From 4ef3ff9793b70b0a2010c835a8350fff5dfff5eb Mon Sep 17 00:00:00 2001 From: evinadmin Date: Tue, 4 Jul 2023 11:23:22 +0200 Subject: [PATCH 1/5] Import Upstream version 2.72.4 --- .clang-format | 11 + .dir-locals.el | 1 + .editorconfig | 17 + AUTHORS | 40 + CONTRIBUTING.md | 274 + COPYING | 502 + HACKING | 17 + INSTALL.in | 125 + NEWS | 14420 +++++++++ NEWS.pre-1-3 | 211 + README | 1 + README.md | 93 + README.rationale | 16 + README.win32 | 1 + README.win32.md | 169 + SECURITY.md | 78 + check-abis.sh | 23 + clang-format-diff.py | 166 + docs/CODEOWNERS | 83 + docs/debugging.txt | 38 + docs/macros.txt | 58 + docs/reference/.gitignore | 16 + docs/reference/AUTHORS | 7 + docs/reference/COPYING | 30 + docs/reference/NEWS | 0 docs/reference/gio/.gitignore | 3 + docs/reference/gio/concat-files-helper.py | 36 + docs/reference/gio/gapplication.xml | 352 + docs/reference/gio/gdbus-codegen.xml | 1193 + .../gdbus-object-manager-example/.gitignore | 1 + .../gdbus-object-manager-example-docs.xml | 19 + .../gdbus-object-manager-example-sections.txt | 161 + .../gdbus-object-manager-example/meson.build | 11 + docs/reference/gio/gdbus.xml | 429 + docs/reference/gio/gio-docs-unix.xml | 3 + docs/reference/gio/gio-docs-win32.xml | 6 + docs/reference/gio/gio-docs.xml | 406 + docs/reference/gio/gio-querymodules.xml | 45 + docs/reference/gio/gio-sections-common.txt | 4772 +++ docs/reference/gio/gio-sections-win32.txt | 112 + docs/reference/gio/gio.xml | 805 + docs/reference/gio/glib-compile-resources.xml | 254 + docs/reference/gio/glib-compile-schemas.xml | 118 + docs/reference/gio/gresource.xml | 127 + docs/reference/gio/gsettings.xml | 248 + docs/reference/gio/gvfs-overview.odg | Bin 0 -> 17772 bytes docs/reference/gio/gvfs-overview.png | Bin 0 -> 48474 bytes docs/reference/gio/menu-example.png | Bin 0 -> 31470 bytes docs/reference/gio/menu-model.png | Bin 0 -> 20647 bytes docs/reference/gio/meson.build | 242 + docs/reference/gio/migrating-gconf.xml | 515 + docs/reference/gio/migrating-gdbus.xml | 310 + docs/reference/gio/migrating-gnome-vfs.xml | 133 + docs/reference/gio/migrating-posix.xml | 27 + docs/reference/gio/overview.xml | 745 + docs/reference/gio/version.xml.in | 1 + docs/reference/gio/xml/gtkdocentities.ent.in | 8 + docs/reference/gio/xml/meson.build | 14 + ...ed_binary_tree_breadth-first_traversal.svg | 134 + .../glib/Sorted_binary_tree_inorder.svg | 753 + .../glib/Sorted_binary_tree_postorder.svg | 750 + .../glib/Sorted_binary_tree_preorder.svg | 750 + docs/reference/glib/building.xml | 365 + docs/reference/glib/changes.xml | 174 + docs/reference/glib/compiling.xml | 125 + docs/reference/glib/cross.xml | 147 + docs/reference/glib/file-name-encodings.png | Bin 0 -> 32141 bytes docs/reference/glib/file-name-encodings.sxd | Bin 0 -> 7006 bytes docs/reference/glib/glib-docs.xml | 302 + docs/reference/glib/glib-gettextize.xml | 88 + docs/reference/glib/glib-overrides.txt | 294 + docs/reference/glib/glib-sections.txt | 4013 +++ docs/reference/glib/gtester-report.xml | 78 + docs/reference/glib/gtester.xml | 192 + docs/reference/glib/gvariant-text.xml | 622 + docs/reference/glib/gvariant-varargs.xml | 1178 + docs/reference/glib/mainloop-states.eps | 306 + docs/reference/glib/mainloop-states.fig | 65 + docs/reference/glib/mainloop-states.gif | Bin 0 -> 7088 bytes docs/reference/glib/mainloop-states.png | Bin 0 -> 15258 bytes docs/reference/glib/meson.build | 104 + docs/reference/glib/programming.xml | 67 + docs/reference/glib/regex-syntax.xml | 2531 ++ docs/reference/glib/resources.xml | 77 + docs/reference/glib/running.xml | 414 + docs/reference/glib/version.xml.in | 1 + docs/reference/glib/xml/gtkdocentities.ent.in | 8 + docs/reference/glib/xml/meson.build | 14 + docs/reference/gobject/glib-genmarshal.xml | 579 + docs/reference/gobject/glib-mkenums.xml | 653 + docs/reference/gobject/gobject-docs.xml | 224 + docs/reference/gobject/gobject-overrides.txt | 0 docs/reference/gobject/gobject-query.xml | 123 + docs/reference/gobject/gobject-sections.txt | 1048 + docs/reference/gobject/images/glue.png | Bin 0 -> 12722 bytes docs/reference/gobject/meson.build | 68 + docs/reference/gobject/tut_gobject.xml | 728 + docs/reference/gobject/tut_gsignal.xml | 495 + docs/reference/gobject/tut_gtype.xml | 1003 + docs/reference/gobject/tut_howto.xml | 1535 + docs/reference/gobject/tut_intro.xml | 185 + docs/reference/gobject/tut_tools.xml | 125 + docs/reference/gobject/version.xml.in | 1 + .../gobject/xml/gtkdocentities.ent.in | 8 + docs/reference/gobject/xml/meson.build | 14 + docs/reference/meson.build | 62 + fuzzing/README.md | 51 + fuzzing/driver.c | 36 + fuzzing/fuzz.h | 22 + fuzzing/fuzz_bookmark.c | 15 + fuzzing/fuzz_bookmark.corpus | 1 + fuzzing/fuzz_canonicalize_filename.c | 19 + fuzzing/fuzz_date_parse.c | 19 + fuzzing/fuzz_date_time_new_from_iso8601.c | 25 + fuzzing/fuzz_dbus_message.c | 28 + .../fuzz_inet_address_mask_new_from_string.c | 25 + fuzzing/fuzz_inet_address_new_from_string.c | 25 + ...fuzz_inet_socket_address_new_from_string.c | 25 + fuzzing/fuzz_key.c | 27 + fuzzing/fuzz_key.corpus | 2 + fuzzing/fuzz_network_address_parse.c | 25 + fuzzing/fuzz_network_address_parse_uri.c | 25 + fuzzing/fuzz_paths.c | 32 + fuzzing/fuzz_resolver.c | 53 + fuzzing/fuzz_uri_escape.c | 65 + fuzzing/fuzz_uri_parse.c | 44 + fuzzing/fuzz_uri_parse_params.c | 28 + fuzzing/fuzz_variant_binary.c | 21 + fuzzing/fuzz_variant_text.c | 21 + fuzzing/fuzz_variant_text.dict | 32 + fuzzing/meson.build | 45 + gio/completion/.gitignore | 1 + gio/completion/gapplication | 55 + gio/completion/gdbus | 33 + gio/completion/gio | 122 + gio/completion/gresource | 58 + gio/completion/gsettings | 88 + gio/data-to-c.py | 17 + gio/dbus-daemon.xml | 76 + gio/fam/gfamfilemonitor.c | 235 + gio/fam/gfamfilemonitor.map | 8 + gio/fam/meson.build | 42 + gio/gaction.c | 587 + gio/gaction.h | 98 + gio/gactiongroup.c | 790 + gio/gactiongroup.h | 161 + gio/gactiongroupexporter.c | 608 + gio/gactiongroupexporter.h | 45 + gio/gactionmap.c | 285 + gio/gactionmap.h | 95 + gio/gappinfo.c | 1520 + gio/gappinfo.h | 349 + gio/gappinfoprivate.h | 26 + gio/gapplication-tool.c | 471 + gio/gapplication.c | 3136 ++ gio/gapplication.h | 252 + gio/gapplicationcommandline.c | 840 + gio/gapplicationcommandline.h | 122 + gio/gapplicationimpl-dbus.c | 1003 + gio/gapplicationimpl.h | 44 + gio/gasynchelper.c | 87 + gio/gasynchelper.h | 41 + gio/gasyncinitable.c | 464 + gio/gasyncinitable.h | 130 + gio/gasyncresult.c | 237 + gio/gasyncresult.h | 85 + gio/gbufferedinputstream.c | 1275 + gio/gbufferedinputstream.h | 133 + gio/gbufferedoutputstream.c | 755 + gio/gbufferedoutputstream.h | 86 + gio/gbytesicon.c | 269 + gio/gbytesicon.h | 52 + gio/gcancellable.c | 821 + gio/gcancellable.h | 118 + gio/gcharsetconverter.c | 472 + gio/gcharsetconverter.h | 63 + gio/gcocoanotificationbackend.m | 277 + gio/gcontenttype-win32.c | 442 + gio/gcontenttype.c | 1575 + gio/gcontenttype.h | 82 + gio/gcontenttypeprivate.h | 34 + gio/gcontextspecificgroup.c | 274 + gio/gcontextspecificgroup.h | 51 + gio/gconverter.c | 201 + gio/gconverter.h | 96 + gio/gconverterinputstream.c | 651 + gio/gconverterinputstream.h | 80 + gio/gconverteroutputstream.c | 689 + gio/gconverteroutputstream.h | 80 + gio/gcredentials.c | 705 + gio/gcredentials.h | 85 + gio/gcredentialsprivate.h | 185 + gio/gdatagrambased.c | 474 + gio/gdatagrambased.h | 144 + gio/gdatainputstream.c | 1477 + gio/gdatainputstream.h | 180 + gio/gdataoutputstream.c | 598 + gio/gdataoutputstream.h | 125 + gio/gdbus-2.0/codegen/.flake8 | 4 + gio/gdbus-2.0/codegen/.gitignore | 3 + gio/gdbus-2.0/codegen/__init__.py | 29 + gio/gdbus-2.0/codegen/codegen.py | 5234 ++++ gio/gdbus-2.0/codegen/codegen_docbook.py | 480 + gio/gdbus-2.0/codegen/codegen_main.py | 500 + gio/gdbus-2.0/codegen/codegen_rst.py | 332 + gio/gdbus-2.0/codegen/config.py.in | 24 + gio/gdbus-2.0/codegen/dbustypes.py | 525 + gio/gdbus-2.0/codegen/gdbus-codegen.in | 55 + gio/gdbus-2.0/codegen/meson.build | 42 + gio/gdbus-2.0/codegen/parser.py | 302 + gio/gdbus-2.0/codegen/utils.py | 165 + gio/gdbus-tool.c | 2641 ++ gio/gdbusactiongroup-private.h | 35 + gio/gdbusactiongroup.c | 550 + gio/gdbusactiongroup.h | 54 + gio/gdbusaddress.c | 1467 + gio/gdbusaddress.h | 65 + gio/gdbusauth.c | 1394 + gio/gdbusauth.h | 86 + gio/gdbusauthmechanism.c | 334 + gio/gdbusauthmechanism.h | 152 + gio/gdbusauthmechanismanon.c | 322 + gio/gdbusauthmechanismanon.h | 61 + gio/gdbusauthmechanismexternal.c | 443 + gio/gdbusauthmechanismexternal.h | 61 + gio/gdbusauthmechanismsha1.c | 1290 + gio/gdbusauthmechanismsha1.h | 61 + gio/gdbusauthobserver.c | 315 + gio/gdbusauthobserver.h | 51 + gio/gdbusconnection.c | 7580 +++++ gio/gdbusconnection.h | 684 + gio/gdbusdaemon.c | 1744 ++ gio/gdbusdaemon.h | 21 + gio/gdbuserror.c | 895 + gio/gdbuserror.h | 109 + gio/gdbusinterface.c | 137 + gio/gdbusinterface.h | 81 + gio/gdbusinterfaceskeleton.c | 1014 + gio/gdbusinterfaceskeleton.h | 127 + gio/gdbusintrospection.c | 2194 ++ gio/gdbusintrospection.h | 325 + gio/gdbusmenumodel.c | 940 + gio/gdbusmenumodel.h | 45 + gio/gdbusmessage.c | 3833 +++ gio/gdbusmessage.h | 197 + gio/gdbusmethodinvocation.c | 838 + gio/gdbusmethodinvocation.h | 132 + gio/gdbusnameowning.c | 991 + gio/gdbusnameowning.h | 115 + gio/gdbusnamewatching.c | 923 + gio/gdbusnamewatching.h | 102 + gio/gdbusobject.c | 152 + gio/gdbusobject.h | 78 + gio/gdbusobjectmanager.c | 253 + gio/gdbusobjectmanager.h | 94 + gio/gdbusobjectmanagerclient.c | 1872 ++ gio/gdbusobjectmanagerclient.h | 146 + gio/gdbusobjectmanagerserver.c | 1190 + gio/gdbusobjectmanagerserver.h | 93 + gio/gdbusobjectproxy.c | 356 + gio/gdbusobjectproxy.h | 79 + gio/gdbusobjectskeleton.c | 509 + gio/gdbusobjectskeleton.h | 96 + gio/gdbusprivate.c | 2629 ++ gio/gdbusprivate.h | 165 + gio/gdbusproxy.c | 3200 ++ gio/gdbusproxy.h | 214 + gio/gdbusserver.c | 1202 + gio/gdbusserver.h | 60 + gio/gdbusutils.c | 847 + gio/gdbusutils.h | 63 + gio/gdebugcontroller.c | 119 + gio/gdebugcontroller.h | 79 + gio/gdebugcontrollerdbus.c | 709 + gio/gdebugcontrollerdbus.h | 69 + gio/gdelayedsettingsbackend.c | 516 + gio/gdelayedsettingsbackend.h | 65 + gio/gdesktopappinfo.c | 5197 +++ gio/gdesktopappinfo.h | 198 + gio/gdocumentportal.c | 216 + gio/gdocumentportal.h | 32 + gio/gdrive.c | 943 + gio/gdrive.h | 272 + gio/gdtlsclientconnection.c | 273 + gio/gdtlsclientconnection.h | 75 + gio/gdtlsconnection.c | 1254 + gio/gdtlsconnection.h | 228 + gio/gdtlsserverconnection.c | 95 + gio/gdtlsserverconnection.h | 69 + gio/gdummyfile.c | 748 + gio/gdummyfile.h | 49 + gio/gdummyproxyresolver.c | 134 + gio/gdummyproxyresolver.h | 52 + gio/gdummytlsbackend.c | 521 + gio/gdummytlsbackend.h | 44 + gio/gemblem.c | 379 + gio/gemblem.h | 61 + gio/gemblemedicon.c | 467 + gio/gemblemedicon.h | 81 + gio/gfdonotificationbackend.c | 513 + gio/gfile.c | 8804 ++++++ gio/gfile.h | 1318 + gio/gfileattribute-priv.h | 91 + gio/gfileattribute.c | 981 + gio/gfileattribute.h | 84 + gio/gfiledescriptorbased.c | 71 + gio/gfiledescriptorbased.h | 65 + gio/gfileenumerator.c | 887 + gio/gfileenumerator.h | 152 + gio/gfileicon.c | 366 + gio/gfileicon.h | 57 + gio/gfileinfo-priv.h | 144 + gio/gfileinfo.c | 2971 ++ gio/gfileinfo.h | 1313 + gio/gfileinputstream.c | 429 + gio/gfileinputstream.h | 114 + gio/gfileiostream.c | 662 + gio/gfileiostream.h | 121 + gio/gfilemonitor.c | 295 + gio/gfilemonitor.h | 98 + gio/gfilenamecompleter.c | 510 + gio/gfilenamecompleter.h | 79 + gio/gfileoutputstream.c | 532 + gio/gfileoutputstream.h | 122 + gio/gfilterinputstream.c | 309 + gio/gfilterinputstream.h | 78 + gio/gfilteroutputstream.c | 308 + gio/gfilteroutputstream.h | 78 + gio/ggtknotificationbackend.c | 122 + gio/ghttpproxy.c | 416 + gio/ghttpproxy.h | 54 + gio/gicon.c | 690 + gio/gicon.h | 102 + gio/ginetaddress.c | 912 + gio/ginetaddress.h | 123 + gio/ginetaddressmask.c | 473 + gio/ginetaddressmask.h | 84 + gio/ginetsocketaddress.c | 543 + gio/ginetsocketaddress.h | 78 + gio/ginitable.c | 255 + gio/ginitable.h | 105 + gio/ginputstream.c | 1619 + gio/ginputstream.h | 216 + gio/gio-autocleanups.h | 153 + gio/gio-querymodules-wrapper.py | 9 + gio/gio-querymodules.c | 180 + gio/gio-tool-cat.c | 178 + gio/gio-tool-copy.c | 227 + gio/gio-tool-info.c | 390 + gio/gio-tool-launch.c | 131 + gio/gio-tool-list.c | 238 + gio/gio-tool-mime.c | 179 + gio/gio-tool-mkdir.c | 110 + gio/gio-tool-monitor.c | 278 + gio/gio-tool-mount.c | 1264 + gio/gio-tool-move.c | 216 + gio/gio-tool-open.c | 140 + gio/gio-tool-remove.c | 97 + gio/gio-tool-rename.c | 103 + gio/gio-tool-save.c | 202 + gio/gio-tool-set.c | 206 + gio/gio-tool-trash.c | 311 + gio/gio-tool-tree.c | 287 + gio/gio-tool.c | 348 + gio/gio-tool.h | 55 + gio/gio.h | 180 + gio/gio.rc.in | 30 + gio/gio.stp.in | 107 + gio/gio_probes.d | 10 + gio/gio_trace.h | 43 + gio/gioenums.h | 2125 ++ gio/gioenumtypes.c.template | 38 + gio/gioenumtypes.h.template | 24 + gio/gioerror.c | 392 + gio/gioerror.h | 53 + gio/giomodule-priv.c | 70 + gio/giomodule-priv.h | 49 + gio/giomodule.c | 1694 + gio/giomodule.h | 193 + gio/gioprivate.h | 62 + gio/gioscheduler.c | 325 + gio/gioscheduler.h | 54 + gio/giostream.c | 920 + gio/giostream.h | 135 + gio/giotypes.h | 658 + gio/giounix-private.c | 145 + gio/giounix-private.h | 26 + gio/giowin32-afunix.h | 40 + gio/giowin32-priv.h | 42 + gio/giowin32-private.c | 450 + gio/gkeyfilesettingsbackend.c | 1033 + gio/glib-compile-resources.c | 1312 + gio/glib-compile-schemas.c | 2331 ++ gio/glistmodel.c | 305 + gio/glistmodel.h | 72 + gio/gliststore.c | 579 + gio/gliststore.h | 88 + gio/gloadableicon.c | 233 + gio/gloadableicon.h | 99 + gio/glocalfile.c | 3019 ++ gio/glocalfile.h | 58 + gio/glocalfileenumerator.c | 458 + gio/glocalfileenumerator.h | 55 + gio/glocalfileinfo.c | 2996 ++ gio/glocalfileinfo.h | 382 + gio/glocalfileinputstream.c | 305 + gio/glocalfileinputstream.h | 61 + gio/glocalfileiostream.c | 116 + gio/glocalfileiostream.h | 58 + gio/glocalfilemonitor.c | 931 + gio/glocalfilemonitor.h | 106 + gio/glocalfileoutputstream.c | 1340 + gio/glocalfileoutputstream.h | 92 + gio/glocalvfs.c | 227 + gio/glocalvfs.h | 44 + gio/gmarshal-internal.c | 2631 ++ gio/gmarshal-internal.h | 503 + gio/gmarshal-internal.list | 28 + gio/gmemoryinputstream.c | 530 + gio/gmemoryinputstream.h | 90 + gio/gmemorymonitor.c | 158 + gio/gmemorymonitor.h | 62 + gio/gmemorymonitordbus.c | 185 + gio/gmemorymonitordbus.h | 31 + gio/gmemorymonitorportal.c | 152 + gio/gmemorymonitorportal.h | 31 + gio/gmemorymonitorwin32.c | 261 + gio/gmemoryoutputstream.c | 842 + gio/gmemoryoutputstream.h | 107 + gio/gmemorysettingsbackend.c | 193 + gio/gmenu.c | 1388 + gio/gmenu.h | 182 + gio/gmenuexporter.c | 833 + gio/gmenuexporter.h | 40 + gio/gmenumodel.c | 1006 + gio/gmenumodel.h | 305 + gio/gmount.c | 1060 + gio/gmount.h | 276 + gio/gmountoperation.c | 983 + gio/gmountoperation.h | 177 + gio/gmountprivate.h | 33 + gio/gnativesocketaddress.c | 163 + gio/gnativesocketaddress.h | 65 + gio/gnativevolumemonitor.c | 50 + gio/gnativevolumemonitor.h | 61 + gio/gnetworkaddress.c | 1219 + gio/gnetworkaddress.h | 80 + gio/gnetworking.c | 76 + gio/gnetworking.h.in | 78 + gio/gnetworkingprivate.h | 35 + gio/gnetworkmonitor.c | 418 + gio/gnetworkmonitor.h | 99 + gio/gnetworkmonitorbase.c | 583 + gio/gnetworkmonitorbase.h | 68 + gio/gnetworkmonitornetlink.c | 513 + gio/gnetworkmonitornetlink.h | 55 + gio/gnetworkmonitornm.c | 374 + gio/gnetworkmonitornm.h | 53 + gio/gnetworkmonitorportal.c | 627 + gio/gnetworkmonitorportal.h | 53 + gio/gnetworkservice.c | 766 + gio/gnetworkservice.h | 75 + gio/gnextstepsettingsbackend.m | 481 + gio/gnotification-private.h | 54 + gio/gnotification.c | 859 + gio/gnotification.h | 101 + gio/gnotificationbackend.c | 84 + gio/gnotificationbackend.h | 73 + gio/gnullsettingsbackend.c | 138 + gio/gopenuriportal.c | 367 + gio/gopenuriportal.h | 41 + gio/gosxappinfo.h | 54 + gio/gosxappinfo.m | 772 + gio/gosxcontenttype.m | 597 + gio/goutputstream.c | 3004 ++ gio/goutputstream.h | 332 + gio/gpermission.c | 476 + gio/gpermission.h | 127 + gio/gpollableinputstream.c | 219 + gio/gpollableinputstream.h | 104 + gio/gpollableoutputstream.c | 379 + gio/gpollableoutputstream.h | 125 + gio/gpollableutils.c | 335 + gio/gpollableutils.h | 64 + gio/gpollfilemonitor.c | 221 + gio/gpollfilemonitor.h | 48 + gio/gportalnotificationbackend.c | 97 + gio/gportalsupport.c | 101 + gio/gportalsupport.h | 31 + gio/gpowerprofilemonitor.c | 141 + gio/gpowerprofilemonitor.h | 63 + gio/gpowerprofilemonitordbus.c | 242 + gio/gpowerprofilemonitordbus.h | 32 + gio/gpowerprofilemonitorportal.c | 189 + gio/gpowerprofilemonitorportal.h | 31 + gio/gpropertyaction.c | 620 + gio/gpropertyaction.h | 47 + gio/gproxy.c | 208 + gio/gproxy.h | 128 + gio/gproxyaddress.c | 453 + gio/gproxyaddress.h | 86 + gio/gproxyaddressenumerator.c | 799 + gio/gproxyaddressenumerator.h | 81 + gio/gproxyresolver.c | 244 + gio/gproxyresolver.h | 95 + gio/gproxyresolverportal.c | 208 + gio/gproxyresolverportal.h | 46 + gio/gregistrysettingsbackend.c | 2167 ++ gio/gregistrysettingsbackend.h | 28 + gio/gremoteactiongroup.c | 142 + gio/gremoteactiongroup.h | 75 + gio/gresolver.c | 1254 + gio/gresolver.h | 292 + gio/gresource-tool.c | 664 + gio/gresource.c | 1475 + gio/gresource.h | 130 + gio/gresourcefile.c | 957 + gio/gresourcefile.h | 49 + gio/gschema.dtd | 75 + gio/gschema.its | 25 + gio/gschema.loc | 10 + gio/gseekable.c | 197 + gio/gseekable.h | 103 + gio/gsettings-mapping.c | 592 + gio/gsettings-mapping.h | 34 + gio/gsettings-tool.c | 956 + gio/gsettings.c | 3415 ++ gio/gsettings.h | 345 + gio/gsettingsbackend.c | 1080 + gio/gsettingsbackend.h | 174 + gio/gsettingsbackendinternal.h | 96 + gio/gsettingsschema-internal.h | 76 + gio/gsettingsschema.c | 1901 ++ gio/gsettingsschema.h | 112 + gio/gsimpleaction.c | 650 + gio/gsimpleaction.h | 63 + gio/gsimpleactiongroup.c | 400 + gio/gsimpleactiongroup.h | 97 + gio/gsimpleasyncresult.c | 1151 + gio/gsimpleasyncresult.h | 162 + gio/gsimpleiostream.c | 222 + gio/gsimpleiostream.h | 45 + gio/gsimplepermission.c | 84 + gio/gsimplepermission.h | 45 + gio/gsimpleproxyresolver.c | 597 + gio/gsimpleproxyresolver.h | 89 + gio/gsocket.c | 6320 ++++ gio/gsocket.h | 328 + gio/gsocketaddress.c | 418 + gio/gsocketaddress.h | 82 + gio/gsocketaddressenumerator.c | 198 + gio/gsocketaddressenumerator.h | 101 + gio/gsocketclient.c | 2396 ++ gio/gsocketclient.h | 197 + gio/gsocketconnectable.c | 179 + gio/gsocketconnectable.h | 81 + gio/gsocketconnection.c | 687 + gio/gsocketconnection.h | 115 + gio/gsocketcontrolmessage.c | 214 + gio/gsocketcontrolmessage.h | 111 + gio/gsocketinputstream.c | 225 + gio/gsocketinputstream.h | 58 + gio/gsocketlistener.c | 1281 + gio/gsocketlistener.h | 155 + gio/gsocketoutputstream.c | 282 + gio/gsocketoutputstream.h | 58 + gio/gsocketservice.c | 427 + gio/gsocketservice.h | 93 + gio/gsocks4aproxy.c | 458 + gio/gsocks4aproxy.h | 53 + gio/gsocks4proxy.c | 69 + gio/gsocks4proxy.h | 42 + gio/gsocks5proxy.c | 1109 + gio/gsocks5proxy.h | 46 + gio/gsrvtarget.c | 312 + gio/gsrvtarget.h | 58 + gio/gsubprocess.c | 1805 ++ gio/gsubprocess.h | 167 + gio/gsubprocesslauncher-private.h | 59 + gio/gsubprocesslauncher.c | 802 + gio/gsubprocesslauncher.h | 119 + gio/gtask.c | 2285 ++ gio/gtask.h | 182 + gio/gtcpconnection.c | 332 + gio/gtcpconnection.h | 69 + gio/gtcpwrapperconnection.c | 201 + gio/gtcpwrapperconnection.h | 69 + gio/gtestdbus.c | 894 + gio/gtestdbus.h | 72 + gio/gthemedicon.c | 628 + gio/gthemedicon.h | 68 + gio/gthreadedresolver.c | 1254 + gio/gthreadedresolver.h | 60 + gio/gthreadedsocketservice.c | 277 + gio/gthreadedsocketservice.h | 81 + gio/gtlsbackend.c | 348 + gio/gtlsbackend.h | 113 + gio/gtlscertificate.c | 1330 + gio/gtlscertificate.h | 123 + gio/gtlsclientconnection.c | 422 + gio/gtlsclientconnection.h | 86 + gio/gtlsconnection.c | 1163 + gio/gtlsconnection.h | 212 + gio/gtlsdatabase.c | 1034 + gio/gtlsdatabase.h | 247 + gio/gtlsfiledatabase.c | 103 + gio/gtlsfiledatabase.h | 58 + gio/gtlsinteraction.c | 846 + gio/gtlsinteraction.h | 148 + gio/gtlspassword.c | 456 + gio/gtlspassword.h | 119 + gio/gtlsserverconnection.c | 98 + gio/gtlsserverconnection.h | 69 + gio/gtrashportal.c | 138 + gio/gtrashportal.h | 31 + gio/gunionvolumemonitor.c | 635 + gio/gunionvolumemonitor.h | 47 + gio/gunixconnection.c | 735 + gio/gunixconnection.h | 100 + gio/gunixcredentialsmessage.c | 355 + gio/gunixcredentialsmessage.h | 87 + gio/gunixfdlist.c | 400 + gio/gunixfdlist.h | 95 + gio/gunixfdmessage.c | 331 + gio/gunixfdmessage.h | 84 + gio/gunixinputstream.c | 487 + gio/gunixinputstream.h | 83 + gio/gunixmount.c | 395 + gio/gunixmount.h | 58 + gio/gunixmounts.c | 3222 ++ gio/gunixmounts.h | 170 + gio/gunixoutputstream.c | 641 + gio/gunixoutputstream.h | 82 + gio/gunixsocketaddress.c | 576 + gio/gunixsocketaddress.h | 81 + gio/gunixvolume.c | 439 + gio/gunixvolume.h | 59 + gio/gunixvolumemonitor.c | 419 + gio/gunixvolumemonitor.h | 62 + gio/gvdb/gvdb-builder.c | 636 + gio/gvdb/gvdb-builder.h | 66 + gio/gvdb/gvdb-format.h | 85 + gio/gvdb/gvdb-reader.c | 736 + gio/gvdb/gvdb-reader.h | 78 + gio/gvdb/gvdb.doap | 57 + gio/gvfs.c | 511 + gio/gvfs.h | 168 + gio/gvolume.c | 687 + gio/gvolume.h | 253 + gio/gvolumemonitor.c | 395 + gio/gvolumemonitor.h | 154 + ...gwin32api-application-activation-manager.h | 126 + gio/gwin32api-iterator.h | 125 + gio/gwin32api-misc.h | 1 + gio/gwin32api-package.h | 264 + gio/gwin32api-storage.h | 339 + gio/gwin32appinfo.c | 5476 ++++ gio/gwin32appinfo.h | 52 + gio/gwin32file-sync-stream.c | 508 + gio/gwin32file-sync-stream.h | 44 + gio/gwin32inputstream.c | 400 + gio/gwin32inputstream.h | 84 + gio/gwin32mount.c | 539 + gio/gwin32mount.h | 56 + gio/gwin32networkmonitor.c | 339 + gio/gwin32networkmonitor.h | 53 + gio/gwin32notificationbackend.c | 96 + gio/gwin32outputstream.c | 386 + gio/gwin32outputstream.h | 83 + gio/gwin32packageparser.c | 818 + gio/gwin32packageparser.h | 48 + gio/gwin32registrykey.c | 2728 ++ gio/gwin32registrykey.h | 291 + gio/gwin32sid.c | 234 + gio/gwin32sid.h | 40 + gio/gwin32volumemonitor.c | 255 + gio/gwin32volumemonitor.h | 63 + gio/gzlibcompressor.c | 436 + gio/gzlibcompressor.h | 62 + gio/gzlibdecompressor.c | 413 + gio/gzlibdecompressor.h | 58 + gio/inotify/ginotifyfilemonitor.c | 114 + gio/inotify/ginotifyfilemonitor.h | 52 + gio/inotify/inotify-helper.c | 290 + gio/inotify/inotify-helper.h | 31 + gio/inotify/inotify-kernel.c | 458 + gio/inotify/inotify-kernel.h | 62 + gio/inotify/inotify-missing.c | 156 + gio/inotify/inotify-missing.h | 33 + gio/inotify/inotify-path.c | 595 + gio/inotify/inotify-path.h | 31 + gio/inotify/inotify-sub.c | 81 + gio/inotify/inotify-sub.h | 41 + gio/inotify/meson.build | 15 + gio/kqueue/dep-list.c | 536 + gio/kqueue/dep-list.h | 69 + gio/kqueue/gkqueuefilemonitor.c | 617 + gio/kqueue/kqueue-helper.c | 196 + gio/kqueue/kqueue-helper.h | 60 + gio/kqueue/kqueue-missing.c | 179 + gio/kqueue/meson.build | 13 + gio/meson.build | 1050 + gio/org.freedesktop.portal.Documents.xml | 277 + gio/org.freedesktop.portal.OpenURI.xml | 167 + gio/org.freedesktop.portal.ProxyResolver.xml | 49 + gio/org.freedesktop.portal.Trash.xml | 48 + gio/strinfo.c | 348 + gio/tests/.gitignore | 146 + gio/tests/111_digit_test.gresource.xml | 6 + gio/tests/actions.c | 1249 + gio/tests/appinfo-test-actions.desktop | 16 + gio/tests/appinfo-test-gnome.desktop.in | 6 + gio/tests/appinfo-test-notgnome.desktop.in | 6 + gio/tests/appinfo-test-static.desktop | 19 + gio/tests/appinfo-test.c | 28 + gio/tests/appinfo-test.desktop.in | 19 + gio/tests/appinfo-test2.desktop.in | 11 + gio/tests/appinfo.c | 601 + gio/tests/appmonitor.c | 130 + gio/tests/apps.c | 147 + gio/tests/async-close-output-stream.c | 276 + gio/tests/async-splice-output-stream.c | 231 + gio/tests/autoptr.c | 23 + gio/tests/basic-application.c | 274 + gio/tests/buffered-input-stream.c | 552 + gio/tests/buffered-output-stream.c | 329 + gio/tests/cancellable.c | 349 + gio/tests/cert-tests/cert-crlf.pem | 17 + gio/tests/cert-tests/cert-key.pem | 32 + gio/tests/cert-tests/cert-list.pem | 68 + gio/tests/cert-tests/cert1.pem | 17 + gio/tests/cert-tests/cert2.pem | 17 + gio/tests/cert-tests/cert3.pem | 17 + .../cert-tests/key-cert-password-123.p12 | Bin 0 -> 1717 bytes gio/tests/cert-tests/key-cert.pem | 32 + gio/tests/cert-tests/key-crlf.pem | 15 + gio/tests/cert-tests/key.pem | 15 + gio/tests/cert-tests/key8.pem | 16 + gio/tests/cert-tests/key8enc.pem | 18 + gio/tests/cert-tests/key_missing-footer.pem | 14 + gio/tests/cert-tests/key_missing-header.pem | 14 + gio/tests/cert-tests/nothing.pem | 0 gio/tests/codegen.py | 682 + gio/tests/contenttype.c | 449 + gio/tests/contexts.c | 441 + gio/tests/converter-stream.c | 1235 + gio/tests/credentials.c | 213 + gio/tests/cxx.cpp | 26 + gio/tests/data-input-stream.c | 507 + gio/tests/data-output-stream.c | 514 + gio/tests/dbus-appinfo.c | 449 + gio/tests/dbus-launch.c | 78 + gio/tests/de.po | 17 + gio/tests/de/LC_MESSAGES/meson.build | 8 + gio/tests/debugcontroller.c | 396 + gio/tests/defaultvalue.c | 228 + gio/tests/desktop-app-info.c | 836 + .../home/applications/eog.desktop | 11 + ...022b17686306243dada811d550d25eb1fb.desktop | 7 + .../usr/applications/baobab.desktop | 39 + .../usr/applications/cheese.desktop | 47 + .../usr/applications/dconf-editor.desktop | 33 + .../usr/applications/eog.desktop | 44 + .../usr/applications/evince-previewer.desktop | 28 + .../usr/applications/evince.desktop | 42 + .../usr/applications/file-roller.desktop | 43 + .../usr/applications/frobnicator.desktop | 9 + .../usr/applications/gcr-prompter.desktop | 19 + .../usr/applications/gcr-viewer.desktop | 10 + .../usr/applications/gedit.desktop | 83 + .../usr/applications/glade.desktop | 56 + .../usr/applications/gnome-contacts.desktop | 26 + .../applications/gnome-font-viewer.desktop | 33 + .../usr/applications/gnome-music.desktop | 23 + .../usr/applications/gnome-terminal.desktop | 39 + .../usr/applications/gucharmap.desktop | 38 + .../usr/applications/invalid-desktop.desktop | 5 + .../usr/applications/kde4/dolphin.desktop | 27 + .../usr/applications/kde4/kate.desktop | 26 + .../usr/applications/kde4/konqbrowser.desktop | 26 + .../usr/applications/kde4/okular.desktop | 23 + .../usr/applications/mimeinfo.cache | 246 + .../nautilus-autorun-software.desktop | 19 + .../usr/applications/nautilus-classic.desktop | 15 + .../nautilus-connect-server.desktop | 22 + .../usr/applications/nautilus.desktop | 39 + .../usr/applications/org.gnome.clocks.desktop | 404 + .../usr/applications/totem.desktop | 36 + .../usr/applications/yelp.desktop | 39 + gio/tests/echo-server.c | 70 + gio/tests/empty.txt | 0 gio/tests/enums.xml.template | 18 + gio/tests/fake-document-portal.c | 144 + gio/tests/fake-service-name.c | 120 + gio/tests/file.c | 3160 ++ gio/tests/fileattributematcher.c | 162 + gio/tests/filter-cat.c | 269 + gio/tests/filter-streams.c | 391 + gio/tests/g-file-info-filesystem-readonly.c | 273 + gio/tests/g-file-info.c | 908 + gio/tests/g-file.c | 537 + gio/tests/g-icon.c | 622 + gio/tests/gapplication-example-actions.c | 122 + gio/tests/gapplication-example-cmdline.c | 43 + gio/tests/gapplication-example-cmdline2.c | 106 + gio/tests/gapplication-example-cmdline3.c | 106 + gio/tests/gapplication-example-cmdline4.c | 85 + gio/tests/gapplication-example-dbushooks.c | 97 + gio/tests/gapplication-example-open.c | 56 + gio/tests/gapplication.c | 1230 + gio/tests/gdbus-address-get-session.c | 227 + gio/tests/gdbus-addresses.c | 223 + gio/tests/gdbus-auth.c | 314 + gio/tests/gdbus-bz627724.c | 87 + gio/tests/gdbus-close-pending.c | 394 + gio/tests/gdbus-connection-flush-helper.c | 56 + gio/tests/gdbus-connection-flush.c | 381 + gio/tests/gdbus-connection-loss.c | 146 + gio/tests/gdbus-connection-slow.c | 239 + gio/tests/gdbus-connection.c | 1296 + gio/tests/gdbus-daemon.c | 70 + gio/tests/gdbus-error.c | 269 + gio/tests/gdbus-example-export.c | 335 + .../gdbus-example-objectmanager-client.c | 168 + .../gdbus-example-objectmanager-server.c | 160 + gio/tests/gdbus-example-own-name.c | 84 + gio/tests/gdbus-example-peer.c | 394 + gio/tests/gdbus-example-proxy-subclass.c | 358 + gio/tests/gdbus-example-server.c | 391 + gio/tests/gdbus-example-subtree.c | 402 + gio/tests/gdbus-example-unix-fd-client.c | 131 + gio/tests/gdbus-example-watch-name.c | 86 + gio/tests/gdbus-example-watch-proxy.c | 230 + gio/tests/gdbus-exit-on-close.c | 218 + gio/tests/gdbus-export.c | 1987 ++ gio/tests/gdbus-introspection.c | 324 + gio/tests/gdbus-message.c | 225 + gio/tests/gdbus-method-invocation.c | 406 + gio/tests/gdbus-names.c | 1368 + gio/tests/gdbus-non-socket.c | 303 + .../gdbus-example-objectmanager.xml | 78 + .../gdbus-object-manager-example/meson.build | 49 + gio/tests/gdbus-overflow.c | 250 + gio/tests/gdbus-peer-object-manager.c | 386 + gio/tests/gdbus-peer.c | 2215 ++ gio/tests/gdbus-proxy-threads.c | 250 + gio/tests/gdbus-proxy-unique-name.c | 215 + gio/tests/gdbus-proxy-well-known-name.c | 272 + gio/tests/gdbus-proxy.c | 1039 + gio/tests/gdbus-serialization.c | 1660 + gio/tests/gdbus-server-auth.c | 554 + gio/tests/gdbus-sessionbus.c | 71 + gio/tests/gdbus-sessionbus.h | 35 + gio/tests/gdbus-test-codegen.c | 2749 ++ gio/tests/gdbus-test-fixture.c | 100 + gio/tests/gdbus-tests.c | 234 + gio/tests/gdbus-tests.h | 122 + gio/tests/gdbus-testserver.c | 891 + gio/tests/gdbus-threading.c | 686 + gio/tests/gen-big-test-resource.py | 26 + gio/tests/gengiotypefuncs.py | 50 + gio/tests/gio-du.c | 163 + gio/tests/giomodule.c | 153 + gio/tests/glistmodel.c | 908 + gio/tests/gmenumodel.c | 1532 + gio/tests/gnotification-server.c | 337 + gio/tests/gnotification-server.h | 44 + gio/tests/gnotification.c | 250 + gio/tests/gschema-compile.c | 164 + gio/tests/gsettings.c | 3157 ++ gio/tests/gsocketclient-slow.c | 185 + gio/tests/gsubprocess-testprog.c | 307 + gio/tests/gsubprocess.c | 2135 ++ gio/tests/gtesttlsbackend.c | 522 + gio/tests/gtesttlsbackend.h | 44 + gio/tests/gtlsconsoleinteraction.c | 162 + gio/tests/gtlsconsoleinteraction.h | 54 + gio/tests/httpd.c | 188 + gio/tests/inet-address.c | 427 + gio/tests/io-stream.c | 171 + gio/tests/live-g-file.c | 1493 + gio/tests/live-g-file.txt | 27 + gio/tests/memory-input-stream.c | 302 + gio/tests/memory-monitor-dbus.py.in | 115 + gio/tests/memory-monitor-portal.py.in | 133 + gio/tests/memory-monitor.c | 72 + gio/tests/memory-output-stream.c | 465 + gio/tests/memory-settings-backend.c | 57 + gio/tests/meson.build | 927 + gio/tests/mimeapps.c | 648 + gio/tests/mock-resolver.c | 263 + gio/tests/mock-resolver.h | 35 + gio/tests/modules/meson.build | 13 + gio/tests/modules/symbol-visibility.h | 20 + gio/tests/modules/test-module-a.c | 63 + gio/tests/modules/test-module-b.c | 63 + gio/tests/mount-operation.c | 132 + gio/tests/network-address.c | 1286 + gio/tests/network-monitor-race.c | 94 + gio/tests/network-monitor.c | 580 + gio/tests/null-settings-backend.c | 54 + .../org.gtk.schemasourcecheck.gschema.xml | 8 + gio/tests/org.gtk.test.dbusappinfo.desktop | 18 + .../org.gtk.test.dbusappinfo.flatpak.desktop | 5 + gio/tests/org.gtk.test.gschema.override.orig | 2 + gio/tests/org.gtk.test.gschema.xml.orig | 222 + gio/tests/permission.c | 117 + gio/tests/pollable.c | 392 + gio/tests/power-profile-monitor-dbus.py.in | 107 + gio/tests/power-profile-monitor-portal.py.in | 142 + gio/tests/power-profile-monitor.c | 79 + gio/tests/proxy-test.c | 1527 + gio/tests/proxy.c | 658 + gio/tests/readwrite.c | 313 + gio/tests/resolver-parsing.c | 879 + gio/tests/resolver.c | 794 + gio/tests/resourceplugin.c | 28 + gio/tests/resources.c | 1074 + .../array-default-not-in-choices.gschema.xml | 11 + gio/tests/schema-tests/bad-choice.gschema.xml | 14 + gio/tests/schema-tests/bad-key.gschema.xml | 7 + gio/tests/schema-tests/bad-key2.gschema.xml | 7 + gio/tests/schema-tests/bad-key3.gschema.xml | 7 + gio/tests/schema-tests/bad-key4.gschema.xml | 7 + gio/tests/schema-tests/bad-type.gschema.xml | 7 + gio/tests/schema-tests/bare-alias.gschema.xml | 7 + gio/tests/schema-tests/cdata.gschema.xml | 7 + .../schema-tests/choice-alias.gschema.xml | 15 + gio/tests/schema-tests/choice-bad.gschema.xml | 14 + .../schema-tests/choice-badtype.gschema.xml | 7 + .../choice-invalid-alias.gschema.xml | 15 + .../choice-missing-value.gschema.xml | 10 + .../choice-shadowed-alias.gschema.xml | 14 + .../choice-upside-down.gschema.xml | 14 + gio/tests/schema-tests/choice.gschema.xml | 14 + .../choices-wrong-type.gschema.xml | 8 + .../default-in-aliases.gschema.xml | 15 + .../default-not-in-choices.gschema.xml | 11 + .../default-out-of-range.gschema.xml | 8 + .../description-xmllang.gschema.xml | 13 + gio/tests/schema-tests/empty-key.gschema.xml | 7 + .../enum-with-aliases.gschema.xml | 20 + .../enum-with-bad-default.gschema.xml | 16 + .../enum-with-chained-alias.gschema.xml | 21 + .../schema-tests/enum-with-choice.gschema.xml | 17 + .../enum-with-invalid-alias.gschema.xml | 20 + .../enum-with-invalid-value.gschema.xml | 10 + .../enum-with-repeated-alias.gschema.xml | 21 + .../enum-with-repeated-nick.gschema.xml | 10 + .../enum-with-repeated-value.gschema.xml | 10 + .../enum-with-shadow-alias.gschema.xml | 20 + gio/tests/schema-tests/enum.gschema.xml | 16 + .../extend-and-shadow-indirect.gschema.xml | 17 + .../extend-and-shadow.gschema.xml | 17 + .../schema-tests/extend-missing.gschema.xml | 3 + .../schema-tests/extend-nonlist.gschema.xml | 4 + .../schema-tests/extend-self.gschema.xml | 3 + .../extend-wrong-list-indirect.gschema.xml | 6 + .../extend-wrong-list.gschema.xml | 5 + gio/tests/schema-tests/extending.gschema.xml | 21 + .../flags-aliased-default.gschema.xml | 19 + .../flags-bad-default.gschema.xml | 16 + .../flags-more-than-one-bit.gschema.xml | 10 + .../flags-with-enum-attr.gschema.xml | 14 + .../flags-with-enum-tag.gschema.xml | 14 + gio/tests/schema-tests/from-docs.gschema.xml | 34 + .../schema-tests/incomplete-list.gschema.xml | 7 + .../inherit-gettext-domain.gschema.xml | 8 + .../schema-tests/invalid-path.gschema.xml | 3 + .../key-in-list-indirect.gschema.xml | 8 + .../schema-tests/key-in-list.gschema.xml | 6 + .../schema-tests/list-of-missing.gschema.xml | 3 + .../schema-tests/missing-quotes.gschema.xml | 7 + gio/tests/schema-tests/no-default.gschema.xml | 6 + gio/tests/schema-tests/overflow.gschema.xml | 7 + .../schema-tests/override-missing.gschema.xml | 11 + .../override-range-error.gschema.xml | 12 + .../override-then-key.gschema.xml | 15 + .../schema-tests/override-twice.gschema.xml | 12 + .../override-type-error.gschema.xml | 11 + gio/tests/schema-tests/override.gschema.xml | 34 + .../schema-tests/range-badtype.gschema.xml | 7 + .../range-default-high.gschema.xml | 8 + .../range-default-low.gschema.xml | 8 + .../range-high-default.gschema.xml | 8 + .../range-low-default.gschema.xml | 8 + .../range-missing-max.gschema.xml | 8 + .../range-missing-min.gschema.xml | 8 + .../range-parse-error.gschema.xml | 8 + .../schema-tests/range-type-test.gschema.xml | 76 + .../schema-tests/range-wrong-type.gschema.xml | 8 + gio/tests/schema-tests/range.gschema.xml | 8 + .../summary-xmllang-and-attrs.gschema.xml | 13 + .../schema-tests/summary-xmllang.gschema.xml | 13 + .../schema-tests/wrong-category.gschema.xml | 7 + gio/tests/send-data.c | 207 + gio/tests/services/meson.build | 31 + ...rg.freedesktop.portal.Documents.service.in | 3 + ...tk.GDBus.Examples.ObjectManager.service.in | 3 + .../org.gtk.GDBus.FakeService.service.in | 3 + gio/tests/simple-async-result.c | 199 + gio/tests/simple-proxy.c | 293 + gio/tests/sleepy-stream.c | 293 + gio/tests/slow-connect-preload.c | 43 + gio/tests/socket-address.c | 119 + gio/tests/socket-client.c | 444 + gio/tests/socket-common.c | 123 + gio/tests/socket-listener.c | 92 + gio/tests/socket-server.c | 366 + gio/tests/socket-service.c | 566 + gio/tests/socket.c | 2350 ++ gio/tests/srvtarget.c | 157 + gio/tests/static-link.py | 55 + gio/tests/static-link/app.c | 8 + gio/tests/static-link/meson.build | 8 + gio/tests/stream-rw_all.c | 258 + gio/tests/taptestrunner.py | 186 + gio/tests/task.c | 2405 ++ gio/tests/test-codegen.xml | 499 + gio/tests/test-io-stream.c | 102 + gio/tests/test-io-stream.h | 51 + gio/tests/test-pipe-unix.c | 129 + gio/tests/test-pipe-unix.h | 35 + gio/tests/test.gresource.xml | 13 + gio/tests/test1.overlay | 1 + gio/tests/test1.txt | 1 + gio/tests/test2.gresource.xml | 11 + gio/tests/test2.txt | 1 + gio/tests/test3.gresource.xml | 6 + gio/tests/test3.txt | 1 + gio/tests/test4.gresource.xml | 6 + gio/tests/test5.gresource.xml | 6 + gio/tests/testenum.h | 16 + gio/tests/testfilemonitor.c | 1104 + gio/tests/thumbnail-verification.c | 131 + gio/tests/thumbnails/bad-header.png | Bin 0 -> 512 bytes gio/tests/thumbnails/empty-key.png | Bin 0 -> 512 bytes .../thumbnails/header-and-chunk-size.png | Bin 0 -> 20 bytes gio/tests/thumbnails/header-only.png | 2 + gio/tests/thumbnails/huge-chunk-size.png | Bin 0 -> 512 bytes gio/tests/thumbnails/mtime-zero.png | Bin 0 -> 512 bytes gio/tests/thumbnails/no-text-data.png | Bin 0 -> 256 bytes gio/tests/thumbnails/overlong-value.png | Bin 0 -> 512 bytes gio/tests/thumbnails/uri-mismatch.png | Bin 0 -> 512 bytes gio/tests/thumbnails/valid-no-size.png | Bin 0 -> 512 bytes gio/tests/thumbnails/valid.png | Bin 0 -> 512 bytes gio/tests/tls-bindings.c | 95 + gio/tests/tls-certificate.c | 728 + gio/tests/tls-database.c | 75 + gio/tests/tls-interaction.c | 1107 + gio/tests/trash.c | 198 + gio/tests/unix-fd.c | 242 + gio/tests/unix-mounts.c | 63 + gio/tests/unix-streams.c | 872 + gio/tests/vfs.c | 130 + gio/tests/volumemonitor.c | 180 + gio/tests/win32-appinfo.c | 469 + gio/tests/win32-streams.c | 535 + .../image-dcf/DCIM/Camera/20130831_203925.jpg | 0 .../image-dcf/DCIM/Camera/20130831_203928.jpg | 0 gio/tests/x-content/unix-software/autorun.sh | 3 + .../x-content/win32-software/autorun.exe | 0 gio/thumbnail-verify.c | 252 + gio/thumbnail-verify.h | 30 + gio/win32/gwin32filemonitor.c | 104 + gio/win32/gwin32filemonitor.h | 62 + gio/win32/gwin32fsmonitorutils.c | 425 + gio/win32/gwin32fsmonitorutils.h | 76 + gio/win32/gwinhttpfile.c | 788 + gio/win32/gwinhttpfile.h | 62 + gio/win32/gwinhttpfileinputstream.c | 175 + gio/win32/gwinhttpfileinputstream.h | 50 + gio/win32/gwinhttpfileoutputstream.c | 183 + gio/win32/gwinhttpfileoutputstream.h | 49 + gio/win32/gwinhttpvfs.c | 479 + gio/win32/gwinhttpvfs.h | 106 + gio/win32/meson.build | 15 + gio/win32/winhttp.h | 247 + gio/xdgmime/.gitignore | 1 + gio/xdgmime/meson.build | 17 + gio/xdgmime/xdgmime.c | 1012 + gio/xdgmime/xdgmime.h | 135 + gio/xdgmime/xdgmimealias.c | 184 + gio/xdgmime/xdgmimealias.h | 51 + gio/xdgmime/xdgmimecache.c | 1165 + gio/xdgmime/xdgmimecache.h | 81 + gio/xdgmime/xdgmimeglob.c | 725 + gio/xdgmime/xdgmimeglob.h | 70 + gio/xdgmime/xdgmimeicon.c | 183 + gio/xdgmime/xdgmimeicon.h | 50 + gio/xdgmime/xdgmimeint.c | 206 + gio/xdgmime/xdgmimeint.h | 78 + gio/xdgmime/xdgmimemagic.c | 830 + gio/xdgmime/xdgmimemagic.h | 57 + gio/xdgmime/xdgmimeparent.c | 220 + gio/xdgmime/xdgmimeparent.h | 51 + glib-gettextize.in | 187 + glib.doap | 64 + glib.supp | 1111 + glib/deprecated/gallocator.c | 104 + glib/deprecated/gallocator.h | 88 + glib/deprecated/gcache.c | 350 + glib/deprecated/gcache.h | 75 + glib/deprecated/gcompletion.c | 503 + glib/deprecated/gcompletion.h | 83 + glib/deprecated/gmain.h | 135 + glib/deprecated/grel.c | 685 + glib/deprecated/grel.h | 105 + glib/deprecated/gthread-deprecated.c | 1578 + glib/deprecated/gthread.h | 293 + glib/dirent/README | 2 + glib/dirent/dirent-zip | 19 + glib/dirent/dirent.c | 341 + glib/dirent/dirent.h | 127 + glib/dirent/wdirent.c | 3 + glib/docs.c | 2636 ++ glib/galloca.h | 145 + glib/garcbox.c | 381 + glib/garray.c | 2576 ++ glib/garray.h | 281 + glib/gasyncqueue.c | 906 + glib/gasyncqueue.h | 124 + glib/gasyncqueueprivate.h | 29 + glib/gatomic.c | 967 + glib/gatomic.h | 470 + glib/gbacktrace.c | 455 + glib/gbacktrace.h | 72 + glib/gbase64.c | 462 + glib/gbase64.h | 61 + glib/gbitlock.c | 563 + glib/gbitlock.h | 76 + glib/gbookmarkfile.c | 4022 +++ glib/gbookmarkfile.h | 295 + glib/gbsearcharray.h | 299 + glib/gbytes.c | 612 + glib/gbytes.h | 97 + glib/gcharset.c | 838 + glib/gcharset.h | 47 + glib/gcharsetprivate.h | 34 + glib/gchecksum.c | 1864 ++ glib/gchecksum.h | 104 + glib/gconstructor.h | 159 + glib/gconvert.c | 2066 ++ glib/gconvert.h | 177 + glib/gconvertprivate.h | 40 + glib/gdataset.c | 1251 + glib/gdataset.h | 150 + glib/gdatasetprivate.h | 42 + glib/gdate.c | 2755 ++ glib/gdate.h | 307 + glib/gdatetime.c | 3527 +++ glib/gdatetime.h | 273 + glib/gdir.c | 330 + glib/gdir.h | 52 + glib/gen-unicode-tables.pl | 1552 + glib/genviron.c | 701 + glib/genviron.h | 63 + glib/gerror.c | 1157 + glib/gerror.h | 261 + glib/gfileutils.c | 2978 ++ glib/gfileutils.h | 221 + glib/ggettext.c | 637 + glib/ggettext.h | 63 + glib/ghash.c | 2533 ++ glib/ghash.h | 190 + glib/ghmac.c | 441 + glib/ghmac.h | 83 + glib/ghook.c | 1050 + glib/ghook.h | 202 + glib/ghostutils.c | 888 + glib/ghostutils.h | 43 + glib/gi18n-lib.h | 36 + glib/gi18n.h | 32 + glib/giochannel.c | 2581 ++ glib/giochannel.h | 404 + glib/giounix.c | 657 + glib/giowin32.c | 2241 ++ glib/gkeyfile.c | 4686 +++ glib/gkeyfile.h | 330 + glib/glib-autocleanups.h | 103 + glib/glib-init.c | 458 + glib/glib-init.h | 48 + glib/glib-mirroring-tab/gen-mirroring-tab.c | 230 + glib/glib-mirroring-tab/meson.build | 5 + glib/glib-mirroring-tab/packtab.c | 422 + glib/glib-mirroring-tab/packtab.h | 48 + glib/glib-object.h | 44 + glib/glib-private.c | 62 + glib/glib-private.h | 204 + glib/glib-typeof.h | 43 + glib/glib-unix.c | 546 + glib/glib-unix.h | 123 + glib/glib.h | 119 + glib/glib.rc.in | 30 + glib/glib.stp.in | 645 + glib/glib_gdb.py | 300 + glib/glib_probes.d | 50 + glib/glib_trace.h | 43 + glib/glibconfig.h.in | 210 + glib/glibintl.h | 44 + glib/glist.c | 1365 + glib/glist.h | 177 + glib/gmacros.h | 1282 + glib/gmain-internal.h | 33 + glib/gmain.c | 6235 ++++ glib/gmain.h | 835 + glib/gmappedfile.c | 428 + glib/gmappedfile.h | 58 + glib/gmarkup.c | 2976 ++ glib/gmarkup.h | 261 + glib/gmem.c | 702 + glib/gmem.h | 407 + glib/gmessages.c | 3474 +++ glib/gmessages.h | 688 + glib/gmirroringtable.h | 945 + glib/gnode.c | 1280 + glib/gnode.h | 307 + glib/gnulib/README | 87 + glib/gnulib/arg-nonnull.h | 26 + glib/gnulib/asnprintf.c | 36 + glib/gnulib/c++defs.h | 316 + glib/gnulib/float+.h | 147 + glib/gnulib/fpucw.h | 108 + glib/gnulib/frexp.c | 22 + glib/gnulib/frexpl.c | 21 + glib/gnulib/g-gnulib.h | 46 + .../gl_cv_cc_double_expbit0/meson.build | 101 + .../gnulib/gl_cv_func_frexp_works/meson.build | 110 + .../gl_cv_func_frexpl_works/meson.build | 141 + .../gl_cv_func_ldexpl_works/meson.build | 57 + .../gl_cv_func_printf_directive_a/meson.build | 94 + .../gl_cv_func_printf_directive_f/meson.build | 81 + .../meson.build | 82 + .../gl_cv_func_printf_enomem/meson.build | 73 + .../meson.build | 37 + .../meson.build | 39 + .../gl_cv_func_printf_flag_zero/meson.build | 40 + .../gl_cv_func_printf_infinite/meson.build | 135 + .../meson.build | 208 + .../gl_cv_func_printf_long_double/meson.build | 50 + .../gl_cv_func_printf_precision/meson.build | 54 + .../meson.build | 24 + glib/gnulib/gl_extern_inline/meson.build | 103 + glib/gnulib/glib-gnulib.patch | 460 + glib/gnulib/gnulib_math.h.in | 2451 ++ glib/gnulib/isinf.c | 30 + glib/gnulib/isnan.c | 189 + glib/gnulib/isnand-nolibm.h | 33 + glib/gnulib/isnand.c | 22 + glib/gnulib/isnanf-nolibm.h | 40 + glib/gnulib/isnanf.c | 20 + glib/gnulib/isnanl-nolibm.h | 33 + glib/gnulib/isnanl.c | 23 + glib/gnulib/meson.build | 371 + glib/gnulib/printf-args.c | 189 + glib/gnulib/printf-args.h | 158 + glib/gnulib/printf-frexp.c | 190 + glib/gnulib/printf-frexp.h | 23 + glib/gnulib/printf-frexpl.c | 37 + glib/gnulib/printf-frexpl.h | 23 + glib/gnulib/printf-parse.c | 640 + glib/gnulib/printf-parse.h | 193 + glib/gnulib/printf.c | 145 + glib/gnulib/printf.h | 52 + glib/gnulib/signbitd.c | 64 + glib/gnulib/signbitf.c | 64 + glib/gnulib/signbitl.c | 64 + glib/gnulib/vasnprintf.c | 5632 ++++ glib/gnulib/vasnprintf.h | 79 + glib/gnulib/verify.h | 283 + glib/gnulib/xsize.c | 3 + glib/gnulib/xsize.h | 119 + glib/goption.c | 2761 ++ glib/goption.h | 406 + glib/gosxutils.m | 56 + glib/gpattern.c | 527 + glib/gpattern.h | 63 + glib/gpoll.c | 557 + glib/gpoll.h | 120 + glib/gprimes.c | 96 + glib/gprimes.h | 50 + glib/gprintf.c | 370 + glib/gprintf.h | 57 + glib/gprintfint.h | 56 + glib/gqsort.c | 303 + glib/gqsort.h | 45 + glib/gquark.c | 374 + glib/gquark.h | 68 + glib/gqueue.c | 1177 + glib/gqueue.h | 203 + glib/grand.c | 730 + glib/grand.h | 99 + glib/grcbox.c | 502 + glib/grcbox.h | 89 + glib/grcboxprivate.h | 71 + glib/grefcount.c | 294 + glib/grefcount.h | 123 + glib/grefstring.c | 302 + glib/grefstring.h | 57 + glib/gregex.c | 3197 ++ glib/gregex.h | 609 + glib/gscanner.c | 2267 ++ glib/gscanner.h | 299 + glib/gscripttable.h | 3342 ++ glib/gsequence.c | 2085 ++ glib/gsequence.h | 173 + glib/gshell.c | 731 + glib/gshell.h | 57 + glib/gslice.c | 1799 ++ glib/gslice.h | 115 + glib/gslist.c | 1117 + glib/gslist.h | 164 + glib/gspawn-private.h | 115 + glib/gspawn-win32-helper.c | 462 + glib/gspawn-win32.c | 1590 + glib/gspawn.c | 2890 ++ glib/gspawn.h | 288 + glib/gstdio-private.c | 166 + glib/gstdio.c | 1784 ++ glib/gstdio.h | 181 + glib/gstdioprivate.h | 72 + glib/gstrfuncs.c | 3500 +++ glib/gstrfuncs.h | 366 + glib/gstring.c | 1266 + glib/gstring.h | 192 + glib/gstringchunk.c | 298 + glib/gstringchunk.h | 57 + glib/gstrvbuilder.c | 178 + glib/gstrvbuilder.h | 67 + glib/gtester-report.in | 498 + glib/gtester.c | 765 + glib/gtestutils.c | 4464 +++ glib/gtestutils.h | 704 + glib/gthread-posix.c | 1664 + glib/gthread-win32.c | 753 + glib/gthread.c | 1121 + glib/gthread.h | 601 + glib/gthreadpool.c | 1221 + glib/gthreadpool.h | 103 + glib/gthreadprivate.h | 89 + glib/gtimer.c | 657 + glib/gtimer.h | 78 + glib/gtimezone.c | 2456 ++ glib/gtimezone.h | 96 + glib/gtrace-private.h | 80 + glib/gtrace.c | 177 + glib/gtranslit-data.h | 12 + glib/gtranslit.c | 408 + glib/gtrashstack.c | 152 + glib/gtrashstack.h | 58 + glib/gtree.c | 1792 ++ glib/gtree.h | 179 + glib/gtypes.h | 587 + glib/gunibreak.c | 59 + glib/gunibreak.h | 26020 ++++++++++++++++ glib/gunichartables.h | 20122 ++++++++++++ glib/gunicode.h | 962 + glib/gunicodeprivate.h | 32 + glib/gunicollate.c | 687 + glib/gunicomp.h | 1008 + glib/gunidecomp.c | 767 + glib/gunidecomp.h | 14022 +++++++++ glib/guniprop.c | 1575 + glib/guri.c | 2890 ++ glib/guri.h | 418 + glib/guriprivate.h | 36 + glib/gutf8.c | 1870 ++ glib/gutils.c | 3208 ++ glib/gutils.h | 489 + glib/gutilsprivate.h | 57 + glib/guuid.c | 211 + glib/guuid.h | 42 + glib/gvalgrind.h | 32 + glib/gvariant-core.c | 1229 + glib/gvariant-core.h | 39 + glib/gvariant-internal.h | 68 + glib/gvariant-parser.c | 2878 ++ glib/gvariant-serialiser.c | 1751 ++ glib/gvariant-serialiser.h | 76 + glib/gvariant.c | 6085 ++++ glib/gvariant.h | 539 + glib/gvarianttype.c | 1290 + glib/gvarianttype.h | 382 + glib/gvarianttypeinfo.c | 894 + glib/gvarianttypeinfo.h | 161 + glib/gversion.c | 193 + glib/gversion.h | 55 + glib/gversionmacros.h | 1167 + glib/gwakeup.c | 274 + glib/gwakeup.h | 35 + glib/gwin32-private.c | 78 + glib/gwin32.c | 1458 + glib/gwin32.h | 140 + glib/libcharset/.gitignore | 3 + glib/libcharset/README | 44 + glib/libcharset/codeset.m4 | 21 + glib/libcharset/config.charset | 672 + glib/libcharset/glibc21.m4 | 30 + glib/libcharset/libcharset-glib.patch | 77 + glib/libcharset/libcharset.h | 46 + glib/libcharset/localcharset.c | 461 + glib/libcharset/localcharset.h | 43 + glib/libcharset/make-patch.sh | 28 + glib/libcharset/meson.build | 4 + glib/libcharset/ref-add.sin | 31 + glib/libcharset/ref-del.sin | 26 + glib/libcharset/update.sh | 33 + glib/libglib-gdb.py.in | 10 + glib/meson.build | 495 + glib/tests/.gitignore | 89 + glib/tests/1bit-mutex.c | 165 + glib/tests/4096-random-bytes | 45 + glib/tests/642026.c | 102 + glib/tests/array-test.c | 2111 ++ glib/tests/asyncqueue.c | 526 + glib/tests/atomic.c | 314 + glib/tests/autoptr.c | 767 + glib/tests/base64.c | 542 + glib/tests/bitlock.c | 39 + glib/tests/bookmarkfile.c | 728 + glib/tests/bookmarks.xbel | 23 + glib/tests/bookmarks/fail-01.xbel | 0 glib/tests/bookmarks/fail-02.xbel | 2 + glib/tests/bookmarks/fail-03.xbel | 18 + glib/tests/bookmarks/fail-04.xbel | 21 + glib/tests/bookmarks/fail-05.xbel | 21 + glib/tests/bookmarks/fail-06.xbel | 19 + glib/tests/bookmarks/fail-07.xbel | 21 + glib/tests/bookmarks/fail-08.xbel | 18 + glib/tests/bookmarks/fail-09.xbel | 20 + glib/tests/bookmarks/fail-10.xbel | 21 + glib/tests/bookmarks/fail-11.xbel | 22 + glib/tests/bookmarks/fail-12.xbel | 22 + glib/tests/bookmarks/fail-13.xbel | 22 + glib/tests/bookmarks/fail-14.xbel | 24 + glib/tests/bookmarks/fail-15.xbel | 23 + glib/tests/bookmarks/fail-16.xbel | 24 + glib/tests/bookmarks/fail-17.xbel | 22 + glib/tests/bookmarks/fail-18.xbel | 1 + glib/tests/bookmarks/fail-19.xbel | 1 + glib/tests/bookmarks/fail-20.xbel | 1 + glib/tests/bookmarks/fail-21.xbel | 1 + glib/tests/bookmarks/fail-22.xbel | 1 + glib/tests/bookmarks/fail-23.xbel | 1 + glib/tests/bookmarks/fail-24.xbel | 1 + glib/tests/bookmarks/fail-25.xbel | 1 + glib/tests/bookmarks/fail-26.xbel | 1 + glib/tests/bookmarks/fail-27.xbel | 1 + glib/tests/bookmarks/fail-28.xbel | 1 + glib/tests/bookmarks/fail-29.xbel | 1 + glib/tests/bookmarks/fail-30.xbel | 1 + glib/tests/bookmarks/fail-31.xbel | 1 + glib/tests/bookmarks/fail-32.xbel | 1 + glib/tests/bookmarks/fail-33.xbel | 1 + glib/tests/bookmarks/fail-34.xbel | 1 + glib/tests/bookmarks/fail-35.xbel | 1 + glib/tests/bookmarks/fail-36.xbel | 1 + glib/tests/bookmarks/fail-37.xbel | 1 + glib/tests/bookmarks/fail-38.xbel | 1 + glib/tests/bookmarks/fail-39.xbel | 1 + glib/tests/bookmarks/fail-40.xbel | 1 + glib/tests/bookmarks/fail-41.xbel | 1 + glib/tests/bookmarks/fail-42.xbel | 1 + glib/tests/bookmarks/valid-01.xbel | 22 + glib/tests/bookmarks/valid-02.xbel | 17 + glib/tests/bookmarks/valid-03.xbel | 22 + glib/tests/bytes.c | 512 + glib/tests/cache.c | 167 + glib/tests/casefold.txt | 1499 + glib/tests/casemap.txt | 4023 +++ glib/tests/charset.c | 83 + glib/tests/checksum.c | 1213 + glib/tests/collate.c | 314 + glib/tests/completion.c | 102 + glib/tests/cond.c | 381 + glib/tests/convert.c | 969 + glib/tests/cxx.cpp | 104 + glib/tests/dataset.c | 270 + glib/tests/date.c | 1811 ++ glib/tests/dir.c | 53 + glib/tests/echo-script | 2 + glib/tests/echo-script.bat | 2 + glib/tests/empty | 0 glib/tests/environment.c | 305 + glib/tests/error.c | 409 + glib/tests/fileutils.c | 2468 ++ glib/tests/gdatetime.c | 3193 ++ glib/tests/gen-casefold-txt.py | 83 + glib/tests/gen-casemap-txt.py | 240 + glib/tests/getpwuid-preload.c | 45 + glib/tests/gpoll.c | 624 + glib/tests/gutils-user-database.c | 42 + glib/tests/guuid.c | 70 + glib/tests/gvariant.c | 5206 ++++ glib/tests/gwakeuptest.c | 276 + glib/tests/hash.c | 1742 ++ glib/tests/hmac.c | 550 + glib/tests/hook.c | 94 + glib/tests/hostutils.c | 367 + glib/tests/include.c | 26 + glib/tests/io-channel.c | 222 + glib/tests/iochannel-test-infile | 5 + glib/tests/keyfile.c | 1876 ++ glib/tests/keyfiletest.ini | 4 + glib/tests/list.c | 659 + glib/tests/logging.c | 668 + glib/tests/macros.c | 71 + glib/tests/mainloop.c | 2394 ++ glib/tests/mappedfile.c | 205 + glib/tests/markup-collect.c | 238 + glib/tests/markup-escape.c | 169 + glib/tests/markup-parse.c | 348 + glib/tests/markup-subparser.c | 385 + glib/tests/markup.c | 98 + glib/tests/markups/fail-1.expected | 1 + glib/tests/markups/fail-1.gmarkup | 0 glib/tests/markups/fail-10.expected | 4 + glib/tests/markups/fail-10.gmarkup | 2 + glib/tests/markups/fail-11.expected | 7 + glib/tests/markups/fail-11.gmarkup | 4 + glib/tests/markups/fail-12.expected | 1 + glib/tests/markups/fail-12.gmarkup | 1 + glib/tests/markups/fail-13.expected | 1 + glib/tests/markups/fail-13.gmarkup | 1 + glib/tests/markups/fail-14.expected | 4 + glib/tests/markups/fail-14.gmarkup | 2 + glib/tests/markups/fail-15.expected | 8 + glib/tests/markups/fail-15.gmarkup | 3 + glib/tests/markups/fail-16.expected | 2 + glib/tests/markups/fail-16.gmarkup | 1 + glib/tests/markups/fail-17.expected | 1 + glib/tests/markups/fail-17.gmarkup | 1 + glib/tests/markups/fail-18.expected | 1 + glib/tests/markups/fail-18.gmarkup | 1 + glib/tests/markups/fail-19.expected | 1 + glib/tests/markups/fail-19.gmarkup | 1 + glib/tests/markups/fail-2.expected | 1 + glib/tests/markups/fail-2.gmarkup | 1 + glib/tests/markups/fail-20.expected | 1 + glib/tests/markups/fail-20.gmarkup | 1 + glib/tests/markups/fail-21.expected | 1 + glib/tests/markups/fail-21.gmarkup | 1 + glib/tests/markups/fail-22.expected | 2 + glib/tests/markups/fail-22.gmarkup | 1 + glib/tests/markups/fail-23.expected | 4 + glib/tests/markups/fail-23.gmarkup | 2 + glib/tests/markups/fail-24.expected | 1 + glib/tests/markups/fail-24.gmarkup | 1 + glib/tests/markups/fail-25.expected | 1 + glib/tests/markups/fail-25.gmarkup | 1 + glib/tests/markups/fail-26.expected | 2 + glib/tests/markups/fail-26.gmarkup | 1 + glib/tests/markups/fail-27.expected | 2 + glib/tests/markups/fail-27.gmarkup | 1 + glib/tests/markups/fail-28.expected | 2 + glib/tests/markups/fail-28.gmarkup | 1 + glib/tests/markups/fail-29.expected | 2 + glib/tests/markups/fail-29.gmarkup | 1 + glib/tests/markups/fail-3.expected | 50 + glib/tests/markups/fail-3.gmarkup | 49 + glib/tests/markups/fail-30.expected | 2 + glib/tests/markups/fail-30.gmarkup | 1 + glib/tests/markups/fail-31.expected | 2 + glib/tests/markups/fail-31.gmarkup | 1 + glib/tests/markups/fail-32.expected | 2 + glib/tests/markups/fail-32.gmarkup | 1 + glib/tests/markups/fail-33.expected | 2 + glib/tests/markups/fail-33.gmarkup | 1 + glib/tests/markups/fail-34.expected | 2 + glib/tests/markups/fail-34.gmarkup | 1 + glib/tests/markups/fail-35.expected | 2 + glib/tests/markups/fail-35.gmarkup | 1 + glib/tests/markups/fail-36.expected | 4 + glib/tests/markups/fail-36.gmarkup | 1 + glib/tests/markups/fail-37.expected | 1 + glib/tests/markups/fail-37.gmarkup | 1 + glib/tests/markups/fail-38.expected | 3 + glib/tests/markups/fail-38.gmarkup | 1 + glib/tests/markups/fail-39.expected | 3 + glib/tests/markups/fail-39.gmarkup | 1 + glib/tests/markups/fail-4.expected | 1 + glib/tests/markups/fail-4.gmarkup | 1 + glib/tests/markups/fail-40.expected | 2 + glib/tests/markups/fail-40.gmarkup | 1 + glib/tests/markups/fail-41.expected | 1 + glib/tests/markups/fail-41.gmarkup | 3 + glib/tests/markups/fail-42.expected | 1 + glib/tests/markups/fail-42.gmarkup | 5 + glib/tests/markups/fail-43.expected | 1 + glib/tests/markups/fail-43.gmarkup | 1 + glib/tests/markups/fail-44.expected | 2 + glib/tests/markups/fail-44.gmarkup | 1 + glib/tests/markups/fail-45.expected | 3 + glib/tests/markups/fail-45.gmarkup | 1 + glib/tests/markups/fail-46.expected | 2 + glib/tests/markups/fail-46.gmarkup | 2 + glib/tests/markups/fail-47.expected | 1 + glib/tests/markups/fail-47.gmarkup | 1 + glib/tests/markups/fail-48.expected | 1 + glib/tests/markups/fail-48.gmarkup | 2 + glib/tests/markups/fail-49.expected | 3 + glib/tests/markups/fail-49.gmarkup | 1 + glib/tests/markups/fail-5.expected | 1 + glib/tests/markups/fail-5.gmarkup | 2 + glib/tests/markups/fail-50.expected | 1 + glib/tests/markups/fail-50.gmarkup | 1 + glib/tests/markups/fail-51.expected | 1 + glib/tests/markups/fail-51.gmarkup | 1 + glib/tests/markups/fail-52.expected | 1 + glib/tests/markups/fail-52.gmarkup | 1 + glib/tests/markups/fail-53.expected | 2 + glib/tests/markups/fail-53.gmarkup | 1 + glib/tests/markups/fail-54.expected | 1 + glib/tests/markups/fail-54.gmarkup | 1 + glib/tests/markups/fail-6.expected | 1 + glib/tests/markups/fail-6.gmarkup | 2 + glib/tests/markups/fail-7.expected | 1 + glib/tests/markups/fail-7.gmarkup | 2 + glib/tests/markups/fail-8.expected | 2 + glib/tests/markups/fail-8.gmarkup | 2 + glib/tests/markups/fail-9.expected | 1 + glib/tests/markups/fail-9.gmarkup | 2 + glib/tests/markups/valid-1.expected | 37 + glib/tests/markups/valid-1.gmarkup | 9 + glib/tests/markups/valid-10.expected | 6 + glib/tests/markups/valid-10.gmarkup | 6 + glib/tests/markups/valid-11.expected | 3 + glib/tests/markups/valid-11.gmarkup | 2 + glib/tests/markups/valid-12.expected | 5 + glib/tests/markups/valid-12.gmarkup | 3 + glib/tests/markups/valid-13.expected | 4 + glib/tests/markups/valid-13.gmarkup | 3 + glib/tests/markups/valid-14.expected | 29 + glib/tests/markups/valid-14.gmarkup | 23 + glib/tests/markups/valid-15.expected | 3 + glib/tests/markups/valid-15.gmarkup | 1 + glib/tests/markups/valid-16.cdata-as-text | 42 + glib/tests/markups/valid-16.expected | 42 + glib/tests/markups/valid-16.gmarkup | 10 + glib/tests/markups/valid-17.expected | 6 + glib/tests/markups/valid-17.gmarkup | 2 + glib/tests/markups/valid-2.expected | 51 + glib/tests/markups/valid-2.gmarkup | 49 + glib/tests/markups/valid-3.expected | 61 + glib/tests/markups/valid-3.gmarkup | 10 + glib/tests/markups/valid-4.expected | 29 + glib/tests/markups/valid-4.gmarkup | 8 + glib/tests/markups/valid-5.expected | 4 + glib/tests/markups/valid-5.gmarkup | 2 + glib/tests/markups/valid-6.expected | 6 + glib/tests/markups/valid-6.gmarkup | 4 + glib/tests/markups/valid-7.expected | 4 + glib/tests/markups/valid-7.gmarkup | 2 + glib/tests/markups/valid-8.cdata-as-text | 5 + glib/tests/markups/valid-8.expected | 5 + glib/tests/markups/valid-8.gmarkup | 1 + glib/tests/markups/valid-9.expected | 3 + glib/tests/markups/valid-9.gmarkup | 2 + glib/tests/mem-overflow.c | 258 + glib/tests/memchunk.c | 64 + glib/tests/meson.build | 326 + glib/tests/mutex.c | 241 + glib/tests/node.c | 522 + glib/tests/once.c | 217 + glib/tests/option-argv0.c | 111 + glib/tests/option-context.c | 2711 ++ glib/tests/overflow.c | 199 + glib/tests/pages.ini | 92 + glib/tests/path-test-subdir/meson.build | 6 + .../path-test-subdir/spawn-test-helper.c | 7 + glib/tests/pattern.c | 271 + glib/tests/private.c | 403 + glib/tests/protocol.c | 382 + glib/tests/queue.c | 1298 + glib/tests/rand.c | 181 + glib/tests/rcbox.c | 298 + glib/tests/rec-mutex.c | 257 + glib/tests/refcount.c | 222 + glib/tests/refstring.c | 116 + glib/tests/regex.c | 2867 ++ glib/tests/relation.c | 128 + glib/tests/rwlock.c | 289 + glib/tests/scannerapi.c | 142 + glib/tests/search-utils.c | 126 + glib/tests/sequence.c | 1402 + glib/tests/shell.c | 216 + glib/tests/slice-color.c | 133 + glib/tests/slice-concurrent.c | 130 + glib/tests/slice.c | 167 + glib/tests/slist.c | 463 + glib/tests/sort.c | 152 + glib/tests/spawn-multithreaded.c | 445 + glib/tests/spawn-path-search-helper.c | 171 + glib/tests/spawn-path-search.c | 490 + glib/tests/spawn-singlethread.c | 533 + glib/tests/spawn-test-helper.c | 7 + glib/tests/strfuncs.c | 2602 ++ glib/tests/string.c | 627 + glib/tests/strvbuilder.c | 117 + glib/tests/test-printf.c | 987 + glib/tests/test-spawn-echo.c | 39 + glib/tests/test-spawn-sleep.c | 32 + glib/tests/testing-helper.c | 192 + glib/tests/testing.c | 1733 + glib/tests/thread-pool.c | 268 + glib/tests/thread.c | 226 + glib/tests/time-zones/Amsterdam-fat | Bin 0 -> 2910 bytes glib/tests/time-zones/Amsterdam-slim | Bin 0 -> 1071 bytes glib/tests/timeout.c | 202 + glib/tests/timer.c | 363 + glib/tests/tree.c | 728 + glib/tests/types.c | 154 + glib/tests/unicode.c | 1858 ++ glib/tests/unix.c | 352 + glib/tests/uri.c | 2057 ++ glib/tests/utf8-misc.c | 177 + glib/tests/utf8-performance.c | 247 + glib/tests/utf8-pointer.c | 188 + glib/tests/utf8-validate.c | 377 + glib/tests/utils.c | 1184 + glib/tests/win32.c | 177 + glib/update-gtranslit.py | 456 + glib/valgrind.h | 6648 ++++ glib/win_iconv.c | 2098 ++ gmodule/AUTHORS | 1 + gmodule/COPYING | 502 + gmodule/gmodule-ar.c | 182 + gmodule/gmodule-dl.c | 225 + gmodule/gmodule-win32.c | 237 + gmodule/gmodule.c | 910 + gmodule/gmodule.h | 142 + gmodule/gmodule.rc.in | 30 + gmodule/gmoduleconf.h.in | 48 + gmodule/meson.build | 137 + gmodule/tests/cxx.cpp | 26 + gmodule/tests/meson.build | 47 + gobject/gatomicarray.c | 172 + gobject/gatomicarray.h | 58 + gobject/gbinding.c | 1637 + gobject/gbinding.h | 154 + gobject/gbindinggroup.c | 679 + gobject/gbindinggroup.h | 85 + gobject/gboxed.c | 565 + gobject/gboxed.h | 122 + gobject/gclosure.c | 1990 ++ gobject/gclosure.h | 321 + gobject/genums.c | 760 + gobject/genums.h | 279 + gobject/glib-enumtypes.c.template | 47 + gobject/glib-enumtypes.h.template | 24 + gobject/glib-genmarshal.in | 1080 + gobject/glib-mkenums.in | 806 + gobject/glib-types.h | 395 + gobject/gmarshal.c | 2521 ++ gobject/gmarshal.h | 434 + gobject/gobject-autocleanups.h | 31 + gobject/gobject-query.c | 223 + gobject/gobject.c | 4871 +++ gobject/gobject.h | 946 + gobject/gobject.rc.in | 30 + gobject/gobject.stp.in | 199 + gobject/gobject_gdb.py | 352 + gobject/gobject_probes.d | 13 + gobject/gobject_trace.h | 43 + gobject/gobjectnotifyqueue.c | 197 + gobject/gparam.c | 1619 + gobject/gparam.h | 458 + gobject/gparamspecs.c | 2622 ++ gobject/gparamspecs.h | 1173 + gobject/gsignal.c | 4075 +++ gobject/gsignal.h | 640 + gobject/gsignalgroup.c | 912 + gobject/gsignalgroup.h | 93 + gobject/gsourceclosure.c | 322 + gobject/gsourceclosure.h | 38 + gobject/gtype-private.h | 113 + gobject/gtype.c | 5024 +++ gobject/gtype.h | 2515 ++ gobject/gtypemodule.c | 602 + gobject/gtypemodule.h | 300 + gobject/gtypeplugin.c | 203 + gobject/gtypeplugin.h | 134 + gobject/gvalue.c | 675 + gobject/gvalue.h | 210 + gobject/gvaluearray.c | 370 + gobject/gvaluearray.h | 104 + gobject/gvaluecollector.h | 265 + gobject/gvaluetransform.c | 428 + gobject/gvaluetypes.c | 1471 + gobject/gvaluetypes.h | 316 + gobject/libgobject-gdb.py.in | 10 + gobject/meson.build | 190 + gobject/tests/.gitignore | 18 + gobject/tests/autoptr.c | 237 + gobject/tests/binding.c | 1102 + gobject/tests/bindinggroup.c | 694 + gobject/tests/boxed.c | 704 + gobject/tests/closure-refcount.c | 337 + gobject/tests/closure.c | 223 + gobject/tests/cxx.cpp | 26 + gobject/tests/dynamictests.c | 368 + gobject/tests/enums.c | 170 + gobject/tests/flags.c | 179 + gobject/tests/genmarshal.py | 817 + gobject/tests/ifaceproperties.c | 645 + gobject/tests/marshalers.list | 3 + gobject/tests/meson.build | 161 + gobject/tests/mkenums.py | 739 + gobject/tests/object.c | 150 + gobject/tests/param.c | 1266 + gobject/tests/private.c | 261 + gobject/tests/properties.c | 658 + gobject/tests/qdata.c | 123 + gobject/tests/reference.c | 973 + gobject/tests/signal-handler.c | 299 + gobject/tests/signalgroup.c | 650 + gobject/tests/signals.c | 1828 ++ gobject/tests/taptestrunner.py | 186 + gobject/tests/testcommon.h | 105 + gobject/tests/testing.c | 71 + gobject/tests/threadtests.c | 525 + gobject/tests/type-flags.c | 88 + gobject/tests/type.c | 215 + gobject/tests/value.c | 752 + gthread/gthread-impl.c | 48 + gthread/gthread.def | 3 + gthread/gthread.rc.in | 30 + gthread/meson.build | 40 + m4macros/attributes.m4 | 288 + m4macros/glib-2.0.m4 | 215 + m4macros/glib-gettext.m4 | 486 + m4macros/glibtests.m4 | 31 + m4macros/gsettings.m4 | 88 + meson.build | 2455 ++ meson_options.txt | 124 + msvc_recommended_pragmas.h | 41 + po/LINGUAS | 100 + po/Makefile.in.in | 268 + po/POTFILES.in | 205 + po/POTFILES.skip | 2 + po/af.po | 3818 +++ po/am.po | 3731 +++ po/an.po | 4568 +++ po/ar.po | 4275 +++ po/as.po | 4808 +++ po/ast.po | 3821 +++ po/az.po | 3817 +++ po/be.po | 4509 +++ po/be@latin.po | 4125 +++ po/bg.po | 6380 ++++ po/bn.po | 3802 +++ po/bn_IN.po | 4796 +++ po/bs.po | 4680 +++ po/ca.po | 6478 ++++ po/ca@valencia.po | 5897 ++++ po/cs.po | 6296 ++++ po/cy.po | 3850 +++ po/da.po | 6333 ++++ po/de.po | 6473 ++++ po/dz.po | 3833 +++ po/el.po | 6893 ++++ po/en@shaw.po | 3809 +++ po/en_CA.po | 4018 +++ po/en_GB.po | 6605 ++++ po/eo.po | 5984 ++++ po/es.po | 6825 ++++ po/et.po | 5932 ++++ po/eu.po | 6094 ++++ po/fa.po | 6295 ++++ po/fi.po | 6861 ++++ po/fr.po | 6539 ++++ po/fur.po | 6199 ++++ po/ga.po | 3840 +++ po/gd.po | 5457 ++++ po/gl.po | 6423 ++++ po/gu.po | 4666 +++ po/he.po | 6267 ++++ po/hi.po | 4828 +++ po/hr.po | 6291 ++++ po/hu.po | 6348 ++++ po/hy.po | 3956 +++ po/id.po | 6297 ++++ po/is.po | 4628 +++ po/it.po | 6486 ++++ po/ja.po | 6278 ++++ po/ka.po | 6035 ++++ po/kk.po | 6017 ++++ po/kn.po | 4764 +++ po/ko.po | 6222 ++++ po/ku.po | 3721 +++ po/lt.po | 6438 ++++ po/lv.po | 6244 ++++ po/mai.po | 3845 +++ po/meson.build | 5 + po/mg.po | 3845 +++ po/mk.po | 3874 +++ po/ml.po | 4520 +++ po/mn.po | 3852 +++ po/mr.po | 4789 +++ po/ms.po | 6222 ++++ po/nb.po | 5701 ++++ po/nds.po | 3707 +++ po/ne.po | 6344 ++++ po/nl.po | 6241 ++++ po/nn.po | 3916 +++ po/oc.po | 7028 +++++ po/or.po | 4843 +++ po/pa.po | 6745 ++++ po/pl.po | 6402 ++++ po/po2tbl.sed.in | 101 + po/ps.po | 3744 +++ po/pt.po | 6715 ++++ po/pt_BR.po | 6654 ++++ po/ro.po | 6625 ++++ po/ru.po | 6371 ++++ po/rw.po | 3892 +++ po/si.po | 3769 +++ po/sk.po | 6572 ++++ po/sl.po | 6451 ++++ po/sq.po | 4294 +++ po/sr.po | 6467 ++++ po/sr@ije.po | 3830 +++ po/sr@latin.po | 6010 ++++ po/sv.po | 6407 ++++ po/ta.po | 4859 +++ po/te.po | 4804 +++ po/tg.po | 4258 +++ po/th.po | 5510 ++++ po/tl.po | 3870 +++ po/tr.po | 6521 ++++ po/tt.po | 3751 +++ po/ug.po | 4389 +++ po/uk.po | 6381 ++++ po/vi.po | 4891 +++ po/wa.po | 3770 +++ po/xh.po | 3859 +++ po/yi.po | 3817 +++ po/zh_CN.po | 6358 ++++ po/zh_HK.po | 4527 +++ po/zh_TW.po | 6068 ++++ subprojects/gtk-doc.wrap | 5 + subprojects/libffi.wrap | 5 + subprojects/pcre.wrap | 11 + subprojects/proxy-libintl.wrap | 5 + subprojects/sysprof.wrap | 5 + subprojects/zlib.wrap | 11 + template-tap.test.in | 4 + template.test.in | 3 + tests/assert-msg-test.c | 7 + tests/assert-msg-test.gdb | 5 + tests/collate/collate-1.file | 9 + tests/collate/collate-1.in | 9 + tests/collate/collate-1.unicode | 9 + tests/collate/collate-2.file | 13 + tests/collate/collate-2.in | 13 + tests/collate/collate-2.unicode | 13 + tests/gio-test.c | 421 + tests/gobject/.gitignore | 15 + tests/gobject/accumulator.c | 307 + tests/gobject/defaultiface.c | 199 + tests/gobject/deftype.c | 59 + tests/gobject/dynamictype.c | 175 + tests/gobject/meson.build | 98 + tests/gobject/override.c | 418 + tests/gobject/performance-threaded.c | 375 + tests/gobject/performance.c | 1060 + tests/gobject/references.c | 280 + tests/gobject/signals.c | 134 + tests/gobject/singleton.c | 84 + tests/gobject/testcommon.h | 105 + tests/gobject/testgobject.c | 445 + tests/gobject/testmarshal.list | 4 + tests/gobject/testmodule.c | 66 + tests/gobject/testmodule.h | 55 + tests/gobject/timeloop-closure.c | 228 + tests/libmoduletestplugin_a.c | 75 + tests/libmoduletestplugin_b.c | 76 + tests/mainloop-test.c | 442 + tests/mapping-test.c | 321 + tests/memchunks.c | 603 + tests/meson.build | 139 + tests/module-test.c | 214 + tests/onceinit.c | 273 + tests/refcount/meson.build | 60 + tests/refcount/objects.c | 163 + tests/refcount/objects2.c | 121 + tests/refcount/properties.c | 237 + tests/refcount/properties2.c | 202 + tests/refcount/properties3.c | 202 + tests/refcount/properties4.c | 173 + tests/refcount/signals.c | 308 + tests/run-assert-msg-test.sh | 49 + tests/slice-test.c | 303 + tests/slice-threadinit.c | 166 + tests/spawn-test-win32-gui.c | 88 + tests/spawn-test.c | 352 + tests/thread-test.c | 400 + tests/threadpool-test.c | 465 + tests/timeloop-basic.c | 236 + tests/timeloop.c | 221 + tests/unicode-encoding.c | 444 + tests/unicode-normalize.c | 210 + tests/utf8.txt | 291 + 2003 files changed, 1332420 insertions(+) create mode 100644 .clang-format create mode 100644 .dir-locals.el create mode 100644 .editorconfig create mode 100644 AUTHORS create mode 100644 CONTRIBUTING.md create mode 100644 COPYING create mode 100644 HACKING create mode 100644 INSTALL.in create mode 100644 NEWS create mode 100644 NEWS.pre-1-3 create mode 100644 README create mode 100644 README.md create mode 100644 README.rationale create mode 100644 README.win32 create mode 100644 README.win32.md create mode 100644 SECURITY.md create mode 100755 check-abis.sh create mode 100755 clang-format-diff.py create mode 100644 docs/CODEOWNERS create mode 100644 docs/debugging.txt create mode 100644 docs/macros.txt create mode 100644 docs/reference/.gitignore create mode 100644 docs/reference/AUTHORS create mode 100644 docs/reference/COPYING create mode 100644 docs/reference/NEWS create mode 100644 docs/reference/gio/.gitignore create mode 100644 docs/reference/gio/concat-files-helper.py create mode 100644 docs/reference/gio/gapplication.xml create mode 100644 docs/reference/gio/gdbus-codegen.xml create mode 100644 docs/reference/gio/gdbus-object-manager-example/.gitignore create mode 100644 docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-docs.xml create mode 100644 docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.txt create mode 100644 docs/reference/gio/gdbus-object-manager-example/meson.build create mode 100644 docs/reference/gio/gdbus.xml create mode 100644 docs/reference/gio/gio-docs-unix.xml create mode 100644 docs/reference/gio/gio-docs-win32.xml create mode 100644 docs/reference/gio/gio-docs.xml create mode 100644 docs/reference/gio/gio-querymodules.xml create mode 100644 docs/reference/gio/gio-sections-common.txt create mode 100644 docs/reference/gio/gio-sections-win32.txt create mode 100644 docs/reference/gio/gio.xml create mode 100644 docs/reference/gio/glib-compile-resources.xml create mode 100644 docs/reference/gio/glib-compile-schemas.xml create mode 100644 docs/reference/gio/gresource.xml create mode 100644 docs/reference/gio/gsettings.xml create mode 100644 docs/reference/gio/gvfs-overview.odg create mode 100644 docs/reference/gio/gvfs-overview.png create mode 100644 docs/reference/gio/menu-example.png create mode 100644 docs/reference/gio/menu-model.png create mode 100644 docs/reference/gio/meson.build create mode 100644 docs/reference/gio/migrating-gconf.xml create mode 100644 docs/reference/gio/migrating-gdbus.xml create mode 100644 docs/reference/gio/migrating-gnome-vfs.xml create mode 100644 docs/reference/gio/migrating-posix.xml create mode 100644 docs/reference/gio/overview.xml create mode 100644 docs/reference/gio/version.xml.in create mode 100644 docs/reference/gio/xml/gtkdocentities.ent.in create mode 100644 docs/reference/gio/xml/meson.build create mode 100644 docs/reference/glib/Sorted_binary_tree_breadth-first_traversal.svg create mode 100644 docs/reference/glib/Sorted_binary_tree_inorder.svg create mode 100644 docs/reference/glib/Sorted_binary_tree_postorder.svg create mode 100644 docs/reference/glib/Sorted_binary_tree_preorder.svg create mode 100644 docs/reference/glib/building.xml create mode 100644 docs/reference/glib/changes.xml create mode 100644 docs/reference/glib/compiling.xml create mode 100644 docs/reference/glib/cross.xml create mode 100644 docs/reference/glib/file-name-encodings.png create mode 100644 docs/reference/glib/file-name-encodings.sxd create mode 100644 docs/reference/glib/glib-docs.xml create mode 100644 docs/reference/glib/glib-gettextize.xml create mode 100644 docs/reference/glib/glib-overrides.txt create mode 100644 docs/reference/glib/glib-sections.txt create mode 100644 docs/reference/glib/gtester-report.xml create mode 100644 docs/reference/glib/gtester.xml create mode 100644 docs/reference/glib/gvariant-text.xml create mode 100644 docs/reference/glib/gvariant-varargs.xml create mode 100644 docs/reference/glib/mainloop-states.eps create mode 100644 docs/reference/glib/mainloop-states.fig create mode 100644 docs/reference/glib/mainloop-states.gif create mode 100644 docs/reference/glib/mainloop-states.png create mode 100644 docs/reference/glib/meson.build create mode 100644 docs/reference/glib/programming.xml create mode 100644 docs/reference/glib/regex-syntax.xml create mode 100644 docs/reference/glib/resources.xml create mode 100644 docs/reference/glib/running.xml create mode 100644 docs/reference/glib/version.xml.in create mode 100644 docs/reference/glib/xml/gtkdocentities.ent.in create mode 100644 docs/reference/glib/xml/meson.build create mode 100644 docs/reference/gobject/glib-genmarshal.xml create mode 100644 docs/reference/gobject/glib-mkenums.xml create mode 100644 docs/reference/gobject/gobject-docs.xml create mode 100644 docs/reference/gobject/gobject-overrides.txt create mode 100644 docs/reference/gobject/gobject-query.xml create mode 100644 docs/reference/gobject/gobject-sections.txt create mode 100644 docs/reference/gobject/images/glue.png create mode 100644 docs/reference/gobject/meson.build create mode 100644 docs/reference/gobject/tut_gobject.xml create mode 100644 docs/reference/gobject/tut_gsignal.xml create mode 100644 docs/reference/gobject/tut_gtype.xml create mode 100644 docs/reference/gobject/tut_howto.xml create mode 100644 docs/reference/gobject/tut_intro.xml create mode 100644 docs/reference/gobject/tut_tools.xml create mode 100644 docs/reference/gobject/version.xml.in create mode 100644 docs/reference/gobject/xml/gtkdocentities.ent.in create mode 100644 docs/reference/gobject/xml/meson.build create mode 100644 docs/reference/meson.build create mode 100644 fuzzing/README.md create mode 100644 fuzzing/driver.c create mode 100644 fuzzing/fuzz.h create mode 100644 fuzzing/fuzz_bookmark.c create mode 100644 fuzzing/fuzz_bookmark.corpus create mode 100644 fuzzing/fuzz_canonicalize_filename.c create mode 100644 fuzzing/fuzz_date_parse.c create mode 100644 fuzzing/fuzz_date_time_new_from_iso8601.c create mode 100644 fuzzing/fuzz_dbus_message.c create mode 100644 fuzzing/fuzz_inet_address_mask_new_from_string.c create mode 100644 fuzzing/fuzz_inet_address_new_from_string.c create mode 100644 fuzzing/fuzz_inet_socket_address_new_from_string.c create mode 100644 fuzzing/fuzz_key.c create mode 100644 fuzzing/fuzz_key.corpus create mode 100644 fuzzing/fuzz_network_address_parse.c create mode 100644 fuzzing/fuzz_network_address_parse_uri.c create mode 100644 fuzzing/fuzz_paths.c create mode 100644 fuzzing/fuzz_resolver.c create mode 100644 fuzzing/fuzz_uri_escape.c create mode 100644 fuzzing/fuzz_uri_parse.c create mode 100644 fuzzing/fuzz_uri_parse_params.c create mode 100644 fuzzing/fuzz_variant_binary.c create mode 100644 fuzzing/fuzz_variant_text.c create mode 100644 fuzzing/fuzz_variant_text.dict create mode 100644 fuzzing/meson.build create mode 100644 gio/completion/.gitignore create mode 100644 gio/completion/gapplication create mode 100644 gio/completion/gdbus create mode 100644 gio/completion/gio create mode 100644 gio/completion/gresource create mode 100644 gio/completion/gsettings create mode 100755 gio/data-to-c.py create mode 100644 gio/dbus-daemon.xml create mode 100644 gio/fam/gfamfilemonitor.c create mode 100644 gio/fam/gfamfilemonitor.map create mode 100644 gio/fam/meson.build create mode 100644 gio/gaction.c create mode 100644 gio/gaction.h create mode 100644 gio/gactiongroup.c create mode 100644 gio/gactiongroup.h create mode 100644 gio/gactiongroupexporter.c create mode 100644 gio/gactiongroupexporter.h create mode 100644 gio/gactionmap.c create mode 100644 gio/gactionmap.h create mode 100644 gio/gappinfo.c create mode 100644 gio/gappinfo.h create mode 100644 gio/gappinfoprivate.h create mode 100644 gio/gapplication-tool.c create mode 100644 gio/gapplication.c create mode 100644 gio/gapplication.h create mode 100644 gio/gapplicationcommandline.c create mode 100644 gio/gapplicationcommandline.h create mode 100644 gio/gapplicationimpl-dbus.c create mode 100644 gio/gapplicationimpl.h create mode 100644 gio/gasynchelper.c create mode 100644 gio/gasynchelper.h create mode 100644 gio/gasyncinitable.c create mode 100644 gio/gasyncinitable.h create mode 100644 gio/gasyncresult.c create mode 100644 gio/gasyncresult.h create mode 100644 gio/gbufferedinputstream.c create mode 100644 gio/gbufferedinputstream.h create mode 100644 gio/gbufferedoutputstream.c create mode 100644 gio/gbufferedoutputstream.h create mode 100644 gio/gbytesicon.c create mode 100644 gio/gbytesicon.h create mode 100644 gio/gcancellable.c create mode 100644 gio/gcancellable.h create mode 100644 gio/gcharsetconverter.c create mode 100644 gio/gcharsetconverter.h create mode 100644 gio/gcocoanotificationbackend.m create mode 100644 gio/gcontenttype-win32.c create mode 100644 gio/gcontenttype.c create mode 100644 gio/gcontenttype.h create mode 100644 gio/gcontenttypeprivate.h create mode 100644 gio/gcontextspecificgroup.c create mode 100644 gio/gcontextspecificgroup.h create mode 100644 gio/gconverter.c create mode 100644 gio/gconverter.h create mode 100644 gio/gconverterinputstream.c create mode 100644 gio/gconverterinputstream.h create mode 100644 gio/gconverteroutputstream.c create mode 100644 gio/gconverteroutputstream.h create mode 100644 gio/gcredentials.c create mode 100644 gio/gcredentials.h create mode 100644 gio/gcredentialsprivate.h create mode 100644 gio/gdatagrambased.c create mode 100644 gio/gdatagrambased.h create mode 100644 gio/gdatainputstream.c create mode 100644 gio/gdatainputstream.h create mode 100644 gio/gdataoutputstream.c create mode 100644 gio/gdataoutputstream.h create mode 100644 gio/gdbus-2.0/codegen/.flake8 create mode 100644 gio/gdbus-2.0/codegen/.gitignore create mode 100644 gio/gdbus-2.0/codegen/__init__.py create mode 100644 gio/gdbus-2.0/codegen/codegen.py create mode 100644 gio/gdbus-2.0/codegen/codegen_docbook.py create mode 100644 gio/gdbus-2.0/codegen/codegen_main.py create mode 100644 gio/gdbus-2.0/codegen/codegen_rst.py create mode 100644 gio/gdbus-2.0/codegen/config.py.in create mode 100644 gio/gdbus-2.0/codegen/dbustypes.py create mode 100755 gio/gdbus-2.0/codegen/gdbus-codegen.in create mode 100644 gio/gdbus-2.0/codegen/meson.build create mode 100644 gio/gdbus-2.0/codegen/parser.py create mode 100644 gio/gdbus-2.0/codegen/utils.py create mode 100644 gio/gdbus-tool.c create mode 100644 gio/gdbusactiongroup-private.h create mode 100644 gio/gdbusactiongroup.c create mode 100644 gio/gdbusactiongroup.h create mode 100644 gio/gdbusaddress.c create mode 100644 gio/gdbusaddress.h create mode 100644 gio/gdbusauth.c create mode 100644 gio/gdbusauth.h create mode 100644 gio/gdbusauthmechanism.c create mode 100644 gio/gdbusauthmechanism.h create mode 100644 gio/gdbusauthmechanismanon.c create mode 100644 gio/gdbusauthmechanismanon.h create mode 100644 gio/gdbusauthmechanismexternal.c create mode 100644 gio/gdbusauthmechanismexternal.h create mode 100644 gio/gdbusauthmechanismsha1.c create mode 100644 gio/gdbusauthmechanismsha1.h create mode 100644 gio/gdbusauthobserver.c create mode 100644 gio/gdbusauthobserver.h create mode 100644 gio/gdbusconnection.c create mode 100644 gio/gdbusconnection.h create mode 100644 gio/gdbusdaemon.c create mode 100644 gio/gdbusdaemon.h create mode 100644 gio/gdbuserror.c create mode 100644 gio/gdbuserror.h create mode 100644 gio/gdbusinterface.c create mode 100644 gio/gdbusinterface.h create mode 100644 gio/gdbusinterfaceskeleton.c create mode 100644 gio/gdbusinterfaceskeleton.h create mode 100644 gio/gdbusintrospection.c create mode 100644 gio/gdbusintrospection.h create mode 100644 gio/gdbusmenumodel.c create mode 100644 gio/gdbusmenumodel.h create mode 100644 gio/gdbusmessage.c create mode 100644 gio/gdbusmessage.h create mode 100644 gio/gdbusmethodinvocation.c create mode 100644 gio/gdbusmethodinvocation.h create mode 100644 gio/gdbusnameowning.c create mode 100644 gio/gdbusnameowning.h create mode 100644 gio/gdbusnamewatching.c create mode 100644 gio/gdbusnamewatching.h create mode 100644 gio/gdbusobject.c create mode 100644 gio/gdbusobject.h create mode 100644 gio/gdbusobjectmanager.c create mode 100644 gio/gdbusobjectmanager.h create mode 100644 gio/gdbusobjectmanagerclient.c create mode 100644 gio/gdbusobjectmanagerclient.h create mode 100644 gio/gdbusobjectmanagerserver.c create mode 100644 gio/gdbusobjectmanagerserver.h create mode 100644 gio/gdbusobjectproxy.c create mode 100644 gio/gdbusobjectproxy.h create mode 100644 gio/gdbusobjectskeleton.c create mode 100644 gio/gdbusobjectskeleton.h create mode 100644 gio/gdbusprivate.c create mode 100644 gio/gdbusprivate.h create mode 100644 gio/gdbusproxy.c create mode 100644 gio/gdbusproxy.h create mode 100644 gio/gdbusserver.c create mode 100644 gio/gdbusserver.h create mode 100644 gio/gdbusutils.c create mode 100644 gio/gdbusutils.h create mode 100644 gio/gdebugcontroller.c create mode 100644 gio/gdebugcontroller.h create mode 100644 gio/gdebugcontrollerdbus.c create mode 100644 gio/gdebugcontrollerdbus.h create mode 100644 gio/gdelayedsettingsbackend.c create mode 100644 gio/gdelayedsettingsbackend.h create mode 100644 gio/gdesktopappinfo.c create mode 100644 gio/gdesktopappinfo.h create mode 100644 gio/gdocumentportal.c create mode 100644 gio/gdocumentportal.h create mode 100644 gio/gdrive.c create mode 100644 gio/gdrive.h create mode 100644 gio/gdtlsclientconnection.c create mode 100644 gio/gdtlsclientconnection.h create mode 100644 gio/gdtlsconnection.c create mode 100644 gio/gdtlsconnection.h create mode 100644 gio/gdtlsserverconnection.c create mode 100644 gio/gdtlsserverconnection.h create mode 100644 gio/gdummyfile.c create mode 100644 gio/gdummyfile.h create mode 100644 gio/gdummyproxyresolver.c create mode 100644 gio/gdummyproxyresolver.h create mode 100644 gio/gdummytlsbackend.c create mode 100644 gio/gdummytlsbackend.h create mode 100644 gio/gemblem.c create mode 100644 gio/gemblem.h create mode 100644 gio/gemblemedicon.c create mode 100644 gio/gemblemedicon.h create mode 100644 gio/gfdonotificationbackend.c create mode 100644 gio/gfile.c create mode 100644 gio/gfile.h create mode 100644 gio/gfileattribute-priv.h create mode 100644 gio/gfileattribute.c create mode 100644 gio/gfileattribute.h create mode 100644 gio/gfiledescriptorbased.c create mode 100644 gio/gfiledescriptorbased.h create mode 100644 gio/gfileenumerator.c create mode 100644 gio/gfileenumerator.h create mode 100644 gio/gfileicon.c create mode 100644 gio/gfileicon.h create mode 100644 gio/gfileinfo-priv.h create mode 100644 gio/gfileinfo.c create mode 100644 gio/gfileinfo.h create mode 100644 gio/gfileinputstream.c create mode 100644 gio/gfileinputstream.h create mode 100644 gio/gfileiostream.c create mode 100644 gio/gfileiostream.h create mode 100644 gio/gfilemonitor.c create mode 100644 gio/gfilemonitor.h create mode 100644 gio/gfilenamecompleter.c create mode 100644 gio/gfilenamecompleter.h create mode 100644 gio/gfileoutputstream.c create mode 100644 gio/gfileoutputstream.h create mode 100644 gio/gfilterinputstream.c create mode 100644 gio/gfilterinputstream.h create mode 100644 gio/gfilteroutputstream.c create mode 100644 gio/gfilteroutputstream.h create mode 100644 gio/ggtknotificationbackend.c create mode 100644 gio/ghttpproxy.c create mode 100644 gio/ghttpproxy.h create mode 100644 gio/gicon.c create mode 100644 gio/gicon.h create mode 100644 gio/ginetaddress.c create mode 100644 gio/ginetaddress.h create mode 100644 gio/ginetaddressmask.c create mode 100644 gio/ginetaddressmask.h create mode 100644 gio/ginetsocketaddress.c create mode 100644 gio/ginetsocketaddress.h create mode 100644 gio/ginitable.c create mode 100644 gio/ginitable.h create mode 100644 gio/ginputstream.c create mode 100644 gio/ginputstream.h create mode 100644 gio/gio-autocleanups.h create mode 100644 gio/gio-querymodules-wrapper.py create mode 100644 gio/gio-querymodules.c create mode 100644 gio/gio-tool-cat.c create mode 100644 gio/gio-tool-copy.c create mode 100644 gio/gio-tool-info.c create mode 100644 gio/gio-tool-launch.c create mode 100644 gio/gio-tool-list.c create mode 100644 gio/gio-tool-mime.c create mode 100644 gio/gio-tool-mkdir.c create mode 100644 gio/gio-tool-monitor.c create mode 100644 gio/gio-tool-mount.c create mode 100644 gio/gio-tool-move.c create mode 100644 gio/gio-tool-open.c create mode 100644 gio/gio-tool-remove.c create mode 100644 gio/gio-tool-rename.c create mode 100644 gio/gio-tool-save.c create mode 100644 gio/gio-tool-set.c create mode 100644 gio/gio-tool-trash.c create mode 100644 gio/gio-tool-tree.c create mode 100644 gio/gio-tool.c create mode 100644 gio/gio-tool.h create mode 100644 gio/gio.h create mode 100644 gio/gio.rc.in create mode 100644 gio/gio.stp.in create mode 100644 gio/gio_probes.d create mode 100644 gio/gio_trace.h create mode 100644 gio/gioenums.h create mode 100644 gio/gioenumtypes.c.template create mode 100644 gio/gioenumtypes.h.template create mode 100644 gio/gioerror.c create mode 100644 gio/gioerror.h create mode 100644 gio/giomodule-priv.c create mode 100644 gio/giomodule-priv.h create mode 100644 gio/giomodule.c create mode 100644 gio/giomodule.h create mode 100644 gio/gioprivate.h create mode 100644 gio/gioscheduler.c create mode 100644 gio/gioscheduler.h create mode 100644 gio/giostream.c create mode 100644 gio/giostream.h create mode 100644 gio/giotypes.h create mode 100644 gio/giounix-private.c create mode 100644 gio/giounix-private.h create mode 100644 gio/giowin32-afunix.h create mode 100644 gio/giowin32-priv.h create mode 100644 gio/giowin32-private.c create mode 100644 gio/gkeyfilesettingsbackend.c create mode 100644 gio/glib-compile-resources.c create mode 100644 gio/glib-compile-schemas.c create mode 100644 gio/glistmodel.c create mode 100644 gio/glistmodel.h create mode 100644 gio/gliststore.c create mode 100644 gio/gliststore.h create mode 100644 gio/gloadableicon.c create mode 100644 gio/gloadableicon.h create mode 100644 gio/glocalfile.c create mode 100644 gio/glocalfile.h create mode 100644 gio/glocalfileenumerator.c create mode 100644 gio/glocalfileenumerator.h create mode 100644 gio/glocalfileinfo.c create mode 100644 gio/glocalfileinfo.h create mode 100644 gio/glocalfileinputstream.c create mode 100644 gio/glocalfileinputstream.h create mode 100644 gio/glocalfileiostream.c create mode 100644 gio/glocalfileiostream.h create mode 100644 gio/glocalfilemonitor.c create mode 100644 gio/glocalfilemonitor.h create mode 100644 gio/glocalfileoutputstream.c create mode 100644 gio/glocalfileoutputstream.h create mode 100644 gio/glocalvfs.c create mode 100644 gio/glocalvfs.h create mode 100644 gio/gmarshal-internal.c create mode 100644 gio/gmarshal-internal.h create mode 100644 gio/gmarshal-internal.list create mode 100644 gio/gmemoryinputstream.c create mode 100644 gio/gmemoryinputstream.h create mode 100644 gio/gmemorymonitor.c create mode 100644 gio/gmemorymonitor.h create mode 100644 gio/gmemorymonitordbus.c create mode 100644 gio/gmemorymonitordbus.h create mode 100644 gio/gmemorymonitorportal.c create mode 100644 gio/gmemorymonitorportal.h create mode 100644 gio/gmemorymonitorwin32.c create mode 100644 gio/gmemoryoutputstream.c create mode 100644 gio/gmemoryoutputstream.h create mode 100644 gio/gmemorysettingsbackend.c create mode 100644 gio/gmenu.c create mode 100644 gio/gmenu.h create mode 100644 gio/gmenuexporter.c create mode 100644 gio/gmenuexporter.h create mode 100644 gio/gmenumodel.c create mode 100644 gio/gmenumodel.h create mode 100644 gio/gmount.c create mode 100644 gio/gmount.h create mode 100644 gio/gmountoperation.c create mode 100644 gio/gmountoperation.h create mode 100644 gio/gmountprivate.h create mode 100644 gio/gnativesocketaddress.c create mode 100644 gio/gnativesocketaddress.h create mode 100644 gio/gnativevolumemonitor.c create mode 100644 gio/gnativevolumemonitor.h create mode 100644 gio/gnetworkaddress.c create mode 100644 gio/gnetworkaddress.h create mode 100644 gio/gnetworking.c create mode 100644 gio/gnetworking.h.in create mode 100644 gio/gnetworkingprivate.h create mode 100644 gio/gnetworkmonitor.c create mode 100644 gio/gnetworkmonitor.h create mode 100644 gio/gnetworkmonitorbase.c create mode 100644 gio/gnetworkmonitorbase.h create mode 100644 gio/gnetworkmonitornetlink.c create mode 100644 gio/gnetworkmonitornetlink.h create mode 100644 gio/gnetworkmonitornm.c create mode 100644 gio/gnetworkmonitornm.h create mode 100644 gio/gnetworkmonitorportal.c create mode 100644 gio/gnetworkmonitorportal.h create mode 100644 gio/gnetworkservice.c create mode 100644 gio/gnetworkservice.h create mode 100644 gio/gnextstepsettingsbackend.m create mode 100644 gio/gnotification-private.h create mode 100644 gio/gnotification.c create mode 100644 gio/gnotification.h create mode 100644 gio/gnotificationbackend.c create mode 100644 gio/gnotificationbackend.h create mode 100644 gio/gnullsettingsbackend.c create mode 100644 gio/gopenuriportal.c create mode 100644 gio/gopenuriportal.h create mode 100644 gio/gosxappinfo.h create mode 100644 gio/gosxappinfo.m create mode 100644 gio/gosxcontenttype.m create mode 100644 gio/goutputstream.c create mode 100644 gio/goutputstream.h create mode 100644 gio/gpermission.c create mode 100644 gio/gpermission.h create mode 100644 gio/gpollableinputstream.c create mode 100644 gio/gpollableinputstream.h create mode 100644 gio/gpollableoutputstream.c create mode 100644 gio/gpollableoutputstream.h create mode 100644 gio/gpollableutils.c create mode 100644 gio/gpollableutils.h create mode 100644 gio/gpollfilemonitor.c create mode 100644 gio/gpollfilemonitor.h create mode 100644 gio/gportalnotificationbackend.c create mode 100644 gio/gportalsupport.c create mode 100644 gio/gportalsupport.h create mode 100644 gio/gpowerprofilemonitor.c create mode 100644 gio/gpowerprofilemonitor.h create mode 100644 gio/gpowerprofilemonitordbus.c create mode 100644 gio/gpowerprofilemonitordbus.h create mode 100644 gio/gpowerprofilemonitorportal.c create mode 100644 gio/gpowerprofilemonitorportal.h create mode 100644 gio/gpropertyaction.c create mode 100644 gio/gpropertyaction.h create mode 100644 gio/gproxy.c create mode 100644 gio/gproxy.h create mode 100644 gio/gproxyaddress.c create mode 100644 gio/gproxyaddress.h create mode 100644 gio/gproxyaddressenumerator.c create mode 100644 gio/gproxyaddressenumerator.h create mode 100644 gio/gproxyresolver.c create mode 100644 gio/gproxyresolver.h create mode 100644 gio/gproxyresolverportal.c create mode 100644 gio/gproxyresolverportal.h create mode 100644 gio/gregistrysettingsbackend.c create mode 100644 gio/gregistrysettingsbackend.h create mode 100644 gio/gremoteactiongroup.c create mode 100644 gio/gremoteactiongroup.h create mode 100644 gio/gresolver.c create mode 100644 gio/gresolver.h create mode 100644 gio/gresource-tool.c create mode 100644 gio/gresource.c create mode 100644 gio/gresource.h create mode 100644 gio/gresourcefile.c create mode 100644 gio/gresourcefile.h create mode 100644 gio/gschema.dtd create mode 100644 gio/gschema.its create mode 100644 gio/gschema.loc create mode 100644 gio/gseekable.c create mode 100644 gio/gseekable.h create mode 100644 gio/gsettings-mapping.c create mode 100644 gio/gsettings-mapping.h create mode 100644 gio/gsettings-tool.c create mode 100644 gio/gsettings.c create mode 100644 gio/gsettings.h create mode 100644 gio/gsettingsbackend.c create mode 100644 gio/gsettingsbackend.h create mode 100644 gio/gsettingsbackendinternal.h create mode 100644 gio/gsettingsschema-internal.h create mode 100644 gio/gsettingsschema.c create mode 100644 gio/gsettingsschema.h create mode 100644 gio/gsimpleaction.c create mode 100644 gio/gsimpleaction.h create mode 100644 gio/gsimpleactiongroup.c create mode 100644 gio/gsimpleactiongroup.h create mode 100644 gio/gsimpleasyncresult.c create mode 100644 gio/gsimpleasyncresult.h create mode 100644 gio/gsimpleiostream.c create mode 100644 gio/gsimpleiostream.h create mode 100644 gio/gsimplepermission.c create mode 100644 gio/gsimplepermission.h create mode 100644 gio/gsimpleproxyresolver.c create mode 100644 gio/gsimpleproxyresolver.h create mode 100644 gio/gsocket.c create mode 100644 gio/gsocket.h create mode 100644 gio/gsocketaddress.c create mode 100644 gio/gsocketaddress.h create mode 100644 gio/gsocketaddressenumerator.c create mode 100644 gio/gsocketaddressenumerator.h create mode 100644 gio/gsocketclient.c create mode 100644 gio/gsocketclient.h create mode 100644 gio/gsocketconnectable.c create mode 100644 gio/gsocketconnectable.h create mode 100644 gio/gsocketconnection.c create mode 100644 gio/gsocketconnection.h create mode 100644 gio/gsocketcontrolmessage.c create mode 100644 gio/gsocketcontrolmessage.h create mode 100644 gio/gsocketinputstream.c create mode 100644 gio/gsocketinputstream.h create mode 100644 gio/gsocketlistener.c create mode 100644 gio/gsocketlistener.h create mode 100644 gio/gsocketoutputstream.c create mode 100644 gio/gsocketoutputstream.h create mode 100644 gio/gsocketservice.c create mode 100644 gio/gsocketservice.h create mode 100644 gio/gsocks4aproxy.c create mode 100644 gio/gsocks4aproxy.h create mode 100644 gio/gsocks4proxy.c create mode 100644 gio/gsocks4proxy.h create mode 100644 gio/gsocks5proxy.c create mode 100644 gio/gsocks5proxy.h create mode 100644 gio/gsrvtarget.c create mode 100644 gio/gsrvtarget.h create mode 100644 gio/gsubprocess.c create mode 100644 gio/gsubprocess.h create mode 100644 gio/gsubprocesslauncher-private.h create mode 100644 gio/gsubprocesslauncher.c create mode 100644 gio/gsubprocesslauncher.h create mode 100644 gio/gtask.c create mode 100644 gio/gtask.h create mode 100644 gio/gtcpconnection.c create mode 100644 gio/gtcpconnection.h create mode 100644 gio/gtcpwrapperconnection.c create mode 100644 gio/gtcpwrapperconnection.h create mode 100644 gio/gtestdbus.c create mode 100644 gio/gtestdbus.h create mode 100644 gio/gthemedicon.c create mode 100644 gio/gthemedicon.h create mode 100644 gio/gthreadedresolver.c create mode 100644 gio/gthreadedresolver.h create mode 100644 gio/gthreadedsocketservice.c create mode 100644 gio/gthreadedsocketservice.h create mode 100644 gio/gtlsbackend.c create mode 100644 gio/gtlsbackend.h create mode 100644 gio/gtlscertificate.c create mode 100644 gio/gtlscertificate.h create mode 100644 gio/gtlsclientconnection.c create mode 100644 gio/gtlsclientconnection.h create mode 100644 gio/gtlsconnection.c create mode 100644 gio/gtlsconnection.h create mode 100644 gio/gtlsdatabase.c create mode 100644 gio/gtlsdatabase.h create mode 100644 gio/gtlsfiledatabase.c create mode 100644 gio/gtlsfiledatabase.h create mode 100644 gio/gtlsinteraction.c create mode 100644 gio/gtlsinteraction.h create mode 100644 gio/gtlspassword.c create mode 100644 gio/gtlspassword.h create mode 100644 gio/gtlsserverconnection.c create mode 100644 gio/gtlsserverconnection.h create mode 100644 gio/gtrashportal.c create mode 100644 gio/gtrashportal.h create mode 100644 gio/gunionvolumemonitor.c create mode 100644 gio/gunionvolumemonitor.h create mode 100644 gio/gunixconnection.c create mode 100644 gio/gunixconnection.h create mode 100644 gio/gunixcredentialsmessage.c create mode 100644 gio/gunixcredentialsmessage.h create mode 100644 gio/gunixfdlist.c create mode 100644 gio/gunixfdlist.h create mode 100644 gio/gunixfdmessage.c create mode 100644 gio/gunixfdmessage.h create mode 100644 gio/gunixinputstream.c create mode 100644 gio/gunixinputstream.h create mode 100644 gio/gunixmount.c create mode 100644 gio/gunixmount.h create mode 100644 gio/gunixmounts.c create mode 100644 gio/gunixmounts.h create mode 100644 gio/gunixoutputstream.c create mode 100644 gio/gunixoutputstream.h create mode 100644 gio/gunixsocketaddress.c create mode 100644 gio/gunixsocketaddress.h create mode 100644 gio/gunixvolume.c create mode 100644 gio/gunixvolume.h create mode 100644 gio/gunixvolumemonitor.c create mode 100644 gio/gunixvolumemonitor.h create mode 100644 gio/gvdb/gvdb-builder.c create mode 100644 gio/gvdb/gvdb-builder.h create mode 100644 gio/gvdb/gvdb-format.h create mode 100644 gio/gvdb/gvdb-reader.c create mode 100644 gio/gvdb/gvdb-reader.h create mode 100644 gio/gvdb/gvdb.doap create mode 100644 gio/gvfs.c create mode 100644 gio/gvfs.h create mode 100644 gio/gvolume.c create mode 100644 gio/gvolume.h create mode 100644 gio/gvolumemonitor.c create mode 100644 gio/gvolumemonitor.h create mode 100755 gio/gwin32api-application-activation-manager.h create mode 100755 gio/gwin32api-iterator.h create mode 100755 gio/gwin32api-misc.h create mode 100755 gio/gwin32api-package.h create mode 100755 gio/gwin32api-storage.h create mode 100644 gio/gwin32appinfo.c create mode 100644 gio/gwin32appinfo.h create mode 100755 gio/gwin32file-sync-stream.c create mode 100755 gio/gwin32file-sync-stream.h create mode 100644 gio/gwin32inputstream.c create mode 100644 gio/gwin32inputstream.h create mode 100644 gio/gwin32mount.c create mode 100644 gio/gwin32mount.h create mode 100644 gio/gwin32networkmonitor.c create mode 100644 gio/gwin32networkmonitor.h create mode 100644 gio/gwin32notificationbackend.c create mode 100644 gio/gwin32outputstream.c create mode 100644 gio/gwin32outputstream.h create mode 100755 gio/gwin32packageparser.c create mode 100755 gio/gwin32packageparser.h create mode 100644 gio/gwin32registrykey.c create mode 100644 gio/gwin32registrykey.h create mode 100644 gio/gwin32sid.c create mode 100644 gio/gwin32sid.h create mode 100644 gio/gwin32volumemonitor.c create mode 100644 gio/gwin32volumemonitor.h create mode 100644 gio/gzlibcompressor.c create mode 100644 gio/gzlibcompressor.h create mode 100644 gio/gzlibdecompressor.c create mode 100644 gio/gzlibdecompressor.h create mode 100644 gio/inotify/ginotifyfilemonitor.c create mode 100644 gio/inotify/ginotifyfilemonitor.h create mode 100644 gio/inotify/inotify-helper.c create mode 100644 gio/inotify/inotify-helper.h create mode 100644 gio/inotify/inotify-kernel.c create mode 100644 gio/inotify/inotify-kernel.h create mode 100644 gio/inotify/inotify-missing.c create mode 100644 gio/inotify/inotify-missing.h create mode 100644 gio/inotify/inotify-path.c create mode 100644 gio/inotify/inotify-path.h create mode 100644 gio/inotify/inotify-sub.c create mode 100644 gio/inotify/inotify-sub.h create mode 100644 gio/inotify/meson.build create mode 100644 gio/kqueue/dep-list.c create mode 100644 gio/kqueue/dep-list.h create mode 100644 gio/kqueue/gkqueuefilemonitor.c create mode 100644 gio/kqueue/kqueue-helper.c create mode 100644 gio/kqueue/kqueue-helper.h create mode 100644 gio/kqueue/kqueue-missing.c create mode 100644 gio/kqueue/meson.build create mode 100644 gio/meson.build create mode 100644 gio/org.freedesktop.portal.Documents.xml create mode 100644 gio/org.freedesktop.portal.OpenURI.xml create mode 100644 gio/org.freedesktop.portal.ProxyResolver.xml create mode 100644 gio/org.freedesktop.portal.Trash.xml create mode 100644 gio/strinfo.c create mode 100644 gio/tests/.gitignore create mode 100644 gio/tests/111_digit_test.gresource.xml create mode 100644 gio/tests/actions.c create mode 100644 gio/tests/appinfo-test-actions.desktop create mode 100644 gio/tests/appinfo-test-gnome.desktop.in create mode 100644 gio/tests/appinfo-test-notgnome.desktop.in create mode 100644 gio/tests/appinfo-test-static.desktop create mode 100644 gio/tests/appinfo-test.c create mode 100644 gio/tests/appinfo-test.desktop.in create mode 100644 gio/tests/appinfo-test2.desktop.in create mode 100644 gio/tests/appinfo.c create mode 100644 gio/tests/appmonitor.c create mode 100644 gio/tests/apps.c create mode 100644 gio/tests/async-close-output-stream.c create mode 100644 gio/tests/async-splice-output-stream.c create mode 100644 gio/tests/autoptr.c create mode 100644 gio/tests/basic-application.c create mode 100644 gio/tests/buffered-input-stream.c create mode 100644 gio/tests/buffered-output-stream.c create mode 100644 gio/tests/cancellable.c create mode 100644 gio/tests/cert-tests/cert-crlf.pem create mode 100644 gio/tests/cert-tests/cert-key.pem create mode 100644 gio/tests/cert-tests/cert-list.pem create mode 100644 gio/tests/cert-tests/cert1.pem create mode 100644 gio/tests/cert-tests/cert2.pem create mode 100644 gio/tests/cert-tests/cert3.pem create mode 100644 gio/tests/cert-tests/key-cert-password-123.p12 create mode 100644 gio/tests/cert-tests/key-cert.pem create mode 100644 gio/tests/cert-tests/key-crlf.pem create mode 100644 gio/tests/cert-tests/key.pem create mode 100644 gio/tests/cert-tests/key8.pem create mode 100644 gio/tests/cert-tests/key8enc.pem create mode 100644 gio/tests/cert-tests/key_missing-footer.pem create mode 100644 gio/tests/cert-tests/key_missing-header.pem create mode 100644 gio/tests/cert-tests/nothing.pem create mode 100644 gio/tests/codegen.py create mode 100644 gio/tests/contenttype.c create mode 100644 gio/tests/contexts.c create mode 100644 gio/tests/converter-stream.c create mode 100644 gio/tests/credentials.c create mode 100644 gio/tests/cxx.cpp create mode 100644 gio/tests/data-input-stream.c create mode 100644 gio/tests/data-output-stream.c create mode 100644 gio/tests/dbus-appinfo.c create mode 100644 gio/tests/dbus-launch.c create mode 100644 gio/tests/de.po create mode 100644 gio/tests/de/LC_MESSAGES/meson.build create mode 100644 gio/tests/debugcontroller.c create mode 100644 gio/tests/defaultvalue.c create mode 100644 gio/tests/desktop-app-info.c create mode 100644 gio/tests/desktop-files/home/applications/eog.desktop create mode 100644 gio/tests/desktop-files/home/applications/epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb.desktop create mode 100644 gio/tests/desktop-files/usr/applications/baobab.desktop create mode 100644 gio/tests/desktop-files/usr/applications/cheese.desktop create mode 100644 gio/tests/desktop-files/usr/applications/dconf-editor.desktop create mode 100644 gio/tests/desktop-files/usr/applications/eog.desktop create mode 100644 gio/tests/desktop-files/usr/applications/evince-previewer.desktop create mode 100644 gio/tests/desktop-files/usr/applications/evince.desktop create mode 100644 gio/tests/desktop-files/usr/applications/file-roller.desktop create mode 100644 gio/tests/desktop-files/usr/applications/frobnicator.desktop create mode 100644 gio/tests/desktop-files/usr/applications/gcr-prompter.desktop create mode 100644 gio/tests/desktop-files/usr/applications/gcr-viewer.desktop create mode 100644 gio/tests/desktop-files/usr/applications/gedit.desktop create mode 100644 gio/tests/desktop-files/usr/applications/glade.desktop create mode 100644 gio/tests/desktop-files/usr/applications/gnome-contacts.desktop create mode 100644 gio/tests/desktop-files/usr/applications/gnome-font-viewer.desktop create mode 100644 gio/tests/desktop-files/usr/applications/gnome-music.desktop create mode 100644 gio/tests/desktop-files/usr/applications/gnome-terminal.desktop create mode 100644 gio/tests/desktop-files/usr/applications/gucharmap.desktop create mode 100644 gio/tests/desktop-files/usr/applications/invalid-desktop.desktop create mode 100644 gio/tests/desktop-files/usr/applications/kde4/dolphin.desktop create mode 100644 gio/tests/desktop-files/usr/applications/kde4/kate.desktop create mode 100644 gio/tests/desktop-files/usr/applications/kde4/konqbrowser.desktop create mode 100644 gio/tests/desktop-files/usr/applications/kde4/okular.desktop create mode 100644 gio/tests/desktop-files/usr/applications/mimeinfo.cache create mode 100644 gio/tests/desktop-files/usr/applications/nautilus-autorun-software.desktop create mode 100644 gio/tests/desktop-files/usr/applications/nautilus-classic.desktop create mode 100644 gio/tests/desktop-files/usr/applications/nautilus-connect-server.desktop create mode 100644 gio/tests/desktop-files/usr/applications/nautilus.desktop create mode 100644 gio/tests/desktop-files/usr/applications/org.gnome.clocks.desktop create mode 100644 gio/tests/desktop-files/usr/applications/totem.desktop create mode 100644 gio/tests/desktop-files/usr/applications/yelp.desktop create mode 100644 gio/tests/echo-server.c create mode 100644 gio/tests/empty.txt create mode 100644 gio/tests/enums.xml.template create mode 100644 gio/tests/fake-document-portal.c create mode 100644 gio/tests/fake-service-name.c create mode 100644 gio/tests/file.c create mode 100644 gio/tests/fileattributematcher.c create mode 100644 gio/tests/filter-cat.c create mode 100644 gio/tests/filter-streams.c create mode 100644 gio/tests/g-file-info-filesystem-readonly.c create mode 100644 gio/tests/g-file-info.c create mode 100644 gio/tests/g-file.c create mode 100644 gio/tests/g-icon.c create mode 100644 gio/tests/gapplication-example-actions.c create mode 100644 gio/tests/gapplication-example-cmdline.c create mode 100644 gio/tests/gapplication-example-cmdline2.c create mode 100644 gio/tests/gapplication-example-cmdline3.c create mode 100644 gio/tests/gapplication-example-cmdline4.c create mode 100644 gio/tests/gapplication-example-dbushooks.c create mode 100644 gio/tests/gapplication-example-open.c create mode 100644 gio/tests/gapplication.c create mode 100644 gio/tests/gdbus-address-get-session.c create mode 100644 gio/tests/gdbus-addresses.c create mode 100644 gio/tests/gdbus-auth.c create mode 100644 gio/tests/gdbus-bz627724.c create mode 100644 gio/tests/gdbus-close-pending.c create mode 100644 gio/tests/gdbus-connection-flush-helper.c create mode 100644 gio/tests/gdbus-connection-flush.c create mode 100644 gio/tests/gdbus-connection-loss.c create mode 100644 gio/tests/gdbus-connection-slow.c create mode 100644 gio/tests/gdbus-connection.c create mode 100644 gio/tests/gdbus-daemon.c create mode 100644 gio/tests/gdbus-error.c create mode 100644 gio/tests/gdbus-example-export.c create mode 100644 gio/tests/gdbus-example-objectmanager-client.c create mode 100644 gio/tests/gdbus-example-objectmanager-server.c create mode 100644 gio/tests/gdbus-example-own-name.c create mode 100755 gio/tests/gdbus-example-peer.c create mode 100644 gio/tests/gdbus-example-proxy-subclass.c create mode 100644 gio/tests/gdbus-example-server.c create mode 100644 gio/tests/gdbus-example-subtree.c create mode 100644 gio/tests/gdbus-example-unix-fd-client.c create mode 100644 gio/tests/gdbus-example-watch-name.c create mode 100644 gio/tests/gdbus-example-watch-proxy.c create mode 100644 gio/tests/gdbus-exit-on-close.c create mode 100644 gio/tests/gdbus-export.c create mode 100644 gio/tests/gdbus-introspection.c create mode 100644 gio/tests/gdbus-message.c create mode 100644 gio/tests/gdbus-method-invocation.c create mode 100644 gio/tests/gdbus-names.c create mode 100644 gio/tests/gdbus-non-socket.c create mode 100644 gio/tests/gdbus-object-manager-example/gdbus-example-objectmanager.xml create mode 100644 gio/tests/gdbus-object-manager-example/meson.build create mode 100644 gio/tests/gdbus-overflow.c create mode 100644 gio/tests/gdbus-peer-object-manager.c create mode 100644 gio/tests/gdbus-peer.c create mode 100644 gio/tests/gdbus-proxy-threads.c create mode 100644 gio/tests/gdbus-proxy-unique-name.c create mode 100644 gio/tests/gdbus-proxy-well-known-name.c create mode 100644 gio/tests/gdbus-proxy.c create mode 100644 gio/tests/gdbus-serialization.c create mode 100644 gio/tests/gdbus-server-auth.c create mode 100644 gio/tests/gdbus-sessionbus.c create mode 100644 gio/tests/gdbus-sessionbus.h create mode 100644 gio/tests/gdbus-test-codegen.c create mode 100644 gio/tests/gdbus-test-fixture.c create mode 100644 gio/tests/gdbus-tests.c create mode 100644 gio/tests/gdbus-tests.h create mode 100644 gio/tests/gdbus-testserver.c create mode 100644 gio/tests/gdbus-threading.c create mode 100644 gio/tests/gen-big-test-resource.py create mode 100644 gio/tests/gengiotypefuncs.py create mode 100644 gio/tests/gio-du.c create mode 100644 gio/tests/giomodule.c create mode 100644 gio/tests/glistmodel.c create mode 100644 gio/tests/gmenumodel.c create mode 100644 gio/tests/gnotification-server.c create mode 100644 gio/tests/gnotification-server.h create mode 100644 gio/tests/gnotification.c create mode 100644 gio/tests/gschema-compile.c create mode 100644 gio/tests/gsettings.c create mode 100644 gio/tests/gsocketclient-slow.c create mode 100644 gio/tests/gsubprocess-testprog.c create mode 100644 gio/tests/gsubprocess.c create mode 100644 gio/tests/gtesttlsbackend.c create mode 100644 gio/tests/gtesttlsbackend.h create mode 100644 gio/tests/gtlsconsoleinteraction.c create mode 100644 gio/tests/gtlsconsoleinteraction.h create mode 100644 gio/tests/httpd.c create mode 100644 gio/tests/inet-address.c create mode 100644 gio/tests/io-stream.c create mode 100644 gio/tests/live-g-file.c create mode 100644 gio/tests/live-g-file.txt create mode 100644 gio/tests/memory-input-stream.c create mode 100755 gio/tests/memory-monitor-dbus.py.in create mode 100755 gio/tests/memory-monitor-portal.py.in create mode 100644 gio/tests/memory-monitor.c create mode 100644 gio/tests/memory-output-stream.c create mode 100644 gio/tests/memory-settings-backend.c create mode 100644 gio/tests/meson.build create mode 100644 gio/tests/mimeapps.c create mode 100644 gio/tests/mock-resolver.c create mode 100644 gio/tests/mock-resolver.h create mode 100644 gio/tests/modules/meson.build create mode 100644 gio/tests/modules/symbol-visibility.h create mode 100644 gio/tests/modules/test-module-a.c create mode 100644 gio/tests/modules/test-module-b.c create mode 100644 gio/tests/mount-operation.c create mode 100644 gio/tests/network-address.c create mode 100644 gio/tests/network-monitor-race.c create mode 100644 gio/tests/network-monitor.c create mode 100644 gio/tests/null-settings-backend.c create mode 100644 gio/tests/org.gtk.schemasourcecheck.gschema.xml create mode 100644 gio/tests/org.gtk.test.dbusappinfo.desktop create mode 100644 gio/tests/org.gtk.test.dbusappinfo.flatpak.desktop create mode 100644 gio/tests/org.gtk.test.gschema.override.orig create mode 100644 gio/tests/org.gtk.test.gschema.xml.orig create mode 100644 gio/tests/permission.c create mode 100644 gio/tests/pollable.c create mode 100755 gio/tests/power-profile-monitor-dbus.py.in create mode 100755 gio/tests/power-profile-monitor-portal.py.in create mode 100644 gio/tests/power-profile-monitor.c create mode 100644 gio/tests/proxy-test.c create mode 100644 gio/tests/proxy.c create mode 100644 gio/tests/readwrite.c create mode 100644 gio/tests/resolver-parsing.c create mode 100644 gio/tests/resolver.c create mode 100644 gio/tests/resourceplugin.c create mode 100644 gio/tests/resources.c create mode 100644 gio/tests/schema-tests/array-default-not-in-choices.gschema.xml create mode 100644 gio/tests/schema-tests/bad-choice.gschema.xml create mode 100644 gio/tests/schema-tests/bad-key.gschema.xml create mode 100644 gio/tests/schema-tests/bad-key2.gschema.xml create mode 100644 gio/tests/schema-tests/bad-key3.gschema.xml create mode 100644 gio/tests/schema-tests/bad-key4.gschema.xml create mode 100644 gio/tests/schema-tests/bad-type.gschema.xml create mode 100644 gio/tests/schema-tests/bare-alias.gschema.xml create mode 100644 gio/tests/schema-tests/cdata.gschema.xml create mode 100644 gio/tests/schema-tests/choice-alias.gschema.xml create mode 100644 gio/tests/schema-tests/choice-bad.gschema.xml create mode 100644 gio/tests/schema-tests/choice-badtype.gschema.xml create mode 100644 gio/tests/schema-tests/choice-invalid-alias.gschema.xml create mode 100644 gio/tests/schema-tests/choice-missing-value.gschema.xml create mode 100644 gio/tests/schema-tests/choice-shadowed-alias.gschema.xml create mode 100644 gio/tests/schema-tests/choice-upside-down.gschema.xml create mode 100644 gio/tests/schema-tests/choice.gschema.xml create mode 100644 gio/tests/schema-tests/choices-wrong-type.gschema.xml create mode 100644 gio/tests/schema-tests/default-in-aliases.gschema.xml create mode 100644 gio/tests/schema-tests/default-not-in-choices.gschema.xml create mode 100644 gio/tests/schema-tests/default-out-of-range.gschema.xml create mode 100644 gio/tests/schema-tests/description-xmllang.gschema.xml create mode 100644 gio/tests/schema-tests/empty-key.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-aliases.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-bad-default.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-chained-alias.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-choice.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-invalid-alias.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-invalid-value.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-repeated-alias.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-repeated-nick.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-repeated-value.gschema.xml create mode 100644 gio/tests/schema-tests/enum-with-shadow-alias.gschema.xml create mode 100644 gio/tests/schema-tests/enum.gschema.xml create mode 100644 gio/tests/schema-tests/extend-and-shadow-indirect.gschema.xml create mode 100644 gio/tests/schema-tests/extend-and-shadow.gschema.xml create mode 100644 gio/tests/schema-tests/extend-missing.gschema.xml create mode 100644 gio/tests/schema-tests/extend-nonlist.gschema.xml create mode 100644 gio/tests/schema-tests/extend-self.gschema.xml create mode 100644 gio/tests/schema-tests/extend-wrong-list-indirect.gschema.xml create mode 100644 gio/tests/schema-tests/extend-wrong-list.gschema.xml create mode 100644 gio/tests/schema-tests/extending.gschema.xml create mode 100644 gio/tests/schema-tests/flags-aliased-default.gschema.xml create mode 100644 gio/tests/schema-tests/flags-bad-default.gschema.xml create mode 100644 gio/tests/schema-tests/flags-more-than-one-bit.gschema.xml create mode 100644 gio/tests/schema-tests/flags-with-enum-attr.gschema.xml create mode 100644 gio/tests/schema-tests/flags-with-enum-tag.gschema.xml create mode 100644 gio/tests/schema-tests/from-docs.gschema.xml create mode 100644 gio/tests/schema-tests/incomplete-list.gschema.xml create mode 100644 gio/tests/schema-tests/inherit-gettext-domain.gschema.xml create mode 100644 gio/tests/schema-tests/invalid-path.gschema.xml create mode 100644 gio/tests/schema-tests/key-in-list-indirect.gschema.xml create mode 100644 gio/tests/schema-tests/key-in-list.gschema.xml create mode 100644 gio/tests/schema-tests/list-of-missing.gschema.xml create mode 100644 gio/tests/schema-tests/missing-quotes.gschema.xml create mode 100644 gio/tests/schema-tests/no-default.gschema.xml create mode 100644 gio/tests/schema-tests/overflow.gschema.xml create mode 100644 gio/tests/schema-tests/override-missing.gschema.xml create mode 100644 gio/tests/schema-tests/override-range-error.gschema.xml create mode 100644 gio/tests/schema-tests/override-then-key.gschema.xml create mode 100644 gio/tests/schema-tests/override-twice.gschema.xml create mode 100644 gio/tests/schema-tests/override-type-error.gschema.xml create mode 100644 gio/tests/schema-tests/override.gschema.xml create mode 100644 gio/tests/schema-tests/range-badtype.gschema.xml create mode 100644 gio/tests/schema-tests/range-default-high.gschema.xml create mode 100644 gio/tests/schema-tests/range-default-low.gschema.xml create mode 100644 gio/tests/schema-tests/range-high-default.gschema.xml create mode 100644 gio/tests/schema-tests/range-low-default.gschema.xml create mode 100644 gio/tests/schema-tests/range-missing-max.gschema.xml create mode 100644 gio/tests/schema-tests/range-missing-min.gschema.xml create mode 100644 gio/tests/schema-tests/range-parse-error.gschema.xml create mode 100644 gio/tests/schema-tests/range-type-test.gschema.xml create mode 100644 gio/tests/schema-tests/range-wrong-type.gschema.xml create mode 100644 gio/tests/schema-tests/range.gschema.xml create mode 100644 gio/tests/schema-tests/summary-xmllang-and-attrs.gschema.xml create mode 100644 gio/tests/schema-tests/summary-xmllang.gschema.xml create mode 100644 gio/tests/schema-tests/wrong-category.gschema.xml create mode 100644 gio/tests/send-data.c create mode 100644 gio/tests/services/meson.build create mode 100644 gio/tests/services/org.freedesktop.portal.Documents.service.in create mode 100644 gio/tests/services/org.gtk.GDBus.Examples.ObjectManager.service.in create mode 100644 gio/tests/services/org.gtk.GDBus.FakeService.service.in create mode 100644 gio/tests/simple-async-result.c create mode 100644 gio/tests/simple-proxy.c create mode 100644 gio/tests/sleepy-stream.c create mode 100644 gio/tests/slow-connect-preload.c create mode 100644 gio/tests/socket-address.c create mode 100644 gio/tests/socket-client.c create mode 100644 gio/tests/socket-common.c create mode 100644 gio/tests/socket-listener.c create mode 100644 gio/tests/socket-server.c create mode 100644 gio/tests/socket-service.c create mode 100644 gio/tests/socket.c create mode 100644 gio/tests/srvtarget.c create mode 100755 gio/tests/static-link.py create mode 100644 gio/tests/static-link/app.c create mode 100644 gio/tests/static-link/meson.build create mode 100644 gio/tests/stream-rw_all.c create mode 100644 gio/tests/taptestrunner.py create mode 100644 gio/tests/task.c create mode 100644 gio/tests/test-codegen.xml create mode 100644 gio/tests/test-io-stream.c create mode 100644 gio/tests/test-io-stream.h create mode 100644 gio/tests/test-pipe-unix.c create mode 100644 gio/tests/test-pipe-unix.h create mode 100644 gio/tests/test.gresource.xml create mode 100644 gio/tests/test1.overlay create mode 100644 gio/tests/test1.txt create mode 100644 gio/tests/test2.gresource.xml create mode 100644 gio/tests/test2.txt create mode 100644 gio/tests/test3.gresource.xml create mode 100644 gio/tests/test3.txt create mode 100644 gio/tests/test4.gresource.xml create mode 100644 gio/tests/test5.gresource.xml create mode 100644 gio/tests/testenum.h create mode 100644 gio/tests/testfilemonitor.c create mode 100644 gio/tests/thumbnail-verification.c create mode 100644 gio/tests/thumbnails/bad-header.png create mode 100644 gio/tests/thumbnails/empty-key.png create mode 100644 gio/tests/thumbnails/header-and-chunk-size.png create mode 100644 gio/tests/thumbnails/header-only.png create mode 100644 gio/tests/thumbnails/huge-chunk-size.png create mode 100644 gio/tests/thumbnails/mtime-zero.png create mode 100644 gio/tests/thumbnails/no-text-data.png create mode 100644 gio/tests/thumbnails/overlong-value.png create mode 100644 gio/tests/thumbnails/uri-mismatch.png create mode 100644 gio/tests/thumbnails/valid-no-size.png create mode 100644 gio/tests/thumbnails/valid.png create mode 100644 gio/tests/tls-bindings.c create mode 100644 gio/tests/tls-certificate.c create mode 100644 gio/tests/tls-database.c create mode 100644 gio/tests/tls-interaction.c create mode 100644 gio/tests/trash.c create mode 100644 gio/tests/unix-fd.c create mode 100644 gio/tests/unix-mounts.c create mode 100644 gio/tests/unix-streams.c create mode 100644 gio/tests/vfs.c create mode 100644 gio/tests/volumemonitor.c create mode 100644 gio/tests/win32-appinfo.c create mode 100644 gio/tests/win32-streams.c create mode 100644 gio/tests/x-content/image-dcf/DCIM/Camera/20130831_203925.jpg create mode 100644 gio/tests/x-content/image-dcf/DCIM/Camera/20130831_203928.jpg create mode 100644 gio/tests/x-content/unix-software/autorun.sh create mode 100755 gio/tests/x-content/win32-software/autorun.exe create mode 100644 gio/thumbnail-verify.c create mode 100644 gio/thumbnail-verify.h create mode 100644 gio/win32/gwin32filemonitor.c create mode 100644 gio/win32/gwin32filemonitor.h create mode 100644 gio/win32/gwin32fsmonitorutils.c create mode 100644 gio/win32/gwin32fsmonitorutils.h create mode 100644 gio/win32/gwinhttpfile.c create mode 100644 gio/win32/gwinhttpfile.h create mode 100644 gio/win32/gwinhttpfileinputstream.c create mode 100644 gio/win32/gwinhttpfileinputstream.h create mode 100644 gio/win32/gwinhttpfileoutputstream.c create mode 100644 gio/win32/gwinhttpfileoutputstream.h create mode 100644 gio/win32/gwinhttpvfs.c create mode 100644 gio/win32/gwinhttpvfs.h create mode 100644 gio/win32/meson.build create mode 100644 gio/win32/winhttp.h create mode 100644 gio/xdgmime/.gitignore create mode 100644 gio/xdgmime/meson.build create mode 100644 gio/xdgmime/xdgmime.c create mode 100644 gio/xdgmime/xdgmime.h create mode 100644 gio/xdgmime/xdgmimealias.c create mode 100644 gio/xdgmime/xdgmimealias.h create mode 100644 gio/xdgmime/xdgmimecache.c create mode 100644 gio/xdgmime/xdgmimecache.h create mode 100644 gio/xdgmime/xdgmimeglob.c create mode 100644 gio/xdgmime/xdgmimeglob.h create mode 100644 gio/xdgmime/xdgmimeicon.c create mode 100644 gio/xdgmime/xdgmimeicon.h create mode 100644 gio/xdgmime/xdgmimeint.c create mode 100644 gio/xdgmime/xdgmimeint.h create mode 100644 gio/xdgmime/xdgmimemagic.c create mode 100644 gio/xdgmime/xdgmimemagic.h create mode 100644 gio/xdgmime/xdgmimeparent.c create mode 100644 gio/xdgmime/xdgmimeparent.h create mode 100755 glib-gettextize.in create mode 100644 glib.doap create mode 100644 glib.supp create mode 100644 glib/deprecated/gallocator.c create mode 100644 glib/deprecated/gallocator.h create mode 100644 glib/deprecated/gcache.c create mode 100644 glib/deprecated/gcache.h create mode 100644 glib/deprecated/gcompletion.c create mode 100644 glib/deprecated/gcompletion.h create mode 100644 glib/deprecated/gmain.h create mode 100644 glib/deprecated/grel.c create mode 100644 glib/deprecated/grel.h create mode 100644 glib/deprecated/gthread-deprecated.c create mode 100644 glib/deprecated/gthread.h create mode 100644 glib/dirent/README create mode 100644 glib/dirent/dirent-zip create mode 100644 glib/dirent/dirent.c create mode 100644 glib/dirent/dirent.h create mode 100644 glib/dirent/wdirent.c create mode 100644 glib/docs.c create mode 100644 glib/galloca.h create mode 100644 glib/garcbox.c create mode 100644 glib/garray.c create mode 100644 glib/garray.h create mode 100644 glib/gasyncqueue.c create mode 100644 glib/gasyncqueue.h create mode 100644 glib/gasyncqueueprivate.h create mode 100644 glib/gatomic.c create mode 100644 glib/gatomic.h create mode 100644 glib/gbacktrace.c create mode 100644 glib/gbacktrace.h create mode 100644 glib/gbase64.c create mode 100644 glib/gbase64.h create mode 100644 glib/gbitlock.c create mode 100644 glib/gbitlock.h create mode 100644 glib/gbookmarkfile.c create mode 100644 glib/gbookmarkfile.h create mode 100644 glib/gbsearcharray.h create mode 100644 glib/gbytes.c create mode 100644 glib/gbytes.h create mode 100644 glib/gcharset.c create mode 100644 glib/gcharset.h create mode 100644 glib/gcharsetprivate.h create mode 100644 glib/gchecksum.c create mode 100644 glib/gchecksum.h create mode 100644 glib/gconstructor.h create mode 100644 glib/gconvert.c create mode 100644 glib/gconvert.h create mode 100644 glib/gconvertprivate.h create mode 100644 glib/gdataset.c create mode 100644 glib/gdataset.h create mode 100644 glib/gdatasetprivate.h create mode 100644 glib/gdate.c create mode 100644 glib/gdate.h create mode 100644 glib/gdatetime.c create mode 100644 glib/gdatetime.h create mode 100644 glib/gdir.c create mode 100644 glib/gdir.h create mode 100755 glib/gen-unicode-tables.pl create mode 100644 glib/genviron.c create mode 100644 glib/genviron.h create mode 100644 glib/gerror.c create mode 100644 glib/gerror.h create mode 100644 glib/gfileutils.c create mode 100644 glib/gfileutils.h create mode 100644 glib/ggettext.c create mode 100644 glib/ggettext.h create mode 100644 glib/ghash.c create mode 100644 glib/ghash.h create mode 100644 glib/ghmac.c create mode 100644 glib/ghmac.h create mode 100644 glib/ghook.c create mode 100644 glib/ghook.h create mode 100644 glib/ghostutils.c create mode 100644 glib/ghostutils.h create mode 100644 glib/gi18n-lib.h create mode 100644 glib/gi18n.h create mode 100644 glib/giochannel.c create mode 100644 glib/giochannel.h create mode 100644 glib/giounix.c create mode 100644 glib/giowin32.c create mode 100644 glib/gkeyfile.c create mode 100644 glib/gkeyfile.h create mode 100644 glib/glib-autocleanups.h create mode 100644 glib/glib-init.c create mode 100644 glib/glib-init.h create mode 100644 glib/glib-mirroring-tab/gen-mirroring-tab.c create mode 100644 glib/glib-mirroring-tab/meson.build create mode 100644 glib/glib-mirroring-tab/packtab.c create mode 100644 glib/glib-mirroring-tab/packtab.h create mode 100644 glib/glib-object.h create mode 100644 glib/glib-private.c create mode 100644 glib/glib-private.h create mode 100644 glib/glib-typeof.h create mode 100644 glib/glib-unix.c create mode 100644 glib/glib-unix.h create mode 100644 glib/glib.h create mode 100644 glib/glib.rc.in create mode 100644 glib/glib.stp.in create mode 100644 glib/glib_gdb.py create mode 100644 glib/glib_probes.d create mode 100644 glib/glib_trace.h create mode 100644 glib/glibconfig.h.in create mode 100644 glib/glibintl.h create mode 100644 glib/glist.c create mode 100644 glib/glist.h create mode 100644 glib/gmacros.h create mode 100644 glib/gmain-internal.h create mode 100644 glib/gmain.c create mode 100644 glib/gmain.h create mode 100644 glib/gmappedfile.c create mode 100644 glib/gmappedfile.h create mode 100644 glib/gmarkup.c create mode 100644 glib/gmarkup.h create mode 100644 glib/gmem.c create mode 100644 glib/gmem.h create mode 100644 glib/gmessages.c create mode 100644 glib/gmessages.h create mode 100644 glib/gmirroringtable.h create mode 100644 glib/gnode.c create mode 100644 glib/gnode.h create mode 100644 glib/gnulib/README create mode 100644 glib/gnulib/arg-nonnull.h create mode 100644 glib/gnulib/asnprintf.c create mode 100644 glib/gnulib/c++defs.h create mode 100644 glib/gnulib/float+.h create mode 100644 glib/gnulib/fpucw.h create mode 100644 glib/gnulib/frexp.c create mode 100644 glib/gnulib/frexpl.c create mode 100644 glib/gnulib/g-gnulib.h create mode 100644 glib/gnulib/gl_cv_cc_double_expbit0/meson.build create mode 100644 glib/gnulib/gl_cv_func_frexp_works/meson.build create mode 100644 glib/gnulib/gl_cv_func_frexpl_works/meson.build create mode 100644 glib/gnulib/gl_cv_func_ldexpl_works/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_directive_a/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_directive_f/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_directive_ls/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_enomem/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_flag_grouping/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_flag_leftadjust/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_flag_zero/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_infinite/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_infinite_long_double/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_long_double/meson.build create mode 100644 glib/gnulib/gl_cv_func_printf_precision/meson.build create mode 100644 glib/gnulib/gl_cv_long_double_equals_double/meson.build create mode 100644 glib/gnulib/gl_extern_inline/meson.build create mode 100644 glib/gnulib/glib-gnulib.patch create mode 100644 glib/gnulib/gnulib_math.h.in create mode 100644 glib/gnulib/isinf.c create mode 100644 glib/gnulib/isnan.c create mode 100644 glib/gnulib/isnand-nolibm.h create mode 100644 glib/gnulib/isnand.c create mode 100644 glib/gnulib/isnanf-nolibm.h create mode 100644 glib/gnulib/isnanf.c create mode 100644 glib/gnulib/isnanl-nolibm.h create mode 100644 glib/gnulib/isnanl.c create mode 100644 glib/gnulib/meson.build create mode 100644 glib/gnulib/printf-args.c create mode 100644 glib/gnulib/printf-args.h create mode 100644 glib/gnulib/printf-frexp.c create mode 100644 glib/gnulib/printf-frexp.h create mode 100644 glib/gnulib/printf-frexpl.c create mode 100644 glib/gnulib/printf-frexpl.h create mode 100644 glib/gnulib/printf-parse.c create mode 100644 glib/gnulib/printf-parse.h create mode 100644 glib/gnulib/printf.c create mode 100644 glib/gnulib/printf.h create mode 100644 glib/gnulib/signbitd.c create mode 100644 glib/gnulib/signbitf.c create mode 100644 glib/gnulib/signbitl.c create mode 100644 glib/gnulib/vasnprintf.c create mode 100644 glib/gnulib/vasnprintf.h create mode 100644 glib/gnulib/verify.h create mode 100644 glib/gnulib/xsize.c create mode 100644 glib/gnulib/xsize.h create mode 100644 glib/goption.c create mode 100644 glib/goption.h create mode 100644 glib/gosxutils.m create mode 100644 glib/gpattern.c create mode 100644 glib/gpattern.h create mode 100644 glib/gpoll.c create mode 100644 glib/gpoll.h create mode 100644 glib/gprimes.c create mode 100644 glib/gprimes.h create mode 100644 glib/gprintf.c create mode 100644 glib/gprintf.h create mode 100644 glib/gprintfint.h create mode 100644 glib/gqsort.c create mode 100644 glib/gqsort.h create mode 100644 glib/gquark.c create mode 100644 glib/gquark.h create mode 100644 glib/gqueue.c create mode 100644 glib/gqueue.h create mode 100644 glib/grand.c create mode 100644 glib/grand.h create mode 100644 glib/grcbox.c create mode 100644 glib/grcbox.h create mode 100644 glib/grcboxprivate.h create mode 100644 glib/grefcount.c create mode 100644 glib/grefcount.h create mode 100644 glib/grefstring.c create mode 100644 glib/grefstring.h create mode 100644 glib/gregex.c create mode 100644 glib/gregex.h create mode 100644 glib/gscanner.c create mode 100644 glib/gscanner.h create mode 100644 glib/gscripttable.h create mode 100644 glib/gsequence.c create mode 100644 glib/gsequence.h create mode 100644 glib/gshell.c create mode 100644 glib/gshell.h create mode 100644 glib/gslice.c create mode 100644 glib/gslice.h create mode 100644 glib/gslist.c create mode 100644 glib/gslist.h create mode 100644 glib/gspawn-private.h create mode 100644 glib/gspawn-win32-helper.c create mode 100644 glib/gspawn-win32.c create mode 100644 glib/gspawn.c create mode 100644 glib/gspawn.h create mode 100644 glib/gstdio-private.c create mode 100644 glib/gstdio.c create mode 100644 glib/gstdio.h create mode 100644 glib/gstdioprivate.h create mode 100644 glib/gstrfuncs.c create mode 100644 glib/gstrfuncs.h create mode 100644 glib/gstring.c create mode 100644 glib/gstring.h create mode 100644 glib/gstringchunk.c create mode 100644 glib/gstringchunk.h create mode 100644 glib/gstrvbuilder.c create mode 100644 glib/gstrvbuilder.h create mode 100644 glib/gtester-report.in create mode 100644 glib/gtester.c create mode 100644 glib/gtestutils.c create mode 100644 glib/gtestutils.h create mode 100644 glib/gthread-posix.c create mode 100644 glib/gthread-win32.c create mode 100644 glib/gthread.c create mode 100644 glib/gthread.h create mode 100644 glib/gthreadpool.c create mode 100644 glib/gthreadpool.h create mode 100644 glib/gthreadprivate.h create mode 100644 glib/gtimer.c create mode 100644 glib/gtimer.h create mode 100644 glib/gtimezone.c create mode 100644 glib/gtimezone.h create mode 100644 glib/gtrace-private.h create mode 100644 glib/gtrace.c create mode 100644 glib/gtranslit-data.h create mode 100644 glib/gtranslit.c create mode 100644 glib/gtrashstack.c create mode 100644 glib/gtrashstack.h create mode 100644 glib/gtree.c create mode 100644 glib/gtree.h create mode 100644 glib/gtypes.h create mode 100644 glib/gunibreak.c create mode 100644 glib/gunibreak.h create mode 100644 glib/gunichartables.h create mode 100644 glib/gunicode.h create mode 100644 glib/gunicodeprivate.h create mode 100644 glib/gunicollate.c create mode 100644 glib/gunicomp.h create mode 100644 glib/gunidecomp.c create mode 100644 glib/gunidecomp.h create mode 100644 glib/guniprop.c create mode 100644 glib/guri.c create mode 100644 glib/guri.h create mode 100644 glib/guriprivate.h create mode 100644 glib/gutf8.c create mode 100644 glib/gutils.c create mode 100644 glib/gutils.h create mode 100644 glib/gutilsprivate.h create mode 100644 glib/guuid.c create mode 100644 glib/guuid.h create mode 100644 glib/gvalgrind.h create mode 100644 glib/gvariant-core.c create mode 100644 glib/gvariant-core.h create mode 100644 glib/gvariant-internal.h create mode 100644 glib/gvariant-parser.c create mode 100644 glib/gvariant-serialiser.c create mode 100644 glib/gvariant-serialiser.h create mode 100644 glib/gvariant.c create mode 100644 glib/gvariant.h create mode 100644 glib/gvarianttype.c create mode 100644 glib/gvarianttype.h create mode 100644 glib/gvarianttypeinfo.c create mode 100644 glib/gvarianttypeinfo.h create mode 100644 glib/gversion.c create mode 100644 glib/gversion.h create mode 100644 glib/gversionmacros.h create mode 100644 glib/gwakeup.c create mode 100644 glib/gwakeup.h create mode 100644 glib/gwin32-private.c create mode 100644 glib/gwin32.c create mode 100644 glib/gwin32.h create mode 100644 glib/libcharset/.gitignore create mode 100644 glib/libcharset/README create mode 100644 glib/libcharset/codeset.m4 create mode 100755 glib/libcharset/config.charset create mode 100644 glib/libcharset/glibc21.m4 create mode 100644 glib/libcharset/libcharset-glib.patch create mode 100644 glib/libcharset/libcharset.h create mode 100644 glib/libcharset/localcharset.c create mode 100644 glib/libcharset/localcharset.h create mode 100755 glib/libcharset/make-patch.sh create mode 100644 glib/libcharset/meson.build create mode 100644 glib/libcharset/ref-add.sin create mode 100644 glib/libcharset/ref-del.sin create mode 100755 glib/libcharset/update.sh create mode 100644 glib/libglib-gdb.py.in create mode 100644 glib/meson.build create mode 100644 glib/tests/.gitignore create mode 100644 glib/tests/1bit-mutex.c create mode 100644 glib/tests/4096-random-bytes create mode 100644 glib/tests/642026.c create mode 100644 glib/tests/array-test.c create mode 100644 glib/tests/asyncqueue.c create mode 100644 glib/tests/atomic.c create mode 100644 glib/tests/autoptr.c create mode 100644 glib/tests/base64.c create mode 100644 glib/tests/bitlock.c create mode 100644 glib/tests/bookmarkfile.c create mode 100644 glib/tests/bookmarks.xbel create mode 100644 glib/tests/bookmarks/fail-01.xbel create mode 100644 glib/tests/bookmarks/fail-02.xbel create mode 100644 glib/tests/bookmarks/fail-03.xbel create mode 100644 glib/tests/bookmarks/fail-04.xbel create mode 100644 glib/tests/bookmarks/fail-05.xbel create mode 100644 glib/tests/bookmarks/fail-06.xbel create mode 100644 glib/tests/bookmarks/fail-07.xbel create mode 100644 glib/tests/bookmarks/fail-08.xbel create mode 100644 glib/tests/bookmarks/fail-09.xbel create mode 100644 glib/tests/bookmarks/fail-10.xbel create mode 100644 glib/tests/bookmarks/fail-11.xbel create mode 100644 glib/tests/bookmarks/fail-12.xbel create mode 100644 glib/tests/bookmarks/fail-13.xbel create mode 100644 glib/tests/bookmarks/fail-14.xbel create mode 100644 glib/tests/bookmarks/fail-15.xbel create mode 100644 glib/tests/bookmarks/fail-16.xbel create mode 100644 glib/tests/bookmarks/fail-17.xbel create mode 100644 glib/tests/bookmarks/fail-18.xbel create mode 100644 glib/tests/bookmarks/fail-19.xbel create mode 100644 glib/tests/bookmarks/fail-20.xbel create mode 100644 glib/tests/bookmarks/fail-21.xbel create mode 100644 glib/tests/bookmarks/fail-22.xbel create mode 100644 glib/tests/bookmarks/fail-23.xbel create mode 100644 glib/tests/bookmarks/fail-24.xbel create mode 100644 glib/tests/bookmarks/fail-25.xbel create mode 100644 glib/tests/bookmarks/fail-26.xbel create mode 100644 glib/tests/bookmarks/fail-27.xbel create mode 100644 glib/tests/bookmarks/fail-28.xbel create mode 100644 glib/tests/bookmarks/fail-29.xbel create mode 100644 glib/tests/bookmarks/fail-30.xbel create mode 100644 glib/tests/bookmarks/fail-31.xbel create mode 100644 glib/tests/bookmarks/fail-32.xbel create mode 100644 glib/tests/bookmarks/fail-33.xbel create mode 100644 glib/tests/bookmarks/fail-34.xbel create mode 100644 glib/tests/bookmarks/fail-35.xbel create mode 100644 glib/tests/bookmarks/fail-36.xbel create mode 100644 glib/tests/bookmarks/fail-37.xbel create mode 100644 glib/tests/bookmarks/fail-38.xbel create mode 100644 glib/tests/bookmarks/fail-39.xbel create mode 100644 glib/tests/bookmarks/fail-40.xbel create mode 100644 glib/tests/bookmarks/fail-41.xbel create mode 100644 glib/tests/bookmarks/fail-42.xbel create mode 100644 glib/tests/bookmarks/valid-01.xbel create mode 100644 glib/tests/bookmarks/valid-02.xbel create mode 100644 glib/tests/bookmarks/valid-03.xbel create mode 100644 glib/tests/bytes.c create mode 100644 glib/tests/cache.c create mode 100644 glib/tests/casefold.txt create mode 100644 glib/tests/casemap.txt create mode 100644 glib/tests/charset.c create mode 100644 glib/tests/checksum.c create mode 100644 glib/tests/collate.c create mode 100644 glib/tests/completion.c create mode 100644 glib/tests/cond.c create mode 100644 glib/tests/convert.c create mode 100644 glib/tests/cxx.cpp create mode 100644 glib/tests/dataset.c create mode 100644 glib/tests/date.c create mode 100644 glib/tests/dir.c create mode 100755 glib/tests/echo-script create mode 100644 glib/tests/echo-script.bat create mode 100644 glib/tests/empty create mode 100644 glib/tests/environment.c create mode 100644 glib/tests/error.c create mode 100644 glib/tests/fileutils.c create mode 100644 glib/tests/gdatetime.c create mode 100755 glib/tests/gen-casefold-txt.py create mode 100755 glib/tests/gen-casemap-txt.py create mode 100644 glib/tests/getpwuid-preload.c create mode 100644 glib/tests/gpoll.c create mode 100644 glib/tests/gutils-user-database.c create mode 100644 glib/tests/guuid.c create mode 100644 glib/tests/gvariant.c create mode 100644 glib/tests/gwakeuptest.c create mode 100644 glib/tests/hash.c create mode 100644 glib/tests/hmac.c create mode 100644 glib/tests/hook.c create mode 100644 glib/tests/hostutils.c create mode 100644 glib/tests/include.c create mode 100644 glib/tests/io-channel.c create mode 100644 glib/tests/iochannel-test-infile create mode 100644 glib/tests/keyfile.c create mode 100644 glib/tests/keyfiletest.ini create mode 100644 glib/tests/list.c create mode 100644 glib/tests/logging.c create mode 100644 glib/tests/macros.c create mode 100644 glib/tests/mainloop.c create mode 100644 glib/tests/mappedfile.c create mode 100644 glib/tests/markup-collect.c create mode 100644 glib/tests/markup-escape.c create mode 100644 glib/tests/markup-parse.c create mode 100644 glib/tests/markup-subparser.c create mode 100644 glib/tests/markup.c create mode 100644 glib/tests/markups/fail-1.expected create mode 100644 glib/tests/markups/fail-1.gmarkup create mode 100644 glib/tests/markups/fail-10.expected create mode 100644 glib/tests/markups/fail-10.gmarkup create mode 100644 glib/tests/markups/fail-11.expected create mode 100644 glib/tests/markups/fail-11.gmarkup create mode 100644 glib/tests/markups/fail-12.expected create mode 100644 glib/tests/markups/fail-12.gmarkup create mode 100644 glib/tests/markups/fail-13.expected create mode 100644 glib/tests/markups/fail-13.gmarkup create mode 100644 glib/tests/markups/fail-14.expected create mode 100644 glib/tests/markups/fail-14.gmarkup create mode 100644 glib/tests/markups/fail-15.expected create mode 100644 glib/tests/markups/fail-15.gmarkup create mode 100644 glib/tests/markups/fail-16.expected create mode 100644 glib/tests/markups/fail-16.gmarkup create mode 100644 glib/tests/markups/fail-17.expected create mode 100644 glib/tests/markups/fail-17.gmarkup create mode 100644 glib/tests/markups/fail-18.expected create mode 100644 glib/tests/markups/fail-18.gmarkup create mode 100644 glib/tests/markups/fail-19.expected create mode 100644 glib/tests/markups/fail-19.gmarkup create mode 100644 glib/tests/markups/fail-2.expected create mode 100644 glib/tests/markups/fail-2.gmarkup create mode 100644 glib/tests/markups/fail-20.expected create mode 100644 glib/tests/markups/fail-20.gmarkup create mode 100644 glib/tests/markups/fail-21.expected create mode 100644 glib/tests/markups/fail-21.gmarkup create mode 100644 glib/tests/markups/fail-22.expected create mode 100644 glib/tests/markups/fail-22.gmarkup create mode 100644 glib/tests/markups/fail-23.expected create mode 100644 glib/tests/markups/fail-23.gmarkup create mode 100644 glib/tests/markups/fail-24.expected create mode 100644 glib/tests/markups/fail-24.gmarkup create mode 100644 glib/tests/markups/fail-25.expected create mode 100644 glib/tests/markups/fail-25.gmarkup create mode 100644 glib/tests/markups/fail-26.expected create mode 100644 glib/tests/markups/fail-26.gmarkup create mode 100644 glib/tests/markups/fail-27.expected create mode 100644 glib/tests/markups/fail-27.gmarkup create mode 100644 glib/tests/markups/fail-28.expected create mode 100644 glib/tests/markups/fail-28.gmarkup create mode 100644 glib/tests/markups/fail-29.expected create mode 100644 glib/tests/markups/fail-29.gmarkup create mode 100644 glib/tests/markups/fail-3.expected create mode 100644 glib/tests/markups/fail-3.gmarkup create mode 100644 glib/tests/markups/fail-30.expected create mode 100644 glib/tests/markups/fail-30.gmarkup create mode 100644 glib/tests/markups/fail-31.expected create mode 100644 glib/tests/markups/fail-31.gmarkup create mode 100644 glib/tests/markups/fail-32.expected create mode 100644 glib/tests/markups/fail-32.gmarkup create mode 100644 glib/tests/markups/fail-33.expected create mode 100644 glib/tests/markups/fail-33.gmarkup create mode 100644 glib/tests/markups/fail-34.expected create mode 100644 glib/tests/markups/fail-34.gmarkup create mode 100644 glib/tests/markups/fail-35.expected create mode 100644 glib/tests/markups/fail-35.gmarkup create mode 100644 glib/tests/markups/fail-36.expected create mode 100644 glib/tests/markups/fail-36.gmarkup create mode 100644 glib/tests/markups/fail-37.expected create mode 100644 glib/tests/markups/fail-37.gmarkup create mode 100644 glib/tests/markups/fail-38.expected create mode 100644 glib/tests/markups/fail-38.gmarkup create mode 100644 glib/tests/markups/fail-39.expected create mode 100644 glib/tests/markups/fail-39.gmarkup create mode 100644 glib/tests/markups/fail-4.expected create mode 100644 glib/tests/markups/fail-4.gmarkup create mode 100644 glib/tests/markups/fail-40.expected create mode 100644 glib/tests/markups/fail-40.gmarkup create mode 100644 glib/tests/markups/fail-41.expected create mode 100644 glib/tests/markups/fail-41.gmarkup create mode 100644 glib/tests/markups/fail-42.expected create mode 100644 glib/tests/markups/fail-42.gmarkup create mode 100644 glib/tests/markups/fail-43.expected create mode 100644 glib/tests/markups/fail-43.gmarkup create mode 100644 glib/tests/markups/fail-44.expected create mode 100644 glib/tests/markups/fail-44.gmarkup create mode 100644 glib/tests/markups/fail-45.expected create mode 100644 glib/tests/markups/fail-45.gmarkup create mode 100644 glib/tests/markups/fail-46.expected create mode 100644 glib/tests/markups/fail-46.gmarkup create mode 100644 glib/tests/markups/fail-47.expected create mode 100644 glib/tests/markups/fail-47.gmarkup create mode 100644 glib/tests/markups/fail-48.expected create mode 100644 glib/tests/markups/fail-48.gmarkup create mode 100644 glib/tests/markups/fail-49.expected create mode 100644 glib/tests/markups/fail-49.gmarkup create mode 100644 glib/tests/markups/fail-5.expected create mode 100644 glib/tests/markups/fail-5.gmarkup create mode 100644 glib/tests/markups/fail-50.expected create mode 100644 glib/tests/markups/fail-50.gmarkup create mode 100644 glib/tests/markups/fail-51.expected create mode 100644 glib/tests/markups/fail-51.gmarkup create mode 100644 glib/tests/markups/fail-52.expected create mode 100644 glib/tests/markups/fail-52.gmarkup create mode 100644 glib/tests/markups/fail-53.expected create mode 100644 glib/tests/markups/fail-53.gmarkup create mode 100644 glib/tests/markups/fail-54.expected create mode 100644 glib/tests/markups/fail-54.gmarkup create mode 100644 glib/tests/markups/fail-6.expected create mode 100644 glib/tests/markups/fail-6.gmarkup create mode 100644 glib/tests/markups/fail-7.expected create mode 100644 glib/tests/markups/fail-7.gmarkup create mode 100644 glib/tests/markups/fail-8.expected create mode 100644 glib/tests/markups/fail-8.gmarkup create mode 100644 glib/tests/markups/fail-9.expected create mode 100644 glib/tests/markups/fail-9.gmarkup create mode 100644 glib/tests/markups/valid-1.expected create mode 100644 glib/tests/markups/valid-1.gmarkup create mode 100644 glib/tests/markups/valid-10.expected create mode 100644 glib/tests/markups/valid-10.gmarkup create mode 100644 glib/tests/markups/valid-11.expected create mode 100644 glib/tests/markups/valid-11.gmarkup create mode 100644 glib/tests/markups/valid-12.expected create mode 100644 glib/tests/markups/valid-12.gmarkup create mode 100644 glib/tests/markups/valid-13.expected create mode 100644 glib/tests/markups/valid-13.gmarkup create mode 100644 glib/tests/markups/valid-14.expected create mode 100644 glib/tests/markups/valid-14.gmarkup create mode 100644 glib/tests/markups/valid-15.expected create mode 100644 glib/tests/markups/valid-15.gmarkup create mode 100644 glib/tests/markups/valid-16.cdata-as-text create mode 100644 glib/tests/markups/valid-16.expected create mode 100644 glib/tests/markups/valid-16.gmarkup create mode 100644 glib/tests/markups/valid-17.expected create mode 100644 glib/tests/markups/valid-17.gmarkup create mode 100644 glib/tests/markups/valid-2.expected create mode 100644 glib/tests/markups/valid-2.gmarkup create mode 100644 glib/tests/markups/valid-3.expected create mode 100644 glib/tests/markups/valid-3.gmarkup create mode 100644 glib/tests/markups/valid-4.expected create mode 100644 glib/tests/markups/valid-4.gmarkup create mode 100644 glib/tests/markups/valid-5.expected create mode 100644 glib/tests/markups/valid-5.gmarkup create mode 100644 glib/tests/markups/valid-6.expected create mode 100644 glib/tests/markups/valid-6.gmarkup create mode 100644 glib/tests/markups/valid-7.expected create mode 100644 glib/tests/markups/valid-7.gmarkup create mode 100644 glib/tests/markups/valid-8.cdata-as-text create mode 100644 glib/tests/markups/valid-8.expected create mode 100644 glib/tests/markups/valid-8.gmarkup create mode 100644 glib/tests/markups/valid-9.expected create mode 100644 glib/tests/markups/valid-9.gmarkup create mode 100644 glib/tests/mem-overflow.c create mode 100644 glib/tests/memchunk.c create mode 100644 glib/tests/meson.build create mode 100644 glib/tests/mutex.c create mode 100644 glib/tests/node.c create mode 100644 glib/tests/once.c create mode 100644 glib/tests/option-argv0.c create mode 100644 glib/tests/option-context.c create mode 100644 glib/tests/overflow.c create mode 100644 glib/tests/pages.ini create mode 100644 glib/tests/path-test-subdir/meson.build create mode 100644 glib/tests/path-test-subdir/spawn-test-helper.c create mode 100644 glib/tests/pattern.c create mode 100644 glib/tests/private.c create mode 100644 glib/tests/protocol.c create mode 100644 glib/tests/queue.c create mode 100644 glib/tests/rand.c create mode 100644 glib/tests/rcbox.c create mode 100644 glib/tests/rec-mutex.c create mode 100644 glib/tests/refcount.c create mode 100644 glib/tests/refstring.c create mode 100644 glib/tests/regex.c create mode 100644 glib/tests/relation.c create mode 100644 glib/tests/rwlock.c create mode 100644 glib/tests/scannerapi.c create mode 100644 glib/tests/search-utils.c create mode 100644 glib/tests/sequence.c create mode 100644 glib/tests/shell.c create mode 100644 glib/tests/slice-color.c create mode 100644 glib/tests/slice-concurrent.c create mode 100644 glib/tests/slice.c create mode 100644 glib/tests/slist.c create mode 100644 glib/tests/sort.c create mode 100644 glib/tests/spawn-multithreaded.c create mode 100644 glib/tests/spawn-path-search-helper.c create mode 100644 glib/tests/spawn-path-search.c create mode 100644 glib/tests/spawn-singlethread.c create mode 100644 glib/tests/spawn-test-helper.c create mode 100644 glib/tests/strfuncs.c create mode 100644 glib/tests/string.c create mode 100644 glib/tests/strvbuilder.c create mode 100644 glib/tests/test-printf.c create mode 100644 glib/tests/test-spawn-echo.c create mode 100644 glib/tests/test-spawn-sleep.c create mode 100644 glib/tests/testing-helper.c create mode 100644 glib/tests/testing.c create mode 100644 glib/tests/thread-pool.c create mode 100644 glib/tests/thread.c create mode 100644 glib/tests/time-zones/Amsterdam-fat create mode 100644 glib/tests/time-zones/Amsterdam-slim create mode 100644 glib/tests/timeout.c create mode 100644 glib/tests/timer.c create mode 100644 glib/tests/tree.c create mode 100644 glib/tests/types.c create mode 100644 glib/tests/unicode.c create mode 100644 glib/tests/unix.c create mode 100644 glib/tests/uri.c create mode 100644 glib/tests/utf8-misc.c create mode 100644 glib/tests/utf8-performance.c create mode 100644 glib/tests/utf8-pointer.c create mode 100644 glib/tests/utf8-validate.c create mode 100644 glib/tests/utils.c create mode 100644 glib/tests/win32.c create mode 100755 glib/update-gtranslit.py create mode 100644 glib/valgrind.h create mode 100644 glib/win_iconv.c create mode 100644 gmodule/AUTHORS create mode 100644 gmodule/COPYING create mode 100644 gmodule/gmodule-ar.c create mode 100644 gmodule/gmodule-dl.c create mode 100644 gmodule/gmodule-win32.c create mode 100644 gmodule/gmodule.c create mode 100644 gmodule/gmodule.h create mode 100644 gmodule/gmodule.rc.in create mode 100644 gmodule/gmoduleconf.h.in create mode 100644 gmodule/meson.build create mode 100644 gmodule/tests/cxx.cpp create mode 100644 gmodule/tests/meson.build create mode 100644 gobject/gatomicarray.c create mode 100644 gobject/gatomicarray.h create mode 100644 gobject/gbinding.c create mode 100644 gobject/gbinding.h create mode 100644 gobject/gbindinggroup.c create mode 100644 gobject/gbindinggroup.h create mode 100644 gobject/gboxed.c create mode 100644 gobject/gboxed.h create mode 100644 gobject/gclosure.c create mode 100644 gobject/gclosure.h create mode 100644 gobject/genums.c create mode 100644 gobject/genums.h create mode 100644 gobject/glib-enumtypes.c.template create mode 100644 gobject/glib-enumtypes.h.template create mode 100755 gobject/glib-genmarshal.in create mode 100755 gobject/glib-mkenums.in create mode 100644 gobject/glib-types.h create mode 100644 gobject/gmarshal.c create mode 100644 gobject/gmarshal.h create mode 100644 gobject/gobject-autocleanups.h create mode 100644 gobject/gobject-query.c create mode 100644 gobject/gobject.c create mode 100644 gobject/gobject.h create mode 100644 gobject/gobject.rc.in create mode 100644 gobject/gobject.stp.in create mode 100644 gobject/gobject_gdb.py create mode 100644 gobject/gobject_probes.d create mode 100644 gobject/gobject_trace.h create mode 100644 gobject/gobjectnotifyqueue.c create mode 100644 gobject/gparam.c create mode 100644 gobject/gparam.h create mode 100644 gobject/gparamspecs.c create mode 100644 gobject/gparamspecs.h create mode 100644 gobject/gsignal.c create mode 100644 gobject/gsignal.h create mode 100644 gobject/gsignalgroup.c create mode 100644 gobject/gsignalgroup.h create mode 100644 gobject/gsourceclosure.c create mode 100644 gobject/gsourceclosure.h create mode 100644 gobject/gtype-private.h create mode 100644 gobject/gtype.c create mode 100644 gobject/gtype.h create mode 100644 gobject/gtypemodule.c create mode 100644 gobject/gtypemodule.h create mode 100644 gobject/gtypeplugin.c create mode 100644 gobject/gtypeplugin.h create mode 100644 gobject/gvalue.c create mode 100644 gobject/gvalue.h create mode 100644 gobject/gvaluearray.c create mode 100644 gobject/gvaluearray.h create mode 100644 gobject/gvaluecollector.h create mode 100644 gobject/gvaluetransform.c create mode 100644 gobject/gvaluetypes.c create mode 100644 gobject/gvaluetypes.h create mode 100644 gobject/libgobject-gdb.py.in create mode 100644 gobject/meson.build create mode 100644 gobject/tests/.gitignore create mode 100644 gobject/tests/autoptr.c create mode 100644 gobject/tests/binding.c create mode 100644 gobject/tests/bindinggroup.c create mode 100644 gobject/tests/boxed.c create mode 100644 gobject/tests/closure-refcount.c create mode 100644 gobject/tests/closure.c create mode 100644 gobject/tests/cxx.cpp create mode 100644 gobject/tests/dynamictests.c create mode 100644 gobject/tests/enums.c create mode 100644 gobject/tests/flags.c create mode 100644 gobject/tests/genmarshal.py create mode 100644 gobject/tests/ifaceproperties.c create mode 100644 gobject/tests/marshalers.list create mode 100644 gobject/tests/meson.build create mode 100644 gobject/tests/mkenums.py create mode 100644 gobject/tests/object.c create mode 100644 gobject/tests/param.c create mode 100644 gobject/tests/private.c create mode 100644 gobject/tests/properties.c create mode 100644 gobject/tests/qdata.c create mode 100644 gobject/tests/reference.c create mode 100644 gobject/tests/signal-handler.c create mode 100644 gobject/tests/signalgroup.c create mode 100644 gobject/tests/signals.c create mode 100644 gobject/tests/taptestrunner.py create mode 100644 gobject/tests/testcommon.h create mode 100644 gobject/tests/testing.c create mode 100644 gobject/tests/threadtests.c create mode 100644 gobject/tests/type-flags.c create mode 100644 gobject/tests/type.c create mode 100644 gobject/tests/value.c create mode 100644 gthread/gthread-impl.c create mode 100644 gthread/gthread.def create mode 100644 gthread/gthread.rc.in create mode 100644 gthread/meson.build create mode 100644 m4macros/attributes.m4 create mode 100644 m4macros/glib-2.0.m4 create mode 100644 m4macros/glib-gettext.m4 create mode 100644 m4macros/glibtests.m4 create mode 100644 m4macros/gsettings.m4 create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 msvc_recommended_pragmas.h create mode 100644 po/LINGUAS create mode 100644 po/Makefile.in.in create mode 100644 po/POTFILES.in create mode 100644 po/POTFILES.skip create mode 100644 po/af.po create mode 100644 po/am.po create mode 100644 po/an.po create mode 100644 po/ar.po create mode 100644 po/as.po create mode 100644 po/ast.po create mode 100644 po/az.po create mode 100644 po/be.po create mode 100644 po/be@latin.po create mode 100644 po/bg.po create mode 100644 po/bn.po create mode 100644 po/bn_IN.po create mode 100644 po/bs.po create mode 100644 po/ca.po create mode 100644 po/ca@valencia.po create mode 100644 po/cs.po create mode 100644 po/cy.po create mode 100644 po/da.po create mode 100644 po/de.po create mode 100644 po/dz.po create mode 100644 po/el.po create mode 100644 po/en@shaw.po create mode 100644 po/en_CA.po create mode 100644 po/en_GB.po create mode 100644 po/eo.po create mode 100644 po/es.po create mode 100644 po/et.po create mode 100644 po/eu.po create mode 100644 po/fa.po create mode 100644 po/fi.po create mode 100644 po/fr.po create mode 100644 po/fur.po create mode 100644 po/ga.po create mode 100644 po/gd.po create mode 100644 po/gl.po create mode 100644 po/gu.po create mode 100644 po/he.po create mode 100644 po/hi.po create mode 100644 po/hr.po create mode 100644 po/hu.po create mode 100644 po/hy.po create mode 100644 po/id.po create mode 100644 po/is.po create mode 100644 po/it.po create mode 100644 po/ja.po create mode 100644 po/ka.po create mode 100644 po/kk.po create mode 100644 po/kn.po create mode 100644 po/ko.po create mode 100644 po/ku.po create mode 100644 po/lt.po create mode 100644 po/lv.po create mode 100644 po/mai.po create mode 100644 po/meson.build create mode 100644 po/mg.po create mode 100644 po/mk.po create mode 100644 po/ml.po create mode 100644 po/mn.po create mode 100644 po/mr.po create mode 100644 po/ms.po create mode 100644 po/nb.po create mode 100644 po/nds.po create mode 100644 po/ne.po create mode 100644 po/nl.po create mode 100644 po/nn.po create mode 100644 po/oc.po create mode 100644 po/or.po create mode 100644 po/pa.po create mode 100644 po/pl.po create mode 100644 po/po2tbl.sed.in create mode 100644 po/ps.po create mode 100644 po/pt.po create mode 100644 po/pt_BR.po create mode 100644 po/ro.po create mode 100644 po/ru.po create mode 100644 po/rw.po create mode 100644 po/si.po create mode 100644 po/sk.po create mode 100644 po/sl.po create mode 100644 po/sq.po create mode 100644 po/sr.po create mode 100644 po/sr@ije.po create mode 100644 po/sr@latin.po create mode 100644 po/sv.po create mode 100644 po/ta.po create mode 100644 po/te.po create mode 100644 po/tg.po create mode 100644 po/th.po create mode 100644 po/tl.po create mode 100644 po/tr.po create mode 100644 po/tt.po create mode 100644 po/ug.po create mode 100644 po/uk.po create mode 100644 po/vi.po create mode 100644 po/wa.po create mode 100644 po/xh.po create mode 100644 po/yi.po create mode 100644 po/zh_CN.po create mode 100644 po/zh_HK.po create mode 100644 po/zh_TW.po create mode 100644 subprojects/gtk-doc.wrap create mode 100644 subprojects/libffi.wrap create mode 100644 subprojects/pcre.wrap create mode 100644 subprojects/proxy-libintl.wrap create mode 100644 subprojects/sysprof.wrap create mode 100644 subprojects/zlib.wrap create mode 100644 template-tap.test.in create mode 100644 template.test.in create mode 100644 tests/assert-msg-test.c create mode 100644 tests/assert-msg-test.gdb create mode 100644 tests/collate/collate-1.file create mode 100644 tests/collate/collate-1.in create mode 100644 tests/collate/collate-1.unicode create mode 100644 tests/collate/collate-2.file create mode 100644 tests/collate/collate-2.in create mode 100644 tests/collate/collate-2.unicode create mode 100644 tests/gio-test.c create mode 100644 tests/gobject/.gitignore create mode 100644 tests/gobject/accumulator.c create mode 100644 tests/gobject/defaultiface.c create mode 100644 tests/gobject/deftype.c create mode 100644 tests/gobject/dynamictype.c create mode 100644 tests/gobject/meson.build create mode 100644 tests/gobject/override.c create mode 100644 tests/gobject/performance-threaded.c create mode 100644 tests/gobject/performance.c create mode 100644 tests/gobject/references.c create mode 100644 tests/gobject/signals.c create mode 100644 tests/gobject/singleton.c create mode 100644 tests/gobject/testcommon.h create mode 100644 tests/gobject/testgobject.c create mode 100644 tests/gobject/testmarshal.list create mode 100644 tests/gobject/testmodule.c create mode 100644 tests/gobject/testmodule.h create mode 100644 tests/gobject/timeloop-closure.c create mode 100644 tests/libmoduletestplugin_a.c create mode 100644 tests/libmoduletestplugin_b.c create mode 100644 tests/mainloop-test.c create mode 100644 tests/mapping-test.c create mode 100644 tests/memchunks.c create mode 100644 tests/meson.build create mode 100644 tests/module-test.c create mode 100644 tests/onceinit.c create mode 100644 tests/refcount/meson.build create mode 100644 tests/refcount/objects.c create mode 100644 tests/refcount/objects2.c create mode 100644 tests/refcount/properties.c create mode 100644 tests/refcount/properties2.c create mode 100644 tests/refcount/properties3.c create mode 100644 tests/refcount/properties4.c create mode 100644 tests/refcount/signals.c create mode 100755 tests/run-assert-msg-test.sh create mode 100644 tests/slice-test.c create mode 100644 tests/slice-threadinit.c create mode 100644 tests/spawn-test-win32-gui.c create mode 100644 tests/spawn-test.c create mode 100644 tests/thread-test.c create mode 100644 tests/threadpool-test.c create mode 100644 tests/timeloop-basic.c create mode 100644 tests/timeloop.c create mode 100644 tests/unicode-encoding.c create mode 100644 tests/unicode-normalize.c create mode 100644 tests/utf8.txt diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..13fd0fb --- /dev/null +++ b/.clang-format @@ -0,0 +1,11 @@ +# See https://wiki.apertis.org/Guidelines/Coding_conventions#Code_formatting +BasedOnStyle: GNU +AlwaysBreakAfterDefinitionReturnType: All +BreakBeforeBinaryOperators: None +BinPackParameters: false +SpaceAfterCStyleCast: true +# Our column limit is actually 80, but setting that results in clang-format +# making a lot of dubious hanging-indent choices; disable it and assume the +# developer will line wrap appropriately. clang-format will still check +# existing hanging indents. +ColumnLimit: 0 diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..abf24af --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1 @@ +((c-mode . ((indent-tabs-mode . nil))))) diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d433576 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf + +[*.[ch]] +indent_size = 2 +indent_style = space +insert_final_newline = true +# For the legacy tabs which still exist in the code: +tab_width = 8 + +[meson.build] +indent_size = 2 +indent_style = space + diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..16884db --- /dev/null +++ b/AUTHORS @@ -0,0 +1,40 @@ +Below are just a few of the people who have contributed +to GLib. Please don't mail these people about problems you +have with GLib; see the README.md file for information about +filing bugs and submitting changes. + +GLib-2.0 Team +------------- +Hans Breuer +Matthias Clasen +Tor Lillqvist +Tim Janik +Havoc Pennington +Ron Steinke +Owen Taylor +Sebastian Wilhelmi + +GLib-1.2 Team +------------- +Shawn T. Amundson +Jeff Garzik +Raja R Harinath +Tim Janik +Elliot Lee +Tor Lillqvist +Paolo Molaro +Havoc Pennington +Manish Singh +Owen Taylor +Sebastian Wilhelmi + +The random number generator "Mersenne Twister", which is used by GLib, +was developed and originally coded by: +Makoto Matsumoto +Takuji Nishimura + +Original Authors +---------------- +Peter Mattis +Spencer Kimball +Josh MacDonald diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ba8039d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,274 @@ +# Contribution guidelines + +Thank you for considering contributing to the GLib project! + +These guidelines are meant for new contributors, regardless of their level +of proficiency; following them allows the core developers of the GLib project to +more effectively evaluate your contribution, and provide prompt feedback to +you. Additionally, by following these guidelines you clearly communicate +that you respect the time and effort that the people developing GLib put into +managing the project. + +GLib is a complex free software utility library, and it would not exist without +contributions from the free and open source software community. There are +many things that we value: + + - bug reporting and fixing + - documentation and examples + - tests + - testing and support for other platforms + - new features + +Please, do not use the issue tracker for support questions. If you have +questions on how to use GLib effectively, you can use: + + - the `#gtk` IRC channel on irc.gnome.org + - the [`glib` tag on GNOME's Discourse](https://discourse.gnome.org/tags/glib) + +You can also look at the [`glib` tag on Stack +Overflow](https://stackoverflow.com/questions/tagged/glib). + +The issue tracker is meant to be used for actionable issues only. + +## How to report bugs + +### Security issues + +You should not open a new issue for security related questions. + +When in doubt, send an email to the [security](mailto:security@gnome.org) +mailing list. + +### Bug reports + +If you’re reporting a bug make sure to list: + + 0. which version of GLib are you using? + 0. which operating system are you using? + 0. the necessary steps to reproduce the issue + 0. the expected outcome + 0. a description of the behavior + 0. a small, self-contained example exhibiting the behavior + +If the issue includes a crash, you should also include: + + 0. the eventual warnings printed on the terminal + 0. a backtrace, obtained with tools such as GDB or LLDB + +If the issue includes a memory leak, you should also include: + + 0. a log of definite leaks from a tool such as [valgrind’s + memcheck](http://valgrind.org/docs/manual/mc-manual.html) + +For small issues, such as: + + - spelling/grammar fixes in the documentation, + - typo correction, + - comment clean ups, + - changes to metadata files (CI, `.gitignore`), + - build system changes, or + - source tree clean ups and reorganizations; + +or for self-contained bug fixes where you have implemented and tested a solution +already, you should directly open a merge request instead of filing a new issue. + +### Features and enhancements + +Feature discussion can be open ended and require high bandwidth channels; if +you are proposing a new feature on the issue tracker, make sure to make +an actionable proposal, and list: + + 0. what you’re trying to achieve and the problem it solves + 0. three (or more) existing pieces of software which would benefit from the + new feature + 0. how the feature is implementable on platforms other than Linux + +New APIs, in particular, should follow the ‘rule of three’, where there should +be three (or more) pieces of software which are ready to use the new APIs. This +allows us to check that the new APIs are usable in real-life code, and fit well +with related APIs. This reduces the chances of awkward or unusable APIs becoming +stable in GLib and having to be supported forever. + +A common way to introduce new APIs or data types to GLib is to prototype them in +another code base for a while, to gain real-life experience with them before +they are imported into GLib and marked as stable. + +Each feature should also come fully documented, and with tests which approach +full branch coverage of the new code. GLib’s CI system generates code coverage +reports which are viewable for each merge request. + +If proposing a large feature or change, it’s better to discuss it (on the +`#gtk` IRC channel or on [Discourse](https://discourse.gnome.org) before +putting time into writing an actionable issue — and certainly before putting +time into writing a merge request. + +## Your first contribution + +### Prerequisites + +If you want to contribute to the GLib project, you will need to have the +development tools appropriate for your operating system, including: + + - Python 3.x + - Meson + - Ninja + - Gettext (19.7 or newer) + - a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements) + +Up-to-date instructions about developing GNOME applications and libraries +can be found on [the GNOME Developer Center](https://developer.gnome.org). + +The [GLib project uses GitLab](https://gitlab.gnome.org/GNOME/glib/) for code +hosting and for tracking issues. More information about using GitLab can be +found [on the GNOME wiki](https://wiki.gnome.org/GitLab). + +### Getting started + +You should start by forking the GLib repository from the GitLab web UI, and +cloning from your fork: + +```sh +$ git clone https://gitlab.gnome.org/yourusername/glib.git +$ cd glib +``` + +**Note**: if you plan to push changes to back to the main repository and +have a GNOME account, you can skip the fork, and use the following instead: + +```sh +$ git clone git@gitlab.gnome.org:GNOME/glib.git +$ cd glib +``` + +To compile the Git version of GLib on your system, you will need to +configure your build using Meson: + +```sh +$ meson _builddir . +$ cd _builddir +$ ninja +``` + +Typically, you should work on your own branch: + +```sh +$ git checkout -b your-branch +``` + +Once you’ve finished working on the bug fix or feature, push the branch +to the Git repository and open a new merge request, to let the GLib +core developers review your contribution. + +### Code reviews + +Each contribution is reviewed by the core developers of the GLib project. + +The [CODEOWNERS](./docs/CODEOWNERS) document contains the list of core +contributors to GLib and the areas for which they are responsible; you +should ensure to receive their review and signoff on your changes. + +It is our intention that every commit to GLib is reviewed by at least one other +person, including commits from core developers. We all make mistakes and can +always learn from each other, and code review allows that. It also reduces +[bus factor](https://en.wikipedia.org/wiki/Bus_factor) by spreading knowledge +of each commit between at least two people. + +With each code review, we intend to: + + 0. Identify if this is a desirable change or new feature. Ideally for larger + features this will have been discussed (in an issue, on IRC, or on Discourse) + already, so that effort isn’t wasted on putting together merge requests + which will be rejected. + 0. Check the design of any new API. + 0. Provide realistic estimates of how long a review might take, if it can’t + happen immediately. + 0. Ensure that all significant contributions of new code, or bug fixes, are + adequately tested, either through requiring tests to be submitted at the + same time, or as a follow-up. + 0. Ensure that all new APIs are documented and have [introspection + annotations](https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations). + 0. Check that the contribution is split into logically separate commits, each + with a good commit message. + 0. Encourage further high quality contributions. + 0. Ensure code style and quality is upheld. + +If a code review is stalled (due to not receiving comments for two or more +weeks; or due to a technical disagreement), please ping another GLib core +developer on the merge request, or on IRC, to ask for a second opinion. + +### Commit messages + +The expected format for git commit messages is as follows: + +```plain +Short explanation of the commit + +Longer explanation explaining exactly what’s changed, whether any +external or private interfaces changed, what bugs were fixed (with bug +tracker reference if applicable) and so forth. Be concise but not too +brief. + +Closes #1234 +``` + + - Always add a brief description of the commit to the _first_ line of + the commit and terminate by two newlines (it will work without the + second newline, but that is not nice for the interfaces). + + - First line (the brief description) must only be one sentence and + should start with a capital letter unless it starts with a lowercase + symbol or identifier. Don’t use a trailing period either. Don’t exceed + 72 characters. + + - The main description (the body) is normal prose and should use normal + punctuation and capital letters where appropriate. Consider the commit + message as an email sent to the developers (or yourself, six months + down the line) detailing **why** you changed something. There’s no need + to specify the **how**: the changes can be inlined. + + - When committing code on behalf of others use the `--author` option, e.g. + `git commit -a --author "Joe Coder "` and `--signoff`. + + - If your commit is addressing an issue, use the + [GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html) + to automatically close the issue when merging the commit with the upstream + repository: + +```plain +Closes #1234 +Fixes #1234 +Closes: https://gitlab.gnome.org/GNOME/glib/issues/1234 +``` + + - If you have a merge request with multiple commits and none of them + completely fixes an issue, you should add a reference to the issue in + the commit message, e.g. `Bug: #1234`, and use the automatic issue + closing syntax in the description of the merge request. + +### Merge access to the GLib repository + +GLib is part of the GNOME infrastructure. At the current time, any +person with write access to the GNOME repository can merge merge requests to +GLib. This is a good thing, in that it allows maintainership to be delegated +and shared as needed. However, GLib is a fairly large and complicated package +that many other things depend on, and which has platform specific behavior — so +to avoid unnecessary breakage, and to take advantage of the knowledge about GLib +that has been built up over the years, we’d like to ask people contributing to +GLib to follow a few rules: + +0. Never push to the `main` branch, or any stable branches, directly; you + should always go through a merge request, to ensure that the code is + tested on the CI infrastructure at the very least. A merge request is + also the proper place to get a comprehensive code review from the core + developers of GLib. + +0. Always get a code review, even for seemingly trivial changes. + +0. Pay attention to the CI results. Merge requests cannot be merged until the + CI passes. If they consistently fail, either something is wrong with the + change, or the CI tests need fixing — in either case, please bring this to + the attention of a core developer rather than overriding the CI. + +If you have been contributing to GLib for a while and you don’t have commit +access to the repository, you may ask to obtain it following the [GNOME account +process](https://wiki.gnome.org/AccountsTeam/NewAccounts). diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/HACKING b/HACKING new file mode 100644 index 0000000..3306350 --- /dev/null +++ b/HACKING @@ -0,0 +1,17 @@ +If you want to hack on the GLib project, you'll need to have the +following packages installed: + + - Meson 0.48.0 + - GNU gettext 0.10.40 + - pkg-config 0.16 + - gtk-doc + - libffi 3.0.0 + +To compile a Git version of glib on your system, you will need to take +several steps to setup the tree for compilation. You can do all these +steps at once by running: + + checkout/glib# meson _build + +For information about submitting patches see the CONTRIBUTING.md file. For +information about major design decisions, see the README.rationale file. diff --git a/INSTALL.in b/INSTALL.in new file mode 100644 index 0000000..c5b551c --- /dev/null +++ b/INSTALL.in @@ -0,0 +1,125 @@ +Simple install procedure +======================== + + % tar xf glib-@GLIB_VERSION@.tar.gz # unpack the sources + % cd glib-@GLIB_VERSION@ # change to the toplevel directory + % meson _build # configure the build + % ninja -C _build # build GLib + + [ Become root if necessary ] + % ninja -C _build install # install GLib + +Requirements +============ + +GLib requires a C90-compliant (but not necessarily C99-compliant) C +compiler and libc. On UNIX-like systems, it also assumes compliance +with at least the original 1990 version of POSIX. + +GLib-2.0 requires pkg-config, which is tool for tracking the +compilation flags needed for libraries. (For each library, a small .pc +text file is installed in a standard location that contains the +compilation flags needed for that library along with version number +information.) Information about pkg-config can be found at: + + http://www.freedesktop.org/software/pkgconfig/ + +Meson (http://mesonbuild.com/) is also required. + +In order to implement conversions between character sets, +GLib requires an implementation of the standard iconv() routine. +Most modern systems will have a suitable implementation, however +many older systems lack an iconv() implementation. On such systems, +you must install the libiconv library. This can be found at: + + http://www.gnu.org/software/libiconv/ + +If your system has an iconv implementation but you want to use +libiconv instead, you can pass the --with-libiconv option to +configure. This forces libiconv to be used. + +Note that if you have libiconv installed in your default include +search path (for instance, in /usr/local/), but don't enable +it, you will get an error while compiling GLib because the +iconv.h that libiconv installs hides the system iconv. + +If you are using the native iconv implementation on Solaris +instead of libiconv, you'll need to make sure that you have +the converters between locale encodings and UTF-8 installed. +At a minimum you'll need the SUNWuiu8 package. You probably +should also install the SUNWciu8, SUNWhiu8, SUNWjiu8, and +SUNWkiu8 packages. + +The native iconv on Compaq Tru64 doesn't contain support for +UTF-8, so you'll need to use GNU libiconv instead. (When +using GNU libiconv for GLib, you'll need to use GNU libiconv +for GNU gettext as well.) This probably applies to related +operating systems as well. + +Finally, for message catalog handling, GLib requires an implementation +of gettext(). If your system doesn't provide this functionality, +you should use the libintl library from the GNU gettext package, +available from: + + http://www.gnu.org/software/gettext/ + +Support for extended attributes and SELinux in GIO requires +libattr and libselinux. + +Some of the mimetype-related functionality in GIO requires the +update-mime-database and update-desktop-database utilities, which +are part of shared-mime-info and desktop-file-utils, respectively. + +GObject uses libffi to implement generic marshalling functionality. + +The Nitty-Gritty +================ + +Complete information about installing GLib can be found +in the file: + + docs/reference/glib/html/glib-building.html + +Or online at: + + https://developer.gnome.org/glib/stable/glib-building.html + + +Installation directories +======================== + +The location of the installed files is determined by the --prefix +and --exec-prefix options given to configure. There are also more +detailed flags to control individual directories. However, the +use of these flags is not tested. + +One particular detail to note, is that the architecture-dependent +include file glibconfig.h is installed in: + + $libdir/glib-2.0/include/ + +.pc files for the various libraries are installed in +$libdir/pkgconfig to provide information when compiling +other packages that depend on GLib. If you set PKG_CONFIG_PATH +so that it points to this directory, then you can get the +correct include flags and library flags for compiling a GLib +application with: + + pkg-config --cflags glib-2.0 + pkg-config --libs glib-2.0 + +This is the only supported way of determining the include and library flags +for building against GLib. + + +Cross-compiling GLib +==================== + +Information about cross-compilation of GLib can be found +in the file: + + docs/reference/glib/html/glib-cross-compiling.html + +Or online at: + + https://developer.gnome.org/glib/stable/glib-cross-compiling.html diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..3e862df --- /dev/null +++ b/NEWS @@ -0,0 +1,14420 @@ +Overview of changes in GLib 2.72.4 +================================== + +* Bugs fixed: + - #2634 g_cond_wait_until: returning FALSE immediately on mips24 (Philip + Withnall) + - #2687 Regression: in GLib 2.72.3, in gsocketclient/cancellable (Philip + Withnall) + - #2719 GParamSpec constructors should have nullable annotation on nick/blurb + (Andy Holmes) + - #2733 gio: GVariantBuilder builder leaked in g_document_portal_add_documents + when URI list is empty (Sebastian Keller) + - !2810 Backport !2808 “gsocketclient: Fix passing NULL to + g_task_get_cancellable()†to glib-2-72 + +* Translation updates: + - Czech (Marek ÄŒernocký) + - Georgian (Zurab Kargareteli) + - Hungarian (Balázs Úr) + - Serbian (МироÑлав Ðиколић) + - Spanish (Daniel Mustieles) + +Overview of changes in GLib 2.72.3 +================================== + +* Bugs fixed: + - #1941 disposing a non-cancelled inotify GFileMonitor causes deadlocks + - #2597 Crash in g_socket_client_enumerator_callback when proxy resolving + - #2639 xdgmime update breaks webkit2gtk file:// requests + - #2670 Growing memory when using cancellable in g_socket_client_connect_async + - !2703 glocalfilemonitor: Avoid file monitor destruction from event thread + - !2709 Backport !2707 “credentials: macos: check for existence of LOCAL_PEERPID†to glib-2-72 + - !2720 Backport !2708 “xdgmime: Fix broken file:// content type lookups for webkitgtk†to glib-2-72 + - !2750 Backport !2745 “gsocketclient: Fix still-reachable references to cancellables†to glib-2-72 + - !2787 Backport !2742 “proxyaddressenumerator: set error parameter more thoughtfully†to glib-2-72 + + +Overview of changes in GLib 2.72.2 +================================== + +* Bugs fixed: + - #2640 UWP warnings about extensions and verbs with glib 2.72.1 + - !2605 Backport !2449 and !2600 mingw test fixes to glib-2-72 + - !2616 Backport !2615 “Meson: Fix gio-windows-2.0 override name†to glib-2-72 + - !2629 Backport !2626, !2627 minor leak fixes to glib-2-72 + - !2643 Backport !2642 “meson: Check rres.compiled() before calling rres.returncode()†to glib-2-72 + - !2644 Backport !2631 “Cast to guintptr instead of subtracting by null†to glib-2-72 + - !2662 Backport !2654 “gtask: use g_strconcat() in g_task_return() only if needed†to glib-2-72 + - !2691 Backport !2661 “win32appinfo: change log level from warning to debug†to glib-2-72 + +* Translation updates: + - Croatian + - Danish + - English (United Kingdom) + - French + - Galician + - German + - Nepali + - Portuguese (Brazil) + + +Overview of changes in GLib 2.72.1 +================================== + +* Fix building projects which use g_warning_once() with clang++ (#2625) + +* Fix `g_file_trash()` not deleting directories via the portals backend (work by Matthias Clasen) (#2629) + +* A number more compiler warnings fixed for MSVC (work by Loïc Le Page) (!2495) + +* Fix detection of broken `poll()` function on macOS (work by Haruka Ma) (!2571) + +* Fix spawning subprocesses from GUI programs on Windows (work by Marc-André Lureau) (!2582) + +* Bugs fixed: + - #2312 gdbus-test-codegen tests leak GWeakRef objects + - #2625 g_warning_once fails to build with clang++ + - #2629 g_file_trash() does not work on directories inside a sandbox + - !2495 Cleanup warnings split 6 + - !2499 Various contenttype-related test fixes on win32 + - !2534 gpowerprofilemonitor: Tweak wording of documentation to make more sense + - !2540 Various win32 tests skip & fixes + - !2541 meson: simplify lookup of python command + - !2543 ci: Update the Fedora CI image to Fedora 34 + - !2556 gdbusconnection: Use g_strv_contains() rather than a home-grown version + - !2557 gdbusmethodinvocation: Fix a leak on an early return path + - !2558 Move unit test on g_basename() function to glib/tests/fileutils.c + - !2559 Move tests/relation-test.c to glib/tests/relation.c + - !2560 ci: Update Coverity, mingw and Android CI images to Fedora 34 + - !2563 glib: Format GDateTime ISO8601 years as %C%y + - !2564 Move test files on slices from tests/ to glib/tests/ + - !2566 tests: Add more tests for GResolver response parsing + - !2573 Backport translation fixes and !2571 “meson: Set BROKEN_POLL in macOS builds†to glib-2-72 + - !2574 Backport !2565 “Revert "meson: simplify lookup of python command"†to glib-2-72 + - !2587 Backport !2583 “Fix trashing sandboxed directories†to glib-2-72 + - !2588 Backport !2582 “glib/win32: fix spawn from GUI regression†to glib-2-72 + - !2590 Backport !2589 “tests: Don’t exit gdbus-method-invocation test early on connection close†to glib-2-72 + - !2593 Backport !2578 “gatomic: Add a C++ variant of g_atomic_int_compare_and_exchange()†to glib-2-72 + +* Translation updates: + - Bulgarian + - Catalan + - Indonesian + - Italian + - Lithuanian + - Polish + - Portuguese + - Russian + - Slovenian + - Swedish + - Turkish + - Ukrainian + + +Overview of changes in GLib 2.72.0 +================================== + +* Bugs fixed: + - #2620 g_time_zone_new_offset() assertion failure if offset >= 25 hours + - !2538 Various unit test fixes + - !2542 fuzzing: Fix test failure with G_DISABLE_ASSERT + - !2547 gprintf: Fix a memory leak with an invalid format in g_vasprintf() + - !2548 tests: Various fixes to gdbus-auth, gdbus-non-socket, gdbus-connection-flush, spawn-multithreaded tests + - !2551 tests: More flaky test fixes to converter-stream and test-printf + - !2552 gtlsconnection: fix typo in docs + +* Translation updates: + - Czech + - French + - Friulian + - Hebrew + - Hungarian + - Italian + - Kazakh + - Polish + - Romanian + - Serbian + - Swedish + + +Overview of changes in GLib 2.71.3 +================================== + +* Fix flaky `GDebugController` tests (!2504) + +* Numerous small documentation updates + +* Bugs fixed: + - #517 g_utf8_collate returns 0 on U+C5D0 vs U+CD94 + - #1929 gdbus-connection-flush: setup_client_cb: Exhausted all available authentication mechanisms (tried: EXTERNAL, DBUS_COOKIE_SHA1) + - #2589 Hash sign misinterpreted as heading + - #2598 g_main_loop_run() may leak a GMainLoop reference + - #2609 Clarify documentation for g_log_set_debug_enabled() + - #2611 Unspecified options considered present + - #2612 side effects of ensure_valid_dict result used in g_return_if_fail macro + - #2613 Naked magic literal in gvariant.h + - !1707 Add cache to g_unix_mount_points_get() + - !2424 Remove old test file tests/testglib.c + - !2451 glib: fix buffer overflow in g_canonicalize_filename() + - !2466 Various minor fixes for empty argv handling + - !2480 Various glib/tests/date fixes on win32 + - !2485 Various spawn-related test fixes on win32 + - !2490 Cleanup warnings split 1 + - !2491 Cleanup warnings split 2 + - !2492 Cleanup warnings split 3 + - !2493 Cleanup warnings split 4 + - !2501 glib-compile-resources: Fix a memory leak of the compiler option + - !2502 tests: Merge iochannel-test into io-channel tests in glib directory + - !2503 gbacktrace: Fix a set-but-not-used variable + - !2504 gdebugcontrollerdbus: Track pending tasks with weak refs + - !2505 tests: Stop ignoring test failures on macOS + - !2506 gresource-tool: Fix unused-but-set-variable warn with G_DISABLE_ASSERT + - !2507 ci: Drop custom dependency builds from installed-tests + - !2508 codegen: Reformat parser.py according to black + - !2509 tests: Fix various small memory leaks + - !2510 gdesktopappinfo: Fix a leak when launching URIs over D-Bus + - !2512 doc: Extend a bit G_DECLARE_* documentation example + - !2513 gmain: Expand documentation about GSource priorities a little + - !2514 ci: Various cleanups and moving Android API 21 and FreeBSD 12 to scheduled run + - !2515 gmessages: Fix typo in docs + - !2516 glocalfileinfo: Always define _g_stat_mtim_nsec, etc. + - !2517 meson: Add schemasdir and giomoduledir to gio dependency + - !2518 meson: Set GIO_EXTRA_MODULES in devenv + - !2519 gdebugcontrollerdbus: Mark a variable as G_GNUC_UNUSED + - !2520 tests: Remove threads from mock-resolver/network-address test + - !2523 Add handling of NULL time_t* pointer as argument + - !2524 Revert "meson: Add schemasdir and giomoduledir to gio dependency" + - !2525 meson: Add schemasdir and giomoduledir to gio dependency + - !2526 Remove unused test tests/testgdateparser.c + - !2527 Move tests/type-test.c to glib/tests/types.c + - !2528 meson: Add PYTHONPATH to load GDB helper module + - !2531 gtask: Document that task name is set by g_task_set_source_tag() + +* Translation updates: + - Basque + - Catalan + - Chinese (China) + - Croatian + - Danish + - German + - Hebrew + - Indonesian + - Korean + - Lithuanian + - Romanian + - Russian + - Spanish + - Turkish + + +Overview of changes in GLib 2.71.2 +================================== + +* Rework `glib-compile-resources` to output compiler-specific files to reduce + compilation time; see the new `--compiler` option (work by Emmanuele Bassi) (#2492) + +* Add a cross-platform API for aligned memory allocations (`g_aligned_alloc()`, + `g_aligned_alloc0()` and `g_aligned_free()`) (work by Emmanuele Bassi) (#2574) + +* Deprecate `force_posix_threads` configure option, since it was a workaround + for static linking on Windows (#2592) + +* Add `GBindingGroup` and `GSignalGroup` APIs (work by Christian Hergert and + Garrett Regier) (!2235) + +* Implement FD remapping support for `g_spawn_async_with_pipes_and_fds()` on + Windows (work by Marc-André Lureau) (!2458) + +* Add an async file move API, `g_file_move_async()` (work by Lucas Schwiderski) (!2469) + +* Bugs fixed: + - #1190 gapplication: Add an org.gtk.Debugging interface + - #2329 GApplication CLI parsing of DOUBLE type failure + - #2492 glib-compile-resources contains resource data twice and creates large output files + - #2563 g_test_build_filename and friends not safe to call after g_test_run() has finished + - #2574 Add API for aligned allocations + - #2592 Consider deprecating 'force_posix_threads' build option + - #2601 Missing tag in generated files + - !2235 Add GBindingGroup and GSignalGroup + - !2378 gtestutils: Mention the unit used for the test timer + - !2404 File tests + - !2433 Remove tests/testgdate.c from tests + - !2458 Implement fd passing for Windows spawn + - !2464 Amend g_bus_get* documentation regarding private connection + - !2465 gi: expose some files as variable for gobject-introspection + - !2467 ci: Add link to Coverage output at end of coverage job + - !2468 gfile: resolve_relative_path isn't nullable + - !2469 Implement async file movement + - !2471 Fix test on the date format for FreeBSD and MacOS X. + - !2472 Fix test date (again)... + - !2473 Fix glib/test/date.c for FreeBSD/OpenBSD/MacOS X + - !2476 Add G_UNICODE_SCRIPT_MATH to GUnicodeScript + - !2477 Improve coverage of two digit years in gdate tests + - !2481 Fix glib/tests/fileutils on win32 + - !2482 Fix unit test on date format '%Z' which is too versatile to be trustable + - !2483 Fix glib/tests/gdatetime on win32 + - !2484 tests: Use g_test_skip() to skip a test on Windows + - !2487 gconstructor.h: Visual Studio: Only include gslist.h if needed + - !2488 Fix some problems with g_aligned_alloc() tests + +* Translation updates: + - Basque + - Catalan + - Chinese (China) + - Czech + - French + - Galician + - Indonesian + - Japanese + - Polish + - Portuguese + - Portuguese (Brazil) + - Russian + - Slovenian + - Spanish + - Ukrainian + + +Overview of changes in GLib 2.71.1 +================================== + +* Basic support for static builds on Windows (work by Loïc Le Page, + Marc-André Lureau, with contributions from Xavier Claessens, Nirbheek Chauhan, + Charlie Barto, Luca Bacci, Amos Wenger) (#692, #2585, !2442) + +* Add `GDebugController` and a D-Bus implementation which exposes whether + debug output is enabled in a process using the `org.gtk.Debugging` D-Bus + interface (work by Philip Withnall) (#1190) + +* Support for `AF_UNIX` sockets on Windows 10 (and later) (work by Marc-André Lureau) (#2487) + +* Several important fixes to GDBus message and GVariant parsing of invalid data (work by Sebastian Wilhelmi) (#2557, #2572) + +* Fix potential data loss due to missing fsync when saving files on btrfs (work by Sebastian Keller) (!2425) + +* Fix potential buffer overflows in `garray.c` for very large `GArray`s and `GPtrArray`s (work by Tobias Stoeckmann) (#2578) + +* Fix FDs in gspawn not being closed and causing process hangs if `close_range()` fails unexpectedly (work by Dan Nicholson) (#2580) + +* Fix `g_find_program_in_path()` not returning an absolute path if `$PATH` is relative (work by Christoph Niethammer) (#2586) + +* Add support for loading PKCS#12 encrypted files in `GTlsCertificate` (work by Patrick Griffis) (!2239) + +* A number of improvements to unit tests (work by Emmanuel Fleury, Charlie Barto) (!2399, !2400, !2402, !2403, !2428, !2431, !2432, !2434) + +* Support `LOCAL_PEERPID` on macOS, giving partial support for PIDs in + `GCredentials` on that platform (work by Ignacio Casal Quinteiro) (!2362) + +* Add `g_get_user_state_dir()` to support `XDG_STATE_HOME` (work by Sophie Herold) (!2395) + +* Add `g_hash_table_new_similar()` to copy a hash table and its hash/equal functions without its data (work by Jonas Ã…dahl) (!2405) + +* Support D-Bus client authentication with `EXTERNAL` on Windows (work by Marc-André Lureau) (!2429) + +* Add a reStructuredText documentation generator to `gdbus-codegen` (work by Emmanuele Bassi) (!2448) + +* Add a Windows implementation of `GMemoryMonitor` (work by Marc-André Lureau) (!2452) + +* Bugs fixed: + - #692 meta: Fix static build on Windows + - #1190 gapplication: Add an org.gtk.Debugging interface + - #2487 Add support for native unix domain sockets on WIN32 to GLib.Socket and related classes + - #2550 possible GDateTime issue with localtime on Illumos/Solaris + - #2557 Arrays of zero-element tuples with non-zero length lead to infinite loops in g_dbus_message_new_from_blob + - #2559 2.71.0: compile and link time warnings + - #2560 Link error xdgmime.c: unresolved external symbol S_ISREG when building with VS2022 + - #2564 Hangul Jamo Extended-B should be 0-width + - #2565 Build glib-2.71.0 failed in Windows using MSYS2-MINGW64 + - #2571 Cross build error "undefined reference to `_g_binary_test1_resource_data'" when building tests for Windows on openSUSE Leap + - #2572 Check for GVariant recursion depth before recursing + - #2578 buffer overflows in garray.c + - #2579 Outdated paths in INSTALL.in + - #2580 gspawn doesn't set CLOEXEC if close_range fails unexpectedly + - #2582 glib 2.71.0 muslc - build error missing sentinel in function call + - #2585 Static link issue on Windows due to resource files being linked in twice + - #2586 g_find_program_in_path not returning an absolute path + - !2239 gtlscertificate: Add ability to load PKCS#12 encrypted files + - !2362 credentials: support the local peerpid on macos + - !2384 meson: Fix linking with static library in Windows + - !2395 utils: Add XDG_STATE_HOME support + - !2399 Move tests/env-test.c into glib/tests/environment.c + - !2400 Prevent gtest tests from popping up dialog boxes + - !2402 Improving glib/tests/environment.c + - !2403 Improve test coverage of glib/tests/asyncqueue.c + - !2405 ghash: Add g_hash_table_new_similar + - !2407 tests: Fix environment test on FreeBSD + - !2411 annotate `g_content_type_guess` parameter as filename + - !2412 paramspec: fix unref annotation + - !2413 Use meson dependency to link against apple framework + - !2414 docs: Improve docs for gdbusutils.c + - !2417 gtestutils: Fix minor typos in the g_test_get_filename() docs + - !2423 Make clear in doc that signals are emitted synchroniously + - !2425 gfileutils: Remove outdated BTRFS fsync optimization from set_contents + - !2426 gdbus-codegen: Fix a typo in a comment + - !2428 Merge tests/gobject/gvalue-test.c with gobject/tests/value.c + - !2429 gdbus: make client work with EXTERNAL on Windows + - !2431 Merge tests/gobject/paramspec-test.c into gobject/tests/param.c + - !2432 Merge test/unicode-caseconv.c into glib/tests/unicode.c + - !2434 Remove a disabled test case that was covered by glib/tests/collate.c + - !2440 Improve g_ascii_formatd docs and preconditions + - !2441 Reduce the amount of compile-time warnings + - !2442 Fix tests with static build on Windows + - !2447 giowin32: use gint64 and _lseeki64 + - !2448 Add reStructuredText documentation generator for gdbus-codegen + - !2452 gio/win32: add GMemoryMonitorWin32 + - !2453 Add `(array length)` annotation to `g_tls_certificate_new_from_pkcs12()` + - !2454 gdbusmessage, gvariant and garray fixes + - !2456 tests: Pass --internal and -z noexecstack to glib-compile-resources tests + - !2459 gio: add missing zlib dependency in gio-windows-2.0.pc + - !2461 Fix memory leak in gio/gdbusauthmechanismsha1.c + - !2463 Revert "Merge branch 'fix-windows-pc' into 'main'" + +* Translation updates: + - Catalan + - Chinese (China) + - Czech + - Galician + - Hebrew + - Indonesian + - Lithuanian + - Polish + - Portuguese + - Portuguese (Brazil) + - Russian + - Spanish + - Ukrainian + + +Overview of changes in GLib 2.71.0 +================================== + +* Fix network changes not being signalled from NetworkManager (work by + Julian Andres Klode) (#2505) + +* Fix build when building with --fatal-meson-warnings (work by Eli Schwartz) (!2304) + +* Fix use of the default log writer with journald namespaces (diagnosis by Ilya Basin) (#2530) + +* Fix hang in `dbus-daemon` under `GTestDBus` when `G_MESSAGES_DEBUG=all` is set (work by Marco Trevisan) (#2537) + +* Speed up `g_canonicalize_filename()` to avoid pathogenic cases with `..` (work by Sebastian Wilhelmi) (#2541) + +* Fix URI for pcre subproject as it’s moved upstream (work by Albert Astals Cid) (!2324) + +* Fix storing GSettings dictionaries on macOS (work by Maurice) (#2527) + +* Speed up ‘remove dot segments’ algorithm in `GUri` to avoid pathogenic cases with `..` (work by Sebastian Wilhelmi) (#2526) + +* Fix infinite loops in D-Bus message parsing for truncated inputs (work by Sebastian Wilhelmi) (#2528) + +* Improve correctness of version information returned by `g_get_os_info()` for Windows 10/Server 2019+ (work by Chun-wei Fan) (#2443) + +* Various fixes to GWeakRef cleanup (#865, #2390) and toggle refs (#2394) (work by Marco Trevisan) + +* Add `G_DBUS_PROXY_FLAGS_NO_MATCH_RULE` flag for disabling match rules when creating a `GDBusProxy` (#1109) + +* Fix FD remapping in `g_spawn_async_with_pipes_and_fds()` with certain values of target FDs (#2503, #2506) (work by Michael Catanzaro) + +* Make `GDBusProxy::g-signal` signal detailed with D-Bus signal names (#2536) (work by Aleksandr Mezin) + +* Emit `launched` signal for D-Bus activation of apps with `GDesktopAppInfo` (!2227) (work by Guido Günther) + +* Fix IDs of `GDesktopAppInfo`s which are constructed from a `.desktop` file in a subdirectory (!2283) (work by Ivalyo Dimitrov) + +* Add `--interactive` option to `gdbus call` (!2329) + +* Add `G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP` to `GSubprocess` (!2333) (work by Hristo Venev) + +* Bugs fixed: + - #475 Add g_alloca0() and g_newa0() + - #847 g_set_prgname() should be thread-safe + - #865 GWeakRefs not cleared by g_object_run_dispose() + - #1109 [PATCH] GDBusProxy: add G_DBUS_PROXY_FLAGS_NO_MATCH_RULE flag + - #1231 gobject declare macros cause alignment warnings on armhf/armhf/mipsel + - #1331 GArray with 10 million items overflows index arithmetic + - #1735 Get back to a -werror build + - #1781 Sort output of gsettings command-line tool + - #2310 contenttype test leaks xdg-mime internal data + - #2390 GWeakRef's aren't cleared again on finalization (and not fully thread-safe) + - #2394 Toggle refs notification may not handle multiple threads correctly + - #2400 Use-after-free in invoke_set_property_in_idle_cb() + - #2401 GDBus runtime warning from remove_interfaces() + - #2404 GTask: clarify that GTask assumes are running mainloop + - #2426 GSettings delayed apply generates runtime warnings + - #2443 Add Windows 11 support to get_windows_version() + - #2468 GSequence pessimizes itself and slows down + - #2471 g_output_stream_write_all_async prints error when count == 0 and content == NULL + - #2488 Unix password unit test fails on FreeBSD 13 + - #2489 Add a (diagnostic) warning for finalized objects with floating refs + - #2490 Upgrade to Unicode Character Database 14.0 + - #2496 Wrong parameter type for g_simple_proxy_resolver_set_ignore_hosts + - #2498 GIR: Remove non-existing IOModule methods `load`, `unload` + - #2500 Able to export object manager and object on root path, but not other paths + - #2503 gspawn.c may clobber target fds + - #2505 g_network_monitor_nm never updates on connection change (listens for signal on wrong dbus interface) + - #2506 gspawn.c fails to close child_err_report_fd if it is duped to avoid conflation with one of the target_fds + - #2507 Strange behavior of GFileEnumerator with GVfs locations + - #2514 test suite failure in glib/tests/gdatetime.c if German locale de_DE.ISO-8859-1 is available + - #2518 Misleading message when privileged program starts G_BUS_TYPE_SESSION + - #2520 g_date_new_ functions return NULL on invalid input + - #2523 MacOS generates warnings for g_size_checked_mul() + - #2526 fuzz_uri_parse failure + - #2527 Error storing dictionary with string keys as GSettings on macOS + - #2528 g_dbus_message_new_from_blob goes into infinite loop for certain inputs + - #2529 load_user_special_dirs returns NULL in certain cases + - #2530 g_log_writer_is_journald fails if a Journal Namespace is used + - #2536 GDBusProxy: make g-signal detailed + - #2537 GTestDBus dbus daemon causes child process to hang when using verbose output + - #2541 g_canonicalize_filename should work in linear time complexity + - #2553 Consider not depending on strtoull_l and strtoll_l as much + - !1960 Add g_main_context_new_with_flags() and ownerless polling option + - !1968 gspawn: Implement fd remapping for posix_spawn codepath, and fix file descriptor conflation issues + - !1991 Keyfile parsing performance improvements + - !2029 Updating xdgmime + - !2064 gobject: Cleanup GWeakRef locations on object finalization + - !2114 Coerce type cast to void* because it causes compiler warnings + - !2191 docs: Add .editorconfig file + - !2214 Document potential footgun with GTlsCertificateFlags and deprecate certain usages + - !2223 Better detection of the cleanup attribute. + - !2227 gdesktopappinfo: Emit "launched" signal for D-Bus activation too + - !2242 gsettings: Add various missing (nullable) or (not nullable) annotations + - !2244 gutils: Avoid segfault in g_get_user_database_entry + - !2245 gdesktopappinfo: Do not call xterm when it does not exist, inform the caller the launch failed + - !2246 gobject: Document it’s unsafe to call g_object_ref() from GWeakNotify + - !2249 Add version macros for GLib 2.72 and bump version to 2.71.0 + - !2251 GString: Bump minimum size + - !2254 Small optimization for g_object_set + - !2255 gobject: Clarify behaviour of adding weak refs during disposal + - !2257 Fix documentation for g_dbus_object_manager_get_object(). + - !2260 GWin32AppInfo: Do not assert about successful open'ing of registry keys + - !2261 Provide built DLLs as Gitlab-CI artifacts + - !2266 fix uninitial variable + - !2273 Fix more (Windows) warnings + - !2277 Revert "Don't compile some unused functions in gio/xdgmime/" + - !2283 GDesktopAppInfo: Try to always correctly set id + - !2284 update the proxy-libintl subproject to the latest release + - !2285 fix issues found by svace static code analyzer + - !2286 meson: fix warnings for extract_all_objects function + - !2287 ci: Update CI images to latest stable Debian and Fedora, bump Meson dependency to 0.52 + - !2288 Update g_source_remove doc comment: the function doesn't always return TRUE + - !2289 Update g_source_remove documentation for the returned value + - !2290 mkdir path specified by XDG_RUNTIME_DIR + - !2292 Fix cast from pointer to integer of different size warning in gio/gwin32appinfo.c + - !2293 glib-private: Fix MSVC build with AddressSanitizer + - !2294 Fix windows warnings + - !2295 gutf8: Document that out args from g_utf16_to_utf8() are non-negative + - !2303 Fix more windows warnings + - !2305 gio: document GFile API when relative path is absolute + - !2306 gunixmounts: Drop references to pamconsole mount option + - !2308 gthread-win32: Remove an unnecessary volatile qualifier + - !2309 Rename libpcre.wrap to pcre.wrap + - !2310 tests: Fix a typo in a test message in gdatetime.c + - !2311 Fix always true comparison warning in glib/garray.c + - !2319 docs: Fix the GListModel description + - !2323 Fix final warnings in Windows code + - !2324 Fix link to pcre-8.37.tar.bz2 + - !2326 Improve some documentation related to GTlsDatabase + - !2328 gutf8: add string length check when ending character offset is -1 + - !2329 gdbus: Add --interactive option to `gdbus call` + - !2332 Changed gendered terms to be gender-neutral + - !2333 gsubprocess: Add G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP + - !2336 tests: Drop arbitrary and flaky waits from actions tests + - !2339 ci: Bump Meson version to 0.60.1 on macOS + - !2341 tests: Wait for gdbus-testserver to die when killing it + - !2342 tests: Reformat mkenums.py slightly to make run-black.sh happy + - !2345 gutils: Disable some dead code on macOS + - !2347 Removing tests/asyncqueue-test.c from tests/ + - !2348 gio/tests/codegen.py: bump timeout to 100 seconds + - !2349 Annotate `g_getenv()` and `g_environ_getenv()` return value as `nullable` + - !2352 tests: Fix a flaky wait in converter-stream + - !2353 Address some oddities around GResolver::reload + - !2357 ci: Upgrade to clang-format-11 from clang-format-7 + - !2360 meson: specify when commands need to succeed in run_command + - !2364 tests: Allow `objcopy --help` to fail, because it fails on FreeBSD + - !2365 Add vfunc checks in gappinfo.c + - !2368 De-duplicate g_nearest_pow() implementation and add some overflow protections to g_ptr_array_maybe_expand(), g_string_maybe_expand() and g_string_chunk_insert_len() + - !2370 gqsort: Move test to glib/tests/ + - !2371 Freeze notification during object destruction + - !2372 docs: Improve GVariant docs + - !2373 glib.supp: Suppress one-time allocation in g_get_home_dir() + - !2376 GSource: move test to glib/tests/ + - !2379 Merging tests/bit-test.c into glib/tests/utils.c + - !2381 tests: Test the function forms of g_bit_*() APIs too + - !2382 gfileutils: Correctly reset start value when canonicalising paths + - !2385 gfileutils: Fix transfer annotation and whitespace issues + - !2386 docs: Add API documentation links to the README + - !2387 docs: Update the README a little + - !2390 Merging tests/child-test.c into glib/tests/spawn-multithreaded.c + - !2391 Removing redundant cxx test tests/cxx-test.cpp + - !2392 Move tests/completion-test.c to glib/tests/completion.c + - !2393 Removing unnecessary test on gdatetime.c + - !2396 fuzzing: Add a fuzz test for parsing DNS records + - !2397 Moving tests/dirname-test.c to glib/tests/fileutils.c + - !2398 fix /list/position test + +* Translation updates: + - Croatian + - Friulian + - Galician + - Hebrew + - Indonesian + - Italian + - Latvian + - Lithuanian + - Occitan (post 1500) + - Persian + - Polish + - Portuguese + - Portuguese (Brazil) + - Romanian + - Russian + - Serbian + - Slovak + - Spanish + - Swedish + - Ukrainian + + +Overview of changes in GLib 2.70.0 +================================== + +* Bugs fixed: + - !2248 ci: Replace FreeBSD 11 with FreeBSD 13 + +* Translation updates: + - Croatian + - Danish + - English (United Kingdom) + - French + - German + - Hungarian + - Polish + - Swedish + - Turkish + + +Overview of changes in GLib 2.69.3 +================================== + +* Bugs fixed: + - #2425 g_settings_schema_key_range_check() misbehaves for int versus bool + - #2472 Compiling anything with GCC <4.6 spews deprecation warnings + - #2477 `g_invoke_closure` bindings API break. + - #2481 GPowerProfileMonitorPortal does not notice initial power-saver-enabled status + - !2219 doc: Explicitly said, that no null term. is needed + - !2238 ci: Use C.UTF-8 locale on FreeBSD 12 + - !2240 gio: Fix conditions in memory-monitor test + +* Translation updates: + - Basque + - Catalan + - Chinese (China) + - Galician + - Kazakh + - Korean + - Lithuanian + - Romanian + + +Overview of changes in GLib 2.69.2 +================================== + +* The `DBUS_SESSION_BUS_ADDRESS` environment variable is once more not used if + the process is `AT_SECURE` (setuid/setgid/setcap); this change was previously + applied and then reverted because it broke gnome-keyring (#2316) + +* Add `g_test_fail_printf()`, `g_test_skip_printf()`, + `g_test_incomplete_printf()` helper functions for printing messages when tests + end prematurely (work by Simon McVittie) (!2215) + +* Add portal implementation of `GPowerProfileMonitor` (work by + Bastien Nocera) (!2222) + +* Bugs fixed: + - #2316 Re-harden DBUS_SESSION_BUS_ADDRESS for AT_SECURE processes in GLib 2.70 + - #2343 Document explicitly refcount mgmt of source-object during GAsyncReadyCallbacks + - #2454 Read past the end of buffer in g_win32_package_parser_enum_packages + - #2456 Frequent test failure on FreeBSD: glib/tests/thread-pool.c:197:test_thread_pool_full: 'free_func_called' should be TRUE + - !2157 tests: Add missing wakeup calls to gdbus-names test + - !2165 docs: Mention the stable/unstable support version in README.md + - !2211 Improve documentation of various TLS stuff + - !2215 gtestutils: Add more convenience functions + - !2216 tests: Fix error handling when testing gtestutils + - !2222 gio: Add portal version of GPowerProfileMonitor + - !2224 Docs: Mention that G_VA_COPY() must be followed by `va_end()` + - !2225 build: Fix implicit declaration of function errors + - !2226 Annotate the GString constructors + +* Translation updates: + - Czech + - Hebrew + - Slovenian + - Spanish + - Swedish + + +Overview of changes in GLib 2.69.1 +================================== + +* Support categories in desktop notifications (`GNotification`) + (work by Guido Günther) (#2446) + +* Add `GPowerProfileMonitor` for monitoring when to use less power (due to being + on battery power, electricity being expensive or high-carbon, etc.) + (work by Patrick Griffis, Bastien Nocera) (#2444) + +* Allow static names to be set for `GSource`s to avoid unnecessary string copies + (work by Matthias Clasen) (!2196) + +* Bugs fixed: + - #203 API: need g_module_open() variant with GError + - #2058 win32: GPrivate can leak some objects + - #2321 Add a GTypeFlag for final types + - #2429 safe_fdwalk/safe_closefrom for Solaris 11.3/11.4 + - #2439 gio trash doesn't recognize existing trash directory in non-fs-root mount + - #2446 Support `categories` for notifications + - #2452 g_string_replace() loops 2**32 times when replacing empty string + - !2177 gio/tests/g-file-info: don't assume million-in-one events don't happen + - !2178 Clarify GValue documentation + - !2179 Update GValue doc: How to use GBoxed with GValue + - !2180 correctly use 3 parameters for close_range + - !2181 gclosure: Fix the invoke() return_value annotation + - !2182 glocalfileinfo: Fix usec/nsec confusion with filetimes on Windows + - !2184 gspawn: Use CLOSE_RANGE_CLOEXEC if available + - !2188 g_boxed_type_register_static, G_DEFINE_BOXED_TYPE: added correlating information + - !2192 Fix more warnings + - !2193 glib.supp: Expand match kinds for g_get_language_names() suppressions + - !2194 Add GPowerProfileMonitor + - !2195 Fix some test suite memory leaks + - !2196 mainloop: Add g_source_set_static_name + - !2197 GResource compiler: Prefix static [con|de]strutors with c_name + - !2198 Port internal uses to use g_source_set_static_name() + - !2200 Fix doc stanzas for GDataInputStream properties + - !2201 Fix a Unicode typo + - !2202 Document the stance on ID-based mainloop APIs + - !2204 tests: Add a test for Unicode normalization + - !2205 GWin32RegistryKey / GWin32AppInfo registry watch fixes + - !2206 Adapt documentation to gi-docgen + - !2210 GWin32AppInfo: Fix missing initialization + +* Translation updates: + - Indonesian + - Portuguese + - Portuguese (Brazil) + - Russian + - Ukrainian + + +Overview of changes in GLib 2.69.0 +================================== + +* Fix a crash in `GKeyFile` when parsing a file which contains translations + using a `GKeyFile` instance which has loaded another file previously (#2361) + +* Pin GIO DLL in memory on Windows (!2016) + +* Fix building third-party projects against GLib on CentOS 7 (work by + Ignacio Casal Quinteiro) (#2387) + +* Add `g_thread_pool_new_full()` API to allow queued `GThreadPool` data to be + freed if the pool is freed early (work by Nitin Wartkar) (#121) + +* Ensure `dlerror()` is used with locking as it’s not thread-safe in some libc + implementations (#399) + +* Add `g_dbus_is_error_name()` and `g_dbus_is_interface_name()` convenience + functions (work by Nitin Wartkar) (#402) + +* Drop internal libpcre copy in favour of a subproject from wrapdb (#962, #642) + +* Add `g_prefix_error_literal()` helper function (work by Emmanuel Fleury, + building on work by Dan Williams) (#663) + +* Add `g_bytes_get_region()` to get data from a `GBytes` with range checks + (work by Nitin Wartkar, building on work by Allison Karlitskaya) (#1098) + +* Add `g_object_take_ref()` to sink a floating ref (work by Nitin Wartkar, + building on work by Allison Karlitskaya) (#1112) + +* Optimise grefcount atomic operations (work by Nishal Kulkarni) (#1583) + +* Fix resolving child GSettings schemas from the parent’s schema source (work + by Christian Persch) (#1884) + +* Fix `g_date_time_format()` return value encoding if `LC_TIME` is not a UTF-8 + locale but other locale settings are (work by Frederic Martinsons) (#2055) + +* Set app name in freedesktop.org notifications with `GNotification` (work + by André Apitzsch) (#2069) + +* Significantly improve retrieval of mount data on Windows (work by LRN based + on initial analysis by Jehan Pagès) (#2096) + +* Add `g_file_info_get_(access|creation)_date_time()` accessors (work + by Abanoub Ghadban) (#2281) + +* Always apply the remove_dot_segments algorithm to URIs in `g_uri_parse()`; + previously it was only applied to relative URIs (work + by Carlos Garcia Campos) (#2342) + +* Rename git `master` branch to `main` (#2348) + +* Various macro and version check cleanup (work by Gaël Bonithon, + Robin Verdenal-Tallieux, Nishal Kulkarni) (#2376, #2388, #2389) + +* Add a `GTlsConnectionClass.get_negotiated_protocol` vfunc so that + `g_tls_connection_get_negotiated_protocol()` can be made thread-safe + (work by Michael Catanzaro) (#2393) + +* Improve guess about whether a Windows process is a console process + (work by Princeton Ferro with input from LRN) (!1662) + +* Add `g_steal_fd()` function (work by Simon McVittie) (!1966) + +* Add `g_spawn_check_wait_status()` and distinguish more carefully between + wait status and exit status in the `GSpawn` API (work by Simon McVittie) (!1967) + +* Document GLib’s security policy; see + https://gitlab.gnome.org/GNOME/glib/-/blob/main/SECURITY.md (!1985) + +* Add `g_tree_remove_all()` (work by Lighto-Ku) (!1986) + +* Simplify exception handling on Windows to eliminate risk of it failing due + to prior heap corruption (work by LRN) (!2031) + +* Fix handling EOF when reading from SOCKS5 proxy stream (work + by Benjamin Berg) (!2032) + +* Unset the registered state of a `GApplication` after it has shut down (work + by Marco Trevisan) (!2056) + +* Support `GPattern` as a boxed type (work by Marco Trevisan) (!2066) + +* Add `g_tls_connection_get_protocol_version()` and + `g_tls_connection_get_ciphersuite_name()` to get TLS connection information + (work by Michael Catanzaro) (!2077) + +* Make TLS private key properties readable in `GTlsCertificate` (work + by Michael Catanzaro) (!2087) + +* Fix detection of static libintl when building on macOS (work + by Jonas Hahnfeld) (!2109) + +* Add `g_strv_builder_addv()` and `g_strv_builder_add_many()` to the + `GStrvBuilder` API (work by Alexandros Theodotou) (!2112) + +* Add `not-valid-before`, `not-valid-after`, `subject-name`, `issuer-name`, + `dns-names`, `ip-addresses` properties to `GTlsCertificate` + (work by Ross Wollman) (!2113, !2142) + +* Add PKCS#11 flags to `GTlsPasswordFlags` (work by Patrick Griffis) (!2126) + +* Bugs fixed: + - #121 GThreadPool and the ability to free data waiting to be handled + - #229 g_match_info_fetch_named not return empty string as expected + - #310 ref doc doesn't talk about "helper getters" optimization in g_file_info.c + - #399 dlerror() not thread-safe in all libc, making gmodule-dl.c's fetch_dlerror fail sometimes + - #402 please consider: #define g_dbus_is_error_name(x) g_dbus_is_interface_name (x) + - #626 Add documentation example for GArray and g_array_set_clear_func() + - #642 update to pcre 8.35+ + - #663 [patch] add g_prefix_error_literal() + - #793 Potentially confusing error message when object doesn't exist + - #817 gobject: Allow passing %NULL for @data in g_object_remove_toggle_ref + - #962 drop embedded pcre copy + - #1036 gdbusproxy stops tracking if dbus service restarts + - #1098 GBytes: add range-checked pointer getter + - #1112 GObject: add g_object_take_ref() + - #1583 Optimise gatomicrefcount operations + - #1864 Somewhat misleading documentation of GSourceFuncs + - #1884 `g_settings_get_child` not compatible with `g_settings_schema_source_new_from_directory` + - #2011 Add additional unit tests for D-Bus name watching + - #2055 g_date_time_format() does not return UTF-8 if LC_TIME is not UTF8 but other locale settings are UTF-8 + - #2069 FreedesktopNotification fails to set app_name + - #2096 SHGetFileInfoW() is not reliable (time-wise) + - #2281 Add g_file_info_get_(access|creation)_date_time() + - #2300 Crash on Windows MSVC build around gio + - #2311 testfilemonitor test leaks ip_watched_file_t struct + - #2340 GIO tests fail to build with clang-cl + - #2342 g_uri_parse doesn't apply the remove_dot_segments algorithm to the path + - #2348 Investigate renaming master git branch to main + - #2352 RUN_FIRST | RUN_CLEANUP signals with a default handler ignore return values from user handlers + - #2359 GLib 2.68.0: gio-querymodules segfaults on Windows + - #2361 g_key_file_load_from_file segfaults on "Key[*]="like lines + - #2363 g_newa() doesn’t check for multiplication overflow + - #2368 g_task_run_in_thread () limits are not clear + - #2369 glocalfile: Add native exfat magic number to filesystem list + - #2376 GLIB_VERSION_MAX_ALLOWED < 2.60 does not warn when using G_GNUC_FALLTHROUGH + - #2387 json-glib does not build with glib 2.68.1 + - #2388 Pixman compilation error due to glib + - #2389 Use G_GNUC_CHECK_VERSION to check the GNUC version + - #2393 g_tls_connection_get_negotiated_protocol() is not threadsafe + - #2397 Slow to list device in windows + - #2399 Change spelling of ‘serialise’ to ‘serialize’ in documentation + - #2405 Mention that GNotification requires an installed .desktop file to work + - #2409 Project crashes when executing g_application_mark_busy + - #2414 Devhelp: Glib Reference Manual/Glib Overview/Running Glib Applications formatting issue. + - #2416 certificate: g_tls_certificate_new_from_pem invalid read on non null terminated data + - #2417 GFile: `g_file_replace_contents()` reports `G_IO_ERROR_WRONG_ETAG` when saving from a symlink + - #2418 gatomic: __atomic functions are called for CV-qualified output variables + - #2423 resources.c:656:test_resource_binary_linked: 'found' should be TRUE + - !1514 gbookmarkfile: Don't crash if we're not visited + - !1662 gspawn-win32: improve guess whether process is console process + - !1812 docs: Expand documentation about D-Bus GUIDs + - !1957 Fix more warnings + - !1965 gversionmacros: Add version macros for GLib 2.70 + - !1966 Add g_steal_fd() to API + - !1967 Distinguish more clearly between wait status and exit status + - !1969 glib_typeof: Move definition to its own header + - !1985 docs: Add a policy for handling security issues + - !1986 make g_tree_remove_all public + - !1996 Include glibconfig.h to get the G_OS_UNIX token + - !1998 gpollableinputstream: Add missing annotation + - !1999 goption.c: Simplfy parse_short_option() + - !2004 Some improvements to clang-cl builds + - !2005 introspection: Remove 'caller-allocates' from POD types + - !2006 fuzzing: Add fuzz tests for functions which parse paths + - !2008 tests: Deactivate tls-bindings test suite for windows + - !2011 docs: Fix example program link + - !2012 docs: Replace git.gnome.org with gitlab.gnome.org urls + - !2013 fuzzing: Fix assertion failure in fuzz_paths.c + - !2016 GIO W32: Pin gio DLL + - !2023 gtlspassword: Fix g-i annotation of return for g_tls_password_get_value + - !2025 [th/gdbus-cleanup] two minor cleanup patches for gdbusconnection.c + - !2026 Split g_test_log() messages that contain multiple lines + - !2027 Fix a handful of minor leaks found by Coverity + - !2030 Fix more warnings + - !2031 Re-simplify exception handling on Windows + - !2032 gsocks5proxy: Handle EOF when reading from a stream + - !2033 Fix annotation of count arguments + - !2036 gmacros.h: use G_GNUC_CHECK_VERSION + - !2038 Fix more warnings + - !2039 Implement G_ANALYZER_NORETURN for Coverity + - !2040 Fix more warnings + - !2041 refcount: Clarify when the ref count ends up undefined + - !2042 grefcount: Clarify that the initial reference count is 1 + - !2043 gmacros.h: use g_macro__has_attribute() where possible + - !2046 gerror: Clarify docs around message requirements + - !2047 Fix more warnings + - !2048 Fix more warnings + - !2049 Fix typo in g_socket_listener_accept_async()'s comment + - !2050 gdbus: document completion after idle action for g_dbus_connection_signal_unsubscribe() + - !2051 Add nullable annotations in GUnixMountEntry + - !2052 g_string_replace(): Fix documentation of 'limit' parameter + - !2054 docs: Fix formatting of code block + - !2055 Improve handling of FILENAME_MAX + - !2056 application: Unset the registered state after shutting down + - !2063 Fix more warnings + - !2066 gpattern: Register as Boxed type and support introspection for it + - !2067 gmacros: missing check if __STDC_VERSION__ is defined + - !2069 gdbus-tool: Actually use argv[0] basename as program name + - !2071 gstring: Cleanup documentation of g_string_replace + - !2074 Fix more warnings + - !2075 gdtlsconnection: Fix a check for a vfunc being implemented + - !2077 tls: add functions to get protocol version and ciphersuite name + - !2078 gthreadedresolver: don't ignore flags in lookup_by_name_with_flags + - !2080 guuid: fix shift operation to parse hex string in uuid_parse_string() + - !2081 Fix more warnings + - !2085 gcredentials.h: Fix comment typo + - !2087 gtlscertificate: make private key properties readable + - !2088 Fix more warnings + - !2090 docs: Standardize spelling of serializ* + - !2091 Fix more warnings (clang) + - !2098 grefcount: Optimise g_atomic_ref_count_dec + - !2099 gmacros.h: G_NORETURN: remove useless checks + - !2100 tests: Add missing return value check in string test + - !2101 Fix more warnings + - !2104 tests: Drop use of g_test_bug_base() + - !2105 tests: Use a temporary file in the bookmarkfile tests + - !2106 Fix more warnings + - !2108 glib spawn-singlethread test only if F_DUPFD_CLOEXEC is defined + - !2109 meson: Fix detection of static libintl on macOS + - !2112 gstrvbuilder: add addv and add_many to the API + - !2113 tls: expose cert details on GTlsCertificate + - !2119 Fix more warnings + - !2120 gdbusobjectmanagerclient: Call GetManagedObjects async + - !2123 gdbus: Add various missing (nullable) or (not nullable) annotations + - !2126 gtlspassword: Add flags signifying PIN type for PKCS#11 + - !2127 gutils: ensure g_find_program_in_path() return an absolute path + - !2130 Revert "tests: Deactivate tls-bindings test suite for windows" + - !2139 gdbus, win32: Fix accidental dllexport in static builds + - !2142 tls: expose SAN details on GTlsCertificate + - !2143 compiling.xml: Don't recommend backticks + - !2144 pcre: Drop internal libpcre copy + - !2145 gunixmounts: Document NULL return value for g_unix_mount_for() + - !2152 tests: A few small improvements to GBytes tests + - !2153 docs: Fix annotations for optional arguments + - !2155 glocalfilemonitor: Avoid a deadlock on finalization + - !2162 testgdate: fix -Wmisleading-indentation warning + - !2166 gtlscertificate: Add more annotations to new properties + - !2167 g_value_set_string description: clarified (unified), that v_string is a copy. + - !2173 gasyncqueue: Add missing (nullable) annotation to free function + - !2174 data-to-c.py: generate new-line at the end of the file + +* Translation updates: + - Chinese (China) + - English (United Kingdom) + - Hebrew + - Nepali + - Occitan (post 1500) + - Serbian + + +Overview of changes in GLib 2.68.0 +================================== + +* Bugs fixed: + - !1987 build: Drop gconstructor_as_data_h usage from glib-compile-schemas + - !1989 glib.supp: Generalize some suppressions + - !1992 gbytesicon: Fix error in g_bytes_icon_new() documentation + - !1994 glocalfileoutputstream: Tidy up error handling + - !1995 tests: Fix copy/paste error in queue test + +* Translation updates: + - Czech + - Finnish + - Italian + - Korean + - Lithuanian + - Polish + - Romanian + - Slovenian + - Turkish + + +Overview of changes in GLib 2.67.6 +================================== + +* Fix a security issue when using `g_file_replace()` with + `G_FILE_CREATE_REPLACE_DESTINATION` (#2325) + +* Disallow operations on the empty path with `g_file_new_from_path()` (#2328) + +* Various fixes for GLib when building with clang-cl on Windows (work by + Aleksandr Mezin) (#2341, #2344) + +* Bugs fixed: + - #2325 file-roller symlink attack + - #2327 Teach glib-mkenums about GLIB_AVAILABLE_ENUMERATOR_IN_2_68, and start using it + - #2328 g_file_new_for_path("") yields CWD, which seems wrong + - #2341 glib-genmarshal output is sometimes empty because output file is not closed + - #2344 c_std=c11: gbitlock.c: ‘asm’ undeclared + - !1962 Validate D-Bus machine ID after loading + - !1976 Use the right permissions for directory watching on Win32 + - !1977 gio/tests/{meson.build,pollable.c}: Determine libutil SONAME at build time + - !1980 glib.supp: Add another system thread suppression + +* Translation updates: + - Basque + - Catalan + - Czech + - French + - Galician + - German + - Hungarian + - Indonesian + - Korean + - Latvian + - Portuguese + - Portuguese (Brazil) + - Serbian + - Spanish + - Swedish + - Ukrainian + + +Overview of changes in GLib 2.67.5 +================================== + +* Fix more issues with `glib_typeof` macro from 2.67.3–2.67.4 (work by + Iain Lane, Simon McVittie) (#2331, !1975) + +* Fix regression with some FD mappings passed to `g_subprocess_launcher_spawnv()` + caused by changes for #2097 in GLib 2.67.4 (work by Olivier Fourdan, + Philip Withnall) (#2332) + +* Fix detection of `str[n]casecmp()` when building with `clang-cl` (work by + Aleksandr Mezin) (#2337) + +* Use zlib from subproject if configured with `wrap_mode=forcefallback` (work by + Seungha Yang) (!1959) + +* Bump Visual Studio compilation requirement to VS 2012, and Windows 8 SDK for + GLib 2.67.x onwards (work by Chun-wei Fan) (!1970) + +* Bugs fixed: + - #832 Some tweaks re: GRWLock + - #2331 glib 2.67.3: can no longer be included in extern "C" blocks + - #2332 Glib 2.67.4 causes gnome-shell to exit when spawning Xwayland on demand + - #2333 Missing relation between g_file_info_get_size() and G_FILE_ATTRIBUTE_STANDARD_SIZE attribute in documentation + - #2337 Linking fails when building with clang-cl because of str[n]casecmp + - !1936 tests: Fix leak of dlopened module in pollable test + - !1954 Change SkipAsyncData fields to be gsize (and not gssize) + - !1956 The ETag returned by various GFile functions is nullable + - !1959 meson: Use subproject zlib if "wrap_mode=forcefallback" was specified + - !1961 gkeyfilesettingsbackend: check for errors when creating file monitors + - !1970 README.win32.md: Mention about Window 8+ SDK requirement + - !1971 gio/tests/pollable.c: Fix build on non-Linux UNIX + - !1975 gatomic.h: Make `glib_typeof` API break opt in. + +* Translation updates: + - Basque + - Danish + - English (United Kingdom) + - Galician + - German + - Indonesian + - Lithuanian + - Portuguese + - Portuguese (Brazil) + - Slovenian + + +Overview of changes in GLib 2.67.4 +================================== + +* Add a `g_string_replace()` function (work by Joshua Lee) (#225) + +* Add `G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER` flag to simplify + the common case for writing a D-Bus authentication observer, allowing most + uses of `GDBusAuthObserver` to be dropped (#1804) + +* Add a new `g_spawn_with_pipes_and_fds()` variant which supports renumbering + FDs (#2097) + +* Add new g_memdup2() API to replace g_memdup(), which is vulnerable to a + silent integer truncation and heap overflow problem if not used carefully + (discovered by Kevin Backhouse, work by Philip Withnall) (#2319) + +* Fix various regressions caused by rushed security fixes in 2.66.6 (work by + Simon McVittie and Jan Alexander Steffens) (!1932, !1941, #2323) + +* Fix a silent integer truncation when calling g_byte_array_new_take() for + byte arrays bigger than G_MAXUINT (work by Krzesimir Nowak) (!1942) + +* Fix `g_utf8_strdown()` to fix some issues in Turkish + (work by Kjell Ahlstedt) (!1930) + +* Bugs fixed: + - #225 GString doesn't have a g_string_replace() function + - #587 g_input_stream_skip() out-of-bounds behavior is inconsistent between implementations + - #1804 Add G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER flag + - #2097 GSubprocessLauncher with FD assignment can clash with g_spawn_async internal pipe + - #2315 httpproxy: Need overflow protection when reading response during connection establishment + - #2319 CVE-2021-27219 (GHSL-2021-045): integer overflow in g_bytes_new/g_memdup + - #2322 g_test_dbus: double output when piping + - #2323 [GLIB 2.66.6] g_io_channel_set_line_term() stopped working with null terminated strings and length -1 + - !1917 Adding a missing test on integer overflow within g_http_proxy_connect() + - !1918 Fix more warnings + - !1923 Add support for Tilix and Konsole + - !1930 guniprop: Fix g_utf8_strdown() for Turkish locale + - !1932 gtlspassword: Fix inverted assertion + - !1934 gdbus: Reject attempts to set future connection or server flags + - !1938 Fix more warnings + - !1939 ci: Temporarily disable macOS CI job as runner is offline + - !1940 Fix more warnings + - !1941 gkeyfilesettingsbackend: Fix basename handling when group is unset + - !1942 CVE-2021-27218: gbytearray: Do not accept too large byte arrays + - !1947 Revert "Merge branch 'wip/pwithnall/macos-ci-disable' into 'master'" + - !1948 tests: Use a more realistic language code than sv_SV + - !1949 gatomic: Make fallback g_atomic_pointer_get type-safe + - !1951 Add a test for parsing 0 as double + - !1955 tests: Add missing NULL terminator to spawn-singlethread test + +* Translation updates: + - Catalan + - Galician + - Hungarian + - Portuguese + - Romanian + - Slovenian + - Spanish + - Swedish + - Turkish + - Ukrainian + + +Overview of changes in GLib 2.67.3 +================================== + +* Add new `g_memdup2()` API to replace `g_memdup()`, which is vulnerable to a + silent integer truncation and heap overflow problem if not used carefully + (discovered by Kevin Backhouse, work by Philip Withnall) (#2319) + +* Add new `g_dbus_object_path_escape()` and `g_dbus_object_path_unescape()` APIs + to provide one way of escaping arbitrary bytestrings for use in D-Bus object + paths (work by Lars Karlitski and Frederic Martinsons) (#968) + +* Use `bash-completion.pc` (if available) to provide the path to install + completion files into (work by Frederic Martinsons) (#1054) + +* Fix support for public/private trigraphs in `glib-mkenums` (work by Matthias Klumpp) (!1870) + +* Add `glib_debug` configure option to allow disabling debug infrastructure in + builds with debug symbols enabled (work by Ole André Vadla RavnÃ¥s) (!1889) + +* Fix a regression where `PATH` would always be searched when using `g_spawn()`, + even when it wasn’t supposed to (work by Simon McVittie and Thomas Haller) (!1902) + +* Override `gio-querymodules` in Meson when used as a submodule (work by Xavier Claessens) (!1909) + +* Bugs fixed: + - #344 gdbus(1) command-line completion issues + - #968 gdbus: add g_dbus_object_path_{un,}escape + - #1054 Use pkg-config to get path for bash-completion file installation + - #1180 GUnixInputStream and GUnixOutputStream don't consider TTYs pollable + - #2011 Add additional unit tests for D-Bus name watching + - #2226 clang++ compilation fails on clusterfuzz + - #2292 Cannot find a common ancestor when running CI style check jobs + - #2299 GObject introspection annotation of g_closure_new_object() is wrong + - #2305 GIO security hardening causing gnome-keyring to regress when session bus is provided by dbus-launch (dbus-x11) + - #2314 gdatetime: math library link issue + - #2319 GHSL-2021-045: integer overflow in g_bytes_new/g_memdup + - !610 Various memory leak cleanups to GSettings tests + - !1804 Add more GIR annotations to gparam.c and gsignal.c + - !1823 Fix more warnings + - !1843 gfile: Add Linux kernel headers compatibility kludge + - !1847 Port to QNX + - !1853 ginetaddress: Handle systems without IPv6 support + - !1859 docs: update g_action_group_activate_action() remote activation semantics + - !1860 glocalfile: Fix an uninitialized variable + - !1865 tests: Add more debug information to gdbus-connection-slow + - !1868 gdesktopappinfo: Fix validation of XDG_CURRENT_DESKTOP + - !1870 mkenums: Support public/private trigraph again + - !1873 Fix possible integer overflow of g_socket_send_message() + - !1876 Fixing g_socket_send_message() documentation to make it clearer + - !1877 Fix more warnings + - !1878 Another fix on g_socket_send_message() + - !1879 Fix more warnings + - !1880 GError documentation tweaks + - !1881 docs: Move ‘Notes’ section from README to NEWS + - !1883 gutils: Document caching of XDG directory variables + - !1884 gthread-win32: Use SetThreadDescription Win32 API for setting thread name + - !1887 ci: Fix msys-mingw32 CI builds due to package rename + - !1888 docs: Add documentation for GLIB_VERSION_CUR_STABLE and PREV_STABLE + - !1889 build: Add glib_debug option + - !1890 gtype: Improve formatting of GType documentation + - !1891 Fix more warnings + - !1893 gwin32appinfo: Fix printf length sub-specifier + - !1894 gsocket: Fix SO_NOSIGPIPE regression on Darwin + - !1898 gtestutils: Add g_test_get_path() API + - !1899 m4macros: replace obsolete macros AC_TRY_RUN and AC_TRY_LINK in glib-2.0.m4 + - !1900 [th/gsignal-cleanup] minor changes to GSignal related code + - !1901 Check if the remote already exists before adding it. + - !1902 spawn: Don't set a search path if we don't want to search PATH + - !1903 m4macros: Increment serial number of glib-2.0.m4 + - !1905 Start to ignore known leaks under AddressSanitizer + - !1906 gdbus-serialization: Don't leak string containing first serialization + - !1908 Fix straightforward memory leaks in tests + - !1909 Meson: override gio-querymodules program + - !1910 gio: Add explicit virtual g-i annotations for undiscovered invoker relationship + - !1911 Fix more warnings + - !1915 Mark g_key_file_get_comment() key parameter as nullable + - !1919 atomic: Fix type check of g_atomic_pointer_compare_and_exchange() + - !1921 guri: Mark g_uri_get_host as nullable + - !1925 gapplication: Fix a memory leak + +* Translation updates: + - Czech + - Friulian + - Galician + - Hungarian + - Portuguese + - Portuguese (Brazil) + - Romanian + - Spanish + - Ukrainian + + +Overview of changes in GLib 2.67.2 +================================== + +* Add `gio launch` command to execute programs (work by Frederic Martinsons) (#54) + +* Fix unused parameter warnings in code generated by `gdbus-codegen` (work by Frederic Martinsons) (#1105) + +* Officially deprecate `to-pixdata` option for `glib-compile-resources`, in favour + of simply embedding more modern image formats in linked-in `GResource` files (#1281) + +* Support querying and running UWP applications on Windows (work by LRN) (#1991) + +* Support `gio trash --restore` and `gio trash --list` commands (work by Frederic Martinsons) (#2098) + +* No longer read environment variables for GIO module locations when running as setuid (#2168) + +* More progress on fixing compiler warnings (work by Emmanuel Fleury) (!1773 and others) + +* `GKeyFile` performance improvements (work by Timm Bäder) (!1829, !1832) + +* Improve UDP socket behaviour on Windows (work by Marco Mastropaolo and Ole André Vadla RavnÃ¥s) (!1827, !1844) + +* Add `-Dtests` meson configure option for disabling tests entirely (work by Ole André Vadla RavnÃ¥s) (!1850) + +* Bugs fixed: + - #54 Add `gio launch` command to execute .desktop files + - #513 GSignal: Impossible to have return values in signals which are G_SIGNAL_RUN_FIRST only + - #514 GSignal: Only limited usage of accumulator function possible + - #1105 gdbus-codegen: fix some unused parameter warnings + - #1188 Crash in gapplication.c:1014 when reading error message if dbus_register returns false without setting error + - #1281 Update glib-compile-resources and GResource docs to deprecate/remove to-pixdata in stable/master resp. + - #1283 gvfs-trash error message when unable to create trash directory is unhelpful + - #1568 GObject tutorial does not mention floating references + - #1991 W32: Glib cannot run UWP applications + - #2098 gio trash: restore trashed files to their original location + - #2168 giomodule: Loads GIO modules even if setuid, etc. + - #2264 GPtrArray might call qsort() with NULL data + - #2265 2.67.1 regression: assertion failure starting gnome-terminal + - #2275 gio/completion/gio: Some variables are not localized + - #2279 g_source_is_destroyed example uses deprecated GDK API + - !1304 Extended error + - !1773 Fix more warnings + - !1783 gtlsdatabase: remove duplicate precondition check + - !1784 fuzzing: Add more fuzzing tests for various string parsing functions + - !1785 glocalfile: Add an assertion to help static analysis + - !1787 Debuggability improvements in gosxappinfo.m + - !1788 gdate: Validate input as UTF-8 before parsing + - !1791 gdatetime: Disallow NAN as a number of seconds in a GDateTime + - !1794 gio-tool-info: Prevent criticals if mount options are not available + - !1796 gfileutils: Fix typo in docs + - !1797 gdatetime: Improve ISO 8601 parsing to avoid floating point checks + - !1801 glib: Add more missing return value annotations + - !1802 gobject: More missing return value annotations + - !1806 tests: Add some rounding tolerance in timeout test + - !1807 python: Reformat some files to keep style-check-diff happy + - !1808 tests: Be more lenient with timing checks on asyncqueue pops + - !1810 gfileinfo: Add missing preconditions to g_file_info_get_attribute_data() + - !1811 Add more missing nullable annotations + - !1813 gdbus-codegen: Ignore some flake8 warnings + - !1815 Fix more warnings + - !1816 fuzzing: Add more GUriFlags to the URI parsing test + - !1817 fuzzing: Add more parsing flags to the GKeyFile test + - !1818 Fix more warnings + - !1819 Fix more warnings + - !1821 gdate: Limit length of dates which can be parsed as valid + - !1822 Fix more warnings + - !1827 Windows: fix FD_READ condition flag still set on recoverable UDP socket errors. + - !1829 keyfile: Delay calling g_get_language_names() until it's needed + - !1830 gsocket: Fix credentials error-handling on Apple OSes + - !1832 More small GKeyFile performance improvements + - !1834 Update gvdb + - !1837 gdatetime.c: Fix MSVC builds for lack of NAN items + - !1838 Minor improvements to GError documentation + - !1840 Add nullable annotation for g_file_get_uri_scheme + - !1841 gthread: Fix incorrect cast + - !1842 gthread: Port native mutex to Clang + - !1844 gsocket: Improve default UDP behavior on Windows + - !1845 gsocket: Fix use-after-close + - !1848 gwin32: Always use unicode APIs + - !1850 build: Add option for disabling tests + - !1855 build: Fix ssize_t detection on older versions of glibc + - !1856 build: Fix Android system checks + - !1857 gtestutils: Fix g_assert_not_reached() on MSVC + - !1861 More GError tests + - !1863 tests: Ignore -Wformat-nonliteral warning in new GError tests + +* Translation updates: + - Catalan + - Galician + - German + - Lithuanian + - Romanian + - Spanish + - Ukrainian + + +Overview of changes in GLib 2.67.1 +================================== + +* Deprecate `g_time_zone_new()` in favour of `g_time_zone_new_identifier()`, + which makes error checking easier (#553) + +* Remove `volatile` from various public APIs, including `G_DEFINE_*`. You should + adjust your code to not use `volatile` for atomic variables, `GOnce` + variables, or mostly anything else (see + http://isvolatileusefulwiththreads.in/c/). (#600) + +* Support passing file handles to `gdbus` command line tool (work by + Norbert Pocs and Tim Waugh) (#961) + +* Add `g_assert_cmpstrv()` test convenience function (work by Niels De Graef) (#2015) + +* Changes to the behaviour of the `G_URI_FLAGS_SCHEME_NORMALIZE` scheme + normalization flag in `GUri` (work by Carlos Garcia Campos) (#2257, !1716) + +* Add new `--run-prefix` and `--skip-prefix` options to GTest, to allow running + or skipping test suites by prefix (work by Frederic Martinsons) (!1738) + +* Fix thread-safety of `GBinding`; see the updated documentation for + `g_object_bind_property()` for full details — if your code uses `GBinding` + across threads, you should re-check it against the latest documentation, use + `g_binding_unbind()` rather than implicitly dropping the binding with your + last `g_object_unref()` call, and use `g_binding_dup_source()`/`g_binding_dup_target()` + instead of `g_binding_get_source()`/`g_binding_get_target()` + (work by Sebastian Dröge) (!1745) + +* Bugs fixed: + - #553 Improved error-handling when timezone lookup fails + - #600 Remove "volatile" from G_DEFINE_* + - #961 gdbus tool: file handle passing doesn't work + - #994 mark g_assert_* as "noreturn" also on MSVC + - #1560 Can't get data for empty compressed resources + - #1592 Main loop ignores GPollFD sources when there is at least one source ready with priority higher than default one + - #1833 meson: reconsider G_DISABLE_CAST_CHECKS handling + - #1849 Documentation of g_set_object(): can object_ptr be null? + - #1963 Follow-up from "gdbusmessage: Limit recursion of variants in D-Bus messages" + - #2015 Add g_assert_cmpstrv() test utility + - #2046 Add pylint and shellcheck CI checks + - #2074 Big dbus writes with a FD list fail + - #2076 g_type_register_fundamental() and g_type_add_interface_static() should not trigger valgrind leak warnings + - #2150 Add URI parsing tests from GstURI to GUri + - #2221 GLib-GIO:ERROR:../gio/tests/gsocketclient-slow.c:99:on_event: 'connection' should be NULL + - #2223 Documentation of g_strrstr_len is misleading; suggested fix + - #2233 GSocketClient crashes on connection failure + - #2236 Docs: gdbus-codegen example links broken + - #2253 In gspawn.c, use sysconf() system call on Mac OS, instead of default maxfiles limit of 4096 + - #2257 GUri: apply scheme normalization flag consistently + - !1251 Improve support for interface types + - !1385 gobject: allocate parameter list for g_object_new_valist() entirely on stack + - !1629 Add some tracing to GTask + - !1699 Fix signedness warnings + - !1701 gio: Fix some remaining DocBook syntax in a documentation comment + - !1708 gio: Add missing nullable annotations + - !1716 guri: Normalize uri segments if they are encoded and add a flag to do scheme-based normalization + - !1722 gio: Fix various typos of the name ‘D-Bus’ + - !1724 glib/tests/fileutils: Fix expectations when running as root + - !1726 gdbus: Document the intended semantics of handles and fdsTim Waugh + - !1731 Make more use of g_assert_no_errno() + - !1733 gdbusauthmechanismsha1: Don’t create keyring dir when running as setuid + - !1734 glocalfileinfo: Use a single timeout source at a time for hidden file cache + - !1735 gobject: Standardise on the term ‘instantiatable’ + - !1737 gscanner: Avoid undefined behaviour copying between union members + - !1738 Extend the usage of -p option for glib test framework + - !1740 Fix more warnings + - !1745 Make GBinding thread-safe (alternative approach) + - !1746 gkeyfilesettingsbackend: improve error-checking + - !1747 Fix broken link syntax in g_vasprintf docs + - !1748 Fix minor Coverity return value warnings + - !1750 Fix warnings + - !1754 GWin32AppInfo: Use a thread pool for async appinfo tree rebuilds + - !1755 Minor Coverity fixes + - !1756 shellcheck fixes + - !1757 Python formatting improvements + - !1758 Fix warnings + - !1765 Fix more warnings + - !1766 Fix some gdatetime annotations + - !1767 tests: Fix GDateTime tests on FreeBSD + - !1769 gfileicon: Fix unused-but-set variable with G_DISABLE_ASSERT + - !1770 Minor scan-build fixes + - !1771 macos: fix frexpl checks in cross-compilation + - !1776 gio: ‘security_context_t’ is deprecated + - !1780 Minor Coverity fixes + - !1781 gspawn: Handle ENOSYS from close_range() + - !1782 ghostutils: Abandon hostname conversion early if it’s too long + +* Translation updates: + - Czech + - Spanish + - Ukrainian + + +Overview of changes in GLib 2.67.0 +================================== + +* Important and time-critical fix to DST transitions which will happen in Europe + on 2020-10-25 on distributions which use the ‘slim’ tzdata format (which is + now the default in tzdata/tzcode 2020b) (work by Claudi M., LRN) (#2224) + +* Further timezone handling changes to improve performance of `GTimeZone` (work + by António Fernandes, Sebastian Keller) (#2204) + +* Fix deadlock on Windows when `G_SLICE` is set in the environment (diagnosis by + Christoph Reiter) (#2225) + +* Fix UTF-8 validation when escaping URI components (thanks to Marc-André Lureau) (!1680) + +* Security fix for incorrect scope/zone ID parsing in URIs (!1669) + +* Add `g_log_writer_default_set_use_stderr()` API for printing log messages to stderr (work by Simon McVittie) (#2087) + +* Improve connection error reporting when IPv6 is available and disabled (work by Michael Catanzaro, debugging by Konstantin Kharlamov and Milan Crha) (#2211) + +* Fix definition of `G_MSVC_SYMBOL_PREFIX` for ARM (work by Wolfgang Stöggl) (!1187) + +* Add `GStrvBuilder` convenience API for building `NULL`-terminated string arrays (work by Robert Ancell) (!1417) + +* Support appinfo verbs other than ‘open’ on Windows (work by LRN) (!1502) + +* Expose node-based `GTree` APIs (work by Maciej S. Szmigiero) (!1509) + +* Add `G_DBUS_METHOD_INVOCATION_HANDLED`/`_UNHANDLED` convenience constants (work by Simon McVittie) (!1603) + +* Set `IP_BIND_ADDRESS_NO_PORT` on sockets when binding to local addresses (work by Cristian Rodríguez) (!1598) + +* Add Meson option for libelf support (work by Niklas Gürtler) (!1650) + +* Add support for PKCS #11-backed TLS certificates (work by Patrick Griffis) (!1663) + +* Add `g_subprocess_launcher_close()` API to make `GSubprocessLauncher` more usable in bindings (work by Sergio Costas) (!1677) + +* Bugs fixed: + - #1233 GType for GTree + - #2077 Invalid Pointer Arithmetic in g_path_get_basename + - #2087 Respecting G_MESSAGES_DEBUG in a custom log writer should be easy to do + - #2164 GDBus DBUS_COOKIE_SHA1 mechanism may use too old a key + - #2194 gtk3/glib crash on gimp + - #2203 fstatat is available only on macOS 10.10+ + - #2204 Time zone cache is constantly invalidated if TZ is NULL + - #2209 gthreadedresolver: faulty logic in parse_res_txt + - #2210 g_private_replace ordering issue + - #2211 "Network is unreachable" error returned when IPv6 is disabled and network is reachable using IPv4 + - #2215 DST incorrectly ends on wrong dates + - #2224 top bar time is incorrect, timezone map in control center is broken + - #2225 Setting G_SLICE makes Windows programs hang since 2.66 + - !1187 Define G_MSVC_SYMBOL_PREFIX correctly for ARM + - !1417 gstrvbuilder: Add a new object to make NULL-terminated string arrays. + - !1449 gio: Expose g_file_query_info_for_copy() + - !1502 GWin32AppInfo: Support verbs other than "open" + - !1509 GTree: add an ability to iterate over a tree and a node-based API + - !1575 Use C++11 decltype where possible + - !1598 gsocketclient: set IP_BIND_ADDRESS_NO_PORT if binding to local address + - !1603 GDBus: Add G_DBUS_METHOD_INVOCATION_HANDLED, _UNHANDLED + - !1643 Minor Coverity fixes + - !1645 Fix various signedness warnings + - !1647 Fix warnings (keep going) + - !1648 glocalfile: Never require G_LOCAL_FILE_STAT_FIELD_ATIME + - !1650 Make libelf dependency optional via meson feature + - !1652 trash portal: Handle portal failures + - !1654 gio-tool-trash: Prevent recursion to speed up emptying trash + - !1657 glist: Clarify that g_list_free() and friends only free an entire list + - !1658 utils: Limit the scope of the variable `max` + - !1661 Lookup fallback time zones in the cache to improve performance + - !1663 gtlscertificate: Add support for PKCS #11 backed certificates + - !1665 Fix g_module_symbol() under Windows sometimes not succeeding + - !1669 guri: Fix URI scope parsing + - !1670 GSubprocessLauncher: Move cleanup to dispose() + - !1671 gdatetime: Avoid integer overflow creating dates too far in the past + - !1673 CI: Re-enable code coverage reporting for MSYS2 builds + - !1674 Add version macros for 2.68 + - !1675 Make static assertions about standard types + - !1677 gsubprocesslauncher: Allow to close FDs + - !1678 gmessages: Document that using a custom log writer basically disables fatal handling + - !1679 gmain: Fix minor typo in documentation + - !1680 guri: Fix UTF-8 validation when escaping URI components + - !1681 gspawn: Handle error opening /dev/null + - !1686 Various improvements in GSocketClient + - !1687 uri: add missing (not)nullable annotations + - !1688 gspawn: Use close_range() if available to close FDs between fork/exec + - !1691 gmain: Fix possible locking issue in source unref + - !1692 gsignal: Plug g_signal_connect_object leak + - !1695 gfile: Clarify refcount handling for g_file_replace_contents_bytes_async() + - !1696 Fix various minor scan build warnings + - !1706 Add various missing nullable annotations + - !1712 Revert "Use C++11 decltype where possible" + - !1714 gmacros: Use __typeof__ when compiling with Clang + - !1718 gtrace: Add G_GNUC_PRINTF annotation + +* Translation updates: + - Chinese (Taiwan) + - Danish + - Greek, Modern (1453-) + - Hebrew + - Latvian + - Portuguese + - Russian + - Slovak + - Ukrainian + + +Overview of changes in GLib 2.66.0 +================================== + +* Bugs fixed: + - #2200 missing tab in makefile rule + - !1639 guri: Fix user passed to g_uri_split_with_user() not being NULL'd + +* Translation updates: + - Croatian + - Hungarian + - Italian + - Serbian + - Slovak + - Swedish + + +Overview of changes in GLib 2.65.3 +================================== + +* Fixes to the new `statx()` calls — note that since GLib 2.65.2 uses `statx()` + (if available) instead of `stat()`/`fstat()`/`lstat()`/`fstatat()`, syscall + sandboxing for third party applications might need to be updated + +* Bugs fixed: + - #2189 g_file_query_info on ro file system: Numerical result out of range + - #2191 Calling nice(20) can lead to thread related warnings + - #2197 Segfaulting Integer Overflow in g_option_group_add_entries + - !1025 Big o notations + - !1626 gio: Document g_settings_new() missing schema behaviour + - !1627 gthread: Add a sysprof mark for thread creation + - !1628 Replace a bunch of fallthrough comments with an attribute + - !1631 Fix splice behavior on cancellation + - !1632 Fixing signedness warning in glib/gfileutils.c + - !1635 gcancellable: Mark a variable as unused if built with G_DISABLE_ASSERT + +* Translation updates: + - Basque + - Catalan + - Chinese (China) + - Czech + - English (United Kingdom) + - Friulian + - German + - Japanese + - Kazakh + - Korean + - Lithuanian + - Polish + - Portuguese (Brazil) + - Slovenian + + +Overview of changes in GLib 2.65.2 +================================== + +* Support `statx()` and `G_FILE_ATTRIBUTE_TIME_CREATED` (work by Andre Miranda) (#1970) + +* Fix deadlock in `g_subprocess_communicate_async()` (work by Alexander Larsson) (#2182) + +* Add `%f`/microsecond placeholder support to `g_date_time_format()` (work by Johan Bjäreholt) (!1605) + +* Bugs fixed: + - #5 g_new0 performance + - #1970 Make G_FILE_ATTRIBUTE_TIME_CREATED support stx_btime + - #2176 Inconsistent introspection annotations for g_input_stream_read and g_socket_receive + - #2182 g_subprocess_communicate_async() can deadlock when writing + - !1593 CI support for Coverity Scan + - !1605 gdatetime: Add %f format specifier and microsecond precision to g_date_time_format_iso8601 + - !1613 gfile: Document TOCTTOU avoidance using g_file_delete() + - !1615 docs: glib-compile-resources: json-stripblanks + - !1616 gioerror: Map WSAENETRESET on Windows to G_IO_ERROR_CONNECTION_CLOSED + - !1619 Minor Coverity fixes + - !1620 gvariant: Ensure GVS.depth is initialised + - !1622 gdatetime: Widen a variable before multiplication + - !1623 gcancellable: Assert that make_pollfd() call succeeds + - !1624 gdbusaddress: Drop an unnecessary NULL check + - !1625 gdbusmessage: Drop redundant uint ≥ 0 checks + +* Translation updates: + - French + - Galician + - Greek, Modern (1453-) + - Indonesian + - Romanian + - Spanish + - Turkish + - Ukrainian + + +Overview of changes in GLib 2.65.1 +================================== + +* Add `GUri` API for parsing, building and representing URIs according to + [RFC 3986](https://tools.ietf.org/html/rfc3986) (work by Marc-André Lureau) (#110) + +* Fix handling of xattr data with embedded nuls (#422) + +* Add `g_file_set_contents_full()` which gives more control over fsyncs (#1302) + +* Fix cross-compilation on iOS (work by Nirbheek Chauhan) (#1868) + +* Add a `x-gvfs-notrash` option to disable trash on certain mounts (work by Ondrej Holy) (!1549) + +* Support ‘slim’ TZif files generated with `zic -b slim` (work by Paul Eggert) (#2129) + +* Support emitting profiling marks from `GMainContext` to sysprof capture files (!1551) + +* Accept IPv6 zone IDs in `g_hostname_is_ip_address()` (work by Marc-André Lureau) (!1604) + +* Bugs fixed: + - #4 Include a UTF-8 safe escaping function + - #110 Basic URI operations + - #137 display_name should be always available + - #250 GTestCase's setup/teardown functions appear pointless + - #272 allow thread pools to adjust the number of threads to the number of cpu's/cores + - #422 Wrong assumption in libgio GFileInfo on xattr/acl string: it may contain binary data. + - #858 glib2 @2.40.0 issues a "Got weird mach timebase info" error (Macports, PPC) + - #1022 g_object_new Should Mention That it Zeroes Out Private Struct + - #1200 Make g_assert_null/nonnull clang static analyzer friendly + - #1203 Add a variant of g_file_set_contents() which accepts file mode + - #1288 gmacros: Introduce non-public G_CLANG_ANALYZER_NORETURN macro + - #1302 g_file_set_contents() can fill target with NUL bytes if it did not previously exist + - #1670 ThreadSanitizer data races + - #1764 cancellable test: on_mock_operation_ready: assertion failed (iterations_requested > iterations_done): (10 > 10) + - #1868 iOS cross compile impossible due to frexpl check not supporting cross compilation + - #1869 iOS doesn't have Cocoa, which thankfully isn't a requirement of this code that supposedly requires it + - #1982 GSocketAddressEnumerator documentation is inconsistent with existing usage + - #2127 Spurious GIO module initialization on Fedora Silverblue (and other ostree-based systems?) + - #2129 date_time bugs after 2038, or with today's date and 'zic -b slim' TZif files + - #2132 Valgrind reports "still reachable" after g_thread_pool_new/free + - #2136 Valgrind reports "still reachable" after g_option_context_parse + - #2140 calling malloc in fork child is undefined-behaviour + - #2141 g_value_copy is was recently broken + - #2149 Make G_URI_FLAGS_PARSE_STRICT the default + - #2156 Merge _g_uri_parse_authority() into GUri + - #2159 Thread-unsafe initialization in gportalsupport.c + - #2160 More guri regressions + - #2165 More guri breakage + - #2166 g_uri_build() functions should accept a NULL scheme + - !1328 guri: new URI parsing and generating functions + - !1527 Add g_tls_connection_get_channel_binding_data call and enums + - !1534 Various GLocalFile fixes related to the filesystem::remote attribute + - !1546 tree: Fix various ableist language + - !1549 Add support to ignore trash for certain mounts + - !1551 Add initial sysprof support + - !1553 gtestutils: Mark that g_assert_whatever() macros do not normally return + - !1554 GUri build fixes + - !1555 Remove c-format from the string that is not c-formatted + - !1556 fuzzing: Another fix for g_uri_parse() test + - !1557 A few g_uri_parse_params() improvements + - !1559 Fix buffer read overflows in GUri + - !1561 gconvert: Use a pointer array in extract_uris + - !1563 gdesktopappinfo: Fix unnecessarily copied and leaked URI list + - !1564 tests: limit number of threads to something reasonable. + - !1570 Reduce CI bandwidth requirements + - !1572 Add GUriParamsIter + - !1576 gtask: Only override g_task_set_source_tag() for GLib ≥ 2.60 + - !1577 uri: add illegal_characters argument to unescape_bytes + - !1578 tests: Add tests for RFC 8536 v3 parsing of time zones + - !1579 glib: Use g_getenv everywhere instead of getenv + - !1582 appinfo: Add properties + - !1583 gio: Remove broken support for XP + - !1590 Use CI schedules and DAGs + - !1591 gfileutils: Fix O_NOFOLLOW handling on BSD systems + - !1594 GFile: Document that G_FILE_CREATE_REPLACE_DESTINATION can only be used with... + - !1595 uri: add ENCODED_PATH & ENCODED_FRAGMENT flags + - !1599 uri: do not add ipv6 brackets on non-ip host + - !1600 uri: do not encode ':' and ';' from userinfo + - !1601 timezone: Fix an uninitialized use + - !1602 Revert "Merge branch 'appinfo-properties' into 'master'" + - !1604 Make g_hostname_is_ip_address() accept ipv6 zoneid + - !1609 Fix multiple typos in guri.c + - !1611 guri: Always prepend `//` to the host when building a URI + - !1612 guri: Document and check restrictions on path prefixes + +* Translation updates: + - Catalan + - Kazakh + - Lithuanian + - Romanian + - Slovenian + - Spanish + - Ukrainian + + +Overview of changes in GLib 2.65.0 +================================== + +* Fix memory monitor tests to only be installed if installed-tests are enabled, + and to be skipped if GObject-Introspection is too old (!1407) + +* Stability improvements for various unit tests + +* D-Bus credentials support on macOS (#507) + +* MSVC support for the files generated by `glib-compile-resource` and `gdbus-codegen` (#1215, !1452) + +* Year 2038 fixes involving new API in `GBookmarkFile` (#1931) + +* SOCKS5 proxy authentication fixes (#1986, #1988) + +* Support for more than `MAXIMUM_WAIT_OBJECTS` FDs for `g_poll()` on Windows (#2107) + +* Add `g_assert_no_errno()` test macro for testing POSIX-style functions (!1204) + +* Update Unicode Character Database to version 13.0.0 (!1422) + +* Support storing interned strings in `GValue`s efficiently, via `g_value_set_interned_string()` (#2109) + +* Bugs fixed: + - #2 g_filename_from_utf8() should normalize? + - #176 the behaviour of constructors for GLib data types is not specified if memory allocation fails + - #480 /gdbus/connection/signals test intermittently fails: assertion failed (count_name_owner_changed == 2): (1 == 2) + - #507 GDBus credentials don’t work on OS X + - #602 GLib.Thread not usable from GObject-Introspection + - #1154 Missing documentation how to set a value in a GArray + - #1215 MSVC cannot build glib-compile-resource's output resource file + - #1323 meson, autotools: figure out if mem barrier is needed for arm64 host variant aarch64 + - #1398 gdate: Add error handling for GetDateFormatW calls + - #1841 Signal handler disconnection race when finalising GCancellableSource + - #1851 Meson Build Failure on Windows: Undefined Reference to libiconv + - #1911 Memory leak in g_param_spec_flags and/or g_param_spec_enum + - #1931 GBookmarkFile API involves time_t + - #1954 gdbus-server-auth intermittent failure + - #1957 gdbus-connection test failure on FreeBSD + - #1986 Socks5 Proxy: Authentication seems broken + - #1988 Socks5 Proxy: Wrong error returned when using no authentication + - #2038 Bindings: g_tls_connection_set_database() does not allow None as argument + - #2051 GUnixOutputStream can block on close() + - #2057 Call malloc_trim() under memory pressure + - #2067 Glib uses _Static_assert in C++17 mode + - #2081 gdbus error messages contains mixed up body and head signatures + - #2082 AM/PM - specific variation support needed to Hebrew language + - #2083 Memory monitor tests fail if dbusmock isn't installed + - #2092 FreeBSD CI timing out in gdbus-connection filter test + - #2094 Deprecation warnings when compiling with -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_28 -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_28 + - #2106 Duplicated if - else if conditions in gtranslit.c + - #2107 g_poll() implementation on Windows stall when more than MAXIMUM_WAIT_OBJECTS FDs have passed + - #2109 GValue: Add support for interned string + - #2124 g_file_info_get_content_type() may return NULL + - #2132 Valgrind reports "still reachable" after g_thread_pool_new/free + - #2134 Valgrind reports "still reachable" after `g_uuid_string_random()`. + - #2135 Valgrind reports "still reachable" after g_key_file_new/free + - #2136 Valgrind reports "still reachable" after g_option_context_parse + - !1204 gtestutils: Add a new g_assert_no_errno() test macro + - !1302 gobject: new g_param_is_valid_property_name() function. + - !1329 Support nanoseconds in stat timestamps on Windows + - !1341 MUI capabilities for GWin32RegistryKey + - !1360 CI: Show execution environment before we start + - !1395 tests: Move memory_monitor_tests under installed_tests_enabled + - !1396 macros: Define G_GNUC_FALLTHROUGH for more compilers + - !1397 tests: Skip MemoryMonitor test if GObject-Introspection is too old + - !1398 gcontenttype: Fix crash in _get_generic_icon_name() + - !1402 ci: Update Android Docker image for aarch64 CPU naming change + - !1405 tests: Disable link-time warning for mem-overflow + - !1406 Replace fallthrough comments with G_GNUC_FALLTHROUGH + - !1408 tests: Don't compare strings by pointer + - !1409 gdummytlsconnection: Add missing overrides for ALPN properties + - !1413 gapplication: Fix a minor typo in the documentation + - !1414 gstrutils: Set locale explicitly for search-utils test + - !1415 meson: Don't use assert in test code + - !1418 ginetaddress, ginetsocketaddress: Add missing (nullable) annotations + - !1422 glib: Update Unicode Character Database to version 13.0.0 + - !1423 gobject: Clarify assertion failure on ref-after-finalize + - !1424 docs: Fix configuration with gtk_doc=true and installed_tests=false + - !1425 gdbusconnection: GDBusSignalCallback can have a NULL sender_name + - !1426 gunidecomp: Update and reformat Unicode version support history + - !1427 gicon: Clarify GVariant refcounting in docs + - !1428 Add missing 'extern' to the dllexport version of GLIB_VAR/GOBJECT_VAR + - !1429 Fix arch detection ifdefs in glib/valgrind.h + - !1430 Use __builtin_trap() on Clang on any platform + - !1431 glib-unix.c: fix heap corruption in g_unix_get_passwd_entry + - !1432 docs: Mention new gio tool options + - !1433 meson: Fix buildtype usage + - !1434 gdbusconnection: Clarify nullability of SignalInstance.sender + - !1436 glib: Update internal copy of valgrind.h from Valgrind 3.15 release + - !1437 gmarkup tests: tab character escape/unescape + - !1439 Don't misdetect stpcpy on windows platforms on clang + - !1440 Silence clang errors about -Wformat-nonliteral due to missing intermediate attributes + - !1441 Meson: Override every dependency glib provides + - !1442 gfile: Fallback to fast-content-type if content-type is not set + - !1443 gio: use TAPTestRunner in the memory monitor tests + - !1444 Meson: Add glib-checks and glib-asserts options + - !1452 Make symbols generated by gdbus-codegen exportable on Visual Studio-style builds + - !1455 gdesktopappinfo: Note that search results are not filtered + - !1456 GCredentials documentation fixes + - !1458 meson: Exclude gosxutils.m when building for iOS + - !1459 meson: Fix the gnulib checks for isnan* functions + - !1460 glib: Sync the local modification to glib/valgrind.h to what was upstreamed + - !1462 gvariant-core: Add a note about memory safety of children + - !1463 gdesktopappinfo: Add several nullable annotation to GAppInfo getters + - !1464 Update Fedora CI + - !1466 CI: Switch to new Windows runners + - !1469 goption: Treat an empty option context parameter string as NULL + - !1475 Improve documentation of g_tls_database_verify_chain() + - !1476 tests: Fix remaining race in gdbus-connection filter test + - !1479 Improve documentation of client connection validation flags + - !1480 CI: Make sure we use meson 0.49.2 in MSYS2 + - !1481 array: fix corrupt state of GPtrArray after g_ptr_array_extend_and_steal() + - !1482 [th/g-ptr-array-variable-cleanups] minor cleanup of variables for GPtrArray + - !1487 glib: annotate static inline functions with G_AVAILABLE-type macros + - !1488 Rebuild Fedora CI image + - !1491 gdatetime: update annotations + - !1492 glib-mkenums: allow optional 'since' tag + - !1493 meson: Remove stray ] in O_DIRECTORY check + - !1496 Fix GLIB_UNAVAILABLE_STATIC_INLINE declaration + - !1498 array: add internal ptr_array_new() helper for creating GPtrArray + - !1503 docs: Add indexes for symbols added in 2.66 + - !1505 gobject: Handle runtime checks as such + - !1506 tests: Speed up the cancellable test + - !1508 tests: Speed up the file test and make it more reliable + - !1512 Various fixes when building for iOS + - !1513 Initialize the visited time of a new GBookmarkFile + - !1515 meson: check for stpcpy using cc.links() + - !1516 gthreadedsocketservice: Mark source_object of run signal as nullable + - !1517 GWin32RegistryKey: Move assertions + - !1518 strfuncs: Use a GPtrArray in strsplit() + - !1522 meson: Fix gnulib printf checks + - !1524 meson: Fix gnulib build where isnan*() is needed + - !1525 Normalize C source files to end with exactly one newline + - !1528 gtlsconnection: Improve documentation of peer-certificate[-errors] + - !1530 tree: Fix various typos and outdated terminology + - !1531 gvariant: Fix documentation for g_variant_get_string() to match reality + - !1532 win32: spelling fix + - !1535 glib.supp improvements + +* Translation updates: + - BokmÃ¥l, Norwegian + - Catalan + - Catalan (Valencia) + - Chinese (Taiwan) + - Dutch + - French + - Galician + - German + - Hebrew + - Indonesian + - Italian + - Japanese + - Latvian + - Lithuanian + - Malay + - Romanian + - Serbian + - Slovak + - Slovenian + - Spanish + - Turkish + - Ukrainian + + +Overview of changes in GLib 2.64.0 +================================== + +* Use `posix_spawn()` to speed up launching test D-Bus instances (!1388) + +* Bugs fixed: + - #1783 Document using glib-mkenums with meson + - #2049 Crash in g_array_copy + - !1384 Some minor clang warning fixes + - !1386 docs: Document generated headers caveats for genmarshal + - !1387 ci: Correctly propagate exit status in run-style-check-diff.sh + - !1388 gtestdbus: Use posix_spawn() to spawn dbus-daemon + - !1389 Update GError docs to use G_DEFINE_QUARK + +* Translation updates: + - Czech + - Danish + + +Overview of changes in GLib 2.63.6 +================================== + +* Fix potential relative read when calling g_printerr(), which could lead to a + denial of service from a setuid-root process being used to block access to the + TTY for another user (#1919) + +* Fix SOCKS proxy resolver sometimes not being used when resolving addresses + via Happy Eyeballs (CVE-2020-6750) (#1989) + +* Several other Happy Eyeballs fixes for address resolution (#1871, #1872, #1902) + +* Various race fixes in `GDBusConnection` and its unit tests (#1515) + +* Fix a race condition with D-Bus name ownership (#1517) + +* Drop `gio-launch-desktop` helper application in favour of calling `sh` directly (#1633) + +* Fix win32 exception handling with C# exceptions (#2025) + +* Fix thread safety of `GUnixMountMonitor` (#2030) + +* Additional fixes to new thread pool attribute behaviour from GLib 2.63.4 to + check if sched_setattr() is allowed by system policies before depending on it (#2039, !1356) + +* Fix memory leaks and corruption when freeing `GSource`s while freeing a `GMainContext` (!1353) + +* Drop inappropriate installation of object manager example documentation (!1359) + +* Bugs fixed: + - #938 gdbus call -a doesn't support message bus connections + - #1515 gio/gdbus-threading test sometimes fails in CI + - #1517 g_bus_own_name does not always call name_lost_handler when _REPLACE and _ALLOW_REPLACEMENT are set + - #1633 should not install gio-launch-desktop into PATH + - #1919 read from relative path in g_printerr() in 2.58.3 + - #1995 Tracker issue for Happy Eyeballs regressions + - #2002 g_io_channel_read_line does not honour the line_term symbols set + - #2025 W32 exception handling misbehaves when C# exceptions are thrown when running inside the Visual Studio debugger + - #2030 Random nautilus test suite failures involving GUnixMountMonitor + - #2039 sched_setattr() still can cause EPERM through natural causes + - #2043 Low memory monitor test failed in CI + - #2044 GApplication docs suggest invalid GVariant type + - !1185 gtimezone: Tidy up UTC timezone creation + - !1281 ci: Update Docker packages + - !1283 gmodule: change _g_module_close to only take a handle. + - !1298 tests: Speed up the GIO actions test + - !1299 gapplication: Fix a minor typo in the documentation + - !1339 gsocketclient: Refactor g_socket_client_connect_async() + - !1353 GMainContext - Fix memory leaks and memory corruption when freeing sources while freeing a context + - !1354 GThreadPool - Add test for !1340 + - !1355 glist: Add docs examples of how to combine with g_steal_pointer() + - !1356 GThread - Check if sched_setattr is allowed by the system policies before depending on it + - !1359 docs: Don’t install object manager example separately + - !1363 Make tests pass if we are euid != 0 with capabilities + - !1366 Fix oss-fuzz coverage link + - !1372 gobject: Fix strict aliasing warnings with g_set_object() + - !1376 gitlab-ci: 64-bit ARM is aarch64, not arm64 + - !1381 ghash: Document the iteration order over a hash table is not defined + - !1382 tests: Bump the refcount timeout in gdbus-threading + - !1383 ci: Enable parallelisation when running installed tests + +* Translation updates: + - Basque + - English (United Kingdom) + - French + - Galician + - German + - Greek, Modern (1453-) + - Hungarian + - Indonesian + - Japanese + - Korean + - Lithuanian + - Polish + - Portuguese (Brazil) + - Spanish + - Swedish + - Turkish + + +Overview of changes in GLib 2.63.5 +================================== + +* Fix behaviour of `g_file_move()` fallback code to not follow symlinks (#986) + +* Rename `--glib-min-version` argument of `gdbus-codegen` to `--glib-min-required` + (this is not an API break as `--glib-min-version` was added earlier in the + 2.63 cycle) (#1993) + +* Add gtk-doc checks to CI and fix a number of documentation issues + (thanks to Xavier Claessens) (!978) + +* Add `G_SIZEOF_MEMBER()` macro (!1333) + +* Add a debug message if `g_setenv()` or `g_unsetenv()` are used after any + threads have been spawned — this will be upgraded to a warning in future (!1337, #715) + +* Skip memory monitor tests if xdg-desktop-portal or dbusmock are not available (!1296, !1338) + +* Change the `libmount` configure option from a boolean to a Meson `feature` (!1344) + +* Do not return `target-uri` from `g_file_peek_path()` when called on trash/recent files (!1346) + +* Drop new TLS certificate API for PKCS #11 backed certificates, as the implementation + is not ready yet (this is not an API break as the API was added earlier in the + 2.63 cycle) (!1347) + +* Bugs fixed: + - #986 g_file_move: remove G_FILE_COPY_NOFOLLOW_SYMLINKS section + - #1551 CI: Add checks for `TODO` in MRs + - #1925 Large number of routes installed into kernel cause high cpu usage + - #1993 Rename gdbus-codegen --glib-min-version argument to --glib-min-required and add --glib-max-allowed + - #2012 spawn_thread_queue not initialised in GThreadPool + - #2020 g_network_monitor_base_add_network() improperly unrefs GInetAddressMask + - !978 Various fixes to make gtkdoc-check pass on glib + - !1018 docs: tag enclose 'all' and 'help' values + - !1170 Avoid C++20 deprecated assignment to volatile + - !1296 tests: Skip GMemoryMonitor tests if the dbusmock template is not available + - !1307 Remove global declaration of GMemoryMonitor + - !1322 gmain: Mark G_SOURCE_FUNC as available in 2.58 + - !1333 Add and use G_SIZEOF_MEMBER() macro + - !1337 genviron: Message if g_setenv()/g_unsetenv() are used after threads spawned + - !1338 tests: Skip GMemoryMonitor tests if xdg-desktop-portal is not available + - !1344 meson: libmount autodectection + - !1345 gio-tool-info: Print unix mount information where available + - !1346 gfile: Do not return target-uri from g_file_peek_path() + - !1347 Revert "gtlscertificate: Add support for PKCS #11 backed certificates" + - !1348 ghash: Clarify that g_hash_table_add() always consumes the key + - !1349 doc: Clarify that _locker_new() does not actually allocate memory + - !1351 glib.supp: update g-threaded-resolver-getaddrinfo-config + +* Translation updates: + - Japanese + - Lithuanian + - Malay + - Portuguese (Brazil) + - Swedish + + +Overview of changes in GLib 2.63.4 +================================== + +* Fix various race conditions on signal emission in GDBus (#604, #978, #1232) + +* Change thread pools so that thread attributes (in particular, priority) are + inherited from the thread which created the `GThreadPool` initially, rather + than from the thread which is pushing a new job into the pool (#1834, #2007) + +* Expand support for running Windows apps with + `g_app_info_launch_default_for_uri()` using rundll32 on Windows (#1932) + +* Support multiple directories in `GSETTINGS_SCHEMA_DIR` environment variable (#1998) + +* Support full Julian day range in `TZ` environment variable (#1999) + +* Apply recursion depth limits to variants in D-Bus messages (!1201) + +* Support adding call flags and timeouts to method calls generated by + `gdbus-codegen` through the new `--glib-min-version` option (!1286) + +* Fully deprecate TLS rehandshakes; they are now ignored due to TLS protocol + changes (!1305) + +* Bugs fixed: + - #198 g_fopen and friends: should also state how to close a stream + - #604 GDBus name watching dispatch is buggy/excessively-complicated + - #833 g_object_set: document the need to cast varargs + - #978 SIGSEGV in on_name_lost_or_acquired + - #1232 Insufficient thread safety around GDBusObjectManagerClient + - #1416 Re-add macOS CI + - #1834 Unwanted priority/etc inheritance with GThreadPool and GThread and the POSIX implementation + - #1932 Windows: Gio.AppInfo.launch_default_for_uri seems not to work for local files/folders + - #1983 glib:gio / dbus-appinfo test fails: GLib-GIO:ERROR:../../../../Projects/glib/gio/tests/dbus-appinfo.c:326:on_flatpak_open: 'g_file_equal (files[0], f)' should be TRUE + - #1997 Base64 encoding with "break_lines" claims to wrap at 72 characters but seems to wrap at 76 + - #1998 support multiple directories in GSETTINGS_SCHEMA_DIR + - #1999 GTimeZone fails to accept full Julian day range when parsing the direct $TZ string format + - #2007 Thread scheduler attributes fail under valgrind + - !388 ci: Avoid downloading subprojects for each job + - !1111 gio: test that launch_uris() exports files with the document portal when launching a flatpak + - !1201 gdbusmessage: Limit recursion of variants in D-Bus messages + - !1279 tests: Fix an error message set by foo_set_property() + - !1286 gdbus-codegen: Add a GDBusCallFlags arg to method calls + - !1291 gio-tool-list: Add an option to print display names + - !1294 GMemoryMonitor docs fixes + - !1295 gio: Fix socket test + - !1301 GThread - Inherit parent thread priority by default for new Win32 threads + - !1303 gvariant-core: Don't pass NULL second argument to memcpy + - !1305 Fully deprecate TLS rehandshakes + - !1308 gsocketclient: run timeout source on the task's main context + - !1309 Fix crash in gutils when application is prevented access to passwd file + - !1317 gfdonotificationbackend: remove notifications when bus name vanishes + - !1320 subprojects: Temporarily avoid using wrapdb while it’s down + - !1324 ci: Add some documentation to the style check CI test + - !1325 Check for SYS_sched_getattr before using it unconditionally + - !1330 W32: Correctly set st_ino when doing private stat() + - !1334 gthread: Ensure GThreadSchedulerSettings is always defined + +* Translation updates: + - Catalan + - Galician + - Hungarian + - Indonesian + - Polish + - Portuguese (Brazil) + - Spanish + + +Overview of changes in GLib 2.63.3 +================================== + +* Add a `--glib-min-version` argument to `gdbus-codegen` which controls breaks in the API of generated code (#1726) + +* Add `g_clear_list()` API to clear `GList`s to `NULL` (#1943) + +* Add a `GMemoryMonitor` API to be notified of memory pressure situations using the low-memory-monitor project (!1005) + +* Add support for dispose functions for `GSource` implementations (!1175) + +* Tighten up validation of GObject signal and property names, allowing performance improvements (!1224) + +* Fix installation path of GIO modules on MSVC to be the bindir (!1254) + +* Bugs fixed: + - #650 g_signal_lookup gives too many warnings + - #1011 GListStore, easily find if the item is already inserted + - #1130 gdbus-codegen: Add an option to strictly generate markdown in source comments + - #1687 glocalvfs.c uses non-thread-safe getpwnam() + - #1726 Warn when method/signal uses type 'h' but lacks GDBus.C.UnixFD annotation + - #1935 Assert in _kqsub_free seems to be too strict + - #1943 Consider g_clear_list() + - #1947 Documentation clarification for g_uuid_string_random() + - #1953 Documentation for g_type_init() and others missing from online gtk-doc documentation + - #1961 A typo in the comment of `g_settings_schema_get_path`: threfore -> therefore + - !1005 gio: Add GMemoryMonitor to monitor for low-memory + - !1172 gptrarray: Add an example to the g_ptr_array_steal() docs + - !1175 Implement a dispose function for GSource + - !1223 Add additional valgrind suppressions + - !1224 Signal name handling improvements + - !1230 ci: Run installed-tests on Fedora + - !1235 Add sudo to Fedora docker image + - !1239 tests: Run "timeout tests" sequentially + - !1248 ci: Update all Debian CI runners to use v5 of the Dockerfile + - !1249 gio-tool-mount: Allow mounting by the given UUID + - !1252 ci: Fix running all jobs on merge requests + - !1253 gthread: Fix "zero as null pointer" warning + - !1254 giomodule: gio modules are no longer installed in bindir on MSVC + - !1255 ci: Build Docker images rather than OCI images if using podman + - !1256 gdate: Add autoptr support + - !1258 Minor CI fixups + - !1261 gtk-doc: Ensure we have recent enough version + - !1262 tests: Add tests for the gdbus-codegen executable + - !1265 build: don't check for protected visibility + - !1267 Revert "doc: Workaround gtkdoc-scan bug leading to undocumented symbols" + - !1268 ci: Work-around successful installed tests having no logs + - !1269 gvariant: Add guard to g_variant_get() + - !1271 tests: Enable GDBus debug for a number of unreliable tests + - !1274 trash portal: Don't follow symlinks + - !1275 Small doc correction + - !1277 Various gtk-doc improvements + - !1278 Update installed tests CI + - !1280 clang-format-diff: Output diff for multiple files, not just one + - !1282 Revert "Revert "docs: remove GDBusObjectManager example"" + - !1284 Update POTFILES.in 191212 + - !1287 atomic/tests: test g_atomic_pointer_compare_and_exchange() with const pointers + - !1289 gtype: Define auto-cleanup functions for Module class + +* Translation updates: + - Spanish + + +Overview of changes in GLib 2.63.2 +================================== + +* Use `lldb` rather than `gdb` on macOS for debugging (#1004) + +* Switch the atomic builtins from `__sync_fetch_*()` to the slightly more modern + `__atomic_*()` (#1750) + +* Fix calculation of `gsize` width on various platforms (including OpenBSD) (#1777) + +* Fix undefined behaviour causing brokenness in `g_utf8_find_prev_char()` when + compiling with GCC ≥ 8 (#1917) + +* Revert UNIX mode changes in `G_FILE_ATTRIBUTE_ID_UNIX_MODE` which broke OSTree (#1934) + +* Slightly improve performance for signal emissions when no handlers are connected (!1083) + +* Add `g_task_return_value()` and `g_task_propagate_value()` APIs to allow + `GTask` to be used from language bindings more easily (!1216) + +* Fix a file monitoring crash on kqueue-based systems (BSD) (!1221) + +* Bugs fixed: + - #1004 [PATCH] Make gbacktrace use lldb on Mac OS X + - #1552 CI: Add code style checks + - #1750 Switch from __sync_fetch_*() to __atomic_*() in glib/gatomic.h + - #1777 gsize: improper typedef on (at least) OpenBSD + - #1895 Regression: glib does not compile on centos 6: "objcopy: unrecognized option '--add-symbol'" + - #1917 Test utf8-pointer fails with static build, LTO, optimisations, and new GCC + - #1930 glib/tests/bookmarkfile.c:385:test_modify: assertion failed: (stamp == now) + - #1934 ostree tests broken since bfdc5fc4fc84ef8518d2d1a328c8482cf5a38e98: File '/tmp/test-tmp-libostree_test-basic-user.sh.test-QB4SA0/diff-test2' is not empty + - #1938 GDateTime doesn't support leap seconds + - #1940 atomics test fails on FreeBSD CI since !1123 + - !1039 Improve documentation for footgun function g_tls_client_connection_copy_session_state() + - !1083 Use the GObject hole on 64bit arches for some flags to improve performance + - !1202 CI updates after !1177 + - !1208 gutils: Slightly improve docs formatting for g_get_os_info() + - !1209 Make ld executable configurable + - !1210 gdbus-server-auth test: Include gcredentialsprivate.h + - !1213 gsocket: Improve diagnostics on bind() failure + - !1214 gvariant, gbytes: Avoid memcmp (NULL, ., 0) or memcmp (., NULL, 0) + - !1216 Make GTask more binding-friendly + - !1218 gdb: Fix GHashTable pretty printer off-by-one error + - !1220 gparam: fix memory leak in g_param_value_defaults() + - !1221 Add NOTE_REVOKE to the list of the monitoring events + - !1225 gtlsconnection: clarify handshake() documentation + - !1227 Deprecate old GTlsConnection functionality even harder! + - !1231 Fix build on old libc that does not define _SC_HOST_NAME_MAX + - !1238 gstrfuncs: use gsize type internally for strv functions + - !1242 gfileinfo: Clarify the documentation for G_FILE_ATTRIBUTE_UNIX_MODE + - !1243 docs: Fix "occurred" typos in API documentation + +* Translation updates: + - Spanish + + +Overview of changes in GLib 2.63.1 +================================== + +* Several usability improvements to command line `gio` tool (!1153) + +* Add `g_array_steal()`, `g_ptr_array_steal()` and `g_byte_array_steal()` APIs (#285) + +* Add `g_get_os_info()` API (!1063, !1160) + +* Add `g_warning_once()` API (!1028) + +* Always resolve `localhost` to loopback address in `GResolver` (!616) + +* Add `GMainContextPusher` API (!983) + +* Limit recursion in `g_variant_parse()` (!1173) + +* Fix crash in `g_spawn()` with high FD numbers due to use of `select()` rather + than `poll()` (#954) + +* Allow passing empty `GValue`s to `g_param_value_set_default()` (!1186) + +* Escape header guards generated by `gdbus-codegen` better (#1379) + +* Bugs fixed: + - #285 [PATCH] add array steal and memdup functions + - #954 The g_spawn_sync() function uses select() which has limitations + - #1318 rare failure in gdbus-peer test: invalid uninstantiatable type '(null)' in cast to 'GDBusServer' + - #1379 gdbus-codegen generates invalid header guards when build directory contains a + character + - #1622 NULL pointer derefs on g_vasprintf() failure + - #1813 g_option_context_add_main_entries() is missing array annotation for entries parameter + - #1831 No reply on private socket due to auth problem + - #1836 gobject.c uses undefined annotation “(not optional)†+ - #1858 docs/reference/gobject/tut_gobject.xml: object properties example uses deprecated API + - #1877 g_cancellable_source_new annotated with 'skip' + - #1896 Use after free when calling g_dbus_connection_flush_sync() in a dedicated thread + - #1897 glib 2.62.0 fails test 'test_writev_no_vectors' wih gcc7 + - #1903 use-after-free in mimeapps test causes intermittent segfault during testing + - #1906 test_os_info fails on FreeBSD + - #1916 objcopy not used from cross-compilation file in GIO tests + - #1923 Recent Versions of GLib Break Dolphin File-Manager's Thumbnailing when Using 'gtk2' Style + - !616 Always resolve localhost to loopback address + - !983 gmain: Add GMainContextPusher convenience API + - !1014 tests: Add a test for g_assert_finalize_object() + - !1028 gmessages: Add g_warning_once() + - !1035 Switching from C gnu89 to C gnu99 standard + - !1063 gutils: Add g_get_os_info() + - !1082 gdatetime: Document RFC 3339 extensions when parsing ISO 8601 + - !1105 syscall flood on every time*() function call + - !1120 Update documentation with FreeBSD build instructions + - !1135 gmain: use atomic operation instead of GMutex to access g_main_context_default() + - !1146 Solaris build fixes + - !1147 gmodule: fix typo in doc comment + - !1148 gio/gfileinfo: fix parameter references + - !1149 gio/gfile: fix parameter reference for value_p + - !1150 gio/gfile: fix parameter references to @contents + - !1151 gio/gfile: fix typo in doc comment + - !1152 gwinhttpvfs: Handle g_get_prgname() returning NULL + - !1153 Several gio-tool bash completion fixes and improvements + - !1155 Strict-aliasing fixes to new atomic built-ins + - !1157 Fix various compiler warnings on Android + - !1160 Add Windows support to g_get_os_info() + - !1161 hash: Remove an assertion from the hot path + - !1163 gcharset: Expand the documentation for g_get_locale_variants() + - !1165 Use uname as a fallback to get OS info + - !1167 Fix some minor leaks in testfilemonitor + - !1168 Fix gdatetime tests on toolbox + - !1171 Revert "gdbus-codegen: emit GUnixFDLists if an arg has type 'h'" + - !1173 gvariant: Limit recursion in g_variant_parse() + - !1177 ci: Add libdbus development files to CI Docker images + - !1179 Improve GPtrArray doc-comments + - !1180 array: Avoid use of memcpy(dest, NULL, 0) + - !1181 gmain: Clarify thread safety of some common GSource functions + - !1182 gio: Fix typo in URL + - !1186 Allow using an empty GValue with g_param_value_set_default() + - !1189 gparamspecs: Fix type class leaks on error handling paths + - !1197 Fix GDBus test failures on non-Linux (in particular FreeBSD) + - !1200 Minor fixes from a scan-build run + +* Translation updates: + - Catalan + - Chinese (Taiwan) + - Spanish + + +Overview of changes in GLib 2.63.0 +================================== + +* Add g_fsync() API (#35) + +* Fix regression in g_file_copy() when passing + `G_FILE_COPY_TARGET_DEFAULT_PERMS` flag; the destination permissions would be + private rather than following the process’ umask (!1142) + +* Several `GDateTime` parsing fixes (!1127) + +* Always build the tests if installed-tests are enabled, so that the tests can + actually be installed (!1141) + +* Rework atomic function implementations to use memory barrier in the correct + place (when compiler intrinsics aren’t providing the atomics), and fix + signedness issues (#1449, #1565) + +* Use the OS’ `fdwalk()` function (if safe) to speed up `g_spawn_*()` on BSD (#1638) + +* Remove the macOS `dyld` `GModule` implementation in favour of `dl` instead (!1093) + +* Bump Python requirement to ≥ 3.5, which we implicitly relied on anyway through + our Meson dependency (!1132) + +* Bugs fixed: + - #35 add g_fsync to API + - #174 g_file_copy always preserves permissions, even if G_FILE_COPY_ALL_METADATA flag is not set + - #259 docs: fix a misunderstanding in g_type_add_interface_* + - #767 g_signal_lookup fails if class is not referenced + - #1052 g_io_write_chars calls abort when given a null byte as input + - #1449 glib fallback atomic int/ptr get/set have memory barrier in wrong place + - #1565 Signedness of atomic operations + - #1638 g_spawn_*() is extremely slow under certain circumstances + - #1809 Provide API for working with PKCS11 backed certificates + - #1843 TSAN false positive with g_atomic_pointer_get/g_atomic_pointer_set under Clang + - #1865 g_variant_get_data_as_bytes fails after serializing a variant + - #1875 Segfault and Overflow in __gio_xdg_cache_mime_type_subclass() with Wps-Office installed + - #1887 glib 2.62.0 breaks loading dylibs as modules + - #1888 2.62: docs build on Windows broken + - #1897 glib 2.62.0 fails test 'test_writev_no_vectors' wih gcc7 + - !1020 docs: Remove priv pointers from the tutorial example + - !1062 gtype: mark the inline functions in G_DECLARE_*_TYPE() as UNUSED + - !1080 tests: Fix skipping mkdir-with-parents-permission test + - !1088 Various small scan-build fixes + - !1090 giochannel: Clarify type of GSource callback in documentation + - !1093 gmodule: remove macOS dyld implementation + - !1095 Define G_IOV_MAX to 512 on macOS/iOS + - !1099 gmem: clarify that g_malloc always uses the system allocator + - !1109 doc: fix typo in gio/gsettings.c + - !1110 gio: Add missing "gio remove" option to bash completion script + - !1112 Add version macros for GLib 2.64 + - !1115 gdatetime: Fix error handling in g_date_time_new_ordinal() + - !1116 gmarkup: Add a limit on the number of attributes in an element + - !1119 Annotate the return value of various utility functions + - !1124 docs: Fix typo in GConverter{Input,Output}Stream section titles + - !1125 gdatetime: Fix error handling in g_date_time_new_week() + - !1126 fileinfo: Mention that usec mtimes are set + - !1129 gdate: Fix tautological comparison warnings on Android + - !1130 Improve GLIB_DEPRECATED_MACRO_FOR output + - !1131 gio/gfileinfo: fix param reference in doc comment + - !1132 build: Bump Python requirement to ≥ 3.5 + - !1137 gregistrysettings: bump key name length to 2048 + - !1138 Always build tests if we enabled installed-tests + - !1139 g_file_info_get_modification_date_time: Calculate in integer domain + +* Translation updates: + - Danish + - Italian + - Panjabi + - Serbian + - Turkish + + +Overview of changes in GLib 2.62.0 +================================== + +* Fix new `GFileInfo` APIs to work when `G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC` + was not queried (!1087) + +* Bugs fixed: + - #487 Add valgrind test runs to CI + - !1084 garray: Fix reference to GLIB_SIZEOF_INT + - !1086 glib.supp: make gobject_init() calloc also of the possible kind + - !1087 fileinfo: ignore USEC if not available + +* Translation updates: + - Friulian + - Portuguese (Brazil) + + +Overview of changes in GLib 2.61.3 +================================== + +* Support setting thread name on BSD systems (#1761) + +* Install previously-uninstalled headers for public `GNativeSocketAddress` + object (#1854) + +* Very initial support for Windows apps (UWP) (!1057) + +* Add various new valgrind suppressions to `glib.supp` (#1879, !1075) + +* Bugs fixed: + - #83 Optimisation for g_nearest_pow() in garray.c + - #512 GSignal: accumulator function not called to accumulate G_SIGNAL_RUN_CLEANUP object handler return values + - #873 allow NULL arguments to parse_strv + - #905 Patches from static analysis run on 2.40 + - #1057 goption: add sanity check to input parameters + - #1309 GSettings object stops emitting "changed" signal on g_settings_reset after call to g_settings_delay + - #1620 GDBus criticals from GVfs with GLib master + - #1761 Setting thread-name on BSD systems + - #1803 GDK_SCALE=X is not respected when using "gio open" + - #1819 Invalid characters in Open Location dialog crashes GIMP + - #1852 Regression: g_mkdir_with_parents() returns 0 on failure + - #1854 glib/gio: GNativeSocketAddress headers not installed. + - #1860 g_clear_handle_id does not trigger GLIB_VERSION_MAX_ALLOWED warning + - #1863 Potential invalid writes on g_utf8_strreverse + - #1867 A couple of en_GBisms + - #1870 GSettingsBackend watches not thread-safe + - #1879 Incomplete valgrind suppressions - 16 KiB leak reported by valgrind from loading libglib-2.0.so + - #1880 glib/gbacktrace.c: If dup2 happened to return -1, don't call dup2 with same value + - #1881 GIO_USE_VOLUME_MONITOR and GIO_USE_FILE_MONITOR do not work as documented + - !1002 Remove mentions of mailing lists from the documentation + - !1011 gapplication: Fix a leaking GRemoteActionGroup member + - !1015 Post-release version bump + - !1016 gnetworkmonitornm fixups + - !1017 Improve ISO 8601 parsing by GDateTime + - !1023 g_object_get_property: Improve documentation for use of G_VALUE_INIT + - !1026 gutf8: Assert that written memory stays in bounds + - !1027 gfileutils: Fix error propagation for other than ENOENT + - !1031 meson: build gnulib if printf isn't good enough + - !1032 meson: small printf check cleanups + - !1033 win32: don't assume the format specifier for the stdlib printf/scanf like functions + - !1034 glib/tests/fileutils: Add a reproducer for #1852 + - !1036 cond test: Don't make assumptions about struct sigaction member order + - !1037 Meson: Override glib-compile-resources/schemas + - !1044 Relax use of g_test_bug() to not require g_test_bug_base() to be called first + - !1049 minor typos in the documentation + - !1050 tests: Fix a pragma warning on FreeBSD + - !1054 gerror: Add a docs paragraph about not displaying errors verbatim in UI + - !1057 Some (probably) easy uwp patches + - !1059 Update win32 readme, add myself to codeowners + - !1066 libffi.wrap: Meson port has moved to FDO gitlab + - !1068 gsubprocesslauncher.c: fix documentation + - !1071 meson: Move libdl_dep to the top level + - !1074 Adjust README formatting + - !1075 glib.supp: add suppression for g_type_class_ref() + +* Translation updates: + - Basque + - Catalan + - Czech + - English (United Kingdom) + - French + - Galician + - German + - Hungarian + - Indonesian + - Korean + - Lithuanian + - Polish + - Romanian + - Spanish + - Swedish + + +Overview of changes in GLib 2.61.2 +================================== + +* Add various new array functions (#236, #269, #373) + - `g_array_copy()` + - `g_ptr_array_copy()` + - `g_ptr_array_extend()` + - `g_ptr_array_extend_and_steal()` + - `g_array_binary_search()` + +* Add `g_assert_finalize_object()` helper function for writing tests (#488) + +* Rework how D-Bus connections are closed/unreffed when `g_test_dbus_down()` is + called. Tests which leak a `GDBusConnection` may now time out and abort, + rather than silently leaking. (#787) + +* Add a deprecation macro for GLib macros, and use it; third-party uses of + long-deprecated GLib macros may now start causing warnings. (#1060) + +* Deprecate `GTime` and `GTimeVal`, and various functions which use them. + Use `GDateTime` and `guint64` UNIX timestamps instead. (#1438) + +* Stop using `G_DISABLE_DEPRECATED` to allow disabling deprecation warnings; + third-party code should now be using + `GLIB_VERSION_{MIN_REQUIRED, MAX_ALLOWED}` to control symbol usage (!871) + +* Improve support for running `ninja test` when GLib is built statically (#1648) + +* Improve `GNetworkMonitor` detection of offline states (#1788) + +* Fix build failure on macOS related to missing `_g_content_type_get_mime_dirs` + function (#1791) + +* Add various installed utilities’ paths to `gio-2.0.pc` (#1796) + +* Fix keyfile `GSettings` backend and portal (especially relevant to any version + of GLib included in a flatpak runtime) (#1822, !985) + +* More IPv6 ‘Happy Eyeballs’ fixes in `GNetworkAddress` (!865) + +* Fix CVE-2019-12450, wide permissions of files when copying using GIO (!876) + +* Bump the Meson dependency from 0.48.0 to 0.49.2; we won’t depend on anything + higher than this for a while, as Debian 10 ships 0.49 (!924) + +* Various test fixes for Windows (!930, !931) + +* Initial support for Universal Windows Platform (UWP): certification, and use + of packaged libraries (!951) + +* Add experimental clang-cl support on Windows, allowing `g_autoptr()` support + on Windows (!979) + +* Bugs fixed: + - #77 G_STDIO_NO_WRAP_ON_UNIX wraps + - #236 Add a function to copy an array + - #269 Additional convenience functions for g_ptr_array + - #373 GArray could use a binary search function + - #436 running tests leaves lots of coredumps + - #453 find-enclosing-mount docs confusing + - #488 Add g_object_assert_last_unref() helper macro to detect object leaks in tests + - #590 A reader lock can be obtained even if a writer is already waiting for a lock + - #638 g_atexit is defined when not declared + - #737 Initialize GValue in g_object_get_property() + - #787 gtestdbus: Properly close server connections + - #804 gdbusproxy prefixes unstripped error + - #870 Fix and enhance GDatetime for Windows + - #872 ucs4 functions have wrong return transfer + - #887 gdusmessage.c mishandles bounds of GDBusMessageType and related enums + - #894 gvalue: Avoid expensive checks where possible + - #940 Docs for g_socket_listener_set_backlog are not very helpful + - #943 G_DEFINE_TYPE_WITH_PRIVATE docs not helpful + - #1018 Allow guid key in dbus addresses + - #1060 Add deprecation macro for macros + - #1169 Tools can display gibberish messages from translations + - #1270 g_get_charset always returns 8-bit codepage on Windows, crippling UTF-8 output + - #1438 Deprecate GTimeVal- and GTime-based APIs + - #1635 g_socket_join_multicast_group iface parameter fails on win32/64 + - #1648 2.58.2: Assorted asserts fail in Arch Linux when built statically + - #1729 g_content_type_guess segfaults when passed an empty data buffer on Mac OS + - #1788 GNetworkMonitor claims I am offline + - #1790 documentation on g_file_info_get_attribute_as_string + - #1791 _g_content_type_get_mime_dirs missing from libgio-2.0.0.dylib on MacOS + - #1792 glib-genmarshal generated valist marshal does not respect static scope for some types + - #1793 glib-genmarshal generates wrong code for va marshaler for VARIANT type + - #1794 API Proposal: g_timer_is_active + - #1796 Add gio-querymodules variable to pkg-config file + - #1797 glib/tests/win32 test failing on 64-bit Visual Studio builds + - #1798 /contenttype/tree reliably fails on FreeBSD since !863 + - #1807 g_dbus_server_new_sync() documentation references nonexistent function + - #1808 Stopping a GDBusServer should clean up Unix socket paths (if not abstract) and nonce-tcp nonce files + - #1811 Introspection info for g_unichar_compose's 3rd arg should be OUT + - #1822 keyfile gsettings backend not loading + - #1823 Documentation for disabling selinux is incorrect + - #1825 GKeyFileSettingsBackend created without filename construct property and unchecked assertion + - #1828 Small typo in gio manpage + - #1837 Specify for each (optional) parameter, whether it is OUT or INOUT + - #1838 Reword documentation for G_DECLARE_FINAL_TYPE + - #1847 Setting GLIB_VERSION_{MIN_REQUIRED, MAX_ALLOWED} to before 2.56 triggers warnings + - !533 docs: Document pitfall of deprecation pragmas + - !563 ci: Add scan-build job in a new ‘analysis’ pipeline stage + - !678 glib-compile-schemas: Improve translatable strings + - !817 gdate: Officially mark GTime as deprecated + - !851 gsettings: Document that lists are returned in no defined order + - !853 gobject: Fix apostrophe usage in a few small bits of documentation + - !859 gobject: Add a g_assert_finalize_object() macro + - !863 gunicollate/cygwin: Don't use __STDC_ISO_10646__ for wchar_t related checks + - !865 gnetworkaddress: fix "happy eyeballs" logic + - !867 Post-release version bump + - !871 Drop G_DISABLE_DEPRECATED + - !873 Use atomic reference counting for GSource + - !874 Clamp number of vectors to IOV_MAX / UIO_MAXIOV for GOutputStream writev()... + - !875 CI/msys2: disable coverage reporting, lcov doesn't support gcc9 yet + - !876 CVE-2019-12450: gfile: Limit access to files when copying + - !877 gio: specify proper c_marshaller and va_marshallers + - !883 tests: Fix small race in GSubprocess tests + - !884 garcbox.c: Fix typo atomit => atomic + - !885 goption: Clarify G_OPTION_ARG_FILENAME documentation + - !889 Include for FIONREAD + - !901 gmain: Clarify that g_source_destroy() doesn’t drop a reference + - !904 Add glib-genmarshal tests and fix some valist marshaller bugs + - !906 property action: Add state hints + - !908 Improve testfilemonitor test repeatability and debuggability + - !909 D-Bus auth mechanism improvements + - !914 ci: Run scan-build in a different build directory + - !915 docs: fix typo on arrays examples in gvariant-text + - !917 docs: Fix name of IRC channel in CONTRIBUTING.md + - !919 glib/tests/refcount.c: Fix tests on non-GCC-isque compilers + - !920 gmacros: Only use deprecated attributes on enumerators with GCC ≥ 6.5 + - !923 Check if compiler symbols are defined before using them + - !924 Bump the required version of Meson + - !930 glib/tests/convert.c: Skip tests that aren't meaningful for Windows + - !931 glib/tests/fileutils.c: Fix stdio Wrapper Test on Windows + - !934 build: Increase the slow test timeout to 180s + - !935 Ignore */__pycache__/* directories + - !937 Fix module tests on Visual Studio builds + - !939 gstdio: minor cleanups + - !941 list model: Expand items-changed docs + - !944 gutils: Don't limit the length of the host name to 99 + - !945 Avoid overrunning stack at the end of the varargs. + - !947 gobject/tests/signals.c: Fix tests on Windows + - !948 GObject: Fix mkenums.py and genmarshal.py tests on Windows + - !950 ci: Enable CI on FreeBSD 12 + - !951 Preliminary patches for Universal Windows Platform support + - !952 gio: Make minor docs improvements + - !953 g_utf8_normalize: Doc comment return missing nullable annotation + - !954 Fix the ISO 15924 code for Manichaean + - !955 gmacros: Use _Static_assert when C11 is available + - !958 gthread: fix minor errno problem in GCond + - !961 gmain: Fix g_main_context_prepare priority annotation + - !962 gmacros: Use _Static_assert only for non-expr static assert + - !964 gmacros.h: Use static_assert on MSVC if possible + - !968 Fix typo in request handle + - !970 gdatetime: Unset LC_ALL for the test as well + - !971 docs.c: Forward link from g_auto* → G_DEFINE_AUTO* + - !973 doc: fix typo in gio/gresource.c + - !979 Experimental clang-cl support + - !980 gmacros.h: Add better support for clang-cl + - !981 gio: fix typo in g_settings_reset documentation + - !982 Various doc fixes + - !985 Keyfile portal fixes + - !987 gio/tests: Remove code and comments referring to libtool + - !991 fix atomic detection on older gcc versions + - !992 docs: Add example to g_test_summary() documentation + - !994 gio: Fix minor docs mistakes + - !996 Small array test fixes + - !997 gdbusaddress: Add missing transfer annotation + - !1007 Resubmission of !832 “Try to create the complete path right away and fall back†+ - !1009 gapplication: remove inactivity_timeout source on finalize + +* Translation updates: + - Hungarian + - Indonesian + - Portuguese (Brazil) + - Spanish + + +Overview of changes in GLib 2.61.1 +================================== + +* `g_unichar_isxdigit()` and `g_unichar_xdigit_value()` now handle full-width + characters (U+FF21–U+FF26 and U+FF41–U+FF46) (#58) + +* Deprecate `gtester` utility and its test reporting format and enable TAP + output by default instead — the `--tap` option to tests is now a no-op + (#1441, #1619) + +* Add `g_test_summary()` to allow test authors to programmatically summarise + what each unit test in a test suite does (#1450) + +* Upgrade to Unicode Character Database v12.1 (#1713, !822) + +* More IPv6 Happy Eyeballs fixes to `GNetworkAddress` and `GSocketClient` + (#1747, #1771, #1774) + +* Fix valgrind and gdb support for the new `GHashTable` changes (#1749, #1780) + +* Fix GTask wait times growing faster than the number of task threads (#1683) + +* Change `GApplication` to ignore `-psn_*` arguments on the macOS command line, + as they are irrelevant (#1784) + +* Add `g_autoqueue()` helper macros, similar to `g_autolist()` (!474) + +* Add pre-allocated link helpers for `GList` and `GQueue`: + - `g_list_insert_before_link()` + - `g_queue_insert_before_link()` + - `g_queue_insert_after_link()` + +* Improve network availability detection with NetworkManager to treat lower + levels of connectivity as having reduced availability (!781) + +* Add `g_clear_signal_handler()` to allow disconnecting from a `GObject` signal + and clearing the signal handler ID to zero in a single call (!819) + +* Add `g_autoptr()` support for `GRWLock` (!825) + +* Define `G_OS_UNIX`, not `G_OS_WIN32`, when GLib is built agains Cygwin (!862) + +* Bugs fixed: + - #29 GScanner: should explicitly document modifiable fields (value, next_value, ...) + - #58 g_unichar_isxdigit() and g_unichar_xdigit_value() should deal with full-width a-fA-F + - #106 Boxed types should be documented better + - #135 g_unichar_totitle(0) returns 0x00001F88 instead of 0 + - #429 g_format_size() is broken on Windows + - #1441 Deprecate gtester + - #1450 Add API for tests to describe what they're checking + - #1619 GTest should have a way to default to TAP + - #1683 GTask: task_wait_time is increased constantly when the number of running thread is greather than 10 + - #1713 Upgrade to Unicode Character Database v12 + - #1739 meson build failure libdl + - #1747 Critical in g_socket_client_async_connect_complete + - #1749 New GHashTable implementation confuses valgrind + - #1753 Remove memory leaks from gio/test/resolver.c + - #1755 Please revert #535 gmacros: Try to use the standard __func__ first in G_STRFUNC + - #1759 test_month_names: assertion failed + - #1760 Document for g_resolver_lookup_records why it returns a list of list of gchar*. + - #1763 tests: -p runs tests in the reverse of the specified order + - #1768 g_strlcat(): Possible buffer overflow in implementation + - #1771 GNetworkAddressAddressEnumerator unsafely modifies cache in GNetworkAddress + - #1774 Leaks in gsocketclient.c connection code + - #1776 glib/date test fails + - #1780 GDB pretty-printer for GHashTable no longer works + - #1782 Error in documentation for cross-compile. + - #1784 MacOS adds a -psn_X_XXXXXX parameter to the command line + - !474 Add g_autoqueue + - !476 Add pre-allocated link helpers for GList and GQueue + - !556 gtestutils: Make --tap compatible with -p and --GTestSkipCount + - !732 gsocket: Clarify in docs that `flags` arguments can be platform specific + - !766 W32: swap special g_get_prgname() for platform_get_argv0() + - !774 Only build tests if certain conditions are met. + - !780 Add copyright and licensing terms to test report generator + - !781 gnetworkmonitornm: Fix network available detection + - !782 build: Fix check for RTLD_NEXT + - !785 Remove monitor test + - !787 build: Remove */.gitignore files + - !791 glib/gconstructor.h: Include stdlib.h for MSVC builds + - !792 general: Remove a few unhelpful references to ‘master’ + - !795 gdesktopappinfo: Add support for MATE and Xfce4 terminals + - !802 gio: tests, don't check for libdl on OpenBSD + - !806 Get to 100% coverage on GQueue tests + - !808 Update the Docker images used for CI + - !809 Modified version of !784 — Adding tests cases for a better coverage of glib/tests/strfuncs.c + - !813 gappinfo: Add precondition checks to GAppLaunchContext env methods + - !814 gschema.dtd: Add target attribute to alias + - !819 Clear signal handler + - !820 ci: Keep JUnit report script working on Debian stable + - !821 Various minor cleanups to autoptrs + - !822 glib: Update Unicode Character Database to version 12.1.0 + - !825 Add autoptr support for GRWLock + - !831 build: (Long time after) post-release version bump + - !835 Fix typo in German translation + - !836 Document the best practices for binding GInitiallyUnowned + - !862 build: define G_OS_UNIX, not G_OS_WIN32 under cygwin + +* Translation updates: + - Basque + - Catalan + - German + - Indonesian + - Spanish + + +Overview of changes in GLib 2.61.0 +================================== + +* Changes to `iconv` configure options, including the default iconv + implementation on macOS — distributors may need to check their configure + scripts (#1557) + +* Build fixes when building GLib with `G_DISABLE_ASSERT` defined (#1708) + +* Fix documentation for `gdbus-tool wait` to use correct units (#1737) + +* Improvements to symlink handling on Windows (!269) + +* Add exception handling for crashes on Windows (!582) + +* Set `G_WITH_CYGWIN` again when GLib is built on Cygwin (this was a regression + from the autotools build) (!736) + +* Use `GCocoaNotificationBackend` by default on macOS, rather than + `GGtkNotificationBackend` (!745) + +* Use Windows symbol visibility when GLib is built on Cygwin, as PE binaries + are subject to W32 visibility mechanics — this affects the definition of + `_GLIB_EXTERN` (!752) + +* Add coloured output support to `gdbus introspect` (!761) + +* Bugs fixed: + - #682 docs: advise not to use non-literal strings as qdata keys + - #1177 gparted crashes due to g_quark_from_static_string used in global initialization + - #1258 the buffer written to by g_input_stream_read is not marked as an out parameter + - #1557 By default glib tries to use libc instead of native iconv on OSX + - #1566 Meld Windows shows error on startup "There was a problem starting c:\Program" + - #1614 GIO tests fail on FreeBSD CI with: Unexpected error from C library during 'pthread_mutex_lock': Invalid argument + - #1708 Building GLib with G_DISABLE_ASSERT fails + - #1709 GResource generation test incompatible with stable LLVM on Linux + - #1710 Crash in g_cancellable_cancel + - #1712 gdbus-proxy test is flaky + - #1724 unconditional check in fuzzing/meson.build + - #1725 gosxappinfo.h is not installed on macOS + - #1727 Cannot use trash folder with an NFS mount using automount / autofs + - #1728 GSocket does not support ENOTSOCK + - #1732 Win32: lookup_by_name_async segfaults for not available domains + - #1737 gdbus-tool wait command timeout argument incorrect unit reference + - !67 glib: update internal gnulib from upstream + - !269 Win32 symlink code refactoring + - !493 tests: Check that cancelling g_file_replace don't overwrite existing file + - !582 Basic W32 exception handling for glib + - !680 Fix warnings glib + - !690 Fix thread safety issues + - !694 gvariant-parser: Fix pattern coalesce of M and * + - !706 Fix data races in task test and gmenumodel test + - !709 Bump release version for 2.62 series + - !710 socket: Fix annotation for flags in g_socket_receive_message + - !712 gwin32: Fix comment for g_win32_veh_handler + - !716 Various minor documentation fixes + - !717 Improve formatting of GCC attribute documentation + - !718 GSocketClient - Free last error if a connection attempt fails and on retry the... + - !719 Handle an UNKNOWN NetworkManager connectivity as NONE + - !721 codegen: Fix use of uninitialised variable + - !723 Provide examples for GNUC attribute macros + - !724 meson: do a build-time check for strlcpy before attempting runtime check + - !728 gsocket: Remove (type) annotation from flags arguments + - !730 Improve gdbus-address parsing tests + - !735 docs: Use the right g_autoptr function when using an auxiliary function + - !736 Set G_WITH_CYGWIN again + - !737 gresolver: Don’t use gai_strerror() on Windows, as it isn’t threadsafe + - !741 Fix use-after-free triggered by gnome-session-binary + - !745 gcocoanotificationbackend: give more priority than the gtk one + - !749 gio: Add missing autocleanup definition for GSettingsSchema{Key,Source} + - !750 Check for RTLD_NEXT + - !752 Use W32 visibility for Cygwin + - !754 Check for /proc/self/cmdline + - !757 Fix gnulib build on older Visual Studio builds + - !760 Properly ensure the cocoa notification backend type + - !761 RFC: gdbus-tool: Add --color option for introspect + - !762 gutils: Add (nullable) annotation to g_get_prgname() + - !765 gslice: Use a convenience macro + - !769 ci: Generate a cover report for the test suite + - !772 tests: Check that option-argv0 test succeeds on Linux + - !776 tests: Only run --external-data test on GNU ld/objcopy + - !779 Fix 2.62 documentation symbols + +* Translation updates: + - Dutch + + +Overview of changes in GLib 2.60.0 +================================== + +* Further fixes to the Happy Eyeballs (RFC 8305) implementation (#1653, #1679, #1693) + +* Add support for the XDG trash portal (#1676, !276) + +* Bugs fixed: + - #1653 gsocketclient-slow test is flaky + - #1658 keyfile settings backend: Consider tightening permissions + - #1668 Fill in CODE-OWNERS file + - #1675 glib-compile-resources: c_name generation issue + - #1676 Trash portal tries to open files as read-only but D-Bus API documents against that + - #1679 socket-service test is flaky + - #1693 Happy Eyeballs failure in gsocketclient-slow test + - #1697 gthreadresolver: do_lookup_records does res_ninit with an uninitialized state + - #1698 g_base64_encode(NULL, 0) causes critical warnings + - !276 Support the trash portal + - !639 gvariant-parser: Fix error handling when type coalescing fails + - !666 Socket fixes to W32 test suite + - !674 Update gvdb submodule + - !676 Initialize a variable + - !677 gerror: Add a missing precondition assertion in documentation + - !686 gio: Also support modules built with MSVC + - !688 gsocketclient: Fix critical on cancellation + - !689 glib-compile-resources: Fix a minor leak + - !691 gtask: Separate GTask fields memory locations to avoid data races + - !692 glib.supp: Add more variations of existing suppressions + - !696 Move closures refcount test to gobject/tests/ + - !698 gthreadedresolver: Remove unused thread pool + - !699 tests: Fix closure-refcount to preserve old semantics + - !702 Rename gobjectenumtypes.[ch] to glib-enumtypes.[ch] + - !703 Clean up gmarshal.[ch] + +* Translation updates: + - Catalan + - Czech + - French + - Friulian + - German + - Italian + - Korean + - Romanian + - Serbian + + +Overview of changes in GLib 2.59.3 +================================== + +* Fix support for g_get_user_special_dir() on macOS, including support for the Downloads directory (#1048) + +* Ensure that cancelling a GTask cannot cause its callback to be called synchronously (in the same call chain as the original *_async() call) (#1608) + +* Further fixes to the Happy Eyeballs (RFC 8305) implementation (#1644, #1680) + +* Various fixes for installation of installed tests (thanks to Iain Lane) (!649, !651) + +* Various fixes for tests when run on Windows (thanks to LRN) (!665, !667) + +* Bugs fixed: + - #535 gmacros: Try to use the standard __func__ first in G_STRFUNC + - #875 gio-gvfs on Windows: Don't mishandle other non-native URIs in gwinhttpvfs.c + - #1048 "Desktop" shortcut appears twice in file chooser sidebar on OSX + - #1608 Cancellation might not be asynchronous under certain circumstances + - #1644 network-address test failure in CI: IPv6 Broken (g-io-error-quark, 24) + - #1680 Regression: g_socket_client_connect_to_host_async() sometimes gets "Connection refused" when connecting to localhost + - #1686 gdbus-peer test is sometimes timing out + - !613 Use win32 io channel on windows for the protocol test + - !634 Win32: gio/gsocket.c: Set WSAEWOULDBLOCK on G_POLLABLE_RETURN_WOULD_BLOCK + - !638 gvariant-parser: Fix parsing of G_MININT* values in GVariant text format + - !640 tests: Tag socket-service test as ‘flaky’ + - !641 Minor typo fixes to GSpawn documentation + - !645 gsocketlistener: Fix multiple returns of GTask when accepting sockets + - !647 gsocketclient: Ensure task is always returned on cancel + - !648 gio/tests/task: Run the worker indefinitely until it's cancelled + - !649 gio tests: Install test1.overlay file when building installed tests + - !650 gstring: fully document semantics of @len for g_string_insert_len + - !651 tests: Install the slow-connect-preload.so library and use it + - !667 GSubprocess fixes for W32 test suite + - !668 tests: Mark gdbus-peer test as flaky + - !669 GWin32VolumeMonitor: Sort the volumes correctly + - !670 gpollableoutputstream: Fix the description of the interface + - !672 Fix some tests when running as root + +* Translation updates: + - Catalan + - Danish + - French + - Indonesian + - Kazakh + - Portuguese (Brazil) + - Slovenian + - Turkish + + +Overview of changes in GLib 2.59.2 +================================== + +* Fix check on GDBusMessage size when reading it. (#1642) + +* Add async GIO API: g_file_query_default_handler_async(), g_app_info_launch_uris_async() (#1249, #1347) + +* Fix some bugs in the Happy Eyeballs implementation. (#1646, #1649) + +* Install a new generated header with enum types for Unicode enums. (!481) + +* Support the XDG trash portal. (!276) + +* Bugs fixed: + - #1224 TSAN patches + - #1249 xdg-open/gnome-open doesn't work if service isn't started + - #1347 g_app_info_launch_default_for_uri_async is not really async + - #1376 gmarkup: Optimize g_markup_escape_text() + - #1642 minor mismatch between error and code in g_dbus_message_bytes_needed + - #1646 Criticals in g_socket_client_enumerator_callback() + - #1649 Critical in g_socket_client_connected_callback + - #1673 G_MININT constants broken in g-i + - !276 Support the trash portal + - !481 Define enum types for Unicode enums + - !585 gio: do not pass O_PATH file descriptors to portal APIs + - !593 Don't fail trash test if ~/.local doesn't exist or mount points can't be determined (master) + - !609 Make `g_app_info_launch_uris_async()` really asynchronous + - !619 gvariant: Fix a mistake in docs + - !622 Fixing warnings + - !626 gdbus: Avoid printing null strings + - !627 gsocketclient: Fix criticals + - !629 Various memory leak cleanups to GSettings tests (subset) + - !630 docs: Ignore more version macros + +* Translation updates: + - Galician + - Hungarian + - Lithuanian + - Polish + - Spanish + + +Overview of changes in GLib 2.59.1 +================================== + +* Autotools support is gone. (!580) + +* g_format_size() now uses a no-break space to separate digits and units; + translations will need to be updated accordingly. (#1625) + +* New g_queue_clear_full() API. (#1464) + +* Fix argument quoting on win32 when spawning subprocesses. (!419) + +* Allow polling more than 64 handles on win32 using g_poll(). (#1071) + +* Tag various tests as ‘flaky’. These are no longer run routinely on our + upstream CI machines, and downstream packagers may want to not run them (or + not treat those test failures as package build failures) on their test + machines either. They are in the `flaky` test suite. (!579) + +* Add overlay support to g_resources_get_info(). (#1445) + +* Support defaults and locks in the keyfile GSettings backend. This will be + used for flatpaks. (!450) + +* Accept unquoted strings in the keyfile GSettings backend to simplify things + for sysadmins. (!603) + +* Update our contribution guidelines (`CONTRIBUTING.md`). (!590) + +* Add writev() and writev_all() APIs to GOutputStream and GPollableOutputStream, + and provide implementations of them for many subclasses. (#1431) + +* Bugs fixed: + - #424 Add 'proxy' debugging support + - #1055 Provide alignment macros + - #1071 Eliminate MAXIMUM_WAIT_OBJECTS limitation in g_poll() on Windows + - #1445 g_resources_get_info doesn't respect resource overlays + - #1464 Add g_queue_clear_full() API + - #1500 GListStore needs double checking on some warnings + - #1623 xdg-open: file with colon results in “The specified location is not supported†+ - #1625 Unbreakable space needed when showing size of folder/file + - #1636 GTask getters don’t return TRUE/FALSE after bitfield changes + - #1637 EXCEPTION_ACCESS_VIOLATION in g_clear_pointer + - #1639 GListStore implementation of g_list_model_get_item() returns wrong results on integer overflow + - #1655 gvariant-parser warnings + - #1663 G_MININT32 triggers compiler warning C4146 with Visual C++ + - #1666 `G_DEFINE_DYNAMIC_TYPE_EXTENDED` causes warnings with -Wcast-function-type + - !319 giomodule: Print the type of each default GIO module + - !333 Add writev() API to GOutputStream and GPollableOutputStream + - !419 gspawn, win32: qouted args - escape end backslash + - !450 Settings portal + - !512 gtype: Clarify type of GInterfaceInitFunc + - !516 gthread: Add g_private_set_alloc0() convenience API + - !535 win32 gpoll: overcome the 64 handles limit + - !545 goption: Fix an annotation on g_option_context_parse_strv() + - !560 docs: Fix dconf GSETTINGS_BACKEND name in gio overview + - !564 gtype: Document type for iface_default_init() function + - !568 Add separate definitions of g_assert_[non]null() for C++ + - !571 docs: Add note on how to check a gboolean condition + - !575 gio: Update bad cert error in accept-certificate and GTlsError docs + - !579 Temporarily disable flaky tests + - !580 Drop autotools support + - !583 gmacros: MSVC supports the noreturn function attribute + - !587 Remove unused .pc.in files + - !588 MSVC: Move dirent implementation to glib/dirent/ + - !590 Update contribution documentation + - !591 gfileinfo: Fix annotation for g_file_info_set_attribute_stringv + - !592 Remove leftover build/ directory + - !595 gtestutils: pass open file descriptors to subprocess + - !597 tests: Tag gsocketclient-slow test as ‘flaky’ + - !598 gdbus-proxy test fails with GLib-GIO:ERROR:glib/gio/tests/gdbus-proxy.c:832:fail_test: code should not be reached + - !599 gdtlsconnection: do not return on a void method + - !601 gio: Support "help" in extension point env vars + - !602 Update POTFILES.in + - !603 keyfile settings: Accept unquoted strings + - !608 build: Add -Wno-pedantic flag to compiler arguments + - !611 gnetworkaddress: fix use-after-free for network address + - !612 gdir: shutup a warning when building with msvc + - !615 Fix a couple of wrong compiler warnings + +* Translation updates: + - Spanish + - Swedish + + +Overview of changes in GLib 2.59.0 +================================== + +* This will be the last development release with autotools support. As our + Meson support has been around since 2.56.x, and was used to release tarballs + in 2.58.x, the next development release (2.59.1) will drop autotools as used + to build GLib. The macros installed for other packages to use will remain. + +* Add `G_TEST_OPTION_ISOLATE_DIRS` to redirect `XDG_*_HOME` to a temporary + directory for each unit test. (#538) + +* Support `Property.EmitsChangedSignal` annotations in `gdbus-codegen`. (#542) + +* Add `g_assert_cmpvariant()` API for unit tests. (#1191) + +* Hide bind mounts from GIO mount listings. (#1271) + +* Automatically realign data passed to `g_variant_new_from_bytes()` or + `g_variant_new_from_data()` if it is not correctly aligned. This prevents + misaligned accesses on architectures which don’t support them. Callers should + still aim to correctly align data to get higher performance. (#1342) + +* Support `ld -b binary` (on platforms which support it; i.e. Linux) to provide + large pre-compiled `GResource` resources with a fast compilation time. (#1489) + +* Unconditionally install GLib m4 macros, so that projects which depend on GLib + and which still build using autotools can continue to build even once GLib has + ported entirely to Meson. (#1520) + +* Various fixes to the Meson build. + +* Drop Python 2 support and require Python 3.4+. See discussion on + https://mail.gnome.org/archives/desktop-devel-list/2018-July/msg00004.html. + (!196) + +* `GHashTable` performance and memory improvements for common cases. See + https://hpjansson.org/blag/2018/07/24/a-hash-table-re-hash/. (!208) + +* Add flags that allow a `GApplication` to signal and replace a currently + running other instance of the same `GApplication`. This will be used for app + upgrades with flatpak. (!250) + +* Autostart xdg-desktop-portal when using the network monitor and proxy monitor + portal backends. (!317) + +* Add a g_task_set_name() API to allow `GTask`s to be described; useful for + debugging. (!384) + +* Enable FreeBSD CI on every commit for upstream GLib. (!387) + +* Various GVariant, GMarkup and GDBus fuzzing fixes, including buffer overflow + fixes. (!411) + +* Various fixes to eliminate thread races, found by thread sanitizer (tsan). + +* Deprecate TLS/DTLS rehandshaking, as it has been removed from the protocol in + TLS 1.3. (!478) + +* Support reading arguments from a file with `glib-mkenums`, which is useful + for long argument lists due to having deeply nested build directories, on + systems with a low limit on the command line length. (!489) + +* Make `g_environ_*()` case-insensitive on Windows, as the environment itself + is case-insensitive on Windows. (!500) + +* Add Application Layer Protocol Negotiation (ALPN) support to `GTlsConnection` + and `GDtlsConnection`, so that higher layer protocols can be negotiated when + setting up a TLS connection, without additional round trips and latency. This + is needed for eventual HTTP/2 support. (!520) + +* Add support for TPM keys in PEM files when loading TLS certificates. (!522) + +* Add a `GRecMutexLocker` auto-pointer wrapper for `GRecMutex`. (!528) + +* Bugs fixed: + - #107 The "g_key_file_get_comment" interface returns comment with unexpected new line symbol at the end + - #179 g_object_unref assert in debug code + - #277 'destroy_data' in g_cclosure_new is registered as finalize notifier instread invalidate. + - #538 Add helpers to redirect XDG_*_HOME to a temp dir for unit tests + - #542 gdbus-codegen does not honor "Property.EmitsChangedSignal" annotations + - #656 check for -Werror=format-security broken + - #734 Provide a way to instantiate a GDBusProxy-derived class from a GDBusConnection and a object path without blocking + - #827 gmain: Clarify that g_source_set_callback() is safe on attached sources + - #1055 Provide alignment macros + - #1119 GVolumeMonitor: Results don't reflect current state but state when application was launched + - #1191 add g_assert_equal_variants + - #1261 Add option to leave in gschema empty + - #1271 fstab binds appear as mounts (x-gvfs-hide is being ignored) + - #1310 gdbusproxy: make g-name-owner property useful with unique names + - #1313 Meson: Rework the config.h generation + - #1342 Automatically realign data passed to g_variant_new_from_bytes() or g_variant_new_from_data() + - #1343 g_date_set_parse: Parses "September" in Polish incorrectly + - #1362 Incorrect documentation about GSettings child add/remove notifications + - #1452 GFileInfo: unable to retrieve correct modification time of links and mounted volumes on Windows + - #1471 Incorporate oss-fuzz fuzz targets into GLib + - #1489 Use `ld -b binary` to speed up GResource generation for linking + - #1498 distcheck fails in distclean + - #1506 error: redefinition of typedef 'GKqueueFileMonitor' + - #1509 test_timeval_to_iso8601_overflow: 'out' should be NULL + - #1513 GIcon regression? + - #1514 gio/appinfo test sometimes fails in CI + - #1518 /network-monitor/create-in-thread fails in (LXC) containers on glib-2-56 + - #1520 Change conditions for installing m4 macros + - #1522 Trash not working on NTFS folder accessed from symlink + - #1523 GIO NetworkMonitor doesn't reflect the current network state + - #1525 GTask allows (buggy) application code to cause callback to be called twice, without warning + - #1527 Meson doesn't install data for installed-tests + - #1528 Meson tests are hard to debug in an autobuilder environment + - #1530 tests/mainloop-test appears to be flaky + - #1535 meson: installed-test metadata not run in TAP mode + - #1536 meson: spurious dependencies on convenience libraries in .pc files + - #1537 meson: absolute paths to ${builddir} included in gtk-doc HTML + - #1538 meson: G_HAVE_GROWING_STACK defined differently + - #1539 meson: Some files are unnecessarily installed executable + - #1541 meson: timeloop-closure test not installed + - #1542 meson: /usr/lib/glib2.0/installed-tests/glib/gdbus-peer: error while loading shared libraries: libgdbus-example-objectmanager.so: cannot open shared object file: No such file or directory + - #1544 meson: gtester-report #! not replaced with ${PYTHON} + - #1546 Cross-compilation fails in 2.58 + - #1556 build: Too long file path issue with meson on Windows + - #1562 GDate test suite fails with latest glibc + - #1570 ghash.c:694:27: left shift of 1 by 31 places cannot be represented in type 'int' + - #1572 Flags validation fails + - #1575 g_date_time_format() should have format attribute + - #1576 Fails to build with Meson on Debian armel (armv5te EABI softfloat little-endian) + - #1580 glib-compile-resources using strings breaks building e.g. GTK+ on MS Visual C, which limits strings to 65535 chars + - #1581 Memory used for reference counted data might be misaligned. + - #1588 Moving a bookmark item to the same URI causes a crash + - #1589 g_log_writer_is_journald memoizes a single result, even though it accepts a parameter + - #1590 tests: g-file-info-filesystem-readonly fails if run more than once with fuse & bindfs installed + - #1594 Return value of g_dbus_connection_get_unique_name not annotated as nullable + - #1600 g_timeout_source_new_seconds overflows when given interval > (G_MAXUINT / 1000) + - #1601 appinfo test fix is defective + - #1605 g_date_time_format fails when used with non ASCII format string on POSIX locale + - #1615 gdbus-codegen not generating nullable annotation + - !196 [RFC] build: Drop Python 2 support and require Python 3.4+ + - !200 Add a new GTlsError to indicate protocol downgrade attacks + - !208 GHashTable improvements + - !219 glocalfilemonitor: Fallback to poll file monitor for NFS + - !238 W32 GFileInfo improvements + - !250 Application replace + - !264 glib-compile-resources: encode data as string + - !268 build: simplify alloca checks. See #1313 + - !272 dtrace: Add missing const attributes to types in glib_probes.d + - !273 gtlsbackend: add support for setting the default TLS database + - !277 Use "command -v" instead of "which" + - !282 meson: Add macOS libtool versioning for ABI compatibility + - !286 gspawn: Fix build on systems without O_CLOEXEC + - !287 glib-compile-resources: Fix generated code compiling with C++ compilers + - !289 tests: Add more tests to finish branch coverage of GHashTable + - !290 build: fix installation dir of glib-gettextize + - !292 Remove all ChangeLog files + - !293 Document new volume class `loop` + - !294 portal network monitor: Always emit changed signal on changed + - !295 meson: fix typo + - !296 Add G_GNUC_FALLTHROUGH for __attribute__(fallthrough)) + - !297 build: Drop AC_C_CONST from configure.ac + - !302 Document that GTimeVal is subject to the year 2038 problem on 32-bit systems + - !303 liststore: Simplify code + - !304 Add more GListStore/GListModel tests + - !309 codegen: Change pointer casting to remove type-punning warnings + - !312 Enable GIO tests on Windows + - !316 gdbus: Improve error when well-known name is unowned + - !317 Autostart xdg-desktop-portal if needed + - !322 gnetworkmonitornm: Set a GError properly on an error handling path + - !332 gmarkup: Make the documentation even more explicit about untrusted input + - !334 gio: automake: Add libgmodule dependency + - !338 gcharset: fix leaking g_get_language_names_with_category + - !339 Add g_desktop_app_info_get_string_list(); fix g_key_file_free() + - !340 tests: Mark two more tests as slow + - !345 Fix build failure on systems without POSIX spawn + - !347 Use Meson 0.48.0 for CI + - !348 Documentation tweaks for g_array_free + - !353 Meson: Do not run tests/refcount with --tap + - !354 Fix spelling mistakes detected by Debian's Lintian tool + - !358 Autotools: Move libmount from Libs.private to Requires.private + - !360 CI: Test static build on installed glib + - !363 Tests: Mark printf wrappers with G_GNUC_PRINTF + - !364 ci: Enable FreeBSD CI + - !366 gunixmounts: Mark mounts as system internal instead of filtering out + - !372 gmacros: Fix G_[UN]LIKELY to not mask -Wparentheses + - !374 gthreadpool: Include prgname in thread name + - !375 m4macros: Allow information from pkg-config to be overridden + - !376 gthread: Clarify priority handling in GRWLock + - !379 Ignore g_return_*if_fail() branches in lcov coverage report + - !381 Add UTF-8 communication tests for GSubprocess + - !384 gtask: Add a g_task_set_name() method + - !387 ci: Enable FreeBSD CI in the official repository + - !396 m4: Fix AM_PATH_GLIB_2_0 macro + - !400 grefcount: add missing gatomic.h + - !403 build-sys: Pass CFLAGS to $(DTRACE) + - !405 ci/msys2: fix path to the lcov config file + - !406 meson: Mark 1bit-emufutex test as slow + - !407 meson: Increase test timeouts + - !410 gfileutils: Add examples to g_path_get_dirname() documentation + - !411 Various GVariant, GMarkup and GDBus fuzzing fixes + - !412 Enable compile time check of g_date_time_format() format + - !413 Add support for g_auto(s)list to G_DECLARE'd types + - !414 gio, tests: ensure objectmanager sources are generated + - !415 gseekable: fix 'attmepting' typo + - !416 gdbus-peer: Make sure to not include objectmanager-gen.c source + - !417 Fix ^*ay handling in g_variant_iter_loop() + - !418 Meson: Cleanup a FIXME now that we have dict addition + - !420 gdbus-codegen: add autocleanup for FooObject + - !422 GMarkup buffer overflow fixes for error handling, round 2 + - !423 gutils: Check whether getauxval function exists + - !424 ci: Fix Docker image version + - !425 gdate: Reinitialize using_twodigit_years and locale_era_adjust. + - !435 gdatetime: Fix formatting of time zones offsets in range -01:00 to +00:00 + - !436 valgrind: Add glib_init()-related suppressions + - !440 Fix minor memory leaks in tests + - !443 tests: Avoid multithreaded use of g_test_rand_int_range + - !444 gvarianttypeinfo: Consistently use atomics to access ref_count + - !446 gmain: Fix data races in GUnixSignalWatchSource and GChildWatchSource + - !451 closures test: Avoid timeout on ARM64 CPUs + - !452 Atomic reference count in GVariant, ContainerInfo and GDBus introspection + - !453 tests: Fix some data races in tests + - !454 gdbusproxy: make g-name-owner property useful with unique names + - !458 glib-compile-resources: Fix size allocation for compressed streams + - !460 gatomicrefcount: Make g_atomic_ref_count_init non-atomic + - !461 Meson: Fix build error in gdbus-example-objectmanager + - !462 meson: add aarch64 memory barrier handling + - !463 gio, tests: fix leak of dbus connection. + - !467 Update documentation of g_tls_connection_handshake() again + - !469 docs: add index of new symbols for gio > 2.52 + - !470 docs: Clarify return/error behaviour of D-Bus signal subscriptions + - !472 gdbusmessage: Gracefully handle message signatures with invalid types + - !477 gthread: Remove unsynchronized access to g_once_init_list from assertion + - !478 Deprecate TLS rehandshaking + - !480 docs: add a missing semicolon + - !482 Check for 'z' library before fallbacking to subproject + - !483 meson: Turn selinux into a meson feature and make it auto by default + - !484 Meson: Add 'nls' option to disable translation + - !485 gdbus-codegen: Tag interfaces and properties so annotated with G_PARAM_DEPRECATED + - !486 Check for zlib header + - !489 glib-mkenums: Support reading @rspfiles for arguments + - !490 gspawn: Fix g_spawn deadlock in a multi-threaded program on Linux + - !491 Meson: Add missing include_directories when using glib as subproject + - !492 g_value_get_variant: return value is transfer-none not transfer-full + - !494 Resolve "Follow-up from "gunixmounts: Stop considering cifs/nfs as system file systems"" + - !500 genviron: make g_environ_* case-insensitive on Windows + - !504 tests: Unset LANGUAGE when running gdatetime tests + - !505 Support isolating directories for unit tests + - !508 ci: Install additional locales used during tests + - !510 Add new Linux Testing project version number to configure script + - !511 gvariant: Fix error handling for parsing Unicode escapes + - !514 fix gdbus-codegen --interface-info-{header,body} + - !515 binding: Clarify the use of g_object_unref() to remove a binding + - !517 Meson: Fix deprecation warning with upcoming 0.49.0 release + - !518 Meson: Fix declare_dependency() calls + - !520 GTlsConnection: add ALPN support + - !521 tests: Rename macro to avoid conflict with encoding prefix + - !522 gtlscertificate: Add support for TPM keys in PEM files + - !524 gdatetime: Fix typo in the comment + - !528 Add GRecMutexLocker + - !530 tests: Minor improvements to mkenums.py and taptestrunner.py used by it + - !534 gtlscertificate: Fix bug in PEM private key parser + - !536 Various minor docs fixes + - !541 gtimezone: Fallback to /etc/timezone on Gentoo + - !546 spawn: add shebang line to script + - !547 Do not check for NULL when calling free() + - !549 Improve documentation of g_assert_error() + - !551 Revert "tests: Fix GOptionContext leak in GSubprocess tests" + - !554 Only subscribe to owner-changed signals on message bus connections + - !555 Suppress -Wint-in-bool-context warning with G_DEFINE_INTERFACE and g++ + +* Translation updates: + - Brazilian Portuguese + - Czech + - Danish + - Greek + - Hungarian + - Lithuanian + - Norwegian bokmÃ¥l + - Polish + - Slovak + - Slovenian + - Spanish + - Swedish + - Turkish + + +Overview of changes in GLib 2.58.0 +================================== + +* Tarball built with `ninja dist`, so if you want to build this release with + autotools (which is supported), you will need to re-run autogen.sh. This + release, and all micro releases in the 2.58.x series, support being built + with Meson or autotools. See: + https://mail.gnome.org/archives/gtk-devel-list/2018-June/msg00012.html + +* Fix cancellation of g_subprocess_communicate_async() calls. See !266. + +* Drop support for the __int64 type, which further breaks compilation on old + MSVC versions (before VS2013). See #1313. + +* Expose GSettings schema directory in gio-2.0.pc as `schemasdir`. See !274. + +* Support v3 of the xdg-desktop-portal network monitor API. See !265, !279. + +* Fix G_MODULE_SUFFIX on macOS when GLib is built with Meson — it should be `so` + rather than `dylib`. Projects that use Meson and the `g_module_build_path()` + API such as glib-networking should pass `name_suffix:` to `shared_module()` to + ensure that plugins continue to be called libfoo.so on macOS. See !280. + +Bugs fixed: + !280 meson: Always set G_MODULE_SUFFIX to `so` on macOS + !266 subprocess: Fix communicate_cancelled signature + !279 Revert "Add a gnet utility" (see !265) + !265 Network monitor again + !274 gio: Provide schemas directory information in pkg-config file + !239 gvariant: Fix more bounds checking in GVariant text format parser + !195 garray: add overflow checks before expanding array + #1497 g_strdup_printf warns on invalid format specifier with G_GUINT64_FORMAT on Win32 + !270 autotools: remove support for the __int64 type. See #1313 + !267 ci: Add an autotools job + +* Translation updates: + Czech + Galician + Indonesian + Italian + Kazakh + Korean + Turkish + + +Overview of changes in GLib 2.57.3 +================================== + +* G_GNUC_MALLOC’s definition has been tightened up to match an updated + definition from GCC. Many uses of G_GNUC_MALLOC which were previously + appropriate may cause miscompilation with newer GCC versions. Check your uses + of it against the updated documentation. See #1465. + +* Many minor documentation fixes. + +* Fix for gint64 and int64_t compatibility on macOS and BSD. See #972. + +* Fix free space metadata on some file systems (notably FAT). See #328. + +* Support installed-tests with our Meson build system. See #1444. + +* Forbid @filename@/@basename@ in glib-mkenums templates, which is a change to + its long-standing behaviour (which was long-standing nonsensical). See !241. + +* Various stat() fixes on Windows. See #1452, #1476. + +* MinGW-w64 ABI warning: In case you build 64 bit glib without LFS support by + passing --disable-largefile (not the default) and use GStatBuf, you need to + rebuild your application as the size of GStatBuf has changed for this case. + See #1476. + +* Improve TAP compatibility of g_test_incomplete(). See #1474. + +* Change fallback preferences when loading icons. See !72. + +Bugs fixed: + !263 build: Clean files left behind after gio/tests/gresource.c test + !262 gmem: Only evaluate pointer argument to g_clear_pointer() once + #1465 Many uses of G_GNUC_MALLOC are incorrect + #1448 g_error does not abort() as documented + #1494 g_clear_pointer may not use the correct calling convention with its callback + #972 Mismatch between gint64 and int64_t on 64-bit macOS/BSD + !251 gtestdbus: Fix watcher crash on FreeBSD + #1492 gcc-8: -Wcast-function-type: new warnings for g_list_copy_deep() + !252 tests: fix gnotification tests broken due to the recent icon name fallback changes + #328 filesystem::{free,size,used} not set for full FAT fs + !248 network monitor portal: update properties initially + #1373 Incorrect transfer annotation for g_binding_unbind. + #1444 the meson build doesn't support installed tests + #1027 Fix trashing on overlayfs + #1454 gvdb does not treat corrupt files as empty as promised; dconf suffers + !243 tests: Explicitly set TZ=UTC for g_time_val_from_iso8601() testing + #1488 ‘O_CLOEXEC’ undeclared (first use in this function) + !241 glib-mkenums: forbid @filename@/@basename@ in fhead and ftail + !240 gtimer: Ensure arithmetic is correctly signed for ISO 8601 parsing + #1452 GFileInfo: unable to retrieve correct modification time of links and mounted volumes on Windows + !234 DOC: Documentation fix in GTask description + #1363 Meson: Review cross compilation properties + !225 gtimer: Add overflow checks to g_time_val_from_iso8601() + !230 gbookmarkfile: Fix some more minor leaks when metadata elements are repeated + !229 Fix up g_bytes_compare() documentation + #1476 g_stat - possbile memory corruption causing SEGFAULT + !199 Update TLS documentation + #1474 g_test_incomplete() makes test_case_run() return FALSE + #1475 glib/tests/atomic.c test_types() trips -Werror=bad-function-cast on Debian armel + #1472 Test for BROKEN_IP_MREQ_SOURCE_STRUCT is broken on Windows / Mingw + !220 date test: Use g_test_skip(), not g_test_incomplete() + #1467 malloc difference causes refstring test to fail on FreeBSD + !230 gbookmarkfile: Fix some more minor leaks when metadata elements are repeated + #1466 Not Able to Build glib 2.57.2 in Mingw-w64 x64 bits + #1433 test_posix_parse: assertion failed (g_time_zone_get_abbreviation (tz, 0) == "UTC"): ("LMT" == "UTC") + #1446 Follow-up from "Document difference between g_assert() and g_assert_*() wrt G_DISABLE_ASSERT" + !206 grefstring: Avoid an unnecessary NUL assignment + #1458 g_volume_get_mount returns NULL value after g_volume_mount_finish is called with no error + !72 gio: icons should fallback to non-preferred style appropriately. + +* Translation updates: + Brazilian + Chinese (Taiwan) + French + German + Lithuanian + Polish + Romanian + Turkish + + +Overview of changes in GLib 2.57.2 +================================== + +* Require pcre 8.31 +* Require meson 0.47.0 + +* Bugs fixed: + 742456 Add g_steal_pointer() convenience function to mark ownership... + 795569 MinGW CI: fix tests + 796341 gmem.h: Use typeof() in g_steal_pointer() macro + #1013 Support for per-session overrides + #1360 glib-mkenums breaks if option specified but no nick + #1175 Add names and tags to various GSources and GTasks constructed in GLib + #903 g_main_context_wait() not deprecated in API, but emits a g_critical()... + #786 Fix memory leaks in libgio tests + #927 gio/gresource.c:do_lookup check for terminating "/" + #976 Document difference between g_assert() and g_assert_*()... + #1447 glib 2.57.1: test_month_names: assertion failed... + #1407 Update to Unicode Character Database 11 + #1455 glib python tools have full python path in shebang, limits to 128 characters + #1459 Missing g_return_val_if_fail in g_async_queue_timeout_pop + +* Translation updates: + Friulian + German + Romanian + Spanish + + +Overview of changes in GLib 2.57.1 +================================== + +* New api: + - g_hash_table_steal_extended + - G_GNUC_NO_INLINE + +* Bug fixes: + 668132 Use libmount and expose mount options on GUnixMountEntry type + 736741 Update private copy of valgrind.h + 748620 g_regex_* utf-8 validity requirements are not stated clearly + 784995 meson: some Windows improvements + 788771 NODELETE missing when built with meson + 788773 meson does not install correct pc files + 789968 Add g_autoptr() support for GTypeClass + 794325 Various fixes to compile on OSX + 795152 gdesktopappinfo: Mark GDesktopAppInfo constructors as nullable. + 795165 Add g_date_time_get_timezone() and g_time_zone_get_identifier() + 795180 Investigate performance impacts of recent compiler features on hot functions + 795302 Add g_hash_table_steal_extended() API + 795376 Add g_ptr_array_steal() + 795544 Add binary/textfile/zero size detection + 795569 MinGW CI: fix tests + 795636 gitlab-ci: generate test coverage reports + 795735 Fix comparison for GVariant property values + 795802 gdbus-codegen doesn't accept --output-directory with --output for --body and --header + 795849 gwin32: Fix detection of MinGW32 vs MinGW-w64 + 795876 meson: Fix checks for posix_memalign and stpcpy + 795960 g_format_size_for_display() is deprecated since 2.30 + 796085 Meson: Many apps breaks on non-glibc because of missing libintl + 796138 Fix typo in g_file_info_set_attribute docs + 796139 Add g_autoptr() support for GParamSpec + 796164 Fix atomic ops check in meson.build + 796186 Typo: "instead off" in gsignal.c + 796213 Meson: Fail to build on macosx + 796220 meson: do not run atomic test with msvc + 796264 Add android CI + 796325 meson: Add exception for atomic ops test for Android + 796328 gengiotypefuncs.py: Read and parse files in binary mode + +* Translation updates: + Czech + Indonesian + + +Overview of changes in GLib 2.57.0 +================================== + +* Bug fixes: + 739424 Rewrite kqueue GFileMonitor backend to drop threading + 751826 Use g_get_language_names() for other locale categories + 788773 meson does not install correct pc files + 793400 g_application_id_is_valid() not strict enough + 793578 gdatetime tests depend on Japanese translation of month names + 793645 test_month_names: Updated translations needed for el_GR, hr_HR, ru_RU + 793729 gitlab-ci: Add Windows MinGW support + 793994 GUnixVolumeMonitor doesn’t show user mounts when run as root + 794170 gdbus: hexdecode() and hexencode() do not return/use decoded/encoded s... + 794194 gobject_gdb.py: 'address' is a property of gdb.Value not a function + 794207 leak: g_socket_listener_add_inet_port increases ref-count on socket-li... + 794284 Support whitespace stripping for JSON resources + 794285 glib-compile-resources should not noisily g_printerr() when xmllint is... + 794473 Remove duplicated option in gio.xml + 794506 glib-mkenums: Enters infinite loop if using typedef enum SomeIdentifier + 794528 Fix segfault caused by use-after-free in GPollFileMonitor + 794555 glib meson build fails on MinGW due to misdetected functions + 794557 gtkdoc-scangobj fails on gio in meson builds + 794606 glib-2.56.0 fails to compile when res_nquery is not available + 794635 gmacros: Don't define bogus __has_* macros + 794636 G_HAVE_GNUC_VISIBILITY is defined in meson MinGW builds + 794686 Date (except weekday) displayed in English + 794732 Fix various compiler warnings + +* Translation updates + Hungarian + Slowak + Slovenian + Spanish + + +Overview of changes in GLib 2.56.0 +================================== + +* Bugs fixed: + 672777 Error in gdummyfile.c + 732184 GObject: warn on use of deprecated properties + 733338 Don't segfault in GNetworkMonitor when IPv6 support is unavailable + 742124 g_data_input_stream_read_upto()'s documentation should say that the... + 749206 GDateTime: month names in the genitive case + 768507 simplify qguark functions + 791457 Slow transfer rate when writing to smb/cifs + 793272 fix GCC 8.0's -Wcast-function-type warnings + 793300 g_hash_table_add() return value change in 2.40 not mentioned in docs + 793399 Fix some cases of -Wduplicated-branches + 793555 -Wimplicit-function-declaration when using g_abort() + 793565 GLib does not compile on macOS 10.13 due to .m file naming + 793597 gdbus-tool: Make --dest optional for emit again + 793635 Enable CI for GLib + 793880 gnetworkmonitor: Minor fixes based on code review + 793578 gdatetime tests depend on Japanese translation of month names + 794180 test_month_names fails unless installed + +* Translation updates: + Brazilian Portuguese + British English + Catalan + Czech + Danish + Dutch + Finnish + French + Friulian + Galician + German + Hungarian + Indonesian + Italian + Kazakh + Korean + Lithuanian + Polish + Scottish Gaelic + Serbian + Serbian Latin + Spanish + Swedish + Turkish + + +Overview of changes in GLib 2.55.2 +================================== + +* GFile now has API to get the path without copying + +* A network monitor implementation for Windows has been added + +* Bugs fixed: + 520116 g_utf8_strlcpy() + 584284 g_data_input_stream_read_until_async behaves confusingly different f... + 605700 request for g_key_file_get_locale() + 658713 ngettext (plural forms) needed for "Message has %d file descriptors ... + 685442 windows GNetworkMonitor implementation + 723003 gsettings list-recursively reports some keys multiple times + 749583 GSequence performance improvements + 757284 Move G_DIR_SEPARATOR* and G_SEARCHPATH_SEPARATOR* into glibconfig.h + 760324 [PATCH] gkeyfile.c: find_file_in_data_dirs fails to return the path ... + 761102 Increase performance for main loop + 767976 GFile: Add g_file_peek_path() + 770335 gdbus-codegen: generated getter for 'ao' property is actually (trans... + 772989 Totem allows invalid urls that might cause segfault that's irrecover... + 790698 convert: test failure on NetBSD + 791015 gdbus-codegen: Split generation of header and source + 791622 Disable strict-aliasing in GLib + 792050 GResolver is not thread-safe + 792217 Deprecate GTlsClientConnection:use-ssl3 + 792338 meson, autotools: figure out if mem barrier is needed for arm64 host... + 792351 gbookmarkfile: check length before dereferencing groups + 792364 gdbus-threading test method-calls-in-thread: assertion failed (elaps... + 792370 GNetworkMonitor: Rename "network-changed" signal argument + 792410 GDateTime new_from_iso8601 test broken in 2.55 on i386 + 792432 flush stdout after logging (debug) messages + 792455 Improve docs of GSequence + 792499 deadlock on startup with TCP session bus + 792516 gconvert: More consistent handling of embedded NUL bytes + 792777 g_notification_set_urgent() unconditionally sets G_NOTIFICATION_PRIO... + 792780 gbytes should reference toplevel bytes when slicing with g_bytes_new... + 792856 off64_t isn't a part of C standard + 792862 gpollableoutputstream: document side effects of WOULD_BLOCK on D/TLS + 792903 Clarification between g_try_.. functions and their counterparts + 793006 High CPU load for GUnixMountsMonitor consumers + 793026 possible mem leak in g_mutex_impl_new + 793074 g_message() does not get -Wformat warnings when compiling with G_LOG... + +* Translation updates: + Hungarian + Indonesian + Polish + + +Overview of changes in GLib 2.55.1 +================================== + +* Build: + - The --enable-rebuilds configure option has been removed + - The --with-charsetalias-dir configure option has been added + +* GList and GSList now have autoptr support + +* The gsettings list-schemas command has gained a --print-paths option + +* Bugs fixed: + 346816 Refactor LIBDIR in libcharset Makefile + 508976 Does g_slist_sort preserve the order of equal elements? + 562334 2.18.2 break libglade on Solaris + 662802 systemtap multiarch issue + 684282 Add support static link of GIO modules + 692034 Install an invalidation notifier for GClosure in g_source_set_closure() + 694723 Get rid of REBUILD stuff in configure.ac + 697715 floating point precision problem in check test gst/gstvalue + 701156 testgobject assumes that the priv data follows the instance data + 720380 Segfault when using GDBusMenuModel on a peer-to-peer connection + 724383 glib: document restrictions on various foreach() functions + 724412 GLib mappedfile.c test uses g_get_user_runtime_dir instead of a tempo... + 724794 Fix "on on" typo in tap-driver.sh comment + 732003 gnode: Eliminate implicit signed-to-unsigned integer conversion + 734479 G_VALUE_HOLDS etc. cause -Wcast-qual warnings for a const GValue * + 737677 gmain: Make GSourceCallback thread-safe + 741167 gdbus-codegen fix for boxed out parameters + 748534 gtest: if a subprocess assertion fails, print its stdout and stderr + 749527 add weak pointer helpers similar to g_set_object + 749652 compilation errors with gcc 4.8 + 754634 Update the list of Linux filesystem magic numbers used in get_fs_type + 756011 Fix up annotations for GBookmarkFile + 761102 Increase performance for main loop + 773980 GIR scanner doesn't interpret array type properly + 776147 gio/glocalfilemonitor.c doesn't handle case G_FILE_MONITOR_EVENT_MOVE... + 776195 -z nodelete configure check does not work on Solaris + 777075 Potential leak of memory pointed to by 'list' + 779413 Translated X-Geoclue-Reason string not used in a dialog window + 780309 gio/tests/appinfo build fails: gdesktopappinfo.c skipped on OS X + 780893 Reword licensing header for gdbus-codegen + 782057 Unit tests fail in run-assert-msg-test.sh + 784995 meson: some Windows improvements + 786796 gtk-doc build fails with meson + 788806 Impossible to build static glib via meson + 788936 Show mime type icons on OS X + 790416 g_date_time_format returns empty string on %r with German locale + 790588 Generated file missing from .gitignore + 790697 g_object_ref API should propagate parameter type + 790785 glib-tap: Add missing mkdir for .test generation rule + 790829 glib-genmarshal --body must not generate alias implementations + 790830 Mismatch between number of interface methods in text and example code + 790837 Meson: missing many configure options + 790839 GApplication command line: lacks parameter_string, summary and descri... + 790877 fix non-portable check in G_GNUC_CHECK_VERSION + 790894 Do not connect to the session bus when trying GProxyResolverPortal io... + 790896 docs/reference/README has broken link to http://www.gtk.org/rdp/ + 790914 gdesktopappinfo: Downgrade a warning to a debug message + 790934 gtester doesn't handle skipped tests + 790948 GSourceFuncs documentation is confusing: when will dispatch be called? + 791036 Guard for g_output_stream_vprintf makes no sense + 791128 C runtime complains about bad arguments on each g_log() call + 791221 po/README.translators has no useful information in 2017 + 791235 Fix gschema.dtd regarding flags. + 791267 Make gschema.dtd usable. + 791296 gtester-report: fix range usage when running as python3 app + 791318 GBytes: Improve documentation + 791325 Gio handling of thumbnail:: attribute namespace causes inconsistent b... + 791334 gbinding.c:898: The target object of type GNetworkAddress has no prop... + 791337 Crash opening URIs with g_desktop_app_info_launch_uris_with_spawn() + 791342 Add autoptr support for lists + 791460 meson: fixes for OSX + 791532 Implicit declaration of function ‘memcmp’ in gtestutils.h + 791622 Disable strict-aliasing in GLib + 791720 Criticals in gio/xdp-dbus.h leading to crash under flatpak + 791744 gmenumodel test sometimes fails: assertion failed (items_changed_coun... + 791745 not immediately clear whether g_test_slow() is in effect by default + 791906 GSocketListenerClass.event has wrong signature + 792064 gsettings list-schemas --print-paths + 792098 Binding: bind_property’s @notify func is nullable + 792099 gdbus-test-codegen: Cast to void* to printf "%p" + 792129 meson: skip optional linux/unix deps that default to true when buildi... + 792322 GLib-GIO:ERROR:gschema-compile.c:51:test_schema: child process (/gsch... + 792324 gkeyfile: Document need for KEEP_TRANSLATIONS with get_locale_string() + +* Translation updates + Hebrew + Indonesian + + +Overview of changes in GLib 2.55.0 +================================== + +* New API: + - g_clear_handle_id, to simplify removing sources from the default mainloop + - g_file_load_bytes, to make it more convenient to load files into GBytes + +* Bugs fixed: + 330458 Sample code for the GLib Key-value parser + 483341 g_error and friends create warnings when not used in MSVC + 569375 g[u]intptr undocumented + 573251 documentation for g_seekable_truncate() needs some love + 629347 Missing annotations in GFile (was: Perf throws an exception in cur... + 630983 [PATCH] Type accuracy for result of strlen() in string utilities. + 632953 Clarify documentation of GValueTransform. + 636210 Document that pre-unmount is not guaranteed and backend-dependant + 656502 type information for GSettings::backend missing from .gir + 661442 Nautilus crashes when refreshing home folder after modifying ~/.co... + 668035 gtester-report broken with python 2.7.2 and glib 2.30.1 + 670139 gbytes.c:try_steal_and_unref nit + 677233 (transfer full) annotation not correct for g_closure_new_simple re... + 679347 glocalfile seems to leak 'fstype' + 679467 Mention translation in g_warning() documentation + 689323 Variable scoping in gunixmounts.c + 691436 glib-mkenums output arch dependent + 695681 gsettings bash completion put error messages + 705331 AM_PATH_GLIB_2_0 macro fails with -Wstrict-prototypes -Werror + 706667 Fix permission denied error when installing from an nfs directory + 711809 gdbus-proxy: Fix erroneous timeout during following tests + 722256 gslist: Simplified node removal and got rid of some code duplication + 723655 Socket source is left in the poll after the socket is closed + 723743 g_child_watch_add() doesn't check for non-pids + 725014 g_settings_schema_source_ref should check for NULL pointer + 727346 docs: Escape some backslashes for markdown + 730296 gsignal: Fix a potential NULL pointer dereference + 731625 Improve test for darwin printf format-strings + 731705 gio/tests/desktop-app-info assumes /bin/true + 737278 Clarify relationship of g_application_quit() to hold count + 738176 Skip GSpawnChildSetupFunc closures in introspection + 740223 source_object for GAsyncResult should be nullable + 740791 gio: cannot specify the source when joining a multicast group (IGM... + 740826 glib doesn't know fuse filesystems + 742548 configure.ac: stay out of autoconf's namespace + 742997 Don't skip invalid enum values in schemas + 745723 -Wunused-but-set-variable work-around no longer sufficient + 749371 Use a GHashTable as a set when possible + 751738 Unused-variable warnings in glib/tests/autoptr.c + 752239 Missing dependency for python files in build file + 752240 Add DTLS support to GIO + 753459 GDateTime: Add conversion functions from/to ISO 8601 strings + 753521 g_subprocess_launcher_set_environ misses argument annotations + 754026 gfileutils: add some sanity checks + 756009 'const gchar* const *' gets incorrectly defaulted to utf8 + 756103 Skip g_base64_decode_step() in introspection + 756128 Fix up annotations in gconvert + 756430 g_rw_lock_reader_lock() can return without locking, or error + 756470 Fix up annotations in gdataset.c + 756588 Fix up annotations on data/qdata API of GObject + 760022 Memory leak in gvariant-parser.c + 760109 [PATCH] Invalid GDate can't be g_boxed_copy()'d + 760716 Fix documentation regarding + 765063 Update annotations for gio + 765552 Please set serial in .m4 files to prevent autoreconf failure on up... + 767215 GCC version number is interpreted as start of a list in docs for g... + 767239 Tautological comparisons in convert tests + 769674 some GIO tests' arbitrary timeouts are too short + 769846 gmessages: Add timestamp to g_log_writer_format_fields() + 770459 Tutorial article is slightly wrong + 773355 Incorrect documentation about stopping a signal emission from a hook + 774083 spelling mistakes in glib: charater + 776562 Add Intel C Compiler support for G_GNUC_BEGIN/END_IGNORE_DEPRECATI... + 777308 GModule win32: disable error dialog popup + 777310 gio/gasynchelper.c: fix cast from pointer to smaller int type on w... + 777956 gmessages: Update advice for G_LOG_DOMAIN + 779182 xdg-open fails with gio open for some uris + 779501 Type of GIConv given wrongly on web + 780202 introspection: Don't expose GValueArray.free + 780296 xdg-open/gnome-open doesn't work if service isn't started + 781598 gstdio.h should #include what it needs to work + 781867 various gvfsd-* wants to look in /boot/efi, causes unnecessary/ina... + 783210 build: Switch to sassc for generating style + 783270 Improve Visual Studio support for Meson builds + 783825 Suggest that asynchronous operations should invoke the callback in... + 786737 No g_variant_get() example for dicts + 786785 Commit #fe2a9887a8 breaks gdbus-codegen, cannot find its module so... + 787271 Make GListModel usable from G-I bindings + 787485 g_tls_backend_supports_dtls () returns true when the backend doesn't + 787551 Factor out some duplicated code in GParamSpec validation + 787581 tests: Add tests for g_slist_copy() and g_slist_copy_deep() + 787671 meson: Fix permissions of installed scripts + 787731 g_file_query_filesystem_info() wrongly reports "filesystem::readon... + 788138 glib-compile-resources: Fix leak of a GHashTable + 788180 G_FILE_ATTRIBUTE_ID_FILE is useless on W32 + 788270 gmodule - failed to load symbol on Android 64bit + 788368 Race condition in GDbusObjectManagerClient + 788384 gtypes: Fix signedness of __builtin_bswap() usage + 788385 gtestutils: Explicitly cast args to g_assertion_message_cmpnum() + 788401 PATCH: MacOS build cannot detect content type from content - xdgmi... + 788467 Fatal errors and warnings should be reported as TAP + 788488 GFile-based API for g_build_filename() + 788489 gmain: add g_clear_source API + 788561 Document how to integrate GTest into your project + 788594 gdbus-tool doesn’t handle non-message-bus connections correctly + 788705 Allow building GLib on older Linux platforms + 788766 fixed a doc-typo in socket_get_remote_address + 788772 meson installs gdb scripts incorrectly + 788863 Add more filename type annotations for strings which can contain f... + 788880 gunixmounts: Update list of virtual file systems to ignore + 788927 Expose better API for detecting ‘system’ mounts + 788936 Show mime type icons on OS X + 788948 Document Autotools best practices for genmarshal/mkenums + 788975 Meson + Visual Studio: Can't find zlib.h with subprojects/zlib + 788978 Document XML has a syntax error + 788989 Use subdir-objects with Autotools + 788990 Include licensing information in output from glib-mkenums, glib-ge... + 789087 gint and guint misrepresented as functions + 789170 GFormatSizeFlags should have a value for bits + 789245 g_settings_bind() not conforming to lifecycle specification + 789444 Fix handling of length in g_utf8_make_valid + 789637 glib-mkenums: Fails when --ouput file does not exist + 789681 meson: Libmount support not built + 789723 [PATCH] gdbus-codegen: Call abspath() earlier + 789755 g_get_host_name: ensure return value is always UTF8 encoded + 789820 GPollFileMonitor is not cleaning up correctly + 790015 docs: Various linking and syntax fixes + 790030 GResource/GVariant fails to load from non-pointer aligned memory + 790093 gio-tool: fix inverted logic in monitor tool + 790126 gengiotypefuncs.py is missing from tarballs + 790147 build: Drop data-to-c.pl in favour of data-to-c.py + 790157 gmessages: Give examples of G_DEBUG with gdb in the documentation + 790272 file: add g_file_load_bytes() + 790275 avoid temporary string allocations in g_resources_enumerate_children + 790310 speedup path canonicalization in GResourceFile + +* Translation updates: + Catalan (Valencian) + Czech + German + Nepali + Norwegian bokmÃ¥l + Slovak + Slovenian + Spanish + + +Overview of changes in GLib 2.54.0 +================================== + +* Bugs fixed: + 780861 Crash in GnomeWallClock + 786983 Please make the output of gio-querymodules deterministic + 787109 Valgrind false positive in ioctl() in btrfs file copy + 787123 glib: Slighty update GIOChannel documentation + 787146 GMainLoop: match of parameter pair of LOCK_CONTEXT/UNLOCK_CONTEXT + +* Translation updates: + Basque + Catalan + Romanian + Swedish + + +Overview of changes in GLib 2.53.7 +================================== + +* Bugs fixed: + 736710 remove unnecessary executions of libtool from configure + 785260 gio/tests/appmonitor fails if local dir not writeable + 786456 g_subprocess_wait[_check]_async() breaks when cancelled... + 786555 g_array_free() is not thread safe w.r.t. g_array_unref() + 786580 gdesktopappinfo.c: Add Tilix as a fallback terminal + 786807 g_uuid_string_random undefined when built with meson + +* Translation updates: + Brazilian Portuguese + Catalan + Czech + Danish + Finnish + French + Friulian + German + Italian + Kazakh + Korean + Latvian + Nepali + Polish + Spanish + Turkish + + +Overview of changes in GLib 2.53.6 +================================== + +* Bugs fixed: + 766358 glib doesn't respect XDG_* envvars on W32, ever + 783270 Improve Visual Studio support for Meson builds + 785955 pthread_setname_np misdetected with meson + 786060 Sequences documentation does not make it clear... + 786360 gobject: add autoptr support for GClosure + 786452 crash on Linux without stderr stream + 786460 gio-tool: Unify buffer sizes + 786462 Use g_output_stream_write_all instead of while + 786463 gio-tool-save: Prevent overwriting error + +* Translation updates: + Catalan + Galician + Hungarian + Indonesian + Lithuanian + Nepali + Serbian + + +Overview of changes in GLib 2.53.5 +================================== + +* Bugs fixed: + 695573 Untranslatable strings in glib-compile-schemas + 725950 GApplication: call dbus_unregister only once, and before destruction + 731703 giomodule test misbuilds its test modules as libraries + 769135 External control for g_test_add/g_test_run + 779332 Rewrite mkenums in Python + 779607 Race between mounts-changed signal and g_unix_mounts_get() function + 784000 Improve strerror_r() detection + 784815 Map G_NOTIFICATION_PRIORITY_HIGH to NOTIFY_URGENCY_NORMAL + 784965 Use the glib preset for i18n in Meson + 784995 meson: some Windows improvements + 785113 glib-mkenums Python port fixes + 785130 G_LOG_DOMAIN shouldn't be left undefined for applications + 785438 Spurious -Wmaybe-uninitialized in gdatetime.c + 785468 glib/gpoll: Unnecessary if conditional included in the poll_rest() function + 785520 Replace advice to use removed gdk_spawn functions + 785577 clobbers errno while setting GError + +* Translation updates: + Slovenian + Spanish + + +Overview of changes in GLib 2.53.4 +================================== + +* Unicode support has been updated to Unicode 10.0.0 + +* glib-genmarshal and glib-mkenums have been rewritten in python. + Every effort has been made to keep compatibility. Please report + problems related to these tools + +* GLib can now be built with meson. autotools are still supported + +* Bugs fixed: + 722047 drop makefile.msc? + 733821 g_strerror() uses strerror(3) instead of strerror_r(3) + 773842 g_utf8_find_next_char() won't signal the end of a NUL-terminated string + 779332 Rewrite mkenums in Python + 780095 g_utf8_get_char_validated() stopping at nul byte even for length specified... + 780634 Remove remaining old codepage ABI comapt code + 783841 test_GDateTime_new_from_timeval_overflow fails on 32 bit systems + 784000 Improve strerror_r() detection + 784020 GKeyFile – Add array length annotations to to_data(), get_keys() and get_g... + 784037 gio: Mention the ALL_METADATA flag in g_file_copy() + 784433 gdbus-codegen with variant type parameters result in nested variant + 784456 Update to Unicode 10.0.0 + 784528 Rewrite glib-genmarshal in Python + 784579 Calling g_dir_open on Missing Directory When Executable File Path Contains... + 784581 docs: Fix cut'n'paste error in g_resources_get_info() doc + 784739 Minor typo in configure error message + 784792 Just fixing a little typo in comments + +* Translation updates: + Hebrew + + +Overview of changes in GLib 2.53.3 +================================== + +* Bugs fixed: + 658446 Add translation comment for wrong password notice string + 661926 Improve the default logging setup in GLib + 674885 type initialisation deadlock in GObject + 775593 GIO cannot write symlinks on FreeBSD and NetBSD + 776169 Various gio-tool fixes + 776333 Fix annotation on g_file_copy_async() + 776504 Upgrade license from LGPLv2+ to LGPLv2.1+ + 777307 race condition between gdbus signal callback and g_bus_unwatch_name... + 778422 gsubprocesslauncher: Clarify the behavior of set_environ() + 781301 Stack pointer corrupted by incorrect call of NtNotifyChangeMultipleKeys + 782336 Add additional documentation of the GResource XML format + 782996 build: Use AM_TESTS_ENVIRONMENT rather than TESTS_ENVIRONMENT + 783061 GApplication: Remove some unused members + 783130 Make dbus activation sandbox-aware + 783193 Adapt to OpenURI api change + 783201 gdbus-codegen: Apply --output-directory to generated docs as well + 783340 win32: port monotonic times to use QPC + 783350 length parameter can be NULL g_data_input_stream_read_line + 783392 incorrect (out) annotation for g_dbus_interface_info_generate_xml + 783593 GGtkNotificationBackend should use /org/freedesktop/DBus to call Ge... + +* Translation updates: + Esperanto + German + Indonesian + Kazakh + Spanish + + +Overview of changes in GLib 2.53.2 +================================== + +* A few new number parsing functions have been added: + - g_ascii_string_to_signed + - g_ascii_string_to_unsigned + These have better error handling than the existing ones. + +* glib-mkenums now supports /*< private >*/ and /*< public >*/ + +* GSettings now consider XDG_DATA_HOME in addition to XDG_DATA_DIRS. + +* Bugs fixed: + 674885 type initialisation deadlock in GObject + 698064 Add g_ptr_array_contains() + 732000 gdatetime: Remove an unnecessary NULL pointer check + 734946 Implement GContentType on OSX + 741335 Possible differences in use of XDG_DATA_DIRS versus XDG base directory specification + 748263 Use-after-free in g_dbus_connection_call_internal() + 776876 gmodule – Various Android bug-fixes + 777030 build error where minor() and major() cant be resolved in gio/gdbusmessage.c + 780300 gio/gosxappinfo.c uses deprecated LSFindApplicationForInfo + 780309 gio/tests/appinfo build fails: gdesktopappinfo.c skipped on OS X + 781755 Avoid compiler warnings in generated marshallers code + 781826 portal support: Read /.flatpak-info + 781830 Fix some typos and errors in GVariant documentation + 781847 Use-after-free under send_message_with_reply_cleanup():gdbusconnection.c:1792 + 781867 various gvfsd-* wants to look in /boot/efi, causes unnecessary/inappropriate auto... + 782068 doc: Trivial typo fixes + 782075 gtimer: Handle gmtime() failure in g_time_val_to_iso8601() + 782089 gdatetime: Fix overflow checks when constructing from timestamps + 782162 Support public/private trigraph in glib-mkenums + 782237 make check error + 782311 inode/directory is treated as a subclass of application/octet-stream + 782628 libmount build dependency check not requiring the right version? + +* Translation updates: + Hungarian + Indonesian + Spanish + + +Overview of changes in GLib 2.53.1 +================================== + +* The gdbus tool gained a wait command + +* g_unix_signal_source_new support SIGWINCH now + +* There are now g_enum_to_string and g_flags_to_string functions + +* A new function to instantiate objects: g_objet_new_with_properties + +* GParameter and related APIs have been deprecated + +* Bug fixes + 447907 enum/flags from string + type transform + tests + 668962 GUnixMountPoint/GUnixMountEntry not usable through gobject-introspection + 669355 gdbus-codegen output contains stray semicolons at file scope (forbidden in C99) + 674885 type initialisation deadlock in GObject + 698064 Add g_ptr_array_contains() + 709865 Add boxing to GParameter + 725894 build: Include gettext libraries for static compilation on Mac OS X + 734946 Implement GContentType on OSX + 741229 gio: Handle NULL cached properties in NetworkManager monitor + 745971 gdbus-tool: Add a command to wait for a well-known name on the bus + 755046 gfileutils: Add precondition checks to g_file_test() + 761102 Increase performance for main loop + 761889 GDateTime: %p does not always print AM/PM string + 766660 Please clarify the extent to which GInitable, GAsyncInitable must be idempotent + 769534 g_unix_signal_source_new does not support SIGWINCH + 772221 Take advantage of Unicode + 775879 g_log_default_handler should not check G_MESSAGES_DEBUG + 776169 various gio-tool fixes + 777961 Documentation for g_app_info_equals() could be clearer + 778049 race in gsource detected by TSan + 778207 gio-querymodules: fix memory leak + 778287 G_MODULE_EXPORT and -fvisibility=hidden + 779409 Fix false positive g_warning() in remove_filter() + 780066 g_base64_encode_close() in glib/gbase64.c produces invalid base64 encoding + 780095 g_utf8_get_char_validated() stopping at nul byte even for length specified buffers + 780306 Unused function in gunicollate.c for CARBON + 780310 g_tls_database_verify_chain doesn't set the GError for failures other than cancell... + 780384 gio/tests/contenttype fails on OS X: "public.directory" != "public.folder" + 780441 Make the portal implementation of g_app_info_launch() synchronous + 780634 Remove remaining old codepage ABI comapt code + 780908 gobject: remove duplicate GType sanity check + 780924 Memory leak in gdbusmethodinvocation.c + 781125 gio-tool: Fix errors format string + 781234 the buffer written to by g_input_stream_read is not marked as an out parameter + 781298 gfileutils.c:330:3: error: ISO C90 forbids mixed declarations and code + +* Translation updates + Catalan + Friulian + German + Hebrew + Indonesian + Polish + Russian + + +Overview of changes in GLib 2.52.0 +================================== + +* Bug fixes: + 779799 gdatetime test fails with tzdata 2017a + 780032 Add missing attributes to two functions + 780144 gio/fam: Remove leftover debug print + +* Translation updates: + French + Friulian + Latvian + + +Overview of changes in GLib 2.51.5 +================================== + +* OS X implementations of GContentType and GAppInfo + have been added + +* Bugs fixed: + 673047 gunicollate is broken on OS X (patch included!) + 734946 Implement GContentType on OSX + 747146 Implement GNotification on OSX + 769983 glib-mkenums generates non-reproducible Makefile snippets + 777203 gnulib license information is not correct in glib2.0 + 778515 Crash in the gio kqueue backend + 779456 Make g_utf8_make_valid optionally take a length + +* Translation updates: + Danish + Friulian + German + Hungarian + Korean + Lithuanian + + +Overview of changes in GLib 2.51.4 +================================== + +* Memory leak fixes +* Fix the released tarball + + +Overview of changes in GLib 2.51.3 +================================== + +* Bugs fixed: + 771997 gchecksum: Add SHA-384 support + 778422 gsubprocesslauncher: Clarify the behavior of set_environ() + 778581 gdbus-codegen: Fix -Wconversion warning + 778801 gdbus-codegen: Add --outdir flag + 778991 Plug a mem leak in gdbusauth + 779183 g_io_extension_point_get_extensions should check for NULL pointer + +* Translation updates: + Basque + Chinese (Taiwan) + Danish + Indonesian + Italian + Serbian + + +Overview of changes in GLib 2.51.2 +================================== + +* Minimal support for UUIDs has been added + +* A new file attribute, G_FILE_ATTRIBUTE_RECENT_MODIFIED has been added + to improve sorting of recent files + +* Bugs fixed: + 639078 UUID support feature request + 777135 gkeyfile: Be more specific about error codes in documentation + 777307 race condition between gdbus signal callback and g_bus_unwatch_name... + 777481 goutputstream: docs: fix typos + 777493 g_mkdtemp() not introspectable + 777507 Recent view sorting incorrectly + 777592 Add minor examples to GDBus and GVariant documentation + 778002 race in gdbusprivate.c detected by the ThreadSanitizer + 778096 race in gdbusconnection reported by TSan + +* Translation updates: + Norwegian bokmÃ¥l + Polish + Simplified Chinese + Slovak + Spanish + Swedish + + +Overview of changes in GLib 2.51.1 +================================== + +* glib-compile-resources grew a --generate-phony-targets flag + +* GLib now installs a valgrind suppressions file for GLib and GIO + +* Bugs fixed: + 666114 should have infrastructure to run its tests under valgrind + 729730 GDBusMessage: Fix segfault if DEBUG_SERIALIZER is enabled + 730932 statically assert that reasonable assumptions about enums are true + 735731 gobject: Document behaviour of GType checking macros on NULL + 736810 gdbus: Fix leak in g_dbus_message_print() + 762283 GSocket – Fix race conditions on Win32 if multiple threads are waiting on cond... + 767609 Test suite problems + 767952 g_dbus_method_invocation_return_*, g_dbus_method_invocation_take_error: They d... + 769672 Assert threads for testcase 642026 are sucessfully created + 769745 gtask: Add guards for public functions + 770175 Add command line argument to mkenums and genmarshal to write output to a file + 770646 glib: Namespace global tapset variables by soname + 772160 Add g_unix_mount_for() support + 772989 Totem allows invalid urls that might cause segfault that's irrecoverable + 773823 gio: Bump copy buffer size to 256k by default + 774086 fix g_main_context_check declaration + 774368 Dependency file output of resource scanner breaks Ninja + 774421 Two minor patches + 774520 GSocket allocates and processes control messages even if not requested + 775309 Crash in gdbusauth + 775468 Improve log write supports color method on windows + 775510 testing with -fsanitize=undefined reports various undefined behaviour + 775517 Password input is echoed in the terminal + 775621 gmessages: Fix compilation on Android + 775765 FDO notification withdrawal backend sends wrong ID to the server + 775913 subprocesslauncher: potential infinite loop in verify_disposition() + 776198 Stray semicolon after g_variant_print() function in gvariant.c + 776586 License headers cleanup + 777077 Use of memory after it is freed + +* Translation updates: + Brazilian Portuguese + Czech + Galician + German + Hebrew + Kazakh + Lithuanian + Spanish + Swedish + + +Overview of changes in GLib 2.51.0 +================================== + +* glib-genmarshal and glib-mkenums have gained --output options + for better build system integration + +* New API: g_utf8_make_valid + +* Bugs fixed: + 591603 Make _g_utf8_make_valid public + 610969 Nice to have g_utf8_make_valid as public + 767882 Bit shift overflow (-Wshift-overflow) warning in gparam.h + 769135 External control for g_test_add/g_test_run + 769630 gfile: G_FILE_MONITOR_WATCH_MOVES was actually introduced in 2.46 + 772160 Add g_unix_mount_for() support + 772221 Take advantage of Unicode + 773303 GApplication leaks option_strings + +* Translation updates: + French + Galician + German + Hungarian + Lithuanian + Norwegian bokmÃ¥l + Occitan + Polish + Slovak + Turkish + + +Overview of changes in GLib 2.50.1 +================================== + +* Update Unicode support to Unicode 9.0.0 + +* Bugs fixed: + 662946 gunixmounts monitoring doesn't work correctly with libmount + 771591 Update to Unicode 9.0.0 + 772054 glib/gspawn-win32-helper.c: unexpected behavior re CommandLineToArgvW() + 772255 gresolver: Mark GResolver as an abstract class + 772269 Add --version options to glib-compile-resources and glib-compile-schemas + 772297 completion: Complete gsettings describe + 772511 g_log_default_handler crashes windows apps with "Unspecified fatal err... + +* Translation updates: + Brazilian Portuguese + Catalan + Croatian + Czech + Danish + Hungarian + Italian + Latvian + Polish + Swedish + + +Overview of changes in GLib 2.50.0 +================================== + +* Bugs fixed: + 771438 Turn on libmount by default on linux + Fix the annotation for g_log_variant + +* Translation updates: + British English + French + + +Overview of changes in GLib 2.49.7 +================================== + +* Add g_log_variant, binding-friendly api for structured logging + +Bugs fixed: + 646926 arg_data invalid after g_option_context_parse() fails + +* Translation updates: + Danish + Finnish + Galician + German + Hebrew + Kazakh + Korean + Latvian + Lithuanian + Polish + Portuguese + Serbian + Slovak + Spanish + Swedish + Thai + + +Overview of changes in GLib 2.49.6 +================================== + +* The gsettings commandline tool now has a describe command + +Bugs fixed: + 745754 Add gcc-style dependency output to glib-compile-resources + 769076 Fix warning: attempt to override closure->va_marshal with new marshal + 770372 gdbus-codegen: Strip @since parameters before comparison + +Translation updates: + Brazilian Portuguese + Czech + German + Hungarian + Polish + Portuguese + Spanish + + +Overview of changes in GLib 2.49.5 +================================== + +* Structured logging: + - drop libsystemd dependency + - document that g_test_expect_message does not work with structured logs + +* Use libmount for unix mount support + +* Add an async variant of g_app_info_launch_default_for_uri + +Bugs fixed: + 522053 GUnixMountMonitor needs to use /proc/self/mountinfo on recent Linux + 682794 Add usage guidance to logging documentation + 744456 Structured logging API + 766370 Add a macro for initializing g_auto(GVariantBuilder) + 767240 Regex failures with pcre 8.38 + 768198 Can't build glib with systemtap enabled + 768453 Gdbus test: compilation fails due to -Werror=format-y2k errors + 768752 Add async variant of g_app_info_launch_default_for_uri + 769027 Docs misleadingly imply G_CHECKSUM_SHA512 is available since 2.16 + 769029 gmessage: compiler complains about -Wformat-nonliteral + 769042 'O_CLOEXEC' undeclared (first use in this function) + 769087 gmessages: support NULL log domain + 769089 Fix gsettings uint64 testcase + 769104 Build failure when using _GLIB_CHECKED_ADD_U32 with the Intel compiler + 769139 g_log_writer_journald uses non-standard 'htole64' function + 769238 memory increases every time I umount and mount my secondary hard disk. + 769245 is_valid_heap_iter define misses NULL pointer check + 769507 gmessages: Don’t require is_journald() call before writer_journald() + 769785 gmessages: Expand documentation further for structured logging + 769995 gdbus-codegen: Allow '@since: UNRELEASED' in documentation comments + +Translation updates: + Catalan + Hebrew + Lithuanian + Slovak + Spanish + + +Overview of changes in GLib 2.49.4 +================================== + +* Change the just-introduced structured logging API. The arguments + of g_log_structured() had to be reordered to enable an implementation + within the limits of what the standards guarantee about var args. + +Bugs fixed: + 744456 Structured logging API + 768936 gio doc build fails because of missing gio.xml in the tarballs + 768963 improper va_list use in g_log_structured() + 768968 gio/tests/socket-listener hangs since e4ee307 + +Translation updates: + Spanish + + +Overview of changes in GLib 2.49.3 +================================== + +* GLib has a structured logging API, g_log_structured, with support + for writing to the systemd journal. It also supports colored output + in terminals + +* Some new GBytes API has been added: + - g_key_file_load_from_bytes + - g_compute_hmac_for_bytes + +* Stack-allocated GVariantBuilder and GVariantDict objects can now be + initialized with G_VARIANT_BUILDER_INIT and G_VARIANT_DICT_INIT + +* gio: + - Add a way to register handlers for custom uri schemes + - Add a G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE attribute to + have these heuristics in a single place + - Include a gio tool that makes the functionality of the + various gvfs commandline tools available in a single place + - Add portal support to g_app_info_launch_default_for_uri + - Add portal support to GNetworkMonitor + - Add portal support to GProxyResolver + - Add portal support to g_application_send_notification + +Bugs fixed: + 547200 g_utf8_find_next_char() issues + 662802 systemtap multiarch issue + 723506 fork/exec from non-main thread when autolaunching could be avoided... + 725902 build: simplify dtrace configuration + 728207 gsocketservice: Documentation does not mention that is already act... + 729914 instead of DEBUG_CODE and IF_DEBUG, provide a common macro to supp... + 744456 Structured logging API + 744678 Unable to delete relocatable schemas + 746685 clarify that g_variant_get_data() can be used instead of g_variant... + 747134 glib-compile-resources --generate should detect common C++ file ex... + 750257 GSettings changed signal should clearly state the order required + 753231 Memory is potentially used after free + 754012 missing filename in "Error loading css: Failed to import: Error op... + 760115 gtestutils: add missing dash in seed argument's --help documentation + 760423 gio-querymodules prints error messages as question marks on some l... + 761102 Increase performance for main loop + 765338 GLib.compute_hmac_for_data throws every time + 766370 Add a macro for initializing g_auto(GVariantBuilder) + 766899 Superflous HTML/XML comments in GDBusProxyTypeFunc documentation s... + 766933 GSocketAddress leaks in gnetworkmonitornetlink.c:read_netlink_mess... + 767765 Add names and tags to various GSources and GTasks constructed in GLib + 767880 gkeyfile: add g_key_file_load_from_bytes() API + 767887 vfs: add g_vfs_register_uri_scheme() + 767949 [patch] Typos in glib docs + 768029 infinite loop in parse_name_internal() + 768119 Fix fallout from get_supported_schemes() changes + 768357 Build the gio tool on Windows/MSVC + 768498 portal support for glib + 768504 keyfile: g_key_file_get_double behavior doesn't follow documentation + 768549 Test failure: test_ip_sync_dgram + 768551 Test failure: test_socket_address_to_string + 768560 gio/tests/gsettings: fix GSettings reference leaks in some tests + 768780 O_PATH is a non-standard flag which may be unavailable on non-Lin... + 768806 gdbus tool must swallow -- argument + +Translation updates: + Chinese (Taiwan) + French + Hebrew + Indonesian + Lithuanian + Portuguese + Spanish + + +Overview of changes in GLib 2.49.2 +================================== + + * GMainContext and GTask have gained more systemtap probes + +Bugs fixed: + 673101 resource compiler dependency generation not working for gen... + 700756 GFile.new_for_path arguments misses (type filename) annotation + 730187 glocalfileoutputstream: Fix an FD leak in an error path + 755439 Memory leak in gdbusproxy.c + 759813 Add more SystemTap/DTrace probes for main context and GTask + 761810 gio: Support using GDBusObjectManagerServer at path ‘/’ + 767172 docs: Move GIO_USE_VFS to "okay for production" section + 767218 Remove a UTF-8 ellipsis from gsignal.h + 767245 Add filename type annotations + 767824 Some UTC timezones incorrectly recognized on Windows 7 + +Translation updates: + Occitan + + +Overview of changes in GLib 2.49.1 +================================== + + * GDesktopAppInfo now allows bus activation with dashes. This is + not technically allowed per the Desktop Entry specification, but + it happens in the wild. Rather than forcing people to go through + another traumatic desktop file rename, accept it and translate - to _. + + * The support for giving names to threads has been improved. Thread names + are now supported on Solaris as well, and the Linux support no longer + uses prctl() but the pthread api. + + * GIO resources can now be overridden at runtime, using the G_RESOURCE_OVERLAYS + environment variable. + + * gdbus-codegen can now generate autocleanup definitions for the types + it generates. Use the --c-generate-autocleanup option to control this + +Bugs fixed: + 665446 Use g_abort() instead of abort() + 731988 glocalfile: Avoid a potential NULL pointer dereference + 742898 g_value_type_transformable() description differs from the code + 747107 GVariant varargs documentation: g_variant_get() example + 747478 g_system_thread_set_name() is not implemented for gthread-win32 + 748474 g_get_language_names() is not thread-safe + 748530 gthread: W32 implementation of g_get_num_processors() has lame fallback + 748806 GVariant: Better introduction to the concepts and its uses + 749583 GSequence performance improvements + 749606 tests: always remove app.desktop + 755898 [PATCH] settings: add get/set uint64 + 758174 Fix documentation typos + 758738 Usage of GType properties causes crashes due to gulong/gpointer mismatch + 760186 namespace clash with gdb pretty-printing code + 762994 Race condition in GIO/AppFileChooser crashes Firefox/Gtk3 + 763379 codegen: Add support for g_autoptr to gdbus-codegen–generated objects + 763821 build: Also dist Systemtap files always for gobject/ + 764092 gstrfuncs: Document the behaviour of g_strjoinv() + 764163 g_task_had_error doesn't remember the error after g_task_propagate_* + 764415 Very High CPU usage in g_poll() Windows implementation + 764574 build: Fix all statfs() tests failing + 764575 tests: Fix compilation errors due to Y2K format problems + 764685 GApplication documentation about handling command-line options is confusing + 764754 '-' in application id: unbreak bus activation and notifications + 765173 documentation of g_main_context_push_thread_default() regarding GIO... + 765668 GResources: add support for resource overlays + 765710 gdbus-tool: only print note about expected argument types if that... + 765712 tests: Fix compilation + 765861 task: avoid context lock when setting source name + 765900 Add g_drive_is_removable() support + 765924 Improve external drives detection + 765959 socket: set fd field to -1 after closing socket + 765990 Visual Studio: Define inline only when necessary + 765991 Compilation of gresource.c is broken due to S_ISDIR + 766092 Incorrect locale handling in g_date_time_format_locale() + 766211 Fix the upper bound in g_unichar_iswide_bsearch + 766407 Some build-related defects in glib testsuite + 766570 build: Fix a misnamed variable in glib-tap.mk + +Translation updates: + Basque + Catalan + Chinese + Occitan + Portuguese + Turkish + Vietnamese + + +Overview of changes in GLib 2.48.0 +================================== + + * The system copy of PCRE is now used by default to implement GRegex. + Configure with --with-pcre=internal if a system PCRE version + is unavailable or undesired. + + * a minor build fix in the name of determinism + + * a few coverity fixes + +Bugs fixed: + 763617 giotypefuncs.c: Sort _get_type functions in the 'C' locale + +Translations updated: + Danish + Italian + +Overview of changes in GLib 2.47.92 +=================================== + + * gdbus-codegen now supports g_autoptr() + + * g_get_user_runtime_dir() now reliably returns an existing directory + + * g_array_remove_range() can now remove 0 items from the end of an array + + * Many fixes for Windows + * build fixes + * file monitoring + * gsettings backend + * streams + * random numbers + * wide character support + + * documentation improvements + + * other small bugfixes + +Bugs fixed: + 724847 Segmentation fault on "gsettings list-recursively" + 743933 gapplication: add --app-id command line option + 756706 [PATCH] gio/gtestdbus.c: don't use non-standard %m printf modifier + 757506 gsettings: schema_list should use the passed schema's source + 760694 W32: Apps linked with -mwindows make cursor busy sometimes + 762202 g_win32_error_message improvements + 762637 build: Unconditionally dist tapset files + 762748 Undefined behavior + 762937 Mention that g_clear_error can be used with an "empty" GError + 763339 array: Support clearing an empty array with g_array_remove_range() + 763344 g_get_user_runtime_dir(): ensure directory exists + 763379 codegen: Add support for g_autoptr to gdbus-codegen–generated objects + +Translations updated: + Brazilian Portuguese + Czech + Finnish + French + Galician s + German + Greek + Hebrew + Hungarian + Italian + Kazakh + Korean + Latvian + Lithuanian + Occitan + Polish + Russian + Serbian + Slovak + Slovenian + Spanish + Swedish + +Overview of changes in GLib 2.47.6 +================================== + +* Windows usupport: + - Fixes and improvements to the GSettings registry backend + - Handle readability and writability of registry keys + - Use Unicode registry APIs + +* Bugs fixed: +760852 744772 761126 747927 761337 744570 761504 761550 761843 + 744570 GString is missing (transfer none) annotations on many of its methods + 744772 systemtap and gdb scripts install in wrong place + 747927 Documentation: various small improvements + 760852 gdbusobjectmanagerserver: Clarify recommended ObjectManager paths + 761126 winiconv: update to upstream version + 761337 Fix some annotations + 761504 W32 registry GSettings backend does not use Unicode + 761550 Cannot build with default flags under Fedora rawhide (-Werror=format-... + 761843 gmacros.h is testing attributes with __has_feature (when compiling wi... + +* Translation updates: + Brazilian Portuguese + Bulagarian + Chinese (Taiwan) + Hungarian + Polish + Slovak + Slovenian + Spanish + Swedish + + +Overview of changes in GLib 2.47.5 +================================== + +* the system copy of PCRE is now used by default to implement GRegex. + Configure with --with-pcre=internal if a system PCRE version + is unavailable or undesired. + +* interfaces for DTLS support have been added. A new version of + glib-networking will also be required. + +* GDBusMethodInvocation now drops replies if the sender set the + NO_REPLY_EXPECTED flag + +* several GApplication fixes, including fixes for commandline arguments + in interpreted languages on Windows + +Bugs fixed: + 624186 Deprecate glib-gettext macros + 734095 gtk-demo.py of PyGObject fails to run on Windows (and likely other binding scripts using g_application_run()) + 735754 Implement close on TLS GOutputStream + 748064 gnulib vfprintf returns desired (not actual) number of bytes, ignores errors + 752240 Add DTLS support to GIO + 755421 GDBus ignores NO_REPLY_EXPECTED flag in messages, leading to warnings on system bus + 756875 Include ntdef.h for NTSTATUS + 759554 g_application_run() calls g_main_context_default() repeatidly + 760199 gsettings: Install gettext ITS rules + 760215 G_LIKELY/_UNLIKELY macros need more parentheses + 760683 regex test: Check the expected PCRE exceptions at runtime + +Translations updated: + Brazilian Portuguese + Czech + German + Lithuanian + Swedish + +Overview of changes in GLib 2.47.4 +================================== + +* The GApplication documentation has been improved in several areas. + +* Bugs fixed: + 749092 gdb pretty-printers fail on Python 3 with a TypeError... + 757374 macros: clean up "inline" mess + 758641 Memory leak in g_dbus_proxy_new_for_bus_sync() + 759134 Add missing checks for gnulib vasnprintf() + 759408 Do not use uninitialized var + 756475 Stop supporting non-POSIX getpwuid_r, getgrgid_r + 757372 GApplication: destroy the impl on shutdown + 728099 macros: add G_GNUC_CHECK_VERSION() for compiler checks + 757299 glib-compile-resources: do not leak c_name + 758553 Fix gettext use + 758823 file monitors: reorder some code to avoid segfault + 756214 gsettings: Don't translate "" + 710243 Add GParamSpec object ref management annotations + 735696 xdgmime: Finer handling for cases where mmap() is not available + 752983 gapplication: Acquire the main context before running + +* Translation updates: + Swedish + + +Overview of changes in GLib 2.47.3 +================================== + +The inline cleanup in the last release accidentally removed three +symbols from libglib-2.0.so. It is unlikely that this will have caused +any problems because these symbols were only backup symbols for +definitions exported as inlines in the header files, but ABI is ABI. + +This release corrects only this problem. + +Overview of changes in GLib 2.47.2 +================================== + +* We have formalised the assumption that all compilers that are + interested in support 'static inline' and simplified the macros around + this considerably. Please watch for and report unintentional fallout. + +* New API: hardware-assisted helpers for overflow-checked integer math. + +* other fixes + +Bugs fixed: + 696324 gtester-report doesn't work with Python 3.x + 719966 glib: Add missing (nullable) and (optional) annotations + 752837 gobject and glib-compile-resources rely on .CRT$XCU section, no longer works with Win 10 UCRT (VS 2015) + 755364 make gtkdoc-check happy again + 756134 Segmentation fault on calling g_simple_action_group_add_action with bad action constructor call + 756179 gwin32.c: Replace VerifyVersionInfoW() with RtlGetVersion() due to API deprecation + 756988 GSequence should document each function's complexity + 757294 Move G_POLLFD_FORMAT to glibconfig.h + 757374 macros: clean up "inline" mess + 757451 doc: fix g_task_attach_source() example + 757628 gio tests fail to build when cross compiling 2.46.1 + 757693 Invalid free in g_local_file_trash() + 757742 Fix up annotations in ghash.c + 758181 GTask: fix wrong example code + +Translations updated: + Greek + Hebrew + Hungarian + Norwegian bokmÃ¥l + Portuguese + Scottish Gaelic + Simplified Chinese + Spanish + +Overview of changes in GLib 2.47.1 +================================== + +* The Unicode support has been updated to version 8.0 of the Unicode standard + +* GDesktopAppInfo no longer sets the DISPLAY environment variable when + launching apps. This is now done in the GAppLaunchContext implementations + when appropriate + +* Bug fixes: + 664740 Key-value file parser, space after integer + 687223 cleverer GThreadPool management + 692085 stderr and stdout are not always file descriptors 1 and 2 + 697907 Add interface for socket-like things (GSocket, DTLS, etc) + 735754 Implement close on TLS GOutputStream + 737116 Add functions to print GSocketConnectables and addresses as strings + 743011 Minor additions to GError documentation + 749161 undefined reference to `__imp__stat32i64' + 749314 Cannot restore a just-trashed file + 751924 Add recvmmsg()-like API on GSocket + 752240 Add DTLS support to GIO + 752837 gobject and glib-compile-resources rely on .CRT$XCU section, no longer... + 753310 Remove `#pragma GCC system_header` from gmessages.h + 753935 Update example namespace and class names in GObject tutorial + 754855 Object instantiation documentation refers to example that no longer ex... + 754983 Wayland: g_desktop_app_info_launch_uris_with_spawn() forces DISPLAY va... + 754994 g_date_time_get_second () sometimes returns an off-by-one result + 755083 Clarify in G_ADD_PRIVATE that it is safe to call _get_instance_private... + 755351 Example still contains g_autoptr(gchar) + 755355 Move GStrv to glib.h so it can be used with g_auto() + 755374 g_variant_get_child(): flatten-first logic on '&' + 755496 glib 2.46 fails GStreamer test suite + 755609 glib 2.46.0 breaks Sun Java JVM 1.8.0.60 + 755766 gvalue: The g_auto cleanup function assert if value is G_VALUE_INIT + 755795 2.46 considers empty files as octet-stream rather than text (leads to... + 755961 Fix up annotations in gbytes.c + 756053 MSVC doesn't understand the symbol 'msghdr' + 756054 MSVC linker error due to 'g_socket_send_message_with_timeout()' + 756077 testutils: remove internal ABI comment + 756099 g_main_context_query(): Annotate @n_fds as (in) parameter + 756139 musl: ctors called in the wrong order + 756179 gwin32.c: Replace VerifyVersionInfoW() with RtlGetVersion() due to AP... + 756251 The documentation of G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is confusing + 756255 GOutputStream swallowing errors in splice with G_OUTPUT_STREAM_SPLICE... + 756316 GSequence should provide fast api to check if empty + 756382 snprintf used on Windows with VS2015 doesn't support %n + 756477 gio/gthreadedresolver.c has outdated copy of bionic headers (for android) + 756550 gtypes.h: Make G_MININTn literals negative + 756875 Include ntdef.h for NTSTATUS + 756952 giomodule: return a copy of module name + +* Translation updates: + Basque + Czech + Serbian + Serbian Latin + Vietnamese + + +Overview of changes in GLib 2.46.0 +================================== + +* GTask no longer imposes a fixed limit on the number of tasks that + can be run_in_thread() simultaneously, since doing this inevitably + results in deadlocks in some use cases. Instead, it now has a base + number of threads that can be used "for free", but will gradually + add more threads to the pool if too much time passes without any + tasks completing. + + The exact behavior may continue to change in the future, and it's + possible that some future version of GLib may not do any + rate-limiting at all. As a result, you should no longer assume that + GTask will rate-limit tasks itself (or, by extension, that calls to + certain async gio methods will automatically be rate-limited for + you). If you have a very large number of tasks to run, and don't + want them to all run at once, you should rate-limit them yourself. + +* Disable runtime-deprecation warnings + +* Fix marshalling of flags on bigendian 64bit architectures + +* Translation updates + Brazilian Portuguese + Danish + German + Latvian + Russian + Turkish + + +Overview of changes in GLib 2.45.8 +================================== + +* utf8 validation and utf8-to-ucs4 conversion are faster + +* Small speedups to property change notification + +* Various other small optimizations for GQuark, GData + +* Bugs fixed: + 696426 GParamSpecTypeInfo do not need to be static + 735429 Cleanup MSVC Project Files Generation + 738504 Optimize UTF-8 decoding by unrolling branches and expressions + 742903 Add missing (transfer) annotation to GString + 748633 g_set_object order of operations + 754431 Fix build of glib/gstrfuncs.c on Windows + 754560 gioerror: Add more mappings for WinSock error codes + 754582 Glib cannot compile + 754601 Make g_strerror work with non-glibc POSIX systems + 754636 tests/unicode-encoding test fails for glib 2.45.7 on x86-64 + 754788 more g_strerror stuff + 754831 autocleanups: Add GString type + 754924 Improve test coverage of g_utf8_validate() by added known-... + 754986 Avoid unnecessary signal emission during draw + +* Translation updates: + Italian + Kazakh + Korean + Lithuanian + Slovenian + Swedish + + +Overview of changes in GLib 2.45.7 +================================== + +* Add G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE for use by non-POSIX-like + backends (e.g. cloud storage). + +* GFileMonitor: Make the inotify backend work with atomic renames again + +* GSettings: change notification is again working unconditionally + +* GListStore has a sort function now + +* Test infrastructure: + - Tests are now required to have unique names + - TAP support has been improved + - A macro for asserting that two memory regions have identical content + has been added + +* Bugs fixed: + 708525 A "g_file_query_info" on the file path "/sys/kernel/debug/hid"... + 742849 inotify: send paired events to both sides + 744060 Update GObject tutorial documentation to use G_DECLARE_FINAL_T... + 747364 Fix GError leak in g_file_query_writable_namespaces() + 749492 Support file creation time on FreeBSD and NetBSD + 752769 (g_socket_receive_message | g_socket_send_message) performance + 753745 glib-genmarshal still needed for cross-compilation + 754152 Add g_list_store_sort + 754211 Memory leak in g_file_enumerator_iterate () + 754264 GLib 2.44 certificate chain construction fails if the PEM incl... + 754283 gtestutils: add g_assert_cmpmem() + 754284 gtestutils: print the TAP test plan first, not last + 754286 misc gtestutils fixes + 754307 size of array '_GStaticAssertCompileTimeAssertion_3387' is neg... + + +* Translation updates: + Chinese (Taiwan) + French + Galician + Greek + Hebrew + Hungarian + Indonesian + Polish + Portuguese + + +Overview of changes in GLib 2.45.6 +================================== + +* Fix a test failure and a build failure + +Overview of changes in GLib 2.45.5 +================================== + +* GNetworkMonitor now provides information about metered networks + +* g_mem_set_vtable has been deprecated; it has not been working for + quite a while. The recommendation is to use valgrind, or replace + malloc itself. + +* Bugs fixed: + 656325 Make GDBusInterfaceVTable binding friendly + 741779 Documentation tweaks addressing real-world API misuses + 741822 Fails to build with VS 2015 + 742386 gdbusconnection: Don't g_printerr() when exiting + 743018 gobject: Add more cross-links between documentation pages + 750282 Add g_network_monitor_get_network_metered() to get if the connection... + 751358 GFileMonitor doesn't react to "mv some-file watched-file" + 751592 Stop using GMemVtable + 751598 Stop 'handle-local-options' propagation when callback reports an err... + 751610 g_str_hash produces collisions with strings of length 2 + 751751 Wrong docs of g_async_queue_remove + 752210 gdbus command crashes with SIGSEGV + 752656 gdbusconnection: Fix signal subscription documentation + 752767 Fix typo in g_hash_table_replace() documentation + 753278 gdbus: Don't use g_assert_no_error() GDBusObjectManagerServer + 753285 g_menu_item_set_icon fails if called with NULL icon + +* Translation updates: + Catalan + Czech + French + Indonesian + Lithuanian + Norwegian bokmÃ¥l + Slovak + Spanish + Thai + Turkish + + +Overview of changes in GLib 2.45.4 +================================== + +* Bugs fixed: + 727829 win32: glibconfig.h.win32 updates + 741901 Clang cannot know that g_error don't return + 746339 GSocket kills process when fd is not a socket + 747676 gio/tests/socket fails: test_fd_roundtrip + 748610 Some tests fail with non-English locales + 749911 g_inet_address_to_string broken on XP/2003 + 749912 g_inet_address_new_from_string broken on XP/2003 + 750625 Should dismiss Software Updates Available notification after... + 750807 G_BREAKPOINT doesn't work as intended on Darwin + 751160 gtask does unnecessary work + 751672 -Wduplicate-decl-specifier in glib/tests/keyfile.c + 751731 GFile/DirectoryMonitor emit move events with other_file=NULL + 751737 gio/tests/appmonitor test fails in 2.45.3 + 751798 Wrong enum type used in some test-cases + 752089 make gsocketservice::active a property + 752293 small cleanup: use list_free_full + +* Translation updates: + Greek + Hebrew + Portuguese + + +Overview of changes in GLib 2.45.3 +================================== + +* Improve performance of g_signal_handler_disconnect for signals + with many handlers + +* GDBus has gained a new call flag to allow interactive authorization + +* GSettings: + - New API: g_settings_schema_list_keys + - Deprecated: g_settings_list_keys + +* OS X: + - Implement GNotification + - Bump the OS X requirement to 10.9 + +* Windows: + - Add registry reading API + - Reimplement GAppInfo using registry information + +* Bugs fixed: + 666831 Support URI opening on W32 + 728489 property action with inverted boolean state + 730168 Incorrect annotation on g_action_group_get_action_state_type return... + 733325 Several regex tests fail with pcre3 8.35 + 734888 GLib has no helper functions to work with W32 Registry + 737009 signal handler lookup doesn't scale + 738185 Misleading language about "file name encoding" in the docs on g_env... + 738504 Optimize UTF-8 decoding by unrolling branches and expressions + 739122 glib not handling -1 return ("no limit") from sysconf (_SC_THREAD_S... + 739424 gnome-shell crashes when files are added, deleted, or modified in $... + 739616 DBus; Add new call flag to allow interactive authorization + 740308 Add g_settings_schema_list_keys() method + 740516 RFE: please provide an introspectible version of g_log_set_handler + 741788 Document GSettings build system integration + 745013 GBinding not thread safe + 747146 Implement GNotification on OSX + 747941 try XDG_RUNTIME_DIR/bus before falling back to X11 autolaunch (dbus... + 748727 Filechooser dialog shows no icons for directories on W32 + 749693 GActionGroupExporter: flush queue on requests + 750203 GNetworkMonitorNetlink hangs in user namespace + 750322 gapplication: Make sure --help output is translated + 750344 GTlsInteractionClass is missing from doc + 750369 Various GBinding cleanups + 750386 Race condition in g_io_condition_get_type + 750399 Typo "equilalent" in glib documentation's glib-Error-Reporting.html... + 750573 GTlsDatabaseClass is not documented + 750918 genmarshal: silence register storage class warnings + 751122 gsocket: avoid unnecessary g_socket_cond_wait() in _send_messages() + 479730 The "g_key_file_set_comment" interface prepends '#' character to... + +* Translation updates: + Hungarian + Spanish + + +Overview of changes in GLib 2.45.2 +================================== + +* Improve error reporting in glib-compile-schemas. + +* Add introspection annotations to GListStore. + +* Bugs fixed: + 696749 win32 : failed to compile because of careless mistake in the code + 723394 const parameter to GtkPopover gtk_popover_set_pointing_to + 724113 gdbus-connection-loss test can fail on slow machines + 725981 tap-driver.sh: internal error getting exit status + 733325 Several regex tests fail with pcre3 8.35 + 744895 Unknown or unsupported transport 'this-should-not-be-used-and-will... + 747882 gtype: Bump allowed number of children + 748534 gtest: if a subprocess assertion fails, print its stdout and stderr + 748612 de_DE locale used in option-context test is not supported by FreeBSD + 748614 Double unref in g_socket_listener_add_inet_port + 748834 glocalfilemonitor: Emit notification on rate limit change + 749079 gdbus-peer test: TCP tests can fail with ECONNRESET due to a race... + 749080 gdatetime test: fails if close to rollover between seconds + 749180 gnetworkaddress: add return type annotation to parse methods + 749352 g_binding_unbind() fails when source is also the target + 749353 GBinding does not connect to the detailed notify signal + +* Translation updates: + Catalan + French + Slovak + Thai + + +Overview of changes in GLib 2.45.1 +================================== + +* The GSettings schema compiler, glib-compile-schemas has been changed + to reject schema xml that has duplicate or + elements. Such elements typically occur when translations are merged + into the schema, with xml:lang attributes. This is not the correct + way to translate schemas. Instead keep the translations in the .mo + file and set the gettext-domain attribute on the element. + +* The file monitoring infrastructure has been rewritten, and all backends + have seen major improvements. + + The inotify backend is reporting events with less delay (no event will + be delayed more than 10ms) and wakeups due to file monitoring have been + significantly reduced. A CHANGES_DONE event will also be sent when new + files appear. + + The poll implementation is now using the thread default main context. + + The fam implmentation is now running in the worker thread. + + The fen implementation has been removed, since it was unmaintained. + +* The GSettings schema compiler, glib-compile-schemas, is more strict + about rejecting schemas with xml:lang style merged translations. + Schema translations should be done by specifying the gettext domain + in the xml, and keeping the translations in gettext. To avoid breaking + already-installed schemas, this change is only taking effect when + you use the --strict option. + +* The hardcoded 10-thread limit of GTask's thread pool has been removed, + since it was prone to causing deadlocks. The thread pool is now allowed + to grow dynamically and will shrink back over time. + +* GSimpleAsyncResult has been deprecated in favor of GTask. + +* The algorithm used by GAppInfo to find default handlers for mime types + has been tweaked to prefer apps that handle the specific subtype over + default handlers for a generic supertype. + +* Bug fixes: + 627285 inotify file monitor hardwired delay + 631597 Segmentation fault in append_escaped_text + 661767 merge/improve various bits of run-in-thread functionality + 687223 cleverer GThreadPool management + 711547 win32: silence some build warnings + 719966 glib: Add missing (nullable) and (optional) annotations + 726447 Possibly an error in text string + 728663 W32: wrong stat struct is used when built with MinGW-w64 + 728669 W32: GLocalFile can't measure size of files larger than 2^32... + 730188 gsocket: Document FD ownership with g_socket_new_from_fd() + 733325 Several regex tests fail with pcre3 8.35 + 738207 Add a way to set SO_SENDBUF and SO_RECVBUF on listener (and... + 739850 GClosure: add valgrind hints + 741791 gmain: Save errno when handling unix signals + 744282 gvfs-open for application/x-virt-viewer changed behaviour bet... + 745255 Add support for copying sessions between GTlsClientConnections + 745745 gdbus: fix out-of-bound array access + 745821 Don't use __alloc_size__ attribute with clang + 746749 GLib-GIO:ERROR:inotify-kernel.c:327:ik_source_dispatch: ass... + 746753 Glib-compile-resources --generate-header not using ".h" as ... + 747209 glib-compile-schemas ought to reject repeated and... + 747349 Conversion of gdbus to use GTask causes deadlocks + 747363 gatomic: Add missing new line in API doc comment + 747472 Don't ignore already-installed schemas with multiple --help doesn't work even when options were added + 740309 Fix docs in g_strfreev + 740413 Fix the GSettings Registry Backend + +* Translation updates: + Norwegian bokmÃ¥l + + +Overview of changes in GLib 2.43.0 +================================== + +* GObject gained a debug option to provide instance counts. To use it, + set GOBJECT_DEBUG=instance-count and call g_type_get_instance_count(). + +* GOption now has a strict POSIX mode in which it stops parsing arguments + as soon as a non-option argument is encountered. + +* Bugs fixed: + 354457 Feature Proposal: Per-Type Statistics for Instantiable GTypes + 695082 g_hash_table_remove_all is not save against a call to g_hash_table_remove + 723160 GOption: add strict posix mode + 728256 gcredentials: add NetBSD support + 729739 tlscertificate: add support for loading certificate chains + 733338 Don't segfault in GNetworkMonitor when IPv6 support is unavailable + 736273 gdesktopappinfo: Use symbolic names in the code + 736284 Keep only one list of signal emissions + 736806 gtask: Fix reference count loop causing leaks + 736914 Docs: various fixes and improvements + 737143 Include in glib/valgrind.h + 737259 gcancellable: Clarify that GSources hold references to GCancellables + 737338 gmain: Unref child sources when finalising a GSource + 737446 tests: Fix some minor leaks in the unit tests + 737451 Provide api to read_all_async + 737741 g_datalist_id_get_data assertion fails for non-existant keys + 737869 GApplication command line handling breaks --help + 738170 g_byte_array_new_take() doesn't initialize array->alloc + 738197 g_cond_timed_wait() doesn't time out on Mac OS X + 738374 gfile: g_file_equal (x, x) is TRUE + 738675 GSubprocessLauncher is missing some data on the docs + +* Translation updates: + Bengali (India) + Bulgarian + Gujarati + Italian + Telugu + + +Overview of changes in GLib 2.42.0 +=================================== + +All changes in this release are trivial in nature. + + - introspection warning fixes + + - g_application_add_main_option now uses an enum instead of an 'int' + for the type of a parameter + + - added a G_OPTION_FLAG_NONE so that people don't need to use 0 + + - gresource: Use GError in more places + + - gresource commandline tool: improve extraction from multiple sections + + - GSource now takes the context lock (if any) in g_source_set_name() + + - new documentation to clarify the use of some APIs related to + GVariant, GSource, GApplication + + - other minor updates to docs + +* Bugs fixed + 736683 Thread safety issues with g_main_context_find_source_by_id + 736975 [patch] please document that GVariant serialization needs an + out-of-band length field + +* Translation updates + Danish + Hindi + Marathi + Punjabi + Serbian + Simplified Chinese + +Overview of changes in GLib 2.41.5 +================================== + +* Bug fixes: + 735819 single native credential struct used for two purposes + 735915 glib-building.html uses --enable-gcov instead of --enable-coverage + 736350 GDesktopAppInfo: avoid polling on missing desktop dirs + 736351 Don't use issetugid() on Android + Fix the default application logic in GDesktopAppInfo + 736458 Only use rand_s() when targetting Visual Studio >= 2005 + +* Translation updates + Galician + Hungarian + Indonesian + Kannada + Latvian + Polish + Russian + Slovenian + Tamil + + +Overview of changes in GLib 2.41.4 +================================== + +* GApplication now has binding-friendly API to handle + commandline options: g_application_add_main_option + +* G_GNUC_BEGIN_IGNORE_DEPRECATIONS works with clang + +* Bugs fixed: + 583330 poll list of mounted file systems (no mtab support) + 727455 Command line option parsing from bindings + 734126 add G_GNUC_BEGIN_IGNORE_DEPRECATIONS macro for clang + 735179 gsocketclient: Handle cancellation between CONNECTING... + 735297 Docs claim that GThread struct is deprecated + +* Translation updates: + Assamese + Catalan + Catalan (Valencian) + Czech + French + German + Greek + Hebrew + Korean + Oriya + Traditional Chinese + + +Overview of changes in GLib 2.41.3 +================================== + +* g_clear_pointer and g_clear_object no longer use atomics + +* Bugs fixed: + 711547 win32: silence some build warnings + 725511 Compiled resource files should have the same /-separators everywhere + 725513 Some tests fail to build on W32 + 725514 W32: gfileutils does not preserve errno correctly + 725515 test-printf fails on W32 + 728730 gsocket: Set SO_NOSIGPIPE on sockets on Darwin + 729703 Leaks a GError in g_file_move + 730932 statically assert that reasonable assumptions about enums are true + 732085 gtype: Fast-path for g_type_is_a + 732754 GDBusMessage: optimise (de)serialisation of fixed arrays + 733345 ginetaddress: Add a precondition to g_inet_address_new_from_string() + 733576 Patches from static analysis run on 2.40 + 733715 glib's configure.ac makes accidentally use of nested function + 733934 win32: improve the package installation dir lookup + 733960 W32: spawning a console process creates a new window when stdout... + 733969 Remove atomic aspects of g_clear_pointer/object + 733982 Do not crash when checking whether an instance type is of a given... + 734035 gedit hangs up when there's no GSettings key in the registry + +* Translation updates: + Basque + Brazilian Portuguese + Lithuanian + Slovenian + Spanish + + +Overview of changes in GLib 2.41.2 +================================== + +* The Unicode support has been updated to version 7.0 + of the Unicode standard + +* GNotification now supports priorities for notifications + +* GCredentials has gained NetBSD support + +* GMutex now uses a faster, native implementation on Linux + +* Bugs fixed: + 699132 Pluggable event loop backends + 720708 g_assert_warning(): number of arguments doesn't match for... + 722092 Add GtkApplication resources support + 724986 Change gio/data-to-c.pl to /usr/bin/env perl. + 727974 Fix up failure-to-see-expected-message logging + 728256 gcredentials: add NetBSD support + 728401 GDateTime: Add guards to g_date_time_new() + 729825 Formatting of g_alloca documentation + 729914 instead of DEBUG_CODE and IF_DEBUG, provide a common macro... + 730293 clang++-3.4: error: 'register' storage class specifier is ... + 731339 giochannel: avoid setting uninitialised length + 731424 #ifdef spaghetti for load_user_special_dirs() implementations + 731623 GNotification: add support for a priority setting + 731929 update tables to unicode 7.0.0 + 731950 gvalue: New g_value_from_instance + 731986 GLib: implement GMutex natively on Linux + 732184 GObject: warn on use of deprecated properties + 732357 Docs: various fixes and improvements + 732429 GActionEntry: improve documentation + 732465 Fix build on x64 Visual C++ builds + 732704 Docs: various fixes and improvements + 732739 ginetsocketaddress: Explicitly initialise flags for getaddr... + 732754 GDBusMessage: optimise (de)serialisation of fixed arrays + 732984 g_object_ref(NULL) in g_dbus_object_manager_client_finalize + 733084 Typos in g_bytes_hash() and g_time_zone_find_interval() docs + 733146 spawn helper does not use correctly the parameters + +* Translation updates: + Lithuanian + + +Overview of changes in GLib 2.41.1 +================================== + +* Bug fixes: + 697229 Custom Interface implementations will be broken with glib 2.37/38 + 698614 GObject: prevent installing properties after init + 729269 gvariant: Fix confusion between type and format strings in the docs + 730198 broken valgrind.h leads to crashes in g_type_free_instance on mingw64 + 730807 GMutex performance regression + 730963 gconvert: mention that the g_convert len should be in bytes + 730984 Faster instance type check for fundamentals + 731050 tags appear in documentation + 731200 unconditional 'notify' during g_object_set() is problematic + 731335 gtype: guard uses of new fundamental type check + 731341 gparam: change value of G_PARAM_EXPLICIT_NOTIFY + 731366 run-assert-msg-test.sh gdb leaves assert-msg-test zombie + 731425 giomodule protects function-call with different token than function... + 731513 clang: build failure: implicit declaration of function '__atomic_load_4' + 731584 gbookmarkfile: Cleaner error handling code to pacify static analysis + 731657 Prevent an invalid @CARBON_LIBS@ from appearing in the .pc files + 731979 docs: Correct param to interface's default_init() + 731996 Return folder as icon for directories + 732002 gwakeup: Clarify buffer sizing in g_wakeup_signal() + 732005 Remove unused assignments + 732019 gtestdbus: Don’t close stdout for dbus-daemon + 732068 gsignal: Add an example to the g_signal_connect_swapped() documentation + 732081 gsocket: Document that g_socket_create_source() holds a socket ref + 732107 gsocketlistener: Reconsider closing sockets on listener finalisation + + +Overview of changes in GLib 2.41.0 +=================================== + +* Many bugfixes found by static analysis, including potential fd leaks + and NULL pointer dereferences. + +* Increased use of (nullable) attribute on out values and return types + now that it is supported (mostly from porting Vala metadata). + +* use XDG_CURRENT_DESKTOP for OnlyShowIn/NotShowIn handling of desktop + files, deprecating g_desktop_app_info_set_desktop_env() + +* add support for g_desktop_app_info_get_implementations() to find + desktop files that have an Implements= line for a given interface + +* GHmac has gained SHA-512 support + +* support the new mimeapps specification (most notably, moving the + assoications/defaults configuration to ~/.config/mimeapps.list). + +* libgobject is now linked -Wl,-z,nodelete when possible to avoid errors + when gobject is used from a module for a program that does not itself + use gobject and that module is unloaded/reloaded + +* ... and many other bug fixes. + + 623552 glib warns if backtrace.py is not present + 667468 glib-2.30.2: ipv6 tests fail when no ipv6 support is available + 668152 -framework Carbon linker flag not passed to pkg-config .pc files + 707298 libgobject should be linked with -Wl,-z,nodelete + 712391 Add g_desktop_app_info_get_implementors() + 722723 Infinite recursion when calling g_io_stream_close_async() from libsoup + 724741 hmac: Fix support for SHA-512 in GHmac + 726040 networkaddress: fix parsing of uri with @ after authority + 726318 gio: Document that GSocket is not thread safe + 726611 socketclient: Leak on cancellation + 726872 gio: Add names to idles and timeouts + 727119 wrong IN6_IS_ADDR_MC_LINKLOCAL usage break android build + 727123 GNotification: Some small documentation fixes + 727320 docs: Remove escaping '\' from literals + 727551 Check use_count of GApplication in g_application_release() + 727559 g_file_copy: Don't set GError when we intend to ignore errors + 727692 gio/gtlscertificate.c -- broken PEM-file processing (affects local CA root stores, for starters) + 727890 soup_content_sniffer_real_sniff segfault + 727900 gio: Add newer dbus UnknownXxxx and PropertyReadOnly errors + 727928 gapplication-tool fixes + 727939 INTLLIBS are always appended in configure checks + 727964 g_io_extension_point_get_extension_by_name: Warn, but don't crash, for NULL inputs + 728040 Implement new mimeapps spec + 728066 Deal with startup notify id being NULL + 728280 platform_get_argv0: fix sysctl(3) use on OpenBSD + 728285 docs: Use markdown links in .h files, too + 728350 gaction: Minor clarifications in the GAction documentation + 728380 docs: Remove comment before plural s + 728565 gfile: More explicitly document the context for GFileProgressCallback + 728983 Docs: various fixes and improvements + 729167 gobject: Document that classes/objects/interfaces are zero-filled + 729563 GOption: A short option's value is included in G_OPTION_REMAINING + 729813 AppInfo: use XDG_CURRENT_DESKTOP for OnlyShowIn + 729875 gio: cleanup gdbusmessage.c file + 730045 Avoid overeager warning about deprecated properties + 730189 gtestutils: Fix a very unlikely FD leak in test fork handling + 730190 gsocket: Add missing preconditions to g_socket_send_message() + 730277 gthread: Fix use of a local variable after it went out of scope + 730278 gsubprocess: Add a missing va_end() call + 730295 gdbus-tool: Remove dead variables + 730493 Port annotations from Vala metadata + +Translations updated: + Basque + Brazilian Portuguese + Catalan + Czech + Danish + Greek + Hebrew + Hungarian + Punjabi + Serbian + Slovenian + Spanish + Ukrainian + +Overview of changes from GLib 2.39.91 to GLib 2.39.92 +===================================================== + +This is a release candidate for 2.40.0. + +* g_test_run() no longer runs tests in exactly the order they are + registered; instead, it groups them according to test suites (ie, + path components) like the documentation always claimed it did. In + some cases, this can result in a sub-optimal ordering of tests, + relative to the old behavior. The fix is to change the test paths to + properly group together the tests that should run together. (eg, if + you want to run test_foo_simple(), test_bar_simple(), and + test_foo_using_bar() in that order, they should have test paths like + "/simple/foo", "/simple/bar", "/complex/foo-using-bar", not + "/foo/simple", "/bar/simple", "/foo/using-bar" (which would result + in test_foo_using_bar() running before test_bar_simple()). + + (The behavior actually changed in GLib 2.36, but it was not + documented at the time, since we didn't realize it mattered.) + +There are no major changes in this release, but a few serious bugs have +been fixed. + +* Bugs fixed: + 710367 Crash in g_settings_backend_dispatch_signal() + 723899 G_DEFINE_TYPE() causes compiler warnings with clang due to foo_get_instance_private + 724859 Let the test_wait_until() test also run on non-*nix + 724916 gio unmount code makes XFCE's Thunar crash + 725651 GSubprocessLauncher: Does not copy the calling process environment. + 725656 Unskip GVariantDict + 725891 gio tests: add codegen to BUILT_SOURCES + 726046 Recent commit created symbolic icons issues + +* Translations: + Chinese + French + Korean + Latvian + Norwegian bokmÃ¥l + Portuguese + Russian + Traditional Chinese + +Overview of changes from GLib 2.39.90 to GLib 2.39.91 +===================================================== + +This release introduces a hard dependency on present and functioning +clock_gettime() and CLOCK_MONOTONIC. It also introduces a dependency on +pthread_condattr_setclock() unless your system happens to have +pthread_cond_timedwait_relative_np() (as do Mac OS and Android). This +release is known to be broken with at least GNU/Hurd, pending addition +of working pthread_condattr_setclock(CLOCK_MONOTONIC) there. + +New API: g_str_to_ascii() + +* Fixed bugs: + 670144 unconditional use of CLOCK_MONOTONIC is broken + 673607 invalid assumption in g_cond_wait_until() / g_get_monotonic_time() API + 710142 Add more impressive transliteration to GLib + 722360 make check fails + 722604 (partial) Various tests are failing with 2.39.3 + 723316 g_hash_table_iter_remove() should be explicit whether or not it is safe while iterating the table + 724609 Fix build of GIO on Windows + 724687 gmain: make monotonic time really monotonic, everywhere + 724706 gsource: document priority of child sources + 724707 some GSocket source improvements + 724839 GMainContext: some source ID cleanups + 724858 Dist gtranslit-data.h + 724994 Missing icons for bookmarks in file chooser + 725023 Can no longer find apps by executable/desktop file name + +* Translations: + Lithuanian + Polish + Thai + +Overview of changes from GLib 2.39.4 to GLib 2.39.90 +==================================================== + +* Fixed bugs: + 625408 make GVariant dictionaries more useful + 660809 document that if you fail a precondition check, documented guarantees do not apply + 661576 fix handling of constructors that destroy half-constructed objects + 679957 g_inet_address_new_from_string is not able to handle dots and numbers IPv4 addresses + 712837 gvariant: Document the need to cast varargs when constructing GVariants + 721458 g_simple_async_result_is_valid has a NULL check for the wrong source_tag + 721977 improve split handling of command line arguments + 722033 win32: fixup lib.exe invocation + 723422 Fix g_socket_get_available() with TCP on Windows + 723616 gio/tests: fix race when generating code + 724001 gsubprocess: Fix a broken link in the documentation + 724124 glib/tests/collate.c fails if no en_US locale + 724126 intermittent GApplication test failure: /gapplication/local-actions: lines of output permuted + 724233 gsocketservice: Note g_socket_listener_close() for closing open sockets + 724239 soup_session_queue_message - Connection terminated unexpectedly + 724278 gsocketconnection: Document closing connections with g_io_stream_close() + 724330 configure.ac: tweak inotify check + 724385 gtestutils: make the new assert messages more detailed + 724401 gsubprocess: Mutex leak + 724417 glib master build broken on OpenBSD + 724434 Build failure in gio/gresolver.c + +* Updated translations: + Brazilian Portuguese + Galician + Indonesian + Italian + Kannada + Norwegian bokmÃ¥l + Spanish + Thai + +Overview of changes from GLib 2.39.3 to GLib 2.39.4 +=================================================== + +* Fixed Bugs: + 139699 Correction for g_main_context_unref() + 583036 g_strchomp and g_strchug are not declared const + 683388 improve documentation for application developers + 685204 ./configure fails to add the '-g' flag to CFLAGS + 688406 GStaticMutex broke ABI on at least ARM EABI during 2.31.x + 693299 cannot compile on Solaris: error in gbitlock.c + 707111 Clarify type transformability and compatibility + 711547 win32: silence some build warnings + 719344 Fix the various test programs (or GLib itself) on Windows + 722025 cleanup/clarify command line argument encoding on Windows + 722323 remove unused include 'gslist.h' in 'gbookmarkfile.c' + 722326 gstringchunk: Use g_slist_free_full() where possible + 722357 gio: fix small memory leak on local xattr + 722436 Adjust doc to Makefile.decl renaming + 722503 GSimpleAction: add default activate handler + 722526 glib/deprecated/gthread.h error on FreeBSD + 722591 [documentation] broken link to GtkAction from GAction.html + 722973 Broken example in GApplication reference + 723048 'network-access' test can fail to guess interface index + 723360 gmain: Note that g_source_destroy() can be called multiple times + +* Updated Translations: + Assamese + Tamil + Traditional Chinese + + +Overview of changes from GLib 2.39.2 to GLib 2.39.3 +=================================================== + +No major changes this release -- mostly lots of small fixes and +improvements in test coverage. + + * fix a crasher in code from gdbus-codegen + + * improvements to gobject gdb helper script + + * portability: + + - fix a deadlock issue with kqueue on FreeBSD + + - work around a quirk in the sunstudio compiler + + - rename a variable to avoid clashing with a macro definition of + 'environ' on some platforms (like mingw) + + - use POSIX-specified over + + - many improvements to Visual Studio projects and and some build + fixes for Windows + + * tests + - a very large number of improvements in test coverage + + - don't report skipped tests as failures + + - return 77 if we skip all tests in an executable + + - improve gtest documentation and fix some minor issues + + - fix g_test_trap_reached_timeout() return value + + - remove some dead code uncovered during test coverage expansion + + - Use tap mode for installed tests too, when using tap + + * fix races in unix signal handling + + * make our GVariant-based commandline tools (glib-compile-schemas, + gdbus, gapplication) print out GVariant parse errors in context + + * GApplication now has a --gapplication-service command line switch to + turn any GApplication into a service + + * improve compatibility of GApplication and GOptionContext + + * fix gsettings.m4 wrt. builddir != srcdir with non-recursive make + + * use a directory monitor in GKeyfileSettingsBackend + + * improve robustness of some GIcon classes + +Bugs fixed + 141251 poll(2) is in , not per SUS standard + 613732 [PATCH] gobject.py: Don't install frame filters when GDB does not support them + 708212 g_variant_parser_error_get_quark() has unexpected name. + 710965 GApplication: add --gapplication-service switch + 711090 periodic failure of spawn-multithreaded async testcase + 712171 gsettings.m4: @GSETTINGS_RULES@: Support srcdir != builddir with nonrecursive make + 712630 Revert "gsettings m4: check for .xml in src/builddir" + 715028 GVariant: add way to print context of parse errors + 719344 Fix the various test programs (or GLib itself) on Windows + 720263 gtestutils: skipping a test should count as success, not failure + 720539 gdbus-codegen: Fix crasher in goa-using apps + 720635 Make gdb pretty-printers compatible with Python3 + 720891 g_settings_get_child does not inherit the backend + 721034 glib 2.38.2 cannot be compiled with SunStudio Compiler under Solaris + 721059 g_subprocess_launcher_set_environ vs "environ" + 721074 kqueue: deadlock + 721087 Missing -lselinux in pkg-config --libs --static gio-2.0 + 721324 Error message is printed to stdout + 721624 Regression in GTest framework reorders existing test cases + 721625 backwards NEWS entry about g_source_remove change + 721796 insufficient escaping in g_dbus_annotation_info_generate_xml() + 721947 Improve GApplication ⇔ GOptionContext compatibility + +Translations updated: + Brazilian Portuguese + Galician + Greek + Hebrew + +Overview of changes from GLib 2.39.1 to GLib 2.39.2 +=================================================== + +* Portability + + - Remove alleged support for OS/2 + + - Remove alleged support for BeOS + + - Remove alleged support for last-millennium Unixes + + - Require C90 compliance + + - Require POSIX.1 (1990) compliance on Unix + + - Require GNU make + +* Bugs fixed: + 113075 support "nonnull" attribute + 159528 g_ptr_array_remove_range() + 307947 The check for growing stack pointer in configure can fail + 607016 docs should mention property notification order + 671557 Fun with integers and g_key_file_load_from_data() + 676761 don't use g_critical for a runtime error + 690525 g_file_replace_contents_async doesn't copy its @conten... + 691608 Support compilation with clang 3.2 + 697585 g_variant_builder_add's doc example is leaking + 697828 g_hash_table_add() should return a boolean + 702862 gdbus-codegen : look for deps in default install path + 703522 Reference leak in GvariantBuilder documentation + 705902 g_get_current_dir() should check PWD env var and retur... + 708274 Added GObject Introspection annotations to genums.c + 710519 Portability schmortability + 710741 some mainloop instrumentation + 710983 Test failures on powerpc + 711047 Enable the build of the various test programs on Windo... + 711051 Add basic test for the GNotification gtk backend + 711088 gbacktrace: Don't close stderr when running gdb + 711103 gmessages: Add g_info macro for G_LOG_LEVEL_INFO + 711178 appinfo test problems + 711546 utf8: report allocation error + 711640 gdesktopappinfo: Rank Keywords matches higher than Gen... + 711751 Fix memory leaks in libglib tests + 711753 gthread-posix: Don't use gslice allocated GRecMutex + 711796 glib-tap.mk: fix to actually use the TAP driver + 711800 fix g_test_set_nonfatal_assertions() + 711801 giomodule: Allow overriding source directory gio modul... + 711805 gdbus-connection: Fix race condition in test + 711806 gtestdbus: Don't destroy GSource twice + 711807 gtestdbus: Properly close server connections + 711871 Broken and misleading configure check for growing stack + 712136 'O_CLOEXEC' undeclared (first use in this function) + 712148 Add system bus support to GTestDBus + 712171 gsettings.m4: @GSETTINGS_RULES@: Support srcdir != bui... + 712314 AIX port: splice(); major()/minor(); libtool library order + 712315 GSettings: More docs for deprecated _list_schemas() + 712393 gobject: Box GMappedFile + 712547 GSocketClient "event" not useful for determining resol... + 715164 Clang static analysis fixes + 719395 GPtrArray add g_ptr_array_insert + 719402 Crashes when startup + 719472 leak in generated proxy-side property-setter + 719687 fix or remove g_trap_object_ref + 719809 Signal connection ids are always > 0 if successful + 719837 gdbus-connection: Work around race in connection tests + 719884 Fix documentation typos in GTask and GCancellable examples + 719979 g_settings_get: check validity of format string + 720080 Truncating a GMemoryOutputStream to a larger size cause... + 720210 gdataset: Remove unused define + 720236 Allow clean simple use of g_test_trap_subprocess() + +* Translations updates: + Italian + Lithuanian + Simplified Chinese + Spanish + + +Overview of changes from GLib 2.39.0 to GLib 2.39.1 +==================================================== + + * GSettings fixes/improvements + + - GSettingsSchema API is now more powerful and consistent + + - new GSettingsSchemaKey API allows accessing metadata for keys: + type, default value, range and the long-awaited support for summary + and description + + - GSettingsSchemaSource gains support for listing schemas within a + source. Deprecate the global API that did this for the default + source. + + - 'gsettings list-schemas' now works properly with --schemadir + + - deprecate a bunch of now-redundant functionality on GSettings + + - add API to GSettings for getting the default value of a key (as set + by the sysadmin) + + - add API to GSettings for determining if the user has assigned a + particular value to a key (ie: we are not just reading the default) + + - ignore qualified tags and attributes appearing in schema files + + * Applications/Actions + + - make GSimpleAction a bit more strict with respect to state changes + that would violate the interface (ie: by changing the state type + after construction) + + - throw an error when attempting to 'Describe' a non-existent action + via D-Bus instead of returning a bogus description + + - throw an error when attempting to invoke unsupported methods on an + Application (eg: 'Open' on an app that doesn't HANDLES_OPEN) + instead of emitting a g_critical() in context of the app (which is + not itself at fault for the errant call) + + * Appinfo + + - substantially rework GDesktopAppInfo to reduce the amount of disk + accesses that are performed in common situations + + - add a new class: GAppInfoMonitor for discovering when applications + are installed/removed + + - add a new g_desktop_app_info_search() API for searching for + installed applications by name, keywords, etc. + + * GMarkup: add new G_MARKUP_IGNORE_QUALIFIED flag for skipping over + "qualified" tags and attributes (those with a colon in the name, such + as 'my:tag') + + * GDBus + + - ignore qualified tags, as above + + - GTestDBus: unset all D-Bus addresses (such as STARTER) to ensure + that test programs don't pick them up + + - add new session_bus_run() convenience in the tests and use it + + * GRand: use real random data as a seed on win32 and use the + timestamp/pid/uid fallback only on UNIX machines where we can't open + '/dev/urandom'. This may cause issues with older mingw32 releases + due to a missing prototype for the rand_s() API. + + * Many win32 (and particularly MSVC) portability fixes. Many + additional tests are now runnable when building with MSVC. + + * Due to early testing of the (soon to land) GCleanup framework, a very + large number of memory errors have been found and fixed (mostly in + the testcases, but some in glib itself). + + * GIO: + + - some more seeking cleanups: particularly on GLocalFileInputStream + + - don't leave a .trashinfo file around if trashing a file fails + + - Add a request_certificate virtual method to GTlsInteraction + +Translations updated: + Assamese + Galician + Greek + Spanish + Tamil + +Bugs fixed: + 635641 schema compiler should ignore unknown attributes + 637257 g_tls_client_connection_gnutls_retrieve_function needs to be able to block + 637956 GKeyfileSettingsBackend should ignore file deletions + 645453 keys from base schema missing from extended schema + 665634 g_dbus_node_info_new_for_xml() errors on unknown attributes in XML files + 668232 Unable to get description and summary for a key + 668233 Unable to determine if a key is set to the default / what the default value is + 680838 Need g_settings_schema_source_get_schemas() + 683017 API for accessing GSettings Schema metadata + 687185 org.gtk.Actions.Describe doesn't return an error for non-existing action names + 687202 If trashing fails, the ".trashinfo" file is not removed + 695558 The --schemadir option has no effect + 696424 GSimpleAction.state property is not right + 697348 GTestDBus should unset DBUS_STARTER_ADDRESS, DBUS_STARTER_BUS_TYPE + 710133 Emit backward compatible code with gdbus-codegen + 710691 glib-networking: locking during implicit handshake + 710738 GRand has lame fallback for Windows + 710859 Typo in gio docs + 710885 Two fixes for GApplication + 710962 error: 'F_DUPFD_CLOEXEC' undeclared (first use in this function) + 710964 Add g_hash_table_get_key_array() + 710991 test: g_debug messages shouldn't affect g_assert_expected_messages + 711016 g_settings_list_keys () segfaults for empty schemas + 711048 glocalfileinputstream.c allows skip past end of file + 711049 Fix build of GLib-GIO 2.39.x on Windows/MSVC + 711064 Adding child source to blocked source can cause a segfault + 711070 Copying a symlink over another one segfaults + 711099 gapplication test failure + 711520 GDesktopAppInfo: allow more than one level of legacy folder prefixes + 711556 Add GAppInfoMonitor + 711557 Add g_desktop_app_info_search() + 711600 trivial portability fix + 711632 The desktop-app-info test fails during make check + 711754 gmain: Fix use of uninitialized memory in sigaction structure + 711755 private: Use threading primitives correctly in private test + 711756 gthreadpool: Don't pass bad data to GThreadPool sorter + 711768 Fix memory leaks in libgmodule tests + 711775 utils: Don't free memory owned by glib in test + 711782 boxed: Fix double free in boxed unit tests + 711803 gsubprocess: Fix a number of leaks and a segfault + 711808 gtestdbus: Fix leak of GMainLoop + +Overview of changes from GLib 2.38.0 to GLib 2.39.0 +==================================================== + + * prep for the 2.40 series (version macros, docs index, etc.) + + * GNotification + + - new API for sending persistent notifications via the desktop shell + + - notifications persist when the application has quit and clicking on + them can restart the application with an action (via + DBusActivatable) + + * GSubprocess + + - new API for launching subprocesses + + - nice GIO integration like async functions, cancellability, etc. + + - a convenient communicate() API inspired by the same API in Python + + - related: the gspawn API now has a CLOEXEC flag for the created + pipes for stdin/stdout/stderr + + * New gapplication(1) commandline tool + + - intended to be used with DBusActivatable apps + + - can be used for launching apps, opening files, invoking application + actions and listing apps and actions + + - bash tab completion is supported + + * GDesktopAppInfo changes: + + - g_file_get_path() can implicitly cause a FUSE mount so don't call + it until we know we need it (for an app that doesn't support URIs) + + - don't crash when trying to load from a keyfile with + DBusActivatable=true + + - remove some dead code, refactor the search path handling a bit and + do a large-scale whitespace cleanup (prep work for the pending + desktop file index) + + * File monitors + + - fix broken handling of mount point monitoring + + - remove some strange use of GObject::constructor() from the base + class and inotify backend + + - fix GFileMonitor to work in the non-default main context even when + the main context is not running (or is blocked) + + - add internal private API for easily creating a file monitor in the + GLib worker thread + + * GSettings + + - g_settings_list_children: only list viable schemas. This fixes a + longstanding issue where 'gsettings list-recursively' will crash + when there are invalid schemas installed + + - don't accept invalid paths on g_settings_new_with_path, etc. + + * GIO + + - GFile now has a thumbnail::is-valid attribute to check if the + thumbnail in thumbnail::path needs to be regenerated + + - GDBusProxy now has a flag to control autostarting of services at + construction time + + - for GSeekable, properly introduce the concept of "resizable" vs. + "fixed-sized" streams in the docs, explaining the expected + semantics of the interface in each case + + - fix some cases in GMemoryOutputStream that were violating the above + expectations (which may cause a slight API incompatibility) + + - clean up GCredentials code and add support for Hurd and Solaris + + - improve splicing by using different codepaths for the case where we + have real _read_async() and _write_async() implementations on the + stream vs. the case where they are internally emulated (via + dispatching the sync variant of the call in a thread) + + * GKeyFile + + - fix a leak in g_key_file_get_(u)int64 when we fail to parse the + value as an integer + + - add long-requested API g_key_file_save_to_file() + + * Portability improvements + + - avoid using O_DIRECTORY on platforms that don't have it + + - be careful about systems that define SOCK_CLOEXEC but don't + actually support it (like Hurd) + + - only use SA_RESTART if it exists + + * Other small API changes/additions + + - a pair of functions to support matching strings for the type of + search functionality that you'd expect to have with things like + GtkSearchBar. This will also be used by the desktop file index. + + - g_str_is_ascii() with obvious purpose + + - g_test_expect_message() no longer appears to allow you to catch + G_LOG_ERROR messages + + * GMainContext/GSource + + - fix handling of overflowing the 'next source id' counter + + - g_source_remove() will now throw a critical in the case that you + try to remove a non-existent source. We expect that there is some + code in the wild that will fall afoul of this new critical but + considering that we now reuse source IDs, this code is already + broken and should probably be fixed. + + - simplify handling of the 'current dispatching source' to not + require use of a linked list + + * GObject + + - the long-broken (and leaky) pattern of destroying a just-allocated + object from inside of a custom GObject::constructor is now + officially completely illegal and will abort the program + + * Unicode: update to 6.3.0 + + * Bug fixes + + - g_file_copy() now falls back to pathname queryinfo. This should + clear up the bugs with copying from some GVfs backends (afp, + gphoto, archive, at least). + + - fix an out-of-bounds read in the xdgmime code + + - fix a typo in the /org/freedesktop/DBus path on the object manager + client + + - skip emitting path_namespace='/' in match rules in order to + workaround a bug in the D-Bus daemon and fix our own implementation + (which shared exactly the same bug) + + - fix crashes on precondition violations for GParamSpec constructors + + - many other small fixups (see bug list) + + * Many documentation improvements + +Bugs fixed: + 309224 g_key_file_save_to_file missing + 583321 QNX: no SA_RESTART + 661576 fix handling of constructors that destroy half-constructed objects + 672102 GSubprocess class + 684842 Seeks on GMemoryOutputStream don't have opaque semantics + 688492 Add a notification API + 691581 g_output_stream_real_splice_async doesn't use overriden read/write_async functions + 702516 gfileutils: Make -Werror=format-nonliteral happy + 704218 New gapplication(1) tool + 704593 g_setenv: on some systems (BSD, OSX…), setting a variable to NULL crashes the system + 704882 GLocalDirectoryMonitorClass mount_notify field is useless + 704887 file monitoring improvements + 705029 Support for Solaris credentials + 705688 g_settings_list_children: only list viable schemas + 706254 Afp backend cannot copy files + 707887 Attempting to create GObject Property with underscore prefix segfaults + 708042 gapplication: don't rely on cmdline being finalized immediately + 708265 add support for GNU/Hurd in GLib D-Bus Library + 708266 fix error code checks when SOCK_CLOEXEC is defined but not supported + 708529 xdgmime: valgrind warns about invalid reads + 708677 incorrect object path 'deskop' used in gio/gdbusobjectmanagerclient.c + 708714 Typo in docs of GLIB_VERSION_2_40 macro. + 708753 gdesktopappinfo: Call g_file_get_path() on demand + 708793 glib build fails with clang < 3.1: error: expected ';' after top level declarator + 708828 GDBusProxy: add the ability to call methods on non autostarted proxies + 708860 glib-2.38.0 doesn't build on Solaris 10 + 708972 gnetworking.h in tarball screws up out-of-source builds + 709113 [PATCH] Main loop dispatch path has needless linked list + 709227 Update to unicode 6.3.0 + 709301 goutputstream: Add clear warning about short writes to _write_bytes() and async version + 709326 GDesktopAppInfo crashes creating a DBusActivatable app without a filename + 709440 Fix overloading of "source" and "target" terminology in GBinding + 709615 Cannot use g_test_expect_message with g_error + 709753 Add helpers for string matches when using GtkSearchBar-like widget + 709898 Expose thumbnail validity in GFile attributes + 709966 Remove outdated documentation + 709994 Minor fix for HACKERS doc to direct hackers to proper help file + 709995 Obsolete makefile rules + 710002 G_MAXUINT may be assigned as duplicate source id + 710313 Memory leak in g_key_file_get_(u)int64 with invalid integer values + 710345 [Patches] Fix some redundant-decls + 710496 g_locale_to/from_utf8() doc updated. + 710625 g_file_error_from_errno: Remove unneeded breaks + 710666 Frame clock related bug fixes + 710724 gmain: Warn when g_source_remove() fails + 710726 Work around D-Bus bug with path_namespace='/' match rules + +Translations: + Assamese + Brazilian Portuguese + Indonesian + Russian + Tamil + Traditional Chinese + +What's new in Glib 2.38 +======================== + + * Application support + + - GIO now provides an implementation of Desktop Actions from the + desktop entry specification + + - GApplication now implements the org.freedesktop.Application + interface as per the desktop entry specification, allowing for + standards-based D-Bus launching of GLib-based applications + + - GDesktopAppInfo now supports DBusActivatable as per the desktop + entry specification, allowing GLib-based applications to use D-Bus + to launch other applications + + - GApplication now has a "busy" flag that can be set on an application + to allow the shell to show that it is busy + + * GObject + + - the private offset for a given class type is now always constant. + This was done by reorganising the memory layout of instances so that + the private data comes before the "official" pointer for the object + (ie: at a negative offset). Valgrind macros were added to mitigate + any problems that this may have caused. + + - a new G_DEFINE_TYPE_WITH_PRIVATE has been added along with a + generated function *_get_instance_private() that can now serve as an + equally-performing alternative to ->priv pointers in instances + (allowing memory savings) + + - new G_PRIVATE_FIELD, G_PRIVATE_FIELD_P and G_PRIVATE_OFFSET macros + provide a convenient method of converting between named variables in + private structures and their (now constant) offsets + + - installing properties on a GObjectClass must now be done from + class_init. It is no longer valid to install them after class_init + has returned. + + - it is now possible to manually break a GObject property binding + without destroying one of the objects involved + + * Icons + + - the requirements for implementing the GIcon interface have changed + in order to make it possible to consume all implementations of GIcon + with a finite number of cases + + - a new GBytesIcon type was added for an icon represented by an + in-memory binary blob in a known image format (ideally png). + + - new APIs g_icon_serialize() and g_icon_deserialize() replace the old + to/from_string APIs and will always work, irrespective of which + types have been initialised in the calling process, allowing for a + serialised GdkPixbuf to be deserialised in a process that doesn't + have GdkPixbuf + + - support for icons has been added to GMenuModel using the new APIs + + * Actions and menus + + - GPropertyAction provides a convenient way of creating a stateful + property corresponding to a property on a GObject, such as the + "visible-child-name" property of a GtkStack + + - new API g_menu_remove_all() + + - we now have established rules about what is a "valid" action name + and an API to check them + + - a new API for converting detailed action names to and from the + split-out name and parameter value (as GVariant) + + - for backwards compatibility, invalid action names can still be used + with most functions, but this is not recommended + + * Other GIO + + - GDBus now supports services that wish to handle some of all + properties on an interface asynchronously, without requiring the + service to reimplement the entire org.freedesktop.DBus.Properties + interface + + - GFile now has a new _measure_disk_usage() (and async) API for + recursively determining the amount of disk space used by a + particular directory (akin to 'du'). + + - asynchronous version of g_file_trash() and g_file_make_directory() + have been added + + * Other new API + + - GRegex has a new function to query the maximum lookbehind length to + allow for regexp matching on streams + + - GVariant has two new APIs for constructing strings that allow + avoiding copies in some cases: g_variant_new_take_string() and + g_variant_new_printf() + + * Testing + + - we can now generate TAP output + + - new support functions for simplifying the process of dealing with + data files for srcdir != builddir and installed test cases + + - g_test_trap_subprocess() provides a portable alternative to + g_test_trap_fork() + + * Other + + - GLib now builds on Android against the bionic C library + +Overview of changes from GLib 2.37.93 to 2.38.0 +================================================ + +* fix the documentation for GSourceFuncs + +* fix compilation on OS X/ppc64 + +Bugs fixed: 708445, 647145 + +Translations updated: + Danish + French + Portuguese + Punjabi + +Overview of changes from GLib 2.37.92 to 2.37.93 +================================================ + +* a couple of bugfixes in the new g_file_measure_disk_usage() API + +* updated Traditional Chinese translation + +Overview of changes from GLib 2.37.7 to 2.37.92 +=============================================== + +* new API g_file_measure_disk_usage() similar to du(1) + +* minor fixes + +* Translation updates: + Assamese + Belarusian + Brazilian Portuguese + Catalan + Czech + Galician + German + Hungarian + Indonesian + Italian + Korean + Korean + Latvian + Lithuanian + Polish + Serbian + Slovenian + Spanish + +Overview of changes from GLib 2.37.6 to 2.37.7 +============================================== + +* GDateTime now supports %:z formatting variations + for timezones. This is a GNU date extension. + +* Bugs fixed: + 685387 Segfault with GObject.signal_handler_is_connected()... + 686786 g_socket_get_available_bytes() returns wrong value ... + 705027 GSocket GSource not threadsafe on Windows + 706469 Fix G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE documentation + 706706 Fix Gir annotations on g_loadable_icon_load_finish + 706888 gtype: fix a no-op assertion + 706958 configure.ac: fix atomic opts detection + 707092 "File Utilities" page for GLib documentation doesn'... + 707151 gdatetime: Extend the '%z' timezone format + +* Translation updates: + Catalan + Hungarian + Japanese + Polish + Slovak + Tamil + + +Overview of changes from GLib 2.37.5 to 2.37.6 +============================================== + +* Tests using the g_test facilities can now generate TAP output + +* Bugs fixed: + 680926 generic type fallback logic is broken for -symbolic + 684327 setting null icon to icon list + 689245 GSocket unable to reuse (address,port) on Mac OS X + 692125 Support TAP as GTest output format + 693335 build: fix dtrace-related warnings + 696633 gdbus-codegen trips over unicode chars when using python 3.x + 696970 Compiling 2.36.0 for win64 fails + 697185 GSocket – Allow specifying the multicast interface from... + 700268 Add support for using the clang analyzer + 701318 Add G_SPAWN_DEFAULT to GSpawnFlags + 701529 glib/tests/gdatetime: use UTC time in test_GDateTime_diff() + 701800 a new approach to reporting critical errors + 702674 g_date_time_new_utc crash + 704165 GLib.IOChannel read_unichar() fails + 705075 Simplify g_get_tmp_dir() + 705152 Race in glib/task.test + 705398 gtype: Fix typo in g_type_class_add_private() error message + 705570 Check ref_count in g_object_notify_by_pspec + 705600 Deprecate GSimpleActionGroup functions? + +* Updated translations: + Assamese + Brazilian Portuguese + Czech + Dutch + Galician + Gujarati + Hebrew + Italian + Lithuanian + Marathi + Norwegian bokmÃ¥l + Russian + Slovenian + Spanish + Thai + Traditional Chinese + + +Overview of changes from GLib 2.37.4 to 2.37.5 +============================================== + +* Implement the Desktop Action specification: In the case that the + application is a GApplication and DBusActivatable, actions from the + desktop file are translated into GActions that have been added to + the application with g_action_map_add_action(). + +* GPropertyAction is a new type of GAction that represents the value + of a property on an object, and allows to change the value when + activated. + +* GNetworkMonitorNetlink can now handle default routes via a device. + +* The gsettings tool now reports failure to write a key (e.g. because + the key was locked down) + +* Miscellaneous new api: + - g_variant_new_printf + - g_action_print_detailed_name + - g_regex_get_max_lookbehind + +* Bugs fixed: + 664444 Support additional application actions in .desktop files + 684123 glib build only tries -D_GNU_SOURCE if glibc is detected + 689794 support incremental matching + 699259 add org.freedesktop.Application support to GIO + 700460 rewrite tests to not rely on precise timing of timeouts + 701511 updates to various GSource types + 701609 gnetworkmonitornetlink: handle default route via device + 703270 add GPropertyAction + 704157 GAction: add function for printing detailed names + 704250 Doc: various fixes + 704267 regression gsourceclosure: segfault in gedit file chooser + 704322 glib-unix: fix handling of multiple signal source for the... + 704424 No error when failing to override a locked key + 704447 Fix build/use of g_child_watch_closure_callback on Windows + 704523 g_thread_create_full() can dereference NULL pointer + 704543 Add implementations for G_GNUC_*_IGNORE_DEPRECATIONS for ... + 704567 gdbusnameowning: Don't spew an error if we're releasing a... + 704585 libc printf can give mixed-case strings for NaN and Inf + 704587 FTBFS: statfs_result is undeclared for statvfs() + 704699 gmain: Reset signal handlers to default when source is + 704704 AI_NUMERICSERV cannot be used with ai_socktype = 0 + 704873 inotify: don't assume mainloop is running + 704999 glib/convert.test crashing due to lack of iconv cache + 704931 GMenuModel: add annotations to virtual functions + +* Translation updates: + Assamese + Czech + German + Gujarati + Spanish + Tamil + + +Overview of changes from GLib 2.37.3 to 2.37.4 +============================================== + +* Bugs fixed: + 701283 g_source_add_child_source() segfault + 702147 inconsistency of G_STRFUNC + 703191 new private macros interact poorly with versioning macros + 703254 Doc: various fixes + 703407 g_spawn_async() keeps child_pid_report_pipe open in child process + 703437 GDBusConnection: be more careful with async GetAll + 703478 Missing G_BEGIN/END_DECLS in gsettingsschema.h + +* Translation updates: + Catalan + +Overview of changes from GLib 2.37.2 to 2.37.3 +============================================== + +* add a new API for instance private data: G_DEFINE_TYPE_WITH_PRIVATE + +* fix timestamps in tarball to prevent automake from being required to + build the unmodified source + +* add new D-Bus API for async property handling + +* add back fsync() on ext4 for g_file_set_contents() after it was + discovered that despite statements in the ext4 documentation + suggesting that this is safe, it is not safe. + +* Translations: + Italian + Norwegian bokmÃ¥l + +* Bugs fixed: + 698375 - D-Bus async properties + 700350 - timestamp issue + 701560 - fsync issue (fixed again) + 700035 - new API for instance private data + +Overview of changes from GLib 2.37.1 to 2.37.2 +============================================== + +* The GLib test utilities have grown some file-related APIs + to support tests that can be used installed and uninstalled. + +* Installing properties after class initialization is deprecated, + and will trigger a warning. + +* GApplication: + - Support org.freedesktop.Application, including D-Bus activation + from desktop files + - Set prgname to appid for services + +* Bugs fixed: + 549783 gtester lacks framework for tests with data files + 692848 Fix property example in gobject tutorial + 698018 Add an explicit g_binding_release() + 698614 GObject: prevent installing properties after init + 699259 add org.freedesktop.Application support to GIO + 699959 g_file_copy(): Ensure we create private files by default + 700123 Test failure: g_inet_socket_address_get_scope_id + 700725 GIcon: NULLify the `type' out param in the sync methods too + 701401 gtest: add function for testing for WINE + 701456 Error in gnome/glib/gio/tests/file.c + 701474 Error building glibmm due to extra comma in glib/gtestutils.h + 701560 various improvements for g_file_set_contents() + 701680 GFileEnumerator: Add some documentation about ordering + 701878 Check wakeup() before iteration(TRUE) doesn't block + +* Translations: + Assamese + Czech + Galician + Gujarati + Kannada + Marathi + Odia + Polish + Slovenian + Spanish + Telugu + + +Overview of changes from GLib 2.37.0 to 2.37.1 +============================================== + + * add support for installed tests: + https://live.gnome.org/GnomeGoals/InstalledTests + + * add a new g_test_trap_subprocess() that works on Windows as a + replacement for the (now deprecated) g_test_trap_fork() + + * support for explicitly cancelling a gobject property binding + + * performance improvements for signal argument handling + + * stop using `quotes' in very many log messages generated by GLib, for + favour of 'this style'. This may cause testcases in other packages + to fail if they were matching on the previous text. + + * improve manpages: add missing arguments and flags + +Translations: + Aragonese + Assamese + Gujarati + Hindi + Kannada + Norwegian bokmÃ¥l + Odia + Slovenian + Spanish + Tamil + Telugu + +Bugs fixed: + 679683 replace g_test_trap_fork() + 694380 Improve signal argument collection performance + 695233 Strings require plural forms + 697849 spelling fixes in cross.xml and running.xml + 698877 GProxyAddressEnumerator calls g_network_address_parse_uri without port + 698981 [PATCH] test /gdbus/connection/large_message could hang forever + 699079 Prototype support for installed tests + 699485 [PATCH] tests/mappedfile: Also handle ENOMEM + 699493 SOCKS5 proxy code crashes if it cannot authenticate + 699500 gbitlock: fix this to not unconditionally use futex emulation + 699779 [PATCH] G_GNUC_FORMAT: documentation error + 700263 m4macros/glib-gettext.m4: Don't use AC_HEADER_STDC + 700714 [PATCH] gtestutils: Ensure test subprocesses don't dump core + 700746 Use 'dumb quotes' rather than `really dumb quotes' + +Overview of changes fron GLib 2.36.0 to 2.37.0 +============================================== + +* The syntax for detailed action names has been documented, + and a parser API for them is now provided + +* GApplication has gained a busy state. This feature is intended for + clients that want to signal a desktop shell their busy state, for + instance because a long-running operation is pending. + +* GLib can now be built with the bionic C library + +* GIcon can now be serialized to a GVariant + +* Bugs fixed: + 548353 Finish implementing GFile interface (mostly asynchron... + 645881 Full port of glib-2.28.1 onto Android-ARM + 665445 Glib mistakes nl_langinfo() from plibc for the real t... + 672018 Need API to set global application state (busy, count... + 687659 drop support for adding interfaces after class_init + 688820 GIcon is a bad interface + 688954 extend 'detailed action' syntax, provide parser + 689223 Fix compilation on Android with the bionic C library + 695156 Add support for arg0namespace matching in signal_subs... + 696108 gdbus-codegen: avoid warnings in generated code + 696629 fix sed(1) usage + 696652 GTask won't free its error member variable on finalize + 696857 GThreadedResolver: set an error if no records could b... + 696973 Compiling 2.36.0 for win64 fails in gdbusmessage.c + 697131 No --version + 697160 [PATCH] gmacros: Mark G_UNAVAILABLE() functions as de... + 697229 Custom Interface implementations will be broken with ... + 697250 Documentation glitch of G_DEFINE_TYPE_EXTENDED causes... + 697365 Fix usage of hasmntopt in gunixmounts.c + 697367 Remove warning on gio/gunixmounts.c + 697386 Except const argument with atomic is not lock free + 697595 g_main_context_unref unlocks a mutex twice + 697601 reduce GMenuModel D-Bus traffic + 697626 Allow posix threads to be used on w32 + 697652 Help options generated even when help disabled + 697771 fix a typo of "fo" to "of" in building.xml + 697887 GVariant: fix transfer annotation + 697942 abicheck.sh fails on mips + 698056 rewrite g_object_new() + 698081 Pidgin hangs in g_spawn_command_line_sync + 698455 GVariant: add new g_variant_new_take_string() API + 698457 g_variant_get_data_as_bytes() always returns toplevel... + 698478 gactionmap: don't require GActionGroup + 698595 the valgrind/priv-before-instance bug + 698655 desktop-app-info test relies on true being in /usr/bin/ + 698686 GUnixSocketAddress: fix construct parameter issue + 698716 Use of g_mem_set_vtable() breaks after gobject automa... + 698999 bytesicon: fix a memory leak + 699001 bytesicon: don't use g_object_unref() on GBytes + 699361 gio: fix small leak + +* Translation updates: + Assamese + Gujarati + Hungarian + Italian + Kannada + Norwegian bokmÃ¥l + Polish + Spanish + Tamil + + +Overview of changes fron GLib 2.35.9 to 2.36.0 +============================================== + +* It is no longer necessary to call g_type_init(). If you are + loading GLib as a dynamic module, you should be careful to avoid + unloading it, then subsequently loading it again. This never + really worked before, but it is now explicitly undefined behavior. + Note that if g_type_init() was the only explicit use of a GObject + API and you are using linker flags such as --no-add-needed, then + you may have to artificially use some GObject call to keep the + linker from optimizing away -lgobject. We recommend to use + g_type_ensure (G_TYPE_OBJECT) for this purpose. + +* This release contains an incompatible change to the g_get_home_dir() + function. Previously, this function would effectively ignore the HOME + environment variable and always return the value from /etc/password. + As of this version, the HOME variable is used if it is set and the + value from /etc/passwd is only used as a fallback. + +* The 'flowinfo' and 'scope_id' fields of GInetSocketAddress + (introduced in GLib 2.32) have been fixed to be in host byte order + rather than network byte order. This is an incompatible change, but + the previous behavior was clearly broken, so it seems unlikely that + anyone was using it. + +This release contains only small bugfixes and translations updates. + + - g_file_copy(): fix bug where attributes were not applied properly to + the destination file + + - fix some 'available since' annotations + + - fix gdbus-codegen to produce more pedantically-correct code + +* Bugs fixed: + 696108 gdbus-codegen: avoid warnings in generated code + 696014 g_file_copy(): Ensure G_FILE_COPY_OVERWRITE preserves permissions + +* Translations updated: + Basque + Czech + Gujarati + Hindi + Hungarian + Japanese + Malayalam + Marathi + Odia + Punjabi + Russian + Tadjik + Tamil + Telugu + +Overview of changes from GLib 2.35.8 to 2.35.9 +============================================== + +This release drops the old codepage ABI from gutils.c. This is a +source-compatible change and only breaks ABI with respect to truly +ancient binaries (and those binaries are already broken for other +reasons). This change only affects Windows. + +* Bugs fixed: + 682896 glib doesn't build on mingw32 + 693204 split up g_get_{hostname,username,realname,home_dir} etc. + 694181 Handle GNetworkAddress better in g_network_monitor_base_... + 694253 occasional /gdbus/unref-pending test failure + 694350 Add type names to gsignal warnings + 694757 Use separate GLIB_WARN_CFLAGS that can be overridden ext... + 568405 Which is the correct replacement for g_strncasecmp, if... + 630284 g_hash_table_get_keys docs + 659428 docs: Small clean-up of howto subsection headers + 675333 Cannot forget association in Open With dialog: program... + 694669 consider unicode corrigendum #9 + 694843 g_base64_decode_step () produces invalid data + 695147 Don't use PATH_MAX as it's not guaranteed to be defined + 695191 Commit f641699 broke /appinfo/mime/api test case + 695339 Swapped msgid plural forms for translation + 695376 GDBusMethodInvocation leak and potential crash + 695425 Untranslatable message in gsettings-tool + 695887 Improvements to GObject API documentation + 695925 GUINT32/64_SWAP_LE_BE macros do not enclose val argume... + 696015 PATCH Add doc warning to g_base64_decode() + +* Translation updates: + Assamese + Belarusian + Brazilian Portuguese + Catalan + Catalan (Valencian) + Danish + French + Galician + German + Greek + Gujarati + Italian + Korean + Latvian + Lithuanian + Polish + Portuguese + Punjabi + Serbian + Simplified Chinese + Slovak + Slovenian + Spanish + Thai + Traditional Chinese + Uyghur + Vietnamese + + +Overview of changes from GLib 2.35.7 to 2.35.8 +============================================== + +This release contains one major change that may cause problems: type +modules are now never unloaded. This is implemented by (effectively) +leaking the last reference on dynamic types. Some testcases that check +for unloading of types have been observed to be broken by this change, +but we know of no actual cases of "real code" breaking. Please report +any problems. + +Other changes: + * A couple of build fixes for Solaris + * Fix signal emission for GDBusObjectManagerClient + * annotations fixes + * new API: g_dbus_address_escape_value() + * GSocketClient: add proxy-resolver property + * GSimpleProxyResolver: new simple GProxyResolver class + * documentation fixes + * gnetworkaddress: preserve IPv6 scope ID in IP literals + +Bugs fixed: + 691105 Allow GSocketClient to override GProxyResolver for per client proxy settings. + 692827 configure test fails for arpa_nameser.h + 692829 new Btrfs support causes build failure on Solaris + 693285 GDBusObjectManagerClient: won't emit object-added|removed if name-owner arrives later + 693502 Cross-compiling documentation: typo (np -> no) + 693673 add g_dbus_address_escape_value() + 693694 gio: Fix annotations on g_[async_]initable_new() and friends + +Translations: + Dutch + Galician + Polish + Serbian + +Overview of changes from GLib 2.35.6 to 2.35.7 +============================================== + +This is a quick follow-up release with a few bug fixes. + +* Fix the build on systems with strict linkers by adding -pthread back + to the LDFLAGS for a testcase. + +* Re-enable native atomic operations on some buggy versions of clang + that ship as part of the MacOS X SDK. + +* Make G_IO_FLAG_IS_WRITEABLE an enum again (the #define broke bindings) + +* a small docs fix + +* Bugs fixed: + 657045 + 636683 + 682818 + 693105 + +* Translations: + Italian + +Overview of changes from GLib 2.35.4 to 2.35.6 +============================================== + +* GUnixFdSource is a new way to add file descriptors + to the mainloop + +* g_source_set_ready_time lets you mark a source to become + ready at a specified monotonic time + +* The internal visibility handling of GLib has been reworked + +* GFileMonitor will now automatically use fam instead of inotify + if $HOME is on NFS + +* The file monitor implementation can now be overridden with + the GIO_USE_FILE_MONITOR environment variable + +* Bugs fixed: + 570572 2 make check errors on + 592211 No monitoring over NFS mounts + 625552 wrong behaviour of GVolume GVolumeMonitor related func... + 657729 modernise GMainLoop + 658020 GSource for a single GPollFD + 678223 g_mutex_free + 682560 leak fixes + 682819 EINTR-harden all the things + 684404 When using g_network_address_address_enumerator_next()... + 686853 new GSource fd API + 688169 G_DISABLE_DEPRECATED doesn't cover deprecated/gthread.... + 688681 build: Make .symbols file canonical on all platforms + 690118 Crash when closing last tab of a window using Ctrl-w + 691624 glib/gtester.c: missing include + 691812 gioinputstream - give task as callback_data not task_data + 691866 fails out of source build directory - gnetwork.h not f... + 692029 Add new API checking utility + 692034 Install an invalidation notifier for GClosure in g_sou... + 692058 Broken makefile for gio tests + 692079 build failure in gmarkup.c when using gcc 4.8 and buil... + 692201 inotify: fix a memleak + 692202 gfile: don't report completion twice on g_file_load_co... + 692229 Incorrect string formatters in a translation string + 692332 GNetworkMonitorNetlink: make the netlink socket cloexec + 692360 possibly non-threadsafe code in g_content_type_guess()? + 692404 tester: Use FD_CLOEXEC when creating pipes + 692408 nautilus SIGSEGV in g_file_info_get_size() + 692544 [PATCH] gfile: Ensure we create internal pipe with FD_C... + 692583 atomic get doesn't accept a const argument on architect... + 692618 Use g_timeout_add_seconds + 692815 Using g_hash_table_insert() when using a hash table as ... + 692865 Invalid docbook generated by gdbus-codegen + 692928 Document G_MENU_{ATTRIBUTE,LINK}_* + +* Translation updates: + Hebrew + Kannada + Lithuanian + Norwegian bokmÃ¥l + Polish + Serbian + Slovenian + Spanish + Uyghur + + +Overview of changes from GLib 2.35.3 to 2.35.4 +============================================== + +* New features: + - New API: g_get_num_processors + - New API: g_application_command_line_get_stdin + - New GFileMonitor flag: G_FILE_MONITOR_WATCH_HARD_LINKS + - Parse more timezone offset formats + - Better timezone support on Windows + - Make GParamSpec constructors introspectable + +* Removed or deprecated features: + - Disallow adding interfaces after class_init + +* Bug fixes: + 532815 gio + inotify support for hardlinks + 614930 add g_get_num_processors (), return the max concurrent... + 626497 Btrfs clone/reflink ioctl support in g_local_file_copy + 633117 glib fails stests if /etc/localtime is not properly set + 661767 merge/improve various bits of run-in-thread functionality + 668210 Add g_application_command_line_get_stdin() + 675856 Use GDbus via gobject-introspection instead dbus-python + 684103 make glib work with python3 + 684723 run-assert-msg-test.sh fails + 686058 OpenBSD: disable ipv6_v4mapped test + 686128 GTimeZone should be able to parse POSIX format for... + 687223 cleverer GThreadPool management + 687659 drop support for adding interfaces after class_init + 687920 GCredentials should have an accessor for the process ID + 688681 build: Make .symbols file canonical on all platforms + 688829 Variable overflow in utils.c test on 32-bit machine + 689324 Variable scoping in gunixmounts.c + 689810 Include guard optimization + 690043 Broken link for gsettings tutorial: gnome-utils in... + 690084 gmarkup: Make GMarkupParseContext a boxed type + 690388 Check if CMSG_FIRSTHDR() returns NULL when there is... + 690538 gschema DTD is invalid + 690543 Add test coverage for testing in-tree DBus services... + 690670 local_command_line not introspectable/annotated + 690902 G_END_DECLS needs to be at the end of gutils.h + 690970 Unhelpful deprecation message for g_value_array_get_nth + 691001 building docs is broken on master branch + 691011 Automake-1.13 errors on obsolete AM_PROG_CC_STDC + 691077 gio-querymodules crashes with SIGSEGV + 691110 g_cond_wait() docs incomplete + 691489 Crash in Oscars 2013 page + 691558 Only check for .hidden files if standard::is-hidden... + 691608 Support compilation with clang 3.2 + +* Translation updates: + Assamese + Bulgarian + Estonian + Galician + Greek + Hebrew + Norwegian bokmÃ¥l + Polish + Slovak + Slovenian + Spanish + Tamil + + +Overview of changes from GLib 2.35.2 to 2.35.3 +============================================== + +* This release contains an incompatible change to the g_get_home_dir() + function. Previously, this function would effectively ignore the HOME + environment variable and always return the value from /etc/password. + As of this version, the HOME variable is used if it is set and the + value from /etc/passwd is only used as a fallback. + +* We now install a public "gnetworking.h" header that can be used to + include the relevant OS-dependent networking headers. This does not + really abstract away unix-vs-windows however; error codes, in + particular, are incompatible. + +* Bugs fixed in this release: + 142568 Allow $HOME to override passwd entry if the user really wants + 587806 The file selector should honor .hidden files + 602715 [GChecksum] Please add support for SHA512 + 623187 provide some support for arbitrary setsockopt()s? + 629301 .goutputstream files left behind when cancelling I/O + 652650 Optimize GDBusMessage serialization + 664627 /gapplication/basic test intermittently fails: cmdline re-or... + 675516 Win32: Don't start a DBus server when built as static library + 679683 replace g_test_trap_fork() + 684145 Current Git sources fails to cross-compile for Windows in Li... + 686895 file-info: catch thumbnail files in large directory as well + 687092 IPv6 <-> IPv4 mismatch when subscribing to multicast (send) + 688180 GObject: Minor error in description of floating reference + 688319 gthread: add missing AVAILABLE_IN_2_32 annotations + 688377 configure: add missing square bracket in AS_IF for memmove + 688419 gtask: source_object arguments and return values not annota... + 688497 AppInfo: Add sufficient api to port gnome-session from Egg... + 688681 build: Make .symbols file canonical on all platforms + 688704 Add boxed GType for GThread + 688886 Improve the i18n documentation + 688931 GMemoryOutputStream: Add new _resizable() constructor usab... + 689037 need helper for creating a GFile from a remote commandline... + 689377 Fix a compiler warning in GDBus + 689538 Source object tag set too late in gsocketlistener + 689800 Treat lost+found directory as a hidden file + 689847 Add fast repeated typename -> GType resolver + 689982 Make GChecksum more fully introspectable + 690069 g_unix_open_pipe: Add missing F_SETFD + 690083 gfileenumerator: Add a g_file_enumerator_get_child method + 690163 Add a pre-configured gio/gnetworking.h for Visual C++ builds + 690346 Remove an unneeded escaping in NAMESER_COMPAT_INCLUDE + 690348 Fix g_type_add_class_private() name in g_warning + +* Translation updates: + Assamese + Galician + Hebrew + Hindi + Kannada + Odia + Polish + Spanish + + +Overview of changes from GLib 2.35.1 to 2.35.2 +============================================== + +Note that the incompatible change to the ->constructed() vfunc that was +made in the last unstable release (2.35.1) has been reverted due to +causing regressions in applications. + +A new incompatible change has been introduced in this version: it is no +longer permitted to add interfaces to a class after the first +instantiation (or more strictly: after g_type_class_ref()). Bug #687659 +is tracking this. + +Two private symbols (g_menu_{attribute,link}_hash_iter_get_type) which +were accidentally exported have also been properly hidden. This may +cause some tools to issue warnings about ABI mismatch. + +The remaining changes should be relatively harmless: + + * GIO now has kqueue support for GFileMonitor (BSDs, Mac OS) + + * New g_variant_new_from_bytes() API + + * UNIX signal sources now allow watching SIGUSR1 and SIGUSR2 + + * Many pedantic cleanups to adhere to a higher level of -W use + + * GTask changes to avoid a deadlock + + * many cleanups/fixes for Windows + + * Boxing for GPollFD, GIOChannel, GBytes, GByteArray + + * Fix URL-encoding of trashed files + + * Many other docs and annotations fixes + +Translations: + + Galician + Gujarati + Lithuanian + Serbian + Slovak + Slovenian + +Bugs closed: + + 649302 Add support for GNU/FreeBSD + 668842 [GSocket] Add caching for the sender address in g_socket_receive_from() + 672924 Add annotations for g_filename_from_uri() + 673229 glib: Use Returns:, not @returns + 677062 (partial) GVariant: Make g_variant_new_from_bytes() public, add more GBytes API + 686185 g_date_time_format Transcoding Fails on OSX + 686191 g_mutex_get_impl() should use g_atomic_pointer_get() + 686797 Box GPollFD to make it introspectable + 686810 [regression] Infinite wait in g_task_run_in_thread_sync() + 686822 possible dlopen()/dlclose() issue with automatic g_type_init() + 686839 mkinstalldirs: Move to glib-mkinstalldirs + 686895 file-info: catch thumbnail files in large directory as well + 686898 g_unix_signal_source_new: Allow SIGUSR1 and SIGUSR2 + 686920 gdbus: Allow GDBusObjectManagerClient to work on peer connections + 686921 Remove some of the repetition from gio/tests/Makefile.am + 687075 g_spawn_sync diagnostic incorrectly complains about SIGCHLD + 687089 g_dbus_connection_export_menu_model(): fix a crash + 687098 Repeated g_timeout_add* use can lead to guint overflow + 687385 Add some stricter CFLAGS, fix up the code + 687441 ABI break in master: g_menu_attribute_hash_iter_get_type, g_menu_link_hash_iter_get_type removed + 687516 typo in string: KB should be kB + 687540 In Trash folder, Nautilus misinterprets "\n" in filename as a line break + 687541 GSignalQuery param_types field needs array annotation + 687600 gfileutils.c performs invalid cast of (varargs) open to non-vararg type + 687698 plural forms needed + 687700 ending spaces + 687742 Add support for internal linkage to glib-compile-resources + 687801 tests/buffered-input-stream: Fix size of parameter passed + 688109 win32 warning/error fixes + 688255 'make check' regressed in 138f4c1 because GMarkup error messages changed + 688338 [PATCH] gobject/gtype.c: Fix spelling of »exceed« + 688370 GDBusError documentation improvement for client-side + 688378 g_socket_join_multicast_group not working + 688518 gio-kqueue: use O_EVTONLY on MacOS + + + +Overview of changes from GLib 2.34.0 to 2.35.1 +============================================== + +These two changes in particular may be slightly incompatible. Please +give feedback if they cause trouble: + + * Signal handlers connected with g_signal_connect_object() are now + automatically disconnected on target object destruction + + * The ->constructed vfunc is now called after all properties are set + +The remaining changes should not cause problems. + + * g_type_init() is no longer necessary and has been deprecated + + * GTask (the new GAsyncResult implementation) has landed + + * GLib version macros updated + + * Update to Unicode 6.2 + + * Thread safety fixes for GFileMonitor in non-default main contexts + + * GTimeZone support for old-format zoneinfo database (as on Mac OS) + + * g_settings_bind() now works with non-canonical property names + + * Fix crashes related to NULL connection passed to + GBusNameVanishedCallback and document this situation + +* Bugs fixed: + 118536 Make g_signal_connect_object'ed handlers disconnect when the data object is destroyed + 661767 merge/improve various bits of run-in-thread functionality + 682950 GFileMonitor crashing on high event count when running in different thread + 683642 Missing g_content_type_get_symbolic_icon + 684882 Gsettings should spaw a warning when binding against a low_underscored_property + 684909 codegen: Explicitly close output + 684912 Update to Unicode 6.2 + 685037 g_strcmp0: Returns shall include values less and greater than zero + 685069 Leak in glib-compile-resources + 685208 missing g_return_if_fail + 685608 [Patch] Port gio tests from pygobject to pygi + 685697 Documentation typo in g_dbus_interface_skeleton_has_connection() + 685733 Call ->constructed() after all properties are set + 685787 gtestdbus: correct documentation typos + 685995 Crash in g_menu_exporter_name_vanished + 686091 Invalid reads in g_bytes_unref_to_data + 686119 dtrace, gobject_probes.d, the last three probes - semicolon missing + 686161 Deprecate g_type_init() + 686231 GBusNameVanishedCallback: document NULL connection + 686458 slightly increase poll duration in test_timed_wait + +* Translations updated + Catalan (Valencian) + Czech + Danish + Italian + Lithuanian + Norwegian bokmÃ¥l + Slovenian + +Overview of changes from GLib 2.33.14 to 2.34.0 +=============================================== + +* GIO now looks for thumbnails in XDG_CACHE_HOME, following a + recent alignment of the thumbnail spec with the basedir spec. + +* The default values for GThreadPools max_unused_threads and + max_idle_time settings have been changed to 2 and 15*1000, + respectively. + +* Bug fixes: + 654239 g_type_init()'s docs have no statement about how to... + 674620 Update GSettings migration guide for intltool updates + 676034 Fix doc annotation for g_ptr_array_ref() + 684278 Fix GIO build on Windows + +* Translation updates: + Brazilian Portuguese + British English + Bulgarian + Catalan + Galician + German + Hebrew + Hindi + Hungarian + Kannada + Latvian + Marathi + Spanish + Telugu + + +Overview of changes from GLib 2.33.12 to 2.33.14 +================================================ + + * CVE-2012-3524: don't run dbus-launch from setuid binaries + + * g_content_type_get_generic_icon_name(): + new API for getting the icon name for a mime type + + * Introspection fixes: + - GDBusConnection nullability fixes + - give a box type to GTimeZone + + * Drop GVFS_INOTIFY_DIAG + + * Add a new "Writing GLib Applications" section to the reference + documentation with general info on security, threads, etc. + + * gwin32mount.c: Fix syntax error + + * gresource tests: srcdir != builddir fixes + + * tests/gvariant: Fix test on big endian architectures + + * Fix regression in g_shell_parse_argv() + +Bugs fixed: + 562907 g_shell_parse_argv() mishandles # (hash) + 683167 g_time_zone_new not introspectable + 683384 /gvariant/checksum-basic failure on big endian machines + 683641 Typo in gwin32mount.c + 683744 have a way to get the generic icon name for a mime type + +Translation updates: + Assamese + Belarusian + British English + Czech + Danish + French + Galician + German + Greek + Hebrew + Indonesian + Indonesian + Korean + Lithuanian + Marathi + Marathi + Polish + Portuguese + Punjabi + Russian + Serbian + Slovenian + Traditional Chinese + +Overview of changes from GLib 2.33.10 to 2.33.12 +================================================ + +* Add a G_DEFINE_QUARK macro + +* Add symbolic icon support to drive, volume, and mount, file + and content types + +* Add API to allow thread-safe access to the same qdata item + +* Bugs fixed: + 562907 g_shell_parse_argv() mishandles # (hash) + 627240 add G_DEFINE_QUARK + 672329 memory leaks in gutils.c and glib tests + 673012 Stable byte-level specification for normal form + 674805 gdbusproxy async test is broken + 679835 gvariant format string parsing (and assertions)... + 682075 gdbus: Fix double free and use after free of ob... + 682101 Provide a way to get a symbolic icon for a device + 682222 test_method_calls_on_proxy: assertion failed (e... + 682284 mount-op: use gint64 instead of guint64 for tim... + 682386 "make check" fails due to sys/resource.h not be... + 682560 leak fixes + 682586 gsettings-tool: make list-recursively really re... + 682819 EINTR-harden all the things + 682833 Handle EINTR for open() + 682849 drop the global lock for g_object_weak_ref + 682965 gdbus-tool: Check return value of strrchr() + 683088 gdbus-codegen: fix error when wrong interface n... + Fix the build with gtk-doc-stub + Don't crash if set_app_info is called before ad... + +* Translation updates + Assamese + Galician + Greek + Indonesian + Japanese + Latvian + Lithuanian + Norwegian bokmÃ¥l + Polish + Portuguese + Punjabi + Russian + Spanish + Traditional Chinese + Vietnamese + + +Overview of changes from GLib 2.33.8 to 2.33.10 +=============================================== + +* New GTest API for testcases where log output is expected: + g_test_expect_message() + +* GMenuItem now has 'get' accessors and a construct-from-GMenuModel API + +* GVariant now has a function to check a format-string for type + compatibility + +* win32: We now use overlapped IO to support multiple asynchronous + operations (ie: reading and writing) at the same time. + +* GMappedFile: Add g_mapped_file_get_bytes() + +* The problems with g_file_make_directory_with_parents() should be + resolved. + +* The long-standing issues with placeholder generation of manpages are + now resolved. + +* gtlscertificate: Add GBytes based certificate and private-key props + +* build: Switch back to using AS_IF for conditionals + +* test coverage improvements, documentation improvements, leak fixes + +* Bugs fixed + 326931 Better docs for G_GNUC_* + 550433 g_test_init doesn't recognize --help + 600751 GCompletion should better document if and how items memory is managed + 628193 Miscellaneous string fixes + 637460 man glib-genmarshal is hard to use + 674483 broken configure results when cross-compiling with gcc >= 4.5 + 677065 GMappedFile: Add g_mapped_file_get_bytes() + 679288 win32: use overlapped events for streams + 679556 it's hard to use gtest when g_warning() is expected + 680823 g_file_make_directory_with_parents: Fix error propagation + 681319 gtlscertificate: Add certificate-bytes and private-key-bytes props + 681336 man pages not built if --enable-gtk-doc not specified + 681413 build: Switch back to using AS_IF for conditionals + 681501 gmem: array only partially filled with memcpy + 681854 Documentation fix for Howto compile a program with glib + 682025 Documentation correction + 682067 Fix problems with CLEANFILES and automake-1.11.1 + +* Translations updated: + Lithuanian + Spanish + Galician + Telugu + Serbian + Assamese + Marathi + Indonesian + Traditional Chinese + +Overview of changes from GLib 2.33.6 to 2.33.8 +============================================== + +* GIO now has a g_file_delete_async function + +* The defaults for GThreadPools max_unused_threads + and max_idle_time values have been changed to + 2 and 15*1000, respectively. + +* Bugs fixed: + 661767 merge/improve various bits of run-in-thread functionality + 680074 undefined symbol "get_C_locale" + 680121 g_cancellable_source_new: don't use a file descriptor + 680148 gthread: check for definition of PR_SET_NAME + 680310 Sorting of access points by strengh not working + 680704 g_utf8_strup() crash + 68076a0 GFile: Add g_file_delete_async() + 680787 Add .dir-locals.el to tell Emacs users not to use tabs... + 680823 g_file_make_directory_with_parents: Fix error propagation + 680994 STATIC_ASSERT in GDBusError docs don't have much utility + 681116 gtlscertificate: Add g_tls_certificate_equal() function + 681118 gtlsdatabase: Don't complain if no callbacks for async... + 669331 try to get gio tests working a little better on win32 + 674314 Make gtk-doc not a hard dependency of GLib + 674800 gclosure: generic marshaller leaks return value + 675524 gsocket: FIONREAD undeclared (needs sys/filio.h) + 679509 use after free in g_dbus_action_group_describe_all_done() + 679996 gobject docs minor cleanup + 680459 Extra newline char in local implementation of g_applic... + 680505 object_path memory leak in gdbusobjectproxy.c + 680831 Deprecate and remove g_slice_[sg]et_config.* + 680912 gchecksum: Add g_compute_checksum_for_bytes() + 681151 checksum: Use functions instead of macros when buildin... + 681158 gtlscertificate: Don't confuse certificate and public ... + +* Translation updates: + Galician + German + Gujarati + Hebrew + Norwegian bokmÃ¥l + Serbian + Slovenian + + +Overview of changes from GLib 2.33.4 to 2.33.6 +============================================== + +* GAsyncInitable: partially revert the init_finish changes, + some applications were found to rely on behaviour that + was broken by these changes + +* Bugs fixed: + 679617 win32: fix g_get_environ() + 679968 Add some annotations to GBytes, GVariantType... + 680111 GIOScheduler assumes GCancellable "cancelled... + +* Translation updates: + Spanish + +Overview of changes from GLib 2.33.3 to 2.33.4 +============================================== + +* GMainContext: the source list has been reorganzied to + avoid O(n) behaviour + +* GRegex: Update included PCRE to 8.31 and expose new + functionality in 8.x versions of PCRE + +* GMountOperation gained a ::show-unmount-progress signal + which provides information about slow unmount operations + +* Bugs fixed: + 616892 gio: Add a boxed type for GFileAttributeMatcher + 619329 g_source_attach() O(n) in number of sources + 639771 g_dir_read_name() can also return NULL on error + 661767 merge/improve various bits of run-in-thread fun... + 667375 GAsyncInitable subclassing (and async subclassi... + 671545 Constify collect and lcopy strings in GTypeValu... + 674452 SEGFAULT in gio contenttype test + 674898 Deal with GLIB_VERSION_MIN_REQUIRED/MAX_ALLOWED... + 675504 Fix up GObject interface documentation + 677064 GString: Tweak documentation, add g_string_free... + 677578 error in PCRE error code conversion + 677579 update GRegexError for newer PCRE error codes + 678066 gdbus codegen does not work with python3 + 678273 unicode othercasing is wrong in gregex + 678576 GIOScheduler performance enhancements + 678758 GTlsInteraction unlocks an unlocked mutex + 678808 GTestDBus issues + 678881 Test failures in /socket/timed_wait in some cas... + 678941 /contenttype/guess test case failure + 678944 gio returns the wrong default applications for ... + 678949 wrong definition of ulong_bool for 64 bit big e... + 678959 /mainloop/timeouts race condition: assertion fa... + 679193 update included pcre to 8.31 + 679258 The 'Since' tag for G_SOURCE_CONTINUE and G_SOU... + 679473 Don't generate invalid property names + 679691 Add g_spawn_check_exit_status() + 679671 GDBusNodeInfo: the XML string must contain exac... + 676111 mount-operation: add show-unmount-progress signal + 679691 win32: fix build g_spawn_check_exit_status() wi... + 679813 Documentation bug on http://developer.gnome.org... + +* Translation updates: + Assamese + Belarusian + Bulgarian + Galician + Greek + Norwegian bokmÃ¥l + Polish + Spanish + Traditional Chinese + Vietnamese + + +Overview of changes from GLib 2.33.2 to 2.33.3 +============================================== + +This release contains mostly bugfixes, cleanups and performance +improvements (including many fixes contributed by Colin on the advice of +Coverity). There are a few notable externally-visible changes: + +* Thumbnails are now in XDG_CACHE_HOME + +* new GDBus API: per-thread g_dbus_connection_get_last_serial() + +* GUnixOutputStream now has a can_poll() implementation + +* New deep copy APIs for G(S)List: g_(s)list_copy_deep + +* Bugs fixed: + 518309 Incorrect data*dir path in glib-gettextize output + 566994 Safer passing of -framework flag + 672889 GLib.utf8_validate does segfault + 673253 Not strict enough autconf test for libelf + 675024 adds g_list_copy_deep() and g_slist_copy_deep + 675168 prepare for thumbnails to move to XDG_CACHE_HOME + 675966 gresolver: More robust parsing of DNS responses + 676594 [Patch] fix g_reload_user_special_dirs_cache + 676825 Implement g_dbus_connection_get_last_serial () + 677235 Clarify the comment at the top of gmarshal.list + 677527 OS X: gthread/spawn-async selftest failure + 677718 GDBusProxy: treat org.freedesktop.systemd1.Masked error as non-fatal + 677770 GUnixOutputStream does not implement can_poll + 677782 Install bash completion files in /usr/share + 677817 g_key_file_to_data adds extra blank lines in some cases + 677952 Missing annotation for GDBusConnection signal "closed" + 678052 g_wakeup_acknowledge is called too often. + 678273 unicode othercasing is wrong in gregex + 678333 gdbus-codegen code causes warnings under -Wfloat-equal + +* Translations updated: + Arabic + Assamese + Galecian + Greek + Spanish + Telugu + +Overview of changes from GLib 2.33.1 to 2.33.2 +============================================== + +* GLIB_VERSION_MIN_REQUIRED now defaults to the current stable version + +* GIO input and output stream classes have grown GBytes-based methods + +* GApplication now has hooks to register D-Bus objects before the bus + name is taken + +* Bugs fixed: + 605976 add g_type_ensure(), to ensure that a type has... + 660851 Breakage of code due to changes in the GThread... + 666386 Empathy doesn't open Redirect URI with particu... + 671139 need (transfer async) for io stream buffers + 672329 memory leaks in gutils.c and glib tests + 672548 g_utf8_validate: @str shouldn't end up annotat... + 674111 Provide an accessor for MimeType desktop entry... + 674483 broken configure results when cross-compiling ... + 674634 Add g_clear_pointer() + 674777 What's the (transfer) of g_variant_lookup()? + 675309 gkeyfile: Fix annotations for g_key_file_load_... + 675446 gfile: Plug memory leak in g_file_make_directo... + 675509 add extra dbus hooks + 675832 Incomplete gsettings bash auto-completion + 676208 The tmpl parameter to g_file_new_tmp can be NULL + 676265 GNetworkMonitor leaks a lot of memory + 676277 Document that g_app_info_create_from_commandli... + 676397 g_environ_* should work with NULL envp + 676398 g_spawn_* should take PATH from the passed env... + 676478 Broken gzip decoding + 676594 [Patch] fix g_reload_user_special_dirs_cache + 676816 Add more GLIB_AVAILABLE_IN_* + 676937 Document notify signal deduplication with free... + +* Translation updates: + Czech + French + German + Greek + Japanese + Russian + Slovenian + Spanish + + +Overview of changes from GLib 2.32.1 to 2.33.1 +============================================== + +* GApplication + - can now have a NULL application ID + - add accessors for determining dbus connection and object path + +* g_clear_object: fix warnings when using it on C++ (due to lack of + ability to implicitly cast void*) +* add g_clear_pointer as a generic form of g_clear_object + +* GDBus: + - add our own implementation of the message bus for use on Windows only + - fix up a few bugs that use of this bus uncovered in GDBus + - escape nonce files in dbus addressess (think 'c:\') + - support initial underscores in dbus codegen namespace (for private) + - add GTestDBus for bringing up a session bus for testing purposes + - gdbus-codegen: Avoid warnings in generated code + - GDBusAuthObserver: Add a way to control what authentication mechanisms to use + - + +* Fix misdetection of GNUstep as Cocoa (for the MacOS GSettings backend) + +* make sure configure fails if AC_CHECK_ALIGNOF cannot detect the alignment + +* GAppInfo + - overwrite the DISPLAY only if it is set in the launch context + - add accessor for StartupWMClass + +* glib/tests/date: force US locale running the GDateTime tests + +* Resources: + - fix broken use of GVDB on big endian machines + - set a 'display name' so that pretty file names appear in Gtk CSS + warning messages + +* GMainContext: + - block child sources when blocking the parent + - introduce more testcases for child sources + +* GResolver: add support for MX, TXT, NS and SOA records + +* GSocketControlMessage: Don't warn about unknown messages + +* GIO: + - implement GSeekable for the data and buffered stream classes + - implement GPollable for many more classes as well + - fix GConverterInputStream infinite loop when fill_buffer returns an error + - fileinfo: document the correct type for trash::orig-path + +* test coverage improvements and general fixes + +* new 2.34 stuff: version macros, docs index section, etc. + +* Build: + - add --disable-modular-tests build option + - don't require host binaries if tests are not enabled for cross-builds + +* Translations updated + Brazilian Portuguese + Bulgarian + Czech + French + Galician + German + Hebrew + Hindi + Italian + Norwegian bokmÃ¥l + Polish + Russian + Russian + Serbian + Simplified Chinese + Slovenian + Spanish + Telugu + +Overview of changes from GLib 2.32.0 to 2.32.1 +============================================== + +* Bugs fixed: + 670254 glib-2.30.2: Fails /GDateTime/new_from_unix test + 672541 glib-compile-resources prepends --sourcedir to absolute paths + 673139 URL to mailing lists in README incorrect + 673174 g_input_stream_read[_finish]: document returning 0 on EOF + 673191 glib/gchecksum.c warning: dereferencing type-punned pointer... + 673216 [W32] gtestutils does not use path separators consistently + 673439 Properly deprecate g_value_{set,get}_char + 673612 Fails to decode dictionaries wrapped in two layers of array + 673803 gclosure: Support return values of GVariants + 669285 glib/tests/markup-parse fails under non-english locale + 673911 gio-2.0.pc lists full path to executables, breaking cross com.. + 673762 gnextstepsettingsbackend.c:343: error: parse error before 'in' + +* Updated translations: + Belarusian + British English + Bulgarian + Catalan + Czech + French + German + Hebrew + Hindi + Hungarian + Italian + Japanese + Kannada + Latvian + Lithuanian + Marathi + Norwegian bokmÃ¥l + Odia + Polish + Serbian + Slovenian + Spanish + Swedish + Telugu + + +Overview of changes from GLib 2.31.22 to 2.32.0 +=============================================== + +* It is no longer necessary to use g_thread_init() or to link against + libgthread. libglib is now always thread-enabled. Custom thread + system implementations are no longer supported (including errorcheck + mutexes). + +* The thread and synchronisation APIs have been updated. + GMutex and GCond can be statically allocated without explicit + initialisation, as can new types GRWLock and GRecMutex. The + GStatic_______ variants of these types have been deprecated. GPrivate + can also be statically allocated and has a nicer API (deprecating + GStaticPrivate). Finally, g_thread_create() has been replaced with a + substantially simplified g_thread_new(). + +* The g_once_init_enter()/_leave() functions have been replaced with + macros that allow for a pointer to any gsize-sized object, not just a + gsize*. The assertions to ensure that a pointer to a correctly-sized + object is being used will not work with generic pointers (ie: (void*) + and (gpointer) casts) which would have worked with the old version. + +* It is now mandatory to include glib.h instead of individual headers. + +* The -uninstalled variants of the pkg-config files have been dropped. + +* For a long time, gobject-2.0.pc mistakenly declared a public + dependency on gthread-2.0.pc (when the dependency should have been + private). This means that programs got away with calling + g_thread_init() without explicitly listing gthread-2.0.pc among their + dependencies. + + gthread has now been removed as a gobject dependency, which will cause + such programs to break. + + The fix for this problem is either to declare an explicit dependency + on gthread-2.0.pc (if you care about compatibility with older GLib + versions) or to stop calling g_thread_init(). + +* g_debug() output is no longer enabled by default. It can be enabled + on a per-domain basis with the G_MESSAGES_DEBUG environment variable + like + G_MESSAGES_DEBUG=domain1,domain2 + or + G_MESSAGES_DEBUG=all + +* Bugs fixed: + 671988 Quickly registering / unregistering objects on bus... + 672095 glib needs stable sort function + 672406 glib/tests/include.c fails to build on FreeBSD + +* Updated translations: + Telugu + + +Overview of changes from GLib 2.31.20 to 2.31.22 +================================================ + +* Bugs fixed: + 531901 Use __builtin_bswap* for GUINT*_SWAP_LE_BE if building... + 653167 Out of tree build is broken on windows + 668973 Test /gvariant/parser fails on Solaris 10 + 669797 gvfs now lists its fuse mounts + 670846 deadlock: GStreamer-WARNING **: wrong STREAM_LOCK count 0 + 671664 gio-querymodules: unlink instead of writing empty cache + 671676 Glib can't be cross-compiled any more after merge of... + 671918 gnome-shell is inaccessible unless started while an AT... + 671942 GSocketMsgFlags: annotate as a flags + 671997 Unix signal handling assumes that volatile 1-byte writes... + 672013 GSimpleAsyncResult: support reliable cancellation + 672026 default log output should include pid and/or prgname + 672095 glib needs stable sort function + 672201 G_SPAWN_SEARCH_PATH should continue on ENODEV and ETIMEDOUT + 672239 request NO_REPLY from g_dbus_connection_call() with no as... + 672249 gdbusproxy leaks asyncresult in an error case instead of... + +* Translation updates: + Assamese + British English + Catalan + Catalan (Valencian) + Danish + Esperanto + Finnish + French + German + Hungarian + Korean + Lithuanian + Norwegian bokmÃ¥l + Polish + Portuguese + Russian + Traditional Chinese + + +Overview of changes from GLib 2.31.18 to 2.31.20 +================================================ + +* Update to Unicode 6.1 + +* Update PCRE to 8.30 + +* Deprecations are now versioned, and new API is + marked with the version it was introduced. + Use these with GLIB_VERSION_{MIN,MAX}_REQUIRED + +* The performance of signal emissions has been + improved for simple cases + +* Bugs fixed: + 529806 Cannot build in 64-bit Mac OS X due to libiconv + 580873 Documentation of register type functions incomplete + 592666 Document how to unset an attribute + 597785 g_type_class_add_private code snippet is a bad example + 621368 glib-2.24.1: FAIL: run-assert-msg-test.sh when updating... + 622149 --disable-regex breaks glib2 build + 639873 GBinding: Crash when binding two properties on the same... + 640202 For GLIB v. 2.23.6 and above: impossibility to build mu... + 668295 Need a way to classify GVolume instances + 669670 gasyncqueue: don't use deprecated g_cond_timed_wait() + 670542 Add version information for deprecations + 670557 gvaluetransform: Fix an infinite loop with GFlagsValue... + 670721 global variable for signal ID should be hidden + 670751 IceWM build fails due to the G_DEPRECATED_FOR macro + 670909 g_dbus_connection_call leaks when it receives an error... + 670922 Include path to gdbus-codegen in the pkgconfig file + 670969 GSequence lookup may fail if there was no sort prior to... + 671025 Constants and identifiers starting with a number are no... + 671270 make distclean failures + 671281 glib-compile-resources.xml is missing from the dist tar... + +* Translation updates: + Basque + Belarusian + Brazilian Portuguese + Bulgarian + Galician + Hebrew + Lithuanian + Persian + Punjabi + Serbian + Simplified Chinese + Slovenian + Telugu + Traditional Chinese + Uyghur + Vietnamese + + +Overview of changes from GLib 2.31.16 to 2.31.18 +================================================ + +* GDBusProxy has now a flag, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + which can be set to make GDBus automatically reload + changed properties even if the propertychanged signal + does not contain the new values. + +* GApplication puts non-unique applications on the bus + +* GApplication now has g_application_quit() + +* g_async_queue_timed_pop has been deprecated in favor of + the new g_async_queue_timeout_pop, which uses relative + delays in microseconds instead of a GTimeVal. + +* a huge number of API documentation fixes + +* Bugs fixed: + 647986 put non-unique apps on D-Bus + 658484 vpn connection vs NetworkSecretDialog + 664237 GDateTime falls back to UTC if TZ is set + 669329 gthread-win32: update for g_get_monotonic_time() changes + 669330 glocalfile: fix error code when opening a directory on win32 + 669372 glib/tests memory leaks. + 669412 mem leak in g_environ_unsetenv + 669538 Fix compilation of glib-compile-resources.c on Windows + 669544 gdbus-codegen example introspection XML is not complete + 669595 glib-mkenums: fix handling of forward enum declarations + 669670 gasyncqueue: don't use deprecated g_cond_timed_wait() + 669671 gobject: use #pragmas to avoid deprecated function warnings + 669689 Retrieve cwd and environ in local GApplicationCommandLine + 669810 socket/win32: flush pending read before signaling HUP + 669865 g_regex_fetch() + 670085 memory leak in g_output_stream_write_async + 670138 gbytes.h is missing the G_BEGIN/END_DECL guards + 670485 Simplify session API (shared bug with gtk+) + +* Updated translations: + Belarusian + Danish + Galician + Serbian + Telugu + Hebrew + + +Overview of changes from GLib 2.31.14 to 2.31.16 +================================================ + +* GResource: + - The resource compiler can now convert pngs into + pixel data that can be used without parsing at runtime + (requires gdk-pixbuf-pixdata to be present) + +* Bugs fixed: + 669123 resource compiler: failing to-pixdata should... + 669173 resource: fix xml preprocess entity handling + 669224 Cross-compilation broken by data-to-c + 669253 gsettings set buggy on array values + 669334 fix memory leak in bookmark file parser + +* Translation updates: + Norwegian bokmÃ¥l + Spanish + + +Overview of changes from GLib 2.31.12 to 2.31.14 +================================================ + +* GResource: + - GLib now includes a commandline utility, gresource, + to explore resources in ELF files + - The resource compiler can now optionally strip + ignorable whitespace from XML resources + - The resource compiler can now generate build dependencies + - The resource compiler will now autoselect output formats + +* GApplication: + - The menu markup parser API has been dropped, the + menu XML support lives in GTK+ now + +* GValueArray has been deprecated + +* Bugs fixed: + 626258 N-ary Trees - 'nodes' can be inserted before and after... + 634232 Core Dump / Aborted using g_key_file_to_data + 639099 schema compiler chokes on valid schema + 667228 Deprecate GValueArray + 667243 Add an element clear function to GArray + 667929 glib-compile-resources: xml resources doesn't need to... + 668250 g_date_time_format() produces a non-UTF8 string + 668468 'IP_ADD_SOURCE_MEMBERSHIP' undeclared + 668532 resources: add dependency generator to the resource compiler + 668539 resources: compiler should autoselect output format... + 668561 gresource-tool not internationalized + 668572 glib_cv_g_atomic_lock_free config.cache setting not honored... + 668650 GRealArray->clear_func should be initialized + 668756 GKeyFile: allow loading from empty strings + 668857 fix couple of typos in comments + 669024 goption: implement platform_get_argv0() for OpenBSD + +* Updated translations: + Galician + Norwegian bokmÃ¥l + Spanish + Traditional Chinese + +Overview of changes from GLib 2.31.10 to 2.31.12 +================================================ + +* GApplication: + - Drop support for exporting menus - this functionality + will be provided in GtkApplication + - Add a way to create actions that change settings + +* Bugs fixed: + 629503 Add async versions of g_unix_connection_{receive,send}_credentials + 656301 glib-compile-schemas should not create an empty file + 668071 mingw-gcc build fails on gio/gsocket.[c|h] + 668118 the big appmenu switcheroo + 668158 base64 encode and line termination + 668163 GDBusConnection: note that exit-on-close is sometimes TRUE + 668269 gsignal: add g_signal_handlers_disconnect_by_data + 668279 create GAction from GSettings + +* Translation updates: + Norwegian bokmÃ¥l + + +Overview of changes from GLib 2.31.8 to 2.31.10 +=============================================== + +* GResource: + - A new facility to allow linking data files into binaries + and make them available as resources + - Resources are compiled using glib-compile-resources + - GIO supports resource:/// uris to access resources + +* Bugs fixed: + 619126 Missing dependency libs + 658315 g_key_file_get_keys() should set length to 0... + 660371 is it ever valid to have 0 as a GError domain? + 666700 Add some missing (allow-none) annotations + 667375 GAsyncInitable subclassing (and async subclassing... + 667447 Missing many introspection annotations + 667790 Protect call to pthread_condattr_setclock with define + 667938 wrong gtypes generated for empty flags enums + +* Translation updates: + Hebrew + Spanish + + +Overview of changes from GLib 2.31.6 to 2.31.8 +============================================== + +* GObject: + - The type checks for overriding properties have been loosened. + In particular, it is now possible to add the CONSTRUCT flag + to an overridden property + - GWeakRef is a new API for weak references; unlike g_object_weak_ref + and g_object_add_weak_pointer, it is thread-safe. + +* GHashTable has grown new convenience api for use as a set: + g_hash_table_add, g_hash_table_contains + +* GSocketConnection has gained API for managing connection status + +* GSettings: a native OS X backend has been added, under the + name 'nexstep' + +* Bugs fixed + 455640 Something fishy with GRegex and unicode + 548954 weak references are not threadsafe + 625751 Add G_FILE_ATTRIBUTE_FILESYSTEM_USED + 658871 gbacktrace: g_get_prgname () isn't called for a NULL argu... + 664069 gvariant: Never break out of g_variant_iter_loop + 664830 g_strescape doesn't natively handle \v (vertical tab) + 665211 GDBusConnection singleton access can race with disposal + 665805 Add GSocketClient::action, for tracking socket client status + 666116 some tests provoke undefined behaviour, which is undesira... + 666422 Unreachable code in gio gnetworkmonitornetlink.c + 666551 Crash in g_thread_xp_SleepConditionVariableSRW + 666595 menu parser disallows id='' on submenu and section + 666615 loosen property override flag restrictions + 666616 gobject: fix property override type checks + 666803 g_utf8_validate() fails to validate strings with known size + 666804 g_ateaxit deprecation warning in devhelp points in wrong ... + 666951 g_mkdtemp: Since version incorrect in docs + 666978 Fails to compile glib applications with ISO C90 compiler + 667098 ginetaddressmask leaks its address property + 667225 GSocket: add missing type checks to public methods + 667226 GSocket: fix an error return value + 667279 Sometimes crashes when launching commandline-crea... + 667285 Wrong keyname listed in documentation for g_deskt... + 667331 Use g_queue_free_full() convenience function + 667420 GHashTable GDB pretty printing is broken + +* Updated translations + Belarusian + Bulgarian + Hebrew + Norwegian bokmÃ¥l + Norwegian Nynorsk + Spanish + Vietnamese + + +Overview of changes from GLib 2.31.4 to 2.31.6 +============================================== + +* GApplication no longer has APIs for setting menus. Those have been + moved to GtkApplication. + +* the GActionGroup import/export functionality has been decoupled from + GApplication by the introduction of a new interface for the purpose of + handling platform data: GRemoteActionGroup. This allows Gtk to + properly deal with platform data (and gdk threads) on window actions. + +* lots of documentation improvements + +* bug fixes and a huge number of memory leak fixes + +* the test suite now passes on ARM and some of the GDBus testcase hangs + we've been seeing have been resolved (although others could remain) + +* g_bytes_get_data() API changed: now includes 'size' out parameter + +* new g_queue_free_full() API similar to g_[s]list_free_full() + +* desktop files: use standard "Keywords" now, not "X-GNOME-Keywords" + +* gsettings commandline tool now has --schemadir option for schemas not + installed in the usual place (ie: as part of plugins) + +* Bugs fixed: + 643736 GApplication doesn't emit dbus signals on action updates + 657433 g_queue_free_full() missing + 664699 glib: documentation fixes + 665737 acquire/release gdk threads lock on incoming dbus + 665879 GBytes: add a size argument to g_bytes_get_data + 666113 various leaks in GLib, GIO are visible in the regression tests + 666115 various tests leak memory, obscuring real leaks in the library + 666145 Doc could be more explicite that g_thread_init calls can be droped + 666173 Configure warning - linux/netlink.h usability... no + 666296 Race condition in g_thread_xp_get_srwlock + 666415 Settings tools should allow specifying a schema directory + +* Translations updated: + French + Spanish + +Overview of changes from GLib 2.31.2 to 2.31.4 +============================================== + +* EXPERIMENTAL: Menu support has been added to GApplication. Menus + are exported on the bus, alongside the actions that are already there. + There have also been many related improvements to action group + functionality. + + These new APIs are subject to changes in the coming releases. In + particular, it seems somewhat likely that the APIs for registering + menubars may change in order to accommodate windows with different + types of menubars. + +* GDBusConnection previously directly dispatched destroy notifies when + unregistering objects if the current main context was the same context + the object was exported on. It now unconditionally dispatches these + through an idle on the context. + +* Clean up Requires in pc files. Linking against GIO no + longer drags in gmodule. This may require dependency + fixes here and there. + +* Introduce GBytes, a data type for immutable, fixed-size + byte sequences. This makes the pre-existing GBuffer + API available outside GLib + +* GDBusInterfaceSkeleton can now be exported on multiple + connections + +* Bugs fixed: + 600161 Do not use static GTypeInfo and GInterfaceInfo + 640077 GFileMonitor: Always send CHANGES_DONE_HINT after a move... + 641720 Misleading definition for local_command_line() in GApplic... + 648516 Little comment error and 2 useless lines of code + 651997 Dummy backend for gapplication + 652560 Test for g_ascii_strtod is failing + 662208 failure to initialize a GInitable should be considered... + 662718 GDBusInterfaceSkeleton should be able to export on multi... + 663291 GBytes: Immutable, refcounted sequence of bytes + 664406 Need context for a proper translation + 664455 Build fixes for GLib GIT master (2.31.x) + 664558 GDBusWorker.frozen has a value > 1 in a gboolean + 664559 sys/wait.h not available on windows + 664617 gdbus segfault error 4 in libgio-2.0.so.0.3102.0 + 664635 GMemory{Out,In}putStream _async functions break sub-class... + 664809 Add command line option to gtester to allow skipping tests + 665067 cryptic assertion failure if nonsensical flag combinations... + 665184 Check ref. count before reffing/unreffing + 665298 Add 'Requires.private: libpcre' to glib-2.0.pc + 665391 update documentation around mainloops + 665607 ./configure is there for fiddling with cross-compile enviro... + 665634 g_dbus_node_info_new_for_xml() errors on unknown attributes... + 665685 Add a #define for the max length of a Unicode decomposition + 665733 GDBusConnection holds lock while calling destroynotify + +* Translation updates: + Norwegian bokmÃ¥l + Spanish + + +Overview of changes from GLib 2.31.0 to 2.31.2 +============================================== + +* Monotonic time is now properly supported on Windows + +* glib-mkenums: fix @ENUMPREFIX@ with /*< underscore_name=... >*/ + +* EXPERIMENTAL: introduce new GSettingsSchema and GSettingsSchemaSource + APIs for the convenience of plugin system authors and those who wish + to introspect the contents of schemas. This API may change. + +* Improve the performance of GObject property notifies. + +* GDBus: + - fix a race when unowning a name immediately after owning it + - thread safety improvements on GDBusConnection + - fixes for exit-on-close functionality + +* Deprecations: + - add G_SIGNAL_DEPRECATED + - don't use G_DISABLE_DEPRECATED masking for functions anymore + +* docs + - tmpl/ is finally dead for glib + +* GIO: + - GInetAddressMask: new type for internet address range matching + - various GIO file and stream fixes + - improvements to attribute and fileinfo handling + +Overview of changes from GLib 2.29/2.30 to 2.31.0 +================================================= + +This release contains a huge number of changes (500 commits worth). The +list below attempts to summarise, but not every change is listed. + +* Major changes to threading and synchronisation + - threading is now always enabled in GLib + - support for custom thread implementations (including our own internal + support for errorcheck mutexes) has been removed + - a whole lot of dead code (to deal with the non-threaded case) has + been ripped out. This includes the racy path of GMainContext that + caused deadlocks with respect to child process exits in + single-threaded programs (such as gtester). + - libgthread is now an empty shell and g_thread_init() is no longer + required (and has been deprecated) + - GMutex and GCond can now be statically allocated without explicit + initialisation. Dynamic allocation for these types is deprecated. + - new types GRecMutex and GRWLock can also be statically allocated + without explicit initialisation. + - GPrivate can now be statically allocated and has an improved API. + Dynamic allocation of GPrivate is deprecated. + - GStaticMutex, GStaticRecMutex, GStaticRwLock, GStaticPrivate are + deprecated. + - GCond now uses monotonic time internally and a new API takes + monotonic time for timed waits, deprecating the wallclock API + - removal of the insane macro indirection used in the previous + implementation of threading and synchronisation APIs + - use SRWLock and CONDITION_VARIABLE APIs when available on Windows + (Vista and later) and emulate them on XP + - leaks of G(Static)Private-allocated data on some cases of thread exit + have been fixed + - simplified new thread creation API with the old API deprecated. The + concept of joinability has disappeared (all threads are joinable) as + have priority levels, 'bound'ness (ie: kernel vs. userspace threads) + and ability to manipulate the stack size. + - GThread is now a refcounted type + - other implementation details changed + +* Move headers for some deprecated functionality to a separate + deprecated/ directory. + +* New support for attribute-based deprecations to issue compiler + warnings instead of breaking the build and/or giving warnings about + implicit declarations (and possibly miscompiling). + +* GCache has been deprecated (after its last use was removed from our + platform over a year ago). + +* It is no longer possible to include individual headers (like + "ghash.h") -- you must #include . + +* The misguided experiment of allowing the program to stumble along with + missing GSettings schemas is now over -- the abort is back. + +* Clarify that fork() is not valid while using GMainContext. This is + because the internal resources of the GMainContext end up being shared + by both processes. We had an assert here but it was breaking existing + (valid) use cases as well, so it has been removed for now. + +* GApplication + - add ::shutdown signal as logical dual to ::startup + - don't use a GMainLoop: iterate the GMainContext directly (improves + quit logic) + +* Several portability fixes for Windows, OpenBSD, Solaris + +* Add new GValue API to specifically deal in signed chars (in case the + platform defines 'char' as unsigned) + +* some new API to mitigate the problems associated with calling setenv() + in a multi-threaded program + +* Use CLOCK_MONOTONIC unconditionally if the libc has support at compile + time (ie: stop checking for kernel support at runtime). + +* pkg-config files: + - drop -uninstalled variants + - remove gobject dependency on gthread + +* New macro G_ATOMIC_LOCK_FREE is defined if the atomic operations are + implemented without use of a mutex. Cleaned up atomic-related + compilation issues with mingw compilers on win32 systems. + +* SOCKS proxy and resolver improvements + +* Fix the spelling of G_IO_FLAG_IS_WRITABLE (was WRITEABLE) and + introduce a macro for backwards compatibility. + +* GDBus: + - many code generation updates and improvements + - some race condition fixes, including testcase hangs + +* GVariant: + - new g_variant_new_from_fixed_array() API + - substantial docs improvements/clarifications + +* GKeyFile is now refcounted and boxed + +* mount monitoring is now based on /proc/mounts (where available) + instead of mtab + +* new macros G_SOURCE_CONTINUE and G_SOURCE_REMOVE for returning from + GSourceFunc (so you don't have to remember what TRUE and FALSE mean) + +* use xlocale functions where available to avoid too much heavy lifting + in functions like g_ascii_strtod() + +* GMappedFile can now be created from an fd + +* error message strings grammar/i18n fixes + +* many docs updates + +* Partial list of bugs closed: + 70598 Unify GStaticMutex and GMutex. + 320888 optimization for g_main_context_wakeup + 398418 GChildWatch race condition? + 527214 g_timer_elapsed() returns random values + 580505 add a way to set/get name for a thread + 583511 race condition means g_main_loop_quit() does not work + 590808 GKeyFile should have a refcount and a boxed type in GObject + 592715 Document that g_str_hash() and g_int_hash() are not NULL safe + 631413 Add macros for GSourceFunc return values + 632049 not immediately clear what g_variant_get_fixed_array expects + 640212 "Error stating file" is not a friendly message + 640293 Use xlocale functions to implement g_ascii_strtod() + 640975 Check that error exists before trying to set it + 643934 GApplication lacking a logical dual for the ::startup signal + 651268 assertion failed in GDBus worker thread + 653987 g_key_file_get_integer cannot interpret trailing spaces + 654412 Documentation for g_variant_get_child_value unclear + 654563 info capplet: Failed to calculate disk space + 655366 missing GSettings schemas lead to obscure crashes + 656621 g_spawn_*() calls executables in current directory + 656679 [gi] Add two annotations to gio + 657992 Add glib__private__() API to share between glib,gio + 658188 _set_as_last_used_for_type generates a broken mimeapps.list + 658206 gsocks5proxy.c has invalid gettext use + 658207 glib-compile-schemas says "can not" + 658558 simpleaction: Fix documentation of :enabled + 658683 clean up charset/language threading issues + 658692 add introspection annotations to g_time_val_from_iso8601() + 658715 Duplicite strings + 658769 Invalid reuse of GError in GThreadedResolver + 658806 sign error in string hash implementation + 658976 gdbus-codegen's C namespace option needs to support Ugly_Case + 659070 gdbus-codegen generated code segfaults when property changes + 659082 gdbus-codegen: Single letter namespaces get dropped from names + 659212 GMappedFile should fail on non-regular files + 659324 _SPLICE_CLOSE_TARGET doesn't mark the output stream as closed + 659423 Use adaptive mutexes when available + 659427 Move deprecated code to a separate directory + 659646 gdbus-codegen produce code that warnings at build + 659690 Possible build warning in code generated by gdbus-codegen + 659699 property name collision when generating code for "Connection" + 659754 Add API to GMappedFile that allows to pass FD + 659838 incorrect types in introspection for g_object_bind_property + 659866 pthread_rwlock_t requires defined __USE_UNIX98 + 659870 gvalue: Fix signedness of g_value_get_char() + 659889 glib-2.29.92/gio-2.0.pc.in has a wrong line. + 659916 GObject size of 64K is not actively enforced + 659920 Missing setter for read/write property 'closed' of GIOStream + 659923 Add g_variant_new_fixed_array() function + 660013 Remove old g_atomic configure cruft + 660096 glib/rwlock tests failure (tests asserted) + 660130 Possible loss of user data when updating mimeapps.list + 660147 tracker causes g_critical in "gsettings list-recursively" + 660413 Make G_ASSERT_STATIC work with clang + 660498 Generated test code fails when the codegen changes + 660511 Use /proc/mounts for monitoring mounts, not /etc/mtab + 660536 Expose options for /etc/fstab entries + 660635 Deprecate g_thread_foreach + 660637 Pending dbus method calls not canceled on connection loss + 660739 kill off g_{mutex,cond}_{new,free}() + 660740 make GThread more standard + 660741 g_cond_timedwait is a disaster + 660743 macro wrappers for g_once_init_enter/leave + 660744 finish killing g_thread_init() + 660745 GPrivate leaks on Windows + 660791 [gio] Improve doc for g_file_make_directory_with_parents() + 660843 asyncqueue-test is broken + 660849 Remove cruft from g_strerror and g_strsignal + 660886 GDBusProxy: don't drop/complain about unknown props/signals + 660887 g_slice_set_config() is broken + 660994 Add g_main_context_ref_thread_default() + 661255 gio: enable test_peer regression test for OpenBSD + 661257 giomodules.c uses ":" instead of G_SEARCHPATH_SEPARATOR_S + 661318 tests use pthread without appropriate compiler/linker flags + 661421 Applications fail to initialize on GNU Hurd - commit + 661438 Implement G_GNUC_DEPRECATED/G_GNUC_DEPRECATED_FOR on Visual C++ + 661711 Sorting keys for GDrive, GVolume and GMount instances + 661763 desktop-app-info: Add support for X-GNOME-Keywords + 661896 /gdbus/connection/life-cycle is racy + 661914 Gstreamer/Totem locks up + 662100 regression: g_dbus_connection_close() triggers exit-on-close logic + +* Translations updates: + Belarusian + Brazilian Portuguese + British English + Bulgarian + Catalan + Catalan (Valencian) + Czech + Danish + Esperanto + French + Gujarati + Hebrew + Hungarian + Italian + Japanese + Lithuanian + Norwegian bokmÃ¥l + Oriya + Polish + Russian + Serbian + Simplified Chinese + Slovak + Slovenian + Spanish + Tamil + Vietnamese + +Overview of changes from GLib 2.29.18 to 2.29.90 +================================================ + +* GObject includes a generic marshaller, g_cclosure_marshal_generic. + To use it, simply specify NULL as the marshaller in g_signal_new(). + The generic marshaller is implemented with libffi, and consequently + GObject depends on libffi now. + +* API/ABI changes: + - unix signal watches now match the API of all of the other sources + - revert the addition of g_date_time_source_new () from last release + +* networking and other fixes for Solaris + - we no longer support symbolic port names (ie: from /etc/services) + - check if -lsocket is needed + - fix g_socket_details_from_fd() + - avoid getmntinfo + - fix some harmless warnings + +* GDateTime improvements: + - generally improved standards compliance (with C99) + - support C99-specified format strings: %g, %G, %V, %c, %C, %w + - consult the locale for the preferred 12-hour time format (%r) + - drop support for non-standard %N and broken %W + - better support for formatting non-POSIX (eg: Arabic) numerals + - locale-related test case fixups, and fix some leaks + +* GTlsInteraction: add interaction method invocation guarantees + +* gdbus-codegen: post-process all interfaces when parsing >1 file + +* make GMainLoop, GMainContext and GSource boxed types + +* fix a race condition in the first use of g_get_monotonic_time() + +* lots gtk-doc cleanups + +* better intltool compatibility when generating pot file + +* avoid GCC-specific compiler options when not using GCC + +* Translation updates: + Belarusian + Brazilian Portuguese + Canadian English + Galician + Indonesian + Korean + Lithuanian + Norwegian bokmÃ¥l + Portuguese + Spanish + Swedish + +Overview of changes from GLib 2.29.16 to 2.29.18 +================================================ + +* GDateTime is now respecting LC_TIME when formatting + +* GTimeZoneMonitor has been removed again + +* A new API for wallclock functionality has been added: + g_date_time_source_new(). This API is still experimental + and may be changed or removed before 2.30. + +* Bugs fixed: + 628904 Add credential support for FreeBSD and fix a socket issue + 650763 gdbus-codegen is broken with python 2.7 + 655129 GDateTime could provide api for implementing wall clocks + 656341 gtlsconsoleinteraction.c uses getpass() which isn't avail... + 656387 GCancellable can be used concurrently + 656443 Make GTlsInteraction ask_password cancellable + 656675 void functions should not return in glib 2.29.16 + 656772 g_variant_compare for uint64 incorrect + 656914 Load GIO_EXTRA_MODULES first, and ignore duplicates + 657083 The header langinfo.h is not available on all systems + 657084 gfileutils: fix docs/annotations for temp file methods + 657138 Some files missing in POTFILES.in + 657206 GInputStream leaked in g_file_icon_load_async() + 657243 g_cancellable_set_error_if_cancelled() documentation + 657274 Use detected PYTHON variable as shebang for gdbus-codegen + 657336 Speling fixes for glib found with codespell + 657452 plural forms needed + 657454 Translation comment needed + 657540 Print out file:// URL to coverage HTML report after building + 657593 g_test_trap_fork calls close(-1) + 646082 Addresses from GSocket should be normalized before returning + 657517 fix gio/tests/gdbus-peer on bsd + +* Translation updates: + Brazilian Portuguese + Galician + Norwegian bokmÃ¥l + Punjabi + Russian + Serbian + Spanish + Swedish + Traditional Chinese + Uighur + + +Overview of changes from GLib 2.29.14 to 2.29.16 +================================================ + +* GTlsDatabase: an abstract class that provides support + or certificate and key lookup. An implementation will + be provided in glib-networking + +* GHmac: Support or HMAC digests + +* Misc new API: + - g_ptr_array_add_full: creates a GPtrArray with + a preallocated size and a destroy function + - g_desktop_app_info_get_show_in: checks if a GDesktopAppInfo + should be shown in a given desktop environment + - g_mkdtemp, g_mkdtemp_full, g_dir_make_tmp: create + temporary directories + +* Unify thread wakeup implementations of GMainContext + and GCancellable, and use eventfd for it when available + +* Show mounts in $XDG_USER_DIR in addition to /media and $HOME + +* Bugs fixed: + 636572 GTlsCertificateDB + 644601 Some tests need a running dbus session + 652284 deal with small key lengths + 652827 glib-2.29.8 no longer builds with mingw.org's toolchain + 653063 PEM parser fails parsing private key when put first + 654078 Fail to static linking with Glib library + 654450 New functions: g_ptr_array_new_full() + 654793 Add G_VALUE_INIT + 655044 GDesktopAppInfo: Add g_desktop_app_info_get_show_in() + 655148 gdbusconnection is broken when compiling with mingw + 655241 glocalfile.c no longer compiles with MinGW GCC + 655598 g_cancellable_get_fd: silently return -1 for NULL cancellable + 655664 gdbus should not abort if no dbus session is available + 655769 Use ZLIB_CFLAGS when compiling gio + 656031 Improve GVariant annotations + 656048 glib-codegen requires Python >= 2.5 + 656151 configure test logic inverted, doesn't match comments + 656152 GCC only syntax used, yet other compilers allowed by configure. + 656162 allow use of lcov 1.9 for coverage + 656282 GDBusProxy: uninitialized local variables can be freed + 656283 Failing tls connection cause assertion + 118563 Add g_mkdtemp in the spirit of g_mkstemp + 636405 Add g_return_if_fail() to g_settings_bind_with_mapping() + 656039 race condition between GDBusProxy signals and public API + 656492 g_io_channel_new_file failure (open(2) behavior wrt POSIX) + +* Translation updates: + Bulgarian + Esperanto + French + Galician + German + Hebrew + Indonesian + Italian + Norwegian bokmÃ¥l + Russian + Spanish + Swedish + + +Overview of changes from GLib 2.29.12 to 2.29.14 +================================================ + +* Unicode improvements + - add g_unicode_script_{to,from}_iso15924 + - add G_UNICODE_SPACING_MARK define + - more normalisation improvements + - stop using deprecated g_unicode_canonical_decomposition() + +* GParamSpec: + - mark the 'name' field as 'const' and add a comment to the header to + help avoid future problems caused by bad hacks + +* Merge some (modified) patches from Debian: + - 03_blacklist-directories.patch + - add some blacklisted mount directories + - 60_wait-longer-for-threads-to-die.patch + - sleep longer in a test case, if needed to avoid failing + +* Units policy change: prefer use of SI units + - deprecate g_format_size_for_display, add g_format_size(_full) + +* GSettings: don't call g_error() when the schema is missing + +* GVariant support for arrays of object paths: + - new g_variant_{new,get,dup}_objv API + - support for g_variant_{new,get} '^ao' and '^a&o' similar to '^as' + +* GDBus: + - use new improved array-of-objects support and pass 'ao' as char** + instead of GVariant* + - improve handling of 'h' type (Unix file descriptor index) + +* GIO: + - fix compilation without USE_STATFS and USE_STATVFS + +* Documentation fixes + +* Bugs fixed: + 622921 Migrate from dbus-glib to glib's GDBus + 648271 Add g_unicode_script_to_iso15924() + 654948 Stop using deprecated g_unicode_canonical_decomposition() + 654988 g_atomic_int_add should document behaviour change + 655025 #define G_UNICODE_SPACING_MARK G_UNICODE_COMBINING_MARK + 655076 normalization misses some Full_Composition_Exclusion=True. + +* Translations updated: + Spanish + +Overview of changes from GLib 2.29.10 to 2.29.12 +================================================ + +* Add new API to do Unicode (de-)composition in atomic steps, + for use in Harfbuzz. + +* Bugs fixed: + 615895 (indirectly) support non-NULL-terminated regexes in GRegex + 617949 glib trunk fails to compile on Solaris w/ Studio 12... + 620423 Document the possibility to unset attributes + 627974 Floating reference headaches + 644687 Not finding cross-links in current doc set + 649246 g_output_stream_splice() cannot be used on 32-bit machines... + 653841 a helper script to build glib from git master on win32 + 653935 g_slist_free_full/g_list_free_full iterates twice in the list + 654017 tests: fix glib_translations_work() in gsettings unit test + 654085 Don't needlessly use "echo -e" when creating .def files + 654195 Add g_unichar_compose() and g_unichar_decompose() + 654232 GCancellable eventfd problems + 654394 suspicious use of floating references in GDBusInterfaceSkeleton + 654536 GSettings: lift key name length restriction to 64 + 654627 GParamSpec: intern property names + 654651 Better g_unicode_canonical_decomposition() + 654917 Make g_cclosure_marshal_generic the default signal handler + +* Translation updates: + Belarusian + Finnish + Korean + Latvian + Lithuanian + Norwegian bokmÃ¥l + Turkish + + +Overview of changes from GLib 2.29.8 to 2.29.10 +=============================================== + +* New features: + - g_desktop_app_info_get_nodisplay: a function that is required + to port gnome-menus to GDesktopAppInfo + - g_hash_Table_iter_replace: new function to replace a value + while iterating over a hash table + - g_utf8_substring: convenience API to extract substrings from + UTF-8 strings + - g_action_group_add_entries: convenience API for creating lots + of actions quickly + - Use eventfd instead of pipes for waking up main contexts and + for cancellation when available + - GMatchInfo is now a refcounted boxed type + +* API changes in GAction: + - the 'set_state' entry in the GActionInterface vtable has been + renamed to 'change_state + - g_action_set_state has been renamed to g_action_change_state + - the 'state' property has been changed to read-only + - GSimpleAction can no longer be subclassed + +* Bug fixes + 647796 g_variant_new_variant is not marked as constructor + 652072 gmain: make use of signalfd() + 652168 Crosscompiling Fails if build<=2.24 and host >2.24 + 652750 make dist fails + 652758 GDataInputStream: Clarify g_data_input_stream_read_line docs... + 652822 Add a g_hash_table_iter_replace + 652897 tiny docs clarification for g_utf8_to_ucs4_fast + 653140 gmain: use Linux eventfd() for main context wake up + 653429 drop AM_MAINTAINER_MODE or enable it by default + 653484 GAsyncCallbacks should default to allow-none + Add missing fundamental types to the generic marshaller + +* Translation updates + Belarusian + Galician + Russian + +Overview of changes from GLib 2.29.6 to 2.29.8 +============================================== + +* Bug fixes + 646608 export_symbols variable for gio dynamic library is wrong + 646635 Fix introspection of GLib + 647930 Documentation: GDataInputStream _read_upto() version + 651745 Switch to _ prefixing rather than G_GNUC_INTERNAL + 651920 Improve qsort_r detection + 651959 gbitlock: "asm goto" is not available in gcc < 4.5 + 651998 gdbus-codegen: Use relative Python imports + 652000 Fix for gatomic.c on Windows/MSVC + 652002 Proposal to clean up gvaluetransform.c for MSVC + 652025 g_dbus_connection_register_object: error is not set... + 652081 Typos in a GBinding warning message + 652197 Improper handling of double values in GDBusMessage + Fix a deadlock in gobject finalization + +* Translation updates: + Czech + Galician + German + Hebrew + Norwegian bokmÃ¥l + Spanish + Uighur + + +Overview of changes from GLib 2.29.4 to 2.29.6 +============================================== + +* Atomic operations have been rewritten from scratch to make use + of gcc builtins where possible. As a side-effect of this, calls + to g_atomic_ API with explicit casts may now be problematic; if + that happens to you, try first to remove the casts. Another + side-effect of the rewrite is that g_atomic_int_exchange_and_add + has been deprecated in favor of g_atomic_int_add. + +* A full set of atomic operations on pointers has been added, + including bit locks in pointer-size locations. + +* Access to quarks is now lockless + +* GObject data scalability has been greatly improved + +* g_data_time_format now supports alternative digits and padding + +* Introspection improvements: + - Add a boxed type for GVariantBuilder + - Annotation fixes in GDBus, GVariant, g_base64_ + +* Bugs fixed: + 502560 g_rand_double_range returns 'inf' + 612729 g_mkdir_with_parents can fail if the directory already exists + 617491 g_once() implementation is inefficient + 619418 Add a performance test for UTF-8 decoding functions + 619435 Make g_utf8_to_ucs4_fast() yet faster + 626549 G_STATIC_ASSERT_EXPR + 631231 bitlock: Fix detection and usage of futexes with Bionic + 632294 g_queue_remove() should return a boolean + 640518 GMainLoop has quadratic complexity when all pollfd's... + 642026 Race condition in g_static_private_free + 646635 Fix introspection of GLib + 648678 g_date_time_format(): support %O flags for localized numbers + 649480 Use MSG_CMSG_CLOEXEC in recvmsg in gio/gsocket.c + 649506 GTestFunc et al lacking Since tag + 649657 Don't return gboolean for functions that throw + 649775 glib-gio-gdbuscodegen-Makefile.patch + 649915 gsettings accepts unquoted strings longer than two characters + 649973 gthread: build unix tests only on unix + 649988 gdbus-codegen: Drop dependency on argparse + 650078 forkbomb building glib/tests/protocol + 650211 Optimization in key file parsing + 650236 Application over DBus implements action state incorrectly + 650345 g_key_file_has_key_full: New function to fix g_key_file_has_key... + 650458 reduce overhead in g_object_set/get_data + 650459 hash table consistency while calling destroy notify funcs + 650688 enforce rules about hash table modification + 650823 expand the set of atomic ops + 650874 codegen chokes on docs + 650882 use stdout instead of stderr for informational messages + 650884 fix compilation with gcc2 + 650885 implement glib credentials on OpenBSD (hackish) + 650935 G_GNUC_MAY_ALIAS and atomic ops + 651009 minor documentation fix + 651034 Regarding g_cond_wait after g_thread_pool_push in gthreadedresolver + 651133 race condition in GDBusConnection's emit_signal_instance_in_idle_cb + 651141 hashtable infinite loop + 651219 fix path to true(1) on OpenBSD + 651223 Fix some compile warnings on OpenBSD + 651327 Minor fixes for the gsocket API + 651467 Add pointer sized bitlocks + 651650 gdbus: Avoid busy wait loop + 651725 gmain: Cleanups and a new test case + 651745 Switch to _ prefixing rather than G_GNUC_INTERNAL + +* Updated translations: + Catalan (Valencian) + Esperanto + Hebrew + Hungarian + Russian + Spanish + + +Overview of changes from GLib 2.29.2 to 2.29.4 +============================================== + +* GDBus: + - Includes several new types to support modeling D-Bus + objects and interfaces more fully, and also introduces + an 'object manager' pattern: + GDBusInterface, GDBusObject, GDBusObjectManager + These interfaces have client-side implementations: + GDBusProxy, GDBusObjectProxy, GDBusObjectManagerClient + And server-side implementations: + GDBusInterfaceSkeleton, GDBusObjectSkeleton, GDBusObjectManagerServer + - The new gdbus-codegen utility uses these new classes + to generate C code and documentation from D-Bus interface + descriptions in XML + +* GTest: + - There is now a g_test_fail() function to mark + tests as failed + +* GDesktopAppInfo + - Now has a binding-friendly filename property + - Other new API to more fully expose desktop file contents: + g_desktop_app_info_get_categories(), + g_desktop_app_info_get_generic_name() + +* GHashTable: + - Several optimizations to reduce space consumption of + large hash tables, in particular tables that are used + to store sets. + +* Unix-specific APIs: + GLib now installs a separate header, glib-unix.h, that is + meant to collect Unix-specific APIs. For now, it contains + g_unix_open_pipe(), g_unix_set_fd_non_blocking() for dealing + with pipes and fds, as well as APIs to create mainloop + sources which can trigger callbacks on certain Unix + signals (SIGTERM, SIGHUP, SIGINT). + +* Bugs fixed: + 631379 GDBus nonce-tcp test failing + 632631 GLib-CRITICAL **: g_variant_new_string: assertion `g_utf8_validate (string, -1, NULL)' failed + 635694 gdbus aborting due to unauthorized socket in DBUS_SESSION_BUS_ADDRESS + 637561 Crash when using G_DBUS_SERVER_FLAGS_RUN_IN_THREAD + 642935 g_date_time_format() prints wrong value for %z and timezone -0800 + 643134 g_dbus_message_copy + 644941 glib-unix: New Unix-specific API + 646013 g_hash_table_remove_all_nodes optimization + 646309 glib cannot be cross-compilled for mingw32 + 646435 GTimeZone doesn't seem to be thread-safe + 646957 GIO chained calls don't work with a thread default context + 647594 README link to mailing list is broken + 647602 Cannot connect to remote message bus via TCP + 647746 The GSocketService documentation is incomplete. + 647826 API: gtester: Add g_test_fail() + 647903 GDesktopAppInfo: Add g_desktop_app_info_get_categories() + 648416 g_app_info_create_from_commandline ignores SUPPORTS_STARTUP_NOTIFICATION + 648423 Support G_DEBUG=trap-warnings + 648425 GDesktopAppInfo: Add "filename" property for bindings + 648966 Update g_unichar_iswide and g_unichar_iswide_cjk + +* Updated translations + Norwegian bokmÃ¥l + Spanish + Turkish + Uighur + + +Overview of Changes from GLib 2.28.0 to 2.29.2 +============================================== + +* GApplication + - The documentation has been enhanced and clarified + - An opt-out for uniqueness has been added: G_APPLICATION_NON_UNIQUE + - GApplication now syncs settings before g_application_run() returns + +* GDBus + - Interface lookups are now happening in constant time + - Signature checking and handling of various unexpected + situations has been improved + +* GVariant + - The format accepted by the GVariant parser has beend documented + - GVariant accepts G_VARIANT_TYPE_VARDICT for a{sv} + +* GDateTime: + - The return value of g_datetime_compare() has been fixed to + match strcmp() semantics + - In order to handle problems with changing timezones, a GTimeZoneMonitor + has been added to GIO, and g_time_zone_refresh_local() can be + called to update the cached information about the local timezone + +* GOption now uses /proc/self/cmdline to set the program name instead + and only falls back to "" if that is unavailable + +* GSettings: + - The schema compiler now warns about references to non-existing schemas + +* Commandline utilities are now fully translated + +* Signals can now indicate that collecting their arguments must + always happen, even in the absence of connected signal handlers, + using the G_SIGNAL_MUST_COLLECT flag. + +* Bugs fixed: + 635099 Memory leak in gdbus introspection when parsing xml + 640489 $ and ^ do not match lines if G_REGEX_MULTILINE|G_R... + 642042 Overriding GDBus org.freedesktop.DBus.Properties im... + 642052 g_timeout_add(_seconds) cannot handle large intervals + 642490 notify_desktop_launch() "g_variant_new_bytestring:... + 613269 g_type_get_qdata() doesn't work as I expected on subtypes + 624943 G_VALUE_NOCOPY_CONTENTS is undocumented + 637738 object_interface_check_properties never actually executes + 638185 GIOCondition should be annotated as "flags" + 639478 GDBusServer's g_dbus_server_new_sync() function should just... + 641755 Add g_settings_get/set_uint() helpers + 641768 dconf gsettings backend silently drops writes if it can't... + 642797 g_app_info_get_default_for_type() broken for subtypes + 642825 Unnecessary assertion failure in g_option_context_parse() + 642944 NULL key lookup using g_hash_table_lookup_extended() + 643074 Incorrect documentation for g_socket_receive() and g_socket... + 643197 g_application_id_is_valid docs imply no valid ids + 643468 GApplication docs: Warn that handling "command-line" means... + 643478 GApplication::local_command_line vfunc documentation seems wrong + 643624 Can g_variant_unref() on an already free'd variant + 643649 g_application_run() should say that argc/argv can be NULL + 643780 shouldn't need to create an action group to use actions... + 643795 g_timeout_add_seconds fires with intervals 1 second longer... + 644309 Program name is not set when using GtkApplication + 644428 Crash in failure section of g_markup_collect_attributes() + 644465 undefined reference to `_usleep' + 644552 g_timeout_add_seconds(1, ...) may have a latency of up to 2... + 644607 Correct internal definition of C_() + 645789 annotations for g_file_*_contents + 646039 g_settings_list_children() returns child that cannot be opened + 646310 Accept range with only min or max + 646420 g_dbus_method_invocation_get_parameters() docs should say... + 646843 occasional abort on autologin + 646985 add G_APPLICATION_NON_UNIQUE flag + 647579 gsettings: Implement reset-recursively + 647600 gsettings description has typo + +* Translation updates + Afrikaans + Bulgarian + Bengali India + British English + Bulgarian + Catalan + Czech + Danish + French + Galician + German + Greek + Gujarati + Hebrew + Hungarian + Italian + Japanese + Korean + Lithuanian + Polish + Portuguese + Romanian + Serbian + Simplified Chinese + Spanish + Swedish + Traditional Chinese + Uighur + Vietnamese + + +Overview of Changes from GLib 2.27.93 to 2.28.0 +=============================================== + +* The GApplication API has changed compared to the version that was + included in the 2.25 development snapshots. Existing users will need + adjustments. + +* Bugs fixed: +641363 GInitable documentation isn't clear about that finalize... +641395 Add more data about the origin application to the "Lau... +641411 gdesktopappinfo signals lost if it's the session bus... +641477 glib-mkenums uses unportable #! line +641572 Add @EXEEXT@ to pkgconfig binary name +641688 glib installs GSettings.html and gsettings.html + +* Translation updates: + Galician + Italian + Korean + Punjabi + + +Overview of Changes from GLib 2.27.92 to 2.27.93 +================================================ + +* Bugs fixed: + 637013 gio/gdbusmessage.c fails to compile on Solaris + 640192 Error creating a Gio.Settings object through py... + 640261 Minimum version for external pcre needs to be.. + 640262 GActionGroup contains redundant TYPE macros + 640436 Make load_user_special_dirs() resistant to non... + 640695 g_key_file_load_from_file() mishandles a CR-LF... + 640724 can't compile gio due to format string issues + 640725 can't compile tests due to format string issue + 640807 improve GVariant behaviour with invalid pointers + 640823 wrong documentation for g_source_add_child_source + +* Translation updates: + Bulgarian + Galician + Hebrew + Norwegian bokmÃ¥l + Spanish + Traditional Chinese + + +Overview of Changes from GLib 2.27.91 to 2.27.92 +================================================ + +* Update to Unicode 6.0 + +* Update PCRE to 8.12 + +* Bugs fixed: + 637696 g_unix_connection_send_fd() doesn't work + 638872 null settings backend bug + 640042 GtkApplication's warning about not connecting... + +* Translation updates: + Arabic + Basque + Estonian + Greek + +Overview of Changes from GLib 2.27.90 to 2.27.91 +================================================ + +* Bugs fixed: + 638838 gdesktopappinfo: Don't crash if we don't have a desktop filename + 638894 Splitting on \s* gives no result + 639064 Update gschema.dtd + 639084 Copy/paste error in GSettings::writable-changed signal + 639177 SIGSEGV for GApplications with G_APPLICATION_IS_SERVICE + +* Translation updates: + Estonian + Galician + Indonesian + + +Overview of Changes from GLib 2.27.5 to 2.27.90 +=============================================== + +* Test reports created by gtester-report can now + include revision information + +* The g_desktop_app_info_launch_* family of functions + now emit a DBus signal when an application is launched. + Additionally, there is a new variant + g_desktop_app_info_launch_uris_as_manager(), which + gives more control over the launched process. + +* The memory and null GSettings backends are now available + as public API + +* g_get_locale_variants() is a new function that returns a + list of variants of a locale identifier + +* Bugs fixed: + 587898 I/O timeouts for GSocket + 606960 gio: Add extension point for informing parties... + 631980 Handle an optional node in the report... + 634569 Document that g_variant_builder_add_value consumes... + 635998 Make _g_compute_locale_variants public + 636806 Add g_{memory,null}_settings_backend_get_default + 637262 Need a binary DER version of ::accepted-cas + 637544 Skip fsync() on btrfs + 637720 void functions should not return a value. + 637738 object_interface_check_properties never actually... + 637759 GIOChannel: fix a crash in g_io_channel_read_chars() + 637852 Updates to glib.vsprops file for MSVC 2008 builds... + 637858 Updates to test/testglib.c... + 638349 parameter name of g_variant_new_* may conflict... + +* Translation updates: + Hebrew + Norwegian bokmÃ¥l + Simplified Chinese + Spanish + Swedish + Uyghur + Vietnamese + + +Overview of Changes from GLib 2.27.4 to 2.27.5 +============================================== + +* Network support: + - Add g_tls_certificate_verify() to verify a certificate + - Add GTlsConnection:use-system-certdb + - Other TLS api additions + +* GIO: + - Add g_io_stream_splice_async()/_finish() to splice two iostreams + - Add g_emblemed_icon_clear_emblems() and make GEmblemedIcon derivable + - Remove GPeriodic; it did not receive the necessary review and + integration work to declare it stable + +* GSequence: + - New methods g_sequence_lookup() and g_sequence_lookup_iter() + +* Bugs fixed: + 617254 Missing g_sequence_lookup + 632544 g_dbus_connection_send_message can not send a locked message... + 633350 g_hostname_to_ascii() ignores non-ascii dots + 634583 Better error reporting for g_variant_parse() + 635007 gsetting enum rule don't work for out-of-srcdir builds + 635626 GDBus message idle can execute while flushes are pending + 636100 Can't read GSettings:backend property + 636305 Typo on g_queue_remove_all() function description + 636311 appinfo: tweak application positioning for content-types + 636351 g_simple_async_result_is_valid lacks a version tag + 636387 gdb autoload files shadow the "dir" builtin + 636673 g_simple_async_report_error_in_idle should allow object... + 637147 Add a "delay-apply" property to GSettings + 637171 emblemedicon: add g_emblemed_icon_clear_emblems() + 637237 gapplication: plug a memory leak + +* Translation updates: + Estonian + Galician + Hebrew + Norwegian bokmÃ¥l + Simplified Chinese + Spanish + Traditional Chinese + Vietnamese + + +Overview of Changes from GLib 2.27.3 to 2.27.4 +============================================== + +* GIO + - Mounts are treated as hidden if they have a path element + that starts with a dot + - GAppInfo gained API to differentiate between recommended + and fallback mime handlers + - g_cancellable_create_source: creates a GSource that triggers + when the GCancellable is canceled + - GPollableInput/OutputStream: Interfaces for pollable streams + - TLS support has landed, with an extension point that is + implemented in glib-networking + +* GLib + - Mainloop sources can now have 'child sources' + - g_get_runtime_dir: New function to return the XDG_RUNTIME_DIR + +* Bugs fixed: + 530786 GFileMonitor "changed" signal underdocumented + 588189 TLS support for GSocket* + 630357 g_object_new_valist uses uninitialized memory + 630559 typo in public string in gsocks: 'The SOCKSv5 require... + 632445 Documentation refers to removed GNOME 2.0 porting guide + 634239 Child GSources + 634241 Add pollable input/output streams + 634504 allow passing a NULL emblem to g_emblemed_icon_new() + 634613 unsufficient g_get_user_runtime_dir() documentation + 635640 schema should inherit gettext-domain from schemalist + 635768 Protect g_file_monitor_set_rate_limit() against negative... + 635882 Fix the wrong-category schema test + 635187 Wrong type of GVariant received in an action... + +* Updated translations: + Galician + Italian + Norwegian bokmÃ¥l + Uyghur + + +Overview of Changes from GLib 2.27.2 to 2.27.3 +============================================== + +* The GTimeSpec type that was introduced in the 2.27.2 has been + dropped again in favour of APIs that return microseconds as + 64-bit integer. + Affected functions: + g_source_get_time + g_periodic_unblock + g_get_monotonic_time + g_get_real_time + The similar GTimeVal struct is still around, but its use is + discouraged. + +* GTimer is now using monotonic time unconditionally + +* There are some new functions to facilitate error reporting + in async GIO APIs: + g_simple_async_result_take_error + g_simple_async_result_new_take_error + g_simple_async_report_take_gerror_in_idle + +* There is new convenience API to us GVariant dictionaries: + g_variant_lookup + +* It is now possible to delay sending match rules to the + D-Bus daemon in GDBus: + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE + +* Support has been added for XDG_RUNTIME_DIR: + g_get_user_runtime_dir + +* Various fixes for Win64/MSVC builds have been committed + +* Bugs fixed: + 620263 Add g_clear_object, g_clear_pointer, g_clear_boxed + 633075 update Project Files and sources for MSVC 2008/C89 + 633381 gsettings Makefile rules should handle empty list... + 633685 Use g_simple_async_result_{new_,}take_error + 633686 Add g_simple_async_report_take_gerror_in_idle + +* Translation updates: + Belarusian + Galician + Hebrew + Punjabi + Spanish + + +Overview of Changes from GLib 2.27.1 to 2.27.2 +============================================== + +* GApplication + - Export actions over DBus and support activating them from remote instances + - Support environment passing + +* GSettings + - The gsettings utility has a list-recursively command + - The gsettings utility has commandline completion for enum values + +* GLib is now linked against librt and uses monotonic time for + timeouts and GPeriod sources. GSource has a new g_source_get_time() + which returns monotonic time, and g_source_get_current_time() has + been deprecated + +* Bugs fixed: + 158725 free linked list with data + 626320 GVariant: Avoid locking in g_variant_get_child_value() if possible + 629247 add gsimpleasyncresult methods to take over a GError + 629274 GNetworkService does not do fallback when there is no SRV record + 631264 gsettings-tool choice/range support + 631482 g_date_time_from_instant: 1000000000000000000 + 632169 docs for manual use of gsettings-data-convert + 632571 Add equivalent to gconftool-2's -R option + 633115 GSettings m4 doesn't fail the build for broken schemas + 633206 Default g_application_local_command_line() doesn't set exit_status... + 633339 support more complex gapplication setups + 633356 Make timeout G_MAXINT mean "no timeout" + +* Translation updates: + Catalan (Valencian) + Indonesian + Japanese + + +Overview of Changes from GLib 2.27.0 to 2.27.1 +============================================== + +* GDateTime now has full week number support. + New API: g_date_time_get_week_numbering_year + +* The GSettings schema compiler will now skip over + broken .xml schema files instead of aborting altogether + +* GSettings now works properly on bigendian systems + +* GSettings has more complete support for ranges + New API: + g_settings_get_range + g_settings_range_check + The gsettings commandline tool supports ranges too. + +* GApplication has been rewritten; see the API docs for details + and examples. The action support is not complete yet. + +* The GLib mainloop has gained 'dispatch to context' functionality, + which can replace manually created idles in many cases. + New API: + g_main_context_invoke + g_main_context_invoke_full + +* The gio-desktop-app-info-lookup extension point has been + removed from GIO. GIO now uses x-scheme-handler mimetypes when + looking for default applications. + +* On win32, make g_get_user_data_dir() return the CSIDL_LOCAL_APPDATA + folder on Windows, and not CSIDL_PERSONAL. This matches what Qt does, + and has been widely requested. Also make g_get_user_config_dir() return + this and not the (roaming) CSIDL_APPDATA folder. + +* A periodic event clock has been added in GIO: GPeriodic. Note that this + API is still experimental and expected to undergo changes before it + will be incorporated into a stable GLib release. Use at your own risk. + +Bug fixes: + 613822 gobject signal connect/disconnect not thread safe + 618737 "dispatch to context" functionality + 620710 g_get_user_data_dir() uses CSIDL_PERSONAL and not CSIDL_APPDATA + 623400 acquire context before dispatching + 627126 gsettings schema files don't get installed on FreeBSD + 627171 g_socket_new_from_fd() doesn't set the right protocol + 628876 Wrong error description + 628937 gracefully handle broken schemas + 629274 GNetworkService doesn't fallback when there is no SRV record + 629289 g_error() used wrong, produces core dump + 629687 leaks class refcount in gsocketcontrolmessage + 629849 GLib-CRITICAL **: g_source_get_context: assertion `!SOURCE_... + 629945 GDBus deadlock in g_bus_get_sync() + 630000 g_date_time_difference + 630077 GDateTime week number support + 630185 Allow NULL strings in g_quark_try_string() + 630797 docs mention non-existent g_object_dispose() + 630968 gschema-compile problems on power g5 + 631263 GSettings needs range/choice APIs + 631264 gsettings-tool choice/range support + 631379 GDBus nonce-tcp test failing + 631410 Port gapplookupgconf.c to using x-scheme-handler/ + 632884 Possible deadlock in g_object_remove_toggle_ref() + +Transation updates: + Basque + Brazilian Portuguese + British English + Bulgarian + Czech + Dutch + Estonian + French + Galician + German + Greek + Hebrew + Hungarian + Japanese + Lithuanian + Polish + Portuguese + Romanian + Simplified Chinese + Slovenian + Spanish + + +Overview of Changes from GLib 2.25.15 to GLib 2.27.0 +==================================================== + +Build: + - massive restructuring to reduce #include abuse + - tweaks to silence some harmless compiler warnings + - rename gschema-compile.c to glib-compile-schemas.c + - Windows fixes + - fix building with zlib < 1.2.4 on win32 + +GDateTime: + - better msgctxt for translating month and weekday names + - API is changed quite a lot, implementation is improved + - GTimeZone is now exposed + +GObject: + - make ordering for overridden interface properties consistent + - ->priv structures are limited to 64k but this was not documented, + and exceeding this limit produced bad results. Add docs and enforce + the limit properly. + - add g_object_class_install_properties() to install multiple + properties in one go + - improve debugging output for GValue containing G_TYPE_STRV + +GIO: + - fix priority sorting of GIO extensions + - add GCredentials support on FreeBSD + - fix support for IPv6 addresses in URI parsing functions + - GSocketClient fixes for when g_socket_connect succeeds immediately + - clarify string encoding for GFile constructors in docs + - new functions g_data_input_stream_read_upto{,async,finish} + - tweak confusing documentation for g_output_stream_write() + +GDBus: + - GDBusMessage can now be locked and copied (like in libdbus) + - GDBusConnection filter function API has changed again + - GDBusServer: ::new-connection now declares if the connection was claimed + - add a partial workaround for GObject bug 627724. + - very many memory leaks fixed + +GVariant: + - check for size == 0 in g_variant_get_bytestring to avoid a crash + when attempting to get_bytestring() from an empty array + - improve gobject-introspection annotations + +GSettings: + - add GSettings Windows registry backend + - some internal tweaks to the backend API + - remove g_settings_list_items + - add g_settings_list_children and _list_keys to replace it + - add schema compiler restrictions for dealing with lists + - don't automatically emit value changed signals on writability + changes + +Other: + - constify the 'parser' vtable param to g_markup_parse_context_push() + - plug many memory leaks in test cases + +Bugs closed: + 50076 Time API to go with date API + 584284 g_data_input_stream_read_until_async different from sync version + 624546 Modification of GDBusMessage in filter function + 626919 Let g_object_class_install_property() return the installed GParamSpec* + 628029 GDateTime missing get_week_of_year method + 628253 Interface properties not listed in a consistent order + 628331 Plug lots of mem leaks in gio test suite + 628345 Plug a mem leak + 628436 Plug a mem leak + 628505 Fix building with zlib < 1.2.4 on win32 + 628839 [PATCH] datetime: Rename shadowing variables + 628904 [PATCH] Add credential support for FreeBSD and fix a socket issue + 628952 incorrect glib_major_version and other variables on cygwin. + 629192 g_strdup_value_contents(): dump GStrv more usefully + 629251 g_socket_client_async_connect_complete: assertion failed + 629259 Failed to connect to "::1" + 629328 g_markup_parse_context_push doesn't respect const structs + 629429 month "May" short and full form same with "GDateTime" msgctxt + 629689 GDBusConnection leaks its GCredentials + 629698 Segfault in g_variant_get_bytestring() + +Updated translations: + Arabic + Armenian + Basque + British English + Czech + Finnish + Galician + German + Hungarian + Indonesian + Japanese + Lithuanian + Norwegian bokmÃ¥l + Polish + Portuguese + Punjabi + Simplified Chinese + Slovenian + Spanish + Swedish + Swedish + Traditional Chinese + +Overview of Changes from GLib 2.25.14 to GLib 2.25.15 +===================================================== + + * GIO + - Memory leak fixes + - The GZip(De}Compressor can now process header information + - Support for network proxies has been added, with the GProxy + interface and the gio-proxy-resolver extension point. GIO + includes SOCKSv4 and SOCKSv5 implementations, and libproxy + is also going to provide an implementation of this extension + point. + - There are GAction and GActionGroup interfaces now, which will + be used in GApplication in the near future. + + * GObject + - There are now convenience macros for defining boxed and + pointer types + + * GDBus + - Memory leak fixes + - GDBusProxy for well-known names can now auto-restart + the service if the name owner disapperas + - Filter functions are now allowed to modify messages + + * GLib + - GDateTime is a replacement for GDate that supports time + and timezone information. + + * Bugs fixed: + 50076 Time API to go with date API + 449565 Add G_DEFINE_BOXED_TYPE() + 617691 Add GZIP header processing to GZlibCompressor/GZlibDecompressor + 622184 add g_memory_output_stream_steal_data + 624546 Modification of GDBusMessage in filter function + 627088 Build failure in gdbus-peer.c on FreeBSD + 627181 save a memdup + 627182 Plug a mem leak in the gdbus-connection test + 627187 Plug some gdbus mem leaks + 627188 gdbus-non-socket test occasionally fails + 627252 G_OPTION_FLAG_NO_ARG is only for callback options + 627392 gdbus commit 8a3a4596 breaks win32 compile + 627407 FTBFS on !linux UNIX platforms + 627604 String error: 'that' twice in a row + 627969 ABR in g_file_open_tmp + 628084 gdbus-peer fails with assertion + 628193 Miscellaneous string fixes + 628296 abort() in gsocketconnection.c + 628309 Plug a mem leak in GConverterOutputStream + 628317 GEmblemedIcon:equal implementation is buggy + 628323 Fix invalid reads + 628327 Plug a mem leak + 628328 Plug a mem leak + 628329 Don't leak the FD list + 628324 Invalid reads in gdbus-export test + + * Updated translations: + British English + Danish + Galician + Hebrew + Punjabi + Serbian + Spanish + Traditional Chinese + + +Overview of Changes from GLib 2.25.13 to GLib 2.25.14 +===================================================== + +* GDBus + - Make the closure variants of GDBus apis work + - Make error unregistration work + - Use async IO in the IO thread (626748) + +* GIO + - Make g_simple_async_result_is_valid work without source (626208) + - GSocketClient: add a timeout property + - Fix memory leaks in GSocketClient + - Handle async vs. sync correctly in GSocketConnection stream (616458) + - Declare stream base classes as abstract + - Clarify semantics of g_output_stream_write() (627071) + +* Other + - Improve test coverage for GDBus, GRegex, GAsyncResult + - Drop dead code in pcre, xdgmime + - Fix a race condition in gtester (578295) + - Avoid an extra allocation in GAsyncQueue (626704) + - Add test case for non-socket GIOStream (626841) + - More explicit GVariant docs (622770) + - Imroved docs for GAsyncInitable and GSimpleAsyncResult (602417) + +* Translation updates: + - Galician + - Norwegian bokmÃ¥l + - Punjabi + - Simplified Chinese + - Swedish + + +Overview of Changes from GLib 2.25.12 to GLib 2.25.13 +===================================================== + ++-------------------------------------------------------------------+ +| WARNING: There have been no breaks in API or ABI. Weird, eh? | ++-------------------------------------------------------------------+ + +The primary purpose of this release is to fix a serious problem with +glib 2.25.12: glibconfig.h (as generated on a Fedora amd64 system) was +being distributed in the tarball. It was being used to build some parts +of glib on other systems (eg: 32bit ones). This was causing some very +serious problems. + +There have been many other improvements, however: + + Build and testing: + - vastly improved test coverage + - old tests moved to the gtester framework + - gtester Makefile modified so that the tests only run once + - cleanup of how we handle includes while building glib + + GVariant: + - add a g_return_if_fail (utf8) to g_variant_new_string() + + GDBus: + - perform extra sanity checks when serialising messages + - add API to query and set the byteorder of a GDBusMessage + - improve debug output, add some extra options + - if exiting due to the bus disconnecting us, print an error message + explaining why + - sort property names correctly + - don't bother sending RemoveMatch when we will close the connection + anyway + - use effective uid/gid for credential passing + + GSettings: + - add G_SETTINGS_BIND_INVERT_BOOLEAN for inverting boolean bindings + without mapping functions + - mark all strings in the schema compiler for translation + + Binding: + - improve closure support for bindings + - copy GSettings INVERT_BOOLEAN flag + + Other: + - fix another complicated GCancellable deadlock possibility + +Bugs closed: + 599590 glib build doesn't look for correct pkg-config + 619026 avoid warning in gutils.h when using gcc with -Wconversion + 624739 Please fix POTFILES.in + 625472 Valgrind claims uninitialized bytes used + 625500 g_date_set_time_val documentation doesn't mention local time + 625628 GDBusProxy: wrong property name sorting + 625753 Incorrect flags used in g_dbus_connection_call_sync() + 625827 Expand documentation about error quark naming + 625988 builddir != srcdir issues + 626107 glibconfig.h is being disted + +Updated translations: + French + Galician + Hebrew + Norwegian bokmÃ¥l + Spanish + + +Overview of Changes from GLib 2.25.11 to GLib 2.25.12 +===================================================== + ++-------------------------------------------------------------------+ +| WARNING: There have been many API changes in GDBus -- sending | +| messages, subscribing to signals, closing connections and | +| registering subtrees are affected. The ABI for GSettingsBackend | +| has also been changed. For both reasons, a new dconf release is | +| required (and will be along soon). | ++-------------------------------------------------------------------+ + +Build: + - cleanup automake setup + - rename configure.in to configure.ac + - various docs fixups + - move glibconfig.h to glib/ + - disable dtrace support on Mac OS (which has incompatible 'dtrace') + +GSettings: + - add support for vendor override files (to change the default values + in a schema) + - change GSettingsBackend vtable + - add g_settings_reset() + - support binding to G_TYPE_STRV properties + +GDBus: + - many bug fixes, including a serialisation fix + - stop handling incoming connections as soon as stop() is called + - proper support for file descriptor passing + - new flags parameter for sending messages + - new flags parameter for subscribing to signals + - always reset the message serial when sending a message unless + G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL is given + - constness fixes for introspection structures + - clean ups to subtree registration API + +Other: + - fix divide by zero bug in g_malloc_n functions + - GIO: don't blindly assume that SOCK_CLOEXEC is supported + - make GObject property notify freezes threadsafe + - GIO: clean up credentials passing + - GApplication: make default-quit not apply if register=FALSE + - GIO: add annotations for gobject-introspection + +Bugs closed: + 166020 use GAtomic for refcounting + 617483 Credentials passing + 622005 [GApplication] no way to modify the "default-quit" property + 623293 vendor override files + 623810 Message serialization bug + 623815 Don't check sender for GDBusProxy objects where name is not set + 624473 GDBusSubtreeIntrospectFunc return type + 624483 GDBusSubtreeEnumerateFunc clarification + 624484 GDBusSubtreeDispatchFunc clarification + 624754 gdbusaddress.c missing sys/wait.h + 624968 div by zero in g_malloc_n family + 624991 GSettings mapping for G_TYPE_STRV + 625383 Add missing GI annotations + +Updated Translations: + Armenian + Galician + German + Hebrew + Kazakh + Romanian + Simplified Chinese + Spanish + +Overview of Changes from GLib 2.25.10 to GLib 2.25.11 +===================================================== + ++-------------------------------------------------------------------+ +| WARNING: There have been minor API changes in GDBus and GVariant. | +| These API changes will not affect many users, but they do require | +| a new version of GTK+ to be installed. | ++-------------------------------------------------------------------+ + +Build: + - add a --disable-Bsymbolic configure flag to disable linking with + -Bsymbolic-functions + - this release sees the complete removal of the old 'g*alias' hacks + - honour the NOCONFIGURE environment variable from autogen.sh + - use proper feature test macros for isnan + - use pkg-config to check for zlib + - add ACLOCAL_AMFLAGS to Makefile.am + +GDBus: + - hide Class and instance structures for all GDBus types except + GDBusProxy. This breaks API by preventing subclassing, but probably + nobody was doing that. + - add new GDBusConnection call to support flushing all pending + outgoing messages + - change the register_object API to add a reference to the + GDBusInterfaceInfo object so the caller need not keep it alive + themselves + - don't rewrite the serial number when sending messages that already + have a serial number + - better error checking for DBUS_SESSION_BUS_ADDRESS environment + variable + - switch to g_parse_debug_string for G_DBUS_DEBUG and add a lot of new + flags + - add support for temporarily freezing a freshly created + GDBusConnection. Do this until after the ::new-connection signal + has finished running on GDBus services. + - never require non-closed connections (the user is incapable of doing + this due to the obvious race) + - remove weird/misleading redundant check on NameOwnerChanged signal + - emit GDBusProxy::g-properties-changed on NameOwnerChanged + +GVariant: + - the 'g_variant_{new,get}_byte_array' APIs have been removed + - g_variant_{new,get,dup}_bytestring has been added, with different + arguments and different behaviour + - g_variant_{new,get,dup}_bytestring_array has been added, doing + essentially the same thing as the 'strv' functions, but with byte + strings instead of utf8 strings + - G_VARIANT_TYPE_BYTESTRING ('ay'), BYTESTRING_ARRAY ('aay') and + STRING_ARRAY ('as') constants have been added + - the undocumented behaviour that g_variant_get_strv() deserialised + arrays of object paths or signature strings has been dropped + - additional varargs support for converting bytestrings or bytestring + arrays with ^ay ^aay ^&ay and ^a&ay + - improved gobject-introspection annotation + - fix a problem with GBuffer calling g_slice_free for the wrong type + - fix leaks in the type inferencing code of the parser + +GSettings: + - improved documentation + - updated schema XML DTD, now xincluded into the docs + - added support for schemas that extend other schemas (using the + 'extends=' attribute). Values of keys in the base schema can be + overridden using . + - added theoretical support for lists (using the 'list-of=' attribute) + - lots of new tests + - add support for flags (implemented similarly to enums) + - add support for generating .enums.xml files to gsettings.m4: + gsettings_ENUM_NAMESPACE = org.example.myapp + gsettings_ENUM_FILES = ../path/to/*.h + will generate org.example.myapp.enums.xml with mappings for all + enums and flags in the specified .h files. + - warn with g_message() if the 'memory' backend is used by default + (ie: because no other GSettings backends are installed) + - fix get_property() for GSettings::schema + - command line tool: fix a bug that prevented non-basic values from + being set due to a premature free + - command line tool: bash completion support + - chain up in _finalize + - add a new g_settings_get_mapped API to read settings that require + post-processing + - retry with the translated or schema default value if the + GSettingsBindGetMapping function fails + - schema compiler: never fail due to empty schema directories (but + warn) + - peek rather than ref/unref the GEnumClass in the mapping function + - schema compiler: compile *.enums.xml before *.gschemas.xml to ensure + that we have all the enums that the schemas may reference + - schema compiler: improve accuracy of line numbers in error reports + - fix crashes in the keyfile backend caused by invalid group names in + the keyfile + +Other: + - always intern GBinding prop names + - base64: remove asserts preventing conversion of empty strings + - document NULL special-cases for GValueArray + - GNode docs improvements + - improve detection of 'system internal' mounts + - fix leaks in the inotify GFileMonitor implementation + - annotate all custom GIO GSources to improve debugging (e.g. using + SystemTap) + +Tests: + - Turn on glibc malloc checking features for make check + - improvements for GSettings tests, plus new tests + - improved tests for GKeyfile + - new tests for GDir, GSList, GSList, GAppLaunchContext, + CharsetConverter, GIcon, ... + - move some tests to GTester (tree tests, uri tests) + - generally, really an awful lot of new tests + - don't try to allocate 2gigs of memory anymore for the array test + + 552363 g_value_array_{insert,prepend,append}'s special cases for NULL + 561248 Improve return value description from g_node_prev/next_sibling() + 570036 Add ACLOCAL_AMFLAGS to Makefile.am + 576833 g_sprintf add a reference to g_strdup_printf + 576854 g_strconcat() documentation should provide a hint about bad l10n + 582227 reference: add other URI functions to 'URI Functions' section + 599223 should provide g_spawn_* variants that take a GAppLaunchContext + 610784 array test failing + 613057 Leak in inotify GFileMonitor implementation + 620536 Annotate all custom GIO GSource using g_source_set_name + 620913 More control with G_DBUS_DEBUG + 622124 implement flags + 622127 GSettings extended key validation + 622128 retry with default value for failed mapping + 622294 More annotations for GVariant + 622565 glib-compile-schemas fails when no schemas + 622600 Fix missing prototype warning + 622813 gsettings mapping & enum buglet + 623142 Ensure ::new-connection runs before processing D-Bus messages + 623143 Never require non-closed connections + 623319 use g_parse_debug_string for dbus debug flags + 623401 process enums first + 623402 schema compiler reports wrong line numbers + 623407 g_keyfile_settings_backend_new crashes with the key "/" + 623473 zlib should be checked with pkg-config + 623537 GDBusProxy has weird checking on NameOwnerChanged + 623538 GDBusProxy::g-properties-changed emission for corner cases + 623692 directory with file at multiple MLS levels may display empty + 623720 gschema.dtd does not contain enum definitions + 623770 quoting of expand_macro in gdesktopappinfo.c + 623772 gdesktopappinfo.c, function child_setup + 623780 g_unix_is_mount_path_system_internal + 623954 g_settings_finalize + 623955 Dubious return values + +Updated translations: + Galician + Hebrew + Norwegian bokmÃ¥l + Spanish + +Overview of Changes from GLib 2.25.9 to GLib 2.25.10 +==================================================== + ++----------------------------------------------------------------+ +| WARNING: There have been API changes in GDBus. Users of these | +| APIs will need to be adapted. In particular, a new release of | +| dconf is required to go along with this one. There has also | +| been a change in the GSettings backend API used for keyfiles. | ++----------------------------------------------------------------+ + +* GDBus: + - add direction parameter to filter functions (API change) + - allow calling other interfaces with a GDBusProxy + - padding added to class struct fields (ABI change) + - fixes for closures-based functions + +* GVariant: + - new is_floating() call + - add g_value_take_variant() call (required for marshallers) + +* GSettings: + - support for binding GParamSpecEnum properties + - ifelse-style condition support for GLIB_GSETTINGS m4 macro + - remove gsettings-schema-convert tool (now in GConf) + - allow introspection of all installed schemas + - allow introspection of the keys in a schema + - rewrite keyfile backend (API change) + +* GNIO: + - don't implicitly close GSocket until it is destroyed + - windows fixups + +* Other: + - allow GChecksum to take (NULL, 0) for data/length + - GRelation and GCompletion are now deprecated + - introduce G_PARAM_DEPRECATED and G_ENABLE_DIAGNOSTIC + - add working directory to GApplication platform data + - lots of documentation cleanups + - PCRE updated to 8.02 + +* Build: + - the IA__g_* style symbol aliasing has been disabled and replaced with + the -Bsymbolic-functions linker flag on platforms that support it. + Please be on the watch for portability issues and report them to us. + - many test cases have been moved to the GTester framework + - lcov support has been added for tests + - many windows fixes + +* Bugs fixed: + 501057 lcov coverage suite and GLib integration + 551271 deprecate GRelation + 601686 Implement diagnostic mode + 603309 GSocketOutputStream broken on Windows (?) + 616718 GLIB_GSETTINGS macro can't be used conditionally + 616855 GSocketConnection: don't close the socket if it's still reffed + 618866 g_ptr_array_remove_index_fast memory leak + 619878 keyfile backend calls keys_changed with invalid argument + 619879 keyfile backend doesn't make use of expected_type + 621092 Add with_closures() variants for bindings + 621172 Cross compiling fails + 621838 Actually add cwd to platform data + 621945 Filter outgoing messages in GDBusConnection + 621947 add g_value_take_variant + 622038 GSettings: "It is a programmer error" documentation is unclear + 622154 [patch] update documentation for g_application_new + 622281 binding: Add SYNC_CREATE to the flags + 622480 Improve documentation for g_strcmp0() + 622554 g_error called if schema not installed + 622601 Return interned strings from g_settings_list_keys + +* Translation updates: + - Galician + +Overview of Changes from GLib 2.25.8 to GLib 2.25.9 +=================================================== + ++----------------------------------------------------------------+ +| WARNING: There have been API changes in GDBus, GSettings and | +| GApplication. Users of these APIs will need to be adapted. In | +| particular, a new release of GTK+ is required to go along with | +| this one. | ++----------------------------------------------------------------+ + +* GDBus + - Use Gio's default async implementation + - Fix proxy construction for objects with no properties + - Fix error handling in synchronous initialization + - Do not dispatch calls to unregistered objects + - Add _with_closures alternative functions + - Allow constructing GDBusProxy with well-known names + - Remove GType parameters from GDBusProxy constructors + - Nuke g_bus_watch_proxy API + - Add --xml to gdbus-tool to print raw introspected XML + +* GSettings + - schema file format change: store (default, options) in gvdb + - Add g_settings_sync() + - Add support for enums and ranges + - 'context' support has been replaced by direct use of + GSettingsBackend + +* GApplication + - Switch to using variants for timestamps + - Use GInitable + +* GObject + - Introduce g_object_notify_by_pspec + - Add GBinding + - The GVariant gtype G_TYPE_VARIANT was changed from boxed + to fundamental. We believe there were no existing users + of the boxed type, so this should not cause any applications + to break. + +* Test framework + - Add package and version to the test report XML + - Use optparse to parse gtester-report commandline + - Add subunit support to gtester-report + - Prevent division by zero if no tests + +* Bugs fixed: + 621782 Crash using gbinding + 619945 GConverterOutputStream triggers assertion and corrupts data + 621319 more leaked GVariants in GSettings + 621168 GKeyFile memory leak on Windows platform + 621002 Switch to using variants for timestamps, split out signals + 620953 tiny docs addition + 618904 Lies in gunixmounts documentation + 621702 Correctly initialize GError + 611778 minor cleanup of gtester-report + 621213 GDBusProxy and well-known names + 621034 Rewrite apps test to ensure children are killed + 620954 gapplication gvariant simplifications + 611869 add subunit out feature to gtester-report + 621119 GDBusProxy and objects with no properties + 620990 Use Gio's default async implementation again + 620952 g_application_register_with_data is an ugly API + 621252 GSettings leaks context + 618715 fork() in GSettings test cases is problematic 618715 + 621905 Assume a ref when doing async work + 621266 GSettings "context" clarification + +* Translation updates: + Chinese + + +Overview of Changes from GLib 2.25.7 to GLib 2.25.8 +=================================================== + +* Initial support for dtrace and systemtap profiling: + - mainloop sources can be named + - probes for memory allocation with g_malloc and gslice + - gquark name tracking + - type creation + - object life-cyle (creation, finalization, ref, unref) + - signal creation and emission + +* GVariant + - has been fixed to work with the FreeBSD malloc + - added introspection annotations + - new function: g_variant_builder_add_parsed + +* GSettings: + - g_settings_set/get_strv functions have lost their length parameter + - g_settings_set_strv accepts NULL + - added introspection annotiations + +* GPermission: an abstract interface for representing permissions, + with a minimal implementation named GSimplePermission + +* GApplication: a basic application support class, with a D-Bus based + implementation + +* Bugs fixed: + 619585 glib-compile-schemas asserts on FreeBSD + 620384 Annotate GVariant and GSettings _strv() functions + 606044 Add support for dtrace/systemtap static markers + 620350 add g_variant_builder_add_parsed() API + 620349 utf8ify GVariant printer + 620767 Typo in GSettings documentation: "INTLTOOL_NOMERGE_RULE" + 620312 Fix g_settings_[gs]et_strv() API + 620519 GPermission + 620582 GPermission needs a simple implementation + 620496 GSettings schema compiler should reject invalid paths + 620173 missing single header inclusion guards + 620265 g_assertion_message_error should take const GError * + +* Translation updates: + Esperanto + Galician + Hebrew + Indonesian + Norwegian bokmÃ¥l + Slovenian + Spanish + + +Overview of Changes from GLib 2.25.6 to GLib 2.25.7 +=================================================== + +* NOTE: API/ABI breaks since 2.25.6 release: + - g_dbus_connection_sync{,_sync} takes a new 'reply_type' argument + - GSettingsBackendClass 'list' virtual function changed + + GSettings backends and things using GDBus may need to be rebuilt. + +* GDBus: many build-related fixes + +* GDBus (service): return a DBus error when receiving a method call for + an unknown interface. + +* GSettings: fix 'make install' bug in gsettings.m4 for generated schema + files + +* GSettings: avoid non-portable use of LC_MESSAGES + +* better approach to handling man pages + + +* Bugs fixed: + 619527 please improve docs on g_file_make_symlink + 619391 send-with-reply should have expected result signature + 618616 Use stack-allocated GVariantBuilders + 617004 Build with "--disable-nls" fails under MinGW/Win32 + 619142 Build fixes (GDBus) + +* Updated translations: + Estonian + Galician + Norwegian bokmÃ¥l + +Overview of Changes from GLib 2.25.5 to GLib 2.25.6 +=================================================== + +* GDBus: introspection improvements +* GDBus: build fixes + +* GSettings: GSettingsBackend ABI changed **** NOTE **** +* GSettings: --uninstall option for schema compiler +* GSettings: new m4 macro with more power +* GSettings: thread support + +* rework of file notification on Solaris +* fixes for gold linker + +* Bugs fixed: + 619038 increase gsettings.m4 power + 619031 method-calls-in-thread test failing + 618839 Typo at translation message + 616864 GSETTINGS_CHECK_RULE doesn't work with multiple files + 618730 gunixcredentialsmessage.c doesn't compile on GNU/kfreebsd + 616314 Make GSettings (partially) threadsafe + +* Updated Translations: + Indonesian + Galician + Spanish + +Overview of Changes from GLib 2.25.4 to GLib 2.25.5 +=================================================== + +* GDBus: Fix serialization of empty arrays + +* GDBus: Plug various memory leaks + +* GSettings: Fix problems with GSETTINGS_CHECK_RULE + +* Bugs fixed: + 616731 GSETTINGS_CHECK_RULE doesn't work in non-srcdir builds + 616864 GSETTINGS_CHECK_RULE doesn't work with multiple files + 618615 mem leaks in parse_value_from_blob + 618622 Plug some mem leaks in gdbus + 618650 Plug a mem leak in gdbusauth + 618663 Plug mem leaks in gdbus tests & examples + +* Updated translations: + Spanish + + +Overview of Changes from GLib 2.25.3 to GLib 2.25.4 +=================================================== + +* GDBus D-Bus support has been merged. This provides an API + to replace dbus-glib + +* GVariant no requires strings to be UTF-8. You can use byte + arrays for non-UTF-8 strings. + +* GSettings allows to bind string properties to byte arrays + +* The schema compiler supports range restrictions + +* Bugs fixed: + 618051 socket-server|client.c fail to compile under AIX... + 616102 GSettings ignores and + 616720 Chunked quark allocation + 616877 Several issues with g_socket_receive_message + 616892 gio: Add a boxed type for GFileAttributeMatcher + 616967 Add g_regex_get_compile_flags() and g_regex_get_match_flags() + 617767 g_settings_[gs]et_strv() 'length' argument has missing docs... + 617914 gtester-report: cope with binaries with no test cases + 617937 output_stream_close vs output_stream_close_async semantics + 615494 Connction timeouts produce partially invalid error messages + 617823 glib-compile-schemas problems with an out of source build + 617947 glib-mkenums: add @valuenum@ support + +* Translation updates: + Galicaian + Norwegian bokmÃ¥l + Shavian + Spanish + + +Overview of Changes from GLib 2.25.2 to GLib 2.25.3 +=================================================== + +* New macro: G_GNUC_DEPRECATED_FOR, a variant of G_GNUC_DEPRECATED + that lets you add replacement information (requires gcc 4.5) + +* Rename AM_GSETTINGS autoconf macro to GLIB_GSETTINGS + +* Rename gschema-compile utility to glib-compile-schemas + +* Add support for timeouts in GSocket + +* Bugs fixed: + 589989 Compilation error on Solaris 9 + 616648 Change AM_GSETTINGS macro to GLIB_GSETTINGS + 587898 I/O timeouts for GSocket + 614541 Add G_TYPE_ERROR boxed type for GError + + +Overview of Changes from GLib 2.25.0 to GLib 2.25.2 +=================================================== + +* Include a 'gsettings' utility, for commandline access to GSettings + +* Install a AM_GSETTINGS autoconf macro similar to AM_GCONF + +* GSettings can bind the writability of a key explicitly + +* There is now a predefined boxed type for GError + +* Bugs fixed: + 615379 g_new macros crash if sizeof(struct_type) == 0 + 616312 Add m4 rule equivalent to GCONF_SCHEMAS_INSTALL + 616295 mapping bug for uint64 + 616216 glib compile from remote directory fails + 615960 Fix size passed to connect() for abstract sockets + 616432 Crash in gschema-compile + 616331 gsettings-schema-convert uses imaginary types + 616309 gsettings-schema-convert should output gettext-domain + 616384 Add mention of GConfBridge in conversion docs + 616311 gschema-compile outputs in current directory + 616276 simplify gschema-compile test setup + 616156 keys with unnecessary empty options arrays + 616405 gsettings missing g_return_if_fail's + 616245 Use G_DEFINE_INTERFACE macro + 614541 Add G_TYPE_ERROR boxed type for GError + +* Updated translations: + Catalan (Valencian) + Galician + Kannada + Spanish + + +Overview of Changes from GLib 2.24.0 to GLib 2.25.0 +=================================================== + +* The GSettings framework has been merged. This provides the API to + replace GConf. DConf will provide a backend implementation for it. + GConf will also provide a backend implementation to ease the + transition. We provide utilities to assist with schema conversion + and data migration, as well as a porting guide. + +* Translation updates: + Bengali + Catalan + Danish + Gujarati + Marathi + Thai + Traditional Chinese + + +Overview of Changes from GLib 2.23.6 to GLib 2.24.0 +=================================================== + +* It is now allowed to call g_thread_init(NULL) multiple times, and + to call glib functions before g_thread_init(NULL) is called + (although the later is mainly a change in docs as this worked before + too). See the GThread reference documentation for the details. + +* GObject now links to GThread and threads are enabled automatically + when g_type_init() is called. + +* GObject no longer allows to call g_object_set() on construct-only properties + while an object is being initialized. If this behavior is needed, setting a + custom constructor that just chains up will re-enable this functionality. + +* GMappedFile on an empty file now returns NULL for the contents instead of + returning an empty string. The documentation specifically states that code + may not rely on nul-termination here so any breakage caused by this change + is a bug in application code. + +* Bug fixes: + 613601 buglet in dup_close_on_exec_fd + 584284 g_data_input_stream_read_until_async behaves confusingly + 613748 Write errors in middle of copy cause hang + 613923 splice_stream_with_progress: wrong error handling + 613667 Typo in GObject documentation + 613618 gvariant format string docs unclear + +* Translation updates: + Basque + Ukrainian + Vietnamese + + +Overview of Changes from GLib 2.23.5 to GLib 2.23.6 +=================================================== + +* Class private data: + - support for private data associated with a GTypeClass + +* GVariant merge is now complete: + - loading functions and parser merged + +* Windows improvements: + - socket fixes + - various build improvements + - removal of GCC/C99isms in favour of portable code + - drop unmaintained Visual Studio 8 support + +* Minor API addition: + - g_desktop_app_info_get_filename() + +* Bugs fixed: + 521707 Class private data + 612502 build fails on glib/tests/gvariant.c + 612832 [GDesktopAppInfo] New function g_desktop_app_info_get_filename + 612702 [PATCH] Fix GSocket-related crash on Windows + 612736 Improve the documentation about single include + 610858 gvariant test fails sometimes + 612327 uninitialized variable + +* New translations: + Afrikaans + LowGerman + +* Updated translations: + Czech + Finnish + Galician + Greek + Punjabi + Romanian + Serbian + + +Overview of Changes from GLib 2.23.4 to GLib 2.23.5 +=================================================== + +* New API addition: g_malloc_n() and friends used to implement an + overflow-safe family of g_new() macros. + +* GVariant: + - GVariantBuilder and GVariantIter are now merged. + - The variable arguments API is now merged. + - The parser will be in a future release. + +* GIO: + - Remove GUtf8InputStream (which never appeared in a stable release) + for now since it doesn't satisfy the needs of its main intended use + case. We hope to reimplement this feature in a better form in a + future release. + +* Bugs fixed: + 609531 missing licence headers + 612107 Missing G_FILE_ATTRIBUTE_TRASH_ORIG_PATH + 611897 g_io_modules_scan_all_in_directory leaks + 608196 Overflow-safe g_new family + 611696 gio uses GetAddrInfo which requires special handing on windows 2k + 605667 Don't use G_PARAM_SPEC_VALUE_TYPE when we know the pspec is valid + 610860 test_g_file_open_readwrite fails if $HOME is unwritable + 552912 glib-2.18 /live-g-file/test_copy_move failed when run as root + 609813 Renaming a file discards file notes + +* Updated translations: + Basque + Brazilian Portuguese + British English + Bulgarian + Catalan + Danish + Estonian + French + German + Hungarian + Italian + Lithuanian + Norwegian bokmÃ¥l + Portuguese + Russian + Slovenian + Spanish + Swedish + Traditional Chinese + + +Overview of Changes from GLib 2.23.3 to GLib 2.23.4 +=================================================== + +* GVariant: The core of GVariant has been merged now, with some + API still to follow. + +* GIO: + - There is a new interface GFileDescriptorBased for file descriptor + based IO. GLocalFile{Input,Output}Stream implement it + - Use splice(2) to transfer data between file descriptors without + extraneous copies + - Add a way to request move events from file monitors + +* Bugs fixed: + 609143 *result_uncertain is never assigned in g_content_type_guess + 604086 Use splice(2) when doing local file copies + 547890 No move events for GFileMonitorEvent? + 568760 nautilus freezes due to a bug in garray.c:322 + 609962 Add info about the use of G_DEFINE_INTERFACE + 609564 g_base64_encode_close docs should mention outbuf size... + 610484 g_variant_equal bug + 610131 libasyncns does not compile on Solaris 8 + 609530 missing single header include guards + +* Updated translations: + Czech + Estonian + Galician + German + Korean + Polish + Slovenian + Spanish + Traditional Chinese + + +Overview of Changes from GLib 2.23.2 to GLib 2.23.3 +=================================================== + +* GLib now has a facility for locks that consume only one bit of + storage inside an integer: g_bit_lock() + +* GVariant: The serializer has been merged, with more API to follow + +* Bugs fixed + 548967 1 bit mutex lock + 604967 2.22.3 libasyncns build fails on HP-UX 11.11 + 608602 G_VALUE_COLLECT_INIT variables shadow those in G_VALUE_COLLECT + 608743 Crash in g_hostname_to_ascii visiting certain website in epiphany + 599197 array ref and unref functions crash on NULL array. + 608159 mem leak in g_io_modules_scan_all_in_directory + +* Translation updates + Brazilian Portuguese + Czech + French + Norwegian bokmÃ¥l + Slovenian + Spanish + Thai + + +Overview of Changes from GLib 2.23.1 to GLib 2.23.2 +=================================================== + +* We are now using gcc builtins for atomic operations when available + +* g_assert() grew the ability to store assertions in core dumps + +* GIO supports lazy loading of GIO modules, and there is a new + gio-querymodule utility that goes along with this. + Packagers will need to adapt to this. + +* Threading changes: + - The requirements for g_thread_init() have been relaxed slightly, + it can be called multiple times, and does not have to be the first + call. + - GObject now links to GThread and threads are enabled automatically + when g_type_init() is called. + - Thread-safety issues with boxed types in GObject have been fixed. + +* GObject: + - Another bunch of performance work has landed + +* GVariant: + - GVariantType has been merged, with the rest of the GVariant + API to follow. + +* Bugs fixed: + 568760 nautilus freezes due to a bug in garray.c:322 + 602417 Document lifecycles of GSimpleAsyncResult and friends + 604824 crash in Epiphany: Selecting my Slashdot bo... + 448888 don't init g_slice for always-malloc + 531902 Use GCC atomic buildins for g_atomic* + 554887 boxed type registration is not thread safe + 586150 unresolved symbols when building glib 2.21.2 on OS X Tiger + 589176 row gvalue transform array exponentially + 594872 Support storing assertion messages into core dump + 602240 Upgrade libasyncns to 0.8 + 603590 Speed up G_VALUE_COLLECT + 604457 gutf8inputstream.c: increasing unknown size pointer + 605686 GCharsetConverter doesn't flush + 605733 g_memory_output_stream_new violates GObject standards + 605883 g_object_new() processes varargs even when there are none + 605977 invalid utf-8 conversion in g_local_file_get_parse_name(... + 606775 Enable threads by default in gobject + +* Translation updates: + Asturian + Basque + Bengali + Bulgarian + Estonian + Norwegian bokmÃ¥l + Spanish + Thai + Ukrainian + + +Overview of Changes from GLib 2.23.0 to GLib 2.23.1 +=================================================== + +* GObject performance work has landed: + - Construction of simple objects is much faster + - Interface lookup is lock-free and constant-time now + - Reduced locking overhead when dealing with types + +* GType now has a G_DEFINE_INTERFACE convenience macro + +* GIO gained GUtf8InputStream, an input stream that + performs utf-8 validation + +* GLib now has byte-swap macros for gsize and gssize + +* Bugs fixed: +557151 Determining the newly_constructed boolean in gobject.c... +557100 Performance improvements for GObjectClasses that don't... +501166 Warning message says IA__g_type_init instead of g_type_init +585375 Performance and Contention problems with g_type_class_ref... +587892 Race in GType when instantiating the same class for the... +603270 Input Stream validating utf8 +603476 gioenums.h:62: error: comma at end of enumerator list +603540 g_time_val_from_iso8601 uses uninitialised variable +603982 Stack overflow when reading file async with filter +604645 G_DEFINE_INTERFACE_* documentation is not generated +604875 Use of sa_len conflicts with system header +320482 provide G_DEFINE_TYPE like macros for interfaces + +* Updated translations: + Estonian + Hebrew + Norwegian bokmÃ¥l + Vietnamese + Welsh + + +Overview of Changes from GLib 2.22.x to GLib 2.23.0 +=================================================== + +* GIO: + - GConverter: a generic interface for stateful conversions of data, + suitable for charset conversion, compression, decompression, regexp + replacement. Concrete implementations are GCharsetConverter, + GZlibCompressor and GZlibDecompressor. GConverterInputStream, + GConverterOutputStream are stream implementations that convert data + while loading or saving it. + - GMounts can now have a 'default location': a path that reflects + the main entry point for the user (e.g. the home directory). + - As a consequence of the compression support, GIO depends on zlib now. + +* GObject: + - G_IMPLEMENT_INTERFACE_DYNAMIC: a convenience macro for adding + interfaces to dynamic types. + +* GModule: + - The -pthread flag has been added to all gmodule .pc files, because + it is not generally permissible to load modules that are linked + against libpthread if the program has not been compiled with threading + support. + +* Bugs fixed: + 601637 GUnixFDMessage should contain a GUnixFDList + 585566 GSocketListener API issues + 572252 Bug in g_file_test() function. + 600550 g_app_info_create_from_commandline doesn't treat arguments properly + 541236 not detecting exact content type + 350200 [PATCH] GTypeModule derived class unref does not unload plugin + 589631 Please enclose literal values with double quotes + 577711 cross compile check for g++ broken + 600620 Support X-GNOME-FullName in GAppInfo + 598899 GWin32DirectoryMonitor is broken + 593809 Nautilus does not restore the position of the icons on the desktop... + 563627 g_get_prgname() threadsafety + 600141 Add -pthread to gmodule pkg-config + 593856 file and directory monitors don't work when glib is compiled... + 324930 Nautilus should disallow copying of symlink to FAT drive early + 587300 Deadlock when calling g_cancellable_disconnect in a... + 595138 GFile not robust with invalid input + 591216 Warning building resolver.o + 590016 Does not compile under MinGW32 + Wine + 591214 Warnings building gcancellable.o + 561998 Have specific entry points (paths) for mounts... + 508157 Add G_IMPLEMENT_INTERFACE_DYNAMIC + 535159 g_file_has_parent + +* Updated translations: + Brazilian Portuguese + Catalan + Estonian + Galician + Norwegian bokmÃ¥l + Shavian + Slovenian + Spanish + Swedish + + +Overview of Changes from GLib 2.22.1 to GLib 2.22.2 +=================================================== + +* GIO: + - Support case-sensitive globs in the shared mime database, + including support for the newer cache format that allows these. + Case-sensitive globs have been introduced in shared-mime-info + version 0.70 + +* GObject: + - Speed up creation of simple objects + +* Bugs fixed: + 597194 Typo in _G_TYPE_CVH macro + +* Updated translations: + Russian + + +Overview of Changes from GLib 2.22.0 to GLib 2.22.1 +=================================================== + +* Bugs fixed: + 596064 Test file marked for translation + 595972 possibly invalid search in mime_info_cache_dir_add_... + 596561 C99 style of declaration of variable in gmessages.c + 596314 g_utf16_to_utf8 returns an invalid UTF8 string + 596748 g_async_result_get_source_object returns a new ref + 593809 Nautilus does not restore the position of the icons... + 593775 uses inotify_init1 unconditionally + +* Updated translations: + Bengali + Hebrew + + +Overview of Changes from GLib 2.21.6 to GLib 2.22.0 +=================================================== + +* Repeated calls to g_simple_async_result_set_op_res_gpointer used + to leak the data. This has been fixed to always call the provided + destroy notify. + +* Add gdb python macros to make gobject debugging more pleasant + +* Bugs fixed: + 579050 Allow making selected critical and warning messages non-fatal + 594759 g_socket_send_message fails due to invalid sendmsg params + 593941 GNetworkAddress skipping addresses when enumerating + 594597 Fix build with srcdir != builddir + 595619 Include gdb pretty printers + +* Changes that might affect bindings: + - The error parameter of g_simple_async_result_set_from_error has been + made const. + +* Updated translations: + Assamese + Bengali India + British English + Bulgarian + Catalan + Czech + Danish + Finnish + Galician + Greek + Gujarati + Hindi + Japanese + Kannada + Malayalam + Marathi + Norwegian bokmÃ¥l + Oriya + Polish + Punjabi + Romanian + Serbian + Simplified Chinese + Slovenian + Spanish + Tamil + Telugu + Thai + Traditional Chinese + Ukrainian + Vietnamese + + +Overview of Changes from GLib 2.21.5 to GLib 2.21.6 +=================================================== + +* Minor API additions: + g_mkstemp_full is a variant of g_mkstemp that allows to specify flags + and permissions + +* Bugs fixed: + 593232 g_rand_new: read no more than requested from /dev/urandom + 591995 use saved errno + 589491 g_time_val_from_iso8601 doesn't handle some cases + 593406 Permissions set to 777 after copying via Nautilus + 594034 Add g_mkstemp_full() + +* Updated translations: + Assamese + Basque + Brazilian Portuguese + Czech + Estonian + French + German + Hungarian + Italian + Kannada + Malayalam + Marathi + Norwegian bokmÃ¥l + Oriya + Portuguese + Swedish + Tamil + Turkish + + +Overview of Changes from GLib 2.21.4 to GLib 2.21.5 +=================================================== + +* A performance problem with trashing of many files has been fixed + +* GResolver now invalidates the libc resolv.conf cache as needed + +* Minor api additions: + - g_cancellable_make_pollfd returns a boolean now. And there is a + new function g_cancellable_release_fd that can be used to released + the resources used by a GCancellable. + +* Bugs fixed: + 589988 Compilation error on Solaris 9 (missing stdint.h) + 588901 gtcpconnection.c won't compile + 584246 GResolver needs to call res_init() when network state changes + 591714 Figure out failure handling for g_cancellable_make_pollfd() + 591532 redundent '/' returned from g_file_resolve_relative_path + 591378 Use MSG_NOSIGNAL in GSocket if it's available + 589649 API documentation migration for Base64 Encoding + 591840 configure fails with autoconf 2.64 + +* Updated translations: + Basque + Brazilian Portuguese + Bulgarian + Danish + Estonian + Finnish + Galician + Gujarati + Hndi + Irish + Japanese + Korean + Norwegian bokmÃ¥l + Polish + Portuguese + Punjabi + Spanish + Swedish + Telugu + Traditional Chinese + Thai + + +Overview of Changes from GLib 2.21.3 to GLib 2.21.4 +=================================================== + +* GTree is now refcounted + +* Bugs fixed: + 587938 Undocumented limitation for g_str_equal + 587773 refcounts for GTree + +* Updated translations: + French + Hebrew + Norwegian bokmÃ¥l + Spanish + Swedish + Traditional Chinese + Ukrainian + + +Overview of Changes from GLib 2.21.2 to GLib 2.21.3 +=================================================== + +* GMappedFile is refcounted now + +* Mainloop: It is now possible to set per-thread default contexts, + with g_main_context_push_thread_default. + +* glib-mkenums supports a @basename@ substitution, in addition + to @filename@. + +* GIO: + - Vfs implementations can support storing of per-file metadata. + - GCancellable can now be subclassed. + - Unmount and eject methods now optionally allow interaction, via + variants that take a GMountOperation object. + +* Bugs fixed: + 556706 Inconsistent help arguments -h, -? + 579449 FileChoosers no longer work if an idle handler is active + 579933 mainloop FD_CLOEXEC has a race condition + 579984 alternate GMainContext support + 585937 gio/gsocket.c (glib 2.21.2) does not compile (Windows/mingw) + 586675 Runtime library location + 586797 Add GCancellables to GSocket ops + 586868 g_filename_complete_get_completions doesn't always return... + 587415 g_resolver_lookup_by_name_finish returns a freed list + 587434 regression tests fail, at least on x86_64 + 586928 Avoid g++ warning in g_error() + +* Updated translations: + Estonian + Hebrew + + +Overview of Changes from GLib 2.21.1 to GLib 2.21.2 +=================================================== + +* GIO: + - g_socket_speaks_ipv4 is a new function to check if a socket can + speak IPv4. + - g_socket_listener_add_address gained a new effective_address out + parameter. + - GIO now returns special icons for XDG user directories, by the + name folder-music, folder-documents, etc. + - GIO gained support for starting/stopping of drives, which can be used + in connection with external hard disk enclosures, disk arrays, iSCSI + devices, etc. See g_file_start/stop_mountable. + +* GLib: + - g_reload_user_special_dirs_cache is a new function to force GLib to + reload the XDG user directory mapping from disk. + +* Bug fixes: + 584574 glib compile failure on Mac OS X with gunixresolver.c and... + 585566 GSocketListener API issues + 584255 Incorrect freeing of thread pool in GThreadedSocketService + 585088 g_string_chunk_insert_len stops at nul bytes + 585360 Monitor fontconfig configuration files using gio causes m... + 580103 Terminal starts on Display :0.0 when started on :0.1 in D... + 580301 network: a few issues on old darwin + 583398 SRV weight sorting is incorrect + 584176 build fixes on FreeBSD + 585189 g_cancellable_reset() must be called in same thread as g_... + 585280 compilation dies on gio/gsocket.c, needs sys/uio.h to con... + 585281 gio/gunixfdmessage.c needs sys/types.h for platforms that... + 585478 don't leak the inotify fd + 585575 g_socket_listener_add_inet_port() doesn't do the right thing + 585599 g_socket_listener_add_socket() consumes the socket + 585676 GEmblem doesn't reference its 'icon' if that is set as a ... + 585717 "bytes" nautilus translation to french is not shown in th... + 541276 XDG directories should have their own icons + 585726 Grammatical error in GList documentation + 585520 Wrong warning option in documentation + 585673 GNOME Goal: Remove deprecated glib symbols + 585591 Starting/stopping drives + +* Updated translations: + Bengali India + Norwegian bokmÃ¥l + + +Overview of Changes from GLib 2.21.0 to GLib 2.21.1 +=================================================== + +* GIO: + - Support for network IO has been added, including a low-level + socket API and a high-level API for network connections and + services. + - Support for read-write access with GIOStream and its subclasses. + - GMount gained a pre-unmount signal. + +* Bug fixes: + 576104Implement GMount::pre-unmount + 578769 implement GWinHttpFileInputStream::close_fn + 582856 gsocket.c doesn't compile on Solaris + 569375 g[u]intptr undocumented + 573246 [FIX] g_desktop_app_info_dup() can access NULL pointer + 575013 g_cancellable_push_current() does not allow NULL + 577884 live-g-file.c:461: error: format ‘%d’ expects type ... + 578499 g_output_stream_splice and stream closing with gnio strea... + 579558 Application employing gvfs crashes with only libgvfscommo... + 583001 SIGPIPE (grr!) + 583061 Please add convenience function to connect to machines by... + 583198 typo in error message + 583206 use g_set_error_literal where appropriate + 583229 void function g_async_initable_init_async returns value + 583324 locking problem in g_main_context_iterate() + 583408 void function g_socket_control_message_serialize returns ... + 578786 wrong and confusing error message + 583205 g_inet_address_to_bytes has no length outparam + 583196 mem leak in keyfile test + 583663 GSocketType enum ends with a comma + 569024 Make g_error_new_valist public + 569376 missing G_G[U]INTPTR_FORMAT + 580347 off-by-1 bug in GWinHttpFile + +* Updated translations: + Oriya + Spanish + Valencian-Catalan + + +Overview of Changes from GLib 2.20.x to GLib 2.21.0 +=================================================== + +* GIO: + - New helper functions g_cancellable_connect/disconnect to avoid + race conditions when connecting to the "cancelled" signal on + GCancellable. + - New types and methods for dealing with IPv4 and IPv6 addresses (and + UNIX domain socket addresses under UNIX). This does not include code + for actual socket I/O. + - GResolver provides asynchronous and cancellable APIs for resolving + hostnames, reverse lookup of IP addresses and resolving SRV records. + +* Glib now provides hash and comparison functions for int64 and double + types, suitable for use with GHashTable. + +* GArray, GPtrArray and GByteArray can be ref counted now, and have + boxed types. + +* Bugs fixed: + 572844 Helper for GCancellable::cancelled connect/disconnect + 578363 goption docs should be improved + 548466 async/cancellable DNS resolver + 579830 param spec strings should use P_() + 579862 requesting xattr::foo ends up calling getxattr(..., user... + 580453 Hash and equal functions for gint64 and gdouble + 580450 Reference counting and boxed types for arrays + 580194 gresolver doesn't build on Solaris + 580301 network: a few issues on old darwin + 580299 network: include sys/types.h before sys/socket.h to insur... + 572508 gmarkup speedup + 580546 g_strtoull() referenced in documentation... + 580656 g_key_file_set_string_list erroneously asserts list != NULL + 579272 leaks in g_simple_async_result_set_op_res_gpointer + + +* Updated translations: + Catalan (ca) + Pashto (ps) + Spanish (es) + + +Overview of Changes from GLib 2.20.0 to GLib 2.20.1 +=================================================== + +* Bug fixes: + 575555 Use fsync() when replacing files to avoid data loss on + 575708 runaway inotify madness + 575270 GVolumeMonitor::mount-pre-unmount not being emitted + 577128 glib make check Failed to execute child process... + 573673 Always show "backup" directories + 578369 g_time_val_from_iso8601() parses timezones incorrectly + 578002 Fix a small typo in GFile docs + 578017 G_DEFINE_TYPE_EXTENDED docs + +* Updated translations: + Arabic + Assamese + Basque + Bularian + Brazilian Portuguese + British English + Catalan + Danish + French + Galician + German + Greek + Hungarian + Italian + Japanese + Kannada + Lithuanian + Malayalam + Norwegian bokmÃ¥l + Oriya + Polish + Punjabi + Russian + Simplified Chinese + Slovenian + Spanish + Swedish + Tamil + + +Overview of Changes from GLib 2.19.9 to GLib 2.20.0 +=================================================== + +* The functions for launching applications (e.g. g_app_info_launch() + + friends) now passes a FUSE file:// URI if possible (requires gvfs + with the FUSE daemon to be running and operational). With gvfs 2.26, + FUSE file:// URIs will be mapped back to gio URIs in the GFile + constructors. The intent of this change is to better integrate + POSIX-only applications, see bug #528670 for the rationale. The + only user-visible change is when an application needs to examine an + URI passed to it (e.g. as a positional parameter). Instead of + looking at the given URI, the application will now need to look at + the result of g_file_get_uri() after having constructed a GFile + object with the given URI. + +* Base64 support: Avoid integer overflows. CVE-2008-4316 + +* Bugs fixed: + 574019 GChecksum: document and guarantee hex characters in lower case + 573454 Unable copy/move files to directories symlinked to gvfs share + 561172 gnome-open fails on local URIs with anchors + 573970 crash in gunixvolumemonitor:update_mounts when unmounting + 573843 g_get_current_dir returns non-absolute path + +* Updated translations: + Assamese (as) + Bengali (bn_IN) + Czech (cs) + Hindi (hi) + Italian (it) + Japanese (ja) + Lithuanian (lt) + Malayalam (ml) + Marathi (mr) + Oriya (or) + Polish (pl) + Romanian (ro) + Telugu (te) + + +Overview of Changes from GLib 2.19.8 to GLib 2.19.9 +=================================================== + +* GMarkup: + - Considerable speedup + +* GIO + - Add G_FILE_CREATE_REPLACE_DESTINATION flag to allow replacing + the destination of a copying operation as if it did not exit before. + - Be more careful when classifying files as desktop files + - Support desktop file key X-GIO-NoFuse which disables the use + of fuse pathnames for %u and %U arguments + +* Bugs fixed: + 572672 glib/gthread.c: argument is different type + 572464 Doc for g_file_get_contents + 572151 “it's†and “its†confused in docs and comments + 570501 g_win32_get_system_data_dirs uses invalid conversion... + 167569 g_string_append_printf crashes on win32 when used... + 572508 gmarkup speedup + 560564 Replacing a symlink with its linked file truncates... + 549298 impossible to copy files with p (pipe) flag + 543183 Clarify docs for g_file_has_prefix + 540461 g_memory_output_stream_get_data_size() doesn't behave... + 573462 GEmblemedIcon leak + 573421 Clarify message format in GMountOperation + 573658 Deadlock in giomodule.c + 556706 Inconsistent help arguments -h, -? + 573527 Wrong shell to run config.status in Makefile.in.in + 573128 A couple of typos in GObject documentation + +* Updated translations: + Catalan (ca) + British English (en_GB) + Spanish (es) + Basque (eu) + Finnish (fi) + French (fr) + Gujarati (gu) + Hebrew (he) + Hungarian (hu) + Korean (ko) + Maithili (mai) + Norwegian bokmÃ¥l (nb) + Dutch (nl) + Portugese (pt) + Swedish (sv) + Thai (th) + Traditional Chinese (zh_HK) + Traditional Chinese (zh_TW) + + +Overview of Changes from GLib 2.19.7 to GLib 2.19.8 +=================================================== + +* GIO: Fix missing exports of new API + +* Fix strict aliasing warnings and violations to make Glib work + with gcc 4.4 + + +Overview of Changes from GLib 2.19.6 to GLib 2.19.7 +=================================================== + +* GIO + - GFile gained an attribute for the actual file size in bytes + - GMountOperation gained an "aborted' signal that allows to abort + a mount operation from the backend side + +* Bugs fixed: + 523742 Use noinst for non-installable libraries + 566747 URIs opened with firefox %u load as local files + 541225 Can't compile gio on AIX duplicate case value in gioerror.c + 571598 GAsyncResult with NULL gobject + 505042 add file attribute for actually used file size in bytes + +* Updates translations: + Basque (eu) + Gujarati (gu) + Italian (it) + Japanese (ja) + Norwegian bokmÃ¥l (nb) + Dutch (nl) + Portugese (pt) + Thai (th) + Vietnamese (vi) + + +Overview of Changes from GLib 2.19.5 to GLib 2.19.6 +=================================================== + +* New format macro to print goffset data: G_OFFSET_FORMAT + +* GIO: + - Add a GFilter{Input,Output}Stream::close-base-stream properties which + determine whether the base stream will be closed when the filter stream + is finalized. + - g_data_input_stream_read_line and ..._read_until have asynchronous + variants now. + +* Bugs fixed: + 568294 A wrong reference in the description of g_bookmark_file_... + 563141 RFE: define G_OFFSET_FORMAT + 569105 g_time_val_to_iso8601() assumes time_t==long + 568394 dropping the last reference to a stream filter closes... + 568741 g_buffered_input_stream_fill_async doesn't work + 568723 g_buffered_input_stream_fill_async doesn't take count == -1 + 568575 _async functions for GDataInputStream + +* Updated translations: + Bulgarian (bg) + Finnish (fi) + Hungarian (hu) + Oriya (or) + Swedish (sv) + Traditional Chinese (zh_HK) + Traditional Chinese (zy_TW) + + +Overview of Changes from GLib 2.19.4 to GLib 2.19.5 +=================================================== + +* Update included PCRE to 7.8 + +* g_base64_decode_inplace: New function to do base64 decoding in place + +* Bugs fixed: + 567138 get_package_directory_from_module() does not free ... + 566569 gregex docs clarification + 566573 g_match_info_fetch_pos docs + 564728 Add function to decode base64 encoded data in place + 567838 G_STRUCT_OFFSETOF fails to compile under icc 9.1 + 567977 textdomain() macro should not return NULL ... + 512779 --disable-regex breaks compilation + 566770 error code 0 for Too many open files is useless + 565484 g_content_type_guess passes non-UTF8 text to XDG ... + +* Updated translations: + Catalan (ca) + Spanish (es) + Italian (it) + Swedish (sv) + + +Overview of Changes from GLib 2.19.3 to GLib 2.19.4 +=================================================== + +* GIO: + - Use O_NOATIME when sniffing mimetypes + - Add a convenience method to check if a GSimpleAsyncResult + is valid + +* Bugs fixed: + 560676 function access for g_threads_supported + 565905 There is no g_context_group_set_translation_domain + 564210 SUN Studio 12 has supported visibility attribute + 565136 GObject's "notify" signal parameters are wrong in gtk-doc + 565831 error in interface creation sample + 566348 g_file_open_tmp uses the wrong g_mkstemp on win32 + 566064 Add NOATIME flag to query_info_flags + 566170 g_async_result_verify_source_object + +* Updated translations: + Spanish (es) + Norwegian bokmÃ¥l (nb) + Brazilian Portugese (pt_BR) + Simplified Chinese (zh_CN) + + +Overview of Changes from GLib 2.19.1 to GLib 2.19.3 +=================================================== + +* Bugs fixed: + 508021 Add support for the CRIS and CRISv32 architectures + 526320 should not list mounts that the user doesn't have permission to use + 558458 Cannot build gio tests on Solaris using SUN cc + 555465 GUnix{Input,Output}Stream lacks fd/close_fd_at_close property + 558298 Hide ecryptfs mounts + 515777 incorrect date&time on copy + 562452 Ensure we return G_IO_ERROR_CANCELLED if cancelling + g_simple_async_result_run_in_thread + 473150 g_type_module_use inconsistently increases the use + counter in case of error + 563150 G_GU?INT*_MODIFIER/FORMAT docs + 563156 Document printing and scanning gunichar values + +* Updated translations: + Hebrew (he) + Italian (it) + + +Overview of Changes from GLib 2.19.0 to GLib 2.19.1 +=================================================== + +* GIO: + - g_icon_to_string, g_icon_new_for_string: GIcon serialization support + - G_FILE_ATTRIBUTE_PREVIEW_ICON: new file attribute for preview images + - g_app_info_get_commandline: new function to get the full commandline + - g_mount_shadow, g_mount_unshadow, g_mount_is_shadowed: New functions + to 'shadow' mounts (i.e. hide them from the UI when they already + have a different representation, like a bookmark) + +* Bugs fixed: + 556186 gpoll.h breaks gmain.h inclusion + 557087 mem leak in g_content_types_get_registered + 556921 gpoll.h breaks hal compilation + 557210 g_compute_checksum_for_* asserts with less than 2 bytes + 558381 Add support for compile time assertions + 558185 'parent' variable in g_local_file_get_child_for_display_name() + hits g_object_unref(NULL) assertion + 558513 g_warn_if_fail FIXME in gtestutils + 558672 NULL key lookup using g_hash_table_lookup_extended() + 555740 gicon serialization + 557182 preview functionality + 528320 Incorrect icons displayed for files with custom mimetype icons + 556910 Memory leak: sub + 557592 Missing include in gwinhttpfile.c + 556415 Crash on Windows 2000 in g_winhttp_vfs_init() + 555935 Clarify the mechanism of overwriting properties + 552776 ac_cv_func_posix_getgrgid_r not mentioned + 559448 GObject Reference Manual (typo) + 561212 GFileReadMoreCallback API doc refers to non-existant function + 560569 gkeyfile doesn't use the set list_separator in some cases + 560568 gkeyfile docs buglet + 559413 g_option_group_set_error_hook docs buglet + 562378 callback return value not respected for callback option + with no arg + 559110 Do not include libintl.h after glibintl.h + 557603 carbon check output misplaced + 562544 g_key_file_get_string and g_key_file_get_value + documentation does not explain the difference + 547264 Missing "no flags" flag + 562638 GDebugKey key member should be const + 562639 g_parse_debug_flags() parsing "help" + 562549 g_byte_array_free should tell how free data + 559452 GObject Reference Manual (typo) + 559462 GObject Reference Manual (typo) + 559517 GObject Reference Manual (typo) + 562538 GObject interface tutorial shouldn't finalise with + "Please forget everything" + 561352 Leak of icon description + 561375 Leaks mountpoint description + 561807 inotify_sub.c: dup_dirname() fails to remove trailing '/' + 562393 g_buffered_input_stream_read_byte broken if data available + 541715 win32 : patch for warnings and signature problems in recent code + 547481 g_data_input_stream_read_line behaves not as stated in the docs + 548163 Nautilus displays wrong error message for too long file names + 559633 gtk_image_new_from_gicon does not always work for .desktop files + 555486 – No way to recover command line from GAppInfo + +* Translation updates: + Spanish (es) + Ukrainian (uk) + + +Overview of Changes from GLib 2.18.1 to GLib 2.19.0 +=================================================== + +* Rewrite GHashTable to use open addressing with quadratic probing instead + of chaining. This has the potential to reduce memory fragmentation + significantly, while being slightly faster due to better locality and + no need to call alloc/free functions for nodes. Benchmarks suggest it + also uses less memory overall. + +* Make g_poll available as public api + +* New macros g_assert_error and g_assert_no_error to assert + that a GError is set or unset + +* g_cancellable_make_pollfd: New method to make a GPollFD for a cancellable + +* g_app_info_can_delete, g_app_info_delete, g_app_info_reset_type_associations: + New functions to clean up app infos and content types + +* When launching applications, always pass fuse file:// uris when possible, + and let gio convert such uris back to gio uris. + +* Bugs fixed: + 505361 gunixinputstream.c assumes poll() available + 509446 portable blocking gio cancellation + 553820 gpoll.c: undeclared identifier + 553724 python interpretter path not patched in correctly + 553857 gbacktrace.h requires signal.h + 553447 g_assert_no_error() + 554092 glib doesn't return G_FILE_ERROR_NOENT et al on OS X + 528670 Always pass file:/// uri's in GAppLaunchContext + 555224 Improve g_format_size_for_display doc + 555309 giochannel breaks on error + 554790 g_convert() misbehaves with winiconv versions + 555314 mem leak in gmarkup + 555313 GFileAttribute boxed type get_type function should... + 552861 glib-2.0.m4 calls system(3) without storing its result + 554557 Patch to fix gcc warnings about missing format specifiers + 552107 Small libtool fixes + 551355 Make glib build with libtool 2.2 + 555311 format not a string literal and no format arguments + 556101 static mutex yields warnings with g++ + 556186 gpoll.h breaks gmain.h inclusion + 526456 Open addressing in GHashTable + 553426 cancellable clarifications + 545350 GAppInfo deletion + 545351 Reset associations for content type + 552168 volume's mount not mounted after g_volume_mount_finish + 554970 segfault when update-desktop-database is not available... + 554745 GFileAttributeInfoList should be boxed + 555121 Improved build-time handling of gio module-dir + 555711 Wrong fallback order of mimetype icons + 555331 Deprecate adoption of mounts + 556335 make check fails in abicheck.sh + 556334 Warning when building without selinux support + 556422 g_file_enumerator_next_file: unclear... + +* Updated translations: + Arabic (ar) + Danish (da) + Polish (pl) + Brazilian Portugese (pt_BR) + Romanian (ro) + Russian (ru) + + +Overview of Changes from GLib 2.18.0 to GLib 2.18.1 +=================================================== + +* Bugs fixed: + 550433 g_test_init doesn't recognize --help + 523463 Core dump in gmain.c:2482:IA__g_main_context_check + 551228 G_STRFUNC on recent Sun compiler should be expanded... + 551410 gtestutils.c: using printf without prototype + 551731 g_date_set_time[_t] docs should mention what timezone + 548321 is not included in gi18n-lib.h + 551149 xdgmime mem leak + 550647 synchronous pipe I/O when reading mount reply + 551887 Docs for g_desktop_app_info_new_from_filename aren't... + 551681 g_content_type_guess() too naive with filenames + 552352 g_app_info_launch doesn't work if "Path" key... + 551408 gmodule.def generated to builddir... + 552359 g_file_info_get_icon should return GThemedIcon, and... + +* Updated translations: + Arabic (ar) + Bengali India (bn_IN) + British English (en_GB) + Hindi (hi) + Croatian (hr) + Korean (ko) + Oriya (or) + Turkish (tr) + Telugu (te) + + +Overview of Changes from GLib 2.17.7 to GLib 2.18.0 +=================================================== + +* The recommended way of using GLib has always been to only include the + toplevel headers glib.h, glib-object.h and gio.h. GLib enforces this by + generating an error when individual headers are directly included. + To help with the transition, the enforcement is not turned on by + default for GLib headers (it is turned on for GObject and GIO). + To turn it on, define the preprocessor symbol G_DISABLE_SINGLE_INCLUDES. + +* Win32: + - rework the g_poll() implementation to match poll() semantics more closely + +* Bugs fixed: + 324234 Using g_io_add_watch_full() to wait for connect() to return... + 548278 Async GETs connections are always terminated unexpectedly... + 500246 Bug fixes for giowin32 + 523939 Example program for GValue + 550096 GBookmarkFile parser is not forward compatible + 550040 Move GString, rand and printf tests to the unit test framework + 550104 trivial documentation fix for g_get_home_dir + 548988 g_file_replace fails on Windows when the target file exists + 550059 Wrong docs for g_emblemed_icon_add_emblem + 548800 Missing a g_object_get_type function + 550056 Missing documentation for g_emblemed_icon_get_emblems + +* Updated translations: + Bulgarian (bg) + Czech (cs) + German (de) + Estonian (et) + Basque (eu) + French (fr) + Hebrew (he) + Hungarian (hu) + Italian (it) + Japanese (ja) + Lithuanian (lt) + Maithili (mai) + Dutch (nl) + Swedish (sv) + Thai (th) + Ukrainian (uk) + Vietnamese (vi) + + +Overview of Changes from GLib 2.17.6 to GLib 2.17.7 +=================================================== + +* More fixes for 64-bit Windows + +* GIO + - Add a vfs implementation for HTTP and HTTPS URIs on Windows + +* Bugs fixed: + 546329 API docs for g_utf8_normalize() are incorrect + 546876 Modify GMarkup parser to accept  ..  + 547200 g_utf8_find_next_char() issues + 547637 unconditional #include of sys/statfs.h in configure + 547337 G_DISABLE_DEPRECATED breaks tests build + 547832 gtk+-2.12.11 fails to build - AC_PROG_MMAP too strict + 502498 Test framework assertion failures should follow gcc + 546371 Improve docs re g_file_monitor + 546483 GThemedIcon:use-default-fallbacks is not readable without... + 546132 GFileIcon is bindings-unfriendly + 542156 zfs mount in home directory shown on nautilus desktop + 535124 umask 002 not being applied for new directories... + 547080 g_file_copy leaks expected errors + 546582 Callbacks from GFileMonitor present a GFile... + 547262 Missing link in the docs + +* Updated translations: + Arabic (ar) + Catalan (ca) + Spanish (es) + Basque (eu) + Finnish (fi) + Galician (gl) + Hebrew (he) + Marathi (mr) + Norwegian bokmÃ¥l (nb) + Portugese (pt) + Brazilian Portugese (pt_BR) + Swedish (sv) + Thai (th) + + +Overview of Changes from GLib 2.17.4 to GLib 2.17.6 +=================================================== + +* Fix problems on 64-bit Windows + +* g_markup_context_get_user_data: New function to access + the user_data outside of callbacks + +* GIO + - g_mount_guess_content_type_sync: synchronous version of + g_mount_guess_content_type + - GEmblem: A GIcon implementation that adds emblem-related + metadata to icons + - GEmblemedIcon: A GIcon implementation that can add emblems + to icons + +* Bugs fixed: + 544088 option_test_LDADD is left in tests/Makefile.am + 544465 gmarkup makes it hard to use pre-rolled parsers + 545485 Implicit declaration of utime() + 545798 "Since: 2.18" mark is missing in g_set_error_literal... + 544140 fam-helper 64-bit issue + 529694 SELinux context setting support + 545157 wrong/no list of "open with" applications for .cc... + 545203 gfile.c: argument is different type + 545457 gdmsetup crashed with SIGSEGV in g_unix_mount_guess... + 544177 Fix trivial cut and paste error in documentation + 545395 Language tweak for g_value_set_string* docs + 541036 Gnumeric crashes when trying to open Desktop... + 546079 leak in xdgmime + 545395 Language tweak for g_value_set_string* docs + 546017 Don't copy attributes when copying a symlink + +* Updated translations: + Arabic (ar) + Estonian (et) + Galician (gl) + Italian (it) + Japanese (ja) + Korean (ko) + Norwegian bokmÃ¥l (nb) + Pashto (ps) + Portugese (pt) + + +Overview of Changes from GLib 2.17.3 to GLib 2.17.4 +=================================================== + +* GIO: + - New API to handle content types: g_mount_guess_content_type, + g_content_type_guess_for_tree. + - Export the eject-button signal on the volume monitor class + - New API to enable out-of-process volume monitors: + g_volume_get_activation_root + +* GObject: + - New API to handle signals without slots in the class structure: + g_signal_new_class_handler, g_signal_override_class_handler + +* Internationalization: + - Add an NC_ macro that is a no-op equivalent of C_ + +* GMarkup: + - Add two new functions g_markup_parse_context_push, + g_markup_parse_context_pop to support "subparsers" + +* Bugs fixed: + 541208 Functions to easily install and use signals without... + 541507 Ambiguous description of assigned characters in the... + 543040 async reading on dummy file will crash on GIO_USE_VFS=local + 543560 enable gio-FEN back-end warnings on Solaris will crash... + 528317 GRegex does not allow recursion limit + 337518 GMarkup: Subparser support + 541794 drive-eject-button signal + 541793 activation root for volumes + 467707 test_iconv_state() in tests/convert-test.c fails on AIX 5.3 + 428048 2 of 51 tests fail on Solaris + 542332 small fix for error message in GMarkup + 482413 get_contents_stdio -- overflow and memory corruption + 406120 g_ascii_strtod + 334234 "printf" format error + 536996 Missing noop i18n macro equivalent to C_ + 540616 mem leak in filechooser button + 539229 gobject-query calls itself query + 521589 [RFC] gobject documentation should mention Vala + 543168 Description of G_SLICE=debug-blocks discourages its use + 543220 Case collision on gio-extension-points.html + 530759 update the gobject tutorial to the XXI century + 535223 gbookmark file inefficiency ... + 543504 crash in Epiphany Web Browser: Opening local file + +* Updated translation: + German (de) + Estonian (et) + Pashto (ps) + Albanian (sq) + Thai (th) + Traditional Chinese (zh_HK) + Traditional Chinese (zh_TW) + + +Overview of Changes from GLib 2.17.1 to GLib 2.17.3 +=================================================== + +* PCRE + - fix for CVE-2008-2371 + +* Bugs fixed: + 538119 glib's mainloop leaks a pipe to sub-processes + 537635 Corrections and improvements to g_time_val_{to,from}_iso8601 + 539067 The document g_io_channel_win32_new_fd() says... + 535949 annotate g_strip_context and g_dpgettext with G_GNUC_FORMAT + 539123 annotate g_d[n]gettext with G_GNUC_FORMAT + 539074 Cannot get exit status with g_spawn_command_line_sync + 316221 G_LOCK warns about breaking strict-aliasing rules + 539770 migrate gstrfunc unit tests to gtest + 539626 Update docstrings for g_object_freeze_notify and g_object_thaw_notify + 538044 unconditional use of LC_MESSAGES + 540545 Monotonic time and timer offset + 535947 want g_set_error_literal + 539999 glibconfig.h: add GLIB_USING_SYSTEM_PRINTF + 536252 GFileEnumerator should allow access to the containing GFile + 538362 Get Win32 icons back in the file chooser + 540802 g_list_prepend doesn't concat lists + 540423 unrecoverable error after g_seekable_truncate + 538836 make check failure on PPC and ALPHA: pltcheck.sh on g_atomic_pointer_get + 539090 g_content_type_from_mime_type() should unalias + 540331 g_file_append_to () documentation: can return NULL + 534639 add g_desktop_app_info_new_from_keyfile + 536733 gio build failure on Irix + 536160 Add g_file_monitor() + 538127 FileChooser broken on win32 + 531476 /live-g-file/test_traverse_structure test fails on Mac HFS+ + 538564 gio should have gio-types.h + 540047 glib-genmarshal.c: '#include ' is too before + +Updated translations: + Korean (ko) + Occitan (oc) + + +Overview of Changes from GLib 2.17.0 to GLib 2.17.1 +=================================================== + +* New function: g_utime(), a gstdio wrapper for utime() + +* New functions: g_dgettext() and g_dngettext(), wrappers + for corresponding gettext functions with added functionaliy + +* Support the latest version of the shared-mime spec, including + icons for mime types + +* New function: g_themed_icon_prepend_name() + +* Bugs fixed: + 535418 Please document which glib version defines goffset + 528715 Misprint in the description of the interface g_type_class_add_private + 528714 Misprint in the description of the interface g_param_spec_flags + 537260 Doc bug in G_TYPE_INSTANCE_GET_CLASS() + 530527 Misprint in the description of the interface + g_cclosure_marshal_VOID__FLAGS + 530526 Misprint in the description of the fields 'class_init' and + 'class_finalize' of the structure GTypeInfo + 528719 Improvement to the documentation of the "g_object_connect" interface + 528172 gtk_signal_handlers_unblock_* functions return value + amount of matched signals, not amount of actually unblocked + 528717 Misprint in the description of the parameter 'type_id' for + the interface g_type_register_fundamental + 528716 Misprint in the description of the parameter 'iface_data' for + the callback types GInterfaceInitFunc and GInterfaceFinalizeFunc + 537555 GObject instantiation not thread safe + 537546 'desktop' shortcut in file chooser looks like a generic folder + 537392 Additional colon in xattr name + 536641 Filesystem querying in gio does not list AFS and autofs file systems + 528600 g_dummy_file_get_parent("scheme://example.com/") + 503071 Application direction changes to right to left even if theres no + translation + 502511 g_assert_cmphex prints invalid message + 338162 Use po/LINGUAS + 314453 Nautilus crashes in Solaris when browsing the attached file + 529321 make check fails in glib/pcre + 455215 g_get_user_special_dir: no reference about G_USER_DIRECTORY_DOWNLOAD + fallback to $HOME/Desktop if xdg-user-dirs is not in use + 498732 g_key_file_to_data cannot fail + 511367 add g_file_make_directory_with_parents + 531900 Use __builtin_offsetof for G_STRUCT_OFFSET if building with + gcc 4.0 or newer + 536158 also bump GHashTable version when a node is removed via + g_hash_table_iter_remove()/g_hash_table_iter_steal() + 531403 g_utf8_collate broken on Mac + 535628 test/patterntest.c still includes gpattern.h directly + 535625 alias.h:2648: error: 'utime' undeclared here (not in a function) + +* Translation updates: + Arabic (ar) + German (de) + Italian (it) + Norwegian bokmÃ¥l (nb) + Thai (th) + + +Overview of Changes from GLib 2.16.x to GLib 2.17.0 +=================================================== + +* Update to Unicode 5.1 + +* Update included libcharset to the one shipped with libiconv 0.12 + +* Update included PCRE to 7.7 + +* Enforce that only toplevel headers are directly included. + This is turned on by default for GObject and GIO. To turn + it on for GLib, define G_DISABLE_SINGLE_INCLUDES. + +* Fix library version of GIO. GLib 2.16 shipped with libgio-2.0.so.0.0.0 + +* On Solaris, use FEN for file monitoring in GIO + +* Use the GIO_EXTRA_MODULES environment variable to find + additional GIO modules + +* G_GNUC_ALLOC_SIZE: New macro that wraps the gcc alloc_size + function attribute + +* g_checksum_reset: New function to reset the state of a GChecksum + +* g_unix_mount_monitor_set_rate_limit: New function to limit the + rate at which events are reported + +* g_file_query_file_type: New utility function to query the type of + a file + +* g_memory_output_stream_get_data_size: New function to obtain the + size of the written data. + +* Bugs fixed: + 522292 Gives warnings in glib/gutils.h with GCC in C99 mode + 523298 win_iconv can't convert from UTF-8 to GB18030 (or vice versa) + 518160 replace two g_strdup_printf calls in GBookmarkFile + 523877 gbookmarkfile: avoid using g_string_append_printf() and + other optimizations + 525192 100% CPU if run main loop with no IO sources + 315437 extern inline -> static inline + 524314 g_convert() on Win32 implicitly converts full width + alphanumerics into half width + 525732 Error in documentation for g_list_first + 525674 A typo in gmarkup.c + 448943 g_timeout_add_seconds() problems + 525972 UCS-4 not in the new win_iconv implementation + 526619 make test-report crash + 491554 Update to Unicode 5.1.0 + 519137 g_slice_dup macro needs cast for 64-bit platform + 528752 Win32 build and SSL not working + 530457 G_USER_DIRECTORY_DOWNLOAD folder improperly mapped + 528667 Typos in testing module documentation + 459905 Bug in wcwidth data + 534085 g_unichar_iswide_cjk() has a totally wrong table + 501651 Update glib/libcharset + 519026 G_STMT_START/G_STMT_END test a non-existent preprocessor symbol + 534319 GLib's .pc files could use Libs.private + 534137 Typo in g_spawn_async_with_pipes doc + 517419 gio win32 directory monitor + 526796 Wrong order of arguments in g_file_copy's fallback + 530196 _g_local_file_has_trash_dir() doesn't handle st_dev == 0 + 532965 Should not return filesystem::free for certain file systems + 525553 fix typo and nitpicking in GArray documentation + 526572 Missing * in declaration of parent_class in Object + Destruction section of GObject Reference Manual + 528648 Extra >s in Object Construction section + 535021 g_param_spec_internal documentation should + describe purpose of nick and blurb + 521513 Firefox crash when using file picker + 528433 gdesktopappinfo snafu ... + 533369 API g_file_info_get_attribute_string () unables to get "... + 521045 glib f_fstypename miscellany + 521672 compile error + 521946 control rate limit on GUnixMountMonitor + 522335 Fails to build: glib/gtester.c:276: error: 'ARG_MAX' unde... + 523015 Implement sliding window based upload operation + 523019 Use new GCC 4 feature + 523338 list nfs4 as a nfs mount type + 524350 Make glib build without NLS again + 524579 g_file_copy reports wrong total on progress callback for ... + 524742 A typo in gtestutils.c. + 524950 Minor documentation typos. + 525866 the user directory should not be considered as a mount to... + 526320 should not list mounts that the user doesn't have permiss... + 527132 nautilus crash when making ftp connection + 532852 CRITICAL **: totem_pl_parser_parse_with_base: assertion `... + 534759 Build failure in gio + 534764 Typo in error produced by g_file_make_directory + 521851 Redudant tests in gunixmounts.c + 524344 glib/gthread.h still use G_GNUC_PRETTY_FUNCTION + 525060 glib fails to build with -DG_DISABLE_ASSERT in CPPFLAGS o... + 534177 Invalid description of the interface g_cclosure_marshal_S... + 520715 Add GFile method g_file_query_file_type + 523039 nautilus can't access to trash/computer/network if gvfs i... + +* Updated translations: + Arabic (ar) + Bulgarian (bg) + Catalan (ca) + Czech (cs) + Greek (el) + Candian English (en_CA) + British English (en_GB) + Spanish (es) + Estonian (et) + Basque (eu) + Galician (gl) + Hebrew (he) + Hungarian (hu) + Japanese (ja) + Lithuanian (lt) + Norwegian bokmÃ¥l (nb) + Dutch (nl) + Occitan (oc) + Portugese (pt) + Russian (ru) + Slovak (sk) + Albanian (sq) + Swedish (sv) + Turkish (tr) + Vietnamese (vi) + + +Overview of Changes from GLib 2.16.0 to GLib 2.16.1 +=================================================== + +* Fix a crash in g_themed_icon_new + +* Update the included PCRE to 7.6 + + +Overview of Changes from GLib 2.15.6 to GLib 2.16.0 +=================================================== + +* GLib now includes GIO, which adds optional dependencies against libattr + and libselinux for extended attribute and SELinux support. Use + --disable-xattr and --disable-selinux to build without these. + +* Fix the definition of G_INLINE_FUNC to work with gcc 4.3.0 + +* GIO: + - Add missing GMountMountFlags argument to g_unix_volume_mount + - Fix the adopt_orphan_mount vfunc to take a volume monitor + reference + - Add properties to GThemedIcon for bindings sake + +* Bugs fixed: + 520484 gvfsd-trash crashed with SIGSEGV in g_path_is_absolute() + 510855 g_checksum_update(): Take -1 for length. + 517676 g_themed_icon_new*() do more than call g_object_new(). + 518816 should handle rmdir returning EEXIST correctly + 519352 g_[s]list_delete_link() docs + 519489 Fixes for sparse warnings in gio + 520169 add monitor argument to vfunc for GVolumeMonitor + 520700 Add type check in g_file_query_exists + 521145 FILE_READ_ONLY_VOLUME not present on Mingw32 + 518720 No MIME type for empty files + 521013 in documentation, goffset doesn't say "Since 2.x" + 521028 Missleading error messages from g_io_channel_set_encoding() + 517484 GMainLoop could set the thread "Alertable" for APCs to be... + +* Updated translations: + Assamese (as) + Bengali India (bn_IN) + Czech (cs) + German (de) + Spanish (es) + Estonian (et) + Finnish (fi) + French (fr) + Gujarati (gu) + Italian (it) + Lithuanian (lt) + Malayalam (ml) + Marathi (mr) + Norwegian bokmÃ¥l (nb) + Romanian (ro) + Russian (ru) + Slovak (sk) + Ukrainian (uk) + + +Overview of Changes from GLib 2.15.5 to GLib 2.15.6 +=================================================== + +* GIO: + - New file attributes: trash::item-count, filesystem::use-preview + - Rename g_file_contains_file to g_file_has_prefix + - g_file_query_filesystem_info grew async variants + - g_themed_icon_append_name: new convenience function + - g_content_type_get_icon is implemented now + - Only show mounts in /media and ~ + - g_file_contains_file has been renamed to g_file_has_prefix + +* Win32: + - g_win32_get_package_installation_directory_of_module: new function + which supersedes g_win32_get_package_installation_directory + - Use alertable wait functions so that I/O completion routines or + user-mode Asynchronous Procedure Calls can be run + - Fix race conditions in g_spawn implementation on win32 + +* Other: + - g_uri_get_scheme has been renamed go g_uri_parse_scheme + +* Updated translations: + Arabic (ar) + Belarusian Latin (be@latin) + Catalan (ca) + British English (en_GB) + Finnish (fi) + Galician (gl) + Hebrew (he) + Italian (it) + Kannada (kn) + Norwegian bokmÃ¥l (nb) + Dutch (nl) + Brazilian Portugese (pt_BR) + Vietnamese (vi) + + +Overview of Changes from GLib 2.15.4 to GLib 2.15.5 +=================================================== + +* Update the included PCRE to 7.6 + +* GIO: + - g_volume_should_automount: new function to determine if a volume + should be mounted automatically + - g_file_query_default_handler: new convenience function to get + the default handler for a file + - g_app_info_launch_default_for_uri new convenience function to + launch the default handler for a URI + - Use mimeapps.list and defaults.list as discussed on xdg list + recently + - g_app_info_get_default_for_uri_scheme has a real implementation + now (gvfs provides a GConf-based implementation) + - There is the beginning of a test suite + - standard::description: new file attribute + - GMountMountFlags flags argument added to mount calls + +* GObject: + - class initialization is now threadsafe + +* Updated translations: + Arabic (ar) + Catalan (ca) + Spanish (es) + Basque (eu) + Italian (it) + Japanese (ja) + Kannada (kn) + Korean (ko) + Macedonian (mk) + Occitan (oc) + Portugese (pt) + Brazilian Portugese (pt_BR) + Swedish (sv) + Thai (th) + + +Overview of Changes from GLib 2.15.3 to GLib 2.15.4 +=================================================== + +* G_GNUC_PRETTY_FUNCTION has been deprecated + +* GIO: + - g_file_copy has an async variant now + - Drives and volumes now have API to get identifiers + like Hal UDIs or UUIDs. + - There is now a registration API to let modules register + extensions they provide, such as volume monitor implementations + +* Bugs fixed: + 511807 g_time_val_to_iso8601() uses MT-unsafe gmtime() function + 316260 [patch] Doc patches for gnode (2.8.1) + 385132 solaris gettext support fix + 484261 ./configure check for system PCRE unicode support fails w... + 510292 GOption main help not shown + 511580 Implement g_file_copy_async + 511654 Compile errors due to C99 constructs + 487909 g_utf8_strreverse and combining marks + 512381 unused variable 'is_main_group' + +* Updated translations: + Arabic (ar) + Belarusian (be) + Czech (cz) + Spanish (es) + French (fr) + Galician (gl) + Portugese (pt) + Russian (ru) + Swedish (sv) + Thai (th) + + +Overview of Changes from GLib 2.15.2 to GLib 2.15.3 +=================================================== + +* GChecksum: + - g_checksum_update can accept nul-terminated strings + - The MD5 implementation works correctly on buffers + that are longer than 64 bytes + +* GIO: + - Don't include a copy of the inotify headers, rely on system headers + - g_file_find_enclosing_mount has an async variant now + - Reduntant seek API on file streams has been removed + +* Bugs fixed: + 508602 gmemory{in|out}putstream.c: unknown pointer size + 508771 There is no g_file_test/exists() for GFile + 508773 g_uri_escape_string() documentation unclear. + 509465 AM_PATH_GLIB_2_0 doesn't support gio + 509626 async functions: Document allowed NULL callback? + 509990 GSeekable documentation unclear + 510448 No inotify support on ARM or SH5 + 510855 g_checksum_update(): Take -1 for length. + +* Updated translations: + Basque (eu) + Marathi (mr) + Swedish (sv) + Ukrainian (uk) + + +Overview of Changes from GLib 2.15.1 to GLib 2.15.2 +=================================================== + +* GIO: + - Mount operation API change: unhandled methods get reported via + the reply, rather than by the signal emission return value + - File monitor API change: Add a GError argument to g_file_monitor_file + - g_unix_mount_guess_should_display(): new function + +* Bugs fixed: + 508224 [PATCH] FAM backend crashes due to double free + 508074 GAsyncResult documentation suggests g_freeing it. + 508108 GFile documentation slightly unclear. + 508309 rpc_pipefs mount points should be hidden + 508378 GFileInfo documentation implies that it changes attribute... + 508719 g_file_get_relative_path fails if parent is root + 508773 g_uri_escape_string() documentation unclear. + +* Updated translations: + Arabic (ar) + Spanish (es) + Hebrew (he) + Italian (it) + Korean (ko) + Turkish (tr) + + +Overview of Changes from GLib 2.15.0 to GLib 2.15.1 +=================================================== + + * Portability fixes: + - Assertion functions are marked as noreturn again + - Handling of inline functions has been fixed to work with gcc 4.3 + - C99 comments have been removed from headers + - The nonportable sed -i option is no longer used + + * GIO: + - Clarified the semantics of g_app_info_get_all() + - API for memory input and output streams has been changed a bit + - GDirectoryMonitor has been removed; GFileMonitor can monitor + files and directories now + + * Bugs fixed: + 504829 Invalid environment passed to g_spawn_async in g_desktop_... + 505258 crash in Users and Groups: Adding a user + 505815 g_content_types_get_registered should not g_free keys + 491218 g_timer_new() doesn't initialize timer->end + 315437 extern inline -> static inline + 476856 Inconsistency between standard and implementation of the ... + 480122 g_module_open fails to open modules with ".la" extension + 495589 gspawn.c failing to set FD_CLOEXEC + 500273 doesn't build with --disable-visibility + 504142 Do not show empty groups in --help output + 504879 giofam incorrectly linked + 505042 add file attribute for actually used file size in bytes + 505058 xattr namespace docs + 505674 Misprint in the definition of the macro G_CCLOSURE_SWAP_DATA + 505730 Fails to build on OSX 10.4: _NSGetEnviron not declared + 505887 older darwin lacks lchown + 506374 gmemoryinputstream api + 506461 Conversion of g_assert_not_reached() and friends into fun... + 503051 Small bug in glib interface + 506395 Updates to GIO documentation + 507628 Missing .pc entry for gio linking against glib + 505195 [patch] typo in g_try_new0 docs + 507822 g{file,directory}monitor changes signal problem + 506377 gmemoryoutputstream write implementation + 507835 bug in gunixinputstream + + * Updated translations: + Arabic (ar) + Belarusian Latin (be@latin) + Spanish (es) + Basque (eu) + Irish (ga) + Hebrew (he) + Occitan (oc) + Vietnamese (vi) + + +Overview of Changes from GLib 2.14.x to GLib 2.15.0 +=================================================== + +Major new features: + + * GIO: a VFS API, designed to replace GnomeVFS. The GIO implementation + in GLib has support for local filesystems. The new, separate gvfs + module contains various backend implementations (cifs, ftp, sftp, + http, ...) + + * GChecksum: provides various hash algorithms, such as MD5, SHA-1 + and SHA-256 + + * GTest: a test framework + +Smaller additions: + + * GHash: + - GHash has iterators, as an alternative to g_hash_table_foreach + + * GMarkup: + - g_markup_parse_context_get_element_stack: New function to + get the stack of open elements + - G_MARKUP_PREFIX_ERROR_POSITION: New flag to improve error + reporting + - g_markup_collect_attributes: Convenience function for handling + attributes + +* GKeyFile: + - Functions that take a GError now return a boolean to indicate + success, instead of void + - Various performance improvements + +* GAsyncQueue: + - g_async_queue_new_full: new function that allows to specify + a free function for leftover elements + +* GError: + - g_prefix_error and g_propagate_prefixed_error: New functions + to ease error propagation + +* Internationalization: + - C_: A new 2-argument variant of the Q_() macro + - Use native character set conversion API on Windows + +* GLib builds with automake 1.10 + +* Bugs fixed: + 455725 specific combination of g_utf8_strlen and g_pattern_match... + 467537 g_convert_with_iconv() not resetting iconv() state correc... + 497033 Commandline option parser should warn about missing optio... + 504527 gchecksum: Conditional jump or move depends on uninitiali... + 445362 Non-numeric local labels in gatomic.c are causing linker ... + 482313 gregex: no way to tell why compilation failed + 317775 main loops continues to run after g_main_loop_quit() has ... + 418778 Insufficient pkg-config version requirement + 436293 g_option_context_new() doc should mention that the string... + 466557 glib-mkenums shifts ARGV[0] to undefined + 468882 GKeyFile doesn't accept "True" as a true boolean value + 469551 application --help messages are garbaged on none UTF-8 lo... + 479724 Memory leak upon calling "g_main_loop_run" in the seconda... + 490061 outptrs uninitialized after g_parse_long_long + 490637 gobject documentation patch + 495294 glib-genmarshal prints warnings but returns 0 + 496046 option to prefix location of errors for GMarkup + 498113 tests/regex-test fails on 64bit environment + 500506 Fails to build on OSX 10.4 + 500638 gkeyfile speedup ... + 500875 Make check fails as there is no "test" target for "build"... + 502511 g_assert_cmphex prints invalid message + 502927 g_array_index triggers cast aligment warning + 503029 g_time_val_from_iso8601 parse non-ISO8601 dates + 503222 Need context to translate + 503420 gkeyfile leaks a hash table + 503470 Fix build when builddir != srcdir + 504227 Inverse variant for g_test_trap_assert_stdout, g_test_tra... + 71704 file include order + 491957 Misprint in the specification of the interface "g_main_co... + 491959 Misprint in description of the structure "GThreadPool" + 491965 Mistype in the specification of the function "g_hook_list... + 491966 Misprint in the specification of the interface "g_main_co... + 491968 The documentation does not mention the restriction for th... + 491970 The documentation for the interface "g_date_clamp" is inc... + 491974 The documentation of the interface "g_main_context_iterat... + 491975 The documentation for the interfaces "g_io_channel_read_u... + 491979 Misprint in the description of the interfaces g_key_file_... + 491982 Misprint in the description of the interface "g_key_file_... + 501107 EXTRA_DIST automake warnings + 501997 g_utf8_normalize() returns NULL on invalid string + 502590 C_/g_dpgettext efficiency + 464259 g_set_application_name() docs should say "Since 2.2" + 496518 gbase64.c API doc clarification + 498728 g_key_file_get_*_list should set length to 0 when returni... + 500361 Improve docs for g_array_free() and g_ptr_array_free() + 501853 g_checksum_get_digest docs + 503862 Allow NULL strings in g_parse_debug_string() + 142676 Q_ + 367550 Add g_async_queue_new_full() with GDestroyNotify function + 375651 Minor enhancements to GKeyFile API + 443648 MD5 digest support + 449937 Upgrade auto* sources to be clean under automake1.9 + 452887 gmarkup context "get element" function is useless when ca... + 491549 [PATCH] Eliminate libiconv dependency on Windows + 500507 GHashTableIter API + +* Translation updates + Belarusian Latin (be@latin) + Czech (cs) + German (de) + Spanish (es) + Esperanto (et) + French (fr) + Korean (ko) + Marathi (mr) + Norwegian bokmÃ¥l (nb) + Brazilian Portugese (pt_BR) + Slovenian (sl) + Swedish (sv) + + +Overview of Changes from GLib 2.14.2 to GLib 2.14.3 +=================================================== + +* Update PCRE to 7.4 + +* Bugs fixed: + 487491 Fix some warnings from sparse + 488068 Small (one-time) memory leak in glib_gettext initialization + 493688 TYPE macro "_get_type ()" is documented wrong + +* Updated translations: + Arabic (ar) + Belarusian Latin (be@latin) + Estonian (et) + Irish (ga) + Slovenian (sl) + + +Overview of Changes from GLib 2.14.1 to GLib 2.14.2 +=================================================== + +* Bugs fixed: + 476849 Invocation of the interface "g_hook_free" fails in certai... + 359165 marshallers can throw warnings with -Wunused + 477957 more discussion on g_value_set_object vs. g_value_take_ob... + 478459 G_DEFINE_DYNAMIC_TYPE_EXTENDED doesn't work with G_IMPLEM... + 483337 inline is disabled for MSVC when compiling C code + 478349 Broken link to gettext website + 469231 g_spawn optimization for setting all open fds to CLOEXEC + +* Updated translations: +Arabic (ar) +Galician (gl) +Hebrew (he) +Korean (ko) + + +Overview of Changes from GLib 2.14.0 to GLib 2.14.1 +=================================================== + +* Bugs fixed: + 476840 Invocation of the interface "g_utf8_strreverse" crashes f... + 444765 Fix FIXME in gregex.c when new pcre is out + 464145 g_markup_escape_text Produces Invalid XML + 465625 g_type_default_interface_ref() does not ensure working g_... + 466768 Clearify that comments can be put anywhere in a Key-file. + 474229 The GError documentation should give convention for the G... + 474899 G_BREAKPOINT() docs inaccurate + 475854 Overuse of -lpcre when using system pcre + 473879 Incorrect includes in gregex.c + 468694 Typoes in documentation + 469051 g_snprintf () talks about characters where it probably me... + 457601 Missing arch specific atomic implementation + 475923 Missing pcre flags when static-linking against glib + 475619 glibthread-2.0.la does not list -lpthread + +* Updated translations: + Bulgarian (bg) + Catalan (ca) + Danish (da) + German (de) + Canadian English (en_CA) + British English (en_GB) + Spanish (es) + Estonian (et) + Finnish (fi) + French (fr) + Gujarati (gu) + Hungarian (hu) + Italian (it) + Georgian (ka) + Kannada (kn) + Lithuanian (lt) + Makedonian (mk) + Norwegian (nb) + Dutch (nl) + Polish (pl) + Portugese (pt) + Brazilian Portugese (pt_BR) + Romanian (ro) + Russian (ru) + Albanian (sq) + Serbian (sr, sr@Latn) + Swedish (sv) + Tamil (ta) + Thai (th) + Ukrainian (uk) + Vietnamese (vi) + + +Overview of Changes from GLib 2.13.7 to GLib 2.14.0 +=================================================== + +* Last-minute API additions: + - Make g_unichar_combining_class public + - Add goffset type, add G_MAXSSIZE and G_MINSSIZE + +* Update PCRE to 7.2 + +* Bugs fixed: + 453998 Make _g_unichar_combining_class() public + 462549 gregex.c: variable is declared at middle of block + 417068 g_file_test doc inconsistency + +* Updated translations: + Assamese (as) + Basque (eu) + Kannada (kn) + Malayalam (ml) + Dutch (nl) + Polish (pl) + Brazilian Portugese (pt_BR) + Turkish (tr) + + +Overview of Changes from GLib 2.13.6 to GLib 2.13.7 +=================================================== + +* The memory corruption warning from the slice allocator that + occurred when threads were initialized after the slice allocator + has been removed, as the slice allocator now works fine + in this scenario. + +* New functions g_once_init_enter() and g_once_init_leave() make + it easier to write threadsafe one-time initialization functions + +* Bugs fixed: + 454473 Simple XML Subset Parser terminates on invalid XML + 445813 g_module_open error, add file name + 453796 errno gets clobbered by g_filename_display_name + 341988 don't use "-c" with msgfmt in Makefile.in.in + 447048 Please produce slightly more output during long tests + 454785 GModule documentation lists same block of code twice. + 454786 GModule documentation lists same paragraph twice. + 383155 small docs quirks in gobject/closure API documentation + 65041 _get_type() functions aren't thread safe + +* Updated translations + Assamese (as) + Spanish (es) + Gujarati (gu) + Japanese (ja) + Korean (ko) + Macedonian (mk) + + +Overview of Changes from GLib 2.13.5 to GLib 2.13.6 +=================================================== + +* Reintroduce a GType typedef whose removal in 2.13.5 + caused trouble for C++ bindings + +* Bugs fixed: + 450216 docs not explicit enough about g_free() + 451459 g_type_register_static_simple calls g_type_register_static + +* Updated translations + Norwegian bokmÃ¥l (nb) + Sinhala (si) + + +Overview of Changes from GLib 2.13.4 to GLib 2.13.5 +=================================================== + +* xdg-user-dirs support: + - the Desktop directory is guaranteed to be defined + - user-dirs.dirs is no longer reloaded on changes + +* Slice allocator: + - new api to duplicate slices + +* Regular expression support: + - GRegex is a boxed type now + +* Bugs fixed: + 44793 make check failing in trunk + 354522 Small problem with PLT hiding 6 symbols + 363986 glib 2.12.4 does not compile with SGI IDO cc + 443869 g_type_class_add_private doesn't warn when adding 0-sized... + 446859 Legitimately return 0 for g_quark_from_string(NULL) + 447534 Small typo in g_timeout_add_seconds() doc + 447583 GStaticRWLock + 447935 g_get_current_dir SIGSEGV on long path + 448260 CLAMP has surprising result if low > high + 57693 g_string_vprintf() + 442029 add g_slice_dup() + 445065 Add GRegex boxed type + 448819 Add full version of g_timeout_add_seconds() + +* Updated translations: + Swedish (sv) + Oriya (or) + Hebrew (he) + Spanish (es) + Estonian (et) + + +Overview of Changes from GLib 2.13.3 to GLib 2.13.4 +=================================================== + +* Bugs fixed: + 444121 g_get_user_special_dir deadlocks + 444161 invalid UTF8 in key name shows up as valgrind error in g_... + 444130 g_option_context_get_help() is broken when there's a desc... + + +Overview of Changes from GLib 2.13.2 to GLib 2.13.3 +=================================================== + +* GKeyFile: + - Added defines for easier handling of desktop files + +* Unicode support: + - Update g_unichar_iswide_cjk for Unicode 5.0 + +* Regular expression support: + - GRegex structs can now be ref-counted + - Some new functions for dealing with incremental + replacement have been added + - The GRegexEvalCallback signature has been changed + +* g_get_user_special_dir() has been added to support + xdg-user-dirs + +* Bugs fixed: + 419376 Functions using named subpatterns behave inconsistently w... + 434358 g_regex_fetch_named() and g_regex_fetch_named_pos() are b... + 423708 typo in the README.win32 file see patch below + 339225 Add new defines for easier handling of .desktop files + 442265 API additions/changes for GRegex + 432651 Add a glib-ish xdg_user_dir_lookup + +* Updated translations: + Estonian (et) + Norwegian bokmÃ¥l (nb) + + +Overview of Changes from GLib 2.13.1 to GLib 2.13.2 +=================================================== + +* Unicode support: + - Add g_unichar_ismark() + +* GOption: + - Allow to use callbacks for remaining args + +* Updated translations: + Belarusian Latin (be@latin) + British English (en_GB) + Galician (gl) + Norwegian bokmÃ¥l (nb) + Oriya (or) + Spanish (es) + Thai (th) + + +Overview of Changes from GLib 2.13.0 to GLib 2.13.1 +=================================================== + +* GRegex: + - Portability fixes + - Split into immutable GRegex and GMatchInfo + - Add g_regex_get_max_backref() and g_regex_get_capture_count() + to obtain information about the compiled regex + +* GKeyFile: + - Fix roundtrip problems + - Add g_key_file_load_from_dirs() + +* Unicode support: + - Fix corner cases in case conversion routines + +* GOption: + - Add a function to get the formatted help string + +* GHash: + - Add new functions g_hash_table_get_keys() and + g_hash_table_get_values() to retrieve the keys and + values in list form + +* Updated transations: + Simplified Chinese (zh_CN) + Arabic (ar) + + +Overview of Changes from GLib 2.12 to GLib 2.13.0 +================================================= + +* Add GSequence, a list that is implemented using + a balanced binary tree. + +* Add GRegex, an implementation of Perl regular expressions, + based on PCRE. + +* Use Posix monotonic clocks instead of gettimeofday() + for GTimer when available. + +* Support static initialization of GQeues with G_QUEUE_INIT, + g_queue_init() and g_queue_clear(). + +* Add g_string_chunk_clear() for clearing a + GStringChunk. + +* Add g_unichar_get_script() to obtain Unicode + script information. + +* Add g_unichar_iszerowidth() to obtain information + about zero-width characters. + +* Add G_GNUC_MAY_ALIAS which wraps the gcc may_alias + type attribute. + +* G_GNUC_INTERNAL has a working definition for the + Sun Studio compiler. This requires the macro to + be positioned before the function declaration. + +* The slice allocator can produce detailed debugging + information with G_SLICE=debug-blocks. + +* Modules support G_DEBUG flags resident-modules and + bind-now-modules. + +* Add G_DEFINE_DYNAMIC_TYPE() to make it easier + to define types in modules. + +* Bug fixes: too many to list them in detail here. + +* New and updated translations (be,bg,bn,ca,cs,de, + en_CA,en_GB,et,fa,fr,he,hu,it,ja,ku,lt,mg,mk,ml, + nb,ne,nn,pt,pt_BR,ro,sr,sr@Latn,sv,ta,uk,vi,zh_CN, + zh_HK,zh_TW) + + +Overview of Changes from GLib 2.12.1 to GLib 2.12.2 +=================================================== + +* Unicode updates: + - Normalization is following Unicode TR #29 + - g_unichar_isxdigit() only accept characters + for which g_unichar_xdigit_value() returns a value + - g_unichar_toupper and g_unichar_tolower leave + unconvertable characters in place instead of + replacing them by NUL + +* Bugs fixed + 348491 g_utf8_strup() and g_utf8_strdown() returns + string with NUL bytes + 349825 GKeyFile always inserts a newline before a group + 347842 g_unichar_isxdigit() is too general about what + it considers a digit + 348694 g_utf8_normalize() hasn't been updated to PR #29 + 348785 Hint about G_DEBUG in Message Logging docs + 349792 Wrong english string (UI) + 349952 gparamspecs.c uses gcc feature + +* Translation updates (ca,cs,de,dz,es,eu,fi,gu,ko, + nl,pl,tr,uk,zh_HK,zh_TW) + + +Overview of Changes from GLib 2.12.0 to GLib 2.12.1 +=================================================== + +* Update to final Unicode Character Database 5.0.0 + +* Bugs fixed: + 346660 issues with base64 api documentation / g_base64_decode_cl... + 348136 Coverity reports allocation of wrong size CID #2839 + 336281 Update to UCD 5.0 + 346197 g_date_strftime %F option doesnt work for win32 + 348011 Small optimization to real_toupper() + 246494 prototype mismatch in glib/gconvert.c + +* New and updated translations (bg,bn_IN,ca,dz,eu,fi, + fr,he,it,ja,mk,or,pt) + + +Overview of Changes from GLib 2.11.4 to GLib 2.12 +================================================= + +* Bugs fixed: + 344905 leap-year bug in g_time_val_from_iso8601 w/o HAVE_TIMEGM + +* Updated translations (cy,nb,nl) + + +Overview of Changes from GLib 2.11.3 to GLib 2.11.4 +=================================================== + +* GBookmarkFile: + - g_bookmark_file_remove_item returns a boolean + +* g_mkstemp accepts the XXXXXX in the middle of + the template + +* Bugs fixed: + 344868 g_key_file_to_data should separate groups + +* Updated translations (de,es,fr,gu,hi,ko,th) + + +Overview of Changes from GLib 2.11.2 to GLib 2.11.3 +=================================================== + +* GBookmarkFile: + - g_bookmark_file_move_item: Return TRUE in case of + an empty target + +* Bugs fixed: + 343919 gunicollate.c: strxfrm bug on VC8 + +* Updated translations (fi) + +Overview of Changes from GLib 2.11.1 to GLib 2.11.2 +=================================================== + +* Add g_ascii_stroll to parse signed 64bit integers + +* GMarkup: add a flag to treat CDATA as text + +* GHashTable: add functions to remove all entries + +* GMainLoop: add functions to find the currently + running source, and determine if it is destroyed + +* Bug fixes: + 342563 g_atomic_thread_init() needs to be called before + other _g_*_thread_init() functions + 343548 Potential use after free in callers of g_string_free() + 168538 Wish: Clearing contents of GHashTables + 321886 GTK+ cannot be reliably used in multi-threaded + applications + 341826 goption.c: 'strtoll' is C99's function + 343899 g_ascii_formatd dosn't work as expected for all + format strings + 317793 Make GEnumValue strings const + 337129 Compile warnings in G_IMPLEMENT_INTERFACE + 303622 What is G_TYPE_CHAR? + +* Updated translations (bg,dz,eu,gl,ja,ko,nl,th,vi) + + +Overview of Changes from GLib 2.11.0 to GLib 2.11.1 +=================================================== + +* GOption + - Support 64-bit integers + - Allow optional text before and after the options + in help output + +* Bug fixes: + 340538 gbase64-test writes OOB + 340816 GKeyFile set_string_list invalid memory reads + 339105 g_key_file_parse_value_as_double + 340434 convert-test.c fails (function test_one_half) + 311043 Memory leaks (and potential infinite loops) + when using G_ERRORCHECK_MUTEXES + 335198 Error checking mutexes are fubar + 341237 Add a G_OPTION_ARG_INT64 + 341192 g_io_channel_set_flags not implemented on win32 + 336120 Allow adding description before/after GOption + --help output body + 341191 misplaced check in g_relation_delete + 340530 mismatched calloc / g_free in win32 threads + +* Updated translation (es) + +Overview of Changes from GLib 2.10.x to GLib 2.11.0 +=================================================== + +* GBookmarkFile: a parser for files containing bookmarks + stored using the Desktop Bookmark specification. + +* Base64 encoding support + +* Unicode 5.0 support + +* GOption supports floating point numbers + +* GKeyFile supports floating point numbers + +* Bug fixes: + 155884 gatomic.c should be based on new SDK + 157877 update-desktop-database doesn't handle duplicate entries + 164719 keyfile parser doesn't support floats + 327662 Import BookmarkFile from libegg + 329548 Add G_OPTION_ARG_DOUBLE + 329789 option-test.c type confusion + 332841 Segmentation Fault when %llu is passed to vasnprintf and + HAVE_SNPRINTF is not defined + 333879 gthread/gthread-win32.c: IsDebuggerPresent needs '#define + _WIN32_WINDOWS 0x0401' + 333916 g_timer_elapsed docs should mention that microseconds + may be NULL + 334440 dlerror() portability issue causes crash on (old) a.out + NetBSD platform + 334646 goption + error out params + 334799 g_remove() must check return value of remove() + 334943 make check FAIL: threadpool-test + 335215 Some breakages with GThreadPool + 336085 g_option_context_new parameter lacks better explanation + 336677 Documentation for g_object_ref_sink() is incorrect + 337027 gbookmarkfile.c: sys/time.h include error + 337553 Wrong escaping of URIs + 338572 Dereferencing NULL value in g_key_file_get_group_comment + 338845 g_completion_complete_utf8 crashes when NULL is passed to it + 339337 g_bookmark_file_set_description + 339338 gbookmarkfile.c, function expand_exec_line + 339340 gbookmarkfile.c, function bookmark_app_info_dump + +* Translation updates (bg,en_GB,et,gl,gu,he,hi,ka,nb,nl,nn, + or,pt_BR,ro,tr,vi,zh_CN) + + +Overview of Changes from GLib 2.10.0 to GLib 2.10.1 +=================================================== + +* Bugs fixed: + 314794 Broken pthread detection on Darwin [Gregor Riepl] + 322476 Missing check for .dylib [Vladimir Panov] + 333651 Inconsistent _g_charset_get_aliases prototype [Julio + M. Merino Vidal] + 333761 GInitiallyUnowned breaks application code [Sven Herzberg] + +* Win32 changes: + - Fix g_listenv() implementation. + - Allow up to 100 GPrivate structs + +* Translation updates (fr,hu,lt,pl,sv) + + +Overview of Changes from GLib 2.9.6 to GLib 2.10.0 +================================================== + +* The functions g_snprintf() and g_vsnprintf() have been removed from + the gprintf.h header, since they are already declared in glib.h. This + doesn't break documented use of gprintf.h, but people have been known + to include gprintf.h without including glib.h. + +* The Unicode support has been updated to Unicode 4.1. This adds several + new members to the GUnicodeBreakType enumeration. + +* The support for Solaris threads has been retired. Solaris has provided + POSIX threads for long enough now to have them available on every + Solaris platform. + +* 'make check' has been changed to validate translations by calling + msgfmt with the -c option. As a result, it may fail on systems with + older gettext implementations (GNU gettext < 0.14.1, or Solaris gettext). + 'make check' will also fail on systems where the C compiler does not + support ELF visibility attributes. + +* The GMemChunk API has been deprecated in favour of a new 'slice + allocator'. See the g_slice documentation for more details. + +* A new type, GInitiallyUnowned, has been introduced, which is + intended to serve as a common implementation of the 'floating reference' + concept that is e.g. used by GtkObject. Note that changing the + inheritance hierarchy of a type can cause problems for language + bindings and other code which needs to work closely with the type + system. Therefore, switching to GInitiallyUnowned should be done + carefully. g_object_compat_control() has been added to GLib 2.8.5 + to help with the transition. + +* Bugs fixed: + 328997 64bit pointer trunction in glib slab-allocator + [Pascal Hofstee] + 331110 g_cond_broadcast(inform_cond) without holding + inform_mutex [Chris Wilson, Sebastian Wilhelmi] + 332093 Fix some leaks in the tests [Kjartan Maraas] + 332435 g_utf8_strlen returns wrong value if a maximum + number of bytes to check is specified + [Matthias Clasen] + 331367 gslice requires more POSIX-like semantics for + GPrivate destructors [Tor Lillqvist] + +* Documentation improvements [Matthias, Kang Jeong-Hee, + Tor Lillqvist, Stefan Kost] + +* Translation updates (el,eu,ka,uk) + +Overview of Changes from GLib 2.9.5 to GLib 2.9.6 +================================================= + +* Bugs fixed: + 329124 distclean removes README [Kjartan Maraas, Tim Janik] + 317679 GRelation field type not documented [Behdad Esfahbod] + 329123 Typo in GTime docs [Kjartan Maraas] + +* Documentation improvements [Sven Herzberg, David + Schleef, Kjartan Maraas, Behdad Esfahbod] + +* Translation updates (cs,cy,it,ko,pt,sq,sr,sr@Latn,ru + +Overview of Changes from GLib 2.9.4 to GLib 2.9.5 +================================================= + +* Memory management: + Runtime debugging support: The slice allocator + can be turned off by setting G_SLICE=always-malloc + in the environment. Zeroing of freed memory can + now be turned on at runtime by setting + G_DEBUG=gc-friendly in the environment. [Tim Janik] + +* Bugs fixed: + 328253 HP-UX/IA-64 uses ".so" as default shared library + extension [Albert Chin] + 143380 unicode-encoding test fails converting to UTF-16 + with libiconv [Marc Moorcroft] + 328254 Build breakage (GSlice) [Jens Ganseuer] + 328705 C99ism in glib/gmem.c [Kazuki Iwamoto] + +* Translation updates (da,et,zh_CN) + +Overview of Changes from GLib 2.9.3 to GLib 2.9.4 +================================================= + +* Type system: + Fix a problem with g_object_compat_control() which + can lead to segfaults in GTK+ applications on 64bit + platforms. + +* Thread suppport: + Unused threads now fall back to the global pool after + 500 milliseconds, where they wait for another + max-idle-time milliseconds. [Sebastian Wilhelmi] + +* Fix a memory allocation problem in GKeyFile. [Morten + Welinder] + + +Overview of Changes from GLib 2.9.2 to GLib 2.9.3 +================================================= + +* GTree: + - Replace the simple recursive implementation by + a nonrecursive, threaded one [Maurizio Monge] + +* Change g_filename_display_name and + g_filename_display_basename to use the Unicode + replacement character U+FFFD instead of a question + mark, and don't append "(invalid encoding)" [Matthias] + +* Documentation improvements [Sven Herzberg, Federico + Mena Quintero, Stefan Kost] + +* Bugs fixed: + 323937 gslice.c in glib 2.9.1 doesn't build on Mac OS X + [Bogdan Nicula] + 326558 Some test failures on IRIX 6.5 [Daichi Kawahata] + 169285 "threaded" tree implementation for GTree + [Maurizio Monge] + 326747 g_filename_display_basename adds (invalid encoding) + [Alberto Ruiz] + +Other contributors: Christian Kellner, Murray Cumming + +New and updated translations (bg,ca,de,es,et,gu,ja,nl,th,vi) + + +Overview of Changes from GLib 2.9.1 to GLib 2.9.2 +================================================= + +* Memory management: + - Add tests for cache colorization [Tim Janik] + - Minimize space consumption if small amounts of differently + sized slices are allocated, at a small performance cost. [Tim] + +* Thread support: + - Add g_atomic_pointer_set() and g_atomic_int_set() [Tim Janik, + Sebastian Wilhelmi] + - Add g_thread_pool_set_sort_function() to allow sorting the + tasks of a threadpool. [Martyn Russell] + - Add g_thread_pool_set_idle_time() to allow unused threads + to exit after a certain time. [Martyn] + +* Type system: + - introduce a new type GInitiallyUnowned, which has an initial + floating reference. [Tim] + - Add support for GType parameters. [Matthias] + +* Main loop: + - Add g_main_context_is_owner() to determine if the current + thread is the owner of the context. [Michael Meeks] + +* Provide g_access(), g_chdir(), g_unlink(), g_rmdir() as + wrapper functions instead of macros. [Manish Singh] + +* Documentation improvements [Tim, Matthias, Federico Mena Quintero, + Stefan Kasal, Dan Williams] + +* New and updated translations (en_CA,fi,fr,gl,ml,nb,no,zh_HK,zh_TW) + +* Bugs fixed: + 324179 g_allocator_new() returns pointer to const dummy which Gtk+ 2.8 + tries to modify [J. Ali Harlow] + 324332 g_option_context_parse() returns false without setting error + [Tim-Philipp Müller] + 324950 GLIB 2.9.1 testcase errors [Dan Yefimov] + 325015 gslice.c: process.h is needed on Windows [Kazuki Iwamoto] + 321978 G_DATALIST_GET_FLAGS() macro is not casting datalist to + gpointer [Andrew Paprocki] + 316221 G_LOCK warns about breaking strict-aliasing [Michal Benes, + Stanislav Brabec] + 325273 Error in documentation for glib_check_version () [Declan Naughton] + 325310 g_spawn_sync hangs when catching both stdout and + stderr [Tor Lillqvist] + 325249 gcc warning when using g_rmdir from [Jani Monoses] + 325864 glib/gthreadpool.c:"#define debug(...)" is C99 [Kazuki Iwamoto] + 325874 Should say somewhere that source IDs are > 0 [Dan Williams] + 325438 a typo (compatability) [Stefan Kasal] + 323937 gslice.c in glib 2.9.1 doesn't build on Mac OS X [Bogdan Nicula] + + +Overview of Changes from GLib 2.9.0 to GLib 2.9.1 +================================================= + +* Memory management + - The slice allocator is implemented [Tim Janik] + - g_slice_free_chain() has been renamed to + g_slice_free_chain_with_offset() [Tim, Behdad Esfahbod] + - Mem chunks are deprecated [Matthias Clasen] + +* Data structures + - Hash tables are refcounted, and have a boxed type [Tim] + +* Thread support + - Support for Solaris threads has been removed + [Sebastian Wilhelmi, Andrew Paprocki] + - g_async_queue_sort(), g_async_queue_push_sorted() have + been added to allow GAsyncQueue to be used as a priority + queue, together with the corresponding _unlocked + variants [Martyn Russell] + +* GObject: + - The concept of a floating initial reference has been + moved from GtkObject to GObject [Tim] + +* Win32 changes: + - Make g_rename() replace existing files [Tor Lillqvist] + +* Misc new API: + - G_GUINT64_CONSTANT macro to define guint64 + constants [Andrew Paprocki] + - G_GNUC_WARN_UNUSED_RESULT macro to instruct the + compiler to emit a warning if the value returned + by a function is ignored. [Arjan van de Ven, Alex Larsson] + - GList and GSList now have sort functions which take an + extra user data argument [Martyn Russell] + - g_param_spec_ref_sink() has been added for consistency [Tim] + +* $LOGNAME is respected when determining user data. [Laszlo Peter] + +* Other changes and bug fixes [Tim, Matthias, Behdad, + Christian Persch, Benedikt Meurer, Andrew Paprocki, + Kazuki Iwamoto, Alexis S. L. Carvalho, Stanislav Brabec, + Andreas Schwab, Kalle Vahlman] + +* Documentation + - Deprecation warnings carry version information [Matthias] + - The slice allocator has been documented [Matthias, Tim] + - Other improvements [Morten Welinder] + +Overview of Changes from GLib 2.8.x to GLib 2.9.0 +================================================= +* Unicode support: + - The Unicode tables have been updated to Unicode 4.1, + adding several new values to the GUnicodeBreakType + enumeration. This breaks Pango <= 1.10 + [Behdad Esfahbod] + - The various Unicode character predicate functions + (g_unichar_isalpha, g_unichar_isdigit,...) have + been optimized + [Behdad] + - g_utf8_pointer_to_offset, g_utf8_offset_to_pointer: + These functions handle negative offsets now, and + going backwards in g_utf8_offset_to_pointer uses + "stutter stepping". + [Larry Ewing, Matthias Clasen] + +* Memory management: + - Mem chunks are no longer used internally in GLib and + GObject. GMemChunk will be deprecated in GLib 2.10 + - All APIs based on GAllocator (g_list_push/pop_allocator, + and similar push/pop_allocator functions for other + data structures) have been deprecated, since they + never worked as intended. + - The g_slice_* functions have been added as a + new API for fast allocation of small memory blocks. + The implementation in GLib 2.9.0 is just a simple + wrapper around malloc. GLib 2.10 will have an + efficient and scalable implementation. + [Tim Janik, Matthias] + +* Pattern matching: + - g_pattern_match has been optimized to avoid + unnecessary recursion. + [Tim, Matthias] + +* g_intern_string, g_intern_static_string: + - New functions to intern strings. These are now used + by GObject to avoid duplicating static strings + [Matthias] + +* g_thread_foreach: + - New function to iterate over all GThreads + [Tim, Matthias] + +* g_date_set_time_t, g_date_set_time_val: + - New functions to set a GDate from a time_t or + GTimeVal value. g_date_set_time has been deprecated + in favor of these. + [Roger Leigh] + +* g_snprintf and g_vsnprintf: + - These functions are no longer declared in gprintf.h, + since they are in glib.h + [Matthias] + +Overview of Changes from GLib 2.8.0 to GLib 2.8.1 +================================================= +* Optimize single-character insertions in GString [Ross Burton] +* Fix build problems on OS X +* Fix build problems on Win32 [Tor Lillqvist, Hans Breuer] +* Other bug fixes [Matthew F. Barnes, Stepan Kasal] +* Documentation improvements [Tristan van Berkom, Behnam + Esfahbod, Gustavo Carneiro, Stepan Kasal, Matthias] +* New and updated translations (ca,cy,ko,ro,uk) + +Overview of Changes from GLib 2.7.7 to GLib 2.8.0 +================================================= +* Make g_value_transform() handle enum values + correctly on ppc64. [Michael Lorenz] + (Third-party code accessing enumeration values + in GValues should also be changed to access + v_long, not v_int, in order to work on bigendian + 64bit machines.) +* Make g_flags_get_first_value() handle a value + of 0 meaningfully. [Tim-Philipp Müller] + +Overview of Changes from GLib 2.7.6 to GLib 2.7.7 +================================================= +* Make atomic operations on s390 work [Matthias] +* Fix C++ guards in gstdio.h [Tor Lillqvist] + +Overview of Changes from GLib 2.7.5 to GLib 2.7.6 +================================================= +* Add native implementations of atomic operations + on s390 [Matthias] +* Make atomic reference counting of closures + work on s390 [Matthias] +* Avoid an infinite loop in g_convert_with_iconv(). + [Sebastian Bacher] +* Documentation improvements [Ross Burton] + +Overview of Changes from GLib 2.7.4 to GLib 2.7.5 +================================================= +* Thread-related changes + - Fix build issues on HP-UX [Paul Cornett] + - Threadsafe access to flags stored in datasets [Tim Janik] + - Fix several issues with atomic refcounting for + closures, objects and paramspecs [Tim] + - Improve tests for atomic refcounting changes [Tim] +* Fix handling of stateful encodings in g_convert_* [Matthias] +* Fix translation of GOption help output [Dan Winship] +* Catch format errors in translations. This may cause + "make check" to fail when using older versions + of gettext [Matthias] +* Win32 bug fixes [Tor Lillqvist] +* Documentation improvements [Ross Burton, Jochen Baier, + Matthias, Tim] +* New and updated translations (de,fi,gu,pl,pt,tr,zh_TW) + +Overview of Changes from GLib 2.7.3 to GLib 2.7.4 +================================================= +* Fix g_atomic_pointer_compare_and_exchange + on Sparc64 [Gert Doering] +* Fix a hang in g_thread_pool_free. [Hong Jen Yee] +* Win32 bug fixes [Tor Lillquist] +* Other bug fixes [Benoit Dejean, Manish Singh] +* Documentation improvements [Bryan Silverthorn, + Callum McKenzie] +* New and updated translations (de,lt,sq,zh_CN) + +Overview of Changes from GLib 2.7.2 to GLib 2.7.3 +================================================= +* GOption + - Allow callbacks with optional arguments [Pawel Sliwowski] + - Allow to turn off the automatic long option name + disambiguation [Adam McLaurin] + - Only allow printable ASCII as short option names [Matthias] +* Win32 + - Build fixes [Tor Lillqvist] + - Rewrite iochannel socket implementation [Tor] +* GObject + - Threadsafety improvements; in particular, refcounting + of objects is done atomically now. [Wim Taymans, Tim Janik] +* Bug fixes [Morten Welinder, Matthias, Wim Taymans] +* Documentation improvements [Richard Laager, Matthias] +* New and improved translations (bf,cs,hu,nb,nl,no) + +Overview of Changes from GLib 2.7.1 to GLib 2.7.2 +================================================= +* Win32 build fixes [Hans Breuer] +* Bug fixes [Mikael Magnusson] +* Documentation improvements [Matthias Clasen] +* New and updated translations (en_CA,es,et,ja,sr,sr@Latn,zh_TW) + +Overview of Changes from GLib 2.7.0 to GLib 2.7.1 +================================================= +* GOption + - Allow callback arguments without parameters [Dan Winship] +* GMappedFile: an mmap wrapper [David Schleef, Behdad Esfahbod] +* Misc new functions: + - g_get_host_name [Tor Lillqvist] + - g_mkdir_with_parents [Tor] + - g_build_pathv, g_build_filenamev [Todd A. Fisher, + Matthias Clasen] +* Bug fixes [Roger Leigh, Masatake YAMATO, Kjartan Maraas, + Manish Singh, Tor, Murray Cumming, Kian Duffy, Morten Welinder] +* Documentation improvements [Hong Gang XU, Dan Winship, Matthias] +* New and updated translations (bg,cs,da,en_CA,es,et,nb,nl,no, + sk,th,zh_TW) + +Overview of Changes from GLib 2.6.x to GLib 2.7.0 +================================================= +* GKeyFile + - Add unit tests [Matthias Clasen, Suren A. Chilingaryan] + - Accept \r\n as line end [Bastian Nocera] + - Don't interpret leading zeros as octal numbers. [Matthias] + - Make key and group removal work [David Hoover, Matthias Hasselmann] +* GOption + - Improve formatting of --help output [Matthias, Noah Levitt] + - Accept -? [Matthias] + - Warn about duplicate main groups [Jeff Franks] + - Treat '-' as non-option argument [Tim Musson, Thomas Leonard] + - Report missing arguments as errors [Björn Lindqvist] + - Add a boxed type for GDate [Tim-Philipp Müller] +* GTree + - g_tree_remove() and g_tree_steal() return status information [Matthew F. Barnes] +* Stdio wrappers + - Work regardless of large file support [Manish Singh] + - Add g_access(), g_chmod(), g_creat(), g_chdir [Tor Lillqvist] +* GObject + - Implement "toggle references" to help language bindings [Owen Taylor] + - Allow to mark names, nicks and blurbs of pspecs as static [Ben Maurer, Matthias] + - Make pspec lookup a bit faster [Morten Welinder] +* Add g_listenv() to list all set environment variables [Hans Petter Jansson] +* Add g_file_set_contents() to atomically write a file. [Søren Sandmann, + Sven Neumann, Manish, Alexis S. L. Carvalho] +* Add g_try_malloc(), g_try_new(), g_try_new0() and g_try_renew() [Stefan Kost] +* Add g_utf8_collate_key_for_filename() to sort filenames taking + extensions and numeric suffixes into account. [Ole Laursen, Alex Larsson] +* Add G_GNUC_NULL_TERMINATED to mark varargs function with + NULL-terminated argument lists. [Marc Meissner] +* Win32 changes + - Improved debugability [Ulf Lamping, Hans Breuer] + - Make filename handling more robust [Tor, Billy Skaggs] + - Improve g_get_system_data_dirs() [Tor] + - Use more precise timers [Tor] + - Build fixes [Kazuki Iwamoto, Hans, Tor, Robert Ögren] +* Other bug fixes [Roger Leigh, Owen, Matthias, Morten, Kjartan Maraas, + Pawel Sakowski, Tor, Simon Budig, Ed Avis, Manish, Nicolas Laurent, + Bastien, Fabrício Barros Cabral, Michael Banck, Daniel Atallah, + J. Ali Harlow, Tim Janik, Hazael Maldonado Torres, Sven, Jon-Kare Hellan, + Dave Benson, Tommi Komulainen, Benjamin Otte, Brian Cameron, Changwoo Ryu, + Christian Biere, Noah, Benoît Carpentier] +* Documentation improvements [Vincent Untz, Matthias, Tim-Philipp Müller, + Morten, Matthew, Federico Mena Quintero, Sebastian Bacher, Oliver Sessink, + Stefan, Jared Lash, Tor, Owen, Daniel Vaillard, Mathieu Lacage] +* New and updated translations (ca,cs,da,el,en_CA,en_GB,es,et,eu,fa,fr,gl, + hu,id,it,lt,mn,ne,nl,pl,pt,pt_BR,ro,rw,sk,sq,sr,sr@Latn,tl,uk,xh,zh_CN) + +Overview of Changes from GLib 2.6.0 to GLib 2.6.1 +================================================= +* GOption + - Make gtk_init(NULL, NULL) work again [Marcin Krzyzanowski] + - Improve handling of -- [Matthias Clasen] + - Don't show G_OPTION_REMAINING in --help output [Matthew F. Barnes] +* g_find_program_in_path() doesn't return directories [Tommi Komulainen] +* Add gmodule-export-2.0.pc [Matthias] +* Win32 changes + - Improve hangling of UNC paths [Tor Lillqvist] + - g_getenv(), g_setenv(), g_unsetenv(), g_find_program_in_path() + take and return UTF-8 now [Tor] + - Make g_file_test() work more reliably, and use PATHEXT + when check for executables [Tor] + - Build and cross-compilation fixes [J. Ali Harlow] +* Other bug fixes [Jens Hatlak, Morten Welinder, + Tor, Kalpesh Shah, Adrian Bunk] +* Documentation improvements [Marcin Krzyzanowski, Tor, Crispin + Flowerday, Mariano Suárez-Alvarez, Christian Biere, Danny Milo, + Vincent Untz, Bastien Nocera] +* New and updated translations (cy,de,nl,ru,sq,sv) + +Overview of Changes from GLib 2.4.x to GLib 2.6.0 +================================================= + +* GLib 2.6 introduces the concept of 'GLib filename encoding', which is the + on-disk encoding on Unix, but UTF-8 on Windows. All GLib functions + returning or accepting pathnames have been changed to expect + filenames in this encoding, and the common POSIX functions dealing + with pathnames have been wrapped. These wrappers are declared in the + header which must be included explicitly; it is not + included through . + + On current (NT-based) Windows versions, where the on-disk file names + are Unicode, these wrappers use the wide-character API in the C + library. Thus applications can handle file names containing any + Unicode characters through GLib's own API and its POSIX wrappers, + not just file names restricted to characters in the system codepage. + + To keep binary compatibility with applications compiled against + older versions of GLib, the Windows DLL still provides entry points + with the old semantics using the old names, and applications + compiled against GLib 2.6 will actually use new names for the + functions. This is transparent to the programmer. + + When compiling against GLib 2.6, applications intended to be + portable to Windows must take the UTF-8 file name encoding into + consideration, and use the gstdio wrappers to access files whose + names have been constructed from strings returned from GLib. + +* Likewise, g_get_user_name() and g_get_real_name() have been changed + to return UTF-8 on Windows, while keeping the old semantics for + applications compiled against older versions of GLib. + +* The GLib uses an '_' prefix to indicate private symbols that + must not be used by applications. On some platforms, symbols beginning + with prefixes such as _g will be exported from the library, on others not. + In no case can applications use these private symbols. In addition to that, + GLib+ 2.6 makes several symbols private which were not in any installed + header files and were never intended to be exported. + +* To reduce code size and improve efficiency, GLib, when compiled + with the GNU toolchain, has separate internal and external entry + points for exported functions. The internal names, which begin with + IA__, may be seen when debugging a GLib program. + +* On Windows, GLib no longer opens a console window when printing + warning messages if stdout or stderr are invalid, as they are in + "Windows subsystem" (GUI) applications. Simply redirect stdout or + stderr if you need to see them. + +* The child watch functionality tends to reveal a bug in many + thread implementations (in particular the older LinuxThreads + implementation on Linux) where it's not possible to call waitpid() + for a child created in a different thread. For this reason, for + maximum portability, you should structure your code to fork all + child processes that you want to wait for from the main thread. + +* A problem was recently discovered with g_signal_connect_object(); + it doesn't actually disconnect the signal handler once the object being + connected to dies, just disables it. See the API docs for the function + for further details and the correct workaround that will continue to + work with future versions of GLib. + +* Major new APIs + - GOption, a commandline option parser + - GKeyFile, a parser/editor for the .ini like files + - Functions to support the XDG basedir specification + - Wrappers for common POSIX pathname functions to handle filename + encodings consistently. On Windows, these use UTF-8. + +* Miscellaneous new functions + - g_filename_display_name() converts filenames in displayable UTF-8 strings + - g_uri_list_extract_uris() splits uri lists + - g_date_get_iso8601_week_of_year() gets ISO 8601 week numbers + - g_log_set_default_handler() installs an alternate default log handler + - g_get_language_names() obtains a list of applicable locale names + - g_strv_length() calculates the length of NULL-terminated string arrays + - g_win32_get_windows_version() determines the Windows version + - G_GNUC_INTERNAL marks functions as non-exported + - glib_check_version() checks the GLib version at runtime + - g_debug() completes the family of logging functions + +* Performance improvements + - Optimize g_utf8_validate() + - Optimize g_markup_parse_context_parse() + - Reduce signal connection complexity from O(n) to O(1) + - Get rid of many PLT entries for internally used exported symbols + - Reduce code size by removing literal strings from g_return_if_fail() + +* Other changes + - On Windows, GLib functions that take file name arguments now require + those to be in UTF-8. Functions that return file names return UTF-8. + - Use higher precision for mathematical constants + - Don't convert to/from UTF-8 in g_filename_to_uri/g_filename_from_uri + - Support ll as printf format modifier for long long on all platforms + - Clean up the ABI and enforce the list of exported symbols + - Add a .pc file for using gmodule in libraries + - Require ngettext + +Overview of Changes from GLib 2.5.7 to GLib 2.6.0 +================================================= +* GOption: Don't list help options if group-specific + options have been requested [Glynn Foster] +* Make g_get_language_names() track locale changes [Christian Persch] +* Win32 bug fixes [Tor Lillqvist] +* Bug fixes [Philippe Blain, Owen Taylor, Sebastian Wilhelmi] +* New and updated translations (da,es,ja,lt,zh_CN) +Bugs fixed: 159530,100697,160271,160645,157255 + +Overview of Changes from GLib 2.5.6 to GLib 2.5.7 +================================================= +* Optimize g_utf8_validate() [Owen Taylor, Matthias Clasen] +* Optimize g_markup_parse_context_parse() [Havoc Pennington, + Morten Welinder] +* Reduce signal connection complexity from O(n) to O(1) + [Sven Neumann] +* Add a .pc file for using gmodule in libraries [Owen] +* Add G_GNUC_MALLOC to mark functions returning newly + allocated memory [Matthias] +* Win32 bug fixes [Hans Breuer, Tor Lillqvist, Robert Ögren, + Bruce Hochstetler] +* Bug fixes [Kazuki IWAMOTO, Matthias, Manish Singh, Morten, + Frederic Crozat, Tor] +* Documentation improvements [Matthias, Tor, Owen] +* New and updated translations (cs,da,de,en_CA,en_GB,es,nb,nl,sq,zh_CN) + +Overview of Changes from GLib 2.5.5 to GLib 2.5.6 +================================================= +* GOption + - Add G_OPTION_FLAG_REVERSE to allow options + which unset a boolean variable [Tor Lillqvist] +* GChildWatch + - Use sigaction instead of signal [Jonas Jonnson, + Archana Shah] + - Make the very first SIGCHLD work [Gustavo Carneiro] +* Bug fixes [Morten Welinder, Tor, David MacLachlan, + Manish Singh, J. Ali Harlow] +* Documentation improvements [Matthias Clasen, Tor] +* Updated translations (da,ja,tr,zh_CN) + +Overview of Changes from GLib 2.5.4 to GLib 2.5.5 +================================================= +* GKeyFile + - Cleanups, add more error checking [Ray Strode] + - Fall back to the untranslated string when getting + locale strings [Mark McLoughlin] +* GOption + - Document GOption [Matthias Clasen] + - Better support for rest arguments [Owen Taylor, Matthias] + - Handle conflicts between groups [Matthias] +* Add g_lstat() to the stdio wrappers [Tor Lillqvist] +* Add g_filename_display_name() to convert filenames + in displayable UTF-8 strings [Alex Larsson, Matthias] +* Win32 bug fixes [Kazuki IWAMOTO, Hans Breuer, Tor] +* Bug fixes [Christophe Fergeau, Morten Welinder, + Owen, Kjartan Maraas, Mark] +* Documentation improvements [Matthias, Tor] + +Overview of Changes from GLib 2.5.3 to GLib 2.5.4 +================================================= +Add GKeyFile, a parser/editor for the .ini like files used in various + freedesktop.org specifications. [Ray Strode] +Make the handling of filename encodings consistent across all + GLib functions, introduce wrappers for common POSIX + functions which accept the same filename encoding. [Tor Lillqvist, + Owen Taylor] +GOption + - Rename g_context_option_error_quark() to a more language-binding + friendly name [Murray Cumming] + - Accept backslashes in filenames on Win32 [Tor Lillqvist] +* Strip the internal aliasing prefix IA__ from function names in + assertions [Matthias Clasen] +* Add a function to split uri lists. [Matthias] +* Win32 bug fixes + - Don't open console windows [Tor] +* Other bug fixes [Philippe Blain, Robert Ögren, Hidetaka Iwai, Matthias, + Morten Welinder, Mats-Ola Persson, Tor, Nickolay V. Shmyrev, Kjartan Maraas, + Anders Carlsson, Tim-Philipp Müller, Lucas Rocha, Andrea Campi, Manish + Singh, Thomas Fitzsimmons, Kazuki IWAMOTO] +* Documentation improvements [Matthias, Linus Walleij, Nickolay, Philippe, + Adam Hooper, Gustavo Carneiro] +* New and updated translations (cs,en_CA,en_GB,ja,nb,nl,or,sr,sr@Latn,sq) + +Overview of Changes from GLib 2.5.2 to GLib 2.5.3 +================================================= +* GOption + - set the program name from argv[0] [Masatake YAMATO] + - make contexts work without a main group [Anders Carlsson] +* Performance + - Get rid of many PLT entries for internally used exported symbols, + and clean up the ABI at the same time and make make check check the + list of exported symbols. [Matthias Clasen] +* Add API to get ISO 8601 week numbers [Niklas Lundell] +* Add API to install an alternate default log handler [Darin Adler] +* Add API to obtain a list of applicable locale names [Hidetoshi Tajima] +* Reduce code size bloat by removing literal strings from + the g_return_if_fail() macros [Owen Taylor] +* Add g_strv_length [Tim-Philipp Müller] +* Win32 changes + - Add API to determine the Windows version [Tor Lillqvist] +* Other bug fixes [Stepan Kasal, Anders, Tor, Kazuki Iwamoto, + Manish Singh] +* Documentation improvements [Morten Welinder, Matthias] +* New and updated translations (es,nn,ro) + +Overview of Changes from GLib 2.5.1 to GLib 2.5.2 +================================================= +* Add G_GNUC_INTERNAL macro [Arjan van de Ven] +* Add GOption, a commandline option parser [Anders Carlsson] +* Add glib_check_version [Michael Natterer] +* Add XDG basedir API [Ray Strode] +* Require ngettext [Danilo Segan] +* Bug fixes [Manish Singh, Ray Strode, Vincent Noel, + Jon-Kare Hellan, Jody Goldberg] +* Win32 bug fixes [Tor Lillqvist, Hans Breuer, Peter Zelezny] +* Documentation improvements [Matthias Clasen, Vincent Untz, Christian Persch] +* New and updated translations (bs,eu,fi,gu,ne,pa) + +Overview of Changes from GLib 2.5.0 to GLib 2.5.1 +================================================= + +* Bug fixes [Oliver Guntermann, Sven Neumann, James + Henstridge, Hiroyuki Ikezoe, Matthias Clasen, Robert + Ögren, Tommi Komulainen] +* Documentation improvements [Soeren Sandmann, + Christophe Fergeau, Danek Duvall] +* New and updated translations (eu,hi) + +Overview of Changes from GLib 2.4.1 to GLib 2.5.0 +================================================= + +* New functions g_debug [Sven Herzberg] +* Use higher precision for mathematical constants [Morten + Welinder] +* Don't convert to/from UTF-8 in g_filename_{to,from}_uri + [Federico Mena Quintero] +* Win32 + - Handle empty digit string in printf() functions + correctly [Tor Lillqvist] + - Support ll as format modifier for long long [Tor] + - Be more careful about HOME [Tor, Ivan Wong] + - Bug fixes [John Ehresman] +* Miscellaneous bug and portability fixes [Danilo Segan, + Owen Taylor, Nikolai Weibull, Benoît Carpentier, Morten + Welinder, Manish Singh, Sven Neumann, Julio M. Merino Vidal, + Kaz Sasayama, Murray Cumming, Federico, Mariano Suarez-Alvarez] +* Documentation updates [Matthias Clasen, Crispin Flowerday, + Tommi Komulainen, Federico Mena Quintero, Ed Griffiths] +* New and updated translations (ja,ne,no,wa) + +Overview of Changes from GLib 2.4.0 to GLib 2.4.1 +================================================= + +* Win32 bug fixes [Tor Lillqvist, Roger Leigh, John Ehresman] +* Miscellaneous bug and portability fixes [Owen Taylor, + Matthias Clasen, Jonas Jonsson, Christian Krause, + Nickolay V. Shmyrev, Christophe Saout, Philippe Blain, + Piotr Klaban] +* Documentation updates [Matthias] +* New and updated translations (ca,cs,cy,el,en_CA,en_GB,es,eu,fi, + fr,gu,he,id,nl,pt,pl,ru,sr,sr@ije,sr@Latn,sv,uk) + +Overview of Changes from GLib 2.3.6 to GLib 2.4.0 +================================================= + +* Handle invalid-UTF-8 in g_log() properly [Matthias Clasen] +* Win32 bug fixes [Tor Lillqvist, Bruce Hochstetler] +* Miscellaneous bug and portability fixes [Olivier Biot, David L. Cooper II, + Kjartan Maraas, Frédéric L. W. Meunier, Christof Petig, Manish Singh, + Sebastian Wilhelmi] +* Documentation updates [Owen] +* Updated translations (hr,ro) + +Overview of Changes from GLib 2.3.5 to GLib 2.3.6 +================================================= + +* GAtomic bug fixes [Sebastian Wilhelmi, Mark McLoughlin] +* GMain threading fixes and improvements [Sebastian] +* Win32 [Tor Lillqvist] + - restore some symbols extraneously exported from gobject to maintain ABI compatibility + - Misc build improvements and fixes [Tor, Cedric Gustin, Hans Breuer] +* Documentation updates [Sebastian, Takeshi AIHANA, Matthias, Sven Herzberg] +* New and updated translations (be,es,fi,ga,pa,sr@ije,zh_CN) + +Overview of Changes from GLib 2.3.3 to GLib 2.3.5 +================================================= + +* Make glib-mkenums parse initializers with macros. [Matthias Clasen, muppet] +* Respect locale era in g_date_set_parse(). [Theppitak Karoonboonyanan] +* Add atomic operations and use it for the async queue and + gonce implementation. [Sebastian Wilhelmi] +* Documentation improvements [Sebastian, Matthias, Sven Herzberg] +* Add g_main_depth() for finding the recursion depth of the main + loop [Owen Taylor, Tim Janik, Stefan Westerfeld] +* Add g_spawn_close_pid(), needed on win32 [J. Ali] +* Win32 fixes. [Hans Breuer, J. Ali Harlow] +* Misc bugfixes [Sebastian, Matthias, Balazs Scheidler, Owen] +* Updated translations (cy,et,ga,sq) + +Overview of Changes from GLib 2.3.2 to GLib 2.3.3 +================================================= + +* Add a native AIX gmodule implementation. [Laurent Vivier] +* Add g_node_copy_deep(). [James M. Cape, Matthias Clasen] +* Extend GQueue API to match the GList API. [Soeren Sandmann] +* Add g_hash_table_find(). [Tim Janik] +* Add a G_MODULE_BIND_LOCAL flag. [David Schleef] +* Inline g_string_append_c() when possible. [Owen Taylor, Tim] +* Wrap waitpid() as a GSource. [Jonathan R. Blandford] +* Add g_completion_complete_utf8(). [Theppitak Karoonboonyanan, + Matthias] +* Add g_strsplit_set(). [Soeren] +* Documentation improvements. [Vincent Untz, Sebastian Wilhelmi, + Soeren, Matthias] +* Win32 build fixes. [Tor Lillqvist] +* Misc bugfixes [Manish Singh, Noah Levitt, Simon Josefsson, + Morten Welinder, Damien Carbery, Julio M. Merino Vidal, Sebastian, + Matthias] +* Updated translations (nn,cs,it,ko,sq,ms,az,hr,uk,sr,sr@Latn,sq,ta) + +Overview of Changes from GLib 2.3.1 to GLib 2.3.2 +================================================= + +* Add G_MAXSIZE. [Manish Singh] +* Add g_rand_new_with_seed_array(), g_rand_set_seed_array(), + implementing the init-by-array functionality of the + original mersenne twister. Add g_rand_copy(). Improve seeding. + [George Lebl] +* Add a lowercase_name option to glib-mkenums. [Murray Cumming] +* Add g_ptr_array_foreach(). [Matthias Clasen] +* Add g_timer_continue(). [Tim-Philipp Müller] +* Fix a threadsafety issue in mem chunks. [Matthias, Balazs Scheidler] +* Fix g_filename_{to,from}_utf8() on Win32 and improve + g_file_test() there too [Hans Breuer] +* Add a boxed type for NULL-terminated string arrays. [Matthias] +* Add G_DEFINE_TYPE() plus variants to ease the constuction + of GObject boilerplate code. [Tim Janik] +* Support & in password GECOS field [Matthias, Soeren Boll Overgaard] +* Documentation improvements [Matthias, Manish] +* Win32 build fixes [Hans] +* Misc bug fixes [Damien Carbery, Matthias, Manish, Olivier Poncet, + Zack Rusin] +* Updated translations (ar,de,fa,ga,mn,nn,no,sq) + +Overview of Changes from GLib 2.3.0 to GLib-2.3.1 +================================================= + +* Add glib/gi18n.h and glib/gi18n-lib.h for common + gettext support, including a Q_() macro for translation + with context [Matthias Clasen] +* Add a more flexible G_FILENAME_ENCODING variable + as a replacement for G_BROKEN_FILENAMES [Matthias] +* Fix the return value g_main_context_iterate() for + newly ready sources [Padraig O'Briain] +* Handle Hangul composition for normalization [Noah Levitt] +* Add G_{MIN,MAX,MAXU}INT{8,16,32}. [Mark Jones, Matthias] +* Add G_GSIZE_FORMAT/G_SSIZE_FORMAT [Manish Singh] +* Add G_STRFUNC as a portable wrapper for __func__ [Tim Janik] +* Documentation improvements [Matthias] +* GObject [Tim Janik] + - Support '-' in g_signal_connect()/disconnect() names + like 'swapped-signal'. + - Add g_type_class_peek_static() and use to optimize + g_object_new() for static types [Tim] + - Allow setting construct-only properties from within + init() implementations + - Enforce readability/writeability in g_object_set/get() +* Fix bug with g_ascii_strtod and multi-byte separator. + [Behdad Esfahbod, Roozbeh Pournader] +* Misc bug fixes [Matthias, John Ehresman, Andrew Lanoix, + Tor Lillqvist, Mark McLoughlin, Tim-Philipp Müller, Manish, + Morten Welinder] +* Updated translations (ca,cs,da,es,fr,ja,nn,no,pt,ru) + +Overview of Changes from GLib 2.2.x to GLib-2.3.0 +================================================= + +* Replace Trio printf by gnulib vasnprintf [Matthias Clasen] +* Update Unicode data to Unicode 4.0 [Noah Levitt] +* Support XML-safe formatted output with + g_markup_[v]printf_escaped [Owen Taylor] +* Add g_file_read_link to read symbolic links [Matthias] +* Add g_unichar_get_mirror_char to obtain the + mirrored variant of a character [Noah] +* Support for one-time initialization functions. + [Sebastian Wilhelmi] +* Miscellaneous API additions: g_vasprintf + g_string_chunk_insert_len, g_setenv, g_unsetenv [Matthias] +* Docs improvements [Matthias] +* Add support instance-private data on classed types + [Mark McLoughlin, Tim Janik, Owen] +* Optimize signal emissions [Soeren Sandmann, Tim] +* Support a "default vtable" per interface [Tim] +* Add support for properties on interfaces [Owen, Tim] +* Miscellaneous API additions: g_value_take_string(), + g_value_take_param(), g_value_take_object(), + g_value_take_boxed(). [Matthias] +* Win32 build fixes [Tor Lillqvist] + +Overview of Changes from GLib 2.1.5 to GLib-2.2.0 +================================================= + +* Fix a problem with g_thread_init() on 64-bit problems + [Alceste Scalas, Sebastian Wilhelmi] +* Add assembly implementations of byteswap macros + for ia64 and x86_64. [Manish Singh] +* IOChannel fixes for Win32 [Tor Lillqvist, Thorsten Maerz] +* Updated translations (bg,ca,es,da,fi,lv,ru,sk) + +Overview of Changes from GLib 2.1.4 to GLib-2.1.5 +================================================= + +* Win32 bug fixes [Tor Lillqvist] +* Various post-rewrite fixes for glib-gettext.m4 [Owen Taylor, + Jody Goldberg, Kjartan Maraas, Johannes Stezenbach] +* Ensure we have a GUINT64_FORMAT by pulling in Trio + if necessary [Manish Singh] +* Further Trio build fixes [Matthias Clasen, Owen] +* Hack around gcc, libtool issues with -pthread [Owen] +* Docs improvements [Matthias] +* Bug and portability fixes +* Updated and new translations (bg,de,fi,fr,sq,fr) + +Other contributors: Kai Poitschke, Morten Welinder + +Overview of Changes from GLib 2.1.3 to GLib-2.1.4 +================================================= + +* autoconf changes to make it possible to cross compile + GLib. [Owen Taylor, Dan Kegel, Amy Lin, Dimi Shahbaz, + Johannes Stezenbach] +* Use libintl when it has bind_textdomain_codeset() and + GLib doesn't. [Owen] +* Improve generation of pseudo-random integers [Morten Welinder, + Sebastian Wilhelmi] +* Avoid literal UTF-8 in favor of octal escapes [Owen, Tomas Ogren] +* Cleanup include order [Sven Neumann] +* autoconf cleanups and bug fixes [Daniel, Matthias Clasen, Owen] +* Doc fixes and additions [Matthias] + +Other contributors: James M. Cape, Frederic Crozat, Martin Gansser, + Phuc LeHong, Manish Singh, Joshua Weage, Morten Welinder + +Overview of Changes from GLib 2.0.x to GLib-2.1.x +================================================= + +* Add copy of the Trio library to build and use for printf() when + system printf isn't good enough. Add g_printf()/etc. [Matthias Clasen] +* Add g_str_has_suffix()/g_str_has_prefix() [Alex Larsson] +* Add g_markup_parse_context_get_element() [Matthias] +* Add g_utf8_strreverse [Matthias] +* Add g_ascii_strtoull() [Tim Janik] +* Support scanning of 64-bit values with GScanner [Tim] +* Add g_set/get_application_name() [Havoc Pennington] +* Add G_LIKELY()/G_UNLIKELY() macros for hinting branch probabilities. + Use for g_return_if_fail(). [Matthias Clasen] +* Add G_GNUC_DEPRECATED macro [Tom Tromey] +* Improve the seeding algorithm of GRandom to avoid problems + with certain pathological seeds. Support G_RANDOM_VERSION=2.0 + environment variable. [Sebastian Wilhelmi] +* Improve thread configure checks, use -pthread where applicable + [Sebastian] +* Improve handlng of thread priorities [Sebastian] +* Fix up parameter names that might shadow functions from + system headers [Soeren Sandmann] +* Clean up usage of deprecated functions [Manish Singh] +* Docs fixes and improvements. In particular, include "Since" information. + [Matthias, Soeren, Martin Schulze, Daryll Strauss, Bill Janssen, + Owen Taylor, Morten Welinder]. + +Overview of Changes in GLib 2.0.7 +================================= + +* Fix C++ warnings in gtype.h [Dom Lachowicz] +* Fix g_type_fundamental_next() [Tim Janik] +* Fix various missing includes of config.h [Morten Welinder] +* Handle main loop initialization before g_thread_init [Sebastian Wilhelmi] +* Various 64-bit fixes [Manish Singh] +* Fix GPoll on Win32 [Tor Lillqvist, Herman Bloggs] +* Fix bug with buffering on UTF-8 IOChannels [Daniel Elstner] +* Misc bug and build fixes [Soren Andersen, Gustavo Carneiro, Tor, + Tim, Havoc Pennington, Matthias Clasen, Sebastian Rittau, + Masahiro Sakai, Arvind Samptur, HideToshi Tajima, Owen Taylor] +* Updated and new translations (be,cs,de,*fa,it,lv,pt_BR,tr) + +Overview of Changes in GLib 2.0.6 +================================= + +* Fix problem with interface prerequisites [Jon Trowbridge, Dave Camp] +* Clean up debug spew from GObject [Anders Carlsson] +* Compiler warning fixes [David L. Cooper II] +* Fix some problems with g_build_path() [Guillaume Chazarain, Owen Taylor] +* Fixes for --disable-debug [Sebastian Wilhelmi] +* Threading fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, + Rajkumar Sivasamy, Laurent Vivier] +* Documentation fixes [Jacob Berkman, Manuel Clos, Jared Dukat, + Sebastian Rittau, Linus Welleij] +* Misc bug fixes [Anders Carlsson, Sam Couter, Morten Welinder, Owen] +* Updated translations (bg,ko,vi) + +Overview of Changes in GLib 2.0.5 +================================= + +* Fix problem with interface prerequisites [Jon Trowbridge, Dave Camp] +* Clean up debug spew from GObject [Anders Carlsson] +* Compiler warning fixes [David L. Cooper II] +* Fix some problems with g_build_path() [Guillaume Chazarain, Owen Taylor] +* Fixes for --disable-debug [Sebastian Wilhelmi] +* Threading fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, + Rajkumar Sivasamy, Laurent Vivier] +* Documentation fixes [Jacob Berkman, Manuel Clos, Jared Dukat, + Sebastian Rittau, Linus Welleij] +* Misc bug fixes [Anders Carlsson, Sam Couter, Morten Welinder, Owen] +* Updated translations (bg,ko,vi) + +Overview of Changes in GLib 2.0.4 +================================= + +* Fix some 64-bit problems. (George Lebl, David L. Cooper II) +* Add note about Tru64 iconv to INSTALL. (Manuel Op de Coul) +* Fix problem with timouts > MAXINT. (Tim Janik, Owen Taylor) +* Updated translations (ca,es,fr,ja,gl,ms,nl,pl,pt,ru) + +Overview of Changes in GLib 2.0.3 +================================= + +* Handle sorting 0-length arrays (Ron Arts) +* Threading fixes (Sebastian Wilhelmi) +* Portability fixes (Miroslaw Dobrzanski-Neumann, Jacob Berkman, Gareth Pierce, + Sebastian, Qingjiang Yuan) +* Various fixes for glib-2.0.m4. (Jim Gettys, others.) +* Locate right glib-genmarshal when cross-compiling. (Mitch Natterer) +* Win32 fixes (Tor Lillqvist) +* Try to fix g_get_charset() related segfaults. (Owen) +* Fixes for gettext detection. (Dan Winship, HideToshi Tajima, Boyd Lynn Gerber, + Andrew P. Lentvorski, Jr.) +* Fix g_scanner_unexp_token() (Tim Janik, Sven Neumann) +* g_markup fixes. (Matthias Clasen.) +* Bug fixes and cleanups (Daniel Elstner, Matthias, Laszlo Peter, Morten Welinder, + Wayne Schuller) + +Overview of Changes in GLib 2.0.1 +================================= + +* Portability fixes for Sun's Forte compiler [Erwann Chenede] +* Performance improvements for GObject parameter lookup, + g_filename_to/from_utf8() [Alex Larsson] +* Actually check interface prerequisites [Matthias Clasen, + Miroslaw Dobrzanski-Neumann] +* Fix problem with glib-mkenums taking huge amounts of stack. [Owen Taylor] +* Fix g_signal_handlers_disconnect_by_func() for C++ [Damien Sandras] +* Fixes for g_log() and threading. + [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, Tim Janik] +* Make g_print(), g_printerr(), g_warning(), etc, convert from + UTF-8 to the encoding of the locale [Sebastian Wilhelmi, Tim] +* Fixes for GIOChannel on windows. [Tor Lillqvist] +* Fix gsize/gint mismatches in giochannel.c [Miroslaw Dobrzanski-Neumann] +* Fix file descriptor leak in g_file_get_contents() [Matthias] +* Workaround iconv() problems on older Solaris [Lauri Alanko] +* Fix warnings with gcc-3.1 about asm const [Cody Russel] +* Minor bug fixes. + +Other contributors: Hans Breuer, LEE Sau Dan, Sven Neumann, Salmaso Raffaele, + Akira Tagoh, Morten Welinder + + +Overview of Changes in GLib 2.0.0 +================================= + +* Thread portability fixes [Sebastian Wilhelmi] +* Documentation updates [Owen Taylor] +* Make g_strerror(), g_strsignal() properly return UTF-8, + call bind_text_domain_codeset() so that error strings + are in UTF-8 as well. [Owen, Tor Lillqvist] + +Overview of Changes in GLib 2.0.0 rc1: +====================================== + +* Win32 fixes [Tor Lillqvist] +* Portability fixes [Finlay Dobbie, Miroslaw Dobrzanski-Neumann] +* Fix up g_date_strftime [Daniel Elstner] +* Add some structure padding [Tim Janik] +* Make g_get_homedir() prefer the users home directory to $HOME + +Other contributors: Matthias Clasen, Paolo Maggi, Christian Rose + +Overview of Changes in GLib 1.3.15: +=================================== + +* Speed up marshalers by using private access to GValue + [Anders Carlsson, Tim Janik] +* Reduce GValue to 2 elements [Tim] +* Add G_DEBUG environment variable, G_DEBUG=fatal_warnings [Matthias Clasen] +* Fixes for AIX compilation [Miroslaw Dobrzanski-Neumann] +* Add padding to various structures [Owen Taylor, Tim] +* Win32 fixes [Tor Lillqvist] + +Other contributors: James Henstridge, Ryan Lovett, Morten Welinder, + Daniel Elstner + +Overview of Changes in GLib 1.3.14: +=================================== + +* Register value transformations for gint64, guint64 [Andy Wingo] +* Build with large-file support [Sven Neumann, Owen Taylor] +* Fix handling of hostnames in URI's [Darin Adler] +* Main loop bug fixes [Havoc Pennington, Owen] +* Doc fixes and improvements [Manish Singh, Tim Janik] +* Support ' as attribute delimiters in GMarkup [Matthias Clasen] +* Win32 fixes [Hans Breuer, Tor Lillqvist] +* Threading bug and build fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann] +* Miscellaneous bug fixes + +Other contributors: Matthias Clasen, James Henstridge, Mitch Natterer, + Morten Welinder. + +Overview of Changes in GLib 1.3.13: +=================================== + +* Fix g_filename_to/from_uri for Win32 [Tor Lillqvist, Darin Adler] +* Miscellaneous win32 fixes [Tor, Hans Breuer] +* Fix thread options for gcc on AIX [Jerome Zago, Sebastian Wilhelmi] +* Documentation improvements [Ron Steinke, Matthias, Sebastian] +* Cache iconv converters as used by g_convert() [Jeffrey Stedfast] +* Bug fixes [Sven Neumann, Owen Taylor, Matthias Clasen, Jeffrey, + Laszlo Peter, Havoc Pennington, Tim Janik] + +Overview of Changes in GLib 1.3.12: +=================================== + +* Implement closure chaining, fixing up API (Tim Janik) +* Closure chaining test case (James Henstridge) +* Make GType long not int where both are equal width (Tim) +* Win32 fixes and improvements (Hans Breuer, Tor Lillqvist) +* Fixes for NetBSD. (Dan Winship) +* Use snprintf() for g_printf_string_upper_bound() where possible. (Matthias Clasen) +* Save space for GBSearchArray (Tim Janik) +* Documentation improvements. (Matthias, Sven Neumann, Havoc Pennington) + +Other contributors: Darin Adler, Chris Blizzard, Anders Carlson, Daniel Elstner, Michael Meeks, + Mark McLoughlin, Dave Neary, Manish Singh, Owen Taylor, HideToshi Tajima, + Sebastian Wilhelmi. + + +Overview of Changes in GLib 1.3.11: +=================================== + +* Win32 fixes [Hans Breuer, Tor Lillqvist] +* Documentation improvements [Matthias Clasen] +* Portable directory handling API [Hans] +* Threading fixes [Sebastian Wilhelmi, Havoc Pennington] +* Fix excess relocations in Unicode tables [Andrew Taylor] +* Fix gpattern for UTF-8 [Matthias Clasen] +* Support overriding class closures [Tim Janik] +* Support for derivation from G_TYPE_POINTER [Owen Taylor] +* Hide pointers to type information inside GType to reduce locking + [Alex Larsson, Tim] +* Adds check for direct inclusion of gobject/*.h [Owen] +* GObject API cleanups [Tim] + +Other contributors: Darin Adler, Jacob Berkman, Daniel Egger, Eric Lemings, + Michael Meeks, Mark McLoughlin, Arkadiusz Miskiewicz, Dan Winship + + +Overview of Changes in GLib 1.3.10: +=================================== + +* Many Win32 fixes and improvements [Tor Lillqvist] +* Documentation improvements [Matthias Clasen] +* g_string_printfa() renamed to g_string_append_printf() +* Use libcharset from libiconv to implement charset detection + more portably. [Owen Taylor, Hidetoshi Tajima] +* Add 64 bit type support to GObject [Joshua Pritikin, Mathieu Lacage, Owen] +* Make support for 64 bit integers a requirement [Joshua] +* GPattern improvements [Tim Janik, Matthias] +* Locale independent g_ascii_strtod / g_ascii_dtostr [Alex Larsson] +* Many bug fixes and minor tweaks. + +Other Contributors: Darin Adler, Jakub Jelinek, James Antill, Andrew Taylor, + Ben Gertzfield, Elliot Lee, Manish Singh, Abel Cheung, Laszlo Peter, + Sven Neumann, George Lebl, Raja Harinath, Sebastian Wilhelmi, + Jacob Berkman + + +Overview of Changes in GLib 1.3.9: +================================== + +* Fixes for comparison of threads [Sebastian Wilhelmi] +* Use vasprintf() when possible for g_strdup_printf [Matthias Clasen] +* Win32 fixes [Tor Lillqvist, Hans Breuer] +* Add a len argument to g_ascii_strup/strdown +* Bug, portability fixes, cleanups. + +Other Contributors: Darin Adler, Katsuhiro Okuno, Joshua N. Pritikin + + +Overview of Changes in GLib 1.3.8: +================================== + +* Documentation updates [Owen] +* Made GType interfaces overridable in derived types +* Many win32 fixes [Tor Lillqvist] +* Miscellaneous cleanups and fixes + +Other contributors: + Darin Adler, Matthias Clasen, Ron Steinke, Hans Breuer, Alex Larsson + + +Overview of Changes in GLib 1.3.7: +================================== + +* Integrate GClosure support into the main loop [Owen Taylor] +* More GSignal convenience functions (macros) [Sven Neumann, Tim Janik] +* Introduced weak references for GObject [James Henstridge, Sven, Tim] +* Minor hash table optimizations +* Main loop and threading improvements [Sebastian Wilhelmi] +* Added g_ascii_* functions to be used for locale insensitive UTF-8 + compliant code instead of old string functions [Darin Adler, Alex Larsson] +* Add functions for Unicode case-conversion, normalization, and + collation [Owen]* GString improvements [Owen] +* Reworked the GIOChannel code [Hidetoshi Tajima, Ron Steinke] +* Removed glib-config-2.0 in favour of pkgconfig [Sebastian] +* Make code 64bit clean [Mark Murnane] +* More G_CONST_RETURN fixes +* Many improvements to the win32 code [Tor Lillqvist, Hans Breuer] +* Miscellaneous bug and API fixes + +Other contributors: + Michael Natterer, Christopher James Lahey, Padraig O'Briain, + Matthias Clasen, Josh Pritikin, Steve Baker, Cesar Rincon, Garry R. Osgood, + Michael Meeks, Laszlo Peter, Martin Baulig, Kjartan Maraas, Andrew Lanoix, + Peter Williams + + +Overview of Changes in GLib 1.3.6: +================================== + +* Threads have a "return value" from g_thread_join +* Removed ability to adjust thread stack size +* Prefix warnings with progname/PID by default, change toggle for this to + be an env variable G_MESSAGES_PREFIXED not a compile-time option +* GMarkup speedups +* GDate const, convenience fixups +* Include test cases that headers are compilable by C++ compiler +* Add ability to spawn processes with argv[0] != executable path. +* g_strstr_len, g_strrstr, g_strrstr_len +* Add length argument to g_utf8_strchr and g_utf8_strrchr. +* Misc bug fixes + + +Overview of Changes in GLib 1.3.5: +================================== + +* Added an installed glib-mkenums Perl program for parsing enumeration + declarations from header files. +* Mark some additional deprecated functions. +* Bug and Portability fixes + + +Overview of Changes in GLib 1.3.4: +================================== + +* Efficiency improvements for GThreadPool +* A few bug fixes +* Build fixes +* Documentation improvements + + +Overview of Changes in GLib 1.3.3: +================================== + +GLib: + +* More user_data support in various functions. +* Main loop API revamps to support per-thread main loops. +* Unicode handling improvements. +* Implemented debugging traps. +* G_CONST_RETURN specification all over the place. +* Various new small utility functions. +* Random number generator precision improvements. +* New configure option --disable-mem-pools. +* Many Win32 improvements. +* Added g_try_malloc() friends varinats. +* Many documentation improvements. +* Many threading improvements, support for dynamic allocation + of static mutexes. +* GHookLIst API cleanups. +* Improved format support of GDate parser. +* String function speed improvements with new g_stpcpy(). +* Hashtable API additions. +* New GPatternSpec for shell-style pattern matching (from GtkPatternSpec). +* Optimizations, cleanups, bug fixes. + +GObject: + +* Added many convenience functions. +* GClosure and GParamSpec use float/sink ref-counting scheme now. +* Reworked property change notification. +* Binary searchable array cleanups, so it's widely usable now. +* Added static content keeping for some GValue types. +* Support for statically scoped signal parameters. +* Extinguished property trailer args in set/get interface. +* Added support for abstract types. +* G_CONST_RETURN specification all over the place. +* Split parameter exchange functionality into value transforms + and parameter conversions. +* Added signal emission hooks and signal accumulators. +* Added interface prerequisites to support is_a (interface, object) + relations. +* Implemented GValueArray. +* New types, boxed: G_TYPE_VALUE, G_TYPE_CLOSURE, G_TYPE_GSTRING + GParamSpecs: G_TYPE_PARAM_PARAM, G_TYPE_PARAM_POINTER, G_TYPE_PARAM_CLOSURE, + G_TYPE_VALUE_ARRAY, G_TYPE_PARAM_UNICHAR, G_TYPE_PARAM_VALUE_ARRAY. +* Varrags value collection improvements. +* Implemented debugging traps. +* Made things thread-safe. +* Many documentation improvements. +* Many cleanups, optimizations and bug fixes. + + +Overview of Changes in GLib 1.3.2: +================================== + +GLib: + +* Win32 build improvements [Tor] +* Improvements to error reporting + (g_critical(), g_return_if_reached()) [Darin] +* Add g_strlcpy/g_strlcat [David Wheeler] +* New IO channel implementation for Win32 [Tor] +* Make g_array_free, g_string_free return pointer to memory requested + not to be freed. [Darin] +* Added GError based error reporting for thread functions. [Sebastian] +* Moved reference docs into GLib distribution. [Owen] +* Added g_convert() for doing convenient character set conversions based + on iconv. (GLib now requires libiconv or a native iconv.) [Havoc/Owen] +* Various Unicode handling additions (g_ucs4_to_utf8, g_utf8_validate(), + g_{locale,filename}_{to,from}_utf8) [Robert/Havoc/Owen] +* Portability fixes for threading. [Sebastian] +* Added convenient functions for launching new processes (g_spawn_*), + and shell quoting/unquoting functions. [Havoc] +* Split glib.h into many headers. [Sebastian] +* Added a simple callback-based parser for XML-like files (GMarkup). [Havoc] +* Fixed confusions between comparison functions that return <0, 0, >0 + and equaility functions that return FALSE,TRUE. [Sebastian] +* Added safe/portable temporary file manipulation functions. [Tor] +* autoconf improvements. [Raja] +* Many documentation improvements. +* Bug fixes. + +GObject: + +* Added boxed and pointer types. [Tim/Jonathan] +* Added callback abstraction (GClosure) [Tim] +* Added signal system (GSignal) [Tim] +* Make GTypePlugin an interface [Tim] +* Added GTypeModule - a simple GTypePlugin instantiation [Owen] +* Bug fixes. + + +What's new in GLib 1.3.1: +========================= + +* New GObject library added including object system based on + the GTK+ object system. +* Functions for getting the properties of Unicode characters, + computing the canonical decomposition and ordering combining + characters aand manipulating UTF-8 string manipulation based + on libunicode. +* GString now properly handles embedded nuls. +* Multiple fixes from the 1.2.x branch. +* Upgrade to libtool 1.3.3 +* Full thread support (thread creation and destruction). +* BeOS port, BeOS dynamic modules. +* Many improvements to the Windows ports. +* Improvements to the OS/2 port, OS/2 module support. +* Double ended queue implementation. +* GLib macros for printf() formatting, e.g. G_GULONG_FORMAT = "lu" +* New configure option --enable-msg-prefix to prefix messages, warnings + et ceteri with the program name and the process id. +* New thread-safe random number generator Mersenne Twister. +* g_strcompress() added, g_strescape() had a slight API change, and + more tightly defined semantics. +* the g_string(x) macro has been removed, #x may be used instead. + + diff --git a/NEWS.pre-1-3 b/NEWS.pre-1-3 new file mode 100644 index 0000000..1aa4f4e --- /dev/null +++ b/NEWS.pre-1-3 @@ -0,0 +1,211 @@ +Overview of Changes in GLib 1.2.1: + +* g_realloc() fix for SunOS (please report further problems). +* Continued the never ending fix vendetta regarding getpwuid(), + this time AIX has been the culprit. +* Upgrade to libtool 1.2f +* Miscellaneous other buglets fixed. + +What's new in GLib 1.2.0 (since GLib 1.0.x): + +* GLib is distributed seperatedly from Gtk+ +* Win32 Portability +* Threading support +* GModule mechanism (implemented in an extra library) which wraps dynamic + object code loading facilities in a portable manner +* GIOChannel structure to encapsulate the IPC mechanism +* GQuarks and datasets +* GRelations for n-way mapping of certain data +* An n-way tree implementation +* GDate functionality for calendar date manipulations +* GAllocator type and associated functions +* Added generic callback maintenance functions (ghook) +* Generic functions for TAB completions +* Endian defines (G_*_ENDIAN) +* g_log() mechanism for logging of messages at different log levels +* Generic main-loop mechanism +* New glib-config helper script +* Many more API extensions + +Overview of Changes in GLib 1.1.16: + +* Allocate smaller pools of memory for glists, gslists, gnodes +* Bug Fixes + +Overview of Changes in GLib 1.1.15: + +* HPUX 11 thread system detection should now work +* Release the main loop lock around calls to prepare() and + check() so it is not held over user code +* A few Win32 fixups + +Overview of Changes in GLib 1.1.14: + +* Check for dlsym() in system libraries and -dl +* FreeBSD portability fixes +* Random bug fixes and autoconf/automake changes + +Overview of Changes in GLib 1.1.13: + +* Removed alloca() based function and macro variants again. +* Improved thread related configure tests. +* GSource destruction fixups. +* Fixed up idle function removal based on user_data pointer. +* Advanced Win32 portability. +* Enforced GSource's check(), prepare() and dispatch() constrains, + loop recursions may only happen from dispatch(), and check() as well + as prepare() are called while the main_loop lock is being held. +* GLib development now requires GNU autoconf 2.13, GNU automake 1.4 + and GNU libtool 1.2d. +* Lots of random portability and bug fixes. + +Overview of Changes in GLib 1.1.12: + +* Added alloca functions/macros: g_strdup_a, g_strconcat3_a, g_alloca, + g_new_a, g_new0_a +* New tests structure. Type 'make check' on your system to run them. +* Avoid unnecessary extra hook referencing in g_hook_list_marshal + +Overview of Changes in GLib 1.1.11: + +* provide defaults for POLL sysdefs +* g_main_is_running: new function to check whether a main loop has been quitted +* a few other enhancement/fixes + +Overview of Changes in GLib 1.1.9: + +* Check for pthread_attr_init in all cases, Digital Unix 4 requires this +* For G_LOCK_DECLARE_*, if !G_THREADS_ENABLED, eat trailing semicolon better +* Changed g_main_poll_(add|remove) to g_main_(add|remove)_poll + +Overview of Changes in GLib 1.1.8: + +* Added threading support + - The ability to specify a set of functions to be used for + locking at runtime. + - Default implementations of locking functions for pthreads, + Solaris threads, and (experimentally) NSPR. + - All static variables should now properly locked. + - Enhancements to the generic main-loop mechanism to be thread-safe. + (It is used for the main-loop in GTK+ as of GTK+-1.1.8) +* Portability fixes. + +Overview of Changes in GLib 1.1.7: + +* Removed multiple define from glibconfig.h + +Overview of Changes in GLib 1.1.6: + +* New GDate functionality for calendar date manipulations (g_date_*) +* New GAllocator type and associated functions +* New functions g_slist_copy and g_list_copy to duplicate a list with all + its data pointers. +* New function g_array_insert_vals and new macro g_array_insert_val to + insert elements at an arbitrary index +* GAllocators used for glist, gslist, gnode node allocations +* Incremental freezing in ghash +* New function g_hook_list_marshal_check to eventually destroy hooks after + they got marshalled +* Revised GIOChannel to provide generic virtual-function based interface +* Added generic main-loop abstraction +* Removed GListAllocator type and its g_*_allocator_*() function variants +* Bug fixes + +Overview of Changes in GLib 1.1.5: + +* Win32 portability +* GIOChannel structure to encapsulate the IPC mechanism +* Reimplemented endian stuff, using inline asm for x86 +* New functions: + - g_strescape: escapes backslashes + - g_path_is_absolute and g_path_skip_root + - g_getenv: expands environment variables that contain references + to other environment variables + - g_scanner_sync_file_offset: rewind the filedescriptor to the current + buffer position and blow the file read ahead buffer + - g_array_remove_index: remove an entry, preserving the order + - g_array_remove_index_fast: remove an entry, order might be distorted + - g_ptr_array_remove: remove an entry, preserving the order + - g_ptr_array_remove_fast: remove an entry, order might be distorted + - g_byte_array_remove_index: wrapper for g_array_remove_index + - g_byte_array_remove_index_fast: wrapper for g_array_remove_index_fast + - g_strncasecmp: modeled closely after g_strcasecmp + - g_list_sort, g_slist_sort: to merge sort GLists and GSLists +* New macros: + - G_DIR_SEPARATOR, G_DIR_SEPARATOR_S: platform-dependant file name + syntax elements + - G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S: platform-dependant + search path syntax conventions + - G_STRUCT_OFFSET, G_STRUCT_MEMBER_P, G_STRUCT_MEMBER: for handling + structure fields through their offsets +* Removed G_ENUM, G_FLAGS, G_NV, and G_SV macros +* Bug fixes + +Overview of Changes in GLib 1.1.4: + +* Added generic callback maintenance functions (ghook) +* New endian defines (G_*_ENDIAN) +* New string join/split/free routines +* Fixes + +Overview of Changes in GLib 1.1.3: + +* New GModule mechanism (implemented in an extra library) which wraps dynamic + object code loading facilities in a portable manner. +* glib-config features extra "glib" (old behaviour remains) and "gmodule" + (add libgmodule.so to the --libs output) arguments now. this can also + be specified as fourth argument to the AM_PATH_GLIB() macro. +* Overhaul of the `inline' autoconfiguration stuff, so inlining should be + sufficiently supported on all systems that allow inlining now. +* New g_log() mechanism for logging of messages at different log levels, + associated with certain log domains (define -DG_LOG_DOMAIN for your library). +* New inline functions for bit masks tests. +* GNode macros (and functions) now return the newly allocated node. +* New macro G_VA_COPY() to work around va_list copying oddities on some + platforms. the non-static g_vsprintf() function vanished in favour of + a publically exported g_strdup_vprintf(). + People that used the former g_vsprintf() would definitely want to read the + associated ChangeLog entries (grep for printf). +* New utility functions: + g_strndup(), g_on_error_query(), g_on_error_stack_trace(), g_strdup_printf(), + g_strdup_vprintf(), g_printf_string_upper_bound(), g_spaced_primes_closest(), + g_strnfill(), g_memdup(). +* Overhaul of the array implementations, this contains some source incompatible + changes. Again, the ChangeLog is much more informative (grep for garray.c). +* The internals of the g_dataset mechanism are now exported through the + new g_datalist_* API (this is also the underlying implementation for the + keyed data of GtkObjects). +* New function g_atexit(), use of the ATEXIT() macro is discouraged. +* Better configure checks for ansi compliance. +* Libtool update to version 1.2b. +* Lotsa bug fixes and cleanups as always ;) + +Overview of Changes in GLib 1.1.2: + +* Fixed packaging mistake which occured in 1.1.1 +* fix 64-bitness in g_prints in glibtest + +What is new in GLib 1.1.1: + +* An n-way tree implementation is provided now, based on the GNode structure. +* Bugfix for pointer arrays. + +What is new in GLib 1.1.0: + +* GLib is distributed seperatedly from Gtk+ now and uses a sophisticated + shared library versioning scheme to deal with interface and binary + incompatibilities. +* There is a glib-config helper script installed now. +* Fixups all over the place. +* gboolean is now a gint, not a gchar anymore. +* API extensions for GList and GSList. +* New g_str*() functions for simple string handling. +* GScanner extensions for scope, warning and error handling. +* Minor performance improvements for GMemChunks. +* Implementations of GQuarks and datasets (similar to GtkObjects data + mechansim, but works for generic memory locations). +* More convenience macros for GNU C function arguments. +* Const correction all over the place, including a new pointer type + gconstpointer. +* Generic functions for TAB completions. +* GRelations for n-way mapping of certain data. diff --git a/README b/README new file mode 100644 index 0000000..96dc92f --- /dev/null +++ b/README @@ -0,0 +1 @@ +See README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..7b436b5 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# GLib + +GLib is the low-level core library that forms the basis for projects such +as GTK and GNOME. It provides data structure handling for C, portability +wrappers, and interfaces for such runtime functionality as an event loop, +threads, dynamic loading, and an object system. + +The official download locations are: + + +The official web site is: + + +## Installation + +See the file '[INSTALL.in](INSTALL.in)' + +## Supported versions + +Only the most recent unstable and stable release series are supported. All +older versions are not supported upstream and may contain bugs, some of +which may be exploitable security vulnerabilities. + +See [SECURITY.md](SECURITY.md) for more details. + +## Documentation + +API documentation is available online for GLib for the: + * [GLib](https://docs.gtk.org/glib/) + * [GObject](https://docs.gtk.org/gobject/) + * [GModule](https://docs.gtk.org/gmodule/) + * [GIO](https://docs.gtk.org/gio/) + +## Discussion + +If you have a question about how to use GLib, seek help on [GNOME’s Discourse +instance](https://discourse.gnome.org/tags/glib). Alternatively, ask a question +on [StackOverflow and tag it `glib`](https://stackoverflow.com/questions/tagged/glib). + +## Reporting bugs + +Bugs should be [reported to the GNOME issue tracking system](https://gitlab.gnome.org/GNOME/glib/issues/new). +You will need to create an account for yourself. You may also submit bugs by +e-mail (without an account) by e-mailing , +but this will give you a degraded experience. + +Bugs are for reporting problems in GLib itself, not for asking questions about +how to use it. To ask questions, use one of our [discussion forums](#discussion). + +In bug reports please include: + +* Information about your system. For instance: + * What operating system and version + * For Linux, what version of the C library + * And anything else you think is relevant. +* How to reproduce the bug. + * If you can reproduce it with one of the test programs that are built + in the `tests/` subdirectory, that will be most convenient. Otherwise, + please include a short test program that exhibits the behavior. + As a last resort, you can also provide a pointer to a larger piece + of software that can be downloaded. +* If the bug was a crash, the exact text that was printed out + when the crash occurred. +* Further information such as stack traces may be useful, but + is not necessary. + +## Contributing to GLib + +Please follow the [contribution guide](./CONTRIBUTING.md) to know how to +start contributing to GLib. + +Patches should be [submitted as merge requests](https://gitlab.gnome.org/GNOME/glib/-/merge_requests/new) +to gitlab.gnome.org. If the patch fixes an existing issue, please refer to the +issue in your commit message with the following notation (for issue 123): +``` +Closes: #123 +``` + +Otherwise, create a new merge request that introduces the change. Filing a +separate issue is not required. + +## Default branch renamed to `main` + +The default development branch of GLib has been renamed to `main`. To update +your local checkout, use: +```sh +git checkout master +git branch -m master main +git fetch +git branch --unset-upstream +git branch -u origin/main +git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main +``` diff --git a/README.rationale b/README.rationale new file mode 100644 index 0000000..e1d4593 --- /dev/null +++ b/README.rationale @@ -0,0 +1,16 @@ +This file documents various major decisions which affect GLib development, +giving a brief rationale of each decision, plus a link to further discussion. + + + * Compiler attributes: https://bugzilla.gnome.org/show_bug.cgi?id=113075#c46 + + GLib uses GIR annotations instead of compiler attributes. They are tidier, + already supported by GLib and GNOME tools, and accomplish the same task as + compiler attributes. GLib does not provide macros for attributes like + nonnull because it would not use them. + + * Main loop API: + + The ID-based mainloop APIs (g_idle_add, g_timeout_add, etc) are considered + legacy, and new features (such as g_source_set_static_name) will only be + added to the explicit GSource APIs. diff --git a/README.win32 b/README.win32 new file mode 100644 index 0000000..7530a68 --- /dev/null +++ b/README.win32 @@ -0,0 +1 @@ +See README.win32.md diff --git a/README.win32.md b/README.win32.md new file mode 100644 index 0000000..17b36ac --- /dev/null +++ b/README.win32.md @@ -0,0 +1,169 @@ +Chun-wei Fan `` +Philip Withnall `` +Nirbheek Chauhan `` + +This document was last updated in 2019. You're reading this in the future, and +lots of information might be misleading or outdated in your age. You have been +warned. + +# General + +For prebuilt binaries (DLLs and EXEs) and developer packages (headers, +import libraries) of GLib, Pango, GTK+ etc for Windows, go to +https://www.gtk.org/download/windows.php . They are for "native" +Windows meaning they use the Win32 API and Microsoft C runtime library +only. No POSIX (Unix) emulation layer like Cygwin is involved. + +To build GLib on Win32, you can use either GCC ("MinGW") or the Microsoft +Visual Studio toolchain. For the latter, Visual Studio 2015 and later are +recommended. For older Visual Studio versions, see below. + +You can also cross-compile GLib for Windows from Linux using the +cross-compiling mingw packages for your distro. + +Note that to just *use* GLib on Windows, there is no need to build it +yourself. + +On Windows setting up a correct build environment is very similar to typing +`meson; ninja` like on Linux. + +The following preprocessor macros are to be used for conditional +compilation related to Win32 in GLib-using code: + +- `G_OS_WIN32` is defined when compiling for native Win32, without + any POSIX emulation, other than to the extent provided by the + bundled Microsoft C library. + +- `G_WITH_CYGWIN` is defined if compiling for the Cygwin + environment. Note that `G_OS_WIN32` is *not* defined in that case, as + Cygwin is supposed to behave like Unix. `G_OS_UNIX` *is* defined by a GLib + for Cygwin. + +- `G_PLATFORM_WIN32` is defined when either `G_OS_WIN32` or `G_WITH_CYGWIN` + is defined. + +These macros are defined in `glibconfig.h`, and are thus available in +all source files that include ``. + +Additionally, there are the compiler-specific macros: +- `__GNUC__` is defined when using GCC or Clang +- `__clang__` is defined when using Clang or Clang-CL +- `_MSC_VER` is defined when using MSVC or Clang-CL + +`G_OS_WIN32` implies using the Microsoft C runtime, which used to be +`msvcrt.dll` and is now the [Universal CRT](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2015) +when building with Visual Studio. When using the MinGW-GCC toolchain, the CRT +in use depends on the settings used while the toolchain was built. We highly +recommend [using the Universal CRT when building with +MinGW](https://mingwpy.github.io/ucrt.html) too. + +GLib is not actively tested with the static versions of the UCRT, but if you +need to use those, patches are welcome. + +# Building software that use GLib or GTK+ + +Building software that just *uses* GLib or GTK+ also require to have +the right compiler set up the right way. If you intend to use MinGW-GCC, +follow the relevant instructions below in that case, too. + +You should link to GLib using the `-mms-bitfields` GCC flag. This flag means +that the struct layout rules are identical to those used by MSVC. This is +essential if the same DLLs are to be usable both from gcc- and MSVC-compiled +code. + +## Cross-CRT issues + +You should take care that the DLLs that your code links to are using the same +C runtime library. Not doing so can and likely will lead to panics and crashes +**unless** you're very careful while passing objects allocated by a library +linked with one CRT to a library linked to another CRT, or (more commonly) not +doing that at all. + +If you *do* pass CRT objects across CRT boundaries, do not file any issues +about whatever happens next. + +To give an example, opening a `FILE` handle created by one CRT cannot be +understood by any other CRT, and will lead to an access violation. You also +cannot allocate memory in one CRT and free it using another. + +There are [many other cases where you must not allow objects to cross CRT boundaries](https://docs.microsoft.com/en-us/cpp/c-runtime-library/potential-errors-passing-crt-objects-across-dll-boundaries?view=vs-2019), +but in theory if you're **very very** careful, you can make things work. Again, +please do not come to us for help if you choose to do this. + +# Building GLib + +You can build GLib with MinGW-GCC, MSVC, or (experimentally) with Clang-CL. + +For all compilers, you will need the following: + +- Install Python 3.6.x or newer, either 32-bit or 64-bit. We recommend enabling + the option to add it to your `PATH`. +- [Install Meson](https://mesonbuild.com/Getting-meson.html) +- Install the [Ninja build tool](https://github.com/ninja-build/ninja/releases), which can also be + installed with `pip3`. You can skip this step if you want to generate Visual + Studio project files. +- [git for Windows](https://gitforwindows.org/) is required, since Meson makes + use of git to download dependencies using subprojects. + +## Building with MinGW-GCC + +Open your MSYS or [MSYS2](https://www.msys2.org/) shell where you have the +MinGW-GCC toolchain installed, and build GLib [like any other Meson +project](https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project). + +## Building with Visual Studio 2015 or newer + +Meson is now the only supported method of building GLib using Visual Studio. + +To do a build using Meson, do the following: + +- Open a Visual Studio (or SDK) command prompt that matches the Visual Studio + version and build platform (Win32/x86, x64, etc.) that will be used in all + the following steps. + +- Create an empty directory/folder for the build inside your GLib sources + directory, say, `_builddir`, and `cd` into it. + +- Set up the build using Meson: + +```cmd +> meson .. --buildtype= --prefix= [--backend=vs] +``` + + Please see [the Meson docs](https://mesonbuild.com/Builtin-options.html#core-options) + for an explanation for `--buildtype`. + + The path passed for `--prefix` need not to be on the same drive as where the + build is carried out, but it is recommended to use forward slashes for this + path. The `--backend=vs` option can be used if the Visual Studio project + generator is preferred over using Ninja. + +- Build, test and install the build: + Run `ninja` to build, `meson test` to test and `meson install` to install the + build. If you used `--backend=vs`, instead of running `ninja`, you need to + use `msbuild` or you can open the generated solution in Visual Studio. + +## Building with old versions of Visual Studio + +The steps are the same as above, with the following notes about issues that you might face. + +### C4819 build errors + +If you are building GLib-based libraries or applications, or GLib itself +and you see a `C4819` error (or warning, before `C4819` is treated as an error +in `msvc_recommended_pragmas.h`), please be advised that this error/warning should +not be disregarded, as this likely means portions of the build are not being +done correctly, as this is an issue of Visual Studio running on CJK (East Asian) +locales. This is an issue that also affects builds of other projects, such as +QT, Firefox, LibreOffice/OpenOffice, Pango and GTK, along with many other projects. + +To overcome this problem, please set your system's locale setting for non-Unicode to +English (United States), reboot, and restart the build, and the code should build +normally. + +### Support for pre-2012 Visual Studio + +This release of GLib requires at least the Windows 8 SDK in order to be built +successfully using Visual Studio, which means that it is no longer supported to +build GLib with Visual Studio 2008 nor 2010. People that still need to use +Visual Studio 2008 or 2010 should continue to use glib-2.66.x. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..e49460a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,78 @@ +# Security policy for GLib + + * [Supported Versions](#Supported-Versions) + * [Reporting a Vulnerability](#Reporting-a-Vulnerability) + * [Security Announcements](#Security-Announcements) + * [Acknowledgements](#Acknowledgements) + +## Supported Versions + +Upstream GLib only supports the most recent stable release series, and the +current development release series. Any older stable release series are no +longer supported, although they may still receive backported security updates +in long-term support distributions. Such support is up to the distributions, +though. + +Under GLib’s versioning scheme, stable release series have an *even* minor +component (for example, 2.66.0, 2.66.1, 2.68.3), and development release series +have an *odd* minor component (2.67.1, 2.69.0). + +## Signed Releases + +The git tags for all releases ≥2.58.0 are signed by a maintainer using +[git-evtag](https://github.com/cgwalters/git-evtag). The maintainer will use +their personal GPG key; there is currently not necessarily a formal chain of +trust for these keys. Please [create an issue](https://gitlab.gnome.org/GNOME/glib/-/issues/new) +if you would like to work on improving this. + +Unsigned releases ≥2.58.0 should not be trusted. Releases prior to 2.58.0 were +not signed. + +## Reporting a Vulnerability + +If you think you've identified a security issue in GLib, GObject or GIO, please +**do not** report the issue publicly via a mailing list, IRC, a public issue on +the GitLab issue tracker, a merge request, or any other public venue. + +Instead, report a +[*confidential* issue in the GitLab issue tracker](https://gitlab.gnome.org/GNOME/glib/-/issues/new?issue[confidential]=1), +with the “This issue is confidential†box checked. Please include as many +details as possible, including a minimal reproducible example of the issue, and +an idea of how exploitable/severe you think it is. + +**Do not** provide a merge request to fix the issue, as there is currently no +way to make confidential merge requests on gitlab.gnome.org. If you have patches +which fix the security issue, please attach them to your confidential issue as +patch files. + +Confidential issues are only visible to the reporter and the GLib maintainers. + +As per the [GNOME security policy](https://security.gnome.org/), the next steps +are then: + * The report is triaged. + * Code is audited to find any potential similar problems. + * If it is determined, in consultation with the submitter, that a CVE is + required, the submitter obtains one via [cveform.mitre.org](https://cveform.mitre.org/). + * The fix is prepared for the development branch, and for the most recent + stable branch. + * The fix is submitted to the public repository. + * On the day the issue and fix are made public, an announcement is made on the + [public channels listed below](#Security-Announcements). + * A new release containing the fix is issued. + +## Security Announcements + +Security announcements are made publicly via the +[`distributor` tag on discourse.gnome.org](https://discourse.gnome.org/tag/distributor) +and cross-posted to the +[distributor-list](https://mail.gnome.org/mailman/listinfo/distributor-list). + +Announcements for security issues with wide applicability or high impact may +additionally be made via +[oss-security@lists.openwall.com](https://www.openwall.com/lists/oss-security/). + +## Acknowledgements + +This text was partially based on the +[github.com/containers security policy](https://github.com/containers/common/blob/HEAD/SECURITY.md), +and partially based on the [flatpak security policy](https://github.com/flatpak/flatpak/blob/HEAD/SECURITY.md). diff --git a/check-abis.sh b/check-abis.sh new file mode 100755 index 0000000..5340f31 --- /dev/null +++ b/check-abis.sh @@ -0,0 +1,23 @@ +#!/bin/sh -e + +list_leaked_symbols () { + nm -D "$1" | grep ' T ' | cut -f 3 -d ' ' | grep -E -v "$2" +} + +check_symbols () { + if [ "$(list_leaked_symbols "$1" "$2" | wc -l)" -ne 0 ]; then + echo File "$1" possibly leaking symbols: + list_leaked_symbols "$1" "$2" + exit 1 + fi +} + +allowed="^_init$|^_fini$|^_ftext$|^g_" +allowed_in_libglib="${allowed}|^glib__private__$|^glib_gettext$|^glib_pgettext$|^glib_check_version$" +allowed_in_libgthread='^_init$|^_fini$|^_ftext$|^g_thread_init$|^g_thread_init_with_errorcheck_mutexes$' + +check_symbols glib/.libs/libglib-2.0.so "$allowed_in_libglib" +check_symbols gthread/.libs/libgthread-2.0.so "$allowed_in_libgthread" +for file in gmodule/.libs/libgmodule-2.0.so gobject/.libs/libgobject-2.0.so gio/.libs/libgio-2.0.so; do + check_symbols "$file" "$allowed" +done diff --git a/clang-format-diff.py b/clang-format-diff.py new file mode 100755 index 0000000..4eb1910 --- /dev/null +++ b/clang-format-diff.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python3 +# +# === clang-format-diff.py - ClangFormat Diff Reformatter ---*- python -*-=== # +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===---------------------------------------------------------------------=== # + +""" +This script reads input from a unified diff and reformats all the changed +lines. This is useful to reformat all the lines touched by a specific patch. +Example usage for git/svn users: + + git diff -U0 --no-color HEAD^ | clang-format-diff.py -p1 -i + svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i + +""" +from __future__ import absolute_import, division, print_function + +import argparse +import difflib +import re +import subprocess +import sys + +if sys.version_info.major >= 3: + from io import StringIO +else: + from io import BytesIO as StringIO + + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument( + "-i", + action="store_true", + default=False, + help="apply edits to files instead of displaying a " "diff", + ) + parser.add_argument( + "-p", + metavar="NUM", + default=0, + help="strip the smallest prefix containing P slashes", + ) + parser.add_argument( + "-regex", + metavar="PATTERN", + default=None, + help="custom pattern selecting file paths to reformat " + "(case sensitive, overrides -iregex)", + ) + parser.add_argument( + "-iregex", + metavar="PATTERN", + default=r".*\.(cpp|cc|c\+\+|cxx|c|cl|h|hh|hpp|m|mm|inc" + r"|js|ts|proto|protodevel|java|cs)", + help="custom pattern selecting file paths to reformat " + "(case insensitive, overridden by -regex)", + ) + parser.add_argument( + "-sort-includes", + action="store_true", + default=False, + help="let clang-format sort include blocks", + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + help="be more verbose, ineffective without -i", + ) + parser.add_argument( + "-style", + help="formatting style to apply (LLVM, Google, " "Chromium, Mozilla, WebKit)", + ) + parser.add_argument( + "-binary", + default="clang-format", + help="location of binary to use for clang-format", + ) + args = parser.parse_args() + + # Extract changed lines for each file. + filename = None + lines_by_file = {} + for line in sys.stdin: + match = re.search(r"^\+\+\+\ (.*?/){%s}(\S*)" % args.p, line) + if match: + filename = match.group(2) + if filename is None: + continue + + if args.regex is not None: + if not re.match("^%s$" % args.regex, filename): + continue + else: + if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE): + continue + + match = re.search(r"^@@.*\+(\d+)(,(\d+))?", line) + if match: + start_line = int(match.group(1)) + line_count = 1 + if match.group(3): + line_count = int(match.group(3)) + if line_count == 0: + continue + end_line = start_line + line_count - 1 + lines_by_file.setdefault(filename, []).extend( + ["-lines", str(start_line) + ":" + str(end_line)] + ) + + # Reformat files containing changes in place. + # We need to count amount of bytes generated in the output of + # clang-format-diff. If clang-format-diff doesn't generate any bytes it + # means there is nothing to format. + format_line_counter = 0 + for filename, lines in lines_by_file.items(): + if args.i and args.verbose: + print("Formatting {}".format(filename)) + command = [args.binary, filename] + if args.i: + command.append("-i") + if args.sort_includes: + command.append("-sort-includes") + command.extend(lines) + if args.style: + command.extend(["-style", args.style]) + p = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=None, + stdin=subprocess.PIPE, + universal_newlines=True, + ) + stdout, _ = p.communicate() + if p.returncode != 0: + sys.exit(p.returncode) + + if not args.i: + with open(filename) as f: + code = f.readlines() + formatted_code = StringIO(stdout).readlines() + diff = difflib.unified_diff( + code, + formatted_code, + filename, + filename, + "(before formatting)", + "(after formatting)", + ) + diff_string = "".join(diff) + if diff_string: + format_line_counter += sys.stdout.write(diff_string) + + if format_line_counter > 0: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS new file mode 100644 index 0000000..e1d6efe --- /dev/null +++ b/docs/CODEOWNERS @@ -0,0 +1,83 @@ +# These are the people responsible for subsystems in GLib; if you're opening +# a merge request for files listed here, please add the following people to +# the list of reviewers + +# The syntax of this file is defined by GitLab: +# https://docs.gitlab.com/ee/user/project/code_owners.html +# Which, in turn, is similar to the .gitignore and .gitattributes files: +# +# - comments start with `#` +# - the first column contains paths and globs +# - the second column contains GitLab user names or email addresses, +# separated by spaces +# +# The last matching glob (rather than the union of *all* matching globs) gives +# the owners of a piece of code. +# +# If you want to be responsible for code reviews in specific sections of +# the GLib code base, add yourself here. + +# Overall maintainers +* @pwithnall @ebassi + +# Build system +meson.build @xclaesse @nirbheek @pwithnall +meson_options.txt @xclaesse @nirbheek @pwithnall +subprojects/ @xclaesse @nirbheek @pwithnall + +# CI integration +.gitlab-ci* @pwithnall @xclaesse @creiter + +# macOS support +*osx* @jralls @pwithnall @sdroege +*.m @jralls @pwithnall @sdroege + +# Windows support +*win32* @lrn @creiter @fanc999 @pwithnall @sdroege @nirbheek + +# Windows support (MSVC-specific) +*msvc* @fanc999 @creiter @pwithnall @sdroege @nirbheek + +# Windows support (UWP-specific) +*uwp* @nirbheek + +# Android support +*android* @xclaesse @pwithnall @sdroege + +# BSD support +*bsd* @jmatthew @ajacoutot @lantw @pwithnall +*kqueue* @jmatthew @ajacoutot @lantw @pwithnall + +# flatpak portals +gio/*portal* @matthiasc @alexl @pwithnall + +# Networking +gio/g*{tcp,udp,tls,socket,resolver,proxy,network,inet,datagram}* @mcatanzaro @pgriffis @pwithnall @sdroege + +# D-Bus +gio/g*bus* @smcv @pwithnall + +# I/O +gio/g*{file,vfs,mount,drive,volume}* @oholy @alexl @pwithnall @sdroege +gio/g*stream* @alexl @pwithnall @sdroege +gio/gio-tool* @oholy @alexl @pwithnall + +# Generic bits of GLib +glib/ @ebassi @pwithnall @sdroege + +# GObject type system +gobject/ @ebassi @pwithnall @sdroege + +# GVariant +glib/gvariant* @pwithnall @sdroege + +# grefcount, GRcBox and GRefString +glib/gref{count,string}.[ch] @ebassi @pwithnall @sdroege +glib/grc*.[ch] @ebassi @pwithnall @sdroege +glib/garc*.[ch] @ebassi @pwithnall @sdroege + +# Logging +glib/gmessages.[ch] @pwithnall @sdroege + +# Google clusterfuzz support +fuzzing/ @pwithnall \ No newline at end of file diff --git a/docs/debugging.txt b/docs/debugging.txt new file mode 100644 index 0000000..2cc600a --- /dev/null +++ b/docs/debugging.txt @@ -0,0 +1,38 @@ + +Traps (G_BREAKPOINT) and traces for the debugging +================================================= + +Some code portions contain trap variables that can be set during +debugging time if G_ENABLE_DEBUG has been defined upon compilation +(use the --buildtype=debug option to configure for this, macros.txt +covers more details). +Such traps lead to immediate code halts to examine the current +program state and backtrace. +Currently, the following trap variables exist: + +static volatile gulong g_trap_free_size; +static volatile gulong g_trap_realloc_size; +static volatile gulong g_trap_malloc_size; + If set to a size > 0, g_free(), g_realloc() and g_malloc() + respectively, will be intercepted if the size matches the + size of the corresponding memory block to free/reallocate/allocate. + This will only work with g_mem_set_vtable (glib_mem_profiler_table) + upon startup though, because memory profiling is required to match + on the memory block sizes. +static volatile GObject *g_trap_object_ref; + If set to a valid object pointer, ref/unref will be intercepted + with G_BREAKPOINT (); +static volatile gpointer *g_trap_instance_signals; +static volatile gpointer *g_trace_instance_signals; + If set to a valid instance pointer, debugging messages + will be spewed about emissions of signals on this instance. + For g_trap_instance_signals matches, the emissions will + also be intercepted with G_BREAKPOINT (); + +Environment variables for debugging +=================================== +When G_ENABLE_DEBUG was defined upon compilation, the GObject library +supports an environment variable GOBJECT_DEBUG that can be set to a +combination of the flags passed in to g_type_init() (currently +"objects" and "signals") to trigger debugging messages about +object bookkeeping and signal emissions during runtime. \ No newline at end of file diff --git a/docs/macros.txt b/docs/macros.txt new file mode 100644 index 0000000..ec449f1 --- /dev/null +++ b/docs/macros.txt @@ -0,0 +1,58 @@ +GLib's configure options and corresponding macros +================================================= + +--buildtype={plain,release,minsize,custom} + none +--buildtype={debug,debugoptimized} [debugoptimized is the default] + -DG_ENABLE_DEBUG -g +-Dglib_debug=disabled + Omits G_ENABLE_DEBUG when implied by --buildtype/-Ddebug +-Dglib_debug=enabled + Defines G_ENABLE_DEBUG regardless of --buildtype/-Ddebug +-Dglib_asserts=false + -DG_DISABLE_ASSERT +-Dglib_checks=false + -DG_DISABLE_CHECKS + +Besides these, there are some local feature specific options, but my main +focus here is to concentrate on macros that affect overall GLib behaviour +and/or third party code. + + +Notes on GLib's internal and global macros +========================================== + +G_DISABLE_ASSERT + The g_assert() and g_assert_not_reached() become non-functional + with this define. The motivation is to speed up end-user apps by + avoiding expensive checks. + This macro can affect third-party code. Defining it when building GLib + will only disable the assertion macros for GLib itself, but third-party code + that passes -DG_DISABLE_ASSERT to the compiler upon its own build + will end up with the non-functional variants after including glib.h + as well. + NOTE: Code inside the assertion macros should not have side effects + that affect the operation of the program. +G_DISABLE_CHECKS + This macro is similar to G_DISABLE_ASSERT, it affects third-party + code as mentioned above and the NOTE about G_DISABLE_ASSERT applies + too. The macros that become non-functional here are + g_return_if_fail(), g_return_val_if_fail(), g_return_if_reached() and + g_return_val_if_reached(). + Additionally the glib_mem_profiler_table and g_mem_profile() from + gmem.h become non-functional if this macro is supplied. + This macro also switches off certain checks in the GSignal code. +G_ENABLE_DEBUG + Quite a bit of additional debugging code is compiled into GLib for this + macro, and since it is a globally visible define, third-party code may + be affected by it similar to G_DISABLE_ASSERT. + The additional code executed/compiled for this macro currently involve: + - extra validity checks for GDate + - memory profiling traps in gmem.c (consult debugging.txt for details) + - BREAKPOINT abortion for fatal log levels in gmessage.c instead of + plain abort() to allow debuggers trapping and overriding them + - added verbosity of gscanner.c to catch deprecated code paths + - added verbosity of gutils.c to catch deprecated code paths + - object ref/unref traps (consult debugging.txt) and object bookkeeping + in gobject.c + - extra validity checks in gsignal.c \ No newline at end of file diff --git a/docs/reference/.gitignore b/docs/reference/.gitignore new file mode 100644 index 0000000..f9e370e --- /dev/null +++ b/docs/reference/.gitignore @@ -0,0 +1,16 @@ +*-decl-list.txt +*-decl.txt +*-unused.txt +*-undocumented.txt +*-undeclared.txt +*.args +*.hierarchy +*.interfaces +*.prerequisites +*.signals +*.stamp +html +xml +*.bak +version.xml +*.1 diff --git a/docs/reference/AUTHORS b/docs/reference/AUTHORS new file mode 100644 index 0000000..64f46b7 --- /dev/null +++ b/docs/reference/AUTHORS @@ -0,0 +1,7 @@ +Damon Chaplin and others. + +See: + + http://www.gtk.org/rdp/status.html + +for a complete list. diff --git a/docs/reference/COPYING b/docs/reference/COPYING new file mode 100644 index 0000000..df952d3 --- /dev/null +++ b/docs/reference/COPYING @@ -0,0 +1,30 @@ +This work may be reproduced and distributed in whole or in part, in +any medium, physical or electronic, so as long as this copyright +notice remains intact and unchanged on all copies. Commercial +redistribution is permitted and encouraged, but you may not +redistribute, in whole or in part, under terms more restrictive than +those under which you received it. If you redistribute a modified or +translated version of this work, you must also make the source code to +the modified or translated version available in electronic form +without charge. However, mere aggregation as part of a larger work +shall not count as a modification for this purpose. + +All code examples in this work are placed into the public domain, +and may be used, modified and redistributed without restriction. + +BECAUSE THIS WORK IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE WORK, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE WORK "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. SHOULD THE WORK PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY REPAIR OR CORRECTION. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE WORK AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +WORK, EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. diff --git a/docs/reference/NEWS b/docs/reference/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/docs/reference/gio/.gitignore b/docs/reference/gio/.gitignore new file mode 100644 index 0000000..e9e522e --- /dev/null +++ b/docs/reference/gio/.gitignore @@ -0,0 +1,3 @@ +*.1 +gio-overrides.txt +tmpl diff --git a/docs/reference/gio/concat-files-helper.py b/docs/reference/gio/concat-files-helper.py new file mode 100644 index 0000000..d434f9e --- /dev/null +++ b/docs/reference/gio/concat-files-helper.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright (C) 2018 Collabora Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: Xavier Claessens + +import os +import sys + +if len(sys.argv) < 3: + print( + "Usage: {} ...".format( + os.path.basename(sys.argv[0]) + ) + ) + sys.exit(1) + +with open(sys.argv[1], "w") as outfile: + for fname in sys.argv[2:]: + with open(fname) as infile: + for line in infile: + outfile.write(line) diff --git a/docs/reference/gio/gapplication.xml b/docs/reference/gio/gapplication.xml new file mode 100644 index 0000000..13e3f23 --- /dev/null +++ b/docs/reference/gio/gapplication.xml @@ -0,0 +1,352 @@ + + + gapplication + GIO + + + Developer + Ryan + Lortie + + + + + + gapplication + 1 + User Commands + + + + gapplication + D-Bus application launcher + + + + + gapplication + help + COMMAND + + + gapplication + version + + + gapplication + list-apps + + + gapplication + launch + APPID + + + gapplication + launch + APPID + FILE + + + gapplication + list-actions + APPID + + + gapplication + action + APPID + ACTION + PARAMETER + + + + + Description + + + gapplication is a commandline implementation of the client-side of the + org.freedesktop.Application interface as specified by the freedesktop.org + Desktop Entry Specification. + + + + gapplication can be used to start applications that have + DBusActivatable set to true in their .desktop + files and can be used to send messages to already-running instances of other applications. + + + + It is possible for applications to refer to gapplication in the Exec + line of their .desktop file to maintain backwards compatibility + with implementations that do not directly support DBusActivatable. + + + + gapplication ships as part of GLib. + + + + + Commands + + + Global commands + + + + + help + COMMAND + + + + Displays a short synopsis of the available commands or provides detailed help on a specific + command. + + + + + + + version + + + + Prints the GLib version whence gapplication came. + + + + + + + list-apps + + + + Prints a list of all application IDs that are known to support D-Bus activation. This list is + generated by scanning .desktop files as per the current + XDG_DATA_DIRS. + + + + + + + launch + APPID + FILE + + + + Launches an application. + + + The first parameter is the application ID in the familiar "reverse DNS" style (eg: + 'org.gnome.app') without the .desktop + suffix. + + + Optionally, if additional parameters are given, they are treated as the names of files to open and + may be filenames or URIs. If no files are given then the application is simply activated. + + + + + + + list-actions + APPID + + + + List the actions declared in the application's .desktop + file. The parameter is the application ID, as above. + + + + + + + action + APPID + ACTION + PARAMETER + + + + Invokes the named action (in the same way as would occur when activating an action specified in + the .desktop file). + + + The application ID (as above) is the first parameter. The action name follows. + + + Optionally, following the action name can be one parameter, in GVariant format, given as a single + argument. Make sure to use sufficient quoting. + + + + + + + + + + Examples + + + From the commandline + + + Launching an application: + + + + gapplication launch org.example.fooview + + + + Opening a file with an application: + + + + gapplication launch org.example.fooview ~/file.foo + + + + Opening many files with an application: + + + + gapplication launch org.example.fooview ~/foos/*.foo + + + + Invoking an action on an application: + + + + gapplication action org.example.fooview create + + + + Invoking an action on an application, with an action: + + + + gapplication action org.example.fooview show-item '"item_id_828739"' + + + + + + From the <varname>Exec</varname> lines of a <filename class='extension'>.desktop</filename> file + + + + The commandline interface of gapplication was designed so that it could be used + directly from the Exec line of a .desktop + file. + + + + You might want to do this to allow for backwards compatibility with implementations of the specification + that do not understand how to do D-Bus activation, without having to install a separate utility program. + + + + Consider the following example: + + + + [Desktop Entry] + Version=1.1 + Type=Application + Name=Foo Viewer + DBusActivatable=true + MimeType=image/x-foo; + Exec=gapplication launch org.example.fooview %F + Actions=gallery;create; + + [Desktop Action gallery] + Name=Browse Gallery + Exec=gapplication action org.example.fooview gallery + + [Desktop Action create] + Name=Create a new Foo! + Exec=gapplication action org.example.fooview create + + + + + From a script + + + If installing an application that supports D-Bus activation you may still want to put a file in + /usr/bin so that your program can be started from a terminal. + + + + It is possible for this file to be a shell script. The script can handle arguments such as --help and + --version directly. It can also parse other command line arguments and convert them to uses of + gapplication to activate the application, open files, or invoke actions. + + + + Here is a simplified example, as may be installed in /usr/bin/fooview: + + + + #!/bin/sh + + case "$1" in + --help) + echo "see 'man fooview' for more information" + ;; + + --version) + echo "fooview 1.2" + ;; + + --gallery) + gapplication action org.example.fooview gallery + ;; + + --create) + gapplication action org.example.fooview create + ;; + + -*) + echo "unrecognised commandline argument" + exit 1 + ;; + + *) + gapplication launch org.example.fooview "$@" + ;; + esac + + + + + + See also + + Desktop Entry Specification, + + gdbus + 1 + , + + xdg-open + 1 + , + + desktop-file-validate + 1 + + + + + diff --git a/docs/reference/gio/gdbus-codegen.xml b/docs/reference/gio/gdbus-codegen.xml new file mode 100644 index 0000000..5860fed --- /dev/null +++ b/docs/reference/gio/gdbus-codegen.xml @@ -0,0 +1,1193 @@ + + + + gdbus + GIO + + + Developer + David + Zeuthen + zeuthen@gmail.com + + + + + + gdbus-codegen + 1 + User Commands + + + + gdbus-codegen + D-Bus code and documentation generator + + + + + gdbus-codegen + , + org.project.Prefix + OUTFILES + YourProject + + none|objects|all + OUTDIR + OUTFILES + OUTFILES + + FILE + + + + + DECORATOR + HEADER + DEFINE + OUTFILE + + + + ELEMENT + KEY + VALUE + + + VERSION + VERSION + FILE + + FILE + + + + + + Description + + gdbus-codegen is used to generate code and/or + documentation for one or more D-Bus interfaces. + + + gdbus-codegen reads + D-Bus + Introspection XML from files passed as additional + arguments on the command line and generates output files. + It currently supports generating C source code (via + ) or header (via ) + and Docbook XML (via ). Alternatively, + more restricted C source code and headers can be generated, which just + contain the interface information (as GDBusInterfaceInfo + structures) using and + . + + + + + Generating C code + + When generating C code, a + #GInterface-derived type is generated for each D-Bus + interface. Additionally, for every generated type, + FooBar, two concrete instantiatable types, + FooBarProxy and FooBarSkeleton, implementing + said interface are also generated. The former is derived from + #GDBusProxy and intended for use on the client side + while the latter is derived from the + #GDBusInterfaceSkeleton type making it easy to export on a + #GDBusConnection either directly or via a + #GDBusObjectManagerServer instance. + + + For C code generation either that + generates source code, that + generates headers, that generates + interface information source code, or + that generates interface information + headers, can be used. These options must be used along with + , which is used to specify the file to output to. + + + Both files can be generated at the same time by using + , but this option is deprecated. + In this case cannot be used due to the + generation of multiple files. Instead pass + to specify the directory to put + the output files in. By default the current directory will be used. + + + The name of each generated C type is derived from the D-Bus + interface name stripped with the prefix given with + and with the dots removed and + initial characters capitalized. For example, for the D-Bus + interface com.acme.Coyote the name used is + ComAcmeCoyote. For the D-Bus interface + org.project.Bar.Frobnicator with + + org.project., the name used is + BarFrobnicator. + + + For methods, signals and properties, if not specified, the name + defaults to the name of the method, signal or property. + + + Two forms of the name are used - the CamelCase form and the + lower-case form. The CamelCase form is used for the #GType and + struct name, while lower-case form is used in function names. The + lower-case form is calculated by converting from CamelCase to + lower-case and inserting underscores at word boundaries (using + certain heuristics). + + + If the value given by the org.gtk.GDBus.C.Name + annotation or the option contains + an underscore (sometimes called Ugly_Case), + then the camel-case name is derived by removing all underscores, + and the lower-case name is derived by lower-casing the + string. This is useful in some situations where abbreviations are + used. For example, if the annotation is used on the interface + net.MyCorp.MyApp.iSCSITarget with the value + iSCSI_Target the CamelCase form is + iSCSITarget while the lower-case form is + iscsi_target. If the annotation is used on the + method EjectTheiPod with the value + Eject_The_iPod, the lower-case form is + eject_the_ipod. + + + + + Generating Docbook documentation + + Each generated Docbook XML file (see the + option for details) is a RefEntry + article describing the D-Bus interface. + + + + + Generating reStructuredText documentation + + Each generated reStructuredText file (see the + option for details) is a plain text + reStructuredText + document describing the D-Bus interface. + + + + + Options + + The following options are supported: + + + + + , + + + Show help and exit. + + + + + + FILE + + + This option is deprecated; use positional arguments instead. + The D-Bus introspection XML file. + + + + + + org.project.Prefix. + + + A prefix to strip from all D-Bus interface names when + calculating the typename for the C binding and the Docbook + sortas + attribute. + + + + + + OUTFILES + + + Generate Docbook Documentation for each D-Bus interface and + put it in OUTFILES-NAME.xml + where NAME is a place-holder for the interface + name, e.g. net.Corp.FooBar and so on. + + + Pass to specify the directory + to put the output files in. By default the current directory + will be used. + + + + + + OUTFILES + + + Generate reStructuredText Documentation for each D-Bus interface and + put it in OUTFILES-NAME.rst + where NAME is a place-holder for the interface + name, e.g. net.Corp.FooBar and so on. + + + Pass to specify the directory + to put the output files in. By default the current directory + will be used. + + + + + + OUTFILES + + + Generate C code for all D-Bus interfaces and put it in + OUTFILES.c and + OUTFILES.h including any sub-directories. If you want the files to + be output in a different location use as OUTFILES.h + including sub-directories will be referenced from OUTFILES.c. + + + The full paths would then be $(OUTDIR)/$(dirname $OUTFILES)/$(basename $OUTFILES).{c,h}. + + + + + + YourProject + + + The namespace to use for generated C code. This is expected + to be in CamelCase + or Ugly_Case (see above). + + + + + + + + + If this option is passed, the + #pragma once + preprocessor directive is used instead of include guards. + + + + + + + + + If this option is passed, suitable #GDBusObject, + #GDBusObjectProxy, #GDBusObjectSkeleton and + #GDBusObjectManagerClient subclasses are generated. + + + + + + none|objects|all + + + This option influences what types autocleanup functions are + generated for. 'none' means to not generate any autocleanup functions. + 'objects' means to generate them for object types, and 'all' means to + generate them for object types and interfaces. The default is 'objects' + due to a corner case in backwards compatibility with a few projects, + but you should likely switch your project to use 'all'. + This option was added in GLib 2.50. + + + + + + OUTDIR + + + Directory to output generated source to. Equivalent to changing directory before generation. + + + This option cannot be used with , + , or + ; and + must be used. + + + + + + + + + + If this option is passed, it will generate the header code and write it to the disk by + using the path and file name provided by . + + + Using , or + are not allowed to be used along with + and options, because these options + are used to generate only one file. + + + + + + + + + If this option is passed, it will generate the source code and write it to the disk by + using the path and file name provided by . + + + Using , or + are not allowed to be used along with + and options, because these options + are used to generate only one file. + + + + + + + + + If this option is passed, it will generate the header code for the + GDBusInterfaceInfo structures only and will write it to + the disk by using the path and file name provided by + . + + + Using , or + are not allowed to be used along with + the and + options, because these options + are used to generate only one file. + + + + + + + + + If this option is passed, it will generate the source code for the + GDBusInterfaceInfo structures only and will write it to + the disk by using the path and file name provided by + . + + + Using , or + are not allowed to be used along with + the and + options, because these options + are used to generate only one file. + + + + + + DECORATOR + + + If a DECORATOR is passed in with this option, all the + generated function prototypes in the generated header will be marked with + DECORATOR. This can be used, for instance, to export + symbols from code generated with gdbus-codegen. + This option is added in GLib-2.66 + + + + + + HEADER + + + If a HEADER is passed in with this option, the + generated header will put a #include HEADER before the rest of the + items, except for the inclusion guards or #pragma once + (if is used). This is used if using another header file is + needed for the decorator passed in via to be defined. + This option is added in GLib-2.66. + + + This option can only be used if is used. + + + + + + DEFINE + + + If a DEFINE is passed in with this option, the + generated source will add a #define DEFINE before the rest of the + items. This is used if a particular macro is needed to ensure the decorator + passed in via uses the correct definition when the + generated source is being compiled. This option is added in GLib-2.66. + + + This option can only be used if is used. + + + + + + OUTFILE + + + The full path where the header (, + ) or the source code + (, ) will + be written, using the path and filename provided by + . The full path could be something like + $($OUTFILE).{c,h}. + + + Using , or + is not allowed along with + , because the latter is used to generate only one file. + + + + + + ELEMENT KEY VALUE + + + Used to inject D-Bus annotations into the given XML + files. It can be used with interfaces, methods, signals, + properties and arguments in the following way: + + + + Any UTF-8 string can be used for KEY and VALUE. + + + + + + VERSION + + + Specifies the minimum version of GLib which the code generated by + gdbus-codegen can depend on. This may be used to + make backwards-incompatible changes in the output or behaviour of + gdbus-codegen in future, which users may opt in to + by increasing the value they pass for . + If this option is not passed, the output from gdbus-codegen + is guaranteed to be compatible with all versions of GLib from 2.30 + upwards, as that is when gdbus-codegen was first + released. + + + Note that some version parameters introduce incompatible changes: all callers + of the generated code might need to be updated, and if the generated code is part of + a library's API or ABI, then increasing the version parameter can result in an API + or ABI break. + + + The version number must be of the form + MAJOR.MINOR.MICRO, + where all parts are integers. MINOR and + MICRO are optional. The version number may not be smaller + than 2.30. + + + If the version number is 2.64 or greater, the generated code will + have the following features: (1) If a method has h (file + descriptor) parameter(s), a GUnixFDList parameter will exist in the + generated code for it (whereas previously the annotation + org.gtk.GDBus.C.UnixFD was required), and (2) Method call functions will + have two additional arguments to allow the user to specify GDBusCallFlags + and a timeout value, as is possible when using g_dbus_proxy_call(). + + + + + + VERSION + + + Specifies the maximum version of GLib which the code generated by + gdbus-codegen can depend on. This may be used to + ensure that code generated by gdbus-codegen is + compilable with specific older versions of GLib that your software has + to support. + + + The version number must be of the form + MAJOR.MINOR.MICRO, + where all parts are integers. MINOR and + MICRO are optional. The version number must + be greater than or equal to that passed to . + It defaults to the version of GLib which provides this gdbus-codegen. + + + + + + + + + Supported D-Bus Annotations + + The following D-Bus annotations are supported by + gdbus-codegen: + + + + + + org.freedesktop.DBus.Deprecated + + + Can be used on any <interface>, + <method>, + <signal> and + <property> element to specify that + the element is deprecated if its value is + true. Note that this annotation is + defined in the D-Bus + specification and can only assume the values + true and false. In + particular, you cannot specify the version that the element + was deprecated in nor any helpful deprecation message. Such + information should be added to the element documentation + instead. + + + When generating C code, this annotation is used to add + #G_GNUC_DEPRECATED to generated functions for the element. + + + When generating Docbook XML, a deprecation warning will + appear along the documentation for the element. + + + + + + org.gtk.GDBus.Since + + + Can be used on any <interface>, + <method>, + <signal> and + <property> element to specify the + version (any free-form string but compared using a + version-aware sort function) the element appeared in. + + + When generating C code, this field is used to ensure + function pointer order for preserving ABI/API, see . + + + When generating Docbook XML, the value of this tag appears + in the documentation. + + + + + + org.gtk.GDBus.DocString + + + A string with Docbook content for documentation. This annotation can + be used on <interface>, + <method>, + <signal>, + <property> and + <arg> elements. + + + + + + org.gtk.GDBus.DocString.Short + + + A string with Docbook content for short/brief + documentation. This annotation can only be used on + <interface> elements. + + + + + + org.gtk.GDBus.C.Name + + + Can be used on any <interface>, + <method>, + <signal> and + <property> element to specify the + name to use when generating C code. The value is expected to + be in CamelCase + or Ugly_Case (see above). + + + + + + org.gtk.GDBus.C.ForceGVariant + + + If set to a non-empty string, a #GVariant instance will + be used instead of the natural C type. This annotation can + be used on any <arg> and + <property> element. + + + + + + org.gtk.GDBus.C.UnixFD + + + If set to a non-empty string, the generated code will + include parameters to exchange file descriptors using the + #GUnixFDList type. This annotation can be used on + <method> elements. + + + + + + + + As an easier alternative to using the + org.gtk.GDBus.DocString annotation, note that + parser used by gdbus-codegen parses XML + comments in a way similar to gtk-doc: +longer description. + + This is a new paragraph. +--> + + + + + + + + + + + + + + + + +]]> + + + Note that can be used in any inline + documentation bit (e.g. for interfaces, methods, signals and + properties) to set the org.gtk.GDBus.Since + annotation. For the org.gtk.GDBus.DocString + annotation (and inline comments), note that substrings of the form + , + , + and + are all + expanded to links to the respective interface, method, signal and + property. + Additionally, substrings starting with @ and % characters are rendered as + parameter and + constant respectively. + + + If both XML comments and + org.gtk.GDBus.DocString or + org.gtk.GDBus.DocString.Short annotations are + present, the latter wins. + + + + + Example + + Consider the following D-Bus Introspection XML. + + + + + + + + + + + + + + + + + +]]> + + + If gdbus-codegen is used on this file like this: + + + + two files called + myapp-generated.[ch] are + generated. The files provide an abstract + #GTypeInterface-derived type called + MyAppFrobber as well as two instantiatable types with + the same name but suffixed with Proxy and + Skeleton. The generated file, roughly, contains the + following facilities: + + + + Thus, for every D-Bus method, there will be three C functions for + calling the method, one #GObject signal for handling an incoming + call and one C function for completing an incoming call. For every + D-Bus signal, there's one #GObject signal and one C function for + emitting it. For every D-Bus property, two C functions are + generated (one setter, one getter) and one #GObject property. The + following table summarizes the generated facilities and where they + are applicable: + + + + + + + Client + Server + + + + + Types + Use MyAppFrobberProxy + Any type implementing the MyAppFrobber interface + + + Methods + Use m_a_f_hello_world() to call. + Receive via the handle_hello_world() signal handler. Complete the call with m_a_f_complete_hello_world() + + + Signals + Connect to the ::notification GObject signal. + Use m_a_f_emit_notification() to emit signal. + + + Properties (Reading) + Use m_a_f_get_verbose() or :verbose. + Implement #GObject's get_property() vfunc. + + + Properties (writing) + Use m_a_f_set_verbose() or :verbose. + Implement #GObject's set_property() vfunc. + + + + + + + Client-side usage + + You can use the generated proxy type with the generated + constructors: + + + + Instead of using the generic #GDBusProxy facilities, one can use + the generated methods such as + my_app_frobber_call_hello_world() to invoke + the net.Corp.MyApp.Frobber.HelloWorld() + D-Bus method, connect to the + ::notification GObject signal to receive + the net.Corp.MyApp.Frobber::Notification + D-Bus signal and get/set the + net.Corp.MyApp.Frobber:Verbose D-Bus + Property using either the GObject property + :verbose or the + my_app_get_verbose() and + my_app_set_verbose() methods. Use the + standard #GObject::notify signal to listen to property changes. + + + Note that all property access is via #GDBusProxy's + property cache so no I/O is ever done when reading properties. + Also note that setting a property will cause the + org.freedesktop.DBus.Properties.Set method to be + called on the remote object. This call, however, is asynchronous + so setting a property won't block. Further, the change is + delayed and no error checking is possible. + + + + + Server-side usage + + The generated MyAppFrobber interface is designed so + it is easy to implement it in a #GObject + subclass. For example, to handle + HelloWorld() method invocations, set the + vfunc for handle_hello_hello_world() in the + MyAppFrobberIface structure. Similarly, to handle + the net.Corp.MyApp.Frobber:Verbose + property override the :verbose #GObject + property from the subclass. To emit a signal, use + e.g. my_app_emit_signal() or + g_signal_emit_by_name(). + + + Instead of subclassing, it is often easier to use the generated + MyAppFrobberSkeleton subclass. To handle incoming + method calls, use g_signal_connect() with + the ::handle-* signals and instead of + overriding #GObject's + get_property() and + set_property() vfuncs, use + g_object_get() and + g_object_set() or the generated property + getters and setters (the generated class has an internal + property bag implementation). + + + + To facilitate atomic changesets (multiple properties changing at + the same time), #GObject::notify signals are queued up when + received. The queue is drained in an idle handler (which is called from the + thread-default main loop + of the thread where the skeleton object was + constructed) and will cause emissions of the org.freedesktop.DBus.Properties::PropertiesChanged + signal with all the properties that have changed. Use + g_dbus_interface_skeleton_flush() or + g_dbus_object_skeleton_flush() to empty the queue + immediately. Use g_object_freeze_notify() and + g_object_thaw_notify() for atomic changesets if on a different + thread. + + + + + + C Type Mapping + + Scalar types + (type-strings + 'b', + 'y', + 'n', + 'q', + 'i', + 'u', + 'x', + 't' and + 'd') + ), + strings (type-strings + 's', + 'ay', + 'o' and + 'g') and + arrays of string (type-strings + 'as', + 'ao' and + 'aay') + are mapped to the natural types, + e.g. #gboolean, #gdouble, #gint, gchar*, + gchar** and + so on. Everything else is mapped to the #GVariant + type. + + + This automatic mapping can be turned off by using the annotation + org.gtk.GDBus.C.ForceGVariant - if used then a + #GVariant is always exchanged instead of the + corresponding native C type. This annotation may be convenient to + use when using + bytestrings (type-string 'ay') + for data that could have embedded NUL bytes. + + + + + Stability Guarantees + + The generated C functions are guaranteed to not change their ABI + that is, if a method, signal or property does not change its + signature in the introspection XML, the generated C functions will + not change its C ABI either. The ABI of the generated instance and + class structures will be preserved as well. + + + The ABI of the generated #GTypes will be preserved only if + the org.gtk.GDBus.Since annotation is used + judiciously — this is because the VTable for the #GInterface + relies on functions pointers for signal handlers. Specifically, if + a D-Bus method, property or signal or is added to a D-Bus + interface, then ABI of the generated #GInterface type is preserved + if, and only if, each added method, property signal is annotated + with they org.gtk.GDBus.Since annotation using + a greater version number than previous versions. + + + The generated C code currently happens to be annotated with gtk-doc / GObject + Introspection comments / annotations. The layout and + contents might change in the future so no guarantees about + e.g. SECTION usage etc. is given. + + + While the generated Docbook for D-Bus interfaces isn't expected to + change, no guarantees are given at this point. + + + It is important to note that the generated code should not be + checked into revision control systems, nor it should be included + in distributed source archives. + + + + + Bugs + + Please send bug reports to either the distribution bug tracker + or the upstream bug tracker at + https://gitlab.gnome.org/GNOME/glib/issues/new. + + + + + See also + + + gdbus1 + + + + + diff --git a/docs/reference/gio/gdbus-object-manager-example/.gitignore b/docs/reference/gio/gdbus-object-manager-example/.gitignore new file mode 100644 index 0000000..cc8a11d --- /dev/null +++ b/docs/reference/gio/gdbus-object-manager-example/.gitignore @@ -0,0 +1 @@ +gdbus-object-manager-example-overrides.txt diff --git a/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-docs.xml b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-docs.xml new file mode 100644 index 0000000..fd4c307 --- /dev/null +++ b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-docs.xml @@ -0,0 +1,19 @@ + + +]> + + + GDBus ObjctManager Example + + Interfaces + + + + + + + + + diff --git a/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.txt b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.txt new file mode 100644 index 0000000..1e3b8b8 --- /dev/null +++ b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.txt @@ -0,0 +1,161 @@ +
+ExampleAnimal +ExampleAnimal +ExampleAnimal +ExampleAnimalIface +example_animal_interface_info +example_animal_override_properties +example_animal_call_poke +example_animal_call_poke_finish +example_animal_call_poke_sync +example_animal_complete_poke +example_animal_emit_jumped +example_animal_get_mood +example_animal_get_foo +example_animal_get_bar +example_animal_dup_mood +example_animal_dup_foo +example_animal_dup_bar +example_animal_set_mood +example_animal_set_foo +example_animal_set_bar +ExampleAnimalProxy +ExampleAnimalProxyClass +example_animal_proxy_new +example_animal_proxy_new_finish +example_animal_proxy_new_sync +example_animal_proxy_new_for_bus +example_animal_proxy_new_for_bus_finish +example_animal_proxy_new_for_bus_sync +ExampleAnimalSkeleton +ExampleAnimalSkeletonClass +example_animal_skeleton_new + +example_animal_get_type +example_animal_proxy_get_type +example_animal_skeleton_get_type +ExampleAnimalSkeletonPrivate +ExampleAnimalProxyPrivate +EXAMPLE_TYPE_ANIMAL +EXAMPLE_TYPE_ANIMAL_PROXY +EXAMPLE_TYPE_ANIMAL_SKELETON +EXAMPLE_ANIMAL +EXAMPLE_ANIMAL_GET_IFACE +EXAMPLE_ANIMAL_PROXY +EXAMPLE_ANIMAL_PROXY_CLASS +EXAMPLE_ANIMAL_PROXY_GET_CLASS +EXAMPLE_ANIMAL_SKELETON +EXAMPLE_ANIMAL_SKELETON_CLASS +EXAMPLE_ANIMAL_SKELETON_GET_CLASS +EXAMPLE_IS_ANIMAL +EXAMPLE_IS_ANIMAL_PROXY +EXAMPLE_IS_ANIMAL_PROXY_CLASS +EXAMPLE_IS_ANIMAL_SKELETON +EXAMPLE_IS_ANIMAL_SKELETON_CLASS +
+ +
+ExampleCat +ExampleCat +ExampleCat +ExampleCatIface +example_cat_interface_info +example_cat_override_properties +ExampleCatProxy +ExampleCatProxyClass +example_cat_proxy_new +example_cat_proxy_new_finish +example_cat_proxy_new_sync +example_cat_proxy_new_for_bus +example_cat_proxy_new_for_bus_finish +example_cat_proxy_new_for_bus_sync +ExampleCatSkeleton +ExampleCatSkeletonClass +example_cat_skeleton_new + +example_cat_get_type +example_cat_proxy_get_type +example_cat_skeleton_get_type +ExampleCatProxyPrivate +ExampleCatSkeletonPrivate +EXAMPLE_TYPE_CAT +EXAMPLE_TYPE_CAT_PROXY +EXAMPLE_TYPE_CAT_SKELETON +EXAMPLE_CAT +EXAMPLE_CAT_GET_IFACE +EXAMPLE_CAT_PROXY +EXAMPLE_CAT_PROXY_CLASS +EXAMPLE_CAT_PROXY_GET_CLASS +EXAMPLE_CAT_SKELETON +EXAMPLE_CAT_SKELETON_CLASS +EXAMPLE_CAT_SKELETON_GET_CLASS +EXAMPLE_IS_CAT +EXAMPLE_IS_CAT_PROXY +EXAMPLE_IS_CAT_PROXY_CLASS +EXAMPLE_IS_CAT_SKELETON +EXAMPLE_IS_CAT_SKELETON_CLASS +
+ +
+ExampleObject +ExampleObject +ExampleObject +ExampleObjectIface +example_object_get_animal +example_object_get_cat +example_object_peek_animal +example_object_peek_cat +ExampleObjectProxy +ExampleObjectProxyClass +example_object_proxy_new +ExampleObjectSkeleton +ExampleObjectSkeletonClass +example_object_skeleton_new +example_object_skeleton_set_animal +example_object_skeleton_set_cat + +example_object_get_type +example_object_proxy_get_type +example_object_skeleton_get_type +ExampleObjectProxyPrivate +ExampleObjectSkeletonPrivate +EXAMPLE_IS_OBJECT +EXAMPLE_IS_OBJECT_PROXY +EXAMPLE_IS_OBJECT_PROXY_CLASS +EXAMPLE_IS_OBJECT_SKELETON +EXAMPLE_IS_OBJECT_SKELETON_CLASS +EXAMPLE_OBJECT +EXAMPLE_OBJECT_GET_IFACE +EXAMPLE_OBJECT_PROXY +EXAMPLE_OBJECT_PROXY_CLASS +EXAMPLE_OBJECT_PROXY_GET_CLASS +EXAMPLE_OBJECT_SKELETON +EXAMPLE_OBJECT_SKELETON_CLASS +EXAMPLE_OBJECT_SKELETON_GET_CLASS +EXAMPLE_TYPE_OBJECT +EXAMPLE_TYPE_OBJECT_PROXY +EXAMPLE_TYPE_OBJECT_SKELETON +
+ +
+ExampleObjectManagerClient +ExampleObjectManagerClient +ExampleObjectManagerClient +ExampleObjectManagerClientClass +example_object_manager_client_get_proxy_type +example_object_manager_client_new +example_object_manager_client_new_finish +example_object_manager_client_new_sync +example_object_manager_client_new_for_bus +example_object_manager_client_new_for_bus_finish +example_object_manager_client_new_for_bus_sync + +example_object_manager_client_get_type +EXAMPLE_IS_OBJECT_MANAGER_CLIENT +EXAMPLE_IS_OBJECT_MANAGER_CLIENT_CLASS +EXAMPLE_OBJECT_MANAGER_CLIENT +EXAMPLE_OBJECT_MANAGER_CLIENT_CLASS +EXAMPLE_OBJECT_MANAGER_CLIENT_GET_CLASS +EXAMPLE_TYPE_OBJECT_MANAGER_CLIENT +ExampleObjectManagerClientPrivate +
diff --git a/docs/reference/gio/gdbus-object-manager-example/meson.build b/docs/reference/gio/gdbus-object-manager-example/meson.build new file mode 100644 index 0000000..13cae5b --- /dev/null +++ b/docs/reference/gio/gdbus-object-manager-example/meson.build @@ -0,0 +1,11 @@ +gdbus_object_manager_example_doc = gnome.gtkdoc('gdbus-object-manager-example', + main_xml : 'gdbus-object-manager-example-docs.xml', + namespace : 'example', + dependencies : [libgdbus_example_objectmanager_dep], + src_dir : 'gio/tests/gdbus-object-manager-example', + scan_args : gtkdoc_common_scan_args + [ + '--rebuild-types', + ], + install : false, +) + diff --git a/docs/reference/gio/gdbus.xml b/docs/reference/gio/gdbus.xml new file mode 100644 index 0000000..60c172e --- /dev/null +++ b/docs/reference/gio/gdbus.xml @@ -0,0 +1,429 @@ + + + + gdbus + GIO + + + Developer + David + Zeuthen + zeuthen@gmail.com + + + + + + gdbus + 1 + User Commands + + + + gdbus + Tool for working with D-Bus objects + + + + + gdbus + introspect + + --system + --session + --address address + + --dest bus_name + --object-path /path/to/object + + --xml + + + --recurse + + + --only-properties + + + + gdbus + monitor + + --system + --session + --address address + + --dest bus_name + + --object-path /path/to/object + + + + gdbus + call + + --system + --session + --address address + + --dest bus_name + --object-path /path/to/object + --method org.project.InterfaceName.MethodName + + --timeout seconds + --interactive + + ARG1 + ARG2 + + + gdbus + emit + + --system + --session + --address address + + --object-path /path/to/object + --signal org.project.InterfaceName.SignalName + + --dest unique_bus_name + + ARG1 + ARG2 + + + gdbus + wait + + --system + --session + --address address + + --activate bus_name + + --timeout seconds + + bus_name + + + gdbus + help + + + + + Description + + gdbus is a simple tool for working with D-Bus objects. + + + + Commands + + + + + Prints out interfaces and property values for a remote object. + For this to work, the owner of the object needs to implement the + org.freedesktop.DBus.Introspectable interface. + If the option is used, the returned + introspection XML is printed, otherwise a parsed pretty + representation is printed. + The option can be used to + introspect children (and their children and so on) and the + option can be used to + only print the interfaces with properties. + + + + + + Monitors one or all objects owned by the owner of + bus_name. + + + + + + Invokes a method on a remote object. Each argument to pass to the + method must be specified as a serialized + GVariant except that strings do + not need explicit quotes. The return values are printed out as + serialized GVariant + values. + + + + + + Emits a signal. Each argument to include in the signal must be specified as a serialized + GVariant except that strings do + not need explicit quotes. + + + + + + Waits until bus_name is owned by some + process on the bus. If the is specified, + that bus name will be auto-started first. It may be the same as the + bus name being waited for, or different. + + + + + + Prints help and exit. + + + + + + + Bash Completion + + gdbus ships with a bash completion script to + complete commands, destinations, bus names, object paths and + interface/method names. + + + + + Examples + This shows how to introspect an object - note that the value of each + property is displayed: + +$ gdbus introspect --system \ + --dest org.freedesktop.NetworkManager \ + --object-path /org/freedesktop/NetworkManager/Devices/0 +node /org/freedesktop/NetworkManager/Devices/0 { + interface org.freedesktop.DBus.Introspectable { + methods: + Introspect(out s data); + }; + interface org.freedesktop.DBus.Properties { + methods: + Get(in s interface, + in s propname, + out v value); + Set(in s interface, + in s propname, + in v value); + GetAll(in s interface, + out a{sv} props); + }; + interface org.freedesktop.NetworkManager.Device.Wired { + signals: + PropertiesChanged(a{sv} arg_0); + properties: + readonly b Carrier = false; + readonly u Speed = 0; + readonly s HwAddress = '00:1D:72:88:BE:97'; + }; + interface org.freedesktop.NetworkManager.Device { + methods: + Disconnect(); + signals: + StateChanged(u arg_0, + u arg_1, + u arg_2); + properties: + readonly u DeviceType = 1; + readonly b Managed = true; + readwrite o Ip6Config = '/'; + readwrite o Dhcp4Config = '/'; + readwrite o Ip4Config = '/'; + readonly u State = 2; + readwrite u Ip4Address = 0; + readonly u Capabilities = 3; + readonly s Driver = 'e1000e'; + readwrite s Interface = 'eth0'; + readonly s Udi = '/sys/devices/pci0000:00/0000:00:19.0/net/eth0'; + }; +}; + + + The and options can be useful when wanting to inspect all objects owned by a particular process: + + +$ gdbus introspect --system --dest org.freedesktop.UPower --object-path / --recurse --only-properties +node / { + node /org { + node /org/freedesktop { + node /org/freedesktop/UPower { + interface org.freedesktop.UPower { + properties: + readonly b IsDocked = true; + readonly b LidForceSleep = false; + readonly b LidIsPresent = false; + readonly b LidIsClosed = false; + readonly b OnLowBattery = false; + readonly b OnBattery = false; + readonly b CanHibernate = true; + readonly b CanSuspend = true; + readonly s DaemonVersion = '0.9.10'; + }; + node /org/freedesktop/UPower/Policy { + }; + node /org/freedesktop/UPower/Wakeups { + interface org.freedesktop.UPower.Wakeups { + properties: + readonly b HasCapability = true; + }; + }; + }; + }; + }; +}; + + + In a similar fashion, the command can be + used to learn details about the Notify method: + + +[...] + interface org.freedesktop.Notifications { + methods: + GetServerInformation(out s return_name, + out s return_vendor, + out s return_version, + out s return_spec_version); + GetCapabilities(out as return_caps); + CloseNotification(in u id); + Notify(in s app_name, + in u id, + in s icon, + in s summary, + in s body, + in as actions, + in a{sv} hints, + in i timeout, + out u return_id); + }; +[...] + + + With this information, it's easy to use the + command to display a notification + + +$ gdbus call --session \ + --dest org.freedesktop.Notifications \ + --object-path /org/freedesktop/Notifications \ + --method org.freedesktop.Notifications.Notify \ + my_app_name \ + 42 \ + gtk-dialog-info \ + "The Summary" \ + "Here's the body of the notification" \ + [] \ + {} \ + 5000 +(uint32 12,) + + + Call a method with file handle argument: + + +$ gdbus call --session \ + --dest org.example.foo \ + --object-path /org/example/foo \ + --method SendFDs \ + 1 \ + 10 \ + 10<file.foo + + + Monitoring all objects on a service: + + +$ gdbus monitor --system --dest org.freedesktop.ConsoleKit +Monitoring signals from all objects owned by org.freedesktop.ConsoleKit +The name org.freedesktop.ConsoleKit is owned by :1.15 +/org/freedesktop/ConsoleKit/Session2: org.freedesktop.ConsoleKit.Session.ActiveChanged (false,) +/org/freedesktop/ConsoleKit/Seat1: org.freedesktop.ConsoleKit.Seat.ActiveSessionChanged ('',) +/org/freedesktop/ConsoleKit/Session2: org.freedesktop.ConsoleKit.Session.ActiveChanged (true,) +/org/freedesktop/ConsoleKit/Seat1: org.freedesktop.ConsoleKit.Seat.ActiveSessionChanged ('/org/freedesktop/ConsoleKit/Session2',) + + + Monitoring a single object on a service: + + +$ gdbus monitor --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/AccessPoint/4141 +Monitoring signals on object /org/freedesktop/NetworkManager/AccessPoint/4141 owned by org.freedesktop.NetworkManager +The name org.freedesktop.NetworkManager is owned by :1.5 +/org/freedesktop/NetworkManager/AccessPoint/4141: org.freedesktop.NetworkManager.AccessPoint.PropertiesChanged ({'Strength': <byte 0x5c>},) +/org/freedesktop/NetworkManager/AccessPoint/4141: org.freedesktop.NetworkManager.AccessPoint.PropertiesChanged ({'Strength': <byte 0x64>},) +/org/freedesktop/NetworkManager/AccessPoint/4141: org.freedesktop.NetworkManager.AccessPoint.PropertiesChanged ({'Strength': <byte 0x5e>},) +/org/freedesktop/NetworkManager/AccessPoint/4141: org.freedesktop.NetworkManager.AccessPoint.PropertiesChanged ({'Strength': <byte 0x64>},) + + + + Emitting a signal: + + +$ gdbus emit --session --object-path /foo --signal org.bar.Foo "['foo', 'bar', 'baz']" + + + + Emitting a signal to a specific process: + + +$ gdbus emit --session --object-path /bar --signal org.bar.Bar someString --dest :1.42 + + + + Waiting for a well-known name to be owned on the bus; this will + not auto-start the service: + + +$ gdbus wait --session org.bar.SomeName + + + + Auto-starting then waiting for a well-known name to be owned on the bus: + + +$ gdbus wait --session --activate org.bar.SomeName + + + + Auto-starting a different service, then waiting for a well-known name to be + owned on the bus. This is useful in situations where + SomeName is not directly activatable: + + +$ gdbus wait --session --activate org.bar.PrerequisiteName org.bar.SomeName + + + + Waiting for a well-known name and giving up after 30 seconds. By default, + the timeout is disabled; or set to 0 to disable it: + + +$ gdbus wait --session --timeout 30 org.bar.SomeName + + + + + + Bugs + + Please send bug reports to either the distribution bug tracker + or the upstream bug tracker at + . + + + + + See Also + + + dbus-send1 + + + + + + diff --git a/docs/reference/gio/gio-docs-unix.xml b/docs/reference/gio/gio-docs-unix.xml new file mode 100644 index 0000000..b78edda --- /dev/null +++ b/docs/reference/gio/gio-docs-unix.xml @@ -0,0 +1,3 @@ + + + diff --git a/docs/reference/gio/gio-docs-win32.xml b/docs/reference/gio/gio-docs-win32.xml new file mode 100644 index 0000000..f34a6e6 --- /dev/null +++ b/docs/reference/gio/gio-docs-win32.xml @@ -0,0 +1,6 @@ + + Win32 support + + + + diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml new file mode 100644 index 0000000..76057e8 --- /dev/null +++ b/docs/reference/gio/gio-docs.xml @@ -0,0 +1,406 @@ + + + +]> + +GIO Reference Manual + + GIO Reference Manual + + for GIO &version; + The latest version of this documentation can be found on-line at + https://developer.gnome.org/gio/unstable/. + + + + + + + API Reference + + File Operations + + + + + + + + + File System Monitoring + + + + File-related Utilities + + + + Asynchronous I/O + + + + + + + + Data conversion + + + + + + + Streaming I/O + + + + + + + + + + + + + + + + + + + + + + + + + + + File types and applications + + + + + + + Volumes and Drives + + + + + + + + Icons + + + + + + + + + + Failable Initialization + + + + + Subprocesses + + + + + Low-level network support + + + + + + + + + + + + + + + + + + + High-level network functionality + + + + + + + + + + + + TLS (SSL) support + + + + + + + + + + + + + + + + DNS resolution + + + + + + + + + + + + Low-level D-Bus Support + + + + + + + + + + + + High-level D-Bus Support + + + + + + + + + + + + + + Settings + + + + + + Resources + + + + Permissions + + + + + Data Models + + + + + + Application support + + + + + + + + + + + + + + + + + + + + + + + Extending GIO + + + + + + GIO Tools + + + + + + + + + + + + GIO Testing + + + + + + + Migrating to GIO + + + + + + + + Object Hierarchy + + + + + Index + + + + Index of deprecated symbols + + + + Index of new symbols in 2.18 + + + + Index of new symbols in 2.20 + + + + Index of new symbols in 2.22 + + + + Index of new symbols in 2.24 + + + + Index of new symbols in 2.26 + + + + Index of new symbols in 2.28 + + + + Index of new symbols in 2.30 + + + + Index of new symbols in 2.32 + + + + Index of new symbols in 2.34 + + + + Index of new symbols in 2.36 + + + + Index of new symbols in 2.38 + + + + Index of new symbols in 2.40 + + + + Index of new symbols in 2.42 + + + + Index of new symbols in 2.44 + + + + Index of new symbols in 2.46 + + + + Index of new symbols in 2.48 + + + + Index of new symbols in 2.50 + + + + Index of new symbols in 2.52 + + + + Index of new symbols in 2.54 + + + + Index of new symbols in 2.56 + + + + Index of new symbols in 2.58 + + + + Index of new symbols in 2.60 + + + + Index of new symbols in 2.62 + + + + Index of new symbols in 2.64 + + + + Index of new symbols in 2.66 + + + + Index of new symbols in 2.68 + + + + Index of new symbols in 2.70 + + + + Index of new symbols in 2.72 + + + + + + diff --git a/docs/reference/gio/gio-querymodules.xml b/docs/reference/gio/gio-querymodules.xml new file mode 100644 index 0000000..c9c5eec --- /dev/null +++ b/docs/reference/gio/gio-querymodules.xml @@ -0,0 +1,45 @@ + + + + glib-compile-schemas + GIO + + + Developer + Alexander + Larsson + + + + + + gio-querymodules + 1 + User Commands + + + + gio-querymodules + GIO module cache creation + + + + + gio-querymodules + DIRECTORY + + + +Description +gio-querymodules creates a +giomodule.cache file in the listed directories. +This file lists the implemented extension points for each module +that has been found. It is used by GIO at runtime to avoid opening +all modules just to find out which extension points they are implementing. + + +GIO modules are usually installed in the gio/modules +subdirectory of libdir. + + + diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt new file mode 100644 index 0000000..4e88a59 --- /dev/null +++ b/docs/reference/gio/gio-sections-common.txt @@ -0,0 +1,4772 @@ +
+ginitable +GInitable +GInitable +GInitableIface +g_initable_init +g_initable_new +g_initable_new_valist +g_initable_newv + +G_INITABLE +G_INITABLE_GET_IFACE +G_IS_INITABLE +G_TYPE_INITABLE +G_TYPE_IS_INITABLE + +g_initable_get_type +
+ +
+gasyncinitable +GAsyncInitable +GAsyncInitable +GAsyncInitableIface +g_async_initable_init_async +g_async_initable_init_finish +g_async_initable_new_async +g_async_initable_new_finish +g_async_initable_new_valist_async +g_async_initable_newv_async + +G_ASYNC_INITABLE +G_ASYNC_INITABLE_GET_IFACE +G_IS_ASYNC_INITABLE +G_TYPE_ASYNC_INITABLE +G_TYPE_IS_ASYNC_INITABLE + +g_async_initable_get_type +
+ +
+gvfs +GVfs +GVfs +GVfsFileLookupFunc +G_VFS_EXTENSION_POINT_NAME +g_vfs_get_file_for_path +g_vfs_get_file_for_uri +g_vfs_parse_name +g_vfs_get_default +g_vfs_get_local +g_vfs_is_active +g_vfs_get_supported_uri_schemes +g_vfs_register_uri_scheme +g_vfs_unregister_uri_scheme + +GVfsClass +G_VFS +G_IS_VFS +G_TYPE_VFS +G_VFS_CLASS +G_IS_VFS_CLASS +G_VFS_GET_CLASS + +g_vfs_get_type +
+ +
+gfile +GFile +GFile +GFileIface +GFileQueryInfoFlags +GFileCreateFlags +GFileCopyFlags +GFileMonitorFlags +GFileMeasureFlags +GFilesystemPreviewType +GFileProgressCallback +GFileReadMoreCallback +GFileMeasureProgressCallback +g_file_new_for_path +g_file_new_for_uri +g_file_new_for_commandline_arg +g_file_new_for_commandline_arg_and_cwd +g_file_new_tmp +g_file_parse_name +g_file_new_build_filename +g_file_dup +g_file_hash +g_file_equal +g_file_get_basename +g_file_get_path +g_file_peek_path +g_file_get_uri +g_file_get_parse_name +g_file_get_parent +g_file_has_parent +g_file_get_child +g_file_get_child_for_display_name +g_file_has_prefix +g_file_get_relative_path +g_file_resolve_relative_path +g_file_is_native +g_file_has_uri_scheme +g_file_get_uri_scheme +g_file_read +g_file_read_async +g_file_read_finish +g_file_append_to +g_file_create +g_file_replace +g_file_append_to_async +g_file_append_to_finish +g_file_create_async +g_file_create_finish +g_file_replace_async +g_file_replace_finish +g_file_query_info +g_file_query_info_async +g_file_query_info_finish +g_file_query_exists +g_file_query_file_type +g_file_query_filesystem_info +g_file_query_filesystem_info_async +g_file_query_filesystem_info_finish +g_file_query_default_handler +g_file_query_default_handler_async +g_file_query_default_handler_finish +g_file_measure_disk_usage +g_file_measure_disk_usage_async +g_file_measure_disk_usage_finish +g_file_find_enclosing_mount +g_file_find_enclosing_mount_async +g_file_find_enclosing_mount_finish +g_file_enumerate_children +g_file_enumerate_children_async +g_file_enumerate_children_finish +g_file_set_display_name +g_file_set_display_name_async +g_file_set_display_name_finish +g_file_delete +g_file_delete_async +g_file_delete_finish +g_file_trash +g_file_trash_async +g_file_trash_finish +g_file_copy +g_file_copy_async +g_file_copy_finish +g_file_move +g_file_move_async +g_file_move_finish +g_file_make_directory +g_file_make_directory_async +g_file_make_directory_finish +g_file_make_directory_with_parents +g_file_make_symbolic_link +g_file_query_settable_attributes +g_file_query_writable_namespaces +g_file_set_attribute +g_file_set_attributes_from_info +g_file_set_attributes_async +g_file_set_attributes_finish +g_file_set_attribute_string +g_file_set_attribute_byte_string +g_file_set_attribute_uint32 +g_file_set_attribute_int32 +g_file_set_attribute_uint64 +g_file_set_attribute_int64 +g_file_mount_mountable +g_file_mount_mountable_finish +g_file_unmount_mountable +g_file_unmount_mountable_finish +g_file_unmount_mountable_with_operation +g_file_unmount_mountable_with_operation_finish +g_file_eject_mountable +g_file_eject_mountable_finish +g_file_eject_mountable_with_operation +g_file_eject_mountable_with_operation_finish +g_file_start_mountable +g_file_start_mountable_finish +g_file_stop_mountable +g_file_stop_mountable_finish +g_file_poll_mountable +g_file_poll_mountable_finish +g_file_mount_enclosing_volume +g_file_mount_enclosing_volume_finish +g_file_monitor_directory +g_file_monitor_file +g_file_monitor +g_file_load_bytes +g_file_load_bytes_async +g_file_load_bytes_finish +g_file_load_contents +g_file_load_contents_async +g_file_load_contents_finish +g_file_load_partial_contents_async +g_file_load_partial_contents_finish +g_file_replace_contents +g_file_replace_contents_async +g_file_replace_contents_bytes_async +g_file_replace_contents_finish +g_file_build_attribute_list_for_copy +g_file_copy_attributes +g_file_create_readwrite +g_file_create_readwrite_async +g_file_create_readwrite_finish +g_file_open_readwrite +g_file_open_readwrite_async +g_file_open_readwrite_finish +g_file_replace_readwrite +g_file_replace_readwrite_async +g_file_replace_readwrite_finish +g_file_supports_thread_contexts + +G_FILE +G_IS_FILE +G_TYPE_FILE +G_FILE_GET_IFACE +G_TYPE_FILESYSTEM_PREVIEW_TYPE +G_TYPE_FILE_COPY_FLAGS +G_TYPE_FILE_CREATE_FLAGS +G_TYPE_FILE_MEASURE_FLAGS +G_TYPE_FILE_MONITOR_EVENT +G_TYPE_FILE_MONITOR_FLAGS +G_TYPE_FILE_QUERY_INFO_FLAGS + +g_file_get_type +g_file_copy_flags_get_type +g_file_create_flags_get_type +g_file_measure_flags_get_type +g_file_monitor_event_get_type +g_file_monitor_flags_get_type +g_file_query_info_flags_get_type +g_filesystem_preview_type_get_type +
+ +
+gfileenumerator +GFileEnumerator +GFileEnumerator +g_file_enumerator_iterate +g_file_enumerator_next_file +g_file_enumerator_close +g_file_enumerator_next_files_async +g_file_enumerator_next_files_finish +g_file_enumerator_close_async +g_file_enumerator_close_finish +g_file_enumerator_is_closed +g_file_enumerator_has_pending +g_file_enumerator_set_pending +g_file_enumerator_get_container +g_file_enumerator_get_child + +GFileEnumeratorClass +G_FILE_ENUMERATOR +G_IS_FILE_ENUMERATOR +G_TYPE_FILE_ENUMERATOR +G_FILE_ENUMERATOR_CLASS +G_IS_FILE_ENUMERATOR_CLASS +G_FILE_ENUMERATOR_GET_CLASS + +g_file_enumerator_get_type +GFileEnumeratorPrivate +
+ +
+gfileinfo +GFileInfo +GFileAttributeMatcher +GFileType +GFileInfo +G_FILE_ATTRIBUTE_STANDARD_TYPE +G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN +G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP +G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK +G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL +G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE +G_FILE_ATTRIBUTE_STANDARD_NAME +G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME +G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME +G_FILE_ATTRIBUTE_STANDARD_COPY_NAME +G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION +G_FILE_ATTRIBUTE_STANDARD_ICON +G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON +G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE +G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE +G_FILE_ATTRIBUTE_STANDARD_SIZE +G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE +G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET +G_FILE_ATTRIBUTE_STANDARD_TARGET_URI +G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER +G_FILE_ATTRIBUTE_ETAG_VALUE +G_FILE_ATTRIBUTE_ID_FILE +G_FILE_ATTRIBUTE_ID_FILESYSTEM +G_FILE_ATTRIBUTE_ACCESS_CAN_READ +G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE +G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE +G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE +G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH +G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME +G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT +G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT +G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT +G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE +G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE_FILE +G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI +G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START +G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START_DEGRADED +G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP +G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE +G_FILE_ATTRIBUTE_MOUNTABLE_CAN_POLL +G_FILE_ATTRIBUTE_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC +G_FILE_ATTRIBUTE_TIME_MODIFIED +G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC +G_FILE_ATTRIBUTE_TIME_ACCESS +G_FILE_ATTRIBUTE_TIME_ACCESS_USEC +G_FILE_ATTRIBUTE_TIME_CHANGED +G_FILE_ATTRIBUTE_TIME_CHANGED_USEC +G_FILE_ATTRIBUTE_TIME_CREATED +G_FILE_ATTRIBUTE_TIME_CREATED_USEC +G_FILE_ATTRIBUTE_UNIX_DEVICE +G_FILE_ATTRIBUTE_UNIX_INODE +G_FILE_ATTRIBUTE_UNIX_MODE +G_FILE_ATTRIBUTE_UNIX_NLINK +G_FILE_ATTRIBUTE_UNIX_UID +G_FILE_ATTRIBUTE_UNIX_GID +G_FILE_ATTRIBUTE_UNIX_RDEV +G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE +G_FILE_ATTRIBUTE_UNIX_BLOCKS +G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT +G_FILE_ATTRIBUTE_DOS_IS_ARCHIVE +G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT +G_FILE_ATTRIBUTE_DOS_IS_SYSTEM +G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG +G_FILE_ATTRIBUTE_OWNER_USER +G_FILE_ATTRIBUTE_OWNER_USER_REAL +G_FILE_ATTRIBUTE_OWNER_GROUP +G_FILE_ATTRIBUTE_THUMBNAIL_PATH +G_FILE_ATTRIBUTE_THUMBNAILING_FAILED +G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID +G_FILE_ATTRIBUTE_PREVIEW_ICON +G_FILE_ATTRIBUTE_FILESYSTEM_SIZE +G_FILE_ATTRIBUTE_FILESYSTEM_FREE +G_FILE_ATTRIBUTE_FILESYSTEM_USED +G_FILE_ATTRIBUTE_FILESYSTEM_TYPE +G_FILE_ATTRIBUTE_FILESYSTEM_READONLY +G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW +G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE +G_FILE_ATTRIBUTE_GVFS_BACKEND +G_FILE_ATTRIBUTE_SELINUX_CONTEXT +G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT +G_FILE_ATTRIBUTE_TRASH_ORIG_PATH +G_FILE_ATTRIBUTE_TRASH_DELETION_DATE +G_FILE_ATTRIBUTE_RECENT_MODIFIED +g_file_info_new +g_file_info_dup +g_file_info_copy_into +g_file_info_has_attribute +g_file_info_has_namespace +g_file_info_list_attributes +g_file_info_get_attribute_type +g_file_info_remove_attribute +g_file_info_get_attribute_as_string +g_file_info_get_attribute_data +g_file_info_get_attribute_status +g_file_info_get_attribute_string +g_file_info_get_attribute_stringv +g_file_info_get_attribute_byte_string +g_file_info_get_attribute_boolean +g_file_info_get_attribute_uint32 +g_file_info_get_attribute_int32 +g_file_info_get_attribute_uint64 +g_file_info_get_attribute_int64 +g_file_info_get_attribute_object +g_file_info_set_attribute +g_file_info_set_attribute_status +g_file_info_set_attribute_string +g_file_info_set_attribute_stringv +g_file_info_set_attribute_byte_string +g_file_info_set_attribute_boolean +g_file_info_set_attribute_uint32 +g_file_info_set_attribute_int32 +g_file_info_set_attribute_uint64 +g_file_info_set_attribute_int64 +g_file_info_set_attribute_object +g_file_info_clear_status +g_file_info_get_file_type +g_file_info_get_is_hidden +g_file_info_get_is_backup +g_file_info_get_is_symlink +g_file_info_get_name +g_file_info_get_display_name +g_file_info_get_edit_name +g_file_info_get_icon +g_file_info_get_symbolic_icon +g_file_info_get_content_type +g_file_info_get_size +g_file_info_get_modification_time +g_file_info_get_modification_date_time +g_file_info_get_access_date_time +g_file_info_get_creation_date_time +g_file_info_get_symlink_target +g_file_info_get_etag +g_file_info_get_sort_order +g_file_info_get_deletion_date +g_file_info_set_attribute_mask +g_file_info_unset_attribute_mask +g_file_info_set_file_type +g_file_info_set_is_hidden +g_file_info_set_is_symlink +g_file_info_set_name +g_file_info_set_display_name +g_file_info_set_edit_name +g_file_info_set_icon +g_file_info_set_symbolic_icon +g_file_info_set_content_type +g_file_info_set_size +g_file_info_set_modification_time +g_file_info_set_modification_date_time +g_file_info_set_access_date_time +g_file_info_set_creation_date_time +g_file_info_set_symlink_target +g_file_info_set_sort_order +g_file_attribute_matcher_new +g_file_attribute_matcher_ref +g_file_attribute_matcher_subtract +g_file_attribute_matcher_unref +g_file_attribute_matcher_matches +g_file_attribute_matcher_matches_only +g_file_attribute_matcher_enumerate_namespace +g_file_attribute_matcher_enumerate_next +g_file_attribute_matcher_to_string + +GFileInfoClass +G_FILE_INFO +G_IS_FILE_INFO +G_TYPE_FILE_INFO +G_FILE_INFO_CLASS +G_IS_FILE_INFO_CLASS +G_FILE_INFO_GET_CLASS +g_file_attribute_matcher_get_type +G_TYPE_FILE_TYPE + +g_file_info_get_type +g_file_type_get_type +
+ +
+gfileattribute +GFileAttribute +GFileAttributeType +GFileAttributeInfoFlags +GFileAttributeStatus +GFileAttributeInfo +GFileAttributeInfoList +g_file_attribute_info_list_new +g_file_attribute_info_list_ref +g_file_attribute_info_list_unref +g_file_attribute_info_list_dup +g_file_attribute_info_list_lookup +g_file_attribute_info_list_add + +G_TYPE_FILE_ATTRIBUTE_INFO_FLAGS +G_TYPE_FILE_ATTRIBUTE_INFO_LIST +G_TYPE_FILE_ATTRIBUTE_MATCHER +G_TYPE_FILE_ATTRIBUTE_STATUS +G_TYPE_FILE_ATTRIBUTE_TYPE + +g_file_attribute_info_list_get_type +g_file_attribute_info_flags_get_type +g_file_attribute_status_get_type +g_file_attribute_type_get_type +
+ +
+gfilemonitor +GFileMonitor +GFileMonitorEvent +GFileMonitor +g_file_monitor_cancel +g_file_monitor_is_cancelled +g_file_monitor_set_rate_limit +g_file_monitor_emit_event + +GFileMonitorClass +G_FILE_MONITOR +G_IS_FILE_MONITOR +G_TYPE_FILE_MONITOR +G_FILE_MONITOR_CLASS +G_IS_FILE_MONITOR_CLASS +G_FILE_MONITOR_GET_CLASS + +g_file_monitor_get_type +GFileMonitorPrivate +
+ +
+gicon +GIcon +GIcon +GIconIface +g_icon_hash +g_icon_equal +g_icon_to_string +g_icon_new_for_string +g_icon_serialize +g_icon_deserialize + +G_ICON +G_IS_ICON +G_TYPE_ICON +G_ICON_GET_IFACE + +g_icon_get_type +
+ +
+gthemedicon +GThemedIcon +GThemedIcon +g_themed_icon_new +g_themed_icon_new_from_names +g_themed_icon_new_with_default_fallbacks +g_themed_icon_prepend_name +g_themed_icon_append_name +g_themed_icon_get_names + +GThemedIconClass +G_THEMED_ICON +G_IS_THEMED_ICON +G_TYPE_THEMED_ICON +G_THEMED_ICON_CLASS +G_IS_THEMED_ICON_CLASS +G_THEMED_ICON_GET_CLASS + +g_themed_icon_get_type +
+ +
+gloadableicon +GLoadableIcon +GLoadableIcon +GLoadableIconIface +g_loadable_icon_load +g_loadable_icon_load_async +g_loadable_icon_load_finish + +G_LOADABLE_ICON +G_IS_LOADABLE_ICON +G_TYPE_LOADABLE_ICON +G_LOADABLE_ICON_GET_IFACE + +g_loadable_icon_get_type +
+ +
+gfileicon +GFileIcon +GFileIcon +g_file_icon_new +g_file_icon_get_file + +GFileIconClass +G_FILE_ICON +G_IS_FILE_ICON +G_TYPE_FILE_ICON +G_FILE_ICON_CLASS +G_IS_FILE_ICON_CLASS +G_FILE_ICON_GET_CLASS + +g_file_icon_get_type +
+ +
+gbytesicon +GBytesIcon +GBytesIcon +g_bytes_icon_new +g_bytes_icon_get_bytes + +G_BYTES_ICON +G_IS_BYTES_ICON +G_TYPE_BYTES_ICON + +g_bytes_icon_get_type +
+ +
+gemblemedicon +GEmblemedIcon +GEmblemedIcon +g_emblemed_icon_new +g_emblemed_icon_get_icon +g_emblemed_icon_get_emblems +g_emblemed_icon_add_emblem +g_emblemed_icon_clear_emblems + +GEmblemedIconClass +G_EMBLEMED_ICON +G_EMBLEMED_ICON_CLASS +G_EMBLEMED_ICON_GET_CLASS +G_IS_EMBLEMED_ICON +G_IS_EMBLEMED_ICON_CLASS +G_TYPE_EMBLEMED_ICON + + +GEmblemedIconPrivate +g_emblemed_icon_get_type +
+ +
+gemblem +GEmblem +GEmblem +GEmblemOrigin +g_emblem_new +g_emblem_new_with_origin +g_emblem_get_icon +g_emblem_get_origin + +GEmblemClass +g_emblem_get_type +G_EMBLEM +G_EMBLEM_CLASS +G_EMBLEM_GET_CLASS +G_IS_EMBLEM +G_IS_EMBLEM_CLASS +G_TYPE_EMBLEM +G_TYPE_EMBLEM_ORIGIN +g_emblem_origin_get_type +
+ +
+ginputstream +GInputStream +GInputStream +g_input_stream_read +g_input_stream_read_all +g_input_stream_read_all_async +g_input_stream_read_all_finish +g_input_stream_skip +g_input_stream_close +g_input_stream_read_async +g_input_stream_read_finish +g_input_stream_skip_async +g_input_stream_skip_finish +g_input_stream_close_async +g_input_stream_close_finish +g_input_stream_is_closed +g_input_stream_has_pending +g_input_stream_set_pending +g_input_stream_clear_pending +g_input_stream_read_bytes +g_input_stream_read_bytes_async +g_input_stream_read_bytes_finish + +GInputStreamClass +G_INPUT_STREAM +G_IS_INPUT_STREAM +G_TYPE_INPUT_STREAM +G_INPUT_STREAM_CLASS +G_IS_INPUT_STREAM_CLASS +G_INPUT_STREAM_GET_CLASS + +g_input_stream_get_type +GInputStreamPrivate +
+ +
+gfileinputstream +GFileInputStream +GFileInputStream +g_file_input_stream_query_info +g_file_input_stream_query_info_async +g_file_input_stream_query_info_finish + +GFileInputStreamClass +G_FILE_INPUT_STREAM +G_IS_FILE_INPUT_STREAM +G_TYPE_FILE_INPUT_STREAM +G_FILE_INPUT_STREAM_CLASS +G_IS_FILE_INPUT_STREAM_CLASS +G_FILE_INPUT_STREAM_GET_CLASS + +g_file_input_stream_get_type +GFileInputStreamPrivate +
+ +
+gfilterinputstream +GFilterInputStream +GFilterInputStream +g_filter_input_stream_get_base_stream +g_filter_input_stream_get_close_base_stream +g_filter_input_stream_set_close_base_stream + +GFilterInputStreamClass +G_FILTER_INPUT_STREAM +G_IS_FILTER_INPUT_STREAM +G_TYPE_FILTER_INPUT_STREAM +G_FILTER_INPUT_STREAM_CLASS +G_IS_FILTER_INPUT_STREAM_CLASS +G_FILTER_INPUT_STREAM_GET_CLASS + +g_filter_input_stream_get_type +
+ +
+gunixinputstream +GUnixInputStream +GUnixInputStream +g_unix_input_stream_new +g_unix_input_stream_set_close_fd +g_unix_input_stream_get_close_fd +g_unix_input_stream_get_fd + +GUnixInputStreamClass +G_UNIX_INPUT_STREAM +G_IS_UNIX_INPUT_STREAM +G_TYPE_UNIX_INPUT_STREAM +G_UNIX_INPUT_STREAM_CLASS +G_IS_UNIX_INPUT_STREAM_CLASS +G_UNIX_INPUT_STREAM_GET_CLASS + +g_unix_input_stream_get_type +GUnixInputStreamPrivate +
+ +
+gmemoryinputstream +GMemoryInputStream +GMemoryInputStream +g_memory_input_stream_new +g_memory_input_stream_new_from_data +g_memory_input_stream_new_from_bytes +g_memory_input_stream_add_data +g_memory_input_stream_add_bytes + +GMemoryInputStreamClass +G_MEMORY_INPUT_STREAM +G_IS_MEMORY_INPUT_STREAM +G_TYPE_MEMORY_INPUT_STREAM +G_MEMORY_INPUT_STREAM_CLASS +G_IS_MEMORY_INPUT_STREAM_CLASS +G_MEMORY_INPUT_STREAM_GET_CLASS + +GMemoryInputStreamPrivate +g_memory_input_stream_get_type +
+ +
+gdatainputstream +GDataInputStream +GDataInputStream +GDataStreamByteOrder +GDataStreamNewlineType +g_data_input_stream_new +g_data_input_stream_set_byte_order +g_data_input_stream_get_byte_order +g_data_input_stream_set_newline_type +g_data_input_stream_get_newline_type +g_data_input_stream_read_byte +g_data_input_stream_read_int16 +g_data_input_stream_read_uint16 +g_data_input_stream_read_int32 +g_data_input_stream_read_uint32 +g_data_input_stream_read_int64 +g_data_input_stream_read_uint64 +g_data_input_stream_read_line +g_data_input_stream_read_line_utf8 +g_data_input_stream_read_line_async +g_data_input_stream_read_line_finish +g_data_input_stream_read_line_finish_utf8 +g_data_input_stream_read_upto +g_data_input_stream_read_upto_async +g_data_input_stream_read_upto_finish +g_data_input_stream_read_until +g_data_input_stream_read_until_async +g_data_input_stream_read_until_finish + +GDataInputStreamClass +G_DATA_INPUT_STREAM +G_IS_DATA_INPUT_STREAM +G_TYPE_DATA_INPUT_STREAM +G_DATA_INPUT_STREAM_CLASS +G_IS_DATA_INPUT_STREAM_CLASS +G_DATA_INPUT_STREAM_GET_CLASS +G_TYPE_DATA_STREAM_BYTE_ORDER +G_TYPE_DATA_STREAM_NEWLINE_TYPE + +g_data_input_stream_get_type +GDataInputStreamPrivate +g_data_stream_byte_order_get_type +g_data_stream_newline_type_get_type +
+ +
+gbufferedinputstream +GBufferedInputStream +GBufferedInputStream +g_buffered_input_stream_new +g_buffered_input_stream_new_sized +g_buffered_input_stream_get_buffer_size +g_buffered_input_stream_set_buffer_size +g_buffered_input_stream_get_available +g_buffered_input_stream_peek_buffer +g_buffered_input_stream_peek +g_buffered_input_stream_fill +g_buffered_input_stream_fill_async +g_buffered_input_stream_fill_finish +g_buffered_input_stream_read_byte + +GBufferedInputStreamClass +G_BUFFERED_INPUT_STREAM +G_IS_BUFFERED_INPUT_STREAM +G_TYPE_BUFFERED_INPUT_STREAM +G_BUFFERED_INPUT_STREAM_CLASS +G_IS_BUFFERED_INPUT_STREAM_CLASS +G_BUFFERED_INPUT_STREAM_GET_CLASS + +g_buffered_input_stream_get_type +GBufferedInputStreamPrivate +
+ +
+goutputstream +GOutputStream +GOutputStreamSpliceFlags +GOutputStream +g_output_stream_write +g_output_stream_write_all +g_output_stream_write_all_async +g_output_stream_write_all_finish +g_output_stream_writev +g_output_stream_writev_all +g_output_stream_writev_async +g_output_stream_writev_finish +g_output_stream_writev_all_async +g_output_stream_writev_all_finish +g_output_stream_splice +g_output_stream_flush +g_output_stream_close +g_output_stream_write_async +g_output_stream_write_finish +g_output_stream_splice_async +g_output_stream_splice_finish +g_output_stream_flush_async +g_output_stream_flush_finish +g_output_stream_close_async +g_output_stream_close_finish +g_output_stream_is_closing +g_output_stream_is_closed +g_output_stream_has_pending +g_output_stream_set_pending +g_output_stream_clear_pending +g_output_stream_write_bytes +g_output_stream_write_bytes_async +g_output_stream_write_bytes_finish +g_output_stream_printf +g_output_stream_vprintf + +GOutputStreamClass +G_OUTPUT_STREAM +G_IS_OUTPUT_STREAM +G_TYPE_OUTPUT_STREAM +G_OUTPUT_STREAM_CLASS +G_IS_OUTPUT_STREAM_CLASS +G_OUTPUT_STREAM_GET_CLASS +G_TYPE_OUTPUT_STREAM_SPLICE_FLAGS + +g_output_stream_get_type +GOutputStreamPrivate +g_output_stream_splice_flags_get_type +
+ +
+gfileoutputstream +GFileOutputStream +GFileOutputStream +g_file_output_stream_query_info +g_file_output_stream_query_info_async +g_file_output_stream_query_info_finish +g_file_output_stream_get_etag + +GFileOutputStreamClass +G_FILE_OUTPUT_STREAM +G_IS_FILE_OUTPUT_STREAM +G_TYPE_FILE_OUTPUT_STREAM +G_FILE_OUTPUT_STREAM_CLASS +G_IS_FILE_OUTPUT_STREAM_CLASS +G_FILE_OUTPUT_STREAM_GET_CLASS + +g_file_output_stream_get_type +GFileOutputStreamPrivate +
+ +
+gfilteroutputstream +GFilterOutputStream +GFilterOutputStream +g_filter_output_stream_get_base_stream +g_filter_output_stream_get_close_base_stream +g_filter_output_stream_set_close_base_stream + +GFilterOutputStreamClass +G_FILTER_OUTPUT_STREAM +G_IS_FILTER_OUTPUT_STREAM +G_TYPE_FILTER_OUTPUT_STREAM +G_FILTER_OUTPUT_STREAM_CLASS +G_IS_FILTER_OUTPUT_STREAM_CLASS +G_FILTER_OUTPUT_STREAM_GET_CLASS + +g_filter_output_stream_get_type +
+ +
+gbufferedoutputstream +GBufferedOutputStream +GBufferedOutputStream +g_buffered_output_stream_new +g_buffered_output_stream_new_sized +g_buffered_output_stream_get_buffer_size +g_buffered_output_stream_set_buffer_size +g_buffered_output_stream_get_auto_grow +g_buffered_output_stream_set_auto_grow + +GBufferedOutputStreamClass +G_BUFFERED_OUTPUT_STREAM +G_IS_BUFFERED_OUTPUT_STREAM +G_TYPE_BUFFERED_OUTPUT_STREAM +G_BUFFERED_OUTPUT_STREAM_CLASS +G_IS_BUFFERED_OUTPUT_STREAM_CLASS +G_BUFFERED_OUTPUT_STREAM_GET_CLASS + +g_buffered_output_stream_get_type +GBufferedOutputStreamPrivate +
+ +
+gmemoryoutputstream +GMemoryOutputStream +GReallocFunc +GMemoryOutputStream +g_memory_output_stream_new +g_memory_output_stream_new_resizable +g_memory_output_stream_get_data +g_memory_output_stream_get_size +g_memory_output_stream_get_data_size +g_memory_output_stream_steal_data +g_memory_output_stream_steal_as_bytes + +GMemoryOutputStreamClass +G_MEMORY_OUTPUT_STREAM +G_IS_MEMORY_OUTPUT_STREAM +G_TYPE_MEMORY_OUTPUT_STREAM +G_MEMORY_OUTPUT_STREAM_CLASS +G_IS_MEMORY_OUTPUT_STREAM_CLASS +G_MEMORY_OUTPUT_STREAM_GET_CLASS + +g_memory_output_stream_get_type +GMemoryOutputStreamPrivate +
+ +
+gdataoutputstream +GDataOutputStream +GDataOutputStream +g_data_output_stream_new +g_data_output_stream_set_byte_order +g_data_output_stream_get_byte_order +g_data_output_stream_put_byte +g_data_output_stream_put_int16 +g_data_output_stream_put_uint16 +g_data_output_stream_put_int32 +g_data_output_stream_put_uint32 +g_data_output_stream_put_int64 +g_data_output_stream_put_uint64 +g_data_output_stream_put_string + +GDataOutputStreamClass +G_DATA_OUTPUT_STREAM +G_IS_DATA_OUTPUT_STREAM +G_TYPE_DATA_OUTPUT_STREAM +G_DATA_OUTPUT_STREAM_CLASS +G_IS_DATA_OUTPUT_STREAM_CLASS +G_DATA_OUTPUT_STREAM_GET_CLASS + +g_data_output_stream_get_type +GDataOutputStreamPrivate +
+ +
+gunixoutputstream +GUnixOutputStream +GUnixOutputStream +g_unix_output_stream_new +g_unix_output_stream_set_close_fd +g_unix_output_stream_get_close_fd +g_unix_output_stream_get_fd + +GUnixOutputStreamClass +G_UNIX_OUTPUT_STREAM +G_IS_UNIX_OUTPUT_STREAM +G_TYPE_UNIX_OUTPUT_STREAM +G_UNIX_OUTPUT_STREAM_CLASS +G_IS_UNIX_OUTPUT_STREAM_CLASS +G_UNIX_OUTPUT_STREAM_GET_CLASS + +g_unix_output_stream_get_type +GUnixOutputStreamPrivate +
+ +
+giostream +GIOStream +GIOStreamSpliceFlags +GIOStream +g_io_stream_get_input_stream +g_io_stream_get_output_stream +g_io_stream_splice_async +g_io_stream_splice_finish +g_io_stream_close +g_io_stream_close_async +g_io_stream_close_finish +g_io_stream_is_closed +g_io_stream_has_pending +g_io_stream_set_pending +g_io_stream_clear_pending + +GIOStreamClass +G_IO_STREAM +G_IO_STREAM_CLASS +G_IO_STREAM_GET_CLASS +G_IS_IO_STREAM +G_IS_IO_STREAM_CLASS +G_TYPE_IO_STREAM +G_TYPE_IO_STREAM_SPLICE_FLAGS + +GIOStreamPrivate +GIOStreamAdapter +g_io_stream_get_type +g_io_stream_splice_flags_get_type +
+ +
+gsimpleiostream +GSimpleIOStream +GSimpleIOStream +g_simple_io_stream_new + +GIOStreamClass +G_TYPE_SIMPLE_IO_STREAM +G_IS_SIMPLE_IO_STREAM +G_SIMPLE_IO_STREAM + +g_simple_io_stream_get_type +
+ +
+gfileiostream +GFileIOStream +GFileIOStream +g_file_io_stream_get_etag +g_file_io_stream_query_info +g_file_io_stream_query_info_async +g_file_io_stream_query_info_finish + +GFileIOStreamClass +G_FILE_IO_STREAM +G_FILE_IO_STREAM_CLASS +G_FILE_IO_STREAM_GET_CLASS +G_IS_FILE_IO_STREAM +G_IS_FILE_IO_STREAM_CLASS +G_TYPE_FILE_IO_STREAM + +GFileIOStreamPrivate +g_file_io_stream_get_type +
+ +
+gseekable +GSeekable +GSeekable +GSeekableIface +g_seekable_tell +g_seekable_can_seek +g_seekable_seek +g_seekable_can_truncate +g_seekable_truncate + +G_SEEKABLE +G_IS_SEEKABLE +G_TYPE_SEEKABLE +G_SEEKABLE_GET_IFACE + +g_seekable_get_type +
+ +
+gvolumemonitor +GVolumeMonitor +GVolumeMonitor +G_VOLUME_MONITOR_EXTENSION_POINT_NAME +g_volume_monitor_get +g_volume_monitor_get_connected_drives +g_volume_monitor_get_volumes +g_volume_monitor_get_mounts +g_volume_monitor_adopt_orphan_mount +g_volume_monitor_get_mount_for_uuid +g_volume_monitor_get_volume_for_uuid + +GVolumeMonitorClass +G_VOLUME_MONITOR +G_IS_VOLUME_MONITOR +G_TYPE_VOLUME_MONITOR +G_VOLUME_MONITOR_CLASS +G_IS_VOLUME_MONITOR_CLASS +G_VOLUME_MONITOR_GET_CLASS + +g_volume_monitor_get_type +
+ +
+gmount +GMount +GMount +GMountIface +g_mount_get_name +g_mount_get_uuid +g_mount_get_icon +g_mount_get_symbolic_icon +g_mount_get_drive +g_mount_get_root +g_mount_get_volume +g_mount_get_default_location +g_mount_can_unmount +GMountMountFlags +GMountUnmountFlags +g_mount_unmount +g_mount_unmount_finish +g_mount_unmount_with_operation +g_mount_unmount_with_operation_finish +g_mount_remount +g_mount_remount_finish +g_mount_can_eject +g_mount_eject +g_mount_eject_finish +g_mount_eject_with_operation +g_mount_eject_with_operation_finish +g_mount_guess_content_type +g_mount_guess_content_type_finish +g_mount_guess_content_type_sync +g_mount_is_shadowed +g_mount_shadow +g_mount_unshadow +g_mount_get_sort_key + +G_IS_MOUNT +G_MOUNT +G_MOUNT_GET_IFACE +G_TYPE_MOUNT +G_TYPE_MOUNT_MOUNT_FLAGS +G_TYPE_MOUNT_UNMOUNT_FLAGS + +g_mount_get_type +g_mount_mount_flags_get_type +g_mount_unmount_flags_get_type +
+ +
+gvolume +GVolume +GVolume +GVolumeIface +g_volume_get_name +g_volume_get_uuid +g_volume_get_icon +g_volume_get_symbolic_icon +g_volume_get_drive +g_volume_get_mount +g_volume_can_mount +g_volume_should_automount +g_volume_get_activation_root +g_volume_mount +g_volume_mount_finish +g_volume_can_eject +g_volume_eject +g_volume_eject_finish +g_volume_eject_with_operation +g_volume_eject_with_operation_finish +G_VOLUME_IDENTIFIER_KIND_HAL_UDI +G_VOLUME_IDENTIFIER_KIND_LABEL +G_VOLUME_IDENTIFIER_KIND_NFS_MOUNT +G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE +G_VOLUME_IDENTIFIER_KIND_UUID +G_VOLUME_IDENTIFIER_KIND_CLASS +g_volume_enumerate_identifiers +g_volume_get_identifier +g_volume_get_sort_key + +G_VOLUME +G_IS_VOLUME +G_TYPE_VOLUME +G_VOLUME_GET_IFACE + +g_volume_get_type +
+ +
+gdrive +GDrive +GDrive +GDriveIface +GDriveStartFlags +GDriveStartStopType +g_drive_get_name +g_drive_get_icon +g_drive_get_symbolic_icon +g_drive_has_volumes +g_drive_get_volumes +g_drive_can_eject +g_drive_get_start_stop_type +g_drive_can_start +g_drive_can_start_degraded +g_drive_can_stop +g_drive_can_poll_for_media +g_drive_poll_for_media +g_drive_poll_for_media_finish +g_drive_has_media +g_drive_is_media_check_automatic +g_drive_is_removable +g_drive_is_media_removable +g_drive_eject +g_drive_eject_finish +g_drive_eject_with_operation +g_drive_eject_with_operation_finish +g_drive_start +g_drive_start_finish +g_drive_stop +g_drive_stop_finish +g_drive_enumerate_identifiers +g_drive_get_identifier +g_drive_get_sort_key +G_DRIVE_IDENTIFIER_KIND_UNIX_DEVICE + +G_DRIVE +G_IS_DRIVE +G_TYPE_DRIVE +G_DRIVE_GET_IFACE +G_TYPE_DRIVE_START_FLAGS +G_TYPE_DRIVE_START_STOP_TYPE + +g_drive_get_type +g_drive_start_flags_get_type +g_drive_start_stop_type_get_type +
+ +
+gcancellable +GCancellable +GCancellable +g_cancellable_new +g_cancellable_is_cancelled +g_cancellable_set_error_if_cancelled +g_cancellable_get_fd +g_cancellable_make_pollfd +g_cancellable_release_fd +g_cancellable_source_new +GCancellableSourceFunc +g_cancellable_get_current +g_cancellable_pop_current +g_cancellable_push_current +g_cancellable_reset +g_cancellable_connect +g_cancellable_disconnect +g_cancellable_cancel + +GCancellableClass +G_CANCELLABLE +G_IS_CANCELLABLE +G_TYPE_CANCELLABLE +G_CANCELLABLE_CLASS +G_IS_CANCELLABLE_CLASS +G_CANCELLABLE_GET_CLASS + +GCancellablePrivate +g_cancellable_get_type +
+ +
+gasyncresult +GAsyncResult +GAsyncResult +GAsyncResultIface +GAsyncReadyCallback +g_async_result_get_user_data +g_async_result_get_source_object +g_async_result_is_tagged +g_async_result_legacy_propagate_error + +G_ASYNC_RESULT +G_IS_ASYNC_RESULT +G_TYPE_ASYNC_RESULT +G_ASYNC_RESULT_GET_IFACE + +g_async_result_get_type +
+ +
+gsimpleasyncresult +GSimpleAsyncResult +GSimpleAsyncResult +GSimpleAsyncThreadFunc +g_simple_async_result_new +g_simple_async_result_new_error +g_simple_async_result_new_from_error +g_simple_async_result_new_take_error +g_simple_async_result_set_check_cancellable +g_simple_async_result_set_op_res_gpointer +g_simple_async_result_get_op_res_gpointer +g_simple_async_result_set_op_res_gssize +g_simple_async_result_get_op_res_gssize +g_simple_async_result_set_op_res_gboolean +g_simple_async_result_get_op_res_gboolean +g_simple_async_result_get_source_tag +g_simple_async_result_is_valid +g_simple_async_result_set_handle_cancellation +g_simple_async_result_complete +g_simple_async_result_complete_in_idle +g_simple_async_result_run_in_thread +g_simple_async_result_set_from_error +g_simple_async_result_take_error +g_simple_async_result_propagate_error +g_simple_async_result_set_error +g_simple_async_result_set_error_va +g_simple_async_report_error_in_idle +g_simple_async_report_gerror_in_idle +g_simple_async_report_take_gerror_in_idle + +GSimpleAsyncResultClass +G_SIMPLE_ASYNC_RESULT +G_IS_SIMPLE_ASYNC_RESULT +G_TYPE_SIMPLE_ASYNC_RESULT +G_SIMPLE_ASYNC_RESULT_CLASS +G_IS_SIMPLE_ASYNC_RESULT_CLASS +G_SIMPLE_ASYNC_RESULT_GET_CLASS + +g_simple_async_result_get_type +
+ +
+gioscheduler +GIOScheduler +GIOSchedulerJob +GIOSchedulerJobFunc +g_io_scheduler_push_job +g_io_scheduler_cancel_all_jobs +g_io_scheduler_job_send_to_mainloop +g_io_scheduler_job_send_to_mainloop_async +
+ +
+gioerror +GIOError +G_IO_ERROR +GIOErrorEnum +g_io_error_from_errno +g_io_error_from_win32_error + +G_TYPE_IO_ERROR_ENUM + +g_io_error_quark +g_io_error_enum_get_type +
+ +
+gcontenttype +GContentType +g_content_type_equals +g_content_type_is_a +g_content_type_is_mime_type +g_content_type_is_unknown +g_content_type_get_description +g_content_type_get_mime_type +g_content_type_get_icon +g_content_type_get_symbolic_icon +g_content_type_get_generic_icon_name +g_content_type_can_be_executable +g_content_type_from_mime_type +g_content_type_guess +g_content_type_guess_for_tree +g_content_types_get_registered +
+ +
+gappinfo +GAppInfo +GAppInfoCreateFlags +GAppInfo +GAppInfoIface +GAppLaunchContext +g_app_info_create_from_commandline +g_app_info_dup +g_app_info_equal +g_app_info_get_id +g_app_info_get_name +g_app_info_get_display_name +g_app_info_get_description +g_app_info_get_executable +g_app_info_get_commandline +g_app_info_get_icon +g_app_info_launch +g_app_info_supports_files +g_app_info_supports_uris +g_app_info_launch_uris +g_app_info_launch_uris_async +g_app_info_launch_uris_finish +g_app_info_should_show +g_app_info_can_delete +g_app_info_delete +g_app_info_reset_type_associations +g_app_info_set_as_default_for_type +g_app_info_set_as_default_for_extension +g_app_info_set_as_last_used_for_type +g_app_info_add_supports_type +g_app_info_can_remove_supports_type +g_app_info_remove_supports_type +g_app_info_get_supported_types +g_app_info_get_all +g_app_info_get_all_for_type +g_app_info_get_default_for_type +g_app_info_get_default_for_uri_scheme +g_app_info_get_fallback_for_type +g_app_info_get_recommended_for_type +g_app_info_launch_default_for_uri +g_app_info_launch_default_for_uri_async +g_app_info_launch_default_for_uri_finish +g_app_launch_context_setenv +g_app_launch_context_unsetenv +g_app_launch_context_get_environment +g_app_launch_context_get_display +g_app_launch_context_get_startup_notify_id +g_app_launch_context_launch_failed +g_app_launch_context_new + +GAppLaunchContextClass +G_APP_INFO +G_IS_APP_INFO +G_TYPE_APP_INFO +G_APP_INFO_GET_IFACE +G_APP_LAUNCH_CONTEXT +G_APP_LAUNCH_CONTEXT_CLASS +G_APP_LAUNCH_CONTEXT_GET_CLASS +G_IS_APP_LAUNCH_CONTEXT +G_IS_APP_LAUNCH_CONTEXT_CLASS +G_TYPE_APP_LAUNCH_CONTEXT +G_TYPE_APP_INFO_CREATE_FLAGS + +g_app_info_get_type +g_app_info_create_flags_get_type +g_app_launch_context_get_type +GAppLaunchContextPrivate +
+ +
+gappinfomonitor +GAppInfoMonitor +g_app_info_monitor_get + +GAppInfoMonitor +G_APP_INFO_MONITOR +G_IS_APP_INFO_MONITOR +G_TYPE_APP_INFO_MONITOR + +g_app_info_monitor_get_type +
+ +
+gmountoperation +GMountOperation +GAskPasswordFlags +GPasswordSave +GMountOperation +GMountOperationResult +g_mount_operation_new +g_mount_operation_get_username +g_mount_operation_set_username +g_mount_operation_get_password +g_mount_operation_set_password +g_mount_operation_get_anonymous +g_mount_operation_set_anonymous +g_mount_operation_get_domain +g_mount_operation_set_domain +g_mount_operation_get_password_save +g_mount_operation_set_password_save +g_mount_operation_get_choice +g_mount_operation_set_choice +g_mount_operation_get_is_tcrypt_hidden_volume +g_mount_operation_set_is_tcrypt_hidden_volume +g_mount_operation_get_is_tcrypt_system_volume +g_mount_operation_set_is_tcrypt_system_volume +g_mount_operation_get_pim +g_mount_operation_set_pim +g_mount_operation_reply + +GMountOperationClass +G_MOUNT_OPERATION +G_IS_MOUNT_OPERATION +G_TYPE_MOUNT_OPERATION +G_MOUNT_OPERATION_CLASS +G_IS_MOUNT_OPERATION_CLASS +G_MOUNT_OPERATION_GET_CLASS +G_TYPE_ASK_PASSWORD_FLAGS +G_TYPE_MOUNT_OPERATION_RESULT +G_TYPE_PASSWORD_SAVE + +g_mount_operation_get_type +g_ask_password_flags_get_type +GMountOperationPrivate +g_mount_operation_result_get_type +g_password_save_get_type +
+ +
+gfilenamecompleter +GFilenameCompleter +GFilenameCompleter +g_filename_completer_new +g_filename_completer_get_completion_suffix +g_filename_completer_get_completions +g_filename_completer_set_dirs_only + +GFilenameCompleterClass +G_FILENAME_COMPLETER +G_IS_FILENAME_COMPLETER +G_TYPE_FILENAME_COMPLETER +G_FILENAME_COMPLETER_CLASS +G_IS_FILENAME_COMPLETER_CLASS +G_FILENAME_COMPLETER_GET_CLASS + +g_filename_completer_get_type +
+ +
+gunixmounts +Unix Mounts +GUnixMountPoint +GUnixMountEntry +GUnixMountMonitor +g_unix_mount_free +g_unix_mount_compare +g_unix_mount_copy +g_unix_mount_get_mount_path +g_unix_mount_get_device_path +g_unix_mount_get_root_path +g_unix_mount_get_fs_type +g_unix_mount_get_options +g_unix_mount_is_readonly +g_unix_mount_is_system_internal +g_unix_mount_guess_icon +g_unix_mount_guess_symbolic_icon +g_unix_mount_guess_name +g_unix_mount_guess_can_eject +g_unix_mount_guess_should_display +g_unix_mount_point_free +g_unix_mount_point_compare +g_unix_mount_point_copy +g_unix_mount_point_get_mount_path +g_unix_mount_point_get_device_path +g_unix_mount_point_get_fs_type +g_unix_mount_point_get_options +g_unix_mount_point_is_readonly +g_unix_mount_point_is_user_mountable +g_unix_mount_point_is_loopback +g_unix_mount_point_guess_icon +g_unix_mount_point_guess_symbolic_icon +g_unix_mount_point_guess_name +g_unix_mount_point_guess_can_eject +g_unix_mount_points_get +g_unix_mount_point_at +g_unix_mounts_get +g_unix_mount_at +g_unix_mount_for +g_unix_mounts_changed_since +g_unix_mount_points_changed_since +g_unix_mount_monitor_get +g_unix_mount_monitor_new +g_unix_mount_monitor_set_rate_limit +g_unix_is_mount_path_system_internal +g_unix_is_system_fs_type +g_unix_is_system_device_path + +GUnixMountMonitorClass +G_UNIX_MOUNT_MONITOR +G_IS_UNIX_MOUNT_MONITOR +G_TYPE_UNIX_MOUNT_MONITOR +G_UNIX_MOUNT_MONITOR_CLASS +G_IS_UNIX_MOUNT_MONITOR_CLASS +G_TYPE_UNIX_MOUNT_ENTRY +G_TYPE_UNIX_MOUNT_POINT + +g_unix_mount_monitor_get_type +g_unix_mount_entry_get_type +g_unix_mount_point_get_type +
+ +
+gdesktopappinfo +Desktop file based GAppInfo +GDesktopAppInfo +g_desktop_app_info_new_from_filename +g_desktop_app_info_new_from_keyfile +g_desktop_app_info_new +g_desktop_app_info_get_filename +g_desktop_app_info_get_is_hidden +g_desktop_app_info_get_nodisplay +g_desktop_app_info_get_show_in +g_desktop_app_info_get_generic_name +g_desktop_app_info_get_categories +g_desktop_app_info_get_keywords +g_desktop_app_info_get_startup_wm_class +g_desktop_app_info_set_desktop_env +g_desktop_app_info_get_string +g_desktop_app_info_get_locale_string +g_desktop_app_info_get_boolean +g_desktop_app_info_get_string_list +g_desktop_app_info_has_key +GDesktopAppLaunchCallback +g_desktop_app_info_launch_uris_as_manager +g_desktop_app_info_launch_uris_as_manager_with_fds + +g_desktop_app_info_list_actions +g_desktop_app_info_get_action_name +g_desktop_app_info_launch_action + +g_desktop_app_info_search +g_desktop_app_info_get_implementations + +GDesktopAppInfoLookup +GDesktopAppInfoLookupIface +G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME + +GDesktopAppInfoClass +G_TYPE_DESKTOP_APP_INFO +G_DESKTOP_APP_INFO +G_DESKTOP_APP_INFO_CLASS +G_IS_DESKTOP_APP_INFO +G_IS_DESKTOP_APP_INFO_CLASS +G_DESKTOP_APP_INFO_GET_CLASS +G_DESKTOP_APP_INFO_LOOKUP +G_DESKTOP_APP_INFO_LOOKUP_GET_IFACE +G_IS_DESKTOP_APP_INFO_LOOKUP +G_TYPE_DESKTOP_APP_INFO_LOOKUP + +g_desktop_app_info_get_type +g_desktop_app_info_lookup_get_default_for_uri_scheme +g_desktop_app_info_lookup_get_type +
+ +
+giomodule +GIOModule +GIOModule +GIOModuleScope +GIOModuleScopeFlags +g_io_module_new +g_io_module_scope_block +g_io_module_scope_free +g_io_module_scope_new +g_io_modules_load_all_in_directory +g_io_modules_load_all_in_directory_with_scope +g_io_modules_scan_all_in_directory +g_io_modules_scan_all_in_directory_with_scope +g_io_module_load +g_io_module_unload +g_io_module_query + +GIOModuleClass +G_IO_MODULE +G_IO_IS_MODULE +G_IO_TYPE_MODULE +G_IO_MODULE_CLASS +G_IO_IS_MODULE_CLASS +G_IO_MODULE_GET_CLASS +G_TYPE_IO_MODULE_SCOPE_FLAGS + +g_io_module_get_type +g_io_module_scope_flags_get_type +
+ +
+extensionpoints +Extension Points +GIOExtension +GIOExtensionPoint +g_io_extension_get_name +g_io_extension_get_priority +g_io_extension_get_type +g_io_extension_point_get_extension_by_name +g_io_extension_point_get_extensions +g_io_extension_point_get_required_type +g_io_extension_point_implement +g_io_extension_point_lookup +g_io_extension_point_register +g_io_extension_point_set_required_type +g_io_extension_ref_class +
+ +
+gunixfdlist +GUnixFDList +GUnixFDList +g_unix_fd_list_new_from_array +g_unix_fd_list_new +g_unix_fd_list_get_length +g_unix_fd_list_get +g_unix_fd_list_peek_fds +g_unix_fd_list_steal_fds +g_unix_fd_list_append + +GUnixFDListClass +G_UNIX_FD_LIST +G_UNIX_FD_LIST_CLASS +G_IS_UNIX_FD_LIST +G_IS_UNIX_FD_LIST_CLASS +G_UNIX_FD_LIST_GET_CLASS +G_TYPE_UNIX_FD_LIST + +GUnixFDListPrivate +g_unix_fd_list_get_type +
+ +
+ginetaddress +GInetAddress +GInetAddress +g_inet_address_new_from_string +g_inet_address_new_from_bytes +g_inet_address_new_any +g_inet_address_new_loopback +g_inet_address_equal +g_inet_address_to_bytes +g_inet_address_get_native_size +g_inet_address_to_string +g_inet_address_get_family +g_inet_address_get_is_any +g_inet_address_get_is_loopback +g_inet_address_get_is_link_local +g_inet_address_get_is_site_local +g_inet_address_get_is_multicast +g_inet_address_get_is_mc_link_local +g_inet_address_get_is_mc_node_local +g_inet_address_get_is_mc_site_local +g_inet_address_get_is_mc_org_local +g_inet_address_get_is_mc_global + +GInetAddressClass +GInetAddressPrivate +G_INET_ADDRESS +G_INET_ADDRESS_CLASS +G_INET_ADDRESS_GET_CLASS +G_IS_INET_ADDRESS +G_IS_INET_ADDRESS_CLASS +G_TYPE_INET_ADDRESS + +g_inet_address_get_type +
+ +
+ginetaddressmask +GInetAddressMask +GInetAddressMask +g_inet_address_mask_new +g_inet_address_mask_new_from_string +g_inet_address_mask_to_string +g_inet_address_mask_get_family +g_inet_address_mask_get_address +g_inet_address_mask_get_length +g_inet_address_mask_matches +g_inet_address_mask_equal + +GInetAddressMaskClass +GInetAddressMaskPrivate +G_INET_ADDRESS_MASK +G_INET_ADDRESS_MASK_CLASS +G_INET_ADDRESS_MASK_GET_CLASS +G_IS_INET_ADDRESS_MASK +G_IS_INET_ADDRESS_MASK_CLASS +G_TYPE_INET_ADDRESS_MASK + +g_inet_address_mask_get_type +
+ +
+gsocketaddress +GSocketAddress +GSocketAddress +GSocketFamily +g_socket_address_new_from_native +g_socket_address_get_family +g_socket_address_to_native +g_socket_address_get_native_size + +GSocketAddressClass +G_IS_SOCKET_ADDRESS +G_IS_SOCKET_ADDRESS_CLASS +G_SOCKET_ADDRESS +G_SOCKET_ADDRESS_CLASS +G_SOCKET_ADDRESS_GET_CLASS +G_TYPE_SOCKET_ADDRESS +G_TYPE_SOCKET_FAMILY + +g_socket_address_get_type +g_socket_family_get_type +
+ +
+ginetsocketaddress +GInetSocketAddress +GInetSocketAddress +g_inet_socket_address_new +g_inet_socket_address_new_from_string +g_inet_socket_address_get_address +g_inet_socket_address_get_port +g_inet_socket_address_get_flowinfo +g_inet_socket_address_get_scope_id + +GInetSocketAddressClass +GInetSocketAddressPrivate +G_INET_SOCKET_ADDRESS +G_INET_SOCKET_ADDRESS_CLASS +G_INET_SOCKET_ADDRESS_GET_CLASS +G_IS_INET_SOCKET_ADDRESS +G_IS_INET_SOCKET_ADDRESS_CLASS +G_TYPE_INET_SOCKET_ADDRESS + +g_inet_socket_address_get_type +
+ +
+gunixsocketaddress +GUnixSocketAddress +GUnixSocketAddress +GUnixSocketAddressType +g_unix_socket_address_new +g_unix_socket_address_new_abstract +g_unix_socket_address_new_with_type +g_unix_socket_address_get_is_abstract +g_unix_socket_address_get_address_type +g_unix_socket_address_get_path +g_unix_socket_address_get_path_len +g_unix_socket_address_abstract_names_supported + +GUnixSocketAddressClass +GUnixSocketAddressPrivate +G_IS_UNIX_SOCKET_ADDRESS +G_IS_UNIX_SOCKET_ADDRESS_CLASS +G_TYPE_UNIX_SOCKET_ADDRESS +G_UNIX_SOCKET_ADDRESS +G_UNIX_SOCKET_ADDRESS_CLASS +G_UNIX_SOCKET_ADDRESS_GET_CLASS +G_TYPE_UNIX_SOCKET_ADDRESS_TYPE + +g_unix_socket_address_get_type +g_unix_socket_address_type_get_type +
+ +
+gnativesocketaddress +GNativeSocketAddress +GNativeSocketAddress +g_native_socket_address_new + +GNativeSocketAddressClass +GNativeSocketAddressPrivate +G_IS_NATIVE_SOCKET_ADDRESS +G_IS_NATIVE_SOCKET_ADDRESS_CLASS +G_TYPE_NATIVE_SOCKET_ADDRESS +G_NATIVE_SOCKET_ADDRESS +G_NATIVE_SOCKET_ADDRESS_CLASS +G_NATIVE_SOCKET_ADDRESS_GET_CLASS +G_TYPE_NATIVE_SOCKET_ADDRESS_TYPE + +g_native_socket_address_get_type +
+ +
+gresolver +GResolver +GResolver +g_resolver_get_default +g_resolver_set_default +g_resolver_lookup_by_name +g_resolver_lookup_by_name_async +g_resolver_lookup_by_name_finish +GResolverNameLookupFlags +g_resolver_lookup_by_name_with_flags +g_resolver_lookup_by_name_with_flags_async +g_resolver_lookup_by_name_with_flags_finish +g_resolver_free_addresses +g_resolver_lookup_by_address +g_resolver_lookup_by_address_async +g_resolver_lookup_by_address_finish +g_resolver_lookup_service +g_resolver_lookup_service_async +g_resolver_lookup_service_finish +g_resolver_free_targets + +GResolverRecordType +g_resolver_lookup_records +g_resolver_lookup_records_async +g_resolver_lookup_records_finish + + +G_RESOLVER_ERROR +GResolverError + + +GResolverClass +G_IS_RESOLVER +G_IS_RESOLVER_CLASS +G_RESOLVER +G_RESOLVER_CLASS +G_RESOLVER_GET_CLASS +G_TYPE_RESOLVER +G_TYPE_RESOLVER_ERROR +G_TYPE_RESOLVER_RECORD_TYPE +G_TYPE_RESOLVER_NAME_LOOKUP_FLAGS + + +GResolverPrivate +g_resolver_get_type +g_resolver_error_quark +g_resolver_record_type_get_type +g_resolver_error_get_type +g_resolver_name_lookup_flags_get_type +
+ +
+gsrvtarget +GSrvTarget +GSrvTarget +g_srv_target_new +g_srv_target_copy +g_srv_target_free +g_srv_target_get_hostname +g_srv_target_get_port +g_srv_target_get_priority +g_srv_target_get_weight +g_srv_target_list_sort + +G_TYPE_SRV_TARGET + +g_srv_target_get_type +
+ +
+gsocketconnectable +GSocketConnectable +GSocketConnectable +GSocketConnectableIface +g_socket_connectable_enumerate +g_socket_connectable_proxy_enumerate +g_socket_connectable_to_string + +G_IS_SOCKET_CONNECTABLE +G_SOCKET_CONNECTABLE +G_SOCKET_CONNECTABLE_GET_IFACE +G_TYPE_SOCKET_CONNECTABLE + +g_socket_connectable_get_type +
+ +
+gsocketaddressenumerator +GSocketAddressEnumerator +GSocketAddressEnumerator +GSocketAddressEnumeratorClass +g_socket_address_enumerator_next +g_socket_address_enumerator_next_async +g_socket_address_enumerator_next_finish + +G_IS_SOCKET_ADDRESS_ENUMERATOR +G_IS_SOCKET_ADDRESS_ENUMERATOR_CLASS +G_SOCKET_ADDRESS_ENUMERATOR +G_SOCKET_ADDRESS_ENUMERATOR_CLASS +G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS +G_TYPE_SOCKET_ADDRESS_ENUMERATOR + +g_socket_address_enumerator_get_type +
+ +
+gproxyaddressenumerator +GProxyAddressEnumerator +GProxyAddressEnumerator +GProxyAddressEnumeratorClass + +G_IS_PROXY_ADDRESS_ENUMERATOR +G_IS_PROXY_ADDRESS_ENUMERATOR_CLASS +G_PROXY_ADDRESS_ENUMERATOR +G_PROXY_ADDRESS_ENUMERATOR_CLASS +G_PROXY_ADDRESS_ENUMERATOR_GET_CLASS +G_TYPE_PROXY_ADDRESS_ENUMERATOR + +GProxyAddressEnumeratorPrivate +g_proxy_address_enumerator_get_type +
+ +
+gnetworkaddress +GNetworkAddress +GNetworkAddress +g_network_address_new +g_network_address_new_loopback +g_network_address_parse +g_network_address_parse_uri +g_network_address_get_hostname +g_network_address_get_port +g_network_address_get_scheme + +GNetworkAddressClass +GNetworkAddressPrivate +G_IS_NETWORK_ADDRESS +G_IS_NETWORK_ADDRESS_CLASS +G_NETWORK_ADDRESS +G_NETWORK_ADDRESS_CLASS +G_NETWORK_ADDRESS_GET_CLASS +G_TYPE_NETWORK_ADDRESS + +g_network_address_get_type +
+ +
+gnetworkservice +GNetworkService +GNetworkService +g_network_service_new +g_network_service_get_service +g_network_service_get_protocol +g_network_service_get_domain +g_network_service_get_scheme +g_network_service_set_scheme + +GNetworkServiceClass +GNetworkServicePrivate +G_IS_NETWORK_SERVICE +G_IS_NETWORK_SERVICE_CLASS +G_NETWORK_SERVICE +G_NETWORK_SERVICE_CLASS +G_NETWORK_SERVICE_GET_CLASS +G_TYPE_NETWORK_SERVICE + +g_network_service_get_type +
+ +
+gdatagrambased +GDatagramBased +GDatagramBased +GDatagramBasedInterface +GDatagramBasedSourceFunc +g_datagram_based_receive_messages +g_datagram_based_send_messages +g_datagram_based_create_source +g_datagram_based_condition_check +g_datagram_based_condition_wait + +G_DATAGRAM_BASED +G_DATAGRAM_BASED_GET_IFACE +G_IS_DATAGRAM_BASED +G_TYPE_DATAGRAM_BASED +G_TYPE_IS_DATAGRAM_BASED + +g_datagram_based_get_type +
+ +
+gsocket +GSocket +GSocket +GSocketSourceFunc +GSocketType +GSocketProtocol +GSocketMsgFlags +GInputVector +GInputMessage +GOutputVector +GOutputMessage +g_socket_new +g_socket_new_from_fd +g_socket_bind +g_socket_listen +g_socket_accept +g_socket_connect +g_socket_check_connect_result +g_socket_receive +g_socket_receive_from +g_socket_receive_message +g_socket_receive_messages +g_socket_receive_with_blocking +g_socket_send +g_socket_send_to +g_socket_send_message +g_socket_send_message_with_timeout +g_socket_send_messages +g_socket_send_with_blocking +g_socket_close +g_socket_is_closed +g_socket_shutdown +g_socket_is_connected +g_socket_create_source +g_socket_condition_check +g_socket_condition_wait +g_socket_condition_timed_wait +g_socket_get_available_bytes +g_socket_set_listen_backlog +g_socket_get_listen_backlog +g_socket_get_blocking +g_socket_set_blocking +g_socket_get_keepalive +g_socket_set_keepalive +g_socket_get_timeout +g_socket_set_timeout +g_socket_set_ttl +g_socket_get_ttl +g_socket_get_broadcast +g_socket_set_broadcast +g_socket_get_option +g_socket_set_option +g_socket_get_family +g_socket_get_fd +g_socket_get_local_address +g_socket_get_protocol +g_socket_get_remote_address +g_socket_get_socket_type +g_socket_speaks_ipv4 +g_socket_get_credentials + +g_socket_join_multicast_group +g_socket_leave_multicast_group +g_socket_join_multicast_group_ssm +g_socket_leave_multicast_group_ssm +g_socket_get_multicast_loopback +g_socket_set_multicast_loopback +g_socket_get_multicast_ttl +g_socket_set_multicast_ttl + +GSocketClass +G_IS_SOCKET +G_IS_SOCKET_CLASS +G_SOCKET +G_SOCKET_CLASS +G_TYPE_SOCKET +G_SOCKET_GET_CLASS +G_TYPE_SOCKET_MSG_FLAGS +G_TYPE_SOCKET_PROTOCOL +G_TYPE_SOCKET_TYPE + +g_socket_get_type +GSocketPrivate +g_socket_msg_flags_get_type +g_socket_protocol_get_type +g_socket_type_get_type +
+ +
+gsocketclient +GSocketClient +GSocketClient +GSocketClientEvent +g_socket_client_new +g_socket_client_connect +g_socket_client_connect_async +g_socket_client_connect_finish +g_socket_client_connect_to_host +g_socket_client_connect_to_host_async +g_socket_client_connect_to_host_finish +g_socket_client_connect_to_service +g_socket_client_connect_to_service_async +g_socket_client_connect_to_service_finish +g_socket_client_connect_to_uri +g_socket_client_connect_to_uri_async +g_socket_client_connect_to_uri_finish +g_socket_client_set_family +g_socket_client_set_local_address +g_socket_client_set_protocol +g_socket_client_set_socket_type +g_socket_client_set_timeout +g_socket_client_set_enable_proxy +g_socket_client_set_proxy_resolver +g_socket_client_set_tls +g_socket_client_set_tls_validation_flags +g_socket_client_get_family +g_socket_client_get_local_address +g_socket_client_get_protocol +g_socket_client_get_socket_type +g_socket_client_get_timeout +g_socket_client_get_enable_proxy +g_socket_client_get_proxy_resolver +g_socket_client_get_tls +g_socket_client_get_tls_validation_flags +g_socket_client_add_application_proxy + +GSocketClientClass +G_IS_SOCKET_CLIENT +G_IS_SOCKET_CLIENT_CLASS +G_SOCKET_CLIENT +G_SOCKET_CLIENT_CLASS +G_SOCKET_CLIENT_GET_CLASS +G_TYPE_SOCKET_CLIENT +G_TYPE_SOCKET_CLIENT_EVENT + +GSocketClientPrivate +g_socket_client_get_type +g_socket_client_event_get_type +
+ +
+gsocketconnection +GSocketConnection +GSocketConnection +g_socket_connection_connect +g_socket_connection_connect_async +g_socket_connection_connect_finish + +g_socket_connection_is_connected +g_socket_connection_get_local_address +g_socket_connection_get_remote_address +g_socket_connection_get_socket + +g_socket_connection_factory_create_connection +g_socket_connection_factory_lookup_type +g_socket_connection_factory_register_type + +GSocketConnectionClass +G_IS_SOCKET_CONNECTION +G_IS_SOCKET_CONNECTION_CLASS +G_SOCKET_CONNECTION +G_SOCKET_CONNECTION_CLASS +G_SOCKET_CONNECTION_GET_CLASS +G_TYPE_SOCKET_CONNECTION + +GSocketConnectionPrivate +g_socket_connection_get_type +
+ +
+gunixconnection +GUnixConnection +GUnixConnection +g_unix_connection_receive_fd +g_unix_connection_send_fd +g_unix_connection_receive_credentials +g_unix_connection_receive_credentials_async +g_unix_connection_receive_credentials_finish +g_unix_connection_send_credentials +g_unix_connection_send_credentials_async +g_unix_connection_send_credentials_finish + +GUnixConnectionClass +G_IS_UNIX_CONNECTION +G_IS_UNIX_CONNECTION_CLASS +G_TYPE_UNIX_CONNECTION +G_UNIX_CONNECTION +G_UNIX_CONNECTION_CLASS +G_UNIX_CONNECTION_GET_CLASS + +GUnixConnectionPrivate +g_unix_connection_get_type +
+ +
+gtcpconnection +GTcpConnection +GTcpConnection +g_tcp_connection_set_graceful_disconnect +g_tcp_connection_get_graceful_disconnect + +GTcpConnectionClass +G_IS_TCP_CONNECTION +G_IS_TCP_CONNECTION_CLASS +G_TYPE_TCP_CONNECTION +G_TCP_CONNECTION +G_TCP_CONNECTION_CLASS +G_TCP_CONNECTION_GET_CLASS + +GTcpConnectionPrivate +g_tcp_connection_get_type +
+ +
+gtcpwrapperconnection +GTcpWrapperConnection +GTcpWrapperConnection +g_tcp_wrapper_connection_new +g_tcp_wrapper_connection_get_base_io_stream + +GTcpWrapperConnectionClass +G_IS_TCP_WRAPPER_CONNECTION +G_IS_TCP_WRAPPER_CONNECTION_CLASS +G_TYPE_TCP_WRAPPER_CONNECTION +G_TCP_WRAPPER_CONNECTION +G_TCP_WRAPPER_CONNECTION_CLASS +G_TCP_WRAPPER_CONNECTION_GET_CLASS + +GTcpWrapperConnectionPrivate +g_tcp_wrapper_connection_get_type +
+ +
+gsocketcontrolmessage +GSocketControlMessage +GSocketControlMessage +g_socket_control_message_deserialize +g_socket_control_message_get_level +g_socket_control_message_get_msg_type +g_socket_control_message_get_size +g_socket_control_message_serialize + +GSocketControlMessageClass +G_IS_SOCKET_CONTROL_MESSAGE +G_IS_SOCKET_CONTROL_MESSAGE_CLASS +G_SOCKET_CONTROL_MESSAGE +G_SOCKET_CONTROL_MESSAGE_CLASS +G_SOCKET_CONTROL_MESSAGE_GET_CLASS +G_TYPE_SOCKET_CONTROL_MESSAGE + +GSocketControlMessagePrivate +g_socket_control_message_get_type +
+ +
+gsocketlistener +GSocketListener +GSocketListener +GSocketListenerEvent +g_socket_listener_new +g_socket_listener_add_socket +g_socket_listener_add_address +g_socket_listener_add_inet_port +g_socket_listener_add_any_inet_port +g_socket_listener_accept +g_socket_listener_accept_async +g_socket_listener_accept_finish +g_socket_listener_accept_socket +g_socket_listener_accept_socket_async +g_socket_listener_accept_socket_finish +g_socket_listener_close +g_socket_listener_set_backlog + +GSocketListenerClass +G_IS_SOCKET_LISTENER +G_IS_SOCKET_LISTENER_CLASS +G_SOCKET_LISTENER +G_SOCKET_LISTENER_CLASS +G_SOCKET_LISTENER_GET_CLASS +G_TYPE_SOCKET_LISTENER +G_TYPE_SOCKET_LISTENER_EVENT + +GSocketListenerPrivate +g_socket_listener_get_type +g_socket_listener_event_get_type +
+ +
+gsocketservice +GSocketService +GSocketService +g_socket_service_new +g_socket_service_start +g_socket_service_stop +g_socket_service_is_active + +GSocketServiceClass +G_IS_SOCKET_SERVICE +G_IS_SOCKET_SERVICE_CLASS +G_SOCKET_SERVICE +G_SOCKET_SERVICE_CLASS +G_SOCKET_SERVICE_GET_CLASS +G_TYPE_SOCKET_SERVICE + +GSocketServicePrivate +g_socket_service_get_type +
+ +
+gthreadedsocketservice +GThreadedSocketService +GThreadedSocketService +g_threaded_socket_service_new + +GThreadedSocketServiceClass +G_IS_THREADED_SOCKET_SERVICE +G_IS_THREADED_SOCKET_SERVICE_CLASS +G_THREADED_SOCKET_SERVICE +G_THREADED_SOCKET_SERVICE_CLASS +G_THREADED_SOCKET_SERVICE_GET_CLASS +G_TYPE_THREADED_SOCKET_SERVICE + +GThreadedSocketServicePrivate +g_threaded_socket_service_get_type +
+ +
+gunixfdmessage +GUnixFDMessage +GUnixFDMessage +g_unix_fd_message_new_with_fd_list +g_unix_fd_message_new +g_unix_fd_message_get_fd_list +g_unix_fd_message_append_fd +g_unix_fd_message_steal_fds + +GUnixFDMessageClass +G_IS_UNIX_FD_MESSAGE +G_IS_UNIX_FD_MESSAGE_CLASS +G_TYPE_UNIX_FD_MESSAGE +G_UNIX_FD_MESSAGE +G_UNIX_FD_MESSAGE_CLASS +G_UNIX_FD_MESSAGE_GET_CLASS + +GUnixFDMessagePrivate +g_unix_fd_message_get_type +
+ +
+gconverter +GConverter +GConverter +GConverterIface +GConverterResult +GConverterFlags +g_converter_convert +g_converter_reset + +G_TYPE_CONVERTER +G_CONVERTER +G_IS_CONVERTER +G_CONVERTER_GET_IFACE +G_TYPE_CONVERTER_FLAGS +G_TYPE_CONVERTER_RESULT + +g_converter_get_type +g_converter_flags_get_type +g_converter_result_get_type +
+ +
+gcharsetconverter +GCharsetConverter +GCharsetConverter +g_charset_converter_new +g_charset_converter_set_use_fallback +g_charset_converter_get_use_fallback +g_charset_converter_get_num_fallbacks + +GCharsetConverterClass +G_TYPE_CHARSET_CONVERTER +G_CHARSET_CONVERTER +G_IS_CHARSET_CONVERTER +G_CHARSET_CONVERTER_CLASS +G_IS_CHARSET_CONVERTER_CLASS +G_CHARSET_CONVERTER_GET_CLASS + +g_charset_converter_get_type +
+ +
+gconverterinputstream +GConverterInputStream +GConverterInputStream +g_converter_input_stream_new +g_converter_input_stream_get_converter + +GConverterInputStreamClass +G_TYPE_CONVERTER_INPUT_STREAM +G_CONVERTER_INPUT_STREAM +G_IS_CONVERTER_INPUT_STREAM +G_CONVERTER_INPUT_STREAM_CLASS +G_IS_CONVERTER_INPUT_STREAM_CLASS +G_CONVERTER_INPUT_STREAM_GET_CLASS + +GConverterInputStreamPrivate +g_converter_input_stream_get_type +
+ +
+gconverteroutputstream +GConverterOutputStream +GConverterOutputStream +g_converter_output_stream_new +g_converter_output_stream_get_converter + +GConverterOutputStreamClass +G_TYPE_CONVERTER_OUTPUT_STREAM +G_CONVERTER_OUTPUT_STREAM +G_IS_CONVERTER_OUTPUT_STREAM +G_CONVERTER_OUTPUT_STREAM_CLASS +G_IS_CONVERTER_OUTPUT_STREAM_CLASS +G_CONVERTER_OUTPUT_STREAM_GET_CLASS + +GConverterOutputStreamPrivate +g_converter_output_stream_get_type +
+ +
+gzlibcompressor +GZlibCompressor +GZlibCompressor +GZlibCompressorFormat +g_zlib_compressor_new +g_zlib_compressor_get_file_info +g_zlib_compressor_set_file_info + +GZlibCompressorClass +G_TYPE_ZLIB_COMPRESSOR +G_ZLIB_COMPRESSOR +G_IS_ZLIB_COMPRESSOR +G_ZLIB_COMPRESSOR_CLASS +G_IS_ZLIB_COMPRESSOR_CLASS +G_ZLIB_COMPRESSOR_GET_CLASS +G_TYPE_ZLIB_COMPRESSOR_FORMAT + +g_zlib_compressor_get_type +g_zlib_compressor_format_get_type +
+ +
+gzlibdecompressor +GZlibDecompressor +GZlibDecompressor +g_zlib_decompressor_new +g_zlib_decompressor_get_file_info + +GZlibDecompressorClass +G_TYPE_ZLIB_DECOMPRESSOR +G_ZLIB_DECOMPRESSOR +G_IS_ZLIB_DECOMPRESSOR +G_ZLIB_DECOMPRESSOR_CLASS +G_IS_ZLIB_DECOMPRESSOR_CLASS +G_ZLIB_DECOMPRESSOR_GET_CLASS + +g_zlib_decompressor_get_type +
+ +
+gfiledescriptorbased +GFileDescriptorBased +GFileDescriptorBased +GFileDescriptorBasedIface +g_file_descriptor_based_get_fd + +g_file_descriptor_based_get_type +G_FILE_DESCRIPTOR_BASED +G_FILE_DESCRIPTOR_BASED_GET_IFACE +G_IS_FILE_DESCRIPTOR_BASED +G_TYPE_FILE_DESCRIPTOR_BASED +
+ +
+gsettingsbackend +GSettingsBackend +GSettingsBackend +GSettingsBackendClass +G_SETTINGS_BACKEND_EXTENSION_POINT_NAME +g_settings_backend_get_default +g_settings_backend_changed +g_settings_backend_path_changed +g_settings_backend_keys_changed +g_settings_backend_path_writable_changed +g_settings_backend_writable_changed +g_settings_backend_changed_tree +g_settings_backend_flatten_tree +g_keyfile_settings_backend_new +g_memory_settings_backend_new +g_null_settings_backend_new + + +G_IS_SETTINGS_BACKEND +G_IS_SETTINGS_BACKEND_CLASS +G_SETTINGS_BACKEND +G_SETTINGS_BACKEND_CLASS +G_SETTINGS_BACKEND_GET_CLASS +G_TYPE_SETTINGS_BACKEND + + +g_settings_backend_get_type +GSettingsBackendPrivate +
+ +
+gsettingsschema +GSettingsSchema, GSettingsSchemaSource +GSettingsSchemaSource +g_settings_schema_source_get_default +g_settings_schema_source_ref +g_settings_schema_source_unref + + +g_settings_schema_source_new_from_directory + + +g_settings_schema_source_list_schemas +g_settings_schema_source_lookup + + +GSettingsSchema +g_settings_schema_ref +g_settings_schema_unref + + +g_settings_schema_get_id +g_settings_schema_get_path + + +GSettingsSchemaKey +g_settings_schema_has_key +g_settings_schema_get_key +g_settings_schema_key_ref +g_settings_schema_key_unref +g_settings_schema_list_children +g_settings_schema_list_keys + + +g_settings_schema_key_get_value_type +g_settings_schema_key_get_default_value +g_settings_schema_key_get_range +g_settings_schema_key_range_check + + +g_settings_schema_key_get_name +g_settings_schema_key_get_summary +g_settings_schema_key_get_description + + +G_TYPE_SETTINGS_SCHEMA_KEY +G_TYPE_SETTINGS_SCHEMA +G_TYPE_SETTINGS_SCHEMA_SOURCE + + +g_settings_schema_get_type +g_settings_schema_key_get_type +g_settings_schema_source_get_type +
+ +
+gsettings +GSettings +GSettings +g_settings_new +g_settings_new_with_path +g_settings_new_with_backend +g_settings_new_with_backend_and_path +g_settings_new_full +g_settings_sync +g_settings_get_value +g_settings_set_value +g_settings_is_writable +g_settings_delay +g_settings_apply +g_settings_revert +g_settings_get_has_unapplied +g_settings_get_child +g_settings_reset +g_settings_get_user_value +g_settings_get_default_value + + +g_settings_list_schemas +g_settings_list_relocatable_schemas +g_settings_list_keys +g_settings_list_children +g_settings_get_range +g_settings_range_check + + +g_settings_get +g_settings_set +g_settings_get_boolean +g_settings_set_boolean +g_settings_get_int +g_settings_set_int +g_settings_get_int64 +g_settings_set_int64 +g_settings_get_uint +g_settings_set_uint +g_settings_get_uint64 +g_settings_set_uint64 +g_settings_get_double +g_settings_set_double +g_settings_get_string +g_settings_set_string +g_settings_get_strv +g_settings_set_strv +g_settings_get_enum +g_settings_set_enum +g_settings_get_flags +g_settings_set_flags + + +GSettingsGetMapping +g_settings_get_mapped + + +GSettingsBindFlags +g_settings_bind +g_settings_bind_with_mapping +g_settings_bind_writable +g_settings_unbind +GSettingsBindSetMapping +GSettingsBindGetMapping + + +g_settings_create_action + + +GSettingsClass +G_IS_SETTINGS +G_IS_SETTINGS_CLASS +G_SETTINGS +G_SETTINGS_CLASS +G_SETTINGS_GET_CLASS +G_TYPE_SETTINGS +G_TYPE_SETTINGS_BIND_FLAGS + + +GSettingsPrivate +g_settings_get_type +g_settings_bind_flags_get_type +
+ +
+gunixcredentialsmessage +GUnixCredentialsMessage +GUnixCredentialsMessage +GUnixCredentialsMessageClass +g_unix_credentials_message_new +g_unix_credentials_message_new_with_credentials +g_unix_credentials_message_get_credentials +g_unix_credentials_message_is_supported + +G_IS_UNIX_CREDENTIALS_MESSAGE +G_IS_UNIX_CREDENTIALS_MESSAGE_CLASS +G_TYPE_UNIX_CREDENTIALS_MESSAGE +G_UNIX_CREDENTIALS_MESSAGE +G_UNIX_CREDENTIALS_MESSAGE_CLASS +G_UNIX_CREDENTIALS_MESSAGE_GET_CLASS + +GUnixCredentialsMessagePrivate +g_unix_credentials_message_get_type +
+ +
+gcredentials +GCredentials +GCredentials +GCredentialsType +g_credentials_new +g_credentials_to_string +g_credentials_get_native +g_credentials_set_native +g_credentials_is_same_user +g_credentials_get_unix_user +g_credentials_set_unix_user +g_credentials_get_unix_pid + +G_CREDENTIALS +G_IS_CREDENTIALS +G_TYPE_CREDENTIALS +G_CREDENTIALS_CLASS +G_IS_CREDENTIALS_CLASS +G_CREDENTIALS_GET_CLASS +G_TYPE_CREDENTIALS_TYPE + +g_credentials_get_type +g_credentials_type_get_type +G_CREDENTIALS_NATIVE_SIZE +G_CREDENTIALS_NATIVE_TYPE +G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED +G_CREDENTIALS_SPOOFING_SUPPORTED +G_CREDENTIALS_SUPPORTED +G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED +G_CREDENTIALS_USE_FREEBSD_CMSGCRED +G_CREDENTIALS_USE_LINUX_UCRED +G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED +G_CREDENTIALS_USE_SOLARIS_UCRED +
+ +
+gdbusaddress +g_dbus_is_address +g_dbus_is_supported_address +g_dbus_address_get_stream +g_dbus_address_get_stream_finish +g_dbus_address_get_stream_sync +g_dbus_address_get_for_bus_sync +g_dbus_address_escape_value +
+ +
+gdbusutils +g_dbus_generate_guid +g_dbus_is_guid +g_dbus_is_name +g_dbus_is_unique_name +g_dbus_is_member_name +g_dbus_is_interface_name +g_dbus_is_error_name +g_dbus_gvalue_to_gvariant +g_dbus_gvariant_to_gvalue +g_dbus_escape_object_path_bytestring +g_dbus_escape_object_path +g_dbus_unescape_object_path +
+ +
+gdbusauthobserver +GDBusAuthObserver +GDBusAuthObserver +g_dbus_auth_observer_new +g_dbus_auth_observer_authorize_authenticated_peer +g_dbus_auth_observer_allow_mechanism + +G_DBUS_AUTH_OBSERVER +G_IS_DBUS_AUTH_OBSERVER +G_TYPE_DBUS_AUTH_OBSERVER + +g_dbus_auth_observer_get_type +
+ +
+gdbusserver +GDBusServer +GDBusServer +GDBusServerFlags +g_dbus_server_new_sync +g_dbus_server_start +g_dbus_server_stop +g_dbus_server_is_active +g_dbus_server_get_guid +g_dbus_server_get_flags +g_dbus_server_get_client_address + +G_DBUS_SERVER +G_IS_DBUS_SERVER +G_TYPE_DBUS_SERVER +G_TYPE_DBUS_SERVER_FLAGS + +g_dbus_server_get_type +g_dbus_server_flags_get_type +
+ +
+gdbusmessage +GDBusMessage +GDBusMessage +GDBusMessageType +GDBusMessageFlags +GDBusMessageHeaderField +GDBusMessageByteOrder +g_dbus_message_new +g_dbus_message_new_signal +g_dbus_message_new_method_call +g_dbus_message_new_method_reply +g_dbus_message_new_method_error +g_dbus_message_new_method_error_valist +g_dbus_message_new_method_error_literal +g_dbus_message_print +g_dbus_message_get_locked +g_dbus_message_lock +g_dbus_message_copy +g_dbus_message_get_byte_order +g_dbus_message_set_byte_order +g_dbus_message_get_message_type +g_dbus_message_set_message_type +g_dbus_message_get_serial +g_dbus_message_set_serial +g_dbus_message_get_flags +g_dbus_message_set_flags +g_dbus_message_get_body +g_dbus_message_set_body +g_dbus_message_get_unix_fd_list +g_dbus_message_set_unix_fd_list +g_dbus_message_get_num_unix_fds +g_dbus_message_set_num_unix_fds +g_dbus_message_get_header_fields +g_dbus_message_get_header +g_dbus_message_set_header +g_dbus_message_get_destination +g_dbus_message_set_destination +g_dbus_message_get_error_name +g_dbus_message_set_error_name +g_dbus_message_get_interface +g_dbus_message_set_interface +g_dbus_message_get_member +g_dbus_message_set_member +g_dbus_message_get_path +g_dbus_message_set_path +g_dbus_message_get_reply_serial +g_dbus_message_set_reply_serial +g_dbus_message_get_sender +g_dbus_message_set_sender +g_dbus_message_get_signature +g_dbus_message_set_signature +g_dbus_message_get_arg0 +g_dbus_message_to_blob +g_dbus_message_bytes_needed +g_dbus_message_new_from_blob +g_dbus_message_to_gerror + +G_DBUS_MESSAGE +G_IS_DBUS_MESSAGE +G_TYPE_DBUS_MESSAGE +G_TYPE_DBUS_MESSAGE_BYTE_ORDER +G_TYPE_DBUS_MESSAGE_FLAGS +G_TYPE_DBUS_MESSAGE_HEADER_FIELD +G_TYPE_DBUS_MESSAGE_TYPE + +g_dbus_message_get_type +g_dbus_message_byte_order_get_type +g_dbus_message_flags_get_type +g_dbus_message_header_field_get_type +g_dbus_message_type_get_type +
+ +
+gdbusconnection +GDBusConnection +GBusType +g_bus_get +g_bus_get_finish +g_bus_get_sync +GDBusConnection +GDBusConnectionFlags +g_dbus_connection_new +g_dbus_connection_new_finish +g_dbus_connection_new_sync +g_dbus_connection_new_for_address +g_dbus_connection_new_for_address_finish +g_dbus_connection_new_for_address_sync +g_dbus_connection_start_message_processing +g_dbus_connection_close +g_dbus_connection_close_finish +g_dbus_connection_close_sync +g_dbus_connection_is_closed +g_dbus_connection_flush +g_dbus_connection_flush_finish +g_dbus_connection_flush_sync +g_dbus_connection_get_exit_on_close +g_dbus_connection_set_exit_on_close +g_dbus_connection_get_stream +g_dbus_connection_get_flags +g_dbus_connection_get_guid +g_dbus_connection_get_unique_name +GDBusCapabilityFlags +g_dbus_connection_get_capabilities +g_dbus_connection_get_peer_credentials +g_dbus_connection_get_last_serial +GDBusCallFlags +g_dbus_connection_call +g_dbus_connection_call_finish +g_dbus_connection_call_sync +g_dbus_connection_call_with_unix_fd_list +g_dbus_connection_call_with_unix_fd_list_finish +g_dbus_connection_call_with_unix_fd_list_sync +g_dbus_connection_emit_signal +GDBusSignalFlags +GDBusSignalCallback +g_dbus_connection_signal_subscribe +g_dbus_connection_signal_unsubscribe +GDBusSendMessageFlags +g_dbus_connection_send_message +g_dbus_connection_send_message_with_reply +g_dbus_connection_send_message_with_reply_finish +g_dbus_connection_send_message_with_reply_sync +GDBusMessageFilterFunction +g_dbus_connection_add_filter +g_dbus_connection_remove_filter +GDBusInterfaceVTable +GDBusInterfaceMethodCallFunc +GDBusInterfaceGetPropertyFunc +GDBusInterfaceSetPropertyFunc +g_dbus_connection_register_object +g_dbus_connection_unregister_object +g_dbus_connection_register_object_with_closures +GDBusSubtreeVTable +GDBusSubtreeEnumerateFunc +GDBusSubtreeIntrospectFunc +GDBusSubtreeDispatchFunc +GDBusSubtreeFlags +g_dbus_connection_register_subtree +g_dbus_connection_unregister_subtree + +G_DBUS_CONNECTION +G_IS_DBUS_CONNECTION +G_TYPE_DBUS_CONNECTION +G_TYPE_BUS_TYPE +G_TYPE_DBUS_CALL_FLAGS +G_TYPE_DBUS_CAPABILITY_FLAGS +G_TYPE_DBUS_CONNECTION_FLAGS +G_TYPE_DBUS_SEND_MESSAGE_FLAGS +G_TYPE_DBUS_SIGNAL_FLAGS +G_TYPE_DBUS_SUBTREE_FLAGS + +g_dbus_connection_get_type +g_bus_type_get_type +g_dbus_call_flags_get_type +g_dbus_capability_flags_get_type +g_dbus_connection_flags_get_type +g_dbus_send_message_flags_get_type +g_dbus_signal_flags_get_type +g_dbus_subtree_flags_get_type +
+ +
+gdbusmethodinvocation +GDBusMethodInvocation +GDBusMethodInvocation +g_dbus_method_invocation_get_sender +g_dbus_method_invocation_get_object_path +g_dbus_method_invocation_get_interface_name +g_dbus_method_invocation_get_method_name +g_dbus_method_invocation_get_method_info +g_dbus_method_invocation_get_property_info +g_dbus_method_invocation_get_connection +g_dbus_method_invocation_get_message +g_dbus_method_invocation_get_parameters +g_dbus_method_invocation_get_user_data +g_dbus_method_invocation_return_value +g_dbus_method_invocation_return_error +g_dbus_method_invocation_return_error_valist +g_dbus_method_invocation_return_error_literal +g_dbus_method_invocation_return_gerror +g_dbus_method_invocation_return_dbus_error +g_dbus_method_invocation_take_error +g_dbus_method_invocation_return_value_with_unix_fd_list +G_DBUS_METHOD_INVOCATION_HANDLED +G_DBUS_METHOD_INVOCATION_UNHANDLED + +G_DBUS_METHOD_INVOCATION +G_IS_DBUS_METHOD_INVOCATION +G_TYPE_DBUS_METHOD_INVOCATION + +g_dbus_method_invocation_get_type +
+ +
+gdbusnameowning +GBusAcquiredCallback +GBusNameAcquiredCallback +GBusNameLostCallback +GBusNameOwnerFlags +g_bus_own_name +g_bus_own_name_on_connection +g_bus_unown_name +g_bus_own_name_with_closures +g_bus_own_name_on_connection_with_closures + + +G_TYPE_BUS_NAME_OWNER_FLAGS + +g_bus_name_owner_flags_get_type +
+ +
+gdbusnamewatching +GBusNameAppearedCallback +GBusNameVanishedCallback +GBusNameWatcherFlags +g_bus_watch_name +g_bus_watch_name_on_connection +g_bus_unwatch_name +g_bus_watch_name_with_closures +g_bus_watch_name_on_connection_with_closures + + +G_TYPE_BUS_NAME_WATCHER_FLAGS + +g_bus_name_watcher_flags_get_type +
+ +
+gdbuserror +GDBusError +G_DBUS_ERROR +g_dbus_error_is_remote_error +g_dbus_error_get_remote_error +g_dbus_error_strip_remote_error +GDBusErrorEntry +g_dbus_error_register_error_domain +g_dbus_error_register_error +g_dbus_error_unregister_error +g_dbus_error_new_for_dbus_error +g_dbus_error_set_dbus_error +g_dbus_error_set_dbus_error_valist +g_dbus_error_encode_gerror + +G_TYPE_DBUS_ERROR +g_dbus_error_quark +g_dbus_error_get_type +
+ +
+gdbusproxy +GDBusProxy +GDBusProxyFlags +GDBusProxy +GDBusProxyClass +g_dbus_proxy_new +g_dbus_proxy_new_finish +g_dbus_proxy_new_sync +g_dbus_proxy_new_for_bus +g_dbus_proxy_new_for_bus_finish +g_dbus_proxy_new_for_bus_sync +g_dbus_proxy_get_flags +g_dbus_proxy_get_connection +g_dbus_proxy_get_name +g_dbus_proxy_get_name_owner +g_dbus_proxy_get_object_path +g_dbus_proxy_get_interface_name +g_dbus_proxy_get_default_timeout +g_dbus_proxy_set_default_timeout +g_dbus_proxy_get_cached_property +g_dbus_proxy_set_cached_property +g_dbus_proxy_get_cached_property_names +g_dbus_proxy_set_interface_info +g_dbus_proxy_get_interface_info +g_dbus_proxy_call +g_dbus_proxy_call_finish +g_dbus_proxy_call_sync +g_dbus_proxy_call_with_unix_fd_list +g_dbus_proxy_call_with_unix_fd_list_finish +g_dbus_proxy_call_with_unix_fd_list_sync + +G_DBUS_PROXY +G_IS_DBUS_PROXY +G_TYPE_DBUS_PROXY +G_DBUS_PROXY_CLASS +G_IS_DBUS_PROXY_CLASS +G_DBUS_PROXY_GET_CLASS +G_TYPE_DBUS_PROXY_FLAGS + +GDBusProxyPrivate +g_dbus_proxy_get_type +g_dbus_proxy_flags_get_type +
+ +
+gdbusintrospection +GDBusAnnotationInfo +GDBusArgInfo +GDBusMethodInfo +GDBusSignalInfo +GDBusPropertyInfoFlags +GDBusPropertyInfo +GDBusInterfaceInfo +GDBusNodeInfo +g_dbus_annotation_info_lookup +g_dbus_interface_info_lookup_method +g_dbus_interface_info_lookup_signal +g_dbus_interface_info_lookup_property +g_dbus_interface_info_cache_build +g_dbus_interface_info_cache_release +g_dbus_interface_info_generate_xml +g_dbus_node_info_new_for_xml +g_dbus_node_info_lookup_interface +g_dbus_node_info_generate_xml +G_TYPE_DBUS_NODE_INFO +G_TYPE_DBUS_INTERFACE_INFO +G_TYPE_DBUS_METHOD_INFO +G_TYPE_DBUS_SIGNAL_INFO +G_TYPE_DBUS_PROPERTY_INFO +G_TYPE_DBUS_ARG_INFO +G_TYPE_DBUS_ANNOTATION_INFO +g_dbus_node_info_ref +g_dbus_interface_info_ref +g_dbus_method_info_ref +g_dbus_signal_info_ref +g_dbus_property_info_ref +g_dbus_arg_info_ref +g_dbus_annotation_info_ref +g_dbus_node_info_unref +g_dbus_interface_info_unref +g_dbus_method_info_unref +g_dbus_signal_info_unref +g_dbus_property_info_unref +g_dbus_arg_info_unref +g_dbus_annotation_info_unref + +G_TYPE_DBUS_PROPERTY_INFO_FLAGS + +g_dbus_annotation_info_get_type +g_dbus_arg_info_get_type +g_dbus_interface_info_get_type +g_dbus_method_info_get_type +g_dbus_node_info_get_type +g_dbus_property_info_get_type +g_dbus_signal_info_get_type +g_dbus_property_info_flags_get_type +
+ +
+gpermission +GPermission +g_permission_get_allowed +g_permission_get_can_acquire +g_permission_get_can_release + +g_permission_acquire +g_permission_acquire_async +g_permission_acquire_finish +g_permission_release +g_permission_release_async +g_permission_release_finish + +g_permission_impl_update + +G_PERMISSION +G_PERMISSION_CLASS +G_PERMISSION_GET_CLASS +G_IS_PERMISSION +G_IS_PERMISSION_CLASS +GPermissionClass +G_TYPE_PERMISSION + +g_permission_get_type +GPermissionPrivate +
+ +
+gsimplepermission +GSimplePermission +g_simple_permission_new + + +G_SIMPLE_PERMISSION +G_IS_SIMPLE_PERMISSION +G_TYPE_SIMPLE_PERMISSION + + +g_simple_permission_get_type +
+ +
+gapplication +GApplication +GApplicationClass + +GApplicationFlags +g_application_id_is_valid +g_application_new + +g_application_get_application_id +g_application_set_application_id + +g_application_get_inactivity_timeout +g_application_set_inactivity_timeout + +g_application_get_flags +g_application_set_flags + +g_application_get_resource_base_path +g_application_set_resource_base_path + +g_application_get_dbus_connection +g_application_get_dbus_object_path + +g_application_set_action_group + +g_application_get_is_registered +g_application_get_is_remote +g_application_register + +g_application_hold +g_application_release +g_application_quit + +g_application_activate +g_application_open + +g_application_send_notification +g_application_withdraw_notification + +g_application_run +g_application_add_main_option_entries +g_application_add_main_option +g_application_add_option_group +g_application_set_option_context_parameter_string +g_application_set_option_context_summary +g_application_set_option_context_description + +g_application_set_default +g_application_get_default + +g_application_mark_busy +g_application_unmark_busy +g_application_get_is_busy +g_application_bind_busy_property +g_application_unbind_busy_property + +G_TYPE_APPLICATION +G_APPLICATION +G_APPLICATION_CLASS +G_IS_APPLICATION +G_IS_APPLICATION_CLASS +G_APPLICATION_GET_CLASS +G_TYPE_APPLICATION_FLAGS + +GApplicationPrivate +g_application_get_type +g_application_flags_get_type +
+ +
+gapplicationcommandline +GApplicationCommandLine +GApplicationCommandLineClass + +g_application_command_line_get_arguments +g_application_command_line_get_cwd +g_application_command_line_get_environ +g_application_command_line_get_options_dict +g_application_command_line_get_stdin +g_application_command_line_create_file_for_arg +g_application_command_line_getenv +g_application_command_line_get_is_remote +g_application_command_line_get_platform_data + +g_application_command_line_set_exit_status +g_application_command_line_get_exit_status + +g_application_command_line_print +g_application_command_line_printerr + +G_TYPE_APPLICATION_COMMAND_LINE +G_APPLICATION_COMMAND_LINE +G_APPLICATION_COMMAND_LINE_CLASS +G_IS_APPLICATION_COMMAND_LINE +G_IS_APPLICATION_COMMAND_LINE_CLASS +G_APPLICATION_COMMAND_LINE_GET_CLASS + +GApplicationCommandLinePrivate +g_application_command_line_get_type +
+ + +
+gactiongroup +GActionGroup +GActionGroup +GActionGroupInterface + + +g_action_group_list_actions +g_action_group_query_action + + +g_action_group_has_action +g_action_group_get_action_enabled +g_action_group_get_action_parameter_type +g_action_group_get_action_state_type +g_action_group_get_action_state_hint +g_action_group_get_action_state + + +g_action_group_change_action_state +g_action_group_activate_action + + +g_action_group_action_added +g_action_group_action_removed +g_action_group_action_enabled_changed +g_action_group_action_state_changed + + +g_action_group_get_type +G_TYPE_ACTION_GROUP +G_IS_ACTION_GROUP +G_ACTION_GROUP_GET_IFACE +G_ACTION_GROUP +
+ +
+gactiongroupexporter +g_dbus_connection_export_action_group +g_dbus_connection_unexport_action_group +
+ +
+gdbusactiongroup +GDBusActionGroup +g_dbus_action_group_get + + +G_TYPE_DBUS_ACTION_GROUP +G_DBUS_ACTION_GROUP +G_DBUS_ACTION_GROUP_CLASS +G_IS_DBUS_ACTION_GROUP +G_IS_DBUS_ACTION_GROUP_CLASS +G_DBUS_ACTION_GROUP_GET_CLASS + + +g_dbus_action_group_get_type +
+ +
+gremoteactiongroup +GRemoteActionGroup +GRemoteActionGroupInterface + + +g_remote_action_group_activate_action_full +g_remote_action_group_change_action_state_full + + +G_TYPE_REMOTE_ACTION_GROUP +G_REMOTE_ACTION_GROUP +G_IS_REMOTE_ACTION_GROUP +G_REMOTE_ACTION_GROUP_GET_IFACE +g_remote_action_group_get_type +
+ +
+gaction +GAction +GAction +GActionInterface + + +g_action_name_is_valid +g_action_get_name +g_action_get_parameter_type +g_action_get_state_type +g_action_get_state_hint + + +g_action_get_enabled +g_action_get_state + + +g_action_change_state +g_action_activate + + +g_action_parse_detailed_name +g_action_print_detailed_name + + +g_action_get_type +G_TYPE_ACTION +G_IS_ACTION +G_ACTION_GET_IFACE +G_ACTION +
+ +
+gsimpleaction +GSimpleAction +GSimpleAction + + +g_simple_action_new +g_simple_action_new_stateful + + +g_simple_action_set_enabled +g_simple_action_set_state +g_simple_action_set_state_hint + + +g_simple_action_get_type +G_TYPE_SIMPLE_ACTION +G_IS_SIMPLE_ACTION +G_SIMPLE_ACTION +
+ +
+gpropertyaction +GPropertyAction +GPropertyAction + + +g_property_action_new + + +g_property_action_get_type +G_TYPE_PROPERTY_ACTION +G_IS_PROPERTY_ACTION +G_PROPERTY_ACTION +
+ +
+gsimpleactiongroup +GSimpleActionGroup +GSimpleActionGroup + + +g_simple_action_group_new + + +g_simple_action_group_lookup +g_simple_action_group_insert +g_simple_action_group_remove + + +g_simple_action_group_add_entries + + +GSimpleActionGroupClass +GSimpleActionGroupPrivate +g_simple_action_group_get_type +G_TYPE_SIMPLE_ACTION_GROUP +G_IS_SIMPLE_ACTION_GROUP +G_SIMPLE_ACTION_GROUP_CLASS +G_SIMPLE_ACTION_GROUP_GET_CLASS +G_IS_SIMPLE_ACTION_GROUP_CLASS +G_SIMPLE_ACTION_GROUP +
+ +
+gactionmap +GActionMap +GActionMap +GActionMapInterface +g_action_map_lookup_action +GActionEntry +g_action_map_add_action_entries +g_action_map_add_action +g_action_map_remove_action + + +G_TYPE_ACTION_MAP +G_ACTION_MAP +G_IS_ACTION_MAP +G_ACTION_MAP_GET_IFACE + + +g_action_map_get_type +
+ +
+gproxyresolver +GProxyResolver +GProxyResolver +GProxyResolverInterface +G_PROXY_RESOLVER_EXTENSION_POINT_NAME +g_proxy_resolver_get_default +g_proxy_resolver_is_supported +g_proxy_resolver_lookup +g_proxy_resolver_lookup_async +g_proxy_resolver_lookup_finish + +G_PROXY_RESOLVER +G_IS_PROXY_RESOLVER +G_TYPE_PROXY_RESOLVER +G_PROXY_RESOLVER_GET_IFACE + +g_proxy_resolver_get_type +
+ +
+gproxyaddress +GProxyAddress +GProxyAddress +GProxyAddressClass +g_proxy_address_get_destination_protocol +g_proxy_address_get_destination_hostname +g_proxy_address_get_destination_port +g_proxy_address_get_password +g_proxy_address_get_protocol +g_proxy_address_get_username +g_proxy_address_get_uri +g_proxy_address_new + +G_PROXY_ADDRESS +G_PROXY_ADDRESS_CLASS +G_PROXY_ADDRESS_GET_CLASS +G_IS_PROXY_ADDRESS +G_IS_PROXY_ADDRESS_CLASS +G_TYPE_PROXY_ADDRESS + +GProxyAddressPrivate +g_proxy_address_get_type +
+ +
+gproxy +GProxy +GProxy +GProxyInterface +G_PROXY_EXTENSION_POINT_NAME +g_proxy_connect +g_proxy_connect_async +g_proxy_connect_finish +g_proxy_get_default_for_protocol +g_proxy_supports_hostname + +G_PROXY +G_PROXY_GET_IFACE +G_IS_PROXY +G_TYPE_PROXY + +g_proxy_get_type +
+ +
+gpollableinputstream +GPollableInputStream +GPollableInputStream +GPollableInputStreamInterface + +g_pollable_input_stream_can_poll +g_pollable_input_stream_is_readable +g_pollable_input_stream_create_source +g_pollable_input_stream_read_nonblocking + +G_POLLABLE_INPUT_STREAM +G_POLLABLE_INPUT_STREAM_GET_INTERFACE +G_IS_POLLABLE_INPUT_STREAM +G_TYPE_POLLABLE_INPUT_STREAM + +g_pollable_input_stream_get_type +
+ +
+gpollableoutputstream +GPollableOutputStream +GPollableOutputStream +GPollableOutputStreamInterface + +g_pollable_output_stream_can_poll +g_pollable_output_stream_is_writable +g_pollable_output_stream_create_source +g_pollable_output_stream_write_nonblocking +g_pollable_output_stream_writev_nonblocking + +G_POLLABLE_OUTPUT_STREAM +G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE +G_IS_POLLABLE_OUTPUT_STREAM +G_TYPE_POLLABLE_OUTPUT_STREAM + +g_pollable_output_stream_get_type +
+ +
+gpollableutils +GPollableReturn +GPollableSourceFunc +g_pollable_source_new +g_pollable_source_new_full + +g_pollable_stream_read +g_pollable_stream_write +g_pollable_stream_write_all + +G_TYPE_POLLABLE_RETURN + +g_pollable_return_get_type +
+ +
+gtls +G_TLS_ERROR +GTlsError +G_TLS_CHANNEL_BINDING_ERROR +GTlsChannelBindingError + +GTlsAuthenticationMode +GTlsCertificateFlags +GTlsProtocolVersion + +G_TYPE_TLS_AUTHENTICATION_MODE +G_TYPE_TLS_CERTIFICATE_FLAGS +G_TYPE_TLS_CHANNEL_BINDING_ERROR +G_TYPE_TLS_ERROR +G_TYPE_TLS_PROTOCOL_VERSION +g_tls_authentication_mode_get_type +g_tls_certificate_flags_get_type +g_tls_channel_binding_error_get_type +g_tls_channel_binding_error_quark +g_tls_error_get_type +g_tls_protocol_version_get_type +
+ +
+gtlsbackend +GTlsBackend +G_TLS_BACKEND_EXTENSION_POINT_NAME +GTlsBackend +GTlsBackendInterface +g_tls_backend_get_default +g_tls_backend_supports_tls +g_tls_backend_supports_dtls +g_tls_backend_get_default_database +g_tls_backend_set_default_database +g_tls_backend_get_certificate_type +g_tls_backend_get_client_connection_type +g_tls_backend_get_server_connection_type +g_tls_backend_get_dtls_client_connection_type +g_tls_backend_get_dtls_server_connection_type +g_tls_backend_get_file_database_type + +G_IS_TLS_BACKEND +G_TLS_BACKEND +G_TLS_BACKEND_GET_INTERFACE +G_TYPE_TLS_BACKEND +g_tls_error_quark + +g_tls_backend_get_type +
+ +
+gtlscertificate +GTlsCertificate +GTlsCertificate +g_tls_certificate_new_from_pem +g_tls_certificate_new_from_pkcs12 +g_tls_certificate_new_from_file +g_tls_certificate_new_from_file_with_password +g_tls_certificate_new_from_files +g_tls_certificate_new_from_pkcs11_uris +g_tls_certificate_list_new_from_file +g_tls_certificate_get_dns_names +g_tls_certificate_get_ip_addresses +g_tls_certificate_get_issuer +g_tls_certificate_get_issuer_name +g_tls_certificate_get_not_valid_before +g_tls_certificate_get_not_valid_after +g_tls_certificate_get_subject_name +g_tls_certificate_verify +g_tls_certificate_is_same + +GTlsCertificateClass +GTlsCertificatePrivate +G_IS_TLS_CERTIFICATE +G_IS_TLS_CERTIFICATE_CLASS +G_TLS_CERTIFICATE +G_TLS_CERTIFICATE_CLASS +G_TLS_CERTIFICATE_GET_CLASS +G_TYPE_TLS_CERTIFICATE + +g_tls_certificate_get_type +
+ +
+gtlsconnection +GTlsConnection +GTlsConnection +GTlsChannelBindingType +g_tls_connection_set_certificate +g_tls_connection_get_certificate +g_tls_connection_get_peer_certificate +g_tls_connection_get_peer_certificate_errors +g_tls_connection_get_channel_binding_data +g_tls_connection_set_require_close_notify +g_tls_connection_get_require_close_notify +GTlsRehandshakeMode +g_tls_connection_set_rehandshake_mode +g_tls_connection_get_rehandshake_mode +g_tls_connection_set_advertised_protocols +g_tls_connection_get_negotiated_protocol +g_tls_connection_set_use_system_certdb +g_tls_connection_get_use_system_certdb +g_tls_connection_get_database +g_tls_connection_set_database +g_tls_connection_get_interaction +g_tls_connection_set_interaction +g_tls_connection_get_protocol_version +g_tls_connection_get_ciphersuite_name + +g_tls_connection_handshake +g_tls_connection_handshake_async +g_tls_connection_handshake_finish + +g_tls_connection_emit_accept_certificate + +GTlsConnectionClass +GTlsConnectionPrivate +G_IS_TLS_CONNECTION +G_IS_TLS_CONNECTION_CLASS +G_TLS_CONNECTION +G_TLS_CONNECTION_CLASS +G_TLS_CONNECTION_GET_CLASS +G_TYPE_TLS_CHANNEL_BINDING_TYPE +G_TYPE_TLS_CONNECTION +G_TYPE_TLS_REHANDSHAKE_MODE + +g_tls_channel_binding_type_get_type +g_tls_connection_get_type +g_tls_rehandshake_mode_get_type +
+ +
+gtlsclientconnection +GTlsClientConnection +GTlsClientConnection +GTlsClientConnectionInterface +g_tls_client_connection_new +g_tls_client_connection_set_server_identity +g_tls_client_connection_get_server_identity +g_tls_client_connection_set_validation_flags +g_tls_client_connection_get_validation_flags +g_tls_client_connection_set_use_ssl3 +g_tls_client_connection_get_use_ssl3 +g_tls_client_connection_get_accepted_cas +g_tls_client_connection_copy_session_state + +G_IS_TLS_CLIENT_CONNECTION +G_TLS_CLIENT_CONNECTION +G_TLS_CLIENT_CONNECTION_GET_INTERFACE +G_TYPE_TLS_CLIENT_CONNECTION + +g_tls_client_connection_get_type +
+ +
+gtlsdatabase +GTlsDatabase +GTlsDatabase +GTlsDatabaseClass +GTlsDatabaseVerifyFlags +G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER +G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT +g_tls_database_verify_chain +g_tls_database_verify_chain_async +g_tls_database_verify_chain_finish +GTlsDatabaseLookupFlags +g_tls_database_lookup_certificate_issuer +g_tls_database_lookup_certificate_issuer_async +g_tls_database_lookup_certificate_issuer_finish +g_tls_database_lookup_certificates_issued_by +g_tls_database_lookup_certificates_issued_by_async +g_tls_database_lookup_certificates_issued_by_finish +g_tls_database_create_certificate_handle +g_tls_database_lookup_certificate_for_handle +g_tls_database_lookup_certificate_for_handle_async +g_tls_database_lookup_certificate_for_handle_finish + +G_IS_TLS_DATABASE +G_IS_TLS_DATABASE_CLASS +G_TLS_DATABASE +G_TLS_DATABASE_CLASS +G_TLS_DATABASE_GET_CLASS +G_TYPE_TLS_DATABASE +G_TYPE_TLS_DATABASE_LOOKUP_FLAGS +G_TYPE_TLS_DATABASE_VERIFY_FLAGS + +g_tls_database_lookup_flags_get_type +g_tls_database_verify_flags_get_type +g_tls_database_get_type +GTlsDatabasePrivate +
+ +
+gtlsfiledatabase +GTlsFileDatabase +GTlsFileDatabase +GTlsFileDatabaseInterface +g_tls_file_database_new + +G_TLS_FILE_DATABASE +G_TLS_FILE_DATABASE_GET_INTERFACE +G_TYPE_TLS_FILE_DATABASE +G_IS_TLS_FILE_DATABASE + +g_tls_file_database_get_type +
+ +
+gtlsserverconnection +GTlsServerConnection +GTlsServerConnection +GTlsServerConnectionInterface +g_tls_server_connection_new + +G_IS_TLS_SERVER_CONNECTION +G_TLS_SERVER_CONNECTION +G_TLS_SERVER_CONNECTION_GET_INTERFACE +G_TYPE_TLS_SERVER_CONNECTION + +g_tls_server_connection_get_type +
+ +
+gtlspassword +GTlsPassword +GTlsPassword +GTlsPasswordClass +GTlsPasswordFlags +g_tls_password_new +g_tls_password_get_value +g_tls_password_set_value +g_tls_password_set_value_full +g_tls_password_get_description +g_tls_password_set_description +g_tls_password_get_flags +g_tls_password_set_flags +g_tls_password_get_warning +g_tls_password_set_warning + +g_tls_password_flags_get_type +g_tls_password_get_type +G_IS_TLS_PASSWORD +G_TLS_PASSWORD +G_TYPE_TLS_PASSWORD +G_TYPE_TLS_PASSWORD_FLAGS +G_TLS_PASSWORD_CLASS +G_TLS_PASSWORD_GET_CLASS +G_IS_TLS_PASSWORD_CLASS + +GTlsPasswordPrivate +
+ +
+gtlsinteraction +GTlsInteraction +GTlsInteraction +GTlsInteractionResult +GTlsCertificateRequestFlags +GTlsInteractionClass +g_tls_interaction_invoke_ask_password +g_tls_interaction_invoke_request_certificate +g_tls_interaction_ask_password +g_tls_interaction_ask_password_async +g_tls_interaction_ask_password_finish +g_tls_interaction_request_certificate +g_tls_interaction_request_certificate_async +g_tls_interaction_request_certificate_finish + +G_IS_TLS_INTERACTION +G_IS_TLS_INTERACTION_CLASS +G_TYPE_TLS_INTERACTION +G_TLS_INTERACTION +G_TLS_INTERACTION_CLASS +G_TLS_INTERACTION_GET_CLASS +G_TYPE_TLS_INTERACTION_RESULT +G_TYPE_TLS_CERTIFICATE_REQUEST_FLAGS + +GTlsInteractionPrivate +g_tls_interaction_get_type +g_tls_interaction_result_get_type +g_tls_certificate_request_flags_get_type +
+ +
+gdtlsconnection +GDtlsConnection +GDtlsConnection +g_dtls_connection_set_certificate +g_dtls_connection_get_certificate +g_dtls_connection_get_peer_certificate +g_dtls_connection_get_peer_certificate_errors +g_dtls_connection_get_channel_binding_data +g_dtls_connection_set_require_close_notify +g_dtls_connection_get_require_close_notify +g_dtls_connection_set_rehandshake_mode +g_dtls_connection_get_rehandshake_mode +g_dtls_connection_set_advertised_protocols +g_dtls_connection_get_negotiated_protocol +g_dtls_connection_get_database +g_dtls_connection_set_database +g_dtls_connection_get_interaction +g_dtls_connection_set_interaction +g_dtls_connection_get_protocol_version +g_dtls_connection_get_ciphersuite_name + +g_dtls_connection_handshake +g_dtls_connection_handshake_async +g_dtls_connection_handshake_finish + +g_dtls_connection_shutdown +g_dtls_connection_shutdown_async +g_dtls_connection_shutdown_finish +g_dtls_connection_close +g_dtls_connection_close_async +g_dtls_connection_close_finish + +g_dtls_connection_emit_accept_certificate + +GDtlsConnectionClass +GDtlsConnectionPrivate +G_IS_DTLS_CONNECTION +G_IS_DTLS_CONNECTION_CLASS +G_DTLS_CONNECTION +G_DTLS_CONNECTION_CLASS +G_DTLS_CONNECTION_GET_CLASS +G_TYPE_DTLS_CONNECTION +G_DTLS_CONNECTION_GET_INTERFACE + +g_dtls_connection_get_type +
+ +
+gdtlsclientconnection +GDtlsClientConnection +GDtlsClientConnection +GDtlsClientConnectionInterface +g_dtls_client_connection_new +g_dtls_client_connection_set_server_identity +g_dtls_client_connection_get_server_identity +g_dtls_client_connection_set_validation_flags +g_dtls_client_connection_get_validation_flags +g_dtls_client_connection_get_accepted_cas + +G_IS_DTLS_CLIENT_CONNECTION +G_DTLS_CLIENT_CONNECTION +G_DTLS_CLIENT_CONNECTION_GET_INTERFACE +G_TYPE_DTLS_CLIENT_CONNECTION + +g_dtls_client_connection_get_type +
+ +
+gdtlsserverconnection +GDtlsServerConnection +GDtlsServerConnection +GDtlsServerConnectionInterface +g_dtls_server_connection_new + +G_IS_DTLS_SERVER_CONNECTION +G_DTLS_SERVER_CONNECTION +G_DTLS_SERVER_CONNECTION_GET_INTERFACE +G_TYPE_DTLS_SERVER_CONNECTION + +g_dtls_server_connection_get_type +
+ +
+gdbusinterface +GDBusInterface +GDBusInterface +GDBusInterfaceIface +g_dbus_interface_get_info +g_dbus_interface_get_object +g_dbus_interface_dup_object +g_dbus_interface_set_object + +G_DBUS_INTERFACE +G_IS_DBUS_INTERFACE +G_TYPE_DBUS_INTERFACE +g_dbus_interface_get_type +G_DBUS_INTERFACE_GET_IFACE +
+ + +
+gdbusinterfaceskeleton +GDBusInterfaceSkeleton +GDBusInterfaceSkeleton +GDBusInterfaceSkeletonClass +g_dbus_interface_skeleton_flush +g_dbus_interface_skeleton_get_info +g_dbus_interface_skeleton_get_vtable +g_dbus_interface_skeleton_get_properties +g_dbus_interface_skeleton_export +g_dbus_interface_skeleton_unexport +g_dbus_interface_skeleton_unexport_from_connection +g_dbus_interface_skeleton_get_connection +g_dbus_interface_skeleton_get_connections +g_dbus_interface_skeleton_has_connection +g_dbus_interface_skeleton_get_object_path +GDBusInterfaceSkeletonFlags +g_dbus_interface_skeleton_get_flags +g_dbus_interface_skeleton_set_flags + +G_DBUS_INTERFACE_SKELETON +G_IS_DBUS_INTERFACE_SKELETON +G_TYPE_DBUS_INTERFACE_SKELETON +g_dbus_interface_skeleton_get_type +G_DBUS_INTERFACE_SKELETON_CLASS +G_IS_DBUS_INTERFACE_SKELETON_CLASS +G_DBUS_INTERFACE_SKELETON_GET_CLASS + +GDBusInterfaceSkeletonPrivate +G_TYPE_DBUS_INTERFACE_SKELETON_FLAGS +g_dbus_interface_skeleton_flags_get_type +
+ +
+gdbusobject +GDBusObject +GDBusObject +GDBusObjectIface +g_dbus_object_get_object_path +g_dbus_object_get_interfaces +g_dbus_object_get_interface + +G_DBUS_OBJECT +G_IS_DBUS_OBJECT +G_TYPE_DBUS_OBJECT +g_dbus_object_get_type +G_DBUS_OBJECT_GET_IFACE +
+ +
+gdbusobjectproxy +GDBusObjectProxy +GDBusObjectProxy +GDBusObjectProxyClass +g_dbus_object_proxy_new +g_dbus_object_proxy_get_connection + +G_DBUS_OBJECT_PROXY +G_IS_DBUS_OBJECT_PROXY +G_TYPE_DBUS_OBJECT_PROXY +g_dbus_object_proxy_get_type +G_DBUS_OBJECT_PROXY_CLASS +G_IS_DBUS_OBJECT_PROXY_CLASS +G_DBUS_OBJECT_PROXY_GET_CLASS + +GDBusObjectProxyPrivate +
+ +
+gdbusobjectskeleton +GDBusObjectSkeleton +GDBusObjectSkeleton +GDBusObjectSkeletonClass +g_dbus_object_skeleton_new +g_dbus_object_skeleton_flush +g_dbus_object_skeleton_add_interface +g_dbus_object_skeleton_remove_interface +g_dbus_object_skeleton_remove_interface_by_name +g_dbus_object_skeleton_set_object_path + +G_DBUS_OBJECT_SKELETON +G_IS_DBUS_OBJECT_SKELETON +G_TYPE_DBUS_OBJECT_SKELETON +g_dbus_object_skeleton_get_type +G_DBUS_OBJECT_SKELETON_CLASS +G_IS_DBUS_OBJECT_SKELETON_CLASS +G_DBUS_OBJECT_SKELETON_GET_CLASS + +GDBusObjectSkeletonPrivate +
+ +
+gdbusobjectmanager +GDBusObjectManager +GDBusObjectManager +GDBusObjectManagerIface +g_dbus_object_manager_get_object_path +g_dbus_object_manager_get_objects +g_dbus_object_manager_get_object +g_dbus_object_manager_get_interface + +G_DBUS_OBJECT_MANAGER +G_IS_DBUS_OBJECT_MANAGER +G_TYPE_DBUS_OBJECT_MANAGER +g_dbus_object_manager_get_type +G_DBUS_OBJECT_MANAGER_GET_IFACE +
+ +
+gdbusobjectmanagerclient +GDBusObjectManagerClient +GDBusObjectManagerClient +GDBusObjectManagerClientClass +GDBusObjectManagerClientFlags +GDBusProxyTypeFunc +g_dbus_object_manager_client_new +g_dbus_object_manager_client_new_finish +g_dbus_object_manager_client_new_sync +g_dbus_object_manager_client_new_for_bus +g_dbus_object_manager_client_new_for_bus_finish +g_dbus_object_manager_client_new_for_bus_sync +g_dbus_object_manager_client_get_connection +g_dbus_object_manager_client_get_flags +g_dbus_object_manager_client_get_name +g_dbus_object_manager_client_get_name_owner + +G_DBUS_OBJECT_MANAGER_CLIENT +G_IS_DBUS_OBJECT_MANAGER_CLIENT +G_TYPE_DBUS_OBJECT_MANAGER_CLIENT +g_dbus_object_manager_client_get_type +G_DBUS_OBJECT_MANAGER_CLIENT_CLASS +G_IS_DBUS_OBJECT_MANAGER_CLIENT_CLASS +G_DBUS_OBJECT_MANAGER_CLIENT_GET_CLASS + +GDBusObjectManagerClientPrivate +G_TYPE_DBUS_OBJECT_MANAGER_CLIENT_FLAGS +g_dbus_object_manager_client_flags_get_type +
+ +
+gdbusobjectmanagerserver +GDBusObjectManagerServer +GDBusObjectManagerServer +GDBusObjectManagerServerClass +g_dbus_object_manager_server_new +g_dbus_object_manager_server_get_connection +g_dbus_object_manager_server_set_connection +g_dbus_object_manager_server_export +g_dbus_object_manager_server_export_uniquely +g_dbus_object_manager_server_is_exported +g_dbus_object_manager_server_unexport + +G_DBUS_OBJECT_MANAGER_SERVER +G_IS_DBUS_OBJECT_MANAGER_SERVER +G_TYPE_DBUS_OBJECT_MANAGER_SERVER +g_dbus_object_manager_server_get_type +G_DBUS_OBJECT_MANAGER_SERVER_CLASS +G_IS_DBUS_OBJECT_MANAGER_SERVER_CLASS +G_DBUS_OBJECT_MANAGER_SERVER_GET_CLASS + +GDBusObjectManagerServerPrivate +
+ +
+gdebugcontroller +GDebugController +GDebugController +GDebugControllerInterface +G_DEBUG_CONTROLLER_EXTENSION_POINT_NAME +g_debug_controller_get_debug_enabled +g_debug_controller_set_debug_enabled + +g_debug_controller_get_type +G_TYPE_DEBUG_CONTROLLER +G_DEBUG_CONTROLLER +G_IS_DEBUG_CONTROLLER +G_DEBUG_CONTROLLER_GET_INTERFACE +
+ +
+gdebugcontrollerdbus +GDebugControllerDBus +GDebugControllerDBus +g_debug_controller_dbus_new +g_debug_controller_dbus_stop + +g_debug_controller_dbus_get_type +G_TYPE_DEBUG_CONTROLLER_DBUS +G_DEBUG_CONTROLLER_DBUS +G_IS_DEBUG_CONTROLLER_DBUS +G_DEBUG_CONTROLLER_DBUS_GET_CLASS +
+ +
+gmemorymonitor +GMemoryMonitor +GMemoryMonitor +GMemoryMonitorInterface +GMemoryMonitorWarningLevel +G_MEMORY_MONITOR_EXTENSION_POINT_NAME +g_memory_monitor_dup_default + +g_memory_monitor_get_type +G_TYPE_MEMORY_MONITOR +G_MEMORY_MONITOR +G_IS_MEMORY_MONITOR +G_MEMORY_MONITOR_GET_INTERFACE +G_TYPE_MEMORY_MONITOR_WARNING_LEVEL +g_memory_monitor_warning_level_get_type +
+ +
+gnetworkmonitor +GNetworkMonitor +GNetworkMonitor +GNetworkMonitorInterface +G_NETWORK_MONITOR_EXTENSION_POINT_NAME +g_network_monitor_get_default +g_network_monitor_get_network_available +g_network_monitor_get_network_metered +g_network_monitor_can_reach +g_network_monitor_can_reach_async +g_network_monitor_can_reach_finish +GNetworkConnectivity +g_network_monitor_get_connectivity + +g_network_monitor_get_type +G_TYPE_NETWORK_CONNECTIVITY +G_TYPE_NETWORK_MONITOR +G_NETWORK_MONITOR +G_IS_NETWORK_MONITOR +G_NETWORK_MONITOR_GET_INTERFACE +g_network_connectivity_get_type +
+ +
+gpowerprofilemonitor +GPowerProfileMonitor +GPowerProfileMonitor +GPowerProfileMonitorInterface +G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME +g_power_profile_monitor_dup_default +g_power_profile_monitor_get_power_saver_enabled + +g_power_profile_monitor_get_type +G_TYPE_POWER_PROFILE_MONITOR +G_POWER_PROFILE_MONITOR +G_IS_POWER_PROFILE_MONITOR +G_POWER_PROFILE_MONITOR_GET_INTERFACE +G_TYPE_POWER_PROFILE_LEVEL +g_power_profile_level_get_type +
+ +
+gmenuexporter +g_dbus_connection_export_menu_model +g_dbus_connection_unexport_menu_model +
+ +
+gdbusmenumodel +GDBusMenuModel +g_dbus_menu_model_get + + +G_TYPE_DBUS_MENU_MODEL +G_DBUS_MENU_MODEL +G_IS_DBUS_MENU_MODEL + + +g_dbus_menu_model_get_type +
+ +
+gmenu +GMenu +g_menu_new +g_menu_freeze + + +g_menu_insert +g_menu_prepend +g_menu_append + + +g_menu_insert_item +g_menu_append_item +g_menu_prepend_item + + +g_menu_insert_section +g_menu_prepend_section +g_menu_append_section + + +g_menu_append_submenu +g_menu_insert_submenu +g_menu_prepend_submenu + + +g_menu_remove +g_menu_remove_all + + +GMenuItem +g_menu_item_new +g_menu_item_new_section +g_menu_item_new_submenu +g_menu_item_new_from_model + + +g_menu_item_set_label +g_menu_item_set_icon +g_menu_item_set_action_and_target_value +g_menu_item_set_action_and_target +g_menu_item_set_detailed_action +g_menu_item_set_section +g_menu_item_set_submenu + + +g_menu_item_get_attribute_value +g_menu_item_get_attribute +g_menu_item_get_link +g_menu_item_set_attribute_value +g_menu_item_set_attribute +g_menu_item_set_link + + +g_menu_item_get_type +g_menu_get_type + + +G_TYPE_MENU +G_MENU +G_IS_MENU + +G_TYPE_MENU_ITEM +G_MENU_ITEM +G_IS_MENU_ITEM +
+ +
+gmenumodel +GMenuModel +g_menu_model_is_mutable +g_menu_model_get_n_items + + +G_MENU_ATTRIBUTE_ACTION +G_MENU_ATTRIBUTE_ACTION_NAMESPACE +G_MENU_ATTRIBUTE_TARGET +G_MENU_ATTRIBUTE_LABEL +G_MENU_ATTRIBUTE_ICON +G_MENU_LINK_SECTION +G_MENU_LINK_SUBMENU + + +g_menu_model_get_item_attribute_value +g_menu_model_get_item_attribute +g_menu_model_get_item_link +g_menu_model_iterate_item_attributes +g_menu_model_iterate_item_links + + +g_menu_model_items_changed + + +GMenuAttributeIter +g_menu_attribute_iter_get_next +g_menu_attribute_iter_get_name +g_menu_attribute_iter_get_value +g_menu_attribute_iter_next + + +GMenuLinkIter +g_menu_link_iter_get_name +g_menu_link_iter_get_next +g_menu_link_iter_get_value +g_menu_link_iter_next + + +g_menu_attribute_iter_get_type +g_menu_link_iter_get_type +g_menu_model_get_type +g_menu_model_get_label_quark +g_menu_model_get_action_quark +g_menu_model_get_section_quark +g_menu_model_get_submenu_quark +g_menu_model_get_target_quark + + +GMenuModelClass +GMenuModelPrivate +G_TYPE_MENU_MODEL +G_MENU_MODEL +G_IS_MENU_MODEL +G_MENU_MODEL_CLASS +G_IS_MENU_MODEL_CLASS +G_MENU_MODEL_GET_CLASS + +GMenuAttributeIterClass +GMenuAttributeIterPrivate +G_TYPE_MENU_LINK_ITER +G_MENU_LINK_ITER +G_IS_MENU_LINK_ITER +G_MENU_LINK_ITER_CLASS +G_IS_MENU_LINK_ITER_CLASS +G_MENU_LINK_ITER_GET_CLASS + +GMenuLinkIterClass +GMenuLinkIterPrivate +G_TYPE_MENU_ATTRIBUTE_ITER +G_MENU_ATTRIBUTE_ITER +G_IS_MENU_ATTRIBUTE_ITER +G_MENU_ATTRIBUTE_ITER_CLASS +G_IS_MENU_ATTRIBUTE_ITER_CLASS +G_MENU_ATTRIBUTE_ITER_GET_CLASS +
+ +
+gresource +GResource +GResource +GResourceFlags +GResourceLookupFlags +g_resource_load +g_resource_new_from_data +g_resource_ref +g_resource_unref +g_resource_lookup_data +g_resource_open_stream +g_resource_enumerate_children +g_resource_get_info + + +GStaticResource +g_static_resource_init +g_static_resource_fini +g_static_resource_get_resource + + +g_resources_register +g_resources_unregister +g_resources_lookup_data +g_resources_open_stream +g_resources_enumerate_children +g_resources_get_info + + +G_RESOURCE_ERROR +GResourceError + + +G_TYPE_RESOURCE +G_TYPE_RESOURCE_ERROR +G_TYPE_RESOURCE_FILE +G_TYPE_RESOURCE_FLAGS +G_TYPE_RESOURCE_LOOKUP_FLAGS + + +g_resource_get_type +g_resource_error_get_type +g_resource_flags_get_type +g_resource_lookup_flags_get_type +g_resource_error_quark +
+ +
+gtestdbus +GTestDBus +GTestDBus +GTestDBusFlags +g_test_dbus_new +g_test_dbus_get_flags +g_test_dbus_get_bus_address +g_test_dbus_add_service_dir +g_test_dbus_up +g_test_dbus_stop +g_test_dbus_down +g_test_dbus_unset + +g_test_dbus_get_type +g_test_dbus_flags_get_type + +G_TEST_DBUS +G_IS_TEST_DBUS +G_TYPE_TEST_DBUS +G_TYPE_TEST_DBUS_FLAGS +
+ +
+gtask +GTask +GTask +g_task_new +g_task_set_task_data +g_task_set_priority +g_task_set_check_cancellable +g_task_set_return_on_cancel +g_task_set_source_tag +g_task_set_name + +g_task_report_error +g_task_report_new_error + +g_task_get_task_data +g_task_get_priority +g_task_get_cancellable +g_task_get_check_cancellable +g_task_get_return_on_cancel +g_task_get_context +g_task_get_source_object +g_task_get_source_tag +g_task_get_name + +g_task_return_boolean +g_task_return_int +g_task_return_pointer +g_task_return_value +g_task_return_error +g_task_return_new_error +g_task_return_error_if_cancelled + +g_task_propagate_boolean +g_task_propagate_int +g_task_propagate_pointer +g_task_propagate_value +g_task_had_error +g_task_get_completed + +g_task_run_in_thread +g_task_run_in_thread_sync +GTaskThreadFunc +g_task_attach_source + +g_task_is_valid + +GTaskClass +GTaskPrivate +G_TYPE_TASK +G_TASK +G_IS_TASK +G_TASK_CLASS +G_IS_TASK_CLASS +G_TASK_GET_CLASS +g_task_get_type +
+ +
+gnetworking +gnetworking.h +g_networking_init + +CMSG_LEN +CMSG_SPACE +GLIB_ALIGN_TO_SIZEOF +T_SRV +
+ +
+gsimpleproxyresolver +GSimpleProxyResolver +GSimpleProxyResolver +g_simple_proxy_resolver_new +g_simple_proxy_resolver_set_default_proxy +g_simple_proxy_resolver_set_ignore_hosts +g_simple_proxy_resolver_set_uri_proxy + +GSimpleProxyResolverClass +GSimpleProxyResolverPrivate +G_TYPE_SIMPLE_PROXY_RESOLVER +G_SIMPLE_PROXY_RESOLVER +G_IS_SIMPLE_PROXY_RESOLVER +G_SIMPLE_PROXY_RESOLVER_CLASS +G_IS_SIMPLE_PROXY_RESOLVER_CLASS +G_SIMPLE_PROXY_RESOLVER_GET_CLASS +g_simple_proxy_resolver_get_type +
+ +
+gsubprocess +GSubprocess +GSubprocess +GSubprocessFlags +g_subprocess_new +g_subprocess_newv +g_subprocess_get_identifier + +g_subprocess_get_stdin_pipe +g_subprocess_get_stdout_pipe +g_subprocess_get_stderr_pipe + +g_subprocess_wait +g_subprocess_wait_async +g_subprocess_wait_finish +g_subprocess_wait_check +g_subprocess_wait_check_async +g_subprocess_wait_check_finish + +g_subprocess_get_successful +g_subprocess_get_if_exited +g_subprocess_get_exit_status +g_subprocess_get_if_signaled +g_subprocess_get_term_sig +g_subprocess_get_status + +g_subprocess_send_signal +g_subprocess_force_exit + +g_subprocess_communicate +g_subprocess_communicate_async +g_subprocess_communicate_finish +g_subprocess_communicate_utf8 +g_subprocess_communicate_utf8_async +g_subprocess_communicate_utf8_finish + +G_IS_SUBPROCESS +G_TYPE_SUBPROCESS +G_SUBPROCESS +G_TYPE_SUBPROCESS_FLAGS +g_subprocess_get_type +g_subprocess_flags_get_type +
+ +
+gsubprocesslauncher +GSubprocessLauncher +GSubprocessLauncher +g_subprocess_launcher_new +g_subprocess_launcher_spawn +g_subprocess_launcher_spawnv +g_subprocess_launcher_set_environ +g_subprocess_launcher_setenv +g_subprocess_launcher_unsetenv +g_subprocess_launcher_getenv +g_subprocess_launcher_set_cwd +g_subprocess_launcher_set_flags +g_subprocess_launcher_set_stdin_file_path +g_subprocess_launcher_take_stdin_fd +g_subprocess_launcher_set_stdout_file_path +g_subprocess_launcher_take_stdout_fd +g_subprocess_launcher_set_stderr_file_path +g_subprocess_launcher_take_stderr_fd +g_subprocess_launcher_take_fd +g_subprocess_launcher_close +g_subprocess_launcher_set_child_setup + +G_IS_SUBPROCESS_LAUNCHER +G_SUBPROCESS_LAUNCHER +G_TYPE_SUBPROCESS_LAUNCHER +g_subprocess_launcher_get_type +
+ +
+gnotification +GNotification +GNotification +g_notification_new + +g_notification_set_title +g_notification_set_body +g_notification_set_icon +GNotificationPriority +g_notification_set_priority +g_notification_set_urgent +g_notification_set_category + +g_notification_set_default_action +g_notification_set_default_action_and_target +g_notification_set_default_action_and_target_value + +g_notification_add_button +g_notification_add_button_with_target +g_notification_add_button_with_target_value + +G_IS_NOTIFICATION +G_NOTIFICATION +G_TYPE_NOTIFICATION +G_TYPE_NOTIFICATION_BACKEND +g_notification_get_type +G_TYPE_NOTIFICATION_PRIORITY +g_notification_priority_get_type +
+ +
+glistmodel +GListModel +GListModel +GListModelInterface + +g_list_model_get_item_type +g_list_model_get_n_items +g_list_model_get_item +g_list_model_get_object +g_list_model_items_changed + +G_TYPE_LIST_MODEL +G_LIST_MODEL +G_IS_LIST_MODEL +G_LIST_MODEL_GET_IFACE + +g_list_model_get_type +
+ +
+gliststore +GListStore +GListStore + +g_list_store_new +g_list_store_insert +g_list_store_insert_sorted +g_list_store_append +g_list_store_remove +g_list_store_remove_all +g_list_store_splice +g_list_store_sort +g_list_store_find +g_list_store_find_with_equal_func + +G_TYPE_LIST_STORE + +g_list_store_get_type +
diff --git a/docs/reference/gio/gio-sections-win32.txt b/docs/reference/gio/gio-sections-win32.txt new file mode 100644 index 0000000..52d137e --- /dev/null +++ b/docs/reference/gio/gio-sections-win32.txt @@ -0,0 +1,112 @@ +
+gwin32inputstream +GWin32InputStream +GWin32InputStream +g_win32_input_stream_new +g_win32_input_stream_set_close_handle +g_win32_input_stream_get_close_handle +g_win32_input_stream_get_handle + +GWin32InputStreamClass +G_WIN32_INPUT_STREAM +G_IS_WIN32_INPUT_STREAM +G_TYPE_WIN32_INPUT_STREAM +G_WIN32_INPUT_STREAM_CLASS +G_IS_WIN32_INPUT_STREAM_CLASS +G_WIN32_INPUT_STREAM_GET_CLASS + +g_win32_input_stream_get_type +GWin32InputStreamPrivate +
+ +
+gwin32outputstream +GWin32OutputStream +GWin32OutputStream +g_win32_output_stream_new +g_win32_output_stream_set_close_handle +g_win32_output_stream_get_close_handle +g_win32_output_stream_get_handle + +GWin32OutputStreamClass +G_WIN32_OUTPUT_STREAM +G_IS_WIN32_OUTPUT_STREAM +G_TYPE_WIN32_OUTPUT_STREAM +G_WIN32_OUTPUT_STREAM_CLASS +G_IS_WIN32_OUTPUT_STREAM_CLASS +G_WIN32_OUTPUT_STREAM_GET_CLASS + +g_win32_output_stream_get_type +GWin32OutputStreamPrivate +
+ +
+gwin32registrykey + + +GWin32RegistrySubkeyIter +g_win32_registry_subkey_iter_copy +g_win32_registry_subkey_iter_free +g_win32_registry_subkey_iter_assign + + +GWin32RegistryValueIter +g_win32_registry_value_iter_copy +g_win32_registry_value_iter_free +g_win32_registry_value_iter_assign + + +GWin32RegistryKey +g_win32_registry_key_new +g_win32_registry_key_new_w +g_win32_registry_key_get_child +g_win32_registry_key_get_child_w + + +g_win32_registry_subkey_iter_init +g_win32_registry_subkey_iter_clear +g_win32_registry_subkey_iter_n_subkeys +g_win32_registry_subkey_iter_next +g_win32_registry_subkey_iter_get_name +g_win32_registry_subkey_iter_get_name_w + + +g_win32_registry_value_iter_init +g_win32_registry_value_iter_clear +g_win32_registry_value_iter_n_values +g_win32_registry_value_iter_next +GWin32RegistryValueType +g_win32_registry_value_iter_get_value_type +g_win32_registry_value_iter_get_name +g_win32_registry_value_iter_get_name_w +g_win32_registry_value_iter_get_data +g_win32_registry_value_iter_get_data_w + + +g_win32_registry_key_get_value +g_win32_registry_key_get_value_w +g_win32_registry_key_get_path +g_win32_registry_key_get_path_w +GWin32RegistryKeyWatchCallbackFunc +GWin32RegistryKeyWatcherFlags +g_win32_registry_key_watch +g_win32_registry_key_has_changed +g_win32_registry_key_erase_change_indicator + + +GWin32RegistryKeyClass + + +GWin32RegistryKeyPrivate +g_win32_registry_key_get_type +g_win32_registry_subkey_iter_get_type +g_win32_registry_value_iter_get_type +G_TYPE_WIN32_REGISTRY_KEY +G_WIN32_REGISTRY_KEY +G_WIN32_REGISTRY_KEY_CLASS +G_IS_WIN32_REGISTRY_KEY +G_IS_WIN32_REGISTRY_KEY_CLASS +G_WIN32_REGISTRY_KEY_GET_CLASS +G_TYPE_WIN32_REGISTRY_SUBKEY_ITER +G_TYPE_WIN32_REGISTRY_VALUE_ITER +
diff --git a/docs/reference/gio/gio.xml b/docs/reference/gio/gio.xml new file mode 100644 index 0000000..532bf90 --- /dev/null +++ b/docs/reference/gio/gio.xml @@ -0,0 +1,805 @@ + + + + + gio + GIO + + + Developer + Matthias + Clasen + mclasen@redhat.com + + + + + + gio + 1 + User Commands + + + + gio + GIO commandline tool + + + + + gio + help + COMMAND + + + gio + version + + + gio + cat + LOCATION + + + gio + copy + OPTION + SOURCE + DESTINATION + + + gio + info + OPTION + LOCATION + + + gio + launch + DESKTOP-FILE + FILE-ARG + + + gio + list + OPTION + LOCATION + + + gio + mime + MIMETYPE + HANDLER + + + gio + mkdir + OPTION + LOCATION + + + gio + monitor + OPTION + LOCATION + + + gio + mount + OPTION + LOCATION + + + gio + move + OPTION + SOURCE + DESTINATION + + + gio + open + LOCATION + + + gio + rename + LOCATION + NAME + + + gio + remove + OPTION + LOCATION + + + gio + save + OPTION + DESTINATION + + + gio + set + OPTION + LOCATION + ATTRIBUTE + VALUE + + + gio + trash + OPTION + LOCATION + + + gio + tree + OPTION + LOCATION + + + + + Description + gio is a utility that makes many of the GIO + features available from the commandline. In doing so, it provides + commands that are similar to traditional utilities, but let you + use GIO locations instead of local files: for example you can use + something like smb://server/resource/file.txt + as a location. + Plain filenames which contain a colon will be interpreted as URIs + with an unknown protocol. To avoid this, prefix them with a path such as + ./, or with the file: protocol. + + + + Commands + + + + + help + COMMAND + + + Displays a short synopsis of the available commands or provides + detailed help on a specific command. + + + + + + version + + + Prints the GLib version to which gio + belongs. + + + + + + cat + LOCATION + + + Concatenates the given files and prints them to the standard + output. + The cat command works just like the traditional cat utility. + Note: just pipe through cat if you need its formatting options + like , or other. + + + + + + copy + OPTION + SOURCE + DESTINATION + + + Copies one or more files from SOURCE + to DESTINATION. If more than one source + is specified, the destination must be a directory. + The copy command is similar to the traditional cp utility. + + Options + + + , + Don’t copy into DESTINATION even if it is a directory. + + + , + Show progress. + + + , + Prompt for confirmation before overwriting files. + + + + Preserve all attributes of copied files. + + + , + Create backups of existing destination files. + + + , + Never follow symbolic links. + + + + Use the default permissions of the current process for the destination file, rather than copying the permissions of the source file. + + + + + + + + info + OPTION + LOCATION + + + Shows information about the given locations. + The info command is similar to the traditional ls utility. + + Options + + + , + List writable attributes. + + + , + Show information about the filesystem that the given + locations reside on. + + + + The attributes to get. + Attributes can be specified with their GIO name, e.g. + standard::icon, or just by namespace, e.g. unix, or by *, + which matches all attributes. Several attributes or groups + of attributes can be specified, separated by comma. + By default, all attributes are listed. + + + , + Don’t follow symbolic links. + + + + + + + + + launch + DESKTOP-FILE + FILE-ARG + + + Launch a desktop file from any location given. + The launch command extends the behavior of the open command by allowing + any desktop file to be launched, not only those registered as file handlers. + + + + + + list + OPTION + LOCATION + + + Lists the contents of the given locations. If no location is + given, the contents of the current directory are shown. + The list command is similar to the traditional ls utility. + + Options + + + + The attributes to get. + Attributes can be specified with their GIO name, e.g. + standard::icon, or just by namespace, e.g. unix, or by *, + which matches all attributes. Several attributes or groups + of attributes can be specified, separated by comma. + By default, all attributes are listed. + + + , + Show hidden files. + + + , + Use a long listing format. + + + , + Don’t follow symbolic links. + + + , + Print display names. + + + , + Print full URIs. + + + + + + + + + mime + MIMETYPE + HANDLER + + + If no handler is given, the mime command lists the + registered and recommended applications for the mimetype. + If a handler is given, it is set as the default handler for + the mimetype. + Handlers must be specified by their desktop file name, + including the extension. Example: org.gnome.gedit.desktop. + + + + + + mkdir + OPTION + LOCATION + + + Creates directories. + The mkdir command is similar to the traditional mkdir utility. + + Options + + + , + Create parent directories when necessary. + + + + + + + + + monitor + OPTION + LOCATION + + + Monitors files or directories for changes, such as creation + deletion, content and attribute changes, and mount and unmount + operations affecting the monitored locations. + The monitor command uses the GIO file monitoring APIs to do + its job. GIO has different implementations for different platforms. + The most common implementation on Linux uses inotify. + + Options + + + , + Monitor the given location as a directory. Normally, + the file type is used to determine whether to monitor a file or directory. + + + , + Monitor the given location as a file. Normally, + the file type is used to determine whether to monitor a file or directory. + + + , + Monitor the file directly. This allows changes made via hardlinks to be captured. + + + , + Monitor the file directly, but don’t report changes. + + + , + Report moves and renames as simple deleted/created events. + + + , + Watch for mount events. + + + + + + + + + mount + OPTION + LOCATION + + + Provides commandline access to various aspects of GIO’s mounting + functionality. + Mounting refers to the traditional concept of arranging multiple + file systems and devices in a single tree, rooted at /. Classical + mounting happens in the kernel and is controlled by the mount utility. + GIO expands this concept by introducing mount daemons that can make + file systems available to GIO applications without kernel + involvement. + GIO mounts can require authentication, and the mount command + may ask for user IDs, passwords, and so on, when required. + + Options + + + , + Mount as mountable. + + + , + Mount volume with device file, or other identifier. + + + , + Unmount the location. + + + , + Eject the location. + + + , + Stop drive with device file. + + + , + Unmount all mounts with the given scheme. + + + , + Ignore outstanding file operations when unmounting or ejecting. + + + , + Use an anonymous user when authenticating. + + + , + List all GIO mounts. + + + , + Monitor mount-related events. + + + + , + Show extra information. + + + + + The numeric PIM when unlocking a VeraCrypt volume. + + + + + Mount a TCRYPT hidden volume. + + + + + Mount a TCRYPT system volume. + + + + + + + + + + move + OPTION + SOURCE + DESTINATION + + + Moves one or more files from SOURCE + to DESTINATION. If more than one source + is specified, the destination must be a directory. + The move command is similar to the traditional mv utility. + + Options + + + , + Don’t copy into DESTINATION even if it is a directory. + + + , + Show progress. + + + , + Prompt for confirmation before overwriting files. + + + , + Create backups of existing destination files. + + + , + Don’t use copy and delete fallback. + + + + + + + + + open + LOCATION + + + Opens files with the default application that is registered + to handle files of this type. + GIO obtains this information from the shared-mime-info + database, with per-user overrides stored in + $XDG_DATA_HOME/applications/mimeapps.list. + The mime command can be used to change the default handler for + a mimetype. + Environment variables will not be set on the application, as it + may be an existing process which is activated to handle the new file. + + + + + + rename + LOCATION + NAME + + + Renames a file. + The rename command is similar to the traditional rename utility. + + + + + + remove + OPTION + LOCATION + + + Deletes each given file. + This command removes files irreversibly. If you want a reversible + way to remove files, see the trash command. + Note that not all URI schemes that are supported by GIO may + allow deletion of files. + The remove command is similar to the traditional rm utility. + + Options + + + , + Ignore non-existent and non-deletable files. + + + + + + + + + save + OPTION + DESTINATION + + + Reads from standard input and saves the data to the given + location. + This is similar to just redirecting output to a file using + traditional shell syntax, but the save command allows saving to + location that GIO can write to. + + Options + + + , + Back up existing destination files. + + + , + Only create the destination if it doesn’t exist yet. + + + , + Append to the end of the file. + + + , + When creating, restrict access to the current user. + + + , + When replacing, replace as if the destination did not exist. + + + , + Print the new ETag in the end. + + + , + The ETag of the file that is overwritten. + + + + + + + + + set + LOCATION + ATTRIBUTE + VALUE + + + Sets a file attribute on a file. + File attributes can be specified with their GIO name, e.g + standard::icon. Note that not all GIO file attributes are writable. + Use the option of the info command to list + writable file attributes. + If the TYPE is unset, + VALUE does not have to be specified. + If the TYPE is stringv, multiple values can be given. + + Options + + + , + Specifies the type of the attribute. Supported + types are string, stringv, + bytestring, boolean, + uint32, int32, + uint64, int64 and unset. + If the type is not specified, string is assumed. + + + + , + Don’t follow symbolic links. + + + + + + + + + trash + OPTION + LOCATION + + + Sends files or directories to the ‘Trashcan’ or restore them from + ‘Trashcan’. This can be a different folder depending on where the file + is located, and not all file systems support this concept. In the common + case that the file lives inside a user’s home directory, the trash folder is + $XDG_DATA_HOME/Trash. + Note that moving files to the trash does not free up space on + the file system until the ‘Trashcan’ is emptied. If you are interested + in deleting a file irreversibly, see the remove command. + Inspecting and emptying the ‘Trashcan’ is normally supported by + graphical file managers such as Nautilus, but you can also see the + trash with the command: gio trash --list or + gio list trash://. + + Options + + + , + Ignore non-existent and non-deletable files. + + + + Empty the trash. + + + + List files in the trash with their original locations + + + + Restore a file from trash to its original location. A URI beginning + with trash:// is expected here. If the original + directory doesn't exist, it will be recreated. + + + + + + + + + tree + OPTION + LOCATION + + + Lists the contents of the given locations recursively, in a + tree-like format. If no location is given, it defaults to the current + directory. + The tree command is similar to the traditional tree utility. + + Options + + + , + Show hidden files. + + + , + Follow symbolic links. + + + + + + + + + + Exit status + On success 0 is returned, a non-zero failure code otherwise. + + + + See Also + + + cat + 1 + , + + cp + 1 + , + + ls + 1 + , + + mkdir + 1 + , + + mv + 1 + , + + rm + 1 + , + + tree + 1 + . + + + diff --git a/docs/reference/gio/glib-compile-resources.xml b/docs/reference/gio/glib-compile-resources.xml new file mode 100644 index 0000000..7ab36f5 --- /dev/null +++ b/docs/reference/gio/glib-compile-resources.xml @@ -0,0 +1,254 @@ + + + + glib-compile-schemas + GIO + + + Developer + Alexander + Larsson + + + + + + glib-compile-resources + 1 + User Commands + + + + glib-compile-resources + GLib resource compiler + + + + + glib-compile-resources + OPTION + FILE + + + +Description +glib-compile-resources reads the resource description from +FILE and the files that it references +and creates a binary resource bundle that is suitable for use with the +GResource API. +The resulting bundle is then written out as-is, or as C source for linking into +an application. + + +The XML resource files normally have the filename extension .gresource.xml. +For a detailed description of the XML file format, see the +GResource documentation. + + + +Options + + + +, + +Print help and exit + + + + + + +Print program version and exit + + + + + + +Store the compiled resources in the file TARGET. +If not specified a filename based on the FILE +basename is used. + + + + + + +The files referenced in FILE are loaded from +this directory. If not specified, the current directory is used. + + + + + + +Write the output file in the format selected for by its filename extension: + + +.c +C source + + +.h +C header + + +.gresource +resource bundle + + + + + + + + +Instead of a writing the resource bundle in binary form create a C source file +that contains the resource bundle. This can then be compiled into an +application for easy access. + + + + + + +Generate a header file for use with C code generated by +. + + + + + + +Prints the list of files that the resource bundle references to standard output. +This can be used to track dependencies in the build system. For example, the +following make rule would mark test.gresource as +depending on all the files that test.gresource.xml +includes, so that is is automatically rebuilt if any of them change: + +test.gresource: test.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies test.gresource.xml) + +Note that this may or may not be portable to non-GNU make. + + +Also see . + + + + + + + +Specify the prefix used for the C identifiers in the code generated by + and . + + + + + + +By default code generated by uses automatic +initialization of the resource. This works on most systems by using the +compiler support for constructors. However, some (uncommon) compilers may not +support this, you can then specify , +which will generate custom register and unregister functions that your code +can manually call at initialization and uninitialization time. + + + + + + +By default code generated by declares all +initialization functions as extern. So they are exported +unless this is prevented by a link script or other means. Since libraries +usually want to use the functions only internally it can be more useful to +declare them as +G_GNUC_INTERNAL +which is what does. + + + + + + +By default code generated by embeds the +resource data as a string literal. When +is given, the data is only declared in the generated C file, and the data +has to be linked externally. + + + + + + +Write dependencies in the same style as gcc -M -MF to the given file. +If is -, the dependencies are written to the standard +output. Unlike , this option can be +combined with other options to generate dependencies +as a side-effect of generating sources. + + + + + + +When creating a dependency file with +include phony targets in the same style as gcc -MP. This would typically +be used with make. + + + + + + +Generate code that is going to target the given compiler NAME. +The current two compiler modes are "gcc", for all GCC-compatible toolchains; and "msvc", +for the Microsoft Visual C Compiler. If this option isn't set, then the default will be +taken from the CC environment variable. + + + + + + +Environment + + + +XMLLINT + +The full path to the xmllint executable. This is used to +preprocess resources with the xml-stripblanks preprocessing +option. If this environment variable is not set, xmllint is +searched for in the PATH. + + + + +GDK_PIXBUF_PIXDATA + +Deprecated since gdk-pixbuf 2.32, as GResource supports embedding +modern image formats without conversion. + +The full path to the gdk-pixbuf-pixdata executable. This is +used to preprocess resources with the to-pixdata preprocessing +option. If this environment variable is not set, gdk-pixbuf-pixdata +is searched for in the PATH. + + + + +JSON_GLIB_FORMAT + +The full path to the json-glib-format executable. This is used +to preprocess resources with the json-stripblanks preprocessing +option. If this environment variable is not set, json-glib-format +is searched for in the PATH. + + + + + + diff --git a/docs/reference/gio/glib-compile-schemas.xml b/docs/reference/gio/glib-compile-schemas.xml new file mode 100644 index 0000000..0796bd7 --- /dev/null +++ b/docs/reference/gio/glib-compile-schemas.xml @@ -0,0 +1,118 @@ + + + + glib-compile-schemas + GIO + + + Developer + Ryan + Lortie + + + + + + glib-compile-schemas + 1 + User Commands + + + + glib-compile-schemas + GSettings schema compiler + + + + + glib-compile-schemas + OPTION + DIRECTORY + + + +Description +glib-compile-schemas compiles all the GSettings XML +schema files in DIRECTORY into a binary file +with the name gschemas.compiled that can be used +by GSettings. The XML schema +files must have the filename extension .gschema.xml. +For a detailed description of the XML file format, see the +GSettings documentation. + + +At runtime, GSettings looks for schemas in the +glib-2.0/schemas subdirectories of all directories +specified in the XDG_DATA_DIRS environment variable. The +usual location to install schema files is +/usr/share/glib-2.0/schemas. + + +In addition to schema files, glib-compile-schemas reads 'vendor override' +files, which are key files that can override default values for keys in +the schemas. The group names in the key files are the schema id, and the +values are written in serialized GVariant form. +Vendor override files must have the filename extension +.gschema.override. + + +By convention, vendor override files begin with nn_ +where nn is a number from 00 to 99. Higher +numbered files have higher priority (eg: if the same override is made in +a file numbered 10 and then again in a file numbered 20, the override +from 20 will take precedence). + + + +Options + + + +, + +Print help and exit + + + + + + +Print program version and exit + + + + + + +Store gschemas.compiled in the TARGET directory instead of DIRECTORY. + + + + + + +Abort on any errors in schemas. Without this option, faulty schema files are +simply omitted from the resulting compiled schema. + + + + + + +Don't write gschemas.compiled. This option can be used +to check .gschema.xml sources for errors. + + + + + + +Do not enforce restrictions on key names. Note that this option is purely +to facility the transition from GConf, and will be removed at some time +in the future. + + + + + + diff --git a/docs/reference/gio/gresource.xml b/docs/reference/gio/gresource.xml new file mode 100644 index 0000000..4ada0eb --- /dev/null +++ b/docs/reference/gio/gresource.xml @@ -0,0 +1,127 @@ + + + + gresource + GIO + + + Developer + Matthias + Clasen + + + + + + gresource + 1 + User Commands + + + + gresource + GResource tool + + + + + gresource + --section SECTION + list + FILE + PATH + + + gresource + --section SECTION + details + FILE + PATH + + + gresource + --section SECTION + extract + FILE + PATH + + + gresource + sections + FILE + + + gresource + help + COMMAND + + + +Description +gresource offers a simple commandline +interface to GResource. +It lets you list and extract resources that have been compiled +into a resource file or included in an elf file (a binary or a +shared library). + + +The file to operate on is specified by the FILE +argument. + + +If an elf file includes multiple sections with resources, it is +possible to select which one to operate on with the +--section option. Use the +sections command to find available sections. + + + +Commands + + + + + +Lists resources. If SECTION is given, only +list resources in this section. If PATH is +given, only list matching resources. + + + + + + +Lists resources with details. If SECTION +is given, only list resources in this section. If +PATH is given, only list matching resources. +Details include the section, size and compression of each resource. + + + + + + +Extracts the resource named by PATH to stdout. +Note that resources may contain binary data. + + + + + + +Lists sections containing resources. This is only interesting if +FILE is an elf file. + + + + + + +Prints help and exits. + + + + + + + diff --git a/docs/reference/gio/gsettings.xml b/docs/reference/gio/gsettings.xml new file mode 100644 index 0000000..5f720d6 --- /dev/null +++ b/docs/reference/gio/gsettings.xml @@ -0,0 +1,248 @@ + + + + gsettings + GIO + + + Developer + Ryan + Lortie + + + + + + gsettings + 1 + User Commands + + + + gsettings + GSettings configuration tool + + + + + gsettings + get + SCHEMA:PATH + KEY + + + gsettings + monitor + SCHEMA:PATH + KEY + + + gsettings + writable + SCHEMA:PATH + KEY + + + gsettings + range + SCHEMA:PATH + KEY + + + gsettings + describe + SCHEMA:PATH + KEY + + + gsettings + set + SCHEMA:PATH + KEY + VALUE + + + gsettings + reset + SCHEMA:PATH + KEY + + + gsettings + reset-recursively + SCHEMA:PATH + + + gsettings + list-schemas + --print-paths + + + gsettings + list-relocatable-schemas + + + gsettings + list-keys + SCHEMA:PATH + + + gsettings + list-children + SCHEMA:PATH + + + gsettings + list-recursively + SCHEMA:PATH + + + gsettings + help + COMMAND + + + +Description +gsettings offers a simple commandline +interface to GSettings. +It lets you get, set or monitor an individual key for changes. + + +The SCHEMA and KEY +arguments are required for most commands to specify the schema id and the +name of the key to operate on. The schema id may optionally have a +:PATH suffix. Specifying the path is only needed +if the schema does not have a fixed path. + + +When setting a key, you also need specify a VALUE +The format for the value is that of a serialized +GVariant, +so e.g. a string +must include explicit quotes: "'foo'". This format is also used when printing +out values. + + +Note that gsettings needs a D-Bus session bus connection to write changes to +the dconf database. + + + +Commands + + + + + +Gets the value of KEY. +The value is printed out as a serialized +GVariant. + + + + + + +Monitors KEY for changes and prints the changed +values. If no KEY is specified, all keys in the +schema are monitored. Monitoring will continue until the process is terminated. + + + + + + +Finds out whether KEY is writable. + + + + + + +Queries the range of valid values for KEY. + + + + + + +Queries the description of valid values for KEY. + + + + + + +Sets the value of KEY to +VALUE. The value is specified as a serialized +GVariant. + + + + + + +Resets KEY to its default value. + + + + + + +Reset all keys under the given SCHEMA. + + + + + + +Lists the installed, non-relocatable schemas. +See if you are interested in +relocatable schemas. If +is given, the path where each schema is mapped is also printed. + + + + + + +Lists the installed, relocatable schemas. +See if you are interested in +non-relocatable schemas. + + + + + + +Lists the keys in SCHEMA. + + + + + + +Lists the children of SCHEMA. + + + + + + +Lists keys and values, recursively. If no SCHEMA +is given, list keys in all schemas. + + + + + + +Prints help and exits. + + + + + + + diff --git a/docs/reference/gio/gvfs-overview.odg b/docs/reference/gio/gvfs-overview.odg new file mode 100644 index 0000000000000000000000000000000000000000..ca2bb8d66d24619fbf28e346ac6b41d772ecbb35 GIT binary patch literal 17772 zcmWIWW@Zs#0D+UGC#>c(>mAW%U|;}Y4h9B>+|1n6lFEYA#DapH%;dz9%=|q4vb+?% z{KVqSV!ix=)V!4ZlNgscLw;m^KwaXF)%RjdV077F)%PFfG`I$ z0|SH0lCEP649pAxJ|V6k4>B|`G%zqUG=K;&)zHvz;J^U}hW`xz85sWm2N7Tj%w#ZT zU`S(Nn90C!2Bd<4!I;6=m?6!WVWu&|8Dob3U}@tthO{(>nQ07X(ir}ORU6M_NSnzp zb0))?nGFBInvKseq@7`yd4}Q48HWF0vyA^Ur2S`@`Jds;e+H1PAcKw57>s8!7@uJ< z{tvdv*w{GD*m$O~@fl;||6q%a(~Q&7jAy19pGhAd}M0 zfYgG#WSj;9Gt<(}q^11_`_Oo1TH4ICnKRSQ%uM?a_OS68ko3$mX=l!){RjKs_&-SX z%>QX;{-^y12Zu2zY-Y{``F`eqhM5c?56w&iIeF$8kfT6>Wt;{wdS=?pGifvbgTu~v zCdj6lGiRQeIrBd_D2>m6ES`C0=9x1y|ARx;_&>-UGyl&#^MB@la6lV_BH_$TP%xkQ z&v1qT6mngTe~DWM5c>|rZSxfvK3lJoOQ zpe5$pn8^Iwr$p=CuNSBYT;O^zwQaY+??+6Iza}xT-4Uxb)+o~0xXgmZQ+HqeqW-`2 ze^uv7zO&Zs4tk{Kn3MfX=A7mIo1Vw!*V(@RdsWbNV|z0@ABWI(r^a4c{Tp@#_5W{+ z-+NG3`{%Iwn_csIukmf;uNG0+)7#uq6EFBqA#V9@{yU0X*KTy}t&okV7FjP`-Rms! zB<8i&*I9F?t~+vaw*Abxg5f)bOZ=7@1>cfdzjbDvk@C7C>xreaPWfbVt_Up?_fNGu zZudT^>6hIWq4kPKZ+>sO&Ym}2H-NQI6ox z4mq)I2ZkiS-R_;Hp>|%;qM8MFeu4T)1cfARz{2sRH^~Uvzb;`5foZh~EX}s(2mFa=Eq(aJ`v`)V2 zvvTzxiN{VMrzWsj3yXVAQd%}&`^s|1Pr*-AHC9cy-TY+R)7z|%D(4voWv%Ly_YZkbu-K+kWqAhSsZuwTG z{7u>cx58eyT#>923_r@zYT?Djyz_E5gC(oja*K7LGR_*wjj@f(d)};hCF(LO*X7hF z?}s1dK7Ib6)pF*X`*Q(TxzsH+j~uUjxlzdZ;K;^;9qVEi%$vRV@6Xt99VYF^YegbY z*gg|A?OhO|Beur5X{BV&yroBed<>o?b@O`YFJsZijm1s}Qn}Z;#ysfNS?b!xzgG9r zk-BTSSCa0!h3)wKrp9uMQq=RC>~^V(_+CX!JpAqwfoz{O!~HwC8DcG}H24 zrfEvAO5C+3#0I^!J^oQrEs1rCV#|ZI0!6WhH3fDxFZ%RWr1WmJ)~Y*Rfg1Td$M?-& z^lGih)YR@jd*?5@wN_-RO77y^cgt7oTd=55=wbLFfd>s+3)4Df9#r9XTlUeq z*>5id9m`j)(Gsc>k`2fG71yN0;2Uz3$Br`?)EpHzd?!TKa)>oj2;H4(}ew zJ@fz0k(F({f%#I?gS!XC51fs%_S|&A_O<1X$Zob&jr*GyG^b!L} z1@U_r_By(vFZT9mQn>y#-(-$^ARW^Tlr(=`K z)OTk-Hmcsf9+`2!Sc}>F+qUkhyH;C1Wok%iW2g7l?!lzsqx_;;QysS$mY6+qQJ!Zg{6v*~*8lm>)OOo{Ik%;>d*bWgn^`^0 zyrr4AgtWDbdp2Hp^SQWeZ{XJ*cdwWkCcP`a|7vBZXXhue;B^68BUWmi&Z~8c7V?Pfp)^KvCN`_)+j`3*YIxooBp!zD?+3QAI49kG5qj8;`ff+vJRgWm%;d6~bo@;n~%%kb`_m)2hVck2Ite(!YZl&hCv z_jQgLYf3-H3hCFZ`)WM#|Igh02kZKdD=w=vE%2C`FeQ>fY-^M5v3u`bgkAqC2iJPc zlw5VFJH)s0(S=PXT_<)cyG)+zX4~@ig3_~S=|jOw@^!yXk>^+ZnZ?1#Sm)6)MO!JQ z#-ruRYDE^-r_M@CVtEyRIzL(*&p)4k*7Dxfic4xP*yP3uF6^JV{G~Quc$3H9jY6fV z*4fLC-us@jxtF)>UKjsO?yddvZ}51;ul8MjaLeCi^Bq5)*dr5rbN0@gN8~3bw(sqq z{kGO^UFnC(pLi3#rTy&Ms~2&F~agw9Y(z zDDJDS+KpQ+f2X|vaZUQ~eW@qXb}BFbt~j%(jUm)@|I&H)uLZKWYKooTviIVXN1vmA zT7JG@@OkmCll}F+asM~{>eX;<%lvh%GHrFi1n-!laGeAhN0EKZfuR$6)D{E;Ol7or zT2d`@PUz6dRVVhYIuIDzpvSQEsjTv;jFta(8WksmyCr^~!+x&&iyNACio<1d(- zULRsv{%!BsYloeB^bJ~n>8+Ov*9cD7W>@i9U+H72RVMdqmK4WJdY8KXNQa&5<*1$R z_shEE72iz3^V&|!Y|5I?E5CfOdV8i;cv08VHf1)Gb@SwX99x~Q9v0y#R&o3?>)4)M znJNdbJP258Y_zWO+Rx+DpJzv~dn|tD8N6tdhgZ&wRngbqUhEBD5^wqAMH7or8@hC48(E&nP7o25<2{)nK7nZ& zkJ+ju^`yVG&m7J!KJcO`bA@R_h~wldQbv(ZnvEwtqdo=wJjNyWB46tG?u1B&Dt9Lq zhjlw@V%5`5T={jGd)^sayY_3E8L7J#PBMRU0)4wG=G(s_)7d->Gla?UcBnpOrP!+ z6`wF;^6N*dbPmR;`T z5Rz!ky((?%2koY1SMS)auJ}Ajq3dNnLqzG98u4@|i+l3l#k6yf9d?f$k(*Z=w)`s{J%ewewou0Gtv;Q!?qheuJt*|~xuJ}YPPnC!hK@pQ9) zx?aHZQny}^w(`t zVWeJ$nd{jYgNHkhHyvDiy(wB$B{-99d(`GQwY>D4?9WNJXNcUkidpHhO4;yt-|~aG zr<#xXiN9#R`e~+KY?6QW(Oa8iHa_1jZugHL)R+Fft@x-67X!n;09aodTcZ-xg)1(p z%t)?Un;fH}76=n3gentqPZj z=x=u!XlTWla$jZtIaOv+G3jSHs@!d#bHU~s^5preBHMDh{dFYKTdem z@2=DBa%S_@t3S5K+fO+Ck^lX_PhmRKZIV7mxTKyka^>3U9bw4yaLo+qM^|@Dxfyez zN&IuqvNbbSXXq78i(I(#wC(lanSy^eEPOQU=G3s9)oonL`QFp?+Rm?;8T&Hg(%FE- zC#*iPAD2pK?a>w5B%&ge=_k5>@lmsfH>a=u7`3wIUFGbvX`3u(bL{-obTj8!X4cw* zkk3z-`j~{vRO%#JL_TDld|>k)&ES$1bthi0nlkle)5(Ju0$jg`nNDBBAZ8%`x9CQ5 z%*<)^ch|91Uw^xb{aJ?Z(**m=XL7?WyW4l4ihOfwS;*SzYu_*ZW^ws@eR+Rx{K=9R zF(+;}X-%?`&sp}c>}jjO)>Rq_X1l}8zx-X9ZfAXGcJmwQlcJOPs!Jx=F7gaf*1M#4 zp+WycL-U5{lApKUO;K-N%XUvreW9d0kL{;-J6E}UsMfXlu5!9H#8lz*Lr3v6&exHT zRM#$NJeRa+zC%F3`KNXV58r*e@I?9JK+!#OTLk;=-+YrW>Co=&60e_WdnWTeQvS7jQ2HvgC{z?owebL zy{_au&1s@BZyk#7|Gy{rYT1RH*3Gw<>$mh6u4BBr`b_M zS@y{Td+Q!f)KXkm)%gBj%enpO|K2!%xU6zMEG*=0QEuq0#i40yA|A)3PmoBmc6oR) zgmL)^J1(i~VoO5m5-(l-H$SNBYz523%DU4xpSf>j?RNjC@x?uTpJe-oS!@PwOfu2! z|E~Y4Y@PIoTiH-IO8YBg4cEsC{>M7U{@-nxZoWO_Ud!g$emwz6DL35fnUC$?K0R=g zN2KM#E{2$se?5eztu>g!zPbDT_iLg2d{-khS`EIfdU5G}__>d3U;bpZ5MPlfRCH$A z7N1p*@15w;)jVQCU2PFqN|gsX>{ki z;o%8w?%{t$LR{nvr<-U-OSY{ba4jA8n&|{d%)&hw!`ymP!wO zXRLI-ws)cEH%>uqYV^UAk#l*Yzi@oBdX}~MU^LH+_rH&R z60J``@Oskld{++VoTtKveZ*2H8JHTm$Xu`Vt2a?;+IsWqkNy9DmcM;= z&RNR;`>&=ycRA{K-<9q47FUv#pUmJBFmK-LCGTa8o^b>pW}lgrQj({}&8E80j%&}s z)=N{Sq^m6Cp0Kj~tn~LOAJUy(ytydQbm@7hl1Z&gi(b5{)ARne0E?OXyjt$rNI9ji z7n)eT%O*Sa2OBR5{?Op&TM%iQb!Ns@&t)c=0h_kYxc%Tli_n9~%Z^`7 zJ-h7C9lQ0n*nJ%LdN25Mwj}(F>xZXXn|K`b0ZJO2I`F76L z5nJjvn8XJ^&Zs_Xcv7g(_rG=Q(&}BFNgrprW*ru73BSDTeU8>mHT|hyS(!G4Uy;9B z{whP+x9M}TwddFE-0W38;_cNwX}e`|3~d>FHy@oZbWW@7&Zj2*SMTS`?Oynq;k060 z^8MGGzUF85JpLoI{k(ZW-e&Fp6Q*$szMmI-`S9}vTBr9mz9`!gI{!3NO!L>Wb^GU* z);?GL92rkzR%|tEYC`Fush2lYEi8RnQWX;0sm6LfG5Ec!()}&I zeK{9f+M`UWkNg!o`(e>Flf7+v?iGKETKqT5#NKtoHa))ik z<+aO$U29jZ@E85Ma#39;$6T#f2>!qQD^{H4+g<%WQ|QZ`npK>#N3Rr4pMUGd9NDj~ zuV!78$Y-~$m#pXiB0B5x2L5vf5`7m7LsuMq5&4VhJbTdZdo%ZHut}TQ$?Z~K^)Ozm zr0#gH?Ye}1_j-{FQ!Xx=azAPJF5Z>N@7+z$_CEU;ygcT0T!`}1HS^z2bO_ThUbm{o z;7aS^b+zyAR@ys$6|7g3ynjGI(0fC|I*BE_=4ymyYu5dI(r;bCwkxBH4V&)!8{JTKKa*=wTAgB4{~ZvJPV-rah*AxN@YVtd%jy+5zsS5q?K zyR~EeXE%mNI_s`C)UbQ6|9#Z|{Xce4>*{9RkMnAr3=9@tu+|j=0|R&hB>a6!MGp%D z0|Ul+3(zTcywtH(d)QdpjVRe4^su; z6i{|HAkr#5H4idjX6Ij!n&%HrA7Eb@>lvu{WagDtD4;rvK35&rLKXQu7O2}p_!G5 znU$f1jXq2gVnb?5W=UpVx^8l1a!zWooe9)HG+|V=DbSfpyMPb_0}oS6UqiECG<|R- z5S{Q02b$T;EH24RRse@peiA4sb(8Z;^Ga-$jE$7^q0v%WoLZ!tlA4y8mzn}m3d)VP zN}hRX`3i=_DI?M}W8zFR0V#tfb1RVJ?QCE?xbMKixF;DvvlSs3rMXFYiJ3XY`Xw+X zXx49PWNE;a_}%~CZQ|hO;P%$>*k00JqSafX#jT-mcdn54bPg>A#SR4zk8*R5@=lW- zmktR{zi<8h+}z6dbFGX2TNbCC`)u>v^86fi`-`_`^}l}{_>hsIApU9RB0h$OciS9H z-|gMKRpyKX7XyD-h{)3~HAeiK7T7KMWx98J@W1)1XDkTVC!?~bS?1WBh(4zS?7#&fCA*i=T3&E z8gFHWg?D24J{&!&;3&qi$*(|K-d&}PBdDK2{)LXypZu1u`i=%386qD`G^%_4Y)C)w zAuqAFmcM1uSJ8y7sbbasKmP=tU0C25<}9fivx)DQe&d&lq^$Ia_mjS7TYSG<%BH_| z&D%A~^1YWg9l5spx1+S{dULm1qBnOmEYF=XRa?`9XHL&MP4+LsE3bYL+I0Dp=(#yl zxvrV~oxh0VqNdKu>oAKl)6Qoj0V&CyM2YKnJv z?X_bQy4CobvEq|%fYp^Zc1N|;KV5#2 z+!j?`(h<4Q&h!3{>x<7Gd0F^1-!0WTd>+rmz+27k(ws}vE~n`)eQ@^w3$uN^mmZha z9A0FXXe77%|I0058TnW5Z1B=JyKVi0xu%I7C9*}q_ww|!H(b>58nV#zK4lRfs!^4wlf z7w4CkYW&IlP1?;o*3tvpT8~F-9dy}oiR)u;$>$xBQT0au*{$Y2Jr`1(?VaF$>Ew-d z-}$5O{&Qv9ADR-lwms*nh?|&dcGN-$w|Y ze55B)w1Vx4Y>Sje!0{;@^_!yB6faGU&f9gwN~hBzEXS{_fLlaDU2)3<=dRy#E1zv& zduoxm?Uoh4%8$4@_+-Ci(2|JvSJ9dH{^24Ey@z)`n1iS+1wb02Ln-t2wQwPWozU6uM>*A6P^Ev|Up)$r14pCq*0SexnVYxi}H4~tAf-q`;&?Z5S`>Eekw%PYPZGxvA6Tomiv$=jT3=Pff& z@9uuT@{WM4eRo6o);?{S7<*+&am9(QggI{A9Bleb3tx78`n6PE^5DjfpvO<6q7VIL zlbvE?mvv+p_rwp*w^+6pC{8cW3|2ZQTz#K^%JZ%lMbF=!*|A65{pur+*7C20=T@)o znyWtBBd_VzMLB1V(zlN;OSG6jRhqg$z~}an<}Hdbe|@W_ZTfZfZ%(#caMC*cV@cI~ zofGyRe{*MX*R<)ImdxZ9vH|UjG-m*Vl6Y;Jpqd9`zP2D&yHQMykjS9cxZ<{W#%Kv&C>U8cx_w~PLWOb6n znC4r0gk0Qlcx3e!h|nC%@%U{@jmj zN9_;Jt!r*oZhorHxo0O+{VzVgAjaP>Evn)SqW+wSlCJo8`qhaCVOa+M#P%%y7?&xo zUh~xbsprONOs(q~$`|L>7HS!!uuuQ?PH#yyvbg-q~}(xE3@mjix0mw*dr>lLw3qduglZlzh_Yvj(TNmz>qh4p=8j5o2xWVXcdW*TZZe|q9GO|+x`Nqq`mE?ZW`rRfDZH#x*hZ#oGTHLTg} zkY+0zU~*RSTG%uH4i!O3`&Zn`Uw3yMU0fIC%_2W@79YLiptPfteIek-4<2|>9cPB4-s@`HYYl^MKk4=i( z-haHh_s?RNzt`jcN+oGV#u)E-abIhL>ZsGV z#Qr8vtPEKzP^BH;AIM)Ho$J@ne`rp3alM_zy!8T}a$46y*IryW`@#N|-5zre{6EU4 z&OY_?tcTfWs&~~)Irh?o|H<6ndn;JK3w%8mDp7egTG{iD2BN zYsw|o|8G-4MNQ$$Pc?f#UXNIF>wZ(Q(>=3@rq_z~+m7EnW>|Dg;--72X^hz^YxmQx zx|2oiHVJ2zzDwO=cWb68+xiNd$@$+DZPLP?c;3uuayV)GbMG7Z-<#F0M!j-8vgyIq zn_8ck#M~A(Yb`0^UD41Ky!++S9=_MQtxI=xUOaO>pmz3(UvUS_ek@D9u3;4y`|g&_ z@1(q#mq9{v7K&L}>h4z4&1MbSzPjw%ui`Y@`yL-32WHIqrIqQ(x-Vx{W6rXYx$nI< zyn0i;U=8Q#$2t7l1bn*6gL~t*+0FTL-Ph!@%7kg9_ZFo7l`HOM;E}Es*fw#^Ox={1 z-a9M&15U7ne3nGpwo*nO}O?bM8%i4D1{cNusyARPDc{?U(>xeALHHKvZVK{^ny1ri6W+%T-v%pu|IVi z_0(pWef2+Fy8Vf4)y(Z5mwnE;9(wOe|0(Ibw)I;##?6|X&wqQzle$y0*H7qQ)6{V? zJe+GMYtG4;Q=TrVU0F6QP?tmIOVY96ykgF|)2|#}ug!c!rr;j;ee?5m;!MiyAMgHZ zTbQiA;78_}S&dDbWmcVFW4n-+v8dnU%aW>}-`qA8IGYJqPZd73SoGHkmn$dN{#r2i zW~R-`A4hNW)y!Kq%dLpNda9=3Gsb`Z+wbpO-m`T6@zdXDY-092bk|7V?SM?w5g|=e zp|lOcd*^ElF^8VBQo8-fxUR2!bpMXc>vbH`*WSJBdMbGJ{!PQmuN%TI z=N7N`IDfO?LiUvD9|OOxeD-W|w_;e*`WMQKJL-PumUle!xbfb%$Mqe18FRRWNvzKn zt9d?qjvoHczp*{~YtSTv2j&mvDBY5})_8|wi_GuPe5noPNtfQHe&2It(+xwD$$mT3 zxB{#4KKY!!`2IxkrkB6}RG<5BH{|1~$H#TDMHsgInXT%2Uf20bQJL4f9=p}Q;>8@? zS0CI~uC%RZp>LM@;kvK3X11En%igPns!VCG;7V#t`1^1D55}_$>n==BxW4}~`?lwk zSF5H@?PV9Y|NqVVPv-Q_l8=8nrns+dh+UKKQ{SbrquBIZ(=)F{ zUGrpthen}5-R)~FFJIkZyEgyGPVT?9nLYcb?&^G>zHhPYyZK=fHrE4pJy$t(>8jVH z?XQcR4zBspEE1W!;xfk(*C{+-ei_etD3CvYYd$%OZA(cUHe<<_!J$Mt?612#{oGcETndLMK-e*c{f>!OwBaarEc z66`M3-`D*9>t?elikre>UT)=@?OGySCH_j{V{xM0x0qiOGK**Ao!{}j!Y$yg*mi$M zv;R3Uw|>rxzThXi%h}bvWZRF1ve&a?4lKw%es#{}2*DNKrcE-HDbk%|T(|LhqV>A% z6EgUf8rY{uGJleu8S~(7!2bgtw|38Ce=G5Ri_nLa8-1_X?D3t~x2>;t-)4=)GFsIU zkKYFESeRhFaqsTBgL@NXF6GHNm$=e?q_bG3Fe}EiMtJBAZsn3zlB| zxQ+k1-H**z-fz}T?wfx5PlJ=Y=Zk~#8w+{Oo0VrWbal7u=)Gsvahv@&BLhi`KoHQg!dQRN=R|HYqw*_ZjX_DtWW?RpEr7s;a9GBW(E> z{c$>+nD^1{nwPQ6-Ka*{#^kJxTFskxeRx~p&ZEq!XMg>%`Ndof*UK7mtWy8CO1D)7 z^mm>)bwp{ULiu*ltTPJL_l+Orxr;6ER0>+f`MhwuFJF<@&08JX{pPZeeHZWF zQ_Y@MtpbUA8h)Iq3et4?vfC@-XrkRCvrQ|P{tn(CGw;hZ?gz`CT+n)Cqrm#|t=w;q zk8gUsn~t4S{<-G9xc6qUql+iYb-DP5wDt7JA3X9{y{^4~OD|Wj*fxi0KEZmb$~!Lw z?q7Yr;MnB8`SA*Jt|#)u;~(9AIz_--Ev43FnySjrBOCczSh7_xsXp|0nLf&NcCF=uA(c{EZLZ zNuEr(!N11$%gl8F(~g|kJ}ueo`ZoVNOLMql^>yulyP23-0-=co$ zS0L|ZJ)?cGKjz&%w(P^c)9vYhP9JkIm&#{I)1P$tVFgRzX5la97p~WR{{8rb_~dEL zS9Sje+->{ov!?wS_mL>EIVQb(6N@V^D(|^%`s>Cs|IF=NbGOfM+bZl9^><~aj`fe* zj62){xtDiW%5LSI|9|G;8+iiveraC4_58Ql-GArjAK;ypEoZ&t`sA1!{ZH)bT~8Di zy+3tv-odjs?GjhKd;4ZFv-01oA#Fz*^Utge|5s4D`Ar0u`r{4P7%sY6TtD`()SJ)R zT+&0`?H5OM@E*_T%hfv-lzJ}u=_T_OO*?FHhGo}} z?g>h3E{SFM%Ph@f^qeuFHnPfTRd9HE()U@{D+M-}xMlc+={qpZh+lcdQ{=>~pnq?J zZhPH$Tr77nsk~%qm#X?_e(i{*73+MnqzyD$ce2#~b1A+$ZPib~!#4YDe=D{*Z`#qa zK+!*FbKI;;d|kowg8kO2%GCdNJ8AUZwu|M5&}*B^dk%zTywX`zKYLr#!*8;d`{tFM zv*YKmQvQ8~KWvi0`;$*siqG7#Kg7Oq?v695evy~v{)pq=Ze4kN-tpd-iL19}-;Z6l z?(9+roo$6y&hZKz8}{B63|X|m@a|+Ty|+_0%U8D=m%QKi@U69&vWwL^Q-bo=&zLGxc%~2$l<@oCm8tdQ$<3=8Wi$g+!6Iz*FJ3*@8_*k&OLolbA9<8f0g?8fBz-q zFzBuPu-cVvfAy1-A9WsVsJ7PVl+XyNzaH2-w`{pbP?@i9;hXJ_`WxP#%7|#4WqfGi z({k^v*PD%Za2a@di!`m>yF`L7;=aw?*LK^T1RvQ18Mj-!uAZa)b%Ty;kei&^q67vL zZT~sJ@28wN@OsaeN?jwNovW|5a+iF1>h?GL$dlf`LXKtE)g1a3@-ER~V~@H$WzFU; zsSjq8twc9}Qa<8&bhlOh;^}7}X0Q4=JN@j}SHAh>Z5rIgiH9B(oypj6>G&7jWwYhK zyPaQu=|$3|8D_o}_hxc6bKcF>yZ=tH#r3>i?X|kQY;LpdQ(kv1v^^jBLSoxgLGv#g zqZgI@tv;+YbNUC7-7moV zb&Xot{Q&NSsI@9*(hUEJ<-kEFj)YcZ+fm^t(L;?|(Pzv>#^O3(QN`=?}z%x19l z)q2bw`nLOZ_|{-k?W=x2uIYZtjQ(t@6;as{Jjr=OnP~oriTfkgURpiPXgz!9_b)D; zm5fb(92aAqmuJ_k{5Ek`h@tmK;RWHzQTh)bO`0?FFXN5W)FadOPUv+`TO*|2eESgR z=?&d>3r;i`<=B0-Z_jG@6Xm!2%VYmbVLPtYn{JZh+?;>Z?;Y>AzotiiX)8qcdtbac zQ}osae&IJK4&{j^FFW>G?fiq5&7sx$}0Be&8^qGiV} z)$N}@djf0TeOK%61#Dq%FU%LLTi>dCRpr;Lx*t+o{P!=<`fz(skKI(!OXm-qv^p{6 z*X8_)TMjlV&%aST@5k2vXYYIMTdaR)S_XR_zx~SDv$7;=UR$O7SoBA$O&RaxC|M0~CHuSb*KFfN)Bq{g{4Q)qhy8%MQWq2^iDtE!Bm+r%>8 zMH!rIWH(vmc=6g|%ci25C6QOk{~R&V_pAD3E6ixWv5WuPsx;NeplLq-%IA029zRu= zy=%$RM>nH?pPHv4HFKQ@s>-;NX7ANc1Z7;iWG5NbhquU18U2U=)Rmbn%bl)9pJ8!o$9ZJJ{5 z8#;S}Vva(Wt5xxdZ(uAI6y|KxXOmtGIy zEr0A{y(XOrdZE8@&Asj|Z@sj+HT(G5Ywn$#^6S&ejvoD4w{QNjWIXv{`}es$X2vlt zVNQomYRoh1$@lJITN|?G`;E(!&DV9_5O>_|_Ttgu`HZF~pPl*k>GGxhIr{>)q|3jZ z-J|sPnerX+x54v+aNVEGdoYCmhHr03wQJ~3&ZEw@T(vi3rbt{3-Pivo z?2WwAO794X+uub0NWD?3pX2;Hc(Si;z{+(m=00WUUcHe|Ra!E4g`=6Dc6F26-IblX zb7sxG+^qTC`*7E6rC>c*kD8#9kz6{Hb*GB?_dZ>zxa-rBAJUg&axb~hQJ3<5aO&7T zsaA!Rk%tyvpSxtL(zSSrbsL*wyz8TWojfDEzc_iO{c@zXcTU2E6tpN~1u5&L!SOyjlQ z5>eMLPrc3@y4?QVW2wg$>NQg>YrSy+xN8W6aeaQu zw5?^EqP`vq*`mkw%>2W2|C8F)v)MW=vi6)mEwwZEXne|@%fGI+#D3ZO^yaz433pNr z;^%PYX&-QB5dUdjkos47!HdPVIntu0N*C@O=8no$&N*LREtWUi!(fTVCJx7)S0-+E zeDFkZN9)vy!5hL8^j@cE?0YlY?2sOZSS3d_-(eAz#riz6>k_`&GSnxrJbB3Ww$x$8 zKYkN-HXXHw*xTafr=;6ne{+)7jxm43k#YaSnPXjxq*|9wk~+t-zo_EGO$!x)>)%>x zmTgKrqQ=j7s<}=sKlxli&e~L`mgwijdAc8sUaRjqyZ^3@K<>$&{6pKGf4`;Tv1XU3 z^_4XR+GV{hT}6xwuC9w&H`(y_2k!ET67j+-XWLJU3SXT1`b|xgY)(j#Uh(m}Q=0Sx z>#{5g{jav>ui4(DW6T@o+faXoWm@jm&ZpKHX4|gt9ua%>-B{{<>!;|%q`cR6<^k+b?kxs1AkY~;Eg`_l-}5b_fJ+ysd~(lW?+zzfvrlww&s(Efq|ho zwFES$3SRa3G%C9Ik(o%{`}HR(eqFE=aGG?smGcb)C+}vJg^b(o?&JKOaOK1#_est_ zzH4(%-gL}QMzYlEvdxnu@B8I_=PvG?xca=lpk)P{p21?>^@SBrWEs9jHe}xTv}|(S z+e5$a{CnAT_W6zWv;%)sn6$E)mV|g8X}sm@tG9nQJ{H${P5N4w=AW{ohT^C$SzTQ&Ml z9eS}fI%+xl{?vEL>-TPadu++u)gc$Z_Df9@$gGxM(r+4nI(U`&d_$dh+k>ZXe}6o0 zeMCm8mCS{fqxYUIjXC;Cb=jrt>r&#+)5E{UF5qwEPt+^E*sm|OeCoyj2O49Z9GqWc zWxrbQkM4tliQ4}PA3yrELZ?pGsgUxzPSX86KA^ImsWA$t(h2Zxy?+gdBWd?6x_55C4}&iC_``8EKkL(`{CE*f}ZQ zQIt#4x-;>`duN}86O#Cke=+ziU32sKtA)kW1cRra=rvNF)Di8%%(TdPTE^20wOe1W zieG2Rb^O(;iAkStR3G3yD7ehyP{+inmfIFqDOk_a)7LY#lby=v9hqCUGiHXy*5d+e zL!O;}q|BJUJXVz@zVdC=%k|yU=ISVmDyjZj?_r$sPnhL>cTm0jt9hkMy8auBv+YT@ zb-S^yg3A&V-6uM%?{1)MJp6~wC`*@a4?X^ zMZ7(8PKl7z`p88&H9d*j_T9_lxahYqfjq>&oP&JrO%T?dh}s3sf!3?@S8O_)^VN z$k=+xyzjiO>@)cfNjFz7{2rPaqw(YB$>mumjs}G{UHiI0@Yng@DolMUkNGUuH5vuq zdAd2|!|d?B{QpgI_wT$g6j-+4nu&SH_2yRIbVZWQu+x;6}B&`&gn-M<4j*nYS+y4I~ z4aPcO&R0rjAGSB0eG?HXdwAk1)yjU?DxX#C&BCrbuWz~}^8VVapJhv~d+4mOWcK!( zvAD&<)q2{`r$^j3`F-SBfBpv#JL84$&!O{Q@P<0heqti>GLmuY*4jlsxdWCbpMJ$s z*i+_Kp_$d0wv}6PS=FA@-U8=l^Y7uk#qXbMh$OJ4y?wOs?#cT~FK^#p-I}}U57V5o zmQ6o37Vh(jDUD@Ld}bVbY#zssnF9I3B@_QYS>$^6Sw-=+*qJU*oy?2aq54r>?H^LFEMvfs=fFeqVUS zH^IZg=jFLSn!1a1qKh7Tc$zS;`&8dj^xOG#;vtWzf{N}RljgWgT>T)+=H+)5L7mOV z<5I0s5*qnKo?V&WuzHS#%j&y^7mv;6h`tuG@U+LGt7}|l7Oy@nE}(f#B4yHA5qqmD z`Nio!cKr+Z-}sF~Snu7d8}2N3z8qrvbvEptP=yq`miHSWGLe+Jw+K97<^qr9CbbY-1Ku3^D@&?i%UQYytYog zn0H7)r0xB85#H~*ukyAX%Q6yPU;a>z;bo@kLI(@>#rgJGi^^t4UR(NQnZt|k|NmS# zTvYq2q>QEi)U2+v-IAvdctmSo4ttZl{cQY=s;^t#v;^`hOugpz>qqij>l3l^I^DO_ZqUT(Nz>WPJDR6$_JY!PEV5e1B;}tzHcUG23?f!QXXX4Iey-@???9Wpz~Au~~0Ng_V=ip6zSdeYRiT`!%ItQxg# z3I+zyaRCT^AeQa*pmjp96A&Qga3Gz506WG&9bpIq14Abkb8wu9fX{KDRXPZBA7C*Q zaUKH1X&}`nOHWvVXc$KIq8K9s#vu>L=Of@Y2XsOL%uEIbKWyfpoR@&xBvgNOU@-}C zegd(k?89OT;yeZ1rhraVK=|ql7E>_JS3ork{e%UCVTMc$3<0E^w*X5Eumpy@w+FN> z9AWfzR+LTR=o*oit%A1xAT;U-FfbrC0>Siw>eNih&9D=(f85nX?Axm6gx?s*k zZjPcxt&JQ51FmIe=%yeS%b=z!#9k1oV1?R{Mc0X3LV${GkRAw*v&T`02Y9oxfs_a^ O2rziEFfi~sf_MN%26j~d literal 0 HcmV?d00001 diff --git a/docs/reference/gio/gvfs-overview.png b/docs/reference/gio/gvfs-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..628684dc350d2428170e169099263c6fd13ae9f4 GIT binary patch literal 48474 zcmeAS@N?(olHy`uVBq!ia0y~yU}k1uV3y}#V_;zDGUGnXz`(#*9OUlAuD*S%$6U|=ut^mS#w$;QE_ug$K1 zO`m~*L9)a(qQp5rH#aq}gu%HeHL)Z$MWH;iBtya7(>EZzkx!g~L4m>3#WAGf)|?ST41(qod=< zBZuRklv3SeKCRP!wz7{IY~`gcrVtCZ2W*=f9v*mjV5P&NP3tClS=VR9^2Dslf!KQ~ zbY_G6jnw`7nC3COV^b@cWKuRQ>cLUofB*06$?%jMoAp)d!3DKT%das&Ok`s{V3ff7 zf$f7{0Mj4&4@w3RH^anD?xyPZGf%sD@Us5_xl{9Y+*qdbLd>Kg!o_9DWKZUA%z5m3 zo9?e>tXsckWq82dMDdh&EJ2M5VccCuj<=s`%5&5Oh0oj@tOq84`!tQ?^%}OgW3S9M z%dVas$aZZ;v*v-wh{pnl3>*75L@9(Zv6d~gl9gz?s$OsPpfu;P%=Ztx1*~D^%UmAV z{?2dzZEf7R{_WR)+)uVB#n0RN|11+5!}Wx%B5St%pC*{NTj7IowWZ(>9t~ExZPUwd zzVBx{$Jp0#dE42}G=q0y4=Szsi{E~)x|wM;{e-SkJX1ciJ%jbz$I55#?RUSGS^Dg{ zz0C2L!(UXH=ex~(Hce*wIU7GlyMt2FpZF6PC!|0Bc&}_hO@p2wI3~-|Pxd{XWx)F8 z_#u%y3|$TRZ?ET6&#mLV#>sH~_CbdoZ^dt~|9_+PLP2Xe^J=qy77K3i@yz4hd~bW1 z;py>cH(q|Lup+GW@9ybIyk7fM_-=2z z#(jV}@!tKet8?GvKCpVw!^ZmB`t5<$3x%wEy&JD@+_m87>VO-w9$(6s@Q>?3j{Aq; z*~jB=|NNt}VY;61+C_OzyE~a>^)vt1yvzEz{;_My_YdSdns-^XkGqUQp zDLXy<5$vvTf&GX02g?twu>q@PH_YLWx#nVJ)X4t!Y3PAH2Cd&$zkO=EF>6uu;<5)D zj_WZnr&x2ft~cM9d-%{Z+p@$Av9P!QYSw&|+&bUBHB|cUt=#Cx-0lhn4A~Ap#lQXg z%^l{uQ+~&Jy*t*-8*Vu)U=MryYx%d2A8j`5|9g|o-7e|<>o(KB-EXch&#j3uJM;L~ zee>J*{^dR}_+4yY(5=VJ#b#wazc%PjlKVDyCiZ00M%m7*Ys#xzqGsNWOl@X*nQRr} z;&MoN8i0HeRYQaY<L!4qeQZ} z-rfk)?Jv(R`7DsIDYjv^`08hSt~p1nWz#I&anG8akAF$s>67o@)R!~OUi@R7LfG}m z;%{rbwlL2wZj86&np1wH@^-`(3#J~C-|ye%zh9iPTj%4Bzm*I-&Tf2L|F(8|(sWb4 zP1_5Z7r$vLJItUh_x<}dx#{Qb?>oR3bL__L@635+YbG!EZfR;fr^R5yE0Ze!rMO{h z#MvUo-%3GESLeUm|BdyH%bIQ&JFnQ|b6>HzKx* zXU(nWTf&~XzdexH5O4M)XG-h_PAjIiXFW%x$}e1)+4uBn?uOhg*Ahc@nBH7g__1>9 z^4NfPj(<1Gmf!gOPWX_&_iLHkfuhSFo5~$udfCN#MaPtPS+PnYJSA?T2i9+##jE}1 zR#WkYS|3m~Xa2(x`x~cE7RP_R zwcQ*3mWLxZu=q}a)sEtgvktyz`?u0rL(fEZj>mO@-0Xb*HF-AYs!u-ed+O<%^LmYD zo(03ttlb~PSj-qNZ`hUZvmyR))Q8#M4!;sJ5?}p(=XpLMx!&LjA=U*IF)gKjo0(U5 zSr=IBpZVTqPbbs1&-XxX|616*C)ab{-o*Ro%^8nIY<*exs{Co!^a`2je${Q2=K~BD zBrGtlJ}St;qZYFGvdH1S8s9bls<&>oKBM^S<=$DrjB}byA3H9qO+4{pfz7Lqmk%Co ztleV%rGPQSdwFy7jb$y}*GmcneorZw#pkC|7xV3>*&)08=azgF={a{Z^q0x!*sW4x z|9&NWb==RmT08rI-kI9G`0!uJSD(cTI5!^Lu>XDSZiSp1-?tpGcyc=Fc>b^CmeOAg zdpBy$jq6mBcp>b%kM(xK?F`H4s_J7q-YTsTn}4dz1{C&Is;`R{BrMQgsbVs_sr^F3 zyo|YQHtFsMCqJICj-g9 zE3o4-iwBYD>C)& zM{UmCGUx9*@nakA&hC5qT6sgJo%ucWi{o3E@`A7btiN%+GyeAVz4kZfi&|(&M+F52 z-acAlaj|so&IA9pH!VxQQE7hY_tCzmSIlmhMV&i!lz$e79pAB8cVCqJwte2y(5#%Z zeM`68^hF5^F5kMfAZ)4fR4cuf<3d@Ra$g+aSf63v?+SB_?(*jBice+7G#`Sp=WQv+ zj5Qam4qd;)&bhTfDq`zjzy8G1@7D7^Jf2*`yDr?9Q=sZpfxQ!R`R2y^w@(+ZyuZ{e zs#|vd!|j22k8>L9)^&cJ=Dy?F{udGVmh*1wz2 z-R8iW^z7v&*{?MpMp?_o-JqQ z+&j0?lx@wWy0fJs%VHypEge@l39QjPJ^dD=v)#2HdoFKGJ3sr9f<;N(Y#~WFkLqdXZ>6^4uV*q(KVG1__HB|>w(1GNi1Qm(uI>C+J;UKK+nQ4=;@x*#i}m~= z`6Fs`?i#h*Kfh{RTa&lHSKv=fX1LhZd&k|AeaqvV9^d+I`{vMpE~m9l#c#sj?yX<; zckYejCw2!;1t}!d#&MaV6c2v=z=iL#TC**ElZy6b}_V96LbrZoG_tWn0e|CfQcc_&rY zoD{Y3jd`5SzG7KmeG&6=!!pOO#SiQw&TDlpTl6H-J@Grg;WK}+u(O}7l)m@-AD{K? zr{NmIsLBY_U&(JDq$Ua9zdtKC`R@7so4$Yk{H<5c!-mMlp({&1e}#N=~UvN1N>^8LJ*H#7Tksw*ieak1@MqS^9`eDTuD2MfLiAKLn*;^LG7B_*Z1-E0Ee1%+34pB6T;-dFnZ;*W?8BL!Ti*M8`*%iYOYXM=vjUS? zuQ4}E$qBEujPrRQDaC&;Z$+8cjwKqO8YQkzyphSU(Ie-%xA%JIU2P}dmFZ<@b@ORFI8%^6T z%>-wZi*oE6{n**p&KFu|dc1pCi}1v|cNg*93R|*yTI5wDg;=eo+_S8ardFG*=Sycv z3J6Y&crPnu4DKdh^3{a&s&RCi-^?@Fx}rq0+p3~kP*8B<-OeaTw;D&Md$&5Tf|%e$ zG0T8R1to9?eV6=Ylc}7WZX5GBAK&%n+ZA6AaJQVKUO5i8mAHXB>mJ{eCEU8VoB9Sz zYHXSva2h;V;9daPRAe%t!ZpdyzY*>Iw_n_m_@I zO|x5$h*a@PoqRI++|z&Q&jUq!=CtW{-+Q>L`&`ogz~+-)-iIFhE;~QL*7D<=)0HnT z^WO4QIy?7x!%mN%3QCuj%69Ck@_57ga~D%3cmLdseT!F?{+YVk;&p>_MRIE3NElU+|&?*C&vTkB6??)OjL(yylJ?{^1bfj4SX}!J|$Z5(2EuYkAlh z&Nyhw@BJy1zwfJA@x9r{f5nD=wUak^86;M3(0%XQl|`Cz;!_!ok8Rn-$@Z6v%>|UV zG$aHv`x6fEOnY3k{OGrGAN$q&{xyWB{hwSdSG{=Mh5g^pu)GkgEK>guy^ z?62s~pCv3+@h7uzYgr3q{46uScF)43BdfgP7oRWJoq2WDd--YcqY~HUv z>z(~8C6(RM{1LUju1kt9NXQAk)Y7xdRM<>beQ$b zI=jx3k?TJe2L4!Q)4pSR;qgUR8DeTryi~C*=2w@q>hoED^4Zk*qWAfAq1)fR=zh<~ z$~JRy<^O4#K6`#Tuj&#jc(5<{=kNP@&z5vPKIv69aeJm}aeURB*Ljt5lHw=u-;eD6 zzaV?dVV6S&43}#hBo!}d`klxY+t z|9`~xsa?vK$m`qv%kbHsua8#jayBvVh=a?8VFQkNc)?dp!U7mSi=9E%E$9!gqEE zPkM2&T%%pKT&@1+cbjYVUkaKX7!EwRQ+-dN{AEnuoKg3OGY~cERNmrXK;Bb4$gmMhd!1rZG;mi0f9~!uLXE^4*CjNgsP2WhbdWSLFj^{#Z>7_5R5EiE|cPUU|LHWIk2f&)1iz^7gzmpZQGe z+WPrS4X11Ms(JR#UGQI;i%V|tq9ntA4ytXt%{x!JPn`R?dXnu)29|8GfPf!7Pp94& z(|y^4k$gUJ!Q(dg`2WO|2ZhC>D_s^uVU}-$+POzBr}B%{d;%q zN%h|Q&v#C+ZM$>h!S~P```=q^lFih=u|vQ0-=+=qho80{-tVkUq!9%joqxTd8TBqt3 zEqY_=W%Pbg{P~xH&7EyLn`B>}R(&!5_%z?}N5;$xzccR)nRa&Bsz=&vJU{i{y;8ri z=WRaA*#*gSbwj4uI;S3WV&kct?GoPfxP5xS1oOFvKDBLq!^rgSY{)P3;K+|+u17CR zUii;vK0s9OEu^4Rk<j_Bs}*G`Jv4bvezl^p9$O7IRV>qQ~%w3qZ5@RT5$LGq|2|XE=@ZAcu~`=RX;`E z?3&9JFFEz7`KGhBv;N(DyjVw9-SXe&$$#$HCoG9Oc0kVfL)E1Z*J}>0dmA43aQy+E zb!z(meKr1C&)c&4#ofm-d){4Pd%Z?g|GzcccdHHWqP@%K_$B`IXV|gl_@&j)mo8E1 zJ7!SxW7Ym;8voh6R+l|mU)8zxcALSH|EeEPmpp%OT)rXu_1CX;@e7`1m*vgBsqxmf zO=l_l#jRc**B2Rr<_s<=a%pY5uKWFMv8?AkMu|4=!zWY>Q>ALz?({u8bzriA%=G-c z6+F^^X5_khuidoPa6(=4JZ0mr4tLhE@Pw;%YA(N6{=mB;Hf(Ns>cjOb_9kaivB5EJkNa%&&TI1APBwIA+kd{HZu_;p@xedDeRgM0Fn^sm>27E5 zHq)5uOV-6xVqfW|h2LBzw$yOx_cLy>Ju#fmul}yjTHie@MqT31m5JZ#onmkO_i@^x z=ip{$TYT*5-|brxTxY*+o)VW>H^1EN#+K9XJny!+xVY@v8S%WQKm7ZIkaD5aMlXhK zZ!6~f+gsm!yuf^SY~;;pyPkgOIg#mq;)kV36l-SuNAn4WI?qhfsx}{Dk#c_h*Z%PA zn_sM+tqZs%yH+vtWwWyQg`he<9VUfwr946-b`=b=9$@ZPBC9CJ*}A-#rleC>pS6B)0+Q%kDhYOC45KK z zp%jU|vYF>|H`hMsQbageBL7w@kJKm8zrXMKru_<3xpH;d>>sPdgEoA2GRxgNvmyD` zIWa@--C@UOr0p$mUUIgn2s|aXrT5f}FykOkKilpnS2i~=n1;>|jQb|kdi1k_;m2@W z|Ga-Ed0zcA)@~@MT*3E?;YRX}SsR-Btyi-g_U+9)oAboHxk9;TqQOnEQ*y}xx1a3h z0JVb!CyEu7^&1`*&1kmY@*w(d#bmXKcZ}achtMNm&m3r9SW_l{k?*G-7hB5r9R~5zRh=CjTU4J5H)bC?^H_exKmXPH>=mE# z_c6U&70_sM_z)aET${w+*cVDhPC`M*u&ucz6rJia}9pZE7gc}{Pa>|%`Trm*JK z;*96&zIpK*9&>4B*ByF(+oj(ze&R#VmEU(t{@Ipyv*2y?_BUtu2!q~5J9Q$LpfB~zz50OP zNr9m?bwi1=%~#GjX54IcEdP50E(V4!oK-I<_)_Ll@ULsS({uMXo|=_ABW*%Mz9eg< z{qid|O)1mOAAR%u;}QC`pQUN)ll;ANHl2FP;%h&{?vLsH4cWiHE_5n6R@!&qLHd{1 zg&SlIYK~4jJ3S!kqikcs)~##vMVGd2-%xq`F$=Tw$~7~bMGsrM&XatX{BpA4Ex+Gh z+j4f!+H@+E<*Y*5hL%^ScD}h`v^LMD#r*O6B|9fSp7nn1!#QrI`*S4K9Ge<_tt59D zY~|Uq@Dh{7JH;P|=4n}4%IeMJ2>#x(x608^=tp*fx1CN5@Bd#scG?YVXFu4&{$QW? z!|l9LoMw92`@e|aeB8fj(pG&}7Zsnxeb4u*Oqtt#{)_OJ^XlcF{{$?&F5&Rru{>bk z*ZR`;Gq21SSKoPkzvudyZkeTuj{luL6&*gm{JrNq$Nh4TU;lsmCjF)Go;k9v@&aFU z6OM0V6%2Z*ruv!hSL*xQnV)pGUO)YXW1g?$&7vmL;*+Q6O7D9x_n$S}7b~-OKkrG| z2C;8i`$c{AoXw9*yvifqmtXm^1vIw1YGs=y|AD0HoC}KW2cnldt!JCeRw4B3sZBfs zg8~C+EkL46{p-?$DnE|THu!A3`sjo2{s&s39||1bY#;Z3!{0jRZ}Z=DpJ2W%>nJvTUR7drgH|9#{92~nR^ zmZoyA05@s6I@zbM7Qc6-aLKZ{zG=UX7_>$ce+eqhi)(Z&V*)3w`K-fPU|iT!EA<|F#;(fjqAAN;=-eR?rpgZ%m4 zy4&vanzW}!pKkuv;ye9-Z~39Qg3CPoe497jek1$pg`G&={%K+dPE;%EGg$sj{F=Ye zz2&v@+wzw`GL8#>x^=7leD{%O4hKxmezQ;GbvA8MQi{E@t5n$}ZGrBT>1|AnEc!JT zw%gv;7t8USZn<2?R_@mmzw3{k#nb#Sg$c75=f{a!3V_x&OuRdP7w6VSd8gR#5~T(_ z1;@A5Hi=)m8}om!^*@&K3pHo!gYznQ>~yy8```P&*^u*AIH>J=cjl|s+XrU%IqnNq zFP&tvm-Blr!*=O^g`zT(*ZoydQUWz+AH93qb>Y*^OxgMKOuZjm@jqzr;1~D9MRm8_ zK_)E9bIMKHtG~tO*6od%nzuNG<2Eo)4t{vfu=jfAyP2#L?XDk40xhm!Wxmv4{iVRJ zMy;av2KTLx8YRD1Jv`FBK!JhXr|r3V)_qV*yQ8Vm%+!o=-@0wn_OEVpo@}Ki`~SN} zO`^TUnhh4;5}bp(yE?$5d=hgfigB@}i62~88yzQ*-|N23p^9(Hv%|lZepudF@Z8|7 zJjl+C84QKe7XKz(__U`|c6y(kbK=+c4_vARKL7PU>PY57>^hP|MV@VlStIh+~toe=MtJ^Xec`})C7%WMC`Yxx)FwQ4^<*mO1^ zAor|YR48-ywu9X9hi>*CJkb7Nu1)srHTOO|EB(5^e9z;Ztk-omF4NQ1>(#T(pPR26 z9(w5Fdb9n$59eO<292GS`LiWty*jZ?nCF1<`$KEzJ0wmq{h1kA@Ka>RPXmwK4?Rsg z^$&60H@Ua0Ox`M8k!ySW`~U2J^45Med9-_d<7@UT`O;OwpQ0j`KcDaBscRjPc&=)$#_ydAHeZ}?kQ@y^5|U#90Rr)1pf)BZ_JUrse~9!`8V z@x!mD0R_T;ettOC$Z%j|`XOC*$Neg+9p+Et`OVjBXB!^N(QF%5zVNnO``cG~phS2n zcV()>663iOvLq*nfm<&}yud3}l$7qyfb`BL=ABxsBOo~OTEzCe79&T<+MN<}Swla^ zCAN}n3m?anWxrAb83szyps=82_YT?{C285wrKGk*4Pl5*kMh)6%Zwb$vcaR29VOvs zul{TQ9mCl4#_x&|Xz=y!G_G%u-UY0uSz?|g3+*W{I^YNz2LdHSaNtbLb2R-2RV`uw z?g$GCLKYnb}RkZ-PC@lpV!{A&XNO%#7o41~+dt-X&-R_^w%*%rC+ zKVC0CaYF#g_g}1{Xg67 z?P^Wc><6!k6Z`8XJZSqOGs8qQ?w{B1Fqb8lSy@2i14}Mz+~>>uyXI+2$d8o_Y!!>| z-wWqk{Jo{Nzd7^rgFh?3a(~_$RdhE$&rIdRHx)O+gwv|U|9s5d@!I8Wy5K}V zK@PA%#Xld;yYOj6cM>;C7IQ~w^n~@!5_x``H+~K{!W9hoj85xxq--3(;rI95QzfN8F^rB|0 z{@=^~od4^#J>JQ_RC>#NR~IX8+r|i&CBlW)Y%hQLd@wUC_AlQ2%i*{G*UFf(AK&-B zT=;aB5XfWaoWL=2BEmiUKzVAc{@-RHWfsf6#tV+183=G5=$(5}dy7qV@#WXE(td=y zdv%nA8@^s14asaC%*X$$ZLxX3ZQb;LZ%rTG=eLMrzSD_tVBmCzMYXB-eu&lFKDvvm zHbUgz->l;njYoLirb80+C66RAoASP`GAkNaUS6QqmS-w^SHAw+pAYY!>vQU+zg_uP z2U1EMvU=)iQP{9`&TqvYdv3E()BUmU%nfpDUi_E6DEs{N|K>{$kH7z~bItgx^5M7(pUcx!D@xZ~^p(DjE_{403+c0+=o$dt&(g{w~`o;9j?$Z7FAL!!c9&*n?F z)Uy36KL0M;x3J=Y3-h;`T=Q%AL+v!qwC;~(`@VkTHP16G$JMjtyE{t6*b=hR*aat^ zQ-9Iy{*Pn39ZT!K7u!6gS*FLco5wS*KDQ}eO|Telzf ztj?_Of)_e`{A?y^;32Xlvx6XOI?)Oc)M5=Z^9ZgIAf+#;g@Ld1p@Zg^=Xef;n1M?0 zjuLyhhKI%1wbWg9tt>s>|DfUK=Ba{8cQ0%=PCIaB<|&Se@3OAxlnM)h3)Xdz!WkA4 zIEqiIcpy_>F4gh$TI)KOyPrPn%${Alf9H8Ct-VUSyYth}tcbQt`1U64e*U}7>wZ<= z&aR%AmwIi@g->T@p51@{PP*6n5+QIOT2S!ivMWXx*sQYG?v7$!vO8#P`Slai6K*C= zi}@D**7#-At|;DJS$~!?f=kEc0h=@W;FY_(>-(HgwT_N0#-+kp%o};G@aFyPX}akj z^zUvElj~E7Ov{SzR&&m5u6MunVqWj{`(HR&|5tW>dOuxAW95+(avq-!UVc${F|{IC z_{40xzDKfO$mD~-7EKL2uw=XQb94mS^c zlRr`W*S0Hc&C&3n)`_z`Po3EN(l*!X=3!&$_49w*M#tCpKbrdb!_=z}PQCH`RVVz? z{_k^@^_GU3>#26CRv<;rQvo#1vVh z&N$&?ZlyiPXMKD2Y3Z}&s&8iOpKwY3dSGmX&xQO4=T0e>K8brGQ)_gy`df~X?bX%$ zRNgN>uMzuK*tB)&gb6NA?;Dr&|CikBZ`buia(gjr`Pk$HVZ$t@QwNFO%m%& zMMdg<*soAjh$#pUKbGR%wF9GA@Bn8>;&io5b>Kp?BcwQYNU9b92( zP}I=p&dMCyG0~ym^Xi;kZ`_#vIlQpZyz6*%`uf1HS7oyD{>$6)y%OJbQNMnYZ~YHr z$9jV;b^qK>-T!MXI={|kzk2+VWw+wL&pa*sG*&yn>EPYVntyV95A$<8$zNtvZ#*@A zuj|Fzmn93{%YJ3*S#j>~tFKRDE7_jT_L8aza!t7I#AMnpu zxOlTc|04eQo^U_(xxNJeu}xng1<@-Elv(rJvXFFN?H~{drsS+tx*4Vx%F`{|DLjR^F zn^XIKH|_a3S@QGpZl~YMalai^9(_H^+p7I=Y5#%3y$e>!n5}8*&3?Ef{=kGS7t(J} zJ2ZQ~^M#Fdm4-V1rLN^R#Lr=?JD#q$IQjBznR>-Nf22gh%>OW)>RNmKnCXYZ5f-Ih zfA0&gY5N}E{*|?N|Mopcs&an_PU~&W3|_?D<#N!Wy;ybg=kMDOzqtIO{Nz#zMbfD_WS#dulGft z_{s(nzxW&iu+t+WptzwCMw6y(-_tl;N|wZCUATAsJyOZ(g()At{_ zHoMK>$vy9+Un@nw|6Qdg@Ij`;uvTxL8TZSF%GAABL+N&r3 zNVubCA1WO_>HDS0PyR>r`@x>{znbQdR%%$z$KwTyqXT#=#a>!FRKo z|FEm+)NHZIzt7}&m4yWT+P^$vvgM4x%Wcw%D0F^j_2WTu#b;>_7TNm6%$KEm`R{SEGC6;1 zc0TSHCdHDSaGUMNhh&Y<2fvAKC=l@}y7K9Kz34UZ$kVoM2NT&H?#mc3ZO|6q_k*KI zJK;80g}U&vx9gMjrrn;uX+blKm&W(E#}`z;S4zDi5F=;4PVVrDJzpX>wWmaGjS02i zl)SOD`IG*>##dhRw_g5rF5y6ay>rt093Fq8&foLh{=3T`yz|9nZ&+If3wK=Vad+u8 z#rBo@Y<8bGGJn5q*1p+2aYk498^JICKJQjpt{(L=;+Htr_Nm9dm~-vB8Mpn;_qNv_ zQbr7iA0P5Kqf+=k^GoH6vYsV8Hh;Xa44^ zdw%v-ZL;mqkB9B*G3OIJBP}TOERGa$A=7+vYl~3w;em=HMS)v+IpMSJF=YF8z z^eyI1$%5bSIjm=Pf9Uz?ftQzR>79o?JASK8622RD;oq^^kPudx z+xm%jZC>9gP4!QCvvt2hZ33U(cJA^hzMIGAo?mgfEi&`d+oZ$Bryp4E zi|#FqwuL)+dGfVZR{N*?SiAp-htI*=yY1)g$$zw8-bHC%#8rV8+?V?r?#+Bq=9pzB zW5!#h68ZYar^MiyTlc(F{&4eo=rIe6qIwU1rgA18Dc;Nd?T3zjjpns7+I#WFi-_+# zI4>yQ5?7>!?mYPDbbq12TN#f{ z>pXLQGIeE_oY9ncAtj{0L-UI2F~!GS^RMcL+iz!SSoM7W`fB}`o4TdHMw@O@zx;ed zqv7&}&+PxNdCm5~_V;;}io-HO?{cc*EY`i-zx4c?j+gmAvYc31!)HjbgrC#osV+8j zo>w=YvHb3>yq7|m8b5m^6SL1%#~SR)+xf_M_3fyivlq?|ebpl@J$LfDGaug+2CVO> zU;XH-W$E#XPglG>crKqkTd>^t#TwgJ|MtJ0+FR&Z9jx{Lx6r{`C39;;U%uq*y*$;T zW1;%3>$4p!XWO6W&i(&Qd&akKnfq;&bGTDaZQOsr!{f;0tIXl|o)_M(H??!u_L@u70YBGrQ}_ZI%I-x_>;c2naz#kUjw zCEhRR|5>SFasKy#U5QVpwr{(=+5N`bNohWvmb|I)t$t6oEM{|$Id7~uW!VA#_eZ~& z2N_R(HEp}?2aA8N9F}`b_i(o54p6!DP7Yer(8!{Z-y~^n}FMoZopKb2_j{4OZ znJdJ0A3t)!vAKNzh5O(B{wR&PbZ^QbeP{EF^W4An$ILWT{jxXobKRO~y?;gFcZ<$- zeE6B9(x38w`M;w-+U1kppiNW9N}q zaqcVizr@Xd!qNIwajyE_iylQ^eCF@p5hs31Ew^Bc#+#ci3?^45u8Xk^_dMtz9(eoc z(vR$YOfE-*UZ+LNNfk_*cEL@^w$o z&6D_;FFL(F@7v5w&WZgWuLQiF9{JB12J@tf~+KJen-n!wgA-pX}7b>Xw0Tc&)I zoo4o6(qe-**}hl9*MB;^G<@^7i_33*{CGV?EM(j1I)P3Z$K8kb&%a>4B_?@0hXr$F ze#_e+x6*lE+#avk>wG$Ue^dQm>1VnPQ(rGw)0t;`j_Zg@x$wcZ#g8^rb@y$T$Y3aR zPpfOWna|_DqV4>b=&d=7$9otBw|mQo6-)i;vjt(TeKWgKh&=T*~+PiNQMk|?Y0-(CB9 z_MXS*Q_qNI{`vBL`wE?v2fv60|2f(&QvXp=g00i}yV~;=!Y`~dWA1KMyZ75sWs%48 z=G%dv<+mJP%(7^Ps)pk3&r8guoYf8$dVV;mlx=mzfptw}-d=_(-loFehi0(tWt?-j zd)BUHJA!0yXYed+YScT_VR5_v@d5L-P8&1bj6F`=E$dwS{d@BKO$Vxfr1H$Fu$wyn z{K7xoKSOFZ3&eYx&QRND%B}h1wUd{f#q`GSccjW>T%(tIt9&cI6lb>B^3yDhm}~#L z)cQUqgdDH%$;>z6mpZF>%t${4`2H<``@1nJ2T9W@3htX^X&{% zql19|45rPIn-!m#s8rl7J+JoRI?G453^9}1+fJFE__A*Dmo1%Cb0bnkzD#TeV^-at zo=-pZ11-|!(k>j?|E97?-hQT|as9P@FNHS#WIni|_{8i+q2rdBy*EGZh`n-SbNNpu zwR;BVzZ%p|oPA+0r{1bJVjHC5CoJKJW%Q|Ue4PKi&->QwNl!|zpPjVj{r>q!Wgqie zo_xLNQr@-o-&j4r?Ydp>zH5?)eFoP{cHhJak_)o_7IBH!9r?z;Usb~7vE=O^*SYF@4Ou1QB>{WX}ftVj7#z~cwUtgD1>8mAk+ zSoX3s|M#>1JCiS~-i^xKY5%7%OtPwC+Qb~*An(F2v1@g0%y*@Wxz5v6*S;IQJtpK; z_l~#?Iwq6bv}^D0Sh80$GIL>x<#AUR?aLc$J!h_eT)yg|TILVCFS{RP9gDMF`tI$j z^Km(o|0)OtE;(tOwaqe%^Ub=}b6rmHEn<7SuFh58yH>O9n~}nv-WMTHO=jDVf-G{F3a$=G$BI+siH-c)YgBJ#0lm%(kT}e=2{^|7o~f z@$H8TIf_p|o4LlE|Nn4z>FIgSef`;XDl&iA-4CXQF87>XV*m3r_hI>T>3u7r%f4@B zJC~N$!Znfg_Mz{yb?cQsy|ImCZ#~8)S|_xVb>Xwm>z%&e{mb9weQUPP8GpX3Rquc7 zGk9imrszyo$Pd>aFaMrdwN+=|hopV8D@9M|*Q~hvE&tKJbn8nSR{DNx_HciX_bMc+Rwy$R^_-S`mr)xLDOCCUYM*4wH;HwReGfW_ zuT-gcRM*riCn2=t$Hjot4wv-TNa{@T<2qXy`}4)?-u!i~+$Vple7pGh-sbfyUuVaB ze)ayft?+_(yKAFweryW$I9@QhHZR9mLgY?8YxH`nPTusM#VO&BohC=V%i+Aa{q7~z zODjJ7`*WH_YVKq;>v_C)|6KChdhY0z#ZIP4OV8Kcda=9d=;V%-*7V z?SJ0C|DFWetdTR zgWulzN#Tx<#f~PVzOdw8_e2ofF8KAP+u-gk-ycT|!~Z*$8SE<$d$HF)%=F*7uCp7K zEdiC1@@HDZ<67!%^K3JB1TNHY>OS1a-ac*mnf3Myc7!bu5xZKp(d@wj8QFX;HY@Gt z9Y1)2e#|(#{f_HX|7gR%j!i$aHS2!JbZwhMCydX1C4u zr_jDbLO%7XSMTq0dzU&r@lAE~8BHUjzNP0quQ_*~IW;wB=clYw)7C0Q2p?IawXo`D zOj(TW+IKIH-+TPuFDmS>W&d?q`$g|Ww-r46HF4Eddm)Y0D*tDl){NdYCt<66lieTb zeTmm~ueYE3|9E|O^e&fK&v#tj8GPc2b(qZ$nWeMK1$kILisz*szg#|P`(3W2-YJ1R zlDT)6Ojes4Zyw!Of7p9X?MLNRUD^hJuZHOSo?>eLhxdBi#Pr97OJz@dP+se_G;(X_ zRP*zT3a+Lx?NdlAWffh$@7eO`yhV5N#Qf(KsoKh{6Y5ph_WNXKpQ!&W8TRLCE|Y8J6uqC5HaYCS@a?62@{K8t-*)bvHFdka zf1#hqvi#gS; z{QBg@^!*Kle@z6QZ8$ox1HN)7c5b5Su$r{S@M~aUUPpM*`7ML zEa6~Lll1dR-*@j!yzXuDshnrWs~a=++y6XOKY3rB)Y5Ej&UaBB_r5-y&;CHtytz)i zFMoSUXF}VvZDx0F^6Y%*GVT5kmDTwb`# zrhR+1WNwjd^%a{VZRKLZH@?YAzx%D{l-tzZ^H?wC$jYzUOq=xfv@%XD-|+Qx?~nRl zJzKZeU8}g## z1@C0HgG|30>%8qY#cjRRet>iF!;k$|?p2EoE4AKKNtT5<-b`DOo14Ajzr~CT%l}nR z_G^E2J@KrcMg)7lOGVnLdF=;p(buRZyMpg>ey5fgzbw30Sz&W- z<%y&j2M>Fw{rw`Tl|Gw1y z5DvOuJ?T;__lkQP8XY_})#PGc?)|_g?fyzIeRAa$mse-|ZXA0lWGK7YU!wDG!T0$` z;=ZSB{(7}sGj1nee5R;dme|V0-xr^kynIq-LXiCh+fU|it|qfY-~ZdO>1*`I--?RM z?Iqd$m;KLle_U!_>?alXE3S@xW_#_SKGyhvU3to;M^hWv{loNw-1-(C7d(D3IcNWl z<$Gsto+g(b>wHY{^o@@Xow~x;EUXGwWQ=DBPvYXV{XNO5O2&4XjPJ7v2Aj(yI={@V zRF`b8J=523w>;;rT9(%-!#yWezDRle`oa9N_L8B>@~itwCOw^Ulwp@^56NtvX^_!-@LoGukqc>+mgl!&wNr{ z!bLP1kEgYB-I_jcz0JfMXJ;)nWRBgmX`#v?9$DA_ysnim-L)6H+;!ep8|D_aOro*W>(d zZZf^5s)PaOwCBMV z&*RtpfAs(6?)NV=R_*6~aQ<3O6{`~yqZ4;%m3x)=ltoR4xIF||SR7ddCwy{t2oYcr z6%f$$dau%=Br)NhwW2^3*OJ^<+baLxu-Khgez|di&HUn`b7#-ZwKo3lXZGE?_<3KU znoQ>%*{ApPWG)9vePLqp6?#6-DUtPtubzd>|XGRj#Ch%Fj zKwr?Kk|XE$WuyKpaxZSN2b_wCKa#K@V#1BXpX=Kn6cnfm@xOD9s<8NyWvZ~beN9N^ zidWm(U+-=Vm|Bt$E4X*ceoyNkegEb3jyDMwe=(W#-nPxmQgp&C$G}A*bF!|ucjm=D zc(PQ>WcQkaAjj#G_#BnmFYT7G*}aEi~m;4EQw1sd6$jUIpt2`E!D`aihb=ehyWk4>lmHwCXH;z-DydH-sV=plPnEZD#Cr zQTq2JO;YmZ<@XN{zml8aq4HtHP4?QXlqIX{JE~t+g$aPXBziBQ;nTqhZTh!O5B_>x z7_iIa$U))yN9QNAUpx@mx#RWgi%afK_b}ct3+#o14iklK9{SeQ>j(*Tip00Saf?-F z74a+GsGh>LM2J(VzqUV2`1{61AjKNzRhkqy^w$(@R&+R@ueLh%XzZJ*@`0?Bniq>H9f-(T7Oi{+jK=x5068kfFIT-1ox5{qwD_+4?kv zJZ!9=Z|j(xp1Mp&>MQ4zZ#jJtYZ=d_{#O2WPwIr~&usN=ptFPmKTcks==AY=v%#ag zWg5|kSc_&dy<7VC;?u($ElR@YzL(v-A)U2t-)+v&KYJDiX(@!?SlE*9y5*%E1NZ+w z(pK8F;kCb*KQ2sRUoR*5dk6dB>g~<(p5YoPMHbb+7G1S=-uN}fXWH%hiZt_M{FVHr ztA89k>&d$FlHAf$p|02Kls71v94fkJEn;LD_KL*tsQ4->h$HgjE?gg?!8riF!P$l-qgTG#=lEc25;c%3v;i9VsH=Zv1Qraw)eC^t5 z28QpiY&Yip*F3W7@&aGaBU6)i8|+xR{Ug_}i%&D|eQo!7?X~3FGVQOkj!WFj<4N&l z7A#WZ(Uj7iXSb(|RXK`@f#;XXnRizi`RC1E^!dT`e5Haq0T#!G+LLM#n^Z*%UzIFb znOtb}qrBu>IU|Ei)E`5ub5@zjxBWk4u2u~AI-}+C!@vt!!G+&z40iprU}D(fdEKDk zk7jqWfB*e{c_kr6hHrAQ9}3;-vSn)97IwE6&h9LK{xG4&N;w)-B2;}WXOokwiQl93 zHts368-`tsz)-uh^5wq-gQ26xzKsXkIJk!aR=kF?(B;Rjk6G$oV9VC+RI4+hXWJ$>{cij zKexg(Z2Q}&kHU&~Csf`&A?$qQY2UqO-BWz`FNDRsyZ<|2+uMQ-+xNfpJG#tzk1@F5 z(f@buz)Q)6NxObNx+umk=aI5*hWY-$b*J}Q)XMQl@^8BKFH2NwWr|qkk|KSbS(hFD z)E=Gk+3a-n$I0U{Ji75SI*R}>*bam0^OzSba!elTiw5EQf_UiY-p^{{g|TO ziMpT?=Bd}brbbon9-GaqC~N>%y?lJu4okew=wn(ZNUBBv9=1 z|9z7+mfa31JG*UPjP`cH%bnZ#Kj)}{R?mvd^Zc2eAvOQr8P`nH{!@En*PZ6=@)o{) z*EZDb^Ua;*B9~tl{?2{&`dQ*$o~7Q&hHE`d?n>Se&AwHaUVi&_`G;4^%O)#tk2)KC z-81py%%8=qO$#9@#l*`FEZbDM3rpd6s)# ziKBk_P(bp7{-nul#!Qvq_OPXlAk-`)xk9+F4hNgiF~hPOq7w zn4vIH%KEm@Ok18^BHeGFPw|Q5+V#a__VJX!hmlV-S58q@d%WHuJ6R{b$9}toD8Gr8#LLJeE=3nZ?h)q-CGp zY&&g@^%H;YHHME$mpv|;oPOUVXy@!q`;tPN*`UR*FOIS^-%AT$vv_OO>dG%KzZb`@ z+kfhc;r{u{w$JpR|Ifkabm+GEx*b<;+%RAJl55wQbM8LjTg`djdR~xJ;BeYz&(^%| zfYf0d1_OSc95$t06~WG@?o^n8RvljK=4X?dX{%lkmHU^^Au1`7}s|Jb1wR>71iqcD?=>_W923O_tZ6etY#;eVO@suI)45zuVQDbnE@wduE^4 zTK>54>iPL||23DzYRzowlylbVdfED0Zts_48L8hce0V6sqWqGx-Pf@f7H{3JdE%F~j^gb-llB zy8Iqbe;5|R^yQXF%Y4p*$KSqw(6Y+<)QywHq3iah`{zi;Ni!_)+|}X6`zz`5MDKv* zFBf|D9dA{h{n7F9uSXY_%xaXrxP3|USLVsP7fLq;>^>gxr}(AZr4qIkiw|$eI5PXk zyJa5}qphc>Mcg_T9&`NMR?%<1*}M!M-S$0frBw;OA3Tq&x}0z!^TU&Ku4`r)Gi|jx z>w0MNZHq0{%zdw!xYihE^{mlawqBR>wAuf)N0*8BhRR0vrW->`fn{Q>4eYzs7oNI( zU+L_rkU2)FnmT(6m`_VhKeV!^uX@ux2KLP_t8#odYDxqdY_IpO`TBgP&i4Bo{>R9~ z*(wIleD>5U*oRvYLL^XJ*Qa#{E$IB6Z9}@8caI#@Fg!4=uN*gvIrFWM<t1M@v zJ@33IRTQ$$+_F-E_ktgd)MHV>gAw0-Dz3C!YT0#yT1Kp$>zUzV5Ooiq zPiDb-L!QLxWyvM`{Z<5=5-nOO()Z3T9=H+v+~R0S9qIPGR^=Iz&KN&eKqe_=rs z>y8`RiW5B+6cxEIoz?sC;fa+uioYo~ondNhN_c*aasKpTMusKF-W|-Jc+%{%n)|;t z+l|NC*Tic1oG=rZ;GtqxpQ8&p-(%4t-Sg#aTyGhlK6q7=`0d33g()vLNHGLdItb+b zy?8Tg-vh?b3#n@hH7-7A=HIw!ZT`AfYU&l+;q9>Lo);b--t;cwzXqpKtGM4WJGWYO z*JV1lmKbZiy~uKYOO?gcpA3cHuRH3UjJ<0BPP|H*s~2o=H7?S*WzB2U$x`(;c+dZj zVcj~>ZQqU>uay((Xu4RfnO**VGJgVcvLwsO|TuP`&*`T5%UjIFS;Ubm$! z`(N`rj0{(#Hw(|d{;fjs_kjbTvmRHxcx@4aq^G`*V{*_d0W*x54ueSPIzK^LG0<9l%MOAA$~fkUoN;#DYgn;r}{8t+Rs+h5?{P zeiFRDup;7tECa+t;ClH;LPMAJJzc1xH-A6{q9CG|;VSiBNI*~!)Gc9S1f@P$hosAh zlOawDRFx@dwLM|j@P+3wIbd{4?e|D-cbJ9&8F&yfYe+OzC61b@%JD2GM64P=P~k4Wk9u(qz3zl6U({(mo%d8ge( zQD>0vdDyykwP!{d+Ab)!Ua>^T;o-S1MNr^7wekz>XJFf$`0`s2r#9HzTuYT|(-ofP z8IDRXy`q$q(R<213z``A3a&9aEE(8 zYpD|xPms06j^B$)p0=&HTPSd=Aw1QRY3_W-}_q~(cyYZ-)uDaqi&E{{Dwn3wU-Zb+GX@QP&b&fd?_%O9U=y!)dhT4Ual zmq$|liZoNYs$K-$65TC-RQchb5Qz(CkF6DE-0f$}#&Bc$JQn+E)-5kB-|Sd^|G=hy zzJ>qtYM!zF3Q=*r?-ubTw?+21@bB$B2d|`_exP*z-?Ltqcd23$cigMKn4Nj^S8m?2 z*?sz^-|X_<#P@7i+-_+2L?%Z6{NXSD``uRETT_>$Twt1_m?v|$pY!1Jzu!VG4;Ct~zbt!eySsb! zLHkF)7Wzu;c&Mc!#L4nd_53&G7X@#Q%SCLqyODJJ)rsgGLY3U%PIZnis!toF9SXST zrL3g1NNK6Zw_KK36S4YVQzba2yfzdME!@aL9sPa@#HYmHz{vlW_cFUNCq_T&#& z`!xO(8HwIsbGLbxs*G_`pLWE?1m0);a~aS3T{f%?-;z3SN_NE8$18nqTbSNtFlPr4A{^Xp~#l@Fzc z&u;%P6kBI;GM@*Wm;!Dboh#8*ttrLOu=l)1jb*9QsfudHWd$xbk1-oQJAYQ-T@Clv zo1w4%|5_-Q`^;gMpoGl*ipyC)4Xvl8mK;j0Snj(s=I!lo_3~XWC*D8jrux4q;Kb4i ztM3G^E3D^<|7-l@Tiyp9VTShK(M4e^j+8XJPcPz2U-H*5^_$O>&$^r|eOT8wtdsci zw>@dzinY!Yp8S?nJ3ohO|0UHm&pNF)T@v|Y6WbbkFp+^_r?ah3)NamRDbtqby|PQn z&V5+!(*dTV%w>vRqy1M`F{CxxXi?{46ZI(&Ms_JUCM#E-XxkJ+=NR@UtLn7<|OGLzpouM=h zhKAXvcRh$(HSN9>xKLbRu>1Gym#en@7k{jKY=gG#ZiNl8tgBz2lAX1nd3)iXsx#-} z*FLk{_fw4Fz`83IAtfQtvhL5z@^LPo62^A@_Ed=m)rEyK_Wrd}(}|n2{PB9z+^(ac zW$gb2XV$I%`}Mh4Z~i>@)qH}N`KO;1Zolw@FRpcx*UVHKrO!_H19^|!@Bdp9=i{zp z?z=TA^HGLP{S~2=+Eu-|UoM@W?5?fW#n|!wfbWV|%Ql@*-n_o`AafQI152%p8B6Qu zXwV7I5}Cye}h-{ze~}WxG8fAS(3JhBsGMtxEaz*SG$=&S#EW8iuv+UML&hT`+t9*|)p) z-}LuUpL0JY%KlKv^aX*U{;OZ_GJEy^()r1o6$O)axxUXb`#iPgcuCB}`qocy=WL(s z>;E~dXv^kV$Je#IJ-0l)J@V1vHM{+6PHoZocql}Ig;A)J#nvk1#Mgaa=b6RGw25r3 z=Th6Q+dW^6|MJuc8H_8dXy|@2Q*zX zaqe5~lxE8n6uLE5({JsCZ7srlZmT~gR0>=;XHxU*+4|*1O`U=q1=~)4-M7>HKV$Io zibvZkH-FGD6J_&NS@$NoOZ)dUC#8u8j2AG^+HcJ_cUO6nPCx&Zf8PyC>OTKDUXw9- zcTk$~e3ysH%Xn}7PO`f9<|dE$&faemrq{iEe$sgJ<5_of((Ac?UHSayngXa;TkLU9 z(%`@sg;j6$*6W-$isCcs6ZY?$(Y2%}vXjMGXj{82GsBd3|2^k@KfnBM_zWqT){UR1 zE%v=G_u-VpYCR67d2##)`)1Dlcy)vS0<+m-Uqeq7-cXQOvrg62`?i+1fJy839cR7= zf1d(Q=piX0C#{*!6-g!;uluF;lBXaz;+Rd_mkm0nH7=$~soXDZT+n^AZ}-L@8#ajt z$^YXolzduNy*lZi)uNzumMy$44!0e?h?aEhsbWa~uIGN?S?&cXmLv0ji++Co{pc3X zwQ-fTRhmyLCZ)}BRX2<6zohkgdGCVC1TKat%hI`Ho&?!km0)Jw>c?NMU7pQy_HWJG z#R@9Vt7P-1GVvRw&5f!!#UOfL%-6-m<*3iZJ;njoa%}$82lv?N|9!b@&0>}3ei<(_ z=am1y74-PR1ozct3=D5<+82b0C7&slmpt(>cC+y=-y2OY@AHb<_uVtz7;q&$H~jKu z7IC4V+-H|n-icl23cq}Nw)PBLb%Dgiwp%(KBj>M3J3MPkSenAs<#SGdExc-Iy>7#j zk~(PtK|#Uh#zhOJwKvbOtJJ@jHLv<~d0MpJ?0;7o891LmV`OORmslTH{ayC&p>KCL zKeY*FH~*TnaK-tmw||a&**SOH@@q9xTLOKmx4g=IRg&&=m5X8dyQuvBbawOfo&0)f z<>gA3b)Nt7-?dZa`th&FZZF$y&E9YSXgg@M)KEf$OY5tl@5IXNds*F2Z`}~kF`pfF zX`0Yob?MLQatD^GAKWo1V~^IomFZ7y-rqi#S!?kAe^#lC#V$?#|L>m^$7f!)_piv^U$-G5{DN!p z;Z19p=QF5Zo;%}k`J;K-4$TYxvp)Z|!|VH8e(RMV{U3b0<8UP7OW5b5^Jn&)w+cVj zw6S($>C^Y%WUR!-+!}dOuKU3Z!|dK)$EN?tyjbL7+uiOsyN6x9?)ag7whMEn{GFQ8 zn$2(W)qqd**2a(C3=NkS%fH%v^Lgd{KdI9N>)sj(2?cLR49K5jRm-ROGKzzZH|g;I zgUinQyx03smtMATg@0?dKhOKzn(s||PnDj1dEZ_9Tu;$=al4+W9RIo8V_l73k19IY zz0YxRF28(NvR_U6!ED14ZOt4lv41;w0ylCRya*B~wq?n7yK*o#wS0$muKl4)i(DlQ zYkzew+#&dn!KzvAm3#Vz;-c6&7fPI`#+-YnQl8anD8Jo|t>)F?8F$yS`^ngMKAB>| zQN=4H7kgy?YPW=ED|UL+R!N&XnLp^WYk+1l4+akJ^Bk`44#?%ocKkmZsl3nfI?KDi zJ78-8=A2rtz3tGQjn|Wm-u?-|2#UXY$En^%~G_Sr~lDUE6eKD&~|QFa;ivT(@!Hk zo=?YK-Vk9paDF*!Vb--Z{m}VD*`b2cvrxHv^PCwjBY_I0t&U2FwD zI;y_Dx%#x_jJ=EawylflSuK9faqgPNxwG}PuGDkOw$(RFJ&h4u7SwUDAu7FL`OP)X zMaR=-?9t?iuAkHGo$jw}XDI0P5gFWyyC$`09XE|*Yw%`zcT}S}(eITRC9!D)arO9UUDjGFVwO7L~JY zO1^OCsQTHS%kf@QpME^Ozr4~cVB-;M&`j4+6M+dHUC)e}pIs83cOc5#U3hn#kM`Yr z&u%(^`dvr;Cd#U9Nh|Q3!_V(r)W!BbuiO3irgbx?-H-UQd&aj{m*%H4frfEJtzEyJ zb2xp>&*Pj#{XXRl;^*e<=juJz@Z|`*#cy|oY442BP1g_om2_ajEgNA_S8v4)%}wWd zIGl{O^{;Gwpfitk!YS_sznh9*+}gr(o<(chk24H{f`Nv-EM1>+oP;`+tMs^>zwYHO zNI4&NXJ@JGs}>fCCw&Flv654z_V-?6wsSvv$q#CB1sjXTvdx@=69wOcI_9F69Tr%e zQ3LtL#pRkIWDFvSw9c(}Q5d7(#8RP77oX2ZbB+{G?&wmwC#kUL`m)cHul9#%wFW)q znE&bOg^k}8bfW4RRgWK?9R^NR=V03MQnRAyJ=?eZ*j_{VvWEQLJdVl( zJ6=~sJ0I`c{?^*8&hX$iwMElinHr{xcHG#h_a{DVr=+rOhQZcW`Lw^%tPCqm-?8ZZ zz3^je{&LHywjZv(-En={*^XRam)8IFt63U0eBs%j(b2U!kypi4UxH!5zW>ZIr+V2L zEGoV_7M)RJXwdsACc+oW$e@?1uJG{R_70AyjsqvV3;*1TeIc6X5p2Kp#xl2BvA%V@ z3rsmQu9uoCeJk0#^X-JVe=oMY)l&&#J*T3wc;4hgIsu;UC*n?;oaKFI^T9GrwW2cm0uDx{emrPsJ7`2`5arb#Uzx{Z-fVI^MnKKeXbX z?7~MkSU}?@M-m>mvNAX6i3PQ)GdO4!H^nVyV~{BER}7wFz{aWiOX-!5_>^z*Jt}(- zF8cF)yXD$N)@k=T+b^xu3%c@LVe`IJlj5z%KOQOB@w2{n#|Oz}=cYYVY}=O85W0NP zraRvo;x-p#eooO)*~!DkA{*B8zHuRU)8;jcw=JHg_+eVm%U00+l*4G8+?3SDV z^xNLqdc-LsOmoHhFGznYohg38?Ei`+fKKC8IvfqczyKsx^W`7LiwESEj%upnjfLW_cT zW|JciN77|KF)bl(_t_4m^X4# z2No|reR0og{+a&+J>Q;fTB-hH%T<9DRX&Gae$dF+x^hRgoy6Ump70f0!SjtPnIg9@ zcxAF3l%}>l4ZZrczKs8c78_IQ?jH9SQ#qDoeev+`JNj~h>5GVCoD2e$HLSOKZ4c>d zEjlD1&`{3S(Y19^Rl35%b2>Xh=WsC;XxZ|-I=(+@ifZt*rtV_dI~AM6RoBKWtf`wV z^_A0Nhgox+z=vZ?jCUC9-gneWJl))3?#Xn;i6;t7>{!pn_%wR_UzY#iMYD!YwOF@q z|J4^S@}_6rT`q3t-nr{@@9#IpT(8{ipYGth^r-2hb2*%*sLD_d-K^qIx2@~PZ% za(dwQklGmEYff6_$5-yqxMD7UXiDpr8+QwIFEUFtGpNsJ?5Now)pzO4V;{eBSv_jO zy|PEV{(e))sSQ`Lk7O0UuV}!*G{x_0f$1|5t(8Xc_U134yAlHij9+)^hP- zC0ncRtP{0&EV*$$U{%SXA-5U79?VbyHs5Ym@b*(~)5K z!-1XIn#Uae%!z8=b$)LA$^PpHHlNC7 z^_9FWT)Zaja`vKtU-Grq z=R5vr-}h@%Tl^=@{`{5~SC|~`UgTB?w_KF+(kS3=Ts}|Vvh&S~i#JF8UL7hnH<)3< zsl6LA{Fpy}7Y#ml`%eEl?d2)2<}fw5_fAZc{V{I7NENyw;b-WB7eNm0cowIySZ#gM`^r7?CeZMrWyDJ3$n#Cmg_HxYH-G$CAGx%iU z&Zg}<)%f?wmtNO}mU{KSqS|2S1D>q_#4?K|c#dK@ks zsCYcl$>r#s*A_k+%e}7E%Ue5#E#BBZ_w1&3%U=du^PBe8?EmV;Us{w43i6qo6&4&` zX3g<3*zwHggn0fRrT17nU7DCTuFQCyR{7Qb=Rr-K=%3>M?8?{@%ileYj8VE|B9*Z< z>cy6*7iaFx`ctzz#k54_Kw#%=$-~Bnf=fSyN7}1>mP`(jn>+EBj)r?_{L4P4yAy}zWB>*oJ3 zHf9$dwk{t7g{j&P16S!}UCnPR|5e)}_IoZA8hbabKRv_{#GM+ zT9clwk$dIbr$&XxmYOs(?3Ou}_Uw1+>S9g?@YM9jhasI;_}FTr`mB#x^0F1}hWg`r z!h_K3U+dT9&FZaNoc6G&WYy6s(O0Dh9tb`*C@fGf+@_-hYHRVZeY$H|C762iRC#Wp z@s%H6ES7NbyQm&N;H}uYz`tq!Vr#i&uP;;_6rJ;9joY$KO3vzsmR~Iw0FBV_#J2k% z{_x#uVb#)21?6QeK?_?h`Ef3dnYKLPfTN!4s<;!WwkHw{p5#chSGpTV<~KB(q}y6n z&lJhDe7WG&WQD2L=_LW71}}o+D-9;xw>q0W_o=Bw#nsZemC{*%_SQ0Qdw-+V)=_cC zXA|AaMfc6yAKz(IwXBP4?})qeKkT2Vkl@pxqx{Pql_nlo(0g=B_C|(=mJk0QChpoO zZ1MHKR@9o$uOFl)9bfr#O~9Lfm0I_*?sEJ~^*Vg_Dr+B~)`^Lep4YC*%Ad7W)iGUQ z`QkIL)R#9hFoc*%7ZsWN&VT&%Pw29*@6tEUv-{gPW7_IJ+^*KoxBGpLO0Nu^@hVEG z*zNYc#)vP+`C8mp7yfk-Nb7sU`n#vSOaAX??OVOPPp5MRDjrB^=+Kz{=8kpZjO~Rp zTu+od&e56v{0+D$bTsEb9hqKNy+Z7=eSc=c);m*T&MBmES+i*1A3U-*vQ?ng5kcH0^h*W#XDDyvOUO(gHty28Z=_b&o!sU7h2fT2+46&G7B_ zviD9GkNsSGdC#@TxV?O(vH#XqE=%^`bwXbV)R1ynzuc=?jhW%nBff-imkkw9%MV>R z753S@%xrIQLTt#Uqo35<>mAmc27WM*cCOX8{T#qQ^Jc``^j&B86~m=%<^7Bv?^>wL zB$$^xW9xRH@a2&zFR;2|GdYK*V?8^iAdhwZ}M8WyOz13yZgA)^m#q$7yBo^ z`mM;Y;M$X!kE+7=Nw?h2oaQ|F%ggTqKhCN$95ehLyzH8mNbVePN=v?<@r0wMTB7R=@q6*YJ2(gN*$8+RpNgg)2Tjje6O6{KA5t32*Eq+fsVvJPpe?{@eYqqWF|& zvU^w{)Bbg4`#i7T+pNBg$9&&x$H^svy;5I}K2x5)!0)p2WSM?$ceBUM$G#Ru<<_J- zpFPm~BKp$8fGvfPDmga#cFtm_fa|`g(+l66Nww+pJ~(69-i`krSRPrPrTD^hNBvXz zp4WL*|J@uOWzuVtFa16be`c=2P)c3bq!rvuv5?|i(Wo)+5 zleFsnDOxSY^6XXDganUcbNHi^KE-dlAEh1sGx6QM$3OP;_TQ}1oN;@<>b_r}W2QYd ze`7D+9`3(kM(Oj=vuYs%;Cgo5+T6FFSFg!txUl^G@ds&NH$IEGrhiuZa+ZjmOazC& z<$6z{y|4bS33_d%`{wYkbFodhtIC#7A&cb`@07w{bWp3kepMRm|CWC1++}aYAB8Wo-u(V;k>_gDWaZ0k?QT9rGoH0Ky7Wl9v)cmi z*!MQq?;qW({o(PZQj4NjN^)+;9n;=($^VzixV}`~?r)MvR^_e8*!M*rv~+&G^_Q`$ zWc;o?-%&sC(CU)PEBV*hAOj9&Kin{V|VGiH&*6{ByVK=jHESGfi;sIq=l7 zXpO;v-^Ji=`cV<+L^yQ*8b0@JW4U_42hW|-EpPYNf#!CV6%9qTzHeG_;X`hTjG-{2 z-MO7w+HVimz4=jUr#H{CafgMeh~Lr&;mehy>P^IXv!-o2F@G}qgw3avC4>s zYH)l%ll^KE8MRG-7uuW|hmdn8jKbiGil~mDrfS*nIu!I>W3&W>V=g^U!5B zyHO?&C%s9ppXf2wqcfuO0&YkyY?z2?xocp{l%{Q#6 z51zAMdVXc2ov7!s0Y*2dBXh%U^CTL1Kyld}9Cl>>igqP~VM;sO; zy=R>vCej_>r~Y{MR`w5Rwwl-YW!WnI)~)iE*-&;PW5F|ro`1?b-F?{`6@FO#`kFm` zTcBPYwSj7nDgHn$(l8Ui#rTQ@qbF9y`@LilG(iu?+?ShPv2P>UIgnu?ic3g&iTLnf3{ZklkJ-WPwtly zDbjqRRX!#Aj{M>9|2#YQO52=fIq>kGn3;v3px{OAV~I|!9!EX}7{-F@BE!^-yMNc-appi)hKN%SD%F->@x_W_WP#(_;tj{Y*FiFPEA-Bg{)TKmG=I`iuF- zh1N4)US2j#KE@NqA{fXx(=1m?yD?6Bk8wc9oNf<+%e|{AqRu|PwW7Z7boPZ~RqFRQ zI@ue}{g&e1__kiwyxMSY%CGGmzLz%!c6O||@sL$4$-tpfXr7@92g9GaQ^G!L#N2wi zW6!H|TC3-umYLm=8GGp@)9wHFF1I;r8Qv4@xMj~e`S!G<{*&7uKR9=`LT2s>HqcUy zBm;+SM`oW@c%n2tGT)%`rOfo_3%7*2c^c}zP~y({e|Pr(hLy!>2d^KlXg{!^^T^a% z?~R4ecF(wZmUl9H$)S65e=iWfam~fW#f69M#m-{}y_>h2CQeYuD2kcqleAjovt-K` z)+!#mxBCxWd7#lVce_mPu5S&~XKN+zXSLZY*CcCf{djfae23VE&EU1}f%iTzK5{zZ zs&_QFcjM$W*Iqtcw_(pF{fu|dckE%AD>pCfl);NdzK-pSeAayn6qvO6tnx%Fg6x zXGQbwQ|}7GZ&h76{3T$W%d@swlN8R#Sc@eleqV6)nZ=am8zn$EaC8i zdlsd?WP&bj72uIN()PdEcYdwPv#)jOX3}#yIyzp6PG%68Ht*r#=2lnen0yBBv|Odo zDNg^tntwQdAn1`XtNmOvhna@w;squd?pY|z;IM2}-}~!*$G_A$Ph7Bdj-iLr_XE4N z^B2T^6`E;xUG;zW%(+p@r%nkduG}Qkmb0&iyLnHcl^H9;htHXen|hA(@Z9@r_Ed0JAR5KRp~M@cD9tWaY=ulR%}px zbbiLIO{_6ON~)vBs`h`FPzbuJ%vOhQ*KL zw!FK*I8RP*g4faw#UEX-ZaZvHRJ+4ffq?-!tiJa4*7o+<+Dn2gL-OiYTq`s=mbbHs z&F)-*c{RJ!rkmfEa@q4l2{#JHpLMx=%=f{|r;Iye*jC1{x}X2F;>wrUFY^SO@~8bf z;s9Flw!(mg<-uIWMM=HoY#kk++RNEqY~^LCNC(MvtoQ-y=RnHQ4iKPdITcx&LmZwk zfCAXm5tJ-LWSSWr1tNrx_P8WTGJJyUIf=9I0lBS%z-lfW*01NcT-~rDVdnk|Z%eBt z-hRF7KE%IVnvUy_HTGt2uzjI$E`DdLlnIY=W`}{wf-&OCqy;1Vi zl!De6t;Rd&Cdib{S@rL(B7H(I*u`px^onQ3*MnISXXp*Cuu`2fLZXxYu)9ddk zo!%p~ll|GdS&TC;af)VNalbl6Iqb8o&1UJx?R(mHh5mW)Y)Mm0W`EGrRg1Fs3*Hcr zn)uX=rIu;i9~)-d+op~2n*293Qvz;SE^xVdD&y)~=9>TR9G7@lH_vlX60FbJiElH? zuIFx2FE79AO5KHTE6Ee4%)>`E{FV6ZC?2Bmmao-^FWoTU)GnLSmCpM3212wvbXzpT?9qB&>P z;}?%VXFOSR=CY;YL@mMUui_!~kCSaKzR>;b`PMM=x^KK|BTbu1`Yi(Gh*AhV$Sg3B6R19?1%p^O!03tS-Gd)&_nh^ z;p~eJj~hAcMBA2>=qAa>AAe-{wr6gIv(~=q_0mdPS*tt$xn40B6ckMTTra=JI3P#) z;B(O@l?B;PZ?CXQS^lH?uwAl2>79a-Od*DyD$k!TIm&wQ@M`HGUZy9jK5CH@z8hD5&U_hn`{ zvs1QTUwc>7l-E%ogvXbO@ucpnw(08wS;+K@vdFMH&R#)HYzSTbId~EIf zu*=-W>+P5sN^aNk@8110GS*(dob6N8eHWMYQtx>#yuKs{oQENmq>Pn>EI12hW=|gXX`LAG6Yy$J0$-&JFR5d zV}rEVie*pB&$L~#IH98~=sus(!@JA*$lKR5t!7llo}boz`T4;K7a7<6y{gsiz`%gK z6(;QTt6fE1N9T(4ODUgiS}~z!Yy8~*x?4C{7!q!r&+mF^Y}_yY!ZP^6S6>$wmz&83 z4*GAdNbP+kaxUjDXTIsGgjY-Kx(^(beQogibl{6Sd(7_0crU2j{x9OobHw;fdyk=h_Rmvg z=Ca;T>}RieCK-7A^dsY)&J8onG8TQ>y8iwC$LU{-zrR{m8|?l@%;gD1`D6t@>=)aJ@{Kts!HVezrX1UT(GqOwtchvb>xLgKjycpN}DgPuMKuL z2akU`yMx9*w-=ep8l2mvyxqKPLnwF<)Fb9w!u#hdK3rpZVch4x?vq>ly!^$ zuu(Z{O5w(+w7Bb=O+}W?S}bI4)c3TiON{Z`wfjGpd++9LtxaWUIJD2mM02~&Dc?)d z4>YDeskpt-J8zYRRYDU)JLkpMcjQwH4kSES z%EElUdvCeuLic`!itA!)Zr4a;?fsY-GINuNnd=?L^OyLJ_3icPDsg`I&3l;+Yiw1@ zvhzrTl&-cRE3Pv(yZ0PEa&Yc~igi(+HqBehxBlnG8?VkVHzas8hNRUw>Zx91=DCcArsx&}-6yk)6T?|wfk zm}9-+NYa{`yz85y3DK@0^d=-}7(% z5?>|LYv29X_ljLM+HJH`E7;)4o74=}P*4M4iY*&+$OE~1yE+!=W*g@Jasi^o{lTkg3m+X%%vRes<10gnx%ITS=Yw*e zdH3GcT^2g;Zk(sIT-Wxv>n}UOqhy%}kUg&Mz)*4(_^=f20)s5QU8{FxMf3EDZ1 zTO?^;B6QiYaqh;qZZ*?>vhJ1o{Hsr}e!at$?1nazrIv+{COtC@OU$S@Um-Fs<{4M&{>a6?o_738^Rd$GhrPp7Cg>5^av~+Q!h(W<-z;Va6z2XAx0yX*f&ZaNg?~RBePsKH$Li+F%gH>~*8Sx(og;dF zdfV5@Rf!k2TQ4}9B(Ew28zoHZD*F2JyWx(=+BKHnO-{d^o@vS@&ZpC|JZ9GVubXBW zx*IG>$ooI-$E)*ej-Q7P6*e^A>~YpFGE+P_foJ6zPKE^qEBan+ejNC>cVR`+Q^%y0 zhnPS2-#sv+P1UG&o#!9%tzO%Ytra<~=u{MHxn^&f<2klA%%&oy(w zi>r^_YcBOCWc-;z%$Ryj@Kr{uXl?mt+c;sLh_!i(QwO8|IgCy!-Pvco|<> z-1XC&;+F8u*z!+Dk9Dm}!h60IAf5W#2ymO+A4TBXvERx)^ zaarGP=g=LjJjZ&qs|`Qx<A$|be4}$AyStnX)YAdalYpE69n^&O6J1<|F{BTaV^K4jn)n1trdfh7zEyMM{gD{FodxPMA--lzr)g zQ0LKfaM)~`c7Hps|7^3~sUEGX>`#DKg1Njo6O0x{do}i~cHm)qF?E86ikQ9S*>r7v zK|w+5ub^Ql(*x|ypkRmeBrj?o*v)w)p&@SNo_n$nVnG)vmc8pl3F$?19>uaG891~$ z<+cAQ=nw#z^b$RF^x~Tex&|bac$EO+s0!rLnx?dV>T{z``ka z1r+!MK|2hV&xhy+t(N_t|9;=$C9B@C_0^}RSEq8zPD#pfN$zA7l@469Vu7KQcg@u! zD<D;%-^Gd|V#Lf<>qw7Qx8<)Oex_$f1p87k9<=gZ(=%ntS z|NP;{cV~9KJyZDX&%4Y?DxRZ`>NEtrNN`5J0#=H@4h zk|(KnUb1?T)%wWP?CI1lUXXoDN-x~xI+~sHN?TN#$K%$cBTAxsKAiab=kd#zd%izZ zKQnWG$JME!CN7gtoI06&VS`{z?R8trFDo8f{{7K>V#DDjDl7ZB7!Bo&m6zCMUs`sz zX6LqP`zpnc*Hv@<*If51>{s1w*<;N9_J<}a7wd3m{bZKpDt*0j{u15Gb1uyB+t0kK z%HHtqvR~HHT&*$=I+>>fH$G4-vwFbp+jwBdWc_Co)8o@0ZVEMVS!8l0Y;(%H<9{CC zn{AQuyN+SauQ!rvZ;J%v!_8+kPFiAjJi+0T*yDdE#W(FyWI9l{zp67_e$PZ` z%v%9PjMr@oc^_WMaqGW1_wB0q%qsn$?GpktTr@&+kakR)`UI# zYTPbY^8dXa{#M>-)2x3hPqsKI9@4DTS=Ya9_PQr$Px>COTK44fvbT2<#hC)OCa{Um ztzucs_DxxJj!)kIwH8l~$bbHHsBd@pQKi*0%Wj*>nAhcRlZtSN@|rPai_b6q|5EHS zl}6_OzFKB2p62X%YmP;l!>iZZ78o*DY9^kNZoZXK7~8UNWvu=C75$D`t7kq;x~Mhj z&`pLVDeq2fiWJ{?SI<5nvUbVYf1VF>*44ZUUN_HR%hA^peC z@87G{>960k>hf<%lW#uvs-Nofc-{On-_$bA;ni&!V+GIIGn2WDXKnM}{qkwv+sU`i ziCkQ`q^HH}Z_+tQ`_>OPHdo|b6A!s=zG2Z1<+}QJ77U9fdevFK6cD?%l}9A*=f#D- zjRzX`o`2R_zJJN4braiW72TWtPk{Xk|GAGZlfw({?457^)?8ICWXiwq{cq#mKi_W8 zdElCQFUy0Y@q4c3?Gm3C&*X6Mx_(xvz4wocjOml?KBn)nP1oe*H9b@PUb0VS603vr z)8ljMPM$G4Uj6Bc@+_vthwbr)dib9Q2g@&9x2k9R{N3}N+gT3=pPXH8`0r4-PS2z* zJ8ga(n8vs=|8`Rpo8A8365Fgl$NSd5FZ?62ZqExDzWdeHlbo~5*Boh0x%5lc;o~N8 z&8)9met$A-{qybdg6vBR`OiPRnctsP^?u66`wzCZdTZ+HCf|C*#dp>}d*l1A|8YM5 zWAoV*s!#k3(fJkp;TOC8g8%0Km=5$@Eqycn_9xE2u7`_${$0eC_u~Ph-rb)fL7U5# zt$Or#+IR8nlnghk?$=5(Urxxx*(8Q^|2`@G*LhlPVRW}c#>?n*!;JU48BR!*uub)T zmsfbtFmh#0%w2{9yG6ggnKk#)qra<;eh=R9mX$}!q$6?h@z1w52b=$w_lRa&Vz*X3 znr+vnjdktL3nv_GNHN%;>Z>dDv_JjL*(ufc^FC%(J>>XyH$VPZpX}+n$KTTL@7?ED zW^v_hLc;mk>7TE)#^+B?`*`}e;g<#V3km`ywl$)Jr`_eQxI$e74(KeDch#Hjkoutt>B#4e?gS+OKvdCR$GC$(|>*HSMT! z$~Sw#hTqe|3U4)>5&K?zNxQouAAEga_s8lOzAFrd3d(iwCLS_2uw{-dzbB&Qh5JOlUtzqQ}}znmWPX?MQa(&(Ro1@liz-u`fxac1th z+IM=cxpCg-?(F+nfAiP2$1;7oryjgNy^3+hkG=Ol{;{3DF?5-|;-oD<{}*LFUcvs4 zX^!Cfmi?SMUEz}!f8_d=^`Q8H=L4<>MhS_lAJ5sj%uH~7!TR3okAJJmEni;C_J`qz z?FTLc{uMp*&ACF3GPi^`%x>UrSSrT9cK+Rd>-p;UW}W_YKE3F?eEs47a|$eO^S-?v z^K+f{)82af6H_MhCtkSD_o%TvtfXp>GWVt1wYH|^>!1B!dis9O=enzhX8!p%t9wSp zi+^u6oaJB>5t}f3vaef}l;*>}{dMZ|xAHQmuD^Tr(O3TZ?@|o$*6BpxBi=EGKA^*$LmfMzful4LM6wPtbxmK3&@$2_F&KCD}efX&yZm_Gs!hKE+-}XCy zHRMI7N54?XG)^^N*qa!+CuzUczjFHr1rMYT1Sm{iP`ZHS2g8r@8hMT=hII>fPE~OF zP_m!#1pB+F?$;K=5uO)jeF*q-C80AmB7U+b{-2$Hy0Cfn{6*?z zt2Og`CS8u(z9_sT4(u?w_yE#Zw?keCOwui#-hjHXE+d}}r?p!%dh4uHtE65@E6dK)uYMuowoF~P+jYmo?gX~^zpk$T zbpDdmq|5FF_a-Dfo44eOVvOl7`Hc}h@&Byv9k&lVK3DZ%6ytF@>pkwD^UrYFKmU8w zd*;6v|357bRySIuu~)NT#_w~*F_q5}du%?m>tq*fWc0ihBf;}!+kKUgC;SZOUb?y3 zbSC5+ko&m*b)&TKz5j8CzU{rcr?1-j#(s5Oj~jN&y0;`gC{mD=@Vj87l?A%m10q>Iakm+nm)uKikD^&(oBPtLxMDthV%? zbg<#p#;yh4JS_hI&PSjAtIxvK@X=(uh{J`m8E0oX8)w!@-Ji&@Aua1uqr*M6UH4x^ zP1~aMAn^hJ0g>+RYknV}zyJJY3;T|LuTI}O^Yi}1HIDZ)Z{@9-c{_2Jc=%TNx!0!e zzqn=YH0yPlzt27DTK4w#vYO3zYgbSIzxQ(X?f>c4tlz&rS$y#St?T>P4}24UcVFr5 zhtBDY8$Nwrt+}#4=v!UEojDK1%Pf;G{c>kJnX~_TVvJ>}l)SI??w3#X-|aucr0L1V zoTa=`{7^;2>z#8hHCjJ*JR-ODUi4?{I}Cg7A1$=&SkC<8AKRY$b6Vckmu)XfG`zTL zXU-ivnZiFSW6I8conxL`xBc5n&Du>njpm!LJ6!VJKmN|U*Gu33U7KlLK3jSAV$pMN!OV!(%~OB z^M`$S8gIv(aKy9yYu3Mhi&wv%DXjcd%e_QJl4nKlkyfYvR}YilGp&i7{oE>rL7dWFQvRPxr^Vs6cEz906KX27@+&=bd=C6n)O|SP~zQeNh?8@-c z8D-C0?H4Ou+V$YrkH@TMgDc(^hZb`mh_gJ)-DTKv|m zvmWQ|o18yi?sU!i@tD2-;onnLL7U1RO(|Q(wKt>4;K8${*=Zjiol(fJ`0*vscGmvz zxpg+b-)=N^=GwGl_l`|xf0wSF{aH!3JRjzX`{(Dqn&w$8X;U=`6`2>zL)(?UtsND`m>&e!lCzXfAj6~a*JgfDy`11p7*CEW64vCCT~8TYZ5!&?@F+7e&}bP|J}R#%+iA* z399S=we8nkuQp}MIo0Ur-!lI7@t%M7HF9(0rcJXnlhr?8_);Djdf7oI=zJ4@{L@8? z|1Z~k`z`(NH6~5Z*__M8-uh0?tkbgVo%dcS*l$CgBag+TZ`b*Di2n%xbLab|P1@(B zZ1=vn5&iM{{uc@JMViFA{x<&IusR_BcGEJkURSN1Ul&c@QSvI-clFb<)ajkU6%QJv zB_?0qWPN^CrkV3Y9s<1g-0#Q$%+`#ZC?@7=P_E4mMQYRjJgE4PlHoOpxr`RDuM{~QuOJ^R1rGGIslNZiB)Cu3 zdw-9}q@YWZ``+g1_62YGtRLl*U3KtZ^R4~wm+;hWj{a=QWBKNY-1*xDx5Dmx|5o#_ z@VNfWk`woOBw|3lyaF#P)@HX2_gjQ_{M+|@#_vn>w{=Y7r#CmoXwUhSsH(6o3?=W ztHoJ$L6_H-@S3l=_vo`ySkzI_;Dq+q*EMh2Brb{yzPi79>8E{H*H|oWSE+SY znQJy@FZjh5%~lmGcJRym^+F}BJH>X)dS}11zr;9}?;yj&q^5Un?U(Po&2af+WwzyX zqv`%&=ZtyZwit`9{p2<2*Mei_-koM?ldl}rFS%LE8(kM?vv1Y$zN@>gs)Wg^?lN-v zySwy?-}+^L)_F;3D~H_M)AXucTk^-R1f%WWX0F^;Gwsv8GP$$HFVC>$EvfcDx1UAN z=ZE#u?k~^R{M@P#QJ#>x`nvg+_o_Mfy$r+_7zZ{LGG)so1Wvqid`SyuYr`%#ulw)+ zy!79)WX`Ki5-kdIHa$)AeER;C`HhXvGd)|{mrW=vG5filCt-DJbl``(TNLWWuLgbU zJ$hx@ZKnmg^L3f`{!8^YXnmH-(p|q-lAo)OsZ70M(R{xPtr?mJyY}WExxD75pOn{z zitzL@4~uhaKh_#I=2pG5`_3N6_>cPvv%Olz!W-;2x)NlZl{YZ`kf;#)p|vkxv0#>~ ztMqhZj+NV64=EP0t8AdrW z8(nHL&873Gf{nt=D|auQw6bi!^FBo&Yxz>Ejop6k$wIfhg;(b$6K*CC|kq4xHH&Zm4Gh2)CQpHFUD`+Q@O?9s}-(e+kSRua-`c**Z&b{kQD*+)c0cuUqzLqSmW>`3njoTOv$cf)Zzd++b(h zzvumu@``oGB16~g+dFBN`%K7qCEA0DJ!`gT&``JI|g$G5JXxAnyNgFAa-?(9#k zn|6#tw9V6cLu#E{dU)`+*`XnOBixthcucM<5c`{_p^zLA)IW9V*PnZ4yDSR1yKz=m z=G7~;5&lbbxI7gnv8hbnR4f&#{%k_Imztt{>i3+R$5*v1=BF|JG~Unr_Vy*}?w9JomcIixYAm4=5g1x|BU9DkSSa`=;s3#Bx`8 zsH+>kStZi7ewFf+d1pFKt@V7BAoFq3qMaerk9q7Zk?7s8uXgK(XX;)Xn=<#*g``G-QM0`Ze85s0pXG{=@$=8e4-jMEBR}$j(oV!(KF}j_XMkn8vMEVXWGUeYzMqZ+&@WWdC_-g|OiBm+p!Oe)ZgPxw!rKGowFK|Lwh`^lVY`tqq4*Vl&^d zo>PmMk!^5r%K}A(sSh}RUT=KNk#=imb3*FFcYTHyii)`$Gj5#zKEuVp`ojFi$qliO z7=69|R88W%CUm1Qq4e2ojwl-*7L~6j+g%KU&T)k`_gpm#vfBOkR2nF+U0U#Hg0*UE zggE~ct$pElLUwxJGVE?V&!3!fRKqQ_Kjp{k<`a_QE;7CAr*3}HAty6s&LsXHq6`c& zm7Xq+AsZ6pz6yrPY?yQ5NFC2?4sj6vlmu!k%4u&h=4w>h6 z+|Ag^tg3kn*Om#heE!RuUN;Gkzq%DJ&B(-0^%18k`?6o=70h9)}N3%T=y?2zg zcx9xda^)d~ZFS4u=5Uox*IV-ASe4VynLS$4cV1q8|6&r?Gu~LS5WCHnCHB>5Xue!K zPs7wL!sdf^)~TlVjZOOQlkBZl9)A7$ob8tHRhM4GxYbP zo1Wx_wU5_j-zy6*dFb^lH&iU<`UD#{J*}*&{FgUcujus%==K^FeDpB-9Q`c)$^NBh z?w5wnu1(fnJu`euON5Bi%ac5DJ47X2b-(w9UJbU{Fyq&%hzmhmidZr^gXeBLaen<% z!$+GJP5WtCZ29@SR=%I{GI?b?ot%$6hK9aL^S+lvM&3SOop>$g)#~QQe5)m{KHA5) zs9Sr+{&%y|I2ilC#kGG-tY6szSRF=90xpvuv{k^I^d)MM6|7sj=pOSSbnz1PR@~nSrb|f7>^L9>UdEM-~XP(JLv$dqPYhNS zsYKWB3|-H{RNHy5L1pFjX690zub2KT5Q@6(aPzqC;>H`7idH>}ZTY0{_x4l7RDaX= z^J}w?7q_X%-;Md%yC-U^<2&vA>Dx^A1f(6Zz2a^*chjtUbHX?7I=1z;xvAoO=~?er zetP)q@sl~13){a>**wd>yUo6Ak3!%*zueUY3wx%eDwQACyQK1@(trBYt$+7y7HV3o zdOzAVd8_WVy+?1hsCY`N8f2`>x#_z$_1>5BYUvk>w7eFD{M|Bb(ehclxvt)qneUq6 zp?A|YmOb>U_UzAQn>RfEvhdHDXXh7Ro%}(LyXaQ*P4kWOe=ZB*TeR`p`ogofxnFDS z-`#ZU`s)?*Z+n!aPKl`9FhNrG%$tzVX&)k=lz)m8No8Dmu+nQ)!=19rOG~HDcZdr6 z{&~;x)2D9L-D~~+B(U;|R)^zZ1H)e!g4(ZZ<&$X*}N!--yYag4amF&&1^$zGhuTXk-eoJ}yrL>Ug z-JxdX^_;0&Yi`9AUpDg6Tb;3;JG|V!n^m&-`Y)?nHEDNGoZmXLX*0wfC*4Ji{ybEf zHgEr=U#W&kTLoAB5A*wa|CAz&=I+!<#d&gn&z(4O?5Nzo`pY^KRC2QpI>x{En^IK8 z*rE`2+2Q7L$F;`WwkW+&nj*63#S^)C;TIX!w7%HW_3V>{#=__`JwameQv57V6Mi0M zV%uxdvsNtc?1@li$wo&@-Pyv*uBUz}LGrEVHXe^xU%TdQ(R;d7f2%~xC!-VcGmo6w8K_ks=l;;% zXytxYJLj|8e(FANd#|&?gWvS*g-a3A%BGwD{uP@4q3zOjqYE8w+jsm~zjsk(LH4Wu z+0S>!)w)$)R=E8oo!T3^xUf@*8OvR|DV?{jV@n* z5+faAqO8vr9J6kZafQsR!eqbg{S$9|uReR=aoOh`Yj(abUtzF0)M46$b#tro)@-Uf z{i`o3^zf$i$D;S1sC4;duKN%sVxI2sUo-RVaW_t54%Jg$KXkIf^Q)fjR6li!twPG- zRou)c{<23tWS&h{mwKoF`S_Ithe=n$n~v?%`uW0X(jkG>D;7WcthFlah=OY8qWseT z6N|omJS)qv>fOs7`L2(f&x+o7k{q=zSHN!$!?L+o^OWDOy;o#pE4B2?g{8jQ-74H)ue^M4?plz(en!=%`1-?}#EN&CKdp{cK3ykVze~R9k9M@( z$8#^P$AoJ9*SPh|Ir(bjRcQlZp{73GnEJj@lMRnPw63YMezAPMiP3CD^KEasCf%@I zos@YyZPKyn;ekcg4IcpA(fgdi0#QV|B_;YuO^b$vt(_X*vOquFP0kzgktSHN(@tSFTr3 zw>Q9i@vKn$_;ZI2a!3A+5hzrt)$LY%&#Q1}m3Pg4<=OM+P4|m%e49Q|LI2tHz`Cxar?VOIn8cyo%Lzaq4sKrP3KaF` zOyVoNZWx{g|#zL)p%Pdjk@@5)=dwH|(6dVE=( z&Wt%{CjD+YRevGI z4Hs?Jj@VLrTK)UV$y^derBCqsOA=Pd}A**~G{hw1Wo%a+Egsye@8MK7LT64~BnzC;Z{7uJ&u?$KMp6?1}d|x?6D3(W^Rt!+uvzu5plSUcWW?JI3*}-BWtL z>%UUglpc>odZtHaWtJ`C)jck`rvJ=;S+BYb$*29-1vL97P7zm2J$^;*^t}K-p@;tx zgUbBWA3xyPv~RL+)_=ceH_m$|zYurU{C(1E)x4Dp3oAu79a{2kmfyF?$}iTc6`$sp zJx=)4H9hEKj_gG@54oE)XK!BTQ+m84E9`!t<5%xelQa1$QPRp&rn-FU2)V>}LgD!t z8>8~O9G7|5rbkAuKd+=alQBQv_1fIkD=W6l+Qt96b4`bkGPu8!zhrW05ntukZkB|I%iwcuq32V;A_o#bg1)4dx&6 z58@L3|ENwq(CV=Dri$mJCB5gTHS+3;{wS>ZeYHa2L-d2|ZNDpvd~Ue<@p@51 z-~q=2b#v!r^L^m?V7NgjgW*%-+s4BUvbS$8XS6WfH<$ko>ly|*mVewKN6!B*eNeJM zW8OFI2Z2r3`cGBNn)@h|%X-JY@&@rn{YTf?Cy4LgUih(^yR@j5^}yV<>(=kNy0crS z2)u%0_N>p1Gg)HW?AW}bLuW}ho_;L)^jaA6`=kH&GRE9mbxDT#9rL^enKQqrX>;sS z-|J?O_i#HM6N8Nw*XZ>;Q&*jYXnfEg(t-Z8|?MxTDNN2FId&BI8|67Xl zQ$N;ke$;s8>K2)B!Mv&NrypORZm~J0^3d0S$2 zo)?b3{8n*GnseR>Vg8hNsu?$L@c$@g&wQ6%+GnrI!gTnt=)d-c{m1*aE<5^2_|~== zTlVeKZm<w)~ow;~Vt58Pu3p1F*9H^ctrm06eFA5DGsP3!j7kNfqz*aZ@s^lYZ9E~(V}cTXh2 zfju)#EoVJT+L7&-A2%L8_wj8=lb+9YhMONvHaAY-z{6%H zxpS@7$If-i8L|}?3zOz#R2=&Ds^zVF<~ym9nAOD-0yyo}_Q@(r?7lEj{^GX#|2~A( z&%b{3tLnPIPX&j*`Y!vsGW75PO<5M}wR7*E`-p9#dQHvOGNpvKrK{%1-#A(M-Q&i;9g|CxuRXd0 zT9;HN8Y~^PrrRKg)j;-#NQBpgstXe9|CEQE^vy{;@$Si;PF*%_YtQTV9^Ag>|LF2= zkI5DDJN;i3TUq9pv47vP?fUauk&r~T z`d+^Gb!o|F6|*lFV2+NMwPEi34Sx*}>R4>7NG)gDz;7_)foFw9+(f&5&8I%zvg7T~ zX{vlITnmmp-Ka+gZY&nswp=Zw&0kF-<93w0F55~I`}@<(4oOD3(`)Lg3q z4#UW9!81$uFRMP6xJ9OA_Kn=-i`AdY`fi_T;eDZc_Jh6szBlSNPA=)ZJojDZ#EGCa zTQ`KRFzjdA*Yn?2;78nQlTPC&YqFk8$TR5+Z_!w@aar`)iJbEv#lNWd@V5QHOcw2b zey@-Iwx9RRasU4p4}M8;?6MH_uWmZ(Hc91VLPBwnp=< z^_>4g5iSO936cjF#a?HaoN==@EzHJO?d)cbP{B3le#hBxbPDi9%@eafcIrpnUdslH z_Ge%Dvl_h{`X4bmKSK$BqWETHRuN#g(ZalKyYDb@dqxYfh)t3F|`q;IM8(I%c zm0e=ZU~yatlJYE1D?~iWX4xRTL0(t_ZY7b@Y5a{KVbmREwIr&B)riQ9>Ofda*YTu1a7=3l-et0jL!&O&8g zILOggv!Z$+>(y8`&fvE7$gNXwR&+b=Hd`=A-c;RW`Q`Tw>+Z$Rew?%B{=)!`Co@3n z)mE;DteXQh>?WyTt~EOeUa^LAg&R#YAltcQpW;oO2`VdVi=B$kuz*+BeKp+}vF5bN z!hnv88!x6!TXJ^V-4;;wVW*WLIU~glv_`MiNaBTG@CuNqZZ}v~1=RLKU7d%^?U$Y@ zgRIQFdzSO8p)fd1u3SHov@vffcdJuRU$5C=mE58?;PryIjKC6JX7YMgYMw#*1xu44 zzHp3P8}f$h=p-|--JG7_5&^Mr5SO`^(ll9)?3(pIVv~)m?gzJA{nyE5-|fpQ^cDtm6nHVlUvsQ3+0_@D_wY9d?{t^eFv zcHMd51*`wrx?(FI{M>){SmkoxwE1_-QW6~HUamaZGCBC<+4twSS-(BF;JH_qB>zyEws!L94NYI)=Te2vbj{#C-zH_xoU-dF0P2+x|;NA6Evnt$);#{2UQ z)pxDlwKaeLTfWDQ%jF-Qm}n^`;Q6Z8K|#bwV#1PpVTS)X)!vjUJ! zu`8yNY=7`*iQT{Z_O(T^2Vc4VN)^l6Y_X~5Qysj5W+x=X*2`;&*&KP1>z7>Vd?Cv4 z-IMO07hg`6*!^09P4tR)h9Q%PA@^=o||No-=YkA3?Y-6#NPrhlk7v5XDo_WHYjlAop)f~BT zCxl_1_0w#hiVxlld9e`(cOKrfdr#jf*X@&ybzVq)*&00m`RDz0tB>{{{>8?;{jK4I z&uO~M3H#&s9_i8Md-LO;)M<}_Ot5x($`jT z`=2aZ_I7pNo#n^hfBwaPde*l8-yi+8+Q0t^)4J+MQioRF?2+4SeLHl2lH{h#UMd^Km={dc$D7(L|ZvrH3O?t5qZ%e~$1 z&k8^PDVlV7ds5-gJ$}qR8IQT#p7W&DX@d%DZgejZNY zwdst|IW~j)-h;#TJ-L>?e#Pdp|o}m`nBJjZdq}nA_$>r87L3dwhA(*HZJ(PtH`n zUB?smi~(=Cj0(zUTizD|1l+dRDBeSE~lRM-7`>tiLWKD>Q1L9)lS;?JG- z=so6d?_@G8Nqc{2?PIpwD|<90C! zNd^j@d!KBOuUVVBiob24P zz*o5_%b6l0R8~&E;p;J}%Jc53mrq3HoMKJfEJ_vfr|PAAf3tOV;0o*5iY)K{u4Vs| zJC7vw%>8AUKW96$y#L+lhW1s>0UE8(Pig%K+rQK<2qSd!bY!1~OQz?n){JeXs zzwgV*XMavHKX*vUbMKJ^he=fzHkl^F@|gZxx2{_1c+KL< zg_{a)UGTd+|L5~gh7i49%>L(otJlW`u^#wXK4;Ux_aA4?Rx`=9uf3LN^Y7&k)LYY z%qQb<^0c?->ATZEg|08%x$j`rc{P#jC$kQ_6@D!~*mc_T*sMrmf>^jbGEZF>@Pie?oI9GH_P^y@BS5g@8{8VcYhT| ztWRL*KrCmu;%9gg1?;LXMxtC^Lc0XJGn0%RuyX*#I&1^%?fV-=npVXV-kgVgTp*hz)Y;D^6 zIalI1*{-ellO^{3?thNU>3dGT@!ywl^3&9i>!t#Jo{QrjGPw2JYqUKsdt~E%yQ$7) zl1Yu=Qel#c=Uzb`i-rhLBYZKW?L>TY6I4Zl`fQ-qIJjl#3G$LBRT|@*4FUqj(x7JW dzUTiLnbm(7d@Xo3gMop8!PC{xWt~$(69B(}`&|G4 literal 0 HcmV?d00001 diff --git a/docs/reference/gio/menu-example.png b/docs/reference/gio/menu-example.png new file mode 100644 index 0000000000000000000000000000000000000000..91aeccfd95394d7557b1a45d579e6838586f0a05 GIT binary patch literal 31470 zcmeAS@N?(olHy`uVBq!ia0y~yU|h(+z!=2A#=yW3y)L1Yfq{XsILO_JVcj{ImkbOH zY)RhkE({C|Dh&T$v+g>_z`(#+;1OBOz`%C|gc+x5^GP!>FtC?+`ns~;X66&u7cKpz zbcca~L9)a(qQp5rH#aq}gu%HeHL)Z$MWH;iBtya7(>EZzkx!g~L4m>3#WAGf)|VSx()LEhf|)e89q#*&-En zfbZG3gT$638`)m6DQj=f9beWaZ`QAv~e2txZj- zH!Sl*bW?$eVP-~#$#fSJLs?f96~0e9ELuu3lP+Dj&~o{P^%oA5R$o{l z^?%vE?lghPYD&Dkz78LSCS)Dk*c|FPtD{eWQ&xx3^|wgjoXas=mvnkKFMcc>P|Trr z>-oY7lhhU|dpMmfl*!QhdF1onoi0l}J)9ROPY5XH(3toB&m+>VDieiZVv__%^2X`9$7!$>IcxrwXC!!8d~N4r@wq9Qm= zm)ax=2Iy?+{3EBYnW=Q?!UdKkNfZ3ermHZv&c1Z0vqPgrRJ(WLGYemMh z-IRJ-Y+LT_W3lCTui7{D9I}_@zIbf*qLrJU<*_dmY!~Wsbud}jvS{X+MHBtseg~QQ z_3QO`|Ew&nAg@1l`|G5oq}-j)hjZ{8c364%e%kIkdB48A^}c?{Nv{6S$F1deORpa= zFikn0aXG~0w(8Uf@(Yyd}e>Wy&Vkr#sr(+@!;uytYm&F<30%xn`&P!^ciaO$9D4GE%xOPQJQaQtxL3 zsQheU_jQnxa^Ed9Y1LMq2*0F$=A%lBGSYTNygrthS|Z`0ac}Fxj)fgP79ARMCV*0f z%v+T!ho0@|DASwv$#BK{Nx2sa1cM#_oc@vFWX0p9Atvamyfk8RX!1mVTUAibef&aI zQB!nL>68i0%gz=|WD${5@^lyW)t($+!*b|-yCz~|-`mhwi_AX`Mm`Ha|I-L`GF`pm#x~jO{|mJio^bU$?EJ%Nxv${F zV-K~s3s=mq5D6$gQ@BiRp&85nw6uRuS>vi-D~E;7-m>=SWRXzq`H#!}Z4TStkM&he zJD#=VcFDc%Y@C`YJq-dpayBy(o!ckPnilrEJ}XM4#Sv!{~({;Bz4KPKLMZdiLP^oyUsR{azE zf10Y@|E;$>)#&juo0GcDlMIqVMVAHyEfkr-CwzFqk^2X8DusfA*q+xWJSvb%xczna zqQ-P1BZ0{N&OeQOl z4wF7vdxl`oH@5K~zcPw`Q~H}Te}BW>X{~dsn4Zhcc5PC=r?w-v{FMvOqDk9&Wp!0l zCe4}Cu{iciX#YIEtpZG!O(uFB<6%6VbZ(C2jcvUGO^nRHj1wH{TLe5bXBwyT{c~7w z(PGJ@hbm7xoLP@h+dCB#ThHK=yvko+ZFHg z&wqMYKKo|mE7wPAyU%MJ>pz!pdiv*xT`PHvSF0bNTPtgCyIz0gqMq~1{x;dK-{fiY z((&KNZbubKMzcLN=KE{%^;f-E{^#+(dpb4GEbU_UPTi||^~co7U;gat+53ZSo#jSt z&V?-+@57$$`(k4(zAm+VYWJHn4BL9vuPNF6ZvCIHmz-i2>CNXkeEj?WUDHqgzt?ld zs=0kx{P6=V%r&3dcmFueCBO5z-_wuTyEcAYYX2c*jZIcwodnaL+ZEsS&wqG0Ywa7o zk4fDwMb$hBZ;q_q`R0e-*7MS$Ws=#?_MG9C*Gak?H+zfTU(2VDWr7>G z=E7qf8gil{-kh#NL2E7j+MBtT@I09FI9QPBTg^Al=(P#+s?6)p?fJ{)Dt^vtv3j27 z#HrOcUYAaoGpXUjlnq~Rf1hDj%V+(^F?d3kiD2YWo&Q<7(cP;#G=vkwH>clyzUSK| zYn>YbJ^oQ4?_$sInJ)KmXQ*7x)KiA)U!Al(f36Z0;bvxH|MBkj-W$_==YLezESSFW z(dw-^cf%Wxn-zNKvu~?E{>J|Qy!zY^3QL_%28sQt=z+^{DkJiOgWbm~+w*7W~VPVd%!a*zMV>EE+&?tEZ5FZ$iVQ?n23z0Rj>eX#Lj zgq*3leaeSfqW5dgZ~GhiV`^t+=%(z$Noi+)sP3P?yS<@j;`d93`Tx&5#jIa@?pCav zkWjAIHvQ*w)$30ipFZ7Oxc&1c>3t2E$%@w2?Q7n=x%EA6^P{q`GP9dEEk9nJEU^4y zf$ZsusR6;4LrkI?TV^fpdK6{tr@ioSqf6I0i@`}(ER8Mc-RO8?n-+^gxm`eg29`%hK>-!)lr8N<>S z^|wF&`M!34k#l)tz*C*L4brJnDSURVN-RnD&1*KtJ3g)2cXM69m$W~Ha|NdP7F?vwfufnmwdUf!uO2{|Kbc-uHE~2ChEz-X)Al`Ke(p-f1Vq+f3f{C!T7oNKRr5c z@qf|joi9Fl#+3Y2$*U@4j$5j*kX`)GAFf|g8~)zEyyO4Mqaml5)b1L0HhP-b?VtS5 z_etRAPm8Aozgk!MKDDmiPtWOR#J^Y8IolSMFHb#r-RA#0znt9@vgcLI{lDiU+xfd! z_?wOFDzine$~tgfoe&VbY|EA}CdcL!FgbDPoK_OxDDwbuUP`|7jl17rsdsPd<1H)K z^3HfX>y|%<)cg%nm#zK0I`5r$cj3XiLap?&-}?V=#hlt>`FiI+HvRv?Wzx9urK*RJWdMV8zE9BITjZPm}w?ck-$V-v0K5jXy7o?a#ZC(2GpcO}wEt4a}lmdJgSbmMSDp0>RMN|Fd%giOaWLf^0y?gh(;Puq|20x$j zPKoGR7k=mL)W1R-_sHe!?h!Sf->2OF=sdsR#P&-?7vJ}M6ggMftD9=SVc)GKC+>a_ zWZE6R@obpJwomJ=)joDHOyQZO@;z@^%p8wZn{Ms3UEx_gC(~#{{r?L!N+;jk+#Kjt zc(3yLRk`1yZ15fTNk!sieZe^CSk1r->2p0Ki{~my<)+H&Fd`ZJ9b9T`1<{3 z&a?#r9UWC7Z})0UbjWhb$WQTJD4?=Tl}Xg&G#jH=iqW4d`#Qe9zG3v8d*7+(-f+!b z|1(VH%8D`W-uKp1)5DAZsNjaz(=DtUQlnWymK={haVF^h`djz!uB&d^9~aeO{H5Q3 zha=>1I9H15ZS!}lbIrfi?w>em71O1uORAo7pFO>};*+!KnQ)nP6J8!XrqA1>QJH_+ zuIX%+*y8h+GnvBYUSB-ZaE8zF#t&MzKL7e`>UE;z$h#J{&q^<}EYi=(thvzjdvp5v zXKyy2=bOrWHA6=5?Hu3B>uxqJ3%}f#Dtalpe)|NWMS_vHZse`*eY++rqxjCl&CAky zcQhED%>J<`iPQhT@RE=xbL=J_)STq7)%EDNxgpw|w&x$d>OQZqyNEM>?}zwp63$Dp?zcHYOc^1UF#h?dh)IA?hhW+Y0pPTkLO-YCU>c10ex1JqnO0WF2x+vvYKwIZio#=1jazEqc zm(82!d$dpO(~AY47KhCf=fP_`YsV-ILFv(kqTkHlKF- z+)Ljs&VS6iHM~!$``%))>aaYQcr33@=k%ke)8pMVUH$UXKUqCjY)Lpj&vws`N8Jox zUfVM)zbyHFgY%k=3X26MQr(ksr^z^{G;1Og|vJ zz5LEJ@%m#w^;@@#a`Nna+;X9iZYVW_#UaTwBYOBF7`Z&sg5`G zR+Z%^z2&$5pqdg;aVBAxI_H#`r+>`<+hW{h^-y8roi`;yvb?;!tM&!1`6uHX`q}R8 z7rVbaT&)a~B#R#wSb5slS$Dk*y=cHU$>Q1Z%QL<`4wjfOz3buXW7@2qbGamoV*G=8 z7s%>QE0+m!J0rU4Q2K#i=5Y^RYt23)Tz4q6d6MUwQpW4OUQQ?8SAIOY^vAE5lYe`k z25#AMe4@Om$Ga&`2a*+ob{o8z#9r~|7o!SGO@!N&J>|;`e*9{$c+nPYxlBR!^0&vE z6*RZ=vubkg;IZl{pL4jxL`q0l$kWH8=lA~%MJGyh-2D?V#__T|Y86Ry?}zDYsCg&fR>*DYJLEAK;;X6wU( z$q&k|eK!d#ZXzdq7f&&9HQ zi+1ZvuLEyOS}tijy*q7ZGtZ&8ASjr@reydpO_bP*T0s^YayL^Tl@>@-jC%McLWhoAtco z%x|teWm9Yfn5G>06!v)Qt#bE0yLQcbzwdXSUu2|i-TKP-nuD_CcM7E+u+{`N*?*Db zsO4{I66Gp$SrM74SR=dZgFtSN$76#Tj~9LAnl)*C@62akW?V>o=PhyQSahW1Ww!M> z_Vcpp&%AEk^s#!?hia#fl3e+zs`qXki%F=~TDeBnn~U#PI2%Lg!R!5Z&rV*ws!2_K z=7AN`dW-hoJ`^6h{X;>@oUe~MJl6C4_`ve$cBQ$5Z|dV@)iTkk|2|~1Tncwxy8hcT z0ptEzGvy~%W=nX)o61EWo%o%7I{RB*zvaS*4YHp9+tPG&xuv%9ks^-^r(SSO4%oA5 zmFD}MRnIJX`50C=)y93O(oG2pKNeG^UEX_|F&54|X-^CY*1IY2Um?kB6V)#YBacBi};Z zKL%OPin^7&^ZU{39$x;(QaPBWGRFEHnlN?h(Q|XHPZsPp>=B#ac>9J$>7HqGD&`1p zxqK)w%xTd~eG9qD)n^N3MGi5X4)$z4*L7=AzJyS|tLxmKfs5rhEBD5Ab$5IEc^-UQ zwtY$Fx{acOe6E6-mogKDtfs`V`|e4}op<4aMOWf&v)J8bs=B(pXJ?xSM+IGy^3s_0 zeYV-*t-?ZCIg7MR^8X3wP4|AjukBbM&*@Dbo}P&>E-ch7>lf7yJ91U-;*RA8v)0_2 zCe-y*RlIwR1OLCwj0~5?DMI`2-%tA3zDC#g?F22U%=0Ecw-^cu6?)vOsFu4WvwY#g zi&7R6s#oT0^M5Rmu;l_b`(E|kZEbG16&F6+5-61$!D;Gh(YyD_FD;K-2RWOhq@<+Q zu5O!kxhzvgQK;*=tEsEW$8%2CELe2@Cz@~G_ha7M-QJn}_ZA&8crj`2vDW2Zk|XZd z+~vQRk;`N?W1Du^?G@ievzWa+9&;q!+;!LH|G%O(9?3H+0wdohO?J>!t^O|l`OuuF z3s??!eKHZu%*YVRnmEsW@$oIehZa6wTY29&MTR_QouqWvweUTg;g-FH(~A3+e%TvcWo>QlRtK$Hp(jqAN;5NNjt}JA8{AXAh zV{9V$J+V{&U%`{py`YiNg)>&9eYACcd26e7EZ3`c#_hUFg;##YRCry#b=PF-mJPY3 zE|;$^O<)P$w^r$zn3dPfh_GJHQ?Bng#anEhS&QrMEWgQ{vPO4GHQ&j{#}@~`OmVT) zli`t@dfwDo*i)$Ml@Px)f5eTod(IZ$skD7#Cl>BDGZT$$Q>k*IFW9q9lI* zyOp;0+rznu<`&6p!+WB)x7_y05%8EvDx(cV^BhtVv%d8-Jiwz5LmnI?oi#rsJ}bk};-w?f*C(ch544 znNt!Zo@Zg%Y-3!}=i%|Jsjza+49AQ+&l9Eu6icq%`F_tFe!bV8-@D^euDxIX^vgx( zmzT>q9@p74>wo)Es=avOLQjn=F9nzcxJ1`@itq+|Qaj(yWZ1pL_au|NklT zxZgkDbo+jqyTewWU0KgxRYZP0A{z7iNLt(7-$wHLew*jL{j0hE&)-K?w_~r{I&&q@ zk2~>sx!MDXpDNzwIVq=~`JR~<(x5p@X`#eHt_@YYTaB%!=B-QE@2h!W>Vb`xYN^(% zZl+&dF<;75j7Kwe(+qj{(jAx1vbXbo7vSS>KurFm}>7=wM0sT)h&ss z((l02WeR}}OyOBdbEnK-JC*CERBdgZOKjHdszw_6r z{hO{W-uvCe6%x?f;tp4Nc*Yu;N?w@V3{x5dXeB1Kf@2n3gSfpP*VB+Hw+;YZ^eRhA>C0WroFQ=Yd5HneR zTZD&#srgL3L+204+UZDENrgHGai#8%ymj37<@eo@8xC`6Z9K)m&E&`BzBJ&)s-)iQ z$Der}ToI$*XKN>9EbOsHBYmdF;^O--y6IFI&jF|Pb_ zbH1^Hp~<%-waZ&)&kpVV+WCEbg6qcq_wQuA=l^z%*sZ$pt>2n^Z{0*#B*3L_tNg$^O*iak>jvOp%PLB|V?V>oU))&8pghCJjLZp3Ts=YT-AFsuU!fr7K{!LRSsre*}eYqTbnmGm8W*yb<^tBmDc*${k@y=5Hhjv8JHeO&tV z#4G>zON7GK-s|80ZI_mr&OJ6SH{Z=c3ARIC?_jeZuKmWluW#g(_OID-{?X6au z{AO)J7?>#Do9u6&}YKU*u8Ni_6L z5GRk0kJ@3bf9m{(e>Z-Px^n)r#r?`FMVlW6hfTS*^y=n^#nZyoFK@3`Ur>7YT4~1H zOa>`;T~1l6ZqrZJl`P-ylq=2qf9F*1{_1A^u)LJd{MtW?z8U}dwQhMtT&V=xoZ8=! z`?FNF!`oWlU)!+sP}`NqJKyed+V}hM`f^r8 z8Q<5=Ilm?TZ?k`R{-gH%e`lwhJilS>_1-@#~ z;I-)a5BvSIIh>u&dke zZkg_PI^lxs`j7tao<8(;|4^N7_LKSCL-lh0hv(c~drYif)?O8<`*n5w&%2e$JNz}< zY&K0OU-#nDiuM?rpAowjPswGrx_tM;h9%b&75`L*%uQ|znv!?#sP;V{Kb=!g-po_u zWU9Gpx9y$I(x_`Z?{2@j^VB_c=Z*cRyTdi7Y`VEqo8jiW4gVhn9$^n;3z_SZ_0O7L z-<&D=i%6Yuie7)rZ}%{9^$W>o&hGheLYK!!q&>jT#Kh#0{GUEoXRmXc#*7eK}*z&6ZaR|Pu#R_qaag@0bk{7 z2G!g*5}UuYzFeWotNPa9sj@-Kp|FHmX(!Iw7@g&cG>$Y?T9@(T<(Kc4Kc5s9<~|lE z$qoNH#sA616YfGxE<0{^bFeBaq`X-5+x}L);fI^)#XoP~O*j8#mo&X`LHQgZwPk|; zt=G?g{HL{+^Sv<##?RJm?jyNjxae)flkh zP?Ic|k<^@P(f%E-EfO{Wb7X+e@7bAi$>fI+Ovr7T^MC`h4NS!Yhu| z$F~NXJbh%BdP-!;l(SvMx3*+f)p#!Uom!YX>9Wd_i+vsHGC^L;{N_rTuk@K|^pwLU z&{973QZM(n|8sTaC|Oy`!h}>2=YcLT-so zTYJ6n0!P`BMN?~e*S47S1^63ma+1^Gld(APbb9=`TU)bVUR^C-ey=jUxp>~sPu!>0 zJg~L#US9N1f8WEN{pX*&OP*}N!r`t~d-?YHGWJuS5@+Yh>@vQaH?`h3-E;QKEkc(v zm|03TsHEIBv;TS0KVowlZ~47S_3iiTszWBnUfdwqBV##fqOyC@od%hhL%z=&4`=_E zHnf<0)j$4xr|V7?E8!EmRuf;(|JC)#A!65?Br%)H*vHRZ-ZD+!_`*ND(CIzT9nYUU z^9*|X%YQn*I+66eetE&q8~dK9Sr=Me)|9cDsQEr`$u6^7LHBHxJC}Ss|KZscZpn+< zvs<=ouE^fMRy53dJHrtr4PIX-skJeZkJq+jUt9BValhRv+yAZNaS0a}x%$j9>5R_b zE84DnEYEgfWz5!v_v-D!eC?YH%XJq#&($}4fBWa2f?~$`cMG|m+wBzV4{4bGUe0!J zXYnFC-A|u)&)Ac|!T;yCw%FeP0*lRU&fHA*Pfy+IqWCdvm*u-<>Xp?8z4k?0&3^ej z^uw1_;hFpPtSU>k%VhshUnbr^E%vDQ{hY-)-+j)VHTo*#{&vHi?BbZ?ZDz-}7K)1a z@*a(r)IFW_>B-48@%!hg&###jxY+IEkH`I!XU{&(%x@zwxnY*e&*?TcwW_S;H776I zOFOR8On6|tXG9GM>%b$%e|mEAPTB3;DbuGH->>~Xao)VT z3okj}#2$OqW#TqJ&}EZk%tl9vOdiYc7D8TO8;bU~*85+6ex#)X^H(>~t*toE_wXzQP!lefOH32-dE8aB`VVB?o|;n@cYmOr?}b7kM@ zdY(@gQUws-85zGU%!-u&Wk z5AvQYQG4)ZZTdg8z50Rf&U3rVHvAX#<;^t8`hOwW>21dhzH2&x&MxcseByff@@4xz zEvH+ZHU-ZW+U!eAw~N>vefxORjn5xT^8TInYy0yqyvNT}z)j})k*@u3l;7?9$vJ2L zJcsY6^eaC-dzqv0OZ30o;_cbi@BjTWi@U45^?5YA?q{bJ zQ6JYFZ`dMq$-*g1W1CTyoS>+fm|WWx)uK0h|37~G-@0#WfBd->$?k?P`=up~YxUmW zx16Bje5BIv%9NxzMsr^t7XS2s^{|A^KRG+?9ka{rcl0ZIvMHtN^zX6jO}5`TG1>b0 z<>D7d_gr{cw`_hw(u;2^oy+$~trnMx;>_HVpqjHL$gJ&|&e6*=D)pZ(Nx%6tRASlU zZ41TM+4$}ItNP5JZ{|TKKbABJVUt=vspb14o7jchH5+);Y9f41*_Q3-D}Eoi@ZS2y z#A_Pr>^tpuO*aq!vng)QqsHzZp3N0mb=h0Wg}AB?v$l(5pV}AZI;+JbDuVH-()@~J zEz5joU#p3fIqjqFv#7F|`|yz*uSV0tJ_FgWT!}yOFLy|4rZqSBRc*2}itGKxu9>=4 zyR0`-&%4{ zxld|Ps>>F-WHHNQ#kcAW`pY^!CQmpvQDHt?wB-x06&DXGrnYbeb)ASjH><~lGjof9 z;L(!v*QWX}UVNQV%KUgH(QVIl@>4CN7QV&7GMl|6bgGvvpRslI4`_*=<{Nb)qv5 z`?f1Ad{L@6>!^dXwqoxzwdIE&Y^!>3fKhM%pQ3B)V!hYL?cMSDoVE14l=si<&HEnT zy4f1@zy7>Ya!L85J=Hfh{Nc8X+S|+(J@Gk9YIMZ6gSi^z8rS7EmM8q&;A_rzmowj1 z=+eCfQJk4FlA4iV_<(|!4zJ7VWljwZES0|5rw~dI8bH45(?zepM#q)W}3c6+g z%DJZZzxB@BB)r^s?xBUkGe5m^TP5niTAUm!edE;qKK~^TmQ_wUy{qxXBXfUM&BsZ0 z8e0Qzy!rh_aGgw~$E?$xmuI?^y%*m3^K9;q!<${FVX0D=Tn~{_%(&*Ql=;VakL6b< zw=bvE6yNIHyOp2adX;O%&3m)e)K+ITfzsNdB_fO4CDM&|q@9(r`}Jb+t*&2(xb-(= zTvSr?opogG_Iq821)X`UH@}?7Y5lDB#3$ykjL#O095X+&tn8_-wB3Bp?}*_u*KHvo zk3UxY`1H$ZPTP^_m(O<0p7-P}tM<>lmpRMkhabE=-8bdeC#@w}Pofq&acL$AMBR#* z#$%NxGvn}iy?Lj)9?Pel+f=$HdTYaWx!uze=N_8xs%XEz`y_YUhXecfCtdu_Z&-Es z@SNIjC1GLSBECxvuL#^?{4@XV(Z#9ZA1|5T*0^muxp=eB7J;m}o8osDWH$TFJU73O zDYq~CbC<@iOR68g{L{f#{&&|K-)vWsl>k_nP*18#0ojEzD?3}94t_K!H zbC?om&1ia{R?NrV7bQKld*1ZB$89?TlJE8}syn}-{+yxB$7fdWByFZFiMW33;f3_+ zxhcV^QispkbwB?7{DHuQ#qSf2C0)7y$U0Z1-=x6f_Rx)4j|Hk!yu-?;W z_y0BDJl(xf$^T8c+TqPUJr~3tc)Bh(wAtAcs{K7lQ?y>Hx_7C6SD5|UxO*3~k7Wv7 z%80ggdbOwZk*u&3*4p|<)r3O_N>VQ*AK4jWU8&`NKIXuy@9Pv(FFOBu^>^=$jgub4 z9?L&J`^aTc@lVhFuWkD5zj#xIEwXvw7?7PmANbXSz+7QJ=c|G{=>HZxdfn z%5C|5k<(p>_3*jJ$9|`M_@sV%#_!KLV)nnavTYKRJ@5bTPhDCXUTJzy0ZYyQmYJ zrrtODzjwdE&sX<1oRT>yYJcjmV$2i%Q|(*x4bzX7mA$|1Khr-c?Hi~yzDf zp58rVy?ggYFu7f z{g2D+-Hn6GmKIlh-h9`hnqTq0>Z>zpsq%&2&-#DZ|MYd_=cnCw3eT39iQGN4{@9X- zZ$$j1OmFdVX6jpjn&#dX6Q@pWTg_$ee}<)V#fA+A`?!U=XB7B_m+kv&U_ZCQNV%=| z$rt(mjX!Uie|p}3KdtD$3(v!4|NZ5kpPP99^XiLxHQ!7+KU4p`!UU6P?s4;vZJdAS z#KyUwUs`@iihEIFf7##Qunc=rjJ9ma?r)Lvb~}E29=!X)$_El^{|=vB8|Nt4+m01GfJC?dQ4PJ-f^Q zF4<#JqerKDuax_|mJS0~^O#-ki))=*m;~p$-AJ!6a6Tv~HfP}jF4po0j}Ec4Gc!J3 z*m^x?t!;GDmp@CUY%NyNIelnbE>k1JwA6>+e`g;)7rT4slS$r-o;_~nx4W^X+FP^o z#lrSiD^*lggHBdG(^TwPkm+|tl5?qU_I7FUHs;F=Q;tkqnC;xh=ycP=M`r8k7e{u8 zwN4U>)@pie!Q`xw!@2CRi%U%SWWB>CS=<{p>E`hG2+j#!x@eBDzf|+bmgSL)O$~~l z`F#3p^|)kL!R}a#SiL!X?0(CIFPjuv$Q&#RG)`48X;l!?|NA=i-Hyk7?2P$654gGi z1#q-9iHf}mm>}rbS}XK4crj;&_}j7t9gBF+m|bO_W0o8BIkm85rk?~`+T^6jgc*V7 zgxHp4nrP&?*<4o=XzNsd+2xuaqU9T_0;`e1E8S>q3H$2dMS0Ef}!G z(~18?mQ3!e`5kX%Oh9d>MNF%Hubs8EY)+foZ{7c2ZJni8OM}}d9Tl&tS~66Z6ozOi z?(N#9rr2xd;AMJh`L$?|S6$05UOZiQIJNp!{VN+##ix~}k6;~M>{=hBM{6AWWE zZ{@nAvZV0HiO$2DHm_=PtA5$zs&{ws#g7Y~b8c<+;@}OxxK43lEXYH8?Q`| zQ@^URO0O!l2-lm+HThg9pCw;tR@ZN&Ax35d; z{f=W{-WOJ_`0KnoV|%KRQWAH2TF5@l;AJK|KgOyo^PRoyxlHC3M^%x#mhPZf;SSvs zwQFVg#iTcDg*J<8&a^7cy0gS6_0*KZe^j2Z7I_+%Qx4Z*!j-*)Z>Vw(Vo($ zreIt!cQYnl{phjc;jTh(hhtmfqHocwt<-i{8yEcWaO+#csVs5lE5rF7KTs(sWE5RmzK$79Z$QzyuaY-38zajesj*LY^t7r;%t82;dtp((bs8r&$kHfJyB#` zsP^o_|1G;`?lo>$G^PB!2WBH{afs;aw0oz29{;Lv`KgNGcKPM^KH1!#*0OZ<$zrFE z^S{Zww<%&>{QJqIDKlIzN`5!2p6$PS=QWM5M&EW7&T0omZjk$5= zTv$Q^RBwJYmkhsjY*R`MZ;RGU>VFaq_&w)z98n6hHKuR{v9N|LhyQ z?l0Ib@jdweMo&(6ch~fNH{EW&n>lCp(i^}2sP_D;FMj#$^8U{kKTWOq`YZO!-#=o0 z`~Q`0`ze~RaVf~n^}oFTMO5mp*SYKVaam-{zW4qypS!o;ki4)q;q-OJn+d9Kt&}cx ztyt_Z`|&OJ+%>Bk5?!ung)O(OfBwYpe9PTzh5CqZY@O{AYh!m!^qrc?WBpsF@BRE{ zXNUfM&63@XiVde)eX2hMU#kCQxc=`q6(e89FUbckOg?BJ5W=o}YIm39{+TBlc-Wg< zR{WaOF88O2vA^#4WAkqZavA=1SNxe7dgkZF`7`!D4yv2Bd&SG*sy3lpf8FGMKb`r- z%TzE^{d4zj_YW_0^EdDM6|`%~>?-BPYcD#kmL2L)Py!Dj1xs?q@7Xf-?ITIySN)tb zHA~)4Jh1Rx(i4q22V%u-kCh5nZ!Gu{Imhl_$+?*og6VuG53;g+(|LNES+i$n0>{f` zj&B7*oHtli?ZL9= zH?(GQ-@AF>b$VKoTTK28zBjy$YUd4IG!+Dvt=@Mwilb$c$6c{)N}Q%8$1ZYfl*qg= zTxb@@*}0}-?Y(Nb$|H6rbkgyRAe( z;%im2H}f(xgf3--I%OH3{rv9#dp3QGJEuO`iHgEeerf5 zO!CjiA3P>&ePc@rUw+*->Gb!CPj<5?rSb&Vl?xs9k3Y5K{=S2Irb_=vd|Gqw*X_$S zI}Xe5=Jb+0eC2-s@?Te1@AxrK{71!0E3-ARhtiGzA9?%#J-^PnDJv?@U37hSVtS?I z#=YC`9diM7(^V91T{vRPes_KCwC8yNe|}!kE77uO>-=9({Q64ZjKWhK%8FADe0sj4 z_RvS37gxI(m)|`+oq5@ZZ{6V+u4*!f@6D^4-Ky{7w6~W3x$O1%jmr8@_RW<3Xr8sW z_|oULNS(^ZW<~pJW@sPhTlC*>dBM%U#y79-l)vfM*zsDXcU!wrp71_|jmJ z$*F^PV{=!oFuW=0l;~|B>*&sy8hvAig;TTM*Lv+Gy00~@6nS_y|Jyr->zVu6%!kii zj`=sgK6E0Aqs8FW#FXIYF1_(LBg*a?XKmq0J2%I(G*tBD$&)Io>J#To@kvTz;^gey zaaS)!Pn@rv`Lcu2AFHHb$PM*C zJJVTjE@f?z4vy)KwUJXb$-TAZ+380ePpexV9!Na$Za>H2oC2Fa+d*SC5r6M99X6Rg z<&l%bjI=MCl^*9;#M%^^7uiJpIdo)Uw(slGGb{El&U$Nh->Mo^q>BB#Qqw;}{Yp#q zv^d`A#eb*QM{Zx8wZzkppQlvf#k5tt!u(%D`Y+ACl_?WC;o<7GmftDvceA}g^+|+5Zf)U+HdOf&3{sl?g(>t$k!|VZA0{SN zHL??U&5Lsq7G1uevZU~bR&0;**W;~AoL(6!_V&feFX<}q>sZ@hq6q3aojfJ6CROpP z@ceR6v*!JjtAYZFmqkoWKuxC7B`XZiW(Kz$yBPRQdAt6_Rm&eco)^yIX9)>rJREjm z-AqHn>}xu61EplAG<4hu40U}w2b{lNaz(CgmZ~})Tk){9DruEl`{6Z_n-}FgU2xKU z@&vcls~1=myL@5w$-Z{x(uEf@vOHSP`iJtqYFoDC8~@$byu&P49Qa#>CzknKc=2F@ zX&)K$7Hj`tu-jKc3^8ojVmnZLSS<$=n* zis)B%x#l~HHtl$}#81THR{X8(G(izjmB1bO{<;N6_)gE7VxrdL zqZsRPP4DL6@YHs*g+Z=1_0`R5A1r=)bdIIU?0uD<3m%+)?>)h2)0?c+`-}+z^{3SX z-#^U~%Bo)?Y^S{Eppe>@V>2ck;NX12_O?~P@vZEq8`c}PPSJPyd`Z~sj_BuIzjj+~ zzf+qvFZAfvfXxRSl2p}$r^KARzSTwfMaTq?T_GIo99MsQWBxd`bys`F`nQ{ptN%>6 zS$9rmmhb&PDh$uoS_*u#S>@>Nz4-2`1sS311C8gZE!=kAgSU7}nWzcDc=QMcgq9rj&3=N^C2X%v{d)oo=7iMT_s0n5YWvQRi2x2{X%TUqP`|Pq6 zk?XuyaYWbNSaomHwczz`o*GMpQof&g)|1zDHT&Dg!kH?j=5q~eV`sE&|0c!R(Nl8l zhjzrSRZXqSW-n|ulDvNZy!7eSD<^%On&5pm{diYwjl~-7bStll)I!sF8}8;LYipnU zwpOmI&vR+_<-@ARB_ai@yx`;J+TX2QQD*TjdPdNhf_=-}A} zb&_*z1B|j=O{eBotUsJJ|LmOn??n$k&eeQ1sVAhXGP|oe)%$90@TFCy+5xAwg`WOd zcRKHst(XuyXXe}!x-v%|IL3NhS^SKBb;}mZb%$p>S+sINRkD+=&Y>7hABpLg7Km^% z{xc8`|1mH5REhDH*^@Wk`5lL>R@^_&+LTbn3*9+pg5+WJx<|if-%jpYzL0J5v0_(-}FFd#zb)ckf(zFY?$vhay|ySw%Z6 z*R^-QI$QlCY4!XDCM~`P{w2kA{U$}*WfRo%`d+_VlJr?_-yK1l}W1x(8}UrKU3;QDYy$gZ8MBHw1-o;-c^9<%%JS0qK85BVjkvUp0;y;n&& zlDE{ow<&dN@mufvHzB`F<#O^3PM)(~2e;UUOnaB=pJ_TR$bs8$MyQ$BjFJVKJK3%n z%ekytup-N2a)7nL@vFLt_X{?yvQOB0;Y^XEgVu&sGj=bTlcc?-Kg&we&ZgZdGnrNA z)J2fd#1M@0BdF1eic-A-R_{~B5Sn_JBpA}2Wdgo>t+oxjFo!iHEGmMJ zc{$HKVY&S7d+u%b)%$7!CpBC@d`g#*O;l}Cl$OMdN9jj{^skgipZa&Q0mBNn8!WXcw;)+p7Sn=jQj-mhr;_O?Yiq~Gdk z$wGlwucm$q+>^(7`uf`iOSBr4ExZ5J9hSVLF1?*`g_c>(55CpL$BVC>IA`HJ{pYs2 zBX8En_RK6W`nit5`uVw(g;Ga9THcP_U8%oxo{yWqP4BwA*F{la3EgFpR@9{sA)Qc}7nwwwR!S(uI0S5YOD|-Ec)MR+`Ws>qeRrCMl3nN#LtC{g=QK54?7niYQa#?1waa*0 zmqB3b*+?$=az&G{)SrK*+)$fq?CVmfP_fqF#Hlicme6WnjcHZMenw}E4UFzh+tZ)R z{BD7Ed2n%PO2ztn!ACFE&b83zH>(MDZC%^c8}y-<_5J&=fjN>-QfEv2e!IYuulbCO zIN#~RcJq}Q`kA+RmaSrBUlSn3bIIuJt@Mq1oT49dEInWM@YGqpVSajZcYj$Becf*d ztH6!pvrJW0_$;~~|4Mr(!gR^qcvX`A{I&o39@!^fRCUsqKR$k^jGC4Ptz3(bP z9iQ}f(vmqPey?99yq^_R7Rj~Lre?F|fhBd3U-a*tURC58VwpWS^Twa zPm1={+jDQP)SS+?a%Jb2cRCT9H?`P?NryV^nm$qj+Rx=GJFc zEt7kibk2NLo$^z}@@%GSaFJ(eTWN;P(J4RXq?DgMBDqhh?nT_G=rfG#m*jlB{U^OJ zW%q++SCW-CalZ`T(Uosk-~H$flU4aS<^3D1D`&pDrnc}y=c+D?@PG>{SNH_%o-BTq z`|U2*GYiq9E}}hx=1i8~&!d(CvS)RXMW#==-z2lCPp9fcK7M+JvD8m<>Fn~4 zoAf6OcUu+u`A=qHyq6_^yKG93?(JtLvlSShPM-cU?dr55ySR<~r`H94Go5X6YSvk) zv)6LXTOX=euGT&|m+Qs7_Yr+Jzl#3QbHccG1JiWz5Q_c5ZwW z?zO1k!qX?6b0)mcviPUX!lZupxSzuI6!YC>ZlNeZD^X)%{{qM}%Nw0t1-LosM<*wqRyHSj0Ywn#qc6Cvl@U|-3ug5z1 z-sn8r8+$a7H@qj-{Wb%S;*5$KyPq>TYqoFg>7Vxg=%$nm8J!or;j7!6?)RtU`zsVI zTlUyZ@WXA6aJnc!JbcLASrT zYRe5&yf-br;V-JT^XJStff*YrJw=xqnXD69e09nzjyvrJnI#%OgQT~2t}Nt9IM! zwl@_`Jo?~VCr7vvGkeO1ho^q(_*%_dbWU&2?(oeebK83qk570i&@j1Y-OUXpy0g7M zznGo*;O^e8r_!qfR|N}iTOq^7_wLNLqwyc67OODtDpg|SPyOv>u=|^;zTtF7=g&9) zovjhu;cl=Yo$q8?!>dhu-`vQ&{CJ1sl4`RJMU#EY>hxY}>V0^V{yUD}Eh{bie6i6X z4|kJAb+7&|_gryz#uFC_LCG1*E*|oFA@I{%qU7b=vnP+wv|z}eI$eI++XtWD9{g$Z z_N|>1d;iqgrz18-UX}Jesn@-}Xn>#~saHdxI-? z{nhRUR`#QUsR<4tF7Bn#aD&Mn)}=ghhK4aG7F2GS_3hKG=&dDex)(lc z$XfOOG(M-ay*@lPEJ$F2%0eG;-<)-w9qOA-Em^c`#j3Vdt@;yo2Isa$&HDMdP3(65 z=Z7VdU$6gHo^wc?wW?g--8E&_HqmC^)zzJo{{6f+@B9bP&5~xCao1zY=SwsnKbwBi zLZ*K9w_4F4%VJGY2@>h2?En2a{%Yrd;Rol9kl5<;r zecpQV%;`u4rQeqM%TlHJU+pwgKDlE4{~JNC&-p#A)H@#-bg#X8&aV#@Z91**MEYYL zisl7u>+%S_x}hONRY$?s`MPO||BuDL4bBS-wOrO#{Qc%bnE$WNvg0$=mL;B;J$0{& zm48RYN)MGOg`WzACpIn1%-Gep?DdOX?CXznA2@9~`>C(+CP(LOpU-uu$Z0Rr(yO`s zV9rwICvQ((ddB^IoyAORz355)<eK!T0vzYf#kdk@ur13>nl){$p+L*OKS@hV%5}3R8v6FTyI(Ka zW2bMoo4Sh{VX3R&o994h9YyDPL@s|2|Vc!knp(<=52ucx?6dxc>3y9*H)=iQW-ftClUwwvy{_UvS>tKtd&@Md`fp zVPlc*mXF$a4`^hBRDm)jGv*qrDe;~za1@AL3RFGU201GdO}vr zDpP`(gg8?xxDL&0QA&1_>t{b~@^PkZY&I9ys%5T06Q(zuch`{MDL*Rd_Prt?YS}4q zmfMAQi)Ckib>I~7A{?rAr+B^M*`OZaz1`uXs*+a@8ar1TDS_SADl&TV<4)Kz{i;7sns0Jgg5 zEo%xUGR}wyi*T~_mb_v2_C>_RWe-2Ld}!Nqx0U1KMupS+{J4vfmQS$b{Q5_sYR~O- zRt|r;RjauA_uM%0YS#Ue($hodZ{+-Vym=1OB$X+?vEr*%B}Im9@7Tqg@;#j_D-gC{1nKdT7wjxg3m&+RmZFw+5$dyH9NwCwo+ux?< zF7CcL^Be2@DLFHgV+sU)=AYi;>LfX@t%_yI7p=QyzP!$tFO>49edk=6ww^^rNa&KT zVztz!_(QSBY>%%^oKdtUOo}J=s`g`((=wE>^1CEOafp5{b~Eexob z?QzyAhV9wm$faVpU)_JcbuX`s^-+6D+_e*8v za{jcdqTsCdljlzh|LqKxu-hRLU{SH8bNcIhDaY^qU9+P`@VK>T-&VHW+huKQHJ(4+ z_W60Pu1xVdsfATD;%qxI8->^0yy&=l=9;6S0ixBXCNJxrJmW}+$`nP&fPaJ%?@tik_KoX}9N7!IO`HQ=2VU zCkf2X{{G>{eDlv&S5LoqEAfKp%h|X8_v<-b{wx`P<5ahAn9uzQaTCt(sJZcf+x#-+ z%F?(mrnkC(**#iOctrVX;Z2=IFXRjNxI9slp4dNOrI69t4LpmCm1iuIjNB2}X<2D{ z&(LN|Kw|XY-%p-DHLQPD;q}=x?%p36?fP%RI+s)49a>uRug%&b{~8OQoaMRf-QNut z6|uaRd3S{AkMG(&cc-47;ibRcB5}TVF z`{r(WlWeb|)5J2Im5I&baVUjU*mW8KWt_% z_~0SDly%qI(`O#JIBU1B_L^xD@qF!f=NS$UA279PGiFIKwfJQGThMxacl2oi^;><9 zwWSYTIcT+hI}4}l_jK3YkJn7u_Oru-<9fbWkZgGxx2M3ShZUhp&$+)^m94$;+QHyS zRSi3@=;?Vglv3}Vdy@L!-ZWHIfahz6?v+!kdsSnCW_lmo?Q0ShcTVo%QH!c6d)F%N z^11No^Gdn+Gc88?KdVA!C6qKs@(6CYvLQsL*}=f&fLE%tr&C@>3yb56@H@v07ORK5 zUq8_`z2(*}9k!_=g&#bG7i+N_S09}8PH%_CbG-P+mWKm9@9?S%39%?{PD!~LRdo7V&~a&Dt7~Znc~=DDZhcfs59N9E+5AppYUGui zD!$X3X6!D|)Xv)@92#2r^6T~))#ozoEZ!Y2nG*QB-#qw!;E64(Y^2sOefqn0Pnk|j zV&kK)ffMsT`o(g;H=8{}Y{7FQ9r+Bt`Sa7G!~|p8zQ6TOo!uWI+L^2U4O^Dy=vl3mu-7?wd?Jl-)emP!}HwU8Gg(X zjAi?7A3fvQ9I@)a#=E*EQi*|)jSR<`v<|mF38+{!SGeumi;v6_@0b3*vnQiU*+?#B z*%setb%FtRc6s>wIvF*tRN%Ndxvk3k#NVF>Cmd}QRtt}>lJoz!wvD;H-?03bMH{~y z!-0dxlJ|VMHM^v=wD9Gz+wt9IR- zls~z$g(-H9>5>Vj)A$~&6z8859#W;H)U|zvtlmkFw2NXaihqNO&XwQTdoN(p`it$e zc4xfe2r@0Ph@WFJ>k@yL`owqny^`fEJ@1J%jKd|$Bdy}7f zzVVvfPS+QIXX?c7oAdSc_02jNA97-acm6!8uDmGZn((B_p{$N4rid9-P5m`v!fQPj zi{%OnKYWeO-+NRvJm%o8($^d;yk>7Rk4_K25iWRA=T?(K%60RC)2~(<91e3-`z-(M z{c`~xww3GGKYz7){j*N>c?-0E$eHGEe{@>+MR&)f(&L>iERHAUwDrH!bf{KeSn-^b zbGi6swS@@=9owMcMqp9C-eRwLiBx>Kqp{IAE$)^2NNbZC>;3q_V&)F)1oUr9AvNj|M%;k(#O^>?#*dY>Z-{L zTBOV2^la(89ZzrSUH(2}+R3h;OKUz&p6?Q<%3XV7%eHSKr7TR1?_9Rz-Zp!;?{{9< zx|oxy+)@%21q!UJAB8W<&;O-dU%Ozp!9iVF%gX^@wyA=0@7qaTv0wO1e5Z0&{boFC zc28I|AjD07-w&nxf8Uk={P%tT`9@~;3#Pq){`|4Xo?Up!(_?DCqd?0)vHs7uHr=^A z@xp!=R*}8;_EZ{chp$_*Xi*ct-H(R8zCIUMWpz_E6_6Ewl@7hSTB`oV{-Q~WzpJ!a z&V&2^|K4A@X3dia2b)XE%8vb>v&70zpyiFoq|FA79{kHPg*aFYc$&9nUpFdxa$0Zb`#s>_uqv%Sazj1T{GeB zKi+))`DDYTlM_x%Py{XaTob*$@3>rbPjvp?sim*41;)hmtb6^V#!gF1i=)*kPspqE z7|X;73LGytPAGP3nHSvlYg)^$UAr|5{~sqiin6T zc>VY8k+}(XHzn4DRnB4lUo6SI<&EIO4-XID+*PWrs;c_uZGQdZi|+DI*X@4y=*{Ny z&(>@{w`jwL4c3A`YwWhi&be}@&`3>%<52s1`O~k?IbFQ{QO(fT)uEkF_R+`V^2--4 zY)m~pt?<0<_k#1b-#66!ERvFvs`zrzJu^SQ{N}E?Yt6$aJpTOPV~hU1NnFcf%k=x- z=e<3gb6xk(+fPbG;G;I{+95m zDE3?NEQ_Ki9K5`|XXaW@|MaP->7c^(_G@8HY`7?i+pvs1id36`JH67pf{`rmF{vT%^tAG6Y?r+P|kkF+YH%^>3O>EWb z)tcJc%J%m1hYfyw+rIzoWPiJpOFSoAl)MPg+FdLy>@}+moNag4yorCh`>F8EZR$6- z_4f9LgoLQ9ty{ffg~z>$D92gfZ4aM+_gnd_W%17&J8ZTva{v7Gye;7S?Egvq_BPud zum4|f6A^wabi3|CpWpx!USCELQQzwqOJ&dAo5ilc(~3C$FHvD#sACCFRcB1 z`OQ0njZtw=+_lS%{`6h_^J`h^nK>qtyZ7(wa^Gh(BfS2Xaa`W!UiIETM&Iw(3WmDc z6}8VfuUme0k@Bwjmp?@QsIjw=1`pPwH zd@OSN&#G&N9|hG69{ml6wkJ)?_b}z0yKU3!!~389VYJ(G&*s#z+Bx#(bB^Eb|36K; zy)tl0&AFW~)ztQUH`u>2_vogm%BS{n&+bl)fAXxj+auF!w_*2;h&2nfxVj!KED2Gy z%;hyHi(={DbMD(2jY?(*+Bz<=zZ{`{PjU;lUZb?)@yTKtx4mAU!0!qAYAGX-B`UH0sa+a(lPa^=;{ z{za9^lbaSTh)9!P^}|D}^!v^SQ{E-@?|Z}dYadg)ilU>yrDKrSJ-=pcen@Ny2?`2i4#0k$8Qx{%QIDO8fe^ zR`YMKTXkslx0;pLi)|ue*Oq)OoW}0|(?m_gWb@mfwLf-m&rSYry#8XO%}meKsBP<( zPSIc$)aM1o-HZC4NACFTwL16wvtjZvo>{YI-Plo>eCK)otu39`u7#~yz54MIRnUPEZp%)5Y*!F6TX>ud2ZVz-`k5d zxL8?PW6JNA?)i93+UC;<Dm2#zj zys96XXgFnce)NkOe-9l0vHs5->($?j&d<3R!Y6&ob+vSr*B0S_LOXqSeviENzl1IS z&mZGC)=y*B{X1%XCVFS%|DDB3l{a_yP4bfO7IHY&!s6(WuGHn}w8SL2Y29lPaq;5A zyygMX(WifXeQjCu!+_!G)2BW&japy5dS$_MD*atP-vjed6I;(m8?1gl*ek5@IRD|Y znXG%cguX1C{^9cTX`dgT$PT+w(0WIG-s=U-ym!^s9^$S$ztQi)7mx7S zCuivx9vC1Zy7srdrf07G%=s;o_W6LT=IIlCT~&KLJv2?S5Qx6rm|ejHDRTnJ)D29PFpog zFEqMVed^biDo)RP>5c-Iv{WM_zxH^;yADd`E>7vwT0B%)LFvw8c2CtGWzQEpeokJS zOh65%h4+O5_FN6oJ$=Z?cVfUdZx7!11Ek3wM4HiQMp@~ z?jq!M>#rK9$#wS9%g7t&c21k%@uFu!!2GZXQBKaL3-_hE{=C+?%vN|oQdu#`*9BC^ zUz*Vsb4^6(+!hs(m5RknF4yL2U!C@DhjEb8ghLh+LH5;&2AnxB<6WJ8Y>Vw7&qYe= ztGSvcd^9TZc0DpJXZ}nUiyaU5S7tq~V@iLve&&li3NsIc2(+B>cCC%Q_xp>`qZ``U zH+P)x54D(@dRjd=C)(khPvIL~1_mir&>aCb8=IfcyX!i8rt{TH{sn$B>rQc>jGT5- za?MSbtA(78Co6C`?aC3+yQ*fJ?3AckaWU%Nv%6}C)j9-x^WQG^{p#XUx$6JKgYF4i zR{MXN2#VDIrr!!LO<>LRaS|+QGhFt8;r+g=Cyq2af7Eh#z>)vXTtnV`%CcXFw_Urk z=<@@^xR@Z{5uU(|oza^}62%y-5!d3P0glI!A#+@`>u~j!S!|G}{%( zDDP>n`0T*G?B=n?y}cFgy{QfEFR!ME^~^Z4Bk-_fM3773$pkl_nTMY|3cL5;oqO5e zr_XzmeogV}s*zfC+`V6#=hpZAXWDpoC;nm8nHT9<7k{1qdvD6CCl8;z)>^f`=c2KC zU_p|3wUqPAH{V`=u9yI>1oV`;Z%hum+!W??b%xTny+7s7sw&>I3OsVN*!x1$-uYQu z-ld=Ki``TIgGH8cbM%s|ICZrJuJa=dW;peqet#$8^s&Qism9Zd%Y6jpo~lgpcC>We zR-0YPtoe~8Gw)mS)arms!fke23>7V_eFR$g%{eE&lN1i&a_dV!uw7CFX(7- ziA+&j-Z*PTeWLOEC;pG`sB%k2OlS`0{?Pw?{-SF=x(NX$vRBv2o|E_5`BSg`e)ark z6DMna*4!2rQ<&Khdv9{a_PLk-rnLn}R7JnGTdREK^EvJ&g)fUs-fZfeyJyOldFo4^ zgc_uE9NhR=&G{Iwa(Jm=(|-;3sJ%RM4W=zr{rSU2s_UXxa`vmY`zM(<%@o&rwB~`{ zzkP-5?SChlEUh?kGLWN;Eos#ktG=z@?|GhfoW=C5uqnJUFZyp z>U;Be>)PrU8dB$fI4-Z#yR3Qiq}>@waaV9HvbrKk@8vuHOSMl_vP8cg^qFZt_wCl` z%5VJ-PU|lyc_OlGdhWBYc5Q5?=^DXe`i|9!%BHV*pXpgnPh9-0=w0X9E4KUFVzcyI zo6o2HnbIh8_u-9QHDZ_9zrGa;O`g%!0vZwfcw_zD zlq>Zwri8|yoZ29?oZnm8qTAcvntRHNj9w?dpDNGdj5N2soomyiHN_)*#`K5YcE^|R zdhh=7Z}HXeb4!-aPYn8=t+Ax&S&&xRt?zc7+Q+Tp7C%~?bEq=L;^H@DSI_UqrTy(V zkGF$Dc!?=zYyR?;29AM~YC^+fjz!$5pLVG(w(g#{T;BP@yHlNh?G+ApQaD}B-8A83 z=8AAGr)fneil&HM3W%CCA$2!Llfn_6Ew^{SxD-8O0`HO6uTFD>+}V9kXkXCFK4BKc z+|Cu@H@B%Q6#3NFG-=`b9-dcyn`N$_3sK={x-hq^O3iTUcjeh%J>;isKBN zluSQbXTDYUrNSITA+M*O7OE_)(DV>saTG`j2o~{NlxKSSY5KY6mikQ!bAH}bUz)$> zl0rv|UC))tK5if(F`*XzSf`UmQdD>7b2M3a9Z?msT6=uT)F;~%IGPmZY-thd{k@}h z`b0xT#~&KYWmoPL^IP09srR=-R%~HW2v?H=hx*i(J1LVr9L{x1?&N6t5a{FfNsNQ< zi^}otNskIsmrkhj@pNiZI5Iu>{w%i3CLe$QWnp5}IqeiEV&Z%F@y7?Be;OrbGCvei zo#J7Ux7~A69cV!4#m>Yetw{4*QX^%s2dX0`d*Z(r!S@|e5p!m6%z-$fr4 z%o%5LrhqEIhf7+oT)ld9p>uo0?lN6fRaKqnZ9QFGTntiDQY%)jT)1!FJW=hifS8y$ zZSiMLPxx$qHa*&X(&Alr`#+b>U{gH&?ow?H|2!ccMV^8Ybsz03%zW=_tvsfME%BU?Ip`ppg>J~Xg?Wr(qZEd}B?V8oU z{{rm)f63Yz*Yh-gwym%^8sfKq&iggh?S1c-OPb{Uk-Q!f9`xkvgO5)F&8is9?RU<1 zDDS?0Znl4IxBr<{Nej+5tCtHr*5A{;Uxp{?;-O#u{0j9aCZEx2B*@PqMu-Fu^D zyeAKbTg|Gx{;%up**=jJnZ?f<^*1EENhq?lgNgp59J|2d=ZF|$qV=Ev_Jv%kB)shG{hy02-^_xa%g zwO^fo=>Jmm&%1lFPkjE9_UZi&{pUpTq*{13FQ3@6^Zv;`dELjG=D%6|tG)i|RPp-r zwvYcEJNrHNsKMgsA2+}1dq@81m2$iLjbnEF?L&vn`O`1Ua{s)+oPQxRN^@^tj)VQt z!)lS5+cZ5r1X?c7TqPwfy>i70kEp+4fq@4XI=9Q%e>Hk_`TIxTMcjvbli%zJm8nfL z+F$d@cb{dc)ji?&AM&CFpU3Q(bMrC#LhXWUGgh8)cMWaWw)W41|2a#3Xuq!f^ZR+= zD$N5HYCiVzA)>7HkKz}la@+rWD(6=7IJNHM(PE7YBFpY<@A@`t%x#;U7=zlbZJDOZuLg!_GP(llS%+dpmvH_25p6i2h%RZP^Ztu2c7G zIa(}M?n{lfb$h!nLSw-Vy^G%zIwSntZbRn=^|}=m z?A5otW)?rZ`NVbmb#~+QpAt7j?zw+B@%l}kZqm6;8=tt(Uo2wyHre>ZPhVN<{Yp3yLmq$Ki`kb=41I+U8*sEbu{1k2 z9aN~>zyJ58ix(Z;-PtFr`F8F0_q{A(k|Ds$%Nr6JsyZde*_rw2)2AElzwAHvU4QSa z|JB#ZD}VenJtGR&w1nXn;+KK9}BhLHMw}- z@A7%SukjRdtY@hHl)JYz_2rYQx2H?AD~fDvzpu6U-!7CnY3+-;P3J7t=eFFr6tHO# zi#ca2!`E}x@BaurD2=h%mi^ncKgQ(t)~wxOG3ypHZLPNnnx@3@xBvG2noQ)j+Tl^XGPDk+?*TXN0#pYrzP&M>lQAW zQ9E1reN@Ed9Q~;C$v-Toe|q{-{;~J>e+|>$&pCAH{$KOzcNXohJ{8XhyL4*V{wtTa zrN|wv-O{kUM(gpX{*8;@X&kI{{UOp|cJJ0NxoM$dmFM7nWAXC}@qrCyW%i$?<{o`+ zywd0J>bbXGpHShnOm{0#lizOQ(v&hK$7V&en^~qtp-bZZ zf~3%<|9i8(6#9A2KYzSO()h;KY;kGxyp)fRj;_nhxV+4F%eHMnv9YqBcZ6B>buRVI zsrld495HWiiM2-|BTuf_ES4A-e$t#*WpE zC*#`9wWaoj_=kl)TCym`mDBA>!sht)Nhgl)li$5#iv?3qENG^_<;>&>u@0-=b}yZ` zszt)Gec_y0G{-uEqa z*_t3tdCR8abw9_$?25l<*~K&aOSrCU*GBdwEy#vfAhLM zpH3}t&fkiZZ1l~HPKnQiA!28xKdx^Cq0F)7i#^D$XUZQ0s0k%1v0 zy4xO|*>vb}%*Ew5=O;@l_PqQ1b)S5lB-^sgL_xdlo}oHC!X|suPsyD&F;IT&eDV4! zOTP-=FIK<0O|!2RTn!Ds%WdMSr`{m8K=cKJRimDQ1gFwPC)3sXR|~mLs%!LK=Uwjh zFIm;`dgPv0R@+6Es0vQ-@DMO^cRHuPW!2m6)tj~To=%Dcjrdv?&#;53j3x$bQdy!R(4QpSFX(P_ zPD^6Dp~~EQPj7UxEZL=^FmZyyl6Z#)_e7s>^yKi{WbJ41Sv6&PpDm~AE3eI`Pb$=z zNA8&%Gxs^Os@6%ruXjM|Q`%Zgl8!eo>UZZBRpG34QJwOJB{aRO@YJ!QC5lHU_IPZP z-`(&?R4L<&-sdUnEF4eRao#-Myr_Qrx69Tno=%<{b0%%7pKTbN^JVhX^4-16OO?Q; zu4^%g_IKaHek9It_2u0~VFH{-Rm6WEd}@<^qGV#wCZ(2&=gccr{Hi{|arI zo@PBcz=V<2)k!{=Gm=v(Cq1$0^Tv=c@2wqkH(ZG8%Ds_PwaS$vXo3RAP1S`NoZF6H z>$|c1&!^5770#tyx6g3Z`Z}-jb@?V7JNMDcY$j0hf9B;;UbC{d?0oC5SuH-7kANqe zHt2A>23~+oH_a3|$G~a1`iai*gQEI^D>)}kEH<<;|EVJV|K(|!!Xgnarz+JaHi1_a z%I-vLKdElDF*S(b6w|I6uJi<_3PI)5gVHxJxV%$?QPE9N}2Be zRhH7PFX`&~J@Zey#h>?9H2xfva{7cw%=r3;nj3qL8xo@f!IYMPedj@@^Jo^ zXD#}D=|O+@UxJLBPS3nfR5q=u?Kv^8NvQ1j%w?X%#m3p!*QI`Xa#AO1i$hSf?j!Eag*}9}TwS{BnsiTKDS~+HlojTwhu{G8Bte|RH-hVmy{i)KY z>vp&8UiM_6)`AyHdo-`z$Zg@6x%A1q$fNIH?K^k=yl#ii&b#Nn-M2Y%+p<;SEL+>u zQ`rKXs@@KrVUeYi1-IpfOs}=L9K7n2XX+n!P*AEWo^^F{6c;>t^!@kE#n1h`yu2c| zWC*U3+TG$9;?^y$|Li~`^ObAYjMC4|+1Jnil3Bt!+2Q-$ZRZ>-MCG3frw7HxI+S?I zyT0VOFHvO}FTK03UH;Cg^0ZiwmCF)L|IUrKyLqy8yI$(={{MQsLGmh7UKQO}@pLVd zyy==UeZs4bXUjM|1kQPIS_TJvc@lD1P5yVqL~Td|c~j2KO)W`*BCS6^Ki^#Uw<_)Y zyxJgFu5Y;_uAKjsCSJLkU7jT=ey`55Kju5bYiaSqrvg)*&;OA=UuA#t{rSr~lhKJj?XX^t0YIWuX(W-YxZlbVFo6i;u;$jMo`lW+}zRZJZKNGiiU$#W&GEVqOZ#MU*%A*Bnebs~?~8q0~Or z?c?Dhl{qaflja&PQ4yRt)rEzv_I+9R^codbPNy_)kEP#Vtt|U!vHY!<=G-|#s`DS% zU%PYmN=KB-?!;!=bo9qzsT(W$JO_P?bkNPU+sVX%w2s#xf5T@<%unK zo=nb((Fj!XQhmGR(pNQ24}ne2PTvknpPg3qX8IDLOD4UJ&1@GhTyO{t4Rz8qH8BZ@ zi+lHP!TLF!#;aHMt?b(@F{zmAZ2P0sFITr4eV)Jn=-Tb9KN8OA|G1)||LS#-!kjfN zk4g_}a^^*Ap3<0?@~i06N)8W!P5w??w(85OWSP98W<2-^n~?xDF8`e0o^$gM=;*c% zua}bdUv@?=|HGYq*zVk0@jC}Yvmbt1KHWGZ+}_K0Q`8apS(YzVro4&>*z@VFi_+$p zC&?3Q?znpv9N=!6P${(O{I2}?P}8U>0(<9{a2a5>oF?7ek}14)?b?v=@bB->aArx$ z$M5ZDUKD%v2xb3pOxaAkKZob0PN==)OM=sylP_cIL z$64o?^RE_M*3i!?Q(rj6b;*~930_a1d&%c%*WU39nxK%fyyZ0%3bL5%{3CrSUAlID7K zn(fg4%1~=P{lw1y6<5nYu9(~)y=uAzq9mo=G2xq;)f@;yy?El%E=$YebdvRujA3ug~8JEYLY zg2nNK%_8Gx(S65Gc9_HkGL|yhe7zF@Gb1kH{Wjq$keekBK)2wab ziO2U&JpT4vV~LrY?w7ZlH_Hfd-MqBQUTNlwqxqA48NPF7#h%`l%2?(oaOvibo2ge^ z&wH*7Tq(iFcr$o{hlcI^$+o;%)H@~<;hC(LwkJ9qosD~oilP2j;uV_w1Mx3|3#nBeu^%fi#~ zrKfYAah!#?hR^LSwoM8gD^0R?ba1q{@U+)}+MQSI=Z7l^s_s^qb0Ead#!=uG^Kz3p z;-)9Ja%g;ZdGcmi@$No#1#deCM*$;87Zrg?LeDEN)h&$&F-4zOuIr4jb8!^7q`An& zsi@lL*19tSfl7)yZJ%i={8V6dJRu_ZP)S;~HMiwU7l-)G2+bU2`DF?mlB$a*@6=xs z@1|ZHZx`YyU=-(Z$t`vHgdm~*ngdM=DT^nxyb%d<`e!e^%rGRML1aGz0|SGntDnm{ Hr-UW|=II@M literal 0 HcmV?d00001 diff --git a/docs/reference/gio/menu-model.png b/docs/reference/gio/menu-model.png new file mode 100644 index 0000000000000000000000000000000000000000..a4d9f113012af59808f192a0b2cbc2bc6da4ce9c GIT binary patch literal 20647 zcmeAS@N?(olHy`uVBq!ia0y~yV7kJ;fq@|iq{unHpt2}4J)?xd*;&D{q@*Y_sk9_BKTkI}Be5veF()%SRUxCKq`*pF zKe;G1u_UuBH90>wH$Sf!WRiYPW^!s?acZ%CQl)NjqQ0@7fqqFS zZ|;^?gj~IL;Nkt5p86_F#CI)Z=ZLksw1i6|<3-?3rfb!rqSDvSckOM6U~qJG=qlOB zp!nsUvyg|s#!K7abKj3YI52~OQ)Q;gn(vjLW>{9g-+Z0NFmiLcxNG1PCD%Zcj@w;s zi!B#ke(AJEwp}1~p~k5Y*T835T}f{PTttIHMMFc=SFHNAc5AYrQ^)I#fuUFPUR_yf zVQn34Ef(mSl$?BXOXlR&TOSK7lF5-W$ygw7TeYQmE3;r|`qfpTm4$_cX4m?hITZ7b zupKyimRDR{Jo~uPs*XR=-LpEdX-ex+>-x}8O)afW zVLFS1G`pJi?%lifu)rdx7hkKsRDqaN4;(wjCM_*FMa=1nj@bUKU0q!j-|v>M742T( zqUYy#rskbxcDtfW>y3@c?9tovww6gO65^3CXqabP9c9g<*rG8#sGTt_ZneV|kCO+y z7GJ!T$Pu`3%Plhrp2KTo+g3P4y{*b_S7;G1UwUQF&4*E}rZd(~7B=JK6Irr6I_5hk zpIh88zP3{D|jy36i|Z4F)>cJIc`Ova8bFJ*oI^uTw|()tfB zm^3>&r}u+a=e1jm9EwMLSAMK4?!LH~bEeVKBVYH&)y?ES-alJ@d;O2ZsD9bgP51Wd zzWVxm|Np}W&-S*}{xaAftRBQCv*OE)Rsqx7i~GycE-bM2((Uf^OMiCee*Vt>o11?> zc>dh!{5;+l_v;03Z#x<}<@{{(IXiafq@Dfsc-n6vCyv7GtQx1cH@9f=R(*Z6etO)d z9sk}>d~sv{e>H8peJ;P3D!VfoM2lH)DxP|Aq?22scNwpST*U&@fB)9id^(xOpci*$ z^#nU7=WvDzGc8v;y;E-ySoG=2j~1x~7Ut9cettGJ>e-XGz7EIx7@jO!a_7q5w=uDq zSGMb)yLV6J-MzC%C#&aMg(U@7)o0caK(5*1xztU-{49*vRegc*ONW&dg>~Y}pZerK{yv)ty(@)m3zO z`j`1$eEM|ij8BEia=x>T3NNemRM}=uoXGR{llQgrGY&p%<-EDs_5X{mt+Qozm~CeF=jU?~BV%q)@6*p;uW$c+fLZ&;+wCWez8e-K z2+LKiuw~~{`TTbK_YYTsXa9KAy_aFn2Pb_s->lQ`?soq8xziy3UcoZo=+pZ9=NN3S ze=@PpB=?nP!UFBSzHLjEJh`y5n87&h#3KjA7LER>i2=KR{1Pg=Di#&V$+>2h31`EU zX7)%yDX;13^A>!)vGM7??;G^@t5n{%3u|d(T4s5Bv6#+-Ctac<&!2^P{Bi2I^?dF2 zUmNq|jlSRcY+SW>V!z$4+5UEtIeshdSFM(3=Tk9GYFYW`FhBdpkH^b5m*uKtN%k9a za(!A*_}JgmU;n|w_S>I79&e7^^1{H<@@UQ1t9JLQvUl%%SA72KgSFd#MXFq3INWBM z`sYXd+3R!X#df-Er&|V@S)RJ28CvF&Y1?wiczf-U-i6cYplv@6LipERN0W z!X_04E40eit*bE04pXe1GX}al!rCS$=YUeXty3Cz%@6P1oa<9+a*?IWIy}flSzx#P>C;a@Refh?x z&!wubI22oU?29sVik&k(Tr=2U&YnF1CQ?khOAanC&Hns#^6BZx8tZ(cLpc?-CWWnj z@bF=VVY-#tF%$b+r%!isi+|FazC1p3UZS4Ar{?YD@#*K|cGf2)nOV)9xT{o_@v@)F z=CrRVCnqg#X+M5>QLDIf8_U!k$Is2>e8xJ>i9<2ZZ>`4)ZKuRAu`<1Bi_LegTq)7j zZMm;R^LX8#i(V5s6|UxGpk2f1gg-)7O^y0$7`!=jg zYOC#we_q|RiL0a7+Hw$nOvQ#U%pI+4kYFPyI{px3SM&j;pMxq6xRr+rBD)e{RhgpS0ApNB34tblv-5`~71#kGG2#7grkC+^PBdeWvlr zj?Tnm7Z=-2ekH?{ZbXo*V&%R!t|M=3<8o#+!bBdqOTU3}_-hJ2jUPZFB zxPF{w{-q^)mzS^CE}YMAf2VWr-f3sfM9Ns1oL!Xj_m{Cwlu6f=Dd`-%ylOf*TPuGZ zo1LHc{2;rtMSY!G{U5`bKR-XcprzQdLWgU?xjB}?;^N|5+}xGl@0M3e&g2f7t-|Cj zD>K9LbcusYNr{Pe*cyxIfPjEsf%#4$#$Ahi__?@#6+Al9>BkVgJx|rfMz}d~%2sD# zQIFNJXJgANFK$lvXAskmn<$>)jGeqRuz?!4R^2cxrP{ohlhjfuBT}e18(2EX;^w|OZHV!r;ec1bYWbB|yJKSFr|qt6^-$UnqWybY$E{_YM~`meFU?(ab=|fy z4kwPn;H*C~S--7HKX7wueti1mZERMp>*~}Wdn$LBW+W8GX6K*(Q2BY?O+Svp-9ueZDJ#F(ZIh=zjax3YcAD5?x5VdfVzPE`JU#t#+MyP%{&AHeHW< zefsnH?@z9*JT7Uvs?~Mw$;r1jmb{!X`(5&*BinSM&Ax>>>t1!{-+KIh{I=5~P93WP zveU}WeEiNHy7%R`U4Lqx#iZYxSH0NH;@aBk%iqPFuE>0Sef?oGKU>lL+S3txf0;1Y z*`2enz8!UCb@cT{x86JXyXHsd>bD3is#;;n`St6Txh9?OjMEoon7Hiu9@qJ)bGF&T z2YJ61Z_7C&u}N6?Y^t-}@16sCu^;koPRcuP<9xeQ*n6#d%ZiGwMHz;3?GpzCQW${{Q*B=I5 zX0Z9}V}7hR+c{x@c4y~JotTOl`up#&ADE!%xaU_^{GUHDA3hZsZU6sncXQ3>-j#o6 znJ(P(@0S^$oDbuJmCJV}Wv@;>H)k%xj-59@KkD8qVPnC;&+pzRXM6s~$NiJ0hNkpw zj|G!#YSZ&L~xV=^?s!ummd=#|%Thf2@^@r2? z$q}2LXw?2Tdo-_lR&cCn1Zo?j1|g>ubp{#kr0ef8l)BXh>vx4Ng4?0zs7s&i$C}B>T1hx zkNX*(%(IW*>F>e8SipXPz=pW-fEnF>BSYzhWGpBJ?r-M zv2ybX3r=*1xRIsimvh?oyNUkR+I~6S717rZ{@IZk?EmKNdL6xahKr43cd;1N{aOFy ziOA*s^~okuM;}%0`QYR~uku-Wi52twI;)m7Yn<*?rn57Yl|`kU{ndQpgo#zjhv&QB zzgxJ#;rySU>}THI-uf9-Rr1MrJhcBG+1=i*ylva21Cbnx|JGhpxsqJ>@8+YAU4@T5 z?riNY3tl#1Prkh1`~Cb5KW^s>?@H@+z5C@w#+!A8Cgo*LObovcIej`e|M{htm!}Hs z6?i1&#PIo)RcPqyCmF9EB{75A7yA3}%#PhHr>3XZ{r~s=w>mKu5_8Xal$8nIyy-f} ze!h3&!g-gM>rdTreE0iVLgCfby1UEOH>G;>+}(XW{b1AK)U0~txz_9gqEpYEoGcy~ z8nNL)L8q1d|C%{Vz5AIj?AvRfn5g)y<=5Zu%4a^ly*vBJv$M;7tn*vJSX9(?mUF*= zQ^%#Nvs!*lKGy3!*ZJ+e6@s3>zs;17|GQUU(XH1<_lx;kTUv&C9=9$#VqEb-=+)KL zhj$bn-1GSyLrm=3pDz~2re@iv`Dmw|dExT$EipRfsdSPKmx7F@4)fxNmZ`bckpZ_+m&Zeq_TdsDCaqg`jlV(PCOrI`% zd)v`zFVYXUt>Eg8`UY!ha^Gc12su;=&*z$#YYwlG2W|vp_ ze@Rv7`y0i=>r?y7&aa6*y}+_~Lt%k}x#?8q&(DKrObq<#@6&O+W06MQfp7==2aKVi z=JEUP-MD{$|NSGK!gCoGEnci`+PBQt_U4vMCHuc6J;l$BUfkL$mwbF%(yuS2VqdrA zbRN8YyEDE{^6*0Em2Ykcp6`?W_~zbRkFYSsZn569>+4vS`Mq^WN-FED`}gCqj+|Vd zPPEyyX7=EYjt+Gj8@YxLA1vn8?UF7li~98?(%W-XM!-?;!zb$#J-2dRsr{rJYbyFvC+qE2^gTm!2Zyc-@nM2Cjz zM`=%+tgdfV`^)Orw_KNgIbILnv#A#r9L>2cmL90D@9+Nim%MSt1zD5aSB<^BFP-h1 z9hZi$XYG-{-*#vDOv=B}{nr{B+o$G=Vf@IaxBC-c<4TF;VKCiCCC(T;w$_p_hH>+9}@WjWeR zOfizCS(>xWX5Q;qq4nkE<_RAk-@dS{mtTMXAMu?#kN)@-C71K{sCczy&5feCZ30dm zlSCZmS{AG6>FJ4xiG6yv`~4@QtqPaL(mD?Wv9qV0o5ecA?R(goh{A0P7Chj4?WWdJ zx&GzN1D6lzgof_dS$givf&~ls|4S~sx2sh9;lr5{Jd0OZL

=a_j1y(&^&1)!$eW zK0Z3S)6mfH{Hj$}=T9xrTX{Piqz8m&V^Z4;kPXc2JgDAG1v7*|(m zw{e9mSLoE)_EYx$$;ruy+rD+{+rZY?uB-zI1}{pi?uvwlo-XN`w@71h!}-S61D{u| z5{un`bpPC==iWV+4i`3UJ2-)Vcy+x>)N$x4-dCTYl{VT=H%wCUZXE9J-g0# zw%Oa88xl{(a=N_Tns?W#K{`*Uw({Y_7$0ta=g`o*A@}ypGRgwwB zw+bx+i|*(MWvvbKUhX${jcE4@S1Gd`4SVnHGf#7VE!FJ0G+CRQ|Ms0XhYmM1G-%!L zj{$4 zJw(V|TwLu>HvhX-o3hSo1?eq|SehSLX_6sfU8OT`-n{E;muq+luhX%4Q?;3!|MBC; zxzEqd)t;?--_6L#D8;c~V3FGfj}^Uc%AJ~;J#1UTxI9AklqBSrope@R<#p<)h@Qy~ zhEJTeYZt{XcU^utc6;9<6Fdd;m|F|j;i1ert22@h+Q>EPq~KIn=hd`tq+vcAa&sCGXDEe~YqRE3)WXu*g#J0+AKX zFOM9K_FC2|;MDPIotydTtiOoM}^)@rl ze12}@zl-kcEA^$>*=?GdF2rn&-+b*HpKJ85oT9aRYda?vCN8@CvMFWV>$j@5wtwg6 zvnN@7{J^cDIL`mgwY3aaR)+WgKX&X>Ns!R_X_KC4 zO7Sw=|7Za9=roj?o?pJ4S$V&fp(kp`gu48_p^JJKFIU$W7kl*TeY~arDz;#er_qZq zzNme3!%#_Cd97^U3Z`~``Dd@!@BjDwp+{(Ff3&e2sEf4f>W`LRXLgmEytym=_UYqG zvw0*A?6m)XBp~IMkAk(~M9aFmKSl5NF5ULtB3CL`-7h6?ciEYbpOfDz_Zw7QREqiY zxAXqS<^y`MURyZdTxvaYBcf>1WbOBzR~@<*)v&iP-8yv0>Dv1E^Di$iUn@Ipg^pIv z%}uSk(c28t&djJ^ckhj!oD+wlOK<37^UodkH!?4d^WSUzUM25$*(@H31OF;NpSrW} zas9u;6J5JK`up6n(~rLlT`ggf&c|E*Rmo1N>EHW3&5JHxNc&S^W&ca#e(8I^gz0)J zE-oRDHm|C1wURA^h!COvNAJivz!ChR=(=96%ReW z!hF%?mlak-_j`DI+uEalUP>2c-`ywYj-oOx%$dR~NCKb?-ZJ@UHB4x84=kw`xz^|2J%+|KdwGZ{9E{eB{C) zBqVfWQ>wRDVd2LPt~ZAyFPmi^d}jCdO~$n~k{?%o6ur^ALeFHIR2!eH*2yiP(VnnPERaR=zeQtMbvh*emZZHt+JCwc+{a z^PEyfEe+@9-u(3Ev#4m@)Bq7ydwY9^qT=F<874xz@Vtj{o_$yHfAV zRih-Iq~uk)0zJHnaGl*A8#M#pIm;hM9#Iwg{Ax5uG2O5QiA63d)xyomk%iER!GsN7_ZJoI+_h`b)vVQf?jJhj#KoN&RG0hY!2<g_P0BDtm|{G>(Ss)QFnIsw5XRQ$K~sPPW-I-e67`6mk^u9_fC9y zdHJk*LDr+E1ULJ`H^T9I>BH)<@an*B1QmNDXqf`VVqFSwu z{>&Cseib3QwY8=ydiISo8{g$~uH7cfc35NeF$Jw@VY_eLQUuKr?0ozA*|ERBAKzZa z%ivl4eVT=Y8;4@vlDt^sY4(rW79Tl(EJ$3i4EC;voRB0YJyZ<%$oz%%Azw4g%Y>iNS zS(*8~utgU&cI>vkuxqP%@iU%XX_c$P?$!Kwcz3GcJ^?2V?NuL@uaxQO-LQ&!wH!imhs5nrlzmX({ryET@wwk0 z>#~$r@9y51^09wY{%o^5U!Tq9`Ta^;Z=RLwg$D<1MCAI8J=<2HuhbG6>$j|)#i^^S z%f$ZA2WD1Q*09dhXJ_8AuvX5H=a-W?vLaAd>&-vV(C+&Ea*jSeY_rYXFYnnY9v2tx z7tPO8^7KgO@g48?g}u2o)gdX#tl#$9%|~*e;os@;@6JA-&#$Vg%D(rW$L($V8Z;IE z{rf#}$#U@tvu2$>)Vg?v$;!1m-)=r%mVS^axU#5-k6XMi>C+SK#cz$%N|H`as?NN3 zXY!ddPIdolg>0+MR&02#-y&cdx%LE?weNht_LaeB`?r>r&Drs%w*UFO!z-?DuDGBO z5c=)x+|$OMo?GS`G&bL_i(dBo_VtyA&F5NAE_=rF`}w)2t#5K>-7n@}9(Jno)+4iJ zPEJltJ9q93kAJ&Z!^<^wCf5g<3(Ol>Jv==VFD`PuQ+Qlf^h)c}!pBXL=6W~&R2*zN zZ1d&9EU%ZZ@4wr>-&8w%o{@e=%$^@BTz{@!|Ly6aRvW95AGd0JSL<4GFY}d-Z)&nT zoUv!q>c0MdspnV2e{ZVz7`SKe+=|D&yJy%`ik_YxAA7G| zzRn_P-}!a1oj$X-@ijb1kgxilccM?$$V>N#eNJxf^~|leR^9gwiI{pY!DFQ;=huz% z>mI$ox%q6rdfu&+e|8(Z#kq`)B|n_AewOWOX$hJhdG=d8Ep3um>aQ2U)90UW6;}U{ zchyTMt1vp4S4&V(@J2*kl(F=M*u|ceHyOYFye|E}r-w%`ZV!jW)LSpY*2Gq~sn5TY zQ8#CDaLB{jnA7?DU5(1$6@Z36etk`k*!O42(USf?*}pe;TrBEpI~Y);ed_D$^AReS z8FFv^NXXAWJh%MX;^5^B41fN_WZbzS8y(G?d+W!n)7E8scJ0wCD~syt_WgX~@Zra2 zzT4FOVLEuwPW1DW))lHEt}n0dt^RIx&C0_!Wbc|aI)@G)-kjy?6gy?EZ(7cppBo*^ zpY~5!yI6VW%9UbIciaD)!F{}c`pVIHfc0`Juo!zSZT~F9*RW-HEi*^~FKC7!{wk_xT)~#!ANEUaC z%cq{7r?Si^^EkKumq&lUvtQcyxaRYpba(e?Bcr?;t0xy1KlhF)F4?kl#|;M`pItx0 zBXe?=RsP$$crowMqil;7d+Yyq_w(EMvwCr$>*9%rXSMv;{_O1R=%)v?6J=MfT-nmz ze!Wjq{(7;dkx>5vg>UC)m*1_r$;oN)``5InXHpU!-TUo#YHDgk>DDPK%KUn_`xHkw zN1|E_f&#$nx0Dj(gckwM%+wbXVdE-XLhYtlRwtJt%d@xSGRPl1@{)(SZ_jmNvGzlut zGAw^r$DpLFZc^w^-o;q0ukF)`<5}f(Iq`4@KmT@%BdS@C-Hz$RdfoP%e8SH|!A^9by!zr3Qk@Abvz z-S;Y*IbUC2eEPh4;&na0KcBi?XW!WW|Jn9-`DJ&fXj)WOZ7R8pzLzb7GRB^O;nq4z0pdmoEn&e|ofY>cblwxkW@@u8;h8GrhW?bZhd*M;Aev zHaz}r*W%=p@e3Eb>8Aer;&*1=-S+wQcIW>5WY;<6-v6&P^Rksub(#D$J==5F<7b}= z6@7L_(#4@c`}a3hWda#(iM~On^*Jq)7{;|J4-b0|M~IeCJz_ay1!MNiVq$g z4M|{mkn=XcrS&B9wP`z|9t*$f^|y<{V= zM=e^WQR}ev+IweRP%Bz7FXu={8jqYz$fIBN|1LL9m>{jc<;%xHHRIxGKTqF_iypk+ty*4)>pe|*fnu|@M%jjqChsXsrvUs!v)*F1Sgfg*qT_i|93cX_$| z@e;G^Zx4cJ>$Y%kJz8^SfqA!|fBNNHTQBU`xYc>5s^hwKVXuGpwUs}Z^DM_}mFwDt zxoeKzyLV5kwz{(N;)+16Ra*8TTRRu+c<}ONCfMe+@$yHb^S>%99JsniZgKtpV==p? zoWHl%^I4UiUKtD9u1T|Id54Al{QkPUY}?Yfy;kOT_gQW7Sn>AF8;-da7o#?IM7?^~ zSRQT75_p=0on2T)rsi>%6NlodHy<8`fTo-8@89@y%QZ&kSsOBgxBNV?;=H~5A<#IY z-?@c#wdVi+{gx3{TeBr%OO5UPI;$D(axXLT_LpYsJU;$E>e;ueQ_s8scQ*tYUT(R{ z$UJL?Jio++7GCLfb1v;FdaAi+ul<8QYrDgzU)S2$$W*>u8kf57|EkdCA3yHAbnoun z#_+h8u?x>1l*(cF_U>-?+_`hNCJTnD=<2TZ`fXkGgu~KuY5r5ytZm=k-hTWh#`Lyh zYD&tDcQ*q6Is3YtojP%%V*QMk6-l76zw&jN>074h?)~t!H1YE@?c2it|CZ~RnMv&` zU+>?{mUrY>+NCv-Hwk^&l~wLHXKZ_sD2zJs+<(hGCfCs z;f}j@-NJe7uL`FwSg>G~*9zs$n>J0$zrD@3t|L!*)v8qvOSV21cvSZ3`TX>cUrH9G zdh4_CWE^^Tw^K}g_qjPY=l=iu-mgz~w?j^jT4Q7By4~&n_uGEvrhd*o&`w zr+y4sHKq4p!if&-FZmat%$;QvODF42j7-#9-U41)t-70+OB*zdJ z=f@*^Ym3Y8&FRJ-e&-fOZ?6)&e)q2Iis0k(K0o(;YilbjX|^U()o$`CWzMbOI5&vi zZ`Y;hJZsYI=ra!wuYC5pv-9SfNMX;4AI_i=?#s*N(_de^5%m7!MfcqiyGnR&Z?`{j z*}t4w!P2rlbhY2++TYC}btg`!ue-T#*~*XZ{h*O7r;e`TZ#isxtMwJMS8s5+Im7Vu ziwg(mPt)By!}4=^kDI8!|8b$Oc7F=Q@7EMh`1ba%hv&|sO}GDk*I!;+Z6CGu)3clD z_3rD+12b9?AepX|r$I@T2itHlmxRo+QMtRy_mkINt^bFdI%Y3grIneP`Qzu$NNW+rmKDeL zZ7gG0#O2|n+pS*Z7=6X81gqEEN89iHo9(YZrSJ z;B-fjGr48cP+A6vFcUZ?3dnwQ!bX3 zmF1tv`2N;4G&H%e@Z;)LtJbZ0QLWweC_g!Qv*YTkx5B>cb^W^R`s@GKUVrtEu;$C& zu<_!9XKDVQpT#e@sL>;Fv8Vi=WJ7OnoB91aanFAD$lVp%d+)^j`gyC5WMqqZu5ewt zd-wgjPo6&qt-Ij7b9cSHen99|ABB*>DVhg@Tm!`li@C*WZEb93eSLHD@;fzWQPY5m zii(FnKR?%geVMnq`QU}JD=Pv&`TaL5`t~N$Z;r*pK*{f6BB@)#R<9MT42_9Vb9H6& zo4?QH{XJeuqa~X8`*zNKdD*(~*B8}odA+9B-`?EJIMhx^BhJ;I*6ew$H z&F#0p=Nc9!$WVSKaQer`w>Q-M^aRa5<>eWEe)d+~)O34R+>Gb|<$n)d&t6;NDV*J| zu*N6!s%zJxHw<+w-!!|7_U+*oi;ao-a`526NdfoW_++h?*w_E7S$a12V#lR- z`m5$2I^^Ux$0G3I_fV0eautUY3@rYAyPe-7Wy&QlKcDOUaw7}t+Y7HtGZqwY1}#Io zxcT|iyZ-6t-yJ^KtjRFPet!Gjy}YfhRhKSvcl4fRaae9V>$SDzO{4mM9M{%bAHG}8 zUikm-+RUr3ycuF*-rU&#Ur;aRMDoW+%09ENb^d;r?dfsChKFscTkoBjrmNMP+3p_v z^)--3;zG-X3kgwMek@uQ*Ed^@bF082uNAAL7HfF=oXWGc-H*)#Wge4)6Xpl zTpuU<>udIznn35VM>7}WgpK#RW4%-+8L$lkegb1Q$nJp1PM^fQxG-93G3r1JCC z_2SN?pPEtz8dq6yQT@eNH!)qSLrcBS8y2N-hpn?=ogwsTrg44x`FSd0x>i0#pNxO} zvWo603U{9r(9M-@BE?((?`L{pMa7PDw>EZYJ*`>HwQAL?#_6K2H+ggdMN$m}maTf# z`l)0~`TMwUZY~Y0?xn0)6cr@0>+3t;<9)KL_q_I=uD3DerBIJVeoW*QjmEl08-r(! zUc2`%(ztg(W!dVhR`^9wRwBI)!{qv{h)srU|?rNO$&)pQf_+Zq2^DkAlmX($g?~Egs)(3hf z9aOxw@KFA0jV}IWb9>qtlo`AIVq#+@tx7cF>wc!TevcKrwQa6*mD< zi{HH7-xpmeEbh9xAlN=+(Jw8Qr2M~TU5hdr*Ub=mq3B@!fMJ8+4~YzJ8&(!(lbjm@ z`T6go-{0Ue%k4Ur5i-+uH~+qU=l=Y9y;7*u$e4R&@bP_jzV~%`Jzu$e*DQH!iyHz$ zkB;Bj`8!YZ*(--Ib8f{oUZGcA9jblm*L>6J3VIisBhF7NkM*gRe9e;j{yu--wNLwgbHwhQrN+!Q z<#!!J?EIQZ>~(*?F1vN_T$`!vv1y*s7Jq+aZfnhbd^Ao!%6iG|X^S-WbuID<6iL-A z5RBk8VX|ZT6B4>NIP~iE(9pZ9SH0Tq;NI&N{N&lQV;2@Wua)?@)=(;R-~WFCpv5Rl zz59bBB8mzU9v{-zP_@AH3Cr)eY znP#rfR9PtI6ft+zDnkeU2j)K9VyCyduSveU%S7H%C|X_pvuV1#{H%VN&P7+FuGs#3 zyP@oNtoeZpf4FT9hH` z`f{PhspzgnG7LhEFAsP=$U6`odew8)s((vXW!>6;d-bZQHCMB`ot&KucfBePES)qj z?!dO(La|^YugytEJx!!q-|x2%$@@6U~9vMPP_=i=fgv3ok2XG=ft zm)rVgf2j7KTieyE9=mZ}^5t%QbN9}Q`)j5D$yzPgxKT0VLqf6r^L`o4;F^=azdsfi zYMR^44O+KgX+2p|JU#IE-auv0bjig8g}mElMUy7$p4uC=ZOOg4<&&y@6s)YZxU$xJ zv0ZIJLAiR}alT877oQf1R?W;YkuqgvWwo%fiZbTg%$ckHA^J)Fo_%jiKX0Ai|34@2 zxL@}118U44%fCLqax~aQ#bw6nJ#+VD#%wpNp8Rdr`mdQc+L<-kPw1Mxef;|63(xBR z-~N=o)3^Fnu5v`b#n!XhqUzs@qqS8gFB-Q`Hg6B+->iT0)8ilSzV5z!YPaae$d7*t zzw!61dK%T1Ht+0w%x`0`@8z){P?1kPa`8;YrbB!+xP3#r}X6i|5Dug{~djF z%l3Q3Kc4*CV(#&m5|*J0*HPP#2C!a_pt_GQ{7=?N^>I3@UC z>5d&1$KUV&KkvnCpF?}1wyCJ-^cMABC zwzRZfT#aI&fTW5GDr zdiLpNXXlxPUo=1y#E05=xBR-Eu{ZwrH=D9YEVc3VbFcB+9Ozl>o@rN*(UJmzTT7A1^c3FWpcdYUDDTYO^?1|R=4ZDx|^B&$!+Z0Kc0Nxf97eq z>Avoxi^Ze2{Iq_PKdZ{b)c)Or`;Ali*F0%%l;2SJ$jxo5MC!$7@2uaced_eE+x1&{ z*Y)@3&L`KU6-;=^JIn3jhLSTuW_~wLEU;$V_~f4I8qV0}LsMCb4xV6L!x`(m{nuR% zUcRTN7hcT{oCj*#AG7LO^k@De4faNs2Z9eQ3^*=_^qpL_>R*lV$r4|2nKy^q<@p}X zOyBkST6C(tW#9>ptpbarcI`>{$mkmQjUo2H7VhS__3C1WEQ@uXMS+$}N`AOkom2TOvaI%tV40qtji9J&-m0f3X6>CVJ>NXP zFUvq+R~m2mom%tG-R09?TF(9ZnE%|rkL=9%YQ?v=@#>y3*|rTduK2I!qpQ-rYX0c- z^m!dUOBBw2dcSk=a`pM<*=<<{1^?IY7c!|Z;1m>0IdWu!lF1Y`X7*19*6-h>WU|G_ z@bB%;)YC71{`qY2``4zTLo7|ldyS{x{rj+8CU(z^(#y*iXPETFZtG!uzwb2v-`|Tf zw(`s}ZeP28pVyDu`N_{89a^mJ7cgaRZl3+8-R~{77O6_h)yp*W_1hfUuzug8Gq<*` z2;C8V`e{m)?F9h^Q`4!g-C~9*CnjihKa3KSi8?T)EZC#QYNDum_=mHN`4$t3QhUoI zJS5iciN5&cvf2{SB^UP>)^GE=Hser8Q0k%uYSv*ta> zczoi!^8V+q|Hgm56tABc(t9KGZNcVpHGiB+uk1A`BC%K~3)de2!N%*S~3 zaqtA`jhnfZ^w0MSDu)Tl)!n)EFeG^Ce#Yr7Q5=DD*FGz9`rH5I%a?4mE9uwPD*u1v zdced~c|q`UqtZu$A}y1ri(i~=&Kxjjw)drZwi!7(^{&Tq?)79D(0b?dIb{r}3fMHDoNRnye0>EXY9MqlFdS6%+I&Hj8n zrQMKeVqJAvt*z#pqy|^s*Vm7wBs|Vc(`|V9)%(s??&qh~kM8{O`|3yWRPgs|L<4#+UV`GD_7>+2zVAN zt$lW-_wtM%p3Z99XM@7;#_#!i*Vt^GwDI(Dre!O|swaJ$5SCE2c&l!nH0v&=T~}X+ zt!s&Le7M{Beqf5h+32&^XZH2*edAO+VA`PSK7GdWLJ{e%oip-()n|EJ5csD0{_(l0 zaJ!k7r7uP1GFxx{^Q7n!_obav>N~gp-hZ~~F!v3)?RRVPvrl=QesrLb*(CRt2tPmn zw|94UFW<1Cz$^62-BqCmZpmjQUz|Jd|77|6ZA=#ywT3#cyk;_MQucGzg4G!N z_8HZ))$Q$n?!PX=@tNi2XaCE2q+GtwG(LT$vw62QL*&PBvBN2l`N>wB_AUCtV8`(1|IP;wA3E-@`x~*Ztdg~?xR~o}>lu54`9Im8UB0#3w0*h! zGVcWOZ)$Ik-o80|#ux4XY*mZr?O0>6XU?8eSKS-;H87u4EjRyK_RTH*ir`GK$SiC5 zboo27cR0B@jpMt|cd1+5{qpSe0;v~U7l`|p)^_E))iiIOYkWSxa$Y`PUGTaeT2Zm{ zciH^;aG2rE{rFEQ`%jhp|C_vOi+!RkXn&hSsxYD)G+#TjnXLKh3(&hA+dzxjU)OYr~LT>_tfzkl}c^zP?d7VfxVvTB`% zd2QE|&eYRhF{eGfoJ^%YX5XL3eY}76W9>61K>Ob2obI-%y}iwJf8D;^+p})}|NQIS z|6keX;^dC*6LWWWzoWnZ;D)VRO_?%RtvYt^%4E&hHH$Q!Hy&-6-`>tHtmfmee03fB z?s+>Znu=#We-XFex_a_Aq4}cz?Em?m6{Sa~&#E+2wmbdhSDHvl!1aymcJ5gk?%nc^X3M%A-=-{j@g-y4jUO!jc{P)k zzpLpgXWMhQ=`i;NY47{fV>@m+31um|Y+br4Yt|wSeMU!KDU*t%Pft$zHB@>zxSsU$ zP*7BAdUxK=``FFREM;%I;ypMv*8h)P_gf@2ee#xce#OMZoa)ECpTG1-pY-)q%)4#2 z>--$gs1OmxxmKW7-$(1RDXaf4*}Lqn>?}T6uPbf5qGcw#7w(wxqF0)8rcvwW=xqzO zZdd=&$ZoN>%9No}TyMgTYV)`9bu*UK{swJh_;q*pU%6wPw{T`L0E0Sf=^RFktle_YVqQyI0-Ff@F(Vv#f%~W(Wy1DcAhsqx5paoO+P;`+s|8g>v?UP_%^o9p%E%FWFdRTT-3A2ckwc%kM92gAM39~?}jB26oelBerF?leyK zxU;!^aku#Nh&>Tv(evu(?OVU^RL*AKt{tBL7f#Y5I#dw;6&|M{h@9=;~wsVU!L&Go(h zb|?St|95J#poOt)9vG{PR8uZyJe!5bK}5ePELsut8;lbljdnLZTL3PUE}pxwr7@s)q@W53K+Gziabcp}yNb@$r$~6!Fx>p<8TrJahak^L)-D8M}L54W-p`7Mut;vfKKeZmG(z zsE`n+@Rm&(SCo|Icc|zY^SMX6xBa!?X|O;4_hj(wc}XAlc3+hAQU3LFSIy^+(%AN0 zIWrPwb+0piaYExv!Zmr-@+~XReyRF<-MwFKZS~_>i_8qAdL_G}9F--UI07R@TxZIO zh3)6+1jeP&nEVs@9~H49`sG0EWUB(Mpd^Nrd@4qdAyoe#3xP4 z-no2NlT*T6hc9lmUvJd^viR}l+rx`1`PJy6FZ~a+*Y&-FkQAg z-BOwUpBraj_c#Zls8OWTloK-}r~)y_D5 zHDvL{q{O7muHs@(>*8gL4zDupSvB#({1fZ*M0)aCrSSURHvKC1PWB?L0ZHqT|_tx*4xSXJ>v|BsLk;0($)A?d|FN zo?3)OcSwKy{Q2?L>v5aQB%C^=UR|4Z7Ch+BQ8;_DV3wjwZ$L=Ml9hbbtlg`ELqbAQ zo9(RT_HEfRtJr0WhIMpww2iIpTG_T0Pr*)M`KhU?>3YBR``oM7*LJR2ylR!;iT#O3 zxh71TcIq0 zANK!zDd$c-dH%c3EdF)ie)gH0jUo+-99zF!ytCQT{{DC4s9v99!AD^rO9h-ljLoE^ z@4UJDLgt2~d9^u%Q?v6)%~JVmC+;^~byQ=TOzfcx%baft zY-KEGFK4KkQ#<2EnNn`;?IZ)K8`Jmn=kwJxJDSe8UB3EyZy%#Wj5-ThF$4#rv@N^ZWj?IK;N^vMGHYyhrw*+0nKn zHWSH)`Q7rZznt34rTu)Wc;w&y>adwB=U37s?XIltwT1aIi})9s5ioFD$bz5Dx$6{l_b9>142;8Re0 z@k%K&Ytqzi$*iPlow?CbVPPtH;!79#^k+s_Ub5N!dS344;%#Mnb5`EHa!D^ON&LOG z(+W>l?am5DW)&BQj2$OSf4r5y^1`A*Q-ba5=U>@%_n&{0{r78Ld-^z_PlW}s4BY#oK6HP+9lWJIxwJRD^}YSB`Ilw|{VIETdl^?&^v2#+ZgHcE z4+(F|e$Qk#X+D}1d1GJgZ@sY9SNC#z&Q9EZdvBkd?W^@oQ7$e^cz<7?{y*vKy{jQt z!!3`h#~3$e3SOSEGgS@LFr3$D>se)S^69m{zej(s+&cf)Tn~Mv?U^w@W zlK;#91bkz@-WGHFNyTLof9wB~V!b8g&F7t%H_=DN;-cXBjZZHqZ)ks9`Qd1D>@mI< zW(@g@H#YFU6marr7ub{&nf`TeRCl68OzqdJHs5X}ySTU{%vvUTBVEF6PNIae&D{BO zQiS(81 zv|QJkndYgs^y*TEJ$oLfrrj}UzIt)BWkk`0$cWqlYWNHyoW0UCAe)k_oPT1n|&aAS!UYyBUZ1k=O4>^ z-;?-b>yeU6YBR1}d#A3Ww3%cL9ut`8{VCr>vpTB>H+KY73TuF zJ33CVo;Nw0a@j94MEnu}Y2+wFg|MgM$KRF`Gn*?%nd^>m)Y z72FkDm-aQ!dELgld&;9n$tr4QwUMVbB-;M?csxr;Xp_J7`4<;!J-kjO-rdDxo^rD) zB%mAQuJh;nH|$HC;qG6r+$IygVPyjo*9&)h|K&wl_b&YWbZ&pv3;*MeVGP=JR(zjS zj`ug~82B3RTUq$^>(?t+uO@EX5ocUsxAXNne!tsxX=h&EK5wqI!qw$T)AfzX?(Zav z`L87gP!!vJ+djSi4yLX56c7&8?aSXR+j$z^Z9&dM@Pbq4T*9mzqX3! zJ?gXmbzy6E^`_0aIuRd4-|yXi`=XrCrN-y;cF&8>d)d2xf9sSfHScylcV2G!Ztr)k zc~w~)d#lSIeRx>(?_^18;6l?2)-yasJzB{r3r1SCuT^SpWBRfm`pcKU3cR z{Z*R!?@!>DHb1|NlIn+tSWn{N;t=v$Ni5FE7RV)gJ5FIcfR) zeSP=#Hd_=eX|gQdwsXzpTP1B#E-o%lbY?88JYsV8rUU;2)dztOIua$^8_x3b^45up ziY{4Ry>3T#hQUmmO5JAm{U3u3t&RmUFrS%I$*ia-yW{h@@0~p{r>?Dylu*C2CHeTj zK2`5y8&bW+4!7$k{`%s}!p?4SOI-h7+l(2e5jt^yzHNUSd#(QOSCOQoYY!ejerm#Z zAnR+|<74e7&aYR{%2J(c_0w|hW;33M-QVi|{MB`FU7Pasl&wyj&8*pZub#dr{(d)n zQ_W9X6_pg@q$5W2D${}|S8g$T3y%MjCcf)=rOhg=cr#sDS@%B*C>8dz;uGT4VP0du z{dSI7QE_o}%G&r>`t_N6W*oVH-^t0z?Dlr~q!$;wZ){K$Zg6aNy0PV@f~2G>gHFVU zsh58|pD%xGRp`qz^X4)*xVdpgZ%?zn_4%{*iSz3htXj42+iDSVBCd^L`4Gqn?zi+SV zbj$3G8<}SqEVN&^aIS{#T15+shS=SG7PtQYJTI#gWispIe3}H*|&SE*#qO^PS3M-?YnVquD!+EfcV0r z`7_MVe?7Z!-ZD^irDw4$a~gwxr4_$r{u%~0Cb7c?96UTn&aeL(|LoGzZu`&AdQ+a9 zc$#y&jN@`kON&I0@VSyTaeJqizBbzN_1Zm~F9G$JE~yoNJi0z0yBT)-d^^0&&qXqcNpJaIQZ(vpW^uo6ymo(xh`V`sw*U3K z)#Zv}-Qvw`trkhn?Qw_7@5|b+x;!IZ9^{By3&jKl1vA+$o2=$JyyINb#+urzq2Z_Kox)d>CkPz=^;Po8)2YIeH-%@fouwPS zuY8OB_dE5TK0S%Qzqv$)*gwA+}%fKH#KqH ztG8d<`EA~h9~G9j%HNz&)qE-N@uP6vufoTsQ>KJiUb8D$Fe7yJrJpYr|DIu8u5Nz! zO1E9Dm9XsJiHpylnfd=|x4zu7)B5tMCnv?Su(Jz@JUKo8-^>h4R^!#?c$A%y~lO$RjP|N9B_!& z(#~f5@X1K#?fZSd=Pv$xW8-7{fIWY|iGnJNLx*-5Wrx|wT1TBcsad+^|Hpp$&qsut zcYM1g5ERTk!>V-eWA-TwD_639dA)tYjT?+S^7oqW+%Xc<_shJv|MB|78O!uGii6@t zZ}rt#)@5&Qyj!@i_xhE+UoM>v3GZj#Rc&UN>G<^k_n8@n%<=K@IcCzu&(B?z%n}q7 z6rA|%!bE-$!~EmNn>~qJ{`JZ~(o-v47oM{k)LaxSY!6)g&mlJW>hw8}^^PZPv~UIG z(~gcEj{pDtwVm6vMQAQKT?l5ffy$qbjvWWPMCF45152Ov75RPq*7ou7`{ze~9}5N5 znjJeF^YZkrUTtplOMj#NoXc9k-PyT0I0RIqcXZs2X?wTOZvGYKLcKt6lSJu|Z26ak z>(({$N*l>;T(M%Gh*;RCzu)bJM6Z6Il004a_R$|7|7z;3OZxfgz060?$!vka$l#K;O{t`iFDYEB)5X*vo?(zJh{D$?O46&srwKR>%qoF0DecK-kVb+NZU zzpuZ4>R9hgP~GU_^5oE@d2vT}6s~5FFj``5e!oUiSiR28(Q#?;{v$_n7A^Yq=~i~U zu&k_GO^sN1%tvYeC3jYp8^3%}a_fnBR@CgC@+9ce zf&N=NyDU>r*|FiySmlom)uf_M?Ac>OFG})Dm|ha78d60sNwPd8VSMsOXIxGymm^YnQB9!^7bGze@m= qqwM76=Qo$_{%hp_TygFD|8KW+FF)ei=gq*tz~JfX=d#Wzp$Pz9`0kJZ literal 0 HcmV?d00001 diff --git a/docs/reference/gio/meson.build b/docs/reference/gio/meson.build new file mode 100644 index 0000000..bb14e69 --- /dev/null +++ b/docs/reference/gio/meson.build @@ -0,0 +1,242 @@ +if get_option('gtk_doc') + subdir('gdbus-object-manager-example') + subdir('xml') + + ignore_headers = [ + 'fam', + 'fen', + 'gdbus-2.0', + 'gvdb', + 'inotify', + 'kqueue', + 'libasyncns', + 'tests', + 'win32', + 'xdgmime', + 'gappinfoprivate.h', + 'gapplicationimpl.h', + 'gasynchelper.h', + 'gcontenttypeprivate.h', + 'gcontextspecificgroup.h', + 'gcredentialsprivate.h', + 'gdbus-daemon-generated.h', + 'gdbusactiongroup-private.h', + 'gdbusauth.h', + 'gdbusauthmechanismanon.h', + 'gdbusauthmechanismexternal.h', + 'gdbusauthmechanism.h', + 'gdbusauthmechanismsha1.h', + 'gdbusdaemon.h', + 'gdbusprivate.h', + 'gdelayedsettingsbackend.h', + 'gdocumentportal.h', + 'gdummyfile.h', + 'gdummyproxyresolver.h', + 'gdummytlsbackend.h', + 'gfileattribute-priv.h', + 'gfileinfo-priv.h', + 'ghttpproxy.h', + 'giomodule-priv.h', + 'gioprivate.h', + 'giowin32-afunix.h', + 'giowin32-priv.h', + 'gio_probes.h', + 'gio_trace.h', + 'gio-tool.h', + 'glocaldirectorymonitor.h', + 'glocalfileenumerator.h', + 'glocalfile.h', + 'glocalfileinfo.h', + 'glocalfileinputstream.h', + 'glocalfileiostream.h', + 'glocalfilemonitor.h', + 'glocalfileoutputstream.h', + 'glocalvfs.h', + 'gmemorymonitordbus.h', + 'gmemorymonitorportal.h', + 'gmountprivate.h', + 'gnativevolumemonitor.h', + 'gnetworkingprivate.h', + 'gnetworkmonitorbase.h', + 'gnetworkmonitornetlink.h', + 'gnetworkmonitornm.h', + 'gnetworkmonitorportal.h', + 'gnotificationbackend.h', + 'gnotification-private.h', + 'gopenuriportal.h', + 'gpollfilemonitor.h', + 'gportalsupport.h', + 'gpowerprofilemonitordbus.h', + 'gpowerprofilemonitorportal.h', + 'gproxyresolverportal.h', + 'gregistrysettingsbackend.h', + 'gresourcefile.h', + 'gsettingsbackendinternal.h', + 'gsettings-mapping.h', + 'gsettingsschema-internal.h', + 'gsocketinputstream.h', + 'gsocketoutputstream.h', + 'gsocks4aproxy.h', + 'gsocks4proxy.h', + 'gsocks5proxy.h', + 'gsubprocesslauncher-private.h', + 'gthreadedresolver.h', + 'gtrashportal.h', + 'gunionvolumemonitor.h', + 'gunixmount.h', + 'gunixresolver.h', + 'gunixvolume.h', + 'gunixvolumemonitor.h', + 'gwin32networkmonitor.h', + 'gwin32api-application-activation-manager.h', + 'gwin32api-iterator.h', + 'gwin32api-misc.h', + 'gwin32api-package.h', + 'gwin32api-storage.h', + 'gwin32appinfo.h', + 'gwin32file-sync-stream.h', + 'gwin32mount.h', + 'gwin32packageparser.h', + 'gwin32resolver.h', + 'gwin32volumemonitor.h', + 'thumbnail-verify.h', + 'xdp-dbus.h', + ] + + sections_files = files('gio-sections-common.txt') + + if host_system == 'windows' + ignore_headers += [ + 'gfiledescriptorbased.h', + 'gunixmounts.h', + 'gunixfdlist.h', + 'gunixfdmessage.h', + 'gunixinputstream.h', + 'gunixoutputstream.h', + 'gdesktopappinfo.h', + 'gosxappinfo.h', + ] + sections_files += files('gio-sections-win32.txt') + platform_file = files('gio-docs-win32.xml') + else + if glib_have_cocoa + ignore_headers += ['gdesktopappinfo.h'] + else + ignore_headers += ['gosxappinfo.h'] + endif + + ignore_headers += [ + 'gwin32inputstream.h', + 'gwin32outputstream.h', + 'gwin32registrykey.h', + ] + platform_file = files('gio-docs-unix.xml') + endif + + ignore_sources = [ + 'kqueue', + 'tests', + 'gdbus-daemon-generated.c', + 'xdp-dbus.c', + ] + + docpath = join_paths(glib_datadir, 'gtk-doc', 'html') + version_conf = configuration_data() + version_conf.set('VERSION', meson.project_version()) + configure_file( + input: 'version.xml.in', + output: 'version.xml', + configuration: version_conf + ) + + # FIXME: configure_file() does not support more than one file in input + # argument. If input argument is omitted then meson checks that all items in + # the command array are strings. But if we have an input then extra files + # can be passed in command array. + # See https://github.com/mesonbuild/meson/issues/5893 + concat_files_helper = find_program('concat-files-helper.py') + configure_file( + output : 'gio-sections.txt', + input : sections_files[0], + command : [concat_files_helper, '@OUTPUT@'] + sections_files, + ) + + configure_file( + output : 'gio-docs-platform.xml', + input : platform_file, + copy : true, + ) + + content_files = [ + 'overview.xml', + 'migrating-posix.xml', + 'migrating-gnome-vfs.xml', + 'migrating-gconf.xml', + 'migrating-gdbus.xml', + 'gio-querymodules.xml', + 'glib-compile-schemas.xml', + 'glib-compile-resources.xml', + 'gapplication.xml', + 'gsettings.xml', + 'gresource.xml', + 'gdbus.xml', + 'gdbus-codegen.xml', + ] + + content_files += [ + gdbus_example_objectmanager_xml, + gdbus_example_objectmanager_sources, + gdbus_object_manager_example_doc + ] + + gnome.gtkdoc('gio', + main_xml : 'gio-docs.xml', + namespace : 'g', + mode : 'none', + dependencies : [libgio_dep, libgobject_dep, libglib_dep], + src_dir : 'gio', + scan_args : gtkdoc_common_scan_args + [ + '--rebuild-types', + '--ignore-headers=' + ' '.join(ignore_headers), + ], + mkdb_args : [ + '--ignore-files=' + ' '.join(ignore_sources), + ], + content_files : content_files, + expand_content_files : [ + 'overview.xml', + 'migrating-posix.xml', + 'migrating-gnome-vfs.xml', + 'migrating-gconf.xml', + 'migrating-gdbus.xml', + 'gdbus-codegen.xml', + ], + html_assets : [ + 'gvfs-overview.png', + 'menu-example.png', + 'menu-model.png', + ], + fixxref_args: [ + '--html-dir=' + docpath, + '--extra-dir=' + join_paths('gio', '..', 'glib', 'html'), + '--extra-dir=' + join_paths('gio', '..', 'gobject', 'html'), + ], + install: true, + check: true, + ) +endif + + +if get_option('man') + manpages = ['gapplication', 'gio-querymodules', 'glib-compile-schemas', + 'glib-compile-resources', 'gsettings', 'gresource', 'gdbus', + 'gio', 'gdbus-codegen'] + foreach page : manpages + custom_target(page + '-man', + input: page + '.xml', + output: page + '.1', + command: xsltproc_command, + install: true, + install_dir: man1_dir) + endforeach +endif diff --git a/docs/reference/gio/migrating-gconf.xml b/docs/reference/gio/migrating-gconf.xml new file mode 100644 index 0000000..d9fd064 --- /dev/null +++ b/docs/reference/gio/migrating-gconf.xml @@ -0,0 +1,515 @@ + + Migrating from GConf to GSettings + +

+ Before you start + + + Converting individual applications and their settings from GConf to + GSettings can be done at will. But desktop-wide settings like font or + theme settings often have consumers in multiple modules. Therefore, + some consideration has to go into making sure that all users of a setting + are converted to GSettings at the same time or that the program + responsible for configuring that setting continues to update the value in + both places. + + + It is always a good idea to have a look at how others have handled + similar problems before. + +
+ +
+ Conceptual differences + + + Conceptually, GConf and GSettings are fairly similar. Both + have a concept of pluggable backends. Both keep information + about keys and their types in schemas. Both have a concept of + mandatory values, which lets you implement lock-down. + + + There are some differences in the approach to schemas. GConf + installs the schemas into the database and has API to handle + schema information (gconf_client_get_default_from_schema(), + gconf_value_get_schema(), etc). GSettings on the other hand + assumes that an application knows its own schemas, and does + not provide API to handle schema information at runtime. + GSettings is also more strict about requiring a schema whenever + you want to read or write a key. To deal with more free-form + information that would appear in schema-less entries in GConf, + GSettings allows for schemas to be 'relocatable'. + + + One difference in the way applications interact with their + settings is that with GConf you interact with a tree of + settings (ie the keys you pass to functions when reading + or writing values are actually paths with the actual name + of the key as the last element. With GSettings, you create + a GSettings object which has an implicit prefix that determines + where the settings get stored in the global tree of settings, + but the keys you pass when reading or writing values are just + the key names, not the full path. + +
+ +
+ GConfClient (and GConfBridge) API conversion + + + Most people use GConf via the high-level #GConfClient API. + The corresponding API is the #GSettings object. While not + every GConfClient function has a direct GSettings equivalent, + many do: + + + + GConfClientGSettings + + + gconf_client_get_default()no direct equivalent, + instead you call g_settings_new() for the schemas you use + gconf_client_set()g_settings_set() + gconf_client_get()g_settings_get() + gconf_client_get_bool()g_settings_get_boolean() + gconf_client_set_bool()g_settings_set_boolean() + gconf_client_get_int()g_settings_get_int() + gconf_client_set_int()g_settings_set_int() + gconf_client_get_float()g_settings_get_double() + gconf_client_set_float()g_settings_set_double() + gconf_client_get_string()g_settings_get_string() + gconf_client_set_string()g_settings_set_string() + gconf_client_get_list()for string lists, see g_settings_get_strv(), else see g_settings_get_value() and #GVariant API + gconf_client_set_list()for string lists, see g_settings_set_strv(), else see g_settings_set_value() and #GVariant API + gconf_entry_get_is_writable()g_settings_is_writable() + gconf_client_notify_add()not required, the #GSettings::changed signal is emitted automatically + gconf_client_add_dir()not required, each GSettings instance automatically watches all keys in its path + #GConfChangeSetg_settings_delay(), g_settings_apply() + gconf_client_get_default_from_schema()no equivalent, applications are expected to know their schema + gconf_client_all_entries()no equivalent, applications are expected to know their schema, and GSettings does not allow schema-less entries + gconf_client_get_without_default()no equivalent + gconf_bridge_bind_property()g_settings_bind() + gconf_bridge_bind_property_full()g_settings_bind_with_mapping() + + +
+
+ + GConfBridge was a third-party library that used GConf to bind an object property + to a particular configuration key. GSettings offers this service itself. + + + There is a pattern that is sometimes used for GConf, where a setting can have + explicit 'value A', explicit 'value B' or 'use the system default'. With GConf, + 'use the system default' is sometimes implemented by unsetting the user value. + + + This is not possible in GSettings, since it does not have API to determine if a value + is the default and does not let you unset values. The recommended way (and much + clearer) way in which this can be implemented in GSettings is to have a separate + 'use-system-default' boolean setting. + +
+ +
+ Change notification + + + GConf requires you to call gconf_client_add_dir() and + gconf_client_notify_add() to get change notification. With + GSettings, this is not necessary; signals get emitted automatically + for every change. + + + The #GSettings::changed signal is emitted for each changed key. + There is also a #GSettings::change-event signal that you can handle + if you need to see groups of keys that get changed at the same time. + + + GSettings also notifies you about changes in writability of keys, + with the #GSettings::writable-changed signal (and the + #GSettings::writable-change-event signal). + +
+ +
Change sets + + GConf has a concept of a set of changes which can be applied or reverted + at once: #GConfChangeSet (GConf doesn't actually apply changes atomically, + which is one of its shortcomings). + + + Instead of a separate object to represent a change set, GSettings has a + 'delayed-apply' mode, which can be turned on for a GSettings object by + calling g_settings_delay(). In this mode, changes done to the GSettings + object are not applied - they are still visible when calling g_settings_get() + on the same object, but not to other GSettings instances + or even other processes. + + + To apply the pending changes all at once (GSettings does + atomicity here), call g_settings_apply(). To revert the pending changes, + call g_settings_revert() or just drop the reference to the #GSettings object. + +
+ +
+ Schema conversion + + + If you are porting your application from GConf, most likely you already + have a GConf schema. GConf comes with a commandline tool + gsettings-schema-convert that can help with the task of converting + a GConf schema into an equivalent GSettings schema. The tool is not + perfect and may need assistance in some cases. + + An example for using gsettings-schema-convert + Running gsettings-schema-convert --gconf --xml --schema-id "org.gnome.font-rendering" --output org.gnome.font-rendering.gschema.xml destop_gnome_font_rendering.schemas on the following desktop_gnome_font_rendering.schemas file: + + + + + + /schemas/desktop/gnome/font_rendering/dpi + /desktop/gnome/font_rendering/dpi + gnome + int + 96 + + DPI + The resolution used for converting font sizes to pixel sizes, in dots per inch. + + + + +]]> + +produces a org.gnome.font-rendering.gschema.xml file with the following content: + + + + + 96 + DPI + The resolution used for converting font sizes to pixel sizes, in dots per inch. + + + +]]> + + + + + + GSettings schemas are identified at runtime by their id (as specified + in the XML source file). It is recommended to use a dotted name as schema + id, similar in style to a D-Bus bus name, e.g. "org.gnome.SessionManager". + In cases where the settings are general and not specific to one application, + the id should not use StudlyCaps, e.g. "org.gnome.font-rendering". + The filename used for the XML schema source is immaterial, but + schema compiler expects the files to have the extension + .gschema.xml. It is recommended to simply + use the schema id as the filename, followed by this extension, + e.g. org.gnome.SessionManager.gschema.xml. + + + + The XML source file for your GSettings schema needs to get installed + into $datadir/glib-2.0/schemas, and needs to be + compiled into a binary form. At runtime, GSettings looks for compiled + schemas in the glib-2.0/schemas subdirectories + of all XDG_DATA_DIRS directories, so if you install + your schema in a different location, you need to set the + XDG_DATA_DIRS environment variable appropriately. + + + Schemas are compiled into binary form by the + glib-compile-schemas utility. + GIO provides a glib_compile_schemas + variable for the schema compiler. + + + You can ignore all of this by using the provided m4 macros. To + do this, add to your configure.ac: + +GLIB_GSETTINGS + + The corresponding Makefile.am fragment looks like + this: + +# gsettings_SCHEMAS is a list of all the schemas you want to install +gsettings_SCHEMAS = my.app.gschema.xml + +# include the appropriate makefile rules for schema handling +@GSETTINGS_RULES@ + + + + + This is not sufficient on its own. You need to mention what the source + of the my.app.gschema.xml file is. If the schema + file is distributed directly with your project's tarball then a mention + in EXTRA_DIST is appropriate. If the schema file is + generated from another source then you will need the appropriate rule + for that, plus probably an item in EXTRA_DIST for the + source files used by that rule. + + + + One possible pitfall in doing schema conversion is that the default + values in GSettings schemas are parsed by the #GVariant parser. + This means that strings need to include quotes in the XML. Also note + that the types are now specified as #GVariant type strings. + +string +rgb +]]> + + becomes + + + 'rgb' + +]]> + + + + Another possible complication is that GConf specifies full paths + for each key, while a GSettings schema has a 'path' attribute that + contains the prefix for all the keys in the schema, and individual + keys just have a simple name. So + +/schemas/desktop/gnome/font_rendering/antialiasing +]]> + + becomes + + + +]]> + + + + Default values can be localized in both GConf and GSettings schemas, + but GSettings uses gettext for the localization. You can specify + the gettext domain to use in the gettext-domain + attribute. Therefore, when converting localized defaults in GConf, + +/schemas/apps/my_app/font_size + + 18 + + + 24 + + +]]> + + becomes + + + ... + + 18 + +]]> + + + + GSettings uses gettext for translation of default values. + The string that is translated is exactly the string that appears + inside of the default element. This + includes the quotation marks that appear around strings. + Default values must be marked with the l10n + attribute in the default tag, which + should be set as equal to 'messages' or + 'time' depending on the desired category. An + optional translation context can also be specified with the + context attribute, as in the example. This + is usually recommended, since the string "18" + is not particularly easy to translate without context. The + translated version of the default value should be stored in the + specified gettext-domain. Care must be taken + during translation to ensure that all translated values remain + syntactically valid; mistakes here will cause runtime errors. + + + GSettings schemas have optional summary and + description elements for each key which + correspond to the short and + long elements in the GConf schema and + will be used in similar ways by a future gsettings-editor, so you + should use the same conventions for them: The summary is just a short + label with no punctuation, the description can be one or more complete + sentences. If multiple paragraphs are desired for the description, the + paragraphs should be separated by a completely empty line. + + + Translations for these strings will also be handled + via gettext, so you should arrange for these strings to be + extracted into your gettext catalog. One way to do that is to use + intltool. Since intltool 0.50.1, schema files are + supported, so all you have to do is to add your .gschema.xml + files to POTFILES.in with a line like + + [type: gettext/gsettings]data/org.foo.MyApp.gschema.xml + + + + GSettings is a bit more restrictive about key names than GConf. Key + names in GSettings can be at most 32 characters long, and must only + consist of lowercase characters, numbers and dashes, with no + consecutive dashes. The first character must not be a number or dash, + and the last character cannot be '-'. + + + If you are using the GConf backend for GSettings during the + transition, you may want to keep your key names the same they + were in GConf, so that existing settings in the users GConf + database are preserved. You can achieve this by using the + with the + glib-compile-schemas schema + compiler. Note that this option is only meant + to ease the process of porting your application, allowing parts + of your application to continue to access GConf and parts to use + GSettings. By the time you have finished porting your application + you must ensure that all key names are valid. + +
+ +
Data conversion + + GConf comes with a GSettings backend that can be used to + facility the transition to the GSettings API until you are + ready to make the jump to a different backend (most likely + dconf). To use it, you need to set the GSETTINGS_BACKEND + to 'gconf', e.g. by using + + g_setenv ("GSETTINGS_BACKEND", "gconf", TRUE); + + early on in your program. Note that this backend is meant purely + as a transition tool, and should not be used in production. + + + GConf also comes with a utility called + gsettings-data-convert, which is designed to help + with the task of migrating user settings from GConf into another + GSettings backend. It can be run manually, but it is designed to be + executed automatically, every time a user logs in. It keeps track of + the data migrations that it has already done, and it is harmless to + run it more than once. + + + To make use of this utility, you must install a keyfile in the + directory /usr/share/GConf/gsettings which + lists the GSettings keys and GConf paths to map to each other, for + each schema that you want to migrate user data for. + + + Here is an example: + + + + The last key demonstrates that it may be necessary to modify the key + name to comply with stricter GSettings key name rules. Of course, + that means your application must use the new key names when looking + up settings in GSettings. + + + The last group in the example also shows how to handle the case + of 'relocatable' schemas, which don't have a fixed path. You can + specify the path to use in the group name, separated by a colon. + + + There are some limitations: gsettings-data-convert + does not do any transformation of the values. And it does not handle + complex GConf types other than lists of strings or integers. + + + Don't forget to require GConf 2.31.1 or newer in your configure + script if you are making use of the GConf backend or the conversion + utility. + + + + If, as an application developer, you are interested in manually + ensuring that gsettings-data-convert has been + invoked (for example, to deal with the case where the user is + logged in during a distribution upgrade or for non-XDG desktop + environments which do not run the command as an autostart) you + may invoke it manually during your program initialisation. This + is not recommended for all application authors -- it is your + choice if this use case concerns you enough. + + + Internally, gsettings-data-convert uses a + keyfile to track which settings have been migrated. The + following code fragment will check that keyfile to see if your + data conversion script has been run yet and, if not, will + attempt to invoke the tool to run it. You should adapt it to + your application as you see fit. + + + + + + + + Although there is the possibility that the + gsettings-data-convert script will end up + running multiple times concurrently with this approach, it is + believed that this is safe. + +
+ diff --git a/docs/reference/gio/migrating-gdbus.xml b/docs/reference/gio/migrating-gdbus.xml new file mode 100644 index 0000000..dc4ee75 --- /dev/null +++ b/docs/reference/gio/migrating-gdbus.xml @@ -0,0 +1,310 @@ + + + +]> + + Migrating to GDBus + +
+ Conceptual differences + + + The central concepts of D-Bus are modelled in a very similar way + in dbus-glib and GDBus. Both have objects representing connections, + proxies and method invocations. But there are some important + differences: + + + dbus-glib uses the libdbus + reference implementation, GDBus doesn't. Instead, it + relies on GIO streams as transport layer, and has its own + implementation for the D-Bus connection setup and + authentication. Apart from using streams as transport, + avoiding libdbus also lets GDBus avoid some thorny + multithreading issues. + + + dbus-glib uses the GObject type system for method arguments and + return values, including a homegrown container specialization + mechanism. GDBus relies on the #GVariant type system which is + explicitly designed to match D-Bus types. + + + dbus-glib models only D-Bus interfaces and does not provide + any types for objects. GDBus models both D-Bus interfaces + (via the #GDBusInterface, #GDBusProxy and + #GDBusInterfaceSkeleton types) and objects (via the + #GDBusObject, #GDBusObjectSkeleton and #GDBusObjectProxy types). + + + GDBus includes native support for the org.freedesktop.DBus.Properties (via the #GDBusProxy type) and org.freedesktop.DBus.ObjectManager D-Bus interfaces, dbus-glib doesn't. + + + The typical way to export an object in dbus-glib involves + generating glue code from XML introspection data using + dbus-binding-tool. GDBus provides a + similar tool called gdbus-codegen that + can also generate Docbook D-Bus interface documentation. + + + dbus-glib doesn't provide any convenience API for owning and + watching bus names, GDBus provides the g_bus_own_name() and + g_bus_watch_name() family of convenience functions. + + + GDBus provides API to parse, generate and work with Introspection + XML, dbus-glib doesn't. + + + GTestDBus provides API to create isolated unit tests GDBus Test Scaffolding. + + + +
+ +
+ API comparison + + + dbus-glib APIs and their GDBus counterparts + + + dbus-glibGDBus + + + #DBusGConnection#GDBusConnection + #DBusGProxy#GDBusProxy, #GDBusInterface - also see #GDBusObjectProxy + #DBusGObject#GDBusInterfaceSkeleton, #GDBusInterface - also see #GDBusObjectSkeleton + #DBusGMethodInvocation#GDBusMethodInvocation + dbus_g_bus_get()g_bus_get_sync(), also see + g_bus_get() + dbus_g_proxy_new_for_name()g_dbus_proxy_new_sync() and + g_dbus_proxy_new_for_bus_sync(), also see g_dbus_proxy_new() + dbus_g_proxy_add_signal()not needed, use the generic #GDBusProxy::g-signal + dbus_g_proxy_connect_signal()use g_signal_connect() with #GDBusProxy::g-signal + dbus_g_connection_register_g_object()g_dbus_connection_register_object() - also see g_dbus_object_manager_server_export() + dbus_g_connection_unregister_g_object()g_dbus_connection_unregister_object() - also see g_dbus_object_manager_server_unexport() + dbus_g_object_type_install_info()introspection data is installed while registering + an object, see g_dbus_connection_register_object() + dbus_g_proxy_begin_call()g_dbus_proxy_call() + dbus_g_proxy_end_call()g_dbus_proxy_call_finish() + dbus_g_proxy_call()g_dbus_proxy_call_sync() + dbus_g_error_domain_register()g_dbus_error_register_error_domain() + dbus_g_error_has_name()no direct equivalent, see g_dbus_error_get_remote_error() + dbus_g_method_return()g_dbus_method_invocation_return_value() + dbus_g_method_return_error()g_dbus_method_invocation_return_error() and variants + dbus_g_method_get_sender()g_dbus_method_invocation_get_sender() + + +
+
+ +
+ Owning bus names + + Using dbus-glib, you typically call RequestName manually + to own a name, like in the following excerpt: + message); + g_error_free (error); + } + else + { + g_warning ("Failed to acquire %s", NAME_TO_CLAIM); + } + goto out; + } + + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) + { + if (error != NULL) + { + g_warning ("Failed to acquire %s: %s", + NAME_TO_CLAIM, error->message); + g_error_free (error); + } + else + { + g_warning ("Failed to acquire %s", NAME_TO_CLAIM); + } + exit (1); + } + + dbus_g_proxy_add_signal (system_bus_proxy, "NameLost", + G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (system_bus_proxy, "NameLost", + G_CALLBACK (on_name_lost), NULL, NULL); + + /* further setup ... */ +]]> + + + + While you can do things this way with GDBus too, using + g_dbus_proxy_call_sync(), it is much nicer to use the high-level API + for this: + + + Note that g_bus_own_name() works asynchronously and requires + you to enter your mainloop to await the on_name_aquired() + callback. Also note that in order to avoid race conditions (e.g. + when your service is activated by a method call), you have to export + your manager object before acquiring the + name. The on_bus_acquired() callback is the right place to do + such preparations. + +
+ +
+ Creating proxies for well-known names + + dbus-glib lets you create proxy objects for well-known names, like the + following example: + + + For a #DBusGProxy constructed like this, method calls will be sent to + the current owner of the name, and that owner can change over time. + + + The same can be achieved with #GDBusProxy: + + + For an added layer of safety, you can specify what D-Bus + interface the proxy is expected to conform to by using the + #GDBusInterfaceInfo type. Additionally, #GDBusProxy loads, + caches and tracks changes to the D-Bus properties on the remote + object. It also sets up match rules so D-Bus signals from the + remote object are delivered locally. + + + The #GDBusProxy type normally isn't used directly - instead + proxies subclassing #GDBusProxy generated by gdbus-codegen is used, see + +
+ +
+ Generating code and docs + +
+ Using gdbus-codegen + + + dbus-glib comes with dbus-binding-tool, which + can produce somewhat nice client- and server-side wrappers for a D-Bus interface. + With GDBus, gdbus-codegen is used and like + its counterpart, it also takes D-Bus Introspection XML as input: + + Example D-Bus Introspection XMLFIXME: MISSING XINCLUDE CONTENT: gdbus-example-objectmanager.xml + + If this XML is processed like this + + then two files generated-code.h and + generated-code.c are + generated. Additionally, two XML files + generated-docs-org.gtk.GDBus.Example.ObjectManager.Animal and + generated-docs-org.gtk.GDBus.Example.ObjectManager.Cat + with Docbook XML are generated. For an example of what the docs look + like see the Animal D-Bus interface documentation. + and + the Cat D-Bus interface documentation. + + + While the contents of generated-code.h and + generated-code.c are best described by the + gdbus-codegen manual + page, brief examples of how this generated code can be used can be found in + + and . Additionally, since + the generated code has 100% gtk-doc coverage, see + #ExampleAnimal, #ExampleCat, #ExampleObject and + #ExampleObjectManagerClient pages for documentation. + + + Server-side application using generated codeFIXME: MISSING XINCLUDE CONTENT: gdbus-example-objectmanager-server.c + + Client-side application using generated codeFIXME: MISSING XINCLUDE CONTENT: gdbus-example-objectmanager-client.c + +
+ + + FIXME: MISSING XINCLUDE CONTENT: objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Animal.xml + FIXME: MISSING XINCLUDE CONTENT: objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Cat.xml + FIXME: MISSING XINCLUDE CONTENT: ExampleAnimal.xml + FIXME: MISSING XINCLUDE CONTENT: ExampleCat.xml + FIXME: MISSING XINCLUDE CONTENT: ExampleObject.xml + FIXME: MISSING XINCLUDE CONTENT: ExampleObjectManagerClient.xml + +
+ +
diff --git a/docs/reference/gio/migrating-gnome-vfs.xml b/docs/reference/gio/migrating-gnome-vfs.xml new file mode 100644 index 0000000..27194aa --- /dev/null +++ b/docs/reference/gio/migrating-gnome-vfs.xml @@ -0,0 +1,133 @@ + + Migrating from GnomeVFS to GIO + + + Comparison of GnomeVFS and GIO concepts + + + GnomeVFSGIO + + + GnomeVFSURIGFile + GnomeVFSFileInfoGFileInfo + GnomeVFSResultGError, with G_IO_ERROR values + GnomeVFSHandle & GnomeVFSAsyncHandleGInputStream or GOutputStream + GnomeVFSDirectoryHandleGFileEnumerator + mime typecontent type + GnomeVFSMonitorGFileMonitor + GnomeVFSVolumeMonitorGVolumeMonitor + GnomeVFSVolumeGMount + GnomeVFSDriveGVolume + -GDrive + GnomeVFSContextGCancellable + gnome_vfs_async_cancelg_cancellable_cancel + + +
+ +
+ Trash handling + + + The handling of trashed files has been changed in GIO, compared + to gnome-vfs. gnome-vfs has a home-grown trash implementation that + predates the freedesktop.org Desktop Trash Can specification + that is implemented in GIO. The location for storing trashed files + has changed from $HOME/.Trash to + $HOME/.local/share/Trash (or more correctly + $XDG_DATA_HOME/Trash), which means that + there is a need for migrating files that have been trashed by + gnome-vfs to the new location. + + + In gnome-vfs, the trash:// scheme offering a + merged view of all trash directories was implemented in nautilus, + and trash-handling applications had to find and monitor all trash + directories themselves. With GIO, the trash:// + implementation has been moved to gvfs and applications can simply + monitor that location: + + +static void +file_changed (GFileMonitor *file_monitor, + GFile *child, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + switch (event_type) + { + case G_FILE_MONITOR_EVENT_DELETED: + g_print ("'%s' removed from trash\n", g_file_get_basename (child)); + break; + case G_FILE_MONITOR_EVENT_CREATED: + g_print ("'%s' added to trash\n", g_file_get_basename (child)); + break; + default: ; + } +} + +static void +start_monitoring_trash (void) +{ + GFile *file; + GFileMonitor *monitor; + + file = g_file_new_for_uri ("trash://"); + monitor = g_file_monitor_directory (file, 0, NULL, NULL); + g_object_unref (file); + + g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), NULL); + + /* ... */ + +} + + + GIO exposes some useful metadata about trashed files. There are + trash::orig-path and trash::deletion-date attributes. The + standard::icon attribute of the trash:// + itself provides a suitable icon for displaying the trash can on + the desktop. If you are using this icon, make sure to monitor + this attribute for changes, since the icon may be updated to + reflect that state of the trash can. + + + Moving a file to the trash is much simpler with GIO. Instead of + using gnome_vfs_find_directory() with %GNOME_VFS_DIRECTORY_KIND_TRASH + to find out where to move the trashed file, just use the g_file_trash() + function. + +
+ +
+ Operations on multiple files + + + gnome-vfs has the dreaded gnome_vfs_xfer_uri_list() function which + has tons of options and offers the equivalent of cp, mv, ln, mkdir + and rm at the same time. + + + GIO offers a much simpler I/O scheduler functionality instead, that + lets you schedule a function to be called in a separate thread, or + if threads are not available, as an idle in the mainloop. + See g_io_scheduler_push_job(). + + +
+ +
+ Mime monitoring + + + gnome-vfs offered a way to monitor the association between mime types + and default handlers for changes, with the #GnomeVFSMIMEMonitor object. + GIO does not offer a replacement for this functionality at this time, + since we have not found a compelling use case where + #GnomeVFSMIMEMonitor was used. If you think you have such a use + case, please report it at + https://gitlab.gnome.org/GNOME/glib/issues/new. + +
+
diff --git a/docs/reference/gio/migrating-posix.xml b/docs/reference/gio/migrating-posix.xml new file mode 100644 index 0000000..e7dc9f4 --- /dev/null +++ b/docs/reference/gio/migrating-posix.xml @@ -0,0 +1,27 @@ + + Migrating to GIO + + + Migrating from POSIX to GIO + + + Comparison of POSIX and GIO concepts + + + POSIXGIO + + + char *pathGFile *file + struct stat *bufGFileInfo *info + struct statvfs *bufGFileInfo *info + int fdGInputStream *in + GOutputStream *out + DIR *GFileEnumerator *enum + fstab entryGUnixMountPoint *mount_point + mtab entryGUnixMountEntry *mount_entry + + +
+ +
+
diff --git a/docs/reference/gio/overview.xml b/docs/reference/gio/overview.xml new file mode 100644 index 0000000..f30b142 --- /dev/null +++ b/docs/reference/gio/overview.xml @@ -0,0 +1,745 @@ + + GIO Overview + + + Introduction + + + GIO is striving to provide a modern, easy-to-use VFS API that sits + at the right level in the library stack, as well as other generally + useful APIs for desktop applications (such as networking and + D-Bus support). The goal is to overcome the shortcomings of GnomeVFS + and provide an API that is so good that developers prefer it over raw + POSIX calls. Among other things that means using GObject. It also means + not cloning the POSIX API, but providing higher-level, document-centric + interfaces. + + + + The abstract file system model of GIO consists of a number of + interfaces and base classes for I/O and files: + + + GFile + reference to a file + + + GFileInfo + information about a file or filesystem + + + GFileEnumerator + list files in directories + + + GDrive + represents a drive + + + GVolume + represents a file system in an abstract way + + + GMount + represents a mounted file system + + + Then there is a number of stream classes, similar to the input and + output stream hierarchies that can be found in frameworks like Java: + + + GInputStream + read data + + + GOutputStream + write data + + + GIOStream + read and write data + + + GSeekable + interface optionally implemented by streams to support seeking + + + There are interfaces related to applications and the types + of files they handle: + + + GAppInfo + information about an installed application + + + GIcon + abstract type for file and application icons + + + There is a framework for storing and retrieving application settings: + + + GSettings + stores and retrieves application settings + + + There is support for network programming, including connectivity monitoring, + name resolution, lowlevel socket APIs and highlevel client and server + helper classes: + + + GSocket + lowlevel platform independent socket object + + + GResolver + asynchronous and cancellable DNS resolver + + + GSocketClient + high-level network client helper + + + GSocketService + high-level network server helper + + + GSocketConnection + network connection stream + + + GNetworkMonitor + network connectivity monitoring + + + There is support for connecting to D-Bus, + sending and receiving messages, owning and watching bus names, + and making objects available on the bus: + + + GDBusConnection + a D-Bus connection + + + + GDBusMethodInvocation + for handling remote calls + + + + GDBusServer + helper for accepting connections + + + + GDBusProxy + proxy to access D-Bus interfaces on a remote object + + + + Beyond these, GIO provides facilities for file monitoring, + asynchronous I/O and filename completion. In addition to the + interfaces, GIO provides implementations for the local case. + Implementations for various network file systems are provided + by the GVFS package as loadable modules. + + + + Other design choices which consciously break with the GnomeVFS + design are to move backends out-of-process, which minimizes the + dependency bloat and makes the whole system more robust. The backends + are not included in GIO, but in the separate GVFS package. The GVFS + package also contains the GVFS daemon, which spawn further mount + daemons for each individual connection. + + +
+ GIO in the GTK+ library stack + +
+ + + The GIO model of I/O is stateful: if an application establishes e.g. + a SFTP connection to a server, it becomes available to all applications + in the session; the user does not have to enter their password over + and over again. + + + One of the big advantages of putting the VFS in the GLib layer + is that GTK+ can directly use it, e.g. in the filechooser. + +
+ + + Writing GIO applications + + + The information in the GLib documentation about writing GLib + applications is generally applicable when writing GIO applications. + + + Threads + + + GDBus has its own private worker thread, so applications using + GDBus have at least 3 threads. GIO makes heavy use of the concept + of a thread-default + main context to execute callbacks of asynchronous + methods in the same context in which the operation was started. + + + + + Asynchronous Programming + + + Many GIO functions come in two versions: synchronous and asynchronous, + denoted by an _async suffix. It is important to use these + appropriately: synchronous calls should not be used from + within a main loop which is shared with other code, such as one in the + application’s main thread. Synchronous calls block until they complete, + and I/O operations can take noticeable amounts of time (even on ‘fast’ + SSDs). Blocking a main loop iteration while waiting for I/O means that + other sources in the main loop will not be dispatched, such as input and + redraw handlers for the application’s UI. This can cause the application + to ‘freeze’ until I/O completes. + + + + A few self-contained groups of functions, such as code generated by + gdbus-codegen, + use a different convention: functions are asynchronous default, and it is + the synchronous version which has a + _sync + suffix. Aside from naming differences, they should be treated the same + way as functions following the normal convention above. + + + + The asynchronous (_async) versions of functions return + control to the caller immediately, after scheduling the I/O in the kernel + and adding a callback for it to the main loop. This callback will be + invoked when the operation has completed. From the callback, the paired + _finish function should be called to retrieve the return + value of the I/O operation, and any errors which occurred. For more + information on using and implementing asynchronous functions, see + GAsyncResult + and GTask. + + + + By starting multiple asynchronous operations in succession, they will be + executed in parallel (up to an arbitrary limit imposed by GIO’s internal + worker thread pool). + + + + The synchronous versions of functions can be used early in application + startup when there is no main loop to block, for example to load initial + configuration files. They can also be used for I/O on files which are + guaranteed to be small and on the local disk. Note that the user’s home + directory is not guaranteed to be on the local disk. + + + + Security + + +When your program needs to carry out some privileged operation (say, +create a new user account), there are various ways in which you can go +about this: + + +Implement a daemon that offers the privileged operation. A convenient +way to do this is as a D-Bus system-bus service. The daemon will probably +need ways to check the identity and authorization of the caller before +executing the operation. polkit is a framework that allows this. + + +Use a small helper that is executed with elevated privileges via +pkexec. pkexec is a small program launcher that is part of polkit. + + +Use a small helper that is executed with elevated privileges by +being suid root. + + +None of these approaches is the clear winner, they all have their +advantages and disadvantages. + + + +When writing code that runs with elevated privileges, it is important +to follow some basic rules of secure programming. David Wheeler has an +excellent book on this topic, +Secure Programming for Linux and Unix HOWTO. + + + +When using GIO in code that runs with elevated privileges, you have to +be careful. GIO has extension points whose implementations get loaded +from modules (executable code in shared objects), which could allow +an attacker to sneak their own code into your application by tricking it +into loading the code as a module. However, GIO will never load modules +from your home directory except when explicitly asked to do so via an +environment variable. + + + +In most cases, your helper program should be so small that you don't +need GIO, whose APIs are largely designed to support full-blown desktop +applications. If you can't resist the convenience of these APIs, here +are some steps you should take: + + +Clear the environment, e.g. using the clearenv() +function. +David Wheeler has a good explanation for why it is +important to sanitize the environment. +See +for a list of all environment variables affecting GIO. In particular, +PATH (used to locate binaries), GIO_EXTRA_MODULES (used to locate loadable modules) and DBUS_{SYSTEM,SESSION}_BUS_ADDRESS (used to locate the D-Bus system and session bus) are important. + + +Don't use GVfs, by setting GIO_USE_VFS=local in the environment. +The reason to avoid GVfs in security-sensitive programs is that it uses +many libraries which have not necessarily been audited for security problems. +Gvfs is also heavily distributed and relies on a session bus to be present. + + + + + + + + + + Compiling GIO applications + + + GIO comes with a gio-2.0.pc file that you + should use together with pkg-config to obtain + the necessary information about header files and libraries. See + the pkg-config man page or the GLib documentation + for more information on how to use pkg-config + to compile your application. + + + + If you are using GIO on UNIX-like systems, you may want to use + UNIX-specific GIO interfaces such as #GUnixInputStream, + #GUnixOutputStream, #GUnixMount or #GDesktopAppInfo. + To do so, use the gio-unix-2.0.pc file + instead of gio-2.0.pc + + + + + Running GIO applications + + + GIO inspects a few environment variables in addition to the + ones used by GLib. + + + + <envar>XDG_DATA_HOME</envar>, <envar>XDG_DATA_DIRS</envar> + + + GIO uses these environment variables to locate MIME information. + For more information, see the Shared MIME-info Database + and the Base Directory Specification. + + + + + <envar>GVFS_DISABLE_FUSE</envar> + + + This variable can be set to keep #Gvfs from starting the fuse backend, + which may be unwanted or unnecessary in certain situations. + + + + + <envar>GIO_USE_VFS</envar> + + + This environment variable can be set to the name of a #GVfs + implementation to override the default for debugging purposes. + The #GVfs implementation for local files that is included in GIO + has the name "local", the implementation in the gvfs module has + the name "gvfs". Most commonly, system software will set this to "local" + to avoid having `GFile` APIs perform unnecessary D-Bus calls. + + The special value help can be used to print a list of + available implementations to standard output. + + + + + The following environment variables are only useful for debugging + GIO itself or modules that it loads. They should not be set in a + production environment. + + + + <envar>GIO_USE_FILE_MONITOR</envar> + + + This variable can be set to the name of a #GFileMonitor + implementation to override the default for debugging purposes. + The #GFileMonitor implementation for local files that is included + in GIO on Linux has the name inotify, others that are built + are built as modules (depending on the platform) are called + fam and fen. + + The special value help can be used to print a list of + available implementations to standard output. + + + + + <envar>GIO_USE_VOLUME_MONITOR</envar> + + + This variable can be set to the name of a #GVolumeMonitor + implementation to override the default for debugging purposes. + The #GVolumeMonitor implementation for local files that is included + in GIO has the name "unix", the udisks2-based implementation in the + gvfs module has the name "udisks2". + + The special value help can be used to print a list of + available implementations to standard output. + + + + + <envar>GIO_USE_TLS</envar> + + + This variable can be set to the name of a #GTlsBackend + implementation to override the default for debugging purposes. + GIO does not include a #GTlsBackend implementation, the gnutls-based + implementation in the glib-networking module has the name "gnutls". + + The special value help can be used to print a list of + available implementations to standard output. + + + + + <envar>GIO_MODULE_DIR</envar> + + + When this environment variable is set to a path, GIO will load + modules from this alternate directory instead of the directory + built into GIO. This is useful when running tests, for example. + + + This environment variable is ignored when running in a setuid program. + + + + + <envar>GIO_EXTRA_MODULES</envar> + + + When this environment variable is set to a path, or a set of + paths separated by a colon, GIO will attempt to load + additional modules from within the path. + + + This environment variable is ignored when running in a setuid program. + + + + + <envar>GSETTINGS_BACKEND</envar> + + + This variable can be set to the name of a #GSettingsBackend + implementation to override the default for debugging purposes. + The memory-based implementation that is included in GIO has + the name "memory", the one in dconf has the name "dconf". + + The special value help can be used to print a list of + available implementations to standard output. + + + + + <envar>GSETTINGS_SCHEMA_DIR</envar> + + + This variable can be set to the names of directories to consider when looking for compiled schemas for #GSettings, + in addition to the glib-2.0/schemas + subdirectories of the XDG system data dirs. To specify multiple directories, use G_SEARCHPATH_SEPARATOR_S as a separator. + + + + + <envar>DBUS_SYSTEM_BUS_ADDRESS</envar> + + + This variable is consulted to find the address of the D-Bus system + bus. For the format of D-Bus addresses, see the D-Bus + specification. + + + Setting this variable overrides platform-specific ways of determining + the system bus address. + + + + + <envar>DBUS_SESSION_BUS_ADDRESS</envar> + + + This variable is consulted to find the address of the D-Bus session bus. + + + Setting this variable overrides platform-specific ways of determining + the session bus address. + + + + + <envar>DBUS_STARTER_BUS_TYPE</envar> + + + This variable is consulted to find out the 'starter' bus for an + application that has been started via D-Bus activation. The possible + values are 'system' or 'session'. + + + + + <envar>G_DBUS_DEBUG</envar> + + + This variable can be set to a list of debug options, which + cause GLib to print out different types of debugging + information when using the D-Bus routines. + + + transport + Show IO activity (e.g. reads and writes) + + + message + Show all sent and received D-Bus messages + + + payload + Show payload for all sent and received D-Bus messages (implies message) + + + call + Trace g_dbus_connection_call() and g_dbus_connection_call_sync() API usage + + + signal + Show when a D-Bus signal is received + + + incoming + Show when an incoming D-Bus method call is received + + + return + Show when a reply is returned via the #GDBusMethodInvocation API + + + emission + Trace g_dbus_connection_emit_signal() API usage + + + authentication + Show information about connection authentication + + + address + Show information about D-Bus address lookups and autolaunching + + + The special value all can be used to turn + on all debug options. The special value + help can be used to print a list of + supported options to standard output. + + + + + <envar>G_DBUS_COOKIE_SHA1_KEYRING_DIR</envar> + + + Can be used to override the directory used to store the + keyring used in the DBUS_COOKIE_SHA1 + authentication mechanism. Normally the directory used is + .dbus-keyrings in the user's home + directory. + + + + + <envar>G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION</envar> + + + If set, the permissions of the directory used to store the + keyring used in the DBUS_COOKIE_SHA1 + authentication mechanism won't be checked. Normally the + directory must be readable only by the user. + + + + + + Extending GIO + + + A lot of the functionality that is accessible through GIO + is implemented in loadable modules, and modules provide a convenient + way to extend GIO. In addition to the #GIOModule API which supports + writing such modules, GIO has a mechanism to define extension points, + and register implementations thereof, see #GIOExtensionPoint. + + + The following extension points are currently defined by GIO: + + + + G_VFS_EXTENSION_POINT_NAME + + + Allows to override the functionality of the #GVfs class. + Implementations of this extension point must be derived from #GVfs. + GIO uses the implementation with the highest priority that is active, + see g_vfs_is_active(). + + + GIO implements this extension point for local files, gvfs contains + an implementation that supports all the backends in gvfs. + + + + + G_VOLUME_MONITOR_EXTENSION_POINT_NAME + + + Allows to add more volume monitors. + Implementations of this extension point must be derived from + #GVolumeMonitor. GIO uses all registered extensions. + + + gvfs contains an implementation that works together with the #GVfs + implementation in gvfs. + + + + + G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME + + + Allows to override the 'native' volume monitor. + Implementations of this extension point must be derived from + #GNativeVolumeMonitor. GIO uses the implementation with + the highest priority that is supported, as determined by the + is_supported() vfunc in #GVolumeMonitorClass. + + + GIO implements this extension point for local mounts, + gvfs contains a udisks2-based implementation. + + + + + G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME + + + Allows to override the file monitor implementation for + local files. Implementations of this extension point must + be derived from #GLocalFileMonitor. GIO uses the implementation + with the highest priority that is supported, as determined by the + is_supported() vfunc in #GLocalFileMonitorClass. + + + GIO uses this extension point internally, to switch between + its fam-based and inotify-based file monitoring implementations. + + + + + G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME + + + Unix-only. Allows to provide a way to associate default handlers + with URI schemes. Implementations of this extension point must + implement the #GDesktopAppInfoLookup interface. GIO uses the + implementation with the highest priority. + + + This extension point has been discontinued in GLib 2.28. It is + still available to keep API and ABI stability, but GIO is no + longer using it for default handlers. Instead, the mime handler + mechanism is used, together with x-scheme-handler pseudo-mimetypes. + + + + + G_SETTINGS_BACKEND_EXTENSION_POINT_NAME + + + Allows to provide an alternative storage for #GSettings. + Implementations of this extension point must derive from the + #GSettingsBackend type. GIO contains a keyfile-based + implementation of this extension point, another one is provided + by dconf. + + + + + G_PROXY_EXTENSION_POINT_NAME + + + Allows to provide implementations for network proxying. + Implementations of this extension point must provide the + #GProxy interface, and must be named after the network + protocol they are proxying. + + + glib-networking contains an implementation of this extension + point based on libproxy. + + + + G_TLS_BACKEND_EXTENSION_POINT_NAME + + + Allows to provide implementations for TLS support. + Implementations of this extension point must implement + the #GTlsBackend interface. + + + glib-networking contains an implementation of this extension + point. + + + + + G_NETWORK_MONITOR_EXTENSION_POINT_NAME + + + Allows to provide implementations for network connectivity + monitoring. + Implementations of this extension point must implement + the #GNetworkMonitorInterface interface. + + + GIO contains an implementation of this extension point + that is using the netlink interface of the Linux kernel. + + + +
+ diff --git a/docs/reference/gio/version.xml.in b/docs/reference/gio/version.xml.in new file mode 100644 index 0000000..d78bda9 --- /dev/null +++ b/docs/reference/gio/version.xml.in @@ -0,0 +1 @@ +@VERSION@ diff --git a/docs/reference/gio/xml/gtkdocentities.ent.in b/docs/reference/gio/xml/gtkdocentities.ent.in new file mode 100644 index 0000000..f12c9ff --- /dev/null +++ b/docs/reference/gio/xml/gtkdocentities.ent.in @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/reference/gio/xml/meson.build b/docs/reference/gio/xml/meson.build new file mode 100644 index 0000000..6aeb745 --- /dev/null +++ b/docs/reference/gio/xml/meson.build @@ -0,0 +1,14 @@ +ent_conf = configuration_data() +ent_conf.set('PACKAGE', 'glib') +ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new') +ent_conf.set('PACKAGE_NAME', 'glib') +ent_conf.set('PACKAGE_STRING', 'glib') +ent_conf.set('PACKAGE_TARNAME', 'glib') +ent_conf.set('PACKAGE_URL', 'FIXME') +ent_conf.set('PACKAGE_VERSION', glib_version) +ent_conf.set('PACKAGE_API_VERSION', glib_api_version) +configure_file( + input: 'gtkdocentities.ent.in', + output: 'gtkdocentities.ent', + configuration: ent_conf +) diff --git a/docs/reference/glib/Sorted_binary_tree_breadth-first_traversal.svg b/docs/reference/glib/Sorted_binary_tree_breadth-first_traversal.svg new file mode 100644 index 0000000..697d7db --- /dev/null +++ b/docs/reference/glib/Sorted_binary_tree_breadth-first_traversal.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + sorted_binary_tree + + C + + C + + + E + + E + + + H + + H + + + A + + A + + + D + + D + + + D->C + + + + + D->E + + + + + I + + I + + + I->H + + + + + B + + B + + + B->A + + + + + B->D + + + + + G + + G + + + G->I + + + + + F + + F + + + F->B + + + + + F->G + + + + + diff --git a/docs/reference/glib/Sorted_binary_tree_inorder.svg b/docs/reference/glib/Sorted_binary_tree_inorder.svg new file mode 100644 index 0000000..3927430 --- /dev/null +++ b/docs/reference/glib/Sorted_binary_tree_inorder.svg @@ -0,0 +1,753 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + sorted_binary_tree + + C + + C + + + E + + E + + + H + + H + + + A + + A + + + D + + D + + + D->C + + + + + D->E + + + + + I + + I + + + I->H + + + + + B + + B + + + B->A + + + + + B->D + + + + + G + + G + + + G->I + + + + + F + + F + + + F->B + + + + + F->G + + + + + + + + + + + + + + + + diff --git a/docs/reference/glib/Sorted_binary_tree_postorder.svg b/docs/reference/glib/Sorted_binary_tree_postorder.svg new file mode 100644 index 0000000..1160e42 --- /dev/null +++ b/docs/reference/glib/Sorted_binary_tree_postorder.svg @@ -0,0 +1,750 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + sorted_binary_tree + + C + + C + + + E + + E + + + H + + H + + + A + + A + + + D + + D + + + D->C + + + + + D->E + + + + + I + + I + + + I->H + + + + + B + + B + + + B->A + + + + + B->D + + + + + G + + G + + + G->I + + + + + F + + F + + + F->B + + + + + F->G + + + + + + + + + + + + + + + + diff --git a/docs/reference/glib/Sorted_binary_tree_preorder.svg b/docs/reference/glib/Sorted_binary_tree_preorder.svg new file mode 100644 index 0000000..ae3d22c --- /dev/null +++ b/docs/reference/glib/Sorted_binary_tree_preorder.svg @@ -0,0 +1,750 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + sorted_binary_tree + + C + + C + + + E + + E + + + H + + H + + + A + + A + + + D + + D + + + D->C + + + + + D->E + + + + + I + + I + + + I->H + + + + + B + + B + + + B->A + + + + + B->D + + + + + G + + G + + + G->I + + + + + F + + F + + + F->B + + + + + F->G + + + + + + + + + + + + + + + + diff --git a/docs/reference/glib/building.xml b/docs/reference/glib/building.xml new file mode 100644 index 0000000..d165c5c --- /dev/null +++ b/docs/reference/glib/building.xml @@ -0,0 +1,365 @@ + + + + + Compiling the GLib package + 3 + GLib Library + + + + Compiling the GLib Package + How to compile GLib itself + + + + Building the Library on UNIX + + On UNIX, GLib uses the standard Meson build + system. The normal sequence for compiling and installing the GLib library + is thus: + + + meson _build + ninja -C _build + ninja -C _build install + + + On FreeBSD: + + env CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib -Wl,--disable-new-dtags" meson -Dxattr=false -Dinstalled_tests=true -Diconv=external -Db_lundef=false _build + ninja -C _build + + + + + The standard options provided by Meson may be + passed to the meson command. Please see the + Meson documentation or run + meson configure --help for information about + the standard options. + + + GLib is compiled with + strict aliasing + disabled. It is strongly recommended that this is not re-enabled by + overriding the compiler flags, as GLib has not been tested with strict + aliasing and cannot be guaranteed to work. + + + The GTK+ documentation contains + further details + about the build process and ways to influence it. + + + + Dependencies + + Before you can compile the GLib library, you need to have + various other tools and libraries installed on your system. + If you are building from a release archive, you will need + a compliant C toolchain, + Meson, and pkg-config; + the requirements are the same when building from a Git repository clone + of GLib. + + + + + pkg-config + is a tool for tracking the compilation flags needed for + libraries that are used by the GLib library. (For each + library, a small .pc text file is + installed in a standard location that contains the compilation + flags needed for that library along with version number + information). + + + + + A UNIX build of GLib requires that the system implements at + least the original 1990 version of POSIX. Beyond this, it + depends on a number of other libraries. + + + + + The GNU + libiconv library is needed to build GLib if your + system doesn't have the iconv() + function for doing conversion between character + encodings. Most modern systems should have + iconv(), however many older systems lack + an iconv() implementation. On such systems, + you must install the libiconv library. This can be found at: + http://www.gnu.org/software/libiconv. + + + If your system has an iconv() implementation but + you want to use libiconv instead, you can pass the + option to meson. This + forces libiconv to be used. + + + Note that if you have libiconv installed in your default include + search path (for instance, in /usr/local/), but + don't enable it, you will get an error while compiling GLib because + the iconv.h that libiconv installs hides the + system iconv. + + + If you are using the native iconv implementation on Solaris + instead of libiconv, you'll need to make sure that you have + the converters between locale encodings and UTF-8 installed. + At a minimum you'll need the SUNWuiu8 package. You probably + should also install the SUNWciu8, SUNWhiu8, SUNWjiu8, and + SUNWkiu8 packages. + + + The native iconv on Compaq Tru64 doesn't contain support for + UTF-8, so you'll need to use GNU libiconv instead. (When + using GNU libiconv for GLib, you'll need to use GNU libiconv + for GNU gettext as well.) This probably applies to related + operating systems as well. + + + + + Python 3.5 or newer is required. Your system Python must + conform to PEP 394 + + For FreeBSD, this means that the + lang/python3 port must be installed. + + + + + The libintl library from the GNU gettext + package is needed if your system doesn't have the + gettext() functionality for handling + message translation databases. + + + + + A thread implementation is needed. The thread support in GLib + can be based upon POSIX threads or win32 threads. + + + + + GRegex uses the PCRE library + for regular expression matching. The system version of PCRE is used, + unless not available (which is the case on Android), in which case a + fallback subproject is used. + + + + + The optional extended attribute support in GIO requires the + getxattr() family of functions that may be + provided by the C library or by the standalone libattr library. To + build GLib without extended attribute support, use the + option. + + + + + The optional SELinux support in GIO requires libselinux. + To build GLib without SELinux support, use the + option. + + + + + The optional support for DTrace requires the + sys/sdt.h header, which is provided + by SystemTap on Linux. To build GLib without DTrace, use + the option. + + + + + The optional support for + SystemTap + can be disabled with the + option. Additionally, you can control the location + where GLib installs the SystemTap probes, using the + option. + + + + + + + Extra Configuration Options + + + In addition to the normal options, these additional ones are supported + when configuring the GLib library: + + + + <option>--buildtype</option> + + + This is a standard Meson option which + specifies how much debugging and optimization to enable. If the build + type starts with debug, + G_ENABLE_DEBUG will be defined and GLib will be built + with additional debug code enabled. + + + If the build type is plain, GLib will not enable any + optimization or debug options by default, and will leave it entirely to + the user to choose their options. To build with the options recommended + by GLib developers, choose release. + + + + + <option>-Dforce_posix_threads=true</option> + + + Normally, Meson should be able to work out + the correct thread implementation to use. This option forces POSIX + threads to be used even if the platform provides another threading API + (for example, on Windows). + + + + + <option>-Dbsymbolic_functions=false</option> and + <option>-Dbsymbolic_functions=true</option> + + + By default, GLib uses the + linker flag to avoid intra-library PLT jumps. A side-effect + of this is that it is no longer possible to override + internal uses of GLib functions with + LD_PRELOAD. Therefore, it may make + sense to turn this feature off in some situations. + The option allows + to do that. + + + + + <option>-Dgtk_doc=false</option> and + <option>-Dgtk_doc=true</option> + + + By default, GLib will detect whether the + gtk-doc package is installed. + If it is, then it will use it to extract and build the + documentation for the GLib library. These options + can be used to explicitly control whether + gtk-doc should be + used or not. If it is not used, the distributed, + pre-generated HTML files will be installed instead of + building them on your machine. + + + + + <option>-Dman=false</option> and + <option>-Dman=true</option> + + + By default, GLib will detect whether xsltproc + and the necessary DocBook stylesheets are installed. + If they are, then it will use them to rebuild the included + man pages from the XML sources. These options can be used + to explicitly control whether man pages should be rebuilt + used or not. The distribution includes pre-generated man + pages. + + + + + <option>-Dxattr=false</option> and + <option>-Dxattr=true</option> + + + By default, GLib will detect whether the + getxattr() + family of functions is available. If it is, then extended + attribute support will be included in GIO. These options can + be used to explicitly control whether extended attribute + support should be included or not. getxattr() + and friends can be provided by glibc or by the standalone + libattr library. + + + + + <option>-Dselinux=auto</option>, + <option>-Dselinux=enabled</option> or + <option>-Dselinux=disabled</option> + + + By default, GLib will detect if libselinux is available and + include SELinux support in GIO if it is. These options can be + used to explicitly control whether SELinux support should + be included. + + + + + <option>-Ddtrace=false</option> and + <option>-Ddtrace=true</option> + + + By default, GLib will detect if DTrace support is available, and use it. + These options can be used to explicitly control whether DTrace support + is compiled into GLib. + + + + + <option>-Dsystemtap=false</option> and + <option>-Dsystemtap=true</option> + + + This option requires DTrace support. If it is available, then + GLib will also check for the presence of SystemTap. + + + + + <option>-Db_coverage=true</option> and + <option>-Db_coverage=false</option> + + + Enable the generation of coverage reports for the GLib tests. + This requires the lcov frontend to gcov from the + Linux Test Project. + To generate a coverage report, use + ninja coverage-html. The report is placed in the + meson-logs directory. + + + + + <option>-Druntime_libdir=RELPATH</option> + + + Allows specifying a relative path to where to install the runtime + libraries (meaning library files used for running, not developing, + GLib applications). This can be used in operating system setups where + programs using GLib needs to run before e.g. /usr + is mounted. + For example, if LIBDIR is /usr/lib and + ../../lib is passed to + then the + runtime libraries are installed into /lib rather + than /usr/lib. + + + + + diff --git a/docs/reference/glib/changes.xml b/docs/reference/glib/changes.xml new file mode 100644 index 0000000..9b4aa74 --- /dev/null +++ b/docs/reference/glib/changes.xml @@ -0,0 +1,174 @@ + + + + +Changes to GLib +3 +Changes to GLib + + + +Changes to GLib + +Incompatible changes made between successive versions of GLib + + + + + +Incompatible changes from 2.0 to 2.2 + + + + + +GLib changed the seeding algorithm for the pseudo-random number +generator Mersenne Twister, as used by GRand +and GRandom. This was necessary, because some +seeds would yield very bad pseudo-random streams. Also the +pseudo-random integers generated by +g_rand*_int_range() will have a +slightly better equal distribution with the new version of GLib. + + + +Further information can be found at the website of the Mersenne +Twister random number generator at http://www.math.keio.ac.jp/~matumoto/emt.html. + + + +The original seeding and generation algorithms, as found in GLib +2.0.x, can be used instead of the new ones by setting the environment +variable G_RANDOM_VERSION to the value of '2.0'. Use +the GLib-2.0 algorithms only if you have sequences of numbers generated +with Glib-2.0 that you need to reproduce exactly. + + + + + + + + + +Incompatible changes from 1.2 to 2.0 + + + + + +The event loop functionality GMain has extensively +been revised to support multiple separate main loops in separate threads. +All sources (timeouts, idle functions, etc.) are associated with a +GMainContext. + + + +Compatibility functions exist so that most application code dealing with +the main loop will continue to work. However, code that creates new custom +types of sources will require modification. + + + +The main changes here are: + + + + + + Sources are now exposed as GSource *, rather than simply as + numeric ids. + + + + + + New types of sources are created by structure "derivation" from + GSource, so the source_data + parameter to the GSource virtual functions has been + replaced with a GSource *. + + + + + + Sources are first created, then later added to a specific + GMainContext. + + + + + + Dispatching has been modified so both the callback and data are passed + in to the dispatch() virtual function. + + + + + To go along with this change, the vtable for + GIOChannel has changed and + add_watch() has been replaced by + create_watch(). + + + + + +g_list_foreach() and +g_slist_foreach() have been changed so they +are now safe against removal of the current item, not the next item. + + + +It's not recommended to mutate the list in the callback to these +functions in any case. + + + + + +GDate now works in UTF-8, not in the current locale. +If you want to use it with the encoding of the locale, you need to convert +strings using g_locale_to_utf8() first. + + + + + +g_strsplit() has been fixed to: + + + + + include trailing empty tokens, rather than stripping them + + + + + split into a maximum of max_tokens tokens, rather + than max_tokens + 1 + + + + + Code depending on either of these bugs will need to be fixed. + + + + + +Deprecated functions that got removed: +g_set_error_handler(), +g_set_warning_handler(), +g_set_message_handler(), use +g_log_set_handler() instead. + + + + + + + diff --git a/docs/reference/glib/compiling.xml b/docs/reference/glib/compiling.xml new file mode 100644 index 0000000..c7a058c --- /dev/null +++ b/docs/reference/glib/compiling.xml @@ -0,0 +1,125 @@ + + + + +Compiling GLib Applications +3 +GLib Library + + + +Compiling GLib Applications + +How to compile your GLib application + + + + +Compiling GLib Applications on UNIX + + +To compile a GLib application, you need to tell the compiler where to +find the GLib header files and libraries. This is done with the +pkg-config utility. + + +The following interactive shell session demonstrates how +pkg-config is used (the actual output on +your system may be different): + +$ pkg-config --cflags glib-2.0 + -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include +$ pkg-config --libs glib-2.0 + -L/usr/lib -lm -lglib-2.0 + + + +See the pkg-config website +for more information about pkg-config. + + +If your application uses or GObject +features, it must be compiled and linked with the options returned +by the following pkg-config invocation: + +$ pkg-config --cflags --libs gobject-2.0 + + + +If your application uses modules, it must be compiled and linked +with the options returned by one of the following +pkg-config invocations: + +$ pkg-config --cflags --libs gmodule-no-export-2.0 +$ pkg-config --cflags --libs gmodule-2.0 + +The difference between the two is that gmodule-2.0 adds + to the linker flags, +which is often not needed. + + +The simplest way to compile a program is to use command substitution +feature of a shell. A command written in the format +$(command) gets substituted into the command line +before execution. So to compile a GLib Hello, World, you would type +the following: + +$ cc hello.c $(pkg-config --cflags --libs glib-2.0) -o hello + + + +Note that the name of the file must come before the other options +(such as pkg-config), or else you may get an +error from the linker. + + + +Deprecated GLib functions are annotated to make the compiler +emit warnings when they are used (e.g. with gcc, you need to use +the -Wdeprecated-declarations option). If these warnings are +problematic, they can be turned off by defining the preprocessor +symbol %GLIB_DISABLE_DEPRECATION_WARNINGS by using the commandline +option -DGLIB_DISABLE_DEPRECATION_WARNINGS + + + +GLib deprecation annotations are versioned; by defining the +macros %GLIB_VERSION_MIN_REQUIRED and %GLIB_VERSION_MAX_ALLOWED, +you can specify the range of GLib versions whose API you want +to use. APIs that were deprecated before or introduced after +this range will trigger compiler warnings. + + + +Since GLib 2.62, the older deprecation mechanism of hiding deprecated interfaces +entirely from the compiler by using the preprocessor symbol +G_DISABLE_DEPRECATED has been removed. All deprecations +are now handled using the above mechanism. + + + +The recommended way of using GLib has always been to only include the +toplevel headers glib.h, +glib-object.h, gio.h. +Starting with 2.32, GLib enforces this by generating an error +when individual headers are directly included. + + + +Still, there are some exceptions; these headers have to be included +separately: +gmodule.h, +glib-unix.h, +glib/gi18n-lib.h or +glib/gi18n.h (see +the Internationalization section), +glib/gprintf.h and +glib/gstdio.h +(we don't want to pull in all of stdio). + + + + + diff --git a/docs/reference/glib/cross.xml b/docs/reference/glib/cross.xml new file mode 100644 index 0000000..c90b30b --- /dev/null +++ b/docs/reference/glib/cross.xml @@ -0,0 +1,147 @@ + + + + +Cross-compiling the GLib package +3 +GLib Library + + + +Cross-compiling the GLib Package + +How to cross-compile GLib + + + + + Building the Library for a different architecture + + Cross-compilation is the process of compiling a program or + library on a different architecture or operating system then + it will be run upon. GLib is slightly more difficult to + cross-compile than many packages because much of GLib is + about hiding differences between different systems. + + + These notes cover things specific to cross-compiling GLib; + for general information about cross-compilation, see the + meson + info pages. + + + GLib tries to detect as much information as possible about + the target system by compiling and linking programs without + actually running anything; however, some information GLib + needs is not available this way. This information needs + to be provided to meson via a ‘cross file’. + + + As an example of using a cross file, to cross compile for + the ‘MingW32’ Win64 runtime environment on a Linux system, + create a file cross_file.txt with the following + contents: + + +[host_machine] +system = 'windows' +cpu_family = 'x86_64' +cpu = 'x86_64' +endian = 'little' + +[properties] +c_args = [] +c_link_args = [] + +[binaries] +c = 'x86_64-w64-mingw32-gcc' +cpp = 'x86_64-w64-mingw32-g++' +ar = 'x86_64-w64-mingw32-ar' +ld = 'x86_64-w64-mingw32-ld' +objcopy = 'x86_64-w64-mingw32-objcopy' +strip = 'x86_64-w64-mingw32-strip' +pkgconfig = 'x86_64-w64-mingw32-pkg-config' +windres = 'x86_64-w64-mingw32-windres' + + + Then execute the following commands: + + +meson --cross-file cross_file.txt builddir + + + The complete list of cross properties follows. Most + of these won't need to be set in most cases. + + + + Cross properties + + have_[function] + + + When meson checks if a function is supported, the test can be + overridden by setting the + have_function property + to true or false. + For example Checking for function "fsync" : YES + can be overridden by setting have_fsync = false + + + + growing_stack=[true/false] + + + Whether the stack grows up or down. Most places will want + false. + A few architectures, such as PA-RISC need true. + + + + have_strlcpy=[true/false] + + + Whether you have strlcpy() that matches + OpenBSD. Defaults to false, which is safe, + since GLib uses a built-in version in that case. + + + + va_val_copy=[true/false] + + + Whether va_list can be copied as a pointer. If set + to false, then memcopy() + will be used. Only matters if you don't have + va_copy() or __va_copy(). + (So, doesn't matter for GCC.) + Defaults to true which is slightly more common + than false. + + + + have_c99_vsnprintf=[true/false] + + + Whether you have a vsnprintf() with C99 + semantics. (C99 semantics means returning the number of bytes + that would have been written had the output buffer had enough + space.) Defaults to false. + + + + have_c99_snprintf=[true/false] + + + Whether you have a snprintf() with C99 + semantics. (C99 semantics means returning the number of bytes + that would have been written had the output buffer had enough + space.) Defaults to false. + + + + + + diff --git a/docs/reference/glib/file-name-encodings.png b/docs/reference/glib/file-name-encodings.png new file mode 100644 index 0000000000000000000000000000000000000000..7adbcea393fc43286f09cbaa8ab507f19d4eb50c GIT binary patch literal 32141 zcmeAS@N?(olHy`uVBq!ia0y~yVEoR&z}UmV#K6Gd@u{YWfkA=6)5S5Q;?|qHGBdp}?v9Mt4)nsR@h14z`x+zglr?*V zH2E1A7=q*&7#Nn=fE-cDz`!u!69WT7m1{+~u$G>lUFj5HnBQ;{dV}&PfJsmraPaXHDl(U+f$}% zKUw;8>B*BPSy@@v{t07pyKw26k+I?C4Vxr#OlNo~{PXn<42_*SX`++TWTrn%2}c)Z6yow$-x#q(7n$2MZ}%9RdX*QQ37cWv3tL{siCS+_3P0575OVxufBZcipwrM>#B@Iqt`zpcEi^x4$n z-kzSU*IAF{j+us-u8G;VX~T{WM_vjCbxv7*{Ax-@SZHYM{=&VxcKzCXbpFfNuMTUm zfc(9B*|ujfH+DXcJioWSs@~+GvRQlY@egz7&YdVYF??OTW%au?Tc>W_cP_iRXXVk9 z%*|1=qV!_-ikN73tUX)z_CMpH$Qh9{X3k1YO;=S_E%p9+Y15@in}no#pFMolDDbHK zL;jsT7cX3RApgKV^Nxzv)ULx1U6KOX_bad0@b?bpRy0X}HfP6=9eeiJ__jTp1cbe`@xbGY^f2rCs zH9wvi9S;p7CW3Oq@kzmxm$Uo653{(F|Krp7X_qs<*!j7rO+Kn}#KyDoQOff#XQ$s6 z=+M8mrN7xOFEhVV;O~Qjd)Xc3+4tsgHLqdom9o^bvH5duueBh*a?aY^wQJX$^*vkp z%Z6|E;iOGh=AS=s@ma-=>Xhdx>Pyvr{`ysPGbXh%Jv}|CCP{sN@s%Bcr{v@&dQ6F* z(r;jreM`r7-MnAww<2z9#A}>?eo#?{ul;pp&7!&Y>ps3Zx@_4p$>6jz^9-f?OTVsu z@$!|S>CEbH?>*0Z)X(~K@PI`$M2uzuU9cK1j+4TmJ;FBn|*t2`Rui4>sEhOb5#ob zwYg-8!{K)R@cxPxftfyKMMYhGz2{Dxe38nPB2;;)#nXg0$|uLiGt$!y1lXK9P9{Y~ zNA0%Q-SbI$>79pxY15=blbrZwH#=Lj1QdH0pV}eTxXnDT zrQ5b{w>@2BR&>KdXyTV`Z-WB^14H9nmtSn>lU>#IW8Duk0|OHy9bH{r4XptGO5e6+ z%a<>&@-_B0<~f{VH1mJ^zf~RKo65JiKM(Yc?e$S>-YV#Ds=569p*u+z|F}v?NxfDrikO<2s;R1{rlyNd7h4~*Dd?)xc&3XR$I_G~Cfm*U zrA$s-xDXK8>$Y^~?p^M79X7SEN{W&;HBW9noWNcj{CQvf)?>$xEqkWc86s3FY%xRh6pfKU|(+y@!9+e;7 z1!{;mJ0Ffax8zN7zi+U&u#<<OWJgAPg4>L^SnmJ^9d_H2c&wI z<$XKqEgn37shfR|nW5QClf+3yn`PS%_sU!UEBy0#M$3$kkB_~6`GV8+P)D^O3sYjt zdydff$!%@N)aC0JoxJ2zHR+4V+n0;g`$f1~&7!M+Ymh8J^Q;lr5>6qX{xRazVPzZqpYNyOSRuV%vjpG zbZP5S52dWkOwZFk*79X`=KAJ_hJ~NpCs+S3VVmo?_+m=YOd0k1=kdG^<$QX(8S1&Y zT8&ap2($!*luU6@_`w}4(0$bQxAT-+KXTXp32PDPbW)n=`Kn&Gudh$-m>Mf9tNHso zXU?5c3qCO~Zl2VX>v@rrJ5yrUy=y;gzeP4hds4@#Ri}5=Nl3`GKNN5>s{HP}pslTq zjg3uKR+h70D9*f{!QoUhW1ox4&x#)f7IT{ZGXZQZhE1;1!l>rU347rU+;VMO7;DwVk9TiexpC!+%K?sCYu5cM(Q5Tl4OSKE{G=37`pfE< z^WC;b1v_TUn6aWgP^k0C()tB`+n!u`vShjE2EK;xEMIOk>}Ta`FP3;CV4?V-=Ects z(hnmoBl-IHs;a7jI=5`xXQ-~feAzZPz3Kgurq4=)S7fjFZT#o_j2#lTvbM?0$-1$+ zN^UuMdFM`_*Vfg2`uXQFwPla(WUjw8V-PVqdiA8KqTRw(ySNmeJbbj!vwr34J#+8Z zJ@~-5PVai+gyxAGC$dE@Ub*yT;iboS?!;KlefRQW=|1Jzhp#=$m_BXVJd5H(XK(f{ zJa|B`Kukl?#_V(oECE5LH ze(0*|DmqoPlC?6aGeU22GE0xw!c8-DJwmP*sIjRUqmbC3`{rRW=dGyR^&DArdX7|aP|2s8R+tbst zu&|J;)#!u(60=#(awTP!+FM>aeD?6ITe~#&uUNBd zjq`=ZhXztpmmRe8c^g4SDRJ<$+mo_y%hp>5yHcKY-k|M1GaP&4J!mHuUXpQXZPghyNrP!;sVi67d-`9PSj|3bW?;5q z+opL2X-t#PwU{w71j+HpTwdlg+bmUT3p2yr0~<9NKrzO^aKV1>W4YPY6Ti<}YTum3 z%J64)YHB*~jVb%(E9J!u7#Q~0-@CbWJ@fhS_*zjJnKf}jGBSUTipM*gX85o!BqZd_ zEYs}U+j8sb>Mlst3%{7o&hRH$FLsxRy!`&Mw^12f9+eCS9D)M^3LYF_Yze5V+xLmJ zVG26~k4#=(9xE#=hoas5{Y6htWnW+CINRYAGXq=4g$n@_J(k23{rmGXPZiX=ywD#U zry=rf-fuAHzsB$MLx&Gn^A!~rYwPH=s5MPtXZVu5s(GF5!NdrUN(P7h+tbd@iffD8 zQ(>s6$QZ>LB*$<;KQ%3F*^(t+f)*}Xq-13kr8U(l8q~4;HS@@kBQGy6|NQgMz16vQ zb{MLtu*~8H>G&V?@8{>|wJR$>J@L#~SI#<5iHYGyyoQDb2S2~OUCoY9xoK%>&d$wM ztku=keC>;?q=kew)%+~VFbBEee?n%aq^Ri9D(lQkOY+o%^KNg;eRQPrLcn{OFE=pz z%i#Vj$ot?pX{gt?i2v6*Wy+Lq-^#Au{`Bcno+uYL_u|EiL-Q?V`u6U%-6GAv5VWt} z!^bCPXHlxYD4(27#fJxuS8pFU;84*f$?(9I-PTNBCw5oK@jltwH9kv&w&&mH>t$nT znDXA-fJfS{X2-;df$>_qckOa2=LMNH|Kpc0HdS9V`j5ZfJ8S>``iKY#6LFBl|Bv6l z*C(H1XJL8q`n7X3BZI=z->P4&pMMpRkl2xT*D6DmfniBay{pp1XJ=-9-sQMC{d}7m z6NAI4@9(GF-(Ua#%uM5IJ}yqq#wqL|!Rj2d+vm^sA52&w9u*Ps@3&8%W*H{4ZQ*2K2&#J^VU}~_>+9=+PCRVN zii!*S#eEnV4*X_*m;9OS+O=!x>h!u+$Uw-SM!|-7L z#F;a1UbwIzE-63%{KJ9;so+rG!}?-6I|GBq&-&G0|y|k>X&gA1_ZgIU5 zZGKKp&RN1=#O+?++??JmrmLl+5i-?d=_Pyp|2xah-r^Ki>yfoDdu%Sv%^lC9yIv=L zYt_}i?B5d&8yT1F*imtBPo?Bb$yJkPy_yyO{hw9(wK@EM?PE5joIK3Vzf@>tRz`5~ z<$AM!&tq;_?u_AE%dYvq?9%1S#zsbQmL6)8j~+iB9uiWbou8YzcIDd2+x$W$9A>$9 zmaJWxo0zvyON6WSc)wizyx(({pMSh*NBH{qub;nG&-oEydBx%WfeQx;UN2i)V<$gN zM8cqD?xDBQ+fF|%Vy|Woeb^PMU1$9#y4rpB(v_)cVb7*y2G{+1slIZH_KU4EqRhg~ z4&H8l{rc5H#&}1@xO|@jGdP9S_7nwFS6fHV{`>j7eYv*2u4e78H!pA3UFgj=KXdl% zd=>jZ{V85cQ;()9E%aCza3b~7@y>oeaWqw_ml^|NEI9C&Z-kN01H_~Oddt1GocM8tMf@A$vzzj(%hdB6V7 zoZ{Xm)7jB+V|)Gmh05(h!ooLozAbX?cI%V4sh9EJ_|N%h^SrHFw^mkFt&7;ywD@xA zk9`XlKD@Ox`{Txss#8^S)T(c6NbH`jvn*%@hvH5jx!(rgzCYgI?fPiv=jUCjNlYJI zg*}g6y6}17!s*VXJFL3J^k12&Yum+7oI9^q;L*#^=jK`8&dsQ)`O_zB{q4=o;@9ui zp6KwH!(^U%Ys${e&y!qyG(_(0tZzU4l&?@~ksViCqT90A^cRmmSX8rDYt4!=7{rzbh;^wr31%(L}X{gxh&UIVL%F60H)57&;cEQU_OD`|? z%fG+v?~jj#Yk1E*wAo z{Mp&rQ@2iy(F>2v$Vz(k@Ll24OH+?>i(Qs5i6~=Ub$r>16&hMvStrxI$J}-HO{?mHX$(N8Pi!rvinZ|ihXY6)<4buB6RlJ0H4I)CN%jT<bMn>u~Ey;lv( z>AVGBZ>)*mKhH&RZRB>hoxiUge7|DtI^Nv^%NDOMe)Gd{qQ{a6+H$Hko3?EE^Y{Dx zsf$fa&8JSAb}F^#>Fw(6?_a)r75n$|Di4)eX1TZ6_sNThi)ugVsxE)`vBD;_-?yx6 z+wS(?hgi9n2CZ~jcVmCOz0->H{gsSqCbO(FD<(}6YIRbaeDaj{ zY1O1or-cKA?9*&IU7ReQyn46l@a4|#?$=gfhc6{< zzUk>d>D*lF@<&HH{~Y?W?c26pZB{Eoe!aM;EH5u#JJ0UW!od?JByVRhYUH;)SX3S7%`B1TE;l_oVtXJ&ayLaQtkEQ%8xVX5i z%HG^q_aK(fkIy{s{)&~AFE6Z{xG*p~I@>vzIcI%Cx%Q*PmdgU_?CR_?eC|q<)qH2G zh;U90njEs1LHL;8f&k45o4P+gJ}OPrP&Q^(ymI4)guJ+Y^{*UdXXVtb8y_DNn=Td} z7N&JvIjCdua-U-cJc>`=KE8Y9%9V5Z^@T4&HP)siA4ql_S@h~wRz%rdo)&AF48yHHKE7AHyS%%C=P%>?TD3C!{H;4tJKq;Q zKQ{NP^fm9LL44Dj6KD9SO+J|t)ETlcAmmzD*5<7zQ;eKEnwKp+dMT*)p5lv)yxeQ% zFRBC-nvW)2xc@FILTYMSX6nt&F&{QcdcN&}a*l+!MX@>C$_0_o8OS+B0$|bI%M3i;iAho zR7y)rSIxM$GyD0!``=cp9ZfNqYAWb7E5!HeDnF%(M}#(pe0wy{sdw)KAKY!cS&8ibUzHa@>c8twvCy%0wYOrcjXN=zQ#~(c!U6KTS z7q70L&>-mHGRZ^Z)vK42v|W-e-rj0DvElIkq`RsUJ*1?h{(Li^BaoSx>9{bU%e!mh zBUkg(>}c&ypG6q~388H7#d^Iad#D7hoZ_IQ(DH-Hj<0?3gx%LnR{Cg7J~d_iQ6)pU z{^b)iI23K#mQT<;Jzej+^uy(Lrq$KI?f$xPuvpE#ckq3HhREHfeQVd|p4YEVN=p95 z_Fndx^_u59a^L1kFfP9M@WN{cpP%z$=ElCiyFWcGD=jVY+TPnPYToDl=37=Tdo1Ao zG;7L?88^1_cRf6-b4Kg5HmfX?RdZZu^wmpu7M;EF?iO2O)~gqFVfBIhi8S_Vn3vAx@W6Q?|K@xv9F-PuAAd?E1Rm3#)7M zqQ&cjLnBqEpPstcO6$14tbP5zKiA`HY|H-K2=9vyj$G_`?ZL~>2{-?02i3j&v~>FV zxPRx%|3~i3S!xy?eL?fYi4!YUt-7@%QMoO#Z(E;WxpGWw%*~jxytsFL^UF$dgM~ed zo1e-3c-ydi`|`x}u6;`TjPKdqRyAwZxc}(AvA6vDf`iQ-Dwm$Uoo)E1d+Uak zD_5>v>$~%);OuLLS(e^^YnosD$Z!^R)|S?en0j#c*PD;dPg@&R_Tt0Bm%+=oZ{3!A zbKB7qCo&G*;EbK^V)19<{r(-6J1?5PJb3Wnuc}{+{}?$GYis`=?H2#PDbov2EJ6-QCqWNpHMPdVQT@U;ORNvV8Niv(3-nJZq`D z_w^a`*^XwfmOnb8cFbr-kD{J4I0WxCq;DucfA2ouzim}dvpD^f#JVy?ZoOG>lS5Hy z;*O8Ed+p!;$-MZ;)kjyY)rE7G+>~jv+5`?6-GuhhcD#q~=1wf)a0!Yvn?j&eU^KU@F! z&a2n2ckkSBcTaJ!j?m;2OT=S+ZoNr%@0Yc%;dwZL=Oj-B+x<2F)2^%tT*W1{QRQFa zp2^LVXRee4r7CcqF~?uhtaj*uR65)`ubg#yH|eGeU$u2S6An4&fA2WrI+8o_lyh) z35kw={q*V8&FRawZQHhL)hg!;j!Kgve5Ng&xbV}vgF+jZ>{%02sS_9Nef!E46HUvL zhYlS&aKK?`evvbX?<`;tM4*aNj`n`!aA__03O-{n5_&$rDDH|_t*ct2>R$l>JmHn%saKV{t_ z(YE)~nIwjPcCxavD_5>8D=T|ttNZ^!KBMLYAGO2D6+d(jZ2NOtQ%kF>uP;o0ra|JN z`@0P|@;6!(Slo%e%KjjB;l+%7`}Vy*pU?PE!0kZ7&OLm0;^jacW=4hwd&^&6TdRMq zHZb__qd5Oe|I6EQZW&d6dNS*mNds&xKtmzp{hGhNd1dRWzBBgXF>*g4}yNE3Qat6`RUyqwTF*iSAXR=C2PgjrKaAKw|@P- z_U=0+KG2N+`?;&@<3u}H79Z~k+iy|x``g>;>tpQ1tKRk7|FfuhVKDvl-=ELtPc`4| z&XFh~W@7%L@YCZPJ8m%EF)H}M$M7L)wpngges=t>q?Z$w-7j6b%=3lUF8=Gz&6|sz zgPmU-z3{vI{plx0_V)X)o(`LAy6arho|>PZR!&|X!r!uK`{ww)Nn1ZP2BfB@n&;i= z=&NY>{cYCkw|do@sGT*bF-b9h7FYO}pXdF5(?MyX zfRo`z!{z?-^)xj%8f=f)Q?PON>e*GZK3o5ozCNz3pkTwcEn)Njw{nZET2;BDa>k4q zQ$nYhZZ&!Ny6kSuwbTyo$tQbyI%FQ2JN-RXd}A6r!yoOG)YRC$Wu;fULj8m1&w4R4 zWLl`*`RcfU7=!F{YvSwv9R-bcU-|Om;^SiRGFxq~m2wyJ7qxlSu4Ph+ zB0m*A9a$-S>(;G%&U;^){5tkOCuVb&Z*cMCqBX(G{ZB60wCvcjlfmltRbNh=xuT<@ zqVlM&#YM@o>d%WO{c6`kukYNwbNbY&XZdE;KEB5LRqk7Q=J`#VHy`hly#4oy%+~s* zUB`Br)k(J>zId&wkV#{rhs@W9E8P3#rcRxHaGMRogZnFXZoPT^eEHR`P#?9;OLw~J zO_u-nxF9g_;`-lpves!ja_#%8-@lur>aC=#tnNE&iOkZqdv!H5GEQDnm1vt8J>&iD z?dzB9aEbS~S5Qbebb~YI?z-p|ayRN9O#i!IUI@wb{)+Y6RhJ2agnvEL+e=4wpBV>2M)}7sAI!Q(|ITWXf zdCy*4`}bCH209cH0W9+UdD->G{jgC$4<*g8gFp z`FXa5k6dz{b8D0Leo9-%p}3Auy#HY)k5sFZp@~6?VWbIfly9GRb#|Be-25wdDUu*y^q#ixu6|J`im*_@UJ zweRAO-CMQwmn;VlFK_jHztq&H>uh(s)mS7wHkan@;q72as)_ld@jtMrbSdbBN>%+st@!{^XSNo=4&_1QTtMrzMsrlPGdyT(lX1%x>uw2n^z0CGid%UKv zUVZX{%!<>X@!Jn&*Ve>-{(3f z4S?^T-o5$swzaqa{dnB(FJ7zVC{(ySB09SIXV=rc{Y%eZ{{QOq`fu-V%ZrE{xsZ}E z!E{>9rYFbW+VA`L_(jRDw*NUl3V-+8|NF4mM^V_*wLkk|B9DexX<*T1Re%`o!Q@LfC|NMUk+2tpkeDd&cd;H$2 z(8>>Gx3}esHc582Od1Pc{cCLx-_~q$KcU$dV zbt?b+?liPRc=hp93M65xAwpEZMygDZ}@$B|1~T#5Ou#Y4!LjJwrzI( zoi)1zwwJ%nefwGL%;qgy?(EI}&X6YtDiC-C?$`d0jjD=TzF~8}=KX8eo>`wM|Mlf1 z^X^E{05EgQ>fNh1cN@#SetmSFja>fMS67+;W!eBHm~&%8JHPzC$txcg zSoC}lJAdNH!~dfEG0jt`GSzX_c=nWY^X>1iWpOyg%Pd&Tl#j(qBWpNfi# z^Nx9Wd9AIj7hEQMVrZ!IDZQ{&-GYZ(lb_+m_iJk+FP{cAnAKEN9JC!lMl3yZ=FF5S zQ{uEVjQznZD2r2PE!^g$ zx@4rK<@L4f(h|?Re#`D`%e{T1Q+VORdzLRYGBPlDz}EwU0-6EjC-D3RWZ~fdxPpCu zxHUC3-@bjjYWvftPw#4ph>5wmyRW`iWFb>sU7cYLnpyZiVaALdMNdz~X~}@*I1Vw^L~DUgjvmx0%hgJ`$Eb} zOIzPbfy}ah{PJbxmluI@{nx8a>+An-*kF*M2a@>z`2G9;$ENUea9p^4y?q;a`ojBF z`MKAc1_lLpca>i70?iQo>vB;#JJa}iX>;27dAzJ6nTYj@9wUy zdi(ULY4S0i3}FU_C4UZplHBX->y=w1c-)+voaFUqFflZIXTNj&8Sk34YxnNm8ygd| zK$C&tub|(;fIrpya$}QYgNrZU?hC~|+wsd{*TQ{@bKTn0TBf{Tw`bL!UF)Q#Suy;r zQ@?#@*3y$rWiPlP^B{QRYyxO;Cn7Q{;t$+Cb+0c#BW8EjTkrpqE&i+sT }hRz$2 zb^nY0p1Enfx4lxiMXxpX)TtArcj!egZ}0c_cl_&S z>4)%)lF`S<(%*WO+B?SBIgEe<~JU#dOFIK6M}+_&Y@`!6SDt^HqSJNc*!hv^mb zn(YsFvvP~`e3e?YX4wSoq(wBHqYy=;v*&G#p|Cvk(?*^es}(U=ZYmD`D7<& zXWw4m>-D?k6u-=0|L^jpON;&$#^`hJT@ zZP%|{J=3Om)3Rl1PAfL<`XK9wGqX=$DyLnWreegYIAz|n zb7`A*r)}E%_{Dqo_jh(ACub+;=H0z>rRL)$*L95FoB8cdoH=o4SEcq$pR!HmTB|i~ zfB4#Fntkm@|L5b$KYs1{b>+zwP2uGVJfhFU-R^Ws2pc?`tUBKyf~RFdUJq=~+2xQ}%B? zp2KZB_$GEOUD>(Pf4+@v*(-?_&Lw}U&z8@4f2Xzh;|=e>u_;_Xcgyd)eEGWcf%rQI zFDCvy_BHBORQ_K6E1EVXKLkRXe_j2xe$Cr8g%vTev3DQ;I9@CB_wYn{zqzKNGc~n% ze2=~Qx?0fb;>L^3Ic#hHC7CvU5qtf)iIv-Dt?yOuRa&bBoMdv(&8;p!)+gUBxN%-G z=Z~f}Z`LI4JG^PrrcK71ZTH$ved@w>@yr<=P0f=B4=&ugbnC)>jmICa?9VX2@hLnM~jyq|7`o2qxX9$ui#7@JGFn$&d#1+^XKG~nUgh5x?E`LNwRhL0{VZu*w=hqAzwsBJ zj2Eo|((JP@Cc8cU_~YZ`x{P=9er4E_3Bms$@84r98P`rPMY{5;e=yozpr`FM3bMMMJ_2WrL|k- z!t>wk*qA4m$D!Ehu;Jh7ug2-;T#QPdpPPH_T$pwA?#kk4fsr9kJC>?04GavloN39l z(81q5-{}F%az(#Wk2S^5#h*BHDrQ5$!KdESPoF+Dx81^jmQm-yggd*cw9O2|)TZ`I z8D>rSuOT#b$*bHGr_byz{T>#WIdR#tW%Jk1zwcphG_yxwlGoC}iGdq8ZtVTqTVi$h z&Y_xHS2A;A%f7$;xX0$J+-&*%|1VxTb?N5CpTD-gPBl$+b8{vCoJ^jy-kMAEA$-FW)F*Y_0@`PKE=(?ttx7l z)>ADljrLbK|&Z`cnC?8>nfyX;IMBPqDS}CA|#? z8cw`8F{9nEPWi8fh}V1L!|%edT)A{*QMpTe ze0=#Hy(35e3(3^hrl%C$+a#Z(KYVs3B0d|KsoOh2l$v zR{E%U`}*066utN|^Ky>tHaYkA-+FJ`=lol^cBk*v=vlL7Wu>H~63e5f75n$Zz~nHUu@z|`hR|%ULRe5qsso#KEv}f{FeUT^nSYW^79=> zlUgSDsO>KLcxqN@ww9Jw4*ShZo?q^N`~U6px%o$x44pK-xV%{RcDG1SYxnN%#)*!3 zWqG;2x##sS-MKR7pH8fbkmmig)YRC06+frP*G*JfIdfxVl-I3STUWnc{kpnu#>{z| zlTXIP#$4U*x%(~8UiCY7?tc05HShi|-H9Gme7!XSnMpZG>FLi?UQd}k_wtn=j|y3v z=dy8Iv79fS=YFrh_3ekw zP1+=s?48WCG5hnmW5<^5TexrKOHuyV3n^K*Zrw^-mhPo`$^0D8#WtYwZo@tPxW|d^2_{wU2;}lmx#unq8}UW`)up~-8p=kSyALi z;Da{{ZmI}zDqcDH{*UR8>(%A&D}PpL^0RfcEIQ!X$e7Ihgv)aFQM=l2Tl&|ZzczoH zQKZjAk1g5H*R}j;IdHNuMm8_d@nY)*?qD_lna1^ey?&EDQv}PE`PyWB>ZiRkyYklY z4YRoU^xoNKK_(g;iW>uZoOhUSYj#?9;PD4;``8!nUiKY-I9Yh|_Pm=?;?m}o$DZVw zzMl2^Nzu+#kALJIJ$~GLyP3B193Qpc{a>$N{hPm?T|aKuilgsdRV@n8s8jx9ux534 z+MgL8pP!qnt*d!;LDrrvyVV5Jm!(?q6eeuG+4rt*;c{nfZLO_0W9R-ZvATQY%#(w6 z*{6n1&6CUXzZ~~!`ib-B?aRK*(0btGu9UT^2fJt-F{NVh&3)SEa;l%i#J|kY_&&L2v+d)yH{vOYwrxP z(=3?u>4aRTOHp~De~))aUe$6NPr(unHNQC?i!Tc}NeF)adEohxPT^Bi(l^bRDmwN2 zq|YR@G?Edrd%iY=cufBODs6T9M( zq>W{7?p>VjfAaj<^()r~);?Vr=luWol=@FEI2-@`Kkj5Y^Bdnct6j0RXZ_assr%16 zbMjPSS!rFS*{4rGWouSDhDiuYKQc(E|NHOLrK0NN>-uE7*pA*i`0x7O{d}7wj~KtZ zmm3-zDl00v^w;Yz1>avJpRzw+85el->Jk;9&eIQ91>HM!>{LVg1cCVv%&z!`#;=>; zog&23|Mk!OFbxr-nLLN%c$5SO!L+r5BuxoDW%dFu)s!j*{*fFHm)o@neKh1{&$5?bh1!+A+jf_f8Mzx zk3an3+h=xZnbC@EX50GZ?e+Av-zPKcMeJDc{NnZhm)^}U-~Z`_wo}L1#C{puPw(FD zo_1~8E5V-@A2)_*T}{dm6&2aKZTqX&FVyWkW$dzctUAbU&G+rsf$S&j%GG)9^$)%u zYg%b7hw6UwBt%6;rG-~(U0IYZ zdb*o+E|XZ2VFXXK^zC+j`A@fhPEefiiJ5nz&z3D4{^Yz&XF1i)cKpMPPYMzGpFVxk zi{E8adF#o6ex|LFw=9_6-CJ92UHkJh9|*30}|ym8yd%c1l4trmMA`Kdr+-I7H|ZXCLC;6}pN>8rQr-<&5f z{lh#xeW8mtkN&(jw_5e6>Z(KEzI|JBXU(%`&zOJnC%E{iO}=V=g?k=n%OUZ*kB%KX zc0cdew|dLf+sd}3a9JuVJC{~zw>lYu7T4-b@ml(d-AT~NMQP&MG;>pvlTVDE$~z?I zD!2M9+?ZjzI7UM#EIfR+#4Ldg`W_*o?1 zrWo6dQrA@1Qd66$!a;QhByBPZPE8hxowsgfYvy*xw{PF>?YVL3)}?#5{x#lbKUEy1 zlH{4@_AGujd$4dYSF6*);5m2a#z!_DTfkc=X>=s@M7w<5jh%~))y$sBF55GCv2a_W zr>Cdg;hK3x>+=M#%>a_wBScIVn{+qT`dEU?Wq-a2#Enb+6XvDb;L2+)`` zU&YmVq`*-EW8HxVGUpU}O{& zcj3zJS+i!{xf64Bo7r5q@cnAd9!k5aci!Jw?OyswxYcQ9sq2~E_c_f4r@;)X-P8XSKvfcE0=+(df ze!pMFw(K$UaqV)BRa&cW-M;<$)hlpk>g?OIvu4ez`c-wej49_$j>*hft*otKJlZW2 zwyym;qrq_dp?t%YXB5{tyC?+)Cr|#wVc#%CKH$c$H(&3s*)LR<7=Il23}tmZG9zu#VWrK?-IUt&#tMd4XfSvYHIT` zznQPhPx;sWii?Y@vZ``D>dK)wF<{E{xyz4UyJTKdxSz$@*?AtL{?kmZ^Bv!h?ez8Y zI(PbXu&hYp=9|&m@(fK(YaVxqAJU82UFK`LX!q{lt4vp4(T<3YynXXl=(NyPUT1XA zPG1{S_U+8gyY_F7eVE~+_IQJ(b35`>8b_g*%^+sljX zCf}j}ji;$kb8~aczLlL4jE;`(=I+kT$ql)E;_TV8OI4SiI(3To(za{cZq2&I=g7|2 zzxZNC4BzynN1ZrK&CSeBOgOAqjb{2ZuUfc#@$pM(U*D|G&CAl$*WSKyYhaxB)VWiA z(=S}@*ZZOqs4l>fwJJO6b`+0uDmowem++t+&wzGxv1?e9& zICJER%g-qELT9NDpS>C)#4v9_^h?Q`eO%uPyLWcAqieWl#|^X8_; zsheh`s-`M!JaOq%P-R@#CR=YWFRLH2Rxxu=z4EHAuKrs0VbUX^g#i{P$^@J=lx>}r z>R!I7R_e@1O}+X%Y;AzXnR9RICiAFG&dkZ0GkNaeq>VkkyKe2=v}e=0b$w@3S8uOz zc6P3f-5a2B#K0%oJK8MX;CZ}A#zLt(qr^~kH+}*pXq-LKweabUs(yArR_XA^N z@7}xTry{U*>(;N8zyAMiEXgj;o~AZu0jK7F^CdP64{8}S@0S)F>xKZtFVlV))E&unW}%WiAN z02zMTy1k ztrwIdv@)H4FWHx{gQ>P1(?MF+Sky(l5f{Hmi9!@+~41OvrMzAB&$9?I@;30lA#JR zVgHnwGiOekbjiE5tE=n9i;R^aT)C{ExrTJ2rx5P)!>15xetdX%YWvKYGkJM=Ux~hX z`_@vX?^Ujc$B9o*PcOU+8cF`!ymV=5NXV2|ZaWEw-mcbP9Y_G~D5c}do~?8`=@sa|*Y)mocKF)#$} zyMMqS=f{VKZfq!oO@55$8@|7MB0Zx%uY*Yv;JKPCEU>f~WoP!?^IL-|pU) zJa1&xI(J&wG{@p50jH@?r(QI?sG6!OA!lr2^5yeaW21Ltp%&!$c(_=Mf>H=89d$In?XY0jKInU|N@ zR)1UJ7dqwi)BW;4ZB2AU6kV1EfB&~Cz>*@%q{nr-=ps z|NS+*XxQZEc;H6E*Z8&5Pd_~$G;gkLy_vFlv(q9AD=WRI4JXbVT64QYS6BDo!Gp~? zY_&GuAB&&XGp+o;?{DJ$(+>@e{)?^ezL&ks;gOSQx`5?uRPW3{`r|_PM?n6oObq^y!r0k zyZ3K$D#`isYU=8nK4$Ly&Bq@LI$aID>gedGx>U7_t*XLi->yZs8qx)%#IiC{R@fzZ z7M}d3d;5C*-nhTZeHUNMySwLT{^R@`J08mWRql-W_w&~I&6hVX_nUX>(FPq|ovZC# zE{j&J(%KlYM(g0?5AXEer7&3ng#w|~E1C23&Ru*i{v*{c9F36ciP9U3~H0?U^~xw;xwO zVs37}f1T5fmj-6DWq&G6a(nwrEP7j>rlz)K-KQTN50wR+HWqH=7Sp-$>j__x%ri*z5vI$`S$PMzCL@g_GN=aqXWk*@h^9ey-!{tnb(@`1n|VaX~@F;|}}(e~jm!umAAD(b@U% zdHer80zqGIn3$Qh$#6~dep+EO&qe7b|F-wlDyk}KOKiO-pMJV++qTDljticQwVvxg z&!)4lYo2X&SxHGrr0dLu3m@)iD2$0+_vvv^P*BmP;;5f%eXK5Dy;{2BdBD?quO1)o z4-N{_keagW*fK-L&I^wpS-lE^6#^|yUXue z9KCYoivGSIP74D-PWI z@Aom!+V#t>Vg4Iep+ono^=BHnFb2wWJd#^+by1j1$l9x`Vz;e(Ub!Xe_lm8z7F}zN zV*m9ZEQaHRnB*q&#FmK@Z1340l1>gdvTEy%`_I=uxmP^7+COjK_a}FX^Xs%~qfRAl zN)kWP$0NN`>h=DTmqE_8hZh`Ju=setS@A4&7r&0q&Wnq(6?L# z+}P#k=e&FUc(u(do!DJdeALW0NpC$7#VxLDGoxU`x`lZ^A3a@syvL2Bv~c&iIE&eT z_NVAgmzEIN@n!PTUB7nKu1_p4|GuN}v4B%$Wu=9To{o-BrOoeOuh)P5`gLmRy4d|? zZ$227Y2Q9|DeK@N*1t9)`Y}5$Ts&C#_4(?l{`J3JF2Aznitus2H~04bzO%D9H#gU5 z;fKfl_F>z~&2nxSBpu;s2}n;*FDWr`(lFPb-k{#oCDD2?VT!HU-Me?Is;Z8u+5WBC zwr!h;k?R5R75g)NYkhw${_^(n_V0OatiRa1jz0R*{?aba?(fZ${~q?uwfXjU`~Als zE4W&Vls>xD)$QBaT3H{oZ`-zQix)3myxLhuFgz?wsm0*Nyao~PBU3}C7Ipr4b91xz zbiL5`8(&&K`oHzcWjVJyX&5wnp!G-?d9ti*%!B3S;&Iwv6`BiH%$>r6KBkux3BJRmB0V_wzf9o z<>xt6on#n~=cU}fb>r8MA1O~$YB#+Q=4($*$_lz4@c;Nt`??z+n^$+g)(+pgYgd$l zKuO_l7o~|sw@->}s%m_Eyx-i+WZ9A>G5e}!dMzpYxNF9(GX_pKUYV{A&RZIBBci0p z%GK%Ob?JTc#I5-iuUxpWA@8o0xw-kihX21G-uDa+$tVFRh%c=IiC* zVNvs=;NWDYr+41mdDG&|xjKA(nt?>Wk=)m~Kd-K?=E-$S3tN`e6{2NZ|8dXGrIkNA zK5UI&(>qf*IWco%`hB^L5o>e=1OyT?6D@6OetZ%=t?obL%mU-GH+L4!G0i-+WaGr- z@byuDpZ?N6?$TpuY-nBfW=7Gp`Sa(`oqKor$N95n&5DYQ)Q#AZ@aM?KeRlhn`g>bj zS*!WZPRYyLmvFFY>io4|K7Hfj;mdix<@?@;NgFK`LEzxcvo}wl_Wo({v;O3tynRj! z1v*{q-~2gv;6lQqC7s#V)^>Ju7#N#c*S*;hqE(wZwW_L0uOoIr)vlVKMcUHZtxglC zO`A4h!iJ=$TuL*4{QZ7k`~JpFdx9c;6a+Mu->|;<`{z$p6%`q)k{AE}{^n|Z^k?Vi zef#!Re|vNC?CG=TPTl))_1J-i17CVdzM9|Nle>BP^6HMnxL5^eoQNP@&EN3RPs8zyHB5fHfz?bx{pW2_2;A}Wo>$Q zy7X0Wo%NsDeU0bxIrn=m4Qll%eDXmsJNvct^?Z%z|Gr%I=U8Z(ea%BfsMYD?+3ELh z+`hTo)+bm)M0KgEXsRez<@wh+f3g;D-dvoPw#;eakB`UYzkc~@b<3LXU(p1oWi~ZG zCY()cZ)?lDy=U#FT}A~N4_*{5o_)iYt98-7Wp+9`IrrQ@w>Tx*Z?C<#r*hxEefo1u z^X^#e;;YU4b7|T%u~w&x0oMcKgZF=2-McJp+4RZ!r=J$t_5XkQ$v-zY*VxENgv-^< zjcu;u{>s;BerbG@58m0D9UdNj{nL-9!D@biswYqP$k|rKJh8ZXd2RIeOEXKZhNYyX z8AfXlk<2MSESFc+2?D)BK^NqhR#~GNJ z%`?xR=c5+AJ8kXs>DTvEe!lX&iucnesVAj>e|?Rw`?++!@4{otj{UWNzkTy&Z=0Db zRFVlEW!Exl-Scv{FJmL4udi>nxW1p&{4H5WwOTG5>y@7S zc5WeyjMIvpD=qc(-ko@;d}=pW^2Qq<9zNV%_IA~}ReA4o?r$rVo_)4YMmRD!cJkEO zUmx6SuFw5_ea+0x92JKSxAQ-*Gx^?MTz{la=JxR_Ar6+O$L3koHTfuJ=TwBIUY&Ww z*twnW@81jWMWmK)-C26-il%$NysVtvo_P1i;vc_*fWM!g-G|eSFJ5Hy)>RtqOqb=8 zw_3A&{qlWw$;bLMD}pv;URE>e)tTxsQ6~4^p2)?&Rn4`-p+kqv{AT;8 zT{gdzpOy8fz~a&lA6T@!G{jSrb>NOyfI!>C_~*rIJz-X{qUdzb-x*ZMn98zRk96o8;aYOEe#~ zIaTvz$qP^K=ebwG;sv)XjaIISz7QK1d9PTBq4}cu1$T)htJiB!>x#Uk zW5cE|z-hJHT3;=;WJ|G(aaPZ!=NHR2te-dWUh{AMUw%Ksb6jg<3o{GZ{5CaZDsZ5O|_f+j2W{gtbFpl?1ZMKUlvtnAa|HZf-%A#W9-B@UIAmC@UBD?dHqj6V?mFK4QU z$|^_w3MRScg9#fWc-WkkCVi-|;cFM}bj>l_y?Af(;c#iQ+`CJ3BID!l2V7T}e)|5Y zXA)8ppxrF~nyYoBg-lwGzVdVvcNd@Napl5|3&lK#9~(sQur(iiSm44W*nL=tgC*7Z zpZ-6EK6SbM<=^jp`=8U_)paPr;N;1Z+Tm+$ioTq9CAvB^b(hud4;6b}wX9`RYd-n- z&v4sU27`G&3YD zG<53Rsc+>UtdF~K_2O6GZB4h&KHX9*v$p!2^Me8lYj5i^<7f?$e_um)m7WgMYTflV z{`Qo^p|UYD%Y0{VtN;J+{l1^?Zr;3}XV>UZ@vtI*hs}9mzz>^!F>3A!4uxff^NiE` zvQqB3%hx`6@?^=Z?!z|a(_9-xxR$I~zdn9fj^<1^yP_W*-MhJGx|}<8ic3yPXY%Q| zKXMW+1|BLeITzgAoUZLZX=Q-Ml}3yDp>mMnS@Wh-}`^|8(scH<*y3Rxc5h+ z^z$iSX69x=LFFmx(rx_`d1-lNe?OIeow7V=<=s7b8$EoK_CF}+pMPFm&~xwZH}U#U zSB7Mjhi~`LQ4;j@XjBn8dE1Is&(@&;`Xk9&gH~I85-B-UaNSFCO_*kJd@x=4bp})EM z&nr(pv6o%ptFPK*&(wUYf*+Y5gN2iYuigx=uC7*^7!euwGbY(_wx*zW+>Xg7pMKKI zn=Tgnx-|Tse8RBpMk=;Q&64`J>9G}G`(*EVzt8Qm+8uQA$_vhmIiA>Ksn^toH>7Oq^lcX8~` zTwNVam5Cl|Zff~IHn|8*JpK4oYLO0~wgAVh*|Saiv@Lk}_J&zKni!%b`his^SIo&n zY08PEMXByHyJjwpjLnT@Uw-()6W0A-rKP35e*OB}^1zp+>C@i6dAn=Zu2-*L3p&}@ ztzWnA-TKTOi5nwS++V$4x_EJNYG!L-g46ut2?lW!Q$_tni;hlN8T{qTmkkj)#l^+0 zuCDdh4jwuMC+LKOsLc&2ec! z{Ldy4sin=g6(^q*aFUgk)jg|w{;C99_u)qq-k565bXxpj_s=`)=5-5M-L`&ev{UTs zPPXYwx2kUMzJ2rJ&nD&GkZX5tcakAF7H<@&c8FG@O$uk`%_g*0yJ3eHaWNRWg2f`u3^6S zA$4ue8mU*(^F-_%Ii^mVc5heV>z&CA6Ft%|oYp@5`~GKP8;cza_dPteRXS*9h}z`4 zJ4zQX+LYAsU*M}z+`PECv2#UD_50TRQU4ic7IsVLt$EhzIf z_`My4i~C=f|MpZ6*l;taMPT;XX{Vp^_VR{?hK6W`hKGk=)iN&2bAl=zYL&!0UtWyaNa#b5v0JoB61x9xfN zcGZ2})!WMp+GS&MuQ$`6Z2> z+>w7SuQX!@Z`e4$NT=j`+YiGFFSDSvvV`8v(Bv8Xa8vFNAJs* zFPYcueAqs}?!coBy1cso>i(U!k6ss-=5(cHy?M>tsWU|%$S?SqWwi3mv8~de{-vp5 z?cyo&PfRmjPFkui>>szg@a&yCcTQgPl)R9?Xv2nrudl9hDDt%*7XM^kw|$~xI*+7T z%GFb$R<~@Q*W~2nB#9q=cXRvmPg74<*!(;3P`TNL?dY*%T}vOm{eMqy@<|o0&KQ;L zo3_2G?$CD1ICI0W|FeAltv#K`76hIQ5f`8S@NnDm)Ma1O-{1Lp_?+$UZ#wb2Vwxs) zv?fW-6f;&|Hh;FHu<+*x|C)dJKaRYmqwl}ISK9p5%hwxAB2GV={_)42rG?%rMOHaz z%&@8awC6@;$gS1=RvYDyF1zRdx903~Ha9jqIXlootkd)CtY=tS_{_F@`+f2L|L;%z z@2GgR{eF#g(vyyT@ddAXR;H$=dWugHIQz5WN-J6U z_^w@<^MsAe&BNy<|M~Oz{M6tVC00{iu0~97QGNRSS+|Q)bar%$z*M)tUoQK%^GVP8 zsmUzqGtKaNvOWxml*!(_V?6+-#?m{8-lh&5qec+xKjmbvbU-ITz>GWw+ ziz;JkYyT?mm$$5aRFYYlX>Tvr>NIiItgN)OWio7wuYguaOkW-tOpRQe>Syf%FU7hxWsV>zuwc34mjNbC>i(kKf?d|EAB06{OT;GKObLP&S+8rJe zVq$8_%F3$wTgmIR*H0(AnJ(M5YG)&$d4;s?5yH^v>=MQA#zMsi&v6 ziof~pk#+0ViFLJ_aGgDM%q!e|`+WU~$jF;Fu5=uJxJGyF&X~OD>gb05o9{1_;ak3G z)1=dnl~{|)%C1RlnLK;8w}L=S?0j!7x#{7du}3qXKiF6yD=V9wo!$Gd+;0AUlRV8s zi({?J4JCcPM!NUO{4D(5-_9>vchgq1Vb`;3X|mJ$KDpdH$jn~;_Fk#Q!wvoG`LFQ2 zxZV5OJgk1(uj|eGfANIfj((Eya=G_S-#5zb{a?24yl_0?*W~4X&z?M)VxzmW=&9F- z2@iN*n;&r1`>*l+{oU`MK6ve(|LxAxqTIKR2OX{JZZLkm?0U{M2t#!%^0j9)PBkhYuhAze{@7KJ}lKKl$ZsUf9}d zSY%8%zF>bvD&HIX3)OdKO`Le~!-t1HYM=jxO$pJO>iyK^)8=)2J45uQbxpNR{(B|7 z-#4%@(7n1nLMiQngxEAOt6f$SJkS2@{4A~?^X98j#=oYY2c4Vjm&g|0-&ecbZ*I_h zA#w5Wn24Cz(6xb=F5LL=m{mUePWk5fKWhGcQaxSmU;eeAH&$Tv#n4aJC!b7}V0Ei? zS?RQH!pT&r#rqDt7UF8{m$!dsJNIZ(WOQ`>2j`HRIc2`SzVBa(iHX(!b#01_jNIGa znVp##86CYpY{tLbgY~X^uRNb$ziyA@yi?!a-nRe!#(0G!!@X&{cI}chPRqHsXXpDu zy9d4r3%M8=-k+XnoGxcmv7zXx*9!1yf9=cGtjRe)&z581rAt9inL*pneiZ!p^=sPH zsfsNXHupBAo}M&m(gHuwoUVMwWOdX0(t<}vI?KyHgJ!T9eyk3TdweW+Z!vfe9GhI~ z|1+)J;#KEAef@fMhph$p@IZrAlh^G%mE*w_~oPC{5$dzbzB9=RS7Ye)80*N1qmj z`e$cnn{rK=K7IL;B`fB=diiqa&Yg~X85tCwvbSy7vL*HOw6B2)_xIKQ{`NN5wzsRR z>AwLp!=JN`{b!B4#r5y)D$Ta%4qkahH+q}HQm`%_89s3-sjR%bd-K0s+ZD&aAZq}+ zBjAvoo!y04@O*Lt6B84koJ~ej(xvi^9UUD-`DJ| z{_b>&8RP+**x0)hCJ0!~U1xXk+O@J57ZwIsGB9}jh)$zv0#>>lmo2@{b=jtt*nw$0G_H+m=y8LqG%9VfjByce>{Ih#tXSV*qg9id4 zB2V7F)125A6FP9KG<){mDwVBD}etmBj^?aP$FgkB_XT} zM$jed#S6A?s#nsRzB}!z)K^Ul9lfNGBR@PJ?~J{({#vbR_PI3&8Jh*2)cfYG&{-ez z|LiaR%+K=6>}<+^-TAftdiLhH-$Flmv&}7TSf80^F5P}ybGgQouHD<;&GWI@S@iYP z+}q{*3N(4xgoVV6YM*^6oxlF|ix&a&pIV;yJUMm#mpGRLqA?!3CQO}t^z}1IX{mO8 zZh0A#84hX(?r|$TJ-FI)>7_Ska{TrE)7jH?*t!J{C2icbYZr&&&X{|*E@=sMO;OFx z%If0ow%>48oYN&&H@9f#AAg=oK7)&RDN({sX2JQx<2gdjf@E#s*;(K=J|JX^0Lj0 z45ZBS<}B}5cUrM|^XJv2@kh_}34UO?o*(mGsD!sjUc}h8?a&ep@ilAK>?!>m<{8-O zpkZKWBq?rsu6Ba;A%&I;8ArjW9xpx~yzw!3)oc>-yGh zUAuMa&d{`~v~!E+%&+_9dEVoFZ7tWmxO)o~7jo`bKQqg++eOXP%yiiuPtb9scLHS{ zPBmYjFm2kg$DgOznyCn7{@U`=B`ba}@oo?OwdKp3nVW-``^+_~mg;qz+?g6adA*!PfkKVTj_K>Kuid@<5A)ya^_%Cp zs42D_aWZ6Uu1vMnc*12PxL+f0;`H_6V$Htw6ZWNEp4PsSf3ceD-tMgWUteCXXRkZ@ zsH$zd?>vi{sRu4;B!=pn+>6)li9L`v$ULR;VjbgzPY+C|*y?8I zWro=;yZrLv#f!De|GdrKzIM%;rZ$#`oE0qs6P;v4Eni(a>iu==S3f;Jj^?JrO}=M* z1e`dU+gSK-{{Q^%TVL7JO}lpOx;y9H7xkAhdf{r*G!42|b!jaOIN{>cA`m=VQb?@n zXyQhTHFGD=_0gJbQKvNdqzgx&hKRoZ`ZGN~8zXuIs=j=f=%dsvBksBQqJWcyQr?RX z3pv|`xa7nuepVT7ooRa2v~p(Uy?^&AnC5xBi&smU(A?eJKAl~x+m)m8XT?K~9c|0n z%0u4v^7d}ezvuS9{)?n#Qp)=&@1K>a$NC6yuzY@g&V0L>zqkMH;^%%*QBf%&DtztD zvEmM=n(JoTmY2QXyuNnDs?A@K6rLV&#Mx^AY%ZtgG)f_2kGh6)r z?V+TNw{G1!bzkz-;^|HcA8`NB*IpB#F(K;v4yT0^PCxy-{@8>I6TZf;zi#on>cjJ9 z$xO*p$A#7W6EY0f#qQfybM(^*&WRj~{__4aBg!)VFPv~e;OTmK&<#1a-4z67WMz}Z zk38}?FT~YP5rw+J(0$4y|POWUpe@|VEVcETRXF#&%YVpS;5x4 zvFvS>(%VRD+3tf#Pp_<=pmd+bZYwl`At#eM{B1U%q=W*0R+{EjluCu3c@E z*2F_~912el?tb*e}A{{?v(AtTdJe}Y+1R{vocIl zQAL2Gi@RHQt#0QL`}>)4Vsc_)a^Kd3x8LSsGa^)m1vaDIMv{_`#UGRB+UvzA8gDv`2%>2&FZ;bKuP*IUh7 zrrg%7&yzjYBUAkNSMOWvZS^w0H?}TiWov%;`G>22*Rpf7x&*9BK1|rXd-t|=W@7DY z*RM@C-#mBDoO^kyKC=yTuXct0{{C*hWwn~~Y(+uub*k~Fbx-_#v-$j%E%$CQNVv1R zyR#o>uI3Bi46*8tiwdfGd1&bd!9)=))^E-Xn*8@fow*O2W?!3QU7L4%S#E{Uyar`~ z6D@{<$#FXu?4A5~ie#|fyuB6XPxV@z3@;f=30pq<^Ye3klB@>LsZ-~}Uua%>f*P?bSa&KbN8&N`SSJa)aNReYv)|s7PhZJfBH$ykgkmj4JRLcV>@Hh+O=!nvA!X|pOs6W`cb*pcW&xa$=rF_<|U27U@x^CS% z6)w-(UyuJB=dn6`=+vXB&NiY&uEEK{+0m#=O3 zoHWCM>f&c-X0r3kt%=zww2CQ6j^V>XO>OPlo74H7R&3c4@)NwE*G^{NzI~~wsT_)O z{o8YHZd$TLWd(SpGy9__CnqaiEOu7(n`5!ikQH=#2wMT@c$9rux`w*?`t4fao?HTn zeM7COPO+eKQ`lx~*|KG2@bXU;d-iqb-q?`%{@&hzSkN&ijnh9JJ$m%7X626$i7VD^ zXU+T0%?yj$YU zn>Ts)_pPmxl9gR+IHTzEv$Kzn_qTUdyuRGxoh1TKYjW%Ws1nvU|U;Tb93_*phHsr9GEa|+P0jVo9wvW+}@sle_!pY<$-~L zALP>*8unYh*jSnN@zK%f?Rjt06Sb!9N@(VuFGbXUyQZ3R=u8U!kO=6gTtJVz*u+Gqbi`ObiaE_&q?U zr08mCWnEnr8sH7;&NX&lqy=WQ*29|t-Z zX33w1<*Qdq3kf+bzkF5w)~#E7vQ{Em>-$qY~j*~9N%Q1Ibsx458FiIuIX>DKw+v*7O^kKWzyo0|G`qO!Z)9xg3S zO-GJSmqoqO=7-)f9k~5BZKZYLBNsovbM0Gth~B6Ew0_&4<5!Q0+Ql*)u#bE+^T=U${{OyVY`>l|GCXhwMJ;HlK1Kw7Fgvin zx_STlEj?ShPI0lbv&ZYlUp>M-U5}%sso@}Fm{{2R)U~IyPhB>;RPwdNy3xsH0PISc3wVcXl7JbuBk7; z74&X7hf34Mg^O2;WWAqaU-oH6^JL~FHXx(o%KXaG+|tCib1RnozV}vBc=?|1p^GlR zG-~Z}P}sA3`-7sL`~QB6Hs4>p;{Antn*J(6Teog~8C7z_mSKsF#Em0Kg=KNu9271j zzAP!+{qEj=>$*D?N{v72u4kQFW2w}6;@+`;wQCzTPyRf~e_BRn=0Q0og{KD(Tsx7c zQx(;s{@{3zMDhEFdygGEc4_(2b?e^$2!#8FTKd^!5B@cS;IM6dufft^4!+zW;GM>r$_D1O}`7?yY*9b?fk!wrgx$ z6Cb^KA!BB9=KSq`r)4X+-rw8(`&MsuvRmIwo5D|5Ux#15G*47c&hF0j)8TtRa39s{ zdslNOIom#v6slW9t>klq_HZI)QzWVryhstl?z7ceiohvJO zQ}X7`o2jCyx@&cfcKU=zUq5zFttMi}_IC5Bw=NrRetcZkJpX=(-M@^7?x)x#bkvND ziag&4wOrULeZA~&`Sj+=hu7uq4tcLP`Q$0>Q~CFH&73;@>Wxbs#~SZ^yO`G1tj(*x*Ov=-up~Pt zyR*A5ahPM~m*$oh=XdYQikc%hFHx15lV+Qg}v?_WIlv8jCe zsUXKe1>iId$oac_ElekSO;yMqZ=#CO)dFAEA15^FX! zHJsWFnwazypY$sGwSDA=&W#fd-_(IZqgZ#&v^`BWy1Hu__A|6hXy47=eRS2@^|~uH zHg4K->4eVCn7ELjBNvj6=ynyC7akY>aCgtU)8=~dd&^8;22EPJ^{K#q#aFG|-Q1E< zJ*wQ(ckJAu$*msmzpw1?tW5~QD?Zjg zvS0_@P-i=ReXJO#E2APK8yg#k;w~}Uiii&%7azYYw~X~Co1p|x?e0-_s&pXKvkE`lqX+cGy?!FB_fQB|smBF@)Q4@i+O9|4zS0w-;=WFA-Me@1{%Yz^KfTjNZ+C0#{gC+k zA^9089RjOXt`zJ(TEA!=3zK7EprMmSiN^}9N7ZJR@0_}PSy*w(+?i`PUYRj5IYe;% zlcz6R1+sE8r=EVYft@MibaVOZkB^V%&M^~C7Iu$zzk1Sv*_K&deEFO;bFQojaj!n> zmlZ1;%UsLc+gWz4OoVIc;?>QU4_?$*vwr>h$Q#G{e3Z&dvc&3^uG*y4GGX#w;h8?~ zcB_P+*jxHMtSqf8Jbk*0(nRei9EvMLx&$7T753H@#KNB|I_QRb=lO}q6Sz{pPyfD}# zY7>W|Zkw1`zi6lHtJdF(doQ;MBxP={THny+v`|A&_uu<}|HHz=UcY>0ID?0)b}*h@J}{%?)$6-92M(NAuxs0{ojW6yCQk5JBEEc&!-VOx+c#*Wx%D*fZT_WG zCjHwttEWNv#io+kATTReC+AAKr^=*l+ss-f*m=vB=`v{Y{}cPc^zZC!^HigoYi2}l zUViRf>;uPR&3EnJ>gj0eXzCUg7Y6&TU%66KS6B9lp~ux((@v)FUzRW08RPBkoqYNE zv4-m**QZRKR=K0vCfwq!V*l~YTQ->(8CI<={U-h9yT<3hSBtM)Tvo; z`l(Hj{PNt5y;Jp3w&rz{=;snVeGSeWo~f6@_gT+$D%((=k(alx^!c>@>HWWW%WhfZ zO7aHETGGbmH&P$BnS2pwVy09H99(g{ zcwriR@ACOOSN1I3`Si!h$GpDhd(S`owBzd5s~n0pa`_AL6+}2U7tiM{7wl@?{{HT{ zGbgU({C@D^)WSJmd%v!)Dc5R!_4=*%;!8zE#qaLyUo5ra@Z-;Var+{oqfaMoWMX4K zu#Rh9sQi&w4EQa4vms%S9_j=uQ=bm&~vuaeXJ z(QT}Ji?c6FXG!PX-+MM~^I4y>$NJ^`4+vg~KGpWC&40e#-Cu{VEo^jt=~LzGd-!ej z_M17|cFx@C_VC|@%NJ+cRsL#pW)Hd?d{Z|^++5td*n6kby@2}xF)?ov-ft-Q=cG0D z)#JyL=gg^jbfxpvt}J$T_LUL8etdlVW=~FV@a0RBg1(BYOzLh0;f91eXBRG4p2FB^6bg#IqnKV$9iSc z(=yn0i#1GPe;;4!TmB1xJ@_W`8f6nFE}ZCA-!Xmp^#zX2pz~1g_uFc}dH!~L!NEiJ zg~|ppeC9SeJLb*1_c8c*_Ny!{{ZKCzAss$%wTUxt`8?HaI;rxh$J01PDAFy=?bFmJ z-P84iI#|S-pW2?Ne$>)=I$Srr-cf3*S>hcQKk4PmmZhCPUoBG9`l~jlDmioWqv^+9 zzk0E3>2h0-+JeW|cy-vkmj;~mJ#)NIR$5NzpWpk*JPb>0Ug)opkv3K1YCc#|UG?4Y z!qG!llJ3o^WZLKOcTv5Ln6!*UPHx`cB~Lu7)2+q2O^r>93yTsj&D78N&&Mm3m7Mqa z$;-*#&Xwu#Wv3-Qd-Y^hVa7-KH|y80fB)daos*Y7K0e0X(sb|dd%1UVV$;O@yXKpi zn{u-->ByZ<+N7hao4ck;>Ooai756iJi8uB;)@}3C5xbmWl5Lz_U0rQC>G+ur#Yr8j zUhfxhI_Gyz`%$=vxajt6+fS(&@vtT5-!ERD94&o&hNPiX{R$_=;AdxNipz+^1cqL` zc(L*D!;;dHxw3P7&-z^LHhj@DL(O5T$Z*>YUeff;Nsxm&-=L8dH7!3U2L0pr)B!o>uDMMk~T~F#g_zTHtuU& zab2=~hNR)F z{{F9Qp$wp2Cj-1A)y&_svUBC`)w@@E?%(zJtk0QW@e&Llo;`S@T@fs-?lZ?CG0C3W zziXa}W|dHg6vKsS?9g8G0{{G-$DiFgo4xbr&VaQH4fUJUTm9{BOxa)e*{bFM1H*^! zje!~>0o)7>9~L&%RWe}haD%o~L*1jv&%p4&`AhxA9j)3{mOE1!7#J8lUHx3vIVCg! E00d&@9{>OV literal 0 HcmV?d00001 diff --git a/docs/reference/glib/file-name-encodings.sxd b/docs/reference/glib/file-name-encodings.sxd new file mode 100644 index 0000000000000000000000000000000000000000..46750dc17c54ed6462f960f00ce354397a62729b GIT binary patch literal 7006 zcmWIWW@Zs#0D-GJ&l@~7zOX}vfq?;pIT#oiax-&NODYRe6AKD*GLsWaGV}BF%kon6 zic9nKDspr5Qi>AGAtrDza4>*O0GR~C+zbp1$@zIDsd*(J)mNkL<~_0y*>`{WiL|Y& zZ*mKLa$gWFan|SdMUTIeZ$-Y13soyzVd^Pkx$wZABXRG3zn%PM<7a1u2@Os&ot8Ge zP5xaoe}8e3^tt=znd7St>ZqB>oSJoMs;Z3D71f6+8uhh%UVVA`eewKr_4{`G{_^Ad z-=!|L{T4sYEIns(An{UR#*72IOa6a-{B^qjq&tCEcXPCtAM#n4vuKrgzj#p8z7tiR z2K}qz?wy)6r*HX=PVN44+j;ry+CE0!vYIk~vWiu3DA(l+Pfe<}-wwUJX-;X!1AhqV^Ccr00#ese=a^YoKy=Yzh*bL}~2 zob>excem=?w%ZQNA3i&F;L2yQvR|)wO}gsMuY13X46wE^*Z5%B0mdD~V zlY^Uf?S0)6y30?ZYhI`D^RI$QHV&=}Cx7b_7TMMD(c)Z=#D;@HP05^LQqK~$o{ruqMh&pwhr`7GIf%08LQIpIBn)|qQ><1Bd6Gerfie`RgW>O5@a^p#my>yNjj z>?uWF#RzYi=PPzU+IlD;D_Zr0@cOi-nm4L5MXx8NA9|q^Ke5HPaOqpg$tQ~^nOA+$ zQAiBD`SkVlt4~jJg;on>%Q&vAx}FiRDs(HuQog6{t^yBQ1l@lfXy}pB{qCjwhoN@X z`t|2y4_y&lFYkJ|R`o4omdcD9EfZghZRGTr&hF}YCQ~(f>JD}WtDigeFYGv0U!%eq z&=RQdw^MSGT!6%K-d5>7{w_l7DxaDpJj+E4B-;0!bB*(L63_a^v*fo|laK$Fb?Dag!<=?e_ZrxgK&3fYsg&WrfE7 z@9*t*Gt@TR;jF%3__f&L@{If(XYsOUhm3Alithd_WN`Uc=z~?COZa7e$yu}{$|$nC z9V)nUEUEj<-^k6&*eH21gp$b0LM{o5nUOK(5ielP8rwrRSwUFmDy+G_^O-X)dj z<*oU_T2oa%HIJh*a`I>I&8~%q)!u#BtbN$xpwFE<>AB)JoP+1*m$xz=_6w4AxbsAO zdW!b;^6!=1{bGNl6)P5BR@v)z?!{FdSM#H)w(HNl&q-8I5}#T;Z@$UxQ>VLAErmU& ztbO(BN~H3d(umyl&39gO9a#1=k#R+HPfp%!VflmYOl8L!94wZ7_SJb29cdsHX&|yV zd+lU~Q=88SaV|@ml`5oj^qQ2%1!<3lGK)Do^b+6q+<$FxqH+79gE>ze!`aGO*?CXA zoLX_gXX$lY8^J%>Tg!imiQO_hW1lbktAWLwdoBBwo4!t$r=}Jjyu3Pz|JG;g%1;XS zDt>A%^uK)M_5Nz^o*P~FvQu1|&u-j#t}|DDl5qdUg!-@=p+~+w648}Q!P<5O%dh!-S$aR~@Zr;UUQNCG=ffqD%NaElkzU*5 zC;7!+T-%oM%2eaH$NbnmBHk)f!dQZ@U!3ATfBw3CG4c26cI>R#wdZe1`NyZUsLaN|uuO}A0e9WP z#lXN&TvC~nS`4aM-bTmg-!>DdzrXx~Nsj;IugA-z(hJ+RW$xznjMm}ZV0%d@b@No0 z#zl`(;*n${>#=Fh?CbJz(Z`>iPrpB>uKM4*r|tIl_ZwwM2+7Z9xpF>vPJ#C0a=~*w->>WI z)zxOsn3lWWyYQ2rSFc9&t#3cui=F@4>9a|Gkhop<^_q!~>0ONnjg@7$49zoUq^NgU znupI>uD;Fpq2`vVuICngYwKnoWw6{89_N)&*q2|qev5!c>%~X&b}nrZ)l^(oKlj$dFJ2aS6lzi+9WY`*Bv*NpI0>XcSf03o-rH|a&JJ9u`JuW{<%*+T30JFU6@BWRJ)bBi6v=R9`cZeAKDd(Cp2exv69 zoqJZ~oPTuhWUE8x`E-@H*JC@&8Pfsy{w)27R8)(5}(n)nO{4>tfjX?%A_R3rk%8oVjvHliAwPPhpFw z;`t4%@8mCR6%FdBp6@2IXUb-oJqAnEC#_iin{lbh@0UvZRga0Lsf6tJ{d>XdO4K73 zmOndBX7o&IbMe~2A6M8c5m>lt{-lZf57^yvStD^lX^Kwq78W5tm4nMG4@s^ltiAfp zV~XGulTsJYYl{|zICO_+T~TRKi*k6mct(`!S?`P>KAkPu$yc|2$(-XR5%!BYsxh<9 zM6YN*iw1LOy~&n$O+lCAjOR74npikj;D+*s!pf_iYim5rcLgmGjX#;|eB+de0%lqtK`NodNMDvzbVES-OZ z#YCx*E6%lvf!jr?v2GZ!=>X|huD*AJjJiK{rsTzdEL~N@}+M& z_8Wb0e6H%bhNFFtL6U1q%FbKMn)GunicKk&dL6pM{^!*{v!2CRq-Cy>I-PEEx+T7; zr?2DNmY>s(blVu$iF018@J>H=bn!BO*Wl+HTx6n@Jg0fRo_d?>feoiYaKP+f<0Pw1`hF`wdWV0zNPYohs6?PJ}1ZECCIw?5yKUwxsN zqoAW|Vq)*>c=<^w(M6l5U1ZW)SifxUvZ%dT&NnyhiJBtU=zOC%%OhLbTl^ZI;LAN0 zZM|-;2d}+5UEop>@i}Yf#Wh^(%VeKdUly1==Yh+Myp@-C=^P0;Gk>mEnaidk=9L_R z`wj*&CQWn~e3oV8+5WP7r|4;+=P!5ud~aXB{jJLEosYRb*~mzWn^Xl{%2I1S`K7wh zZ_96!yNvDInfWv|&NE$OI=oS~JEdMFX#JBTO7j=9+N`~^xUZ|^@6|){@7eFmR#F8@CBSu!Sn7XN+F&oA|7v+Y6oibvM>`2RgQAbdY3{zv=VA2I3ne=e^# z{(SYu(aLqZiwpdZH|W_V&0o*SetN~Uxa!9a-yH0X8JOA+icQLnjCD*?>-MsTA z)5hj?zKzE3@84wK+&#PE)n)gM$$>xbP3Sox^)zsn*neiDvpZjGv0+QQdU@j1^Ub2c z`Z03n`$J{7O|RmXx?{VyOM2%q+a|BF^sV;KB-fa|%QLiF^=nnA^u$yn^Hw#LJ-20< zmLvtdJj*wu5T1rnv?<&P{($YAAJ+ptj7U<*@Q*ntaN5>brK+6ft~ zBFB>tW#{kP7ZPeT^G(Q9j=6W$Lw7xIYOH#_KYHW4ucEJ`&rFkM%hkW|I(1T3`J0TO z_r|lgtbO^|$Ge2rx^3b6^J)Hh$J0`mwdGt-n_W^Go&2Qi&UFpRt)Wu#rRy(=ul>De zy=^=H)Y}0&dC`g4R+Z}wxQ;A6p#RHju?469o^^{iTrU#)R<`P!$+_jaKkT>zzVE2p z9vSb+_MfY){r}GH&C46^mu;P0pi%dycCAqIl&5b3Yxl=}dSAu4P|J3;H{06BQq%cY z1=_yP-@EO`Msqt}?Yge>(Md--^E2DbP76gFo?7rDC*tehrI!njZhyxnYq!BMOtrMy zaqY^Wex`ljb4+GmdHHMI=I4FOHop??m?CJvmb&EEIfEwAvo%w$-9LU^;a>l(T869} z#>Xz}y|=fTwQXU(WbihTRf@dY85^R*Eg11L2^VT#=iTS8N55vQ^3`DJihh*Uv9V&4UPm?JzPh zFwlqal@uTvDsnROvf=8>%ggo3jlpUSEiEne!Ll%=Damkk1*JtfU{xu}`l&goApaHX z8|oSA!_^HPfv zOY)2CP=j2-P|r}$P(i~dGq1El(?%anv5lgxu9=CchEr)~PKuRpo=Q#0EXmAE*G;ZW&Pgq{Gl5!&CXA{!rL+j_YP*0CBO_lU z<6tyRaCwNf(&E%2-IUa{%)HbT1#sZxCFZ8uDtYFmm@Ga2H-{G_bZ=QC;8W%SK>sX z*v~|6?&DwU@Tu0?+WO=@`M5t7MRN}+8^{M2t(@Z5?Zw#Psp~Us`YE6M`ExYwv+862 z+})G+;&b3?2XXG4Lpxp19$-D>U-KYl%UABjk$dlFi%by?-TSQ}=J;Db&FEEG!TDm> zuAlYY-lPz8^;&?YM)rZ=?r5*KN}{n5o_{`nee8Yo*&XZfP_2p=+WtEubXL92PQCo_ z>xEni{q8&(@lS?;igVE0Y(q;rz2CNb@P%{-a{sCto=I^wanEJ0I?Dm|nK%>r$_k zpS}kC5f-mhpAqqa<(i&&%gJKV?}Cj-!`dTw63^c3?uufp#cUI$O=|{l>)&Hg__%9diwD}?!b%d9>hnqF;*oFGsyUxt8Ij)Cb2HQO z#!;3+iNJKx-D~yp3Un8F-ruyUMvIT)Lo=V+K+D`L|1TS>F)%)-x<;)JQ?H8O+eHS}rSg=^tqxlJw za{0$k|8-uSQxPw{zv;RWZ`Ta|mDi@9x^LWeTKfn4w&zay-B)L3{n&n3`) z{oZ5Rtml@iXY#Mj3b(NO?)7ed34u?S1VNAV{V+3*)#L(I<-%^ zGt(j^&o;4g$>{0K{v=@_3iFc*Ryu~AUoM~F&`qknVgEku*H6z59i0Oy>zY!xoqVa3=M_7* z>{|0*E{TgZf|iRLX4p(n<@@p{!hKEfuLlmRP86CnSsBTvXlUkJF4;S=)APthUH69_ z7jMr?dp^)*{JgLm*?@IH~rrdH_D#AQ)m=r#_)ul zCoRSQ)tx1&lJV}x4+`vHGnmM^Lt~@D*%kJEE>0U$PHbM@`1;f>g~u5Z>?aP^m>Zu^ zUU+oFfvQJ5qLa0zsk~o&b>Fmavo0OE8mqUiMRjNEdxp-W9GBX6vw5m*#4n0eY?vLm zuU_7id-wkpuBQ#}%og1x+t+()L&mgr?UHc)tojG(F}ozsA8MX;FYA^=@$uK(p|;uC zZ-3AH@hhRDI(U1R`rNWYyQ}l0mgpV(x3!}F`f9&Z<_G`Y_0Nx6Wj|}`$Q|n#x;pjh-^|6kKVIDv!+Y`V+0P#Nv7GmBx}}H7zKFU};Jxi- z)Vzm&IWBqg*7}_^Jh8(nqa|_w%Ad?U!~kTFzg`xkKfB!|ssox&I0TMk`4 z_;pSWr^Bj83*P;W^78%tFyd`IXgtV{QO=6_C#uAOdu z(QCEzr#*A{7Tw9WySJT5>Bympy0hG_i8=w+_W!(nyiRwxyGwdJ?^&nX9{>2{svG=f ze9p;NPs`7Uo^^1>2~WGUhK6$A9c!oTdbUu#e*LkMG#Hm zw}nn0Pgi}mVaxO_nsIBdz7hw8U)1agSN}3FFuY>|g&!l62m|i<9#HEXfnl>h0p1W@ zuy98np##nFAappP&iJ5fMD7lN2JjFX=dmFV=fU)W + + +]> + + + GLib Reference Manual + + for GLib &version; + The latest version of this documentation can be found on-line at + https://developer.gnome.org/glib/unstable/. + + + + + GLib Overview + + GLib is a general-purpose utility library, which provides many useful + data types, macros, type conversions, string utilities, file utilities, + a mainloop abstraction, and so on. It works on many UNIX-like platforms, + as well as Windows and OS X. GLib is released under the GNU Lesser + General Public License (GNU LGPL). + + + + + + + + + + + + + + GLib Fundamentals + + + + + + + + + + + + + GLib Core Application Support + + + + + + + + + + + + + + + GLib Utilities + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GLib Data Types + + + + + + + + + + + + + + + + + + + + + + + + + + + + Deprecated APIs + + + + + + + + GLib Tools + + + + + Deprecated Tools + + + + + + Index + + + + Index of deprecated symbols + + + + Index of new symbols in 2.2 + + + + Index of new symbols in 2.4 + + + + Index of new symbols in 2.6 + + + + Index of new symbols in 2.8 + + + + Index of new symbols in 2.10 + + + + Index of new symbols in 2.12 + + + + Index of new symbols in 2.14 + + + + Index of new symbols in 2.16 + + + + Index of new symbols in 2.18 + + + + Index of new symbols in 2.20 + + + + Index of new symbols in 2.22 + + + + Index of new symbols in 2.24 + + + + Index of new symbols in 2.26 + + + + Index of new symbols in 2.28 + + + + Index of new symbols in 2.30 + + + + Index of new symbols in 2.32 + + + + Index of new symbols in 2.34 + + + + Index of new symbols in 2.36 + + + + Index of new symbols in 2.38 + + + + Index of new symbols in 2.40 + + + + Index of new symbols in 2.42 + + + + Index of new symbols in 2.44 + + + + Index of new symbols in 2.46 + + + + Index of new symbols in 2.48 + + + + Index of new symbols in 2.50 + + + + Index of new symbols in 2.52 + + + + Index of new symbols in 2.54 + + + + Index of new symbols in 2.56 + + + + Index of new symbols in 2.58 + + + + Index of new symbols in 2.60 + + + + Index of new symbols in 2.62 + + + + Index of new symbols in 2.64 + + + + Index of new symbols in 2.66 + + + + Index of new symbols in 2.68 + + + + Index of new symbols in 2.70 + + + + Index of new symbols in 2.72 + + + + + + diff --git a/docs/reference/glib/glib-gettextize.xml b/docs/reference/glib/glib-gettextize.xml new file mode 100644 index 0000000..f016b28 --- /dev/null +++ b/docs/reference/glib/glib-gettextize.xml @@ -0,0 +1,88 @@ + + + +glib-gettextize +GLib + + +Developer +Owen +Taylor + + + + + +glib-gettextize +1 +User Commands + + + +glib-gettextize +gettext internationalization utility + + + + +glib-gettextize +OPTION +DIRECTORY + + + +Description +glib-gettextize helps to prepare a source package for being +internationalized through gettext. +It is a variant of the gettextize that ships with +gettext. + + +glib-gettextize differs +from gettextize in that it doesn't create an +intl/ subdirectory and doesn't modify +po/ChangeLog (note that newer versions of +gettextize behave like this when called with the + option). + + + +Options + + + + + +print help and exit + + + + + + +print version information and exit + + + + +, + +copy files instead of making symlinks + + + + +, + +force writing of new files even if old ones exist + + + + + +See also + +gettextize1 + + + diff --git a/docs/reference/glib/glib-overrides.txt b/docs/reference/glib/glib-overrides.txt new file mode 100644 index 0000000..991fcf2 --- /dev/null +++ b/docs/reference/glib/glib-overrides.txt @@ -0,0 +1,294 @@ +# This file makes most of the thread related macros look like +# functions, which they really were, if possible easy. + + +GLIB_DISABLE_DEPRECATION_WARNINGS +#ifdef GLIB_DISABLE_DEPRECATION_WARNINGS + + + +G_ATOMIC_LOCK_FREE +#define G_ATOMIC_LOCK_FREE + + +# default thread implementation + + +G_THREADS_IMPL_POSIX +#define G_THREADS_IMPL_POSIX + + + +G_THREADS_IMPL_WIN32 +#define G_THREADS_IMPL_NONE + + +# threads supported? + + +g_thread_supported +gboolean + + +# GMutex + + +g_mutex_new +GMutex * + + + +g_mutex_lock +void +GMutex *mutex + + + +g_mutex_trylock +gboolean +GMutex *mutex + + + +g_mutex_unlock +void +GMutex *mutex + + + +g_mutex_free +void +GMutex *mutex + + +# GStaticMutex + + +GStaticMutex + + + +G_STATIC_MUTEX_INIT +#define G_STATIC_MUTEX_INIT + + + +g_static_mutex_lock +void +GStaticMutex* mutex + + + +g_static_mutex_trylock +gboolean +GStaticMutex* mutex + + + +g_static_mutex_unlock +void +GStaticMutex* mutex + + + +g_static_mutex_get_mutex +GMutex * +GStaticMutex* mutex + + +# GThread + + +g_thread_yield +void + + + +g_thread_create +GThread * +GThreadFunc func +gpointer data, +gboolean joinable, +GError **error + + +# G_LOCK_* macros + + +G_LOCK_DEFINE +#define G_LOCK_DEFINE(name) + + + +G_LOCK_DEFINE_STATIC +#define G_LOCK_DEFINE_STATIC(name) + + + +G_LOCK_EXTERN +#define G_LOCK_EXTERN(name) + + + +G_LOCK +#define G_LOCK(name) + + + +G_UNLOCK +#define G_UNLOCK(name) + + + +G_TRYLOCK +#define G_TRYLOCK(name) + + +# GCond + + +g_cond_new +GCond* + + + +g_cond_signal +void +GCond *cond + + + +g_cond_broadcast +void +GCond *cond + + + +g_cond_wait +void +GCond *cond, GMutex *mutex + + + +g_cond_timed_wait +gboolean +GCond *cond, GMutex *mutex, GTimeVal *abs_time + + + +g_cond_free +void +GCond *cond + + +# GPrivate + +G_PRIVATE_INIT +#define G_PRIVATE_INIT(notify) + + +# GStaticPrivate + + +G_STATIC_PRIVATE_INIT +#define G_STATIC_PRIVATE_INIT + + +# Definitions for different operating systems + + +G_OS_UNIX +#define G_OS_UNIX + + + +G_OS_WIN32 +#define G_OS_WIN32 + + +# g_ascii_isxxx + + +g_ascii_isalnum +gboolean +gchar c + + + +g_ascii_isalpha +gboolean +gchar c + + + +g_ascii_iscntrl +gboolean +gchar c + + + +g_ascii_isdigit +gboolean +gchar c + + + +g_ascii_isgraph +gboolean +gchar c + + + +g_ascii_islower +gboolean +gchar c + + + +g_ascii_isprint +gboolean +gchar c + + + +g_ascii_ispunct +gboolean +gchar c + + + +g_ascii_isspace +gboolean +gchar c + + + +g_ascii_isupper +gboolean +gchar c + + + +g_ascii_isxdigit +gboolean +gchar c + + +# g_atomic + + +g_atomic_int_inc +void +gint *atomic + + + +g_atomic_int_dec_and_test +gboolean +gint *atomic + + + +G_VA_COPY +#define G_VA_COPY(ap1,ap2) + diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt new file mode 100644 index 0000000..97dcf1f --- /dev/null +++ b/docs/reference/glib/glib-sections.txt @@ -0,0 +1,4013 @@ +glib.h + +
+Basic Types +types +gboolean +gpointer +gconstpointer +gchar +guchar + + +gint +G_MININT +G_MAXINT +guint +G_MAXUINT +gshort +G_MINSHORT +G_MAXSHORT +gushort +G_MAXUSHORT +glong +G_MINLONG +G_MAXLONG +gulong +G_MAXULONG + + +gint8 +G_MININT8 +G_MAXINT8 +guint8 +G_MAXUINT8 +gint16 +G_MININT16 +G_MAXINT16 +G_GINT16_MODIFIER +G_GINT16_FORMAT +guint16 +G_MAXUINT16 +G_GUINT16_FORMAT +gint32 +G_MININT32 +G_MAXINT32 +G_GINT32_MODIFIER +G_GINT32_FORMAT +guint32 +G_MAXUINT32 +G_GUINT32_FORMAT +gint64 +G_MININT64 +G_MAXINT64 +G_GINT64_MODIFIER +G_GINT64_FORMAT +G_GINT64_CONSTANT +guint64 +G_MAXUINT64 +G_GUINT64_FORMAT +G_GUINT64_CONSTANT + + +gfloat +G_MINFLOAT +G_MAXFLOAT +gdouble +G_MINDOUBLE +G_MAXDOUBLE + + +gsize +G_MAXSIZE +G_GSIZE_MODIFIER +G_GSIZE_FORMAT +gssize +G_MINSSIZE +G_MAXSSIZE +G_GSSIZE_MODIFIER +G_GSSIZE_FORMAT +goffset +G_MINOFFSET +G_MAXOFFSET +G_GOFFSET_MODIFIER +G_GOFFSET_FORMAT +G_GOFFSET_CONSTANT + + +gintptr +G_GINTPTR_MODIFIER +G_GINTPTR_FORMAT +guintptr +G_GUINTPTR_FORMAT + + +GLIB_SIZEOF_SSIZE_T +GLIB_SIZEOF_VOID_P +GLIB_SIZEOF_LONG +GLIB_SIZEOF_SIZE_T +G_HAVE_GINT64 +
+ +
+Version Information +version +glib_major_version +glib_minor_version +glib_micro_version +glib_binary_age +glib_interface_age +glib_check_version + + +GLIB_MAJOR_VERSION +GLIB_MINOR_VERSION +GLIB_MICRO_VERSION +GLIB_CHECK_VERSION + + +GLIB_VERSION_2_26 +GLIB_VERSION_2_28 +GLIB_VERSION_2_30 +GLIB_VERSION_2_32 +GLIB_VERSION_2_34 +GLIB_VERSION_2_36 +GLIB_VERSION_2_38 +GLIB_VERSION_2_40 +GLIB_VERSION_2_42 +GLIB_VERSION_2_44 +GLIB_VERSION_2_46 +GLIB_VERSION_2_48 +GLIB_VERSION_2_50 +GLIB_VERSION_2_52 +GLIB_VERSION_2_54 +GLIB_VERSION_2_56 +GLIB_VERSION_2_58 +GLIB_VERSION_2_60 +GLIB_VERSION_2_62 +GLIB_VERSION_2_64 +GLIB_VERSION_2_66 +GLIB_VERSION_2_68 +GLIB_VERSION_2_70 +GLIB_VERSION_2_72 +GLIB_VERSION_CUR_STABLE +GLIB_VERSION_PREV_STABLE +GLIB_VERSION_MIN_REQUIRED +GLIB_VERSION_MAX_ALLOWED +GLIB_DISABLE_DEPRECATION_WARNINGS + + +G_ENCODE_VERSION +GLIB_AVAILABLE_ENUMERATOR_IN_2_26 +GLIB_AVAILABLE_ENUMERATOR_IN_2_28 +GLIB_AVAILABLE_ENUMERATOR_IN_2_30 +GLIB_AVAILABLE_ENUMERATOR_IN_2_32 +GLIB_AVAILABLE_ENUMERATOR_IN_2_34 +GLIB_AVAILABLE_ENUMERATOR_IN_2_36 +GLIB_AVAILABLE_ENUMERATOR_IN_2_38 +GLIB_AVAILABLE_ENUMERATOR_IN_2_40 +GLIB_AVAILABLE_ENUMERATOR_IN_2_42 +GLIB_AVAILABLE_ENUMERATOR_IN_2_44 +GLIB_AVAILABLE_ENUMERATOR_IN_2_46 +GLIB_AVAILABLE_ENUMERATOR_IN_2_48 +GLIB_AVAILABLE_ENUMERATOR_IN_2_50 +GLIB_AVAILABLE_ENUMERATOR_IN_2_52 +GLIB_AVAILABLE_ENUMERATOR_IN_2_54 +GLIB_AVAILABLE_ENUMERATOR_IN_2_56 +GLIB_AVAILABLE_ENUMERATOR_IN_2_58 +GLIB_AVAILABLE_ENUMERATOR_IN_2_60 +GLIB_AVAILABLE_ENUMERATOR_IN_2_62 +GLIB_AVAILABLE_ENUMERATOR_IN_2_64 +GLIB_AVAILABLE_ENUMERATOR_IN_2_66 +GLIB_AVAILABLE_ENUMERATOR_IN_2_68 +GLIB_AVAILABLE_ENUMERATOR_IN_2_70 +GLIB_AVAILABLE_ENUMERATOR_IN_2_72 +GLIB_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_2_26 +GLIB_AVAILABLE_IN_2_28 +GLIB_AVAILABLE_IN_2_30 +GLIB_AVAILABLE_IN_2_32 +GLIB_AVAILABLE_IN_2_34 +GLIB_AVAILABLE_IN_2_36 +GLIB_AVAILABLE_IN_2_38 +GLIB_AVAILABLE_IN_2_40 +GLIB_AVAILABLE_IN_2_42 +GLIB_AVAILABLE_IN_2_44 +GLIB_AVAILABLE_IN_2_46 +GLIB_AVAILABLE_IN_2_48 +GLIB_AVAILABLE_IN_2_50 +GLIB_AVAILABLE_IN_2_52 +GLIB_AVAILABLE_IN_2_54 +GLIB_AVAILABLE_IN_2_56 +GLIB_AVAILABLE_IN_2_58 +GLIB_AVAILABLE_IN_2_60 +GLIB_AVAILABLE_IN_2_62 +GLIB_AVAILABLE_IN_2_64 +GLIB_AVAILABLE_IN_2_66 +GLIB_AVAILABLE_IN_2_68 +GLIB_AVAILABLE_IN_2_70 +GLIB_AVAILABLE_IN_2_72 +GLIB_AVAILABLE_MACRO_IN_2_26 +GLIB_AVAILABLE_MACRO_IN_2_28 +GLIB_AVAILABLE_MACRO_IN_2_30 +GLIB_AVAILABLE_MACRO_IN_2_32 +GLIB_AVAILABLE_MACRO_IN_2_34 +GLIB_AVAILABLE_MACRO_IN_2_36 +GLIB_AVAILABLE_MACRO_IN_2_38 +GLIB_AVAILABLE_MACRO_IN_2_40 +GLIB_AVAILABLE_MACRO_IN_2_42 +GLIB_AVAILABLE_MACRO_IN_2_44 +GLIB_AVAILABLE_MACRO_IN_2_46 +GLIB_AVAILABLE_MACRO_IN_2_48 +GLIB_AVAILABLE_MACRO_IN_2_50 +GLIB_AVAILABLE_MACRO_IN_2_52 +GLIB_AVAILABLE_MACRO_IN_2_54 +GLIB_AVAILABLE_MACRO_IN_2_56 +GLIB_AVAILABLE_MACRO_IN_2_58 +GLIB_AVAILABLE_MACRO_IN_2_60 +GLIB_AVAILABLE_MACRO_IN_2_62 +GLIB_AVAILABLE_MACRO_IN_2_64 +GLIB_AVAILABLE_MACRO_IN_2_66 +GLIB_AVAILABLE_MACRO_IN_2_68 +GLIB_AVAILABLE_MACRO_IN_2_70 +GLIB_AVAILABLE_MACRO_IN_2_72 +GLIB_AVAILABLE_STATIC_INLINE_IN_2_44 +GLIB_AVAILABLE_STATIC_INLINE_IN_2_60 +GLIB_AVAILABLE_STATIC_INLINE_IN_2_62 +GLIB_AVAILABLE_STATIC_INLINE_IN_2_64 +GLIB_AVAILABLE_STATIC_INLINE_IN_2_66 +GLIB_AVAILABLE_STATIC_INLINE_IN_2_68 +GLIB_AVAILABLE_STATIC_INLINE_IN_2_70 +GLIB_AVAILABLE_STATIC_INLINE_IN_2_72 +GLIB_AVAILABLE_TYPE_IN_2_26 +GLIB_AVAILABLE_TYPE_IN_2_28 +GLIB_AVAILABLE_TYPE_IN_2_30 +GLIB_AVAILABLE_TYPE_IN_2_32 +GLIB_AVAILABLE_TYPE_IN_2_34 +GLIB_AVAILABLE_TYPE_IN_2_36 +GLIB_AVAILABLE_TYPE_IN_2_38 +GLIB_AVAILABLE_TYPE_IN_2_40 +GLIB_AVAILABLE_TYPE_IN_2_42 +GLIB_AVAILABLE_TYPE_IN_2_44 +GLIB_AVAILABLE_TYPE_IN_2_46 +GLIB_AVAILABLE_TYPE_IN_2_48 +GLIB_AVAILABLE_TYPE_IN_2_50 +GLIB_AVAILABLE_TYPE_IN_2_52 +GLIB_AVAILABLE_TYPE_IN_2_54 +GLIB_AVAILABLE_TYPE_IN_2_56 +GLIB_AVAILABLE_TYPE_IN_2_58 +GLIB_AVAILABLE_TYPE_IN_2_60 +GLIB_AVAILABLE_TYPE_IN_2_62 +GLIB_AVAILABLE_TYPE_IN_2_64 +GLIB_AVAILABLE_TYPE_IN_2_66 +GLIB_AVAILABLE_TYPE_IN_2_68 +GLIB_AVAILABLE_TYPE_IN_2_70 +GLIB_AVAILABLE_TYPE_IN_2_72 +GLIB_DEPRECATED_ENUMERATOR +GLIB_DEPRECATED_ENUMERATOR_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_26 +GLIB_DEPRECATED_ENUMERATOR_IN_2_26_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_28 +GLIB_DEPRECATED_ENUMERATOR_IN_2_28_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_30 +GLIB_DEPRECATED_ENUMERATOR_IN_2_30_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_32 +GLIB_DEPRECATED_ENUMERATOR_IN_2_32_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_34 +GLIB_DEPRECATED_ENUMERATOR_IN_2_34_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_36 +GLIB_DEPRECATED_ENUMERATOR_IN_2_36_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_38 +GLIB_DEPRECATED_ENUMERATOR_IN_2_38_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_40 +GLIB_DEPRECATED_ENUMERATOR_IN_2_40_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_42 +GLIB_DEPRECATED_ENUMERATOR_IN_2_42_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_44 +GLIB_DEPRECATED_ENUMERATOR_IN_2_44_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_46 +GLIB_DEPRECATED_ENUMERATOR_IN_2_46_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_48 +GLIB_DEPRECATED_ENUMERATOR_IN_2_48_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_50 +GLIB_DEPRECATED_ENUMERATOR_IN_2_50_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_52 +GLIB_DEPRECATED_ENUMERATOR_IN_2_52_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_54 +GLIB_DEPRECATED_ENUMERATOR_IN_2_54_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_56 +GLIB_DEPRECATED_ENUMERATOR_IN_2_56_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_58 +GLIB_DEPRECATED_ENUMERATOR_IN_2_58_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_60 +GLIB_DEPRECATED_ENUMERATOR_IN_2_60_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_62 +GLIB_DEPRECATED_ENUMERATOR_IN_2_62_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_64 +GLIB_DEPRECATED_ENUMERATOR_IN_2_64_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_66 +GLIB_DEPRECATED_ENUMERATOR_IN_2_66_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_68 +GLIB_DEPRECATED_ENUMERATOR_IN_2_68_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_70 +GLIB_DEPRECATED_ENUMERATOR_IN_2_70_FOR +GLIB_DEPRECATED_ENUMERATOR_IN_2_72 +GLIB_DEPRECATED_ENUMERATOR_IN_2_72_FOR +GLIB_DEPRECATED_IN_2_26 +GLIB_DEPRECATED_IN_2_26_FOR +GLIB_DEPRECATED_IN_2_28 +GLIB_DEPRECATED_IN_2_28_FOR +GLIB_DEPRECATED_IN_2_30 +GLIB_DEPRECATED_IN_2_30_FOR +GLIB_DEPRECATED_IN_2_32 +GLIB_DEPRECATED_IN_2_32_FOR +GLIB_DEPRECATED_IN_2_34 +GLIB_DEPRECATED_IN_2_34_FOR +GLIB_DEPRECATED_IN_2_36 +GLIB_DEPRECATED_IN_2_36_FOR +GLIB_DEPRECATED_IN_2_38 +GLIB_DEPRECATED_IN_2_38_FOR +GLIB_DEPRECATED_IN_2_40 +GLIB_DEPRECATED_IN_2_40_FOR +GLIB_DEPRECATED_IN_2_42 +GLIB_DEPRECATED_IN_2_42_FOR +GLIB_DEPRECATED_IN_2_44 +GLIB_DEPRECATED_IN_2_44_FOR +GLIB_DEPRECATED_IN_2_46 +GLIB_DEPRECATED_IN_2_46_FOR +GLIB_DEPRECATED_IN_2_48 +GLIB_DEPRECATED_IN_2_48_FOR +GLIB_DEPRECATED_IN_2_50 +GLIB_DEPRECATED_IN_2_50_FOR +GLIB_DEPRECATED_IN_2_52 +GLIB_DEPRECATED_IN_2_52_FOR +GLIB_DEPRECATED_IN_2_54 +GLIB_DEPRECATED_IN_2_54_FOR +GLIB_DEPRECATED_IN_2_56 +GLIB_DEPRECATED_IN_2_56_FOR +GLIB_DEPRECATED_IN_2_58 +GLIB_DEPRECATED_IN_2_58_FOR +GLIB_DEPRECATED_IN_2_60 +GLIB_DEPRECATED_IN_2_60_FOR +GLIB_DEPRECATED_IN_2_62 +GLIB_DEPRECATED_IN_2_62_FOR +GLIB_DEPRECATED_IN_2_64 +GLIB_DEPRECATED_IN_2_64_FOR +GLIB_DEPRECATED_IN_2_66 +GLIB_DEPRECATED_IN_2_66_FOR +GLIB_DEPRECATED_IN_2_68 +GLIB_DEPRECATED_IN_2_68_FOR +GLIB_DEPRECATED_IN_2_70 +GLIB_DEPRECATED_IN_2_70_FOR +GLIB_DEPRECATED_IN_2_72 +GLIB_DEPRECATED_IN_2_72_FOR +GLIB_DEPRECATED_MACRO +GLIB_DEPRECATED_MACRO_FOR +GLIB_DEPRECATED_MACRO_IN_2_26 +GLIB_DEPRECATED_MACRO_IN_2_26_FOR +GLIB_DEPRECATED_MACRO_IN_2_28 +GLIB_DEPRECATED_MACRO_IN_2_28_FOR +GLIB_DEPRECATED_MACRO_IN_2_30 +GLIB_DEPRECATED_MACRO_IN_2_30_FOR +GLIB_DEPRECATED_MACRO_IN_2_32 +GLIB_DEPRECATED_MACRO_IN_2_32_FOR +GLIB_DEPRECATED_MACRO_IN_2_34 +GLIB_DEPRECATED_MACRO_IN_2_34_FOR +GLIB_DEPRECATED_MACRO_IN_2_36 +GLIB_DEPRECATED_MACRO_IN_2_36_FOR +GLIB_DEPRECATED_MACRO_IN_2_38 +GLIB_DEPRECATED_MACRO_IN_2_38_FOR +GLIB_DEPRECATED_MACRO_IN_2_40 +GLIB_DEPRECATED_MACRO_IN_2_40_FOR +GLIB_DEPRECATED_MACRO_IN_2_42 +GLIB_DEPRECATED_MACRO_IN_2_42_FOR +GLIB_DEPRECATED_MACRO_IN_2_44 +GLIB_DEPRECATED_MACRO_IN_2_44_FOR +GLIB_DEPRECATED_MACRO_IN_2_46 +GLIB_DEPRECATED_MACRO_IN_2_46_FOR +GLIB_DEPRECATED_MACRO_IN_2_48 +GLIB_DEPRECATED_MACRO_IN_2_48_FOR +GLIB_DEPRECATED_MACRO_IN_2_50 +GLIB_DEPRECATED_MACRO_IN_2_50_FOR +GLIB_DEPRECATED_MACRO_IN_2_52 +GLIB_DEPRECATED_MACRO_IN_2_52_FOR +GLIB_DEPRECATED_MACRO_IN_2_54 +GLIB_DEPRECATED_MACRO_IN_2_54_FOR +GLIB_DEPRECATED_MACRO_IN_2_56 +GLIB_DEPRECATED_MACRO_IN_2_56_FOR +GLIB_DEPRECATED_MACRO_IN_2_58 +GLIB_DEPRECATED_MACRO_IN_2_58_FOR +GLIB_DEPRECATED_MACRO_IN_2_60 +GLIB_DEPRECATED_MACRO_IN_2_60_FOR +GLIB_DEPRECATED_MACRO_IN_2_62 +GLIB_DEPRECATED_MACRO_IN_2_62_FOR +GLIB_DEPRECATED_MACRO_IN_2_64 +GLIB_DEPRECATED_MACRO_IN_2_64_FOR +GLIB_DEPRECATED_MACRO_IN_2_66 +GLIB_DEPRECATED_MACRO_IN_2_66_FOR +GLIB_DEPRECATED_MACRO_IN_2_68 +GLIB_DEPRECATED_MACRO_IN_2_68_FOR +GLIB_DEPRECATED_MACRO_IN_2_70 +GLIB_DEPRECATED_MACRO_IN_2_70_FOR +GLIB_DEPRECATED_MACRO_IN_2_72 +GLIB_DEPRECATED_MACRO_IN_2_72_FOR +GLIB_DEPRECATED_TYPE +GLIB_DEPRECATED_TYPE_FOR +GLIB_DEPRECATED_TYPE_IN_2_26 +GLIB_DEPRECATED_TYPE_IN_2_26_FOR +GLIB_DEPRECATED_TYPE_IN_2_28 +GLIB_DEPRECATED_TYPE_IN_2_28_FOR +GLIB_DEPRECATED_TYPE_IN_2_30 +GLIB_DEPRECATED_TYPE_IN_2_30_FOR +GLIB_DEPRECATED_TYPE_IN_2_32 +GLIB_DEPRECATED_TYPE_IN_2_32_FOR +GLIB_DEPRECATED_TYPE_IN_2_34 +GLIB_DEPRECATED_TYPE_IN_2_34_FOR +GLIB_DEPRECATED_TYPE_IN_2_36 +GLIB_DEPRECATED_TYPE_IN_2_36_FOR +GLIB_DEPRECATED_TYPE_IN_2_38 +GLIB_DEPRECATED_TYPE_IN_2_38_FOR +GLIB_DEPRECATED_TYPE_IN_2_40 +GLIB_DEPRECATED_TYPE_IN_2_40_FOR +GLIB_DEPRECATED_TYPE_IN_2_42 +GLIB_DEPRECATED_TYPE_IN_2_42_FOR +GLIB_DEPRECATED_TYPE_IN_2_44 +GLIB_DEPRECATED_TYPE_IN_2_44_FOR +GLIB_DEPRECATED_TYPE_IN_2_46 +GLIB_DEPRECATED_TYPE_IN_2_46_FOR +GLIB_DEPRECATED_TYPE_IN_2_48 +GLIB_DEPRECATED_TYPE_IN_2_48_FOR +GLIB_DEPRECATED_TYPE_IN_2_50 +GLIB_DEPRECATED_TYPE_IN_2_50_FOR +GLIB_DEPRECATED_TYPE_IN_2_52 +GLIB_DEPRECATED_TYPE_IN_2_52_FOR +GLIB_DEPRECATED_TYPE_IN_2_54 +GLIB_DEPRECATED_TYPE_IN_2_54_FOR +GLIB_DEPRECATED_TYPE_IN_2_56 +GLIB_DEPRECATED_TYPE_IN_2_56_FOR +GLIB_DEPRECATED_TYPE_IN_2_58 +GLIB_DEPRECATED_TYPE_IN_2_58_FOR +GLIB_DEPRECATED_TYPE_IN_2_60 +GLIB_DEPRECATED_TYPE_IN_2_60_FOR +GLIB_DEPRECATED_TYPE_IN_2_62 +GLIB_DEPRECATED_TYPE_IN_2_62_FOR +GLIB_DEPRECATED_TYPE_IN_2_64 +GLIB_DEPRECATED_TYPE_IN_2_64_FOR +GLIB_DEPRECATED_TYPE_IN_2_66 +GLIB_DEPRECATED_TYPE_IN_2_66_FOR +GLIB_DEPRECATED_TYPE_IN_2_68 +GLIB_DEPRECATED_TYPE_IN_2_68_FOR +GLIB_DEPRECATED_TYPE_IN_2_70 +GLIB_DEPRECATED_TYPE_IN_2_70_FOR +GLIB_DEPRECATED_TYPE_IN_2_72 +GLIB_DEPRECATED_TYPE_IN_2_72_FOR +GLIB_VERSION_CUR_STABLE +GLIB_VERSION_PREV_STABLE +
+ +
+Standard Macros +macros + +G_OS_WIN32 +G_OS_UNIX + + +G_DIR_SEPARATOR +G_DIR_SEPARATOR_S +G_IS_DIR_SEPARATOR +G_SEARCHPATH_SEPARATOR +G_SEARCHPATH_SEPARATOR_S + + +TRUE +FALSE + + +NULL + + +MIN +MAX + + +ABS +CLAMP +G_APPROX_VALUE + + +G_SIZEOF_MEMBER +G_STRUCT_MEMBER +G_STRUCT_MEMBER_P +G_STRUCT_OFFSET + + +G_MEM_ALIGN + + +G_ALIGNOF + + +G_CONST_RETURN +G_NORETURN +G_NORETURN_FUNCPTR + + +G_N_ELEMENTS +
+ +
+Type Conversion Macros +type_conversion +GINT_TO_POINTER +GPOINTER_TO_INT + + +GUINT_TO_POINTER +GPOINTER_TO_UINT +GSIZE_TO_POINTER +GPOINTER_TO_SIZE +
+ +
+Byte Order Macros +byte_order +G_BYTE_ORDER +G_LITTLE_ENDIAN +G_BIG_ENDIAN +G_PDP_ENDIAN + + +g_htonl +g_htons +g_ntohl +g_ntohs + + +GINT_FROM_BE +GINT_FROM_LE +GINT_TO_BE +GINT_TO_LE + + +GUINT_FROM_BE +GUINT_FROM_LE +GUINT_TO_BE +GUINT_TO_LE + + +GLONG_FROM_BE +GLONG_FROM_LE +GLONG_TO_BE +GLONG_TO_LE + + +GULONG_FROM_BE +GULONG_FROM_LE +GULONG_TO_BE +GULONG_TO_LE + + +GSIZE_FROM_BE +GSIZE_FROM_LE +GSIZE_TO_BE +GSIZE_TO_LE + + +GSSIZE_FROM_BE +GSSIZE_FROM_LE +GSSIZE_TO_BE +GSSIZE_TO_LE + + +GINT16_FROM_BE +GINT16_FROM_LE +GINT16_TO_BE +GINT16_TO_LE + + +GUINT16_FROM_BE +GUINT16_FROM_LE +GUINT16_TO_BE +GUINT16_TO_LE + + +GINT32_FROM_BE +GINT32_FROM_LE +GINT32_TO_BE +GINT32_TO_LE + + +GUINT32_FROM_BE +GUINT32_FROM_LE +GUINT32_TO_BE +GUINT32_TO_LE + + +GINT64_FROM_BE +GINT64_FROM_LE +GINT64_TO_BE +GINT64_TO_LE + + +GUINT64_FROM_BE +GUINT64_FROM_LE +GUINT64_TO_BE +GUINT64_TO_LE + + +GUINT16_SWAP_BE_PDP +GUINT16_SWAP_LE_BE +GUINT16_SWAP_LE_PDP + + +GUINT32_SWAP_BE_PDP +GUINT32_SWAP_LE_BE +GUINT32_SWAP_LE_PDP + + +GUINT64_SWAP_LE_BE + + +GUINT16_SWAP_LE_BE_CONSTANT +GUINT32_SWAP_LE_BE_CONSTANT +GUINT64_SWAP_LE_BE_CONSTANT +GUINT16_SWAP_LE_BE_IA32 +GUINT32_SWAP_LE_BE_IA32 +GUINT64_SWAP_LE_BE_IA32 +GUINT16_SWAP_LE_BE_IA64 +GUINT32_SWAP_LE_BE_IA64 +GUINT64_SWAP_LE_BE_IA64 +GUINT32_SWAP_LE_BE_X86_64 +GUINT64_SWAP_LE_BE_X86_64 + +
+ +
+Bounds-checked integer arithmetic +checkedmath +g_uint_checked_add +g_uint_checked_mul +g_uint64_checked_add +g_uint64_checked_mul +g_size_checked_add +g_size_checked_mul +
+ +
+Numerical Definitions +numerical +G_IEEE754_FLOAT_BIAS +G_IEEE754_DOUBLE_BIAS +GFloatIEEE754 +GDoubleIEEE754 + + +G_E +G_LN2 +G_LN10 +G_PI +G_PI_2 +G_PI_4 +G_SQRT2 +G_LOG_2_BASE_10 +
+ +
+Miscellaneous Macros +macros_misc +G_INLINE_FUNC + + +g_auto +g_autoptr +g_autofree +g_autolist +g_autoslist +g_autoqueue +G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC +G_DEFINE_AUTO_CLEANUP_FREE_FUNC + + +G_STMT_START +G_STMT_END + + +G_BEGIN_DECLS +G_END_DECLS + + +G_VA_COPY + + +G_STRINGIFY +G_PASTE +G_STATIC_ASSERT +G_STATIC_ASSERT_EXPR + + +G_GNUC_CHECK_VERSION +G_GNUC_EXTENSION +G_GNUC_CONST +G_GNUC_PURE +G_GNUC_MALLOC +G_GNUC_ALLOC_SIZE +G_GNUC_ALLOC_SIZE2 +G_GNUC_DEPRECATED +G_GNUC_DEPRECATED_FOR +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +G_GNUC_END_IGNORE_DEPRECATIONS +G_GNUC_NORETURN +G_GNUC_FALLTHROUGH +G_GNUC_UNUSED +G_GNUC_PRINTF +G_GNUC_SCANF +G_GNUC_STRFTIME +G_GNUC_FORMAT +G_GNUC_NULL_TERMINATED +G_GNUC_WARN_UNUSED_RESULT +G_GNUC_FUNCTION +G_GNUC_PRETTY_FUNCTION +G_GNUC_NO_INLINE +G_GNUC_NO_INSTRUMENT +G_HAVE_GNUC_VISIBILITY +G_GNUC_INTERNAL +G_GNUC_MAY_ALIAS + + +G_DEPRECATED +G_DEPRECATED_FOR +G_UNAVAILABLE + + +G_LIKELY +G_UNLIKELY + + +G_STRLOC +G_STRFUNC + + +GLIB_VAR +G_STRINGIFY_ARG +G_PASTE_ARGS +G_HAVE_INLINE +G_CAN_INLINE +inline +G_HAVE___INLINE +G_HAVE___INLINE__ +G_INLINE_DEFINE_NEEDED +G_HAVE_GNUC_VARARGS +G_HAVE_ISO_VARARGS +G_HAVE_GROWING_STACK +G_VA_COPY_AS_ARRAY +GLIB_CANNOT_IGNORE_DEPRECATIONS +GLIB_DEPRECATED +GLIB_DEPRECATED_FOR +GLIB_UNAVAILABLE +GLIB_UNAVAILABLE_ENUMERATOR +GLIB_UNAVAILABLE_MACRO +GLIB_UNAVAILABLE_STATIC_INLINE +GLIB_UNAVAILABLE_TYPE +G_ANALYZER_ANALYZING +G_ANALYZER_NORETURN +g_autoptr_cleanup_generic_gfree +glib_typeof +g_macro__has_attribute +g_macro__has_builtin +g_macro__has_feature +g_macro__has_extension +g_macro__has_attribute___alloc_size__ +g_macro__has_attribute___const__ +g_macro__has_attribute___deprecated__ +g_macro__has_attribute___format__ +g_macro__has_attribute___format_arg__ +g_macro__has_attribute___malloc__ +g_macro__has_attribute___no_instrument_function__ +g_macro__has_attribute___noreturn__ +g_macro__has_attribute___pure__ +g_macro__has_attribute___sentinel__ +g_macro__has_attribute___unused__ +g_macro__has_attribute_fallthrough +g_macro__has_attribute_may_alias +g_macro__has_attribute___noinline__ +g_macro__has_attribute_warn_unused_result +g_macro__has_attribute_cleanup +
+ +
+Error Reporting +error_reporting +GError +g_error_new +g_error_new_literal +g_error_new_valist +g_error_free +g_error_copy +g_error_matches +g_set_error +g_set_error_literal +g_propagate_error +g_clear_error +g_prefix_error +g_prefix_error_literal +g_propagate_prefixed_error + +GErrorInitFunc +GErrorCopyFunc +GErrorClearFunc +G_DEFINE_EXTENDED_ERROR +g_error_domain_register_static +g_error_domain_register +
+ +
+The Main Event Loop +main +GMainLoop +g_main_loop_new +g_main_loop_ref +g_main_loop_unref +g_main_loop_run +g_main_loop_quit +g_main_loop_is_running +g_main_loop_get_context +g_main_new +g_main_destroy +g_main_run +g_main_quit +g_main_is_running + + +G_PRIORITY_HIGH +G_PRIORITY_DEFAULT +G_PRIORITY_HIGH_IDLE +G_PRIORITY_DEFAULT_IDLE +G_PRIORITY_LOW + + +G_SOURCE_CONTINUE +G_SOURCE_REMOVE + + +GMainContext +GMainContextFlags +g_main_context_new +g_main_context_new_with_flags +g_main_context_ref +g_main_context_unref +g_main_context_default +g_main_context_iteration +g_main_iteration +g_main_context_pending +g_main_pending +g_main_context_find_source_by_id +g_main_context_find_source_by_user_data +g_main_context_find_source_by_funcs_user_data +g_main_context_wakeup +g_main_context_acquire +g_main_context_release +g_main_context_is_owner +g_main_context_wait +g_main_context_prepare +g_main_context_query +g_main_context_check +g_main_context_dispatch +g_main_context_set_poll_func +g_main_context_get_poll_func +GPollFunc +g_main_context_add_poll +g_main_context_remove_poll +g_main_depth +g_main_current_source +g_main_set_poll_func +g_main_context_invoke +g_main_context_invoke_full + + +GMainContextPusher +g_main_context_pusher_new +g_main_context_pusher_free + + +g_main_context_get_thread_default +g_main_context_ref_thread_default +g_main_context_push_thread_default +g_main_context_pop_thread_default + + +g_timeout_source_new +g_timeout_source_new_seconds +g_timeout_add +g_timeout_add_full +g_timeout_add_seconds +g_timeout_add_seconds_full + + +g_idle_source_new +g_idle_add +g_idle_add_full +g_idle_remove_by_data + + +GPid +G_PID_FORMAT +GChildWatchFunc +g_child_watch_source_new +g_child_watch_add +g_child_watch_add_full + + +GPollFD +g_poll +G_POLLFD_FORMAT + + +GSource +GSourceDummyMarshal +GSourceFuncs +GSourceDisposeFunc +GSourceCallbackFuncs +g_source_new +g_source_ref +g_source_unref +g_source_set_funcs +g_source_set_dispose_function +g_source_attach +g_source_destroy +g_source_is_destroyed +g_source_set_priority +g_source_get_priority +g_source_set_can_recurse +g_source_get_can_recurse +g_source_get_id +g_source_get_name +g_source_set_name +g_source_set_static_name +g_source_set_name_by_id +g_source_get_context +g_source_set_callback +GSourceFunc +G_SOURCE_FUNC +g_source_set_callback_indirect +g_source_set_ready_time +g_source_get_ready_time +g_source_add_unix_fd +g_source_remove_unix_fd +g_source_modify_unix_fd +g_source_query_unix_fd +g_source_add_poll +g_source_remove_poll +g_source_add_child_source +g_source_remove_child_source +g_source_get_time +g_source_get_current_time +g_source_remove +g_source_remove_by_funcs_user_data +g_source_remove_by_user_data +GClearHandleFunc +g_clear_handle_id + + +g_steal_fd + + +GLIB_HAVE_ALLOCA_H +alloca +GLIB_USING_SYSTEM_PRINTF +GLIB_SYSDEF_POLLERR +GLIB_SYSDEF_POLLHUP +GLIB_SYSDEF_POLLIN +GLIB_SYSDEF_POLLNVAL +GLIB_SYSDEF_POLLOUT +GLIB_SYSDEF_POLLPRI +GLIB_SYSDEF_AF_INET +GLIB_SYSDEF_AF_INET6 +GLIB_SYSDEF_AF_UNIX +GLIB_SYSDEF_MSG_DONTROUTE +GLIB_SYSDEF_MSG_OOB +GLIB_SYSDEF_MSG_PEEK +G_WIN32_MSG_HANDLE +g_idle_funcs +g_timeout_funcs +g_child_watch_funcs +g_unix_signal_funcs +g_unix_fd_source_funcs +GSourcePrivate +
+ + +
+Threads +threads + +G_THREAD_ERROR +GThreadError + + +GThread +GThreadFunc +g_thread_new +g_thread_try_new +g_thread_ref +g_thread_unref +g_thread_join +g_thread_yield +g_thread_exit +g_thread_self + + +GMutex +g_mutex_init +g_mutex_clear +g_mutex_lock +g_mutex_trylock +g_mutex_unlock + + +GMutexLocker +g_mutex_locker_new +g_mutex_locker_free + + +G_LOCK_DEFINE +G_LOCK_DEFINE_STATIC +G_LOCK_EXTERN +G_LOCK +G_TRYLOCK +G_UNLOCK + + +GRecMutex +g_rec_mutex_init +g_rec_mutex_clear +g_rec_mutex_lock +g_rec_mutex_trylock +g_rec_mutex_unlock + + +GRecMutexLocker +g_rec_mutex_locker_new +g_rec_mutex_locker_free + + +GRWLockWriterLocker +g_rw_lock_writer_locker_new +g_rw_lock_writer_locker_free + + +GRWLockReaderLocker +g_rw_lock_reader_locker_new +g_rw_lock_reader_locker_free + + +GRWLock +g_rw_lock_init +g_rw_lock_clear +g_rw_lock_writer_lock +g_rw_lock_writer_trylock +g_rw_lock_writer_unlock +g_rw_lock_reader_lock +g_rw_lock_reader_trylock +g_rw_lock_reader_unlock + + +GCond +g_cond_init +g_cond_clear +g_cond_wait +g_cond_timed_wait +g_cond_wait_until +g_cond_signal +g_cond_broadcast + + +GPrivate +G_PRIVATE_INIT +g_private_get +g_private_set +g_private_replace + + +GOnce +GOnceStatus +G_ONCE_INIT +g_once +g_once_init_enter +g_once_init_leave + + +g_bit_lock +g_bit_trylock +g_bit_unlock +g_pointer_bit_lock +g_pointer_bit_trylock +g_pointer_bit_unlock + + +g_get_num_processors + + +G_LOCK_NAME +atexit +g_thread_error_quark +g_once_impl +
+ +
+Deprecated Thread APIs +threads-deprecated + + +G_THREADS_IMPL_POSIX +G_THREADS_IMPL_WIN32 + + +g_thread_init +g_thread_supported +g_thread_get_initialized + + +g_thread_create +g_thread_create_full +GThreadPriority +g_thread_set_priority +g_thread_foreach + + +g_mutex_new +g_mutex_free +g_cond_new +g_cond_free +g_private_new + + +GStaticMutex +G_STATIC_MUTEX_INIT +g_static_mutex_init +g_static_mutex_lock +g_static_mutex_trylock +g_static_mutex_unlock +g_static_mutex_get_mutex +g_static_mutex_free + + +GStaticRecMutex +G_STATIC_REC_MUTEX_INIT +g_static_rec_mutex_init +g_static_rec_mutex_lock +g_static_rec_mutex_trylock +g_static_rec_mutex_unlock +g_static_rec_mutex_lock_full +g_static_rec_mutex_unlock_full +g_static_rec_mutex_free + + +GStaticRWLock +G_STATIC_RW_LOCK_INIT +g_static_rw_lock_init +g_static_rw_lock_reader_lock +g_static_rw_lock_reader_trylock +g_static_rw_lock_reader_unlock +g_static_rw_lock_writer_lock +g_static_rw_lock_writer_trylock +g_static_rw_lock_writer_unlock +g_static_rw_lock_free + + +GStaticPrivate +G_STATIC_PRIVATE_INIT +g_static_private_init +g_static_private_get +g_static_private_set +g_static_private_free + + +GThreadFunctions +g_thread_init_with_errorcheck_mutexes +G_THREADS_ENABLED +g_static_mutex_get_mutex_impl +g_thread_use_default_impl +g_threads_got_initialized +g_thread_functions_for_glib_use +g_thread_gettime +g_once_init_enter_impl +
+ +
+Thread Pools +thread_pools +GThreadPool +g_thread_pool_new +g_thread_pool_new_full +g_thread_pool_push +g_thread_pool_set_max_threads +g_thread_pool_get_max_threads +g_thread_pool_get_num_threads +g_thread_pool_unprocessed +g_thread_pool_free +g_thread_pool_set_max_unused_threads +g_thread_pool_get_max_unused_threads +g_thread_pool_get_num_unused_threads +g_thread_pool_stop_unused_threads +g_thread_pool_set_sort_function +g_thread_pool_set_max_idle_time +g_thread_pool_get_max_idle_time +g_thread_pool_move_to_front +
+ +
+Asynchronous Queues +async_queues +GAsyncQueue +g_async_queue_new +g_async_queue_new_full +g_async_queue_ref +g_async_queue_unref +g_async_queue_push +g_async_queue_push_sorted +g_async_queue_push_front +g_async_queue_remove +g_async_queue_pop +g_async_queue_try_pop +g_async_queue_timeout_pop +g_async_queue_length +g_async_queue_sort + + +g_async_queue_lock +g_async_queue_unlock +g_async_queue_ref_unlocked +g_async_queue_unref_and_unlock +g_async_queue_push_unlocked +g_async_queue_push_sorted_unlocked +g_async_queue_push_front_unlocked +g_async_queue_remove_unlocked +g_async_queue_pop_unlocked +g_async_queue_try_pop_unlocked +g_async_queue_timeout_pop_unlocked +g_async_queue_length_unlocked +g_async_queue_sort_unlocked + + +g_async_queue_timed_pop +g_async_queue_timed_pop_unlocked +
+ +
+Atomic Operations +atomic_operations +G_ATOMIC_LOCK_FREE + + +g_atomic_int_get +g_atomic_int_set +g_atomic_int_inc +g_atomic_int_dec_and_test +g_atomic_int_compare_and_exchange +g_atomic_int_add +g_atomic_int_and +g_atomic_int_or +g_atomic_int_xor + + +g_atomic_pointer_get +g_atomic_pointer_set +g_atomic_pointer_compare_and_exchange +g_atomic_pointer_add +g_atomic_pointer_and +g_atomic_pointer_or +g_atomic_pointer_xor + + +g_atomic_int_exchange_and_add +
+ +
+IO Channels +iochannels +GIOChannel + + +g_io_channel_unix_new +g_io_channel_unix_get_fd +g_io_channel_win32_new_fd +g_io_channel_win32_new_socket +g_io_channel_win32_new_messages + + +g_io_channel_init + + +g_io_channel_new_file +g_io_channel_read_chars +g_io_channel_read_unichar +g_io_channel_read_line +g_io_channel_read_line_string +g_io_channel_read_to_end +g_io_channel_write_chars +g_io_channel_write_unichar +g_io_channel_flush +g_io_channel_seek_position +GSeekType +g_io_channel_shutdown + + +GIOStatus +GIOChannelError +G_IO_CHANNEL_ERROR +g_io_channel_error_from_errno + + +g_io_channel_ref +g_io_channel_unref + + +g_io_create_watch +g_io_add_watch +g_io_add_watch_full +GIOCondition +GIOFunc + + +GIOFuncs + + +g_io_channel_get_buffer_size +g_io_channel_set_buffer_size +g_io_channel_get_buffer_condition +g_io_channel_get_flags +g_io_channel_set_flags +GIOFlags +g_io_channel_get_line_term +g_io_channel_set_line_term +g_io_channel_get_buffered +g_io_channel_set_buffered +g_io_channel_get_encoding +g_io_channel_set_encoding +g_io_channel_get_close_on_unref +g_io_channel_set_close_on_unref + + +g_io_channel_read +GIOError +g_io_channel_write +g_io_channel_seek +g_io_channel_close + + +g_io_channel_win32_poll +g_io_channel_win32_make_pollfd +g_io_channel_win32_get_fd +g_io_channel_win32_new_stream_socket +g_io_channel_win32_set_debug +g_io_channel_error_quark +g_io_watch_funcs +G_IO_FLAG_IS_WRITEABLE +
+ +
+Memory Allocation +memory +g_new +g_new0 +g_renew +g_try_new +g_try_new0 +g_try_renew + + +g_malloc +g_malloc0 +g_realloc +g_try_malloc +g_try_malloc0 +g_try_realloc +g_malloc_n +g_malloc0_n +g_realloc_n +g_try_malloc_n +g_try_malloc0_n +g_try_realloc_n + + +g_free +g_clear_pointer +g_steal_pointer +g_mem_gc_friendly + + +g_alloca +g_alloca0 +g_newa +g_newa0 + + +g_aligned_alloc +g_aligned_alloc0 +g_aligned_free + + +g_memmove +g_memdup +g_memdup2 + + +GMemVTable +g_mem_set_vtable +g_mem_is_system_malloc + + +glib_mem_profiler_table +g_mem_profile +
+ +
+Warnings and Assertions +warnings +g_print +g_set_print_handler +GPrintFunc + + +g_printerr +g_set_printerr_handler + + +g_return_if_fail +g_return_val_if_fail +g_return_if_reached +g_return_val_if_reached +g_warn_if_fail +g_warn_if_reached + + +g_on_error_query +g_on_error_stack_trace + + +G_BREAKPOINT + + +g_return_if_fail_warning +g_assert_warning +g_warn_message +
+ +
+Glob-style pattern matching +patterns +GPatternSpec +g_pattern_spec_new +g_pattern_spec_free +g_pattern_spec_equal +g_pattern_spec_copy +g_pattern_spec_match +g_pattern_spec_match_string +g_pattern_match +g_pattern_match_string +g_pattern_match_simple +
+ +
+Perl-compatible regular expressions +gregex +GRegexError +G_REGEX_ERROR +GRegexCompileFlags +GRegexMatchFlags +GRegex +GRegexEvalCallback +g_regex_new +g_regex_ref +g_regex_unref +g_regex_get_pattern +g_regex_get_max_backref +g_regex_get_capture_count +g_regex_get_has_cr_or_lf +g_regex_get_max_lookbehind +g_regex_get_string_number +g_regex_get_compile_flags +g_regex_get_match_flags +g_regex_escape_string +g_regex_escape_nul +g_regex_match_simple +g_regex_match +g_regex_match_full +g_regex_match_all +g_regex_match_all_full +g_regex_split_simple +g_regex_split +g_regex_split_full +g_regex_replace +g_regex_replace_literal +g_regex_replace_eval +g_regex_check_replacement +GMatchInfo +g_match_info_get_regex +g_match_info_get_string +g_match_info_ref +g_match_info_unref +g_match_info_free +g_match_info_matches +g_match_info_next +g_match_info_get_match_count +g_match_info_is_partial_match +g_match_info_expand_references +g_match_info_fetch +g_match_info_fetch_pos +g_match_info_fetch_named +g_match_info_fetch_named_pos +g_match_info_fetch_all + +g_regex_error_quark +
+ +
+Message Logging +messages +G_LOG_DOMAIN +G_LOG_FATAL_MASK +G_LOG_LEVEL_USER_SHIFT +GLogFunc +GLogLevelFlags + + +g_log +g_logv +g_message +g_warning +g_warning_once +g_critical +g_error +g_info +g_debug + + +g_log_set_handler +g_log_set_handler_full +g_log_remove_handler +g_log_set_always_fatal +g_log_set_fatal_mask +g_log_default_handler +g_log_set_default_handler +g_log_get_debug_enabled +g_log_set_debug_enabled + + +g_log_structured +g_log_variant +GLogField +g_log_structured_array +G_DEBUG_HERE + + +GLogWriterOutput +GLogWriterFunc +g_log_set_writer_func +g_log_writer_supports_color +g_log_writer_is_journald +g_log_writer_format_fields +g_log_writer_journald +g_log_writer_standard_streams +g_log_writer_default +g_log_writer_default_set_use_stderr +g_log_writer_default_would_drop + + +g_log_structured_standard +
+ +
+Timers +timers +GTimer +g_timer_new +g_timer_start +g_timer_stop +g_timer_continue +g_timer_elapsed +g_timer_reset +g_timer_destroy +g_timer_is_active +
+ +
+Spawning Processes +spawn +GSpawnError +G_SPAWN_ERROR +GSpawnFlags +GSpawnChildSetupFunc +g_spawn_async_with_fds +g_spawn_async_with_pipes +g_spawn_async_with_pipes_and_fds +g_spawn_async +g_spawn_sync +G_SPAWN_EXIT_ERROR +g_spawn_check_wait_status +g_spawn_check_exit_status +g_spawn_command_line_async +g_spawn_command_line_sync +g_spawn_close_pid + +g_spawn_error_quark +g_spawn_exit_error_quark +
+ +
+Simple XML Subset Parser +markup +GMarkupError +G_MARKUP_ERROR +GMarkupParseFlags +GMarkupParseContext +GMarkupParser +g_markup_escape_text +g_markup_printf_escaped +g_markup_vprintf_escaped +g_markup_parse_context_new +g_markup_parse_context_parse +g_markup_parse_context_end_parse +g_markup_parse_context_free +g_markup_parse_context_get_position +g_markup_parse_context_get_element +g_markup_parse_context_get_element_stack +g_markup_parse_context_get_user_data +g_markup_parse_context_push +g_markup_parse_context_pop +g_markup_parse_context_ref +g_markup_parse_context_unref + +GMarkupCollectType +g_markup_collect_attributes + +g_markup_error_quark +
+ + +
+Shell-related Utilities +shell +GShellError +G_SHELL_ERROR +g_shell_parse_argv +g_shell_quote +g_shell_unquote + +g_shell_error_quark +
+ + +
+Commandline option parser +option +GOptionError +G_OPTION_ERROR +GOptionArgFunc +GOptionContext +g_option_context_new +g_option_context_set_summary +g_option_context_get_summary +g_option_context_set_description +g_option_context_get_description +GTranslateFunc +g_option_context_set_translate_func +g_option_context_set_translation_domain +g_option_context_free +g_option_context_parse +g_option_context_parse_strv +g_option_context_set_help_enabled +g_option_context_get_help_enabled +g_option_context_set_ignore_unknown_options +g_option_context_get_ignore_unknown_options +g_option_context_get_help +g_option_context_get_strict_posix +g_option_context_set_strict_posix +GOptionArg +GOptionFlags +G_OPTION_REMAINING +GOptionEntry +G_OPTION_ENTRY_NULL +g_option_context_add_main_entries +GOptionGroup +g_option_context_add_group +g_option_context_set_main_group +g_option_context_get_main_group +g_option_group_new +g_option_group_ref +g_option_group_unref +g_option_group_free +g_option_group_add_entries +GOptionParseFunc +g_option_group_set_parse_hooks +GOptionErrorFunc +g_option_group_set_error_hook +g_option_group_set_translate_func +g_option_group_set_translation_domain + +g_option_error_quark +
+ + +
+File Utilities +fileutils +glib.h,glib/gstdio.h,fcntl.h,sys/types.h,sys/stat.h +GFileError +G_FILE_ERROR +GFileTest +g_file_error_from_errno +g_file_get_contents +GFileSetContentsFlags +g_file_set_contents +g_file_set_contents_full +g_file_test +g_mkstemp +g_mkstemp_full +g_file_open_tmp +g_file_read_link +g_mkdir_with_parents +g_mkdtemp +g_mkdtemp_full +g_dir_make_tmp + + +GDir +g_dir_open +g_dir_read_name +g_dir_rewind +g_dir_close + + +GMappedFile +g_mapped_file_new +g_mapped_file_new_from_fd +g_mapped_file_ref +g_mapped_file_unref +g_mapped_file_free +g_mapped_file_get_length +g_mapped_file_get_contents +g_mapped_file_get_bytes + + +g_open +g_rename +g_mkdir +GStatBuf +g_stat +g_lstat +g_unlink +g_remove +g_rmdir +g_fopen +g_freopen +g_fsync +g_chmod +g_access +g_creat +g_chdir +g_utime +g_close + + +g_file_error_quark +utimbuf +
+ + +
+String Utility Functions +string_utils +glib.h,glib/gprintf.h +g_strdup +g_strndup +g_strdupv +g_strnfill +g_stpcpy +g_strstr_len +g_strrstr +g_strrstr_len +g_str_has_prefix +g_str_has_suffix +g_strcmp0 +g_str_to_ascii +g_str_tokenize_and_fold +g_str_match_string + + +g_strlcpy +g_strlcat + + +g_strdup_printf +g_strdup_vprintf +g_printf +g_vprintf +g_fprintf +g_vfprintf +g_sprintf +g_vsprintf +g_snprintf +g_vsnprintf +g_vasprintf +g_printf_string_upper_bound + + +g_str_is_ascii +g_ascii_isalnum +g_ascii_isalpha +g_ascii_iscntrl +g_ascii_isdigit +g_ascii_isgraph +g_ascii_islower +g_ascii_isprint +g_ascii_ispunct +g_ascii_isspace +g_ascii_isupper +g_ascii_isxdigit + + +g_ascii_digit_value +g_ascii_xdigit_value + + +g_ascii_strcasecmp +g_ascii_strncasecmp + + +g_ascii_strup +g_ascii_strdown + + +g_ascii_tolower +g_ascii_toupper + + +g_string_ascii_up +g_string_ascii_down + + +g_strup +g_strdown + + +g_strcasecmp +g_strncasecmp + + +g_strreverse + + +g_ascii_strtoll +g_ascii_strtoull +G_ASCII_DTOSTR_BUF_SIZE +g_ascii_strtod +g_ascii_dtostr +g_ascii_formatd +g_strtod + + +GNumberParserError +G_NUMBER_PARSER_ERROR +g_ascii_string_to_signed +g_ascii_string_to_unsigned + + +g_number_parser_error_quark + + +g_strchug +g_strchomp +g_strstrip + + +g_strdelimit +G_STR_DELIMITERS +g_strescape +g_strcompress +g_strcanon +g_strsplit +g_strsplit_set +g_strfreev +g_strconcat +g_strjoin +g_strjoinv + + +GStrv +GStrvBuilder +g_strv_length +g_strv_contains +g_strv_equal +g_strv_builder_new +g_strv_builder_ref +g_strv_builder_unref +g_strv_builder_add +g_strv_builder_addv +g_strv_builder_add_many +g_strv_builder_end + + +g_strerror +g_strsignal + + +GAsciiType +g_ascii_table +
+ +
+Date and Time Functions +date +G_USEC_PER_SEC +GTimeVal +g_get_current_time +g_usleep +g_time_val_add +g_time_val_from_iso8601 +g_time_val_to_iso8601 + + +g_get_monotonic_time +g_get_real_time + + +GDate +GTime +GDateDMY +GDateDay +GDateMonth +GDateYear +GDateWeekday + + +G_DATE_BAD_DAY +G_DATE_BAD_JULIAN +G_DATE_BAD_YEAR + + +g_date_new +g_date_new_dmy +g_date_new_julian +g_date_clear +g_date_free +g_date_copy + + +g_date_set_day +g_date_set_month +g_date_set_year +g_date_set_dmy +g_date_set_julian +g_date_set_time +g_date_set_time_t +g_date_set_time_val +g_date_set_parse + + +g_date_add_days +g_date_subtract_days +g_date_add_months +g_date_subtract_months +g_date_add_years +g_date_subtract_years +g_date_days_between +g_date_compare +g_date_clamp +g_date_order + + +g_date_get_day +g_date_get_month +g_date_get_year +g_date_get_julian +g_date_get_weekday +g_date_get_day_of_year + + +g_date_get_days_in_month +g_date_is_first_of_month +g_date_is_last_of_month +g_date_is_leap_year +g_date_get_monday_week_of_year +g_date_get_monday_weeks_in_year +g_date_get_sunday_week_of_year +g_date_get_sunday_weeks_in_year +g_date_get_iso8601_week_of_year + + +g_date_strftime +g_date_to_struct_tm + + +g_date_valid +g_date_valid_day +g_date_valid_month +g_date_valid_year +g_date_valid_dmy +g_date_valid_julian +g_date_valid_weekday + + +g_date_weekday +g_date_month +g_date_year +g_date_day +g_date_julian +g_date_day_of_year +g_date_monday_week_of_year +g_date_sunday_week_of_year +g_date_days_in_month +g_date_monday_weeks_in_year +g_date_sunday_weeks_in_year +
+ +
+timezone + +GTimeZone +g_time_zone_unref +g_time_zone_ref + +g_time_zone_new +g_time_zone_new_identifier +g_time_zone_new_local +g_time_zone_new_utc +g_time_zone_new_offset + +GTimeType +g_time_zone_find_interval +g_time_zone_adjust_time + +g_time_zone_get_identifier +g_time_zone_get_abbreviation +g_time_zone_get_offset +g_time_zone_is_dst +
+ +
+date-time +GTimeSpan +G_TIME_SPAN_DAY +G_TIME_SPAN_HOUR +G_TIME_SPAN_MINUTE +G_TIME_SPAN_SECOND +G_TIME_SPAN_MILLISECOND + + +GDateTime +g_date_time_unref +g_date_time_ref + + +g_date_time_new_now +g_date_time_new_now_local +g_date_time_new_now_utc + + +g_date_time_new_from_unix_local +g_date_time_new_from_unix_utc + + +g_date_time_new_from_timeval_local +g_date_time_new_from_timeval_utc +g_date_time_new_from_iso8601 + + +g_date_time_new +g_date_time_new_local +g_date_time_new_utc + + +g_date_time_add + + +g_date_time_add_years +g_date_time_add_months +g_date_time_add_weeks +g_date_time_add_days + + +g_date_time_add_hours +g_date_time_add_minutes +g_date_time_add_seconds + + +g_date_time_add_full + + +g_date_time_compare +g_date_time_difference +g_date_time_hash +g_date_time_equal + + +g_date_time_get_ymd + + +g_date_time_get_year +g_date_time_get_month +g_date_time_get_day_of_month + + +g_date_time_get_week_numbering_year +g_date_time_get_week_of_year +g_date_time_get_day_of_week + + +g_date_time_get_day_of_year + + +g_date_time_get_hour +g_date_time_get_minute +g_date_time_get_second +g_date_time_get_microsecond +g_date_time_get_seconds + + +g_date_time_to_unix +g_date_time_to_timeval + + +g_date_time_get_utc_offset +g_date_time_get_timezone +g_date_time_get_timezone_abbreviation +g_date_time_is_daylight_savings + + +g_date_time_to_timezone +g_date_time_to_local +g_date_time_to_utc + + +g_date_time_format +g_date_time_format_iso8601 +
+ +
+Hook Functions +hooks +GHookList +GHookFinalizeFunc +GHook +GHookFunc +GHookCheckFunc + + +g_hook_list_init +g_hook_list_invoke +g_hook_list_invoke_check +g_hook_list_marshal +GHookMarshaller +g_hook_list_marshal_check +GHookCheckMarshaller +g_hook_list_clear + + +g_hook_alloc +g_hook_append +g_hook_prepend +g_hook_insert_before +g_hook_insert_sorted +GHookCompareFunc +g_hook_compare_ids + + +g_hook_get +g_hook_find +GHookFindFunc +g_hook_find_data +g_hook_find_func +g_hook_find_func_data + + +g_hook_first_valid +g_hook_next_valid + +GHookFlagMask +G_HOOK_FLAGS +G_HOOK_FLAG_USER_SHIFT + + +G_HOOK +G_HOOK_IS_VALID +G_HOOK_ACTIVE +G_HOOK_IN_CALL +G_HOOK_IS_UNLINKED + + +g_hook_ref +g_hook_unref + +g_hook_free +g_hook_destroy +g_hook_destroy_link +
+ +
+Miscellaneous Utility Functions +misc_utils +g_get_application_name +g_set_application_name +g_get_prgname +g_set_prgname +g_get_environ +g_environ_getenv +g_environ_setenv +g_environ_unsetenv +g_getenv +g_setenv +g_unsetenv +g_listenv +g_get_user_name +g_get_real_name +g_get_user_cache_dir +g_get_user_data_dir +g_get_user_config_dir +g_get_user_state_dir +g_get_user_runtime_dir +GUserDirectory +g_get_user_special_dir +g_get_system_data_dirs +g_get_system_config_dirs +g_reload_user_special_dirs_cache +g_get_os_info + + +G_OS_INFO_KEY_NAME +G_OS_INFO_KEY_PRETTY_NAME +G_OS_INFO_KEY_VERSION +G_OS_INFO_KEY_VERSION_CODENAME +G_OS_INFO_KEY_VERSION_ID +G_OS_INFO_KEY_ID +G_OS_INFO_KEY_HOME_URL +G_OS_INFO_KEY_DOCUMENTATION_URL +G_OS_INFO_KEY_SUPPORT_URL +G_OS_INFO_KEY_BUG_REPORT_URL +G_OS_INFO_KEY_PRIVACY_POLICY_URL + + +g_get_host_name +g_get_home_dir +g_get_tmp_dir +g_get_current_dir +g_basename +g_dirname +g_canonicalize_filename +g_path_is_absolute +g_path_skip_root +g_path_get_basename +g_path_get_dirname +g_build_filename +g_build_filenamev +g_build_filename_valist +g_build_path +g_build_pathv + + +g_format_size +GFormatSizeFlags +g_format_size_full +g_format_size_for_display + + +g_find_program_in_path + + +g_bit_nth_lsf +g_bit_nth_msf +g_bit_storage + + +g_spaced_primes_closest + + +g_atexit +g_abort + + +g_parse_debug_string +GDebugKey + + +GVoidFunc +GFreeFunc + + +g_qsort_with_data + + +g_nullify_pointer + + +G_NATIVE_ATEXIT +g_ATEXIT +g_win32_get_system_data_dirs_for_module +ATEXIT +g_bit_nth_lsf_impl +g_bit_nth_msf_impl +g_bit_storage_impl + +
+ +
+Lexical Scanner +scanner +GScanner +GScannerConfig +g_scanner_new +g_scanner_destroy + + +g_scanner_input_file +g_scanner_sync_file_offset +g_scanner_input_text +g_scanner_peek_next_token +g_scanner_get_next_token +g_scanner_eof + + +g_scanner_cur_line +g_scanner_cur_position +g_scanner_cur_token +g_scanner_cur_value + + +g_scanner_set_scope +g_scanner_scope_add_symbol +g_scanner_scope_foreach_symbol +g_scanner_scope_lookup_symbol +g_scanner_scope_remove_symbol +g_scanner_add_symbol +g_scanner_remove_symbol +g_scanner_foreach_symbol + + +g_scanner_freeze_symbol_table +g_scanner_thaw_symbol_table +g_scanner_lookup_symbol + + +g_scanner_warn +g_scanner_error +g_scanner_unexp_token +GScannerMsgFunc + + +G_CSET_a_2_z +G_CSET_A_2_Z +G_CSET_DIGITS +G_CSET_LATINC +G_CSET_LATINS +GTokenType +GTokenValue +GErrorType + +
+ +
+Key-value file parser +keyfile +GKeyFile +G_KEY_FILE_ERROR +GKeyFileError +GKeyFileFlags + + +g_key_file_new +g_key_file_free +g_key_file_ref +g_key_file_unref +g_key_file_set_list_separator +g_key_file_load_from_file +g_key_file_load_from_data +g_key_file_load_from_bytes +g_key_file_load_from_data_dirs +g_key_file_load_from_dirs +g_key_file_to_data +g_key_file_save_to_file +g_key_file_get_start_group +g_key_file_get_groups +g_key_file_get_keys +g_key_file_has_group +g_key_file_has_key + + +g_key_file_get_value +g_key_file_get_string +g_key_file_get_locale_string +g_key_file_get_locale_for_key +g_key_file_get_boolean +g_key_file_get_integer +g_key_file_get_int64 +g_key_file_get_uint64 +g_key_file_get_double +g_key_file_get_string_list +g_key_file_get_locale_string_list +g_key_file_get_boolean_list +g_key_file_get_integer_list +g_key_file_get_double_list +g_key_file_get_comment + + +g_key_file_set_value +g_key_file_set_string +g_key_file_set_locale_string +g_key_file_set_boolean +g_key_file_set_integer +g_key_file_set_int64 +g_key_file_set_uint64 +g_key_file_set_double +g_key_file_set_string_list +g_key_file_set_locale_string_list +g_key_file_set_boolean_list +g_key_file_set_integer_list +g_key_file_set_double_list +g_key_file_set_comment +g_key_file_remove_group +g_key_file_remove_key +g_key_file_remove_comment + + +G_KEY_FILE_DESKTOP_GROUP +G_KEY_FILE_DESKTOP_KEY_TYPE +G_KEY_FILE_DESKTOP_KEY_VERSION +G_KEY_FILE_DESKTOP_KEY_NAME +G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME +G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY +G_KEY_FILE_DESKTOP_KEY_COMMENT +G_KEY_FILE_DESKTOP_KEY_ICON +G_KEY_FILE_DESKTOP_KEY_HIDDEN +G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN +G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN +G_KEY_FILE_DESKTOP_KEY_TRY_EXEC +G_KEY_FILE_DESKTOP_KEY_EXEC +G_KEY_FILE_DESKTOP_KEY_PATH +G_KEY_FILE_DESKTOP_KEY_TERMINAL +G_KEY_FILE_DESKTOP_KEY_MIME_TYPE +G_KEY_FILE_DESKTOP_KEY_CATEGORIES +G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY +G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS +G_KEY_FILE_DESKTOP_KEY_URL +G_KEY_FILE_DESKTOP_KEY_ACTIONS +G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE +G_KEY_FILE_DESKTOP_TYPE_APPLICATION +G_KEY_FILE_DESKTOP_TYPE_LINK +G_KEY_FILE_DESKTOP_TYPE_DIRECTORY + + +g_key_file_error_quark +g_key_file_get_type +
+ +
+Bookmark file parser +bookmarkfile +GBookmarkFile +G_BOOKMARK_FILE_ERROR +GBookmarkFileError +g_bookmark_file_new +g_bookmark_file_free +g_bookmark_file_load_from_file +g_bookmark_file_load_from_data +g_bookmark_file_load_from_data_dirs +g_bookmark_file_to_data +g_bookmark_file_to_file +g_bookmark_file_has_item +g_bookmark_file_has_group +g_bookmark_file_has_application +g_bookmark_file_get_size +g_bookmark_file_get_uris G_GNUC_MALLOC + + +g_bookmark_file_get_title +g_bookmark_file_get_description +g_bookmark_file_get_mime_type +g_bookmark_file_get_is_private +g_bookmark_file_get_icon +g_bookmark_file_get_added +g_bookmark_file_get_added_date_time +g_bookmark_file_get_modified +g_bookmark_file_get_modified_date_time +g_bookmark_file_get_visited +g_bookmark_file_get_visited_date_time +g_bookmark_file_get_groups +g_bookmark_file_get_applications +g_bookmark_file_get_app_info +g_bookmark_file_get_application_info + + +g_bookmark_file_set_title +g_bookmark_file_set_description +g_bookmark_file_set_mime_type +g_bookmark_file_set_is_private +g_bookmark_file_set_icon +g_bookmark_file_set_added +g_bookmark_file_set_added_date_time +g_bookmark_file_set_groups +g_bookmark_file_set_modified +g_bookmark_file_set_modified_date_time +g_bookmark_file_set_visited +g_bookmark_file_set_visited_date_time +g_bookmark_file_set_app_info +g_bookmark_file_set_application_info +g_bookmark_file_add_group +g_bookmark_file_add_application +g_bookmark_file_remove_group +g_bookmark_file_remove_application +g_bookmark_file_remove_item +g_bookmark_file_move_item + + +g_bookmark_file_error_quark +
+ +
+Dynamic Loading of Modules +modules +gmodule.h +GModule +GModuleError +G_MODULE_ERROR +g_module_supported +g_module_build_path +g_module_open +g_module_open_full +GModuleFlags +g_module_symbol +g_module_name +g_module_make_resident +g_module_close +g_module_error + +GModuleCheckInit +GModuleUnload +G_MODULE_SUFFIX +G_MODULE_EXPORT +G_MODULE_IMPORT + +g_module_error_quark +
+ +
+Automatic String Completion +completion +GCompletion +g_completion_new +GCompletionFunc +g_completion_add_items +g_completion_remove_items +g_completion_clear_items +g_completion_complete +g_completion_complete_utf8 +g_completion_set_compare +GCompletionStrncmpFunc +g_completion_free +
+ +
+Windows Compatibility Functions +windows +MAXPATHLEN +GWin32OSType + +g_win32_check_windows_version +g_win32_get_command_line +g_win32_error_message +g_win32_getlocale +g_win32_get_package_installation_directory +g_win32_get_package_installation_directory_of_module +g_win32_get_package_installation_subdirectory +g_win32_get_windows_version +g_win32_locale_filename_from_utf8 +G_WIN32_DLLMAIN_FOR_DLL_NAME +G_WIN32_HAVE_WIDECHAR_API +G_WIN32_IS_NT_BASED + + +g_win32_ftruncate + +
+ +
+UNIX-specific utilities and integration +gunix +G_UNIX_ERROR +g_unix_open_pipe +g_unix_set_fd_nonblocking + + +g_unix_signal_add +g_unix_signal_add_full +g_unix_signal_source_new + + +GUnixFDSourceFunc +g_unix_fd_add +g_unix_fd_add_full +g_unix_fd_source_new + + +g_unix_get_passwd_entry + + +g_unix_error_quark +
+ +# Data Structures + +
+Memory Slices +memory_slices +g_slice_alloc +g_slice_alloc0 +g_slice_copy +g_slice_free1 +g_slice_free_chain_with_offset + + +g_slice_new +g_slice_new0 +g_slice_dup +g_slice_free +g_slice_free_chain + + +GSliceConfig +g_slice_set_config +g_slice_get_config +g_slice_get_config_state +g_slice_debug_tree_statistics +
+ +
+Doubly-Linked Lists +linked_lists_double +GList + + +g_list_append +g_list_prepend +g_list_insert +g_list_insert_before +g_list_insert_before_link +g_list_insert_sorted +g_list_remove +g_list_remove_link +g_list_delete_link +g_list_remove_all +g_list_free +g_list_free_full +g_clear_list + + +g_list_alloc +g_list_free_1 +g_list_free1 + + +g_list_length +g_list_copy +g_list_copy_deep +g_list_reverse +g_list_sort +GCompareFunc +g_list_insert_sorted_with_data +g_list_sort_with_data +GCompareDataFunc +g_list_concat +g_list_foreach +GFunc + + +g_list_first +g_list_last +g_list_previous +g_list_next +g_list_nth +g_list_nth_data +g_list_nth_prev + + +g_list_find +g_list_find_custom +g_list_position +g_list_index +
+ +
+Singly-Linked Lists +linked_lists_single +GSList + + +g_slist_alloc +g_slist_append +g_slist_prepend +g_slist_insert +g_slist_insert_before +g_slist_insert_sorted +g_slist_remove +g_slist_remove_link +g_slist_delete_link +g_slist_remove_all +g_slist_free +g_slist_free_full +g_slist_free_1 +g_slist_free1 +g_clear_slist + + +g_slist_length +g_slist_copy +g_slist_copy_deep +g_slist_reverse +g_slist_insert_sorted_with_data +g_slist_sort +g_slist_sort_with_data +g_slist_concat +g_slist_foreach + + +g_slist_last +g_slist_next +g_slist_nth +g_slist_nth_data + + +g_slist_find +g_slist_find_custom +g_slist_position +g_slist_index +
+ +
+Double-ended Queues +queue + +GQueue +g_queue_new +g_queue_free +g_queue_free_full +G_QUEUE_INIT +g_queue_init +g_queue_clear +g_queue_clear_full +g_queue_is_empty +g_queue_get_length +g_queue_reverse +g_queue_copy +g_queue_foreach +g_queue_find +g_queue_find_custom +g_queue_sort +g_queue_push_head +g_queue_push_tail +g_queue_push_nth +g_queue_pop_head +g_queue_pop_tail +g_queue_pop_nth +g_queue_peek_head +g_queue_peek_tail +g_queue_peek_nth +g_queue_index +g_queue_remove +g_queue_remove_all +g_queue_insert_before +g_queue_insert_before_link +g_queue_insert_after +g_queue_insert_after_link +g_queue_insert_sorted +g_queue_push_head_link +g_queue_push_tail_link +g_queue_push_nth_link +g_queue_pop_head_link +g_queue_pop_tail_link +g_queue_pop_nth_link +g_queue_peek_head_link +g_queue_peek_tail_link +g_queue_peek_nth_link +g_queue_link_index +g_queue_unlink +g_queue_delete_link +
+ +
+Sequences +sequence + +GSequence +GSequenceIter +GSequenceIterCompareFunc + + +g_sequence_new +g_sequence_free +g_sequence_get_length +g_sequence_is_empty +g_sequence_foreach +g_sequence_foreach_range +g_sequence_sort +g_sequence_sort_iter + + +g_sequence_get_begin_iter +g_sequence_get_end_iter +g_sequence_get_iter_at_pos +g_sequence_append +g_sequence_prepend +g_sequence_insert_before +g_sequence_move +g_sequence_swap +g_sequence_insert_sorted +g_sequence_insert_sorted_iter +g_sequence_sort_changed +g_sequence_sort_changed_iter +g_sequence_remove +g_sequence_remove_range +g_sequence_move_range +g_sequence_search +g_sequence_search_iter +g_sequence_lookup +g_sequence_lookup_iter + + +g_sequence_get +g_sequence_set + + +g_sequence_iter_is_begin +g_sequence_iter_is_end +g_sequence_iter_next +g_sequence_iter_prev +g_sequence_iter_get_position +g_sequence_iter_move +g_sequence_iter_get_sequence + + +g_sequence_iter_compare +g_sequence_range_get_midpoint +
+ +
+Trash Stacks +trash_stack +GTrashStack + +g_trash_stack_push +g_trash_stack_pop +g_trash_stack_peek +g_trash_stack_height +
+ +
+Hash Tables +hash_tables +GHashTable +g_hash_table_new +g_hash_table_new_full +g_hash_table_new_similar +GHashFunc +GEqualFunc +g_hash_table_insert +g_hash_table_replace +g_hash_table_add +g_hash_table_contains +g_hash_table_size +g_hash_table_lookup +g_hash_table_lookup_extended +g_hash_table_foreach +g_hash_table_find +GHFunc +g_hash_table_remove +g_hash_table_steal +g_hash_table_steal_extended +g_hash_table_foreach_remove +g_hash_table_foreach_steal +g_hash_table_remove_all +g_hash_table_steal_all +g_hash_table_get_keys +g_hash_table_get_values +g_hash_table_get_keys_as_array +GHRFunc +g_hash_table_freeze +g_hash_table_thaw +g_hash_table_destroy +g_hash_table_ref +g_hash_table_unref +GHashTableIter +g_hash_table_iter_init +g_hash_table_iter_next +g_hash_table_iter_get_hash_table +g_hash_table_iter_replace +g_hash_table_iter_remove +g_hash_table_iter_steal + + +g_direct_equal +g_direct_hash +g_int_equal +g_int_hash +g_int64_equal +g_int64_hash +g_double_equal +g_double_hash +g_str_equal +g_str_hash + +
+ +
+Strings +strings +GString +g_string_new +g_string_new_len +g_string_sized_new +g_string_assign +g_string_sprintf +g_string_sprintfa +g_string_vprintf +g_string_append_vprintf +g_string_printf +g_string_append_printf +g_string_append +g_string_append_c +g_string_append_unichar +g_string_append_len +g_string_append_uri_escaped +g_string_prepend +g_string_prepend_c +g_string_prepend_unichar +g_string_prepend_len +g_string_insert +g_string_insert_c +g_string_insert_unichar +g_string_insert_len +g_string_overwrite +g_string_overwrite_len +g_string_replace +g_string_erase +g_string_truncate +g_string_set_size +g_string_free +g_string_free_to_bytes + + +g_string_up +g_string_down + + +g_string_hash +g_string_equal + + +g_string_append_c_inline +g_autoptr_cleanup_gstring_free +
+ +
+String Chunks +string_chunks +GStringChunk +g_string_chunk_new +g_string_chunk_insert +g_string_chunk_insert_const +g_string_chunk_insert_len +g_string_chunk_clear +g_string_chunk_free + +
+ +
+Arrays +arrays +GArray +g_array_new +g_array_steal +g_array_sized_new +g_array_copy +g_array_ref +g_array_unref +g_array_get_element_size +g_array_append_val +g_array_append_vals +g_array_prepend_val +g_array_prepend_vals +g_array_insert_val +g_array_insert_vals +g_array_remove_index +g_array_remove_index_fast +g_array_remove_range +g_array_sort +g_array_sort_with_data +g_array_binary_search +g_array_index +g_array_set_size +g_array_set_clear_func +g_array_free +
+ +
+Pointer Arrays +arrays_pointer +GPtrArray +g_ptr_array_new +g_ptr_array_steal +g_ptr_array_sized_new +g_ptr_array_new_with_free_func +g_ptr_array_copy +g_ptr_array_new_full +g_ptr_array_set_free_func +g_ptr_array_ref +g_ptr_array_unref +g_ptr_array_add +g_ptr_array_extend +g_ptr_array_extend_and_steal +g_ptr_array_insert +g_ptr_array_remove +g_ptr_array_remove_index +g_ptr_array_remove_fast +g_ptr_array_remove_index_fast +g_ptr_array_remove_range +g_ptr_array_steal_index +g_ptr_array_steal_index_fast +g_ptr_array_sort +g_ptr_array_sort_with_data +g_ptr_array_set_size +g_ptr_array_index +g_ptr_array_free +g_ptr_array_foreach +g_ptr_array_find +g_ptr_array_find_with_equal_func + +
+ +
+Byte Arrays +arrays_byte + +GByteArray +g_byte_array_new +g_byte_array_steal +g_byte_array_new_take +g_byte_array_sized_new +g_byte_array_ref +g_byte_array_unref +g_byte_array_append +g_byte_array_prepend +g_byte_array_remove_index +g_byte_array_remove_index_fast +g_byte_array_remove_range +g_byte_array_sort +g_byte_array_sort_with_data +g_byte_array_set_size +g_byte_array_free +g_byte_array_free_to_bytes + + +GBytes +g_bytes_new +g_bytes_new_take +g_bytes_new_static +g_bytes_new_with_free_func +g_bytes_new_from_bytes +g_bytes_get_data +g_bytes_get_region +g_bytes_get_size +g_bytes_hash +g_bytes_equal +g_bytes_compare +g_bytes_ref +g_bytes_unref +g_bytes_unref_to_data +g_bytes_unref_to_array + + +g_bytes_get_type +
+ +
+Balanced Binary Trees +trees-binary +GTree +GTreeNode +g_tree_new +g_tree_ref +g_tree_unref +g_tree_new_with_data +g_tree_new_full +g_tree_node_first +g_tree_node_last +g_tree_node_previous +g_tree_node_next +g_tree_insert_node +g_tree_insert +g_tree_replace_node +g_tree_replace +g_tree_node_key +g_tree_node_value +g_tree_nnodes +g_tree_height +g_tree_lookup_node +g_tree_lookup +g_tree_lookup_extended +g_tree_foreach_node +g_tree_foreach +g_tree_traverse +GTraverseFunc +GTraverseNodeFunc +g_tree_search_node +g_tree_search +g_tree_lower_bound +g_tree_upper_bound +g_tree_remove +g_tree_steal +g_tree_remove_all +g_tree_destroy +
+ +
+N-ary Trees +trees-nary +GNode +g_node_new +g_node_copy +GCopyFunc +g_node_copy_deep + + +g_node_insert +g_node_insert_before +g_node_insert_after +g_node_append +g_node_prepend + + +g_node_insert_data +g_node_insert_data_after +g_node_insert_data_before +g_node_append_data +g_node_prepend_data + + +g_node_reverse_children +g_node_traverse +GTraverseType +GTraverseFlags +GNodeTraverseFunc +g_node_children_foreach +GNodeForeachFunc + + +g_node_get_root +g_node_find +g_node_find_child +g_node_child_index +g_node_child_position +g_node_first_child +g_node_last_child +g_node_nth_child +g_node_first_sibling +g_node_next_sibling +g_node_prev_sibling +g_node_last_sibling + + +G_NODE_IS_LEAF +G_NODE_IS_ROOT +g_node_depth +g_node_n_nodes +g_node_n_children +g_node_is_ancestor +g_node_max_height + + +g_node_unlink +g_node_destroy +
+ + +
+Quarks +quarks +GQuark +G_DEFINE_QUARK +g_quark_from_string +g_quark_from_static_string +g_quark_to_string +g_quark_try_string +g_intern_string +g_intern_static_string +
+ +
+Keyed Data Lists +datalist +GData +g_datalist_init + + +g_datalist_id_set_data +g_datalist_id_set_data_full +g_datalist_id_get_data +g_datalist_id_remove_data +g_datalist_id_remove_no_notify +GDuplicateFunc +g_datalist_id_dup_data +g_datalist_id_replace_data + + +g_datalist_set_data +g_datalist_set_data_full +g_datalist_get_data +g_datalist_remove_data +g_datalist_remove_no_notify + + +g_datalist_foreach +g_datalist_clear +g_datalist_set_flags +g_datalist_unset_flags +g_datalist_get_flags +G_DATALIST_FLAGS_MASK +
+ + +
+Datasets +datasets +g_dataset_id_set_data +g_dataset_id_set_data_full +GDestroyNotify +g_dataset_id_get_data +g_dataset_id_remove_data +g_dataset_id_remove_no_notify + + +g_dataset_set_data +g_dataset_set_data_full +g_dataset_get_data +g_dataset_remove_data +g_dataset_remove_no_notify + + +g_dataset_foreach +GDataForeachFunc +g_dataset_destroy + +
+ +
+Relations and Tuples +relations +GRelation +g_relation_new +g_relation_index +g_relation_insert +g_relation_exists +g_relation_count +g_relation_select +g_relation_delete +g_relation_destroy + + +g_relation_print + + +GTuples +g_tuples_destroy +g_tuples_index +
+ +
+Caches +caches +GCache +g_cache_new +g_cache_insert +g_cache_remove +g_cache_destroy + + +g_cache_key_foreach +g_cache_value_foreach + + +GCacheDestroyFunc +GCacheDupFunc +GCacheNewFunc +
+ +
+Random Numbers +random_numbers +GRand +g_rand_new_with_seed +g_rand_new_with_seed_array +g_rand_new +g_rand_copy +g_rand_free +g_rand_set_seed +g_rand_set_seed_array +g_rand_boolean +g_rand_int +g_rand_int_range +g_rand_double +g_rand_double_range +g_random_set_seed +g_random_boolean +g_random_int +g_random_int_range +g_random_double +g_random_double_range +
+ +
+Character Set Conversion +conversions +g_convert +g_convert_with_fallback +GIConv +g_convert_with_iconv +G_CONVERT_ERROR +g_iconv_open +g_iconv +g_iconv_close +g_locale_to_utf8 +g_filename_to_utf8 +g_filename_from_utf8 +g_get_filename_charsets +g_filename_display_name +g_filename_display_basename +g_locale_from_utf8 +GConvertError + + +g_get_charset +g_get_codeset +g_get_console_charset + + +g_convert_error_quark +
+ +
+Unicode Manipulation +unicode +gunichar +gunichar2 + + +g_unichar_validate +g_unichar_isalnum +g_unichar_isalpha +g_unichar_iscntrl +g_unichar_isdefined +g_unichar_isdigit +g_unichar_isgraph +g_unichar_islower +g_unichar_ismark +g_unichar_isprint +g_unichar_ispunct +g_unichar_isspace +g_unichar_istitle +g_unichar_isupper +g_unichar_isxdigit +g_unichar_iswide +g_unichar_iswide_cjk +g_unichar_iszerowidth +g_unichar_toupper +g_unichar_tolower +g_unichar_totitle +g_unichar_digit_value +g_unichar_xdigit_value +g_unichar_compose +g_unichar_decompose +g_unichar_fully_decompose +G_UNICHAR_MAX_DECOMPOSITION_LENGTH +GUnicodeType +G_UNICODE_COMBINING_MARK +g_unichar_type +GUnicodeBreakType +g_unichar_break_type +g_unichar_combining_class +g_unicode_canonical_ordering +g_unicode_canonical_decomposition +g_unichar_get_mirror_char +GUnicodeScript +g_unichar_get_script +g_unicode_script_from_iso15924 +g_unicode_script_to_iso15924 + + +g_utf8_next_char +g_utf8_get_char +g_utf8_get_char_validated +g_utf8_offset_to_pointer +g_utf8_pointer_to_offset +g_utf8_prev_char +g_utf8_find_next_char +g_utf8_find_prev_char +g_utf8_strlen +g_utf8_strncpy +g_utf8_strchr +g_utf8_strrchr +g_utf8_strreverse +g_utf8_substring +g_utf8_validate +g_utf8_validate_len +g_utf8_make_valid + + +g_utf8_strup +g_utf8_strdown +g_utf8_casefold +g_utf8_normalize +GNormalizeMode +g_utf8_collate +g_utf8_collate_key +g_utf8_collate_key_for_filename + + +g_utf8_to_utf16 +g_utf8_to_ucs4 +g_utf8_to_ucs4_fast +g_utf16_to_ucs4 +g_utf16_to_utf8 +g_ucs4_to_utf16 +g_ucs4_to_utf8 +g_unichar_to_utf8 + + +g_utf8_skip +
+ +
+I18N +i18n +glib.h,glib/gi18n.h +_ +Q_ +C_ +N_ +NC_ +g_dgettext +g_dcgettext +g_dngettext +g_dpgettext +g_dpgettext2 +g_strip_context + +g_get_language_names +g_get_locale_variants +
+ +
+Base64 Encoding +base64 +g_base64_encode_step +g_base64_encode_close +g_base64_encode +g_base64_decode_step +g_base64_decode +g_base64_decode_inplace +
+ +
+URI Functions +guri +GUri +g_uri_ref +g_uri_unref + +GUriFlags +g_uri_split +g_uri_split_with_user +g_uri_split_network +g_uri_is_valid +g_uri_join +g_uri_join_with_user +g_uri_parse +g_uri_parse_relative +g_uri_resolve_relative +g_uri_build +g_uri_build_with_user +g_uri_peek_scheme +g_uri_parse_scheme + +GUriHideFlags +g_uri_to_string +g_uri_to_string_partial + +g_uri_get_scheme +g_uri_get_userinfo +g_uri_get_user +g_uri_get_password +g_uri_get_auth_params +g_uri_get_host +g_uri_get_port +g_uri_get_path +g_uri_get_query +g_uri_get_fragment +g_uri_get_flags + +GUriParamsIter +GUriParamsFlags +g_uri_params_iter_init +g_uri_params_iter_next +g_uri_parse_params + +G_URI_RESERVED_CHARS_ALLOWED_IN_PATH +G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT +G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO +G_URI_RESERVED_CHARS_GENERIC_DELIMITERS +G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS +g_uri_escape_string +g_uri_unescape_string +g_uri_escape_bytes +g_uri_unescape_bytes +g_uri_unescape_segment + +g_uri_list_extract_uris +g_filename_from_uri +g_filename_to_uri + +G_URI_ERROR +GUriError + +g_uri_error_quark +
+ +
+Data Checksums +checksum +GChecksumType +g_checksum_type_get_length +GChecksum +g_checksum_new +g_checksum_copy +g_checksum_free +g_checksum_reset +g_checksum_update +g_checksum_get_string +g_checksum_get_digest + +g_compute_checksum_for_data +g_compute_checksum_for_string +g_compute_checksum_for_bytes +
+ +
+Data HMACs +hmac +GHmac +g_hmac_new +g_hmac_copy +g_hmac_ref +g_hmac_unref +g_hmac_update +g_hmac_get_string +g_hmac_get_digest + +g_compute_hmac_for_data +g_compute_hmac_for_string +g_compute_hmac_for_bytes +
+ +
+Testing +testing +G_TEST_OPTION_ISOLATE_DIRS +g_test_minimized_result +g_test_maximized_result +g_test_init +g_test_initialized +g_test_quick +g_test_slow +g_test_thorough +g_test_perf +g_test_verbose +g_test_undefined +g_test_quiet +g_test_subprocess +g_test_run +GTestFunc +g_test_add_func +GTestDataFunc +g_test_add_data_func +g_test_add_data_func_full +g_test_add +g_test_get_path + +GTestFileType +g_test_build_filename +g_test_get_filename +g_test_get_dir + +g_test_fail +g_test_fail_printf +g_test_skip +g_test_skip_printf +g_test_incomplete +g_test_incomplete_printf +g_test_failed +g_test_message +g_test_bug_base +g_test_bug +g_test_summary +GTestLogFatalFunc +g_test_log_set_fatal_handler + +g_test_timer_start +g_test_timer_elapsed +g_test_timer_last + +g_test_queue_free +g_test_queue_destroy +g_test_queue_unref + +g_test_expect_message +g_test_assert_expected_messages + +GTestTrapFlags +GTestSubprocessFlags +g_test_trap_subprocess +g_test_trap_has_passed +g_test_trap_reached_timeout +g_test_trap_assert_passed +g_test_trap_assert_failed +g_test_trap_assert_stdout +g_test_trap_assert_stdout_unmatched +g_test_trap_assert_stderr +g_test_trap_assert_stderr_unmatched +g_test_trap_fork + +g_test_rand_bit +g_test_rand_int +g_test_rand_int_range +g_test_rand_double +g_test_rand_double_range + +g_assert +g_assert_not_reached + +g_assert_cmpstr +g_assert_cmpstrv +g_assert_cmpint +g_assert_cmpuint +g_assert_cmphex +g_assert_cmpfloat +g_assert_cmpfloat_with_epsilon +g_assert_cmpmem +g_assert_cmpvariant +g_assert_no_error +g_assert_error +g_assert_true +g_assert_false +g_assert_null +g_assert_nonnull +g_assert_no_errno +g_test_set_nonfatal_assertions + +GTestCase +GTestSuite +GTestFixtureFunc +g_test_create_case +g_test_create_suite +g_test_get_root +g_test_suite_add +g_test_suite_add_suite +g_test_run_suite +g_test_case_free +g_test_suite_free + + +g_test_trap_assertions +g_assertion_message +g_assertion_message_expr +g_assertion_message_cmpstr +g_assertion_message_cmpnum +g_assertion_message_error +g_test_assert_expected_messages_internal + +g_test_config_vars + +g_test_add_vtable +GTestConfig +GTestLogType +GTestLogMsg +GTestLogBuffer +GTestResult + +g_test_log_type_name +g_test_log_buffer_new +g_test_log_buffer_free +g_test_log_buffer_push +g_test_log_buffer_pop +g_test_log_msg_free +
+ +
+GVariantType +gvarianttype +GVariantType +G_VARIANT_TYPE_BOOLEAN +G_VARIANT_TYPE_BYTE +G_VARIANT_TYPE_INT16 +G_VARIANT_TYPE_UINT16 +G_VARIANT_TYPE_INT32 +G_VARIANT_TYPE_UINT32 +G_VARIANT_TYPE_INT64 +G_VARIANT_TYPE_UINT64 +G_VARIANT_TYPE_HANDLE +G_VARIANT_TYPE_DOUBLE +G_VARIANT_TYPE_STRING +G_VARIANT_TYPE_OBJECT_PATH +G_VARIANT_TYPE_SIGNATURE +G_VARIANT_TYPE_VARIANT +G_VARIANT_TYPE_ANY +G_VARIANT_TYPE_BASIC +G_VARIANT_TYPE_MAYBE +G_VARIANT_TYPE_ARRAY +G_VARIANT_TYPE_TUPLE +G_VARIANT_TYPE_UNIT +G_VARIANT_TYPE_DICT_ENTRY +G_VARIANT_TYPE_DICTIONARY +G_VARIANT_TYPE_STRING_ARRAY +G_VARIANT_TYPE_OBJECT_PATH_ARRAY +G_VARIANT_TYPE_BYTESTRING +G_VARIANT_TYPE_BYTESTRING_ARRAY +G_VARIANT_TYPE_VARDICT + + +G_VARIANT_TYPE +g_variant_type_free +g_variant_type_copy +g_variant_type_new + + +g_variant_type_string_is_valid +g_variant_type_string_scan +g_variant_type_get_string_length +g_variant_type_peek_string +g_variant_type_dup_string + + +g_variant_type_is_definite +g_variant_type_is_container +g_variant_type_is_basic +g_variant_type_is_maybe +g_variant_type_is_array +g_variant_type_is_tuple +g_variant_type_is_dict_entry +g_variant_type_is_variant + + +g_variant_type_hash +g_variant_type_equal +g_variant_type_is_subtype_of + + +g_variant_type_new_maybe +g_variant_type_new_array +g_variant_type_new_tuple +g_variant_type_new_dict_entry + + +g_variant_type_element +g_variant_type_n_items +g_variant_type_first +g_variant_type_next +g_variant_type_key +g_variant_type_value +
+ +
+GVariant +gvariant +GVariant +g_variant_unref +g_variant_ref +g_variant_ref_sink +g_variant_is_floating +g_variant_take_ref +g_variant_get_type +g_variant_get_type_string +g_variant_is_of_type +g_variant_is_container +g_variant_compare + + +g_variant_classify +GVariantClass + + +g_variant_check_format_string +g_variant_get +g_variant_get_va +g_variant_new +g_variant_new_va + + +g_variant_new_boolean +g_variant_new_byte +g_variant_new_int16 +g_variant_new_uint16 +g_variant_new_int32 +g_variant_new_uint32 +g_variant_new_int64 +g_variant_new_uint64 +g_variant_new_handle +g_variant_new_double +g_variant_new_string +g_variant_new_take_string +g_variant_new_printf +g_variant_new_object_path +g_variant_is_object_path +g_variant_new_signature +g_variant_is_signature +g_variant_new_variant +g_variant_new_strv +g_variant_new_objv +g_variant_new_bytestring +g_variant_new_bytestring_array + + +g_variant_get_boolean +g_variant_get_byte +g_variant_get_int16 +g_variant_get_uint16 +g_variant_get_int32 +g_variant_get_uint32 +g_variant_get_int64 +g_variant_get_uint64 +g_variant_get_handle +g_variant_get_double +g_variant_get_string +g_variant_dup_string +g_variant_get_variant +g_variant_get_strv +g_variant_dup_strv +g_variant_get_objv +g_variant_dup_objv +g_variant_get_bytestring +g_variant_dup_bytestring +g_variant_get_bytestring_array +g_variant_dup_bytestring_array + + +g_variant_new_maybe +g_variant_new_array +g_variant_new_tuple +g_variant_new_dict_entry +g_variant_new_fixed_array + + +g_variant_get_maybe +g_variant_n_children +g_variant_get_child_value +g_variant_get_child +g_variant_lookup_value +g_variant_lookup +g_variant_get_fixed_array + + +g_variant_get_size +g_variant_get_data +g_variant_get_data_as_bytes +g_variant_store +g_variant_new_from_data +g_variant_new_from_bytes +g_variant_byteswap +g_variant_get_normal_form +g_variant_is_normal_form + + +g_variant_hash +g_variant_equal + + +g_variant_print +g_variant_print_string + + +GVariantIter +g_variant_iter_copy +g_variant_iter_free +g_variant_iter_init +g_variant_iter_n_children +g_variant_iter_new +g_variant_iter_next_value +g_variant_iter_next +g_variant_iter_loop + + +G_VARIANT_BUILDER_INIT +GVariantBuilder +g_variant_builder_unref +g_variant_builder_ref +g_variant_builder_new +g_variant_builder_init +g_variant_builder_clear +g_variant_builder_add_value +g_variant_builder_add +g_variant_builder_add_parsed +g_variant_builder_end +g_variant_builder_open +g_variant_builder_close + + +G_VARIANT_DICT_INIT +GVariantDict +g_variant_dict_unref +g_variant_dict_ref +g_variant_dict_new +g_variant_dict_init +g_variant_dict_clear +g_variant_dict_contains +g_variant_dict_lookup +g_variant_dict_lookup_value +g_variant_dict_insert +g_variant_dict_insert_value +g_variant_dict_remove +g_variant_dict_end + + +GVariantParseError +G_VARIANT_PARSE_ERROR +g_variant_parse +g_variant_new_parsed_va +g_variant_new_parsed +g_variant_parse_error_print_context + + +g_variant_parse_error_quark +g_variant_parser_get_error_quark +g_variant_type_checked_ +g_variant_type_string_get_depth_ +
+ + +
+ghostutils +Hostname Utilities +g_hostname_to_ascii +g_hostname_to_unicode + +g_hostname_is_non_ascii +g_hostname_is_ascii_encoded + +g_hostname_is_ip_address +
+ +
+uuid +GUuid +g_uuid_string_is_valid +g_uuid_string_random +
+ +
+refcount +grefcount +g_ref_count_init +g_ref_count_inc +g_ref_count_dec +g_ref_count_compare + +gatomicrefcount +g_atomic_ref_count_init +g_atomic_ref_count_inc +g_atomic_ref_count_dec +g_atomic_ref_count_compare +
+ +
+rcbox +g_rc_box_alloc +g_rc_box_alloc0 +g_rc_box_new +g_rc_box_new0 +g_rc_box_dup +g_rc_box_acquire +g_rc_box_release +g_rc_box_release_full +g_rc_box_get_size +
+ +
+arcbox +g_atomic_rc_box_alloc +g_atomic_rc_box_alloc0 +g_atomic_rc_box_new +g_atomic_rc_box_new0 +g_atomic_rc_box_dup +g_atomic_rc_box_acquire +g_atomic_rc_box_release +g_atomic_rc_box_release_full +g_atomic_rc_box_get_size +
+ +
+refstring +GRefString +g_ref_string_new +g_ref_string_new_intern +g_ref_string_new_len +g_ref_string_acquire +g_ref_string_release +g_ref_string_length +
diff --git a/docs/reference/glib/gtester-report.xml b/docs/reference/glib/gtester-report.xml new file mode 100644 index 0000000..eee9337 --- /dev/null +++ b/docs/reference/glib/gtester-report.xml @@ -0,0 +1,78 @@ + + + +gtester-report +GLib + + +Developer +Tim +Janik + + + + + +gtester-report +1 +User Commands + + + +gtester-report +test report formatting utility + + + + +gtester-report +option +gtester-log + + + +Description +gtester-report is a script which converts +the XML output generated by gtester into HTML. + +Since GLib 2.62, gtester-report is deprecated. Use +TAP for reporting test results instead, and feed it to the test harness provided +by your build system. + + +Options + + + +, + +print help and exit + + + + +, + +print version information and exit + + + + +, + +Output subunit. Needs python-subunit. + + + + + + +See also + + +gtester +1 + + + + diff --git a/docs/reference/glib/gtester.xml b/docs/reference/glib/gtester.xml new file mode 100644 index 0000000..5626d4d --- /dev/null +++ b/docs/reference/glib/gtester.xml @@ -0,0 +1,192 @@ + + + +gtester +GLib + + +Developer +Tim +Janik + + +Developer +Sven +Herzberg + + + + + +gtester +1 +User Commands + + + +gtester +test running utility + + + + +gtester +OPTION +testprogram + + + +Description +gtester is a utility to run unit tests that have +been written using the GLib test framework. + +Since GLib 2.62, gtester-report is deprecated. Use +TAP for reporting test results instead, and feed it to the test harness provided +by your build system. + +When called with the option, gtester +writes an XML report of the test results, which can be converted +into HTML using the gtester-report utility. + + + +Options + + + +, + +print help and exit + + + + +, + +print version information and exit + + + + + + +make warnings fatal + + + + +, + +continue running after tests failed + + + + + + +list paths of available test cases + + + + + + + run test cases in MODE, which can be one of: + + + + + + run performance tests + + + + + , + + run slow tests, or repeat non-deterministic tests more often + + + + + + + do not run slow or performance tests, or do extra repeats + of non-deterministic tests (default) + + + + + + + run test cases that deliberately provoke checks or assertion + failures, if implemented (default) + + + + + + + do not run test cases that deliberately provoke checks or + assertion failures + + + + + + + + + + +only run test cases matching TESTPATH + + + + + + +skip test cases matching TESTPATH + + + + + + +run all test cases with random number seed SEEDSTRING + + + + + + +write the test log to LOGFILE + + + + +, + +suppress per test binary output + + + + + + +report success per testcase + + + + + + +See also + + +gtester-report +1 + + + + diff --git a/docs/reference/glib/gvariant-text.xml b/docs/reference/glib/gvariant-text.xml new file mode 100644 index 0000000..55d476e --- /dev/null +++ b/docs/reference/glib/gvariant-text.xml @@ -0,0 +1,622 @@ + + + + + GVariant Text Format + + + GVariant Text Format + textual representation of GVariants + + + + GVariant Text Format + + + This page attempts to document the GVariant text format as produced by + g_variant_print() and parsed by the + g_variant_parse() family of functions. In most + cases the style closely resembles the formatting of literals in Python but there are some additions and + exceptions. + + + + The functions that deal with GVariant text format absolutely always deal in utf-8. Conceptually, GVariant + text format is a string of Unicode characters -- not bytes. Non-ASCII but otherwise printable Unicode + characters are not treated any differently from normal ASCII characters. + + + + The parser makes two passes. The purpose of the first pass is to determine the type of the value being + parsed. The second pass does the actual parsing. Based on the fact that all elements in an array have to + have the same type, GVariant is able to make some deductions that would not otherwise be possible. As an + example: + + [[1, 2, 3], [4, 5, 6]] + + is parsed as an array of arrays of integers (type 'aai'), but + + [[1, 2, 3], [4, 5, 6.0]] + + is parsed as an array of arrays of doubles (type 'aad'). + + + + As another example, GVariant is able to determine that + + ["hello", nothing] + + is an array of maybe strings (type 'ams'). + + + + What the parser accepts as valid input is dependent on context. The API permits for out-of-band type + information to be supplied to the parser (which will change its behaviour). This can be seen in the + GSettings and GDBus command line utilities where the type information is available from the schema or the + remote introspection information. The additional information can cause parses to succeed when they would not + otherwise have been able to (by resolving ambiguous type information) or can cause them to fail (due to + conflicting type information). Unless stated otherwise, the examples given in this section assume that no + out-of-band type data has been given to the parser. + + + + + Syntax Summary + + + The following table describes the rough meaning of symbols that may appear inside GVariant text format. + Each symbol is described in detail in its own section, including usage examples. + + + + + + + + + + + + Symbol + + + + + Meaning + + + + + + + + true, + false + + + + + Booleans. + + + + + + + + "", + '' + + + + + String literal. See Strings below. + + + + + + + + numbers + + + + + See Numbers below. + + + + + + + + () + + + + + Tuples. + + + + + + + + [] + + + + + Arrays. + + + + + + + + {} + + + + + Dictionaries and Dictionary Entries. + + + + + + + + <> + + + + + Variants. + + + + + + + + just, + nothing + + + + + Maybe Types. + + + + + + + + @ + + + + + Type Annotations. + + + + + + + + type keywords + + + + + boolean, + byte, + int16, + uint16, + int32, + uint32, + handle, + int64, + uint64, + double, + string, + objectpath, + signature + + + See Type Annotations below. + + + + + + + + b"", + b'' + + + + + Bytestrings. + + + + + + + + % + + + + + Positional Parameters. + + + + + + + + + Booleans + + The strings true and false are parsed as booleans. This is the only + way to specify a boolean value. + + + + + Strings + + Strings literals must be quoted using "" or ''. The two are + completely equivalent (except for the fact that each one is unable to contain itself unescaped). + + + Strings are Unicode strings with no particular encoding. For example, to specify the character + é, you just write 'é'. You could also give the Unicode codepoint of + that character (U+E9) as the escape sequence '\u00e9'. Since the strings are pure + Unicode, you should not attempt to encode the utf-8 byte sequence corresponding to the string using escapes; + it won't work and you'll end up with the individual characters corresponding to each byte. + + + Unicode escapes of the form \uxxxx and \Uxxxxxxxx are supported, in + hexadecimal. The usual control sequence escapes \a, \b, + \f, \n, \r, \t and + \v are supported. Additionally, a \ before a newline character causes + the newline to be ignored. Finally, any other character following \ is copied literally + (for example, \" or \\) but for forwards compatibility with future + additions you should only use this feature when necessary for escaping backslashes or quotes. + + + The usual octal and hexadecimal escapes \0nnn and \xnn are not + supported here. Those escapes are used to encode byte values and GVariant strings are Unicode. + + + Single-character strings are not interpreted as bytes. Bytes must be specified by their numerical value. + + + + + Numbers + + Numbers are given by default as decimal values. Octal and hex values can be given in the usual way (by + prefixing with 0 or 0x). Note that GVariant considers bytes to be + unsigned integers and will print them as a two digit hexadecimal number by default. + + + Floating point numbers can also be given in the usual ways, including scientific and hexadecimal notations. + + + For lack of additional information, integers will be parsed as int32 values by default. If the number has a + point or an 'e' in it, then it will be parsed as a double precision floating point number by default. If + type information is available (either explicitly or inferred) then that type will be used instead. + + + Some examples: + + + 5 parses as the int32 value five. + + + 37.5 parses as a floating point value. + + + 3.75e1 parses the same as the value above. + + + uint64 7 parses seven as a uint64. + See Type Annotations. + + + + + Tuples + + Tuples are formed using the same syntax as Python. Here are some examples: + + + () parses as the empty tuple. + + + (5,) is a tuple containing a single value. + + + ("hello", 42) is a pair. Note that values of different types are permitted. + + + + + Arrays + + Arrays are formed using the same syntax as Python uses for lists (which is arguably the term that GVariant + should have used). Note that, unlike Python lists, GVariant arrays are statically typed. This has two + implications. + + + First, all items in the array must have the same type. Second, the type of the array must be known, even in + the case that it is empty. This means that (unless there is some other way to infer it) type information + will need to be given explicitly for empty arrays. + + + The parser is able to infer some types based on the fact that all items in an array must have the same type. + See the examples below: + + + [1] parses (without additional type information) as a one-item array of signed integers. + + + [1, 2, 3] parses (similarly) as a three-item array. + + + [1, 2, 3.0] parses as an array of doubles. This is the most simple case of the type + inferencing in action. + + + [(1, 2), (3, 4.0)] causes the 2 to also be parsed as a double (but the 1 and 3 are still + integers). + + + ["", nothing] parses as an array of maybe strings. The presence of + "nothing" clearly implies that the array elements are nullable. + + + [[], [""]] will parse properly because the type of the first (empty) array can be + inferred to be equal to the type of the second array (both are arrays of strings). + + + [b'hello', []] looks odd but will parse properly. + See Bytestrings + + + And some examples of errors: + + + ["hello", 42] fails to parse due to conflicting types. + + + [] will fail to parse without additional type information. + + + + + Dictionaries and Dictionary Entries + + Dictionaries and dictionary entries are both specified using the {} characters. + + + The dictionary syntax is more commonly used. This is what the printer elects to use in the normal case of + dictionary entries appearing in an array (aka "a dictionary"). The separate syntax for dictionary entries + is typically only used for when the entries appear on their own, outside of an array (which is valid but + unusual). Of course, you are free to use the dictionary entry syntax within arrays but there is no good + reason to do so (and the printer itself will never do so). Note that, as with arrays, the type of empty + dictionaries must be established (either explicitly or through inference). + + + The dictionary syntax is the same as Python's syntax for dictionaries. Some examples: + + + @a{sv} {} parses as the empty dictionary of everyone's favourite type. + + + @a{sv} [] is the same as above (owing to the fact that dictionaries are really arrays). + + + {1: "one", 2: "two", 3: "three"} parses as a dictionary mapping integers to strings. + + + The dictionary entry syntax looks just like a pair (2-tuple) that uses braces instead of parens. The + presence of a comma immediately following the key differentiates it from the dictionary syntax (which + features a colon after the first key). Some examples: + + + {1, "one"} is a free-standing dictionary entry that can be parsed on its own or as part + of another container value. + + + [{1, "one"}, {2, "two"}, {3, "three"}] is exactly equivalent to the dictionary example + given above. + + + + + Variants + + Variants are denoted using angle brackets (aka "XML brackets"), <>. They may not + be omitted. + + + Using <> effectively disrupts the type inferencing that occurs between array + elements. This can have positive and negative effects. + + + [<"hello">, <42>] will parse whereas ["hello", 42] would + not. + + + [<['']>, <[]>] will fail to parse even though [[''], []] + parses successfully. You would need to specify [<['']>, <@as []>]. + + + {"title": <"frobit">, "enabled": <true>, "width": <800>} is an example of + perhaps the most pervasive use of both dictionaries and variants. + + + + + Maybe Types + + The syntax for specifying maybe types is inspired by Haskell. + + + The null case is specified using the keyword nothing and the non-null case is explicitly + specified using the keyword just. GVariant allows just to be omitted + in every case that it is able to unambiguously determine the intention of the writer. There are two cases + where it must be specified: + + + + when using nested maybes, in order to specify the just nothing case + + + + to establish the nullability of the type of a value without explicitly specifying its full type + + + + + Some examples: + + + just 'hello' parses as a non-null nullable string. + + + @ms 'hello' is the same (demonstrating how just can be dropped if the type is already + known). + + + nothing will not parse wtihout extra type information. + + + @ms nothing parses as a null nullable string. + + + [just 3, nothing] is an array of nullable integers + + + [3, nothing] is the same as the above (demonstrating another place were + just can be dropped). + + + [3, just nothing] parses as an array of maybe maybe integers (type + 'ammi'). + + + + + Type Annotations + + Type annotations allow additional type information to be given to the parser. Depending on the context, + this type information can change the output of the parser, cause an error when parsing would otherwise have + succeeded or resolve an error when parsing would have otherwise failed. + + + Type annotations come in two forms: type codes and type keywords. + + + Type keywords can be seen as more verbose (and more legible) versions of a common subset of the type codes. + The type keywords boolean, byte, int16, + uint16, int32, uint32, handle, + int64, uint64, double, string, + objectpath and literal signature are each exactly equivalent to their + corresponding type code. + + + Type codes are an @ ("at" sign) followed by a definite GVariant type string. Some + examples: + + + uint32 5 causes the number to be parsed unsigned instead of signed (the default). + + + @u 5 is the same + + + objectpath "/org/gnome/xyz" creates an object path instead of a normal string + + + @au [] specifies the type of the empty array (which would not parse otherwise) + + + @ms "" indicates that a string value is meant to have a maybe type + + + + + Bytestrings + + The bytestring syntax is a piece of syntactic sugar meant to complement the bytestring APIs in GVariant. It + constructs arrays of non-nul bytes (type 'ay') with a nul terminator at the end. These are + normal C strings with no particular encoding enforced, so the bytes may not be valid UTF-8. + Bytestrings are a special case of byte arrays; byte arrays (also type 'ay'), in the general + case, can contain nul at any position, and need not end with nul. + + + Bytestrings are specified with either b"" or b''. As with strings, + there is no fundamental difference between the two different types of quotes. + + + Bytestrings support the full range of escapes that you would expect (ie: those supported by + g_strcompress(). This includes the normal control + sequence escapes (as mentioned in the section on strings) as well as octal and hexadecimal escapes of the + forms \0nnn and \xnn. + + + b'abc' is equivalent to [byte 0x61, 0x62, 0x63, 0]. + + + When formatting arrays of bytes, the printer will choose to display the array as a bytestring if it contains + a nul character at the end and no other nul bytes within. Otherwise, it is formatted as a normal array. + + + + + Positional Parameters + + Positional parameters are not a part of the normal GVariant text format, but they are mentioned here because + they can be used with g_variant_new_parsed(). + + + A positional parameter is indicated with a % followed by any valid + GVariant Format String. Variable arguments are collected as + specified by the format string and the resulting value is inserted at the current position. + + + This feature is best explained by example: + + , 'enabled': <%b>}", t, en);]]> + + This constructs a dictionary mapping strings to variants (type 'a{sv}') with two items in + it. The key names are parsed from the string and the values for those keys are taken as variable arguments + parameters. + + + The arguments are always collected in the order that they appear in the string to be parsed. Format strings + that collect multiple arguments are permitted, so you may require more varargs parameters than the number of + % signs that appear. You can also give format strings that collect no arguments, but + there's no good reason to do so. + + + + diff --git a/docs/reference/glib/gvariant-varargs.xml b/docs/reference/glib/gvariant-varargs.xml new file mode 100644 index 0000000..f60eabb --- /dev/null +++ b/docs/reference/glib/gvariant-varargs.xml @@ -0,0 +1,1178 @@ + + + + + GVariant Format Strings + + + GVariant Format Strings + varargs conversion of GVariants + + + + Variable Argument Conversions + + + This page attempts to document how to perform variable argument + conversions with GVariant. + + + Conversions occur according to format strings. A format string is a two-way mapping between a single + GVariant value and one or more C values. + + + A conversion from C values into a GVariant value is made using the + g_variant_new() function. A conversion from a + GVariant into C values is made using the + g_variant_get() function. + + + + + Syntax + + + This section exhaustively describes all possibilities for GVariant format strings. There are no valid forms of + format strings other than those described here. Please note that the format string syntax is likely to expand in the + future. + + + Valid format strings have one of the following forms: + + + + any type string + + + + a type string prefixed with a '@' + + + + + '&s' '&o', '&g', '^as', + '^a&s', '^ao', '^a&o','^ay', + '^&ay', '^aay' or '^a&ay'. + + + + + any format string, prefixed with an 'm' + + + + + a sequence of zero or more format strings, concatenated and enclosed in parentheses + + + + + an opening brace, followed by two format strings, followed by a closing brace (subject to the constraint that the + first format string correspond to a type valid for use as the key type of a dictionary) + + + + + + Symbols + + + The following table describes the rough meaning of symbols that may appear inside a GVariant format string. Each + symbol is described in detail in its own section, including usage examples. + + + + + + + + + + + + Symbol + + + + + Meaning + + + + + + + + + b, y, n, q, i, + u, x, t, h, d + + + + + + Used for building or deconstructing boolean, byte and numeric types. See + Numeric Types below. + + + + + + + + + s, o, g + + + + + + Used for building or deconstructing string types. See + Strings below. + + + + + + + + v + + + + + Used for building or deconstructing variant types. See + Variants below. + + + + + + + + + a + + + + + + Used for building or deconstructing arrays. See + Arrays below. + + + + + + + + + m + + + + + + Used for building or deconstructing maybe types. See + Maybe Types below. + + + + + + + + + () + + + + + + Used for building or deconstructing tuples. See + Tuples below. + + + + + + + + + {} + + + + + + Used for building or deconstructing dictionary entries. See + Dictionaries below. + + + + + + + + + @ + + + + + + Used as a prefix for a GVariant type string (not a prefix for a format string, so @as is + a valid format string but @^as is not). Denotes that a pointer to a + GVariant should be used in place of the normal C type or types. For + g_variant_new() this means that you must pass a + non-NULL (GVariant + *); if it is a floating reference, ownership will be taken, as + if by using g_variant_ref_sink(). + For g_variant_get() this means that you + must pass a pointer to a (GVariant *) for the value to be returned + by reference or NULL to ignore the value. See + GVariant * below. + + + + + + + + + *, ?, r + + + + + + Exactly equivalent to @*, @? and @r. Provided only for + completeness so that all GVariant type strings can be used also as format strings. See GVariant * below. + + + + + + + + & + + + + + Used as a prefix for a GVariant type string (not a prefix for a format string, so &s is + a valid format string but &@s is not). + Denotes that a C pointer to serialized data + should be used in place of the normal C type. See + Pointers below. + + + + + + + + ^ + + + + + Used as a prefix on some specific types of format strings. See + Convenience Conversions below. + + + + + + + + + + Numeric Types + + + Characters: b, y, n, q, + i, u, x, t, h, + d + + + + + Variable argument conversions from numeric types work in the most obvious way possible. Upon encountering one of + these characters, g_variant_new() takes the equivalent C + type as an argument. g_variant_get() takes a pointer to + the equivalent C type (or NULL to ignore the value). + + + + The equivalent C types are as follows: + + + + + + + + + + Character + + + + + Equivalent C type + + + + + + + + b + + + + + + gboolean + + + + + + + + y + + + + + + guchar + + + + + + + + n + + + + + + gint16 + + + + + + + + q + + + + + + guint16 + + + + + + + + i + + + + + + gint32 + + + + + + + + u + + + + + + guint32 + + + + + + + + x + + + + + + gint64 + + + + + + + + t + + + + + + guint64 + + + + + + + + h + + + + + + gint32 + + + + + + + + d + + + + + + gdouble + + + + + + + + + + Note that in C, small integer types in variable argument lists are promoted up to int or unsigned int as appropriate, and + read back accordingly. int is 32 bits on every platform on which GLib is + currently supported. This means that you can use C expressions of type int + with g_variant_new() and format characters + 'b', 'y', 'n', 'q', + 'i', 'u' and 'h'. Specifically, you can use integer + literals with these characters. + + + + When using the 'x' and 't' characters, you must ensure that the value that you + provide is 64 bit. This means that you should use a cast or make use of the + G_GINT64_CONSTANT or + G_GUINT64_CONSTANT macros. + + + + No type promotion occurs when using g_variant_get() since + it operates with pointers. The pointers must always point to a memory region of exactly the correct size. + + + + Examples + + + + + + + Strings + + + Characters: s, o, g + + + + + String conversions occur to and from standard nul-terminated C strings. Upon encountering an + 's', 'o' or 'g' in a format string, + g_variant_new() takes a (const + gchar *) and makes a copy of it. + NULL is not a valid string; use + maybe types to encode that. If the 'o' or + 'g' characters are used, care must be taken to ensure that the passed string is a valid D-Bus + object path or D-Bus type signature, respectively. + + + Upon encounting 's', 'o' or 'g', g_variant_get() takes a pointer to a + (gchar *) (ie: (gchar **)) and + sets it to a newly-allocated copy of the string. It is appropriate to free this copy using + g_free(). + NULL may also be passed to indicate that the value of the + string should be ignored (in which case no copy is made). + + + + Examples + + + + + + + Variants + + + Characters: v + + + + + Upon encountering a 'v', + g_variant_new() takes a (GVariant *). The value of the + GVariant is used as the contents of the variant value. + + + Upon encountering a 'v', g_variant_get() takes a pointer to a + (GVariant *) (ie: (GVariant **) + ). It is set to a new reference to a GVariant instance + containing the contents of the variant value. It is appropriate to free this reference using + g_variant_unref(). + NULL may also be passed to indicate that the value should be + ignored (in which case no new reference is created). + + + + Examples + + + + + + + + Arrays + + + Characters: a + + + + + Upon encountering an 'a' character followed by a type string, + g_variant_new() will take a + (GVariantBuilder *) that has been created as an array builder + for an array of the type given in the type string. The builder will have + g_variant_builder_end() called on it and the + result will be used as the value. As a special exception, if the given type string is a definite type, then + NULL may be given to mean an empty array of that type. + + + + Upon encountering an 'a' character followed by a type string, + g_variant_get() will take a pointer to a + (GVariantIter *) (ie: + (GVariantIter **)). + A new heap-allocated iterator is created and returned, initialised for iterating over the elements of the array. + This iterator should be freed when you are done with it, using + g_variant_iter_free(). + NULL may also be given to indicate that the value of the array + should be ignored. + + + + Examples + + + + + + + Maybe Types + + + Characters: m + + + + Maybe types are handled in two separate ways depending on the format string that follows the + 'm'. The method that is used currently depends entirely on the character immediately following the + 'm'. + + + + The first way is used with format strings starting with 'a', 's', + 'o', 'g', 'v', '@', + '*', '?', 'r', '&', or + '^'. In all of these cases, for non-maybe types, + g_variant_new() takes a pointer to a + non-NULL value and + g_variant_get() returns (by reference) a + non-NULL pointer. When any of these format strings are + prefixed with an 'm', the type of arguments that are collected does not change in any way, but + NULL becomes a permissible value, to indicate the Nothing case. + + + Note that the "special exception" introduced in the array section for constructing empty arrays is ignored + here. Using a NULL pointer with the format string 'mas' constructs + the Nothing value -- not an empty array. + + + The second way is used with all other format strings. For + g_variant_new() an additional + gboolean argument is collected and for + g_variant_get() an additional + (gboolean *). Following this argument, the arguments that are normally + collected for the equivalent non-maybe type will be collected. + + + If FALSE is given to + g_variant_new() then the Nothing value is constructed and + the collected arguments are ignored. Otherwise (if TRUE was + given), the arguments are used in the normal way to create the Just value. + + + If NULL is given to + g_variant_get() then the value is ignored. If a + non-NULL pointer is given then it is used to return by reference + whether the value was Just. In the case that the value was Just, the + gboolean will be set to + TRUE and the value will be stored in the arguments in the usual + way. In the case that the value was Nothing, the gboolean will be set to + FALSE and the arguments will be collected in the normal way + but have their values set to binary zero. + + + + Examples + + + + + + + Tuples + + + Characters: () + + + + + Tuples are handled by handling each item in the tuple, in sequence. Each item is handled in the usual way. + + + + Examples + + + + + + + GVariant * + + + Characters: @, *, ?, r + + + + + Upon encountering a '@' in front of a type string, + g_variant_new() takes a + non-NULL pointer to a + GVariant and uses its value directly instead of collecting arguments to + create the value. The provided GVariant must have a type that matches the + type string following the '@'. '*' is + the same as '@*' (ie: take a GVariant of any type). + '?' is the same as '@?' (ie: take a + GVariant of any basic type). 'r' is the same as + '@r' (ie: take a GVariant of any tuple type). + + + Upon encountering a '@' in front of a type string, + g_variant_get() + takes a pointer to a (GVariant *) (ie: a + (GVariant **)) and sets it to a new reference to a + GVariant containing the value (instead of deconstructing the value into + C types in the usual way). NULL can be given to ignore the + value. '*', '?' and 'r' are handled in a way analogous to + what is stated above. + + + You can always use '*' as an alternative to '?', 'r' or any + use of '@'. Using the other characters where possible is recommended, however, due to the + improvements in type safety and code self-documentation. + + + + Examples + + + + + + + Dictionaries + + + Characters: {} + + + + + Dictionary entries are handled by handling first the key, then the value. Each is handled in the usual way. + + + + Examples + + + + + + To extract data from nested dictionaries you can go through a vardict. + + + + Examples + +, 'max': <%i>}})", + "/object/path", value, max); +{ + GVariant *params; + GVariant *p_brightness; + gchar *obj + gint p_max; + + g_variant_get (data, "(o@a{?*})", &obj, ¶ms); + g_print ("object_path: %s\n", obj); + g_free (obj); + + p_brightness = g_variant_lookup_value (params, "brightness", G_VARIANT_TYPE_VARDICT); + g_variant_lookup (p_brightness, "max", "i", &p_max); + g_print ("max: %d\n", p_max); + g_variant_unref (params); +}]]> + + + + + + Pointers + + + Characters: & + + + + + The '&' character is used to indicate that serialized data should be directly exchanged via a + pointer. + + + Currently, the only use for this character is when it is applied to a string (ie: '&s', + '&o' or '&g'). For + g_variant_new() this has absolutely no effect. The string + is collected and duplicated normally. For g_variant_get() + it means that instead of creating a newly allocated copy of the string, a pointer to the serialized data is + returned. This pointer should not be freed. Validity checks are performed to ensure that the string data will + always be properly nul-terminated. + + + + Examples + + + + + + + Convenience Conversions + + + Characters: ^ + + + + + The '^' character currently supports conversion to and from bytestrings or to and from arrays + of strings or bytestrings. It does not support byte arrays. It has a number of forms. + + + + In all forms, when used with g_variant_new() one + pointer value is collected from the variable arguments and passed to a function (as given in the table below). + The result of that function is used as the value for this position. When used with + g_variant_get() one pointer value is produced by using + the function (given in the table) and returned by reference. + + + + + + + + + + + + + Conversion + + + + + + Used with g_variant_new() + + + + + + + Used with g_variant_get() + + + + + + + + + + ^as + + + + + + equivalent to g_variant_new_strv() + + + + + equivalent to g_variant_dup_strv() + + + + + + + + + ^a&s + + + + + + equivalent to g_variant_get_strv() + + + + + + + + + ^ao + + + + + + equivalent to g_variant_new_objv() + + + + + equivalent to g_variant_dup_objv() + + + + + + + + + ^a&o + + + + + + equivalent to g_variant_get_objv() + + + + + + + + + ^ay + + + + + + equivalent to g_variant_new_bytestring() + + + + + equivalent to g_variant_dup_bytestring() + + + + + + + + + ^&ay + + + + + + equivalent to g_variant_get_bytestring() + + + + + + + + + ^aay + + + + + + equivalent to g_variant_new_bytestring_array() + + + + + equivalent to g_variant_dup_bytestring_array() + + + + + + + + + ^a&ay + + + + + + equivalent to g_variant_get_bytestring_array() + + + + + + + + + + diff --git a/docs/reference/glib/mainloop-states.eps b/docs/reference/glib/mainloop-states.eps new file mode 100644 index 0000000..b3d159b --- /dev/null +++ b/docs/reference/glib/mainloop-states.eps @@ -0,0 +1,306 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: mainloop-stages.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3c +%%CreationDate: Wed Nov 29 12:23:52 2000 +%%For: otaylor@fresnel.labs.redhat.com (Owen Taylor) +%%BoundingBox: 0 0 503 291 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 291 moveto 0 0 lineto 503 0 lineto 503 291 lineto closepath clip newpath +-106.0 402.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +/Times-Roman ff 270.00 scf sf +9300 6225 m +gs 1 -1 sc (Initial[n+1]) dup sw pop 2 div neg 0 rm col0 sh gr +/Times-Roman ff 270.00 scf sf +9300 6540 m +gs 1 -1 sc (\(Recursion\)) dup sw pop 2 div neg 0 rm col0 sh gr +% Polyline +15.000 slw + [60] 0 sd +n 1905 6000 m 1800 6000 1800 6420 105 arcto 4 {pop} repeat + 1800 6525 3120 6525 105 arcto 4 {pop} repeat + 3225 6525 3225 6105 105 arcto 4 {pop} repeat + 3225 6000 1905 6000 105 arcto 4 {pop} repeat + cp gs col0 s gr [] 0 sd +% Polyline + [60] 0 sd +gs clippath +3865 5498 m 3806 5431 l 3688 5535 l 3808 5490 l 3747 5602 l cp +3184 5976 m 3243 6043 l 3361 5939 l 3242 5985 l 3302 5872 l cp +eoclip +n 3225 6000 m + 3825 5475 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 3302 5872 m 3242 5985 l 3361 5939 l 3302 5872 l cp gs 0.00 setgray ef gr col0 s +% arrowhead +n 3747 5602 m 3808 5490 l 3688 5535 l 3747 5602 l cp gs 0.00 setgray ef gr col0 s +% Polyline +n 4980 5775 m 4875 5775 4875 6270 105 arcto 4 {pop} repeat + 4875 6375 6870 6375 105 arcto 4 {pop} repeat + 6975 6375 6975 5880 105 arcto 4 {pop} repeat + 6975 5775 4980 5775 105 arcto 4 {pop} repeat + cp gs col0 s gr +% Polyline + [60] 0 sd +gs clippath +8457 5969 m 8515 5900 l 8394 5799 l 8458 5911 l 8337 5868 l cp +8042 5505 m 7984 5574 l 8105 5675 l 8042 5564 l 8162 5606 l cp +eoclip +n 8025 5550 m + 8475 5925 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 8162 5606 m 8042 5564 l 8105 5675 l 8162 5606 l cp gs 0.00 setgray ef gr col0 s +% arrowhead +n 8337 5868 m 8458 5911 l 8394 5799 l 8337 5868 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [60] 0 sd +n 8580 5850 m 8475 5850 8475 6570 105 arcto 4 {pop} repeat + 8475 6675 10020 6675 105 arcto 4 {pop} repeat + 10125 6675 10125 5955 105 arcto 4 {pop} repeat + 10125 5850 8580 5850 105 arcto 4 {pop} repeat + cp gs col0 s gr [] 0 sd +% Polyline +n 7155 3825 m 7050 3825 7050 4320 105 arcto 4 {pop} repeat + 7050 4425 9045 4425 105 arcto 4 {pop} repeat + 9150 4425 9150 3930 105 arcto 4 {pop} repeat + 9150 3825 7155 3825 105 arcto 4 {pop} repeat + cp gs col0 s gr +% Polyline +n 5055 2100 m 4950 2100 4950 2595 105 arcto 4 {pop} repeat + 4950 2700 6945 2700 105 arcto 4 {pop} repeat + 7050 2700 7050 2205 105 arcto 4 {pop} repeat + 7050 2100 5055 2100 105 arcto 4 {pop} repeat + cp gs col0 s gr +% Polyline +n 2730 3900 m 2625 3900 2625 4395 105 arcto 4 {pop} repeat + 2625 4500 4620 4500 105 arcto 4 {pop} repeat + 4725 4500 4725 4005 105 arcto 4 {pop} repeat + 4725 3900 2730 3900 105 arcto 4 {pop} repeat + cp gs col0 s gr +% Polyline + [60] 0 sd +n 8580 1875 m 8475 1875 8475 2295 105 arcto 4 {pop} repeat + 8475 2400 9645 2400 105 arcto 4 {pop} repeat + 9750 2400 9750 1980 105 arcto 4 {pop} repeat + 9750 1875 8580 1875 105 arcto 4 {pop} repeat + cp gs col0 s gr [] 0 sd +% Polyline + [60] 0 sd +gs clippath +8518 2419 m 8451 2358 l 8345 2474 l 8460 2416 l 8412 2534 l cp +8003 2848 m 8070 2909 l 8176 2793 l 8062 2852 l 8109 2733 l cp +eoclip +n 8047 2868 m + 8475 2400 l gs col0 s gr gr + [] 0 sd +% arrowhead +n 8109 2733 m 8062 2852 l 8176 2793 l 8109 2733 l cp gs 0.00 setgray ef gr col0 s +% arrowhead +n 8412 2534 m 8460 2416 l 8345 2474 l 8412 2534 l cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +3340 4475 m 3252 4494 l 3286 4648 l 3305 4522 l 3374 4629 l cp +eoclip +n 4875 6075 m 4874 6075 l 4872 6074 l 4868 6073 l 4861 6072 l 4852 6070 l + 4839 6067 l 4824 6064 l 4805 6059 l 4783 6054 l 4759 6048 l + 4731 6041 l 4701 6033 l 4669 6025 l 4635 6015 l 4600 6004 l + 4563 5993 l 4526 5981 l 4487 5967 l 4448 5953 l 4408 5937 l + 4367 5920 l 4326 5901 l 4284 5881 l 4241 5859 l 4198 5835 l + 4154 5809 l 4109 5781 l 4063 5749 l 4016 5715 l 3968 5678 l + 3920 5638 l 3872 5595 l 3825 5550 l 3780 5503 l 3737 5455 l + 3697 5407 l 3660 5359 l 3626 5312 l 3594 5266 l 3566 5221 l + 3540 5177 l 3516 5134 l 3494 5091 l 3474 5049 l 3455 5008 l + 3438 4967 l 3422 4927 l 3408 4888 l 3394 4849 l 3382 4812 l + 3371 4775 l 3360 4740 l 3350 4706 l 3342 4674 l 3334 4644 l + 3327 4616 l 3321 4592 l 3316 4570 l 3311 4551 l 3308 4536 l + 3305 4523 l 3303 4514 l + 3300 4500 l gs col0 s gr gr + +% arrowhead +0 slj +n 3374 4629 m 3305 4522 l 3286 4648 l 3374 4629 l cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +6943 6114 m 6978 6197 l 7123 6135 l 6995 6141 l 7087 6052 l cp +eoclip +n 8475 4500 m 8475 4501 l 8475 4503 l 8475 4508 l 8475 4515 l 8474 4525 l + 8474 4538 l 8473 4553 l 8472 4573 l 8470 4594 l 8468 4619 l + 8465 4646 l 8462 4675 l 8457 4706 l 8452 4739 l 8445 4773 l + 8437 4808 l 8427 4845 l 8416 4882 l 8403 4921 l 8388 4961 l + 8370 5002 l 8350 5045 l 8326 5090 l 8299 5137 l 8268 5186 l + 8232 5237 l 8192 5290 l 8148 5345 l 8100 5400 l 8057 5445 l + 8013 5490 l 7968 5533 l 7923 5573 l 7878 5612 l 7833 5649 l + 7789 5684 l 7745 5717 l 7701 5749 l 7658 5779 l 7615 5807 l + 7573 5834 l 7531 5861 l 7489 5886 l 7447 5910 l 7407 5933 l + 7366 5955 l 7327 5977 l 7288 5997 l 7250 6017 l 7214 6035 l + 7180 6052 l 7147 6068 l 7117 6083 l 7090 6096 l 7065 6108 l + 7043 6118 l 7025 6127 l 7010 6134 l 6998 6140 l 6989 6144 l + + 6975 6150 l gs col0 s gr gr + +% arrowhead +0 slj +n 7087 6052 m 6995 6141 l 7123 6135 l 7087 6052 l cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +8433 3848 m 8521 3831 l 8493 3676 l 8471 3803 l 8404 3693 l cp +eoclip +n 7050 2400 m 7051 2400 l 7054 2401 l 7058 2401 l 7066 2403 l 7076 2404 l + 7090 2407 l 7107 2410 l 7127 2414 l 7150 2418 l 7177 2424 l + 7206 2430 l 7238 2437 l 7271 2445 l 7306 2454 l 7343 2463 l + 7381 2474 l 7419 2486 l 7458 2499 l 7498 2513 l 7538 2528 l + 7579 2545 l 7621 2564 l 7663 2585 l 7706 2608 l 7750 2634 l + 7795 2662 l 7841 2694 l 7887 2728 l 7933 2766 l 7980 2807 l + 8025 2850 l 8068 2895 l 8109 2942 l 8147 2988 l 8181 3034 l + 8213 3080 l 8241 3125 l 8267 3169 l 8290 3212 l 8311 3254 l + 8330 3296 l 8347 3337 l 8362 3377 l 8376 3417 l 8389 3456 l + 8401 3494 l 8412 3532 l 8421 3569 l 8430 3604 l 8438 3637 l + 8445 3669 l 8451 3698 l 8457 3725 l 8461 3748 l 8465 3768 l + 8468 3785 l 8471 3799 l 8472 3809 l + 8475 3825 l gs col0 s gr gr + +% arrowhead +0 slj +n 8404 3693 m 8471 3803 l 8493 3676 l 8404 3693 l cp gs 0.00 setgray ef gr col0 s +% Polyline +2 slj +gs clippath +4970 2442 m 4959 2353 l 4803 2372 l 4928 2403 l 4814 2461 l cp +eoclip +n 3375 3900 m 3375 3899 l 3376 3897 l 3377 3892 l 3378 3886 l 3380 3876 l + 3383 3863 l 3386 3848 l 3391 3828 l 3396 3806 l 3402 3781 l + 3409 3753 l 3417 3722 l 3425 3689 l 3435 3655 l 3446 3619 l + 3457 3581 l 3469 3543 l 3483 3504 l 3497 3464 l 3513 3423 l + 3530 3383 l 3549 3341 l 3569 3299 l 3591 3257 l 3615 3214 l + 3641 3170 l 3669 3125 l 3701 3080 l 3735 3034 l 3772 2988 l + 3812 2941 l 3855 2895 l 3900 2850 l 3950 2804 l 4001 2762 l + 4052 2723 l 4102 2687 l 4152 2655 l 4201 2625 l 4248 2599 l + 4295 2576 l 4340 2555 l 4385 2536 l 4429 2519 l 4472 2504 l + 4515 2490 l 4557 2477 l 4598 2466 l 4638 2456 l 4677 2447 l + 4715 2439 l 4751 2432 l 4784 2426 l 4815 2420 l 4843 2415 l + 4868 2411 l 4890 2408 l 4908 2406 l 4922 2404 l 4933 2402 l + + 4950 2400 l gs col0 s gr gr + +% arrowhead +0 slj +n 4814 2461 m 4928 2403 l 4803 2372 l 4814 2461 l cp gs 0.00 setgray ef gr col0 s +/Times-Roman ff 360.00 scf sf +5925 6225 m +gs 1 -1 sc (Initial[n]) dup sw pop 2 div neg 0 rm col0 sh gr +/Times-Roman ff 360.00 scf sf +8100 4275 m +gs 1 -1 sc (Dispatching) dup sw pop 2 div neg 0 rm col0 sh gr +/Times-Roman ff 360.00 scf sf +3675 4350 m +gs 1 -1 sc (Prepared) dup sw pop 2 div neg 0 rm col0 sh gr +/Times-Roman ff 360.00 scf sf +5925 2550 m +gs 1 -1 sc (Polling) dup sw pop 2 div neg 0 rm col0 sh gr +/Times-Roman ff 270.00 scf sf +4050 3300 m +gs 1 -1 sc (query\(\)) col0 sh gr +/Times-Roman ff 270.00 scf sf +7800 3225 m +gs 1 -1 sc (check\(\)) dup sw pop neg 0 rm col0 sh gr +/Times-Roman ff 270.00 scf sf +2475 6375 m +gs 1 -1 sc (Working) dup sw pop 2 div neg 0 rm col0 sh gr +/Times-Roman ff 270.00 scf sf +3900 5400 m +gs 1 -1 sc (prepare\(\)) col0 sh gr +/Times-Roman ff 270.00 scf sf +8025 5325 m +gs 1 -1 sc (dispatch\(\)) dup sw pop neg 0 rm col0 sh gr +/Times-Roman ff 270.00 scf sf +9150 2250 m +gs 1 -1 sc (Working) dup sw pop 2 div neg 0 rm col0 sh gr +$F2psEnd +rs diff --git a/docs/reference/glib/mainloop-states.fig b/docs/reference/glib/mainloop-states.fig new file mode 100644 index 0000000..6acbedb --- /dev/null +++ b/docs/reference/glib/mainloop-states.fig @@ -0,0 +1,65 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 8625 6000 9975 6600 +4 1 0 50 0 0 18 0.0000 4 240 1290 9300 6225 Initial[n+1]\001 +4 1 0 50 0 0 18 0.0000 4 255 1335 9300 6540 (Recursion)\001 +-6 +2 4 1 2 0 7 50 0 -1 4.000 0 0 7 0 0 5 + 3225 6525 3225 6000 1800 6000 1800 6525 3225 6525 +2 1 1 2 0 7 50 0 -1 4.000 0 0 -1 1 1 2 + 1 1 2.00 90.00 120.00 + 1 1 2.00 90.00 120.00 + 3225 6000 3825 5475 +2 4 0 2 0 7 50 0 -1 0.000 0 0 7 0 0 5 + 6975 6375 6975 5775 4875 5775 4875 6375 6975 6375 +2 1 1 2 0 7 50 0 -1 4.000 0 0 -1 1 1 2 + 1 1 2.00 90.00 120.00 + 1 1 2.00 90.00 120.00 + 8025 5550 8475 5925 +2 4 1 2 0 7 50 0 -1 4.000 0 0 7 0 0 5 + 10125 6675 10125 5850 8475 5850 8475 6675 10125 6675 +2 4 0 2 0 7 50 0 -1 0.000 0 0 7 0 0 5 + 9150 4425 9150 3825 7050 3825 7050 4425 9150 4425 +2 4 0 2 0 7 50 0 -1 0.000 0 0 7 0 0 5 + 7050 2700 7050 2100 4950 2100 4950 2700 7050 2700 +2 4 0 2 0 7 50 0 -1 0.000 0 0 7 0 0 5 + 4725 4500 4725 3900 2625 3900 2625 4500 4725 4500 +2 4 1 2 0 7 50 0 -1 4.000 0 0 7 0 0 5 + 9750 2400 9750 1875 8475 1875 8475 2400 9750 2400 +2 1 1 2 0 7 50 0 -1 4.000 0 0 -1 1 1 2 + 1 1 2.00 90.00 120.00 + 1 1 2.00 90.00 120.00 + 8047 2868 8475 2400 +3 2 0 2 0 7 50 0 -1 0.000 0 1 0 3 + 1 1 2.00 90.00 120.00 + 4875 6075 3825 5550 3300 4500 + 0.000 -1.000 0.000 +3 2 0 2 0 7 50 0 -1 0.000 0 1 0 3 + 1 1 2.00 90.00 120.00 + 8475 4500 8100 5400 6975 6150 + 0.000 -1.000 0.000 +3 2 0 2 0 7 50 0 -1 0.000 0 1 0 3 + 1 1 2.00 90.00 120.00 + 7050 2400 8025 2850 8475 3825 + 0.000 -1.000 0.000 +3 2 0 2 0 7 50 0 -1 0.000 0 1 0 3 + 1 1 2.00 90.00 120.00 + 3375 3900 3900 2850 4950 2400 + 0.000 -1.000 0.000 +4 1 0 50 0 0 24 0.0000 4 315 1290 5925 6225 Initial[n]\001 +4 1 0 50 0 0 24 0.0000 4 330 1770 8100 4275 Dispatching\001 +4 1 0 50 0 0 24 0.0000 4 330 1320 3675 4350 Prepared\001 +4 1 0 50 0 0 24 0.0000 4 330 1050 5925 2550 Polling\001 +4 0 0 50 0 0 18 0.0000 4 255 825 4050 3300 query()\001 +4 2 0 50 0 0 18 0.0000 4 255 855 7800 3225 check()\001 +4 1 0 50 0 0 18 0.0000 4 255 990 2475 6375 Working\001 +4 0 0 50 0 0 18 0.0000 4 255 1050 3900 5400 prepare()\001 +4 2 0 50 0 0 18 0.0000 4 255 1140 8025 5325 dispatch()\001 +4 1 0 50 0 0 18 0.0000 4 255 990 9150 2250 Working\001 diff --git a/docs/reference/glib/mainloop-states.gif b/docs/reference/glib/mainloop-states.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ba1a8999c5ba981c58b7d53999c6f7c0f82cd49 GIT binary patch literal 7088 zcmZ?wbhEHb{K2Tg_?Us=|NsAMR;`&ca}EOo!`@wc&z?IgARwTipio>|eDB`9q|_us z1HE;^0#~c>Iar9EB#9MS)y4Op{J8WBDlXX5WJi6+U{iO?h1&-YMje zDt-V7~I;k)y{N7i2hag$FbE6w31W zh;g%PtUi8_WzpSx_a8ib^!UlsXU|_e+r0GTsXhi?=GWKdS>Fot9#*}1YcC@^`z1~p zj|~eB7BMi-*wwy}gPD_)&0w;?14WKD?H^w+FFkNzSMNU-9-kwn3Q`TMZ1*%hHY^lm z?O`xdttel}aF&b7DEEk{!qanHd^{RQzNYv#vNG?nkl0yr)0**;tNc6@I1%KC88E#P;_8cIrFqjB^UA-yct|OWG1SM-MD#3 z>_nB+QpTso4E|LC1_lcmQdLA%{>{DceQCm(j@nEf+bW?m+yT-yJvS1bh@M|yx&7Q3 z$+9M|X@+}vc~_St-k<0f{a|)D)8vIhBI@h^8m%~bw^;mGjgrUvH(QI!J@0-g#5!fYH|91c^zOEied z`h2>`s&q>8r04XRs*f2Mxp)#9RHY+2UCN6mbRL&(mr+ww;>>YtoHNJp%Mv@u9XHR& z*W8=_<7CGR+9Hn)Dp-Cs=l(?;Trs-qv zi(4P7L@}0Jxx!o}CUBl%#tj87#$dNiHyJZilpM^33zSdA^SG~fKML|JEJlkDy_ zn;2BO9eQVpImHP0%NgXX3>+pOoZ~*(JkU*%n8a|z zIzw%1YwQo64>3#M3LMvpd;4dDyI{ki31^R9mYi^GVa1mPX-7rtSA1mPH`(KMQ7&Cb zQ^1Gk!HYDHzybv9>x-IcGDzVfW7n1N1^>*q6V=eb09zs%(@dbol?MEd*3d5ZN) za~9|&=WgHiYS+rpSkwI*V)t+~taX$9lPPv(e|r4#&{HR4F{^%{#S9ZnQ=zW>8;G8)p2Sw;_qFzG^sFceqUhbTDUcNSmTn+{WCWQnp zgHSe>xt?MY+<`n99%iDO9Q1YHu-D&8vJtybz!Uj$D&I~v=C5m8*iLXK)!tIt)+6(Q zKkBFWKjw8AP0FX8{ zChUmB4NW2bl3T*r0?Q=dY@ARTb4B3k2_~0WPist0crkzAXtGxOB>tZvQKHJ}WD?8L zegg@m&n^>0<>NMqep_@-!fMj7_?DI)3yae#-V>&NoO?-h{hKGe{{$yA|M)ch08g5e z-*GP?gAdbO0#&7X#LlEyeV+L+BbB%6kVnd^B)u)0)DDP!VDM_YIOUcKtLfoN4*81p z9NYy57#%#%`FXU?eS3zvqh~q8r!|`M)@_)+^F!ovA*Q4Ho;%g;y$z>F@?8;_rkJcC zyTBn+E<|A3%4g31o(ml1^zcXxne#$T$JncvZP6kbTLvlHRh{!nrYvbt2sgiM5;Vn& zNlU%-rTm2FZZn;jmYKP_xE6PDtosnM-0oMVqJ>t-0gx4!VQ=K(8N44K9_$ttN`Du8ez_pEWOw-c-9tyj>YVG!oU%97kd>Z{(;QG#2 z4s$v6XD~C|Rfn$pdZ~G-4 z)4EgP7WqSp>Ey03)|Rt}k8=D|h&Uo~K&jK|Q2e}-r6D$+iswzw1$+{6RGV^RnrD=Oq4c^I`?QT8yZpq$xiv6s&UWfiN zQfGB!)U8`u#_)gF0aa-SUBORTimBJk4)E%UG3fNLJokCP&~f+;`_DeC2!Uit$WsA-++o&+i&V4C#WJyD9U)R0`9Uc;r3ns|Te|_lHP3M?dU+xO; z*m^|n0aH=Gz>Mox()xEky(9W=6YKmHFLwKG6L6kuHbu!~0RykmP41IAjfU%s9h?jT zcrJ!8GTkv}{onA3eSy_I-W*NIccB}@C4~M>QT%h`)Yq#S<*FBK#cMpz%LFh)xw6f6 zI4q>B)N;Jh+&1uEOZr~rAIeKsJ`omOz;4ob&OlILu9Bh+`wSiDYl=Ihw)49d03PE?ECeGypy>Sn*TDUZt(Z4v zV;(Pd`*D(UqO`~Iyr;_Bw?;BQD44-~sM{vA_w0LS&wtn7RX=a7_}Mg{{fpC+tb^|Q zyA&igd_43o=B2>fpDCGqrA{1wcWAA*Qke8Esyo|Oz(;-k$^CL28+VsIN?~uA;1PX! z%lCuXF&0}dzkFL}w1Pc?ck%9!!kBXVBYYez3hN>Z@0E+YM00F>nz@bpJiDiN%b`qG zi^o4FB*?y=`hN2B!?VQoLJpK!bwhvc8%34h zx7Po=_~glzQ~j4%&mBI*yG3>R^UYBimrh8}+;M)#lJ%Sa%vDKAg6`Bt%~3&(D274h#0XhWEVq^w7#s=+*D2C9n1ghJ=AruTi51Hj8d@LL&r)i5=hE=zLfx*0D$WxPE{cuw7L*@JXk6mhxNSj0 zb3@~S2aWp`8y!X2=3SETEoYL^;81wMt^Gsz=0la$>Oq@=8KacgUR{(mJ>hcfLeriD z&C-JMO`jCm1VT+0cu!fZEp>v^ZUwh@g#5zIrqdQ0?Rv!MF5!OsLd%YZ)?*AU28@ay z(wPDrTcbFbG&^{<3&dy|v>iFndR0;I>Z0gRlWpWSvu~Uvl(m_!@v+DeHr2uvqNb_} zN-id|KWYgFv~S)dDcz#IAgnE`oymYB-t}>V=?4|>6>WN-T9zmBr(D$2+|1@L#QLxC z2t&G2OMPPw!vZ;BMGY6FuJa30&t5PvY}9^}qg7 zC77mh@Z@wbG6k8xGOAK8Hd?vEw#-@Y{6aY~MwXmU#<|Cg3?|FGb~J9D+A{k=x9A7; zN`oG8Mw8khKH)lVoQT>g5R4(znrs@Cpxj#$ol(a+ptZR zbA|u)TxIN=bzoxrLU}O}e%1}{I)XxWf?bO>N|tqWEti;D<~X&%u*D=$&v>HEvb4#$ zOu~)}v+_QPUpM2)J0!j`KyT(_HT#0}+dKO0clJMV%6-0cV$FkYmC0&1n&q+`iu^Yi zIWf8Yv6vFh#L#iGFThabR0Y$~AKWizC}~XW{}CYh^D^J{VpZ-=)4WMGDl4O^S5BYL zDIPCj8LlzG_p`}v=jwo_hz}jTpEYtWXfSS(WchrE<$XkF#!SW|8zqgOMgP_)sYzsQ z2-oE{&==gO<~&7wyJBm3Nwgr7@j=NsyOULaA7=Rbxp)1{w!072{FQ9^XO{2Y+3w;w zahm0v6@~hO{}$!!$#m2)G!Z_cm1WGO(4?Ii#`%ANO}Su)(nk@W#RBpsQ@`DGjQilo zYvknM(DLEnlx2z&W~$2mFiQB9p?`iyKVMVNyUeH$nan1hO+k+oEvF=jXmR?j?0eW4 z-9LHyW20FmH)jYji1s83pWPs-dP_|?irID-vu6t9nP;=CGZqTp%=)xVRIx{z^i5)(@w6ksfuZtjh0(rNwS$tZtgii+G)1r6t7}AL#CS z!D1h0*d*BI?<%Wp zXmD6uwQc&^Tf5fYxwUq^_}U{0Ytufgs$*EUBwhKNyOe49In;nfI<;=$#oEW= z>%V!`9adZK@VVxZdG_~T>lYQ&225YGTtw*4vh@iL8>X`;&F$JyvS34}3YW_B4J8U$ zX;U>Wx@{~Ks3>+7+i_`wlsB8q?=Z&+35we6?~jEAzA%*wUZZa99JR_fY^5>lqfPqV zO@`UNXG#rUS8YxZh^=y6Yp2aN?fbtl2kR}#3R`ko%RIQ*0;Wc!UEdOKu&H(Fl%Q_r z#OV={pX3yx!v)zt#`>D*uveGz2Y}x3wNsim0eq!cP=#Dxk=kT%(^7^ z_O4Z{)3<5w77W~0th#P{H@~HJ$bRcxlGz3I+^HEwlGhv}YqrK{d`n!=7VjUHG-*0N z$F#^0r_}4OS$1ddIv$=Bp<%ZCVElx{$ZraJCjU##`*D@e%5mMh6O4)*S6LWxt+>hf z@>Su%?s(sYYM~27qZ>p@wRYo-$QNomrv!?Kc$~BZ2u}M*e~4H!Ip5w zaDoiOVe9RC8W!veQc`-yDwRCVcg;3Y0jC_ z>>Wer8tN_Q5ZJiT?`o4+z@Eetg^6bvvpd=3Uxt)8{bA&IW0I|q9Hhvgzsx3RLOa(S z8|MYbgD)OeGd!qtDY6Z^omS?N)ll8M%%PYfSFFl@bQBD~OVhmmQfn|5AU z+K#3){|BrkVLA$@Pa5VFh}KMAD<<8O;1x${5DTPIx$~#aTnsR;rg+GV= z8p1sPDC%rHw)b>aV2xQsR{qa4#?;AWi$f>py76CHnAK2t?0SLplRd1z_OKV6$?ROb zoTXeNb!wS&)#Qmb5+{suj+U|V`sV0|r!H4Z=@Ym(`^=8B%En0>!t%bKIdS5&`6||I zw<4F#Jm3GEK6N?Qd{^#?iDz6koDqG@mJs0GW8T#0l&SsTY;mgORqlVqj*O9V9jzbk zoUyqY(vvP}6MRLt;DWvG!k+fa<+B&cJ-BGL{L1|8p~03i9=3Y%x@AFsD-%QaeOh&O zzBt2E^W!4j*Ls%QnN4HJICSmTt83nS9Rv?4m(;Ga2-STf74BKc%d_?RO!un|jhv;k zv*R|asVqOSgnhl}1ruI@E9&gQ0gM`bXDfbP(Vl-a>S%Cz&f$#IM88&dJv&RelaGz3 z@RrUCE*A{VmzyZQ@pI{)#K=g&Yagy%ml7yXezLDB?bcjTq2t!!L5%gP6aCV3uk;m^PW*i7t#yN{8nLuXMT}Wqz-?@UHa*W`S30Ip#g!dbf75 zl=p$Ad*;7#-uPN`vpkg9*29$#rY={v<5;^e|zD=)#&9vwh6YDRqVnyYxJEs~os5=9l%Y z;GoEdniF?;1veYyyXYz~cbjwRGArqZ=RLi4NrzEdE{4yL%a~g@k7JpQnQY+^qlWDZ z1-I68A3kn8xiZkh|3Y@!zo*p#&v+gi9Cdn{Zues1;-`jz&zjCX-!pUl1_kYpMQkNc zp6%VG_%CXQhwnVbvSXJvM(a$kV_P}tS>pkzmoAs%1zs+YJHD{7byCSIwFfF17X=ey zxESI%zN!d5e!VKwC_X(?(ffqvV)mCxPXyP<`3Jaex6);QmAr1U^UFRCt$Vr5)nDES zhniF-ik@;|&ub9U*|PG}#wI)Em*oq#tSfkJt12S9@QsmnJNXY!JQ7QU`v*tq-_ z*Kf-=yIE|{c=f~=yb(R{UVMRaT0>*{l*b7MukTzGxc%;VE8mOgID^i0A0p3vXn*%1 zZeG;nwZZ&f7+%|*i)B%jp3i96!KgT&G2)Qc|Ba00U8_z=Fr}w_INL1fA|y~d&w$(i z*&l{l{?8vwY27B@im+xCwmF0)7d!Q-hym`+iro5yM9n+429qmyL9exug znHSnm(C?TwdHJGdp}v6c6B;4~n%I7Q;Jf2JCpjnSuv5m2uLgDfL4UN)O?#=gO`|(; z=d8^)_@ZC7t-8s#l|z5~4(mI8Hn9fZ4l1^l)%3l+BcLsxeJ^{7-`1~dl@_1!FyA$Q zRyp(X+vmSBADgWtc%xmPJv>GA%RlQMZ<_vHJfHQP|L=;v$V(UR$1D8sefdKqa|+Kx zwVf-ij^u0J-2YdA;mMM#d;vUCe+9Hf+&7u{Z+XR#BruJSk%gK0LEpA?)p_4yUq4;^ zCS>|$y@?*CbI&gqv|1YGd+F6Hc9Sf|IL;ZZ0u5(_)<^irW(crYI9}Xv?QPiGhLf8t z8-(|BHZwIG*f4+5-f4>kbk+z=us(Ux&Fi%H#N#VBuT|2UD%;N1x*11TB2Vp6I^uk%v&rc0y68T>hmGygZc!;dXH(LaKV5M-DD>sa*{vb3-sEh3zU*Dv z2Yr#~_}D^DCbnh!?|dsReq1qS>4&P{)#;voZ%zK0%w|fuvCrl3vA5^UYc>n;l^lO} zcP9(`Dbp$6H!N}$oXDUs!E})$d(hz&TZw|REX

#XNj&7~OFauDd0oQjx&G%)q!p zH6!!@W0Mr$w>OJBPx1Lo|8?xFprEzg*e;{Mc6^@3d zoDGUnBHp*AiCya9@F=U8@L+LwudI}cMu9lvWCk;Fkr&d&v1X8adsem|HomoLYRBcNzY!wN^6=DMnh41IkPyYtS>{kV)} z-Vzm-12dV{&Am7Mt!(%_&UdqX&n{I?u2Vh9Vxi7AV^5;Pntx5UN-`a#?v4xvpTuh1 zX4b8*s?PPiC*K^u|6I*Sj>)qhIILjk`79%_Zh{7pAouqq(*lh-j-ITx*#{YJ1Y|$l z%;I!9VFs&(>6aTK4ZnKsc$?j3h}9C}XxJPk#ZfeE>O2L9JMlCB==80$NGX?N&5=q= zXyP{ekR*~2yZO5>ue&LOr<^9v)Ms2o3>=nowdo3Co=VhmK#Ibnm|G25;IW?nO;?g7dy4L%iQ!kr63i@C2Q!`#jbR< z^}McpRu_x%J%O?-r=!bjW7-&AJiO>QaRGlgmyE*7b*l|bpG$A6RsB}_sC)T?h7Vf` z6ug|wtQu?t%4A)YW5Z4tCC?CHx3p)Qnwi5qB$!0l&iPz1Rdu|;J*QLhr;fzN z{1XR5t1{!V#Tb|vZ#-dGdhsrU+ly6F4bPiXKOADVE0VervVv{X4Y6F7AKSQ}1+=F* zaolRqan$nBSWv0LagVRJ!sYv%2a*0k(^8&nSYWTi$ww=%q`F!@+t_XQT2PSf#eoKo0(Ox% ni?{sS(dyu**;M(Gf%)$Z2Twe*HRCOyoeWoceF<1ith%ZDq literal 0 HcmV?d00001 diff --git a/docs/reference/glib/mainloop-states.png b/docs/reference/glib/mainloop-states.png new file mode 100644 index 0000000000000000000000000000000000000000..4e9fc9d9a46d128af43a962b5f9ca1535305c8dd GIT binary patch literal 15258 zcmeAS@N?(olHy`uVBq!ia0y~yVEnQK$!8;-MT*v3=Hfgp1!W^7r12wAC3rZR6gW2R`J?!XO@X87Oh;3)7>;kWzhzKqx}^>3wZm2aF1d?CodV@l7z%5Nfp2c@F0?ku?Ud%ITOZ2i{xau%e)uanS1+-K*F3NGymCN@-Lg%x>vrCy35HrYq@WEZgG=S|Cw`FpHBU~%~7m3 z_cqVrnAkYiyAzHCtPJB&j9qLk!L!RPJVKm9QDMQh+}-nMeGqKhzjUt9+pA|Ut0}td zzNmGT>##wA4oB_hEt+e%H>|F_l_Jq*$FN13*N-J#r6pvQsQ>C0FYoLYW8tzjvX(ji zFv2cni*)bf9V?-_= zjqJ_UQ<86Qt6t*Iv2Z>2g5O{ASH1bb!TB$nztO4x42PCq$b-+Ns}v1pWV1ChzOe3D z=6m^z#K8qT4Ck4D72XJ7e*7_UbHDow_jjK-_Wsv5;(yWOn)YN@ajb^eqP(M8K^kIV zHV0mY{+;^&P__T}Uw`WoS8tekyQRNHpz^--&KvK)zr4RlVV8a1lKb!XSNuFwZ>;gh zHZFIi+j)a3wuoxCMRPP6mnFF^bQegOc~bmy%Y?GkvG+8Eohs&?PceQQCS5ZBP~jZw zw6@1PPF^+hpZzwhy6uDeyyx6Un_?!LFX??2Ssb&`f4)8IjJ==an^ti+3aGSg(BY2a zzxbtP!ttZW_x9VK|DCZgVn;?S2S4ky)TguF+{})gmTn|+dehm>&-kP5JDM!6im>lp ze1Ctr{R)Q4`42ik$((VY?|&ODyQ+{H7yD=3l@fP%XUdpIwD~T-Z18$2m*EZn7iD`F z9}ZF5skZsd^vZ}+Gn2mX+~6ygeel#_-AT9e8+5qK4!S*)PWye*Z0<5`t|X4j$^~gU zM#=}z-EscY9By~9<6-ddO77)V%R?+F8T0J3+@WUB^iB z!a;`V!863Br7oSL@^s1X@9)CDuP*XEW@y3WIeT&5QKrhmKT0=NXvthup1i>>`eljK zrL)@UUM-K~C0_oHjN*u7omMR=ws$f6?06RUFDGObZWR_eiRF{DqzW{+ylPYfZhI@Hv0}x%*#!*H*^o$(XLwTYqnV_4{*m zOUu9TW;P2L{g^d*nqMK$Oz(9kv%F(j>zhHf(Wc*7uXpX6 zd3R2MM^nUuY%dE>qlrrrW<9(5G<0dyN%7AmKX?``yPGjHr|q%DiAS+3!^E~EFxhI> zT*)(uSk#!tU%pVG zwI`o7;5lsIvv0=w5be{`k4p$~3p?H6Y!L+IE5$1Jd>M1DXx4epFTeb9@+PNZit+B1 z+pZo=m~b+UFJ3Nf)67qKKMOw^@~m{q2u)ng(41;9H*?mPJq8Pk`5!7yJ{huX38!0s z;qHVV@4xJKsXX*UJ8C=Q5~my)^DlkxEc%vZ8|;~yZN%&CyX&{qt{AJiYAq?7WmO%=F>p~AFH{1iE=MLH9GBgvgo^8Z*OuE6bu zLJvAO=ILHGx%~3W?9b+BFE9HL5b^H7DObU*Z#g0@w&j}p&rUchcCGbSU~L8G7RiV$ zy>(8E8>aHhtFGY|)|#1kx`6Taw$@TcsR<|3?$kA1nDO~kd2im*sD~DPi4wa4vTPbx z`-)!_yT0(Y7e>HebrlrqD-X zU3>J+@0%oY?Y?*M@&9$kJZFTr>3Cl@otC)J-r?Do6|dnd5)$iN>IcMVgHOTi=iqotMX-%F_9^7o)pcjz4N$2&4_3caN zURo6DAaca~dH%hBU&Q9j|DeC~=GGODR_9)QX)S%JO{3$~Orh2JEK&M3+J82Dbv~2p zyHV{`IG2jYI=%G@XVwL+)w#851IJ}vQ^UYxa}RBMd&!UUTG%s-bFpVke4{*y8zJ~tH%sxW)1QZxahAb8ms2FeM2>#SvwUK?T_E525ZAIO)_@nnJu#CNi`Q4JWShsz z`BCBh>A!XR@4v6!X5J_5ZQ0uX{O7Sk<|lS@{ic_nUbuIw$TqG++nJ7?X6N9lRcd@t zuJ!Ts+>`oh4Xpbo=wB#(bKs@#v|DvYH|d2zMJa?(tX}(0x?R6pA z0)m32(fb;{*Zgq#SCc!>OtDnT_pg{p`1J6`>zxc4yFA&lyhU9v?%K+8xTAj|L(syb zT5qa$7RoH&AiDAQ_C3*NzLTH-NVt4XBmLC3ci%Q}vv9Vpm~V1I_Qtlk`p+cWI`4!T z3vr|!FRbOrFqcx%?bxLl-%#G|(Dv=aGyzY$PEp3mvyMvbT`azh%OFvG-oms~GdIor zz3G%t+g}~N4-Dq#XMNmxBFN8($NAp$%P+T7tvn|z_~GSeb>HigX80>15t= zeAV<JMi4qnQ+=aSgCc8T7u@{FP-zm;@rvClk4`^ zU)&XNPGriD2?tlqJ`r$k%3Jl@XD_R*ve|UxfR@ss?N0BX-#hr<@<72R4~K>QY$25? zr3<3^vpZc_xoTNn$ksmAmtOJd#H)rVdEJb~{L+ilMYeIR_;kX{@$J`#YXVy<92WA6 zN+maI^{1)d@8!)rylKsf+nbyobl9nIMYFagepo8%$e~!|d(C>+vTO@c8<~I?hZ%O8 zHdP#0=s#n@%e03Y>0L$ZR^*;ZZdTZT(I)qmtZb{DOo7Y(hznm^6doVgt!z@@vftqV zWA%qO48ILGSxhlbJ-5fO_i@{l$w4cx>|mOfdN3%U%ALQ!S0hm1wDr@sm&yV}l^!1u z{L7^Ie%kN9`>Hy-mnwFvPM!7L&8+Ge^T&fHyn5z+{I-0%$?jG6F6y4D#r|CgoqQjGDh@EkC7Ul_H{Nj}TvPv{Dwquv*=44PKWNO*sSWv%7>`A!+Pq6)}!}n+AwEc5v5x8vf z@cpkq*>|tkT|Ap&{H`~k&PjD!?({ORZMnP8TdY$(ShscE#Z-y5I&PJSfEUciOnjX@ zuD@`*J3;cL)LpNwO!e93QJ=R+=2i=sKXyx-_x8iaptTilr5{fFtyr=p_>;%l^TupW z;1*D0csCClv&mf+pUUkqE5jy9`@j6QhxJ{Vv(vII!A1Aqmb-2H^82s2etgU2ZHavI zWM9b2?%mYQ&}!##Wm;D4wmXVkg$D{{<|o;{spP))w(Sh(VS{%DW&M@45_=c#uCKaq zfpe+}sQYsJugwDsy)AE&bxxc0NoA~z=Lp>Er6a#Bw^&AeN9^s-Om-4HUe>C=4ySIC z{Qf?|epRsyd-MT+hL3Y^^@gnslW5DFXSQ&z%<;yB-(G#vntZk)(rohC4D(sb8Lyn{ zcJa$xuCj(ZA$Fzw)s?LidW`Nih)%q9=e2w3i#e0EckbHL#OHk8;?7dv%RG17{2yBI z@wPQKJIPB-%~CD!T@#|6*KN6XzWco!kLTn+S$)32>ZZe&hl?|3ePOMCa(DNRXsMZE zx3@jK_)ad!;rI#h&#{ZMXQ}n@IB3sa?pyI;_i6rcrpF9U9!sMdZ@rk|u=}FTH+hZy z7RkS^J{3J)$i1p2)o~#|o5W)lIpYT}KTdAFxBv6mZMkiU3GZ7PAGY+Kc=e$3aHB3a zulb1-V~Z91Vp}eGoO}v+B((XO5KkiiaXaOtFTD9 z_a2_!{$+8|vYP)Nez$&``F!hh!Cx)Yg+zWa7*x6KzM3bas}gxUWZi~|=eAFLV|#b^ z-n~<^Kb7Ffp>232h5KX=Ee`kwOCIh@4ySfTS(Xwu9RDaKbO z$?5z|ns<$7n&gk!=PDZ|^->mn?%k1gc}FAj-Q8`r`P`+u6;D{qT7K5$yj731#+T2F z?q*!sC}|P9nERZ`jDsGn`@r4$nz;{^)^H1`8NR70P7jq{cjs}C^tU~_SKhWM2tTmM zvtZ+y$?Fqrqo1f2DLb?G+NL!(YnZdV-&)t6&#tK4e#au~Lcp(2d6n;9%1M2k_#soq z+^*(NL*zbY#@0H$gie{uCWlW3S=Qew?0Rg`uFu~--~Zj)1eMq=j$)2(k1WpJx-~0v zR^xGtH3}MEiUUCviuAbxxnF<(><@puBk=BeuGdYs!rbpU^*z>j-Zf?Nul?T)8P$ap z6Ys^J=H>ePCSuxDzva2N`4TPkpDy|S{+_T?OX4 zDa+p{2uL*P@XdREbz4{5B1^}G^97F=UV6DDQ6j^^Wx~Kb2yKX3c`?P7mF$ci-rvv>M_Iew0LR^Bq^&-n@-Dhu|O$Q8KQ z%f1b(7S#4s%dRQHYWV4umu^|vHu|L%Kd^4#unu|!(#tNwBKzTH3FS79omCU<=p zZ{-T8X!XnsJRxpy@Mg|~jykR{<-0cYW%3KCFu6Fs`Tkqu%jQNWd)Di7vwNPnPFUe! z{P)a)3;vDwE*fqSa$Ll8_KR_|(|hp~`OTFZ1y!^PThV&?x7)$n})x z&!o6}(>WFW?*II3Uf;LN)srdrOL;R}6-y^`-{U2hGrtDa7XEou`PS0y;7@jUm=w4G ze0ulO@ACJp?M_$DdJ1Vkr8uA7HLCAVmuO49x#IRDm4FxT*?7Nj2+2zw=ao6<&wcB~ zdj{Sw9&-ZEP3gXN^mqCD#d#hpN_yWhe{{5Xek#Sdzq|kR?xzKQ+Z762>e=`9+a}7k z^LxB8sA|*b5MSGU{OIv*x%^?AfdYpuC+6Pn@9x)+5?`d?v~6`ulkzX?3E4)9OA7CF z>{8_TBrQ-MbWbz+JP-R$HSOnJnX@>*@-Db=zj4asX%CL_Mj9<})=Kxf!W*e5RC{)^ z;+JWuFJ=E;e(wKpew1anNo@7+%eO!H%SwHJe|LJ3(7HKOMRZPkEx)`iSG}ZUW`NM% zNf~!?zw|wxQhxen$**5`OI3Ice2aI6&J!s5`_2m7W}m@eCip_uHvY`wQ|&ybH~mbq zTgdq_dG70DFC?Wex$T?LU-n@WS6aaF!Y8$sbN#Y+wM}MAI=B4%{0hCw=2NN-&wqHl z;rc9`z3{$X?&95=G7-~4&xuS+-0pq5vro@KAZ5mnS$R{8TYt7WPUW9`tg!iKo9Bw% zoQ@L;kA%Nabg+08wnj$4RHjs0fQ56?53awz%in)KT61M>gypBBe^&W!cA2nLeV>y* z$H5&<9}Z^sDV%m+0~#W}Ai!$aCd}MBuWUGiKDIdgYQI8_-&t)DZo6#mwNE)&Tjd`EX)1S`jS+`(< z<3jfdQ=LUzF8q2`XZqx4;i;LQR{hgDW30r|YWMPm?A(0|l{@NP9M^w z-}`gdabNOjOqDOX7ihiXR?z9)snb$rk54QTn(@yztZ1iNcN0hZWfQO7$H%@+&UNC* z`97yR^=62cD%YZ0LG98y*Hh*_Uuc-;e74~9-LuW>A6OoFA=$c?Y0JV5p%I;uO%I>E zpWn!EJ8f3l-xYR$?i%0pSsLZ}ZV~SnZ`SDCIn}I25JlHNcb;lr_4>SpGhMyqNq6N9>pMkn-J01Y=3Lp9 zo6+!G;77*oZPlCjY7TP#*#D_edEfRgN?*FKaqbn~rF_`n!tBW$Tz|QQrd-&~ePi2O z%{Mq~MulKP<>)J!EuNM{GnPHRu_1m{;0zzpbHJ{g< zG&nQ+v-yXfOc`^DG}cW|-2QqQPCIbh?9=ZhK zP`K@Z<{PnigMPF-QA22=hJ&kAx>DX#cXIful?ZMt9<#5ySa}&7H;`> z?($E|>wgwpI4)yf^mv~gt zb!mPfs5ftRxF&M``QVCMmwoNR16b;wPE2SF*qHIRz57MQ!-OwA+wJ$-R+L@%eWO{| z@BYsZpV^rIc@t;+EHM>MtavC{n^V-Zd&tOPg{ih)K4RIr--i~PMvfJ|6ub<_PAwbt&!fc zi2CKiP6=D17pH%zdue#zz;Q0$Js;gf9!X#)bZX==Zy4YH)%Qf zFTHR+TU__d=bEKaFTekmzQopZ>T93g`_sM3`Kk*0rlrdM`)Uw>#`%rG=?yIt?j4_Z z(OBmA#B3u8J=>R?|IW|LPwy8{dS5@Y#Ywb2H&?fF{bUa(&vyry+Pqq88lU-Y*3sU{ zHdC|XnCXLNhTCRuW=MToQE_U=<*J^~A{Wahz1$mQJiqVPCItcEe=Fp#s#o_cS30+s zNwVhc>cF|Slh0nTN%HjJc(L!RTiZQfh4?eSKi)hx;m5AKlO756T+>ed(sST>xBAml z>vg83F1?(2dz*6nzQdbz+7gxW-7GBnHgDUOHY-iYHs#~qrIVG+Px9JJxCgEKqs6@K z;8c$#a?(PzXANJmIZkqayker?@<_JNvaKyKlW(szoBMf&Mbg`z-u>s*|LM+|_Vl-# zH|Ob1v(~+ojXmXg>gHX>2PbkY`WDa84D!1K8dNxG8gw-Lh4D?F-Bmh5_6o8A{f6=y``f`=>uBXf{lt4T+GquJd6ozs`Be=R>h-^t?o!OhH1V}AZ#U(f$A#_-|4y}yI} zydIedq?md>4C&WA`1+~q`xmWin-V27YB+@a170jw-S=>6AmciZ%J{xriX2S}2OFH; zKYhRd-`+jJW_4y6b=EA7kDBjYY@goYq}J^8{^$$I`?bI47A?zppQnG;M1v(#Z2`yC zE(Qi^ZqQnQAJrLQbNNK7^sl9Nr{3t@pW|Vf`TJzqm9vflEHlMLs`R&S-!5H$Q=!Gg ze|D9-|EVi6ERlje^BNrwTyApuZ{0JGv0JO8H*fbZ1%>KO_G0QtC9p& z;`Y>kkE_sdx!cv!=wvSzD6ro8df;{@#|if%X0^&Yv9;Fe^w-t2Y@Es=q`l_67~k`B zhSoZrMGD`3*T%FmJ3eZ@csQqdbAyw8XN}?iZ_BrX_3GFB_yLNE!0k$v3oiI48E@~r zCe6~xf9(9pxFyzF25UddE(y}SZ1OQz&{64l;he2oO{c7pJRta2_DOf8%oSx1nG5${ z&dgDJ6{aF2^2_?hnY_6DhZVe8I_JGUXL>6)joH_{oFTt^TW<0Ty(Sm#^PjV#UDwWM zl(~4H5!86ycQ?!Zt^iA9X3xBf@4p8=O=oWXmuI$lw)%R1a8Jyn%Kg0f=fLesD;He2 z@4Iit_B`Fwn-=A9G_BFgudmuY^LEcJQBT&^e|ZP0nzLJ#JwhU;rQVHdO;UW-rXng* z6`%9$LRGWE#D&{Jw%k6$%(YiPL8FoJD~AxL`g;EhdB*%2U+OePxW(6YuZV6`&}Qe^ z01}jNe=mM|)1{XtY*&;$PE093t#jC{PdddzvQfGmb&;yKN z3JYGQaeXWMc0sjUA+hMwuO(Z8ouM)BTSvUY6W4DA+i$ z@}S_~k~g+@t3Q5ny|UI}!qf*Jo+j>_;XZY~yv#*^UQj<(>FE-%CLW&Wrm=_rn0;<` zvNt_7v*_Zk12d{vA~lM9%YOA0Epxd$A(f%EPOKoHUxAyoDYu|-`vQlB^I2uCD4%fB z%n_~VJAUIQNJJ1M(saSPDsgqfEH$@KHdeR0XHI-hKVSGvM98knUH|>Gl}uet63Yr7 zpF7x_8kyyN)%uss&A8LMpB@Wj4z+VAaIv?xId5P8O(yx(#0ia0bswJ7%@LJ3&UvBh zg~hp)R^O$^y4o%pgC=C&=vKLJ*U4_%?F^dtcG#V?p0^FxJl=D z;j!8|3_LNG%M{2uj4eC+uOXY zRd=LIwl!LBue`OSo}aDRYpc>4?tleBYkAn1-?}NcTzCtr!1YA(=9y)-21uL=h|HL0 zmgucETksldm4af+yG6(O*qVLJ7T?X7mzKUs^8bCoTb7?yozxnf?DeN+rLMX+N5SXv zo?Uw`mAU#E*ZJy!evlr|h$lbis|LTiCTVmU6+oH!FTcmpvC1i|sIYfR{Zp@wic*nC$ z<5z7gKG$CaZM=}T<>~LHlTD8;zPoQ%y1d``CeQK0d5K$htL$mm^}Vb&@ADSRpclvY zzN_BWZ}aV(myOPAUlI9$7t9Q7$_6u{q>OI%{FV+~HC6R@)5)Ycdv^WbmTNuvY{SM@ zzTV@qEAD1|U2G-N9RsRrGM7JDu3{wpqKB73Q{59(On%F0?=PNi+4uN(@3Z^2pY1>A zAd~IUV8E07rN_GarR?8VpHBVC@x0XWK=OE@MW1qu!-K^!lht?FO12dqKXkvctnabT z>0O&!51%mI`9FJqVawzManCFMvs4qGm7gzsXH>E9THY3~t%nSJK5vP%Uv)Uvi(}!m zYb*EU+P#)xc^Ki`#CqoShoGn1F7n4LPP_Ft=k~H=g+Goy%+K1rUjFJzN10s{mK*%2 zYb|9wb*2ARUizBdiC>a4mp}RVbjGsE<-KzE+A^P>XmVJ{-!pTsXG+iRp1ke3yR%DH zo@-)1^Hyf|soT$%pR<(B_IMDmndf-n)U4LW76SLZwmQ}C@G+aL|BO>{X3nv-rwbGm zTV}Z@#5i%B6#x9;27_<=tplGP+bO@5_z(gf{PaG3nAvUjMVn{hZ{1Fde-_>+V#9gC zM4n0Gi=$C=jfCW5z2f|K>r=hfYm%NkJiwAa`@EI=HsQ_*E9a;t{>xfAchc_MrE@Q} zEZmiQ`_L|j-7=d33es{8fU4&uD>uEXTqbp?|J_^RqT+t*nD;N-&TEKp+nhfi`Mjmq z;|%BL@M4+gAD$|f)V&B74pNv>etKGJ;;QBXhxD8SD{@0E!_(gFyAo^GbMNBax+@cx z&p374Y~i_?ve_rJ4sUvMaC7sq!ox2lZO;1#RPI#!UiWV0^v&va&dZou?Gh^H<;$2V zT%GcN@rpxo`)qVX>Swq4T`hb6^4{CGYxn3oZ|!~Dc3EEW!k2=rOTYcDwYc-y<3sTB zDU*Bp+n#I8Xz5hps5sMZnUxk9w(jJIIO}yiMawjvcijpz^bDzRNim8lT4r=@a^O27 zgEhPB7eC7sc6*)o{Kk&M?p3${T(@ja=IzwomV5m8L(WWTgEML=7hdhsaB&pbC;Dei zh2?V5Qb)H4f4>iqK~TNRJ!hIP8k>O@0bTxktE+`!R-Rbvvh25E);qnW&HJQG43~ok zg{wmA zUv;)=ymiw)FjvgeU?RW2^VgGe+Lb*xN_zGDdb-3+?&^qbD9QJb7I>ZXg~$J#0C=g) zhYQn9>t|Ts#_$c{7Xx)_ZQ`@(1zxp@JYVNe`Pv80XyRUT*V|?mUsbIH2tN*2m5_@Z%Vn@@8m$Qo2 zmGtTe(JK4zK9^&hY z{eo-lE?3rzX!Gja?VR~%f(x^7{QDSfuCPt5M>!HJSN;mLog=37|Ly&MZ|^UvyQah0 z_xR82|9`LN%h&xrZvXG%bH)4r&%gh_<=gW5U-$oiS-#c2liwg!Vv@}i#7G|l|iG* zp(3sZ*ICvb)j560DMun~zs928cRm_tFQ;)>@+h48ckV+9OQgoOT<0X_m=iiX7hE{+ zVKFny=duWBXrtry60OT7-qxxSCj=r{WR6b-t+RCd?VN2cb-eIrlHHRlK0DqeYyh>i z?%WJJym8)VoBS_4n(Db8(nY>~o&`-YlU)N-B*Su72bMor>YBS+=Wy2|jq6W5>Qavv zKA9DBL(8O3`qfgYWxG!l&Y65&y>%_q+YcXK{_#|O^>2&!J&;Iw>^s$#Uw-+z{CbE?xXj}8C6`}*%Dbt}9k@T}2w#WF=G@!c-dgP0>&M^} zufSp~6RlM?V@1TBsqD%XGxnZPztuZU|Jljwt}8hd&t6tLUO3NaV^*=uf`=ROyv6Tr z-+$P|_eI15)>EL4z>B;)Mf)?9)wpUybY7flX0?ewbNt$$T+j%r-WqP6!w&Yxb-vYo z@TofR`&;>xGOq`Z^xsY~y6JP}>`bN!)fqn@RJOU4&qa?@CK{Jbw6Ag< zFMKe&_w8iOc@JuTOA7=g-8TEVi^(r@xk%~aWz2bOZHY!V&nP9e1iVD#^g@4;KeAmtOZ{o{W>O6!|1w!?FA zo-5OWG|rw~Kb!7dtd_67U;8^YbNLj%<@!5CiN2>RZR>p5boqM+ zy;a8w58G}QkJL<)b@m_9M5mE`UU;rn&`ayYzJqsz?}N@ zh<*Pv{{LLgpz|nZ-ujxNx=$;9Xmma<{|{cKw*G$X_UN}hW}9c;))C z30|A=B{@L6%Pg&pYpU_nqo>9H*#4`0Yq@v!gsY8Zv+vK$Q@CuRvGQx>$@tG#r+FTIae%0dY zIr+E0z1kyuF_YE%vz@hc`1Ej-EZz7s*ZW@y>v2RjyiD66f9}8^$@Ois4T}#m{d7BA z`b&qiO{(wlGz-1d(iAO?q{O1$30_+#bwma#Cd^X1u~M>4QvKIQktz>M@e1Q4y)O^K z3-TjbJK1aE;tKXKPF{YL<8@Q|xwZ3S4_tjJddKwLv%8gU_7!PN&OQ%v_I6*8dY%(p zbkJgL;x4!Cbs^`)KbI_tUl}H5a`(>V!k4+s>thNI@3{NeAav3_hOdivJ&!Hj!Nb5g zZDB;_@+Uv_>RSGt+tzDcP}df}Pq9X9-_chdHV^)PD(hW0f4*}3nd*|6W&ICh4xov+P~v^nPWG@d`plJzfWmp`VY%A1KzXB zUxfY4H);Lhk6Big1U4OE<=TG$~Pxop2i^aMA_NZvD z^=)a<{PI~u;@*n886}g9m#mxZ{$jb7Fh_vmiaoc(P8Z5lsi`~H^SyOzUaq|LLE}5e zH1l7RFYXPvv6q|caPYK0br)9`I@!NlGEdAeW6$~C$^8DjY|I@_v$f_`o#ZgEso5EM zq_wG_w0!G4U1Jf6?Sg3`clMXp|33NciB)ab>;G4ZCwVR12$PEBzW@!lzugH}%Y z|1?zkIIl&@lej>E@Sh(yb6wcOdieF1U+s@AKACQvcuOjAZJOjXflI${7+0}9DP-ZF z{ojQ1#45&b!v1l*;9kQEW5pESne~=0?oZO^UDmm)k*DL`N|qLZ{>$~ZCe+NhXz;E? zf?rts*xw*yhQycic6M)2W2-ub!^M=bpIOxW;STubr;H=+gz%zqcVE!Ww9@#z~*)0>S<^w<18E>#{>ZtebW#|9ROx6{g}$#d#j&b{Eg z_~oo#fo0F;RTPz0njY@zn^^uxv|sP5|C9Y8GtR8JuJJ|t+@kt5k}d!ETPB>nv&=dn zn<>cek;S{W{`n7;&woC&>q6evm)gflpZ_{1GokPCk9yTc2~MYu)X2&GP1}p+U#*gO z`Oi&&rBgb1rA+O@pUjFbr#$~{o*~xNdQabW!-_-y|JLoln{`<%VD+xY7EkXQnZ7<8 z_tYmcI{J0(o0Fz9QzKVB-rz0bvUhRw(Rj3bJ1zx=XnwJz79BQgU9oT_)lE6&X=poQR%gaS|S{1Mw}H^XkFq%W_BuC9QJd-G%l|6Qt9DvFEUzHG}i z<}sGp==@IVqVsR#n>>dN=CLU>CeKn^cT&{ogV~-M?rY}{Z)j6cR(!W&c4lIvS^Syj z-Idc)6Hh;Wl-!nR^UEWVM#(kPQ)pmd9J0Fx7xvlcrns?#L=e8{<|ML6$yVtUJ z3+K!fuXX*u*1uw&{`)E0y>EX$lkfB=`Ag5+OJ$YIdyLud@)T(O-on#1XGPtPU3-f7 z=jYy*`{@_3GVH({r|*YW<$t+SV#pqGphMu00nZuh0{_q%1}_`dDKK-qKE(65s)@NJ zvthnyUEhk^o3=RoZ+|UQ8a=5ubJhlfP0<<&cei*L+1%f0_K@Yy&24`_>=s=n#CxK* zZ1F++84Q-Wsv2J|Gwmy%q1vIt)c5$9tA@hA#^Qu z>h)sDMQd?|FPVQ9s{gvQ@8Q%pf-H`YI{g=Z-|>1y(zG(KL%SFxHD2CZcX8<}&hrd6 zUi1AvmtwqOVo&Ecwd7@g`C|g#yyN`e+$qW8_KZp5=hb5$trxbhVVitiGd^jHbZ+W? z>n0t;!$oi8s;bXO%-bMi)gkvYV5Y*Cd6Q=5q*XAMmmAKPWKpY^VJ|#>@v}|*%CIW= z>dTU~)0n_(TPLT#RpQv>Go}3W(z!vU`(H&aJ2v@<>V&BkSG}k1Kc4?5)%ldCa`?`f zTFnQx{MmM|dH(T3n=YB|I<%{y@D#_UDFrg-d5#jdw<)HJ&*ctU8D`N}y#LN&gFD7g zg-7-ye}KO^%#av`j_sUWQqM<57osw>g?x+Rm?h6Xa)P z*EjFb*-bg0eJ2ZSioM0Q^LF*F^6F~s_oqK>EWA_ji%(G{{*3&;uL5k3L$oE@8uu$o z?%thteuHe#4)HG5!v=1B*VI!4B-&FWgP(u>#Ie6@@x_aFwdZy$=D+(me%HmfOlA6f z=9P=nr>_5SzE#0PNK$Ow#0+z(t;a4{{`{FVukX>zqJ{;WXD_R{+%1rCcmKF8w|U79 z^GgpTXIx=3tyuP#d1ek-7GqnYW6o2DL*GvTXR z81O=n#Z%%z?B~cEg)&cLBKvr@x}AUV|JL{acfp%8r%5hO7x~0mz_<8E4URPiEQF zM1rkR>3!UmC~@eperL_szIng6dN)e$oG9RAzDqe`$sCvMmwStRmr1XzI`%E5wdUYU v>$b#-MLicJyA?P#J$cX}=O~bJ^5_3r=K6iLTHPHC3=9mOu6{1-oD!M<&~$va literal 0 HcmV?d00001 diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build new file mode 100644 index 0000000..838a4f7 --- /dev/null +++ b/docs/reference/glib/meson.build @@ -0,0 +1,104 @@ +if get_option('gtk_doc') + subdir('xml') + + ignore_headers = [ + 'gallocator.h', + 'gdatasetprivate.h', + 'glibintl.h', + 'gbsearcharray.h', + 'glib-private.h', + 'gmoduleconf.h', + 'grcboxprivate.h', + 'gstdioprivate.h', + 'gthreadprivate.h', + 'gunibreak.h', + 'gunicomp.h', + 'gunidecomp.h', + 'gunichartables.h', + 'glib_probes.h', + 'glib_trace.h', + 'libcharset.h', + 'gdebug.h', + 'gprintfint.h', + 'gmirroringtable.h', + 'gscripttable.h', + 'gtrace-private.h', + 'glib-mirroring-tab', + 'gnulib', + 'gbytesprivate.h', + 'gvariant-internal.h', + 'gvariant-serialiser.h', + 'gvariant-core.h', + 'gvarianttypeinfo.h', + 'gwakeup.h', + 'gtranslit-data.h', + 'glib-init.h', + 'gconstructor.h', + 'valgrind.h', + 'gutilsprivate.h', + 'gvalgrind.h', + 'dirent.h', + ] + + docpath = join_paths(glib_datadir, 'gtk-doc', 'html') + version_conf = configuration_data() + version_conf.set('GLIB_VERSION', meson.project_version()) + configure_file( + input: 'version.xml.in', + output: 'version.xml', + configuration: version_conf + ) + + gnome.gtkdoc('glib', + main_xml : 'glib-docs.xml', + namespace : 'g', + mode : 'none', + src_dir : [ 'glib', 'gmodule' ], + dependencies : libglib_dep, + scan_args : gtkdoc_common_scan_args + [ + '--ignore-headers=' + ' '.join(ignore_headers), + ], + content_files : [ + 'cross.xml', + 'running.xml', + 'building.xml', + 'changes.xml', + 'compiling.xml', + 'programming.xml', + 'resources.xml', + 'regex-syntax.xml', + 'glib-gettextize.xml', + 'gtester.xml', + 'gtester-report.xml', + 'gvariant-varargs.xml', + 'gvariant-text.xml', + ], + expand_content_files : [ + 'compiling.xml', + ], + html_assets : [ + 'file-name-encodings.png', + 'mainloop-states.gif', + 'Sorted_binary_tree_breadth-first_traversal.svg', + 'Sorted_binary_tree_inorder.svg', + 'Sorted_binary_tree_postorder.svg', + 'Sorted_binary_tree_preorder.svg', + ], + fixxref_args: [ + '--html-dir=' + docpath, + ], + install: true, + check: true) +endif + +if get_option('man') + manpages = ['glib-gettextize', 'gtester', 'gtester-report'] + foreach page : manpages + custom_target(page + '-man', + input: page + '.xml', + output: page + '.1', + command: xsltproc_command, + install: true, + install_dir: man1_dir) + endforeach +endif diff --git a/docs/reference/glib/programming.xml b/docs/reference/glib/programming.xml new file mode 100644 index 0000000..52df907 --- /dev/null +++ b/docs/reference/glib/programming.xml @@ -0,0 +1,67 @@ + + + + +Writing GLib Applications +3 +GLib Library + + + +Writing GLib Applications + +General considerations when programming with GLib + + + + +Writing GLib Applications + + +Threads + + +The general policy of GLib is that all functions are invisibly threadsafe +with the exception of data structure manipulation functions, where, if +you have two threads manipulating the same data +structure, they must use a lock to synchronize their operation. + + + +GLib creates a worker thread for its own purposes so GLib applications +will always have at least 2 threads. + + + +See the sections on threads and +threadpools for GLib APIs that +support multithreaded applications. + + + + + +Security + + +When writing code that runs with elevated privileges, it is important +to follow some basic rules of secure programming. David Wheeler has an +excellent book on this topic, +Secure Programming for Linux and Unix HOWTO. + + + +When it comes to GLib and its associated libraries, GLib and +GObject are generally fine to use in code that runs with elevated +privileges; they don't load modules (executable code in shared objects) +or run other programs 'behind your back'. GIO has to be used +carefully in privileged programs, see the GIO documentation for details. + + + + + + + diff --git a/docs/reference/glib/regex-syntax.xml b/docs/reference/glib/regex-syntax.xml new file mode 100644 index 0000000..5dd9291 --- /dev/null +++ b/docs/reference/glib/regex-syntax.xml @@ -0,0 +1,2531 @@ + + + + + Regular expression syntax + + + + + + +Regular expression syntax + +syntax and semantics of regular expressions supported by GRegex + + + + +GRegex regular expression details + +A regular expression is a pattern that is matched against a +string from left to right. Most characters stand for themselves in a +pattern, and match the corresponding characters in the string. As a +trivial example, the pattern + + + +The quick brown fox + + + +matches a portion of a string that is identical to itself. When +caseless matching is specified (the G_REGEX_CASELESS flag), letters are +matched independently of case. + + + +The power of regular expressions comes from the ability to include +alternatives and repetitions in the pattern. These are encoded in the +pattern by the use of metacharacters, which do not stand for themselves +but instead are interpreted in some special way. + + + +There are two different sets of metacharacters: those that are recognized +anywhere in the pattern except within square brackets, and those +that are recognized in square brackets. Outside square brackets, the +metacharacters are as follows: + + + +Metacharacters outside square brackets + + + + + Character + Meaning + + + + + \ + general escape character with several uses + + + ^ + assert start of string (or line, in multiline mode) + + + $ + assert end of string (or line, in multiline mode) + + + . + match any character except newline (by default) + + + [ + start character class definition + + + | + start of alternative branch + + + ( + start subpattern + + + ) + end subpattern + + + ? + extends the meaning of (, or 0/1 quantifier, or quantifier minimizer + + + * + 0 or more quantifier + + + + + 1 or more quantifier, also "possessive quantifier" + + + { + start min/max quantifier + + + +
+ + +Part of a pattern that is in square brackets is called a "character +class". In a character class the only metacharacters are: + + + +Metacharacters inside square brackets + + + + + Character + Meaning + + + + + \ + general escape character + + + ^ + negate the class, but only if the first character + + + - + indicates character range + + + [ + POSIX character class (only if followed by POSIX syntax) + + + ] + terminates the character class + + + +
+
+ + +Backslash + +The backslash character has several uses. Firstly, if it is followed by +a non-alphanumeric character, it takes away any special meaning that +character may have. This use of backslash as an escape character +applies both inside and outside character classes. + + + +For example, if you want to match a * character, you write \* in the +pattern. This escaping action applies whether or not the following +character would otherwise be interpreted as a metacharacter, so it is +always safe to precede a non-alphanumeric with backslash to specify +that it stands for itself. In particular, if you want to match a +backslash, you write \\. + + + +If a pattern is compiled with the G_REGEX_EXTENDED +option, whitespace in the pattern (other than in a character class) and +characters between a # outside a character class and the next newline +are ignored. +An escaping backslash can be used to include a whitespace or # character +as part of the pattern. + + + +Note that the C compiler interprets backslash in strings itself, therefore +you need to duplicate all \ characters when you put a regular expression +in a C string, like "\\d{3}". + + + +If you want to remove the special meaning from a sequence of characters, +you can do so by putting them between \Q and \E. +The \Q...\E sequence is recognized both inside and outside character +classes. + + + +Non-printing characters + +A second use of backslash provides a way of encoding non-printing +characters in patterns in a visible manner. There is no restriction on the +appearance of non-printing characters, apart from the binary zero that +terminates a pattern, but when a pattern is being prepared by text +editing, it is usually easier to use one of the following escape +sequences than the binary character it represents: + + + +Non-printing characters + + + + + Escape + Meaning + + + + + \a + alarm, that is, the BEL character (hex 07) + + + \cx + "control-x", where x is any character + + + \e + escape (hex 1B) + + + \f + formfeed (hex 0C) + + + \n + newline (hex 0A) + + + \r + carriage return (hex 0D) + + + \t + tab (hex 09) + + + \ddd + character with octal code ddd, or backreference + + + \xhh + character with hex code hh + + + \x{hhh..} + character with hex code hhh.. + + + +
+ + +The precise effect of \cx is as follows: if x is a lower case letter, +it is converted to upper case. Then bit 6 of the character (hex 40) is +inverted. Thus \cz becomes hex 1A, but \c{ becomes hex 3B, while \c; +becomes hex 7B. + + + +After \x, from zero to two hexadecimal digits are read (letters can be +in upper or lower case). Any number of hexadecimal digits may appear +between \x{ and }, but the value of the character code +must be less than 2**31 (that is, the maximum hexadecimal value is +7FFFFFFF). If characters other than hexadecimal digits appear between +\x{ and }, or if there is no terminating }, this form of escape is not +recognized. Instead, the initial \x will be interpreted as a basic hexadecimal +escape, with no following digits, giving a character whose +value is zero. + + + +Characters whose value is less than 256 can be defined by either of the +two syntaxes for \x. There is no difference +in the way they are handled. For example, \xdc is exactly the same as +\x{dc}. + + + +After \0 up to two further octal digits are read. If there are fewer +than two digits, just those that are present are used. +Thus the sequence \0\x\07 specifies two binary zeros followed by a BEL +character (code value 7). Make sure you supply two digits after the +initial zero if the pattern character that follows is itself an octal +digit. + + + +The handling of a backslash followed by a digit other than 0 is complicated. +Outside a character class, GRegex reads it and any following digits as a +decimal number. If the number is less than 10, or if there +have been at least that many previous capturing left parentheses in the +expression, the entire sequence is taken as a back reference. A +description of how this works is given later, following the discussion +of parenthesized subpatterns. + + + +Inside a character class, or if the decimal number is greater than 9 +and there have not been that many capturing subpatterns, GRegex re-reads +up to three octal digits following the backslash, and uses them to generate +a data character. Any subsequent digits stand for themselves. For example: + + + +Non-printing characters + + + + + Escape + Meaning + + + + + \040 + is another way of writing a space + + + \40 + is the same, provided there are fewer than 40 previous capturing subpatterns + + + \7 + is always a back reference + + + \11 + might be a back reference, or another way of writing a tab + + + \011 + is always a tab + + + \0113 + is a tab followed by the character "3" + + + \113 + might be a back reference, otherwise the character with octal code 113 + + + \377 + might be a back reference, otherwise the byte consisting entirely of 1 bits + + + \81 + is either a back reference, or a binary zero followed by the two characters "8" and "1" + + + +
+ + +Note that octal values of 100 or greater must not be introduced by a +leading zero, because no more than three octal digits are ever read. + + + +All the sequences that define a single character can be used both inside +and outside character classes. In addition, inside a character class, the +sequence \b is interpreted as the backspace character (hex 08), and the +sequences \R and \X are interpreted as the characters "R" and "X", respectively. +Outside a character class, these sequences have different meanings (see below). + +
+ + +Absolute and relative back references + +The sequence \g followed by a positive or negative number, optionally enclosed +in braces, is an absolute or relative back reference. Back references are +discussed later, following the discussion of parenthesized subpatterns. + + + + +Generic character types + + +Another use of backslash is for specifying generic character types. +The following are always recognized: + + + +Generic characters + + + + + Escape + Meaning + + + + + \d + any decimal digit + + + \D + any character that is not a decimal digit + + + \s + any whitespace character + + + \S + any character that is not a whitespace character + + + \w + any "word" character + + + \W + any "non-word" character + + + +
+ + +Each pair of escape sequences partitions the complete set of characters +into two disjoint sets. Any given character matches one, and only one, +of each pair. + + + +These character type sequences can appear both inside and outside character +classes. They each match one character of the appropriate type. +If the current matching point is at the end of the passed string, all +of them fail, since there is no character to match. + + + +For compatibility with Perl, \s does not match the VT character (code +11). This makes it different from the POSIX "space" class. The \s +characters are HT (9), LF (10), FF (12), CR (13), and space (32). + + + +A "word" character is an underscore or any character less than 256 that +is a letter or digit. + + +Characters with values greater than 128 never match \d, +\s, or \w, and always match \D, \S, and \W. + +
+ + +Newline sequences +Outside a character class, the escape sequence \R matches any Unicode +newline sequence. +This particular group matches either the two-character sequence CR followed by +LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab, +U+000B), FF (formfeed, U+000C), CR (carriage return, U+000D), NEL (next +line, U+0085), LS (line separator, U+2028), or PS (paragraph separator, U+2029). +The two-character sequence is treated as a single unit that +cannot be split. Inside a character class, \R matches the letter "R". + + + +Unicode character properties + +To support generic character types there are three additional escape +sequences, they are: + + + +Generic character types + + + + + Escape + Meaning + + + + + \p{xx} + a character with the xx property + + + \P{xx} + a character without the xx property + + + \X + an extended Unicode sequence + + + +
+ + +The property names represented by xx above are limited to the Unicode +script names, the general category properties, and "Any", which matches +any character (including newline). Other properties such as "InMusicalSymbols" +are not currently supported. Note that \P{Any} does not match any characters, +so always causes a match failure. + + + +Sets of Unicode characters are defined as belonging to certain scripts. A +character from one of these sets can be matched using a script name. For +example, \p{Greek} or \P{Han}. + + + +Those that are not part of an identified script are lumped together as +"Common". The current list of scripts can be found in the documentation for +the #GUnicodeScript enumeration. Script names for use with \p{} can be +found by replacing all spaces with underscores, e.g. for Linear B use +\p{Linear_B}. + + + +Each character has exactly one general category property, specified by a +two-letter abbreviation. For compatibility with Perl, negation can be specified +by including a circumflex between the opening brace and the property name. For +example, \p{^Lu} is the same as \P{Lu}. + + + +If only one letter is specified with \p or \P, it includes all the general +category properties that start with that letter. In this case, in the absence +of negation, the curly brackets in the escape sequence are optional; these two +examples have the same effect: + + + +\p{L} +\pL + + + +In addition to the two-letter category codes listed in the +documentation for the #GUnicodeType enumeration, the following +general category property codes are supported: + + + +Property codes + + + + + Code + Meaning + + + + + C + Other + + + L + Letter + + + M + Mark + + + N + Number + + + P + Punctuation + + + S + Symbol + + + Z + Separator + + + +
+ + +The special property L& is also supported: it matches a character that has +the Lu, Ll, or Lt property, in other words, a letter that is not classified as +a modifier or "other". + + + +The long synonyms for these properties that Perl supports (such as \ep{Letter}) +are not supported by GRegex, nor is it permitted to prefix any of these +properties with "Is". + + + +No character that is in the Unicode table has the Cn (unassigned) property. +Instead, this property is assumed for any code point that is not in the +Unicode table. + + + +Specifying caseless matching does not affect these escape sequences. +For example, \p{Lu} always matches only upper case letters. + + + +The \X escape matches any number of Unicode characters that form an +extended Unicode sequence. \X is equivalent to + + + +(?>\PM\pM*) + + + +That is, it matches a character without the "mark" property, followed +by zero or more characters with the "mark" property, and treats the +sequence as an atomic group (see below). Characters with the "mark" +property are typically accents that affect the preceding character. + + + +Matching characters by Unicode property is not fast, because GRegex has +to search a structure that contains data for over fifteen thousand +characters. That is why the traditional escape sequences such as \d and +\w do not use Unicode properties. + +
+ + +Simple assertions + +The final use of backslash is for certain simple assertions. An +assertion specifies a condition that has to be met at a particular point in +a match, without consuming any characters from the string. The +use of subpatterns for more complicated assertions is described below. +The backslashed assertions are: + + + +Simple assertions + + + + + Escape + Meaning + + + + + \b + matches at a word boundary + + + \B + matches when not at a word boundary + + + \A + matches at the start of the string + + + \Z + matches at the end of the string or before a newline at the end of the string + + + \z + matches only at the end of the string + + + \G + matches at first matching position in the string + + + +
+ + +These assertions may not appear in character classes (but note that \b +has a different meaning, namely the backspace character, inside a +character class). + + + +A word boundary is a position in the string where the current +character and the previous character do not both match \w or \W (i.e. +one matches \w and the other matches \W), or the start or end of the +string if the first or last character matches \w, respectively. + + + +The \A, \Z, and \z assertions differ from the traditional circumflex +and dollar (described in the next section) in that they only ever match +at the very start and end of the string, whatever options are +set. Thus, they are independent of multiline mode. These three assertions +are not affected by the G_REGEX_MATCH_NOTBOL or G_REGEX_MATCH_NOTEOL options, +which affect only the behaviour of the circumflex and dollar metacharacters. +However, if the start_position argument of a matching function is non-zero, +indicating that matching is to start at a point other than the beginning of +the string, \A can never match. The difference between \Z and \z is +that \Z matches before a newline at the end of the string as well at the +very end, whereas \z matches only at the end. + + + +The \G assertion is true only when the current matching position is at +the start point of the match, as specified by the start_position argument +to the matching functions. It differs from \A when the value of startoffset is +non-zero. + + + +Note, however, that the interpretation of \G, as the start of the +current match, is subtly different from Perl’s, which defines it as the +end of the previous match. In Perl, these can be different when the +previously matched string was empty. + + + +If all the alternatives of a pattern begin with \G, the expression is +anchored to the starting match position, and the "anchored" flag is set +in the compiled regular expression. + +
+
+ + +Circumflex and dollar + +Outside a character class, in the default matching mode, the circumflex +character is an assertion that is true only if the current matching +point is at the start of the string. If the start_position argument to +the matching functions is non-zero, circumflex can never match if the +G_REGEX_MULTILINE option is unset. Inside a character class, circumflex +has an entirely different meaning (see below). + + + +Circumflex need not be the first character of the pattern if a number +of alternatives are involved, but it should be the first thing in each +alternative in which it appears if the pattern is ever to match that +branch. If all possible alternatives start with a circumflex, that is, +if the pattern is constrained to match only at the start of the string, +it is said to be an "anchored" pattern. (There are also other +constructs that can cause a pattern to be anchored.) + + + +A dollar character is an assertion that is true only if the current +matching point is at the end of the string, or immediately +before a newline at the end of the string (by default). Dollar need not +be the last character of the pattern if a number of alternatives are +involved, but it should be the last item in any branch in which it +appears. Dollar has no special meaning in a character class. + + + +The meaning of dollar can be changed so that it matches only at the +very end of the string, by setting the G_REGEX_DOLLAR_ENDONLY option at +compile time. This does not affect the \Z assertion. + + + +The meanings of the circumflex and dollar characters are changed if the +G_REGEX_MULTILINE option is set. When this is the case, +a circumflex matches immediately after internal newlines as well as at the +start of the string. It does not match after a newline that ends the string. +A dollar matches before any newlines in the string, as well as at the very +end, when G_REGEX_MULTILINE is set. When newline is +specified as the two-character sequence CRLF, isolated CR and LF characters +do not indicate newlines. + + + +For example, the pattern /^abc$/ matches the string "def\nabc" (where +\n represents a newline) in multiline mode, but not otherwise. Consequently, +patterns that are anchored in single line mode because all branches start with +^ are not anchored in multiline mode, and a match for circumflex is possible +when the start_position argument of a matching function +is non-zero. The G_REGEX_DOLLAR_ENDONLY option is ignored +if G_REGEX_MULTILINE is set. + + + +Note that the sequences \A, \Z, and \z can be used to match the start and +end of the string in both modes, and if all branches of a pattern start with +\A it is always anchored, whether or not G_REGEX_MULTILINE +is set. + + + + +Full stop (period, dot) + +Outside a character class, a dot in the pattern matches any one character +in the string, including a non-printing character, but not (by +default) newline. In UTF-8 a character might be more than one byte long. + + + +When a line ending is defined as a single character, dot never matches that +character; when the two-character sequence CRLF is used, dot does not match CR +if it is immediately followed by LF, but otherwise it matches all characters +(including isolated CRs and LFs). When any Unicode line endings are being +recognized, dot does not match CR or LF or any of the other line ending +characters. + + + +If the G_REGEX_DOTALL flag is set, dots match newlines +as well. The handling of dot is entirely independent of the handling of circumflex +and dollar, the only relationship being that they both involve newline +characters. Dot has no special meaning in a character class. + + + +The behaviour of dot with regard to newlines can be changed. If the +G_REGEX_DOTALL option is set, a dot matches any one +character, without exception. If newline is defined as the two-character +sequence CRLF, it takes two dots to match it. + + + +The handling of dot is entirely independent of the handling of circumflex and +dollar, the only relationship being that they both involve newlines. Dot has no +special meaning in a character class. + + + + +Matching a single byte + +Outside a character class, the escape sequence \C matches any one byte, +both in and out of UTF-8 mode. Unlike a dot, it always matches any line +ending characters. +The feature is provided in Perl in order to match individual bytes in +UTF-8 mode. Because it breaks up UTF-8 characters into individual +bytes, what remains in the string may be a malformed UTF-8 string. For +this reason, the \C escape sequence is best avoided. + + + +GRegex does not allow \C to appear in lookbehind assertions (described +below), because in UTF-8 mode this would make it impossible to calculate +the length of the lookbehind. + + + + +Square brackets and character classes + +An opening square bracket introduces a character class, terminated by a +closing square bracket. A closing square bracket on its own is not special. If a closing square bracket is required as a member of the class, +it should be the first data character in the class (after an initial +circumflex, if present) or escaped with a backslash. + + + +A character class matches a single character in the string. A matched character +must be in the set of characters defined by the class, unless the first +character in the class definition is a circumflex, in which case the +string character must not be in the set defined by the class. If a +circumflex is actually required as a member of the class, ensure it is +not the first character, or escape it with a backslash. + + + +For example, the character class [aeiou] matches any lower case vowel, +while [^aeiou] matches any character that is not a lower case vowel. +Note that a circumflex is just a convenient notation for specifying the +characters that are in the class by enumerating those that are not. A +class that starts with a circumflex is not an assertion: it still consumes +a character from the string, and therefore it fails if the current pointer +is at the end of the string. + + + +In UTF-8 mode, characters with values greater than 255 can be included +in a class as a literal string of bytes, or by using the \x{ escaping +mechanism. + + + +When caseless matching is set, any letters in a class represent both +their upper case and lower case versions, so for example, a caseless +[aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not +match "A", whereas a caseful version would. + + + +Characters that might indicate line breaks are never treated +in any special way when matching character classes, whatever line-ending +sequence is in use, and whatever setting of the G_REGEX_DOTALL +and G_REGEX_MULTILINE options is used. A class such as [^a] +always matches one of these characters. + + + +The minus (hyphen) character can be used to specify a range of characters in +a character class. For example, [d-m] matches any letter +between d and m, inclusive. If a minus character is required in a +class, it must be escaped with a backslash or appear in a position +where it cannot be interpreted as indicating a range, typically as the +first or last character in the class. + + + +It is not possible to have the literal character "]" as the end character +of a range. A pattern such as [W-]46] is interpreted as a class of +two characters ("W" and "-") followed by a literal string "46]", so it +would match "W46]" or "-46]". However, if the "]" is escaped with a +backslash it is interpreted as the end of range, so [W-\]46] is interpreted +as a class containing a range followed by two other characters. +The octal or hexadecimal representation of "]" can also be used to end +a range. + + + +Ranges operate in the collating sequence of character values. They can +also be used for characters specified numerically, for example +[\000-\037]. In UTF-8 mode, ranges can include characters whose values +are greater than 255, for example [\x{100}-\x{2ff}]. + + + +The character types \d, \D, \p, \P, \s, \S, \w, and \W may also appear +in a character class, and add the characters that they match to the +class. For example, [\dABCDEF] matches any hexadecimal digit. A +circumflex can conveniently be used with the upper case character types to +specify a more restricted set of characters than the matching lower +case type. For example, the class [^\W_] matches any letter or digit, +but not underscore. + + + +The only metacharacters that are recognized in character classes are +backslash, hyphen (only where it can be interpreted as specifying a +range), circumflex (only at the start), opening square bracket (only +when it can be interpreted as introducing a POSIX class name - see the +next section), and the terminating closing square bracket. However, +escaping other non-alphanumeric characters does no harm. + + + + +Posix character classes + +GRegex supports the POSIX notation for character classes. This uses names +enclosed by [: and :] within the enclosing square brackets. For example, + + + +[01[:alpha:]%] + + + +matches "0", "1", any alphabetic character, or "%". The supported class +names are + + + +Posix classes + + + + + Name + Meaning + + + + + alnum + letters and digits + + + alpha + letters + + + ascii + character codes 0 - 127 + + + blank + space or tab only + + + cntrl + control characters + + + digit + decimal digits (same as \d) + + + graph + printing characters, excluding space + + + lower + lower case letters + + + print + printing characters, including space + + + punct + printing characters, excluding letters and digits + + + space + white space (not quite the same as \s) + + + upper + upper case letters + + + word + "word" characters (same as \w) + + + xdigit + hexadecimal digits + + + +
+ + +The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), +and space (32). Notice that this list includes the VT character (code +11). This makes "space" different to \s, which does not include VT (for +Perl compatibility). + + + +The name "word" is a Perl extension, and "blank" is a GNU extension. +Another Perl extension is negation, which is indicated by a ^ character +after the colon. For example, + + + +[12[:^digit:]] + + + +matches "1", "2", or any non-digit. GRegex also recognize the +POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but +these are not supported, and an error is given if they are encountered. + + + +In UTF-8 mode, characters with values greater than 128 do not match any +of the POSIX character classes. + +
+ + +Vertical bar + +Vertical bar characters are used to separate alternative patterns. For +example, the pattern + + + + gilbert|sullivan + + + +matches either "gilbert" or "sullivan". Any number of alternatives may +appear, and an empty alternative is permitted (matching the empty +string). The matching process tries each alternative in turn, from +left to right, and the first one that succeeds is used. If the alternatives are within a subpattern (defined below), "succeeds" means matching the rest of the main pattern as well as the alternative in the subpattern. + + + + +Internal option setting + +The settings of the G_REGEX_CASELESS, G_REGEX_MULTILINE, G_REGEX_MULTILINE, +and G_REGEX_EXTENDED options can be changed from within the pattern by a +sequence of Perl-style option letters enclosed between "(?" and ")". The +option letters are + + + +Option settings + + + + + Option + Flag + + + + + i + G_REGEX_CASELESS + + + m + G_REGEX_MULTILINE + + + s + G_REGEX_DOTALL + + + x + G_REGEX_EXTENDED + + + +
+ + +For example, (?im) sets caseless, multiline matching. It is also +possible to unset these options by preceding the letter with a hyphen, and a +combined setting and unsetting such as (?im-sx), which sets G_REGEX_CASELESS +and G_REGEX_MULTILINE while unsetting G_REGEX_DOTALL and G_REGEX_EXTENDED, +is also permitted. If a letter appears both before and after the +hyphen, the option is unset. + + + +When an option change occurs at top level (that is, not inside subpattern +parentheses), the change applies to the remainder of the pattern +that follows. + + + +An option change within a subpattern (see below for a description of subpatterns) +affects only that part of the current pattern that follows it, so + + + +(a(?i)b)c + + + +matches abc and aBc and no other strings (assuming G_REGEX_CASELESS is not +used). By this means, options can be made to have different settings +in different parts of the pattern. Any changes made in one alternative +do carry on into subsequent branches within the same subpattern. For +example, + + + +(a(?i)b|c) + + + +matches "ab", "aB", "c", and "C", even though when matching "C" the +first branch is abandoned before the option setting. This is because +the effects of option settings happen at compile time. There would be +some very weird behaviour otherwise. + + + +The options G_REGEX_UNGREEDY and +G_REGEX_EXTRA and G_REGEX_DUPNAMES +can be changed in the same way as the Perl-compatible options by using +the characters U, X and J respectively. + +
+ + +Subpatterns + +Subpatterns are delimited by parentheses (round brackets), which can be +nested. Turning part of a pattern into a subpattern does two things: + + + + +It localizes a set of alternatives. For example, the pattern +cat(aract|erpillar|) matches one of the words "cat", "cataract", or +"caterpillar". Without the parentheses, it would match "cataract", +"erpillar" or an empty string. + + +It sets up the subpattern as a capturing subpattern. This means +that, when the whole pattern matches, that portion of the +string that matched the subpattern can be obtained using g_match_info_fetch(). +Opening parentheses are counted from left to right (starting from 1, as +subpattern 0 is the whole matched string) to obtain numbers for the +capturing subpatterns. + + + + +For example, if the string "the red king" is matched against the pattern + + + +the ((red|white) (king|queen)) + + + +the captured substrings are "red king", "red", and "king", and are numbered 1, 2, and 3, respectively. + + + +The fact that plain parentheses fulfil two functions is not always +helpful. There are often times when a grouping subpattern is required +without a capturing requirement. If an opening parenthesis is followed +by a question mark and a colon, the subpattern does not do any capturing, +and is not counted when computing the number of any subsequent +capturing subpatterns. For example, if the string "the white queen" is +matched against the pattern + + + +the ((?:red|white) (king|queen)) + + + +the captured substrings are "white queen" and "queen", and are numbered +1 and 2. The maximum number of capturing subpatterns is 65535. + + + +As a convenient shorthand, if any option settings are required at the +start of a non-capturing subpattern, the option letters may appear +between the "?" and the ":". Thus the two patterns + + + +(?i:saturday|sunday) +(?:(?i)saturday|sunday) + + + +match exactly the same set of strings. Because alternative branches are +tried from left to right, and options are not reset until the end of +the subpattern is reached, an option setting in one branch does affect +subsequent branches, so the above patterns match "SUNDAY" as well as +"Saturday". + + + + +Named subpatterns + +Identifying capturing parentheses by number is simple, but it can be +very hard to keep track of the numbers in complicated regular expressions. +Furthermore, if an expression is modified, the numbers may +change. To help with this difficulty, GRegex supports the naming of +subpatterns. A subpattern can be named in one of three ways: (?<name>...) or +(?'name'...) as in Perl, or (?P<name>...) as in Python. +References to capturing parentheses from other +parts of the pattern, such as backreferences, recursion, and conditions, +can be made by name as well as by number. + + + +Names consist of up to 32 alphanumeric characters and underscores. Named +capturing parentheses are still allocated numbers as well as names, exactly as +if the names were not present. +By default, a name must be unique within a pattern, but it is possible to relax +this constraint by setting the G_REGEX_DUPNAMES option at +compile time. This can be useful for patterns where only one instance of the +named parentheses can match. Suppose you want to match the name of a weekday, +either as a 3-letter abbreviation or as the full name, and in both cases you +want to extract the abbreviation. This pattern (ignoring the line breaks) does +the job: + + + +(?<DN>Mon|Fri|Sun)(?:day)?| +(?<DN>Tue)(?:sday)?| +(?<DN>Wed)(?:nesday)?| +(?<DN>Thu)(?:rsday)?| +(?<DN>Sat)(?:urday)? + + + +There are five capturing substrings, but only one is ever set after a match. +The function for extracting the data by name returns the substring +for the first (and in this example, the only) subpattern of that name that +matched. This saves searching to find which numbered subpattern it was. If you +make a reference to a non-unique named subpattern from elsewhere in the +pattern, the one that corresponds to the lowest number is used. + + + + +Repetition + +Repetition is specified by quantifiers, which can follow any of the +following items: + + + +a literal data character +the dot metacharacter +the \C escape sequence +the \X escape sequence (in UTF-8 mode) +the \R escape sequence +an escape such as \d that matches a single character +a character class +a back reference (see next section) +a parenthesized subpattern (unless it is an assertion) + + + +The general repetition quantifier specifies a minimum and maximum number +of permitted matches, by giving the two numbers in curly brackets +(braces), separated by a comma. The numbers must be less than 65536, +and the first must be less than or equal to the second. For example: + + + +z{2,4} + + + +matches "zz", "zzz", or "zzzz". A closing brace on its own is not a +special character. If the second number is omitted, but the comma is +present, there is no upper limit; if the second number and the comma +are both omitted, the quantifier specifies an exact number of required +matches. Thus + + + +[aeiou]{3,} + + + +matches at least 3 successive vowels, but may match many more, while + + + +\d{8} + + + +matches exactly 8 digits. An opening curly bracket that appears in a +position where a quantifier is not allowed, or one that does not match +the syntax of a quantifier, is taken as a literal character. For example, +{,6} is not a quantifier, but a literal string of four characters. + + + +In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to +individual bytes. Thus, for example, \x{100}{2} matches two UTF-8 +characters, each of which is represented by a two-byte sequence. Similarly, +\X{3} matches three Unicode extended sequences, each of which may be +several bytes long (and they may be of different lengths). + + + +The quantifier {0} is permitted, causing the expression to behave as if +the previous item and the quantifier were not present. + + + +For convenience, the three most common quantifiers have single-character +abbreviations: + + + +Abbreviations for quantifiers + + + + + Abbreviation + Meaning + + + + + * + is equivalent to {0,} + + + + + is equivalent to {1,} + + + ? + is equivalent to {0,1} + + + +
+ + +It is possible to construct infinite loops by following a subpattern +that can match no characters with a quantifier that has no upper limit, +for example: + + + +(a?)* + + + +Because there are cases where this can be useful, such patterns are +accepted, but if any repetition of the subpattern does in fact match +no characters, the loop is forcibly broken. + + + +By default, the quantifiers are "greedy", that is, they match as much +as possible (up to the maximum number of permitted times), without +causing the rest of the pattern to fail. The classic example of where +this gives problems is in trying to match comments in C programs. These +appear between /* and */ and within the comment, individual * and / +characters may appear. An attempt to match C comments by applying the +pattern + + + +/\*.*\*/ + + + +to the string + + + +/* first comment */ not comment /* second comment */ + + + +fails, because it matches the entire string owing to the greediness of +the .* item. + + + +However, if a quantifier is followed by a question mark, it ceases to +be greedy, and instead matches the minimum number of times possible, so +the pattern + + + +/\*.*?\*/ + + + +does the right thing with the C comments. The meaning of the various +quantifiers is not otherwise changed, just the preferred number of +matches. Do not confuse this use of question mark with its use as a +quantifier in its own right. Because it has two uses, it can sometimes +appear doubled, as in + + + +\d??\d + + + +which matches one digit by preference, but can match two if that is the +only way the rest of the pattern matches. + + + +If the G_REGEX_UNGREEDY flag is set, the quantifiers are not greedy +by default, but individual ones can be made greedy by following them with +a question mark. In other words, it inverts the default behaviour. + + + +When a parenthesized subpattern is quantified with a minimum repeat +count that is greater than 1 or with a limited maximum, more memory is +required for the compiled pattern, in proportion to the size of the +minimum or maximum. + + + +If a pattern starts with .* or .{0,} and the G_REGEX_DOTALL flag +is set, thus allowing the dot to match newlines, the +pattern is implicitly anchored, because whatever follows will be tried +against every character position in the string, so there is no +point in retrying the overall match at any position after the first. +GRegex normally treats such a pattern as though it were preceded by \A. + + + +In cases where it is known that the string contains no newlines, it +is worth setting G_REGEX_DOTALL in order to obtain this optimization, +or alternatively using ^ to indicate anchoring explicitly. + + + +However, there is one situation where the optimization cannot be used. +When .* is inside capturing parentheses that are the subject of a +backreference elsewhere in the pattern, a match at the start may fail +where a later one succeeds. Consider, for example: + + + +(.*)abc\1 + + + +If the string is "xyz123abc123" the match point is the fourth character. +For this reason, such a pattern is not implicitly anchored. + + + +When a capturing subpattern is repeated, the value captured is the +substring that matched the final iteration. For example, after + + + +(tweedle[dume]{3}\s*)+ + + + +has matched "tweedledum tweedledee" the value of the captured substring +is "tweedledee". However, if there are nested capturing subpatterns, +the corresponding captured values may have been set in previous iterations. +For example, after + + + +/(a|(b))+/ + + + +matches "aba" the value of the second captured substring is "b". + +
+ + +Atomic grouping and possessive quantifiers + +With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") +repetition, failure of what follows normally causes the repeated +item to be re-evaluated to see if a different number +of repeats allows the rest of the pattern to match. Sometimes it +is useful to prevent this, either to change the nature of the +match, or to cause it fail earlier than it otherwise might, when the +author of the pattern knows there is no point in carrying on. + + + +Consider, for example, the pattern \d+foo when applied to the string + + + +123456bar + + + +After matching all 6 digits and then failing to match "foo", the normal +action of the matcher is to try again with only 5 digits matching the +\d+ item, and then with 4, and so on, before ultimately failing. +"Atomic grouping" (a term taken from Jeffrey Friedl’s book) provides +the means for specifying that once a subpattern has matched, it is not +to be re-evaluated in this way. + + + +If we use atomic grouping for the previous example, the matcher +give up immediately on failing to match "foo" the first time. The notation +is a kind of special parenthesis, starting with (?> as in this +example: + + + +(?>\d+)foo + + + +This kind of parenthesis "locks up" the part of the pattern it contains +once it has matched, and a failure further into the pattern is +prevented from backtracking into it. Backtracking past it to previous +items, however, works as normal. + + + +An alternative description is that a subpattern of this type matches +the string of characters that an identical standalone pattern would +match, if anchored at the current point in the string. + + + +Atomic grouping subpatterns are not capturing subpatterns. Simple cases +such as the above example can be thought of as a maximizing repeat that +must swallow everything it can. So, while both \d+ and \d+? are prepared +to adjust the number of digits they match in order to make the +rest of the pattern match, (?>\d+) can only match an entire sequence of +digits. + + + +Atomic groups in general can of course contain arbitrarily complicated +subpatterns, and can be nested. However, when the subpattern for an +atomic group is just a single repeated item, as in the example above, a +simpler notation, called a "possessive quantifier" can be used. This +consists of an additional + character following a quantifier. Using +this notation, the previous example can be rewritten as + + + +\d++foo + + + +Possessive quantifiers are always greedy; the setting of the +G_REGEX_UNGREEDY option is ignored. They are a convenient notation for the +simpler forms of atomic group. However, there is no difference in the +meaning of a possessive quantifier and the equivalent +atomic group, though there may be a performance difference; +possessive quantifiers should be slightly faster. + + + +The possessive quantifier syntax is an extension to the Perl syntax. +It was invented by Jeffrey Friedl in the first edition of his book and +then implemented by Mike McCloskey in Sun's Java package. +It ultimately found its way into Perl at release 5.10. + + + +GRegex has an optimization that automatically "possessifies" certain simple +pattern constructs. For example, the sequence A+B is treated as A++B because +there is no point in backtracking into a sequence of A's when B must follow. + + + +When a pattern contains an unlimited repeat inside a subpattern that +can itself be repeated an unlimited number of times, the use of an +atomic group is the only way to avoid some failing matches taking a +very long time indeed. The pattern + + + +(\D+|<\d+>)*[!?] + + + +matches an unlimited number of substrings that either consist of non- +digits, or digits enclosed in <>, followed by either ! or ?. When it +matches, it runs quickly. However, if it is applied to + + + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + + +it takes a long time before reporting failure. This is because the +string can be divided between the internal \D+ repeat and the external +* repeat in a large number of ways, and all have to be tried. (The +example uses [!?] rather than a single character at the end, because +GRegex has an optimization that allows for fast failure +when a single character is used. It remember the last single character +that is required for a match, and fail early if it is not present +in the string.) If the pattern is changed so that it uses an atomic +group, like this: + + + +((?>\D+)|<\d+>)*[!?] + + + +sequences of non-digits cannot be broken, and failure happens quickly. + + + + +Back references + +Outside a character class, a backslash followed by a digit greater than +0 (and possibly further digits) is a back reference to a capturing subpattern +earlier (that is, to its left) in the pattern, provided there have been that +many previous capturing left parentheses. + + + +However, if the decimal number following the backslash is less than 10, +it is always taken as a back reference, and causes an error only if +there are not that many capturing left parentheses in the entire pattern. +In other words, the parentheses that are referenced need not be +to the left of the reference for numbers less than 10. A "forward back +reference" of this type can make sense when a repetition is involved and +the subpattern to the right has participated in an earlier iteration. + + + +It is not possible to have a numerical "forward back reference" to subpattern +whose number is 10 or more using this syntax because a sequence such as \e50 is +interpreted as a character defined in octal. See the subsection entitled +"Non-printing characters" above for further details of the handling of digits +following a backslash. There is no such problem when named parentheses are used. +A back reference to any subpattern is possible using named parentheses (see below). + + + +Another way of avoiding the ambiguity inherent in the use of digits following a +backslash is to use the \g escape sequence (introduced in Perl 5.10.) +This escape must be followed by a positive or a negative number, +optionally enclosed in braces. + + + +A positive number specifies an absolute reference without the ambiguity that is +present in the older syntax. It is also useful when literal digits follow the +reference. A negative number is a relative reference. Consider "(abc(def)ghi)\g{-1}", +the sequence \g{-1} is a reference to the most recently started capturing +subpattern before \g, that is, is it equivalent to \2. Similarly, \g{-2} +would be equivalent to \1. The use of relative references can be helpful in +long patterns, and also in patterns that are created by joining together +fragments that contain references within themselves. + + + +A back reference matches whatever actually matched the capturing subpattern +in the current string, rather than anything matching +the subpattern itself (see "Subpatterns as subroutines" below for a way +of doing that). So the pattern + + + +(sens|respons)e and \1ibility + + + +matches "sense and sensibility" and "response and responsibility", but +not "sense and responsibility". If caseful matching is in force at the +time of the back reference, the case of letters is relevant. For example, + + + +((?i)rah)\s+\1 + + + +matches "rah rah" and "RAH RAH", but not "RAH rah", even though the +original capturing subpattern is matched caselessly. + + + +Back references to named subpatterns use the Perl syntax \k<name> or \k'name' +or the Python syntax (?P=name). We could rewrite the above example in either of +the following ways: + + + +(?<p1>(?i)rah)\s+\k<p1> +(?P<p1>(?i)rah)\s+(?P=p1) + + + +A subpattern that is referenced by name may appear in the pattern before or +after the reference. + + + +There may be more than one back reference to the same subpattern. If a +subpattern has not actually been used in a particular match, any back +references to it always fail. For example, the pattern + + + +(a|(bc))\2 + + + +always fails if it starts to match "a" rather than "bc". Because there +may be many capturing parentheses in a pattern, all digits following +the backslash are taken as part of a potential back reference number. +If the pattern continues with a digit character, some delimiter must be +used to terminate the back reference. If the G_REGEX_EXTENDED flag is +set, this can be whitespace. Otherwise an empty comment (see "Comments" below) can be used. + + + +A back reference that occurs inside the parentheses to which it refers +fails when the subpattern is first used, so, for example, (a\1) never +matches. However, such references can be useful inside repeated subpatterns. +For example, the pattern + + + +(a|b\1)+ + + + +matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration +of the subpattern, the back reference matches the character +string corresponding to the previous iteration. In order for this to +work, the pattern must be such that the first iteration does not need +to match the back reference. This can be done using alternation, as in +the example above, or by a quantifier with a minimum of zero. + + + + +Assertions + +An assertion is a test on the characters following or preceding the +current matching point that does not actually consume any characters. +The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are +described above. + + + +More complicated assertions are coded as subpatterns. There are two +kinds: those that look ahead of the current position in the +string, and those that look behind it. An assertion subpattern is +matched in the normal way, except that it does not cause the current +matching position to be changed. + + + +Assertion subpatterns are not capturing subpatterns, and may not be +repeated, because it makes no sense to assert the same thing several +times. If any kind of assertion contains capturing subpatterns within +it, these are counted for the purposes of numbering the capturing +subpatterns in the whole pattern. However, substring capturing is carried +out only for positive assertions, because it does not make sense for +negative assertions. + + + +Lookahead assertions + +Lookahead assertions start with (?= for positive assertions and (?! for +negative assertions. For example, + + + +\w+(?=;) + + + +matches a word followed by a semicolon, but does not include the semicolon +in the match, and + + + +foo(?!bar) + + + +matches any occurrence of "foo" that is not followed by "bar". Note +that the apparently similar pattern + + + +(?!foo)bar + + + +does not find an occurrence of "bar" that is preceded by something +other than "foo"; it finds any occurrence of "bar" whatsoever, because +the assertion (?!foo) is always true when the next three characters are +"bar". A lookbehind assertion is needed to achieve the other effect. + + + +If you want to force a matching failure at some point in a pattern, the +most convenient way to do it is with (?!) because an empty string +always matches, so an assertion that requires there not to be an empty +string must always fail. + + + + +Lookbehind assertions + +Lookbehind assertions start with (?<= for positive assertions and (?<! +for negative assertions. For example, + + + +(?<!foo)bar + + + +does find an occurrence of "bar" that is not preceded by "foo". The +contents of a lookbehind assertion are restricted such that all the +strings it matches must have a fixed length. However, if there are +several top-level alternatives, they do not all have to have the same +fixed length. Thus + + + +(?<=bullock|donkey) + + + +is permitted, but + + + +(?<!dogs?|cats?) + + + +causes an error at compile time. Branches that match different length +strings are permitted only at the top level of a lookbehind assertion. +An assertion such as + + + +(?<=ab(c|de)) + + + +is not permitted, because its single top-level branch can match two +different lengths, but it is acceptable if rewritten to use two top- +level branches: + + + +(?<=abc|abde) + + + +The implementation of lookbehind assertions is, for each alternative, +to temporarily move the current position back by the fixed length and +then try to match. If there are insufficient characters before the +current position, the assertion fails. + + + +GRegex does not allow the \C escape (which matches a single byte in UTF-8 +mode) to appear in lookbehind assertions, because it makes it impossible +to calculate the length of the lookbehind. The \X and \R escapes, which can +match different numbers of bytes, are also not permitted. + + + +Possessive quantifiers can be used in conjunction with lookbehind assertions to +specify efficient matching at the end of the subject string. Consider a simple +pattern such as + + + +abcd$ + + + +when applied to a long string that does not match. Because matching +proceeds from left to right, GRegex will look for each "a" in the string +and then see if what follows matches the rest of the pattern. If the +pattern is specified as + + + +^.*abcd$ + + + +the initial .* matches the entire string at first, but when this fails +(because there is no following "a"), it backtracks to match all but the +last character, then all but the last two characters, and so on. Once +again the search for "a" covers the entire string, from right to left, +so we are no better off. However, if the pattern is written as + + + +^.*+(?<=abcd) + + + +there can be no backtracking for the .*+ item; it can match only the +entire string. The subsequent lookbehind assertion does a single test +on the last four characters. If it fails, the match fails immediately. +For long strings, this approach makes a significant difference to the +processing time. + + + + +Using multiple assertions + +Several assertions (of any sort) may occur in succession. For example, + + + +(?<=\d{3})(?<!999)foo + + + +matches "foo" preceded by three digits that are not "999". Notice that +each of the assertions is applied independently at the same point in +the string. First there is a check that the previous three +characters are all digits, and then there is a check that the same +three characters are not "999". This pattern does not match "foo" preceded +by six characters, the first of which are digits and the last +three of which are not "999". For example, it doesn’t match "123abcfoo". +A pattern to do that is + + + +(?<=\d{3}...)(?<!999)foo + + + +This time the first assertion looks at the preceding six characters, +checking that the first three are digits, and then the second assertion +checks that the preceding three characters are not "999". + + + +Assertions can be nested in any combination. For example, + + + +(?<=(?<!foo)bar)baz + + + +matches an occurrence of "baz" that is preceded by "bar" which in turn +is not preceded by "foo", while + + + +(?<=\d{3}(?!999)...)foo + + + +is another pattern that matches "foo" preceded by three digits and any +three characters that are not "999". + + + + + +Conditional subpatterns + +It is possible to cause the matching process to obey a subpattern +conditionally or to choose between two alternative subpatterns, depending +on the result of an assertion, or whether a previous capturing subpattern +matched or not. The two possible forms of conditional subpattern are + + + +(?(condition)yes-pattern) +(?(condition)yes-pattern|no-pattern) + + + +If the condition is satisfied, the yes-pattern is used; otherwise the +no-pattern (if present) is used. If there are more than two alternatives +in the subpattern, a compile-time error occurs. + + + +There are four kinds of condition: references to subpatterns, references to +recursion, a pseudo-condition called DEFINE, and assertions. + + + +Checking for a used subpattern by number + +If the text between the parentheses consists of a sequence of digits, the +condition is true if the capturing subpattern of that number has previously +matched. + + + +Consider the following pattern, which contains non-significant white space +to make it more readable (assume the G_REGEX_EXTENDED) +and to divide it into three parts for ease of discussion: + + + +( \( )? [^()]+ (?(1) \) ) + + + +The first part matches an optional opening parenthesis, and if that +character is present, sets it as the first captured substring. The second +part matches one or more characters that are not parentheses. The +third part is a conditional subpattern that tests whether the first set +of parentheses matched or not. If they did, that is, if string started +with an opening parenthesis, the condition is true, and so the yes-pattern +is executed and a closing parenthesis is required. Otherwise, +since no-pattern is not present, the subpattern matches nothing. In +other words, this pattern matches a sequence of non-parentheses, +optionally enclosed in parentheses. + + + + +Checking for a used subpattern by name + +Perl uses the syntax (?(<name>)...) or (?('name')...) to test for a used +subpattern by name, the Python syntax (?(name)...) is also recognized. However, +there is a possible ambiguity with this syntax, because subpattern names may +consist entirely of digits. GRegex looks first for a named subpattern; if it +cannot find one and the name consists entirely of digits, GRegex looks for a +subpattern of that number, which must be greater than zero. Using subpattern +names that consist entirely of digits is not recommended. + + + +Rewriting the above example to use a named subpattern gives this: + + + +(?<OPEN> \( )? [^()]+ (?(<OPEN>) \) ) + + + + +Checking for pattern recursion + +If the condition is the string (R), and there is no subpattern with the name R, +the condition is true if a recursive call to the whole pattern or any +subpattern has been made. If digits or a name preceded by ampersand follow the +letter R, for example: + + + +(?(R3)...) +(?(R&name)...) + + + +the condition is true if the most recent recursion is into the subpattern whose +number or name is given. This condition does not check the entire recursion +stack. + + + +At "top level", all these recursion test conditions are false. Recursive +patterns are described below. + + + + +Defining subpatterns for use by reference only + +If the condition is the string (DEFINE), and there is no subpattern with the +name DEFINE, the condition is always false. In this case, there may be only one +alternative in the subpattern. It is always skipped if control reaches this +point in the pattern; the idea of DEFINE is that it can be used to define +"subroutines" that can be referenced from elsewhere. (The use of "subroutines" +is described below.) For example, a pattern to match an IPv4 address could be +written like this (ignore whitespace and line breaks): + + + +(?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) ) +\b (?&byte) (\.(?&byte)){3} \b + + + +The first part of the pattern is a DEFINE group inside which another group +named "byte" is defined. This matches an individual component of an IPv4 +address (a number less than 256). When matching takes place, this part of the +pattern is skipped because DEFINE acts like a false condition. + + + +The rest of the pattern uses references to the named group to match the four +dot-separated components of an IPv4 address, insisting on a word boundary at +each end. + + + + +Assertion conditions + +If the condition is not in any of the above formats, it must be an +assertion. This may be a positive or negative lookahead or lookbehind +assertion. Consider this pattern, again containing non-significant +white space, and with the two alternatives on the second line: + + + +(?(?=[^a-z]*[a-z]) +\d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) + + + +The condition is a positive lookahead assertion that matches an +optional sequence of non-letters followed by a letter. In other words, +it tests for the presence of at least one letter in the string. If a +letter is found, the string is matched against the first alternative; +otherwise it is matched against the second. This pattern matches +strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are +letters and dd are digits. + + + + + +Comments + +The sequence (?# marks the start of a comment that continues up to the +next closing parenthesis. Nested parentheses are not permitted. The +characters that make up a comment play no part in the pattern matching +at all. + + + +If the G_REGEX_EXTENDED option is set, an unescaped # +character outside a character class introduces a comment that continues to +immediately after the next newline in the pattern. + + + + +Recursive patterns + +Consider the problem of matching a string in parentheses, allowing for +unlimited nested parentheses. Without the use of recursion, the best +that can be done is to use a pattern that matches up to some fixed +depth of nesting. It is not possible to handle an arbitrary nesting +depth. + + + +For some time, Perl has provided a facility that allows regular expressions to +recurse (amongst other things). It does this by interpolating Perl code in the +expression at run time, and the code can refer to the expression itself. A Perl +pattern using code interpolation to solve the parentheses problem can be +created like this: + + + +$re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x; + + + +The (?p{...}) item interpolates Perl code at run time, and in this case refers +recursively to the pattern in which it appears. + + + +Obviously, GRegex cannot support the interpolation of Perl code. Instead, it +supports special syntax for recursion of the entire pattern, and also for +individual subpattern recursion. This kind of recursion was introduced into +Perl at release 5.10. + + + +A special item that consists of (? followed by a number greater than zero and a +closing parenthesis is a recursive call of the subpattern of the given number, +provided that it occurs inside that subpattern. (If not, it is a "subroutine" +call, which is described in the next section.) The special item (?R) or (?0) is +a recursive call of the entire regular expression. + + + +In GRegex (like Python, but unlike Perl), a recursive subpattern call is always +treated as an atomic group. That is, once it has matched some of the subject +string, it is never re-entered, even if it contains untried alternatives and +there is a subsequent matching failure. + + + +This pattern solves the nested parentheses problem (assume the +G_REGEX_EXTENDED option is set so that white space is +ignored): + + + +\( ( (?>[^()]+) | (?R) )* \) + + + +First it matches an opening parenthesis. Then it matches any number of +substrings which can either be a sequence of non-parentheses, or a +recursive match of the pattern itself (that is, a correctly parenthesized +substring). Finally there is a closing parenthesis. + + + +If this were part of a larger pattern, you would not want to recurse +the entire pattern, so instead you could use this: + + + +( \( ( (?>[^()]+) | (?1) )* \) ) + + + +We have put the pattern into parentheses, and caused the recursion to +refer to them instead of the whole pattern. In a larger pattern, keeping +track of parenthesis numbers can be tricky. It may be more convenient to +use named parentheses instead. +The Perl syntax for this is (?&name); GRegex also supports the(?P>name) +syntax. We could rewrite the above example as follows: + + + +(?<pn> \( ( (?>[^()]+) | (?&pn) )* \) ) + + + +If there is more than one subpattern with the same name, the earliest one is +used. This particular example pattern contains nested unlimited repeats, and so +the use of atomic grouping for matching strings of non-parentheses is important +when applying the pattern to strings that do not match. +For example, when this pattern is applied to + + + +(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() + + + +it yields "no match" quickly. However, if atomic grouping is not used, +the match runs for a very long time indeed because there are so many +different ways the + and * repeats can carve up the string, and all +have to be tested before failure can be reported. + + + +At the end of a match, the values set for any capturing subpatterns are +those from the outermost level of the recursion at which the subpattern +value is set. + + + +If the pattern above is matched against + + + +(ab(cd)ef) + + + +the value for the capturing parentheses is "ef", which is the last +value taken on at the top level. If additional parentheses are added, +giving + + + +\( ( ( (?>[^()]+) | (?R) )* ) \) + ^ ^ + ^ ^ + + + +the string they capture is "ab(cd)ef", the contents of the top level +parentheses. + + + +Do not confuse the (?R) item with the condition (R), which tests for +recursion. Consider this pattern, which matches text in angle brackets, +allowing for arbitrary nesting. Only digits are allowed in nested +brackets (that is, when recursing), whereas any characters are permitted +at the outer level. + + + +< (?: (?(R) \d++ | [^<>]*+) | (?R)) * > + + + +In this pattern, (?(R) is the start of a conditional subpattern, with +two different alternatives for the recursive and non-recursive cases. +The (?R) item is the actual recursive call. + + + + +Subpatterns as subroutines + +If the syntax for a recursive subpattern reference (either by number or +by name) is used outside the parentheses to which it refers, it operates +like a subroutine in a programming language. The "called" subpattern may +be defined before or after the reference. An earlier example pointed out +that the pattern + + + +(sens|respons)e and \1ibility + + + +matches "sense and sensibility" and "response and responsibility", but +not "sense and responsibility". If instead the pattern + + + +(sens|respons)e and (?1)ibility + + + +is used, it does match "sense and responsibility" as well as the other +two strings. Another example is given in the discussion of DEFINE above. + + + +Like recursive subpatterns, a "subroutine" call is always treated as an atomic +group. That is, once it has matched some of the string, it is never +re-entered, even if it contains untried alternatives and there is a subsequent +matching failure. + + + +When a subpattern is used as a subroutine, processing options such as +case-independence are fixed when the subpattern is defined. They cannot be +changed for different calls. For example, consider this pattern: + + + +(abc)(?i:(?1)) + + + +It matches "abcabc". It does not match "abcABC" because the change of +processing option does not affect the called subpattern. + + + + + + +Copyright + +This document was copied and adapted from the PCRE documentation, +specifically from the man page for pcrepattern. +The original copyright note is: + + + +Copyright (c) 1997-2006 University of Cambridge. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the name of Google + Inc. nor the names of their contributors may be used to endorse or + promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + + +
diff --git a/docs/reference/glib/resources.xml b/docs/reference/glib/resources.xml new file mode 100644 index 0000000..c5cfa78 --- /dev/null +++ b/docs/reference/glib/resources.xml @@ -0,0 +1,77 @@ + + + + +Mailing lists and bug reports +3 +Mailing lists and bug reports + + + +Mailing lists and bug reports + +Getting help with GLib + + + + +Filing a bug report or feature request + + +If you encounter a bug, misfeature, or missing feature in GLib, please +file a bug report on the issue tracker at +https://gitlab.gnome.org/GNOME/glib/issues/new. +We'd also appreciate reports of incomplete or misleading information in +the GLib documentation; file those with the ‘Documentation’ label. + + + +Don't hesitate to file a bug report, even if you think we may know +about it already, or aren't sure of the details. Just give us as much +information as you have, and if it's already fixed or has already been +discussed, we'll add a note to that effect in the report. + + + +The issue tracker should definitely be used for feature requests, it's +not only for bugs. We track all GLib development in GitLab, so it's +the way to be sure the GLib developers won't forget about an issue. + + + + + +Code Contributions + + +If you develop a bugfix or enhancement for GLib, please open a merge request +for that in GitLab as well. All branches must be offered under the terms of +the GNU LGPL license, so be sure you are authorized to give us the branch +under those terms. + + + +If you want to discuss your branch before or after developing it, open a +topic on Discourse. +But be sure to create the GitLab merge request as well; if the branch is only +on the list and not in GitLab, it's likely to slip through the cracks. + + + + + +Discussions and user questions + + +The GLib issue tracker +is meant for discussions with actionable topics. If you want to ask a question +about using GLib, or discuss new features, you should use +the glib tag on Discourse. + + + + + + diff --git a/docs/reference/glib/running.xml b/docs/reference/glib/running.xml new file mode 100644 index 0000000..80a8da0 --- /dev/null +++ b/docs/reference/glib/running.xml @@ -0,0 +1,414 @@ + + + + +Running GLib Applications +3 +GLib Library + + + +Running GLib Applications + +How to run and debug your GLib application + + + + +Running and debugging GLib Applications + + +Environment variables + + + The runtime behaviour of GLib applications can be influenced by a + number of environment variables. + + + + Standard variables + + + GLib reads standard environment variables like LANG, + PATH, HOME, TMPDIR, + TZ and LOGNAME. + + + + + XDG directories + + + GLib consults the environment variables XDG_DATA_HOME, + XDG_DATA_DIRS, XDG_CONFIG_HOME, + XDG_CONFIG_DIRS, XDG_CACHE_HOME and + XDG_RUNTIME_DIR for the various XDG directories. + For more information, see the XDG basedir spec. + + + + + <envar>G_FILENAME_ENCODING</envar> + + + This environment variable can be set to a comma-separated list of character + set names. GLib assumes that filenames are encoded in the first character + set from that list rather than in UTF-8. The special token "@locale" can be + used to specify the character set for the current locale. + + + + + <envar>G_BROKEN_FILENAMES</envar> + + + If this environment variable is set, GLib assumes that filenames are in + the locale encoding rather than in UTF-8. G_FILENAME_ENCODING takes + priority over G_BROKEN_FILENAMES. + + + + + <envar>G_MESSAGES_PREFIXED</envar> + + + A list of log levels for which messages should be prefixed by the + program name and PID of the application. The default is to prefix + everything except G_LOG_LEVEL_MESSAGE and + G_LOG_LEVEL_INFO. + The possible values are + error, + warning, + critical, + message, + info and + debug. + You can also use the special values + all and + help. + + + This environment variable only affects the default log handler, + g_log_default_handler(). + + + + + <envar>G_MESSAGES_DEBUG</envar> + + + A space-separated list of log domains for which informational + and debug messages should be printed. By default, these + messages are not printed. + + + You can also use the special value all. + + + This environment variable only affects the default log handler, + g_log_default_handler(). + + + + + <envar>G_DEBUG</envar> + + + This environment variable can be set to a list of debug options, + which cause GLib to print out different types of debugging information. + + + fatal-warnings + Causes GLib to abort the program at the first call + to g_warning() or g_critical(). Use of this flag is not + recommended except when debugging. + + + + fatal-criticals + Causes GLib to abort the program at the first call + to g_critical(). This flag can be useful during debugging and + testing. + + + + gc-friendly + Newly allocated memory that isn't directly initialized, + as well as memory being freed will be reset to 0. The point here is + to allow memory checkers and similar programs that use Boehm GC alike + algorithms to produce more accurate results. + + + + resident-modules + All modules loaded by GModule will be made resident. + This can be useful for tracking memory leaks in modules which are + later unloaded; but it can also hide bugs where code is accessed + after the module would have normally been unloaded. + + + + bind-now-modules + All modules loaded by GModule will bind their symbols + at load time, even when the code uses %G_MODULE_BIND_LAZY. + + + + The special value all can be used to turn on all debug options. + The special value help can be used to print all available options. + + + + + <envar>G_SLICE</envar> + + + This environment variable allows reconfiguration of the GSlice + memory allocator. + + + always-malloc + This will cause all slices allocated through + g_slice_alloc() and released by g_slice_free1() to be actually + allocated via direct calls to g_malloc() and g_free(). + This is most useful for memory checkers and similar programs that + use Boehm GC alike algorithms to produce more accurate results. + It can also be in conjunction with debugging features of the system's + malloc() implementation such as glibc's MALLOC_CHECK_=2 to debug + erroneous slice allocation code, although + debug-blocks is usually a better suited debugging + tool. + + + + debug-blocks + Using this option (present since GLib 2.13) engages + extra code which performs sanity checks on the released memory + slices. Invalid slice addresses or slice sizes will be reported and + lead to a program halt. This option is for debugging scenarios. + In particular, client packages sporting their own test suite should + always enable this option when running tests. + Global slice validation is ensured by storing size and address + information for each allocated chunk, and maintaining a global + hash table of that data. That way, multi-thread scalability is + given up, and memory consumption is increased. However, the + resulting code usually performs acceptably well, possibly better + than with comparable memory checking carried out using external + tools. + An example of a memory corruption scenario that cannot be + reproduced with G_SLICE=always-malloc, but will + be caught by G_SLICE=debug-blocks is as follows: + + /* void* gives up type-safety */ + void *slist = g_slist_alloc (); + + /* corruption: sizeof (GSList) != sizeof (GList) */ + g_list_free (slist); + + + + + The special value all can be used to turn on all options. + The special value help can be used to print all available options. + + + + + <envar>G_RANDOM_VERSION</envar> + + + If this environment variable is set to '2.0', the outdated + pseudo-random number seeding and generation algorithms from + GLib 2.0 are used instead of the newer, better ones. You should + only set this variable if you have sequences of numbers that were + generated with Glib 2.0 that you need to reproduce exactly. + + + + + <envar>LIBCHARSET_ALIAS_DIR</envar> + + + Allows to specify a nonstandard location for the + charset.aliases file that is used by the + character set conversion routines. The default location is the + libdir specified at compilation time. + + + + + <envar>TZDIR</envar> + + + Allows to specify a nonstandard location for the timezone data files + that are used by the #GDateTime API. The default location is under + /usr/share/zoneinfo. For more information, + also look at the tzset manual page. + + + + + <envar>G_ENABLE_DIAGNOSTIC</envar> + + + If set to a non-zero value, this environment variable enables + diagnostic messages, like deprecation messages for GObject properties + and signals. + + + + + <envar>G_DEBUGGER</envar> + + + When running on Windows, if set to a non-empty string, GLib will + try to interpret the contents of this environment variable as + a command line to a debugger, and run it if the process crashes. + The debugger command line should contain %p and %e substitution + tokens, which GLib will replace with the process ID of the crashing + process and a handle to an event that the debugger should signal + to let GLib know that the debugger successfully attached to the + process. If %e is absent, or if the debugger is not able to + signal events, GLib will resume execution after 60 seconds. + If %p is absent, the debugger won't know which process to attach to, + and GLib will also resume execution after 60 seconds. + + + Additionally, even if G_DEBUGGER is not set, GLib would still + try to print basic exception information (code and address) into + stderr. + + + By default the debugger gets a new console allocated for it. + Set the G_DEBUGGER_OLD_CONSOLE environment variable to any + non-empty string to make the debugger inherit the console of + the crashing process. Normally this is only used by the GLib + testsuite. + + + The exception handler is written with the aim of making it as + simple as possible, to minimize the risk of it invoking + buggy functions or running buggy code, which would result + in exceptions being raised recursively. Because of that + it lacks most of the amenities that one would expect of GLib. + Namely, it does not support Unicode, so it is highly advisable + to only use ASCII characters in G_DEBUGGER. + + + See also G_VEH_CATCH. + + + + + <envar>G_VEH_CATCH</envar> + + + Catching some exceptions can break the program, since Windows + will sometimes use exceptions for execution flow control and + other purposes other than signalling a crash. + + + The G_VEH_CATCH environment variable augments + Vectored Exception Handling + on Windows (see G_DEBUGGER), allowing GLib to catch more + exceptions. Set this variable to a comma-separated list of + hexadecimal exception codes that should additionally be caught. + + + By default GLib will only catch Access Violation, Stack Overflow and + Illegal Instruction exceptions. + + + + + + +Locale + + +A number of interfaces in GLib depend on the current locale in which +an application is running. Therefore, most GLib-using applications should +call setlocale (LC_ALL, "") to set up the current +locale. + + + +On Windows, in a C program there are several locale concepts +that not necessarily are synchronized. On one hand, there is the +system default ANSI code-page, which determines what encoding is used +for file names handled by the C library's functions and the Win32 +API. (We are talking about the "narrow" functions here that take +character pointers, not the "wide" ones.) + + + +On the other hand, there is the C library's current locale. The +character set (code-page) used by that is not necessarily the same as +the system default ANSI code-page. Strings in this character set are +returned by functions like strftime(). + + + + + +GLib ships with a set of Python macros for the GDB debugger. These includes pretty +printers for lists, hashtables and GObject types. It also has a backtrace filter +that makes backtraces with signal emissions easier to read. + + + +To use this you need a version of GDB that supports Python scripting; anything +from 7.0 should be fine. You then need to install GLib in the same prefix as +GDB so that the Python GDB autoloaded files get installed in the right place +for GDB to pick up. + + + +General pretty printing should just happen without having to do anything special. +To get the signal emission filtered backtrace you must use the "new-backtrace" command +instead of the standard one. + + + +There is also a new command called gforeach that can be used to apply a command +on each item in a list. E.g. you can do + +gforeach i in some_list_variable: print *(GtkWidget *)l + +Which would print the contents of each widget in a list of widgets. + + + +SystemTap + + +SystemTap is a dynamic whole-system +analysis toolkit. GLib ships with a file libglib-2.0.so.*.stp which defines a +set of probe points, which you can hook into with custom SystemTap scripts. +See the files libglib-2.0.so.*.stp, libgobject-2.0.so.*.stp +and libgio-2.0.so.*.stp which +are in your shared SystemTap scripts directory. + + + + + +Memory statistics + + +g_mem_profile() will output a summary g_malloc() memory usage, if memory +profiling has been enabled by calling +g_mem_set_vtable (glib_mem_profiler_table) upon startup. + + + +If GLib has been configured with , +then g_slice_debug_tree_statistics() can be called in a debugger to +output details about the memory usage of the slice allocator. + + + + + diff --git a/docs/reference/glib/version.xml.in b/docs/reference/glib/version.xml.in new file mode 100644 index 0000000..af9b9c4 --- /dev/null +++ b/docs/reference/glib/version.xml.in @@ -0,0 +1 @@ +@GLIB_VERSION@ diff --git a/docs/reference/glib/xml/gtkdocentities.ent.in b/docs/reference/glib/xml/gtkdocentities.ent.in new file mode 100644 index 0000000..f12c9ff --- /dev/null +++ b/docs/reference/glib/xml/gtkdocentities.ent.in @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/reference/glib/xml/meson.build b/docs/reference/glib/xml/meson.build new file mode 100644 index 0000000..6aeb745 --- /dev/null +++ b/docs/reference/glib/xml/meson.build @@ -0,0 +1,14 @@ +ent_conf = configuration_data() +ent_conf.set('PACKAGE', 'glib') +ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new') +ent_conf.set('PACKAGE_NAME', 'glib') +ent_conf.set('PACKAGE_STRING', 'glib') +ent_conf.set('PACKAGE_TARNAME', 'glib') +ent_conf.set('PACKAGE_URL', 'FIXME') +ent_conf.set('PACKAGE_VERSION', glib_version) +ent_conf.set('PACKAGE_API_VERSION', glib_api_version) +configure_file( + input: 'gtkdocentities.ent.in', + output: 'gtkdocentities.ent', + configuration: ent_conf +) diff --git a/docs/reference/gobject/glib-genmarshal.xml b/docs/reference/gobject/glib-genmarshal.xml new file mode 100644 index 0000000..2b3e86f --- /dev/null +++ b/docs/reference/gobject/glib-genmarshal.xml @@ -0,0 +1,579 @@ + + + + glib-genmarshal + GObject + + + Developer + Emmanuele + Bassi + + + Original developer + Tim + Janik + + + + + +glib-genmarshal +1 +User Commands + + + +glib-genmarshal +C code marshaller generation utility for GLib closures + + + + +glib-genmarshal +OPTION +FILE + + + +Description +glib-genmarshal is a small utility that generates C code +marshallers for callback functions of the GClosure mechanism in the GObject +sublibrary of GLib. The marshaller functions have a standard signature, +they get passed in the invoking closure, an array of value structures holding +the callback function parameters and a value structure for the return value +of the callback. The marshaller is then responsible to call the respective C +code function of the closure with all the parameters on the stack and to +collect its return value. + + +glib-genmarshal takes a list of marshallers to generate as +input. The marshaller list is either read from files passed as additional arguments +on the command line; or from standard input, by using - as the +input file. + + +Marshaller list format + +The marshaller lists are processed line by line, a line can contain a +comment in the form of + +# this is a comment + +or a marshaller specification of the form + +RTYPE:PTYPE +RTYPE:PTYPE,PTYPE +RTYPE:PTYPE,PTYPE,PTYPE + + + +The RTYPE part specifies the callback's return +type and the PTYPEs right to the colon specify +the callback's parameter list, except for the first and the last arguments +which are always pointers. + + +Parameter types + +Currently, the following types are supported: + + +VOID + +indicates no return type, or no extra parameters. +If VOID is used as the parameter list, no +additional parameters may be present. + + + + +BOOLEAN + +for boolean types (gboolean) + + + + +CHAR + +for signed char types (gchar) + + + + +UCHAR + +for unsigned char types (guchar) + + + + +INT + +for signed integer types (gint) + + + + +UINT + +for unsigned integer types (guint) + + + + +LONG + +for signed long integer types (glong) + + + + +ULONG + +for unsigned long integer types (gulong) + + + + +INT64 + +for signed 64bit integer types (gint64) + + + + +UINT64 + +for unsigned 64bit integer types (guint64) + + + + +ENUM + +for enumeration types (gint) + + + + +FLAGS + +for flag enumeration types (guint) + + + + +FLOAT + +for single-precision float types (gfloat) + + + + +DOUBLE + +for double-precision float types (gdouble) + + + + +STRING + +for string types (gchar*) + + + + +BOXED + +for boxed (anonymous but reference counted) types (GBoxed*) + + + + +PARAM + +for GParamSpec or derived types (GParamSpec*) + + + + +POINTER + +for anonymous pointer types (gpointer) + + + + +OBJECT + +for GObject or derived types (GObject*) + + + + +VARIANT + +for GVariant types (GVariant*) + + + + +NONE + +deprecated alias for VOID + + + + +BOOL + +deprecated alias for BOOLEAN + + + + + + + +Options + + + + + +Generate header file contents of the marshallers. This option is mutually +exclusive with the option. + + + + + + +Generate C code file contents of the marshallers. This option is mutually +exclusive with the option. + + + + + + +Specify marshaller prefix. The default prefix is `g_cclosure_user_marshal'. + + + + + + +Skip source location remarks in generated comments. + + + + + + +Use the standard marshallers of the GObject library, and include +glib-object.h in generated header files. This +option is mutually exclusive with the +option. + + + + + + +Do not use the standard marshallers of the GObject library, and skip +glib-object.h include directive in generated header files. +This option is mutually exclusive with the option. + + + + + + +Mark generated functions as internal, using G_GNUC_INTERNAL. + + + + + + +Generate valist marshallers, for use with g_signal_set_va_marshaller(). + + + + +, + +Print version information. + + + + + + +Make warnings fatal, that is, exit immediately once a warning occurs. + + + + +, + +Print brief help and exit. + + + + +, + +Print version and exit. + + + + + + +Write output to FILE instead of the standard output. + + + + + + +Generate function prototypes before the function definition in the C source +file, in order to avoid a missing-prototypes compiler +warning. This option is only useful when using the +option. + + + + + + +Use the once pragma instead of an old style header guard +when generating the C header file. This option is only useful when using the + option. + + + + + + +Adds a #include directive for the given file in the C +source file. This option is only useful when using the +option. + + + + + + +Adds a #define C pre-processor directive for +SYMBOL and its given VALUE, +or "1" if the value is unset. You can use this option multiple times; if you do, +all the symbols will be defined in the same order given on the command line, before +the symbols undefined using the option. This option is only +useful when using the option. + + + + + + +Adds a #undef C pre-processor directive to undefine the +given SYMBOL. You can use this option multiple times; +if you do, all the symbols will be undefined in the same order given on the +command line, after the symbols defined using the option. +This option is only useful when using the option. + + + + + + +Minimizes the output of glib-genmarshal, by printing only +warnings and errors. This option is mutually exclusive with the + option. + + + + + + +Increases the verbosity of glib-genmarshal, by printing +debugging information. This option is mutually exclusive with the + option. + + + + + + +Using <command>glib-genmarshal</command> with Meson + +Meson supports generating closure marshallers using glib-genmarshal +out of the box in its "gnome" module. + + + +In your meson.build file you will typically call the +gnome.genmarshal() method with the source list of marshallers +to generate: + + +gnome = import('gnome') +marshal_files = gnome.genmarshal('marshal', + sources: 'marshal.list', + internal: true, +) + + +The marshal_files variable will contain an array of two elements +in the following order: + + + a build target for the source file + a build target for the header file + + +You should use the returned objects to provide a dependency on every other +build target that references the source or header file; for instance, if you +are using the source to build a library: + + +mainlib = library('project', + sources: project_sources + marshal_files, + ... +) + + +Additionally, if you are including the generated header file inside a build +target that depends on the library you just built, you must ensure that the +internal dependency includes the generated header as a required source file: + + +mainlib_dep = declare_dependency(sources: marshal_files[1], link_with: mainlib) + + +You should not include the generated source file as well, otherwise it will +be built separately for every target that depends on it, causing build +failures. To know more about why all this is required, please refer to the + +corresponding Meson FAQ entry. + + +For more information on how to use the method, see the +Meson +documentation for gnome.genmarshal(). + + + +Using <command>glib-genmarshal</command> with Autotools + +In order to use glib-genmarshal in your project when using +Autotools as the build system, you will first need to modify your +configure.ac file to ensure you find the appropriate +command using pkg-config, similarly as to how you discover +the compiler and linker flags for GLib. + + +PKG_PROG_PKG_CONFIG([0.28]) + +PKG_CHECK_VAR([GLIB_GENMARSHAL], [glib-2.0], [glib_genmarshal]) + + +In your Makefile.am file you will typically need very +simple rules to generate the C files needed for the build. + + +marshal.h: marshal.list + $(AM_V_GEN)$(GLIB_GENMARSHAL) \ + --header \ + --output=$@ \ + $< + +marshal.c: marshal.list marshal.h + $(AM_V_GEN)$(GLIB_GENMARSHAL) \ + --include-header=marshal.h \ + --body \ + --output=$@ \ + $< + +BUILT_SOURCES += marshal.h marshal.c +CLEANFILES += marshal.h marshal.c +EXTRA_DIST += marshal.list + + +In the example above, the first rule generates the header file and depends on +a marshal.list file in order to regenerate the result in +case the marshallers list is updated. The second rule generates the source file +for the same marshal.list, and includes the file generated +by the header rule. + + + +Example + +To generate marshallers for the following callback functions: + + +void foo (gpointer data1, + gpointer data2); +void bar (gpointer data1, + gint param1, + gpointer data2); +gfloat baz (gpointer data1, + gboolean param1, + guchar param2, + gpointer data2); + + +The marshaller.list file has to look like this: + + +VOID:VOID +VOID:INT +FLOAT:BOOLEAN,UCHAR + + +and you call glib-genmarshal like this: + + +glib-genmarshal --header marshaller.list > marshaller.h +glib-genmarshal --body marshaller.list > marshaller.c + + +The generated marshallers have the arguments encoded in their function name. +For this particular list, they are + + +g_cclosure_user_marshal_VOID__VOID(...), +g_cclosure_user_marshal_VOID__INT(...), +g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR(...). + + +They can be used directly for GClosures or be passed in as the +GSignalCMarshaller c_marshaller; argument upon creation of signals: + + +GClosure *cc_foo, *cc_bar, *cc_baz; + +cc_foo = g_cclosure_new (NULL, foo, NULL); +g_closure_set_marshal (cc_foo, g_cclosure_user_marshal_VOID__VOID); +cc_bar = g_cclosure_new (NULL, bar, NULL); +g_closure_set_marshal (cc_bar, g_cclosure_user_marshal_VOID__INT); +cc_baz = g_cclosure_new (NULL, baz, NULL); +g_closure_set_marshal (cc_baz, g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR); + + +See also + + +glib-mkenums +1 + + + + diff --git a/docs/reference/gobject/glib-mkenums.xml b/docs/reference/gobject/glib-mkenums.xml new file mode 100644 index 0000000..ce250a3 --- /dev/null +++ b/docs/reference/gobject/glib-mkenums.xml @@ -0,0 +1,653 @@ + + + + gdbus + GObject + + + Developer + Owen + Taylor + + + + + +glib-mkenums +1 +User Commands + + + +glib-mkenums +C language enum description generation utility + + + + +glib-mkenums +OPTION +FILE + + + +Description +glib-mkenums is a small utility that parses C code to +extract enum definitions and produces enum descriptions based on text templates +specified by the user. Typically, you can use this tool to generate enumeration +types for the GType type system, for GObject properties and signal marshalling; +additionally, you can use it to generate enumeration values of GSettings schemas. + + +glib-mkenums takes a list of valid C code files as +input. The options specified control the text that generated, substituting various +keywords enclosed in @ characters in the templates. + + +Production text substitutions + +Certain keywords enclosed in @ characters will be substituted in the +emitted text. For the substitution examples of the keywords below, +the following example enum definition is assumed: + + +typedef enum +{ + PREFIX_THE_XVALUE = 1 << 3, + PREFIX_ANOTHER_VALUE = 1 << 4 +} PrefixTheXEnum; + + + +@EnumName@> + +The name of the enum currently being processed, enum names are assumed to be +properly namespaced and to use mixed capitalization to separate +words (e.g. PrefixTheXEnum). + + + + +@enum_name@ + +The enum name with words lowercase and word-separated by underscores +(e.g. prefix_the_xenum). + + + + +@ENUMNAME@ + +The enum name with words uppercase and word-separated by underscores +(e.g. PREFIX_THE_XENUM). + + + + +@ENUMSHORT@ + +The enum name with words uppercase and word-separated by underscores, +prefix stripped (e.g. THE_XENUM). + + + + +@ENUMPREFIX@ + +The prefix of the enum name (e.g. PREFIX). + + + + +@VALUENAME@ + +The enum value name currently being processed with words uppercase and +word-separated by underscores, +this is the assumed literal notation of enum values in the C sources +(e.g. PREFIX_THE_XVALUE). + + + + +@valuenick@ + +A nick name for the enum value currently being processed, this is usually +generated by stripping common prefix words of all the enum values of the +current enum, the words are lowercase and underscores are substituted by a +minus (e.g. the-xvalue). + + + + +@valuenum@ + +The integer value for the enum value currently being processed. If the +evaluation fails then glib-mkenums will exit with an +error status, but this only happens if @valuenum@ +appears in your value production template. (Since: 2.26) + + + + +@type@ + +This is substituted either by "enum" or "flags", depending on whether the +enum value definitions contained bit-shift operators or not (e.g. flags). + + + + +@Type@ + +The same as @type@ with the first letter capitalized (e.g. Flags). + + + + +@TYPE@ + +The same as @type@ with all letters uppercased (e.g. FLAGS). + + + + +@filename@ + +The full path of the input file currently being processed (e.g. /build/environment/project/src/foo.h). + + + + +@basename@ + +The base name of the input file currently being processed (e.g. foo.h). +Typically you want to use @basename@ in place of @filename@ +in your templates, to improve the reproducibility of the build. (Since: 2.22) + + + + +Trigraph extensions + +Some C comments are treated specially in the parsed enum definitions, +such comments start out with the trigraph sequence /*< +and end with the trigraph sequence >*/. + + +The following options can be specified per enum definition: + + +skip + +Indicates this enum definition should be skipped. + + + +flags + +Indicates this enum should be treated as a flags definition. + + + +underscore_name + +Specifies the word separation used in the *_get_type() +function. For instance, /*< underscore_name=gnome_vfs_uri_hide_options >*/. + + + +since + +Specifies the version tag that will be used to substitute the @enumsince@ +keyword in the template, useful when documenting methods generated from the enums +(e.g. Since: @enumsince@). (Since: 2.66) + + + + +The following options can be specified per value definition: + + +skip + +Indicates the value should be skipped. + + + +nick + +Specifies the otherwise auto-generated nickname. + + + + +Examples: + +typedef enum /*< skip >*/ +{ + PREFIX_FOO +} PrefixThisEnumWillBeSkipped; +typedef enum /*< flags,prefix=PREFIX,since=1.0 >*/ +{ + PREFIX_THE_ZEROTH_VALUE, /*< skip >*/ + PREFIX_THE_FIRST_VALUE, + PREFIX_THE_SECOND_VALUE, + PREFIX_THE_THIRD_VALUE, /*< nick=the-last-value >*/ +} PrefixTheFlagsEnum; + + + + +Options + + + + TEXT + +Emits TEXT prior to processing input files. + + +You can specify this option multiple times, and the TEXT +will be concatenated. + + +When used along with a template file, TEXT +will be prepended to the template's file-header section. + + + + + TEXT + +Emits TEXT every time a new input file +is being processed. + + +You can specify this option multiple times, and the TEXT +will be concatenated. + + +When used along with a template file, TEXT +will be appended to the template's file-production section. + + + + + TEXT + +Emits TEXT after all input files have been +processed. + + +You can specify this option multiple times, and the TEXT +will be concatenated. + + +When used along with a template file, TEXT +will be appended to the template's file-tail section. + + + + + TEXT + +Emits TEXT every time an enum is encountered +in the input files. + + + + + TEXT + +Emits TEXT before iterating over the set of +values of an enum. + + +You can specify this option multiple times, and the TEXT +will be concatenated. + + +When used along with a template file, TEXT +will be prepended to the template's value-header section. + + + + + TEXT + +Emits TEXT for every value of an enum. + + +You can specify this option multiple times, and the TEXT +will be concatenated. + + +When used along with a template file, TEXT +will be appended to the template's value-production section. + + + + + TEXT + +Emits TEXT after iterating over all values +of an enum. + + +You can specify this option multiple times, and the TEXT +will be concatenated. + + +When used along with a template file, TEXT +will be appended to the template's value-tail section. + + + + + TEXT + +Template for auto-generated comments, the default (for C code generations) is +"/* @comment@ */". + + + + + FILE + +Read templates from the given file. The templates are enclosed in +specially-formatted C comments: + + +/*** BEGIN section ***/ +/*** END section ***/ + + +section may be file-header, +file-production, file-tail, +enumeration-production, value-header, +value-production, value-tail or +comment. + + + + + PREFIX + +Indicates what portion of the enum name should be interpreted as the +prefix (eg, the "Gtk" in +"GtkDirectionType"). Normally this will be figured +out automatically, but you may need to override the default if your +namespace is capitalized oddly. + + + + + PREFIX + +Indicates what prefix should be used to correspond to the identifier +prefix in related C function names (eg, the "gtk" +in "gtk_direction_type_get_type". Equivalently, +this is the lowercase version of the prefix component of the enum +value names (eg, the "GTK" in +"GTK_DIR_UP". The default value is the identifier +prefix, converted to lowercase. + + + + + + +Print brief help and exit. + + + + + + +Print version and exit. + + + + + + +Write output to FILE instead of stdout. + + + + + + +When passed as the sole argument, read and parse the actual arguments from +RSPFILE. Useful on systems with a low command-line length +limit. For example, Windows has a limit of 8191 characters. + + + + + + +Using templates + +Instead of passing the various sections of the generated file to the command +line of glib-mkenums, it's strongly recommended to use a +template file, especially for generating C sources. + + + +A C header template file will typically look like this: + + +/*** BEGIN file-header ***/ +#pragma once + +/* Include the main project header */ +#include "project.h" + +G_BEGIN_DECLS +/*** END file-header ***/ + +/*** BEGIN file-production ***/ + +/* enumerations from "@basename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType @enum_name@_get_type (void) G_GNUC_CONST; +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) +/*** END value-header ***/ + +/*** BEGIN file-tail ***/ +G_END_DECLS +/*** END file-tail ***/ + + + +A C source template file will typically look like this: + + +/*** BEGIN file-header ***/ +#include "config.h" +#include "enum-types.h" + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +/* enumerations from "@basename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static gsize static_g_@type@_type_id; + + if (g_once_init_enter (&static_g_@type@_type_id)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + + GType g_@type@_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + + g_once_init_leave (&static_g_@type@_type_id, g_@type@_type_id); + } + return static_g_@type@_type_id; +} + +/*** END value-tail ***/ + + + +Template files are easier to modify and update, and can be used +to generate various types of outputs using the same command line +or tools during the build. + + + +Using glib-mkenums with Meson + +Meson supports generating enumeration types using glib-mkenums +out of the box in its "gnome" module. + + + +In your meson.build file you will typically call the +gnome.mkenums_simple() method to generate idiomatic enumeration +types from a list of headers to inspect: + + +project_headers = [ + 'project-foo.h', + 'project-bar.h', + 'project-baz.h', +] + +gnome = import('gnome') +enum_files = gnome.mkenums_simple('enum-types', + sources: project_headers, +) + + + +The enum_files variable will contain an array of two elements +in the following order: + + + a build target for the source file + a build target for the header file + + +You should use the returned objects to provide a dependency on every other +build target that references the source or header file; for instance, if you +are using the source to build a library: + + +mainlib = library('project', + sources: project_sources + enum_files, + ... +) + + +Additionally, if you are including the generated header file inside a build +target that depends on the library you just built, you must ensure that the +internal dependency includes the generated header as a required source file: + + +mainlib_dep = declare_dependency(sources: enum_files[1], link_with: mainlib) + + +You should not include the generated source file as well, otherwise it will +be built separately for every target that depends on it, causing build +failures. To know more about why all this is required, please refer to the + +corresponding Meson FAQ entry. + + + +If you are generating C header and source files that require special +templates, you can use gnome.mkenums() to provide those +headers, for instance: + + +enum_files = gnome.mkenums('enum-types', + sources: project_headers, + h_template: 'enum-types.h.in', + c_template: 'enum-types.c.in', + install_header: true, +) + + +For more information, see the Meson +documentation for gnome.mkenums(). + + + +Using glib-mkenums with Autotools + +In order to use glib-mkenums in your project when using +Autotools as the build system, you will first need to modify your +configure.ac file to ensure you find the appropriate +command using pkg-config, similarly as to how you discover +the compiler and linker flags for GLib. + + +PKG_PROG_PKG_CONFIG([0.28]) + +PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.0], [glib_mkenums]) + + +In your Makefile.am file you will typically use rules +like these: + + +# A list of headers to inspect +project_headers = \ + project-foo.h \ + project-bar.h \ + project-baz.h + +enum-types.h: $(project_headers) enum-types.h.in + $(AM_V_GEN)$(GLIB_MKENUMS) \ + --template=enum-types.h.in \ + --output=$@ \ + $(project_headers) + +enum-types.c: $(project_headers) enum-types.c.in enum-types.h + $(AM_V_GEN)$(GLIB_MKENUMS) \ + --template=enum-types.c.in \ + --output=$@ \ + $(project_headers) + +# Build the enum types files before every other target +BUILT_SOURCES += enum-types.h enum-types.c +CLEANFILES += enum-types.h enum-types.c +EXTRA_DIST += enum-types.h.in enum-types.c.in + + +In the example above, we have a variable called project_headers +where we reference all header files we want to inspect for generating enumeration +GTypes. In the enum-types.h rule we use glib-mkenums +with a template called enum-types.h.in in order to generate the +header file; similarly, in the enum-types.c rule we use a +template called enum-types.c.in. + + + +See also + + +glib-genmarshal +1 + + + + diff --git a/docs/reference/gobject/gobject-docs.xml b/docs/reference/gobject/gobject-docs.xml new file mode 100644 index 0000000..aa5a9c7 --- /dev/null +++ b/docs/reference/gobject/gobject-docs.xml @@ -0,0 +1,224 @@ + + + +]> + + + GObject Reference Manual + + for GObject &version; + The latest version of this documentation can be found on-line at + https://developer.gnome.org/gobject/unstable/. + + + + + Introduction + + Most modern programming languages come with their own native object + systems and additional fundamental algorithmic language constructs. + Just as GLib serves as an implementation of such fundamental + types and algorithms (linked lists, hash tables and so forth), the + GLib Object System provides the required implementations of a + flexible, extensible, and intentionally easy to map (into other + languages) object-oriented framework for C. + The substantial elements that are provided can be summarized as: + + + A generic type system to register arbitrary single-inherited + flat and deep derived types as well as interfaces for + structured types. + It takes care of creation, initialization and memory management + of the assorted object and class structures, maintains + parent/child relationships and deals with dynamic implementations + of such types. That is, their type specific implementations are + relocatable/unloadable during runtime. + + + A collection of fundamental type implementations, such as integers, + doubles, enums and structured types, to name a few. + + + A sample fundamental type implementation to base object hierarchies + upon - the GObject fundamental type. + + + A signal system that allows very flexible user customization of + virtual/overridable object methods and can serve as a powerful + notification mechanism. + + + An extensible parameter/value system, supporting all the provided + fundamental types that can be used to generically handle object + properties or otherwise parameterized types. + + + + + + + Concepts + + + + + + + + API Reference + + + + + + + + + + + + + + + + + + + + Tools Reference + + + + + + + + + + + Index + + + + Index of deprecated symbols + + + + Index of new symbols in 2.2 + + + + Index of new symbols in 2.4 + + + + Index of new symbols in 2.6 + + + + Index of new symbols in 2.8 + + + + Index of new symbols in 2.10 + + + + Index of new symbols in 2.12 + + + + Index of new symbols in 2.14 + + + + Index of new symbols in 2.18 + + + + Index of new symbols in 2.22 + + + + Index of new symbols in 2.24 + + + + Index of new symbols in 2.26 + + + + Index of new symbols in 2.28 + + + + Index of new symbols in 2.30 + + + + Index of new symbols in 2.32 + + + + Index of new symbols in 2.34 + + + + Index of new symbols in 2.36 + + + + Index of new symbols in 2.38 + + + + Index of new symbols in 2.40 + + + + Index of new symbols in 2.42 + + + + Index of new symbols in 2.44 + + + + Index of new symbols in 2.46 + + + + Index of new symbols in 2.54 + + + + Index of new symbols in 2.56 + + + + Index of new symbols in 2.62 + + + + Index of new symbols in 2.66 + + + + Index of new symbols in 2.68 + + + + Index of new symbols in 2.70 + + + + Index of new symbols in 2.72 + + + + + + diff --git a/docs/reference/gobject/gobject-overrides.txt b/docs/reference/gobject/gobject-overrides.txt new file mode 100644 index 0000000..e69de29 diff --git a/docs/reference/gobject/gobject-query.xml b/docs/reference/gobject/gobject-query.xml new file mode 100644 index 0000000..437d714 --- /dev/null +++ b/docs/reference/gobject/gobject-query.xml @@ -0,0 +1,123 @@ + + + + gobject-query + GObject + + + Developer + Tim + Janik + + + + + +gobject-query +1 +User Commands + + + +gobject-query +display a tree of types + + + + +gobject-query +froots +OPTION + + +gobject-query +tree +OPTION + + + +Description + +gobject-query is a small utility that draws a tree of +types. + + + +gobject-query takes a mandatory argument that specifies +whether it should iterate over the fundamental types or print a type tree. + + + +Commands + + + + +iterate over fundamental roots + + + + + +print type tree + + + + + +Options + + + + TYPE + +specify the root type + + + + + + +don't descend type tree + + + + + STRING + +specify indent string + + + + + STRING + +specify incremental indent string + + + + + + NUMBER + +specify line spacing + + + + +, + +Print brief help and exit. + + + + +, + +Print version and exit. + + + + + + diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt new file mode 100644 index 0000000..cbab924 --- /dev/null +++ b/docs/reference/gobject/gobject-sections.txt @@ -0,0 +1,1048 @@ +glib-object.h + +

+gtype +Type Information +GType +G_TYPE_FUNDAMENTAL +G_TYPE_FUNDAMENTAL_MAX +G_TYPE_MAKE_FUNDAMENTAL +G_TYPE_IS_ABSTRACT +G_TYPE_IS_DERIVED +G_TYPE_IS_FUNDAMENTAL +G_TYPE_IS_VALUE_TYPE +G_TYPE_HAS_VALUE_TABLE +G_TYPE_IS_CLASSED +G_TYPE_IS_INSTANTIATABLE +G_TYPE_IS_DERIVABLE +G_TYPE_IS_DEEP_DERIVABLE +G_TYPE_IS_INTERFACE +G_TYPE_IS_FINAL +GTypeInterface +GTypeInstance +GTypeClass +GTypeInfo +GTypeFundamentalInfo +GInterfaceInfo +GTypeValueTable +G_TYPE_FROM_INSTANCE +G_TYPE_FROM_CLASS +G_TYPE_FROM_INTERFACE +G_TYPE_INSTANCE_GET_CLASS +G_TYPE_INSTANCE_GET_INTERFACE +G_TYPE_INSTANCE_GET_PRIVATE +G_TYPE_CLASS_GET_PRIVATE +G_TYPE_CHECK_INSTANCE +G_TYPE_CHECK_INSTANCE_CAST +G_TYPE_CHECK_INSTANCE_TYPE +G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE +G_TYPE_CHECK_CLASS_CAST +G_TYPE_CHECK_CLASS_TYPE +G_TYPE_CHECK_VALUE +G_TYPE_CHECK_VALUE_TYPE +G_TYPE_FLAG_RESERVED_ID_BIT +g_type_init +GTypeDebugFlags +g_type_init_with_debug_flags +g_type_name +g_type_qname +g_type_from_name +g_type_parent +g_type_depth +g_type_next_base +g_type_is_a +g_type_class_ref +g_type_class_peek +g_type_class_peek_static +g_type_class_unref +g_type_class_peek_parent +g_type_class_add_private +g_type_add_class_private +g_type_interface_peek +g_type_interface_peek_parent +g_type_default_interface_ref +g_type_default_interface_peek +g_type_default_interface_unref +g_type_children +g_type_interfaces +g_type_interface_prerequisites +g_type_interface_instantiatable_prerequisite +g_type_set_qdata +g_type_get_qdata +g_type_query +GTypeQuery +GBaseInitFunc +GBaseFinalizeFunc +GClassInitFunc +GClassFinalizeFunc +GInstanceInitFunc +GInterfaceInitFunc +GInterfaceFinalizeFunc +GTypeClassCacheFunc +GTypeFlags +GTypeFundamentalFlags +g_type_register_static +g_type_register_static_simple +g_type_register_dynamic +g_type_register_fundamental +g_type_add_interface_static +g_type_add_interface_dynamic +g_type_interface_add_prerequisite +g_type_get_plugin +g_type_interface_get_plugin +g_type_fundamental_next +g_type_fundamental +g_type_create_instance +g_type_free_instance +g_type_add_class_cache_func +g_type_remove_class_cache_func +g_type_class_unref_uncached +g_type_add_interface_check +g_type_remove_interface_check +GTypeInterfaceCheckFunc +g_type_value_table_peek +g_type_ensure +g_type_get_type_registration_serial +g_type_get_instance_count + +G_DECLARE_FINAL_TYPE +G_DECLARE_DERIVABLE_TYPE +G_DECLARE_INTERFACE +G_DEFINE_TYPE +G_DEFINE_TYPE_WITH_PRIVATE +G_DEFINE_TYPE_WITH_CODE +G_DEFINE_ABSTRACT_TYPE +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE +G_DEFINE_ABSTRACT_TYPE_WITH_CODE +G_DEFINE_FINAL_TYPE +G_DEFINE_FINAL_TYPE_WITH_PRIVATE +G_DEFINE_FINAL_TYPE_WITH_CODE +G_ADD_PRIVATE +G_PRIVATE_OFFSET +G_PRIVATE_FIELD +G_PRIVATE_FIELD_P +G_DEFINE_INTERFACE +G_DEFINE_INTERFACE_WITH_CODE +G_IMPLEMENT_INTERFACE +G_DEFINE_TYPE_EXTENDED +G_DEFINE_BOXED_TYPE +G_DEFINE_BOXED_TYPE_WITH_CODE +G_DEFINE_POINTER_TYPE +G_DEFINE_POINTER_TYPE_WITH_CODE + + +G_TYPE_FUNDAMENTAL_SHIFT +g_type_check_instance +g_type_check_instance_cast +g_type_check_instance_is_a +g_type_check_instance_is_fundamentally_a +g_type_check_class_cast +g_type_check_class_is_a +g_type_check_is_value_type +g_type_check_value +g_type_check_value_holds +g_type_class_adjust_private_offset +g_type_add_instance_private +g_type_instance_get_private +g_type_class_get_instance_private_offset +g_type_class_get_private +g_type_test_flags +g_type_name_from_instance +g_type_name_from_class + + +G_TYPE_INVALID +G_TYPE_NONE +G_TYPE_INTERFACE +G_TYPE_CHAR +G_TYPE_UCHAR +G_TYPE_BOOLEAN +G_TYPE_INT +G_TYPE_UINT +G_TYPE_LONG +G_TYPE_ULONG +G_TYPE_INT64 +G_TYPE_UINT64 +G_TYPE_ENUM +G_TYPE_FLAGS +G_TYPE_FLOAT +G_TYPE_DOUBLE +G_TYPE_STRING +G_TYPE_POINTER +G_TYPE_BOXED +G_TYPE_PARAM +G_TYPE_OBJECT +G_TYPE_GTYPE +G_TYPE_VARIANT +G_TYPE_CHECKSUM + + +G_TYPE_RESERVED_GLIB_FIRST +G_TYPE_RESERVED_GLIB_LAST +G_TYPE_RESERVED_BSE_FIRST +G_TYPE_RESERVED_BSE_LAST +G_TYPE_RESERVED_USER_FIRST + + +GOBJECT_VAR +
+ +
+gtypeplugin +GTypePlugin +GTypePlugin +GTypePluginClass +GTypePluginUse +GTypePluginUnuse +GTypePluginCompleteTypeInfo +GTypePluginCompleteInterfaceInfo +g_type_plugin_use +g_type_plugin_unuse +g_type_plugin_complete_type_info +g_type_plugin_complete_interface_info + +G_TYPE_PLUGIN +G_IS_TYPE_PLUGIN +G_TYPE_TYPE_PLUGIN +g_type_plugin_get_type +G_TYPE_PLUGIN_CLASS +G_IS_TYPE_PLUGIN_CLASS +G_TYPE_PLUGIN_GET_CLASS +
+ +
+gtypemodule +GTypeModule +GTypeModule +GTypeModuleClass +g_type_module_use +g_type_module_unuse +g_type_module_set_name +g_type_module_register_type +g_type_module_add_interface +g_type_module_register_enum +g_type_module_register_flags + +G_DEFINE_DYNAMIC_TYPE +G_DEFINE_DYNAMIC_TYPE_EXTENDED +G_IMPLEMENT_INTERFACE_DYNAMIC +G_ADD_PRIVATE_DYNAMIC + + +G_TYPE_MODULE +G_IS_TYPE_MODULE +G_TYPE_TYPE_MODULE +g_type_module_get_type +G_TYPE_MODULE_CLASS +G_IS_TYPE_MODULE_CLASS +G_TYPE_MODULE_GET_CLASS +
+ +
+The Base Object Type +objects +GObject +GObjectClass +GObjectConstructParam +GObjectGetPropertyFunc +GObjectSetPropertyFunc +GObjectFinalizeFunc +G_TYPE_IS_OBJECT +G_OBJECT +G_IS_OBJECT +G_OBJECT_CLASS +G_IS_OBJECT_CLASS +G_OBJECT_GET_CLASS +G_OBJECT_TYPE +G_OBJECT_TYPE_NAME +G_OBJECT_CLASS_TYPE +G_OBJECT_CLASS_NAME +g_object_class_install_property +g_object_class_install_properties +g_object_class_find_property +g_object_class_list_properties +g_object_class_override_property +g_object_interface_install_property +g_object_interface_find_property +g_object_interface_list_properties +g_object_new +g_object_new_with_properties +g_object_newv +GParameter +g_object_ref +g_object_unref +g_object_ref_sink +g_object_take_ref +g_set_object +g_clear_object +GInitiallyUnowned +GInitiallyUnownedClass +G_TYPE_INITIALLY_UNOWNED +g_object_is_floating +g_object_force_floating +GWeakNotify +g_object_weak_ref +g_object_weak_unref +g_object_add_weak_pointer +g_object_remove_weak_pointer +g_set_weak_pointer +g_clear_weak_pointer +GToggleNotify +g_object_add_toggle_ref +g_object_remove_toggle_ref +g_object_connect +g_object_disconnect +g_object_set +g_object_setv +g_object_get +g_object_getv +g_object_notify +g_object_notify_by_pspec +g_object_freeze_notify +g_object_thaw_notify +g_object_get_data +g_object_set_data +g_object_set_data_full +g_object_steal_data +g_object_dup_data +g_object_replace_data +g_object_get_qdata +g_object_set_qdata +g_object_set_qdata_full +g_object_steal_qdata +g_object_dup_qdata +g_object_replace_qdata +g_object_set_property +g_object_get_property +g_object_new_valist +g_object_set_valist +g_object_get_valist +g_object_watch_closure +g_object_run_dispose +G_OBJECT_WARN_INVALID_PROPERTY_ID + + +GWeakRef +g_weak_ref_init +g_weak_ref_clear +g_weak_ref_get +g_weak_ref_set + + +g_assert_finalize_object + + +G_INITIALLY_UNOWNED +G_INITIALLY_UNOWNED_CLASS +G_INITIALLY_UNOWNED_GET_CLASS +G_IS_INITIALLY_UNOWNED +G_IS_INITIALLY_UNOWNED_CLASS + + +G_OBJECT_WARN_INVALID_PSPEC +g_initially_unowned_get_type +g_object_compat_control +g_object_get_type +
+ +
+Enumeration and Flag Types +enumerations_flags +GEnumClass +GFlagsClass +G_ENUM_CLASS_TYPE +G_ENUM_CLASS_TYPE_NAME +G_TYPE_IS_ENUM +G_ENUM_CLASS +G_IS_ENUM_CLASS +G_TYPE_IS_FLAGS +G_FLAGS_CLASS +G_IS_FLAGS_CLASS +G_FLAGS_CLASS_TYPE +G_FLAGS_CLASS_TYPE_NAME +GEnumValue +GFlagsValue +g_enum_get_value +g_enum_get_value_by_name +g_enum_get_value_by_nick +g_enum_to_string +g_flags_get_first_value +g_flags_get_value_by_name +g_flags_get_value_by_nick +g_flags_to_string +g_enum_register_static +g_flags_register_static +g_enum_complete_type_info +g_flags_complete_type_info +
+ +
+gboxed +Boxed Types +GBoxedCopyFunc +GBoxedFreeFunc +g_boxed_copy +g_boxed_free +g_boxed_type_register_static +g_pointer_type_register_static + + +G_TYPE_HASH_TABLE +G_TYPE_DATE +G_TYPE_GSTRING +G_TYPE_STRV +G_TYPE_REGEX +G_TYPE_MATCH_INFO +G_TYPE_ARRAY +G_TYPE_BYTE_ARRAY +G_TYPE_PTR_ARRAY +G_TYPE_BYTES +G_TYPE_VARIANT_TYPE +G_TYPE_ERROR +G_TYPE_DATE_TIME +G_TYPE_TIME_ZONE +G_TYPE_IO_CHANNEL +G_TYPE_IO_CONDITION +G_TYPE_VARIANT_BUILDER +G_TYPE_VARIANT_DICT +G_TYPE_KEY_FILE +G_TYPE_MAIN_CONTEXT +G_TYPE_MAIN_LOOP +G_TYPE_MAPPED_FILE +G_TYPE_MARKUP_PARSE_CONTEXT +G_TYPE_SOURCE +G_TYPE_POLLFD +G_TYPE_THREAD +G_TYPE_OPTION_GROUP +G_TYPE_URI +G_TYPE_TREE +G_TYPE_PATTERN_SPEC + + +G_TYPE_IS_BOXED + + +g_gstring_get_type +g_strv_get_type +g_date_get_type +g_hash_table_get_type +g_regex_get_type +g_match_info_get_type +g_array_get_type +g_byte_array_get_type +g_ptr_array_get_type +g_error_get_type +g_date_time_get_type +g_time_zone_get_type +g_variant_get_gtype +g_variant_type_get_gtype +g_variant_builder_get_type +g_variant_dict_get_type +g_gtype_get_type +g_main_context_get_type +g_main_loop_get_type +g_source_get_type +g_pollfd_get_type +g_bytes_get_type +g_key_file_get_type +g_checksum_get_type +g_mapped_file_get_type +g_markup_parse_context_get_type +g_thread_get_type +g_option_group_get_type +g_uri_get_type +g_tree_get_type +g_pattern_spec_get_type +
+ +
+Generic values +generic_values +G_VALUE_INIT +G_VALUE_HOLDS +G_VALUE_TYPE +G_VALUE_TYPE_NAME +G_TYPE_IS_VALUE +G_TYPE_IS_VALUE_ABSTRACT +G_IS_VALUE +GValue +G_TYPE_VALUE +G_TYPE_VALUE_ARRAY +g_value_init +g_value_copy +g_value_reset +g_value_unset +g_value_init_from_instance +g_value_set_instance +g_value_fits_pointer +g_value_peek_pointer +g_value_type_compatible +g_value_type_transformable +g_value_transform +GValueTransform +g_value_register_transform_func +g_strdup_value_contents + + +G_VALUE_NOCOPY_CONTENTS +g_value_get_type +g_value_array_get_type +
+ +
+Value arrays +value_arrays +GValueArray +g_value_array_get_nth +g_value_array_new +g_value_array_copy +g_value_array_free +g_value_array_append +g_value_array_prepend +g_value_array_insert +g_value_array_remove +g_value_array_sort +g_value_array_sort_with_data +
+ +
+GParamSpec +gparamspec +G_TYPE_IS_PARAM +G_PARAM_SPEC +G_IS_PARAM_SPEC +G_PARAM_SPEC_CLASS +G_IS_PARAM_SPEC_CLASS +G_PARAM_SPEC_GET_CLASS +G_PARAM_SPEC_TYPE +G_PARAM_SPEC_TYPE_NAME +G_PARAM_SPEC_VALUE_TYPE +GParamSpec +GParamSpecClass +GParamFlags +G_PARAM_STATIC_STRINGS +G_PARAM_MASK +G_PARAM_USER_SHIFT +g_param_spec_ref +g_param_spec_unref +g_param_spec_sink +g_param_spec_ref_sink +g_param_spec_get_default_value +g_param_value_set_default +g_param_value_defaults +g_param_value_validate +g_param_value_convert +g_param_values_cmp +g_param_spec_is_valid_name +g_param_spec_get_name +g_param_spec_get_name_quark +g_param_spec_get_nick +g_param_spec_get_blurb +g_param_spec_get_qdata +g_param_spec_set_qdata +g_param_spec_set_qdata_full +g_param_spec_steal_qdata +g_param_spec_get_redirect_target +g_param_spec_internal +GParamSpecTypeInfo +g_param_type_register_static +GParamSpecPool +g_param_spec_pool_new +g_param_spec_pool_insert +g_param_spec_pool_remove +g_param_spec_pool_lookup +g_param_spec_pool_list +g_param_spec_pool_list_owned +
+ +
+Standard Parameter and Value Types +param_value_types + + +G_IS_PARAM_SPEC_BOOLEAN +G_PARAM_SPEC_BOOLEAN +G_VALUE_HOLDS_BOOLEAN +G_TYPE_PARAM_BOOLEAN +GParamSpecBoolean +g_param_spec_boolean +g_value_set_boolean +g_value_get_boolean + + +G_IS_PARAM_SPEC_CHAR +G_PARAM_SPEC_CHAR +G_VALUE_HOLDS_CHAR +G_TYPE_PARAM_CHAR +GParamSpecChar +g_param_spec_char +g_value_set_char +g_value_get_char +g_value_get_schar +g_value_set_schar + + +G_IS_PARAM_SPEC_UCHAR +G_PARAM_SPEC_UCHAR +G_VALUE_HOLDS_UCHAR +G_TYPE_PARAM_UCHAR +GParamSpecUChar +g_param_spec_uchar +g_value_set_uchar +g_value_get_uchar + + +G_IS_PARAM_SPEC_INT +G_PARAM_SPEC_INT +G_VALUE_HOLDS_INT +G_TYPE_PARAM_INT +GParamSpecInt +g_param_spec_int +g_value_set_int +g_value_get_int + + +G_IS_PARAM_SPEC_UINT +G_PARAM_SPEC_UINT +G_VALUE_HOLDS_UINT +G_TYPE_PARAM_UINT +GParamSpecUInt +g_param_spec_uint +g_value_set_uint +g_value_get_uint + + +G_IS_PARAM_SPEC_LONG +G_PARAM_SPEC_LONG +G_VALUE_HOLDS_LONG +G_TYPE_PARAM_LONG +GParamSpecLong +g_param_spec_long +g_value_set_long +g_value_get_long + + +G_IS_PARAM_SPEC_ULONG +G_PARAM_SPEC_ULONG +G_VALUE_HOLDS_ULONG +G_TYPE_PARAM_ULONG +GParamSpecULong +g_param_spec_ulong +g_value_set_ulong +g_value_get_ulong + + +G_IS_PARAM_SPEC_INT64 +G_PARAM_SPEC_INT64 +G_VALUE_HOLDS_INT64 +G_TYPE_PARAM_INT64 +GParamSpecInt64 +g_param_spec_int64 +g_value_set_int64 +g_value_get_int64 + + +G_IS_PARAM_SPEC_UINT64 +G_PARAM_SPEC_UINT64 +G_VALUE_HOLDS_UINT64 +G_TYPE_PARAM_UINT64 +GParamSpecUInt64 +g_param_spec_uint64 +g_value_set_uint64 +g_value_get_uint64 + + +G_IS_PARAM_SPEC_FLOAT +G_PARAM_SPEC_FLOAT +G_VALUE_HOLDS_FLOAT +G_TYPE_PARAM_FLOAT +GParamSpecFloat +g_param_spec_float +g_value_set_float +g_value_get_float + + +G_IS_PARAM_SPEC_DOUBLE +G_PARAM_SPEC_DOUBLE +G_VALUE_HOLDS_DOUBLE +G_TYPE_PARAM_DOUBLE +GParamSpecDouble +g_param_spec_double +g_value_set_double +g_value_get_double + + +G_IS_PARAM_SPEC_ENUM +G_PARAM_SPEC_ENUM +G_VALUE_HOLDS_ENUM +G_TYPE_PARAM_ENUM +GParamSpecEnum +g_param_spec_enum +g_value_set_enum +g_value_get_enum + + +G_IS_PARAM_SPEC_FLAGS +G_PARAM_SPEC_FLAGS +G_VALUE_HOLDS_FLAGS +G_TYPE_PARAM_FLAGS +GParamSpecFlags +g_param_spec_flags +g_value_set_flags +g_value_get_flags + + +G_IS_PARAM_SPEC_STRING +G_PARAM_SPEC_STRING +G_VALUE_HOLDS_STRING +G_TYPE_PARAM_STRING +G_VALUE_IS_INTERNED_STRING +G_VALUE_INTERNED_STRING +GParamSpecString +gchararray +g_param_spec_string +g_value_set_string +g_value_set_static_string +g_value_take_string +g_value_set_string_take_ownership +g_value_get_string +g_value_dup_string +g_value_set_interned_string + + +G_IS_PARAM_SPEC_PARAM +G_PARAM_SPEC_PARAM +G_VALUE_HOLDS_PARAM +G_TYPE_PARAM_PARAM +GParamSpecParam +g_param_spec_param +g_value_set_param +g_value_take_param +g_value_set_param_take_ownership +g_value_get_param +g_value_dup_param + + +G_IS_PARAM_SPEC_BOXED +G_PARAM_SPEC_BOXED +G_VALUE_HOLDS_BOXED +G_TYPE_PARAM_BOXED +GParamSpecBoxed +g_param_spec_boxed +g_value_set_boxed +g_value_set_static_boxed +g_value_take_boxed +g_value_set_boxed_take_ownership +g_value_get_boxed +g_value_dup_boxed + + +G_IS_PARAM_SPEC_POINTER +G_PARAM_SPEC_POINTER +G_VALUE_HOLDS_POINTER +G_TYPE_PARAM_POINTER +GParamSpecPointer +g_param_spec_pointer +g_value_set_pointer +g_value_get_pointer + + +G_IS_PARAM_SPEC_OBJECT +G_PARAM_SPEC_OBJECT +G_VALUE_HOLDS_OBJECT +G_TYPE_PARAM_OBJECT +GParamSpecObject +g_param_spec_object +g_value_set_object +g_value_take_object +g_value_set_object_take_ownership +g_value_get_object +g_value_dup_object + + +G_IS_PARAM_SPEC_UNICHAR +G_PARAM_SPEC_UNICHAR +G_TYPE_PARAM_UNICHAR +GParamSpecUnichar +g_param_spec_unichar + + +G_IS_PARAM_SPEC_VALUE_ARRAY +G_PARAM_SPEC_VALUE_ARRAY +G_TYPE_PARAM_VALUE_ARRAY +GParamSpecValueArray +g_param_spec_value_array + + +G_IS_PARAM_SPEC_OVERRIDE +G_PARAM_SPEC_OVERRIDE +G_TYPE_PARAM_OVERRIDE +GParamSpecOverride +g_param_spec_override + + +G_IS_PARAM_SPEC_GTYPE +G_PARAM_SPEC_GTYPE +G_VALUE_HOLDS_GTYPE +G_TYPE_PARAM_GTYPE +GParamSpecGType +g_param_spec_gtype +g_value_get_gtype +g_value_set_gtype + + +G_IS_PARAM_SPEC_VARIANT +G_PARAM_SPEC_VARIANT +G_VALUE_HOLDS_VARIANT +G_TYPE_PARAM_VARIANT +GParamSpecVariant +g_param_spec_variant +g_value_get_variant +g_value_dup_variant +g_value_set_variant +g_value_take_variant + + +g_value_set_instance +g_param_spec_types +
+ +
+Varargs Value Collection +value_collection +glib-object.h,gobject/gvaluecollector.h +GTypeCValue +G_VALUE_COLLECT_INIT +G_VALUE_COLLECT +G_VALUE_COLLECT_SKIP +G_VALUE_LCOPY +G_VALUE_COLLECT_FORMAT_MAX_LENGTH +
+ +
+Signals +signals +GSignalInvocationHint +GSignalAccumulator +GSignalCMarshaller +GSignalCVaMarshaller +GSignalEmissionHook +GSignalFlags +GSignalMatchType +GSignalQuery +G_SIGNAL_TYPE_STATIC_SCOPE +G_SIGNAL_MATCH_MASK +G_SIGNAL_FLAGS_MASK +g_signal_new +g_signal_newv +g_signal_new_valist +g_signal_set_va_marshaller +g_signal_query +g_signal_lookup +g_signal_name +g_signal_list_ids +g_signal_emit +g_signal_emit_by_name +g_signal_emitv +g_signal_emit_valist +g_signal_connect +g_signal_connect_after +g_signal_connect_swapped +g_signal_connect_object +GConnectFlags +g_signal_connect_data +g_signal_connect_closure +g_signal_connect_closure_by_id +g_signal_handler_block +g_signal_handler_unblock +g_signal_handler_disconnect +g_signal_handler_find +g_signal_handlers_block_matched +g_signal_handlers_unblock_matched +g_signal_handlers_disconnect_matched +g_signal_handler_is_connected +g_signal_handlers_block_by_func +g_signal_handlers_unblock_by_func +g_signal_handlers_disconnect_by_func +g_signal_handlers_disconnect_by_data +g_signal_has_handler_pending +g_signal_stop_emission +g_signal_stop_emission_by_name +g_signal_override_class_closure +g_signal_chain_from_overridden +g_signal_new_class_handler +g_signal_override_class_handler +g_signal_chain_from_overridden_handler +g_signal_add_emission_hook +g_signal_remove_emission_hook +g_signal_is_valid_name +g_signal_parse_name +g_signal_get_invocation_hint +g_signal_type_cclosure_new +g_signal_accumulator_first_wins +g_signal_accumulator_true_handled +g_clear_signal_handler + +g_signal_handlers_destroy +
+ +
+gclosure +Closures +G_CLOSURE_NEEDS_MARSHAL +G_CLOSURE_N_NOTIFIERS +G_CCLOSURE_SWAP_DATA +G_CALLBACK +GCallback +GClosure +G_TYPE_CLOSURE +GCClosure +GClosureMarshal +GVaClosureMarshal +GClosureNotify +g_cclosure_new +g_cclosure_new_swap +g_cclosure_new_object +g_cclosure_new_object_swap +g_cclosure_marshal_generic +g_closure_new_object +g_closure_ref +g_closure_sink +g_closure_unref +g_closure_invoke +g_closure_invalidate +g_closure_add_finalize_notifier +g_closure_add_invalidate_notifier +g_closure_remove_finalize_notifier +g_closure_remove_invalidate_notifier +g_closure_new_simple +g_closure_set_marshal +g_closure_add_marshal_guards +g_closure_set_meta_marshal +g_source_set_closure +g_source_set_dummy_callback + + +g_cclosure_marshal_VOID__VOID +g_cclosure_marshal_VOID__BOOLEAN +g_cclosure_marshal_VOID__CHAR +g_cclosure_marshal_VOID__UCHAR +g_cclosure_marshal_VOID__INT +g_cclosure_marshal_VOID__UINT +g_cclosure_marshal_VOID__LONG +g_cclosure_marshal_VOID__ULONG +g_cclosure_marshal_VOID__ENUM +g_cclosure_marshal_VOID__FLAGS +g_cclosure_marshal_VOID__FLOAT +g_cclosure_marshal_VOID__DOUBLE +g_cclosure_marshal_VOID__STRING +g_cclosure_marshal_VOID__PARAM +g_cclosure_marshal_VOID__BOXED +g_cclosure_marshal_VOID__POINTER +g_cclosure_marshal_VOID__OBJECT +g_cclosure_marshal_VOID__VARIANT +g_cclosure_marshal_STRING__OBJECT_POINTER +g_cclosure_marshal_VOID__UINT_POINTER +g_cclosure_marshal_BOOLEAN__FLAGS +g_cclosure_marshal_BOOL__FLAGS +g_cclosure_marshal_BOOLEAN__BOXED_BOXED +g_cclosure_marshal_BOOL__BOXED_BOXED + + +g_cclosure_marshal_generic_va +g_cclosure_marshal_VOID__VOIDv +g_cclosure_marshal_VOID__BOOLEANv +g_cclosure_marshal_VOID__CHARv +g_cclosure_marshal_VOID__UCHARv +g_cclosure_marshal_VOID__INTv +g_cclosure_marshal_VOID__UINTv +g_cclosure_marshal_VOID__LONGv +g_cclosure_marshal_VOID__ULONGv +g_cclosure_marshal_VOID__ENUMv +g_cclosure_marshal_VOID__FLAGSv +g_cclosure_marshal_VOID__FLOATv +g_cclosure_marshal_VOID__DOUBLEv +g_cclosure_marshal_VOID__STRINGv +g_cclosure_marshal_VOID__PARAMv +g_cclosure_marshal_VOID__BOXEDv +g_cclosure_marshal_VOID__POINTERv +g_cclosure_marshal_VOID__OBJECTv +g_cclosure_marshal_VOID__VARIANTv +g_cclosure_marshal_STRING__OBJECT_POINTERv +g_cclosure_marshal_VOID__UINT_POINTERv +g_cclosure_marshal_BOOLEAN__FLAGSv +g_cclosure_marshal_BOOLEAN__BOXED_BOXEDv + + +GClosureNotifyData +g_closure_get_type +g_io_channel_get_type +g_io_condition_get_type +
+ +
+gbinding +GBinding +GBindingFlags +g_binding_get_source +g_binding_dup_source +g_binding_get_source_property +g_binding_get_target +g_binding_dup_target +g_binding_get_target_property +g_binding_get_flags +g_binding_unbind + +g_object_bind_property +GBindingTransformFunc +g_object_bind_property_full +g_object_bind_property_with_closures + +G_TYPE_BINDING +G_TYPE_BINDING_FLAGS +G_BINDING +G_IS_BINDING + +g_binding_flags_get_type +g_binding_get_type +
+ +
+gbindinggroup +GBindingGroup +g_binding_group_new +g_binding_group_dup_source +g_binding_group_set_source +g_binding_group_bind +g_binding_group_bind_full +g_binding_group_bind_with_closures + +G_TYPE_BINDING_GROUP +G_TYPE_BINDING_GROUP_CLASS +G_BINDING_GROUP +G_IS_BINDING_GROUP + +g_binding_group_get_type +
+ +
+gsignalgroup +GSignalGroup +g_signal_group_block +g_signal_group_connect +g_signal_group_connect_after +g_signal_group_connect_data +g_signal_group_connect_object +g_signal_group_connect_swapped +g_signal_group_dup_target +g_signal_group_get_type +g_signal_group_new +g_signal_group_set_target +g_signal_group_unblock + +G_IS_SIGNAL_GROUP +G_SIGNAL_GROUP +G_TYPE_SIGNAL_GROUP + +g_signal_group_get_type +
diff --git a/docs/reference/gobject/images/glue.png b/docs/reference/gobject/images/glue.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f3aab2fa34fa43b3d08fc5ac1829aa9f5e5bd3 GIT binary patch literal 12722 zcmeAS@N?(olHy`uVBq!ia0y~yV4BRpz_6EtiGhJ3!8h?J0|Ntdv6E*A2M5RPhyD*3 z7#KJUJR*x37}zg>Fyqed=kpmD6c{{R978JRyuDi;AzZ%C{=@s0mI(!%(@&TRIqVE} z5ZEKKrDVF>&NXVaMYVV-=?zY(h|=c_mun#ug~0!T7THiC_Vf4iGK^O&)n_5esSinozLe9 zcOPZvlQEFsF`1#Et=-+*JJo9`FE4M-@ud6`-|+xz?HFIsW!TG%$`jq)!_o0F>MdM!=TW_YvMapOLa`F9u0h&!&Wq2b}}o%}ny zX0}=KF`ik=xVgD+@*SyLaGkg7W$E>GvB~HueB-l7hba+{bF^mm0Mg!M#k->rQQEOpN|}IDK9VQ=kH%W zuWHr8g^4a z%^Dr2j-Zt>TQUMYJUjvdF06~)?UrACaM_EmRa>LhUd-T7tp9a+e$Vc@tE)oa@A=%9 zsjt+MlA3z-`0?LAe(d>pOu9v2Y0%D+mq9aq%6C@j4zfG1b zDk^e&EM&1UV$H=2wmfH!o10R-tE;VzbFJ=MY|OuJH)~mUR~HLY4r(w`sD!{CS`9L z8X6|6`(HAt{q^PLl`A2$mQ`0(?b)*@D=X{8{jz!G_iLvwdud(%&Y(8!=clLjKTpSR ziCXKo{P*ejf1iHe|9|hsr9I|-a%I)BM$M`dB;CY}npNGl7g<|cezml-wzAq1l{=qf zM)Tx%|9`xB^~z{|rrpBpuYJ{f`l~7{XYTV&{B|VZ;SZU}#Z@)4&cAv4_UorltJbgo z|L61h^z-v_dk$J$T;5+HK%%=K7IPPNpWG}OXKC|Ewvtt$1^|vSW&AcQMGs9=FO9DK3KMF+4FhT z=MMcim}g;SW%uvLTVuQk@`qz^%aCxF_l9y*-u1 zX=%^C->>(-yd`RF-2S>+Cnu+fh=}^PKWpkTGc^@e%+1R$OpUgilv`Ex%liEu=gTFj zsi{6bKFP_8Te+KTBllE%JT6~9XZrN*1rMDbpZQmHaZlyvvNtytUVr_ysx~a_+MdeK zYeb*TXgI^Lt$FdxL=o-pe|~QL3-rZS~CJBj) zo4?p-o_T4>hYtnMxSAZ_-roNH(o*ln#>UNQXHT6w$H&7Xb1SVOc7|~}pYe(2*|VjM z(;MQpl)sN_byA#u`e{+6ukYD=d#l$;k-my3yu z$L}ae{Qd21%LMWGn!>|vy!-!rI^8R6ZujfO;?vXh`=4E7IB;Ua@-qz+BM#jA^L2f_ z>3+v0E2nCQ3pp)Xv}jAzTZXeiK|wQqI~nEgRaRD>`7OTo>s9-IANi9vXJ21u`{%=9 zWg$z39=YmMJU`ByWsKgQw{(YsrRB~|n^b-M{RM@X zuWzdL1jm%Lw0XAGWnW)i&0+tPf2MZs;lqb@_pC3T|9FG_ncBJW)o)E(oeWb?O_^W! zi_^S=B}~ECM#B08&x$*DCd`_ZW&L-b{mhv&bJ{;hpQ)Yu_wV2EwNa)8-p~5>sH&y0;X&wR*u!!ga_DckNtclJ!%So!(c+1cjCmtS97Yn-1j zM^8uRjq&lCLl$pezpj3EX68i>IR>}Rxv6Y(p0hD9JP-=WV_;y=b9@Tr{4RNPr1Qm# zjPUUA`uhL6(c4~ptxB^?O`Lz13^T1cLC$+I&v zeP^5fegFU8`lz-0N?u+PkFS|HckbD;0EPpbE}q~?O-7`1;t`*u80IXW9Sz z*sm<4#lti8Hs9MD8y`P7*xcFKDdO7N((>fVlP_Pse93g4*?Xt^;SR<(w=+`MTAel~ z9qrn%!NBRnqods)XWq8@u-d>nBp|?`_?ge+{U^boS??&%uGzC@-MV&d+O%oY=FI7F zv}JsAG9#r8WZ;()rw+g6)qlTUH#RbIQ!aYJJb&j~0oTAY@43&+Az zC5_VpM4rBT7Z(vx@%Gl%i~S-DYtp|M9iARvH*>;-3zsi%uK)jUV!!m62gciFyZZaj zpFdy!<)ZuZb922fZ}D3C>C2Zl>o*oYiA%c>yD`FtBQq~gt|Ft3;lZ4XCwNSJ^KWc; zcx`R;@qT%Jet!9@KMr!t-}&}}_WC`a{(L?!E+%%#G6B3w)#tdo>*-tW8P3J-Fv3s;i1;1CZ!w}Yd%9dsC-o3A{ub*$0drSV`hxUsR`@NQ~TC?WOix(MrV341`e*OCJl_4z? z?(Qz%|Nq}_Sy|b&Yu9FN-L-mk_Jys1B2OPYIPm!6kD7fSXQcE6H6L`~xR|xoYVNs7 z2jDRs0-=(Cava++awX~w5qF%jzt*xy+d)BO9CS`?% zAHRJ|W3v?MKKk+F$1{SDUV*_QFnIGuN2v2i(#8m#vXT-Ju2!Xq9p|5OvoJl@*I`dH zkf^GzHkIo2TmJght5+{yUd%8#X8z{w+qbe{khL{xZP@m$V6bglSZL_V5Ur&_D?_w= zuWw5`JInlj&E>Oa&z=W^%a@H+R8$lc9JHqT&9S(6`}XgHapnxOO*hS4xN+mgWy{!R zGP1Ru%3UdIUAATWc44P8$Mp=ZU%FKE{oUOzF!=Q8)2dZktxkb)arbWDK5eo<4#c4-@SYH@#Dwh=jWz+s5CY<-n(~CsPoAE`}c3(zHPC@z%_7n`1-iLRbMl5#QTp6 zce*G|>=1bL^r`8Uqr7a*K`V2zvR18L?d|U$zb$8Gj9$3b)Y8(@@bz(_T2oC;O^?m* z3KCJBep=mcjt9rjN8S2!=FV+yZf0g?PBprDB2T2@s)X_3soLRexi(AA2#AZfpE1}Z zooXJilil(1m)rUKeK`{O{G3jFeSLjv)Y^}=tHW0BEqfak85xM_I6Ii`?cTit_)s2gRRES-pZ=#Pzz^bV&cMu3lkF)1qB6zR$e)E zn<>Ha^O=Ij$9PlNlvCOQTTj_e`1b8v=;|<8`?@yx!g29Ud5X z@XYtmpSgK?d;9z2cN8dIzRJYR%r0@E{>_K)AW;8eVS7)pMpxD2Uh}YZF_9r5A+fQs zF)=Z5aq9v!KrN+JtF)H&Iw;JrtF4NNhzJP@@$vCVNm22e(by}YV0>q1@$wxzZkQPV z`1Px;wN=r0hI3j)!iqb8ch&wbb8~AeEO7`{_n()Om)F?mqpq&5+w<@5tN#AZ-~R8HgY5DK^Fvse4l4KC2+7IGNlVY3 zF+)OL{`}*I>AeZLOP4O~7SnY~ldwI()9mzg-~RJyQ}ndSYhGEoyE_;y}y6{PoJuiQqr$4FDFi%*xA_`yv!%@ z+)2hBxfHf-3dS=Y`8=)r`}O+fO`C4?J-W{)YgO{%!otLLDwdW%Z){91+F9e`v?+ff z7;ua0rTjCM;0a$Bv$OK^v#r_J^X}{@{P7{N`QU_U)4rWGzrR6RJ>ov7aLm7du1w^= znbJ%}P0g1-K0ZFdGfiUi%tqs>*4o;yAuWTgw~V)K*)nCy6cKUp>C>i_m6Xh|d-CAH zhV=7t-1RXR=bt%qW^?-azDuPGzx5t}>^sva_0$y2Gy6?^@9!#Iy?OKGyDJ(*Z*R|c zPh&WC<0Q|Vm3LYuT)7ewR<-$H!j8JXzjhWs|McmTUi`j0ckiyf{u&fZZ{+#ajE#$z zD9Jq5=rY=Sg7uhG3fm5S>vKFYtM24H{8+&W2GZtvZ{EJ$Tk$a|E-tRP*!XrKBg5=7 z#)o$nKc66ZfNMt;W1O3tn}4TTda=7g)F$`J+t=OPlzOJ&-}l(twVEPbqS|3Ct*wGiV)}7C<<}U(+RiW}v#4u- zpQ!B4p=kf-!(oQ^Yf4etqc=AsItK*>rKYCF#ofELH9I;w`fT{7yt}&^8W_?%66@># ze|>%Z`}S?Wz5M;}Z_O6J{NwBO`12=DNGv?d%FwM~d_W>`d-#gAF*_#-2#Ja=y_&_T zxZHn!-S@lYnq6GHyldC3D=RBAi+}Rv<>jYOpPqTRtMc=+4~~ zs}8sEZqK`GRrhDd%ZDCvp5iXf~SmaW@EvZ+eN`O zcKf$%nIbT0_H1j1&0oHhq$TXB{{GH)uGQ6w|CP`DKJ`?7e)jgpM(6d{Uw{3zX3d() z&(C-@C;j>J$9uZoT+3oM_U9cRzJIr``SD?rs`rwhmun(7Z`!=MyQ}L4AD0F5%!6@? z#sbzW?nH0T^Y!%X?Cv(Uy>#a7?d|&Z_Vxw_2D-Yr=jYj;sePp8J4-}PF7FTH$$NXN zMY&pI^roMFYHDg){r#P6kczlojE07W00)bRYoN%}Cr`c{kY;U}uw#csn$zm5&z?We zzq7+oO-;?h;>XYD^X*GtO))&obVuB%d9PF2kL`2j$lQ8XsOon*a-VC=&2NJD7cssI z)e+!$c5d$NTeqy~*5A*c$9`l% zX4Jxfkg%|6)27|qTfKeJqD4D)>{zlyMOF3bzPFPnP3n`gm6DOkd1`TxP0{#iv8b)B?ft&r>o#uOxNzaZZQG{(%xV&N^yG=k^wXf`;+{Q!{``rF zjkUG4t*xn%`yuwOXy>1e$K|AV9@x2X1(z5VgskOD|2BFrlG=L0?~g zXUx0j&!4}2YkMY8V&{r&+rrj{UB3zfnp01G`t)hmtXb2hP203-)2mlmk6)L)x&j&m zeDL7G&CTiQX=!aOEiCNp?k+Af>Ks5t@G{@oJ^y#@-u?X9Grg!SCvMGVG2@xps69c_ z?ZS-Lw$4vqgMc?j<)cpZ9!{s_mqWwDwMDu%ZQ69~*s)iyUhOV_FD5Gb^yyPm6BCKu z3W_dTQ-A&VVUU09c(3&HmoHzwef#$5)29y~Do*vXwXwN#_pYt2?aiCp6kol1m6ewl zw)(2p)Kv=?E?m2I?b4-7w{6?DcJ11gD_5>s)g`bg?X1-0v*jfvJbZk792_4$ew=Al z`s&BW$AAC)adL7>N>2X%=B9DRq28XJl9G}u873_gjvP6Xe7vu= z5B>_+DbF(hJU_48ot~)Wz`|_5D;ZbX+{dCOA&tLDh_~OfwyLa#I1%tbH@5X`?)m$);-5<32>f5(( z&oEZruNL=G5t`}q?A0r)ygNIVELk$!Jm2o?m0)ghy)Pd=aBy)Y?X#3Q_gY7QW6`2T z>*DwSJH)NO=j*j-r-cO;*~}8TCwPu+m?-Hcs`Z^in1jV=rjOcW-V4jtu3fuz>(-Sk zJ(mV;-MUqC>Zxnj!nQ`;y>@L`*y@>&9Tx_al$4Z|mX?;42|4x2SRUe8ZsRp)&KyWn zxvZ?Lu&}VKtgN*3>*vqh+}y>*#h*WXC@3v0Eiach&ztknWZqBqraO1;Y}vA9`TV*n z7G`f>-`clZuZ!u&*)+Xo*)YNv|0Fo&Cqg^;v0R3)-5Pv zW+(^>3%j;0_x6pxq=GZ01v&1C;UBV?7z%{?j~@97fEi0?AF1ab6V1nPz_a}Q zJ=@ApDz^i9@*W-Ol$4YN83Y>Cv3Pk>eg2v?YeYC$a@dVHo*i4vEvA!TE%3YXlx>Ps zZ`;@V0hdhHhOM4C`&n6Osp0mES2Ij(!QjlWFo_C_NLady}WbpdMjwEFvoU^vRPoaeHrB95*v& zb`AXc_3Pr#Qayny?l@n#eS3G^-(Q)Rm;HUnUoX-7b#=(9Q>RY#_4PdigKyuy{rXik z)ytLR=HBY>zu)h_fAQkMJL|V2_5XU}Qf$;_F20grAm9WZ6Wy$0psucN4hGNkTHd{T z7Z(>N)Y-CAcD;+zM6accjEslx)G+ipr8%T+Fbc`@UKz4#rg8eeACLQ)8Xq+F`!5ZO zjE${*e{XMFTidN$x4OEzrcImn>({SSr%o+fw#=?KHYR4z-n}z#U+F&j=*N$WXB>s4 zU{F|?m{+2Y-s}6Bck0ml3p{Mju&fEmj#9nHezbvd=wc9XUK_Uh>Z@&FaP8W)Rjah7 zdMynB5if6DTNC;D+3fsXJ9qvBgUYHZP?^fY;<5Bnr?7feb+!GC*K7%!-OP+l%*?J` zxuRfv;6T7m-L1*T`@VfEb2@Q#bvS$O9SZw=vlnS3Kfby;e0H6>SyP40JP%OExrJjCLv@>Ysn$@d!SAAU-v~tbLl?yXxW%>k8iP4*H zQK+Q&q+5SqL0K6eA0HnN&ymI(#B;%3X)2axA`= z^Y{NXQ*5!c;8eW6KK^>v)??q-My>sJYio9DYUT0%ro=uC4Z{0SqTbKWo2bfMdS2yCg+v6Zr!S@t6To=&dOD* zva+&v)&4e9e6sufKI_s~B9|M^KX-R`_n%>)sH3A}Vq&7Bqobtcq%}3FGMYgreV%0A zogIy55?am}tP0r4e(B!5eOXsmJwDz)``nwCFD(lmIAmsKdU~GRTm4;2OKZl@y1KfB z3m1O;_z~12*%g(Lpzyi(n#A+>An^Z!Gr#2X0Fkf9r1RIr?A)|s#fn|KcJ0`)W6z$L zg#k5xJ{}JZ4fT<3bTFv>^<~3`4J%fxm@#9CqI;;2Fh5 z42#)kHtL?>S!NNuGrs=s*EMT&wk`g#-MJmq@5`8>?dj)dSN3K`jGp|&32&k^K;Xrp zR_>YgylkKmguHuuD&OAPDs7%8V^?z{!C=YKrL~{Wn!h>5d2M^?>uYasZ{I9?bbqf$ znunK{Rox#8qh{4(IcX1ko}N2(s_NU#^x)v&wcmPlb#+x$RgWG$x^(GMSy|a-{FW9L zZ*Fc*pW!T?3K=P$vW|OezKvY|sVSPE-s-=lnZK^Bjh;Jq?i)AOH8=LvS{pGN9P?=Q|B>%54m^pK%vgktz_rNJH zUG)sEDHtE9y;+#{An0itcmHv34-mMqqcAx?|NYT!@z0+=&6+*?W*;}hjg)zk=jK|s zpJ50)aFzRmk&%&;lar3jqV@LP)Adr-dX%Mkyfj44&9nV|*8IN7-WM0A98Bow?UnTl zVfb+1##tWg@^>z24B8K}p8orC+5hyZQ$PMB)}|MHc@dblX!q`Fl_sTje))Ok`Jl-~ z8>MXKhJ{XP4I3LKPyIbJeV$^A&7Tj4t>&Kl;=A$Xf(A=V%a0#F-n)0ty8N9=%a$!$ zY<@nO+}POY=;$b4_hVt9YVdNut1nB=L#)~}#3 zsO;4+JS&oO7*QzyZ&YV6Sy}K+oJA3s{ zuWM_g#RUWo@Myky|9*en-(UZ(U7IgyoM!X!h%g@?pYo=e3?nU9=jPTH zp>uCb=4FHM>K`8-`rG|vdCs(^bMpM1?^mCfTxr+*?8Vor$I|zH{i=FAw~{TP#yo4E z*@mXW?fmNnS}uKLU=Z{Ktp$kL`RPcf@Za8W)&$NJw#Bm6WimDu28MZ`u5h=(=}Ve?8F<+IJ{X<^!ewXOP7M2Jo571F`T`0 z`SQ%hkMHj8HZOe@^7!xbnbs$bpPik(J^47_-njMGUvJ*D2{a?IYU1GofBydEm$%!K za#Cnzh*kErHE-U$S+q!LTQk!+hctumfB^Vt{_SnK(j_agPVIcpOn6$%c!K8$pVs$l zYomjMf*w738>gLFpmFN%-Mt$&e7LnWd$IgWhY6DZbk)_{w^hb; zUM`xJFBrb9_Q>{(hH6o6mZqJ>&$n&c#%G;%`{=v6?fc`7i!Ponxy*ll-M2T9kN0~m zog|PH6FQ%B8OtS;x9{HFyLt2EnVhVwSMT2Kdw;6c>EVaRE@>NBHa4HXbFKW{9m`W^ zo}8R~v+p$D(IZE`e4o(W?VXmk%tdKqnhgWNiQ zDRt8nZEgR~Ex)%gbJwO#MrvxyHg3GQ%JDwG5p()FU4K8nb7#(MxhYu7&BfLBYcrR; zy!;)$4#&$|oEENFvqnc(cW?FgJXcrO!oosNPfsteQ?<9%RaIqet4u5`Zk#G?;&n>f zaHolt`_}E-)AeF+UAQ11Bs6L6+}f|NuG;0!*v#|q-@nyiYm=V6xxGFAXqRYXVE~p`#i!4jHS5u%q-QaLmk*pg zsfoK=%;xU9YVF$4)mOpIz*4WJoA&J4vuxS2rAwEtS+i!>u3JBL&9y4kQc_Z~u&DU< z=H|?qGZhsT4<0-yC@8p0J|OSjp3Gm#!R6)O@7%fL+AS7YJ^4VJqHzJM(P0j$;=SoB zYHC4%Q_8q zdHH8&f9xoHY-4K+YGv-(V`F2pBxq%Od;9L)yO%Flx4v!W5*r(P_UzfLtx-#ZOifI- zY~8wb%a$wGu5H`8)zs89G&EGu>DrpeW5w##tHCooT&;^1E?l^E>(*tvUBIo%*;&C5IqOmv{|!$-O66C8@H!| zj=R#IA;3F;MJzI%7=<(FHca`W@oA56IL z`fJqMX_fN1e-6rTR(Ky?1L_r9TUc{1F;mg z)4d4Ix@4FCrzGg zY;3GK`}yO?%F|EZtlP?Pj4P$hu={)&gTapE<9%~&tEauyU{jxdTE6;?;kLyL6510a zkLiTu@l81WbanXpG;1z~4Z0_IlEwDvvg7ZI%PF=j%iMOj!H|9Lxo?T`jb9gDk8Co} zzP9GotE_E@H)MYO`nAT+UPYzlt-~Aks=Es!-k08RZ%(QOEtlKnXt=lU`GW@qpP%_| zYu=d2%F1drm+$y<4yX0fA&H3#{g!j{@ui_JD64)l(f!;!+vt#xBV{&bUCUm^?k;0x zV_Q_zukdA8qh$5n7Ea+CU5vjo61HssuUk9Nv$wCLyxiTz#b=hu%FUZ6vl-X_eI2ja zWmWu)=XT=_(J#9iZ#u0%Y$r8C_l@%J<~VbM9sB>I z|9^sAzq*RbhVQ8jYYU2tm0MWY*y=u?HDB}2s5 z{oP!{JXJU9YdN=Pz~S z-ma>ov}nr~k-Z`e2RhD|F(hdAx@}H4*mUXAr8#rv*#CX$zifUK?X=AM2Mt|M=sbJ9pIl=dB6QXxph< zJMV4@pKG9?px`tYK86JIfSs0)Z*9$9w{BfvU|{pMKi_WWr=OXzFl;ryoXwAe?D8+Z zf+op8eUoLmX1TYfOr2_4{_f6`Cr>^U33N*Dk9{QTQyz1PxNX1TZi z{rx?8(xkHY_x9%A-qz8D#5CP#x2))2YwnlKa^&FT=ijbU#1QSk5xFU)^I$^4KV3~t zNk1Vo2_E^nABjOhlYG>;IXFIi|L*VaFTc>^|Jg$vzq?arNOSx>SebV&p)6uPXo|FI z@4T65`^?v^S_PU@`t$R1=B&KjT-BBimqiB-9C*L~|Gkoflhyry{r)ZN^ykkX4#mBD z_fFHFJ$dru2M-eD9;VN)J@)uxT-D2^6K{!~j+C%uc(G5PqT$B#9;UcGy#r=uhDFU!|=j>W|glPeEiElGX3UsroE{buA|e0x)#~+1N=l$9?%J=RmqTBcSo!;(-?L}WZ@Y`X z-|v@~m$$F{^aP|jER1i%wtrFo{=TpG_wh05{qXJW?agUtxp;VZczJ8z@BOaRd1S|q zmsLK?&(4?CY5aU=j-agU-Me>dpPmxEJoD?ds$La^5x5yqN1YZ@9tE-+xc9lGbMr9#+rxc{W2?+}`GdKUf zeH&v`-mNX2$AABqf4ge+>h7*C&@w2Q+B4Np9hD`2luA6fnV9h7%vs6vw%=nM91eg+ zj()vf|GH$?zgd+P6@T89@84bd`I-9s8lx-ACC+VXnb6b2Gi%xQ+}mkYN2L1GgT?Z^ z<((Ez5D1Eo_vcu-c5UpIjEf$wdhdt1>{FVM)Dw0V@AWrMCl%akco3@-ov{ytqx!}l^E&iQq} zG<`4M-kzVnZtI)(cQ#y{rW^g|@88d#KhNyGntylK(Jh+V+QQvO@7Mj-z3j6#?E7}J z)6r5qZ8K)f*#Gx!eif*%ZfDgCCW+d zDB>@@X;&;IB^9?nNvq-bZ1Uj3s^^%?Dc^X+8i<>kf1#Kgt7*Zlm%crC5+^zH5W{`2kbUcMZxH+}!_ zce|&#Bt`uY*NsvU>lPLko|!N8tGa9h%R37u(26#T^T-R^P*%A?IRE)w4m9QMGP)FVdQ&MBb@08^`m#sB~S literal 0 HcmV?d00001 diff --git a/docs/reference/gobject/meson.build b/docs/reference/gobject/meson.build new file mode 100644 index 0000000..a9a6543 --- /dev/null +++ b/docs/reference/gobject/meson.build @@ -0,0 +1,68 @@ +if get_option('gtk_doc') + subdir('xml') + + ignore_headers = [ + 'tests', + 'gatomicarray.h', + 'gobject_probes.h', + 'gobject_trace.h', + 'gtype-private.h', + 'glib-enumtypes.h', + ] + + docpath = join_paths(glib_datadir, 'gtk-doc', 'html') + version_conf = configuration_data() + version_conf.set('GLIB_VERSION', meson.project_version()) + configure_file( + input: 'version.xml.in', + output: 'version.xml', + configuration: version_conf + ) + + gtkdocincl = include_directories('.') + + gnome.gtkdoc('gobject', + main_xml : 'gobject-docs.xml', + namespace : 'g', + mode : 'none', + dependencies : [libgobject_dep, libglib_dep], + include_directories : [gtkdocincl], + src_dir : 'gobject', + scan_args : gtkdoc_common_scan_args + [ + '--rebuild-types', + '--ignore-headers=' + ' '.join(ignore_headers), + ], + content_files : [ + 'glib-mkenums.xml', + 'glib-genmarshal.xml', + 'gobject-query.xml', + 'tut_gobject.xml', + 'tut_gsignal.xml', + 'tut_gtype.xml', + 'tut_howto.xml', + 'tut_intro.xml', + 'tut_tools.xml' + ], + html_assets : [ + 'images/glue.png' + ], + fixxref_args: [ + '--html-dir=' + docpath, + '--extra-dir=' + join_paths('gobject', '..', 'glib', 'html'), + ], + install: true, + check: true, + ) +endif + +if get_option('man') + manpages = ['glib-mkenums', 'glib-genmarshal', 'gobject-query'] + foreach page : manpages + custom_target(page + '-man', + input: page + '.xml', + output: page + '.1', + command: xsltproc_command, + install: true, + install_dir: man1_dir) + endforeach +endif diff --git a/docs/reference/gobject/tut_gobject.xml b/docs/reference/gobject/tut_gobject.xml new file mode 100644 index 0000000..0423a38 --- /dev/null +++ b/docs/reference/gobject/tut_gobject.xml @@ -0,0 +1,728 @@ + + + + The GObject base class + + + The previous chapter discussed the details of GLib's Dynamic Type System. + The GObject library also contains an implementation for a base fundamental + type named GObject. + + + + GObject is a fundamental classed instantiatable type. It implements: + + Memory management with reference counting + Construction/Destruction of instances + Generic per-object properties with set/get function pairs + Easy use of signals + + All the GNOME libraries which use the GLib type system (like GTK+ and GStreamer) + inherit from GObject which is why it is important to understand + the details of how it works. + + + + Object instantiation + + + The g_object_new + family of functions can be used to instantiate any GType which inherits + from the GObject base type. All these functions make sure the class and + instance structures have been correctly initialized by GLib's type system + and then invoke at one point or another the constructor class method + which is used to: + + + Allocate and clear memory through g_type_create_instance, + + + Initialize the object's instance with the construction properties. + + + Although one can expect all class and instance members (except the fields + pointing to the parents) to be set to zero, some consider it good practice + to explicitly set them. + + + + Once all construction operations have been completed and constructor + properties set, the constructed class method is called. + + + + Objects which inherit from GObject are allowed to override this + constructed class method. + The example below shows how ViewerFile overrides the parent's construction process: + +#define VIEWER_TYPE_FILE viewer_file_get_type () +G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject) + +struct _ViewerFile +{ + GObject parent_instance; + + /* instance members */ + gchar *filename; + guint zoom_level; +}; + +/* will create viewer_file_get_type and set viewer_file_parent_class */ +G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT) + +static void +viewer_file_constructed (GObject *obj) +{ + /* update the object state depending on constructor properties */ + + /* Always chain up to the parent constructed function to complete object + * initialisation. */ + G_OBJECT_CLASS (viewer_file_parent_class)->constructed (obj); +} + +static void +viewer_file_finalize (GObject *obj) +{ + ViewerFile *self = VIEWER_FILE (obj); + + g_free (self->filename); + + /* Always chain up to the parent finalize function to complete object + * destruction. */ + G_OBJECT_CLASS (viewer_file_parent_class)->finalize (obj); +} + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = viewer_file_constructed; + object_class->finalize = viewer_file_finalize; +} + +static void +viewer_file_init (ViewerFile *self) +{ + /* initialize the object */ +} + + + If the user instantiates an object ViewerFile with: + +ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL); + + If this is the first instantiation of such an object, the + viewer_file_class_init function will be invoked + after any viewer_file_base_class_init function. + This will make sure the class structure of this new object is + correctly initialized. Here, viewer_file_class_init + is expected to override the object's class methods and setup the + class' own methods. In the example above, the constructed + method is the only overridden method: it is set to + viewer_file_constructed. + + + + Once g_object_new has obtained a reference to an initialized + class structure, it invokes its constructor method to create an instance of the new + object, if the constructor has been overridden in viewer_file_class_init. + Overridden constructors must chain up to their parent’s constructor. In + order to find the parent class and chain up to the parent class + constructor, we can use the viewer_file_parent_class + pointer that has been set up for us by the + G_DEFINE_TYPE + macro. + + + + Finally, at one point or another, g_object_constructor is invoked + by the last constructor in the chain. This function allocates the object's instance buffer + through g_type_create_instance + which means that the instance_init function is invoked at this point if one + was registered. After instance_init returns, the object is fully initialized and should be + ready to have its methods called by the user. When + g_type_create_instance + returns, g_object_constructor sets the construction properties + (i.e. the properties which were given to g_object_new) and returns + to the user's constructor. + + + + The process described above might seem a bit complicated, but it can be + summarized easily by the table below which lists the functions invoked + by g_object_new + and their order of invocation: + + + + + <function><link linkend="g-object-new">g_object_new</link></function> + + + + + + + + Invocation time + Function invoked + Function's parameters + Remark + + + + + First call to g_object_new for target type + target type's base_init function + On the inheritance tree of classes from fundamental type to target type. + base_init is invoked once for each class structure. + Never used in practice. Unlikely you will need it. + + + + target type's class_init function + On target type's class structure + + Here, you should make sure to initialize or override class methods (that is, + assign to each class' method its function pointer) and create the signals and + the properties associated to your object. + + + + + interface's base_init function + On interface's vtable + + + + + interface's interface_init function + On interface's vtable + + + + Each call to g_object_new for target type + target type's class constructor method: GObjectClass->constructor + On object's instance + + If you need to handle construct properties in a custom way, or implement a singleton class, override the constructor + method and make sure to chain up to the object's + parent class before doing your own initialization. + In doubt, do not override the constructor method. + + + + + type's instance_init function + On the inheritance tree of classes from fundamental type to target type. + the instance_init provided for each type is invoked once for each instance + structure. + + Provide an instance_init function to initialize your object before its construction + properties are set. This is the preferred way to initialize a GObject instance. + This function is equivalent to C++ constructors. + + + + + target type's class constructed method: GObjectClass->constructed + On object's instance + + If you need to perform object initialization steps after all construct properties have been set. + This is the final step in the object initialization process, and is only called if the constructor + method returned a new object instance (rather than, for example, an existing singleton). + + + + +
+
+ + + Readers should feel concerned about one little twist in the order in + which functions are invoked: while, technically, the class' constructor + method is called before the GType's instance_init + function (since g_type_create_instance which calls instance_init is called by + g_object_constructor which is the top-level class + constructor method and to which users are expected to chain to), the + user's code which runs in a user-provided constructor will always + run after GType's instance_init function since the + user-provided constructor must (you've been warned) + chain up before doing anything useful. + +
+ + + Object memory management + + + The memory-management API for GObjects is a bit complicated but the idea behind it + is pretty simple: the goal is to provide a flexible model based on reference counting + which can be integrated in applications which use or require different memory management + models (such as garbage collection). The methods which are used to + manipulate this reference count are described below. + + + + Reference count + + + The functions g_object_ref/g_object_unref respectively + increase and decrease the reference count. These functions are + thread-safe. + g_clear_object + is a convenience wrapper around g_object_unref + which also clears the pointer passed to it. + + + The reference count is initialized to one by + g_object_new which means that the caller + is currently the sole owner of the newly-created reference. (If the object is derived from GInitiallyUnowned, this reference count is floating.) + When the reference count reaches zero, that is, + when g_object_unref is called by the last client holding + a reference to the object, the dispose and the + finalize class methods are invoked. + + + Finally, after finalize is invoked, + g_type_free_instance is called to free the object instance. + Depending on the memory allocation policy decided when the type was registered (through + one of the g_type_register_* functions), the object's instance + memory will be freed or returned to the object pool for this type. + Once the object has been freed, if it was the last instance of the type, the type's class + will be destroyed as described in and + . + + + + The table below summarizes the destruction process of a GObject: + + <function><link linkend="g-object-unref">g_object_unref</link></function> + + + + + + + + Invocation time + Function invoked + Function's parameters + Remark + + + + + Last call to g_object_unref for an instance + of target type + + target type's dispose class function + GObject instance + + When dispose ends, the object should not hold any reference to any other + member object. The object is also expected to be able to answer client + method invocations (with possibly an error code but no memory violation) + until finalize is executed. dispose can be executed more than once. + dispose should chain up to its parent implementation just before returning + to the caller. + + + + + target type's finalize class function + GObject instance + + Finalize is expected to complete the destruction process initiated by + dispose. It should complete the object's destruction. finalize will be + executed only once. + finalize should chain up to its parent implementation just before returning + to the caller. + The reason why the destruction process is split is two different phases is + explained in . + + + + Last call to g_object_unref for the last + instance of target type + + interface's interface_finalize function + On interface's vtable + Never used in practice. Unlikely you will need it. + + + + interface's base_finalize function + On interface's vtable + Never used in practice. Unlikely you will need it. + + + + target type's class_finalize function + On target type's class structure + Never used in practice. Unlikely you will need it. + + + + type's base_finalize function + On the inheritance tree of classes from fundamental type to target type. + base_init is invoked once for each class structure. + Never used in practice. Unlikely you will need it. + + + +
+
+ +
+ + + Weak References + + + Weak references are used to monitor object finalization: + g_object_weak_ref adds a monitoring callback which does + not hold a reference to the object but which is invoked when the object runs + its dispose method. As such, each weak ref can be invoked more than once upon + object finalization (since dispose can run more than once during object + finalization). + + + + g_object_weak_unref can be used to remove a monitoring + callback from the object. + + + + Weak references are also used to implement g_object_add_weak_pointer + and g_object_remove_weak_pointer. These functions add a weak reference + to the object they are applied to which makes sure to nullify the pointer given by the user + when object is finalized. + + + + Similarly, GWeakRef can be + used to implement weak references if thread safety is required. + + + + + Reference counts and cycles + + + GObject's memory management model was designed to be easily integrated in existing code + using garbage collection. This is why the destruction process is split in two phases: + the first phase, executed in the dispose handler is supposed to release all references + to other member objects. The second phase, executed by the finalize handler is supposed + to complete the object's destruction process. Object methods should be able to run + without program error in-between the two phases. + + + + This two-step destruction process is very useful to break reference counting cycles. + While the detection of the cycles is up to the external code, once the cycles have been + detected, the external code can invoke g_object_run_dispose which + will indeed break any existing cycles since it will run the dispose handler associated + to the object and thus release all references to other objects. + + + + This explains one of the rules about the dispose handler stated earlier: + the dispose handler can be invoked multiple times. Let's say we + have a reference count cycle: object A references B which itself references object A. + Let's say we have detected the cycle and we want to destroy the two objects. One way to + do this would be to invoke g_object_run_dispose on one of the + objects. + + + + If object A releases all its references to all objects, this means it releases its + reference to object B. If object B was not owned by anyone else, this is its last + reference count which means this last unref runs B's dispose handler which, in turn, + releases B's reference on object A. If this is A's last reference count, this last + unref runs A's dispose handler which is running for the second time before + A's finalize handler is invoked ! + + + + The above example, which might seem a bit contrived, can really happen if + GObjects are being handled by language bindings — hence the rules for + object destruction should be closely followed. + + +
+ + + Object properties + + + One of GObject's nice features is its generic get/set mechanism for object + properties. When an object + is instantiated, the object's class_init handler should be used to register + the object's properties with g_object_class_install_properties. + + + + The best way to understand how object properties work is by looking at a real example + of how it is used: + +/************************************************/ +/* Implementation */ +/************************************************/ + +typedef enum +{ + PROP_FILENAME = 1, + PROP_ZOOM_LEVEL, + N_PROPERTIES +} ViewerFileProperty; + +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + +static void +viewer_file_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ViewerFile *self = VIEWER_FILE (object); + + switch ((ViewerFileProperty) property_id) + { + case PROP_FILENAME: + g_free (self->filename); + self->filename = g_value_dup_string (value); + g_print ("filename: %s\n", self->filename); + break; + + case PROP_ZOOM_LEVEL: + self->zoom_level = g_value_get_uint (value); + g_print ("zoom level: %u\n", self->zoom_level); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +viewer_file_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ViewerFile *self = VIEWER_FILE (object); + + switch ((ViewerFileProperty) property_id) + { + case PROP_FILENAME: + g_value_set_string (value, self->filename); + break; + + case PROP_ZOOM_LEVEL: + g_value_set_uint (value, self->zoom_level); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = viewer_file_set_property; + object_class->get_property = viewer_file_get_property; + + obj_properties[PROP_FILENAME] = + g_param_spec_string ("filename", + "Filename", + "Name of the file to load and display from.", + NULL /* default value */, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + + obj_properties[PROP_ZOOM_LEVEL] = + g_param_spec_uint ("zoom-level", + "Zoom level", + "Zoom level to view the file at.", + 0 /* minimum value */, + 10 /* maximum value */, + 2 /* default value */, + G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, + N_PROPERTIES, + obj_properties); +} + +/************************************************/ +/* Use */ +/************************************************/ + +ViewerFile *file; +GValue val = G_VALUE_INIT; + +file = g_object_new (VIEWER_TYPE_FILE, NULL); + +g_value_init (&val, G_TYPE_UINT); +g_value_set_char (&val, 11); + +g_object_set_property (G_OBJECT (file), "zoom-level", &val); + +g_value_unset (&val); + + The client code above looks simple but a lot of things happen under the hood: + + + + g_object_set_property first ensures a property + with this name was registered in file's class_init handler. If so it walks the class hierarchy, + from bottom-most most-derived type, to top-most fundamental type to find the class + which registered that property. It then tries to convert the user-provided + GValue + into a GValue whose type is that of the associated property. + + + + If the user provides a signed char GValue, as is shown + here, and if the object's property was registered as an unsigned int, + g_value_transform will try to transform the input signed char into + an unsigned int. Of course, the success of the transformation depends on the availability + of the required transform function. In practice, there will almost always be a transformation + + Its behaviour might not be what you expect but it is up to you to actually avoid + relying on these transformations. + + + which matches and conversion will be carried out if needed. + + + + After transformation, the GValue is validated by + g_param_value_validate which makes sure the user's + data stored in the GValue matches the characteristics specified by + the property's GParamSpec. + Here, the GParamSpec we + provided in class_init has a validation function which makes sure that the GValue + contains a value which respects the minimum and maximum bounds of the + GParamSpec. In the example above, the client's GValue does not + respect these constraints (it is set to 11, while the maximum is 10). As such, the + g_object_set_property function will return with an error. + + + + If the user's GValue had been set to a valid value, g_object_set_property + would have proceeded with calling the object's + set_property class method. Here, since our + implementation of ViewerFile did override this method, execution would jump to + viewer_file_set_property after having retrieved from the + GParamSpec the param_id + + + It should be noted that the param_id used here need only to uniquely identify each + GParamSpec within the ViewerFileClass such that the switch + used in the set and get methods actually works. Of course, this locally-unique + integer is purely an optimization: it would have been possible to use a set of + if (strcmp (a, b) == 0) {} else if (strcmp (a, b) == 0) {} statements. + + + which had been stored by + g_object_class_install_property. + + + + Once the property has been set by the object's + set_property class method, execution + returns to g_object_set_property which makes sure that + the "notify" signal is emitted on the object's instance with the changed property as + parameter unless notifications were frozen by g_object_freeze_notify. + + + + g_object_thaw_notify can be used to re-enable notification of + property modifications through the + “notify†signal. It is important to remember that + even if properties are changed while property change notification is frozen, the "notify" + signal will be emitted once for each of these changed properties as soon as the property + change notification is thawed: no property change is lost for the "notify" + signal, although multiple notifications for a single property are + compressed. Signals can only be delayed by the notification freezing + mechanism. + + + + It sounds like a tedious task to set up GValues every time when one wants to modify a property. + In practice one will rarely do this. The functions g_object_set_property + and g_object_get_property + are meant to be used by language bindings. For application there is an easier way and + that is described next. + + + + Accessing multiple properties at once + + + It is interesting to note that the g_object_set and + g_object_set_valist (variadic version) functions can be used to set + multiple properties at once. The client code shown above can then be re-written as: + +ViewerFile *file; +file = /* */; +g_object_set (G_OBJECT (file), + "zoom-level", 6, + "filename", "~/some-file.txt", + NULL); + + This saves us from managing the GValues that we were needing to handle when using + g_object_set_property. + The code above will trigger one notify signal emission for each property modified. + + + + Equivalent _get versions are also available: + g_object_get + and g_object_get_valist (variadic version) can be used to get numerous + properties at once. + + + + These high level functions have one drawback — they don't provide a return value. + One should pay attention to the argument types and ranges when using them. + A known source of errors is to pass a different type from what the + property expects; for instance, passing an integer when the property + expects a floating point value and thus shifting all subsequent parameters + by some number of bytes. Also forgetting the terminating + NULL will lead to undefined behaviour. + + + + This explains how g_object_new, + g_object_newv and g_object_new_valist + work: they parse the user-provided variable number of parameters and invoke + g_object_set on the parameters only after the object has been successfully constructed. + The "notify" signal will be emitted for each property set. + + + + + + + + +
diff --git a/docs/reference/gobject/tut_gsignal.xml b/docs/reference/gobject/tut_gsignal.xml new file mode 100644 index 0000000..5559673 --- /dev/null +++ b/docs/reference/gobject/tut_gsignal.xml @@ -0,0 +1,495 @@ + + + + The GObject messaging system + + + Closures + + + Closures are central to the concept of asynchronous signal delivery + which is widely used throughout GTK+ and GNOME applications. A closure is an + abstraction, a generic representation of a callback. It is a small structure + which contains three objects: + + a function pointer (the callback itself) whose prototype looks like: + +return_type function_callback (… , gpointer user_data); + + + + the user_data pointer which is passed to the callback upon invocation of the closure + + + a function pointer which represents the destructor of the closure: whenever the + closure's refcount reaches zero, this function will be called before the closure + structure is freed. + + + + + + The GClosure structure represents the common functionality of all + closure implementations: there exists a different closure implementation for + each separate runtime which wants to use the GObject type system. + + In practice, closures sit at the boundary of language runtimes: if you are + writing Python code and one of your Python callbacks receives a signal from + a GTK+ widget, the C code in GTK+ needs to execute your Python + code. The closure invoked by the GTK+ object invokes the Python callback: + it behaves as a normal C object for GTK+ and as a normal Python object for + Python code. + + The GObject library provides a simple GCClosure type which + is a specific implementation of closures to be used with C/C++ callbacks. + + + A GClosure provides simple services: + + + Invocation (g_closure_invoke): this is what closures + were created for: they hide the details of callback invocation from the + callback invoker. + + + Notification: the closure notifies listeners of certain events such as + closure invocation, closure invalidation and closure finalization. Listeners + can be registered with g_closure_add_finalize_notifier + (finalization notification), g_closure_add_invalidate_notifier + (invalidation notification) and + g_closure_add_marshal_guards (invocation notification). + There exist symmetric deregistration functions for finalization and invalidation + events (g_closure_remove_finalize_notifier and + g_closure_remove_invalidate_notifier) but not for the invocation + process. + + Closures are reference counted and notify listeners of their destruction in a two-stage + process: the invalidation notifiers are invoked before the finalization notifiers. + + + + + + + C Closures + + + If you are using C or C++ + to connect a callback to a given event, you will either use simple GCClosures + which have a pretty minimal API or the even simpler g_signal_connect + functions (which will be presented a bit later). + + + + g_cclosure_new will create a new closure which can invoke the + user-provided callback_func with the user-provided + user_data as its last parameter. When the closure + is finalized (second stage of the destruction process), it will invoke + the destroy_data function if the user has + supplied one. + + + + g_cclosure_new_swap will create a new closure which can invoke the + user-provided callback_func with the + user-provided user_data as its first parameter + (instead of being the + last parameter as with g_cclosure_new). When the closure + is finalized (second stage of the destruction process), it will invoke + the destroy_data function if the user has + supplied one. + + + + + Non-C closures (for the fearless) + + + As was explained above, closures hide the details of callback invocation. In C, + callback invocation is just like function invocation: it is a matter of creating + the correct stack frame for the called function and executing a call + assembly instruction. + + + + C closure marshallers transform the array of GValues which represent + the parameters to the target function into a C-style function parameter list, invoke + the user-supplied C function with this new parameter list, get the return value of the + function, transform it into a GValue and return this GValue to the marshaller caller. + + + + A generic C closure marshaller is available as + g_cclosure_marshal_generic + which implements marshalling for all function types using libffi. Custom + marshallers for different types are not needed apart from performance + critical code where the libffi-based marshaller may be too slow. + + + + An example of a custom marshaller is given below, illustrating how + GValues can be converted to a C function call. The + marshaller is for a C function which takes an integer as its first + parameter and returns void. + +g_cclosure_marshal_VOID__INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INT) (gpointer data1, + gint arg_1, + gpointer data2); + register GMarshalFunc_VOID__INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + + callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_int (param_values + 1), + data2); +} + + + + + There exist other kinds of marshallers, for example there is a generic + Python marshaller which is used by all Python closures (a Python closure + is used to invoke a callback written in Python). This Python marshaller + transforms the input GValue list representing the function parameters + into a Python tuple which is the equivalent structure in Python. + + + + + + + Signals + + + GObject's signals have nothing to do with standard UNIX signals: they connect + arbitrary application-specific events with any number of listeners. + For example, in GTK+, every user event (keystroke or mouse move) is received + from the windowing system and generates a GTK+ event in the form of a signal emission + on the widget object instance. + + + + Each signal is registered in the type system together with the type on which + it can be emitted: users of the type are said to connect + to the signal on a given type instance when they register a closure to be + invoked upon the signal emission. The closure will be called synchronously on emission. + Users can also emit the signal by themselves or stop the emission of the signal from + within one of the closures connected to the signal. + + + + When a signal is emitted on a given type instance, all the closures + connected to this signal on this type instance will be invoked. All the closures + connected to such a signal represent callbacks whose signature looks like: + +return_type function_callback (gpointer instance, …, gpointer user_data); + + + + + Signal registration + + + To register a new signal on an existing type, we can use any of g_signal_newv, + g_signal_new_valist or g_signal_new functions: + +guint g_signal_newv (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + GClosure *class_closure, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + GType *param_types); + + The number of parameters to these functions is a bit intimidating but they are relatively + simple: + + + signal_name: is a string which can be used to uniquely identify a given signal. + + + itype: is the instance type on which this signal can be emitted. + + + signal_flags: partly defines the order in which closures which were connected to the + signal are invoked. + + + class_closure: this is the default closure for the signal: if it is not NULL upon + the signal emission, it will be invoked upon this emission of the signal. The + moment where this closure is invoked compared to other closures connected to that + signal depends partly on the signal_flags. + + + accumulator: this is a function pointer which is invoked after each closure + has been invoked. If it returns FALSE, signal emission is stopped. If it returns + TRUE, signal emission proceeds normally. It is also used to compute the return + value of the signal based on the return value of all the invoked closures. + For example, an accumulator could ignore + NULL returns from closures; or it + could build a list of the values returned by the + closures. + + + accu_data: this pointer will be passed down to each invocation of the + accumulator during emission. + + + c_marshaller: this is the default C marshaller for any closure which is connected to + this signal. + + + return_type: this is the type of the return value of the signal. + + + n_params: this is the number of parameters this signal takes. + + + param_types: this is an array of GTypes which indicate the type of each parameter + of the signal. The length of this array is indicated by n_params. + + + + + + As you can see from the above definition, a signal is basically a description + of the closures which can be connected to this signal and a description of the + order in which the closures connected to this signal will be invoked. + + + + + + Signal connection + + + If you want to connect to a signal with a closure, you have three possibilities: + + + You can register a class closure at signal registration: this is a + system-wide operation. i.e.: the class closure will be invoked during each emission + of a given signal on any of the instances of the type which supports that signal. + + + You can use g_signal_override_class_closure which + overrides the class closure of a given type. It is possible to call this function + only on a derived type of the type on which the signal was registered. + This function is of use only to language bindings. + + + You can register a closure with the g_signal_connect + family of functions. This is an instance-specific operation: the closure + will be invoked only during emission of a given signal on a given instance. + + + It is also possible to connect a different kind of callback on a given signal: + emission hooks are invoked whenever a given signal is emitted whatever the instance on + which it is emitted. Emission hooks are used for example to get all mouse_clicked + emissions in an application to be able to emit the small mouse click sound. + Emission hooks are connected with g_signal_add_emission_hook + and removed with g_signal_remove_emission_hook. + + + + + + Signal emission + + + Signal emission is done through the use of the g_signal_emit family + of functions. + +void g_signal_emitv (const GValue *instance_and_params, + guint signal_id, + GQuark detail, + GValue *return_value); + + + + The instance_and_params array of GValues contains the list of input + parameters to the signal. The first element of the array is the + instance pointer on which to invoke the signal. The following elements of + the array contain the list of parameters to the signal. + + + signal_id identifies the signal to invoke. + + + detail identifies the specific detail of the signal to invoke. A detail is a kind of + magic token/argument which is passed around during signal emission and which is used + by closures connected to the signal to filter out unwanted signal emissions. In most + cases, you can safely set this value to zero. See for + more details about this parameter. + + + return_value holds the return value of the last closure invoked during emission if + no accumulator was specified. If an accumulator was specified during signal creation, + this accumulator is used to calculate the return value as a function of the return + values of all the closures invoked during emission. + If no closure is invoked during + emission, the return_value is nonetheless initialized to zero/null. + + + + + + Signal emission is done synchronously and can be decomposed in 5 steps: + + + RUN_FIRST: if the + G_SIGNAL_RUN_FIRST flag was used + during signal registration and if there exists a class closure for this signal, + the class closure is invoked. + + + EMISSION_HOOK: if any emission hook was added to + the signal, they are invoked from first to last added. Accumulate return values. + + + HANDLER_RUN_FIRST: if any closure were connected + with the g_signal_connect family of + functions, and if they are not blocked (with the g_signal_handler_block + family of functions) they are run here, from first to last connected. + + + RUN_LAST: if the G_SIGNAL_RUN_LAST + flag was set during registration and if a class closure + was set, it is invoked here. + + + HANDLER_RUN_LAST: if any closure were connected + with the g_signal_connect_after family of + functions, if they were not invoked during HANDLER_RUN_FIRST and if they + are not blocked, they are run here, from first to last connected. + + + RUN_CLEANUP: if the G_SIGNAL_RUN_CLEANUP flag + was set during registration and if a class closure was set, + it is invoked here. Signal emission is completed here. + + + + + + If, at any point during emission (except in RUN_CLEANUP or + EMISSION_HOOK state), one of the closures stops the signal emission with + g_signal_stop_emission, + emission jumps to RUN_CLEANUP state. + + + + If, at any point during emission, one of the closures or emission hook + emits the same signal on the same instance, emission is restarted from + the RUN_FIRST state. + + + + The accumulator function is invoked in all states, after invocation + of each closure (except in RUN_EMISSION_HOOK and + RUN_CLEANUP). It accumulates + the closure return value into the signal return value and returns TRUE or + FALSE. If, at any point, it does not return TRUE, emission jumps + to RUN_CLEANUP state. + + + + If no accumulator function was provided, the value returned by the last handler + run will be returned by g_signal_emit. + + + + + + + The <emphasis>detail</emphasis> argument + + All the functions related to signal emission or signal connection have a parameter + named the detail. Sometimes, this parameter is hidden by the API + but it is always there, in one form or another. + + + + Of the three main connection functions, + only one has an explicit detail parameter as a GQuark: + g_signal_connect_closure_by_id. + + A GQuark is an integer which uniquely represents a string. It is possible to transform + back and forth between the integer and string representations with the functions + g_quark_from_string and g_quark_to_string. + + + + + The two other functions, + g_signal_connect_closure and + g_signal_connect_data + hide the detail parameter in the signal name identification. + Their detailed_signal parameter is a + string which identifies the name of the signal to connect to. + The format of this string should match + signal_name::detail_name. For example, + connecting to the signal named + notify::cursor_position will actually + connect to the signal named notify with the + cursor_position detail. + Internally, the detail string is transformed to a GQuark if it is present. + + + + Of the four main signal emission functions, one hides it in its + signal name parameter: + g_signal_connect. + The other three have an explicit detail parameter as a + GQuark again: + g_signal_emit, + g_signal_emitv and + g_signal_emit_valist. + + + + If a detail is provided by the user to the emission function, it is used during emission to match + against the closures which also provide a detail. + If a closure's detail does not match the detail provided by the user, it + will not be invoked (even though it is connected to a signal which is + being emitted). + + + + This completely optional filtering mechanism is mainly used as an optimization for signals + which are often emitted for many different reasons: the clients can filter out which events they are + interested in before the closure's marshalling code runs. For example, this is used extensively + by the notify signal of GObject: whenever a property is modified on a GObject, + instead of just emitting the notify signal, GObject associates as a detail to this + signal emission the name of the property modified. This allows clients who wish to be notified of changes + to only one property to filter most events before receiving them. + + + + As a simple rule, users can and should set the detail parameter to zero: this will disable completely + this optional filtering for that signal. + + + + + + + diff --git a/docs/reference/gobject/tut_gtype.xml b/docs/reference/gobject/tut_gtype.xml new file mode 100644 index 0000000..ee04288 --- /dev/null +++ b/docs/reference/gobject/tut_gtype.xml @@ -0,0 +1,1003 @@ + + + + The GLib Dynamic Type System + + + A type, as manipulated by the GLib type system, is much more generic than what + is usually understood as an Object type. It is best explained by looking at the + structure and the functions used to register new types in the type system. + +typedef struct _GTypeInfo GTypeInfo; +struct _GTypeInfo +{ + /* interface types, classed types, instantiated types */ + guint16 class_size; + + GBaseInitFunc base_init; + GBaseFinalizeFunc base_finalize; + + /* classed types, instantiated types */ + GClassInitFunc class_init; + GClassFinalizeFunc class_finalize; + gconstpointer class_data; + + /* instantiated types */ + guint16 instance_size; + guint16 n_preallocs; + GInstanceInitFunc instance_init; + + /* value handling */ + const GTypeValueTable *value_table; +}; +GType g_type_register_static (GType parent_type, + const gchar *type_name, + const GTypeInfo *info, + GTypeFlags flags); +GType g_type_register_fundamental (GType type_id, + const gchar *type_name, + const GTypeInfo *info, + const GTypeFundamentalInfo *finfo, + GTypeFlags flags); + + + + + g_type_register_static, + g_type_register_dynamic and + g_type_register_fundamental + are the C functions, defined in + gtype.h and implemented in gtype.c + which you should use to register a new GType in the program's type system. + It is not likely you will ever need to use + g_type_register_fundamental + but in case you want to, the last chapter explains how to create + new fundamental types. + + + + Fundamental types are top-level types which do not derive from any other type + while other non-fundamental types derive from other types. + Upon initialization, the type system not only initializes its + internal data structures but it also registers a number of core + types: some of these are fundamental types. Others are types derived from these + fundamental types. + + + + Fundamental and non-fundamental types are defined by: + + + class size: the class_size field in GTypeInfo. + + + class initialization functions (C++ constructor): the base_init and + class_init fields in GTypeInfo. + + + class destruction functions (C++ destructor): the base_finalize and + class_finalize fields in GTypeInfo. + + + instance size (C++ parameter to new): the instance_size field in + GTypeInfo. + + + instantiation policy (C++ type of new operator): the n_preallocs + field in GTypeInfo. + + + copy functions (C++ copy operators): the value_table field in + GTypeInfo. + + + type characteristic flags: GTypeFlags. + + + Fundamental types are also defined by a set of GTypeFundamentalFlags + which are stored in a GTypeFundamentalInfo. + Non-fundamental types are furthermore defined by the type of their parent which is + passed as the parent_type parameter to g_type_register_static + and g_type_register_dynamic. + + + + Copy functions + + + The major common point between all GLib types (fundamental and + non-fundamental, classed and non-classed, instantiatable and non-instantiatable) is that + they can all be manipulated through a single API to copy/assign them. + + + + The GValue structure is used as an abstract container for all of these + types. Its simplistic API (defined in gobject/gvalue.h) can be + used to invoke the value_table functions registered + during type registration: for example g_value_copy copies the + content of a GValue to another GValue. This is similar + to a C++ assignment which invokes the C++ copy operator to modify the default + bit-by-bit copy semantics of C++/C structures/classes. + + + + The following code shows how you can copy around a 64 bit integer, as well as a GObject + instance pointer: + +static void test_int (void) +{ + GValue a_value = G_VALUE_INIT; + GValue b_value = G_VALUE_INIT; + guint64 a, b; + + a = 0xdeadbeef; + + g_value_init (&a_value, G_TYPE_UINT64); + g_value_set_uint64 (&a_value, a); + + g_value_init (&b_value, G_TYPE_UINT64); + g_value_copy (&a_value, &b_value); + + b = g_value_get_uint64 (&b_value); + + if (a == b) { + g_print ("Yay !! 10 lines of code to copy around a uint64.\n"); + } else { + g_print ("Are you sure this is not a Z80 ?\n"); + } +} + +static void test_object (void) +{ + GObject *obj; + GValue obj_vala = G_VALUE_INIT; + GValue obj_valb = G_VALUE_INIT; + obj = g_object_new (VIEWER_TYPE_FILE, NULL); + + g_value_init (&obj_vala, VIEWER_TYPE_FILE); + g_value_set_object (&obj_vala, obj); + + g_value_init (&obj_valb, G_TYPE_OBJECT); + + /* g_value_copy's semantics for G_TYPE_OBJECT types is to copy the reference. + * This function thus calls g_object_ref. + * It is interesting to note that the assignment works here because + * VIEWER_TYPE_FILE is a G_TYPE_OBJECT. + */ + g_value_copy (&obj_vala, &obj_valb); + + g_object_unref (G_OBJECT (obj)); + g_object_unref (G_OBJECT (obj)); +} + + The important point about the above code is that the exact semantics of the copy calls + is undefined since they depend on the implementation of the copy function. Certain + copy functions might decide to allocate a new chunk of memory and then to copy the + data from the source to the destination. Others might want to simply increment + the reference count of the instance and copy the reference to the new GValue. + + + + The value table used to specify these assignment functions is + documented in + GTypeValueTable. + + + Interestingly, it is also very unlikely + you will ever need to specify a value_table during type registration + because these value_tables are inherited from the parent types for + non-fundamental types. + + + + + Conventions + + + + There are a number of conventions users are expected to follow when creating new types + which are to be exported in a header file: + + + Type names (including object names) must be at least three + characters long and start with ‘a–z’, ‘A–Z’ or ‘_’. + + + Use the object_method pattern for function names: to invoke + the method named save on an instance of object type file, call + file_save. + + Use prefixing to avoid namespace conflicts with other projects. + If your library (or application) is named Viewer, + prefix all your function names with viewer_. + For example: viewer_object_method. + + Create a macro named PREFIX_TYPE_OBJECT which always + returns the GType for the associated object type. For an object of type + File in the Viewer namespace, + use: VIEWER_TYPE_FILE. + This macro is implemented using a function named + prefix_object_get_type; for example, viewer_file_get_type. + + + + Use G_DECLARE_FINAL_TYPE + or G_DECLARE_DERIVABLE_TYPE + to define various other conventional macros for your object: + + + PREFIX_OBJECT (obj), which + returns a pointer of type PrefixObject. This macro is used to enforce + static type safety by doing explicit casts wherever needed. It also enforces + dynamic type safety by doing runtime checks. It is possible to disable the dynamic + type checks in production builds (see building GLib). + For example, we would create + VIEWER_FILE (obj) to keep the previous example. + + PREFIX_OBJECT_CLASS (klass), which + is strictly equivalent to the previous casting macro: it does static casting with + dynamic type checking of class structures. It is expected to return a pointer + to a class structure of type PrefixObjectClass. An example is: + VIEWER_FILE_CLASS. + + PREFIX_IS_OBJECT (obj), which + returns a gboolean which indicates whether the input + object instance pointer is non-NULL and of type OBJECT. + For example, VIEWER_IS_FILE. + + PREFIX_IS_OBJECT_CLASS (klass), which returns a boolean + if the input class pointer is a pointer to a class of type OBJECT. + For example, VIEWER_IS_FILE_CLASS. + + PREFIX_OBJECT_GET_CLASS (obj), + which returns the class pointer associated to an instance of a given type. This macro + is used for static and dynamic type safety purposes (just like the previous casting + macros). + For example, VIEWER_FILE_GET_CLASS. + + + + + The implementation of these macros is pretty straightforward: a number of simple-to-use + macros are provided in gtype.h. For the example we used above, we would + write the following trivial code to declare the macros: + +#define VIEWER_TYPE_FILE viewer_file_get_type () +G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject) + + + + + Unless your code has special requirements, you can use the + G_DEFINE_TYPE + macro to define a class: + +G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT) + + + + + Otherwise, the viewer_file_get_type function must be + implemented manually: + +GType viewer_file_get_type (void) +{ + static GType type = 0; + if (type == 0) { + const GTypeInfo info = { + /* You fill this structure. */ + }; + type = g_type_register_static (G_TYPE_OBJECT, + "ViewerFile", + &info, 0); + } + return type; +} + + + + + + + Non-instantiatable non-classed fundamental types + + + A lot of types are not instantiatable by the type system and do not have + a class. Most of these types are fundamental trivial types such as gchar, + and are already registered by GLib. + + + + In the rare case of needing to register such a type in the type + system, fill a + GTypeInfo structure with zeros since these types are also most of the time + fundamental: + + GTypeInfo info = { + 0, /* class_size */ + NULL, /* base_init */ + NULL, /* base_destroy */ + NULL, /* class_init */ + NULL, /* class_destroy */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + static const GTypeValueTable value_table = { + value_init_long0, /* value_init */ + NULL, /* value_free */ + value_copy_long0, /* value_copy */ + NULL, /* value_peek_pointer */ + "i", /* collect_format */ + value_collect_int, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_char, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo, 0); + + + + + + Having non-instantiatable types might seem a bit useless: what good is a type + if you cannot instantiate an instance of that type ? Most of these types + are used in conjunction with GValues: a GValue is initialized + with an integer or a string and it is passed around by using the registered + type's value_table. GValues (and by extension these trivial fundamental + types) are most useful when used in conjunction with object properties and signals. + + + + + + Instantiatable classed types: objects + + + This section covers the theory behind objects. See + for the recommended way to define a + GObject. + + + + Types which are registered with a class and are declared instantiatable are + what most closely resembles an object. + Although GObjects (detailed in ) + are the most well known type of instantiatable + classed types, other kinds of similar objects used as the base of an inheritance + hierarchy have been externally developed and they are all built on the fundamental + features described below. + + + + For example, the code below shows how you could register + such a fundamental object type in the type system (using none of the + GObject convenience API): + +typedef struct { + GObject parent; + + /* instance members */ + gchar *filename; +} ViewerFile; + +typedef struct { + GObjectClass parent; + + /* class members */ + /* the first is public, pure and virtual */ + void (*open) (ViewerFile *self, + GError **error); + + /* the second is public and virtual */ + void (*close) (ViewerFile *self, + GError **error); +} ViewerFileClass; + +#define VIEWER_TYPE_FILE (viewer_file_get_type ()) + +GType +viewer_file_get_type (void) +{ + static GType type = 0; + if (type == 0) { + const GTypeInfo info = { + sizeof (ViewerFileClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) viewer_file_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ViewerFile), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL /* instance_init */ + }; + type = g_type_register_static (G_TYPE_OBJECT, + "ViewerFile", + &info, 0); + } + return type; +} + + Upon the first call to viewer_file_get_type, the type named + ViewerFile will be registered in the type system as inheriting + from the type G_TYPE_OBJECT. + + + + Every object must define two structures: its class structure and its + instance structure. All class structures must contain as first member + a GTypeClass structure. All instance structures must contain as first + member a GTypeInstance structure. The declaration of these C types, + coming from gtype.h is shown below: + +struct _GTypeClass +{ + GType g_type; +}; +struct _GTypeInstance +{ + GTypeClass *g_class; +}; + + These constraints allow the type system to make sure that every object instance + (identified by a pointer to the object's instance structure) contains in its + first bytes a pointer to the object's class structure. + + + This relationship is best explained by an example: let's take object B which + inherits from object A: + +/* A definitions */ +typedef struct { + GTypeInstance parent; + int field_a; + int field_b; +} A; +typedef struct { + GTypeClass parent_class; + void (*method_a) (void); + void (*method_b) (void); +} AClass; + +/* B definitions. */ +typedef struct { + A parent; + int field_c; + int field_d; +} B; +typedef struct { + AClass parent_class; + void (*method_c) (void); + void (*method_d) (void); +} BClass; + + The C standard mandates that the first field of a C structure is stored starting + in the first byte of the buffer used to hold the structure's fields in memory. + This means that the first field of an instance of an object B is A's first field + which in turn is GTypeInstance's first field which in + turn is g_class, a pointer + to B's class structure. + + + + Thanks to these simple conditions, it is possible to detect the type of every + object instance by doing: + +B *b; +b->parent.parent.g_class->g_type + + or, more quickly: + +B *b; +((GTypeInstance *) b)->g_class->g_type + + + + + Initialization and Destruction + + + instantiation of these types can be done with + g_type_create_instance, + which will look up the type information + structure associated with the type requested. Then, the instance size and instantiation + policy (if the n_preallocs field is set + to a non-zero value, the type system allocates + the object's instance structures in chunks rather than mallocing for every instance) + declared by the user are used to get a buffer to hold the object's instance + structure. + + + + If this is the first instance of the object ever created, the type system must create a class structure. + It allocates a buffer to hold the object's class structure and initializes it. The first part of the + class structure (ie: the embedded parent class structure) is initialized by copying the contents from + the class structure of the parent class. The rest of class structure is initialized to zero. If there + is no parent, the entire class structure is initialized to zero. The type system then invokes the + base_class_initialization functions + (GBaseInitFunc) from topmost + fundamental object to bottom-most most derived object. The object's class_init + (GClassInitFunc) function is invoked afterwards to complete + initialization of the class structure. + Finally, the object's interfaces are initialized (we will discuss interface initialization + in more detail later). + + + + Once the type system has a pointer to an initialized class structure, it sets the object's + instance class pointer to the object's class structure and invokes the object's + instance_init + (GInstanceInitFunc) + functions, from top-most fundamental + type to bottom-most most-derived type. + + + + Object instance destruction through g_type_free_instance is very simple: + the instance structure is returned to the instance pool if there is one and if this was the + last living instance of the object, the class is destroyed. + + + + + Class destruction (the concept of destruction is sometimes partly + referred to as finalization in GType) is the symmetric process of + the initialization: interfaces are destroyed first. + Then, the most derived + class_finalize (GClassFinalizeFunc) function is invoked. Finally, the + base_class_finalize (GBaseFinalizeFunc) functions are + invoked from bottom-most most-derived type to top-most fundamental type and + the class structure is freed. + + + + The base initialization/finalization process is + very similar to the C++ constructor/destructor paradigm. The practical details are different + though and it is important not to get confused by superficial similarities. + GTypes have no instance destruction mechanism. It is + the user's responsibility to implement correct destruction semantics on top + of the existing GType code. (This is what GObject does: see + .) + Furthermore, C++ code equivalent to the base_init + and class_init callbacks of GType is usually not needed because C++ cannot really create object + types at runtime. + + + + The instantiation/finalization process can be summarized as follows: + + GType Instantiation/Finalization + + + + + + + + Invocation time + Function invoked + Function's parameters + + + + + First call to g_type_create_instance for target type + type's base_init function + On the inheritance tree of classes from fundamental type to target type. + base_init is invoked once for each class structure. + + + + target type's class_init function + On target type's class structure + + + + interface initialization, see + + + + + Each call to g_type_create_instance for target type + target type's instance_init function + On object's instance + + + Last call to g_type_free_instance for target type + interface destruction, see + + + + + + target type's class_finalize function + On target type's class structure + + + + type's base_finalize function + On the inheritance tree of classes from fundamental type to target type. + base_finalize is invoked once for each class structure. + + + +
+
+ +
+ +
+ + + Non-instantiatable classed types: interfaces + + + This section covers the theory behind interfaces. See + for the recommended way to define an + interface. + + + + GType's interfaces are very similar to Java's interfaces. They allow + to describe a common API that several classes will adhere to. + Imagine the play, pause and stop buttons on hi-fi equipment — those can + be seen as a playback interface. Once you know what they do, you can + control your CD player, MP3 player or anything that uses these symbols. + To declare an interface you have to register a non-instantiatable + classed type which derives from + GTypeInterface. The following piece of code declares such an interface. + +#define VIEWER_TYPE_EDITABLE viewer_editable_get_type () +G_DECLARE_INTERFACE (ViewerEditable, viewer_editable, VIEWER, EDITABLE, GObject) + +struct _ViewerEditableInterface { + GTypeInterface parent; + + void (*save) (ViewerEditable *self, + GError **error); +}; + +void viewer_editable_save (ViewerEditable *self, + GError **error); + + The interface function, viewer_editable_save is implemented + in a pretty simple way: + +void +viewer_editable_save (ViewerEditable *self, + GError **error) +{ + ViewerEditableinterface *iface; + + g_return_if_fail (VIEWER_IS_EDITABLE (self)); + g_return_if_fail (error == NULL || *error == NULL); + + iface = VIEWER_EDITABLE_GET_IFACE (self); + g_return_if_fail (iface->save != NULL); + iface->save (self); +} + + viewer_editable_get_type registers a type named ViewerEditable + which inherits from G_TYPE_INTERFACE. All interfaces must + be children of G_TYPE_INTERFACE in the inheritance tree. + + + + An interface is defined by only one structure which must contain as first member + a GTypeInterface structure. The interface structure is expected to + contain the function pointers of the interface methods. It is good style to + define helper functions for each of the interface methods which simply call + the interface's method directly: viewer_editable_save + is one of these. + + + + If you have no special requirements you can use the + G_IMPLEMENT_INTERFACE macro + to implement an interface: + +static void +viewer_file_save (ViewerEditable *self) +{ + g_print ("File implementation of editable interface save method.\n"); +} + +static void +viewer_file_editable_interface_init (ViewerEditableInterface *iface) +{ + iface->save = viewer_file_save; +} + +G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, VIEWER_TYPE_FILE, + G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE, + viewer_file_editable_interface_init)) + + + + + If your code does have special requirements, you must write a custom + get_type function to register your GType which + inherits from some GObject + and which implements the interface ViewerEditable. For + example, this code registers a new ViewerFile class which + implements ViewerEditable: + +static void +viewer_file_save (ViewerEditable *editable) +{ + g_print ("File implementation of editable interface save method.\n"); +} + +static void +viewer_file_editable_interface_init (gpointer g_iface, + gpointer iface_data) +{ + ViewerEditableInterface *iface = g_iface; + + iface->save = viewer_file_save; +} + +GType +viewer_file_get_type (void) +{ + static GType type = 0; + if (type == 0) { + const GTypeInfo info = { + sizeof (ViewerFileClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ViewerFile), + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + const GInterfaceInfo editable_info = { + (GInterfaceInitFunc) viewer_file_editable_interface_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + type = g_type_register_static (VIEWER_TYPE_FILE, + "ViewerFile", + &info, 0); + g_type_add_interface_static (type, + VIEWER_TYPE_EDITABLE, + &editable_info); + } + return type; +} + + + + + g_type_add_interface_static records in the type system that + a given type implements also FooInterface + (foo_interface_get_type returns the type of + FooInterface). + The GInterfaceInfo structure holds + information about the implementation of the interface: + +struct _GInterfaceInfo +{ + GInterfaceInitFunc interface_init; + GInterfaceFinalizeFunc interface_finalize; + gpointer interface_data; +}; + + + + + Interface Initialization + + + When an instantiatable classed type which implements an interface + (either directly or by inheriting an implementation from a superclass) + is created for the first time, its class structure is initialized + following the process described in . + After that, the interface implementations associated with + the type are initialized. + + + + First a memory buffer is allocated to hold the interface structure. The parent's + interface structure is then copied over to the new interface structure (the parent + interface is already initialized at that point). If there is no parent interface, + the interface structure is initialized with zeros. The + g_type and the + g_instance_type fields are then + initialized: g_type is set to the type of + the most-derived interface and + g_instance_type is set to the type of the + most derived type which implements this interface. + + + + The interface's base_init function is called, + and then the interface's default_init is invoked. + Finally if the type has registered an implementation of the interface, + the implementation's interface_init + function is invoked. If there are multiple implementations of an + interface the base_init and + interface_init functions will be invoked once + for each implementation initialized. + + + + It is thus recommended to use a default_init function to + initialize an interface. This function is called only once for the interface no + matter how many implementations there are. The + default_init function is declared by + G_DEFINE_INTERFACE + which can be used to define the interface: + +G_DEFINE_INTERFACE (ViewerEditable, viewer_editable, G_TYPE_OBJECT) + +static void +viewer_editable_default_init (ViewerEditableInterface *iface) +{ + /* add properties and signals here, will only be called once */ +} + + + + + Or you can do that yourself in a GType function for your interface: + +GType +viewer_editable_get_type (void) +{ + static gsize type_id = 0; + if (g_once_init_enter (&type_id)) { + const GTypeInfo info = { + sizeof (ViewerEditableInterface), + NULL, /* base_init */ + NULL, /* base_finalize */ + viewer_editable_default_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + GType type = g_type_register_static (G_TYPE_INTERFACE, + "ViewerEditable", + &info, 0); + g_once_init_leave (&type_id, type); + } + return type_id; +} + +static void +viewer_editable_default_init (ViewerEditableInterface *iface) +{ + /* add properties and signals here, will only called once */ +} + + + + + In summary, interface initialization uses the following functions: + + + + + Interface Initialization + + + + + + + + Invocation time + Function Invoked + Function's parameters + Remark + + + + + First call to g_type_create_instance + for any type implementing interface + + interface's base_init function + On interface's vtable + Rarely necessary to use this. Called once per instantiated classed type implementing the interface. + + + First call to g_type_create_instance + for each type implementing interface + + interface's default_init function + On interface's vtable + Register interface's signals, properties, etc. here. Will be called once. + + + First call to g_type_create_instance + for any type implementing interface + + implementation's interface_init function + On interface's vtable + + Initialize interface implementation. Called for each class that that + implements the interface. Initialize the interface method pointers + in the interface structure to the implementing class's implementation. + + + + +
+
+ +
+ + + Interface Destruction + + + When the last instance of an instantiatable type which registered + an interface implementation is destroyed, the interface's + implementations associated to the type are destroyed. + + + + To destroy an interface implementation, GType first calls the + implementation's interface_finalize function + and then the interface's most-derived + base_finalize function. + + + + Again, it is important to understand, as in + , + that both interface_finalize and base_finalize + are invoked exactly once for the destruction of each implementation of an interface. Thus, + if you were to use one of these functions, you would need to use a static integer variable + which would hold the number of instances of implementations of an interface such that + the interface's class is destroyed only once (when the integer variable reaches zero). + + + + The above process can be summarized as follows: + + Interface Finalization + + + + + + + + Invocation time + Function Invoked + Function's parameters + + + + + Last call to g_type_free_instance for type + implementing interface + + interface's interface_finalize function + On interface's vtable + + + + interface's base_finalize function + On interface's vtable + + + +
+
+
+
+
diff --git a/docs/reference/gobject/tut_howto.xml b/docs/reference/gobject/tut_howto.xml new file mode 100644 index 0000000..b61a328 --- /dev/null +++ b/docs/reference/gobject/tut_howto.xml @@ -0,0 +1,1535 @@ + + + + Tutorial + + + This chapter tries to answer the real-life questions of users and presents + the most common use cases in order from most likely to least + likely. + + + + + How to define and implement a new GObject + + + This chapter focuses on the implementation of a subtype of GObject, for + example to create a custom class hierarchy, or to subclass a GTK+ widget. + + + + Throughout the chapter, a running example of a file viewer program is used, + which has a ViewerFile class to represent a single file being + viewed, and various derived classes for different types of files with + special functionality, such as audio files. The example application also + supports editing files (for example, to tweak a photo being viewed), using + a ViewerEditable interface. + + + + Boilerplate header code + + + The first step before writing the code for your GObject is to write the + type's header which contains the needed type, function and macro + definitions. Each of these elements is nothing but a convention which + is followed by almost all users of GObject, and has been refined over + multiple years of experience developing GObject-based code. If you are + writing a library, it is particularly important for you to adhere closely + to these conventions; users of your library will assume that you have. + Even if not writing a library, it will help other people who want to work + on your project. + + + + Pick a name convention for your headers and source code and stick to it: + + use a dash to separate the prefix from the typename: + viewer-file.h and viewer-file.c + (this is the convention used by Nautilus and most GNOME libraries). + use an underscore to separate the prefix from the + typename: viewer_file.h and + viewer_file.c. + Do not separate the prefix from the typename: + viewerfile.h and viewerfile.c. + (this is the convention used by GTK+) + + Some people like the first two solutions better: it makes reading file + names easier for those with poor eyesight. + + + + The basic conventions for any header which exposes a GType are described + in . + + + + If you want to declare a type named ‘file’ in namespace ‘viewer’, name the + type instance ViewerFile and its class + ViewerFileClass (names are case sensitive). The + recommended method of declaring a type differs based on whether the type + is final or derivable. + + + + Final types cannot be subclassed further, and should be the default choice + for new types — changing a final type to be derivable is always a change + that will be compatible with existing uses of the code, but the converse + will often cause problems. Final types are declared using + G_DECLARE_FINAL_TYPE, + and require a structure to hold the instance data to be declared in the + source code (not the header file). + + +/* + * Copyright/Licensing information. + */ + +/* inclusion guard */ +#ifndef __VIEWER_FILE_H__ +#define __VIEWER_FILE_H__ + +#include <glib-object.h> +/* + * Potentially, include other headers on which this header depends. + */ + +G_BEGIN_DECLS + +/* + * Type declaration. + */ +#define VIEWER_TYPE_FILE viewer_file_get_type () +G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject) + +/* + * Method definitions. + */ +ViewerFile *viewer_file_new (void); + +G_END_DECLS + +#endif /* __VIEWER_FILE_H__ */ + + + + + Derivable types can be subclassed further, and their class and + instance structures form part of the public API which must not be changed + if API stability is cared about. They are declared using + G_DECLARE_DERIVABLE_TYPE: + +/* + * Copyright/Licensing information. + */ + +/* inclusion guard */ +#ifndef __VIEWER_FILE_H__ +#define __VIEWER_FILE_H__ + +#include <glib-object.h> +/* + * Potentially, include other headers on which this header depends. + */ + +G_BEGIN_DECLS + +/* + * Type declaration. + */ +#define VIEWER_TYPE_FILE viewer_file_get_type () +G_DECLARE_DERIVABLE_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject) + +struct _ViewerFileClass +{ + GObjectClass parent_class; + + /* Class virtual function fields. */ + void (* open) (ViewerFile *file, + GError **error); + + /* Padding to allow adding up to 12 new virtual functions without + * breaking ABI. */ + gpointer padding[12]; +}; + +/* + * Method definitions. + */ +ViewerFile *viewer_file_new (void); + +G_END_DECLS + +#endif /* __VIEWER_FILE_H__ */ + + + + + The convention for header includes is to add the minimum number of + #include directives to the top of your headers needed + to compile that header. This + allows client code to simply #include "viewer-file.h", + without needing to know the prerequisites for + viewer-file.h. + + + + + Boilerplate code + + + In your code, the first step is to #include the + needed headers: + +/* + * Copyright information + */ + +#include "viewer-file.h" + +/* Private structure definition. */ +typedef struct { + gchar *filename; + /* stuff */ +} ViewerFilePrivate; + +/* + * forward definitions + */ + + + + + If the class is being declared as final using + G_DECLARE_FINAL_TYPE, its instance structure should + be defined in the C file: + +struct _ViewerFile +{ + GObject parent_instance; + + /* Other members, including private data. */ +}; + + + + + Call the G_DEFINE_TYPE macro (or + G_DEFINE_TYPE_WITH_PRIVATE if your class needs + private data — final types do not need private data) + using the name + of the type, the prefix of the functions and the parent GType to + reduce the amount of boilerplate needed. This macro will: + + + implement the viewer_file_get_type + function + define a parent class pointer accessible from + the whole .c file + add private instance data to the type (if using + G_DEFINE_TYPE_WITH_PRIVATE) + + + + + If the class has been declared as final using + G_DECLARE_FINAL_TYPE (see + ), private data should be placed in + the instance structure, ViewerFile, and + G_DEFINE_TYPE should be used instead of + G_DEFINE_TYPE_WITH_PRIVATE. The instance structure + for a final class is not exposed publicly, and is not embedded in the + instance structures of any derived classes (because the class is final); + so its size can vary without causing incompatibilities for code which uses + the class. Conversely, private data for derivable classes + must be included in a private structure, and + G_DEFINE_TYPE_WITH_PRIVATE must be used. + + +G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT) + +or + +G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT) + + + + + It is also possible to use the + G_DEFINE_TYPE_WITH_CODE macro to control the + get_type function implementation — for instance, to + add a call to the G_IMPLEMENT_INTERFACE macro to + implement an interface. + + + + + Object construction + + + People often get confused when trying to construct their GObjects because of the + sheer number of different ways to hook into the objects's construction process: it is + difficult to figure which is the correct, recommended way. + + + + shows what user-provided functions + are invoked during object instantiation and in which order they are invoked. + A user looking for the equivalent of the simple C++ constructor function should use + the instance_init method. It will be invoked after + all the parents’ instance_init + functions have been invoked. It cannot take arbitrary construction parameters + (as in C++) but if your object needs arbitrary parameters to complete initialization, + you can use construction properties. + + + + Construction properties will be set only after all + instance_init functions have run. + No object reference will be returned to the client of g_object_new + until all the construction properties have been set. + + + + It is important to note that object construction cannot ever + fail. If you require a fallible GObject construction, you can use the + GInitable and + GAsyncInitable + interfaces provided by the GIO library. + + + + You should write the following code first: + +G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT) + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ +} + +static void +viewer_file_init (ViewerFile *self) +{ + ViewerFilePrivate *priv = viewer_file_get_instance_private (self); + + /* initialize all public and private members to reasonable default values. + * They are all automatically initialized to 0 to begin with. */ +} + + + + + If you need special construction properties (with + G_PARAM_CONSTRUCT_ONLY + set), install the properties in + the class_init() function, override the set_property() + and get_property() methods of the GObject class, + and implement them as described by . + + + + Property IDs must start from 1, as 0 is reserved for internal use by + GObject. + +enum +{ + PROP_FILENAME = 1, + PROP_ZOOM_LEVEL, + N_PROPERTIES +}; + +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = viewer_file_set_property; + object_class->get_property = viewer_file_get_property; + + obj_properties[PROP_FILENAME] = + g_param_spec_string ("filename", + "Filename", + "Name of the file to load and display from.", + NULL /* default value */, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + + obj_properties[PROP_ZOOM_LEVEL] = + g_param_spec_uint ("zoom-level", + "Zoom level", + "Zoom level to view the file at.", + 0 /* minimum value */, + 10 /* maximum value */, + 2 /* default value */, + G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, + N_PROPERTIES, + obj_properties); +} + + If you need this, make sure you can build and run code similar to the + code shown above. Also, make sure your construct properties can be set + without side effects during construction. + + + + Some people sometimes need to complete the initialization of an instance + of a type only after the properties passed to the constructors have been + set. This is possible through the use of the constructor() + class method as described in or, + more simply, using the constructed() class method. + Note that the constructed() + virtual function will only be invoked after the properties marked as + G_PARAM_CONSTRUCT_ONLY or + G_PARAM_CONSTRUCT have been consumed, but + before the regular properties passed to g_object_new() + have been set. + + + + + Object destruction + + + Again, it is often difficult to figure out which mechanism to use to + hook into the object's destruction process: when the last + g_object_unref + function call is made, a lot of things happen as described in + . + + + + The destruction process of your object is in two phases: dispose and + finalize. This split is necessary to handle + potential cycles due to the nature of the reference counting mechanism + used by GObject, as well as dealing with temporary revival of + instances in case of signal emission during the destruction sequence. + See for more information. + +struct _ViewerFilePrivate +{ + gchar *filename; + guint zoom_level; + + GInputStream *input_stream; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT) + +static void +viewer_file_dispose (GObject *gobject) +{ + ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject)); + + /* In dispose(), you are supposed to free all types referenced from this + * object which might themselves hold a reference to self. Generally, + * the most simple solution is to unref all members on which you own a + * reference. + */ + + /* dispose() might be called multiple times, so we must guard against + * calling g_object_unref() on an invalid GObject by setting the member + * NULL; g_clear_object() does this for us. + */ + g_clear_object (&priv->input_stream); + + /* Always chain up to the parent class; there is no need to check if + * the parent class implements the dispose() virtual function: it is + * always guaranteed to do so + */ + G_OBJECT_CLASS (viewer_file_parent_class)->dispose (gobject); +} + +static void +viewer_file_finalize (GObject *gobject) +{ + ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject)); + + g_free (priv->filename); + + /* Always chain up to the parent class; as with dispose(), finalize() + * is guaranteed to exist on the parent's class virtual function table + */ + G_OBJECT_CLASS (viewer_file_parent_class)->finalize (gobject); +} + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = viewer_file_dispose; + object_class->finalize = viewer_file_finalize; +} + +static void +viewer_file_init (ViewerFile *self); +{ + ViewerFilePrivate *priv = viewer_file_get_instance_private (self); + + priv->input_stream = g_object_new (VIEWER_TYPE_INPUT_STREAM, NULL); + priv->filename = /* would be set as a property */; +} + + + + + It is possible that object methods might be invoked after dispose is + run and before finalize runs. GObject does not consider this to be a + program error: you must gracefully detect this and neither crash nor + warn the user, by having a disposed instance revert to an inert state. + + + + + Object methods + + + Just as with C++, there are many different ways to define object + methods and extend them: the following list and sections draw on + C++ vocabulary. (Readers are expected to know basic C++ concepts. + Those who have not had to write C++ code recently can refer to e.g. + to refresh + their memories.) + + + non-virtual public methods, + + + virtual public methods and + + + virtual private methods + + + + + + Non-virtual public methods + + + These are the simplest, providing a simple method which + acts on the object. Provide a function + prototype in the header and an implementation of that prototype + in the source file. + +/* declaration in the header. */ +void viewer_file_open (ViewerFile *self, + GError **error); + +/* implementation in the source file */ +void +viewer_file_open (ViewerFile *self, + GError **error) +{ + g_return_if_fail (VIEWER_IS_FILE (self)); + g_return_if_fail (error == NULL || *error == NULL); + + /* do stuff here. */ +} + + + + + + Virtual public methods + + + This is the preferred way to create GObjects with overridable methods: + + + Define the common method and its virtual function in the + class structure in the public header + + + Define the common method in the header file and implement it in the + source file + + + Implement a base version of the virtual function in the source + file and initialize the virtual function pointer to this + implementation in the object’s class_init + function; or leave it as NULL for a ‘pure + virtual’ method which must be overridden by derived classes + + + Re-implement the virtual function in each derived class which needs + to override it + + + + + Note that virtual functions can only be defined if the class is + derivable, declared using + G_DECLARE_DERIVABLE_TYPE + so the class structure can be defined. + +/* declaration in viewer-file.h. */ +#define VIEWER_TYPE_FILE viewer_file_get_type () +G_DECLARE_DERIVABLE_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject) + +struct _ViewerFileClass +{ + GObjectClass parent_class; + + /* stuff */ + void (*open) (ViewerFile *self, + GError **error); + + /* Padding to allow adding up to 12 new virtual functions without + * breaking ABI. */ + gpointer padding[12]; +}; + +void viewer_file_open (ViewerFile *self, + GError **error); + +/* implementation in viewer-file.c */ +void +viewer_file_open (ViewerFile *self, + GError **error) +{ + ViewerFileClass *klass; + + g_return_if_fail (VIEWER_IS_FILE (self)); + g_return_if_fail (error == NULL || *error == NULL); + + klass = VIEWER_FILE_GET_CLASS (self); + g_return_if_fail (klass->open != NULL); + + klass->open (self, error); +} + + The code above simply redirects the open call + to the relevant virtual function. + + + + It is possible to provide a default + implementation for this class method in the object's + class_init function: initialize the + klass->open field to a pointer to the + actual implementation. + By default, class methods that are not inherited are initialized to + NULL, and thus are to be considered "pure virtual". + +static void +viewer_file_real_close (ViewerFile *self, + GError **error) +{ + /* Default implementation for the virtual method. */ +} + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ + /* this is not necessary, except for demonstration purposes. + * + * pure virtual method: mandates implementation in children. + */ + klass->open = NULL; + + /* merely virtual method. */ + klass->close = viewer_file_real_close; +} + +void +viewer_file_open (ViewerFile *self, + GError **error) +{ + ViewerFileClass *klass; + + g_return_if_fail (VIEWER_IS_FILE (self)); + g_return_if_fail (error == NULL || *error == NULL); + + klass = VIEWER_FILE_GET_CLASS (self); + + /* if the method is purely virtual, then it is a good idea to + * check that it has been overridden before calling it, and, + * depending on the intent of the class, either ignore it silently + * or warn the user. + */ + g_return_if_fail (klass->open != NULL); + klass->open (self, error); +} + +void +viewer_file_close (ViewerFile *self, + GError **error) +{ + ViewerFileClass *klass; + + g_return_if_fail (VIEWER_IS_FILE (self)); + g_return_if_fail (error == NULL || *error == NULL); + + klass = VIEWER_FILE_GET_CLASS (self); + if (klass->close != NULL) + klass->close (self, error); +} + + + + + + Virtual private Methods + + + These are very similar to virtual + public methods. They just don't + have a public function to call directly. The header + file contains only a declaration of the virtual function: + +/* declaration in viewer-file.h. */ +struct _ViewerFileClass +{ + GObjectClass parent; + + /* Public virtual method as before. */ + void (*open) (ViewerFile *self, + GError **error); + + /* Private helper function to work out whether the file can be loaded via + * memory mapped I/O, or whether it has to be read as a stream. */ + gboolean (*can_memory_map) (ViewerFile *self); + + /* Padding to allow adding up to 12 new virtual functions without + * breaking ABI. */ + gpointer padding[12]; +}; + +void viewer_file_open (ViewerFile *self, GError **error); + + These virtual functions are often used to delegate part of the job + to child classes: + +/* this accessor function is static: it is not exported outside of this file. */ +static gboolean +viewer_file_can_memory_map (ViewerFile *self) +{ + return VIEWER_FILE_GET_CLASS (self)->can_memory_map (self); +} + +void +viewer_file_open (ViewerFile *self, + GError **error) +{ + g_return_if_fail (VIEWER_IS_FILE (self)); + g_return_if_fail (error == NULL || *error == NULL); + + /* + * Try to load the file using memory mapped I/O, if the implementation of the + * class determines that is possible using its private virtual method. + */ + if (viewer_file_can_memory_map (self)) + { + /* Load the file using memory mapped I/O. */ + } + else + { + /* Fall back to trying to load the file using streaming I/O… */ + } +} + + + + + Again, it is possible to provide a default implementation for this + private virtual function: + +static gboolean +viewer_file_real_can_memory_map (ViewerFile *self) +{ + /* As an example, always return false. Or, potentially return true if the + * file is local. */ + return FALSE; +} + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ + /* non-pure virtual method; does not have to be implemented in children. */ + klass->can_memory_map = viewer_file_real_can_memory_map; +} + + + + + Derived classes can then override the method with code such as: + +static void +viewer_audio_file_class_init (ViewerAudioFileClass *klass) +{ + ViewerFileClass *file_class = VIEWER_FILE_CLASS (klass); + + /* implement pure virtual function. */ + file_class->can_memory_map = viewer_audio_file_can_memory_map; +} + + + + + + + Chaining up + + Chaining up is often loosely defined by the following set of + conditions: + + Parent class A defines a public virtual method named foo and + provides a default implementation. + Child class B re-implements method foo. + B’s implementation of foo calls (‘chains up to’) its parent class A’s implementation of foo. + + There are various uses of this idiom: + + You need to extend the behaviour of a class without modifying its code. You create + a subclass to inherit its implementation, re-implement a public virtual method to modify the behaviour + and chain up to ensure that the previous behaviour is not really modified, just extended. + + You need to implement the + Chain + Of Responsibility pattern: each object of the inheritance + tree chains up to its parent (typically, at the beginning or the end of the method) to ensure that + each handler is run in turn. + + + + + To explicitly chain up to the implementation of the virtual method in the parent class, + you first need a handle to the original parent class structure. This pointer can then be used to + access the original virtual function pointer and invoke it directly. + + + The original adjective used in this sentence is not innocuous. To fully + understand its meaning, recall how class structures are initialized: for each object type, + the class structure associated with this object is created by first copying the class structure of its + parent type (a simple memcpy) and then by invoking the class_init callback on + the resulting class structure. Since the class_init callback is responsible for overwriting the class structure + with the user re-implementations of the class methods, the modified copy of the parent class + structure stored in the derived instance cannot be used. A copy of the class structure of an instance of the parent + class is needed. + + + + + + Use the parent_class pointer created and initialized + by the + G_DEFINE_TYPE + family of macros, for instance: + +static void +b_method_to_call (B *obj, gint some_param) +{ + /* do stuff before chain up */ + + /* call the method_to_call() virtual function on the + * parent of BClass, AClass. + * + * remember the explicit cast to AClass* + */ + A_CLASS (b_parent_class)->method_to_call (obj, some_param); + + /* do stuff after chain up */ +} + + + + + + + + + + How to define and implement interfaces + + + Defining interfaces + + + The theory behind how GObject interfaces work is given in + ; this section covers how to + define and implement an interface. + + + + The first step is to get the header right. This interface + defines three methods: + +/* + * Copyright/Licensing information. + */ + +#ifndef __VIEWER_EDITABLE_H__ +#define __VIEWER_EDITABLE_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define VIEWER_TYPE_EDITABLE viewer_editable_get_type () +G_DECLARE_INTERFACE (ViewerEditable, viewer_editable, VIEWER, EDITABLE, GObject) + +struct _ViewerEditableInterface +{ + GTypeInterface parent_iface; + + void (*save) (ViewerEditable *self, + GError **error); + void (*undo) (ViewerEditable *self, + guint n_steps); + void (*redo) (ViewerEditable *self, + guint n_steps); +}; + +void viewer_editable_save (ViewerEditable *self, + GError **error); +void viewer_editable_undo (ViewerEditable *self, + guint n_steps); +void viewer_editable_redo (ViewerEditable *self, + guint n_steps); + +G_END_DECLS + +#endif /* __VIEWER_EDITABLE_H__ */ + + This code is the same as the code for a normal GType + which derives from a GObject except for a few details: + + + The _GET_CLASS function is called + _GET_IFACE (and is defined by + G_DECLARE_INTERFACE). + + + The instance type, ViewerEditable, is not fully defined: it is + used merely as an abstract type which represents an instance of + whatever object which implements the interface. + + + The parent of the ViewerEditableInterface is + GTypeInterface, not GObjectClass. + + + + + + The implementation of the ViewerEditable type itself is trivial: + + G_DEFINE_INTERFACE + creates a viewer_editable_get_type function which registers the + type in the type system. The third argument is used to define a + prerequisite interface + (which we'll talk about more later). Just pass 0 for this + argument when an interface has no prerequisite. + + viewer_editable_default_init is expected + to register the interface's signals if there are any (we will see a bit + later how to use them). + The interface methods viewer_editable_save, + viewer_editable_undo and viewer_editable_redo dereference the interface + structure to access its associated interface function and call it. + + + +G_DEFINE_INTERFACE (ViewerEditable, viewer_editable, G_TYPE_OBJECT) + +static void +viewer_editable_default_init (ViewerEditableInterface *iface) +{ + /* add properties and signals to the interface here */ +} + +void +viewer_editable_save (ViewerEditable *self, + GError **error) +{ + ViewerEditableInterface *iface; + + g_return_if_fail (VIEWER_IS_EDITABLE (self)); + g_return_if_fail (error == NULL || *error == NULL); + + iface = VIEWER_EDITABLE_GET_IFACE (self); + g_return_if_fail (iface->save != NULL); + iface->save (self, error); +} + +void +viewer_editable_undo (ViewerEditable *self, + guint n_steps) +{ + ViewerEditableInterface *iface; + + g_return_if_fail (VIEWER_IS_EDITABLE (self)); + + iface = VIEWER_EDITABLE_GET_IFACE (self); + g_return_if_fail (iface->undo != NULL); + iface->undo (self, n_steps); +} + +void +viewer_editable_redo (ViewerEditable *self, + guint n_steps) +{ + ViewerEditableInterface *iface; + + g_return_if_fail (VIEWER_IS_EDITABLE (self)); + + iface = VIEWER_EDITABLE_GET_IFACE (self); + g_return_if_fail (iface->redo != NULL); + iface->redo (self, n_steps); +} + + + + + + Implementing interfaces + + + Once the interface is defined, implementing it is rather trivial. + + + + The first step is to define a normal final GObject class exactly as in + . + + + + The second step is to implement ViewerFile by defining + it using + G_DEFINE_TYPE_WITH_CODE + and + G_IMPLEMENT_INTERFACE + instead of + G_DEFINE_TYPE: + +static void viewer_file_editable_interface_init (ViewerEditableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE, + viewer_file_editable_interface_init)) + + This definition is very much like all the similar functions seen + previously. The only interface-specific code present here is the use of + G_IMPLEMENT_INTERFACE. + + + Classes can implement multiple interfaces by using multiple calls to + G_IMPLEMENT_INTERFACE + inside the call to + G_DEFINE_TYPE_WITH_CODE + + + + viewer_file_editable_interface_init, the interface + initialization function: inside it every virtual method of the interface + must be assigned to its implementation: + +static void +viewer_file_editable_save (ViewerFile *self, + GError **error) +{ + g_print ("File implementation of editable interface save method: %s.\n", + self->filename); +} + +static void +viewer_file_editable_undo (ViewerFile *self, + guint n_steps) +{ + g_print ("File implementation of editable interface undo method: %s.\n", + self->filename); +} + +static void +viewer_file_editable_redo (ViewerFile *self, + guint n_steps) +{ + g_print ("File implementation of editable interface redo method: %s.\n", + self->filename); +} + +static void +viewer_file_editable_interface_init (ViewerEditableInterface *iface) +{ + iface->save = viewer_file_editable_save; + iface->undo = viewer_file_editable_undo; + iface->redo = viewer_file_editable_redo; +} + +static void +viewer_file_init (ViewerFile *self) +{ + /* Instance variable initialisation code. */ +} + + + + If the object is not of final type, e.g. was declared using + G_DECLARE_DERIVABLE_TYPE + then + G_ADD_PRIVATE + macro should be added. The private structure should be declared exactly + as for a normal derivable object, see . + +G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT, + G_ADD_PRIVATE (ViewerFile) + G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE, + viewer_file_editable_interface_init)) + + + + + + Interface definition prerequisites + + + To specify that an interface requires the presence of other interfaces + when implemented, GObject introduces the concept of + prerequisites: it is possible to associate + a list of prerequisite types to an interface. For example, if + object A wishes to implement interface I1, and if interface I1 has a + prerequisite on interface I2, A has to implement both I1 and I2. + + + + The mechanism described above is, in practice, very similar to + Java's interface I1 extends interface I2. The example below shows + the GObject equivalent: + +/* Make the ViewerEditableLossy interface require ViewerEditable interface. */ +G_DEFINE_INTERFACE (ViewerEditableLossy, viewer_editable_lossy, VIEWER_TYPE_EDITABLE) + + In the G_DEFINE_INTERFACE + call above, the third parameter defines the prerequisite type. This + is the GType of either an interface or a class. In this case + the ViewerEditable interface is a prerequisite of + ViewerEditableLossy. The code + below shows how an implementation can implement both interfaces and + register their implementations: + +static void +viewer_file_editable_lossy_compress (ViewerEditableLossy *editable) +{ + ViewerFile *self = VIEWER_FILE (editable); + + g_print ("File implementation of lossy editable interface compress method: %s.\n", + self->filename); +} + +static void +viewer_file_editable_lossy_interface_init (ViewerEditableLossyInterface *iface) +{ + iface->compress = viewer_file_editable_lossy_compress; +} + +static void +viewer_file_editable_save (ViewerEditable *editable, + GError **error) +{ + ViewerFile *self = VIEWER_FILE (editable); + + g_print ("File implementation of editable interface save method: %s.\n", + self->filename); +} + +static void +viewer_file_editable_undo (ViewerEditable *editable, + guint n_steps) +{ + ViewerFile *self = VIEWER_FILE (editable); + + g_print ("File implementation of editable interface undo method: %s.\n", + self->filename); +} + +static void +viewer_file_editable_redo (ViewerEditable *editable, + guint n_steps) +{ + ViewerFile *self = VIEWER_FILE (editable); + + g_print ("File implementation of editable interface redo method: %s.\n", + self->filename); +} + +static void +viewer_file_editable_interface_init (ViewerEditableInterface *iface) +{ + iface->save = viewer_file_editable_save; + iface->undo = viewer_file_editable_undo; + iface->redo = viewer_file_editable_redo; +} + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ + /* Nothing here. */ +} + +static void +viewer_file_init (ViewerFile *self) +{ + /* Instance variable initialisation code. */ +} + +G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE, + viewer_file_editable_interface_init) + G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE_LOSSY, + viewer_file_editable_lossy_interface_init)) + + It is very important to notice that the order in which interface + implementations are added to the main object is not random: + g_type_add_interface_static, + which is called by + G_IMPLEMENT_INTERFACE, + must be invoked first on the interfaces which have no prerequisites and then on + the others. + + + + + Interface properties + + + GObject interfaces can also have + properties. Declaration of the interface properties is similar to + declaring the properties of ordinary GObject types as explained in + , except that + g_object_interface_install_property + is used to declare the properties instead of + g_object_class_install_property. + + + + To include a property named 'autosave-frequency' of type gdouble in the + ViewerEditable interface example code above, we only need to + add one call in viewer_editable_default_init as shown + below: + +static void +viewer_editable_default_init (ViewerEditableInterface *iface) +{ + g_object_interface_install_property (iface, + g_param_spec_double ("autosave-frequency", + "Autosave frequency", + "Frequency (in per-seconds) to autosave backups of the editable content at. " + "Or zero to disable autosaves.", + 0.0, /* minimum */ + G_MAXDOUBLE, /* maximum */ + 0.0, /* default */ + G_PARAM_READWRITE)); +} + + + + + One point worth noting is that the declared property wasn't assigned an + integer ID. The reason being that integer IDs of properties are used + only inside the get_property and + set_property virtual methods. Since interfaces + declare but do not implement properties, there is no + need to assign integer IDs to them. + + + + An implementation declares and defines its properties in the usual + way as explained in , except for one + small change: it can declare the properties of the interface it + implements using g_object_class_override_property + instead of g_object_class_install_property. + The following code snippet shows the modifications needed in the + ViewerFile declaration and implementation above: + +struct _ViewerFile +{ + GObject parent_instance; + + gdouble autosave_frequency; +}; + +enum +{ + PROP_AUTOSAVE_FREQUENCY = 1, + N_PROPERTIES +}; + +static void +viewer_file_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ViewerFile *file = VIEWER_FILE (object); + + switch (prop_id) + { + case PROP_AUTOSAVE_FREQUENCY: + file->autosave_frequency = g_value_get_double (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +viewer_file_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ViewerFile *file = VIEWER_FILE (object); + + switch (prop_id) + { + case PROP_AUTOSAVE_FREQUENCY: + g_value_set_double (value, file->autosave_frequency); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +viewer_file_class_init (ViewerFileClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = viewer_file_set_property; + object_class->get_property = viewer_file_get_property; + + g_object_class_override_property (object_class, PROP_AUTOSAVE_FREQUENCY, "autosave-frequency"); +} + + + + + + + Overriding interface methods + + + If a base class already implements an interface and a derived + class needs to implement the same interface but needs to override certain + methods, you must reimplement the interface and set only the interface + methods which need overriding. + + + + In this example, ViewerAudioFile is derived from + ViewerFile. Both implement the ViewerEditable + interface. ViewerAudioFile only implements one method of the + ViewerEditable interface and uses the base class implementation of + the other. + +static void +viewer_audio_file_editable_save (ViewerEditable *editable, + GError **error) +{ + ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable); + + g_print ("Audio file implementation of editable interface save method.\n"); +} + +static void +viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface) +{ + /* Override the implementation of save(). */ + iface->save = viewer_audio_file_editable_save; + + /* + * Leave iface->undo and ->redo alone, they are already set to the + * base class implementation. + */ +} + +G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE, + G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE, + viewer_audio_file_editable_interface_init)) + +static void +viewer_audio_file_class_init (ViewerAudioFileClass *klass) +{ + /* Nothing here. */ +} + +static void +viewer_audio_file_init (ViewerAudioFile *self) +{ + /* Nothing here. */ +} + + + + + To access the base class interface implementation use + g_type_interface_peek_parent + from within an interface's default_init function. + + + + To call the base class implementation of an interface + method from a derived class where than interface method has been + overridden, stash away the pointer returned from + g_type_interface_peek_parent + in a global variable. + + + + In this example ViewerAudioFile overrides the + save interface method. In its overridden method + it calls the base class implementation of the same interface method. + +static ViewerEditableInterface *viewer_editable_parent_interface = NULL; + +static void +viewer_audio_file_editable_save (ViewerEditable *editable, + GError **error) +{ + ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable); + + g_print ("Audio file implementation of editable interface save method.\n"); + + /* Now call the base implementation */ + viewer_editable_parent_interface->save (editable, error); +} + +static void +viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface) +{ + viewer_editable_parent_interface = g_type_interface_peek_parent (iface); + + iface->save = viewer_audio_file_editable_save; +} + +G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE, + G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE, + viewer_audio_file_editable_interface_init)) + +static void +viewer_audio_file_class_init (ViewerAudioFileClass *klass) +{ + /* Nothing here. */ +} + +static void +viewer_audio_file_init (ViewerAudioFile *self) +{ + /* Nothing here. */ +} + + + + + + + + + + How to create and use signals + + + The signal system in GType is pretty complex and + flexible: it is possible for its users to connect at runtime any + number of callbacks (implemented in any language for which a binding + exists) + + A Python callback can be connected to any signal on any + C-based GObject, and vice versa, assuming that the Python object + inherits from GObject. + + to any signal and to stop the emission of any signal at any + state of the signal emission process. This flexibility makes it + possible to use GSignal for much more than just emitting signals to + multiple clients. + + + + Simple use of signals + + + The most basic use of signals is to implement event + notification. For example, given a ViewerFile object with + a write method, a signal could be emitted whenever + the file is changed using that method. + The code below shows how the user can connect a callback to the + "changed" signal. + +file = g_object_new (VIEWER_FILE_TYPE, NULL); + +g_signal_connect (file, "changed", (GCallback) changed_event, NULL); + +viewer_file_write (file, buffer, strlen (buffer)); + + + + + The ViewerFile signal is registered in the + class_init function: + +file_signals[CHANGED] = + g_signal_newv ("changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + NULL /* closure */, + NULL /* accumulator */, + NULL /* accumulator data */, + NULL /* C marshaller */, + G_TYPE_NONE /* return_type */, + 0 /* n_params */, + NULL /* param_types */); + + and the signal is emitted in viewer_file_write: + +void +viewer_file_write (ViewerFile *self, + const guint8 *buffer, + gsize size) +{ + g_return_if_fail (VIEWER_IS_FILE (self)); + g_return_if_fail (buffer != NULL || size == 0); + + /* First write data. */ + + /* Then, notify user of data written. */ + g_signal_emit (self, file_signals[CHANGED], 0 /* details */); +} + + As shown above, the details parameter can safely be set to zero if no + detail needs to be conveyed. For a discussion of what it can be used for, + see + + + + The C signal marshaller should always be NULL, in which + case the best marshaller for the given closure type will be chosen by + GLib. This may be an internal marshaller specific to the closure type, or + g_cclosure_marshal_generic, which implements generic + conversion of arrays of parameters to C callback invocations. GLib used to + require the user to write or generate a type-specific marshaller and pass + that, but that has been deprecated in favour of automatic selection of + marshallers. + + + + Note that g_cclosure_marshal_generic is slower than + non-generic marshallers, so should be avoided for performance critical + code. However, performance critical code should rarely be using signals + anyway, as emitting a signal blocks on emitting it to all listeners, which + has potentially unbounded cost. + + + + diff --git a/docs/reference/gobject/tut_intro.xml b/docs/reference/gobject/tut_intro.xml new file mode 100644 index 0000000..7614bf0 --- /dev/null +++ b/docs/reference/gobject/tut_intro.xml @@ -0,0 +1,185 @@ + + + + Background + + + GObject, and its lower-level type system, GType, are used by GTK+ and most GNOME libraries to + provide: + + object-oriented C-based APIs and + automatic transparent API bindings to other compiled + or interpreted languages. + + + + + A lot of programmers are used to working with compiled-only or dynamically interpreted-only + languages and do not understand the challenges associated with cross-language interoperability. + This introduction tries to provide an insight into these challenges and briefly describes + the solution chosen by GLib. + + + + The following chapters go into greater detail into how GType and GObject work and + how you can use them as a C programmer. It is useful to keep in mind that + allowing access to C objects from other interpreted languages was one of the major design + goals: this can often explain the sometimes rather convoluted APIs and features present + in this library. + + + + Data types and programming + + + One could say + that a programming language is merely a way to create data types and manipulate them. Most languages + provide a number of language-native types and a few primitives to create more complex types based + on these primitive types. + + + + In C, the language provides types such as char, long, + pointer. During compilation of C code, the compiler maps these + language types to the compiler's target architecture machine types. If you are using a C interpreter + (assuming one exists), the interpreter (the program which interprets + the source code and executes it) maps the language types to the machine types of the target machine at + runtime, during the program execution (or just before execution if it uses a Just In Time compiler engine). + + + + Perl and Python are interpreted languages which do not really provide type definitions similar + to those used by C. Perl and Python programmers manipulate variables and the type of the variables + is decided only upon the first assignment or upon the first use which forces a type on the variable. + The interpreter also often provides a lot of automatic conversions from one type to the other. For example, + in Perl, a variable which holds an integer can be automatically converted to a string given the + required context: + +my $tmp = 10; +print "this is an integer converted to a string:" . $tmp . "\n"; + + Of course, it is also often possible to explicitly specify conversions when the default conversions provided + by the language are not intuitive. + + + + + + Exporting a C API + + + C APIs are defined by a set of functions and global variables which are usually exported from a + binary. C functions have an arbitrary number of arguments and one return value. Each function is thus + uniquely identified by the function name and the set of C types which describe the function arguments + and return value. The global variables exported by the API are similarly identified by their name and + their type. + + + + A C API is thus merely defined by a set of names to which a set of types are associated. If you know the + function calling convention and the mapping of the C types to the machine types used by the platform you + are on, you can resolve the name of each function to find where the code associated to this function + is located in memory, and then construct a valid argument list for the function. Finally, all you have to + do is trigger a call to the target C function with the argument list. + + + + For the sake of discussion, here is a sample C function and the associated 32 bit x86 + assembly code generated by GCC on a Linux computer: + +static void +function_foo (int foo) +{ +} + +int +main (int argc, + char *argv[]) +{ + function_foo (10); + + return 0; +} + +push $0xa +call 0x80482f4 <function_foo> + + The assembly code shown above is pretty straightforward: the first instruction pushes + the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls + function_foo. As you can see, C function calls are implemented by + GCC as native function calls (this is probably the fastest implementation possible). + + + + Now, let's say we want to call the C function function_foo from + a Python program. To do this, the Python interpreter needs to: + + Find where the function is located. This probably means finding the binary generated by the C compiler + which exports this function. + Load the code of the function in executable memory. + Convert the Python parameters to C-compatible parameters before calling + the function. + Call the function with the right calling convention. + Convert the return values of the C function to Python-compatible + variables to return them to the Python code. + + + + + The process described above is pretty complex and there are a lot of ways to make it entirely automatic + and transparent to C and Python programmers: + + The first solution is to write by hand a lot of glue code, once for each function exported or imported, + which does the Python-to-C parameter conversion and the C-to-Python return value conversion. This glue code is then + linked with the interpreter which allows Python programs to call Python functions which delegate work to + C functions. + Another, nicer solution is to automatically generate the glue code, once for each function exported or + imported, with a special compiler which + reads the original function signature. + The solution used by GLib is to use the GType library which holds at runtime a description of + all the objects manipulated by the programmer. This so-called dynamic type + + + There are numerous different implementations of dynamic type systems: all C++ + compilers have one, Java and .NET have one too. A dynamic type system allows you + to get information about every instantiated object at runtime. It can be implemented + by a process-specific database: every new object created registers the characteristics + of its associated type in the type system. It can also be implemented by introspection + interfaces. The common point between all these different type systems and implementations + is that they all allow you to query for object metadata at runtime. + + + library is then used by special generic glue code to automatically convert function parameters and + function calling conventions between different runtime domains. + + The greatest advantage of the solution implemented by GType is that the glue code sitting at the runtime domain + boundaries is written once: the figure below states this more clearly. +
+ + + + + + + + +
+ + Currently, there exist at least Python and Perl generic glue code which makes it possible to use + C objects written with GType directly in Python or Perl, with a minimum amount of work: there + is no need to generate huge amounts of glue code either automatically or by hand. +
+ + + Although that goal was arguably laudable, its pursuit has had a major influence on + the whole GType/GObject library. C programmers are likely to be puzzled at the complexity + of the features exposed in the following chapters if they forget that the GType/GObject library + was not only designed to offer OO-like features to C programmers but also transparent + cross-language interoperability. + + +
+ +
diff --git a/docs/reference/gobject/tut_tools.xml b/docs/reference/gobject/tut_tools.xml new file mode 100644 index 0000000..f1076e8 --- /dev/null +++ b/docs/reference/gobject/tut_tools.xml @@ -0,0 +1,125 @@ + + + + Related Tools + + + + Several useful developer tools have been build around GObject + technology. The next sections briefly introduce them and link to + the respective project pages. + + + + For example, writing GObjects is often seen as a tedious task. It + requires a lot of typing and just doing a copy/paste requires a + great deal of care. A lot of projects and scripts have been + written to generate GObject skeleton form boilerplate code, or + even translating higher-level language into plain C. + + + + + Vala + + From the Vala + homepage itself: Vala is a new programming language + that aims to bring modern programming language features to GNOME + developers without imposing any additional runtime requirements + and without using a different ABI compared to applications and + libraries written in C. + + + + The syntax of Vala is similar to C#. The available compiler + translates Vala into GObject C code. It can also compile + non-GObject C, using plain C API. + + + + + GObject builder + + + In order to help a GObject class developer, one obvious idea is + to use some sort of templates for the skeletons and then run + them through a special tool to generate the real C files. GOB (or GOB2) is + such a tool. It is a preprocessor which can be used to build + GObjects with inline C code so that there is no need to edit the + generated C code. The syntax is inspired by Java and Yacc or + Lex. The implementation is intentionally kept simple: the inline C + code provided by the user is not parsed. + + + + + Graphical inspection of GObjects + + + Yet another tool that you may find helpful when working with + GObjects is G-Inspector. It + is able to display GLib/GTK+ objects and their properties. + + + + + Debugging reference count problems + + + The reference counting scheme used by GObject does solve quite + a few memory management problems but also introduces new sources of bugs. + In large applications, finding the exact spot where the reference count + of an Object is not properly handled can be very difficult. + + + A useful tool in debugging reference counting problems is to + set breakpoints in gdb on g_object_ref() and g_object_unref(). + Once you know the address of the object you are interested in, + you can make the breakpoints conditional: + +break g_object_ref if _object == 0xcafebabe +break g_object_unref if _object == 0xcafebabe + + + + + + Writing API docs + + The API documentation for most of the GLib, GObject, GTK+ and GNOME + libraries is built with a combination of complex tools. Typically, the part of + the documentation which describes the behavior of each function is extracted + from the specially-formatted source code comments by a tool named gtk-doc which + generates DocBook XML and merges this DocBook XML with a set of template XML + DocBook files. These XML DocBook files are finally processed with xsltproc + (a small program part of the libxslt library) to generate the final HTML + output. Other tools can be used to generate PDF output from the source XML. + The following code excerpt shows what these comments look like. + +/** + * gtk_widget_freeze_child_notify: + * @widget: a #GtkWidget + * + * Stops emission of "child-notify" signals on @widget. The signals are + * queued until gtk_widget_thaw_child_notify() is called on @widget. + * + * This is the analogue of g_object_freeze_notify() for child properties. + **/ +void +gtk_widget_freeze_child_notify (GtkWidget *widget) +{ +... + + + + Thorough + documentation + on how to set up and use gtk-doc in your project is provided on the + GNOME developer website. + + + diff --git a/docs/reference/gobject/version.xml.in b/docs/reference/gobject/version.xml.in new file mode 100644 index 0000000..af9b9c4 --- /dev/null +++ b/docs/reference/gobject/version.xml.in @@ -0,0 +1 @@ +@GLIB_VERSION@ diff --git a/docs/reference/gobject/xml/gtkdocentities.ent.in b/docs/reference/gobject/xml/gtkdocentities.ent.in new file mode 100644 index 0000000..f12c9ff --- /dev/null +++ b/docs/reference/gobject/xml/gtkdocentities.ent.in @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/reference/gobject/xml/meson.build b/docs/reference/gobject/xml/meson.build new file mode 100644 index 0000000..6aeb745 --- /dev/null +++ b/docs/reference/gobject/xml/meson.build @@ -0,0 +1,14 @@ +ent_conf = configuration_data() +ent_conf.set('PACKAGE', 'glib') +ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new') +ent_conf.set('PACKAGE_NAME', 'glib') +ent_conf.set('PACKAGE_STRING', 'glib') +ent_conf.set('PACKAGE_TARNAME', 'glib') +ent_conf.set('PACKAGE_URL', 'FIXME') +ent_conf.set('PACKAGE_VERSION', glib_version) +ent_conf.set('PACKAGE_API_VERSION', glib_api_version) +configure_file( + input: 'gtkdocentities.ent.in', + output: 'gtkdocentities.ent', + configuration: ent_conf +) diff --git a/docs/reference/meson.build b/docs/reference/meson.build new file mode 100644 index 0000000..8128e21 --- /dev/null +++ b/docs/reference/meson.build @@ -0,0 +1,62 @@ +# The list of minor versions in the 2.x.x series which have had +# GLIB_AVAILABLE_IN_* macros. This should include the current unreleased stable +# version. +# +# FIXME: It would be good to be able to generate this list: +# https://github.com/mesonbuild/meson/issues/5026 +stable_2_series_versions = [ + '26', '28', '30', '32', '34', '36', '38', + '40', '42', '44', '46', '48', '50', '52', '54', '56', '58', + '60', '62', '64', '66', '68', '70', '72', +] + +ignore_decorators = [ + 'GLIB_VAR', + 'G_GNUC_INTERNAL', + 'G_GNUC_WARN_UNUSED_RESULT', + 'GLIB_AVAILABLE_IN_ALL', +] + +foreach version : stable_2_series_versions + ignore_decorators += [ + # Note that gtkdoc is going to use those in regex, and the longest match + # must come first. That's why '_FOR()' variant comes first. + # gtkdoc special-case '()' and replace it by a regex matching a symbol name. + 'GLIB_AVAILABLE_IN_2_' + version, + 'GLIB_DEPRECATED_IN_2_' + version + '_FOR()', + 'GLIB_DEPRECATED_IN_2_' + version, + + 'GLIB_AVAILABLE_STATIC_INLINE_IN_2_' + version, + + 'GLIB_AVAILABLE_ENUMERATOR_IN_2_' + version, + 'GLIB_DEPRECATED_ENUMERATOR_IN_2_' + version + '_FOR()', + 'GLIB_DEPRECATED_ENUMERATOR_IN_2_' + version, + + 'GLIB_AVAILABLE_MACRO_IN_2_' + version, + 'GLIB_DEPRECATED_MACRO_IN_2_' + version + '_FOR()', + 'GLIB_DEPRECATED_MACRO_IN_2_' + version, + + 'GLIB_AVAILABLE_TYPE_IN_2_' + version, + 'GLIB_DEPRECATED_TYPE_IN_2_' + version + '_FOR()', + 'GLIB_DEPRECATED_TYPE_IN_2_' + version, + ] +endforeach + +gtkdoc_common_scan_args = [ + '--ignore-decorators=' + '|'.join(ignore_decorators), +] + +if get_option('gtk_doc') + if not meson.version().version_compare('>=0.52.0') + error('Building documentation requires Meson >= 0.52.0.') + endif + # Check we have the minimum gtk-doc version required. Older versions won't + # generate correct documentation. + dependency('gtk-doc', version : '>=1.32.1', + fallback : ['gtk-doc', 'dummy_dep'], + default_options : ['tests=false']) +endif + +subdir('gio') +subdir('glib') +subdir('gobject') diff --git a/fuzzing/README.md b/fuzzing/README.md new file mode 100644 index 0000000..21565e3 --- /dev/null +++ b/fuzzing/README.md @@ -0,0 +1,51 @@ +Fuzz targets used by [oss-fuzz](https://github.com/google/oss-fuzz/). + +Useful links: [Dashboard](https://oss-fuzz.com/) _(requires access)_, [Build logs](https://oss-fuzz-build-logs.storage.googleapis.com/index.html), [Coverage](https://oss-fuzz.com/coverage-report/job/libfuzzer_asan_glib/latest) + +## How to add new targets + +Add **fuzz_target_name.c** and edit `meson.build` accordingly. + +New targets are picked up by oss-fuzz automatically within a day. Targets must not be renamed once added. + +Add (optional) **fuzz_target_name.dict** containing keywords and magic bytes. + +Add (optional) **fuzz_target_name.corpus** with file names on separate lines. Wildcards `?`, `*` and `**` are supported. Examples below. + +```bash +glib/* # all files in directory glib +glib/** # all files in directory glib and sub-directories +**.xbel # all files ending with .xbel in the repository +``` + +Recommended reading: [Fuzz Target](https://llvm.org/docs/LibFuzzer.html#fuzz-target), [Dictionaries](https://llvm.org/docs/LibFuzzer.html#dictionaries), [Corpus](https://llvm.org/docs/LibFuzzer.html#corpus) + +## How to reproduce oss-fuzz bugs locally + +Build with at least the following flags, choosing a sanitizer as needed. A somewhat recent version of [clang](http://clang.llvm.org/) is recommended. + +```bash +$ CC=clang CXX=clang++ meson DIR -Db_sanitize= -Db_lundef=false +``` + +Afterwards run the affected target against the provided test case. + +```bash +$ DIR/fuzzing/fuzz_target_name FILE +``` + +#### FAQs + +###### What about Memory Sanitizer (MSAN)? + +Correct MSAN instrumentation is [difficult to achieve](https://clang.llvm.org/docs/MemorySanitizer.html#handling-external-code) locally, so false positives are very likely to mask the actual bug. + +If need be, [you can still reproduce](https://google.github.io/oss-fuzz/advanced-topics/reproducing/#building-using-docker) those bugs with the oss-fuzz provided docker images. + +###### There are no file/function names in the stack trace. + +`llvm-symbolizer` must be in `PATH`. + +###### UndefinedBehavior Sanitizer (UBSAN) doesn't provide a stack trace. + +Set environment variable `UBSAN_OPTIONS` to `print_stacktrace=1` prior to running the target. diff --git a/fuzzing/driver.c b/fuzzing/driver.c new file mode 100644 index 0000000..296ce57 --- /dev/null +++ b/fuzzing/driver.c @@ -0,0 +1,36 @@ +/* Simpler gnu89 version of StandaloneFuzzTargetMain.c from LLVM */ + +#include +#include +#include + +extern int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size); + +int +main (int argc, char **argv) +{ + FILE *f; + long tell_result; + size_t n_read, len; + unsigned char *buf; + + if (argc < 2) + return 1; + + f = fopen (argv[1], "r"); + assert (f); + fseek (f, 0, SEEK_END); + tell_result = ftell (f); + assert (tell_result >= 0); + len = (size_t) tell_result; + fseek (f, 0, SEEK_SET); + buf = (unsigned char*) malloc (len); + n_read = fread (buf, 1, len, f); + assert (n_read == len); + LLVMFuzzerTestOneInput (buf, len); + + free (buf); + fclose (f); + printf ("Done!\n"); + return 0; +} diff --git a/fuzzing/fuzz.h b/fuzzing/fuzz.h new file mode 100644 index 0000000..4a87998 --- /dev/null +++ b/fuzzing/fuzz.h @@ -0,0 +1,22 @@ +#include "gio/gio.h" +#include "glib/glib.h" + +int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size); + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +static GLogWriterOutput +empty_logging_func (GLogLevelFlags log_level, const GLogField *fields, + gsize n_fields, gpointer user_data) +{ + return G_LOG_WRITER_HANDLED; +} +#endif + +/* Disables logging for oss-fuzz. Must be used with each target. */ +static void +fuzz_set_logging_func (void) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + g_log_set_writer_func (empty_logging_func, NULL, NULL); +#endif +} diff --git a/fuzzing/fuzz_bookmark.c b/fuzzing/fuzz_bookmark.c new file mode 100644 index 0000000..4f257fd --- /dev/null +++ b/fuzzing/fuzz_bookmark.c @@ -0,0 +1,15 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + GBookmarkFile *bookmark = NULL; + + fuzz_set_logging_func (); + + bookmark = g_bookmark_file_new (); + g_bookmark_file_load_from_data (bookmark, (const gchar*) data, size, NULL); + + g_bookmark_file_free (bookmark); + return 0; +} diff --git a/fuzzing/fuzz_bookmark.corpus b/fuzzing/fuzz_bookmark.corpus new file mode 100644 index 0000000..5c78bc9 --- /dev/null +++ b/fuzzing/fuzz_bookmark.corpus @@ -0,0 +1 @@ +glib/tests/**.xbel diff --git a/fuzzing/fuzz_canonicalize_filename.c b/fuzzing/fuzz_canonicalize_filename.c new file mode 100644 index 0000000..86b323e --- /dev/null +++ b/fuzzing/fuzz_canonicalize_filename.c @@ -0,0 +1,19 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + gchar *canonicalized = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (g_canonicalize_filename() doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + canonicalized = g_canonicalize_filename ((const gchar *) nul_terminated_data, "/"); + g_free (nul_terminated_data); + + g_free (canonicalized); + + return 0; +} diff --git a/fuzzing/fuzz_date_parse.c b/fuzzing/fuzz_date_parse.c new file mode 100644 index 0000000..0a7b62e --- /dev/null +++ b/fuzzing/fuzz_date_parse.c @@ -0,0 +1,19 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + GDate *date = g_date_new (); + + fuzz_set_logging_func (); + + /* ignore @size (g_date_set_parse() doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + g_date_set_parse (date, (const gchar *) nul_terminated_data); + g_free (nul_terminated_data); + + g_date_free (date); + + return 0; +} diff --git a/fuzzing/fuzz_date_time_new_from_iso8601.c b/fuzzing/fuzz_date_time_new_from_iso8601.c new file mode 100644 index 0000000..be53a13 --- /dev/null +++ b/fuzzing/fuzz_date_time_new_from_iso8601.c @@ -0,0 +1,25 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + GDateTime *dt = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (the function doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + dt = g_date_time_new_from_iso8601 ((const gchar *) nul_terminated_data, NULL); + g_free (nul_terminated_data); + + if (dt != NULL) + { + gchar *text = g_date_time_format_iso8601 (dt); + g_free (text); + } + + g_clear_pointer (&dt, g_date_time_unref); + + return 0; +} diff --git a/fuzzing/fuzz_dbus_message.c b/fuzzing/fuzz_dbus_message.c new file mode 100644 index 0000000..1030d8d --- /dev/null +++ b/fuzzing/fuzz_dbus_message.c @@ -0,0 +1,28 @@ +#include "fuzz.h" + +static const GDBusCapabilityFlags flags = G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + gssize bytes; + GDBusMessage *msg = NULL; + guchar *blob = NULL; + gsize msg_size; + + fuzz_set_logging_func (); + + bytes = g_dbus_message_bytes_needed ((guchar*) data, size, NULL); + if (bytes <= 0) + return 0; + + msg = g_dbus_message_new_from_blob ((guchar*) data, size, flags, NULL); + if (msg == NULL) + return 0; + + blob = g_dbus_message_to_blob (msg, &msg_size, flags, NULL); + + g_free (blob); + g_object_unref (msg); + return 0; +} diff --git a/fuzzing/fuzz_inet_address_mask_new_from_string.c b/fuzzing/fuzz_inet_address_mask_new_from_string.c new file mode 100644 index 0000000..9ac62ed --- /dev/null +++ b/fuzzing/fuzz_inet_address_mask_new_from_string.c @@ -0,0 +1,25 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + GInetAddressMask *mask = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (the function doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + mask = g_inet_address_mask_new_from_string ((const gchar *) nul_terminated_data, NULL); + g_free (nul_terminated_data); + + if (mask != NULL) + { + gchar *text = g_inet_address_mask_to_string (mask); + g_free (text); + } + + g_clear_object (&mask); + + return 0; +} diff --git a/fuzzing/fuzz_inet_address_new_from_string.c b/fuzzing/fuzz_inet_address_new_from_string.c new file mode 100644 index 0000000..af24592 --- /dev/null +++ b/fuzzing/fuzz_inet_address_new_from_string.c @@ -0,0 +1,25 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + GInetAddress *addr = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (the function doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + addr = g_inet_address_new_from_string ((const gchar *) nul_terminated_data); + g_free (nul_terminated_data); + + if (addr != NULL) + { + gchar *text = g_inet_address_to_string (addr); + g_free (text); + } + + g_clear_object (&addr); + + return 0; +} diff --git a/fuzzing/fuzz_inet_socket_address_new_from_string.c b/fuzzing/fuzz_inet_socket_address_new_from_string.c new file mode 100644 index 0000000..11dd165 --- /dev/null +++ b/fuzzing/fuzz_inet_socket_address_new_from_string.c @@ -0,0 +1,25 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + GSocketAddress *addr = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (the function doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + addr = g_inet_socket_address_new_from_string ((const gchar *) nul_terminated_data, 1); + g_free (nul_terminated_data); + + if (addr != NULL) + { + gchar *text = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr)); + g_free (text); + } + + g_clear_object (&addr); + + return 0; +} diff --git a/fuzzing/fuzz_key.c b/fuzzing/fuzz_key.c new file mode 100644 index 0000000..9f1f918 --- /dev/null +++ b/fuzzing/fuzz_key.c @@ -0,0 +1,27 @@ +#include "fuzz.h" + +static void +test_parse (const gchar *data, + size_t size, + GKeyFileFlags flags) +{ + GKeyFile *key = NULL; + + key = g_key_file_new (); + g_key_file_load_from_data (key, (const gchar*) data, size, G_KEY_FILE_NONE, + NULL); + + g_key_file_free (key); +} + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + fuzz_set_logging_func (); + + test_parse ((const gchar *) data, size, G_KEY_FILE_NONE); + test_parse ((const gchar *) data, size, G_KEY_FILE_KEEP_COMMENTS); + test_parse ((const gchar *) data, size, G_KEY_FILE_KEEP_TRANSLATIONS); + + return 0; +} diff --git a/fuzzing/fuzz_key.corpus b/fuzzing/fuzz_key.corpus new file mode 100644 index 0000000..5a1cb41 --- /dev/null +++ b/fuzzing/fuzz_key.corpus @@ -0,0 +1,2 @@ +glib/tests/**.ini +gio/tests/**.desktop diff --git a/fuzzing/fuzz_network_address_parse.c b/fuzzing/fuzz_network_address_parse.c new file mode 100644 index 0000000..bda05c2 --- /dev/null +++ b/fuzzing/fuzz_network_address_parse.c @@ -0,0 +1,25 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + GSocketConnectable *connectable = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (g_network_address_parse() doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + connectable = g_network_address_parse ((const gchar *) nul_terminated_data, 1, NULL); + g_free (nul_terminated_data); + + if (connectable != NULL) + { + gchar *text = g_socket_connectable_to_string (connectable); + g_free (text); + } + + g_clear_object (&connectable); + + return 0; +} diff --git a/fuzzing/fuzz_network_address_parse_uri.c b/fuzzing/fuzz_network_address_parse_uri.c new file mode 100644 index 0000000..ea51133 --- /dev/null +++ b/fuzzing/fuzz_network_address_parse_uri.c @@ -0,0 +1,25 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + GSocketConnectable *connectable = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (g_network_address_parse_uri() doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + connectable = g_network_address_parse_uri ((const gchar *) nul_terminated_data, 1, NULL); + g_free (nul_terminated_data); + + if (connectable != NULL) + { + gchar *text = g_socket_connectable_to_string (connectable); + g_free (text); + } + + g_clear_object (&connectable); + + return 0; +} diff --git a/fuzzing/fuzz_paths.c b/fuzzing/fuzz_paths.c new file mode 100644 index 0000000..9481594 --- /dev/null +++ b/fuzzing/fuzz_paths.c @@ -0,0 +1,32 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + const gchar *skipped_root G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + gchar *basename = NULL, *dirname = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (none of the functions support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + + g_path_is_absolute ((const gchar *) nul_terminated_data); + + skipped_root = g_path_skip_root ((const gchar *) nul_terminated_data); + g_assert (skipped_root == NULL || skipped_root >= (const gchar *) nul_terminated_data); + g_assert (skipped_root == NULL || skipped_root <= (const gchar *) nul_terminated_data + size); + + basename = g_path_get_basename ((const gchar *) nul_terminated_data); + g_assert (strcmp (basename, ".") == 0 || strlen (basename) <= size); + + dirname = g_path_get_dirname ((const gchar *) nul_terminated_data); + g_assert (strcmp (dirname, ".") == 0 || strlen (dirname) <= size); + + g_free (nul_terminated_data); + g_free (dirname); + g_free (basename); + + return 0; +} diff --git a/fuzzing/fuzz_resolver.c b/fuzzing/fuzz_resolver.c new file mode 100644 index 0000000..d4ba4b8 --- /dev/null +++ b/fuzzing/fuzz_resolver.c @@ -0,0 +1,53 @@ +#include "fuzz.h" +#include "gio/gnetworking.h" + +#include "../gio/gthreadedresolver.h" + +static void +test_for_rrtype (const guint8 *data, + gsize data_len, + gint rrtype) +{ + /* g_resolver_records_from_res_query() is only available on Unix */ +#ifdef G_OS_UNIX + GList *record_list = NULL; + + /* Data too long? */ + if (data_len > G_MAXSSIZE) + return; + + /* rrname is only used in error messages, so doesn’t need to vary. + * herr is used similarly, so is just set to zero. */ + record_list = g_resolver_records_from_res_query ("rrname", + rrtype, + data, + data_len, + 0, + NULL); + + g_list_free_full (record_list, (GDestroyNotify) g_variant_unref); +#endif /* G_OS_UNIX */ +} + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + const gint rrtypes_to_test[] = + { + /* See https://en.wikipedia.org/wiki/List_of_DNS_record_types */ + 33 /* SRV */, + 15 /* MX */, + 6 /* SOA */, + 2 /* NS */, + 16 /* TXT */, + 999, /* not currently a valid rrtype, to test the ‘unknown’ code path */ + }; + gsize i; + + fuzz_set_logging_func (); + + for (i = 0; i < G_N_ELEMENTS (rrtypes_to_test); i++) + test_for_rrtype (data, size, rrtypes_to_test[i]); + + return 0; +} diff --git a/fuzzing/fuzz_uri_escape.c b/fuzzing/fuzz_uri_escape.c new file mode 100644 index 0000000..6a3d197 --- /dev/null +++ b/fuzzing/fuzz_uri_escape.c @@ -0,0 +1,65 @@ +#include "fuzz.h" + +static void +test_bytes (const guint8 *data, + gsize size) +{ + GError *error = NULL; + GBytes *unescaped_bytes = NULL; + gchar *escaped_string = NULL; + + if (size > G_MAXSSIZE) + return; + + unescaped_bytes = g_uri_unescape_bytes ((const gchar *) data, (gssize) size, NULL, &error); + if (unescaped_bytes == NULL) + { + g_assert_nonnull (error); + g_clear_error (&error); + return; + } + + escaped_string = g_uri_escape_bytes (g_bytes_get_data (unescaped_bytes, NULL), + g_bytes_get_size (unescaped_bytes), + NULL); + g_bytes_unref (unescaped_bytes); + + if (escaped_string == NULL) + return; + + g_free (escaped_string); +} + +static void +test_string (const guint8 *data, + gsize size) +{ + gchar *unescaped_string = NULL; + gchar *escaped_string = NULL; + + unescaped_string = g_uri_unescape_segment ((const gchar *) data, (const gchar *) data + size, NULL); + if (unescaped_string == NULL) + return; + + escaped_string = g_uri_escape_string (unescaped_string, NULL, TRUE); + g_free (unescaped_string); + + if (escaped_string == NULL) + return; + + g_free (escaped_string); +} + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + fuzz_set_logging_func (); + + /* Bytes form */ + test_bytes (data, size); + + /* String form (doesn’t do %-decoding) */ + test_string (data, size); + + return 0; +} diff --git a/fuzzing/fuzz_uri_parse.c b/fuzzing/fuzz_uri_parse.c new file mode 100644 index 0000000..03c581e --- /dev/null +++ b/fuzzing/fuzz_uri_parse.c @@ -0,0 +1,44 @@ +#include "fuzz.h" + +static void +test_with_flags (const gchar *data, + GUriFlags flags) +{ + GUri *uri = NULL; + gchar *uri_string = NULL; + + uri = g_uri_parse (data, flags, NULL); + + if (uri == NULL) + return; + + uri_string = g_uri_to_string (uri); + g_uri_unref (uri); + + if (uri_string == NULL) + return; + + g_free (uri_string); +} + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + unsigned char *nul_terminated_data = NULL; + + fuzz_set_logging_func (); + + /* ignore @size (g_uri_parse() doesn’t support it); ensure @data is nul-terminated */ + nul_terminated_data = (unsigned char *) g_strndup ((const gchar *) data, size); + test_with_flags ((const gchar *) nul_terminated_data, G_URI_FLAGS_NONE); + test_with_flags ((const gchar *) nul_terminated_data, G_URI_FLAGS_PARSE_RELAXED); + test_with_flags ((const gchar *) nul_terminated_data, G_URI_FLAGS_NON_DNS); + test_with_flags ((const gchar *) nul_terminated_data, G_URI_FLAGS_HAS_AUTH_PARAMS); + test_with_flags ((const gchar *) nul_terminated_data, G_URI_FLAGS_HAS_PASSWORD); + test_with_flags ((const gchar *) nul_terminated_data, G_URI_FLAGS_ENCODED_QUERY); + test_with_flags ((const gchar *) nul_terminated_data, G_URI_FLAGS_ENCODED_PATH); + test_with_flags ((const gchar *) nul_terminated_data, G_URI_FLAGS_SCHEME_NORMALIZE); + g_free (nul_terminated_data); + + return 0; +} diff --git a/fuzzing/fuzz_uri_parse_params.c b/fuzzing/fuzz_uri_parse_params.c new file mode 100644 index 0000000..ddae570 --- /dev/null +++ b/fuzzing/fuzz_uri_parse_params.c @@ -0,0 +1,28 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + GError *error = NULL; + GHashTable *parsed_params = NULL; + + fuzz_set_logging_func (); + + if (size > G_MAXSSIZE) + return 0; + + parsed_params = g_uri_parse_params ((const gchar *) data, (gssize) size, + "&", G_URI_PARAMS_NONE, &error); + if (parsed_params == NULL) + { + g_assert (error); + g_clear_error (&error); + return 0; + } + + + g_assert_no_error (error); + g_hash_table_unref (parsed_params); + + return 0; +} diff --git a/fuzzing/fuzz_variant_binary.c b/fuzzing/fuzz_variant_binary.c new file mode 100644 index 0000000..995718c --- /dev/null +++ b/fuzzing/fuzz_variant_binary.c @@ -0,0 +1,21 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + GVariant *variant = NULL, *normal_variant = NULL; + + fuzz_set_logging_func (); + + variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, FALSE, + NULL, NULL); + if (variant == NULL) + return 0; + + normal_variant = g_variant_take_ref (g_variant_get_normal_form (variant)); + g_variant_get_data (variant); + + g_variant_unref (normal_variant); + g_variant_unref (variant); + return 0; +} diff --git a/fuzzing/fuzz_variant_text.c b/fuzzing/fuzz_variant_text.c new file mode 100644 index 0000000..a797909 --- /dev/null +++ b/fuzzing/fuzz_variant_text.c @@ -0,0 +1,21 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + const gchar *gdata = (const gchar*) data; + GVariant *variant = NULL; + gchar *text = NULL; + + fuzz_set_logging_func (); + + variant = g_variant_parse (NULL, gdata, gdata + size, NULL, NULL); + if (variant == NULL) + return 0; + + text = g_variant_print (variant, TRUE); + + g_free (text); + g_variant_unref (variant); + return 0; +} diff --git a/fuzzing/fuzz_variant_text.dict b/fuzzing/fuzz_variant_text.dict new file mode 100644 index 0000000..a0e5284 --- /dev/null +++ b/fuzzing/fuzz_variant_text.dict @@ -0,0 +1,32 @@ +"'" +"\"" +"(" +")" +"<" +">" +"[" +"]" +"{" +"}" +"*" +"?" +"@" +"b'" +"b\"" +"boolean" +"byte" +"double" +"false" +"handle" +"int16" +"int32" +"int64" +"just" +"nothing" +"objectpath" +"signature" +"string" +"true" +"uint16" +"uint32" +"uint64" diff --git a/fuzzing/meson.build b/fuzzing/meson.build new file mode 100644 index 0000000..49cfc37 --- /dev/null +++ b/fuzzing/meson.build @@ -0,0 +1,45 @@ +fuzz_targets = [ + 'fuzz_bookmark', + 'fuzz_canonicalize_filename', + 'fuzz_date_parse', + 'fuzz_date_time_new_from_iso8601', + 'fuzz_dbus_message', + 'fuzz_inet_address_mask_new_from_string', + 'fuzz_inet_address_new_from_string', + 'fuzz_inet_socket_address_new_from_string', + 'fuzz_key', + 'fuzz_network_address_parse', + 'fuzz_network_address_parse_uri', + 'fuzz_paths', + 'fuzz_resolver', + 'fuzz_uri_escape', + 'fuzz_uri_parse', + 'fuzz_uri_parse_params', + 'fuzz_variant_binary', + 'fuzz_variant_text', +] + +deps = [libgmodule_dep, libgio_dep, libglib_dep, libgobject_dep] + +extra_sources = [] +extra_c_args = cc.get_supported_arguments('-Werror=unused-function') + +# Links in a static library provided by oss-fuzz, else a standalone driver. +# https://google.github.io/oss-fuzz/getting-started/new-project-guide/#buildsh-script-environment +have_fuzzing_engine = false +if have_cxx + fuzzing_engine = cxx.find_library('FuzzingEngine', required : get_option('oss_fuzz')) + have_fuzzing_engine = fuzzing_engine.found() +endif +if have_fuzzing_engine + deps += fuzzing_engine +else + extra_sources += 'driver.c' +endif + +foreach target_name : fuzz_targets + exe = executable(target_name, [extra_sources, target_name + '.c'], + c_args : extra_c_args, + dependencies : deps, + ) +endforeach diff --git a/gio/completion/.gitignore b/gio/completion/.gitignore new file mode 100644 index 0000000..6930af9 --- /dev/null +++ b/gio/completion/.gitignore @@ -0,0 +1 @@ +!gio diff --git a/gio/completion/gapplication b/gio/completion/gapplication new file mode 100644 index 0000000..565025b --- /dev/null +++ b/gio/completion/gapplication @@ -0,0 +1,55 @@ + +# Check for bash +[ -z "$BASH_VERSION" ] && return + +#################################################################################################### + +__app() { + case "${COMP_CWORD}" in + 1) + COMPREPLY=($(compgen -W "help version list-apps launch action list-actions" -- "${COMP_WORDS[1]}")) + return 0 + ;; + + 2) + case "${COMP_WORDS[1]}" in + launch|action|list-actions) + COMPREPLY=($(compgen -W "`gapplication list-apps`" -- "${COMP_WORDS[2]}")) + return 0 + ;; + + *) + COMPREPLY=() + return 0 + ;; + esac + ;; + esac + + # Otherwise, what we will do is based on the command in ${COMP_WORDS[1]} + case "${COMP_WORDS[1]}" in + action) + # Word 3 is the action name. This is the only one we can help with. + if [ "${COMP_CWORD}" == 3 ]; then + COMPREPLY=($(compgen -W "`gapplication list-actions "${COMP_WORDS[2]}"`" -- "${COMP_WORDS[3]}")) + return 0 + else + COMPREPLY=() + return 0 + fi + ;; + launch) + # Filenames... + COMPREPLY=($(compgen -A file "${COMP_WORDS[COMP_CWORD]}")) + return 0 + ;; + *) + # Nothing else should be out this far... + COMPREPLY=() + return 0 + esac +} + +#################################################################################################### + +complete -F __app gapplication diff --git a/gio/completion/gdbus b/gio/completion/gdbus new file mode 100644 index 0000000..79f4cb4 --- /dev/null +++ b/gio/completion/gdbus @@ -0,0 +1,33 @@ + +# Check for bash +[ -z "$BASH_VERSION" ] && return + +#################################################################################################### + + +__gdbus() { + local IFS=$'\n' + local cur=`_get_cword :` + + local suggestions=$(gdbus complete "${COMP_LINE}" ${COMP_POINT}) + COMPREPLY=($(compgen -W "$suggestions" -- "$cur")) + + # Remove colon-word prefix from COMPREPLY items + case "$cur" in + *:*) + case "$COMP_WORDBREAKS" in + *:*) + local colon_word=${cur%${cur##*:}} + local i=${#COMPREPLY[*]} + while [ $((--i)) -ge 0 ]; do + COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"} + done + ;; + esac + ;; + esac +} + +#################################################################################################### + +complete -o nospace -F __gdbus gdbus diff --git a/gio/completion/gio b/gio/completion/gio new file mode 100644 index 0000000..c650475 --- /dev/null +++ b/gio/completion/gio @@ -0,0 +1,122 @@ +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# licence, or (at your option) any later version. +# +# This is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, see . +# + +# Check for bash +[ -z "$BASH_VERSION" ] && return + +#################################################################################################### + +# Check whether the suggestions have common prefix (i.e. suggestions won't be +# shown and prefix will be completed first) +__gio_has_common_prefix() { + local i + for (( i = 1; i < ${#COMPREPLY[@]}; i++ )); do + if [[ "${COMPREPLY[i-1]:${#cur}:1}" != "${COMPREPLY[i]:${#cur}:1}" ]]; then + return 1 # False + fi + done + + return 0 # True +} + +# Complete file location +__gio_location() { + # Prevent breaking on colons, we have to work with uris + local cur + _get_comp_words_by_ref -n : cur + + # Resolve dirname for dir listing + local dir="" + if [[ $cur =~ "/"$ ]]; then + dir="$cur" + elif [[ $cur =~ "/" ]]; then + # Subtract basename because dirname cmd doesn't work well with schemes + dir=${cur%$(basename "$cur")} + fi + + # List volumes and mounts + local mounts=( ) + local mount + while IFS=$'\n' read mount; do + # Do not care about local mounts + [[ "$mount" =~ ^"file:" ]] && continue + + # Use only matching mounts + [[ "$mount" =~ ^"$cur" && "$mount" != "$cur" ]] && mounts+=("$mount") + done < <(gio mount -li | sed -n -r 's/^ *(default_location|activation_root)=(.*)$/\2/p' | sort -u) + + # Workaround to unescape dir name (e.g. "\ " -> " ") + local -a tmp="( ${dir} )" + local unescaped_dir="${tmp[0]}" + + # List files + local files=() + local names=() + local name size type + while IFS=$'\t' read name size type; do + # Escape name properly + local escaped_name="$(printf "%q" "$name")" + + # Append slash for directories and space for files + if [[ "$type" == "(directory)" ]]; then + escaped_name="$escaped_name/" + else + escaped_name="$escaped_name " + fi + + local path="$dir$escaped_name" + + # Use only matching paths + if [[ "$path" =~ ^"$cur" ]]; then + files+=("$path") + names+=("$escaped_name") + fi + done < <(gio list -hl "$unescaped_dir" 2> /dev/null) + + COMPREPLY=("${files[@]}" "${mounts[@]}") + + # Workaround to show suggestions as basenames only + if ! __gio_has_common_prefix; then + COMPREPLY=("${mounts[@]} ${names[@]}") + + # Workaround to prevent overwriting suggestions, it adds empty + # suggestion, otherwise names with colons will be corrupted + COMPREPLY+=(" ") + + return 0 + fi + + # Workaround to complete names with colons, it removes colon prefix from + # COMPREPLY + __ltrim_colon_completions "$cur" +} + +__gio() { + # Complete subcommands + if (( ${COMP_CWORD} == 1 )); then + COMPREPLY=($(compgen -W "help version cat copy info launch list mime mkdir monitor mount move open rename remove save set trash tree" -- "${COMP_WORDS[1]}")) + compopt +o nospace + return 0 + fi + + # Complete file locations + __gio_location +} + +#################################################################################################### + +complete -o nospace -F __gio gio diff --git a/gio/completion/gresource b/gio/completion/gresource new file mode 100644 index 0000000..ef1145d --- /dev/null +++ b/gio/completion/gresource @@ -0,0 +1,58 @@ + +# Check for bash +[ -z "$BASH_VERSION" ] && return + +#################################################################################################### + +__gresource() { + local choices coffset section + + if [ ${COMP_CWORD} -gt 2 ]; then + if [ ${COMP_WORDS[1]} = --section ]; then + section=${COMP_WORDS[2]} + coffset=2 + else + coffset=0 + fi + else + coffset=0 + fi + + case "$((${COMP_CWORD}-$coffset))" in + 1) + choices=$'--section \nhelp \nsections \nlist \ndetails \nextract ' + ;; + + 2) + case "${COMP_WORDS[$(($coffset+1))]}" in + --section) + return 0 + ;; + + help) + choices=$'sections\nlist\ndetails\nextract' + ;; + + sections|list|details|extract) + COMPREPLY=($(compgen -f -- ${COMP_WORDS[${COMP_CWORD}]})) + return 0 + ;; + esac + ;; + + 3) + case "${COMP_WORDS[$(($coffset+1))]}" in + list|details|extract) + choices="$(gresource list ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null | sed -e 's.$. .')" + ;; + esac + ;; + esac + + local IFS=$'\n' + COMPREPLY=($(compgen -W "${choices}" -- "${COMP_WORDS[${COMP_CWORD}]}")) +} + +#################################################################################################### + +complete -o nospace -F __gresource gresource diff --git a/gio/completion/gsettings b/gio/completion/gsettings new file mode 100644 index 0000000..d509758 --- /dev/null +++ b/gio/completion/gsettings @@ -0,0 +1,88 @@ + +# Check for bash +[ -z "$BASH_VERSION" ] && return + +#################################################################################################### + +__gsettings() { + local choices coffset schemadir + + if [ ${COMP_CWORD} -gt 2 ]; then + if [ ${COMP_WORDS[1]} = --schemadir ]; then + # this complexity is needed to perform correct tilde expansion + schemadir=$(eval "echo --schemadir ${COMP_WORDS[2]}") + coffset=2 + else + coffset=0 + fi + else + coffset=0 + fi + + case "$((${COMP_CWORD}-$coffset))" in + 1) + choices=$'--schemadir\n--version\nhelp \nlist-schemas\nlist-relocatable-schemas\nlist-keys \nlist-children \nlist-recursively \nget \nrange \nset \nreset \nreset-recursively \nwritable \nmonitor \ndescribe ' + ;; + + 2) + case "${COMP_WORDS[$(($coffset+1))]}" in + --schemadir) + COMPREPLY=($(compgen -o dirnames -- ${COMP_WORDS[${COMP_CWORD}]})) + return 0 + ;; + + help) + choices=$'list-schemas\nlist-relocatable-schemas\nlist-keys\nlist-children\nlist-recursively\nget\nrange\nset\nreset\nreset-recursively\nwritable\nmonitor' + ;; + list-keys|list-children|list-recursively|reset-recursively) + choices="$(gsettings $schemadir list-schemas 2> /dev/null)"$'\n'"$(gsettings $schemadir list-relocatable-schemas 2> /dev/null | sed -e 's.$.:/.')" + ;; + list-schemas) + COMPREPLY=($(compgen -W "--print-paths" -- ${COMP_WORDS[${COMP_CWORD}]})) + return 0 + ;; + + get|range|set|reset|writable|monitor|describe) + choices="$(gsettings $schemadir list-schemas 2> /dev/null | sed -e 's.$. .')"$'\n'"$(gsettings $schemadir list-relocatable-schemas 2> /dev/null | sed -e 's.$.:/.')" + ;; + esac + ;; + + 3) + case "${COMP_WORDS[$(($coffset+1))]}" in + set) + choices="$(gsettings $schemadir list-keys ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null | sed -e 's.$. .')" + ;; + + get|range|reset|writable|monitor|describe) + choices="$(gsettings $schemadir list-keys ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null)" + ;; + esac + ;; + + 4) + case "${COMP_WORDS[$(($coffset+2))]}" in + set) + range=($(gsettings $schemadir range ${COMP_WORDS[$(($coffset+2))]} ${COMP_WORDS[$(($coffset+3))]} 2> /dev/null)) + case "${range[0]}" in + enum) + unset range[0] + ;; + *) + unset range + ;; + esac + local IFS=$'\n' + choices="${range[*]}" + ;; + esac + ;; + esac + + local IFS=$'\n' + COMPREPLY=($(compgen -W "${choices}" -- "${COMP_WORDS[${COMP_CWORD}]}")) +} + +#################################################################################################### + +complete -o nospace -F __gsettings gsettings diff --git a/gio/data-to-c.py b/gio/data-to-c.py new file mode 100755 index 0000000..8407fb4 --- /dev/null +++ b/gio/data-to-c.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import sys + +if len(sys.argv) < 4: + print("Usage: {0} ") + +with open(sys.argv[1], "r", encoding="utf-8", errors="backslashreplace") as f: + in_data = f.read() + +b = [r"\x{:02x}".format(ord(c)) for c in in_data] + +out_data = 'const char {0}[] = "'.format(sys.argv[2]) +out_data += "".join(b) + '";\n' + +with open(sys.argv[3], "w") as f: + f.write(out_data) diff --git a/gio/dbus-daemon.xml b/gio/dbus-daemon.xml new file mode 100644 index 0000000..515dd34 --- /dev/null +++ b/gio/dbus-daemon.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gio/fam/gfamfilemonitor.c b/gio/fam/gfamfilemonitor.c new file mode 100644 index 0000000..d9518a6 --- /dev/null +++ b/gio/fam/gfamfilemonitor.c @@ -0,0 +1,235 @@ +/* + * Copyright © 2015 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include +#include +#include "glib-private.h" +#include +#include + +static GMutex fam_lock; +static gboolean fam_initialised; +static FAMConnection fam_connection; +static GSource *fam_source; + +#define G_TYPE_FAM_FILE_MONITOR (g_fam_file_monitor_get_type ()) +#define G_FAM_FILE_MONITOR(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_FAM_FILE_MONITOR, GFamFileMonitor)) + +typedef GLocalFileMonitorClass GFamFileMonitorClass; + +typedef struct +{ + GLocalFileMonitor parent_instance; + + FAMRequest request; +} GFamFileMonitor; + +static GType g_fam_file_monitor_get_type (void); +G_DEFINE_DYNAMIC_TYPE (GFamFileMonitor, g_fam_file_monitor, G_TYPE_LOCAL_FILE_MONITOR) + +static gboolean +g_fam_file_monitor_callback (gint fd, + GIOCondition condition, + gpointer user_data) +{ + gint64 now = g_source_get_time (fam_source); + + g_mutex_lock (&fam_lock); + + while (FAMPending (&fam_connection)) + { + const gchar *child; + FAMEvent ev; + + if (FAMNextEvent (&fam_connection, &ev) != 1) + { + /* The daemon died. We're in a really bad situation now + * because we potentially have a bunch of request structures + * outstanding which no longer make any sense to anyone. + * + * The best thing that we can do is do nothing. Notification + * won't work anymore for this process. + */ + g_mutex_unlock (&fam_lock); + + g_warning ("Lost connection to FAM (file monitoring) service. Expect no further file monitor events."); + + return FALSE; + } + + /* We expect ev.filename to be a relative path for children in a + * monitored directory, and an absolute path for a monitored file + * or the directory itself. + */ + if (ev.filename[0] != '/') + child = ev.filename; + else + child = NULL; + + switch (ev.code) + { + case FAMAcknowledge: + g_source_unref (ev.userdata); + break; + + case FAMChanged: + g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CHANGED, child, NULL, NULL, now); + break; + + case FAMDeleted: + g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_DELETED, child, NULL, NULL, now); + break; + + case FAMCreated: + g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CREATED, child, NULL, NULL, now); + break; + + default: + /* unknown type */ + break; + } + } + + g_mutex_unlock (&fam_lock); + + return TRUE; +} + +static gboolean +g_fam_file_monitor_is_supported (void) +{ + g_mutex_lock (&fam_lock); + + if (!fam_initialised) + { + fam_initialised = FAMOpen2 (&fam_connection, "GLib GIO") == 0; + + if (fam_initialised) + { +#ifdef HAVE_FAM_NO_EXISTS + /* This is a gamin extension that avoids sending all the + * Exists event for dir monitors + */ + FAMNoExists (&fam_connection); +#endif + + fam_source = g_unix_fd_source_new (FAMCONNECTION_GETFD (&fam_connection), G_IO_IN); + g_source_set_callback (fam_source, (GSourceFunc) g_fam_file_monitor_callback, NULL, NULL); + g_source_attach (fam_source, GLIB_PRIVATE_CALL(g_get_worker_context) ()); + } + } + + g_mutex_unlock (&fam_lock); + + return fam_initialised; +} + +static gboolean +g_fam_file_monitor_cancel (GFileMonitor *monitor) +{ + GFamFileMonitor *gffm = G_FAM_FILE_MONITOR (monitor); + + g_mutex_lock (&fam_lock); + + g_assert (fam_initialised); + + FAMCancelMonitor (&fam_connection, &gffm->request); + + g_mutex_unlock (&fam_lock); + + return TRUE; +} + +static void +g_fam_file_monitor_start (GLocalFileMonitor *local_monitor, + const gchar *dirname, + const gchar *basename, + const gchar *filename, + GFileMonitorSource *source) +{ + GFamFileMonitor *gffm = G_FAM_FILE_MONITOR (local_monitor); + + g_mutex_lock (&fam_lock); + + g_assert (fam_initialised); + + g_source_ref ((GSource *) source); + + if (dirname) + FAMMonitorDirectory (&fam_connection, dirname, &gffm->request, source); + else + FAMMonitorFile (&fam_connection, filename, &gffm->request, source); + + g_mutex_unlock (&fam_lock); +} + +static void +g_fam_file_monitor_init (GFamFileMonitor* monitor) +{ +} + +static void +g_fam_file_monitor_class_init (GFamFileMonitorClass *class) +{ + GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (class); + + class->is_supported = g_fam_file_monitor_is_supported; + class->start = g_fam_file_monitor_start; + file_monitor_class->cancel = g_fam_file_monitor_cancel; +} + +static void +g_fam_file_monitor_class_finalize (GFamFileMonitorClass *class) +{ +} + +void +g_io_module_load (GIOModule *module) +{ + g_type_module_use (G_TYPE_MODULE (module)); + + g_fam_file_monitor_register_type (G_TYPE_MODULE (module)); + + g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + G_TYPE_FAM_FILE_MONITOR, "fam", 10); + + g_io_extension_point_implement (G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME, + G_TYPE_FAM_FILE_MONITOR, "fam", 10); +} + +void +g_io_module_unload (GIOModule *module) +{ + g_assert_not_reached (); +} + +char ** +g_io_module_query (void) +{ + char *eps[] = { + G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME, + NULL + }; + + return g_strdupv (eps); +} diff --git a/gio/fam/gfamfilemonitor.map b/gio/fam/gfamfilemonitor.map new file mode 100644 index 0000000..43ed5a7 --- /dev/null +++ b/gio/fam/gfamfilemonitor.map @@ -0,0 +1,8 @@ +{ +global: + g_io_module_load; + g_io_module_unload; + g_io_module_query; +local: + *; +}; diff --git a/gio/fam/meson.build b/gio/fam/meson.build new file mode 100644 index 0000000..e3f5703 --- /dev/null +++ b/gio/fam/meson.build @@ -0,0 +1,42 @@ +if not get_option('fam') + subdir_done() +endif + +fam_dep = cc.find_library('fam') +fam_c_args = gio_c_args +if cc.has_function('FAMNoExists', dependencies : fam_dep) + fam_c_args += '-DHAVE_FAM_NO_EXISTS=1' +endif + +deps = [ + fam_dep, + libglib_dep, + libgobject_dep, + libgio_dep, +] + +symbol_map = join_paths(meson.current_source_dir(), 'gfamfilemonitor.map') +fam_ldflags = cc.get_supported_link_arguments([ + '-Wl,--version-script,' + symbol_map, + '-Wl,-no-undefined', +]) + +module = shared_module('giofam', 'gfamfilemonitor.c', + include_directories : [gmoduleinc], + dependencies : deps, + c_args : fam_c_args, + link_args : fam_ldflags, + link_depends : symbol_map, + install_dir : glib_giomodulesdir, + install : true, +) + +if not meson.is_cross_build() + meson.add_install_script('../gio-querymodules-wrapper.py', gio_querymodules.full_path(), glib_giomodulesdir) +endif + +if meson.version().version_compare('>=0.58') + env = environment() + env.prepend('GIO_EXTRA_MODULES', meson.current_build_dir()) + meson.add_devenv(env) +endif \ No newline at end of file diff --git a/gio/gaction.c b/gio/gaction.c new file mode 100644 index 0000000..645eb26 --- /dev/null +++ b/gio/gaction.c @@ -0,0 +1,587 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" +#include "gaction.h" +#include "glibintl.h" + +#include + +G_DEFINE_INTERFACE (GAction, g_action, G_TYPE_OBJECT) + +/** + * SECTION:gaction + * @title: GAction + * @short_description: An action interface + * @include: gio/gio.h + * + * #GAction represents a single named action. + * + * The main interface to an action is that it can be activated with + * g_action_activate(). This results in the 'activate' signal being + * emitted. An activation has a #GVariant parameter (which may be + * %NULL). The correct type for the parameter is determined by a static + * parameter type (which is given at construction time). + * + * An action may optionally have a state, in which case the state may be + * set with g_action_change_state(). This call takes a #GVariant. The + * correct type for the state is determined by a static state type + * (which is given at construction time). + * + * The state may have a hint associated with it, specifying its valid + * range. + * + * #GAction is merely the interface to the concept of an action, as + * described above. Various implementations of actions exist, including + * #GSimpleAction. + * + * In all cases, the implementing class is responsible for storing the + * name of the action, the parameter type, the enabled state, the + * optional state type and the state and emitting the appropriate + * signals when these change. The implementor is responsible for filtering + * calls to g_action_activate() and g_action_change_state() for type + * safety and for the state being enabled. + * + * Probably the only useful thing to do with a #GAction is to put it + * inside of a #GSimpleActionGroup. + **/ + +/** + * GAction: + * + * #GAction is an opaque data structure and can only be accessed + * using the following functions. + **/ + +/** + * GActionInterface: + * @get_name: the virtual function pointer for g_action_get_name() + * @get_parameter_type: the virtual function pointer for g_action_get_parameter_type() + * @get_state_type: the virtual function pointer for g_action_get_state_type() + * @get_state_hint: the virtual function pointer for g_action_get_state_hint() + * @get_enabled: the virtual function pointer for g_action_get_enabled() + * @get_state: the virtual function pointer for g_action_get_state() + * @change_state: the virtual function pointer for g_action_change_state() + * @activate: the virtual function pointer for g_action_activate(). Note that #GAction does not have an + * 'activate' signal but that implementations of it may have one. + * + * The virtual function table for #GAction. + * + * Since: 2.28 + */ + +void +g_action_default_init (GActionInterface *iface) +{ + /** + * GAction:name: + * + * The name of the action. This is mostly meaningful for identifying + * the action once it has been added to a #GActionGroup. It is immutable. + * + * Since: 2.28 + **/ + g_object_interface_install_property (iface, + g_param_spec_string ("name", + P_("Action Name"), + P_("The name used to invoke the action"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GAction:parameter-type: + * + * The type of the parameter that must be given when activating the + * action. This is immutable, and may be %NULL if no parameter is needed when + * activating the action. + * + * Since: 2.28 + **/ + g_object_interface_install_property (iface, + g_param_spec_boxed ("parameter-type", + P_("Parameter Type"), + P_("The type of GVariant passed to activate()"), + G_TYPE_VARIANT_TYPE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GAction:enabled: + * + * If @action is currently enabled. + * + * If the action is disabled then calls to g_action_activate() and + * g_action_change_state() have no effect. + * + * Since: 2.28 + **/ + g_object_interface_install_property (iface, + g_param_spec_boolean ("enabled", + P_("Enabled"), + P_("If the action can be activated"), + TRUE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GAction:state-type: + * + * The #GVariantType of the state that the action has, or %NULL if the + * action is stateless. This is immutable. + * + * Since: 2.28 + **/ + g_object_interface_install_property (iface, + g_param_spec_boxed ("state-type", + P_("State Type"), + P_("The type of the state kept by the action"), + G_TYPE_VARIANT_TYPE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GAction:state: + * + * The state of the action, or %NULL if the action is stateless. + * + * Since: 2.28 + **/ + g_object_interface_install_property (iface, + g_param_spec_variant ("state", + P_("State"), + P_("The state the action is in"), + G_VARIANT_TYPE_ANY, + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_action_change_state: + * @action: a #GAction + * @value: the new state + * + * Request for the state of @action to be changed to @value. + * + * The action must be stateful and @value must be of the correct type. + * See g_action_get_state_type(). + * + * This call merely requests a change. The action may refuse to change + * its state or may change its state to something other than @value. + * See g_action_get_state_hint(). + * + * If the @value GVariant is floating, it is consumed. + * + * Since: 2.30 + **/ +void +g_action_change_state (GAction *action, + GVariant *value) +{ + const GVariantType *state_type; + + g_return_if_fail (G_IS_ACTION (action)); + g_return_if_fail (value != NULL); + state_type = g_action_get_state_type (action); + g_return_if_fail (state_type != NULL); + g_return_if_fail (g_variant_is_of_type (value, state_type)); + + g_variant_ref_sink (value); + + G_ACTION_GET_IFACE (action) + ->change_state (action, value); + + g_variant_unref (value); +} + +/** + * g_action_get_state: + * @action: a #GAction + * + * Queries the current state of @action. + * + * If the action is not stateful then %NULL will be returned. If the + * action is stateful then the type of the return value is the type + * given by g_action_get_state_type(). + * + * The return value (if non-%NULL) should be freed with + * g_variant_unref() when it is no longer required. + * + * Returns: (nullable) (transfer full): the current state of the action + * + * Since: 2.28 + **/ +GVariant * +g_action_get_state (GAction *action) +{ + g_return_val_if_fail (G_IS_ACTION (action), NULL); + + return G_ACTION_GET_IFACE (action) + ->get_state (action); +} + +/** + * g_action_get_name: + * @action: a #GAction + * + * Queries the name of @action. + * + * Returns: the name of the action + * + * Since: 2.28 + **/ +const gchar * +g_action_get_name (GAction *action) +{ + g_return_val_if_fail (G_IS_ACTION (action), NULL); + + return G_ACTION_GET_IFACE (action) + ->get_name (action); +} + +/** + * g_action_get_parameter_type: + * @action: a #GAction + * + * Queries the type of the parameter that must be given when activating + * @action. + * + * When activating the action using g_action_activate(), the #GVariant + * given to that function must be of the type returned by this function. + * + * In the case that this function returns %NULL, you must not give any + * #GVariant, but %NULL instead. + * + * Returns: (nullable): the parameter type + * + * Since: 2.28 + **/ +const GVariantType * +g_action_get_parameter_type (GAction *action) +{ + g_return_val_if_fail (G_IS_ACTION (action), NULL); + + return G_ACTION_GET_IFACE (action) + ->get_parameter_type (action); +} + +/** + * g_action_get_state_type: + * @action: a #GAction + * + * Queries the type of the state of @action. + * + * If the action is stateful (e.g. created with + * g_simple_action_new_stateful()) then this function returns the + * #GVariantType of the state. This is the type of the initial value + * given as the state. All calls to g_action_change_state() must give a + * #GVariant of this type and g_action_get_state() will return a + * #GVariant of the same type. + * + * If the action is not stateful (e.g. created with g_simple_action_new()) + * then this function will return %NULL. In that case, g_action_get_state() + * will return %NULL and you must not call g_action_change_state(). + * + * Returns: (nullable): the state type, if the action is stateful + * + * Since: 2.28 + **/ +const GVariantType * +g_action_get_state_type (GAction *action) +{ + g_return_val_if_fail (G_IS_ACTION (action), NULL); + + return G_ACTION_GET_IFACE (action) + ->get_state_type (action); +} + +/** + * g_action_get_state_hint: + * @action: a #GAction + * + * Requests a hint about the valid range of values for the state of + * @action. + * + * If %NULL is returned it either means that the action is not stateful + * or that there is no hint about the valid range of values for the + * state of the action. + * + * If a #GVariant array is returned then each item in the array is a + * possible value for the state. If a #GVariant pair (ie: two-tuple) is + * returned then the tuple specifies the inclusive lower and upper bound + * of valid values for the state. + * + * In any case, the information is merely a hint. It may be possible to + * have a state value outside of the hinted range and setting a value + * within the range may fail. + * + * The return value (if non-%NULL) should be freed with + * g_variant_unref() when it is no longer required. + * + * Returns: (nullable) (transfer full): the state range hint + * + * Since: 2.28 + **/ +GVariant * +g_action_get_state_hint (GAction *action) +{ + g_return_val_if_fail (G_IS_ACTION (action), NULL); + + return G_ACTION_GET_IFACE (action) + ->get_state_hint (action); +} + +/** + * g_action_get_enabled: + * @action: a #GAction + * + * Checks if @action is currently enabled. + * + * An action must be enabled in order to be activated or in order to + * have its state changed from outside callers. + * + * Returns: whether the action is enabled + * + * Since: 2.28 + **/ +gboolean +g_action_get_enabled (GAction *action) +{ + g_return_val_if_fail (G_IS_ACTION (action), FALSE); + + return G_ACTION_GET_IFACE (action) + ->get_enabled (action); +} + +/** + * g_action_activate: + * @action: a #GAction + * @parameter: (nullable): the parameter to the activation + * + * Activates the action. + * + * @parameter must be the correct type of parameter for the action (ie: + * the parameter type given at construction time). If the parameter + * type was %NULL then @parameter must also be %NULL. + * + * If the @parameter GVariant is floating, it is consumed. + * + * Since: 2.28 + **/ +void +g_action_activate (GAction *action, + GVariant *parameter) +{ + g_return_if_fail (G_IS_ACTION (action)); + + if (parameter != NULL) + g_variant_ref_sink (parameter); + + G_ACTION_GET_IFACE (action) + ->activate (action, parameter); + + if (parameter != NULL) + g_variant_unref (parameter); +} + +/** + * g_action_name_is_valid: + * @action_name: a potential action name + * + * Checks if @action_name is valid. + * + * @action_name is valid if it consists only of alphanumeric characters, + * plus '-' and '.'. The empty string is not a valid action name. + * + * It is an error to call this function with a non-utf8 @action_name. + * @action_name must not be %NULL. + * + * Returns: %TRUE if @action_name is valid + * + * Since: 2.38 + **/ +gboolean +g_action_name_is_valid (const gchar *action_name) +{ + gchar c; + gint i; + + g_return_val_if_fail (action_name != NULL, FALSE); + + for (i = 0; (c = action_name[i]); i++) + if (!g_ascii_isalnum (c) && c != '.' && c != '-') + return FALSE; + + return i > 0; +} + +/** + * g_action_parse_detailed_name: + * @detailed_name: a detailed action name + * @action_name: (out): the action name + * @target_value: (out): the target value, or %NULL for no target + * @error: a pointer to a %NULL #GError, or %NULL + * + * Parses a detailed action name into its separate name and target + * components. + * + * Detailed action names can have three formats. + * + * The first format is used to represent an action name with no target + * value and consists of just an action name containing no whitespace + * nor the characters ':', '(' or ')'. For example: "app.action". + * + * The second format is used to represent an action with a target value + * that is a non-empty string consisting only of alphanumerics, plus '-' + * and '.'. In that case, the action name and target value are + * separated by a double colon ("::"). For example: + * "app.action::target". + * + * The third format is used to represent an action with any type of + * target value, including strings. The target value follows the action + * name, surrounded in parens. For example: "app.action(42)". The + * target value is parsed using g_variant_parse(). If a tuple-typed + * value is desired, it must be specified in the same way, resulting in + * two sets of parens, for example: "app.action((1,2,3))". A string + * target can be specified this way as well: "app.action('target')". + * For strings, this third format must be used if * target value is + * empty or contains characters other than alphanumerics, '-' and '.'. + * + * Returns: %TRUE if successful, else %FALSE with @error set + * + * Since: 2.38 + **/ +gboolean +g_action_parse_detailed_name (const gchar *detailed_name, + gchar **action_name, + GVariant **target_value, + GError **error) +{ + const gchar *target; + gsize target_len; + gsize base_len; + + /* For historical (compatibility) reasons, this function accepts some + * cases of invalid action names as long as they don't interfere with + * the separation of the action from the target value. + * + * We decide which format we have based on which we see first between + * '::' '(' and '\0'. + */ + + if (*detailed_name == '\0' || *detailed_name == ' ') + goto bad_fmt; + + base_len = strcspn (detailed_name, ": ()"); + target = detailed_name + base_len; + target_len = strlen (target); + + switch (target[0]) + { + case ' ': + case ')': + goto bad_fmt; + + case ':': + if (target[1] != ':') + goto bad_fmt; + + *target_value = g_variant_ref_sink (g_variant_new_string (target + 2)); + break; + + case '(': + { + if (target[target_len - 1] != ')') + goto bad_fmt; + + *target_value = g_variant_parse (NULL, target + 1, target + target_len - 1, NULL, error); + if (*target_value == NULL) + goto bad_fmt; + } + break; + + case '\0': + *target_value = NULL; + break; + } + + *action_name = g_strndup (detailed_name, base_len); + + return TRUE; + +bad_fmt: + if (error) + { + if (*error == NULL) + g_set_error (error, G_VARIANT_PARSE_ERROR, G_VARIANT_PARSE_ERROR_FAILED, + "Detailed action name '%s' has invalid format", detailed_name); + else + g_prefix_error (error, "Detailed action name '%s' has invalid format: ", detailed_name); + } + + return FALSE; +} + +/** + * g_action_print_detailed_name: + * @action_name: a valid action name + * @target_value: (nullable): a #GVariant target value, or %NULL + * + * Formats a detailed action name from @action_name and @target_value. + * + * It is an error to call this function with an invalid action name. + * + * This function is the opposite of g_action_parse_detailed_name(). + * It will produce a string that can be parsed back to the @action_name + * and @target_value by that function. + * + * See that function for the types of strings that will be printed by + * this function. + * + * Returns: a detailed format string + * + * Since: 2.38 + **/ +gchar * +g_action_print_detailed_name (const gchar *action_name, + GVariant *target_value) +{ + g_return_val_if_fail (g_action_name_is_valid (action_name), NULL); + + if (target_value == NULL) + return g_strdup (action_name); + + if (g_variant_is_of_type (target_value, G_VARIANT_TYPE_STRING)) + { + const gchar *str = g_variant_get_string (target_value, NULL); + + if (g_action_name_is_valid (str)) + return g_strconcat (action_name, "::", str, NULL); + } + + { + GString *result = g_string_new (action_name); + g_string_append_c (result, '('); + g_variant_print_string (target_value, result, TRUE); + g_string_append_c (result, ')'); + + return g_string_free (result, FALSE); + } +} diff --git a/gio/gaction.h b/gio/gaction.h new file mode 100644 index 0000000..f9f4b38 --- /dev/null +++ b/gio/gaction.h @@ -0,0 +1,98 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_ACTION_H__ +#define __G_ACTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_ACTION (g_action_get_type ()) +#define G_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_ACTION, GAction)) +#define G_IS_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_ACTION)) +#define G_ACTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \ + G_TYPE_ACTION, GActionInterface)) + +typedef struct _GActionInterface GActionInterface; + +struct _GActionInterface +{ + GTypeInterface g_iface; + + /* virtual functions */ + const gchar * (* get_name) (GAction *action); + const GVariantType * (* get_parameter_type) (GAction *action); + const GVariantType * (* get_state_type) (GAction *action); + GVariant * (* get_state_hint) (GAction *action); + + gboolean (* get_enabled) (GAction *action); + GVariant * (* get_state) (GAction *action); + + void (* change_state) (GAction *action, + GVariant *value); + void (* activate) (GAction *action, + GVariant *parameter); +}; + +GLIB_AVAILABLE_IN_2_30 +GType g_action_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +const gchar * g_action_get_name (GAction *action); +GLIB_AVAILABLE_IN_ALL +const GVariantType * g_action_get_parameter_type (GAction *action); +GLIB_AVAILABLE_IN_ALL +const GVariantType * g_action_get_state_type (GAction *action); +GLIB_AVAILABLE_IN_ALL +GVariant * g_action_get_state_hint (GAction *action); + +GLIB_AVAILABLE_IN_ALL +gboolean g_action_get_enabled (GAction *action); +GLIB_AVAILABLE_IN_ALL +GVariant * g_action_get_state (GAction *action); + +GLIB_AVAILABLE_IN_ALL +void g_action_change_state (GAction *action, + GVariant *value); +GLIB_AVAILABLE_IN_ALL +void g_action_activate (GAction *action, + GVariant *parameter); + +GLIB_AVAILABLE_IN_2_28 +gboolean g_action_name_is_valid (const gchar *action_name); + +GLIB_AVAILABLE_IN_2_38 +gboolean g_action_parse_detailed_name (const gchar *detailed_name, + gchar **action_name, + GVariant **target_value, + GError **error); + +GLIB_AVAILABLE_IN_2_38 +gchar * g_action_print_detailed_name (const gchar *action_name, + GVariant *target_value); + +G_END_DECLS + +#endif /* __G_ACTION_H__ */ diff --git a/gio/gactiongroup.c b/gio/gactiongroup.c new file mode 100644 index 0000000..7c7b0e7 --- /dev/null +++ b/gio/gactiongroup.c @@ -0,0 +1,790 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" +#include "gactiongroup.h" +#include "gaction.h" +#include "glibintl.h" +#include "gmarshal-internal.h" + +/** + * SECTION:gactiongroup + * @title: GActionGroup + * @short_description: A group of actions + * @include: gio/gio.h + * @see_also: #GAction + * + * #GActionGroup represents a group of actions. Actions can be used to + * expose functionality in a structured way, either from one part of a + * program to another, or to the outside world. Action groups are often + * used together with a #GMenuModel that provides additional + * representation data for displaying the actions to the user, e.g. in + * a menu. + * + * The main way to interact with the actions in a GActionGroup is to + * activate them with g_action_group_activate_action(). Activating an + * action may require a #GVariant parameter. The required type of the + * parameter can be inquired with g_action_group_get_action_parameter_type(). + * Actions may be disabled, see g_action_group_get_action_enabled(). + * Activating a disabled action has no effect. + * + * Actions may optionally have a state in the form of a #GVariant. The + * current state of an action can be inquired with + * g_action_group_get_action_state(). Activating a stateful action may + * change its state, but it is also possible to set the state by calling + * g_action_group_change_action_state(). + * + * As typical example, consider a text editing application which has an + * option to change the current font to 'bold'. A good way to represent + * this would be a stateful action, with a boolean state. Activating the + * action would toggle the state. + * + * Each action in the group has a unique name (which is a string). All + * method calls, except g_action_group_list_actions() take the name of + * an action as an argument. + * + * The #GActionGroup API is meant to be the 'public' API to the action + * group. The calls here are exactly the interaction that 'external + * forces' (eg: UI, incoming D-Bus messages, etc.) are supposed to have + * with actions. 'Internal' APIs (ie: ones meant only to be accessed by + * the action group implementation) are found on subclasses. This is + * why you will find - for example - g_action_group_get_action_enabled() + * but not an equivalent set() call. + * + * Signals are emitted on the action group in response to state changes + * on individual actions. + * + * Implementations of #GActionGroup should provide implementations for + * the virtual functions g_action_group_list_actions() and + * g_action_group_query_action(). The other virtual functions should + * not be implemented - their "wrappers" are actually implemented with + * calls to g_action_group_query_action(). + */ + +/** + * GActionGroup: + * + * #GActionGroup is an opaque data structure and can only be accessed + * using the following functions. + **/ + +/** + * GActionGroupInterface: + * @has_action: the virtual function pointer for g_action_group_has_action() + * @list_actions: the virtual function pointer for g_action_group_list_actions() + * @get_action_parameter_type: the virtual function pointer for g_action_group_get_action_parameter_type() + * @get_action_state_type: the virtual function pointer for g_action_group_get_action_state_type() + * @get_action_state_hint: the virtual function pointer for g_action_group_get_action_state_hint() + * @get_action_enabled: the virtual function pointer for g_action_group_get_action_enabled() + * @get_action_state: the virtual function pointer for g_action_group_get_action_state() + * @change_action_state: the virtual function pointer for g_action_group_change_action_state() + * @query_action: the virtual function pointer for g_action_group_query_action() + * @activate_action: the virtual function pointer for g_action_group_activate_action() + * @change_action_state: the virtual function pointer for g_action_group_change_action_state() + * @action_added: the class closure for the #GActionGroup::action-added signal + * @action_removed: the class closure for the #GActionGroup::action-removed signal + * @action_enabled_changed: the class closure for the #GActionGroup::action-enabled-changed signal + * @action_state_changed: the class closure for the #GActionGroup::action-enabled-changed signal + * + * The virtual function table for #GActionGroup. + * + * Since: 2.28 + **/ + +G_DEFINE_INTERFACE (GActionGroup, g_action_group, G_TYPE_OBJECT) + +enum +{ + SIGNAL_ACTION_ADDED, + SIGNAL_ACTION_REMOVED, + SIGNAL_ACTION_ENABLED_CHANGED, + SIGNAL_ACTION_STATE_CHANGED, + NR_SIGNALS +}; + +static guint g_action_group_signals[NR_SIGNALS]; + +static gboolean +g_action_group_real_has_action (GActionGroup *action_group, + const gchar *action_name) +{ + return g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, NULL, NULL); +} + +static gboolean +g_action_group_real_get_action_enabled (GActionGroup *action_group, + const gchar *action_name) +{ + gboolean enabled = FALSE; + + g_action_group_query_action (action_group, action_name, &enabled, NULL, NULL, NULL, NULL); + + return enabled; +} + +static const GVariantType * +g_action_group_real_get_action_parameter_type (GActionGroup *action_group, + const gchar *action_name) +{ + const GVariantType *type = NULL; + + g_action_group_query_action (action_group, action_name, NULL, &type, NULL, NULL, NULL); + + return type; +} + +static const GVariantType * +g_action_group_real_get_action_state_type (GActionGroup *action_group, + const gchar *action_name) +{ + const GVariantType *type = NULL; + + g_action_group_query_action (action_group, action_name, NULL, NULL, &type, NULL, NULL); + + return type; +} + +static GVariant * +g_action_group_real_get_action_state_hint (GActionGroup *action_group, + const gchar *action_name) +{ + GVariant *hint = NULL; + + g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, &hint, NULL); + + return hint; +} + +static GVariant * +g_action_group_real_get_action_state (GActionGroup *action_group, + const gchar *action_name) +{ + GVariant *state = NULL; + + g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, NULL, &state); + + return state; +} + +static gboolean +g_action_group_real_query_action (GActionGroup *action_group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state) +{ + GActionGroupInterface *iface = G_ACTION_GROUP_GET_IFACE (action_group); + + /* we expect implementations to override this method, but we also + * allow for implementations that existed before this method was + * introduced to override the individual accessors instead. + * + * detect the case that neither has happened and report it. + */ + if G_UNLIKELY (iface->has_action == g_action_group_real_has_action || + iface->get_action_enabled == g_action_group_real_get_action_enabled || + iface->get_action_parameter_type == g_action_group_real_get_action_parameter_type || + iface->get_action_state_type == g_action_group_real_get_action_state_type || + iface->get_action_state_hint == g_action_group_real_get_action_state_hint || + iface->get_action_state == g_action_group_real_get_action_state) + { + g_critical ("Class '%s' implements GActionGroup interface without overriding " + "query_action() method -- bailing out to avoid infinite recursion.", + G_OBJECT_TYPE_NAME (action_group)); + return FALSE; + } + + if (!(* iface->has_action) (action_group, action_name)) + return FALSE; + + if (enabled != NULL) + *enabled = (* iface->get_action_enabled) (action_group, action_name); + + if (parameter_type != NULL) + *parameter_type = (* iface->get_action_parameter_type) (action_group, action_name); + + if (state_type != NULL) + *state_type = (* iface->get_action_state_type) (action_group, action_name); + + if (state_hint != NULL) + *state_hint = (* iface->get_action_state_hint) (action_group, action_name); + + if (state != NULL) + *state = (* iface->get_action_state) (action_group, action_name); + + return TRUE; +} + +static void +g_action_group_default_init (GActionGroupInterface *iface) +{ + iface->has_action = g_action_group_real_has_action; + iface->get_action_enabled = g_action_group_real_get_action_enabled; + iface->get_action_parameter_type = g_action_group_real_get_action_parameter_type; + iface->get_action_state_type = g_action_group_real_get_action_state_type; + iface->get_action_state_hint = g_action_group_real_get_action_state_hint; + iface->get_action_state = g_action_group_real_get_action_state; + iface->query_action = g_action_group_real_query_action; + + /** + * GActionGroup::action-added: + * @action_group: the #GActionGroup that changed + * @action_name: the name of the action in @action_group + * + * Signals that a new action was just added to the group. + * This signal is emitted after the action has been added + * and is now visible. + * + * Since: 2.28 + **/ + g_action_group_signals[SIGNAL_ACTION_ADDED] = + g_signal_new (I_("action-added"), + G_TYPE_ACTION_GROUP, + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_STRUCT_OFFSET (GActionGroupInterface, action_added), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + /** + * GActionGroup::action-removed: + * @action_group: the #GActionGroup that changed + * @action_name: the name of the action in @action_group + * + * Signals that an action is just about to be removed from the group. + * This signal is emitted before the action is removed, so the action + * is still visible and can be queried from the signal handler. + * + * Since: 2.28 + **/ + g_action_group_signals[SIGNAL_ACTION_REMOVED] = + g_signal_new (I_("action-removed"), + G_TYPE_ACTION_GROUP, + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_STRUCT_OFFSET (GActionGroupInterface, action_removed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + + /** + * GActionGroup::action-enabled-changed: + * @action_group: the #GActionGroup that changed + * @action_name: the name of the action in @action_group + * @enabled: whether the action is enabled or not + * + * Signals that the enabled status of the named action has changed. + * + * Since: 2.28 + **/ + g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED] = + g_signal_new (I_("action-enabled-changed"), + G_TYPE_ACTION_GROUP, + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_STRUCT_OFFSET (GActionGroupInterface, + action_enabled_changed), + NULL, NULL, + _g_cclosure_marshal_VOID__STRING_BOOLEAN, + G_TYPE_NONE, 2, + G_TYPE_STRING, + G_TYPE_BOOLEAN); + g_signal_set_va_marshaller (g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED], + G_TYPE_FROM_INTERFACE (iface), + _g_cclosure_marshal_VOID__STRING_BOOLEANv); + + /** + * GActionGroup::action-state-changed: + * @action_group: the #GActionGroup that changed + * @action_name: the name of the action in @action_group + * @value: the new value of the state + * + * Signals that the state of the named action has changed. + * + * Since: 2.28 + **/ + g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED] = + g_signal_new (I_("action-state-changed"), + G_TYPE_ACTION_GROUP, + G_SIGNAL_RUN_LAST | + G_SIGNAL_DETAILED | + G_SIGNAL_MUST_COLLECT, + G_STRUCT_OFFSET (GActionGroupInterface, + action_state_changed), + NULL, NULL, + _g_cclosure_marshal_VOID__STRING_VARIANT, + G_TYPE_NONE, 2, + G_TYPE_STRING, + G_TYPE_VARIANT); + g_signal_set_va_marshaller (g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED], + G_TYPE_FROM_INTERFACE (iface), + _g_cclosure_marshal_VOID__STRING_VARIANTv); +} + +/** + * g_action_group_list_actions: + * @action_group: a #GActionGroup + * + * Lists the actions contained within @action_group. + * + * The caller is responsible for freeing the list with g_strfreev() when + * it is no longer required. + * + * Returns: (transfer full): a %NULL-terminated array of the names of the + * actions in the group + * + * Since: 2.28 + **/ +gchar ** +g_action_group_list_actions (GActionGroup *action_group) +{ + g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL); + + return G_ACTION_GROUP_GET_IFACE (action_group) + ->list_actions (action_group); +} + +/** + * g_action_group_has_action: + * @action_group: a #GActionGroup + * @action_name: the name of the action to check for + * + * Checks if the named action exists within @action_group. + * + * Returns: whether the named action exists + * + * Since: 2.28 + **/ +gboolean +g_action_group_has_action (GActionGroup *action_group, + const gchar *action_name) +{ + g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE); + + return G_ACTION_GROUP_GET_IFACE (action_group) + ->has_action (action_group, action_name); +} + +/** + * g_action_group_get_action_parameter_type: + * @action_group: a #GActionGroup + * @action_name: the name of the action to query + * + * Queries the type of the parameter that must be given when activating + * the named action within @action_group. + * + * When activating the action using g_action_group_activate_action(), + * the #GVariant given to that function must be of the type returned + * by this function. + * + * In the case that this function returns %NULL, you must not give any + * #GVariant, but %NULL instead. + * + * The parameter type of a particular action will never change but it is + * possible for an action to be removed and for a new action to be added + * with the same name but a different parameter type. + * + * Returns: (nullable): the parameter type + * + * Since: 2.28 + **/ +const GVariantType * +g_action_group_get_action_parameter_type (GActionGroup *action_group, + const gchar *action_name) +{ + g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL); + + return G_ACTION_GROUP_GET_IFACE (action_group) + ->get_action_parameter_type (action_group, action_name); +} + +/** + * g_action_group_get_action_state_type: + * @action_group: a #GActionGroup + * @action_name: the name of the action to query + * + * Queries the type of the state of the named action within + * @action_group. + * + * If the action is stateful then this function returns the + * #GVariantType of the state. All calls to + * g_action_group_change_action_state() must give a #GVariant of this + * type and g_action_group_get_action_state() will return a #GVariant + * of the same type. + * + * If the action is not stateful then this function will return %NULL. + * In that case, g_action_group_get_action_state() will return %NULL + * and you must not call g_action_group_change_action_state(). + * + * The state type of a particular action will never change but it is + * possible for an action to be removed and for a new action to be added + * with the same name but a different state type. + * + * Returns: (nullable): the state type, if the action is stateful + * + * Since: 2.28 + **/ +const GVariantType * +g_action_group_get_action_state_type (GActionGroup *action_group, + const gchar *action_name) +{ + g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL); + + return G_ACTION_GROUP_GET_IFACE (action_group) + ->get_action_state_type (action_group, action_name); +} + +/** + * g_action_group_get_action_state_hint: + * @action_group: a #GActionGroup + * @action_name: the name of the action to query + * + * Requests a hint about the valid range of values for the state of the + * named action within @action_group. + * + * If %NULL is returned it either means that the action is not stateful + * or that there is no hint about the valid range of values for the + * state of the action. + * + * If a #GVariant array is returned then each item in the array is a + * possible value for the state. If a #GVariant pair (ie: two-tuple) is + * returned then the tuple specifies the inclusive lower and upper bound + * of valid values for the state. + * + * In any case, the information is merely a hint. It may be possible to + * have a state value outside of the hinted range and setting a value + * within the range may fail. + * + * The return value (if non-%NULL) should be freed with + * g_variant_unref() when it is no longer required. + * + * Returns: (nullable) (transfer full): the state range hint + * + * Since: 2.28 + **/ +GVariant * +g_action_group_get_action_state_hint (GActionGroup *action_group, + const gchar *action_name) +{ + g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL); + + return G_ACTION_GROUP_GET_IFACE (action_group) + ->get_action_state_hint (action_group, action_name); +} + +/** + * g_action_group_get_action_enabled: + * @action_group: a #GActionGroup + * @action_name: the name of the action to query + * + * Checks if the named action within @action_group is currently enabled. + * + * An action must be enabled in order to be activated or in order to + * have its state changed from outside callers. + * + * Returns: whether or not the action is currently enabled + * + * Since: 2.28 + **/ +gboolean +g_action_group_get_action_enabled (GActionGroup *action_group, + const gchar *action_name) +{ + g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE); + + return G_ACTION_GROUP_GET_IFACE (action_group) + ->get_action_enabled (action_group, action_name); +} + +/** + * g_action_group_get_action_state: + * @action_group: a #GActionGroup + * @action_name: the name of the action to query + * + * Queries the current state of the named action within @action_group. + * + * If the action is not stateful then %NULL will be returned. If the + * action is stateful then the type of the return value is the type + * given by g_action_group_get_action_state_type(). + * + * The return value (if non-%NULL) should be freed with + * g_variant_unref() when it is no longer required. + * + * Returns: (nullable) (transfer full): the current state of the action + * + * Since: 2.28 + **/ +GVariant * +g_action_group_get_action_state (GActionGroup *action_group, + const gchar *action_name) +{ + g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL); + + return G_ACTION_GROUP_GET_IFACE (action_group) + ->get_action_state (action_group, action_name); +} + +/** + * g_action_group_change_action_state: + * @action_group: a #GActionGroup + * @action_name: the name of the action to request the change on + * @value: the new state + * + * Request for the state of the named action within @action_group to be + * changed to @value. + * + * The action must be stateful and @value must be of the correct type. + * See g_action_group_get_action_state_type(). + * + * This call merely requests a change. The action may refuse to change + * its state or may change its state to something other than @value. + * See g_action_group_get_action_state_hint(). + * + * If the @value GVariant is floating, it is consumed. + * + * Since: 2.28 + **/ +void +g_action_group_change_action_state (GActionGroup *action_group, + const gchar *action_name, + GVariant *value) +{ + g_return_if_fail (G_IS_ACTION_GROUP (action_group)); + g_return_if_fail (action_name != NULL); + g_return_if_fail (value != NULL); + + G_ACTION_GROUP_GET_IFACE (action_group) + ->change_action_state (action_group, action_name, value); +} + +/** + * g_action_group_activate_action: + * @action_group: a #GActionGroup + * @action_name: the name of the action to activate + * @parameter: (nullable): parameters to the activation + * + * Activate the named action within @action_group. + * + * If the action is expecting a parameter, then the correct type of + * parameter must be given as @parameter. If the action is expecting no + * parameters then @parameter must be %NULL. See + * g_action_group_get_action_parameter_type(). + * + * If the #GActionGroup implementation supports asynchronous remote + * activation over D-Bus, this call may return before the relevant + * D-Bus traffic has been sent, or any replies have been received. In + * order to block on such asynchronous activation calls, + * g_dbus_connection_flush() should be called prior to the code, which + * depends on the result of the action activation. Without flushing + * the D-Bus connection, there is no guarantee that the action would + * have been activated. + * + * The following code which runs in a remote app instance, shows an + * example of a "quit" action being activated on the primary app + * instance over D-Bus. Here g_dbus_connection_flush() is called + * before `exit()`. Without g_dbus_connection_flush(), the "quit" action + * may fail to be activated on the primary instance. + * + * |[ + * // call "quit" action on primary instance + * g_action_group_activate_action (G_ACTION_GROUP (app), "quit", NULL); + * + * // make sure the action is activated now + * g_dbus_connection_flush (...); + * + * g_debug ("application has been terminated. exiting."); + * + * exit (0); + * ]| + * + * Since: 2.28 + **/ +void +g_action_group_activate_action (GActionGroup *action_group, + const gchar *action_name, + GVariant *parameter) +{ + g_return_if_fail (G_IS_ACTION_GROUP (action_group)); + g_return_if_fail (action_name != NULL); + + G_ACTION_GROUP_GET_IFACE (action_group) + ->activate_action (action_group, action_name, parameter); +} + +/** + * g_action_group_action_added: + * @action_group: a #GActionGroup + * @action_name: the name of an action in the group + * + * Emits the #GActionGroup::action-added signal on @action_group. + * + * This function should only be called by #GActionGroup implementations. + * + * Since: 2.28 + **/ +void +g_action_group_action_added (GActionGroup *action_group, + const gchar *action_name) +{ + g_return_if_fail (G_IS_ACTION_GROUP (action_group)); + g_return_if_fail (action_name != NULL); + + g_signal_emit (action_group, + g_action_group_signals[SIGNAL_ACTION_ADDED], + g_quark_try_string (action_name), + action_name); +} + +/** + * g_action_group_action_removed: + * @action_group: a #GActionGroup + * @action_name: the name of an action in the group + * + * Emits the #GActionGroup::action-removed signal on @action_group. + * + * This function should only be called by #GActionGroup implementations. + * + * Since: 2.28 + **/ +void +g_action_group_action_removed (GActionGroup *action_group, + const gchar *action_name) +{ + g_return_if_fail (G_IS_ACTION_GROUP (action_group)); + g_return_if_fail (action_name != NULL); + + g_signal_emit (action_group, + g_action_group_signals[SIGNAL_ACTION_REMOVED], + g_quark_try_string (action_name), + action_name); +} + +/** + * g_action_group_action_enabled_changed: + * @action_group: a #GActionGroup + * @action_name: the name of an action in the group + * @enabled: whether or not the action is now enabled + * + * Emits the #GActionGroup::action-enabled-changed signal on @action_group. + * + * This function should only be called by #GActionGroup implementations. + * + * Since: 2.28 + **/ +void +g_action_group_action_enabled_changed (GActionGroup *action_group, + const gchar *action_name, + gboolean enabled) +{ + g_return_if_fail (G_IS_ACTION_GROUP (action_group)); + g_return_if_fail (action_name != NULL); + + enabled = !!enabled; + + g_signal_emit (action_group, + g_action_group_signals[SIGNAL_ACTION_ENABLED_CHANGED], + g_quark_try_string (action_name), + action_name, + enabled); +} + +/** + * g_action_group_action_state_changed: + * @action_group: a #GActionGroup + * @action_name: the name of an action in the group + * @state: the new state of the named action + * + * Emits the #GActionGroup::action-state-changed signal on @action_group. + * + * This function should only be called by #GActionGroup implementations. + * + * Since: 2.28 + **/ +void +g_action_group_action_state_changed (GActionGroup *action_group, + const gchar *action_name, + GVariant *state) +{ + g_return_if_fail (G_IS_ACTION_GROUP (action_group)); + g_return_if_fail (action_name != NULL); + + g_signal_emit (action_group, + g_action_group_signals[SIGNAL_ACTION_STATE_CHANGED], + g_quark_try_string (action_name), + action_name, + state); +} + +/** + * g_action_group_query_action: + * @action_group: a #GActionGroup + * @action_name: the name of an action in the group + * @enabled: (out): if the action is presently enabled + * @parameter_type: (out) (transfer none) (optional): the parameter type, or %NULL if none needed + * @state_type: (out) (transfer none) (optional): the state type, or %NULL if stateless + * @state_hint: (out) (optional): the state hint, or %NULL if none + * @state: (out) (optional): the current state, or %NULL if stateless + * + * Queries all aspects of the named action within an @action_group. + * + * This function acquires the information available from + * g_action_group_has_action(), g_action_group_get_action_enabled(), + * g_action_group_get_action_parameter_type(), + * g_action_group_get_action_state_type(), + * g_action_group_get_action_state_hint() and + * g_action_group_get_action_state() with a single function call. + * + * This provides two main benefits. + * + * The first is the improvement in efficiency that comes with not having + * to perform repeated lookups of the action in order to discover + * different things about it. The second is that implementing + * #GActionGroup can now be done by only overriding this one virtual + * function. + * + * The interface provides a default implementation of this function that + * calls the individual functions, as required, to fetch the + * information. The interface also provides default implementations of + * those functions that call this function. All implementations, + * therefore, must override either this function or all of the others. + * + * If the action exists, %TRUE is returned and any of the requested + * fields (as indicated by having a non-%NULL reference passed in) are + * filled. If the action doesn't exist, %FALSE is returned and the + * fields may or may not have been modified. + * + * Returns: %TRUE if the action exists, else %FALSE + * + * Since: 2.32 + **/ +gboolean +g_action_group_query_action (GActionGroup *action_group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state) +{ + return G_ACTION_GROUP_GET_IFACE (action_group) + ->query_action (action_group, action_name, enabled, parameter_type, state_type, state_hint, state); +} diff --git a/gio/gactiongroup.h b/gio/gactiongroup.h new file mode 100644 index 0000000..bba8a23 --- /dev/null +++ b/gio/gactiongroup.h @@ -0,0 +1,161 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_ACTION_GROUP_H__ +#define __G_ACTION_GROUP_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + + +#define G_TYPE_ACTION_GROUP (g_action_group_get_type ()) +#define G_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_ACTION_GROUP, GActionGroup)) +#define G_IS_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_ACTION_GROUP)) +#define G_ACTION_GROUP_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \ + G_TYPE_ACTION_GROUP, GActionGroupInterface)) + +typedef struct _GActionGroupInterface GActionGroupInterface; + +struct _GActionGroupInterface +{ + GTypeInterface g_iface; + + /* virtual functions */ + gboolean (* has_action) (GActionGroup *action_group, + const gchar *action_name); + + gchar ** (* list_actions) (GActionGroup *action_group); + + gboolean (* get_action_enabled) (GActionGroup *action_group, + const gchar *action_name); + + const GVariantType * (* get_action_parameter_type) (GActionGroup *action_group, + const gchar *action_name); + + const GVariantType * (* get_action_state_type) (GActionGroup *action_group, + const gchar *action_name); + + GVariant * (* get_action_state_hint) (GActionGroup *action_group, + const gchar *action_name); + + GVariant * (* get_action_state) (GActionGroup *action_group, + const gchar *action_name); + + void (* change_action_state) (GActionGroup *action_group, + const gchar *action_name, + GVariant *value); + + void (* activate_action) (GActionGroup *action_group, + const gchar *action_name, + GVariant *parameter); + + /* signals */ + void (* action_added) (GActionGroup *action_group, + const gchar *action_name); + void (* action_removed) (GActionGroup *action_group, + const gchar *action_name); + void (* action_enabled_changed) (GActionGroup *action_group, + const gchar *action_name, + gboolean enabled); + void (* action_state_changed) (GActionGroup *action_group, + const gchar *action_name, + GVariant *state); + + /* more virtual functions */ + gboolean (* query_action) (GActionGroup *action_group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_action_group_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gboolean g_action_group_has_action (GActionGroup *action_group, + const gchar *action_name); +GLIB_AVAILABLE_IN_ALL +gchar ** g_action_group_list_actions (GActionGroup *action_group); + +GLIB_AVAILABLE_IN_ALL +const GVariantType * g_action_group_get_action_parameter_type (GActionGroup *action_group, + const gchar *action_name); +GLIB_AVAILABLE_IN_ALL +const GVariantType * g_action_group_get_action_state_type (GActionGroup *action_group, + const gchar *action_name); +GLIB_AVAILABLE_IN_ALL +GVariant * g_action_group_get_action_state_hint (GActionGroup *action_group, + const gchar *action_name); + +GLIB_AVAILABLE_IN_ALL +gboolean g_action_group_get_action_enabled (GActionGroup *action_group, + const gchar *action_name); + +GLIB_AVAILABLE_IN_ALL +GVariant * g_action_group_get_action_state (GActionGroup *action_group, + const gchar *action_name); +GLIB_AVAILABLE_IN_ALL +void g_action_group_change_action_state (GActionGroup *action_group, + const gchar *action_name, + GVariant *value); + +GLIB_AVAILABLE_IN_ALL +void g_action_group_activate_action (GActionGroup *action_group, + const gchar *action_name, + GVariant *parameter); + +/* signals */ +GLIB_AVAILABLE_IN_ALL +void g_action_group_action_added (GActionGroup *action_group, + const gchar *action_name); +GLIB_AVAILABLE_IN_ALL +void g_action_group_action_removed (GActionGroup *action_group, + const gchar *action_name); +GLIB_AVAILABLE_IN_ALL +void g_action_group_action_enabled_changed (GActionGroup *action_group, + const gchar *action_name, + gboolean enabled); + +GLIB_AVAILABLE_IN_ALL +void g_action_group_action_state_changed (GActionGroup *action_group, + const gchar *action_name, + GVariant *state); + +GLIB_AVAILABLE_IN_2_32 +gboolean g_action_group_query_action (GActionGroup *action_group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state); + +G_END_DECLS + +#endif /* __G_ACTION_GROUP_H__ */ diff --git a/gio/gactiongroupexporter.c b/gio/gactiongroupexporter.c new file mode 100644 index 0000000..d1c1903 --- /dev/null +++ b/gio/gactiongroupexporter.c @@ -0,0 +1,608 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gactiongroupexporter.h" + +#include "gdbusmethodinvocation.h" +#include "gremoteactiongroup.h" +#include "gdbusintrospection.h" +#include "gdbusconnection.h" +#include "gactiongroup.h" +#include "gdbuserror.h" + +/** + * SECTION:gactiongroupexporter + * @title: GActionGroup exporter + * @include: gio/gio.h + * @short_description: Export GActionGroups on D-Bus + * @see_also: #GActionGroup, #GDBusActionGroup + * + * These functions support exporting a #GActionGroup on D-Bus. + * The D-Bus interface that is used is a private implementation + * detail. + * + * To access an exported #GActionGroup remotely, use + * g_dbus_action_group_get() to obtain a #GDBusActionGroup. + */ + +static GVariant * +g_action_group_describe_action (GActionGroup *action_group, + const gchar *name) +{ + const GVariantType *type; + GVariantBuilder builder; + gboolean enabled; + GVariant *state; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(bgav)")); + + enabled = g_action_group_get_action_enabled (action_group, name); + g_variant_builder_add (&builder, "b", enabled); + + if ((type = g_action_group_get_action_parameter_type (action_group, name))) + { + gchar *str = g_variant_type_dup_string (type); + g_variant_builder_add (&builder, "g", str); + g_free (str); + } + else + g_variant_builder_add (&builder, "g", ""); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("av")); + if ((state = g_action_group_get_action_state (action_group, name))) + { + g_variant_builder_add (&builder, "v", state); + g_variant_unref (state); + } + g_variant_builder_close (&builder); + + return g_variant_builder_end (&builder); +} + +/* Using XML saves us dozens of relocations vs. using the introspection + * structure types. We only need to burn cycles and memory if we + * actually use the exporter -- not in every single app using GIO. + * + * It's also a lot easier to read. :) + * + * For documentation of this interface, see + * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI + */ +const char org_gtk_Actions_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +static GDBusInterfaceInfo *org_gtk_Actions; + +typedef struct +{ + GActionGroup *action_group; + GDBusConnection *connection; + GMainContext *context; + gchar *object_path; + GHashTable *pending_changes; + GSource *pending_source; +} GActionGroupExporter; + +#define ACTION_ADDED_EVENT (1u<<0) +#define ACTION_REMOVED_EVENT (1u<<1) +#define ACTION_STATE_CHANGED_EVENT (1u<<2) +#define ACTION_ENABLED_CHANGED_EVENT (1u<<3) + +static gboolean +g_action_group_exporter_dispatch_events (gpointer user_data) +{ + GActionGroupExporter *exporter = user_data; + GVariantBuilder removes; + GVariantBuilder enabled_changes; + GVariantBuilder state_changes; + GVariantBuilder adds; + GHashTableIter iter; + gpointer value; + gpointer key; + + g_variant_builder_init (&removes, G_VARIANT_TYPE_STRING_ARRAY); + g_variant_builder_init (&enabled_changes, G_VARIANT_TYPE ("a{sb}")); + g_variant_builder_init (&state_changes, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_init (&adds, G_VARIANT_TYPE ("a{s(bgav)}")); + + g_hash_table_iter_init (&iter, exporter->pending_changes); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + guint events = GPOINTER_TO_INT (value); + const gchar *name = key; + + /* Adds and removes are incompatible with enabled or state + * changes, but we must report at least one event. + */ + g_assert (((events & (ACTION_ENABLED_CHANGED_EVENT | ACTION_STATE_CHANGED_EVENT)) == 0) != + ((events & (ACTION_REMOVED_EVENT | ACTION_ADDED_EVENT)) == 0)); + + if (events & ACTION_REMOVED_EVENT) + g_variant_builder_add (&removes, "s", name); + + if (events & ACTION_ENABLED_CHANGED_EVENT) + { + gboolean enabled; + + enabled = g_action_group_get_action_enabled (exporter->action_group, name); + g_variant_builder_add (&enabled_changes, "{sb}", name, enabled); + } + + if (events & ACTION_STATE_CHANGED_EVENT) + { + GVariant *state; + + state = g_action_group_get_action_state (exporter->action_group, name); + g_variant_builder_add (&state_changes, "{sv}", name, state); + g_variant_unref (state); + } + + if (events & ACTION_ADDED_EVENT) + { + GVariant *description; + + description = g_action_group_describe_action (exporter->action_group, name); + g_variant_builder_add (&adds, "{s@(bgav)}", name, description); + } + } + + g_hash_table_remove_all (exporter->pending_changes); + + g_dbus_connection_emit_signal (exporter->connection, NULL, exporter->object_path, + "org.gtk.Actions", "Changed", + g_variant_new ("(asa{sb}a{sv}a{s(bgav)})", + &removes, &enabled_changes, + &state_changes, &adds), + NULL); + + exporter->pending_source = NULL; + + return FALSE; +} + +static void +g_action_group_exporter_flush_queue (GActionGroupExporter *exporter) +{ + if (exporter->pending_source) + { + g_source_destroy (exporter->pending_source); + g_action_group_exporter_dispatch_events (exporter); + g_assert (exporter->pending_source == NULL); + } +} + +static guint +g_action_group_exporter_get_events (GActionGroupExporter *exporter, + const gchar *name) +{ + return (gsize) g_hash_table_lookup (exporter->pending_changes, name); +} + +static void +g_action_group_exporter_set_events (GActionGroupExporter *exporter, + const gchar *name, + guint events) +{ + gboolean have_events; + gboolean is_queued; + + if (events != 0) + g_hash_table_insert (exporter->pending_changes, g_strdup (name), GINT_TO_POINTER (events)); + else + g_hash_table_remove (exporter->pending_changes, name); + + have_events = g_hash_table_size (exporter->pending_changes) > 0; + is_queued = exporter->pending_source != NULL; + + if (have_events && !is_queued) + { + GSource *source; + + source = g_idle_source_new (); + exporter->pending_source = source; + g_source_set_callback (source, g_action_group_exporter_dispatch_events, exporter, NULL); + g_source_set_static_name (source, "[gio] g_action_group_exporter_dispatch_events"); + g_source_attach (source, exporter->context); + g_source_unref (source); + } + + if (!have_events && is_queued) + { + g_source_destroy (exporter->pending_source); + exporter->pending_source = NULL; + } +} + +static void +g_action_group_exporter_action_added (GActionGroup *action_group, + const gchar *action_name, + gpointer user_data) +{ + GActionGroupExporter *exporter = user_data; + guint event_mask; + + event_mask = g_action_group_exporter_get_events (exporter, action_name); + + /* The action is new, so we should not have any pending + * enabled-changed or state-changed signals for it. + */ + g_assert (~event_mask & (ACTION_STATE_CHANGED_EVENT | + ACTION_ENABLED_CHANGED_EVENT)); + + event_mask |= ACTION_ADDED_EVENT; + + g_action_group_exporter_set_events (exporter, action_name, event_mask); +} + +static void +g_action_group_exporter_action_removed (GActionGroup *action_group, + const gchar *action_name, + gpointer user_data) +{ + GActionGroupExporter *exporter = user_data; + guint event_mask; + + event_mask = g_action_group_exporter_get_events (exporter, action_name); + + /* If the add event for this is still queued then just cancel it since + * it's gone now. + * + * If the event was freshly added, there should not have been any + * enabled or state changed events. + */ + if (event_mask & ACTION_ADDED_EVENT) + { + g_assert (~event_mask & ~(ACTION_STATE_CHANGED_EVENT | ACTION_ENABLED_CHANGED_EVENT)); + event_mask &= ~ACTION_ADDED_EVENT; + } + + /* Otherwise, queue a remove event. Drop any state or enabled changes + * that were queued before the remove. */ + else + { + event_mask |= ACTION_REMOVED_EVENT; + event_mask &= ~(ACTION_STATE_CHANGED_EVENT | ACTION_ENABLED_CHANGED_EVENT); + } + + g_action_group_exporter_set_events (exporter, action_name, event_mask); +} + +static void +g_action_group_exporter_action_state_changed (GActionGroup *action_group, + const gchar *action_name, + GVariant *value, + gpointer user_data) +{ + GActionGroupExporter *exporter = user_data; + guint event_mask; + + event_mask = g_action_group_exporter_get_events (exporter, action_name); + + /* If it was removed, it must have been added back. Otherwise, why + * are we hearing about changes? + */ + g_assert (~event_mask & ACTION_REMOVED_EVENT || + event_mask & ACTION_ADDED_EVENT); + + /* If it is freshly added, don't also bother with the state change + * signal since the updated state will be sent as part of the pending + * add message. + */ + if (~event_mask & ACTION_ADDED_EVENT) + event_mask |= ACTION_STATE_CHANGED_EVENT; + + g_action_group_exporter_set_events (exporter, action_name, event_mask); +} + +static void +g_action_group_exporter_action_enabled_changed (GActionGroup *action_group, + const gchar *action_name, + gboolean enabled, + gpointer user_data) +{ + GActionGroupExporter *exporter = user_data; + guint event_mask; + + event_mask = g_action_group_exporter_get_events (exporter, action_name); + + /* Reasoning as above. */ + g_assert (~event_mask & ACTION_REMOVED_EVENT || + event_mask & ACTION_ADDED_EVENT); + + if (~event_mask & ACTION_ADDED_EVENT) + event_mask |= ACTION_ENABLED_CHANGED_EVENT; + + g_action_group_exporter_set_events (exporter, action_name, event_mask); +} + +static void +org_gtk_Actions_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GActionGroupExporter *exporter = user_data; + GVariant *result = NULL; + + g_action_group_exporter_flush_queue (exporter); + + if (g_str_equal (method_name, "List")) + { + gchar **list; + + list = g_action_group_list_actions (exporter->action_group); + result = g_variant_new ("(^as)", list); + g_strfreev (list); + } + + else if (g_str_equal (method_name, "Describe")) + { + const gchar *name; + GVariant *desc; + + g_variant_get (parameters, "(&s)", &name); + + if (!g_action_group_has_action (exporter->action_group, name)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "The named action ('%s') does not exist.", name); + return; + } + + desc = g_action_group_describe_action (exporter->action_group, name); + result = g_variant_new ("(@(bgav))", desc); + } + + else if (g_str_equal (method_name, "DescribeAll")) + { + GVariantBuilder builder; + gchar **list; + gint i; + + list = g_action_group_list_actions (exporter->action_group); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{s(bgav)}")); + for (i = 0; list[i]; i++) + { + const gchar *name = list[i]; + GVariant *description; + + description = g_action_group_describe_action (exporter->action_group, name); + g_variant_builder_add (&builder, "{s@(bgav)}", name, description); + } + result = g_variant_new ("(a{s(bgav)})", &builder); + g_strfreev (list); + } + + else if (g_str_equal (method_name, "Activate")) + { + GVariant *parameter = NULL; + GVariant *platform_data; + GVariantIter *iter; + const gchar *name; + + g_variant_get (parameters, "(&sav@a{sv})", &name, &iter, &platform_data); + g_variant_iter_next (iter, "v", ¶meter); + g_variant_iter_free (iter); + + if (G_IS_REMOTE_ACTION_GROUP (exporter->action_group)) + g_remote_action_group_activate_action_full (G_REMOTE_ACTION_GROUP (exporter->action_group), + name, parameter, platform_data); + else + g_action_group_activate_action (exporter->action_group, name, parameter); + + if (parameter) + g_variant_unref (parameter); + + g_variant_unref (platform_data); + } + + else if (g_str_equal (method_name, "SetState")) + { + GVariant *platform_data; + const gchar *name; + GVariant *state; + + g_variant_get (parameters, "(&sv@a{sv})", &name, &state, &platform_data); + + if (G_IS_REMOTE_ACTION_GROUP (exporter->action_group)) + g_remote_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (exporter->action_group), + name, state, platform_data); + else + g_action_group_change_action_state (exporter->action_group, name, state); + + g_variant_unref (platform_data); + g_variant_unref (state); + } + + else + g_assert_not_reached (); + + g_dbus_method_invocation_return_value (invocation, result); +} + +static void +g_action_group_exporter_free (gpointer user_data) +{ + GActionGroupExporter *exporter = user_data; + + g_signal_handlers_disconnect_by_func (exporter->action_group, + g_action_group_exporter_action_added, exporter); + g_signal_handlers_disconnect_by_func (exporter->action_group, + g_action_group_exporter_action_enabled_changed, exporter); + g_signal_handlers_disconnect_by_func (exporter->action_group, + g_action_group_exporter_action_state_changed, exporter); + g_signal_handlers_disconnect_by_func (exporter->action_group, + g_action_group_exporter_action_removed, exporter); + + g_hash_table_unref (exporter->pending_changes); + if (exporter->pending_source) + g_source_destroy (exporter->pending_source); + + g_main_context_unref (exporter->context); + g_object_unref (exporter->connection); + g_object_unref (exporter->action_group); + g_free (exporter->object_path); + + g_slice_free (GActionGroupExporter, exporter); +} + +/** + * g_dbus_connection_export_action_group: + * @connection: a #GDBusConnection + * @object_path: a D-Bus object path + * @action_group: a #GActionGroup + * @error: a pointer to a %NULL #GError, or %NULL + * + * Exports @action_group on @connection at @object_path. + * + * The implemented D-Bus API should be considered private. It is + * subject to change in the future. + * + * A given object path can only have one action group exported on it. + * If this constraint is violated, the export will fail and 0 will be + * returned (with @error set accordingly). + * + * You can unexport the action group using + * g_dbus_connection_unexport_action_group() with the return value of + * this function. + * + * The thread default main context is taken at the time of this call. + * All incoming action activations and state change requests are + * reported from this context. Any changes on the action group that + * cause it to emit signals must also come from this same context. + * Since incoming action activations and state change requests are + * rather likely to cause changes on the action group, this effectively + * limits a given action group to being exported from only one main + * context. + * + * Returns: the ID of the export (never zero), or 0 in case of failure + * + * Since: 2.32 + **/ +guint +g_dbus_connection_export_action_group (GDBusConnection *connection, + const gchar *object_path, + GActionGroup *action_group, + GError **error) +{ + const GDBusInterfaceVTable vtable = { + org_gtk_Actions_method_call, NULL, NULL, { 0 } + }; + GActionGroupExporter *exporter; + guint id; + + if G_UNLIKELY (org_gtk_Actions == NULL) + { + GError *error = NULL; + GDBusNodeInfo *info; + + info = g_dbus_node_info_new_for_xml (org_gtk_Actions_xml, &error); + if G_UNLIKELY (info == NULL) + g_error ("%s", error->message); + org_gtk_Actions = g_dbus_node_info_lookup_interface (info, "org.gtk.Actions"); + g_assert (org_gtk_Actions != NULL); + g_dbus_interface_info_ref (org_gtk_Actions); + g_dbus_node_info_unref (info); + } + + exporter = g_slice_new (GActionGroupExporter); + id = g_dbus_connection_register_object (connection, object_path, org_gtk_Actions, &vtable, + exporter, g_action_group_exporter_free, error); + + if (id == 0) + { + g_slice_free (GActionGroupExporter, exporter); + return 0; + } + + exporter->context = g_main_context_ref_thread_default (); + exporter->pending_changes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + exporter->pending_source = NULL; + exporter->action_group = g_object_ref (action_group); + exporter->connection = g_object_ref (connection); + exporter->object_path = g_strdup (object_path); + + g_signal_connect (action_group, "action-added", + G_CALLBACK (g_action_group_exporter_action_added), exporter); + g_signal_connect (action_group, "action-removed", + G_CALLBACK (g_action_group_exporter_action_removed), exporter); + g_signal_connect (action_group, "action-state-changed", + G_CALLBACK (g_action_group_exporter_action_state_changed), exporter); + g_signal_connect (action_group, "action-enabled-changed", + G_CALLBACK (g_action_group_exporter_action_enabled_changed), exporter); + + return id; +} + +/** + * g_dbus_connection_unexport_action_group: + * @connection: a #GDBusConnection + * @export_id: the ID from g_dbus_connection_export_action_group() + * + * Reverses the effect of a previous call to + * g_dbus_connection_export_action_group(). + * + * It is an error to call this function with an ID that wasn't returned + * from g_dbus_connection_export_action_group() or to call it with the + * same ID more than once. + * + * Since: 2.32 + **/ +void +g_dbus_connection_unexport_action_group (GDBusConnection *connection, + guint export_id) +{ + g_dbus_connection_unregister_object (connection, export_id); +} diff --git a/gio/gactiongroupexporter.h b/gio/gactiongroupexporter.h new file mode 100644 index 0000000..ba28c89 --- /dev/null +++ b/gio/gactiongroupexporter.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + + +#ifndef __G_ACTION_GROUP_EXPORTER_H__ +#define __G_ACTION_GROUP_EXPORTER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_2_32 +guint g_dbus_connection_export_action_group (GDBusConnection *connection, + const gchar *object_path, + GActionGroup *action_group, + GError **error); + +GLIB_AVAILABLE_IN_2_32 +void g_dbus_connection_unexport_action_group (GDBusConnection *connection, + guint export_id); + +G_END_DECLS + +#endif /* __G_ACTION_GROUP_EXPORTER_H__ */ diff --git a/gio/gactionmap.c b/gio/gactionmap.c new file mode 100644 index 0000000..077e3cf --- /dev/null +++ b/gio/gactionmap.c @@ -0,0 +1,285 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gsimpleaction.h" +#include "gactionmap.h" +#include "gaction.h" + +/** + * SECTION:gactionmap + * @title: GActionMap + * @include: gio/gio.h + * @short_description: Interface for action containers + * + * The GActionMap interface is implemented by #GActionGroup + * implementations that operate by containing a number of + * named #GAction instances, such as #GSimpleActionGroup. + * + * One useful application of this interface is to map the + * names of actions from various action groups to unique, + * prefixed names (e.g. by prepending "app." or "win."). + * This is the motivation for the 'Map' part of the interface + * name. + * + * Since: 2.32 + **/ + +/** + * GActionMap: + * + * #GActionMap is an opaque data structure and can only be accessed + * using the following functions. + **/ + +/** + * GActionMapInterface: + * @lookup_action: the virtual function pointer for g_action_map_lookup_action() + * @add_action: the virtual function pointer for g_action_map_add_action() + * @remove_action: the virtual function pointer for g_action_map_remove_action() + * + * The virtual function table for #GActionMap. + * + * Since: 2.32 + **/ + +G_DEFINE_INTERFACE (GActionMap, g_action_map, G_TYPE_OBJECT) + +static void +g_action_map_default_init (GActionMapInterface *iface) +{ +} + +/** + * g_action_map_lookup_action: + * @action_map: a #GActionMap + * @action_name: the name of an action + * + * Looks up the action with the name @action_name in @action_map. + * + * If no such action exists, returns %NULL. + * + * Returns: (nullable) (transfer none): a #GAction, or %NULL + * + * Since: 2.32 + */ +GAction * +g_action_map_lookup_action (GActionMap *action_map, + const gchar *action_name) +{ + return G_ACTION_MAP_GET_IFACE (action_map) + ->lookup_action (action_map, action_name); +} + +/** + * g_action_map_add_action: + * @action_map: a #GActionMap + * @action: a #GAction + * + * Adds an action to the @action_map. + * + * If the action map already contains an action with the same name + * as @action then the old action is dropped from the action map. + * + * The action map takes its own reference on @action. + * + * Since: 2.32 + */ +void +g_action_map_add_action (GActionMap *action_map, + GAction *action) +{ + G_ACTION_MAP_GET_IFACE (action_map)->add_action (action_map, action); +} + +/** + * g_action_map_remove_action: + * @action_map: a #GActionMap + * @action_name: the name of the action + * + * Removes the named action from the action map. + * + * If no action of this name is in the map then nothing happens. + * + * Since: 2.32 + */ +void +g_action_map_remove_action (GActionMap *action_map, + const gchar *action_name) +{ + G_ACTION_MAP_GET_IFACE (action_map)->remove_action (action_map, action_name); +} + +/** + * GActionEntry: + * @name: the name of the action + * @activate: the callback to connect to the "activate" signal of the + * action. Since GLib 2.40, this can be %NULL for stateful + * actions, in which case the default handler is used. For + * boolean-stated actions with no parameter, this is a + * toggle. For other state types (and parameter type equal + * to the state type) this will be a function that + * just calls @change_state (which you should provide). + * @parameter_type: the type of the parameter that must be passed to the + * activate function for this action, given as a single + * GVariant type string (or %NULL for no parameter) + * @state: the initial state for this action, given in + * [GVariant text format][gvariant-text]. The state is parsed + * with no extra type information, so type tags must be added to + * the string if they are necessary. Stateless actions should + * give %NULL here. + * @change_state: the callback to connect to the "change-state" signal + * of the action. All stateful actions should provide a + * handler here; stateless actions should not. + * + * This struct defines a single action. It is for use with + * g_action_map_add_action_entries(). + * + * The order of the items in the structure are intended to reflect + * frequency of use. It is permissible to use an incomplete initialiser + * in order to leave some of the later values as %NULL. All values + * after @name are optional. Additional optional fields may be added in + * the future. + * + * See g_action_map_add_action_entries() for an example. + **/ + +/** + * g_action_map_add_action_entries: + * @action_map: a #GActionMap + * @entries: (array length=n_entries) (element-type GActionEntry): a pointer to + * the first item in an array of #GActionEntry structs + * @n_entries: the length of @entries, or -1 if @entries is %NULL-terminated + * @user_data: the user data for signal connections + * + * A convenience function for creating multiple #GSimpleAction instances + * and adding them to a #GActionMap. + * + * Each action is constructed as per one #GActionEntry. + * + * |[ + * static void + * activate_quit (GSimpleAction *simple, + * GVariant *parameter, + * gpointer user_data) + * { + * exit (0); + * } + * + * static void + * activate_print_string (GSimpleAction *simple, + * GVariant *parameter, + * gpointer user_data) + * { + * g_print ("%s\n", g_variant_get_string (parameter, NULL)); + * } + * + * static GActionGroup * + * create_action_group (void) + * { + * const GActionEntry entries[] = { + * { "quit", activate_quit }, + * { "print-string", activate_print_string, "s" } + * }; + * GSimpleActionGroup *group; + * + * group = g_simple_action_group_new (); + * g_action_map_add_action_entries (G_ACTION_MAP (group), entries, G_N_ELEMENTS (entries), NULL); + * + * return G_ACTION_GROUP (group); + * } + * ]| + * + * Since: 2.32 + */ +void +g_action_map_add_action_entries (GActionMap *action_map, + const GActionEntry *entries, + gint n_entries, + gpointer user_data) +{ + gint i; + + g_return_if_fail (G_IS_ACTION_MAP (action_map)); + g_return_if_fail (entries != NULL || n_entries == 0); + + for (i = 0; n_entries == -1 ? entries[i].name != NULL : i < n_entries; i++) + { + const GActionEntry *entry = &entries[i]; + const GVariantType *parameter_type; + GSimpleAction *action; + + if (entry->parameter_type) + { + if (!g_variant_type_string_is_valid (entry->parameter_type)) + { + g_critical ("g_action_map_add_entries: the type " + "string '%s' given as the parameter type for " + "action '%s' is not a valid GVariant type " + "string. This action will not be added.", + entry->parameter_type, entry->name); + return; + } + + parameter_type = G_VARIANT_TYPE (entry->parameter_type); + } + else + parameter_type = NULL; + + if (entry->state) + { + GError *error = NULL; + GVariant *state; + + state = g_variant_parse (NULL, entry->state, NULL, NULL, &error); + if (state == NULL) + { + g_critical ("g_action_map_add_entries: GVariant could " + "not parse the state value given for action '%s' " + "('%s'): %s. This action will not be added.", + entry->name, entry->state, error->message); + g_error_free (error); + continue; + } + + action = g_simple_action_new_stateful (entry->name, + parameter_type, + state); + + g_variant_unref (state); + } + else + { + action = g_simple_action_new (entry->name, + parameter_type); + } + + if (entry->activate != NULL) + g_signal_connect (action, "activate", + G_CALLBACK (entry->activate), user_data); + + if (entry->change_state != NULL) + g_signal_connect (action, "change-state", + G_CALLBACK (entry->change_state), user_data); + + g_action_map_add_action (action_map, G_ACTION (action)); + g_object_unref (action); + } +} diff --git a/gio/gactionmap.h b/gio/gactionmap.h new file mode 100644 index 0000000..2a22a27 --- /dev/null +++ b/gio/gactionmap.h @@ -0,0 +1,95 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_ACTION_MAP_H__ +#define __G_ACTION_MAP_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + + +#define G_TYPE_ACTION_MAP (g_action_map_get_type ()) +#define G_ACTION_MAP(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_ACTION_MAP, GActionMap)) +#define G_IS_ACTION_MAP(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_ACTION_MAP)) +#define G_ACTION_MAP_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \ + G_TYPE_ACTION_MAP, GActionMapInterface)) + +typedef struct _GActionMapInterface GActionMapInterface; +typedef struct _GActionEntry GActionEntry; + +struct _GActionMapInterface +{ + GTypeInterface g_iface; + + GAction * (* lookup_action) (GActionMap *action_map, + const gchar *action_name); + void (* add_action) (GActionMap *action_map, + GAction *action); + void (* remove_action) (GActionMap *action_map, + const gchar *action_name); +}; + +struct _GActionEntry +{ + const gchar *name; + + void (* activate) (GSimpleAction *action, + GVariant *parameter, + gpointer user_data); + + const gchar *parameter_type; + + const gchar *state; + + void (* change_state) (GSimpleAction *action, + GVariant *value, + gpointer user_data); + + /*< private >*/ + gsize padding[3]; +}; + +GLIB_AVAILABLE_IN_2_32 +GType g_action_map_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +GAction * g_action_map_lookup_action (GActionMap *action_map, + const gchar *action_name); +GLIB_AVAILABLE_IN_2_32 +void g_action_map_add_action (GActionMap *action_map, + GAction *action); +GLIB_AVAILABLE_IN_2_32 +void g_action_map_remove_action (GActionMap *action_map, + const gchar *action_name); +GLIB_AVAILABLE_IN_2_32 +void g_action_map_add_action_entries (GActionMap *action_map, + const GActionEntry *entries, + gint n_entries, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_ACTION_MAP_H__ */ diff --git a/gio/gappinfo.c b/gio/gappinfo.c new file mode 100644 index 0000000..3f03328 --- /dev/null +++ b/gio/gappinfo.c @@ -0,0 +1,1520 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gappinfo.h" +#include "gappinfoprivate.h" +#include "gcontextspecificgroup.h" +#include "gtask.h" +#include "gcancellable.h" + +#include "glibintl.h" +#include "gmarshal-internal.h" +#include +#include + +#ifdef G_OS_UNIX +#include "gdbusconnection.h" +#include "gdbusmessage.h" +#include "gportalsupport.h" +#include "gunixfdlist.h" +#include "gopenuriportal.h" +#include +#include +#include +#endif + +/** + * SECTION:gappinfo + * @short_description: Application information and launch contexts + * @include: gio/gio.h + * @see_also: #GAppInfoMonitor + * + * #GAppInfo and #GAppLaunchContext are used for describing and launching + * applications installed on the system. + * + * As of GLib 2.20, URIs will always be converted to POSIX paths + * (using g_file_get_path()) when using g_app_info_launch() even if + * the application requested an URI and not a POSIX path. For example + * for a desktop-file based application with Exec key `totem + * %U` and a single URI, `sftp://foo/file.avi`, then + * `/home/user/.gvfs/sftp on foo/file.avi` will be passed. This will + * only work if a set of suitable GIO extensions (such as gvfs 2.26 + * compiled with FUSE support), is available and operational; if this + * is not the case, the URI will be passed unmodified to the application. + * Some URIs, such as `mailto:`, of course cannot be mapped to a POSIX + * path (in gvfs there's no FUSE mount for it); such URIs will be + * passed unmodified to the application. + * + * Specifically for gvfs 2.26 and later, the POSIX URI will be mapped + * back to the GIO URI in the #GFile constructors (since gvfs + * implements the #GVfs extension point). As such, if the application + * needs to examine the URI, it needs to use g_file_get_uri() or + * similar on #GFile. In other words, an application cannot assume + * that the URI passed to e.g. g_file_new_for_commandline_arg() is + * equal to the result of g_file_get_uri(). The following snippet + * illustrates this: + * + * |[ + * GFile *f; + * char *uri; + * + * file = g_file_new_for_commandline_arg (uri_from_commandline); + * + * uri = g_file_get_uri (file); + * strcmp (uri, uri_from_commandline) == 0; + * g_free (uri); + * + * if (g_file_has_uri_scheme (file, "cdda")) + * { + * // do something special with uri + * } + * g_object_unref (file); + * ]| + * + * This code will work when both `cdda://sr0/Track 1.wav` and + * `/home/user/.gvfs/cdda on sr0/Track 1.wav` is passed to the + * application. It should be noted that it's generally not safe + * for applications to rely on the format of a particular URIs. + * Different launcher applications (e.g. file managers) may have + * different ideas of what a given URI means. + */ + +struct _GAppLaunchContextPrivate { + char **envp; +}; + +typedef GAppInfoIface GAppInfoInterface; +G_DEFINE_INTERFACE (GAppInfo, g_app_info, G_TYPE_OBJECT) + +static void +g_app_info_default_init (GAppInfoInterface *iface) +{ +} + + +/** + * g_app_info_dup: + * @appinfo: a #GAppInfo. + * + * Creates a duplicate of a #GAppInfo. + * + * Returns: (transfer full): a duplicate of @appinfo. + **/ +GAppInfo * +g_app_info_dup (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->dup) (appinfo); +} + +/** + * g_app_info_equal: + * @appinfo1: the first #GAppInfo. + * @appinfo2: the second #GAppInfo. + * + * Checks if two #GAppInfos are equal. + * + * Note that the check *may not* compare each individual + * field, and only does an identity check. In case detecting changes in the + * contents is needed, program code must additionally compare relevant fields. + * + * Returns: %TRUE if @appinfo1 is equal to @appinfo2. %FALSE otherwise. + **/ +gboolean +g_app_info_equal (GAppInfo *appinfo1, + GAppInfo *appinfo2) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo1), FALSE); + g_return_val_if_fail (G_IS_APP_INFO (appinfo2), FALSE); + + if (G_TYPE_FROM_INSTANCE (appinfo1) != G_TYPE_FROM_INSTANCE (appinfo2)) + return FALSE; + + iface = G_APP_INFO_GET_IFACE (appinfo1); + + return (* iface->equal) (appinfo1, appinfo2); +} + +/** + * g_app_info_get_id: + * @appinfo: a #GAppInfo. + * + * Gets the ID of an application. An id is a string that + * identifies the application. The exact format of the id is + * platform dependent. For instance, on Unix this is the + * desktop file id from the xdg menu specification. + * + * Note that the returned ID may be %NULL, depending on how + * the @appinfo has been constructed. + * + * Returns: (nullable): a string containing the application's ID. + **/ +const char * +g_app_info_get_id (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->get_id) (appinfo); +} + +/** + * g_app_info_get_name: + * @appinfo: a #GAppInfo. + * + * Gets the installed name of the application. + * + * Returns: the name of the application for @appinfo. + **/ +const char * +g_app_info_get_name (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->get_name) (appinfo); +} + +/** + * g_app_info_get_display_name: + * @appinfo: a #GAppInfo. + * + * Gets the display name of the application. The display name is often more + * descriptive to the user than the name itself. + * + * Returns: the display name of the application for @appinfo, or the name if + * no display name is available. + * + * Since: 2.24 + **/ +const char * +g_app_info_get_display_name (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->get_display_name == NULL) + return (* iface->get_name) (appinfo); + + return (* iface->get_display_name) (appinfo); +} + +/** + * g_app_info_get_description: + * @appinfo: a #GAppInfo. + * + * Gets a human-readable description of an installed application. + * + * Returns: (nullable): a string containing a description of the + * application @appinfo, or %NULL if none. + **/ +const char * +g_app_info_get_description (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->get_description) (appinfo); +} + +/** + * g_app_info_get_executable: (virtual get_executable) + * @appinfo: a #GAppInfo + * + * Gets the executable's name for the installed application. + * + * Returns: (type filename): a string containing the @appinfo's application + * binaries name + **/ +const char * +g_app_info_get_executable (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->get_executable) (appinfo); +} + + +/** + * g_app_info_get_commandline: (virtual get_commandline) + * @appinfo: a #GAppInfo + * + * Gets the commandline with which the application will be + * started. + * + * Returns: (nullable) (type filename): a string containing the @appinfo's commandline, + * or %NULL if this information is not available + * + * Since: 2.20 + **/ +const char * +g_app_info_get_commandline (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->get_commandline) + return (* iface->get_commandline) (appinfo); + + return NULL; +} + +/** + * g_app_info_set_as_default_for_type: + * @appinfo: a #GAppInfo. + * @content_type: the content type. + * @error: a #GError. + * + * Sets the application as the default handler for a given type. + * + * Returns: %TRUE on success, %FALSE on error. + **/ +gboolean +g_app_info_set_as_default_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + g_return_val_if_fail (content_type != NULL, FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->set_as_default_for_type) + return (* iface->set_as_default_for_type) (appinfo, content_type, error); + + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Setting default applications not supported yet")); + return FALSE; +} + +/** + * g_app_info_set_as_last_used_for_type: + * @appinfo: a #GAppInfo. + * @content_type: the content type. + * @error: a #GError. + * + * Sets the application as the last used application for a given type. + * This will make the application appear as first in the list returned + * by g_app_info_get_recommended_for_type(), regardless of the default + * application for that content type. + * + * Returns: %TRUE on success, %FALSE on error. + **/ +gboolean +g_app_info_set_as_last_used_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + g_return_val_if_fail (content_type != NULL, FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->set_as_last_used_for_type) + return (* iface->set_as_last_used_for_type) (appinfo, content_type, error); + + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Setting application as last used for type not supported yet")); + return FALSE; +} + +/** + * g_app_info_set_as_default_for_extension: + * @appinfo: a #GAppInfo. + * @extension: (type filename): a string containing the file extension + * (without the dot). + * @error: a #GError. + * + * Sets the application as the default handler for the given file extension. + * + * Returns: %TRUE on success, %FALSE on error. + **/ +gboolean +g_app_info_set_as_default_for_extension (GAppInfo *appinfo, + const char *extension, + GError **error) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + g_return_val_if_fail (extension != NULL, FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->set_as_default_for_extension) + return (* iface->set_as_default_for_extension) (appinfo, extension, error); + + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "g_app_info_set_as_default_for_extension not supported yet"); + return FALSE; +} + + +/** + * g_app_info_add_supports_type: + * @appinfo: a #GAppInfo. + * @content_type: a string. + * @error: a #GError. + * + * Adds a content type to the application information to indicate the + * application is capable of opening files with the given content type. + * + * Returns: %TRUE on success, %FALSE on error. + **/ +gboolean +g_app_info_add_supports_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + g_return_val_if_fail (content_type != NULL, FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->add_supports_type) + return (* iface->add_supports_type) (appinfo, content_type, error); + + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "g_app_info_add_supports_type not supported yet"); + + return FALSE; +} + + +/** + * g_app_info_can_remove_supports_type: + * @appinfo: a #GAppInfo. + * + * Checks if a supported content type can be removed from an application. + * + * Returns: %TRUE if it is possible to remove supported + * content types from a given @appinfo, %FALSE if not. + **/ +gboolean +g_app_info_can_remove_supports_type (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->can_remove_supports_type) + return (* iface->can_remove_supports_type) (appinfo); + + return FALSE; +} + + +/** + * g_app_info_remove_supports_type: + * @appinfo: a #GAppInfo. + * @content_type: a string. + * @error: a #GError. + * + * Removes a supported type from an application, if possible. + * + * Returns: %TRUE on success, %FALSE on error. + **/ +gboolean +g_app_info_remove_supports_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + g_return_val_if_fail (content_type != NULL, FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->remove_supports_type) + return (* iface->remove_supports_type) (appinfo, content_type, error); + + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "g_app_info_remove_supports_type not supported yet"); + + return FALSE; +} + +/** + * g_app_info_get_supported_types: + * @appinfo: a #GAppInfo that can handle files + * + * Retrieves the list of content types that @app_info claims to support. + * If this information is not provided by the environment, this function + * will return %NULL. + * This function does not take in consideration associations added with + * g_app_info_add_supports_type(), but only those exported directly by + * the application. + * + * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): + * a list of content types. + * + * Since: 2.34 + */ +const char ** +g_app_info_get_supported_types (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->get_supported_types) + return iface->get_supported_types (appinfo); + else + return NULL; +} + + +/** + * g_app_info_get_icon: + * @appinfo: a #GAppInfo. + * + * Gets the icon for the application. + * + * Returns: (nullable) (transfer none): the default #GIcon for @appinfo or %NULL + * if there is no default icon. + **/ +GIcon * +g_app_info_get_icon (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->get_icon) (appinfo); +} + + +/** + * g_app_info_launch: + * @appinfo: a #GAppInfo + * @files: (nullable) (element-type GFile): a #GList of #GFile objects + * @context: (nullable): a #GAppLaunchContext or %NULL + * @error: a #GError + * + * Launches the application. Passes @files to the launched application + * as arguments, using the optional @context to get information + * about the details of the launcher (like what screen it is on). + * On error, @error will be set accordingly. + * + * To launch the application without arguments pass a %NULL @files list. + * + * Note that even if the launch is successful the application launched + * can fail to start if it runs into problems during startup. There is + * no way to detect this. + * + * Some URIs can be changed when passed through a GFile (for instance + * unsupported URIs with strange formats like mailto:), so if you have + * a textual URI you want to pass in as argument, consider using + * g_app_info_launch_uris() instead. + * + * The launched application inherits the environment of the launching + * process, but it can be modified with g_app_launch_context_setenv() + * and g_app_launch_context_unsetenv(). + * + * On UNIX, this function sets the `GIO_LAUNCHED_DESKTOP_FILE` + * environment variable with the path of the launched desktop file and + * `GIO_LAUNCHED_DESKTOP_FILE_PID` to the process id of the launched + * process. This can be used to ignore `GIO_LAUNCHED_DESKTOP_FILE`, + * should it be inherited by further processes. The `DISPLAY` and + * `DESKTOP_STARTUP_ID` environment variables are also set, based + * on information provided in @context. + * + * Returns: %TRUE on successful launch, %FALSE otherwise. + **/ +gboolean +g_app_info_launch (GAppInfo *appinfo, + GList *files, + GAppLaunchContext *launch_context, + GError **error) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->launch) (appinfo, files, launch_context, error); +} + + +/** + * g_app_info_supports_uris: + * @appinfo: a #GAppInfo. + * + * Checks if the application supports reading files and directories from URIs. + * + * Returns: %TRUE if the @appinfo supports URIs. + **/ +gboolean +g_app_info_supports_uris (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->supports_uris) (appinfo); +} + + +/** + * g_app_info_supports_files: + * @appinfo: a #GAppInfo. + * + * Checks if the application accepts files as arguments. + * + * Returns: %TRUE if the @appinfo supports files. + **/ +gboolean +g_app_info_supports_files (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->supports_files) (appinfo); +} + + +/** + * g_app_info_launch_uris: + * @appinfo: a #GAppInfo + * @uris: (nullable) (element-type utf8): a #GList containing URIs to launch. + * @context: (nullable): a #GAppLaunchContext or %NULL + * @error: a #GError + * + * Launches the application. This passes the @uris to the launched application + * as arguments, using the optional @context to get information + * about the details of the launcher (like what screen it is on). + * On error, @error will be set accordingly. + * + * To launch the application without arguments pass a %NULL @uris list. + * + * Note that even if the launch is successful the application launched + * can fail to start if it runs into problems during startup. There is + * no way to detect this. + * + * Returns: %TRUE on successful launch, %FALSE otherwise. + **/ +gboolean +g_app_info_launch_uris (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GError **error) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->launch_uris) (appinfo, uris, launch_context, error); +} + +/** + * g_app_info_launch_uris_async: + * @appinfo: a #GAppInfo + * @uris: (nullable) (element-type utf8): a #GList containing URIs to launch. + * @context: (nullable): a #GAppLaunchContext or %NULL + * @cancellable: (nullable): a #GCancellable + * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done + * @user_data: (nullable): data to pass to @callback + * + * Async version of g_app_info_launch_uris(). + * + * The @callback is invoked immediately after the application launch, but it + * waits for activation in case of D-Bus–activated applications and also provides + * extended error information for sandboxed applications, see notes for + * g_app_info_launch_default_for_uri_async(). + * + * Since: 2.60 + **/ +void +g_app_info_launch_uris_async (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GAppInfoIface *iface; + + g_return_if_fail (G_IS_APP_INFO (appinfo)); + g_return_if_fail (context == NULL || G_IS_APP_LAUNCH_CONTEXT (context)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + iface = G_APP_INFO_GET_IFACE (appinfo); + if (iface->launch_uris_async == NULL) + { + GTask *task; + + task = g_task_new (appinfo, cancellable, callback, user_data); + g_task_set_source_tag (task, g_app_info_launch_uris_async); + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Operation not supported for the current backend."); + g_object_unref (task); + + return; + } + + (* iface->launch_uris_async) (appinfo, uris, context, cancellable, callback, user_data); +} + +/** + * g_app_info_launch_uris_finish: + * @appinfo: a #GAppInfo + * @result: a #GAsyncResult + * @error: (nullable): a #GError + * + * Finishes a g_app_info_launch_uris_async() operation. + * + * Returns: %TRUE on successful launch, %FALSE otherwise. + * + * Since: 2.60 + */ +gboolean +g_app_info_launch_uris_finish (GAppInfo *appinfo, + GAsyncResult *result, + GError **error) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + if (iface->launch_uris_finish == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Operation not supported for the current backend."); + return FALSE; + } + + return (* iface->launch_uris_finish) (appinfo, result, error); +} + +/** + * g_app_info_should_show: + * @appinfo: a #GAppInfo. + * + * Checks if the application info should be shown in menus that + * list available applications. + * + * Returns: %TRUE if the @appinfo should be shown, %FALSE otherwise. + **/ +gboolean +g_app_info_should_show (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + return (* iface->should_show) (appinfo); +} + +/** + * g_app_info_launch_default_for_uri: + * @uri: the uri to show + * @context: (nullable): an optional #GAppLaunchContext + * @error: (nullable): return location for an error, or %NULL + * + * Utility function that launches the default application + * registered to handle the specified uri. Synchronous I/O + * is done on the uri to detect the type of the file if + * required. + * + * The D-Bus–activated applications don't have to be started if your application + * terminates too soon after this function. To prevent this, use + * g_app_info_launch_default_for_uri_async() instead. + * + * Returns: %TRUE on success, %FALSE on error. + **/ +gboolean +g_app_info_launch_default_for_uri (const char *uri, + GAppLaunchContext *launch_context, + GError **error) +{ + char *uri_scheme; + GAppInfo *app_info = NULL; + gboolean res = FALSE; + + /* g_file_query_default_handler() calls + * g_app_info_get_default_for_uri_scheme() too, but we have to do it + * here anyway in case GFile can't parse @uri correctly. + */ + uri_scheme = g_uri_parse_scheme (uri); + if (uri_scheme && uri_scheme[0] != '\0') + app_info = g_app_info_get_default_for_uri_scheme (uri_scheme); + g_free (uri_scheme); + + if (!app_info) + { + GFile *file; + + file = g_file_new_for_uri (uri); + app_info = g_file_query_default_handler (file, NULL, error); + g_object_unref (file); + } + + if (app_info) + { + GList l; + + l.data = (char *)uri; + l.next = l.prev = NULL; + res = g_app_info_launch_uris (app_info, &l, launch_context, error); + g_object_unref (app_info); + } + +#ifdef G_OS_UNIX + if (!res && glib_should_use_portal ()) + { + const char *parent_window = NULL; + + /* Reset any error previously set by launch_default_for_uri */ + g_clear_error (error); + + if (launch_context && launch_context->priv->envp) + parent_window = g_environ_getenv (launch_context->priv->envp, "PARENT_WINDOW_ID"); + + return g_openuri_portal_open_uri (uri, parent_window, error); + } +#endif + + return res; +} + +typedef struct +{ + gchar *uri; + GAppLaunchContext *context; +} LaunchDefaultForUriData; + +static void +launch_default_for_uri_data_free (LaunchDefaultForUriData *data) +{ + g_free (data->uri); + g_clear_object (&data->context); + g_free (data); +} + +#ifdef G_OS_UNIX +static void +launch_default_for_uri_portal_open_uri_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + GError *error = NULL; + + if (g_openuri_portal_open_uri_finish (result, &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); +} +#endif + +static void +launch_default_for_uri_portal_open_uri (GTask *task, GError *error) +{ +#ifdef G_OS_UNIX + LaunchDefaultForUriData *data = g_task_get_task_data (task); + GCancellable *cancellable = g_task_get_cancellable (task); + + if (glib_should_use_portal ()) + { + const char *parent_window = NULL; + + /* Reset any error previously set by launch_default_for_uri */ + g_error_free (error); + + if (data->context && data->context->priv->envp) + parent_window = g_environ_getenv (data->context->priv->envp, + "PARENT_WINDOW_ID"); + + g_openuri_portal_open_uri_async (data->uri, + parent_window, + cancellable, + launch_default_for_uri_portal_open_uri_cb, + g_steal_pointer (&task)); + return; + } +#endif + + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); +} + +static void +launch_default_for_uri_launch_uris_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GAppInfo *app_info = G_APP_INFO (object); + GTask *task = G_TASK (user_data); + GError *error = NULL; + + if (g_app_info_launch_uris_finish (app_info, result, &error)) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + } + else + launch_default_for_uri_portal_open_uri (g_steal_pointer (&task), g_steal_pointer (&error)); +} + +static void +launch_default_for_uri_launch_uris (GTask *task, + GAppInfo *app_info) +{ + GCancellable *cancellable = g_task_get_cancellable (task); + GList l; + LaunchDefaultForUriData *data = g_task_get_task_data (task); + + l.data = (char *)data->uri; + l.next = l.prev = NULL; + g_app_info_launch_uris_async (app_info, + &l, + data->context, + cancellable, + launch_default_for_uri_launch_uris_cb, + g_steal_pointer (&task)); + g_object_unref (app_info); +} + +static void +launch_default_for_uri_default_handler_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GFile *file = G_FILE (object); + GTask *task = G_TASK (user_data); + GAppInfo *app_info = NULL; + GError *error = NULL; + + app_info = g_file_query_default_handler_finish (file, result, &error); + if (app_info) + launch_default_for_uri_launch_uris (g_steal_pointer (&task), g_steal_pointer (&app_info)); + else + launch_default_for_uri_portal_open_uri (g_steal_pointer (&task), g_steal_pointer (&error)); +} + +/** + * g_app_info_launch_default_for_uri_async: + * @uri: the uri to show + * @context: (nullable): an optional #GAppLaunchContext + * @cancellable: (nullable): a #GCancellable + * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done + * @user_data: (nullable): data to pass to @callback + * + * Async version of g_app_info_launch_default_for_uri(). + * + * This version is useful if you are interested in receiving + * error information in the case where the application is + * sandboxed and the portal may present an application chooser + * dialog to the user. + * + * This is also useful if you want to be sure that the D-Bus–activated + * applications are really started before termination and if you are interested + * in receiving error information from their activation. + * + * Since: 2.50 + */ +void +g_app_info_launch_default_for_uri_async (const char *uri, + GAppLaunchContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + char *uri_scheme; + GAppInfo *app_info = NULL; + LaunchDefaultForUriData *data; + + g_return_if_fail (uri != NULL); + + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (task, g_app_info_launch_default_for_uri_async); + + data = g_new (LaunchDefaultForUriData, 1); + data->uri = g_strdup (uri); + data->context = (context != NULL) ? g_object_ref (context) : NULL; + g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) launch_default_for_uri_data_free); + + /* g_file_query_default_handler_async() calls + * g_app_info_get_default_for_uri_scheme() too, but we have to do it + * here anyway in case GFile can't parse @uri correctly. + */ + uri_scheme = g_uri_parse_scheme (uri); + if (uri_scheme && uri_scheme[0] != '\0') + /* FIXME: The following still uses blocking calls. */ + app_info = g_app_info_get_default_for_uri_scheme (uri_scheme); + g_free (uri_scheme); + + if (!app_info) + { + GFile *file; + + file = g_file_new_for_uri (uri); + g_file_query_default_handler_async (file, + G_PRIORITY_DEFAULT, + cancellable, + launch_default_for_uri_default_handler_cb, + g_steal_pointer (&task)); + g_object_unref (file); + } + else + launch_default_for_uri_launch_uris (g_steal_pointer (&task), g_steal_pointer (&app_info)); +} + +/** + * g_app_info_launch_default_for_uri_finish: + * @result: a #GAsyncResult + * @error: (nullable): return location for an error, or %NULL + * + * Finishes an asynchronous launch-default-for-uri operation. + * + * Returns: %TRUE if the launch was successful, %FALSE if @error is set + * + * Since: 2.50 + */ +gboolean +g_app_info_launch_default_for_uri_finish (GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +/** + * g_app_info_can_delete: + * @appinfo: a #GAppInfo + * + * Obtains the information whether the #GAppInfo can be deleted. + * See g_app_info_delete(). + * + * Returns: %TRUE if @appinfo can be deleted + * + * Since: 2.20 + */ +gboolean +g_app_info_can_delete (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->can_delete) + return (* iface->can_delete) (appinfo); + + return FALSE; +} + + +/** + * g_app_info_delete: + * @appinfo: a #GAppInfo + * + * Tries to delete a #GAppInfo. + * + * On some platforms, there may be a difference between user-defined + * #GAppInfos which can be deleted, and system-wide ones which cannot. + * See g_app_info_can_delete(). + * + * Virtual: do_delete + * Returns: %TRUE if @appinfo has been deleted + * + * Since: 2.20 + */ +gboolean +g_app_info_delete (GAppInfo *appinfo) +{ + GAppInfoIface *iface; + + g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + + iface = G_APP_INFO_GET_IFACE (appinfo); + + if (iface->do_delete) + return (* iface->do_delete) (appinfo); + + return FALSE; +} + + +enum { + LAUNCH_FAILED, + LAUNCH_STARTED, + LAUNCHED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE_WITH_PRIVATE (GAppLaunchContext, g_app_launch_context, G_TYPE_OBJECT) + +/** + * g_app_launch_context_new: + * + * Creates a new application launch context. This is not normally used, + * instead you instantiate a subclass of this, such as #GdkAppLaunchContext. + * + * Returns: a #GAppLaunchContext. + **/ +GAppLaunchContext * +g_app_launch_context_new (void) +{ + return g_object_new (G_TYPE_APP_LAUNCH_CONTEXT, NULL); +} + +static void +g_app_launch_context_finalize (GObject *object) +{ + GAppLaunchContext *context = G_APP_LAUNCH_CONTEXT (object); + + g_strfreev (context->priv->envp); + + G_OBJECT_CLASS (g_app_launch_context_parent_class)->finalize (object); +} + +static void +g_app_launch_context_class_init (GAppLaunchContextClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = g_app_launch_context_finalize; + + /** + * GAppLaunchContext::launch-failed: + * @context: the object emitting the signal + * @startup_notify_id: the startup notification id for the failed launch + * + * The #GAppLaunchContext::launch-failed signal is emitted when a #GAppInfo launch + * fails. The startup notification id is provided, so that the launcher + * can cancel the startup notification. + * + * Since: 2.36 + */ + signals[LAUNCH_FAILED] = g_signal_new (I_("launch-failed"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GAppLaunchContextClass, launch_failed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_STRING); + + /** + * GAppLaunchContext::launch-started: + * @context: the object emitting the signal + * @info: the #GAppInfo that is about to be launched + * @platform_data: (nullable): additional platform-specific data for this launch + * + * The #GAppLaunchContext::launch-started signal is emitted when a #GAppInfo is + * about to be launched. If non-null the @platform_data is an + * GVariant dictionary mapping strings to variants (ie `a{sv}`), which + * contains additional, platform-specific data about this launch. On + * UNIX, at least the `startup-notification-id` keys will be + * present. + * + * The value of the `startup-notification-id` key (type `s`) is a startup + * notification ID corresponding to the format from the [startup-notification + * specification](https://specifications.freedesktop.org/startup-notification-spec/startup-notification-0.1.txt). + * It allows tracking the progress of the launchee through startup. + * + * It is guaranteed that this signal is followed by either a #GAppLaunchContext::launched or + * #GAppLaunchContext::launch-failed signal. + * + * Since: 2.72 + */ + signals[LAUNCH_STARTED] = g_signal_new (I_("launch-started"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GAppLaunchContextClass, launch_started), + NULL, NULL, + _g_cclosure_marshal_VOID__OBJECT_VARIANT, + G_TYPE_NONE, 2, + G_TYPE_APP_INFO, G_TYPE_VARIANT); + g_signal_set_va_marshaller (signals[LAUNCH_STARTED], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__OBJECT_VARIANTv); + + /** + * GAppLaunchContext::launched: + * @context: the object emitting the signal + * @info: the #GAppInfo that was just launched + * @platform_data: additional platform-specific data for this launch + * + * The #GAppLaunchContext::launched signal is emitted when a #GAppInfo is successfully + * launched. The @platform_data is an GVariant dictionary mapping + * strings to variants (ie `a{sv}`), which contains additional, + * platform-specific data about this launch. On UNIX, at least the + * `pid` and `startup-notification-id` keys will be present. + * + * Since 2.72 the `pid` may be 0 if the process id wasn't known (for + * example if the process was launched via D-Bus). The `pid` may not be + * set at all in subsequent releases. + * + * Since: 2.36 + */ + signals[LAUNCHED] = g_signal_new (I_("launched"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GAppLaunchContextClass, launched), + NULL, NULL, + _g_cclosure_marshal_VOID__OBJECT_VARIANT, + G_TYPE_NONE, 2, + G_TYPE_APP_INFO, G_TYPE_VARIANT); + g_signal_set_va_marshaller (signals[LAUNCHED], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__OBJECT_VARIANTv); +} + +static void +g_app_launch_context_init (GAppLaunchContext *context) +{ + context->priv = g_app_launch_context_get_instance_private (context); +} + +/** + * g_app_launch_context_setenv: + * @context: a #GAppLaunchContext + * @variable: (type filename): the environment variable to set + * @value: (type filename): the value for to set the variable to. + * + * Arranges for @variable to be set to @value in the child's + * environment when @context is used to launch an application. + * + * Since: 2.32 + */ +void +g_app_launch_context_setenv (GAppLaunchContext *context, + const char *variable, + const char *value) +{ + g_return_if_fail (G_IS_APP_LAUNCH_CONTEXT (context)); + g_return_if_fail (variable != NULL); + g_return_if_fail (value != NULL); + + if (!context->priv->envp) + context->priv->envp = g_get_environ (); + + context->priv->envp = + g_environ_setenv (context->priv->envp, variable, value, TRUE); +} + +/** + * g_app_launch_context_unsetenv: + * @context: a #GAppLaunchContext + * @variable: (type filename): the environment variable to remove + * + * Arranges for @variable to be unset in the child's environment + * when @context is used to launch an application. + * + * Since: 2.32 + */ +void +g_app_launch_context_unsetenv (GAppLaunchContext *context, + const char *variable) +{ + g_return_if_fail (G_IS_APP_LAUNCH_CONTEXT (context)); + g_return_if_fail (variable != NULL); + + if (!context->priv->envp) + context->priv->envp = g_get_environ (); + + context->priv->envp = + g_environ_unsetenv (context->priv->envp, variable); +} + +/** + * g_app_launch_context_get_environment: + * @context: a #GAppLaunchContext + * + * Gets the complete environment variable list to be passed to + * the child process when @context is used to launch an application. + * This is a %NULL-terminated array of strings, where each string has + * the form `KEY=VALUE`. + * + * Returns: (array zero-terminated=1) (element-type filename) (transfer full): + * the child's environment + * + * Since: 2.32 + */ +char ** +g_app_launch_context_get_environment (GAppLaunchContext *context) +{ + g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL); + + if (!context->priv->envp) + context->priv->envp = g_get_environ (); + + return g_strdupv (context->priv->envp); +} + +/** + * g_app_launch_context_get_display: + * @context: a #GAppLaunchContext + * @info: a #GAppInfo + * @files: (element-type GFile): a #GList of #GFile objects + * + * Gets the display string for the @context. This is used to ensure new + * applications are started on the same display as the launching + * application, by setting the `DISPLAY` environment variable. + * + * Returns: (nullable): a display string for the display. + */ +char * +g_app_launch_context_get_display (GAppLaunchContext *context, + GAppInfo *info, + GList *files) +{ + GAppLaunchContextClass *class; + + g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL); + g_return_val_if_fail (G_IS_APP_INFO (info), NULL); + + class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context); + + if (class->get_display == NULL) + return NULL; + + return class->get_display (context, info, files); +} + +/** + * g_app_launch_context_get_startup_notify_id: + * @context: a #GAppLaunchContext + * @info: a #GAppInfo + * @files: (element-type GFile): a #GList of of #GFile objects + * + * Initiates startup notification for the application and returns the + * `DESKTOP_STARTUP_ID` for the launched operation, if supported. + * + * Startup notification IDs are defined in the + * [FreeDesktop.Org Startup Notifications standard](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt). + * + * Returns: (nullable): a startup notification ID for the application, or %NULL if + * not supported. + **/ +char * +g_app_launch_context_get_startup_notify_id (GAppLaunchContext *context, + GAppInfo *info, + GList *files) +{ + GAppLaunchContextClass *class; + + g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL); + g_return_val_if_fail (G_IS_APP_INFO (info), NULL); + + class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context); + + if (class->get_startup_notify_id == NULL) + return NULL; + + return class->get_startup_notify_id (context, info, files); +} + + +/** + * g_app_launch_context_launch_failed: + * @context: a #GAppLaunchContext. + * @startup_notify_id: the startup notification id that was returned by g_app_launch_context_get_startup_notify_id(). + * + * Called when an application has failed to launch, so that it can cancel + * the application startup notification started in g_app_launch_context_get_startup_notify_id(). + * + **/ +void +g_app_launch_context_launch_failed (GAppLaunchContext *context, + const char *startup_notify_id) +{ + g_return_if_fail (G_IS_APP_LAUNCH_CONTEXT (context)); + g_return_if_fail (startup_notify_id != NULL); + + g_signal_emit (context, signals[LAUNCH_FAILED], 0, startup_notify_id); +} + + +/** + * SECTION:gappinfomonitor + * @short_description: Monitor application information for changes + * + * #GAppInfoMonitor is a very simple object used for monitoring the app + * info database for changes (ie: newly installed or removed + * applications). + * + * Call g_app_info_monitor_get() to get a #GAppInfoMonitor and connect + * to the "changed" signal. + * + * In the usual case, applications should try to make note of the change + * (doing things like invalidating caches) but not act on it. In + * particular, applications should avoid making calls to #GAppInfo APIs + * in response to the change signal, deferring these until the time that + * the data is actually required. The exception to this case is when + * application information is actually being displayed on the screen + * (eg: during a search or when the list of all applications is shown). + * The reason for this is that changes to the list of installed + * applications often come in groups (like during system updates) and + * rescanning the list on every change is pointless and expensive. + * + * Since: 2.40 + **/ + +/** + * GAppInfoMonitor: + * + * The only thing you can do with this is to get it via + * g_app_info_monitor_get() and connect to the "changed" signal. + * + * Since: 2.40 + **/ + +typedef struct _GAppInfoMonitorClass GAppInfoMonitorClass; + +struct _GAppInfoMonitor +{ + GObject parent_instance; + GMainContext *context; +}; + +struct _GAppInfoMonitorClass +{ + GObjectClass parent_class; +}; + +static GContextSpecificGroup g_app_info_monitor_group; +static guint g_app_info_monitor_changed_signal; + +G_DEFINE_TYPE (GAppInfoMonitor, g_app_info_monitor, G_TYPE_OBJECT) + +static void +g_app_info_monitor_finalize (GObject *object) +{ + GAppInfoMonitor *monitor = G_APP_INFO_MONITOR (object); + + g_context_specific_group_remove (&g_app_info_monitor_group, monitor->context, monitor, NULL); + + G_OBJECT_CLASS (g_app_info_monitor_parent_class)->finalize (object); +} + +static void +g_app_info_monitor_init (GAppInfoMonitor *monitor) +{ +} + +static void +g_app_info_monitor_class_init (GAppInfoMonitorClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + /** + * GAppInfoMonitor::changed: + * + * Signal emitted when the app info database for changes (ie: newly installed + * or removed applications). + **/ + g_app_info_monitor_changed_signal = g_signal_new (I_("changed"), G_TYPE_APP_INFO_MONITOR, G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + object_class->finalize = g_app_info_monitor_finalize; +} + +/** + * g_app_info_monitor_get: + * + * Gets the #GAppInfoMonitor for the current thread-default main + * context. + * + * The #GAppInfoMonitor will emit a "changed" signal in the + * thread-default main context whenever the list of installed + * applications (as reported by g_app_info_get_all()) may have changed. + * + * You must only call g_object_unref() on the return value from under + * the same main context as you created it. + * + * Returns: (transfer full): a reference to a #GAppInfoMonitor + * + * Since: 2.40 + **/ +GAppInfoMonitor * +g_app_info_monitor_get (void) +{ + return g_context_specific_group_get (&g_app_info_monitor_group, + G_TYPE_APP_INFO_MONITOR, + G_STRUCT_OFFSET (GAppInfoMonitor, context), + NULL); +} + +void +g_app_info_monitor_fire (void) +{ + g_context_specific_group_emit (&g_app_info_monitor_group, g_app_info_monitor_changed_signal); +} diff --git a/gio/gappinfo.h b/gio/gappinfo.h new file mode 100644 index 0000000..ad3068e --- /dev/null +++ b/gio/gappinfo.h @@ -0,0 +1,349 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_APP_INFO_H__ +#define __G_APP_INFO_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_APP_INFO (g_app_info_get_type ()) +#define G_APP_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_APP_INFO, GAppInfo)) +#define G_IS_APP_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_APP_INFO)) +#define G_APP_INFO_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_APP_INFO, GAppInfoIface)) + +#define G_TYPE_APP_LAUNCH_CONTEXT (g_app_launch_context_get_type ()) +#define G_APP_LAUNCH_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContext)) +#define G_APP_LAUNCH_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContextClass)) +#define G_IS_APP_LAUNCH_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_APP_LAUNCH_CONTEXT)) +#define G_IS_APP_LAUNCH_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_APP_LAUNCH_CONTEXT)) +#define G_APP_LAUNCH_CONTEXT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContextClass)) + +typedef struct _GAppLaunchContextClass GAppLaunchContextClass; +typedef struct _GAppLaunchContextPrivate GAppLaunchContextPrivate; + +/** + * GAppInfo: + * + * Information about an installed application and methods to launch + * it (with file arguments). + */ + +/** + * GAppInfoIface: + * @g_iface: The parent interface. + * @dup: Copies a #GAppInfo. + * @equal: Checks two #GAppInfos for equality. + * @get_id: Gets a string identifier for a #GAppInfo. + * @get_name: Gets the name of the application for a #GAppInfo. + * @get_description: Gets a short description for the application described by the #GAppInfo. + * @get_executable: Gets the executable name for the #GAppInfo. + * @get_icon: Gets the #GIcon for the #GAppInfo. + * @launch: Launches an application specified by the #GAppInfo. + * @supports_uris: Indicates whether the application specified supports launching URIs. + * @supports_files: Indicates whether the application specified accepts filename arguments. + * @launch_uris: Launches an application with a list of URIs. + * @should_show: Returns whether an application should be shown (e.g. when getting a list of installed applications). + * [FreeDesktop.Org Startup Notification Specification](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt). + * @set_as_default_for_type: Sets an application as default for a given content type. + * @set_as_default_for_extension: Sets an application as default for a given file extension. + * @add_supports_type: Adds to the #GAppInfo information about supported file types. + * @can_remove_supports_type: Checks for support for removing supported file types from a #GAppInfo. + * @remove_supports_type: Removes a supported application type from a #GAppInfo. + * @can_delete: Checks if a #GAppInfo can be deleted. Since 2.20 + * @do_delete: Deletes a #GAppInfo. Since 2.20 + * @get_commandline: Gets the commandline for the #GAppInfo. Since 2.20 + * @get_display_name: Gets the display name for the #GAppInfo. Since 2.24 + * @set_as_last_used_for_type: Sets the application as the last used. See g_app_info_set_as_last_used_for_type(). + * @get_supported_types: Retrieves the list of content types that @app_info claims to support. + * @launch_uris_async: Asynchronously launches an application with a list of URIs. (Since: 2.60) + * @launch_uris_finish: Finishes an operation started with @launch_uris_async. (Since: 2.60) + + * Application Information interface, for operating system portability. + */ +typedef struct _GAppInfoIface GAppInfoIface; + +struct _GAppInfoIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + GAppInfo * (* dup) (GAppInfo *appinfo); + gboolean (* equal) (GAppInfo *appinfo1, + GAppInfo *appinfo2); + const char * (* get_id) (GAppInfo *appinfo); + const char * (* get_name) (GAppInfo *appinfo); + const char * (* get_description) (GAppInfo *appinfo); + const char * (* get_executable) (GAppInfo *appinfo); + GIcon * (* get_icon) (GAppInfo *appinfo); + gboolean (* launch) (GAppInfo *appinfo, + GList *files, + GAppLaunchContext *context, + GError **error); + gboolean (* supports_uris) (GAppInfo *appinfo); + gboolean (* supports_files) (GAppInfo *appinfo); + gboolean (* launch_uris) (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *context, + GError **error); + gboolean (* should_show) (GAppInfo *appinfo); + + /* For changing associations */ + gboolean (* set_as_default_for_type) (GAppInfo *appinfo, + const char *content_type, + GError **error); + gboolean (* set_as_default_for_extension) (GAppInfo *appinfo, + const char *extension, + GError **error); + gboolean (* add_supports_type) (GAppInfo *appinfo, + const char *content_type, + GError **error); + gboolean (* can_remove_supports_type) (GAppInfo *appinfo); + gboolean (* remove_supports_type) (GAppInfo *appinfo, + const char *content_type, + GError **error); + gboolean (* can_delete) (GAppInfo *appinfo); + gboolean (* do_delete) (GAppInfo *appinfo); + const char * (* get_commandline) (GAppInfo *appinfo); + const char * (* get_display_name) (GAppInfo *appinfo); + gboolean (* set_as_last_used_for_type) (GAppInfo *appinfo, + const char *content_type, + GError **error); + const char ** (* get_supported_types) (GAppInfo *appinfo); + void (* launch_uris_async) (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* launch_uris_finish) (GAppInfo *appinfo, + GAsyncResult *result, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_app_info_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GAppInfo * g_app_info_create_from_commandline (const char *commandline, + const char *application_name, + GAppInfoCreateFlags flags, + GError **error); +GLIB_AVAILABLE_IN_ALL +GAppInfo * g_app_info_dup (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_equal (GAppInfo *appinfo1, + GAppInfo *appinfo2); +GLIB_AVAILABLE_IN_ALL +const char *g_app_info_get_id (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +const char *g_app_info_get_name (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +const char *g_app_info_get_display_name (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +const char *g_app_info_get_description (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +const char *g_app_info_get_executable (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +const char *g_app_info_get_commandline (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +GIcon * g_app_info_get_icon (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_launch (GAppInfo *appinfo, + GList *files, + GAppLaunchContext *context, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_supports_uris (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_supports_files (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_launch_uris (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *context, + GError **error); +GLIB_AVAILABLE_IN_2_60 +void g_app_info_launch_uris_async (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_60 +gboolean g_app_info_launch_uris_finish (GAppInfo *appinfo, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_should_show (GAppInfo *appinfo); + +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_set_as_default_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_set_as_default_for_extension (GAppInfo *appinfo, + const char *extension, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_add_supports_type (GAppInfo *appinfo, + const char *content_type, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_can_remove_supports_type (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_remove_supports_type (GAppInfo *appinfo, + const char *content_type, + GError **error); +GLIB_AVAILABLE_IN_2_34 +const char **g_app_info_get_supported_types (GAppInfo *appinfo); + +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_can_delete (GAppInfo *appinfo); +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_delete (GAppInfo *appinfo); + +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_set_as_last_used_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GList * g_app_info_get_all (void); +GLIB_AVAILABLE_IN_ALL +GList * g_app_info_get_all_for_type (const char *content_type); +GLIB_AVAILABLE_IN_ALL +GList * g_app_info_get_recommended_for_type (const gchar *content_type); +GLIB_AVAILABLE_IN_ALL +GList * g_app_info_get_fallback_for_type (const gchar *content_type); + +GLIB_AVAILABLE_IN_ALL +void g_app_info_reset_type_associations (const char *content_type); +GLIB_AVAILABLE_IN_ALL +GAppInfo *g_app_info_get_default_for_type (const char *content_type, + gboolean must_support_uris); +GLIB_AVAILABLE_IN_ALL +GAppInfo *g_app_info_get_default_for_uri_scheme (const char *uri_scheme); + +GLIB_AVAILABLE_IN_ALL +gboolean g_app_info_launch_default_for_uri (const char *uri, + GAppLaunchContext *context, + GError **error); + +GLIB_AVAILABLE_IN_2_50 +void g_app_info_launch_default_for_uri_async (const char *uri, + GAppLaunchContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_50 +gboolean g_app_info_launch_default_for_uri_finish (GAsyncResult *result, + GError **error); + + +/** + * GAppLaunchContext: + * + * Integrating the launch with the launching application. This is used to + * handle for instance startup notification and launching the new application + * on the same screen as the launching window. + */ +struct _GAppLaunchContext +{ + GObject parent_instance; + + /*< private >*/ + GAppLaunchContextPrivate *priv; +}; + +struct _GAppLaunchContextClass +{ + GObjectClass parent_class; + + char * (* get_display) (GAppLaunchContext *context, + GAppInfo *info, + GList *files); + char * (* get_startup_notify_id) (GAppLaunchContext *context, + GAppInfo *info, + GList *files); + void (* launch_failed) (GAppLaunchContext *context, + const char *startup_notify_id); + void (* launched) (GAppLaunchContext *context, + GAppInfo *info, + GVariant *platform_data); + void (* launch_started) (GAppLaunchContext *context, + GAppInfo *info, + GVariant *platform_data); + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_app_launch_context_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GAppLaunchContext *g_app_launch_context_new (void); + +GLIB_AVAILABLE_IN_2_32 +void g_app_launch_context_setenv (GAppLaunchContext *context, + const char *variable, + const char *value); +GLIB_AVAILABLE_IN_2_32 +void g_app_launch_context_unsetenv (GAppLaunchContext *context, + const char *variable); +GLIB_AVAILABLE_IN_2_32 +char ** g_app_launch_context_get_environment (GAppLaunchContext *context); + +GLIB_AVAILABLE_IN_ALL +char * g_app_launch_context_get_display (GAppLaunchContext *context, + GAppInfo *info, + GList *files); +GLIB_AVAILABLE_IN_ALL +char * g_app_launch_context_get_startup_notify_id (GAppLaunchContext *context, + GAppInfo *info, + GList *files); +GLIB_AVAILABLE_IN_ALL +void g_app_launch_context_launch_failed (GAppLaunchContext *context, + const char * startup_notify_id); + +#define G_TYPE_APP_INFO_MONITOR (g_app_info_monitor_get_type ()) +#define G_APP_INFO_MONITOR(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_APP_INFO_MONITOR, GAppInfoMonitor)) +#define G_IS_APP_INFO_MONITOR(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_APP_INFO_MONITOR)) + +typedef struct _GAppInfoMonitor GAppInfoMonitor; + +GLIB_AVAILABLE_IN_2_40 +GType g_app_info_monitor_get_type (void); + +GLIB_AVAILABLE_IN_2_40 +GAppInfoMonitor * g_app_info_monitor_get (void); + +G_END_DECLS + +#endif /* __G_APP_INFO_H__ */ diff --git a/gio/gappinfoprivate.h b/gio/gappinfoprivate.h new file mode 100644 index 0000000..f8b0f48 --- /dev/null +++ b/gio/gappinfoprivate.h @@ -0,0 +1,26 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_APP_INFO_PRIVATE_H__ +#define __G_APP_INFO_PRIVATE_H__ + +void g_app_info_monitor_fire (void); + +#endif /* __G_APP_INFO_PRIVATE_H__ */ diff --git a/gio/gapplication-tool.c b/gio/gapplication-tool.c new file mode 100644 index 0000000..7ad0622 --- /dev/null +++ b/gio/gapplication-tool.c @@ -0,0 +1,471 @@ +/* + * Copyright © 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include + +#include +#include + +#include +#include + +struct help_topic +{ + const gchar *command; + const gchar *summary; + const gchar *description; + const gchar *synopsis; +}; + +struct help_substvar +{ + const gchar *var; + const gchar *description; +}; + +static const struct help_topic topics[] = { + { "help", N_("Print help"), + N_("Print help"), + N_("[COMMAND]") + }, + { "version", N_("Print version"), + N_("Print version information and exit"), + NULL + }, + { "list-apps", N_("List applications"), + N_("List the installed D-Bus activatable applications (by .desktop files)"), + NULL + }, + { "launch", N_("Launch an application"), + N_("Launch the application (with optional files to open)"), + N_("APPID [FILE…]") + }, + { "action", N_("Activate an action"), + N_("Invoke an action on the application"), + N_("APPID ACTION [PARAMETER]") + }, + { "list-actions", N_("List available actions"), + N_("List static actions for an application (from .desktop file)"), + N_("APPID") + } +}; + +static const struct help_substvar substvars[] = { + { N_("COMMAND"), N_("The command to print detailed help for") }, + { N_("APPID"), N_("Application identifier in D-Bus format (eg: org.example.viewer)") }, + { N_("FILE"), N_("Optional relative or absolute filenames, or URIs to open") }, + { N_("ACTION"), N_("The action name to invoke") }, + { N_("PARAMETER"), N_("Optional parameter to the action invocation, in GVariant format") } +}; + +static int +app_help (gboolean requested, + const gchar *command) +{ + const struct help_topic *topic = NULL; + GString *string; + + string = g_string_new (NULL); + + if (command) + { + gsize i; + + for (i = 0; i < G_N_ELEMENTS (topics); i++) + if (g_str_equal (topics[i].command, command)) + topic = &topics[i]; + + if (!topic) + { + g_string_printf (string, _("Unknown command %s\n\n"), command); + requested = FALSE; + } + } + + g_string_append (string, _("Usage:\n")); + + if (topic) + { + guint maxwidth; + gsize i; + + g_string_append_printf (string, "\n %s %s %s\n\n", "gapplication", + topic->command, topic->synopsis ? _(topic->synopsis) : ""); + g_string_append_printf (string, "%s\n\n", _(topic->description)); + + if (topic->synopsis) + { + g_string_append (string, _("Arguments:\n")); + + maxwidth = 0; + for (i = 0; i < G_N_ELEMENTS (substvars); i++) + if (strstr (topic->synopsis, substvars[i].var)) + maxwidth = MAX(maxwidth, strlen (_(substvars[i].var))); + + for (i = 0; i < G_N_ELEMENTS (substvars); i++) + if (strstr (topic->synopsis, substvars[i].var)) + g_string_append_printf (string, " %-*.*s %s\n", maxwidth, maxwidth, + _(substvars[i].var), _(substvars[i].description)); + g_string_append (string, "\n"); + } + } + else + { + guint maxwidth; + gsize i; + + g_string_append_printf (string, "\n %s %s %s\n\n", "gapplication", _("COMMAND"), _("[ARGS…]")); + g_string_append_printf (string, _("Commands:\n")); + + maxwidth = 0; + for (i = 0; i < G_N_ELEMENTS (topics); i++) + maxwidth = MAX(maxwidth, strlen (topics[i].command)); + + for (i = 0; i < G_N_ELEMENTS (topics); i++) + g_string_append_printf (string, " %-*.*s %s\n", maxwidth, maxwidth, + topics[i].command, _(topics[i].summary)); + + g_string_append (string, "\n"); + /* Translators: do not translate 'help', but please translate 'COMMAND'. */ + g_string_append_printf (string, _("Use “%s help COMMAND†to get detailed help.\n\n"), "gapplication"); + } + + if (requested) + g_print ("%s", string->str); + else + g_printerr ("%s\n", string->str); + + g_string_free (string, TRUE); + + return requested ? 0 : 1; +} + +static gboolean +app_check_name (gchar **args, + const gchar *command) +{ + if (args[0] == NULL) + { + g_printerr (_("%s command requires an application id to directly follow\n\n"), command); + return FALSE; + } + + if (!g_dbus_is_name (args[0])) + { + g_printerr (_("invalid application id: “%sâ€\n"), args[0]); + return FALSE; + } + + return TRUE; +} + +static int +app_no_args (const gchar *command) +{ + /* Translators: %s is replaced with a command name like 'list-actions' */ + g_printerr (_("“%s†takes no arguments\n\n"), command); + return app_help (FALSE, command); +} + +static int +app_version (gchar **args) +{ + if (g_strv_length (args)) + return app_no_args ("version"); + + g_print (PACKAGE_VERSION "\n"); + return 0; +} + +static int +app_list (gchar **args) +{ + GList *apps; + + if (g_strv_length (args)) + return app_no_args ("list"); + + apps = g_app_info_get_all (); + + while (apps) + { + GDesktopAppInfo *info = apps->data; + + if (G_IS_DESKTOP_APP_INFO (info)) + if (g_desktop_app_info_get_boolean (info, "DBusActivatable")) + { + const gchar *filename; + + filename = g_app_info_get_id (G_APP_INFO (info)); + if (g_str_has_suffix (filename, ".desktop")) + { + gchar *id; + + id = g_strndup (filename, strlen (filename) - 8); + g_print ("%s\n", id); + g_free (id); + } + } + + apps = g_list_delete_link (apps, apps); + g_object_unref (info); + } + + return 0; +} + +static gchar * +app_path_for_id (const gchar *app_id) +{ + gchar *path; + gint i; + + path = g_strconcat ("/", app_id, NULL); + for (i = 0; path[i]; i++) + { + if (path[i] == '.') + path[i] = '/'; + if (path[i] == '-') + path[i] = '_'; + } + + return path; +} + +static int +app_call (const gchar *app_id, + const gchar *method_name, + GVariant *parameters) +{ + GDBusConnection *session; + GError *error = NULL; + gchar *object_path; + GVariant *result; + + + session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + if (!session) + { + g_variant_unref (g_variant_ref_sink (parameters)); + g_printerr (_("unable to connect to D-Bus: %s\n"), error->message); + g_error_free (error); + return 1; + } + + object_path = app_path_for_id (app_id); + + result = g_dbus_connection_call_sync (session, app_id, object_path, "org.freedesktop.Application", + method_name, parameters, G_VARIANT_TYPE_UNIT, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + g_free (object_path); + + if (result) + { + g_variant_unref (result); + return 0; + } + else + { + g_printerr (_("error sending %s message to application: %s\n"), method_name, error->message); + g_error_free (error); + return 1; + } +} + +static GVariant * +app_get_platform_data (void) +{ + GVariantBuilder builder; + const gchar *startup_id; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + + if ((startup_id = g_getenv ("DESKTOP_STARTUP_ID"))) + g_variant_builder_add (&builder, "{sv}", "desktop-startup-id", g_variant_new_string (startup_id)); + + return g_variant_builder_end (&builder); +} + +static int +app_action (gchar **args) +{ + GVariantBuilder params; + const gchar *name; + + if (!app_check_name (args, "action")) + return 1; + + if (args[1] == NULL) + { + g_printerr (_("action name must be given after application id\n")); + return 1; + } + + name = args[1]; + + if (!g_action_name_is_valid (name)) + { + g_printerr (_("invalid action name: “%sâ€\n" + "action names must consist of only alphanumerics, “-†and “.â€\n"), name); + return 1; + } + + g_variant_builder_init (¶ms, G_VARIANT_TYPE ("av")); + + if (args[2]) + { + GError *error = NULL; + GVariant *parameter; + + parameter = g_variant_parse (NULL, args[2], NULL, NULL, &error); + + if (!parameter) + { + gchar *context; + + context = g_variant_parse_error_print_context (error, args[2]); + g_printerr (_("error parsing action parameter: %s\n"), context); + g_variant_builder_clear (¶ms); + g_error_free (error); + g_free (context); + return 1; + } + + g_variant_builder_add (¶ms, "v", parameter); + g_variant_unref (parameter); + + if (args[3]) + { + g_printerr (_("actions accept a maximum of one parameter\n")); + g_variant_builder_clear (¶ms); + return 1; + } + } + + return app_call (args[0], "ActivateAction", g_variant_new ("(sav@a{sv})", name, ¶ms, app_get_platform_data ())); +} + +static int +app_activate (const gchar *app_id) +{ + return app_call (app_id, "Activate", g_variant_new ("(@a{sv})", app_get_platform_data ())); +} + +static int +app_launch (gchar **args) +{ + GVariantBuilder files; + gint i; + + if (!app_check_name (args, "launch")) + return 1; + + if (args[1] == NULL) + return app_activate (args[0]); + + g_variant_builder_init (&files, G_VARIANT_TYPE_STRING_ARRAY); + + for (i = 1; args[i]; i++) + { + GFile *file; + + /* "This operation never fails" */ + file = g_file_new_for_commandline_arg (args[i]); + g_variant_builder_add_value (&files, g_variant_new_take_string (g_file_get_uri (file))); + g_object_unref (file); + } + + return app_call (args[0], "Open", g_variant_new ("(as@a{sv})", &files, app_get_platform_data ())); +} + +static int +app_list_actions (gchar **args) +{ + const gchar * const *actions; + GDesktopAppInfo *app_info; + gchar *filename; + gint i; + + if (!app_check_name (args, "list-actions")) + return 1; + + if (args[1]) + { + g_printerr (_("list-actions command takes only the application id")); + app_help (FALSE, "list-actions"); + } + + filename = g_strconcat (args[0], ".desktop", NULL); + app_info = g_desktop_app_info_new (filename); + g_free (filename); + + if (app_info == NULL) + { + g_printerr (_("unable to find desktop file for application %s\n"), args[0]); + return 1; + } + + actions = g_desktop_app_info_list_actions (app_info); + + for (i = 0; actions[i]; i++) + g_print ("%s\n", actions[i]); + + g_object_unref (app_info); + + return 0; +} + +int +main (int argc, char **argv) +{ + setlocale (LC_ALL, ""); + textdomain (GETTEXT_PACKAGE); + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + + if (argc < 2) + return app_help (TRUE, NULL); + + if (g_str_equal (argv[1], "help")) + return app_help (TRUE, argv[2]); + + if (g_str_equal (argv[1], "version")) + return app_version (argv + 2); + + if (g_str_equal (argv[1], "list-apps")) + return app_list (argv + 2); + + if (g_str_equal (argv[1], "launch")) + return app_launch (argv + 2); + + if (g_str_equal (argv[1], "action")) + return app_action (argv + 2); + + if (g_str_equal (argv[1], "list-actions")) + return app_list_actions (argv + 2); + + g_printerr (_("unrecognised command: %s\n\n"), argv[1]); + + return app_help (FALSE, NULL); +} diff --git a/gio/gapplication.c b/gio/gapplication.c new file mode 100644 index 0000000..cbc467a --- /dev/null +++ b/gio/gapplication.c @@ -0,0 +1,3136 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +/* Prologue {{{1 */ +#include "config.h" + +#include "gapplication.h" + +#include "gapplicationcommandline.h" +#include "gsimpleactiongroup.h" +#include "gremoteactiongroup.h" +#include "gapplicationimpl.h" +#include "gactiongroup.h" +#include "gactionmap.h" +#include "gsettings.h" +#include "gnotification-private.h" +#include "gnotificationbackend.h" +#include "gdbusutils.h" + +#include "gioenumtypes.h" +#include "gioenums.h" +#include "gfile.h" + +#include "glibintl.h" +#include "gmarshal-internal.h" + +#include + +/** + * SECTION:gapplication + * @title: GApplication + * @short_description: Core application class + * @include: gio/gio.h + * + * A #GApplication is the foundation of an application. It wraps some + * low-level platform-specific services and is intended to act as the + * foundation for higher-level application classes such as + * #GtkApplication or #MxApplication. In general, you should not use + * this class outside of a higher level framework. + * + * GApplication provides convenient life cycle management by maintaining + * a "use count" for the primary application instance. The use count can + * be changed using g_application_hold() and g_application_release(). If + * it drops to zero, the application exits. Higher-level classes such as + * #GtkApplication employ the use count to ensure that the application + * stays alive as long as it has any opened windows. + * + * Another feature that GApplication (optionally) provides is process + * uniqueness. Applications can make use of this functionality by + * providing a unique application ID. If given, only one application + * with this ID can be running at a time per session. The session + * concept is platform-dependent, but corresponds roughly to a graphical + * desktop login. When your application is launched again, its + * arguments are passed through platform communication to the already + * running program. The already running instance of the program is + * called the "primary instance"; for non-unique applications this is + * always the current instance. On Linux, the D-Bus session bus + * is used for communication. + * + * The use of #GApplication differs from some other commonly-used + * uniqueness libraries (such as libunique) in important ways. The + * application is not expected to manually register itself and check + * if it is the primary instance. Instead, the main() function of a + * #GApplication should do very little more than instantiating the + * application instance, possibly connecting signal handlers, then + * calling g_application_run(). All checks for uniqueness are done + * internally. If the application is the primary instance then the + * startup signal is emitted and the mainloop runs. If the application + * is not the primary instance then a signal is sent to the primary + * instance and g_application_run() promptly returns. See the code + * examples below. + * + * If used, the expected form of an application identifier is the same as + * that of of a + * [D-Bus well-known bus name](https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus). + * Examples include: `com.example.MyApp`, `org.example.internal_apps.Calculator`, + * `org._7_zip.Archiver`. + * For details on valid application identifiers, see g_application_id_is_valid(). + * + * On Linux, the application identifier is claimed as a well-known bus name + * on the user's session bus. This means that the uniqueness of your + * application is scoped to the current session. It also means that your + * application may provide additional services (through registration of other + * object paths) at that bus name. The registration of these object paths + * should be done with the shared GDBus session bus. Note that due to the + * internal architecture of GDBus, method calls can be dispatched at any time + * (even if a main loop is not running). For this reason, you must ensure that + * any object paths that you wish to register are registered before #GApplication + * attempts to acquire the bus name of your application (which happens in + * g_application_register()). Unfortunately, this means that you cannot use + * g_application_get_is_remote() to decide if you want to register object paths. + * + * GApplication also implements the #GActionGroup and #GActionMap + * interfaces and lets you easily export actions by adding them with + * g_action_map_add_action(). When invoking an action by calling + * g_action_group_activate_action() on the application, it is always + * invoked in the primary instance. The actions are also exported on + * the session bus, and GIO provides the #GDBusActionGroup wrapper to + * conveniently access them remotely. GIO provides a #GDBusMenuModel wrapper + * for remote access to exported #GMenuModels. + * + * There is a number of different entry points into a GApplication: + * + * - via 'Activate' (i.e. just starting the application) + * + * - via 'Open' (i.e. opening some files) + * + * - by handling a command-line + * + * - via activating an action + * + * The #GApplication::startup signal lets you handle the application + * initialization for all of these in a single place. + * + * Regardless of which of these entry points is used to start the + * application, GApplication passes some ‘platform data’ from the + * launching instance to the primary instance, in the form of a + * #GVariant dictionary mapping strings to variants. To use platform + * data, override the @before_emit or @after_emit virtual functions + * in your #GApplication subclass. When dealing with + * #GApplicationCommandLine objects, the platform data is + * directly available via g_application_command_line_get_cwd(), + * g_application_command_line_get_environ() and + * g_application_command_line_get_platform_data(). + * + * As the name indicates, the platform data may vary depending on the + * operating system, but it always includes the current directory (key + * "cwd"), and optionally the environment (ie the set of environment + * variables and their values) of the calling process (key "environ"). + * The environment is only added to the platform data if the + * %G_APPLICATION_SEND_ENVIRONMENT flag is set. #GApplication subclasses + * can add their own platform data by overriding the @add_platform_data + * virtual function. For instance, #GtkApplication adds startup notification + * data in this way. + * + * To parse commandline arguments you may handle the + * #GApplication::command-line signal or override the local_command_line() + * vfunc, to parse them in either the primary instance or the local instance, + * respectively. + * + * For an example of opening files with a GApplication, see + * [gapplication-example-open.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-open.c). + * + * For an example of using actions with GApplication, see + * [gapplication-example-actions.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-actions.c). + * + * For an example of using extra D-Bus hooks with GApplication, see + * [gapplication-example-dbushooks.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-dbushooks.c). + */ + +/** + * GApplication: + * + * #GApplication is an opaque data structure and can only be accessed + * using the following functions. + * Since: 2.28 + */ + +/** + * GApplicationClass: + * @startup: invoked on the primary instance immediately after registration + * @shutdown: invoked only on the registered primary instance immediately + * after the main loop terminates + * @activate: invoked on the primary instance when an activation occurs + * @open: invoked on the primary instance when there are files to open + * @command_line: invoked on the primary instance when a command-line is + * not handled locally + * @local_command_line: invoked (locally). The virtual function has the chance + * to inspect (and possibly replace) command line arguments. See + * g_application_run() for more information. Also see the + * #GApplication::handle-local-options signal, which is a simpler + * alternative to handling some commandline options locally + * @before_emit: invoked on the primary instance before 'activate', 'open', + * 'command-line' or any action invocation, gets the 'platform data' from + * the calling instance + * @after_emit: invoked on the primary instance after 'activate', 'open', + * 'command-line' or any action invocation, gets the 'platform data' from + * the calling instance + * @add_platform_data: invoked (locally) to add 'platform data' to be sent to + * the primary instance when activating, opening or invoking actions + * @quit_mainloop: Used to be invoked on the primary instance when the use + * count of the application drops to zero (and after any inactivity + * timeout, if requested). Not used anymore since 2.32 + * @run_mainloop: Used to be invoked on the primary instance from + * g_application_run() if the use-count is non-zero. Since 2.32, + * GApplication is iterating the main context directly and is not + * using @run_mainloop anymore + * @dbus_register: invoked locally during registration, if the application is + * using its D-Bus backend. You can use this to export extra objects on the + * bus, that need to exist before the application tries to own the bus name. + * The function is passed the #GDBusConnection to to session bus, and the + * object path that #GApplication will use to export is D-Bus API. + * If this function returns %TRUE, registration will proceed; otherwise + * registration will abort. Since: 2.34 + * @dbus_unregister: invoked locally during unregistration, if the application + * is using its D-Bus backend. Use this to undo anything done by + * the @dbus_register vfunc. Since: 2.34 + * @handle_local_options: invoked locally after the parsing of the commandline + * options has occurred. Since: 2.40 + * @name_lost: invoked when another instance is taking over the name. Since: 2.60 + * + * Virtual function table for #GApplication. + * + * Since: 2.28 + */ + +struct _GApplicationPrivate +{ + GApplicationFlags flags; + gchar *id; + gchar *resource_path; + + GActionGroup *actions; + + guint inactivity_timeout_id; + guint inactivity_timeout; + guint use_count; + guint busy_count; + + guint is_registered : 1; + guint is_remote : 1; + guint did_startup : 1; + guint did_shutdown : 1; + guint must_quit_now : 1; + + GRemoteActionGroup *remote_actions; + GApplicationImpl *impl; + + GNotificationBackend *notifications; + + /* GOptionContext support */ + GOptionGroup *main_options; + GSList *option_groups; + GHashTable *packed_options; + gboolean options_parsed; + gchar *parameter_string; + gchar *summary; + gchar *description; + + /* Allocated option strings, from g_application_add_main_option() */ + GSList *option_strings; +}; + +enum +{ + PROP_NONE, + PROP_APPLICATION_ID, + PROP_FLAGS, + PROP_RESOURCE_BASE_PATH, + PROP_IS_REGISTERED, + PROP_IS_REMOTE, + PROP_INACTIVITY_TIMEOUT, + PROP_ACTION_GROUP, + PROP_IS_BUSY +}; + +enum +{ + SIGNAL_STARTUP, + SIGNAL_SHUTDOWN, + SIGNAL_ACTIVATE, + SIGNAL_OPEN, + SIGNAL_ACTION, + SIGNAL_COMMAND_LINE, + SIGNAL_HANDLE_LOCAL_OPTIONS, + SIGNAL_NAME_LOST, + NR_SIGNALS +}; + +static guint g_application_signals[NR_SIGNALS]; + +static void g_application_action_group_iface_init (GActionGroupInterface *); +static void g_application_action_map_iface_init (GActionMapInterface *); +G_DEFINE_TYPE_WITH_CODE (GApplication, g_application, G_TYPE_OBJECT, + G_ADD_PRIVATE (GApplication) + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_application_action_group_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_MAP, g_application_action_map_iface_init)) + +/* GApplicationExportedActions {{{1 */ + +/* We create a subclass of GSimpleActionGroup that implements + * GRemoteActionGroup and deals with the platform data using + * GApplication's before/after_emit vfuncs. This is the action group we + * will be exporting. + * + * We could implement GRemoteActionGroup on GApplication directly, but + * this would be potentially extremely confusing to have exposed as part + * of the public API of GApplication. We certainly don't want anyone in + * the same process to be calling these APIs... + */ +typedef GSimpleActionGroupClass GApplicationExportedActionsClass; +typedef struct +{ + GSimpleActionGroup parent_instance; + GApplication *application; +} GApplicationExportedActions; + +static GType g_application_exported_actions_get_type (void); +static void g_application_exported_actions_iface_init (GRemoteActionGroupInterface *iface); +G_DEFINE_TYPE_WITH_CODE (GApplicationExportedActions, g_application_exported_actions, G_TYPE_SIMPLE_ACTION_GROUP, + G_IMPLEMENT_INTERFACE (G_TYPE_REMOTE_ACTION_GROUP, g_application_exported_actions_iface_init)) + +static void +g_application_exported_actions_activate_action_full (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *parameter, + GVariant *platform_data) +{ + GApplicationExportedActions *exported = (GApplicationExportedActions *) remote; + + G_APPLICATION_GET_CLASS (exported->application) + ->before_emit (exported->application, platform_data); + + g_action_group_activate_action (G_ACTION_GROUP (exported), action_name, parameter); + + G_APPLICATION_GET_CLASS (exported->application) + ->after_emit (exported->application, platform_data); +} + +static void +g_application_exported_actions_change_action_state_full (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *value, + GVariant *platform_data) +{ + GApplicationExportedActions *exported = (GApplicationExportedActions *) remote; + + G_APPLICATION_GET_CLASS (exported->application) + ->before_emit (exported->application, platform_data); + + g_action_group_change_action_state (G_ACTION_GROUP (exported), action_name, value); + + G_APPLICATION_GET_CLASS (exported->application) + ->after_emit (exported->application, platform_data); +} + +static void +g_application_exported_actions_init (GApplicationExportedActions *actions) +{ +} + +static void +g_application_exported_actions_iface_init (GRemoteActionGroupInterface *iface) +{ + iface->activate_action_full = g_application_exported_actions_activate_action_full; + iface->change_action_state_full = g_application_exported_actions_change_action_state_full; +} + +static void +g_application_exported_actions_class_init (GApplicationExportedActionsClass *class) +{ +} + +static GActionGroup * +g_application_exported_actions_new (GApplication *application) +{ + GApplicationExportedActions *actions; + + actions = g_object_new (g_application_exported_actions_get_type (), NULL); + actions->application = application; + + return G_ACTION_GROUP (actions); +} + +/* Command line option handling {{{1 */ + +static void +free_option_entry (gpointer data) +{ + GOptionEntry *entry = data; + + switch (entry->arg) + { + case G_OPTION_ARG_STRING: + case G_OPTION_ARG_FILENAME: + g_free (*(gchar **) entry->arg_data); + break; + + case G_OPTION_ARG_STRING_ARRAY: + case G_OPTION_ARG_FILENAME_ARRAY: + g_strfreev (*(gchar ***) entry->arg_data); + break; + + default: + /* most things require no free... */ + break; + } + + /* ...except for the space that we allocated for it ourselves */ + g_free (entry->arg_data); + + g_slice_free (GOptionEntry, entry); +} + +static void +g_application_pack_option_entries (GApplication *application, + GVariantDict *dict) +{ + GHashTableIter iter; + gpointer item; + + g_hash_table_iter_init (&iter, application->priv->packed_options); + while (g_hash_table_iter_next (&iter, NULL, &item)) + { + GOptionEntry *entry = item; + GVariant *value = NULL; + + switch (entry->arg) + { + case G_OPTION_ARG_NONE: + if (*(gboolean *) entry->arg_data != 2) + value = g_variant_new_boolean (*(gboolean *) entry->arg_data); + break; + + case G_OPTION_ARG_STRING: + if (*(gchar **) entry->arg_data) + value = g_variant_new_string (*(gchar **) entry->arg_data); + break; + + case G_OPTION_ARG_INT: + if (*(gint32 *) entry->arg_data) + value = g_variant_new_int32 (*(gint32 *) entry->arg_data); + break; + + case G_OPTION_ARG_FILENAME: + if (*(gchar **) entry->arg_data) + value = g_variant_new_bytestring (*(gchar **) entry->arg_data); + break; + + case G_OPTION_ARG_STRING_ARRAY: + if (*(gchar ***) entry->arg_data) + value = g_variant_new_strv (*(const gchar ***) entry->arg_data, -1); + break; + + case G_OPTION_ARG_FILENAME_ARRAY: + if (*(gchar ***) entry->arg_data) + value = g_variant_new_bytestring_array (*(const gchar ***) entry->arg_data, -1); + break; + + case G_OPTION_ARG_DOUBLE: + if (*(gdouble *) entry->arg_data) + value = g_variant_new_double (*(gdouble *) entry->arg_data); + break; + + case G_OPTION_ARG_INT64: + if (*(gint64 *) entry->arg_data) + value = g_variant_new_int64 (*(gint64 *) entry->arg_data); + break; + + default: + g_assert_not_reached (); + } + + if (value) + g_variant_dict_insert_value (dict, entry->long_name, value); + } +} + +static GVariantDict * +g_application_parse_command_line (GApplication *application, + gchar ***arguments, + GError **error) +{ + gboolean become_service = FALSE; + gchar *app_id = NULL; + gboolean replace = FALSE; + GVariantDict *dict = NULL; + GOptionContext *context; + GOptionGroup *gapplication_group; + + /* Due to the memory management of GOptionGroup we can only parse + * options once. That's because once you add a group to the + * GOptionContext there is no way to get it back again. This is fine: + * local_command_line() should never get invoked more than once + * anyway. Add a sanity check just to be sure. + */ + g_return_val_if_fail (!application->priv->options_parsed, NULL); + + context = g_option_context_new (application->priv->parameter_string); + g_option_context_set_summary (context, application->priv->summary); + g_option_context_set_description (context, application->priv->description); + + gapplication_group = g_option_group_new ("gapplication", + _("GApplication options"), _("Show GApplication options"), + NULL, NULL); + g_option_group_set_translation_domain (gapplication_group, GETTEXT_PACKAGE); + g_option_context_add_group (context, gapplication_group); + + /* If the application has not registered local options and it has + * G_APPLICATION_HANDLES_COMMAND_LINE then we have to assume that + * their primary instance commandline handler may want to deal with + * the arguments. We must therefore ignore them. + * + * We must also ignore --help in this case since some applications + * will try to handle this from the remote side. See #737869. + */ + if (application->priv->main_options == NULL && (application->priv->flags & G_APPLICATION_HANDLES_COMMAND_LINE)) + { + g_option_context_set_ignore_unknown_options (context, TRUE); + g_option_context_set_help_enabled (context, FALSE); + } + + /* Add the main option group, if it exists */ + if (application->priv->main_options) + { + /* This consumes the main_options */ + g_option_context_set_main_group (context, application->priv->main_options); + application->priv->main_options = NULL; + } + + /* Add any other option groups if they exist. Adding them to the + * context will consume them, so we free the list as we go... + */ + while (application->priv->option_groups) + { + g_option_context_add_group (context, application->priv->option_groups->data); + application->priv->option_groups = g_slist_delete_link (application->priv->option_groups, + application->priv->option_groups); + } + + /* In the case that we are not explicitly marked as a service or a + * launcher then we want to add the "--gapplication-service" option to + * allow the process to be made into a service. + */ + if ((application->priv->flags & (G_APPLICATION_IS_SERVICE | G_APPLICATION_IS_LAUNCHER)) == 0) + { + GOptionEntry entries[] = { + { "gapplication-service", '\0', 0, G_OPTION_ARG_NONE, &become_service, + N_("Enter GApplication service mode (use from D-Bus service files)"), NULL }, + G_OPTION_ENTRY_NULL + }; + + g_option_group_add_entries (gapplication_group, entries); + } + + /* Allow overriding the ID if the application allows it */ + if (application->priv->flags & G_APPLICATION_CAN_OVERRIDE_APP_ID) + { + GOptionEntry entries[] = { + { "gapplication-app-id", '\0', 0, G_OPTION_ARG_STRING, &app_id, + N_("Override the application’s ID"), NULL }, + G_OPTION_ENTRY_NULL + }; + + g_option_group_add_entries (gapplication_group, entries); + } + + /* Allow replacing if the application allows it */ + if (application->priv->flags & G_APPLICATION_ALLOW_REPLACEMENT) + { + GOptionEntry entries[] = { + { "gapplication-replace", '\0', 0, G_OPTION_ARG_NONE, &replace, + N_("Replace the running instance"), NULL }, + G_OPTION_ENTRY_NULL + }; + + g_option_group_add_entries (gapplication_group, entries); + } + + /* Now we parse... */ + if (!g_option_context_parse_strv (context, arguments, error)) + goto out; + + /* Check for --gapplication-service */ + if (become_service) + application->priv->flags |= G_APPLICATION_IS_SERVICE; + + /* Check for --gapplication-app-id */ + if (app_id) + g_application_set_application_id (application, app_id); + + /* Check for --gapplication-replace */ + if (replace) + application->priv->flags |= G_APPLICATION_REPLACE; + + dict = g_variant_dict_new (NULL); + if (application->priv->packed_options) + { + g_application_pack_option_entries (application, dict); + g_hash_table_unref (application->priv->packed_options); + application->priv->packed_options = NULL; + } + +out: + /* Make sure we don't run again */ + application->priv->options_parsed = TRUE; + + g_option_context_free (context); + g_free (app_id); + + return dict; +} + +static void +add_packed_option (GApplication *application, + GOptionEntry *entry) +{ + switch (entry->arg) + { + case G_OPTION_ARG_NONE: + entry->arg_data = g_new (gboolean, 1); + *(gboolean *) entry->arg_data = 2; + break; + + case G_OPTION_ARG_INT: + entry->arg_data = g_new0 (gint, 1); + break; + + case G_OPTION_ARG_STRING: + case G_OPTION_ARG_FILENAME: + case G_OPTION_ARG_STRING_ARRAY: + case G_OPTION_ARG_FILENAME_ARRAY: + entry->arg_data = g_new0 (gpointer, 1); + break; + + case G_OPTION_ARG_INT64: + entry->arg_data = g_new0 (gint64, 1); + break; + + case G_OPTION_ARG_DOUBLE: + entry->arg_data = g_new0 (gdouble, 1); + break; + + default: + g_return_if_reached (); + } + + if (!application->priv->packed_options) + application->priv->packed_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_option_entry); + + g_hash_table_insert (application->priv->packed_options, + g_strdup (entry->long_name), + g_slice_dup (GOptionEntry, entry)); +} + +/** + * g_application_add_main_option_entries: + * @application: a #GApplication + * @entries: (array zero-terminated=1) (element-type GOptionEntry) a + * %NULL-terminated list of #GOptionEntrys + * + * Adds main option entries to be handled by @application. + * + * This function is comparable to g_option_context_add_main_entries(). + * + * After the commandline arguments are parsed, the + * #GApplication::handle-local-options signal will be emitted. At this + * point, the application can inspect the values pointed to by @arg_data + * in the given #GOptionEntrys. + * + * Unlike #GOptionContext, #GApplication supports giving a %NULL + * @arg_data for a non-callback #GOptionEntry. This results in the + * argument in question being packed into a #GVariantDict which is also + * passed to #GApplication::handle-local-options, where it can be + * inspected and modified. If %G_APPLICATION_HANDLES_COMMAND_LINE is + * set, then the resulting dictionary is sent to the primary instance, + * where g_application_command_line_get_options_dict() will return it. + * This "packing" is done according to the type of the argument -- + * booleans for normal flags, strings for strings, bytestrings for + * filenames, etc. The packing only occurs if the flag is given (ie: we + * do not pack a "false" #GVariant in the case that a flag is missing). + * + * In general, it is recommended that all commandline arguments are + * parsed locally. The options dictionary should then be used to + * transmit the result of the parsing to the primary instance, where + * g_variant_dict_lookup() can be used. For local options, it is + * possible to either use @arg_data in the usual way, or to consult (and + * potentially remove) the option from the options dictionary. + * + * This function is new in GLib 2.40. Before then, the only real choice + * was to send all of the commandline arguments (options and all) to the + * primary instance for handling. #GApplication ignored them completely + * on the local side. Calling this function "opts in" to the new + * behaviour, and in particular, means that unrecognised options will be + * treated as errors. Unrecognised options have never been ignored when + * %G_APPLICATION_HANDLES_COMMAND_LINE is unset. + * + * If #GApplication::handle-local-options needs to see the list of + * filenames, then the use of %G_OPTION_REMAINING is recommended. If + * @arg_data is %NULL then %G_OPTION_REMAINING can be used as a key into + * the options dictionary. If you do use %G_OPTION_REMAINING then you + * need to handle these arguments for yourself because once they are + * consumed, they will no longer be visible to the default handling + * (which treats them as filenames to be opened). + * + * It is important to use the proper GVariant format when retrieving + * the options with g_variant_dict_lookup(): + * - for %G_OPTION_ARG_NONE, use `b` + * - for %G_OPTION_ARG_STRING, use `&s` + * - for %G_OPTION_ARG_INT, use `i` + * - for %G_OPTION_ARG_INT64, use `x` + * - for %G_OPTION_ARG_DOUBLE, use `d` + * - for %G_OPTION_ARG_FILENAME, use `^&ay` + * - for %G_OPTION_ARG_STRING_ARRAY, use `^a&s` + * - for %G_OPTION_ARG_FILENAME_ARRAY, use `^a&ay` + * + * Since: 2.40 + */ +void +g_application_add_main_option_entries (GApplication *application, + const GOptionEntry *entries) +{ + gint i; + + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (entries != NULL); + + if (!application->priv->main_options) + { + application->priv->main_options = g_option_group_new (NULL, NULL, NULL, NULL, NULL); + g_option_group_set_translation_domain (application->priv->main_options, NULL); + } + + for (i = 0; entries[i].long_name; i++) + { + GOptionEntry my_entries[2] = + { + G_OPTION_ENTRY_NULL, + G_OPTION_ENTRY_NULL + }; + my_entries[0] = entries[i]; + + if (!my_entries[0].arg_data) + add_packed_option (application, &my_entries[0]); + + g_option_group_add_entries (application->priv->main_options, my_entries); + } +} + +/** + * g_application_add_main_option: + * @application: the #GApplication + * @long_name: the long name of an option used to specify it in a commandline + * @short_name: the short name of an option + * @flags: flags from #GOptionFlags + * @arg: the type of the option, as a #GOptionArg + * @description: the description for the option in `--help` output + * @arg_description: (nullable): the placeholder to use for the extra argument + * parsed by the option in `--help` output + * + * Add an option to be handled by @application. + * + * Calling this function is the equivalent of calling + * g_application_add_main_option_entries() with a single #GOptionEntry + * that has its arg_data member set to %NULL. + * + * The parsed arguments will be packed into a #GVariantDict which + * is passed to #GApplication::handle-local-options. If + * %G_APPLICATION_HANDLES_COMMAND_LINE is set, then it will also + * be sent to the primary instance. See + * g_application_add_main_option_entries() for more details. + * + * See #GOptionEntry for more documentation of the arguments. + * + * Since: 2.42 + **/ +void +g_application_add_main_option (GApplication *application, + const char *long_name, + char short_name, + GOptionFlags flags, + GOptionArg arg, + const char *description, + const char *arg_description) +{ + gchar *dup_string; + GOptionEntry my_entry[2] = { + { NULL, short_name, flags, arg, NULL, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (long_name != NULL); + g_return_if_fail (description != NULL); + + my_entry[0].long_name = dup_string = g_strdup (long_name); + application->priv->option_strings = g_slist_prepend (application->priv->option_strings, dup_string); + + my_entry[0].description = dup_string = g_strdup (description); + application->priv->option_strings = g_slist_prepend (application->priv->option_strings, dup_string); + + my_entry[0].arg_description = dup_string = g_strdup (arg_description); + application->priv->option_strings = g_slist_prepend (application->priv->option_strings, dup_string); + + g_application_add_main_option_entries (application, my_entry); +} + +/** + * g_application_add_option_group: + * @application: the #GApplication + * @group: (transfer full): a #GOptionGroup + * + * Adds a #GOptionGroup to the commandline handling of @application. + * + * This function is comparable to g_option_context_add_group(). + * + * Unlike g_application_add_main_option_entries(), this function does + * not deal with %NULL @arg_data and never transmits options to the + * primary instance. + * + * The reason for that is because, by the time the options arrive at the + * primary instance, it is typically too late to do anything with them. + * Taking the GTK option group as an example: GTK will already have been + * initialised by the time the #GApplication::command-line handler runs. + * In the case that this is not the first-running instance of the + * application, the existing instance may already have been running for + * a very long time. + * + * This means that the options from #GOptionGroup are only really usable + * in the case that the instance of the application being run is the + * first instance. Passing options like `--display=` or `--gdk-debug=` + * on future runs will have no effect on the existing primary instance. + * + * Calling this function will cause the options in the supplied option + * group to be parsed, but it does not cause you to be "opted in" to the + * new functionality whereby unrecognised options are rejected even if + * %G_APPLICATION_HANDLES_COMMAND_LINE was given. + * + * Since: 2.40 + **/ +void +g_application_add_option_group (GApplication *application, + GOptionGroup *group) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (group != NULL); + + application->priv->option_groups = g_slist_prepend (application->priv->option_groups, group); +} + +/** + * g_application_set_option_context_parameter_string: + * @application: the #GApplication + * @parameter_string: (nullable): a string which is displayed + * in the first line of `--help` output, after the usage summary `programname [OPTION...]`. + * + * Sets the parameter string to be used by the commandline handling of @application. + * + * This function registers the argument to be passed to g_option_context_new() + * when the internal #GOptionContext of @application is created. + * + * See g_option_context_new() for more information about @parameter_string. + * + * Since: 2.56 + */ +void +g_application_set_option_context_parameter_string (GApplication *application, + const gchar *parameter_string) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + + g_free (application->priv->parameter_string); + application->priv->parameter_string = g_strdup (parameter_string); +} + +/** + * g_application_set_option_context_summary: + * @application: the #GApplication + * @summary: (nullable): a string to be shown in `--help` output + * before the list of options, or %NULL + * + * Adds a summary to the @application option context. + * + * See g_option_context_set_summary() for more information. + * + * Since: 2.56 + */ +void +g_application_set_option_context_summary (GApplication *application, + const gchar *summary) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + + g_free (application->priv->summary); + application->priv->summary = g_strdup (summary); +} + +/** + * g_application_set_option_context_description: + * @application: the #GApplication + * @description: (nullable): a string to be shown in `--help` output + * after the list of options, or %NULL + * + * Adds a description to the @application option context. + * + * See g_option_context_set_description() for more information. + * + * Since: 2.56 + */ +void +g_application_set_option_context_description (GApplication *application, + const gchar *description) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + + g_free (application->priv->description); + application->priv->description = g_strdup (description); + +} + + +/* vfunc defaults {{{1 */ +static void +g_application_real_before_emit (GApplication *application, + GVariant *platform_data) +{ +} + +static void +g_application_real_after_emit (GApplication *application, + GVariant *platform_data) +{ +} + +static void +g_application_real_startup (GApplication *application) +{ + application->priv->did_startup = TRUE; +} + +static void +g_application_real_shutdown (GApplication *application) +{ + application->priv->did_shutdown = TRUE; +} + +static void +g_application_real_activate (GApplication *application) +{ + if (!g_signal_has_handler_pending (application, + g_application_signals[SIGNAL_ACTIVATE], + 0, TRUE) && + G_APPLICATION_GET_CLASS (application)->activate == g_application_real_activate) + { + static gboolean warned; + + if (warned) + return; + + g_warning ("Your application does not implement " + "g_application_activate() and has no handlers connected " + "to the 'activate' signal. It should do one of these."); + warned = TRUE; + } +} + +static void +g_application_real_open (GApplication *application, + GFile **files, + gint n_files, + const gchar *hint) +{ + if (!g_signal_has_handler_pending (application, + g_application_signals[SIGNAL_OPEN], + 0, TRUE) && + G_APPLICATION_GET_CLASS (application)->open == g_application_real_open) + { + static gboolean warned; + + if (warned) + return; + + g_warning ("Your application claims to support opening files " + "but does not implement g_application_open() and has no " + "handlers connected to the 'open' signal."); + warned = TRUE; + } +} + +static int +g_application_real_command_line (GApplication *application, + GApplicationCommandLine *cmdline) +{ + if (!g_signal_has_handler_pending (application, + g_application_signals[SIGNAL_COMMAND_LINE], + 0, TRUE) && + G_APPLICATION_GET_CLASS (application)->command_line == g_application_real_command_line) + { + static gboolean warned; + + if (warned) + return 1; + + g_warning ("Your application claims to support custom command line " + "handling but does not implement g_application_command_line() " + "and has no handlers connected to the 'command-line' signal."); + + warned = TRUE; + } + + return 1; +} + +static gint +g_application_real_handle_local_options (GApplication *application, + GVariantDict *options) +{ + return -1; +} + +static GVariant * +get_platform_data (GApplication *application, + GVariant *options) +{ + GVariantBuilder *builder; + GVariant *result; + + builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + + { + gchar *cwd = g_get_current_dir (); + g_variant_builder_add (builder, "{sv}", "cwd", + g_variant_new_bytestring (cwd)); + g_free (cwd); + } + + if (application->priv->flags & G_APPLICATION_SEND_ENVIRONMENT) + { + GVariant *array; + gchar **envp; + + envp = g_get_environ (); + array = g_variant_new_bytestring_array ((const gchar **) envp, -1); + g_strfreev (envp); + + g_variant_builder_add (builder, "{sv}", "environ", array); + } + + if (options) + g_variant_builder_add (builder, "{sv}", "options", options); + + G_APPLICATION_GET_CLASS (application)-> + add_platform_data (application, builder); + + result = g_variant_builder_end (builder); + g_variant_builder_unref (builder); + + return result; +} + +static void +g_application_call_command_line (GApplication *application, + const gchar * const *arguments, + GVariant *options, + gint *exit_status) +{ + if (application->priv->is_remote) + { + GVariant *platform_data; + + platform_data = get_platform_data (application, options); + *exit_status = g_application_impl_command_line (application->priv->impl, arguments, platform_data); + } + else + { + GApplicationCommandLine *cmdline; + GVariant *v; + + v = g_variant_new_bytestring_array ((const gchar **) arguments, -1); + cmdline = g_object_new (G_TYPE_APPLICATION_COMMAND_LINE, + "arguments", v, + "options", options, + NULL); + g_signal_emit (application, g_application_signals[SIGNAL_COMMAND_LINE], 0, cmdline, exit_status); + g_object_unref (cmdline); + } +} + +static gboolean +g_application_real_local_command_line (GApplication *application, + gchar ***arguments, + int *exit_status) +{ + GError *error = NULL; + GVariantDict *options; + gint n_args; + + options = g_application_parse_command_line (application, arguments, &error); + if (!options) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + *exit_status = 1; + return TRUE; + } + + g_signal_emit (application, g_application_signals[SIGNAL_HANDLE_LOCAL_OPTIONS], 0, options, exit_status); + + if (*exit_status >= 0) + { + g_variant_dict_unref (options); + return TRUE; + } + + if (!g_application_register (application, NULL, &error)) + { + g_printerr ("Failed to register: %s\n", error->message); + g_variant_dict_unref (options); + g_error_free (error); + *exit_status = 1; + return TRUE; + } + + n_args = g_strv_length (*arguments); + + if (application->priv->flags & G_APPLICATION_IS_SERVICE) + { + if ((*exit_status = n_args > 1)) + { + g_printerr ("GApplication service mode takes no arguments.\n"); + application->priv->flags &= ~G_APPLICATION_IS_SERVICE; + *exit_status = 1; + } + else + *exit_status = 0; + } + else if (application->priv->flags & G_APPLICATION_HANDLES_COMMAND_LINE) + { + g_application_call_command_line (application, + (const gchar **) *arguments, + g_variant_dict_end (options), + exit_status); + } + else + { + if (n_args <= 1) + { + g_application_activate (application); + *exit_status = 0; + } + + else + { + if (~application->priv->flags & G_APPLICATION_HANDLES_OPEN) + { + g_critical ("This application can not open files."); + *exit_status = 1; + } + else + { + GFile **files; + gint n_files; + gint i; + + n_files = n_args - 1; + files = g_new (GFile *, n_files); + + for (i = 0; i < n_files; i++) + files[i] = g_file_new_for_commandline_arg ((*arguments)[i + 1]); + + g_application_open (application, files, n_files, ""); + + for (i = 0; i < n_files; i++) + g_object_unref (files[i]); + g_free (files); + + *exit_status = 0; + } + } + } + + g_variant_dict_unref (options); + + return TRUE; +} + +static void +g_application_real_add_platform_data (GApplication *application, + GVariantBuilder *builder) +{ +} + +static gboolean +g_application_real_dbus_register (GApplication *application, + GDBusConnection *connection, + const gchar *object_path, + GError **error) +{ + return TRUE; +} + +static void +g_application_real_dbus_unregister (GApplication *application, + GDBusConnection *connection, + const gchar *object_path) +{ +} + +static gboolean +g_application_real_name_lost (GApplication *application) +{ + g_application_quit (application); + return TRUE; +} + +/* GObject implementation stuff {{{1 */ +static void +g_application_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GApplication *application = G_APPLICATION (object); + + switch (prop_id) + { + case PROP_APPLICATION_ID: + g_application_set_application_id (application, + g_value_get_string (value)); + break; + + case PROP_FLAGS: + g_application_set_flags (application, g_value_get_flags (value)); + break; + + case PROP_RESOURCE_BASE_PATH: + g_application_set_resource_base_path (application, g_value_get_string (value)); + break; + + case PROP_INACTIVITY_TIMEOUT: + g_application_set_inactivity_timeout (application, + g_value_get_uint (value)); + break; + + case PROP_ACTION_GROUP: + g_clear_object (&application->priv->actions); + application->priv->actions = g_value_dup_object (value); + break; + + default: + g_assert_not_reached (); + } +} + +/** + * g_application_set_action_group: + * @application: a #GApplication + * @action_group: (nullable): a #GActionGroup, or %NULL + * + * This used to be how actions were associated with a #GApplication. + * Now there is #GActionMap for that. + * + * Since: 2.28 + * + * Deprecated:2.32:Use the #GActionMap interface instead. Never ever + * mix use of this API with use of #GActionMap on the same @application + * or things will go very badly wrong. This function is known to + * introduce buggy behaviour (ie: signals not emitted on changes to the + * action group), so you should really use #GActionMap instead. + **/ +void +g_application_set_action_group (GApplication *application, + GActionGroup *action_group) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (!application->priv->is_registered); + + if (application->priv->actions != NULL) + g_object_unref (application->priv->actions); + + application->priv->actions = action_group; + + if (application->priv->actions != NULL) + g_object_ref (application->priv->actions); +} + +static void +g_application_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GApplication *application = G_APPLICATION (object); + + switch (prop_id) + { + case PROP_APPLICATION_ID: + g_value_set_string (value, + g_application_get_application_id (application)); + break; + + case PROP_FLAGS: + g_value_set_flags (value, + g_application_get_flags (application)); + break; + + case PROP_RESOURCE_BASE_PATH: + g_value_set_string (value, g_application_get_resource_base_path (application)); + break; + + case PROP_IS_REGISTERED: + g_value_set_boolean (value, + g_application_get_is_registered (application)); + break; + + case PROP_IS_REMOTE: + g_value_set_boolean (value, + g_application_get_is_remote (application)); + break; + + case PROP_INACTIVITY_TIMEOUT: + g_value_set_uint (value, + g_application_get_inactivity_timeout (application)); + break; + + case PROP_IS_BUSY: + g_value_set_boolean (value, g_application_get_is_busy (application)); + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_application_constructed (GObject *object) +{ + GApplication *application = G_APPLICATION (object); + + if (g_application_get_default () == NULL) + g_application_set_default (application); + + /* People should not set properties from _init... */ + g_assert (application->priv->resource_path == NULL); + + if (application->priv->id != NULL) + { + gint i; + + application->priv->resource_path = g_strconcat ("/", application->priv->id, NULL); + + for (i = 1; application->priv->resource_path[i]; i++) + if (application->priv->resource_path[i] == '.') + application->priv->resource_path[i] = '/'; + } +} + +static void +g_application_dispose (GObject *object) +{ + GApplication *application = G_APPLICATION (object); + + if (application->priv->impl != NULL && + G_APPLICATION_GET_CLASS (application)->dbus_unregister != g_application_real_dbus_unregister) + { + static gboolean warned; + + if (!warned) + { + g_warning ("Your application did not unregister from D-Bus before destruction. " + "Consider using g_application_run()."); + } + + warned = TRUE; + } + + G_OBJECT_CLASS (g_application_parent_class)->dispose (object); +} + +static void +g_application_finalize (GObject *object) +{ + GApplication *application = G_APPLICATION (object); + + if (application->priv->inactivity_timeout_id) + g_source_remove (application->priv->inactivity_timeout_id); + + g_slist_free_full (application->priv->option_groups, (GDestroyNotify) g_option_group_unref); + if (application->priv->main_options) + g_option_group_unref (application->priv->main_options); + if (application->priv->packed_options) + g_hash_table_unref (application->priv->packed_options); + + g_free (application->priv->parameter_string); + g_free (application->priv->summary); + g_free (application->priv->description); + + g_slist_free_full (application->priv->option_strings, g_free); + + if (application->priv->impl) + g_application_impl_destroy (application->priv->impl); + g_free (application->priv->id); + + if (g_application_get_default () == application) + g_application_set_default (NULL); + + if (application->priv->actions) + g_object_unref (application->priv->actions); + + g_clear_object (&application->priv->remote_actions); + + if (application->priv->notifications) + g_object_unref (application->priv->notifications); + + g_free (application->priv->resource_path); + + G_OBJECT_CLASS (g_application_parent_class) + ->finalize (object); +} + +static void +g_application_init (GApplication *application) +{ + application->priv = g_application_get_instance_private (application); + + application->priv->actions = g_application_exported_actions_new (application); + + /* application->priv->actions is the one and only ref on the group, so when + * we dispose, the action group will die, disconnecting all signals. + */ + g_signal_connect_swapped (application->priv->actions, "action-added", + G_CALLBACK (g_action_group_action_added), application); + g_signal_connect_swapped (application->priv->actions, "action-enabled-changed", + G_CALLBACK (g_action_group_action_enabled_changed), application); + g_signal_connect_swapped (application->priv->actions, "action-state-changed", + G_CALLBACK (g_action_group_action_state_changed), application); + g_signal_connect_swapped (application->priv->actions, "action-removed", + G_CALLBACK (g_action_group_action_removed), application); +} + +static gboolean +g_application_handle_local_options_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + gint value; + + value = g_value_get_int (handler_return); + g_value_set_int (return_accu, value); + + return value < 0; +} + +static void +g_application_class_init (GApplicationClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->constructed = g_application_constructed; + object_class->dispose = g_application_dispose; + object_class->finalize = g_application_finalize; + object_class->get_property = g_application_get_property; + object_class->set_property = g_application_set_property; + + class->before_emit = g_application_real_before_emit; + class->after_emit = g_application_real_after_emit; + class->startup = g_application_real_startup; + class->shutdown = g_application_real_shutdown; + class->activate = g_application_real_activate; + class->open = g_application_real_open; + class->command_line = g_application_real_command_line; + class->local_command_line = g_application_real_local_command_line; + class->handle_local_options = g_application_real_handle_local_options; + class->add_platform_data = g_application_real_add_platform_data; + class->dbus_register = g_application_real_dbus_register; + class->dbus_unregister = g_application_real_dbus_unregister; + class->name_lost = g_application_real_name_lost; + + g_object_class_install_property (object_class, PROP_APPLICATION_ID, + g_param_spec_string ("application-id", + P_("Application identifier"), + P_("The unique identifier for the application"), + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_FLAGS, + g_param_spec_flags ("flags", + P_("Application flags"), + P_("Flags specifying the behaviour of the application"), + G_TYPE_APPLICATION_FLAGS, G_APPLICATION_FLAGS_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_RESOURCE_BASE_PATH, + g_param_spec_string ("resource-base-path", + P_("Resource base path"), + P_("The base resource path for the application"), + NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_IS_REGISTERED, + g_param_spec_boolean ("is-registered", + P_("Is registered"), + P_("If g_application_register() has been called"), + FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_IS_REMOTE, + g_param_spec_boolean ("is-remote", + P_("Is remote"), + P_("If this application instance is remote"), + FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_INACTIVITY_TIMEOUT, + g_param_spec_uint ("inactivity-timeout", + P_("Inactivity timeout"), + P_("Time (ms) to stay alive after becoming idle"), + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_ACTION_GROUP, + g_param_spec_object ("action-group", + P_("Action group"), + P_("The group of actions that the application exports"), + G_TYPE_ACTION_GROUP, + G_PARAM_DEPRECATED | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + + /** + * GApplication:is-busy: + * + * Whether the application is currently marked as busy through + * g_application_mark_busy() or g_application_bind_busy_property(). + * + * Since: 2.44 + */ + g_object_class_install_property (object_class, PROP_IS_BUSY, + g_param_spec_boolean ("is-busy", + P_("Is busy"), + P_("If this application is currently marked busy"), + FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + /** + * GApplication::startup: + * @application: the application + * + * The ::startup signal is emitted on the primary instance immediately + * after registration. See g_application_register(). + */ + g_application_signals[SIGNAL_STARTUP] = + g_signal_new (I_("startup"), G_TYPE_APPLICATION, G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GApplicationClass, startup), + NULL, NULL, NULL, G_TYPE_NONE, 0); + + /** + * GApplication::shutdown: + * @application: the application + * + * The ::shutdown signal is emitted only on the registered primary instance + * immediately after the main loop terminates. + */ + g_application_signals[SIGNAL_SHUTDOWN] = + g_signal_new (I_("shutdown"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, shutdown), + NULL, NULL, NULL, G_TYPE_NONE, 0); + + /** + * GApplication::activate: + * @application: the application + * + * The ::activate signal is emitted on the primary instance when an + * activation occurs. See g_application_activate(). + */ + g_application_signals[SIGNAL_ACTIVATE] = + g_signal_new (I_("activate"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, activate), + NULL, NULL, NULL, G_TYPE_NONE, 0); + + + /** + * GApplication::open: + * @application: the application + * @files: (array length=n_files) (element-type GFile): an array of #GFiles + * @n_files: the length of @files + * @hint: a hint provided by the calling instance + * + * The ::open signal is emitted on the primary instance when there are + * files to open. See g_application_open() for more information. + */ + g_application_signals[SIGNAL_OPEN] = + g_signal_new (I_("open"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, open), + NULL, NULL, + _g_cclosure_marshal_VOID__POINTER_INT_STRING, + G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_STRING); + g_signal_set_va_marshaller (g_application_signals[SIGNAL_OPEN], + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_VOID__POINTER_INT_STRINGv); + + /** + * GApplication::command-line: + * @application: the application + * @command_line: a #GApplicationCommandLine representing the + * passed commandline + * + * The ::command-line signal is emitted on the primary instance when + * a commandline is not handled locally. See g_application_run() and + * the #GApplicationCommandLine documentation for more information. + * + * Returns: An integer that is set as the exit status for the calling + * process. See g_application_command_line_set_exit_status(). + */ + g_application_signals[SIGNAL_COMMAND_LINE] = + g_signal_new (I_("command-line"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, command_line), + g_signal_accumulator_first_wins, NULL, + _g_cclosure_marshal_INT__OBJECT, + G_TYPE_INT, 1, G_TYPE_APPLICATION_COMMAND_LINE); + g_signal_set_va_marshaller (g_application_signals[SIGNAL_COMMAND_LINE], + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_INT__OBJECTv); + + /** + * GApplication::handle-local-options: + * @application: the application + * @options: the options dictionary + * + * The ::handle-local-options signal is emitted on the local instance + * after the parsing of the commandline options has occurred. + * + * You can add options to be recognised during commandline option + * parsing using g_application_add_main_option_entries() and + * g_application_add_option_group(). + * + * Signal handlers can inspect @options (along with values pointed to + * from the @arg_data of an installed #GOptionEntrys) in order to + * decide to perform certain actions, including direct local handling + * (which may be useful for options like --version). + * + * In the event that the application is marked + * %G_APPLICATION_HANDLES_COMMAND_LINE the "normal processing" will + * send the @options dictionary to the primary instance where it can be + * read with g_application_command_line_get_options_dict(). The signal + * handler can modify the dictionary before returning, and the + * modified dictionary will be sent. + * + * In the event that %G_APPLICATION_HANDLES_COMMAND_LINE is not set, + * "normal processing" will treat the remaining uncollected command + * line arguments as filenames or URIs. If there are no arguments, + * the application is activated by g_application_activate(). One or + * more arguments results in a call to g_application_open(). + * + * If you want to handle the local commandline arguments for yourself + * by converting them to calls to g_application_open() or + * g_action_group_activate_action() then you must be sure to register + * the application first. You should probably not call + * g_application_activate() for yourself, however: just return -1 and + * allow the default handler to do it for you. This will ensure that + * the `--gapplication-service` switch works properly (i.e. no activation + * in that case). + * + * Note that this signal is emitted from the default implementation of + * local_command_line(). If you override that function and don't + * chain up then this signal will never be emitted. + * + * You can override local_command_line() if you need more powerful + * capabilities than what is provided here, but this should not + * normally be required. + * + * Returns: an exit code. If you have handled your options and want + * to exit the process, return a non-negative option, 0 for success, + * and a positive value for failure. To continue, return -1 to let + * the default option processing continue. + * + * Since: 2.40 + **/ + g_application_signals[SIGNAL_HANDLE_LOCAL_OPTIONS] = + g_signal_new (I_("handle-local-options"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, handle_local_options), + g_application_handle_local_options_accumulator, NULL, + _g_cclosure_marshal_INT__BOXED, + G_TYPE_INT, 1, G_TYPE_VARIANT_DICT); + g_signal_set_va_marshaller (g_application_signals[SIGNAL_HANDLE_LOCAL_OPTIONS], + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_INT__BOXEDv); + + /** + * GApplication::name-lost: + * @application: the application + * + * The ::name-lost signal is emitted only on the registered primary instance + * when a new instance has taken over. This can only happen if the application + * is using the %G_APPLICATION_ALLOW_REPLACEMENT flag. + * + * The default handler for this signal calls g_application_quit(). + * + * Returns: %TRUE if the signal has been handled + * + * Since: 2.60 + */ + g_application_signals[SIGNAL_NAME_LOST] = + g_signal_new (I_("name-lost"), G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, name_lost), + g_signal_accumulator_true_handled, NULL, + _g_cclosure_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, 0); + g_signal_set_va_marshaller (g_application_signals[SIGNAL_NAME_LOST], + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_BOOLEAN__VOIDv); +} + +/* Application ID validity {{{1 */ + +/** + * g_application_id_is_valid: + * @application_id: a potential application identifier + * + * Checks if @application_id is a valid application identifier. + * + * A valid ID is required for calls to g_application_new() and + * g_application_set_application_id(). + * + * Application identifiers follow the same format as + * [D-Bus well-known bus names](https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus). + * For convenience, the restrictions on application identifiers are + * reproduced here: + * + * - Application identifiers are composed of 1 or more elements separated by a + * period (`.`) character. All elements must contain at least one character. + * + * - Each element must only contain the ASCII characters `[A-Z][a-z][0-9]_-`, + * with `-` discouraged in new application identifiers. Each element must not + * begin with a digit. + * + * - Application identifiers must contain at least one `.` (period) character + * (and thus at least two elements). + * + * - Application identifiers must not begin with a `.` (period) character. + * + * - Application identifiers must not exceed 255 characters. + * + * Note that the hyphen (`-`) character is allowed in application identifiers, + * but is problematic or not allowed in various specifications and APIs that + * refer to D-Bus, such as + * [Flatpak application IDs](http://docs.flatpak.org/en/latest/introduction.html#identifiers), + * the + * [`DBusActivatable` interface in the Desktop Entry Specification](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#dbus), + * and the convention that an application's "main" interface and object path + * resemble its application identifier and bus name. To avoid situations that + * require special-case handling, it is recommended that new application + * identifiers consistently replace hyphens with underscores. + * + * Like D-Bus interface names, application identifiers should start with the + * reversed DNS domain name of the author of the interface (in lower-case), and + * it is conventional for the rest of the application identifier to consist of + * words run together, with initial capital letters. + * + * As with D-Bus interface names, if the author's DNS domain name contains + * hyphen/minus characters they should be replaced by underscores, and if it + * contains leading digits they should be escaped by prepending an underscore. + * For example, if the owner of 7-zip.org used an application identifier for an + * archiving application, it might be named `org._7_zip.Archiver`. + * + * Returns: %TRUE if @application_id is valid + */ +gboolean +g_application_id_is_valid (const gchar *application_id) +{ + return g_dbus_is_name (application_id) && + !g_dbus_is_unique_name (application_id); +} + +/* Public Constructor {{{1 */ +/** + * g_application_new: + * @application_id: (nullable): the application id + * @flags: the application flags + * + * Creates a new #GApplication instance. + * + * If non-%NULL, the application id must be valid. See + * g_application_id_is_valid(). + * + * If no application ID is given then some features of #GApplication + * (most notably application uniqueness) will be disabled. + * + * Returns: a new #GApplication instance + **/ +GApplication * +g_application_new (const gchar *application_id, + GApplicationFlags flags) +{ + g_return_val_if_fail (application_id == NULL || g_application_id_is_valid (application_id), NULL); + + return g_object_new (G_TYPE_APPLICATION, + "application-id", application_id, + "flags", flags, + NULL); +} + +/* Simple get/set: application id, flags, inactivity timeout {{{1 */ +/** + * g_application_get_application_id: + * @application: a #GApplication + * + * Gets the unique identifier for @application. + * + * Returns: (nullable): the identifier for @application, owned by @application + * + * Since: 2.28 + **/ +const gchar * +g_application_get_application_id (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), NULL); + + return application->priv->id; +} + +/** + * g_application_set_application_id: + * @application: a #GApplication + * @application_id: (nullable): the identifier for @application + * + * Sets the unique identifier for @application. + * + * The application id can only be modified if @application has not yet + * been registered. + * + * If non-%NULL, the application id must be valid. See + * g_application_id_is_valid(). + * + * Since: 2.28 + **/ +void +g_application_set_application_id (GApplication *application, + const gchar *application_id) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + + if (g_strcmp0 (application->priv->id, application_id) != 0) + { + g_return_if_fail (application_id == NULL || g_application_id_is_valid (application_id)); + g_return_if_fail (!application->priv->is_registered); + + g_free (application->priv->id); + application->priv->id = g_strdup (application_id); + + g_object_notify (G_OBJECT (application), "application-id"); + } +} + +/** + * g_application_get_flags: + * @application: a #GApplication + * + * Gets the flags for @application. + * + * See #GApplicationFlags. + * + * Returns: the flags for @application + * + * Since: 2.28 + **/ +GApplicationFlags +g_application_get_flags (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), 0); + + return application->priv->flags; +} + +/** + * g_application_set_flags: + * @application: a #GApplication + * @flags: the flags for @application + * + * Sets the flags for @application. + * + * The flags can only be modified if @application has not yet been + * registered. + * + * See #GApplicationFlags. + * + * Since: 2.28 + **/ +void +g_application_set_flags (GApplication *application, + GApplicationFlags flags) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + + if (application->priv->flags != flags) + { + g_return_if_fail (!application->priv->is_registered); + + application->priv->flags = flags; + + g_object_notify (G_OBJECT (application), "flags"); + } +} + +/** + * g_application_get_resource_base_path: + * @application: a #GApplication + * + * Gets the resource base path of @application. + * + * See g_application_set_resource_base_path() for more information. + * + * Returns: (nullable): the base resource path, if one is set + * + * Since: 2.42 + */ +const gchar * +g_application_get_resource_base_path (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), NULL); + + return application->priv->resource_path; +} + +/** + * g_application_set_resource_base_path: + * @application: a #GApplication + * @resource_path: (nullable): the resource path to use + * + * Sets (or unsets) the base resource path of @application. + * + * The path is used to automatically load various [application + * resources][gresource] such as menu layouts and action descriptions. + * The various types of resources will be found at fixed names relative + * to the given base path. + * + * By default, the resource base path is determined from the application + * ID by prefixing '/' and replacing each '.' with '/'. This is done at + * the time that the #GApplication object is constructed. Changes to + * the application ID after that point will not have an impact on the + * resource base path. + * + * As an example, if the application has an ID of "org.example.app" then + * the default resource base path will be "/org/example/app". If this + * is a #GtkApplication (and you have not manually changed the path) + * then Gtk will then search for the menus of the application at + * "/org/example/app/gtk/menus.ui". + * + * See #GResource for more information about adding resources to your + * application. + * + * You can disable automatic resource loading functionality by setting + * the path to %NULL. + * + * Changing the resource base path once the application is running is + * not recommended. The point at which the resource path is consulted + * for forming paths for various purposes is unspecified. When writing + * a sub-class of #GApplication you should either set the + * #GApplication:resource-base-path property at construction time, or call + * this function during the instance initialization. Alternatively, you + * can call this function in the #GApplicationClass.startup virtual function, + * before chaining up to the parent implementation. + * + * Since: 2.42 + */ +void +g_application_set_resource_base_path (GApplication *application, + const gchar *resource_path) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (resource_path == NULL || g_str_has_prefix (resource_path, "/")); + + if (g_strcmp0 (application->priv->resource_path, resource_path) != 0) + { + g_free (application->priv->resource_path); + + application->priv->resource_path = g_strdup (resource_path); + + g_object_notify (G_OBJECT (application), "resource-base-path"); + } +} + +/** + * g_application_get_inactivity_timeout: + * @application: a #GApplication + * + * Gets the current inactivity timeout for the application. + * + * This is the amount of time (in milliseconds) after the last call to + * g_application_release() before the application stops running. + * + * Returns: the timeout, in milliseconds + * + * Since: 2.28 + **/ +guint +g_application_get_inactivity_timeout (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), 0); + + return application->priv->inactivity_timeout; +} + +/** + * g_application_set_inactivity_timeout: + * @application: a #GApplication + * @inactivity_timeout: the timeout, in milliseconds + * + * Sets the current inactivity timeout for the application. + * + * This is the amount of time (in milliseconds) after the last call to + * g_application_release() before the application stops running. + * + * This call has no side effects of its own. The value set here is only + * used for next time g_application_release() drops the use count to + * zero. Any timeouts currently in progress are not impacted. + * + * Since: 2.28 + **/ +void +g_application_set_inactivity_timeout (GApplication *application, + guint inactivity_timeout) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + + if (application->priv->inactivity_timeout != inactivity_timeout) + { + application->priv->inactivity_timeout = inactivity_timeout; + + g_object_notify (G_OBJECT (application), "inactivity-timeout"); + } +} +/* Read-only property getters (is registered, is remote, dbus stuff) {{{1 */ +/** + * g_application_get_is_registered: + * @application: a #GApplication + * + * Checks if @application is registered. + * + * An application is registered if g_application_register() has been + * successfully called. + * + * Returns: %TRUE if @application is registered + * + * Since: 2.28 + **/ +gboolean +g_application_get_is_registered (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), FALSE); + + return application->priv->is_registered; +} + +/** + * g_application_get_is_remote: + * @application: a #GApplication + * + * Checks if @application is remote. + * + * If @application is remote then it means that another instance of + * application already exists (the 'primary' instance). Calls to + * perform actions on @application will result in the actions being + * performed by the primary instance. + * + * The value of this property cannot be accessed before + * g_application_register() has been called. See + * g_application_get_is_registered(). + * + * Returns: %TRUE if @application is remote + * + * Since: 2.28 + **/ +gboolean +g_application_get_is_remote (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), FALSE); + g_return_val_if_fail (application->priv->is_registered, FALSE); + + return application->priv->is_remote; +} + +/** + * g_application_get_dbus_connection: + * @application: a #GApplication + * + * Gets the #GDBusConnection being used by the application, or %NULL. + * + * If #GApplication is using its D-Bus backend then this function will + * return the #GDBusConnection being used for uniqueness and + * communication with the desktop environment and other instances of the + * application. + * + * If #GApplication is not using D-Bus then this function will return + * %NULL. This includes the situation where the D-Bus backend would + * normally be in use but we were unable to connect to the bus. + * + * This function must not be called before the application has been + * registered. See g_application_get_is_registered(). + * + * Returns: (nullable) (transfer none): a #GDBusConnection, or %NULL + * + * Since: 2.34 + **/ +GDBusConnection * +g_application_get_dbus_connection (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), FALSE); + g_return_val_if_fail (application->priv->is_registered, FALSE); + + return g_application_impl_get_dbus_connection (application->priv->impl); +} + +/** + * g_application_get_dbus_object_path: + * @application: a #GApplication + * + * Gets the D-Bus object path being used by the application, or %NULL. + * + * If #GApplication is using its D-Bus backend then this function will + * return the D-Bus object path that #GApplication is using. If the + * application is the primary instance then there is an object published + * at this path. If the application is not the primary instance then + * the result of this function is undefined. + * + * If #GApplication is not using D-Bus then this function will return + * %NULL. This includes the situation where the D-Bus backend would + * normally be in use but we were unable to connect to the bus. + * + * This function must not be called before the application has been + * registered. See g_application_get_is_registered(). + * + * Returns: (nullable): the object path, or %NULL + * + * Since: 2.34 + **/ +const gchar * +g_application_get_dbus_object_path (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), FALSE); + g_return_val_if_fail (application->priv->is_registered, FALSE); + + return g_application_impl_get_dbus_object_path (application->priv->impl); +} + + +/* Register {{{1 */ +/** + * g_application_register: + * @application: a #GApplication + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a pointer to a NULL #GError, or %NULL + * + * Attempts registration of the application. + * + * This is the point at which the application discovers if it is the + * primary instance or merely acting as a remote for an already-existing + * primary instance. This is implemented by attempting to acquire the + * application identifier as a unique bus name on the session bus using + * GDBus. + * + * If there is no application ID or if %G_APPLICATION_NON_UNIQUE was + * given, then this process will always become the primary instance. + * + * Due to the internal architecture of GDBus, method calls can be + * dispatched at any time (even if a main loop is not running). For + * this reason, you must ensure that any object paths that you wish to + * register are registered before calling this function. + * + * If the application has already been registered then %TRUE is + * returned with no work performed. + * + * The #GApplication::startup signal is emitted if registration succeeds + * and @application is the primary instance (including the non-unique + * case). + * + * In the event of an error (such as @cancellable being cancelled, or a + * failure to connect to the session bus), %FALSE is returned and @error + * is set appropriately. + * + * Note: the return value of this function is not an indicator that this + * instance is or is not the primary instance of the application. See + * g_application_get_is_remote() for that. + * + * Returns: %TRUE if registration succeeded + * + * Since: 2.28 + **/ +gboolean +g_application_register (GApplication *application, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), FALSE); + + if (!application->priv->is_registered) + { + if (application->priv->id == NULL) + application->priv->flags |= G_APPLICATION_NON_UNIQUE; + + application->priv->impl = + g_application_impl_register (application, application->priv->id, + application->priv->flags, + application->priv->actions, + &application->priv->remote_actions, + cancellable, error); + + if (application->priv->impl == NULL) + return FALSE; + + application->priv->is_remote = application->priv->remote_actions != NULL; + application->priv->is_registered = TRUE; + + g_object_notify (G_OBJECT (application), "is-registered"); + + if (!application->priv->is_remote) + { + g_signal_emit (application, g_application_signals[SIGNAL_STARTUP], 0); + + if (!application->priv->did_startup) + g_critical ("GApplication subclass '%s' failed to chain up on" + " ::startup (from start of override function)", + G_OBJECT_TYPE_NAME (application)); + } + } + + return TRUE; +} + +/* Hold/release {{{1 */ +/** + * g_application_hold: + * @application: a #GApplication + * + * Increases the use count of @application. + * + * Use this function to indicate that the application has a reason to + * continue to run. For example, g_application_hold() is called by GTK+ + * when a toplevel window is on the screen. + * + * To cancel the hold, call g_application_release(). + **/ +void +g_application_hold (GApplication *application) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + + if (application->priv->inactivity_timeout_id) + { + g_source_remove (application->priv->inactivity_timeout_id); + application->priv->inactivity_timeout_id = 0; + } + + application->priv->use_count++; +} + +static gboolean +inactivity_timeout_expired (gpointer data) +{ + GApplication *application = G_APPLICATION (data); + + application->priv->inactivity_timeout_id = 0; + + return G_SOURCE_REMOVE; +} + + +/** + * g_application_release: + * @application: a #GApplication + * + * Decrease the use count of @application. + * + * When the use count reaches zero, the application will stop running. + * + * Never call this function except to cancel the effect of a previous + * call to g_application_hold(). + **/ +void +g_application_release (GApplication *application) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (application->priv->use_count > 0); + + application->priv->use_count--; + + if (application->priv->use_count == 0 && application->priv->inactivity_timeout) + application->priv->inactivity_timeout_id = g_timeout_add (application->priv->inactivity_timeout, + inactivity_timeout_expired, application); +} + +/* Activate, Open {{{1 */ +/** + * g_application_activate: + * @application: a #GApplication + * + * Activates the application. + * + * In essence, this results in the #GApplication::activate signal being + * emitted in the primary instance. + * + * The application must be registered before calling this function. + * + * Since: 2.28 + **/ +void +g_application_activate (GApplication *application) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (application->priv->is_registered); + + if (application->priv->is_remote) + g_application_impl_activate (application->priv->impl, + get_platform_data (application, NULL)); + + else + g_signal_emit (application, g_application_signals[SIGNAL_ACTIVATE], 0); +} + +/** + * g_application_open: + * @application: a #GApplication + * @files: (array length=n_files): an array of #GFiles to open + * @n_files: the length of the @files array + * @hint: a hint (or ""), but never %NULL + * + * Opens the given files. + * + * In essence, this results in the #GApplication::open signal being emitted + * in the primary instance. + * + * @n_files must be greater than zero. + * + * @hint is simply passed through to the ::open signal. It is + * intended to be used by applications that have multiple modes for + * opening files (eg: "view" vs "edit", etc). Unless you have a need + * for this functionality, you should use "". + * + * The application must be registered before calling this function + * and it must have the %G_APPLICATION_HANDLES_OPEN flag set. + * + * Since: 2.28 + **/ +void +g_application_open (GApplication *application, + GFile **files, + gint n_files, + const gchar *hint) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (application->priv->flags & + G_APPLICATION_HANDLES_OPEN); + g_return_if_fail (application->priv->is_registered); + + if (application->priv->is_remote) + g_application_impl_open (application->priv->impl, + files, n_files, hint, + get_platform_data (application, NULL)); + + else + g_signal_emit (application, g_application_signals[SIGNAL_OPEN], + 0, files, n_files, hint); +} + +/* Run {{{1 */ +/** + * g_application_run: + * @application: a #GApplication + * @argc: the argc from main() (or 0 if @argv is %NULL) + * @argv: (array length=argc) (element-type filename) (nullable): + * the argv from main(), or %NULL + * + * Runs the application. + * + * This function is intended to be run from main() and its return value + * is intended to be returned by main(). Although you are expected to pass + * the @argc, @argv parameters from main() to this function, it is possible + * to pass %NULL if @argv is not available or commandline handling is not + * required. Note that on Windows, @argc and @argv are ignored, and + * g_win32_get_command_line() is called internally (for proper support + * of Unicode commandline arguments). + * + * #GApplication will attempt to parse the commandline arguments. You + * can add commandline flags to the list of recognised options by way of + * g_application_add_main_option_entries(). After this, the + * #GApplication::handle-local-options signal is emitted, from which the + * application can inspect the values of its #GOptionEntrys. + * + * #GApplication::handle-local-options is a good place to handle options + * such as `--version`, where an immediate reply from the local process is + * desired (instead of communicating with an already-running instance). + * A #GApplication::handle-local-options handler can stop further processing + * by returning a non-negative value, which then becomes the exit status of + * the process. + * + * What happens next depends on the flags: if + * %G_APPLICATION_HANDLES_COMMAND_LINE was specified then the remaining + * commandline arguments are sent to the primary instance, where a + * #GApplication::command-line signal is emitted. Otherwise, the + * remaining commandline arguments are assumed to be a list of files. + * If there are no files listed, the application is activated via the + * #GApplication::activate signal. If there are one or more files, and + * %G_APPLICATION_HANDLES_OPEN was specified then the files are opened + * via the #GApplication::open signal. + * + * If you are interested in doing more complicated local handling of the + * commandline then you should implement your own #GApplication subclass + * and override local_command_line(). In this case, you most likely want + * to return %TRUE from your local_command_line() implementation to + * suppress the default handling. See + * [gapplication-example-cmdline2.c][https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-cmdline2.c] + * for an example. + * + * If, after the above is done, the use count of the application is zero + * then the exit status is returned immediately. If the use count is + * non-zero then the default main context is iterated until the use count + * falls to zero, at which point 0 is returned. + * + * If the %G_APPLICATION_IS_SERVICE flag is set, then the service will + * run for as much as 10 seconds with a use count of zero while waiting + * for the message that caused the activation to arrive. After that, + * if the use count falls to zero the application will exit immediately, + * except in the case that g_application_set_inactivity_timeout() is in + * use. + * + * This function sets the prgname (g_set_prgname()), if not already set, + * to the basename of argv[0]. + * + * Much like g_main_loop_run(), this function will acquire the main context + * for the duration that the application is running. + * + * Since 2.40, applications that are not explicitly flagged as services + * or launchers (ie: neither %G_APPLICATION_IS_SERVICE or + * %G_APPLICATION_IS_LAUNCHER are given as flags) will check (from the + * default handler for local_command_line) if "--gapplication-service" + * was given in the command line. If this flag is present then normal + * commandline processing is interrupted and the + * %G_APPLICATION_IS_SERVICE flag is set. This provides a "compromise" + * solution whereby running an application directly from the commandline + * will invoke it in the normal way (which can be useful for debugging) + * while still allowing applications to be D-Bus activated in service + * mode. The D-Bus service file should invoke the executable with + * "--gapplication-service" as the sole commandline argument. This + * approach is suitable for use by most graphical applications but + * should not be used from applications like editors that need precise + * control over when processes invoked via the commandline will exit and + * what their exit status will be. + * + * Returns: the exit status + * + * Since: 2.28 + **/ +int +g_application_run (GApplication *application, + int argc, + char **argv) +{ + gchar **arguments; + int status; + GMainContext *context; + gboolean acquired_context; + + g_return_val_if_fail (G_IS_APPLICATION (application), 1); + g_return_val_if_fail (argc == 0 || argv != NULL, 1); + g_return_val_if_fail (!application->priv->must_quit_now, 1); + +#ifdef G_OS_WIN32 + { + gint new_argc = 0; + + arguments = g_win32_get_command_line (); + + /* + * CommandLineToArgvW(), which is called by g_win32_get_command_line(), + * pulls in the whole command line that is used to call the program. This is + * fine in cases where the program is a .exe program, but in the cases where the + * program is a called via a script, such as PyGObject's gtk-demo.py, which is normally + * called using 'python gtk-demo.py' on Windows, the program name (argv[0]) + * returned by g_win32_get_command_line() will not be the argv[0] that ->local_command_line() + * would expect, causing the program to fail with "This application can not open files." + */ + new_argc = g_strv_length (arguments); + + if (new_argc > argc) + { + gint i; + + for (i = 0; i < new_argc - argc; i++) + g_free (arguments[i]); + + memmove (&arguments[0], + &arguments[new_argc - argc], + sizeof (arguments[0]) * (argc + 1)); + } + } +#elif defined(__APPLE__) + { + gint i, j; + + /* + * OSX adds an unexpected parameter on the format -psn_X_XXXXXX + * when opening the application using Launch Services. In order + * to avoid that GOption fails to parse this parameter we just + * skip it if it was provided. + * See: https://gitlab.gnome.org/GNOME/glib/issues/1784 + */ + arguments = g_new (gchar *, argc + 1); + for (i = 0, j = 0; i < argc; i++) + { + if (!g_str_has_prefix (argv[i], "-psn_")) + { + arguments[j] = g_strdup (argv[i]); + j++; + } + } + arguments[j] = NULL; + } +#else + { + gint i; + + arguments = g_new (gchar *, argc + 1); + for (i = 0; i < argc; i++) + arguments[i] = g_strdup (argv[i]); + arguments[i] = NULL; + } +#endif + + if (g_get_prgname () == NULL && argc > 0) + { + gchar *prgname; + + prgname = g_path_get_basename (argv[0]); + g_set_prgname (prgname); + g_free (prgname); + } + + context = g_main_context_default (); + acquired_context = g_main_context_acquire (context); + if (!acquired_context) + { + g_critical ("g_application_run() cannot acquire the default main context because it is already acquired by another thread!"); + g_strfreev (arguments); + return 1; + } + + if (!G_APPLICATION_GET_CLASS (application) + ->local_command_line (application, &arguments, &status)) + { + GError *error = NULL; + + if (!g_application_register (application, NULL, &error)) + { + g_printerr ("Failed to register: %s\n", error->message); + g_error_free (error); + return 1; + } + + g_application_call_command_line (application, (const gchar **) arguments, NULL, &status); + } + + g_strfreev (arguments); + + if (application->priv->flags & G_APPLICATION_IS_SERVICE && + application->priv->is_registered && + !application->priv->use_count && + !application->priv->inactivity_timeout_id) + { + application->priv->inactivity_timeout_id = + g_timeout_add (10000, inactivity_timeout_expired, application); + } + + while (application->priv->use_count || application->priv->inactivity_timeout_id) + { + if (application->priv->must_quit_now) + break; + + g_main_context_iteration (context, TRUE); + status = 0; + } + + if (application->priv->is_registered && !application->priv->is_remote) + { + g_signal_emit (application, g_application_signals[SIGNAL_SHUTDOWN], 0); + + if (!application->priv->did_shutdown) + g_critical ("GApplication subclass '%s' failed to chain up on" + " ::shutdown (from end of override function)", + G_OBJECT_TYPE_NAME (application)); + } + + if (application->priv->impl) + { + if (application->priv->is_registered) + { + application->priv->is_registered = FALSE; + + g_object_notify (G_OBJECT (application), "is-registered"); + } + + g_application_impl_flush (application->priv->impl); + g_application_impl_destroy (application->priv->impl); + application->priv->impl = NULL; + } + + g_settings_sync (); + + if (!application->priv->must_quit_now) + while (g_main_context_iteration (context, FALSE)) + ; + + g_main_context_release (context); + + return status; +} + +static gchar ** +g_application_list_actions (GActionGroup *action_group) +{ + GApplication *application = G_APPLICATION (action_group); + + g_return_val_if_fail (application->priv->is_registered, NULL); + + if (application->priv->remote_actions != NULL) + return g_action_group_list_actions (G_ACTION_GROUP (application->priv->remote_actions)); + + else if (application->priv->actions != NULL) + return g_action_group_list_actions (application->priv->actions); + + else + /* empty string array */ + return g_new0 (gchar *, 1); +} + +static gboolean +g_application_query_action (GActionGroup *group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state) +{ + GApplication *application = G_APPLICATION (group); + + g_return_val_if_fail (application->priv->is_registered, FALSE); + + if (application->priv->remote_actions != NULL) + return g_action_group_query_action (G_ACTION_GROUP (application->priv->remote_actions), + action_name, + enabled, + parameter_type, + state_type, + state_hint, + state); + + if (application->priv->actions != NULL) + return g_action_group_query_action (application->priv->actions, + action_name, + enabled, + parameter_type, + state_type, + state_hint, + state); + + return FALSE; +} + +static void +g_application_change_action_state (GActionGroup *action_group, + const gchar *action_name, + GVariant *value) +{ + GApplication *application = G_APPLICATION (action_group); + + g_return_if_fail (application->priv->is_remote || + application->priv->actions != NULL); + g_return_if_fail (application->priv->is_registered); + + if (application->priv->remote_actions) + g_remote_action_group_change_action_state_full (application->priv->remote_actions, + action_name, value, get_platform_data (application, NULL)); + + else + g_action_group_change_action_state (application->priv->actions, action_name, value); +} + +static void +g_application_activate_action (GActionGroup *action_group, + const gchar *action_name, + GVariant *parameter) +{ + GApplication *application = G_APPLICATION (action_group); + + g_return_if_fail (application->priv->is_remote || + application->priv->actions != NULL); + g_return_if_fail (application->priv->is_registered); + + if (application->priv->remote_actions) + g_remote_action_group_activate_action_full (application->priv->remote_actions, + action_name, parameter, get_platform_data (application, NULL)); + + else + g_action_group_activate_action (application->priv->actions, action_name, parameter); +} + +static GAction * +g_application_lookup_action (GActionMap *action_map, + const gchar *action_name) +{ + GApplication *application = G_APPLICATION (action_map); + + g_return_val_if_fail (G_IS_ACTION_MAP (application->priv->actions), NULL); + + return g_action_map_lookup_action (G_ACTION_MAP (application->priv->actions), action_name); +} + +static void +g_application_add_action (GActionMap *action_map, + GAction *action) +{ + GApplication *application = G_APPLICATION (action_map); + + g_return_if_fail (G_IS_ACTION_MAP (application->priv->actions)); + + g_action_map_add_action (G_ACTION_MAP (application->priv->actions), action); +} + +static void +g_application_remove_action (GActionMap *action_map, + const gchar *action_name) +{ + GApplication *application = G_APPLICATION (action_map); + + g_return_if_fail (G_IS_ACTION_MAP (application->priv->actions)); + + g_action_map_remove_action (G_ACTION_MAP (application->priv->actions), action_name); +} + +static void +g_application_action_group_iface_init (GActionGroupInterface *iface) +{ + iface->list_actions = g_application_list_actions; + iface->query_action = g_application_query_action; + iface->change_action_state = g_application_change_action_state; + iface->activate_action = g_application_activate_action; +} + +static void +g_application_action_map_iface_init (GActionMapInterface *iface) +{ + iface->lookup_action = g_application_lookup_action; + iface->add_action = g_application_add_action; + iface->remove_action = g_application_remove_action; +} + +/* Default Application {{{1 */ + +static GApplication *default_app; + +/** + * g_application_get_default: + * + * Returns the default #GApplication instance for this process. + * + * Normally there is only one #GApplication per process and it becomes + * the default when it is created. You can exercise more control over + * this by using g_application_set_default(). + * + * If there is no default application then %NULL is returned. + * + * Returns: (nullable) (transfer none): the default application for this process, or %NULL + * + * Since: 2.32 + **/ +GApplication * +g_application_get_default (void) +{ + return default_app; +} + +/** + * g_application_set_default: + * @application: (nullable): the application to set as default, or %NULL + * + * Sets or unsets the default application for the process, as returned + * by g_application_get_default(). + * + * This function does not take its own reference on @application. If + * @application is destroyed then the default application will revert + * back to %NULL. + * + * Since: 2.32 + **/ +void +g_application_set_default (GApplication *application) +{ + default_app = application; +} + +/** + * g_application_quit: + * @application: a #GApplication + * + * Immediately quits the application. + * + * Upon return to the mainloop, g_application_run() will return, + * calling only the 'shutdown' function before doing so. + * + * The hold count is ignored. + * Take care if your code has called g_application_hold() on the application and + * is therefore still expecting it to exist. + * (Note that you may have called g_application_hold() indirectly, for example + * through gtk_application_add_window().) + * + * The result of calling g_application_run() again after it returns is + * unspecified. + * + * Since: 2.32 + **/ +void +g_application_quit (GApplication *application) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + + application->priv->must_quit_now = TRUE; +} + +/** + * g_application_mark_busy: + * @application: a #GApplication + * + * Increases the busy count of @application. + * + * Use this function to indicate that the application is busy, for instance + * while a long running operation is pending. + * + * The busy state will be exposed to other processes, so a session shell will + * use that information to indicate the state to the user (e.g. with a + * spinner). + * + * To cancel the busy indication, use g_application_unmark_busy(). + * + * The application must be registered before calling this function. + * + * Since: 2.38 + **/ +void +g_application_mark_busy (GApplication *application) +{ + gboolean was_busy; + + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (application->priv->is_registered); + + was_busy = (application->priv->busy_count > 0); + application->priv->busy_count++; + + if (!was_busy) + { + g_application_impl_set_busy_state (application->priv->impl, TRUE); + g_object_notify (G_OBJECT (application), "is-busy"); + } +} + +/** + * g_application_unmark_busy: + * @application: a #GApplication + * + * Decreases the busy count of @application. + * + * When the busy count reaches zero, the new state will be propagated + * to other processes. + * + * This function must only be called to cancel the effect of a previous + * call to g_application_mark_busy(). + * + * Since: 2.38 + **/ +void +g_application_unmark_busy (GApplication *application) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (application->priv->busy_count > 0); + + application->priv->busy_count--; + + if (application->priv->busy_count == 0) + { + g_application_impl_set_busy_state (application->priv->impl, FALSE); + g_object_notify (G_OBJECT (application), "is-busy"); + } +} + +/** + * g_application_get_is_busy: + * @application: a #GApplication + * + * Gets the application's current busy state, as set through + * g_application_mark_busy() or g_application_bind_busy_property(). + * + * Returns: %TRUE if @application is currently marked as busy + * + * Since: 2.44 + */ +gboolean +g_application_get_is_busy (GApplication *application) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), FALSE); + + return application->priv->busy_count > 0; +} + +/* Notifications {{{1 */ + +/** + * g_application_send_notification: + * @application: a #GApplication + * @id: (nullable): id of the notification, or %NULL + * @notification: the #GNotification to send + * + * Sends a notification on behalf of @application to the desktop shell. + * There is no guarantee that the notification is displayed immediately, + * or even at all. + * + * Notifications may persist after the application exits. It will be + * D-Bus-activated when the notification or one of its actions is + * activated. + * + * Modifying @notification after this call has no effect. However, the + * object can be reused for a later call to this function. + * + * @id may be any string that uniquely identifies the event for the + * application. It does not need to be in any special format. For + * example, "new-message" might be appropriate for a notification about + * new messages. + * + * If a previous notification was sent with the same @id, it will be + * replaced with @notification and shown again as if it was a new + * notification. This works even for notifications sent from a previous + * execution of the application, as long as @id is the same string. + * + * @id may be %NULL, but it is impossible to replace or withdraw + * notifications without an id. + * + * If @notification is no longer relevant, it can be withdrawn with + * g_application_withdraw_notification(). + * + * Since: 2.40 + */ +void +g_application_send_notification (GApplication *application, + const gchar *id, + GNotification *notification) +{ + gchar *generated_id = NULL; + + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (G_IS_NOTIFICATION (notification)); + g_return_if_fail (g_application_get_is_registered (application)); + g_return_if_fail (!g_application_get_is_remote (application)); + + if (application->priv->notifications == NULL) + application->priv->notifications = g_notification_backend_new_default (application); + + if (id == NULL) + { + generated_id = g_dbus_generate_guid (); + id = generated_id; + } + + g_notification_backend_send_notification (application->priv->notifications, id, notification); + + g_free (generated_id); +} + +/** + * g_application_withdraw_notification: + * @application: a #GApplication + * @id: id of a previously sent notification + * + * Withdraws a notification that was sent with + * g_application_send_notification(). + * + * This call does nothing if a notification with @id doesn't exist or + * the notification was never sent. + * + * This function works even for notifications sent in previous + * executions of this application, as long @id is the same as it was for + * the sent notification. + * + * Note that notifications are dismissed when the user clicks on one + * of the buttons in a notification or triggers its default action, so + * there is no need to explicitly withdraw the notification in that case. + * + * Since: 2.40 + */ +void +g_application_withdraw_notification (GApplication *application, + const gchar *id) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (id != NULL); + + if (application->priv->notifications == NULL) + application->priv->notifications = g_notification_backend_new_default (application); + + g_notification_backend_withdraw_notification (application->priv->notifications, id); +} + +/* Busy binding {{{1 */ + +typedef struct +{ + GApplication *app; + gboolean is_busy; +} GApplicationBusyBinding; + +static void +g_application_busy_binding_destroy (gpointer data, + GClosure *closure) +{ + GApplicationBusyBinding *binding = data; + + if (binding->is_busy) + g_application_unmark_busy (binding->app); + + g_object_unref (binding->app); + g_slice_free (GApplicationBusyBinding, binding); +} + +static void +g_application_notify_busy_binding (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + GApplicationBusyBinding *binding = user_data; + gboolean is_busy; + + g_object_get (object, pspec->name, &is_busy, NULL); + + if (is_busy && !binding->is_busy) + g_application_mark_busy (binding->app); + else if (!is_busy && binding->is_busy) + g_application_unmark_busy (binding->app); + + binding->is_busy = is_busy; +} + +/** + * g_application_bind_busy_property: + * @application: a #GApplication + * @object: (type GObject.Object): a #GObject + * @property: the name of a boolean property of @object + * + * Marks @application as busy (see g_application_mark_busy()) while + * @property on @object is %TRUE. + * + * The binding holds a reference to @application while it is active, but + * not to @object. Instead, the binding is destroyed when @object is + * finalized. + * + * Since: 2.44 + */ +void +g_application_bind_busy_property (GApplication *application, + gpointer object, + const gchar *property) +{ + guint notify_id; + GQuark property_quark; + GParamSpec *pspec; + GApplicationBusyBinding *binding; + GClosure *closure; + + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (property != NULL); + + notify_id = g_signal_lookup ("notify", G_TYPE_OBJECT); + property_quark = g_quark_from_string (property); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property); + + g_return_if_fail (pspec != NULL && pspec->value_type == G_TYPE_BOOLEAN); + + if (g_signal_handler_find (object, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC, + notify_id, property_quark, NULL, g_application_notify_busy_binding, NULL) > 0) + { + g_critical ("%s: '%s' is already bound to the busy state of the application", G_STRFUNC, property); + return; + } + + binding = g_slice_new (GApplicationBusyBinding); + binding->app = g_object_ref (application); + binding->is_busy = FALSE; + + closure = g_cclosure_new (G_CALLBACK (g_application_notify_busy_binding), binding, + g_application_busy_binding_destroy); + g_signal_connect_closure_by_id (object, notify_id, property_quark, closure, FALSE); + + /* fetch the initial value */ + g_application_notify_busy_binding (object, pspec, binding); +} + +/** + * g_application_unbind_busy_property: + * @application: a #GApplication + * @object: (type GObject.Object): a #GObject + * @property: the name of a boolean property of @object + * + * Destroys a binding between @property and the busy state of + * @application that was previously created with + * g_application_bind_busy_property(). + * + * Since: 2.44 + */ +void +g_application_unbind_busy_property (GApplication *application, + gpointer object, + const gchar *property) +{ + guint notify_id; + GQuark property_quark; + gulong handler_id; + + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (property != NULL); + + notify_id = g_signal_lookup ("notify", G_TYPE_OBJECT); + property_quark = g_quark_from_string (property); + + handler_id = g_signal_handler_find (object, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC, + notify_id, property_quark, NULL, g_application_notify_busy_binding, NULL); + if (handler_id == 0) + { + g_critical ("%s: '%s' is not bound to the busy state of the application", G_STRFUNC, property); + return; + } + + g_signal_handler_disconnect (object, handler_id); +} + +/* Epilogue {{{1 */ +/* vim:set foldmethod=marker: */ diff --git a/gio/gapplication.h b/gio/gapplication.h new file mode 100644 index 0000000..adc32ed --- /dev/null +++ b/gio/gapplication.h @@ -0,0 +1,252 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_APPLICATION_H__ +#define __G_APPLICATION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_APPLICATION (g_application_get_type ()) +#define G_APPLICATION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_APPLICATION, GApplication)) +#define G_APPLICATION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_APPLICATION, GApplicationClass)) +#define G_IS_APPLICATION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_APPLICATION)) +#define G_IS_APPLICATION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_APPLICATION)) +#define G_APPLICATION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_APPLICATION, GApplicationClass)) + +typedef struct _GApplicationPrivate GApplicationPrivate; +typedef struct _GApplicationClass GApplicationClass; + +struct _GApplication +{ + /*< private >*/ + GObject parent_instance; + + GApplicationPrivate *priv; +}; + +struct _GApplicationClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + /* signals */ + void (* startup) (GApplication *application); + + void (* activate) (GApplication *application); + + void (* open) (GApplication *application, + GFile **files, + gint n_files, + const gchar *hint); + + int (* command_line) (GApplication *application, + GApplicationCommandLine *command_line); + + /* vfuncs */ + + /** + * GApplicationClass::local_command_line: + * @application: a #GApplication + * @arguments: (inout) (array zero-terminated=1): array of command line arguments + * @exit_status: (out): exit status to fill after processing the command line. + * + * This virtual function is always invoked in the local instance. It + * gets passed a pointer to a %NULL-terminated copy of @argv and is + * expected to remove arguments that it handled (shifting up remaining + * arguments). + * + * The last argument to local_command_line() is a pointer to the @status + * variable which can used to set the exit status that is returned from + * g_application_run(). + * + * See g_application_run() for more details on #GApplication startup. + * + * Returns: %TRUE if the commandline has been completely handled + */ + gboolean (* local_command_line) (GApplication *application, + gchar ***arguments, + int *exit_status); + + void (* before_emit) (GApplication *application, + GVariant *platform_data); + void (* after_emit) (GApplication *application, + GVariant *platform_data); + void (* add_platform_data) (GApplication *application, + GVariantBuilder *builder); + void (* quit_mainloop) (GApplication *application); + void (* run_mainloop) (GApplication *application); + void (* shutdown) (GApplication *application); + + gboolean (* dbus_register) (GApplication *application, + GDBusConnection *connection, + const gchar *object_path, + GError **error); + void (* dbus_unregister) (GApplication *application, + GDBusConnection *connection, + const gchar *object_path); + gint (* handle_local_options)(GApplication *application, + GVariantDict *options); + gboolean (* name_lost) (GApplication *application); + + /*< private >*/ + gpointer padding[7]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_application_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gboolean g_application_id_is_valid (const gchar *application_id); + +GLIB_AVAILABLE_IN_ALL +GApplication * g_application_new (const gchar *application_id, + GApplicationFlags flags); + +GLIB_AVAILABLE_IN_ALL +const gchar * g_application_get_application_id (GApplication *application); +GLIB_AVAILABLE_IN_ALL +void g_application_set_application_id (GApplication *application, + const gchar *application_id); + +GLIB_AVAILABLE_IN_2_34 +GDBusConnection * g_application_get_dbus_connection (GApplication *application); +GLIB_AVAILABLE_IN_2_34 +const gchar * g_application_get_dbus_object_path (GApplication *application); + +GLIB_AVAILABLE_IN_ALL +guint g_application_get_inactivity_timeout (GApplication *application); +GLIB_AVAILABLE_IN_ALL +void g_application_set_inactivity_timeout (GApplication *application, + guint inactivity_timeout); + +GLIB_AVAILABLE_IN_ALL +GApplicationFlags g_application_get_flags (GApplication *application); +GLIB_AVAILABLE_IN_ALL +void g_application_set_flags (GApplication *application, + GApplicationFlags flags); + +GLIB_AVAILABLE_IN_2_42 +const gchar * g_application_get_resource_base_path (GApplication *application); +GLIB_AVAILABLE_IN_2_42 +void g_application_set_resource_base_path (GApplication *application, + const gchar *resource_path); + +GLIB_DEPRECATED +void g_application_set_action_group (GApplication *application, + GActionGroup *action_group); + +GLIB_AVAILABLE_IN_2_40 +void g_application_add_main_option_entries (GApplication *application, + const GOptionEntry *entries); + +GLIB_AVAILABLE_IN_2_42 +void g_application_add_main_option (GApplication *application, + const char *long_name, + char short_name, + GOptionFlags flags, + GOptionArg arg, + const char *description, + const char *arg_description); +GLIB_AVAILABLE_IN_2_40 +void g_application_add_option_group (GApplication *application, + GOptionGroup *group); +GLIB_AVAILABLE_IN_2_56 +void g_application_set_option_context_parameter_string (GApplication *application, + const gchar *parameter_string); +GLIB_AVAILABLE_IN_2_56 +void g_application_set_option_context_summary (GApplication *application, + const gchar *summary); +GLIB_AVAILABLE_IN_2_56 +void g_application_set_option_context_description (GApplication *application, + const gchar *description); +GLIB_AVAILABLE_IN_ALL +gboolean g_application_get_is_registered (GApplication *application); +GLIB_AVAILABLE_IN_ALL +gboolean g_application_get_is_remote (GApplication *application); + +GLIB_AVAILABLE_IN_ALL +gboolean g_application_register (GApplication *application, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_application_hold (GApplication *application); +GLIB_AVAILABLE_IN_ALL +void g_application_release (GApplication *application); + +GLIB_AVAILABLE_IN_ALL +void g_application_activate (GApplication *application); + +GLIB_AVAILABLE_IN_ALL +void g_application_open (GApplication *application, + GFile **files, + gint n_files, + const gchar *hint); + +GLIB_AVAILABLE_IN_ALL +int g_application_run (GApplication *application, + int argc, + char **argv); + +GLIB_AVAILABLE_IN_2_32 +void g_application_quit (GApplication *application); + +GLIB_AVAILABLE_IN_2_32 +GApplication * g_application_get_default (void); +GLIB_AVAILABLE_IN_2_32 +void g_application_set_default (GApplication *application); + +GLIB_AVAILABLE_IN_2_38 +void g_application_mark_busy (GApplication *application); +GLIB_AVAILABLE_IN_2_38 +void g_application_unmark_busy (GApplication *application); +GLIB_AVAILABLE_IN_2_44 +gboolean g_application_get_is_busy (GApplication *application); + +GLIB_AVAILABLE_IN_2_40 +void g_application_send_notification (GApplication *application, + const gchar *id, + GNotification *notification); +GLIB_AVAILABLE_IN_2_40 +void g_application_withdraw_notification (GApplication *application, + const gchar *id); + +GLIB_AVAILABLE_IN_2_44 +void g_application_bind_busy_property (GApplication *application, + gpointer object, + const gchar *property); + +GLIB_AVAILABLE_IN_2_44 +void g_application_unbind_busy_property (GApplication *application, + gpointer object, + const gchar *property); + +G_END_DECLS + +#endif /* __G_APPLICATION_H__ */ diff --git a/gio/gapplicationcommandline.c b/gio/gapplicationcommandline.c new file mode 100644 index 0000000..d7be108 --- /dev/null +++ b/gio/gapplicationcommandline.c @@ -0,0 +1,840 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gapplicationcommandline.h" + +#include "glibintl.h" +#include "gfile.h" + +#include +#include + +#ifdef G_OS_UNIX +#include "gunixinputstream.h" +#endif + +#ifdef G_OS_WIN32 +#include +#undef environ +#include "gwin32inputstream.h" +#endif + +/** + * SECTION:gapplicationcommandline + * @title: GApplicationCommandLine + * @short_description: A command-line invocation of an application + * @include: gio/gio.h + * @see_also: #GApplication + * + * #GApplicationCommandLine represents a command-line invocation of + * an application. It is created by #GApplication and emitted + * in the #GApplication::command-line signal and virtual function. + * + * The class contains the list of arguments that the program was invoked + * with. It is also possible to query if the commandline invocation was + * local (ie: the current process is running in direct response to the + * invocation) or remote (ie: some other process forwarded the + * commandline to this process). + * + * The GApplicationCommandLine object can provide the @argc and @argv + * parameters for use with the #GOptionContext command-line parsing API, + * with the g_application_command_line_get_arguments() function. See + * [gapplication-example-cmdline3.c][gapplication-example-cmdline3] + * for an example. + * + * The exit status of the originally-invoked process may be set and + * messages can be printed to stdout or stderr of that process. The + * lifecycle of the originally-invoked process is tied to the lifecycle + * of this object (ie: the process exits when the last reference is + * dropped). + * + * The main use for #GApplicationCommandLine (and the + * #GApplication::command-line signal) is 'Emacs server' like use cases: + * You can set the `EDITOR` environment variable to have e.g. git use + * your favourite editor to edit commit messages, and if you already + * have an instance of the editor running, the editing will happen + * in the running instance, instead of opening a new one. An important + * aspect of this use case is that the process that gets started by git + * does not return until the editing is done. + * + * Normally, the commandline is completely handled in the + * #GApplication::command-line handler. The launching instance exits + * once the signal handler in the primary instance has returned, and + * the return value of the signal handler becomes the exit status + * of the launching instance. + * |[ + * static int + * command_line (GApplication *application, + * GApplicationCommandLine *cmdline) + * { + * gchar **argv; + * gint argc; + * gint i; + * + * argv = g_application_command_line_get_arguments (cmdline, &argc); + * + * g_application_command_line_print (cmdline, + * "This text is written back\n" + * "to stdout of the caller\n"); + * + * for (i = 0; i < argc; i++) + * g_print ("argument %d: %s\n", i, argv[i]); + * + * g_strfreev (argv); + * + * return 0; + * } + * ]| + * The complete example can be found here: + * [gapplication-example-cmdline.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-cmdline.c) + * + * In more complicated cases, the handling of the commandline can be + * split between the launcher and the primary instance. + * |[ + * static gboolean + * test_local_cmdline (GApplication *application, + * gchar ***arguments, + * gint *exit_status) + * { + * gint i, j; + * gchar **argv; + * + * argv = *arguments; + * + * if (argv[0] == NULL) + * { + * *exit_status = 0; + * return FALSE; + * } + * + * i = 1; + * while (argv[i]) + * { + * if (g_str_has_prefix (argv[i], "--local-")) + * { + * g_print ("handling argument %s locally\n", argv[i]); + * g_free (argv[i]); + * for (j = i; argv[j]; j++) + * argv[j] = argv[j + 1]; + * } + * else + * { + * g_print ("not handling argument %s locally\n", argv[i]); + * i++; + * } + * } + * + * *exit_status = 0; + * + * return FALSE; + * } + * + * static void + * test_application_class_init (TestApplicationClass *class) + * { + * G_APPLICATION_CLASS (class)->local_command_line = test_local_cmdline; + * + * ... + * } + * ]| + * In this example of split commandline handling, options that start + * with `--local-` are handled locally, all other options are passed + * to the #GApplication::command-line handler which runs in the primary + * instance. + * + * The complete example can be found here: + * [gapplication-example-cmdline2.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-cmdline2.c) + * + * If handling the commandline requires a lot of work, it may + * be better to defer it. + * |[ + * static gboolean + * my_cmdline_handler (gpointer data) + * { + * GApplicationCommandLine *cmdline = data; + * + * // do the heavy lifting in an idle + * + * g_application_command_line_set_exit_status (cmdline, 0); + * g_object_unref (cmdline); // this releases the application + * + * return G_SOURCE_REMOVE; + * } + * + * static int + * command_line (GApplication *application, + * GApplicationCommandLine *cmdline) + * { + * // keep the application running until we are done with this commandline + * g_application_hold (application); + * + * g_object_set_data_full (G_OBJECT (cmdline), + * "application", application, + * (GDestroyNotify)g_application_release); + * + * g_object_ref (cmdline); + * g_idle_add (my_cmdline_handler, cmdline); + * + * return 0; + * } + * ]| + * In this example the commandline is not completely handled before + * the #GApplication::command-line handler returns. Instead, we keep + * a reference to the #GApplicationCommandLine object and handle it + * later (in this example, in an idle). Note that it is necessary to + * hold the application until you are done with the commandline. + * + * The complete example can be found here: + * [gapplication-example-cmdline3.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gapplication-example-cmdline3.c) + */ + +/** + * GApplicationCommandLine: + * + * #GApplicationCommandLine is an opaque data structure and can only be accessed + * using the following functions. + */ + +/** + * GApplicationCommandLineClass: + * + * The #GApplicationCommandLineClass-struct + * contains private data only. + * + * Since: 2.28 + **/ +enum +{ + PROP_NONE, + PROP_ARGUMENTS, + PROP_OPTIONS, + PROP_PLATFORM_DATA, + PROP_IS_REMOTE +}; + +struct _GApplicationCommandLinePrivate +{ + GVariant *platform_data; + GVariant *arguments; + GVariant *options; + GVariantDict *options_dict; + gchar *cwd; /* in GLib filename encoding, not UTF-8 */ + + gchar **environ; + gint exit_status; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT) + +/* All subclasses represent remote invocations of some kind. */ +#define IS_REMOTE(cmdline) (G_TYPE_FROM_INSTANCE (cmdline) != \ + G_TYPE_APPLICATION_COMMAND_LINE) + +static void +grok_platform_data (GApplicationCommandLine *cmdline) +{ + GVariantIter iter; + const gchar *key; + GVariant *value; + + g_variant_iter_init (&iter, cmdline->priv->platform_data); + + while (g_variant_iter_loop (&iter, "{&sv}", &key, &value)) + if (strcmp (key, "cwd") == 0) + { + if (!cmdline->priv->cwd) + cmdline->priv->cwd = g_variant_dup_bytestring (value, NULL); + } + + else if (strcmp (key, "environ") == 0) + { + if (!cmdline->priv->environ) + cmdline->priv->environ = + g_variant_dup_bytestring_array (value, NULL); + } + + else if (strcmp (key, "options") == 0) + { + if (!cmdline->priv->options) + cmdline->priv->options = g_variant_ref (value); + } +} + +static void +g_application_command_line_real_print_literal (GApplicationCommandLine *cmdline, + const gchar *message) +{ + g_print ("%s", message); +} + +static void +g_application_command_line_real_printerr_literal (GApplicationCommandLine *cmdline, + const gchar *message) +{ + g_printerr ("%s", message); +} + +static GInputStream * +g_application_command_line_real_get_stdin (GApplicationCommandLine *cmdline) +{ +#ifdef G_OS_UNIX + return g_unix_input_stream_new (0, FALSE); +#else + return g_win32_input_stream_new (GetStdHandle (STD_INPUT_HANDLE), FALSE); +#endif +} + +static void +g_application_command_line_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object); + + switch (prop_id) + { + case PROP_ARGUMENTS: + g_value_set_variant (value, cmdline->priv->arguments); + break; + + case PROP_PLATFORM_DATA: + g_value_set_variant (value, cmdline->priv->platform_data); + break; + + case PROP_IS_REMOTE: + g_value_set_boolean (value, IS_REMOTE (cmdline)); + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_application_command_line_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object); + + switch (prop_id) + { + case PROP_ARGUMENTS: + g_assert (cmdline->priv->arguments == NULL); + cmdline->priv->arguments = g_value_dup_variant (value); + break; + + case PROP_OPTIONS: + g_assert (cmdline->priv->options == NULL); + cmdline->priv->options = g_value_dup_variant (value); + break; + + case PROP_PLATFORM_DATA: + g_assert (cmdline->priv->platform_data == NULL); + cmdline->priv->platform_data = g_value_dup_variant (value); + if (cmdline->priv->platform_data != NULL) + grok_platform_data (cmdline); + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_application_command_line_finalize (GObject *object) +{ + GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object); + + if (cmdline->priv->options_dict) + g_variant_dict_unref (cmdline->priv->options_dict); + + if (cmdline->priv->options) + g_variant_unref (cmdline->priv->options); + + if (cmdline->priv->platform_data) + g_variant_unref (cmdline->priv->platform_data); + if (cmdline->priv->arguments) + g_variant_unref (cmdline->priv->arguments); + + g_free (cmdline->priv->cwd); + g_strfreev (cmdline->priv->environ); + + G_OBJECT_CLASS (g_application_command_line_parent_class) + ->finalize (object); +} + +static void +g_application_command_line_init (GApplicationCommandLine *cmdline) +{ + cmdline->priv = g_application_command_line_get_instance_private (cmdline); +} + +static void +g_application_command_line_constructed (GObject *object) +{ + GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object); + + if (IS_REMOTE (cmdline)) + return; + + /* In the local case, set cmd and environ */ + if (!cmdline->priv->cwd) + cmdline->priv->cwd = g_get_current_dir (); + + if (!cmdline->priv->environ) + cmdline->priv->environ = g_get_environ (); +} + +static void +g_application_command_line_class_init (GApplicationCommandLineClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->get_property = g_application_command_line_get_property; + object_class->set_property = g_application_command_line_set_property; + object_class->finalize = g_application_command_line_finalize; + object_class->constructed = g_application_command_line_constructed; + + class->printerr_literal = g_application_command_line_real_printerr_literal; + class->print_literal = g_application_command_line_real_print_literal; + class->get_stdin = g_application_command_line_real_get_stdin; + + g_object_class_install_property (object_class, PROP_ARGUMENTS, + g_param_spec_variant ("arguments", + P_("Commandline arguments"), + P_("The commandline that caused this ::command-line signal emission"), + G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_OPTIONS, + g_param_spec_variant ("options", + P_("Options"), + P_("The options sent along with the commandline"), + G_VARIANT_TYPE_VARDICT, NULL, G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_PLATFORM_DATA, + g_param_spec_variant ("platform-data", + P_("Platform data"), + P_("Platform-specific data for the commandline"), + G_VARIANT_TYPE ("a{sv}"), NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_IS_REMOTE, + g_param_spec_boolean ("is-remote", + P_("Is remote"), + P_("TRUE if this is a remote commandline"), + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); +} + + +/** + * g_application_command_line_get_arguments: + * @cmdline: a #GApplicationCommandLine + * @argc: (out) (optional): the length of the arguments array, or %NULL + * + * Gets the list of arguments that was passed on the command line. + * + * The strings in the array may contain non-UTF-8 data on UNIX (such as + * filenames or arguments given in the system locale) but are always in + * UTF-8 on Windows. + * + * If you wish to use the return value with #GOptionContext, you must + * use g_option_context_parse_strv(). + * + * The return value is %NULL-terminated and should be freed using + * g_strfreev(). + * + * Returns: (array length=argc) (element-type filename) (transfer full) + * the string array containing the arguments (the argv) + * + * Since: 2.28 + **/ +gchar ** +g_application_command_line_get_arguments (GApplicationCommandLine *cmdline, + int *argc) +{ + gchar **argv; + gsize len; + + g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL); + + argv = g_variant_dup_bytestring_array (cmdline->priv->arguments, &len); + + if (argc) + *argc = len; + + return argv; +} + +/** + * g_application_command_line_get_options_dict: + * @cmdline: a #GApplicationCommandLine + * + * Gets the options there were passed to g_application_command_line(). + * + * If you did not override local_command_line() then these are the same + * options that were parsed according to the #GOptionEntrys added to the + * application with g_application_add_main_option_entries() and possibly + * modified from your GApplication::handle-local-options handler. + * + * If no options were sent then an empty dictionary is returned so that + * you don't need to check for %NULL. + * + * Returns: (transfer none): a #GVariantDict with the options + * + * Since: 2.40 + **/ +GVariantDict * +g_application_command_line_get_options_dict (GApplicationCommandLine *cmdline) +{ + g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL); + + if (!cmdline->priv->options_dict) + cmdline->priv->options_dict = g_variant_dict_new (cmdline->priv->options); + + return cmdline->priv->options_dict; +} + +/** + * g_application_command_line_get_stdin: + * @cmdline: a #GApplicationCommandLine + * + * Gets the stdin of the invoking process. + * + * The #GInputStream can be used to read data passed to the standard + * input of the invoking process. + * This doesn't work on all platforms. Presently, it is only available + * on UNIX when using a D-Bus daemon capable of passing file descriptors. + * If stdin is not available then %NULL will be returned. In the + * future, support may be expanded to other platforms. + * + * You must only call this function once per commandline invocation. + * + * Returns: (nullable) (transfer full): a #GInputStream for stdin + * + * Since: 2.34 + **/ +GInputStream * +g_application_command_line_get_stdin (GApplicationCommandLine *cmdline) +{ + return G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)->get_stdin (cmdline); +} + +/** + * g_application_command_line_get_cwd: + * @cmdline: a #GApplicationCommandLine + * + * Gets the working directory of the command line invocation. + * The string may contain non-utf8 data. + * + * It is possible that the remote application did not send a working + * directory, so this may be %NULL. + * + * The return value should not be modified or freed and is valid for as + * long as @cmdline exists. + * + * Returns: (nullable) (type filename): the current directory, or %NULL + * + * Since: 2.28 + **/ +const gchar * +g_application_command_line_get_cwd (GApplicationCommandLine *cmdline) +{ + return cmdline->priv->cwd; +} + +/** + * g_application_command_line_get_environ: + * @cmdline: a #GApplicationCommandLine + * + * Gets the contents of the 'environ' variable of the command line + * invocation, as would be returned by g_get_environ(), ie as a + * %NULL-terminated list of strings in the form 'NAME=VALUE'. + * The strings may contain non-utf8 data. + * + * The remote application usually does not send an environment. Use + * %G_APPLICATION_SEND_ENVIRONMENT to affect that. Even with this flag + * set it is possible that the environment is still not available (due + * to invocation messages from other applications). + * + * The return value should not be modified or freed and is valid for as + * long as @cmdline exists. + * + * See g_application_command_line_getenv() if you are only interested + * in the value of a single environment variable. + * + * Returns: (array zero-terminated=1) (element-type filename) (transfer none): + * the environment strings, or %NULL if they were not sent + * + * Since: 2.28 + **/ +const gchar * const * +g_application_command_line_get_environ (GApplicationCommandLine *cmdline) +{ + return (const gchar **)cmdline->priv->environ; +} + +/** + * g_application_command_line_getenv: + * @cmdline: a #GApplicationCommandLine + * @name: (type filename): the environment variable to get + * + * Gets the value of a particular environment variable of the command + * line invocation, as would be returned by g_getenv(). The strings may + * contain non-utf8 data. + * + * The remote application usually does not send an environment. Use + * %G_APPLICATION_SEND_ENVIRONMENT to affect that. Even with this flag + * set it is possible that the environment is still not available (due + * to invocation messages from other applications). + * + * The return value should not be modified or freed and is valid for as + * long as @cmdline exists. + * + * Returns: (nullable): the value of the variable, or %NULL if unset or unsent + * + * Since: 2.28 + **/ +const gchar * +g_application_command_line_getenv (GApplicationCommandLine *cmdline, + const gchar *name) +{ + gint length = strlen (name); + gint i; + + /* TODO: expand on windows */ + if (cmdline->priv->environ) + for (i = 0; cmdline->priv->environ[i]; i++) + if (strncmp (cmdline->priv->environ[i], name, length) == 0 && + cmdline->priv->environ[i][length] == '=') + return cmdline->priv->environ[i] + length + 1; + + return NULL; +} + +/** + * g_application_command_line_get_is_remote: + * @cmdline: a #GApplicationCommandLine + * + * Determines if @cmdline represents a remote invocation. + * + * Returns: %TRUE if the invocation was remote + * + * Since: 2.28 + **/ +gboolean +g_application_command_line_get_is_remote (GApplicationCommandLine *cmdline) +{ + return IS_REMOTE (cmdline); +} + +/** + * g_application_command_line_print: + * @cmdline: a #GApplicationCommandLine + * @format: a printf-style format string + * @...: arguments, as per @format + * + * Formats a message and prints it using the stdout print handler in the + * invoking process. + * + * If @cmdline is a local invocation then this is exactly equivalent to + * g_print(). If @cmdline is remote then this is equivalent to calling + * g_print() in the invoking process. + * + * Since: 2.28 + **/ +void +g_application_command_line_print (GApplicationCommandLine *cmdline, + const gchar *format, + ...) +{ + gchar *message; + va_list ap; + + g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline)); + g_return_if_fail (format != NULL); + + va_start (ap, format); + message = g_strdup_vprintf (format, ap); + va_end (ap); + + G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline) + ->print_literal (cmdline, message); + g_free (message); +} + +/** + * g_application_command_line_printerr: + * @cmdline: a #GApplicationCommandLine + * @format: a printf-style format string + * @...: arguments, as per @format + * + * Formats a message and prints it using the stderr print handler in the + * invoking process. + * + * If @cmdline is a local invocation then this is exactly equivalent to + * g_printerr(). If @cmdline is remote then this is equivalent to + * calling g_printerr() in the invoking process. + * + * Since: 2.28 + **/ +void +g_application_command_line_printerr (GApplicationCommandLine *cmdline, + const gchar *format, + ...) +{ + gchar *message; + va_list ap; + + g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline)); + g_return_if_fail (format != NULL); + + va_start (ap, format); + message = g_strdup_vprintf (format, ap); + va_end (ap); + + G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline) + ->printerr_literal (cmdline, message); + g_free (message); +} + +/** + * g_application_command_line_set_exit_status: + * @cmdline: a #GApplicationCommandLine + * @exit_status: the exit status + * + * Sets the exit status that will be used when the invoking process + * exits. + * + * The return value of the #GApplication::command-line signal is + * passed to this function when the handler returns. This is the usual + * way of setting the exit status. + * + * In the event that you want the remote invocation to continue running + * and want to decide on the exit status in the future, you can use this + * call. For the case of a remote invocation, the remote process will + * typically exit when the last reference is dropped on @cmdline. The + * exit status of the remote process will be equal to the last value + * that was set with this function. + * + * In the case that the commandline invocation is local, the situation + * is slightly more complicated. If the commandline invocation results + * in the mainloop running (ie: because the use-count of the application + * increased to a non-zero value) then the application is considered to + * have been 'successful' in a certain sense, and the exit status is + * always zero. If the application use count is zero, though, the exit + * status of the local #GApplicationCommandLine is used. + * + * Since: 2.28 + **/ +void +g_application_command_line_set_exit_status (GApplicationCommandLine *cmdline, + int exit_status) +{ + g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline)); + + cmdline->priv->exit_status = exit_status; +} + +/** + * g_application_command_line_get_exit_status: + * @cmdline: a #GApplicationCommandLine + * + * Gets the exit status of @cmdline. See + * g_application_command_line_set_exit_status() for more information. + * + * Returns: the exit status + * + * Since: 2.28 + **/ +int +g_application_command_line_get_exit_status (GApplicationCommandLine *cmdline) +{ + g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), -1); + + return cmdline->priv->exit_status; +} + +/** + * g_application_command_line_get_platform_data: + * @cmdline: #GApplicationCommandLine + * + * Gets the platform data associated with the invocation of @cmdline. + * + * This is a #GVariant dictionary containing information about the + * context in which the invocation occurred. It typically contains + * information like the current working directory and the startup + * notification ID. + * + * For local invocation, it will be %NULL. + * + * Returns: (nullable): the platform data, or %NULL + * + * Since: 2.28 + **/ +GVariant * +g_application_command_line_get_platform_data (GApplicationCommandLine *cmdline) +{ + g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL); + + if (cmdline->priv->platform_data) + return g_variant_ref (cmdline->priv->platform_data); + else + return NULL; +} + +/** + * g_application_command_line_create_file_for_arg: + * @cmdline: a #GApplicationCommandLine + * @arg: (type filename): an argument from @cmdline + * + * Creates a #GFile corresponding to a filename that was given as part + * of the invocation of @cmdline. + * + * This differs from g_file_new_for_commandline_arg() in that it + * resolves relative pathnames using the current working directory of + * the invoking process rather than the local process. + * + * Returns: (transfer full): a new #GFile + * + * Since: 2.36 + **/ +GFile * +g_application_command_line_create_file_for_arg (GApplicationCommandLine *cmdline, + const gchar *arg) +{ + g_return_val_if_fail (arg != NULL, NULL); + + if (cmdline->priv->cwd) + return g_file_new_for_commandline_arg_and_cwd (arg, cmdline->priv->cwd); + + g_warning ("Requested creation of GFile for commandline invocation that did not send cwd. " + "Using cwd of local process to resolve relative path names."); + + return g_file_new_for_commandline_arg (arg); +} diff --git a/gio/gapplicationcommandline.h b/gio/gapplicationcommandline.h new file mode 100644 index 0000000..6610e86 --- /dev/null +++ b/gio/gapplicationcommandline.h @@ -0,0 +1,122 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_APPLICATION_COMMAND_LINE_H__ +#define __G_APPLICATION_COMMAND_LINE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_APPLICATION_COMMAND_LINE (g_application_command_line_get_type ()) +#define G_APPLICATION_COMMAND_LINE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_APPLICATION_COMMAND_LINE, \ + GApplicationCommandLine)) +#define G_APPLICATION_COMMAND_LINE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_APPLICATION_COMMAND_LINE, \ + GApplicationCommandLineClass)) +#define G_IS_APPLICATION_COMMAND_LINE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_APPLICATION_COMMAND_LINE)) +#define G_IS_APPLICATION_COMMAND_LINE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_APPLICATION_COMMAND_LINE)) +#define G_APPLICATION_COMMAND_LINE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_APPLICATION_COMMAND_LINE, \ + GApplicationCommandLineClass)) + +typedef struct _GApplicationCommandLinePrivate GApplicationCommandLinePrivate; +typedef struct _GApplicationCommandLineClass GApplicationCommandLineClass; + +struct _GApplicationCommandLine +{ + /*< private >*/ + GObject parent_instance; + + GApplicationCommandLinePrivate *priv; +}; + +struct _GApplicationCommandLineClass +{ + /*< private >*/ + GObjectClass parent_class; + + void (* print_literal) (GApplicationCommandLine *cmdline, + const gchar *message); + void (* printerr_literal) (GApplicationCommandLine *cmdline, + const gchar *message); + GInputStream * (* get_stdin) (GApplicationCommandLine *cmdline); + + gpointer padding[11]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_application_command_line_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gchar ** g_application_command_line_get_arguments (GApplicationCommandLine *cmdline, + int *argc); + +GLIB_AVAILABLE_IN_2_40 +GVariantDict * g_application_command_line_get_options_dict (GApplicationCommandLine *cmdline); + +GLIB_AVAILABLE_IN_2_36 +GInputStream * g_application_command_line_get_stdin (GApplicationCommandLine *cmdline); + +GLIB_AVAILABLE_IN_ALL +const gchar * const * g_application_command_line_get_environ (GApplicationCommandLine *cmdline); + +GLIB_AVAILABLE_IN_ALL +const gchar * g_application_command_line_getenv (GApplicationCommandLine *cmdline, + const gchar *name); + +GLIB_AVAILABLE_IN_ALL +const gchar * g_application_command_line_get_cwd (GApplicationCommandLine *cmdline); + +GLIB_AVAILABLE_IN_ALL +gboolean g_application_command_line_get_is_remote (GApplicationCommandLine *cmdline); + +GLIB_AVAILABLE_IN_ALL +void g_application_command_line_print (GApplicationCommandLine *cmdline, + const gchar *format, + ...) G_GNUC_PRINTF(2, 3); +GLIB_AVAILABLE_IN_ALL +void g_application_command_line_printerr (GApplicationCommandLine *cmdline, + const gchar *format, + ...) G_GNUC_PRINTF(2, 3); + +GLIB_AVAILABLE_IN_ALL +int g_application_command_line_get_exit_status (GApplicationCommandLine *cmdline); +GLIB_AVAILABLE_IN_ALL +void g_application_command_line_set_exit_status (GApplicationCommandLine *cmdline, + int exit_status); + +GLIB_AVAILABLE_IN_ALL +GVariant * g_application_command_line_get_platform_data (GApplicationCommandLine *cmdline); + +GLIB_AVAILABLE_IN_2_36 +GFile * g_application_command_line_create_file_for_arg (GApplicationCommandLine *cmdline, + const gchar *arg); + +G_END_DECLS + +#endif /* __G_APPLICATION_COMMAND_LINE_H__ */ diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c new file mode 100644 index 0000000..5604b92 --- /dev/null +++ b/gio/gapplicationimpl-dbus.c @@ -0,0 +1,1003 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gapplicationimpl.h" + +#include "gactiongroup.h" +#include "gactiongroupexporter.h" +#include "gremoteactiongroup.h" +#include "gdbusactiongroup-private.h" +#include "gapplication.h" +#include "gfile.h" +#include "gdbusconnection.h" +#include "gdbusintrospection.h" +#include "gdbuserror.h" +#include "glib/gstdio.h" + +#include +#include + +#include "gapplicationcommandline.h" +#include "gdbusmethodinvocation.h" + +#ifdef G_OS_UNIX +#include "gunixinputstream.h" +#include "gunixfdlist.h" +#endif + +/* D-Bus Interface definition {{{1 */ + +/* For documentation of these interfaces, see + * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI + */ +static const gchar org_gtk_Application_xml[] = + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +static GDBusInterfaceInfo *org_gtk_Application; + +static const gchar org_freedesktop_Application_xml[] = + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +static GDBusInterfaceInfo *org_freedesktop_Application; + +static const gchar org_gtk_private_CommandLine_xml[] = + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +static GDBusInterfaceInfo *org_gtk_private_CommandLine; + +/* GApplication implementation {{{1 */ +struct _GApplicationImpl +{ + GDBusConnection *session_bus; + GActionGroup *exported_actions; + const gchar *bus_name; + guint name_lost_signal; + + gchar *object_path; + guint object_id; + guint fdo_object_id; + guint actions_id; + + gboolean properties_live; + gboolean primary; + gboolean busy; + gboolean registered; + GApplication *app; +}; + + +static GApplicationCommandLine * +g_dbus_command_line_new (GDBusMethodInvocation *invocation); + +static GVariant * +g_application_impl_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + GApplicationImpl *impl = user_data; + + if (strcmp (property_name, "Busy") == 0) + return g_variant_new_boolean (impl->busy); + + g_assert_not_reached (); + + return NULL; +} + +static void +send_property_change (GApplicationImpl *impl) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (&builder, + "{sv}", + "Busy", g_variant_new_boolean (impl->busy)); + + g_dbus_connection_emit_signal (impl->session_bus, + NULL, + impl->object_path, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(sa{sv}as)", + "org.gtk.Application", + &builder, + NULL), + NULL); +} + +static void +g_application_impl_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GApplicationImpl *impl = user_data; + GApplicationClass *class; + + class = G_APPLICATION_GET_CLASS (impl->app); + + if (strcmp (method_name, "Activate") == 0) + { + GVariant *platform_data; + + /* Completely the same for both freedesktop and gtk interfaces */ + + g_variant_get (parameters, "(@a{sv})", &platform_data); + + class->before_emit (impl->app, platform_data); + g_signal_emit_by_name (impl->app, "activate"); + class->after_emit (impl->app, platform_data); + g_variant_unref (platform_data); + + g_dbus_method_invocation_return_value (invocation, NULL); + } + + else if (strcmp (method_name, "Open") == 0) + { + GApplicationFlags flags; + GVariant *platform_data; + const gchar *hint; + GVariant *array; + GFile **files; + gint n, i; + + flags = g_application_get_flags (impl->app); + if ((flags & G_APPLICATION_HANDLES_OPEN) == 0) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "Application does not open files"); + return; + } + + /* freedesktop interface has no hint parameter */ + if (g_str_equal (interface_name, "org.freedesktop.Application")) + { + g_variant_get (parameters, "(@as@a{sv})", &array, &platform_data); + hint = ""; + } + else + g_variant_get (parameters, "(@as&s@a{sv})", &array, &hint, &platform_data); + + n = g_variant_n_children (array); + files = g_new (GFile *, n + 1); + + for (i = 0; i < n; i++) + { + const gchar *uri; + + g_variant_get_child (array, i, "&s", &uri); + files[i] = g_file_new_for_uri (uri); + } + g_variant_unref (array); + files[n] = NULL; + + class->before_emit (impl->app, platform_data); + g_signal_emit_by_name (impl->app, "open", files, n, hint); + class->after_emit (impl->app, platform_data); + + g_variant_unref (platform_data); + + for (i = 0; i < n; i++) + g_object_unref (files[i]); + g_free (files); + + g_dbus_method_invocation_return_value (invocation, NULL); + } + + else if (strcmp (method_name, "CommandLine") == 0) + { + GApplicationFlags flags; + GApplicationCommandLine *cmdline; + GVariant *platform_data; + int status; + + flags = g_application_get_flags (impl->app); + if ((flags & G_APPLICATION_HANDLES_COMMAND_LINE) == 0) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, + "Application does not handle command line arguments"); + return; + } + + /* Only on the GtkApplication interface */ + + cmdline = g_dbus_command_line_new (invocation); + platform_data = g_variant_get_child_value (parameters, 2); + class->before_emit (impl->app, platform_data); + g_signal_emit_by_name (impl->app, "command-line", cmdline, &status); + g_application_command_line_set_exit_status (cmdline, status); + class->after_emit (impl->app, platform_data); + g_variant_unref (platform_data); + g_object_unref (cmdline); + } + else if (g_str_equal (method_name, "ActivateAction")) + { + GVariant *parameter = NULL; + GVariant *platform_data; + GVariantIter *iter; + const gchar *name; + + /* Only on the freedesktop interface */ + + g_variant_get (parameters, "(&sav@a{sv})", &name, &iter, &platform_data); + g_variant_iter_next (iter, "v", ¶meter); + g_variant_iter_free (iter); + + class->before_emit (impl->app, platform_data); + g_action_group_activate_action (impl->exported_actions, name, parameter); + class->after_emit (impl->app, platform_data); + + if (parameter) + g_variant_unref (parameter); + + g_variant_unref (platform_data); + + g_dbus_method_invocation_return_value (invocation, NULL); + } + else + g_assert_not_reached (); +} + +static gchar * +application_path_from_appid (const gchar *appid) +{ + gchar *appid_path, *iter; + + if (appid == NULL) + /* this is a private implementation detail */ + return g_strdup ("/org/gtk/Application/anonymous"); + + appid_path = g_strconcat ("/", appid, NULL); + for (iter = appid_path; *iter; iter++) + { + if (*iter == '.') + *iter = '/'; + + if (*iter == '-') + *iter = '_'; + } + + return appid_path; +} + +static void g_application_impl_stop_primary (GApplicationImpl *impl); + +static void +name_lost (GDBusConnection *bus, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GApplicationImpl *impl = user_data; + gboolean handled; + + impl->primary = FALSE; + g_application_impl_stop_primary (impl); + g_signal_emit_by_name (impl->app, "name-lost", &handled); +} + +/* Attempt to become the primary instance. + * + * Returns %TRUE if everything went OK, regardless of if we became the + * primary instance or not. %FALSE is reserved for when something went + * seriously wrong (and @error will be set too, in that case). + * + * After a %TRUE return, impl->primary will be TRUE if we were + * successful. + */ +static gboolean +g_application_impl_attempt_primary (GApplicationImpl *impl, + GCancellable *cancellable, + GError **error) +{ + static const GDBusInterfaceVTable vtable = { + g_application_impl_method_call, + g_application_impl_get_property, + NULL, /* set_property */ + { 0 } + }; + GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app); + GBusNameOwnerFlags name_owner_flags; + GApplicationFlags app_flags; + GVariant *reply; + guint32 rval; + GError *local_error = NULL; + + if (org_gtk_Application == NULL) + { + GError *error = NULL; + GDBusNodeInfo *info; + + info = g_dbus_node_info_new_for_xml (org_gtk_Application_xml, &error); + if G_UNLIKELY (info == NULL) + g_error ("%s", error->message); + org_gtk_Application = g_dbus_node_info_lookup_interface (info, "org.gtk.Application"); + g_assert (org_gtk_Application != NULL); + g_dbus_interface_info_ref (org_gtk_Application); + g_dbus_node_info_unref (info); + + info = g_dbus_node_info_new_for_xml (org_freedesktop_Application_xml, &error); + if G_UNLIKELY (info == NULL) + g_error ("%s", error->message); + org_freedesktop_Application = g_dbus_node_info_lookup_interface (info, "org.freedesktop.Application"); + g_assert (org_freedesktop_Application != NULL); + g_dbus_interface_info_ref (org_freedesktop_Application); + g_dbus_node_info_unref (info); + } + + /* We could possibly have been D-Bus activated as a result of incoming + * requests on either the application or actiongroup interfaces. + * Because of how GDBus dispatches messages, we need to ensure that + * both of those things are registered before we attempt to request + * our name. + * + * The action group need not be populated yet, as long as it happens + * before we return to the mainloop. The reason for that is because + * GDBus does the check to make sure the object exists from the worker + * thread but doesn't actually dispatch the action invocation until we + * hit the mainloop in this thread. There is also no danger of + * receiving 'activate' or 'open' signals until after 'startup' runs, + * for the same reason. + */ + impl->object_id = g_dbus_connection_register_object (impl->session_bus, impl->object_path, + org_gtk_Application, &vtable, impl, NULL, error); + + if (impl->object_id == 0) + return FALSE; + + impl->fdo_object_id = g_dbus_connection_register_object (impl->session_bus, impl->object_path, + org_freedesktop_Application, &vtable, impl, NULL, error); + + if (impl->fdo_object_id == 0) + return FALSE; + + impl->actions_id = g_dbus_connection_export_action_group (impl->session_bus, impl->object_path, + impl->exported_actions, error); + + if (impl->actions_id == 0) + return FALSE; + + impl->registered = TRUE; + if (!app_class->dbus_register (impl->app, + impl->session_bus, + impl->object_path, + &local_error)) + { + g_return_val_if_fail (local_error != NULL, FALSE); + g_propagate_error (error, g_steal_pointer (&local_error)); + return FALSE; + } + + g_return_val_if_fail (local_error == NULL, FALSE); + + if (impl->bus_name == NULL) + { + /* If this is a non-unique application then it is sufficient to + * have our object paths registered. We can return now. + * + * Note: non-unique applications always act as primary-instance. + */ + impl->primary = TRUE; + return TRUE; + } + + /* If this is a unique application then we need to attempt to own + * the well-known name and fall back to remote mode (!is_primary) + * in the case that we can't do that. + */ + name_owner_flags = G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE; + app_flags = g_application_get_flags (impl->app); + + if (app_flags & G_APPLICATION_ALLOW_REPLACEMENT) + { + impl->name_lost_signal = g_dbus_connection_signal_subscribe (impl->session_bus, + "org.freedesktop.DBus", + "org.freedesktop.DBus", + "NameLost", + "/org/freedesktop/DBus", + impl->bus_name, + G_DBUS_SIGNAL_FLAGS_NONE, + name_lost, + impl, + NULL); + + name_owner_flags |= G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; + } + if (app_flags & G_APPLICATION_REPLACE) + name_owner_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; + + reply = g_dbus_connection_call_sync (impl->session_bus, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "RequestName", + g_variant_new ("(su)", impl->bus_name, name_owner_flags), + G_VARIANT_TYPE ("(u)"), + 0, -1, cancellable, error); + + if (reply == NULL) + return FALSE; + + g_variant_get (reply, "(u)", &rval); + g_variant_unref (reply); + + /* DBUS_REQUEST_NAME_REPLY_EXISTS: 3 */ + impl->primary = (rval != 3); + + if (!impl->primary && impl->name_lost_signal) + { + g_dbus_connection_signal_unsubscribe (impl->session_bus, impl->name_lost_signal); + impl->name_lost_signal = 0; + } + + return TRUE; +} + +/* Stop doing the things that the primary instance does. + * + * This should be called if attempting to become the primary instance + * failed (in order to clean up any partial success) and should also + * be called when freeing the GApplication. + * + * It is safe to call this multiple times. + */ +static void +g_application_impl_stop_primary (GApplicationImpl *impl) +{ + GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app); + + if (impl->registered) + { + app_class->dbus_unregister (impl->app, + impl->session_bus, + impl->object_path); + impl->registered = FALSE; + } + + if (impl->object_id) + { + g_dbus_connection_unregister_object (impl->session_bus, impl->object_id); + impl->object_id = 0; + } + + if (impl->fdo_object_id) + { + g_dbus_connection_unregister_object (impl->session_bus, impl->fdo_object_id); + impl->fdo_object_id = 0; + } + + if (impl->actions_id) + { + g_dbus_connection_unexport_action_group (impl->session_bus, impl->actions_id); + impl->actions_id = 0; + } + + if (impl->name_lost_signal) + { + g_dbus_connection_signal_unsubscribe (impl->session_bus, impl->name_lost_signal); + impl->name_lost_signal = 0; + } + + if (impl->primary && impl->bus_name) + { + g_dbus_connection_call (impl->session_bus, "org.freedesktop.DBus", + "/org/freedesktop/DBus", "org.freedesktop.DBus", + "ReleaseName", g_variant_new ("(s)", impl->bus_name), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + impl->primary = FALSE; + } +} + +void +g_application_impl_set_busy_state (GApplicationImpl *impl, + gboolean busy) +{ + if (impl->busy != busy) + { + impl->busy = busy; + send_property_change (impl); + } +} + +void +g_application_impl_destroy (GApplicationImpl *impl) +{ + g_application_impl_stop_primary (impl); + + if (impl->session_bus) + g_object_unref (impl->session_bus); + + g_free (impl->object_path); + + g_slice_free (GApplicationImpl, impl); +} + +GApplicationImpl * +g_application_impl_register (GApplication *application, + const gchar *appid, + GApplicationFlags flags, + GActionGroup *exported_actions, + GRemoteActionGroup **remote_actions, + GCancellable *cancellable, + GError **error) +{ + GDBusActionGroup *actions; + GApplicationImpl *impl; + + g_assert ((flags & G_APPLICATION_NON_UNIQUE) || appid != NULL); + + impl = g_slice_new0 (GApplicationImpl); + + impl->app = application; + impl->exported_actions = exported_actions; + + /* non-unique applications do not attempt to acquire a bus name */ + if (~flags & G_APPLICATION_NON_UNIQUE) + impl->bus_name = appid; + + impl->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, NULL); + + if (impl->session_bus == NULL) + { + /* If we can't connect to the session bus, proceed as a normal + * non-unique application. + */ + *remote_actions = NULL; + return impl; + } + + impl->object_path = application_path_from_appid (appid); + + /* Only try to be the primary instance if + * G_APPLICATION_IS_LAUNCHER was not specified. + */ + if (~flags & G_APPLICATION_IS_LAUNCHER) + { + if (!g_application_impl_attempt_primary (impl, cancellable, error)) + { + g_application_impl_destroy (impl); + return NULL; + } + + if (impl->primary) + return impl; + + /* We didn't make it. Drop our service-side stuff. */ + g_application_impl_stop_primary (impl); + + if (flags & G_APPLICATION_IS_SERVICE) + { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "Unable to acquire bus name '%s'", appid); + g_application_impl_destroy (impl); + + return NULL; + } + } + + /* We are non-primary. Try to get the primary's list of actions. + * This also serves as a mechanism to ensure that the primary exists + * (ie: D-Bus service files installed correctly, etc). + */ + actions = g_dbus_action_group_get (impl->session_bus, impl->bus_name, impl->object_path); + if (!g_dbus_action_group_sync (actions, cancellable, error)) + { + /* The primary appears not to exist. Fail the registration. */ + g_application_impl_destroy (impl); + g_object_unref (actions); + + return NULL; + } + + *remote_actions = G_REMOTE_ACTION_GROUP (actions); + + return impl; +} + +void +g_application_impl_activate (GApplicationImpl *impl, + GVariant *platform_data) +{ + g_dbus_connection_call (impl->session_bus, + impl->bus_name, + impl->object_path, + "org.gtk.Application", + "Activate", + g_variant_new ("(@a{sv})", platform_data), + NULL, 0, -1, NULL, NULL, NULL); +} + +void +g_application_impl_open (GApplicationImpl *impl, + GFile **files, + gint n_files, + const gchar *hint, + GVariant *platform_data) +{ + GVariantBuilder builder; + gint i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(assa{sv})")); + g_variant_builder_open (&builder, G_VARIANT_TYPE_STRING_ARRAY); + for (i = 0; i < n_files; i++) + { + gchar *uri = g_file_get_uri (files[i]); + g_variant_builder_add (&builder, "s", uri); + g_free (uri); + } + g_variant_builder_close (&builder); + g_variant_builder_add (&builder, "s", hint); + g_variant_builder_add_value (&builder, platform_data); + + g_dbus_connection_call (impl->session_bus, + impl->bus_name, + impl->object_path, + "org.gtk.Application", + "Open", + g_variant_builder_end (&builder), + NULL, 0, -1, NULL, NULL, NULL); +} + +static void +g_application_impl_cmdline_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + const gchar *message; + + g_variant_get_child (parameters, 0, "&s", &message); + + if (strcmp (method_name, "Print") == 0) + g_print ("%s", message); + else if (strcmp (method_name, "PrintError") == 0) + g_printerr ("%s", message); + else + g_assert_not_reached (); + + g_dbus_method_invocation_return_value (invocation, NULL); +} + +typedef struct +{ + GMainLoop *loop; + int status; +} CommandLineData; + +static void +g_application_impl_cmdline_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + CommandLineData *data = user_data; + GError *error = NULL; + GVariant *reply; + +#ifdef G_OS_UNIX + reply = g_dbus_connection_call_with_unix_fd_list_finish (G_DBUS_CONNECTION (source), NULL, result, &error); +#else + reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); +#endif + + + if (reply != NULL) + { + g_variant_get (reply, "(i)", &data->status); + g_variant_unref (reply); + } + + else + { + g_printerr ("%s\n", error->message); + g_error_free (error); + data->status = 1; + } + + g_main_loop_quit (data->loop); +} + +int +g_application_impl_command_line (GApplicationImpl *impl, + const gchar * const *arguments, + GVariant *platform_data) +{ + static const GDBusInterfaceVTable vtable = { + g_application_impl_cmdline_method_call, NULL, NULL, { 0 } + }; + const gchar *object_path = "/org/gtk/Application/CommandLine"; + GMainContext *context; + CommandLineData data; + guint object_id G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + context = g_main_context_new (); + data.loop = g_main_loop_new (context, FALSE); + g_main_context_push_thread_default (context); + + if (org_gtk_private_CommandLine == NULL) + { + GError *error = NULL; + GDBusNodeInfo *info; + + info = g_dbus_node_info_new_for_xml (org_gtk_private_CommandLine_xml, &error); + if G_UNLIKELY (info == NULL) + g_error ("%s", error->message); + org_gtk_private_CommandLine = g_dbus_node_info_lookup_interface (info, "org.gtk.private.CommandLine"); + g_assert (org_gtk_private_CommandLine != NULL); + g_dbus_interface_info_ref (org_gtk_private_CommandLine); + g_dbus_node_info_unref (info); + } + + object_id = g_dbus_connection_register_object (impl->session_bus, object_path, + org_gtk_private_CommandLine, + &vtable, &data, NULL, NULL); + /* In theory we should try other paths... */ + g_assert (object_id != 0); + +#ifdef G_OS_UNIX + { + GError *error = NULL; + GUnixFDList *fd_list; + + /* send along the stdin in case + * g_application_command_line_get_stdin_data() is called + */ + fd_list = g_unix_fd_list_new (); + g_unix_fd_list_append (fd_list, 0, &error); + g_assert_no_error (error); + + g_dbus_connection_call_with_unix_fd_list (impl->session_bus, impl->bus_name, impl->object_path, + "org.gtk.Application", "CommandLine", + g_variant_new ("(o^aay@a{sv})", object_path, arguments, platform_data), + G_VARIANT_TYPE ("(i)"), 0, G_MAXINT, fd_list, NULL, + g_application_impl_cmdline_done, &data); + g_object_unref (fd_list); + } +#else + g_dbus_connection_call (impl->session_bus, impl->bus_name, impl->object_path, + "org.gtk.Application", "CommandLine", + g_variant_new ("(o^aay@a{sv})", object_path, arguments, platform_data), + G_VARIANT_TYPE ("(i)"), 0, G_MAXINT, NULL, + g_application_impl_cmdline_done, &data); +#endif + + g_main_loop_run (data.loop); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); + g_main_loop_unref (data.loop); + + return data.status; +} + +void +g_application_impl_flush (GApplicationImpl *impl) +{ + if (impl->session_bus) + g_dbus_connection_flush_sync (impl->session_bus, NULL, NULL); +} + +GDBusConnection * +g_application_impl_get_dbus_connection (GApplicationImpl *impl) +{ + return impl->session_bus; +} + +const gchar * +g_application_impl_get_dbus_object_path (GApplicationImpl *impl) +{ + return impl->object_path; +} + +/* GDBusCommandLine implementation {{{1 */ + +typedef GApplicationCommandLineClass GDBusCommandLineClass; +static GType g_dbus_command_line_get_type (void); +typedef struct +{ + GApplicationCommandLine parent_instance; + GDBusMethodInvocation *invocation; + + GDBusConnection *connection; + const gchar *bus_name; + const gchar *object_path; +} GDBusCommandLine; + + +G_DEFINE_TYPE (GDBusCommandLine, + g_dbus_command_line, + G_TYPE_APPLICATION_COMMAND_LINE) + +static void +g_dbus_command_line_print_literal (GApplicationCommandLine *cmdline, + const gchar *message) +{ + GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline; + + g_dbus_connection_call (gdbcl->connection, + gdbcl->bus_name, + gdbcl->object_path, + "org.gtk.private.CommandLine", "Print", + g_variant_new ("(s)", message), + NULL, 0, -1, NULL, NULL, NULL); +} + +static void +g_dbus_command_line_printerr_literal (GApplicationCommandLine *cmdline, + const gchar *message) +{ + GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline; + + g_dbus_connection_call (gdbcl->connection, + gdbcl->bus_name, + gdbcl->object_path, + "org.gtk.private.CommandLine", "PrintError", + g_variant_new ("(s)", message), + NULL, 0, -1, NULL, NULL, NULL); +} + +static GInputStream * +g_dbus_command_line_get_stdin (GApplicationCommandLine *cmdline) +{ +#ifdef G_OS_UNIX + GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline; + GInputStream *result = NULL; + GDBusMessage *message; + GUnixFDList *fd_list; + + message = g_dbus_method_invocation_get_message (gdbcl->invocation); + fd_list = g_dbus_message_get_unix_fd_list (message); + + if (fd_list && g_unix_fd_list_get_length (fd_list)) + { + gint *fds, n_fds, i; + + fds = g_unix_fd_list_steal_fds (fd_list, &n_fds); + result = g_unix_input_stream_new (fds[0], TRUE); + for (i = 1; i < n_fds; i++) + (void) g_close (fds[i], NULL); + g_free (fds); + } + + return result; +#else + return NULL; +#endif +} + +static void +g_dbus_command_line_finalize (GObject *object) +{ + GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object); + GDBusCommandLine *gdbcl = (GDBusCommandLine *) object; + gint status; + + status = g_application_command_line_get_exit_status (cmdline); + + g_dbus_method_invocation_return_value (gdbcl->invocation, + g_variant_new ("(i)", status)); + g_object_unref (gdbcl->invocation); + + G_OBJECT_CLASS (g_dbus_command_line_parent_class) + ->finalize (object); +} + +static void +g_dbus_command_line_init (GDBusCommandLine *gdbcl) +{ +} + +static void +g_dbus_command_line_class_init (GApplicationCommandLineClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_dbus_command_line_finalize; + class->printerr_literal = g_dbus_command_line_printerr_literal; + class->print_literal = g_dbus_command_line_print_literal; + class->get_stdin = g_dbus_command_line_get_stdin; +} + +static GApplicationCommandLine * +g_dbus_command_line_new (GDBusMethodInvocation *invocation) +{ + GDBusCommandLine *gdbcl; + GVariant *args; + GVariant *arguments, *platform_data; + + args = g_dbus_method_invocation_get_parameters (invocation); + + arguments = g_variant_get_child_value (args, 1); + platform_data = g_variant_get_child_value (args, 2); + gdbcl = g_object_new (g_dbus_command_line_get_type (), + "arguments", arguments, + "platform-data", platform_data, + NULL); + g_variant_unref (arguments); + g_variant_unref (platform_data); + + gdbcl->connection = g_dbus_method_invocation_get_connection (invocation); + gdbcl->bus_name = g_dbus_method_invocation_get_sender (invocation); + g_variant_get_child (args, 0, "&o", &gdbcl->object_path); + gdbcl->invocation = g_object_ref (invocation); + + return G_APPLICATION_COMMAND_LINE (gdbcl); +} + +/* Epilogue {{{1 */ + +/* vim:set foldmethod=marker: */ diff --git a/gio/gapplicationimpl.h b/gio/gapplicationimpl.h new file mode 100644 index 0000000..1e6a718 --- /dev/null +++ b/gio/gapplicationimpl.h @@ -0,0 +1,44 @@ +#include "giotypes.h" + +typedef struct _GApplicationImpl GApplicationImpl; + +typedef struct +{ + gchar *name; + + GVariantType *parameter_type; + gboolean enabled; + GVariant *state; +} RemoteActionInfo; + +void g_application_impl_destroy (GApplicationImpl *impl); + +GApplicationImpl * g_application_impl_register (GApplication *application, + const gchar *appid, + GApplicationFlags flags, + GActionGroup *exported_actions, + GRemoteActionGroup **remote_actions, + GCancellable *cancellable, + GError **error); + +void g_application_impl_activate (GApplicationImpl *impl, + GVariant *platform_data); + +void g_application_impl_open (GApplicationImpl *impl, + GFile **files, + gint n_files, + const gchar *hint, + GVariant *platform_data); + +int g_application_impl_command_line (GApplicationImpl *impl, + const gchar *const *arguments, + GVariant *platform_data); + +void g_application_impl_flush (GApplicationImpl *impl); + +GDBusConnection * g_application_impl_get_dbus_connection (GApplicationImpl *impl); + +const gchar * g_application_impl_get_dbus_object_path (GApplicationImpl *impl); + +void g_application_impl_set_busy_state (GApplicationImpl *impl, + gboolean busy); diff --git a/gio/gasynchelper.c b/gio/gasynchelper.c new file mode 100644 index 0000000..8b18835 --- /dev/null +++ b/gio/gasynchelper.c @@ -0,0 +1,87 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gasynchelper.h" + + +/*< private > + * SECTION:gasynchelper + * @short_description: Asynchronous Helper Functions + * @include: gio/gio.h + * @see_also: #GAsyncResult + * + * Provides helper functions for asynchronous operations. + * + **/ + +#ifdef G_OS_WIN32 +gboolean +_g_win32_overlap_wait_result (HANDLE hfile, + OVERLAPPED *overlap, + DWORD *transferred, + GCancellable *cancellable) +{ + GPollFD pollfd[2]; + gboolean result = FALSE; + gint num, npoll; + +#if GLIB_SIZEOF_VOID_P == 8 + pollfd[0].fd = (gint64)overlap->hEvent; +#else + pollfd[0].fd = (gint)overlap->hEvent; +#endif + pollfd[0].events = G_IO_IN; + num = 1; + + if (g_cancellable_make_pollfd (cancellable, &pollfd[1])) + num++; + +loop: + npoll = g_poll (pollfd, num, -1); + if (npoll <= 0) + /* error out, should never happen */ + goto end; + + if (g_cancellable_is_cancelled (cancellable)) + { + /* CancelIO only cancels pending operations issued by the + * current thread and since we're doing only sync operations, + * this is safe.... */ + /* CancelIoEx is only Vista+. Since we have only one overlap + * operation on this thread, we can just use: */ + result = CancelIo (hfile); + g_warn_if_fail (result); + } + + result = GetOverlappedResult (overlap->hEvent, overlap, transferred, FALSE); + if (result == FALSE && + GetLastError () == ERROR_IO_INCOMPLETE && + !g_cancellable_is_cancelled (cancellable)) + goto loop; + +end: + if (num > 1) + g_cancellable_release_fd (cancellable); + + return result; +} +#endif diff --git a/gio/gasynchelper.h b/gio/gasynchelper.h new file mode 100644 index 0000000..ded5a22 --- /dev/null +++ b/gio/gasynchelper.h @@ -0,0 +1,41 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_ASYNC_HELPER_H__ +#define __G_ASYNC_HELPER_H__ + +#include + +#ifdef G_OS_WIN32 +#include +#endif + +G_BEGIN_DECLS + +#ifdef G_OS_WIN32 +gboolean _g_win32_overlap_wait_result (HANDLE hfile, + OVERLAPPED *overlap, + DWORD *transferred, + GCancellable *cancellable); +#endif + +G_END_DECLS + +#endif /* __G_ASYNC_HELPER_H__ */ diff --git a/gio/gasyncinitable.c b/gio/gasyncinitable.c new file mode 100644 index 0000000..6af6506 --- /dev/null +++ b/gio/gasyncinitable.c @@ -0,0 +1,464 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "gasyncinitable.h" +#include "gasyncresult.h" +#include "gsimpleasyncresult.h" +#include "gtask.h" +#include "glibintl.h" + + +/** + * SECTION:gasyncinitable + * @short_description: Asynchronously failable object initialization interface + * @include: gio/gio.h + * @see_also: #GInitable + * + * This is the asynchronous version of #GInitable; it behaves the same + * in all ways except that initialization is asynchronous. For more details + * see the descriptions on #GInitable. + * + * A class may implement both the #GInitable and #GAsyncInitable interfaces. + * + * Users of objects implementing this are not intended to use the interface + * method directly; instead it will be used automatically in various ways. + * For C applications you generally just call g_async_initable_new_async() + * directly, or indirectly via a foo_thing_new_async() wrapper. This will call + * g_async_initable_init_async() under the cover, calling back with %NULL and + * a set %GError on failure. + * + * A typical implementation might look something like this: + * + * |[ + * enum { + * NOT_INITIALIZED, + * INITIALIZING, + * INITIALIZED + * }; + * + * static void + * _foo_ready_cb (Foo *self) + * { + * GList *l; + * + * self->priv->state = INITIALIZED; + * + * for (l = self->priv->init_results; l != NULL; l = l->next) + * { + * GTask *task = l->data; + * + * if (self->priv->success) + * g_task_return_boolean (task, TRUE); + * else + * g_task_return_new_error (task, ...); + * g_object_unref (task); + * } + * + * g_list_free (self->priv->init_results); + * self->priv->init_results = NULL; + * } + * + * static void + * foo_init_async (GAsyncInitable *initable, + * int io_priority, + * GCancellable *cancellable, + * GAsyncReadyCallback callback, + * gpointer user_data) + * { + * Foo *self = FOO (initable); + * GTask *task; + * + * task = g_task_new (initable, cancellable, callback, user_data); + * g_task_set_name (task, G_STRFUNC); + * + * switch (self->priv->state) + * { + * case NOT_INITIALIZED: + * _foo_get_ready (self); + * self->priv->init_results = g_list_append (self->priv->init_results, + * task); + * self->priv->state = INITIALIZING; + * break; + * case INITIALIZING: + * self->priv->init_results = g_list_append (self->priv->init_results, + * task); + * break; + * case INITIALIZED: + * if (!self->priv->success) + * g_task_return_new_error (task, ...); + * else + * g_task_return_boolean (task, TRUE); + * g_object_unref (task); + * break; + * } + * } + * + * static gboolean + * foo_init_finish (GAsyncInitable *initable, + * GAsyncResult *result, + * GError **error) + * { + * g_return_val_if_fail (g_task_is_valid (result, initable), FALSE); + * + * return g_task_propagate_boolean (G_TASK (result), error); + * } + * + * static void + * foo_async_initable_iface_init (gpointer g_iface, + * gpointer data) + * { + * GAsyncInitableIface *iface = g_iface; + * + * iface->init_async = foo_init_async; + * iface->init_finish = foo_init_finish; + * } + * ]| + */ + +static void g_async_initable_real_init_async (GAsyncInitable *initable, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_async_initable_real_init_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error); + + +typedef GAsyncInitableIface GAsyncInitableInterface; +G_DEFINE_INTERFACE (GAsyncInitable, g_async_initable, G_TYPE_OBJECT) + + +static void +g_async_initable_default_init (GAsyncInitableInterface *iface) +{ + iface->init_async = g_async_initable_real_init_async; + iface->init_finish = g_async_initable_real_init_finish; +} + +/** + * g_async_initable_init_async: + * @initable: a #GAsyncInitable. + * @io_priority: the [I/O priority][io-priority] of the operation + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to callback function + * + * Starts asynchronous initialization of the object implementing the + * interface. This must be done before any real use of the object after + * initial construction. If the object also implements #GInitable you can + * optionally call g_initable_init() instead. + * + * This method is intended for language bindings. If writing in C, + * g_async_initable_new_async() should typically be used instead. + * + * When the initialization is finished, @callback will be called. You can + * then call g_async_initable_init_finish() to get the result of the + * initialization. + * + * Implementations may also support cancellation. If @cancellable is not + * %NULL, then initialization can be cancelled by triggering the cancellable + * object from another thread. If the operation was cancelled, the error + * %G_IO_ERROR_CANCELLED will be returned. If @cancellable is not %NULL, and + * the object doesn't support cancellable initialization, the error + * %G_IO_ERROR_NOT_SUPPORTED will be returned. + * + * As with #GInitable, if the object is not initialized, or initialization + * returns with an error, then all operations on the object except + * g_object_ref() and g_object_unref() are considered to be invalid, and + * have undefined behaviour. They will often fail with g_critical() or + * g_warning(), but this must not be relied on. + * + * Callers should not assume that a class which implements #GAsyncInitable can + * be initialized multiple times; for more information, see g_initable_init(). + * If a class explicitly supports being initialized multiple times, + * implementation requires yielding all subsequent calls to init_async() on the + * results of the first call. + * + * For classes that also support the #GInitable interface, the default + * implementation of this method will run the g_initable_init() function + * in a thread, so if you want to support asynchronous initialization via + * threads, just implement the #GAsyncInitable interface without overriding + * any interface methods. + * + * Since: 2.22 + */ +void +g_async_initable_init_async (GAsyncInitable *initable, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GAsyncInitableIface *iface; + + g_return_if_fail (G_IS_ASYNC_INITABLE (initable)); + + iface = G_ASYNC_INITABLE_GET_IFACE (initable); + + (* iface->init_async) (initable, io_priority, cancellable, callback, user_data); +} + +/** + * g_async_initable_init_finish: + * @initable: a #GAsyncInitable. + * @res: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes asynchronous initialization and returns the result. + * See g_async_initable_init_async(). + * + * Returns: %TRUE if successful. If an error has occurred, this function + * will return %FALSE and set @error appropriately if present. + * + * Since: 2.22 + */ +gboolean +g_async_initable_init_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error) +{ + GAsyncInitableIface *iface; + + g_return_val_if_fail (G_IS_ASYNC_INITABLE (initable), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE); + + if (g_async_result_legacy_propagate_error (res, error)) + return FALSE; + + iface = G_ASYNC_INITABLE_GET_IFACE (initable); + + return (* iface->init_finish) (initable, res, error); +} + +static void +async_init_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + + if (g_initable_init (G_INITABLE (source_object), cancellable, &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +static void +g_async_initable_real_init_async (GAsyncInitable *initable, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + g_return_if_fail (G_IS_INITABLE (initable)); + + task = g_task_new (initable, cancellable, callback, user_data); + g_task_set_source_tag (task, g_async_initable_real_init_async); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, async_init_thread); + g_object_unref (task); +} + +static gboolean +g_async_initable_real_init_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error) +{ + /* For backward compatibility we have to process GSimpleAsyncResults + * even though g_async_initable_real_init_async doesn't generate + * them any more. + */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + if (G_IS_SIMPLE_ASYNC_RESULT (res)) + { + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return TRUE; + } + G_GNUC_END_IGNORE_DEPRECATIONS + + g_return_val_if_fail (g_task_is_valid (res, initable), FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} + +/** + * g_async_initable_new_async: + * @object_type: a #GType supporting #GAsyncInitable. + * @io_priority: the [I/O priority][io-priority] of the operation + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @callback: a #GAsyncReadyCallback to call when the initialization is + * finished + * @user_data: the data to pass to callback function + * @first_property_name: (nullable): the name of the first property, or %NULL if no + * properties + * @...: the value of the first property, followed by other property + * value pairs, and ended by %NULL. + * + * Helper function for constructing #GAsyncInitable object. This is + * similar to g_object_new() but also initializes the object asynchronously. + * + * When the initialization is finished, @callback will be called. You can + * then call g_async_initable_new_finish() to get the new object and check + * for any errors. + * + * Since: 2.22 + */ +void +g_async_initable_new_async (GType object_type, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + const gchar *first_property_name, + ...) +{ + va_list var_args; + + va_start (var_args, first_property_name); + g_async_initable_new_valist_async (object_type, + first_property_name, var_args, + io_priority, cancellable, + callback, user_data); + va_end (var_args); +} + +/** + * g_async_initable_newv_async: + * @object_type: a #GType supporting #GAsyncInitable. + * @n_parameters: the number of parameters in @parameters + * @parameters: the parameters to use to construct the object + * @io_priority: the [I/O priority][io-priority] of the operation + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @callback: a #GAsyncReadyCallback to call when the initialization is + * finished + * @user_data: the data to pass to callback function + * + * Helper function for constructing #GAsyncInitable object. This is + * similar to g_object_newv() but also initializes the object asynchronously. + * + * When the initialization is finished, @callback will be called. You can + * then call g_async_initable_new_finish() to get the new object and check + * for any errors. + * + * Since: 2.22 + * Deprecated: 2.54: Use g_object_new_with_properties() and + * g_async_initable_init_async() instead. See #GParameter for more information. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +void +g_async_initable_newv_async (GType object_type, + guint n_parameters, + GParameter *parameters, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GObject *obj; + + g_return_if_fail (G_TYPE_IS_ASYNC_INITABLE (object_type)); + + obj = g_object_newv (object_type, n_parameters, parameters); + + g_async_initable_init_async (G_ASYNC_INITABLE (obj), + io_priority, cancellable, + callback, user_data); + g_object_unref (obj); /* Passed ownership to async call */ +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_async_initable_new_valist_async: + * @object_type: a #GType supporting #GAsyncInitable. + * @first_property_name: the name of the first property, followed by + * the value, and other property value pairs, and ended by %NULL. + * @var_args: The var args list generated from @first_property_name. + * @io_priority: the [I/O priority][io-priority] of the operation + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @callback: a #GAsyncReadyCallback to call when the initialization is + * finished + * @user_data: the data to pass to callback function + * + * Helper function for constructing #GAsyncInitable object. This is + * similar to g_object_new_valist() but also initializes the object + * asynchronously. + * + * When the initialization is finished, @callback will be called. You can + * then call g_async_initable_new_finish() to get the new object and check + * for any errors. + * + * Since: 2.22 + */ +void +g_async_initable_new_valist_async (GType object_type, + const gchar *first_property_name, + va_list var_args, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GObject *obj; + + g_return_if_fail (G_TYPE_IS_ASYNC_INITABLE (object_type)); + + obj = g_object_new_valist (object_type, + first_property_name, + var_args); + + g_async_initable_init_async (G_ASYNC_INITABLE (obj), + io_priority, cancellable, + callback, user_data); + g_object_unref (obj); /* Passed ownership to async call */ +} + +/** + * g_async_initable_new_finish: + * @initable: the #GAsyncInitable from the callback + * @res: the #GAsyncResult from the callback + * @error: return location for errors, or %NULL to ignore + * + * Finishes the async construction for the various g_async_initable_new + * calls, returning the created object or %NULL on error. + * + * Returns: (type GObject.Object) (transfer full): a newly created #GObject, + * or %NULL on error. Free with g_object_unref(). + * + * Since: 2.22 + */ +GObject * +g_async_initable_new_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error) +{ + if (g_async_initable_init_finish (initable, res, error)) + return g_object_ref (G_OBJECT (initable)); + else + return NULL; +} diff --git a/gio/gasyncinitable.h b/gio/gasyncinitable.h new file mode 100644 index 0000000..f30d2ce --- /dev/null +++ b/gio/gasyncinitable.h @@ -0,0 +1,130 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_ASYNC_INITABLE_H__ +#define __G_ASYNC_INITABLE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_ASYNC_INITABLE (g_async_initable_get_type ()) +#define G_ASYNC_INITABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ASYNC_INITABLE, GAsyncInitable)) +#define G_IS_ASYNC_INITABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ASYNC_INITABLE)) +#define G_ASYNC_INITABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_ASYNC_INITABLE, GAsyncInitableIface)) +#define G_TYPE_IS_ASYNC_INITABLE(type) (g_type_is_a ((type), G_TYPE_ASYNC_INITABLE)) + +/** + * GAsyncInitable: + * + * Interface for asynchronously initializable objects. + * + * Since: 2.22 + **/ +typedef struct _GAsyncInitableIface GAsyncInitableIface; + +/** + * GAsyncInitableIface: + * @g_iface: The parent interface. + * @init_async: Starts initialization of the object. + * @init_finish: Finishes initialization of the object. + * + * Provides an interface for asynchronous initializing object such that + * initialization may fail. + * + * Since: 2.22 + **/ +struct _GAsyncInitableIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + void (* init_async) (GAsyncInitable *initable, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* init_finish) (GAsyncInitable *initable, + GAsyncResult *res, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_async_initable_get_type (void) G_GNUC_CONST; + + +GLIB_AVAILABLE_IN_ALL +void g_async_initable_init_async (GAsyncInitable *initable, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_async_initable_init_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_async_initable_new_async (GType object_type, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + const gchar *first_property_name, + ...); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +GLIB_DEPRECATED_IN_2_54_FOR(g_object_new_with_properties and g_async_initable_init_async) +void g_async_initable_newv_async (GType object_type, + guint n_parameters, + GParameter *parameters, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +G_GNUC_END_IGNORE_DEPRECATIONS + +GLIB_AVAILABLE_IN_ALL +void g_async_initable_new_valist_async (GType object_type, + const gchar *first_property_name, + va_list var_args, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GObject *g_async_initable_new_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error); + + + +G_END_DECLS + + +#endif /* __G_ASYNC_INITABLE_H__ */ diff --git a/gio/gasyncresult.c b/gio/gasyncresult.c new file mode 100644 index 0000000..b96f1ee --- /dev/null +++ b/gio/gasyncresult.c @@ -0,0 +1,237 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "gasyncresult.h" +#include "gsimpleasyncresult.h" +#include "glibintl.h" + + +/** + * SECTION:gasyncresult + * @short_description: Asynchronous Function Results + * @include: gio/gio.h + * @see_also: #GTask + * + * Provides a base class for implementing asynchronous function results. + * + * Asynchronous operations are broken up into two separate operations + * which are chained together by a #GAsyncReadyCallback. To begin + * an asynchronous operation, provide a #GAsyncReadyCallback to the + * asynchronous function. This callback will be triggered when the + * operation has completed, and must be run in a later iteration of + * the [thread-default main context][g-main-context-push-thread-default] + * from where the operation was initiated. It will be passed a + * #GAsyncResult instance filled with the details of the operation's + * success or failure, the object the asynchronous function was + * started for and any error codes returned. The asynchronous callback + * function is then expected to call the corresponding "_finish()" + * function, passing the object the function was called for, the + * #GAsyncResult instance, and (optionally) an @error to grab any + * error conditions that may have occurred. + * + * The "_finish()" function for an operation takes the generic result + * (of type #GAsyncResult) and returns the specific result that the + * operation in question yields (e.g. a #GFileEnumerator for a + * "enumerate children" operation). If the result or error status of the + * operation is not needed, there is no need to call the "_finish()" + * function; GIO will take care of cleaning up the result and error + * information after the #GAsyncReadyCallback returns. You can pass + * %NULL for the #GAsyncReadyCallback if you don't need to take any + * action at all after the operation completes. Applications may also + * take a reference to the #GAsyncResult and call "_finish()" later; + * however, the "_finish()" function may be called at most once. + * + * Example of a typical asynchronous operation flow: + * |[ + * void _theoretical_frobnitz_async (Theoretical *t, + * GCancellable *c, + * GAsyncReadyCallback cb, + * gpointer u); + * + * gboolean _theoretical_frobnitz_finish (Theoretical *t, + * GAsyncResult *res, + * GError **e); + * + * static void + * frobnitz_result_func (GObject *source_object, + * GAsyncResult *res, + * gpointer user_data) + * { + * gboolean success = FALSE; + * + * success = _theoretical_frobnitz_finish (source_object, res, NULL); + * + * if (success) + * g_printf ("Hurray!\n"); + * else + * g_printf ("Uh oh!\n"); + * + * ... + * + * } + * + * int main (int argc, void *argv[]) + * { + * ... + * + * _theoretical_frobnitz_async (theoretical_data, + * NULL, + * frobnitz_result_func, + * NULL); + * + * ... + * } + * ]| + * + * The callback for an asynchronous operation is called only once, and is + * always called, even in the case of a cancelled operation. On cancellation + * the result is a %G_IO_ERROR_CANCELLED error. + * + * ## I/O Priority # {#io-priority} + * + * Many I/O-related asynchronous operations have a priority parameter, + * which is used in certain cases to determine the order in which + * operations are executed. They are not used to determine system-wide + * I/O scheduling. Priorities are integers, with lower numbers indicating + * higher priority. It is recommended to choose priorities between + * %G_PRIORITY_LOW and %G_PRIORITY_HIGH, with %G_PRIORITY_DEFAULT + * as a default. + */ + +typedef GAsyncResultIface GAsyncResultInterface; +G_DEFINE_INTERFACE (GAsyncResult, g_async_result, G_TYPE_OBJECT) + +static void +g_async_result_default_init (GAsyncResultInterface *iface) +{ +} + +/** + * g_async_result_get_user_data: + * @res: a #GAsyncResult. + * + * Gets the user data from a #GAsyncResult. + * + * Returns: (transfer full): the user data for @res. + **/ +gpointer +g_async_result_get_user_data (GAsyncResult *res) +{ + GAsyncResultIface *iface; + + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + iface = G_ASYNC_RESULT_GET_IFACE (res); + + return (* iface->get_user_data) (res); +} + +/** + * g_async_result_get_source_object: + * @res: a #GAsyncResult + * + * Gets the source object from a #GAsyncResult. + * + * Returns: (transfer full) (nullable): a new reference to the source + * object for the @res, or %NULL if there is none. + */ +GObject * +g_async_result_get_source_object (GAsyncResult *res) +{ + GAsyncResultIface *iface; + + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + iface = G_ASYNC_RESULT_GET_IFACE (res); + + return (* iface->get_source_object) (res); +} + +/** + * g_async_result_legacy_propagate_error: + * @res: a #GAsyncResult + * @error: (out): a location to propagate the error to. + * + * If @res is a #GSimpleAsyncResult, this is equivalent to + * g_simple_async_result_propagate_error(). Otherwise it returns + * %FALSE. + * + * This can be used for legacy error handling in async *_finish() + * wrapper functions that traditionally handled #GSimpleAsyncResult + * error returns themselves rather than calling into the virtual method. + * This should not be used in new code; #GAsyncResult errors that are + * set by virtual methods should also be extracted by virtual methods, + * to enable subclasses to chain up correctly. + * + * Returns: %TRUE if @error is has been filled in with an error from + * @res, %FALSE if not. + * + * Since: 2.34 + **/ +gboolean +g_async_result_legacy_propagate_error (GAsyncResult *res, + GError **error) +{ + /* This doesn't use a vmethod, because it's only for code that used + * to use GSimpleAsyncResult. (But it's a GAsyncResult method so + * that callers don't need to worry about GSimpleAsyncResult + * deprecation warnings in the future.) + */ + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + if (G_IS_SIMPLE_ASYNC_RESULT (res)) + { + return g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), + error); + } + else + return FALSE; + G_GNUC_END_IGNORE_DEPRECATIONS +} + +/** + * g_async_result_is_tagged: + * @res: a #GAsyncResult + * @source_tag: an application-defined tag + * + * Checks if @res has the given @source_tag (generally a function + * pointer indicating the function @res was created by). + * + * Returns: %TRUE if @res has the indicated @source_tag, %FALSE if + * not. + * + * Since: 2.34 + **/ +gboolean +g_async_result_is_tagged (GAsyncResult *res, + gpointer source_tag) +{ + GAsyncResultIface *iface; + + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE); + + iface = G_ASYNC_RESULT_GET_IFACE (res); + + if (!iface->is_tagged) + return FALSE; + + return (* iface->is_tagged) (res, source_tag); +} diff --git a/gio/gasyncresult.h b/gio/gasyncresult.h new file mode 100644 index 0000000..956cbc4 --- /dev/null +++ b/gio/gasyncresult.h @@ -0,0 +1,85 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_ASYNC_RESULT_H__ +#define __G_ASYNC_RESULT_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_ASYNC_RESULT (g_async_result_get_type ()) +#define G_ASYNC_RESULT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ASYNC_RESULT, GAsyncResult)) +#define G_IS_ASYNC_RESULT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ASYNC_RESULT)) +#define G_ASYNC_RESULT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_ASYNC_RESULT, GAsyncResultIface)) + +/** + * GAsyncResult: + * + * Holds results information for an asynchronous operation, + * usually passed directly to an asynchronous _finish() operation. + **/ +typedef struct _GAsyncResultIface GAsyncResultIface; + + +/** + * GAsyncResultIface: + * @g_iface: The parent interface. + * @get_user_data: Gets the user data passed to the callback. + * @get_source_object: Gets the source object that issued the asynchronous operation. + * @is_tagged: Checks if a result is tagged with a particular source. + * + * Interface definition for #GAsyncResult. + **/ +struct _GAsyncResultIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + gpointer (* get_user_data) (GAsyncResult *res); + GObject * (* get_source_object) (GAsyncResult *res); + + gboolean (* is_tagged) (GAsyncResult *res, + gpointer source_tag); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_async_result_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gpointer g_async_result_get_user_data (GAsyncResult *res); +GLIB_AVAILABLE_IN_ALL +GObject *g_async_result_get_source_object (GAsyncResult *res); + +GLIB_AVAILABLE_IN_2_34 +gboolean g_async_result_legacy_propagate_error (GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_2_34 +gboolean g_async_result_is_tagged (GAsyncResult *res, + gpointer source_tag); + +G_END_DECLS + +#endif /* __G_ASYNC_RESULT_H__ */ diff --git a/gio/gbufferedinputstream.c b/gio/gbufferedinputstream.c new file mode 100644 index 0000000..d9f150d --- /dev/null +++ b/gio/gbufferedinputstream.c @@ -0,0 +1,1275 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2007 Jürg Billeter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#include "config.h" +#include "gbufferedinputstream.h" +#include "ginputstream.h" +#include "gcancellable.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "gseekable.h" +#include "gioerror.h" +#include +#include "glibintl.h" + + +/** + * SECTION:gbufferedinputstream + * @short_description: Buffered Input Stream + * @include: gio/gio.h + * @see_also: #GFilterInputStream, #GInputStream + * + * Buffered input stream implements #GFilterInputStream and provides + * for buffered reads. + * + * By default, #GBufferedInputStream's buffer size is set at 4 kilobytes. + * + * To create a buffered input stream, use g_buffered_input_stream_new(), + * or g_buffered_input_stream_new_sized() to specify the buffer's size at + * construction. + * + * To get the size of a buffer within a buffered input stream, use + * g_buffered_input_stream_get_buffer_size(). To change the size of a + * buffered input stream's buffer, use + * g_buffered_input_stream_set_buffer_size(). Note that the buffer's size + * cannot be reduced below the size of the data within the buffer. + */ + + +#define DEFAULT_BUFFER_SIZE 4096 + +struct _GBufferedInputStreamPrivate { + guint8 *buffer; + gsize len; + gsize pos; + gsize end; + GAsyncReadyCallback outstanding_callback; +}; + +enum { + PROP_0, + PROP_BUFSIZE +}; + +static void g_buffered_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static void g_buffered_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void g_buffered_input_stream_finalize (GObject *object); + + +static gssize g_buffered_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error); +static void g_buffered_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gssize g_buffered_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); +static gssize g_buffered_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gssize g_buffered_input_stream_real_fill (GBufferedInputStream *stream, + gssize count, + GCancellable *cancellable, + GError **error); +static void g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream, + gssize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gssize g_buffered_input_stream_real_fill_finish (GBufferedInputStream *stream, + GAsyncResult *result, + GError **error); + +static void g_buffered_input_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_buffered_input_stream_tell (GSeekable *seekable); +static gboolean g_buffered_input_stream_can_seek (GSeekable *seekable); +static gboolean g_buffered_input_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_buffered_input_stream_can_truncate (GSeekable *seekable); +static gboolean g_buffered_input_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); + +static void compact_buffer (GBufferedInputStream *stream); + +G_DEFINE_TYPE_WITH_CODE (GBufferedInputStream, + g_buffered_input_stream, + G_TYPE_FILTER_INPUT_STREAM, + G_ADD_PRIVATE (GBufferedInputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_buffered_input_stream_seekable_iface_init)) + +static void +g_buffered_input_stream_class_init (GBufferedInputStreamClass *klass) +{ + GObjectClass *object_class; + GInputStreamClass *istream_class; + GBufferedInputStreamClass *bstream_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = g_buffered_input_stream_get_property; + object_class->set_property = g_buffered_input_stream_set_property; + object_class->finalize = g_buffered_input_stream_finalize; + + istream_class = G_INPUT_STREAM_CLASS (klass); + istream_class->skip = g_buffered_input_stream_skip; + istream_class->skip_async = g_buffered_input_stream_skip_async; + istream_class->skip_finish = g_buffered_input_stream_skip_finish; + istream_class->read_fn = g_buffered_input_stream_read; + + bstream_class = G_BUFFERED_INPUT_STREAM_CLASS (klass); + bstream_class->fill = g_buffered_input_stream_real_fill; + bstream_class->fill_async = g_buffered_input_stream_real_fill_async; + bstream_class->fill_finish = g_buffered_input_stream_real_fill_finish; + + g_object_class_install_property (object_class, + PROP_BUFSIZE, + g_param_spec_uint ("buffer-size", + P_("Buffer Size"), + P_("The size of the backend buffer"), + 1, + G_MAXUINT, + DEFAULT_BUFFER_SIZE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + +} + +/** + * g_buffered_input_stream_get_buffer_size: + * @stream: a #GBufferedInputStream + * + * Gets the size of the input buffer. + * + * Returns: the current buffer size. + */ +gsize +g_buffered_input_stream_get_buffer_size (GBufferedInputStream *stream) +{ + g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), 0); + + return stream->priv->len; +} + +/** + * g_buffered_input_stream_set_buffer_size: + * @stream: a #GBufferedInputStream + * @size: a #gsize + * + * Sets the size of the internal buffer of @stream to @size, or to the + * size of the contents of the buffer. The buffer can never be resized + * smaller than its current contents. + */ +void +g_buffered_input_stream_set_buffer_size (GBufferedInputStream *stream, + gsize size) +{ + GBufferedInputStreamPrivate *priv; + gsize in_buffer; + guint8 *buffer; + + g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream)); + + priv = stream->priv; + + if (priv->len == size) + return; + + if (priv->buffer) + { + in_buffer = priv->end - priv->pos; + + /* Never resize smaller than current buffer contents */ + size = MAX (size, in_buffer); + + buffer = g_malloc (size); + memcpy (buffer, priv->buffer + priv->pos, in_buffer); + priv->len = size; + priv->pos = 0; + priv->end = in_buffer; + g_free (priv->buffer); + priv->buffer = buffer; + } + else + { + priv->len = size; + priv->pos = 0; + priv->end = 0; + priv->buffer = g_malloc (size); + } + + g_object_notify (G_OBJECT (stream), "buffer-size"); +} + +static void +g_buffered_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GBufferedInputStream *bstream; + + bstream = G_BUFFERED_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_BUFSIZE: + g_buffered_input_stream_set_buffer_size (bstream, g_value_get_uint (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_buffered_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GBufferedInputStreamPrivate *priv; + GBufferedInputStream *bstream; + + bstream = G_BUFFERED_INPUT_STREAM (object); + priv = bstream->priv; + + switch (prop_id) + { + case PROP_BUFSIZE: + g_value_set_uint (value, priv->len); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_buffered_input_stream_finalize (GObject *object) +{ + GBufferedInputStreamPrivate *priv; + GBufferedInputStream *stream; + + stream = G_BUFFERED_INPUT_STREAM (object); + priv = stream->priv; + + g_free (priv->buffer); + + G_OBJECT_CLASS (g_buffered_input_stream_parent_class)->finalize (object); +} + +static void +g_buffered_input_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_buffered_input_stream_tell; + iface->can_seek = g_buffered_input_stream_can_seek; + iface->seek = g_buffered_input_stream_seek; + iface->can_truncate = g_buffered_input_stream_can_truncate; + iface->truncate_fn = g_buffered_input_stream_truncate; +} + +static void +g_buffered_input_stream_init (GBufferedInputStream *stream) +{ + stream->priv = g_buffered_input_stream_get_instance_private (stream); +} + + +/** + * g_buffered_input_stream_new: + * @base_stream: a #GInputStream + * + * Creates a new #GInputStream from the given @base_stream, with + * a buffer set to the default size (4 kilobytes). + * + * Returns: a #GInputStream for the given @base_stream. + */ +GInputStream * +g_buffered_input_stream_new (GInputStream *base_stream) +{ + GInputStream *stream; + + g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL); + + stream = g_object_new (G_TYPE_BUFFERED_INPUT_STREAM, + "base-stream", base_stream, + NULL); + + return stream; +} + +/** + * g_buffered_input_stream_new_sized: + * @base_stream: a #GInputStream + * @size: a #gsize + * + * Creates a new #GBufferedInputStream from the given @base_stream, + * with a buffer set to @size. + * + * Returns: a #GInputStream. + */ +GInputStream * +g_buffered_input_stream_new_sized (GInputStream *base_stream, + gsize size) +{ + GInputStream *stream; + + g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL); + + stream = g_object_new (G_TYPE_BUFFERED_INPUT_STREAM, + "base-stream", base_stream, + "buffer-size", (guint)size, + NULL); + + return stream; +} + +/** + * g_buffered_input_stream_fill: + * @stream: a #GBufferedInputStream + * @count: the number of bytes that will be read from the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to read @count bytes from the stream into the buffer. + * Will block during this read. + * + * If @count is zero, returns zero and does nothing. A value of @count + * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error. + * + * On success, the number of bytes read into the buffer is returned. + * It is not an error if this is not the same as the requested size, as it + * can happen e.g. near the end of a file. Zero is returned on end of file + * (or if @count is zero), but never otherwise. + * + * If @count is -1 then the attempted read size is equal to the number of + * bytes that are required to fill the buffer. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an + * operation was partially finished when the operation was cancelled the + * partial result will be returned, without an error. + * + * On error -1 is returned and @error is set accordingly. + * + * For the asynchronous, non-blocking, version of this function, see + * g_buffered_input_stream_fill_async(). + * + * Returns: the number of bytes read into @stream's buffer, up to @count, + * or -1 on error. + */ +gssize +g_buffered_input_stream_fill (GBufferedInputStream *stream, + gssize count, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStreamClass *class; + GInputStream *input_stream; + gssize res; + + g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1); + + input_stream = G_INPUT_STREAM (stream); + + if (count < -1) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), G_STRFUNC); + return -1; + } + + if (!g_input_stream_set_pending (input_stream, error)) + return -1; + + if (cancellable) + g_cancellable_push_current (cancellable); + + class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream); + res = class->fill (stream, count, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_input_stream_clear_pending (input_stream); + + return res; +} + +static void +async_fill_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (source_object); + + g_input_stream_clear_pending (G_INPUT_STREAM (stream)); + (*stream->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (stream); +} + +/** + * g_buffered_input_stream_fill_async: + * @stream: a #GBufferedInputStream + * @count: the number of bytes that will be read from the stream + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): a #gpointer + * + * Reads data into @stream's buffer asynchronously, up to @count size. + * @io_priority can be used to prioritize reads. For the synchronous + * version of this function, see g_buffered_input_stream_fill(). + * + * If @count is -1 then the attempted read size is equal to the number + * of bytes that are required to fill the buffer. + */ +void +g_buffered_input_stream_fill_async (GBufferedInputStream *stream, + gssize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GBufferedInputStreamClass *class; + GError *error = NULL; + + g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream)); + + if (count == 0) + { + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_buffered_input_stream_fill_async); + g_task_return_int (task, 0); + g_object_unref (task); + return; + } + + if (count < -1) + { + g_task_report_new_error (stream, callback, user_data, + g_buffered_input_stream_fill_async, + G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), + G_STRFUNC); + return; + } + + if (!g_input_stream_set_pending (G_INPUT_STREAM (stream), &error)) + { + g_task_report_error (stream, callback, user_data, + g_buffered_input_stream_fill_async, + error); + return; + } + + class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream); + + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + class->fill_async (stream, count, io_priority, cancellable, + async_fill_callback_wrapper, user_data); +} + +/** + * g_buffered_input_stream_fill_finish: + * @stream: a #GBufferedInputStream + * @result: a #GAsyncResult + * @error: a #GError + * + * Finishes an asynchronous read. + * + * Returns: a #gssize of the read stream, or `-1` on an error. + */ +gssize +g_buffered_input_stream_fill_finish (GBufferedInputStream *stream, + GAsyncResult *result, + GError **error) +{ + GBufferedInputStreamClass *class; + + g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1); + + if (g_async_result_legacy_propagate_error (result, error)) + return -1; + else if (g_async_result_is_tagged (result, g_buffered_input_stream_fill_async)) + return g_task_propagate_int (G_TASK (result), error); + + class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream); + return class->fill_finish (stream, result, error); +} + +/** + * g_buffered_input_stream_get_available: + * @stream: #GBufferedInputStream + * + * Gets the size of the available data within the stream. + * + * Returns: size of the available stream. + */ +gsize +g_buffered_input_stream_get_available (GBufferedInputStream *stream) +{ + g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1); + + return stream->priv->end - stream->priv->pos; +} + +/** + * g_buffered_input_stream_peek: + * @stream: a #GBufferedInputStream + * @buffer: (array length=count) (element-type guint8): a pointer to + * an allocated chunk of memory + * @offset: a #gsize + * @count: a #gsize + * + * Peeks in the buffer, copying data of size @count into @buffer, + * offset @offset bytes. + * + * Returns: a #gsize of the number of bytes peeked, or -1 on error. + */ +gsize +g_buffered_input_stream_peek (GBufferedInputStream *stream, + void *buffer, + gsize offset, + gsize count) +{ + gsize available; + gsize end; + + g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1); + g_return_val_if_fail (buffer != NULL, -1); + + available = g_buffered_input_stream_get_available (stream); + + if (offset > available) + return 0; + + end = MIN (offset + count, available); + count = end - offset; + + memcpy (buffer, stream->priv->buffer + stream->priv->pos + offset, count); + return count; +} + +/** + * g_buffered_input_stream_peek_buffer: + * @stream: a #GBufferedInputStream + * @count: (out): a #gsize to get the number of bytes available in the buffer + * + * Returns the buffer with the currently available bytes. The returned + * buffer must not be modified and will become invalid when reading from + * the stream or filling the buffer. + * + * Returns: (array length=count) (element-type guint8) (transfer none): + * read-only buffer + */ +const void* +g_buffered_input_stream_peek_buffer (GBufferedInputStream *stream, + gsize *count) +{ + GBufferedInputStreamPrivate *priv; + + g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), NULL); + + priv = stream->priv; + + if (count) + *count = priv->end - priv->pos; + + return priv->buffer + priv->pos; +} + +static void +compact_buffer (GBufferedInputStream *stream) +{ + GBufferedInputStreamPrivate *priv; + gsize current_size; + + priv = stream->priv; + + current_size = priv->end - priv->pos; + + memmove (priv->buffer, priv->buffer + priv->pos, current_size); + + priv->pos = 0; + priv->end = current_size; +} + +static gssize +g_buffered_input_stream_real_fill (GBufferedInputStream *stream, + gssize count, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStreamPrivate *priv; + GInputStream *base_stream; + gssize nread; + gsize in_buffer; + + priv = stream->priv; + + if (count == -1) + count = priv->len; + + in_buffer = priv->end - priv->pos; + + /* Never fill more than can fit in the buffer */ + count = MIN ((gsize) count, priv->len - in_buffer); + + /* If requested length does not fit at end, compact */ + if (priv->len - priv->end < (gsize) count) + compact_buffer (stream); + + base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + nread = g_input_stream_read (base_stream, + priv->buffer + priv->end, + count, + cancellable, + error); + + if (nread > 0) + priv->end += nread; + + return nread; +} + +static gssize +g_buffered_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStream *bstream; + GBufferedInputStreamPrivate *priv; + GBufferedInputStreamClass *class; + GInputStream *base_stream; + gsize available, bytes_skipped; + gssize nread; + + bstream = G_BUFFERED_INPUT_STREAM (stream); + priv = bstream->priv; + + available = priv->end - priv->pos; + + if (count <= available) + { + priv->pos += count; + return count; + } + + /* Full request not available, skip all currently available and + * request refill for more + */ + + priv->pos = 0; + priv->end = 0; + bytes_skipped = available; + count -= available; + + if (bytes_skipped > 0) + error = NULL; /* Ignore further errors if we already read some data */ + + if (count > priv->len) + { + /* Large request, shortcut buffer */ + + base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + + nread = g_input_stream_skip (base_stream, + count, + cancellable, + error); + + if (nread < 0 && bytes_skipped == 0) + return -1; + + if (nread > 0) + bytes_skipped += nread; + + return bytes_skipped; + } + + class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream); + nread = class->fill (bstream, priv->len, cancellable, error); + + if (nread < 0) + { + if (bytes_skipped == 0) + return -1; + else + return bytes_skipped; + } + + available = priv->end - priv->pos; + count = MIN (count, available); + + bytes_skipped += count; + priv->pos += count; + + return bytes_skipped; +} + +static gssize +g_buffered_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStream *bstream; + GBufferedInputStreamPrivate *priv; + GBufferedInputStreamClass *class; + GInputStream *base_stream; + gsize available, bytes_read; + gssize nread; + + bstream = G_BUFFERED_INPUT_STREAM (stream); + priv = bstream->priv; + + available = priv->end - priv->pos; + + if (count <= available) + { + memcpy (buffer, priv->buffer + priv->pos, count); + priv->pos += count; + return count; + } + + /* Full request not available, read all currently available and + * request refill for more + */ + + memcpy (buffer, priv->buffer + priv->pos, available); + priv->pos = 0; + priv->end = 0; + bytes_read = available; + count -= available; + + if (bytes_read > 0) + error = NULL; /* Ignore further errors if we already read some data */ + + if (count > priv->len) + { + /* Large request, shortcut buffer */ + + base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + + nread = g_input_stream_read (base_stream, + (char *)buffer + bytes_read, + count, + cancellable, + error); + + if (nread < 0 && bytes_read == 0) + return -1; + + if (nread > 0) + bytes_read += nread; + + return bytes_read; + } + + class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream); + nread = class->fill (bstream, priv->len, cancellable, error); + if (nread < 0) + { + if (bytes_read == 0) + return -1; + else + return bytes_read; + } + + available = priv->end - priv->pos; + count = MIN (count, available); + + memcpy ((char *)buffer + bytes_read, (char *)priv->buffer + priv->pos, count); + bytes_read += count; + priv->pos += count; + + return bytes_read; +} + +static goffset +g_buffered_input_stream_tell (GSeekable *seekable) +{ + GBufferedInputStream *bstream; + GBufferedInputStreamPrivate *priv; + GInputStream *base_stream; + GSeekable *base_stream_seekable; + gsize available; + goffset base_offset; + + bstream = G_BUFFERED_INPUT_STREAM (seekable); + priv = bstream->priv; + + base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream; + if (!G_IS_SEEKABLE (base_stream)) + return 0; + base_stream_seekable = G_SEEKABLE (base_stream); + + available = priv->end - priv->pos; + base_offset = g_seekable_tell (base_stream_seekable); + + return base_offset - available; +} + +static gboolean +g_buffered_input_stream_can_seek (GSeekable *seekable) +{ + GInputStream *base_stream; + + base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream; + return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream)); +} + +static gboolean +g_buffered_input_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStream *bstream; + GBufferedInputStreamPrivate *priv; + GInputStream *base_stream; + GSeekable *base_stream_seekable; + + bstream = G_BUFFERED_INPUT_STREAM (seekable); + priv = bstream->priv; + + base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream; + if (!G_IS_SEEKABLE (base_stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Seek not supported on base stream")); + return FALSE; + } + + base_stream_seekable = G_SEEKABLE (base_stream); + + if (type == G_SEEK_CUR) + { + if (offset <= (goffset) (priv->end - priv->pos) && + offset >= (goffset) -priv->pos) + { + priv->pos += offset; + return TRUE; + } + else + { + offset -= priv->end - priv->pos; + } + } + + if (g_seekable_seek (base_stream_seekable, offset, type, cancellable, error)) + { + priv->pos = 0; + priv->end = 0; + return TRUE; + } + else + { + return FALSE; + } +} + +static gboolean +g_buffered_input_stream_can_truncate (GSeekable *seekable) +{ + return FALSE; +} + +static gboolean +g_buffered_input_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Cannot truncate GBufferedInputStream")); + return FALSE; +} + +/** + * g_buffered_input_stream_read_byte: + * @stream: a #GBufferedInputStream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to read a single byte from the stream or the buffer. Will block + * during this read. + * + * On success, the byte read from the stream is returned. On end of stream + * -1 is returned but it's not an exceptional error and @error is not set. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an + * operation was partially finished when the operation was cancelled the + * partial result will be returned, without an error. + * + * On error -1 is returned and @error is set accordingly. + * + * Returns: the byte read from the @stream, or -1 on end of stream or error. + */ +int +g_buffered_input_stream_read_byte (GBufferedInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStreamPrivate *priv; + GBufferedInputStreamClass *class; + GInputStream *input_stream; + gsize available; + gssize nread; + + g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1); + + priv = stream->priv; + input_stream = G_INPUT_STREAM (stream); + + if (g_input_stream_is_closed (input_stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Stream is already closed")); + return -1; + } + + if (!g_input_stream_set_pending (input_stream, error)) + return -1; + + available = priv->end - priv->pos; + + if (available != 0) + { + g_input_stream_clear_pending (input_stream); + return priv->buffer[priv->pos++]; + } + + /* Byte not available, request refill for more */ + + if (cancellable) + g_cancellable_push_current (cancellable); + + priv->pos = 0; + priv->end = 0; + + class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream); + nread = class->fill (stream, priv->len, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_input_stream_clear_pending (input_stream); + + if (nread <= 0) + return -1; /* error or end of stream */ + + return priv->buffer[priv->pos++]; +} + +/* ************************** */ +/* Async stuff implementation */ +/* ************************** */ + +static void +fill_async_callback (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error; + gssize res; + GTask *task = user_data; + + error = NULL; + res = g_input_stream_read_finish (G_INPUT_STREAM (source_object), + result, &error); + if (res == -1) + g_task_return_error (task, error); + else + { + GBufferedInputStream *stream; + GBufferedInputStreamPrivate *priv; + + stream = g_task_get_source_object (task); + priv = G_BUFFERED_INPUT_STREAM (stream)->priv; + + g_assert_cmpint (priv->end + res, <=, priv->len); + priv->end += res; + + g_task_return_int (task, res); + } + + g_object_unref (task); +} + +static void +g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream, + gssize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GBufferedInputStreamPrivate *priv; + GInputStream *base_stream; + GTask *task; + gsize in_buffer; + + priv = stream->priv; + + if (count == -1) + count = priv->len; + + in_buffer = priv->end - priv->pos; + + /* Never fill more than can fit in the buffer */ + count = MIN ((gsize) count, priv->len - in_buffer); + + /* If requested length does not fit at end, compact */ + if (priv->len - priv->end < (gsize) count) + compact_buffer (stream); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_buffered_input_stream_real_fill_async); + + base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + g_input_stream_read_async (base_stream, + priv->buffer + priv->end, + count, + io_priority, + cancellable, + fill_async_callback, + task); +} + +static gssize +g_buffered_input_stream_real_fill_finish (GBufferedInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), -1); + + return g_task_propagate_int (G_TASK (result), error); +} + +typedef struct +{ + gsize bytes_skipped; + gsize count; +} SkipAsyncData; + +static void +free_skip_async_data (gpointer _data) +{ + SkipAsyncData *data = _data; + g_slice_free (SkipAsyncData, data); +} + +static void +large_skip_callback (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + SkipAsyncData *data; + GError *error; + gssize nread; + + data = g_task_get_task_data (task); + + error = NULL; + nread = g_input_stream_skip_finish (G_INPUT_STREAM (source_object), + result, &error); + + /* Only report the error if we've not already read some data */ + if (nread < 0 && data->bytes_skipped == 0) + g_task_return_error (task, error); + else + { + if (error) + g_error_free (error); + + if (nread > 0) + data->bytes_skipped += nread; + + g_task_return_int (task, data->bytes_skipped); + } + + g_object_unref (task); +} + +static void +skip_fill_buffer_callback (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + GBufferedInputStream *bstream; + GBufferedInputStreamPrivate *priv; + SkipAsyncData *data; + GError *error; + gssize nread; + gsize available; + + bstream = G_BUFFERED_INPUT_STREAM (source_object); + priv = bstream->priv; + + data = g_task_get_task_data (task); + + error = NULL; + nread = g_buffered_input_stream_fill_finish (bstream, + result, &error); + + if (nread < 0 && data->bytes_skipped == 0) + g_task_return_error (task, error); + else + { + if (error) + g_error_free (error); + + if (nread > 0) + { + available = priv->end - priv->pos; + data->count = MIN (data->count, available); + + data->bytes_skipped += data->count; + priv->pos += data->count; + } + + g_assert (data->bytes_skipped <= G_MAXSSIZE); + g_task_return_int (task, data->bytes_skipped); + } + + g_object_unref (task); +} + +static void +g_buffered_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GBufferedInputStream *bstream; + GBufferedInputStreamPrivate *priv; + GBufferedInputStreamClass *class; + GInputStream *base_stream; + gsize available; + GTask *task; + SkipAsyncData *data; + + bstream = G_BUFFERED_INPUT_STREAM (stream); + priv = bstream->priv; + + data = g_slice_new (SkipAsyncData); + data->bytes_skipped = 0; + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_buffered_input_stream_skip_async); + g_task_set_task_data (task, data, free_skip_async_data); + + available = priv->end - priv->pos; + + if (count <= available) + { + priv->pos += count; + + g_task_return_int (task, count); + g_object_unref (task); + return; + } + + /* Full request not available, skip all currently available + * and request refill for more + */ + + priv->pos = 0; + priv->end = 0; + + count -= available; + + data->bytes_skipped = available; + data->count = count; + + if (count > priv->len) + { + /* Large request, shortcut buffer */ + base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + + /* If 'count > G_MAXSSIZE then 'g_input_stream_skip_async()' + * will return an error anyway before calling this. + * Assert that this is never called for too big `count` for clarity. */ + g_assert ((gssize) count >= 0); + g_input_stream_skip_async (base_stream, + count, + io_priority, cancellable, + large_skip_callback, + task); + } + else + { + class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream); + class->fill_async (bstream, priv->len, io_priority, cancellable, + skip_fill_buffer_callback, task); + } +} + +static gssize +g_buffered_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), -1); + + return g_task_propagate_int (G_TASK (result), error); +} diff --git a/gio/gbufferedinputstream.h b/gio/gbufferedinputstream.h new file mode 100644 index 0000000..19c4214 --- /dev/null +++ b/gio/gbufferedinputstream.h @@ -0,0 +1,133 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#ifndef __G_BUFFERED_INPUT_STREAM_H__ +#define __G_BUFFERED_INPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_BUFFERED_INPUT_STREAM (g_buffered_input_stream_get_type ()) +#define G_BUFFERED_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStream)) +#define G_BUFFERED_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStreamClass)) +#define G_IS_BUFFERED_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_BUFFERED_INPUT_STREAM)) +#define G_IS_BUFFERED_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_BUFFERED_INPUT_STREAM)) +#define G_BUFFERED_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStreamClass)) + +/** + * GBufferedInputStream: + * + * Implements #GFilterInputStream with a sized input buffer. + **/ +typedef struct _GBufferedInputStreamClass GBufferedInputStreamClass; +typedef struct _GBufferedInputStreamPrivate GBufferedInputStreamPrivate; + +struct _GBufferedInputStream +{ + GFilterInputStream parent_instance; + + /*< private >*/ + GBufferedInputStreamPrivate *priv; +}; + +struct _GBufferedInputStreamClass +{ + GFilterInputStreamClass parent_class; + + gssize (* fill) (GBufferedInputStream *stream, + gssize count, + GCancellable *cancellable, + GError **error); + + /* Async ops: (optional in derived classes) */ + void (* fill_async) (GBufferedInputStream *stream, + gssize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gssize (* fill_finish) (GBufferedInputStream *stream, + GAsyncResult *result, + GError **error); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_buffered_input_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GInputStream* g_buffered_input_stream_new (GInputStream *base_stream); +GLIB_AVAILABLE_IN_ALL +GInputStream* g_buffered_input_stream_new_sized (GInputStream *base_stream, + gsize size); + +GLIB_AVAILABLE_IN_ALL +gsize g_buffered_input_stream_get_buffer_size (GBufferedInputStream *stream); +GLIB_AVAILABLE_IN_ALL +void g_buffered_input_stream_set_buffer_size (GBufferedInputStream *stream, + gsize size); +GLIB_AVAILABLE_IN_ALL +gsize g_buffered_input_stream_get_available (GBufferedInputStream *stream); +GLIB_AVAILABLE_IN_ALL +gsize g_buffered_input_stream_peek (GBufferedInputStream *stream, + void *buffer, + gsize offset, + gsize count); +GLIB_AVAILABLE_IN_ALL +const void* g_buffered_input_stream_peek_buffer (GBufferedInputStream *stream, + gsize *count); + +GLIB_AVAILABLE_IN_ALL +gssize g_buffered_input_stream_fill (GBufferedInputStream *stream, + gssize count, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_buffered_input_stream_fill_async (GBufferedInputStream *stream, + gssize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gssize g_buffered_input_stream_fill_finish (GBufferedInputStream *stream, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +int g_buffered_input_stream_read_byte (GBufferedInputStream *stream, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* __G_BUFFERED_INPUT_STREAM_H__ */ diff --git a/gio/gbufferedoutputstream.c b/gio/gbufferedoutputstream.c new file mode 100644 index 0000000..969bbae --- /dev/null +++ b/gio/gbufferedoutputstream.c @@ -0,0 +1,755 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#include "config.h" +#include "gbufferedoutputstream.h" +#include "goutputstream.h" +#include "gseekable.h" +#include "gtask.h" +#include "string.h" +#include "gioerror.h" +#include "glibintl.h" + +/** + * SECTION:gbufferedoutputstream + * @short_description: Buffered Output Stream + * @include: gio/gio.h + * @see_also: #GFilterOutputStream, #GOutputStream + * + * Buffered output stream implements #GFilterOutputStream and provides + * for buffered writes. + * + * By default, #GBufferedOutputStream's buffer size is set at 4 kilobytes. + * + * To create a buffered output stream, use g_buffered_output_stream_new(), + * or g_buffered_output_stream_new_sized() to specify the buffer's size + * at construction. + * + * To get the size of a buffer within a buffered input stream, use + * g_buffered_output_stream_get_buffer_size(). To change the size of a + * buffered output stream's buffer, use + * g_buffered_output_stream_set_buffer_size(). Note that the buffer's + * size cannot be reduced below the size of the data within the buffer. + **/ + +#define DEFAULT_BUFFER_SIZE 4096 + +struct _GBufferedOutputStreamPrivate { + guint8 *buffer; + gsize len; + goffset pos; + gboolean auto_grow; +}; + +enum { + PROP_0, + PROP_BUFSIZE, + PROP_AUTO_GROW +}; + +static void g_buffered_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static void g_buffered_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void g_buffered_output_stream_finalize (GObject *object); + + +static gssize g_buffered_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_buffered_output_stream_flush (GOutputStream *stream, + GCancellable *cancellable, + GError **error); +static gboolean g_buffered_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error); + +static void g_buffered_output_stream_flush_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_buffered_output_stream_flush_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); +static void g_buffered_output_stream_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_buffered_output_stream_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); + +static void g_buffered_output_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_buffered_output_stream_tell (GSeekable *seekable); +static gboolean g_buffered_output_stream_can_seek (GSeekable *seekable); +static gboolean g_buffered_output_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_buffered_output_stream_can_truncate (GSeekable *seekable); +static gboolean g_buffered_output_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); + +G_DEFINE_TYPE_WITH_CODE (GBufferedOutputStream, + g_buffered_output_stream, + G_TYPE_FILTER_OUTPUT_STREAM, + G_ADD_PRIVATE (GBufferedOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_buffered_output_stream_seekable_iface_init)) + + +static void +g_buffered_output_stream_class_init (GBufferedOutputStreamClass *klass) +{ + GObjectClass *object_class; + GOutputStreamClass *ostream_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = g_buffered_output_stream_get_property; + object_class->set_property = g_buffered_output_stream_set_property; + object_class->finalize = g_buffered_output_stream_finalize; + + ostream_class = G_OUTPUT_STREAM_CLASS (klass); + ostream_class->write_fn = g_buffered_output_stream_write; + ostream_class->flush = g_buffered_output_stream_flush; + ostream_class->close_fn = g_buffered_output_stream_close; + ostream_class->flush_async = g_buffered_output_stream_flush_async; + ostream_class->flush_finish = g_buffered_output_stream_flush_finish; + ostream_class->close_async = g_buffered_output_stream_close_async; + ostream_class->close_finish = g_buffered_output_stream_close_finish; + + g_object_class_install_property (object_class, + PROP_BUFSIZE, + g_param_spec_uint ("buffer-size", + P_("Buffer Size"), + P_("The size of the backend buffer"), + 1, + G_MAXUINT, + DEFAULT_BUFFER_SIZE, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (object_class, + PROP_AUTO_GROW, + g_param_spec_boolean ("auto-grow", + P_("Auto-grow"), + P_("Whether the buffer should automatically grow"), + FALSE, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + +} + +/** + * g_buffered_output_stream_get_buffer_size: + * @stream: a #GBufferedOutputStream. + * + * Gets the size of the buffer in the @stream. + * + * Returns: the current size of the buffer. + **/ +gsize +g_buffered_output_stream_get_buffer_size (GBufferedOutputStream *stream) +{ + g_return_val_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream), -1); + + return stream->priv->len; +} + +/** + * g_buffered_output_stream_set_buffer_size: + * @stream: a #GBufferedOutputStream. + * @size: a #gsize. + * + * Sets the size of the internal buffer to @size. + **/ +void +g_buffered_output_stream_set_buffer_size (GBufferedOutputStream *stream, + gsize size) +{ + GBufferedOutputStreamPrivate *priv; + guint8 *buffer; + + g_return_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream)); + + priv = stream->priv; + + if (size == priv->len) + return; + + if (priv->buffer) + { + size = (priv->pos > 0) ? MAX (size, (gsize) priv->pos) : size; + + buffer = g_malloc (size); + memcpy (buffer, priv->buffer, priv->pos); + g_free (priv->buffer); + priv->buffer = buffer; + priv->len = size; + /* Keep old pos */ + } + else + { + priv->buffer = g_malloc (size); + priv->len = size; + priv->pos = 0; + } + + g_object_notify (G_OBJECT (stream), "buffer-size"); +} + +/** + * g_buffered_output_stream_get_auto_grow: + * @stream: a #GBufferedOutputStream. + * + * Checks if the buffer automatically grows as data is added. + * + * Returns: %TRUE if the @stream's buffer automatically grows, + * %FALSE otherwise. + **/ +gboolean +g_buffered_output_stream_get_auto_grow (GBufferedOutputStream *stream) +{ + g_return_val_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream), FALSE); + + return stream->priv->auto_grow; +} + +/** + * g_buffered_output_stream_set_auto_grow: + * @stream: a #GBufferedOutputStream. + * @auto_grow: a #gboolean. + * + * Sets whether or not the @stream's buffer should automatically grow. + * If @auto_grow is true, then each write will just make the buffer + * larger, and you must manually flush the buffer to actually write out + * the data to the underlying stream. + **/ +void +g_buffered_output_stream_set_auto_grow (GBufferedOutputStream *stream, + gboolean auto_grow) +{ + GBufferedOutputStreamPrivate *priv; + g_return_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream)); + priv = stream->priv; + auto_grow = auto_grow != FALSE; + if (priv->auto_grow != auto_grow) + { + priv->auto_grow = auto_grow; + g_object_notify (G_OBJECT (stream), "auto-grow"); + } +} + +static void +g_buffered_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GBufferedOutputStream *stream; + + stream = G_BUFFERED_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_BUFSIZE: + g_buffered_output_stream_set_buffer_size (stream, g_value_get_uint (value)); + break; + + case PROP_AUTO_GROW: + g_buffered_output_stream_set_auto_grow (stream, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_buffered_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GBufferedOutputStream *buffered_stream; + GBufferedOutputStreamPrivate *priv; + + buffered_stream = G_BUFFERED_OUTPUT_STREAM (object); + priv = buffered_stream->priv; + + switch (prop_id) + { + case PROP_BUFSIZE: + g_value_set_uint (value, priv->len); + break; + + case PROP_AUTO_GROW: + g_value_set_boolean (value, priv->auto_grow); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_buffered_output_stream_finalize (GObject *object) +{ + GBufferedOutputStream *stream; + GBufferedOutputStreamPrivate *priv; + + stream = G_BUFFERED_OUTPUT_STREAM (object); + priv = stream->priv; + + g_free (priv->buffer); + + G_OBJECT_CLASS (g_buffered_output_stream_parent_class)->finalize (object); +} + +static void +g_buffered_output_stream_init (GBufferedOutputStream *stream) +{ + stream->priv = g_buffered_output_stream_get_instance_private (stream); +} + +static void +g_buffered_output_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_buffered_output_stream_tell; + iface->can_seek = g_buffered_output_stream_can_seek; + iface->seek = g_buffered_output_stream_seek; + iface->can_truncate = g_buffered_output_stream_can_truncate; + iface->truncate_fn = g_buffered_output_stream_truncate; +} + +/** + * g_buffered_output_stream_new: + * @base_stream: a #GOutputStream. + * + * Creates a new buffered output stream for a base stream. + * + * Returns: a #GOutputStream for the given @base_stream. + **/ +GOutputStream * +g_buffered_output_stream_new (GOutputStream *base_stream) +{ + GOutputStream *stream; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL); + + stream = g_object_new (G_TYPE_BUFFERED_OUTPUT_STREAM, + "base-stream", base_stream, + NULL); + + return stream; +} + +/** + * g_buffered_output_stream_new_sized: + * @base_stream: a #GOutputStream. + * @size: a #gsize. + * + * Creates a new buffered output stream with a given buffer size. + * + * Returns: a #GOutputStream with an internal buffer set to @size. + **/ +GOutputStream * +g_buffered_output_stream_new_sized (GOutputStream *base_stream, + gsize size) +{ + GOutputStream *stream; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL); + + stream = g_object_new (G_TYPE_BUFFERED_OUTPUT_STREAM, + "base-stream", base_stream, + "buffer-size", size, + NULL); + + return stream; +} + +static gboolean +flush_buffer (GBufferedOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GBufferedOutputStreamPrivate *priv; + GOutputStream *base_stream; + gboolean res; + gsize bytes_written; + gsize count; + + priv = stream->priv; + bytes_written = 0; + base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), FALSE); + + res = g_output_stream_write_all (base_stream, + priv->buffer, + priv->pos, + &bytes_written, + cancellable, + error); + + count = priv->pos - bytes_written; + + if (count > 0) + memmove (priv->buffer, priv->buffer + bytes_written, count); + + priv->pos -= bytes_written; + + return res; +} + +static gssize +g_buffered_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GBufferedOutputStream *bstream; + GBufferedOutputStreamPrivate *priv; + gboolean res; + gsize n; + gsize new_size; + + bstream = G_BUFFERED_OUTPUT_STREAM (stream); + priv = bstream->priv; + + n = priv->len - priv->pos; + + if (priv->auto_grow && n < count) + { + new_size = MAX (priv->len * 2, priv->len + count); + g_buffered_output_stream_set_buffer_size (bstream, new_size); + } + else if (n == 0) + { + res = flush_buffer (bstream, cancellable, error); + + if (res == FALSE) + return -1; + } + + n = priv->len - priv->pos; + + count = MIN (count, n); + memcpy (priv->buffer + priv->pos, buffer, count); + priv->pos += count; + + return count; +} + +static gboolean +g_buffered_output_stream_flush (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GBufferedOutputStream *bstream; + GOutputStream *base_stream; + gboolean res; + + bstream = G_BUFFERED_OUTPUT_STREAM (stream); + base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream; + + res = flush_buffer (bstream, cancellable, error); + + if (res == FALSE) + return FALSE; + + res = g_output_stream_flush (base_stream, cancellable, error); + + return res; +} + +static gboolean +g_buffered_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GBufferedOutputStream *bstream; + GOutputStream *base_stream; + gboolean res; + + bstream = G_BUFFERED_OUTPUT_STREAM (stream); + base_stream = G_FILTER_OUTPUT_STREAM (bstream)->base_stream; + res = flush_buffer (bstream, cancellable, error); + + if (g_filter_output_stream_get_close_base_stream (G_FILTER_OUTPUT_STREAM (stream))) + { + /* report the first error but still close the stream */ + if (res) + res = g_output_stream_close (base_stream, cancellable, error); + else + g_output_stream_close (base_stream, cancellable, NULL); + } + + return res; +} + +static goffset +g_buffered_output_stream_tell (GSeekable *seekable) +{ + GBufferedOutputStream *bstream; + GBufferedOutputStreamPrivate *priv; + GOutputStream *base_stream; + GSeekable *base_stream_seekable; + goffset base_offset; + + bstream = G_BUFFERED_OUTPUT_STREAM (seekable); + priv = bstream->priv; + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + if (!G_IS_SEEKABLE (base_stream)) + return 0; + + base_stream_seekable = G_SEEKABLE (base_stream); + + base_offset = g_seekable_tell (base_stream_seekable); + return base_offset + priv->pos; +} + +static gboolean +g_buffered_output_stream_can_seek (GSeekable *seekable) +{ + GOutputStream *base_stream; + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream)); +} + +static gboolean +g_buffered_output_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GBufferedOutputStream *bstream; + GOutputStream *base_stream; + GSeekable *base_stream_seekable; + gboolean flushed; + + bstream = G_BUFFERED_OUTPUT_STREAM (seekable); + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + if (!G_IS_SEEKABLE (base_stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Seek not supported on base stream")); + return FALSE; + } + + base_stream_seekable = G_SEEKABLE (base_stream); + flushed = flush_buffer (bstream, cancellable, error); + if (!flushed) + return FALSE; + + return g_seekable_seek (base_stream_seekable, offset, type, cancellable, error); +} + +static gboolean +g_buffered_output_stream_can_truncate (GSeekable *seekable) +{ + GOutputStream *base_stream; + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + return G_IS_SEEKABLE (base_stream) && g_seekable_can_truncate (G_SEEKABLE (base_stream)); +} + +static gboolean +g_buffered_output_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error) +{ + GBufferedOutputStream *bstream; + GOutputStream *base_stream; + GSeekable *base_stream_seekable; + gboolean flushed; + + bstream = G_BUFFERED_OUTPUT_STREAM (seekable); + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + if (!G_IS_SEEKABLE (base_stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Truncate not supported on base stream")); + return FALSE; + } + + base_stream_seekable = G_SEEKABLE (base_stream); + + flushed = flush_buffer (bstream, cancellable, error); + if (!flushed) + return FALSE; + return g_seekable_truncate (base_stream_seekable, offset, cancellable, error); +} + +/* ************************** */ +/* Async stuff implementation */ +/* ************************** */ + +/* TODO: This should be using the base class async ops, not threads */ + +typedef struct { + + guint flush_stream : 1; + guint close_stream : 1; + +} FlushData; + +static void +free_flush_data (gpointer data) +{ + g_slice_free (FlushData, data); +} + +/* This function is used by all three (i.e. + * _write, _flush, _close) functions since + * all of them will need to flush the buffer + * and so closing and writing is just a special + * case of flushing + some addition stuff */ +static void +flush_buffer_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GBufferedOutputStream *stream; + GOutputStream *base_stream; + FlushData *fdata; + gboolean res; + GError *error = NULL; + + stream = G_BUFFERED_OUTPUT_STREAM (object); + fdata = task_data; + base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream; + + res = flush_buffer (stream, cancellable, &error); + + /* if flushing the buffer didn't work don't even bother + * to flush the stream but just report that error */ + if (res && fdata->flush_stream) + res = g_output_stream_flush (base_stream, cancellable, &error); + + if (fdata->close_stream) + { + + /* if flushing the buffer or the stream returned + * an error report that first error but still try + * close the stream */ + if (g_filter_output_stream_get_close_base_stream (G_FILTER_OUTPUT_STREAM (stream))) + { + if (res == FALSE) + g_output_stream_close (base_stream, cancellable, NULL); + else + res = g_output_stream_close (base_stream, cancellable, &error); + } + } + + if (res == FALSE) + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); +} + +static void +g_buffered_output_stream_flush_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data) +{ + GTask *task; + FlushData *fdata; + + fdata = g_slice_new0 (FlushData); + fdata->flush_stream = TRUE; + fdata->close_stream = FALSE; + + task = g_task_new (stream, cancellable, callback, data); + g_task_set_source_tag (task, g_buffered_output_stream_flush_async); + g_task_set_task_data (task, fdata, free_flush_data); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, flush_buffer_thread); + g_object_unref (task); +} + +static gboolean +g_buffered_output_stream_flush_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +g_buffered_output_stream_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data) +{ + GTask *task; + FlushData *fdata; + + fdata = g_slice_new0 (FlushData); + fdata->close_stream = TRUE; + + task = g_task_new (stream, cancellable, callback, data); + g_task_set_source_tag (task, g_buffered_output_stream_close_async); + g_task_set_task_data (task, fdata, free_flush_data); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, flush_buffer_thread); + g_object_unref (task); +} + +static gboolean +g_buffered_output_stream_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} diff --git a/gio/gbufferedoutputstream.h b/gio/gbufferedoutputstream.h new file mode 100644 index 0000000..f88f279 --- /dev/null +++ b/gio/gbufferedoutputstream.h @@ -0,0 +1,86 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#ifndef __G_BUFFERED_OUTPUT_STREAM_H__ +#define __G_BUFFERED_OUTPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_BUFFERED_OUTPUT_STREAM (g_buffered_output_stream_get_type ()) +#define G_BUFFERED_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStream)) +#define G_BUFFERED_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStreamClass)) +#define G_IS_BUFFERED_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_BUFFERED_OUTPUT_STREAM)) +#define G_IS_BUFFERED_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_BUFFERED_OUTPUT_STREAM)) +#define G_BUFFERED_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStreamClass)) + +/** + * GBufferedOutputStream: + * + * An implementation of #GFilterOutputStream with a sized buffer. + **/ +typedef struct _GBufferedOutputStreamClass GBufferedOutputStreamClass; +typedef struct _GBufferedOutputStreamPrivate GBufferedOutputStreamPrivate; + +struct _GBufferedOutputStream +{ + GFilterOutputStream parent_instance; + + /*< protected >*/ + GBufferedOutputStreamPrivate *priv; +}; + +struct _GBufferedOutputStreamClass +{ + GFilterOutputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_buffered_output_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GOutputStream* g_buffered_output_stream_new (GOutputStream *base_stream); +GLIB_AVAILABLE_IN_ALL +GOutputStream* g_buffered_output_stream_new_sized (GOutputStream *base_stream, + gsize size); +GLIB_AVAILABLE_IN_ALL +gsize g_buffered_output_stream_get_buffer_size (GBufferedOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +void g_buffered_output_stream_set_buffer_size (GBufferedOutputStream *stream, + gsize size); +GLIB_AVAILABLE_IN_ALL +gboolean g_buffered_output_stream_get_auto_grow (GBufferedOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +void g_buffered_output_stream_set_auto_grow (GBufferedOutputStream *stream, + gboolean auto_grow); + +G_END_DECLS + +#endif /* __G_BUFFERED_OUTPUT_STREAM_H__ */ diff --git a/gio/gbytesicon.c b/gio/gbytesicon.c new file mode 100644 index 0000000..4103b60 --- /dev/null +++ b/gio/gbytesicon.c @@ -0,0 +1,269 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gbytesicon.h" +#include "gbytes.h" +#include "gicon.h" +#include "glibintl.h" +#include "gloadableicon.h" +#include "gmemoryinputstream.h" +#include "gtask.h" +#include "gioerror.h" + + +/** + * SECTION:gbytesicon + * @short_description: An icon stored in memory as a GBytes + * @include: gio/gio.h + * @see_also: #GIcon, #GLoadableIcon, #GBytes + * + * #GBytesIcon specifies an image held in memory in a common format (usually + * png) to be used as icon. + * + * Since: 2.38 + **/ + +typedef GObjectClass GBytesIconClass; + +struct _GBytesIcon +{ + GObject parent_instance; + + GBytes *bytes; +}; + +enum +{ + PROP_0, + PROP_BYTES +}; + +static void g_bytes_icon_icon_iface_init (GIconIface *iface); +static void g_bytes_icon_loadable_icon_iface_init (GLoadableIconIface *iface); +G_DEFINE_TYPE_WITH_CODE (GBytesIcon, g_bytes_icon, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ICON, g_bytes_icon_icon_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON, g_bytes_icon_loadable_icon_iface_init)) + +static void +g_bytes_icon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GBytesIcon *icon = G_BYTES_ICON (object); + + switch (prop_id) + { + case PROP_BYTES: + g_value_set_boxed (value, icon->bytes); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_bytes_icon_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GBytesIcon *icon = G_BYTES_ICON (object); + + switch (prop_id) + { + case PROP_BYTES: + icon->bytes = g_value_dup_boxed (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_bytes_icon_finalize (GObject *object) +{ + GBytesIcon *icon; + + icon = G_BYTES_ICON (object); + + g_bytes_unref (icon->bytes); + + G_OBJECT_CLASS (g_bytes_icon_parent_class)->finalize (object); +} + +static void +g_bytes_icon_class_init (GBytesIconClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = g_bytes_icon_get_property; + gobject_class->set_property = g_bytes_icon_set_property; + gobject_class->finalize = g_bytes_icon_finalize; + + /** + * GBytesIcon:bytes: + * + * The bytes containing the icon. + */ + g_object_class_install_property (gobject_class, PROP_BYTES, + g_param_spec_boxed ("bytes", + P_("bytes"), + P_("The bytes containing the icon"), + G_TYPE_BYTES, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +g_bytes_icon_init (GBytesIcon *bytes) +{ +} + +/** + * g_bytes_icon_new: + * @bytes: a #GBytes. + * + * Creates a new icon for a bytes. + * + * This cannot fail, but loading and interpreting the bytes may fail later on + * (for example, if g_loadable_icon_load() is called) if the image is invalid. + * + * Returns: (transfer full) (type GBytesIcon): a #GIcon for the given + * @bytes. + * + * Since: 2.38 + **/ +GIcon * +g_bytes_icon_new (GBytes *bytes) +{ + g_return_val_if_fail (bytes != NULL, NULL); + + return g_object_new (G_TYPE_BYTES_ICON, "bytes", bytes, NULL); +} + +/** + * g_bytes_icon_get_bytes: + * @icon: a #GIcon. + * + * Gets the #GBytes associated with the given @icon. + * + * Returns: (transfer none): a #GBytes. + * + * Since: 2.38 + **/ +GBytes * +g_bytes_icon_get_bytes (GBytesIcon *icon) +{ + g_return_val_if_fail (G_IS_BYTES_ICON (icon), NULL); + + return icon->bytes; +} + +static guint +g_bytes_icon_hash (GIcon *icon) +{ + GBytesIcon *bytes_icon = G_BYTES_ICON (icon); + + return g_bytes_hash (bytes_icon->bytes); +} + +static gboolean +g_bytes_icon_equal (GIcon *icon1, + GIcon *icon2) +{ + GBytesIcon *bytes1 = G_BYTES_ICON (icon1); + GBytesIcon *bytes2 = G_BYTES_ICON (icon2); + + return g_bytes_equal (bytes1->bytes, bytes2->bytes); +} + +static GVariant * +g_bytes_icon_serialize (GIcon *icon) +{ + GBytesIcon *bytes_icon = G_BYTES_ICON (icon); + + return g_variant_new ("(sv)", "bytes", + g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes_icon->bytes, TRUE)); +} + +static void +g_bytes_icon_icon_iface_init (GIconIface *iface) +{ + iface->hash = g_bytes_icon_hash; + iface->equal = g_bytes_icon_equal; + iface->serialize = g_bytes_icon_serialize; +} + +static GInputStream * +g_bytes_icon_load (GLoadableIcon *icon, + int size, + char **type, + GCancellable *cancellable, + GError **error) +{ + GBytesIcon *bytes_icon = G_BYTES_ICON (icon); + + if (type) + *type = NULL; + + return g_memory_input_stream_new_from_bytes (bytes_icon->bytes); +} + +static void +g_bytes_icon_load_async (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GBytesIcon *bytes_icon = G_BYTES_ICON (icon); + GTask *task; + + task = g_task_new (icon, cancellable, callback, user_data); + g_task_set_source_tag (task, g_bytes_icon_load_async); + g_task_return_pointer (task, g_memory_input_stream_new_from_bytes (bytes_icon->bytes), g_object_unref); + g_object_unref (task); +} + +static GInputStream * +g_bytes_icon_load_finish (GLoadableIcon *icon, + GAsyncResult *res, + char **type, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, icon), NULL); + + if (type) + *type = NULL; + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +g_bytes_icon_loadable_icon_iface_init (GLoadableIconIface *iface) +{ + iface->load = g_bytes_icon_load; + iface->load_async = g_bytes_icon_load_async; + iface->load_finish = g_bytes_icon_load_finish; +} diff --git a/gio/gbytesicon.h b/gio/gbytesicon.h new file mode 100644 index 0000000..5661044 --- /dev/null +++ b/gio/gbytesicon.h @@ -0,0 +1,52 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_BYTES_ICON_H__ +#define __G_BYTES_ICON_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_BYTES_ICON (g_bytes_icon_get_type ()) +#define G_BYTES_ICON(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_BYTES_ICON, GBytesIcon)) +#define G_IS_BYTES_ICON(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_BYTES_ICON)) + +/** + * GBytesIcon: + * + * Gets an icon for a #GBytes. Implements #GLoadableIcon. + **/ +GLIB_AVAILABLE_IN_2_38 +GType g_bytes_icon_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_38 +GIcon * g_bytes_icon_new (GBytes *bytes); + +GLIB_AVAILABLE_IN_2_38 +GBytes * g_bytes_icon_get_bytes (GBytesIcon *icon); + +G_END_DECLS + +#endif /* __G_BYTES_ICON_H__ */ diff --git a/gio/gcancellable.c b/gio/gcancellable.c new file mode 100644 index 0000000..b96e948 --- /dev/null +++ b/gio/gcancellable.c @@ -0,0 +1,821 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "glib.h" +#include +#include "glib-private.h" +#include "gcancellable.h" +#include "glibintl.h" + + +/** + * SECTION:gcancellable + * @short_description: Thread-safe Operation Cancellation Stack + * @include: gio/gio.h + * + * GCancellable is a thread-safe operation cancellation stack used + * throughout GIO to allow for cancellation of synchronous and + * asynchronous operations. + */ + +enum { + CANCELLED, + LAST_SIGNAL +}; + +struct _GCancellablePrivate +{ + /* Atomic so that g_cancellable_is_cancelled does not require holding the mutex. */ + gboolean cancelled; + /* Access to fields below is protected by cancellable_mutex. */ + guint cancelled_running : 1; + guint cancelled_running_waiting : 1; + + guint fd_refcount; + GWakeup *wakeup; +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE_WITH_PRIVATE (GCancellable, g_cancellable, G_TYPE_OBJECT) + +static GPrivate current_cancellable; +static GMutex cancellable_mutex; +static GCond cancellable_cond; + +static void +g_cancellable_finalize (GObject *object) +{ + GCancellable *cancellable = G_CANCELLABLE (object); + + if (cancellable->priv->wakeup) + GLIB_PRIVATE_CALL (g_wakeup_free) (cancellable->priv->wakeup); + + G_OBJECT_CLASS (g_cancellable_parent_class)->finalize (object); +} + +static void +g_cancellable_class_init (GCancellableClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_cancellable_finalize; + + /** + * GCancellable::cancelled: + * @cancellable: a #GCancellable. + * + * Emitted when the operation has been cancelled. + * + * Can be used by implementations of cancellable operations. If the + * operation is cancelled from another thread, the signal will be + * emitted in the thread that cancelled the operation, not the + * thread that is running the operation. + * + * Note that disconnecting from this signal (or any signal) in a + * multi-threaded program is prone to race conditions. For instance + * it is possible that a signal handler may be invoked even after + * a call to g_signal_handler_disconnect() for that handler has + * already returned. + * + * There is also a problem when cancellation happens right before + * connecting to the signal. If this happens the signal will + * unexpectedly not be emitted, and checking before connecting to + * the signal leaves a race condition where this is still happening. + * + * In order to make it safe and easy to connect handlers there + * are two helper functions: g_cancellable_connect() and + * g_cancellable_disconnect() which protect against problems + * like this. + * + * An example of how to us this: + * |[ + * // Make sure we don't do unnecessary work if already cancelled + * if (g_cancellable_set_error_if_cancelled (cancellable, error)) + * return; + * + * // Set up all the data needed to be able to handle cancellation + * // of the operation + * my_data = my_data_new (...); + * + * id = 0; + * if (cancellable) + * id = g_cancellable_connect (cancellable, + * G_CALLBACK (cancelled_handler) + * data, NULL); + * + * // cancellable operation here... + * + * g_cancellable_disconnect (cancellable, id); + * + * // cancelled_handler is never called after this, it is now safe + * // to free the data + * my_data_free (my_data); + * ]| + * + * Note that the cancelled signal is emitted in the thread that + * the user cancelled from, which may be the main thread. So, the + * cancellable signal should not do something that can block. + */ + signals[CANCELLED] = + g_signal_new (I_("cancelled"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GCancellableClass, cancelled), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + +} + +static void +g_cancellable_init (GCancellable *cancellable) +{ + cancellable->priv = g_cancellable_get_instance_private (cancellable); +} + +/** + * g_cancellable_new: + * + * Creates a new #GCancellable object. + * + * Applications that want to start one or more operations + * that should be cancellable should create a #GCancellable + * and pass it to the operations. + * + * One #GCancellable can be used in multiple consecutive + * operations or in multiple concurrent operations. + * + * Returns: a #GCancellable. + **/ +GCancellable * +g_cancellable_new (void) +{ + return g_object_new (G_TYPE_CANCELLABLE, NULL); +} + +/** + * g_cancellable_push_current: + * @cancellable: a #GCancellable object + * + * Pushes @cancellable onto the cancellable stack. The current + * cancellable can then be received using g_cancellable_get_current(). + * + * This is useful when implementing cancellable operations in + * code that does not allow you to pass down the cancellable object. + * + * This is typically called automatically by e.g. #GFile operations, + * so you rarely have to call this yourself. + **/ +void +g_cancellable_push_current (GCancellable *cancellable) +{ + GSList *l; + + g_return_if_fail (cancellable != NULL); + + l = g_private_get (¤t_cancellable); + l = g_slist_prepend (l, cancellable); + g_private_set (¤t_cancellable, l); +} + +/** + * g_cancellable_pop_current: + * @cancellable: a #GCancellable object + * + * Pops @cancellable off the cancellable stack (verifying that @cancellable + * is on the top of the stack). + **/ +void +g_cancellable_pop_current (GCancellable *cancellable) +{ + GSList *l; + + l = g_private_get (¤t_cancellable); + + g_return_if_fail (l != NULL); + g_return_if_fail (l->data == cancellable); + + l = g_slist_delete_link (l, l); + g_private_set (¤t_cancellable, l); +} + +/** + * g_cancellable_get_current: + * + * Gets the top cancellable from the stack. + * + * Returns: (nullable) (transfer none): a #GCancellable from the top + * of the stack, or %NULL if the stack is empty. + **/ +GCancellable * +g_cancellable_get_current (void) +{ + GSList *l; + + l = g_private_get (¤t_cancellable); + if (l == NULL) + return NULL; + + return G_CANCELLABLE (l->data); +} + +/** + * g_cancellable_reset: + * @cancellable: a #GCancellable object. + * + * Resets @cancellable to its uncancelled state. + * + * If cancellable is currently in use by any cancellable operation + * then the behavior of this function is undefined. + * + * Note that it is generally not a good idea to reuse an existing + * cancellable for more operations after it has been cancelled once, + * as this function might tempt you to do. The recommended practice + * is to drop the reference to a cancellable after cancelling it, + * and let it die with the outstanding async operations. You should + * create a fresh cancellable for further async operations. + **/ +void +g_cancellable_reset (GCancellable *cancellable) +{ + GCancellablePrivate *priv; + + g_return_if_fail (G_IS_CANCELLABLE (cancellable)); + + g_mutex_lock (&cancellable_mutex); + + priv = cancellable->priv; + + while (priv->cancelled_running) + { + priv->cancelled_running_waiting = TRUE; + g_cond_wait (&cancellable_cond, &cancellable_mutex); + } + + if (g_atomic_int_get (&priv->cancelled)) + { + if (priv->wakeup) + GLIB_PRIVATE_CALL (g_wakeup_acknowledge) (priv->wakeup); + + g_atomic_int_set (&priv->cancelled, FALSE); + } + + g_mutex_unlock (&cancellable_mutex); +} + +/** + * g_cancellable_is_cancelled: + * @cancellable: (nullable): a #GCancellable or %NULL + * + * Checks if a cancellable job has been cancelled. + * + * Returns: %TRUE if @cancellable is cancelled, + * FALSE if called with %NULL or if item is not cancelled. + **/ +gboolean +g_cancellable_is_cancelled (GCancellable *cancellable) +{ + return cancellable != NULL && g_atomic_int_get (&cancellable->priv->cancelled); +} + +/** + * g_cancellable_set_error_if_cancelled: + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: #GError to append error state to + * + * If the @cancellable is cancelled, sets the error to notify + * that the operation was cancelled. + * + * Returns: %TRUE if @cancellable was cancelled, %FALSE if it was not + */ +gboolean +g_cancellable_set_error_if_cancelled (GCancellable *cancellable, + GError **error) +{ + if (g_cancellable_is_cancelled (cancellable)) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_CANCELLED, + _("Operation was cancelled")); + return TRUE; + } + + return FALSE; +} + +/** + * g_cancellable_get_fd: + * @cancellable: a #GCancellable. + * + * Gets the file descriptor for a cancellable job. This can be used to + * implement cancellable operations on Unix systems. The returned fd will + * turn readable when @cancellable is cancelled. + * + * You are not supposed to read from the fd yourself, just check for + * readable status. Reading to unset the readable status is done + * with g_cancellable_reset(). + * + * After a successful return from this function, you should use + * g_cancellable_release_fd() to free up resources allocated for + * the returned file descriptor. + * + * See also g_cancellable_make_pollfd(). + * + * Returns: A valid file descriptor. `-1` if the file descriptor + * is not supported, or on errors. + **/ +int +g_cancellable_get_fd (GCancellable *cancellable) +{ + GPollFD pollfd; +#ifndef G_OS_WIN32 + gboolean retval G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; +#endif + + if (cancellable == NULL) + return -1; + +#ifdef G_OS_WIN32 + pollfd.fd = -1; +#else + retval = g_cancellable_make_pollfd (cancellable, &pollfd); + g_assert (retval); +#endif + + return pollfd.fd; +} + +/** + * g_cancellable_make_pollfd: + * @cancellable: (nullable): a #GCancellable or %NULL + * @pollfd: a pointer to a #GPollFD + * + * Creates a #GPollFD corresponding to @cancellable; this can be passed + * to g_poll() and used to poll for cancellation. This is useful both + * for unix systems without a native poll and for portability to + * windows. + * + * When this function returns %TRUE, you should use + * g_cancellable_release_fd() to free up resources allocated for the + * @pollfd. After a %FALSE return, do not call g_cancellable_release_fd(). + * + * If this function returns %FALSE, either no @cancellable was given or + * resource limits prevent this function from allocating the necessary + * structures for polling. (On Linux, you will likely have reached + * the maximum number of file descriptors.) The suggested way to handle + * these cases is to ignore the @cancellable. + * + * You are not supposed to read from the fd yourself, just check for + * readable status. Reading to unset the readable status is done + * with g_cancellable_reset(). + * + * Returns: %TRUE if @pollfd was successfully initialized, %FALSE on + * failure to prepare the cancellable. + * + * Since: 2.22 + **/ +gboolean +g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd) +{ + g_return_val_if_fail (pollfd != NULL, FALSE); + if (cancellable == NULL) + return FALSE; + g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE); + + g_mutex_lock (&cancellable_mutex); + + cancellable->priv->fd_refcount++; + + if (cancellable->priv->wakeup == NULL) + { + cancellable->priv->wakeup = GLIB_PRIVATE_CALL (g_wakeup_new) (); + + if (g_atomic_int_get (&cancellable->priv->cancelled)) + GLIB_PRIVATE_CALL (g_wakeup_signal) (cancellable->priv->wakeup); + } + + GLIB_PRIVATE_CALL (g_wakeup_get_pollfd) (cancellable->priv->wakeup, pollfd); + + g_mutex_unlock (&cancellable_mutex); + + return TRUE; +} + +/** + * g_cancellable_release_fd: + * @cancellable: a #GCancellable + * + * Releases a resources previously allocated by g_cancellable_get_fd() + * or g_cancellable_make_pollfd(). + * + * For compatibility reasons with older releases, calling this function + * is not strictly required, the resources will be automatically freed + * when the @cancellable is finalized. However, the @cancellable will + * block scarce file descriptors until it is finalized if this function + * is not called. This can cause the application to run out of file + * descriptors when many #GCancellables are used at the same time. + * + * Since: 2.22 + **/ +void +g_cancellable_release_fd (GCancellable *cancellable) +{ + GCancellablePrivate *priv; + + if (cancellable == NULL) + return; + + g_return_if_fail (G_IS_CANCELLABLE (cancellable)); + + priv = cancellable->priv; + + g_mutex_lock (&cancellable_mutex); + g_assert (priv->fd_refcount > 0); + + priv->fd_refcount--; + if (priv->fd_refcount == 0) + { + GLIB_PRIVATE_CALL (g_wakeup_free) (priv->wakeup); + priv->wakeup = NULL; + } + + g_mutex_unlock (&cancellable_mutex); +} + +/** + * g_cancellable_cancel: + * @cancellable: (nullable): a #GCancellable object. + * + * Will set @cancellable to cancelled, and will emit the + * #GCancellable::cancelled signal. (However, see the warning about + * race conditions in the documentation for that signal if you are + * planning to connect to it.) + * + * This function is thread-safe. In other words, you can safely call + * it from a thread other than the one running the operation that was + * passed the @cancellable. + * + * If @cancellable is %NULL, this function returns immediately for convenience. + * + * The convention within GIO is that cancelling an asynchronous + * operation causes it to complete asynchronously. That is, if you + * cancel the operation from the same thread in which it is running, + * then the operation's #GAsyncReadyCallback will not be invoked until + * the application returns to the main loop. + **/ +void +g_cancellable_cancel (GCancellable *cancellable) +{ + GCancellablePrivate *priv; + + if (cancellable == NULL || g_cancellable_is_cancelled (cancellable)) + return; + + priv = cancellable->priv; + + g_mutex_lock (&cancellable_mutex); + + if (g_atomic_int_get (&priv->cancelled)) + { + g_mutex_unlock (&cancellable_mutex); + return; + } + + g_atomic_int_set (&priv->cancelled, TRUE); + priv->cancelled_running = TRUE; + + if (priv->wakeup) + GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup); + + g_mutex_unlock (&cancellable_mutex); + + g_object_ref (cancellable); + g_signal_emit (cancellable, signals[CANCELLED], 0); + + g_mutex_lock (&cancellable_mutex); + + priv->cancelled_running = FALSE; + if (priv->cancelled_running_waiting) + g_cond_broadcast (&cancellable_cond); + priv->cancelled_running_waiting = FALSE; + + g_mutex_unlock (&cancellable_mutex); + + g_object_unref (cancellable); +} + +/** + * g_cancellable_connect: + * @cancellable: A #GCancellable. + * @callback: The #GCallback to connect. + * @data: Data to pass to @callback. + * @data_destroy_func: (nullable): Free function for @data or %NULL. + * + * Convenience function to connect to the #GCancellable::cancelled + * signal. Also handles the race condition that may happen + * if the cancellable is cancelled right before connecting. + * + * @callback is called at most once, either directly at the + * time of the connect if @cancellable is already cancelled, + * or when @cancellable is cancelled in some thread. + * + * @data_destroy_func will be called when the handler is + * disconnected, or immediately if the cancellable is already + * cancelled. + * + * See #GCancellable::cancelled for details on how to use this. + * + * Since GLib 2.40, the lock protecting @cancellable is not held when + * @callback is invoked. This lifts a restriction in place for + * earlier GLib versions which now makes it easier to write cleanup + * code that unconditionally invokes e.g. g_cancellable_cancel(). + * + * Returns: The id of the signal handler or 0 if @cancellable has already + * been cancelled. + * + * Since: 2.22 + */ +gulong +g_cancellable_connect (GCancellable *cancellable, + GCallback callback, + gpointer data, + GDestroyNotify data_destroy_func) +{ + gulong id; + + g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), 0); + + g_mutex_lock (&cancellable_mutex); + + if (g_atomic_int_get (&cancellable->priv->cancelled)) + { + void (*_callback) (GCancellable *cancellable, + gpointer user_data); + + g_mutex_unlock (&cancellable_mutex); + + _callback = (void *)callback; + id = 0; + + _callback (cancellable, data); + + if (data_destroy_func) + data_destroy_func (data); + } + else + { + id = g_signal_connect_data (cancellable, "cancelled", + callback, data, + (GClosureNotify) data_destroy_func, + 0); + + g_mutex_unlock (&cancellable_mutex); + } + + + return id; +} + +/** + * g_cancellable_disconnect: + * @cancellable: (nullable): A #GCancellable or %NULL. + * @handler_id: Handler id of the handler to be disconnected, or `0`. + * + * Disconnects a handler from a cancellable instance similar to + * g_signal_handler_disconnect(). Additionally, in the event that a + * signal handler is currently running, this call will block until the + * handler has finished. Calling this function from a + * #GCancellable::cancelled signal handler will therefore result in a + * deadlock. + * + * This avoids a race condition where a thread cancels at the + * same time as the cancellable operation is finished and the + * signal handler is removed. See #GCancellable::cancelled for + * details on how to use this. + * + * If @cancellable is %NULL or @handler_id is `0` this function does + * nothing. + * + * Since: 2.22 + */ +void +g_cancellable_disconnect (GCancellable *cancellable, + gulong handler_id) +{ + GCancellablePrivate *priv; + + if (handler_id == 0 || cancellable == NULL) + return; + + g_mutex_lock (&cancellable_mutex); + + priv = cancellable->priv; + + while (priv->cancelled_running) + { + priv->cancelled_running_waiting = TRUE; + g_cond_wait (&cancellable_cond, &cancellable_mutex); + } + + g_signal_handler_disconnect (cancellable, handler_id); + + g_mutex_unlock (&cancellable_mutex); +} + +typedef struct { + GSource source; + + GCancellable *cancellable; + gulong cancelled_handler; + /* Protected by cancellable_mutex: */ + gboolean resurrected_during_cancellation; +} GCancellableSource; + +/* + * The reference count of the GSource might be 0 at this point but it is not + * finalized yet and its dispose function did not run yet, or otherwise we + * would have disconnected the signal handler already and due to the signal + * emission lock it would be impossible to call the signal handler at that + * point. That is: at this point we either have a fully valid GSource, or + * it's not disposed or finalized yet and we can still resurrect it as needed. + * + * As such we first ensure that we have a strong reference to the GSource in + * here before calling any other GSource API. + */ +static void +cancellable_source_cancelled (GCancellable *cancellable, + gpointer user_data) +{ + GSource *source = user_data; + GCancellableSource *cancellable_source = (GCancellableSource *) source; + + g_mutex_lock (&cancellable_mutex); + + /* Drop the reference added in cancellable_source_dispose(); see the comment there. + * The reference must be dropped after unlocking @cancellable_mutex since + * it could be the final reference, and the dispose function takes + * @cancellable_mutex. */ + if (cancellable_source->resurrected_during_cancellation) + { + cancellable_source->resurrected_during_cancellation = FALSE; + g_mutex_unlock (&cancellable_mutex); + g_source_unref (source); + return; + } + + g_source_ref (source); + g_mutex_unlock (&cancellable_mutex); + g_source_set_ready_time (source, 0); + g_source_unref (source); +} + +static gboolean +cancellable_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GCancellableSourceFunc func = (GCancellableSourceFunc)callback; + GCancellableSource *cancellable_source = (GCancellableSource *)source; + + g_source_set_ready_time (source, -1); + return (*func) (cancellable_source->cancellable, user_data); +} + +static void +cancellable_source_dispose (GSource *source) +{ + GCancellableSource *cancellable_source = (GCancellableSource *)source; + + g_mutex_lock (&cancellable_mutex); + + if (cancellable_source->cancellable) + { + if (cancellable_source->cancellable->priv->cancelled_running) + { + /* There can be a race here: if thread A has called + * g_cancellable_cancel() and has got as far as committing to call + * cancellable_source_cancelled(), then thread B drops the final + * ref on the GCancellableSource before g_source_ref() is called in + * cancellable_source_cancelled(), then cancellable_source_dispose() + * will run through and the GCancellableSource will be finalised + * before cancellable_source_cancelled() gets to g_source_ref(). It + * will then be left in a state where it’s committed to using a + * dangling GCancellableSource pointer. + * + * Eliminate that race by resurrecting the #GSource temporarily, and + * then dropping that reference in cancellable_source_cancelled(), + * which should be guaranteed to fire because we’re inside a + * @cancelled_running block. + */ + g_source_ref (source); + cancellable_source->resurrected_during_cancellation = TRUE; + } + + g_clear_signal_handler (&cancellable_source->cancelled_handler, + cancellable_source->cancellable); + g_clear_object (&cancellable_source->cancellable); + } + + g_mutex_unlock (&cancellable_mutex); +} + +static gboolean +cancellable_source_closure_callback (GCancellable *cancellable, + gpointer data) +{ + GClosure *closure = data; + + GValue params = G_VALUE_INIT; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_value_init (¶ms, G_TYPE_CANCELLABLE); + g_value_set_object (¶ms, cancellable); + + g_closure_invoke (closure, &result_value, 1, ¶ms, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + g_value_unset (¶ms); + + return result; +} + +static GSourceFuncs cancellable_source_funcs = +{ + NULL, + NULL, + cancellable_source_dispatch, + NULL, + (GSourceFunc)cancellable_source_closure_callback, + NULL, +}; + +/** + * g_cancellable_source_new: + * @cancellable: (nullable): a #GCancellable, or %NULL + * + * Creates a source that triggers if @cancellable is cancelled and + * calls its callback of type #GCancellableSourceFunc. This is + * primarily useful for attaching to another (non-cancellable) source + * with g_source_add_child_source() to add cancellability to it. + * + * For convenience, you can call this with a %NULL #GCancellable, + * in which case the source will never trigger. + * + * The new #GSource will hold a reference to the #GCancellable. + * + * Returns: (transfer full): the new #GSource. + * + * Since: 2.28 + */ +GSource * +g_cancellable_source_new (GCancellable *cancellable) +{ + GSource *source; + GCancellableSource *cancellable_source; + + source = g_source_new (&cancellable_source_funcs, sizeof (GCancellableSource)); + g_source_set_static_name (source, "GCancellable"); + g_source_set_dispose_function (source, cancellable_source_dispose); + cancellable_source = (GCancellableSource *)source; + + if (cancellable) + { + cancellable_source->cancellable = g_object_ref (cancellable); + + /* We intentionally don't use g_cancellable_connect() here, + * because we don't want the "at most once" behavior. + */ + cancellable_source->cancelled_handler = + g_signal_connect (cancellable, "cancelled", + G_CALLBACK (cancellable_source_cancelled), + source); + if (g_cancellable_is_cancelled (cancellable)) + g_source_set_ready_time (source, 0); + } + + return source; +} diff --git a/gio/gcancellable.h b/gio/gcancellable.h new file mode 100644 index 0000000..45b9a5a --- /dev/null +++ b/gio/gcancellable.h @@ -0,0 +1,118 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_CANCELLABLE_H__ +#define __G_CANCELLABLE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_CANCELLABLE (g_cancellable_get_type ()) +#define G_CANCELLABLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CANCELLABLE, GCancellable)) +#define G_CANCELLABLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CANCELLABLE, GCancellableClass)) +#define G_IS_CANCELLABLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CANCELLABLE)) +#define G_IS_CANCELLABLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CANCELLABLE)) +#define G_CANCELLABLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CANCELLABLE, GCancellableClass)) + +/** + * GCancellable: + * + * Allows actions to be cancelled. + */ +typedef struct _GCancellableClass GCancellableClass; +typedef struct _GCancellablePrivate GCancellablePrivate; + +struct _GCancellable +{ + GObject parent_instance; + + /*< private >*/ + GCancellablePrivate *priv; +}; + +struct _GCancellableClass +{ + GObjectClass parent_class; + + void (* cancelled) (GCancellable *cancellable); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_cancellable_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GCancellable *g_cancellable_new (void); + +/* These are only safe to call inside a cancellable op */ +GLIB_AVAILABLE_IN_ALL +gboolean g_cancellable_is_cancelled (GCancellable *cancellable); +GLIB_AVAILABLE_IN_ALL +gboolean g_cancellable_set_error_if_cancelled (GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +int g_cancellable_get_fd (GCancellable *cancellable); +GLIB_AVAILABLE_IN_ALL +gboolean g_cancellable_make_pollfd (GCancellable *cancellable, + GPollFD *pollfd); +GLIB_AVAILABLE_IN_ALL +void g_cancellable_release_fd (GCancellable *cancellable); + +GLIB_AVAILABLE_IN_ALL +GSource * g_cancellable_source_new (GCancellable *cancellable); + +GLIB_AVAILABLE_IN_ALL +GCancellable *g_cancellable_get_current (void); +GLIB_AVAILABLE_IN_ALL +void g_cancellable_push_current (GCancellable *cancellable); +GLIB_AVAILABLE_IN_ALL +void g_cancellable_pop_current (GCancellable *cancellable); +GLIB_AVAILABLE_IN_ALL +void g_cancellable_reset (GCancellable *cancellable); +GLIB_AVAILABLE_IN_ALL +gulong g_cancellable_connect (GCancellable *cancellable, + GCallback callback, + gpointer data, + GDestroyNotify data_destroy_func); +GLIB_AVAILABLE_IN_ALL +void g_cancellable_disconnect (GCancellable *cancellable, + gulong handler_id); + + +/* This is safe to call from another thread */ +GLIB_AVAILABLE_IN_ALL +void g_cancellable_cancel (GCancellable *cancellable); + +G_END_DECLS + +#endif /* __G_CANCELLABLE_H__ */ diff --git a/gio/gcharsetconverter.c b/gio/gcharsetconverter.c new file mode 100644 index 0000000..d529cbc --- /dev/null +++ b/gio/gcharsetconverter.c @@ -0,0 +1,472 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gcharsetconverter.h" + +#include + +#include "ginitable.h" +#include "gioerror.h" +#include "glibintl.h" + + +enum { + PROP_0, + PROP_FROM_CHARSET, + PROP_TO_CHARSET, + PROP_USE_FALLBACK +}; + +/** + * SECTION:gcharsetconverter + * @short_description: Convert between charsets + * @include: gio/gio.h + * + * #GCharsetConverter is an implementation of #GConverter based on + * GIConv. + */ + +static void g_charset_converter_iface_init (GConverterIface *iface); +static void g_charset_converter_initable_iface_init (GInitableIface *iface); + +/** + * GCharsetConverter: + * + * Conversions between character sets. + */ +struct _GCharsetConverter +{ + GObject parent_instance; + + char *from; + char *to; + GIConv iconv; + gboolean use_fallback; + guint n_fallback_errors; +}; + +G_DEFINE_TYPE_WITH_CODE (GCharsetConverter, g_charset_converter, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, + g_charset_converter_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_charset_converter_initable_iface_init)) + +static void +g_charset_converter_finalize (GObject *object) +{ + GCharsetConverter *conv; + + conv = G_CHARSET_CONVERTER (object); + + g_free (conv->from); + g_free (conv->to); + if (conv->iconv) + g_iconv_close (conv->iconv); + + G_OBJECT_CLASS (g_charset_converter_parent_class)->finalize (object); +} + +static void +g_charset_converter_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GCharsetConverter *conv; + + conv = G_CHARSET_CONVERTER (object); + + switch (prop_id) + { + case PROP_TO_CHARSET: + g_free (conv->to); + conv->to = g_value_dup_string (value); + break; + + case PROP_FROM_CHARSET: + g_free (conv->from); + conv->from = g_value_dup_string (value); + break; + + case PROP_USE_FALLBACK: + conv->use_fallback = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_charset_converter_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GCharsetConverter *conv; + + conv = G_CHARSET_CONVERTER (object); + + switch (prop_id) + { + case PROP_TO_CHARSET: + g_value_set_string (value, conv->to); + break; + + case PROP_FROM_CHARSET: + g_value_set_string (value, conv->from); + break; + + case PROP_USE_FALLBACK: + g_value_set_boolean (value, conv->use_fallback); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_charset_converter_class_init (GCharsetConverterClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_charset_converter_finalize; + gobject_class->get_property = g_charset_converter_get_property; + gobject_class->set_property = g_charset_converter_set_property; + + g_object_class_install_property (gobject_class, + PROP_TO_CHARSET, + g_param_spec_string ("to-charset", + P_("To Charset"), + P_("The character encoding to convert to"), + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_FROM_CHARSET, + g_param_spec_string ("from-charset", + P_("From Charset"), + P_("The character encoding to convert from"), + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_USE_FALLBACK, + g_param_spec_boolean ("use-fallback", + P_("Fallback enabled"), + P_("Use fallback (of form \\) for invalid bytes"), + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_charset_converter_init (GCharsetConverter *local) +{ +} + + +/** + * g_charset_converter_new: + * @to_charset: destination charset + * @from_charset: source charset + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a new #GCharsetConverter. + * + * Returns: a new #GCharsetConverter or %NULL on error. + * + * Since: 2.24 + **/ +GCharsetConverter * +g_charset_converter_new (const gchar *to_charset, + const gchar *from_charset, + GError **error) +{ + GCharsetConverter *conv; + + conv = g_initable_new (G_TYPE_CHARSET_CONVERTER, + NULL, error, + "to-charset", to_charset, + "from-charset", from_charset, + NULL); + + return conv; +} + +static void +g_charset_converter_reset (GConverter *converter) +{ + GCharsetConverter *conv = G_CHARSET_CONVERTER (converter); + + if (conv->iconv == NULL) + { + g_warning ("Invalid object, not initialized"); + return; + } + + g_iconv (conv->iconv, NULL, NULL, NULL, NULL); + conv->n_fallback_errors = 0; +} + +static GConverterResult +g_charset_converter_convert (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + GCharsetConverter *conv; + gsize res; + GConverterResult ret; + gchar *inbufp, *outbufp; + gsize in_left, out_left; + int errsv; + gboolean reset; + + conv = G_CHARSET_CONVERTER (converter); + + if (conv->iconv == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, + _("Invalid object, not initialized")); + return G_CONVERTER_ERROR; + } + + inbufp = (char *)inbuf; + outbufp = (char *)outbuf; + in_left = inbuf_size; + out_left = outbuf_size; + reset = FALSE; + + /* if there is not input try to flush the data */ + if (inbuf_size == 0) + { + if (flags & G_CONVERTER_INPUT_AT_END || + flags & G_CONVERTER_FLUSH) + { + reset = TRUE; + } + else + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, + _("Incomplete multibyte sequence in input")); + return G_CONVERTER_ERROR; + } + } + + if (reset) + /* call g_iconv with NULL inbuf to cleanup shift state */ + res = g_iconv (conv->iconv, + NULL, &in_left, + &outbufp, &out_left); + else + res = g_iconv (conv->iconv, + &inbufp, &in_left, + &outbufp, &out_left); + + *bytes_read = inbufp - (char *)inbuf; + *bytes_written = outbufp - (char *)outbuf; + + /* Don't report error if we converted anything */ + if (res == (gsize) -1 && *bytes_read == 0) + { + errsv = errno; + + switch (errsv) + { + case EINVAL: + /* Incomplete input text */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, + _("Incomplete multibyte sequence in input")); + break; + + case E2BIG: + /* Not enough destination space */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, + _("Not enough space in destination")); + break; + + case EILSEQ: + /* Invalid code sequence */ + if (conv->use_fallback) + { + if (outbuf_size < 3) + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, + _("Not enough space in destination")); + else + { + const char hex[] = "0123456789ABCDEF"; + guint8 v = *(guint8 *)inbuf; + guint8 *out = (guint8 *)outbuf; + out[0] = '\\'; + out[1] = hex[(v & 0xf0) >> 4]; + out[2] = hex[(v & 0x0f) >> 0]; + *bytes_read = 1; + *bytes_written = 3; + in_left--; + conv->n_fallback_errors++; + goto ok; + } + } + else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + _("Invalid byte sequence in conversion input")); + break; + + default: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Error during conversion: %s"), + g_strerror (errsv)); + break; + } + ret = G_CONVERTER_ERROR; + } + else + { + ok: + ret = G_CONVERTER_CONVERTED; + + if (reset && + (flags & G_CONVERTER_INPUT_AT_END)) + ret = G_CONVERTER_FINISHED; + else if (reset && + (flags & G_CONVERTER_FLUSH)) + ret = G_CONVERTER_FLUSHED; + } + + return ret; +} + +/** + * g_charset_converter_set_use_fallback: + * @converter: a #GCharsetConverter + * @use_fallback: %TRUE to use fallbacks + * + * Sets the #GCharsetConverter:use-fallback property. + * + * Since: 2.24 + */ +void +g_charset_converter_set_use_fallback (GCharsetConverter *converter, + gboolean use_fallback) +{ + use_fallback = !!use_fallback; + + if (converter->use_fallback != use_fallback) + { + converter->use_fallback = use_fallback; + g_object_notify (G_OBJECT (converter), "use-fallback"); + } +} + +/** + * g_charset_converter_get_use_fallback: + * @converter: a #GCharsetConverter + * + * Gets the #GCharsetConverter:use-fallback property. + * + * Returns: %TRUE if fallbacks are used by @converter + * + * Since: 2.24 + */ +gboolean +g_charset_converter_get_use_fallback (GCharsetConverter *converter) +{ + return converter->use_fallback; +} + +/** + * g_charset_converter_get_num_fallbacks: + * @converter: a #GCharsetConverter + * + * Gets the number of fallbacks that @converter has applied so far. + * + * Returns: the number of fallbacks that @converter has applied + * + * Since: 2.24 + */ +guint +g_charset_converter_get_num_fallbacks (GCharsetConverter *converter) +{ + return converter->n_fallback_errors; +} + +static void +g_charset_converter_iface_init (GConverterIface *iface) +{ + iface->convert = g_charset_converter_convert; + iface->reset = g_charset_converter_reset; +} + +static gboolean +g_charset_converter_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GCharsetConverter *conv; + int errsv; + + g_return_val_if_fail (G_IS_CHARSET_CONVERTER (initable), FALSE); + + conv = G_CHARSET_CONVERTER (initable); + + if (cancellable != NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Cancellable initialization not supported")); + return FALSE; + } + + conv->iconv = g_iconv_open (conv->to, conv->from); + errsv = errno; + + if (conv->iconv == (GIConv)-1) + { + if (errsv == EINVAL) + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Conversion from character set “%s†to “%s†is not supported"), + conv->from, conv->to); + else + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Could not open converter from “%s†to “%sâ€"), + conv->from, conv->to); + return FALSE; + } + + return TRUE; +} + +static void +g_charset_converter_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_charset_converter_initable_init; +} diff --git a/gio/gcharsetconverter.h b/gio/gcharsetconverter.h new file mode 100644 index 0000000..610f774 --- /dev/null +++ b/gio/gcharsetconverter.h @@ -0,0 +1,63 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_CHARSET_CONVERTER_H__ +#define __G_CHARSET_CONVERTER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_CHARSET_CONVERTER (g_charset_converter_get_type ()) +#define G_CHARSET_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CHARSET_CONVERTER, GCharsetConverter)) +#define G_CHARSET_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CHARSET_CONVERTER, GCharsetConverterClass)) +#define G_IS_CHARSET_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CHARSET_CONVERTER)) +#define G_IS_CHARSET_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CHARSET_CONVERTER)) +#define G_CHARSET_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CHARSET_CONVERTER, GCharsetConverterClass)) + +typedef struct _GCharsetConverterClass GCharsetConverterClass; + +struct _GCharsetConverterClass +{ + GObjectClass parent_class; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_charset_converter_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GCharsetConverter *g_charset_converter_new (const gchar *to_charset, + const gchar *from_charset, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_charset_converter_set_use_fallback (GCharsetConverter *converter, + gboolean use_fallback); +GLIB_AVAILABLE_IN_ALL +gboolean g_charset_converter_get_use_fallback (GCharsetConverter *converter); +GLIB_AVAILABLE_IN_ALL +guint g_charset_converter_get_num_fallbacks (GCharsetConverter *converter); + +G_END_DECLS + +#endif /* __G_CHARSET_CONVERTER_H__ */ diff --git a/gio/gcocoanotificationbackend.m b/gio/gcocoanotificationbackend.m new file mode 100644 index 0000000..42cf8ab --- /dev/null +++ b/gio/gcocoanotificationbackend.m @@ -0,0 +1,277 @@ +/* + * Copyright © 2015 Patrick Griffis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Patrick Griffis + */ + +#include "config.h" + +#import +#include "gnotificationbackend.h" +#include "gapplication.h" +#include "gaction.h" +#include "gactiongroup.h" +#include "giomodule-priv.h" +#include "gnotification-private.h" +#include "gthemedicon.h" +#include "gfileicon.h" +#include "gfile.h" + +#define G_TYPE_COCOA_NOTIFICATION_BACKEND (g_cocoa_notification_backend_get_type ()) +#define G_COCOA_NOTIFICATION_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_COCOA_NOTIFICATION_BACKEND, GCocoaNotificationBackend)) + +typedef struct _GCocoaNotificationBackend GCocoaNotificationBackend; +typedef GNotificationBackendClass GCocoaNotificationBackendClass; +struct _GCocoaNotificationBackend +{ + GNotificationBackend parent; +}; + +GType g_cocoa_notification_backend_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (GCocoaNotificationBackend, g_cocoa_notification_backend, G_TYPE_NOTIFICATION_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, g_define_type_id, "cocoa", 200)); + +static NSString * +nsstring_from_cstr (const char *cstr) +{ + if (!cstr) + return nil; + + return [[NSString alloc] initWithUTF8String:cstr]; +} + +static NSImage* +nsimage_from_gicon (GIcon *icon) +{ + if (G_IS_FILE_ICON (icon)) + { + NSImage *image = nil; + GFile *file; + char *path; + + file = g_file_icon_get_file (G_FILE_ICON (icon)); + path = g_file_get_path (file); + if (path) + { + NSString *str_path = nsstring_from_cstr (path); + image = [[NSImage alloc] initByReferencingFile:str_path]; + + [str_path release]; + g_free (path); + } + return image; + } + else + { + g_warning ("This icon type is not handled by this NotificationBackend"); + return nil; + } +} + +static void +activate_detailed_action (const char * action) +{ + char *name; + GVariant *target; + + if (!g_str_has_prefix (action, "app.")) + { + g_warning ("Notification action does not have \"app.\" prefix"); + return; + } + + if (g_action_parse_detailed_name (action, &name, &target, NULL)) + { + g_action_group_activate_action (G_ACTION_GROUP (g_application_get_default()), name + 4, target); + g_free (name); + if (target) + g_variant_unref (target); + } +} + +@interface GNotificationCenterDelegate : NSObject @end +@implementation GNotificationCenterDelegate + +-(void) userNotificationCenter:(NSUserNotificationCenter*) center + didActivateNotification:(NSUserNotification*) notification +{ + if ([notification activationType] == NSUserNotificationActivationTypeContentsClicked) + { + const char *action = [[notification userInfo][@"default"] UTF8String]; + if (action) + activate_detailed_action (action); + /* OSX Always activates the front window */ + } + else if ([notification activationType] == NSUserNotificationActivationTypeActionButtonClicked) + { + const char *action = [[notification userInfo][@"button0"] UTF8String]; + if (action) + activate_detailed_action (action); + } + + [center removeDeliveredNotification:notification]; +} + +@end + +static GNotificationCenterDelegate *cocoa_notification_delegate; + +static gboolean +g_cocoa_notification_backend_is_supported (void) +{ + NSBundle *bundle = [NSBundle mainBundle]; + + /* This is always actually supported, but without a bundle it does nothing */ + if (![bundle bundleIdentifier]) + return FALSE; + + return TRUE; +} + +static void +add_actions_to_notification (NSUserNotification *userNotification, + GNotification *notification) +{ + guint n_buttons = g_notification_get_n_buttons (notification); + char *action = NULL, *label = NULL; + GVariant *target = NULL; + NSMutableDictionary *user_info = nil; + + if (g_notification_get_default_action (notification, &action, &target)) + { + char *detailed_name = g_action_print_detailed_name (action, target); + NSString *action_name = nsstring_from_cstr (detailed_name); + user_info = [[NSMutableDictionary alloc] init]; + + user_info[@"default"] = action_name; + + [action_name release]; + g_free (detailed_name); + g_clear_pointer (&action, g_free); + g_clear_pointer (&target, g_variant_unref); + } + + if (n_buttons) + { + g_notification_get_button (notification, 0, &label, &action, &target); + if (label) + { + NSString *str_label = nsstring_from_cstr (label); + char *detailed_name = g_action_print_detailed_name (action, target); + NSString *action_name = nsstring_from_cstr (detailed_name); + + if (!user_info) + user_info = [[NSMutableDictionary alloc] init]; + + user_info[@"button0"] = action_name; + userNotification.actionButtonTitle = str_label; + + [str_label release]; + [action_name release]; + g_free (label); + g_free (action); + g_free (detailed_name); + g_clear_pointer (&target, g_variant_unref); + } + + if (n_buttons > 1) + g_warning ("Only a single button is currently supported by this NotificationBackend"); + } + + userNotification.userInfo = user_info; + [user_info release]; +} + +static void +g_cocoa_notification_backend_send_notification (GNotificationBackend *backend, + const gchar *cstr_id, + GNotification *notification) +{ + NSString *str_title = nil, *str_text = nil, *str_id = nil; + NSImage *content = nil; + const char *cstr; + GIcon *icon; + NSUserNotification *userNotification; + NSUserNotificationCenter *center; + + if ((cstr = g_notification_get_title (notification))) + str_title = nsstring_from_cstr (cstr); + if ((cstr = g_notification_get_body (notification))) + str_text = nsstring_from_cstr (cstr); + if (cstr_id != NULL) + str_id = nsstring_from_cstr (cstr_id); + if ((icon = g_notification_get_icon (notification))) + content = nsimage_from_gicon (icon); + /* NOTE: There is no priority */ + + userNotification = [NSUserNotification new]; + userNotification.title = str_title; + userNotification.informativeText = str_text; + userNotification.identifier = str_id; + userNotification.contentImage = content; + /* NOTE: Buttons only show up if your bundle has NSUserNotificationAlertStyle set to "alerts" */ + add_actions_to_notification (userNotification, notification); + + if (!cocoa_notification_delegate) + cocoa_notification_delegate = [[GNotificationCenterDelegate alloc] init]; + + center = [NSUserNotificationCenter defaultUserNotificationCenter]; + center.delegate = cocoa_notification_delegate; + [center deliverNotification:userNotification]; + + [str_title release]; + [str_text release]; + [str_id release]; + [content release]; + [userNotification release]; +} + +static void +g_cocoa_notification_backend_withdraw_notification (GNotificationBackend *backend, + const gchar *cstr_id) +{ + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + NSArray *notifications = [center deliveredNotifications]; + NSString *str_id = nsstring_from_cstr (cstr_id); + + for (NSUserNotification *notification in notifications) + { + if ([notification.identifier compare:str_id] == NSOrderedSame) + { + [center removeDeliveredNotification:notification]; + break; + } + } + + [str_id release]; +} + +static void +g_cocoa_notification_backend_init (GCocoaNotificationBackend *backend) +{ +} + +static void +g_cocoa_notification_backend_class_init (GCocoaNotificationBackendClass *klass) +{ + GNotificationBackendClass *backend_class = G_NOTIFICATION_BACKEND_CLASS (klass); + + backend_class->is_supported = g_cocoa_notification_backend_is_supported; + backend_class->send_notification = g_cocoa_notification_backend_send_notification; + backend_class->withdraw_notification = g_cocoa_notification_backend_withdraw_notification; +} diff --git a/gio/gcontenttype-win32.c b/gio/gcontenttype-win32.c new file mode 100644 index 0000000..9b6f69e --- /dev/null +++ b/gio/gcontenttype-win32.c @@ -0,0 +1,442 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include +#include +#include +#include +#include "gcontenttype.h" +#include "gthemedicon.h" +#include "gicon.h" +#include "glibintl.h" + +#include + +static char * +get_registry_classes_key (const char *subdir, + const wchar_t *key_name) +{ + wchar_t *wc_key; + HKEY reg_key = NULL; + DWORD key_type; + DWORD nbytes; + char *value_utf8; + + value_utf8 = NULL; + + nbytes = 0; + wc_key = g_utf8_to_utf16 (subdir, -1, NULL, NULL, NULL); + if (RegOpenKeyExW (HKEY_CLASSES_ROOT, wc_key, 0, + KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS && + RegQueryValueExW (reg_key, key_name, 0, + &key_type, NULL, &nbytes) == ERROR_SUCCESS && + (key_type == REG_SZ || key_type == REG_EXPAND_SZ)) + { + wchar_t *wc_temp = g_new (wchar_t, (nbytes+1)/2 + 1); + RegQueryValueExW (reg_key, key_name, 0, + &key_type, (LPBYTE) wc_temp, &nbytes); + wc_temp[nbytes/2] = '\0'; + if (key_type == REG_EXPAND_SZ) + { + wchar_t dummy[1]; + DWORD len = ExpandEnvironmentStringsW (wc_temp, dummy, 1); + if (len > 0) + { + wchar_t *wc_temp_expanded = g_new (wchar_t, len); + if (ExpandEnvironmentStringsW (wc_temp, wc_temp_expanded, len) == len) + value_utf8 = g_utf16_to_utf8 (wc_temp_expanded, -1, NULL, NULL, NULL); + g_free (wc_temp_expanded); + } + } + else + { + value_utf8 = g_utf16_to_utf8 (wc_temp, -1, NULL, NULL, NULL); + } + g_free (wc_temp); + + } + g_free (wc_key); + + if (reg_key != NULL) + RegCloseKey (reg_key); + + return value_utf8; +} + +/*< private >*/ +void +g_content_type_set_mime_dirs (const gchar * const *dirs) +{ + /* noop on Windows */ +} + +/*< private >*/ +const gchar * const * +g_content_type_get_mime_dirs (void) +{ + const gchar * const *mime_dirs = { NULL }; + return mime_dirs; +} + +gboolean +g_content_type_equals (const gchar *type1, + const gchar *type2) +{ + char *progid1, *progid2; + gboolean res; + + g_return_val_if_fail (type1 != NULL, FALSE); + g_return_val_if_fail (type2 != NULL, FALSE); + + if (g_ascii_strcasecmp (type1, type2) == 0) + return TRUE; + + res = FALSE; + progid1 = get_registry_classes_key (type1, NULL); + progid2 = get_registry_classes_key (type2, NULL); + if (progid1 != NULL && progid2 != NULL && + strcmp (progid1, progid2) == 0) + res = TRUE; + g_free (progid1); + g_free (progid2); + + return res; +} + +gboolean +g_content_type_is_a (const gchar *type, + const gchar *supertype) +{ + gboolean res; + char *perceived_type; + char *perceived_supertype; + + g_return_val_if_fail (type != NULL, FALSE); + g_return_val_if_fail (supertype != NULL, FALSE); + + if (g_content_type_equals (type, supertype)) + return TRUE; + + perceived_type = get_registry_classes_key (type, L"PerceivedType"); + perceived_supertype = get_registry_classes_key (supertype, L"PerceivedType"); + + res = perceived_type && perceived_supertype && + strcmp (perceived_type, perceived_supertype) == 0; + + g_free (perceived_type); + g_free (perceived_supertype); + + return res; +} + +gboolean +g_content_type_is_mime_type (const gchar *type, + const gchar *mime_type) +{ + gchar *content_type; + gboolean ret; + + g_return_val_if_fail (type != NULL, FALSE); + g_return_val_if_fail (mime_type != NULL, FALSE); + + content_type = g_content_type_from_mime_type (mime_type); + ret = g_content_type_is_a (type, content_type); + g_free (content_type); + + return ret; +} + +gboolean +g_content_type_is_unknown (const gchar *type) +{ + g_return_val_if_fail (type != NULL, FALSE); + + return strcmp ("*", type) == 0; +} + +gchar * +g_content_type_get_description (const gchar *type) +{ + char *progid; + char *description; + + g_return_val_if_fail (type != NULL, NULL); + + progid = get_registry_classes_key (type, NULL); + if (progid) + { + description = get_registry_classes_key (progid, NULL); + g_free (progid); + + if (description) + return description; + } + + if (g_content_type_is_unknown (type)) + return g_strdup (_("Unknown type")); + + return g_strdup_printf (_("%s filetype"), type); +} + +gchar * +g_content_type_get_mime_type (const gchar *type) +{ + char *mime; + + g_return_val_if_fail (type != NULL, NULL); + + mime = get_registry_classes_key (type, L"Content Type"); + if (mime) + return mime; + else if (g_content_type_is_unknown (type)) + return g_strdup ("application/octet-stream"); + else if (*type == '.') + return g_strdup_printf ("application/x-ext-%s", type+1); + else if (strcmp ("inode/directory", type) == 0) + return g_strdup (type); + /* TODO: Map "image" to "image/ *", etc? */ + + return g_strdup ("application/octet-stream"); +} + +G_LOCK_DEFINE_STATIC (_type_icons); +static GHashTable *_type_icons = NULL; + +GIcon * +g_content_type_get_icon (const gchar *type) +{ + GIcon *themed_icon; + char *name = NULL; + + g_return_val_if_fail (type != NULL, NULL); + + /* In the Registry icons are the default value of + HKEY_CLASSES_ROOT\\DefaultIcon with typical values like: + : + REG_EXPAND_SZ: %SystemRoot%\System32\Wscript.exe,3 + REG_SZ: shimgvw.dll,3 + */ + G_LOCK (_type_icons); + if (!_type_icons) + _type_icons = g_hash_table_new (g_str_hash, g_str_equal); + name = g_hash_table_lookup (_type_icons, type); + if (!name && type[0] == '.') + { + /* double lookup by extension */ + gchar *key = get_registry_classes_key (type, NULL); + if (!key) + key = g_strconcat (type+1, "file\\DefaultIcon", NULL); + else + { + gchar *key2 = g_strconcat (key, "\\DefaultIcon", NULL); + g_free (key); + key = key2; + } + name = get_registry_classes_key (key, NULL); + if (name && strcmp (name, "%1") == 0) + { + g_free (name); + name = NULL; + } + if (name) + g_hash_table_insert (_type_icons, g_strdup (type), g_strdup (name)); + g_free (key); + } + + if (!name) + { + /* if no icon found, fall back to standard generic names */ + if (strcmp (type, "inode/directory") == 0) + name = "folder"; + else if (g_content_type_can_be_executable (type)) + name = "system-run"; + else + name = "text-x-generic"; + g_hash_table_insert (_type_icons, g_strdup (type), g_strdup (name)); + } + themed_icon = g_themed_icon_new (name); + G_UNLOCK (_type_icons); + + return G_ICON (themed_icon); +} + +GIcon * +g_content_type_get_symbolic_icon (const gchar *type) +{ + return g_content_type_get_icon (type); +} + +gchar * +g_content_type_get_generic_icon_name (const gchar *type) +{ + return NULL; +} + +gboolean +g_content_type_can_be_executable (const gchar *type) +{ + g_return_val_if_fail (type != NULL, FALSE); + + if (strcmp (type, ".exe") == 0 || + strcmp (type, ".com") == 0 || + strcmp (type, ".bat") == 0) + return TRUE; + + /* TODO: Also look at PATHEXT, which lists the extensions for + * "scripts" in addition to those for true binary executables. + * + * (PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH for me + * right now, for instance). And in a sense, all associated file + * types are "executable" on Windows... You can just type foo.jpg as + * a command name in cmd.exe, and it will run the application + * associated with .jpg. Hard to say what this API actually means + * with "executable". + */ + + return FALSE; +} + +static gboolean +looks_like_text (const guchar *data, + gsize data_size) +{ + gsize i; + guchar c; + for (i = 0; i < data_size; i++) + { + c = data[i]; + if (g_ascii_iscntrl (c) && !g_ascii_isspace (c) && c != '\b') + return FALSE; + } + return TRUE; +} + +gchar * +g_content_type_from_mime_type (const gchar *mime_type) +{ + char *key, *content_type; + + g_return_val_if_fail (mime_type != NULL, NULL); + + /* This is a hack to allow directories to have icons in filechooser */ + if (strcmp ("inode/directory", mime_type) == 0) + return g_strdup (mime_type); + + key = g_strconcat ("MIME\\DataBase\\Content Type\\", mime_type, NULL); + content_type = get_registry_classes_key (key, L"Extension"); + g_free (key); + + + return content_type ? g_steal_pointer (&content_type) : g_strdup ("*"); +} + +gchar * +g_content_type_guess (const gchar *filename, + const guchar *data, + gsize data_size, + gboolean *result_uncertain) +{ + char *basename; + char *type; + char *dot; + size_t i; + + type = NULL; + + if (result_uncertain) + *result_uncertain = FALSE; + + /* our test suite and potentially other code used -1 in the past, which is + * not documented and not allowed; guard against that */ + g_return_val_if_fail (data_size != (gsize) -1, g_strdup ("*")); + + if (filename) + { + i = strlen (filename); + if (i > 0 && filename[i - 1] == G_DIR_SEPARATOR) + { + type = g_strdup ("inode/directory"); + if (result_uncertain) + *result_uncertain = TRUE; + } + else + { + basename = g_path_get_basename (filename); + dot = strrchr (basename, '.'); + if (dot) + type = g_strdup (dot); + g_free (basename); + } + } + + if (type) + return type; + + if (data && looks_like_text (data, data_size)) + return g_strdup (".txt"); + + return g_strdup ("*"); +} + +GList * +g_content_types_get_registered (void) +{ + DWORD index; + wchar_t keyname[256]; + DWORD key_len; + char *key_utf8; + GList *types; + + types = NULL; + index = 0; + key_len = 256; + while (RegEnumKeyExW(HKEY_CLASSES_ROOT, + index, + keyname, + &key_len, + NULL, + NULL, + NULL, + NULL) == ERROR_SUCCESS) + { + key_utf8 = g_utf16_to_utf8 (keyname, -1, NULL, NULL, NULL); + if (key_utf8) + { + if (*key_utf8 == '.') + types = g_list_prepend (types, key_utf8); + else + g_free (key_utf8); + } + index++; + key_len = 256; + } + + return g_list_reverse (types); +} + +gchar ** +g_content_type_guess_for_tree (GFile *root) +{ + /* FIXME: implement */ + return NULL; +} diff --git a/gio/gcontenttype.c b/gio/gcontenttype.c new file mode 100644 index 0000000..1e4f19b --- /dev/null +++ b/gio/gcontenttype.c @@ -0,0 +1,1575 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include +#include +#include +#include +#include "gcontenttypeprivate.h" +#include "gthemedicon.h" +#include "gicon.h" +#include "gfile.h" +#include "gfileenumerator.h" +#include "gfileinfo.h" +#include "glibintl.h" +#include "glib-private.h" + + +/** + * SECTION:gcontenttype + * @short_description: Platform-specific content typing + * @include: gio/gio.h + * + * A content type is a platform specific string that defines the type + * of a file. On UNIX it is a + * [MIME type](http://www.wikipedia.org/wiki/Internet_media_type) + * like `text/plain` or `image/png`. + * On Win32 it is an extension string like `.doc`, `.txt` or a perceived + * string like `audio`. Such strings can be looked up in the registry at + * `HKEY_CLASSES_ROOT`. + * On macOS it is a [Uniform Type Identifier](https://en.wikipedia.org/wiki/Uniform_Type_Identifier) + * such as `com.apple.application`. + **/ + +#include + +#define XDG_PREFIX _gio_xdg +#include "xdgmime/xdgmime.h" + +static void tree_magic_schedule_reload (void); + +/* We lock this mutex whenever we modify global state in this module. + * Taking and releasing this lock should always be associated with a pair of + * g_begin_ignore_leaks()/g_end_ignore_leaks() calls, as any call into xdgmime + * could trigger xdg_mime_init(), which makes a number of one-time allocations + * which GLib can never free as it doesn’t know when is suitable to call + * xdg_mime_shutdown(). */ +G_LOCK_DEFINE_STATIC (gio_xdgmime); + +gsize +_g_unix_content_type_get_sniff_len (void) +{ + gsize size; + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + size = xdg_mime_get_max_buffer_extents (); + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + return size; +} + +gchar * +_g_unix_content_type_unalias (const gchar *type) +{ + gchar *res; + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + res = g_strdup (xdg_mime_unalias_mime_type (type)); + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + return res; +} + +gchar ** +_g_unix_content_type_get_parents (const gchar *type) +{ + const gchar *umime; + gchar **parents; + GPtrArray *array; + int i; + + array = g_ptr_array_new (); + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + + umime = xdg_mime_unalias_mime_type (type); + + g_ptr_array_add (array, g_strdup (umime)); + + parents = xdg_mime_list_mime_parents (umime); + for (i = 0; parents && parents[i] != NULL; i++) + g_ptr_array_add (array, g_strdup (parents[i])); + + free (parents); + + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + g_ptr_array_add (array, NULL); + + return (gchar **)g_ptr_array_free (array, FALSE); +} + +G_LOCK_DEFINE_STATIC (global_mime_dirs); +static gchar **global_mime_dirs = NULL; + +static void +_g_content_type_set_mime_dirs_locked (const char * const *dirs) +{ + g_clear_pointer (&global_mime_dirs, g_strfreev); + + if (dirs != NULL) + { + global_mime_dirs = g_strdupv ((gchar **) dirs); + } + else + { + GPtrArray *mime_dirs = g_ptr_array_new_with_free_func (g_free); + const gchar * const *system_dirs = g_get_system_data_dirs (); + + g_ptr_array_add (mime_dirs, g_build_filename (g_get_user_data_dir (), "mime", NULL)); + for (; *system_dirs != NULL; system_dirs++) + g_ptr_array_add (mime_dirs, g_build_filename (*system_dirs, "mime", NULL)); + g_ptr_array_add (mime_dirs, NULL); /* NULL terminator */ + + global_mime_dirs = (gchar **) g_ptr_array_free (mime_dirs, FALSE); + } + + xdg_mime_set_dirs ((const gchar * const *) global_mime_dirs); + tree_magic_schedule_reload (); +} + +/** + * g_content_type_set_mime_dirs: + * @dirs: (array zero-terminated=1) (nullable): %NULL-terminated list of + * directories to load MIME data from, including any `mime/` subdirectory, + * and with the first directory to try listed first + * + * Set the list of directories used by GIO to load the MIME database. + * If @dirs is %NULL, the directories used are the default: + * + * - the `mime` subdirectory of the directory in `$XDG_DATA_HOME` + * - the `mime` subdirectory of every directory in `$XDG_DATA_DIRS` + * + * This function is intended to be used when writing tests that depend on + * information stored in the MIME database, in order to control the data. + * + * Typically, in case your tests use %G_TEST_OPTION_ISOLATE_DIRS, but they + * depend on the system’s MIME database, you should call this function + * with @dirs set to %NULL before calling g_test_init(), for instance: + * + * |[ + * // Load MIME data from the system + * g_content_type_set_mime_dirs (NULL); + * // Isolate the environment + * g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + * + * … + * + * return g_test_run (); + * ]| + * + * Since: 2.60 + */ +/*< private >*/ +void +g_content_type_set_mime_dirs (const gchar * const *dirs) +{ + G_LOCK (global_mime_dirs); + _g_content_type_set_mime_dirs_locked (dirs); + G_UNLOCK (global_mime_dirs); +} + +/** + * g_content_type_get_mime_dirs: + * + * Get the list of directories which MIME data is loaded from. See + * g_content_type_set_mime_dirs() for details. + * + * Returns: (transfer none) (array zero-terminated=1): %NULL-terminated list of + * directories to load MIME data from, including any `mime/` subdirectory, + * and with the first directory to try listed first + * Since: 2.60 + */ +/*< private >*/ +const gchar * const * +g_content_type_get_mime_dirs (void) +{ + const gchar * const *mime_dirs; + + G_LOCK (global_mime_dirs); + + if (global_mime_dirs == NULL) + _g_content_type_set_mime_dirs_locked (NULL); + + mime_dirs = (const gchar * const *) global_mime_dirs; + + G_UNLOCK (global_mime_dirs); + + g_assert (mime_dirs != NULL); + return mime_dirs; +} + +/** + * g_content_type_equals: + * @type1: a content type string + * @type2: a content type string + * + * Compares two content types for equality. + * + * Returns: %TRUE if the two strings are identical or equivalent, + * %FALSE otherwise. + */ +gboolean +g_content_type_equals (const gchar *type1, + const gchar *type2) +{ + gboolean res; + + g_return_val_if_fail (type1 != NULL, FALSE); + g_return_val_if_fail (type2 != NULL, FALSE); + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + res = xdg_mime_mime_type_equal (type1, type2); + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + return res; +} + +/** + * g_content_type_is_a: + * @type: a content type string + * @supertype: a content type string + * + * Determines if @type is a subset of @supertype. + * + * Returns: %TRUE if @type is a kind of @supertype, + * %FALSE otherwise. + */ +gboolean +g_content_type_is_a (const gchar *type, + const gchar *supertype) +{ + gboolean res; + + g_return_val_if_fail (type != NULL, FALSE); + g_return_val_if_fail (supertype != NULL, FALSE); + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + res = xdg_mime_mime_type_subclass (type, supertype); + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + return res; +} + +/** + * g_content_type_is_mime_type: + * @type: a content type string + * @mime_type: a mime type string + * + * Determines if @type is a subset of @mime_type. + * Convenience wrapper around g_content_type_is_a(). + * + * Returns: %TRUE if @type is a kind of @mime_type, + * %FALSE otherwise. + * + * Since: 2.52 + */ +gboolean +g_content_type_is_mime_type (const gchar *type, + const gchar *mime_type) +{ + return g_content_type_is_a (type, mime_type); +} + +/** + * g_content_type_is_unknown: + * @type: a content type string + * + * Checks if the content type is the generic "unknown" type. + * On UNIX this is the "application/octet-stream" mimetype, + * while on win32 it is "*" and on OSX it is a dynamic type + * or octet-stream. + * + * Returns: %TRUE if the type is the unknown type. + */ +gboolean +g_content_type_is_unknown (const gchar *type) +{ + g_return_val_if_fail (type != NULL, FALSE); + + return strcmp (XDG_MIME_TYPE_UNKNOWN, type) == 0; +} + + +typedef enum { + MIME_TAG_TYPE_OTHER, + MIME_TAG_TYPE_COMMENT +} MimeTagType; + +typedef struct { + int current_type; + int current_lang_level; + int comment_lang_level; + char *comment; +} MimeParser; + + +static int +language_level (const char *lang) +{ + const char * const *lang_list; + int i; + + /* The returned list is sorted from most desirable to least + desirable and always contains the default locale "C". */ + lang_list = g_get_language_names (); + + for (i = 0; lang_list[i]; i++) + if (strcmp (lang_list[i], lang) == 0) + return 1000-i; + + return 0; +} + +static void +mime_info_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + int i; + const char *lang; + MimeParser *parser = user_data; + + if (strcmp (element_name, "comment") == 0) + { + lang = "C"; + for (i = 0; attribute_names[i]; i++) + if (strcmp (attribute_names[i], "xml:lang") == 0) + { + lang = attribute_values[i]; + break; + } + + parser->current_lang_level = language_level (lang); + parser->current_type = MIME_TAG_TYPE_COMMENT; + } + else + parser->current_type = MIME_TAG_TYPE_OTHER; +} + +static void +mime_info_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + MimeParser *parser = user_data; + + parser->current_type = MIME_TAG_TYPE_OTHER; +} + +static void +mime_info_text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + MimeParser *parser = user_data; + + if (parser->current_type == MIME_TAG_TYPE_COMMENT && + parser->current_lang_level > parser->comment_lang_level) + { + g_free (parser->comment); + parser->comment = g_strndup (text, text_len); + parser->comment_lang_level = parser->current_lang_level; + } +} + +static char * +load_comment_for_mime_helper (const char *dir, + const char *basename) +{ + GMarkupParseContext *context; + char *filename, *data; + gsize len; + gboolean res; + MimeParser parse_data = {0}; + GMarkupParser parser = { + mime_info_start_element, + mime_info_end_element, + mime_info_text, + NULL, + NULL + }; + + filename = g_build_filename (dir, basename, NULL); + + res = g_file_get_contents (filename, &data, &len, NULL); + g_free (filename); + if (!res) + return NULL; + + context = g_markup_parse_context_new (&parser, 0, &parse_data, NULL); + res = g_markup_parse_context_parse (context, data, len, NULL); + g_free (data); + g_markup_parse_context_free (context); + + if (!res) + return NULL; + + return parse_data.comment; +} + + +static char * +load_comment_for_mime (const char *mimetype) +{ + const char * const *dirs; + char *basename; + char *comment; + gsize i; + + basename = g_strdup_printf ("%s.xml", mimetype); + + dirs = g_content_type_get_mime_dirs (); + for (i = 0; dirs[i] != NULL; i++) + { + comment = load_comment_for_mime_helper (dirs[i], basename); + if (comment) + { + g_free (basename); + return comment; + } + } + g_free (basename); + + return g_strdup_printf (_("%s type"), mimetype); +} + +/** + * g_content_type_get_description: + * @type: a content type string + * + * Gets the human readable description of the content type. + * + * Returns: a short description of the content type @type. Free the + * returned string with g_free() + */ +gchar * +g_content_type_get_description (const gchar *type) +{ + static GHashTable *type_comment_cache = NULL; + gchar *type_copy = NULL; + gchar *comment; + + g_return_val_if_fail (type != NULL, NULL); + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + type = xdg_mime_unalias_mime_type (type); + g_end_ignore_leaks (); + + if (type_comment_cache == NULL) + type_comment_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + comment = g_hash_table_lookup (type_comment_cache, type); + comment = g_strdup (comment); + + if (comment != NULL) + { + G_UNLOCK (gio_xdgmime); + return comment; + } + + type_copy = g_strdup (type); + + G_UNLOCK (gio_xdgmime); + comment = load_comment_for_mime (type_copy); + G_LOCK (gio_xdgmime); + + g_hash_table_insert (type_comment_cache, + g_steal_pointer (&type_copy), + g_strdup (comment)); + G_UNLOCK (gio_xdgmime); + + return comment; +} + +/** + * g_content_type_get_mime_type: + * @type: a content type string + * + * Gets the mime type for the content type, if one is registered. + * + * Returns: (nullable) (transfer full): the registered mime type for the + * given @type, or %NULL if unknown; free with g_free(). + */ +char * +g_content_type_get_mime_type (const char *type) +{ + g_return_val_if_fail (type != NULL, NULL); + + return g_strdup (type); +} + +static GIcon * +g_content_type_get_icon_internal (const gchar *type, + gboolean symbolic) +{ + char *mimetype_icon; + char *generic_mimetype_icon = NULL; + char *q; + char *icon_names[6]; + int n = 0; + GIcon *themed_icon; + const char *xdg_icon; + int i; + + g_return_val_if_fail (type != NULL, NULL); + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + xdg_icon = xdg_mime_get_icon (type); + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + if (xdg_icon) + icon_names[n++] = g_strdup (xdg_icon); + + mimetype_icon = g_strdup (type); + while ((q = strchr (mimetype_icon, '/')) != NULL) + *q = '-'; + + icon_names[n++] = mimetype_icon; + + generic_mimetype_icon = g_content_type_get_generic_icon_name (type); + if (generic_mimetype_icon) + icon_names[n++] = generic_mimetype_icon; + + if (symbolic) + { + for (i = 0; i < n; i++) + { + icon_names[n + i] = icon_names[i]; + icon_names[i] = g_strconcat (icon_names[i], "-symbolic", NULL); + } + + n += n; + } + + themed_icon = g_themed_icon_new_from_names (icon_names, n); + + for (i = 0; i < n; i++) + g_free (icon_names[i]); + + return themed_icon; +} + +/** + * g_content_type_get_icon: + * @type: a content type string + * + * Gets the icon for a content type. + * + * Returns: (transfer full): #GIcon corresponding to the content type. Free the returned + * object with g_object_unref() + */ +GIcon * +g_content_type_get_icon (const gchar *type) +{ + return g_content_type_get_icon_internal (type, FALSE); +} + +/** + * g_content_type_get_symbolic_icon: + * @type: a content type string + * + * Gets the symbolic icon for a content type. + * + * Returns: (transfer full): symbolic #GIcon corresponding to the content type. + * Free the returned object with g_object_unref() + * + * Since: 2.34 + */ +GIcon * +g_content_type_get_symbolic_icon (const gchar *type) +{ + return g_content_type_get_icon_internal (type, TRUE); +} + +/** + * g_content_type_get_generic_icon_name: + * @type: a content type string + * + * Gets the generic icon name for a content type. + * + * See the + * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec) + * specification for more on the generic icon name. + * + * Returns: (nullable): the registered generic icon name for the given @type, + * or %NULL if unknown. Free with g_free() + * + * Since: 2.34 + */ +gchar * +g_content_type_get_generic_icon_name (const gchar *type) +{ + const gchar *xdg_icon_name; + gchar *icon_name; + + g_return_val_if_fail (type != NULL, NULL); + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + xdg_icon_name = xdg_mime_get_generic_icon (type); + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + if (!xdg_icon_name) + { + const char *p; + const char *suffix = "-x-generic"; + + p = strchr (type, '/'); + if (p == NULL) + p = type + strlen (type); + + icon_name = g_malloc (p - type + strlen (suffix) + 1); + memcpy (icon_name, type, p - type); + memcpy (icon_name + (p - type), suffix, strlen (suffix)); + icon_name[(p - type) + strlen (suffix)] = 0; + } + else + { + icon_name = g_strdup (xdg_icon_name); + } + + return icon_name; +} + +/** + * g_content_type_can_be_executable: + * @type: a content type string + * + * Checks if a content type can be executable. Note that for instance + * things like text files can be executables (i.e. scripts and batch files). + * + * Returns: %TRUE if the file type corresponds to a type that + * can be executable, %FALSE otherwise. + */ +gboolean +g_content_type_can_be_executable (const gchar *type) +{ + g_return_val_if_fail (type != NULL, FALSE); + + if (g_content_type_is_a (type, "application/x-executable") || + g_content_type_is_a (type, "text/plain")) + return TRUE; + + return FALSE; +} + +static gboolean +looks_like_text (const guchar *data, gsize data_size) +{ + gsize i; + char c; + + for (i = 0; i < data_size; i++) + { + c = data[i]; + + if (g_ascii_iscntrl (c) && + !g_ascii_isspace (c) && + c != '\b') + return FALSE; + } + return TRUE; +} + +/** + * g_content_type_from_mime_type: + * @mime_type: a mime type string + * + * Tries to find a content type based on the mime type name. + * + * Returns: (nullable): Newly allocated string with content type or + * %NULL. Free with g_free() + * + * Since: 2.18 + **/ +gchar * +g_content_type_from_mime_type (const gchar *mime_type) +{ + char *umime; + + g_return_val_if_fail (mime_type != NULL, NULL); + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + /* mime type and content type are same on unixes */ + umime = g_strdup (xdg_mime_unalias_mime_type (mime_type)); + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + return umime; +} + +/** + * g_content_type_guess: + * @filename: (nullable) (type filename): a path, or %NULL + * @data: (nullable) (array length=data_size): a stream of data, or %NULL + * @data_size: the size of @data + * @result_uncertain: (out) (optional): return location for the certainty + * of the result, or %NULL + * + * Guesses the content type based on example data. If the function is + * uncertain, @result_uncertain will be set to %TRUE. Either @filename + * or @data may be %NULL, in which case the guess will be based solely + * on the other argument. + * + * Returns: a string indicating a guessed content type for the + * given data. Free with g_free() + */ +gchar * +g_content_type_guess (const gchar *filename, + const guchar *data, + gsize data_size, + gboolean *result_uncertain) +{ + char *basename; + const char *name_mimetypes[10], *sniffed_mimetype; + char *mimetype; + int i; + int n_name_mimetypes; + int sniffed_prio; + + sniffed_prio = 0; + n_name_mimetypes = 0; + sniffed_mimetype = XDG_MIME_TYPE_UNKNOWN; + + if (result_uncertain) + *result_uncertain = FALSE; + + /* our test suite and potentially other code used -1 in the past, which is + * not documented and not allowed; guard against that */ + g_return_val_if_fail (data_size != (gsize) -1, g_strdup (XDG_MIME_TYPE_UNKNOWN)); + + G_LOCK (gio_xdgmime); + g_begin_ignore_leaks (); + + if (filename) + { + i = strlen (filename); + if (i > 0 && filename[i - 1] == '/') + { + name_mimetypes[0] = "inode/directory"; + name_mimetypes[1] = NULL; + n_name_mimetypes = 1; + if (result_uncertain) + *result_uncertain = TRUE; + } + else + { + basename = g_path_get_basename (filename); + n_name_mimetypes = xdg_mime_get_mime_types_from_file_name (basename, name_mimetypes, 10); + g_free (basename); + } + } + + /* Got an extension match, and no conflicts. This is it. */ + if (n_name_mimetypes == 1) + { + gchar *s = g_strdup (name_mimetypes[0]); + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + return s; + } + + if (data) + { + sniffed_mimetype = xdg_mime_get_mime_type_for_data (data, data_size, &sniffed_prio); + if (sniffed_mimetype == XDG_MIME_TYPE_UNKNOWN && + data && + looks_like_text (data, data_size)) + sniffed_mimetype = "text/plain"; + + /* For security reasons we don't ever want to sniff desktop files + * where we know the filename and it doesn't have a .desktop extension. + * This is because desktop files allow executing any application and + * we don't want to make it possible to hide them looking like something + * else. + */ + if (filename != NULL && + strcmp (sniffed_mimetype, "application/x-desktop") == 0) + sniffed_mimetype = "text/plain"; + } + + if (n_name_mimetypes == 0) + { + if (sniffed_mimetype == XDG_MIME_TYPE_UNKNOWN && + result_uncertain) + *result_uncertain = TRUE; + + mimetype = g_strdup (sniffed_mimetype); + } + else + { + mimetype = NULL; + if (sniffed_mimetype != XDG_MIME_TYPE_UNKNOWN) + { + if (sniffed_prio >= 80) /* High priority sniffing match, use that */ + mimetype = g_strdup (sniffed_mimetype); + else + { + /* There are conflicts between the name matches and we + * have a sniffed type, use that as a tie breaker. + */ + for (i = 0; i < n_name_mimetypes; i++) + { + if ( xdg_mime_mime_type_subclass (name_mimetypes[i], sniffed_mimetype)) + { + /* This nametype match is derived from (or the same as) + * the sniffed type). This is probably it. + */ + mimetype = g_strdup (name_mimetypes[i]); + break; + } + } + } + } + + if (mimetype == NULL) + { + /* Conflicts, and sniffed type was no help or not there. + * Guess on the first one + */ + mimetype = g_strdup (name_mimetypes[0]); + if (result_uncertain) + *result_uncertain = TRUE; + } + } + + g_end_ignore_leaks (); + G_UNLOCK (gio_xdgmime); + + return mimetype; +} + +static void +enumerate_mimetypes_subdir (const char *dir, + const char *prefix, + GHashTable *mimetypes) +{ + DIR *d; + struct dirent *ent; + char *mimetype; + + d = opendir (dir); + if (d) + { + while ((ent = readdir (d)) != NULL) + { + if (g_str_has_suffix (ent->d_name, ".xml")) + { + mimetype = g_strdup_printf ("%s/%.*s", prefix, (int) strlen (ent->d_name) - 4, ent->d_name); + g_hash_table_replace (mimetypes, mimetype, NULL); + } + } + closedir (d); + } +} + +static void +enumerate_mimetypes_dir (const char *dir, + GHashTable *mimetypes) +{ + DIR *d; + struct dirent *ent; + const char *mimedir; + char *name; + + mimedir = dir; + + d = opendir (mimedir); + if (d) + { + while ((ent = readdir (d)) != NULL) + { + if (strcmp (ent->d_name, "packages") != 0) + { + name = g_build_filename (mimedir, ent->d_name, NULL); + if (g_file_test (name, G_FILE_TEST_IS_DIR)) + enumerate_mimetypes_subdir (name, ent->d_name, mimetypes); + g_free (name); + } + } + closedir (d); + } +} + +/** + * g_content_types_get_registered: + * + * Gets a list of strings containing all the registered content types + * known to the system. The list and its data should be freed using + * `g_list_free_full (list, g_free)`. + * + * Returns: (element-type utf8) (transfer full): list of the registered + * content types + */ +GList * +g_content_types_get_registered (void) +{ + const char * const *dirs; + GHashTable *mimetypes; + GHashTableIter iter; + gpointer key; + gsize i; + GList *l; + + mimetypes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + dirs = g_content_type_get_mime_dirs (); + for (i = 0; dirs[i] != NULL; i++) + enumerate_mimetypes_dir (dirs[i], mimetypes); + + l = NULL; + g_hash_table_iter_init (&iter, mimetypes); + while (g_hash_table_iter_next (&iter, &key, NULL)) + { + l = g_list_prepend (l, key); + g_hash_table_iter_steal (&iter); + } + + g_hash_table_destroy (mimetypes); + + return l; +} + + +/* tree magic data */ +static GList *tree_matches = NULL; +static gboolean need_reload = FALSE; + +G_LOCK_DEFINE_STATIC (gio_treemagic); + +typedef struct +{ + gchar *path; + GFileType type; + guint match_case : 1; + guint executable : 1; + guint non_empty : 1; + guint on_disc : 1; + gchar *mimetype; + GList *matches; +} TreeMatchlet; + +typedef struct +{ + gchar *contenttype; + gint priority; + GList *matches; +} TreeMatch; + + +static void +tree_matchlet_free (TreeMatchlet *matchlet) +{ + g_list_free_full (matchlet->matches, (GDestroyNotify) tree_matchlet_free); + g_free (matchlet->path); + g_free (matchlet->mimetype); + g_slice_free (TreeMatchlet, matchlet); +} + +static void +tree_match_free (TreeMatch *match) +{ + g_list_free_full (match->matches, (GDestroyNotify) tree_matchlet_free); + g_free (match->contenttype); + g_slice_free (TreeMatch, match); +} + +static TreeMatch * +parse_header (gchar *line) +{ + gint len; + gchar *s; + TreeMatch *match; + + len = strlen (line); + + if (line[0] != '[' || line[len - 1] != ']') + return NULL; + + line[len - 1] = 0; + s = strchr (line, ':'); + if (s == NULL) + return NULL; + + match = g_slice_new0 (TreeMatch); + match->priority = atoi (line + 1); + match->contenttype = g_strdup (s + 1); + + return match; +} + +static TreeMatchlet * +parse_match_line (gchar *line, + gint *depth) +{ + gchar *s, *p; + TreeMatchlet *matchlet; + gchar **parts; + gint i; + + matchlet = g_slice_new0 (TreeMatchlet); + + if (line[0] == '>') + { + *depth = 0; + s = line; + } + else + { + *depth = atoi (line); + s = strchr (line, '>'); + if (s == NULL) + goto handle_error; + } + s += 2; + p = strchr (s, '"'); + if (p == NULL) + goto handle_error; + *p = 0; + + matchlet->path = g_strdup (s); + s = p + 1; + parts = g_strsplit (s, ",", 0); + if (strcmp (parts[0], "=file") == 0) + matchlet->type = G_FILE_TYPE_REGULAR; + else if (strcmp (parts[0], "=directory") == 0) + matchlet->type = G_FILE_TYPE_DIRECTORY; + else if (strcmp (parts[0], "=link") == 0) + matchlet->type = G_FILE_TYPE_SYMBOLIC_LINK; + else + matchlet->type = G_FILE_TYPE_UNKNOWN; + for (i = 1; parts[i]; i++) + { + if (strcmp (parts[i], "executable") == 0) + matchlet->executable = 1; + else if (strcmp (parts[i], "match-case") == 0) + matchlet->match_case = 1; + else if (strcmp (parts[i], "non-empty") == 0) + matchlet->non_empty = 1; + else if (strcmp (parts[i], "on-disc") == 0) + matchlet->on_disc = 1; + else + matchlet->mimetype = g_strdup (parts[i]); + } + + g_strfreev (parts); + + return matchlet; + +handle_error: + g_slice_free (TreeMatchlet, matchlet); + return NULL; +} + +static gint +cmp_match (gconstpointer a, gconstpointer b) +{ + const TreeMatch *aa = (const TreeMatch *)a; + const TreeMatch *bb = (const TreeMatch *)b; + + return bb->priority - aa->priority; +} + +static void +insert_match (TreeMatch *match) +{ + tree_matches = g_list_insert_sorted (tree_matches, match, cmp_match); +} + +static void +insert_matchlet (TreeMatch *match, + TreeMatchlet *matchlet, + gint depth) +{ + if (depth == 0) + match->matches = g_list_append (match->matches, matchlet); + else + { + GList *last; + TreeMatchlet *m; + + last = g_list_last (match->matches); + if (!last) + { + tree_matchlet_free (matchlet); + g_warning ("can't insert tree matchlet at depth %d", depth); + return; + } + + m = (TreeMatchlet *) last->data; + while (--depth > 0) + { + last = g_list_last (m->matches); + if (!last) + { + tree_matchlet_free (matchlet); + g_warning ("can't insert tree matchlet at depth %d", depth); + return; + } + + m = (TreeMatchlet *) last->data; + } + m->matches = g_list_append (m->matches, matchlet); + } +} + +static void +read_tree_magic_from_directory (const gchar *prefix) +{ + gchar *filename; + gchar *text; + gsize len; + gchar **lines; + gsize i; + TreeMatch *match; + TreeMatchlet *matchlet; + gint depth; + + filename = g_build_filename (prefix, "treemagic", NULL); + + if (g_file_get_contents (filename, &text, &len, NULL)) + { + if (strcmp (text, "MIME-TreeMagic") == 0) + { + lines = g_strsplit (text + strlen ("MIME-TreeMagic") + 2, "\n", 0); + match = NULL; + for (i = 0; lines[i] && lines[i][0]; i++) + { + if (lines[i][0] == '[' && (match = parse_header (lines[i])) != NULL) + { + insert_match (match); + } + else if (match != NULL) + { + matchlet = parse_match_line (lines[i], &depth); + if (matchlet == NULL) + { + g_warning ("%s: body corrupt; skipping", filename); + break; + } + insert_matchlet (match, matchlet, depth); + } + else + { + g_warning ("%s: header corrupt; skipping", filename); + break; + } + } + + g_strfreev (lines); + } + else + g_warning ("%s: header not found, skipping", filename); + + g_free (text); + } + + g_free (filename); +} + +static void +tree_magic_schedule_reload (void) +{ + need_reload = TRUE; +} + +static void +xdg_mime_reload (void *user_data) +{ + tree_magic_schedule_reload (); +} + +static void +tree_magic_shutdown (void) +{ + g_list_free_full (tree_matches, (GDestroyNotify) tree_match_free); + tree_matches = NULL; +} + +static void +tree_magic_init (void) +{ + static gboolean initialized = FALSE; + gsize i; + + if (!initialized) + { + initialized = TRUE; + + xdg_mime_register_reload_callback (xdg_mime_reload, NULL, NULL); + need_reload = TRUE; + } + + if (need_reload) + { + const char * const *dirs; + + need_reload = FALSE; + + tree_magic_shutdown (); + + dirs = g_content_type_get_mime_dirs (); + for (i = 0; dirs[i] != NULL; i++) + read_tree_magic_from_directory (dirs[i]); + } +} + +/* a filtering enumerator */ + +typedef struct +{ + gchar *path; + gint depth; + gboolean ignore_case; + gchar **components; + gchar **case_components; + GFileEnumerator **enumerators; + GFile **children; +} Enumerator; + +static gboolean +component_match (Enumerator *e, + gint depth, + const gchar *name) +{ + gchar *case_folded, *key; + gboolean found; + + if (strcmp (name, e->components[depth]) == 0) + return TRUE; + + if (!e->ignore_case) + return FALSE; + + case_folded = g_utf8_casefold (name, -1); + key = g_utf8_collate_key (case_folded, -1); + + found = strcmp (key, e->case_components[depth]) == 0; + + g_free (case_folded); + g_free (key); + + return found; +} + +static GFile * +next_match_recurse (Enumerator *e, + gint depth) +{ + GFile *file; + GFileInfo *info; + const gchar *name; + + while (TRUE) + { + if (e->enumerators[depth] == NULL) + { + if (depth > 0) + { + file = next_match_recurse (e, depth - 1); + if (file) + { + e->children[depth] = file; + e->enumerators[depth] = g_file_enumerate_children (file, + G_FILE_ATTRIBUTE_STANDARD_NAME, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + } + } + if (e->enumerators[depth] == NULL) + return NULL; + } + + while ((info = g_file_enumerator_next_file (e->enumerators[depth], NULL, NULL))) + { + name = g_file_info_get_name (info); + if (component_match (e, depth, name)) + { + file = g_file_get_child (e->children[depth], name); + g_object_unref (info); + return file; + } + g_object_unref (info); + } + + g_object_unref (e->enumerators[depth]); + e->enumerators[depth] = NULL; + g_object_unref (e->children[depth]); + e->children[depth] = NULL; + } +} + +static GFile * +enumerator_next (Enumerator *e) +{ + return next_match_recurse (e, e->depth - 1); +} + +static Enumerator * +enumerator_new (GFile *root, + const char *path, + gboolean ignore_case) +{ + Enumerator *e; + gint i; + gchar *case_folded; + + e = g_new0 (Enumerator, 1); + e->path = g_strdup (path); + e->ignore_case = ignore_case; + + e->components = g_strsplit (e->path, G_DIR_SEPARATOR_S, -1); + e->depth = g_strv_length (e->components); + if (e->ignore_case) + { + e->case_components = g_new0 (char *, e->depth + 1); + for (i = 0; e->components[i]; i++) + { + case_folded = g_utf8_casefold (e->components[i], -1); + e->case_components[i] = g_utf8_collate_key (case_folded, -1); + g_free (case_folded); + } + } + + e->children = g_new0 (GFile *, e->depth); + e->children[0] = g_object_ref (root); + e->enumerators = g_new0 (GFileEnumerator *, e->depth); + e->enumerators[0] = g_file_enumerate_children (root, + G_FILE_ATTRIBUTE_STANDARD_NAME, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + + return e; +} + +static void +enumerator_free (Enumerator *e) +{ + gint i; + + for (i = 0; i < e->depth; i++) + { + if (e->enumerators[i]) + g_object_unref (e->enumerators[i]); + if (e->children[i]) + g_object_unref (e->children[i]); + } + + g_free (e->enumerators); + g_free (e->children); + g_strfreev (e->components); + if (e->case_components) + g_strfreev (e->case_components); + g_free (e->path); + g_free (e); +} + +static gboolean +matchlet_match (TreeMatchlet *matchlet, + GFile *root) +{ + GFile *file; + GFileInfo *info; + gboolean result; + const gchar *attrs; + Enumerator *e; + GList *l; + + e = enumerator_new (root, matchlet->path, !matchlet->match_case); + + do + { + file = enumerator_next (e); + if (!file) + { + enumerator_free (e); + return FALSE; + } + + if (matchlet->mimetype) + attrs = G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE "," + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE; + else + attrs = G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE; + info = g_file_query_info (file, + attrs, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + if (info) + { + result = TRUE; + + if (matchlet->type != G_FILE_TYPE_UNKNOWN && + g_file_info_get_file_type (info) != matchlet->type) + result = FALSE; + + if (matchlet->executable && + !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE)) + result = FALSE; + } + else + result = FALSE; + + if (result && matchlet->non_empty) + { + GFileEnumerator *child_enum; + GFileInfo *child_info; + + child_enum = g_file_enumerate_children (file, + G_FILE_ATTRIBUTE_STANDARD_NAME, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + + if (child_enum) + { + child_info = g_file_enumerator_next_file (child_enum, NULL, NULL); + if (child_info) + g_object_unref (child_info); + else + result = FALSE; + g_object_unref (child_enum); + } + else + result = FALSE; + } + + if (result && matchlet->mimetype) + { + if (strcmp (matchlet->mimetype, g_file_info_get_content_type (info)) != 0) + result = FALSE; + } + + if (info) + g_object_unref (info); + g_object_unref (file); + } + while (!result); + + enumerator_free (e); + + if (!matchlet->matches) + return TRUE; + + for (l = matchlet->matches; l; l = l->next) + { + TreeMatchlet *submatchlet; + + submatchlet = l->data; + if (matchlet_match (submatchlet, root)) + return TRUE; + } + + return FALSE; +} + +static void +match_match (TreeMatch *match, + GFile *root, + GPtrArray *types) +{ + GList *l; + + for (l = match->matches; l; l = l->next) + { + TreeMatchlet *matchlet = l->data; + if (matchlet_match (matchlet, root)) + { + g_ptr_array_add (types, g_strdup (match->contenttype)); + break; + } + } +} + +/** + * g_content_type_guess_for_tree: + * @root: the root of the tree to guess a type for + * + * Tries to guess the type of the tree with root @root, by + * looking at the files it contains. The result is an array + * of content types, with the best guess coming first. + * + * The types returned all have the form x-content/foo, e.g. + * x-content/audio-cdda (for audio CDs) or x-content/image-dcf + * (for a camera memory card). See the + * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec) + * specification for more on x-content types. + * + * This function is useful in the implementation of + * g_mount_guess_content_type(). + * + * Returns: (transfer full) (array zero-terminated=1): an %NULL-terminated + * array of zero or more content types. Free with g_strfreev() + * + * Since: 2.18 + */ +gchar ** +g_content_type_guess_for_tree (GFile *root) +{ + GPtrArray *types; + GList *l; + + types = g_ptr_array_new (); + + G_LOCK (gio_treemagic); + + tree_magic_init (); + for (l = tree_matches; l; l = l->next) + { + TreeMatch *match = l->data; + match_match (match, root, types); + } + + G_UNLOCK (gio_treemagic); + + g_ptr_array_add (types, NULL); + + return (gchar **)g_ptr_array_free (types, FALSE); +} diff --git a/gio/gcontenttype.h b/gio/gcontenttype.h new file mode 100644 index 0000000..db2c974 --- /dev/null +++ b/gio/gcontenttype.h @@ -0,0 +1,82 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_CONTENT_TYPE_H__ +#define __G_CONTENT_TYPE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +gboolean g_content_type_equals (const gchar *type1, + const gchar *type2); +GLIB_AVAILABLE_IN_ALL +gboolean g_content_type_is_a (const gchar *type, + const gchar *supertype); +GLIB_AVAILABLE_IN_2_52 +gboolean g_content_type_is_mime_type (const gchar *type, + const gchar *mime_type); +GLIB_AVAILABLE_IN_ALL +gboolean g_content_type_is_unknown (const gchar *type); +GLIB_AVAILABLE_IN_ALL +gchar * g_content_type_get_description (const gchar *type); +GLIB_AVAILABLE_IN_ALL +gchar * g_content_type_get_mime_type (const gchar *type); +GLIB_AVAILABLE_IN_ALL +GIcon * g_content_type_get_icon (const gchar *type); +GLIB_AVAILABLE_IN_2_34 +GIcon * g_content_type_get_symbolic_icon (const gchar *type); +GLIB_AVAILABLE_IN_2_34 +gchar * g_content_type_get_generic_icon_name (const gchar *type); + +GLIB_AVAILABLE_IN_ALL +gboolean g_content_type_can_be_executable (const gchar *type); + +GLIB_AVAILABLE_IN_ALL +gchar * g_content_type_from_mime_type (const gchar *mime_type); + +GLIB_AVAILABLE_IN_ALL +gchar * g_content_type_guess (const gchar *filename, + const guchar *data, + gsize data_size, + gboolean *result_uncertain); + +GLIB_AVAILABLE_IN_ALL +gchar ** g_content_type_guess_for_tree (GFile *root); + +GLIB_AVAILABLE_IN_ALL +GList * g_content_types_get_registered (void); + +/*< private >*/ +#ifndef __GTK_DOC_IGNORE__ +GLIB_AVAILABLE_IN_2_60 +const gchar * const *g_content_type_get_mime_dirs (void); +GLIB_AVAILABLE_IN_2_60 +void g_content_type_set_mime_dirs (const gchar * const *dirs); +#endif /* __GTK_DOC_IGNORE__ */ + +G_END_DECLS + +#endif /* __G_CONTENT_TYPE_H__ */ diff --git a/gio/gcontenttypeprivate.h b/gio/gcontenttypeprivate.h new file mode 100644 index 0000000..768a647 --- /dev/null +++ b/gio/gcontenttypeprivate.h @@ -0,0 +1,34 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_CONTENT_TYPE_PRIVATE_H__ +#define __G_CONTENT_TYPE_PRIVATE_H__ + +#include "gcontenttype.h" + +G_BEGIN_DECLS + +gsize _g_unix_content_type_get_sniff_len (void); +char * _g_unix_content_type_unalias (const char *type); +char **_g_unix_content_type_get_parents (const char *type); + +G_END_DECLS + +#endif /* __G_CONTENT_TYPE_PRIVATE_H__ */ diff --git a/gio/gcontextspecificgroup.c b/gio/gcontextspecificgroup.c new file mode 100644 index 0000000..acad727 --- /dev/null +++ b/gio/gcontextspecificgroup.c @@ -0,0 +1,274 @@ +/* + * Copyright © 2015 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gcontextspecificgroup.h" + +#include +#include "glib-private.h" + +typedef struct +{ + GSource source; + + GMutex lock; + gpointer instance; + GQueue pending; +} GContextSpecificSource; + +static gboolean +g_context_specific_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GContextSpecificSource *css = (GContextSpecificSource *) source; + guint signal_id; + + g_mutex_lock (&css->lock); + + g_assert (!g_queue_is_empty (&css->pending)); + signal_id = GPOINTER_TO_UINT (g_queue_pop_head (&css->pending)); + + if (g_queue_is_empty (&css->pending)) + g_source_set_ready_time (source, -1); + + g_mutex_unlock (&css->lock); + + g_signal_emit (css->instance, signal_id, 0); + + return TRUE; +} + +static void +g_context_specific_source_finalize (GSource *source) +{ + GContextSpecificSource *css = (GContextSpecificSource *) source; + + g_mutex_clear (&css->lock); + g_queue_clear (&css->pending); +} + +static GContextSpecificSource * +g_context_specific_source_new (const gchar *name, + gpointer instance) +{ + static GSourceFuncs source_funcs = { + NULL, + NULL, + g_context_specific_source_dispatch, + g_context_specific_source_finalize, + NULL, NULL + }; + GContextSpecificSource *css; + GSource *source; + + source = g_source_new (&source_funcs, sizeof (GContextSpecificSource)); + css = (GContextSpecificSource *) source; + + g_source_set_name (source, name); + + g_mutex_init (&css->lock); + g_queue_init (&css->pending); + css->instance = instance; + + return css; +} + +static gboolean +g_context_specific_group_change_state (gpointer user_data) +{ + GContextSpecificGroup *group = user_data; + + g_mutex_lock (&group->lock); + + if (group->requested_state != group->effective_state) + { + (* group->requested_func) (); + + group->effective_state = group->requested_state; + group->requested_func = NULL; + + g_cond_broadcast (&group->cond); + } + + g_mutex_unlock (&group->lock); + + return FALSE; +} + +/* this is not the most elegant way to deal with this, but it's probably + * the best. there are only two other things we could do, really: + * + * - run the start function (but not the stop function) from the user's + * thread under some sort of lock. we don't run the stop function + * from the user's thread to avoid the destroy-while-emitting problem + * + * - have some check-and-compare functionality similar to what + * gsettings does where we send an artificial event in case we notice + * a change during the potential race period (using stat, for + * example) + */ +static void +g_context_specific_group_request_state (GContextSpecificGroup *group, + gboolean requested_state, + GCallback requested_func) +{ + if (requested_state != group->requested_state) + { + if (group->effective_state != group->requested_state) + { + /* abort the currently pending state transition */ + g_assert (group->effective_state == requested_state); + + group->requested_state = requested_state; + group->requested_func = NULL; + } + else + { + /* start a new state transition */ + group->requested_state = requested_state; + group->requested_func = requested_func; + + g_main_context_invoke (GLIB_PRIVATE_CALL(g_get_worker_context) (), + g_context_specific_group_change_state, group); + } + } + + /* we only block for positive transitions */ + if (requested_state) + { + while (group->requested_state != group->effective_state) + g_cond_wait (&group->cond, &group->lock); + + /* there is no way this could go back to FALSE because the object + * that we just created in this thread would have to have been + * destroyed again (from this thread) before that could happen. + */ + g_assert (group->effective_state); + } +} + +gpointer +g_context_specific_group_get (GContextSpecificGroup *group, + GType type, + goffset context_offset, + GCallback start_func) +{ + GContextSpecificSource *css; + GMainContext *context; + + context = g_main_context_get_thread_default (); + if (!context) + context = g_main_context_default (); + + g_mutex_lock (&group->lock); + + if (!group->table) + group->table = g_hash_table_new (NULL, NULL); + + css = g_hash_table_lookup (group->table, context); + + if (!css) + { + gpointer instance; + + instance = g_object_new (type, NULL); + css = g_context_specific_source_new (g_type_name (type), instance); + G_STRUCT_MEMBER (GMainContext *, instance, context_offset) = g_main_context_ref (context); + g_source_attach ((GSource *) css, context); + + g_hash_table_insert (group->table, context, css); + } + else + g_object_ref (css->instance); + + if (start_func) + g_context_specific_group_request_state (group, TRUE, start_func); + + g_mutex_unlock (&group->lock); + + return css->instance; +} + +void +g_context_specific_group_remove (GContextSpecificGroup *group, + GMainContext *context, + gpointer instance, + GCallback stop_func) +{ + GContextSpecificSource *css; + + if (!context) + { + g_critical ("Removing %s with NULL context. This object was probably directly constructed from a " + "dynamic language. This is not a valid use of the API.", G_OBJECT_TYPE_NAME (instance)); + return; + } + + g_mutex_lock (&group->lock); + css = g_hash_table_lookup (group->table, context); + g_hash_table_remove (group->table, context); + g_assert (css); + + /* stop only if we were the last one */ + if (stop_func && g_hash_table_size (group->table) == 0) + g_context_specific_group_request_state (group, FALSE, stop_func); + + g_mutex_unlock (&group->lock); + + g_assert (css->instance == instance); + + g_source_destroy ((GSource *) css); + g_source_unref ((GSource *) css); + g_main_context_unref (context); +} + +void +g_context_specific_group_emit (GContextSpecificGroup *group, + guint signal_id) +{ + g_mutex_lock (&group->lock); + + if (group->table) + { + GHashTableIter iter; + gpointer value; + gpointer ptr; + + ptr = GUINT_TO_POINTER (signal_id); + + g_hash_table_iter_init (&iter, group->table); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + GContextSpecificSource *css = value; + + g_mutex_lock (&css->lock); + + g_queue_remove (&css->pending, ptr); + g_queue_push_tail (&css->pending, ptr); + + g_source_set_ready_time ((GSource *) css, 0); + + g_mutex_unlock (&css->lock); + } + } + + g_mutex_unlock (&group->lock); +} diff --git a/gio/gcontextspecificgroup.h b/gio/gcontextspecificgroup.h new file mode 100644 index 0000000..74d22a4 --- /dev/null +++ b/gio/gcontextspecificgroup.h @@ -0,0 +1,51 @@ +/* + * Copyright © 2015 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_CONTEXT_SPECIFIC_GROUP_H__ +#define __G_CONTEXT_SPECIFIC_GROUP_H__ + +#include + +typedef struct +{ + GHashTable *table; + GMutex lock; + GCond cond; + gboolean requested_state; + GCallback requested_func; + gboolean effective_state; +} GContextSpecificGroup; + +gpointer +g_context_specific_group_get (GContextSpecificGroup *group, + GType type, + goffset context_offset, + GCallback start_func); + +void +g_context_specific_group_remove (GContextSpecificGroup *group, + GMainContext *context, + gpointer instance, + GCallback stop_func); + +void +g_context_specific_group_emit (GContextSpecificGroup *group, + guint signal_id); + +#endif /* __G_CONTEXT_SPECIFIC_GROUP_H__ */ diff --git a/gio/gconverter.c b/gio/gconverter.c new file mode 100644 index 0000000..7e5d308 --- /dev/null +++ b/gio/gconverter.c @@ -0,0 +1,201 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "gconverter.h" +#include "glibintl.h" + + +/** + * SECTION:gconverter + * @short_description: Data conversion interface + * @include: gio/gio.h + * @see_also: #GInputStream, #GOutputStream + * + * #GConverter is implemented by objects that convert + * binary data in various ways. The conversion can be + * stateful and may fail at any place. + * + * Some example conversions are: character set conversion, + * compression, decompression and regular expression + * replace. + * + * Since: 2.24 + **/ + + +typedef GConverterIface GConverterInterface; +G_DEFINE_INTERFACE (GConverter, g_converter, G_TYPE_OBJECT) + +static void +g_converter_default_init (GConverterInterface *iface) +{ +} + +/** + * g_converter_convert: + * @converter: a #GConverter. + * @inbuf: (array length=inbuf_size) (element-type guint8): the buffer + * containing the data to convert. + * @inbuf_size: the number of bytes in @inbuf + * @outbuf: (element-type guint8) (array length=outbuf_size): a buffer to write + * converted data in. + * @outbuf_size: the number of bytes in @outbuf, must be at least one + * @flags: a #GConverterFlags controlling the conversion details + * @bytes_read: (out): will be set to the number of bytes read from @inbuf on success + * @bytes_written: (out): will be set to the number of bytes written to @outbuf on success + * @error: location to store the error occurring, or %NULL to ignore + * + * This is the main operation used when converting data. It is to be called + * multiple times in a loop, and each time it will do some work, i.e. + * producing some output (in @outbuf) or consuming some input (from @inbuf) or + * both. If its not possible to do any work an error is returned. + * + * Note that a single call may not consume all input (or any input at all). + * Also a call may produce output even if given no input, due to state stored + * in the converter producing output. + * + * If any data was either produced or consumed, and then an error happens, then + * only the successful conversion is reported and the error is returned on the + * next call. + * + * A full conversion loop involves calling this method repeatedly, each time + * giving it new input and space output space. When there is no more input + * data after the data in @inbuf, the flag %G_CONVERTER_INPUT_AT_END must be set. + * The loop will be (unless some error happens) returning %G_CONVERTER_CONVERTED + * each time until all data is consumed and all output is produced, then + * %G_CONVERTER_FINISHED is returned instead. Note, that %G_CONVERTER_FINISHED + * may be returned even if %G_CONVERTER_INPUT_AT_END is not set, for instance + * in a decompression converter where the end of data is detectable from the + * data (and there might even be other data after the end of the compressed data). + * + * When some data has successfully been converted @bytes_read and is set to + * the number of bytes read from @inbuf, and @bytes_written is set to indicate + * how many bytes was written to @outbuf. If there are more data to output + * or consume (i.e. unless the %G_CONVERTER_INPUT_AT_END is specified) then + * %G_CONVERTER_CONVERTED is returned, and if no more data is to be output + * then %G_CONVERTER_FINISHED is returned. + * + * On error %G_CONVERTER_ERROR is returned and @error is set accordingly. + * Some errors need special handling: + * + * %G_IO_ERROR_NO_SPACE is returned if there is not enough space + * to write the resulting converted data, the application should + * call the function again with a larger @outbuf to continue. + * + * %G_IO_ERROR_PARTIAL_INPUT is returned if there is not enough + * input to fully determine what the conversion should produce, + * and the %G_CONVERTER_INPUT_AT_END flag is not set. This happens for + * example with an incomplete multibyte sequence when converting text, + * or when a regexp matches up to the end of the input (and may match + * further input). It may also happen when @inbuf_size is zero and + * there is no more data to produce. + * + * When this happens the application should read more input and then + * call the function again. If further input shows that there is no + * more data call the function again with the same data but with + * the %G_CONVERTER_INPUT_AT_END flag set. This may cause the conversion + * to finish as e.g. in the regexp match case (or, to fail again with + * %G_IO_ERROR_PARTIAL_INPUT in e.g. a charset conversion where the + * input is actually partial). + * + * After g_converter_convert() has returned %G_CONVERTER_FINISHED the + * converter object is in an invalid state where its not allowed + * to call g_converter_convert() anymore. At this time you can only + * free the object or call g_converter_reset() to reset it to the + * initial state. + * + * If the flag %G_CONVERTER_FLUSH is set then conversion is modified + * to try to write out all internal state to the output. The application + * has to call the function multiple times with the flag set, and when + * the available input has been consumed and all internal state has + * been produced then %G_CONVERTER_FLUSHED (or %G_CONVERTER_FINISHED if + * really at the end) is returned instead of %G_CONVERTER_CONVERTED. + * This is somewhat similar to what happens at the end of the input stream, + * but done in the middle of the data. + * + * This has different meanings for different conversions. For instance + * in a compression converter it would mean that we flush all the + * compression state into output such that if you uncompress the + * compressed data you get back all the input data. Doing this may + * make the final file larger due to padding though. Another example + * is a regexp conversion, where if you at the end of the flushed data + * have a match, but there is also a potential longer match. In the + * non-flushed case we would ask for more input, but when flushing we + * treat this as the end of input and do the match. + * + * Flushing is not always possible (like if a charset converter flushes + * at a partial multibyte sequence). Converters are supposed to try + * to produce as much output as possible and then return an error + * (typically %G_IO_ERROR_PARTIAL_INPUT). + * + * Returns: a #GConverterResult, %G_CONVERTER_ERROR on error. + * + * Since: 2.24 + **/ +GConverterResult +g_converter_convert (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + GConverterIface *iface; + + g_return_val_if_fail (G_IS_CONVERTER (converter), G_CONVERTER_ERROR); + g_return_val_if_fail (outbuf_size > 0, G_CONVERTER_ERROR); + + *bytes_read = 0; + *bytes_written = 0; + + iface = G_CONVERTER_GET_IFACE (converter); + + return (* iface->convert) (converter, + inbuf, inbuf_size, + outbuf, outbuf_size, + flags, + bytes_read, bytes_written, error); +} + +/** + * g_converter_reset: + * @converter: a #GConverter. + * + * Resets all internal state in the converter, making it behave + * as if it was just created. If the converter has any internal + * state that would produce output then that output is lost. + * + * Since: 2.24 + **/ +void +g_converter_reset (GConverter *converter) +{ + GConverterIface *iface; + + g_return_if_fail (G_IS_CONVERTER (converter)); + + iface = G_CONVERTER_GET_IFACE (converter); + + (* iface->reset) (converter); +} diff --git a/gio/gconverter.h b/gio/gconverter.h new file mode 100644 index 0000000..8716453 --- /dev/null +++ b/gio/gconverter.h @@ -0,0 +1,96 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_CONVERTER_H__ +#define __G_CONVERTER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_CONVERTER (g_converter_get_type ()) +#define G_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_CONVERTER, GConverter)) +#define G_IS_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_CONVERTER)) +#define G_CONVERTER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_CONVERTER, GConverterIface)) + +/** + * GConverter: + * + * Seek object for streaming operations. + * + * Since: 2.24 + **/ +typedef struct _GConverterIface GConverterIface; + +/** + * GConverterIface: + * @g_iface: The parent interface. + * @convert: Converts data. + * @reset: Reverts the internal state of the converter to its initial state. + * + * Provides an interface for converting data from one type + * to another type. The conversion can be stateful + * and may fail at any place. + * + * Since: 2.24 + **/ +struct _GConverterIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + GConverterResult (* convert) (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error); + void (* reset) (GConverter *converter); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_converter_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GConverterResult g_converter_convert (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_converter_reset (GConverter *converter); + + +G_END_DECLS + + +#endif /* __G_CONVERTER_H__ */ diff --git a/gio/gconverterinputstream.c b/gio/gconverterinputstream.c new file mode 100644 index 0000000..dd84b34 --- /dev/null +++ b/gio/gconverterinputstream.c @@ -0,0 +1,651 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "gconverterinputstream.h" +#include "gpollableinputstream.h" +#include "gcancellable.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gconverterinputstream + * @short_description: Converter Input Stream + * @include: gio/gio.h + * @see_also: #GInputStream, #GConverter + * + * Converter input stream implements #GInputStream and allows + * conversion of data of various types during reading. + * + * As of GLib 2.34, #GConverterInputStream implements + * #GPollableInputStream. + **/ + +#define INITIAL_BUFFER_SIZE 4096 + +typedef struct { + char *data; + gsize start; + gsize end; + gsize size; +} Buffer; + +struct _GConverterInputStreamPrivate { + gboolean at_input_end; + gboolean finished; + gboolean need_input; + GConverter *converter; + Buffer input_buffer; + Buffer converted_buffer; +}; + +enum { + PROP_0, + PROP_CONVERTER +}; + +static void g_converter_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_converter_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void g_converter_input_stream_finalize (GObject *object); +static gssize g_converter_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); + +static gboolean g_converter_input_stream_can_poll (GPollableInputStream *stream); +static gboolean g_converter_input_stream_is_readable (GPollableInputStream *stream); +static gssize g_converter_input_stream_read_nonblocking (GPollableInputStream *stream, + void *buffer, + gsize size, + GError **error); + +static GSource *g_converter_input_stream_create_source (GPollableInputStream *stream, + GCancellable *cancellable); + +static void g_converter_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GConverterInputStream, + g_converter_input_stream, + G_TYPE_FILTER_INPUT_STREAM, + G_ADD_PRIVATE (GConverterInputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, + g_converter_input_stream_pollable_iface_init)) + +static void +g_converter_input_stream_class_init (GConverterInputStreamClass *klass) +{ + GObjectClass *object_class; + GInputStreamClass *istream_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = g_converter_input_stream_get_property; + object_class->set_property = g_converter_input_stream_set_property; + object_class->finalize = g_converter_input_stream_finalize; + + istream_class = G_INPUT_STREAM_CLASS (klass); + istream_class->read_fn = g_converter_input_stream_read; + + g_object_class_install_property (object_class, + PROP_CONVERTER, + g_param_spec_object ("converter", + P_("Converter"), + P_("The converter object"), + G_TYPE_CONVERTER, + G_PARAM_READWRITE| + G_PARAM_CONSTRUCT_ONLY| + G_PARAM_STATIC_STRINGS)); + +} + +static void +g_converter_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface) +{ + iface->can_poll = g_converter_input_stream_can_poll; + iface->is_readable = g_converter_input_stream_is_readable; + iface->read_nonblocking = g_converter_input_stream_read_nonblocking; + iface->create_source = g_converter_input_stream_create_source; +} + +static void +g_converter_input_stream_finalize (GObject *object) +{ + GConverterInputStreamPrivate *priv; + GConverterInputStream *stream; + + stream = G_CONVERTER_INPUT_STREAM (object); + priv = stream->priv; + + g_free (priv->input_buffer.data); + g_free (priv->converted_buffer.data); + if (priv->converter) + g_object_unref (priv->converter); + + G_OBJECT_CLASS (g_converter_input_stream_parent_class)->finalize (object); +} + +static void +g_converter_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GConverterInputStream *cstream; + + cstream = G_CONVERTER_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_CONVERTER: + cstream->priv->converter = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_converter_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GConverterInputStreamPrivate *priv; + GConverterInputStream *cstream; + + cstream = G_CONVERTER_INPUT_STREAM (object); + priv = cstream->priv; + + switch (prop_id) + { + case PROP_CONVERTER: + g_value_set_object (value, priv->converter); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} +static void +g_converter_input_stream_init (GConverterInputStream *stream) +{ + stream->priv = g_converter_input_stream_get_instance_private (stream); +} + +/** + * g_converter_input_stream_new: + * @base_stream: a #GInputStream + * @converter: a #GConverter + * + * Creates a new converter input stream for the @base_stream. + * + * Returns: a new #GInputStream. + **/ +GInputStream * +g_converter_input_stream_new (GInputStream *base_stream, + GConverter *converter) +{ + GInputStream *stream; + + g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL); + + stream = g_object_new (G_TYPE_CONVERTER_INPUT_STREAM, + "base-stream", base_stream, + "converter", converter, + NULL); + + return stream; +} + +static gsize +buffer_data_size (Buffer *buffer) +{ + return buffer->end - buffer->start; +} + +static gsize +buffer_tailspace (Buffer *buffer) +{ + return buffer->size - buffer->end; +} + +static char * +buffer_data (Buffer *buffer) +{ + return buffer->data + buffer->start; +} + +static void +buffer_consumed (Buffer *buffer, + gsize count) +{ + buffer->start += count; + if (buffer->start == buffer->end) + buffer->start = buffer->end = 0; +} + +static void +buffer_read (Buffer *buffer, + char *dest, + gsize count) +{ + if (count != 0) + memcpy (dest, buffer->data + buffer->start, count); + + buffer_consumed (buffer, count); +} + +static void +compact_buffer (Buffer *buffer) +{ + gsize in_buffer; + + in_buffer = buffer_data_size (buffer); + memmove (buffer->data, + buffer->data + buffer->start, + in_buffer); + buffer->end -= buffer->start; + buffer->start = 0; +} + +static void +grow_buffer (Buffer *buffer) +{ + char *data; + gsize size, in_buffer; + + if (buffer->size == 0) + size = INITIAL_BUFFER_SIZE; + else + size = buffer->size * 2; + + data = g_malloc (size); + in_buffer = buffer_data_size (buffer); + + if (in_buffer != 0) + memcpy (data, + buffer->data + buffer->start, + in_buffer); + + g_free (buffer->data); + buffer->data = data; + buffer->end -= buffer->start; + buffer->start = 0; + buffer->size = size; +} + +/* Ensures that the buffer can fit at_least_size bytes, + * *including* the current in-buffer data */ +static void +buffer_ensure_space (Buffer *buffer, + gsize at_least_size) +{ + gsize in_buffer, left_to_fill; + + in_buffer = buffer_data_size (buffer); + + if (in_buffer >= at_least_size) + return; + + left_to_fill = buffer_tailspace (buffer); + + if (in_buffer + left_to_fill >= at_least_size) + { + /* We fit in remaining space at end */ + /* If the copy is small, compact now anyway so we can fill more */ + if (in_buffer < 256) + compact_buffer (buffer); + } + else if (buffer->size >= at_least_size) + { + /* We fit, but only if we compact */ + compact_buffer (buffer); + } + else + { + /* Need to grow buffer */ + while (buffer->size < at_least_size) + grow_buffer (buffer); + } +} + +static gssize +fill_input_buffer (GConverterInputStream *stream, + gsize at_least_size, + gboolean blocking, + GCancellable *cancellable, + GError **error) +{ + GConverterInputStreamPrivate *priv; + GInputStream *base_stream; + gssize nread; + + priv = stream->priv; + + buffer_ensure_space (&priv->input_buffer, at_least_size); + + base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + nread = g_pollable_stream_read (base_stream, + priv->input_buffer.data + priv->input_buffer.end, + buffer_tailspace (&priv->input_buffer), + blocking, + cancellable, + error); + + if (nread > 0) + { + priv->input_buffer.end += nread; + priv->need_input = FALSE; + } + + return nread; +} + + +static gssize +read_internal (GInputStream *stream, + void *buffer, + gsize count, + gboolean blocking, + GCancellable *cancellable, + GError **error) +{ + GConverterInputStream *cstream; + GConverterInputStreamPrivate *priv; + gsize available, total_bytes_read; + gssize nread; + GConverterResult res; + gsize bytes_read; + gsize bytes_written; + GError *my_error; + GError *my_error2; + + cstream = G_CONVERTER_INPUT_STREAM (stream); + priv = cstream->priv; + + available = buffer_data_size (&priv->converted_buffer); + + if (available > 0 && + count <= available) + { + /* Converted data available, return that */ + buffer_read (&priv->converted_buffer, buffer, count); + return count; + } + + /* Full request not available, read all currently available and request + refill/conversion for more */ + + buffer_read (&priv->converted_buffer, buffer, available); + + total_bytes_read = available; + buffer = (char *) buffer + available; + count -= available; + + /* If there is no data to convert, and no pre-converted data, + do some i/o for more input */ + if (buffer_data_size (&priv->input_buffer) == 0 && + total_bytes_read == 0 && + !priv->at_input_end) + { + nread = fill_input_buffer (cstream, count, blocking, cancellable, error); + if (nread < 0) + return -1; + if (nread == 0) + priv->at_input_end = TRUE; + } + + /* First try to convert any available data (or state) directly to the user buffer: */ + if (!priv->finished) + { + my_error = NULL; + res = g_converter_convert (priv->converter, + buffer_data (&priv->input_buffer), + buffer_data_size (&priv->input_buffer), + buffer, count, + priv->at_input_end ? G_CONVERTER_INPUT_AT_END : 0, + &bytes_read, + &bytes_written, + &my_error); + if (res != G_CONVERTER_ERROR) + { + total_bytes_read += bytes_written; + buffer_consumed (&priv->input_buffer, bytes_read); + if (res == G_CONVERTER_FINISHED) + priv->finished = TRUE; /* We're done converting */ + } + else if (total_bytes_read == 0 && + !g_error_matches (my_error, + G_IO_ERROR, + G_IO_ERROR_PARTIAL_INPUT) && + !g_error_matches (my_error, + G_IO_ERROR, + G_IO_ERROR_NO_SPACE)) + { + /* No previously read data and no "special" error, return error */ + g_propagate_error (error, my_error); + return -1; + } + else + g_error_free (my_error); + } + + /* We had some pre-converted data and/or we converted directly to the + user buffer */ + if (total_bytes_read > 0) + return total_bytes_read; + + /* If there is no more to convert, return EOF */ + if (priv->finished) + { + g_assert (buffer_data_size (&priv->converted_buffer) == 0); + return 0; + } + + /* There was "complexity" in the straight-to-buffer conversion, + * convert to our own buffer and write from that. + * At this point we didn't produce any data into @buffer. + */ + + /* Ensure we have *some* initial target space */ + buffer_ensure_space (&priv->converted_buffer, count); + + while (TRUE) + { + g_assert (!priv->finished); + + /* Try to convert to our buffer */ + my_error = NULL; + res = g_converter_convert (priv->converter, + buffer_data (&priv->input_buffer), + buffer_data_size (&priv->input_buffer), + buffer_data (&priv->converted_buffer), + buffer_tailspace (&priv->converted_buffer), + priv->at_input_end ? G_CONVERTER_INPUT_AT_END : 0, + &bytes_read, + &bytes_written, + &my_error); + if (res != G_CONVERTER_ERROR) + { + priv->converted_buffer.end += bytes_written; + buffer_consumed (&priv->input_buffer, bytes_read); + + /* Maybe we consumed without producing any output */ + if (buffer_data_size (&priv->converted_buffer) == 0 && res != G_CONVERTER_FINISHED) + continue; /* Convert more */ + + if (res == G_CONVERTER_FINISHED) + priv->finished = TRUE; + + total_bytes_read = MIN (count, buffer_data_size (&priv->converted_buffer)); + buffer_read (&priv->converted_buffer, buffer, total_bytes_read); + + g_assert (priv->finished || total_bytes_read > 0); + + return total_bytes_read; + } + + /* There was some kind of error filling our buffer */ + + if (g_error_matches (my_error, + G_IO_ERROR, + G_IO_ERROR_PARTIAL_INPUT) && + !priv->at_input_end) + { + /* Need more data */ + my_error2 = NULL; + nread = fill_input_buffer (cstream, + buffer_data_size (&priv->input_buffer) + 4096, + blocking, + cancellable, + &my_error2); + if (nread < 0) + { + /* Can't read any more data, return that error */ + g_error_free (my_error); + g_propagate_error (error, my_error2); + priv->need_input = TRUE; + return -1; + } + else if (nread == 0) + { + /* End of file, try INPUT_AT_END */ + priv->at_input_end = TRUE; + } + g_error_free (my_error); + continue; + } + + if (g_error_matches (my_error, + G_IO_ERROR, + G_IO_ERROR_NO_SPACE)) + { + /* Need more destination space, grow it + * Note: if we actually grow the buffer (as opposed to compacting it), + * this will double the size, not just add one byte. */ + buffer_ensure_space (&priv->converted_buffer, + priv->converted_buffer.size + 1); + g_error_free (my_error); + continue; + } + + /* Any other random error, return it */ + g_propagate_error (error, my_error); + return -1; + } + + g_assert_not_reached (); +} + +static gssize +g_converter_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + return read_internal (stream, buffer, count, TRUE, cancellable, error); +} + +static gboolean +g_converter_input_stream_can_poll (GPollableInputStream *stream) +{ + GInputStream *base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + + return (G_IS_POLLABLE_INPUT_STREAM (base_stream) && + g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (base_stream))); +} + +static gboolean +g_converter_input_stream_is_readable (GPollableInputStream *stream) +{ + GInputStream *base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + GConverterInputStream *cstream = G_CONVERTER_INPUT_STREAM (stream); + + if (buffer_data_size (&cstream->priv->converted_buffer)) + return TRUE; + else if (buffer_data_size (&cstream->priv->input_buffer) && + !cstream->priv->need_input) + return TRUE; + else + return g_pollable_input_stream_is_readable (G_POLLABLE_INPUT_STREAM (base_stream)); +} + +static gssize +g_converter_input_stream_read_nonblocking (GPollableInputStream *stream, + void *buffer, + gsize count, + GError **error) +{ + return read_internal (G_INPUT_STREAM (stream), buffer, count, + FALSE, NULL, error); +} + +static GSource * +g_converter_input_stream_create_source (GPollableInputStream *stream, + GCancellable *cancellable) +{ + GInputStream *base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream; + GSource *base_source, *pollable_source; + + if (g_pollable_input_stream_is_readable (stream)) + base_source = g_timeout_source_new (0); + else + base_source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (base_stream), NULL); + + pollable_source = g_pollable_source_new_full (stream, base_source, + cancellable); + g_source_unref (base_source); + + return pollable_source; +} + + +/** + * g_converter_input_stream_get_converter: + * @converter_stream: a #GConverterInputStream + * + * Gets the #GConverter that is used by @converter_stream. + * + * Returns: (transfer none): the converter of the converter input stream + * + * Since: 2.24 + */ +GConverter * +g_converter_input_stream_get_converter (GConverterInputStream *converter_stream) +{ + return converter_stream->priv->converter; +} diff --git a/gio/gconverterinputstream.h b/gio/gconverterinputstream.h new file mode 100644 index 0000000..48cc102 --- /dev/null +++ b/gio/gconverterinputstream.h @@ -0,0 +1,80 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_CONVERTER_INPUT_STREAM_H__ +#define __G_CONVERTER_INPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_CONVERTER_INPUT_STREAM (g_converter_input_stream_get_type ()) +#define G_CONVERTER_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CONVERTER_INPUT_STREAM, GConverterInputStream)) +#define G_CONVERTER_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CONVERTER_INPUT_STREAM, GConverterInputStreamClass)) +#define G_IS_CONVERTER_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CONVERTER_INPUT_STREAM)) +#define G_IS_CONVERTER_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CONVERTER_INPUT_STREAM)) +#define G_CONVERTER_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CONVERTER_INPUT_STREAM, GConverterInputStreamClass)) + +/** + * GConverterInputStream: + * + * An implementation of #GFilterInputStream that allows data + * conversion. + **/ +typedef struct _GConverterInputStreamClass GConverterInputStreamClass; +typedef struct _GConverterInputStreamPrivate GConverterInputStreamPrivate; + +struct _GConverterInputStream +{ + GFilterInputStream parent_instance; + + /*< private >*/ + GConverterInputStreamPrivate *priv; +}; + +struct _GConverterInputStreamClass +{ + GFilterInputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_converter_input_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GInputStream *g_converter_input_stream_new (GInputStream *base_stream, + GConverter *converter); +GLIB_AVAILABLE_IN_ALL +GConverter *g_converter_input_stream_get_converter (GConverterInputStream *converter_stream); + +G_END_DECLS + +#endif /* __G_CONVERTER_INPUT_STREAM_H__ */ diff --git a/gio/gconverteroutputstream.c b/gio/gconverteroutputstream.c new file mode 100644 index 0000000..c1fa29e --- /dev/null +++ b/gio/gconverteroutputstream.c @@ -0,0 +1,689 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "gconverteroutputstream.h" +#include "gpollableoutputstream.h" +#include "gcancellable.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gconverteroutputstream + * @short_description: Converter Output Stream + * @include: gio/gio.h + * @see_also: #GOutputStream, #GConverter + * + * Converter output stream implements #GOutputStream and allows + * conversion of data of various types during reading. + * + * As of GLib 2.34, #GConverterOutputStream implements + * #GPollableOutputStream. + **/ + +#define INITIAL_BUFFER_SIZE 4096 + +typedef struct { + char *data; + gsize start; + gsize end; + gsize size; +} Buffer; + +struct _GConverterOutputStreamPrivate { + gboolean at_output_end; + gboolean finished; + GConverter *converter; + Buffer output_buffer; /* To be converted and written */ + Buffer converted_buffer; /* Already converted */ +}; + +/* Buffering strategy: + * + * Each time we write we must at least consume some input, or + * return an error. Thus we start with writing all already + * converted data and *then* we start converting (reporting + * an error at any point in this). + * + * Its possible that what the user wrote is not enough data + * for the converter, so we must then buffer it in output_buffer + * and ask for more data, but we want to avoid this as much as + * possible, converting directly from the users buffer. + */ + +enum { + PROP_0, + PROP_CONVERTER +}; + +static void g_converter_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_converter_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void g_converter_output_stream_finalize (GObject *object); +static gssize g_converter_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_converter_output_stream_flush (GOutputStream *stream, + GCancellable *cancellable, + GError **error); + +static gboolean g_converter_output_stream_can_poll (GPollableOutputStream *stream); +static gboolean g_converter_output_stream_is_writable (GPollableOutputStream *stream); +static gssize g_converter_output_stream_write_nonblocking (GPollableOutputStream *stream, + const void *buffer, + gsize size, + GError **error); + +static GSource *g_converter_output_stream_create_source (GPollableOutputStream *stream, + GCancellable *cancellable); + +static void g_converter_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GConverterOutputStream, + g_converter_output_stream, + G_TYPE_FILTER_OUTPUT_STREAM, + G_ADD_PRIVATE (GConverterOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, + g_converter_output_stream_pollable_iface_init)) + +static void +g_converter_output_stream_class_init (GConverterOutputStreamClass *klass) +{ + GObjectClass *object_class; + GOutputStreamClass *istream_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = g_converter_output_stream_get_property; + object_class->set_property = g_converter_output_stream_set_property; + object_class->finalize = g_converter_output_stream_finalize; + + istream_class = G_OUTPUT_STREAM_CLASS (klass); + istream_class->write_fn = g_converter_output_stream_write; + istream_class->flush = g_converter_output_stream_flush; + + g_object_class_install_property (object_class, + PROP_CONVERTER, + g_param_spec_object ("converter", + P_("Converter"), + P_("The converter object"), + G_TYPE_CONVERTER, + G_PARAM_READWRITE| + G_PARAM_CONSTRUCT_ONLY| + G_PARAM_STATIC_STRINGS)); + +} + +static void +g_converter_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface) +{ + iface->can_poll = g_converter_output_stream_can_poll; + iface->is_writable = g_converter_output_stream_is_writable; + iface->write_nonblocking = g_converter_output_stream_write_nonblocking; + iface->create_source = g_converter_output_stream_create_source; +} + +static void +g_converter_output_stream_finalize (GObject *object) +{ + GConverterOutputStreamPrivate *priv; + GConverterOutputStream *stream; + + stream = G_CONVERTER_OUTPUT_STREAM (object); + priv = stream->priv; + + g_free (priv->output_buffer.data); + g_free (priv->converted_buffer.data); + if (priv->converter) + g_object_unref (priv->converter); + + G_OBJECT_CLASS (g_converter_output_stream_parent_class)->finalize (object); +} + +static void +g_converter_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GConverterOutputStream *cstream; + + cstream = G_CONVERTER_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_CONVERTER: + cstream->priv->converter = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_converter_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GConverterOutputStreamPrivate *priv; + GConverterOutputStream *cstream; + + cstream = G_CONVERTER_OUTPUT_STREAM (object); + priv = cstream->priv; + + switch (prop_id) + { + case PROP_CONVERTER: + g_value_set_object (value, priv->converter); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_converter_output_stream_init (GConverterOutputStream *stream) +{ + stream->priv = g_converter_output_stream_get_instance_private (stream); +} + +/** + * g_converter_output_stream_new: + * @base_stream: a #GOutputStream + * @converter: a #GConverter + * + * Creates a new converter output stream for the @base_stream. + * + * Returns: a new #GOutputStream. + **/ +GOutputStream * +g_converter_output_stream_new (GOutputStream *base_stream, + GConverter *converter) +{ + GOutputStream *stream; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL); + + stream = g_object_new (G_TYPE_CONVERTER_OUTPUT_STREAM, + "base-stream", base_stream, + "converter", converter, + NULL); + + return stream; +} + +static gsize +buffer_data_size (Buffer *buffer) +{ + return buffer->end - buffer->start; +} + +static gsize +buffer_tailspace (Buffer *buffer) +{ + return buffer->size - buffer->end; +} + +static char * +buffer_data (Buffer *buffer) +{ + return buffer->data + buffer->start; +} + +static void +buffer_consumed (Buffer *buffer, + gsize count) +{ + buffer->start += count; + if (buffer->start == buffer->end) + buffer->start = buffer->end = 0; +} + +static void +compact_buffer (Buffer *buffer) +{ + gsize in_buffer; + + in_buffer = buffer_data_size (buffer); + memmove (buffer->data, + buffer->data + buffer->start, + in_buffer); + buffer->end -= buffer->start; + buffer->start = 0; +} + +static void +grow_buffer (Buffer *buffer) +{ + char *data; + gsize size, in_buffer; + + if (buffer->size == 0) + size = INITIAL_BUFFER_SIZE; + else + size = buffer->size * 2; + + data = g_malloc (size); + in_buffer = buffer_data_size (buffer); + + if (in_buffer != 0) + memcpy (data, + buffer->data + buffer->start, + in_buffer); + + g_free (buffer->data); + buffer->data = data; + buffer->end -= buffer->start; + buffer->start = 0; + buffer->size = size; +} + +/* Ensures that the buffer can fit at_least_size bytes, + * *including* the current in-buffer data */ +static void +buffer_ensure_space (Buffer *buffer, + gsize at_least_size) +{ + gsize in_buffer, left_to_fill; + + in_buffer = buffer_data_size (buffer); + + if (in_buffer >= at_least_size) + return; + + left_to_fill = buffer_tailspace (buffer); + + if (in_buffer + left_to_fill >= at_least_size) + { + /* We fit in remaining space at end */ + /* If the copy is small, compact now anyway so we can fill more */ + if (in_buffer < 256) + compact_buffer (buffer); + } + else if (buffer->size >= at_least_size) + { + /* We fit, but only if we compact */ + compact_buffer (buffer); + } + else + { + /* Need to grow buffer */ + while (buffer->size < at_least_size) + grow_buffer (buffer); + } +} + +static void +buffer_append (Buffer *buffer, + const char *data, + gsize data_size) +{ + buffer_ensure_space (buffer, + buffer_data_size (buffer) + data_size); + memcpy (buffer->data + buffer->end, data, data_size); + buffer->end += data_size; +} + + +static gboolean +flush_buffer (GConverterOutputStream *stream, + gboolean blocking, + GCancellable *cancellable, + GError **error) +{ + GConverterOutputStreamPrivate *priv; + GOutputStream *base_stream; + gsize nwritten; + gsize available; + gboolean res; + + priv = stream->priv; + + base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream; + + available = buffer_data_size (&priv->converted_buffer); + if (available > 0) + { + res = g_pollable_stream_write_all (base_stream, + buffer_data (&priv->converted_buffer), + available, + blocking, + &nwritten, + cancellable, + error); + buffer_consumed (&priv->converted_buffer, nwritten); + return res; + } + return TRUE; +} + + +static gssize +write_internal (GOutputStream *stream, + const void *buffer, + gsize count, + gboolean blocking, + GCancellable *cancellable, + GError **error) +{ + GConverterOutputStream *cstream; + GConverterOutputStreamPrivate *priv; + gssize retval; + GConverterResult res; + gsize bytes_read; + gsize bytes_written; + GError *my_error; + const char *to_convert; + gsize to_convert_size, converted_bytes; + gboolean converting_from_buffer; + + cstream = G_CONVERTER_OUTPUT_STREAM (stream); + priv = cstream->priv; + + /* Write out all available pre-converted data and fail if + not possible */ + if (!flush_buffer (cstream, blocking, cancellable, error)) + return -1; + + if (priv->finished) + return 0; + + /* Convert as much as possible */ + if (buffer_data_size (&priv->output_buffer) > 0) + { + converting_from_buffer = TRUE; + buffer_append (&priv->output_buffer, buffer, count); + to_convert = buffer_data (&priv->output_buffer); + to_convert_size = buffer_data_size (&priv->output_buffer); + } + else + { + converting_from_buffer = FALSE; + to_convert = buffer; + to_convert_size = count; + } + + /* Ensure we have *some* initial target space */ + buffer_ensure_space (&priv->converted_buffer, to_convert_size); + + converted_bytes = 0; + while (!priv->finished && converted_bytes < to_convert_size) + { + /* Ensure we have *some* target space */ + if (buffer_tailspace (&priv->converted_buffer) == 0) + grow_buffer (&priv->converted_buffer); + + /* Try to convert to our buffer */ + my_error = NULL; + res = g_converter_convert (priv->converter, + to_convert + converted_bytes, + to_convert_size - converted_bytes, + buffer_data (&priv->converted_buffer) + buffer_data_size (&priv->converted_buffer), + buffer_tailspace (&priv->converted_buffer), + 0, + &bytes_read, + &bytes_written, + &my_error); + + if (res != G_CONVERTER_ERROR) + { + priv->converted_buffer.end += bytes_written; + converted_bytes += bytes_read; + + if (res == G_CONVERTER_FINISHED) + priv->finished = TRUE; + } + else + { + /* No-space errors can be handled locally: */ + if (g_error_matches (my_error, + G_IO_ERROR, + G_IO_ERROR_NO_SPACE)) + { + /* Need more destination space, grow it + * Note: if we actually grow the buffer (as opposed to compacting it), + * this will double the size, not just add one byte. */ + buffer_ensure_space (&priv->converted_buffer, + priv->converted_buffer.size + 1); + g_error_free (my_error); + continue; + } + + if (converted_bytes > 0) + { + /* We got a conversion error, but we did convert some bytes before + that, so handle those before reporting the error */ + g_error_free (my_error); + break; + } + + if (g_error_matches (my_error, + G_IO_ERROR, + G_IO_ERROR_PARTIAL_INPUT)) + { + /* Consume everything to buffer that we append to next time + we write */ + if (!converting_from_buffer) + buffer_append (&priv->output_buffer, buffer, count); + /* in the converting_from_buffer case we already appended this */ + + g_error_free (my_error); + return count; /* consume everything */ + } + + /* Converted no data and got a normal error, return it */ + g_propagate_error (error, my_error); + return -1; + } + } + + if (converting_from_buffer) + { + buffer_consumed (&priv->output_buffer, converted_bytes); + retval = count; + } + else + retval = converted_bytes; + + /* We now successfully consumed retval bytes, so we can't return an error, + even if writing this to the base stream fails. If it does we'll just + stop early and report this error when we try again on the next + write call. */ + flush_buffer (cstream, blocking, cancellable, NULL); + + return retval; +} + +static gssize +g_converter_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + return write_internal (stream, buffer, count, TRUE, cancellable, error); +} + +static gboolean +g_converter_output_stream_flush (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GConverterOutputStream *cstream; + GConverterOutputStreamPrivate *priv; + GConverterResult res; + GError *my_error; + gboolean is_closing; + gboolean flushed; + gsize bytes_read; + gsize bytes_written; + + cstream = G_CONVERTER_OUTPUT_STREAM (stream); + priv = cstream->priv; + + is_closing = g_output_stream_is_closing (stream); + + /* Write out all available pre-converted data and fail if + not possible */ + if (!flush_buffer (cstream, TRUE, cancellable, error)) + return FALSE; + + /* Ensure we have *some* initial target space */ + buffer_ensure_space (&priv->converted_buffer, 1); + + /* Convert whole buffer */ + flushed = FALSE; + while (!priv->finished && !flushed) + { + /* Ensure we have *some* target space */ + if (buffer_tailspace (&priv->converted_buffer) == 0) + grow_buffer (&priv->converted_buffer); + + /* Try to convert to our buffer */ + my_error = NULL; + res = g_converter_convert (priv->converter, + buffer_data (&priv->output_buffer), + buffer_data_size (&priv->output_buffer), + buffer_data (&priv->converted_buffer) + buffer_data_size (&priv->converted_buffer), + buffer_tailspace (&priv->converted_buffer), + is_closing ? G_CONVERTER_INPUT_AT_END : G_CONVERTER_FLUSH, + &bytes_read, + &bytes_written, + &my_error); + + if (res != G_CONVERTER_ERROR) + { + priv->converted_buffer.end += bytes_written; + buffer_consumed (&priv->output_buffer, bytes_read); + + if (res == G_CONVERTER_FINISHED) + priv->finished = TRUE; + if (!is_closing && + res == G_CONVERTER_FLUSHED) + { + /* Should not have returned FLUSHED with input left */ + g_assert (buffer_data_size (&priv->output_buffer) == 0); + flushed = TRUE; + } + } + else + { + /* No-space errors can be handled locally: */ + if (g_error_matches (my_error, + G_IO_ERROR, + G_IO_ERROR_NO_SPACE)) + { + /* Need more destination space, grow it + * Note: if we actually grow the buffer (as opposed to compacting it), + * this will double the size, not just add one byte. */ + buffer_ensure_space (&priv->converted_buffer, + priv->converted_buffer.size + 1); + g_error_free (my_error); + continue; + } + + /* Any other error, including PARTIAL_INPUT can't be fixed by now + and is an error */ + g_propagate_error (error, my_error); + return FALSE; + } + } + + /* Now write all converted data to base stream */ + if (!flush_buffer (cstream, TRUE, cancellable, error)) + return FALSE; + + return TRUE; +} + +static gboolean +g_converter_output_stream_can_poll (GPollableOutputStream *stream) +{ + GOutputStream *base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream; + + return (G_IS_POLLABLE_OUTPUT_STREAM (base_stream) && + g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (base_stream))); +} + +static gboolean +g_converter_output_stream_is_writable (GPollableOutputStream *stream) +{ + GOutputStream *base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream; + + return g_pollable_output_stream_is_writable (G_POLLABLE_OUTPUT_STREAM (base_stream)); +} + +static gssize +g_converter_output_stream_write_nonblocking (GPollableOutputStream *stream, + const void *buffer, + gsize count, + GError **error) +{ + return write_internal (G_OUTPUT_STREAM (stream), buffer, count, FALSE, + NULL, error); +} + +static GSource * +g_converter_output_stream_create_source (GPollableOutputStream *stream, + GCancellable *cancellable) +{ + GOutputStream *base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream; + GSource *base_source, *pollable_source; + + base_source = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (base_stream), NULL); + pollable_source = g_pollable_source_new_full (stream, base_source, + cancellable); + g_source_unref (base_source); + + return pollable_source; +} + +/** + * g_converter_output_stream_get_converter: + * @converter_stream: a #GConverterOutputStream + * + * Gets the #GConverter that is used by @converter_stream. + * + * Returns: (transfer none): the converter of the converter output stream + * + * Since: 2.24 + */ +GConverter * +g_converter_output_stream_get_converter (GConverterOutputStream *converter_stream) +{ + return converter_stream->priv->converter; +} diff --git a/gio/gconverteroutputstream.h b/gio/gconverteroutputstream.h new file mode 100644 index 0000000..b9a1e5d --- /dev/null +++ b/gio/gconverteroutputstream.h @@ -0,0 +1,80 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_CONVERTER_OUTPUT_STREAM_H__ +#define __G_CONVERTER_OUTPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_CONVERTER_OUTPUT_STREAM (g_converter_output_stream_get_type ()) +#define G_CONVERTER_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CONVERTER_OUTPUT_STREAM, GConverterOutputStream)) +#define G_CONVERTER_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CONVERTER_OUTPUT_STREAM, GConverterOutputStreamClass)) +#define G_IS_CONVERTER_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CONVERTER_OUTPUT_STREAM)) +#define G_IS_CONVERTER_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CONVERTER_OUTPUT_STREAM)) +#define G_CONVERTER_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CONVERTER_OUTPUT_STREAM, GConverterOutputStreamClass)) + +/** + * GConverterOutputStream: + * + * An implementation of #GFilterOutputStream that allows data + * conversion. + **/ +typedef struct _GConverterOutputStreamClass GConverterOutputStreamClass; +typedef struct _GConverterOutputStreamPrivate GConverterOutputStreamPrivate; + +struct _GConverterOutputStream +{ + GFilterOutputStream parent_instance; + + /*< private >*/ + GConverterOutputStreamPrivate *priv; +}; + +struct _GConverterOutputStreamClass +{ + GFilterOutputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_converter_output_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GOutputStream *g_converter_output_stream_new (GOutputStream *base_stream, + GConverter *converter); +GLIB_AVAILABLE_IN_ALL +GConverter *g_converter_output_stream_get_converter (GConverterOutputStream *converter_stream); + +G_END_DECLS + +#endif /* __G_CONVERTER_OUTPUT_STREAM_H__ */ diff --git a/gio/gcredentials.c b/gio/gcredentials.c new file mode 100644 index 0000000..17378e8 --- /dev/null +++ b/gio/gcredentials.c @@ -0,0 +1,705 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include + +#include + +#include "gcredentials.h" +#include "gcredentialsprivate.h" +#include "gnetworking.h" +#include "gioerror.h" +#include "gioenumtypes.h" + +#include "glibintl.h" + +/** + * SECTION:gcredentials + * @short_description: An object containing credentials + * @include: gio/gio.h + * + * The #GCredentials type is a reference-counted wrapper for native + * credentials. This information is typically used for identifying, + * authenticating and authorizing other processes. + * + * Some operating systems supports looking up the credentials of the + * remote peer of a communication endpoint - see e.g. + * g_socket_get_credentials(). + * + * Some operating systems supports securely sending and receiving + * credentials over a Unix Domain Socket, see + * #GUnixCredentialsMessage, g_unix_connection_send_credentials() and + * g_unix_connection_receive_credentials() for details. + * + * On Linux, the native credential type is a `struct ucred` - see the + * unix(7) man page for details. This corresponds to + * %G_CREDENTIALS_TYPE_LINUX_UCRED. + * + * On Apple operating systems (including iOS, tvOS, and macOS), + * the native credential type is a `struct xucred`. + * This corresponds to %G_CREDENTIALS_TYPE_APPLE_XUCRED. + * + * On FreeBSD, Debian GNU/kFreeBSD, and GNU/Hurd, the native + * credential type is a `struct cmsgcred`. This corresponds + * to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED. + * + * On NetBSD, the native credential type is a `struct unpcbid`. + * This corresponds to %G_CREDENTIALS_TYPE_NETBSD_UNPCBID. + * + * On OpenBSD, the native credential type is a `struct sockpeercred`. + * This corresponds to %G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED. + * + * On Solaris (including OpenSolaris and its derivatives), the native + * credential type is a `ucred_t`. This corresponds to + * %G_CREDENTIALS_TYPE_SOLARIS_UCRED. + * + * Since GLib 2.72, on Windows, the native credentials may contain the PID of a + * process. This corresponds to %G_CREDENTIALS_TYPE_WIN32_PID. + */ + +/** + * GCredentials: + * + * The #GCredentials structure contains only private data and + * should only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GCredentials +{ + /*< private >*/ + GObject parent_instance; + +#if G_CREDENTIALS_USE_LINUX_UCRED + struct ucred native; +#elif G_CREDENTIALS_USE_APPLE_XUCRED + struct xucred native; + pid_t pid; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + struct cmsgcred native; +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + struct unpcbid native; +#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED + struct sockpeercred native; +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + ucred_t *native; +#elif G_CREDENTIALS_USE_WIN32_PID + DWORD native; +#else + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic warning "-Wcpp" + #warning Please add GCredentials support for your OS + #pragma GCC diagnostic pop + #endif +#endif +}; + +/** + * GCredentialsClass: + * + * Class structure for #GCredentials. + * + * Since: 2.26 + */ +struct _GCredentialsClass +{ + /*< private >*/ + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT) + +static void +g_credentials_finalize (GObject *object) +{ +#if G_CREDENTIALS_USE_SOLARIS_UCRED + GCredentials *credentials = G_CREDENTIALS (object); + + ucred_free (credentials->native); +#endif + + if (G_OBJECT_CLASS (g_credentials_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_credentials_parent_class)->finalize (object); +} + + +static void +g_credentials_class_init (GCredentialsClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = g_credentials_finalize; +} + +static void +g_credentials_init (GCredentials *credentials) +{ +#if G_CREDENTIALS_USE_LINUX_UCRED + credentials->native.pid = getpid (); + credentials->native.uid = geteuid (); + credentials->native.gid = getegid (); +#elif G_CREDENTIALS_USE_APPLE_XUCRED + gsize i; + + credentials->native.cr_version = XUCRED_VERSION; + credentials->native.cr_uid = geteuid (); + credentials->native.cr_ngroups = 1; + credentials->native.cr_groups[0] = getegid (); + + /* FIXME: In principle this could use getgroups() to fill in the rest + * of cr_groups, but then we'd have to handle the case where a process + * can have more than NGROUPS groups, if that's even possible. A macOS + * user would have to develop and test this. + * + * For now we fill it with -1 (meaning "no data"). */ + for (i = 1; i < NGROUPS; i++) + credentials->native.cr_groups[i] = -1; + + credentials->pid = -1; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + memset (&credentials->native, 0, sizeof (struct cmsgcred)); + credentials->native.cmcred_pid = getpid (); + credentials->native.cmcred_euid = geteuid (); + credentials->native.cmcred_gid = getegid (); +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + credentials->native.unp_pid = getpid (); + credentials->native.unp_euid = geteuid (); + credentials->native.unp_egid = getegid (); +#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED + credentials->native.pid = getpid (); + credentials->native.uid = geteuid (); + credentials->native.gid = getegid (); +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + credentials->native = ucred_get (P_MYID); +#elif G_CREDENTIALS_USE_WIN32_PID + credentials->native = GetCurrentProcessId (); +#endif +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_credentials_new: + * + * Creates a new #GCredentials object with credentials matching the + * the current process. + * + * Returns: (transfer full): A #GCredentials. Free with g_object_unref(). + * + * Since: 2.26 + */ +GCredentials * +g_credentials_new (void) +{ + return g_object_new (G_TYPE_CREDENTIALS, NULL); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_credentials_to_string: + * @credentials: A #GCredentials object. + * + * Creates a human-readable textual representation of @credentials + * that can be used in logging and debug messages. The format of the + * returned string may change in future GLib release. + * + * Returns: (transfer full): A string that should be freed with g_free(). + * + * Since: 2.26 + */ +gchar * +g_credentials_to_string (GCredentials *credentials) +{ + GString *ret; +#if G_CREDENTIALS_USE_APPLE_XUCRED + glib_typeof (credentials->native.cr_ngroups) i; +#endif + + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); + + ret = g_string_new ("GCredentials:"); +#if G_CREDENTIALS_USE_LINUX_UCRED + g_string_append (ret, "linux-ucred:"); + if (credentials->native.pid != (pid_t) -1) + g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid); + if (credentials->native.uid != (uid_t) -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid); + if (credentials->native.gid != (gid_t) -1) + g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid); + if (ret->str[ret->len - 1] == ',') + ret->str[ret->len - 1] = '\0'; +#elif G_CREDENTIALS_USE_APPLE_XUCRED + g_string_append (ret, "apple-xucred:"); + g_string_append_printf (ret, "version=%u,", credentials->native.cr_version); + if (credentials->native.cr_uid != (uid_t) -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cr_uid); + for (i = 0; i < credentials->native.cr_ngroups; i++) + g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cr_groups[i]); + if (ret->str[ret->len - 1] == ',') + ret->str[ret->len - 1] = '\0'; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + g_string_append (ret, "freebsd-cmsgcred:"); + if (credentials->native.cmcred_pid != (pid_t) -1) + g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_pid); + if (credentials->native.cmcred_euid != (uid_t) -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_euid); + if (credentials->native.cmcred_gid != (gid_t) -1) + g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_gid); +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + g_string_append (ret, "netbsd-unpcbid:"); + if (credentials->native.unp_pid != (pid_t) -1) + g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_pid); + if (credentials->native.unp_euid != (uid_t) -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_euid); + if (credentials->native.unp_egid != (gid_t) -1) + g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.unp_egid); + ret->str[ret->len - 1] = '\0'; +#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED + g_string_append (ret, "openbsd-sockpeercred:"); + if (credentials->native.pid != (pid_t) -1) + g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid); + if (credentials->native.uid != (uid_t) -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid); + if (credentials->native.gid != (gid_t) -1) + g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid); + if (ret->str[ret->len - 1] == ',') + ret->str[ret->len - 1] = '\0'; +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + g_string_append (ret, "solaris-ucred:"); + { + id_t id; + if ((id = ucred_getpid (credentials->native)) != (id_t) -1) + g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) id); + if ((id = ucred_geteuid (credentials->native)) != (id_t) -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) id); + if ((id = ucred_getegid (credentials->native)) != (id_t) -1) + g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) id); + if (ret->str[ret->len - 1] == ',') + ret->str[ret->len - 1] = '\0'; + } +#elif G_CREDENTIALS_USE_WIN32_PID + g_string_append_printf (ret, "win32-pid:pid=%lu", credentials->native); +#else + g_string_append (ret, "unknown"); +#endif + + return g_string_free (ret, FALSE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#if G_CREDENTIALS_USE_LINUX_UCRED +/* + * Check whether @native contains invalid data. If getsockopt SO_PEERCRED + * is used on a TCP socket, it succeeds but yields a credentials structure + * with pid 0, uid -1 and gid -1. Similarly, if SO_PASSCRED is used on a + * receiving Unix socket when the sending socket did not also enable + * SO_PASSCRED, it can succeed but yield a credentials structure with + * pid 0, uid /proc/sys/kernel/overflowuid and gid + * /proc/sys/kernel/overflowgid. + */ +static gboolean +linux_ucred_check_valid (struct ucred *native, + GError **error) +{ + if (native->pid == 0 + || native->uid == (uid_t) -1 + || native->gid == (gid_t) -1) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("GCredentials contains invalid data")); + return FALSE; + } + + return TRUE; +} +#endif + +/** + * g_credentials_is_same_user: + * @credentials: A #GCredentials. + * @other_credentials: A #GCredentials. + * @error: Return location for error or %NULL. + * + * Checks if @credentials and @other_credentials is the same user. + * + * This operation can fail if #GCredentials is not supported on the + * the OS. + * + * Returns: %TRUE if @credentials and @other_credentials has the same + * user, %FALSE otherwise or if @error is set. + * + * Since: 2.26 + */ +gboolean +g_credentials_is_same_user (GCredentials *credentials, + GCredentials *other_credentials, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE); + g_return_val_if_fail (G_IS_CREDENTIALS (other_credentials), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; +#if G_CREDENTIALS_USE_LINUX_UCRED + if (linux_ucred_check_valid (&credentials->native, NULL) + && credentials->native.uid == other_credentials->native.uid) + ret = TRUE; +#elif G_CREDENTIALS_USE_APPLE_XUCRED + if (credentials->native.cr_version == other_credentials->native.cr_version && + credentials->native.cr_uid == other_credentials->native.cr_uid) + ret = TRUE; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid) + ret = TRUE; +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + if (credentials->native.unp_euid == other_credentials->native.unp_euid) + ret = TRUE; +#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED + if (credentials->native.uid == other_credentials->native.uid) + ret = TRUE; +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + if (ucred_geteuid (credentials->native) == ucred_geteuid (other_credentials->native)) + ret = TRUE; +#else + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("GCredentials is not implemented on this OS")); +#endif + + return ret; +} + +static gboolean +credentials_native_type_check (GCredentialsType requested_type, + const char *op) +{ + GEnumClass *enum_class; + GEnumValue *requested; +#if G_CREDENTIALS_SUPPORTED + GEnumValue *supported; +#endif + +#if G_CREDENTIALS_SUPPORTED + if (requested_type == G_CREDENTIALS_NATIVE_TYPE) + return TRUE; +#endif + + enum_class = g_type_class_ref (g_credentials_type_get_type ()); + requested = g_enum_get_value (enum_class, requested_type); + +#if G_CREDENTIALS_SUPPORTED + supported = g_enum_get_value (enum_class, G_CREDENTIALS_NATIVE_TYPE); + g_assert (supported); + g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s " + "but only %s is supported on this platform.", + op, op, + requested ? requested->value_name : "(unknown)", + supported->value_name); +#else + g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s " + "but there is no support for GCredentials on this platform.", + op, op, + requested ? requested->value_name : "(unknown)"); +#endif + + g_type_class_unref (enum_class); + return FALSE; +} + +/** + * g_credentials_get_native: (skip) + * @credentials: A #GCredentials. + * @native_type: The type of native credentials to get. + * + * Gets a pointer to native credentials of type @native_type from + * @credentials. + * + * It is a programming error (which will cause a warning to be + * logged) to use this method if there is no #GCredentials support for + * the OS or if @native_type isn't supported by the OS. + * + * Returns: (transfer none) (nullable): The pointer to native credentials or + * %NULL if there is no #GCredentials support for the OS or if @native_type + * isn't supported by the OS. Do not free the returned data, it is owned + * by @credentials. + * + * Since: 2.26 + */ +gpointer +g_credentials_get_native (GCredentials *credentials, + GCredentialsType native_type) +{ + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); + + if (!credentials_native_type_check (native_type, "get")) + return NULL; + +#if G_CREDENTIALS_USE_SOLARIS_UCRED + return credentials->native; +#elif G_CREDENTIALS_SUPPORTED + return &credentials->native; +#else + g_assert_not_reached (); +#endif +} + +/** + * g_credentials_set_native: + * @credentials: A #GCredentials. + * @native_type: The type of native credentials to set. + * @native: (not nullable): A pointer to native credentials. + * + * Copies the native credentials of type @native_type from @native + * into @credentials. + * + * It is a programming error (which will cause a warning to be + * logged) to use this method if there is no #GCredentials support for + * the OS or if @native_type isn't supported by the OS. + * + * Since: 2.26 + */ +void +g_credentials_set_native (GCredentials *credentials, + GCredentialsType native_type, + gpointer native) +{ + if (!credentials_native_type_check (native_type, "set")) + return; + +#if G_CREDENTIALS_USE_SOLARIS_UCRED + memcpy (credentials->native, native, ucred_size ()); +#elif G_CREDENTIALS_SUPPORTED + memcpy (&credentials->native, native, sizeof (credentials->native)); +#else + g_assert_not_reached (); +#endif +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_UNIX +/** + * g_credentials_get_unix_user: + * @credentials: A #GCredentials + * @error: Return location for error or %NULL. + * + * Tries to get the UNIX user identifier from @credentials. This + * method is only available on UNIX platforms. + * + * This operation can fail if #GCredentials is not supported on the + * OS or if the native credentials type does not contain information + * about the UNIX user. + * + * Returns: The UNIX user identifier or `-1` if @error is set. + * + * Since: 2.26 + */ +uid_t +g_credentials_get_unix_user (GCredentials *credentials, + GError **error) +{ + uid_t ret; + + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + +#if G_CREDENTIALS_USE_LINUX_UCRED + if (linux_ucred_check_valid (&credentials->native, error)) + ret = credentials->native.uid; + else + ret = -1; +#elif G_CREDENTIALS_USE_APPLE_XUCRED + if (credentials->native.cr_version == XUCRED_VERSION) + { + ret = credentials->native.cr_uid; + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* No point in translating the part in parentheses... */ + "%s (struct xucred cr_version %u != %u)", + _("There is no GCredentials support for your platform"), + credentials->native.cr_version, + XUCRED_VERSION); + ret = -1; + } +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + ret = credentials->native.cmcred_euid; +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + ret = credentials->native.unp_euid; +#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED + ret = credentials->native.uid; +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + ret = ucred_geteuid (credentials->native); +#else + ret = -1; + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("There is no GCredentials support for your platform")); +#endif + + return ret; +} + +/** + * g_credentials_get_unix_pid: + * @credentials: A #GCredentials + * @error: Return location for error or %NULL. + * + * Tries to get the UNIX process identifier from @credentials. This + * method is only available on UNIX platforms. + * + * This operation can fail if #GCredentials is not supported on the + * OS or if the native credentials type does not contain information + * about the UNIX process ID. + * + * Returns: The UNIX process ID, or `-1` if @error is set. + * + * Since: 2.36 + */ +pid_t +g_credentials_get_unix_pid (GCredentials *credentials, + GError **error) +{ + pid_t ret; + + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + +#if G_CREDENTIALS_USE_LINUX_UCRED + if (linux_ucred_check_valid (&credentials->native, error)) + ret = credentials->native.pid; + else + ret = -1; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + ret = credentials->native.cmcred_pid; +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + ret = credentials->native.unp_pid; +#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED + ret = credentials->native.pid; +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + ret = ucred_getpid (credentials->native); +#elif G_CREDENTIALS_USE_WIN32_PID + ret = credentials->native; +#else + +#if G_CREDENTIALS_USE_APPLE_XUCRED + ret = credentials->pid; +#else + ret = -1; +#endif + + if (ret == -1) + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("GCredentials does not contain a process ID on this OS")); +#endif + + return ret; +} + +/** + * g_credentials_set_unix_user: + * @credentials: A #GCredentials. + * @uid: The UNIX user identifier to set. + * @error: Return location for error or %NULL. + * + * Tries to set the UNIX user identifier on @credentials. This method + * is only available on UNIX platforms. + * + * This operation can fail if #GCredentials is not supported on the + * OS or if the native credentials type does not contain information + * about the UNIX user. It can also fail if the OS does not allow the + * use of "spoofed" credentials. + * + * Returns: %TRUE if @uid was set, %FALSE if error is set. + * + * Since: 2.26 + */ +gboolean +g_credentials_set_unix_user (GCredentials *credentials, + uid_t uid, + GError **error) +{ + gboolean ret = FALSE; + + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE); + g_return_val_if_fail (uid != (uid_t) -1, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + +#if G_CREDENTIALS_USE_LINUX_UCRED + credentials->native.uid = uid; + ret = TRUE; +#elif G_CREDENTIALS_USE_APPLE_XUCRED + credentials->native.cr_uid = uid; + ret = TRUE; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + credentials->native.cmcred_euid = uid; + ret = TRUE; +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + credentials->native.unp_euid = uid; + ret = TRUE; +#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED + credentials->native.uid = uid; + ret = TRUE; +#elif !G_CREDENTIALS_SPOOFING_SUPPORTED + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED, + _("Credentials spoofing is not possible on this OS")); + ret = FALSE; +#else + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("GCredentials is not implemented on this OS")); + ret = FALSE; +#endif + + return ret; +} + +#ifdef __APPLE__ +void +_g_credentials_set_local_peerid (GCredentials *credentials, + pid_t pid) +{ + g_return_if_fail (G_IS_CREDENTIALS (credentials)); + g_return_if_fail (pid >= 0); + + credentials->pid = pid; +} +#endif /* __APPLE__ */ + +#endif /* G_OS_UNIX */ diff --git a/gio/gcredentials.h b/gio/gcredentials.h new file mode 100644 index 0000000..b61ab78 --- /dev/null +++ b/gio/gcredentials.h @@ -0,0 +1,85 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_CREDENTIALS_H__ +#define __G_CREDENTIALS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +#ifdef G_OS_UNIX +/* To get the uid_t type */ +#include +#include +#endif + +G_BEGIN_DECLS + +#define G_TYPE_CREDENTIALS (g_credentials_get_type ()) +#define G_CREDENTIALS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CREDENTIALS, GCredentials)) +#define G_CREDENTIALS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CREDENTIALS, GCredentialsClass)) +#define G_CREDENTIALS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CREDENTIALS, GCredentialsClass)) +#define G_IS_CREDENTIALS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CREDENTIALS)) +#define G_IS_CREDENTIALS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CREDENTIALS)) + +typedef struct _GCredentialsClass GCredentialsClass; + +GLIB_AVAILABLE_IN_ALL +GType g_credentials_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GCredentials *g_credentials_new (void); + +GLIB_AVAILABLE_IN_ALL +gchar *g_credentials_to_string (GCredentials *credentials); + +GLIB_AVAILABLE_IN_ALL +gpointer g_credentials_get_native (GCredentials *credentials, + GCredentialsType native_type); + +GLIB_AVAILABLE_IN_ALL +void g_credentials_set_native (GCredentials *credentials, + GCredentialsType native_type, + gpointer native); + +GLIB_AVAILABLE_IN_ALL +gboolean g_credentials_is_same_user (GCredentials *credentials, + GCredentials *other_credentials, + GError **error); + +#ifdef G_OS_UNIX +GLIB_AVAILABLE_IN_2_36 +pid_t g_credentials_get_unix_pid (GCredentials *credentials, + GError **error); +GLIB_AVAILABLE_IN_ALL +uid_t g_credentials_get_unix_user (GCredentials *credentials, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_credentials_set_unix_user (GCredentials *credentials, + uid_t uid, + GError **error); +#endif + +G_END_DECLS + +#endif /* __G_CREDENTIALS_H__ */ diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h new file mode 100644 index 0000000..c09f9ec --- /dev/null +++ b/gio/gcredentialsprivate.h @@ -0,0 +1,185 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_CREDENTIALS_PRIVATE_H__ +#define __G_CREDENTIALS_PRIVATE_H__ + +#include "gio/gcredentials.h" +#include "gio/gnetworking.h" + +/* + * G_CREDENTIALS_SUPPORTED: + * + * Defined to 1 if GCredentials works. + */ +#undef G_CREDENTIALS_SUPPORTED + +/* + * G_CREDENTIALS_USE_LINUX_UCRED, etc.: + * + * Defined to 1 if GCredentials uses Linux `struct ucred`, etc. + */ +#undef G_CREDENTIALS_USE_LINUX_UCRED +#undef G_CREDENTIALS_USE_FREEBSD_CMSGCRED +#undef G_CREDENTIALS_USE_NETBSD_UNPCBID +#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED +#undef G_CREDENTIALS_USE_SOLARIS_UCRED +#undef G_CREDENTIALS_USE_APPLE_XUCRED +#undef G_CREDENTIALS_USE_WIN32_PID + +/* + * G_CREDENTIALS_NATIVE_TYPE: + * + * Defined to one of G_CREDENTIALS_TYPE_LINUX_UCRED, etc. + */ +#undef G_CREDENTIALS_NATIVE_TYPE + +/* + * G_CREDENTIALS_NATIVE_SIZE: + * + * Defined to the size of the %G_CREDENTIALS_NATIVE_TYPE + */ +#undef G_CREDENTIALS_NATIVE_SIZE + +/* + * G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED: + * + * Defined to 1 if we have a message-passing API in which credentials + * are attached to a particular message, such as `SCM_CREDENTIALS` on Linux + * or `SCM_CREDS` on FreeBSD. + */ +#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED + +/* + * G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED: + * + * Defined to 1 if we have a `getsockopt()`-style API in which one end of + * a socket connection can directly query the credentials of the process + * that initiated the other end, such as `getsockopt SO_PEERCRED` on Linux + * or `getpeereid()` on multiple operating systems. + */ +#undef G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED + +/* + * G_CREDENTIALS_SPOOFING_SUPPORTED: + * + * Defined to 1 if privileged processes can spoof their credentials when + * using the message-passing API. + */ +#undef G_CREDENTIALS_SPOOFING_SUPPORTED + +/* + * G_CREDENTIALS_PREFER_MESSAGE_PASSING: + * + * Defined to 1 if the data structure transferred by the message-passing + * API is strictly more informative than the one transferred by the + * `getsockopt()`-style API, and hence should be preferred, even for + * protocols like D-Bus that are defined in terms of the credentials of + * the (process that opened the) socket, as opposed to the credentials + * of an individual message. + */ +#undef G_CREDENTIALS_PREFER_MESSAGE_PASSING + +/* + * G_CREDENTIALS_HAS_PID: + * + * Defined to 1 if the %G_CREDENTIALS_NATIVE_TYPE contains the process ID. + */ +#undef G_CREDENTIALS_HAS_PID + +#ifdef __linux__ +#define G_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_USE_LINUX_UCRED 1 +#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_LINUX_UCRED +#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct ucred)) +#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1 +#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_SPOOFING_SUPPORTED 1 +#define G_CREDENTIALS_HAS_PID 1 + +#elif defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) /* Debian GNU/kFreeBSD */ || \ + defined(__GNU__) /* GNU Hurd */ || \ + defined(__DragonFly__) /* DragonFly BSD */ +#define G_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_USE_FREEBSD_CMSGCRED 1 +#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED +#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct cmsgcred)) +#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1 +#define G_CREDENTIALS_SPOOFING_SUPPORTED 1 +/* GLib doesn't implement it yet, but FreeBSD's getsockopt()-style API + * is getpeereid(), which is not as informative as struct cmsgcred - + * it does not tell us the PID. As a result, libdbus prefers to use + * SCM_CREDS, and if we implement getpeereid() in future, we should + * do the same. */ +#define G_CREDENTIALS_PREFER_MESSAGE_PASSING 1 +#define G_CREDENTIALS_HAS_PID 1 + +#elif defined(__NetBSD__) +#define G_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_USE_NETBSD_UNPCBID 1 +#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_NETBSD_UNPCBID +#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct unpcbid)) +/* #undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED */ +#define G_CREDENTIALS_SPOOFING_SUPPORTED 1 +#define G_CREDENTIALS_HAS_PID 1 + +#elif defined(__OpenBSD__) +#define G_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED 1 +#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED +#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct sockpeercred)) +#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_SPOOFING_SUPPORTED 1 +#define G_CREDENTIALS_HAS_PID 1 + +#elif defined(__sun__) || defined(__illumos__) || defined (__OpenSolaris_kernel__) +#include +#define G_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_USE_SOLARIS_UCRED 1 +#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_SOLARIS_UCRED +#define G_CREDENTIALS_NATIVE_SIZE (ucred_size ()) +#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1 +#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_HAS_PID 1 + +#elif defined(__APPLE__) +#include +#define G_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_USE_APPLE_XUCRED 1 +#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_APPLE_XUCRED +#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct xucred)) +#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED +#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_SPOOFING_SUPPORTED 1 +#define G_CREDENTIALS_HAS_PID 0 + +void _g_credentials_set_local_peerid (GCredentials *credentials, + pid_t pid); + +#elif defined(_WIN32) +#define G_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_USE_WIN32_PID 1 +#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_WIN32_PID +#define G_CREDENTIALS_NATIVE_SIZE (sizeof (DWORD)) +#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_HAS_PID 1 + +#endif + +#endif /* __G_CREDENTIALS_PRIVATE_H__ */ diff --git a/gio/gdatagrambased.c b/gio/gdatagrambased.c new file mode 100644 index 0000000..1e1c051 --- /dev/null +++ b/gio/gdatagrambased.c @@ -0,0 +1,474 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2015 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Philip Withnall + */ + +#include "config.h" + +#include "gdatagrambased.h" + +#include "gcancellable.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include "gnetworkingprivate.h" +#include "gsocketaddress.h" +#include "glibintl.h" + +/** + * SECTION:gdatagrambased + * @short_description: Low-level datagram communications interface + * @include: gio/gio.h + * @see_also: #GSocket, [][gio-gnetworking.h] + * + * A #GDatagramBased is a networking interface for representing datagram-based + * communications. It is a more or less direct mapping of the core parts of the + * BSD socket API in a portable GObject interface. It is implemented by + * #GSocket, which wraps the UNIX socket API on UNIX and winsock2 on Windows. + * + * #GDatagramBased is entirely platform independent, and is intended to be used + * alongside higher-level networking APIs such as #GIOStream. + * + * It uses vectored scatter/gather I/O by default, allowing for many messages + * to be sent or received in a single call. Where possible, implementations of + * the interface should take advantage of vectored I/O to minimise processing + * or system calls. For example, #GSocket uses recvmmsg() and sendmmsg() where + * possible. Callers should take advantage of scatter/gather I/O (the use of + * multiple buffers per message) to avoid unnecessary copying of data to + * assemble or disassemble a message. + * + * Each #GDatagramBased operation has a timeout parameter which may be negative + * for blocking behaviour, zero for non-blocking behaviour, or positive for + * timeout behaviour. A blocking operation blocks until finished or there is an + * error. A non-blocking operation will return immediately with a + * %G_IO_ERROR_WOULD_BLOCK error if it cannot make progress. A timeout operation + * will block until the operation is complete or the timeout expires; if the + * timeout expires it will return what progress it made, or + * %G_IO_ERROR_TIMED_OUT if no progress was made. To know when a call would + * successfully run you can call g_datagram_based_condition_check() or + * g_datagram_based_condition_wait(). You can also use + * g_datagram_based_create_source() and attach it to a #GMainContext to get + * callbacks when I/O is possible. + * + * When running a non-blocking operation applications should always be able to + * handle getting a %G_IO_ERROR_WOULD_BLOCK error even when some other function + * said that I/O was possible. This can easily happen in case of a race + * condition in the application, but it can also happen for other reasons. For + * instance, on Windows a socket is always seen as writable until a write + * returns %G_IO_ERROR_WOULD_BLOCK. + * + * As with #GSocket, #GDatagramBaseds can be either connection oriented (for + * example, SCTP) or connectionless (for example, UDP). #GDatagramBaseds must be + * datagram-based, not stream-based. The interface does not cover connection + * establishment — use methods on the underlying type to establish a connection + * before sending and receiving data through the #GDatagramBased API. For + * connectionless socket types the target/source address is specified or + * received in each I/O operation. + * + * Like most other APIs in GLib, #GDatagramBased is not inherently thread safe. + * To use a #GDatagramBased concurrently from multiple threads, you must + * implement your own locking. + * + * Since: 2.48 + */ + +G_DEFINE_INTERFACE (GDatagramBased, g_datagram_based, G_TYPE_OBJECT) + +static void +g_datagram_based_default_init (GDatagramBasedInterface *iface) +{ + /* Nothing here. */ +} + +/** + * g_datagram_based_receive_messages: + * @datagram_based: a #GDatagramBased + * @messages: (array length=num_messages): an array of #GInputMessage structs + * @num_messages: the number of elements in @messages + * @flags: an int containing #GSocketMsgFlags flags for the overall operation + * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1 + * to block indefinitely + * @cancellable: (nullable): a %GCancellable + * @error: return location for a #GError + * + * Receive one or more data messages from @datagram_based in one go. + * + * @messages must point to an array of #GInputMessage structs and + * @num_messages must be the length of this array. Each #GInputMessage + * contains a pointer to an array of #GInputVector structs describing the + * buffers that the data received in each message will be written to. + * + * @flags modify how all messages are received. The commonly available + * arguments for this are available in the #GSocketMsgFlags enum, but the + * values there are the same as the system values, and the flags + * are passed in as-is, so you can pass in system-specific flags too. These + * flags affect the overall receive operation. Flags affecting individual + * messages are returned in #GInputMessage.flags. + * + * The other members of #GInputMessage are treated as described in its + * documentation. + * + * If @timeout is negative the call will block until @num_messages have been + * received, the connection is closed remotely (EOS), @cancellable is cancelled, + * or an error occurs. + * + * If @timeout is 0 the call will return up to @num_messages without blocking, + * or %G_IO_ERROR_WOULD_BLOCK if no messages are queued in the operating system + * to be received. + * + * If @timeout is positive the call will block on the same conditions as if + * @timeout were negative. If the timeout is reached + * before any messages are received, %G_IO_ERROR_TIMED_OUT is returned, + * otherwise it will return the number of messages received before timing out. + * (Note: This is effectively the behaviour of `MSG_WAITFORONE` with + * recvmmsg().) + * + * To be notified when messages are available, wait for the %G_IO_IN condition. + * Note though that you may still receive %G_IO_ERROR_WOULD_BLOCK from + * g_datagram_based_receive_messages() even if you were previously notified of a + * %G_IO_IN condition. + * + * If the remote peer closes the connection, any messages queued in the + * underlying receive buffer will be returned, and subsequent calls to + * g_datagram_based_receive_messages() will return 0 (with no error set). + * + * If the connection is shut down or closed (by calling g_socket_close() or + * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket, for + * example), all calls to this function will return %G_IO_ERROR_CLOSED. + * + * On error -1 is returned and @error is set accordingly. An error will only + * be returned if zero messages could be received; otherwise the number of + * messages successfully received before the error will be returned. If + * @cancellable is cancelled, %G_IO_ERROR_CANCELLED is returned as with any + * other error. + * + * Returns: number of messages received, or -1 on error. Note that the number + * of messages received may be smaller than @num_messages if @timeout is + * zero or positive, if the peer closed the connection, or if @num_messages + * was larger than `UIO_MAXIOV` (1024), in which case the caller may re-try + * to receive the remaining messages. + * + * Since: 2.48 + */ +gint +g_datagram_based_receive_messages (GDatagramBased *datagram_based, + GInputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout, + GCancellable *cancellable, + GError **error) +{ + GDatagramBasedInterface *iface; + gint retval; + GError *child_error = NULL; + + g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), -1); + g_return_val_if_fail (num_messages == 0 || messages != NULL, -1); + g_return_val_if_fail (cancellable == NULL || + G_IS_CANCELLABLE (cancellable), -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based); + g_assert (iface->receive_messages != NULL); + + retval = iface->receive_messages (datagram_based, messages, num_messages, + flags, timeout, cancellable, &child_error); + + /* Postconditions. */ + g_return_val_if_fail ((retval < 0) == (child_error != NULL), -1); + g_return_val_if_fail (timeout == 0 || + !g_error_matches (child_error, G_IO_ERROR, + G_IO_ERROR_WOULD_BLOCK), -1); + g_return_val_if_fail (timeout > 0 || + !g_error_matches (child_error, G_IO_ERROR, + G_IO_ERROR_TIMED_OUT), -1); + g_return_val_if_fail (retval < 0 || (guint) retval <= num_messages, -1); + + if (child_error != NULL) + g_propagate_error (error, child_error); + + return retval; +} + +/** + * g_datagram_based_send_messages: + * @datagram_based: a #GDatagramBased + * @messages: (array length=num_messages): an array of #GOutputMessage structs + * @num_messages: the number of elements in @messages + * @flags: an int containing #GSocketMsgFlags flags + * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1 + * to block indefinitely + * @cancellable: (nullable): a %GCancellable + * @error: return location for a #GError + * + * Send one or more data messages from @datagram_based in one go. + * + * @messages must point to an array of #GOutputMessage structs and + * @num_messages must be the length of this array. Each #GOutputMessage + * contains an address to send the data to, and a pointer to an array of + * #GOutputVector structs to describe the buffers that the data to be sent + * for each message will be gathered from. + * + * @flags modify how the message is sent. The commonly available arguments + * for this are available in the #GSocketMsgFlags enum, but the + * values there are the same as the system values, and the flags + * are passed in as-is, so you can pass in system-specific flags too. + * + * The other members of #GOutputMessage are treated as described in its + * documentation. + * + * If @timeout is negative the call will block until @num_messages have been + * sent, @cancellable is cancelled, or an error occurs. + * + * If @timeout is 0 the call will send up to @num_messages without blocking, + * or will return %G_IO_ERROR_WOULD_BLOCK if there is no space to send messages. + * + * If @timeout is positive the call will block on the same conditions as if + * @timeout were negative. If the timeout is reached before any messages are + * sent, %G_IO_ERROR_TIMED_OUT is returned, otherwise it will return the number + * of messages sent before timing out. + * + * To be notified when messages can be sent, wait for the %G_IO_OUT condition. + * Note though that you may still receive %G_IO_ERROR_WOULD_BLOCK from + * g_datagram_based_send_messages() even if you were previously notified of a + * %G_IO_OUT condition. (On Windows in particular, this is very common due to + * the way the underlying APIs work.) + * + * If the connection is shut down or closed (by calling g_socket_close() or + * g_socket_shutdown() with @shutdown_write set, if it’s a #GSocket, for + * example), all calls to this function will return %G_IO_ERROR_CLOSED. + * + * On error -1 is returned and @error is set accordingly. An error will only + * be returned if zero messages could be sent; otherwise the number of messages + * successfully sent before the error will be returned. If @cancellable is + * cancelled, %G_IO_ERROR_CANCELLED is returned as with any other error. + * + * Returns: number of messages sent, or -1 on error. Note that the number of + * messages sent may be smaller than @num_messages if @timeout is zero + * or positive, or if @num_messages was larger than `UIO_MAXIOV` (1024), in + * which case the caller may re-try to send the remaining messages. + * + * Since: 2.48 + */ +gint +g_datagram_based_send_messages (GDatagramBased *datagram_based, + GOutputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout, + GCancellable *cancellable, + GError **error) +{ + GDatagramBasedInterface *iface; + gint retval; + GError *child_error = NULL; + + g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), -1); + g_return_val_if_fail (num_messages == 0 || messages != NULL, -1); + g_return_val_if_fail (cancellable == NULL || + G_IS_CANCELLABLE (cancellable), -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based); + g_assert (iface->send_messages != NULL); + + retval = iface->send_messages (datagram_based, messages, num_messages, flags, + timeout, cancellable, &child_error); + + /* Postconditions. */ + g_return_val_if_fail ((retval < 0) == (child_error != NULL), -1); + g_return_val_if_fail (timeout == 0 || + !g_error_matches (child_error, G_IO_ERROR, + G_IO_ERROR_WOULD_BLOCK), -1); + g_return_val_if_fail (timeout > 0 || + !g_error_matches (child_error, G_IO_ERROR, + G_IO_ERROR_TIMED_OUT), -1); + g_return_val_if_fail (retval < 0 || (guint) retval <= num_messages, -1); + g_return_val_if_fail (!(timeout < 0 && num_messages > 0) || retval != 0, -1); + + if (child_error != NULL) + g_propagate_error (error, child_error); + + return retval; +} + +/** + * g_datagram_based_create_source: + * @datagram_based: a #GDatagramBased + * @condition: a #GIOCondition mask to monitor + * @cancellable: (nullable): a #GCancellable + * + * Creates a #GSource that can be attached to a #GMainContext to monitor for + * the availability of the specified @condition on the #GDatagramBased. The + * #GSource keeps a reference to the @datagram_based. + * + * The callback on the source is of the #GDatagramBasedSourceFunc type. + * + * It is meaningless to specify %G_IO_ERR or %G_IO_HUP in @condition; these + * conditions will always be reported in the callback if they are true. + * + * If non-%NULL, @cancellable can be used to cancel the source, which will + * cause the source to trigger, reporting the current condition (which is + * likely 0 unless cancellation happened at the same time as a condition + * change). You can check for this in the callback using + * g_cancellable_is_cancelled(). + * + * Returns: (transfer full): a newly allocated #GSource + * + * Since: 2.48 + */ +GSource * +g_datagram_based_create_source (GDatagramBased *datagram_based, + GIOCondition condition, + GCancellable *cancellable) +{ + GDatagramBasedInterface *iface; + + g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), NULL); + g_return_val_if_fail (cancellable == NULL || + G_IS_CANCELLABLE (cancellable), NULL); + + iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based); + g_assert (iface->create_source != NULL); + + return iface->create_source (datagram_based, condition, cancellable); +} + +/** + * g_datagram_based_condition_check: + * @datagram_based: a #GDatagramBased + * @condition: a #GIOCondition mask to check + * + * Checks on the readiness of @datagram_based to perform operations. The + * operations specified in @condition are checked for and masked against the + * currently-satisfied conditions on @datagram_based. The result is returned. + * + * %G_IO_IN will be set in the return value if data is available to read with + * g_datagram_based_receive_messages(), or if the connection is closed remotely + * (EOS); and if the datagram_based has not been closed locally using some + * implementation-specific method (such as g_socket_close() or + * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket). + * + * If the connection is shut down or closed (by calling g_socket_close() or + * g_socket_shutdown() with @shutdown_read set, if it’s a #GSocket, for + * example), all calls to this function will return %G_IO_ERROR_CLOSED. + * + * %G_IO_OUT will be set if it is expected that at least one byte can be sent + * using g_datagram_based_send_messages() without blocking. It will not be set + * if the datagram_based has been closed locally. + * + * %G_IO_HUP will be set if the connection has been closed locally. + * + * %G_IO_ERR will be set if there was an asynchronous error in transmitting data + * previously enqueued using g_datagram_based_send_messages(). + * + * Note that on Windows, it is possible for an operation to return + * %G_IO_ERROR_WOULD_BLOCK even immediately after + * g_datagram_based_condition_check() has claimed that the #GDatagramBased is + * ready for writing. Rather than calling g_datagram_based_condition_check() and + * then writing to the #GDatagramBased if it succeeds, it is generally better to + * simply try writing right away, and try again later if the initial attempt + * returns %G_IO_ERROR_WOULD_BLOCK. + * + * It is meaningless to specify %G_IO_ERR or %G_IO_HUP in @condition; these + * conditions will always be set in the output if they are true. Apart from + * these flags, the output is guaranteed to be masked by @condition. + * + * This call never blocks. + * + * Returns: the #GIOCondition mask of the current state + * + * Since: 2.48 + */ +GIOCondition +g_datagram_based_condition_check (GDatagramBased *datagram_based, + GIOCondition condition) +{ + GDatagramBasedInterface *iface; + GIOCondition out; + + g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), 0); + + iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based); + g_assert (iface->condition_check != NULL); + + out = iface->condition_check (datagram_based, condition); + + /* Postconditions. G_IO_OUT and G_IO_HUP are mutually exclusive. G_IO_IN and + * G_IO_HUP are mutually exclusive. The return value must be a subset of + * (condition | G_IO_ERR | G_IO_HUP). */ + g_return_val_if_fail ((out & (G_IO_OUT | G_IO_HUP)) != (G_IO_OUT | G_IO_HUP), + out & ~G_IO_OUT); + g_return_val_if_fail ((out & (G_IO_IN | G_IO_HUP)) != (G_IO_IN | G_IO_HUP), + out & ~G_IO_IN); + g_return_val_if_fail ((out & ~(condition | G_IO_ERR | G_IO_HUP)) == 0, + out & (condition | G_IO_ERR | G_IO_HUP)); + + return out; +} + +/** + * g_datagram_based_condition_wait: + * @datagram_based: a #GDatagramBased + * @condition: a #GIOCondition mask to wait for + * @timeout: the maximum time (in microseconds) to wait, 0 to not block, or -1 + * to block indefinitely + * @cancellable: (nullable): a #GCancellable + * @error: return location for a #GError + * + * Waits for up to @timeout microseconds for condition to become true on + * @datagram_based. If the condition is met, %TRUE is returned. + * + * If @cancellable is cancelled before the condition is met, or if @timeout is + * reached before the condition is met, then %FALSE is returned and @error is + * set appropriately (%G_IO_ERROR_CANCELLED or %G_IO_ERROR_TIMED_OUT). + * + * Returns: %TRUE if the condition was met, %FALSE otherwise + * + * Since: 2.48 + */ +gboolean +g_datagram_based_condition_wait (GDatagramBased *datagram_based, + GIOCondition condition, + gint64 timeout, + GCancellable *cancellable, + GError **error) +{ + GDatagramBasedInterface *iface; + gboolean out; + GError *child_error = NULL; + + g_return_val_if_fail (G_IS_DATAGRAM_BASED (datagram_based), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), + FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + iface = G_DATAGRAM_BASED_GET_IFACE (datagram_based); + g_assert (iface->condition_wait != NULL); + + out = iface->condition_wait (datagram_based, condition, timeout, + cancellable, &child_error); + + /* Postconditions. */ + g_return_val_if_fail (out == (child_error == NULL), FALSE); + + if (child_error != NULL) + g_propagate_error (error, child_error); + + return out; +} diff --git a/gio/gdatagrambased.h b/gio/gdatagrambased.h new file mode 100644 index 0000000..838b485 --- /dev/null +++ b/gio/gdatagrambased.h @@ -0,0 +1,144 @@ +/* + * Copyright 2015 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Philip Withnall + */ + +#ifndef __G_DATAGRAM_BASED_H__ +#define __G_DATAGRAM_BASED_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DATAGRAM_BASED (g_datagram_based_get_type ()) +#define G_DATAGRAM_BASED(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_DATAGRAM_BASED, GDatagramBased)) +#define G_IS_DATAGRAM_BASED(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_DATAGRAM_BASED)) +#define G_DATAGRAM_BASED_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \ + G_TYPE_DATAGRAM_BASED, \ + GDatagramBasedInterface)) +#define G_TYPE_IS_DATAGRAM_BASED(type) (g_type_is_a ((type), \ + G_TYPE_DATAGRAM_BASED)) + +/** + * GDatagramBased: + * + * Interface for socket-like objects with datagram semantics. + * + * Since: 2.48 + */ +typedef struct _GDatagramBasedInterface GDatagramBasedInterface; + +/** + * GDatagramBasedInterface: + * @g_iface: The parent interface. + * @receive_messages: Virtual method for g_datagram_based_receive_messages(). + * @send_messages: Virtual method for g_datagram_based_send_messages(). + * @create_source: Virtual method for g_datagram_based_create_source(). + * @condition_check: Virtual method for g_datagram_based_condition_check(). + * @condition_wait: Virtual method for + * g_datagram_based_condition_wait(). + * + * Provides an interface for socket-like objects which have datagram semantics, + * following the Berkeley sockets API. The interface methods are thin wrappers + * around the corresponding virtual methods, and no pre-processing of inputs is + * implemented — so implementations of this API must handle all functionality + * documented in the interface methods. + * + * Since: 2.48 + */ +struct _GDatagramBasedInterface +{ + GTypeInterface g_iface; + + /* Virtual table */ + gint (*receive_messages) (GDatagramBased *datagram_based, + GInputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout, + GCancellable *cancellable, + GError **error); + gint (*send_messages) (GDatagramBased *datagram_based, + GOutputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout, + GCancellable *cancellable, + GError **error); + + GSource *(*create_source) (GDatagramBased *datagram_based, + GIOCondition condition, + GCancellable *cancellable); + GIOCondition (*condition_check) (GDatagramBased *datagram_based, + GIOCondition condition); + gboolean (*condition_wait) (GDatagramBased *datagram_based, + GIOCondition condition, + gint64 timeout, + GCancellable *cancellable, + GError **error); +}; + +GLIB_AVAILABLE_IN_2_48 +GType +g_datagram_based_get_type (void); + +GLIB_AVAILABLE_IN_2_48 +gint +g_datagram_based_receive_messages (GDatagramBased *datagram_based, + GInputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +gint +g_datagram_based_send_messages (GDatagramBased *datagram_based, + GOutputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +GSource * +g_datagram_based_create_source (GDatagramBased *datagram_based, + GIOCondition condition, + GCancellable *cancellable); +GLIB_AVAILABLE_IN_2_48 +GIOCondition +g_datagram_based_condition_check (GDatagramBased *datagram_based, + GIOCondition condition); +GLIB_AVAILABLE_IN_2_48 +gboolean +g_datagram_based_condition_wait (GDatagramBased *datagram_based, + GIOCondition condition, + gint64 timeout, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* __G_DATAGRAM_BASED_H__ */ diff --git a/gio/gdatainputstream.c b/gio/gdatainputstream.c new file mode 100644 index 0000000..a9db626 --- /dev/null +++ b/gio/gdatainputstream.c @@ -0,0 +1,1477 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2007 Jürg Billeter + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "gdatainputstream.h" +#include "gtask.h" +#include "gcancellable.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include "glibintl.h" + +#include + +/** + * SECTION:gdatainputstream + * @short_description: Data Input Stream + * @include: gio/gio.h + * @see_also: #GInputStream + * + * Data input stream implements #GInputStream and includes functions for + * reading structured data directly from a binary input stream. + * + **/ + +struct _GDataInputStreamPrivate { + GDataStreamByteOrder byte_order; + GDataStreamNewlineType newline_type; +}; + +enum { + PROP_0, + PROP_BYTE_ORDER, + PROP_NEWLINE_TYPE +}; + +static void g_data_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_data_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +G_DEFINE_TYPE_WITH_PRIVATE (GDataInputStream, + g_data_input_stream, + G_TYPE_BUFFERED_INPUT_STREAM) + + +static void +g_data_input_stream_class_init (GDataInputStreamClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = g_data_input_stream_get_property; + object_class->set_property = g_data_input_stream_set_property; + + /** + * GDataInputStream:byte-order: + * + * The :byte-order property determines the byte ordering that + * is used when reading multi-byte entities (such as integers) + * from the stream. + */ + g_object_class_install_property (object_class, + PROP_BYTE_ORDER, + g_param_spec_enum ("byte-order", + P_("Byte order"), + P_("The byte order"), + G_TYPE_DATA_STREAM_BYTE_ORDER, + G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN, + G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB)); + + /** + * GDataInputStream:newline-type: + * + * The :newline-type property determines what is considered + * as a line ending when reading complete lines from the stream. + */ + g_object_class_install_property (object_class, + PROP_NEWLINE_TYPE, + g_param_spec_enum ("newline-type", + P_("Newline type"), + P_("The accepted types of line ending"), + G_TYPE_DATA_STREAM_NEWLINE_TYPE, + G_DATA_STREAM_NEWLINE_TYPE_LF, + G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB)); +} + +static void +g_data_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDataInputStream *dstream; + + dstream = G_DATA_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_BYTE_ORDER: + g_data_input_stream_set_byte_order (dstream, g_value_get_enum (value)); + break; + + case PROP_NEWLINE_TYPE: + g_data_input_stream_set_newline_type (dstream, g_value_get_enum (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_data_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDataInputStreamPrivate *priv; + GDataInputStream *dstream; + + dstream = G_DATA_INPUT_STREAM (object); + priv = dstream->priv; + + switch (prop_id) + { + case PROP_BYTE_ORDER: + g_value_set_enum (value, priv->byte_order); + break; + + case PROP_NEWLINE_TYPE: + g_value_set_enum (value, priv->newline_type); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} +static void +g_data_input_stream_init (GDataInputStream *stream) +{ + stream->priv = g_data_input_stream_get_instance_private (stream); + stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN; + stream->priv->newline_type = G_DATA_STREAM_NEWLINE_TYPE_LF; +} + +/** + * g_data_input_stream_new: + * @base_stream: a #GInputStream. + * + * Creates a new data input stream for the @base_stream. + * + * Returns: a new #GDataInputStream. + **/ +GDataInputStream * +g_data_input_stream_new (GInputStream *base_stream) +{ + GDataInputStream *stream; + + g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL); + + stream = g_object_new (G_TYPE_DATA_INPUT_STREAM, + "base-stream", base_stream, + NULL); + + return stream; +} + +/** + * g_data_input_stream_set_byte_order: + * @stream: a given #GDataInputStream. + * @order: a #GDataStreamByteOrder to set. + * + * This function sets the byte order for the given @stream. All subsequent + * reads from the @stream will be read in the given @order. + * + **/ +void +g_data_input_stream_set_byte_order (GDataInputStream *stream, + GDataStreamByteOrder order) +{ + GDataInputStreamPrivate *priv; + + g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream)); + + priv = stream->priv; + + if (priv->byte_order != order) + { + priv->byte_order = order; + + g_object_notify (G_OBJECT (stream), "byte-order"); + } +} + +/** + * g_data_input_stream_get_byte_order: + * @stream: a given #GDataInputStream. + * + * Gets the byte order for the data input stream. + * + * Returns: the @stream's current #GDataStreamByteOrder. + **/ +GDataStreamByteOrder +g_data_input_stream_get_byte_order (GDataInputStream *stream) +{ + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN); + + return stream->priv->byte_order; +} + +/** + * g_data_input_stream_set_newline_type: + * @stream: a #GDataInputStream. + * @type: the type of new line return as #GDataStreamNewlineType. + * + * Sets the newline type for the @stream. + * + * Note that using G_DATA_STREAM_NEWLINE_TYPE_ANY is slightly unsafe. If a read + * chunk ends in "CR" we must read an additional byte to know if this is "CR" or + * "CR LF", and this might block if there is no more data available. + * + **/ +void +g_data_input_stream_set_newline_type (GDataInputStream *stream, + GDataStreamNewlineType type) +{ + GDataInputStreamPrivate *priv; + + g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream)); + + priv = stream->priv; + + if (priv->newline_type != type) + { + priv->newline_type = type; + + g_object_notify (G_OBJECT (stream), "newline-type"); + } +} + +/** + * g_data_input_stream_get_newline_type: + * @stream: a given #GDataInputStream. + * + * Gets the current newline type for the @stream. + * + * Returns: #GDataStreamNewlineType for the given @stream. + **/ +GDataStreamNewlineType +g_data_input_stream_get_newline_type (GDataInputStream *stream) +{ + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), G_DATA_STREAM_NEWLINE_TYPE_ANY); + + return stream->priv->newline_type; +} + +static gboolean +read_data (GDataInputStream *stream, + void *buffer, + gsize size, + GCancellable *cancellable, + GError **error) +{ + gsize available; + gssize res; + + while ((available = g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (stream))) < size) + { + res = g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (stream), + size - available, + cancellable, error); + if (res < 0) + return FALSE; + if (res == 0) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Unexpected early end-of-stream")); + return FALSE; + } + } + + /* This should always succeed, since it's in the buffer */ + res = g_input_stream_read (G_INPUT_STREAM (stream), + buffer, size, + NULL, NULL); + g_warn_if_fail (res >= 0 && (gsize) res == size); + return TRUE; +} + + +/** + * g_data_input_stream_read_byte: + * @stream: a given #GDataInputStream. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads an unsigned 8-bit/1-byte value from @stream. + * + * Returns: an unsigned 8-bit/1-byte value read from the @stream or `0` + * if an error occurred. + **/ +guchar +g_data_input_stream_read_byte (GDataInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + guchar c; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), '\0'); + + if (read_data (stream, &c, 1, cancellable, error)) + return c; + + return 0; +} + + +/** + * g_data_input_stream_read_int16: + * @stream: a given #GDataInputStream. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads a 16-bit/2-byte value from @stream. + * + * In order to get the correct byte order for this read operation, + * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order(). + * + * Returns: a signed 16-bit/2-byte value read from @stream or `0` if + * an error occurred. + **/ +gint16 +g_data_input_stream_read_int16 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + gint16 v; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0); + + if (read_data (stream, &v, 2, cancellable, error)) + { + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + v = GINT16_FROM_BE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + v = GINT16_FROM_LE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + return v; + } + + return 0; +} + + +/** + * g_data_input_stream_read_uint16: + * @stream: a given #GDataInputStream. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads an unsigned 16-bit/2-byte value from @stream. + * + * In order to get the correct byte order for this read operation, + * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order(). + * + * Returns: an unsigned 16-bit/2-byte value read from the @stream or `0` if + * an error occurred. + **/ +guint16 +g_data_input_stream_read_uint16 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + guint16 v; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0); + + if (read_data (stream, &v, 2, cancellable, error)) + { + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + v = GUINT16_FROM_BE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + v = GUINT16_FROM_LE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + return v; + } + + return 0; +} + + +/** + * g_data_input_stream_read_int32: + * @stream: a given #GDataInputStream. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads a signed 32-bit/4-byte value from @stream. + * + * In order to get the correct byte order for this read operation, + * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: a signed 32-bit/4-byte value read from the @stream or `0` if + * an error occurred. + **/ +gint32 +g_data_input_stream_read_int32 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + gint32 v; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0); + + if (read_data (stream, &v, 4, cancellable, error)) + { + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + v = GINT32_FROM_BE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + v = GINT32_FROM_LE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + return v; + } + + return 0; +} + + +/** + * g_data_input_stream_read_uint32: + * @stream: a given #GDataInputStream. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads an unsigned 32-bit/4-byte value from @stream. + * + * In order to get the correct byte order for this read operation, + * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: an unsigned 32-bit/4-byte value read from the @stream or `0` if + * an error occurred. + **/ +guint32 +g_data_input_stream_read_uint32 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + guint32 v; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0); + + if (read_data (stream, &v, 4, cancellable, error)) + { + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + v = GUINT32_FROM_BE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + v = GUINT32_FROM_LE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + return v; + } + + return 0; +} + + +/** + * g_data_input_stream_read_int64: + * @stream: a given #GDataInputStream. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads a 64-bit/8-byte value from @stream. + * + * In order to get the correct byte order for this read operation, + * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: a signed 64-bit/8-byte value read from @stream or `0` if + * an error occurred. + **/ +gint64 +g_data_input_stream_read_int64 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + gint64 v; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0); + + if (read_data (stream, &v, 8, cancellable, error)) + { + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + v = GINT64_FROM_BE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + v = GINT64_FROM_LE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + return v; + } + + return 0; +} + + +/** + * g_data_input_stream_read_uint64: + * @stream: a given #GDataInputStream. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads an unsigned 64-bit/8-byte value from @stream. + * + * In order to get the correct byte order for this read operation, + * see g_data_input_stream_get_byte_order(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: an unsigned 64-bit/8-byte read from @stream or `0` if + * an error occurred. + **/ +guint64 +g_data_input_stream_read_uint64 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + guint64 v; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0); + + if (read_data (stream, &v, 8, cancellable, error)) + { + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + v = GUINT64_FROM_BE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + v = GUINT64_FROM_LE (v); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + return v; + } + + return 0; +} + +static gssize +scan_for_newline (GDataInputStream *stream, + gsize *checked_out, + gboolean *last_saw_cr_out, + int *newline_len_out) +{ + GBufferedInputStream *bstream; + GDataInputStreamPrivate *priv; + const char *buffer; + gsize start, end, peeked; + gsize i; + gssize found_pos; + int newline_len; + gsize available, checked; + gboolean last_saw_cr; + + priv = stream->priv; + + bstream = G_BUFFERED_INPUT_STREAM (stream); + + checked = *checked_out; + last_saw_cr = *last_saw_cr_out; + found_pos = -1; + newline_len = 0; + + start = checked; + buffer = (const char*)g_buffered_input_stream_peek_buffer (bstream, &available) + start; + end = available; + peeked = end - start; + + for (i = 0; checked < available && i < peeked; i++) + { + switch (priv->newline_type) + { + case G_DATA_STREAM_NEWLINE_TYPE_LF: + if (buffer[i] == 10) + { + found_pos = start + i; + newline_len = 1; + } + break; + case G_DATA_STREAM_NEWLINE_TYPE_CR: + if (buffer[i] == 13) + { + found_pos = start + i; + newline_len = 1; + } + break; + case G_DATA_STREAM_NEWLINE_TYPE_CR_LF: + if (last_saw_cr && buffer[i] == 10) + { + found_pos = start + i - 1; + newline_len = 2; + } + break; + default: + case G_DATA_STREAM_NEWLINE_TYPE_ANY: + if (buffer[i] == 10) /* LF */ + { + if (last_saw_cr) + { + /* CR LF */ + found_pos = start + i - 1; + newline_len = 2; + } + else + { + /* LF */ + found_pos = start + i; + newline_len = 1; + } + } + else if (last_saw_cr) + { + /* Last was cr, this is not LF, end is CR */ + found_pos = start + i - 1; + newline_len = 1; + } + /* Don't check for CR here, instead look at last_saw_cr on next byte */ + break; + } + + last_saw_cr = (buffer[i] == 13); + + if (found_pos != -1) + { + *newline_len_out = newline_len; + return found_pos; + } + } + + checked = end; + + *checked_out = checked; + *last_saw_cr_out = last_saw_cr; + return -1; +} + + +/** + * g_data_input_stream_read_line: + * @stream: a given #GDataInputStream. + * @length: (out) (optional): a #gsize to get the length of the data read in. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads a line from the data input stream. Note that no encoding + * checks or conversion is performed; the input is not guaranteed to + * be UTF-8, and may in fact have embedded NUL characters. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (nullable) (transfer full) (array zero-terminated=1) (element-type guint8): + * a NUL terminated byte array with the line that was read in + * (without the newlines). Set @length to a #gsize to get the length + * of the read line. On an error, it will return %NULL and @error + * will be set. If there's no content to read, it will still return + * %NULL, but @error won't be set. + **/ +char * +g_data_input_stream_read_line (GDataInputStream *stream, + gsize *length, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStream *bstream; + gsize checked; + gboolean last_saw_cr; + gssize found_pos; + gssize res; + int newline_len; + char *line; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL); + + bstream = G_BUFFERED_INPUT_STREAM (stream); + + newline_len = 0; + checked = 0; + last_saw_cr = FALSE; + + while ((found_pos = scan_for_newline (stream, &checked, &last_saw_cr, &newline_len)) == -1) + { + if (g_buffered_input_stream_get_available (bstream) == + g_buffered_input_stream_get_buffer_size (bstream)) + g_buffered_input_stream_set_buffer_size (bstream, + 2 * g_buffered_input_stream_get_buffer_size (bstream)); + + res = g_buffered_input_stream_fill (bstream, -1, cancellable, error); + if (res < 0) + return NULL; + if (res == 0) + { + /* End of stream */ + if (g_buffered_input_stream_get_available (bstream) == 0) + { + if (length) + *length = 0; + return NULL; + } + else + { + found_pos = checked; + newline_len = 0; + break; + } + } + } + + line = g_malloc (found_pos + newline_len + 1); + + res = g_input_stream_read (G_INPUT_STREAM (stream), + line, + found_pos + newline_len, + NULL, NULL); + if (length) + *length = (gsize)found_pos; + g_warn_if_fail (res == found_pos + newline_len); + line[found_pos] = 0; + + return line; +} + +/** + * g_data_input_stream_read_line_utf8: + * @stream: a given #GDataInputStream. + * @length: (out) (optional): a #gsize to get the length of the data read in. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads a UTF-8 encoded line from the data input stream. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (nullable) (transfer full): a NUL terminated UTF-8 string + * with the line that was read in (without the newlines). Set + * @length to a #gsize to get the length of the read line. On an + * error, it will return %NULL and @error will be set. For UTF-8 + * conversion errors, the set error domain is %G_CONVERT_ERROR. If + * there's no content to read, it will still return %NULL, but @error + * won't be set. + * + * Since: 2.30 + **/ +char * +g_data_input_stream_read_line_utf8 (GDataInputStream *stream, + gsize *length, + GCancellable *cancellable, + GError **error) +{ + char *res; + + res = g_data_input_stream_read_line (stream, length, cancellable, error); + if (!res) + return NULL; + + if (!g_utf8_validate (res, -1, NULL)) + { + g_set_error_literal (error, G_CONVERT_ERROR, + G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + g_free (res); + return NULL; + } + return res; +} + +static gssize +scan_for_chars (GDataInputStream *stream, + gsize *checked_out, + const char *stop_chars, + gsize stop_chars_len) +{ + GBufferedInputStream *bstream; + const char *buffer; + gsize start, end, peeked; + gsize i; + gsize available, checked; + const char *stop_char; + const char *stop_end; + + bstream = G_BUFFERED_INPUT_STREAM (stream); + stop_end = stop_chars + stop_chars_len; + + checked = *checked_out; + + start = checked; + buffer = (const char *)g_buffered_input_stream_peek_buffer (bstream, &available) + start; + end = available; + peeked = end - start; + + for (i = 0; checked < available && i < peeked; i++) + { + for (stop_char = stop_chars; stop_char != stop_end; stop_char++) + { + if (buffer[i] == *stop_char) + return (start + i); + } + } + + checked = end; + + *checked_out = checked; + return -1; +} + +/** + * g_data_input_stream_read_until: + * @stream: a given #GDataInputStream. + * @stop_chars: characters to terminate the read. + * @length: (out) (optional): a #gsize to get the length of the data read in. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting. + * + * Reads a string from the data input stream, up to the first + * occurrence of any of the stop characters. + * + * Note that, in contrast to g_data_input_stream_read_until_async(), + * this function consumes the stop character that it finds. + * + * Don't use this function in new code. Its functionality is + * inconsistent with g_data_input_stream_read_until_async(). Both + * functions will be marked as deprecated in a future release. Use + * g_data_input_stream_read_upto() instead, but note that that function + * does not consume the stop character. + * + * Returns: (transfer full): a string with the data that was read + * before encountering any of the stop characters. Set @length to + * a #gsize to get the length of the string. This function will + * return %NULL on an error. + * Deprecated: 2.56: Use g_data_input_stream_read_upto() instead, which has more + * consistent behaviour regarding the stop character. + */ +char * +g_data_input_stream_read_until (GDataInputStream *stream, + const gchar *stop_chars, + gsize *length, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStream *bstream; + gchar *result; + + bstream = G_BUFFERED_INPUT_STREAM (stream); + + result = g_data_input_stream_read_upto (stream, stop_chars, -1, + length, cancellable, error); + + /* If we're not at end of stream then we have a stop_char to consume. */ + if (result != NULL && g_buffered_input_stream_get_available (bstream) > 0) + { + gsize res G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + gchar b; + + res = g_input_stream_read (G_INPUT_STREAM (stream), &b, 1, NULL, NULL); + g_assert (res == 1); + } + + return result; +} + +typedef struct +{ + gboolean last_saw_cr; + gsize checked; + + gchar *stop_chars; + gsize stop_chars_len; + gsize length; +} GDataInputStreamReadData; + +static void +g_data_input_stream_read_complete (GTask *task, + gsize read_length, + gsize skip_length) +{ + GDataInputStreamReadData *data = g_task_get_task_data (task); + GInputStream *stream = g_task_get_source_object (task); + char *line = NULL; + + if (read_length || skip_length) + { + gssize bytes; + + data->length = read_length; + line = g_malloc (read_length + 1); + line[read_length] = '\0'; + + /* we already checked the buffer. this shouldn't fail. */ + bytes = g_input_stream_read (stream, line, read_length, NULL, NULL); + g_assert_cmpint (bytes, ==, read_length); + + bytes = g_input_stream_skip (stream, skip_length, NULL, NULL); + g_assert_cmpint (bytes, ==, skip_length); + } + + g_task_return_pointer (task, line, g_free); + g_object_unref (task); +} + +static void +g_data_input_stream_read_line_ready (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + GDataInputStreamReadData *data = g_task_get_task_data (task); + GBufferedInputStream *buffer = g_task_get_source_object (task); + gssize found_pos; + gint newline_len; + + if (result) + /* this is a callback. finish the async call. */ + { + GError *error = NULL; + gssize bytes; + + bytes = g_buffered_input_stream_fill_finish (buffer, result, &error); + + if (bytes <= 0) + { + if (bytes < 0) + /* stream error. */ + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_data_input_stream_read_complete (task, data->checked, 0); + return; + } + + /* only proceed if we got more bytes... */ + } + + if (data->stop_chars) + { + found_pos = scan_for_chars (G_DATA_INPUT_STREAM (buffer), + &data->checked, + data->stop_chars, + data->stop_chars_len); + newline_len = 0; + } + else + found_pos = scan_for_newline (G_DATA_INPUT_STREAM (buffer), &data->checked, + &data->last_saw_cr, &newline_len); + + if (found_pos == -1) + /* didn't find a full line; need to buffer some more bytes */ + { + gsize size; + + size = g_buffered_input_stream_get_buffer_size (buffer); + + if (g_buffered_input_stream_get_available (buffer) == size) + /* need to grow the buffer */ + g_buffered_input_stream_set_buffer_size (buffer, size * 2); + + /* try again */ + g_buffered_input_stream_fill_async (buffer, -1, + g_task_get_priority (task), + g_task_get_cancellable (task), + g_data_input_stream_read_line_ready, + user_data); + } + else + { + /* read the line and the EOL. no error is possible. */ + g_data_input_stream_read_complete (task, found_pos, newline_len); + } +} + +static void +g_data_input_stream_read_data_free (gpointer user_data) +{ + GDataInputStreamReadData *data = user_data; + + g_free (data->stop_chars); + g_slice_free (GDataInputStreamReadData, data); +} + +static void +g_data_input_stream_read_async (GDataInputStream *stream, + const gchar *stop_chars, + gssize stop_chars_len, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDataInputStreamReadData *data; + GTask *task; + gsize stop_chars_len_unsigned; + + data = g_slice_new0 (GDataInputStreamReadData); + + if (stop_chars_len < 0) + stop_chars_len_unsigned = strlen (stop_chars); + else + stop_chars_len_unsigned = (gsize) stop_chars_len; + + data->stop_chars = g_memdup2 (stop_chars, stop_chars_len_unsigned); + data->stop_chars_len = stop_chars_len_unsigned; + data->last_saw_cr = FALSE; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_data_input_stream_read_async); + g_task_set_task_data (task, data, g_data_input_stream_read_data_free); + g_task_set_priority (task, io_priority); + + g_data_input_stream_read_line_ready (NULL, NULL, task); +} + +static gchar * +g_data_input_stream_read_finish (GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error) +{ + GTask *task = G_TASK (result); + gchar *line; + + line = g_task_propagate_pointer (task, error); + + if (length && line) + { + GDataInputStreamReadData *data = g_task_get_task_data (task); + + *length = data->length; + } + + return line; +} + +/** + * g_data_input_stream_read_line_async: + * @stream: a given #GDataInputStream. + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied. + * @user_data: (closure): the data to pass to callback function. + * + * The asynchronous version of g_data_input_stream_read_line(). It is + * an error to have two outstanding calls to this function. + * + * When the operation is finished, @callback will be called. You + * can then call g_data_input_stream_read_line_finish() to get + * the result of the operation. + * + * Since: 2.20 + */ +void +g_data_input_stream_read_line_async (GDataInputStream *stream, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + g_data_input_stream_read_async (stream, NULL, 0, io_priority, + cancellable, callback, user_data); +} + +/** + * g_data_input_stream_read_until_async: + * @stream: a given #GDataInputStream. + * @stop_chars: characters to terminate the read. + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied. + * @user_data: (closure): the data to pass to callback function. + * + * The asynchronous version of g_data_input_stream_read_until(). + * It is an error to have two outstanding calls to this function. + * + * Note that, in contrast to g_data_input_stream_read_until(), + * this function does not consume the stop character that it finds. You + * must read it for yourself. + * + * When the operation is finished, @callback will be called. You + * can then call g_data_input_stream_read_until_finish() to get + * the result of the operation. + * + * Don't use this function in new code. Its functionality is + * inconsistent with g_data_input_stream_read_until(). Both functions + * will be marked as deprecated in a future release. Use + * g_data_input_stream_read_upto_async() instead. + * + * Since: 2.20 + * Deprecated: 2.56: Use g_data_input_stream_read_upto_async() instead, which + * has more consistent behaviour regarding the stop character. + */ +void +g_data_input_stream_read_until_async (GDataInputStream *stream, + const gchar *stop_chars, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_return_if_fail (stop_chars != NULL); + + g_data_input_stream_read_async (stream, stop_chars, -1, io_priority, + cancellable, callback, user_data); +} + +/** + * g_data_input_stream_read_line_finish: + * @stream: a given #GDataInputStream. + * @result: the #GAsyncResult that was provided to the callback. + * @length: (out) (optional): a #gsize to get the length of the data read in. + * @error: #GError for error reporting. + * + * Finish an asynchronous call started by + * g_data_input_stream_read_line_async(). Note the warning about + * string encoding in g_data_input_stream_read_line() applies here as + * well. + * + * Returns: (nullable) (transfer full) (array zero-terminated=1) (element-type guint8): + * a NUL-terminated byte array with the line that was read in + * (without the newlines). Set @length to a #gsize to get the length + * of the read line. On an error, it will return %NULL and @error + * will be set. If there's no content to read, it will still return + * %NULL, but @error won't be set. + * + * Since: 2.20 + */ +gchar * +g_data_input_stream_read_line_finish (GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), NULL); + + return g_data_input_stream_read_finish (stream, result, length, error); +} + +/** + * g_data_input_stream_read_line_finish_utf8: + * @stream: a given #GDataInputStream. + * @result: the #GAsyncResult that was provided to the callback. + * @length: (out) (optional): a #gsize to get the length of the data read in. + * @error: #GError for error reporting. + * + * Finish an asynchronous call started by + * g_data_input_stream_read_line_async(). + * + * Returns: (nullable) (transfer full): a string with the line that + * was read in (without the newlines). Set @length to a #gsize to + * get the length of the read line. On an error, it will return + * %NULL and @error will be set. For UTF-8 conversion errors, the set + * error domain is %G_CONVERT_ERROR. If there's no content to read, + * it will still return %NULL, but @error won't be set. + * + * Since: 2.30 + */ +gchar * +g_data_input_stream_read_line_finish_utf8 (GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error) +{ + gchar *res; + + res = g_data_input_stream_read_line_finish (stream, result, length, error); + if (!res) + return NULL; + + if (!g_utf8_validate (res, -1, NULL)) + { + g_set_error_literal (error, G_CONVERT_ERROR, + G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + g_free (res); + return NULL; + } + return res; +} + +/** + * g_data_input_stream_read_until_finish: + * @stream: a given #GDataInputStream. + * @result: the #GAsyncResult that was provided to the callback. + * @length: (out) (optional): a #gsize to get the length of the data read in. + * @error: #GError for error reporting. + * + * Finish an asynchronous call started by + * g_data_input_stream_read_until_async(). + * + * Since: 2.20 + * + * Returns: (transfer full): a string with the data that was read + * before encountering any of the stop characters. Set @length to + * a #gsize to get the length of the string. This function will + * return %NULL on an error. + * Deprecated: 2.56: Use g_data_input_stream_read_upto_finish() instead, which + * has more consistent behaviour regarding the stop character. + */ +gchar * +g_data_input_stream_read_until_finish (GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), NULL); + + return g_data_input_stream_read_finish (stream, result, length, error); +} + +/** + * g_data_input_stream_read_upto: + * @stream: a #GDataInputStream + * @stop_chars: characters to terminate the read + * @stop_chars_len: length of @stop_chars. May be -1 if @stop_chars is + * nul-terminated + * @length: (out) (optional): a #gsize to get the length of the data read in + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @error: #GError for error reporting + * + * Reads a string from the data input stream, up to the first + * occurrence of any of the stop characters. + * + * In contrast to g_data_input_stream_read_until(), this function + * does not consume the stop character. You have to use + * g_data_input_stream_read_byte() to get it before calling + * g_data_input_stream_read_upto() again. + * + * Note that @stop_chars may contain '\0' if @stop_chars_len is + * specified. + * + * The returned string will always be nul-terminated on success. + * + * Returns: (transfer full): a string with the data that was read + * before encountering any of the stop characters. Set @length to + * a #gsize to get the length of the string. This function will + * return %NULL on an error + * + * Since: 2.26 + */ +char * +g_data_input_stream_read_upto (GDataInputStream *stream, + const gchar *stop_chars, + gssize stop_chars_len, + gsize *length, + GCancellable *cancellable, + GError **error) +{ + GBufferedInputStream *bstream; + gsize checked; + gssize found_pos; + gssize res; + char *data_until; + gsize stop_chars_len_unsigned; + + g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL); + + if (stop_chars_len < 0) + stop_chars_len_unsigned = strlen (stop_chars); + else + stop_chars_len_unsigned = (gsize) stop_chars_len; + + bstream = G_BUFFERED_INPUT_STREAM (stream); + + checked = 0; + + while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len_unsigned)) == -1) + { + if (g_buffered_input_stream_get_available (bstream) == + g_buffered_input_stream_get_buffer_size (bstream)) + g_buffered_input_stream_set_buffer_size (bstream, + 2 * g_buffered_input_stream_get_buffer_size (bstream)); + + res = g_buffered_input_stream_fill (bstream, -1, cancellable, error); + if (res < 0) + return NULL; + if (res == 0) + { + /* End of stream */ + if (g_buffered_input_stream_get_available (bstream) == 0) + { + if (length) + *length = 0; + return NULL; + } + else + { + found_pos = checked; + break; + } + } + } + + data_until = g_malloc (found_pos + 1); + + res = g_input_stream_read (G_INPUT_STREAM (stream), + data_until, + found_pos, + NULL, NULL); + if (length) + *length = (gsize)found_pos; + g_warn_if_fail (res == found_pos); + data_until[found_pos] = 0; + + return data_until; +} + +/** + * g_data_input_stream_read_upto_async: + * @stream: a #GDataInputStream + * @stop_chars: characters to terminate the read + * @stop_chars_len: length of @stop_chars. May be -1 if @stop_chars is + * nul-terminated + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * The asynchronous version of g_data_input_stream_read_upto(). + * It is an error to have two outstanding calls to this function. + * + * In contrast to g_data_input_stream_read_until(), this function + * does not consume the stop character. You have to use + * g_data_input_stream_read_byte() to get it before calling + * g_data_input_stream_read_upto() again. + * + * Note that @stop_chars may contain '\0' if @stop_chars_len is + * specified. + * + * When the operation is finished, @callback will be called. You + * can then call g_data_input_stream_read_upto_finish() to get + * the result of the operation. + * + * Since: 2.26 + */ +void +g_data_input_stream_read_upto_async (GDataInputStream *stream, + const gchar *stop_chars, + gssize stop_chars_len, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_return_if_fail (stop_chars != NULL); + + g_data_input_stream_read_async (stream, stop_chars, stop_chars_len, io_priority, + cancellable, callback, user_data); +} + +/** + * g_data_input_stream_read_upto_finish: + * @stream: a #GDataInputStream + * @result: the #GAsyncResult that was provided to the callback + * @length: (out) (optional): a #gsize to get the length of the data read in + * @error: #GError for error reporting + * + * Finish an asynchronous call started by + * g_data_input_stream_read_upto_async(). + * + * Note that this function does not consume the stop character. You + * have to use g_data_input_stream_read_byte() to get it before calling + * g_data_input_stream_read_upto_async() again. + * + * The returned string will always be nul-terminated on success. + * + * Returns: (transfer full): a string with the data that was read + * before encountering any of the stop characters. Set @length to + * a #gsize to get the length of the string. This function will + * return %NULL on an error. + * + * Since: 2.24 + */ +gchar * +g_data_input_stream_read_upto_finish (GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), NULL); + + return g_data_input_stream_read_finish (stream, result, length, error); +} diff --git a/gio/gdatainputstream.h b/gio/gdatainputstream.h new file mode 100644 index 0000000..3ad3b82 --- /dev/null +++ b/gio/gdatainputstream.h @@ -0,0 +1,180 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_DATA_INPUT_STREAM_H__ +#define __G_DATA_INPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DATA_INPUT_STREAM (g_data_input_stream_get_type ()) +#define G_DATA_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DATA_INPUT_STREAM, GDataInputStream)) +#define G_DATA_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DATA_INPUT_STREAM, GDataInputStreamClass)) +#define G_IS_DATA_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DATA_INPUT_STREAM)) +#define G_IS_DATA_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DATA_INPUT_STREAM)) +#define G_DATA_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DATA_INPUT_STREAM, GDataInputStreamClass)) + +/** + * GDataInputStream: + * + * An implementation of #GBufferedInputStream that allows for high-level + * data manipulation of arbitrary data (including binary operations). + **/ +typedef struct _GDataInputStreamClass GDataInputStreamClass; +typedef struct _GDataInputStreamPrivate GDataInputStreamPrivate; + +struct _GDataInputStream +{ + GBufferedInputStream parent_instance; + + /*< private >*/ + GDataInputStreamPrivate *priv; +}; + +struct _GDataInputStreamClass +{ + GBufferedInputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_data_input_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDataInputStream * g_data_input_stream_new (GInputStream *base_stream); + +GLIB_AVAILABLE_IN_ALL +void g_data_input_stream_set_byte_order (GDataInputStream *stream, + GDataStreamByteOrder order); +GLIB_AVAILABLE_IN_ALL +GDataStreamByteOrder g_data_input_stream_get_byte_order (GDataInputStream *stream); +GLIB_AVAILABLE_IN_ALL +void g_data_input_stream_set_newline_type (GDataInputStream *stream, + GDataStreamNewlineType type); +GLIB_AVAILABLE_IN_ALL +GDataStreamNewlineType g_data_input_stream_get_newline_type (GDataInputStream *stream); +GLIB_AVAILABLE_IN_ALL +guchar g_data_input_stream_read_byte (GDataInputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gint16 g_data_input_stream_read_int16 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +guint16 g_data_input_stream_read_uint16 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gint32 g_data_input_stream_read_int32 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +guint32 g_data_input_stream_read_uint32 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gint64 g_data_input_stream_read_int64 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +guint64 g_data_input_stream_read_uint64 (GDataInputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +char * g_data_input_stream_read_line (GDataInputStream *stream, + gsize *length, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_30 +char * g_data_input_stream_read_line_utf8 (GDataInputStream *stream, + gsize *length, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_data_input_stream_read_line_async (GDataInputStream *stream, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +char * g_data_input_stream_read_line_finish (GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error); +GLIB_AVAILABLE_IN_2_30 +char * g_data_input_stream_read_line_finish_utf8(GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error); +GLIB_DEPRECATED_IN_2_56_FOR (g_data_input_stream_read_upto) +char * g_data_input_stream_read_until (GDataInputStream *stream, + const gchar *stop_chars, + gsize *length, + GCancellable *cancellable, + GError **error); +GLIB_DEPRECATED_IN_2_56_FOR (g_data_input_stream_read_upto_async) +void g_data_input_stream_read_until_async (GDataInputStream *stream, + const gchar *stop_chars, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_DEPRECATED_IN_2_56_FOR (g_data_input_stream_read_upto_finish) +char * g_data_input_stream_read_until_finish (GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error); + +GLIB_AVAILABLE_IN_ALL +char * g_data_input_stream_read_upto (GDataInputStream *stream, + const gchar *stop_chars, + gssize stop_chars_len, + gsize *length, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_data_input_stream_read_upto_async (GDataInputStream *stream, + const gchar *stop_chars, + gssize stop_chars_len, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +char * g_data_input_stream_read_upto_finish (GDataInputStream *stream, + GAsyncResult *result, + gsize *length, + GError **error); + +G_END_DECLS + +#endif /* __G_DATA_INPUT_STREAM_H__ */ diff --git a/gio/gdataoutputstream.c b/gio/gdataoutputstream.c new file mode 100644 index 0000000..4c2d251 --- /dev/null +++ b/gio/gdataoutputstream.c @@ -0,0 +1,598 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include +#include "gdataoutputstream.h" +#include "gseekable.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gdataoutputstream + * @short_description: Data Output Stream + * @include: gio/gio.h + * @see_also: #GOutputStream + * + * Data output stream implements #GOutputStream and includes functions for + * writing data directly to an output stream. + * + **/ + + + +struct _GDataOutputStreamPrivate { + GDataStreamByteOrder byte_order; +}; + +enum { + PROP_0, + PROP_BYTE_ORDER +}; + +static void g_data_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_data_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void g_data_output_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_data_output_stream_tell (GSeekable *seekable); +static gboolean g_data_output_stream_can_seek (GSeekable *seekable); +static gboolean g_data_output_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_data_output_stream_can_truncate (GSeekable *seekable); +static gboolean g_data_output_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); + +G_DEFINE_TYPE_WITH_CODE (GDataOutputStream, + g_data_output_stream, + G_TYPE_FILTER_OUTPUT_STREAM, + G_ADD_PRIVATE (GDataOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_data_output_stream_seekable_iface_init)) + + +static void +g_data_output_stream_class_init (GDataOutputStreamClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = g_data_output_stream_get_property; + object_class->set_property = g_data_output_stream_set_property; + + /** + * GDataOutputStream:byte-order: + * + * Determines the byte ordering that is used when writing + * multi-byte entities (such as integers) to the stream. + */ + g_object_class_install_property (object_class, + PROP_BYTE_ORDER, + g_param_spec_enum ("byte-order", + P_("Byte order"), + P_("The byte order"), + G_TYPE_DATA_STREAM_BYTE_ORDER, + G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN, + G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB)); + +} + +static void +g_data_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDataOutputStream *dstream; + + dstream = G_DATA_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_BYTE_ORDER: + g_data_output_stream_set_byte_order (dstream, g_value_get_enum (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_data_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDataOutputStreamPrivate *priv; + GDataOutputStream *dstream; + + dstream = G_DATA_OUTPUT_STREAM (object); + priv = dstream->priv; + + switch (prop_id) + { + case PROP_BYTE_ORDER: + g_value_set_enum (value, priv->byte_order); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_data_output_stream_init (GDataOutputStream *stream) +{ + stream->priv = g_data_output_stream_get_instance_private (stream); + stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN; +} + +static void +g_data_output_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_data_output_stream_tell; + iface->can_seek = g_data_output_stream_can_seek; + iface->seek = g_data_output_stream_seek; + iface->can_truncate = g_data_output_stream_can_truncate; + iface->truncate_fn = g_data_output_stream_truncate; +} + +/** + * g_data_output_stream_new: + * @base_stream: a #GOutputStream. + * + * Creates a new data output stream for @base_stream. + * + * Returns: #GDataOutputStream. + **/ +GDataOutputStream * +g_data_output_stream_new (GOutputStream *base_stream) +{ + GDataOutputStream *stream; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL); + + stream = g_object_new (G_TYPE_DATA_OUTPUT_STREAM, + "base-stream", base_stream, + NULL); + + return stream; +} + +/** + * g_data_output_stream_set_byte_order: + * @stream: a #GDataOutputStream. + * @order: a %GDataStreamByteOrder. + * + * Sets the byte order of the data output stream to @order. + **/ +void +g_data_output_stream_set_byte_order (GDataOutputStream *stream, + GDataStreamByteOrder order) +{ + GDataOutputStreamPrivate *priv; + g_return_if_fail (G_IS_DATA_OUTPUT_STREAM (stream)); + priv = stream->priv; + if (priv->byte_order != order) + { + priv->byte_order = order; + g_object_notify (G_OBJECT (stream), "byte-order"); + } +} + +/** + * g_data_output_stream_get_byte_order: + * @stream: a #GDataOutputStream. + * + * Gets the byte order for the stream. + * + * Returns: the #GDataStreamByteOrder for the @stream. + **/ +GDataStreamByteOrder +g_data_output_stream_get_byte_order (GDataOutputStream *stream) +{ + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN); + + return stream->priv->byte_order; +} + +/** + * g_data_output_stream_put_byte: + * @stream: a #GDataOutputStream. + * @data: a #guchar. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Puts a byte into the output stream. + * + * Returns: %TRUE if @data was successfully added to the @stream. + **/ +gboolean +g_data_output_stream_put_byte (GDataOutputStream *stream, + guchar data, + GCancellable *cancellable, + GError **error) +{ + gsize bytes_written; + + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); + + return g_output_stream_write_all (G_OUTPUT_STREAM (stream), + &data, 1, + &bytes_written, + cancellable, error); +} + +/** + * g_data_output_stream_put_int16: + * @stream: a #GDataOutputStream. + * @data: a #gint16. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Puts a signed 16-bit integer into the output stream. + * + * Returns: %TRUE if @data was successfully added to the @stream. + **/ +gboolean +g_data_output_stream_put_int16 (GDataOutputStream *stream, + gint16 data, + GCancellable *cancellable, + GError **error) +{ + gsize bytes_written; + + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); + + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GINT16_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GINT16_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_output_stream_write_all (G_OUTPUT_STREAM (stream), + &data, 2, + &bytes_written, + cancellable, error); +} + +/** + * g_data_output_stream_put_uint16: + * @stream: a #GDataOutputStream. + * @data: a #guint16. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Puts an unsigned 16-bit integer into the output stream. + * + * Returns: %TRUE if @data was successfully added to the @stream. + **/ +gboolean +g_data_output_stream_put_uint16 (GDataOutputStream *stream, + guint16 data, + GCancellable *cancellable, + GError **error) +{ + gsize bytes_written; + + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); + + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GUINT16_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GUINT16_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_output_stream_write_all (G_OUTPUT_STREAM (stream), + &data, 2, + &bytes_written, + cancellable, error); +} + +/** + * g_data_output_stream_put_int32: + * @stream: a #GDataOutputStream. + * @data: a #gint32. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Puts a signed 32-bit integer into the output stream. + * + * Returns: %TRUE if @data was successfully added to the @stream. + **/ +gboolean +g_data_output_stream_put_int32 (GDataOutputStream *stream, + gint32 data, + GCancellable *cancellable, + GError **error) +{ + gsize bytes_written; + + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); + + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GINT32_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GINT32_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_output_stream_write_all (G_OUTPUT_STREAM (stream), + &data, 4, + &bytes_written, + cancellable, error); +} + +/** + * g_data_output_stream_put_uint32: + * @stream: a #GDataOutputStream. + * @data: a #guint32. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Puts an unsigned 32-bit integer into the stream. + * + * Returns: %TRUE if @data was successfully added to the @stream. + **/ +gboolean +g_data_output_stream_put_uint32 (GDataOutputStream *stream, + guint32 data, + GCancellable *cancellable, + GError **error) +{ + gsize bytes_written; + + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); + + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GUINT32_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GUINT32_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_output_stream_write_all (G_OUTPUT_STREAM (stream), + &data, 4, + &bytes_written, + cancellable, error); +} + +/** + * g_data_output_stream_put_int64: + * @stream: a #GDataOutputStream. + * @data: a #gint64. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Puts a signed 64-bit integer into the stream. + * + * Returns: %TRUE if @data was successfully added to the @stream. + **/ +gboolean +g_data_output_stream_put_int64 (GDataOutputStream *stream, + gint64 data, + GCancellable *cancellable, + GError **error) +{ + gsize bytes_written; + + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); + + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GINT64_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GINT64_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_output_stream_write_all (G_OUTPUT_STREAM (stream), + &data, 8, + &bytes_written, + cancellable, error); +} + +/** + * g_data_output_stream_put_uint64: + * @stream: a #GDataOutputStream. + * @data: a #guint64. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Puts an unsigned 64-bit integer into the stream. + * + * Returns: %TRUE if @data was successfully added to the @stream. + **/ +gboolean +g_data_output_stream_put_uint64 (GDataOutputStream *stream, + guint64 data, + GCancellable *cancellable, + GError **error) +{ + gsize bytes_written; + + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); + + switch (stream->priv->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GUINT64_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GUINT64_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_output_stream_write_all (G_OUTPUT_STREAM (stream), + &data, 8, + &bytes_written, + cancellable, error); +} + +/** + * g_data_output_stream_put_string: + * @stream: a #GDataOutputStream. + * @str: a string. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Puts a string into the output stream. + * + * Returns: %TRUE if @string was successfully added to the @stream. + **/ +gboolean +g_data_output_stream_put_string (GDataOutputStream *stream, + const char *str, + GCancellable *cancellable, + GError **error) +{ + gsize bytes_written; + + g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (str != NULL, FALSE); + + return g_output_stream_write_all (G_OUTPUT_STREAM (stream), + str, strlen (str), + &bytes_written, + cancellable, error); +} + +static goffset +g_data_output_stream_tell (GSeekable *seekable) +{ + GOutputStream *base_stream; + GSeekable *base_stream_seekable; + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + if (!G_IS_SEEKABLE (base_stream)) + return 0; + base_stream_seekable = G_SEEKABLE (base_stream); + return g_seekable_tell (base_stream_seekable); +} + +static gboolean +g_data_output_stream_can_seek (GSeekable *seekable) +{ + GOutputStream *base_stream; + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream)); +} + +static gboolean +g_data_output_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GOutputStream *base_stream; + GSeekable *base_stream_seekable; + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + if (!G_IS_SEEKABLE (base_stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Seek not supported on base stream")); + return FALSE; + } + + base_stream_seekable = G_SEEKABLE (base_stream); + return g_seekable_seek (base_stream_seekable, offset, type, cancellable, error); +} + +static gboolean +g_data_output_stream_can_truncate (GSeekable *seekable) +{ + GOutputStream *base_stream; + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + return G_IS_SEEKABLE (base_stream) && g_seekable_can_truncate (G_SEEKABLE (base_stream)); +} + +static gboolean +g_data_output_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error) +{ + GOutputStream *base_stream; + GSeekable *base_stream_seekable; + + base_stream = G_FILTER_OUTPUT_STREAM (seekable)->base_stream; + if (!G_IS_SEEKABLE (base_stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Truncate not supported on base stream")); + return FALSE; + } + + base_stream_seekable = G_SEEKABLE (base_stream); + return g_seekable_truncate (base_stream_seekable, offset, cancellable, error); +} diff --git a/gio/gdataoutputstream.h b/gio/gdataoutputstream.h new file mode 100644 index 0000000..62cf7b5 --- /dev/null +++ b/gio/gdataoutputstream.h @@ -0,0 +1,125 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_DATA_OUTPUT_STREAM_H__ +#define __G_DATA_OUTPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DATA_OUTPUT_STREAM (g_data_output_stream_get_type ()) +#define G_DATA_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStream)) +#define G_DATA_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStreamClass)) +#define G_IS_DATA_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DATA_OUTPUT_STREAM)) +#define G_IS_DATA_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DATA_OUTPUT_STREAM)) +#define G_DATA_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStreamClass)) + +/** + * GDataOutputStream: + * + * An implementation of #GBufferedOutputStream that allows for high-level + * data manipulation of arbitrary data (including binary operations). + **/ +typedef struct _GDataOutputStream GDataOutputStream; +typedef struct _GDataOutputStreamClass GDataOutputStreamClass; +typedef struct _GDataOutputStreamPrivate GDataOutputStreamPrivate; + +struct _GDataOutputStream +{ + GFilterOutputStream parent_instance; + + /*< private >*/ + GDataOutputStreamPrivate *priv; +}; + +struct _GDataOutputStreamClass +{ + GFilterOutputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_data_output_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDataOutputStream * g_data_output_stream_new (GOutputStream *base_stream); + +GLIB_AVAILABLE_IN_ALL +void g_data_output_stream_set_byte_order (GDataOutputStream *stream, + GDataStreamByteOrder order); +GLIB_AVAILABLE_IN_ALL +GDataStreamByteOrder g_data_output_stream_get_byte_order (GDataOutputStream *stream); + +GLIB_AVAILABLE_IN_ALL +gboolean g_data_output_stream_put_byte (GDataOutputStream *stream, + guchar data, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_data_output_stream_put_int16 (GDataOutputStream *stream, + gint16 data, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_data_output_stream_put_uint16 (GDataOutputStream *stream, + guint16 data, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_data_output_stream_put_int32 (GDataOutputStream *stream, + gint32 data, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_data_output_stream_put_uint32 (GDataOutputStream *stream, + guint32 data, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_data_output_stream_put_int64 (GDataOutputStream *stream, + gint64 data, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_data_output_stream_put_uint64 (GDataOutputStream *stream, + guint64 data, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_data_output_stream_put_string (GDataOutputStream *stream, + const char *str, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* __G_DATA_OUTPUT_STREAM_H__ */ diff --git a/gio/gdbus-2.0/codegen/.flake8 b/gio/gdbus-2.0/codegen/.flake8 new file mode 100644 index 0000000..9450a28 --- /dev/null +++ b/gio/gdbus-2.0/codegen/.flake8 @@ -0,0 +1,4 @@ +[flake8] +# We are generating long lines through templates +max-line-length = 120 +exclude = __pycache__ diff --git a/gio/gdbus-2.0/codegen/.gitignore b/gio/gdbus-2.0/codegen/.gitignore new file mode 100644 index 0000000..0015c09 --- /dev/null +++ b/gio/gdbus-2.0/codegen/.gitignore @@ -0,0 +1,3 @@ +*.pyc +config.py +gdbus-codegen diff --git a/gio/gdbus-2.0/codegen/__init__.py b/gio/gdbus-2.0/codegen/__init__.py new file mode 100644 index 0000000..ed324d7 --- /dev/null +++ b/gio/gdbus-2.0/codegen/__init__.py @@ -0,0 +1,29 @@ +# -*- Mode: Python -*- + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +import os + +builddir = os.environ.get("UNINSTALLED_GLIB_BUILDDIR") + +if builddir is not None: + __path__.append( + os.path.abspath(os.path.join(builddir, "gio", "gdbus-2.0", "codegen")) + ) diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py new file mode 100644 index 0000000..d8d9a85 --- /dev/null +++ b/gio/gdbus-2.0/codegen/codegen.py @@ -0,0 +1,5234 @@ +# -*- Mode: Python -*- +# coding=utf-8 + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2018 Red Hat, Inc. +# Copyright (C) 2018 Iñigo Martínez +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +from . import config +from . import utils +from . import dbustypes +from .utils import print_error + +LICENSE_STR = """/* + * This file is generated by gdbus-codegen, do not modify it. + * + * The license of this code is the same as for the D-Bus interface description + * it was derived from. Note that it links to GLib, so must comply with the + * LGPL linking clauses. + */\n""" + + +# Disable line length warnings as wrapping the C code templates would be hard +# flake8: noqa: E501 + + +def generate_namespace(namespace): + ns = namespace + if len(namespace) > 0: + if utils.is_ugly_case(namespace): + ns = namespace.replace("_", "") + ns_upper = namespace.upper() + "_" + ns_lower = namespace.lower() + "_" + else: + ns_upper = utils.camel_case_to_uscore(namespace).upper() + "_" + ns_lower = utils.camel_case_to_uscore(namespace).lower() + "_" + else: + ns_upper = "" + ns_lower = "" + + return (ns, ns_upper, ns_lower) + + +def generate_header_guard(header_name): + # There might be more characters that are safe to use than these, but lets + # stay conservative. + safe_valid_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + return "".join( + map(lambda c: c if c in safe_valid_chars else "_", header_name.upper()) + ) + + +class HeaderCodeGenerator: + def __init__( + self, + ifaces, + namespace, + generate_objmanager, + generate_autocleanup, + header_name, + input_files_basenames, + use_pragma, + glib_min_required, + symbol_decorator, + symbol_decorator_header, + outfile, + ): + self.ifaces = ifaces + self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) + self.generate_objmanager = generate_objmanager + self.generate_autocleanup = generate_autocleanup + self.header_guard = generate_header_guard(header_name) + self.input_files_basenames = input_files_basenames + self.use_pragma = use_pragma + self.glib_min_required = glib_min_required + self.symbol_decorator = symbol_decorator + self.symbol_decorator_header = symbol_decorator_header + self.outfile = outfile + + # ---------------------------------------------------------------------------------------------------- + + def generate_header_preamble(self): + basenames = ", ".join(self.input_files_basenames) + self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) + self.outfile.write("\n") + + if self.use_pragma: + self.outfile.write("#pragma once\n") + else: + self.outfile.write("#ifndef __{!s}__\n".format(self.header_guard)) + self.outfile.write("#define __{!s}__\n".format(self.header_guard)) + + if self.symbol_decorator_header is not None: + self.outfile.write("\n") + self.outfile.write('#include "%s"\n' % self.symbol_decorator_header) + + self.outfile.write("\n") + self.outfile.write("#include \n") + self.outfile.write("\n") + self.outfile.write("G_BEGIN_DECLS\n") + self.outfile.write("\n") + + # ---------------------------------------------------------------------------------------------------- + + def declare_types(self): + for i in self.ifaces: + self.outfile.write("\n") + self.outfile.write( + "/* ------------------------------------------------------------------------ */\n" + ) + self.outfile.write("/* Declarations for %s */\n" % i.name) + self.outfile.write("\n") + + # First the GInterface + self.outfile.write( + "#define %sTYPE_%s (%s_get_type ())\n" + % (i.ns_upper, i.name_upper, i.name_lower) + ) + self.outfile.write( + "#define %s%s(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s, %s))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) + ) + self.outfile.write( + "#define %sIS_%s(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) + ) + self.outfile.write( + "#define %s%s_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_%s, %sIface))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) + ) + self.outfile.write("\n") + self.outfile.write("struct _%s;\n" % (i.camel_name)) + self.outfile.write( + "typedef struct _%s %s;\n" % (i.camel_name, i.camel_name) + ) + self.outfile.write( + "typedef struct _%sIface %sIface;\n" % (i.camel_name, i.camel_name) + ) + self.outfile.write("\n") + self.outfile.write("struct _%sIface\n" % (i.camel_name)) + self.outfile.write("{\n") + self.outfile.write(" GTypeInterface parent_iface;\n") + + function_pointers = {} + + # vfuncs for methods + if len(i.methods) > 0: + self.outfile.write("\n") + for m in i.methods: + key = (m.since, "_method_%s" % m.name_lower) + value = " gboolean (*handle_%s) (\n" % (m.name_lower) + value += " %s *object,\n" % (i.camel_name) + value += " GDBusMethodInvocation *invocation" + if m.unix_fd: + value += ",\n GUnixFDList *fd_list" + for a in m.in_args: + value += ",\n %sarg_%s" % (a.ctype_in, a.name) + value += ");\n\n" + function_pointers[key] = value + + # vfuncs for signals + if len(i.signals) > 0: + self.outfile.write("\n") + for s in i.signals: + key = (s.since, "_signal_%s" % s.name_lower) + value = " void (*%s) (\n" % (s.name_lower) + value += " %s *object" % (i.camel_name) + for a in s.args: + value += ",\n %sarg_%s" % (a.ctype_in, a.name) + value += ");\n\n" + function_pointers[key] = value + + # vfuncs for properties + if len(i.properties) > 0: + self.outfile.write("\n") + for p in i.properties: + key = (p.since, "_prop_get_%s" % p.name_lower) + value = " %s (*get_%s) (%s *object);\n\n" % ( + p.arg.ctype_in, + p.name_lower, + i.camel_name, + ) + function_pointers[key] = value + + # Sort according to @since tag, then name.. this ensures + # that the function pointers don't change order assuming + # judicious use of @since + # + # Also use a proper version comparison function so e.g. + # 10.0 comes after 2.0. + # + # See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5 + # for discussion + for key in sorted(function_pointers.keys(), key=utils.version_cmp_key): + self.outfile.write("%s" % function_pointers[key]) + + self.outfile.write("};\n") + self.outfile.write("\n") + if self.generate_autocleanup == "all": + self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") + self.outfile.write( + "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%s, g_object_unref)\n" + % (i.camel_name) + ) + self.outfile.write("#endif\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GType %s_get_type (void) G_GNUC_CONST;\n" % (i.name_lower) + ) + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GDBusInterfaceInfo *%s_interface_info (void);\n" % (i.name_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "guint %s_override_properties (GObjectClass *klass, guint property_id_begin);\n" + % (i.name_lower) + ) + self.outfile.write("\n") + + # Then method call completion functions + if len(i.methods) > 0: + self.outfile.write("\n") + self.outfile.write("/* D-Bus method call completion functions: */\n") + for m in i.methods: + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if m.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "void %s_complete_%s (\n" + " %s *object,\n" + " GDBusMethodInvocation *invocation" + % (i.name_lower, m.name_lower, i.camel_name) + ) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList *fd_list") + for a in m.out_args: + self.outfile.write(",\n %s%s" % (a.ctype_in, a.name)) + self.outfile.write(");\n") + self.outfile.write("\n") + self.outfile.write("\n") + + # Then signal emission functions + if len(i.signals) > 0: + self.outfile.write("\n") + self.outfile.write("/* D-Bus signal emissions functions: */\n") + for s in i.signals: + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if s.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "void %s_emit_%s (\n" + " %s *object" % (i.name_lower, s.name_lower, i.camel_name) + ) + for a in s.args: + self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) + self.outfile.write(");\n") + self.outfile.write("\n") + self.outfile.write("\n") + + # Then method call declarations + if len(i.methods) > 0: + self.outfile.write("\n") + self.outfile.write("/* D-Bus method calls: */\n") + for m in i.methods: + # async begin + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if m.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "void %s_call_%s (\n" + " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.in_args: + self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) + if self.glib_min_required >= (2, 64): + self.outfile.write( + ",\n GDBusCallFlags call_flags" + ",\n gint timeout_msec" + ) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList *fd_list") + self.outfile.write( + ",\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data);\n" + ) + self.outfile.write("\n") + # async finish + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if m.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "gboolean %s_call_%s_finish (\n" + " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.out_args: + self.outfile.write(",\n %sout_%s" % (a.ctype_out, a.name)) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList **out_fd_list") + self.outfile.write( + ",\n" " GAsyncResult *res,\n" " GError **error);\n" + ) + self.outfile.write("\n") + # sync + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if m.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "gboolean %s_call_%s_sync (\n" + " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.in_args: + self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) + if self.glib_min_required >= (2, 64): + self.outfile.write( + ",\n GDBusCallFlags call_flags" + ",\n gint timeout_msec" + ) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList *fd_list") + for a in m.out_args: + self.outfile.write(",\n %sout_%s" % (a.ctype_out, a.name)) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList **out_fd_list") + self.outfile.write( + ",\n" + " GCancellable *cancellable,\n" + " GError **error);\n" + ) + self.outfile.write("\n") + self.outfile.write("\n") + + # Then the property accessor declarations + if len(i.properties) > 0: + self.outfile.write("\n") + self.outfile.write("/* D-Bus property accessors: */\n") + for p in i.properties: + # getter + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if p.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s%s_get_%s (%s *object);\n" + % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name) + ) + if p.arg.free_func is not None: + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if p.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s%s_dup_%s (%s *object);\n" + % ( + p.arg.ctype_in_dup, + i.name_lower, + p.name_lower, + i.camel_name, + ) + ) + # setter + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if p.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "void %s_set_%s (%s *object, %svalue);\n" + % (i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in) + ) + self.outfile.write("\n") + + # Then the proxy + self.outfile.write("\n") + self.outfile.write("/* ---- */\n") + self.outfile.write("\n") + self.outfile.write( + "#define %sTYPE_%s_PROXY (%s_proxy_get_type ())\n" + % (i.ns_upper, i.name_upper, i.name_lower) + ) + self.outfile.write( + "#define %s%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_PROXY, %sProxy))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) + ) + self.outfile.write( + "#define %s%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_PROXY, %sProxyClass))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) + ) + self.outfile.write( + "#define %s%s_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_PROXY, %sProxyClass))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) + ) + self.outfile.write( + "#define %sIS_%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_PROXY))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) + ) + self.outfile.write( + "#define %sIS_%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_PROXY))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) + ) + self.outfile.write("\n") + self.outfile.write( + "typedef struct _%sProxy %sProxy;\n" % (i.camel_name, i.camel_name) + ) + self.outfile.write( + "typedef struct _%sProxyClass %sProxyClass;\n" + % (i.camel_name, i.camel_name) + ) + self.outfile.write( + "typedef struct _%sProxyPrivate %sProxyPrivate;\n" + % (i.camel_name, i.camel_name) + ) + self.outfile.write("\n") + self.outfile.write("struct _%sProxy\n" % (i.camel_name)) + self.outfile.write("{\n") + self.outfile.write(" /*< private >*/\n") + self.outfile.write(" GDBusProxy parent_instance;\n") + self.outfile.write(" %sProxyPrivate *priv;\n" % (i.camel_name)) + self.outfile.write("};\n") + self.outfile.write("\n") + self.outfile.write("struct _%sProxyClass\n" % (i.camel_name)) + self.outfile.write("{\n") + self.outfile.write(" GDBusProxyClass parent_class;\n") + self.outfile.write("};\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GType %s_proxy_get_type (void) G_GNUC_CONST;\n" % (i.name_lower) + ) + self.outfile.write("\n") + if self.generate_autocleanup in ("objects", "all"): + self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") + self.outfile.write( + "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sProxy, g_object_unref)\n" + % (i.camel_name) + ) + self.outfile.write("#endif\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "void %s_proxy_new (\n" + " GDBusConnection *connection,\n" + " GDBusProxyFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data);\n" % (i.name_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s *%s_proxy_new_finish (\n" + " GAsyncResult *res,\n" + " GError **error);\n" % (i.camel_name, i.name_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s *%s_proxy_new_sync (\n" + " GDBusConnection *connection,\n" + " GDBusProxyFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GError **error);\n" % (i.camel_name, i.name_lower) + ) + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "void %s_proxy_new_for_bus (\n" + " GBusType bus_type,\n" + " GDBusProxyFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data);\n" % (i.name_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s *%s_proxy_new_for_bus_finish (\n" + " GAsyncResult *res,\n" + " GError **error);\n" % (i.camel_name, i.name_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s *%s_proxy_new_for_bus_sync (\n" + " GBusType bus_type,\n" + " GDBusProxyFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GError **error);\n" % (i.camel_name, i.name_lower) + ) + self.outfile.write("\n") + + # Then the skeleton + self.outfile.write("\n") + self.outfile.write("/* ---- */\n") + self.outfile.write("\n") + self.outfile.write( + "#define %sTYPE_%s_SKELETON (%s_skeleton_get_type ())\n" + % (i.ns_upper, i.name_upper, i.name_lower) + ) + self.outfile.write( + "#define %s%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_SKELETON, %sSkeleton))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) + ) + self.outfile.write( + "#define %s%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_SKELETON, %sSkeletonClass))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) + ) + self.outfile.write( + "#define %s%s_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_SKELETON, %sSkeletonClass))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) + ) + self.outfile.write( + "#define %sIS_%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_SKELETON))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) + ) + self.outfile.write( + "#define %sIS_%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_SKELETON))\n" + % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) + ) + self.outfile.write("\n") + self.outfile.write( + "typedef struct _%sSkeleton %sSkeleton;\n" + % (i.camel_name, i.camel_name) + ) + self.outfile.write( + "typedef struct _%sSkeletonClass %sSkeletonClass;\n" + % (i.camel_name, i.camel_name) + ) + self.outfile.write( + "typedef struct _%sSkeletonPrivate %sSkeletonPrivate;\n" + % (i.camel_name, i.camel_name) + ) + self.outfile.write("\n") + self.outfile.write("struct _%sSkeleton\n" % (i.camel_name)) + self.outfile.write("{\n") + self.outfile.write(" /*< private >*/\n") + self.outfile.write(" GDBusInterfaceSkeleton parent_instance;\n") + self.outfile.write(" %sSkeletonPrivate *priv;\n" % (i.camel_name)) + self.outfile.write("};\n") + self.outfile.write("\n") + self.outfile.write("struct _%sSkeletonClass\n" % (i.camel_name)) + self.outfile.write("{\n") + self.outfile.write(" GDBusInterfaceSkeletonClass parent_class;\n") + self.outfile.write("};\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GType %s_skeleton_get_type (void) G_GNUC_CONST;\n" % (i.name_lower) + ) + self.outfile.write("\n") + if self.generate_autocleanup in ("objects", "all"): + self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") + self.outfile.write( + "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sSkeleton, g_object_unref)\n" + % (i.camel_name) + ) + self.outfile.write("#endif\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s *%s_skeleton_new (void);\n" % (i.camel_name, i.name_lower) + ) + + self.outfile.write("\n") + + # Finally, the Object, ObjectProxy, ObjectSkeleton and ObjectManagerClient + if self.generate_objmanager: + self.outfile.write("\n") + self.outfile.write("/* ---- */\n") + self.outfile.write("\n") + self.outfile.write( + "#define %sTYPE_OBJECT (%sobject_get_type ())\n" + % (self.ns_upper, self.ns_lower) + ) + self.outfile.write( + "#define %sOBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT, %sObject))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sIS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT))\n" + % (self.ns_upper, self.ns_upper) + ) + self.outfile.write( + "#define %sOBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_OBJECT, %sObject))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write("\n") + self.outfile.write("struct _%sObject;\n" % (self.namespace)) + self.outfile.write( + "typedef struct _%sObject %sObject;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write( + "typedef struct _%sObjectIface %sObjectIface;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write("\n") + self.outfile.write("struct _%sObjectIface\n" % (self.namespace)) + self.outfile.write("{\n" " GTypeInterface parent_iface;\n" "};\n" "\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GType %sobject_get_type (void) G_GNUC_CONST;\n" "\n" % (self.ns_lower) + ) + if self.generate_autocleanup == "all": + self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") + self.outfile.write( + "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObject, g_object_unref)\n" + % (self.namespace) + ) + self.outfile.write("#endif\n") + self.outfile.write("\n") + for i in self.ifaces: + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s *%sobject_get_%s (%sObject *object);\n" + % ( + i.camel_name, + self.ns_lower, + i.name_upper.lower(), + self.namespace, + ) + ) + for i in self.ifaces: + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "%s *%sobject_peek_%s (%sObject *object);\n" + % ( + i.camel_name, + self.ns_lower, + i.name_upper.lower(), + self.namespace, + ) + ) + self.outfile.write("\n") + self.outfile.write( + "#define %sTYPE_OBJECT_PROXY (%sobject_proxy_get_type ())\n" + % (self.ns_upper, self.ns_lower) + ) + self.outfile.write( + "#define %sOBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_PROXY, %sObjectProxy))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sOBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sOBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sIS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_PROXY))\n" + % (self.ns_upper, self.ns_upper) + ) + self.outfile.write( + "#define %sIS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_PROXY))\n" + % (self.ns_upper, self.ns_upper) + ) + self.outfile.write("\n") + self.outfile.write( + "typedef struct _%sObjectProxy %sObjectProxy;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write( + "typedef struct _%sObjectProxyClass %sObjectProxyClass;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write( + "typedef struct _%sObjectProxyPrivate %sObjectProxyPrivate;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write("\n") + self.outfile.write("struct _%sObjectProxy\n" % (self.namespace)) + self.outfile.write("{\n") + self.outfile.write(" /*< private >*/\n") + self.outfile.write(" GDBusObjectProxy parent_instance;\n") + self.outfile.write(" %sObjectProxyPrivate *priv;\n" % (self.namespace)) + self.outfile.write("};\n") + self.outfile.write("\n") + self.outfile.write("struct _%sObjectProxyClass\n" % (self.namespace)) + self.outfile.write("{\n") + self.outfile.write(" GDBusObjectProxyClass parent_class;\n") + self.outfile.write("};\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GType %sobject_proxy_get_type (void) G_GNUC_CONST;\n" % (self.ns_lower) + ) + self.outfile.write("\n") + if self.generate_autocleanup in ("objects", "all"): + self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") + self.outfile.write( + "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectProxy, g_object_unref)\n" + % (self.namespace) + ) + self.outfile.write("#endif\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "%sObjectProxy *%sobject_proxy_new (GDBusConnection *connection, const gchar *object_path);\n" + % (self.namespace, self.ns_lower) + ) + self.outfile.write("\n") + self.outfile.write( + "#define %sTYPE_OBJECT_SKELETON (%sobject_skeleton_get_type ())\n" + % (self.ns_upper, self.ns_lower) + ) + self.outfile.write( + "#define %sOBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeleton))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sOBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sOBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sIS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_SKELETON))\n" + % (self.ns_upper, self.ns_upper) + ) + self.outfile.write( + "#define %sIS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_SKELETON))\n" + % (self.ns_upper, self.ns_upper) + ) + self.outfile.write("\n") + self.outfile.write( + "typedef struct _%sObjectSkeleton %sObjectSkeleton;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write( + "typedef struct _%sObjectSkeletonClass %sObjectSkeletonClass;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write( + "typedef struct _%sObjectSkeletonPrivate %sObjectSkeletonPrivate;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write("\n") + self.outfile.write("struct _%sObjectSkeleton\n" % (self.namespace)) + self.outfile.write("{\n") + self.outfile.write(" /*< private >*/\n") + self.outfile.write(" GDBusObjectSkeleton parent_instance;\n") + self.outfile.write(" %sObjectSkeletonPrivate *priv;\n" % (self.namespace)) + self.outfile.write("};\n") + self.outfile.write("\n") + self.outfile.write("struct _%sObjectSkeletonClass\n" % (self.namespace)) + self.outfile.write("{\n") + self.outfile.write(" GDBusObjectSkeletonClass parent_class;\n") + self.outfile.write("};\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GType %sobject_skeleton_get_type (void) G_GNUC_CONST;\n" + % (self.ns_lower) + ) + self.outfile.write("\n") + if self.generate_autocleanup in ("objects", "all"): + self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") + self.outfile.write( + "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectSkeleton, g_object_unref)\n" + % (self.namespace) + ) + self.outfile.write("#endif\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "%sObjectSkeleton *%sobject_skeleton_new (const gchar *object_path);\n" + % (self.namespace, self.ns_lower) + ) + for i in self.ifaces: + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + if i.deprecated: + self.outfile.write("G_GNUC_DEPRECATED ") + self.outfile.write( + "void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_);\n" + % ( + self.ns_lower, + i.name_upper.lower(), + self.namespace, + i.camel_name, + ) + ) + self.outfile.write("\n") + + self.outfile.write("/* ---- */\n") + self.outfile.write("\n") + self.outfile.write( + "#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_type ())\n" + % (self.ns_upper, self.ns_lower) + ) + self.outfile.write( + "#define %sOBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClient))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sOBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sOBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n" + % (self.ns_upper, self.ns_upper, self.namespace) + ) + self.outfile.write( + "#define %sIS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_MANAGER_CLIENT))\n" + % (self.ns_upper, self.ns_upper) + ) + self.outfile.write( + "#define %sIS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_MANAGER_CLIENT))\n" + % (self.ns_upper, self.ns_upper) + ) + self.outfile.write("\n") + self.outfile.write( + "typedef struct _%sObjectManagerClient %sObjectManagerClient;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write( + "typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write( + "typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write("\n") + self.outfile.write("struct _%sObjectManagerClient\n" % (self.namespace)) + self.outfile.write("{\n") + self.outfile.write(" /*< private >*/\n") + self.outfile.write(" GDBusObjectManagerClient parent_instance;\n") + self.outfile.write( + " %sObjectManagerClientPrivate *priv;\n" % (self.namespace) + ) + self.outfile.write("};\n") + self.outfile.write("\n") + self.outfile.write( + "struct _%sObjectManagerClientClass\n" % (self.namespace) + ) + self.outfile.write("{\n") + self.outfile.write(" GDBusObjectManagerClientClass parent_class;\n") + self.outfile.write("};\n") + self.outfile.write("\n") + if self.generate_autocleanup in ("objects", "all"): + self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") + self.outfile.write( + "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectManagerClient, g_object_unref)\n" + % (self.namespace) + ) + self.outfile.write("#endif\n") + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GType %sobject_manager_client_get_type (void) G_GNUC_CONST;\n" + % (self.ns_lower) + ) + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GType %sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data);\n" + % (self.ns_lower) + ) + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "void %sobject_manager_client_new (\n" + " GDBusConnection *connection,\n" + " GDBusObjectManagerClientFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data);\n" % (self.ns_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GDBusObjectManager *%sobject_manager_client_new_finish (\n" + " GAsyncResult *res,\n" + " GError **error);\n" % (self.ns_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GDBusObjectManager *%sobject_manager_client_new_sync (\n" + " GDBusConnection *connection,\n" + " GDBusObjectManagerClientFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GError **error);\n" % (self.ns_lower) + ) + self.outfile.write("\n") + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "void %sobject_manager_client_new_for_bus (\n" + " GBusType bus_type,\n" + " GDBusObjectManagerClientFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data);\n" % (self.ns_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GDBusObjectManager *%sobject_manager_client_new_for_bus_finish (\n" + " GAsyncResult *res,\n" + " GError **error);\n" % (self.ns_lower) + ) + if self.symbol_decorator is not None: + self.outfile.write("%s\n" % self.symbol_decorator) + self.outfile.write( + "GDBusObjectManager *%sobject_manager_client_new_for_bus_sync (\n" + " GBusType bus_type,\n" + " GDBusObjectManagerClientFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GError **error);\n" % (self.ns_lower) + ) + self.outfile.write("\n") + + # ---------------------------------------------------------------------------------------------------- + + def generate_header_postamble(self): + self.outfile.write("\n") + self.outfile.write("G_END_DECLS\n") + + if not self.use_pragma: + self.outfile.write("\n") + self.outfile.write("#endif /* __{!s}__ */\n".format(self.header_guard)) + + # ---------------------------------------------------------------------------------------------------- + + def generate(self): + self.generate_header_preamble() + self.declare_types() + self.generate_header_postamble() + + +# ---------------------------------------------------------------------------------------------------- + + +class InterfaceInfoHeaderCodeGenerator: + def __init__( + self, + ifaces, + namespace, + header_name, + input_files_basenames, + use_pragma, + glib_min_required, + symbol_decorator, + symbol_decorator_header, + outfile, + ): + self.ifaces = ifaces + self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) + self.header_guard = generate_header_guard(header_name) + self.input_files_basenames = input_files_basenames + self.use_pragma = use_pragma + self.glib_min_required = glib_min_required + self.symbol_decorator = symbol_decorator + if self.symbol_decorator is None: + self.symbol_decorator = "" + self.symbol_decorator_header = symbol_decorator_header + self.outfile = outfile + + # ---------------------------------------------------------------------------------------------------- + + def generate_header_preamble(self): + basenames = ", ".join(self.input_files_basenames) + self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) + self.outfile.write("\n") + + if self.use_pragma: + self.outfile.write("#pragma once\n") + else: + self.outfile.write("#ifndef __{!s}__\n".format(self.header_guard)) + self.outfile.write("#define __{!s}__\n".format(self.header_guard)) + + if self.symbol_decorator_header is not None: + self.outfile.write("\n") + self.outfile.write('#include "%s"\n' % self.symbol_decorator_header) + + self.outfile.write("\n") + self.outfile.write("#include \n") + self.outfile.write("\n") + self.outfile.write("G_BEGIN_DECLS\n") + self.outfile.write("\n") + + # ---------------------------------------------------------------------------------------------------- + + def declare_infos(self): + for i in self.ifaces: + self.outfile.write( + "extern %s const GDBusInterfaceInfo %s_interface;\n" + % (self.symbol_decorator, i.name_lower) + ) + + # ---------------------------------------------------------------------------------------------------- + + def generate_header_postamble(self): + self.outfile.write("\n") + self.outfile.write("G_END_DECLS\n") + + if not self.use_pragma: + self.outfile.write("\n") + self.outfile.write("#endif /* __{!s}__ */\n".format(self.header_guard)) + + # ---------------------------------------------------------------------------------------------------- + + def generate(self): + self.generate_header_preamble() + self.declare_infos() + self.generate_header_postamble() + + +# ---------------------------------------------------------------------------------------------------- + + +class InterfaceInfoBodyCodeGenerator: + def __init__( + self, + ifaces, + namespace, + header_name, + input_files_basenames, + glib_min_required, + symbol_decoration_define, + outfile, + ): + self.ifaces = ifaces + self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) + self.header_name = header_name + self.input_files_basenames = input_files_basenames + self.glib_min_required = glib_min_required + self.symbol_decoration_define = symbol_decoration_define + self.outfile = outfile + + # ---------------------------------------------------------------------------------------------------- + + def generate_body_preamble(self): + basenames = ", ".join(self.input_files_basenames) + self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) + + if self.symbol_decoration_define is not None: + self.outfile.write("\n") + self.outfile.write("#define %s\n" % self.symbol_decoration_define) + + self.outfile.write("\n") + self.outfile.write( + "#ifdef HAVE_CONFIG_H\n" + '# include "config.h"\n' + "#endif\n" + "\n" + '#include "%s"\n' + "\n" + "#include \n" % (self.header_name) + ) + self.outfile.write("\n") + + # ---------------------------------------------------------------------------------------------------- + + def generate_array(self, array_name_lower, element_type, elements): + self.outfile.write( + "const %s * const %s[] =\n" % (element_type, array_name_lower) + ) + self.outfile.write("{\n") + for (_, name) in elements: + self.outfile.write(" &%s,\n" % name) + self.outfile.write(" NULL,\n") + self.outfile.write("};\n") + self.outfile.write("\n") + + def define_annotations(self, array_name_lower, annotations): + if len(annotations) == 0: + return + + annotation_pointers = [] + + for a in annotations: + # Skip internal annotations. + if a.key.startswith("org.gtk.GDBus"): + continue + + self.define_annotations( + "%s__%s_annotations" % (array_name_lower, a.key_lower), a.annotations + ) + + self.outfile.write( + "const GDBusAnnotationInfo %s__%s_annotation =\n" + % (array_name_lower, a.key_lower) + ) + self.outfile.write("{\n") + self.outfile.write(" -1, /* ref count */\n") + self.outfile.write(' (gchar *) "%s",\n' % a.key) + self.outfile.write(' (gchar *) "%s",\n' % a.value) + if len(a.annotations) > 0: + self.outfile.write( + " (GDBusAnnotationInfo **) %s__%s_annotations,\n" + % (array_name_lower, a.key_lower) + ) + else: + self.outfile.write(" NULL, /* no annotations */\n") + self.outfile.write("};\n") + self.outfile.write("\n") + + key = (a.since, "%s__%s_annotation" % (array_name_lower, a.key_lower)) + annotation_pointers.append(key) + + self.generate_array( + array_name_lower, "GDBusAnnotationInfo", annotation_pointers + ) + + def define_args(self, array_name_lower, args): + if len(args) == 0: + return + + arg_pointers = [] + + for a in args: + self.define_annotations( + "%s__%s_arg_annotations" % (array_name_lower, a.name), a.annotations + ) + + self.outfile.write( + "const GDBusArgInfo %s__%s_arg =\n" % (array_name_lower, a.name) + ) + self.outfile.write("{\n") + self.outfile.write(" -1, /* ref count */\n") + self.outfile.write(' (gchar *) "%s",\n' % a.name) + self.outfile.write(' (gchar *) "%s",\n' % a.signature) + if len(a.annotations) > 0: + self.outfile.write( + " (GDBusAnnotationInfo **) %s__%s_arg_annotations,\n" + % (array_name_lower, a.name) + ) + else: + self.outfile.write(" NULL, /* no annotations */\n") + self.outfile.write("};\n") + self.outfile.write("\n") + + key = (a.since, "%s__%s_arg" % (array_name_lower, a.name)) + arg_pointers.append(key) + + self.generate_array(array_name_lower, "GDBusArgInfo", arg_pointers) + + def define_infos(self): + for i in self.ifaces: + self.outfile.write( + "/* ------------------------------------------------------------------------ */\n" + ) + self.outfile.write("/* Definitions for %s */\n" % i.name) + self.outfile.write("\n") + + # GDBusMethodInfos. + if len(i.methods) > 0: + method_pointers = [] + + for m in i.methods: + self.define_args( + "%s_interface__%s_method_in_args" + % (i.name_lower, m.name_lower), + m.in_args, + ) + self.define_args( + "%s_interface__%s_method_out_args" + % (i.name_lower, m.name_lower), + m.out_args, + ) + self.define_annotations( + "%s_interface__%s_method_annotations" + % (i.name_lower, m.name_lower), + m.annotations, + ) + + self.outfile.write( + "const GDBusMethodInfo %s_interface__%s_method =\n" + % (i.name_lower, m.name_lower) + ) + self.outfile.write("{\n") + self.outfile.write(" -1, /* ref count */\n") + self.outfile.write(' (gchar *) "%s",\n' % m.name) + if len(m.in_args) > 0: + self.outfile.write( + " (GDBusArgInfo **) %s_interface__%s_method_in_args,\n" + % (i.name_lower, m.name_lower) + ) + else: + self.outfile.write(" NULL, /* no in args */\n") + if len(m.out_args) > 0: + self.outfile.write( + " (GDBusArgInfo **) %s_interface__%s_method_out_args,\n" + % (i.name_lower, m.name_lower) + ) + else: + self.outfile.write(" NULL, /* no out args */\n") + if len(m.annotations) > 0: + self.outfile.write( + " (GDBusAnnotationInfo **) %s_interface__%s_method_annotations,\n" + % (i.name_lower, m.name_lower) + ) + else: + self.outfile.write(" NULL, /* no annotations */\n") + self.outfile.write("};\n") + self.outfile.write("\n") + + key = ( + m.since, + "%s_interface__%s_method" % (i.name_lower, m.name_lower), + ) + method_pointers.append(key) + + self.generate_array( + "%s_interface_methods" % i.name_lower, + "GDBusMethodInfo", + method_pointers, + ) + + # GDBusSignalInfos. + if len(i.signals) > 0: + signal_pointers = [] + + for s in i.signals: + self.define_args( + "%s_interface__%s_signal_args" % (i.name_lower, s.name_lower), + s.args, + ) + self.define_annotations( + "%s_interface__%s_signal_annotations" + % (i.name_lower, s.name_lower), + s.annotations, + ) + + self.outfile.write( + "const GDBusSignalInfo %s_interface__%s_signal =\n" + % (i.name_lower, s.name_lower) + ) + self.outfile.write("{\n") + self.outfile.write(" -1, /* ref count */\n") + self.outfile.write(' (gchar *) "%s",\n' % s.name) + if len(s.args) > 0: + self.outfile.write( + " (GDBusArgInfo **) %s_interface__%s_signal_args,\n" + % (i.name_lower, s.name_lower) + ) + else: + self.outfile.write(" NULL, /* no args */\n") + if len(s.annotations) > 0: + self.outfile.write( + " (GDBusAnnotationInfo **) %s_interface__%s_signal_annotations,\n" + % (i.name_lower, s.name_lower) + ) + else: + self.outfile.write(" NULL, /* no annotations */\n") + self.outfile.write("};\n") + self.outfile.write("\n") + + key = ( + s.since, + "%s_interface__%s_signal" % (i.name_lower, s.name_lower), + ) + signal_pointers.append(key) + + self.generate_array( + "%s_interface_signals" % i.name_lower, + "GDBusSignalInfo", + signal_pointers, + ) + + # GDBusPropertyInfos. + if len(i.properties) > 0: + property_pointers = [] + + for p in i.properties: + if p.readable and p.writable: + flags = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE" + elif p.readable: + flags = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE" + elif p.writable: + flags = "G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE" + else: + flags = "G_DBUS_PROPERTY_INFO_FLAGS_NONE" + + self.define_annotations( + "%s_interface__%s_property_annotations" + % (i.name_lower, p.name_lower), + p.annotations, + ) + + self.outfile.write( + "const GDBusPropertyInfo %s_interface__%s_property =\n" + % (i.name_lower, p.name_lower) + ) + self.outfile.write("{\n") + self.outfile.write(" -1, /* ref count */\n") + self.outfile.write(' (gchar *) "%s",\n' % p.name) + self.outfile.write(' (gchar *) "%s",\n' % p.signature) + self.outfile.write(" %s,\n" % flags) + if len(p.annotations) > 0: + self.outfile.write( + " (GDBusAnnotationInfo **) %s_interface__%s_property_annotations,\n" + % (i.name_lower, p.name_lower) + ) + else: + self.outfile.write(" NULL, /* no annotations */\n") + self.outfile.write("};\n") + self.outfile.write("\n") + + key = ( + p.since, + "%s_interface__%s_property" % (i.name_lower, p.name_lower), + ) + property_pointers.append(key) + + self.generate_array( + "%s_interface_properties" % i.name_lower, + "GDBusPropertyInfo", + property_pointers, + ) + + # Finally the GDBusInterfaceInfo. + self.define_annotations( + "%s_interface_annotations" % i.name_lower, i.annotations + ) + + self.outfile.write( + "const GDBusInterfaceInfo %s_interface =\n" % i.name_lower + ) + self.outfile.write("{\n") + self.outfile.write(" -1, /* ref count */\n") + self.outfile.write(' (gchar *) "%s",\n' % i.name) + if len(i.methods) > 0: + self.outfile.write( + " (GDBusMethodInfo **) %s_interface_methods,\n" % i.name_lower + ) + else: + self.outfile.write(" NULL, /* no methods */\n") + if len(i.signals) > 0: + self.outfile.write( + " (GDBusSignalInfo **) %s_interface_signals,\n" % i.name_lower + ) + else: + self.outfile.write(" NULL, /* no signals */\n") + if len(i.properties) > 0: + self.outfile.write( + " (GDBusPropertyInfo **) %s_interface_properties,\n" % i.name_lower + ) + else: + self.outfile.write("NULL, /* no properties */\n") + if len(i.annotations) > 0: + self.outfile.write( + " (GDBusAnnotationInfo **) %s_interface_annotations,\n" + % i.name_lower + ) + else: + self.outfile.write(" NULL, /* no annotations */\n") + self.outfile.write("};\n") + self.outfile.write("\n") + + # ---------------------------------------------------------------------------------------------------- + + def generate(self): + self.generate_body_preamble() + self.define_infos() + + +# ---------------------------------------------------------------------------------------------------- + + +class CodeGenerator: + def __init__( + self, + ifaces, + namespace, + generate_objmanager, + header_name, + input_files_basenames, + docbook_gen, + glib_min_required, + symbol_decoration_define, + outfile, + ): + self.ifaces = ifaces + self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) + self.generate_objmanager = generate_objmanager + self.header_name = header_name + self.input_files_basenames = input_files_basenames + self.docbook_gen = docbook_gen + self.glib_min_required = glib_min_required + self.symbol_decoration_define = symbol_decoration_define + self.outfile = outfile + + # ---------------------------------------------------------------------------------------------------- + + def generate_body_preamble(self): + basenames = ", ".join(self.input_files_basenames) + self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) + if self.symbol_decoration_define is not None: + self.outfile.write("\n") + self.outfile.write("#define %s\n" % self.symbol_decoration_define) + self.outfile.write("\n") + self.outfile.write( + "#ifdef HAVE_CONFIG_H\n" + '# include "config.h"\n' + "#endif\n" + "\n" + '#include "%s"\n' + "\n" + "#include \n" % (self.header_name) + ) + + self.outfile.write( + "#ifdef G_OS_UNIX\n" "# include \n" "#endif\n" "\n" + ) + + self.outfile.write( + "typedef struct\n" + "{\n" + " GDBusArgInfo parent_struct;\n" + " gboolean use_gvariant;\n" + "} _ExtendedGDBusArgInfo;\n" + "\n" + ) + + self.outfile.write( + "typedef struct\n" + "{\n" + " GDBusMethodInfo parent_struct;\n" + " const gchar *signal_name;\n" + " gboolean pass_fdlist;\n" + "} _ExtendedGDBusMethodInfo;\n" + "\n" + ) + + self.outfile.write( + "typedef struct\n" + "{\n" + " GDBusSignalInfo parent_struct;\n" + " const gchar *signal_name;\n" + "} _ExtendedGDBusSignalInfo;\n" + "\n" + ) + + self.outfile.write( + "typedef struct\n" + "{\n" + " GDBusPropertyInfo parent_struct;\n" + " const gchar *hyphen_name;\n" + " guint use_gvariant : 1;\n" + " guint emits_changed_signal : 1;\n" + "} _ExtendedGDBusPropertyInfo;\n" + "\n" + ) + + self.outfile.write( + "typedef struct\n" + "{\n" + " GDBusInterfaceInfo parent_struct;\n" + " const gchar *hyphen_name;\n" + "} _ExtendedGDBusInterfaceInfo;\n" + "\n" + ) + + self.outfile.write( + "typedef struct\n" + "{\n" + " const _ExtendedGDBusPropertyInfo *info;\n" + " guint prop_id;\n" + " GValue orig_value; /* the value before the change */\n" + "} ChangedProperty;\n" + "\n" + "static void\n" + "_changed_property_free (ChangedProperty *data)\n" + "{\n" + " g_value_unset (&data->orig_value);\n" + " g_free (data);\n" + "}\n" + "\n" + ) + + self.outfile.write( + "static gboolean\n" + "_g_strv_equal0 (gchar **a, gchar **b)\n" + "{\n" + " gboolean ret = FALSE;\n" + " guint n;\n" + " if (a == NULL && b == NULL)\n" + " {\n" + " ret = TRUE;\n" + " goto out;\n" + " }\n" + " if (a == NULL || b == NULL)\n" + " goto out;\n" + " if (g_strv_length (a) != g_strv_length (b))\n" + " goto out;\n" + " for (n = 0; a[n] != NULL; n++)\n" + " if (g_strcmp0 (a[n], b[n]) != 0)\n" + " goto out;\n" + " ret = TRUE;\n" + "out:\n" + " return ret;\n" + "}\n" + "\n" + ) + + self.outfile.write( + "static gboolean\n" + "_g_variant_equal0 (GVariant *a, GVariant *b)\n" + "{\n" + " gboolean ret = FALSE;\n" + " if (a == NULL && b == NULL)\n" + " {\n" + " ret = TRUE;\n" + " goto out;\n" + " }\n" + " if (a == NULL || b == NULL)\n" + " goto out;\n" + " ret = g_variant_equal (a, b);\n" + "out:\n" + " return ret;\n" + "}\n" + "\n" + ) + + # simplified - only supports the types we use + self.outfile.write( + "G_GNUC_UNUSED static gboolean\n" + "_g_value_equal (const GValue *a, const GValue *b)\n" + "{\n" + " gboolean ret = FALSE;\n" + " g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n" + " switch (G_VALUE_TYPE (a))\n" + " {\n" + " case G_TYPE_BOOLEAN:\n" + " ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n" + " break;\n" + " case G_TYPE_UCHAR:\n" + " ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n" + " break;\n" + " case G_TYPE_INT:\n" + " ret = (g_value_get_int (a) == g_value_get_int (b));\n" + " break;\n" + " case G_TYPE_UINT:\n" + " ret = (g_value_get_uint (a) == g_value_get_uint (b));\n" + " break;\n" + " case G_TYPE_INT64:\n" + " ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n" + " break;\n" + " case G_TYPE_UINT64:\n" + " ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n" + " break;\n" + " case G_TYPE_DOUBLE:\n" + " {\n" + " /* Avoid -Wfloat-equal warnings by doing a direct bit compare */\n" + " gdouble da = g_value_get_double (a);\n" + " gdouble db = g_value_get_double (b);\n" + " ret = memcmp (&da, &db, sizeof (gdouble)) == 0;\n" + " }\n" + " break;\n" + " case G_TYPE_STRING:\n" + " ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n" + " break;\n" + " case G_TYPE_VARIANT:\n" + " ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n" + " break;\n" + " default:\n" + " if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n" + " ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n" + " else\n" + ' g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n' + " break;\n" + " }\n" + " return ret;\n" + "}\n" + "\n" + ) + + def generate_annotations(self, prefix, annotations): + if annotations is None: + return + + n = 0 + for a in annotations: + # self.generate_annotations('%s_%d'%(prefix, n), a.get_annotations()) + + # skip internal annotations + if a.key.startswith("org.gtk.GDBus"): + continue + + self.outfile.write( + "static const GDBusAnnotationInfo %s_%d =\n" + "{\n" + " -1,\n" + ' (gchar *) "%s",\n' + ' (gchar *) "%s",\n' % (prefix, n, a.key, a.value) + ) + if len(a.annotations) == 0: + self.outfile.write(" NULL\n") + else: + self.outfile.write( + " (GDBusAnnotationInfo **) &%s_%d_pointers\n" % (prefix, n) + ) + self.outfile.write("};\n" "\n") + n += 1 + + if n > 0: + self.outfile.write( + "static const GDBusAnnotationInfo * const %s_pointers[] =\n" + "{\n" % (prefix) + ) + m = 0 + for a in annotations: + if a.key.startswith("org.gtk.GDBus"): + continue + self.outfile.write(" &%s_%d,\n" % (prefix, m)) + m += 1 + self.outfile.write(" NULL\n" "};\n" "\n") + return n + + def generate_args(self, prefix, args): + for a in args: + num_anno = self.generate_annotations( + "%s_arg_%s_annotation_info" % (prefix, a.name), a.annotations + ) + + self.outfile.write( + "static const _ExtendedGDBusArgInfo %s_%s =\n" + "{\n" + " {\n" + " -1,\n" + ' (gchar *) "%s",\n' + ' (gchar *) "%s",\n' % (prefix, a.name, a.name, a.signature) + ) + if num_anno == 0: + self.outfile.write(" NULL\n") + else: + self.outfile.write( + " (GDBusAnnotationInfo **) &%s_arg_%s_annotation_info_pointers\n" + % (prefix, a.name) + ) + self.outfile.write(" },\n") + if not utils.lookup_annotation( + a.annotations, "org.gtk.GDBus.C.ForceGVariant" + ): + self.outfile.write(" FALSE\n") + else: + self.outfile.write(" TRUE\n") + self.outfile.write("};\n" "\n") + + if len(args) > 0: + self.outfile.write( + "static const GDBusArgInfo * const %s_pointers[] =\n" "{\n" % (prefix) + ) + for a in args: + self.outfile.write(" &%s_%s.parent_struct,\n" % (prefix, a.name)) + self.outfile.write(" NULL\n" "};\n" "\n") + + def generate_introspection_for_interface(self, i): + self.outfile.write( + "/* ---- Introspection data for %s ---- */\n" "\n" % (i.name) + ) + + if len(i.methods) > 0: + for m in i.methods: + self.generate_args( + "_%s_method_info_%s_IN_ARG" % (i.name_lower, m.name_lower), + m.in_args, + ) + self.generate_args( + "_%s_method_info_%s_OUT_ARG" % (i.name_lower, m.name_lower), + m.out_args, + ) + + num_anno = self.generate_annotations( + "_%s_method_%s_annotation_info" % (i.name_lower, m.name_lower), + m.annotations, + ) + + self.outfile.write( + "static const _ExtendedGDBusMethodInfo _%s_method_info_%s =\n" + "{\n" + " {\n" + " -1,\n" + ' (gchar *) "%s",\n' % (i.name_lower, m.name_lower, m.name) + ) + if len(m.in_args) == 0: + self.outfile.write(" NULL,\n") + else: + self.outfile.write( + " (GDBusArgInfo **) &_%s_method_info_%s_IN_ARG_pointers,\n" + % (i.name_lower, m.name_lower) + ) + if len(m.out_args) == 0: + self.outfile.write(" NULL,\n") + else: + self.outfile.write( + " (GDBusArgInfo **) &_%s_method_info_%s_OUT_ARG_pointers,\n" + % (i.name_lower, m.name_lower) + ) + if num_anno == 0: + self.outfile.write(" NULL\n") + else: + self.outfile.write( + " (GDBusAnnotationInfo **) &_%s_method_%s_annotation_info_pointers\n" + % (i.name_lower, m.name_lower) + ) + self.outfile.write( + " },\n" + ' "handle-%s",\n' + " %s\n" % (m.name_hyphen, "TRUE" if m.unix_fd else "FALSE") + ) + self.outfile.write("};\n" "\n") + + self.outfile.write( + "static const GDBusMethodInfo * const _%s_method_info_pointers[] =\n" + "{\n" % (i.name_lower) + ) + for m in i.methods: + self.outfile.write( + " &_%s_method_info_%s.parent_struct,\n" + % (i.name_lower, m.name_lower) + ) + self.outfile.write(" NULL\n" "};\n" "\n") + + # --- + + if len(i.signals) > 0: + for s in i.signals: + self.generate_args( + "_%s_signal_info_%s_ARG" % (i.name_lower, s.name_lower), s.args + ) + + num_anno = self.generate_annotations( + "_%s_signal_%s_annotation_info" % (i.name_lower, s.name_lower), + s.annotations, + ) + self.outfile.write( + "static const _ExtendedGDBusSignalInfo _%s_signal_info_%s =\n" + "{\n" + " {\n" + " -1,\n" + ' (gchar *) "%s",\n' % (i.name_lower, s.name_lower, s.name) + ) + if len(s.args) == 0: + self.outfile.write(" NULL,\n") + else: + self.outfile.write( + " (GDBusArgInfo **) &_%s_signal_info_%s_ARG_pointers,\n" + % (i.name_lower, s.name_lower) + ) + if num_anno == 0: + self.outfile.write(" NULL\n") + else: + self.outfile.write( + " (GDBusAnnotationInfo **) &_%s_signal_%s_annotation_info_pointers\n" + % (i.name_lower, s.name_lower) + ) + self.outfile.write(" },\n" ' "%s"\n' % (s.name_hyphen)) + self.outfile.write("};\n" "\n") + + self.outfile.write( + "static const GDBusSignalInfo * const _%s_signal_info_pointers[] =\n" + "{\n" % (i.name_lower) + ) + for s in i.signals: + self.outfile.write( + " &_%s_signal_info_%s.parent_struct,\n" + % (i.name_lower, s.name_lower) + ) + self.outfile.write(" NULL\n" "};\n" "\n") + + # --- + + if len(i.properties) > 0: + for p in i.properties: + if p.readable and p.writable: + access = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE" + elif p.readable: + access = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE" + elif p.writable: + access = "G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE" + else: + access = "G_DBUS_PROPERTY_INFO_FLAGS_NONE" + num_anno = self.generate_annotations( + "_%s_property_%s_annotation_info" % (i.name_lower, p.name_lower), + p.annotations, + ) + self.outfile.write( + "static const _ExtendedGDBusPropertyInfo _%s_property_info_%s =\n" + "{\n" + " {\n" + " -1,\n" + ' (gchar *) "%s",\n' + ' (gchar *) "%s",\n' + " %s,\n" + % (i.name_lower, p.name_lower, p.name, p.arg.signature, access) + ) + if num_anno == 0: + self.outfile.write(" NULL\n") + else: + self.outfile.write( + " (GDBusAnnotationInfo **) &_%s_property_%s_annotation_info_pointers\n" + % (i.name_lower, p.name_lower) + ) + self.outfile.write(" },\n" ' "%s",\n' % (p.name_hyphen)) + if not utils.lookup_annotation( + p.annotations, "org.gtk.GDBus.C.ForceGVariant" + ): + self.outfile.write(" FALSE,\n") + else: + self.outfile.write(" TRUE,\n") + if p.emits_changed_signal: + self.outfile.write(" TRUE\n") + else: + self.outfile.write(" FALSE\n") + self.outfile.write("};\n" "\n") + + self.outfile.write( + "static const GDBusPropertyInfo * const _%s_property_info_pointers[] =\n" + "{\n" % (i.name_lower) + ) + for p in i.properties: + self.outfile.write( + " &_%s_property_info_%s.parent_struct,\n" + % (i.name_lower, p.name_lower) + ) + self.outfile.write(" NULL\n" "};\n" "\n") + + num_anno = self.generate_annotations( + "_%s_annotation_info" % (i.name_lower), i.annotations + ) + self.outfile.write( + "static const _ExtendedGDBusInterfaceInfo _%s_interface_info =\n" + "{\n" + " {\n" + " -1,\n" + ' (gchar *) "%s",\n' % (i.name_lower, i.name) + ) + if len(i.methods) == 0: + self.outfile.write(" NULL,\n") + else: + self.outfile.write( + " (GDBusMethodInfo **) &_%s_method_info_pointers,\n" % (i.name_lower) + ) + if len(i.signals) == 0: + self.outfile.write(" NULL,\n") + else: + self.outfile.write( + " (GDBusSignalInfo **) &_%s_signal_info_pointers,\n" % (i.name_lower) + ) + if len(i.properties) == 0: + self.outfile.write(" NULL,\n") + else: + self.outfile.write( + " (GDBusPropertyInfo **) &_%s_property_info_pointers,\n" + % (i.name_lower) + ) + if num_anno == 0: + self.outfile.write(" NULL\n") + else: + self.outfile.write( + " (GDBusAnnotationInfo **) &_%s_annotation_info_pointers\n" + % (i.name_lower) + ) + self.outfile.write(" },\n" ' "%s",\n' "};\n" "\n" % (i.name_hyphen)) + self.outfile.write("\n") + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_interface_info:\n" + " *\n" + " * Gets a machine-readable description of the #%s D-Bus interface.\n" + " *\n" + " * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.\n" + % (i.name_lower, i.name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "GDBusInterfaceInfo *\n" + "%s_interface_info (void)\n" + "{\n" + " return (GDBusInterfaceInfo *) &_%s_interface_info.parent_struct;\n" + "}\n" + "\n" % (i.name_lower, i.name_lower) + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_override_properties:\n" + " * @klass: The class structure for a #GObject derived class.\n" + " * @property_id_begin: The property id to assign to the first overridden property.\n" + " *\n" + " * Overrides all #GObject properties in the #%s interface for a concrete class.\n" + " * The properties are overridden in the order they are defined.\n" + " *\n" + " * Returns: The last property id.\n" % (i.name_lower, i.camel_name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "guint\n" "%s_override_properties (GObjectClass *klass" % (i.name_lower) + ) + if len(i.properties) == 0: + self.outfile.write(" G_GNUC_UNUSED") + self.outfile.write(", guint property_id_begin)\n" "{\n") + for p in i.properties: + self.outfile.write( + ' g_object_class_override_property (klass, property_id_begin++, "%s");\n' + % (p.name_hyphen) + ) + self.outfile.write(" return property_id_begin - 1;\n" "}\n" "\n") + self.outfile.write("\n") + + # ---------------------------------------------------------------------------------------------------- + + def generate_interface(self, i): + self.outfile.write("\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s:\n" + " *\n" + " * Abstract interface type for the D-Bus interface #%s.\n" + % (i.camel_name, i.name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write("\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sIface:\n" + " * @parent_iface: The parent interface.\n" % (i.camel_name), + False, + ) + ) + + doc_bits = {} + if len(i.methods) > 0: + for m in i.methods: + key = (m.since, "_method_%s" % m.name_lower) + value = "@handle_%s: " % (m.name_lower) + value += "Handler for the #%s::handle-%s signal." % ( + i.camel_name, + m.name_hyphen, + ) + doc_bits[key] = value + if len(i.signals) > 0: + for s in i.signals: + key = (s.since, "_signal_%s" % s.name_lower) + value = "@%s: " % (s.name_lower) + value += "Handler for the #%s::%s signal." % ( + i.camel_name, + s.name_hyphen, + ) + doc_bits[key] = value + if len(i.properties) > 0: + for p in i.properties: + key = (p.since, "_prop_get_%s" % p.name_lower) + value = "@get_%s: " % (p.name_lower) + value += "Getter for the #%s:%s property." % ( + i.camel_name, + p.name_hyphen, + ) + doc_bits[key] = value + for key in sorted(doc_bits.keys(), key=utils.version_cmp_key): + self.outfile.write(" * %s\n" % doc_bits[key]) + + self.outfile.write( + self.docbook_gen.expand( + " *\n" " * Virtual table for the D-Bus interface #%s.\n" % (i.name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write("\n") + + self.outfile.write( + "typedef %sIface %sInterface;\n" % (i.camel_name, i.camel_name) + ) + self.outfile.write( + "G_DEFINE_INTERFACE (%s, %s, G_TYPE_OBJECT)\n" + % (i.camel_name, i.name_lower) + ) + self.outfile.write("\n") + + self.outfile.write( + "static void\n" + "%s_default_init (%sIface *iface" % (i.name_lower, i.camel_name) + ) + if len(i.methods) == 0 and len(i.signals) == 0 and len(i.properties) == 0: + self.outfile.write(" G_GNUC_UNUSED)\n") + else: + self.outfile.write(")\n") + self.outfile.write("{\n") + if len(i.methods) > 0: + self.outfile.write( + " /* GObject signals for incoming D-Bus method calls: */\n" + ) + for m in i.methods: + self.outfile.write( + self.docbook_gen.expand( + " /**\n" + " * %s::handle-%s:\n" + " * @object: A #%s.\n" + " * @invocation: A #GDBusMethodInvocation.\n" + % (i.camel_name, m.name_hyphen, i.camel_name), + False, + ) + ) + if m.unix_fd: + self.outfile.write( + " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n" + ) + for a in m.in_args: + self.outfile.write( + " * @arg_%s: Argument passed by remote caller.\n" % (a.name) + ) + self.outfile.write( + self.docbook_gen.expand( + " *\n" + " * Signal emitted when a remote caller is invoking the %s.%s() D-Bus method.\n" + " *\n" + " * If a signal handler returns %%TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call %s_complete_%s() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %%G_DBUS_ERROR_UNKNOWN_METHOD error is returned.\n" + " *\n" + " * Returns: %%G_DBUS_METHOD_INVOCATION_HANDLED or %%TRUE if the invocation was handled, %%G_DBUS_METHOD_INVOCATION_UNHANDLED or %%FALSE to let other signal handlers run.\n" + % (i.name, m.name, i.name_lower, m.name_lower), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 2) + if m.unix_fd: + extra_args = 2 + else: + extra_args = 1 + self.outfile.write( + ' g_signal_new ("handle-%s",\n' + " G_TYPE_FROM_INTERFACE (iface),\n" + " G_SIGNAL_RUN_LAST,\n" + " G_STRUCT_OFFSET (%sIface, handle_%s),\n" + " g_signal_accumulator_true_handled,\n" + " NULL,\n" # accu_data + " g_cclosure_marshal_generic,\n" + " G_TYPE_BOOLEAN,\n" + " %d,\n" + " G_TYPE_DBUS_METHOD_INVOCATION" + % ( + m.name_hyphen, + i.camel_name, + m.name_lower, + len(m.in_args) + extra_args, + ) + ) + if m.unix_fd: + self.outfile.write(", G_TYPE_UNIX_FD_LIST") + for a in m.in_args: + self.outfile.write(", %s" % (a.gtype)) + self.outfile.write(");\n") + self.outfile.write("\n") + + if len(i.signals) > 0: + self.outfile.write(" /* GObject signals for received D-Bus signals: */\n") + for s in i.signals: + self.outfile.write( + self.docbook_gen.expand( + " /**\n" + " * %s::%s:\n" + " * @object: A #%s.\n" + % (i.camel_name, s.name_hyphen, i.camel_name), + False, + ) + ) + for a in s.args: + self.outfile.write(" * @arg_%s: Argument.\n" % (a.name)) + self.outfile.write( + self.docbook_gen.expand( + " *\n" + " * On the client-side, this signal is emitted whenever the D-Bus signal #%s::%s is received.\n" + " *\n" + " * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal.\n" + % (i.name, s.name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(s, self.outfile, 2) + self.outfile.write( + ' g_signal_new ("%s",\n' + " G_TYPE_FROM_INTERFACE (iface),\n" + " G_SIGNAL_RUN_LAST,\n" + " G_STRUCT_OFFSET (%sIface, %s),\n" + " NULL,\n" # accumulator + " NULL,\n" # accu_data + " g_cclosure_marshal_generic,\n" + " G_TYPE_NONE,\n" + " %d" % (s.name_hyphen, i.camel_name, s.name_lower, len(s.args)) + ) + for a in s.args: + self.outfile.write(", %s" % (a.gtype)) + self.outfile.write(");\n") + self.outfile.write("\n") + + if len(i.properties) > 0: + self.outfile.write(" /* GObject properties for D-Bus properties: */\n") + for p in i.properties: + if p.readable and p.writable: + hint = "Since the D-Bus property for this #GObject property is both readable and writable, it is meaningful to both read from it and write to it on both the service- and client-side." + elif p.readable: + hint = "Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side." + elif p.writable: + hint = "Since the D-Bus property for this #GObject property is writable but not readable, it is meaningful to write to it on both the client- and service-side. It is only meaningful, however, to read from it on the service-side." + else: + print_error( + 'Cannot handle property "{}" that neither readable nor writable'.format( + p.name + ) + ) + self.outfile.write( + self.docbook_gen.expand( + " /**\n" + " * %s:%s:\n" + " *\n" + " * Represents the D-Bus property #%s:%s.\n" + " *\n" + " * %s\n" + % (i.camel_name, p.name_hyphen, i.name, p.name, hint), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 2) + self.outfile.write(" g_object_interface_install_property (iface,\n") + if p.arg.gtype == "G_TYPE_VARIANT": + s = ( + 'g_param_spec_variant ("%s", "%s", "%s", G_VARIANT_TYPE ("%s"), NULL' + % (p.name_hyphen, p.name, p.name, p.arg.signature) + ) + elif p.arg.signature == "b": + s = 'g_param_spec_boolean ("%s", "%s", "%s", FALSE' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "y": + s = 'g_param_spec_uchar ("%s", "%s", "%s", 0, 255, 0' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "n": + s = ( + 'g_param_spec_int ("%s", "%s", "%s", G_MININT16, G_MAXINT16, 0' + % (p.name_hyphen, p.name, p.name) + ) + elif p.arg.signature == "q": + s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT16, 0' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "i": + s = ( + 'g_param_spec_int ("%s", "%s", "%s", G_MININT32, G_MAXINT32, 0' + % (p.name_hyphen, p.name, p.name) + ) + elif p.arg.signature == "u": + s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT32, 0' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "x": + s = ( + 'g_param_spec_int64 ("%s", "%s", "%s", G_MININT64, G_MAXINT64, 0' + % (p.name_hyphen, p.name, p.name) + ) + elif p.arg.signature == "t": + s = 'g_param_spec_uint64 ("%s", "%s", "%s", 0, G_MAXUINT64, 0' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "d": + s = ( + 'g_param_spec_double ("%s", "%s", "%s", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0' + % (p.name_hyphen, p.name, p.name) + ) + elif p.arg.signature == "s": + s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "o": + s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "g": + s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "ay": + s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "as": + s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "ao": + s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % ( + p.name_hyphen, + p.name, + p.name, + ) + elif p.arg.signature == "aay": + s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % ( + p.name_hyphen, + p.name, + p.name, + ) + else: + print_error( + 'Unsupported gtype "{}" for GParamSpec'.format(p.arg.gtype) + ) + flags = "G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS" + if p.deprecated: + flags = "G_PARAM_DEPRECATED | " + flags + self.outfile.write(" %s, %s));" % (s, flags)) + self.outfile.write("\n") + + self.outfile.write("}\n" "\n") + + # ---------------------------------------------------------------------------------------------------- + + def generate_property_accessors(self, i): + for p in i.properties: + # getter + if p.readable and p.writable: + hint = "Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side." + elif p.readable: + hint = "Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side." + elif p.writable: + hint = "Since this D-Bus property is not readable, it is only meaningful to use this function on the service-side." + else: + print_error( + 'Cannot handle property "{}" that neither readable nor writable'.format( + p.name + ) + ) + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_get_%s: (skip)\n" + " * @object: A #%s.\n" + " *\n" + " * Gets the value of the #%s:%s D-Bus property.\n" + " *\n" + " * %s\n" + " *\n" + % (i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint), + False, + ) + ) + if p.arg.free_func is not None: + self.outfile.write( + " * The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use %s_dup_%s() if on another thread.\n" + " *\n" + " * Returns: (transfer none) (nullable): The property value or %%NULL if the property is not set. Do not free the returned value, it belongs to @object.\n" + % (i.name_lower, p.name_lower) + ) + else: + self.outfile.write(" * Returns: The property value.\n") + self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0) + self.outfile.write( + "%s\n" + "%s_get_%s (%s *object)\n" + "{\n" % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name) + ) + self.outfile.write( + " return %s%s_GET_IFACE (object)->get_%s (object);\n" + % (i.ns_upper, i.name_upper, p.name_lower) + ) + self.outfile.write("}\n") + self.outfile.write("\n") + if p.arg.free_func is not None: + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_dup_%s: (skip)\n" + " * @object: A #%s.\n" + " *\n" + " * Gets a copy of the #%s:%s D-Bus property.\n" + " *\n" + " * %s\n" + " *\n" + " * Returns: (transfer full) (nullable): The property value or %%NULL if the property is not set. The returned value should be freed with %s().\n" + % ( + i.name_lower, + p.name_lower, + i.camel_name, + i.name, + p.name, + hint, + p.arg.free_func, + ), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0) + self.outfile.write( + "%s\n" + "%s_dup_%s (%s *object)\n" + "{\n" + " %svalue;\n" + % ( + p.arg.ctype_in_dup, + i.name_lower, + p.name_lower, + i.camel_name, + p.arg.ctype_in_dup, + ) + ) + self.outfile.write( + ' g_object_get (G_OBJECT (object), "%s", &value, NULL);\n' + % (p.name_hyphen) + ) + self.outfile.write(" return value;\n") + self.outfile.write("}\n") + self.outfile.write("\n") + + # setter + if p.readable and p.writable: + hint = "Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side." + elif p.readable: + hint = "Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side." + elif p.writable: + hint = "Since this D-Bus property is writable, it is meaningful to use this function on both the client- and service-side." + else: + print_error( + 'Cannot handle property "{}" that neither readable nor writable'.format( + p.name + ) + ) + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_set_%s: (skip)\n" + " * @object: A #%s.\n" + " * @value: The value to set.\n" + " *\n" + " * Sets the #%s:%s D-Bus property to @value.\n" + " *\n" + " * %s\n" + % (i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0) + self.outfile.write( + "void\n" + "%s_set_%s (%s *object, %svalue)\n" + "{\n" % (i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in) + ) + self.outfile.write( + ' g_object_set (G_OBJECT (object), "%s", value, NULL);\n' + % (p.name_hyphen) + ) + self.outfile.write("}\n") + self.outfile.write("\n") + + # --------------------------------------------------------------------------------------------------- + + def generate_signal_emitters(self, i): + for s in i.signals: + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_emit_%s:\n" + " * @object: A #%s.\n" % (i.name_lower, s.name_lower, i.camel_name), + False, + ) + ) + for a in s.args: + self.outfile.write( + " * @arg_%s: Argument to pass with the signal.\n" % (a.name) + ) + self.outfile.write( + self.docbook_gen.expand( + " *\n" " * Emits the #%s::%s D-Bus signal.\n" % (i.name, s.name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(s, self.outfile, 0) + self.outfile.write( + "void\n" + "%s_emit_%s (\n" + " %s *object" % (i.name_lower, s.name_lower, i.camel_name) + ) + for a in s.args: + self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) + self.outfile.write( + ")\n" "{\n" ' g_signal_emit_by_name (object, "%s"' % (s.name_hyphen) + ) + for a in s.args: + self.outfile.write(", arg_%s" % a.name) + self.outfile.write(");\n") + self.outfile.write("}\n" "\n") + + # --------------------------------------------------------------------------------------------------- + + def generate_method_calls(self, i): + for m in i.methods: + # async begin + self.outfile.write( + "/**\n" + " * %s_call_%s:\n" + " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.in_args: + self.outfile.write( + " * @arg_%s: Argument to pass with the method invocation.\n" + % (a.name) + ) + if self.glib_min_required >= (2, 64): + self.outfile.write( + " * @call_flags: Flags from the #GDBusCallFlags enumeration. If you want to allow interactive\n" + " authorization be sure to set %G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.\n" + ' * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning "infinite") or\n' + " -1 to use the proxy default timeout.\n" + ) + if m.unix_fd: + self.outfile.write( + " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n" + ) + self.outfile.write( + self.docbook_gen.expand( + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %%NULL.\n" + " * @user_data: User data to pass to @callback.\n" + " *\n" + " * Asynchronously invokes the %s.%s() D-Bus method on @proxy.\n" + " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" + " * You can then call %s_call_%s_finish() to get the result of the operation.\n" + " *\n" + " * See %s_call_%s_sync() for the synchronous, blocking version of this method.\n" + % ( + i.name, + m.name, + i.name_lower, + m.name_lower, + i.name_lower, + m.name_lower, + ), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0) + self.outfile.write( + "void\n" + "%s_call_%s (\n" + " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.in_args: + self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) + if self.glib_min_required >= (2, 64): + self.outfile.write( + ",\n GDBusCallFlags call_flags" ",\n gint timeout_msec" + ) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList *fd_list") + self.outfile.write( + ",\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data)\n" + "{\n" + ) + if m.unix_fd: + self.outfile.write( + " g_dbus_proxy_call_with_unix_fd_list (G_DBUS_PROXY (proxy),\n" + ) + else: + self.outfile.write(" g_dbus_proxy_call (G_DBUS_PROXY (proxy),\n") + self.outfile.write(' "%s",\n' ' g_variant_new ("(' % (m.name)) + for a in m.in_args: + self.outfile.write("%s" % (a.format_in)) + self.outfile.write(')"') + for a in m.in_args: + self.outfile.write(",\n arg_%s" % (a.name)) + self.outfile.write("),\n") + if self.glib_min_required >= (2, 64): + self.outfile.write(" call_flags,\n" " timeout_msec,\n") + else: + self.outfile.write(" G_DBUS_CALL_FLAGS_NONE,\n" " -1,\n") + if m.unix_fd: + self.outfile.write(" fd_list,\n") + self.outfile.write( + " cancellable,\n" " callback,\n" " user_data);\n" + ) + self.outfile.write("}\n" "\n") + # async finish + self.outfile.write( + "/**\n" + " * %s_call_%s_finish:\n" + " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.out_args: + self.outfile.write( + " * @out_%s: (out) (optional)%s: Return location for return parameter or %%NULL to ignore.\n" + % (a.name, " " + a.array_annotation if a.array_annotation else "") + ) + if m.unix_fd: + self.outfile.write( + " * @out_fd_list: (out) (optional): Return location for a #GUnixFDList or %NULL to ignore.\n" + ) + self.outfile.write( + self.docbook_gen.expand( + " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_call_%s().\n" + " * @error: Return location for error or %%NULL.\n" + " *\n" + " * Finishes an operation started with %s_call_%s().\n" + " *\n" + " * Returns: (skip): %%TRUE if the call succeeded, %%FALSE if @error is set.\n" + % (i.name_lower, m.name_lower, i.name_lower, m.name_lower), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0) + self.outfile.write( + "gboolean\n" + "%s_call_%s_finish (\n" + " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.out_args: + self.outfile.write(",\n %sout_%s" % (a.ctype_out, a.name)) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList **out_fd_list") + self.outfile.write( + ",\n" + " GAsyncResult *res,\n" + " GError **error)\n" + "{\n" + " GVariant *_ret;\n" + ) + if m.unix_fd: + self.outfile.write( + " _ret = g_dbus_proxy_call_with_unix_fd_list_finish (G_DBUS_PROXY (proxy), out_fd_list, res, error);\n" + ) + else: + self.outfile.write( + " _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);\n" + ) + self.outfile.write(" if (_ret == NULL)\n" " goto _out;\n") + self.outfile.write(" g_variant_get (_ret,\n" ' "(') + for a in m.out_args: + self.outfile.write("%s" % (a.format_out)) + self.outfile.write(')"') + for a in m.out_args: + self.outfile.write(",\n out_%s" % (a.name)) + self.outfile.write(");\n" " g_variant_unref (_ret);\n") + self.outfile.write("_out:\n" " return _ret != NULL;\n" "}\n" "\n") + + # sync + self.outfile.write( + "/**\n" + " * %s_call_%s_sync:\n" + " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.in_args: + self.outfile.write( + " * @arg_%s: Argument to pass with the method invocation.\n" + % (a.name) + ) + if self.glib_min_required >= (2, 64): + self.outfile.write( + " * @call_flags: Flags from the #GDBusCallFlags enumeration. If you want to allow interactive\n" + " authorization be sure to set %G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.\n" + ' * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning "infinite") or\n' + " -1 to use the proxy default timeout.\n" + ) + if m.unix_fd: + self.outfile.write( + " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n" + ) + for a in m.out_args: + self.outfile.write( + " * @out_%s: (out) (optional)%s: Return location for return parameter or %%NULL to ignore.\n" + % (a.name, " " + a.array_annotation if a.array_annotation else "") + ) + if m.unix_fd: + self.outfile.write( + " * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.\n" + ) + self.outfile.write( + self.docbook_gen.expand( + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @error: Return location for error or %%NULL.\n" + " *\n" + " * Synchronously invokes the %s.%s() D-Bus method on @proxy. The calling thread is blocked until a reply is received.\n" + " *\n" + " * See %s_call_%s() for the asynchronous version of this method.\n" + " *\n" + " * Returns: (skip): %%TRUE if the call succeeded, %%FALSE if @error is set.\n" + % (i.name, m.name, i.name_lower, m.name_lower), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0) + self.outfile.write( + "gboolean\n" + "%s_call_%s_sync (\n" + " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) + ) + for a in m.in_args: + self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) + if self.glib_min_required >= (2, 64): + self.outfile.write( + ",\n GDBusCallFlags call_flags" ",\n gint timeout_msec" + ) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList *fd_list") + for a in m.out_args: + self.outfile.write(",\n %sout_%s" % (a.ctype_out, a.name)) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList **out_fd_list") + self.outfile.write( + ",\n" + " GCancellable *cancellable,\n" + " GError **error)\n" + "{\n" + " GVariant *_ret;\n" + ) + if m.unix_fd: + self.outfile.write( + " _ret = g_dbus_proxy_call_with_unix_fd_list_sync (G_DBUS_PROXY (proxy),\n" + ) + else: + self.outfile.write( + " _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),\n" + ) + self.outfile.write(' "%s",\n' ' g_variant_new ("(' % (m.name)) + for a in m.in_args: + self.outfile.write("%s" % (a.format_in)) + self.outfile.write(')"') + for a in m.in_args: + self.outfile.write(",\n arg_%s" % (a.name)) + self.outfile.write("),\n") + if self.glib_min_required >= (2, 64): + self.outfile.write(" call_flags,\n" " timeout_msec,\n") + else: + self.outfile.write(" G_DBUS_CALL_FLAGS_NONE,\n" " -1,\n") + if m.unix_fd: + self.outfile.write(" fd_list,\n" " out_fd_list,\n") + self.outfile.write( + " cancellable,\n" + " error);\n" + " if (_ret == NULL)\n" + " goto _out;\n" + ) + self.outfile.write(" g_variant_get (_ret,\n" ' "(') + for a in m.out_args: + self.outfile.write("%s" % (a.format_out)) + self.outfile.write(')"') + for a in m.out_args: + self.outfile.write(",\n out_%s" % (a.name)) + self.outfile.write(");\n" " g_variant_unref (_ret);\n") + self.outfile.write("_out:\n" " return _ret != NULL;\n" "}\n" "\n") + + # --------------------------------------------------------------------------------------------------- + + def generate_method_completers(self, i): + for m in i.methods: + self.outfile.write( + "/**\n" + " * %s_complete_%s:\n" + " * @object: A #%s.\n" + " * @invocation: (transfer full): A #GDBusMethodInvocation.\n" + % (i.name_lower, m.name_lower, i.camel_name) + ) + if m.unix_fd: + self.outfile.write( + " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n" + ) + for a in m.out_args: + self.outfile.write(" * @%s: Parameter to return.\n" % (a.name)) + self.outfile.write( + self.docbook_gen.expand( + " *\n" + " * Helper function used in service implementations to finish handling invocations of the %s.%s() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.\n" + " *\n" + " * This method will free @invocation, you cannot use it afterwards.\n" + % (i.name, m.name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0) + self.outfile.write( + "void\n" + "%s_complete_%s (\n" + " %s *object G_GNUC_UNUSED,\n" + " GDBusMethodInvocation *invocation" + % (i.name_lower, m.name_lower, i.camel_name) + ) + if m.unix_fd: + self.outfile.write(",\n GUnixFDList *fd_list") + for a in m.out_args: + self.outfile.write(",\n %s%s" % (a.ctype_in, a.name)) + self.outfile.write(")\n" "{\n") + + if m.unix_fd: + self.outfile.write( + " g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,\n" + ' g_variant_new ("(' + ) + else: + self.outfile.write( + " g_dbus_method_invocation_return_value (invocation,\n" + ' g_variant_new ("(' + ) + for a in m.out_args: + self.outfile.write("%s" % (a.format_in)) + self.outfile.write(')"') + for a in m.out_args: + self.outfile.write(",\n %s" % (a.name)) + if m.unix_fd: + self.outfile.write("),\n fd_list);\n") + else: + self.outfile.write("));\n") + self.outfile.write("}\n" "\n") + + # --------------------------------------------------------------------------------------------------- + + def generate_proxy(self, i): + # class boilerplate + self.outfile.write( + "/* ------------------------------------------------------------------------ */\n" + "\n" + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sProxy:\n" + " *\n" + " * The #%sProxy structure contains only private data and should only be accessed using the provided API.\n" + % (i.camel_name, i.camel_name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write("\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sProxyClass:\n" + " * @parent_class: The parent class.\n" + " *\n" + " * Class structure for #%sProxy.\n" % (i.camel_name, i.camel_name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write("\n") + + self.outfile.write( + "struct _%sProxyPrivate\n" + "{\n" + " GData *qdata;\n" + "};\n" + "\n" % i.camel_name + ) + + self.outfile.write( + "static void %s_proxy_iface_init (%sIface *iface);\n" + "\n" % (i.name_lower, i.camel_name) + ) + self.outfile.write("#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n") + self.outfile.write( + "G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n" + % (i.camel_name, i.name_lower) + ) + self.outfile.write( + " G_ADD_PRIVATE (%sProxy)\n" % (i.camel_name) + ) + self.outfile.write( + " G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init))\n\n" + % (i.ns_upper, i.name_upper, i.name_lower) + ) + self.outfile.write("#else\n") + self.outfile.write( + "G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n" + % (i.camel_name, i.name_lower) + ) + self.outfile.write( + " G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init))\n\n" + % (i.ns_upper, i.name_upper, i.name_lower) + ) + self.outfile.write("#endif\n") + + # finalize + self.outfile.write( + "static void\n" + "%s_proxy_finalize (GObject *object)\n" + "{\n" % (i.name_lower) + ) + self.outfile.write( + " %sProxy *proxy = %s%s_PROXY (object);\n" + % (i.camel_name, i.ns_upper, i.name_upper) + ) + self.outfile.write(" g_datalist_clear (&proxy->priv->qdata);\n") + self.outfile.write( + " G_OBJECT_CLASS (%s_proxy_parent_class)->finalize (object);\n" + "}\n" + "\n" % (i.name_lower) + ) + + # property accessors + # + # Note that we are guaranteed that prop_id starts at 1 and is + # laid out in the same order as introspection data pointers + # + self.outfile.write( + "static void\n" + "%s_proxy_get_property (GObject *object" % (i.name_lower) + ) + if len(i.properties) == 0: + self.outfile.write( + " G_GNUC_UNUSED,\n" + " guint prop_id G_GNUC_UNUSED,\n" + " GValue *value G_GNUC_UNUSED,\n" + ) + else: + self.outfile.write( + ",\n" " guint prop_id,\n" " GValue *value,\n" + ) + self.outfile.write(" GParamSpec *pspec G_GNUC_UNUSED)\n" "{\n") + if len(i.properties) > 0: + self.outfile.write( + " const _ExtendedGDBusPropertyInfo *info;\n" + " GVariant *variant;\n" + " g_assert (prop_id != 0 && prop_id - 1 < %d);\n" + " info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n" + " variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);\n" + " if (info->use_gvariant)\n" + " {\n" + " g_value_set_variant (value, variant);\n" + " }\n" + " else\n" + " {\n" + # could be that we don't have the value in cache - in that case, we do + # nothing and the user gets the default value for the GType + " if (variant != NULL)\n" + " g_dbus_gvariant_to_gvalue (variant, value);\n" + " }\n" + " if (variant != NULL)\n" + " g_variant_unref (variant);\n" % (len(i.properties), i.name_lower) + ) + self.outfile.write("}\n" "\n") + if len(i.properties) > 0: + self.outfile.write( + "static void\n" + "%s_proxy_set_property_cb (GDBusProxy *proxy,\n" + " GAsyncResult *res,\n" + " gpointer user_data)\n" + "{\n" % (i.name_lower) + ) + self.outfile.write( + " const _ExtendedGDBusPropertyInfo *info = user_data;\n" + " GError *error;\n" + " GVariant *_ret;\n" + " error = NULL;\n" + " _ret = g_dbus_proxy_call_finish (proxy, res, &error);\n" + " if (!_ret)\n" + " {\n" + " g_warning (\"Error setting property '%%s' on interface %s: %%s (%%s, %%d)\",\n" + " info->parent_struct.name, \n" + " error->message, g_quark_to_string (error->domain), error->code);\n" + " g_error_free (error);\n" + " }\n" + " else\n" + " {\n" + " g_variant_unref (_ret);\n" + " }\n" % (i.name) + ) + self.outfile.write("}\n" "\n") + self.outfile.write("static void\n" "%s_proxy_set_property (" % (i.name_lower)) + if len(i.properties) == 0: + self.outfile.write( + "GObject *object G_GNUC_UNUSED,\n" + " guint prop_id G_GNUC_UNUSED,\n" + " const GValue *value G_GNUC_UNUSED,\n" + ) + else: + self.outfile.write( + "GObject *object,\n" + " guint prop_id,\n" + " const GValue *value,\n" + ) + self.outfile.write(" GParamSpec *pspec G_GNUC_UNUSED)\n" "{\n") + if len(i.properties) > 0: + self.outfile.write( + " const _ExtendedGDBusPropertyInfo *info;\n" + " GVariant *variant;\n" + " g_assert (prop_id != 0 && prop_id - 1 < %d);\n" + " info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n" + " variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));\n" + " g_dbus_proxy_call (G_DBUS_PROXY (object),\n" + ' "org.freedesktop.DBus.Properties.Set",\n' + ' g_variant_new ("(ssv)", "%s", info->parent_struct.name, variant),\n' + " G_DBUS_CALL_FLAGS_NONE,\n" + " -1,\n" + " NULL, (GAsyncReadyCallback) %s_proxy_set_property_cb, (GDBusPropertyInfo *) &info->parent_struct);\n" + " g_variant_unref (variant);\n" + % (len(i.properties), i.name_lower, i.name, i.name_lower) + ) + self.outfile.write("}\n" "\n") + + # signal received + self.outfile.write( + "static void\n" + "%s_proxy_g_signal (GDBusProxy *proxy,\n" + " const gchar *sender_name G_GNUC_UNUSED,\n" + " const gchar *signal_name,\n" + " GVariant *parameters)\n" + "{\n" % (i.name_lower) + ) + self.outfile.write( + " _ExtendedGDBusSignalInfo *info;\n" + " GVariantIter iter;\n" + " GVariant *child;\n" + " GValue *paramv;\n" + " gsize num_params;\n" + " gsize n;\n" + " guint signal_id;\n" + ) + # Note: info could be NULL if we are talking to a newer version of the interface + self.outfile.write( + " info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, signal_name);\n" + " if (info == NULL)\n" + " return;\n" % (i.name_lower) + ) + self.outfile.write( + " num_params = g_variant_n_children (parameters);\n" + " paramv = g_new0 (GValue, num_params + 1);\n" + " g_value_init (¶mv[0], %sTYPE_%s);\n" + " g_value_set_object (¶mv[0], proxy);\n" % (i.ns_upper, i.name_upper) + ) + self.outfile.write( + " g_variant_iter_init (&iter, parameters);\n" + " n = 1;\n" + " while ((child = g_variant_iter_next_value (&iter)) != NULL)\n" + " {\n" + " _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];\n" + " if (arg_info->use_gvariant)\n" + " {\n" + " g_value_init (¶mv[n], G_TYPE_VARIANT);\n" + " g_value_set_variant (¶mv[n], child);\n" + " n++;\n" + " }\n" + " else\n" + " g_dbus_gvariant_to_gvalue (child, ¶mv[n++]);\n" + " g_variant_unref (child);\n" + " }\n" + ) + self.outfile.write( + " signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n" + % (i.ns_upper, i.name_upper) + ) + self.outfile.write(" g_signal_emitv (paramv, signal_id, 0, NULL);\n") + self.outfile.write( + " for (n = 0; n < num_params + 1; n++)\n" + " g_value_unset (¶mv[n]);\n" + " g_free (paramv);\n" + ) + self.outfile.write("}\n" "\n") + + # property changed + self.outfile.write( + "static void\n" + "%s_proxy_g_properties_changed (GDBusProxy *_proxy,\n" + " GVariant *changed_properties,\n" + " const gchar *const *invalidated_properties)\n" + "{\n" % (i.name_lower) + ) + # Note: info could be NULL if we are talking to a newer version of the interface + self.outfile.write( + " %sProxy *proxy = %s%s_PROXY (_proxy);\n" + " guint n;\n" + " const gchar *key;\n" + " GVariantIter *iter;\n" + " _ExtendedGDBusPropertyInfo *info;\n" + ' g_variant_get (changed_properties, "a{sv}", &iter);\n' + ' while (g_variant_iter_next (iter, "{&sv}", &key, NULL))\n' + " {\n" + " info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, key);\n" + " g_datalist_remove_data (&proxy->priv->qdata, key);\n" + " if (info != NULL)\n" + " g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n" + " }\n" + " g_variant_iter_free (iter);\n" + " for (n = 0; invalidated_properties[n] != NULL; n++)\n" + " {\n" + " info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, invalidated_properties[n]);\n" + " g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);\n" + " if (info != NULL)\n" + " g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n" + " }\n" + "}\n" + "\n" % (i.camel_name, i.ns_upper, i.name_upper, i.name_lower, i.name_lower) + ) + + # property vfuncs + for p in i.properties: + nul_value = "0" + if p.arg.free_func is not None: + nul_value = "NULL" + self.outfile.write( + "static %s\n" + "%s_proxy_get_%s (%s *object)\n" + "{\n" + " %sProxy *proxy = %s%s_PROXY (object);\n" + " GVariant *variant;\n" + " %svalue = %s;\n" + % ( + p.arg.ctype_in, + i.name_lower, + p.name_lower, + i.camel_name, + i.camel_name, + i.ns_upper, + i.name_upper, + p.arg.ctype_in, + nul_value, + ) + ) + # For some property types, we have to free the returned + # value (or part of it, e.g. the container) because of how + # GVariant works.. see https://bugzilla.gnome.org/show_bug.cgi?id=657100 + # for details + # + free_container = False + if ( + p.arg.gvariant_get == "g_variant_get_strv" + or p.arg.gvariant_get == "g_variant_get_objv" + or p.arg.gvariant_get == "g_variant_get_bytestring_array" + ): + free_container = True + # If already using an old value for strv, objv, bytestring_array (see below), + # then just return that... that way the result from multiple consecutive calls + # to the getter are valid as long as they're freed + # + if free_container: + self.outfile.write( + ' value = g_datalist_get_data (&proxy->priv->qdata, "%s");\n' + " if (value != NULL)\n" + " return value;\n" % (p.name) + ) + self.outfile.write( + ' variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "%s");\n' + % (p.name) + ) + if p.arg.gtype == "G_TYPE_VARIANT": + self.outfile.write(" value = variant;\n") + self.outfile.write(" if (variant != NULL)\n") + self.outfile.write(" g_variant_unref (variant);\n") + else: + self.outfile.write(" if (variant != NULL)\n" " {\n") + extra_len = "" + if ( + p.arg.gvariant_get == "g_variant_get_string" + or p.arg.gvariant_get == "g_variant_get_strv" + or p.arg.gvariant_get == "g_variant_get_objv" + or p.arg.gvariant_get == "g_variant_get_bytestring_array" + ): + extra_len = ", NULL" + self.outfile.write( + " value = %s (variant%s);\n" % (p.arg.gvariant_get, extra_len) + ) + if free_container: + self.outfile.write( + ' g_datalist_set_data_full (&proxy->priv->qdata, "%s", (gpointer) value, g_free);\n' + % (p.name) + ) + self.outfile.write(" g_variant_unref (variant);\n") + self.outfile.write(" }\n") + self.outfile.write(" return value;\n") + self.outfile.write("}\n") + self.outfile.write("\n") + + # class boilerplate + self.outfile.write( + "static void\n" + "%s_proxy_init (%sProxy *proxy)\n" + "{\n" + "#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n" + " proxy->priv = %s_proxy_get_instance_private (proxy);\n" + "#else\n" + " proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, %sTYPE_%s_PROXY, %sProxyPrivate);\n" + "#endif\n\n" + " g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), %s_interface_info ());\n" + "}\n" + "\n" + % ( + i.name_lower, + i.camel_name, + i.name_lower, + i.ns_upper, + i.name_upper, + i.camel_name, + i.name_lower, + ) + ) + self.outfile.write( + "static void\n" + "%s_proxy_class_init (%sProxyClass *klass)\n" + "{\n" + " GObjectClass *gobject_class;\n" + " GDBusProxyClass *proxy_class;\n" + "\n" + " gobject_class = G_OBJECT_CLASS (klass);\n" + " gobject_class->finalize = %s_proxy_finalize;\n" + " gobject_class->get_property = %s_proxy_get_property;\n" + " gobject_class->set_property = %s_proxy_set_property;\n" + "\n" + " proxy_class = G_DBUS_PROXY_CLASS (klass);\n" + " proxy_class->g_signal = %s_proxy_g_signal;\n" + " proxy_class->g_properties_changed = %s_proxy_g_properties_changed;\n" + "\n" + % ( + i.name_lower, + i.camel_name, + i.name_lower, + i.name_lower, + i.name_lower, + i.name_lower, + i.name_lower, + ) + ) + if len(i.properties) > 0: + self.outfile.write( + " %s_override_properties (gobject_class, 1);\n\n" % (i.name_lower) + ) + self.outfile.write( + "#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38\n" + " g_type_class_add_private (klass, sizeof (%sProxyPrivate));\n" + "#endif\n" % (i.camel_name) + ) + self.outfile.write("}\n" "\n") + + self.outfile.write( + "static void\n" + "%s_proxy_iface_init (%sIface *iface" % (i.name_lower, i.camel_name) + ) + if len(i.properties) == 0: + self.outfile.write(" G_GNUC_UNUSED)\n") + else: + self.outfile.write(")\n") + self.outfile.write("{\n") + for p in i.properties: + self.outfile.write( + " iface->get_%s = %s_proxy_get_%s;\n" + % (p.name_lower, i.name_lower, p.name_lower) + ) + self.outfile.write("}\n" "\n") + + # constructors + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_proxy_new:\n" + " * @connection: A #GDBusConnection.\n" + " * @flags: Flags from the #GDBusProxyFlags enumeration.\n" + " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n" + " * @object_path: An object path.\n" + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n" + " * @user_data: User data to pass to @callback.\n" + " *\n" + " * Asynchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new() for more details.\n" + " *\n" + " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" + " * You can then call %s_proxy_new_finish() to get the result of the operation.\n" + " *\n" + " * See %s_proxy_new_sync() for the synchronous, blocking version of this constructor.\n" + % (i.name_lower, i.name, i.name_lower, i.name_lower), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "void\n" + "%s_proxy_new (\n" + " GDBusConnection *connection,\n" + " GDBusProxyFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data)\n" + "{\n" + ' g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n' + "}\n" + "\n" % (i.name_lower, i.ns_upper, i.name_upper, i.name) + ) + self.outfile.write( + "/**\n" + " * %s_proxy_new_finish:\n" + " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new().\n" + " * @error: Return location for error or %%NULL\n" + " *\n" + " * Finishes an operation started with %s_proxy_new().\n" + " *\n" + " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n" + % (i.name_lower, i.name_lower, i.name_lower, i.camel_name) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "%s *\n" + "%s_proxy_new_finish (\n" + " GAsyncResult *res,\n" + " GError **error)\n" + "{\n" + " GObject *ret;\n" + " GObject *source_object;\n" + " source_object = g_async_result_get_source_object (res);\n" + " ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n" + " g_object_unref (source_object);\n" + " if (ret != NULL)\n" + " return %s%s (ret);\n" + " else\n" + " return NULL;\n" + "}\n" + "\n" % (i.camel_name, i.name_lower, i.ns_upper, i.name_upper) + ) + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_proxy_new_sync:\n" + " * @connection: A #GDBusConnection.\n" + " * @flags: Flags from the #GDBusProxyFlags enumeration.\n" + " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n" + " * @object_path: An object path.\n" + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @error: Return location for error or %%NULL\n" + " *\n" + " * Synchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new_sync() for more details.\n" + " *\n" + " * The calling thread is blocked until a reply is received.\n" + " *\n" + " * See %s_proxy_new() for the asynchronous version of this constructor.\n" + " *\n" + " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n" + % (i.name_lower, i.name, i.name_lower, i.camel_name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "%s *\n" + "%s_proxy_new_sync (\n" + " GDBusConnection *connection,\n" + " GDBusProxyFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GError **error)\n" + "{\n" + " GInitable *ret;\n" + ' ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n' + " if (ret != NULL)\n" + " return %s%s (ret);\n" + " else\n" + " return NULL;\n" + "}\n" + "\n" + % ( + i.camel_name, + i.name_lower, + i.ns_upper, + i.name_upper, + i.name, + i.ns_upper, + i.name_upper, + ) + ) + self.outfile.write("\n") + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_proxy_new_for_bus:\n" + " * @bus_type: A #GBusType.\n" + " * @flags: Flags from the #GDBusProxyFlags enumeration.\n" + " * @name: A bus name (well-known or unique).\n" + " * @object_path: An object path.\n" + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n" + " * @user_data: User data to pass to @callback.\n" + " *\n" + " * Like %s_proxy_new() but takes a #GBusType instead of a #GDBusConnection.\n" + " *\n" + " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" + " * You can then call %s_proxy_new_for_bus_finish() to get the result of the operation.\n" + " *\n" + " * See %s_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n" + % (i.name_lower, i.name_lower, i.name_lower, i.name_lower), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "void\n" + "%s_proxy_new_for_bus (\n" + " GBusType bus_type,\n" + " GDBusProxyFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data)\n" + "{\n" + ' g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n' + "}\n" + "\n" % (i.name_lower, i.ns_upper, i.name_upper, i.name) + ) + self.outfile.write( + "/**\n" + " * %s_proxy_new_for_bus_finish:\n" + " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new_for_bus().\n" + " * @error: Return location for error or %%NULL\n" + " *\n" + " * Finishes an operation started with %s_proxy_new_for_bus().\n" + " *\n" + " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n" + % (i.name_lower, i.name_lower, i.name_lower, i.camel_name) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "%s *\n" + "%s_proxy_new_for_bus_finish (\n" + " GAsyncResult *res,\n" + " GError **error)\n" + "{\n" + " GObject *ret;\n" + " GObject *source_object;\n" + " source_object = g_async_result_get_source_object (res);\n" + " ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n" + " g_object_unref (source_object);\n" + " if (ret != NULL)\n" + " return %s%s (ret);\n" + " else\n" + " return NULL;\n" + "}\n" + "\n" % (i.camel_name, i.name_lower, i.ns_upper, i.name_upper) + ) + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_proxy_new_for_bus_sync:\n" + " * @bus_type: A #GBusType.\n" + " * @flags: Flags from the #GDBusProxyFlags enumeration.\n" + " * @name: A bus name (well-known or unique).\n" + " * @object_path: An object path.\n" + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @error: Return location for error or %%NULL\n" + " *\n" + " * Like %s_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n" + " *\n" + " * The calling thread is blocked until a reply is received.\n" + " *\n" + " * See %s_proxy_new_for_bus() for the asynchronous version of this constructor.\n" + " *\n" + " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n" + % (i.name_lower, i.name_lower, i.name_lower, i.camel_name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "%s *\n" + "%s_proxy_new_for_bus_sync (\n" + " GBusType bus_type,\n" + " GDBusProxyFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GError **error)\n" + "{\n" + " GInitable *ret;\n" + ' ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n' + " if (ret != NULL)\n" + " return %s%s (ret);\n" + " else\n" + " return NULL;\n" + "}\n" + "\n" + % ( + i.camel_name, + i.name_lower, + i.ns_upper, + i.name_upper, + i.name, + i.ns_upper, + i.name_upper, + ) + ) + self.outfile.write("\n") + + # --------------------------------------------------------------------------------------------------- + + def generate_skeleton(self, i): + # class boilerplate + self.outfile.write( + "/* ------------------------------------------------------------------------ */\n" + "\n" + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sSkeleton:\n" + " *\n" + " * The #%sSkeleton structure contains only private data and should only be accessed using the provided API.\n" + % (i.camel_name, i.camel_name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write("\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sSkeletonClass:\n" + " * @parent_class: The parent class.\n" + " *\n" + " * Class structure for #%sSkeleton.\n" % (i.camel_name, i.camel_name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write("\n") + + self.outfile.write( + "struct _%sSkeletonPrivate\n" + "{\n" + " GValue *properties;\n" + " GList *changed_properties;\n" + " GSource *changed_properties_idle_source;\n" + " GMainContext *context;\n" + " GMutex lock;\n" + "};\n" + "\n" % i.camel_name + ) + + self.outfile.write( + "static void\n" + "_%s_skeleton_handle_method_call (\n" + " GDBusConnection *connection G_GNUC_UNUSED,\n" + " const gchar *sender G_GNUC_UNUSED,\n" + " const gchar *object_path G_GNUC_UNUSED,\n" + " const gchar *interface_name,\n" + " const gchar *method_name,\n" + " GVariant *parameters,\n" + " GDBusMethodInvocation *invocation,\n" + " gpointer user_data)\n" + "{\n" + " %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n" + " _ExtendedGDBusMethodInfo *info;\n" + " GVariantIter iter;\n" + " GVariant *child;\n" + " GValue *paramv;\n" + " gsize num_params;\n" + " guint num_extra;\n" + " gsize n;\n" + " guint signal_id;\n" + " GValue return_value = G_VALUE_INIT;\n" + % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) + ) + self.outfile.write( + " info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);\n" + " g_assert (info != NULL);\n" + ) + self.outfile.write( + " num_params = g_variant_n_children (parameters);\n" + " num_extra = info->pass_fdlist ? 3 : 2;" + " paramv = g_new0 (GValue, num_params + num_extra);\n" + " n = 0;\n" + " g_value_init (¶mv[n], %sTYPE_%s);\n" + " g_value_set_object (¶mv[n++], skeleton);\n" + " g_value_init (¶mv[n], G_TYPE_DBUS_METHOD_INVOCATION);\n" + " g_value_set_object (¶mv[n++], invocation);\n" + " if (info->pass_fdlist)\n" + " {\n" + "#ifdef G_OS_UNIX\n" + " g_value_init (¶mv[n], G_TYPE_UNIX_FD_LIST);\n" + " g_value_set_object (¶mv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));\n" + "#else\n" + " g_assert_not_reached ();\n" + "#endif\n" + " }\n" % (i.ns_upper, i.name_upper) + ) + self.outfile.write( + " g_variant_iter_init (&iter, parameters);\n" + " while ((child = g_variant_iter_next_value (&iter)) != NULL)\n" + " {\n" + " _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];\n" + " if (arg_info->use_gvariant)\n" + " {\n" + " g_value_init (¶mv[n], G_TYPE_VARIANT);\n" + " g_value_set_variant (¶mv[n], child);\n" + " n++;\n" + " }\n" + " else\n" + " g_dbus_gvariant_to_gvalue (child, ¶mv[n++]);\n" + " g_variant_unref (child);\n" + " }\n" + ) + self.outfile.write( + " signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n" + % (i.ns_upper, i.name_upper) + ) + self.outfile.write( + " g_value_init (&return_value, G_TYPE_BOOLEAN);\n" + " g_signal_emitv (paramv, signal_id, 0, &return_value);\n" + " if (!g_value_get_boolean (&return_value))\n" + ' g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);\n' + " g_value_unset (&return_value);\n" + ) + self.outfile.write( + " for (n = 0; n < num_params + num_extra; n++)\n" + " g_value_unset (¶mv[n]);\n" + " g_free (paramv);\n" + ) + self.outfile.write("}\n" "\n") + + self.outfile.write( + "static GVariant *\n" + "_%s_skeleton_handle_get_property (\n" + " GDBusConnection *connection G_GNUC_UNUSED,\n" + " const gchar *sender G_GNUC_UNUSED,\n" + " const gchar *object_path G_GNUC_UNUSED,\n" + " const gchar *interface_name G_GNUC_UNUSED,\n" + " const gchar *property_name,\n" + " GError **error,\n" + " gpointer user_data)\n" + "{\n" + " %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n" + " GValue value = G_VALUE_INIT;\n" + " GParamSpec *pspec;\n" + " _ExtendedGDBusPropertyInfo *info;\n" + " GVariant *ret;\n" + % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) + ) + self.outfile.write( + " ret = NULL;\n" + " info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, property_name);\n" + " g_assert (info != NULL);\n" + " pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n" + " if (pspec == NULL)\n" + " {\n" + ' g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n' + " }\n" + " else\n" + " {\n" + " g_value_init (&value, pspec->value_type);\n" + " g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n" + " ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));\n" + " g_value_unset (&value);\n" + " }\n" + " return ret;\n" + "}\n" + "\n" % (i.name_lower) + ) + + self.outfile.write( + "static gboolean\n" + "_%s_skeleton_handle_set_property (\n" + " GDBusConnection *connection G_GNUC_UNUSED,\n" + " const gchar *sender G_GNUC_UNUSED,\n" + " const gchar *object_path G_GNUC_UNUSED,\n" + " const gchar *interface_name G_GNUC_UNUSED,\n" + " const gchar *property_name,\n" + " GVariant *variant,\n" + " GError **error,\n" + " gpointer user_data)\n" + "{\n" + " %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n" + " GValue value = G_VALUE_INIT;\n" + " GParamSpec *pspec;\n" + " _ExtendedGDBusPropertyInfo *info;\n" + " gboolean ret;\n" % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) + ) + self.outfile.write( + " ret = FALSE;\n" + " info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, property_name);\n" + " g_assert (info != NULL);\n" + " pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n" + " if (pspec == NULL)\n" + " {\n" + ' g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n' + " }\n" + " else\n" + " {\n" + " if (info->use_gvariant)\n" + " g_value_set_variant (&value, variant);\n" + " else\n" + " g_dbus_gvariant_to_gvalue (variant, &value);\n" + " g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n" + " g_value_unset (&value);\n" + " ret = TRUE;\n" + " }\n" + " return ret;\n" + "}\n" + "\n" % (i.name_lower) + ) + + self.outfile.write( + "static const GDBusInterfaceVTable _%s_skeleton_vtable =\n" + "{\n" + " _%s_skeleton_handle_method_call,\n" + " _%s_skeleton_handle_get_property,\n" + " _%s_skeleton_handle_set_property,\n" + " {NULL}\n" + "};\n" + "\n" % (i.name_lower, i.name_lower, i.name_lower, i.name_lower) + ) + + self.outfile.write( + "static GDBusInterfaceInfo *\n" + "%s_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)\n" + "{\n" + " return %s_interface_info ();\n" % (i.name_lower, i.name_lower) + ) + self.outfile.write("}\n" "\n") + + self.outfile.write( + "static GDBusInterfaceVTable *\n" + "%s_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)\n" + "{\n" + " return (GDBusInterfaceVTable *) &_%s_skeleton_vtable;\n" + % (i.name_lower, i.name_lower) + ) + self.outfile.write("}\n" "\n") + + self.outfile.write( + "static GVariant *\n" + "%s_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)\n" + "{\n" + " %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n" + % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) + ) + self.outfile.write( + "\n" + " GVariantBuilder builder;\n" + " guint n;\n" + ' g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n' + " if (_%s_interface_info.parent_struct.properties == NULL)\n" + " goto out;\n" + " for (n = 0; _%s_interface_info.parent_struct.properties[n] != NULL; n++)\n" + " {\n" + " GDBusPropertyInfo *info = _%s_interface_info.parent_struct.properties[n];\n" + " if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)\n" + " {\n" + " GVariant *value;\n" + ' value = _%s_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", info->name, NULL, skeleton);\n' + " if (value != NULL)\n" + " {\n" + " g_variant_take_ref (value);\n" + ' g_variant_builder_add (&builder, "{sv}", info->name, value);\n' + " g_variant_unref (value);\n" + " }\n" + " }\n" + " }\n" + "out:\n" + " return g_variant_builder_end (&builder);\n" + "}\n" + "\n" % (i.name_lower, i.name_lower, i.name_lower, i.name_lower, i.name) + ) + + if len(i.properties) > 0: + self.outfile.write( + "static gboolean _%s_emit_changed (gpointer user_data);\n" + "\n" % (i.name_lower) + ) + + self.outfile.write( + "static void\n" + "%s_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton" + % (i.name_lower) + ) + if len(i.properties) == 0: + self.outfile.write(" G_GNUC_UNUSED)\n") + else: + self.outfile.write(")\n") + self.outfile.write("{\n") + if len(i.properties) > 0: + self.outfile.write( + " %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n" + " gboolean emit_changed = FALSE;\n" + "\n" + " g_mutex_lock (&skeleton->priv->lock);\n" + " if (skeleton->priv->changed_properties_idle_source != NULL)\n" + " {\n" + " g_source_destroy (skeleton->priv->changed_properties_idle_source);\n" + " skeleton->priv->changed_properties_idle_source = NULL;\n" + " emit_changed = TRUE;\n" + " }\n" + " g_mutex_unlock (&skeleton->priv->lock);\n" + "\n" + " if (emit_changed)\n" + " _%s_emit_changed (skeleton);\n" + % (i.camel_name, i.ns_upper, i.name_upper, i.name_lower) + ) + self.outfile.write("}\n" "\n") + + for s in i.signals: + self.outfile.write( + "static void\n" + "_%s_on_signal_%s (\n" + " %s *object" % (i.name_lower, s.name_lower, i.camel_name) + ) + for a in s.args: + self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) + self.outfile.write( + ")\n" + "{\n" + " %sSkeleton *skeleton = %s%s_SKELETON (object);\n\n" + " GList *connections, *l;\n" + " GVariant *signal_variant;\n" + " connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));\n" + % (i.camel_name, i.ns_upper, i.name_upper) + ) + self.outfile.write( + "\n" ' signal_variant = g_variant_ref_sink (g_variant_new ("(' + ) + for a in s.args: + self.outfile.write("%s" % (a.format_in)) + self.outfile.write(')"') + for a in s.args: + self.outfile.write(",\n arg_%s" % (a.name)) + self.outfile.write("));\n") + + self.outfile.write( + " for (l = connections; l != NULL; l = l->next)\n" + " {\n" + " GDBusConnection *connection = l->data;\n" + " g_dbus_connection_emit_signal (connection,\n" + ' NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", "%s",\n' + " signal_variant, NULL);\n" + " }\n" % (i.name, s.name) + ) + self.outfile.write(" g_variant_unref (signal_variant);\n") + self.outfile.write(" g_list_free_full (connections, g_object_unref);\n") + self.outfile.write("}\n" "\n") + + self.outfile.write( + "static void %s_skeleton_iface_init (%sIface *iface);\n" + % (i.name_lower, i.camel_name) + ) + + self.outfile.write("#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n") + self.outfile.write( + "G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n" + % (i.camel_name, i.name_lower) + ) + self.outfile.write( + " G_ADD_PRIVATE (%sSkeleton)\n" % (i.camel_name) + ) + self.outfile.write( + " G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init))\n\n" + % (i.ns_upper, i.name_upper, i.name_lower) + ) + self.outfile.write("#else\n") + self.outfile.write( + "G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n" + % (i.camel_name, i.name_lower) + ) + self.outfile.write( + " G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init))\n\n" + % (i.ns_upper, i.name_upper, i.name_lower) + ) + self.outfile.write("#endif\n") + + # finalize + self.outfile.write( + "static void\n" + "%s_skeleton_finalize (GObject *object)\n" + "{\n" % (i.name_lower) + ) + self.outfile.write( + " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" + % (i.camel_name, i.ns_upper, i.name_upper) + ) + if len(i.properties) > 0: + self.outfile.write( + " guint n;\n" + " for (n = 0; n < %d; n++)\n" + " g_value_unset (&skeleton->priv->properties[n]);\n" + % (len(i.properties)) + ) + self.outfile.write(" g_free (skeleton->priv->properties);\n") + self.outfile.write( + " g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);\n" + ) + self.outfile.write( + " if (skeleton->priv->changed_properties_idle_source != NULL)\n" + ) + self.outfile.write( + " g_source_destroy (skeleton->priv->changed_properties_idle_source);\n" + ) + self.outfile.write(" g_main_context_unref (skeleton->priv->context);\n") + self.outfile.write(" g_mutex_clear (&skeleton->priv->lock);\n") + self.outfile.write( + " G_OBJECT_CLASS (%s_skeleton_parent_class)->finalize (object);\n" + "}\n" + "\n" % (i.name_lower) + ) + + # property accessors (TODO: generate PropertiesChanged signals in setter) + if len(i.properties) > 0: + self.outfile.write( + "static void\n" + "%s_skeleton_get_property (GObject *object,\n" + " guint prop_id,\n" + " GValue *value,\n" + " GParamSpec *pspec G_GNUC_UNUSED)\n" + "{\n" % (i.name_lower) + ) + self.outfile.write( + " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" + " g_assert (prop_id != 0 && prop_id - 1 < %d);\n" + " g_mutex_lock (&skeleton->priv->lock);\n" + " g_value_copy (&skeleton->priv->properties[prop_id - 1], value);\n" + " g_mutex_unlock (&skeleton->priv->lock);\n" + % (i.camel_name, i.ns_upper, i.name_upper, len(i.properties)) + ) + self.outfile.write("}\n" "\n") + + # if property is already scheduled then re-use entry.. though it could be + # that the user did + # + # foo_set_prop_bar (object, ""); + # foo_set_prop_bar (object, "blah"); + # + # say, every update... In this case, where nothing happens, we obviously + # don't want a PropertiesChanged() event. We can easily check for this + # by comparing against the _original value_ recorded before the first + # change event. If the latest value is not different from the original + # one, we can simply ignore the ChangedProperty + # + self.outfile.write( + "static gboolean\n" + "_%s_emit_changed (gpointer user_data)\n" + "{\n" + " %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n" + % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) + ) + self.outfile.write( + " GList *l;\n" + " GVariantBuilder builder;\n" + " GVariantBuilder invalidated_builder;\n" + " guint num_changes;\n" + "\n" + " g_mutex_lock (&skeleton->priv->lock);\n" + ' g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n' + ' g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));\n' + " for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)\n" + " {\n" + " ChangedProperty *cp = l->data;\n" + " GVariant *variant;\n" + " const GValue *cur_value;\n" + "\n" + " cur_value = &skeleton->priv->properties[cp->prop_id - 1];\n" + " if (!_g_value_equal (cur_value, &cp->orig_value))\n" + " {\n" + " variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));\n" + ' g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);\n' + " g_variant_unref (variant);\n" + " num_changes++;\n" + " }\n" + " }\n" + " if (num_changes > 0)\n" + " {\n" + " GList *connections, *ll;\n" + " GVariant *signal_variant;" + "\n" + ' signal_variant = g_variant_ref_sink (g_variant_new ("(sa{sv}as)", "%s",\n' + " &builder, &invalidated_builder));\n" + " connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));\n" + " for (ll = connections; ll != NULL; ll = ll->next)\n" + " {\n" + " GDBusConnection *connection = ll->data;\n" + "\n" + " g_dbus_connection_emit_signal (connection,\n" + " NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),\n" + ' "org.freedesktop.DBus.Properties",\n' + ' "PropertiesChanged",\n' + " signal_variant,\n" + " NULL);\n" + " }\n" + " g_variant_unref (signal_variant);\n" + " g_list_free_full (connections, g_object_unref);\n" + " }\n" + " else\n" + " {\n" + " g_variant_builder_clear (&builder);\n" + " g_variant_builder_clear (&invalidated_builder);\n" + " }\n" % (i.name) + ) + self.outfile.write( + " g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);\n" + ) + self.outfile.write(" skeleton->priv->changed_properties = NULL;\n") + self.outfile.write( + " skeleton->priv->changed_properties_idle_source = NULL;\n" + ) + self.outfile.write(" g_mutex_unlock (&skeleton->priv->lock);\n") + self.outfile.write(" return FALSE;\n" "}\n" "\n") + # holding lock while being called + self.outfile.write( + "static void\n" + "_%s_schedule_emit_changed (%sSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)\n" + "{\n" + " ChangedProperty *cp;\n" + " GList *l;\n" + " cp = NULL;\n" + " for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)\n" + " {\n" + " ChangedProperty *i_cp = l->data;\n" + " if (i_cp->info == info)\n" + " {\n" + " cp = i_cp;\n" + " break;\n" + " }\n" + " }\n" % (i.name_lower, i.camel_name) + ) + self.outfile.write( + " if (cp == NULL)\n" + " {\n" + " cp = g_new0 (ChangedProperty, 1);\n" + " cp->prop_id = prop_id;\n" + " cp->info = info;\n" + " skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);\n" + " g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));\n" + " g_value_copy (orig_value, &cp->orig_value);\n" + " }\n" + "}\n" + "\n" + ) + + # Postpone setting up the refresh source until the ::notify signal is emitted as + # this allows use of g_object_freeze_notify()/g_object_thaw_notify() ... + # This is useful when updating several properties from another thread than + # where the idle will be emitted from + self.outfile.write( + "static void\n" + "%s_skeleton_notify (GObject *object,\n" + " GParamSpec *pspec G_GNUC_UNUSED)\n" + "{\n" + " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" + " g_mutex_lock (&skeleton->priv->lock);\n" + " if (skeleton->priv->changed_properties != NULL &&\n" + " skeleton->priv->changed_properties_idle_source == NULL)\n" + " {\n" + " skeleton->priv->changed_properties_idle_source = g_idle_source_new ();\n" + " g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);\n" + " g_source_set_callback (skeleton->priv->changed_properties_idle_source, _%s_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);\n" + ' g_source_set_name (skeleton->priv->changed_properties_idle_source, "[generated] _%s_emit_changed");\n' + " g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);\n" + " g_source_unref (skeleton->priv->changed_properties_idle_source);\n" + " }\n" + " g_mutex_unlock (&skeleton->priv->lock);\n" + "}\n" + "\n" + % ( + i.name_lower, + i.camel_name, + i.ns_upper, + i.name_upper, + i.name_lower, + i.name_lower, + ) + ) + + self.outfile.write( + "static void\n" + "%s_skeleton_set_property (GObject *object,\n" + " guint prop_id,\n" + " const GValue *value,\n" + " GParamSpec *pspec)\n" + "{\n" % (i.name_lower) + ) + self.outfile.write( + " const _ExtendedGDBusPropertyInfo *info;\n" + " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" + " g_assert (prop_id != 0 && prop_id - 1 < %d);\n" + " info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n" + " g_mutex_lock (&skeleton->priv->lock);\n" + " g_object_freeze_notify (object);\n" + " if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))\n" + " {\n" + " if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL &&\n" + " info->emits_changed_signal)\n" + " _%s_schedule_emit_changed (skeleton, info, prop_id, &skeleton->priv->properties[prop_id - 1]);\n" + " g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);\n" + " g_object_notify_by_pspec (object, pspec);\n" + " }\n" + " g_mutex_unlock (&skeleton->priv->lock);\n" + " g_object_thaw_notify (object);\n" + % ( + i.camel_name, + i.ns_upper, + i.name_upper, + len(i.properties), + i.name_lower, + i.name_lower, + ) + ) + self.outfile.write("}\n" "\n") + + self.outfile.write( + "static void\n" + "%s_skeleton_init (%sSkeleton *skeleton)\n" + "{\n" + "#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n" + " skeleton->priv = %s_skeleton_get_instance_private (skeleton);\n" + "#else\n" + " skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, %sTYPE_%s_SKELETON, %sSkeletonPrivate);\n" + "#endif\n\n" + % ( + i.name_lower, + i.camel_name, + i.name_lower, + i.ns_upper, + i.name_upper, + i.camel_name, + ) + ) + self.outfile.write(" g_mutex_init (&skeleton->priv->lock);\n") + self.outfile.write( + " skeleton->priv->context = g_main_context_ref_thread_default ();\n" + ) + if len(i.properties) > 0: + self.outfile.write( + " skeleton->priv->properties = g_new0 (GValue, %d);\n" + % (len(i.properties)) + ) + n = 0 + for p in i.properties: + self.outfile.write( + " g_value_init (&skeleton->priv->properties[%d], %s);\n" + % (n, p.arg.gtype) + ) + n += 1 + self.outfile.write("}\n" "\n") + + # property vfuncs + n = 0 + for p in i.properties: + self.outfile.write( + "static %s\n" + "%s_skeleton_get_%s (%s *object)\n" + "{\n" % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name) + ) + self.outfile.write( + " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" + % (i.camel_name, i.ns_upper, i.name_upper) + ) + self.outfile.write( + " %svalue;\n" + " g_mutex_lock (&skeleton->priv->lock);\n" + " value = %s (&(skeleton->priv->properties[%d]));\n" + " g_mutex_unlock (&skeleton->priv->lock);\n" + % (p.arg.ctype_in_g, p.arg.gvalue_get, n) + ) + self.outfile.write(" return value;\n") + self.outfile.write("}\n") + self.outfile.write("\n") + n += 1 + + self.outfile.write( + "static void\n" + "%s_skeleton_class_init (%sSkeletonClass *klass)\n" + "{\n" + " GObjectClass *gobject_class;\n" + " GDBusInterfaceSkeletonClass *skeleton_class;\n" + "\n" + " gobject_class = G_OBJECT_CLASS (klass);\n" + " gobject_class->finalize = %s_skeleton_finalize;\n" + % (i.name_lower, i.camel_name, i.name_lower) + ) + if len(i.properties) > 0: + self.outfile.write( + " gobject_class->get_property = %s_skeleton_get_property;\n" + " gobject_class->set_property = %s_skeleton_set_property;\n" + " gobject_class->notify = %s_skeleton_notify;\n" + "\n" % (i.name_lower, i.name_lower, i.name_lower) + ) + self.outfile.write( + "\n" " %s_override_properties (gobject_class, 1);\n" % (i.name_lower) + ) + self.outfile.write( + "\n" " skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);\n" + ) + self.outfile.write( + " skeleton_class->get_info = %s_skeleton_dbus_interface_get_info;\n" + % (i.name_lower) + ) + self.outfile.write( + " skeleton_class->get_properties = %s_skeleton_dbus_interface_get_properties;\n" + % (i.name_lower) + ) + self.outfile.write( + " skeleton_class->flush = %s_skeleton_dbus_interface_flush;\n" + % (i.name_lower) + ) + self.outfile.write( + " skeleton_class->get_vtable = %s_skeleton_dbus_interface_get_vtable;\n" + % (i.name_lower) + ) + + self.outfile.write( + "\n" + "#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38\n" + " g_type_class_add_private (klass, sizeof (%sSkeletonPrivate));\n" + "#endif\n" % (i.camel_name) + ) + + self.outfile.write("}\n" "\n") + + self.outfile.write( + "static void\n" + "%s_skeleton_iface_init (%sIface *iface" % (i.name_lower, i.camel_name) + ) + if len(i.signals) == 0 and len(i.properties) == 0: + self.outfile.write(" G_GNUC_UNUSED)\n") + else: + self.outfile.write(")\n") + self.outfile.write("{\n") + for s in i.signals: + self.outfile.write( + " iface->%s = _%s_on_signal_%s;\n" + % (s.name_lower, i.name_lower, s.name_lower) + ) + for p in i.properties: + self.outfile.write( + " iface->get_%s = %s_skeleton_get_%s;\n" + % (p.name_lower, i.name_lower, p.name_lower) + ) + self.outfile.write("}\n" "\n") + + # constructors + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %s_skeleton_new:\n" + " *\n" + " * Creates a skeleton object for the D-Bus interface #%s.\n" + " *\n" + " * Returns: (transfer full) (type %sSkeleton): The skeleton object.\n" + % (i.name_lower, i.name, i.camel_name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "%s *\n" + "%s_skeleton_new (void)\n" + "{\n" + " return %s%s (g_object_new (%sTYPE_%s_SKELETON, NULL));\n" + "}\n" + "\n" + % ( + i.camel_name, + i.name_lower, + i.ns_upper, + i.name_upper, + i.ns_upper, + i.name_upper, + ) + ) + + # --------------------------------------------------------------------------------------------------- + + def generate_object(self): + self.outfile.write( + "/* ------------------------------------------------------------------------\n" + " * Code for Object, ObjectProxy and ObjectSkeleton\n" + " * ------------------------------------------------------------------------\n" + " */\n" + "\n" + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * SECTION:%sObject\n" + " * @title: %sObject\n" + " * @short_description: Specialized GDBusObject types\n" + " *\n" + " * This section contains the #%sObject, #%sObjectProxy, and #%sObjectSkeleton types which make it easier to work with objects implementing generated types for D-Bus interfaces.\n" + " */\n" + % ( + self.namespace, + self.namespace, + self.namespace, + self.namespace, + self.namespace, + ), + False, + ) + ) + self.outfile.write("\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sObject:\n" + " *\n" + " * The #%sObject type is a specialized container of interfaces.\n" + " */\n" % (self.namespace, self.namespace), + False, + ) + ) + self.outfile.write("\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sObjectIface:\n" + " * @parent_iface: The parent interface.\n" + " *\n" + " * Virtual table for the #%sObject interface.\n" + " */\n" % (self.namespace, self.namespace), + False, + ) + ) + self.outfile.write("\n") + + self.outfile.write( + "typedef %sObjectIface %sObjectInterface;\n" + % (self.namespace, self.namespace) + ) + self.outfile.write( + "G_DEFINE_INTERFACE_WITH_CODE (%sObject, %sobject, G_TYPE_OBJECT, g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_DBUS_OBJECT);)\n" + % (self.namespace, self.ns_lower) + ) + self.outfile.write("\n") + self.outfile.write( + "static void\n" + "%sobject_default_init (%sObjectIface *iface)\n" + "{\n" % (self.ns_lower, self.namespace) + ) + for i in self.ifaces: + self.outfile.write( + self.docbook_gen.expand( + " /**\n" + " * %sObject:%s:\n" + " *\n" + " * The #%s instance corresponding to the D-Bus interface #%s, if any.\n" + " *\n" + " * Connect to the #GObject::notify signal to get informed of property changes.\n" + % (self.namespace, i.name_hyphen, i.camel_name, i.name), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 2) + flags = "G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS" + if i.deprecated: + flags = "G_PARAM_DEPRECATED | " + flags + self.outfile.write( + ' g_object_interface_install_property (iface, g_param_spec_object ("%s", "%s", "%s", %sTYPE_%s, %s));\n' + "\n" + % ( + i.name_hyphen, + i.name_hyphen, + i.name_hyphen, + self.ns_upper, + i.name_upper, + flags, + ) + ) + self.outfile.write("}\n" "\n") + + for i in self.ifaces: + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_get_%s:\n" + " * @object: A #%sObject.\n" + " *\n" + " * Gets the #%s instance for the D-Bus interface #%s on @object, if any.\n" + " *\n" + " * Returns: (transfer full) (nullable): A #%s that must be freed with g_object_unref() or %%NULL if @object does not implement the interface.\n" + % ( + self.ns_lower, + i.name_upper.lower(), + self.namespace, + i.camel_name, + i.name, + i.camel_name, + ), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "%s *%sobject_get_%s (%sObject *object)\n" + % (i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace) + ) + self.outfile.write( + "{\n" + " GDBusInterface *ret;\n" + ' ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' + " if (ret == NULL)\n" + " return NULL;\n" + " return %s%s (ret);\n" + "}\n" + "\n" % (i.name, self.ns_upper, i.name_upper) + ) + self.outfile.write("\n") + for i in self.ifaces: + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_peek_%s: (skip)\n" + " * @object: A #%sObject.\n" + " *\n" + " * Like %sobject_get_%s() but doesn't increase the reference count on the returned object.\n" + " *\n" + " * It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running.\n" + " *\n" + " * Returns: (transfer none) (nullable): A #%s or %%NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object.\n" + % ( + self.ns_lower, + i.name_upper.lower(), + self.namespace, + self.ns_lower, + i.name_upper.lower(), + i.camel_name, + ), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "%s *%sobject_peek_%s (%sObject *object)\n" + % (i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace) + ) + self.outfile.write( + "{\n" + " GDBusInterface *ret;\n" + ' ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' + " if (ret == NULL)\n" + " return NULL;\n" + " g_object_unref (ret);\n" + " return %s%s (ret);\n" + "}\n" + "\n" % (i.name, self.ns_upper, i.name_upper) + ) + self.outfile.write("\n") + # shared by ObjectProxy and ObjectSkeleton classes + self.outfile.write( + "static void\n" + "%sobject_notify (GDBusObject *object, GDBusInterface *interface)\n" + "{\n" + " _ExtendedGDBusInterfaceInfo *info = (_ExtendedGDBusInterfaceInfo *) g_dbus_interface_get_info (interface);\n" + " /* info can be NULL if the other end is using a D-Bus interface we don't know\n" + " * anything about, for example old generated code in this process talking to\n" + " * newer generated code in the other process. */\n" + " if (info != NULL)\n" + " g_object_notify (G_OBJECT (object), info->hyphen_name);\n" + "}\n" + "\n" % (self.ns_lower) + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sObjectProxy:\n" + " *\n" + " * The #%sObjectProxy structure contains only private data and should only be accessed using the provided API.\n" + % (self.namespace, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write("\n") + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sObjectProxyClass:\n" + " * @parent_class: The parent class.\n" + " *\n" + " * Class structure for #%sObjectProxy.\n" + % (self.namespace, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write("\n") + # class boilerplate + self.outfile.write( + "static void\n" + "%sobject_proxy__%sobject_iface_init (%sObjectIface *iface G_GNUC_UNUSED)\n" + "{\n" + "}\n" + "\n" % (self.ns_lower, self.ns_lower, self.namespace) + ) + self.outfile.write( + "static void\n" + "%sobject_proxy__g_dbus_object_iface_init (GDBusObjectIface *iface)\n" + "{\n" + " iface->interface_added = %sobject_notify;\n" + " iface->interface_removed = %sobject_notify;\n" + "}\n" + "\n" % (self.ns_lower, self.ns_lower, self.ns_lower) + ) + self.outfile.write("\n") + self.outfile.write( + "G_DEFINE_TYPE_WITH_CODE (%sObjectProxy, %sobject_proxy, G_TYPE_DBUS_OBJECT_PROXY,\n" + " G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_proxy__%sobject_iface_init)\n" + " G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_proxy__g_dbus_object_iface_init))\n" + "\n" + % ( + self.namespace, + self.ns_lower, + self.ns_upper, + self.ns_lower, + self.ns_lower, + self.ns_lower, + ) + ) + # class boilerplate + self.outfile.write( + "static void\n" + "%sobject_proxy_init (%sObjectProxy *object G_GNUC_UNUSED)\n" + "{\n" + "}\n" + "\n" % (self.ns_lower, self.namespace) + ) + self.outfile.write( + "static void\n" + "%sobject_proxy_set_property (GObject *gobject,\n" + " guint prop_id,\n" + " const GValue *value G_GNUC_UNUSED,\n" + " GParamSpec *pspec)\n" + "{\n" + " G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n" + % (self.ns_lower) + ) + self.outfile.write("}\n" "\n") + self.outfile.write( + "static void\n" + "%sobject_proxy_get_property (GObject *gobject,\n" + " guint prop_id,\n" + " GValue *value,\n" + " GParamSpec *pspec)\n" + "{\n" + " %sObjectProxy *object = %sOBJECT_PROXY (gobject);\n" + " GDBusInterface *interface;\n" + "\n" + " switch (prop_id)\n" + " {\n" % (self.ns_lower, self.namespace, self.ns_upper) + ) + n = 1 + for i in self.ifaces: + self.outfile.write( + " case %d:\n" + ' interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' + " g_value_take_object (value, interface);\n" + " break;\n" + "\n" % (n, i.name) + ) + n += 1 + self.outfile.write( + " default:\n" + " G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n" + " break;\n" + " }\n" + "}\n" + "\n" + ) + self.outfile.write( + "static void\n" + "%sobject_proxy_class_init (%sObjectProxyClass *klass)\n" + "{\n" + " GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n" + "\n" + " gobject_class->set_property = %sobject_proxy_set_property;\n" + " gobject_class->get_property = %sobject_proxy_get_property;\n" + "\n" % (self.ns_lower, self.namespace, self.ns_lower, self.ns_lower) + ) + n = 1 + for i in self.ifaces: + self.outfile.write( + ' g_object_class_override_property (gobject_class, %d, "%s");' + "\n" % (n, i.name_hyphen) + ) + n += 1 + self.outfile.write("}\n" "\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_proxy_new:\n" + " * @connection: A #GDBusConnection.\n" + " * @object_path: An object path.\n" + " *\n" + " * Creates a new proxy object.\n" + " *\n" + " * Returns: (transfer full): The proxy object.\n" + " */\n" % (self.ns_lower), + False, + ) + ) + self.outfile.write( + "%sObjectProxy *\n" + "%sobject_proxy_new (GDBusConnection *connection,\n" + " const gchar *object_path)\n" + "{\n" + " g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);\n" + " g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n" + ' return %sOBJECT_PROXY (g_object_new (%sTYPE_OBJECT_PROXY, "g-connection", connection, "g-object-path", object_path, NULL));\n' + "}\n" + "\n" % (self.namespace, self.ns_lower, self.ns_upper, self.ns_upper) + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sObjectSkeleton:\n" + " *\n" + " * The #%sObjectSkeleton structure contains only private data and should only be accessed using the provided API.\n" + % (self.namespace, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write("\n") + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sObjectSkeletonClass:\n" + " * @parent_class: The parent class.\n" + " *\n" + " * Class structure for #%sObjectSkeleton.\n" + % (self.namespace, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write("\n") + # class boilerplate + self.outfile.write( + "static void\n" + "%sobject_skeleton__%sobject_iface_init (%sObjectIface *iface G_GNUC_UNUSED)\n" + "{\n" + "}\n" + "\n" % (self.ns_lower, self.ns_lower, self.namespace) + ) + self.outfile.write("\n") + self.outfile.write( + "static void\n" + "%sobject_skeleton__g_dbus_object_iface_init (GDBusObjectIface *iface)\n" + "{\n" + " iface->interface_added = %sobject_notify;\n" + " iface->interface_removed = %sobject_notify;\n" + "}\n" + "\n" % (self.ns_lower, self.ns_lower, self.ns_lower) + ) + self.outfile.write( + "G_DEFINE_TYPE_WITH_CODE (%sObjectSkeleton, %sobject_skeleton, G_TYPE_DBUS_OBJECT_SKELETON,\n" + " G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_skeleton__%sobject_iface_init)\n" + " G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_skeleton__g_dbus_object_iface_init))\n" + "\n" + % ( + self.namespace, + self.ns_lower, + self.ns_upper, + self.ns_lower, + self.ns_lower, + self.ns_lower, + ) + ) + # class boilerplate + self.outfile.write( + "static void\n" + "%sobject_skeleton_init (%sObjectSkeleton *object G_GNUC_UNUSED)\n" + "{\n" + "}\n" + "\n" % (self.ns_lower, self.namespace) + ) + self.outfile.write( + "static void\n" + "%sobject_skeleton_set_property (GObject *gobject,\n" + " guint prop_id,\n" + " const GValue *value,\n" + " GParamSpec *pspec)\n" + "{\n" + " %sObjectSkeleton *object = %sOBJECT_SKELETON (gobject);\n" + " GDBusInterfaceSkeleton *interface;\n" + "\n" + " switch (prop_id)\n" + " {\n" % (self.ns_lower, self.namespace, self.ns_upper) + ) + n = 1 + for i in self.ifaces: + self.outfile.write( + " case %d:\n" + " interface = g_value_get_object (value);\n" + " if (interface != NULL)\n" + " {\n" + " g_warn_if_fail (%sIS_%s (interface));\n" + " g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface);\n" + " }\n" + " else\n" + " {\n" + ' g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "%s");\n' + " }\n" + " break;\n" + "\n" % (n, self.ns_upper, i.name_upper, i.name) + ) + n += 1 + self.outfile.write( + " default:\n" + " G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n" + " break;\n" + " }\n" + "}\n" + "\n" + ) + self.outfile.write( + "static void\n" + "%sobject_skeleton_get_property (GObject *gobject,\n" + " guint prop_id,\n" + " GValue *value,\n" + " GParamSpec *pspec)\n" + "{\n" + " %sObjectSkeleton *object = %sOBJECT_SKELETON (gobject);\n" + " GDBusInterface *interface;\n" + "\n" + " switch (prop_id)\n" + " {\n" % (self.ns_lower, self.namespace, self.ns_upper) + ) + n = 1 + for i in self.ifaces: + self.outfile.write( + " case %d:\n" + ' interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' + " g_value_take_object (value, interface);\n" + " break;\n" + "\n" % (n, i.name) + ) + n += 1 + self.outfile.write( + " default:\n" + " G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n" + " break;\n" + " }\n" + "}\n" + "\n" + ) + self.outfile.write( + "static void\n" + "%sobject_skeleton_class_init (%sObjectSkeletonClass *klass)\n" + "{\n" + " GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n" + "\n" + " gobject_class->set_property = %sobject_skeleton_set_property;\n" + " gobject_class->get_property = %sobject_skeleton_get_property;\n" + "\n" % (self.ns_lower, self.namespace, self.ns_lower, self.ns_lower) + ) + n = 1 + for i in self.ifaces: + self.outfile.write( + ' g_object_class_override_property (gobject_class, %d, "%s");' + "\n" % (n, i.name_hyphen) + ) + n += 1 + self.outfile.write("}\n" "\n") + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_skeleton_new:\n" + " * @object_path: An object path.\n" + " *\n" + " * Creates a new skeleton object.\n" + " *\n" + " * Returns: (transfer full): The skeleton object.\n" + " */\n" % (self.ns_lower), + False, + ) + ) + self.outfile.write( + "%sObjectSkeleton *\n" + "%sobject_skeleton_new (const gchar *object_path)\n" + "{\n" + " g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n" + ' return %sOBJECT_SKELETON (g_object_new (%sTYPE_OBJECT_SKELETON, "g-object-path", object_path, NULL));\n' + "}\n" + "\n" % (self.namespace, self.ns_lower, self.ns_upper, self.ns_upper) + ) + for i in self.ifaces: + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_skeleton_set_%s:\n" + " * @object: A #%sObjectSkeleton.\n" + " * @interface_: (nullable): A #%s or %%NULL to clear the interface.\n" + " *\n" + " * Sets the #%s instance for the D-Bus interface #%s on @object.\n" + % ( + self.ns_lower, + i.name_upper.lower(), + self.namespace, + i.camel_name, + i.camel_name, + i.name, + ), + False, + ) + ) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) + self.outfile.write( + "void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_)\n" + % (self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name) + ) + self.outfile.write( + "{\n" + ' g_object_set (G_OBJECT (object), "%s", interface_, NULL);\n' + "}\n" + "\n" % (i.name_hyphen) + ) + self.outfile.write("\n") + + def generate_object_manager_client(self): + self.outfile.write( + "/* ------------------------------------------------------------------------\n" + " * Code for ObjectManager client\n" + " * ------------------------------------------------------------------------\n" + " */\n" + "\n" + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * SECTION:%sObjectManagerClient\n" + " * @title: %sObjectManagerClient\n" + " * @short_description: Generated GDBusObjectManagerClient type\n" + " *\n" + " * This section contains a #GDBusObjectManagerClient that uses %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc.\n" + " */\n" % (self.namespace, self.namespace, self.ns_lower), + False, + ) + ) + self.outfile.write("\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sObjectManagerClient:\n" + " *\n" + " * The #%sObjectManagerClient structure contains only private data and should only be accessed using the provided API.\n" + % (self.namespace, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write("\n") + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sObjectManagerClientClass:\n" + " * @parent_class: The parent class.\n" + " *\n" + " * Class structure for #%sObjectManagerClient.\n" + % (self.namespace, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write("\n") + + # class boilerplate + self.outfile.write( + "G_DEFINE_TYPE (%sObjectManagerClient, %sobject_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT)\n" + "\n" % (self.namespace, self.ns_lower) + ) + + # class boilerplate + self.outfile.write( + "static void\n" + "%sobject_manager_client_init (%sObjectManagerClient *manager G_GNUC_UNUSED)\n" + "{\n" + "}\n" + "\n" % (self.ns_lower, self.namespace) + ) + self.outfile.write( + "static void\n" + "%sobject_manager_client_class_init (%sObjectManagerClientClass *klass G_GNUC_UNUSED)\n" + "{\n" + "}\n" + "\n" % (self.ns_lower, self.namespace) + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_manager_client_get_proxy_type:\n" + " * @manager: A #GDBusObjectManagerClient.\n" + " * @object_path: The object path of the remote object (unused).\n" + " * @interface_name: (nullable): Interface name of the remote object or %%NULL to get the object proxy #GType.\n" + " * @user_data: User data (unused).\n" + " *\n" + " * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusObjectProxy derived and #GDBusProxy derived types.\n" + " *\n" + " * Returns: A #GDBusProxy derived #GType if @interface_name is not %%NULL, otherwise the #GType for #%sObjectProxy.\n" + % (self.ns_lower, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write( + "GType\n" + "%sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name, gpointer user_data G_GNUC_UNUSED)\n" + "{\n" % (self.ns_lower) + ) + self.outfile.write( + " static gsize once_init_value = 0;\n" + " static GHashTable *lookup_hash;\n" + " GType ret;\n" + "\n" + " if (interface_name == NULL)\n" + " return %sTYPE_OBJECT_PROXY;\n" + " if (g_once_init_enter (&once_init_value))\n" + " {\n" + " lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);\n" + % (self.ns_upper) + ) + for i in self.ifaces: + self.outfile.write( + ' g_hash_table_insert (lookup_hash, (gpointer) "%s", GSIZE_TO_POINTER (%sTYPE_%s_PROXY));\n' + % (i.name, i.ns_upper, i.name_upper) + ) + self.outfile.write(" g_once_init_leave (&once_init_value, 1);\n" " }\n") + self.outfile.write( + " ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));\n" + " if (ret == (GType) 0)\n" + " ret = G_TYPE_DBUS_PROXY;\n" + ) + self.outfile.write(" return ret;\n" "}\n" "\n") + + # constructors + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_manager_client_new:\n" + " * @connection: A #GDBusConnection.\n" + " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n" + " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n" + " * @object_path: An object path.\n" + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n" + " * @user_data: User data to pass to @callback.\n" + " *\n" + " * Asynchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new() for more details.\n" + " *\n" + " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" + " * You can then call %sobject_manager_client_new_finish() to get the result of the operation.\n" + " *\n" + " * See %sobject_manager_client_new_sync() for the synchronous, blocking version of this constructor.\n" + % (self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write( + "void\n" + "%sobject_manager_client_new (\n" + " GDBusConnection *connection,\n" + " GDBusObjectManagerClientFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data)\n" + "{\n" + ' g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n' + "}\n" + "\n" % (self.ns_lower, self.ns_upper, self.ns_lower) + ) + self.outfile.write( + "/**\n" + " * %sobject_manager_client_new_finish:\n" + " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new().\n" + " * @error: Return location for error or %%NULL\n" + " *\n" + " * Finishes an operation started with %sobject_manager_client_new().\n" + " *\n" + " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n" + % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace) + ) + self.outfile.write(" */\n") + self.outfile.write( + "GDBusObjectManager *\n" + "%sobject_manager_client_new_finish (\n" + " GAsyncResult *res,\n" + " GError **error)\n" + "{\n" + " GObject *ret;\n" + " GObject *source_object;\n" + " source_object = g_async_result_get_source_object (res);\n" + " ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n" + " g_object_unref (source_object);\n" + " if (ret != NULL)\n" + " return G_DBUS_OBJECT_MANAGER (ret);\n" + " else\n" + " return NULL;\n" + "}\n" + "\n" % (self.ns_lower) + ) + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_manager_client_new_sync:\n" + " * @connection: A #GDBusConnection.\n" + " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n" + " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n" + " * @object_path: An object path.\n" + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @error: Return location for error or %%NULL\n" + " *\n" + " * Synchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new_sync() for more details.\n" + " *\n" + " * The calling thread is blocked until a reply is received.\n" + " *\n" + " * See %sobject_manager_client_new() for the asynchronous version of this constructor.\n" + " *\n" + " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n" + % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write( + "GDBusObjectManager *\n" + "%sobject_manager_client_new_sync (\n" + " GDBusConnection *connection,\n" + " GDBusObjectManagerClientFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GError **error)\n" + "{\n" + " GInitable *ret;\n" + ' ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n' + " if (ret != NULL)\n" + " return G_DBUS_OBJECT_MANAGER (ret);\n" + " else\n" + " return NULL;\n" + "}\n" + "\n" % (self.ns_lower, self.ns_upper, self.ns_lower) + ) + self.outfile.write("\n") + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_manager_client_new_for_bus:\n" + " * @bus_type: A #GBusType.\n" + " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n" + " * @name: A bus name (well-known or unique).\n" + " * @object_path: An object path.\n" + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n" + " * @user_data: User data to pass to @callback.\n" + " *\n" + " * Like %sobject_manager_client_new() but takes a #GBusType instead of a #GDBusConnection.\n" + " *\n" + " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" + " * You can then call %sobject_manager_client_new_for_bus_finish() to get the result of the operation.\n" + " *\n" + " * See %sobject_manager_client_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n" + % (self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write( + "void\n" + "%sobject_manager_client_new_for_bus (\n" + " GBusType bus_type,\n" + " GDBusObjectManagerClientFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GAsyncReadyCallback callback,\n" + " gpointer user_data)\n" + "{\n" + ' g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n' + "}\n" + "\n" % (self.ns_lower, self.ns_upper, self.ns_lower) + ) + self.outfile.write( + "/**\n" + " * %sobject_manager_client_new_for_bus_finish:\n" + " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new_for_bus().\n" + " * @error: Return location for error or %%NULL\n" + " *\n" + " * Finishes an operation started with %sobject_manager_client_new_for_bus().\n" + " *\n" + " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n" + % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace) + ) + self.outfile.write(" */\n") + self.outfile.write( + "GDBusObjectManager *\n" + "%sobject_manager_client_new_for_bus_finish (\n" + " GAsyncResult *res,\n" + " GError **error)\n" + "{\n" + " GObject *ret;\n" + " GObject *source_object;\n" + " source_object = g_async_result_get_source_object (res);\n" + " ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n" + " g_object_unref (source_object);\n" + " if (ret != NULL)\n" + " return G_DBUS_OBJECT_MANAGER (ret);\n" + " else\n" + " return NULL;\n" + "}\n" + "\n" % (self.ns_lower) + ) + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * %sobject_manager_client_new_for_bus_sync:\n" + " * @bus_type: A #GBusType.\n" + " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n" + " * @name: A bus name (well-known or unique).\n" + " * @object_path: An object path.\n" + " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" + " * @error: Return location for error or %%NULL\n" + " *\n" + " * Like %sobject_manager_client_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n" + " *\n" + " * The calling thread is blocked until a reply is received.\n" + " *\n" + " * See %sobject_manager_client_new_for_bus() for the asynchronous version of this constructor.\n" + " *\n" + " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n" + % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace), + False, + ) + ) + self.outfile.write(" */\n") + self.outfile.write( + "GDBusObjectManager *\n" + "%sobject_manager_client_new_for_bus_sync (\n" + " GBusType bus_type,\n" + " GDBusObjectManagerClientFlags flags,\n" + " const gchar *name,\n" + " const gchar *object_path,\n" + " GCancellable *cancellable,\n" + " GError **error)\n" + "{\n" + " GInitable *ret;\n" + ' ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n' + " if (ret != NULL)\n" + " return G_DBUS_OBJECT_MANAGER (ret);\n" + " else\n" + " return NULL;\n" + "}\n" + "\n" % (self.ns_lower, self.ns_upper, self.ns_lower) + ) + self.outfile.write("\n") + + # --------------------------------------------------------------------------------------------------- + + def write_gtkdoc_deprecated_and_since_and_close(self, obj, f, indent): + if len(obj.since) > 0: + f.write("%*s *\n" "%*s * Since: %s\n" % (indent, "", indent, "", obj.since)) + if obj.deprecated: + if isinstance(obj, dbustypes.Interface): + thing = "The D-Bus interface" + elif isinstance(obj, dbustypes.Method): + thing = "The D-Bus method" + elif isinstance(obj, dbustypes.Signal): + thing = "The D-Bus signal" + elif isinstance(obj, dbustypes.Property): + thing = "The D-Bus property" + else: + print_error('Cannot handle object "{}"'.format(obj)) + f.write( + self.docbook_gen.expand( + "%*s *\n" + "%*s * Deprecated: %s has been deprecated.\n" + % (indent, "", indent, "", thing), + False, + ) + ) + f.write("%*s */\n" % (indent, "")) + + # --------------------------------------------------------------------------------------------------- + + def generate_interface_intro(self, i): + self.outfile.write( + "/* ------------------------------------------------------------------------\n" + " * Code for interface %s\n" + " * ------------------------------------------------------------------------\n" + " */\n" + "\n" % (i.name) + ) + + self.outfile.write( + self.docbook_gen.expand( + "/**\n" + " * SECTION:%s\n" + " * @title: %s\n" + " * @short_description: Generated C code for the %s D-Bus interface\n" + " *\n" + " * This section contains code for working with the #%s D-Bus interface in C.\n" + " */\n" % (i.camel_name, i.camel_name, i.name, i.name), + False, + ) + ) + self.outfile.write("\n") + + def generate(self): + self.generate_body_preamble() + for i in self.ifaces: + self.generate_interface_intro(i) + self.generate_introspection_for_interface(i) + self.generate_interface(i) + self.generate_property_accessors(i) + self.generate_signal_emitters(i) + self.generate_method_calls(i) + self.generate_method_completers(i) + self.generate_proxy(i) + self.generate_skeleton(i) + if self.generate_objmanager: + self.generate_object() + self.generate_object_manager_client() diff --git a/gio/gdbus-2.0/codegen/codegen_docbook.py b/gio/gdbus-2.0/codegen/codegen_docbook.py new file mode 100644 index 0000000..b7280e3 --- /dev/null +++ b/gio/gdbus-2.0/codegen/codegen_docbook.py @@ -0,0 +1,480 @@ +# -*- Mode: Python -*- + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +import re +from os import path + +from . import utils + + +# ---------------------------------------------------------------------------------------------------- + + +class DocbookCodeGenerator: + def __init__(self, ifaces): + self.ifaces = ifaces + self.generate_expand_dicts() + + def print_method_prototype(self, i, m, in_synopsis): + max_method_len = 0 + if in_synopsis: + for _m in i.methods: + max_method_len = max(len(_m.name), max_method_len) + else: + max_method_len = max(len(m.name), max_method_len) + + max_signature_len = 0 + if in_synopsis: + for _m in i.methods: + for a in _m.in_args: + max_signature_len = max(len(a.signature), max_signature_len) + for a in _m.out_args: + max_signature_len = max(len(a.signature), max_signature_len) + else: + for a in m.in_args: + max_signature_len = max(len(a.signature), max_signature_len) + for a in m.out_args: + max_signature_len = max(len(a.signature), max_signature_len) + + if in_synopsis: + self.out.write( + '%s%*s (' + % ( + utils.dots_to_hyphens(i.name), + m.name, + m.name, + max_method_len - len(m.name), + "", + ) + ) + else: + self.out.write("%s%*s (" % (m.name, max_method_len - len(m.name), "")) + count = 0 + for a in m.in_args: + if count > 0: + self.out.write(",\n%*s" % (max_method_len + 2, "")) + self.out.write( + "IN %s%*s %s" + % (a.signature, max_signature_len - len(a.signature), "", a.name) + ) + count = count + 1 + for a in m.out_args: + if count > 0: + self.out.write(",\n%*s" % (max_method_len + 2, "")) + self.out.write( + "OUT %s%*s %s" + % (a.signature, max_signature_len - len(a.signature), "", a.name) + ) + count = count + 1 + self.out.write(");\n") + + def print_signal_prototype(self, i, s, in_synopsis): + max_signal_len = 0 + if in_synopsis: + for _s in i.signals: + max_signal_len = max(len(_s.name), max_signal_len) + else: + max_signal_len = max(len(s.name), max_signal_len) + + max_signature_len = 0 + if in_synopsis: + for _s in i.signals: + for a in _s.args: + max_signature_len = max(len(a.signature), max_signature_len) + else: + for a in s.args: + max_signature_len = max(len(a.signature), max_signature_len) + + if in_synopsis: + self.out.write( + '%s%*s (' + % ( + utils.dots_to_hyphens(i.name), + s.name, + s.name, + max_signal_len - len(s.name), + "", + ) + ) + else: + self.out.write("%s%*s (" % (s.name, max_signal_len - len(s.name), "")) + count = 0 + for a in s.args: + if count > 0: + self.out.write(",\n%*s" % (max_signal_len + 2, "")) + self.out.write( + "%s%*s %s" + % (a.signature, max_signature_len - len(a.signature), "", a.name) + ) + count = count + 1 + self.out.write(");\n") + + def print_property_prototype(self, i, p, in_synopsis): + max_property_len = 0 + if in_synopsis: + for _p in i.properties: + max_property_len = max(len(_p.name), max_property_len) + else: + max_property_len = max(len(p.name), max_property_len) + + max_signature_len = 0 + if in_synopsis: + for _p in i.properties: + max_signature_len = max(len(_p.signature), max_signature_len) + else: + max_signature_len = max(len(p.signature), max_signature_len) + + if in_synopsis: + self.out.write( + '%s%*s' + % ( + utils.dots_to_hyphens(i.name), + p.name, + p.name, + max_property_len - len(p.name), + "", + ) + ) + else: + self.out.write("%s%*s" % (p.name, max_property_len - len(p.name), "")) + if p.readable and p.writable: + access = "readwrite" + elif p.readable: + access = "readable " + else: + access = "writable " + self.out.write(" %s %s\n" % (access, p.signature)) + + def print_synopsis_methods(self, i): + self.out.write(' \n') + self.out.write(' Methods\n') + self.out.write(" \n") + for m in i.methods: + self.print_method_prototype(i, m, in_synopsis=True) + self.out.write("\n") + self.out.write(" \n") + + def print_synopsis_signals(self, i): + self.out.write(' \n') + self.out.write(' Signals\n') + self.out.write(" \n") + for s in i.signals: + self.print_signal_prototype(i, s, in_synopsis=True) + self.out.write("\n") + self.out.write(" \n") + + def print_synopsis_properties(self, i): + self.out.write(' \n') + self.out.write(' Properties\n') + self.out.write(" \n") + for p in i.properties: + self.print_property_prototype(i, p, in_synopsis=True) + self.out.write("\n") + self.out.write(" \n") + + def print_method(self, i, m): + self.out.write( + '\n' + % (utils.dots_to_hyphens(i.name), m.name) + ) + self.out.write(" The %s() method\n" % (m.name)) + self.out.write( + ' %s.%s()\n' + % ( + utils.dots_to_hyphens(i.name), + m.name, + i.name_without_prefix, + m.name, + i.name, + m.name, + ) + ) + self.out.write("\n") + self.print_method_prototype(i, m, in_synopsis=False) + self.out.write("\n") + self.out.write("%s\n" % (self.expand_paras(m.doc_string, True))) + if m.in_args or m.out_args: + self.out.write('\n') + for a in m.in_args: + self.out.write("\n") + self.out.write( + " IN %s %s:\n" + % (a.signature, a.name) + ) + self.out.write( + " %s\n" + % (self.expand_paras(a.doc_string, True)) + ) + self.out.write("\n") + for a in m.out_args: + self.out.write("\n") + self.out.write( + " OUT %s %s:\n" + % (a.signature, a.name) + ) + self.out.write( + " %s\n" + % (self.expand_paras(a.doc_string, True)) + ) + self.out.write("\n") + self.out.write("\n") + if len(m.since) > 0: + self.out.write('Since %s\n' % (m.since)) + if m.deprecated: + self.out.write( + "The %s() method is deprecated." + % (m.name) + ) + self.out.write("\n") + + def print_signal(self, i, s): + self.out.write( + '\n' + % (utils.dots_to_hyphens(i.name), s.name) + ) + self.out.write(' The "%s" signal\n' % (s.name)) + self.out.write( + ' %s::%s\n' + % ( + utils.dots_to_hyphens(i.name), + s.name, + i.name_without_prefix, + s.name, + i.name, + s.name, + ) + ) + self.out.write("\n") + self.print_signal_prototype(i, s, in_synopsis=False) + self.out.write("\n") + self.out.write("%s\n" % (self.expand_paras(s.doc_string, True))) + if s.args: + self.out.write('\n') + for a in s.args: + self.out.write("\n") + self.out.write( + " %s %s:\n" + % (a.signature, a.name) + ) + self.out.write( + " %s\n" + % (self.expand_paras(a.doc_string, True)) + ) + self.out.write("\n") + self.out.write("\n") + if len(s.since) > 0: + self.out.write('Since %s\n' % (s.since)) + if s.deprecated: + self.out.write( + 'The "%s" signal is deprecated.' + % (s.name) + ) + self.out.write("\n") + + def print_property(self, i, p): + self.out.write( + '\n' + % (utils.dots_to_hyphens(i.name), p.name) + ) + self.out.write(' The "%s" property\n' % (p.name)) + self.out.write( + ' %s:%s\n' + % ( + utils.dots_to_hyphens(i.name), + p.name, + i.name_without_prefix, + p.name, + i.name, + p.name, + ) + ) + self.out.write("\n") + self.print_property_prototype(i, p, in_synopsis=False) + self.out.write("\n") + self.out.write("%s\n" % (self.expand_paras(p.doc_string, True))) + if len(p.since) > 0: + self.out.write('Since %s\n' % (p.since)) + if p.deprecated: + self.out.write( + 'The "%s" property is deprecated.' + % (p.name) + ) + self.out.write("\n") + + def expand(self, s, expandParamsAndConstants): + for key in self.expand_member_dict_keys: + s = s.replace(key, self.expand_member_dict[key]) + for key in self.expand_iface_dict_keys: + s = s.replace(key, self.expand_iface_dict[key]) + if expandParamsAndConstants: + # replace @foo with foo + s = re.sub( + "@[a-zA-Z0-9_]*", + lambda m: "" + m.group(0)[1:] + "", + s, + ) + # replace e.g. %TRUE with TRUE + s = re.sub( + "%[a-zA-Z0-9_]*", + lambda m: "" + m.group(0)[1:] + "", + s, + ) + return s + + def expand_paras(self, s, expandParamsAndConstants): + s = self.expand(s, expandParamsAndConstants).strip() + res = [] + if not s.startswith(""): + res.append("") + for line in s.split("\n"): + line = line.strip() + if not line: + line = "" + res.append(line) + if not s.endswith(""): + res.append("") + return "\n".join(res) + + def generate_expand_dicts(self): + self.expand_member_dict = {} + self.expand_iface_dict = {} + for i in self.ifaces: + key = "#%s" % (i.name) + value = '%s' % ( + utils.dots_to_hyphens(i.name), + i.name, + ) + self.expand_iface_dict[key] = value + for m in i.methods: + key = "%s.%s()" % (i.name, m.name) + value = '%s()' % ( + utils.dots_to_hyphens(i.name), + m.name, + m.name, + ) + self.expand_member_dict[key] = value + for s in i.signals: + key = "#%s::%s" % (i.name, s.name) + value = '"%s"' % ( + utils.dots_to_hyphens(i.name), + s.name, + s.name, + ) + self.expand_member_dict[key] = value + for p in i.properties: + key = "#%s:%s" % (i.name, p.name) + value = '"%s"' % ( + utils.dots_to_hyphens(i.name), + p.name, + p.name, + ) + self.expand_member_dict[key] = value + # Make sure to expand the keys in reverse order so e.g. #org.foo.Iface:MediaCompat + # is evaluated before #org.foo.Iface:Media ... + self.expand_member_dict_keys = sorted( + self.expand_member_dict.keys(), reverse=True + ) + self.expand_iface_dict_keys = sorted( + self.expand_iface_dict.keys(), reverse=True + ) + + def generate(self, docbook, outdir): + for i in self.ifaces: + self.out = open(path.join(outdir, "%s-%s.xml" % (docbook, i.name)), "w") + self.out.write("") + self.out.write('\n') + self.out.write( + '\n") + self.out.write('\n' % (i.name)) + self.out.write(" ") + self.out.write( + ' %s\n' + % (utils.dots_to_hyphens(i.name), i.name) + ) + self.out.write( + ' %s\n' + % (utils.dots_to_hyphens(i.name), i.name_without_prefix, i.name) + ) + self.out.write(" ") + + self.out.write(" ") + self.out.write(" %s" % (i.name)) + self.out.write(" %s" % (i.doc_string_brief)) + self.out.write(" ") + + if len(i.methods) > 0: + self.print_synopsis_methods(i) + if len(i.signals) > 0: + self.print_synopsis_signals(i) + if len(i.properties) > 0: + self.print_synopsis_properties(i) + + self.out.write( + '\n' + % (utils.dots_to_hyphens(i.name)) + ) + self.out.write(' Description\n') + self.out.write(" %s\n" % (self.expand_paras(i.doc_string, True))) + if len(i.since) > 0: + self.out.write(' Since %s\n' % (i.since)) + if i.deprecated: + self.out.write( + "The %s interface is deprecated." + % (i.name) + ) + self.out.write("\n") + + if len(i.methods) > 0: + self.out.write( + '\n' % (i.name) + ) + self.out.write(' Method Details\n') + for m in i.methods: + self.print_method(i, m) + self.out.write("\n") + + if len(i.signals) > 0: + self.out.write( + '\n' % (i.name) + ) + self.out.write(' Signal Details\n') + for s in i.signals: + self.print_signal(i, s) + self.out.write("\n") + + if len(i.properties) > 0: + self.out.write( + '\n' % (i.name) + ) + self.out.write( + ' Property Details\n' + ) + for s in i.properties: + self.print_property(i, s) + self.out.write("\n") + + self.out.write("\n") + self.out.write("\n") diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py new file mode 100644 index 0000000..194800c --- /dev/null +++ b/gio/gdbus-2.0/codegen/codegen_main.py @@ -0,0 +1,500 @@ +# -*- Mode: Python -*- +# coding=utf-8 + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# Copyright (C) 2018 Iñigo Martínez +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +import argparse +import os +import sys + +from . import config +from . import dbustypes +from . import parser +from . import codegen +from . import codegen_docbook +from . import codegen_rst +from .utils import print_error, print_warning + + +def find_arg(arg_list, arg_name): + for a in arg_list: + if a.name == arg_name: + return a + return None + + +def find_method(iface, method): + for m in iface.methods: + if m.name == method: + return m + return None + + +def find_signal(iface, signal): + for m in iface.signals: + if m.name == signal: + return m + return None + + +def find_prop(iface, prop): + for m in iface.properties: + if m.name == prop: + return m + return None + + +def apply_annotation(iface_list, iface, method, signal, prop, arg, key, value): + iface_obj = None + for i in iface_list: + if i.name == iface: + iface_obj = i + break + + if iface_obj is None: + print_error('No interface "{}"'.format(iface)) + + target_obj = None + + if method: + method_obj = find_method(iface_obj, method) + if method_obj is None: + print_error('No method "{}" on interface "{}"'.format(method, iface)) + if arg: + arg_obj = find_arg(method_obj.in_args, arg) + if arg_obj is None: + arg_obj = find_arg(method_obj.out_args, arg) + if arg_obj is None: + print_error( + 'No arg "{}" on method "{}" on interface "{}"'.format( + arg, method, iface + ) + ) + target_obj = arg_obj + else: + target_obj = method_obj + elif signal: + signal_obj = find_signal(iface_obj, signal) + if signal_obj is None: + print_error('No signal "{}" on interface "{}"'.format(signal, iface)) + if arg: + arg_obj = find_arg(signal_obj.args, arg) + if arg_obj is None: + print_error( + 'No arg "{}" on signal "{}" on interface "{}"'.format( + arg, signal, iface + ) + ) + target_obj = arg_obj + else: + target_obj = signal_obj + elif prop: + prop_obj = find_prop(iface_obj, prop) + if prop_obj is None: + print_error('No property "{}" on interface "{}"'.format(prop, iface)) + target_obj = prop_obj + else: + target_obj = iface_obj + target_obj.annotations.insert(0, dbustypes.Annotation(key, value)) + + +def apply_annotations(iface_list, annotation_list): + # apply annotations given on the command line + for (what, key, value) in annotation_list: + pos = what.find("::") + if pos != -1: + # signal + iface = what[0:pos] + signal = what[pos + 2 :] + pos = signal.find("[") + if pos != -1: + arg = signal[pos + 1 :] + signal = signal[0:pos] + pos = arg.find("]") + arg = arg[0:pos] + apply_annotation(iface_list, iface, None, signal, None, arg, key, value) + else: + apply_annotation( + iface_list, iface, None, signal, None, None, key, value + ) + else: + pos = what.find(":") + if pos != -1: + # property + iface = what[0:pos] + prop = what[pos + 1 :] + apply_annotation(iface_list, iface, None, None, prop, None, key, value) + else: + pos = what.find("()") + if pos != -1: + # method + combined = what[0:pos] + pos = combined.rfind(".") + iface = combined[0:pos] + method = combined[pos + 1 :] + pos = what.find("[") + if pos != -1: + arg = what[pos + 1 :] + pos = arg.find("]") + arg = arg[0:pos] + apply_annotation( + iface_list, iface, method, None, None, arg, key, value + ) + else: + apply_annotation( + iface_list, iface, method, None, None, None, key, value + ) + else: + # must be an interface + iface = what + apply_annotation( + iface_list, iface, None, None, None, None, key, value + ) + + +def codegen_main(): + arg_parser = argparse.ArgumentParser( + description="D-Bus code and documentation generator" + ) + arg_parser.add_argument( + "files", metavar="FILE", nargs="+", help="D-Bus introspection XML file" + ) + arg_parser.add_argument( + "--xml-files", + metavar="FILE", + action="append", + default=[], + help=argparse.SUPPRESS, + ) + arg_parser.add_argument( + "--interface-prefix", + metavar="PREFIX", + default="", + help="String to strip from D-Bus interface names for code and docs", + ) + arg_parser.add_argument( + "--c-namespace", + metavar="NAMESPACE", + default="", + help="The namespace to use for generated C code", + ) + arg_parser.add_argument( + "--c-generate-object-manager", + action="store_true", + help="Generate a GDBusObjectManagerClient subclass when generating C code", + ) + arg_parser.add_argument( + "--c-generate-autocleanup", + choices=["none", "objects", "all"], + default="objects", + help="Generate autocleanup support", + ) + arg_parser.add_argument( + "--generate-docbook", + metavar="OUTFILES", + help="Generate Docbook in OUTFILES-org.Project.IFace.xml", + ) + arg_parser.add_argument( + "--generate-rst", + metavar="OUTFILES", + help="Generate reStructuredText in OUTFILES-org.Project.IFace.rst", + ) + arg_parser.add_argument( + "--pragma-once", + action="store_true", + help='Use "pragma once" as the inclusion guard', + ) + arg_parser.add_argument( + "--annotate", + nargs=3, + action="append", + metavar="WHAT KEY VALUE", + help="Add annotation (may be used several times)", + ) + arg_parser.add_argument( + "--glib-min-required", + metavar="VERSION", + help="Minimum version of GLib to be supported by the outputted code " + "(default: 2.30)", + ) + arg_parser.add_argument( + "--glib-max-allowed", + metavar="VERSION", + help="Maximum version of GLib to be used by the outputted code " + "(default: current GLib version)", + ) + arg_parser.add_argument( + "--symbol-decorator", + help="Macro used to decorate a symbol in the outputted header, " + "possibly to export symbols", + ) + arg_parser.add_argument( + "--symbol-decorator-header", + help="Additional header required for decorator specified by " + "--symbol-decorator", + ) + arg_parser.add_argument( + "--symbol-decorator-define", + help="Additional define required for decorator specified by " + "--symbol-decorator", + ) + + group = arg_parser.add_mutually_exclusive_group() + group.add_argument( + "--generate-c-code", metavar="OUTFILES", help="Generate C code in OUTFILES.[ch]" + ) + group.add_argument("--header", action="store_true", help="Generate C headers") + group.add_argument("--body", action="store_true", help="Generate C code") + group.add_argument( + "--interface-info-header", + action="store_true", + help="Generate GDBusInterfaceInfo C header", + ) + group.add_argument( + "--interface-info-body", + action="store_true", + help="Generate GDBusInterfaceInfo C code", + ) + + group = arg_parser.add_mutually_exclusive_group() + group.add_argument( + "--output", metavar="FILE", help="Write output into the specified file" + ) + group.add_argument( + "--output-directory", + metavar="OUTDIR", + default="", + help="Location to output generated files", + ) + + args = arg_parser.parse_args() + + if len(args.xml_files) > 0: + print_warning( + 'The "--xml-files" option is deprecated; use positional arguments instead' + ) + + if ( + args.generate_c_code is not None + or args.generate_docbook is not None + or args.generate_rst is not None + ) and args.output is not None: + print_error( + "Using --generate-c-code or --generate-docbook or --generate-rst and " + "--output at the same time is not allowed" + ) + + if args.generate_c_code: + header_name = args.generate_c_code + ".h" + h_file = os.path.join(args.output_directory, header_name) + args.header = True + c_file = os.path.join(args.output_directory, args.generate_c_code + ".c") + args.body = True + elif args.header: + if args.output is None: + print_error("Using --header requires --output") + + h_file = args.output + header_name = os.path.basename(h_file) + elif args.body: + if args.output is None: + print_error("Using --body requires --output") + + c_file = args.output + header_name = os.path.splitext(os.path.basename(c_file))[0] + ".h" + elif args.interface_info_header: + if args.output is None: + print_error("Using --interface-info-header requires --output") + if args.c_generate_object_manager: + print_error( + "--c-generate-object-manager is incompatible with " + "--interface-info-header" + ) + + h_file = args.output + header_name = os.path.basename(h_file) + elif args.interface_info_body: + if args.output is None: + print_error("Using --interface-info-body requires --output") + if args.c_generate_object_manager: + print_error( + "--c-generate-object-manager is incompatible with " + "--interface-info-body" + ) + + c_file = args.output + header_name = os.path.splitext(os.path.basename(c_file))[0] + ".h" + + # Check the minimum GLib version. The minimum --glib-min-required is 2.30, + # because that’s when gdbus-codegen was introduced. Support 1, 2 or 3 + # component versions, but ignore the micro component if it’s present. + if args.glib_min_required: + try: + parts = args.glib_min_required.split(".", 3) + glib_min_required = (int(parts[0]), int(parts[1] if len(parts) > 1 else 0)) + # Ignore micro component, but still validate it: + _ = int(parts[2] if len(parts) > 2 else 0) # noqa: F841 + except (ValueError, IndexError): + print_error( + "Unrecognized --glib-min-required string ‘{}’".format( + args.glib_min_required + ) + ) + + if glib_min_required < (2, 30): + print_error( + "Invalid --glib-min-required string ‘{}’: minimum " + "version is 2.30".format(args.glib_min_required) + ) + else: + glib_min_required = (2, 30) + + # And the maximum GLib version. + if args.glib_max_allowed: + try: + parts = args.glib_max_allowed.split(".", 3) + glib_max_allowed = (int(parts[0]), int(parts[1] if len(parts) > 1 else 0)) + # Ignore micro component, but still validate it: + _ = int(parts[2] if len(parts) > 2 else 0) # noqa: F841 + except (ValueError, IndexError): + print_error( + "Unrecognized --glib-max-allowed string ‘{}’".format( + args.glib_max_allowed + ) + ) + else: + glib_max_allowed = (config.MAJOR_VERSION, config.MINOR_VERSION) + + # Only allow --symbol-decorator-define and --symbol-decorator-header if + # --symbol-decorator is used + if args.symbol_decorator is None: + if args.symbol_decorator_header or args.symbol_decorator_define: + print_error( + "--symbol-decorator-define and --symbol-decorator-header must " + "be used with --symbol-decorator" + ) + + # Round --glib-max-allowed up to the next stable release. + glib_max_allowed = ( + glib_max_allowed[0], + glib_max_allowed[1] + (glib_max_allowed[1] % 2), + ) + + if glib_max_allowed < glib_min_required: + print_error( + "Invalid versions: --glib-min-required ({}) must be " + "less than or equal to --glib-max-allowed ({})".format( + glib_min_required, glib_max_allowed + ) + ) + + all_ifaces = [] + input_files_basenames = [] + for fname in sorted(args.files + args.xml_files): + with open(fname, "rb") as f: + xml_data = f.read() + parsed_ifaces = parser.parse_dbus_xml( + xml_data, h_type_implies_unix_fd=(glib_min_required >= (2, 64)) + ) + all_ifaces.extend(parsed_ifaces) + input_files_basenames.append(os.path.basename(fname)) + + if args.annotate is not None: + apply_annotations(all_ifaces, args.annotate) + + for i in all_ifaces: + i.post_process(args.interface_prefix, args.c_namespace) + + docbook = args.generate_docbook + docbook_gen = codegen_docbook.DocbookCodeGenerator(all_ifaces) + if docbook: + docbook_gen.generate(docbook, args.output_directory) + + rst = args.generate_rst + rst_gen = codegen_rst.RstCodeGenerator(all_ifaces) + if rst: + rst_gen.generate(rst, args.output_directory) + + if args.header: + with open(h_file, "w") as outfile: + gen = codegen.HeaderCodeGenerator( + all_ifaces, + args.c_namespace, + args.c_generate_object_manager, + args.c_generate_autocleanup, + header_name, + input_files_basenames, + args.pragma_once, + glib_min_required, + args.symbol_decorator, + args.symbol_decorator_header, + outfile, + ) + gen.generate() + + if args.body: + with open(c_file, "w") as outfile: + gen = codegen.CodeGenerator( + all_ifaces, + args.c_namespace, + args.c_generate_object_manager, + header_name, + input_files_basenames, + docbook_gen, + glib_min_required, + args.symbol_decorator_define, + outfile, + ) + gen.generate() + + if args.interface_info_header: + with open(h_file, "w") as outfile: + gen = codegen.InterfaceInfoHeaderCodeGenerator( + all_ifaces, + args.c_namespace, + header_name, + input_files_basenames, + args.pragma_once, + glib_min_required, + args.symbol_decorator, + args.symbol_decorator_header, + outfile, + ) + gen.generate() + + if args.interface_info_body: + with open(c_file, "w") as outfile: + gen = codegen.InterfaceInfoBodyCodeGenerator( + all_ifaces, + args.c_namespace, + header_name, + input_files_basenames, + glib_min_required, + args.symbol_decorator_define, + outfile, + ) + gen.generate() + + sys.exit(0) + + +if __name__ == "__main__": + codegen_main() diff --git a/gio/gdbus-2.0/codegen/codegen_rst.py b/gio/gdbus-2.0/codegen/codegen_rst.py new file mode 100644 index 0000000..51da2d5 --- /dev/null +++ b/gio/gdbus-2.0/codegen/codegen_rst.py @@ -0,0 +1,332 @@ +# SPDX-FileCopyrightText: 2022 Emmanuele Bassi +# +# SPDX-License-Identifier: LGPL-2.1-or-later + +import os +import re + +from . import utils + +# Disable line length warnings as wrapping the templates would be hard +# flake8: noqa: E501 + + +class RstCodeGenerator: + """Generates documentation in reStructuredText format.""" + + def __init__(self, ifaces): + self.ifaces = ifaces + self._generate_expand_dicts() + + def _expand(self, s, expandParamsAndConstants): + """Expands parameters and constant literals.""" + res = [] + for line in s.split("\n"): + line = line.strip() + if line == "": + res.append("") + continue + for key in self._expand_member_dict_keys: + line = line.replace(key, self._expand_member_dict[key]) + for key in self._expand_iface_dict_keys: + line = line.replace(key, self._expand_iface_dict[key]) + if expandParamsAndConstants: + # replace @foo with ``foo`` + line = re.sub( + "@[a-zA-Z0-9_]*", + lambda m: "``" + m.group(0)[1:] + "``", + line, + ) + # replace e.g. %TRUE with ``TRUE`` + line = re.sub( + "%[a-zA-Z0-9_]*", + lambda m: "``" + m.group(0)[1:] + "``", + line, + ) + res.append(line) + return "\n".join(res) + + def _generate_expand_dicts(self): + """Generates the dictionaries used to expand gtk-doc sigils.""" + self._expand_member_dict = {} + self._expand_iface_dict = {} + for i in self.ifaces: + key = f"#{i.name}" + value = f"`{i.name}`_" + self._expand_iface_dict[key] = value + + for m in i.methods: + key = "%s.%s()" % (i.name, m.name) + value = f"`{i.name}.{m.name}`_" + self._expand_member_dict[key] = value + + for s in i.signals: + key = "#%s::%s" % (i.name, s.name) + value = f"`{i.name}::{s.name}`_" + self._expand_member_dict[key] = value + + for p in i.properties: + key = "#%s:%s" % (i.name, p.name) + value = f"`{i.name}:{p.name}`_" + self._expand_member_dict[key] = value + + # Make sure to expand the keys in reverse order so e.g. #org.foo.Iface:MediaCompat + # is evaluated before #org.foo.Iface:Media ... + self._expand_member_dict_keys = sorted( + self._expand_member_dict.keys(), reverse=True + ) + self._expand_iface_dict_keys = sorted( + self._expand_iface_dict.keys(), reverse=True + ) + + def _generate_header(self, iface): + """Generates the header and preamble of the document.""" + header_len = len(iface.name) + res = [ + f".. _{iface.name}:", + "", + "=" * header_len, + iface.name, + "=" * header_len, + "", + "-----------", + "Description", + "-----------", + "", + f".. _{iface.name} Description:", + "", + iface.doc_string_brief.strip(), + "", + self._expand(iface.doc_string, True), + "", + ] + if iface.since: + res += [ + f"Interface available since: {iface.since}.", + "", + ] + if iface.deprecated: + res += [ + ".. warning::", + "", + " This interface is deprecated.", + "", + "", + ] + res += [""] + return "\n".join(res) + + def _generate_section(self, title, name): + """Generates a section with the given title.""" + res = [ + "-" * len(title), + title, + "-" * len(title), + "", + f".. {name} {title}:", + "", + "", + ] + return "\n".join(res) + + def _generate_properties(self, iface): + """Generates the properties section.""" + res = [] + for p in iface.properties: + title = f"{iface.name}:{p.name}" + if p.readable and p.writable: + access = "readwrite" + elif p.writable: + access = "writable" + else: + access = "readable" + res += [ + title, + "^" * len(title), + "", + "::", + "", + f" {p.name} {access} {p.signature}", + "", + "", + self._expand(p.doc_string, True), + "", + ] + if p.since: + res += [ + f"Property available since: {p.since}.", + "", + ] + if p.deprecated: + res += [ + ".. warning::", + "", + " This property is deprecated.", + "", + "", + ] + res += [""] + return "\n".join(res) + + def _generate_method_signature(self, method): + """Generates the method signature as a code block.""" + res = [ + "::", + "", + ] + n_in_args = len(method.in_args) + n_out_args = len(method.out_args) + if n_in_args == 0 and n_out_args == 0: + res += [ + f" {method.name} ()", + ] + else: + res += [ + f" {method.name} (", + ] + for idx, arg in enumerate(method.in_args): + if idx == n_in_args - 1 and n_out_args == 0: + res += [ + f" IN {arg.name} {arg.signature}", + ] + else: + res += [ + f" IN {arg.name} {arg.signature},", + ] + for idx, arg in enumerate(method.out_args): + if idx == n_out_args - 1: + res += [ + f" OUT {arg.name} {arg.signature}", + ] + else: + res += [ + f" OUT {arg.name} {arg.signature},", + ] + res += [ + " )", + "", + ] + res += [""] + return "\n".join(res) + + def _generate_methods(self, iface): + """Generates the methods section.""" + res = [] + for m in iface.methods: + title = f"{iface.name}.{m.name}" + res += [ + title, + "^" * len(title), + "", + self._generate_method_signature(m), + "", + self._expand(m.doc_string, True), + "", + ] + for a in m.in_args: + arg_desc = self._expand(a.doc_string, True) + res += [ + f"{a.name}", + f" {arg_desc}", + "", + ] + res += [""] + if m.since: + res += [ + f"Method available since: {m.since}.", + "", + ] + if m.deprecated: + res += [ + ".. warning::", + "", + " This method is deprecated.", + "", + "", + ] + res += [""] + return "\n".join(res) + + def _generate_signal_signature(self, signal): + """Generates the signal signature.""" + res = [ + "::", + "", + ] + n_args = len(signal.args) + if n_args == 0: + res += [ + f" {signal.name} ()", + ] + else: + res += [ + f" {signal.name} (", + ] + for idx, arg in enumerate(signal.args): + if idx == n_args - 1: + res += [ + f" {arg.name} {arg.signature}", + ] + else: + res += [ + f" {arg.name} {arg.signature},", + ] + res += [ + " )", + "", + ] + res += [""] + return "\n".join(res) + + def _generate_signals(self, iface): + """Generates the signals section.""" + res = [] + for s in iface.signals: + title = f"{iface.name}::{s.name}" + res += [ + title, + "^" * len(title), + "", + self._generate_signal_signature(s), + "", + self._expand(s.doc_string, True), + "", + ] + for a in s.args: + arg_desc = self._expand(a.doc_string, True) + res += [ + f"{a.name}", + f" {arg_desc}", + "", + ] + res += [""] + if s.since: + res += [ + f"Signal available since: {s.since}.", + "", + ] + if s.deprecated: + res += [ + ".. warning::", + "", + " This signal is deprecated.", + "", + "", + ] + res += [""] + return "\n".join(res) + + def generate(self, rst, outdir): + """Generates the reStructuredText file for each interface.""" + for i in self.ifaces: + with open(os.path.join(outdir, f"{rst}-{i.name}.rst"), "w") as outfile: + outfile.write(self._generate_header(i)) + if len(i.properties) > 0: + outfile.write(self._generate_section("Properties", i.name)) + outfile.write(self._generate_properties(i)) + if len(i.methods) > 0: + outfile.write(self._generate_section("Methods", i.name)) + outfile.write(self._generate_methods(i)) + if len(i.signals) > 0: + outfile.write(self._generate_section("Signals", i.name)) + outfile.write(self._generate_signals(i)) diff --git a/gio/gdbus-2.0/codegen/config.py.in b/gio/gdbus-2.0/codegen/config.py.in new file mode 100644 index 0000000..4e6df5a --- /dev/null +++ b/gio/gdbus-2.0/codegen/config.py.in @@ -0,0 +1,24 @@ +# -*- Mode: Python -*- + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +VERSION = "@VERSION@" +MAJOR_VERSION = @MAJOR_VERSION@ +MINOR_VERSION = @MINOR_VERSION@ diff --git a/gio/gdbus-2.0/codegen/dbustypes.py b/gio/gdbus-2.0/codegen/dbustypes.py new file mode 100644 index 0000000..bbe5c4e --- /dev/null +++ b/gio/gdbus-2.0/codegen/dbustypes.py @@ -0,0 +1,525 @@ +# -*- Mode: Python -*- + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +from . import utils +from .utils import print_error + + +class Annotation: + def __init__(self, key, value): + self.key = key + self.value = value + self.annotations = [] + self.since = "" + + def post_process(self, interface_prefix, cns, cns_upper, cns_lower, container): + key = self.key + overridden_key = utils.lookup_annotation( + self.annotations, "org.gtk.GDBus.C.Name" + ) + if utils.is_ugly_case(overridden_key): + self.key_lower = overridden_key.lower() + else: + if overridden_key: + key = overridden_key + self.key_lower = ( + utils.camel_case_to_uscore(key) + .lower() + .replace("-", "_") + .replace(".", "_") + ) + + if len(self.since) == 0: + self.since = utils.lookup_since(self.annotations) + if len(self.since) == 0: + self.since = container.since + + for a in self.annotations: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) + + +class Arg: + def __init__(self, name, signature): + self.name = name + self.signature = signature + self.annotations = [] + self.doc_string = "" + self.since = "" + + def post_process(self, interface_prefix, cns, cns_upper, cns_lower, arg_number): + if len(self.doc_string) == 0: + self.doc_string = utils.lookup_docs(self.annotations) + if len(self.since) == 0: + self.since = utils.lookup_since(self.annotations) + + if self.name is None: + self.name = "unnamed_arg%d" % arg_number + # default to GVariant + self.ctype_in_g = "GVariant *" + self.ctype_in = "GVariant *" + self.ctype_in_dup = "GVariant *" + self.ctype_out = "GVariant **" + self.gtype = "G_TYPE_VARIANT" + self.free_func = "g_variant_unref" + self.format_in = "@" + self.signature + self.format_out = "@" + self.signature + self.gvariant_get = "XXX" + self.gvalue_get = "g_value_get_variant" + self.array_annotation = "" + + if not utils.lookup_annotation( + self.annotations, "org.gtk.GDBus.C.ForceGVariant" + ): + if self.signature == "b": + self.ctype_in_g = "gboolean " + self.ctype_in = "gboolean " + self.ctype_out = "gboolean *" + self.gtype = "G_TYPE_BOOLEAN" + self.free_func = None + self.format_in = "b" + self.format_out = "b" + self.gvariant_get = "g_variant_get_boolean" + self.gvalue_get = "g_value_get_boolean" + elif self.signature == "y": + self.ctype_in_g = "guchar " + self.ctype_in = "guchar " + self.ctype_out = "guchar *" + self.gtype = "G_TYPE_UCHAR" + self.free_func = None + self.format_in = "y" + self.format_out = "y" + self.gvariant_get = "g_variant_get_byte" + self.gvalue_get = "g_value_get_uchar" + elif self.signature == "n": + self.ctype_in_g = "gint " + self.ctype_in = "gint16 " + self.ctype_out = "gint16 *" + self.gtype = "G_TYPE_INT" + self.free_func = None + self.format_in = "n" + self.format_out = "n" + self.gvariant_get = "g_variant_get_int16" + self.gvalue_get = "g_value_get_int" + elif self.signature == "q": + self.ctype_in_g = "guint " + self.ctype_in = "guint16 " + self.ctype_out = "guint16 *" + self.gtype = "G_TYPE_UINT" + self.free_func = None + self.format_in = "q" + self.format_out = "q" + self.gvariant_get = "g_variant_get_uint16" + self.gvalue_get = "g_value_get_uint" + elif self.signature == "i": + self.ctype_in_g = "gint " + self.ctype_in = "gint " + self.ctype_out = "gint *" + self.gtype = "G_TYPE_INT" + self.free_func = None + self.format_in = "i" + self.format_out = "i" + self.gvariant_get = "g_variant_get_int32" + self.gvalue_get = "g_value_get_int" + elif self.signature == "u": + self.ctype_in_g = "guint " + self.ctype_in = "guint " + self.ctype_out = "guint *" + self.gtype = "G_TYPE_UINT" + self.free_func = None + self.format_in = "u" + self.format_out = "u" + self.gvariant_get = "g_variant_get_uint32" + self.gvalue_get = "g_value_get_uint" + elif self.signature == "x": + self.ctype_in_g = "gint64 " + self.ctype_in = "gint64 " + self.ctype_out = "gint64 *" + self.gtype = "G_TYPE_INT64" + self.free_func = None + self.format_in = "x" + self.format_out = "x" + self.gvariant_get = "g_variant_get_int64" + self.gvalue_get = "g_value_get_int64" + elif self.signature == "t": + self.ctype_in_g = "guint64 " + self.ctype_in = "guint64 " + self.ctype_out = "guint64 *" + self.gtype = "G_TYPE_UINT64" + self.free_func = None + self.format_in = "t" + self.format_out = "t" + self.gvariant_get = "g_variant_get_uint64" + self.gvalue_get = "g_value_get_uint64" + elif self.signature == "d": + self.ctype_in_g = "gdouble " + self.ctype_in = "gdouble " + self.ctype_out = "gdouble *" + self.gtype = "G_TYPE_DOUBLE" + self.free_func = None + self.format_in = "d" + self.format_out = "d" + self.gvariant_get = "g_variant_get_double" + self.gvalue_get = "g_value_get_double" + elif self.signature == "s": + self.ctype_in_g = "const gchar *" + self.ctype_in = "const gchar *" + self.ctype_in_dup = "gchar *" + self.ctype_out = "gchar **" + self.gtype = "G_TYPE_STRING" + self.free_func = "g_free" + self.format_in = "s" + self.format_out = "s" + self.gvariant_get = "g_variant_get_string" + self.gvalue_get = "g_value_get_string" + elif self.signature == "o": + self.ctype_in_g = "const gchar *" + self.ctype_in = "const gchar *" + self.ctype_in_dup = "gchar *" + self.ctype_out = "gchar **" + self.gtype = "G_TYPE_STRING" + self.free_func = "g_free" + self.format_in = "o" + self.format_out = "o" + self.gvariant_get = "g_variant_get_string" + self.gvalue_get = "g_value_get_string" + elif self.signature == "g": + self.ctype_in_g = "const gchar *" + self.ctype_in = "const gchar *" + self.ctype_in_dup = "gchar *" + self.ctype_out = "gchar **" + self.gtype = "G_TYPE_STRING" + self.free_func = "g_free" + self.format_in = "g" + self.format_out = "g" + self.gvariant_get = "g_variant_get_string" + self.gvalue_get = "g_value_get_string" + elif self.signature == "ay": + self.ctype_in_g = "const gchar *" + self.ctype_in = "const gchar *" + self.ctype_in_dup = "gchar *" + self.ctype_out = "gchar **" + self.gtype = "G_TYPE_STRING" + self.free_func = "g_free" + self.format_in = "^ay" + self.format_out = "^ay" + self.gvariant_get = "g_variant_get_bytestring" + self.gvalue_get = "g_value_get_string" + elif self.signature == "as": + self.ctype_in_g = "const gchar *const *" + self.ctype_in = "const gchar *const *" + self.ctype_in_dup = "gchar **" + self.ctype_out = "gchar ***" + self.gtype = "G_TYPE_STRV" + self.free_func = "g_strfreev" + self.format_in = "^as" + self.format_out = "^as" + self.gvariant_get = "g_variant_get_strv" + self.gvalue_get = "g_value_get_boxed" + self.array_annotation = "(array zero-terminated=1)" + elif self.signature == "ao": + self.ctype_in_g = "const gchar *const *" + self.ctype_in = "const gchar *const *" + self.ctype_in_dup = "gchar **" + self.ctype_out = "gchar ***" + self.gtype = "G_TYPE_STRV" + self.free_func = "g_strfreev" + self.format_in = "^ao" + self.format_out = "^ao" + self.gvariant_get = "g_variant_get_objv" + self.gvalue_get = "g_value_get_boxed" + self.array_annotation = "(array zero-terminated=1)" + elif self.signature == "aay": + self.ctype_in_g = "const gchar *const *" + self.ctype_in = "const gchar *const *" + self.ctype_in_dup = "gchar **" + self.ctype_out = "gchar ***" + self.gtype = "G_TYPE_STRV" + self.free_func = "g_strfreev" + self.format_in = "^aay" + self.format_out = "^aay" + self.gvariant_get = "g_variant_get_bytestring_array" + self.gvalue_get = "g_value_get_boxed" + self.array_annotation = "(array zero-terminated=1)" + + for a in self.annotations: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) + + +class Method: + def __init__(self, name, h_type_implies_unix_fd=True): + self.name = name + self.h_type_implies_unix_fd = h_type_implies_unix_fd + self.in_args = [] + self.out_args = [] + self.annotations = [] + self.doc_string = "" + self.since = "" + self.deprecated = False + self.unix_fd = False + + def post_process( + self, interface_prefix, cns, cns_upper, cns_lower, containing_iface + ): + if len(self.doc_string) == 0: + self.doc_string = utils.lookup_docs(self.annotations) + if len(self.since) == 0: + self.since = utils.lookup_since(self.annotations) + if len(self.since) == 0: + self.since = containing_iface.since + + name = self.name + overridden_name = utils.lookup_annotation( + self.annotations, "org.gtk.GDBus.C.Name" + ) + if utils.is_ugly_case(overridden_name): + self.name_lower = overridden_name.lower() + else: + if overridden_name: + name = overridden_name + self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_") + self.name_hyphen = self.name_lower.replace("_", "-") + + arg_count = 0 + for a in self.in_args: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count) + arg_count += 1 + if self.h_type_implies_unix_fd and "h" in a.signature: + self.unix_fd = True + + for a in self.out_args: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count) + arg_count += 1 + if self.h_type_implies_unix_fd and "h" in a.signature: + self.unix_fd = True + + if ( + utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated") + == "true" + ): + self.deprecated = True + + if utils.lookup_annotation(self.annotations, "org.gtk.GDBus.C.UnixFD"): + self.unix_fd = True + + for a in self.annotations: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) + + +class Signal: + def __init__(self, name): + self.name = name + self.args = [] + self.annotations = [] + self.doc_string = "" + self.since = "" + self.deprecated = False + + def post_process( + self, interface_prefix, cns, cns_upper, cns_lower, containing_iface + ): + if len(self.doc_string) == 0: + self.doc_string = utils.lookup_docs(self.annotations) + if len(self.since) == 0: + self.since = utils.lookup_since(self.annotations) + if len(self.since) == 0: + self.since = containing_iface.since + + name = self.name + overridden_name = utils.lookup_annotation( + self.annotations, "org.gtk.GDBus.C.Name" + ) + if utils.is_ugly_case(overridden_name): + self.name_lower = overridden_name.lower() + else: + if overridden_name: + name = overridden_name + self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_") + self.name_hyphen = self.name_lower.replace("_", "-") + + arg_count = 0 + for a in self.args: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count) + arg_count += 1 + + if ( + utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated") + == "true" + ): + self.deprecated = True + + for a in self.annotations: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) + + +class Property: + def __init__(self, name, signature, access): + self.name = name + self.signature = signature + self.access = access + self.annotations = [] + self.arg = Arg("value", self.signature) + self.arg.annotations = self.annotations + self.readable = False + self.writable = False + if self.access == "readwrite": + self.readable = True + self.writable = True + elif self.access == "read": + self.readable = True + elif self.access == "write": + self.writable = True + else: + print_error('Invalid access type "{}"'.format(self.access)) + self.doc_string = "" + self.since = "" + self.deprecated = False + self.emits_changed_signal = True + + def post_process( + self, interface_prefix, cns, cns_upper, cns_lower, containing_iface + ): + if len(self.doc_string) == 0: + self.doc_string = utils.lookup_docs(self.annotations) + if len(self.since) == 0: + self.since = utils.lookup_since(self.annotations) + if len(self.since) == 0: + self.since = containing_iface.since + + name = self.name + overridden_name = utils.lookup_annotation( + self.annotations, "org.gtk.GDBus.C.Name" + ) + if utils.is_ugly_case(overridden_name): + self.name_lower = overridden_name.lower() + else: + if overridden_name: + name = overridden_name + self.name_lower = utils.camel_case_to_uscore(name).lower().replace("-", "_") + self.name_hyphen = self.name_lower.replace("_", "-") + # don't clash with the GType getter, e.g.: + # GType foo_bar_get_type (void); G_GNUC_CONST + if self.name_lower == "type": + self.name_lower = "type_" + + # recalculate arg + self.arg.annotations = self.annotations + self.arg.post_process(interface_prefix, cns, cns_upper, cns_lower, 0) + + if ( + utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated") + == "true" + ): + self.deprecated = True + + for a in self.annotations: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) + + # FIXME: for now we only support 'false' and 'const' on the signal itself, + # see #674913 and + # http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format + # for details + if utils.lookup_annotation( + self.annotations, "org.freedesktop.DBus.Property.EmitsChangedSignal" + ) in ("false", "const"): + self.emits_changed_signal = False + + +class Interface: + def __init__(self, name): + self.name = name + self.methods = [] + self.signals = [] + self.properties = [] + self.annotations = [] + self.doc_string = "" + self.doc_string_brief = "" + self.since = "" + self.deprecated = False + + def post_process(self, interface_prefix, c_namespace): + if len(self.doc_string) == 0: + self.doc_string = utils.lookup_docs(self.annotations) + if len(self.doc_string_brief) == 0: + self.doc_string_brief = utils.lookup_brief_docs(self.annotations) + if len(self.since) == 0: + self.since = utils.lookup_since(self.annotations) + + if len(c_namespace) > 0: + if utils.is_ugly_case(c_namespace): + cns = c_namespace.replace("_", "") + cns_upper = c_namespace.upper() + "_" + cns_lower = c_namespace.lower() + "_" + else: + cns = c_namespace + cns_upper = utils.camel_case_to_uscore(c_namespace).upper() + "_" + cns_lower = utils.camel_case_to_uscore(c_namespace).lower() + "_" + else: + cns = "" + cns_upper = "" + cns_lower = "" + + overridden_name = utils.lookup_annotation( + self.annotations, "org.gtk.GDBus.C.Name" + ) + if utils.is_ugly_case(overridden_name): + name = overridden_name.replace("_", "") + name_with_ns = cns + name + self.name_without_prefix = name + self.camel_name = name_with_ns + self.ns_upper = cns_upper + self.name_lower = cns_lower + overridden_name.lower() + self.name_upper = overridden_name.upper() + + # print_error('handle Ugly_Case "{}"'.format(overridden_name)) + else: + if overridden_name: + name = overridden_name + else: + name = self.name + if name.startswith(interface_prefix): + name = name[len(interface_prefix) :] + self.name_without_prefix = name + name = utils.strip_dots(name) + name_with_ns = utils.strip_dots(cns + "." + name) + self.camel_name = name_with_ns + self.ns_upper = cns_upper + self.name_lower = cns_lower + utils.camel_case_to_uscore(name) + self.name_upper = utils.camel_case_to_uscore(name).upper() + + self.name_hyphen = self.name_upper.lower().replace("_", "-") + + if ( + utils.lookup_annotation(self.annotations, "org.freedesktop.DBus.Deprecated") + == "true" + ): + self.deprecated = True + + for m in self.methods: + m.post_process(interface_prefix, cns, cns_upper, cns_lower, self) + + for s in self.signals: + s.post_process(interface_prefix, cns, cns_upper, cns_lower, self) + + for p in self.properties: + p.post_process(interface_prefix, cns, cns_upper, cns_lower, self) + + for a in self.annotations: + a.post_process(interface_prefix, cns, cns_upper, cns_lower, self) diff --git a/gio/gdbus-2.0/codegen/gdbus-codegen.in b/gio/gdbus-2.0/codegen/gdbus-codegen.in new file mode 100755 index 0000000..67d3675 --- /dev/null +++ b/gio/gdbus-2.0/codegen/gdbus-codegen.in @@ -0,0 +1,55 @@ +#!/usr/bin/env @PYTHON@ + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + + +import os +import sys + +srcdir = os.getenv('UNINSTALLED_GLIB_SRCDIR', None) +filedir = os.path.dirname(__file__) + +if srcdir is not None: + path = os.path.join(srcdir, 'gio', 'gdbus-2.0') +elif os.path.basename(filedir) == 'bin': + # Make the prefix containing gdbus-codegen 'relocatable' at runtime by + # adding /some/prefix/bin/../share/glib-2.0 to the python path + path = os.path.join(filedir, '..', 'share', 'glib-2.0') +else: + # Assume that the modules we need are in the current directory and add the + # parent directory to the python path. + path = os.path.join(filedir, '..') + +# Canonicalize, then do further testing +path = os.path.abspath(path) + +# If the above path detection failed, use the hard-coded datadir. This can +# happen when, for instance, bindir and datadir are not in the same prefix or +# on Windows where we cannot make any guarantees about the directory structure. +# +# In these cases our installation cannot be relocatable, but at least we should +# be able to find the codegen module. +if not os.path.isfile(os.path.join(path, 'codegen', 'codegen_main.py')): + path = os.path.join('@DATADIR@', 'glib-2.0') + +sys.path.insert(0, path) +from codegen import codegen_main + +sys.exit(codegen_main.codegen_main()) diff --git a/gio/gdbus-2.0/codegen/meson.build b/gio/gdbus-2.0/codegen/meson.build new file mode 100644 index 0000000..bf25cda --- /dev/null +++ b/gio/gdbus-2.0/codegen/meson.build @@ -0,0 +1,42 @@ +gdbus_codegen_files = [ + '__init__.py', + 'codegen.py', + 'codegen_main.py', + 'codegen_docbook.py', + 'codegen_rst.py', + 'dbustypes.py', + 'parser.py', + 'utils.py', +] + +gdbus_codegen_conf = configuration_data() +gdbus_codegen_conf.set('VERSION', glib_version) +gdbus_codegen_conf.set('MAJOR_VERSION', major_version) +gdbus_codegen_conf.set('MINOR_VERSION', minor_version) +gdbus_codegen_conf.set('PYTHON', python_name) +gdbus_codegen_conf.set('DATADIR', glib_datadir) + +# Install gdbus-codegen executable +gdbus_codegen = configure_file(input : 'gdbus-codegen.in', + output : 'gdbus-codegen', + install_dir : get_option('bindir'), + configuration : gdbus_codegen_conf +) + # Provide tools for others when we're a subproject and they use the Meson GNOME module +meson.override_find_program('gdbus-codegen', gdbus_codegen) + +codegen_dir = join_paths(glib_datadir, 'glib-2.0', 'codegen') + +gdbus_codegen_built_files = [] +gdbus_codegen_built_files += configure_file(input : 'config.py.in', + output : 'config.py', + install_dir : codegen_dir, + configuration : gdbus_codegen_conf) + +foreach f : gdbus_codegen_files + # Copy these into the builddir so that gdbus-codegen can be used uninstalled + # and then install it too so that it can be used after installation + gdbus_codegen_built_files += configure_file(input : f, output : f, + install_dir : codegen_dir, + copy : true) +endforeach diff --git a/gio/gdbus-2.0/codegen/parser.py b/gio/gdbus-2.0/codegen/parser.py new file mode 100644 index 0000000..cf8ea52 --- /dev/null +++ b/gio/gdbus-2.0/codegen/parser.py @@ -0,0 +1,302 @@ +# -*- Mode: Python -*- + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +import xml.parsers.expat + +from . import dbustypes +from .utils import print_error + + +class DBusXMLParser: + STATE_TOP = "top" + STATE_NODE = "node" + STATE_INTERFACE = "interface" + STATE_METHOD = "method" + STATE_SIGNAL = "signal" + STATE_PROPERTY = "property" + STATE_ARG = "arg" + STATE_ANNOTATION = "annotation" + STATE_IGNORED = "ignored" + + def __init__(self, xml_data, h_type_implies_unix_fd=True): + self._parser = xml.parsers.expat.ParserCreate() + self._parser.CommentHandler = self.handle_comment + self._parser.CharacterDataHandler = self.handle_char_data + self._parser.StartElementHandler = self.handle_start_element + self._parser.EndElementHandler = self.handle_end_element + + self.parsed_interfaces = [] + self._cur_object = None + + self.state = DBusXMLParser.STATE_TOP + self.state_stack = [] + self._cur_object = None + self._cur_object_stack = [] + + self.doc_comment_last_symbol = "" + + self._h_type_implies_unix_fd = h_type_implies_unix_fd + + self._parser.Parse(xml_data) + + COMMENT_STATE_BEGIN = "begin" + COMMENT_STATE_PARAMS = "params" + COMMENT_STATE_BODY = "body" + COMMENT_STATE_SKIP = "skip" + + def handle_comment(self, data): + comment_state = DBusXMLParser.COMMENT_STATE_BEGIN + lines = data.split("\n") + symbol = "" + body = "" + in_para = False + params = {} + for line in lines: + orig_line = line + line = line.lstrip() + if comment_state == DBusXMLParser.COMMENT_STATE_BEGIN: + if len(line) > 0: + colon_index = line.find(": ") + if colon_index == -1: + if line.endswith(":"): + symbol = line[0 : len(line) - 1] + comment_state = DBusXMLParser.COMMENT_STATE_PARAMS + else: + comment_state = DBusXMLParser.COMMENT_STATE_SKIP + else: + symbol = line[0:colon_index] + rest_of_line = line[colon_index + 2 :].strip() + if len(rest_of_line) > 0: + body += f"{rest_of_line}\n" + comment_state = DBusXMLParser.COMMENT_STATE_PARAMS + elif comment_state == DBusXMLParser.COMMENT_STATE_PARAMS: + if line.startswith("@"): + colon_index = line.find(": ") + if colon_index == -1: + comment_state = DBusXMLParser.COMMENT_STATE_BODY + if not in_para: + body += "\n" + in_para = True + body += f"{orig_line}\n" + else: + param = line[1:colon_index] + docs = line[colon_index + 2 :] + params[param] = docs + else: + comment_state = DBusXMLParser.COMMENT_STATE_BODY + if len(line) > 0: + if not in_para: + body += "\n" + in_para = True + body += orig_line + "\n" + elif comment_state == DBusXMLParser.COMMENT_STATE_BODY: + if len(line) > 0: + if not in_para: + in_para = True + body += orig_line + "\n" + else: + if in_para: + body += "\n" + in_para = False + if in_para: + body += "\n" + + if symbol != "": + self.doc_comment_last_symbol = symbol + self.doc_comment_params = params + self.doc_comment_body = body + + def handle_char_data(self, data): + # print 'char_data=%s'%data + pass + + def handle_start_element(self, name, attrs): + old_state = self.state + old_cur_object = self._cur_object + if self.state == DBusXMLParser.STATE_IGNORED: + self.state = DBusXMLParser.STATE_IGNORED + elif self.state == DBusXMLParser.STATE_TOP: + if name == DBusXMLParser.STATE_NODE: + self.state = DBusXMLParser.STATE_NODE + else: + self.state = DBusXMLParser.STATE_IGNORED + elif self.state == DBusXMLParser.STATE_NODE: + if name == DBusXMLParser.STATE_INTERFACE: + self.state = DBusXMLParser.STATE_INTERFACE + iface = dbustypes.Interface(attrs["name"]) + self._cur_object = iface + self.parsed_interfaces.append(iface) + elif name == DBusXMLParser.STATE_ANNOTATION: + self.state = DBusXMLParser.STATE_ANNOTATION + anno = dbustypes.Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object = anno + else: + self.state = DBusXMLParser.STATE_IGNORED + + # assign docs, if any + if "name" in attrs and self.doc_comment_last_symbol == attrs["name"]: + self._cur_object.doc_string = self.doc_comment_body + if "short_description" in self.doc_comment_params: + short_description = self.doc_comment_params["short_description"] + self._cur_object.doc_string_brief = short_description + if "since" in self.doc_comment_params: + self._cur_object.since = self.doc_comment_params["since"].strip() + + elif self.state == DBusXMLParser.STATE_INTERFACE: + if name == DBusXMLParser.STATE_METHOD: + self.state = DBusXMLParser.STATE_METHOD + method = dbustypes.Method( + attrs["name"], h_type_implies_unix_fd=self._h_type_implies_unix_fd + ) + self._cur_object.methods.append(method) + self._cur_object = method + elif name == DBusXMLParser.STATE_SIGNAL: + self.state = DBusXMLParser.STATE_SIGNAL + signal = dbustypes.Signal(attrs["name"]) + self._cur_object.signals.append(signal) + self._cur_object = signal + elif name == DBusXMLParser.STATE_PROPERTY: + self.state = DBusXMLParser.STATE_PROPERTY + prop = dbustypes.Property(attrs["name"], attrs["type"], attrs["access"]) + self._cur_object.properties.append(prop) + self._cur_object = prop + elif name == DBusXMLParser.STATE_ANNOTATION: + self.state = DBusXMLParser.STATE_ANNOTATION + anno = dbustypes.Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object = anno + else: + self.state = DBusXMLParser.STATE_IGNORED + + # assign docs, if any + if "name" in attrs and self.doc_comment_last_symbol == attrs["name"]: + self._cur_object.doc_string = self.doc_comment_body + if "since" in self.doc_comment_params: + self._cur_object.since = self.doc_comment_params["since"].strip() + + elif self.state == DBusXMLParser.STATE_METHOD: + if name == DBusXMLParser.STATE_ARG: + self.state = DBusXMLParser.STATE_ARG + arg_name = None + if "name" in attrs: + arg_name = attrs["name"] + arg = dbustypes.Arg(arg_name, attrs["type"]) + direction = attrs.get("direction", "in") + if direction == "in": + self._cur_object.in_args.append(arg) + elif direction == "out": + self._cur_object.out_args.append(arg) + else: + print_error('Invalid direction "{}"'.format(direction)) + self._cur_object = arg + elif name == DBusXMLParser.STATE_ANNOTATION: + self.state = DBusXMLParser.STATE_ANNOTATION + anno = dbustypes.Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object = anno + else: + self.state = DBusXMLParser.STATE_IGNORED + + # assign docs, if any + if self.doc_comment_last_symbol == old_cur_object.name: + if "name" in attrs and attrs["name"] in self.doc_comment_params: + doc_string = self.doc_comment_params[attrs["name"]] + if doc_string is not None: + self._cur_object.doc_string = doc_string + if "since" in self.doc_comment_params: + self._cur_object.since = self.doc_comment_params[ + "since" + ].strip() + + elif self.state == DBusXMLParser.STATE_SIGNAL: + if name == DBusXMLParser.STATE_ARG: + self.state = DBusXMLParser.STATE_ARG + arg_name = None + if "name" in attrs: + arg_name = attrs["name"] + arg = dbustypes.Arg(arg_name, attrs["type"]) + self._cur_object.args.append(arg) + self._cur_object = arg + elif name == DBusXMLParser.STATE_ANNOTATION: + self.state = DBusXMLParser.STATE_ANNOTATION + anno = dbustypes.Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object = anno + else: + self.state = DBusXMLParser.STATE_IGNORED + + # assign docs, if any + if self.doc_comment_last_symbol == old_cur_object.name: + if "name" in attrs and attrs["name"] in self.doc_comment_params: + doc_string = self.doc_comment_params[attrs["name"]] + if doc_string is not None: + self._cur_object.doc_string = doc_string + if "since" in self.doc_comment_params: + self._cur_object.since = self.doc_comment_params[ + "since" + ].strip() + + elif self.state == DBusXMLParser.STATE_PROPERTY: + if name == DBusXMLParser.STATE_ANNOTATION: + self.state = DBusXMLParser.STATE_ANNOTATION + anno = dbustypes.Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object = anno + else: + self.state = DBusXMLParser.STATE_IGNORED + + elif self.state == DBusXMLParser.STATE_ARG: + if name == DBusXMLParser.STATE_ANNOTATION: + self.state = DBusXMLParser.STATE_ANNOTATION + anno = dbustypes.Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object = anno + else: + self.state = DBusXMLParser.STATE_IGNORED + + elif self.state == DBusXMLParser.STATE_ANNOTATION: + if name == DBusXMLParser.STATE_ANNOTATION: + self.state = DBusXMLParser.STATE_ANNOTATION + anno = dbustypes.Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object = anno + else: + self.state = DBusXMLParser.STATE_IGNORED + + else: + print_error( + 'Unhandled state "{}" while entering element with name "{}"'.format( + self.state, name + ) + ) + + self.state_stack.append(old_state) + self._cur_object_stack.append(old_cur_object) + + def handle_end_element(self, name): + self.state = self.state_stack.pop() + self._cur_object = self._cur_object_stack.pop() + + +def parse_dbus_xml(xml_data, h_type_implies_unix_fd): + parser = DBusXMLParser(xml_data, h_type_implies_unix_fd) + return parser.parsed_interfaces diff --git a/gio/gdbus-2.0/codegen/utils.py b/gio/gdbus-2.0/codegen/utils.py new file mode 100644 index 0000000..95559d3 --- /dev/null +++ b/gio/gdbus-2.0/codegen/utils.py @@ -0,0 +1,165 @@ +# -*- Mode: Python -*- + +# GDBus - GLib D-Bus Library +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +import distutils.version +import os +import sys + + +# pylint: disable=too-few-public-methods +class Color: + """ANSI Terminal colors""" + + GREEN = "\033[1;32m" + BLUE = "\033[1;34m" + YELLOW = "\033[1;33m" + RED = "\033[1;31m" + END = "\033[0m" + + +def print_color(msg, color=Color.END, prefix="MESSAGE"): + """Print a string with a color prefix""" + if os.isatty(sys.stderr.fileno()): + real_prefix = "{start}{prefix}{end}".format( + start=color, prefix=prefix, end=Color.END + ) + else: + real_prefix = prefix + sys.stderr.write("{prefix}: {msg}\n".format(prefix=real_prefix, msg=msg)) + + +def print_error(msg): + """Print an error, and terminate""" + print_color(msg, color=Color.RED, prefix="ERROR") + sys.exit(1) + + +def print_warning(msg, fatal=False): + """Print a warning, and optionally terminate""" + if fatal: + color = Color.RED + prefix = "ERROR" + else: + color = Color.YELLOW + prefix = "WARNING" + print_color(msg, color, prefix) + if fatal: + sys.exit(1) + + +def print_info(msg): + """Print a message""" + print_color(msg, color=Color.GREEN, prefix="INFO") + + +def strip_dots(s): + ret = "" + force_upper = False + for c in s: + if c == ".": + force_upper = True + else: + if force_upper: + ret += c.upper() + force_upper = False + else: + ret += c + return ret + + +def dots_to_hyphens(s): + return s.replace(".", "-") + + +def camel_case_to_uscore(s): + ret = "" + insert_uscore = False + prev_was_lower = False + initial = True + for c in s: + # Keep initial underscores in camel case + if initial and c == "_": + ret += "_" + continue + initial = False + + if c.isupper(): + if prev_was_lower: + insert_uscore = True + prev_was_lower = False + else: + prev_was_lower = True + if insert_uscore: + ret += "_" + ret += c.lower() + insert_uscore = False + return ret + + +def is_ugly_case(s): + if s and s.find("_") > 0: + return True + return False + + +def lookup_annotation(annotations, key): + if annotations: + for a in annotations: + if a.key == key: + return a.value + return None + + +def lookup_docs(annotations): + s = lookup_annotation(annotations, "org.gtk.GDBus.DocString") + if s is None: + return "" + else: + return s + + +def lookup_since(annotations): + s = lookup_annotation(annotations, "org.gtk.GDBus.Since") + if s is None: + return "" + else: + return s + + +def lookup_brief_docs(annotations): + s = lookup_annotation(annotations, "org.gtk.GDBus.DocString.Short") + if s is None: + return "" + else: + return s + + +def version_cmp_key(key): + # If the 'since' version is 'UNRELEASED', compare higher than anything else + # If it is empty put a 0 in its place as this will + # allow LooseVersion to work and will always compare lower. + if key[0] == "UNRELEASED": + v = "9999" + elif key[0]: + v = str(key[0]) + else: + v = "0" + return (distutils.version.LooseVersion(v), key[1]) diff --git a/gio/gdbus-tool.c b/gio/gdbus-tool.c new file mode 100644 index 0000000..476056b --- /dev/null +++ b/gio/gdbus-tool.c @@ -0,0 +1,2641 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#ifdef G_OS_UNIX +#include +#endif + +#include + +#ifdef G_OS_WIN32 +#include "glib/glib-private.h" +#include "gdbusprivate.h" +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Escape values for console colors */ +#define UNDERLINE "\033[4m" +#define BLUE "\033[34m" +#define CYAN "\033[36m" +#define GREEN "\033[32m" +#define MAGENTA "\033[35m" +#define RED "\033[31m" +#define YELLOW "\033[33m" + +/* ---------------------------------------------------------------------------------------------------- */ + +G_GNUC_UNUSED static void completion_debug (const gchar *format, ...); + +/* Uncomment to get debug traces in /tmp/gdbus-completion-debug.txt (nice + * to not have it interfere with stdout/stderr) + */ +#if 0 +G_GNUC_UNUSED static void +completion_debug (const gchar *format, ...) +{ + va_list var_args; + gchar *s; + static FILE *f = NULL; + + va_start (var_args, format); + s = g_strdup_vprintf (format, var_args); + if (f == NULL) + { + f = fopen ("/tmp/gdbus-completion-debug.txt", "a+"); + } + fprintf (f, "%s\n", s); + g_free (s); +} +#else +static void +completion_debug (const gchar *format, ...) +{ +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + + +static void +remove_arg (gint num, gint *argc, gchar **argv[]) +{ + gint n; + + g_assert (num <= (*argc)); + + for (n = num; (*argv)[n] != NULL; n++) + (*argv)[n] = (*argv)[n+1]; + (*argv)[n] = NULL; + (*argc) = (*argc) - 1; +} + +static void +usage (gint *argc, gchar **argv[], gboolean use_stdout) +{ + GOptionContext *o; + gchar *s; + gchar *program_name; + + o = g_option_context_new (_("COMMAND")); + g_option_context_set_help_enabled (o, FALSE); + /* Ignore parsing result */ + g_option_context_parse (o, argc, argv, NULL); + program_name = (*argc > 0) ? g_path_get_basename ((*argv)[0]) : g_strdup ("gdbus-tool"); + s = g_strdup_printf (_("Commands:\n" + " help Shows this information\n" + " introspect Introspect a remote object\n" + " monitor Monitor a remote object\n" + " call Invoke a method on a remote object\n" + " emit Emit a signal\n" + " wait Wait for a bus name to appear\n" + "\n" + "Use “%s COMMAND --help†to get help on each command.\n"), + program_name); + g_free (program_name); + g_option_context_set_description (o, s); + g_free (s); + s = g_option_context_get_help (o, FALSE, NULL); + if (use_stdout) + g_print ("%s", s); + else + g_printerr ("%s", s); + g_free (s); + g_option_context_free (o); +} + +static void +modify_argv0_for_command (gint *argc, gchar **argv[], const gchar *command) +{ + gchar *s; + gchar *program_name; + + /* TODO: + * 1. get a g_set_prgname() ?; or + * 2. save old argv[0] and restore later + */ + + g_assert (*argc > 1); + g_assert (g_strcmp0 ((*argv)[1], command) == 0); + remove_arg (1, argc, argv); + + program_name = g_path_get_basename ((*argv)[0]); + s = g_strdup_printf ("%s %s", program_name, command); + (*argv)[0] = s; + g_free (program_name); +} + +static GOptionContext * +command_option_context_new (const gchar *parameter_string, + const gchar *summary, + const GOptionEntry *entries, + gboolean request_completion) +{ + GOptionContext *o = NULL; + + o = g_option_context_new (parameter_string); + if (request_completion) + g_option_context_set_ignore_unknown_options (o, TRUE); + g_option_context_set_help_enabled (o, FALSE); + g_option_context_set_summary (o, summary); + g_option_context_add_main_entries (o, entries, GETTEXT_PACKAGE); + + return g_steal_pointer (&o); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +print_methods_and_signals (GDBusConnection *c, + const gchar *name, + const gchar *path, + gboolean print_methods, + gboolean print_signals) +{ + GVariant *result; + GError *error; + const gchar *xml_data; + GDBusNodeInfo *node; + guint n; + guint m; + + error = NULL; + result = g_dbus_connection_call_sync (c, + name, + path, + "org.freedesktop.DBus.Introspectable", + "Introspect", + NULL, + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + 3000, /* 3 secs */ + NULL, + &error); + if (result == NULL) + { + g_printerr (_("Error: %s\n"), error->message); + g_error_free (error); + goto out; + } + g_variant_get (result, "(&s)", &xml_data); + + error = NULL; + node = g_dbus_node_info_new_for_xml (xml_data, &error); + g_variant_unref (result); + if (node == NULL) + { + g_printerr (_("Error parsing introspection XML: %s\n"), error->message); + g_error_free (error); + goto out; + } + + for (n = 0; node->interfaces != NULL && node->interfaces[n] != NULL; n++) + { + const GDBusInterfaceInfo *iface = node->interfaces[n]; + for (m = 0; print_methods && iface->methods != NULL && iface->methods[m] != NULL; m++) + { + const GDBusMethodInfo *method = iface->methods[m]; + g_print ("%s.%s \n", iface->name, method->name); + } + for (m = 0; print_signals && iface->signals != NULL && iface->signals[m] != NULL; m++) + { + const GDBusSignalInfo *signal = iface->signals[m]; + g_print ("%s.%s \n", iface->name, signal->name); + } + } + g_dbus_node_info_unref (node); + + out: + ; +} + +static void +print_paths (GDBusConnection *c, + const gchar *name, + const gchar *path) +{ + GVariant *result; + GError *error; + const gchar *xml_data; + GDBusNodeInfo *node; + guint n; + + if (!g_dbus_is_name (name)) + { + g_printerr (_("Error: %s is not a valid name\n"), name); + goto out; + } + if (!g_variant_is_object_path (path)) + { + g_printerr (_("Error: %s is not a valid object path\n"), path); + goto out; + } + + error = NULL; + result = g_dbus_connection_call_sync (c, + name, + path, + "org.freedesktop.DBus.Introspectable", + "Introspect", + NULL, + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + 3000, /* 3 secs */ + NULL, + &error); + if (result == NULL) + { + g_printerr (_("Error: %s\n"), error->message); + g_error_free (error); + goto out; + } + g_variant_get (result, "(&s)", &xml_data); + + //g_printerr ("xml='%s'", xml_data); + + error = NULL; + node = g_dbus_node_info_new_for_xml (xml_data, &error); + g_variant_unref (result); + if (node == NULL) + { + g_printerr (_("Error parsing introspection XML: %s\n"), error->message); + g_error_free (error); + goto out; + } + + //g_printerr ("bar '%s'\n", path); + + if (node->interfaces != NULL) + g_print ("%s \n", path); + + for (n = 0; node->nodes != NULL && node->nodes[n] != NULL; n++) + { + gchar *s; + + //g_printerr ("foo '%s'\n", node->nodes[n].path); + + if (g_strcmp0 (path, "/") == 0) + s = g_strdup_printf ("/%s", node->nodes[n]->path); + else + s = g_strdup_printf ("%s/%s", path, node->nodes[n]->path); + + print_paths (c, name, s); + + g_free (s); + } + g_dbus_node_info_unref (node); + + out: + ; +} + +static void +print_names (GDBusConnection *c, + gboolean include_unique_names) +{ + GVariant *result; + GError *error; + GVariantIter *iter; + gchar *str; + GHashTable *name_set; + GList *keys; + GList *l; + + name_set = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + error = NULL; + result = g_dbus_connection_call_sync (c, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ListNames", + NULL, + G_VARIANT_TYPE ("(as)"), + G_DBUS_CALL_FLAGS_NONE, + 3000, /* 3 secs */ + NULL, + &error); + if (result == NULL) + { + g_printerr (_("Error: %s\n"), error->message); + g_error_free (error); + goto out; + } + g_variant_get (result, "(as)", &iter); + while (g_variant_iter_loop (iter, "s", &str)) + g_hash_table_add (name_set, g_strdup (str)); + g_variant_iter_free (iter); + g_variant_unref (result); + + error = NULL; + result = g_dbus_connection_call_sync (c, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ListActivatableNames", + NULL, + G_VARIANT_TYPE ("(as)"), + G_DBUS_CALL_FLAGS_NONE, + 3000, /* 3 secs */ + NULL, + &error); + if (result == NULL) + { + g_printerr (_("Error: %s\n"), error->message); + g_error_free (error); + goto out; + } + g_variant_get (result, "(as)", &iter); + while (g_variant_iter_loop (iter, "s", &str)) + g_hash_table_add (name_set, g_strdup (str)); + g_variant_iter_free (iter); + g_variant_unref (result); + + keys = g_hash_table_get_keys (name_set); + keys = g_list_sort (keys, (GCompareFunc) g_strcmp0); + for (l = keys; l != NULL; l = l->next) + { + const gchar *name = l->data; + if (!include_unique_names && g_str_has_prefix (name, ":")) + continue; + + g_print ("%s \n", name); + } + g_list_free (keys); + + out: + g_hash_table_unref (name_set); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean opt_connection_system = FALSE; +static gboolean opt_connection_session = FALSE; +static gchar *opt_connection_address = NULL; + +static const GOptionEntry connection_entries[] = +{ + { "system", 'y', 0, G_OPTION_ARG_NONE, &opt_connection_system, N_("Connect to the system bus"), NULL}, + { "session", 'e', 0, G_OPTION_ARG_NONE, &opt_connection_session, N_("Connect to the session bus"), NULL}, + { "address", 'a', 0, G_OPTION_ARG_STRING, &opt_connection_address, N_("Connect to given D-Bus address"), NULL}, + G_OPTION_ENTRY_NULL +}; + +static GOptionGroup * +connection_get_group (void) +{ + static GOptionGroup *g; + + g = g_option_group_new ("connection", + N_("Connection Endpoint Options:"), + N_("Options specifying the connection endpoint"), + NULL, + NULL); + g_option_group_set_translation_domain (g, GETTEXT_PACKAGE); + g_option_group_add_entries (g, connection_entries); + + return g; +} + +static GDBusConnection * +connection_get_dbus_connection (gboolean require_message_bus, + GError **error) +{ + GDBusConnection *c; + + c = NULL; + + /* First, ensure we have exactly one connect */ + if (!opt_connection_system && !opt_connection_session && opt_connection_address == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("No connection endpoint specified")); + goto out; + } + else if ((opt_connection_system && (opt_connection_session || opt_connection_address != NULL)) || + (opt_connection_session && (opt_connection_system || opt_connection_address != NULL)) || + (opt_connection_address != NULL && (opt_connection_system || opt_connection_session))) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Multiple connection endpoints specified")); + goto out; + } + + if (opt_connection_system) + { + c = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); + } + else if (opt_connection_session) + { + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error); + } + else if (opt_connection_address != NULL) + { + GDBusConnectionFlags flags = G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT; + if (require_message_bus) + flags |= G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION; + c = g_dbus_connection_new_for_address_sync (opt_connection_address, + flags, + NULL, /* GDBusAuthObserver */ + NULL, /* GCancellable */ + error); + } + + out: + return c; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GPtrArray * +call_helper_get_method_in_signature (GDBusConnection *c, + const gchar *dest, + const gchar *path, + const gchar *interface_name, + const gchar *method_name, + GError **error) +{ + GPtrArray *ret; + GVariant *result; + GDBusNodeInfo *node_info; + const gchar *xml_data; + GDBusInterfaceInfo *interface_info; + GDBusMethodInfo *method_info; + guint n; + + ret = NULL; + result = NULL; + node_info = NULL; + + result = g_dbus_connection_call_sync (c, + dest, + path, + "org.freedesktop.DBus.Introspectable", + "Introspect", + NULL, + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + 3000, /* 3 secs */ + NULL, + error); + if (result == NULL) + goto out; + + g_variant_get (result, "(&s)", &xml_data); + node_info = g_dbus_node_info_new_for_xml (xml_data, error); + if (node_info == NULL) + goto out; + + interface_info = g_dbus_node_info_lookup_interface (node_info, interface_name); + if (interface_info == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Warning: According to introspection data, interface “%s†does not exist\n"), + interface_name); + goto out; + } + + method_info = g_dbus_interface_info_lookup_method (interface_info, method_name); + if (method_info == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Warning: According to introspection data, method “%s†does not exist on interface “%sâ€\n"), + method_name, + interface_name); + goto out; + } + + ret = g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_type_free); + for (n = 0; method_info->in_args != NULL && method_info->in_args[n] != NULL; n++) + { + g_ptr_array_add (ret, g_variant_type_new (method_info->in_args[n]->signature)); + } + + out: + if (node_info != NULL) + g_dbus_node_info_unref (node_info); + if (result != NULL) + g_variant_unref (result); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GVariant * +_g_variant_parse_me_harder (GVariantType *type, + const gchar *given_str, + GError **error) +{ + GVariant *value; + gchar *s; + guint n; + GString *str; + + str = g_string_new ("\""); + for (n = 0; given_str[n] != '\0'; n++) + { + if (G_UNLIKELY (given_str[n] == '\"')) + g_string_append (str, "\\\""); + else + g_string_append_c (str, given_str[n]); + } + g_string_append_c (str, '"'); + s = g_string_free (str, FALSE); + + value = g_variant_parse (type, + s, + NULL, + NULL, + error); + g_free (s); + + return value; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar *opt_emit_dest = NULL; +static gchar *opt_emit_object_path = NULL; +static gchar *opt_emit_signal = NULL; + +static const GOptionEntry emit_entries[] = +{ + { "dest", 'd', 0, G_OPTION_ARG_STRING, &opt_emit_dest, N_("Optional destination for signal (unique name)"), NULL}, + { "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_emit_object_path, N_("Object path to emit signal on"), NULL}, + { "signal", 's', 0, G_OPTION_ARG_STRING, &opt_emit_signal, N_("Signal and interface name"), NULL}, + G_OPTION_ENTRY_NULL +}; + +static gboolean +handle_emit (gint *argc, + gchar **argv[], + gboolean request_completion, + const gchar *completion_cur, + const gchar *completion_prev) +{ + gint ret; + GOptionContext *o; + gchar *s; + GError *error; + GDBusConnection *c; + GVariant *parameters; + gchar *interface_name; + gchar *signal_name; + GVariantBuilder builder; + gboolean skip_dashes; + guint parm; + guint n; + gboolean complete_names, complete_paths, complete_signals; + + ret = FALSE; + c = NULL; + parameters = NULL; + interface_name = NULL; + signal_name = NULL; + + modify_argv0_for_command (argc, argv, "emit"); + + o = command_option_context_new (NULL, _("Emit a signal."), + emit_entries, request_completion); + g_option_context_add_group (o, connection_get_group ()); + + complete_names = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--dest") == 0) + { + complete_names = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + complete_paths = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--object-path") == 0) + { + complete_paths = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + complete_signals = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--signal") == 0) + { + complete_signals = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + if (!g_option_context_parse (o, argc, argv, NULL)) + { + if (!request_completion) + { + s = g_option_context_get_help (o, FALSE, NULL); + g_printerr ("%s", s); + g_free (s); + goto out; + } + } + + error = NULL; + c = connection_get_dbus_connection ((opt_emit_dest != NULL), &error); + if (c == NULL) + { + if (request_completion) + { + if (g_strcmp0 (completion_prev, "--address") == 0) + { + g_print ("unix:\n" + "tcp:\n" + "nonce-tcp:\n"); + } + else + { + g_print ("--system \n--session \n--address \n"); + } + } + else + { + g_printerr (_("Error connecting: %s\n"), error->message); + } + g_error_free (error); + goto out; + } + + /* validate and complete destination (bus name) */ + if (complete_names) + { + print_names (c, FALSE); + goto out; + } + if (request_completion && opt_emit_dest != NULL && g_strcmp0 ("--dest", completion_prev) == 0) + { + print_names (c, g_str_has_prefix (opt_emit_dest, ":")); + goto out; + } + + if (!request_completion && opt_emit_dest != NULL && !g_dbus_is_unique_name (opt_emit_dest)) + { + g_printerr (_("Error: %s is not a valid unique bus name.\n"), opt_emit_dest); + goto out; + } + + if (opt_emit_dest == NULL && opt_emit_object_path == NULL && request_completion) + { + g_print ("--dest \n"); + } + /* validate and complete object path */ + if (opt_emit_dest != NULL && complete_paths) + { + print_paths (c, opt_emit_dest, "/"); + goto out; + } + if (opt_emit_object_path == NULL) + { + if (request_completion) + g_print ("--object-path \n"); + else + g_printerr (_("Error: Object path is not specified\n")); + goto out; + } + if (request_completion && g_strcmp0 ("--object-path", completion_prev) == 0) + { + if (opt_emit_dest != NULL) + { + gchar *p; + s = g_strdup (opt_emit_object_path); + p = strrchr (s, '/'); + if (p != NULL) + { + if (p == s) + p++; + *p = '\0'; + } + print_paths (c, opt_emit_dest, s); + g_free (s); + } + goto out; + } + if (!request_completion && !g_variant_is_object_path (opt_emit_object_path)) + { + g_printerr (_("Error: %s is not a valid object path\n"), opt_emit_object_path); + goto out; + } + + /* validate and complete signal (interface + signal name) */ + if (opt_emit_dest != NULL && opt_emit_object_path != NULL && complete_signals) + { + print_methods_and_signals (c, opt_emit_dest, opt_emit_object_path, FALSE, TRUE); + goto out; + } + if (opt_emit_signal == NULL) + { + /* don't keep repeatedly completing --signal */ + if (request_completion) + { + if (g_strcmp0 ("--signal", completion_prev) != 0) + g_print ("--signal \n"); + } + else + { + g_printerr (_("Error: Signal name is not specified\n")); + } + + goto out; + } + if (request_completion && opt_emit_dest != NULL && opt_emit_object_path != NULL && + g_strcmp0 ("--signal", completion_prev) == 0) + { + print_methods_and_signals (c, opt_emit_dest, opt_emit_object_path, FALSE, TRUE); + goto out; + } + s = strrchr (opt_emit_signal, '.'); + if (!request_completion && s == NULL) + { + g_printerr (_("Error: Signal name “%s†is invalid\n"), opt_emit_signal); + goto out; + } + signal_name = g_strdup (s + 1); + interface_name = g_strndup (opt_emit_signal, s - opt_emit_signal); + + /* All done with completion now */ + if (request_completion) + goto out; + + if (!g_dbus_is_interface_name (interface_name)) + { + g_printerr (_("Error: %s is not a valid interface name\n"), interface_name); + goto out; + } + + if (!g_dbus_is_member_name (signal_name)) + { + g_printerr (_("Error: %s is not a valid member name\n"), signal_name); + goto out; + } + + /* Read parameters */ + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + skip_dashes = TRUE; + parm = 0; + for (n = 1; n < (guint) *argc; n++) + { + GVariant *value; + + /* Under certain conditions, g_option_context_parse returns the "--" + itself (setting off unparsed arguments), too: */ + if (skip_dashes && g_strcmp0 ((*argv)[n], "--") == 0) + { + skip_dashes = FALSE; + continue; + } + + error = NULL; + value = g_variant_parse (NULL, + (*argv)[n], + NULL, + NULL, + &error); + if (value == NULL) + { + gchar *context; + + context = g_variant_parse_error_print_context (error, (*argv)[n]); + g_error_free (error); + error = NULL; + value = _g_variant_parse_me_harder (NULL, (*argv)[n], &error); + if (value == NULL) + { + /* Use the original non-"parse-me-harder" error */ + g_printerr (_("Error parsing parameter %d: %s\n"), + parm + 1, + context); + g_error_free (error); + g_free (context); + g_variant_builder_clear (&builder); + goto out; + } + g_free (context); + } + g_variant_builder_add_value (&builder, value); + ++parm; + } + parameters = g_variant_builder_end (&builder); + + if (parameters != NULL) + parameters = g_variant_ref_sink (parameters); + if (!g_dbus_connection_emit_signal (c, + opt_emit_dest, + opt_emit_object_path, + interface_name, + signal_name, + parameters, + &error)) + { + g_printerr (_("Error: %s\n"), error->message); + g_error_free (error); + goto out; + } + + if (!g_dbus_connection_flush_sync (c, NULL, &error)) + { + g_printerr (_("Error flushing connection: %s\n"), error->message); + g_error_free (error); + goto out; + } + + ret = TRUE; + + out: + if (c != NULL) + g_object_unref (c); + if (parameters != NULL) + g_variant_unref (parameters); + g_free (interface_name); + g_free (signal_name); + g_option_context_free (o); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar *opt_call_dest = NULL; +static gchar *opt_call_object_path = NULL; +static gchar *opt_call_method = NULL; +static gint opt_call_timeout = -1; +static gboolean opt_call_interactive = FALSE; + +static const GOptionEntry call_entries[] = +{ + { "dest", 'd', 0, G_OPTION_ARG_STRING, &opt_call_dest, N_("Destination name to invoke method on"), NULL}, + { "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_call_object_path, N_("Object path to invoke method on"), NULL}, + { "method", 'm', 0, G_OPTION_ARG_STRING, &opt_call_method, N_("Method and interface name"), NULL}, + { "timeout", 't', 0, G_OPTION_ARG_INT, &opt_call_timeout, N_("Timeout in seconds"), NULL}, + { "interactive", 'i', 0, G_OPTION_ARG_NONE, &opt_call_interactive, N_("Allow interactive authorization"), NULL}, + G_OPTION_ENTRY_NULL +}; + +static gboolean +handle_call (gint *argc, + gchar **argv[], + gboolean request_completion, + const gchar *completion_cur, + const gchar *completion_prev) +{ + gint ret; + GOptionContext *o; + gchar *s; + GError *error; + GDBusConnection *c; + GVariant *parameters; + gchar *interface_name; + gchar *method_name; + GVariant *result; + GPtrArray *in_signature_types; +#ifdef G_OS_UNIX + GUnixFDList *fd_list; + gint fd_id; +#endif + gboolean complete_names; + gboolean complete_paths; + gboolean complete_methods; + GVariantBuilder builder; + gboolean skip_dashes; + guint parm; + guint n; + GDBusCallFlags flags; + + ret = FALSE; + c = NULL; + parameters = NULL; + interface_name = NULL; + method_name = NULL; + result = NULL; + in_signature_types = NULL; +#ifdef G_OS_UNIX + fd_list = NULL; +#endif + + modify_argv0_for_command (argc, argv, "call"); + + o = command_option_context_new (NULL, _("Invoke a method on a remote object."), + call_entries, request_completion); + g_option_context_add_group (o, connection_get_group ()); + + complete_names = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--dest") == 0) + { + complete_names = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + complete_paths = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--object-path") == 0) + { + complete_paths = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + complete_methods = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--method") == 0) + { + complete_methods = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + if (!g_option_context_parse (o, argc, argv, NULL)) + { + if (!request_completion) + { + s = g_option_context_get_help (o, FALSE, NULL); + g_printerr ("%s", s); + g_free (s); + goto out; + } + } + + error = NULL; + c = connection_get_dbus_connection (TRUE, &error); + if (c == NULL) + { + if (request_completion) + { + if (g_strcmp0 (completion_prev, "--address") == 0) + { + g_print ("unix:\n" + "tcp:\n" + "nonce-tcp:\n"); + } + else + { + g_print ("--system \n--session \n--address \n"); + } + } + else + { + g_printerr (_("Error connecting: %s\n"), error->message); + } + g_error_free (error); + goto out; + } + + /* validate and complete destination (bus name) */ + if (complete_names) + { + print_names (c, FALSE); + goto out; + } + if (opt_call_dest == NULL) + { + if (request_completion) + g_print ("--dest \n"); + else + g_printerr (_("Error: Destination is not specified\n")); + goto out; + } + if (request_completion && g_strcmp0 ("--dest", completion_prev) == 0) + { + print_names (c, g_str_has_prefix (opt_call_dest, ":")); + goto out; + } + + if (!request_completion && !g_dbus_is_name (opt_call_dest)) + { + g_printerr (_("Error: %s is not a valid bus name\n"), opt_call_dest); + goto out; + } + + /* validate and complete object path */ + if (complete_paths) + { + print_paths (c, opt_call_dest, "/"); + goto out; + } + if (opt_call_object_path == NULL) + { + if (request_completion) + g_print ("--object-path \n"); + else + g_printerr (_("Error: Object path is not specified\n")); + goto out; + } + if (request_completion && g_strcmp0 ("--object-path", completion_prev) == 0) + { + gchar *p; + s = g_strdup (opt_call_object_path); + p = strrchr (s, '/'); + if (p != NULL) + { + if (p == s) + p++; + *p = '\0'; + } + print_paths (c, opt_call_dest, s); + g_free (s); + goto out; + } + if (!request_completion && !g_variant_is_object_path (opt_call_object_path)) + { + g_printerr (_("Error: %s is not a valid object path\n"), opt_call_object_path); + goto out; + } + + /* validate and complete method (interface + method name) */ + if (complete_methods) + { + print_methods_and_signals (c, opt_call_dest, opt_call_object_path, TRUE, FALSE); + goto out; + } + if (opt_call_method == NULL) + { + if (request_completion) + g_print ("--method \n"); + else + g_printerr (_("Error: Method name is not specified\n")); + goto out; + } + if (request_completion && g_strcmp0 ("--method", completion_prev) == 0) + { + print_methods_and_signals (c, opt_call_dest, opt_call_object_path, TRUE, FALSE); + goto out; + } + s = strrchr (opt_call_method, '.'); + if (!request_completion && s == NULL) + { + g_printerr (_("Error: Method name “%s†is invalid\n"), opt_call_method); + goto out; + } + method_name = g_strdup (s + 1); + interface_name = g_strndup (opt_call_method, s - opt_call_method); + + /* All done with completion now */ + if (request_completion) + goto out; + + /* Introspect, for easy conversion - it's not fatal if we can't do this */ + in_signature_types = call_helper_get_method_in_signature (c, + opt_call_dest, + opt_call_object_path, + interface_name, + method_name, + &error); + if (in_signature_types == NULL) + { + //g_printerr ("Error getting introspection data: %s\n", error->message); + g_error_free (error); + error = NULL; + } + + /* Read parameters */ + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + skip_dashes = TRUE; + parm = 0; + for (n = 1; n < (guint) *argc; n++) + { + GVariant *value; + GVariantType *type; + + /* Under certain conditions, g_option_context_parse returns the "--" + itself (setting off unparsed arguments), too: */ + if (skip_dashes && g_strcmp0 ((*argv)[n], "--") == 0) + { + skip_dashes = FALSE; + continue; + } + + type = NULL; + if (in_signature_types != NULL) + { + if (parm >= in_signature_types->len) + { + /* Only warn for the first param */ + if (parm == in_signature_types->len) + { + g_printerr ("Warning: Introspection data indicates %d parameters but more was passed\n", + in_signature_types->len); + } + } + else + { + type = in_signature_types->pdata[parm]; + } + } + + error = NULL; + value = g_variant_parse (type, + (*argv)[n], + NULL, + NULL, + &error); + if (value == NULL) + { + gchar *context; + + context = g_variant_parse_error_print_context (error, (*argv)[n]); + g_error_free (error); + error = NULL; + value = _g_variant_parse_me_harder (type, (*argv)[n], &error); + if (value == NULL) + { + if (type != NULL) + { + s = g_variant_type_dup_string (type); + g_printerr (_("Error parsing parameter %d of type “%sâ€: %s\n"), + parm + 1, + s, + context); + g_free (s); + } + else + { + g_printerr (_("Error parsing parameter %d: %s\n"), + parm + 1, + context); + } + g_error_free (error); + g_variant_builder_clear (&builder); + g_free (context); + goto out; + } + g_free (context); + } +#ifdef G_OS_UNIX + if (g_variant_is_of_type (value, G_VARIANT_TYPE_HANDLE)) + { + if (!fd_list) + fd_list = g_unix_fd_list_new (); + if ((fd_id = g_unix_fd_list_append (fd_list, g_variant_get_handle (value), &error)) == -1) + { + g_printerr (_("Error adding handle %d: %s\n"), + g_variant_get_handle (value), error->message); + g_variant_builder_clear (&builder); + g_error_free (error); + goto out; + } + g_variant_unref (value); + value = g_variant_new_handle (fd_id); + } +#endif + g_variant_builder_add_value (&builder, value); + ++parm; + } + parameters = g_variant_builder_end (&builder); + + if (parameters != NULL) + parameters = g_variant_ref_sink (parameters); + + flags = G_DBUS_CALL_FLAGS_NONE; + if (opt_call_interactive) + flags |= G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION; + +#ifdef G_OS_UNIX + result = g_dbus_connection_call_with_unix_fd_list_sync (c, + opt_call_dest, + opt_call_object_path, + interface_name, + method_name, + parameters, + NULL, + flags, + opt_call_timeout > 0 ? opt_call_timeout * 1000 : opt_call_timeout, + fd_list, + NULL, + NULL, + &error); +#else + result = g_dbus_connection_call_sync (c, + opt_call_dest, + opt_call_object_path, + interface_name, + method_name, + parameters, + NULL, + flags, + opt_call_timeout > 0 ? opt_call_timeout * 1000 : opt_call_timeout, + NULL, + &error); +#endif + if (result == NULL) + { + g_printerr (_("Error: %s\n"), error->message); + + if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS) && in_signature_types != NULL) + { + if (in_signature_types->len > 0) + { + GString *s; + s = g_string_new (NULL); + + for (n = 0; n < in_signature_types->len; n++) + { + GVariantType *type = in_signature_types->pdata[n]; + g_string_append_len (s, + g_variant_type_peek_string (type), + g_variant_type_get_string_length (type)); + } + + g_printerr ("(According to introspection data, you need to pass '%s')\n", s->str); + g_string_free (s, TRUE); + } + else + g_printerr ("(According to introspection data, you need to pass no arguments)\n"); + } + + g_error_free (error); + goto out; + } + + s = g_variant_print (result, TRUE); + g_print ("%s\n", s); + g_free (s); + + ret = TRUE; + + out: + if (in_signature_types != NULL) + g_ptr_array_unref (in_signature_types); + if (result != NULL) + g_variant_unref (result); + if (c != NULL) + g_object_unref (c); + if (parameters != NULL) + g_variant_unref (parameters); + g_free (interface_name); + g_free (method_name); + g_option_context_free (o); +#ifdef G_OS_UNIX + g_clear_object (&fd_list); +#endif + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar *opt_introspect_dest = NULL; +static gchar *opt_introspect_object_path = NULL; +static gboolean opt_introspect_xml = FALSE; +static gboolean opt_introspect_recurse = FALSE; +static gboolean opt_introspect_only_properties = FALSE; + +/* Introspect colors */ +#define RESET_COLOR (use_colors? "\033[0m": "") +#define INTROSPECT_TITLE_COLOR (use_colors? UNDERLINE: "") +#define INTROSPECT_NODE_COLOR (use_colors? RESET_COLOR: "") +#define INTROSPECT_INTERFACE_COLOR (use_colors? YELLOW: "") +#define INTROSPECT_METHOD_COLOR (use_colors? BLUE: "") +#define INTROSPECT_SIGNAL_COLOR (use_colors? BLUE: "") +#define INTROSPECT_PROPERTY_COLOR (use_colors? MAGENTA: "") +#define INTROSPECT_INOUT_COLOR (use_colors? RESET_COLOR: "") +#define INTROSPECT_TYPE_COLOR (use_colors? GREEN: "") +#define INTROSPECT_ANNOTATION_COLOR (use_colors? RESET_COLOR: "") + +static void +dump_annotation (const GDBusAnnotationInfo *o, + guint indent, + gboolean ignore_indent, + gboolean use_colors) +{ + guint n; + g_print ("%*s%s@%s(\"%s\")%s\n", + ignore_indent ? 0 : indent, "", + INTROSPECT_ANNOTATION_COLOR, o->key, o->value, RESET_COLOR); + for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) + dump_annotation (o->annotations[n], indent + 2, FALSE, use_colors); +} + +static void +dump_arg (const GDBusArgInfo *o, + guint indent, + const gchar *direction, + gboolean ignore_indent, + gboolean include_newline, + gboolean use_colors) +{ + guint n; + + for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) + { + dump_annotation (o->annotations[n], indent, ignore_indent, use_colors); + ignore_indent = FALSE; + } + + g_print ("%*s%s%s%s%s%s%s %s%s", + ignore_indent ? 0 : indent, "", + INTROSPECT_INOUT_COLOR, direction, RESET_COLOR, + INTROSPECT_TYPE_COLOR, o->signature, RESET_COLOR, + o->name, + include_newline ? ",\n" : ""); +} + +static guint +count_args (GDBusArgInfo **args) +{ + guint n; + n = 0; + if (args == NULL) + goto out; + while (args[n] != NULL) + n++; + out: + return n; +} + +static void +dump_method (const GDBusMethodInfo *o, + guint indent, + gboolean use_colors) +{ + guint n; + guint m; + guint name_len; + guint total_num_args; + + for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) + dump_annotation (o->annotations[n], indent, FALSE, use_colors); + + g_print ("%*s%s%s%s(", + indent, "", + INTROSPECT_METHOD_COLOR, o->name, RESET_COLOR); + name_len = strlen (o->name); + total_num_args = count_args (o->in_args) + count_args (o->out_args); + for (n = 0, m = 0; o->in_args != NULL && o->in_args[n] != NULL; n++, m++) + { + gboolean ignore_indent = (m == 0); + gboolean include_newline = (m != total_num_args - 1); + + dump_arg (o->in_args[n], + indent + name_len + 1, + "in ", + ignore_indent, + include_newline, + use_colors); + } + for (n = 0; o->out_args != NULL && o->out_args[n] != NULL; n++, m++) + { + gboolean ignore_indent = (m == 0); + gboolean include_newline = (m != total_num_args - 1); + dump_arg (o->out_args[n], + indent + name_len + 1, + "out ", + ignore_indent, + include_newline, + use_colors); + } + g_print (");\n"); +} + +static void +dump_signal (const GDBusSignalInfo *o, + guint indent, + gboolean use_colors) +{ + guint n; + guint name_len; + guint total_num_args; + + for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) + dump_annotation (o->annotations[n], indent, FALSE, use_colors); + + g_print ("%*s%s%s%s(", + indent, "", + INTROSPECT_SIGNAL_COLOR, o->name, RESET_COLOR); + name_len = strlen (o->name); + total_num_args = count_args (o->args); + for (n = 0; o->args != NULL && o->args[n] != NULL; n++) + { + gboolean ignore_indent = (n == 0); + gboolean include_newline = (n != total_num_args - 1); + dump_arg (o->args[n], + indent + name_len + 1, + "", + ignore_indent, + include_newline, + use_colors); + } + g_print (");\n"); +} + +static void +dump_property (const GDBusPropertyInfo *o, + guint indent, + gboolean use_colors, + GVariant *value) +{ + const gchar *access; + guint n; + + if (o->flags == G_DBUS_PROPERTY_INFO_FLAGS_READABLE) + access = "readonly"; + else if (o->flags == G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE) + access = "writeonly"; + else if (o->flags == (G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE)) + access = "readwrite"; + else + g_assert_not_reached (); + + for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) + dump_annotation (o->annotations[n], indent, FALSE, use_colors); + + if (value != NULL) + { + gchar *s = g_variant_print (value, FALSE); + g_print ("%*s%s %s%s%s %s%s%s = %s;\n", indent, "", access, + INTROSPECT_TYPE_COLOR, o->signature, RESET_COLOR, + INTROSPECT_PROPERTY_COLOR, o->name, RESET_COLOR, + s); + g_free (s); + } + else + { + g_print ("%*s%s %s %s;\n", indent, "", access, o->signature, o->name); + } +} + +static void +dump_interface (GDBusConnection *c, + const gchar *name, + const GDBusInterfaceInfo *o, + guint indent, + gboolean use_colors, + const gchar *object_path) +{ + guint n; + GHashTable *properties; + + properties = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); + + /* Try to get properties */ + if (c != NULL && name != NULL && object_path != NULL && o->properties != NULL) + { + GVariant *result; + result = g_dbus_connection_call_sync (c, + name, + object_path, + "org.freedesktop.DBus.Properties", + "GetAll", + g_variant_new ("(s)", o->name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + 3000, + NULL, + NULL); + if (result != NULL) + { + if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(a{sv})"))) + { + GVariantIter *iter; + GVariant *item; + g_variant_get (result, + "(a{sv})", + &iter); + while ((item = g_variant_iter_next_value (iter))) + { + gchar *key; + GVariant *value; + g_variant_get (item, + "{sv}", + &key, + &value); + + g_hash_table_insert (properties, key, g_variant_ref (value)); + } + } + g_variant_unref (result); + } + else + { + guint n; + for (n = 0; o->properties != NULL && o->properties[n] != NULL; n++) + { + result = g_dbus_connection_call_sync (c, + name, + object_path, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new ("(ss)", o->name, o->properties[n]->name), + G_VARIANT_TYPE ("(v)"), + G_DBUS_CALL_FLAGS_NONE, + 3000, + NULL, + NULL); + if (result != NULL) + { + GVariant *property_value; + g_variant_get (result, + "(v)", + &property_value); + g_hash_table_insert (properties, + g_strdup (o->properties[n]->name), + g_variant_ref (property_value)); + g_variant_unref (result); + } + } + } + } + + for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) + dump_annotation (o->annotations[n], indent, FALSE, use_colors); + + g_print ("%*s%sinterface %s%s {\n", + indent, "", + INTROSPECT_INTERFACE_COLOR, o->name, RESET_COLOR); + if (o->methods != NULL && !opt_introspect_only_properties) + { + g_print ("%*s %smethods%s:\n", + indent, "", + INTROSPECT_TITLE_COLOR, RESET_COLOR); + for (n = 0; o->methods[n] != NULL; n++) + dump_method (o->methods[n], indent + 4, use_colors); + } + if (o->signals != NULL && !opt_introspect_only_properties) + { + g_print ("%*s %ssignals%s:\n", + indent, "", + INTROSPECT_TITLE_COLOR, RESET_COLOR); + for (n = 0; o->signals[n] != NULL; n++) + dump_signal (o->signals[n], indent + 4, use_colors); + } + if (o->properties != NULL) + { + g_print ("%*s %sproperties%s:\n", + indent, "", + INTROSPECT_TITLE_COLOR, RESET_COLOR); + for (n = 0; o->properties[n] != NULL; n++) + { + dump_property (o->properties[n], + indent + 4, + use_colors, + g_hash_table_lookup (properties, (o->properties[n])->name)); + } + } + g_print ("%*s};\n", + indent, ""); + + g_hash_table_unref (properties); +} + +static gboolean +introspect_do (GDBusConnection *c, + const gchar *object_path, + guint indent, + gboolean use_colors); + +static void +dump_node (GDBusConnection *c, + const gchar *name, + const GDBusNodeInfo *o, + guint indent, + gboolean use_colors, + const gchar *object_path, + gboolean recurse) +{ + guint n; + const gchar *object_path_to_print; + + object_path_to_print = object_path; + if (o->path != NULL) + object_path_to_print = o->path; + + for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) + dump_annotation (o->annotations[n], indent, FALSE, use_colors); + + g_print ("%*s%snode %s%s", + indent, "", + INTROSPECT_NODE_COLOR, + object_path_to_print != NULL ? object_path_to_print : "(not set)", + RESET_COLOR); + if (o->interfaces != NULL || o->nodes != NULL) + { + g_print (" {\n"); + for (n = 0; o->interfaces != NULL && o->interfaces[n] != NULL; n++) + { + if (opt_introspect_only_properties) + { + if (o->interfaces[n]->properties != NULL && o->interfaces[n]->properties[0] != NULL) + dump_interface (c, name, o->interfaces[n], indent + 2, use_colors, object_path); + } + else + { + dump_interface (c, name, o->interfaces[n], indent + 2, use_colors, object_path); + } + } + for (n = 0; o->nodes != NULL && o->nodes[n] != NULL; n++) + { + if (recurse) + { + gchar *child_path; + if (g_variant_is_object_path (o->nodes[n]->path)) + { + child_path = g_strdup (o->nodes[n]->path); + /* avoid infinite loops */ + if (g_str_has_prefix (child_path, object_path)) + { + introspect_do (c, child_path, indent + 2, use_colors); + } + else + { + g_print ("Skipping path %s that is not enclosed by parent %s\n", + child_path, object_path); + } + } + else + { + if (g_strcmp0 (object_path, "/") == 0) + child_path = g_strdup_printf ("/%s", o->nodes[n]->path); + else + child_path = g_strdup_printf ("%s/%s", object_path, o->nodes[n]->path); + introspect_do (c, child_path, indent + 2, use_colors); + } + g_free (child_path); + } + else + { + dump_node (NULL, NULL, o->nodes[n], indent + 2, use_colors, NULL, recurse); + } + } + g_print ("%*s};\n", + indent, ""); + } + else + { + g_print ("\n"); + } +} + +static const GOptionEntry introspect_entries[] = +{ + { "dest", 'd', 0, G_OPTION_ARG_STRING, &opt_introspect_dest, N_("Destination name to introspect"), NULL}, + { "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_introspect_object_path, N_("Object path to introspect"), NULL}, + { "xml", 'x', 0, G_OPTION_ARG_NONE, &opt_introspect_xml, N_("Print XML"), NULL}, + { "recurse", 'r', 0, G_OPTION_ARG_NONE, &opt_introspect_recurse, N_("Introspect children"), NULL}, + { "only-properties", 'p', 0, G_OPTION_ARG_NONE, &opt_introspect_only_properties, N_("Only print properties"), NULL}, + G_OPTION_ENTRY_NULL +}; + +static gboolean +introspect_do (GDBusConnection *c, + const gchar *object_path, + guint indent, + gboolean use_colors) +{ + GError *error; + GVariant *result; + GDBusNodeInfo *node; + gboolean ret; + const gchar *xml_data; + + ret = FALSE; + node = NULL; + result = NULL; + + error = NULL; + result = g_dbus_connection_call_sync (c, + opt_introspect_dest, + object_path, + "org.freedesktop.DBus.Introspectable", + "Introspect", + NULL, + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + 3000, /* 3 sec */ + NULL, + &error); + if (result == NULL) + { + g_printerr (_("Error: %s\n"), error->message); + g_error_free (error); + goto out; + } + g_variant_get (result, "(&s)", &xml_data); + + if (opt_introspect_xml) + { + g_print ("%s", xml_data); + } + else + { + error = NULL; + node = g_dbus_node_info_new_for_xml (xml_data, &error); + if (node == NULL) + { + g_printerr (_("Error parsing introspection XML: %s\n"), error->message); + g_error_free (error); + goto out; + } + + dump_node (c, opt_introspect_dest, node, indent, use_colors, object_path, opt_introspect_recurse); + } + + ret = TRUE; + + out: + if (node != NULL) + g_dbus_node_info_unref (node); + if (result != NULL) + g_variant_unref (result); + return ret; +} + +static gboolean +handle_introspect (gint *argc, + gchar **argv[], + gboolean request_completion, + const gchar *completion_cur, + const gchar *completion_prev) +{ + gint ret; + GOptionContext *o; + gchar *s; + GError *error; + GDBusConnection *c; + gboolean complete_names; + gboolean complete_paths; + gboolean color_support; + + ret = FALSE; + c = NULL; + + modify_argv0_for_command (argc, argv, "introspect"); + + o = command_option_context_new (NULL, _("Introspect a remote object."), + introspect_entries, request_completion); + g_option_context_add_group (o, connection_get_group ()); + + complete_names = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--dest") == 0) + { + complete_names = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + complete_paths = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--object-path") == 0) + { + complete_paths = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + if (!g_option_context_parse (o, argc, argv, NULL)) + { + if (!request_completion) + { + s = g_option_context_get_help (o, FALSE, NULL); + g_printerr ("%s", s); + g_free (s); + goto out; + } + } + + error = NULL; + c = connection_get_dbus_connection (TRUE, &error); + if (c == NULL) + { + if (request_completion) + { + if (g_strcmp0 (completion_prev, "--address") == 0) + { + g_print ("unix:\n" + "tcp:\n" + "nonce-tcp:\n"); + } + else + { + g_print ("--system \n--session \n--address \n"); + } + } + else + { + g_printerr (_("Error connecting: %s\n"), error->message); + } + g_error_free (error); + goto out; + } + + if (complete_names) + { + print_names (c, FALSE); + goto out; + } + /* this only makes sense on message bus connections */ + if (opt_introspect_dest == NULL) + { + if (request_completion) + g_print ("--dest \n"); + else + g_printerr (_("Error: Destination is not specified\n")); + goto out; + } + if (request_completion && g_strcmp0 ("--dest", completion_prev) == 0) + { + print_names (c, g_str_has_prefix (opt_introspect_dest, ":")); + goto out; + } + + if (complete_paths) + { + print_paths (c, opt_introspect_dest, "/"); + goto out; + } + + if (!request_completion && !g_dbus_is_name (opt_introspect_dest)) + { + g_printerr (_("Error: %s is not a valid bus name\n"), opt_introspect_dest); + goto out; + } + + if (opt_introspect_object_path == NULL) + { + if (request_completion) + g_print ("--object-path \n"); + else + g_printerr (_("Error: Object path is not specified\n")); + goto out; + } + if (request_completion && g_strcmp0 ("--object-path", completion_prev) == 0) + { + gchar *p; + s = g_strdup (opt_introspect_object_path); + p = strrchr (s, '/'); + if (p != NULL) + { + if (p == s) + p++; + *p = '\0'; + } + print_paths (c, opt_introspect_dest, s); + g_free (s); + goto out; + } + if (!request_completion && !g_variant_is_object_path (opt_introspect_object_path)) + { + g_printerr (_("Error: %s is not a valid object path\n"), opt_introspect_object_path); + goto out; + } + + if (request_completion && opt_introspect_object_path != NULL && !opt_introspect_recurse) + { + g_print ("--recurse \n"); + } + + if (request_completion && opt_introspect_object_path != NULL && !opt_introspect_only_properties) + { + g_print ("--only-properties \n"); + } + + /* All done with completion now */ + if (request_completion) + goto out; + + /* Before we start printing the actual info, check if we can do colors*/ + color_support = g_log_writer_supports_color (fileno (stdout)); + + if (!introspect_do (c, opt_introspect_object_path, 0, color_support)) + goto out; + + ret = TRUE; + + out: + if (c != NULL) + g_object_unref (c); + g_option_context_free (o); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar *opt_monitor_dest = NULL; +static gchar *opt_monitor_object_path = NULL; + +static guint monitor_filter_id = 0; + +static void +monitor_signal_cb (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + gchar *s; + s = g_variant_print (parameters, TRUE); + g_print ("%s: %s.%s %s\n", + object_path, + interface_name, + signal_name, + s); + g_free (s); +} + +static void +monitor_on_name_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + g_print ("The name %s is owned by %s\n", name, name_owner); + g_assert (monitor_filter_id == 0); + monitor_filter_id = g_dbus_connection_signal_subscribe (connection, + name_owner, + NULL, /* any interface */ + NULL, /* any member */ + opt_monitor_object_path, + NULL, /* arg0 */ + G_DBUS_SIGNAL_FLAGS_NONE, + monitor_signal_cb, + NULL, /* user_data */ + NULL); /* user_data destroy notify */ +} + +static void +monitor_on_name_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_print ("The name %s does not have an owner\n", name); + + if (monitor_filter_id != 0) + { + g_dbus_connection_signal_unsubscribe (connection, monitor_filter_id); + monitor_filter_id = 0; + } +} + +static const GOptionEntry monitor_entries[] = +{ + { "dest", 'd', 0, G_OPTION_ARG_STRING, &opt_monitor_dest, N_("Destination name to monitor"), NULL}, + { "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_monitor_object_path, N_("Object path to monitor"), NULL}, + G_OPTION_ENTRY_NULL +}; + +static gboolean +handle_monitor (gint *argc, + gchar **argv[], + gboolean request_completion, + const gchar *completion_cur, + const gchar *completion_prev) +{ + gint ret; + GOptionContext *o; + gchar *s; + GError *error; + GDBusConnection *c; + gboolean complete_names; + gboolean complete_paths; + GMainLoop *loop; + + ret = FALSE; + c = NULL; + + modify_argv0_for_command (argc, argv, "monitor"); + + o = command_option_context_new (NULL, _("Monitor a remote object."), + monitor_entries, request_completion); + g_option_context_add_group (o, connection_get_group ()); + + complete_names = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--dest") == 0) + { + complete_names = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + complete_paths = FALSE; + if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--object-path") == 0) + { + complete_paths = TRUE; + remove_arg ((*argc) - 1, argc, argv); + } + + if (!g_option_context_parse (o, argc, argv, NULL)) + { + if (!request_completion) + { + s = g_option_context_get_help (o, FALSE, NULL); + g_printerr ("%s", s); + g_free (s); + goto out; + } + } + + error = NULL; + c = connection_get_dbus_connection (TRUE, &error); + if (c == NULL) + { + if (request_completion) + { + if (g_strcmp0 (completion_prev, "--address") == 0) + { + g_print ("unix:\n" + "tcp:\n" + "nonce-tcp:\n"); + } + else + { + g_print ("--system \n--session \n--address \n"); + } + } + else + { + g_printerr (_("Error connecting: %s\n"), error->message); + } + g_error_free (error); + goto out; + } + + /* Monitoring doesn’t make sense on a non-message-bus connection. */ + if (g_dbus_connection_get_unique_name (c) == NULL) + { + if (!request_completion) + g_printerr (_("Error: can’t monitor a non-message-bus connection\n")); + goto out; + } + + if (complete_names) + { + print_names (c, FALSE); + goto out; + } + /* this only makes sense on message bus connections */ + if (opt_monitor_dest == NULL) + { + if (request_completion) + g_print ("--dest \n"); + else + g_printerr (_("Error: Destination is not specified\n")); + goto out; + } + if (request_completion && g_strcmp0 ("--dest", completion_prev) == 0) + { + print_names (c, g_str_has_prefix (opt_monitor_dest, ":")); + goto out; + } + + if (!request_completion && !g_dbus_is_name (opt_monitor_dest)) + { + g_printerr (_("Error: %s is not a valid bus name\n"), opt_monitor_dest); + goto out; + } + + if (complete_paths) + { + print_paths (c, opt_monitor_dest, "/"); + goto out; + } + if (opt_monitor_object_path == NULL) + { + if (request_completion) + { + g_print ("--object-path \n"); + goto out; + } + /* it's fine to not have an object path */ + } + if (request_completion && g_strcmp0 ("--object-path", completion_prev) == 0) + { + gchar *p; + s = g_strdup (opt_monitor_object_path); + p = strrchr (s, '/'); + if (p != NULL) + { + if (p == s) + p++; + *p = '\0'; + } + print_paths (c, opt_monitor_dest, s); + g_free (s); + goto out; + } + if (!request_completion && (opt_monitor_object_path != NULL && !g_variant_is_object_path (opt_monitor_object_path))) + { + g_printerr (_("Error: %s is not a valid object path\n"), opt_monitor_object_path); + goto out; + } + + /* All done with completion now */ + if (request_completion) + goto out; + + if (opt_monitor_object_path != NULL) + g_print ("Monitoring signals on object %s owned by %s\n", opt_monitor_object_path, opt_monitor_dest); + else + g_print ("Monitoring signals from all objects owned by %s\n", opt_monitor_dest); + + loop = g_main_loop_new (NULL, FALSE); + g_bus_watch_name_on_connection (c, + opt_monitor_dest, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + monitor_on_name_appeared, + monitor_on_name_vanished, + NULL, + NULL); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + ret = TRUE; + + out: + if (c != NULL) + g_object_unref (c); + g_option_context_free (o); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean opt_wait_activate_set = FALSE; +static gchar *opt_wait_activate_name = NULL; +static gint64 opt_wait_timeout_secs = 0; /* no timeout */ + +typedef enum { + WAIT_STATE_RUNNING, /* waiting to see the service */ + WAIT_STATE_SUCCESS, /* seen it successfully */ + WAIT_STATE_TIMEOUT, /* timed out before seeing it */ +} WaitState; + +static gboolean +opt_wait_activate_cb (const gchar *option_name, + const gchar *value, + gpointer data, + GError **error) +{ + /* @value may be NULL */ + opt_wait_activate_set = TRUE; + opt_wait_activate_name = g_strdup (value); + + return TRUE; +} + +static const GOptionEntry wait_entries[] = +{ + { "activate", 'a', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + opt_wait_activate_cb, + N_("Service to activate before waiting for the other one (well-known name)"), + "[NAME]" }, + { "timeout", 't', 0, G_OPTION_ARG_INT64, &opt_wait_timeout_secs, + N_("Timeout to wait for before exiting with an error (seconds); 0 for " + "no timeout (default)"), "SECS" }, + G_OPTION_ENTRY_NULL +}; + +static void +wait_name_appeared_cb (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + WaitState *wait_state = user_data; + + *wait_state = WAIT_STATE_SUCCESS; +} + +static gboolean +wait_timeout_cb (gpointer user_data) +{ + WaitState *wait_state = user_data; + + *wait_state = WAIT_STATE_TIMEOUT; + + /* Removed in handle_wait(). */ + return G_SOURCE_CONTINUE; +} + +static gboolean +handle_wait (gint *argc, + gchar **argv[], + gboolean request_completion, + const gchar *completion_cur, + const gchar *completion_prev) +{ + gint ret; + GOptionContext *o; + gchar *s; + GError *error; + GDBusConnection *c; + guint watch_id, timer_id = 0, activate_watch_id; + const gchar *activate_service, *wait_service; + WaitState wait_state = WAIT_STATE_RUNNING; + + ret = FALSE; + c = NULL; + + modify_argv0_for_command (argc, argv, "wait"); + + o = command_option_context_new (_("[OPTION…] BUS-NAME"), + _("Wait for a bus name to appear."), + wait_entries, request_completion); + g_option_context_add_group (o, connection_get_group ()); + + if (!g_option_context_parse (o, argc, argv, NULL)) + { + if (!request_completion) + { + s = g_option_context_get_help (o, FALSE, NULL); + g_printerr ("%s", s); + g_free (s); + goto out; + } + } + + error = NULL; + c = connection_get_dbus_connection (TRUE, &error); + if (c == NULL) + { + if (request_completion) + { + if (g_strcmp0 (completion_prev, "--address") == 0) + { + g_print ("unix:\n" + "tcp:\n" + "nonce-tcp:\n"); + } + else + { + g_print ("--system \n--session \n--address \n"); + } + } + else + { + g_printerr (_("Error connecting: %s\n"), error->message); + } + g_error_free (error); + goto out; + } + + /* All done with completion now */ + if (request_completion) + goto out; + + /* + * Try and disentangle the command line arguments, with the aim of supporting: + * gdbus wait --session --activate ActivateName WaitName + * gdbus wait --session --activate ActivateAndWaitName + * gdbus wait --activate --session ActivateAndWaitName + * gdbus wait --session WaitName + */ + if (*argc == 2 && opt_wait_activate_set && opt_wait_activate_name != NULL) + { + activate_service = opt_wait_activate_name; + wait_service = (*argv)[1]; + } + else if (*argc == 2 && + opt_wait_activate_set && opt_wait_activate_name == NULL) + { + activate_service = (*argv)[1]; + wait_service = (*argv)[1]; + } + else if (*argc == 2 && !opt_wait_activate_set) + { + activate_service = NULL; /* disabled */ + wait_service = (*argv)[1]; + } + else if (*argc == 1 && + opt_wait_activate_set && opt_wait_activate_name != NULL) + { + activate_service = opt_wait_activate_name; + wait_service = opt_wait_activate_name; + } + else if (*argc == 1 && + opt_wait_activate_set && opt_wait_activate_name == NULL) + { + g_printerr (_("Error: A service to activate for must be specified.\n")); + goto out; + } + else if (*argc == 1 && !opt_wait_activate_set) + { + g_printerr (_("Error: A service to wait for must be specified.\n")); + goto out; + } + else /* if (*argc > 2) */ + { + g_printerr (_("Error: Too many arguments.\n")); + goto out; + } + + if (activate_service != NULL && + (!g_dbus_is_name (activate_service) || + g_dbus_is_unique_name (activate_service))) + { + g_printerr (_("Error: %s is not a valid well-known bus name.\n"), + activate_service); + goto out; + } + + if (!g_dbus_is_name (wait_service) || g_dbus_is_unique_name (wait_service)) + { + g_printerr (_("Error: %s is not a valid well-known bus name.\n"), + wait_service); + goto out; + } + + /* Start the prerequisite service if needed. */ + if (activate_service != NULL) + { + activate_watch_id = g_bus_watch_name_on_connection (c, activate_service, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + NULL, NULL, + NULL, NULL); + } + else + { + activate_watch_id = 0; + } + + /* Wait for the expected name to appear. */ + watch_id = g_bus_watch_name_on_connection (c, + wait_service, + G_BUS_NAME_WATCHER_FLAGS_NONE, + wait_name_appeared_cb, + NULL, &wait_state, NULL); + + /* Safety timeout. */ + if (opt_wait_timeout_secs > 0) + timer_id = g_timeout_add_seconds (opt_wait_timeout_secs, wait_timeout_cb, &wait_state); + + while (wait_state == WAIT_STATE_RUNNING) + g_main_context_iteration (NULL, TRUE); + + g_bus_unwatch_name (watch_id); + if (timer_id != 0) + g_source_remove (timer_id); + if (activate_watch_id != 0) + g_bus_unwatch_name (activate_watch_id); + + ret = (wait_state == WAIT_STATE_SUCCESS); + + out: + g_clear_object (&c); + g_option_context_free (o); + g_free (opt_wait_activate_name); + opt_wait_activate_name = NULL; + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +pick_word_at (const gchar *s, + gint cursor, + gint *out_word_begins_at) +{ + gint begin; + gint end; + + if (s[0] == '\0') + { + if (out_word_begins_at != NULL) + *out_word_begins_at = -1; + return NULL; + } + + if (g_ascii_isspace (s[cursor]) && ((cursor > 0 && g_ascii_isspace(s[cursor-1])) || cursor == 0)) + { + if (out_word_begins_at != NULL) + *out_word_begins_at = cursor; + return g_strdup (""); + } + + while (!g_ascii_isspace (s[cursor - 1]) && cursor > 0) + cursor--; + begin = cursor; + + end = begin; + while (!g_ascii_isspace (s[end]) && s[end] != '\0') + end++; + + if (out_word_begins_at != NULL) + *out_word_begins_at = begin; + + return g_strndup (s + begin, end - begin); +} + +gint +main (gint argc, gchar *argv[]) +{ + gint ret; + const gchar *command; + gboolean request_completion; + gchar *completion_cur; + gchar *completion_prev; +#ifdef G_OS_WIN32 + gchar *tmp; +#endif + + setlocale (LC_ALL, ""); + textdomain (GETTEXT_PACKAGE); + +#ifdef G_OS_WIN32 + tmp = _glib_get_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, tmp); + g_free (tmp); +#else + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#endif + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + + ret = 1; + completion_cur = NULL; + completion_prev = NULL; + + if (argc < 2) + { + usage (&argc, &argv, FALSE); + goto out; + } + + request_completion = FALSE; + + //completion_debug ("---- argc=%d --------------------------------------------------------", argc); + + again: + command = argv[1]; + if (g_strcmp0 (command, "help") == 0) + { + if (request_completion) + { + /* do nothing */ + } + else + { + usage (&argc, &argv, TRUE); + ret = 0; + } + goto out; + } + else if (g_strcmp0 (command, "emit") == 0) + { + if (handle_emit (&argc, + &argv, + request_completion, + completion_cur, + completion_prev)) + ret = 0; + goto out; + } + else if (g_strcmp0 (command, "call") == 0) + { + if (handle_call (&argc, + &argv, + request_completion, + completion_cur, + completion_prev)) + ret = 0; + goto out; + } + else if (g_strcmp0 (command, "introspect") == 0) + { + if (handle_introspect (&argc, + &argv, + request_completion, + completion_cur, + completion_prev)) + ret = 0; + goto out; + } + else if (g_strcmp0 (command, "monitor") == 0) + { + if (handle_monitor (&argc, + &argv, + request_completion, + completion_cur, + completion_prev)) + ret = 0; + goto out; + } + else if (g_strcmp0 (command, "wait") == 0) + { + if (handle_wait (&argc, + &argv, + request_completion, + completion_cur, + completion_prev)) + ret = 0; + goto out; + } +#ifdef G_OS_WIN32 + else if (g_strcmp0 (command, _GDBUS_ARG_WIN32_RUN_SESSION_BUS) == 0) + { + g_win32_run_session_bus (NULL, NULL, NULL, 0); + ret = 0; + goto out; + } +#endif + else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion) + { + const gchar *completion_line; + gchar **completion_argv; + gint completion_argc; + gint completion_point; + gchar *endp; + gint cur_begin; + + request_completion = TRUE; + + completion_line = argv[2]; + completion_point = strtol (argv[3], &endp, 10); + if (endp == argv[3] || *endp != '\0') + goto out; + +#if 0 + completion_debug ("completion_point=%d", completion_point); + completion_debug ("----"); + completion_debug (" 0123456789012345678901234567890123456789012345678901234567890123456789"); + completion_debug ("'%s'", completion_line); + completion_debug (" %*s^", + completion_point, ""); + completion_debug ("----"); +#endif + + if (!g_shell_parse_argv (completion_line, + &completion_argc, + &completion_argv, + NULL)) + { + /* it's very possible the command line can't be parsed (for + * example, missing quotes etc) - in that case, we just + * don't autocomplete at all + */ + goto out; + } + + /* compute cur and prev */ + completion_prev = NULL; + completion_cur = pick_word_at (completion_line, completion_point, &cur_begin); + if (cur_begin > 0) + { + gint prev_end; + for (prev_end = cur_begin - 1; prev_end >= 0; prev_end--) + { + if (!g_ascii_isspace (completion_line[prev_end])) + { + completion_prev = pick_word_at (completion_line, prev_end, NULL); + break; + } + } + } +#if 0 + completion_debug (" cur='%s'", completion_cur); + completion_debug ("prev='%s'", completion_prev); +#endif + + argc = completion_argc; + argv = completion_argv; + + ret = 0; + + goto again; + } + else + { + if (request_completion) + { + g_print ("help \nemit \ncall \nintrospect \nmonitor \nwait \n"); + ret = 0; + goto out; + } + else + { + g_printerr ("Unknown command '%s'\n", command); + usage (&argc, &argv, FALSE); + goto out; + } + } + + out: + g_free (completion_cur); + g_free (completion_prev); + return ret; +} diff --git a/gio/gdbusactiongroup-private.h b/gio/gdbusactiongroup-private.h new file mode 100644 index 0000000..b46df22 --- /dev/null +++ b/gio/gdbusactiongroup-private.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_DBUS_ACTION_GROUP_PRIVATE_H__ +#define __G_DBUS_ACTION_GROUP_PRIVATE_H__ + +#include "gdbusactiongroup.h" + +G_BEGIN_DECLS + +gboolean +g_dbus_action_group_sync (GDBusActionGroup *group, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif diff --git a/gio/gdbusactiongroup.c b/gio/gdbusactiongroup.c new file mode 100644 index 0000000..894b482 --- /dev/null +++ b/gio/gdbusactiongroup.c @@ -0,0 +1,550 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gdbusactiongroup-private.h" + +#include "gremoteactiongroup.h" +#include "gdbusconnection.h" +#include "gactiongroup.h" + +/** + * SECTION:gdbusactiongroup + * @title: GDBusActionGroup + * @short_description: A D-Bus GActionGroup implementation + * @include: gio/gio.h + * @see_also: [GActionGroup exporter][gio-GActionGroup-exporter] + * + * #GDBusActionGroup is an implementation of the #GActionGroup + * interface that can be used as a proxy for an action group + * that is exported over D-Bus with g_dbus_connection_export_action_group(). + */ + +/** + * GDBusActionGroup: + * + * #GDBusActionGroup is an opaque data structure and can only be accessed + * using the following functions. + */ + +struct _GDBusActionGroup +{ + GObject parent_instance; + + GDBusConnection *connection; + gchar *bus_name; + gchar *object_path; + guint subscription_id; + GHashTable *actions; + + /* The 'strict' flag indicates that the non-existence of at least one + * action has potentially been observed through the API. This means + * that we should always emit 'action-added' signals for all new + * actions. + * + * The user can observe the non-existence of an action by listing the + * actions or by performing a query (such as parameter type) on a + * non-existent action. + * + * If the user has no way of knowing that a given action didn't + * already exist then we can skip emitting 'action-added' signals + * since they have no way of knowing that it wasn't there from the + * start. + */ + gboolean strict; +}; + +typedef GObjectClass GDBusActionGroupClass; + +typedef struct +{ + gchar *name; + GVariantType *parameter_type; + gboolean enabled; + GVariant *state; +} ActionInfo; + +static void +action_info_free (gpointer user_data) +{ + ActionInfo *info = user_data; + + g_free (info->name); + + if (info->state) + g_variant_unref (info->state); + + if (info->parameter_type) + g_variant_type_free (info->parameter_type); + + g_slice_free (ActionInfo, info); +} + +static ActionInfo * +action_info_new_from_iter (GVariantIter *iter) +{ + const gchar *param_str; + ActionInfo *info; + gboolean enabled; + GVariant *state; + gchar *name; + + if (!g_variant_iter_next (iter, "{s(b&g@av)}", &name, + &enabled, ¶m_str, &state)) + return NULL; + + info = g_slice_new (ActionInfo); + info->name = name; + info->enabled = enabled; + + if (g_variant_n_children (state)) + g_variant_get_child (state, 0, "v", &info->state); + else + info->state = NULL; + g_variant_unref (state); + + if (param_str[0]) + info->parameter_type = g_variant_type_copy ((GVariantType *) param_str); + else + info->parameter_type = NULL; + + return info; +} + +static void g_dbus_action_group_remote_iface_init (GRemoteActionGroupInterface *iface); +static void g_dbus_action_group_iface_init (GActionGroupInterface *iface); +G_DEFINE_TYPE_WITH_CODE (GDBusActionGroup, g_dbus_action_group, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_dbus_action_group_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_REMOTE_ACTION_GROUP, g_dbus_action_group_remote_iface_init)) + +static void +g_dbus_action_group_changed (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GDBusActionGroup *group = user_data; + GActionGroup *g_group = user_data; + + /* make sure that we've been fully initialised */ + if (group->actions == NULL) + return; + + if (g_str_equal (signal_name, "Changed") && + g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(asa{sb}a{sv}a{s(bgav)})"))) + { + /* Removes */ + { + GVariantIter *iter; + const gchar *name; + + g_variant_get_child (parameters, 0, "as", &iter); + while (g_variant_iter_next (iter, "&s", &name)) + { + if (g_hash_table_lookup (group->actions, name)) + { + g_hash_table_remove (group->actions, name); + g_action_group_action_removed (g_group, name); + } + } + g_variant_iter_free (iter); + } + + /* Enable changes */ + { + GVariantIter *iter; + const gchar *name; + gboolean enabled; + + g_variant_get_child (parameters, 1, "a{sb}", &iter); + while (g_variant_iter_next (iter, "{&sb}", &name, &enabled)) + { + ActionInfo *info; + + info = g_hash_table_lookup (group->actions, name); + + if (info && info->enabled != enabled) + { + info->enabled = enabled; + g_action_group_action_enabled_changed (g_group, name, enabled); + } + } + g_variant_iter_free (iter); + } + + /* State changes */ + { + GVariantIter *iter; + const gchar *name; + GVariant *state; + + g_variant_get_child (parameters, 2, "a{sv}", &iter); + while (g_variant_iter_next (iter, "{&sv}", &name, &state)) + { + ActionInfo *info; + + info = g_hash_table_lookup (group->actions, name); + + if (info && info->state && !g_variant_equal (state, info->state) && + g_variant_is_of_type (state, g_variant_get_type (info->state))) + { + g_variant_unref (info->state); + info->state = g_variant_ref (state); + + g_action_group_action_state_changed (g_group, name, state); + } + + g_variant_unref (state); + } + g_variant_iter_free (iter); + } + + /* Additions */ + { + GVariantIter *iter; + ActionInfo *info; + + g_variant_get_child (parameters, 3, "a{s(bgav)}", &iter); + while ((info = action_info_new_from_iter (iter))) + { + if (!g_hash_table_lookup (group->actions, info->name)) + { + g_hash_table_insert (group->actions, info->name, info); + + if (group->strict) + g_action_group_action_added (g_group, info->name); + } + else + action_info_free (info); + } + g_variant_iter_free (iter); + } + } +} + + +static void +g_dbus_action_group_describe_all_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GDBusActionGroup *group= user_data; + GVariant *reply; + + g_assert (group->actions == NULL); + group->actions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, action_info_free); + + g_assert (group->connection == (gpointer) source); + reply = g_dbus_connection_call_finish (group->connection, result, NULL); + + if (reply != NULL) + { + GVariantIter *iter; + ActionInfo *action; + + g_variant_get (reply, "(a{s(bgav)})", &iter); + while ((action = action_info_new_from_iter (iter))) + { + g_hash_table_insert (group->actions, action->name, action); + + if (group->strict) + g_action_group_action_added (G_ACTION_GROUP (group), action->name); + } + g_variant_iter_free (iter); + g_variant_unref (reply); + } + + g_object_unref (group); +} + + +static void +g_dbus_action_group_async_init (GDBusActionGroup *group) +{ + if (group->subscription_id != 0) + return; + + group->subscription_id = + g_dbus_connection_signal_subscribe (group->connection, group->bus_name, "org.gtk.Actions", "Changed", group->object_path, + NULL, G_DBUS_SIGNAL_FLAGS_NONE, g_dbus_action_group_changed, group, NULL); + + g_dbus_connection_call (group->connection, group->bus_name, group->object_path, "org.gtk.Actions", "DescribeAll", NULL, + G_VARIANT_TYPE ("(a{s(bgav)})"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, + g_dbus_action_group_describe_all_done, g_object_ref (group)); +} + +static gchar ** +g_dbus_action_group_list_actions (GActionGroup *g_group) +{ + GDBusActionGroup *group = G_DBUS_ACTION_GROUP (g_group); + gchar **keys; + + if (group->actions != NULL) + { + GHashTableIter iter; + gint n, i = 0; + gpointer key; + + n = g_hash_table_size (group->actions); + keys = g_new (gchar *, n + 1); + + g_hash_table_iter_init (&iter, group->actions); + while (g_hash_table_iter_next (&iter, &key, NULL)) + keys[i++] = g_strdup (key); + g_assert_cmpint (i, ==, n); + keys[n] = NULL; + } + else + { + g_dbus_action_group_async_init (group); + keys = g_new0 (gchar *, 1); + } + + group->strict = TRUE; + + return keys; +} + +static gboolean +g_dbus_action_group_query_action (GActionGroup *g_group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state) +{ + GDBusActionGroup *group = G_DBUS_ACTION_GROUP (g_group); + ActionInfo *info; + + if (group->actions != NULL) + { + info = g_hash_table_lookup (group->actions, action_name); + + if (info == NULL) + { + group->strict = TRUE; + return FALSE; + } + + if (enabled) + *enabled = info->enabled; + + if (parameter_type) + *parameter_type = info->parameter_type; + + if (state_type) + *state_type = info->state ? g_variant_get_type (info->state) : NULL; + + if (state_hint) + *state_hint = NULL; + + if (state) + *state = info->state ? g_variant_ref (info->state) : NULL; + + return TRUE; + } + else + { + g_dbus_action_group_async_init (group); + group->strict = TRUE; + + return FALSE; + } +} + +static void +g_dbus_action_group_activate_action_full (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *parameter, + GVariant *platform_data) +{ + GDBusActionGroup *group = G_DBUS_ACTION_GROUP (remote); + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); + + if (parameter) + g_variant_builder_add (&builder, "v", parameter); + + g_dbus_connection_call (group->connection, group->bus_name, group->object_path, "org.gtk.Actions", "Activate", + g_variant_new ("(sav@a{sv})", action_name, &builder, platform_data), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +g_dbus_action_group_change_action_state_full (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *value, + GVariant *platform_data) +{ + GDBusActionGroup *group = G_DBUS_ACTION_GROUP (remote); + + g_dbus_connection_call (group->connection, group->bus_name, group->object_path, "org.gtk.Actions", "SetState", + g_variant_new ("(sv@a{sv})", action_name, value, platform_data), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +g_dbus_action_group_change_state (GActionGroup *group, + const gchar *action_name, + GVariant *value) +{ + g_dbus_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (group), + action_name, value, g_variant_new ("a{sv}", NULL)); +} + +static void +g_dbus_action_group_activate (GActionGroup *group, + const gchar *action_name, + GVariant *parameter) +{ + g_dbus_action_group_activate_action_full (G_REMOTE_ACTION_GROUP (group), + action_name, parameter, g_variant_new ("a{sv}", NULL)); +} + +static void +g_dbus_action_group_finalize (GObject *object) +{ + GDBusActionGroup *group = G_DBUS_ACTION_GROUP (object); + + if (group->subscription_id) + g_dbus_connection_signal_unsubscribe (group->connection, group->subscription_id); + + if (group->actions) + g_hash_table_unref (group->actions); + + g_object_unref (group->connection); + g_free (group->object_path); + g_free (group->bus_name); + + G_OBJECT_CLASS (g_dbus_action_group_parent_class) + ->finalize (object); +} + +static void +g_dbus_action_group_init (GDBusActionGroup *group) +{ +} + +static void +g_dbus_action_group_class_init (GDBusActionGroupClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_dbus_action_group_finalize; +} + +static void +g_dbus_action_group_remote_iface_init (GRemoteActionGroupInterface *iface) +{ + iface->activate_action_full = g_dbus_action_group_activate_action_full; + iface->change_action_state_full = g_dbus_action_group_change_action_state_full; +} + +static void +g_dbus_action_group_iface_init (GActionGroupInterface *iface) +{ + iface->list_actions = g_dbus_action_group_list_actions; + iface->query_action = g_dbus_action_group_query_action; + iface->change_action_state = g_dbus_action_group_change_state; + iface->activate_action = g_dbus_action_group_activate; +} + +/** + * g_dbus_action_group_get: + * @connection: A #GDBusConnection + * @bus_name: (nullable): the bus name which exports the action + * group or %NULL if @connection is not a message bus connection + * @object_path: the object path at which the action group is exported + * + * Obtains a #GDBusActionGroup for the action group which is exported at + * the given @bus_name and @object_path. + * + * The thread default main context is taken at the time of this call. + * All signals on the menu model (and any linked models) are reported + * with respect to this context. All calls on the returned menu model + * (and linked models) must also originate from this same context, with + * the thread default main context unchanged. + * + * This call is non-blocking. The returned action group may or may not + * already be filled in. The correct thing to do is connect the signals + * for the action group to monitor for changes and then to call + * g_action_group_list_actions() to get the initial list. + * + * Returns: (transfer full): a #GDBusActionGroup + * + * Since: 2.32 + */ +GDBusActionGroup * +g_dbus_action_group_get (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path) +{ + GDBusActionGroup *group; + + g_return_val_if_fail (bus_name != NULL || g_dbus_connection_get_unique_name (connection) == NULL, NULL); + + group = g_object_new (G_TYPE_DBUS_ACTION_GROUP, NULL); + group->connection = g_object_ref (connection); + group->bus_name = g_strdup (bus_name); + group->object_path = g_strdup (object_path); + + return group; +} + +gboolean +g_dbus_action_group_sync (GDBusActionGroup *group, + GCancellable *cancellable, + GError **error) +{ + GVariant *reply; + + g_assert (group->subscription_id == 0); + + group->subscription_id = + g_dbus_connection_signal_subscribe (group->connection, group->bus_name, "org.gtk.Actions", "Changed", group->object_path, + NULL, G_DBUS_SIGNAL_FLAGS_NONE, g_dbus_action_group_changed, group, NULL); + + reply = g_dbus_connection_call_sync (group->connection, group->bus_name, group->object_path, "org.gtk.Actions", + "DescribeAll", NULL, G_VARIANT_TYPE ("(a{s(bgav)})"), + G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); + + if (reply != NULL) + { + GVariantIter *iter; + ActionInfo *action; + + g_assert (group->actions == NULL); + group->actions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, action_info_free); + + g_variant_get (reply, "(a{s(bgav)})", &iter); + while ((action = action_info_new_from_iter (iter))) + g_hash_table_insert (group->actions, action->name, action); + g_variant_iter_free (iter); + g_variant_unref (reply); + } + + return reply != NULL; +} diff --git a/gio/gdbusactiongroup.h b/gio/gdbusactiongroup.h new file mode 100644 index 0000000..93e6a2c --- /dev/null +++ b/gio/gdbusactiongroup.h @@ -0,0 +1,54 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_DBUS_ACTION_GROUP_H__ +#define __G_DBUS_ACTION_GROUP_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include "giotypes.h" + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_ACTION_GROUP (g_dbus_action_group_get_type ()) +#define G_DBUS_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_DBUS_ACTION_GROUP, GDBusActionGroup)) +#define G_DBUS_ACTION_GROUP_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_DBUS_ACTION_GROUP, GDBusActionGroupClass)) +#define G_IS_DBUS_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_DBUS_ACTION_GROUP)) +#define G_IS_DBUS_ACTION_GROUP_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_DBUS_ACTION_GROUP)) +#define G_DBUS_ACTION_GROUP_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_DBUS_ACTION_GROUP, GDBusActionGroupClass)) + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_action_group_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +GDBusActionGroup * g_dbus_action_group_get (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path); + +G_END_DECLS + +#endif /* __G_DBUS_ACTION_GROUP_H__ */ diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c new file mode 100644 index 0000000..48fdef2 --- /dev/null +++ b/gio/gdbusaddress.c @@ -0,0 +1,1467 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "gioerror.h" +#include "gdbusutils.h" +#include "gdbusaddress.h" +#include "gdbuserror.h" +#include "gioenumtypes.h" +#include "glib-private.h" +#include "gnetworkaddress.h" +#include "gsocketclient.h" +#include "giostream.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "glib-private.h" +#include "gdbusprivate.h" +#include "gstdio.h" + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +#ifdef G_OS_WIN32 +#include +#endif + +#include "glibintl.h" + +/** + * SECTION:gdbusaddress + * @title: D-Bus Addresses + * @short_description: D-Bus connection endpoints + * @include: gio/gio.h + * + * Routines for working with D-Bus addresses. A D-Bus address is a string + * like `unix:tmpdir=/tmp/my-app-name`. The exact format of addresses + * is explained in detail in the + * [D-Bus specification](http://dbus.freedesktop.org/doc/dbus-specification.html#addresses). + * + * TCP D-Bus connections are supported, but accessing them via a proxy is + * currently not supported. + * + * Since GLib 2.72, `unix:` addresses are supported on Windows with `AF_UNIX` + * support (Windows 10). + */ + +static gchar *get_session_address_platform_specific (GError **error); +static gchar *get_session_address_dbus_launch (GError **error); + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_is_address: + * @string: A string. + * + * Checks if @string is a + * [D-Bus address](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). + * + * This doesn't check if @string is actually supported by #GDBusServer + * or #GDBusConnection - use g_dbus_is_supported_address() to do more + * checks. + * + * Returns: %TRUE if @string is a valid D-Bus address, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_is_address (const gchar *string) +{ + guint n; + gchar **a; + gboolean ret; + + ret = FALSE; + + g_return_val_if_fail (string != NULL, FALSE); + + a = g_strsplit (string, ";", 0); + if (a[0] == NULL) + goto out; + + for (n = 0; a[n] != NULL; n++) + { + if (!_g_dbus_address_parse_entry (a[n], + NULL, + NULL, + NULL)) + goto out; + } + + ret = TRUE; + + out: + g_strfreev (a); + return ret; +} + +static gboolean +is_valid_unix (const gchar *address_entry, + GHashTable *key_value_pairs, + GError **error) +{ + gboolean ret; + GList *keys; + GList *l; + const gchar *path; + const gchar *dir; + const gchar *tmpdir; + const gchar *abstract; + + ret = FALSE; + keys = NULL; + path = NULL; + dir = NULL; + tmpdir = NULL; + abstract = NULL; + + keys = g_hash_table_get_keys (key_value_pairs); + for (l = keys; l != NULL; l = l->next) + { + const gchar *key = l->data; + if (g_strcmp0 (key, "path") == 0) + path = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "dir") == 0) + dir = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "tmpdir") == 0) + tmpdir = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "abstract") == 0) + abstract = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "guid") != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Unsupported key “%s†in address entry “%sâ€"), + key, + address_entry); + goto out; + } + } + + /* Exactly one key must be set */ + if ((path != NULL) + (dir != NULL) + (tmpdir != NULL) + (abstract != NULL) > 1) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Meaningless key/value pair combination in address entry “%sâ€"), + address_entry); + goto out; + } + else if (path == NULL && dir == NULL && tmpdir == NULL && abstract == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract keys)"), + address_entry); + goto out; + } + + ret = TRUE; + + out: + g_list_free (keys); + + return ret; +} + +static gboolean +is_valid_nonce_tcp (const gchar *address_entry, + GHashTable *key_value_pairs, + GError **error) +{ + gboolean ret; + GList *keys; + GList *l; + const gchar *host; + const gchar *port; + const gchar *family; + const gchar *nonce_file; + gint port_num; + gchar *endp; + + ret = FALSE; + keys = NULL; + host = NULL; + port = NULL; + family = NULL; + nonce_file = NULL; + + keys = g_hash_table_get_keys (key_value_pairs); + for (l = keys; l != NULL; l = l->next) + { + const gchar *key = l->data; + if (g_strcmp0 (key, "host") == 0) + host = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "port") == 0) + port = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "family") == 0) + family = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "noncefile") == 0) + nonce_file = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "guid") != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Unsupported key “%s†in address entry “%sâ€"), + key, + address_entry); + goto out; + } + } + + if (port != NULL) + { + port_num = strtol (port, &endp, 10); + if ((*port == '\0' || *endp != '\0') || port_num < 0 || port_num >= 65536) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the “%s†attribute is malformed"), + address_entry, "port"); + goto out; + } + } + + if (family != NULL && !(g_strcmp0 (family, "ipv4") == 0 || g_strcmp0 (family, "ipv6") == 0)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the “%s†attribute is malformed"), + address_entry, "family"); + goto out; + } + + if (host != NULL) + { + /* TODO: validate host */ + } + + if (nonce_file != NULL && *nonce_file == '\0') + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the “%s†attribute is malformed"), + address_entry, "noncefile"); + goto out; + } + + ret = TRUE; + + out: + g_list_free (keys); + + return ret; +} + +static gboolean +is_valid_tcp (const gchar *address_entry, + GHashTable *key_value_pairs, + GError **error) +{ + gboolean ret; + GList *keys; + GList *l; + const gchar *host; + const gchar *port; + const gchar *family; + gint port_num; + gchar *endp; + + ret = FALSE; + keys = NULL; + host = NULL; + port = NULL; + family = NULL; + + keys = g_hash_table_get_keys (key_value_pairs); + for (l = keys; l != NULL; l = l->next) + { + const gchar *key = l->data; + if (g_strcmp0 (key, "host") == 0) + host = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "port") == 0) + port = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "family") == 0) + family = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "guid") != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Unsupported key “%s†in address entry “%sâ€"), + key, + address_entry); + goto out; + } + } + + if (port != NULL) + { + port_num = strtol (port, &endp, 10); + if ((*port == '\0' || *endp != '\0') || port_num < 0 || port_num >= 65536) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the “%s†attribute is malformed"), + address_entry, "port"); + goto out; + } + } + + if (family != NULL && !(g_strcmp0 (family, "ipv4") == 0 || g_strcmp0 (family, "ipv6") == 0)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the “%s†attribute is malformed"), + address_entry, "family"); + goto out; + } + + if (host != NULL) + { + /* TODO: validate host */ + } + + ret= TRUE; + + out: + g_list_free (keys); + + return ret; +} + +/** + * g_dbus_is_supported_address: + * @string: A string. + * @error: Return location for error or %NULL. + * + * Like g_dbus_is_address() but also checks if the library supports the + * transports in @string and that key/value pairs for each transport + * are valid. See the specification of the + * [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). + * + * Returns: %TRUE if @string is a valid D-Bus address that is + * supported by this library, %FALSE if @error is set. + * + * Since: 2.26 + */ +gboolean +g_dbus_is_supported_address (const gchar *string, + GError **error) +{ + guint n; + gchar **a; + gboolean ret; + + ret = FALSE; + + g_return_val_if_fail (string != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + a = g_strsplit (string, ";", 0); + for (n = 0; a[n] != NULL; n++) + { + gchar *transport_name; + GHashTable *key_value_pairs; + gboolean supported; + + if (!_g_dbus_address_parse_entry (a[n], + &transport_name, + &key_value_pairs, + error)) + goto out; + + supported = FALSE; + if (g_strcmp0 (transport_name, "unix") == 0) + supported = is_valid_unix (a[n], key_value_pairs, error); + else if (g_strcmp0 (transport_name, "tcp") == 0) + supported = is_valid_tcp (a[n], key_value_pairs, error); + else if (g_strcmp0 (transport_name, "nonce-tcp") == 0) + supported = is_valid_nonce_tcp (a[n], key_value_pairs, error); + else if (g_strcmp0 (a[n], "autolaunch:") == 0) + supported = TRUE; + else + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Unknown or unsupported transport “%s†for address “%sâ€"), + transport_name, a[n]); + + g_free (transport_name); + g_hash_table_unref (key_value_pairs); + + if (!supported) + goto out; + } + + ret = TRUE; + + out: + g_strfreev (a); + + g_assert (ret || (!ret && (error == NULL || *error != NULL))); + + return ret; +} + +gboolean +_g_dbus_address_parse_entry (const gchar *address_entry, + gchar **out_transport_name, + GHashTable **out_key_value_pairs, + GError **error) +{ + gboolean ret; + GHashTable *key_value_pairs; + gchar *transport_name; + gchar **kv_pairs; + const gchar *s; + guint n; + + ret = FALSE; + kv_pairs = NULL; + transport_name = NULL; + key_value_pairs = NULL; + + s = strchr (address_entry, ':'); + if (s == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Address element “%s†does not contain a colon (:)"), + address_entry); + goto out; + } + else if (s == address_entry) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Transport name in address element “%s†must not be empty"), + address_entry); + goto out; + } + + transport_name = g_strndup (address_entry, s - address_entry); + key_value_pairs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + kv_pairs = g_strsplit (s + 1, ",", 0); + for (n = 0; kv_pairs[n] != NULL; n++) + { + const gchar *kv_pair = kv_pairs[n]; + gchar *key; + gchar *value; + + s = strchr (kv_pair, '='); + if (s == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal sign"), + n, + kv_pair, + address_entry); + goto out; + } + else if (s == kv_pair) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key"), + n, + kv_pair, + address_entry); + goto out; + } + + key = g_uri_unescape_segment (kv_pair, s, NULL); + value = g_uri_unescape_segment (s + 1, kv_pair + strlen (kv_pair), NULL); + if (key == NULL || value == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element “%sâ€"), + n, + kv_pair, + address_entry); + g_free (key); + g_free (value); + goto out; + } + g_hash_table_insert (key_value_pairs, key, value); + } + + ret = TRUE; + +out: + if (ret) + { + if (out_transport_name != NULL) + *out_transport_name = g_steal_pointer (&transport_name); + if (out_key_value_pairs != NULL) + *out_key_value_pairs = g_steal_pointer (&key_value_pairs); + } + + g_clear_pointer (&key_value_pairs, g_hash_table_unref); + g_free (transport_name); + g_strfreev (kv_pairs); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GIOStream * +g_dbus_address_try_connect_one (const gchar *address_entry, + gchar **out_guid, + GCancellable *cancellable, + GError **error); + +/* TODO: Declare an extension point called GDBusTransport (or similar) + * and move code below to extensions implementing said extension + * point. That way we can implement a D-Bus transport over X11 without + * making libgio link to libX11... + */ +static GIOStream * +g_dbus_address_connect (const gchar *address_entry, + const gchar *transport_name, + GHashTable *key_value_pairs, + GCancellable *cancellable, + GError **error) +{ + GIOStream *ret; + GSocketConnectable *connectable; + const gchar *nonce_file; + + connectable = NULL; + ret = NULL; + nonce_file = NULL; + + if (g_strcmp0 (transport_name, "unix") == 0) + { + const gchar *path; + const gchar *abstract; + path = g_hash_table_lookup (key_value_pairs, "path"); + abstract = g_hash_table_lookup (key_value_pairs, "abstract"); + if ((path == NULL && abstract == NULL) || (path != NULL && abstract != NULL)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the unix transport requires exactly one of the " + "keys “path†or “abstract†to be set"), + address_entry); + } + else if (path != NULL) + { + connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (path)); + } + else if (abstract != NULL) + { + connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new_with_type (abstract, + -1, + G_UNIX_SOCKET_ADDRESS_ABSTRACT)); + } + else + { + g_assert_not_reached (); + } + } + else if (g_strcmp0 (transport_name, "tcp") == 0 || g_strcmp0 (transport_name, "nonce-tcp") == 0) + { + const gchar *s; + const gchar *host; + glong port; + gchar *endp; + gboolean is_nonce; + + is_nonce = (g_strcmp0 (transport_name, "nonce-tcp") == 0); + + host = g_hash_table_lookup (key_value_pairs, "host"); + if (host == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the host attribute is missing or malformed"), + address_entry); + goto out; + } + + s = g_hash_table_lookup (key_value_pairs, "port"); + if (s == NULL) + s = "0"; + port = strtol (s, &endp, 10); + if ((*s == '\0' || *endp != '\0') || port < 0 || port >= 65536) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the port attribute is missing or malformed"), + address_entry); + goto out; + } + + + if (is_nonce) + { + nonce_file = g_hash_table_lookup (key_value_pairs, "noncefile"); + if (nonce_file == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error in address “%s†— the noncefile attribute is missing or malformed"), + address_entry); + goto out; + } + } + + /* TODO: deal with family key/value-pair */ + connectable = g_network_address_new (host, port); + } + else if (g_strcmp0 (address_entry, "autolaunch:") == 0) + { + gchar *autolaunch_address; + autolaunch_address = get_session_address_dbus_launch (error); + if (autolaunch_address != NULL) + { + ret = g_dbus_address_try_connect_one (autolaunch_address, NULL, cancellable, error); + g_free (autolaunch_address); + goto out; + } + else + { + g_prefix_error (error, _("Error auto-launching: ")); + } + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Unknown or unsupported transport “%s†for address “%sâ€"), + transport_name, + address_entry); + } + + if (connectable != NULL) + { + GSocketClient *client; + GSocketConnection *connection; + + g_assert (ret == NULL); + client = g_socket_client_new (); + + /* Disable proxy support to prevent a deadlock on startup, since loading a + * proxy resolver causes the GIO modules to be loaded, and there will + * almost certainly be one of them which then tries to use GDBus. + * See: https://bugzilla.gnome.org/show_bug.cgi?id=792499 */ + g_socket_client_set_enable_proxy (client, FALSE); + + connection = g_socket_client_connect (client, + connectable, + cancellable, + error); + g_object_unref (connectable); + g_object_unref (client); + if (connection == NULL) + goto out; + + ret = G_IO_STREAM (connection); + + if (nonce_file != NULL) + { + gchar nonce_contents[16 + 1]; + size_t num_bytes_read; + FILE *f; + int errsv; + + /* be careful to read only 16 bytes - we also check that the file is only 16 bytes long */ + f = fopen (nonce_file, "rb"); + errsv = errno; + if (f == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error opening nonce file “%sâ€: %s"), + nonce_file, + g_strerror (errsv)); + g_object_unref (ret); + ret = NULL; + goto out; + } + num_bytes_read = fread (nonce_contents, + sizeof (gchar), + 16 + 1, + f); + errsv = errno; + if (num_bytes_read != 16) + { + if (num_bytes_read == 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error reading from nonce file “%sâ€: %s"), + nonce_file, + g_strerror (errsv)); + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error reading from nonce file “%sâ€, expected 16 bytes, got %d"), + nonce_file, + (gint) num_bytes_read); + } + g_object_unref (ret); + ret = NULL; + fclose (f); + goto out; + } + fclose (f); + + if (!g_output_stream_write_all (g_io_stream_get_output_stream (ret), + nonce_contents, + 16, + NULL, + cancellable, + error)) + { + g_prefix_error (error, _("Error writing contents of nonce file “%s†to stream:"), nonce_file); + g_object_unref (ret); + ret = NULL; + goto out; + } + } + } + + out: + + return ret; +} + +static GIOStream * +g_dbus_address_try_connect_one (const gchar *address_entry, + gchar **out_guid, + GCancellable *cancellable, + GError **error) +{ + GIOStream *ret; + GHashTable *key_value_pairs; + gchar *transport_name; + const gchar *guid; + + ret = NULL; + transport_name = NULL; + key_value_pairs = NULL; + + if (!_g_dbus_address_parse_entry (address_entry, + &transport_name, + &key_value_pairs, + error)) + goto out; + + ret = g_dbus_address_connect (address_entry, + transport_name, + key_value_pairs, + cancellable, + error); + if (ret == NULL) + goto out; + + guid = g_hash_table_lookup (key_value_pairs, "guid"); + if (guid != NULL && out_guid != NULL) + *out_guid = g_strdup (guid); + +out: + g_free (transport_name); + if (key_value_pairs != NULL) + g_hash_table_unref (key_value_pairs); + return ret; +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + gchar *address; + gchar *guid; +} GetStreamData; + +static void +get_stream_data_free (GetStreamData *data) +{ + g_free (data->address); + g_free (data->guid); + g_free (data); +} + +static void +get_stream_thread_func (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GetStreamData *data = task_data; + GIOStream *stream; + GError *error = NULL; + + stream = g_dbus_address_get_stream_sync (data->address, + &data->guid, + cancellable, + &error); + if (stream) + g_task_return_pointer (task, stream, g_object_unref); + else + g_task_return_error (task, error); +} + +/** + * g_dbus_address_get_stream: + * @address: A valid D-Bus address. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied. + * @user_data: Data to pass to @callback. + * + * Asynchronously connects to an endpoint specified by @address and + * sets up the connection so it is in a state to run the client-side + * of the D-Bus authentication conversation. @address must be in the + * [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). + * + * When the operation is finished, @callback will be invoked. You can + * then call g_dbus_address_get_stream_finish() to get the result of + * the operation. + * + * This is an asynchronous failable function. See + * g_dbus_address_get_stream_sync() for the synchronous version. + * + * Since: 2.26 + */ +void +g_dbus_address_get_stream (const gchar *address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + GetStreamData *data; + + g_return_if_fail (address != NULL); + + data = g_new0 (GetStreamData, 1); + data->address = g_strdup (address); + + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (task, g_dbus_address_get_stream); + g_task_set_task_data (task, data, (GDestroyNotify) get_stream_data_free); + g_task_run_in_thread (task, get_stream_thread_func); + g_object_unref (task); +} + +/** + * g_dbus_address_get_stream_finish: + * @res: A #GAsyncResult obtained from the GAsyncReadyCallback passed to g_dbus_address_get_stream(). + * @out_guid: (optional) (out) (nullable): %NULL or return location to store the GUID extracted from @address, if any. + * @error: Return location for error or %NULL. + * + * Finishes an operation started with g_dbus_address_get_stream(). + * + * A server is not required to set a GUID, so @out_guid may be set to %NULL + * even on success. + * + * Returns: (transfer full): A #GIOStream or %NULL if @error is set. + * + * Since: 2.26 + */ +GIOStream * +g_dbus_address_get_stream_finish (GAsyncResult *res, + gchar **out_guid, + GError **error) +{ + GTask *task; + GetStreamData *data; + GIOStream *ret; + + g_return_val_if_fail (g_task_is_valid (res, NULL), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + task = G_TASK (res); + ret = g_task_propagate_pointer (task, error); + + if (ret != NULL && out_guid != NULL) + { + data = g_task_get_task_data (task); + *out_guid = data->guid; + data->guid = NULL; + } + + return ret; +} + +/** + * g_dbus_address_get_stream_sync: + * @address: A valid D-Bus address. + * @out_guid: (optional) (out) (nullable): %NULL or return location to store the GUID extracted from @address, if any. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Synchronously connects to an endpoint specified by @address and + * sets up the connection so it is in a state to run the client-side + * of the D-Bus authentication conversation. @address must be in the + * [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). + * + * A server is not required to set a GUID, so @out_guid may be set to %NULL + * even on success. + * + * This is a synchronous failable function. See + * g_dbus_address_get_stream() for the asynchronous version. + * + * Returns: (transfer full): A #GIOStream or %NULL if @error is set. + * + * Since: 2.26 + */ +GIOStream * +g_dbus_address_get_stream_sync (const gchar *address, + gchar **out_guid, + GCancellable *cancellable, + GError **error) +{ + GIOStream *ret; + gchar **addr_array; + guint n; + GError *last_error; + + g_return_val_if_fail (address != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + ret = NULL; + last_error = NULL; + + addr_array = g_strsplit (address, ";", 0); + if (addr_array[0] == NULL) + { + last_error = g_error_new_literal (G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("The given address is empty")); + goto out; + } + + for (n = 0; addr_array[n] != NULL; n++) + { + const gchar *addr = addr_array[n]; + GError *this_error; + + this_error = NULL; + ret = g_dbus_address_try_connect_one (addr, + out_guid, + cancellable, + &this_error); + if (ret != NULL) + { + goto out; + } + else + { + g_assert (this_error != NULL); + if (last_error != NULL) + g_error_free (last_error); + last_error = this_error; + } + } + + out: + if (ret != NULL) + { + if (last_error != NULL) + g_error_free (last_error); + } + else + { + g_assert (last_error != NULL); + g_propagate_error (error, last_error); + } + + g_strfreev (addr_array); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* + * Return the address of XDG_RUNTIME_DIR/bus if it exists, belongs to + * us, and is a socket, and we are on Unix. + */ +static gchar * +get_session_address_xdg (void) +{ +#ifdef G_OS_UNIX + gchar *ret = NULL; + gchar *bus; + gchar *tmp; + GStatBuf buf; + + bus = g_build_filename (g_get_user_runtime_dir (), "bus", NULL); + + /* if ENOENT, EPERM, etc., quietly don't use it */ + if (g_stat (bus, &buf) < 0) + goto out; + + /* if it isn't ours, we have incorrectly inherited someone else's + * XDG_RUNTIME_DIR; silently don't use it + */ + if (buf.st_uid != geteuid ()) + goto out; + + /* if it isn't a socket, silently don't use it */ + if ((buf.st_mode & S_IFMT) != S_IFSOCK) + goto out; + + tmp = g_dbus_address_escape_value (bus); + ret = g_strconcat ("unix:path=", tmp, NULL); + g_free (tmp); + +out: + g_free (bus); + return ret; +#else + return NULL; +#endif +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_UNIX +static gchar * +get_session_address_dbus_launch (GError **error) +{ + gchar *ret; + gchar *machine_id; + gchar *command_line; + gchar *launch_stdout; + gchar *launch_stderr; + gint wait_status; + gchar *old_dbus_verbose; + gboolean restore_dbus_verbose; + + ret = NULL; + machine_id = NULL; + command_line = NULL; + launch_stdout = NULL; + launch_stderr = NULL; + restore_dbus_verbose = FALSE; + old_dbus_verbose = NULL; + + /* Don't run binaries as root if we're setuid. */ + if (GLIB_PRIVATE_CALL (g_check_setuid) ()) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Cannot spawn a message bus when AT_SECURE is set")); + goto out; + } + + machine_id = _g_dbus_get_machine_id (error); + if (machine_id == NULL) + { + g_prefix_error (error, _("Cannot spawn a message bus without a machine-id: ")); + goto out; + } + + if (g_getenv ("DISPLAY") == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Cannot autolaunch D-Bus without X11 $DISPLAY")); + goto out; + } + + /* We're using private libdbus facilities here. When everything + * (X11, Mac OS X, Windows) is spec'ed out correctly (not even the + * X11 property is correctly documented right now) we should + * consider using the spec instead of dbus-launch. + * + * --autolaunch=MACHINEID + * This option implies that dbus-launch should scan for a previ†+ * ously-started session and reuse the values found there. If no + * session is found, it will start a new session. The --exit-with- + * session option is implied if --autolaunch is given. This option + * is for the exclusive use of libdbus, you do not want to use it + * manually. It may change in the future. + */ + + /* TODO: maybe provide a variable for where to look for the dbus-launch binary? */ + command_line = g_strdup_printf ("dbus-launch --autolaunch=%s --binary-syntax --close-stderr", machine_id); + + if (G_UNLIKELY (_g_dbus_debug_address ())) + { + _g_dbus_debug_print_lock (); + g_print ("GDBus-debug:Address: Running '%s' to get bus address (possibly autolaunching)\n", command_line); + old_dbus_verbose = g_strdup (g_getenv ("DBUS_VERBOSE")); + restore_dbus_verbose = TRUE; + g_setenv ("DBUS_VERBOSE", "1", TRUE); + _g_dbus_debug_print_unlock (); + } + + if (!g_spawn_command_line_sync (command_line, + &launch_stdout, + &launch_stderr, + &wait_status, + error)) + { + goto out; + } + + if (!g_spawn_check_wait_status (wait_status, error)) + { + g_prefix_error (error, _("Error spawning command line “%sâ€: "), command_line); + goto out; + } + + /* From the dbus-launch(1) man page: + * + * --binary-syntax Write to stdout a nul-terminated bus address, + * then the bus PID as a binary integer of size sizeof(pid_t), + * then the bus X window ID as a binary integer of size + * sizeof(long). Integers are in the machine's byte order, not + * network byte order or any other canonical byte order. + */ + ret = g_strdup (launch_stdout); + + out: + if (G_UNLIKELY (_g_dbus_debug_address ())) + { + gchar *s; + _g_dbus_debug_print_lock (); + g_print ("GDBus-debug:Address: dbus-launch output:"); + if (launch_stdout != NULL) + { + s = _g_dbus_hexdump (launch_stdout, strlen (launch_stdout) + 1 + sizeof (pid_t) + sizeof (long), 2); + g_print ("\n%s", s); + g_free (s); + } + else + { + g_print (" (none)\n"); + } + g_print ("GDBus-debug:Address: dbus-launch stderr output:"); + if (launch_stderr != NULL) + g_print ("\n%s", launch_stderr); + else + g_print (" (none)\n"); + _g_dbus_debug_print_unlock (); + } + + g_free (machine_id); + g_free (command_line); + g_free (launch_stdout); + g_free (launch_stderr); + if (G_UNLIKELY (restore_dbus_verbose)) + { + if (old_dbus_verbose != NULL) + g_setenv ("DBUS_VERBOSE", old_dbus_verbose, TRUE); + else + g_unsetenv ("DBUS_VERBOSE"); + } + g_free (old_dbus_verbose); + return ret; +} + +/* end of G_OS_UNIX case */ +#elif defined(G_OS_WIN32) + +static gchar * +get_session_address_dbus_launch (GError **error) +{ + return _g_dbus_win32_get_session_address_dbus_launch (error); +} + +#else /* neither G_OS_UNIX nor G_OS_WIN32 */ +static gchar * +get_session_address_dbus_launch (GError **error) +{ + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Cannot determine session bus address (not implemented for this OS)")); + return NULL; +} +#endif /* neither G_OS_UNIX nor G_OS_WIN32 */ + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +get_session_address_platform_specific (GError **error) +{ + gchar *ret; + + /* Use XDG_RUNTIME_DIR/bus if it exists and is suitable. This is appropriate + * for systems using the "a session is a user-session" model described in + * , + * and implemented in dbus >= 1.9.14 and sd-bus. + * + * On systems following the more traditional "a session is a login-session" + * model, this will fail and we'll fall through to X11 autolaunching + * (dbus-launch) below. + */ + ret = get_session_address_xdg (); + + if (ret != NULL) + return ret; + + /* TODO (#694472): try launchd on OS X, like + * _dbus_lookup_session_address_launchd() does, since + * 'dbus-launch --autolaunch' probably won't work there + */ + + /* As a last resort, try the "autolaunch:" transport. On Unix this means + * X11 autolaunching; on Windows this means a different autolaunching + * mechanism based on shared memory. + */ + return get_session_address_dbus_launch (error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_address_get_for_bus_sync: + * @bus_type: a #GBusType + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Synchronously looks up the D-Bus address for the well-known message + * bus instance specified by @bus_type. This may involve using various + * platform specific mechanisms. + * + * The returned address will be in the + * [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). + * + * Returns: (transfer full): a valid D-Bus address string for @bus_type or + * %NULL if @error is set + * + * Since: 2.26 + */ +gchar * +g_dbus_address_get_for_bus_sync (GBusType bus_type, + GCancellable *cancellable, + GError **error) +{ + gboolean has_elevated_privileges = GLIB_PRIVATE_CALL (g_check_setuid) (); + gchar *ret, *s = NULL; + const gchar *starter_bus; + GError *local_error; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + ret = NULL; + local_error = NULL; + + if (G_UNLIKELY (_g_dbus_debug_address ())) + { + guint n; + _g_dbus_debug_print_lock (); + s = _g_dbus_enum_to_string (G_TYPE_BUS_TYPE, bus_type); + g_print ("GDBus-debug:Address: In g_dbus_address_get_for_bus_sync() for bus type '%s'\n", + s); + g_free (s); + for (n = 0; n < 3; n++) + { + const gchar *k; + const gchar *v; + switch (n) + { + case 0: k = "DBUS_SESSION_BUS_ADDRESS"; break; + case 1: k = "DBUS_SYSTEM_BUS_ADDRESS"; break; + case 2: k = "DBUS_STARTER_BUS_TYPE"; break; + default: g_assert_not_reached (); + } + v = g_getenv (k); + g_print ("GDBus-debug:Address: env var %s", k); + if (v != NULL) + g_print ("='%s'\n", v); + else + g_print (" is not set\n"); + } + _g_dbus_debug_print_unlock (); + } + + /* Don’t load the addresses from the environment if running as setuid, as they + * come from an unprivileged caller. */ + switch (bus_type) + { + case G_BUS_TYPE_SYSTEM: + if (has_elevated_privileges) + ret = NULL; + else + ret = g_strdup (g_getenv ("DBUS_SYSTEM_BUS_ADDRESS")); + + if (ret == NULL) + { + ret = g_strdup ("unix:path=/var/run/dbus/system_bus_socket"); + } + break; + + case G_BUS_TYPE_SESSION: + if (has_elevated_privileges) + ret = NULL; + else + ret = g_strdup (g_getenv ("DBUS_SESSION_BUS_ADDRESS")); + + if (ret == NULL) + { + ret = get_session_address_platform_specific (&local_error); + } + break; + + case G_BUS_TYPE_STARTER: + starter_bus = g_getenv ("DBUS_STARTER_BUS_TYPE"); + if (g_strcmp0 (starter_bus, "session") == 0) + { + ret = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, cancellable, &local_error); + goto out; + } + else if (g_strcmp0 (starter_bus, "system") == 0) + { + ret = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SYSTEM, cancellable, &local_error); + goto out; + } + else + { + if (starter_bus != NULL) + { + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable" + " — unknown value “%sâ€"), + starter_bus); + } + else + { + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " + "variable is not set")); + } + } + break; + + default: + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unknown bus type %d"), + bus_type); + break; + } + + out: + if (G_UNLIKELY (_g_dbus_debug_address ())) + { + _g_dbus_debug_print_lock (); + s = _g_dbus_enum_to_string (G_TYPE_BUS_TYPE, bus_type); + if (ret != NULL) + { + g_print ("GDBus-debug:Address: Returning address '%s' for bus type '%s'\n", + ret, s); + } + else + { + g_print ("GDBus-debug:Address: Cannot look-up address bus type '%s': %s\n", + s, local_error ? local_error->message : ""); + } + g_free (s); + _g_dbus_debug_print_unlock (); + } + + if (local_error != NULL) + g_propagate_error (error, local_error); + + return ret; +} + +/** + * g_dbus_address_escape_value: + * @string: an unescaped string to be included in a D-Bus address + * as the value in a key-value pair + * + * Escape @string so it can appear in a D-Bus address as the value + * part of a key-value pair. + * + * For instance, if @string is `/run/bus-for-:0`, + * this function would return `/run/bus-for-%3A0`, + * which could be used in a D-Bus address like + * `unix:nonce-tcp:host=127.0.0.1,port=42,noncefile=/run/bus-for-%3A0`. + * + * Returns: (transfer full): a copy of @string with all + * non-optionally-escaped bytes escaped + * + * Since: 2.36 + */ +gchar * +g_dbus_address_escape_value (const gchar *string) +{ + GString *s; + gsize i; + + g_return_val_if_fail (string != NULL, NULL); + + /* There will often not be anything needing escaping at all. */ + s = g_string_sized_new (strlen (string)); + + /* D-Bus address escaping is mostly the same as URI escaping... */ + g_string_append_uri_escaped (s, string, "\\/", FALSE); + + /* ... but '~' is an unreserved character in URIs, but a + * non-optionally-escaped character in D-Bus addresses. */ + for (i = 0; i < s->len; i++) + { + if (G_UNLIKELY (s->str[i] == '~')) + { + s->str[i] = '%'; + g_string_insert (s, i + 1, "7E"); + i += 2; + } + } + + return g_string_free (s, FALSE); +} diff --git a/gio/gdbusaddress.h b/gio/gdbusaddress.h new file mode 100644 index 0000000..43915bb --- /dev/null +++ b/gio/gdbusaddress.h @@ -0,0 +1,65 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_ADDRESS_H__ +#define __G_DBUS_ADDRESS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_2_36 +gchar *g_dbus_address_escape_value (const gchar *string); + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_is_address (const gchar *string); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_is_supported_address (const gchar *string, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_dbus_address_get_stream (const gchar *address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GIOStream *g_dbus_address_get_stream_finish (GAsyncResult *res, + gchar **out_guid, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GIOStream *g_dbus_address_get_stream_sync (const gchar *address, + gchar **out_guid, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gchar *g_dbus_address_get_for_bus_sync (GBusType bus_type, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* __G_DBUS_ADDRESS_H__ */ diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c new file mode 100644 index 0000000..595ab05 --- /dev/null +++ b/gio/gdbusauth.c @@ -0,0 +1,1394 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusauth.h" + +#include "gdbusauthmechanismanon.h" +#include "gdbusauthmechanismexternal.h" +#include "gdbusauthmechanismsha1.h" +#include "gdbusauthobserver.h" + +#include "gdbuserror.h" +#include "gdbusutils.h" +#include "gioenumtypes.h" +#include "gcredentials.h" +#include "gcredentialsprivate.h" +#include "gdbusprivate.h" +#include "giostream.h" +#include "gdatainputstream.h" +#include "gdataoutputstream.h" + +#ifdef G_OS_UNIX +#include "gnetworking.h" +#include "gunixconnection.h" +#include "gunixcredentialsmessage.h" +#endif + +#include "glibintl.h" + +G_GNUC_PRINTF(1, 2) +static void +debug_print (const gchar *message, ...) +{ + if (G_UNLIKELY (_g_dbus_debug_authentication ())) + { + gchar *s; + GString *str; + va_list var_args; + guint n; + + _g_dbus_debug_print_lock (); + + va_start (var_args, message); + s = g_strdup_vprintf (message, var_args); + va_end (var_args); + + str = g_string_new (NULL); + for (n = 0; s[n] != '\0'; n++) + { + if (G_UNLIKELY (s[n] == '\r')) + g_string_append (str, "\\r"); + else if (G_UNLIKELY (s[n] == '\n')) + g_string_append (str, "\\n"); + else + g_string_append_c (str, s[n]); + } + g_print ("GDBus-debug:Auth: %s\n", str->str); + g_string_free (str, TRUE); + g_free (s); + + _g_dbus_debug_print_unlock (); + } +} + +typedef struct +{ + const gchar *name; + gint priority; + GType gtype; +} Mechanism; + +static void mechanism_free (Mechanism *m); + +struct _GDBusAuthPrivate +{ + GIOStream *stream; + + /* A list of available Mechanism, sorted according to priority */ + GList *available_mechanisms; +}; + +enum +{ + PROP_0, + PROP_STREAM +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GDBusAuth, _g_dbus_auth, G_TYPE_OBJECT) + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +_g_dbus_auth_finalize (GObject *object) +{ + GDBusAuth *auth = G_DBUS_AUTH (object); + + if (auth->priv->stream != NULL) + g_object_unref (auth->priv->stream); + g_list_free_full (auth->priv->available_mechanisms, (GDestroyNotify) mechanism_free); + + if (G_OBJECT_CLASS (_g_dbus_auth_parent_class)->finalize != NULL) + G_OBJECT_CLASS (_g_dbus_auth_parent_class)->finalize (object); +} + +static void +_g_dbus_auth_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusAuth *auth = G_DBUS_AUTH (object); + + switch (prop_id) + { + case PROP_STREAM: + g_value_set_object (value, auth->priv->stream); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +_g_dbus_auth_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusAuth *auth = G_DBUS_AUTH (object); + + switch (prop_id) + { + case PROP_STREAM: + auth->priv->stream = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +_g_dbus_auth_class_init (GDBusAuthClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->get_property = _g_dbus_auth_get_property; + gobject_class->set_property = _g_dbus_auth_set_property; + gobject_class->finalize = _g_dbus_auth_finalize; + + g_object_class_install_property (gobject_class, + PROP_STREAM, + g_param_spec_object ("stream", + P_("IO Stream"), + P_("The underlying GIOStream used for I/O"), + G_TYPE_IO_STREAM, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); +} + +static void +mechanism_free (Mechanism *m) +{ + g_free (m); +} + +static void +add_mechanism (GDBusAuth *auth, + GDBusAuthObserver *observer, + GType mechanism_type) +{ + const gchar *name; + + name = _g_dbus_auth_mechanism_get_name (mechanism_type); + if (observer == NULL || g_dbus_auth_observer_allow_mechanism (observer, name)) + { + Mechanism *m; + m = g_new0 (Mechanism, 1); + m->name = name; + m->priority = _g_dbus_auth_mechanism_get_priority (mechanism_type); + m->gtype = mechanism_type; + auth->priv->available_mechanisms = g_list_prepend (auth->priv->available_mechanisms, m); + } +} + +static gint +mech_compare_func (Mechanism *a, Mechanism *b) +{ + gint ret; + /* ensure deterministic order */ + ret = b->priority - a->priority; + if (ret == 0) + ret = g_strcmp0 (b->name, a->name); + return ret; +} + +static void +_g_dbus_auth_init (GDBusAuth *auth) +{ + auth->priv = _g_dbus_auth_get_instance_private (auth); +} + +static void +_g_dbus_auth_add_mechs (GDBusAuth *auth, + GDBusAuthObserver *observer) +{ + /* TODO: trawl extension points */ + add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_ANON); + add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_SHA1); + add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL); + + auth->priv->available_mechanisms = g_list_sort (auth->priv->available_mechanisms, + (GCompareFunc) mech_compare_func); +} + +static GType +find_mech_by_name (GDBusAuth *auth, + const gchar *name) +{ + GType ret; + GList *l; + + ret = (GType) 0; + + for (l = auth->priv->available_mechanisms; l != NULL; l = l->next) + { + Mechanism *m = l->data; + if (g_strcmp0 (name, m->name) == 0) + { + ret = m->gtype; + goto out; + } + } + + out: + return ret; +} + +GDBusAuth * +_g_dbus_auth_new (GIOStream *stream) +{ + return g_object_new (G_TYPE_DBUS_AUTH, + "stream", stream, + NULL); +} + +/* ---------------------------------------------------------------------------------------------------- */ +/* like g_data_input_stream_read_line() but sets error if there's no content to read */ +static gchar * +_my_g_data_input_stream_read_line (GDataInputStream *dis, + gsize *out_line_length, + GCancellable *cancellable, + GError **error) +{ + gchar *ret; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + ret = g_data_input_stream_read_line (dis, + out_line_length, + cancellable, + error); + if (ret == NULL && error != NULL && *error == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unexpected lack of content trying to read a line")); + } + + return ret; +} + +/* This function is to avoid situations like this + * + * BEGIN\r\nl\0\0\1... + * + * e.g. where we read into the first D-Bus message while waiting for + * the final line from the client (TODO: file bug against gio for + * this) + */ +static gchar * +_my_g_input_stream_read_line_safe (GInputStream *i, + gsize *out_line_length, + GCancellable *cancellable, + GError **error) +{ + GString *str; + gchar c; + gssize num_read; + gboolean last_was_cr; + + str = g_string_new (NULL); + + last_was_cr = FALSE; + while (TRUE) + { + num_read = g_input_stream_read (i, + &c, + 1, + cancellable, + error); + if (num_read == -1) + goto fail; + if (num_read == 0) + { + if (error != NULL && *error == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unexpected lack of content trying to (safely) read a line")); + } + goto fail; + } + + g_string_append_c (str, (gint) c); + if (last_was_cr) + { + if (c == 0x0a) + { + g_assert (str->len >= 2); + g_string_set_size (str, str->len - 2); + goto out; + } + } + last_was_cr = (c == 0x0d); + } + + out: + if (out_line_length != NULL) + *out_line_length = str->len; + return g_string_free (str, FALSE); + + fail: + g_assert (error == NULL || *error != NULL); + g_string_free (str, TRUE); + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +hexdecode (const gchar *str, + gsize *out_len, + GError **error) +{ + gchar *ret; + GString *s; + guint n; + + ret = NULL; + s = g_string_new (NULL); + + for (n = 0; str[n] != '\0'; n += 2) + { + gint upper_nibble; + gint lower_nibble; + guint value; + + upper_nibble = g_ascii_xdigit_value (str[n]); + lower_nibble = g_ascii_xdigit_value (str[n + 1]); + if (upper_nibble == -1 || lower_nibble == -1) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Error hexdecoding string '%s' around position %d", + str, n); + goto out; + } + value = (upper_nibble<<4) | lower_nibble; + g_string_append_c (s, value); + } + + *out_len = s->len; + ret = g_string_free (s, FALSE); + s = NULL; + + out: + if (s != NULL) + { + *out_len = 0; + g_string_free (s, TRUE); + } + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAuthMechanism * +client_choose_mech_and_send_initial_response (GDBusAuth *auth, + GCredentials *credentials_that_were_sent, + const gchar* const *supported_auth_mechs, + GPtrArray *attempted_auth_mechs, + GDataOutputStream *dos, + GCancellable *cancellable, + GError **error) +{ + GDBusAuthMechanism *mech; + GType auth_mech_to_use_gtype; + guint n; + guint m; + gchar *initial_response; + gsize initial_response_len; + gchar *encoded; + gchar *s; + + again: + mech = NULL; + + debug_print ("CLIENT: Trying to choose mechanism"); + + /* find an authentication mechanism to try, if any */ + auth_mech_to_use_gtype = (GType) 0; + for (n = 0; supported_auth_mechs[n] != NULL; n++) + { + gboolean attempted_already; + attempted_already = FALSE; + for (m = 0; m < attempted_auth_mechs->len; m++) + { + if (g_strcmp0 (supported_auth_mechs[n], attempted_auth_mechs->pdata[m]) == 0) + { + attempted_already = TRUE; + break; + } + } + if (!attempted_already) + { + auth_mech_to_use_gtype = find_mech_by_name (auth, supported_auth_mechs[n]); + if (auth_mech_to_use_gtype != (GType) 0) + break; + } + } + + if (auth_mech_to_use_gtype == (GType) 0) + { + guint n; + gchar *available; + GString *tried_str; + + debug_print ("CLIENT: Exhausted all available mechanisms"); + + available = g_strjoinv (", ", (gchar **) supported_auth_mechs); + + tried_str = g_string_new (NULL); + for (n = 0; n < attempted_auth_mechs->len; n++) + { + if (n > 0) + g_string_append (tried_str, ", "); + g_string_append (tried_str, attempted_auth_mechs->pdata[n]); + } + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Exhausted all available authentication mechanisms (tried: %s) (available: %s)"), + tried_str->str, + available); + g_string_free (tried_str, TRUE); + g_free (available); + goto out; + } + + /* OK, decided on a mechanism - let's do this thing */ + mech = g_object_new (auth_mech_to_use_gtype, + "stream", auth->priv->stream, + "credentials", credentials_that_were_sent, + NULL); + debug_print ("CLIENT: Trying mechanism '%s'", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); + g_ptr_array_add (attempted_auth_mechs, (gpointer) _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); + + /* the auth mechanism may not be supported + * (for example, EXTERNAL only works if credentials were exchanged) + */ + if (!_g_dbus_auth_mechanism_is_supported (mech)) + { + debug_print ("CLIENT: Mechanism '%s' says it is not supported", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); + g_object_unref (mech); + mech = NULL; + goto again; + } + + initial_response_len = 0; + initial_response = _g_dbus_auth_mechanism_client_initiate (mech, + &initial_response_len); +#if 0 + g_printerr ("using auth mechanism with name '%s' of type '%s' with initial response '%s'\n", + _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype), + g_type_name (G_TYPE_FROM_INSTANCE (mech)), + initial_response); +#endif + if (initial_response != NULL) + { + //g_printerr ("initial_response = '%s'\n", initial_response); + encoded = _g_dbus_hexencode (initial_response, initial_response_len); + s = g_strdup_printf ("AUTH %s %s\r\n", + _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype), + encoded); + g_free (initial_response); + g_free (encoded); + } + else + { + s = g_strdup_printf ("AUTH %s\r\n", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); + } + debug_print ("CLIENT: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + { + g_object_unref (mech); + mech = NULL; + g_free (s); + goto out; + } + g_free (s); + + out: + return mech; +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef enum +{ + CLIENT_STATE_WAITING_FOR_DATA, + CLIENT_STATE_WAITING_FOR_OK, + CLIENT_STATE_WAITING_FOR_REJECT, + CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD +} ClientState; + +gchar * +_g_dbus_auth_run_client (GDBusAuth *auth, + GDBusAuthObserver *observer, + GDBusCapabilityFlags offered_capabilities, + GDBusCapabilityFlags *out_negotiated_capabilities, + GCancellable *cancellable, + GError **error) +{ + gchar *s; + GDataInputStream *dis; + GDataOutputStream *dos; + GCredentials *credentials; + gchar *ret_guid; + gchar *line; + gsize line_length; + gchar **supported_auth_mechs; + GPtrArray *attempted_auth_mechs; + GDBusAuthMechanism *mech; + ClientState state; + GDBusCapabilityFlags negotiated_capabilities; + + debug_print ("CLIENT: initiating"); + + _g_dbus_auth_add_mechs (auth, observer); + + ret_guid = NULL; + supported_auth_mechs = NULL; + attempted_auth_mechs = g_ptr_array_new (); + mech = NULL; + negotiated_capabilities = 0; + credentials = NULL; + + dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream))); + dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream))); + g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE); + g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE); + + g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); + +#ifdef G_OS_UNIX + if (G_IS_UNIX_CONNECTION (auth->priv->stream)) + { + credentials = g_credentials_new (); + if (!g_unix_connection_send_credentials (G_UNIX_CONNECTION (auth->priv->stream), + cancellable, + error)) + goto out; + } + else + { + if (!g_data_output_stream_put_byte (dos, '\0', cancellable, error)) + goto out; + } +#else + if (!g_data_output_stream_put_byte (dos, '\0', cancellable, error)) + goto out; +#endif + + if (credentials != NULL) + { + if (G_UNLIKELY (_g_dbus_debug_authentication ())) + { + s = g_credentials_to_string (credentials); + debug_print ("CLIENT: sent credentials '%s'", s); + g_free (s); + } + } + else + { + debug_print ("CLIENT: didn't send any credentials"); + } + + /* TODO: to reduce roundtrips, try to pick an auth mechanism to start with */ + + /* Get list of supported authentication mechanisms */ + s = "AUTH\r\n"; + debug_print ("CLIENT: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + goto out; + state = CLIENT_STATE_WAITING_FOR_REJECT; + + while (TRUE) + { + switch (state) + { + case CLIENT_STATE_WAITING_FOR_REJECT: + debug_print ("CLIENT: WaitingForReject"); + line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); + if (line == NULL) + goto out; + debug_print ("CLIENT: WaitingForReject, read '%s'", line); + + choose_mechanism: + if (!g_str_has_prefix (line, "REJECTED ")) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "In WaitingForReject: Expected 'REJECTED am1 am2 ... amN', got '%s'", + line); + g_free (line); + goto out; + } + if (supported_auth_mechs == NULL) + { + supported_auth_mechs = g_strsplit (line + sizeof ("REJECTED ") - 1, " ", 0); +#if 0 + for (n = 0; supported_auth_mechs != NULL && supported_auth_mechs[n] != NULL; n++) + g_printerr ("supported_auth_mechs[%d] = '%s'\n", n, supported_auth_mechs[n]); +#endif + } + g_free (line); + mech = client_choose_mech_and_send_initial_response (auth, + credentials, + (const gchar* const *) supported_auth_mechs, + attempted_auth_mechs, + dos, + cancellable, + error); + if (mech == NULL) + goto out; + if (_g_dbus_auth_mechanism_client_get_state (mech) == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA) + state = CLIENT_STATE_WAITING_FOR_DATA; + else + state = CLIENT_STATE_WAITING_FOR_OK; + break; + + case CLIENT_STATE_WAITING_FOR_OK: + debug_print ("CLIENT: WaitingForOK"); + line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); + if (line == NULL) + goto out; + debug_print ("CLIENT: WaitingForOK, read '%s'", line); + if (g_str_has_prefix (line, "OK ")) + { + if (!g_dbus_is_guid (line + 3)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Invalid OK response '%s'", + line); + g_free (line); + goto out; + } + ret_guid = g_strdup (line + 3); + g_free (line); + + if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) + { + s = "NEGOTIATE_UNIX_FD\r\n"; + debug_print ("CLIENT: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + goto out; + state = CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD; + } + else + { + s = "BEGIN\r\n"; + debug_print ("CLIENT: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + goto out; + /* and we're done! */ + goto out; + } + } + else if (g_str_has_prefix (line, "REJECTED ")) + { + goto choose_mechanism; + } + else + { + /* TODO: handle other valid responses */ + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "In WaitingForOk: unexpected response '%s'", + line); + g_free (line); + goto out; + } + break; + + case CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD: + debug_print ("CLIENT: WaitingForAgreeUnixFD"); + line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); + if (line == NULL) + goto out; + debug_print ("CLIENT: WaitingForAgreeUnixFD, read='%s'", line); + if (g_strcmp0 (line, "AGREE_UNIX_FD") == 0) + { + g_free (line); + negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; + s = "BEGIN\r\n"; + debug_print ("CLIENT: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + goto out; + /* and we're done! */ + goto out; + } + else if (g_str_has_prefix (line, "ERROR") && (line[5] == 0 || g_ascii_isspace (line[5]))) + { + //g_strstrip (line + 5); g_debug ("bah, no unix_fd: '%s'", line + 5); + g_free (line); + s = "BEGIN\r\n"; + debug_print ("CLIENT: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + goto out; + /* and we're done! */ + goto out; + } + else + { + /* TODO: handle other valid responses */ + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "In WaitingForAgreeUnixFd: unexpected response '%s'", + line); + g_free (line); + goto out; + } + break; + + case CLIENT_STATE_WAITING_FOR_DATA: + debug_print ("CLIENT: WaitingForData"); + line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); + if (line == NULL) + goto out; + debug_print ("CLIENT: WaitingForData, read='%s'", line); + if (g_str_equal (line, "DATA") || g_str_has_prefix (line, "DATA ")) + { + gchar *encoded; + gchar *decoded_data; + gsize decoded_data_len = 0; + + encoded = g_strdup (line + 4); + g_free (line); + g_strstrip (encoded); + decoded_data = hexdecode (encoded, &decoded_data_len, error); + g_free (encoded); + if (decoded_data == NULL) + { + g_prefix_error (error, "DATA response is malformed: "); + /* invalid encoding, disconnect! */ + goto out; + } + _g_dbus_auth_mechanism_client_data_receive (mech, decoded_data, decoded_data_len); + g_free (decoded_data); + + if (_g_dbus_auth_mechanism_client_get_state (mech) == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND) + { + gchar *data; + gsize data_len; + gchar *encoded_data; + data = _g_dbus_auth_mechanism_client_data_send (mech, &data_len); + encoded_data = _g_dbus_hexencode (data, data_len); + s = g_strdup_printf ("DATA %s\r\n", encoded_data); + g_free (encoded_data); + g_free (data); + debug_print ("CLIENT: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + { + g_free (s); + goto out; + } + g_free (s); + } + state = CLIENT_STATE_WAITING_FOR_OK; + } + else if (g_str_has_prefix (line, "REJECTED ")) + { + /* could be the chosen authentication method just doesn't work. Try + * another one... + */ + goto choose_mechanism; + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "In WaitingForData: unexpected response '%s'", + line); + g_free (line); + goto out; + } + break; + + default: + g_assert_not_reached (); + break; + } + + }; /* main authentication client loop */ + + out: + if (mech != NULL) + g_object_unref (mech); + g_ptr_array_unref (attempted_auth_mechs); + g_strfreev (supported_auth_mechs); + g_object_unref (dis); + g_object_unref (dos); + + /* ensure return value is NULL if error is set */ + if (error != NULL && *error != NULL) + { + g_free (ret_guid); + ret_guid = NULL; + } + + if (ret_guid != NULL) + { + if (out_negotiated_capabilities != NULL) + *out_negotiated_capabilities = negotiated_capabilities; + } + + if (credentials != NULL) + g_object_unref (credentials); + + debug_print ("CLIENT: Done, authenticated=%d", ret_guid != NULL); + + return ret_guid; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +get_auth_mechanisms (GDBusAuth *auth, + gboolean allow_anonymous, + const gchar *prefix, + const gchar *suffix, + const gchar *separator) +{ + GList *l; + GString *str; + gboolean need_sep; + + str = g_string_new (prefix); + need_sep = FALSE; + for (l = auth->priv->available_mechanisms; l != NULL; l = l->next) + { + Mechanism *m = l->data; + + if (!allow_anonymous && g_strcmp0 (m->name, "ANONYMOUS") == 0) + continue; + + if (need_sep) + g_string_append (str, separator); + g_string_append (str, m->name); + need_sep = TRUE; + } + + g_string_append (str, suffix); + return g_string_free (str, FALSE); +} + + +typedef enum +{ + SERVER_STATE_WAITING_FOR_AUTH, + SERVER_STATE_WAITING_FOR_DATA, + SERVER_STATE_WAITING_FOR_BEGIN +} ServerState; + +gboolean +_g_dbus_auth_run_server (GDBusAuth *auth, + GDBusAuthObserver *observer, + const gchar *guid, + gboolean allow_anonymous, + gboolean require_same_user, + GDBusCapabilityFlags offered_capabilities, + GDBusCapabilityFlags *out_negotiated_capabilities, + GCredentials **out_received_credentials, + GCancellable *cancellable, + GError **error) +{ + gboolean ret; + ServerState state; + GDataInputStream *dis; + GDataOutputStream *dos; + GError *local_error; + gchar *line; + gsize line_length; + GDBusAuthMechanism *mech; + gchar *s; + GDBusCapabilityFlags negotiated_capabilities; + GCredentials *credentials; + GCredentials *own_credentials = NULL; + + debug_print ("SERVER: initiating"); + + _g_dbus_auth_add_mechs (auth, observer); + + ret = FALSE; + dis = NULL; + dos = NULL; + mech = NULL; + negotiated_capabilities = 0; + credentials = NULL; + + if (!g_dbus_is_guid (guid)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "The given GUID '%s' is not valid", + guid); + goto out; + } + + dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream))); + dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream))); + g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE); + g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE); + + g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); + + /* read the NUL-byte, possibly with credentials attached */ +#ifdef G_OS_UNIX +#ifndef G_CREDENTIALS_PREFER_MESSAGE_PASSING + if (G_IS_SOCKET_CONNECTION (auth->priv->stream)) + { + GSocket *sock = g_socket_connection_get_socket (G_SOCKET_CONNECTION (auth->priv->stream)); + + local_error = NULL; + credentials = g_socket_get_credentials (sock, &local_error); + + if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + g_propagate_error (error, local_error); + goto out; + } + else + { + /* Clear the error indicator, so we can retry with + * g_unix_connection_receive_credentials() if necessary */ + g_clear_error (&local_error); + } + } +#endif + + if (credentials == NULL && G_IS_UNIX_CONNECTION (auth->priv->stream)) + { + local_error = NULL; + credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream), + cancellable, + &local_error); + if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + g_propagate_error (error, local_error); + goto out; + } + g_clear_error (&local_error); + } + else + { + local_error = NULL; + (void)g_data_input_stream_read_byte (dis, cancellable, &local_error); + if (local_error != NULL) + { + g_propagate_error (error, local_error); + goto out; + } + } +#else + local_error = NULL; + (void)g_data_input_stream_read_byte (dis, cancellable, &local_error); + if (local_error != NULL) + { + g_propagate_error (error, local_error); + goto out; + } +#endif + if (credentials != NULL) + { + if (G_UNLIKELY (_g_dbus_debug_authentication ())) + { + s = g_credentials_to_string (credentials); + debug_print ("SERVER: received credentials '%s'", s); + g_free (s); + } + } + else + { + debug_print ("SERVER: didn't receive any credentials"); + } + + own_credentials = g_credentials_new (); + + state = SERVER_STATE_WAITING_FOR_AUTH; + while (TRUE) + { + switch (state) + { + case SERVER_STATE_WAITING_FOR_AUTH: + debug_print ("SERVER: WaitingForAuth"); + line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); + debug_print ("SERVER: WaitingForAuth, read '%s'", line); + if (line == NULL) + goto out; + if (g_strcmp0 (line, "AUTH") == 0) + { + s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); + debug_print ("SERVER: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + { + g_free (s); + g_free (line); + goto out; + } + g_free (s); + g_free (line); + } + else if (g_str_has_prefix (line, "AUTH ")) + { + gchar **tokens; + const gchar *encoded; + const gchar *mech_name; + GType auth_mech_to_use_gtype; + + tokens = g_strsplit (line, " ", 0); + + switch (g_strv_length (tokens)) + { + case 2: + /* no initial response */ + mech_name = tokens[1]; + encoded = NULL; + break; + + case 3: + /* initial response */ + mech_name = tokens[1]; + encoded = tokens[2]; + break; + + default: + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unexpected line '%s' while in WaitingForAuth state", + line); + g_strfreev (tokens); + g_free (line); + goto out; + } + + g_free (line); + + /* TODO: record that the client has attempted to use this mechanism */ + //g_debug ("client is trying '%s'", mech_name); + + auth_mech_to_use_gtype = find_mech_by_name (auth, mech_name); + if ((auth_mech_to_use_gtype == (GType) 0) || + (!allow_anonymous && g_strcmp0 (mech_name, "ANONYMOUS") == 0)) + { + /* We don't support this auth mechanism */ + g_strfreev (tokens); + s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); + debug_print ("SERVER: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + { + g_free (s); + goto out; + } + g_free (s); + + /* stay in WAITING FOR AUTH */ + state = SERVER_STATE_WAITING_FOR_AUTH; + } + else + { + gchar *initial_response; + gsize initial_response_len; + + g_clear_object (&mech); + mech = g_object_new (auth_mech_to_use_gtype, + "stream", auth->priv->stream, + "credentials", credentials, + NULL); + + initial_response = NULL; + initial_response_len = 0; + if (encoded != NULL) + { + initial_response = hexdecode (encoded, &initial_response_len, error); + if (initial_response == NULL) + { + g_prefix_error (error, "Initial response is malformed: "); + /* invalid encoding, disconnect! */ + g_strfreev (tokens); + goto out; + } + } + + _g_dbus_auth_mechanism_server_initiate (mech, + initial_response, + initial_response_len); + g_free (initial_response); + g_strfreev (tokens); + + change_state: + switch (_g_dbus_auth_mechanism_server_get_state (mech)) + { + case G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED: + if (require_same_user && + (credentials == NULL || + !g_credentials_is_same_user (credentials, own_credentials, NULL))) + { + /* disconnect */ + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("User IDs must be the same for peer and server")); + goto out; + } + else if (observer != NULL && + !g_dbus_auth_observer_authorize_authenticated_peer (observer, + auth->priv->stream, + credentials)) + { + /* disconnect */ + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Cancelled via GDBusAuthObserver::authorize-authenticated-peer")); + goto out; + } + else + { + s = g_strdup_printf ("OK %s\r\n", guid); + debug_print ("SERVER: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + { + g_free (s); + goto out; + } + g_free (s); + state = SERVER_STATE_WAITING_FOR_BEGIN; + } + break; + + case G_DBUS_AUTH_MECHANISM_STATE_REJECTED: + s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); + debug_print ("SERVER: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + { + g_free (s); + goto out; + } + g_free (s); + state = SERVER_STATE_WAITING_FOR_AUTH; + break; + + case G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA: + state = SERVER_STATE_WAITING_FOR_DATA; + break; + + case G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND: + { + gchar *data; + gsize data_len; + + data = _g_dbus_auth_mechanism_server_data_send (mech, &data_len); + if (data != NULL) + { + gchar *encoded_data; + + encoded_data = _g_dbus_hexencode (data, data_len); + s = g_strdup_printf ("DATA %s\r\n", encoded_data); + g_free (encoded_data); + g_free (data); + + debug_print ("SERVER: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + { + g_free (s); + goto out; + } + g_free (s); + } + } + goto change_state; + break; + + default: + /* TODO */ + g_assert_not_reached (); + break; + } + } + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unexpected line '%s' while in WaitingForAuth state", + line); + g_free (line); + goto out; + } + break; + + case SERVER_STATE_WAITING_FOR_DATA: + debug_print ("SERVER: WaitingForData"); + line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); + debug_print ("SERVER: WaitingForData, read '%s'", line); + if (line == NULL) + goto out; + if (g_str_equal (line, "DATA") || g_str_has_prefix (line, "DATA ")) + { + gchar *encoded; + gchar *decoded_data; + gsize decoded_data_len = 0; + + encoded = g_strdup (line + 4); + g_free (line); + g_strstrip (encoded); + decoded_data = hexdecode (encoded, &decoded_data_len, error); + g_free (encoded); + if (decoded_data == NULL) + { + g_prefix_error (error, "DATA response is malformed: "); + /* invalid encoding, disconnect! */ + goto out; + } + _g_dbus_auth_mechanism_server_data_receive (mech, decoded_data, decoded_data_len); + g_free (decoded_data); + /* oh man, this goto-crap is so ugly.. really need to rewrite the state machine */ + goto change_state; + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unexpected line '%s' while in WaitingForData state", + line); + g_free (line); + } + goto out; + + case SERVER_STATE_WAITING_FOR_BEGIN: + debug_print ("SERVER: WaitingForBegin"); + /* Use extremely slow (but reliable) line reader - this basically + * does a recvfrom() system call per character + * + * (the problem with using GDataInputStream's read_line is that because of + * buffering it might start reading into the first D-Bus message that + * appears after "BEGIN\r\n"....) + */ + line = _my_g_input_stream_read_line_safe (g_io_stream_get_input_stream (auth->priv->stream), + &line_length, + cancellable, + error); + if (line == NULL) + goto out; + debug_print ("SERVER: WaitingForBegin, read '%s'", line); + if (g_strcmp0 (line, "BEGIN") == 0) + { + /* YAY, done! */ + ret = TRUE; + g_free (line); + goto out; + } + else if (g_strcmp0 (line, "NEGOTIATE_UNIX_FD") == 0) + { + g_free (line); + if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) + { + negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; + s = "AGREE_UNIX_FD\r\n"; + debug_print ("SERVER: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + goto out; + } + else + { + s = "ERROR \"fd passing not offered\"\r\n"; + debug_print ("SERVER: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + goto out; + } + } + else + { + g_debug ("Unexpected line '%s' while in WaitingForBegin state", line); + g_free (line); + s = "ERROR \"Unknown Command\"\r\n"; + debug_print ("SERVER: writing '%s'", s); + if (!g_data_output_stream_put_string (dos, s, cancellable, error)) + goto out; + } + break; + + default: + g_assert_not_reached (); + break; + } + } + + + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Not implemented (server)"); + + out: + g_clear_object (&mech); + g_clear_object (&dis); + g_clear_object (&dos); + g_clear_object (&own_credentials); + + /* ensure return value is FALSE if error is set */ + if (error != NULL && *error != NULL) + { + ret = FALSE; + } + + if (ret) + { + if (out_negotiated_capabilities != NULL) + *out_negotiated_capabilities = negotiated_capabilities; + if (out_received_credentials != NULL) + *out_received_credentials = credentials != NULL ? g_object_ref (credentials) : NULL; + } + + if (credentials != NULL) + g_object_unref (credentials); + + debug_print ("SERVER: Done, authenticated=%d", ret); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusauth.h b/gio/gdbusauth.h new file mode 100644 index 0000000..70b6a60 --- /dev/null +++ b/gio/gdbusauth.h @@ -0,0 +1,86 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_AUTH_H__ +#define __G_DBUS_AUTH_H__ + +#if !defined (GIO_COMPILATION) +#error "gdbusauth.h is a private header file." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_AUTH (_g_dbus_auth_get_type ()) +#define G_DBUS_AUTH(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_AUTH, GDBusAuth)) +#define G_DBUS_AUTH_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_AUTH, GDBusAuthClass)) +#define G_DBUS_AUTH_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_AUTH, GDBusAuthClass)) +#define G_IS_DBUS_AUTH(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_AUTH)) +#define G_IS_DBUS_AUTH_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_AUTH)) + +typedef struct _GDBusAuth GDBusAuth; +typedef struct _GDBusAuthClass GDBusAuthClass; +typedef struct _GDBusAuthPrivate GDBusAuthPrivate; + +struct _GDBusAuthClass +{ + /*< private >*/ + GObjectClass parent_class; +}; + +struct _GDBusAuth +{ + GObject parent_instance; + GDBusAuthPrivate *priv; +}; + +GType _g_dbus_auth_get_type (void) G_GNUC_CONST; +GDBusAuth *_g_dbus_auth_new (GIOStream *stream); + +/* TODO: need a way to set allowed authentication mechanisms */ + +/* TODO: need a way to convey credentials etc. */ + +/* TODO: need a way to convey negotiated features (e.g. returning flags from e.g. GDBusConnectionFeatures) */ + +/* TODO: need to expose encode()/decode() from the AuthMechanism (and whether it is needed at all) */ + +gboolean _g_dbus_auth_run_server (GDBusAuth *auth, + GDBusAuthObserver *observer, + const gchar *guid, + gboolean allow_anonymous, + gboolean require_same_user, + GDBusCapabilityFlags offered_capabilities, + GDBusCapabilityFlags *out_negotiated_capabilities, + GCredentials **out_received_credentials, + GCancellable *cancellable, + GError **error); + +gchar *_g_dbus_auth_run_client (GDBusAuth *auth, + GDBusAuthObserver *observer, + GDBusCapabilityFlags offered_capabilities, + GDBusCapabilityFlags *out_negotiated_capabilities, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* __G_DBUS_AUTH_H__ */ diff --git a/gio/gdbusauthmechanism.c b/gio/gdbusauthmechanism.c new file mode 100644 index 0000000..897d414 --- /dev/null +++ b/gio/gdbusauthmechanism.c @@ -0,0 +1,334 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusauthmechanism.h" +#include "gcredentials.h" +#include "gdbuserror.h" +#include "gioenumtypes.h" +#include "giostream.h" + +#include "glibintl.h" + +/* ---------------------------------------------------------------------------------------------------- */ + +struct _GDBusAuthMechanismPrivate +{ + GIOStream *stream; + GCredentials *credentials; +}; + +enum +{ + PROP_0, + PROP_STREAM, + PROP_CREDENTIALS +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GDBusAuthMechanism, _g_dbus_auth_mechanism, G_TYPE_OBJECT) + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +_g_dbus_auth_mechanism_finalize (GObject *object) +{ + GDBusAuthMechanism *mechanism = G_DBUS_AUTH_MECHANISM (object); + + if (mechanism->priv->stream != NULL) + g_object_unref (mechanism->priv->stream); + if (mechanism->priv->credentials != NULL) + g_object_unref (mechanism->priv->credentials); + + G_OBJECT_CLASS (_g_dbus_auth_mechanism_parent_class)->finalize (object); +} + +static void +_g_dbus_auth_mechanism_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusAuthMechanism *mechanism = G_DBUS_AUTH_MECHANISM (object); + + switch (prop_id) + { + case PROP_STREAM: + g_value_set_object (value, mechanism->priv->stream); + break; + + case PROP_CREDENTIALS: + g_value_set_object (value, mechanism->priv->credentials); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +_g_dbus_auth_mechanism_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusAuthMechanism *mechanism = G_DBUS_AUTH_MECHANISM (object); + + switch (prop_id) + { + case PROP_STREAM: + mechanism->priv->stream = g_value_dup_object (value); + break; + + case PROP_CREDENTIALS: + mechanism->priv->credentials = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +_g_dbus_auth_mechanism_class_init (GDBusAuthMechanismClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->get_property = _g_dbus_auth_mechanism_get_property; + gobject_class->set_property = _g_dbus_auth_mechanism_set_property; + gobject_class->finalize = _g_dbus_auth_mechanism_finalize; + + g_object_class_install_property (gobject_class, + PROP_STREAM, + g_param_spec_object ("stream", + P_("IO Stream"), + P_("The underlying GIOStream used for I/O"), + G_TYPE_IO_STREAM, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusAuthMechanism:credentials: + * + * If authenticating as a server, this property contains the + * received credentials, if any. + * + * If authenticating as a client, the property contains the + * credentials that were sent, if any. + */ + g_object_class_install_property (gobject_class, + PROP_CREDENTIALS, + g_param_spec_object ("credentials", + P_("Credentials"), + P_("The credentials of the remote peer"), + G_TYPE_CREDENTIALS, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); +} + +static void +_g_dbus_auth_mechanism_init (GDBusAuthMechanism *mechanism) +{ + mechanism->priv = _g_dbus_auth_mechanism_get_instance_private (mechanism); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +GIOStream * +_g_dbus_auth_mechanism_get_stream (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), NULL); + return mechanism->priv->stream; +} + +GCredentials * +_g_dbus_auth_mechanism_get_credentials (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), NULL); + return mechanism->priv->credentials; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +const gchar * +_g_dbus_auth_mechanism_get_name (GType mechanism_type) +{ + const gchar *name; + GDBusAuthMechanismClass *klass; + + g_return_val_if_fail (g_type_is_a (mechanism_type, G_TYPE_DBUS_AUTH_MECHANISM), NULL); + + klass = g_type_class_ref (mechanism_type); + g_assert (klass != NULL); + name = klass->get_name (); + //g_type_class_unref (klass); + + return name; +} + +gint +_g_dbus_auth_mechanism_get_priority (GType mechanism_type) +{ + gint priority; + GDBusAuthMechanismClass *klass; + + g_return_val_if_fail (g_type_is_a (mechanism_type, G_TYPE_DBUS_AUTH_MECHANISM), 0); + + klass = g_type_class_ref (mechanism_type); + g_assert (klass != NULL); + priority = klass->get_priority (); + //g_type_class_unref (klass); + + return priority; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +gboolean +_g_dbus_auth_mechanism_is_supported (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), FALSE); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->is_supported (mechanism); +} + +gchar * +_g_dbus_auth_mechanism_encode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), NULL); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->encode_data (mechanism, data, data_len, out_data_len); +} + + +gchar * +_g_dbus_auth_mechanism_decode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), NULL); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->decode_data (mechanism, data, data_len, out_data_len); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +GDBusAuthMechanismState +_g_dbus_auth_mechanism_server_get_state (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->server_get_state (mechanism); +} + +void +_g_dbus_auth_mechanism_server_initiate (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len) +{ + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism)); + G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->server_initiate (mechanism, initial_response, initial_response_len); +} + +void +_g_dbus_auth_mechanism_server_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len) +{ + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism)); + G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->server_data_receive (mechanism, data, data_len); +} + +gchar * +_g_dbus_auth_mechanism_server_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), NULL); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->server_data_send (mechanism, out_data_len); +} + +gchar * +_g_dbus_auth_mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), NULL); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->server_get_reject_reason (mechanism); +} + +void +_g_dbus_auth_mechanism_server_shutdown (GDBusAuthMechanism *mechanism) +{ + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism)); + G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->server_shutdown (mechanism); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +GDBusAuthMechanismState +_g_dbus_auth_mechanism_client_get_state (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->client_get_state (mechanism); +} + +gchar * +_g_dbus_auth_mechanism_client_initiate (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), NULL); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->client_initiate (mechanism, + out_initial_response_len); +} + +void +_g_dbus_auth_mechanism_client_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len) +{ + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism)); + G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->client_data_receive (mechanism, data, data_len); +} + +gchar * +_g_dbus_auth_mechanism_client_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism), NULL); + return G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->client_data_send (mechanism, out_data_len); +} + +void +_g_dbus_auth_mechanism_client_shutdown (GDBusAuthMechanism *mechanism) +{ + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM (mechanism)); + G_DBUS_AUTH_MECHANISM_GET_CLASS (mechanism)->client_shutdown (mechanism); +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusauthmechanism.h b/gio/gdbusauthmechanism.h new file mode 100644 index 0000000..cee87b0 --- /dev/null +++ b/gio/gdbusauthmechanism.h @@ -0,0 +1,152 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_AUTH_MECHANISM_H__ +#define __G_DBUS_AUTH_MECHANISM_H__ + +#if !defined (GIO_COMPILATION) +#error "gdbusauthmechanism.h is a private header file." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_AUTH_MECHANISM (_g_dbus_auth_mechanism_get_type ()) +#define G_DBUS_AUTH_MECHANISM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_AUTH_MECHANISM, GDBusAuthMechanism)) +#define G_DBUS_AUTH_MECHANISM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_AUTH_MECHANISM, GDBusAuthMechanismClass)) +#define G_DBUS_AUTH_MECHANISM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_AUTH_MECHANISM, GDBusAuthMechanismClass)) +#define G_IS_DBUS_AUTH_MECHANISM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_AUTH_MECHANISM)) +#define G_IS_DBUS_AUTH_MECHANISM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_AUTH_MECHANISM)) + +typedef struct _GDBusAuthMechanism GDBusAuthMechanism; +typedef struct _GDBusAuthMechanismClass GDBusAuthMechanismClass; +typedef struct _GDBusAuthMechanismPrivate GDBusAuthMechanismPrivate; + +typedef enum { + G_DBUS_AUTH_MECHANISM_STATE_INVALID, + G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA, + G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, + G_DBUS_AUTH_MECHANISM_STATE_REJECTED, + G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED, +} GDBusAuthMechanismState; + +struct _GDBusAuthMechanismClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + + /* VTable */ + + /* TODO: server_initiate and client_initiate probably needs to have a + * GCredentials parameter... + */ + + gint (*get_priority) (void); + const gchar *(*get_name) (void); + + /* functions shared by server/client */ + gboolean (*is_supported) (GDBusAuthMechanism *mechanism); + gchar *(*encode_data) (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); + gchar *(*decode_data) (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); + + /* functions for server-side authentication */ + GDBusAuthMechanismState (*server_get_state) (GDBusAuthMechanism *mechanism); + void (*server_initiate) (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len); + void (*server_data_receive) (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); + gchar *(*server_data_send) (GDBusAuthMechanism *mechanism, + gsize *out_data_len); + gchar *(*server_get_reject_reason) (GDBusAuthMechanism *mechanism); + void (*server_shutdown) (GDBusAuthMechanism *mechanism); + + /* functions for client-side authentication */ + GDBusAuthMechanismState (*client_get_state) (GDBusAuthMechanism *mechanism); + gchar *(*client_initiate) (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len); + void (*client_data_receive) (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); + gchar *(*client_data_send) (GDBusAuthMechanism *mechanism, + gsize *out_data_len); + void (*client_shutdown) (GDBusAuthMechanism *mechanism); +}; + +struct _GDBusAuthMechanism +{ + GObject parent_instance; + GDBusAuthMechanismPrivate *priv; +}; + +GType _g_dbus_auth_mechanism_get_type (void) G_GNUC_CONST; + +gint _g_dbus_auth_mechanism_get_priority (GType mechanism_type); +const gchar *_g_dbus_auth_mechanism_get_name (GType mechanism_type); + +GIOStream *_g_dbus_auth_mechanism_get_stream (GDBusAuthMechanism *mechanism); +GCredentials *_g_dbus_auth_mechanism_get_credentials (GDBusAuthMechanism *mechanism); + +gboolean _g_dbus_auth_mechanism_is_supported (GDBusAuthMechanism *mechanism); +gchar *_g_dbus_auth_mechanism_encode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); +gchar *_g_dbus_auth_mechanism_decode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); + +GDBusAuthMechanismState _g_dbus_auth_mechanism_server_get_state (GDBusAuthMechanism *mechanism); +void _g_dbus_auth_mechanism_server_initiate (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len); +void _g_dbus_auth_mechanism_server_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); +gchar *_g_dbus_auth_mechanism_server_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len); +gchar *_g_dbus_auth_mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism); +void _g_dbus_auth_mechanism_server_shutdown (GDBusAuthMechanism *mechanism); + +GDBusAuthMechanismState _g_dbus_auth_mechanism_client_get_state (GDBusAuthMechanism *mechanism); +gchar *_g_dbus_auth_mechanism_client_initiate (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len); +void _g_dbus_auth_mechanism_client_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); +gchar *_g_dbus_auth_mechanism_client_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len); +void _g_dbus_auth_mechanism_client_shutdown (GDBusAuthMechanism *mechanism); + + +G_END_DECLS + +#endif /* __G_DBUS_AUTH_MECHANISM_H__ */ diff --git a/gio/gdbusauthmechanismanon.c b/gio/gdbusauthmechanismanon.c new file mode 100644 index 0000000..dd57826 --- /dev/null +++ b/gio/gdbusauthmechanismanon.c @@ -0,0 +1,322 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusauthmechanismanon.h" +#include "gdbuserror.h" +#include "gioenumtypes.h" + +#include "glibintl.h" + +struct _GDBusAuthMechanismAnonPrivate +{ + gboolean is_client; + gboolean is_server; + GDBusAuthMechanismState state; +}; + +static gint mechanism_get_priority (void); +static const gchar *mechanism_get_name (void); + +static gboolean mechanism_is_supported (GDBusAuthMechanism *mechanism); +static gchar *mechanism_encode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); +static gchar *mechanism_decode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); +static GDBusAuthMechanismState mechanism_server_get_state (GDBusAuthMechanism *mechanism); +static void mechanism_server_initiate (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len); +static void mechanism_server_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); +static gchar *mechanism_server_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len); +static gchar *mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism); +static void mechanism_server_shutdown (GDBusAuthMechanism *mechanism); +static GDBusAuthMechanismState mechanism_client_get_state (GDBusAuthMechanism *mechanism); +static gchar *mechanism_client_initiate (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len); +static void mechanism_client_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); +static gchar *mechanism_client_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len); +static void mechanism_client_shutdown (GDBusAuthMechanism *mechanism); + +/* ---------------------------------------------------------------------------------------------------- */ + +G_DEFINE_TYPE_WITH_PRIVATE (GDBusAuthMechanismAnon, _g_dbus_auth_mechanism_anon, G_TYPE_DBUS_AUTH_MECHANISM) + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +_g_dbus_auth_mechanism_anon_finalize (GObject *object) +{ + //GDBusAuthMechanismAnon *mechanism = G_DBUS_AUTH_MECHANISM_ANON (object); + + if (G_OBJECT_CLASS (_g_dbus_auth_mechanism_anon_parent_class)->finalize != NULL) + G_OBJECT_CLASS (_g_dbus_auth_mechanism_anon_parent_class)->finalize (object); +} + +static void +_g_dbus_auth_mechanism_anon_class_init (GDBusAuthMechanismAnonClass *klass) +{ + GObjectClass *gobject_class; + GDBusAuthMechanismClass *mechanism_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = _g_dbus_auth_mechanism_anon_finalize; + + mechanism_class = G_DBUS_AUTH_MECHANISM_CLASS (klass); + mechanism_class->get_priority = mechanism_get_priority; + mechanism_class->get_name = mechanism_get_name; + mechanism_class->is_supported = mechanism_is_supported; + mechanism_class->encode_data = mechanism_encode_data; + mechanism_class->decode_data = mechanism_decode_data; + mechanism_class->server_get_state = mechanism_server_get_state; + mechanism_class->server_initiate = mechanism_server_initiate; + mechanism_class->server_data_receive = mechanism_server_data_receive; + mechanism_class->server_data_send = mechanism_server_data_send; + mechanism_class->server_get_reject_reason = mechanism_server_get_reject_reason; + mechanism_class->server_shutdown = mechanism_server_shutdown; + mechanism_class->client_get_state = mechanism_client_get_state; + mechanism_class->client_initiate = mechanism_client_initiate; + mechanism_class->client_data_receive = mechanism_client_data_receive; + mechanism_class->client_data_send = mechanism_client_data_send; + mechanism_class->client_shutdown = mechanism_client_shutdown; +} + +static void +_g_dbus_auth_mechanism_anon_init (GDBusAuthMechanismAnon *mechanism) +{ + mechanism->priv = _g_dbus_auth_mechanism_anon_get_instance_private (mechanism); +} + +/* ---------------------------------------------------------------------------------------------------- */ + + +static gint +mechanism_get_priority (void) +{ + /* We prefer ANONYMOUS to most other mechanism (such as DBUS_COOKIE_SHA1) but not to EXTERNAL */ + return 50; +} + + +static const gchar * +mechanism_get_name (void) +{ + return "ANONYMOUS"; +} + +static gboolean +mechanism_is_supported (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), FALSE); + return TRUE; +} + +static gchar * +mechanism_encode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len) +{ + return NULL; +} + + +static gchar * +mechanism_decode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len) +{ + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAuthMechanismState +mechanism_server_get_state (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, G_DBUS_AUTH_MECHANISM_STATE_INVALID); + + return m->priv->state; +} + +static void +mechanism_server_initiate (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism)); + g_return_if_fail (!m->priv->is_server && !m->priv->is_client); + + //g_debug ("ANONYMOUS: initial_response was '%s'", initial_response); + + m->priv->is_server = TRUE; + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED; +} + +static void +mechanism_server_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism)); + g_return_if_fail (m->priv->is_server && !m->priv->is_client); + g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA); + + /* can never end up here because we are never in the WAITING_FOR_DATA state */ + g_assert_not_reached (); +} + +static gchar * +mechanism_server_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL); + g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL); + + /* can never end up here because we are never in the HAVE_DATA_TO_SEND state */ + g_assert_not_reached (); + + return NULL; +} + +static gchar * +mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL); + g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED, NULL); + + /* can never end up here because we are never in the REJECTED state */ + g_assert_not_reached (); + + return NULL; +} + +static void +mechanism_server_shutdown (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism)); + g_return_if_fail (m->priv->is_server && !m->priv->is_client); + + m->priv->is_server = FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAuthMechanismState +mechanism_client_get_state (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID); + g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, G_DBUS_AUTH_MECHANISM_STATE_INVALID); + + return m->priv->state; +} + +static gchar * +mechanism_client_initiate (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + gchar *result; + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL); + g_return_val_if_fail (!m->priv->is_server && !m->priv->is_client, NULL); + + m->priv->is_client = TRUE; + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED; + + /* just return our library name and version */ + result = g_strdup ("GDBus 0.1"); + *out_initial_response_len = strlen (result); + + return result; +} + +static void +mechanism_client_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism)); + g_return_if_fail (m->priv->is_client && !m->priv->is_server); + g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA); + + /* can never end up here because we are never in the WAITING_FOR_DATA state */ + g_assert_not_reached (); +} + +static gchar * +mechanism_client_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL); + g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, NULL); + g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL); + + /* can never end up here because we are never in the HAVE_DATA_TO_SEND state */ + g_assert_not_reached (); + + return NULL; +} + +static void +mechanism_client_shutdown (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism)); + g_return_if_fail (m->priv->is_client && !m->priv->is_server); + + m->priv->is_client = FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusauthmechanismanon.h b/gio/gdbusauthmechanismanon.h new file mode 100644 index 0000000..2968159 --- /dev/null +++ b/gio/gdbusauthmechanismanon.h @@ -0,0 +1,61 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_AUTH_MECHANISM_ANON_H__ +#define __G_DBUS_AUTH_MECHANISM_ANON_H__ + +#if !defined (GIO_COMPILATION) +#error "gdbusauthmechanismanon.h is a private header file." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_AUTH_MECHANISM_ANON (_g_dbus_auth_mechanism_anon_get_type ()) +#define G_DBUS_AUTH_MECHANISM_ANON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_AUTH_MECHANISM_ANON, GDBusAuthMechanismAnon)) +#define G_DBUS_AUTH_MECHANISM_ANON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_AUTH_MECHANISM_ANON, GDBusAuthMechanismAnonClass)) +#define G_DBUS_AUTH_MECHANISM_ANON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_AUTH_MECHANISM_ANON, GDBusAuthMechanismAnonClass)) +#define G_IS_DBUS_AUTH_MECHANISM_ANON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_AUTH_MECHANISM_ANON)) +#define G_IS_DBUS_AUTH_MECHANISM_ANON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_AUTH_MECHANISM_ANON)) + +typedef struct _GDBusAuthMechanismAnon GDBusAuthMechanismAnon; +typedef struct _GDBusAuthMechanismAnonClass GDBusAuthMechanismAnonClass; +typedef struct _GDBusAuthMechanismAnonPrivate GDBusAuthMechanismAnonPrivate; + +struct _GDBusAuthMechanismAnonClass +{ + /*< private >*/ + GDBusAuthMechanismClass parent_class; +}; + +struct _GDBusAuthMechanismAnon +{ + GDBusAuthMechanism parent_instance; + GDBusAuthMechanismAnonPrivate *priv; +}; + +GType _g_dbus_auth_mechanism_anon_get_type (void) G_GNUC_CONST; + + +G_END_DECLS + +#endif /* __G_DBUS_AUTH_MECHANISM_ANON_H__ */ diff --git a/gio/gdbusauthmechanismexternal.c b/gio/gdbusauthmechanismexternal.c new file mode 100644 index 0000000..70aaddc --- /dev/null +++ b/gio/gdbusauthmechanismexternal.c @@ -0,0 +1,443 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include + +#include "gdbusauthmechanismexternal.h" +#include "gcredentials.h" +#include "gdbuserror.h" +#include "gioenumtypes.h" + +#include "glibintl.h" + +#ifdef G_OS_WIN32 +#include "gwin32sid.h" +#endif + +struct _GDBusAuthMechanismExternalPrivate +{ + gboolean is_client; + gboolean is_server; + GDBusAuthMechanismState state; + gboolean empty_data_sent; +}; + +static gint mechanism_get_priority (void); +static const gchar *mechanism_get_name (void); + +static gboolean mechanism_is_supported (GDBusAuthMechanism *mechanism); +static gchar *mechanism_encode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); +static gchar *mechanism_decode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); +static GDBusAuthMechanismState mechanism_server_get_state (GDBusAuthMechanism *mechanism); +static void mechanism_server_initiate (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len); +static void mechanism_server_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); +static gchar *mechanism_server_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len); +static gchar *mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism); +static void mechanism_server_shutdown (GDBusAuthMechanism *mechanism); +static GDBusAuthMechanismState mechanism_client_get_state (GDBusAuthMechanism *mechanism); +static gchar *mechanism_client_initiate (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len); +static void mechanism_client_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); +static gchar *mechanism_client_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len); +static void mechanism_client_shutdown (GDBusAuthMechanism *mechanism); + +/* ---------------------------------------------------------------------------------------------------- */ + +G_DEFINE_TYPE_WITH_PRIVATE (GDBusAuthMechanismExternal, _g_dbus_auth_mechanism_external, G_TYPE_DBUS_AUTH_MECHANISM) + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +_g_dbus_auth_mechanism_external_finalize (GObject *object) +{ + //GDBusAuthMechanismExternal *mechanism = G_DBUS_AUTH_MECHANISM_EXTERNAL (object); + + if (G_OBJECT_CLASS (_g_dbus_auth_mechanism_external_parent_class)->finalize != NULL) + G_OBJECT_CLASS (_g_dbus_auth_mechanism_external_parent_class)->finalize (object); +} + +static void +_g_dbus_auth_mechanism_external_class_init (GDBusAuthMechanismExternalClass *klass) +{ + GObjectClass *gobject_class; + GDBusAuthMechanismClass *mechanism_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = _g_dbus_auth_mechanism_external_finalize; + + mechanism_class = G_DBUS_AUTH_MECHANISM_CLASS (klass); + mechanism_class->get_name = mechanism_get_name; + mechanism_class->get_priority = mechanism_get_priority; + mechanism_class->is_supported = mechanism_is_supported; + mechanism_class->encode_data = mechanism_encode_data; + mechanism_class->decode_data = mechanism_decode_data; + mechanism_class->server_get_state = mechanism_server_get_state; + mechanism_class->server_initiate = mechanism_server_initiate; + mechanism_class->server_data_receive = mechanism_server_data_receive; + mechanism_class->server_data_send = mechanism_server_data_send; + mechanism_class->server_get_reject_reason = mechanism_server_get_reject_reason; + mechanism_class->server_shutdown = mechanism_server_shutdown; + mechanism_class->client_get_state = mechanism_client_get_state; + mechanism_class->client_initiate = mechanism_client_initiate; + mechanism_class->client_data_receive = mechanism_client_data_receive; + mechanism_class->client_data_send = mechanism_client_data_send; + mechanism_class->client_shutdown = mechanism_client_shutdown; +} + +static void +_g_dbus_auth_mechanism_external_init (GDBusAuthMechanismExternal *mechanism) +{ + mechanism->priv = _g_dbus_auth_mechanism_external_get_instance_private (mechanism); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +mechanism_is_supported (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), FALSE); + +#if defined(G_OS_WIN32) + /* all that is required is current process SID */ + return TRUE; +#else + /* This mechanism is only available if credentials has been exchanged */ + if (_g_dbus_auth_mechanism_get_credentials (mechanism) != NULL) + return TRUE; + else + return FALSE; +#endif +} + +static gint +mechanism_get_priority (void) +{ + /* We prefer EXTERNAL to most other mechanism (DBUS_COOKIE_SHA1 and ANONYMOUS) */ + return 100; +} + +static const gchar * +mechanism_get_name (void) +{ + return "EXTERNAL"; +} + +static gchar * +mechanism_encode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len) +{ + return NULL; +} + + +static gchar * +mechanism_decode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len) +{ + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAuthMechanismState +mechanism_server_get_state (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, G_DBUS_AUTH_MECHANISM_STATE_INVALID); + + return m->priv->state; +} + +static gboolean +data_matches_credentials (const gchar *data, + gsize data_len, + GCredentials *credentials) +{ + gboolean match; + + match = FALSE; + + if (credentials == NULL) + goto out; + +#if defined(G_OS_UNIX) + { + gint64 alleged_uid; + gchar *endp; + + /* If we were unable to find out the uid, then nothing + * can possibly match it. */ + if (g_credentials_get_unix_user (credentials, NULL) == (uid_t) -1) + goto out; + + /* An empty authorization identity means we want to be + * whatever identity the out-of-band credentials say we have + * (RFC 4422 appendix A.1). This effectively matches any uid. */ + if (data == NULL || data_len == 0) + { + match = TRUE; + goto out; + } + /* on UNIX, this is the uid as a string in base 10 */ + alleged_uid = g_ascii_strtoll (data, &endp, 10); + if (*endp == '\0') + { + if (g_credentials_get_unix_user (credentials, NULL) == alleged_uid) + { + match = TRUE; + } + } + } +#else + /* TODO: Dont know how to compare credentials on this OS. Please implement. */ +#endif + + out: + return match; +} + +static void +mechanism_server_initiate (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism)); + g_return_if_fail (!m->priv->is_server && !m->priv->is_client); + + m->priv->is_server = TRUE; + + if (initial_response != NULL) + { + if (data_matches_credentials (initial_response, + initial_response_len, + _g_dbus_auth_mechanism_get_credentials (mechanism))) + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED; + } + else + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + } + } + else + { + /* The initial-response optimization was not used, so we need to + * send an empty challenge to prompt the client to respond. */ + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND; + } +} + +static void +mechanism_server_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism)); + g_return_if_fail (m->priv->is_server && !m->priv->is_client); + g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA); + + if (data_matches_credentials (data, + data_len, + _g_dbus_auth_mechanism_get_credentials (mechanism))) + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED; + } + else + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + } +} + +static gchar * +mechanism_server_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL); + + if (out_data_len) + *out_data_len = 0; + + if (m->priv->empty_data_sent) + { + /* We have already sent an empty data response. + Reject the connection. */ + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + return NULL; + } + + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA; + m->priv->empty_data_sent = TRUE; + + return g_strdup (""); +} + +static gchar * +mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL); + g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED, NULL); + + /* can never end up here because we are never in the REJECTED state */ + g_assert_not_reached (); + + return NULL; +} + +static void +mechanism_server_shutdown (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism)); + g_return_if_fail (m->priv->is_server && !m->priv->is_client); + + m->priv->is_server = FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAuthMechanismState +mechanism_client_get_state (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID); + g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, G_DBUS_AUTH_MECHANISM_STATE_INVALID); + + return m->priv->state; +} + +static gchar * +mechanism_client_initiate (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + gchar *initial_response = NULL; +#if defined(G_OS_UNIX) + GCredentials *credentials; +#endif + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL); + g_return_val_if_fail (!m->priv->is_server && !m->priv->is_client, NULL); + + m->priv->is_client = TRUE; + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + + *out_initial_response_len = 0; + + /* return the uid */ +#if defined(G_OS_UNIX) + credentials = _g_dbus_auth_mechanism_get_credentials (mechanism); + g_assert (credentials != NULL); + + initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) g_credentials_get_unix_user (credentials, NULL)); +#elif defined(G_OS_WIN32) + initial_response = _g_win32_current_process_sid_string (NULL); +#else +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic warning "-Wcpp" +#warning Dont know how to send credentials on this OS. The EXTERNAL D-Bus authentication mechanism will not work. +#pragma GCC diagnostic pop +#endif +#endif + if (initial_response) + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED; + *out_initial_response_len = strlen (initial_response); + } + return initial_response; +} + +static void +mechanism_client_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism)); + g_return_if_fail (m->priv->is_client && !m->priv->is_server); + g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA); + + /* can never end up here because we are never in the WAITING_FOR_DATA state */ + g_assert_not_reached (); +} + +static gchar * +mechanism_client_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL); + g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, NULL); + g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL); + + /* can never end up here because we are never in the HAVE_DATA_TO_SEND state */ + g_assert_not_reached (); + + return NULL; +} + +static void +mechanism_client_shutdown (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism)); + g_return_if_fail (m->priv->is_client && !m->priv->is_server); + + m->priv->is_client = FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusauthmechanismexternal.h b/gio/gdbusauthmechanismexternal.h new file mode 100644 index 0000000..4408db9 --- /dev/null +++ b/gio/gdbusauthmechanismexternal.h @@ -0,0 +1,61 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_AUTH_MECHANISM_EXTERNAL_H__ +#define __G_DBUS_AUTH_MECHANISM_EXTERNAL_H__ + +#if !defined (GIO_COMPILATION) +#error "gdbusauthmechanismexternal.h is a private header file." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL (_g_dbus_auth_mechanism_external_get_type ()) +#define G_DBUS_AUTH_MECHANISM_EXTERNAL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL, GDBusAuthMechanismExternal)) +#define G_DBUS_AUTH_MECHANISM_EXTERNAL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL, GDBusAuthMechanismExternalClass)) +#define G_DBUS_AUTH_MECHANISM_EXTERNAL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL, GDBusAuthMechanismExternalClass)) +#define G_IS_DBUS_AUTH_MECHANISM_EXTERNAL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL)) +#define G_IS_DBUS_AUTH_MECHANISM_EXTERNAL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL)) + +typedef struct _GDBusAuthMechanismExternal GDBusAuthMechanismExternal; +typedef struct _GDBusAuthMechanismExternalClass GDBusAuthMechanismExternalClass; +typedef struct _GDBusAuthMechanismExternalPrivate GDBusAuthMechanismExternalPrivate; + +struct _GDBusAuthMechanismExternalClass +{ + /*< private >*/ + GDBusAuthMechanismClass parent_class; +}; + +struct _GDBusAuthMechanismExternal +{ + GDBusAuthMechanism parent_instance; + GDBusAuthMechanismExternalPrivate *priv; +}; + +GType _g_dbus_auth_mechanism_external_get_type (void) G_GNUC_CONST; + + +G_END_DECLS + +#endif /* __G_DBUS_AUTH_MECHANISM_EXTERNAL_H__ */ diff --git a/gio/gdbusauthmechanismsha1.c b/gio/gdbusauthmechanismsha1.c new file mode 100644 index 0000000..ed5aa3f --- /dev/null +++ b/gio/gdbusauthmechanismsha1.c @@ -0,0 +1,1290 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include +#include "gwin32sid.h" +#endif + +#include "gdbusauthmechanismsha1.h" +#include "gcredentials.h" +#include "gdbuserror.h" +#include "glocalfileinfo.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include "gdbusprivate.h" +#include "glib-private.h" + +#include "glibintl.h" + +/* + * Arbitrary timeouts for keys in the keyring. + * For interoperability, these match the reference implementation, libdbus. + * To make them easier to compare, their names also match libdbus + * (see dbus/dbus-keyring.c). + */ + +/* + * Maximum age of a key before we create a new key to use in challenges: + * 5 minutes. + */ +#define NEW_KEY_TIMEOUT_SECONDS (60*5) + +/* + * Time before we drop a key from the keyring: 7 minutes. + * Authentication will succeed if it takes less than + * EXPIRE_KEYS_TIMEOUT_SECONDS - NEW_KEY_TIMEOUT_SECONDS (2 minutes) + * to complete. + * The spec says "delete any cookies that are old (the timeout can be + * fairly short)". + */ +#define EXPIRE_KEYS_TIMEOUT_SECONDS (NEW_KEY_TIMEOUT_SECONDS + (60*2)) + +/* + * Maximum amount of time a key can be in the future due to clock skew + * with a shared home directory: 5 minutes. + * The spec says "a reasonable time in the future". + */ +#define MAX_TIME_TRAVEL_SECONDS (60*5) + + +struct _GDBusAuthMechanismSha1Private +{ + gboolean is_client; + gboolean is_server; + GDBusAuthMechanismState state; + gchar *reject_reason; /* non-NULL iff (state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED) */ + + /* used on the client side */ + gchar *to_send; + + /* used on the server side */ + gchar *cookie; + gchar *server_challenge; +}; + +static gint mechanism_get_priority (void); +static const gchar *mechanism_get_name (void); + +static gboolean mechanism_is_supported (GDBusAuthMechanism *mechanism); +static gchar *mechanism_encode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); +static gchar *mechanism_decode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len); +static GDBusAuthMechanismState mechanism_server_get_state (GDBusAuthMechanism *mechanism); +static void mechanism_server_initiate (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len); +static void mechanism_server_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); +static gchar *mechanism_server_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len); +static gchar *mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism); +static void mechanism_server_shutdown (GDBusAuthMechanism *mechanism); +static GDBusAuthMechanismState mechanism_client_get_state (GDBusAuthMechanism *mechanism); +static gchar *mechanism_client_initiate (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len); +static void mechanism_client_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len); +static gchar *mechanism_client_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len); +static void mechanism_client_shutdown (GDBusAuthMechanism *mechanism); + +/* ---------------------------------------------------------------------------------------------------- */ + +G_DEFINE_TYPE_WITH_PRIVATE (GDBusAuthMechanismSha1, _g_dbus_auth_mechanism_sha1, G_TYPE_DBUS_AUTH_MECHANISM) + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +_g_dbus_auth_mechanism_sha1_finalize (GObject *object) +{ + GDBusAuthMechanismSha1 *mechanism = G_DBUS_AUTH_MECHANISM_SHA1 (object); + + g_free (mechanism->priv->reject_reason); + g_free (mechanism->priv->to_send); + + g_free (mechanism->priv->cookie); + g_free (mechanism->priv->server_challenge); + + if (G_OBJECT_CLASS (_g_dbus_auth_mechanism_sha1_parent_class)->finalize != NULL) + G_OBJECT_CLASS (_g_dbus_auth_mechanism_sha1_parent_class)->finalize (object); +} + +static void +_g_dbus_auth_mechanism_sha1_class_init (GDBusAuthMechanismSha1Class *klass) +{ + GObjectClass *gobject_class; + GDBusAuthMechanismClass *mechanism_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = _g_dbus_auth_mechanism_sha1_finalize; + + mechanism_class = G_DBUS_AUTH_MECHANISM_CLASS (klass); + mechanism_class->get_priority = mechanism_get_priority; + mechanism_class->get_name = mechanism_get_name; + mechanism_class->is_supported = mechanism_is_supported; + mechanism_class->encode_data = mechanism_encode_data; + mechanism_class->decode_data = mechanism_decode_data; + mechanism_class->server_get_state = mechanism_server_get_state; + mechanism_class->server_initiate = mechanism_server_initiate; + mechanism_class->server_data_receive = mechanism_server_data_receive; + mechanism_class->server_data_send = mechanism_server_data_send; + mechanism_class->server_get_reject_reason = mechanism_server_get_reject_reason; + mechanism_class->server_shutdown = mechanism_server_shutdown; + mechanism_class->client_get_state = mechanism_client_get_state; + mechanism_class->client_initiate = mechanism_client_initiate; + mechanism_class->client_data_receive = mechanism_client_data_receive; + mechanism_class->client_data_send = mechanism_client_data_send; + mechanism_class->client_shutdown = mechanism_client_shutdown; +} + +static void +_g_dbus_auth_mechanism_sha1_init (GDBusAuthMechanismSha1 *mechanism) +{ + mechanism->priv = _g_dbus_auth_mechanism_sha1_get_instance_private (mechanism); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gint +mechanism_get_priority (void) +{ + return 0; +} + +static const gchar * +mechanism_get_name (void) +{ + return "DBUS_COOKIE_SHA1"; +} + +static gboolean +mechanism_is_supported (GDBusAuthMechanism *mechanism) +{ + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), FALSE); + return TRUE; +} + +static gchar * +mechanism_encode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len) +{ + return NULL; +} + + +static gchar * +mechanism_decode_data (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len, + gsize *out_data_len) +{ + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gint +random_ascii (void) +{ + gint ret; + ret = g_random_int_range (0, 60); + if (ret < 25) + ret += 'A'; + else if (ret < 50) + ret += 'a' - 25; + else + ret += '0' - 50; + return ret; +} + +static gchar * +random_ascii_string (guint len) +{ + GString *challenge; + guint n; + + challenge = g_string_new (NULL); + for (n = 0; n < len; n++) + g_string_append_c (challenge, random_ascii ()); + return g_string_free (challenge, FALSE); +} + +static gchar * +random_blob (guint len) +{ + GString *challenge; + guint n; + + challenge = g_string_new (NULL); + for (n = 0; n < len; n++) + g_string_append_c (challenge, g_random_int_range (0, 256)); + return g_string_free (challenge, FALSE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* ensure keyring dir exists and permissions are correct */ +static gchar * +ensure_keyring_directory (GError **error) +{ + gchar *path; + const gchar *e; + gboolean is_setuid; +#ifdef G_OS_UNIX + struct stat statbuf; +#endif + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + e = g_getenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR"); + if (e != NULL) + { + path = g_strdup (e); + } + else + { + path = g_build_filename (g_get_home_dir (), + ".dbus-keyrings", + NULL); + } + +#ifdef G_OS_UNIX + if (stat (path, &statbuf) != 0) + { + int errsv = errno; + + if (errsv != ENOENT) + { + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error when getting information for directory “%sâ€: %s"), + path, + g_strerror (errsv)); + g_clear_pointer (&path, g_free); + return NULL; + } + } + else if (S_ISDIR (statbuf.st_mode)) + { + if (g_getenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION") == NULL && + (statbuf.st_mode & 0777) != 0700) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o"), + path, + (guint) (statbuf.st_mode & 0777)); + g_clear_pointer (&path, g_free); + return NULL; + } + + return g_steal_pointer (&path); + } +#else /* if !G_OS_UNIX */ + /* On non-Unix platforms, check that it exists as a directory, but don’t do + * permissions checks at the moment. */ + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) + { +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic warning "-Wcpp" +#warning Please implement permission checking on this non-UNIX platform +#pragma GCC diagnostic pop +#endif /* __GNUC__ */ + return g_steal_pointer (&path); + } +#endif /* if !G_OS_UNIX */ + + /* Only create the directory if not running as setuid */ + is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) (); + if (!is_setuid && + g_mkdir_with_parents (path, 0700) != 0) + { + int errsv = errno; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error creating directory “%sâ€: %s"), + path, + g_strerror (errsv)); + g_clear_pointer (&path, g_free); + return NULL; + } + else if (is_setuid) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED, + _("Error creating directory “%sâ€: %s"), + path, + _("Operation not supported")); + g_clear_pointer (&path, g_free); + return NULL; + } + + return g_steal_pointer (&path); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* looks up an entry in the keyring */ +static gchar * +keyring_lookup_entry (const gchar *cookie_context, + gint cookie_id, + GError **error) +{ + gchar *ret; + gchar *keyring_dir; + gchar *contents; + gchar *path; + guint n; + gchar **lines; + + g_return_val_if_fail (cookie_context != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + ret = NULL; + path = NULL; + contents = NULL; + lines = NULL; + + keyring_dir = ensure_keyring_directory (error); + if (keyring_dir == NULL) + goto out; + + path = g_build_filename (keyring_dir, cookie_context, NULL); + + if (!g_file_get_contents (path, + &contents, + NULL, + error)) + { + g_prefix_error (error, + _("Error opening keyring “%s†for reading: "), + path); + goto out; + } + g_assert (contents != NULL); + + lines = g_strsplit (contents, "\n", 0); + for (n = 0; lines[n] != NULL; n++) + { + const gchar *line = lines[n]; + gchar **tokens; + gchar *endp; + gint line_id; + + if (line[0] == '\0') + continue; + + tokens = g_strsplit (line, " ", 0); + if (g_strv_length (tokens) != 3) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Line %d of the keyring at “%s†with content “%s†is malformed"), + n + 1, + path, + line); + g_strfreev (tokens); + goto out; + } + + line_id = g_ascii_strtoll (tokens[0], &endp, 10); + if (*endp != '\0') + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("First token of line %d of the keyring at “%s†with content “%s†is malformed"), + n + 1, + path, + line); + g_strfreev (tokens); + goto out; + } + + (void)g_ascii_strtoll (tokens[1], &endp, 10); /* do not care what the timestamp is */ + if (*endp != '\0') + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Second token of line %d of the keyring at “%s†with content “%s†is malformed"), + n + 1, + path, + line); + g_strfreev (tokens); + goto out; + } + + if (line_id == cookie_id) + { + /* YAY, success */ + ret = tokens[2]; /* steal pointer */ + tokens[2] = NULL; + g_strfreev (tokens); + goto out; + } + + g_strfreev (tokens); + } + + /* BOOH, didn't find the cookie */ + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Didn’t find cookie with id %d in the keyring at “%sâ€"), + cookie_id, + path); + + out: + g_free (keyring_dir); + g_free (path); + g_free (contents); + g_strfreev (lines); + return ret; +} + +/* function for logging important events that the system administrator should take notice of */ +G_GNUC_PRINTF(1, 2) +static void +_log (const gchar *message, + ...) +{ + gchar *s; + va_list var_args; + + va_start (var_args, message); + s = g_strdup_vprintf (message, var_args); + va_end (var_args); + + /* TODO: might want to send this to syslog instead */ + g_printerr ("GDBus-DBUS_COOKIE_SHA1: %s\n", s); + g_free (s); +} + +/* Returns FD for lock file, if it was created exclusively (didn't exist already, + * and was created successfully) */ +static gint +create_lock_exclusive (const gchar *lock_path, + gint64 *mtime_nsec, + GError **error) +{ + int errsv; + gint ret; + + ret = g_open (lock_path, O_CREAT | O_EXCL, 0600); + errsv = errno; + if (ret < 0) + { + GLocalFileStat stat_buf; + + /* Get the modification time to distinguish between the lock being stale + * or highly contested. */ + if (mtime_nsec != NULL && + g_local_file_stat (lock_path, G_LOCAL_FILE_STAT_FIELD_MTIME, G_LOCAL_FILE_STAT_FIELD_ALL, &stat_buf) == 0) + *mtime_nsec = _g_stat_mtime (&stat_buf) * G_USEC_PER_SEC * 1000 + _g_stat_mtim_nsec (&stat_buf); + else if (mtime_nsec != NULL) + *mtime_nsec = 0; + + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error creating lock file “%sâ€: %s"), + lock_path, + g_strerror (errsv)); + return -1; + } + + return ret; +} + +static gint +keyring_acquire_lock (const gchar *path, + GError **error) +{ + gchar *lock = NULL; + gint ret; + guint num_tries; + int errsv; + gint64 lock_mtime_nsec = 0, lock_mtime_nsec_prev = 0; + + /* Total possible sleep period = max_tries * timeout_usec = 0.5s */ + const guint max_tries = 50; + const guint timeout_usec = 1000 * 10; + + g_return_val_if_fail (path != NULL, -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + ret = -1; + lock = g_strconcat (path, ".lock", NULL); + + /* This is what the D-Bus spec says + * (https://dbus.freedesktop.org/doc/dbus-specification.html#auth-mechanisms-sha) + * + * Create a lockfile name by appending ".lock" to the name of the + * cookie file. The server should attempt to create this file using + * O_CREAT | O_EXCL. If file creation fails, the lock + * fails. Servers should retry for a reasonable period of time, + * then they may choose to delete an existing lock to keep users + * from having to manually delete a stale lock. [1] + * + * [1] : Lockfiles are used instead of real file locking fcntl() because + * real locking implementations are still flaky on network filesystems + */ + + for (num_tries = 0; num_tries < max_tries; num_tries++) + { + lock_mtime_nsec_prev = lock_mtime_nsec; + + /* Ignore the error until the final call. */ + ret = create_lock_exclusive (lock, &lock_mtime_nsec, NULL); + if (ret >= 0) + break; + + /* sleep 10ms, then try again */ + g_usleep (timeout_usec); + + /* If the mtime of the lock file changed, don’t count the retry, as it + * seems like there’s contention between processes for the lock file, + * rather than a stale lock file from a crashed process. */ + if (num_tries > 0 && lock_mtime_nsec != lock_mtime_nsec_prev) + num_tries--; + } + + if (num_tries == max_tries) + { + /* ok, we slept 50*10ms = 0.5 seconds. Conclude that the lock file must be + * stale (nuke it from orbit) + */ + if (g_unlink (lock) != 0) + { + errsv = errno; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error deleting stale lock file “%sâ€: %s"), + lock, + g_strerror (errsv)); + goto out; + } + + _log ("Deleted stale lock file '%s'", lock); + + /* Try one last time to create it, now that we've deleted the stale one */ + ret = create_lock_exclusive (lock, NULL, error); + if (ret < 0) + goto out; + } + +out: + g_free (lock); + return ret; +} + +static gboolean +keyring_release_lock (const gchar *path, + gint lock_fd, + GError **error) +{ + gchar *lock; + gboolean ret; + + g_return_val_if_fail (path != NULL, FALSE); + g_return_val_if_fail (lock_fd != -1, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; + lock = g_strdup_printf ("%s.lock", path); + if (close (lock_fd) != 0) + { + int errsv = errno; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error closing (unlinked) lock file “%sâ€: %s"), + lock, + g_strerror (errsv)); + goto out; + } + if (g_unlink (lock) != 0) + { + int errsv = errno; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error unlinking lock file “%sâ€: %s"), + lock, + g_strerror (errsv)); + goto out; + } + + ret = TRUE; + + out: + g_free (lock); + return ret; +} + + +/* adds an entry to the keyring, taking care of locking and deleting stale/future entries */ +static gboolean +keyring_generate_entry (const gchar *cookie_context, + gint *out_id, + gchar **out_cookie, + GError **error) +{ + gboolean ret; + gchar *keyring_dir; + gchar *path; + gchar *contents; + GError *local_error; + gchar **lines; + gint max_line_id; + GString *new_contents; + gint64 now; + gboolean have_id; + gint use_id; + gchar *use_cookie; + gboolean changed_file; + gint lock_fd; + + g_return_val_if_fail (cookie_context != NULL, FALSE); + g_return_val_if_fail (out_id != NULL, FALSE); + g_return_val_if_fail (out_cookie != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; + path = NULL; + contents = NULL; + lines = NULL; + new_contents = NULL; + have_id = FALSE; + use_id = 0; + use_cookie = NULL; + lock_fd = -1; + + keyring_dir = ensure_keyring_directory (error); + if (keyring_dir == NULL) + goto out; + + path = g_build_filename (keyring_dir, cookie_context, NULL); + + lock_fd = keyring_acquire_lock (path, error); + if (lock_fd == -1) + goto out; + + local_error = NULL; + contents = NULL; + if (!g_file_get_contents (path, + &contents, + NULL, + &local_error)) + { + if (local_error->domain == G_FILE_ERROR && local_error->code == G_FILE_ERROR_NOENT) + { + /* file doesn't have to exist */ + g_error_free (local_error); + } + else + { + g_propagate_prefixed_error (error, + local_error, + _("Error opening keyring “%s†for writing: "), + path); + goto out; + } + } + + new_contents = g_string_new (NULL); + now = g_get_real_time () / G_USEC_PER_SEC; + changed_file = FALSE; + + max_line_id = 0; + if (contents != NULL) + { + guint n; + lines = g_strsplit (contents, "\n", 0); + for (n = 0; lines[n] != NULL; n++) + { + const gchar *line = lines[n]; + gchar **tokens; + gchar *endp; + gint line_id; + gint64 line_when; + gboolean keep_entry; + + if (line[0] == '\0') + continue; + + tokens = g_strsplit (line, " ", 0); + if (g_strv_length (tokens) != 3) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Line %d of the keyring at “%s†with content “%s†is malformed"), + n + 1, + path, + line); + g_strfreev (tokens); + goto out; + } + + line_id = g_ascii_strtoll (tokens[0], &endp, 10); + if (*endp != '\0') + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("First token of line %d of the keyring at “%s†with content “%s†is malformed"), + n + 1, + path, + line); + g_strfreev (tokens); + goto out; + } + + line_when = g_ascii_strtoll (tokens[1], &endp, 10); + if (*endp != '\0') + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Second token of line %d of the keyring at “%s†with content “%s†is malformed"), + n + 1, + path, + line); + g_strfreev (tokens); + goto out; + } + + + /* D-Bus spec says: + * + * Once the lockfile has been created, the server loads the + * cookie file. It should then delete any cookies that are + * old (the timeout can be fairly short), or more than a + * reasonable time in the future (so that cookies never + * accidentally become permanent, if the clock was set far + * into the future at some point). If no recent keys remain, + * the server may generate a new key. + * + */ + keep_entry = TRUE; + if (line_when > now) + { + /* Oddball case: entry is more recent than our current wall-clock time.. + * This is OK, it means that another server on another machine but with + * same $HOME wrote the entry. */ + if (line_when - now > MAX_TIME_TRAVEL_SECONDS) + { + keep_entry = FALSE; + _log ("Deleted SHA1 cookie from %" G_GUINT64_FORMAT " seconds in the future", line_when - now); + } + } + else + { + /* Discard entry if it's too old. */ + if (now - line_when > EXPIRE_KEYS_TIMEOUT_SECONDS) + { + keep_entry = FALSE; + } + } + + if (!keep_entry) + { + changed_file = FALSE; + } + else + { + g_string_append_printf (new_contents, + "%d %" G_GUINT64_FORMAT " %s\n", + line_id, + line_when, + tokens[2]); + max_line_id = MAX (line_id, max_line_id); + /* Only reuse entry if not older than 5 minutes. + * + * (We need a bit of grace time compared to 7 minutes above.. otherwise + * there's a race where we reuse the 6min59.9 secs old entry and a + * split-second later another server purges the now 7 minute old entry.) + */ + if (now - line_when < NEW_KEY_TIMEOUT_SECONDS) + { + if (!have_id) + { + use_id = line_id; + use_cookie = tokens[2]; /* steal memory */ + tokens[2] = NULL; + have_id = TRUE; + } + } + } + g_strfreev (tokens); + } + } /* for each line */ + + ret = TRUE; + + if (have_id) + { + *out_id = use_id; + *out_cookie = use_cookie; + use_cookie = NULL; + } + else + { + gchar *raw_cookie; + *out_id = max_line_id + 1; + raw_cookie = random_blob (32); + *out_cookie = _g_dbus_hexencode (raw_cookie, 32); + g_free (raw_cookie); + + g_string_append_printf (new_contents, + "%d %" G_GINT64_FORMAT " %s\n", + *out_id, + g_get_real_time () / G_USEC_PER_SEC, + *out_cookie); + changed_file = TRUE; + } + + /* and now actually write the cookie file if there are changes (this is atomic) */ + if (changed_file) + { + if (!g_file_set_contents_full (path, + new_contents->str, + -1, + G_FILE_SET_CONTENTS_CONSISTENT, + 0600, + error)) + { + *out_id = 0; + g_free (*out_cookie); + *out_cookie = 0; + ret = FALSE; + goto out; + } + } + + out: + + if (lock_fd != -1) + { + GError *local_error; + local_error = NULL; + if (!keyring_release_lock (path, lock_fd, &local_error)) + { + if (error != NULL) + { + if (*error == NULL) + { + *error = local_error; + } + else + { + g_prefix_error (error, + _("(Additionally, releasing the lock for “%s†also failed: %s) "), + path, + local_error->message); + g_error_free (local_error); + } + } + else + { + g_error_free (local_error); + } + } + } + + g_free (keyring_dir); + g_free (path); + g_strfreev (lines); + g_free (contents); + if (new_contents != NULL) + g_string_free (new_contents, TRUE); + g_free (use_cookie); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +generate_sha1 (const gchar *server_challenge, + const gchar *client_challenge, + const gchar *cookie) +{ + GString *str; + gchar *sha1; + + str = g_string_new (server_challenge); + g_string_append_c (str, ':'); + g_string_append (str, client_challenge); + g_string_append_c (str, ':'); + g_string_append (str, cookie); + sha1 = g_compute_checksum_for_string (G_CHECKSUM_SHA1, str->str, -1); + g_string_free (str, TRUE); + + return sha1; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAuthMechanismState +mechanism_server_get_state (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, G_DBUS_AUTH_MECHANISM_STATE_INVALID); + + return m->priv->state; +} + +static void +mechanism_server_initiate (GDBusAuthMechanism *mechanism, + const gchar *initial_response, + gsize initial_response_len) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism)); + g_return_if_fail (!m->priv->is_server && !m->priv->is_client); + + m->priv->is_server = TRUE; + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + + if (initial_response != NULL && initial_response_len > 0) + { +#ifdef G_OS_UNIX + gint64 uid; + gchar *endp; + + uid = g_ascii_strtoll (initial_response, &endp, 10); + if (*endp == '\0') + { + if (uid == getuid ()) + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND; + } + } +#elif defined(G_OS_WIN32) + gchar *sid; + + sid = _g_win32_current_process_sid_string (NULL); + + if (g_strcmp0 (initial_response, sid) == 0) + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND; + + g_free (sid); +#else +#error Please implement for your OS +#endif + } +} + +static void +mechanism_server_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + gchar **tokens; + const gchar *client_challenge; + const gchar *alleged_sha1; + gchar *sha1; + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism)); + g_return_if_fail (m->priv->is_server && !m->priv->is_client); + g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA); + + tokens = NULL; + sha1 = NULL; + + tokens = g_strsplit (data, " ", 0); + if (g_strv_length (tokens) != 2) + { + g_free (m->priv->reject_reason); + m->priv->reject_reason = g_strdup_printf ("Malformed data '%s'", data); + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + goto out; + } + + client_challenge = tokens[0]; + alleged_sha1 = tokens[1]; + + sha1 = generate_sha1 (m->priv->server_challenge, client_challenge, m->priv->cookie); + + if (g_strcmp0 (sha1, alleged_sha1) == 0) + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED; + } + else + { + g_free (m->priv->reject_reason); + m->priv->reject_reason = g_strdup_printf ("SHA-1 mismatch"); + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + } + + out: + g_strfreev (tokens); + g_free (sha1); +} + +static gchar * +mechanism_server_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + gchar *s; + gint cookie_id; + const gchar *cookie_context; + GError *error; + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), NULL); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL); + g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL); + + s = NULL; + *out_data_len = 0; + + /* TODO: use GDBusAuthObserver here to get the cookie context to use? */ + cookie_context = "org_gtk_gdbus_general"; + + cookie_id = -1; + error = NULL; + if (!keyring_generate_entry (cookie_context, + &cookie_id, + &m->priv->cookie, + &error)) + { + g_free (m->priv->reject_reason); + m->priv->reject_reason = g_strdup_printf ("Error adding entry to keyring: %s", error->message); + g_error_free (error); + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + goto out; + } + + m->priv->server_challenge = random_ascii_string (16); + s = g_strdup_printf ("%s %d %s", + cookie_context, + cookie_id, + m->priv->server_challenge); + *out_data_len = strlen (s); + + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA; + + out: + return s; +} + +static gchar * +mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), NULL); + g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL); + g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED, NULL); + + return g_strdup (m->priv->reject_reason); +} + +static void +mechanism_server_shutdown (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism)); + g_return_if_fail (m->priv->is_server && !m->priv->is_client); + + m->priv->is_server = FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAuthMechanismState +mechanism_client_get_state (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID); + g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, G_DBUS_AUTH_MECHANISM_STATE_INVALID); + + return m->priv->state; +} + +static gchar * +mechanism_client_initiate (GDBusAuthMechanism *mechanism, + gsize *out_initial_response_len) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + gchar *initial_response; + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), NULL); + g_return_val_if_fail (!m->priv->is_server && !m->priv->is_client, NULL); + + m->priv->is_client = TRUE; + + *out_initial_response_len = 0; + +#ifdef G_OS_UNIX + initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) getuid ()); +#elif defined (G_OS_WIN32) + initial_response = _g_win32_current_process_sid_string (NULL); +#else +#error Please implement for your OS +#endif + if (initial_response) + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA; + *out_initial_response_len = strlen (initial_response); + } + else + { + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + } + + return initial_response; +} + +static void +mechanism_client_data_receive (GDBusAuthMechanism *mechanism, + const gchar *data, + gsize data_len) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + gchar **tokens; + const gchar *cookie_context; + guint cookie_id; + const gchar *server_challenge; + gchar *client_challenge; + gchar *endp; + gchar *cookie; + GError *error; + gchar *sha1; + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism)); + g_return_if_fail (m->priv->is_client && !m->priv->is_server); + g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA); + + tokens = NULL; + cookie = NULL; + client_challenge = NULL; + + tokens = g_strsplit (data, " ", 0); + if (g_strv_length (tokens) != 3) + { + g_free (m->priv->reject_reason); + m->priv->reject_reason = g_strdup_printf ("Malformed data '%s'", data); + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + goto out; + } + + cookie_context = tokens[0]; + cookie_id = g_ascii_strtoll (tokens[1], &endp, 10); + if (*endp != '\0') + { + g_free (m->priv->reject_reason); + m->priv->reject_reason = g_strdup_printf ("Malformed cookie_id '%s'", tokens[1]); + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + goto out; + } + server_challenge = tokens[2]; + + error = NULL; + cookie = keyring_lookup_entry (cookie_context, cookie_id, &error); + if (cookie == NULL) + { + g_free (m->priv->reject_reason); + m->priv->reject_reason = g_strdup_printf ("Problems looking up entry in keyring: %s", error->message); + g_error_free (error); + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; + goto out; + } + + client_challenge = random_ascii_string (16); + sha1 = generate_sha1 (server_challenge, client_challenge, cookie); + m->priv->to_send = g_strdup_printf ("%s %s", client_challenge, sha1); + g_free (sha1); + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND; + + out: + g_strfreev (tokens); + g_free (cookie); + g_free (client_challenge); +} + +static gchar * +mechanism_client_data_send (GDBusAuthMechanism *mechanism, + gsize *out_data_len) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + + g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), NULL); + g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, NULL); + g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL); + + g_assert (m->priv->to_send != NULL); + + m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED; + + *out_data_len = strlen (m->priv->to_send); + return g_strdup (m->priv->to_send); +} + +static void +mechanism_client_shutdown (GDBusAuthMechanism *mechanism) +{ + GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism); + + g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism)); + g_return_if_fail (m->priv->is_client && !m->priv->is_server); + + m->priv->is_client = FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusauthmechanismsha1.h b/gio/gdbusauthmechanismsha1.h new file mode 100644 index 0000000..0e563fd --- /dev/null +++ b/gio/gdbusauthmechanismsha1.h @@ -0,0 +1,61 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_AUTH_MECHANISM_SHA1_H__ +#define __G_DBUS_AUTH_MECHANISM_SHA1_H__ + +#if !defined (GIO_COMPILATION) +#error "gdbusauthmechanismsha1.h is a private header file." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_AUTH_MECHANISM_SHA1 (_g_dbus_auth_mechanism_sha1_get_type ()) +#define G_DBUS_AUTH_MECHANISM_SHA1(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_AUTH_MECHANISM_SHA1, GDBusAuthMechanismSha1)) +#define G_DBUS_AUTH_MECHANISM_SHA1_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_AUTH_MECHANISM_SHA1, GDBusAuthMechanismSha1Class)) +#define G_DBUS_AUTH_MECHANISM_SHA1_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_AUTH_MECHANISM_SHA1, GDBusAuthMechanismSha1Class)) +#define G_IS_DBUS_AUTH_MECHANISM_SHA1(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_AUTH_MECHANISM_SHA1)) +#define G_IS_DBUS_AUTH_MECHANISM_SHA1_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_AUTH_MECHANISM_SHA1)) + +typedef struct _GDBusAuthMechanismSha1 GDBusAuthMechanismSha1; +typedef struct _GDBusAuthMechanismSha1Class GDBusAuthMechanismSha1Class; +typedef struct _GDBusAuthMechanismSha1Private GDBusAuthMechanismSha1Private; + +struct _GDBusAuthMechanismSha1Class +{ + /*< private >*/ + GDBusAuthMechanismClass parent_class; +}; + +struct _GDBusAuthMechanismSha1 +{ + GDBusAuthMechanism parent_instance; + GDBusAuthMechanismSha1Private *priv; +}; + +GType _g_dbus_auth_mechanism_sha1_get_type (void) G_GNUC_CONST; + + +G_END_DECLS + +#endif /* __G_DBUS_AUTH_MECHANISM_SHA1_H__ */ diff --git a/gio/gdbusauthobserver.c b/gio/gdbusauthobserver.c new file mode 100644 index 0000000..7bafa94 --- /dev/null +++ b/gio/gdbusauthobserver.c @@ -0,0 +1,315 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusauthobserver.h" +#include "gcredentials.h" +#include "gioenumtypes.h" +#include "giostream.h" +#include "gdbusprivate.h" + +#include "glibintl.h" +#include "gmarshal-internal.h" + +/** + * SECTION:gdbusauthobserver + * @short_description: Object used for authenticating connections + * @include: gio/gio.h + * + * The #GDBusAuthObserver type provides a mechanism for participating + * in how a #GDBusServer (or a #GDBusConnection) authenticates remote + * peers. Simply instantiate a #GDBusAuthObserver and connect to the + * signals you are interested in. Note that new signals may be added + * in the future + * + * ## Controlling Authentication Mechanisms + * + * By default, a #GDBusServer or server-side #GDBusConnection will allow + * any authentication mechanism to be used. If you only + * want to allow D-Bus connections with the `EXTERNAL` mechanism, + * which makes use of credentials passing and is the recommended + * mechanism for modern Unix platforms such as Linux and the BSD family, + * you would use a signal handler like this: + * + * |[ + * static gboolean + * on_allow_mechanism (GDBusAuthObserver *observer, + * const gchar *mechanism, + * gpointer user_data) + * { + * if (g_strcmp0 (mechanism, "EXTERNAL") == 0) + * { + * return TRUE; + * } + * + * return FALSE; + * } + * ]| + * + * ## Controlling Authorization # {#auth-observer} + * + * By default, a #GDBusServer or server-side #GDBusConnection will accept + * connections from any successfully authenticated user (but not from + * anonymous connections using the `ANONYMOUS` mechanism). If you only + * want to allow D-Bus connections from processes owned by the same uid + * as the server, since GLib 2.68, you should use the + * %G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER flag. It’s equivalent + * to the following signal handler: + * + * |[ + * static gboolean + * on_authorize_authenticated_peer (GDBusAuthObserver *observer, + * GIOStream *stream, + * GCredentials *credentials, + * gpointer user_data) + * { + * gboolean authorized; + * + * authorized = FALSE; + * if (credentials != NULL) + * { + * GCredentials *own_credentials; + * own_credentials = g_credentials_new (); + * if (g_credentials_is_same_user (credentials, own_credentials, NULL)) + * authorized = TRUE; + * g_object_unref (own_credentials); + * } + * + * return authorized; + * } + * ]| + */ + +typedef struct _GDBusAuthObserverClass GDBusAuthObserverClass; + +/** + * GDBusAuthObserverClass: + * @authorize_authenticated_peer: Signal class handler for the #GDBusAuthObserver::authorize-authenticated-peer signal. + * + * Class structure for #GDBusAuthObserverClass. + * + * Since: 2.26 + */ +struct _GDBusAuthObserverClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + + /* Signals */ + gboolean (*authorize_authenticated_peer) (GDBusAuthObserver *observer, + GIOStream *stream, + GCredentials *credentials); + + gboolean (*allow_mechanism) (GDBusAuthObserver *observer, + const gchar *mechanism); +}; + +/** + * GDBusAuthObserver: + * + * The #GDBusAuthObserver structure contains only private data and + * should only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GDBusAuthObserver +{ + GObject parent_instance; +}; + +enum +{ + AUTHORIZE_AUTHENTICATED_PEER_SIGNAL, + ALLOW_MECHANISM_SIGNAL, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (GDBusAuthObserver, g_dbus_auth_observer, G_TYPE_OBJECT) + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +g_dbus_auth_observer_finalize (GObject *object) +{ + G_OBJECT_CLASS (g_dbus_auth_observer_parent_class)->finalize (object); +} + +static gboolean +g_dbus_auth_observer_authorize_authenticated_peer_real (GDBusAuthObserver *observer, + GIOStream *stream, + GCredentials *credentials) +{ + return TRUE; +} + +static gboolean +g_dbus_auth_observer_allow_mechanism_real (GDBusAuthObserver *observer, + const gchar *mechanism) +{ + return TRUE; +} + +static void +g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_auth_observer_finalize; + + klass->authorize_authenticated_peer = g_dbus_auth_observer_authorize_authenticated_peer_real; + klass->allow_mechanism = g_dbus_auth_observer_allow_mechanism_real; + + /** + * GDBusAuthObserver::authorize-authenticated-peer: + * @observer: The #GDBusAuthObserver emitting the signal. + * @stream: A #GIOStream for the #GDBusConnection. + * @credentials: (nullable): Credentials received from the peer or %NULL. + * + * Emitted to check if a peer that is successfully authenticated + * is authorized. + * + * Returns: %TRUE if the peer is authorized, %FALSE if not. + * + * Since: 2.26 + */ + signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL] = + g_signal_new (I_("authorize-authenticated-peer"), + G_TYPE_DBUS_AUTH_OBSERVER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusAuthObserverClass, authorize_authenticated_peer), + _g_signal_accumulator_false_handled, + NULL, /* accu_data */ + _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECT, + G_TYPE_BOOLEAN, + 2, + G_TYPE_IO_STREAM, + G_TYPE_CREDENTIALS); + g_signal_set_va_marshaller (signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECTv); + + /** + * GDBusAuthObserver::allow-mechanism: + * @observer: The #GDBusAuthObserver emitting the signal. + * @mechanism: The name of the mechanism, e.g. `DBUS_COOKIE_SHA1`. + * + * Emitted to check if @mechanism is allowed to be used. + * + * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not. + * + * Since: 2.34 + */ + signals[ALLOW_MECHANISM_SIGNAL] = + g_signal_new (I_("allow-mechanism"), + G_TYPE_DBUS_AUTH_OBSERVER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusAuthObserverClass, allow_mechanism), + _g_signal_accumulator_false_handled, + NULL, /* accu_data */ + _g_cclosure_marshal_BOOLEAN__STRING, + G_TYPE_BOOLEAN, + 1, + G_TYPE_STRING); + g_signal_set_va_marshaller (signals[ALLOW_MECHANISM_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_BOOLEAN__STRINGv); +} + +static void +g_dbus_auth_observer_init (GDBusAuthObserver *observer) +{ +} + +/** + * g_dbus_auth_observer_new: + * + * Creates a new #GDBusAuthObserver object. + * + * Returns: A #GDBusAuthObserver. Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusAuthObserver * +g_dbus_auth_observer_new (void) +{ + return g_object_new (G_TYPE_DBUS_AUTH_OBSERVER, NULL); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_auth_observer_authorize_authenticated_peer: + * @observer: A #GDBusAuthObserver. + * @stream: A #GIOStream for the #GDBusConnection. + * @credentials: (nullable): Credentials received from the peer or %NULL. + * + * Emits the #GDBusAuthObserver::authorize-authenticated-peer signal on @observer. + * + * Returns: %TRUE if the peer is authorized, %FALSE if not. + * + * Since: 2.26 + */ +gboolean +g_dbus_auth_observer_authorize_authenticated_peer (GDBusAuthObserver *observer, + GIOStream *stream, + GCredentials *credentials) +{ + gboolean denied; + + denied = FALSE; + g_signal_emit (observer, + signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL], + 0, + stream, + credentials, + &denied); + return denied; +} + +/** + * g_dbus_auth_observer_allow_mechanism: + * @observer: A #GDBusAuthObserver. + * @mechanism: The name of the mechanism, e.g. `DBUS_COOKIE_SHA1`. + * + * Emits the #GDBusAuthObserver::allow-mechanism signal on @observer. + * + * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not. + * + * Since: 2.34 + */ +gboolean +g_dbus_auth_observer_allow_mechanism (GDBusAuthObserver *observer, + const gchar *mechanism) +{ + gboolean ret; + + ret = FALSE; + g_signal_emit (observer, + signals[ALLOW_MECHANISM_SIGNAL], + 0, + mechanism, + &ret); + return ret; +} diff --git a/gio/gdbusauthobserver.h b/gio/gdbusauthobserver.h new file mode 100644 index 0000000..8fe7b32 --- /dev/null +++ b/gio/gdbusauthobserver.h @@ -0,0 +1,51 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_AUTH_OBSERVER_H__ +#define __G_DBUS_AUTH_OBSERVER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_AUTH_OBSERVER (g_dbus_auth_observer_get_type ()) +#define G_DBUS_AUTH_OBSERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_AUTH_OBSERVER, GDBusAuthObserver)) +#define G_IS_DBUS_AUTH_OBSERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_AUTH_OBSERVER)) + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_auth_observer_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDBusAuthObserver *g_dbus_auth_observer_new (void); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_auth_observer_authorize_authenticated_peer (GDBusAuthObserver *observer, + GIOStream *stream, + GCredentials *credentials); + +GLIB_AVAILABLE_IN_2_34 +gboolean g_dbus_auth_observer_allow_mechanism (GDBusAuthObserver *observer, + const gchar *mechanism); + +G_END_DECLS + +#endif /* _G_DBUS_AUTH_OBSERVER_H__ */ diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c new file mode 100644 index 0000000..1159c2d --- /dev/null +++ b/gio/gdbusconnection.c @@ -0,0 +1,7580 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +/* + * TODO for GDBus: + * + * - would be nice to expose GDBusAuthMechanism and an extension point + * + * - Need to rewrite GDBusAuth and rework GDBusAuthMechanism. In particular + * the mechanism VFuncs need to be able to set an error. + * + * - Need to document other mechanisms/sources for determining the D-Bus + * address of a well-known bus. + * + * - e.g. on Win32 we need code like from here + * + * http://cgit.freedesktop.org/~david/gdbus-standalone/tree/gdbus/gdbusaddress.c#n900 + * + * that was never copied over here because it originally was copy-paste + * from the GPLv2 / AFL 2.1 libdbus sources. + * + * - on OS X we need to look in launchd for the address + * + * https://bugs.freedesktop.org/show_bug.cgi?id=14259 + * + * - on X11 we need to look in a X11 property on the X server + * - (we can also just use dbus-launch(1) from the D-Bus + * distribution) + * + * - (ideally) this requires D-Bus spec work because none of + * this has never really been specced out properly (except + * the X11 bits) + * + * - Related to the above, we also need to be able to launch a message bus + * instance.... Since we don't want to write our own bus daemon we should + * launch dbus-daemon(1) (thus: Win32 and OS X need to bundle it) + * + * - probably want a G_DBUS_NONCE_TCP_TMPDIR environment variable + * to specify where the nonce is stored. This will allow people to use + * G_DBUS_NONCE_TCP_TMPDIR=/mnt/secure.company.server/dbus-nonce-dir + * to easily achieve secure RPC via nonce-tcp. + * + * - need to expose an extension point for resolving D-Bus address and + * turning them into GIOStream objects. This will allow us to implement + * e.g. X11 D-Bus transports without dlopen()'ing or linking against + * libX11 from libgio. + * - see g_dbus_address_connect() in gdbusaddress.c + * + * - would be cute to use kernel-specific APIs to resolve fds for + * debug output when using G_DBUS_DEBUG=message, e.g. in addition to + * + * fd 21: dev=8:1,mode=0100644,ino=1171231,uid=0,gid=0,rdev=0:0,size=234,atime=1273070640,mtime=1267126160,ctime=1267126160 + * + * maybe we can show more information about what fd 21 really is. + * Ryan suggests looking in /proc/self/fd for clues / symlinks! + * Initial experiments on Linux 2.6 suggests that the symlink looks + * like this: + * + * 3 -> /proc/18068/fd + * + * e.g. not of much use. + * + * - GDBus High-Level docs + * - Proxy: properties, signals... + * - Connection: IOStream based, ::close, connection setup steps + * mainloop integration, threading + * - Differences from libdbus (extend "Migrating from") + * - the message handling thread + * - Using GVariant instead of GValue + * - Explain why the high-level API is a good thing and what + * kind of pitfalls it avoids + * - Export objects before claiming names + * - Talk about auto-starting services (cf. GBusNameWatcherFlags) + */ + +#include "config.h" + +#include +#include + +#include "gdbusauth.h" +#include "gdbusutils.h" +#include "gdbusaddress.h" +#include "gdbusmessage.h" +#include "gdbusconnection.h" +#include "gdbuserror.h" +#include "gioenumtypes.h" +#include "gdbusintrospection.h" +#include "gdbusmethodinvocation.h" +#include "gdbusprivate.h" +#include "gdbusauthobserver.h" +#include "ginitable.h" +#include "gasyncinitable.h" +#include "giostream.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "gmarshal-internal.h" + +#ifdef G_OS_UNIX +#include "gunixconnection.h" +#include "gunixfdmessage.h" +#endif + +#include "glibintl.h" + +#define G_DBUS_CONNECTION_FLAGS_ALL \ + (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | \ + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | \ + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS | \ + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION | \ + G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING | \ + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER) + +/** + * SECTION:gdbusconnection + * @short_description: D-Bus Connections + * @include: gio/gio.h + * + * The #GDBusConnection type is used for D-Bus connections to remote + * peers such as a message buses. It is a low-level API that offers a + * lot of flexibility. For instance, it lets you establish a connection + * over any transport that can by represented as a #GIOStream. + * + * This class is rarely used directly in D-Bus clients. If you are writing + * a D-Bus client, it is often easier to use the g_bus_own_name(), + * g_bus_watch_name() or g_dbus_proxy_new_for_bus() APIs. + * + * As an exception to the usual GLib rule that a particular object must not + * be used by two threads at the same time, #GDBusConnection's methods may be + * called from any thread. This is so that g_bus_get() and g_bus_get_sync() + * can safely return the same #GDBusConnection when called from any thread. + * + * Most of the ways to obtain a #GDBusConnection automatically initialize it + * (i.e. connect to D-Bus): for instance, g_dbus_connection_new() and + * g_bus_get(), and the synchronous versions of those methods, give you an + * initialized connection. Language bindings for GIO should use + * g_initable_new() or g_async_initable_new_async(), which also initialize the + * connection. + * + * If you construct an uninitialized #GDBusConnection, such as via + * g_object_new(), you must initialize it via g_initable_init() or + * g_async_initable_init_async() before using its methods or properties. + * Calling methods or accessing properties on a #GDBusConnection that has not + * completed initialization successfully is considered to be invalid, and leads + * to undefined behaviour. In particular, if initialization fails with a + * #GError, the only valid thing you can do with that #GDBusConnection is to + * free it with g_object_unref(). + * + * ## An example D-Bus server # {#gdbus-server} + * + * Here is an example for a D-Bus server: + * [gdbus-example-server.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-server.c) + * + * ## An example for exporting a subtree # {#gdbus-subtree-server} + * + * Here is an example for exporting a subtree: + * [gdbus-example-subtree.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-subtree.c) + * + * ## An example for file descriptor passing # {#gdbus-unix-fd-client} + * + * Here is an example for passing UNIX file descriptors: + * [gdbus-unix-fd-client.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-unix-fd-client.c) + * + * ## An example for exporting a GObject # {#gdbus-export} + * + * Here is an example for exporting a #GObject: + * [gdbus-example-export.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-export.c) + */ + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct _GDBusConnectionClass GDBusConnectionClass; + +/** + * GDBusConnectionClass: + * @closed: Signal class handler for the #GDBusConnection::closed signal. + * + * Class structure for #GDBusConnection. + * + * Since: 2.26 + */ +struct _GDBusConnectionClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + /* Signals */ + void (*closed) (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error); +}; + +G_LOCK_DEFINE_STATIC (message_bus_lock); + +static GWeakRef the_session_bus; +static GWeakRef the_system_bus; + +/* Extra pseudo-member of GDBusSendMessageFlags. + * Set by initable_init() to indicate that despite not being initialized yet, + * enough of the only-valid-after-init members are set that we can send a + * message, and we're being called from its thread, so no memory barrier is + * required before accessing them. + */ +#define SEND_MESSAGE_FLAGS_INITIALIZING (1u << 31) + +/* Same as SEND_MESSAGE_FLAGS_INITIALIZING, but in GDBusCallFlags */ +#define CALL_FLAGS_INITIALIZING (1u << 31) + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GDestroyNotify callback; + gpointer user_data; +} CallDestroyNotifyData; + +static gboolean +call_destroy_notify_data_in_idle (gpointer user_data) +{ + CallDestroyNotifyData *data = user_data; + data->callback (data->user_data); + return FALSE; +} + +static void +call_destroy_notify_data_free (CallDestroyNotifyData *data) +{ + g_free (data); +} + +/* + * call_destroy_notify: + * @context: (nullable): A #GMainContext or %NULL. + * @callback: (nullable): A #GDestroyNotify or %NULL. + * @user_data: Data to pass to @callback. + * + * Schedules @callback to run in @context. + */ +static void +call_destroy_notify (GMainContext *context, + GDestroyNotify callback, + gpointer user_data) +{ + GSource *idle_source; + CallDestroyNotifyData *data; + + if (callback == NULL) + return; + + data = g_new0 (CallDestroyNotifyData, 1); + data->callback = callback; + data->user_data = user_data; + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + call_destroy_notify_data_in_idle, + data, + (GDestroyNotify) call_destroy_notify_data_free); + g_source_set_static_name (idle_source, "[gio] call_destroy_notify_data_in_idle"); + g_source_attach (idle_source, context); + g_source_unref (idle_source); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_WIN32 +#define CONNECTION_ENSURE_LOCK(obj) do { ; } while (FALSE) +#else +// TODO: for some reason this doesn't work on Windows +#define CONNECTION_ENSURE_LOCK(obj) do { \ + if (G_UNLIKELY (g_mutex_trylock(&(obj)->lock))) \ + { \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + "CONNECTION_ENSURE_LOCK: GDBusConnection object lock is not locked"); \ + } \ + } while (FALSE) +#endif + +#define CONNECTION_LOCK(obj) do { \ + g_mutex_lock (&(obj)->lock); \ + } while (FALSE) + +#define CONNECTION_UNLOCK(obj) do { \ + g_mutex_unlock (&(obj)->lock); \ + } while (FALSE) + +/* Flags in connection->atomic_flags */ +enum { + FLAG_INITIALIZED = 1 << 0, + FLAG_EXIT_ON_CLOSE = 1 << 1, + FLAG_CLOSED = 1 << 2 +}; + +/** + * GDBusConnection: + * + * The #GDBusConnection structure contains only private data and + * should only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GDBusConnection +{ + /*< private >*/ + GObject parent_instance; + + /* ------------------------------------------------------------------------ */ + /* -- General object state ------------------------------------------------ */ + /* ------------------------------------------------------------------------ */ + + /* General-purpose lock for most fields */ + GMutex lock; + + /* A lock used in the init() method of the GInitable interface - see comments + * in initable_init() for why a separate lock is needed. + * + * If you need both @lock and @init_lock, you must take @init_lock first. + */ + GMutex init_lock; + + /* Set (by loading the contents of /var/lib/dbus/machine-id) the first time + * someone calls org.freedesktop.DBus.Peer.GetMachineId(). Protected by @lock. + */ + gchar *machine_id; + + /* The underlying stream used for communication + * Read-only after initable_init(), so it may be read if you either + * hold @init_lock or check for initialization first. + */ + GIOStream *stream; + + /* The object used for authentication (if any). + * Read-only after initable_init(), so it may be read if you either + * hold @init_lock or check for initialization first. + */ + GDBusAuth *auth; + + /* Last serial used. Protected by @lock. */ + guint32 last_serial; + + /* The object used to send/receive messages. + * Read-only after initable_init(), so it may be read if you either + * hold @init_lock or check for initialization first. + */ + GDBusWorker *worker; + + /* If connected to a message bus, this contains the unique name assigned to + * us by the bus (e.g. ":1.42"). + * Read-only after initable_init(), so it may be read if you either + * hold @init_lock or check for initialization first. + */ + gchar *bus_unique_name; + + /* The GUID returned by the other side if we authenticated as a client or + * the GUID to use if authenticating as a server. + * Read-only after initable_init(), so it may be read if you either + * hold @init_lock or check for initialization first. + */ + gchar *guid; + + /* FLAG_INITIALIZED is set exactly when initable_init() has finished running. + * Inspect @initialization_error to see whether it succeeded or failed. + * + * FLAG_EXIT_ON_CLOSE is the exit-on-close property. + * + * FLAG_CLOSED is the closed property. It may be read at any time, but + * may only be written while holding @lock. + */ + gint atomic_flags; /* (atomic) */ + + /* If the connection could not be established during initable_init(), + * this GError will be set. + * Read-only after initable_init(), so it may be read if you either + * hold @init_lock or check for initialization first. + */ + GError *initialization_error; + + /* The result of g_main_context_ref_thread_default() when the object + * was created (the GObject _init() function) - this is used for delivery + * of the :closed GObject signal. + * + * Only set in the GObject init function, so no locks are needed. + */ + GMainContext *main_context_at_construction; + + /* Read-only construct properties, no locks needed */ + gchar *address; + GDBusConnectionFlags flags; + + /* Map used for managing method replies, protected by @lock */ + GHashTable *map_method_serial_to_task; /* guint32 -> GTask* */ + + /* Maps used for managing signal subscription, protected by @lock */ + GHashTable *map_rule_to_signal_data; /* match rule (gchar*) -> SignalData */ + GHashTable *map_id_to_signal_data; /* id (guint) -> SignalData */ + GHashTable *map_sender_unique_name_to_signal_data_array; /* unique sender (gchar*) -> GPtrArray* of SignalData */ + + /* Maps used for managing exported objects and subtrees, + * protected by @lock + */ + GHashTable *map_object_path_to_eo; /* gchar* -> ExportedObject* */ + GHashTable *map_id_to_ei; /* guint -> ExportedInterface* */ + GHashTable *map_object_path_to_es; /* gchar* -> ExportedSubtree* */ + GHashTable *map_id_to_es; /* guint -> ExportedSubtree* */ + + /* Map used for storing last used serials for each thread, protected by @lock */ + GHashTable *map_thread_to_last_serial; + + /* Structure used for message filters, protected by @lock */ + GPtrArray *filters; + + /* Capabilities negotiated during authentication + * Read-only after initable_init(), so it may be read without holding a + * lock, if you check for initialization first. + */ + GDBusCapabilityFlags capabilities; + + /* Protected by @init_lock */ + GDBusAuthObserver *authentication_observer; + + /* Read-only after initable_init(), so it may be read if you either + * hold @init_lock or check for initialization first. + */ + GCredentials *credentials; + + /* set to TRUE when finalizing */ + gboolean finalizing; +}; + +typedef struct ExportedObject ExportedObject; +static void exported_object_free (ExportedObject *eo); + +typedef struct ExportedSubtree ExportedSubtree; +static ExportedSubtree *exported_subtree_ref (ExportedSubtree *es); +static void exported_subtree_unref (ExportedSubtree *es); + +enum +{ + CLOSED_SIGNAL, + LAST_SIGNAL, +}; + +enum +{ + PROP_0, + PROP_STREAM, + PROP_ADDRESS, + PROP_FLAGS, + PROP_GUID, + PROP_UNIQUE_NAME, + PROP_CLOSED, + PROP_EXIT_ON_CLOSE, + PROP_CAPABILITY_FLAGS, + PROP_AUTHENTICATION_OBSERVER, +}; + +static void distribute_signals (GDBusConnection *connection, + GDBusMessage *message); + +static void distribute_method_call (GDBusConnection *connection, + GDBusMessage *message); + +static gboolean handle_generic_unlocked (GDBusConnection *connection, + GDBusMessage *message); + + +static void purge_all_signal_subscriptions (GDBusConnection *connection); +static void purge_all_filters (GDBusConnection *connection); + +static void schedule_method_call (GDBusConnection *connection, + GDBusMessage *message, + guint registration_id, + guint subtree_registration_id, + const GDBusInterfaceInfo *interface_info, + const GDBusMethodInfo *method_info, + const GDBusPropertyInfo *property_info, + GVariant *parameters, + const GDBusInterfaceVTable *vtable, + GMainContext *main_context, + gpointer user_data); + +#define _G_ENSURE_LOCK(name) do { \ + if (G_UNLIKELY (G_TRYLOCK(name))) \ + { \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + "_G_ENSURE_LOCK: Lock '" #name "' is not locked"); \ + } \ + } while (FALSE) \ + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void initable_iface_init (GInitableIface *initable_iface); +static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface); + +G_DEFINE_TYPE_WITH_CODE (GDBusConnection, g_dbus_connection, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init) + ); + +/* + * Check that all members of @connection that can only be accessed after + * the connection is initialized can safely be accessed. If not, + * log a critical warning. This function is a memory barrier. + * + * Returns: %TRUE if initialized + */ +static gboolean +check_initialized (GDBusConnection *connection) +{ + /* The access to @atomic_flags isn't conditional, so that this function + * provides a memory barrier for thread-safety even if checks are disabled. + * (If you don't want this stricter guarantee, you can call + * g_return_if_fail (check_initialized (c)).) + * + * This isn't strictly necessary now that we've decided use of an + * uninitialized GDBusConnection is undefined behaviour, but it seems + * better to be as deterministic as is feasible. + * + * (Anything that could suffer a crash from seeing undefined values + * must have a race condition - thread A initializes the connection while + * thread B calls a method without initialization, hoping that thread A will + * win the race - so its behaviour is undefined anyway.) + */ + gint flags = g_atomic_int_get (&connection->atomic_flags); + + g_return_val_if_fail (flags & FLAG_INITIALIZED, FALSE); + + /* We can safely access this, due to the memory barrier above */ + g_return_val_if_fail (connection->initialization_error == NULL, FALSE); + + return TRUE; +} + +typedef enum { + MAY_BE_UNINITIALIZED = (1<<1) +} CheckUnclosedFlags; + +/* + * Check the same thing as check_initialized(), and also that the + * connection is not closed. If the connection is uninitialized, + * raise a critical warning (it's programmer error); if it's closed, + * raise a recoverable GError (it's a runtime error). + * + * This function is a memory barrier. + * + * Returns: %TRUE if initialized and not closed + */ +static gboolean +check_unclosed (GDBusConnection *connection, + CheckUnclosedFlags check, + GError **error) +{ + /* check_initialized() is effectively inlined, so we don't waste time + * doing two memory barriers + */ + gint flags = g_atomic_int_get (&connection->atomic_flags); + + if (!(check & MAY_BE_UNINITIALIZED)) + { + g_return_val_if_fail (flags & FLAG_INITIALIZED, FALSE); + g_return_val_if_fail (connection->initialization_error == NULL, FALSE); + } + + if (flags & FLAG_CLOSED) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_CLOSED, + _("The connection is closed")); + return FALSE; + } + + return TRUE; +} + +static GHashTable *alive_connections = NULL; + +static void +g_dbus_connection_dispose (GObject *object) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (object); + + G_LOCK (message_bus_lock); + CONNECTION_LOCK (connection); + if (connection->worker != NULL) + { + _g_dbus_worker_stop (connection->worker); + connection->worker = NULL; + if (alive_connections != NULL) + g_warn_if_fail (g_hash_table_remove (alive_connections, connection)); + } + else + { + if (alive_connections != NULL) + g_warn_if_fail (!g_hash_table_contains (alive_connections, connection)); + } + CONNECTION_UNLOCK (connection); + G_UNLOCK (message_bus_lock); + + if (G_OBJECT_CLASS (g_dbus_connection_parent_class)->dispose != NULL) + G_OBJECT_CLASS (g_dbus_connection_parent_class)->dispose (object); +} + +static void +g_dbus_connection_finalize (GObject *object) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (object); + + connection->finalizing = TRUE; + + purge_all_signal_subscriptions (connection); + + purge_all_filters (connection); + g_ptr_array_unref (connection->filters); + + if (connection->authentication_observer != NULL) + g_object_unref (connection->authentication_observer); + + if (connection->auth != NULL) + g_object_unref (connection->auth); + + if (connection->credentials) + g_object_unref (connection->credentials); + + if (connection->stream != NULL) + { + g_object_unref (connection->stream); + connection->stream = NULL; + } + + g_free (connection->address); + + g_free (connection->guid); + g_free (connection->bus_unique_name); + + if (connection->initialization_error != NULL) + g_error_free (connection->initialization_error); + + g_hash_table_unref (connection->map_method_serial_to_task); + + g_hash_table_unref (connection->map_rule_to_signal_data); + g_hash_table_unref (connection->map_id_to_signal_data); + g_hash_table_unref (connection->map_sender_unique_name_to_signal_data_array); + + g_hash_table_unref (connection->map_id_to_ei); + g_hash_table_unref (connection->map_object_path_to_eo); + g_hash_table_unref (connection->map_id_to_es); + g_hash_table_unref (connection->map_object_path_to_es); + + g_hash_table_unref (connection->map_thread_to_last_serial); + + g_main_context_unref (connection->main_context_at_construction); + + g_free (connection->machine_id); + + g_mutex_clear (&connection->init_lock); + g_mutex_clear (&connection->lock); + + G_OBJECT_CLASS (g_dbus_connection_parent_class)->finalize (object); +} + +/* called in any user thread, with the connection's lock not held */ +static void +g_dbus_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (object); + + switch (prop_id) + { + case PROP_STREAM: + g_value_set_object (value, g_dbus_connection_get_stream (connection)); + break; + + case PROP_GUID: + g_value_set_string (value, g_dbus_connection_get_guid (connection)); + break; + + case PROP_UNIQUE_NAME: + g_value_set_string (value, g_dbus_connection_get_unique_name (connection)); + break; + + case PROP_CLOSED: + g_value_set_boolean (value, g_dbus_connection_is_closed (connection)); + break; + + case PROP_EXIT_ON_CLOSE: + g_value_set_boolean (value, g_dbus_connection_get_exit_on_close (connection)); + break; + + case PROP_CAPABILITY_FLAGS: + g_value_set_flags (value, g_dbus_connection_get_capabilities (connection)); + break; + + case PROP_FLAGS: + g_value_set_flags (value, g_dbus_connection_get_flags (connection)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* called in any user thread, with the connection's lock not held */ +static void +g_dbus_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (object); + + switch (prop_id) + { + case PROP_STREAM: + connection->stream = g_value_dup_object (value); + break; + + case PROP_GUID: + connection->guid = g_value_dup_string (value); + break; + + case PROP_ADDRESS: + connection->address = g_value_dup_string (value); + break; + + case PROP_FLAGS: + connection->flags = g_value_get_flags (value); + break; + + case PROP_EXIT_ON_CLOSE: + g_dbus_connection_set_exit_on_close (connection, g_value_get_boolean (value)); + break; + + case PROP_AUTHENTICATION_OBSERVER: + connection->authentication_observer = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* Base-class implementation of GDBusConnection::closed. + * + * Called in a user thread, by the main context that was thread-default when + * the object was constructed. + */ +static void +g_dbus_connection_real_closed (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error) +{ + gint flags = g_atomic_int_get (&connection->atomic_flags); + + /* Because atomic int access is a memory barrier, we can safely read + * initialization_error without a lock, as long as we do it afterwards. + */ + if (remote_peer_vanished && + (flags & FLAG_EXIT_ON_CLOSE) != 0 && + (flags & FLAG_INITIALIZED) != 0 && + connection->initialization_error == NULL) + { + raise (SIGTERM); + } +} + +static void +g_dbus_connection_class_init (GDBusConnectionClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_connection_finalize; + gobject_class->dispose = g_dbus_connection_dispose; + gobject_class->set_property = g_dbus_connection_set_property; + gobject_class->get_property = g_dbus_connection_get_property; + + klass->closed = g_dbus_connection_real_closed; + + /** + * GDBusConnection:stream: + * + * The underlying #GIOStream used for I/O. + * + * If this is passed on construction and is a #GSocketConnection, + * then the corresponding #GSocket will be put into non-blocking mode. + * + * While the #GDBusConnection is active, it will interact with this + * stream from a worker thread, so it is not safe to interact with + * the stream directly. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_STREAM, + g_param_spec_object ("stream", + P_("IO Stream"), + P_("The underlying streams used for I/O"), + G_TYPE_IO_STREAM, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection:address: + * + * A D-Bus address specifying potential endpoints that can be used + * when establishing the connection. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_ADDRESS, + g_param_spec_string ("address", + P_("Address"), + P_("D-Bus address specifying potential socket endpoints"), + NULL, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection:flags: + * + * Flags from the #GDBusConnectionFlags enumeration. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_FLAGS, + g_param_spec_flags ("flags", + P_("Flags"), + P_("Flags"), + G_TYPE_DBUS_CONNECTION_FLAGS, + G_DBUS_CONNECTION_FLAGS_NONE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection:guid: + * + * The GUID of the peer performing the role of server when + * authenticating. + * + * If you are constructing a #GDBusConnection and pass + * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER in the + * #GDBusConnection:flags property then you **must** also set this + * property to a valid guid. + * + * If you are constructing a #GDBusConnection and pass + * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT in the + * #GDBusConnection:flags property you will be able to read the GUID + * of the other peer here after the connection has been successfully + * initialized. + * + * Note that the + * [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses) + * uses the term ‘UUID’ to refer to this, whereas GLib consistently uses the + * term ‘GUID’ for historical reasons. + * + * Despite its name, the format of #GDBusConnection:guid does not follow + * [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) or the Microsoft + * GUID format. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_GUID, + g_param_spec_string ("guid", + P_("GUID"), + P_("GUID of the server peer"), + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection:unique-name: + * + * The unique name as assigned by the message bus or %NULL if the + * connection is not open or not a message bus connection. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_UNIQUE_NAME, + g_param_spec_string ("unique-name", + P_("unique-name"), + P_("Unique name of bus connection"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection:closed: + * + * A boolean specifying whether the connection has been closed. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_CLOSED, + g_param_spec_boolean ("closed", + P_("Closed"), + P_("Whether the connection is closed"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection:exit-on-close: + * + * A boolean specifying whether the process will be terminated (by + * calling `raise(SIGTERM)`) if the connection is closed by the + * remote peer. + * + * Note that #GDBusConnection objects returned by g_bus_get_finish() + * and g_bus_get_sync() will (usually) have this property set to %TRUE. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_EXIT_ON_CLOSE, + g_param_spec_boolean ("exit-on-close", + P_("Exit on close"), + P_("Whether the process is terminated when the connection is closed"), + FALSE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection:capabilities: + * + * Flags from the #GDBusCapabilityFlags enumeration + * representing connection features negotiated with the other peer. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_CAPABILITY_FLAGS, + g_param_spec_flags ("capabilities", + P_("Capabilities"), + P_("Capabilities"), + G_TYPE_DBUS_CAPABILITY_FLAGS, + G_DBUS_CAPABILITY_FLAGS_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection:authentication-observer: + * + * A #GDBusAuthObserver object to assist in the authentication process or %NULL. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_AUTHENTICATION_OBSERVER, + g_param_spec_object ("authentication-observer", + P_("Authentication Observer"), + P_("Object used to assist in the authentication process"), + G_TYPE_DBUS_AUTH_OBSERVER, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusConnection::closed: + * @connection: the #GDBusConnection emitting the signal + * @remote_peer_vanished: %TRUE if @connection is closed because the + * remote peer closed its end of the connection + * @error: (nullable): a #GError with more details about the event or %NULL + * + * Emitted when the connection is closed. + * + * The cause of this event can be + * + * - If g_dbus_connection_close() is called. In this case + * @remote_peer_vanished is set to %FALSE and @error is %NULL. + * + * - If the remote peer closes the connection. In this case + * @remote_peer_vanished is set to %TRUE and @error is set. + * + * - If the remote peer sends invalid or malformed data. In this + * case @remote_peer_vanished is set to %FALSE and @error is set. + * + * Upon receiving this signal, you should give up your reference to + * @connection. You are guaranteed that this signal is emitted only + * once. + * + * Since: 2.26 + */ + signals[CLOSED_SIGNAL] = g_signal_new (I_("closed"), + G_TYPE_DBUS_CONNECTION, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusConnectionClass, closed), + NULL, + NULL, + _g_cclosure_marshal_VOID__BOOLEAN_BOXED, + G_TYPE_NONE, + 2, + G_TYPE_BOOLEAN, + G_TYPE_ERROR); + g_signal_set_va_marshaller (signals[CLOSED_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__BOOLEAN_BOXEDv); +} + +static void +g_dbus_connection_init (GDBusConnection *connection) +{ + g_mutex_init (&connection->lock); + g_mutex_init (&connection->init_lock); + + connection->map_method_serial_to_task = g_hash_table_new (g_direct_hash, g_direct_equal); + + connection->map_rule_to_signal_data = g_hash_table_new (g_str_hash, + g_str_equal); + connection->map_id_to_signal_data = g_hash_table_new (g_direct_hash, + g_direct_equal); + connection->map_sender_unique_name_to_signal_data_array = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_ptr_array_unref); + + connection->map_object_path_to_eo = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) exported_object_free); + + connection->map_id_to_ei = g_hash_table_new (g_direct_hash, + g_direct_equal); + + connection->map_object_path_to_es = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) exported_subtree_unref); + + connection->map_id_to_es = g_hash_table_new (g_direct_hash, + g_direct_equal); + + connection->map_thread_to_last_serial = g_hash_table_new (g_direct_hash, + g_direct_equal); + + connection->main_context_at_construction = g_main_context_ref_thread_default (); + + connection->filters = g_ptr_array_new (); +} + +/** + * g_dbus_connection_get_stream: + * @connection: a #GDBusConnection + * + * Gets the underlying stream used for IO. + * + * While the #GDBusConnection is active, it will interact with this + * stream from a worker thread, so it is not safe to interact with + * the stream directly. + * + * Returns: (transfer none) (not nullable): the stream used for IO + * + * Since: 2.26 + */ +GIOStream * +g_dbus_connection_get_stream (GDBusConnection *connection) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + + /* do not use g_return_val_if_fail(), we want the memory barrier */ + if (!check_initialized (connection)) + return NULL; + + return connection->stream; +} + +/** + * g_dbus_connection_start_message_processing: + * @connection: a #GDBusConnection + * + * If @connection was created with + * %G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, this method + * starts processing messages. Does nothing on if @connection wasn't + * created with this flag or if the method has already been called. + * + * Since: 2.26 + */ +void +g_dbus_connection_start_message_processing (GDBusConnection *connection) +{ + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + + /* do not use g_return_val_if_fail(), we want the memory barrier */ + if (!check_initialized (connection)) + return; + + g_assert (connection->worker != NULL); + _g_dbus_worker_unfreeze (connection->worker); +} + +/** + * g_dbus_connection_is_closed: + * @connection: a #GDBusConnection + * + * Gets whether @connection is closed. + * + * Returns: %TRUE if the connection is closed, %FALSE otherwise + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_is_closed (GDBusConnection *connection) +{ + gint flags; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + + flags = g_atomic_int_get (&connection->atomic_flags); + + return (flags & FLAG_CLOSED) ? TRUE : FALSE; +} + +/** + * g_dbus_connection_get_capabilities: + * @connection: a #GDBusConnection + * + * Gets the capabilities negotiated with the remote peer + * + * Returns: zero or more flags from the #GDBusCapabilityFlags enumeration + * + * Since: 2.26 + */ +GDBusCapabilityFlags +g_dbus_connection_get_capabilities (GDBusConnection *connection) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), G_DBUS_CAPABILITY_FLAGS_NONE); + + /* do not use g_return_val_if_fail(), we want the memory barrier */ + if (!check_initialized (connection)) + return G_DBUS_CAPABILITY_FLAGS_NONE; + + return connection->capabilities; +} + +/** + * g_dbus_connection_get_flags: + * @connection: a #GDBusConnection + * + * Gets the flags used to construct this connection + * + * Returns: zero or more flags from the #GDBusConnectionFlags enumeration + * + * Since: 2.60 + */ +GDBusConnectionFlags +g_dbus_connection_get_flags (GDBusConnection *connection) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), G_DBUS_CONNECTION_FLAGS_NONE); + + /* do not use g_return_val_if_fail(), we want the memory barrier */ + if (!check_initialized (connection)) + return G_DBUS_CONNECTION_FLAGS_NONE; + + return connection->flags; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called in a temporary thread without holding locks. */ +static void +flush_in_thread_func (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + + if (g_dbus_connection_flush_sync (source_object, + cancellable, + &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +/** + * g_dbus_connection_flush: + * @connection: a #GDBusConnection + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the + * request is satisfied or %NULL if you don't care about the result + * @user_data: The data to pass to @callback + * + * Asynchronously flushes @connection, that is, writes all queued + * outgoing message to the transport and then flushes the transport + * (using g_output_stream_flush_async()). This is useful in programs + * that wants to emit a D-Bus signal and then exit immediately. Without + * flushing the connection, there is no guaranteed that the message has + * been sent to the networking buffers in the OS kernel. + * + * This is an asynchronous method. When the operation is finished, + * @callback will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. You can + * then call g_dbus_connection_flush_finish() to get the result of the + * operation. See g_dbus_connection_flush_sync() for the synchronous + * version. + * + * Since: 2.26 + */ +void +g_dbus_connection_flush (GDBusConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + + task = g_task_new (connection, cancellable, callback, user_data); + g_task_set_source_tag (task, g_dbus_connection_flush); + g_task_run_in_thread (task, flush_in_thread_func); + g_object_unref (task); +} + +/** + * g_dbus_connection_flush_finish: + * @connection: a #GDBusConnection + * @res: a #GAsyncResult obtained from the #GAsyncReadyCallback passed + * to g_dbus_connection_flush() + * @error: return location for error or %NULL + * + * Finishes an operation started with g_dbus_connection_flush(). + * + * Returns: %TRUE if the operation succeeded, %FALSE if @error is set + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_flush_finish (GDBusConnection *connection, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (g_task_is_valid (res, connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} + +/** + * g_dbus_connection_flush_sync: + * @connection: a #GDBusConnection + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Synchronously flushes @connection. The calling thread is blocked + * until this is done. See g_dbus_connection_flush() for the + * asynchronous version of this method and more details about what it + * does. + * + * Returns: %TRUE if the operation succeeded, %FALSE if @error is set + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_flush_sync (GDBusConnection *connection, + GCancellable *cancellable, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; + + /* This is only a best-effort attempt to see whether the connection is + * closed, so it doesn't need the lock. If the connection closes just + * after this check, but before scheduling the flush operation, the + * result will be more or less the same as if the connection closed while + * the flush operation was pending - it'll fail with either CLOSED or + * CANCELLED. + */ + if (!check_unclosed (connection, 0, error)) + goto out; + + g_assert (connection->worker != NULL); + + ret = _g_dbus_worker_flush_sync (connection->worker, + cancellable, + error); + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GDBusConnection *connection; + GError *error; + gboolean remote_peer_vanished; +} EmitClosedData; + +static void +emit_closed_data_free (EmitClosedData *data) +{ + g_object_unref (data->connection); + if (data->error != NULL) + g_error_free (data->error); + g_free (data); +} + +/* Called in a user thread that has acquired the main context that was + * thread-default when the object was constructed + */ +static gboolean +emit_closed_in_idle (gpointer user_data) +{ + EmitClosedData *data = user_data; + gboolean result; + + g_object_notify (G_OBJECT (data->connection), "closed"); + g_signal_emit (data->connection, + signals[CLOSED_SIGNAL], + 0, + data->remote_peer_vanished, + data->error, + &result); + return FALSE; +} + +/* Can be called from any thread, must hold lock. + * FLAG_CLOSED must already have been set. + */ +static void +schedule_closed_unlocked (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error) +{ + GSource *idle_source; + EmitClosedData *data; + + CONNECTION_ENSURE_LOCK (connection); + + data = g_new0 (EmitClosedData, 1); + data->connection = g_object_ref (connection); + data->remote_peer_vanished = remote_peer_vanished; + data->error = error != NULL ? g_error_copy (error) : NULL; + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + emit_closed_in_idle, + data, + (GDestroyNotify) emit_closed_data_free); + g_source_set_static_name (idle_source, "[gio] emit_closed_in_idle"); + g_source_attach (idle_source, connection->main_context_at_construction); + g_source_unref (idle_source); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_close: + * @connection: a #GDBusConnection + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the request is + * satisfied or %NULL if you don't care about the result + * @user_data: The data to pass to @callback + * + * Closes @connection. Note that this never causes the process to + * exit (this might only happen if the other end of a shared message + * bus connection disconnects, see #GDBusConnection:exit-on-close). + * + * Once the connection is closed, operations such as sending a message + * will return with the error %G_IO_ERROR_CLOSED. Closing a connection + * will not automatically flush the connection so queued messages may + * be lost. Use g_dbus_connection_flush() if you need such guarantees. + * + * If @connection is already closed, this method fails with + * %G_IO_ERROR_CLOSED. + * + * When @connection has been closed, the #GDBusConnection::closed + * signal is emitted in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread that @connection was constructed in. + * + * This is an asynchronous method. When the operation is finished, + * @callback will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. You can + * then call g_dbus_connection_close_finish() to get the result of the + * operation. See g_dbus_connection_close_sync() for the synchronous + * version. + * + * Since: 2.26 + */ +void +g_dbus_connection_close (GDBusConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + + /* do not use g_return_val_if_fail(), we want the memory barrier */ + if (!check_initialized (connection)) + return; + + g_assert (connection->worker != NULL); + + task = g_task_new (connection, cancellable, callback, user_data); + g_task_set_source_tag (task, g_dbus_connection_close); + _g_dbus_worker_close (connection->worker, task); + g_object_unref (task); +} + +/** + * g_dbus_connection_close_finish: + * @connection: a #GDBusConnection + * @res: a #GAsyncResult obtained from the #GAsyncReadyCallback passed + * to g_dbus_connection_close() + * @error: return location for error or %NULL + * + * Finishes an operation started with g_dbus_connection_close(). + * + * Returns: %TRUE if the operation succeeded, %FALSE if @error is set + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_close_finish (GDBusConnection *connection, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (g_task_is_valid (res, connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} + +typedef struct { + GMainLoop *loop; + GAsyncResult *result; +} SyncCloseData; + +/* Can be called by any thread, without the connection lock */ +static void +sync_close_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + SyncCloseData *data = user_data; + + data->result = g_object_ref (res); + g_main_loop_quit (data->loop); +} + +/** + * g_dbus_connection_close_sync: + * @connection: a #GDBusConnection + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Synchronously closes @connection. The calling thread is blocked + * until this is done. See g_dbus_connection_close() for the + * asynchronous version of this method and more details about what it + * does. + * + * Returns: %TRUE if the operation succeeded, %FALSE if @error is set + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_close_sync (GDBusConnection *connection, + GCancellable *cancellable, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; + + if (check_unclosed (connection, 0, error)) + { + GMainContext *context; + SyncCloseData data; + + context = g_main_context_new (); + g_main_context_push_thread_default (context); + data.loop = g_main_loop_new (context, TRUE); + data.result = NULL; + + g_dbus_connection_close (connection, cancellable, sync_close_cb, &data); + g_main_loop_run (data.loop); + ret = g_dbus_connection_close_finish (connection, data.result, error); + + g_object_unref (data.result); + g_main_loop_unref (data.loop); + g_main_context_pop_thread_default (context); + g_main_context_unref (context); + } + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_get_last_serial: + * @connection: a #GDBusConnection + * + * Retrieves the last serial number assigned to a #GDBusMessage on + * the current thread. This includes messages sent via both low-level + * API such as g_dbus_connection_send_message() as well as + * high-level API such as g_dbus_connection_emit_signal(), + * g_dbus_connection_call() or g_dbus_proxy_call(). + * + * Returns: the last used serial or zero when no message has been sent + * within the current thread + * + * Since: 2.34 + */ +guint32 +g_dbus_connection_get_last_serial (GDBusConnection *connection) +{ + guint32 ret; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); + + CONNECTION_LOCK (connection); + ret = GPOINTER_TO_UINT (g_hash_table_lookup (connection->map_thread_to_last_serial, + g_thread_self ())); + CONNECTION_UNLOCK (connection); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Can be called by any thread, with the connection lock held */ +static gboolean +g_dbus_connection_send_message_unlocked (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, + guint32 *out_serial, + GError **error) +{ + guchar *blob; + gsize blob_size; + guint32 serial_to_use; + + CONNECTION_ENSURE_LOCK (connection); + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE); + + /* TODO: check all necessary headers are present */ + + if (out_serial != NULL) + *out_serial = 0; + + /* If we're in initable_init(), don't check for being initialized, to avoid + * chicken-and-egg problems. initable_init() is responsible for setting up + * our prerequisites (mainly connection->worker), and only calling us + * from its own thread (so no memory barrier is needed). + */ + if (!check_unclosed (connection, + (flags & SEND_MESSAGE_FLAGS_INITIALIZING) ? MAY_BE_UNINITIALIZED : 0, + error)) + return FALSE; + + blob = g_dbus_message_to_blob (message, + &blob_size, + connection->capabilities, + error); + if (blob == NULL) + return FALSE; + + if (flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) + serial_to_use = g_dbus_message_get_serial (message); + else + serial_to_use = ++connection->last_serial; /* TODO: handle overflow */ + + switch (blob[0]) + { + case 'l': + ((guint32 *) blob)[2] = GUINT32_TO_LE (serial_to_use); + break; + case 'B': + ((guint32 *) blob)[2] = GUINT32_TO_BE (serial_to_use); + break; + default: + g_assert_not_reached (); + break; + } + +#if 0 + g_printerr ("Writing message of %" G_GSIZE_FORMAT " bytes (serial %d) on %p:\n", + blob_size, serial_to_use, connection); + g_printerr ("----\n"); + hexdump (blob, blob_size); + g_printerr ("----\n"); +#endif + + /* TODO: use connection->auth to encode the blob */ + + if (out_serial != NULL) + *out_serial = serial_to_use; + + /* store used serial for the current thread */ + /* TODO: watch the thread disposal and remove associated record + * from hashtable + * - see https://bugzilla.gnome.org/show_bug.cgi?id=676825#c7 + */ + g_hash_table_replace (connection->map_thread_to_last_serial, + g_thread_self (), + GUINT_TO_POINTER (serial_to_use)); + + if (!(flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL)) + g_dbus_message_set_serial (message, serial_to_use); + + g_dbus_message_lock (message); + + _g_dbus_worker_send_message (connection->worker, + message, + (gchar*) blob, /* transfer ownership */ + blob_size); + + return TRUE; +} + +/** + * g_dbus_connection_send_message: + * @connection: a #GDBusConnection + * @message: a #GDBusMessage + * @flags: flags affecting how the message is sent + * @out_serial: (out) (optional): return location for serial number assigned + * to @message when sending it or %NULL + * @error: Return location for error or %NULL + * + * Asynchronously sends @message to the peer represented by @connection. + * + * Unless @flags contain the + * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag, the serial number + * will be assigned by @connection and set on @message via + * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the + * serial number used will be written to this location prior to + * submitting the message to the underlying transport. While it has a `volatile` + * qualifier, this is a historical artifact and the argument passed to it should + * not be `volatile`. + * + * If @connection is closed then the operation will fail with + * %G_IO_ERROR_CLOSED. If @message is not well-formed, + * the operation fails with %G_IO_ERROR_INVALID_ARGUMENT. + * + * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] + * for an example of how to use this low-level API to send and receive + * UNIX file descriptors. + * + * Note that @message must be unlocked, unless @flags contain the + * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag. + * + * Returns: %TRUE if the message was well-formed and queued for + * transmission, %FALSE if @error is set + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_send_message (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, + volatile guint32 *out_serial, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE); + g_return_val_if_fail ((flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) || !g_dbus_message_get_locked (message), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + CONNECTION_LOCK (connection); + ret = g_dbus_connection_send_message_unlocked (connection, message, flags, (guint32 *) out_serial, error); + CONNECTION_UNLOCK (connection); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + guint32 serial; + + gulong cancellable_handler_id; + + GSource *timeout_source; + + gboolean delivered; +} SendMessageData; + +/* Can be called from any thread with or without lock held */ +static void +send_message_data_free (SendMessageData *data) +{ + g_assert (data->timeout_source == NULL); + g_assert (data->cancellable_handler_id == 0); + + g_slice_free (SendMessageData, data); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* can be called from any thread with lock held; @task is (transfer full) */ +static void +send_message_with_reply_cleanup (GTask *task, gboolean remove) +{ + GDBusConnection *connection = g_task_get_source_object (task); + SendMessageData *data = g_task_get_task_data (task); + + CONNECTION_ENSURE_LOCK (connection); + + g_assert (!data->delivered); + + data->delivered = TRUE; + + if (data->timeout_source != NULL) + { + g_source_destroy (data->timeout_source); + data->timeout_source = NULL; + } + if (data->cancellable_handler_id > 0) + { + g_cancellable_disconnect (g_task_get_cancellable (task), data->cancellable_handler_id); + data->cancellable_handler_id = 0; + } + + if (remove) + { + gboolean removed = g_hash_table_remove (connection->map_method_serial_to_task, + GUINT_TO_POINTER (data->serial)); + g_warn_if_fail (removed); + } + + g_object_unref (task); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called from GDBus worker thread with lock held; @task is (transfer full). */ +static void +send_message_data_deliver_reply_unlocked (GTask *task, + GDBusMessage *reply) +{ + SendMessageData *data = g_task_get_task_data (task); + + if (data->delivered) + goto out; + + g_task_return_pointer (task, g_object_ref (reply), g_object_unref); + + send_message_with_reply_cleanup (task, TRUE); + + out: + ; +} + +/* Called from a user thread, lock is not held */ +static void +send_message_data_deliver_error (GTask *task, + GQuark domain, + gint code, + const char *message) +{ + GDBusConnection *connection = g_task_get_source_object (task); + SendMessageData *data = g_task_get_task_data (task); + + CONNECTION_LOCK (connection); + if (data->delivered) + { + CONNECTION_UNLOCK (connection); + return; + } + + g_object_ref (task); + send_message_with_reply_cleanup (task, TRUE); + CONNECTION_UNLOCK (connection); + + g_task_return_new_error (task, domain, code, "%s", message); + g_object_unref (task); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called from a user thread, lock is not held; @task is (transfer full) */ +static gboolean +send_message_with_reply_cancelled_idle_cb (gpointer user_data) +{ + GTask *task = user_data; + + send_message_data_deliver_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, + _("Operation was cancelled")); + return FALSE; +} + +/* Can be called from any thread with or without lock held */ +static void +send_message_with_reply_cancelled_cb (GCancellable *cancellable, + gpointer user_data) +{ + GTask *task = user_data; + GSource *idle_source; + + /* postpone cancellation to idle handler since we may be called directly + * via g_cancellable_connect() (e.g. holding lock) + */ + idle_source = g_idle_source_new (); + g_source_set_static_name (idle_source, "[gio] send_message_with_reply_cancelled_idle_cb"); + g_task_attach_source (task, idle_source, send_message_with_reply_cancelled_idle_cb); + g_source_unref (idle_source); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called from a user thread, lock is not held; @task is (transfer full) */ +static gboolean +send_message_with_reply_timeout_cb (gpointer user_data) +{ + GTask *task = user_data; + + send_message_data_deliver_error (task, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Timeout was reached")); + return FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called from a user thread, connection's lock is held */ +static void +g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, + gint timeout_msec, + guint32 *out_serial, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + SendMessageData *data; + GError *error = NULL; + guint32 serial; + + if (out_serial == NULL) + out_serial = &serial; + + if (timeout_msec == -1) + timeout_msec = 25 * 1000; + + data = g_slice_new0 (SendMessageData); + task = g_task_new (connection, cancellable, callback, user_data); + g_task_set_source_tag (task, + g_dbus_connection_send_message_with_reply_unlocked); + g_task_set_task_data (task, data, (GDestroyNotify) send_message_data_free); + + if (g_task_return_error_if_cancelled (task)) + { + g_object_unref (task); + return; + } + + if (!g_dbus_connection_send_message_unlocked (connection, message, flags, out_serial, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + data->serial = *out_serial; + + if (cancellable != NULL) + { + data->cancellable_handler_id = g_cancellable_connect (cancellable, + G_CALLBACK (send_message_with_reply_cancelled_cb), + g_object_ref (task), + g_object_unref); + } + + if (timeout_msec != G_MAXINT) + { + data->timeout_source = g_timeout_source_new (timeout_msec); + g_task_attach_source (task, data->timeout_source, + (GSourceFunc) send_message_with_reply_timeout_cb); + g_source_unref (data->timeout_source); + } + + g_hash_table_insert (connection->map_method_serial_to_task, + GUINT_TO_POINTER (*out_serial), + g_steal_pointer (&task)); +} + +/** + * g_dbus_connection_send_message_with_reply: + * @connection: a #GDBusConnection + * @message: a #GDBusMessage + * @flags: flags affecting how the message is sent + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @out_serial: (out) (optional): return location for serial number assigned + * to @message when sending it or %NULL + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the request + * is satisfied or %NULL if you don't care about the result + * @user_data: The data to pass to @callback + * + * Asynchronously sends @message to the peer represented by @connection. + * + * Unless @flags contain the + * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag, the serial number + * will be assigned by @connection and set on @message via + * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the + * serial number used will be written to this location prior to + * submitting the message to the underlying transport. While it has a `volatile` + * qualifier, this is a historical artifact and the argument passed to it should + * not be `volatile`. + * + * If @connection is closed then the operation will fail with + * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will + * fail with %G_IO_ERROR_CANCELLED. If @message is not well-formed, + * the operation fails with %G_IO_ERROR_INVALID_ARGUMENT. + * + * This is an asynchronous method. When the operation is finished, @callback + * will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. You can then call + * g_dbus_connection_send_message_with_reply_finish() to get the result of the operation. + * See g_dbus_connection_send_message_with_reply_sync() for the synchronous version. + * + * Note that @message must be unlocked, unless @flags contain the + * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag. + * + * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] + * for an example of how to use this low-level API to send and receive + * UNIX file descriptors. + * + * Since: 2.26 + */ +void +g_dbus_connection_send_message_with_reply (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, + gint timeout_msec, + volatile guint32 *out_serial, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail ((flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) || !g_dbus_message_get_locked (message)); + g_return_if_fail (timeout_msec >= 0 || timeout_msec == -1); + + CONNECTION_LOCK (connection); + g_dbus_connection_send_message_with_reply_unlocked (connection, + message, + flags, + timeout_msec, + (guint32 *) out_serial, + cancellable, + callback, + user_data); + CONNECTION_UNLOCK (connection); +} + +/** + * g_dbus_connection_send_message_with_reply_finish: + * @connection: a #GDBusConnection + * @res: a #GAsyncResult obtained from the #GAsyncReadyCallback passed to + * g_dbus_connection_send_message_with_reply() + * @error: teturn location for error or %NULL + * + * Finishes an operation started with g_dbus_connection_send_message_with_reply(). + * + * Note that @error is only set if a local in-process error + * occurred. That is to say that the returned #GDBusMessage object may + * be of type %G_DBUS_MESSAGE_TYPE_ERROR. Use + * g_dbus_message_to_gerror() to transcode this to a #GError. + * + * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] + * for an example of how to use this low-level API to send and receive + * UNIX file descriptors. + * + * Returns: (transfer full): a locked #GDBusMessage or %NULL if @error is set + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_connection_send_message_with_reply_finish (GDBusConnection *connection, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (g_task_is_valid (res, connection), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GAsyncResult *res; + GMainContext *context; + GMainLoop *loop; +} SendMessageSyncData; + +/* Called from a user thread, lock is not held */ +static void +send_message_with_reply_sync_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + SendMessageSyncData *data = user_data; + data->res = g_object_ref (res); + g_main_loop_quit (data->loop); +} + +/** + * g_dbus_connection_send_message_with_reply_sync: + * @connection: a #GDBusConnection + * @message: a #GDBusMessage + * @flags: flags affecting how the message is sent. + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @out_serial: (out) (optional): return location for serial number + * assigned to @message when sending it or %NULL + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Synchronously sends @message to the peer represented by @connection + * and blocks the calling thread until a reply is received or the + * timeout is reached. See g_dbus_connection_send_message_with_reply() + * for the asynchronous version of this method. + * + * Unless @flags contain the + * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag, the serial number + * will be assigned by @connection and set on @message via + * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the + * serial number used will be written to this location prior to + * submitting the message to the underlying transport. While it has a `volatile` + * qualifier, this is a historical artifact and the argument passed to it should + * not be `volatile`. + * + * If @connection is closed then the operation will fail with + * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will + * fail with %G_IO_ERROR_CANCELLED. If @message is not well-formed, + * the operation fails with %G_IO_ERROR_INVALID_ARGUMENT. + * + * Note that @error is only set if a local in-process error + * occurred. That is to say that the returned #GDBusMessage object may + * be of type %G_DBUS_MESSAGE_TYPE_ERROR. Use + * g_dbus_message_to_gerror() to transcode this to a #GError. + * + * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] + * for an example of how to use this low-level API to send and receive + * UNIX file descriptors. + * + * Note that @message must be unlocked, unless @flags contain the + * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag. + * + * Returns: (transfer full): a locked #GDBusMessage that is the reply + * to @message or %NULL if @error is set + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_connection_send_message_with_reply_sync (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, + gint timeout_msec, + volatile guint32 *out_serial, + GCancellable *cancellable, + GError **error) +{ + SendMessageSyncData data; + GDBusMessage *reply; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + g_return_val_if_fail ((flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL) || !g_dbus_message_get_locked (message), NULL); + g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + data.res = NULL; + data.context = g_main_context_new (); + data.loop = g_main_loop_new (data.context, FALSE); + + g_main_context_push_thread_default (data.context); + + g_dbus_connection_send_message_with_reply (connection, + message, + flags, + timeout_msec, + out_serial, + cancellable, + (GAsyncReadyCallback) send_message_with_reply_sync_cb, + &data); + g_main_loop_run (data.loop); + reply = g_dbus_connection_send_message_with_reply_finish (connection, + data.res, + error); + + g_main_context_pop_thread_default (data.context); + + g_main_context_unref (data.context); + g_main_loop_unref (data.loop); + if (data.res) + g_object_unref (data.res); + + return reply; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + guint id; + guint ref_count; + GDBusMessageFilterFunction filter_function; + gpointer user_data; + GDestroyNotify user_data_free_func; + GMainContext *context; +} FilterData; + +static void +filter_data_destroy (FilterData *filter, gboolean notify_sync) +{ + if (notify_sync) + { + if (filter->user_data_free_func != NULL) + filter->user_data_free_func (filter->user_data); + } + else + { + call_destroy_notify (filter->context, + filter->user_data_free_func, + filter->user_data); + } + g_main_context_unref (filter->context); + g_free (filter); +} + +/* requires CONNECTION_LOCK */ +static FilterData ** +copy_filter_list (GPtrArray *filters) +{ + FilterData **copy; + guint n; + + copy = g_new (FilterData *, filters->len + 1); + for (n = 0; n < filters->len; n++) + { + copy[n] = filters->pdata[n]; + copy[n]->ref_count++; + } + copy[n] = NULL; + + return copy; +} + +/* requires CONNECTION_LOCK */ +static void +free_filter_list (FilterData **filters) +{ + guint n; + + for (n = 0; filters[n]; n++) + { + filters[n]->ref_count--; + if (filters[n]->ref_count == 0) + filter_data_destroy (filters[n], FALSE); + } + g_free (filters); +} + +/* Called in GDBusWorker's thread - we must not block - with no lock held */ +static void +on_worker_message_received (GDBusWorker *worker, + GDBusMessage *message, + gpointer user_data) +{ + GDBusConnection *connection; + FilterData **filters; + guint n; + gboolean alive; + + G_LOCK (message_bus_lock); + alive = g_hash_table_contains (alive_connections, user_data); + if (!alive) + { + G_UNLOCK (message_bus_lock); + return; + } + connection = G_DBUS_CONNECTION (user_data); + g_object_ref (connection); + G_UNLOCK (message_bus_lock); + + //g_debug ("in on_worker_message_received"); + + g_object_ref (message); + g_dbus_message_lock (message); + + //g_debug ("boo ref_count = %d %p %p", G_OBJECT (connection)->ref_count, connection, connection->worker); + + /* First collect the set of callback functions */ + CONNECTION_LOCK (connection); + filters = copy_filter_list (connection->filters); + CONNECTION_UNLOCK (connection); + + /* then call the filters in order (without holding the lock) */ + for (n = 0; filters[n]; n++) + { + message = filters[n]->filter_function (connection, + message, + TRUE, + filters[n]->user_data); + if (message == NULL) + break; + g_dbus_message_lock (message); + } + + CONNECTION_LOCK (connection); + free_filter_list (filters); + CONNECTION_UNLOCK (connection); + + /* Standard dispatch unless the filter ate the message - no need to + * do anything if the message was altered + */ + if (message != NULL) + { + GDBusMessageType message_type; + + message_type = g_dbus_message_get_message_type (message); + if (message_type == G_DBUS_MESSAGE_TYPE_METHOD_RETURN || message_type == G_DBUS_MESSAGE_TYPE_ERROR) + { + guint32 reply_serial; + GTask *task; + + reply_serial = g_dbus_message_get_reply_serial (message); + CONNECTION_LOCK (connection); + task = g_hash_table_lookup (connection->map_method_serial_to_task, + GUINT_TO_POINTER (reply_serial)); + if (task != NULL) + { + /* This removes @task from @map_method_serial_to_task. */ + //g_debug ("delivering reply/error for serial %d for %p", reply_serial, connection); + send_message_data_deliver_reply_unlocked (task, message); + } + else + { + //g_debug ("message reply/error for serial %d but no SendMessageData found for %p", reply_serial, connection); + } + CONNECTION_UNLOCK (connection); + } + else if (message_type == G_DBUS_MESSAGE_TYPE_SIGNAL) + { + CONNECTION_LOCK (connection); + distribute_signals (connection, message); + CONNECTION_UNLOCK (connection); + } + else if (message_type == G_DBUS_MESSAGE_TYPE_METHOD_CALL) + { + CONNECTION_LOCK (connection); + distribute_method_call (connection, message); + CONNECTION_UNLOCK (connection); + } + } + + if (message != NULL) + g_object_unref (message); + g_object_unref (connection); +} + +/* Called in GDBusWorker's thread, lock is not held */ +static GDBusMessage * +on_worker_message_about_to_be_sent (GDBusWorker *worker, + GDBusMessage *message, + gpointer user_data) +{ + GDBusConnection *connection; + FilterData **filters; + guint n; + gboolean alive; + + G_LOCK (message_bus_lock); + alive = g_hash_table_contains (alive_connections, user_data); + if (!alive) + { + G_UNLOCK (message_bus_lock); + return message; + } + connection = G_DBUS_CONNECTION (user_data); + g_object_ref (connection); + G_UNLOCK (message_bus_lock); + + //g_debug ("in on_worker_message_about_to_be_sent"); + + /* First collect the set of callback functions */ + CONNECTION_LOCK (connection); + filters = copy_filter_list (connection->filters); + CONNECTION_UNLOCK (connection); + + /* then call the filters in order (without holding the lock) */ + for (n = 0; filters[n]; n++) + { + g_dbus_message_lock (message); + message = filters[n]->filter_function (connection, + message, + FALSE, + filters[n]->user_data); + if (message == NULL) + break; + } + + CONNECTION_LOCK (connection); + free_filter_list (filters); + CONNECTION_UNLOCK (connection); + + g_object_unref (connection); + + return message; +} + +/* called with connection lock held, in GDBusWorker thread */ +static gboolean +cancel_method_on_close (gpointer key, gpointer value, gpointer user_data) +{ + GTask *task = value; + SendMessageData *data = g_task_get_task_data (task); + + if (data->delivered) + return FALSE; + + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_CLOSED, + _("The connection is closed")); + + /* Ask send_message_with_reply_cleanup not to remove the element from the + * hash table - we're in the middle of a foreach; that would be unsafe. + * Instead, return TRUE from this function so that it gets removed safely. + */ + send_message_with_reply_cleanup (task, FALSE); + return TRUE; +} + +/* Called in GDBusWorker's thread - we must not block - without lock held */ +static void +on_worker_closed (GDBusWorker *worker, + gboolean remote_peer_vanished, + GError *error, + gpointer user_data) +{ + GDBusConnection *connection; + gboolean alive; + guint old_atomic_flags; + + G_LOCK (message_bus_lock); + alive = g_hash_table_contains (alive_connections, user_data); + if (!alive) + { + G_UNLOCK (message_bus_lock); + return; + } + connection = G_DBUS_CONNECTION (user_data); + g_object_ref (connection); + G_UNLOCK (message_bus_lock); + + //g_debug ("in on_worker_closed: %s", error->message); + + CONNECTION_LOCK (connection); + /* Even though this is atomic, we do it inside the lock to avoid breaking + * assumptions in remove_match_rule(). We'd need the lock in a moment + * anyway, so, no loss. + */ + old_atomic_flags = g_atomic_int_or (&connection->atomic_flags, FLAG_CLOSED); + + if (!(old_atomic_flags & FLAG_CLOSED)) + { + g_hash_table_foreach_remove (connection->map_method_serial_to_task, cancel_method_on_close, NULL); + schedule_closed_unlocked (connection, remote_peer_vanished, error); + } + CONNECTION_UNLOCK (connection); + + g_object_unref (connection); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Determines the biggest set of capabilities we can support on this + * connection. + * + * Called with the init_lock held. + */ +static GDBusCapabilityFlags +get_offered_capabilities_max (GDBusConnection *connection) +{ + GDBusCapabilityFlags ret; + ret = G_DBUS_CAPABILITY_FLAGS_NONE; +#ifdef G_OS_UNIX + if (G_IS_UNIX_CONNECTION (connection->stream)) + ret |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; +#endif + return ret; +} + +/* Called in a user thread, lock is not held */ +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (initable); + gboolean ret; + + /* This method needs to be idempotent to work with the singleton + * pattern. See the docs for g_initable_init(). We implement this by + * locking. + * + * Unfortunately we can't use the main lock since the on_worker_*() + * callbacks above needs the lock during initialization (for message + * bus connections we do a synchronous Hello() call on the bus). + */ + g_mutex_lock (&connection->init_lock); + + ret = FALSE; + + /* Make this a no-op if we're already initialized (successfully or + * unsuccessfully) + */ + if ((g_atomic_int_get (&connection->atomic_flags) & FLAG_INITIALIZED)) + { + ret = (connection->initialization_error == NULL); + goto out; + } + + /* Because of init_lock, we can't get here twice in different threads */ + g_assert (connection->initialization_error == NULL); + + /* The user can pass multiple (but mutally exclusive) construct + * properties: + * + * - stream (of type GIOStream) + * - address (of type gchar*) + * + * At the end of the day we end up with a non-NULL GIOStream + * object in connection->stream. + */ + if (connection->address != NULL) + { + g_assert (connection->stream == NULL); + + if ((connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER) || + (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS) || + (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER)) + { + g_set_error_literal (&connection->initialization_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Unsupported flags encountered when constructing a client-side connection")); + goto out; + } + + connection->stream = g_dbus_address_get_stream_sync (connection->address, + NULL, /* TODO: out_guid */ + cancellable, + &connection->initialization_error); + if (connection->stream == NULL) + goto out; + } + else if (connection->stream != NULL) + { + /* nothing to do */ + } + else + { + g_assert_not_reached (); + } + + /* Authenticate the connection */ + if (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER) + { + g_assert (!(connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT)); + g_assert (connection->guid != NULL); + connection->auth = _g_dbus_auth_new (connection->stream); + if (!_g_dbus_auth_run_server (connection->auth, + connection->authentication_observer, + connection->guid, + (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS), + (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER), + get_offered_capabilities_max (connection), + &connection->capabilities, + &connection->credentials, + cancellable, + &connection->initialization_error)) + goto out; + } + else if (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT) + { + g_assert (!(connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER)); + g_assert (connection->guid == NULL); + connection->auth = _g_dbus_auth_new (connection->stream); + connection->guid = _g_dbus_auth_run_client (connection->auth, + connection->authentication_observer, + get_offered_capabilities_max (connection), + &connection->capabilities, + cancellable, + &connection->initialization_error); + if (connection->guid == NULL) + goto out; + } + + if (connection->authentication_observer != NULL) + { + g_object_unref (connection->authentication_observer); + connection->authentication_observer = NULL; + } + + //g_output_stream_flush (G_SOCKET_CONNECTION (connection->stream) + + //g_debug ("haz unix fd passing powers: %d", connection->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); + +#ifdef G_OS_UNIX + /* We want all IO operations to be non-blocking since they happen in + * the worker thread which is shared by _all_ connections. + */ + if (G_IS_SOCKET_CONNECTION (connection->stream)) + { + g_socket_set_blocking (g_socket_connection_get_socket (G_SOCKET_CONNECTION (connection->stream)), FALSE); + } +#endif + + G_LOCK (message_bus_lock); + if (alive_connections == NULL) + alive_connections = g_hash_table_new (g_direct_hash, g_direct_equal); + g_hash_table_add (alive_connections, connection); + G_UNLOCK (message_bus_lock); + + connection->worker = _g_dbus_worker_new (connection->stream, + connection->capabilities, + ((connection->flags & G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) != 0), + on_worker_message_received, + on_worker_message_about_to_be_sent, + on_worker_closed, + connection); + + /* if a bus connection, call org.freedesktop.DBus.Hello - this is how we're getting a name */ + if (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) + { + GVariant *hello_result; + + /* we could lift this restriction by adding code in gdbusprivate.c */ + if (connection->flags & G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) + { + g_set_error_literal (&connection->initialization_error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Cannot use DELAY_MESSAGE_PROCESSING with MESSAGE_BUS_CONNECTION"); + goto out; + } + + hello_result = g_dbus_connection_call_sync (connection, + "org.freedesktop.DBus", /* name */ + "/org/freedesktop/DBus", /* path */ + "org.freedesktop.DBus", /* interface */ + "Hello", + NULL, /* parameters */ + G_VARIANT_TYPE ("(s)"), + CALL_FLAGS_INITIALIZING, + -1, + NULL, /* TODO: cancellable */ + &connection->initialization_error); + if (hello_result == NULL) + goto out; + + g_variant_get (hello_result, "(s)", &connection->bus_unique_name); + g_variant_unref (hello_result); + //g_debug ("unique name is '%s'", connection->bus_unique_name); + } + + ret = TRUE; + out: + if (!ret) + { + g_assert (connection->initialization_error != NULL); + g_propagate_error (error, g_error_copy (connection->initialization_error)); + } + + g_atomic_int_or (&connection->atomic_flags, FLAG_INITIALIZED); + g_mutex_unlock (&connection->init_lock); + + return ret; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = initable_init; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +async_initable_iface_init (GAsyncInitableIface *async_initable_iface) +{ + /* Use default */ +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_new: + * @stream: a #GIOStream + * @guid: (nullable): the GUID to use if authenticating as a server or %NULL + * @flags: flags describing how to make the connection + * @observer: (nullable): a #GDBusAuthObserver or %NULL + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to @callback + * + * Asynchronously sets up a D-Bus connection for exchanging D-Bus messages + * with the end represented by @stream. + * + * If @stream is a #GSocketConnection, then the corresponding #GSocket + * will be put into non-blocking mode. + * + * The D-Bus connection will interact with @stream from a worker thread. + * As a result, the caller should not interact with @stream after this + * method has been called, except by calling g_object_unref() on it. + * + * If @observer is not %NULL it may be used to control the + * authentication process. + * + * When the operation is finished, @callback will be invoked. You can + * then call g_dbus_connection_new_finish() to get the result of the + * operation. + * + * This is an asynchronous failable constructor. See + * g_dbus_connection_new_sync() for the synchronous + * version. + * + * Since: 2.26 + */ +void +g_dbus_connection_new (GIOStream *stream, + const gchar *guid, + GDBusConnectionFlags flags, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + _g_dbus_initialize (); + + g_return_if_fail (G_IS_IO_STREAM (stream)); + g_return_if_fail ((flags & ~G_DBUS_CONNECTION_FLAGS_ALL) == 0); + + g_async_initable_new_async (G_TYPE_DBUS_CONNECTION, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + "stream", stream, + "guid", guid, + "flags", flags, + "authentication-observer", observer, + NULL); +} + +/** + * g_dbus_connection_new_finish: + * @res: a #GAsyncResult obtained from the #GAsyncReadyCallback + * passed to g_dbus_connection_new(). + * @error: return location for error or %NULL + * + * Finishes an operation started with g_dbus_connection_new(). + * + * Returns: (transfer full): a #GDBusConnection or %NULL if @error is set. Free + * with g_object_unref(). + * + * Since: 2.26 + */ +GDBusConnection * +g_dbus_connection_new_finish (GAsyncResult *res, + GError **error) +{ + GObject *object; + GObject *source_object; + + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + source_object = g_async_result_get_source_object (res); + g_assert (source_object != NULL); + object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), + res, + error); + g_object_unref (source_object); + if (object != NULL) + return G_DBUS_CONNECTION (object); + else + return NULL; +} + +/** + * g_dbus_connection_new_sync: + * @stream: a #GIOStream + * @guid: (nullable): the GUID to use if authenticating as a server or %NULL + * @flags: flags describing how to make the connection + * @observer: (nullable): a #GDBusAuthObserver or %NULL + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Synchronously sets up a D-Bus connection for exchanging D-Bus messages + * with the end represented by @stream. + * + * If @stream is a #GSocketConnection, then the corresponding #GSocket + * will be put into non-blocking mode. + * + * The D-Bus connection will interact with @stream from a worker thread. + * As a result, the caller should not interact with @stream after this + * method has been called, except by calling g_object_unref() on it. + * + * If @observer is not %NULL it may be used to control the + * authentication process. + * + * This is a synchronous failable constructor. See + * g_dbus_connection_new() for the asynchronous version. + * + * Returns: (transfer full): a #GDBusConnection or %NULL if @error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusConnection * +g_dbus_connection_new_sync (GIOStream *stream, + const gchar *guid, + GDBusConnectionFlags flags, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GError **error) +{ + _g_dbus_initialize (); + g_return_val_if_fail (G_IS_IO_STREAM (stream), NULL); + g_return_val_if_fail ((flags & ~G_DBUS_CONNECTION_FLAGS_ALL) == 0, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + return g_initable_new (G_TYPE_DBUS_CONNECTION, + cancellable, + error, + "stream", stream, + "guid", guid, + "flags", flags, + "authentication-observer", observer, + NULL); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_new_for_address: + * @address: a D-Bus address + * @flags: flags describing how to make the connection + * @observer: (nullable): a #GDBusAuthObserver or %NULL + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to @callback + * + * Asynchronously connects and sets up a D-Bus client connection for + * exchanging D-Bus messages with an endpoint specified by @address + * which must be in the + * [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). + * + * This constructor can only be used to initiate client-side + * connections - use g_dbus_connection_new() if you need to act as the + * server. In particular, @flags cannot contain the + * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS or + * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER flags. + * + * When the operation is finished, @callback will be invoked. You can + * then call g_dbus_connection_new_for_address_finish() to get the result of + * the operation. + * + * If @observer is not %NULL it may be used to control the + * authentication process. + * + * This is an asynchronous failable constructor. See + * g_dbus_connection_new_for_address_sync() for the synchronous + * version. + * + * Since: 2.26 + */ +void +g_dbus_connection_new_for_address (const gchar *address, + GDBusConnectionFlags flags, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + _g_dbus_initialize (); + + g_return_if_fail (address != NULL); + g_return_if_fail ((flags & ~G_DBUS_CONNECTION_FLAGS_ALL) == 0); + + g_async_initable_new_async (G_TYPE_DBUS_CONNECTION, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + "address", address, + "flags", flags, + "authentication-observer", observer, + NULL); +} + +/** + * g_dbus_connection_new_for_address_finish: + * @res: a #GAsyncResult obtained from the #GAsyncReadyCallback passed + * to g_dbus_connection_new() + * @error: return location for error or %NULL + * + * Finishes an operation started with g_dbus_connection_new_for_address(). + * + * Returns: (transfer full): a #GDBusConnection or %NULL if @error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusConnection * +g_dbus_connection_new_for_address_finish (GAsyncResult *res, + GError **error) +{ + GObject *object; + GObject *source_object; + + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + source_object = g_async_result_get_source_object (res); + g_assert (source_object != NULL); + object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), + res, + error); + g_object_unref (source_object); + if (object != NULL) + return G_DBUS_CONNECTION (object); + else + return NULL; +} + +/** + * g_dbus_connection_new_for_address_sync: + * @address: a D-Bus address + * @flags: flags describing how to make the connection + * @observer: (nullable): a #GDBusAuthObserver or %NULL + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Synchronously connects and sets up a D-Bus client connection for + * exchanging D-Bus messages with an endpoint specified by @address + * which must be in the + * [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). + * + * This constructor can only be used to initiate client-side + * connections - use g_dbus_connection_new_sync() if you need to act + * as the server. In particular, @flags cannot contain the + * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS or + * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER flags. + * + * This is a synchronous failable constructor. See + * g_dbus_connection_new_for_address() for the asynchronous version. + * + * If @observer is not %NULL it may be used to control the + * authentication process. + * + * Returns: (transfer full): a #GDBusConnection or %NULL if @error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusConnection * +g_dbus_connection_new_for_address_sync (const gchar *address, + GDBusConnectionFlags flags, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GError **error) +{ + _g_dbus_initialize (); + + g_return_val_if_fail (address != NULL, NULL); + g_return_val_if_fail ((flags & ~G_DBUS_CONNECTION_FLAGS_ALL) == 0, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + return g_initable_new (G_TYPE_DBUS_CONNECTION, + cancellable, + error, + "address", address, + "flags", flags, + "authentication-observer", observer, + NULL); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_set_exit_on_close: + * @connection: a #GDBusConnection + * @exit_on_close: whether the process should be terminated + * when @connection is closed by the remote peer + * + * Sets whether the process should be terminated when @connection is + * closed by the remote peer. See #GDBusConnection:exit-on-close for + * more details. + * + * Note that this function should be used with care. Most modern UNIX + * desktops tie the notion of a user session with the session bus, and expect + * all of a user's applications to quit when their bus connection goes away. + * If you are setting @exit_on_close to %FALSE for the shared session + * bus connection, you should make sure that your application exits + * when the user session ends. + * + * Since: 2.26 + */ +void +g_dbus_connection_set_exit_on_close (GDBusConnection *connection, + gboolean exit_on_close) +{ + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + + if (exit_on_close) + g_atomic_int_or (&connection->atomic_flags, FLAG_EXIT_ON_CLOSE); + else + g_atomic_int_and (&connection->atomic_flags, ~FLAG_EXIT_ON_CLOSE); + +} + +/** + * g_dbus_connection_get_exit_on_close: + * @connection: a #GDBusConnection + * + * Gets whether the process is terminated when @connection is + * closed by the remote peer. See + * #GDBusConnection:exit-on-close for more details. + * + * Returns: whether the process is terminated when @connection is + * closed by the remote peer + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_get_exit_on_close (GDBusConnection *connection) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + + if (g_atomic_int_get (&connection->atomic_flags) & FLAG_EXIT_ON_CLOSE) + return TRUE; + else + return FALSE; +} + +/** + * g_dbus_connection_get_guid: + * @connection: a #GDBusConnection + * + * The GUID of the peer performing the role of server when + * authenticating. See #GDBusConnection:guid for more details. + * + * Returns: (not nullable): The GUID. Do not free this string, it is owned by + * @connection. + * + * Since: 2.26 + */ +const gchar * +g_dbus_connection_get_guid (GDBusConnection *connection) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + return connection->guid; +} + +/** + * g_dbus_connection_get_unique_name: + * @connection: a #GDBusConnection + * + * Gets the unique name of @connection as assigned by the message + * bus. This can also be used to figure out if @connection is a + * message bus connection. + * + * Returns: (nullable): the unique name or %NULL if @connection is not a message + * bus connection. Do not free this string, it is owned by + * @connection. + * + * Since: 2.26 + */ +const gchar * +g_dbus_connection_get_unique_name (GDBusConnection *connection) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + + /* do not use g_return_val_if_fail(), we want the memory barrier */ + if (!check_initialized (connection)) + return NULL; + + return connection->bus_unique_name; +} + +/** + * g_dbus_connection_get_peer_credentials: + * @connection: a #GDBusConnection + * + * Gets the credentials of the authenticated peer. This will always + * return %NULL unless @connection acted as a server + * (e.g. %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER was passed) + * when set up and the client passed credentials as part of the + * authentication process. + * + * In a message bus setup, the message bus is always the server and + * each application is a client. So this method will always return + * %NULL for message bus clients. + * + * Returns: (transfer none) (nullable): a #GCredentials or %NULL if not + * available. Do not free this object, it is owned by @connection. + * + * Since: 2.26 + */ +GCredentials * +g_dbus_connection_get_peer_credentials (GDBusConnection *connection) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + + /* do not use g_return_val_if_fail(), we want the memory barrier */ + if (!check_initialized (connection)) + return NULL; + + return connection->credentials; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static guint _global_filter_id = 1; /* (atomic) */ + +/** + * g_dbus_connection_add_filter: + * @connection: a #GDBusConnection + * @filter_function: a filter function + * @user_data: user data to pass to @filter_function + * @user_data_free_func: function to free @user_data with when filter + * is removed or %NULL + * + * Adds a message filter. Filters are handlers that are run on all + * incoming and outgoing messages, prior to standard dispatch. Filters + * are run in the order that they were added. The same handler can be + * added as a filter more than once, in which case it will be run more + * than once. Filters added during a filter callback won't be run on + * the message being processed. Filter functions are allowed to modify + * and even drop messages. + * + * Note that filters are run in a dedicated message handling thread so + * they can't block and, generally, can't do anything but signal a + * worker thread. Also note that filters are rarely needed - use API + * such as g_dbus_connection_send_message_with_reply(), + * g_dbus_connection_signal_subscribe() or g_dbus_connection_call() instead. + * + * If a filter consumes an incoming message the message is not + * dispatched anywhere else - not even the standard dispatch machinery + * (that API such as g_dbus_connection_signal_subscribe() and + * g_dbus_connection_send_message_with_reply() relies on) will see the + * message. Similarly, if a filter consumes an outgoing message, the + * message will not be sent to the other peer. + * + * If @user_data_free_func is non-%NULL, it will be called (in the + * thread-default main context of the thread you are calling this + * method from) at some point after @user_data is no longer + * needed. (It is not guaranteed to be called synchronously when the + * filter is removed, and may be called after @connection has been + * destroyed.) + * + * Returns: a filter identifier that can be used with + * g_dbus_connection_remove_filter() + * + * Since: 2.26 + */ +guint +g_dbus_connection_add_filter (GDBusConnection *connection, + GDBusMessageFilterFunction filter_function, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + FilterData *data; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); + g_return_val_if_fail (filter_function != NULL, 0); + g_return_val_if_fail (check_initialized (connection), 0); + + CONNECTION_LOCK (connection); + data = g_new0 (FilterData, 1); + data->id = (guint) g_atomic_int_add (&_global_filter_id, 1); /* TODO: overflow etc. */ + data->ref_count = 1; + data->filter_function = filter_function; + data->user_data = user_data; + data->user_data_free_func = user_data_free_func; + data->context = g_main_context_ref_thread_default (); + g_ptr_array_add (connection->filters, data); + CONNECTION_UNLOCK (connection); + + return data->id; +} + +/* only called from finalize(), removes all filters */ +static void +purge_all_filters (GDBusConnection *connection) +{ + guint n; + + for (n = 0; n < connection->filters->len; n++) + filter_data_destroy (connection->filters->pdata[n], FALSE); +} + +/** + * g_dbus_connection_remove_filter: + * @connection: a #GDBusConnection + * @filter_id: an identifier obtained from g_dbus_connection_add_filter() + * + * Removes a filter. + * + * Note that since filters run in a different thread, there is a race + * condition where it is possible that the filter will be running even + * after calling g_dbus_connection_remove_filter(), so you cannot just + * free data that the filter might be using. Instead, you should pass + * a #GDestroyNotify to g_dbus_connection_add_filter(), which will be + * called when it is guaranteed that the data is no longer needed. + * + * Since: 2.26 + */ +void +g_dbus_connection_remove_filter (GDBusConnection *connection, + guint filter_id) +{ + guint n; + gboolean found; + FilterData *to_destroy; + + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + g_return_if_fail (check_initialized (connection)); + + CONNECTION_LOCK (connection); + found = FALSE; + to_destroy = NULL; + for (n = 0; n < connection->filters->len; n++) + { + FilterData *data = connection->filters->pdata[n]; + if (data->id == filter_id) + { + found = TRUE; + g_ptr_array_remove_index (connection->filters, n); + data->ref_count--; + if (data->ref_count == 0) + to_destroy = data; + break; + } + } + CONNECTION_UNLOCK (connection); + + /* do free without holding lock */ + if (to_destroy != NULL) + filter_data_destroy (to_destroy, TRUE); + else if (!found) + { + g_warning ("g_dbus_connection_remove_filter: No filter found for filter_id %d", filter_id); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + gchar *rule; + gchar *sender; + gchar *sender_unique_name; /* if sender is unique or org.freedesktop.DBus, then that name... otherwise blank */ + gchar *interface_name; + gchar *member; + gchar *object_path; + gchar *arg0; + GDBusSignalFlags flags; + GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */ +} SignalData; + +static void +signal_data_free (SignalData *signal_data) +{ + g_free (signal_data->rule); + g_free (signal_data->sender); + g_free (signal_data->sender_unique_name); + g_free (signal_data->interface_name); + g_free (signal_data->member); + g_free (signal_data->object_path); + g_free (signal_data->arg0); + g_ptr_array_unref (signal_data->subscribers); + g_free (signal_data); +} + +typedef struct +{ + /* All fields are immutable after construction. */ + gatomicrefcount ref_count; + GDBusSignalCallback callback; + gpointer user_data; + GDestroyNotify user_data_free_func; + guint id; + GMainContext *context; +} SignalSubscriber; + +static SignalSubscriber * +signal_subscriber_ref (SignalSubscriber *subscriber) +{ + g_atomic_ref_count_inc (&subscriber->ref_count); + return subscriber; +} + +static void +signal_subscriber_unref (SignalSubscriber *subscriber) +{ + if (g_atomic_ref_count_dec (&subscriber->ref_count)) + { + /* Destroy the user data. It doesn’t matter which thread + * signal_subscriber_unref() is called in (or whether it’s called with a + * lock held), as call_destroy_notify() always defers to the next + * #GMainContext iteration. */ + call_destroy_notify (subscriber->context, + subscriber->user_data_free_func, + subscriber->user_data); + + g_main_context_unref (subscriber->context); + g_free (subscriber); + } +} + +static gchar * +args_to_rule (const gchar *sender, + const gchar *interface_name, + const gchar *member, + const gchar *object_path, + const gchar *arg0, + GDBusSignalFlags flags) +{ + GString *rule; + + rule = g_string_new ("type='signal'"); + if (flags & G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE) + g_string_prepend_c (rule, '-'); + if (sender != NULL) + g_string_append_printf (rule, ",sender='%s'", sender); + if (interface_name != NULL) + g_string_append_printf (rule, ",interface='%s'", interface_name); + if (member != NULL) + g_string_append_printf (rule, ",member='%s'", member); + if (object_path != NULL) + g_string_append_printf (rule, ",path='%s'", object_path); + + if (arg0 != NULL) + { + if (flags & G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH) + g_string_append_printf (rule, ",arg0path='%s'", arg0); + else if (flags & G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE) + g_string_append_printf (rule, ",arg0namespace='%s'", arg0); + else + g_string_append_printf (rule, ",arg0='%s'", arg0); + } + + return g_string_free (rule, FALSE); +} + +static guint _global_subscriber_id = 1; /* (atomic) */ +static guint _global_registration_id = 1; /* (atomic) */ +static guint _global_subtree_registration_id = 1; /* (atomic) */ + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called in a user thread, lock is held */ +static void +add_match_rule (GDBusConnection *connection, + const gchar *match_rule) +{ + GError *error; + GDBusMessage *message; + + if (match_rule[0] == '-') + return; + + message = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */ + "/org/freedesktop/DBus", /* path */ + "org.freedesktop.DBus", /* interface */ + "AddMatch"); + g_dbus_message_set_body (message, g_variant_new ("(s)", match_rule)); + error = NULL; + if (!g_dbus_connection_send_message_unlocked (connection, + message, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + NULL, + &error)) + { + g_critical ("Error while sending AddMatch() message: %s", error->message); + g_error_free (error); + } + g_object_unref (message); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called in a user thread, lock is held */ +static void +remove_match_rule (GDBusConnection *connection, + const gchar *match_rule) +{ + GError *error; + GDBusMessage *message; + + if (match_rule[0] == '-') + return; + + message = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */ + "/org/freedesktop/DBus", /* path */ + "org.freedesktop.DBus", /* interface */ + "RemoveMatch"); + g_dbus_message_set_body (message, g_variant_new ("(s)", match_rule)); + + error = NULL; + if (!g_dbus_connection_send_message_unlocked (connection, + message, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + NULL, + &error)) + { + /* If we could get G_IO_ERROR_CLOSED here, it wouldn't be reasonable to + * critical; but we're holding the lock, and our caller checked whether + * we were already closed, so we can't get that error. + */ + g_critical ("Error while sending RemoveMatch() message: %s", error->message); + g_error_free (error); + } + g_object_unref (message); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +is_signal_data_for_name_lost_or_acquired (SignalData *signal_data) +{ + return g_strcmp0 (signal_data->sender_unique_name, "org.freedesktop.DBus") == 0 && + g_strcmp0 (signal_data->interface_name, "org.freedesktop.DBus") == 0 && + g_strcmp0 (signal_data->object_path, "/org/freedesktop/DBus") == 0 && + (g_strcmp0 (signal_data->member, "NameLost") == 0 || + g_strcmp0 (signal_data->member, "NameAcquired") == 0); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_signal_subscribe: + * @connection: a #GDBusConnection + * @sender: (nullable): sender name to match on (unique or well-known name) + * or %NULL to listen from all senders + * @interface_name: (nullable): D-Bus interface name to match on or %NULL to + * match on all interfaces + * @member: (nullable): D-Bus signal name to match on or %NULL to match on + * all signals + * @object_path: (nullable): object path to match on or %NULL to match on + * all object paths + * @arg0: (nullable): contents of first string argument to match on or %NULL + * to match on all kinds of arguments + * @flags: #GDBusSignalFlags describing how arg0 is used in subscribing to the + * signal + * @callback: callback to invoke when there is a signal matching the requested data + * @user_data: user data to pass to @callback + * @user_data_free_func: (nullable): function to free @user_data with when + * subscription is removed or %NULL + * + * Subscribes to signals on @connection and invokes @callback with a whenever + * the signal is received. Note that @callback will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. + * + * If @connection is not a message bus connection, @sender must be + * %NULL. + * + * If @sender is a well-known name note that @callback is invoked with + * the unique name for the owner of @sender, not the well-known name + * as one would expect. This is because the message bus rewrites the + * name. As such, to avoid certain race conditions, users should be + * tracking the name owner of the well-known name and use that when + * processing the received signal. + * + * If one of %G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE or + * %G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH are given, @arg0 is + * interpreted as part of a namespace or path. The first argument + * of a signal is matched against that part as specified by D-Bus. + * + * If @user_data_free_func is non-%NULL, it will be called (in the + * thread-default main context of the thread you are calling this + * method from) at some point after @user_data is no longer + * needed. (It is not guaranteed to be called synchronously when the + * signal is unsubscribed from, and may be called after @connection + * has been destroyed.) + * + * As @callback is potentially invoked in a different thread from where it’s + * emitted, it’s possible for this to happen after + * g_dbus_connection_signal_unsubscribe() has been called in another thread. + * Due to this, @user_data should have a strong reference which is freed with + * @user_data_free_func, rather than pointing to data whose lifecycle is tied + * to the signal subscription. For example, if a #GObject is used to store the + * subscription ID from g_dbus_connection_signal_subscribe(), a strong reference + * to that #GObject must be passed to @user_data, and g_object_unref() passed to + * @user_data_free_func. You are responsible for breaking the resulting + * reference count cycle by explicitly unsubscribing from the signal when + * dropping the last external reference to the #GObject. Alternatively, a weak + * reference may be used. + * + * It is guaranteed that if you unsubscribe from a signal using + * g_dbus_connection_signal_unsubscribe() from the same thread which made the + * corresponding g_dbus_connection_signal_subscribe() call, @callback will not + * be invoked after g_dbus_connection_signal_unsubscribe() returns. + * + * The returned subscription identifier is an opaque value which is guaranteed + * to never be zero. + * + * This function can never fail. + * + * Returns: a subscription identifier that can be used with g_dbus_connection_signal_unsubscribe() + * + * Since: 2.26 + */ +guint +g_dbus_connection_signal_subscribe (GDBusConnection *connection, + const gchar *sender, + const gchar *interface_name, + const gchar *member, + const gchar *object_path, + const gchar *arg0, + GDBusSignalFlags flags, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + gchar *rule; + SignalData *signal_data; + SignalSubscriber *subscriber; + GPtrArray *signal_data_array; + const gchar *sender_unique_name; + + /* Right now we abort if AddMatch() fails since it can only fail with the bus being in + * an OOM condition. We might want to change that but that would involve making + * g_dbus_connection_signal_subscribe() asynchronous and having the call sites + * handle that. And there's really no sensible way of handling this short of retrying + * to add the match rule... and then there's the little thing that, hey, maybe there's + * a reason the bus in an OOM condition. + * + * Doable, but not really sure it's worth it... + */ + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); + g_return_val_if_fail (sender == NULL || (g_dbus_is_name (sender) && (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION)), 0); + g_return_val_if_fail (interface_name == NULL || g_dbus_is_interface_name (interface_name), 0); + g_return_val_if_fail (member == NULL || g_dbus_is_member_name (member), 0); + g_return_val_if_fail (object_path == NULL || g_variant_is_object_path (object_path), 0); + g_return_val_if_fail (callback != NULL, 0); + g_return_val_if_fail (check_initialized (connection), 0); + g_return_val_if_fail (!((flags & G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH) && (flags & G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE)), 0); + g_return_val_if_fail (!(arg0 == NULL && (flags & (G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH | G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE))), 0); + + CONNECTION_LOCK (connection); + + /* If G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE was specified, we will end up + * with a '-' character to prefix the rule (which will otherwise be + * normal). + * + * This allows us to hash the rule and do our lifecycle tracking in + * the usual way, but the '-' prevents the match rule from ever + * actually being send to the bus (either for add or remove). + */ + rule = args_to_rule (sender, interface_name, member, object_path, arg0, flags); + + if (sender != NULL && (g_dbus_is_unique_name (sender) || g_strcmp0 (sender, "org.freedesktop.DBus") == 0)) + sender_unique_name = sender; + else + sender_unique_name = ""; + + subscriber = g_new0 (SignalSubscriber, 1); + subscriber->ref_count = 1; + subscriber->callback = callback; + subscriber->user_data = user_data; + subscriber->user_data_free_func = user_data_free_func; + subscriber->id = (guint) g_atomic_int_add (&_global_subscriber_id, 1); /* TODO: overflow etc. */ + subscriber->context = g_main_context_ref_thread_default (); + + /* see if we've already have this rule */ + signal_data = g_hash_table_lookup (connection->map_rule_to_signal_data, rule); + if (signal_data != NULL) + { + g_ptr_array_add (signal_data->subscribers, subscriber); + g_free (rule); + goto out; + } + + signal_data = g_new0 (SignalData, 1); + signal_data->rule = rule; + signal_data->sender = g_strdup (sender); + signal_data->sender_unique_name = g_strdup (sender_unique_name); + signal_data->interface_name = g_strdup (interface_name); + signal_data->member = g_strdup (member); + signal_data->object_path = g_strdup (object_path); + signal_data->arg0 = g_strdup (arg0); + signal_data->flags = flags; + signal_data->subscribers = g_ptr_array_new_with_free_func ((GDestroyNotify) signal_subscriber_unref); + g_ptr_array_add (signal_data->subscribers, subscriber); + + g_hash_table_insert (connection->map_rule_to_signal_data, + signal_data->rule, + signal_data); + + /* Add the match rule to the bus... + * + * Avoid adding match rules for NameLost and NameAcquired messages - the bus will + * always send such messages to us. + */ + if (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) + { + if (!is_signal_data_for_name_lost_or_acquired (signal_data)) + add_match_rule (connection, signal_data->rule); + } + + signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, + signal_data->sender_unique_name); + if (signal_data_array == NULL) + { + signal_data_array = g_ptr_array_new (); + g_hash_table_insert (connection->map_sender_unique_name_to_signal_data_array, + g_strdup (signal_data->sender_unique_name), + signal_data_array); + } + g_ptr_array_add (signal_data_array, signal_data); + + out: + g_hash_table_insert (connection->map_id_to_signal_data, + GUINT_TO_POINTER (subscriber->id), + signal_data); + + CONNECTION_UNLOCK (connection); + + return subscriber->id; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* called in any thread */ +/* must hold lock when calling this (except if connection->finalizing is TRUE) + * returns the number of removed subscribers */ +static guint +unsubscribe_id_internal (GDBusConnection *connection, + guint subscription_id) +{ + SignalData *signal_data; + GPtrArray *signal_data_array; + guint n; + guint n_removed = 0; + + signal_data = g_hash_table_lookup (connection->map_id_to_signal_data, + GUINT_TO_POINTER (subscription_id)); + if (signal_data == NULL) + { + /* Don't warn here, we may have thrown all subscriptions out when the connection was closed */ + goto out; + } + + for (n = 0; n < signal_data->subscribers->len; n++) + { + SignalSubscriber *subscriber = signal_data->subscribers->pdata[n]; + + if (subscriber->id != subscription_id) + continue; + + /* It’s OK to rearrange the array order using the ‘fast’ #GPtrArray + * removal functions, since we’re going to exit the loop below anyway — we + * never move on to the next element. Secondly, subscription IDs are + * guaranteed to be unique. */ + g_warn_if_fail (g_hash_table_remove (connection->map_id_to_signal_data, + GUINT_TO_POINTER (subscription_id))); + n_removed++; + g_ptr_array_remove_index_fast (signal_data->subscribers, n); + + if (signal_data->subscribers->len == 0) + { + g_warn_if_fail (g_hash_table_remove (connection->map_rule_to_signal_data, signal_data->rule)); + + signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, + signal_data->sender_unique_name); + g_warn_if_fail (signal_data_array != NULL); + g_warn_if_fail (g_ptr_array_remove (signal_data_array, signal_data)); + + if (signal_data_array->len == 0) + { + g_warn_if_fail (g_hash_table_remove (connection->map_sender_unique_name_to_signal_data_array, + signal_data->sender_unique_name)); + } + + /* remove the match rule from the bus unless NameLost or NameAcquired (see subscribe()) */ + if ((connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) && + !is_signal_data_for_name_lost_or_acquired (signal_data) && + !g_dbus_connection_is_closed (connection) && + !connection->finalizing) + { + /* The check for g_dbus_connection_is_closed() means that + * sending the RemoveMatch message can't fail with + * G_IO_ERROR_CLOSED, because we're holding the lock, + * so on_worker_closed() can't happen between the check we just + * did, and releasing the lock later. + */ + remove_match_rule (connection, signal_data->rule); + } + + signal_data_free (signal_data); + } + + goto out; + } + + g_assert_not_reached (); + + out: + return n_removed; +} + +/** + * g_dbus_connection_signal_unsubscribe: + * @connection: a #GDBusConnection + * @subscription_id: a subscription id obtained from + * g_dbus_connection_signal_subscribe() + * + * Unsubscribes from signals. + * + * Note that there may still be D-Bus traffic to process (relating to this + * signal subscription) in the current thread-default #GMainContext after this + * function has returned. You should continue to iterate the #GMainContext + * until the #GDestroyNotify function passed to + * g_dbus_connection_signal_subscribe() is called, in order to avoid memory + * leaks through callbacks queued on the #GMainContext after it’s stopped being + * iterated. + * Alternatively, any idle source with a priority lower than %G_PRIORITY_DEFAULT + * that was scheduled after unsubscription, also indicates that all resources + * of this subscription are released. + * + * Since: 2.26 + */ +void +g_dbus_connection_signal_unsubscribe (GDBusConnection *connection, + guint subscription_id) +{ + guint n_subscribers_removed G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + g_return_if_fail (check_initialized (connection)); + + CONNECTION_LOCK (connection); + n_subscribers_removed = unsubscribe_id_internal (connection, subscription_id); + CONNECTION_UNLOCK (connection); + + /* invariant */ + g_assert (n_subscribers_removed == 0 || n_subscribers_removed == 1); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + SignalSubscriber *subscriber; /* (owned) */ + GDBusMessage *message; + GDBusConnection *connection; + const gchar *sender; /* (nullable) for peer-to-peer connections */ + const gchar *path; + const gchar *interface; + const gchar *member; +} SignalInstance; + +/* called on delivery thread (e.g. where g_dbus_connection_signal_subscribe() was called) with + * no locks held + */ +static gboolean +emit_signal_instance_in_idle_cb (gpointer data) +{ + SignalInstance *signal_instance = data; + GVariant *parameters; + gboolean has_subscription; + + parameters = g_dbus_message_get_body (signal_instance->message); + if (parameters == NULL) + { + parameters = g_variant_new ("()"); + g_variant_ref_sink (parameters); + } + else + { + g_variant_ref_sink (parameters); + } + +#if 0 + g_print ("in emit_signal_instance_in_idle_cb (id=%d sender=%s path=%s interface=%s member=%s params=%s)\n", + signal_instance->subscriber->id, + signal_instance->sender, + signal_instance->path, + signal_instance->interface, + signal_instance->member, + g_variant_print (parameters, TRUE)); +#endif + + /* Careful here, don't do the callback if we no longer has the subscription */ + CONNECTION_LOCK (signal_instance->connection); + has_subscription = FALSE; + if (g_hash_table_lookup (signal_instance->connection->map_id_to_signal_data, + GUINT_TO_POINTER (signal_instance->subscriber->id)) != NULL) + has_subscription = TRUE; + CONNECTION_UNLOCK (signal_instance->connection); + + if (has_subscription) + signal_instance->subscriber->callback (signal_instance->connection, + signal_instance->sender, + signal_instance->path, + signal_instance->interface, + signal_instance->member, + parameters, + signal_instance->subscriber->user_data); + + g_variant_unref (parameters); + + return FALSE; +} + +static void +signal_instance_free (SignalInstance *signal_instance) +{ + g_object_unref (signal_instance->message); + g_object_unref (signal_instance->connection); + signal_subscriber_unref (signal_instance->subscriber); + g_free (signal_instance); +} + +static gboolean +namespace_rule_matches (const gchar *namespace, + const gchar *name) +{ + gint len_namespace; + gint len_name; + + len_namespace = strlen (namespace); + len_name = strlen (name); + + if (len_name < len_namespace) + return FALSE; + + if (memcmp (namespace, name, len_namespace) != 0) + return FALSE; + + return len_namespace == len_name || name[len_namespace] == '.'; +} + +static gboolean +path_rule_matches (const gchar *path_a, + const gchar *path_b) +{ + gint len_a, len_b; + + len_a = strlen (path_a); + len_b = strlen (path_b); + + if (len_a < len_b && (len_a == 0 || path_a[len_a - 1] != '/')) + return FALSE; + + if (len_b < len_a && (len_b == 0 || path_b[len_b - 1] != '/')) + return FALSE; + + return memcmp (path_a, path_b, MIN (len_a, len_b)) == 0; +} + +/* called in GDBusWorker thread WITH lock held + * + * @sender is (nullable) for peer-to-peer connections */ +static void +schedule_callbacks (GDBusConnection *connection, + GPtrArray *signal_data_array, + GDBusMessage *message, + const gchar *sender) +{ + guint n, m; + const gchar *interface; + const gchar *member; + const gchar *path; + const gchar *arg0; + + interface = NULL; + member = NULL; + path = NULL; + arg0 = NULL; + + interface = g_dbus_message_get_interface (message); + member = g_dbus_message_get_member (message); + path = g_dbus_message_get_path (message); + arg0 = g_dbus_message_get_arg0 (message); + +#if 0 + g_print ("In schedule_callbacks:\n" + " sender = '%s'\n" + " interface = '%s'\n" + " member = '%s'\n" + " path = '%s'\n" + " arg0 = '%s'\n", + sender, + interface, + member, + path, + arg0); +#endif + + /* TODO: if this is slow, then we can change signal_data_array into + * map_object_path_to_signal_data_array or something. + */ + for (n = 0; n < signal_data_array->len; n++) + { + SignalData *signal_data = signal_data_array->pdata[n]; + + if (signal_data->interface_name != NULL && g_strcmp0 (signal_data->interface_name, interface) != 0) + continue; + + if (signal_data->member != NULL && g_strcmp0 (signal_data->member, member) != 0) + continue; + + if (signal_data->object_path != NULL && g_strcmp0 (signal_data->object_path, path) != 0) + continue; + + if (signal_data->arg0 != NULL) + { + if (arg0 == NULL) + continue; + + if (signal_data->flags & G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE) + { + if (!namespace_rule_matches (signal_data->arg0, arg0)) + continue; + } + else if (signal_data->flags & G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH) + { + if (!path_rule_matches (signal_data->arg0, arg0)) + continue; + } + else if (!g_str_equal (signal_data->arg0, arg0)) + continue; + } + + for (m = 0; m < signal_data->subscribers->len; m++) + { + SignalSubscriber *subscriber = signal_data->subscribers->pdata[m]; + GSource *idle_source; + SignalInstance *signal_instance; + + signal_instance = g_new0 (SignalInstance, 1); + signal_instance->subscriber = signal_subscriber_ref (subscriber); + signal_instance->message = g_object_ref (message); + signal_instance->connection = g_object_ref (connection); + signal_instance->sender = sender; + signal_instance->path = path; + signal_instance->interface = interface; + signal_instance->member = member; + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + emit_signal_instance_in_idle_cb, + signal_instance, + (GDestroyNotify) signal_instance_free); + g_source_set_static_name (idle_source, "[gio] emit_signal_instance_in_idle_cb"); + g_source_attach (idle_source, subscriber->context); + g_source_unref (idle_source); + } + } +} + +/* called in GDBusWorker thread with lock held */ +static void +distribute_signals (GDBusConnection *connection, + GDBusMessage *message) +{ + GPtrArray *signal_data_array; + const gchar *sender; + + sender = g_dbus_message_get_sender (message); + + if (G_UNLIKELY (_g_dbus_debug_signal ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Signal:\n" + " <<<< RECEIVED SIGNAL %s.%s\n" + " on object %s\n" + " sent by name %s\n", + g_dbus_message_get_interface (message), + g_dbus_message_get_member (message), + g_dbus_message_get_path (message), + sender != NULL ? sender : "(none)"); + _g_dbus_debug_print_unlock (); + } + + /* collect subscribers that match on sender */ + if (sender != NULL) + { + signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, sender); + if (signal_data_array != NULL) + schedule_callbacks (connection, signal_data_array, message, sender); + } + + /* collect subscribers not matching on sender */ + signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, ""); + if (signal_data_array != NULL) + schedule_callbacks (connection, signal_data_array, message, sender); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* only called from finalize(), removes all subscriptions */ +static void +purge_all_signal_subscriptions (GDBusConnection *connection) +{ + GHashTableIter iter; + gpointer key; + GArray *ids; + guint n; + + ids = g_array_new (FALSE, FALSE, sizeof (guint)); + g_hash_table_iter_init (&iter, connection->map_id_to_signal_data); + while (g_hash_table_iter_next (&iter, &key, NULL)) + { + guint subscription_id = GPOINTER_TO_UINT (key); + g_array_append_val (ids, subscription_id); + } + + for (n = 0; n < ids->len; n++) + { + guint subscription_id = g_array_index (ids, guint, n); + unsubscribe_id_internal (connection, subscription_id); + } + g_array_free (ids, TRUE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusInterfaceVTable * +_g_dbus_interface_vtable_copy (const GDBusInterfaceVTable *vtable) +{ + /* Don't waste memory by copying padding - remember to update this + * when changing struct _GDBusInterfaceVTable in gdbusconnection.h + */ + return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer)); +} + +static void +_g_dbus_interface_vtable_free (GDBusInterfaceVTable *vtable) +{ + g_free (vtable); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusSubtreeVTable * +_g_dbus_subtree_vtable_copy (const GDBusSubtreeVTable *vtable) +{ + /* Don't waste memory by copying padding - remember to update this + * when changing struct _GDBusSubtreeVTable in gdbusconnection.h + */ + return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer)); +} + +static void +_g_dbus_subtree_vtable_free (GDBusSubtreeVTable *vtable) +{ + g_free (vtable); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +struct ExportedObject +{ + gchar *object_path; + GDBusConnection *connection; + + /* maps gchar* -> ExportedInterface* */ + GHashTable *map_if_name_to_ei; +}; + +/* only called with lock held */ +static void +exported_object_free (ExportedObject *eo) +{ + g_free (eo->object_path); + g_hash_table_unref (eo->map_if_name_to_ei); + g_free (eo); +} + +typedef struct +{ + ExportedObject *eo; + + gint refcount; /* (atomic) */ + + guint id; + gchar *interface_name; /* (owned) */ + GDBusInterfaceVTable *vtable; /* (owned) */ + GDBusInterfaceInfo *interface_info; /* (owned) */ + + GMainContext *context; /* (owned) */ + gpointer user_data; + GDestroyNotify user_data_free_func; +} ExportedInterface; + +static ExportedInterface * +exported_interface_ref (ExportedInterface *ei) +{ + g_atomic_int_inc (&ei->refcount); + + return ei; +} + +/* May be called with lock held */ +static void +exported_interface_unref (ExportedInterface *ei) +{ + if (!g_atomic_int_dec_and_test (&ei->refcount)) + return; + + g_dbus_interface_info_cache_release (ei->interface_info); + g_dbus_interface_info_unref ((GDBusInterfaceInfo *) ei->interface_info); + + /* All uses of ei->vtable from callbacks scheduled in idle functions must + * have completed by this call_destroy_notify() call, as language bindings + * may destroy function closures in this callback. */ + call_destroy_notify (ei->context, + ei->user_data_free_func, + ei->user_data); + + g_main_context_unref (ei->context); + + g_free (ei->interface_name); + _g_dbus_interface_vtable_free (ei->vtable); + g_free (ei); +} + +struct ExportedSubtree +{ + gint refcount; /* (atomic) */ + + guint id; + gchar *object_path; /* (owned) */ + GDBusConnection *connection; /* (unowned) */ + GDBusSubtreeVTable *vtable; /* (owned) */ + GDBusSubtreeFlags flags; + + GMainContext *context; /* (owned) */ + gpointer user_data; + GDestroyNotify user_data_free_func; +}; + +static ExportedSubtree * +exported_subtree_ref (ExportedSubtree *es) +{ + g_atomic_int_inc (&es->refcount); + + return es; +} + +/* May be called with lock held */ +static void +exported_subtree_unref (ExportedSubtree *es) +{ + if (!g_atomic_int_dec_and_test (&es->refcount)) + return; + + /* All uses of es->vtable from callbacks scheduled in idle functions must + * have completed by this call_destroy_notify() call, as language bindings + * may destroy function closures in this callback. */ + call_destroy_notify (es->context, + es->user_data_free_func, + es->user_data); + + g_main_context_unref (es->context); + + _g_dbus_subtree_vtable_free (es->vtable); + g_free (es->object_path); + g_free (es); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Convenience function to check if @registration_id (if not zero) or + * @subtree_registration_id (if not zero) has been unregistered. If + * so, returns %TRUE. + * + * If not, sets @out_ei and/or @out_es to a strong reference to the relevant + * #ExportedInterface/#ExportedSubtree and returns %FALSE. + * + * May be called by any thread. Caller must *not* hold lock. + */ +static gboolean +has_object_been_unregistered (GDBusConnection *connection, + guint registration_id, + ExportedInterface **out_ei, + guint subtree_registration_id, + ExportedSubtree **out_es) +{ + gboolean ret; + ExportedInterface *ei = NULL; + gpointer es = NULL; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + + ret = FALSE; + + CONNECTION_LOCK (connection); + + if (registration_id != 0) + { + ei = g_hash_table_lookup (connection->map_id_to_ei, GUINT_TO_POINTER (registration_id)); + if (ei == NULL) + ret = TRUE; + else if (out_ei != NULL) + *out_ei = exported_interface_ref (ei); + } + if (subtree_registration_id != 0) + { + es = g_hash_table_lookup (connection->map_id_to_es, GUINT_TO_POINTER (subtree_registration_id)); + if (es == NULL) + ret = TRUE; + else if (out_es != NULL) + *out_es = exported_subtree_ref (es); + } + + CONNECTION_UNLOCK (connection); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GDBusConnection *connection; + GDBusMessage *message; + gpointer user_data; + const gchar *property_name; + const GDBusInterfaceVTable *vtable; + GDBusInterfaceInfo *interface_info; + const GDBusPropertyInfo *property_info; + guint registration_id; + guint subtree_registration_id; +} PropertyData; + +static void +property_data_free (PropertyData *data) +{ + g_object_unref (data->connection); + g_object_unref (data->message); + g_free (data); +} + +/* called in thread where object was registered - no locks held */ +static gboolean +invoke_get_property_in_idle_cb (gpointer _data) +{ + PropertyData *data = _data; + GVariant *value; + GError *error; + GDBusMessage *reply; + ExportedInterface *ei = NULL; + ExportedSubtree *es = NULL; + + if (has_object_been_unregistered (data->connection, + data->registration_id, + &ei, + data->subtree_registration_id, + &es)) + { + reply = g_dbus_message_new_method_error (data->message, + "org.freedesktop.DBus.Error.UnknownMethod", + _("No such interface “org.freedesktop.DBus.Properties†on object at path %s"), + g_dbus_message_get_path (data->message)); + g_dbus_connection_send_message (data->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + goto out; + } + + error = NULL; + value = data->vtable->get_property (data->connection, + g_dbus_message_get_sender (data->message), + g_dbus_message_get_path (data->message), + data->interface_info->name, + data->property_name, + &error, + data->user_data); + + + if (value != NULL) + { + g_assert_no_error (error); + + g_variant_take_ref (value); + reply = g_dbus_message_new_method_reply (data->message); + g_dbus_message_set_body (reply, g_variant_new ("(v)", value)); + g_dbus_connection_send_message (data->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_variant_unref (value); + g_object_unref (reply); + } + else + { + gchar *dbus_error_name; + g_assert (error != NULL); + dbus_error_name = g_dbus_error_encode_gerror (error); + reply = g_dbus_message_new_method_error_literal (data->message, + dbus_error_name, + error->message); + g_dbus_connection_send_message (data->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_free (dbus_error_name); + g_error_free (error); + g_object_unref (reply); + } + + out: + g_clear_pointer (&ei, exported_interface_unref); + g_clear_pointer (&es, exported_subtree_unref); + + return FALSE; +} + +/* called in thread where object was registered - no locks held */ +static gboolean +invoke_set_property_in_idle_cb (gpointer _data) +{ + PropertyData *data = _data; + GError *error; + GDBusMessage *reply; + GVariant *value; + + error = NULL; + value = NULL; + + g_variant_get (g_dbus_message_get_body (data->message), + "(ssv)", + NULL, + NULL, + &value); + + if (!data->vtable->set_property (data->connection, + g_dbus_message_get_sender (data->message), + g_dbus_message_get_path (data->message), + data->interface_info->name, + data->property_name, + value, + &error, + data->user_data)) + { + gchar *dbus_error_name; + g_assert (error != NULL); + dbus_error_name = g_dbus_error_encode_gerror (error); + reply = g_dbus_message_new_method_error_literal (data->message, + dbus_error_name, + error->message); + g_free (dbus_error_name); + g_error_free (error); + } + else + { + reply = g_dbus_message_new_method_reply (data->message); + } + + g_assert (reply != NULL); + g_dbus_connection_send_message (data->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + g_variant_unref (value); + + return FALSE; +} + +/* called in any thread with connection's lock held */ +static gboolean +validate_and_maybe_schedule_property_getset (GDBusConnection *connection, + GDBusMessage *message, + guint registration_id, + guint subtree_registration_id, + gboolean is_get, + GDBusInterfaceInfo *interface_info, + const GDBusInterfaceVTable *vtable, + GMainContext *main_context, + gpointer user_data) +{ + gboolean handled; + const char *interface_name; + const char *property_name; + const GDBusPropertyInfo *property_info; + GSource *idle_source; + PropertyData *property_data; + GDBusMessage *reply; + + handled = FALSE; + + if (is_get) + g_variant_get (g_dbus_message_get_body (message), + "(&s&s)", + &interface_name, + &property_name); + else + g_variant_get (g_dbus_message_get_body (message), + "(&s&sv)", + &interface_name, + &property_name, + NULL); + + if (vtable == NULL) + goto out; + + /* Check that the property exists - if not fail with org.freedesktop.DBus.Error.InvalidArgs + */ + property_info = NULL; + + /* TODO: the cost of this is O(n) - it might be worth caching the result */ + property_info = g_dbus_interface_info_lookup_property (interface_info, property_name); + if (property_info == NULL) + { + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.InvalidArgs", + _("No such property “%sâ€"), + property_name); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + handled = TRUE; + goto out; + } + + if (is_get && !(property_info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)) + { + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.InvalidArgs", + _("Property “%s†is not readable"), + property_name); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + handled = TRUE; + goto out; + } + else if (!is_get && !(property_info->flags & G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE)) + { + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.InvalidArgs", + _("Property “%s†is not writable"), + property_name); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + handled = TRUE; + goto out; + } + + if (!is_get) + { + GVariant *value; + + /* Fail with org.freedesktop.DBus.Error.InvalidArgs if the type + * of the given value is wrong + */ + g_variant_get_child (g_dbus_message_get_body (message), 2, "v", &value); + if (g_strcmp0 (g_variant_get_type_string (value), property_info->signature) != 0) + { + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.InvalidArgs", + _("Error setting property “%sâ€: Expected type “%s†but got “%sâ€"), + property_name, property_info->signature, + g_variant_get_type_string (value)); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_variant_unref (value); + g_object_unref (reply); + handled = TRUE; + goto out; + } + + g_variant_unref (value); + } + + /* If the vtable pointer for get_property() resp. set_property() is + * NULL then dispatch the call via the method_call() handler. + */ + if (is_get) + { + if (vtable->get_property == NULL) + { + schedule_method_call (connection, message, registration_id, subtree_registration_id, + interface_info, NULL, property_info, g_dbus_message_get_body (message), + vtable, main_context, user_data); + handled = TRUE; + goto out; + } + } + else + { + if (vtable->set_property == NULL) + { + schedule_method_call (connection, message, registration_id, subtree_registration_id, + interface_info, NULL, property_info, g_dbus_message_get_body (message), + vtable, main_context, user_data); + handled = TRUE; + goto out; + } + } + + /* ok, got the property info - call user code in an idle handler */ + property_data = g_new0 (PropertyData, 1); + property_data->connection = g_object_ref (connection); + property_data->message = g_object_ref (message); + property_data->user_data = user_data; + property_data->property_name = property_name; + property_data->vtable = vtable; + property_data->interface_info = interface_info; + property_data->property_info = property_info; + property_data->registration_id = registration_id; + property_data->subtree_registration_id = subtree_registration_id; + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + is_get ? invoke_get_property_in_idle_cb : invoke_set_property_in_idle_cb, + property_data, + (GDestroyNotify) property_data_free); + if (is_get) + g_source_set_static_name (idle_source, "[gio] invoke_get_property_in_idle_cb"); + else + g_source_set_static_name (idle_source, "[gio] invoke_set_property_in_idle_cb"); + g_source_attach (idle_source, main_context); + g_source_unref (idle_source); + + handled = TRUE; + + out: + return handled; +} + +/* called in GDBusWorker thread with connection's lock held */ +static gboolean +handle_getset_property (GDBusConnection *connection, + ExportedObject *eo, + GDBusMessage *message, + gboolean is_get) +{ + ExportedInterface *ei; + gboolean handled; + const char *interface_name; + const char *property_name; + + handled = FALSE; + + if (is_get) + g_variant_get (g_dbus_message_get_body (message), + "(&s&s)", + &interface_name, + &property_name); + else + g_variant_get (g_dbus_message_get_body (message), + "(&s&sv)", + &interface_name, + &property_name, + NULL); + + /* Fail with org.freedesktop.DBus.Error.InvalidArgs if there is + * no such interface registered + */ + ei = g_hash_table_lookup (eo->map_if_name_to_ei, interface_name); + if (ei == NULL) + { + GDBusMessage *reply; + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.InvalidArgs", + _("No such interface “%sâ€"), + interface_name); + g_dbus_connection_send_message_unlocked (eo->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + handled = TRUE; + goto out; + } + + handled = validate_and_maybe_schedule_property_getset (eo->connection, + message, + ei->id, + 0, + is_get, + ei->interface_info, + ei->vtable, + ei->context, + ei->user_data); + out: + return handled; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GDBusConnection *connection; + GDBusMessage *message; + gpointer user_data; + const GDBusInterfaceVTable *vtable; + GDBusInterfaceInfo *interface_info; + guint registration_id; + guint subtree_registration_id; +} PropertyGetAllData; + +static void +property_get_all_data_free (PropertyData *data) +{ + g_object_unref (data->connection); + g_object_unref (data->message); + g_free (data); +} + +/* called in thread where object was registered - no locks held */ +static gboolean +invoke_get_all_properties_in_idle_cb (gpointer _data) +{ + PropertyGetAllData *data = _data; + GVariantBuilder builder; + GDBusMessage *reply; + guint n; + ExportedInterface *ei = NULL; + ExportedSubtree *es = NULL; + + if (has_object_been_unregistered (data->connection, + data->registration_id, + &ei, + data->subtree_registration_id, + &es)) + { + reply = g_dbus_message_new_method_error (data->message, + "org.freedesktop.DBus.Error.UnknownMethod", + _("No such interface “org.freedesktop.DBus.Properties†on object at path %s"), + g_dbus_message_get_path (data->message)); + g_dbus_connection_send_message (data->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + goto out; + } + + /* TODO: Right now we never fail this call - we just omit values if + * a get_property() call is failing. + * + * We could fail the whole call if just a single get_property() call + * returns an error. We need clarification in the D-Bus spec about this. + */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a{sv})")); + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}")); + for (n = 0; data->interface_info->properties != NULL && data->interface_info->properties[n] != NULL; n++) + { + const GDBusPropertyInfo *property_info = data->interface_info->properties[n]; + GVariant *value; + + if (!(property_info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)) + continue; + + value = data->vtable->get_property (data->connection, + g_dbus_message_get_sender (data->message), + g_dbus_message_get_path (data->message), + data->interface_info->name, + property_info->name, + NULL, + data->user_data); + + if (value == NULL) + continue; + + g_variant_take_ref (value); + g_variant_builder_add (&builder, + "{sv}", + property_info->name, + value); + g_variant_unref (value); + } + g_variant_builder_close (&builder); + + reply = g_dbus_message_new_method_reply (data->message); + g_dbus_message_set_body (reply, g_variant_builder_end (&builder)); + g_dbus_connection_send_message (data->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + + out: + g_clear_pointer (&ei, exported_interface_unref); + g_clear_pointer (&es, exported_subtree_unref); + + return FALSE; +} + +static gboolean +interface_has_readable_properties (GDBusInterfaceInfo *interface_info) +{ + gint i; + + if (!interface_info->properties) + return FALSE; + + for (i = 0; interface_info->properties[i]; i++) + if (interface_info->properties[i]->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE) + return TRUE; + + return FALSE; +} + +/* called in any thread with connection's lock held */ +static gboolean +validate_and_maybe_schedule_property_get_all (GDBusConnection *connection, + GDBusMessage *message, + guint registration_id, + guint subtree_registration_id, + GDBusInterfaceInfo *interface_info, + const GDBusInterfaceVTable *vtable, + GMainContext *main_context, + gpointer user_data) +{ + gboolean handled; + GSource *idle_source; + PropertyGetAllData *property_get_all_data; + + handled = FALSE; + + if (vtable == NULL) + goto out; + + /* If the vtable pointer for get_property() is NULL but we have a + * non-zero number of readable properties, then dispatch the call via + * the method_call() handler. + */ + if (vtable->get_property == NULL && interface_has_readable_properties (interface_info)) + { + schedule_method_call (connection, message, registration_id, subtree_registration_id, + interface_info, NULL, NULL, g_dbus_message_get_body (message), + vtable, main_context, user_data); + handled = TRUE; + goto out; + } + + /* ok, got the property info - call user in an idle handler */ + property_get_all_data = g_new0 (PropertyGetAllData, 1); + property_get_all_data->connection = g_object_ref (connection); + property_get_all_data->message = g_object_ref (message); + property_get_all_data->user_data = user_data; + property_get_all_data->vtable = vtable; + property_get_all_data->interface_info = interface_info; + property_get_all_data->registration_id = registration_id; + property_get_all_data->subtree_registration_id = subtree_registration_id; + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + invoke_get_all_properties_in_idle_cb, + property_get_all_data, + (GDestroyNotify) property_get_all_data_free); + g_source_set_static_name (idle_source, "[gio] invoke_get_all_properties_in_idle_cb"); + g_source_attach (idle_source, main_context); + g_source_unref (idle_source); + + handled = TRUE; + + out: + return handled; +} + +/* called in GDBusWorker thread with connection's lock held */ +static gboolean +handle_get_all_properties (GDBusConnection *connection, + ExportedObject *eo, + GDBusMessage *message) +{ + ExportedInterface *ei; + gboolean handled; + const char *interface_name; + + handled = FALSE; + + g_variant_get (g_dbus_message_get_body (message), + "(&s)", + &interface_name); + + /* Fail with org.freedesktop.DBus.Error.InvalidArgs if there is + * no such interface registered + */ + ei = g_hash_table_lookup (eo->map_if_name_to_ei, interface_name); + if (ei == NULL) + { + GDBusMessage *reply; + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.InvalidArgs", + _("No such interface “%sâ€"), + interface_name); + g_dbus_connection_send_message_unlocked (eo->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + handled = TRUE; + goto out; + } + + handled = validate_and_maybe_schedule_property_get_all (eo->connection, + message, + ei->id, + 0, + ei->interface_info, + ei->vtable, + ei->context, + ei->user_data); + out: + return handled; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static const gchar introspect_header[] = + "\n" + "\n" + "\n"; + +static const gchar introspect_tail[] = + "\n"; + +static const gchar introspect_properties_interface[] = + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n"; + +static const gchar introspect_introspectable_interface[] = + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n"; + +static void +introspect_append_header (GString *s) +{ + g_string_append (s, introspect_header); +} + +static void +maybe_add_path (const gchar *path, gsize path_len, const gchar *object_path, GHashTable *set) +{ + if (g_str_has_prefix (object_path, path) && strlen (object_path) > path_len && object_path[path_len-1] == '/') + { + const gchar *begin; + const gchar *end; + gchar *s; + + begin = object_path + path_len; + end = strchr (begin, '/'); + if (end != NULL) + s = g_strndup (begin, end - begin); + else + s = g_strdup (begin); + + if (!g_hash_table_contains (set, s)) + g_hash_table_add (set, s); + else + g_free (s); + } +} + +/* TODO: we want a nicer public interface for this */ +/* called in any thread with connection's lock held */ +static gchar ** +g_dbus_connection_list_registered_unlocked (GDBusConnection *connection, + const gchar *path) +{ + GPtrArray *p; + gchar **ret; + GHashTableIter hash_iter; + const gchar *object_path; + gsize path_len; + GHashTable *set; + GList *keys; + GList *l; + + CONNECTION_ENSURE_LOCK (connection); + + path_len = strlen (path); + if (path_len > 1) + path_len++; + + set = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_iter_init (&hash_iter, connection->map_object_path_to_eo); + while (g_hash_table_iter_next (&hash_iter, (gpointer) &object_path, NULL)) + maybe_add_path (path, path_len, object_path, set); + + g_hash_table_iter_init (&hash_iter, connection->map_object_path_to_es); + while (g_hash_table_iter_next (&hash_iter, (gpointer) &object_path, NULL)) + maybe_add_path (path, path_len, object_path, set); + + p = g_ptr_array_new (); + keys = g_hash_table_get_keys (set); + for (l = keys; l != NULL; l = l->next) + g_ptr_array_add (p, l->data); + g_hash_table_unref (set); + g_list_free (keys); + + g_ptr_array_add (p, NULL); + ret = (gchar **) g_ptr_array_free (p, FALSE); + return ret; +} + +/* called in any thread with connection's lock not held */ +static gchar ** +g_dbus_connection_list_registered (GDBusConnection *connection, + const gchar *path) +{ + gchar **ret; + CONNECTION_LOCK (connection); + ret = g_dbus_connection_list_registered_unlocked (connection, path); + CONNECTION_UNLOCK (connection); + return ret; +} + +/* called in GDBusWorker thread with connection's lock held */ +static gboolean +handle_introspect (GDBusConnection *connection, + ExportedObject *eo, + GDBusMessage *message) +{ + guint n; + GString *s; + GDBusMessage *reply; + GHashTableIter hash_iter; + ExportedInterface *ei; + gchar **registered; + + /* first the header with the standard interfaces */ + s = g_string_sized_new (sizeof (introspect_header) + + sizeof (introspect_properties_interface) + + sizeof (introspect_introspectable_interface) + + sizeof (introspect_tail)); + introspect_append_header (s); + if (!g_hash_table_lookup (eo->map_if_name_to_ei, + "org.freedesktop.DBus.Properties")) + g_string_append (s, introspect_properties_interface); + + if (!g_hash_table_lookup (eo->map_if_name_to_ei, + "org.freedesktop.DBus.Introspectable")) + g_string_append (s, introspect_introspectable_interface); + + /* then include the registered interfaces */ + g_hash_table_iter_init (&hash_iter, eo->map_if_name_to_ei); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &ei)) + g_dbus_interface_info_generate_xml (ei->interface_info, 2, s); + + /* finally include nodes registered below us */ + registered = g_dbus_connection_list_registered_unlocked (connection, eo->object_path); + for (n = 0; registered != NULL && registered[n] != NULL; n++) + g_string_append_printf (s, " \n", registered[n]); + g_strfreev (registered); + g_string_append (s, introspect_tail); + + reply = g_dbus_message_new_method_reply (message); + g_dbus_message_set_body (reply, g_variant_new ("(s)", s->str)); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + g_string_free (s, TRUE); + + return TRUE; +} + +/* called in thread where object was registered - no locks held */ +static gboolean +call_in_idle_cb (gpointer user_data) +{ + GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data); + GDBusInterfaceVTable *vtable; + guint registration_id; + guint subtree_registration_id; + ExportedInterface *ei = NULL; + ExportedSubtree *es = NULL; + + registration_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (invocation), "g-dbus-registration-id")); + subtree_registration_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (invocation), "g-dbus-subtree-registration-id")); + + if (has_object_been_unregistered (g_dbus_method_invocation_get_connection (invocation), + registration_id, + &ei, + subtree_registration_id, + &es)) + { + GDBusMessage *reply; + reply = g_dbus_message_new_method_error (g_dbus_method_invocation_get_message (invocation), + "org.freedesktop.DBus.Error.UnknownMethod", + _("No such interface “%s†on object at path %s"), + g_dbus_method_invocation_get_interface_name (invocation), + g_dbus_method_invocation_get_object_path (invocation)); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + goto out; + } + + vtable = g_object_get_data (G_OBJECT (invocation), "g-dbus-interface-vtable"); + g_assert (vtable != NULL && vtable->method_call != NULL); + + vtable->method_call (g_dbus_method_invocation_get_connection (invocation), + g_dbus_method_invocation_get_sender (invocation), + g_dbus_method_invocation_get_object_path (invocation), + g_dbus_method_invocation_get_interface_name (invocation), + g_dbus_method_invocation_get_method_name (invocation), + g_dbus_method_invocation_get_parameters (invocation), + g_object_ref (invocation), + g_dbus_method_invocation_get_user_data (invocation)); + + out: + g_clear_pointer (&ei, exported_interface_unref); + g_clear_pointer (&es, exported_subtree_unref); + + return FALSE; +} + +/* called in GDBusWorker thread with connection's lock held */ +static void +schedule_method_call (GDBusConnection *connection, + GDBusMessage *message, + guint registration_id, + guint subtree_registration_id, + const GDBusInterfaceInfo *interface_info, + const GDBusMethodInfo *method_info, + const GDBusPropertyInfo *property_info, + GVariant *parameters, + const GDBusInterfaceVTable *vtable, + GMainContext *main_context, + gpointer user_data) +{ + GDBusMethodInvocation *invocation; + GSource *idle_source; + + invocation = _g_dbus_method_invocation_new (g_dbus_message_get_sender (message), + g_dbus_message_get_path (message), + g_dbus_message_get_interface (message), + g_dbus_message_get_member (message), + method_info, + property_info, + connection, + message, + parameters, + user_data); + + /* TODO: would be nicer with a real MethodData like we already + * have PropertyData and PropertyGetAllData... */ + g_object_set_data (G_OBJECT (invocation), "g-dbus-interface-vtable", (gpointer) vtable); + g_object_set_data (G_OBJECT (invocation), "g-dbus-registration-id", GUINT_TO_POINTER (registration_id)); + g_object_set_data (G_OBJECT (invocation), "g-dbus-subtree-registration-id", GUINT_TO_POINTER (subtree_registration_id)); + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + call_in_idle_cb, + invocation, + g_object_unref); + g_source_set_static_name (idle_source, "[gio, " __FILE__ "] call_in_idle_cb"); + g_source_attach (idle_source, main_context); + g_source_unref (idle_source); +} + +/* called in GDBusWorker thread with connection's lock held */ +static gboolean +validate_and_maybe_schedule_method_call (GDBusConnection *connection, + GDBusMessage *message, + guint registration_id, + guint subtree_registration_id, + GDBusInterfaceInfo *interface_info, + const GDBusInterfaceVTable *vtable, + GMainContext *main_context, + gpointer user_data) +{ + GDBusMethodInfo *method_info; + GDBusMessage *reply; + GVariant *parameters; + gboolean handled; + GVariantType *in_type; + + handled = FALSE; + + /* TODO: the cost of this is O(n) - it might be worth caching the result */ + method_info = g_dbus_interface_info_lookup_method (interface_info, g_dbus_message_get_member (message)); + + /* if the method doesn't exist, return the org.freedesktop.DBus.Error.UnknownMethod + * error to the caller + */ + if (method_info == NULL) + { + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.UnknownMethod", + _("No such method “%sâ€"), + g_dbus_message_get_member (message)); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + handled = TRUE; + goto out; + } + + parameters = g_dbus_message_get_body (message); + if (parameters == NULL) + { + parameters = g_variant_new ("()"); + g_variant_ref_sink (parameters); + } + else + { + g_variant_ref (parameters); + } + + /* Check that the incoming args are of the right type - if they are not, return + * the org.freedesktop.DBus.Error.InvalidArgs error to the caller + */ + in_type = _g_dbus_compute_complete_signature (method_info->in_args); + if (!g_variant_is_of_type (parameters, in_type)) + { + gchar *type_string; + + type_string = g_variant_type_dup_string (in_type); + + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.InvalidArgs", + _("Type of message, “%sâ€, does not match expected type “%sâ€"), + g_variant_get_type_string (parameters), + type_string); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_variant_type_free (in_type); + g_variant_unref (parameters); + g_object_unref (reply); + g_free (type_string); + handled = TRUE; + goto out; + } + g_variant_type_free (in_type); + + /* schedule the call in idle */ + schedule_method_call (connection, message, registration_id, subtree_registration_id, + interface_info, method_info, NULL, parameters, + vtable, main_context, user_data); + g_variant_unref (parameters); + handled = TRUE; + + out: + return handled; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* called in GDBusWorker thread with connection's lock held */ +static gboolean +obj_message_func (GDBusConnection *connection, + ExportedObject *eo, + GDBusMessage *message, + gboolean *object_found) +{ + const gchar *interface_name; + const gchar *member; + const gchar *signature; + gboolean handled; + + handled = FALSE; + + interface_name = g_dbus_message_get_interface (message); + member = g_dbus_message_get_member (message); + signature = g_dbus_message_get_signature (message); + + /* see if we have an interface for handling this call */ + if (interface_name != NULL) + { + ExportedInterface *ei; + ei = g_hash_table_lookup (eo->map_if_name_to_ei, interface_name); + if (ei != NULL) + { + /* we do - invoke the handler in idle in the right thread */ + + /* handle no vtable or handler being present */ + if (ei->vtable == NULL || ei->vtable->method_call == NULL) + goto out; + + handled = validate_and_maybe_schedule_method_call (connection, + message, + ei->id, + 0, + ei->interface_info, + ei->vtable, + ei->context, + ei->user_data); + goto out; + } + else + { + *object_found = TRUE; + } + } + + if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Introspectable") == 0 && + g_strcmp0 (member, "Introspect") == 0 && + g_strcmp0 (signature, "") == 0) + { + handled = handle_introspect (connection, eo, message); + goto out; + } + else if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Properties") == 0 && + g_strcmp0 (member, "Get") == 0 && + g_strcmp0 (signature, "ss") == 0) + { + handled = handle_getset_property (connection, eo, message, TRUE); + goto out; + } + else if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Properties") == 0 && + g_strcmp0 (member, "Set") == 0 && + g_strcmp0 (signature, "ssv") == 0) + { + handled = handle_getset_property (connection, eo, message, FALSE); + goto out; + } + else if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Properties") == 0 && + g_strcmp0 (member, "GetAll") == 0 && + g_strcmp0 (signature, "s") == 0) + { + handled = handle_get_all_properties (connection, eo, message); + goto out; + } + + out: + return handled; +} + +/** + * g_dbus_connection_register_object: + * @connection: a #GDBusConnection + * @object_path: the object path to register at + * @interface_info: introspection data for the interface + * @vtable: (nullable): a #GDBusInterfaceVTable to call into or %NULL + * @user_data: (nullable): data to pass to functions in @vtable + * @user_data_free_func: function to call when the object path is unregistered + * @error: return location for error or %NULL + * + * Registers callbacks for exported objects at @object_path with the + * D-Bus interface that is described in @interface_info. + * + * Calls to functions in @vtable (and @user_data_free_func) will happen + * in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. + * + * Note that all #GVariant values passed to functions in @vtable will match + * the signature given in @interface_info - if a remote caller passes + * incorrect values, the `org.freedesktop.DBus.Error.InvalidArgs` + * is returned to the remote caller. + * + * Additionally, if the remote caller attempts to invoke methods or + * access properties not mentioned in @interface_info the + * `org.freedesktop.DBus.Error.UnknownMethod` resp. + * `org.freedesktop.DBus.Error.InvalidArgs` errors + * are returned to the caller. + * + * It is considered a programming error if the + * #GDBusInterfaceGetPropertyFunc function in @vtable returns a + * #GVariant of incorrect type. + * + * If an existing callback is already registered at @object_path and + * @interface_name, then @error is set to %G_IO_ERROR_EXISTS. + * + * GDBus automatically implements the standard D-Bus interfaces + * org.freedesktop.DBus.Properties, org.freedesktop.DBus.Introspectable + * and org.freedesktop.Peer, so you don't have to implement those for the + * objects you export. You can implement org.freedesktop.DBus.Properties + * yourself, e.g. to handle getting and setting of properties asynchronously. + * + * Note that the reference count on @interface_info will be + * incremented by 1 (unless allocated statically, e.g. if the + * reference count is -1, see g_dbus_interface_info_ref()) for as long + * as the object is exported. Also note that @vtable will be copied. + * + * See this [server][gdbus-server] for an example of how to use this method. + * + * Returns: 0 if @error is set, otherwise a registration id (never 0) + * that can be used with g_dbus_connection_unregister_object() + * + * Since: 2.26 + */ +guint +g_dbus_connection_register_object (GDBusConnection *connection, + const gchar *object_path, + GDBusInterfaceInfo *interface_info, + const GDBusInterfaceVTable *vtable, + gpointer user_data, + GDestroyNotify user_data_free_func, + GError **error) +{ + ExportedObject *eo; + ExportedInterface *ei; + guint ret; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); + g_return_val_if_fail (object_path != NULL && g_variant_is_object_path (object_path), 0); + g_return_val_if_fail (interface_info != NULL, 0); + g_return_val_if_fail (g_dbus_is_interface_name (interface_info->name), 0); + g_return_val_if_fail (error == NULL || *error == NULL, 0); + g_return_val_if_fail (check_initialized (connection), 0); + + ret = 0; + + CONNECTION_LOCK (connection); + + eo = g_hash_table_lookup (connection->map_object_path_to_eo, object_path); + if (eo == NULL) + { + eo = g_new0 (ExportedObject, 1); + eo->object_path = g_strdup (object_path); + eo->connection = connection; + eo->map_if_name_to_ei = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) exported_interface_unref); + g_hash_table_insert (connection->map_object_path_to_eo, eo->object_path, eo); + } + + ei = g_hash_table_lookup (eo->map_if_name_to_ei, interface_info->name); + if (ei != NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_EXISTS, + _("An object is already exported for the interface %s at %s"), + interface_info->name, + object_path); + goto out; + } + + ei = g_new0 (ExportedInterface, 1); + ei->refcount = 1; + ei->id = (guint) g_atomic_int_add (&_global_registration_id, 1); /* TODO: overflow etc. */ + ei->eo = eo; + ei->user_data = user_data; + ei->user_data_free_func = user_data_free_func; + ei->vtable = _g_dbus_interface_vtable_copy (vtable); + ei->interface_info = g_dbus_interface_info_ref (interface_info); + g_dbus_interface_info_cache_build (ei->interface_info); + ei->interface_name = g_strdup (interface_info->name); + ei->context = g_main_context_ref_thread_default (); + + g_hash_table_insert (eo->map_if_name_to_ei, + (gpointer) ei->interface_name, + ei); + g_hash_table_insert (connection->map_id_to_ei, + GUINT_TO_POINTER (ei->id), + ei); + + ret = ei->id; + + out: + CONNECTION_UNLOCK (connection); + + return ret; +} + +/** + * g_dbus_connection_unregister_object: + * @connection: a #GDBusConnection + * @registration_id: a registration id obtained from + * g_dbus_connection_register_object() + * + * Unregisters an object. + * + * Returns: %TRUE if the object was unregistered, %FALSE otherwise + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_unregister_object (GDBusConnection *connection, + guint registration_id) +{ + ExportedInterface *ei; + ExportedObject *eo; + gboolean ret; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (check_initialized (connection), FALSE); + + ret = FALSE; + + CONNECTION_LOCK (connection); + + ei = g_hash_table_lookup (connection->map_id_to_ei, + GUINT_TO_POINTER (registration_id)); + if (ei == NULL) + goto out; + + eo = ei->eo; + + g_warn_if_fail (g_hash_table_remove (connection->map_id_to_ei, GUINT_TO_POINTER (ei->id))); + g_warn_if_fail (g_hash_table_remove (eo->map_if_name_to_ei, ei->interface_name)); + /* unregister object path if we have no more exported interfaces */ + if (g_hash_table_size (eo->map_if_name_to_ei) == 0) + g_warn_if_fail (g_hash_table_remove (connection->map_object_path_to_eo, + eo->object_path)); + + ret = TRUE; + + out: + CONNECTION_UNLOCK (connection); + + return ret; +} + +typedef struct { + GClosure *method_call_closure; + GClosure *get_property_closure; + GClosure *set_property_closure; +} RegisterObjectData; + +static RegisterObjectData * +register_object_data_new (GClosure *method_call_closure, + GClosure *get_property_closure, + GClosure *set_property_closure) +{ + RegisterObjectData *data; + + data = g_new0 (RegisterObjectData, 1); + + if (method_call_closure != NULL) + { + data->method_call_closure = g_closure_ref (method_call_closure); + g_closure_sink (method_call_closure); + if (G_CLOSURE_NEEDS_MARSHAL (method_call_closure)) + g_closure_set_marshal (method_call_closure, g_cclosure_marshal_generic); + } + + if (get_property_closure != NULL) + { + data->get_property_closure = g_closure_ref (get_property_closure); + g_closure_sink (get_property_closure); + if (G_CLOSURE_NEEDS_MARSHAL (get_property_closure)) + g_closure_set_marshal (get_property_closure, g_cclosure_marshal_generic); + } + + if (set_property_closure != NULL) + { + data->set_property_closure = g_closure_ref (set_property_closure); + g_closure_sink (set_property_closure); + if (G_CLOSURE_NEEDS_MARSHAL (set_property_closure)) + g_closure_set_marshal (set_property_closure, g_cclosure_marshal_generic); + } + + return data; +} + +static void +register_object_free_func (gpointer user_data) +{ + RegisterObjectData *data = user_data; + + g_clear_pointer (&data->method_call_closure, g_closure_unref); + g_clear_pointer (&data->get_property_closure, g_closure_unref); + g_clear_pointer (&data->set_property_closure, g_closure_unref); + + g_free (data); +} + +static void +register_with_closures_on_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + RegisterObjectData *data = user_data; + GValue params[] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT }; + + g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); + g_value_set_object (¶ms[0], connection); + + g_value_init (¶ms[1], G_TYPE_STRING); + g_value_set_string (¶ms[1], sender); + + g_value_init (¶ms[2], G_TYPE_STRING); + g_value_set_string (¶ms[2], object_path); + + g_value_init (¶ms[3], G_TYPE_STRING); + g_value_set_string (¶ms[3], interface_name); + + g_value_init (¶ms[4], G_TYPE_STRING); + g_value_set_string (¶ms[4], method_name); + + g_value_init (¶ms[5], G_TYPE_VARIANT); + g_value_set_variant (¶ms[5], parameters); + + g_value_init (¶ms[6], G_TYPE_DBUS_METHOD_INVOCATION); + g_value_set_object (¶ms[6], invocation); + + g_closure_invoke (data->method_call_closure, NULL, G_N_ELEMENTS (params), params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); + g_value_unset (params + 2); + g_value_unset (params + 3); + g_value_unset (params + 4); + g_value_unset (params + 5); + g_value_unset (params + 6); +} + +static GVariant * +register_with_closures_on_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + RegisterObjectData *data = user_data; + GValue params[] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT }; + GValue result_value = G_VALUE_INIT; + GVariant *result; + + g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); + g_value_set_object (¶ms[0], connection); + + g_value_init (¶ms[1], G_TYPE_STRING); + g_value_set_string (¶ms[1], sender); + + g_value_init (¶ms[2], G_TYPE_STRING); + g_value_set_string (¶ms[2], object_path); + + g_value_init (¶ms[3], G_TYPE_STRING); + g_value_set_string (¶ms[3], interface_name); + + g_value_init (¶ms[4], G_TYPE_STRING); + g_value_set_string (¶ms[4], property_name); + + g_value_init (&result_value, G_TYPE_VARIANT); + + g_closure_invoke (data->get_property_closure, &result_value, G_N_ELEMENTS (params), params, NULL); + + result = g_value_get_variant (&result_value); + if (result) + g_variant_ref (result); + + g_value_unset (params + 0); + g_value_unset (params + 1); + g_value_unset (params + 2); + g_value_unset (params + 3); + g_value_unset (params + 4); + g_value_unset (&result_value); + + if (!result) + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + _("Unable to retrieve property %s.%s"), + interface_name, property_name); + + return result; +} + +static gboolean +register_with_closures_on_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data) +{ + RegisterObjectData *data = user_data; + GValue params[] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT }; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); + g_value_set_object (¶ms[0], connection); + + g_value_init (¶ms[1], G_TYPE_STRING); + g_value_set_string (¶ms[1], sender); + + g_value_init (¶ms[2], G_TYPE_STRING); + g_value_set_string (¶ms[2], object_path); + + g_value_init (¶ms[3], G_TYPE_STRING); + g_value_set_string (¶ms[3], interface_name); + + g_value_init (¶ms[4], G_TYPE_STRING); + g_value_set_string (¶ms[4], property_name); + + g_value_init (¶ms[5], G_TYPE_VARIANT); + g_value_set_variant (¶ms[5], value); + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_closure_invoke (data->set_property_closure, &result_value, G_N_ELEMENTS (params), params, NULL); + + result = g_value_get_boolean (&result_value); + + g_value_unset (params + 0); + g_value_unset (params + 1); + g_value_unset (params + 2); + g_value_unset (params + 3); + g_value_unset (params + 4); + g_value_unset (params + 5); + g_value_unset (&result_value); + + if (!result) + g_set_error (error, + G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + _("Unable to set property %s.%s"), + interface_name, property_name); + + return result; +} + +/** + * g_dbus_connection_register_object_with_closures: (rename-to g_dbus_connection_register_object) + * @connection: A #GDBusConnection. + * @object_path: The object path to register at. + * @interface_info: Introspection data for the interface. + * @method_call_closure: (nullable): #GClosure for handling incoming method calls. + * @get_property_closure: (nullable): #GClosure for getting a property. + * @set_property_closure: (nullable): #GClosure for setting a property. + * @error: Return location for error or %NULL. + * + * Version of g_dbus_connection_register_object() using closures instead of a + * #GDBusInterfaceVTable for easier binding in other languages. + * + * Returns: 0 if @error is set, otherwise a registration ID (never 0) + * that can be used with g_dbus_connection_unregister_object() . + * + * Since: 2.46 + */ +guint +g_dbus_connection_register_object_with_closures (GDBusConnection *connection, + const gchar *object_path, + GDBusInterfaceInfo *interface_info, + GClosure *method_call_closure, + GClosure *get_property_closure, + GClosure *set_property_closure, + GError **error) +{ + RegisterObjectData *data; + GDBusInterfaceVTable vtable = + { + method_call_closure != NULL ? register_with_closures_on_method_call : NULL, + get_property_closure != NULL ? register_with_closures_on_get_property : NULL, + set_property_closure != NULL ? register_with_closures_on_set_property : NULL, + { 0 } + }; + + data = register_object_data_new (method_call_closure, get_property_closure, set_property_closure); + + return g_dbus_connection_register_object (connection, + object_path, + interface_info, + &vtable, + data, + register_object_free_func, + error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_emit_signal: + * @connection: a #GDBusConnection + * @destination_bus_name: (nullable): the unique bus name for the destination + * for the signal or %NULL to emit to all listeners + * @object_path: path of remote object + * @interface_name: D-Bus interface to emit a signal on + * @signal_name: the name of the signal to emit + * @parameters: (nullable): a #GVariant tuple with parameters for the signal + * or %NULL if not passing parameters + * @error: Return location for error or %NULL + * + * Emits a signal. + * + * If the parameters GVariant is floating, it is consumed. + * + * This can only fail if @parameters is not compatible with the D-Bus protocol + * (%G_IO_ERROR_INVALID_ARGUMENT), or if @connection has been closed + * (%G_IO_ERROR_CLOSED). + * + * Returns: %TRUE unless @error is set + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_emit_signal (GDBusConnection *connection, + const gchar *destination_bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + GError **error) +{ + GDBusMessage *message; + gboolean ret; + + message = NULL; + ret = FALSE; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (destination_bus_name == NULL || g_dbus_is_name (destination_bus_name), FALSE); + g_return_val_if_fail (object_path != NULL && g_variant_is_object_path (object_path), FALSE); + g_return_val_if_fail (interface_name != NULL && g_dbus_is_interface_name (interface_name), FALSE); + g_return_val_if_fail (signal_name != NULL && g_dbus_is_member_name (signal_name), FALSE); + g_return_val_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), FALSE); + g_return_val_if_fail (check_initialized (connection), FALSE); + + if (G_UNLIKELY (_g_dbus_debug_emission ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Emission:\n" + " >>>> SIGNAL EMISSION %s.%s()\n" + " on object %s\n" + " destination %s\n", + interface_name, signal_name, + object_path, + destination_bus_name != NULL ? destination_bus_name : "(none)"); + _g_dbus_debug_print_unlock (); + } + + message = g_dbus_message_new_signal (object_path, + interface_name, + signal_name); + + if (destination_bus_name != NULL) + g_dbus_message_set_header (message, + G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, + g_variant_new_string (destination_bus_name)); + + if (parameters != NULL) + g_dbus_message_set_body (message, parameters); + + ret = g_dbus_connection_send_message (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, error); + g_object_unref (message); + + return ret; +} + +static void +add_call_flags (GDBusMessage *message, + GDBusCallFlags flags) +{ + GDBusMessageFlags msg_flags = 0; + + if (flags & G_DBUS_CALL_FLAGS_NO_AUTO_START) + msg_flags |= G_DBUS_MESSAGE_FLAGS_NO_AUTO_START; + if (flags & G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION) + msg_flags |= G_DBUS_MESSAGE_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION; + if (msg_flags) + g_dbus_message_set_flags (message, msg_flags); +} + +static GVariant * +decode_method_reply (GDBusMessage *reply, + const gchar *method_name, + const GVariantType *reply_type, + GUnixFDList **out_fd_list, + GError **error) +{ + GVariant *result; + + result = NULL; + switch (g_dbus_message_get_message_type (reply)) + { + case G_DBUS_MESSAGE_TYPE_METHOD_RETURN: + result = g_dbus_message_get_body (reply); + if (result == NULL) + { + result = g_variant_new ("()"); + g_variant_ref_sink (result); + } + else + { + g_variant_ref (result); + } + + if (!g_variant_is_of_type (result, reply_type)) + { + gchar *type_string = g_variant_type_dup_string (reply_type); + + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Method “%s†returned type “%sâ€, but expected “%sâ€"), + method_name, g_variant_get_type_string (result), type_string); + + g_variant_unref (result); + g_free (type_string); + result = NULL; + } + +#ifdef G_OS_UNIX + if (result != NULL) + { + if (out_fd_list != NULL) + { + *out_fd_list = g_dbus_message_get_unix_fd_list (reply); + if (*out_fd_list != NULL) + g_object_ref (*out_fd_list); + } + } +#endif + break; + + case G_DBUS_MESSAGE_TYPE_ERROR: + g_dbus_message_to_gerror (reply, error); + break; + + default: + g_assert_not_reached (); + break; + } + + return result; +} + + +typedef struct +{ + GVariantType *reply_type; + gchar *method_name; /* for error message */ + + GUnixFDList *fd_list; +} CallState; + +static void +call_state_free (CallState *state) +{ + g_variant_type_free (state->reply_type); + g_free (state->method_name); + + if (state->fd_list != NULL) + g_object_unref (state->fd_list); + g_slice_free (CallState, state); +} + +/* called in any thread, with the connection's lock not held */ +static void +g_dbus_connection_call_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (source); + GTask *task = user_data; + CallState *state = g_task_get_task_data (task); + GError *error = NULL; + GDBusMessage *reply; + GVariant *value = NULL; + + reply = g_dbus_connection_send_message_with_reply_finish (connection, + result, + &error); + + if (G_UNLIKELY (_g_dbus_debug_call ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Call:\n" + " <<<< ASYNC COMPLETE %s()", + state->method_name); + + if (reply != NULL) + { + g_print (" (serial %d)\n" + " SUCCESS\n", + g_dbus_message_get_reply_serial (reply)); + } + else + { + g_print ("\n" + " FAILED: %s\n", + error->message); + } + _g_dbus_debug_print_unlock (); + } + + if (reply != NULL) + value = decode_method_reply (reply, state->method_name, state->reply_type, &state->fd_list, &error); + + if (error != NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, value, (GDestroyNotify) g_variant_unref); + + g_clear_object (&reply); + g_object_unref (task); +} + +/* called in any thread, with the connection's lock not held */ +static void +g_dbus_connection_call_internal (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDBusMessage *message; + guint32 serial; + + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + g_return_if_fail (bus_name == NULL || g_dbus_is_name (bus_name)); + g_return_if_fail (object_path != NULL && g_variant_is_object_path (object_path)); + g_return_if_fail (interface_name != NULL && g_dbus_is_interface_name (interface_name)); + g_return_if_fail (method_name != NULL && g_dbus_is_member_name (method_name)); + g_return_if_fail (timeout_msec >= 0 || timeout_msec == -1); + g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); + g_return_if_fail (check_initialized (connection)); +#ifdef G_OS_UNIX + g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list)); +#else + g_return_if_fail (fd_list == NULL); +#endif + + message = g_dbus_message_new_method_call (bus_name, + object_path, + interface_name, + method_name); + add_call_flags (message, flags); + if (parameters != NULL) + g_dbus_message_set_body (message, parameters); + +#ifdef G_OS_UNIX + if (fd_list != NULL) + g_dbus_message_set_unix_fd_list (message, fd_list); +#endif + + /* If the user has no callback then we can just send the message with + * the G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED flag set and skip all + * the logic for processing the reply. If the service sends the reply + * anyway then it will just be ignored. + */ + if (callback != NULL) + { + CallState *state; + GTask *task; + + state = g_slice_new0 (CallState); + state->method_name = g_strjoin (".", interface_name, method_name, NULL); + + if (reply_type == NULL) + reply_type = G_VARIANT_TYPE_ANY; + + state->reply_type = g_variant_type_copy (reply_type); + + task = g_task_new (connection, cancellable, callback, user_data); + g_task_set_source_tag (task, g_dbus_connection_call_internal); + g_task_set_task_data (task, state, (GDestroyNotify) call_state_free); + + g_dbus_connection_send_message_with_reply (connection, + message, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + timeout_msec, + &serial, + cancellable, + g_dbus_connection_call_done, + task); + } + else + { + GDBusMessageFlags flags; + + flags = g_dbus_message_get_flags (message); + flags |= G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED; + g_dbus_message_set_flags (message, flags); + + g_dbus_connection_send_message (connection, + message, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + &serial, NULL); + } + + if (G_UNLIKELY (_g_dbus_debug_call ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Call:\n" + " >>>> ASYNC %s.%s()\n" + " on object %s\n" + " owned by name %s (serial %d)\n", + interface_name, + method_name, + object_path, + bus_name != NULL ? bus_name : "(none)", + serial); + _g_dbus_debug_print_unlock (); + } + + if (message != NULL) + g_object_unref (message); +} + +/* called in any thread, with the connection's lock not held */ +static GVariant * +g_dbus_connection_call_finish_internal (GDBusConnection *connection, + GUnixFDList **out_fd_list, + GAsyncResult *res, + GError **error) +{ + GTask *task; + CallState *state; + GVariant *ret; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (g_task_is_valid (res, connection), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + task = G_TASK (res); + state = g_task_get_task_data (task); + + ret = g_task_propagate_pointer (task, error); + if (!ret) + return NULL; + + if (out_fd_list != NULL) + *out_fd_list = state->fd_list != NULL ? g_object_ref (state->fd_list) : NULL; + return ret; +} + +/* called in any user thread, with the connection's lock not held */ +static GVariant * +g_dbus_connection_call_sync_internal (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GUnixFDList **out_fd_list, + GCancellable *cancellable, + GError **error) +{ + GDBusMessage *message; + GDBusMessage *reply; + GVariant *result; + GError *local_error; + GDBusSendMessageFlags send_flags; + + message = NULL; + reply = NULL; + result = NULL; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (bus_name == NULL || g_dbus_is_name (bus_name), NULL); + g_return_val_if_fail (object_path != NULL && g_variant_is_object_path (object_path), NULL); + g_return_val_if_fail (interface_name != NULL && g_dbus_is_interface_name (interface_name), NULL); + g_return_val_if_fail (method_name != NULL && g_dbus_is_member_name (method_name), NULL); + g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL); + g_return_val_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL); +#ifdef G_OS_UNIX + g_return_val_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list), NULL); +#else + g_return_val_if_fail (fd_list == NULL, NULL); +#endif + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (!(flags & CALL_FLAGS_INITIALIZING)) + g_return_val_if_fail (check_initialized (connection), FALSE); + + if (reply_type == NULL) + reply_type = G_VARIANT_TYPE_ANY; + + message = g_dbus_message_new_method_call (bus_name, + object_path, + interface_name, + method_name); + add_call_flags (message, flags); + if (parameters != NULL) + g_dbus_message_set_body (message, parameters); + +#ifdef G_OS_UNIX + if (fd_list != NULL) + g_dbus_message_set_unix_fd_list (message, fd_list); +#endif + + if (G_UNLIKELY (_g_dbus_debug_call ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Call:\n" + " >>>> SYNC %s.%s()\n" + " on object %s\n" + " owned by name %s\n", + interface_name, + method_name, + object_path, + bus_name != NULL ? bus_name : "(none)"); + _g_dbus_debug_print_unlock (); + } + + local_error = NULL; + + send_flags = G_DBUS_SEND_MESSAGE_FLAGS_NONE; + + /* translate from one flavour of flags to another... */ + if (flags & CALL_FLAGS_INITIALIZING) + send_flags |= SEND_MESSAGE_FLAGS_INITIALIZING; + + reply = g_dbus_connection_send_message_with_reply_sync (connection, + message, + send_flags, + timeout_msec, + NULL, /* guint32 *out_serial */ + cancellable, + &local_error); + + if (G_UNLIKELY (_g_dbus_debug_call ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Call:\n" + " <<<< SYNC COMPLETE %s.%s()\n" + " ", + interface_name, + method_name); + if (reply != NULL) + { + g_print ("SUCCESS\n"); + } + else + { + g_print ("FAILED: %s\n", + local_error->message); + } + _g_dbus_debug_print_unlock (); + } + + if (reply == NULL) + { + if (error != NULL) + *error = local_error; + else + g_error_free (local_error); + goto out; + } + + result = decode_method_reply (reply, method_name, reply_type, out_fd_list, error); + + out: + if (message != NULL) + g_object_unref (message); + if (reply != NULL) + g_object_unref (reply); + + return result; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_call: + * @connection: a #GDBusConnection + * @bus_name: (nullable): a unique or well-known bus name or %NULL if + * @connection is not a message bus connection + * @object_path: path of remote object + * @interface_name: D-Bus interface to invoke method on + * @method_name: the name of the method to invoke + * @parameters: (nullable): a #GVariant tuple with parameters for the method + * or %NULL if not passing parameters + * @reply_type: (nullable): the expected type of the reply (which will be a + * tuple), or %NULL + * @flags: flags from the #GDBusCallFlags enumeration + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the request + * is satisfied or %NULL if you don't care about the result of the + * method invocation + * @user_data: the data to pass to @callback + * + * Asynchronously invokes the @method_name method on the + * @interface_name D-Bus interface on the remote object at + * @object_path owned by @bus_name. + * + * If @connection is closed then the operation will fail with + * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will + * fail with %G_IO_ERROR_CANCELLED. If @parameters contains a value + * not compatible with the D-Bus protocol, the operation fails with + * %G_IO_ERROR_INVALID_ARGUMENT. + * + * If @reply_type is non-%NULL then the reply will be checked for having this type and an + * error will be raised if it does not match. Said another way, if you give a @reply_type + * then any non-%NULL return value will be of this type. Unless it’s + * %G_VARIANT_TYPE_UNIT, the @reply_type will be a tuple containing one or more + * values. + * + * If the @parameters #GVariant is floating, it is consumed. This allows + * convenient 'inline' use of g_variant_new(), e.g.: + * |[ + * g_dbus_connection_call (connection, + * "org.freedesktop.StringThings", + * "/org/freedesktop/StringThings", + * "org.freedesktop.StringThings", + * "TwoStrings", + * g_variant_new ("(ss)", + * "Thing One", + * "Thing Two"), + * NULL, + * G_DBUS_CALL_FLAGS_NONE, + * -1, + * NULL, + * (GAsyncReadyCallback) two_strings_done, + * NULL); + * ]| + * + * This is an asynchronous method. When the operation is finished, + * @callback will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. You can then call + * g_dbus_connection_call_finish() to get the result of the operation. + * See g_dbus_connection_call_sync() for the synchronous version of this + * function. + * + * If @callback is %NULL then the D-Bus method call message will be sent with + * the %G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED flag set. + * + * Since: 2.26 + */ +void +g_dbus_connection_call (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_dbus_connection_call_internal (connection, bus_name, object_path, interface_name, method_name, parameters, reply_type, flags, timeout_msec, NULL, cancellable, callback, user_data); +} + +/** + * g_dbus_connection_call_finish: + * @connection: a #GDBusConnection + * @res: a #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_connection_call() + * @error: return location for error or %NULL + * + * Finishes an operation started with g_dbus_connection_call(). + * + * Returns: (transfer full): %NULL if @error is set. Otherwise a non-floating + * #GVariant tuple with return values. Free with g_variant_unref(). + * + * Since: 2.26 + */ +GVariant * +g_dbus_connection_call_finish (GDBusConnection *connection, + GAsyncResult *res, + GError **error) +{ + return g_dbus_connection_call_finish_internal (connection, NULL, res, error); +} + +/** + * g_dbus_connection_call_sync: + * @connection: a #GDBusConnection + * @bus_name: (nullable): a unique or well-known bus name or %NULL if + * @connection is not a message bus connection + * @object_path: path of remote object + * @interface_name: D-Bus interface to invoke method on + * @method_name: the name of the method to invoke + * @parameters: (nullable): a #GVariant tuple with parameters for the method + * or %NULL if not passing parameters + * @reply_type: (nullable): the expected type of the reply, or %NULL + * @flags: flags from the #GDBusCallFlags enumeration + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Synchronously invokes the @method_name method on the + * @interface_name D-Bus interface on the remote object at + * @object_path owned by @bus_name. + * + * If @connection is closed then the operation will fail with + * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the + * operation will fail with %G_IO_ERROR_CANCELLED. If @parameters + * contains a value not compatible with the D-Bus protocol, the operation + * fails with %G_IO_ERROR_INVALID_ARGUMENT. + * + * If @reply_type is non-%NULL then the reply will be checked for having + * this type and an error will be raised if it does not match. Said + * another way, if you give a @reply_type then any non-%NULL return + * value will be of this type. + * + * If the @parameters #GVariant is floating, it is consumed. + * This allows convenient 'inline' use of g_variant_new(), e.g.: + * |[ + * g_dbus_connection_call_sync (connection, + * "org.freedesktop.StringThings", + * "/org/freedesktop/StringThings", + * "org.freedesktop.StringThings", + * "TwoStrings", + * g_variant_new ("(ss)", + * "Thing One", + * "Thing Two"), + * NULL, + * G_DBUS_CALL_FLAGS_NONE, + * -1, + * NULL, + * &error); + * ]| + * + * The calling thread is blocked until a reply is received. See + * g_dbus_connection_call() for the asynchronous version of + * this method. + * + * Returns: (transfer full): %NULL if @error is set. Otherwise a non-floating + * #GVariant tuple with return values. Free with g_variant_unref(). + * + * Since: 2.26 + */ +GVariant * +g_dbus_connection_call_sync (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error) +{ + return g_dbus_connection_call_sync_internal (connection, bus_name, object_path, interface_name, method_name, parameters, reply_type, flags, timeout_msec, NULL, NULL, cancellable, error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_UNIX + +/** + * g_dbus_connection_call_with_unix_fd_list: + * @connection: a #GDBusConnection + * @bus_name: (nullable): a unique or well-known bus name or %NULL if + * @connection is not a message bus connection + * @object_path: path of remote object + * @interface_name: D-Bus interface to invoke method on + * @method_name: the name of the method to invoke + * @parameters: (nullable): a #GVariant tuple with parameters for the method + * or %NULL if not passing parameters + * @reply_type: (nullable): the expected type of the reply, or %NULL + * @flags: flags from the #GDBusCallFlags enumeration + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @fd_list: (nullable): a #GUnixFDList or %NULL + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the request is + * satisfied or %NULL if you don't * care about the result of the + * method invocation + * @user_data: The data to pass to @callback. + * + * Like g_dbus_connection_call() but also takes a #GUnixFDList object. + * + * The file descriptors normally correspond to %G_VARIANT_TYPE_HANDLE + * values in the body of the message. For example, if a message contains + * two file descriptors, @fd_list would have length 2, and + * `g_variant_new_handle (0)` and `g_variant_new_handle (1)` would appear + * somewhere in the body of the message (not necessarily in that order!) + * to represent the file descriptors at indexes 0 and 1 respectively. + * + * When designing D-Bus APIs that are intended to be interoperable, + * please note that non-GDBus implementations of D-Bus can usually only + * access file descriptors if they are referenced in this way by a + * value of type %G_VARIANT_TYPE_HANDLE in the body of the message. + * + * This method is only available on UNIX. + * + * Since: 2.30 + */ +void +g_dbus_connection_call_with_unix_fd_list (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_dbus_connection_call_internal (connection, bus_name, object_path, interface_name, method_name, parameters, reply_type, flags, timeout_msec, fd_list, cancellable, callback, user_data); +} + +/** + * g_dbus_connection_call_with_unix_fd_list_finish: + * @connection: a #GDBusConnection + * @out_fd_list: (out) (optional): return location for a #GUnixFDList or %NULL + * @res: a #GAsyncResult obtained from the #GAsyncReadyCallback passed to + * g_dbus_connection_call_with_unix_fd_list() + * @error: return location for error or %NULL + * + * Finishes an operation started with g_dbus_connection_call_with_unix_fd_list(). + * + * The file descriptors normally correspond to %G_VARIANT_TYPE_HANDLE + * values in the body of the message. For example, + * if g_variant_get_handle() returns 5, that is intended to be a reference + * to the file descriptor that can be accessed by + * `g_unix_fd_list_get (*out_fd_list, 5, ...)`. + * + * When designing D-Bus APIs that are intended to be interoperable, + * please note that non-GDBus implementations of D-Bus can usually only + * access file descriptors if they are referenced in this way by a + * value of type %G_VARIANT_TYPE_HANDLE in the body of the message. + * + * Returns: (transfer full): %NULL if @error is set. Otherwise a non-floating + * #GVariant tuple with return values. Free with g_variant_unref(). + * + * Since: 2.30 + */ +GVariant * +g_dbus_connection_call_with_unix_fd_list_finish (GDBusConnection *connection, + GUnixFDList **out_fd_list, + GAsyncResult *res, + GError **error) +{ + return g_dbus_connection_call_finish_internal (connection, out_fd_list, res, error); +} + +/** + * g_dbus_connection_call_with_unix_fd_list_sync: + * @connection: a #GDBusConnection + * @bus_name: (nullable): a unique or well-known bus name or %NULL + * if @connection is not a message bus connection + * @object_path: path of remote object + * @interface_name: D-Bus interface to invoke method on + * @method_name: the name of the method to invoke + * @parameters: (nullable): a #GVariant tuple with parameters for + * the method or %NULL if not passing parameters + * @reply_type: (nullable): the expected type of the reply, or %NULL + * @flags: flags from the #GDBusCallFlags enumeration + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @fd_list: (nullable): a #GUnixFDList or %NULL + * @out_fd_list: (out) (optional): return location for a #GUnixFDList or %NULL + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Like g_dbus_connection_call_sync() but also takes and returns #GUnixFDList objects. + * See g_dbus_connection_call_with_unix_fd_list() and + * g_dbus_connection_call_with_unix_fd_list_finish() for more details. + * + * This method is only available on UNIX. + * + * Returns: (transfer full): %NULL if @error is set. Otherwise a non-floating + * #GVariant tuple with return values. Free with g_variant_unref(). + * + * Since: 2.30 + */ +GVariant * +g_dbus_connection_call_with_unix_fd_list_sync (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GUnixFDList **out_fd_list, + GCancellable *cancellable, + GError **error) +{ + return g_dbus_connection_call_sync_internal (connection, bus_name, object_path, interface_name, method_name, parameters, reply_type, flags, timeout_msec, fd_list, out_fd_list, cancellable, error); +} + +#endif /* G_OS_UNIX */ + +/* ---------------------------------------------------------------------------------------------------- */ + +/* called without lock held in the thread where the caller registered + * the subtree + */ +static gboolean +handle_subtree_introspect (GDBusConnection *connection, + ExportedSubtree *es, + GDBusMessage *message) +{ + GString *s; + gboolean handled; + GDBusMessage *reply; + gchar **children; + gboolean is_root; + const gchar *sender; + const gchar *requested_object_path; + const gchar *requested_node; + GDBusInterfaceInfo **interfaces; + guint n; + gchar **subnode_paths; + gboolean has_properties_interface; + gboolean has_introspectable_interface; + + handled = FALSE; + + requested_object_path = g_dbus_message_get_path (message); + sender = g_dbus_message_get_sender (message); + is_root = (g_strcmp0 (requested_object_path, es->object_path) == 0); + + s = g_string_new (NULL); + introspect_append_header (s); + + /* Strictly we don't need the children in dynamic mode, but we avoid the + * conditionals to preserve code clarity + */ + children = es->vtable->enumerate (es->connection, + sender, + es->object_path, + es->user_data); + + if (!is_root) + { + requested_node = strrchr (requested_object_path, '/') + 1; + + /* Assert existence of object if we are not dynamic */ + if (!(es->flags & G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES) && + !g_strv_contains ((const gchar * const *) children, requested_node)) + goto out; + } + else + { + requested_node = NULL; + } + + interfaces = es->vtable->introspect (es->connection, + sender, + es->object_path, + requested_node, + es->user_data); + if (interfaces != NULL) + { + has_properties_interface = FALSE; + has_introspectable_interface = FALSE; + + for (n = 0; interfaces[n] != NULL; n++) + { + if (strcmp (interfaces[n]->name, "org.freedesktop.DBus.Properties") == 0) + has_properties_interface = TRUE; + else if (strcmp (interfaces[n]->name, "org.freedesktop.DBus.Introspectable") == 0) + has_introspectable_interface = TRUE; + } + if (!has_properties_interface) + g_string_append (s, introspect_properties_interface); + if (!has_introspectable_interface) + g_string_append (s, introspect_introspectable_interface); + + for (n = 0; interfaces[n] != NULL; n++) + { + g_dbus_interface_info_generate_xml (interfaces[n], 2, s); + g_dbus_interface_info_unref (interfaces[n]); + } + g_free (interfaces); + } + + /* then include entries from the Subtree for the root */ + if (is_root) + { + for (n = 0; children != NULL && children[n] != NULL; n++) + g_string_append_printf (s, " \n", children[n]); + } + + /* finally include nodes registered below us */ + subnode_paths = g_dbus_connection_list_registered (es->connection, requested_object_path); + for (n = 0; subnode_paths != NULL && subnode_paths[n] != NULL; n++) + g_string_append_printf (s, " \n", subnode_paths[n]); + g_strfreev (subnode_paths); + + g_string_append (s, "\n"); + + reply = g_dbus_message_new_method_reply (message); + g_dbus_message_set_body (reply, g_variant_new ("(s)", s->str)); + g_dbus_connection_send_message (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + + handled = TRUE; + + out: + g_string_free (s, TRUE); + g_strfreev (children); + return handled; +} + +/* called without lock held in the thread where the caller registered + * the subtree + */ +static gboolean +handle_subtree_method_invocation (GDBusConnection *connection, + ExportedSubtree *es, + GDBusMessage *message) +{ + gboolean handled; + const gchar *sender; + const gchar *interface_name; + const gchar *member; + const gchar *signature; + const gchar *requested_object_path; + const gchar *requested_node; + gboolean is_root; + GDBusInterfaceInfo *interface_info; + const GDBusInterfaceVTable *interface_vtable; + gpointer interface_user_data; + guint n; + GDBusInterfaceInfo **interfaces; + gboolean is_property_get; + gboolean is_property_set; + gboolean is_property_get_all; + + handled = FALSE; + interfaces = NULL; + + requested_object_path = g_dbus_message_get_path (message); + sender = g_dbus_message_get_sender (message); + interface_name = g_dbus_message_get_interface (message); + member = g_dbus_message_get_member (message); + signature = g_dbus_message_get_signature (message); + is_root = (g_strcmp0 (requested_object_path, es->object_path) == 0); + + is_property_get = FALSE; + is_property_set = FALSE; + is_property_get_all = FALSE; + if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Properties") == 0) + { + if (g_strcmp0 (member, "Get") == 0 && g_strcmp0 (signature, "ss") == 0) + is_property_get = TRUE; + else if (g_strcmp0 (member, "Set") == 0 && g_strcmp0 (signature, "ssv") == 0) + is_property_set = TRUE; + else if (g_strcmp0 (member, "GetAll") == 0 && g_strcmp0 (signature, "s") == 0) + is_property_get_all = TRUE; + } + + if (!is_root) + { + requested_node = strrchr (requested_object_path, '/') + 1; + + if (~es->flags & G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES) + { + /* We don't want to dispatch to unenumerated + * nodes, so ensure that the child exists. + */ + gchar **children; + gboolean exists; + + children = es->vtable->enumerate (es->connection, + sender, + es->object_path, + es->user_data); + + exists = g_strv_contains ((const gchar * const *) children, requested_node); + g_strfreev (children); + + if (!exists) + goto out; + } + } + else + { + requested_node = NULL; + } + + /* get introspection data for the node */ + interfaces = es->vtable->introspect (es->connection, + sender, + requested_object_path, + requested_node, + es->user_data); + + if (interfaces == NULL) + goto out; + + interface_info = NULL; + for (n = 0; interfaces[n] != NULL; n++) + { + if (g_strcmp0 (interfaces[n]->name, interface_name) == 0) + interface_info = interfaces[n]; + } + + /* dispatch the call if the user wants to handle it */ + if (interface_info != NULL) + { + /* figure out where to dispatch the method call */ + interface_user_data = NULL; + interface_vtable = es->vtable->dispatch (es->connection, + sender, + es->object_path, + interface_name, + requested_node, + &interface_user_data, + es->user_data); + if (interface_vtable == NULL) + goto out; + + CONNECTION_LOCK (connection); + handled = validate_and_maybe_schedule_method_call (es->connection, + message, + 0, + es->id, + interface_info, + interface_vtable, + es->context, + interface_user_data); + CONNECTION_UNLOCK (connection); + } + /* handle org.freedesktop.DBus.Properties interface if not explicitly handled */ + else if (is_property_get || is_property_set || is_property_get_all) + { + if (is_property_get) + g_variant_get (g_dbus_message_get_body (message), "(&s&s)", &interface_name, NULL); + else if (is_property_set) + g_variant_get (g_dbus_message_get_body (message), "(&s&sv)", &interface_name, NULL, NULL); + else if (is_property_get_all) + g_variant_get (g_dbus_message_get_body (message), "(&s)", &interface_name, NULL, NULL); + else + g_assert_not_reached (); + + /* see if the object supports this interface at all */ + for (n = 0; interfaces[n] != NULL; n++) + { + if (g_strcmp0 (interfaces[n]->name, interface_name) == 0) + interface_info = interfaces[n]; + } + + /* Fail with org.freedesktop.DBus.Error.InvalidArgs if the user-code + * claims it won't support the interface + */ + if (interface_info == NULL) + { + GDBusMessage *reply; + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.InvalidArgs", + _("No such interface “%sâ€"), + interface_name); + g_dbus_connection_send_message (es->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + handled = TRUE; + goto out; + } + + /* figure out where to dispatch the property get/set/getall calls */ + interface_user_data = NULL; + interface_vtable = es->vtable->dispatch (es->connection, + sender, + es->object_path, + interface_name, + requested_node, + &interface_user_data, + es->user_data); + if (interface_vtable == NULL) + { + g_warning ("The subtree introspection function indicates that '%s' " + "is a valid interface name, but calling the dispatch " + "function on that interface gave us NULL", interface_name); + goto out; + } + + if (is_property_get || is_property_set) + { + CONNECTION_LOCK (connection); + handled = validate_and_maybe_schedule_property_getset (es->connection, + message, + 0, + es->id, + is_property_get, + interface_info, + interface_vtable, + es->context, + interface_user_data); + CONNECTION_UNLOCK (connection); + } + else if (is_property_get_all) + { + CONNECTION_LOCK (connection); + handled = validate_and_maybe_schedule_property_get_all (es->connection, + message, + 0, + es->id, + interface_info, + interface_vtable, + es->context, + interface_user_data); + CONNECTION_UNLOCK (connection); + } + } + + out: + if (interfaces != NULL) + { + for (n = 0; interfaces[n] != NULL; n++) + g_dbus_interface_info_unref (interfaces[n]); + g_free (interfaces); + } + + return handled; +} + +typedef struct +{ + GDBusMessage *message; /* (owned) */ + ExportedSubtree *es; /* (owned) */ +} SubtreeDeferredData; + +static void +subtree_deferred_data_free (SubtreeDeferredData *data) +{ + g_object_unref (data->message); + exported_subtree_unref (data->es); + g_free (data); +} + +/* called without lock held in the thread where the caller registered the subtree */ +static gboolean +process_subtree_vtable_message_in_idle_cb (gpointer _data) +{ + SubtreeDeferredData *data = _data; + gboolean handled; + + handled = FALSE; + + if (g_strcmp0 (g_dbus_message_get_interface (data->message), "org.freedesktop.DBus.Introspectable") == 0 && + g_strcmp0 (g_dbus_message_get_member (data->message), "Introspect") == 0 && + g_strcmp0 (g_dbus_message_get_signature (data->message), "") == 0) + handled = handle_subtree_introspect (data->es->connection, + data->es, + data->message); + else + handled = handle_subtree_method_invocation (data->es->connection, + data->es, + data->message); + + if (!handled) + { + CONNECTION_LOCK (data->es->connection); + handled = handle_generic_unlocked (data->es->connection, data->message); + CONNECTION_UNLOCK (data->es->connection); + } + + /* if we couldn't handle the request, just bail with the UnknownMethod error */ + if (!handled) + { + GDBusMessage *reply; + reply = g_dbus_message_new_method_error (data->message, + "org.freedesktop.DBus.Error.UnknownMethod", + _("Method “%s†on interface “%s†with signature “%s†does not exist"), + g_dbus_message_get_member (data->message), + g_dbus_message_get_interface (data->message), + g_dbus_message_get_signature (data->message)); + g_dbus_connection_send_message (data->es->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + } + + return FALSE; +} + +/* called in GDBusWorker thread with connection's lock held */ +static gboolean +subtree_message_func (GDBusConnection *connection, + ExportedSubtree *es, + GDBusMessage *message) +{ + GSource *idle_source; + SubtreeDeferredData *data; + + data = g_new0 (SubtreeDeferredData, 1); + data->message = g_object_ref (message); + data->es = exported_subtree_ref (es); + + /* defer this call to an idle handler in the right thread */ + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_HIGH); + g_source_set_callback (idle_source, + process_subtree_vtable_message_in_idle_cb, + data, + (GDestroyNotify) subtree_deferred_data_free); + g_source_set_static_name (idle_source, "[gio] process_subtree_vtable_message_in_idle_cb"); + g_source_attach (idle_source, es->context); + g_source_unref (idle_source); + + /* since we own the entire subtree, handlers for objects not in the subtree have been + * tried already by libdbus-1 - so we just need to ensure that we're always going + * to reply to the message + */ + return TRUE; +} + +/** + * g_dbus_connection_register_subtree: + * @connection: a #GDBusConnection + * @object_path: the object path to register the subtree at + * @vtable: a #GDBusSubtreeVTable to enumerate, introspect and + * dispatch nodes in the subtree + * @flags: flags used to fine tune the behavior of the subtree + * @user_data: data to pass to functions in @vtable + * @user_data_free_func: function to call when the subtree is unregistered + * @error: return location for error or %NULL + * + * Registers a whole subtree of dynamic objects. + * + * The @enumerate and @introspection functions in @vtable are used to + * convey, to remote callers, what nodes exist in the subtree rooted + * by @object_path. + * + * When handling remote calls into any node in the subtree, first the + * @enumerate function is used to check if the node exists. If the node exists + * or the %G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES flag is set + * the @introspection function is used to check if the node supports the + * requested method. If so, the @dispatch function is used to determine + * where to dispatch the call. The collected #GDBusInterfaceVTable and + * #gpointer will be used to call into the interface vtable for processing + * the request. + * + * All calls into user-provided code will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. + * + * If an existing subtree is already registered at @object_path or + * then @error is set to %G_IO_ERROR_EXISTS. + * + * Note that it is valid to register regular objects (using + * g_dbus_connection_register_object()) in a subtree registered with + * g_dbus_connection_register_subtree() - if so, the subtree handler + * is tried as the last resort. One way to think about a subtree + * handler is to consider it a fallback handler for object paths not + * registered via g_dbus_connection_register_object() or other bindings. + * + * Note that @vtable will be copied so you cannot change it after + * registration. + * + * See this [server][gdbus-subtree-server] for an example of how to use + * this method. + * + * Returns: 0 if @error is set, otherwise a subtree registration ID (never 0) + * that can be used with g_dbus_connection_unregister_subtree() + * + * Since: 2.26 + */ +guint +g_dbus_connection_register_subtree (GDBusConnection *connection, + const gchar *object_path, + const GDBusSubtreeVTable *vtable, + GDBusSubtreeFlags flags, + gpointer user_data, + GDestroyNotify user_data_free_func, + GError **error) +{ + guint ret; + ExportedSubtree *es; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); + g_return_val_if_fail (object_path != NULL && g_variant_is_object_path (object_path), 0); + g_return_val_if_fail (vtable != NULL, 0); + g_return_val_if_fail (error == NULL || *error == NULL, 0); + g_return_val_if_fail (check_initialized (connection), 0); + + ret = 0; + + CONNECTION_LOCK (connection); + + es = g_hash_table_lookup (connection->map_object_path_to_es, object_path); + if (es != NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_EXISTS, + _("A subtree is already exported for %s"), + object_path); + goto out; + } + + es = g_new0 (ExportedSubtree, 1); + es->refcount = 1; + es->object_path = g_strdup (object_path); + es->connection = connection; + + es->vtable = _g_dbus_subtree_vtable_copy (vtable); + es->flags = flags; + es->id = (guint) g_atomic_int_add (&_global_subtree_registration_id, 1); /* TODO: overflow etc. */ + es->user_data = user_data; + es->user_data_free_func = user_data_free_func; + es->context = g_main_context_ref_thread_default (); + + g_hash_table_insert (connection->map_object_path_to_es, es->object_path, es); + g_hash_table_insert (connection->map_id_to_es, + GUINT_TO_POINTER (es->id), + es); + + ret = es->id; + + out: + CONNECTION_UNLOCK (connection); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_connection_unregister_subtree: + * @connection: a #GDBusConnection + * @registration_id: a subtree registration id obtained from + * g_dbus_connection_register_subtree() + * + * Unregisters a subtree. + * + * Returns: %TRUE if the subtree was unregistered, %FALSE otherwise + * + * Since: 2.26 + */ +gboolean +g_dbus_connection_unregister_subtree (GDBusConnection *connection, + guint registration_id) +{ + ExportedSubtree *es; + gboolean ret; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (check_initialized (connection), FALSE); + + ret = FALSE; + + CONNECTION_LOCK (connection); + + es = g_hash_table_lookup (connection->map_id_to_es, + GUINT_TO_POINTER (registration_id)); + if (es == NULL) + goto out; + + g_warn_if_fail (g_hash_table_remove (connection->map_id_to_es, GUINT_TO_POINTER (es->id))); + g_warn_if_fail (g_hash_table_remove (connection->map_object_path_to_es, es->object_path)); + + ret = TRUE; + + out: + CONNECTION_UNLOCK (connection); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* may be called in any thread, with connection's lock held */ +static void +handle_generic_ping_unlocked (GDBusConnection *connection, + const gchar *object_path, + GDBusMessage *message) +{ + GDBusMessage *reply; + reply = g_dbus_message_new_method_reply (message); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); +} + +/* may be called in any thread, with connection's lock held */ +static void +handle_generic_get_machine_id_unlocked (GDBusConnection *connection, + const gchar *object_path, + GDBusMessage *message) +{ + GDBusMessage *reply; + + reply = NULL; + if (connection->machine_id == NULL) + { + GError *error; + + error = NULL; + connection->machine_id = _g_dbus_get_machine_id (&error); + if (connection->machine_id == NULL) + { + reply = g_dbus_message_new_method_error_literal (message, + "org.freedesktop.DBus.Error.Failed", + error->message); + g_error_free (error); + } + } + + if (reply == NULL) + { + reply = g_dbus_message_new_method_reply (message); + g_dbus_message_set_body (reply, g_variant_new ("(s)", connection->machine_id)); + } + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); +} + +/* may be called in any thread, with connection's lock held */ +static void +handle_generic_introspect_unlocked (GDBusConnection *connection, + const gchar *object_path, + GDBusMessage *message) +{ + guint n; + GString *s; + gchar **registered; + GDBusMessage *reply; + + /* first the header */ + s = g_string_new (NULL); + introspect_append_header (s); + + registered = g_dbus_connection_list_registered_unlocked (connection, object_path); + for (n = 0; registered != NULL && registered[n] != NULL; n++) + g_string_append_printf (s, " \n", registered[n]); + g_strfreev (registered); + g_string_append (s, "\n"); + + reply = g_dbus_message_new_method_reply (message); + g_dbus_message_set_body (reply, g_variant_new ("(s)", s->str)); + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + g_string_free (s, TRUE); +} + +/* may be called in any thread, with connection's lock held */ +static gboolean +handle_generic_unlocked (GDBusConnection *connection, + GDBusMessage *message) +{ + gboolean handled; + const gchar *interface_name; + const gchar *member; + const gchar *signature; + const gchar *path; + + CONNECTION_ENSURE_LOCK (connection); + + handled = FALSE; + + interface_name = g_dbus_message_get_interface (message); + member = g_dbus_message_get_member (message); + signature = g_dbus_message_get_signature (message); + path = g_dbus_message_get_path (message); + + if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Introspectable") == 0 && + g_strcmp0 (member, "Introspect") == 0 && + g_strcmp0 (signature, "") == 0) + { + handle_generic_introspect_unlocked (connection, path, message); + handled = TRUE; + } + else if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Peer") == 0 && + g_strcmp0 (member, "Ping") == 0 && + g_strcmp0 (signature, "") == 0) + { + handle_generic_ping_unlocked (connection, path, message); + handled = TRUE; + } + else if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Peer") == 0 && + g_strcmp0 (member, "GetMachineId") == 0 && + g_strcmp0 (signature, "") == 0) + { + handle_generic_get_machine_id_unlocked (connection, path, message); + handled = TRUE; + } + + return handled; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* called in GDBusWorker thread with connection's lock held */ +static void +distribute_method_call (GDBusConnection *connection, + GDBusMessage *message) +{ + GDBusMessage *reply; + ExportedObject *eo; + ExportedSubtree *es; + const gchar *object_path; + const gchar *interface_name; + const gchar *member; + const gchar *path; + gchar *subtree_path; + gchar *needle; + gboolean object_found = FALSE; + + g_assert (g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL); + + interface_name = g_dbus_message_get_interface (message); + member = g_dbus_message_get_member (message); + path = g_dbus_message_get_path (message); + subtree_path = g_strdup (path); + needle = strrchr (subtree_path, '/'); + if (needle != NULL && needle != subtree_path) + { + *needle = '\0'; + } + else + { + g_free (subtree_path); + subtree_path = NULL; + } + + + if (G_UNLIKELY (_g_dbus_debug_incoming ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Incoming:\n" + " <<<< METHOD INVOCATION %s.%s()\n" + " on object %s\n" + " invoked by name %s\n" + " serial %d\n", + interface_name, member, + path, + g_dbus_message_get_sender (message) != NULL ? g_dbus_message_get_sender (message) : "(none)", + g_dbus_message_get_serial (message)); + _g_dbus_debug_print_unlock (); + } + + object_path = g_dbus_message_get_path (message); + g_assert (object_path != NULL); + + eo = g_hash_table_lookup (connection->map_object_path_to_eo, object_path); + if (eo != NULL) + { + if (obj_message_func (connection, eo, message, &object_found)) + goto out; + } + + es = g_hash_table_lookup (connection->map_object_path_to_es, object_path); + if (es != NULL) + { + if (subtree_message_func (connection, es, message)) + goto out; + } + + if (subtree_path != NULL) + { + es = g_hash_table_lookup (connection->map_object_path_to_es, subtree_path); + if (es != NULL) + { + if (subtree_message_func (connection, es, message)) + goto out; + } + } + + if (handle_generic_unlocked (connection, message)) + goto out; + + /* if we end up here, the message has not been not handled - so return an error saying this */ + if (object_found == TRUE) + { + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.UnknownMethod", + _("No such interface “%s†on object at path %s"), + interface_name, + object_path); + } + else + { + reply = g_dbus_message_new_method_error (message, + "org.freedesktop.DBus.Error.UnknownMethod", + _("Object does not exist at path “%sâ€"), + object_path); + } + + g_dbus_connection_send_message_unlocked (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + + out: + g_free (subtree_path); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called in any user thread, with the message_bus_lock held. */ +static GWeakRef * +message_bus_get_singleton (GBusType bus_type, + GError **error) +{ + GWeakRef *ret; + const gchar *starter_bus; + + ret = NULL; + + switch (bus_type) + { + case G_BUS_TYPE_SESSION: + ret = &the_session_bus; + break; + + case G_BUS_TYPE_SYSTEM: + ret = &the_system_bus; + break; + + case G_BUS_TYPE_STARTER: + starter_bus = g_getenv ("DBUS_STARTER_BUS_TYPE"); + if (g_strcmp0 (starter_bus, "session") == 0) + { + ret = message_bus_get_singleton (G_BUS_TYPE_SESSION, error); + goto out; + } + else if (g_strcmp0 (starter_bus, "system") == 0) + { + ret = message_bus_get_singleton (G_BUS_TYPE_SYSTEM, error); + goto out; + } + else + { + if (starter_bus != NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable" + " — unknown value “%sâ€"), + starter_bus); + } + else + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " + "variable is not set")); + } + } + break; + + default: + g_assert_not_reached (); + break; + } + + out: + return ret; +} + +/* Called in any user thread, without holding locks. */ +static GDBusConnection * +get_uninitialized_connection (GBusType bus_type, + GCancellable *cancellable, + GError **error) +{ + GWeakRef *singleton; + GDBusConnection *ret; + + ret = NULL; + + G_LOCK (message_bus_lock); + singleton = message_bus_get_singleton (bus_type, error); + if (singleton == NULL) + goto out; + + ret = g_weak_ref_get (singleton); + + if (ret == NULL) + { + gchar *address; + address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error); + if (address == NULL) + goto out; + ret = g_object_new (G_TYPE_DBUS_CONNECTION, + "address", address, + "flags", G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, + "exit-on-close", TRUE, + NULL); + + g_weak_ref_set (singleton, ret); + g_free (address); + } + + g_assert (ret != NULL); + + out: + G_UNLOCK (message_bus_lock); + return ret; +} + +/* May be called from any thread. Must not hold message_bus_lock. */ +GDBusConnection * +_g_bus_get_singleton_if_exists (GBusType bus_type) +{ + GWeakRef *singleton; + GDBusConnection *ret = NULL; + + G_LOCK (message_bus_lock); + singleton = message_bus_get_singleton (bus_type, NULL); + if (singleton == NULL) + goto out; + + ret = g_weak_ref_get (singleton); + + out: + G_UNLOCK (message_bus_lock); + return ret; +} + +/* May be called from any thread. Must not hold message_bus_lock. */ +void +_g_bus_forget_singleton (GBusType bus_type) +{ + GWeakRef *singleton; + + G_LOCK (message_bus_lock); + + singleton = message_bus_get_singleton (bus_type, NULL); + + if (singleton != NULL) + g_weak_ref_set (singleton, NULL); + + G_UNLOCK (message_bus_lock); +} + +/** + * g_bus_get_sync: + * @bus_type: a #GBusType + * @cancellable: (nullable): a #GCancellable or %NULL + * @error: return location for error or %NULL + * + * Synchronously connects to the message bus specified by @bus_type. + * Note that the returned object may shared with other callers, + * e.g. if two separate parts of a process calls this function with + * the same @bus_type, they will share the same object. + * + * This is a synchronous failable function. See g_bus_get() and + * g_bus_get_finish() for the asynchronous version. + * + * The returned object is a singleton, that is, shared with other + * callers of g_bus_get() and g_bus_get_sync() for @bus_type. In the + * event that you need a private message bus connection, use + * g_dbus_address_get_for_bus_sync() and + * g_dbus_connection_new_for_address() with + * G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT and + * G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION flags. + * + * Note that the returned #GDBusConnection object will (usually) have + * the #GDBusConnection:exit-on-close property set to %TRUE. + * + * Returns: (transfer full): a #GDBusConnection or %NULL if @error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusConnection * +g_bus_get_sync (GBusType bus_type, + GCancellable *cancellable, + GError **error) +{ + GDBusConnection *connection; + + _g_dbus_initialize (); + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + connection = get_uninitialized_connection (bus_type, cancellable, error); + if (connection == NULL) + goto out; + + if (!g_initable_init (G_INITABLE (connection), cancellable, error)) + { + g_object_unref (connection); + connection = NULL; + } + + out: + return connection; +} + +static void +bus_get_async_initable_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + GError *error = NULL; + + if (!g_async_initable_init_finish (G_ASYNC_INITABLE (source_object), + res, + &error)) + { + g_assert (error != NULL); + g_task_return_error (task, error); + g_object_unref (source_object); + } + else + { + g_task_return_pointer (task, source_object, g_object_unref); + } + g_object_unref (task); +} + +/** + * g_bus_get: + * @bus_type: a #GBusType + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to @callback + * + * Asynchronously connects to the message bus specified by @bus_type. + * + * When the operation is finished, @callback will be invoked. You can + * then call g_bus_get_finish() to get the result of the operation. + * + * This is an asynchronous failable function. See g_bus_get_sync() for + * the synchronous version. + * + * Since: 2.26 + */ +void +g_bus_get (GBusType bus_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDBusConnection *connection; + GTask *task; + GError *error = NULL; + + _g_dbus_initialize (); + + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (task, g_bus_get); + + connection = get_uninitialized_connection (bus_type, cancellable, &error); + if (connection == NULL) + { + g_assert (error != NULL); + g_task_return_error (task, error); + g_object_unref (task); + } + else + { + g_async_initable_init_async (G_ASYNC_INITABLE (connection), + G_PRIORITY_DEFAULT, + cancellable, + bus_get_async_initable_cb, + task); + } +} + +/** + * g_bus_get_finish: + * @res: a #GAsyncResult obtained from the #GAsyncReadyCallback passed + * to g_bus_get() + * @error: return location for error or %NULL + * + * Finishes an operation started with g_bus_get(). + * + * The returned object is a singleton, that is, shared with other + * callers of g_bus_get() and g_bus_get_sync() for @bus_type. In the + * event that you need a private message bus connection, use + * g_dbus_address_get_for_bus_sync() and + * g_dbus_connection_new_for_address() with + * G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT and + * G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION flags. + * + * Note that the returned #GDBusConnection object will (usually) have + * the #GDBusConnection:exit-on-close property set to %TRUE. + * + * Returns: (transfer full): a #GDBusConnection or %NULL if @error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusConnection * +g_bus_get_finish (GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, NULL), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusconnection.h b/gio/gdbusconnection.h new file mode 100644 index 0000000..4bd3e9a --- /dev/null +++ b/gio/gdbusconnection.h @@ -0,0 +1,684 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_CONNECTION_H__ +#define __G_DBUS_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_CONNECTION (g_dbus_connection_get_type ()) +#define G_DBUS_CONNECTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_CONNECTION, GDBusConnection)) +#define G_IS_DBUS_CONNECTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_CONNECTION)) + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_connection_get_type (void) G_GNUC_CONST; + +/* ---------------------------------------------------------------------------------------------------- */ + +GLIB_AVAILABLE_IN_ALL +void g_bus_get (GBusType bus_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_bus_get_finish (GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_bus_get_sync (GBusType bus_type, + GCancellable *cancellable, + GError **error); + +/* ---------------------------------------------------------------------------------------------------- */ + +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_new (GIOStream *stream, + const gchar *guid, + GDBusConnectionFlags flags, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_connection_new_finish (GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_connection_new_sync (GIOStream *stream, + const gchar *guid, + GDBusConnectionFlags flags, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_new_for_address (const gchar *address, + GDBusConnectionFlags flags, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_connection_new_for_address_finish (GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_connection_new_for_address_sync (const gchar *address, + GDBusConnectionFlags flags, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GError **error); + +/* ---------------------------------------------------------------------------------------------------- */ + +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_start_message_processing (GDBusConnection *connection); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_is_closed (GDBusConnection *connection); +GLIB_AVAILABLE_IN_ALL +GIOStream *g_dbus_connection_get_stream (GDBusConnection *connection); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_connection_get_guid (GDBusConnection *connection); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_connection_get_unique_name (GDBusConnection *connection); +GLIB_AVAILABLE_IN_ALL +GCredentials *g_dbus_connection_get_peer_credentials (GDBusConnection *connection); + +GLIB_AVAILABLE_IN_2_34 +guint32 g_dbus_connection_get_last_serial (GDBusConnection *connection); + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_get_exit_on_close (GDBusConnection *connection); +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_set_exit_on_close (GDBusConnection *connection, + gboolean exit_on_close); +GLIB_AVAILABLE_IN_ALL +GDBusCapabilityFlags g_dbus_connection_get_capabilities (GDBusConnection *connection); +GLIB_AVAILABLE_IN_2_60 +GDBusConnectionFlags g_dbus_connection_get_flags (GDBusConnection *connection); + +/* ---------------------------------------------------------------------------------------------------- */ + +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_close (GDBusConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_close_finish (GDBusConnection *connection, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_close_sync (GDBusConnection *connection, + GCancellable *cancellable, + GError **error); + +/* ---------------------------------------------------------------------------------------------------- */ + +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_flush (GDBusConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_flush_finish (GDBusConnection *connection, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_flush_sync (GDBusConnection *connection, + GCancellable *cancellable, + GError **error); + +/* ---------------------------------------------------------------------------------------------------- */ + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_send_message (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, + volatile guint32 *out_serial, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_send_message_with_reply (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, + gint timeout_msec, + volatile guint32 *out_serial, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_connection_send_message_with_reply_finish (GDBusConnection *connection, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_connection_send_message_with_reply_sync (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, + gint timeout_msec, + volatile guint32 *out_serial, + GCancellable *cancellable, + GError **error); + +/* ---------------------------------------------------------------------------------------------------- */ + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_emit_signal (GDBusConnection *connection, + const gchar *destination_bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_call (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_connection_call_finish (GDBusConnection *connection, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_connection_call_sync (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_30 +void g_dbus_connection_call_with_unix_fd_list (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_30 +GVariant *g_dbus_connection_call_with_unix_fd_list_finish (GDBusConnection *connection, + GUnixFDList **out_fd_list, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_2_30 +GVariant *g_dbus_connection_call_with_unix_fd_list_sync (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GUnixFDList **out_fd_list, + GCancellable *cancellable, + GError **error); + +/* ---------------------------------------------------------------------------------------------------- */ + + +/** + * GDBusInterfaceMethodCallFunc: + * @connection: A #GDBusConnection. + * @sender: The unique bus name of the remote caller. + * @object_path: The object path that the method was invoked on. + * @interface_name: The D-Bus interface name the method was invoked on. + * @method_name: The name of the method that was invoked. + * @parameters: A #GVariant tuple with parameters. + * @invocation: (transfer full): A #GDBusMethodInvocation object that must be used to return a value or error. + * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_object(). + * + * The type of the @method_call function in #GDBusInterfaceVTable. + * + * Since: 2.26 + */ +typedef void (*GDBusInterfaceMethodCallFunc) (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data); + +/** + * GDBusInterfaceGetPropertyFunc: + * @connection: A #GDBusConnection. + * @sender: The unique bus name of the remote caller. + * @object_path: The object path that the method was invoked on. + * @interface_name: The D-Bus interface name for the property. + * @property_name: The name of the property to get the value of. + * @error: Return location for error. + * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_object(). + * + * The type of the @get_property function in #GDBusInterfaceVTable. + * + * Returns: A #GVariant with the value for @property_name or %NULL if + * @error is set. If the returned #GVariant is floating, it is + * consumed - otherwise its reference count is decreased by one. + * + * Since: 2.26 + */ +typedef GVariant *(*GDBusInterfaceGetPropertyFunc) (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data); + +/** + * GDBusInterfaceSetPropertyFunc: + * @connection: A #GDBusConnection. + * @sender: The unique bus name of the remote caller. + * @object_path: The object path that the method was invoked on. + * @interface_name: The D-Bus interface name for the property. + * @property_name: The name of the property to get the value of. + * @value: The value to set the property to. + * @error: Return location for error. + * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_object(). + * + * The type of the @set_property function in #GDBusInterfaceVTable. + * + * Returns: %TRUE if the property was set to @value, %FALSE if @error is set. + * + * Since: 2.26 + */ +typedef gboolean (*GDBusInterfaceSetPropertyFunc) (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data); + +/** + * GDBusInterfaceVTable: + * @method_call: Function for handling incoming method calls. + * @get_property: Function for getting a property. + * @set_property: Function for setting a property. + * + * Virtual table for handling properties and method calls for a D-Bus + * interface. + * + * Since 2.38, if you want to handle getting/setting D-Bus properties + * asynchronously, give %NULL as your get_property() or set_property() + * function. The D-Bus call will be directed to your @method_call function, + * with the provided @interface_name set to "org.freedesktop.DBus.Properties". + * + * Ownership of the #GDBusMethodInvocation object passed to the + * method_call() function is transferred to your handler; you must + * call one of the methods of #GDBusMethodInvocation to return a reply + * (possibly empty), or an error. These functions also take ownership + * of the passed-in invocation object, so unless the invocation + * object has otherwise been referenced, it will be then be freed. + * Calling one of these functions may be done within your + * method_call() implementation but it also can be done at a later + * point to handle the method asynchronously. + * + * The usual checks on the validity of the calls is performed. For + * `Get` calls, an error is automatically returned if the property does + * not exist or the permissions do not allow access. The same checks are + * performed for `Set` calls, and the provided value is also checked for + * being the correct type. + * + * For both `Get` and `Set` calls, the #GDBusMethodInvocation + * passed to the @method_call handler can be queried with + * g_dbus_method_invocation_get_property_info() to get a pointer + * to the #GDBusPropertyInfo of the property. + * + * If you have readable properties specified in your interface info, + * you must ensure that you either provide a non-%NULL @get_property() + * function or provide implementations of both the `Get` and `GetAll` + * methods on org.freedesktop.DBus.Properties interface in your @method_call + * function. Note that the required return type of the `Get` call is + * `(v)`, not the type of the property. `GetAll` expects a return value + * of type `a{sv}`. + * + * If you have writable properties specified in your interface info, + * you must ensure that you either provide a non-%NULL @set_property() + * function or provide an implementation of the `Set` call. If implementing + * the call, you must return the value of type %G_VARIANT_TYPE_UNIT. + * + * Since: 2.26 + */ +struct _GDBusInterfaceVTable +{ + GDBusInterfaceMethodCallFunc method_call; + GDBusInterfaceGetPropertyFunc get_property; + GDBusInterfaceSetPropertyFunc set_property; + + /*< private >*/ + /* Padding for future expansion - also remember to update + * gdbusconnection.c:_g_dbus_interface_vtable_copy() when + * changing this. + */ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +guint g_dbus_connection_register_object (GDBusConnection *connection, + const gchar *object_path, + GDBusInterfaceInfo *interface_info, + const GDBusInterfaceVTable *vtable, + gpointer user_data, + GDestroyNotify user_data_free_func, + GError **error); +GLIB_AVAILABLE_IN_2_46 +guint g_dbus_connection_register_object_with_closures (GDBusConnection *connection, + const gchar *object_path, + GDBusInterfaceInfo *interface_info, + GClosure *method_call_closure, + GClosure *get_property_closure, + GClosure *set_property_closure, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_unregister_object (GDBusConnection *connection, + guint registration_id); + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * GDBusSubtreeEnumerateFunc: + * @connection: A #GDBusConnection. + * @sender: The unique bus name of the remote caller. + * @object_path: The object path that was registered with g_dbus_connection_register_subtree(). + * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_subtree(). + * + * The type of the @enumerate function in #GDBusSubtreeVTable. + * + * This function is called when generating introspection data and also + * when preparing to dispatch incoming messages in the event that the + * %G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES flag is not + * specified (ie: to verify that the object path is valid). + * + * Hierarchies are not supported; the items that you return should not + * contain the `/` character. + * + * The return value will be freed with g_strfreev(). + * + * Returns: (array zero-terminated=1) (transfer full): A newly allocated array of strings for node names that are children of @object_path. + * + * Since: 2.26 + */ +typedef gchar** (*GDBusSubtreeEnumerateFunc) (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + gpointer user_data); + +/** + * GDBusSubtreeIntrospectFunc: + * @connection: A #GDBusConnection. + * @sender: The unique bus name of the remote caller. + * @object_path: The object path that was registered with g_dbus_connection_register_subtree(). + * @node: A node that is a child of @object_path (relative to @object_path) or %NULL for the root of the subtree. + * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_subtree(). + * + * The type of the @introspect function in #GDBusSubtreeVTable. + * + * Subtrees are flat. @node, if non-%NULL, is always exactly one + * segment of the object path (ie: it never contains a slash). + * + * This function should return %NULL to indicate that there is no object + * at this node. + * + * If this function returns non-%NULL, the return value is expected to + * be a %NULL-terminated array of pointers to #GDBusInterfaceInfo + * structures describing the interfaces implemented by @node. This + * array will have g_dbus_interface_info_unref() called on each item + * before being freed with g_free(). + * + * The difference between returning %NULL and an array containing zero + * items is that the standard DBus interfaces will returned to the + * remote introspector in the empty array case, but not in the %NULL + * case. + * + * Returns: (array zero-terminated=1) (nullable) (transfer full): A %NULL-terminated array of pointers to #GDBusInterfaceInfo, or %NULL. + * + * Since: 2.26 + */ +typedef GDBusInterfaceInfo ** (*GDBusSubtreeIntrospectFunc) (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *node, + gpointer user_data); + +/** + * GDBusSubtreeDispatchFunc: + * @connection: A #GDBusConnection. + * @sender: The unique bus name of the remote caller. + * @object_path: The object path that was registered with g_dbus_connection_register_subtree(). + * @interface_name: The D-Bus interface name that the method call or property access is for. + * @node: A node that is a child of @object_path (relative to @object_path) or %NULL for the root of the subtree. + * @out_user_data: (nullable) (not optional): Return location for user data to pass to functions in the returned #GDBusInterfaceVTable. + * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_subtree(). + * + * The type of the @dispatch function in #GDBusSubtreeVTable. + * + * Subtrees are flat. @node, if non-%NULL, is always exactly one + * segment of the object path (ie: it never contains a slash). + * + * Returns: (nullable): A #GDBusInterfaceVTable or %NULL if you don't want to handle the methods. + * + * Since: 2.26 + */ +typedef const GDBusInterfaceVTable * (*GDBusSubtreeDispatchFunc) (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *node, + gpointer *out_user_data, + gpointer user_data); + +/** + * GDBusSubtreeVTable: + * @enumerate: Function for enumerating child nodes. + * @introspect: Function for introspecting a child node. + * @dispatch: Function for dispatching a remote call on a child node. + * + * Virtual table for handling subtrees registered with g_dbus_connection_register_subtree(). + * + * Since: 2.26 + */ +struct _GDBusSubtreeVTable +{ + GDBusSubtreeEnumerateFunc enumerate; + GDBusSubtreeIntrospectFunc introspect; + GDBusSubtreeDispatchFunc dispatch; + + /*< private >*/ + /* Padding for future expansion - also remember to update + * gdbusconnection.c:_g_dbus_subtree_vtable_copy() when + * changing this. + */ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +guint g_dbus_connection_register_subtree (GDBusConnection *connection, + const gchar *object_path, + const GDBusSubtreeVTable *vtable, + GDBusSubtreeFlags flags, + gpointer user_data, + GDestroyNotify user_data_free_func, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_connection_unregister_subtree (GDBusConnection *connection, + guint registration_id); + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * GDBusSignalCallback: + * @connection: A #GDBusConnection. + * @sender_name: (nullable): The unique bus name of the sender of the signal, + or %NULL on a peer-to-peer D-Bus connection. + * @object_path: The object path that the signal was emitted on. + * @interface_name: The name of the interface. + * @signal_name: The name of the signal. + * @parameters: A #GVariant tuple with parameters for the signal. + * @user_data: User data passed when subscribing to the signal. + * + * Signature for callback function used in g_dbus_connection_signal_subscribe(). + * + * Since: 2.26 + */ +typedef void (*GDBusSignalCallback) (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +guint g_dbus_connection_signal_subscribe (GDBusConnection *connection, + const gchar *sender, + const gchar *interface_name, + const gchar *member, + const gchar *object_path, + const gchar *arg0, + GDBusSignalFlags flags, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func); +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_signal_unsubscribe (GDBusConnection *connection, + guint subscription_id); + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * GDBusMessageFilterFunction: + * @connection: (transfer none): A #GDBusConnection. + * @message: (transfer full): A locked #GDBusMessage that the filter function takes ownership of. + * @incoming: %TRUE if it is a message received from the other peer, %FALSE if it is + * a message to be sent to the other peer. + * @user_data: User data passed when adding the filter. + * + * Signature for function used in g_dbus_connection_add_filter(). + * + * A filter function is passed a #GDBusMessage and expected to return + * a #GDBusMessage too. Passive filter functions that don't modify the + * message can simply return the @message object: + * |[ + * static GDBusMessage * + * passive_filter (GDBusConnection *connection + * GDBusMessage *message, + * gboolean incoming, + * gpointer user_data) + * { + * // inspect @message + * return message; + * } + * ]| + * Filter functions that wants to drop a message can simply return %NULL: + * |[ + * static GDBusMessage * + * drop_filter (GDBusConnection *connection + * GDBusMessage *message, + * gboolean incoming, + * gpointer user_data) + * { + * if (should_drop_message) + * { + * g_object_unref (message); + * message = NULL; + * } + * return message; + * } + * ]| + * Finally, a filter function may modify a message by copying it: + * |[ + * static GDBusMessage * + * modifying_filter (GDBusConnection *connection + * GDBusMessage *message, + * gboolean incoming, + * gpointer user_data) + * { + * GDBusMessage *copy; + * GError *error; + * + * error = NULL; + * copy = g_dbus_message_copy (message, &error); + * // handle @error being set + * g_object_unref (message); + * + * // modify @copy + * + * return copy; + * } + * ]| + * If the returned #GDBusMessage is different from @message and cannot + * be sent on @connection (it could use features, such as file + * descriptors, not compatible with @connection), then a warning is + * logged to standard error. Applications can + * check this ahead of time using g_dbus_message_to_blob() passing a + * #GDBusCapabilityFlags value obtained from @connection. + * + * Returns: (transfer full) (nullable): A #GDBusMessage that will be freed with + * g_object_unref() or %NULL to drop the message. Passive filter + * functions can simply return the passed @message object. + * + * Since: 2.26 + */ +typedef GDBusMessage *(*GDBusMessageFilterFunction) (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +guint g_dbus_connection_add_filter (GDBusConnection *connection, + GDBusMessageFilterFunction filter_function, + gpointer user_data, + GDestroyNotify user_data_free_func); + +GLIB_AVAILABLE_IN_ALL +void g_dbus_connection_remove_filter (GDBusConnection *connection, + guint filter_id); + +/* ---------------------------------------------------------------------------------------------------- */ + + +G_END_DECLS + +#endif /* __G_DBUS_CONNECTION_H__ */ diff --git a/gio/gdbusdaemon.c b/gio/gdbusdaemon.c new file mode 100644 index 0000000..5dfe62c --- /dev/null +++ b/gio/gdbusdaemon.c @@ -0,0 +1,1744 @@ +#include "config.h" + +#include +#include + +#include +#include +#include +#include "gdbusdaemon.h" +#include "glibintl.h" + +#include "gdbus-daemon-generated.h" + +#define DBUS_SERVICE_NAME "org.freedesktop.DBus" + +/* Owner flags */ +#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */ +#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */ +#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */ + +/* Replies to request for a name */ +#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */ +#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */ +#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 /**< Service is already in the queue */ +#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */ + +/* Replies to releasing a name */ +#define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /**< Service was released from the given name */ +#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */ +#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */ + +/* Replies to service starts */ +#define DBUS_START_REPLY_SUCCESS 1 /**< Service was auto started */ +#define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */ + +#define IDLE_TIMEOUT_MSEC 3000 + +struct _GDBusDaemon +{ + _GFreedesktopDBusSkeleton parent_instance; + + gchar *address; + guint timeout; + gchar *tmpdir; + GDBusServer *server; + gchar *guid; + GHashTable *clients; + GHashTable *names; + guint32 next_major_id; + guint32 next_minor_id; +}; + +struct _GDBusDaemonClass +{ + _GFreedesktopDBusSkeletonClass parent_class; +}; + +enum { + PROP_0, + PROP_ADDRESS, +}; + +enum +{ + SIGNAL_IDLE_TIMEOUT, + NR_SIGNALS +}; + +static guint g_dbus_daemon_signals[NR_SIGNALS]; + + +static void initable_iface_init (GInitableIface *initable_iface); +static void g_dbus_daemon_iface_init (_GFreedesktopDBusIface *iface); + +#define g_dbus_daemon_get_type _g_dbus_daemon_get_type +G_DEFINE_TYPE_WITH_CODE (GDBusDaemon, g_dbus_daemon, _G_TYPE_FREEDESKTOP_DBUS_SKELETON, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init) + G_IMPLEMENT_INTERFACE (_G_TYPE_FREEDESKTOP_DBUS, g_dbus_daemon_iface_init)) + +typedef struct { + GDBusDaemon *daemon; + char *id; + GDBusConnection *connection; + GList *matches; +} Client; + +typedef struct { + Client *client; + guint32 flags; +} NameOwner; + +typedef struct { + int refcount; + + char *name; + GDBusDaemon *daemon; + + NameOwner *owner; + GList *queue; +} Name; + +enum { + MATCH_ELEMENT_TYPE, + MATCH_ELEMENT_SENDER, + MATCH_ELEMENT_INTERFACE, + MATCH_ELEMENT_MEMBER, + MATCH_ELEMENT_PATH, + MATCH_ELEMENT_PATH_NAMESPACE, + MATCH_ELEMENT_DESTINATION, + MATCH_ELEMENT_ARG0NAMESPACE, + MATCH_ELEMENT_EAVESDROP, + MATCH_ELEMENT_ARGN, + MATCH_ELEMENT_ARGNPATH, +}; + +typedef struct { + guint16 type; + guint16 arg; + char *value; +} MatchElement; + +typedef struct { + gboolean eavesdrop; + GDBusMessageType type; + int n_elements; + MatchElement *elements; +} Match; + +static GDBusMessage *filter_function (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data); +static void connection_closed (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + Client *client); + +static NameOwner * +name_owner_new (Client *client, guint32 flags) +{ + NameOwner *owner; + + owner = g_new0 (NameOwner, 1); + owner->client = client; + owner->flags = flags; + return owner; +} + +static void +name_owner_free (NameOwner *owner) +{ + g_free (owner); +} + +static Name * +name_new (GDBusDaemon *daemon, const char *str) +{ + Name *name; + + name = g_new0 (Name, 1); + name->refcount = 1; + name->daemon = daemon; + name->name = g_strdup (str); + + g_hash_table_insert (daemon->names, name->name, name); + + return name; +} + +static Name * +name_ref (Name *name) +{ + g_assert (name->refcount > 0); + name->refcount++; + return name; +} + +static void +name_unref (Name *name) +{ + g_assert (name->refcount > 0); + if (--name->refcount == 0) + { + g_hash_table_remove (name->daemon->names, name->name); + g_free (name->name); + g_free (name); + } +} + +static Name * +name_ensure (GDBusDaemon *daemon, const char *str) +{ + Name *name; + + name = g_hash_table_lookup (daemon->names, str); + + if (name != NULL) + return name_ref (name); + return name_new (daemon, str); +} + +static Name * +name_lookup (GDBusDaemon *daemon, const char *str) +{ + return g_hash_table_lookup (daemon->names, str); +} + +static gboolean +is_key (const char *key_start, const char *key_end, const char *value) +{ + gsize len = strlen (value); + + g_assert (key_end >= key_start); + if (len != (gsize) (key_end - key_start)) + return FALSE; + + return strncmp (key_start, value, len) == 0; +} + +static gboolean +parse_key (MatchElement *element, const char *key_start, const char *key_end) +{ + gboolean res = TRUE; + + if (is_key (key_start, key_end, "type")) + { + element->type = MATCH_ELEMENT_TYPE; + } + else if (is_key (key_start, key_end, "sender")) + { + element->type = MATCH_ELEMENT_SENDER; + } + else if (is_key (key_start, key_end, "interface")) + { + element->type = MATCH_ELEMENT_INTERFACE; + } + else if (is_key (key_start, key_end, "member")) + { + element->type = MATCH_ELEMENT_MEMBER; + } + else if (is_key (key_start, key_end, "path")) + { + element->type = MATCH_ELEMENT_PATH; + } + else if (is_key (key_start, key_end, "path_namespace")) + { + element->type = MATCH_ELEMENT_PATH_NAMESPACE; + } + else if (is_key (key_start, key_end, "destination")) + { + element->type = MATCH_ELEMENT_DESTINATION; + } + else if (is_key (key_start, key_end, "arg0namespace")) + { + element->type = MATCH_ELEMENT_ARG0NAMESPACE; + } + else if (is_key (key_start, key_end, "eavesdrop")) + { + element->type = MATCH_ELEMENT_EAVESDROP; + } + else if (key_end - key_start > 3 && is_key (key_start, key_start + 3, "arg")) + { + const char *digits = key_start + 3; + const char *end_digits = digits; + + while (end_digits < key_end && g_ascii_isdigit (*end_digits)) + end_digits++; + + if (end_digits == key_end) /* argN */ + { + element->type = MATCH_ELEMENT_ARGN; + element->arg = atoi (digits); + } + else if (is_key (end_digits, key_end, "path")) /* argNpath */ + { + element->type = MATCH_ELEMENT_ARGNPATH; + element->arg = atoi (digits); + } + else + res = FALSE; + } + else + res = FALSE; + + return res; +} + +static const char * +parse_value (MatchElement *element, const char *s) +{ + char quote_char; + GString *value; + + value = g_string_new (""); + + quote_char = 0; + + for (;*s; s++) + { + if (quote_char == 0) + { + switch (*s) + { + case '\'': + quote_char = '\''; + break; + + case ',': + s++; + goto out; + + case '\\': + quote_char = '\\'; + break; + + default: + g_string_append_c (value, *s); + break; + } + } + else if (quote_char == '\\') + { + /* \ only counts as an escape if escaping a quote mark */ + if (*s != '\'') + g_string_append_c (value, '\\'); + + g_string_append_c (value, *s); + quote_char = 0; + } + else /* quote_char == ' */ + { + if (*s == '\'') + quote_char = 0; + else + g_string_append_c (value, *s); + } + } + + out: + + if (quote_char == '\\') + g_string_append_c (value, '\\'); + else if (quote_char == '\'') + { + g_string_free (value, TRUE); + return NULL; + } + + element->value = g_string_free (value, FALSE); + return s; +} + +static Match * +match_new (const char *str) +{ + Match *match; + GArray *elements; + const char *p; + const char *key_start; + const char *key_end; + MatchElement element; + gboolean eavesdrop; + GDBusMessageType type; + gsize i; + + eavesdrop = FALSE; + type = G_DBUS_MESSAGE_TYPE_INVALID; + elements = g_array_new (TRUE, TRUE, sizeof (MatchElement)); + + p = str; + + while (*p != 0) + { + memset (&element, 0, sizeof (element)); + + /* Skip initial whitespace */ + while (*p && g_ascii_isspace (*p)) + p++; + + key_start = p; + + /* Read non-whitespace non-equals chars */ + while (*p && *p != '=' && !g_ascii_isspace (*p)) + p++; + + key_end = p; + + /* Skip any whitespace after key */ + while (*p && g_ascii_isspace (*p)) + p++; + + if (key_start == key_end) + continue; /* Allow trailing whitespace */ + + if (*p != '=') + goto error; + + ++p; + + if (!parse_key (&element, key_start, key_end)) + goto error; + + p = parse_value (&element, p); + if (p == NULL) + goto error; + + if (element.type == MATCH_ELEMENT_EAVESDROP) + { + if (strcmp (element.value, "true") == 0) + eavesdrop = TRUE; + else if (strcmp (element.value, "false") == 0) + eavesdrop = FALSE; + else + { + g_free (element.value); + goto error; + } + g_free (element.value); + } + else if (element.type == MATCH_ELEMENT_TYPE) + { + if (strcmp (element.value, "signal") == 0) + type = G_DBUS_MESSAGE_TYPE_SIGNAL; + else if (strcmp (element.value, "method_call") == 0) + type = G_DBUS_MESSAGE_TYPE_METHOD_CALL; + else if (strcmp (element.value, "method_return") == 0) + type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN; + else if (strcmp (element.value, "error") == 0) + type = G_DBUS_MESSAGE_TYPE_ERROR; + else + { + g_free (element.value); + goto error; + } + g_free (element.value); + } + else + g_array_append_val (elements, element); + } + + match = g_new0 (Match, 1); + match->n_elements = elements->len; + match->elements = (MatchElement *)g_array_free (elements, FALSE); + match->eavesdrop = eavesdrop; + match->type = type; + + return match; + + error: + for (i = 0; i < elements->len; i++) + g_free (g_array_index (elements, MatchElement, i).value); + g_array_free (elements, TRUE); + return NULL; +} + +static void +match_free (Match *match) +{ + int i; + for (i = 0; i < match->n_elements; i++) + g_free (match->elements[i].value); + g_free (match->elements); + g_free (match); +} + +static gboolean +match_equal (Match *a, Match *b) +{ + int i; + + if (a->eavesdrop != b->eavesdrop) + return FALSE; + if (a->type != b->type) + return FALSE; + if (a->n_elements != b->n_elements) + return FALSE; + for (i = 0; i < a->n_elements; i++) + { + if (a->elements[i].type != b->elements[i].type || + a->elements[i].arg != b->elements[i].arg || + strcmp (a->elements[i].value, b->elements[i].value) != 0) + return FALSE; + } + return TRUE; +} + +static const gchar * +message_get_argN (GDBusMessage *message, int n, gboolean allow_path) +{ + const gchar *ret; + GVariant *body; + + ret = NULL; + + body = g_dbus_message_get_body (message); + + if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE)) + { + GVariant *item; + item = g_variant_get_child_value (body, n); + if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING) || + (allow_path && g_variant_is_of_type (item, G_VARIANT_TYPE_OBJECT_PATH))) + ret = g_variant_get_string (item, NULL); + g_variant_unref (item); + } + + return ret; +} + +enum { + CHECK_TYPE_STRING, + CHECK_TYPE_NAME, + CHECK_TYPE_PATH_PREFIX, + CHECK_TYPE_PATH_RELATED, + CHECK_TYPE_NAMESPACE_PREFIX +}; + +static gboolean +match_matches (GDBusDaemon *daemon, + Match *match, GDBusMessage *message, + gboolean has_destination) +{ + MatchElement *element; + Name *name; + int i, len, len2; + const char *value; + int check_type; + + if (has_destination && !match->eavesdrop) + return FALSE; + + if (match->type != G_DBUS_MESSAGE_TYPE_INVALID && + g_dbus_message_get_message_type (message) != match->type) + return FALSE; + + for (i = 0; i < match->n_elements; i++) + { + element = &match->elements[i]; + check_type = CHECK_TYPE_STRING; + switch (element->type) + { + case MATCH_ELEMENT_SENDER: + check_type = CHECK_TYPE_NAME; + value = g_dbus_message_get_sender (message); + if (value == NULL) + value = DBUS_SERVICE_NAME; + break; + case MATCH_ELEMENT_DESTINATION: + check_type = CHECK_TYPE_NAME; + value = g_dbus_message_get_destination (message); + break; + case MATCH_ELEMENT_INTERFACE: + value = g_dbus_message_get_interface (message); + break; + case MATCH_ELEMENT_MEMBER: + value = g_dbus_message_get_member (message); + break; + case MATCH_ELEMENT_PATH: + value = g_dbus_message_get_path (message); + break; + case MATCH_ELEMENT_PATH_NAMESPACE: + check_type = CHECK_TYPE_PATH_PREFIX; + value = g_dbus_message_get_path (message); + break; + case MATCH_ELEMENT_ARG0NAMESPACE: + check_type = CHECK_TYPE_NAMESPACE_PREFIX; + value = message_get_argN (message, 0, FALSE); + break; + case MATCH_ELEMENT_ARGN: + value = message_get_argN (message, element->arg, FALSE); + break; + case MATCH_ELEMENT_ARGNPATH: + check_type = CHECK_TYPE_PATH_RELATED; + value = message_get_argN (message, element->arg, TRUE); + break; + default: + case MATCH_ELEMENT_TYPE: + case MATCH_ELEMENT_EAVESDROP: + g_assert_not_reached (); + } + + if (value == NULL) + return FALSE; + + switch (check_type) + { + case CHECK_TYPE_STRING: + if (strcmp (element->value, value) != 0) + return FALSE; + break; + case CHECK_TYPE_NAME: + name = name_lookup (daemon, element->value); + if (name != NULL && name->owner != NULL) + { + if (strcmp (name->owner->client->id, value) != 0) + return FALSE; + } + else if (strcmp (element->value, value) != 0) + return FALSE; + break; + case CHECK_TYPE_PATH_PREFIX: + len = strlen (element->value); + + /* Make sure to handle the case of element->value == '/'. */ + if (len == 1) + break; + + /* Fail if there's no prefix match, or if the prefix match doesn't + * finish at the end of or at a separator in the @value. */ + if (!g_str_has_prefix (value, element->value)) + return FALSE; + if (value[len] != 0 && value[len] != '/') + return FALSE; + + break; + case CHECK_TYPE_PATH_RELATED: + len = strlen (element->value); + len2 = strlen (value); + + if (!(strcmp (value, element->value) == 0 || + (len2 > 0 && value[len2-1] == '/' && g_str_has_prefix (element->value, value)) || + (len > 0 && element->value[len-1] == '/' && g_str_has_prefix (value, element->value)))) + return FALSE; + break; + case CHECK_TYPE_NAMESPACE_PREFIX: + len = strlen (element->value); + if (!(g_str_has_prefix (value, element->value) && + (value[len] == 0 || value[len] == '.'))) + return FALSE; + break; + default: + g_assert_not_reached (); + } + } + + return TRUE; +} + +static void +broadcast_message (GDBusDaemon *daemon, + GDBusMessage *message, + gboolean has_destination, + gboolean preserve_serial, + Client *not_to) +{ + GList *clients, *l, *ll; + GDBusMessage *copy; + + clients = g_hash_table_get_values (daemon->clients); + for (l = clients; l != NULL; l = l->next) + { + Client *client = l->data; + + if (client == not_to) + continue; + + for (ll = client->matches; ll != NULL; ll = ll->next) + { + Match *match = ll->data; + + if (match_matches (daemon, match, message, has_destination)) + break; + } + + if (ll != NULL) + { + copy = g_dbus_message_copy (message, NULL); + if (copy) + { + g_dbus_connection_send_message (client->connection, copy, + preserve_serial?G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL:0, NULL, NULL); + g_object_unref (copy); + } + } + } + + g_list_free (clients); +} + +static void +send_name_owner_changed (GDBusDaemon *daemon, + const char *name, + const char *old_owner, + const char *new_owner) +{ + GDBusMessage *signal_message; + + signal_message = g_dbus_message_new_signal ("/org/freedesktop/DBus", + "org.freedesktop.DBus", + "NameOwnerChanged"); + g_dbus_message_set_body (signal_message, + g_variant_new ("(sss)", + name, + old_owner ? old_owner : "", + new_owner ? new_owner : "")); + + broadcast_message (daemon, signal_message, FALSE, FALSE, NULL); + g_object_unref (signal_message); + +} + +static gboolean +name_unqueue_owner (Name *name, Client *client) +{ + GList *l; + + for (l = name->queue; l != NULL; l = l->next) + { + NameOwner *other = l->data; + + if (other->client == client) + { + name->queue = g_list_delete_link (name->queue, l); + name_unref (name); + name_owner_free (other); + return TRUE; + } + } + + return FALSE; +} + +static void +name_replace_owner (Name *name, NameOwner *owner) +{ + GDBusDaemon *daemon = name->daemon; + NameOwner *old_owner; + char *old_name = NULL, *new_name = NULL; + Client *new_client = NULL; + + if (owner) + new_client = owner->client; + + name_ref (name); + + old_owner = name->owner; + if (old_owner) + { + Client *old_client = old_owner->client; + + g_assert (old_owner->client != new_client); + + g_dbus_connection_emit_signal (old_client->connection, + NULL, "/org/freedesktop/DBus", + "org.freedesktop.DBus", "NameLost", + g_variant_new ("(s)", + name->name), NULL); + + old_name = g_strdup (old_client->id); + if (old_owner->flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) + { + name_unref (name); + name_owner_free (old_owner); + } + else + name->queue = g_list_prepend (name->queue, old_owner); + } + + name->owner = owner; + if (owner) + { + name_unqueue_owner (name, owner->client); + name_ref (name); + new_name = new_client->id; + + g_dbus_connection_emit_signal (new_client->connection, + NULL, "/org/freedesktop/DBus", + "org.freedesktop.DBus", "NameAcquired", + g_variant_new ("(s)", + name->name), NULL); + } + + send_name_owner_changed (daemon, name->name, old_name, new_name); + + g_free (old_name); + + name_unref (name); +} + +static void +name_release_owner (Name *name) +{ + NameOwner *next_owner = NULL; + + name_ref (name); + + /* Will someone else take over? */ + if (name->queue) + { + next_owner = name->queue->data; + name_unref (name); + name->queue = g_list_delete_link (name->queue, name->queue); + } + + name->owner->flags |= DBUS_NAME_FLAG_DO_NOT_QUEUE; + name_replace_owner (name, next_owner); + + name_unref (name); +} + +static void +name_queue_owner (Name *name, NameOwner *owner) +{ + GList *l; + + for (l = name->queue; l != NULL; l = l->next) + { + NameOwner *other = l->data; + + if (other->client == owner->client) + { + other->flags = owner->flags; + name_owner_free (owner); + return; + } + } + + name->queue = g_list_append (name->queue, owner); + name_ref (name); +} + +static Client * +client_new (GDBusDaemon *daemon, GDBusConnection *connection) +{ + Client *client; + GError *error = NULL; + + client = g_new0 (Client, 1); + client->daemon = daemon; + client->id = g_strdup_printf (":%d.%d", daemon->next_major_id, daemon->next_minor_id); + client->connection = g_object_ref (connection); + + if (daemon->next_minor_id == G_MAXUINT32) + { + daemon->next_minor_id = 0; + daemon->next_major_id++; + } + else + daemon->next_minor_id++; + + g_object_set_data (G_OBJECT (connection), "client", client); + g_hash_table_insert (daemon->clients, client->id, client); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (daemon), connection, + "/org/freedesktop/DBus", &error); + g_assert_no_error (error); + + g_signal_connect (connection, "closed", G_CALLBACK (connection_closed), client); + g_dbus_connection_add_filter (connection, + filter_function, + client, NULL); + + send_name_owner_changed (daemon, client->id, NULL, client->id); + + return client; +} + +static void +client_free (Client *client) +{ + GDBusDaemon *daemon = client->daemon; + GList *l, *names; + + g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON (daemon), + client->connection); + + g_hash_table_remove (daemon->clients, client->id); + + names = g_hash_table_get_values (daemon->names); + for (l = names; l != NULL; l = l->next) + { + Name *name = l->data; + + name_ref (name); + + if (name->owner && name->owner->client == client) + name_release_owner (name); + + name_unqueue_owner (name, client); + + name_unref (name); + } + g_list_free (names); + + send_name_owner_changed (daemon, client->id, client->id, NULL); + + g_object_unref (client->connection); + + for (l = client->matches; l != NULL; l = l->next) + match_free (l->data); + g_list_free (client->matches); + + g_free (client->id); + g_free (client); +} + +static gboolean +idle_timeout_cb (gpointer user_data) +{ + GDBusDaemon *daemon = user_data; + + daemon->timeout = 0; + + g_signal_emit (daemon, + g_dbus_daemon_signals[SIGNAL_IDLE_TIMEOUT], + 0); + + return G_SOURCE_REMOVE; +} + +static void +connection_closed (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + Client *client) +{ + GDBusDaemon *daemon = client->daemon; + + client_free (client); + + if (g_hash_table_size (daemon->clients) == 0) + daemon->timeout = g_timeout_add (IDLE_TIMEOUT_MSEC, + idle_timeout_cb, + daemon); +} + +static gboolean +handle_add_match (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_rule) +{ + Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client"); + Match *match; + + match = match_new (arg_rule); + + if (match == NULL) + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_INVALID, + "Invalid rule: %s", arg_rule); + else + { + client->matches = g_list_prepend (client->matches, match); + _g_freedesktop_dbus_complete_add_match (object, invocation); + } + return TRUE; +} + +static gboolean +handle_get_connection_selinux_security_context (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name) +{ + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN, + "selinux context not supported"); + _g_freedesktop_dbus_complete_get_connection_selinux_security_context (object, invocation, ""); + return TRUE; +} + +static gboolean +handle_get_connection_unix_process_id (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name) +{ + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, + "connection pid not supported"); + return TRUE; +} + +static gboolean +handle_get_connection_unix_user (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name) +{ + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, + "connection user not supported"); + return TRUE; +} + +static gboolean +handle_get_id (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + _g_freedesktop_dbus_complete_get_id (object, invocation, + daemon->guid); + return TRUE; +} + +static gboolean +handle_get_name_owner (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + Name *name; + + if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0) + { + _g_freedesktop_dbus_complete_get_name_owner (object, invocation, DBUS_SERVICE_NAME); + return TRUE; + } + + if (arg_name[0] == ':') + { + if (g_hash_table_lookup (daemon->clients, arg_name) == NULL) + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER, + "Could not get owner of name '%s': no such name", arg_name); + else + _g_freedesktop_dbus_complete_get_name_owner (object, invocation, arg_name); + return TRUE; + } + + name = name_lookup (daemon, arg_name); + if (name == NULL || name->owner == NULL) + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER, + "Could not get owner of name '%s': no such name", arg_name); + return TRUE; + } + + _g_freedesktop_dbus_complete_get_name_owner (object, invocation, name->owner->client->id); + return TRUE; +} + +static gboolean +handle_hello (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation) +{ + Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client"); + _g_freedesktop_dbus_complete_hello (object, invocation, client->id); + + g_dbus_connection_emit_signal (client->connection, + NULL, "/org/freedesktop/DBus", + "org.freedesktop.DBus", "NameAcquired", + g_variant_new ("(s)", + client->id), NULL); + + return TRUE; +} + +static gboolean +handle_list_activatable_names (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation) +{ + const char *names[] = { NULL }; + + _g_freedesktop_dbus_complete_list_activatable_names (object, + invocation, + names); + return TRUE; +} + +static gboolean +handle_list_names (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + GPtrArray *array; + GList *clients, *names, *l; + + array = g_ptr_array_new (); + + clients = g_hash_table_get_values (daemon->clients); + for (l = clients; l != NULL; l = l->next) + { + Client *client = l->data; + + g_ptr_array_add (array, client->id); + } + + g_list_free (clients); + + names = g_hash_table_get_values (daemon->names); + for (l = names; l != NULL; l = l->next) + { + Name *name = l->data; + + g_ptr_array_add (array, name->name); + } + + g_list_free (names); + + g_ptr_array_add (array, NULL); + + _g_freedesktop_dbus_complete_list_names (object, + invocation, + (const gchar * const*)array->pdata); + g_ptr_array_free (array, TRUE); + return TRUE; +} + +static gboolean +handle_list_queued_owners (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + GPtrArray *array; + Name *name; + GList *l; + + array = g_ptr_array_new (); + + name = name_lookup (daemon, arg_name); + if (name && name->owner) + { + for (l = name->queue; l != NULL; l = l->next) + { + Client *client = l->data; + + g_ptr_array_add (array, client->id); + } + } + + g_ptr_array_add (array, NULL); + + _g_freedesktop_dbus_complete_list_queued_owners (object, + invocation, + (const gchar * const*)array->pdata); + g_ptr_array_free (array, TRUE); + return TRUE; +} + +static gboolean +handle_name_has_owner (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + Name *name; + Client *client; + + name = name_lookup (daemon, arg_name); + client = g_hash_table_lookup (daemon->clients, arg_name); + + _g_freedesktop_dbus_complete_name_has_owner (object, invocation, + name != NULL || client != NULL); + return TRUE; +} + +static gboolean +handle_release_name (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name) +{ + Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client"); + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + Name *name; + guint32 result; + + if (!g_dbus_is_name (arg_name)) + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "Given bus name \"%s\" is not valid", arg_name); + return TRUE; + } + + if (*arg_name == ':') + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "Cannot release a service starting with ':' such as \"%s\"", arg_name); + return TRUE; + } + + if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0) + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "Cannot release a service named " DBUS_SERVICE_NAME ", because that is owned by the bus"); + return TRUE; + } + + name = name_lookup (daemon, arg_name); + + if (name == NULL) + result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT; + else if (name->owner && name->owner->client == client) + { + name_release_owner (name); + result = DBUS_RELEASE_NAME_REPLY_RELEASED; + } + else if (name_unqueue_owner (name, client)) + result = DBUS_RELEASE_NAME_REPLY_RELEASED; + else + result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER; + + _g_freedesktop_dbus_complete_release_name (object, invocation, result); + return TRUE; +} + +static gboolean +handle_reload_config (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation) +{ + _g_freedesktop_dbus_complete_reload_config (object, invocation); + return TRUE; +} + +static gboolean +handle_update_activation_environment (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + GVariant *arg_environment) +{ + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "UpdateActivationEnvironment not implemented"); + return TRUE; +} + +static gboolean +handle_remove_match (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_rule) +{ + Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client"); + Match *match, *other_match; + GList *l; + + match = match_new (arg_rule); + + if (match == NULL) + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_INVALID, + "Invalid rule: %s", arg_rule); + else + { + for (l = client->matches; l != NULL; l = l->next) + { + other_match = l->data; + if (match_equal (match, other_match)) + { + match_free (other_match); + client->matches = g_list_delete_link (client->matches, l); + break; + } + } + + if (l == NULL) + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_NOT_FOUND, + "The given match rule wasn't found and can't be removed"); + else + _g_freedesktop_dbus_complete_remove_match (object, invocation); + } + if (match) + match_free (match); + + return TRUE; +} + +static gboolean +handle_request_name (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name, + guint flags) +{ + Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client"); + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + Name *name; + NameOwner *owner; + guint32 result; + + if (!g_dbus_is_name (arg_name)) + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "Requested bus name \"%s\" is not valid", arg_name); + return TRUE; + } + + if (*arg_name == ':') + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "Cannot acquire a service starting with ':' such as \"%s\"", arg_name); + return TRUE; + } + + if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0) + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "Cannot acquire a service named " DBUS_SERVICE_NAME ", because that is reserved"); + return TRUE; + } + + name = name_ensure (daemon, arg_name); + if (name->owner == NULL) + { + owner = name_owner_new (client, flags); + name_replace_owner (name, owner); + + result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; + } + else if (name->owner && name->owner->client == client) + { + name->owner->flags = flags; + result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER; + } + else if ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) && + (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || + !(name->owner->flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT))) + { + /* Unqueue if queued */ + name_unqueue_owner (name, client); + result = DBUS_REQUEST_NAME_REPLY_EXISTS; + } + else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) && + (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || + !(name->owner->flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT))) + { + /* Queue the connection */ + owner = name_owner_new (client, flags); + name_queue_owner (name, owner); + result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE; + } + else + { + /* Replace the current owner */ + + owner = name_owner_new (client, flags); + name_replace_owner (name, owner); + + result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; + } + + name_unref (name); + + _g_freedesktop_dbus_complete_request_name (object, invocation, result); + return TRUE; +} + +static gboolean +handle_start_service_by_name (_GFreedesktopDBus *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name, + guint arg_flags) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + Name *name; + + name = name_lookup (daemon, arg_name); + if (name) + _g_freedesktop_dbus_complete_start_service_by_name (object, invocation, + DBUS_START_REPLY_ALREADY_RUNNING); + else + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN, + "No support for activation for name: %s", arg_name); + + return TRUE; +} + +G_GNUC_PRINTF(5, 6) +static void +return_error (Client *client, GDBusMessage *message, + GQuark domain, + gint code, + const gchar *format, + ...) +{ + GDBusMessage *reply; + va_list var_args; + char *error_message; + GError *error; + gchar *dbus_error_name; + + va_start (var_args, format); + error_message = g_strdup_vprintf (format, var_args); + va_end (var_args); + + error = g_error_new_literal (domain, code, ""); + dbus_error_name = g_dbus_error_encode_gerror (error); + + reply = g_dbus_message_new_method_error_literal (message, + dbus_error_name, + error_message); + + g_error_free (error); + g_free (dbus_error_name); + g_free (error_message); + + if (!g_dbus_connection_send_message (client->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL)) + g_warning ("Error sending reply"); + g_object_unref (reply); +} + +static GDBusMessage * +route_message (Client *source_client, GDBusMessage *message) +{ + const char *dest; + Client *dest_client; + GDBusDaemon *daemon; + + daemon = source_client->daemon; + + dest_client = NULL; + dest = g_dbus_message_get_destination (message); + if (dest != NULL && strcmp (dest, DBUS_SERVICE_NAME) != 0) + { + dest_client = g_hash_table_lookup (daemon->clients, dest); + + if (dest_client == NULL) + { + Name *name; + name = name_lookup (daemon, dest); + if (name && name->owner) + dest_client = name->owner->client; + } + + if (dest_client == NULL) + { + if (g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL) + return_error (source_client, message, + G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN, + "The name %s is unknown", dest); + } + else + { + GError *error = NULL; + + if (!g_dbus_connection_send_message (dest_client->connection, message, G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, NULL, &error)) + { + g_warning ("Error forwarding message: %s", error->message); + g_error_free (error); + } + } + } + + broadcast_message (daemon, message, dest_client != NULL, TRUE, dest_client); + + /* Swallow messages not for the bus */ + if (dest == NULL || strcmp (dest, DBUS_SERVICE_NAME) != 0) + { + g_object_unref (message); + message = NULL; + } + + return message; +} + +static GDBusMessage * +copy_if_locked (GDBusMessage *message) +{ + if (g_dbus_message_get_locked (message)) + { + GDBusMessage *copy = g_dbus_message_copy (message, NULL); + g_object_unref (message); + message = copy; + } + return message; +} + +static GDBusMessage * +filter_function (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data) +{ + Client *client = user_data; + + if (0) + { + const char *types[] = {"invalid", "method_call", "method_return", "error", "signal" }; + g_printerr ("%s%s %s %d(%d) sender: %s destination: %s %s %s.%s\n", + client->id, + incoming? "->" : "<-", + types[g_dbus_message_get_message_type (message)], + g_dbus_message_get_serial (message), + g_dbus_message_get_reply_serial (message), + g_dbus_message_get_sender (message), + g_dbus_message_get_destination (message), + g_dbus_message_get_path (message), + g_dbus_message_get_interface (message), + g_dbus_message_get_member (message)); + } + + if (incoming) + { + /* Ensure its not locked so we can set the sender */ + message = copy_if_locked (message); + if (message == NULL) + { + g_warning ("Failed to copy incoming message"); + return NULL; + } + g_dbus_message_set_sender (message, client->id); + + return route_message (client, message); + } + else + { + if (g_dbus_message_get_sender (message) == NULL || + g_dbus_message_get_destination (message) == NULL) + { + message = copy_if_locked (message); + if (message == NULL) + { + g_warning ("Failed to copy outgoing message"); + return NULL; + } + } + + if (g_dbus_message_get_sender (message) == NULL) + g_dbus_message_set_sender (message, DBUS_SERVICE_NAME); + if (g_dbus_message_get_destination (message) == NULL) + g_dbus_message_set_destination (message, client->id); + } + + return message; +} + +static gboolean +on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + GDBusDaemon *daemon = user_data; + + g_dbus_connection_set_exit_on_close (connection, FALSE); + + if (daemon->timeout) + { + g_source_remove (daemon->timeout); + daemon->timeout = 0; + } + + client_new (daemon, connection); + + return TRUE; +} + +static void +g_dbus_daemon_finalize (GObject *object) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + GList *clients, *l; + + if (daemon->timeout) + g_source_remove (daemon->timeout); + + clients = g_hash_table_get_values (daemon->clients); + for (l = clients; l != NULL; l = l->next) + client_free (l->data); + g_list_free (clients); + + g_assert (g_hash_table_size (daemon->clients) == 0); + g_assert (g_hash_table_size (daemon->names) == 0); + + g_hash_table_destroy (daemon->clients); + g_hash_table_destroy (daemon->names); + + g_object_unref (daemon->server); + + if (daemon->tmpdir) + { + g_rmdir (daemon->tmpdir); + g_free (daemon->tmpdir); + } + + g_free (daemon->guid); + g_free (daemon->address); + + G_OBJECT_CLASS (g_dbus_daemon_parent_class)->finalize (object); +} + +static void +g_dbus_daemon_init (GDBusDaemon *daemon) +{ + daemon->next_major_id = 1; + daemon->clients = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + daemon->names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + daemon->guid = g_dbus_generate_guid (); +} + +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (initable); + GDBusServerFlags flags; + + flags = G_DBUS_SERVER_FLAGS_NONE; + if (daemon->address == NULL) + { +#ifdef G_OS_UNIX + if (g_unix_socket_address_abstract_names_supported ()) + daemon->address = g_strdup ("unix:tmpdir=/tmp/gdbus-daemon"); + else + { + daemon->tmpdir = g_dir_make_tmp ("gdbus-daemon-XXXXXX", NULL); + daemon->address = g_strdup_printf ("unix:tmpdir=%s", daemon->tmpdir); + } + flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER; +#else + /* Don’t require authentication on Windows as that hasn’t been + * implemented yet. */ + daemon->address = g_strdup ("nonce-tcp:"); + flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; +#endif + } + + daemon->server = g_dbus_server_new_sync (daemon->address, + flags, + daemon->guid, + NULL, + cancellable, + error); + if (daemon->server == NULL) + return FALSE; + + + g_dbus_server_start (daemon->server); + + g_signal_connect (daemon->server, "new-connection", + G_CALLBACK (on_new_connection), + daemon); + + return TRUE; +} + +static void +g_dbus_daemon_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + + switch (prop_id) + { + case PROP_ADDRESS: + g_free (daemon->address); + daemon->address = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_dbus_daemon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusDaemon *daemon = G_DBUS_DAEMON (object); + + switch (prop_id) + { + case PROP_ADDRESS: + g_value_set_string (value, daemon->address); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_dbus_daemon_class_init (GDBusDaemonClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = g_dbus_daemon_finalize; + gobject_class->set_property = g_dbus_daemon_set_property; + gobject_class->get_property = g_dbus_daemon_get_property; + + g_dbus_daemon_signals[SIGNAL_IDLE_TIMEOUT] = + g_signal_new (I_("idle-timeout"), + G_TYPE_DBUS_DAEMON, + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + g_object_class_install_property (gobject_class, + PROP_ADDRESS, + g_param_spec_string ("address", + "Bus Address", + "The address the bus should use", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_dbus_daemon_iface_init (_GFreedesktopDBusIface *iface) +{ + iface->handle_add_match = handle_add_match; + iface->handle_get_connection_selinux_security_context = handle_get_connection_selinux_security_context; + iface->handle_get_connection_unix_process_id = handle_get_connection_unix_process_id; + iface->handle_get_connection_unix_user = handle_get_connection_unix_user; + iface->handle_get_id = handle_get_id; + iface->handle_get_name_owner = handle_get_name_owner; + iface->handle_hello = handle_hello; + iface->handle_list_activatable_names = handle_list_activatable_names; + iface->handle_list_names = handle_list_names; + iface->handle_list_queued_owners = handle_list_queued_owners; + iface->handle_name_has_owner = handle_name_has_owner; + iface->handle_release_name = handle_release_name; + iface->handle_reload_config = handle_reload_config; + iface->handle_update_activation_environment = handle_update_activation_environment; + iface->handle_remove_match = handle_remove_match; + iface->handle_request_name = handle_request_name; + iface->handle_start_service_by_name = handle_start_service_by_name; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = initable_init; +} + +GDBusDaemon * +_g_dbus_daemon_new (const char *address, + GCancellable *cancellable, + GError **error) +{ + return g_initable_new (G_TYPE_DBUS_DAEMON, + cancellable, + error, + "address", address, + NULL); +} + +const char * +_g_dbus_daemon_get_address (GDBusDaemon *daemon) +{ + return g_dbus_server_get_client_address (daemon->server); +} diff --git a/gio/gdbusdaemon.h b/gio/gdbusdaemon.h new file mode 100644 index 0000000..a39b963 --- /dev/null +++ b/gio/gdbusdaemon.h @@ -0,0 +1,21 @@ +#include + +#define G_TYPE_DBUS_DAEMON (_g_dbus_daemon_get_type ()) +#define G_DBUS_DAEMON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_DAEMON, GDBusDaemon)) +#define G_DBUS_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_DBUS_DAEMON, GDBusDaemonClass)) +#define G_DBUS_DAEMON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_DAEMON, GDBusDaemonClass)) +#define G_IS_DBUS_DAEMON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_DAEMON)) +#define G_IS_DBUS_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_DAEMON)) + +typedef struct _GDBusDaemon GDBusDaemon; +typedef struct _GDBusDaemonClass GDBusDaemonClass; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusDaemon, g_object_unref) + +GType _g_dbus_daemon_get_type (void) G_GNUC_CONST; + +GDBusDaemon *_g_dbus_daemon_new (const char *address, + GCancellable *cancellable, + GError **error); + +const char *_g_dbus_daemon_get_address (GDBusDaemon *daemon); diff --git a/gio/gdbuserror.c b/gio/gdbuserror.c new file mode 100644 index 0000000..4cc542c --- /dev/null +++ b/gio/gdbuserror.c @@ -0,0 +1,895 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include + +#include "gdbuserror.h" +#include "gioenums.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include "gdbusprivate.h" + +#include "glibintl.h" + +/** + * SECTION:gdbuserror + * @title: GDBusError + * @short_description: Mapping D-Bus errors to and from GError + * @include: gio/gio.h + * + * All facilities that return errors from remote methods (such as + * g_dbus_connection_call_sync()) use #GError to represent both D-Bus + * errors (e.g. errors returned from the other peer) and locally + * in-process generated errors. + * + * To check if a returned #GError is an error from a remote peer, use + * g_dbus_error_is_remote_error(). To get the actual D-Bus error name, + * use g_dbus_error_get_remote_error(). Before presenting an error, + * always use g_dbus_error_strip_remote_error(). + * + * In addition, facilities used to return errors to a remote peer also + * use #GError. See g_dbus_method_invocation_return_error() for + * discussion about how the D-Bus error name is set. + * + * Applications can associate a #GError error domain with a set of D-Bus errors in order to + * automatically map from D-Bus errors to #GError and back. This + * is typically done in the function returning the #GQuark for the + * error domain: + * |[ + * // foo-bar-error.h: + * + * #define FOO_BAR_ERROR (foo_bar_error_quark ()) + * GQuark foo_bar_error_quark (void); + * + * typedef enum + * { + * FOO_BAR_ERROR_FAILED, + * FOO_BAR_ERROR_ANOTHER_ERROR, + * FOO_BAR_ERROR_SOME_THIRD_ERROR, + * FOO_BAR_N_ERRORS / *< skip >* / + * } FooBarError; + * + * // foo-bar-error.c: + * + * static const GDBusErrorEntry foo_bar_error_entries[] = + * { + * {FOO_BAR_ERROR_FAILED, "org.project.Foo.Bar.Error.Failed"}, + * {FOO_BAR_ERROR_ANOTHER_ERROR, "org.project.Foo.Bar.Error.AnotherError"}, + * {FOO_BAR_ERROR_SOME_THIRD_ERROR, "org.project.Foo.Bar.Error.SomeThirdError"}, + * }; + * + * // Ensure that every error code has an associated D-Bus error name + * G_STATIC_ASSERT (G_N_ELEMENTS (foo_bar_error_entries) == FOO_BAR_N_ERRORS); + * + * GQuark + * foo_bar_error_quark (void) + * { + * static gsize quark = 0; + * g_dbus_error_register_error_domain ("foo-bar-error-quark", + * &quark, + * foo_bar_error_entries, + * G_N_ELEMENTS (foo_bar_error_entries)); + * return (GQuark) quark; + * } + * ]| + * With this setup, a D-Bus peer can transparently pass e.g. %FOO_BAR_ERROR_ANOTHER_ERROR and + * other peers will see the D-Bus error name org.project.Foo.Bar.Error.AnotherError. + * + * If the other peer is using GDBus, and has registered the association with + * g_dbus_error_register_error_domain() in advance (e.g. by invoking the %FOO_BAR_ERROR quark + * generation itself in the previous example) the peer will see also %FOO_BAR_ERROR_ANOTHER_ERROR instead + * of %G_IO_ERROR_DBUS_ERROR. Note that GDBus clients can still recover + * org.project.Foo.Bar.Error.AnotherError using g_dbus_error_get_remote_error(). + * + * Note that the %G_DBUS_ERROR error domain is intended only + * for returning errors from a remote message bus process. Errors + * generated locally in-process by e.g. #GDBusConnection should use the + * %G_IO_ERROR domain. + */ + +static const GDBusErrorEntry g_dbus_error_entries[] = +{ + {G_DBUS_ERROR_FAILED, "org.freedesktop.DBus.Error.Failed"}, + {G_DBUS_ERROR_NO_MEMORY, "org.freedesktop.DBus.Error.NoMemory"}, + {G_DBUS_ERROR_SERVICE_UNKNOWN, "org.freedesktop.DBus.Error.ServiceUnknown"}, + {G_DBUS_ERROR_NAME_HAS_NO_OWNER, "org.freedesktop.DBus.Error.NameHasNoOwner"}, + {G_DBUS_ERROR_NO_REPLY, "org.freedesktop.DBus.Error.NoReply"}, + {G_DBUS_ERROR_IO_ERROR, "org.freedesktop.DBus.Error.IOError"}, + {G_DBUS_ERROR_BAD_ADDRESS, "org.freedesktop.DBus.Error.BadAddress"}, + {G_DBUS_ERROR_NOT_SUPPORTED, "org.freedesktop.DBus.Error.NotSupported"}, + {G_DBUS_ERROR_LIMITS_EXCEEDED, "org.freedesktop.DBus.Error.LimitsExceeded"}, + {G_DBUS_ERROR_ACCESS_DENIED, "org.freedesktop.DBus.Error.AccessDenied"}, + {G_DBUS_ERROR_AUTH_FAILED, "org.freedesktop.DBus.Error.AuthFailed"}, + {G_DBUS_ERROR_NO_SERVER, "org.freedesktop.DBus.Error.NoServer"}, + {G_DBUS_ERROR_TIMEOUT, "org.freedesktop.DBus.Error.Timeout"}, + {G_DBUS_ERROR_NO_NETWORK, "org.freedesktop.DBus.Error.NoNetwork"}, + {G_DBUS_ERROR_ADDRESS_IN_USE, "org.freedesktop.DBus.Error.AddressInUse"}, + {G_DBUS_ERROR_DISCONNECTED, "org.freedesktop.DBus.Error.Disconnected"}, + {G_DBUS_ERROR_INVALID_ARGS, "org.freedesktop.DBus.Error.InvalidArgs"}, + {G_DBUS_ERROR_FILE_NOT_FOUND, "org.freedesktop.DBus.Error.FileNotFound"}, + {G_DBUS_ERROR_FILE_EXISTS, "org.freedesktop.DBus.Error.FileExists"}, + {G_DBUS_ERROR_UNKNOWN_METHOD, "org.freedesktop.DBus.Error.UnknownMethod"}, + {G_DBUS_ERROR_TIMED_OUT, "org.freedesktop.DBus.Error.TimedOut"}, + {G_DBUS_ERROR_MATCH_RULE_NOT_FOUND, "org.freedesktop.DBus.Error.MatchRuleNotFound"}, + {G_DBUS_ERROR_MATCH_RULE_INVALID, "org.freedesktop.DBus.Error.MatchRuleInvalid"}, + {G_DBUS_ERROR_SPAWN_EXEC_FAILED, "org.freedesktop.DBus.Error.Spawn.ExecFailed"}, + {G_DBUS_ERROR_SPAWN_FORK_FAILED, "org.freedesktop.DBus.Error.Spawn.ForkFailed"}, + {G_DBUS_ERROR_SPAWN_CHILD_EXITED, "org.freedesktop.DBus.Error.Spawn.ChildExited"}, + {G_DBUS_ERROR_SPAWN_CHILD_SIGNALED, "org.freedesktop.DBus.Error.Spawn.ChildSignaled"}, + {G_DBUS_ERROR_SPAWN_FAILED, "org.freedesktop.DBus.Error.Spawn.Failed"}, + {G_DBUS_ERROR_SPAWN_SETUP_FAILED, "org.freedesktop.DBus.Error.Spawn.FailedToSetup"}, + {G_DBUS_ERROR_SPAWN_CONFIG_INVALID, "org.freedesktop.DBus.Error.Spawn.ConfigInvalid"}, + {G_DBUS_ERROR_SPAWN_SERVICE_INVALID, "org.freedesktop.DBus.Error.Spawn.ServiceNotValid"}, + {G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND, "org.freedesktop.DBus.Error.Spawn.ServiceNotFound"}, + {G_DBUS_ERROR_SPAWN_PERMISSIONS_INVALID, "org.freedesktop.DBus.Error.Spawn.PermissionsInvalid"}, + {G_DBUS_ERROR_SPAWN_FILE_INVALID, "org.freedesktop.DBus.Error.Spawn.FileInvalid"}, + {G_DBUS_ERROR_SPAWN_NO_MEMORY, "org.freedesktop.DBus.Error.Spawn.NoMemory"}, + {G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, "org.freedesktop.DBus.Error.UnixProcessIdUnknown"}, + {G_DBUS_ERROR_INVALID_SIGNATURE, "org.freedesktop.DBus.Error.InvalidSignature"}, + {G_DBUS_ERROR_INVALID_FILE_CONTENT, "org.freedesktop.DBus.Error.InvalidFileContent"}, + {G_DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"}, + {G_DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN, "org.freedesktop.DBus.Error.AdtAuditDataUnknown"}, + {G_DBUS_ERROR_OBJECT_PATH_IN_USE, "org.freedesktop.DBus.Error.ObjectPathInUse"}, + {G_DBUS_ERROR_UNKNOWN_OBJECT, "org.freedesktop.DBus.Error.UnknownObject"}, + {G_DBUS_ERROR_UNKNOWN_INTERFACE, "org.freedesktop.DBus.Error.UnknownInterface"}, + {G_DBUS_ERROR_UNKNOWN_PROPERTY, "org.freedesktop.DBus.Error.UnknownProperty"}, + {G_DBUS_ERROR_PROPERTY_READ_ONLY, "org.freedesktop.DBus.Error.PropertyReadOnly"}, +}; + +GQuark +g_dbus_error_quark (void) +{ + G_STATIC_ASSERT (G_N_ELEMENTS (g_dbus_error_entries) - 1 == G_DBUS_ERROR_PROPERTY_READ_ONLY); + static gsize quark = 0; + g_dbus_error_register_error_domain ("g-dbus-error-quark", + &quark, + g_dbus_error_entries, + G_N_ELEMENTS (g_dbus_error_entries)); + return (GQuark) quark; +} + +/** + * g_dbus_error_register_error_domain: + * @error_domain_quark_name: The error domain name. + * @quark_volatile: A pointer where to store the #GQuark. + * @entries: (array length=num_entries): A pointer to @num_entries #GDBusErrorEntry struct items. + * @num_entries: Number of items to register. + * + * Helper function for associating a #GError error domain with D-Bus error names. + * + * While @quark_volatile has a `volatile` qualifier, this is a historical + * artifact and the argument passed to it should not be `volatile`. + * + * Since: 2.26 + */ +void +g_dbus_error_register_error_domain (const gchar *error_domain_quark_name, + volatile gsize *quark_volatile, + const GDBusErrorEntry *entries, + guint num_entries) +{ + gsize *quark; + + g_return_if_fail (error_domain_quark_name != NULL); + g_return_if_fail (quark_volatile != NULL); + g_return_if_fail (entries != NULL); + g_return_if_fail (num_entries > 0); + + /* Drop the volatile qualifier, which should never have been on the argument + * in the first place. */ + quark = (gsize *) quark_volatile; + + if (g_once_init_enter (quark)) + { + guint n; + GQuark new_quark; + + new_quark = g_quark_from_static_string (error_domain_quark_name); + + for (n = 0; n < num_entries; n++) + { + g_warn_if_fail (g_dbus_error_register_error (new_quark, + entries[n].error_code, + entries[n].dbus_error_name)); + } + g_once_init_leave (quark, new_quark); + } +} + +static gboolean +_g_dbus_error_decode_gerror (const gchar *dbus_name, + GQuark *out_error_domain, + gint *out_error_code) +{ + gboolean ret; + guint n; + GString *s; + gchar *domain_quark_string; + + ret = FALSE; + s = NULL; + + if (g_str_has_prefix (dbus_name, "org.gtk.GDBus.UnmappedGError.Quark._")) + { + s = g_string_new (NULL); + + for (n = sizeof "org.gtk.GDBus.UnmappedGError.Quark._" - 1; + dbus_name[n] != '.' && dbus_name[n] != '\0'; + n++) + { + if (g_ascii_isalnum (dbus_name[n])) + { + g_string_append_c (s, dbus_name[n]); + } + else if (dbus_name[n] == '_') + { + guint nibble_top; + guint nibble_bottom; + + n++; + + nibble_top = dbus_name[n]; + if (nibble_top >= '0' && nibble_top <= '9') + nibble_top -= '0'; + else if (nibble_top >= 'a' && nibble_top <= 'f') + nibble_top -= ('a' - 10); + else + goto not_mapped; + + n++; + + nibble_bottom = dbus_name[n]; + if (nibble_bottom >= '0' && nibble_bottom <= '9') + nibble_bottom -= '0'; + else if (nibble_bottom >= 'a' && nibble_bottom <= 'f') + nibble_bottom -= ('a' - 10); + else + goto not_mapped; + + g_string_append_c (s, (nibble_top<<4) | nibble_bottom); + } + else + { + goto not_mapped; + } + } + + if (!g_str_has_prefix (dbus_name + n, ".Code")) + goto not_mapped; + + domain_quark_string = g_string_free (s, FALSE); + s = NULL; + + if (out_error_domain != NULL) + *out_error_domain = g_quark_from_string (domain_quark_string); + g_free (domain_quark_string); + + if (out_error_code != NULL) + *out_error_code = atoi (dbus_name + n + sizeof ".Code" - 1); + + ret = TRUE; + } + + not_mapped: + + if (s != NULL) + g_string_free (s, TRUE); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GQuark error_domain; + gint error_code; +} QuarkCodePair; + +static guint +quark_code_pair_hash_func (const QuarkCodePair *pair) +{ + gint val; + val = pair->error_domain + pair->error_code; + return g_int_hash (&val); +} + +static gboolean +quark_code_pair_equal_func (const QuarkCodePair *a, + const QuarkCodePair *b) +{ + return (a->error_domain == b->error_domain) && (a->error_code == b->error_code); +} + +typedef struct +{ + QuarkCodePair pair; + gchar *dbus_error_name; +} RegisteredError; + +static void +registered_error_free (RegisteredError *re) +{ + g_free (re->dbus_error_name); + g_free (re); +} + +G_LOCK_DEFINE_STATIC (error_lock); + +/* maps from QuarkCodePair* -> RegisteredError* */ +static GHashTable *quark_code_pair_to_re = NULL; + +/* maps from gchar* -> RegisteredError* */ +static GHashTable *dbus_error_name_to_re = NULL; + +/** + * g_dbus_error_register_error: + * @error_domain: A #GQuark for an error domain. + * @error_code: An error code. + * @dbus_error_name: A D-Bus error name. + * + * Creates an association to map between @dbus_error_name and + * #GErrors specified by @error_domain and @error_code. + * + * This is typically done in the routine that returns the #GQuark for + * an error domain. + * + * Returns: %TRUE if the association was created, %FALSE if it already + * exists. + * + * Since: 2.26 + */ +gboolean +g_dbus_error_register_error (GQuark error_domain, + gint error_code, + const gchar *dbus_error_name) +{ + gboolean ret; + QuarkCodePair pair; + RegisteredError *re; + + g_return_val_if_fail (dbus_error_name != NULL, FALSE); + + ret = FALSE; + + G_LOCK (error_lock); + + if (quark_code_pair_to_re == NULL) + { + g_assert (dbus_error_name_to_re == NULL); /* check invariant */ + quark_code_pair_to_re = g_hash_table_new ((GHashFunc) quark_code_pair_hash_func, + (GEqualFunc) quark_code_pair_equal_func); + dbus_error_name_to_re = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) registered_error_free); + } + + if (g_hash_table_lookup (dbus_error_name_to_re, dbus_error_name) != NULL) + goto out; + + pair.error_domain = error_domain; + pair.error_code = error_code; + + if (g_hash_table_lookup (quark_code_pair_to_re, &pair) != NULL) + goto out; + + re = g_new0 (RegisteredError, 1); + re->pair = pair; + re->dbus_error_name = g_strdup (dbus_error_name); + + g_hash_table_insert (quark_code_pair_to_re, &(re->pair), re); + g_hash_table_insert (dbus_error_name_to_re, re->dbus_error_name, re); + + ret = TRUE; + + out: + G_UNLOCK (error_lock); + return ret; +} + +/** + * g_dbus_error_unregister_error: + * @error_domain: A #GQuark for an error domain. + * @error_code: An error code. + * @dbus_error_name: A D-Bus error name. + * + * Destroys an association previously set up with g_dbus_error_register_error(). + * + * Returns: %TRUE if the association was destroyed, %FALSE if it wasn't found. + * + * Since: 2.26 + */ +gboolean +g_dbus_error_unregister_error (GQuark error_domain, + gint error_code, + const gchar *dbus_error_name) +{ + gboolean ret; + RegisteredError *re; + guint hash_size; + + g_return_val_if_fail (dbus_error_name != NULL, FALSE); + + ret = FALSE; + + G_LOCK (error_lock); + + if (dbus_error_name_to_re == NULL) + { + g_assert (quark_code_pair_to_re == NULL); /* check invariant */ + goto out; + } + + re = g_hash_table_lookup (dbus_error_name_to_re, dbus_error_name); + if (re == NULL) + { + QuarkCodePair pair; + pair.error_domain = error_domain; + pair.error_code = error_code; + g_warn_if_fail (g_hash_table_lookup (quark_code_pair_to_re, &pair) == NULL); /* check invariant */ + goto out; + } + + ret = TRUE; + + g_warn_if_fail (g_hash_table_lookup (quark_code_pair_to_re, &(re->pair)) == re); /* check invariant */ + + g_warn_if_fail (g_hash_table_remove (quark_code_pair_to_re, &(re->pair))); + g_warn_if_fail (g_hash_table_remove (dbus_error_name_to_re, re->dbus_error_name)); + + /* destroy hashes if empty */ + hash_size = g_hash_table_size (dbus_error_name_to_re); + if (hash_size == 0) + { + g_warn_if_fail (g_hash_table_size (quark_code_pair_to_re) == 0); /* check invariant */ + + g_hash_table_unref (dbus_error_name_to_re); + dbus_error_name_to_re = NULL; + g_hash_table_unref (quark_code_pair_to_re); + quark_code_pair_to_re = NULL; + } + else + { + g_warn_if_fail (g_hash_table_size (quark_code_pair_to_re) == hash_size); /* check invariant */ + } + + out: + G_UNLOCK (error_lock); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_error_is_remote_error: + * @error: A #GError. + * + * Checks if @error represents an error received via D-Bus from a remote peer. If so, + * use g_dbus_error_get_remote_error() to get the name of the error. + * + * Returns: %TRUE if @error represents an error from a remote peer, + * %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_error_is_remote_error (const GError *error) +{ + g_return_val_if_fail (error != NULL, FALSE); + return g_str_has_prefix (error->message, "GDBus.Error:"); +} + + +/** + * g_dbus_error_get_remote_error: + * @error: a #GError + * + * Gets the D-Bus error name used for @error, if any. + * + * This function is guaranteed to return a D-Bus error name for all + * #GErrors returned from functions handling remote method calls + * (e.g. g_dbus_connection_call_finish()) unless + * g_dbus_error_strip_remote_error() has been used on @error. + * + * Returns: (nullable) (transfer full): an allocated string or %NULL if the + * D-Bus error name could not be found. Free with g_free(). + * + * Since: 2.26 + */ +gchar * +g_dbus_error_get_remote_error (const GError *error) +{ + RegisteredError *re; + gchar *ret; + + g_return_val_if_fail (error != NULL, NULL); + + /* Ensure that e.g. G_DBUS_ERROR is registered using g_dbus_error_register_error() */ + _g_dbus_initialize (); + + ret = NULL; + + G_LOCK (error_lock); + + re = NULL; + if (quark_code_pair_to_re != NULL) + { + QuarkCodePair pair; + pair.error_domain = error->domain; + pair.error_code = error->code; + g_assert (dbus_error_name_to_re != NULL); /* check invariant */ + re = g_hash_table_lookup (quark_code_pair_to_re, &pair); + } + + if (re != NULL) + { + ret = g_strdup (re->dbus_error_name); + } + else + { + if (g_str_has_prefix (error->message, "GDBus.Error:")) + { + const gchar *begin; + const gchar *end; + begin = error->message + sizeof ("GDBus.Error:") -1; + end = strstr (begin, ":"); + if (end != NULL && end[1] == ' ') + { + ret = g_strndup (begin, end - begin); + } + } + } + + G_UNLOCK (error_lock); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_error_new_for_dbus_error: + * @dbus_error_name: D-Bus error name. + * @dbus_error_message: D-Bus error message. + * + * Creates a #GError based on the contents of @dbus_error_name and + * @dbus_error_message. + * + * Errors registered with g_dbus_error_register_error() will be looked + * up using @dbus_error_name and if a match is found, the error domain + * and code is used. Applications can use g_dbus_error_get_remote_error() + * to recover @dbus_error_name. + * + * If a match against a registered error is not found and the D-Bus + * error name is in a form as returned by g_dbus_error_encode_gerror() + * the error domain and code encoded in the name is used to + * create the #GError. Also, @dbus_error_name is added to the error message + * such that it can be recovered with g_dbus_error_get_remote_error(). + * + * Otherwise, a #GError with the error code %G_IO_ERROR_DBUS_ERROR + * in the %G_IO_ERROR error domain is returned. Also, @dbus_error_name is + * added to the error message such that it can be recovered with + * g_dbus_error_get_remote_error(). + * + * In all three cases, @dbus_error_name can always be recovered from the + * returned #GError using the g_dbus_error_get_remote_error() function + * (unless g_dbus_error_strip_remote_error() hasn't been used on the returned error). + * + * This function is typically only used in object mappings to prepare + * #GError instances for applications. Regular applications should not use + * it. + * + * Returns: (transfer full): An allocated #GError. Free with g_error_free(). + * + * Since: 2.26 + */ +GError * +g_dbus_error_new_for_dbus_error (const gchar *dbus_error_name, + const gchar *dbus_error_message) +{ + GError *error; + RegisteredError *re; + + g_return_val_if_fail (dbus_error_name != NULL, NULL); + g_return_val_if_fail (dbus_error_message != NULL, NULL); + + /* Ensure that e.g. G_DBUS_ERROR is registered using g_dbus_error_register_error() */ + _g_dbus_initialize (); + + G_LOCK (error_lock); + + re = NULL; + if (dbus_error_name_to_re != NULL) + { + g_assert (quark_code_pair_to_re != NULL); /* check invariant */ + re = g_hash_table_lookup (dbus_error_name_to_re, dbus_error_name); + } + + if (re != NULL) + { + error = g_error_new (re->pair.error_domain, + re->pair.error_code, + "GDBus.Error:%s: %s", + dbus_error_name, + dbus_error_message); + } + else + { + GQuark error_domain = 0; + gint error_code = 0; + + if (_g_dbus_error_decode_gerror (dbus_error_name, + &error_domain, + &error_code)) + { + error = g_error_new (error_domain, + error_code, + "GDBus.Error:%s: %s", + dbus_error_name, + dbus_error_message); + } + else + { + error = g_error_new (G_IO_ERROR, + G_IO_ERROR_DBUS_ERROR, + "GDBus.Error:%s: %s", + dbus_error_name, + dbus_error_message); + } + } + + G_UNLOCK (error_lock); + return error; +} + +/** + * g_dbus_error_set_dbus_error: + * @error: A pointer to a #GError or %NULL. + * @dbus_error_name: D-Bus error name. + * @dbus_error_message: D-Bus error message. + * @format: (nullable): printf()-style format to prepend to @dbus_error_message or %NULL. + * @...: Arguments for @format. + * + * Does nothing if @error is %NULL. Otherwise sets *@error to + * a new #GError created with g_dbus_error_new_for_dbus_error() + * with @dbus_error_message prepend with @format (unless %NULL). + * + * Since: 2.26 + */ +void +g_dbus_error_set_dbus_error (GError **error, + const gchar *dbus_error_name, + const gchar *dbus_error_message, + const gchar *format, + ...) +{ + g_return_if_fail (error == NULL || *error == NULL); + g_return_if_fail (dbus_error_name != NULL); + g_return_if_fail (dbus_error_message != NULL); + + if (error == NULL) + return; + + if (format == NULL) + { + *error = g_dbus_error_new_for_dbus_error (dbus_error_name, dbus_error_message); + } + else + { + va_list var_args; + va_start (var_args, format); + g_dbus_error_set_dbus_error_valist (error, + dbus_error_name, + dbus_error_message, + format, + var_args); + va_end (var_args); + } +} + +/** + * g_dbus_error_set_dbus_error_valist: + * @error: A pointer to a #GError or %NULL. + * @dbus_error_name: D-Bus error name. + * @dbus_error_message: D-Bus error message. + * @format: (nullable): printf()-style format to prepend to @dbus_error_message or %NULL. + * @var_args: Arguments for @format. + * + * Like g_dbus_error_set_dbus_error() but intended for language bindings. + * + * Since: 2.26 + */ +void +g_dbus_error_set_dbus_error_valist (GError **error, + const gchar *dbus_error_name, + const gchar *dbus_error_message, + const gchar *format, + va_list var_args) +{ + g_return_if_fail (error == NULL || *error == NULL); + g_return_if_fail (dbus_error_name != NULL); + g_return_if_fail (dbus_error_message != NULL); + + if (error == NULL) + return; + + if (format != NULL) + { + gchar *message; + gchar *s; + message = g_strdup_vprintf (format, var_args); + s = g_strdup_printf ("%s: %s", message, dbus_error_message); + *error = g_dbus_error_new_for_dbus_error (dbus_error_name, s); + g_free (s); + g_free (message); + } + else + { + *error = g_dbus_error_new_for_dbus_error (dbus_error_name, dbus_error_message); + } +} + +/** + * g_dbus_error_strip_remote_error: + * @error: A #GError. + * + * Looks for extra information in the error message used to recover + * the D-Bus error name and strips it if found. If stripped, the + * message field in @error will correspond exactly to what was + * received on the wire. + * + * This is typically used when presenting errors to the end user. + * + * Returns: %TRUE if information was stripped, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_error_strip_remote_error (GError *error) +{ + gboolean ret; + + g_return_val_if_fail (error != NULL, FALSE); + + ret = FALSE; + + if (g_str_has_prefix (error->message, "GDBus.Error:")) + { + const gchar *begin; + const gchar *end; + gchar *new_message; + + begin = error->message + sizeof ("GDBus.Error:") -1; + end = strstr (begin, ":"); + if (end != NULL && end[1] == ' ') + { + new_message = g_strdup (end + 2); + g_free (error->message); + error->message = new_message; + ret = TRUE; + } + } + + return ret; +} + +/** + * g_dbus_error_encode_gerror: + * @error: A #GError. + * + * Creates a D-Bus error name to use for @error. If @error matches + * a registered error (cf. g_dbus_error_register_error()), the corresponding + * D-Bus error name will be returned. + * + * Otherwise the a name of the form + * `org.gtk.GDBus.UnmappedGError.Quark._ESCAPED_QUARK_NAME.Code_ERROR_CODE` + * will be used. This allows other GDBus applications to map the error + * on the wire back to a #GError using g_dbus_error_new_for_dbus_error(). + * + * This function is typically only used in object mappings to put a + * #GError on the wire. Regular applications should not use it. + * + * Returns: (transfer full) (not nullable): A D-Bus error name (never %NULL). + * Free with g_free(). + * + * Since: 2.26 + */ +gchar * +g_dbus_error_encode_gerror (const GError *error) +{ + RegisteredError *re; + gchar *error_name; + + g_return_val_if_fail (error != NULL, NULL); + + /* Ensure that e.g. G_DBUS_ERROR is registered using g_dbus_error_register_error() */ + _g_dbus_initialize (); + + error_name = NULL; + + G_LOCK (error_lock); + re = NULL; + if (quark_code_pair_to_re != NULL) + { + QuarkCodePair pair; + pair.error_domain = error->domain; + pair.error_code = error->code; + g_assert (dbus_error_name_to_re != NULL); /* check invariant */ + re = g_hash_table_lookup (quark_code_pair_to_re, &pair); + } + if (re != NULL) + { + error_name = g_strdup (re->dbus_error_name); + G_UNLOCK (error_lock); + } + else + { + const gchar *domain_as_string; + GString *s; + guint n; + + G_UNLOCK (error_lock); + + /* We can't make a lot of assumptions about what domain_as_string + * looks like and D-Bus is extremely picky about error names so + * hex-encode it for transport across the wire. + */ + domain_as_string = g_quark_to_string (error->domain); + + /* 0 is not a domain; neither are non-quark integers */ + g_return_val_if_fail (domain_as_string != NULL, NULL); + + s = g_string_new ("org.gtk.GDBus.UnmappedGError.Quark._"); + for (n = 0; domain_as_string[n] != 0; n++) + { + gint c = domain_as_string[n]; + if (g_ascii_isalnum (c)) + { + g_string_append_c (s, c); + } + else + { + guint nibble_top; + guint nibble_bottom; + g_string_append_c (s, '_'); + nibble_top = ((int) domain_as_string[n]) >> 4; + nibble_bottom = ((int) domain_as_string[n]) & 0x0f; + if (nibble_top < 10) + nibble_top += '0'; + else + nibble_top += 'a' - 10; + if (nibble_bottom < 10) + nibble_bottom += '0'; + else + nibble_bottom += 'a' - 10; + g_string_append_c (s, nibble_top); + g_string_append_c (s, nibble_bottom); + } + } + g_string_append_printf (s, ".Code%d", error->code); + error_name = g_string_free (s, FALSE); + } + + return error_name; +} diff --git a/gio/gdbuserror.h b/gio/gdbuserror.h new file mode 100644 index 0000000..35a156c --- /dev/null +++ b/gio/gdbuserror.h @@ -0,0 +1,109 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_ERROR_H__ +#define __G_DBUS_ERROR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_DBUS_ERROR: + * + * Error domain for errors generated by a remote message bus. Errors + * in this domain will be from the #GDBusError enumeration. See + * #GError for more information on error domains. + * + * Note that this error domain is intended only for + * returning errors from a remote message bus process. Errors + * generated locally in-process by e.g. #GDBusConnection should use the + * %G_IO_ERROR domain. + * + * Since: 2.26 + */ +#define G_DBUS_ERROR g_dbus_error_quark() + +GLIB_AVAILABLE_IN_ALL +GQuark g_dbus_error_quark (void); + +/* Used by applications to check, get and strip the D-Bus error name */ +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_error_is_remote_error (const GError *error); +GLIB_AVAILABLE_IN_ALL +gchar *g_dbus_error_get_remote_error (const GError *error); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_error_strip_remote_error (GError *error); + +/** + * GDBusErrorEntry: + * @error_code: An error code. + * @dbus_error_name: The D-Bus error name to associate with @error_code. + * + * Struct used in g_dbus_error_register_error_domain(). + * + * Since: 2.26 + */ +struct _GDBusErrorEntry +{ + gint error_code; + const gchar *dbus_error_name; +}; + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_error_register_error (GQuark error_domain, + gint error_code, + const gchar *dbus_error_name); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_error_unregister_error (GQuark error_domain, + gint error_code, + const gchar *dbus_error_name); +GLIB_AVAILABLE_IN_ALL +void g_dbus_error_register_error_domain (const gchar *error_domain_quark_name, + volatile gsize *quark_volatile, + const GDBusErrorEntry *entries, + guint num_entries); + +/* Only used by object mappings to map back and forth to GError */ +GLIB_AVAILABLE_IN_ALL +GError *g_dbus_error_new_for_dbus_error (const gchar *dbus_error_name, + const gchar *dbus_error_message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_error_set_dbus_error (GError **error, + const gchar *dbus_error_name, + const gchar *dbus_error_message, + const gchar *format, + ...) G_GNUC_PRINTF(4, 5); +GLIB_AVAILABLE_IN_ALL +void g_dbus_error_set_dbus_error_valist (GError **error, + const gchar *dbus_error_name, + const gchar *dbus_error_message, + const gchar *format, + va_list var_args) G_GNUC_PRINTF(4, 0); +GLIB_AVAILABLE_IN_ALL +gchar *g_dbus_error_encode_gerror (const GError *error); + +G_END_DECLS + +#endif /* __G_DBUS_ERROR_H__ */ diff --git a/gio/gdbusinterface.c b/gio/gdbusinterface.c new file mode 100644 index 0000000..35fa8e4 --- /dev/null +++ b/gio/gdbusinterface.c @@ -0,0 +1,137 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusobject.h" +#include "gdbusinterface.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusinterface + * @short_description: Base type for D-Bus interfaces + * @include: gio/gio.h + * + * The #GDBusInterface type is the base type for D-Bus interfaces both + * on the service side (see #GDBusInterfaceSkeleton) and client side + * (see #GDBusProxy). + */ + +typedef GDBusInterfaceIface GDBusInterfaceInterface; +G_DEFINE_INTERFACE (GDBusInterface, g_dbus_interface, G_TYPE_OBJECT) + +static void +g_dbus_interface_default_init (GDBusInterfaceIface *iface) +{ +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_interface_get_info: + * @interface_: An exported D-Bus interface. + * + * Gets D-Bus introspection information for the D-Bus interface + * implemented by @interface_. + * + * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free. + * + * Since: 2.30 + */ +GDBusInterfaceInfo * +g_dbus_interface_get_info (GDBusInterface *interface_) +{ + g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface_), NULL); + return G_DBUS_INTERFACE_GET_IFACE (interface_)->get_info (interface_); +} + +/** + * g_dbus_interface_get_object: (skip) + * @interface_: An exported D-Bus interface + * + * Gets the #GDBusObject that @interface_ belongs to, if any. + * + * It is not safe to use the returned object if @interface_ or + * the returned object is being used from other threads. See + * g_dbus_interface_dup_object() for a thread-safe alternative. + * + * Returns: (nullable) (transfer none): A #GDBusObject or %NULL. The returned + * reference belongs to @interface_ and should not be freed. + * + * Since: 2.30 + */ +GDBusObject * +g_dbus_interface_get_object (GDBusInterface *interface_) +{ + g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface_), NULL); + return G_DBUS_INTERFACE_GET_IFACE (interface_)->get_object (interface_); +} + +/** + * g_dbus_interface_dup_object: (rename-to g_dbus_interface_get_object) + * @interface_: An exported D-Bus interface. + * + * Gets the #GDBusObject that @interface_ belongs to, if any. + * + * Returns: (nullable) (transfer full): A #GDBusObject or %NULL. The returned + * reference should be freed with g_object_unref(). + * + * Since: 2.32 + */ +GDBusObject * +g_dbus_interface_dup_object (GDBusInterface *interface_) +{ + GDBusObject *ret; + g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface_), NULL); + if (G_LIKELY (G_DBUS_INTERFACE_GET_IFACE (interface_)->dup_object != NULL)) + { + ret = G_DBUS_INTERFACE_GET_IFACE (interface_)->dup_object (interface_); + } + else + { + g_warning ("No dup_object() vfunc on type %s - using get_object() in a way that is not thread-safe.", + g_type_name_from_instance ((GTypeInstance *) interface_)); + ret = G_DBUS_INTERFACE_GET_IFACE (interface_)->get_object (interface_); + if (ret != NULL) + g_object_ref (ret); + } + return ret; +} + +/** + * g_dbus_interface_set_object: + * @interface_: An exported D-Bus interface. + * @object: (nullable): A #GDBusObject or %NULL. + * + * Sets the #GDBusObject for @interface_ to @object. + * + * Note that @interface_ will hold a weak reference to @object. + * + * Since: 2.30 + */ +void +g_dbus_interface_set_object (GDBusInterface *interface_, + GDBusObject *object) +{ + g_return_if_fail (G_IS_DBUS_INTERFACE (interface_)); + g_return_if_fail (object == NULL || G_IS_DBUS_OBJECT (object)); + G_DBUS_INTERFACE_GET_IFACE (interface_)->set_object (interface_, object); +} diff --git a/gio/gdbusinterface.h b/gio/gdbusinterface.h new file mode 100644 index 0000000..b2f3c44 --- /dev/null +++ b/gio/gdbusinterface.h @@ -0,0 +1,81 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_INTERFACE_H__ +#define __G_DBUS_INTERFACE_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_INTERFACE (g_dbus_interface_get_type()) +#define G_DBUS_INTERFACE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_INTERFACE, GDBusInterface)) +#define G_IS_DBUS_INTERFACE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_INTERFACE)) +#define G_DBUS_INTERFACE_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), G_TYPE_DBUS_INTERFACE, GDBusInterfaceIface)) + +/** + * GDBusInterface: + * + * Base type for D-Bus interfaces. + * + * Since: 2.30 + */ + +typedef struct _GDBusInterfaceIface GDBusInterfaceIface; + +/** + * GDBusInterfaceIface: + * @parent_iface: The parent interface. + * @get_info: Returns a #GDBusInterfaceInfo. See g_dbus_interface_get_info(). + * @get_object: Gets the enclosing #GDBusObject. See g_dbus_interface_get_object(). + * @set_object: Sets the enclosing #GDBusObject. See g_dbus_interface_set_object(). + * @dup_object: Gets a reference to the enclosing #GDBusObject. See g_dbus_interface_dup_object(). Added in 2.32. + * + * Base type for D-Bus interfaces. + * + * Since: 2.30 + */ +struct _GDBusInterfaceIface +{ + GTypeInterface parent_iface; + + /* Virtual Functions */ + GDBusInterfaceInfo *(*get_info) (GDBusInterface *interface_); + GDBusObject *(*get_object) (GDBusInterface *interface_); + void (*set_object) (GDBusInterface *interface_, + GDBusObject *object); + GDBusObject *(*dup_object) (GDBusInterface *interface_); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_interface_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDBusInterfaceInfo *g_dbus_interface_get_info (GDBusInterface *interface_); +GLIB_AVAILABLE_IN_ALL +GDBusObject *g_dbus_interface_get_object (GDBusInterface *interface_); +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_set_object (GDBusInterface *interface_, + GDBusObject *object); +GLIB_AVAILABLE_IN_2_32 +GDBusObject *g_dbus_interface_dup_object (GDBusInterface *interface_); + +G_END_DECLS + +#endif /* __G_DBUS_INTERFACE_H__ */ diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c new file mode 100644 index 0000000..878c145 --- /dev/null +++ b/gio/gdbusinterfaceskeleton.c @@ -0,0 +1,1014 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusinterface.h" +#include "gdbusinterfaceskeleton.h" +#include "gdbusobjectskeleton.h" +#include "gioenumtypes.h" +#include "gdbusprivate.h" +#include "gdbusmethodinvocation.h" +#include "gdbusconnection.h" +#include "gmarshal-internal.h" +#include "gtask.h" +#include "gioerror.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusinterfaceskeleton + * @short_description: Service-side D-Bus interface + * @include: gio/gio.h + * + * Abstract base class for D-Bus interfaces on the service side. + */ + +struct _GDBusInterfaceSkeletonPrivate +{ + GMutex lock; + + GDBusObject *object; + GDBusInterfaceSkeletonFlags flags; + + GSList *connections; /* List of ConnectionData */ + gchar *object_path; /* The object path for this skeleton */ + GDBusInterfaceVTable *hooked_vtable; +}; + +typedef struct +{ + GDBusConnection *connection; + guint registration_id; +} ConnectionData; + +enum +{ + G_AUTHORIZE_METHOD_SIGNAL, + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_G_FLAGS +}; + +static guint signals[LAST_SIGNAL] = {0}; + +static void dbus_interface_interface_init (GDBusInterfaceIface *iface); + +static void set_object_path_locked (GDBusInterfaceSkeleton *interface_, + const gchar *object_path); +static void remove_connection_locked (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection); +static void skeleton_intercept_handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data); + + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GDBusInterfaceSkeleton, g_dbus_interface_skeleton, G_TYPE_OBJECT, + G_ADD_PRIVATE (GDBusInterfaceSkeleton) + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_INTERFACE, dbus_interface_interface_init)) + +static void +g_dbus_interface_skeleton_finalize (GObject *object) +{ + GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (object); + + /* Hold the lock just in case any code we call verifies that the lock is held */ + g_mutex_lock (&interface->priv->lock); + + /* unexport from all connections if we're exported anywhere */ + while (interface->priv->connections != NULL) + { + ConnectionData *data = interface->priv->connections->data; + remove_connection_locked (interface, data->connection); + } + + set_object_path_locked (interface, NULL); + + g_mutex_unlock (&interface->priv->lock); + + g_free (interface->priv->hooked_vtable); + + if (interface->priv->object != NULL) + g_object_remove_weak_pointer (G_OBJECT (interface->priv->object), (gpointer *) &interface->priv->object); + + g_mutex_clear (&interface->priv->lock); + + G_OBJECT_CLASS (g_dbus_interface_skeleton_parent_class)->finalize (object); +} + +static void +g_dbus_interface_skeleton_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (object); + + switch (prop_id) + { + case PROP_G_FLAGS: + g_value_set_flags (value, g_dbus_interface_skeleton_get_flags (interface)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_interface_skeleton_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (object); + + switch (prop_id) + { + case PROP_G_FLAGS: + g_dbus_interface_skeleton_set_flags (interface, g_value_get_flags (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +g_dbus_interface_skeleton_g_authorize_method_default (GDBusInterfaceSkeleton *interface, + GDBusMethodInvocation *invocation) +{ + return TRUE; +} + +static void +g_dbus_interface_skeleton_class_init (GDBusInterfaceSkeletonClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = g_dbus_interface_skeleton_finalize; + gobject_class->set_property = g_dbus_interface_skeleton_set_property; + gobject_class->get_property = g_dbus_interface_skeleton_get_property; + + klass->g_authorize_method = g_dbus_interface_skeleton_g_authorize_method_default; + + /** + * GDBusInterfaceSkeleton:g-flags: + * + * Flags from the #GDBusInterfaceSkeletonFlags enumeration. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_G_FLAGS, + g_param_spec_flags ("g-flags", + "g-flags", + "Flags for the interface skeleton", + G_TYPE_DBUS_INTERFACE_SKELETON_FLAGS, + G_DBUS_INTERFACE_SKELETON_FLAGS_NONE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusInterfaceSkeleton::g-authorize-method: + * @interface: The #GDBusInterfaceSkeleton emitting the signal. + * @invocation: A #GDBusMethodInvocation. + * + * Emitted when a method is invoked by a remote caller and used to + * determine if the method call is authorized. + * + * Note that this signal is emitted in a thread dedicated to + * handling the method call so handlers are allowed to perform + * blocking IO. This means that it is appropriate to call e.g. + * [polkit_authority_check_authorization_sync()](http://hal.freedesktop.org/docs/polkit/PolkitAuthority.html#polkit-authority-check-authorization-sync) + * with the + * [POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION](http://hal.freedesktop.org/docs/polkit/PolkitAuthority.html#POLKIT-CHECK-AUTHORIZATION-FLAGS-ALLOW-USER-INTERACTION:CAPS) + * flag set. + * + * If %FALSE is returned then no further handlers are run and the + * signal handler must take a reference to @invocation and finish + * handling the call (e.g. return an error via + * g_dbus_method_invocation_return_error()). + * + * Otherwise, if %TRUE is returned, signal emission continues. If no + * handlers return %FALSE, then the method is dispatched. If + * @interface has an enclosing #GDBusObjectSkeleton, then the + * #GDBusObjectSkeleton::authorize-method signal handlers run before + * the handlers for this signal. + * + * The default class handler just returns %TRUE. + * + * Please note that the common case is optimized: if no signals + * handlers are connected and the default class handler isn't + * overridden (for both @interface and the enclosing + * #GDBusObjectSkeleton, if any) and #GDBusInterfaceSkeleton:g-flags does + * not have the + * %G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD + * flags set, no dedicated thread is ever used and the call will be + * handled in the same thread as the object that @interface belongs + * to was exported in. + * + * Returns: %TRUE if the call is authorized, %FALSE otherwise. + * + * Since: 2.30 + */ + signals[G_AUTHORIZE_METHOD_SIGNAL] = + g_signal_new (I_("g-authorize-method"), + G_TYPE_DBUS_INTERFACE_SKELETON, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusInterfaceSkeletonClass, g_authorize_method), + _g_signal_accumulator_false_handled, + NULL, + _g_cclosure_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, + 1, + G_TYPE_DBUS_METHOD_INVOCATION); + g_signal_set_va_marshaller (signals[G_AUTHORIZE_METHOD_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_BOOLEAN__OBJECTv); +} + +static void +g_dbus_interface_skeleton_init (GDBusInterfaceSkeleton *interface) +{ + interface->priv = g_dbus_interface_skeleton_get_instance_private (interface); + g_mutex_init (&interface->priv->lock); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_interface_skeleton_get_flags: + * @interface_: A #GDBusInterfaceSkeleton. + * + * Gets the #GDBusInterfaceSkeletonFlags that describes what the behavior + * of @interface_ + * + * Returns: One or more flags from the #GDBusInterfaceSkeletonFlags enumeration. + * + * Since: 2.30 + */ +GDBusInterfaceSkeletonFlags +g_dbus_interface_skeleton_get_flags (GDBusInterfaceSkeleton *interface_) +{ + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), G_DBUS_INTERFACE_SKELETON_FLAGS_NONE); + return interface_->priv->flags; +} + +/** + * g_dbus_interface_skeleton_set_flags: + * @interface_: A #GDBusInterfaceSkeleton. + * @flags: Flags from the #GDBusInterfaceSkeletonFlags enumeration. + * + * Sets flags describing what the behavior of @skeleton should be. + * + * Since: 2.30 + */ +void +g_dbus_interface_skeleton_set_flags (GDBusInterfaceSkeleton *interface_, + GDBusInterfaceSkeletonFlags flags) +{ + g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_)); + g_mutex_lock (&interface_->priv->lock); + if (interface_->priv->flags != flags) + { + interface_->priv->flags = flags; + g_mutex_unlock (&interface_->priv->lock); + g_object_notify (G_OBJECT (interface_), "g-flags"); + } + else + { + g_mutex_unlock (&interface_->priv->lock); + } +} + +/** + * g_dbus_interface_skeleton_get_info: + * @interface_: A #GDBusInterfaceSkeleton. + * + * Gets D-Bus introspection information for the D-Bus interface + * implemented by @interface_. + * + * Returns: (transfer none): A #GDBusInterfaceInfo (never %NULL). Do not free. + * + * Since: 2.30 + */ +GDBusInterfaceInfo * +g_dbus_interface_skeleton_get_info (GDBusInterfaceSkeleton *interface_) +{ + GDBusInterfaceInfo *ret; + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), NULL); + ret = G_DBUS_INTERFACE_SKELETON_GET_CLASS (interface_)->get_info (interface_); + g_warn_if_fail (ret != NULL); + return ret; +} + +/** + * g_dbus_interface_skeleton_get_vtable: (skip) + * @interface_: A #GDBusInterfaceSkeleton. + * + * Gets the interface vtable for the D-Bus interface implemented by + * @interface_. The returned function pointers should expect @interface_ + * itself to be passed as @user_data. + * + * Returns: A #GDBusInterfaceVTable (never %NULL). + * + * Since: 2.30 + */ +GDBusInterfaceVTable * +g_dbus_interface_skeleton_get_vtable (GDBusInterfaceSkeleton *interface_) +{ + GDBusInterfaceVTable *ret; + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), NULL); + ret = G_DBUS_INTERFACE_SKELETON_GET_CLASS (interface_)->get_vtable (interface_); + g_warn_if_fail (ret != NULL); + return ret; +} + +/** + * g_dbus_interface_skeleton_get_properties: + * @interface_: A #GDBusInterfaceSkeleton. + * + * Gets all D-Bus properties for @interface_. + * + * Returns: (transfer full): A #GVariant of type + * ['a{sv}'][G-VARIANT-TYPE-VARDICT:CAPS]. + * Free with g_variant_unref(). + * + * Since: 2.30 + */ +GVariant * +g_dbus_interface_skeleton_get_properties (GDBusInterfaceSkeleton *interface_) +{ + GVariant *ret; + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), NULL); + ret = G_DBUS_INTERFACE_SKELETON_GET_CLASS (interface_)->get_properties (interface_); + return g_variant_take_ref (ret); +} + +/** + * g_dbus_interface_skeleton_flush: + * @interface_: A #GDBusInterfaceSkeleton. + * + * If @interface_ has outstanding changes, request for these changes to be + * emitted immediately. + * + * For example, an exported D-Bus interface may queue up property + * changes and emit the + * `org.freedesktop.DBus.Properties.PropertiesChanged` + * signal later (e.g. in an idle handler). This technique is useful + * for collapsing multiple property changes into one. + * + * Since: 2.30 + */ +void +g_dbus_interface_skeleton_flush (GDBusInterfaceSkeleton *interface_) +{ + g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_)); + G_DBUS_INTERFACE_SKELETON_GET_CLASS (interface_)->flush (interface_); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusInterfaceInfo * +_g_dbus_interface_skeleton_get_info (GDBusInterface *interface_) +{ + GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (interface_); + return g_dbus_interface_skeleton_get_info (interface); +} + +static GDBusObject * +g_dbus_interface_skeleton_get_object (GDBusInterface *interface_) +{ + GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (interface_); + GDBusObject *ret; + g_mutex_lock (&interface->priv->lock); + ret = interface->priv->object; + g_mutex_unlock (&interface->priv->lock); + return ret; +} + +static GDBusObject * +g_dbus_interface_skeleton_dup_object (GDBusInterface *interface_) +{ + GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (interface_); + GDBusObject *ret; + g_mutex_lock (&interface->priv->lock); + ret = interface->priv->object; + if (ret != NULL) + g_object_ref (ret); + g_mutex_unlock (&interface->priv->lock); + return ret; +} + +static void +g_dbus_interface_skeleton_set_object (GDBusInterface *interface_, + GDBusObject *object) +{ + GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (interface_); + g_mutex_lock (&interface->priv->lock); + if (interface->priv->object != NULL) + g_object_remove_weak_pointer (G_OBJECT (interface->priv->object), (gpointer *) &interface->priv->object); + interface->priv->object = object; + if (object != NULL) + g_object_add_weak_pointer (G_OBJECT (interface->priv->object), (gpointer *) &interface->priv->object); + g_mutex_unlock (&interface->priv->lock); +} + +static void +dbus_interface_interface_init (GDBusInterfaceIface *iface) +{ + iface->get_info = _g_dbus_interface_skeleton_get_info; + iface->get_object = g_dbus_interface_skeleton_get_object; + iface->dup_object = g_dbus_interface_skeleton_dup_object; + iface->set_object = g_dbus_interface_skeleton_set_object; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + gint ref_count; /* (atomic) */ + GDBusInterfaceSkeleton *interface; + GDBusInterfaceMethodCallFunc method_call_func; + GDBusMethodInvocation *invocation; +} DispatchData; + +static void +dispatch_data_unref (DispatchData *data) +{ + if (g_atomic_int_dec_and_test (&data->ref_count)) + g_slice_free (DispatchData, data); +} + +static DispatchData * +dispatch_data_ref (DispatchData *data) +{ + g_atomic_int_inc (&data->ref_count); + return data; +} + +static gboolean +dispatch_invoke_in_context_func (gpointer user_data) +{ + DispatchData *data = user_data; + data->method_call_func (g_dbus_method_invocation_get_connection (data->invocation), + g_dbus_method_invocation_get_sender (data->invocation), + g_dbus_method_invocation_get_object_path (data->invocation), + g_dbus_method_invocation_get_interface_name (data->invocation), + g_dbus_method_invocation_get_method_name (data->invocation), + g_dbus_method_invocation_get_parameters (data->invocation), + data->invocation, + g_dbus_method_invocation_get_user_data (data->invocation)); + return FALSE; +} + +static void +dispatch_in_thread_func (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + DispatchData *data = task_data; + GDBusInterfaceSkeletonFlags flags; + GDBusObject *object; + gboolean authorized; + + g_mutex_lock (&data->interface->priv->lock); + flags = data->interface->priv->flags; + object = data->interface->priv->object; + if (object != NULL) + g_object_ref (object); + g_mutex_unlock (&data->interface->priv->lock); + + /* first check on the enclosing object (if any), then the interface */ + authorized = TRUE; + if (object != NULL) + { + g_signal_emit_by_name (object, + "authorize-method", + data->interface, + data->invocation, + &authorized); + } + if (authorized) + { + g_signal_emit (data->interface, + signals[G_AUTHORIZE_METHOD_SIGNAL], + 0, + data->invocation, + &authorized); + } + + if (authorized) + { + gboolean run_in_thread; + run_in_thread = (flags & G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); + if (run_in_thread) + { + /* might as well just re-use the existing thread */ + data->method_call_func (g_dbus_method_invocation_get_connection (data->invocation), + g_dbus_method_invocation_get_sender (data->invocation), + g_dbus_method_invocation_get_object_path (data->invocation), + g_dbus_method_invocation_get_interface_name (data->invocation), + g_dbus_method_invocation_get_method_name (data->invocation), + g_dbus_method_invocation_get_parameters (data->invocation), + data->invocation, + g_dbus_method_invocation_get_user_data (data->invocation)); + } + else + { + /* bah, back to original context */ + g_main_context_invoke_full (g_task_get_context (task), + g_task_get_priority (task), + dispatch_invoke_in_context_func, + dispatch_data_ref (data), + (GDestroyNotify) dispatch_data_unref); + } + } + else + { + /* do nothing */ + } + + if (object != NULL) + g_object_unref (object); +} + +static void +g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface, + GDBusInterfaceMethodCallFunc method_call_func, + GDBusMethodInvocation *invocation) +{ + gboolean has_handlers; + gboolean has_default_class_handler; + gboolean emit_authorized_signal; + gboolean run_in_thread; + GDBusInterfaceSkeletonFlags flags; + GDBusObject *object; + + g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface)); + g_return_if_fail (method_call_func != NULL); + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + + g_mutex_lock (&interface->priv->lock); + flags = interface->priv->flags; + object = interface->priv->object; + if (object != NULL) + g_object_ref (object); + g_mutex_unlock (&interface->priv->lock); + + /* optimization for the common case where + * + * a) no handler is connected and class handler is not overridden (both interface and object); and + * b) method calls are not dispatched in a thread + */ + has_handlers = g_signal_has_handler_pending (interface, + signals[G_AUTHORIZE_METHOD_SIGNAL], + 0, + TRUE); + has_default_class_handler = (G_DBUS_INTERFACE_SKELETON_GET_CLASS (interface)->g_authorize_method == + g_dbus_interface_skeleton_g_authorize_method_default); + + emit_authorized_signal = (has_handlers || !has_default_class_handler); + if (!emit_authorized_signal) + { + if (object != NULL) + emit_authorized_signal = _g_dbus_object_skeleton_has_authorize_method_handlers (G_DBUS_OBJECT_SKELETON (object)); + } + + run_in_thread = (flags & G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); + if (!emit_authorized_signal && !run_in_thread) + { + method_call_func (g_dbus_method_invocation_get_connection (invocation), + g_dbus_method_invocation_get_sender (invocation), + g_dbus_method_invocation_get_object_path (invocation), + g_dbus_method_invocation_get_interface_name (invocation), + g_dbus_method_invocation_get_method_name (invocation), + g_dbus_method_invocation_get_parameters (invocation), + invocation, + g_dbus_method_invocation_get_user_data (invocation)); + } + else + { + GTask *task; + DispatchData *data; + + data = g_slice_new0 (DispatchData); + data->interface = interface; + data->method_call_func = method_call_func; + data->invocation = invocation; + data->ref_count = 1; + + task = g_task_new (interface, NULL, NULL, NULL); + g_task_set_source_tag (task, g_dbus_interface_method_dispatch_helper); + g_task_set_name (task, "[gio] D-Bus interface method dispatch"); + g_task_set_task_data (task, data, (GDestroyNotify) dispatch_data_unref); + g_task_run_in_thread (task, dispatch_in_thread_func); + g_object_unref (task); + } + + if (object != NULL) + g_object_unref (object); +} + +static void +skeleton_intercept_handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (user_data); + g_dbus_interface_method_dispatch_helper (interface, + g_dbus_interface_skeleton_get_vtable (interface)->method_call, + invocation); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static ConnectionData * +new_connection (GDBusConnection *connection, + guint registration_id) +{ + ConnectionData *data; + + data = g_slice_new0 (ConnectionData); + data->connection = g_object_ref (connection); + data->registration_id = registration_id; + + return data; +} + +static void +free_connection (ConnectionData *data) +{ + if (data != NULL) + { + g_object_unref (data->connection); + g_slice_free (ConnectionData, data); + } +} + +static gboolean +add_connection_locked (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection, + GError **error) +{ + ConnectionData *data; + guint registration_id; + gboolean ret = FALSE; + + if (interface_->priv->hooked_vtable == NULL) + { + /* Hook the vtable since we need to intercept method calls for + * ::g-authorize-method and for dispatching in thread vs + * context + * + * We need to wait until subclasses have had time to initialize + * properly before building the hooked_vtable, so we create it + * once at the last minute. + */ + interface_->priv->hooked_vtable = g_memdup2 (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable)); + interface_->priv->hooked_vtable->method_call = skeleton_intercept_handle_method_call; + } + + registration_id = g_dbus_connection_register_object (connection, + interface_->priv->object_path, + g_dbus_interface_skeleton_get_info (interface_), + interface_->priv->hooked_vtable, + interface_, + NULL, /* user_data_free_func */ + error); + + if (registration_id > 0) + { + data = new_connection (connection, registration_id); + interface_->priv->connections = g_slist_append (interface_->priv->connections, data); + ret = TRUE; + } + + return ret; +} + +static void +remove_connection_locked (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection) +{ + ConnectionData *data; + GSList *l; + + /* Get the connection in the list and unregister ... */ + for (l = interface_->priv->connections; l != NULL; l = l->next) + { + data = l->data; + if (data->connection == connection) + { + g_warn_if_fail (g_dbus_connection_unregister_object (data->connection, data->registration_id)); + free_connection (data); + interface_->priv->connections = g_slist_delete_link (interface_->priv->connections, l); + /* we are guaranteed that the connection is only added once, so bail out early */ + goto out; + } + } + out: + ; +} + +static void +set_object_path_locked (GDBusInterfaceSkeleton *interface_, + const gchar *object_path) +{ + if (g_strcmp0 (interface_->priv->object_path, object_path) != 0) + { + g_free (interface_->priv->object_path); + interface_->priv->object_path = g_strdup (object_path); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_interface_skeleton_get_connection: + * @interface_: A #GDBusInterfaceSkeleton. + * + * Gets the first connection that @interface_ is exported on, if any. + * + * Returns: (nullable) (transfer none): A #GDBusConnection or %NULL if @interface_ is + * not exported anywhere. Do not free, the object belongs to @interface_. + * + * Since: 2.30 + */ +GDBusConnection * +g_dbus_interface_skeleton_get_connection (GDBusInterfaceSkeleton *interface_) +{ + ConnectionData *data; + GDBusConnection *ret; + + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), NULL); + g_mutex_lock (&interface_->priv->lock); + + ret = NULL; + if (interface_->priv->connections != NULL) + { + data = interface_->priv->connections->data; + if (data != NULL) + ret = data->connection; + } + + g_mutex_unlock (&interface_->priv->lock); + + return ret; +} + +/** + * g_dbus_interface_skeleton_get_connections: + * @interface_: A #GDBusInterfaceSkeleton. + * + * Gets a list of the connections that @interface_ is exported on. + * + * Returns: (element-type GDBusConnection) (transfer full): A list of + * all the connections that @interface_ is exported on. The returned + * list should be freed with g_list_free() after each element has + * been freed with g_object_unref(). + * + * Since: 2.32 + */ +GList * +g_dbus_interface_skeleton_get_connections (GDBusInterfaceSkeleton *interface_) +{ + GList *connections; + GSList *l; + ConnectionData *data; + + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), NULL); + + g_mutex_lock (&interface_->priv->lock); + connections = NULL; + + for (l = interface_->priv->connections; l != NULL; l = l->next) + { + data = l->data; + connections = g_list_prepend (connections, + /* Return a reference to each connection */ + g_object_ref (data->connection)); + } + + g_mutex_unlock (&interface_->priv->lock); + + return g_list_reverse (connections); +} + +/** + * g_dbus_interface_skeleton_has_connection: + * @interface_: A #GDBusInterfaceSkeleton. + * @connection: A #GDBusConnection. + * + * Checks if @interface_ is exported on @connection. + * + * Returns: %TRUE if @interface_ is exported on @connection, %FALSE otherwise. + * + * Since: 2.32 + */ +gboolean +g_dbus_interface_skeleton_has_connection (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection) +{ + GSList *l; + gboolean ret = FALSE; + + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), FALSE); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + + g_mutex_lock (&interface_->priv->lock); + + for (l = interface_->priv->connections; l != NULL; l = l->next) + { + ConnectionData *data = l->data; + if (data->connection == connection) + { + ret = TRUE; + goto out; + } + } + + out: + g_mutex_unlock (&interface_->priv->lock); + return ret; +} + +/** + * g_dbus_interface_skeleton_get_object_path: + * @interface_: A #GDBusInterfaceSkeleton. + * + * Gets the object path that @interface_ is exported on, if any. + * + * Returns: (nullable): A string owned by @interface_ or %NULL if @interface_ is not exported + * anywhere. Do not free, the string belongs to @interface_. + * + * Since: 2.30 + */ +const gchar * +g_dbus_interface_skeleton_get_object_path (GDBusInterfaceSkeleton *interface_) +{ + const gchar *ret; + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), NULL); + g_mutex_lock (&interface_->priv->lock); + ret = interface_->priv->object_path; + g_mutex_unlock (&interface_->priv->lock); + return ret; +} + +/** + * g_dbus_interface_skeleton_export: + * @interface_: The D-Bus interface to export. + * @connection: A #GDBusConnection to export @interface_ on. + * @object_path: The path to export the interface at. + * @error: Return location for error or %NULL. + * + * Exports @interface_ at @object_path on @connection. + * + * This can be called multiple times to export the same @interface_ + * onto multiple connections however the @object_path provided must be + * the same for all connections. + * + * Use g_dbus_interface_skeleton_unexport() to unexport the object. + * + * Returns: %TRUE if the interface was exported on @connection, otherwise %FALSE with + * @error set. + * + * Since: 2.30 + */ +gboolean +g_dbus_interface_skeleton_export (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection, + const gchar *object_path, + GError **error) +{ + gboolean ret = FALSE; + + g_return_val_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_), FALSE); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* Assert that the object path is the same for multiple connections here */ + g_return_val_if_fail (interface_->priv->object_path == NULL || + g_strcmp0 (interface_->priv->object_path, object_path) == 0, FALSE); + + g_mutex_lock (&interface_->priv->lock); + + /* Set the object path */ + set_object_path_locked (interface_, object_path); + + /* Add the connection */ + ret = add_connection_locked (interface_, connection, error); + + g_mutex_unlock (&interface_->priv->lock); + return ret; +} + +/** + * g_dbus_interface_skeleton_unexport: + * @interface_: A #GDBusInterfaceSkeleton. + * + * Stops exporting @interface_ on all connections it is exported on. + * + * To unexport @interface_ from only a single connection, use + * g_dbus_interface_skeleton_unexport_from_connection() + * + * Since: 2.30 + */ +void +g_dbus_interface_skeleton_unexport (GDBusInterfaceSkeleton *interface_) +{ + g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_)); + g_return_if_fail (interface_->priv->connections != NULL); + + g_mutex_lock (&interface_->priv->lock); + + g_assert (interface_->priv->object_path != NULL); + g_assert (interface_->priv->hooked_vtable != NULL); + + /* Remove all connections */ + while (interface_->priv->connections != NULL) + { + ConnectionData *data = interface_->priv->connections->data; + remove_connection_locked (interface_, data->connection); + } + + /* Unset the object path since there are no connections left */ + set_object_path_locked (interface_, NULL); + + g_mutex_unlock (&interface_->priv->lock); +} + + +/** + * g_dbus_interface_skeleton_unexport_from_connection: + * @interface_: A #GDBusInterfaceSkeleton. + * @connection: A #GDBusConnection. + * + * Stops exporting @interface_ on @connection. + * + * To stop exporting on all connections the interface is exported on, + * use g_dbus_interface_skeleton_unexport(). + * + * Since: 2.32 + */ +void +g_dbus_interface_skeleton_unexport_from_connection (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection) +{ + g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_)); + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + g_return_if_fail (interface_->priv->connections != NULL); + + g_mutex_lock (&interface_->priv->lock); + + g_assert (interface_->priv->object_path != NULL); + g_assert (interface_->priv->hooked_vtable != NULL); + + remove_connection_locked (interface_, connection); + + /* Reset the object path if we removed the last connection */ + if (interface_->priv->connections == NULL) + set_object_path_locked (interface_, NULL); + + g_mutex_unlock (&interface_->priv->lock); +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusinterfaceskeleton.h b/gio/gdbusinterfaceskeleton.h new file mode 100644 index 0000000..bf3b630 --- /dev/null +++ b/gio/gdbusinterfaceskeleton.h @@ -0,0 +1,127 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_INTERFACE_SKELETON_H__ +#define __G_DBUS_INTERFACE_SKELETON_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_INTERFACE_SKELETON (g_dbus_interface_skeleton_get_type ()) +#define G_DBUS_INTERFACE_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_INTERFACE_SKELETON, GDBusInterfaceSkeleton)) +#define G_DBUS_INTERFACE_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_INTERFACE_SKELETON, GDBusInterfaceSkeletonClass)) +#define G_DBUS_INTERFACE_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_INTERFACE_SKELETON, GDBusInterfaceSkeletonClass)) +#define G_IS_DBUS_INTERFACE_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_INTERFACE_SKELETON)) +#define G_IS_DBUS_INTERFACE_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_INTERFACE_SKELETON)) + +typedef struct _GDBusInterfaceSkeletonClass GDBusInterfaceSkeletonClass; +typedef struct _GDBusInterfaceSkeletonPrivate GDBusInterfaceSkeletonPrivate; + +/** + * GDBusInterfaceSkeleton: + * + * The #GDBusInterfaceSkeleton structure contains private data and should + * only be accessed using the provided API. + * + * Since: 2.30 + */ +struct _GDBusInterfaceSkeleton +{ + /*< private >*/ + GObject parent_instance; + GDBusInterfaceSkeletonPrivate *priv; +}; + +/** + * GDBusInterfaceSkeletonClass: + * @parent_class: The parent class. + * @get_info: Returns a #GDBusInterfaceInfo. See g_dbus_interface_skeleton_get_info() for details. + * @get_vtable: Returns a #GDBusInterfaceVTable. See g_dbus_interface_skeleton_get_vtable() for details. + * @get_properties: Returns a #GVariant with all properties. See g_dbus_interface_skeleton_get_properties(). + * @flush: Emits outstanding changes, if any. See g_dbus_interface_skeleton_flush(). + * @g_authorize_method: Signal class handler for the #GDBusInterfaceSkeleton::g-authorize-method signal. + * + * Class structure for #GDBusInterfaceSkeleton. + * + * Since: 2.30 + */ +struct _GDBusInterfaceSkeletonClass +{ + GObjectClass parent_class; + + /* Virtual Functions */ + GDBusInterfaceInfo *(*get_info) (GDBusInterfaceSkeleton *interface_); + GDBusInterfaceVTable *(*get_vtable) (GDBusInterfaceSkeleton *interface_); + GVariant *(*get_properties) (GDBusInterfaceSkeleton *interface_); + void (*flush) (GDBusInterfaceSkeleton *interface_); + + /*< private >*/ + gpointer vfunc_padding[8]; + /*< public >*/ + + /* Signals */ + gboolean (*g_authorize_method) (GDBusInterfaceSkeleton *interface_, + GDBusMethodInvocation *invocation); + + /*< private >*/ + gpointer signal_padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_interface_skeleton_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDBusInterfaceSkeletonFlags g_dbus_interface_skeleton_get_flags (GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_skeleton_set_flags (GDBusInterfaceSkeleton *interface_, + GDBusInterfaceSkeletonFlags flags); +GLIB_AVAILABLE_IN_ALL +GDBusInterfaceInfo *g_dbus_interface_skeleton_get_info (GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +GDBusInterfaceVTable *g_dbus_interface_skeleton_get_vtable (GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_interface_skeleton_get_properties (GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_skeleton_flush (GDBusInterfaceSkeleton *interface_); + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_interface_skeleton_export (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection, + const gchar *object_path, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_skeleton_unexport (GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_skeleton_unexport_from_connection (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection); + +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_interface_skeleton_get_connection (GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +GList *g_dbus_interface_skeleton_get_connections (GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_interface_skeleton_has_connection (GDBusInterfaceSkeleton *interface_, + GDBusConnection *connection); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_interface_skeleton_get_object_path (GDBusInterfaceSkeleton *interface_); + +G_END_DECLS + +#endif /* __G_DBUS_INTERFACE_SKELETON_H */ diff --git a/gio/gdbusintrospection.c b/gio/gdbusintrospection.c new file mode 100644 index 0000000..d6aa445 --- /dev/null +++ b/gio/gdbusintrospection.c @@ -0,0 +1,2194 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include + +#include "gdbusintrospection.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusintrospection + * @title: D-Bus Introspection Data + * @short_description: Node and interface description data structures + * @include: gio/gio.h + * + * Various data structures and convenience routines to parse and + * generate D-Bus introspection XML. Introspection information is + * used when registering objects with g_dbus_connection_register_object(). + * + * The format of D-Bus introspection XML is specified in the + * [D-Bus specification](http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format) + */ + +/* ---------------------------------------------------------------------------------------------------- */ + +#define _MY_DEFINE_BOXED_TYPE(TypeName, type_name) \ + G_DEFINE_BOXED_TYPE (TypeName, type_name, type_name##_ref, type_name##_unref) + +_MY_DEFINE_BOXED_TYPE (GDBusNodeInfo, g_dbus_node_info) +_MY_DEFINE_BOXED_TYPE (GDBusInterfaceInfo, g_dbus_interface_info) +_MY_DEFINE_BOXED_TYPE (GDBusMethodInfo, g_dbus_method_info) +_MY_DEFINE_BOXED_TYPE (GDBusSignalInfo, g_dbus_signal_info) +_MY_DEFINE_BOXED_TYPE (GDBusPropertyInfo, g_dbus_property_info) +_MY_DEFINE_BOXED_TYPE (GDBusArgInfo, g_dbus_arg_info) +_MY_DEFINE_BOXED_TYPE (GDBusAnnotationInfo, g_dbus_annotation_info) + +#undef _MY_DEFINE_BOXED_TYPE + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + /* stuff we are currently collecting */ + GPtrArray *args; + GPtrArray *out_args; + GPtrArray *methods; + GPtrArray *signals; + GPtrArray *properties; + GPtrArray *interfaces; + GPtrArray *nodes; + GPtrArray *annotations; + + /* A list of GPtrArray's containing annotations */ + GSList *annotations_stack; + + /* A list of GPtrArray's containing interfaces */ + GSList *interfaces_stack; + + /* A list of GPtrArray's containing nodes */ + GSList *nodes_stack; + + /* Whether the direction was "in" for last parsed arg */ + gboolean last_arg_was_in; + + /* Number of args currently being collected; used for assigning + * names to args without a "name" attribute + */ + guint num_args; + +} ParseData; + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_node_info_ref: + * @info: A #GDBusNodeInfo + * + * If @info is statically allocated does nothing. Otherwise increases + * the reference count. + * + * Returns: (not nullable): The same @info. + * + * Since: 2.26 + */ +GDBusNodeInfo * +g_dbus_node_info_ref (GDBusNodeInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return info; + g_atomic_int_inc (&info->ref_count); + return info; +} + +/** + * g_dbus_interface_info_ref: + * @info: A #GDBusInterfaceInfo + * + * If @info is statically allocated does nothing. Otherwise increases + * the reference count. + * + * Returns: (not nullable): The same @info. + * + * Since: 2.26 + */ +GDBusInterfaceInfo * +g_dbus_interface_info_ref (GDBusInterfaceInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return info; + g_atomic_int_inc (&info->ref_count); + return info; +} + +/** + * g_dbus_method_info_ref: + * @info: A #GDBusMethodInfo + * + * If @info is statically allocated does nothing. Otherwise increases + * the reference count. + * + * Returns: (not nullable): The same @info. + * + * Since: 2.26 + */ +GDBusMethodInfo * +g_dbus_method_info_ref (GDBusMethodInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return info; + g_atomic_int_inc (&info->ref_count); + return info; +} + +/** + * g_dbus_signal_info_ref: + * @info: A #GDBusSignalInfo + * + * If @info is statically allocated does nothing. Otherwise increases + * the reference count. + * + * Returns: (not nullable): The same @info. + * + * Since: 2.26 + */ +GDBusSignalInfo * +g_dbus_signal_info_ref (GDBusSignalInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return info; + g_atomic_int_inc (&info->ref_count); + return info; +} + +/** + * g_dbus_property_info_ref: + * @info: A #GDBusPropertyInfo + * + * If @info is statically allocated does nothing. Otherwise increases + * the reference count. + * + * Returns: (not nullable): The same @info. + * + * Since: 2.26 + */ +GDBusPropertyInfo * +g_dbus_property_info_ref (GDBusPropertyInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return info; + g_atomic_int_inc (&info->ref_count); + return info; +} + +/** + * g_dbus_arg_info_ref: + * @info: A #GDBusArgInfo + * + * If @info is statically allocated does nothing. Otherwise increases + * the reference count. + * + * Returns: (not nullable): The same @info. + * + * Since: 2.26 + */ +GDBusArgInfo * +g_dbus_arg_info_ref (GDBusArgInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return info; + g_atomic_int_inc (&info->ref_count); + return info; +} + +/** + * g_dbus_annotation_info_ref: + * @info: A #GDBusNodeInfo + * + * If @info is statically allocated does nothing. Otherwise increases + * the reference count. + * + * Returns: (not nullable): The same @info. + * + * Since: 2.26 + */ +GDBusAnnotationInfo * +g_dbus_annotation_info_ref (GDBusAnnotationInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return info; + g_atomic_int_inc (&info->ref_count); + return info; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +free_null_terminated_array (gpointer array, GDestroyNotify unref_func) +{ + guint n; + gpointer *p = array; + if (p == NULL) + return; + for (n = 0; p[n] != NULL; n++) + unref_func (p[n]); + g_free (p); +} + +/** + * g_dbus_annotation_info_unref: + * @info: A #GDBusAnnotationInfo. + * + * If @info is statically allocated, does nothing. Otherwise decreases + * the reference count of @info. When its reference count drops to 0, + * the memory used is freed. + * + * Since: 2.26 + */ +void +g_dbus_annotation_info_unref (GDBusAnnotationInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return; + if (g_atomic_int_dec_and_test (&info->ref_count)) + { + g_free (info->key); + g_free (info->value); + free_null_terminated_array (info->annotations, (GDestroyNotify) g_dbus_annotation_info_unref); + g_free (info); + } +} + +/** + * g_dbus_arg_info_unref: + * @info: A #GDBusArgInfo. + * + * If @info is statically allocated, does nothing. Otherwise decreases + * the reference count of @info. When its reference count drops to 0, + * the memory used is freed. + * + * Since: 2.26 + */ +void +g_dbus_arg_info_unref (GDBusArgInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return; + if (g_atomic_int_dec_and_test (&info->ref_count)) + { + g_free (info->name); + g_free (info->signature); + free_null_terminated_array (info->annotations, (GDestroyNotify) g_dbus_annotation_info_unref); + g_free (info); + } +} + +/** + * g_dbus_method_info_unref: + * @info: A #GDBusMethodInfo. + * + * If @info is statically allocated, does nothing. Otherwise decreases + * the reference count of @info. When its reference count drops to 0, + * the memory used is freed. + * + * Since: 2.26 + */ +void +g_dbus_method_info_unref (GDBusMethodInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return; + if (g_atomic_int_dec_and_test (&info->ref_count)) + { + g_free (info->name); + free_null_terminated_array (info->in_args, (GDestroyNotify) g_dbus_arg_info_unref); + free_null_terminated_array (info->out_args, (GDestroyNotify) g_dbus_arg_info_unref); + free_null_terminated_array (info->annotations, (GDestroyNotify) g_dbus_annotation_info_unref); + g_free (info); + } +} + +/** + * g_dbus_signal_info_unref: + * @info: A #GDBusSignalInfo. + * + * If @info is statically allocated, does nothing. Otherwise decreases + * the reference count of @info. When its reference count drops to 0, + * the memory used is freed. + * + * Since: 2.26 + */ +void +g_dbus_signal_info_unref (GDBusSignalInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return; + if (g_atomic_int_dec_and_test (&info->ref_count)) + { + g_free (info->name); + free_null_terminated_array (info->args, (GDestroyNotify) g_dbus_arg_info_unref); + free_null_terminated_array (info->annotations, (GDestroyNotify) g_dbus_annotation_info_unref); + g_free (info); + } +} + +/** + * g_dbus_property_info_unref: + * @info: A #GDBusPropertyInfo. + * + * If @info is statically allocated, does nothing. Otherwise decreases + * the reference count of @info. When its reference count drops to 0, + * the memory used is freed. + * + * Since: 2.26 + */ +void +g_dbus_property_info_unref (GDBusPropertyInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return; + if (g_atomic_int_dec_and_test (&info->ref_count)) + { + g_free (info->name); + g_free (info->signature); + free_null_terminated_array (info->annotations, (GDestroyNotify) g_dbus_annotation_info_unref); + g_free (info); + } +} + +/** + * g_dbus_interface_info_unref: + * @info: A #GDBusInterfaceInfo. + * + * If @info is statically allocated, does nothing. Otherwise decreases + * the reference count of @info. When its reference count drops to 0, + * the memory used is freed. + * + * Since: 2.26 + */ +void +g_dbus_interface_info_unref (GDBusInterfaceInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return; + if (g_atomic_int_dec_and_test (&info->ref_count)) + { + g_free (info->name); + free_null_terminated_array (info->methods, (GDestroyNotify) g_dbus_method_info_unref); + free_null_terminated_array (info->signals, (GDestroyNotify) g_dbus_signal_info_unref); + free_null_terminated_array (info->properties, (GDestroyNotify) g_dbus_property_info_unref); + free_null_terminated_array (info->annotations, (GDestroyNotify) g_dbus_annotation_info_unref); + g_free (info); + } +} + +/** + * g_dbus_node_info_unref: + * @info: A #GDBusNodeInfo. + * + * If @info is statically allocated, does nothing. Otherwise decreases + * the reference count of @info. When its reference count drops to 0, + * the memory used is freed. + * + * Since: 2.26 + */ +void +g_dbus_node_info_unref (GDBusNodeInfo *info) +{ + if (g_atomic_int_get (&info->ref_count) == -1) + return; + if (g_atomic_int_dec_and_test (&info->ref_count)) + { + g_free (info->path); + free_null_terminated_array (info->interfaces, (GDestroyNotify) g_dbus_interface_info_unref); + free_null_terminated_array (info->nodes, (GDestroyNotify) g_dbus_node_info_unref); + free_null_terminated_array (info->annotations, (GDestroyNotify) g_dbus_annotation_info_unref); + g_free (info); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +g_dbus_annotation_info_set (ParseData *data, + GDBusAnnotationInfo *info, + const gchar *key, + const gchar *value, + GDBusAnnotationInfo **embedded_annotations) +{ + info->ref_count = 1; + + if (key != NULL) + info->key = g_strdup (key); + + if (value != NULL) + info->value = g_strdup (value); + + if (embedded_annotations != NULL) + info->annotations = embedded_annotations; +} + +static void +g_dbus_arg_info_set (ParseData *data, + GDBusArgInfo *info, + const gchar *name, + const gchar *signature, + GDBusAnnotationInfo **annotations) +{ + info->ref_count = 1; + + /* name may be NULL - TODO: compute name? */ + if (name != NULL) + info->name = g_strdup (name); + + if (signature != NULL) + info->signature = g_strdup (signature); + + if (annotations != NULL) + info->annotations = annotations; +} + +static void +g_dbus_method_info_set (ParseData *data, + GDBusMethodInfo *info, + const gchar *name, + GDBusArgInfo **in_args, + GDBusArgInfo **out_args, + GDBusAnnotationInfo **annotations) +{ + info->ref_count = 1; + + if (name != NULL) + info->name = g_strdup (name); + + if (in_args != NULL) + info->in_args = in_args; + + if (out_args != NULL) + info->out_args = out_args; + + if (annotations != NULL) + info->annotations = annotations; +} + +static void +g_dbus_signal_info_set (ParseData *data, + GDBusSignalInfo *info, + const gchar *name, + GDBusArgInfo **args, + GDBusAnnotationInfo **annotations) +{ + info->ref_count = 1; + + if (name != NULL) + info->name = g_strdup (name); + + if (args != NULL) + info->args = args; + + if (annotations != NULL) + info->annotations = annotations; +} + +static void +g_dbus_property_info_set (ParseData *data, + GDBusPropertyInfo *info, + const gchar *name, + const gchar *signature, + GDBusPropertyInfoFlags flags, + GDBusAnnotationInfo **annotations) +{ + info->ref_count = 1; + + if (name != NULL) + info->name = g_strdup (name); + + if (flags != G_DBUS_PROPERTY_INFO_FLAGS_NONE) + info->flags = flags; + + if (signature != NULL) + info->signature = g_strdup (signature); + + if (annotations != NULL) + info->annotations = annotations; +} + +static void +g_dbus_interface_info_set (ParseData *data, + GDBusInterfaceInfo *info, + const gchar *name, + GDBusMethodInfo **methods, + GDBusSignalInfo **signals, + GDBusPropertyInfo **properties, + GDBusAnnotationInfo **annotations) +{ + info->ref_count = 1; + + if (name != NULL) + info->name = g_strdup (name); + + if (methods != NULL) + info->methods = methods; + + if (signals != NULL) + info->signals = signals; + + if (properties != NULL) + info->properties = properties; + + if (annotations != NULL) + info->annotations = annotations; +} + +static void +g_dbus_node_info_set (ParseData *data, + GDBusNodeInfo *info, + const gchar *path, + GDBusInterfaceInfo **interfaces, + GDBusNodeInfo **nodes, + GDBusAnnotationInfo **annotations) +{ + info->ref_count = 1; + + if (path != NULL) + { + info->path = g_strdup (path); + /* TODO: relative / absolute path snafu */ + } + + if (interfaces != NULL) + info->interfaces = interfaces; + + if (nodes != NULL) + info->nodes = nodes; + + if (annotations != NULL) + info->annotations = annotations; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +g_dbus_annotation_info_generate_xml (GDBusAnnotationInfo *info, + guint indent, + GString *string_builder) +{ + gchar *tmp; + guint n; + + tmp = g_markup_printf_escaped ("%*skey, + info->value); + g_string_append (string_builder, tmp); + g_free (tmp); + + if (info->annotations == NULL) + { + g_string_append (string_builder, "/>\n"); + } + else + { + g_string_append (string_builder, ">\n"); + + for (n = 0; info->annotations != NULL && info->annotations[n] != NULL; n++) + g_dbus_annotation_info_generate_xml (info->annotations[n], + indent + 2, + string_builder); + + g_string_append_printf (string_builder, "%*s\n", + indent, ""); + } + +} + +static void +g_dbus_arg_info_generate_xml (GDBusArgInfo *info, + guint indent, + const gchar *extra_attributes, + GString *string_builder) +{ + guint n; + + g_string_append_printf (string_builder, "%*ssignature); + + if (info->name != NULL) + g_string_append_printf (string_builder, " name=\"%s\"", info->name); + + if (extra_attributes != NULL) + g_string_append_printf (string_builder, " %s", extra_attributes); + + if (info->annotations == NULL) + { + g_string_append (string_builder, "/>\n"); + } + else + { + g_string_append (string_builder, ">\n"); + + for (n = 0; info->annotations != NULL && info->annotations[n] != NULL; n++) + g_dbus_annotation_info_generate_xml (info->annotations[n], + indent + 2, + string_builder); + + g_string_append_printf (string_builder, "%*s\n", indent, ""); + } + +} + +static void +g_dbus_method_info_generate_xml (GDBusMethodInfo *info, + guint indent, + GString *string_builder) +{ + guint n; + + g_string_append_printf (string_builder, "%*sname); + + if (info->annotations == NULL && info->in_args == NULL && info->out_args == NULL) + { + g_string_append (string_builder, "/>\n"); + } + else + { + g_string_append (string_builder, ">\n"); + + for (n = 0; info->annotations != NULL && info->annotations[n] != NULL; n++) + g_dbus_annotation_info_generate_xml (info->annotations[n], + indent + 2, + string_builder); + + for (n = 0; info->in_args != NULL && info->in_args[n] != NULL; n++) + g_dbus_arg_info_generate_xml (info->in_args[n], + indent + 2, + "direction=\"in\"", + string_builder); + + for (n = 0; info->out_args != NULL && info->out_args[n] != NULL; n++) + g_dbus_arg_info_generate_xml (info->out_args[n], + indent + 2, + "direction=\"out\"", + string_builder); + + g_string_append_printf (string_builder, "%*s\n", indent, ""); + } +} + +static void +g_dbus_signal_info_generate_xml (GDBusSignalInfo *info, + guint indent, + GString *string_builder) +{ + guint n; + + g_string_append_printf (string_builder, "%*sname); + + if (info->annotations == NULL && info->args == NULL) + { + g_string_append (string_builder, "/>\n"); + } + else + { + g_string_append (string_builder, ">\n"); + + for (n = 0; info->annotations != NULL && info->annotations[n] != NULL; n++) + g_dbus_annotation_info_generate_xml (info->annotations[n], + indent + 2, + string_builder); + + for (n = 0; info->args != NULL && info->args[n] != NULL; n++) + g_dbus_arg_info_generate_xml (info->args[n], + indent + 2, + NULL, + string_builder); + + g_string_append_printf (string_builder, "%*s\n", indent, ""); + } +} + +static void +g_dbus_property_info_generate_xml (GDBusPropertyInfo *info, + guint indent, + GString *string_builder) +{ + guint n; + const gchar *access_string; + + if ((info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE) && + (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE)) + { + access_string = "readwrite"; + } + else if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE) + { + access_string = "read"; + } + else if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE) + { + access_string = "write"; + } + else + { + g_assert_not_reached (); + } + + g_string_append_printf (string_builder, "%*ssignature, + info->name, + access_string); + + if (info->annotations == NULL) + { + g_string_append (string_builder, "/>\n"); + } + else + { + g_string_append (string_builder, ">\n"); + + for (n = 0; info->annotations != NULL && info->annotations[n] != NULL; n++) + g_dbus_annotation_info_generate_xml (info->annotations[n], + indent + 2, + string_builder); + + g_string_append_printf (string_builder, "%*s\n", indent, ""); + } + +} + +/** + * g_dbus_interface_info_generate_xml: + * @info: A #GDBusNodeInfo + * @indent: Indentation level. + * @string_builder: A #GString to to append XML data to. + * + * Appends an XML representation of @info (and its children) to @string_builder. + * + * This function is typically used for generating introspection XML + * documents at run-time for handling the + * `org.freedesktop.DBus.Introspectable.Introspect` + * method. + * + * Since: 2.26 + */ +void +g_dbus_interface_info_generate_xml (GDBusInterfaceInfo *info, + guint indent, + GString *string_builder) +{ + guint n; + + g_string_append_printf (string_builder, "%*s\n", + indent, "", + info->name); + + for (n = 0; info->annotations != NULL && info->annotations[n] != NULL; n++) + g_dbus_annotation_info_generate_xml (info->annotations[n], + indent + 2, + string_builder); + + for (n = 0; info->methods != NULL && info->methods[n] != NULL; n++) + g_dbus_method_info_generate_xml (info->methods[n], + indent + 2, + string_builder); + + for (n = 0; info->signals != NULL && info->signals[n] != NULL; n++) + g_dbus_signal_info_generate_xml (info->signals[n], + indent + 2, + string_builder); + + for (n = 0; info->properties != NULL && info->properties[n] != NULL; n++) + g_dbus_property_info_generate_xml (info->properties[n], + indent + 2, + string_builder); + + g_string_append_printf (string_builder, "%*s\n", indent, ""); +} + +/** + * g_dbus_node_info_generate_xml: + * @info: A #GDBusNodeInfo. + * @indent: Indentation level. + * @string_builder: A #GString to to append XML data to. + * + * Appends an XML representation of @info (and its children) to @string_builder. + * + * This function is typically used for generating introspection XML documents at run-time for + * handling the `org.freedesktop.DBus.Introspectable.Introspect` method. + * + * Since: 2.26 + */ +void +g_dbus_node_info_generate_xml (GDBusNodeInfo *info, + guint indent, + GString *string_builder) +{ + guint n; + + g_string_append_printf (string_builder, "%*spath != NULL) + g_string_append_printf (string_builder, " name=\"%s\"", info->path); + + if (info->interfaces == NULL && info->nodes == NULL && info->annotations == NULL) + { + g_string_append (string_builder, "/>\n"); + } + else + { + g_string_append (string_builder, ">\n"); + + for (n = 0; info->annotations != NULL && info->annotations[n] != NULL; n++) + g_dbus_annotation_info_generate_xml (info->annotations[n], + indent + 2, + string_builder); + + for (n = 0; info->interfaces != NULL && info->interfaces[n] != NULL; n++) + g_dbus_interface_info_generate_xml (info->interfaces[n], + indent + 2, + string_builder); + + for (n = 0; info->nodes != NULL && info->nodes[n] != NULL; n++) + g_dbus_node_info_generate_xml (info->nodes[n], + indent + 2, + string_builder); + + g_string_append_printf (string_builder, "%*s\n", indent, ""); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAnnotationInfo ** +parse_data_steal_annotations (ParseData *data, + guint *out_num_elements) +{ + GDBusAnnotationInfo **ret; + if (out_num_elements != NULL) + *out_num_elements = data->annotations->len; + if (data->annotations == NULL) + ret = NULL; + else + { + g_ptr_array_add (data->annotations, NULL); + ret = (GDBusAnnotationInfo **) g_ptr_array_free (data->annotations, FALSE); + } + data->annotations = g_ptr_array_new (); + return ret; +} + +static GDBusArgInfo ** +parse_data_steal_args (ParseData *data, + guint *out_num_elements) +{ + GDBusArgInfo **ret; + if (out_num_elements != NULL) + *out_num_elements = data->args->len; + if (data->args == NULL) + ret = NULL; + else + { + g_ptr_array_add (data->args, NULL); + ret = (GDBusArgInfo **) g_ptr_array_free (data->args, FALSE); + } + data->args = g_ptr_array_new (); + return ret; +} + +static GDBusArgInfo ** +parse_data_steal_out_args (ParseData *data, + guint *out_num_elements) +{ + GDBusArgInfo **ret; + if (out_num_elements != NULL) + *out_num_elements = data->out_args->len; + if (data->out_args == NULL) + ret = NULL; + else + { + g_ptr_array_add (data->out_args, NULL); + ret = (GDBusArgInfo **) g_ptr_array_free (data->out_args, FALSE); + } + data->out_args = g_ptr_array_new (); + return ret; +} + +static GDBusMethodInfo ** +parse_data_steal_methods (ParseData *data, + guint *out_num_elements) +{ + GDBusMethodInfo **ret; + if (out_num_elements != NULL) + *out_num_elements = data->methods->len; + if (data->methods == NULL) + ret = NULL; + else + { + g_ptr_array_add (data->methods, NULL); + ret = (GDBusMethodInfo **) g_ptr_array_free (data->methods, FALSE); + } + data->methods = g_ptr_array_new (); + return ret; +} + +static GDBusSignalInfo ** +parse_data_steal_signals (ParseData *data, + guint *out_num_elements) +{ + GDBusSignalInfo **ret; + if (out_num_elements != NULL) + *out_num_elements = data->signals->len; + if (data->signals == NULL) + ret = NULL; + else + { + g_ptr_array_add (data->signals, NULL); + ret = (GDBusSignalInfo **) g_ptr_array_free (data->signals, FALSE); + } + data->signals = g_ptr_array_new (); + return ret; +} + +static GDBusPropertyInfo ** +parse_data_steal_properties (ParseData *data, + guint *out_num_elements) +{ + GDBusPropertyInfo **ret; + if (out_num_elements != NULL) + *out_num_elements = data->properties->len; + if (data->properties == NULL) + ret = NULL; + else + { + g_ptr_array_add (data->properties, NULL); + ret = (GDBusPropertyInfo **) g_ptr_array_free (data->properties, FALSE); + } + data->properties = g_ptr_array_new (); + return ret; +} + +static GDBusInterfaceInfo ** +parse_data_steal_interfaces (ParseData *data, + guint *out_num_elements) +{ + GDBusInterfaceInfo **ret; + if (out_num_elements != NULL) + *out_num_elements = data->interfaces->len; + if (data->interfaces == NULL) + ret = NULL; + else + { + g_ptr_array_add (data->interfaces, NULL); + ret = (GDBusInterfaceInfo **) g_ptr_array_free (data->interfaces, FALSE); + } + data->interfaces = g_ptr_array_new (); + return ret; +} + +static GDBusNodeInfo ** +parse_data_steal_nodes (ParseData *data, + guint *out_num_elements) +{ + GDBusNodeInfo **ret; + if (out_num_elements != NULL) + *out_num_elements = data->nodes->len; + if (data->nodes == NULL) + ret = NULL; + else + { + g_ptr_array_add (data->nodes, NULL); + ret = (GDBusNodeInfo **) g_ptr_array_free (data->nodes, FALSE); + } + data->nodes = g_ptr_array_new (); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +parse_data_free_annotations (ParseData *data) +{ + if (data->annotations == NULL) + return; + g_ptr_array_foreach (data->annotations, (GFunc) g_dbus_annotation_info_unref, NULL); + g_ptr_array_free (data->annotations, TRUE); + data->annotations = NULL; +} + +static void +parse_data_free_args (ParseData *data) +{ + if (data->args == NULL) + return; + g_ptr_array_foreach (data->args, (GFunc) g_dbus_arg_info_unref, NULL); + g_ptr_array_free (data->args, TRUE); + data->args = NULL; +} + +static void +parse_data_free_out_args (ParseData *data) +{ + if (data->out_args == NULL) + return; + g_ptr_array_foreach (data->out_args, (GFunc) g_dbus_arg_info_unref, NULL); + g_ptr_array_free (data->out_args, TRUE); + data->out_args = NULL; +} + +static void +parse_data_free_methods (ParseData *data) +{ + if (data->methods == NULL) + return; + g_ptr_array_foreach (data->methods, (GFunc) g_dbus_method_info_unref, NULL); + g_ptr_array_free (data->methods, TRUE); + data->methods = NULL; +} + +static void +parse_data_free_signals (ParseData *data) +{ + if (data->signals == NULL) + return; + g_ptr_array_foreach (data->signals, (GFunc) g_dbus_signal_info_unref, NULL); + g_ptr_array_free (data->signals, TRUE); + data->signals = NULL; +} + +static void +parse_data_free_properties (ParseData *data) +{ + if (data->properties == NULL) + return; + g_ptr_array_foreach (data->properties, (GFunc) g_dbus_property_info_unref, NULL); + g_ptr_array_free (data->properties, TRUE); + data->properties = NULL; +} + +static void +parse_data_free_interfaces (ParseData *data) +{ + if (data->interfaces == NULL) + return; + g_ptr_array_foreach (data->interfaces, (GFunc) g_dbus_interface_info_unref, NULL); + g_ptr_array_free (data->interfaces, TRUE); + data->interfaces = NULL; +} + +static void +parse_data_free_nodes (ParseData *data) +{ + if (data->nodes == NULL) + return; + g_ptr_array_foreach (data->nodes, (GFunc) g_dbus_node_info_unref, NULL); + g_ptr_array_free (data->nodes, TRUE); + data->nodes = NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAnnotationInfo * +parse_data_get_annotation (ParseData *data, + gboolean create_new) +{ + if (create_new) + g_ptr_array_add (data->annotations, g_new0 (GDBusAnnotationInfo, 1)); + return data->annotations->pdata[data->annotations->len - 1]; +} + +static GDBusArgInfo * +parse_data_get_arg (ParseData *data, + gboolean create_new) +{ + if (create_new) + g_ptr_array_add (data->args, g_new0 (GDBusArgInfo, 1)); + return data->args->pdata[data->args->len - 1]; +} + +static GDBusArgInfo * +parse_data_get_out_arg (ParseData *data, + gboolean create_new) +{ + if (create_new) + g_ptr_array_add (data->out_args, g_new0 (GDBusArgInfo, 1)); + return data->out_args->pdata[data->out_args->len - 1]; +} + +static GDBusMethodInfo * +parse_data_get_method (ParseData *data, + gboolean create_new) +{ + if (create_new) + g_ptr_array_add (data->methods, g_new0 (GDBusMethodInfo, 1)); + return data->methods->pdata[data->methods->len - 1]; +} + +static GDBusSignalInfo * +parse_data_get_signal (ParseData *data, + gboolean create_new) +{ + if (create_new) + g_ptr_array_add (data->signals, g_new0 (GDBusSignalInfo, 1)); + return data->signals->pdata[data->signals->len - 1]; +} + +static GDBusPropertyInfo * +parse_data_get_property (ParseData *data, + gboolean create_new) +{ + if (create_new) + g_ptr_array_add (data->properties, g_new0 (GDBusPropertyInfo, 1)); + return data->properties->pdata[data->properties->len - 1]; +} + +static GDBusInterfaceInfo * +parse_data_get_interface (ParseData *data, + gboolean create_new) +{ + if (create_new) + g_ptr_array_add (data->interfaces, g_new0 (GDBusInterfaceInfo, 1)); + return data->interfaces->pdata[data->interfaces->len - 1]; +} + +static GDBusNodeInfo * +parse_data_get_node (ParseData *data, + gboolean create_new) +{ + if (create_new) + g_ptr_array_add (data->nodes, g_new0 (GDBusNodeInfo, 1)); + return data->nodes->pdata[data->nodes->len - 1]; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static ParseData * +parse_data_new (void) +{ + ParseData *data; + + data = g_new0 (ParseData, 1); + + /* initialize arrays */ + parse_data_steal_annotations (data, NULL); + parse_data_steal_args (data, NULL); + parse_data_steal_out_args (data, NULL); + parse_data_steal_methods (data, NULL); + parse_data_steal_signals (data, NULL); + parse_data_steal_properties (data, NULL); + parse_data_steal_interfaces (data, NULL); + parse_data_steal_nodes (data, NULL); + + return data; +} + +static void +parse_data_free (ParseData *data) +{ + GSList *l; + + /* free stack of annotation arrays */ + for (l = data->annotations_stack; l != NULL; l = l->next) + { + GPtrArray *annotations = l->data; + g_ptr_array_foreach (annotations, (GFunc) g_dbus_annotation_info_unref, NULL); + g_ptr_array_free (annotations, TRUE); + } + g_slist_free (data->annotations_stack); + + /* free stack of interface arrays */ + for (l = data->interfaces_stack; l != NULL; l = l->next) + { + GPtrArray *interfaces = l->data; + g_ptr_array_foreach (interfaces, (GFunc) g_dbus_interface_info_unref, NULL); + g_ptr_array_free (interfaces, TRUE); + } + g_slist_free (data->interfaces_stack); + + /* free stack of node arrays */ + for (l = data->nodes_stack; l != NULL; l = l->next) + { + GPtrArray *nodes = l->data; + g_ptr_array_foreach (nodes, (GFunc) g_dbus_node_info_unref, NULL); + g_ptr_array_free (nodes, TRUE); + } + g_slist_free (data->nodes_stack); + + /* free arrays (data->annotations, data->interfaces and data->nodes have been freed above) */ + parse_data_free_args (data); + parse_data_free_out_args (data); + parse_data_free_methods (data); + parse_data_free_signals (data); + parse_data_free_properties (data); + parse_data_free_interfaces (data); + parse_data_free_annotations (data); + parse_data_free_nodes (data); + + g_free (data); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +parser_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseData *data = user_data; + GSList *stack; + const gchar *name; + const gchar *type; + const gchar *access; + const gchar *direction; + const gchar *value; + + name = NULL; + type = NULL; + access = NULL; + direction = NULL; + value = NULL; + + stack = (GSList *) g_markup_parse_context_get_element_stack (context); + + /* ---------------------------------------------------------------------------------------------------- */ + if (strcmp (element_name, "node") == 0) + { + if (!(g_slist_length (stack) >= 1 || strcmp (stack->next->data, "node") != 0)) + { + g_set_error_literal (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + " elements can only be top-level or embedded in other elements"); + goto out; + } + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "name", &name, + /* some hand-written introspection XML documents use this */ + G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "xmlns:doc", NULL, + G_MARKUP_COLLECT_INVALID)) + goto out; + + g_dbus_node_info_set (data, + parse_data_get_node (data, TRUE), + name, + NULL, + NULL, + NULL); + + /* push the currently retrieved interfaces and nodes on the stack and prepare new arrays */ + data->interfaces_stack = g_slist_prepend (data->interfaces_stack, data->interfaces); + data->interfaces = NULL; + parse_data_steal_interfaces (data, NULL); + + data->nodes_stack = g_slist_prepend (data->nodes_stack, data->nodes); + data->nodes = NULL; + parse_data_steal_nodes (data, NULL); + + } + /* ---------------------------------------------------------------------------------------------------- */ + else if (strcmp (element_name, "interface") == 0) + { + if (g_slist_length (stack) < 2 || strcmp (stack->next->data, "node") != 0) + { + g_set_error_literal (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + " elements can only be embedded in elements"); + goto out; + } + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING, "name", &name, + /* seen in the wild */ + G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "version", NULL, + G_MARKUP_COLLECT_INVALID)) + goto out; + + g_dbus_interface_info_set (data, + parse_data_get_interface (data, TRUE), + name, + NULL, + NULL, + NULL, + NULL); + + } + /* ---------------------------------------------------------------------------------------------------- */ + else if (strcmp (element_name, "method") == 0) + { + if (g_slist_length (stack) < 2 || strcmp (stack->next->data, "interface") != 0) + { + g_set_error_literal (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + " elements can only be embedded in elements"); + goto out; + } + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING, "name", &name, + /* seen in the wild */ + G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "version", NULL, + G_MARKUP_COLLECT_INVALID)) + goto out; + + g_dbus_method_info_set (data, + parse_data_get_method (data, TRUE), + name, + NULL, + NULL, + NULL); + + data->num_args = 0; + + } + /* ---------------------------------------------------------------------------------------------------- */ + else if (strcmp (element_name, "signal") == 0) + { + if (g_slist_length (stack) < 2 || strcmp (stack->next->data, "interface") != 0) + { + g_set_error_literal (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + " elements can only be embedded in elements"); + goto out; + } + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING, "name", &name, + G_MARKUP_COLLECT_INVALID)) + goto out; + + g_dbus_signal_info_set (data, + parse_data_get_signal (data, TRUE), + name, + NULL, + NULL); + + data->num_args = 0; + + } + /* ---------------------------------------------------------------------------------------------------- */ + else if (strcmp (element_name, "property") == 0) + { + GDBusPropertyInfoFlags flags; + + if (g_slist_length (stack) < 2 || strcmp (stack->next->data, "interface") != 0) + { + g_set_error_literal (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + " elements can only be embedded in elements"); + goto out; + } + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING, "name", &name, + G_MARKUP_COLLECT_STRING, "type", &type, + G_MARKUP_COLLECT_STRING, "access", &access, + G_MARKUP_COLLECT_INVALID)) + goto out; + + if (strcmp (access, "read") == 0) + flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE; + else if (strcmp (access, "write") == 0) + flags = G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE; + else if (strcmp (access, "readwrite") == 0) + flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE; + else + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Unknown value '%s' of access attribute for element ", + access); + goto out; + } + + g_dbus_property_info_set (data, + parse_data_get_property (data, TRUE), + name, + type, + flags, + NULL); + + } + /* ---------------------------------------------------------------------------------------------------- */ + else if (strcmp (element_name, "arg") == 0) + { + gboolean is_in; + gchar *name_to_use; + + if (g_slist_length (stack) < 2 || + (strcmp (stack->next->data, "method") != 0 && + strcmp (stack->next->data, "signal") != 0)) + { + g_set_error_literal (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + " elements can only be embedded in or elements"); + goto out; + } + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "name", &name, + G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "direction", &direction, + G_MARKUP_COLLECT_STRING, "type", &type, + G_MARKUP_COLLECT_INVALID)) + goto out; + + if (strcmp (stack->next->data, "method") == 0) + is_in = TRUE; + else + is_in = FALSE; + if (direction != NULL) + { + if (strcmp (direction, "in") == 0) + is_in = TRUE; + else if (strcmp (direction, "out") == 0) + is_in = FALSE; + else + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Unknown value '%s' of direction attribute", + direction); + goto out; + } + } + + if (is_in && strcmp (stack->next->data, "signal") == 0) + { + g_set_error_literal (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Only direction 'out' is allowed for elements embedded in "); + goto out; + } + + if (name == NULL) + name_to_use = g_strdup_printf ("arg_%d", data->num_args); + else + name_to_use = g_strdup (name); + data->num_args++; + + if (is_in) + { + g_dbus_arg_info_set (data, + parse_data_get_arg (data, TRUE), + name_to_use, + type, + NULL); + data->last_arg_was_in = TRUE; + } + else + { + g_dbus_arg_info_set (data, + parse_data_get_out_arg (data, TRUE), + name_to_use, + type, + NULL); + data->last_arg_was_in = FALSE; + + } + + g_free (name_to_use); + } + /* ---------------------------------------------------------------------------------------------------- */ + else if (strcmp (element_name, "annotation") == 0) + { + if (g_slist_length (stack) < 2 || + (strcmp (stack->next->data, "node") != 0 && + strcmp (stack->next->data, "interface") != 0 && + strcmp (stack->next->data, "signal") != 0 && + strcmp (stack->next->data, "method") != 0 && + strcmp (stack->next->data, "property") != 0 && + strcmp (stack->next->data, "arg") != 0 && + strcmp (stack->next->data, "annotation") != 0)) + { + g_set_error_literal (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + " elements can only be embedded in , , , , , or elements"); + goto out; + } + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING, "name", &name, + G_MARKUP_COLLECT_STRING, "value", &value, + G_MARKUP_COLLECT_INVALID)) + goto out; + + g_dbus_annotation_info_set (data, + parse_data_get_annotation (data, TRUE), + name, + value, + NULL); + } + /* ---------------------------------------------------------------------------------------------------- */ + else + { + /* don't bail on unknown elements; just ignore them */ + } + /* ---------------------------------------------------------------------------------------------------- */ + + /* push the currently retrieved annotations on the stack and prepare a new one */ + data->annotations_stack = g_slist_prepend (data->annotations_stack, data->annotations); + data->annotations = NULL; + parse_data_steal_annotations (data, NULL); + + out: + ; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusAnnotationInfo ** +steal_annotations (ParseData *data) +{ + return parse_data_steal_annotations (data, NULL); +} + + +static void +parser_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseData *data = user_data; + gboolean have_popped_annotations; + + have_popped_annotations = FALSE; + + if (strcmp (element_name, "node") == 0) + { + guint num_nodes; + guint num_interfaces; + GDBusNodeInfo **nodes; + GDBusInterfaceInfo **interfaces; + + nodes = parse_data_steal_nodes (data, &num_nodes); + interfaces = parse_data_steal_interfaces (data, &num_interfaces); + + /* destroy the nodes, interfaces for scope we're exiting and and pop the nodes, interfaces from the + * scope we're reentering + */ + parse_data_free_interfaces (data); + data->interfaces = (GPtrArray *) data->interfaces_stack->data; + data->interfaces_stack = g_slist_remove (data->interfaces_stack, data->interfaces_stack->data); + + parse_data_free_nodes (data); + data->nodes = (GPtrArray *) data->nodes_stack->data; + data->nodes_stack = g_slist_remove (data->nodes_stack, data->nodes_stack->data); + + g_dbus_node_info_set (data, + parse_data_get_node (data, FALSE), + NULL, + interfaces, + nodes, + steal_annotations (data)); + + } + else if (strcmp (element_name, "interface") == 0) + { + guint num_methods; + guint num_signals; + guint num_properties; + GDBusMethodInfo **methods; + GDBusSignalInfo **signals; + GDBusPropertyInfo **properties; + + methods = parse_data_steal_methods (data, &num_methods); + signals = parse_data_steal_signals (data, &num_signals); + properties = parse_data_steal_properties (data, &num_properties); + + g_dbus_interface_info_set (data, + parse_data_get_interface (data, FALSE), + NULL, + methods, + signals, + properties, + steal_annotations (data)); + + } + else if (strcmp (element_name, "method") == 0) + { + guint in_num_args; + guint out_num_args; + GDBusArgInfo **in_args; + GDBusArgInfo **out_args; + + in_args = parse_data_steal_args (data, &in_num_args); + out_args = parse_data_steal_out_args (data, &out_num_args); + + g_dbus_method_info_set (data, + parse_data_get_method (data, FALSE), + NULL, + in_args, + out_args, + steal_annotations (data)); + } + else if (strcmp (element_name, "signal") == 0) + { + guint num_args; + GDBusArgInfo **args; + + args = parse_data_steal_out_args (data, &num_args); + + g_dbus_signal_info_set (data, + parse_data_get_signal (data, FALSE), + NULL, + args, + steal_annotations (data)); + } + else if (strcmp (element_name, "property") == 0) + { + g_dbus_property_info_set (data, + parse_data_get_property (data, FALSE), + NULL, + NULL, + G_DBUS_PROPERTY_INFO_FLAGS_NONE, + steal_annotations (data)); + } + else if (strcmp (element_name, "arg") == 0) + { + g_dbus_arg_info_set (data, + data->last_arg_was_in ? parse_data_get_arg (data, FALSE) : parse_data_get_out_arg (data, FALSE), + NULL, + NULL, + steal_annotations (data)); + } + else if (strcmp (element_name, "annotation") == 0) + { + GDBusAnnotationInfo **embedded_annotations; + + embedded_annotations = steal_annotations (data); + + /* destroy the annotations for scope we're exiting and and pop the annotations from the scope we're reentering */ + parse_data_free_annotations (data); + data->annotations = (GPtrArray *) data->annotations_stack->data; + data->annotations_stack = g_slist_remove (data->annotations_stack, data->annotations_stack->data); + + have_popped_annotations = TRUE; + + g_dbus_annotation_info_set (data, + parse_data_get_annotation (data, FALSE), + NULL, + NULL, + embedded_annotations); + } + else + { + /* don't bail on unknown elements; just ignore them */ + } + + if (!have_popped_annotations) + { + /* destroy the annotations for scope we're exiting and and pop the annotations from the scope we're reentering */ + parse_data_free_annotations (data); + data->annotations = (GPtrArray *) data->annotations_stack->data; + data->annotations_stack = g_slist_remove (data->annotations_stack, data->annotations_stack->data); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +parser_error (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ + gint line_number; + gint char_number; + + g_markup_parse_context_get_position (context, &line_number, &char_number); + + g_prefix_error (&error, "%d:%d: ", + line_number, + char_number); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_node_info_new_for_xml: + * @xml_data: Valid D-Bus introspection XML. + * @error: Return location for error. + * + * Parses @xml_data and returns a #GDBusNodeInfo representing the data. + * + * The introspection XML must contain exactly one top-level + * element. + * + * Note that this routine is using a + * [GMarkup][glib-Simple-XML-Subset-Parser.description]-based + * parser that only accepts a subset of valid XML documents. + * + * Returns: A #GDBusNodeInfo structure or %NULL if @error is set. Free + * with g_dbus_node_info_unref(). + * + * Since: 2.26 + */ +GDBusNodeInfo * +g_dbus_node_info_new_for_xml (const gchar *xml_data, + GError **error) +{ + GDBusNodeInfo *ret; + GMarkupParseContext *context; + GMarkupParser *parser; + guint num_nodes; + ParseData *data; + GDBusNodeInfo **ughret; + + ret = NULL; + parser = NULL; + context = NULL; + + parser = g_new0 (GMarkupParser, 1); + parser->start_element = parser_start_element; + parser->end_element = parser_end_element; + parser->error = parser_error; + + data = parse_data_new (); + context = g_markup_parse_context_new (parser, + G_MARKUP_IGNORE_QUALIFIED, + data, + (GDestroyNotify) parse_data_free); + + if (!g_markup_parse_context_parse (context, + xml_data, + strlen (xml_data), + error)) + goto out; + + if (!g_markup_parse_context_end_parse (context, error)) + goto out; + + ughret = parse_data_steal_nodes (data, &num_nodes); + + if (num_nodes != 1) + { + guint n; + + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Expected a single node in introspection XML, found %d", + num_nodes); + + /* clean up */ + for (n = 0; n < num_nodes; n++) + { + g_dbus_node_info_unref (ughret[n]); + ughret[n] = NULL; + } + } + + ret = ughret[0]; + g_free (ughret); + + out: + g_free (parser); + if (context != NULL) + g_markup_parse_context_free (context); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_annotation_info_lookup: + * @annotations: (array zero-terminated=1) (nullable): A %NULL-terminated array of annotations or %NULL. + * @name: The name of the annotation to look up. + * + * Looks up the value of an annotation. + * + * The cost of this function is O(n) in number of annotations. + * + * Returns: (nullable): The value or %NULL if not found. Do not free, it is owned by @annotations. + * + * Since: 2.26 + */ +const gchar * +g_dbus_annotation_info_lookup (GDBusAnnotationInfo **annotations, + const gchar *name) +{ + guint n; + const gchar *ret; + + ret = NULL; + for (n = 0; annotations != NULL && annotations[n] != NULL; n++) + { + if (g_strcmp0 (annotations[n]->key, name) == 0) + { + ret = annotations[n]->value; + goto out; + } + } + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +G_LOCK_DEFINE_STATIC (info_cache_lock); + +typedef struct +{ + gint use_count; + + /* gchar* -> GDBusMethodInfo* */ + GHashTable *method_name_to_data; + + /* gchar* -> GDBusMethodInfo* */ + GHashTable *signal_name_to_data; + + /* gchar* -> GDBusMethodInfo* */ + GHashTable *property_name_to_data; +} InfoCacheEntry; + +static void +info_cache_free (InfoCacheEntry *cache) +{ + g_assert (cache->use_count == 0); + g_hash_table_unref (cache->method_name_to_data); + g_hash_table_unref (cache->signal_name_to_data); + g_hash_table_unref (cache->property_name_to_data); + g_slice_free (InfoCacheEntry, cache); +} + +/* maps from GDBusInterfaceInfo* to InfoCacheEntry* */ +static GHashTable *info_cache = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_interface_info_lookup_method: + * @info: A #GDBusInterfaceInfo. + * @name: A D-Bus method name (typically in CamelCase) + * + * Looks up information about a method. + * + * The cost of this function is O(n) in number of methods unless + * g_dbus_interface_info_cache_build() has been used on @info. + * + * Returns: (nullable) (transfer none): A #GDBusMethodInfo or %NULL if not found. Do not free, it is owned by @info. + * + * Since: 2.26 + */ +GDBusMethodInfo * +g_dbus_interface_info_lookup_method (GDBusInterfaceInfo *info, + const gchar *name) +{ + guint n; + GDBusMethodInfo *result; + + G_LOCK (info_cache_lock); + if (G_LIKELY (info_cache != NULL)) + { + InfoCacheEntry *cache; + cache = g_hash_table_lookup (info_cache, info); + if (G_LIKELY (cache != NULL)) + { + result = g_hash_table_lookup (cache->method_name_to_data, name); + G_UNLOCK (info_cache_lock); + goto out; + } + } + G_UNLOCK (info_cache_lock); + + for (n = 0; info->methods != NULL && info->methods[n] != NULL; n++) + { + GDBusMethodInfo *i = info->methods[n]; + + if (g_strcmp0 (i->name, name) == 0) + { + result = i; + goto out; + } + } + + result = NULL; + + out: + return result; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_interface_info_lookup_signal: + * @info: A #GDBusInterfaceInfo. + * @name: A D-Bus signal name (typically in CamelCase) + * + * Looks up information about a signal. + * + * The cost of this function is O(n) in number of signals unless + * g_dbus_interface_info_cache_build() has been used on @info. + * + * Returns: (nullable) (transfer none): A #GDBusSignalInfo or %NULL if not found. Do not free, it is owned by @info. + * + * Since: 2.26 + */ +GDBusSignalInfo * +g_dbus_interface_info_lookup_signal (GDBusInterfaceInfo *info, + const gchar *name) +{ + guint n; + GDBusSignalInfo *result; + + G_LOCK (info_cache_lock); + if (G_LIKELY (info_cache != NULL)) + { + InfoCacheEntry *cache; + cache = g_hash_table_lookup (info_cache, info); + if (G_LIKELY (cache != NULL)) + { + result = g_hash_table_lookup (cache->signal_name_to_data, name); + G_UNLOCK (info_cache_lock); + goto out; + } + } + G_UNLOCK (info_cache_lock); + + for (n = 0; info->signals != NULL && info->signals[n] != NULL; n++) + { + GDBusSignalInfo *i = info->signals[n]; + + if (g_strcmp0 (i->name, name) == 0) + { + result = i; + goto out; + } + } + + result = NULL; + + out: + return result; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_interface_info_lookup_property: + * @info: A #GDBusInterfaceInfo. + * @name: A D-Bus property name (typically in CamelCase). + * + * Looks up information about a property. + * + * The cost of this function is O(n) in number of properties unless + * g_dbus_interface_info_cache_build() has been used on @info. + * + * Returns: (nullable) (transfer none): A #GDBusPropertyInfo or %NULL if not found. Do not free, it is owned by @info. + * + * Since: 2.26 + */ +GDBusPropertyInfo * +g_dbus_interface_info_lookup_property (GDBusInterfaceInfo *info, + const gchar *name) +{ + guint n; + GDBusPropertyInfo *result; + + G_LOCK (info_cache_lock); + if (G_LIKELY (info_cache != NULL)) + { + InfoCacheEntry *cache; + cache = g_hash_table_lookup (info_cache, info); + if (G_LIKELY (cache != NULL)) + { + result = g_hash_table_lookup (cache->property_name_to_data, name); + G_UNLOCK (info_cache_lock); + goto out; + } + } + G_UNLOCK (info_cache_lock); + + for (n = 0; info->properties != NULL && info->properties[n] != NULL; n++) + { + GDBusPropertyInfo *i = info->properties[n]; + + if (g_strcmp0 (i->name, name) == 0) + { + result = i; + goto out; + } + } + + result = NULL; + + out: + return result; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_interface_info_cache_build: + * @info: A #GDBusInterfaceInfo. + * + * Builds a lookup-cache to speed up + * g_dbus_interface_info_lookup_method(), + * g_dbus_interface_info_lookup_signal() and + * g_dbus_interface_info_lookup_property(). + * + * If this has already been called with @info, the existing cache is + * used and its use count is increased. + * + * Note that @info cannot be modified until + * g_dbus_interface_info_cache_release() is called. + * + * Since: 2.30 + */ +void +g_dbus_interface_info_cache_build (GDBusInterfaceInfo *info) +{ + InfoCacheEntry *cache; + guint n; + + G_LOCK (info_cache_lock); + if (info_cache == NULL) + info_cache = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) info_cache_free); + cache = g_hash_table_lookup (info_cache, info); + if (cache != NULL) + { + cache->use_count += 1; + goto out; + } + cache = g_slice_new0 (InfoCacheEntry); + cache->use_count = 1; + cache->method_name_to_data = g_hash_table_new (g_str_hash, g_str_equal); + cache->signal_name_to_data = g_hash_table_new (g_str_hash, g_str_equal); + cache->property_name_to_data = g_hash_table_new (g_str_hash, g_str_equal); + for (n = 0; info->methods != NULL && info->methods[n] != NULL; n++) + g_hash_table_insert (cache->method_name_to_data, info->methods[n]->name, info->methods[n]); + for (n = 0; info->signals != NULL && info->signals[n] != NULL; n++) + g_hash_table_insert (cache->signal_name_to_data, info->signals[n]->name, info->signals[n]); + for (n = 0; info->properties != NULL && info->properties[n] != NULL; n++) + g_hash_table_insert (cache->property_name_to_data, info->properties[n]->name, info->properties[n]); + g_hash_table_insert (info_cache, info, cache); + out: + G_UNLOCK (info_cache_lock); +} + +/** + * g_dbus_interface_info_cache_release: + * @info: A GDBusInterfaceInfo + * + * Decrements the usage count for the cache for @info built by + * g_dbus_interface_info_cache_build() (if any) and frees the + * resources used by the cache if the usage count drops to zero. + * + * Since: 2.30 + */ +void +g_dbus_interface_info_cache_release (GDBusInterfaceInfo *info) +{ + InfoCacheEntry *cache; + + G_LOCK (info_cache_lock); + if (G_UNLIKELY (info_cache == NULL)) + { + g_warning ("%s called for interface %s but there is no cache", info->name, G_STRFUNC); + goto out; + } + + cache = g_hash_table_lookup (info_cache, info); + if (G_UNLIKELY (cache == NULL)) + { + g_warning ("%s called for interface %s but there is no cache entry", info->name, G_STRFUNC); + goto out; + } + cache->use_count -= 1; + if (cache->use_count == 0) + { + g_hash_table_remove (info_cache, info); + /* could nuke info_cache itself if empty */ + } + out: + G_UNLOCK (info_cache_lock); +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_node_info_lookup_interface: + * @info: A #GDBusNodeInfo. + * @name: A D-Bus interface name. + * + * Looks up information about an interface. + * + * The cost of this function is O(n) in number of interfaces. + * + * Returns: (nullable) (transfer none): A #GDBusInterfaceInfo or %NULL if not found. Do not free, it is owned by @info. + * + * Since: 2.26 + */ +GDBusInterfaceInfo * +g_dbus_node_info_lookup_interface (GDBusNodeInfo *info, + const gchar *name) +{ + guint n; + GDBusInterfaceInfo *result; + + for (n = 0; info->interfaces != NULL && info->interfaces[n] != NULL; n++) + { + GDBusInterfaceInfo *i = info->interfaces[n]; + + if (g_strcmp0 (i->name, name) == 0) + { + result = i; + goto out; + } + } + + result = NULL; + + out: + return result; +} diff --git a/gio/gdbusintrospection.h b/gio/gdbusintrospection.h new file mode 100644 index 0000000..f2e2917 --- /dev/null +++ b/gio/gdbusintrospection.h @@ -0,0 +1,325 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_INTROSPECTION_H__ +#define __G_DBUS_INTROSPECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * GDBusAnnotationInfo: + * @ref_count: The reference count or -1 if statically allocated. + * @key: The name of the annotation, e.g. "org.freedesktop.DBus.Deprecated". + * @value: The value of the annotation. + * @annotations: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusAnnotationInfo structures or %NULL if there are no annotations. + * + * Information about an annotation. + * + * Since: 2.26 + */ +struct _GDBusAnnotationInfo +{ + /*< public >*/ + gint ref_count; /* (atomic) */ + gchar *key; + gchar *value; + GDBusAnnotationInfo **annotations; +}; + +/** + * GDBusArgInfo: + * @ref_count: The reference count or -1 if statically allocated. + * @name: Name of the argument, e.g. @unix_user_id. + * @signature: D-Bus signature of the argument (a single complete type). + * @annotations: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusAnnotationInfo structures or %NULL if there are no annotations. + * + * Information about an argument for a method or a signal. + * + * Since: 2.26 + */ +struct _GDBusArgInfo +{ + /*< public >*/ + gint ref_count; /* (atomic) */ + gchar *name; + gchar *signature; + GDBusAnnotationInfo **annotations; +}; + +/** + * GDBusMethodInfo: + * @ref_count: The reference count or -1 if statically allocated. + * @name: The name of the D-Bus method, e.g. @RequestName. + * @in_args: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusArgInfo structures or %NULL if there are no in arguments. + * @out_args: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusArgInfo structures or %NULL if there are no out arguments. + * @annotations: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusAnnotationInfo structures or %NULL if there are no annotations. + * + * Information about a method on an D-Bus interface. + * + * Since: 2.26 + */ +struct _GDBusMethodInfo +{ + /*< public >*/ + gint ref_count; /* (atomic) */ + gchar *name; + GDBusArgInfo **in_args; + GDBusArgInfo **out_args; + GDBusAnnotationInfo **annotations; +}; + +/** + * GDBusSignalInfo: + * @ref_count: The reference count or -1 if statically allocated. + * @name: The name of the D-Bus signal, e.g. "NameOwnerChanged". + * @args: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusArgInfo structures or %NULL if there are no arguments. + * @annotations: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusAnnotationInfo structures or %NULL if there are no annotations. + * + * Information about a signal on a D-Bus interface. + * + * Since: 2.26 + */ +struct _GDBusSignalInfo +{ + /*< public >*/ + gint ref_count; /* (atomic) */ + gchar *name; + GDBusArgInfo **args; + GDBusAnnotationInfo **annotations; +}; + +/** + * GDBusPropertyInfo: + * @ref_count: The reference count or -1 if statically allocated. + * @name: The name of the D-Bus property, e.g. "SupportedFilesystems". + * @signature: The D-Bus signature of the property (a single complete type). + * @flags: Access control flags for the property. + * @annotations: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusAnnotationInfo structures or %NULL if there are no annotations. + * + * Information about a D-Bus property on a D-Bus interface. + * + * Since: 2.26 + */ +struct _GDBusPropertyInfo +{ + /*< public >*/ + gint ref_count; /* (atomic) */ + gchar *name; + gchar *signature; + GDBusPropertyInfoFlags flags; + GDBusAnnotationInfo **annotations; +}; + +/** + * GDBusInterfaceInfo: + * @ref_count: The reference count or -1 if statically allocated. + * @name: The name of the D-Bus interface, e.g. "org.freedesktop.DBus.Properties". + * @methods: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusMethodInfo structures or %NULL if there are no methods. + * @signals: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusSignalInfo structures or %NULL if there are no signals. + * @properties: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusPropertyInfo structures or %NULL if there are no properties. + * @annotations: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusAnnotationInfo structures or %NULL if there are no annotations. + * + * Information about a D-Bus interface. + * + * Since: 2.26 + */ +struct _GDBusInterfaceInfo +{ + /*< public >*/ + gint ref_count; /* (atomic) */ + gchar *name; + GDBusMethodInfo **methods; + GDBusSignalInfo **signals; + GDBusPropertyInfo **properties; + GDBusAnnotationInfo **annotations; +}; + +/** + * GDBusNodeInfo: + * @ref_count: The reference count or -1 if statically allocated. + * @path: The path of the node or %NULL if omitted. Note that this may be a relative path. See the D-Bus specification for more details. + * @interfaces: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusInterfaceInfo structures or %NULL if there are no interfaces. + * @nodes: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusNodeInfo structures or %NULL if there are no nodes. + * @annotations: (array zero-terminated=1): A pointer to a %NULL-terminated array of pointers to #GDBusAnnotationInfo structures or %NULL if there are no annotations. + * + * Information about nodes in a remote object hierarchy. + * + * Since: 2.26 + */ +struct _GDBusNodeInfo +{ + /*< public >*/ + gint ref_count; /* (atomic) */ + gchar *path; + GDBusInterfaceInfo **interfaces; + GDBusNodeInfo **nodes; + GDBusAnnotationInfo **annotations; +}; + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_annotation_info_lookup (GDBusAnnotationInfo **annotations, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +GDBusMethodInfo *g_dbus_interface_info_lookup_method (GDBusInterfaceInfo *info, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +GDBusSignalInfo *g_dbus_interface_info_lookup_signal (GDBusInterfaceInfo *info, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +GDBusPropertyInfo *g_dbus_interface_info_lookup_property (GDBusInterfaceInfo *info, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_info_cache_build (GDBusInterfaceInfo *info); +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_info_cache_release (GDBusInterfaceInfo *info); + +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_info_generate_xml (GDBusInterfaceInfo *info, + guint indent, + GString *string_builder); + +GLIB_AVAILABLE_IN_ALL +GDBusNodeInfo *g_dbus_node_info_new_for_xml (const gchar *xml_data, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusInterfaceInfo *g_dbus_node_info_lookup_interface (GDBusNodeInfo *info, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +void g_dbus_node_info_generate_xml (GDBusNodeInfo *info, + guint indent, + GString *string_builder); + +GLIB_AVAILABLE_IN_ALL +GDBusNodeInfo *g_dbus_node_info_ref (GDBusNodeInfo *info); +GLIB_AVAILABLE_IN_ALL +GDBusInterfaceInfo *g_dbus_interface_info_ref (GDBusInterfaceInfo *info); +GLIB_AVAILABLE_IN_ALL +GDBusMethodInfo *g_dbus_method_info_ref (GDBusMethodInfo *info); +GLIB_AVAILABLE_IN_ALL +GDBusSignalInfo *g_dbus_signal_info_ref (GDBusSignalInfo *info); +GLIB_AVAILABLE_IN_ALL +GDBusPropertyInfo *g_dbus_property_info_ref (GDBusPropertyInfo *info); +GLIB_AVAILABLE_IN_ALL +GDBusArgInfo *g_dbus_arg_info_ref (GDBusArgInfo *info); +GLIB_AVAILABLE_IN_ALL +GDBusAnnotationInfo *g_dbus_annotation_info_ref (GDBusAnnotationInfo *info); + +GLIB_AVAILABLE_IN_ALL +void g_dbus_node_info_unref (GDBusNodeInfo *info); +GLIB_AVAILABLE_IN_ALL +void g_dbus_interface_info_unref (GDBusInterfaceInfo *info); +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_info_unref (GDBusMethodInfo *info); +GLIB_AVAILABLE_IN_ALL +void g_dbus_signal_info_unref (GDBusSignalInfo *info); +GLIB_AVAILABLE_IN_ALL +void g_dbus_property_info_unref (GDBusPropertyInfo *info); +GLIB_AVAILABLE_IN_ALL +void g_dbus_arg_info_unref (GDBusArgInfo *info); +GLIB_AVAILABLE_IN_ALL +void g_dbus_annotation_info_unref (GDBusAnnotationInfo *info); + +/** + * G_TYPE_DBUS_NODE_INFO: + * + * The #GType for a boxed type holding a #GDBusNodeInfo. + * + * Since: 2.26 + */ +#define G_TYPE_DBUS_NODE_INFO (g_dbus_node_info_get_type ()) + +/** + * G_TYPE_DBUS_INTERFACE_INFO: + * + * The #GType for a boxed type holding a #GDBusInterfaceInfo. + * + * Since: 2.26 + */ +#define G_TYPE_DBUS_INTERFACE_INFO (g_dbus_interface_info_get_type ()) + +/** + * G_TYPE_DBUS_METHOD_INFO: + * + * The #GType for a boxed type holding a #GDBusMethodInfo. + * + * Since: 2.26 + */ +#define G_TYPE_DBUS_METHOD_INFO (g_dbus_method_info_get_type ()) + +/** + * G_TYPE_DBUS_SIGNAL_INFO: + * + * The #GType for a boxed type holding a #GDBusSignalInfo. + * + * Since: 2.26 + */ +#define G_TYPE_DBUS_SIGNAL_INFO (g_dbus_signal_info_get_type ()) + +/** + * G_TYPE_DBUS_PROPERTY_INFO: + * + * The #GType for a boxed type holding a #GDBusPropertyInfo. + * + * Since: 2.26 + */ +#define G_TYPE_DBUS_PROPERTY_INFO (g_dbus_property_info_get_type ()) + +/** + * G_TYPE_DBUS_ARG_INFO: + * + * The #GType for a boxed type holding a #GDBusArgInfo. + * + * Since: 2.26 + */ +#define G_TYPE_DBUS_ARG_INFO (g_dbus_arg_info_get_type ()) + +/** + * G_TYPE_DBUS_ANNOTATION_INFO: + * + * The #GType for a boxed type holding a #GDBusAnnotationInfo. + * + * Since: 2.26 + */ +#define G_TYPE_DBUS_ANNOTATION_INFO (g_dbus_annotation_info_get_type ()) + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_node_info_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_dbus_interface_info_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_dbus_method_info_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_dbus_signal_info_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_dbus_property_info_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_dbus_arg_info_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_dbus_annotation_info_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __G_DBUS_INTROSPECTION_H__ */ diff --git a/gio/gdbusmenumodel.c b/gio/gdbusmenumodel.c new file mode 100644 index 0000000..e29614a --- /dev/null +++ b/gio/gdbusmenumodel.c @@ -0,0 +1,940 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gdbusmenumodel.h" + +#include "gmenumodel.h" + +/* Prelude {{{1 */ + +/** + * SECTION:gdbusmenumodel + * @title: GDBusMenuModel + * @short_description: A D-Bus GMenuModel implementation + * @include: gio/gio.h + * @see_also: [GMenuModel Exporter][gio-GMenuModel-exporter] + * + * #GDBusMenuModel is an implementation of #GMenuModel that can be used + * as a proxy for a menu model that is exported over D-Bus with + * g_dbus_connection_export_menu_model(). + */ + +/** + * GDBusMenuModel: + * + * #GDBusMenuModel is an opaque data structure and can only be accessed + * using the following functions. + */ + +/* + * There are 3 main (quasi-)classes involved here: + * + * - GDBusMenuPath + * - GDBusMenuGroup + * - GDBusMenuModel + * + * Each of these classes exists as a parameterised singleton keyed to a + * particular thing: + * + * - GDBusMenuPath represents a D-Bus object path on a particular + * unique bus name on a particular GDBusConnection and in a + * particular GMainContext. + * + * - GDBusMenuGroup represents a particular group on a particular + * GDBusMenuPath. + * + * - GDBusMenuModel represents a particular menu within a particular + * GDBusMenuGroup. + * + * There are also two (and a half) utility structs: + * + * - PathIdentifier and ConstPathIdentifier + * - GDBusMenuModelItem + * + * PathIdentifier is the 4-tuple of (GMainContext, GDBusConnection, + * unique name, object path) that uniquely identifies a particular + * GDBusMenuPath. It holds ownership on each of these things, so we + * have a ConstPathIdentifier variant that does not. + * + * We have a 3-level hierarchy of hashtables: + * + * - a global hashtable (g_dbus_menu_paths) maps from PathIdentifier + * to GDBusMenuPath + * + * - each GDBusMenuPath has a hashtable mapping from guint (group + * number) to GDBusMenuGroup + * + * - each GDBusMenuGroup has a hashtable mapping from guint (menu + * number) to GDBusMenuModel. + * + * In this way, each quintuplet of (connection, bus name, object path, + * group id, menu id) maps to a single GDBusMenuModel instance that can be + * located via 3 hashtable lookups. + * + * All of the 3 classes are refcounted (GDBusMenuPath and + * GDBusMenuGroup manually, and GDBusMenuModel by virtue of being a + * GObject). The hashtables do not hold references -- rather, when the + * last reference is dropped, the object is removed from the hashtable. + * + * The hard references go in the other direction: GDBusMenuModel is created + * as the user requests it and only exists as long as the user holds a + * reference on it. GDBusMenuModel holds a reference on the GDBusMenuGroup + * from which it came. GDBusMenuGroup holds a reference on + * GDBusMenuPath. + * + * In addition to refcounts, each object has an 'active' variable (ints + * for GDBusMenuPath and GDBusMenuGroup, boolean for GDBusMenuModel). + * + * - GDBusMenuModel is inactive when created and becomes active only when + * first queried for information. This prevents extra work from + * happening just by someone acquiring a GDBusMenuModel (and not + * actually trying to display it yet). + * + * - The active count on GDBusMenuGroup is equal to the number of + * GDBusMenuModel instances in that group that are active. When the + * active count transitions from 0 to 1, the group calls the 'Start' + * method on the service to begin monitoring that group. When it + * drops from 1 to 0, the group calls the 'End' method to stop + * monitoring. + * + * - The active count on GDBusMenuPath is equal to the number of + * GDBusMenuGroup instances on that path with a non-zero active + * count. When the active count transitions from 0 to 1, the path + * sets up a signal subscription to monitor any changes. The signal + * subscription is taken down when the active count transitions from + * 1 to 0. + * + * When active, GDBusMenuPath gets incoming signals when changes occur. + * If the change signal mentions a group for which we currently have an + * active GDBusMenuGroup, the change signal is passed along to that + * group. If the group is inactive, the change signal is ignored. + * + * Most of the "work" occurs in GDBusMenuGroup. In addition to the + * hashtable of GDBusMenuModel instances, it keeps a hashtable of the actual + * menu contents, each encoded as GSequence of GDBusMenuModelItem. It + * initially populates this table with the results of the "Start" method + * call and then updates it according to incoming change signals. If + * the change signal mentions a menu for which we current have an active + * GDBusMenuModel, the change signal is passed along to that model. If the + * model is inactive, the change signal is ignored. + * + * GDBusMenuModelItem is just a pair of hashtables, one for the attributes + * and one for the links of the item. Both map strings to GVariant + * instances. In the case of links, the GVariant has type '(uu)' and is + * turned into a GDBusMenuModel at the point that the user pulls it through + * the API. + * + * Following the "empty is the same as non-existent" rule, the hashtable + * of GSequence of GDBusMenuModelItem holds NULL for empty menus. + * + * GDBusMenuModel contains very little functionality of its own. It holds a + * (weak) reference to the GSequence of GDBusMenuModelItem contained in the + * GDBusMenuGroup. It uses this GSequence to implement the GMenuModel + * interface. It also emits the "items-changed" signal if it is active + * and it was told that the contents of the GSequence changed. + */ + +typedef struct _GDBusMenuGroup GDBusMenuGroup; +typedef struct _GDBusMenuPath GDBusMenuPath; + +static void g_dbus_menu_group_changed (GDBusMenuGroup *group, + guint menu_id, + gint position, + gint removed, + GVariant *added); +static void g_dbus_menu_model_changed (GDBusMenuModel *proxy, + GSequence *items, + gint position, + gint removed, + gint added); +static GDBusMenuGroup * g_dbus_menu_group_get_from_path (GDBusMenuPath *path, + guint group_id); +static GDBusMenuModel * g_dbus_menu_model_get_from_group (GDBusMenuGroup *group, + guint menu_id); + +/* PathIdentifier {{{1 */ +typedef struct +{ + GMainContext *context; + GDBusConnection *connection; + gchar *bus_name; + gchar *object_path; +} PathIdentifier; + +typedef const struct +{ + GMainContext *context; + GDBusConnection *connection; + const gchar *bus_name; + const gchar *object_path; +} ConstPathIdentifier; + +static guint +path_identifier_hash (gconstpointer data) +{ + ConstPathIdentifier *id = data; + + return g_str_hash (id->object_path); +} + +static gboolean +path_identifier_equal (gconstpointer a, + gconstpointer b) +{ + ConstPathIdentifier *id_a = a; + ConstPathIdentifier *id_b = b; + + return id_a->connection == id_b->connection && + g_strcmp0 (id_a->bus_name, id_b->bus_name) == 0 && + g_str_equal (id_a->object_path, id_b->object_path); +} + +static void +path_identifier_free (PathIdentifier *id) +{ + g_main_context_unref (id->context); + g_object_unref (id->connection); + g_free (id->bus_name); + g_free (id->object_path); + + g_slice_free (PathIdentifier, id); +} + +static PathIdentifier * +path_identifier_new (ConstPathIdentifier *cid) +{ + PathIdentifier *id; + + id = g_slice_new (PathIdentifier); + id->context = g_main_context_ref (cid->context); + id->connection = g_object_ref (cid->connection); + id->bus_name = g_strdup (cid->bus_name); + id->object_path = g_strdup (cid->object_path); + + return id; +} + +/* GDBusMenuPath {{{1 */ + +struct _GDBusMenuPath +{ + PathIdentifier *id; + gint ref_count; + + GHashTable *groups; + gint active; + guint watch_id; +}; + +static GHashTable *g_dbus_menu_paths; + +static GDBusMenuPath * +g_dbus_menu_path_ref (GDBusMenuPath *path) +{ + path->ref_count++; + + return path; +} + +static void +g_dbus_menu_path_unref (GDBusMenuPath *path) +{ + if (--path->ref_count == 0) + { + g_hash_table_remove (g_dbus_menu_paths, path->id); + g_hash_table_unref (path->groups); + path_identifier_free (path->id); + + g_slice_free (GDBusMenuPath, path); + } +} + +static void +g_dbus_menu_path_signal (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GDBusMenuPath *path = user_data; + GVariantIter *iter; + guint group_id; + guint menu_id; + guint position; + guint removes; + GVariant *adds; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a(uuuuaa{sv}))"))) + return; + + g_variant_get (parameters, "(a(uuuuaa{sv}))", &iter); + while (g_variant_iter_loop (iter, "(uuuu@aa{sv})", &group_id, &menu_id, &position, &removes, &adds)) + { + GDBusMenuGroup *group; + + group = g_hash_table_lookup (path->groups, GINT_TO_POINTER (group_id)); + + if (group != NULL) + g_dbus_menu_group_changed (group, menu_id, position, removes, adds); + } + g_variant_iter_free (iter); +} + +static void +g_dbus_menu_path_activate (GDBusMenuPath *path) +{ + if (path->active++ == 0) + path->watch_id = g_dbus_connection_signal_subscribe (path->id->connection, path->id->bus_name, + "org.gtk.Menus", "Changed", path->id->object_path, + NULL, G_DBUS_SIGNAL_FLAGS_NONE, + g_dbus_menu_path_signal, path, NULL); +} + +static void +g_dbus_menu_path_deactivate (GDBusMenuPath *path) +{ + if (--path->active == 0) + g_dbus_connection_signal_unsubscribe (path->id->connection, path->watch_id); +} + +static GDBusMenuPath * +g_dbus_menu_path_get (GMainContext *context, + GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path) +{ + ConstPathIdentifier cid = { context, connection, bus_name, object_path }; + GDBusMenuPath *path; + + if (g_dbus_menu_paths == NULL) + g_dbus_menu_paths = g_hash_table_new (path_identifier_hash, path_identifier_equal); + + path = g_hash_table_lookup (g_dbus_menu_paths, &cid); + + if (path == NULL) + { + path = g_slice_new (GDBusMenuPath); + path->id = path_identifier_new (&cid); + path->groups = g_hash_table_new (NULL, NULL); + path->ref_count = 0; + path->active = 0; + + g_hash_table_insert (g_dbus_menu_paths, path->id, path); + } + + return g_dbus_menu_path_ref (path); +} + +/* GDBusMenuGroup, GDBusMenuModelItem {{{1 */ +typedef enum +{ + GROUP_OFFLINE, + GROUP_PENDING, + GROUP_ONLINE +} GroupStatus; + +struct _GDBusMenuGroup +{ + GDBusMenuPath *path; + guint id; + + GHashTable *proxies; /* uint -> unowned GDBusMenuModel */ + GHashTable *menus; /* uint -> owned GSequence */ + gint ref_count; + GroupStatus state; + gint active; +}; + +typedef struct +{ + GHashTable *attributes; + GHashTable *links; +} GDBusMenuModelItem; + +static GDBusMenuGroup * +g_dbus_menu_group_ref (GDBusMenuGroup *group) +{ + group->ref_count++; + + return group; +} + +static void +g_dbus_menu_group_unref (GDBusMenuGroup *group) +{ + if (--group->ref_count == 0) + { + g_assert (group->state == GROUP_OFFLINE); + g_assert (group->active == 0); + + g_hash_table_remove (group->path->groups, GINT_TO_POINTER (group->id)); + g_hash_table_unref (group->proxies); + g_hash_table_unref (group->menus); + + g_dbus_menu_path_unref (group->path); + + g_slice_free (GDBusMenuGroup, group); + } +} + +static void +g_dbus_menu_model_item_free (gpointer data) +{ + GDBusMenuModelItem *item = data; + + g_hash_table_unref (item->attributes); + g_hash_table_unref (item->links); + + g_slice_free (GDBusMenuModelItem, item); +} + +static GDBusMenuModelItem * +g_dbus_menu_group_create_item (GVariant *description) +{ + GDBusMenuModelItem *item; + GVariantIter iter; + const gchar *key; + GVariant *value; + + item = g_slice_new (GDBusMenuModelItem); + item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + + g_variant_iter_init (&iter, description); + while (g_variant_iter_loop (&iter, "{&sv}", &key, &value)) + if (key[0] == ':') + /* key + 1 to skip the ':' */ + g_hash_table_insert (item->links, g_strdup (key + 1), g_variant_ref (value)); + else + g_hash_table_insert (item->attributes, g_strdup (key), g_variant_ref (value)); + + return item; +} + +/* + * GDBusMenuGroup can be in three states: + * + * OFFLINE: not subscribed to this group + * PENDING: we made the call to subscribe to this group, but the result + * has not come back yet + * ONLINE: we are fully subscribed + * + * We can get into some nasty situations where we make a call due to an + * activation request but receive a deactivation request before the call + * returns. If another activation request occurs then we could risk + * sending a Start request even though one is already in progress. For + * this reason, we have to carefully consider what to do in each of the + * three states for each of the following situations: + * + * - activation requested + * - deactivation requested + * - Start call finishes + * + * To simplify things a bit, we do not have a callback for the Stop + * call. We just send it and assume that it takes effect immediately. + * + * Activation requested: + * OFFLINE: make the Start call and transition to PENDING + * PENDING: do nothing -- call is already in progress. + * ONLINE: this should not be possible + * + * Deactivation requested: + * OFFLINE: this should not be possible + * PENDING: do nothing -- handle it when the Start call finishes + * ONLINE: send the Stop call and move to OFFLINE immediately + * + * Start call finishes: + * OFFLINE: this should not be possible + * PENDING: + * If we should be active (ie: active count > 0): move to ONLINE + * If not: send Stop call and move to OFFLINE immediately + * ONLINE: this should not be possible + * + * We have to take care with regards to signal subscriptions (ie: + * activation of the GDBusMenuPath). The signal subscription is always + * established when transitioning from OFFLINE to PENDING and taken down + * when transitioning to OFFLINE (from either PENDING or ONLINE). + * + * Since there are two places where we transition to OFFLINE, we split + * that code out into a separate function. + */ +static void +g_dbus_menu_group_go_offline (GDBusMenuGroup *group) +{ + g_dbus_menu_path_deactivate (group->path); + g_dbus_connection_call (group->path->id->connection, + group->path->id->bus_name, + group->path->id->object_path, + "org.gtk.Menus", "End", + g_variant_new_parsed ("([ %u ],)", group->id), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, NULL, NULL); + group->state = GROUP_OFFLINE; +} + + +static void +g_dbus_menu_group_start_ready (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (source_object); + GDBusMenuGroup *group = user_data; + GVariant *reply; + + g_assert (group->state == GROUP_PENDING); + + reply = g_dbus_connection_call_finish (connection, result, NULL); + + if (group->active) + { + group->state = GROUP_ONLINE; + + /* If we receive no reply, just act like we got an empty reply. */ + if (reply) + { + GVariantIter *iter; + GVariant *items; + guint group_id; + guint menu_id; + + g_variant_get (reply, "(a(uuaa{sv}))", &iter); + while (g_variant_iter_loop (iter, "(uu@aa{sv})", &group_id, &menu_id, &items)) + if (group_id == group->id) + g_dbus_menu_group_changed (group, menu_id, 0, 0, items); + g_variant_iter_free (iter); + } + } + else + g_dbus_menu_group_go_offline (group); + + if (reply) + g_variant_unref (reply); + + g_dbus_menu_group_unref (group); +} + +static void +g_dbus_menu_group_activate (GDBusMenuGroup *group) +{ + if (group->active++ == 0) + { + g_assert (group->state != GROUP_ONLINE); + + if (group->state == GROUP_OFFLINE) + { + g_dbus_menu_path_activate (group->path); + + g_dbus_connection_call (group->path->id->connection, + group->path->id->bus_name, + group->path->id->object_path, + "org.gtk.Menus", "Start", + g_variant_new_parsed ("([ %u ],)", group->id), + G_VARIANT_TYPE ("(a(uuaa{sv}))"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, + g_dbus_menu_group_start_ready, + g_dbus_menu_group_ref (group)); + group->state = GROUP_PENDING; + } + } +} + +static void +g_dbus_menu_group_deactivate (GDBusMenuGroup *group) +{ + if (--group->active == 0) + { + g_assert (group->state != GROUP_OFFLINE); + + if (group->state == GROUP_ONLINE) + { + /* We are here because nobody is watching, so just free + * everything and don't bother with the notifications. + */ + g_hash_table_remove_all (group->menus); + + g_dbus_menu_group_go_offline (group); + } + } +} + +static void +g_dbus_menu_group_changed (GDBusMenuGroup *group, + guint menu_id, + gint position, + gint removed, + GVariant *added) +{ + GSequenceIter *point; + GVariantIter iter; + GDBusMenuModel *proxy; + GSequence *items; + GVariant *item; + gint n_added; + + /* We could have signals coming to us when we're not active (due to + * some other process having subscribed to this group) or when we're + * pending. In both of those cases, we want to ignore the signal + * since we'll get our own information when we call "Start" for + * ourselves. + */ + if (group->state != GROUP_ONLINE) + return; + + items = g_hash_table_lookup (group->menus, GINT_TO_POINTER (menu_id)); + + if (items == NULL) + { + items = g_sequence_new (g_dbus_menu_model_item_free); + g_hash_table_insert (group->menus, GINT_TO_POINTER (menu_id), items); + } + + point = g_sequence_get_iter_at_pos (items, position + removed); + + g_return_if_fail (point != NULL); + + if (removed) + { + GSequenceIter *start; + + start = g_sequence_get_iter_at_pos (items, position); + g_sequence_remove_range (start, point); + } + + n_added = g_variant_iter_init (&iter, added); + while (g_variant_iter_loop (&iter, "@a{sv}", &item)) + g_sequence_insert_before (point, g_dbus_menu_group_create_item (item)); + + if (g_sequence_is_empty (items)) + { + g_hash_table_remove (group->menus, GINT_TO_POINTER (menu_id)); + items = NULL; + } + + if ((proxy = g_hash_table_lookup (group->proxies, GINT_TO_POINTER (menu_id)))) + g_dbus_menu_model_changed (proxy, items, position, removed, n_added); +} + +static GDBusMenuGroup * +g_dbus_menu_group_get_from_path (GDBusMenuPath *path, + guint group_id) +{ + GDBusMenuGroup *group; + + group = g_hash_table_lookup (path->groups, GINT_TO_POINTER (group_id)); + + if (group == NULL) + { + group = g_slice_new (GDBusMenuGroup); + group->path = g_dbus_menu_path_ref (path); + group->id = group_id; + group->proxies = g_hash_table_new (NULL, NULL); + group->menus = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_sequence_free); + group->state = GROUP_OFFLINE; + group->active = 0; + group->ref_count = 0; + + g_hash_table_insert (path->groups, GINT_TO_POINTER (group->id), group); + } + + return g_dbus_menu_group_ref (group); +} + +static GDBusMenuGroup * +g_dbus_menu_group_get (GMainContext *context, + GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path, + guint group_id) +{ + GDBusMenuGroup *group; + GDBusMenuPath *path; + + path = g_dbus_menu_path_get (context, connection, bus_name, object_path); + group = g_dbus_menu_group_get_from_path (path, group_id); + g_dbus_menu_path_unref (path); + + return group; +} + +/* GDBusMenuModel {{{1 */ + +typedef GMenuModelClass GDBusMenuModelClass; +struct _GDBusMenuModel +{ + GMenuModel parent; + + GDBusMenuGroup *group; + guint id; + + GSequence *items; /* unowned */ + gboolean active; +}; + +G_DEFINE_TYPE (GDBusMenuModel, g_dbus_menu_model, G_TYPE_MENU_MODEL) + +static gboolean +g_dbus_menu_model_is_mutable (GMenuModel *model) +{ + return TRUE; +} + +static gint +g_dbus_menu_model_get_n_items (GMenuModel *model) +{ + GDBusMenuModel *proxy = G_DBUS_MENU_MODEL (model); + + if (!proxy->active) + { + g_dbus_menu_group_activate (proxy->group); + proxy->active = TRUE; + } + + return proxy->items ? g_sequence_get_length (proxy->items) : 0; +} + +static void +g_dbus_menu_model_get_item_attributes (GMenuModel *model, + gint item_index, + GHashTable **table) +{ + GDBusMenuModel *proxy = G_DBUS_MENU_MODEL (model); + GDBusMenuModelItem *item; + GSequenceIter *iter; + + g_return_if_fail (proxy->active); + g_return_if_fail (proxy->items); + + iter = g_sequence_get_iter_at_pos (proxy->items, item_index); + g_return_if_fail (iter); + + item = g_sequence_get (iter); + g_return_if_fail (item); + + *table = g_hash_table_ref (item->attributes); +} + +static void +g_dbus_menu_model_get_item_links (GMenuModel *model, + gint item_index, + GHashTable **table) +{ + GDBusMenuModel *proxy = G_DBUS_MENU_MODEL (model); + GDBusMenuModelItem *item; + GSequenceIter *iter; + + g_return_if_fail (proxy->active); + g_return_if_fail (proxy->items); + + iter = g_sequence_get_iter_at_pos (proxy->items, item_index); + g_return_if_fail (iter); + + item = g_sequence_get (iter); + g_return_if_fail (item); + + *table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + { + GHashTableIter tmp; + gpointer key; + gpointer value; + + g_hash_table_iter_init (&tmp, item->links); + while (g_hash_table_iter_next (&tmp, &key, &value)) + { + if (g_variant_is_of_type (value, G_VARIANT_TYPE ("(uu)"))) + { + guint group_id, menu_id; + GDBusMenuGroup *group; + GDBusMenuModel *link; + + g_variant_get (value, "(uu)", &group_id, &menu_id); + + /* save the hash lookup in a relatively common case */ + if (proxy->group->id != group_id) + group = g_dbus_menu_group_get_from_path (proxy->group->path, group_id); + else + group = g_dbus_menu_group_ref (proxy->group); + + link = g_dbus_menu_model_get_from_group (group, menu_id); + + g_hash_table_insert (*table, g_strdup (key), link); + + g_dbus_menu_group_unref (group); + } + } + } +} + +static void +g_dbus_menu_model_finalize (GObject *object) +{ + GDBusMenuModel *proxy = G_DBUS_MENU_MODEL (object); + + if (proxy->active) + g_dbus_menu_group_deactivate (proxy->group); + + g_hash_table_remove (proxy->group->proxies, GINT_TO_POINTER (proxy->id)); + g_dbus_menu_group_unref (proxy->group); + + G_OBJECT_CLASS (g_dbus_menu_model_parent_class) + ->finalize (object); +} + +static void +g_dbus_menu_model_init (GDBusMenuModel *proxy) +{ +} + +static void +g_dbus_menu_model_class_init (GDBusMenuModelClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + class->is_mutable = g_dbus_menu_model_is_mutable; + class->get_n_items = g_dbus_menu_model_get_n_items; + class->get_item_attributes = g_dbus_menu_model_get_item_attributes; + class->get_item_links = g_dbus_menu_model_get_item_links; + + object_class->finalize = g_dbus_menu_model_finalize; +} + +static void +g_dbus_menu_model_changed (GDBusMenuModel *proxy, + GSequence *items, + gint position, + gint removed, + gint added) +{ + proxy->items = items; + + if (proxy->active && (removed || added)) + g_menu_model_items_changed (G_MENU_MODEL (proxy), position, removed, added); +} + +static GDBusMenuModel * +g_dbus_menu_model_get_from_group (GDBusMenuGroup *group, + guint menu_id) +{ + GDBusMenuModel *proxy; + + proxy = g_hash_table_lookup (group->proxies, GINT_TO_POINTER (menu_id)); + if (proxy) + g_object_ref (proxy); + + if (proxy == NULL) + { + proxy = g_object_new (G_TYPE_DBUS_MENU_MODEL, NULL); + proxy->items = g_hash_table_lookup (group->menus, GINT_TO_POINTER (menu_id)); + g_hash_table_insert (group->proxies, GINT_TO_POINTER (menu_id), proxy); + proxy->group = g_dbus_menu_group_ref (group); + proxy->id = menu_id; + } + + return proxy; +} + +/** + * g_dbus_menu_model_get: + * @connection: a #GDBusConnection + * @bus_name: (nullable): the bus name which exports the menu model + * or %NULL if @connection is not a message bus connection + * @object_path: the object path at which the menu model is exported + * + * Obtains a #GDBusMenuModel for the menu model which is exported + * at the given @bus_name and @object_path. + * + * The thread default main context is taken at the time of this call. + * All signals on the menu model (and any linked models) are reported + * with respect to this context. All calls on the returned menu model + * (and linked models) must also originate from this same context, with + * the thread default main context unchanged. + * + * Returns: (transfer full): a #GDBusMenuModel object. Free with + * g_object_unref(). + * + * Since: 2.32 + */ +GDBusMenuModel * +g_dbus_menu_model_get (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path) +{ + GDBusMenuGroup *group; + GDBusMenuModel *proxy; + GMainContext *context; + + g_return_val_if_fail (bus_name != NULL || g_dbus_connection_get_unique_name (connection) == NULL, NULL); + + context = g_main_context_get_thread_default (); + if (context == NULL) + context = g_main_context_default (); + + group = g_dbus_menu_group_get (context, connection, bus_name, object_path, 0); + proxy = g_dbus_menu_model_get_from_group (group, 0); + g_dbus_menu_group_unref (group); + + return proxy; +} + +#if 0 +static void +dump_proxy (gpointer key, gpointer value, gpointer data) +{ + GDBusMenuModel *proxy = value; + + g_print (" menu %d refcount %d active %d\n", + proxy->id, G_OBJECT (proxy)->ref_count, proxy->active); +} + +static void +dump_group (gpointer key, gpointer value, gpointer data) +{ + GDBusMenuGroup *group = value; + + g_print (" group %d refcount %d state %d active %d\n", + group->id, group->ref_count, group->state, group->active); + + g_hash_table_foreach (group->proxies, dump_proxy, NULL); +} + +static void +dump_path (gpointer key, gpointer value, gpointer data) +{ + PathIdentifier *pid = key; + GDBusMenuPath *path = value; + + g_print ("%s active %d\n", pid->object_path, path->active); + g_hash_table_foreach (path->groups, dump_group, NULL); +} + +void +g_dbus_menu_model_dump (void) +{ + g_hash_table_foreach (g_dbus_menu_paths, dump_path, NULL); +} + +#endif + +/* Epilogue {{{1 */ +/* vim:set foldmethod=marker: */ diff --git a/gio/gdbusmenumodel.h b/gio/gdbusmenumodel.h new file mode 100644 index 0000000..dd2882d --- /dev/null +++ b/gio/gdbusmenumodel.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_DBUS_MENU_MODEL_H__ +#define __G_DBUS_MENU_MODEL_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_MENU_MODEL (g_dbus_menu_model_get_type ()) +#define G_DBUS_MENU_MODEL(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_DBUS_MENU_MODEL, GDBusMenuModel)) +#define G_IS_DBUS_MENU_MODEL(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_DBUS_MENU_MODEL)) + +typedef struct _GDBusMenuModel GDBusMenuModel; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_menu_model_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GDBusMenuModel * g_dbus_menu_model_get (GDBusConnection *connection, + const gchar *bus_name, + const gchar *object_path); + +G_END_DECLS + +#endif /* __G_DBUS_MENU_MODEL_H__ */ diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c new file mode 100644 index 0000000..ecef6cd --- /dev/null +++ b/gio/gdbusmessage.c @@ -0,0 +1,3833 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +/* Uncomment to debug serializer code */ +/* #define DEBUG_SERIALIZER */ + +#include "config.h" + +#include +#include +#include +#include + +#if MAJOR_IN_MKDEV +#include +#elif MAJOR_IN_SYSMACROS +#include +#elif MAJOR_IN_TYPES +#include +#else +#define MAJOR_MINOR_NOT_FOUND 1 +#endif + +#include "gdbusutils.h" +#include "gdbusmessage.h" +#include "gdbuserror.h" +#include "gioenumtypes.h" +#include "ginputstream.h" +#include "gdatainputstream.h" +#include "gmemoryinputstream.h" +#include "goutputstream.h" +#include "gdataoutputstream.h" +#include "gmemoryoutputstream.h" +#include "gseekable.h" +#include "gioerror.h" +#include "gdbusprivate.h" +#include "gutilsprivate.h" + +#ifdef G_OS_UNIX +#include "gunixfdlist.h" +#endif + +#include "glibintl.h" + +/* See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-signature + * This is 64 containers plus 1 value within them. */ +#define G_DBUS_MAX_TYPE_DEPTH (64 + 1) + +typedef struct _GMemoryBuffer GMemoryBuffer; +struct _GMemoryBuffer +{ + gsize len; + gsize valid_len; + gsize pos; + gchar *data; + GDataStreamByteOrder byte_order; +}; + +static gboolean +g_memory_buffer_is_byteswapped (GMemoryBuffer *mbuf) +{ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + return mbuf->byte_order == G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN; +#else + return mbuf->byte_order == G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN; +#endif +} + +static guchar +g_memory_buffer_read_byte (GMemoryBuffer *mbuf, + GError **error) +{ + g_return_val_if_fail (error == NULL || *error == NULL, 0); + + if (mbuf->pos >= mbuf->valid_len) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Unexpected end of message while reading byte."); + return 0; + } + return mbuf->data [mbuf->pos++]; +} + +static gint16 +g_memory_buffer_read_int16 (GMemoryBuffer *mbuf, + GError **error) +{ + gint16 v; + + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + if (mbuf->pos > mbuf->valid_len - 2) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Unexpected end of message while reading int16."); + return 0; + } + + memcpy (&v, mbuf->data + mbuf->pos, 2); + mbuf->pos += 2; + + if (g_memory_buffer_is_byteswapped (mbuf)) + v = GUINT16_SWAP_LE_BE (v); + + return v; +} + +static guint16 +g_memory_buffer_read_uint16 (GMemoryBuffer *mbuf, + GError **error) +{ + guint16 v; + + g_return_val_if_fail (error == NULL || *error == NULL, 0); + + if (mbuf->pos > mbuf->valid_len - 2) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Unexpected end of message while reading uint16."); + return 0; + } + + memcpy (&v, mbuf->data + mbuf->pos, 2); + mbuf->pos += 2; + + if (g_memory_buffer_is_byteswapped (mbuf)) + v = GUINT16_SWAP_LE_BE (v); + + return v; +} + +static gint32 +g_memory_buffer_read_int32 (GMemoryBuffer *mbuf, + GError **error) +{ + gint32 v; + + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + if (mbuf->pos > mbuf->valid_len - 4) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Unexpected end of message while reading int32."); + return 0; + } + + memcpy (&v, mbuf->data + mbuf->pos, 4); + mbuf->pos += 4; + + if (g_memory_buffer_is_byteswapped (mbuf)) + v = GUINT32_SWAP_LE_BE (v); + + return v; +} + +static guint32 +g_memory_buffer_read_uint32 (GMemoryBuffer *mbuf, + GError **error) +{ + guint32 v; + + g_return_val_if_fail (error == NULL || *error == NULL, 0); + + if (mbuf->pos > mbuf->valid_len - 4) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Unexpected end of message while reading uint32."); + return 0; + } + + memcpy (&v, mbuf->data + mbuf->pos, 4); + mbuf->pos += 4; + + if (g_memory_buffer_is_byteswapped (mbuf)) + v = GUINT32_SWAP_LE_BE (v); + + return v; +} + +static gint64 +g_memory_buffer_read_int64 (GMemoryBuffer *mbuf, + GError **error) +{ + gint64 v; + + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + if (mbuf->pos > mbuf->valid_len - 8) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Unexpected end of message while reading int64."); + return 0; + } + + memcpy (&v, mbuf->data + mbuf->pos, 8); + mbuf->pos += 8; + + if (g_memory_buffer_is_byteswapped (mbuf)) + v = GUINT64_SWAP_LE_BE (v); + + return v; +} + +static guint64 +g_memory_buffer_read_uint64 (GMemoryBuffer *mbuf, + GError **error) +{ + guint64 v; + + g_return_val_if_fail (error == NULL || *error == NULL, 0); + + if (mbuf->pos > mbuf->valid_len - 8) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Unexpected end of message while reading uint64."); + return 0; + } + + memcpy (&v, mbuf->data + mbuf->pos, 8); + mbuf->pos += 8; + + if (g_memory_buffer_is_byteswapped (mbuf)) + v = GUINT64_SWAP_LE_BE (v); + + return v; +} + +#define MIN_ARRAY_SIZE 128 + +static void +array_resize (GMemoryBuffer *mbuf, + gsize size) +{ + gpointer data; + gsize len; + + if (mbuf->len == size) + return; + + len = mbuf->len; + data = g_realloc (mbuf->data, size); + + if (size > len) + memset ((guint8 *)data + len, 0, size - len); + + mbuf->data = data; + mbuf->len = size; + + if (mbuf->len < mbuf->valid_len) + mbuf->valid_len = mbuf->len; +} + +static gboolean +g_memory_buffer_write (GMemoryBuffer *mbuf, + const void *buffer, + gsize count) +{ + guint8 *dest; + gsize new_size; + + if (count == 0) + return TRUE; + + /* Check for address space overflow, but only if the buffer is resizable. + Otherwise we just do a short write and don't worry. */ + if (mbuf->pos + count < mbuf->pos) + return FALSE; + + if (mbuf->pos + count > mbuf->len) + { + /* At least enough to fit the write, rounded up + for greater than linear growth. + TODO: This wastes a lot of memory at large buffer sizes. + Figure out a more rational allocation strategy. */ + new_size = g_nearest_pow (mbuf->pos + count); + /* Check for overflow again. We have checked if + pos + count > G_MAXSIZE, but now check if g_nearest_pow () has + overflowed */ + if (new_size == 0) + return FALSE; + + new_size = MAX (new_size, MIN_ARRAY_SIZE); + array_resize (mbuf, new_size); + } + + dest = (guint8 *)mbuf->data + mbuf->pos; + memcpy (dest, buffer, count); + mbuf->pos += count; + + if (mbuf->pos > mbuf->valid_len) + mbuf->valid_len = mbuf->pos; + + return TRUE; +} + +static gboolean +g_memory_buffer_put_byte (GMemoryBuffer *mbuf, + guchar data) +{ + return g_memory_buffer_write (mbuf, &data, 1); +} + +static gboolean +g_memory_buffer_put_int16 (GMemoryBuffer *mbuf, + gint16 data) +{ + switch (mbuf->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GINT16_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GINT16_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_memory_buffer_write (mbuf, &data, 2); +} + +static gboolean +g_memory_buffer_put_uint16 (GMemoryBuffer *mbuf, + guint16 data) +{ + switch (mbuf->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GUINT16_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GUINT16_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_memory_buffer_write (mbuf, &data, 2); +} + +static gboolean +g_memory_buffer_put_int32 (GMemoryBuffer *mbuf, + gint32 data) +{ + switch (mbuf->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GINT32_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GINT32_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_memory_buffer_write (mbuf, &data, 4); +} + +static gboolean +g_memory_buffer_put_uint32 (GMemoryBuffer *mbuf, + guint32 data) +{ + switch (mbuf->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GUINT32_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GUINT32_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_memory_buffer_write (mbuf, &data, 4); +} + +static gboolean +g_memory_buffer_put_int64 (GMemoryBuffer *mbuf, + gint64 data) +{ + switch (mbuf->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GINT64_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GINT64_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_memory_buffer_write (mbuf, &data, 8); +} + +static gboolean +g_memory_buffer_put_uint64 (GMemoryBuffer *mbuf, + guint64 data) +{ + switch (mbuf->byte_order) + { + case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: + data = GUINT64_TO_BE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: + data = GUINT64_TO_LE (data); + break; + case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: + default: + break; + } + + return g_memory_buffer_write (mbuf, &data, 8); +} + +static gboolean +g_memory_buffer_put_string (GMemoryBuffer *mbuf, + const char *str) +{ + g_return_val_if_fail (str != NULL, FALSE); + + return g_memory_buffer_write (mbuf, str, strlen (str)); +} + + +/** + * SECTION:gdbusmessage + * @short_description: D-Bus Message + * @include: gio/gio.h + * + * A type for representing D-Bus messages that can be sent or received + * on a #GDBusConnection. + */ + +typedef struct _GDBusMessageClass GDBusMessageClass; + +/** + * GDBusMessageClass: + * + * Class structure for #GDBusMessage. + * + * Since: 2.26 + */ +struct _GDBusMessageClass +{ + /*< private >*/ + GObjectClass parent_class; +}; + +/** + * GDBusMessage: + * + * The #GDBusMessage structure contains only private data and should + * only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GDBusMessage +{ + /*< private >*/ + GObject parent_instance; + + GDBusMessageType type; + GDBusMessageFlags flags; + gboolean locked; + GDBusMessageByteOrder byte_order; + guchar major_protocol_version; + guint32 serial; + GHashTable *headers; + GVariant *body; +#ifdef G_OS_UNIX + GUnixFDList *fd_list; +#endif +}; + +enum +{ + PROP_0, + PROP_LOCKED +}; + +G_DEFINE_TYPE (GDBusMessage, g_dbus_message, G_TYPE_OBJECT) + +static void +g_dbus_message_finalize (GObject *object) +{ + GDBusMessage *message = G_DBUS_MESSAGE (object); + + if (message->headers != NULL) + g_hash_table_unref (message->headers); + if (message->body != NULL) + g_variant_unref (message->body); +#ifdef G_OS_UNIX + if (message->fd_list != NULL) + g_object_unref (message->fd_list); +#endif + + if (G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_dbus_message_parent_class)->finalize (object); +} + +static void +g_dbus_message_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusMessage *message = G_DBUS_MESSAGE (object); + + switch (prop_id) + { + case PROP_LOCKED: + g_value_set_boolean (value, g_dbus_message_get_locked (message)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_message_class_init (GDBusMessageClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = g_dbus_message_finalize; + gobject_class->get_property = g_dbus_message_get_property; + + /** + * GDBusConnection:locked: + * + * A boolean specifying whether the message is locked. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_LOCKED, + g_param_spec_boolean ("locked", + P_("Locked"), + P_("Whether the message is locked"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); +} + +static void +g_dbus_message_init (GDBusMessage *message) +{ + /* Any D-Bus implementation is supposed to handle both Big and + * Little Endian encodings and the Endianness is part of the D-Bus + * message - we prefer to use Big Endian (since it's Network Byte + * Order and just easier to read for humans) but if the machine is + * Little Endian we use that for performance reasons. + */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN; +#else + /* this could also be G_PDP_ENDIAN */ + message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN; +#endif + message->headers = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify) g_variant_unref); +} + +/** + * g_dbus_message_new: + * + * Creates a new empty #GDBusMessage. + * + * Returns: A #GDBusMessage. Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_message_new (void) +{ + return g_object_new (G_TYPE_DBUS_MESSAGE, NULL); +} + +/** + * g_dbus_message_new_method_call: + * @name: (nullable): A valid D-Bus name or %NULL. + * @path: A valid object path. + * @interface_: (nullable): A valid D-Bus interface name or %NULL. + * @method: A valid method name. + * + * Creates a new #GDBusMessage for a method call. + * + * Returns: A #GDBusMessage. Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_message_new_method_call (const gchar *name, + const gchar *path, + const gchar *interface_, + const gchar *method) +{ + GDBusMessage *message; + + g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL); + g_return_val_if_fail (g_variant_is_object_path (path), NULL); + g_return_val_if_fail (g_dbus_is_member_name (method), NULL); + g_return_val_if_fail (interface_ == NULL || g_dbus_is_interface_name (interface_), NULL); + + message = g_dbus_message_new (); + message->type = G_DBUS_MESSAGE_TYPE_METHOD_CALL; + + if (name != NULL) + g_dbus_message_set_destination (message, name); + g_dbus_message_set_path (message, path); + g_dbus_message_set_member (message, method); + if (interface_ != NULL) + g_dbus_message_set_interface (message, interface_); + + return message; +} + +/** + * g_dbus_message_new_signal: + * @path: A valid object path. + * @interface_: A valid D-Bus interface name. + * @signal: A valid signal name. + * + * Creates a new #GDBusMessage for a signal emission. + * + * Returns: A #GDBusMessage. Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_message_new_signal (const gchar *path, + const gchar *interface_, + const gchar *signal) +{ + GDBusMessage *message; + + g_return_val_if_fail (g_variant_is_object_path (path), NULL); + g_return_val_if_fail (g_dbus_is_member_name (signal), NULL); + g_return_val_if_fail (g_dbus_is_interface_name (interface_), NULL); + + message = g_dbus_message_new (); + message->type = G_DBUS_MESSAGE_TYPE_SIGNAL; + message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED; + + g_dbus_message_set_path (message, path); + g_dbus_message_set_member (message, signal); + g_dbus_message_set_interface (message, interface_); + + return message; +} + + +/** + * g_dbus_message_new_method_reply: + * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to + * create a reply message to. + * + * Creates a new #GDBusMessage that is a reply to @method_call_message. + * + * Returns: (transfer full): #GDBusMessage. Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_message_new_method_reply (GDBusMessage *method_call_message) +{ + GDBusMessage *message; + const gchar *sender; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL); + g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL); + g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL); + + message = g_dbus_message_new (); + message->type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN; + message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED; + /* reply with same endianness */ + message->byte_order = method_call_message->byte_order; + + g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message)); + sender = g_dbus_message_get_sender (method_call_message); + if (sender != NULL) + g_dbus_message_set_destination (message, sender); + + return message; +} + +/** + * g_dbus_message_new_method_error: + * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to + * create a reply message to. + * @error_name: A valid D-Bus error name. + * @error_message_format: The D-Bus error message in a printf() format. + * @...: Arguments for @error_message_format. + * + * Creates a new #GDBusMessage that is an error reply to @method_call_message. + * + * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_message_new_method_error (GDBusMessage *method_call_message, + const gchar *error_name, + const gchar *error_message_format, + ...) +{ + GDBusMessage *ret; + va_list var_args; + + va_start (var_args, error_message_format); + ret = g_dbus_message_new_method_error_valist (method_call_message, + error_name, + error_message_format, + var_args); + va_end (var_args); + + return ret; +} + +/** + * g_dbus_message_new_method_error_literal: + * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to + * create a reply message to. + * @error_name: A valid D-Bus error name. + * @error_message: The D-Bus error message. + * + * Creates a new #GDBusMessage that is an error reply to @method_call_message. + * + * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_message_new_method_error_literal (GDBusMessage *method_call_message, + const gchar *error_name, + const gchar *error_message) +{ + GDBusMessage *message; + const gchar *sender; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (method_call_message), NULL); + g_return_val_if_fail (g_dbus_message_get_message_type (method_call_message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL, NULL); + g_return_val_if_fail (g_dbus_message_get_serial (method_call_message) != 0, NULL); + g_return_val_if_fail (g_dbus_is_name (error_name), NULL); + g_return_val_if_fail (error_message != NULL, NULL); + + message = g_dbus_message_new (); + message->type = G_DBUS_MESSAGE_TYPE_ERROR; + message->flags = G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED; + /* reply with same endianness */ + message->byte_order = method_call_message->byte_order; + + g_dbus_message_set_reply_serial (message, g_dbus_message_get_serial (method_call_message)); + g_dbus_message_set_error_name (message, error_name); + g_dbus_message_set_body (message, g_variant_new ("(s)", error_message)); + + sender = g_dbus_message_get_sender (method_call_message); + if (sender != NULL) + g_dbus_message_set_destination (message, sender); + + return message; +} + +/** + * g_dbus_message_new_method_error_valist: + * @method_call_message: A message of type %G_DBUS_MESSAGE_TYPE_METHOD_CALL to + * create a reply message to. + * @error_name: A valid D-Bus error name. + * @error_message_format: The D-Bus error message in a printf() format. + * @var_args: Arguments for @error_message_format. + * + * Like g_dbus_message_new_method_error() but intended for language bindings. + * + * Returns: (transfer full): A #GDBusMessage. Free with g_object_unref(). + * + * Since: 2.26 + */ +G_GNUC_PRINTF(3, 0) +GDBusMessage * +g_dbus_message_new_method_error_valist (GDBusMessage *method_call_message, + const gchar *error_name, + const gchar *error_message_format, + va_list var_args) +{ + GDBusMessage *ret; + gchar *error_message; + error_message = g_strdup_vprintf (error_message_format, var_args); + ret = g_dbus_message_new_method_error_literal (method_call_message, + error_name, + error_message); + g_free (error_message); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_byte_order: + * @message: A #GDBusMessage. + * + * Gets the byte order of @message. + * + * Returns: The byte order. + */ +GDBusMessageByteOrder +g_dbus_message_get_byte_order (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), (GDBusMessageByteOrder) 0); + return message->byte_order; +} + +/** + * g_dbus_message_set_byte_order: + * @message: A #GDBusMessage. + * @byte_order: The byte order. + * + * Sets the byte order of @message. + */ +void +g_dbus_message_set_byte_order (GDBusMessage *message, + GDBusMessageByteOrder byte_order) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + + if (message->locked) + { + g_warning ("%s: Attempted to modify a locked message", G_STRFUNC); + return; + } + + message->byte_order = byte_order; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* TODO: need GI annotations to specify that any guchar value goes for the type */ + +/** + * g_dbus_message_get_message_type: + * @message: A #GDBusMessage. + * + * Gets the type of @message. + * + * Returns: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration). + * + * Since: 2.26 + */ +GDBusMessageType +g_dbus_message_get_message_type (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_TYPE_INVALID); + return message->type; +} + +/** + * g_dbus_message_set_message_type: + * @message: A #GDBusMessage. + * @type: A 8-bit unsigned integer (typically a value from the #GDBusMessageType enumeration). + * + * Sets @message to be of @type. + * + * Since: 2.26 + */ +void +g_dbus_message_set_message_type (GDBusMessage *message, + GDBusMessageType type) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail ((guint) type < 256); + + if (message->locked) + { + g_warning ("%s: Attempted to modify a locked message", G_STRFUNC); + return; + } + + message->type = type; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* TODO: need GI annotations to specify that any guchar value goes for flags */ + +/** + * g_dbus_message_get_flags: + * @message: A #GDBusMessage. + * + * Gets the flags for @message. + * + * Returns: Flags that are set (typically values from the #GDBusMessageFlags enumeration bitwise ORed together). + * + * Since: 2.26 + */ +GDBusMessageFlags +g_dbus_message_get_flags (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), G_DBUS_MESSAGE_FLAGS_NONE); + return message->flags; +} + +/** + * g_dbus_message_set_flags: + * @message: A #GDBusMessage. + * @flags: Flags for @message that are set (typically values from the #GDBusMessageFlags + * enumeration bitwise ORed together). + * + * Sets the flags to set on @message. + * + * Since: 2.26 + */ +void +g_dbus_message_set_flags (GDBusMessage *message, + GDBusMessageFlags flags) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail ((guint) flags < 256); + + if (message->locked) + { + g_warning ("%s: Attempted to modify a locked message", G_STRFUNC); + return; + } + + message->flags = flags; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_serial: + * @message: A #GDBusMessage. + * + * Gets the serial for @message. + * + * Returns: A #guint32. + * + * Since: 2.26 + */ +guint32 +g_dbus_message_get_serial (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0); + return message->serial; +} + +/** + * g_dbus_message_set_serial: + * @message: A #GDBusMessage. + * @serial: A #guint32. + * + * Sets the serial for @message. + * + * Since: 2.26 + */ +void +g_dbus_message_set_serial (GDBusMessage *message, + guint32 serial) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + + if (message->locked) + { + g_warning ("%s: Attempted to modify a locked message", G_STRFUNC); + return; + } + + message->serial = serial; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* TODO: need GI annotations to specify that any guchar value goes for header_field */ + +/** + * g_dbus_message_get_header: + * @message: A #GDBusMessage. + * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration) + * + * Gets a header field on @message. + * + * The caller is responsible for checking the type of the returned #GVariant + * matches what is expected. + * + * Returns: (transfer none) (nullable): A #GVariant with the value if the header was found, %NULL + * otherwise. Do not free, it is owned by @message. + * + * Since: 2.26 + */ +GVariant * +g_dbus_message_get_header (GDBusMessage *message, + GDBusMessageHeaderField header_field) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + g_return_val_if_fail ((guint) header_field < 256, NULL); + return g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field)); +} + +/** + * g_dbus_message_set_header: + * @message: A #GDBusMessage. + * @header_field: A 8-bit unsigned integer (typically a value from the #GDBusMessageHeaderField enumeration) + * @value: (nullable): A #GVariant to set the header field or %NULL to clear the header field. + * + * Sets a header field on @message. + * + * If @value is floating, @message assumes ownership of @value. + * + * Since: 2.26 + */ +void +g_dbus_message_set_header (GDBusMessage *message, + GDBusMessageHeaderField header_field, + GVariant *value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail ((guint) header_field < 256); + + if (message->locked) + { + g_warning ("%s: Attempted to modify a locked message", G_STRFUNC); + return; + } + + if (value == NULL) + { + g_hash_table_remove (message->headers, GUINT_TO_POINTER (header_field)); + } + else + { + g_hash_table_insert (message->headers, GUINT_TO_POINTER (header_field), g_variant_ref_sink (value)); + } +} + +/** + * g_dbus_message_get_header_fields: + * @message: A #GDBusMessage. + * + * Gets an array of all header fields on @message that are set. + * + * Returns: (array zero-terminated=1): An array of header fields + * terminated by %G_DBUS_MESSAGE_HEADER_FIELD_INVALID. Each element + * is a #guchar. Free with g_free(). + * + * Since: 2.26 + */ +guchar * +g_dbus_message_get_header_fields (GDBusMessage *message) +{ + GList *keys; + guchar *ret; + guint num_keys; + GList *l; + guint n; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + + keys = g_hash_table_get_keys (message->headers); + num_keys = g_list_length (keys); + ret = g_new (guchar, num_keys + 1); + for (l = keys, n = 0; l != NULL; l = l->next, n++) + ret[n] = GPOINTER_TO_UINT (l->data); + g_assert (n == num_keys); + ret[n] = G_DBUS_MESSAGE_HEADER_FIELD_INVALID; + g_list_free (keys); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_body: + * @message: A #GDBusMessage. + * + * Gets the body of a message. + * + * Returns: (nullable) (transfer none): A #GVariant or %NULL if the body is + * empty. Do not free, it is owned by @message. + * + * Since: 2.26 + */ +GVariant * +g_dbus_message_get_body (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + return message->body; +} + +/** + * g_dbus_message_set_body: + * @message: A #GDBusMessage. + * @body: Either %NULL or a #GVariant that is a tuple. + * + * Sets the body @message. As a side-effect the + * %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field is set to the + * type string of @body (or cleared if @body is %NULL). + * + * If @body is floating, @message assumes ownership of @body. + * + * Since: 2.26 + */ +void +g_dbus_message_set_body (GDBusMessage *message, + GVariant *body) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail ((body == NULL) || g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE)); + + if (message->locked) + { + g_warning ("%s: Attempted to modify a locked message", G_STRFUNC); + return; + } + + if (message->body != NULL) + g_variant_unref (message->body); + if (body == NULL) + { + message->body = NULL; + g_dbus_message_set_signature (message, NULL); + } + else + { + const gchar *type_string; + gsize type_string_len; + gchar *signature; + + message->body = g_variant_ref_sink (body); + + type_string = g_variant_get_type_string (body); + type_string_len = strlen (type_string); + g_assert (type_string_len >= 2); + signature = g_strndup (type_string + 1, type_string_len - 2); + g_dbus_message_set_signature (message, signature); + g_free (signature); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_UNIX +/** + * g_dbus_message_get_unix_fd_list: + * @message: A #GDBusMessage. + * + * Gets the UNIX file descriptors associated with @message, if any. + * + * This method is only available on UNIX. + * + * The file descriptors normally correspond to %G_VARIANT_TYPE_HANDLE + * values in the body of the message. For example, + * if g_variant_get_handle() returns 5, that is intended to be a reference + * to the file descriptor that can be accessed by + * `g_unix_fd_list_get (list, 5, ...)`. + * + * Returns: (nullable) (transfer none): A #GUnixFDList or %NULL if no file descriptors are + * associated. Do not free, this object is owned by @message. + * + * Since: 2.26 + */ +GUnixFDList * +g_dbus_message_get_unix_fd_list (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + return message->fd_list; +} + +/** + * g_dbus_message_set_unix_fd_list: + * @message: A #GDBusMessage. + * @fd_list: (nullable): A #GUnixFDList or %NULL. + * + * Sets the UNIX file descriptors associated with @message. As a + * side-effect the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header + * field is set to the number of fds in @fd_list (or cleared if + * @fd_list is %NULL). + * + * This method is only available on UNIX. + * + * When designing D-Bus APIs that are intended to be interoperable, + * please note that non-GDBus implementations of D-Bus can usually only + * access file descriptors if they are referenced by a value of type + * %G_VARIANT_TYPE_HANDLE in the body of the message. + * + * Since: 2.26 + */ +void +g_dbus_message_set_unix_fd_list (GDBusMessage *message, + GUnixFDList *fd_list) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list)); + + if (message->locked) + { + g_warning ("%s: Attempted to modify a locked message", G_STRFUNC); + return; + } + + if (message->fd_list != NULL) + g_object_unref (message->fd_list); + if (fd_list != NULL) + { + message->fd_list = g_object_ref (fd_list); + g_dbus_message_set_num_unix_fds (message, g_unix_fd_list_get_length (fd_list)); + } + else + { + message->fd_list = NULL; + g_dbus_message_set_num_unix_fds (message, 0); + } +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +static guint +get_type_fixed_size (const GVariantType *type) +{ + /* NB: we do not treat 'b' as fixed-size here because GVariant and + * D-Bus disagree about the size. + */ + switch (*g_variant_type_peek_string (type)) + { + case 'y': + return 1; + case 'n': case 'q': + return 2; + case 'i': case 'u': case 'h': + return 4; + case 'x': case 't': case 'd': + return 8; + default: + return 0; + } +} + +static gboolean +validate_headers (GDBusMessage *message, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; + + switch (message->type) + { + case G_DBUS_MESSAGE_TYPE_INVALID: + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("type is INVALID")); + goto out; + break; + + case G_DBUS_MESSAGE_TYPE_METHOD_CALL: + if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH) == NULL || + g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER) == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("METHOD_CALL message: PATH or MEMBER header field is missing")); + goto out; + } + break; + + case G_DBUS_MESSAGE_TYPE_METHOD_RETURN: + if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL) == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("METHOD_RETURN message: REPLY_SERIAL header field is missing")); + goto out; + } + break; + + case G_DBUS_MESSAGE_TYPE_ERROR: + if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME) == NULL || + g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL) == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing")); + goto out; + } + break; + + case G_DBUS_MESSAGE_TYPE_SIGNAL: + if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH) == NULL || + g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE) == NULL || + g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER) == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("SIGNAL message: PATH, INTERFACE or MEMBER header field is missing")); + goto out; + } + if (g_strcmp0 (g_dbus_message_get_path (message), "/org/freedesktop/DBus/Local") == 0) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local")); + goto out; + } + if (g_strcmp0 (g_dbus_message_get_interface (message), "org.freedesktop.DBus.Local") == 0) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local")); + goto out; + } + break; + + default: + /* hitherto unknown type - nothing to check */ + break; + } + + ret = TRUE; + + out: + g_assert (ret || (error == NULL || *error != NULL)); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +ensure_input_padding (GMemoryBuffer *buf, + gsize padding_size) +{ + gsize offset; + gsize wanted_offset; + + offset = buf->pos; + wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size; + buf->pos = wanted_offset; + return TRUE; +} + +static const gchar * +read_string (GMemoryBuffer *mbuf, + gsize len, + GError **error) +{ + gchar *str; + const gchar *end_valid; + + if G_UNLIKELY (mbuf->pos + len >= mbuf->valid_len || mbuf->pos + len < mbuf->pos) + { + mbuf->pos = mbuf->valid_len; + /* G_GSIZE_FORMAT doesn't work with gettext, so we use %lu */ + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + g_dngettext (GETTEXT_PACKAGE, + "Wanted to read %lu byte but only got %lu", + "Wanted to read %lu bytes but only got %lu", + (gulong)len), + (gulong)len, + (gulong)(mbuf->valid_len - mbuf->pos)); + return NULL; + } + + if G_UNLIKELY (mbuf->data[mbuf->pos + len] != '\0') + { + str = g_strndup (mbuf->data + mbuf->pos, len); + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Expected NUL byte after the string “%s†but found byte %d"), + str, mbuf->data[mbuf->pos + len]); + g_free (str); + mbuf->pos += len + 1; + return NULL; + } + + str = mbuf->data + mbuf->pos; + mbuf->pos += len + 1; + + if G_UNLIKELY (!g_utf8_validate (str, -1, &end_valid)) + { + gint offset; + gchar *valid_str; + offset = (gint) (end_valid - str); + valid_str = g_strndup (str, offset); + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). " + "The valid UTF-8 string up until that point was “%sâ€"), + offset, + (gint) len, + valid_str); + g_free (valid_str); + return NULL; + } + + return str; +} + +static gconstpointer +read_bytes (GMemoryBuffer *mbuf, + gsize len, + GError **error) +{ + gconstpointer result; + + if G_UNLIKELY (mbuf->pos + len > mbuf->valid_len || mbuf->pos + len < mbuf->pos) + { + mbuf->pos = mbuf->valid_len; + /* G_GSIZE_FORMAT doesn't work with gettext, so we use %lu */ + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + g_dngettext (GETTEXT_PACKAGE, + "Wanted to read %lu byte but only got %lu", + "Wanted to read %lu bytes but only got %lu", + (gulong)len), + (gulong)len, + (gulong)(mbuf->valid_len - mbuf->pos)); + return NULL; + } + + result = mbuf->data + mbuf->pos; + mbuf->pos += len; + + return result; +} + +/* if just_align==TRUE, don't read a value, just align the input stream wrt padding */ + +/* returns a non-floating GVariant! */ +static GVariant * +parse_value_from_blob (GMemoryBuffer *buf, + const GVariantType *type, + guint max_depth, + gboolean just_align, + guint indent, + GError **error) +{ + GVariant *ret = NULL; + GError *local_error = NULL; +#ifdef DEBUG_SERIALIZER + gboolean is_leaf; +#endif /* DEBUG_SERIALIZER */ + const gchar *type_string; + + if (max_depth == 0) + { + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Value nested too deeply")); + goto fail; + } + + type_string = g_variant_type_peek_string (type); + +#ifdef DEBUG_SERIALIZER + { + gchar *s; + s = g_variant_type_dup_string (type); + g_print ("%*s%s type %s from offset 0x%04x", + indent, "", + just_align ? "Aligning" : "Reading", + s, + (gint) buf->pos); + g_free (s); + } +#endif /* DEBUG_SERIALIZER */ + +#ifdef DEBUG_SERIALIZER + is_leaf = TRUE; +#endif /* DEBUG_SERIALIZER */ + switch (type_string[0]) + { + case 'b': /* G_VARIANT_TYPE_BOOLEAN */ + ensure_input_padding (buf, 4); + if (!just_align) + { + gboolean v; + v = g_memory_buffer_read_uint32 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_boolean (v); + } + break; + + case 'y': /* G_VARIANT_TYPE_BYTE */ + if (!just_align) + { + guchar v; + v = g_memory_buffer_read_byte (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_byte (v); + } + break; + + case 'n': /* G_VARIANT_TYPE_INT16 */ + ensure_input_padding (buf, 2); + if (!just_align) + { + gint16 v; + v = g_memory_buffer_read_int16 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_int16 (v); + } + break; + + case 'q': /* G_VARIANT_TYPE_UINT16 */ + ensure_input_padding (buf, 2); + if (!just_align) + { + guint16 v; + v = g_memory_buffer_read_uint16 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_uint16 (v); + } + break; + + case 'i': /* G_VARIANT_TYPE_INT32 */ + ensure_input_padding (buf, 4); + if (!just_align) + { + gint32 v; + v = g_memory_buffer_read_int32 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_int32 (v); + } + break; + + case 'u': /* G_VARIANT_TYPE_UINT32 */ + ensure_input_padding (buf, 4); + if (!just_align) + { + guint32 v; + v = g_memory_buffer_read_uint32 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_uint32 (v); + } + break; + + case 'x': /* G_VARIANT_TYPE_INT64 */ + ensure_input_padding (buf, 8); + if (!just_align) + { + gint64 v; + v = g_memory_buffer_read_int64 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_int64 (v); + } + break; + + case 't': /* G_VARIANT_TYPE_UINT64 */ + ensure_input_padding (buf, 8); + if (!just_align) + { + guint64 v; + v = g_memory_buffer_read_uint64 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_uint64 (v); + } + break; + + case 'd': /* G_VARIANT_TYPE_DOUBLE */ + ensure_input_padding (buf, 8); + if (!just_align) + { + union { + guint64 v_uint64; + gdouble v_double; + } u; + G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64)); + u.v_uint64 = g_memory_buffer_read_uint64 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_double (u.v_double); + } + break; + + case 's': /* G_VARIANT_TYPE_STRING */ + ensure_input_padding (buf, 4); + if (!just_align) + { + guint32 len; + const gchar *v; + len = g_memory_buffer_read_uint32 (buf, &local_error); + if (local_error) + goto fail; + v = read_string (buf, (gsize) len, &local_error); + if (v == NULL) + goto fail; + ret = g_variant_new_string (v); + } + break; + + case 'o': /* G_VARIANT_TYPE_OBJECT_PATH */ + ensure_input_padding (buf, 4); + if (!just_align) + { + guint32 len; + const gchar *v; + len = g_memory_buffer_read_uint32 (buf, &local_error); + if (local_error) + goto fail; + v = read_string (buf, (gsize) len, &local_error); + if (v == NULL) + goto fail; + if (!g_variant_is_object_path (v)) + { + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Parsed value “%s†is not a valid D-Bus object path"), + v); + goto fail; + } + ret = g_variant_new_object_path (v); + } + break; + + case 'g': /* G_VARIANT_TYPE_SIGNATURE */ + if (!just_align) + { + guchar len; + const gchar *v; + len = g_memory_buffer_read_byte (buf, &local_error); + if (local_error) + goto fail; + v = read_string (buf, (gsize) len, &local_error); + if (v == NULL) + goto fail; + if (!g_variant_is_signature (v)) + { + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Parsed value “%s†is not a valid D-Bus signature"), + v); + goto fail; + } + ret = g_variant_new_signature (v); + } + break; + + case 'h': /* G_VARIANT_TYPE_HANDLE */ + ensure_input_padding (buf, 4); + if (!just_align) + { + gint32 v; + v = g_memory_buffer_read_int32 (buf, &local_error); + if (local_error) + goto fail; + ret = g_variant_new_handle (v); + } + break; + + case 'a': /* G_VARIANT_TYPE_ARRAY */ + ensure_input_padding (buf, 4); + + /* If we are only aligning for this array type, it is the child type of + * another array, which is empty. So, we do not need to add padding for + * this nonexistent array's elements: we only need to align for this + * array itself (4 bytes). See + * . + */ + if (!just_align) + { + guint32 array_len; + const GVariantType *element_type; + guint fixed_size; + + array_len = g_memory_buffer_read_uint32 (buf, &local_error); + if (local_error) + goto fail; + +#ifdef DEBUG_SERIALIZER + is_leaf = FALSE; + g_print (": array spans 0x%04x bytes\n", array_len); +#endif /* DEBUG_SERIALIZER */ + + if (array_len > (2<<26)) + { + /* G_GUINT32_FORMAT doesn't work with gettext, so use u */ + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + g_dngettext (GETTEXT_PACKAGE, + "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB).", + "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB).", + array_len), + array_len); + goto fail; + } + + element_type = g_variant_type_element (type); + fixed_size = get_type_fixed_size (element_type); + + /* Fast-path the cases like 'ay', etc. */ + if (fixed_size != 0) + { + gconstpointer array_data; + + if (array_len % fixed_size != 0) + { + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Encountered array of type “a%câ€, expected to have a length a multiple " + "of %u bytes, but found to be %u bytes in length"), + g_variant_type_peek_string (element_type)[0], fixed_size, array_len); + goto fail; + } + + if (max_depth == 1) + { + /* If we had recursed into parse_value_from_blob() again to + * parse the array values, this would have been emitted. */ + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Value nested too deeply")); + goto fail; + } + + ensure_input_padding (buf, fixed_size); + array_data = read_bytes (buf, array_len, &local_error); + if (array_data == NULL) + goto fail; + + ret = g_variant_new_fixed_array (element_type, array_data, array_len / fixed_size, fixed_size); + + if (g_memory_buffer_is_byteswapped (buf)) + { + GVariant *tmp = g_variant_ref_sink (ret); + ret = g_variant_byteswap (tmp); + g_variant_unref (tmp); + } + } + else + { + GVariantBuilder builder; + goffset offset; + goffset target; + + g_variant_builder_init (&builder, type); + + if (array_len == 0) + { + GVariant *item G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + item = parse_value_from_blob (buf, + element_type, + max_depth - 1, + TRUE, + indent + 2, + NULL); + g_assert (item == NULL); + } + else + { + offset = buf->pos; + target = offset + array_len; + while (offset < target) + { + GVariant *item; + item = parse_value_from_blob (buf, + element_type, + max_depth - 1, + FALSE, + indent + 2, + &local_error); + if (item == NULL) + { + g_variant_builder_clear (&builder); + goto fail; + } + g_variant_builder_add_value (&builder, item); + g_variant_unref (item); + + /* Array elements must not be zero-length. There are no + * valid zero-length serialisations of any types which + * can be array elements in the D-Bus wire format, so this + * assertion should always hold. + * + * See https://gitlab.gnome.org/GNOME/glib/-/issues/2557 + */ + g_assert (buf->pos > (gsize) offset); + + offset = buf->pos; + } + } + + ret = g_variant_builder_end (&builder); + } + } + break; + + default: + if (g_variant_type_is_dict_entry (type)) + { + const GVariantType *key_type; + const GVariantType *value_type; + GVariant *key; + GVariant *value; + + ensure_input_padding (buf, 8); + +#ifdef DEBUG_SERIALIZER + is_leaf = FALSE; + g_print ("\n"); +#endif /* DEBUG_SERIALIZER */ + + if (!just_align) + { + key_type = g_variant_type_key (type); + key = parse_value_from_blob (buf, + key_type, + max_depth - 1, + FALSE, + indent + 2, + &local_error); + if (key == NULL) + goto fail; + value_type = g_variant_type_value (type); + value = parse_value_from_blob (buf, + value_type, + max_depth - 1, + FALSE, + indent + 2, + &local_error); + if (value == NULL) + { + g_variant_unref (key); + goto fail; + } + ret = g_variant_new_dict_entry (key, value); + g_variant_unref (key); + g_variant_unref (value); + } + } + else if (g_variant_type_is_tuple (type)) + { + ensure_input_padding (buf, 8); + +#ifdef DEBUG_SERIALIZER + is_leaf = FALSE; + g_print ("\n"); +#endif /* DEBUG_SERIALIZER */ + + if (!just_align) + { + const GVariantType *element_type; + GVariantBuilder builder; + + g_variant_builder_init (&builder, type); + element_type = g_variant_type_first (type); + if (!element_type) + { + g_variant_builder_clear (&builder); + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Empty structures (tuples) are not allowed in D-Bus")); + goto fail; + } + + while (element_type != NULL) + { + GVariant *item; + item = parse_value_from_blob (buf, + element_type, + max_depth - 1, + FALSE, + indent + 2, + &local_error); + if (item == NULL) + { + g_variant_builder_clear (&builder); + goto fail; + } + g_variant_builder_add_value (&builder, item); + g_variant_unref (item); + + element_type = g_variant_type_next (element_type); + } + ret = g_variant_builder_end (&builder); + } + } + else if (g_variant_type_is_variant (type)) + { +#ifdef DEBUG_SERIALIZER + is_leaf = FALSE; + g_print ("\n"); +#endif /* DEBUG_SERIALIZER */ + + if (!just_align) + { + guchar siglen; + const gchar *sig; + GVariantType *variant_type; + GVariant *value; + + siglen = g_memory_buffer_read_byte (buf, &local_error); + if (local_error) + goto fail; + sig = read_string (buf, (gsize) siglen, &local_error); + if (sig == NULL) + goto fail; + if (!g_variant_is_signature (sig) || + !g_variant_type_string_is_valid (sig)) + { + /* A D-Bus signature can contain zero or more complete types, + * but a GVariant has to be exactly one complete type. */ + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Parsed value “%s†for variant is not a valid D-Bus signature"), + sig); + goto fail; + } + + if (max_depth <= g_variant_type_string_get_depth_ (sig)) + { + /* Catch the type nesting being too deep without having to + * parse the data. We don’t have to check this for static + * container types (like arrays and tuples, above) because + * the g_variant_type_string_is_valid() check performed before + * the initial parse_value_from_blob() call should check the + * static type nesting. */ + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Value nested too deeply")); + goto fail; + } + + variant_type = g_variant_type_new (sig); + value = parse_value_from_blob (buf, + variant_type, + max_depth - 1, + FALSE, + indent + 2, + &local_error); + g_variant_type_free (variant_type); + if (value == NULL) + goto fail; + ret = g_variant_new_variant (value); + g_variant_unref (value); + } + } + else + { + gchar *s; + s = g_variant_type_dup_string (type); + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error deserializing GVariant with type string “%s†from the D-Bus wire format"), + s); + g_free (s); + goto fail; + } + break; + } + + g_assert ((just_align && ret == NULL) || (!just_align && ret != NULL)); + +#ifdef DEBUG_SERIALIZER + if (ret != NULL) + { + if (is_leaf) + { + gchar *s; + if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE)) + { + s = g_strdup_printf ("0x%02x '%c'", g_variant_get_byte (ret), g_variant_get_byte (ret)); + } + else + { + s = g_variant_print (ret, FALSE); + } + g_print (": %s\n", s); + g_free (s); + } + } +#endif /* DEBUG_SERIALIZER */ + + /* sink the reference, if floating */ + if (ret != NULL) + g_variant_take_ref (ret); + return ret; + + fail: +#ifdef DEBUG_SERIALIZER + g_print ("\n" + "%*sFAILURE: %s (%s, %d)\n", + indent, "", + local_error->message, + g_quark_to_string (local_error->domain), + local_error->code); +#endif /* DEBUG_SERIALIZER */ + g_propagate_error (error, local_error); + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* message_header must be at least 16 bytes */ + +/** + * g_dbus_message_bytes_needed: + * @blob: (array length=blob_len) (element-type guint8): A blob representing a binary D-Bus message. + * @blob_len: The length of @blob (must be at least 16). + * @error: Return location for error or %NULL. + * + * Utility function to calculate how many bytes are needed to + * completely deserialize the D-Bus message stored at @blob. + * + * Returns: Number of bytes needed or -1 if @error is set (e.g. if + * @blob contains invalid data or not enough data is available to + * determine the size). + * + * Since: 2.26 + */ +gssize +g_dbus_message_bytes_needed (guchar *blob, + gsize blob_len, + GError **error) +{ + gssize ret; + + ret = -1; + + g_return_val_if_fail (blob != NULL, -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + g_return_val_if_fail (blob_len >= 16, -1); + + if (blob[0] == 'l') + { + /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */ + ret = 12 + 4 + GUINT32_FROM_LE (((guint32 *) blob)[3]); + /* round up so it's a multiple of 8 */ + ret = 8 * ((ret + 7)/8); + /* finally add the body size */ + ret += GUINT32_FROM_LE (((guint32 *) blob)[1]); + } + else if (blob[0] == 'B') + { + /* core header (12 bytes) + ARRAY of STRUCT of (BYTE,VARIANT) */ + ret = 12 + 4 + GUINT32_FROM_BE (((guint32 *) blob)[3]); + /* round up so it's a multiple of 8 */ + ret = 8 * ((ret + 7)/8); + /* finally add the body size */ + ret += GUINT32_FROM_BE (((guint32 *) blob)[1]); + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Unable to determine message blob length - given blob is malformed"); + } + + if (ret > (1<<27)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Blob indicates that message exceeds maximum message length (128MiB)"); + ret = -1; + } + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_new_from_blob: + * @blob: (array length=blob_len) (element-type guint8): A blob representing a binary D-Bus message. + * @blob_len: The length of @blob. + * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported. + * @error: Return location for error or %NULL. + * + * Creates a new #GDBusMessage from the data stored at @blob. The byte + * order that the message was in can be retrieved using + * g_dbus_message_get_byte_order(). + * + * If the @blob cannot be parsed, contains invalid fields, or contains invalid + * headers, %G_IO_ERROR_INVALID_ARGUMENT will be returned. + * + * Returns: A new #GDBusMessage or %NULL if @error is set. Free with + * g_object_unref(). + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_message_new_from_blob (guchar *blob, + gsize blob_len, + GDBusCapabilityFlags capabilities, + GError **error) +{ + GError *local_error = NULL; + GMemoryBuffer mbuf; + GDBusMessage *message; + guchar endianness; + guchar major_protocol_version; + guint32 message_body_len; + GVariant *headers; + GVariant *item; + GVariantIter iter; + GVariant *signature; + + /* TODO: check against @capabilities */ + + g_return_val_if_fail (blob != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + message = g_dbus_message_new (); + + memset (&mbuf, 0, sizeof (mbuf)); + mbuf.data = (gchar *)blob; + mbuf.len = mbuf.valid_len = blob_len; + + endianness = g_memory_buffer_read_byte (&mbuf, &local_error); + if (local_error) + goto fail; + + switch (endianness) + { + case 'l': + mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN; + message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN; + break; + case 'B': + mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN; + message->byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN; + break; + default: + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value 0x%02x"), + endianness); + goto fail; + } + + message->type = g_memory_buffer_read_byte (&mbuf, &local_error); + if (local_error) + goto fail; + message->flags = g_memory_buffer_read_byte (&mbuf, &local_error); + if (local_error) + goto fail; + major_protocol_version = g_memory_buffer_read_byte (&mbuf, &local_error); + if (local_error) + goto fail; + if (major_protocol_version != 1) + { + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid major protocol version. Expected 1 but found %d"), + major_protocol_version); + goto fail; + } + message_body_len = g_memory_buffer_read_uint32 (&mbuf, &local_error); + if (local_error) + goto fail; + message->serial = g_memory_buffer_read_uint32 (&mbuf, &local_error); + if (local_error) + goto fail; + +#ifdef DEBUG_SERIALIZER + g_print ("Parsing blob (blob_len = 0x%04x bytes)\n", (gint) blob_len); + { + gchar *s; + s = _g_dbus_hexdump ((const gchar *) blob, blob_len, 2); + g_print ("%s\n", s); + g_free (s); + } +#endif /* DEBUG_SERIALIZER */ + +#ifdef DEBUG_SERIALIZER + g_print ("Parsing headers (blob_len = 0x%04x bytes)\n", (gint) blob_len); +#endif /* DEBUG_SERIALIZER */ + headers = parse_value_from_blob (&mbuf, + G_VARIANT_TYPE ("a{yv}"), + G_DBUS_MAX_TYPE_DEPTH + 2 /* for the a{yv} */, + FALSE, + 2, + &local_error); + if (headers == NULL) + goto fail; + g_variant_iter_init (&iter, headers); + while ((item = g_variant_iter_next_value (&iter)) != NULL) + { + guchar header_field; + GVariant *value; + g_variant_get (item, + "{yv}", + &header_field, + &value); + g_dbus_message_set_header (message, header_field, value); + g_variant_unref (value); + g_variant_unref (item); + } + g_variant_unref (headers); + + signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE); + if (signature != NULL) + { + const gchar *signature_str; + gsize signature_str_len; + + if (!g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE)) + { + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Signature header found but is not of type signature")); + goto fail; + } + + signature_str = g_variant_get_string (signature, &signature_str_len); + + /* signature but no body */ + if (message_body_len == 0 && signature_str_len > 0) + { + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Signature header with signature “%s†found but message body is empty"), + signature_str); + goto fail; + } + else if (signature_str_len > 0) + { + GVariantType *variant_type; + gchar *tupled_signature_str = g_strdup_printf ("(%s)", signature_str); + + if (!g_variant_is_signature (signature_str) || + !g_variant_type_string_is_valid (tupled_signature_str)) + { + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Parsed value “%s†is not a valid D-Bus signature (for body)"), + signature_str); + g_free (tupled_signature_str); + goto fail; + } + + variant_type = g_variant_type_new (tupled_signature_str); + g_free (tupled_signature_str); +#ifdef DEBUG_SERIALIZER + g_print ("Parsing body (blob_len = 0x%04x bytes)\n", (gint) blob_len); +#endif /* DEBUG_SERIALIZER */ + message->body = parse_value_from_blob (&mbuf, + variant_type, + G_DBUS_MAX_TYPE_DEPTH + 1 /* for the surrounding tuple */, + FALSE, + 2, + &local_error); + g_variant_type_free (variant_type); + if (message->body == NULL) + goto fail; + } + } + else + { + /* no signature, this is only OK if the body is empty */ + if (message_body_len != 0) + { + /* G_GUINT32_FORMAT doesn't work with gettext, just use %u */ + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + g_dngettext (GETTEXT_PACKAGE, + "No signature header in message but the message body is %u byte", + "No signature header in message but the message body is %u bytes", + message_body_len), + message_body_len); + goto fail; + } + } + + if (!validate_headers (message, &local_error)) + { + g_prefix_error (&local_error, _("Cannot deserialize message: ")); + goto fail; + } + + return message; + +fail: + g_clear_object (&message); + g_propagate_error (error, local_error); + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gsize +ensure_output_padding (GMemoryBuffer *mbuf, + gsize padding_size) +{ + gsize offset; + gsize wanted_offset; + gsize padding_needed; + guint n; + + offset = mbuf->pos; + wanted_offset = ((offset + padding_size - 1) / padding_size) * padding_size; + padding_needed = wanted_offset - offset; + + for (n = 0; n < padding_needed; n++) + g_memory_buffer_put_byte (mbuf, '\0'); + + return padding_needed; +} + +/* note that value can be NULL for e.g. empty arrays - type is never NULL */ +static gboolean +append_value_to_blob (GVariant *value, + const GVariantType *type, + GMemoryBuffer *mbuf, + gsize *out_padding_added, + GError **error) +{ + gsize padding_added; + const gchar *type_string; + + type_string = g_variant_type_peek_string (type); + + padding_added = 0; + + switch (type_string[0]) + { + case 'b': /* G_VARIANT_TYPE_BOOLEAN */ + padding_added = ensure_output_padding (mbuf, 4); + if (value != NULL) + { + gboolean v = g_variant_get_boolean (value); + g_memory_buffer_put_uint32 (mbuf, v); + } + break; + + case 'y': /* G_VARIANT_TYPE_BYTE */ + if (value != NULL) + { + guint8 v = g_variant_get_byte (value); + g_memory_buffer_put_byte (mbuf, v); + } + break; + + case 'n': /* G_VARIANT_TYPE_INT16 */ + padding_added = ensure_output_padding (mbuf, 2); + if (value != NULL) + { + gint16 v = g_variant_get_int16 (value); + g_memory_buffer_put_int16 (mbuf, v); + } + break; + + case 'q': /* G_VARIANT_TYPE_UINT16 */ + padding_added = ensure_output_padding (mbuf, 2); + if (value != NULL) + { + guint16 v = g_variant_get_uint16 (value); + g_memory_buffer_put_uint16 (mbuf, v); + } + break; + + case 'i': /* G_VARIANT_TYPE_INT32 */ + padding_added = ensure_output_padding (mbuf, 4); + if (value != NULL) + { + gint32 v = g_variant_get_int32 (value); + g_memory_buffer_put_int32 (mbuf, v); + } + break; + + case 'u': /* G_VARIANT_TYPE_UINT32 */ + padding_added = ensure_output_padding (mbuf, 4); + if (value != NULL) + { + guint32 v = g_variant_get_uint32 (value); + g_memory_buffer_put_uint32 (mbuf, v); + } + break; + + case 'x': /* G_VARIANT_TYPE_INT64 */ + padding_added = ensure_output_padding (mbuf, 8); + if (value != NULL) + { + gint64 v = g_variant_get_int64 (value); + g_memory_buffer_put_int64 (mbuf, v); + } + break; + + case 't': /* G_VARIANT_TYPE_UINT64 */ + padding_added = ensure_output_padding (mbuf, 8); + if (value != NULL) + { + guint64 v = g_variant_get_uint64 (value); + g_memory_buffer_put_uint64 (mbuf, v); + } + break; + + case 'd': /* G_VARIANT_TYPE_DOUBLE */ + padding_added = ensure_output_padding (mbuf, 8); + if (value != NULL) + { + union { + guint64 v_uint64; + gdouble v_double; + } u; + G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64)); + u.v_double = g_variant_get_double (value); + g_memory_buffer_put_uint64 (mbuf, u.v_uint64); + } + break; + + case 's': /* G_VARIANT_TYPE_STRING */ + padding_added = ensure_output_padding (mbuf, 4); + if (value != NULL) + { + gsize len; + const gchar *v; +#ifndef G_DISABLE_ASSERT + const gchar *end; +#endif + + v = g_variant_get_string (value, &len); + g_assert (g_utf8_validate (v, -1, &end) && (end == v + len)); + g_memory_buffer_put_uint32 (mbuf, len); + g_memory_buffer_put_string (mbuf, v); + g_memory_buffer_put_byte (mbuf, '\0'); + } + break; + + case 'o': /* G_VARIANT_TYPE_OBJECT_PATH */ + padding_added = ensure_output_padding (mbuf, 4); + if (value != NULL) + { + gsize len; + const gchar *v = g_variant_get_string (value, &len); + g_assert (g_variant_is_object_path (v)); + g_memory_buffer_put_uint32 (mbuf, len); + g_memory_buffer_put_string (mbuf, v); + g_memory_buffer_put_byte (mbuf, '\0'); + } + break; + + case 'g': /* G_VARIANT_TYPE_SIGNATURE */ + if (value != NULL) + { + gsize len; + const gchar *v = g_variant_get_string (value, &len); + g_assert (g_variant_is_signature (v)); + g_memory_buffer_put_byte (mbuf, len); + g_memory_buffer_put_string (mbuf, v); + g_memory_buffer_put_byte (mbuf, '\0'); + } + break; + + case 'h': /* G_VARIANT_TYPE_HANDLE */ + padding_added = ensure_output_padding (mbuf, 4); + if (value != NULL) + { + gint32 v = g_variant_get_handle (value); + g_memory_buffer_put_int32 (mbuf, v); + } + break; + + case 'a': /* G_VARIANT_TYPE_ARRAY */ + { + const GVariantType *element_type; + GVariant *item; + GVariantIter iter; + goffset array_len_offset; + goffset array_payload_begin_offset; + goffset cur_offset; + gsize array_len; + guint fixed_size; + + padding_added = ensure_output_padding (mbuf, 4); + if (value != NULL) + { + /* array length - will be filled in later */ + array_len_offset = mbuf->valid_len; + g_memory_buffer_put_uint32 (mbuf, 0xF00DFACE); + + /* From the D-Bus spec: + * + * "A UINT32 giving the length of the array data in bytes, + * followed by alignment padding to the alignment boundary of + * the array element type, followed by each array element. The + * array length is from the end of the alignment padding to + * the end of the last element, i.e. it does not include the + * padding after the length, or any padding after the last + * element." + * + * Thus, we need to count how much padding the first element + * contributes and subtract that from the array length. + */ + array_payload_begin_offset = mbuf->valid_len; + + element_type = g_variant_type_element (type); + fixed_size = get_type_fixed_size (element_type); + + if (g_variant_n_children (value) == 0) + { + gsize padding_added_for_item; + if (!append_value_to_blob (NULL, + element_type, + mbuf, + &padding_added_for_item, + error)) + goto fail; + array_payload_begin_offset += padding_added_for_item; + } + else if (fixed_size != 0) + { + GVariant *use_value; + + if (g_memory_buffer_is_byteswapped (mbuf)) + use_value = g_variant_byteswap (value); + else + use_value = g_variant_ref (value); + + array_payload_begin_offset += ensure_output_padding (mbuf, fixed_size); + + array_len = g_variant_get_size (use_value); + g_memory_buffer_write (mbuf, g_variant_get_data (use_value), array_len); + g_variant_unref (use_value); + } + else + { + guint n; + n = 0; + g_variant_iter_init (&iter, value); + while ((item = g_variant_iter_next_value (&iter)) != NULL) + { + gsize padding_added_for_item; + if (!append_value_to_blob (item, + g_variant_get_type (item), + mbuf, + &padding_added_for_item, + error)) + { + g_variant_unref (item); + goto fail; + } + g_variant_unref (item); + if (n == 0) + { + array_payload_begin_offset += padding_added_for_item; + } + n++; + } + } + + cur_offset = mbuf->valid_len; + array_len = cur_offset - array_payload_begin_offset; + mbuf->pos = array_len_offset; + + g_memory_buffer_put_uint32 (mbuf, array_len); + mbuf->pos = cur_offset; + } + } + break; + + default: + if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type)) + { + if (!g_variant_type_first (type)) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Empty structures (tuples) are not allowed in D-Bus")); + goto fail; + } + + padding_added = ensure_output_padding (mbuf, 8); + if (value != NULL) + { + GVariant *item; + GVariantIter iter; + g_variant_iter_init (&iter, value); + while ((item = g_variant_iter_next_value (&iter)) != NULL) + { + if (!append_value_to_blob (item, + g_variant_get_type (item), + mbuf, + NULL, + error)) + { + g_variant_unref (item); + goto fail; + } + g_variant_unref (item); + } + } + } + else if (g_variant_type_is_variant (type)) + { + if (value != NULL) + { + GVariant *child; + const gchar *signature; + child = g_variant_get_child_value (value, 0); + signature = g_variant_get_type_string (child); + g_memory_buffer_put_byte (mbuf, strlen (signature)); + g_memory_buffer_put_string (mbuf, signature); + g_memory_buffer_put_byte (mbuf, '\0'); + if (!append_value_to_blob (child, + g_variant_get_type (child), + mbuf, + NULL, + error)) + { + g_variant_unref (child); + goto fail; + } + g_variant_unref (child); + } + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error serializing GVariant with type string “%s†to the D-Bus wire format"), + g_variant_get_type_string (value)); + goto fail; + } + break; + } + + if (out_padding_added != NULL) + *out_padding_added = padding_added; + + return TRUE; + + fail: + return FALSE; +} + +static gboolean +append_body_to_blob (GVariant *value, + GMemoryBuffer *mbuf, + GError **error) +{ + GVariant *item; + GVariantIter iter; + + if (!g_variant_is_of_type (value, G_VARIANT_TYPE_TUPLE)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Expected a tuple for the body of the GDBusMessage."); + goto fail; + } + + g_variant_iter_init (&iter, value); + while ((item = g_variant_iter_next_value (&iter)) != NULL) + { + if (!append_value_to_blob (item, + g_variant_get_type (item), + mbuf, + NULL, + error)) + { + g_variant_unref (item); + goto fail; + } + g_variant_unref (item); + } + return TRUE; + + fail: + return FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_to_blob: + * @message: A #GDBusMessage. + * @out_size: Return location for size of generated blob. + * @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported. + * @error: Return location for error. + * + * Serializes @message to a blob. The byte order returned by + * g_dbus_message_get_byte_order() will be used. + * + * Returns: (array length=out_size) (transfer full): A pointer to a + * valid binary D-Bus message of @out_size bytes generated by @message + * or %NULL if @error is set. Free with g_free(). + * + * Since: 2.26 + */ +guchar * +g_dbus_message_to_blob (GDBusMessage *message, + gsize *out_size, + GDBusCapabilityFlags capabilities, + GError **error) +{ + GMemoryBuffer mbuf; + guchar *ret; + gsize size; + goffset body_len_offset; + goffset body_start_offset; + gsize body_size; + GVariant *header_fields; + GVariantBuilder builder; + GHashTableIter hash_iter; + gpointer key; + GVariant *header_value; + GVariant *signature; + const gchar *signature_str; + gint num_fds_in_message; + gint num_fds_according_to_header; + + /* TODO: check against @capabilities */ + + ret = NULL; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + g_return_val_if_fail (out_size != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + memset (&mbuf, 0, sizeof (mbuf)); + mbuf.len = MIN_ARRAY_SIZE; + mbuf.data = g_malloc (mbuf.len); + + mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN; + switch (message->byte_order) + { + case G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN: + mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN; + break; + case G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN: + mbuf.byte_order = G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN; + break; + } + + /* Core header */ + g_memory_buffer_put_byte (&mbuf, (guchar) message->byte_order); + g_memory_buffer_put_byte (&mbuf, message->type); + g_memory_buffer_put_byte (&mbuf, message->flags); + g_memory_buffer_put_byte (&mbuf, 1); /* major protocol version */ + body_len_offset = mbuf.valid_len; + /* body length - will be filled in later */ + g_memory_buffer_put_uint32 (&mbuf, 0xF00DFACE); + g_memory_buffer_put_uint32 (&mbuf, message->serial); + + num_fds_in_message = 0; +#ifdef G_OS_UNIX + if (message->fd_list != NULL) + num_fds_in_message = g_unix_fd_list_get_length (message->fd_list); +#endif + num_fds_according_to_header = g_dbus_message_get_num_unix_fds (message); + if (num_fds_in_message != num_fds_according_to_header) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Number of file descriptors in message (%d) differs from header field (%d)"), + num_fds_in_message, + num_fds_according_to_header); + goto out; + } + + if (!validate_headers (message, error)) + { + g_prefix_error (error, _("Cannot serialize message: ")); + goto out; + } + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{yv}")); + g_hash_table_iter_init (&hash_iter, message->headers); + while (g_hash_table_iter_next (&hash_iter, &key, (gpointer) &header_value)) + { + g_variant_builder_add (&builder, + "{yv}", + (guchar) GPOINTER_TO_UINT (key), + header_value); + } + header_fields = g_variant_builder_end (&builder); + + if (!append_value_to_blob (header_fields, + g_variant_get_type (header_fields), + &mbuf, + NULL, + error)) + { + g_variant_unref (header_fields); + goto out; + } + g_variant_unref (header_fields); + + /* header size must be a multiple of 8 */ + ensure_output_padding (&mbuf, 8); + + body_start_offset = mbuf.valid_len; + + signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE); + + if (signature != NULL && !g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE)) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Signature header found but is not of type signature")); + goto out; + } + + signature_str = NULL; + if (signature != NULL) + signature_str = g_variant_get_string (signature, NULL); + if (message->body != NULL) + { + gchar *tupled_signature_str; + if (signature == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Message body has signature “%s†but there is no signature header"), + g_variant_get_type_string (message->body)); + goto out; + } + tupled_signature_str = g_strdup_printf ("(%s)", signature_str); + if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->body)) != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Message body has type signature “%s†but signature in the header field is “%sâ€"), + g_variant_get_type_string (message->body), tupled_signature_str); + g_free (tupled_signature_str); + goto out; + } + g_free (tupled_signature_str); + if (!append_body_to_blob (message->body, &mbuf, error)) + goto out; + } + else + { + if (signature != NULL && strlen (signature_str) > 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Message body is empty but signature in the header field is “(%s)â€"), + signature_str); + goto out; + } + } + + /* OK, we're done writing the message - set the body length */ + size = mbuf.valid_len; + body_size = size - body_start_offset; + + mbuf.pos = body_len_offset; + + g_memory_buffer_put_uint32 (&mbuf, body_size); + + *out_size = size; + ret = (guchar *)mbuf.data; + + out: + if (ret == NULL) + g_free (mbuf.data); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static guint32 +get_uint32_header (GDBusMessage *message, + GDBusMessageHeaderField header_field) +{ + GVariant *value; + guint32 ret; + + ret = 0; + value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field)); + if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32)) + ret = g_variant_get_uint32 (value); + + return ret; +} + +static const gchar * +get_string_header (GDBusMessage *message, + GDBusMessageHeaderField header_field) +{ + GVariant *value; + const gchar *ret; + + ret = NULL; + value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field)); + if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) + ret = g_variant_get_string (value, NULL); + + return ret; +} + +static const gchar * +get_object_path_header (GDBusMessage *message, + GDBusMessageHeaderField header_field) +{ + GVariant *value; + const gchar *ret; + + ret = NULL; + value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field)); + if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) + ret = g_variant_get_string (value, NULL); + + return ret; +} + +static const gchar * +get_signature_header (GDBusMessage *message, + GDBusMessageHeaderField header_field) +{ + GVariant *value; + const gchar *ret; + + ret = NULL; + value = g_hash_table_lookup (message->headers, GUINT_TO_POINTER (header_field)); + if (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE)) + ret = g_variant_get_string (value, NULL); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +set_uint32_header (GDBusMessage *message, + GDBusMessageHeaderField header_field, + guint32 value) +{ + g_dbus_message_set_header (message, + header_field, + g_variant_new_uint32 (value)); +} + +static void +set_string_header (GDBusMessage *message, + GDBusMessageHeaderField header_field, + const gchar *value) +{ + g_dbus_message_set_header (message, + header_field, + value == NULL ? NULL : g_variant_new_string (value)); +} + +static void +set_object_path_header (GDBusMessage *message, + GDBusMessageHeaderField header_field, + const gchar *value) +{ + g_dbus_message_set_header (message, + header_field, + value == NULL ? NULL : g_variant_new_object_path (value)); +} + +static void +set_signature_header (GDBusMessage *message, + GDBusMessageHeaderField header_field, + const gchar *value) +{ + g_dbus_message_set_header (message, + header_field, + value == NULL ? NULL : g_variant_new_signature (value)); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_reply_serial: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field. + * + * Returns: The value. + * + * Since: 2.26 + */ +guint32 +g_dbus_message_get_reply_serial (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0); + return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL); +} + +/** + * g_dbus_message_set_reply_serial: + * @message: A #GDBusMessage. + * @value: The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_reply_serial (GDBusMessage *message, + guint32 value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_interface: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field. + * + * Returns: (nullable): The value. + * + * Since: 2.26 + */ +const gchar * +g_dbus_message_get_interface (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE); +} + +/** + * g_dbus_message_set_interface: + * @message: A #GDBusMessage. + * @value: (nullable): The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_interface (GDBusMessage *message, + const gchar *value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (value == NULL || g_dbus_is_interface_name (value)); + set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_member: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field. + * + * Returns: (nullable): The value. + * + * Since: 2.26 + */ +const gchar * +g_dbus_message_get_member (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER); +} + +/** + * g_dbus_message_set_member: + * @message: A #GDBusMessage. + * @value: (nullable): The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_MEMBER header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_member (GDBusMessage *message, + const gchar *value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (value == NULL || g_dbus_is_member_name (value)); + set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_path: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field. + * + * Returns: (nullable): The value. + * + * Since: 2.26 + */ +const gchar * +g_dbus_message_get_path (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + return get_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH); +} + +/** + * g_dbus_message_set_path: + * @message: A #GDBusMessage. + * @value: (nullable): The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_PATH header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_path (GDBusMessage *message, + const gchar *value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (value == NULL || g_variant_is_object_path (value)); + set_object_path_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_sender: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field. + * + * Returns: (nullable): The value. + * + * Since: 2.26 + */ +const gchar * +g_dbus_message_get_sender (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER); +} + +/** + * g_dbus_message_set_sender: + * @message: A #GDBusMessage. + * @value: (nullable): The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SENDER header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_sender (GDBusMessage *message, + const gchar *value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (value == NULL || g_dbus_is_name (value)); + set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SENDER, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_destination: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field. + * + * Returns: (nullable): The value. + * + * Since: 2.26 + */ +const gchar * +g_dbus_message_get_destination (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION); +} + +/** + * g_dbus_message_set_destination: + * @message: A #GDBusMessage. + * @value: (nullable): The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_destination (GDBusMessage *message, + const gchar *value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (value == NULL || g_dbus_is_name (value)); + set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_error_name: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field. + * + * Returns: (nullable): The value. + * + * Since: 2.26 + */ +const gchar * +g_dbus_message_get_error_name (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + return get_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME); +} + +/** + * g_dbus_message_set_error_name: + * @message: (nullable): A #GDBusMessage. + * @value: The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_error_name (GDBusMessage *message, + const gchar *value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (value == NULL || g_dbus_is_error_name (value)); + set_string_header (message, G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_signature: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field. + * + * This will always be non-%NULL, but may be an empty string. + * + * Returns: (not nullable): The value. + * + * Since: 2.26 + */ +const gchar * +g_dbus_message_get_signature (GDBusMessage *message) +{ + const gchar *ret; + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + ret = get_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE); + if (ret == NULL) + ret = ""; + return ret; +} + +/** + * g_dbus_message_set_signature: + * @message: A #GDBusMessage. + * @value: (nullable): The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_signature (GDBusMessage *message, + const gchar *value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (value == NULL || g_variant_is_signature (value)); + set_signature_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_arg0: + * @message: A #GDBusMessage. + * + * Convenience to get the first item in the body of @message. + * + * Returns: (nullable): The string item or %NULL if the first item in the body of + * @message is not a string. + * + * Since: 2.26 + */ +const gchar * +g_dbus_message_get_arg0 (GDBusMessage *message) +{ + const gchar *ret; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + + ret = NULL; + + if (message->body != NULL && g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE)) + { + GVariant *item; + item = g_variant_get_child_value (message->body, 0); + if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING)) + ret = g_variant_get_string (item, NULL); + g_variant_unref (item); + } + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_get_num_unix_fds: + * @message: A #GDBusMessage. + * + * Convenience getter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field. + * + * Returns: The value. + * + * Since: 2.26 + */ +guint32 +g_dbus_message_get_num_unix_fds (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), 0); + return get_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS); +} + +/** + * g_dbus_message_set_num_unix_fds: + * @message: A #GDBusMessage. + * @value: The value to set. + * + * Convenience setter for the %G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS header field. + * + * Since: 2.26 + */ +void +g_dbus_message_set_num_unix_fds (GDBusMessage *message, + guint32 value) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + set_uint32_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, value); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_message_to_gerror: + * @message: A #GDBusMessage. + * @error: The #GError to set. + * + * If @message is not of type %G_DBUS_MESSAGE_TYPE_ERROR does + * nothing and returns %FALSE. + * + * Otherwise this method encodes the error in @message as a #GError + * using g_dbus_error_set_dbus_error() using the information in the + * %G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME header field of @message as + * well as the first string item in @message's body. + * + * Returns: %TRUE if @error was set, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_message_to_gerror (GDBusMessage *message, + GError **error) +{ + gboolean ret; + const gchar *error_name; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE); + + ret = FALSE; + if (message->type != G_DBUS_MESSAGE_TYPE_ERROR) + goto out; + + error_name = g_dbus_message_get_error_name (message); + if (error_name != NULL) + { + GVariant *body; + + body = g_dbus_message_get_body (message); + + if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(s)"))) + { + const gchar *error_message; + g_variant_get (body, "(&s)", &error_message); + g_dbus_error_set_dbus_error (error, + error_name, + error_message, + NULL); + } + else + { + /* these two situations are valid, yet pretty rare */ + if (body != NULL) + { + g_dbus_error_set_dbus_error (error, + error_name, + "", + _("Error return with body of type “%sâ€"), + g_variant_get_type_string (body)); + } + else + { + g_dbus_error_set_dbus_error (error, + error_name, + "", + _("Error return with empty body")); + } + } + } + else + { + /* TODO: this shouldn't happen - should check this at message serialization + * time and disconnect the peer. + */ + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Error return without error-name header!"); + } + + ret = TRUE; + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +flags_to_string (GType flags_type, guint value) +{ + GString *s; + GFlagsClass *klass; + guint n; + + klass = g_type_class_ref (flags_type); + s = g_string_new (NULL); + for (n = 0; n < 32; n++) + { + if ((value & (1<len > 0) + g_string_append_c (s, ','); + if (flags_value != NULL) + g_string_append (s, flags_value->value_nick); + else + g_string_append_printf (s, "unknown (bit %d)", n); + } + } + if (s->len == 0) + g_string_append (s, "none"); + g_type_class_unref (klass); + return g_string_free (s, FALSE); +} + +static gint +_sort_keys_func (gconstpointer a, + gconstpointer b) +{ + gint ia; + gint ib; + + ia = GPOINTER_TO_INT (a); + ib = GPOINTER_TO_INT (b); + + return ia - ib; +} + +/** + * g_dbus_message_print: + * @message: A #GDBusMessage. + * @indent: Indentation level. + * + * Produces a human-readable multi-line description of @message. + * + * The contents of the description has no ABI guarantees, the contents + * and formatting is subject to change at any time. Typical output + * looks something like this: + * |[ + * Type: method-call + * Flags: none + * Version: 0 + * Serial: 4 + * Headers: + * path -> objectpath '/org/gtk/GDBus/TestObject' + * interface -> 'org.gtk.GDBus.TestInterface' + * member -> 'GimmeStdout' + * destination -> ':1.146' + * Body: () + * UNIX File Descriptors: + * (none) + * ]| + * or + * |[ + * Type: method-return + * Flags: no-reply-expected + * Version: 0 + * Serial: 477 + * Headers: + * reply-serial -> uint32 4 + * destination -> ':1.159' + * sender -> ':1.146' + * num-unix-fds -> uint32 1 + * Body: () + * UNIX File Descriptors: + * fd 12: dev=0:10,mode=020620,ino=5,uid=500,gid=5,rdev=136:2,size=0,atime=1273085037,mtime=1273085851,ctime=1272982635 + * ]| + * + * Returns: (not nullable): A string that should be freed with g_free(). + * + * Since: 2.26 + */ +gchar * +g_dbus_message_print (GDBusMessage *message, + guint indent) +{ + GString *str; + gchar *s; + GList *keys; + GList *l; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + + str = g_string_new (NULL); + + s = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, message->type); + g_string_append_printf (str, "%*sType: %s\n", indent, "", s); + g_free (s); + s = flags_to_string (G_TYPE_DBUS_MESSAGE_FLAGS, message->flags); + g_string_append_printf (str, "%*sFlags: %s\n", indent, "", s); + g_free (s); + g_string_append_printf (str, "%*sVersion: %d\n", indent, "", message->major_protocol_version); + g_string_append_printf (str, "%*sSerial: %d\n", indent, "", message->serial); + + g_string_append_printf (str, "%*sHeaders:\n", indent, ""); + keys = g_hash_table_get_keys (message->headers); + keys = g_list_sort (keys, _sort_keys_func); + if (keys != NULL) + { + for (l = keys; l != NULL; l = l->next) + { + gint key = GPOINTER_TO_INT (l->data); + GVariant *value; + gchar *value_str; + + value = g_hash_table_lookup (message->headers, l->data); + g_assert (value != NULL); + + s = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_HEADER_FIELD, key); + value_str = g_variant_print (value, TRUE); + g_string_append_printf (str, "%*s %s -> %s\n", indent, "", s, value_str); + g_free (s); + g_free (value_str); + } + } + else + { + g_string_append_printf (str, "%*s (none)\n", indent, ""); + } + g_list_free (keys); + g_string_append_printf (str, "%*sBody: ", indent, ""); + if (message->body != NULL) + { + g_variant_print_string (message->body, + str, + TRUE); + } + else + { + g_string_append (str, "()"); + } + g_string_append (str, "\n"); +#ifdef G_OS_UNIX + g_string_append_printf (str, "%*sUNIX File Descriptors:\n", indent, ""); + if (message->fd_list != NULL) + { + gint num_fds; + const gint *fds; + gint n; + + fds = g_unix_fd_list_peek_fds (message->fd_list, &num_fds); + if (num_fds > 0) + { + for (n = 0; n < num_fds; n++) + { + GString *fs; + struct stat statbuf; + fs = g_string_new (NULL); + if (fstat (fds[n], &statbuf) == 0) + { +#ifndef MAJOR_MINOR_NOT_FOUND + g_string_append_printf (fs, "%s" "dev=%d:%d", fs->len > 0 ? "," : "", + (gint) major (statbuf.st_dev), (gint) minor (statbuf.st_dev)); +#endif + g_string_append_printf (fs, "%s" "mode=0%o", fs->len > 0 ? "," : "", + (guint) statbuf.st_mode); + g_string_append_printf (fs, "%s" "ino=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "", + (guint64) statbuf.st_ino); + g_string_append_printf (fs, "%s" "uid=%u", fs->len > 0 ? "," : "", + (guint) statbuf.st_uid); + g_string_append_printf (fs, "%s" "gid=%u", fs->len > 0 ? "," : "", + (guint) statbuf.st_gid); +#ifndef MAJOR_MINOR_NOT_FOUND + g_string_append_printf (fs, "%s" "rdev=%d:%d", fs->len > 0 ? "," : "", + (gint) major (statbuf.st_rdev), (gint) minor (statbuf.st_rdev)); +#endif + g_string_append_printf (fs, "%s" "size=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "", + (guint64) statbuf.st_size); + g_string_append_printf (fs, "%s" "atime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "", + (guint64) statbuf.st_atime); + g_string_append_printf (fs, "%s" "mtime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "", + (guint64) statbuf.st_mtime); + g_string_append_printf (fs, "%s" "ctime=%" G_GUINT64_FORMAT, fs->len > 0 ? "," : "", + (guint64) statbuf.st_ctime); + } + else + { + int errsv = errno; + g_string_append_printf (fs, "(fstat failed: %s)", g_strerror (errsv)); + } + g_string_append_printf (str, "%*s fd %d: %s\n", indent, "", fds[n], fs->str); + g_string_free (fs, TRUE); + } + } + else + { + g_string_append_printf (str, "%*s (empty)\n", indent, ""); + } + } + else + { + g_string_append_printf (str, "%*s (none)\n", indent, ""); + } +#endif + + return g_string_free (str, FALSE); +} + +/** + * g_dbus_message_get_locked: + * @message: A #GDBusMessage. + * + * Checks whether @message is locked. To monitor changes to this + * value, conncet to the #GObject::notify signal to listen for changes + * on the #GDBusMessage:locked property. + * + * Returns: %TRUE if @message is locked, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_message_get_locked (GDBusMessage *message) +{ + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), FALSE); + return message->locked; +} + +/** + * g_dbus_message_lock: + * @message: A #GDBusMessage. + * + * If @message is locked, does nothing. Otherwise locks the message. + * + * Since: 2.26 + */ +void +g_dbus_message_lock (GDBusMessage *message) +{ + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + + if (message->locked) + goto out; + + message->locked = TRUE; + g_object_notify (G_OBJECT (message), "locked"); + + out: + ; +} + +/** + * g_dbus_message_copy: + * @message: A #GDBusMessage. + * @error: Return location for error or %NULL. + * + * Copies @message. The copy is a deep copy and the returned + * #GDBusMessage is completely identical except that it is guaranteed + * to not be locked. + * + * This operation can fail if e.g. @message contains file descriptors + * and the per-process or system-wide open files limit is reached. + * + * Returns: (transfer full): A new #GDBusMessage or %NULL if @error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_message_copy (GDBusMessage *message, + GError **error) +{ + GDBusMessage *ret; + GHashTableIter iter; + gpointer header_key; + GVariant *header_value; + + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + ret = g_dbus_message_new (); + ret->type = message->type; + ret->flags = message->flags; + ret->byte_order = message->byte_order; + ret->major_protocol_version = message->major_protocol_version; + ret->serial = message->serial; + +#ifdef G_OS_UNIX + if (message->fd_list != NULL) + { + gint n; + gint num_fds; + const gint *fds; + + ret->fd_list = g_unix_fd_list_new (); + fds = g_unix_fd_list_peek_fds (message->fd_list, &num_fds); + for (n = 0; n < num_fds; n++) + { + if (g_unix_fd_list_append (ret->fd_list, + fds[n], + error) == -1) + { + g_object_unref (ret); + ret = NULL; + goto out; + } + } + } +#endif + + /* see https://bugzilla.gnome.org/show_bug.cgi?id=624546#c8 for why it's fine + * to just ref (as opposed to deep-copying) the GVariant instances + */ + ret->body = message->body != NULL ? g_variant_ref (message->body) : NULL; + g_hash_table_iter_init (&iter, message->headers); + while (g_hash_table_iter_next (&iter, &header_key, (gpointer) &header_value)) + g_hash_table_insert (ret->headers, header_key, g_variant_ref (header_value)); + +#ifdef G_OS_UNIX + out: +#endif + return ret; +} diff --git a/gio/gdbusmessage.h b/gio/gdbusmessage.h new file mode 100644 index 0000000..5f039dc --- /dev/null +++ b/gio/gdbusmessage.h @@ -0,0 +1,197 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_MESSAGE_H__ +#define __G_DBUS_MESSAGE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_MESSAGE (g_dbus_message_get_type ()) +#define G_DBUS_MESSAGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_MESSAGE, GDBusMessage)) +#define G_IS_DBUS_MESSAGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_MESSAGE)) + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_message_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_new (void); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_new_signal (const gchar *path, + const gchar *interface_, + const gchar *signal); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_new_method_call (const gchar *name, + const gchar *path, + const gchar *interface_, + const gchar *method); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_new_method_reply (GDBusMessage *method_call_message); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_new_method_error (GDBusMessage *method_call_message, + const gchar *error_name, + const gchar *error_message_format, + ...) G_GNUC_PRINTF(3, 4); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_new_method_error_valist (GDBusMessage *method_call_message, + const gchar *error_name, + const gchar *error_message_format, + va_list var_args); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_new_method_error_literal (GDBusMessage *method_call_message, + const gchar *error_name, + const gchar *error_message); +GLIB_AVAILABLE_IN_ALL +gchar *g_dbus_message_print (GDBusMessage *message, + guint indent); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_message_get_locked (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_lock (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_copy (GDBusMessage *message, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusMessageByteOrder g_dbus_message_get_byte_order (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_byte_order (GDBusMessage *message, + GDBusMessageByteOrder byte_order); + +GLIB_AVAILABLE_IN_ALL +GDBusMessageType g_dbus_message_get_message_type (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_message_type (GDBusMessage *message, + GDBusMessageType type); +GLIB_AVAILABLE_IN_ALL +GDBusMessageFlags g_dbus_message_get_flags (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_flags (GDBusMessage *message, + GDBusMessageFlags flags); +GLIB_AVAILABLE_IN_ALL +guint32 g_dbus_message_get_serial (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_serial (GDBusMessage *message, + guint32 serial); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_message_get_header (GDBusMessage *message, + GDBusMessageHeaderField header_field); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_header (GDBusMessage *message, + GDBusMessageHeaderField header_field, + GVariant *value); +GLIB_AVAILABLE_IN_ALL +guchar *g_dbus_message_get_header_fields (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_message_get_body (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_body (GDBusMessage *message, + GVariant *body); +GLIB_AVAILABLE_IN_ALL +GUnixFDList *g_dbus_message_get_unix_fd_list (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_unix_fd_list (GDBusMessage *message, + GUnixFDList *fd_list); + +GLIB_AVAILABLE_IN_ALL +guint32 g_dbus_message_get_reply_serial (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_reply_serial (GDBusMessage *message, + guint32 value); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_message_get_interface (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_interface (GDBusMessage *message, + const gchar *value); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_message_get_member (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_member (GDBusMessage *message, + const gchar *value); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_message_get_path (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_path (GDBusMessage *message, + const gchar *value); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_message_get_sender (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_sender (GDBusMessage *message, + const gchar *value); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_message_get_destination (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_destination (GDBusMessage *message, + const gchar *value); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_message_get_error_name (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_error_name (GDBusMessage *message, + const gchar *value); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_message_get_signature (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_signature (GDBusMessage *message, + const gchar *value); + +GLIB_AVAILABLE_IN_ALL +guint32 g_dbus_message_get_num_unix_fds (GDBusMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_message_set_num_unix_fds (GDBusMessage *message, + guint32 value); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_message_get_arg0 (GDBusMessage *message); + + +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_message_new_from_blob (guchar *blob, + gsize blob_len, + GDBusCapabilityFlags capabilities, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gssize g_dbus_message_bytes_needed (guchar *blob, + gsize blob_len, + GError **error); + +GLIB_AVAILABLE_IN_ALL +guchar *g_dbus_message_to_blob (GDBusMessage *message, + gsize *out_size, + GDBusCapabilityFlags capabilities, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_message_to_gerror (GDBusMessage *message, + GError **error); + +G_END_DECLS + +#endif /* __G_DBUS_MESSAGE_H__ */ diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c new file mode 100644 index 0000000..705af07 --- /dev/null +++ b/gio/gdbusmethodinvocation.c @@ -0,0 +1,838 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include + +#include "gdbusutils.h" +#include "gdbusconnection.h" +#include "gdbusmessage.h" +#include "gdbusmethodinvocation.h" +#include "gdbusintrospection.h" +#include "gdbuserror.h" +#include "gdbusprivate.h" +#include "gioerror.h" + +#ifdef G_OS_UNIX +#include "gunixfdlist.h" +#endif + +#include "glibintl.h" + +/** + * SECTION:gdbusmethodinvocation + * @short_description: Object for handling remote calls + * @include: gio/gio.h + * + * Instances of the #GDBusMethodInvocation class are used when + * handling D-Bus method calls. It provides a way to asynchronously + * return results and errors. + * + * The normal way to obtain a #GDBusMethodInvocation object is to receive + * it as an argument to the handle_method_call() function in a + * #GDBusInterfaceVTable that was passed to g_dbus_connection_register_object(). + */ + +typedef struct _GDBusMethodInvocationClass GDBusMethodInvocationClass; + +/** + * GDBusMethodInvocationClass: + * + * Class structure for #GDBusMethodInvocation. + * + * Since: 2.26 + */ +struct _GDBusMethodInvocationClass +{ + /*< private >*/ + GObjectClass parent_class; +}; + +/** + * GDBusMethodInvocation: + * + * The #GDBusMethodInvocation structure contains only private data and + * should only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GDBusMethodInvocation +{ + /*< private >*/ + GObject parent_instance; + + /* construct-only properties */ + gchar *sender; + gchar *object_path; + gchar *interface_name; + gchar *method_name; + GDBusMethodInfo *method_info; + GDBusPropertyInfo *property_info; + GDBusConnection *connection; + GDBusMessage *message; + GVariant *parameters; + gpointer user_data; +}; + +G_DEFINE_TYPE (GDBusMethodInvocation, g_dbus_method_invocation, G_TYPE_OBJECT) + +static void +g_dbus_method_invocation_finalize (GObject *object) +{ + GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (object); + + g_free (invocation->sender); + g_free (invocation->object_path); + g_free (invocation->interface_name); + g_free (invocation->method_name); + if (invocation->method_info) + g_dbus_method_info_unref (invocation->method_info); + if (invocation->property_info) + g_dbus_property_info_unref (invocation->property_info); + g_object_unref (invocation->connection); + g_object_unref (invocation->message); + g_variant_unref (invocation->parameters); + + G_OBJECT_CLASS (g_dbus_method_invocation_parent_class)->finalize (object); +} + +static void +g_dbus_method_invocation_class_init (GDBusMethodInvocationClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_method_invocation_finalize; +} + +static void +g_dbus_method_invocation_init (GDBusMethodInvocation *invocation) +{ +} + +/** + * g_dbus_method_invocation_get_sender: + * @invocation: A #GDBusMethodInvocation. + * + * Gets the bus name that invoked the method. + * + * Returns: A string. Do not free, it is owned by @invocation. + * + * Since: 2.26 + */ +const gchar * +g_dbus_method_invocation_get_sender (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->sender; +} + +/** + * g_dbus_method_invocation_get_object_path: + * @invocation: A #GDBusMethodInvocation. + * + * Gets the object path the method was invoked on. + * + * Returns: A string. Do not free, it is owned by @invocation. + * + * Since: 2.26 + */ +const gchar * +g_dbus_method_invocation_get_object_path (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->object_path; +} + +/** + * g_dbus_method_invocation_get_interface_name: + * @invocation: A #GDBusMethodInvocation. + * + * Gets the name of the D-Bus interface the method was invoked on. + * + * If this method call is a property Get, Set or GetAll call that has + * been redirected to the method call handler then + * "org.freedesktop.DBus.Properties" will be returned. See + * #GDBusInterfaceVTable for more information. + * + * Returns: A string. Do not free, it is owned by @invocation. + * + * Since: 2.26 + */ +const gchar * +g_dbus_method_invocation_get_interface_name (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->interface_name; +} + +/** + * g_dbus_method_invocation_get_method_info: + * @invocation: A #GDBusMethodInvocation. + * + * Gets information about the method call, if any. + * + * If this method invocation is a property Get, Set or GetAll call that + * has been redirected to the method call handler then %NULL will be + * returned. See g_dbus_method_invocation_get_property_info() and + * #GDBusInterfaceVTable for more information. + * + * Returns: (nullable): A #GDBusMethodInfo or %NULL. Do not free, it is owned by @invocation. + * + * Since: 2.26 + */ +const GDBusMethodInfo * +g_dbus_method_invocation_get_method_info (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->method_info; +} + +/** + * g_dbus_method_invocation_get_property_info: + * @invocation: A #GDBusMethodInvocation + * + * Gets information about the property that this method call is for, if + * any. + * + * This will only be set in the case of an invocation in response to a + * property Get or Set call that has been directed to the method call + * handler for an object on account of its property_get() or + * property_set() vtable pointers being unset. + * + * See #GDBusInterfaceVTable for more information. + * + * If the call was GetAll, %NULL will be returned. + * + * Returns: (nullable) (transfer none): a #GDBusPropertyInfo or %NULL + * + * Since: 2.38 + */ +const GDBusPropertyInfo * +g_dbus_method_invocation_get_property_info (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->property_info; +} + +/** + * g_dbus_method_invocation_get_method_name: + * @invocation: A #GDBusMethodInvocation. + * + * Gets the name of the method that was invoked. + * + * Returns: A string. Do not free, it is owned by @invocation. + * + * Since: 2.26 + */ +const gchar * +g_dbus_method_invocation_get_method_name (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->method_name; +} + +/** + * g_dbus_method_invocation_get_connection: + * @invocation: A #GDBusMethodInvocation. + * + * Gets the #GDBusConnection the method was invoked on. + * + * Returns: (transfer none):A #GDBusConnection. Do not free, it is owned by @invocation. + * + * Since: 2.26 + */ +GDBusConnection * +g_dbus_method_invocation_get_connection (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->connection; +} + +/** + * g_dbus_method_invocation_get_message: + * @invocation: A #GDBusMethodInvocation. + * + * Gets the #GDBusMessage for the method invocation. This is useful if + * you need to use low-level protocol features, such as UNIX file + * descriptor passing, that cannot be properly expressed in the + * #GVariant API. + * + * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] + * for an example of how to use this low-level API to send and receive + * UNIX file descriptors. + * + * Returns: (transfer none): #GDBusMessage. Do not free, it is owned by @invocation. + * + * Since: 2.26 + */ +GDBusMessage * +g_dbus_method_invocation_get_message (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->message; +} + +/** + * g_dbus_method_invocation_get_parameters: + * @invocation: A #GDBusMethodInvocation. + * + * Gets the parameters of the method invocation. If there are no input + * parameters then this will return a GVariant with 0 children rather than NULL. + * + * Returns: (transfer none): A #GVariant tuple. Do not unref this because it is owned by @invocation. + * + * Since: 2.26 + */ +GVariant * +g_dbus_method_invocation_get_parameters (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->parameters; +} + +/** + * g_dbus_method_invocation_get_user_data: (skip) + * @invocation: A #GDBusMethodInvocation. + * + * Gets the @user_data #gpointer passed to g_dbus_connection_register_object(). + * + * Returns: A #gpointer. + * + * Since: 2.26 + */ +gpointer +g_dbus_method_invocation_get_user_data (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->user_data; +} + +/* < internal > + * _g_dbus_method_invocation_new: + * @sender: (nullable): The bus name that invoked the method or %NULL if @connection is not a bus connection. + * @object_path: The object path the method was invoked on. + * @interface_name: The name of the D-Bus interface the method was invoked on. + * @method_name: The name of the method that was invoked. + * @method_info: (nullable): Information about the method call or %NULL. + * @property_info: (nullable): Information about the property or %NULL. + * @connection: The #GDBusConnection the method was invoked on. + * @message: The D-Bus message as a #GDBusMessage. + * @parameters: The parameters as a #GVariant tuple. + * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_object(). + * + * Creates a new #GDBusMethodInvocation object. + * + * Returns: A #GDBusMethodInvocation. Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusMethodInvocation * +_g_dbus_method_invocation_new (const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + const GDBusMethodInfo *method_info, + const GDBusPropertyInfo *property_info, + GDBusConnection *connection, + GDBusMessage *message, + GVariant *parameters, + gpointer user_data) +{ + GDBusMethodInvocation *invocation; + + g_return_val_if_fail (sender == NULL || g_dbus_is_name (sender), NULL); + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + g_return_val_if_fail (interface_name == NULL || g_dbus_is_interface_name (interface_name), NULL); + g_return_val_if_fail (g_dbus_is_member_name (method_name), NULL); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); + g_return_val_if_fail (g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL); + + invocation = G_DBUS_METHOD_INVOCATION (g_object_new (G_TYPE_DBUS_METHOD_INVOCATION, NULL)); + invocation->sender = g_strdup (sender); + invocation->object_path = g_strdup (object_path); + invocation->interface_name = g_strdup (interface_name); + invocation->method_name = g_strdup (method_name); + if (method_info) + invocation->method_info = g_dbus_method_info_ref ((GDBusMethodInfo *)method_info); + if (property_info) + invocation->property_info = g_dbus_property_info_ref ((GDBusPropertyInfo *)property_info); + invocation->connection = g_object_ref (connection); + invocation->message = g_object_ref (message); + invocation->parameters = g_variant_ref (parameters); + invocation->user_data = user_data; + + return invocation; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation, + GVariant *parameters, + GUnixFDList *fd_list) +{ + GDBusMessage *reply; + GError *error; + + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); + + if (g_dbus_message_get_flags (invocation->message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) + goto out; + + if (parameters == NULL) + parameters = g_variant_new_tuple (NULL, 0); + + /* if we have introspection data, check that the signature of @parameters is correct */ + if (invocation->method_info != NULL) + { + GVariantType *type; + + type = _g_dbus_compute_complete_signature (invocation->method_info->out_args); + + if (!g_variant_is_of_type (parameters, type)) + { + gchar *type_string = g_variant_type_dup_string (type); + + g_warning ("Type of return value is incorrect: expected '%s', got '%s'", + type_string, g_variant_get_type_string (parameters)); + g_variant_type_free (type); + g_free (type_string); + goto out; + } + g_variant_type_free (type); + } + + /* property_info is only non-NULL if set that way from + * GDBusConnection, so this must be the case of async property + * handling on either 'Get' or 'Set'. + * + * property_info is NULL for 'GetAll'. + */ + if (invocation->property_info != NULL) + { + if (g_str_equal (invocation->method_name, "Get")) + { + GVariant *nested; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(v)"))) + { + g_warning ("Type of return value for property 'Get' call should be '(v)' but got '%s'", + g_variant_get_type_string (parameters)); + goto out; + } + + /* Go deeper and make sure that the value inside of the + * variant matches the property type. + */ + g_variant_get (parameters, "(v)", &nested); + if (!g_str_equal (g_variant_get_type_string (nested), invocation->property_info->signature)) + { + g_warning ("Value returned from property 'Get' call for '%s' should be '%s' but is '%s'", + invocation->property_info->name, invocation->property_info->signature, + g_variant_get_type_string (nested)); + g_variant_unref (nested); + goto out; + } + g_variant_unref (nested); + } + + else if (g_str_equal (invocation->method_name, "Set")) + { + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT)) + { + g_warning ("Type of return value for property 'Set' call should be '()' but got '%s'", + g_variant_get_type_string (parameters)); + goto out; + } + } + + else + g_assert_not_reached (); + } + else if (g_str_equal (invocation->interface_name, "org.freedesktop.DBus.Properties") && + g_str_equal (invocation->method_name, "GetAll")) + { + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})"))) + { + g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'", + g_variant_get_type_string (parameters)); + goto out; + } + + /* Could iterate the list of properties and make sure that all + * of them are actually on the interface and with the correct + * types, but let's not do that for now... + */ + } + + if (G_UNLIKELY (_g_dbus_debug_return ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Return:\n" + " >>>> METHOD RETURN\n" + " in response to %s.%s()\n" + " on object %s\n" + " to name %s\n" + " reply-serial %d\n", + invocation->interface_name, invocation->method_name, + invocation->object_path, + invocation->sender, + g_dbus_message_get_serial (invocation->message)); + _g_dbus_debug_print_unlock (); + } + + reply = g_dbus_message_new_method_reply (invocation->message); + g_dbus_message_set_body (reply, g_steal_pointer (¶meters)); + +#ifdef G_OS_UNIX + if (fd_list != NULL) + g_dbus_message_set_unix_fd_list (reply, fd_list); +#endif + + error = NULL; + if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED)) + g_warning ("Error sending message: %s", error->message); + g_error_free (error); + } + g_object_unref (reply); + + out: + if (parameters != NULL) + { + g_variant_ref_sink (parameters); + g_variant_unref (parameters); + } + + g_object_unref (invocation); +} + +/** + * g_dbus_method_invocation_return_value: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @parameters: (nullable): A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters. + * + * Finishes handling a D-Bus method call by returning @parameters. + * If the @parameters GVariant is floating, it is consumed. + * + * It is an error if @parameters is not of the right format: it must be a tuple + * containing the out-parameters of the D-Bus method. Even if the method has a + * single out-parameter, it must be contained in a tuple. If the method has no + * out-parameters, @parameters may be %NULL or an empty tuple. + * + * |[ + * GDBusMethodInvocation *invocation = some_invocation; + * g_autofree gchar *result_string = NULL; + * g_autoptr (GError) error = NULL; + * + * result_string = calculate_result (&error); + * + * if (error != NULL) + * g_dbus_method_invocation_return_gerror (invocation, error); + * else + * g_dbus_method_invocation_return_value (invocation, + * g_variant_new ("(s)", result_string)); + * + * // Do not free @invocation here; returning a value does that + * ]| + * + * This method will take ownership of @invocation. See + * #GDBusInterfaceVTable for more information about the ownership of + * @invocation. + * + * Since 2.48, if the method call requested for a reply not to be sent + * then this call will sink @parameters and free @invocation, but + * otherwise do nothing (as per the recommendations of the D-Bus + * specification). + * + * Since: 2.26 + */ +void +g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + g_dbus_method_invocation_return_value_internal (invocation, parameters, NULL); +} + +#ifdef G_OS_UNIX +/** + * g_dbus_method_invocation_return_value_with_unix_fd_list: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @parameters: (nullable): A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters. + * @fd_list: (nullable): A #GUnixFDList or %NULL. + * + * Like g_dbus_method_invocation_return_value() but also takes a #GUnixFDList. + * + * This method is only available on UNIX. + * + * This method will take ownership of @invocation. See + * #GDBusInterfaceVTable for more information about the ownership of + * @invocation. + * + * Since: 2.30 + */ +void +g_dbus_method_invocation_return_value_with_unix_fd_list (GDBusMethodInvocation *invocation, + GVariant *parameters, + GUnixFDList *fd_list) +{ + g_dbus_method_invocation_return_value_internal (invocation, parameters, fd_list); +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_method_invocation_return_error: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @domain: A #GQuark for the #GError error domain. + * @code: The error code. + * @format: printf()-style format. + * @...: Parameters for @format. + * + * Finishes handling a D-Bus method call by returning an error. + * + * See g_dbus_error_encode_gerror() for details about what error name + * will be returned on the wire. In a nutshell, if the given error is + * registered using g_dbus_error_register_error() the name given + * during registration is used. Otherwise, a name of the form + * `org.gtk.GDBus.UnmappedGError.Quark...` is used. This provides + * transparent mapping of #GError between applications using GDBus. + * + * If you are writing an application intended to be portable, + * always register errors with g_dbus_error_register_error() + * or use g_dbus_method_invocation_return_dbus_error(). + * + * This method will take ownership of @invocation. See + * #GDBusInterfaceVTable for more information about the ownership of + * @invocation. + * + * Since 2.48, if the method call requested for a reply not to be sent + * then this call will free @invocation but otherwise do nothing (as per + * the recommendations of the D-Bus specification). + * + * Since: 2.26 + */ +void +g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation, + GQuark domain, + gint code, + const gchar *format, + ...) +{ + va_list var_args; + + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail (format != NULL); + + va_start (var_args, format); + g_dbus_method_invocation_return_error_valist (invocation, + domain, + code, + format, + var_args); + va_end (var_args); +} + +/** + * g_dbus_method_invocation_return_error_valist: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @domain: A #GQuark for the #GError error domain. + * @code: The error code. + * @format: printf()-style format. + * @var_args: #va_list of parameters for @format. + * + * Like g_dbus_method_invocation_return_error() but intended for + * language bindings. + * + * This method will take ownership of @invocation. See + * #GDBusInterfaceVTable for more information about the ownership of + * @invocation. + * + * Since: 2.26 + */ +void +g_dbus_method_invocation_return_error_valist (GDBusMethodInvocation *invocation, + GQuark domain, + gint code, + const gchar *format, + va_list var_args) +{ + gchar *literal_message; + + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail (format != NULL); + + literal_message = g_strdup_vprintf (format, var_args); + g_dbus_method_invocation_return_error_literal (invocation, + domain, + code, + literal_message); + g_free (literal_message); +} + +/** + * g_dbus_method_invocation_return_error_literal: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @domain: A #GQuark for the #GError error domain. + * @code: The error code. + * @message: The error message. + * + * Like g_dbus_method_invocation_return_error() but without printf()-style formatting. + * + * This method will take ownership of @invocation. See + * #GDBusInterfaceVTable for more information about the ownership of + * @invocation. + * + * Since: 2.26 + */ +void +g_dbus_method_invocation_return_error_literal (GDBusMethodInvocation *invocation, + GQuark domain, + gint code, + const gchar *message) +{ + GError *error; + + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail (message != NULL); + + error = g_error_new_literal (domain, code, message); + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); +} + +/** + * g_dbus_method_invocation_return_gerror: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @error: A #GError. + * + * Like g_dbus_method_invocation_return_error() but takes a #GError + * instead of the error domain, error code and message. + * + * This method will take ownership of @invocation. See + * #GDBusInterfaceVTable for more information about the ownership of + * @invocation. + * + * Since: 2.26 + */ +void +g_dbus_method_invocation_return_gerror (GDBusMethodInvocation *invocation, + const GError *error) +{ + gchar *dbus_error_name; + + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail (error != NULL); + + dbus_error_name = g_dbus_error_encode_gerror (error); + + g_dbus_method_invocation_return_dbus_error (invocation, + dbus_error_name, + error->message); + g_free (dbus_error_name); +} + +/** + * g_dbus_method_invocation_take_error: (skip) + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @error: (transfer full): A #GError. + * + * Like g_dbus_method_invocation_return_gerror() but takes ownership + * of @error so the caller does not need to free it. + * + * This method will take ownership of @invocation. See + * #GDBusInterfaceVTable for more information about the ownership of + * @invocation. + * + * Since: 2.30 + */ +void +g_dbus_method_invocation_take_error (GDBusMethodInvocation *invocation, + GError *error) +{ + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail (error != NULL); + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); +} + +/** + * g_dbus_method_invocation_return_dbus_error: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @error_name: A valid D-Bus error name. + * @error_message: A valid D-Bus error message. + * + * Finishes handling a D-Bus method call by returning an error. + * + * This method will take ownership of @invocation. See + * #GDBusInterfaceVTable for more information about the ownership of + * @invocation. + * + * Since: 2.26 + */ +void +g_dbus_method_invocation_return_dbus_error (GDBusMethodInvocation *invocation, + const gchar *error_name, + const gchar *error_message) +{ + GDBusMessage *reply; + + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail (error_name != NULL && g_dbus_is_name (error_name)); + g_return_if_fail (error_message != NULL); + + if (g_dbus_message_get_flags (invocation->message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) + goto out; + + if (G_UNLIKELY (_g_dbus_debug_return ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Return:\n" + " >>>> METHOD ERROR %s\n" + " message '%s'\n" + " in response to %s.%s()\n" + " on object %s\n" + " to name %s\n" + " reply-serial %d\n", + error_name, + error_message, + invocation->interface_name, invocation->method_name, + invocation->object_path, + invocation->sender, + g_dbus_message_get_serial (invocation->message)); + _g_dbus_debug_print_unlock (); + } + + reply = g_dbus_message_new_method_error_literal (invocation->message, + error_name, + error_message); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (reply); + +out: + g_object_unref (invocation); +} diff --git a/gio/gdbusmethodinvocation.h b/gio/gdbusmethodinvocation.h new file mode 100644 index 0000000..775070a --- /dev/null +++ b/gio/gdbusmethodinvocation.h @@ -0,0 +1,132 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_METHOD_INVOCATION_H__ +#define __G_DBUS_METHOD_INVOCATION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_METHOD_INVOCATION (g_dbus_method_invocation_get_type ()) +#define G_DBUS_METHOD_INVOCATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_METHOD_INVOCATION, GDBusMethodInvocation)) +#define G_IS_DBUS_METHOD_INVOCATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_METHOD_INVOCATION)) + +/** + * G_DBUS_METHOD_INVOCATION_HANDLED: + * + * The value returned by handlers of the signals generated by + * the `gdbus-codegen` tool to indicate that a method call has been + * handled by an implementation. It is equal to %TRUE, but using + * this macro is sometimes more readable. + * + * In code that needs to be backwards-compatible with older GLib, + * use %TRUE instead, often written like this: + * + * |[ + * g_dbus_method_invocation_return_error (invocation, ...); + * return TRUE; // handled + * ]| + * + * Since: 2.68 + */ +#define G_DBUS_METHOD_INVOCATION_HANDLED TRUE GLIB_AVAILABLE_MACRO_IN_2_68 + +/** + * G_DBUS_METHOD_INVOCATION_UNHANDLED: + * + * The value returned by handlers of the signals generated by + * the `gdbus-codegen` tool to indicate that a method call has not been + * handled by an implementation. It is equal to %FALSE, but using + * this macro is sometimes more readable. + * + * In code that needs to be backwards-compatible with older GLib, + * use %FALSE instead. + * + * Since: 2.68 + */ +#define G_DBUS_METHOD_INVOCATION_UNHANDLED FALSE GLIB_AVAILABLE_MACRO_IN_2_68 + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_method_invocation_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_method_invocation_get_sender (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_method_invocation_get_object_path (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_method_invocation_get_interface_name (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_method_invocation_get_method_name (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_ALL +const GDBusMethodInfo *g_dbus_method_invocation_get_method_info (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_2_38 +const GDBusPropertyInfo *g_dbus_method_invocation_get_property_info (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_method_invocation_get_connection (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_ALL +GDBusMessage *g_dbus_method_invocation_get_message (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_method_invocation_get_parameters (GDBusMethodInvocation *invocation); +GLIB_AVAILABLE_IN_ALL +gpointer g_dbus_method_invocation_get_user_data (GDBusMethodInvocation *invocation); + +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, + GVariant *parameters); +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_invocation_return_value_with_unix_fd_list (GDBusMethodInvocation *invocation, + GVariant *parameters, + GUnixFDList *fd_list); +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation, + GQuark domain, + gint code, + const gchar *format, + ...) G_GNUC_PRINTF(4, 5); +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_invocation_return_error_valist (GDBusMethodInvocation *invocation, + GQuark domain, + gint code, + const gchar *format, + va_list var_args) + G_GNUC_PRINTF(4, 0); +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_invocation_return_error_literal (GDBusMethodInvocation *invocation, + GQuark domain, + gint code, + const gchar *message); +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_invocation_return_gerror (GDBusMethodInvocation *invocation, + const GError *error); +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_invocation_take_error (GDBusMethodInvocation *invocation, + GError *error); +GLIB_AVAILABLE_IN_ALL +void g_dbus_method_invocation_return_dbus_error (GDBusMethodInvocation *invocation, + const gchar *error_name, + const gchar *error_message); + +G_END_DECLS + +#endif /* __G_DBUS_METHOD_INVOCATION_H__ */ diff --git a/gio/gdbusnameowning.c b/gio/gdbusnameowning.c new file mode 100644 index 0000000..879da0b --- /dev/null +++ b/gio/gdbusnameowning.c @@ -0,0 +1,991 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include + +#include "gdbusutils.h" +#include "gdbusnameowning.h" +#include "gdbuserror.h" +#include "gdbusprivate.h" +#include "gdbusconnection.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusnameowning + * @title: Owning Bus Names + * @short_description: Simple API for owning bus names + * @include: gio/gio.h + * + * Convenience API for owning bus names. + * + * A simple example for owning a name can be found in + * [gdbus-example-own-name.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-own-name.c) + */ + +G_LOCK_DEFINE_STATIC (lock); + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef enum +{ + PREVIOUS_CALL_NONE = 0, + PREVIOUS_CALL_ACQUIRED, + PREVIOUS_CALL_LOST, +} PreviousCall; + +typedef struct +{ + gint ref_count; /* (atomic) */ + guint id; + GBusNameOwnerFlags flags; + gchar *name; + GBusAcquiredCallback bus_acquired_handler; + GBusNameAcquiredCallback name_acquired_handler; + GBusNameLostCallback name_lost_handler; + gpointer user_data; + GDestroyNotify user_data_free_func; + GMainContext *main_context; + + PreviousCall previous_call; + + GDBusConnection *connection; + gulong disconnected_signal_handler_id; + guint name_acquired_subscription_id; + guint name_lost_subscription_id; + + gboolean cancelled; /* must hold lock when reading or modifying */ + + gboolean needs_release; +} Client; + +static guint next_global_id = 1; +static GHashTable *map_id_to_client = NULL; + + +static Client * +client_ref (Client *client) +{ + g_atomic_int_inc (&client->ref_count); + return client; +} + +static void +client_unref (Client *client) +{ + if (g_atomic_int_dec_and_test (&client->ref_count)) + { + if (client->connection != NULL) + { + if (client->disconnected_signal_handler_id > 0) + g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); + if (client->name_acquired_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_acquired_subscription_id); + if (client->name_lost_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_lost_subscription_id); + g_object_unref (client->connection); + } + g_main_context_unref (client->main_context); + g_free (client->name); + if (client->user_data_free_func != NULL) + client->user_data_free_func (client->user_data); + g_free (client); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + + +typedef enum +{ + CALL_TYPE_NAME_ACQUIRED, + CALL_TYPE_NAME_LOST +} CallType; + +typedef struct +{ + Client *client; + + /* keep this separate because client->connection may + * be set to NULL after scheduling the call + */ + GDBusConnection *connection; + + /* set to TRUE to call acquired */ + CallType call_type; +} CallHandlerData; + +static void +call_handler_data_free (CallHandlerData *data) +{ + if (data->connection != NULL) + g_object_unref (data->connection); + client_unref (data->client); + g_free (data); +} + +static void +actually_do_call (Client *client, GDBusConnection *connection, CallType call_type) +{ + switch (call_type) + { + case CALL_TYPE_NAME_ACQUIRED: + if (client->name_acquired_handler != NULL) + { + client->name_acquired_handler (connection, + client->name, + client->user_data); + } + break; + + case CALL_TYPE_NAME_LOST: + if (client->name_lost_handler != NULL) + { + client->name_lost_handler (connection, + client->name, + client->user_data); + } + break; + + default: + g_assert_not_reached (); + break; + } +} + +static gboolean +call_in_idle_cb (gpointer _data) +{ + CallHandlerData *data = _data; + actually_do_call (data->client, data->connection, data->call_type); + return FALSE; +} + +static void +schedule_call_in_idle (Client *client, CallType call_type) +{ + CallHandlerData *data; + GSource *idle_source; + + data = g_new0 (CallHandlerData, 1); + data->client = client_ref (client); + data->connection = client->connection != NULL ? g_object_ref (client->connection) : NULL; + data->call_type = call_type; + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_HIGH); + g_source_set_callback (idle_source, + call_in_idle_cb, + data, + (GDestroyNotify) call_handler_data_free); + g_source_set_static_name (idle_source, "[gio, gdbusnameowning.c] call_in_idle_cb"); + g_source_attach (idle_source, client->main_context); + g_source_unref (idle_source); +} + +static void +do_call (Client *client, CallType call_type) +{ + GMainContext *current_context; + + /* only schedule in idle if we're not in the right thread */ + current_context = g_main_context_ref_thread_default (); + if (current_context != client->main_context) + schedule_call_in_idle (client, call_type); + else + actually_do_call (client, client->connection, call_type); + g_main_context_unref (current_context); +} + +static void +call_acquired_handler (Client *client) +{ + G_LOCK (lock); + if (client->previous_call != PREVIOUS_CALL_ACQUIRED) + { + client->previous_call = PREVIOUS_CALL_ACQUIRED; + if (!client->cancelled) + { + G_UNLOCK (lock); + do_call (client, CALL_TYPE_NAME_ACQUIRED); + goto out; + } + } + G_UNLOCK (lock); + out: + ; +} + +static void +call_lost_handler (Client *client) +{ + G_LOCK (lock); + if (client->previous_call != PREVIOUS_CALL_LOST) + { + client->previous_call = PREVIOUS_CALL_LOST; + if (!client->cancelled) + { + G_UNLOCK (lock); + do_call (client, CALL_TYPE_NAME_LOST); + goto out; + } + } + G_UNLOCK (lock); + out: + ; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_name_lost_or_acquired (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + Client *client = user_data; + const gchar *name; + + if (g_strcmp0 (object_path, "/org/freedesktop/DBus") != 0 || + g_strcmp0 (interface_name, "org.freedesktop.DBus") != 0 || + g_strcmp0 (sender_name, "org.freedesktop.DBus") != 0) + goto out; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)"))) + { + g_warning ("%s signal had unexpected signature %s", signal_name, + g_variant_get_type_string (parameters)); + goto out; + } + + if (g_strcmp0 (signal_name, "NameLost") == 0) + { + g_variant_get (parameters, "(&s)", &name); + if (g_strcmp0 (name, client->name) == 0) + { + call_lost_handler (client); + } + } + else if (g_strcmp0 (signal_name, "NameAcquired") == 0) + { + g_variant_get (parameters, "(&s)", &name); + if (g_strcmp0 (name, client->name) == 0) + { + call_acquired_handler (client); + } + } + out: + ; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +request_name_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + Client *client = user_data; + GVariant *result; + guint32 request_name_reply; + gboolean unsubscribe; + + request_name_reply = 0; + result = NULL; + + /* don't use client->connection - it may be NULL already */ + result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), + res, + NULL); + if (result != NULL) + { + g_variant_get (result, "(u)", &request_name_reply); + g_variant_unref (result); + } + + unsubscribe = FALSE; + + switch (request_name_reply) + { + case 1: /* DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */ + /* We got the name - now listen for NameLost and NameAcquired */ + call_acquired_handler (client); + break; + + case 2: /* DBUS_REQUEST_NAME_REPLY_IN_QUEUE */ + /* Waiting in line - listen for NameLost and NameAcquired */ + call_lost_handler (client); + break; + + default: + /* assume we couldn't get the name - explicit fallthrough */ + case 3: /* DBUS_REQUEST_NAME_REPLY_EXISTS */ + case 4: /* DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER */ + /* Some other part of the process is already owning the name */ + call_lost_handler (client); + unsubscribe = TRUE; + client->needs_release = FALSE; + break; + } + + /* If we’re not the owner and not in the queue, there’s no point in continuing + * to listen to NameAcquired or NameLost. */ + if (unsubscribe) + { + GDBusConnection *connection = NULL; + + /* make sure we use a known good Connection object since it may be set to + * NULL at any point after being cancelled + */ + G_LOCK (lock); + if (!client->cancelled) + connection = g_object_ref (client->connection); + G_UNLOCK (lock); + + if (connection != NULL) + { + if (client->name_acquired_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_acquired_subscription_id); + if (client->name_lost_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_lost_subscription_id); + client->name_acquired_subscription_id = 0; + client->name_lost_subscription_id = 0; + + g_object_unref (connection); + } + } + + client_unref (client); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_connection_disconnected (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + gpointer user_data) +{ + Client *client = user_data; + + if (client->disconnected_signal_handler_id > 0) + g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); + if (client->name_acquired_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_acquired_subscription_id); + if (client->name_lost_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_lost_subscription_id); + g_object_unref (client->connection); + client->disconnected_signal_handler_id = 0; + client->name_acquired_subscription_id = 0; + client->name_lost_subscription_id = 0; + client->connection = NULL; + + call_lost_handler (client); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +has_connection (Client *client) +{ + /* listen for disconnection */ + client->disconnected_signal_handler_id = g_signal_connect (client->connection, + "closed", + G_CALLBACK (on_connection_disconnected), + client); + + /* Start listening to NameLost and NameAcquired messages. We hold + * references to the Client in the signal closures, since it’s possible + * for a signal to be in-flight after unsubscribing the signal handler. + * This creates a reference count cycle, but that’s explicitly broken by + * disconnecting the signal handlers before calling client_unref() in + * g_bus_unown_name(). + * + * Subscribe to NameLost and NameAcquired before calling RequestName() to + * avoid the potential race of losing the name between receiving a reply to + * RequestName() and subscribing to NameLost. The #PreviousCall state will + * ensure that the user callbacks get called an appropriate number of times. */ + client->name_lost_subscription_id = + g_dbus_connection_signal_subscribe (client->connection, + "org.freedesktop.DBus", + "org.freedesktop.DBus", + "NameLost", + "/org/freedesktop/DBus", + client->name, + G_DBUS_SIGNAL_FLAGS_NONE, + on_name_lost_or_acquired, + client_ref (client), + (GDestroyNotify) client_unref); + client->name_acquired_subscription_id = + g_dbus_connection_signal_subscribe (client->connection, + "org.freedesktop.DBus", + "org.freedesktop.DBus", + "NameAcquired", + "/org/freedesktop/DBus", + client->name, + G_DBUS_SIGNAL_FLAGS_NONE, + on_name_lost_or_acquired, + client_ref (client), + (GDestroyNotify) client_unref); + + /* attempt to acquire the name */ + client->needs_release = TRUE; + g_dbus_connection_call (client->connection, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "RequestName", /* method name */ + g_variant_new ("(su)", + client->name, + client->flags), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) request_name_cb, + client_ref (client)); +} + + +static void +connection_get_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + Client *client = user_data; + + /* must not do anything if already cancelled */ + G_LOCK (lock); + if (client->cancelled) + { + G_UNLOCK (lock); + goto out; + } + G_UNLOCK (lock); + + client->connection = g_bus_get_finish (res, NULL); + if (client->connection == NULL) + { + call_lost_handler (client); + goto out; + } + + /* No need to schedule this in idle as we're already in the thread + * that the user called g_bus_own_name() from. This is because + * g_bus_get() guarantees that. + * + * Also, we need to ensure that the handler is invoked *before* + * we call RequestName(). Otherwise there is a race. + */ + if (client->bus_acquired_handler != NULL) + { + client->bus_acquired_handler (client->connection, + client->name, + client->user_data); + } + + has_connection (client); + + out: + client_unref (client); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_bus_own_name_on_connection: + * @connection: a #GDBusConnection + * @name: the well-known name to own + * @flags: a set of flags from the #GBusNameOwnerFlags enumeration + * @name_acquired_handler: (nullable): handler to invoke when @name is acquired or %NULL + * @name_lost_handler: (nullable): handler to invoke when @name is lost or %NULL + * @user_data: user data to pass to handlers + * @user_data_free_func: (nullable): function for freeing @user_data or %NULL + * + * Like g_bus_own_name() but takes a #GDBusConnection instead of a + * #GBusType. + * + * Returns: an identifier (never 0) that can be used with + * g_bus_unown_name() to stop owning the name + * + * Since: 2.26 + */ +guint +g_bus_own_name_on_connection (GDBusConnection *connection, + const gchar *name, + GBusNameOwnerFlags flags, + GBusNameAcquiredCallback name_acquired_handler, + GBusNameLostCallback name_lost_handler, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + Client *client; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); + g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), 0); + + G_LOCK (lock); + + client = g_new0 (Client, 1); + client->ref_count = 1; + client->id = next_global_id++; /* TODO: uh oh, handle overflow */ + client->name = g_strdup (name); + client->flags = flags; + client->name_acquired_handler = name_acquired_handler; + client->name_lost_handler = name_lost_handler; + client->user_data = user_data; + client->user_data_free_func = user_data_free_func; + client->main_context = g_main_context_ref_thread_default (); + + client->connection = g_object_ref (connection); + + if (map_id_to_client == NULL) + { + map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal); + } + g_hash_table_insert (map_id_to_client, + GUINT_TO_POINTER (client->id), + client); + + G_UNLOCK (lock); + + has_connection (client); + + return client->id; +} + +/** + * g_bus_own_name: + * @bus_type: the type of bus to own a name on + * @name: the well-known name to own + * @flags: a set of flags from the #GBusNameOwnerFlags enumeration + * @bus_acquired_handler: (nullable): handler to invoke when connected to the bus of type @bus_type or %NULL + * @name_acquired_handler: (nullable): handler to invoke when @name is acquired or %NULL + * @name_lost_handler: (nullable): handler to invoke when @name is lost or %NULL + * @user_data: user data to pass to handlers + * @user_data_free_func: (nullable): function for freeing @user_data or %NULL + * + * Starts acquiring @name on the bus specified by @bus_type and calls + * @name_acquired_handler and @name_lost_handler when the name is + * acquired respectively lost. Callbacks will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this function from. + * + * You are guaranteed that one of the @name_acquired_handler and @name_lost_handler + * callbacks will be invoked after calling this function - there are three + * possible cases: + * + * - @name_lost_handler with a %NULL connection (if a connection to the bus + * can't be made). + * + * - @bus_acquired_handler then @name_lost_handler (if the name can't be + * obtained) + * + * - @bus_acquired_handler then @name_acquired_handler (if the name was + * obtained). + * + * When you are done owning the name, just call g_bus_unown_name() + * with the owner id this function returns. + * + * If the name is acquired or lost (for example another application + * could acquire the name if you allow replacement or the application + * currently owning the name exits), the handlers are also invoked. + * If the #GDBusConnection that is used for attempting to own the name + * closes, then @name_lost_handler is invoked since it is no longer + * possible for other processes to access the process. + * + * You cannot use g_bus_own_name() several times for the same name (unless + * interleaved with calls to g_bus_unown_name()) - only the first call + * will work. + * + * Another guarantee is that invocations of @name_acquired_handler + * and @name_lost_handler are guaranteed to alternate; that + * is, if @name_acquired_handler is invoked then you are + * guaranteed that the next time one of the handlers is invoked, it + * will be @name_lost_handler. The reverse is also true. + * + * If you plan on exporting objects (using e.g. + * g_dbus_connection_register_object()), note that it is generally too late + * to export the objects in @name_acquired_handler. Instead, you can do this + * in @bus_acquired_handler since you are guaranteed that this will run + * before @name is requested from the bus. + * + * This behavior makes it very simple to write applications that wants + * to [own names][gdbus-owning-names] and export objects. + * Simply register objects to be exported in @bus_acquired_handler and + * unregister the objects (if any) in @name_lost_handler. + * + * Returns: an identifier (never 0) that can be used with + * g_bus_unown_name() to stop owning the name. + * + * Since: 2.26 + */ +guint +g_bus_own_name (GBusType bus_type, + const gchar *name, + GBusNameOwnerFlags flags, + GBusAcquiredCallback bus_acquired_handler, + GBusNameAcquiredCallback name_acquired_handler, + GBusNameLostCallback name_lost_handler, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + Client *client; + + g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), 0); + + G_LOCK (lock); + + client = g_new0 (Client, 1); + client->ref_count = 1; + client->id = next_global_id++; /* TODO: uh oh, handle overflow */ + client->name = g_strdup (name); + client->flags = flags; + client->bus_acquired_handler = bus_acquired_handler; + client->name_acquired_handler = name_acquired_handler; + client->name_lost_handler = name_lost_handler; + client->user_data = user_data; + client->user_data_free_func = user_data_free_func; + client->main_context = g_main_context_ref_thread_default (); + + if (map_id_to_client == NULL) + { + map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal); + } + g_hash_table_insert (map_id_to_client, + GUINT_TO_POINTER (client->id), + client); + + g_bus_get (bus_type, + NULL, + connection_get_cb, + client_ref (client)); + + G_UNLOCK (lock); + + return client->id; +} + +typedef struct { + GClosure *bus_acquired_closure; + GClosure *name_acquired_closure; + GClosure *name_lost_closure; +} OwnNameData; + +static OwnNameData * +own_name_data_new (GClosure *bus_acquired_closure, + GClosure *name_acquired_closure, + GClosure *name_lost_closure) +{ + OwnNameData *data; + + data = g_new0 (OwnNameData, 1); + + if (bus_acquired_closure != NULL) + { + data->bus_acquired_closure = g_closure_ref (bus_acquired_closure); + g_closure_sink (bus_acquired_closure); + if (G_CLOSURE_NEEDS_MARSHAL (bus_acquired_closure)) + g_closure_set_marshal (bus_acquired_closure, g_cclosure_marshal_generic); + } + + if (name_acquired_closure != NULL) + { + data->name_acquired_closure = g_closure_ref (name_acquired_closure); + g_closure_sink (name_acquired_closure); + if (G_CLOSURE_NEEDS_MARSHAL (name_acquired_closure)) + g_closure_set_marshal (name_acquired_closure, g_cclosure_marshal_generic); + } + + if (name_lost_closure != NULL) + { + data->name_lost_closure = g_closure_ref (name_lost_closure); + g_closure_sink (name_lost_closure); + if (G_CLOSURE_NEEDS_MARSHAL (name_lost_closure)) + g_closure_set_marshal (name_lost_closure, g_cclosure_marshal_generic); + } + + return data; +} + +static void +own_with_closures_on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + OwnNameData *data = user_data; + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + + g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); + g_value_set_object (¶ms[0], connection); + + g_value_init (¶ms[1], G_TYPE_STRING); + g_value_set_string (¶ms[1], name); + + g_closure_invoke (data->bus_acquired_closure, NULL, 2, params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); +} + +static void +own_with_closures_on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + OwnNameData *data = user_data; + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + + g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); + g_value_set_object (¶ms[0], connection); + + g_value_init (¶ms[1], G_TYPE_STRING); + g_value_set_string (¶ms[1], name); + + g_closure_invoke (data->name_acquired_closure, NULL, 2, params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); +} + +static void +own_with_closures_on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + OwnNameData *data = user_data; + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + + g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); + g_value_set_object (¶ms[0], connection); + + g_value_init (¶ms[1], G_TYPE_STRING); + g_value_set_string (¶ms[1], name); + + g_closure_invoke (data->name_lost_closure, NULL, 2, params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); +} + +static void +bus_own_name_free_func (gpointer user_data) +{ + OwnNameData *data = user_data; + + if (data->bus_acquired_closure != NULL) + g_closure_unref (data->bus_acquired_closure); + + if (data->name_acquired_closure != NULL) + g_closure_unref (data->name_acquired_closure); + + if (data->name_lost_closure != NULL) + g_closure_unref (data->name_lost_closure); + + g_free (data); +} + +/** + * g_bus_own_name_with_closures: (rename-to g_bus_own_name) + * @bus_type: the type of bus to own a name on + * @name: the well-known name to own + * @flags: a set of flags from the #GBusNameOwnerFlags enumeration + * @bus_acquired_closure: (nullable): #GClosure to invoke when connected to + * the bus of type @bus_type or %NULL + * @name_acquired_closure: (nullable): #GClosure to invoke when @name is + * acquired or %NULL + * @name_lost_closure: (nullable): #GClosure to invoke when @name is lost or + * %NULL + * + * Version of g_bus_own_name() using closures instead of callbacks for + * easier binding in other languages. + * + * Returns: an identifier (never 0) that can be used with + * g_bus_unown_name() to stop owning the name. + * + * Since: 2.26 + */ +guint +g_bus_own_name_with_closures (GBusType bus_type, + const gchar *name, + GBusNameOwnerFlags flags, + GClosure *bus_acquired_closure, + GClosure *name_acquired_closure, + GClosure *name_lost_closure) +{ + return g_bus_own_name (bus_type, + name, + flags, + bus_acquired_closure != NULL ? own_with_closures_on_bus_acquired : NULL, + name_acquired_closure != NULL ? own_with_closures_on_name_acquired : NULL, + name_lost_closure != NULL ? own_with_closures_on_name_lost : NULL, + own_name_data_new (bus_acquired_closure, + name_acquired_closure, + name_lost_closure), + bus_own_name_free_func); +} + +/** + * g_bus_own_name_on_connection_with_closures: (rename-to g_bus_own_name_on_connection) + * @connection: a #GDBusConnection + * @name: the well-known name to own + * @flags: a set of flags from the #GBusNameOwnerFlags enumeration + * @name_acquired_closure: (nullable): #GClosure to invoke when @name is + * acquired or %NULL + * @name_lost_closure: (nullable): #GClosure to invoke when @name is lost + * or %NULL + * + * Version of g_bus_own_name_on_connection() using closures instead of + * callbacks for easier binding in other languages. + * + * Returns: an identifier (never 0) that can be used with + * g_bus_unown_name() to stop owning the name. + * + * Since: 2.26 + */ +guint +g_bus_own_name_on_connection_with_closures (GDBusConnection *connection, + const gchar *name, + GBusNameOwnerFlags flags, + GClosure *name_acquired_closure, + GClosure *name_lost_closure) +{ + return g_bus_own_name_on_connection (connection, + name, + flags, + name_acquired_closure != NULL ? own_with_closures_on_name_acquired : NULL, + name_lost_closure != NULL ? own_with_closures_on_name_lost : NULL, + own_name_data_new (NULL, + name_acquired_closure, + name_lost_closure), + bus_own_name_free_func); +} + +/** + * g_bus_unown_name: + * @owner_id: an identifier obtained from g_bus_own_name() + * + * Stops owning a name. + * + * Note that there may still be D-Bus traffic to process (relating to owning + * and unowning the name) in the current thread-default #GMainContext after + * this function has returned. You should continue to iterate the #GMainContext + * until the #GDestroyNotify function passed to g_bus_own_name() is called, in + * order to avoid memory leaks through callbacks queued on the #GMainContext + * after it’s stopped being iterated. + * + * Since: 2.26 + */ +void +g_bus_unown_name (guint owner_id) +{ + Client *client; + + g_return_if_fail (owner_id > 0); + + client = NULL; + + G_LOCK (lock); + if (owner_id == 0 || map_id_to_client == NULL || + (client = g_hash_table_lookup (map_id_to_client, GUINT_TO_POINTER (owner_id))) == NULL) + { + g_warning ("Invalid id %d passed to g_bus_unown_name()", owner_id); + goto out; + } + + client->cancelled = TRUE; + g_warn_if_fail (g_hash_table_remove (map_id_to_client, GUINT_TO_POINTER (owner_id))); + + out: + G_UNLOCK (lock); + + /* do callback without holding lock */ + if (client != NULL) + { + /* Release the name if needed */ + if (client->needs_release && + client->connection != NULL && + !g_dbus_connection_is_closed (client->connection)) + { + GVariant *result; + GError *error; + guint32 release_name_reply; + + /* TODO: it kinda sucks having to do a sync call to release the name - but if + * we don't, then a subsequent grab of the name will make the bus daemon return + * IN_QUEUE which will trigger name_lost(). + * + * I believe this is a bug in the bus daemon. + */ + error = NULL; + result = g_dbus_connection_call_sync (client->connection, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "ReleaseName", /* method name */ + g_variant_new ("(s)", client->name), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (result == NULL) + { + g_warning ("Error releasing name %s: %s", client->name, error->message); + g_error_free (error); + } + else + { + g_variant_get (result, "(u)", &release_name_reply); + if (release_name_reply != 1 /* DBUS_RELEASE_NAME_REPLY_RELEASED */) + { + g_warning ("Unexpected reply %d when releasing name %s", release_name_reply, client->name); + } + else + { + client->needs_release = FALSE; + } + g_variant_unref (result); + } + } + + if (client->disconnected_signal_handler_id > 0) + g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); + if (client->name_acquired_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_acquired_subscription_id); + if (client->name_lost_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_lost_subscription_id); + client->disconnected_signal_handler_id = 0; + client->name_acquired_subscription_id = 0; + client->name_lost_subscription_id = 0; + if (client->connection != NULL) + { + g_object_unref (client->connection); + client->connection = NULL; + } + + client_unref (client); + } +} diff --git a/gio/gdbusnameowning.h b/gio/gdbusnameowning.h new file mode 100644 index 0000000..89c011a --- /dev/null +++ b/gio/gdbusnameowning.h @@ -0,0 +1,115 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_NAME_OWNING_H__ +#define __G_DBUS_NAME_OWNING_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * GBusAcquiredCallback: + * @connection: The #GDBusConnection to a message bus. + * @name: The name that is requested to be owned. + * @user_data: User data passed to g_bus_own_name(). + * + * Invoked when a connection to a message bus has been obtained. + * + * Since: 2.26 + */ +typedef void (*GBusAcquiredCallback) (GDBusConnection *connection, + const gchar *name, + gpointer user_data); + +/** + * GBusNameAcquiredCallback: + * @connection: The #GDBusConnection on which to acquired the name. + * @name: The name being owned. + * @user_data: User data passed to g_bus_own_name() or g_bus_own_name_on_connection(). + * + * Invoked when the name is acquired. + * + * Since: 2.26 + */ +typedef void (*GBusNameAcquiredCallback) (GDBusConnection *connection, + const gchar *name, + gpointer user_data); + +/** + * GBusNameLostCallback: + * @connection: The #GDBusConnection on which to acquire the name or %NULL if + * the connection was disconnected. + * @name: The name being owned. + * @user_data: User data passed to g_bus_own_name() or g_bus_own_name_on_connection(). + * + * Invoked when the name is lost or @connection has been closed. + * + * Since: 2.26 + */ +typedef void (*GBusNameLostCallback) (GDBusConnection *connection, + const gchar *name, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +guint g_bus_own_name (GBusType bus_type, + const gchar *name, + GBusNameOwnerFlags flags, + GBusAcquiredCallback bus_acquired_handler, + GBusNameAcquiredCallback name_acquired_handler, + GBusNameLostCallback name_lost_handler, + gpointer user_data, + GDestroyNotify user_data_free_func); + +GLIB_AVAILABLE_IN_ALL +guint g_bus_own_name_on_connection (GDBusConnection *connection, + const gchar *name, + GBusNameOwnerFlags flags, + GBusNameAcquiredCallback name_acquired_handler, + GBusNameLostCallback name_lost_handler, + gpointer user_data, + GDestroyNotify user_data_free_func); + +GLIB_AVAILABLE_IN_ALL +guint g_bus_own_name_with_closures (GBusType bus_type, + const gchar *name, + GBusNameOwnerFlags flags, + GClosure *bus_acquired_closure, + GClosure *name_acquired_closure, + GClosure *name_lost_closure); + +GLIB_AVAILABLE_IN_ALL +guint g_bus_own_name_on_connection_with_closures ( + GDBusConnection *connection, + const gchar *name, + GBusNameOwnerFlags flags, + GClosure *name_acquired_closure, + GClosure *name_lost_closure); + +GLIB_AVAILABLE_IN_ALL +void g_bus_unown_name (guint owner_id); + +G_END_DECLS + +#endif /* __G_DBUS_NAME_OWNING_H__ */ diff --git a/gio/gdbusnamewatching.c b/gio/gdbusnamewatching.c new file mode 100644 index 0000000..d4272e4 --- /dev/null +++ b/gio/gdbusnamewatching.c @@ -0,0 +1,923 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include + +#include "gdbusutils.h" +#include "gdbusnamewatching.h" +#include "gdbuserror.h" +#include "gdbusprivate.h" +#include "gdbusconnection.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusnamewatching + * @title: Watching Bus Names + * @short_description: Simple API for watching bus names + * @include: gio/gio.h + * + * Convenience API for watching bus names. + * + * A simple example for watching a name can be found in + * [gdbus-example-watch-name.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-watch-name.c) + */ + +G_LOCK_DEFINE_STATIC (lock); + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef enum +{ + PREVIOUS_CALL_NONE = 0, + PREVIOUS_CALL_APPEARED, + PREVIOUS_CALL_VANISHED, +} PreviousCall; + +typedef struct +{ + gint ref_count; /* (atomic) */ + guint id; + gchar *name; + GBusNameWatcherFlags flags; + gchar *name_owner; + GBusNameAppearedCallback name_appeared_handler; + GBusNameVanishedCallback name_vanished_handler; + gpointer user_data; + GDestroyNotify user_data_free_func; + GMainContext *main_context; + + GDBusConnection *connection; + gulong disconnected_signal_handler_id; + guint name_owner_changed_subscription_id; + + PreviousCall previous_call; + + gboolean cancelled; + gboolean initialized; +} Client; + +/* Must be accessed atomically. */ +static guint next_global_id = 1; /* (atomic) */ + +/* Must be accessed with @lock held. */ +static GHashTable *map_id_to_client = NULL; + +static Client * +client_ref (Client *client) +{ + g_atomic_int_inc (&client->ref_count); + return client; +} + +static gboolean +free_user_data_cb (gpointer user_data) +{ + /* The user data is actually freed by the GDestroyNotify for the idle source */ + return G_SOURCE_REMOVE; +} + +static void +client_unref (Client *client) +{ + if (g_atomic_int_dec_and_test (&client->ref_count)) + { + if (client->connection != NULL) + { + if (client->name_owner_changed_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_owner_changed_subscription_id); + if (client->disconnected_signal_handler_id > 0) + g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); + g_object_unref (client->connection); + } + g_free (client->name); + g_free (client->name_owner); + + if (client->user_data_free_func != NULL) + { + /* Ensure client->user_data_free_func() is called from the right thread */ + if (client->main_context != g_main_context_get_thread_default ()) + { + GSource *idle_source = g_idle_source_new (); + g_source_set_callback (idle_source, free_user_data_cb, + client->user_data, + client->user_data_free_func); + g_source_set_name (idle_source, "[gio, gdbusnamewatching.c] free_user_data_cb"); + g_source_attach (idle_source, client->main_context); + g_source_unref (idle_source); + } + else + client->user_data_free_func (client->user_data); + } + + g_main_context_unref (client->main_context); + + g_free (client); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef enum +{ + CALL_TYPE_NAME_APPEARED, + CALL_TYPE_NAME_VANISHED +} CallType; + +typedef struct +{ + Client *client; + + /* keep this separate because client->connection may + * be set to NULL after scheduling the call + */ + GDBusConnection *connection; + + /* ditto */ + gchar *name_owner; + + CallType call_type; +} CallHandlerData; + +static void +call_handler_data_free (CallHandlerData *data) +{ + if (data->connection != NULL) + g_object_unref (data->connection); + g_free (data->name_owner); + client_unref (data->client); + g_free (data); +} + +static void +actually_do_call (Client *client, GDBusConnection *connection, const gchar *name_owner, CallType call_type) +{ + /* The client might have been cancelled (g_bus_unwatch_name()) while we were + * sitting in the #GMainContext dispatch queue. */ + if (client->cancelled) + return; + + switch (call_type) + { + case CALL_TYPE_NAME_APPEARED: + if (client->name_appeared_handler != NULL) + { + client->name_appeared_handler (connection, + client->name, + name_owner, + client->user_data); + } + break; + + case CALL_TYPE_NAME_VANISHED: + if (client->name_vanished_handler != NULL) + { + client->name_vanished_handler (connection, + client->name, + client->user_data); + } + break; + + default: + g_assert_not_reached (); + break; + } +} + +static gboolean +call_in_idle_cb (gpointer _data) +{ + CallHandlerData *data = _data; + actually_do_call (data->client, data->connection, data->name_owner, data->call_type); + return FALSE; +} + +static void +schedule_call_in_idle (Client *client, CallType call_type) +{ + CallHandlerData *data; + GSource *idle_source; + + data = g_new0 (CallHandlerData, 1); + data->client = client_ref (client); + data->connection = client->connection != NULL ? g_object_ref (client->connection) : NULL; + data->name_owner = g_strdup (client->name_owner); + data->call_type = call_type; + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_HIGH); + g_source_set_callback (idle_source, + call_in_idle_cb, + data, + (GDestroyNotify) call_handler_data_free); + g_source_set_static_name (idle_source, "[gio, gdbusnamewatching.c] call_in_idle_cb"); + g_source_attach (idle_source, client->main_context); + g_source_unref (idle_source); +} + +static void +do_call (Client *client, CallType call_type) +{ + GMainContext *current_context; + + /* only schedule in idle if we're not in the right thread */ + current_context = g_main_context_ref_thread_default (); + if (current_context != client->main_context) + schedule_call_in_idle (client, call_type); + else + actually_do_call (client, client->connection, client->name_owner, call_type); + g_main_context_unref (current_context); +} + +static void +call_appeared_handler (Client *client) +{ + if (client->previous_call != PREVIOUS_CALL_APPEARED) + { + client->previous_call = PREVIOUS_CALL_APPEARED; + if (!client->cancelled && client->name_appeared_handler != NULL) + { + do_call (client, CALL_TYPE_NAME_APPEARED); + } + } +} + +static void +call_vanished_handler (Client *client) +{ + if (client->previous_call != PREVIOUS_CALL_VANISHED) + { + client->previous_call = PREVIOUS_CALL_VANISHED; + if (!client->cancelled && client->name_vanished_handler != NULL) + { + do_call (client, CALL_TYPE_NAME_VANISHED); + } + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Return a reference to the #Client for @watcher_id, or %NULL if it’s been + * unwatched. This is safe to call from any thread. */ +static Client * +dup_client (guint watcher_id) +{ + Client *client; + + G_LOCK (lock); + + g_assert (watcher_id != 0); + g_assert (map_id_to_client != NULL); + + client = g_hash_table_lookup (map_id_to_client, GUINT_TO_POINTER (watcher_id)); + + if (client != NULL) + client_ref (client); + + G_UNLOCK (lock); + + return client; +} + +/* Could be called from any thread, so it could be called after client_unref() + * has started finalising the #Client. Avoid that by looking up the #Client + * atomically. */ +static void +on_connection_disconnected (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + gpointer user_data) +{ + guint watcher_id = GPOINTER_TO_UINT (user_data); + Client *client = NULL; + + client = dup_client (watcher_id); + if (client == NULL) + return; + + if (client->name_owner_changed_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (client->connection, client->name_owner_changed_subscription_id); + if (client->disconnected_signal_handler_id > 0) + g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); + g_object_unref (client->connection); + client->disconnected_signal_handler_id = 0; + client->name_owner_changed_subscription_id = 0; + client->connection = NULL; + + call_vanished_handler (client); + + client_unref (client); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Will always be called from the thread which acquired client->main_context. */ +static void +on_name_owner_changed (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + guint watcher_id = GPOINTER_TO_UINT (user_data); + Client *client = NULL; + const gchar *name; + const gchar *old_owner; + const gchar *new_owner; + + client = dup_client (watcher_id); + if (client == NULL) + return; + + if (!client->initialized) + goto out; + + if (g_strcmp0 (object_path, "/org/freedesktop/DBus") != 0 || + g_strcmp0 (interface_name, "org.freedesktop.DBus") != 0 || + g_strcmp0 (sender_name, "org.freedesktop.DBus") != 0) + goto out; + + g_variant_get (parameters, + "(&s&s&s)", + &name, + &old_owner, + &new_owner); + + /* we only care about a specific name */ + if (g_strcmp0 (name, client->name) != 0) + goto out; + + if ((old_owner != NULL && strlen (old_owner) > 0) && client->name_owner != NULL) + { + g_free (client->name_owner); + client->name_owner = NULL; + call_vanished_handler (client); + } + + if (new_owner != NULL && strlen (new_owner) > 0) + { + g_warn_if_fail (client->name_owner == NULL); + g_free (client->name_owner); + client->name_owner = g_strdup (new_owner); + call_appeared_handler (client); + } + + out: + client_unref (client); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +get_name_owner_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + Client *client = user_data; + GVariant *result; + const char *name_owner; + + name_owner = NULL; + result = NULL; + + result = g_dbus_connection_call_finish (client->connection, + res, + NULL); + if (result != NULL) + { + g_variant_get (result, "(&s)", &name_owner); + } + + if (name_owner != NULL) + { + g_warn_if_fail (client->name_owner == NULL); + client->name_owner = g_strdup (name_owner); + call_appeared_handler (client); + } + else + { + call_vanished_handler (client); + } + + client->initialized = TRUE; + + if (result != NULL) + g_variant_unref (result); + client_unref (client); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +invoke_get_name_owner (Client *client) +{ + g_dbus_connection_call (client->connection, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetNameOwner", /* method name */ + g_variant_new ("(s)", client->name), + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) get_name_owner_cb, + client_ref (client)); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +start_service_by_name_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + Client *client = user_data; + GVariant *result; + + result = NULL; + + result = g_dbus_connection_call_finish (client->connection, + res, + NULL); + if (result != NULL) + { + guint32 start_service_result; + g_variant_get (result, "(u)", &start_service_result); + + if (start_service_result == 1) /* DBUS_START_REPLY_SUCCESS */ + { + invoke_get_name_owner (client); + } + else if (start_service_result == 2) /* DBUS_START_REPLY_ALREADY_RUNNING */ + { + invoke_get_name_owner (client); + } + else + { + g_warning ("Unexpected reply %d from StartServiceByName() method", start_service_result); + call_vanished_handler (client); + client->initialized = TRUE; + } + } + else + { + /* Errors are not unexpected; the bus will reply e.g. + * + * org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.Epiphany2 + * was not provided by any .service files + * + * This doesn't mean that the name doesn't have an owner, just + * that it's not provided by a .service file. So proceed to + * invoke GetNameOwner(). + */ + invoke_get_name_owner (client); + } + + if (result != NULL) + g_variant_unref (result); + client_unref (client); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +has_connection (Client *client) +{ + /* listen for disconnection */ + client->disconnected_signal_handler_id = g_signal_connect (client->connection, + "closed", + G_CALLBACK (on_connection_disconnected), + GUINT_TO_POINTER (client->id)); + + /* start listening to NameOwnerChanged messages immediately */ + client->name_owner_changed_subscription_id = g_dbus_connection_signal_subscribe (client->connection, + "org.freedesktop.DBus", /* name */ + "org.freedesktop.DBus", /* if */ + "NameOwnerChanged", /* signal */ + "/org/freedesktop/DBus", /* path */ + client->name, + G_DBUS_SIGNAL_FLAGS_NONE, + on_name_owner_changed, + GUINT_TO_POINTER (client->id), + NULL); + + if (client->flags & G_BUS_NAME_WATCHER_FLAGS_AUTO_START) + { + g_dbus_connection_call (client->connection, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "StartServiceByName", /* method name */ + g_variant_new ("(su)", client->name, 0), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) start_service_by_name_cb, + client_ref (client)); + } + else + { + /* check owner */ + invoke_get_name_owner (client); + } +} + + +static void +connection_get_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + Client *client = user_data; + + client->connection = g_bus_get_finish (res, NULL); + if (client->connection == NULL) + { + call_vanished_handler (client); + goto out; + } + + has_connection (client); + + out: + client_unref (client); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_bus_watch_name: + * @bus_type: The type of bus to watch a name on. + * @name: The name (well-known or unique) to watch. + * @flags: Flags from the #GBusNameWatcherFlags enumeration. + * @name_appeared_handler: (nullable): Handler to invoke when @name is known to exist or %NULL. + * @name_vanished_handler: (nullable): Handler to invoke when @name is known to not exist or %NULL. + * @user_data: User data to pass to handlers. + * @user_data_free_func: (nullable): Function for freeing @user_data or %NULL. + * + * Starts watching @name on the bus specified by @bus_type and calls + * @name_appeared_handler and @name_vanished_handler when the name is + * known to have an owner respectively known to lose its + * owner. Callbacks will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this function from. + * + * You are guaranteed that one of the handlers will be invoked after + * calling this function. When you are done watching the name, just + * call g_bus_unwatch_name() with the watcher id this function + * returns. + * + * If the name vanishes or appears (for example the application owning + * the name could restart), the handlers are also invoked. If the + * #GDBusConnection that is used for watching the name disconnects, then + * @name_vanished_handler is invoked since it is no longer + * possible to access the name. + * + * Another guarantee is that invocations of @name_appeared_handler + * and @name_vanished_handler are guaranteed to alternate; that + * is, if @name_appeared_handler is invoked then you are + * guaranteed that the next time one of the handlers is invoked, it + * will be @name_vanished_handler. The reverse is also true. + * + * This behavior makes it very simple to write applications that want + * to take action when a certain [name exists][gdbus-watching-names]. + * Basically, the application should create object proxies in + * @name_appeared_handler and destroy them again (if any) in + * @name_vanished_handler. + * + * Returns: An identifier (never 0) that can be used with + * g_bus_unwatch_name() to stop watching the name. + * + * Since: 2.26 + */ +guint +g_bus_watch_name (GBusType bus_type, + const gchar *name, + GBusNameWatcherFlags flags, + GBusNameAppearedCallback name_appeared_handler, + GBusNameVanishedCallback name_vanished_handler, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + Client *client; + + g_return_val_if_fail (g_dbus_is_name (name), 0); + + G_LOCK (lock); + + client = g_new0 (Client, 1); + client->ref_count = 1; + client->id = (guint) g_atomic_int_add (&next_global_id, 1); /* TODO: uh oh, handle overflow */ + client->name = g_strdup (name); + client->flags = flags; + client->name_appeared_handler = name_appeared_handler; + client->name_vanished_handler = name_vanished_handler; + client->user_data = user_data; + client->user_data_free_func = user_data_free_func; + client->main_context = g_main_context_ref_thread_default (); + + if (map_id_to_client == NULL) + { + map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal); + } + g_hash_table_insert (map_id_to_client, + GUINT_TO_POINTER (client->id), + client); + + g_bus_get (bus_type, + NULL, + connection_get_cb, + client_ref (client)); + + G_UNLOCK (lock); + + return client->id; +} + +/** + * g_bus_watch_name_on_connection: + * @connection: A #GDBusConnection. + * @name: The name (well-known or unique) to watch. + * @flags: Flags from the #GBusNameWatcherFlags enumeration. + * @name_appeared_handler: (nullable): Handler to invoke when @name is known to exist or %NULL. + * @name_vanished_handler: (nullable): Handler to invoke when @name is known to not exist or %NULL. + * @user_data: User data to pass to handlers. + * @user_data_free_func: (nullable): Function for freeing @user_data or %NULL. + * + * Like g_bus_watch_name() but takes a #GDBusConnection instead of a + * #GBusType. + * + * Returns: An identifier (never 0) that can be used with + * g_bus_unwatch_name() to stop watching the name. + * + * Since: 2.26 + */ +guint g_bus_watch_name_on_connection (GDBusConnection *connection, + const gchar *name, + GBusNameWatcherFlags flags, + GBusNameAppearedCallback name_appeared_handler, + GBusNameVanishedCallback name_vanished_handler, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + Client *client; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); + g_return_val_if_fail (g_dbus_is_name (name), 0); + + G_LOCK (lock); + + client = g_new0 (Client, 1); + client->ref_count = 1; + client->id = (guint) g_atomic_int_add (&next_global_id, 1); /* TODO: uh oh, handle overflow */ + client->name = g_strdup (name); + client->flags = flags; + client->name_appeared_handler = name_appeared_handler; + client->name_vanished_handler = name_vanished_handler; + client->user_data = user_data; + client->user_data_free_func = user_data_free_func; + client->main_context = g_main_context_ref_thread_default (); + + if (map_id_to_client == NULL) + map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal); + + g_hash_table_insert (map_id_to_client, + GUINT_TO_POINTER (client->id), + client); + + client->connection = g_object_ref (connection); + G_UNLOCK (lock); + + has_connection (client); + + return client->id; +} + +typedef struct { + GClosure *name_appeared_closure; + GClosure *name_vanished_closure; +} WatchNameData; + +static WatchNameData * +watch_name_data_new (GClosure *name_appeared_closure, + GClosure *name_vanished_closure) +{ + WatchNameData *data; + + data = g_new0 (WatchNameData, 1); + + if (name_appeared_closure != NULL) + { + data->name_appeared_closure = g_closure_ref (name_appeared_closure); + g_closure_sink (name_appeared_closure); + if (G_CLOSURE_NEEDS_MARSHAL (name_appeared_closure)) + g_closure_set_marshal (name_appeared_closure, g_cclosure_marshal_generic); + } + + if (name_vanished_closure != NULL) + { + data->name_vanished_closure = g_closure_ref (name_vanished_closure); + g_closure_sink (name_vanished_closure); + if (G_CLOSURE_NEEDS_MARSHAL (name_vanished_closure)) + g_closure_set_marshal (name_vanished_closure, g_cclosure_marshal_generic); + } + + return data; +} + +static void +watch_with_closures_on_name_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + WatchNameData *data = user_data; + GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT }; + + g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); + g_value_set_object (¶ms[0], connection); + + g_value_init (¶ms[1], G_TYPE_STRING); + g_value_set_string (¶ms[1], name); + + g_value_init (¶ms[2], G_TYPE_STRING); + g_value_set_string (¶ms[2], name_owner); + + g_closure_invoke (data->name_appeared_closure, NULL, 3, params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); + g_value_unset (params + 2); +} + +static void +watch_with_closures_on_name_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + WatchNameData *data = user_data; + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + + g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); + g_value_set_object (¶ms[0], connection); + + g_value_init (¶ms[1], G_TYPE_STRING); + g_value_set_string (¶ms[1], name); + + g_closure_invoke (data->name_vanished_closure, NULL, 2, params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); +} + +static void +bus_watch_name_free_func (gpointer user_data) +{ + WatchNameData *data = user_data; + + if (data->name_appeared_closure != NULL) + g_closure_unref (data->name_appeared_closure); + + if (data->name_vanished_closure != NULL) + g_closure_unref (data->name_vanished_closure); + + g_free (data); +} + +/** + * g_bus_watch_name_with_closures: (rename-to g_bus_watch_name) + * @bus_type: The type of bus to watch a name on. + * @name: The name (well-known or unique) to watch. + * @flags: Flags from the #GBusNameWatcherFlags enumeration. + * @name_appeared_closure: (nullable): #GClosure to invoke when @name is known + * to exist or %NULL. + * @name_vanished_closure: (nullable): #GClosure to invoke when @name is known + * to not exist or %NULL. + * + * Version of g_bus_watch_name() using closures instead of callbacks for + * easier binding in other languages. + * + * Returns: An identifier (never 0) that can be used with + * g_bus_unwatch_name() to stop watching the name. + * + * Since: 2.26 + */ +guint +g_bus_watch_name_with_closures (GBusType bus_type, + const gchar *name, + GBusNameWatcherFlags flags, + GClosure *name_appeared_closure, + GClosure *name_vanished_closure) +{ + return g_bus_watch_name (bus_type, + name, + flags, + name_appeared_closure != NULL ? watch_with_closures_on_name_appeared : NULL, + name_vanished_closure != NULL ? watch_with_closures_on_name_vanished : NULL, + watch_name_data_new (name_appeared_closure, name_vanished_closure), + bus_watch_name_free_func); +} + +/** + * g_bus_watch_name_on_connection_with_closures: (rename-to g_bus_watch_name_on_connection) + * @connection: A #GDBusConnection. + * @name: The name (well-known or unique) to watch. + * @flags: Flags from the #GBusNameWatcherFlags enumeration. + * @name_appeared_closure: (nullable): #GClosure to invoke when @name is known + * to exist or %NULL. + * @name_vanished_closure: (nullable): #GClosure to invoke when @name is known + * to not exist or %NULL. + * + * Version of g_bus_watch_name_on_connection() using closures instead of callbacks for + * easier binding in other languages. + * + * Returns: An identifier (never 0) that can be used with + * g_bus_unwatch_name() to stop watching the name. + * + * Since: 2.26 + */ +guint g_bus_watch_name_on_connection_with_closures ( + GDBusConnection *connection, + const gchar *name, + GBusNameWatcherFlags flags, + GClosure *name_appeared_closure, + GClosure *name_vanished_closure) +{ + return g_bus_watch_name_on_connection (connection, + name, + flags, + name_appeared_closure != NULL ? watch_with_closures_on_name_appeared : NULL, + name_vanished_closure != NULL ? watch_with_closures_on_name_vanished : NULL, + watch_name_data_new (name_appeared_closure, name_vanished_closure), + bus_watch_name_free_func); +} + +/** + * g_bus_unwatch_name: + * @watcher_id: An identifier obtained from g_bus_watch_name() + * + * Stops watching a name. + * + * Note that there may still be D-Bus traffic to process (relating to watching + * and unwatching the name) in the current thread-default #GMainContext after + * this function has returned. You should continue to iterate the #GMainContext + * until the #GDestroyNotify function passed to g_bus_watch_name() is called, in + * order to avoid memory leaks through callbacks queued on the #GMainContext + * after it’s stopped being iterated. + * + * Since: 2.26 + */ +void +g_bus_unwatch_name (guint watcher_id) +{ + Client *client; + + g_return_if_fail (watcher_id > 0); + + client = NULL; + + G_LOCK (lock); + if (watcher_id == 0 || + map_id_to_client == NULL || + (client = g_hash_table_lookup (map_id_to_client, GUINT_TO_POINTER (watcher_id))) == NULL) + { + g_warning ("Invalid id %d passed to g_bus_unwatch_name()", watcher_id); + goto out; + } + + client->cancelled = TRUE; + g_warn_if_fail (g_hash_table_remove (map_id_to_client, GUINT_TO_POINTER (watcher_id))); + + out: + G_UNLOCK (lock); + + /* do callback without holding lock */ + if (client != NULL) + { + client_unref (client); + } +} diff --git a/gio/gdbusnamewatching.h b/gio/gdbusnamewatching.h new file mode 100644 index 0000000..19d57f2 --- /dev/null +++ b/gio/gdbusnamewatching.h @@ -0,0 +1,102 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_NAME_WATCHING_H__ +#define __G_DBUS_NAME_WATCHING_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * GBusNameAppearedCallback: + * @connection: The #GDBusConnection the name is being watched on. + * @name: The name being watched. + * @name_owner: Unique name of the owner of the name being watched. + * @user_data: User data passed to g_bus_watch_name(). + * + * Invoked when the name being watched is known to have to have an owner. + * + * Since: 2.26 + */ +typedef void (*GBusNameAppearedCallback) (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data); + +/** + * GBusNameVanishedCallback: + * @connection: The #GDBusConnection the name is being watched on, or + * %NULL. + * @name: The name being watched. + * @user_data: User data passed to g_bus_watch_name(). + * + * Invoked when the name being watched is known not to have to have an owner. + * + * This is also invoked when the #GDBusConnection on which the watch was + * established has been closed. In that case, @connection will be + * %NULL. + * + * Since: 2.26 + */ +typedef void (*GBusNameVanishedCallback) (GDBusConnection *connection, + const gchar *name, + gpointer user_data); + + +GLIB_AVAILABLE_IN_ALL +guint g_bus_watch_name (GBusType bus_type, + const gchar *name, + GBusNameWatcherFlags flags, + GBusNameAppearedCallback name_appeared_handler, + GBusNameVanishedCallback name_vanished_handler, + gpointer user_data, + GDestroyNotify user_data_free_func); +GLIB_AVAILABLE_IN_ALL +guint g_bus_watch_name_on_connection (GDBusConnection *connection, + const gchar *name, + GBusNameWatcherFlags flags, + GBusNameAppearedCallback name_appeared_handler, + GBusNameVanishedCallback name_vanished_handler, + gpointer user_data, + GDestroyNotify user_data_free_func); +GLIB_AVAILABLE_IN_ALL +guint g_bus_watch_name_with_closures (GBusType bus_type, + const gchar *name, + GBusNameWatcherFlags flags, + GClosure *name_appeared_closure, + GClosure *name_vanished_closure); +GLIB_AVAILABLE_IN_ALL +guint g_bus_watch_name_on_connection_with_closures ( + GDBusConnection *connection, + const gchar *name, + GBusNameWatcherFlags flags, + GClosure *name_appeared_closure, + GClosure *name_vanished_closure); +GLIB_AVAILABLE_IN_ALL +void g_bus_unwatch_name (guint watcher_id); + +G_END_DECLS + +#endif /* __G_DBUS_NAME_WATCHING_H__ */ diff --git a/gio/gdbusobject.c b/gio/gdbusobject.c new file mode 100644 index 0000000..c332720 --- /dev/null +++ b/gio/gdbusobject.c @@ -0,0 +1,152 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusobject.h" +#include "gdbusinterface.h" +#include "gdbusutils.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusobject + * @short_description: Base type for D-Bus objects + * @include: gio/gio.h + * + * The #GDBusObject type is the base type for D-Bus objects on both + * the service side (see #GDBusObjectSkeleton) and the client side + * (see #GDBusObjectProxy). It is essentially just a container of + * interfaces. + */ + +/** + * GDBusObject: + * + * #GDBusObject is an opaque data structure and can only be accessed + * using the following functions. + */ + +typedef GDBusObjectIface GDBusObjectInterface; +G_DEFINE_INTERFACE (GDBusObject, g_dbus_object, G_TYPE_OBJECT) + +static void +g_dbus_object_default_init (GDBusObjectIface *iface) +{ + /** + * GDBusObject::interface-added: + * @object: The #GDBusObject emitting the signal. + * @interface: The #GDBusInterface that was added. + * + * Emitted when @interface is added to @object. + * + * Since: 2.30 + */ + g_signal_new (I_("interface-added"), + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectIface, interface_added), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_DBUS_INTERFACE); + + /** + * GDBusObject::interface-removed: + * @object: The #GDBusObject emitting the signal. + * @interface: The #GDBusInterface that was removed. + * + * Emitted when @interface is removed from @object. + * + * Since: 2.30 + */ + g_signal_new (I_("interface-removed"), + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectIface, interface_removed), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_DBUS_INTERFACE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_object_get_object_path: + * @object: A #GDBusObject. + * + * Gets the object path for @object. + * + * Returns: A string owned by @object. Do not free. + * + * Since: 2.30 + */ +const gchar * +g_dbus_object_get_object_path (GDBusObject *object) +{ + GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object); + return iface->get_object_path (object); +} + +/** + * g_dbus_object_get_interfaces: + * @object: A #GDBusObject. + * + * Gets the D-Bus interfaces associated with @object. + * + * Returns: (element-type GDBusInterface) (transfer full): A list of #GDBusInterface instances. + * The returned list must be freed by g_list_free() after each element has been freed + * with g_object_unref(). + * + * Since: 2.30 + */ +GList * +g_dbus_object_get_interfaces (GDBusObject *object) +{ + GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object); + return iface->get_interfaces (object); +} + +/** + * g_dbus_object_get_interface: + * @object: A #GDBusObject. + * @interface_name: A D-Bus interface name. + * + * Gets the D-Bus interface with name @interface_name associated with + * @object, if any. + * + * Returns: (nullable) (transfer full): %NULL if not found, otherwise a + * #GDBusInterface that must be freed with g_object_unref(). + * + * Since: 2.30 + */ +GDBusInterface * +g_dbus_object_get_interface (GDBusObject *object, + const gchar *interface_name) +{ + GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object); + g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); + return iface->get_interface (object, interface_name); +} diff --git a/gio/gdbusobject.h b/gio/gdbusobject.h new file mode 100644 index 0000000..157c52b --- /dev/null +++ b/gio/gdbusobject.h @@ -0,0 +1,78 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_OBJECT_H__ +#define __G_DBUS_OBJECT_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_OBJECT (g_dbus_object_get_type()) +#define G_DBUS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT, GDBusObject)) +#define G_IS_DBUS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT)) +#define G_DBUS_OBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), G_TYPE_DBUS_OBJECT, GDBusObjectIface)) + +typedef struct _GDBusObjectIface GDBusObjectIface; + +/** + * GDBusObjectIface: + * @parent_iface: The parent interface. + * @get_object_path: Returns the object path. See g_dbus_object_get_object_path(). + * @get_interfaces: Returns all interfaces. See g_dbus_object_get_interfaces(). + * @get_interface: Returns an interface by name. See g_dbus_object_get_interface(). + * @interface_added: Signal handler for the #GDBusObject::interface-added signal. + * @interface_removed: Signal handler for the #GDBusObject::interface-removed signal. + * + * Base object type for D-Bus objects. + * + * Since: 2.30 + */ +struct _GDBusObjectIface +{ + GTypeInterface parent_iface; + + /* Virtual Functions */ + const gchar *(*get_object_path) (GDBusObject *object); + GList *(*get_interfaces) (GDBusObject *object); + GDBusInterface *(*get_interface) (GDBusObject *object, + const gchar *interface_name); + + /* Signals */ + void (*interface_added) (GDBusObject *object, + GDBusInterface *interface_); + void (*interface_removed) (GDBusObject *object, + GDBusInterface *interface_); + +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_object_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_object_get_object_path (GDBusObject *object); +GLIB_AVAILABLE_IN_ALL +GList *g_dbus_object_get_interfaces (GDBusObject *object); +GLIB_AVAILABLE_IN_ALL +GDBusInterface *g_dbus_object_get_interface (GDBusObject *object, + const gchar *interface_name); + +G_END_DECLS + +#endif /* __G_DBUS_OBJECT_H__ */ diff --git a/gio/gdbusobjectmanager.c b/gio/gdbusobjectmanager.c new file mode 100644 index 0000000..4c4c74b --- /dev/null +++ b/gio/gdbusobjectmanager.c @@ -0,0 +1,253 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusobject.h" +#include "gdbusobjectmanager.h" +#include "gdbusinterface.h" +#include "gdbusutils.h" + +#include "glibintl.h" +#include "gmarshal-internal.h" + +/** + * SECTION:gdbusobjectmanager + * @short_description: Base type for D-Bus object managers + * @include: gio/gio.h + * + * The #GDBusObjectManager type is the base type for service- and + * client-side implementations of the standardized + * [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager) + * interface. + * + * See #GDBusObjectManagerClient for the client-side implementation + * and #GDBusObjectManagerServer for the service-side implementation. + */ + +/** + * GDBusObjectManager: + * + * #GDBusObjectManager is an opaque data structure and can only be accessed + * using the following functions. + */ + +typedef GDBusObjectManagerIface GDBusObjectManagerInterface; +G_DEFINE_INTERFACE (GDBusObjectManager, g_dbus_object_manager, G_TYPE_OBJECT) + +enum { + OBJECT_ADDED, + OBJECT_REMOVED, + INTERFACE_ADDED, + INTERFACE_REMOVED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +static void +g_dbus_object_manager_default_init (GDBusObjectManagerIface *iface) +{ + /** + * GDBusObjectManager::object-added: + * @manager: The #GDBusObjectManager emitting the signal. + * @object: The #GDBusObject that was added. + * + * Emitted when @object is added to @manager. + * + * Since: 2.30 + */ + signals[OBJECT_ADDED] = + g_signal_new (I_("object-added"), + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectManagerIface, object_added), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_DBUS_OBJECT); + + /** + * GDBusObjectManager::object-removed: + * @manager: The #GDBusObjectManager emitting the signal. + * @object: The #GDBusObject that was removed. + * + * Emitted when @object is removed from @manager. + * + * Since: 2.30 + */ + signals[OBJECT_REMOVED] = + g_signal_new (I_("object-removed"), + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectManagerIface, object_removed), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_DBUS_OBJECT); + + /** + * GDBusObjectManager::interface-added: + * @manager: The #GDBusObjectManager emitting the signal. + * @object: The #GDBusObject on which an interface was added. + * @interface: The #GDBusInterface that was added. + * + * Emitted when @interface is added to @object. + * + * This signal exists purely as a convenience to avoid having to + * connect signals to all objects managed by @manager. + * + * Since: 2.30 + */ + signals[INTERFACE_ADDED] = + g_signal_new (I_("interface-added"), + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectManagerIface, interface_added), + NULL, + NULL, + _g_cclosure_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, + 2, + G_TYPE_DBUS_OBJECT, + G_TYPE_DBUS_INTERFACE); + g_signal_set_va_marshaller (signals[INTERFACE_ADDED], + G_TYPE_FROM_INTERFACE (iface), + _g_cclosure_marshal_VOID__OBJECT_OBJECTv); + + /** + * GDBusObjectManager::interface-removed: + * @manager: The #GDBusObjectManager emitting the signal. + * @object: The #GDBusObject on which an interface was removed. + * @interface: The #GDBusInterface that was removed. + * + * Emitted when @interface has been removed from @object. + * + * This signal exists purely as a convenience to avoid having to + * connect signals to all objects managed by @manager. + * + * Since: 2.30 + */ + signals[INTERFACE_REMOVED] = + g_signal_new (I_("interface-removed"), + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectManagerIface, interface_removed), + NULL, + NULL, + _g_cclosure_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, + 2, + G_TYPE_DBUS_OBJECT, + G_TYPE_DBUS_INTERFACE); + g_signal_set_va_marshaller (signals[INTERFACE_REMOVED], + G_TYPE_FROM_INTERFACE (iface), + _g_cclosure_marshal_VOID__OBJECT_OBJECTv); + +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_object_manager_get_object_path: + * @manager: A #GDBusObjectManager. + * + * Gets the object path that @manager is for. + * + * Returns: A string owned by @manager. Do not free. + * + * Since: 2.30 + */ +const gchar * +g_dbus_object_manager_get_object_path (GDBusObjectManager *manager) +{ + GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager); + return iface->get_object_path (manager); +} + +/** + * g_dbus_object_manager_get_objects: + * @manager: A #GDBusObjectManager. + * + * Gets all #GDBusObject objects known to @manager. + * + * Returns: (transfer full) (element-type GDBusObject): A list of + * #GDBusObject objects. The returned list should be freed with + * g_list_free() after each element has been freed with + * g_object_unref(). + * + * Since: 2.30 + */ +GList * +g_dbus_object_manager_get_objects (GDBusObjectManager *manager) +{ + GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager); + return iface->get_objects (manager); +} + +/** + * g_dbus_object_manager_get_object: + * @manager: A #GDBusObjectManager. + * @object_path: Object path to look up. + * + * Gets the #GDBusObject at @object_path, if any. + * + * Returns: (transfer full) (nullable): A #GDBusObject or %NULL. Free with + * g_object_unref(). + * + * Since: 2.30 + */ +GDBusObject * +g_dbus_object_manager_get_object (GDBusObjectManager *manager, + const gchar *object_path) +{ + GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager); + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + return iface->get_object (manager, object_path); +} + +/** + * g_dbus_object_manager_get_interface: + * @manager: A #GDBusObjectManager. + * @object_path: Object path to look up. + * @interface_name: D-Bus interface name to look up. + * + * Gets the interface proxy for @interface_name at @object_path, if + * any. + * + * Returns: (transfer full) (nullable): A #GDBusInterface instance or %NULL. Free + * with g_object_unref(). + * + * Since: 2.30 + */ +GDBusInterface * +g_dbus_object_manager_get_interface (GDBusObjectManager *manager, + const gchar *object_path, + const gchar *interface_name) +{ + GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager); + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); + return iface->get_interface (manager, object_path, interface_name); +} diff --git a/gio/gdbusobjectmanager.h b/gio/gdbusobjectmanager.h new file mode 100644 index 0000000..260ae2e --- /dev/null +++ b/gio/gdbusobjectmanager.h @@ -0,0 +1,94 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_OBJECT_MANAGER_H__ +#define __G_DBUS_OBJECT_MANAGER_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_OBJECT_MANAGER (g_dbus_object_manager_get_type()) +#define G_DBUS_OBJECT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_MANAGER, GDBusObjectManager)) +#define G_IS_DBUS_OBJECT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_MANAGER)) +#define G_DBUS_OBJECT_MANAGER_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), G_TYPE_DBUS_OBJECT_MANAGER, GDBusObjectManagerIface)) + +typedef struct _GDBusObjectManagerIface GDBusObjectManagerIface; + +/** + * GDBusObjectManagerIface: + * @parent_iface: The parent interface. + * @get_object_path: Virtual function for g_dbus_object_manager_get_object_path(). + * @get_objects: Virtual function for g_dbus_object_manager_get_objects(). + * @get_object: Virtual function for g_dbus_object_manager_get_object(). + * @get_interface: Virtual function for g_dbus_object_manager_get_interface(). + * @object_added: Signal handler for the #GDBusObjectManager::object-added signal. + * @object_removed: Signal handler for the #GDBusObjectManager::object-removed signal. + * @interface_added: Signal handler for the #GDBusObjectManager::interface-added signal. + * @interface_removed: Signal handler for the #GDBusObjectManager::interface-removed signal. + * + * Base type for D-Bus object managers. + * + * Since: 2.30 + */ +struct _GDBusObjectManagerIface +{ + GTypeInterface parent_iface; + + /* Virtual Functions */ + const gchar *(*get_object_path) (GDBusObjectManager *manager); + GList *(*get_objects) (GDBusObjectManager *manager); + GDBusObject *(*get_object) (GDBusObjectManager *manager, + const gchar *object_path); + GDBusInterface *(*get_interface) (GDBusObjectManager *manager, + const gchar *object_path, + const gchar *interface_name); + + /* Signals */ + void (*object_added) (GDBusObjectManager *manager, + GDBusObject *object); + void (*object_removed) (GDBusObjectManager *manager, + GDBusObject *object); + + void (*interface_added) (GDBusObjectManager *manager, + GDBusObject *object, + GDBusInterface *interface_); + void (*interface_removed) (GDBusObjectManager *manager, + GDBusObject *object, + GDBusInterface *interface_); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_object_manager_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_object_manager_get_object_path (GDBusObjectManager *manager); +GLIB_AVAILABLE_IN_ALL +GList *g_dbus_object_manager_get_objects (GDBusObjectManager *manager); +GLIB_AVAILABLE_IN_ALL +GDBusObject *g_dbus_object_manager_get_object (GDBusObjectManager *manager, + const gchar *object_path); +GLIB_AVAILABLE_IN_ALL +GDBusInterface *g_dbus_object_manager_get_interface (GDBusObjectManager *manager, + const gchar *object_path, + const gchar *interface_name); + +G_END_DECLS + +#endif /* __G_DBUS_OBJECT_MANAGER_H__ */ diff --git a/gio/gdbusobjectmanagerclient.c b/gio/gdbusobjectmanagerclient.c new file mode 100644 index 0000000..0d6f5e6 --- /dev/null +++ b/gio/gdbusobjectmanagerclient.c @@ -0,0 +1,1872 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gcancellable.h" +#include "gdbusobjectmanager.h" +#include "gdbusobjectmanagerclient.h" +#include "gdbusobject.h" +#include "gdbusprivate.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include "ginitable.h" +#include "gasyncresult.h" +#include "gasyncinitable.h" +#include "gdbusconnection.h" +#include "gdbusutils.h" +#include "gdbusobject.h" +#include "gdbusobjectproxy.h" +#include "gdbusproxy.h" +#include "gdbusinterface.h" + +#include "glibintl.h" +#include "gmarshal-internal.h" + +/** + * SECTION:gdbusobjectmanagerclient + * @short_description: Client-side object manager + * @include: gio/gio.h + * + * #GDBusObjectManagerClient is used to create, monitor and delete object + * proxies for remote objects exported by a #GDBusObjectManagerServer (or any + * code implementing the + * [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager) + * interface). + * + * Once an instance of this type has been created, you can connect to + * the #GDBusObjectManager::object-added and + * #GDBusObjectManager::object-removed signals and inspect the + * #GDBusObjectProxy objects returned by + * g_dbus_object_manager_get_objects(). + * + * If the name for a #GDBusObjectManagerClient is not owned by anyone at + * object construction time, the default behavior is to request the + * message bus to launch an owner for the name. This behavior can be + * disabled using the %G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START + * flag. It's also worth noting that this only works if the name of + * interest is activatable in the first place. E.g. in some cases it + * is not possible to launch an owner for the requested name. In this + * case, #GDBusObjectManagerClient object construction still succeeds but + * there will be no object proxies + * (e.g. g_dbus_object_manager_get_objects() returns the empty list) and + * the #GDBusObjectManagerClient:name-owner property is %NULL. + * + * The owner of the requested name can come and go (for example + * consider a system service being restarted) – #GDBusObjectManagerClient + * handles this case too; simply connect to the #GObject::notify + * signal to watch for changes on the #GDBusObjectManagerClient:name-owner + * property. When the name owner vanishes, the behavior is that + * #GDBusObjectManagerClient:name-owner is set to %NULL (this includes + * emission of the #GObject::notify signal) and then + * #GDBusObjectManager::object-removed signals are synthesized + * for all currently existing object proxies. Since + * #GDBusObjectManagerClient:name-owner is %NULL when this happens, you can + * use this information to disambiguate a synthesized signal from a + * genuine signal caused by object removal on the remote + * #GDBusObjectManager. Similarly, when a new name owner appears, + * #GDBusObjectManager::object-added signals are synthesized + * while #GDBusObjectManagerClient:name-owner is still %NULL. Only when all + * object proxies have been added, the #GDBusObjectManagerClient:name-owner + * is set to the new name owner (this includes emission of the + * #GObject::notify signal). Furthermore, you are guaranteed that + * #GDBusObjectManagerClient:name-owner will alternate between a name owner + * (e.g. `:1.42`) and %NULL even in the case where + * the name of interest is atomically replaced + * + * Ultimately, #GDBusObjectManagerClient is used to obtain #GDBusProxy + * instances. All signals (including the + * org.freedesktop.DBus.Properties::PropertiesChanged signal) + * delivered to #GDBusProxy instances are guaranteed to originate + * from the name owner. This guarantee along with the behavior + * described above, means that certain race conditions including the + * "half the proxy is from the old owner and the other half is from + * the new owner" problem cannot happen. + * + * To avoid having the application connect to signals on the returned + * #GDBusObjectProxy and #GDBusProxy objects, the + * #GDBusObject::interface-added, + * #GDBusObject::interface-removed, + * #GDBusProxy::g-properties-changed and + * #GDBusProxy::g-signal signals + * are also emitted on the #GDBusObjectManagerClient instance managing these + * objects. The signals emitted are + * #GDBusObjectManager::interface-added, + * #GDBusObjectManager::interface-removed, + * #GDBusObjectManagerClient::interface-proxy-properties-changed and + * #GDBusObjectManagerClient::interface-proxy-signal. + * + * Note that all callbacks and signals are emitted in the + * [thread-default main context][g-main-context-push-thread-default] + * that the #GDBusObjectManagerClient object was constructed + * in. Additionally, the #GDBusObjectProxy and #GDBusProxy objects + * originating from the #GDBusObjectManagerClient object will be created in + * the same context and, consequently, will deliver signals in the + * same main loop. + */ + +struct _GDBusObjectManagerClientPrivate +{ + GMutex lock; + + GBusType bus_type; + GDBusConnection *connection; + gchar *object_path; + gchar *name; + gchar *name_owner; + GDBusObjectManagerClientFlags flags; + + GDBusProxy *control_proxy; + + GHashTable *map_object_path_to_object_proxy; + + guint signal_subscription_id; + gchar *match_rule; + + GDBusProxyTypeFunc get_proxy_type_func; + gpointer get_proxy_type_user_data; + GDestroyNotify get_proxy_type_destroy_notify; + + gulong name_owner_signal_id; + gulong signal_signal_id; + GCancellable *cancel; +}; + +enum +{ + PROP_0, + PROP_BUS_TYPE, + PROP_CONNECTION, + PROP_FLAGS, + PROP_OBJECT_PATH, + PROP_NAME, + PROP_NAME_OWNER, + PROP_GET_PROXY_TYPE_FUNC, + PROP_GET_PROXY_TYPE_USER_DATA, + PROP_GET_PROXY_TYPE_DESTROY_NOTIFY +}; + +enum +{ + INTERFACE_PROXY_SIGNAL_SIGNAL, + INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void initable_iface_init (GInitableIface *initable_iface); +static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface); +static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerClient, g_dbus_object_manager_client, G_TYPE_OBJECT, + G_ADD_PRIVATE (GDBusObjectManagerClient) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init)) + +static void maybe_unsubscribe_signals (GDBusObjectManagerClient *manager); + +static void on_control_proxy_g_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data); + +static void process_get_all_result (GDBusObjectManagerClient *manager, + GVariant *value, + const gchar *name_owner); + +static void +g_dbus_object_manager_client_dispose (GObject *object) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (object); + + if (manager->priv->cancel != NULL) + { + g_cancellable_cancel (manager->priv->cancel); + g_clear_object (&manager->priv->cancel); + } + + G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->dispose (object); +} + +static void +g_dbus_object_manager_client_finalize (GObject *object) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (object); + + maybe_unsubscribe_signals (manager); + + g_hash_table_unref (manager->priv->map_object_path_to_object_proxy); + + if (manager->priv->control_proxy != NULL && manager->priv->signal_signal_id != 0) + g_signal_handler_disconnect (manager->priv->control_proxy, + manager->priv->signal_signal_id); + manager->priv->signal_signal_id = 0; + + if (manager->priv->control_proxy != NULL && manager->priv->name_owner_signal_id != 0) + g_signal_handler_disconnect (manager->priv->control_proxy, + manager->priv->name_owner_signal_id); + manager->priv->name_owner_signal_id = 0; + + g_clear_object (&manager->priv->control_proxy); + + if (manager->priv->connection != NULL) + g_object_unref (manager->priv->connection); + g_free (manager->priv->object_path); + g_free (manager->priv->name); + g_free (manager->priv->name_owner); + + if (manager->priv->get_proxy_type_destroy_notify != NULL) + manager->priv->get_proxy_type_destroy_notify (manager->priv->get_proxy_type_user_data); + + g_mutex_clear (&manager->priv->lock); + + if (G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->finalize (object); +} + +static void +g_dbus_object_manager_client_get_property (GObject *_object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object); + + switch (prop_id) + { + case PROP_CONNECTION: + g_value_set_object (value, g_dbus_object_manager_client_get_connection (manager)); + break; + + case PROP_OBJECT_PATH: + g_value_set_string (value, g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager))); + break; + + case PROP_NAME: + g_value_set_string (value, g_dbus_object_manager_client_get_name (manager)); + break; + + case PROP_FLAGS: + g_value_set_flags (value, g_dbus_object_manager_client_get_flags (manager)); + break; + + case PROP_NAME_OWNER: + g_value_take_string (value, g_dbus_object_manager_client_get_name_owner (manager)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (manager, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_manager_client_set_property (GObject *_object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object); + const gchar *name; + + switch (prop_id) + { + case PROP_BUS_TYPE: + manager->priv->bus_type = g_value_get_enum (value); + break; + + case PROP_CONNECTION: + if (g_value_get_object (value) != NULL) + { + g_assert (manager->priv->connection == NULL); + g_assert (G_IS_DBUS_CONNECTION (g_value_get_object (value))); + manager->priv->connection = g_value_dup_object (value); + } + break; + + case PROP_OBJECT_PATH: + g_assert (manager->priv->object_path == NULL); + g_assert (g_variant_is_object_path (g_value_get_string (value))); + manager->priv->object_path = g_value_dup_string (value); + break; + + case PROP_NAME: + g_assert (manager->priv->name == NULL); + name = g_value_get_string (value); + g_assert (name == NULL || g_dbus_is_name (name)); + manager->priv->name = g_strdup (name); + break; + + case PROP_FLAGS: + manager->priv->flags = g_value_get_flags (value); + break; + + case PROP_GET_PROXY_TYPE_FUNC: + manager->priv->get_proxy_type_func = g_value_get_pointer (value); + break; + + case PROP_GET_PROXY_TYPE_USER_DATA: + manager->priv->get_proxy_type_user_data = g_value_get_pointer (value); + break; + + case PROP_GET_PROXY_TYPE_DESTROY_NOTIFY: + manager->priv->get_proxy_type_destroy_notify = g_value_get_pointer (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (manager, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_manager_client_class_init (GDBusObjectManagerClientClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_dbus_object_manager_client_dispose; + gobject_class->finalize = g_dbus_object_manager_client_finalize; + gobject_class->set_property = g_dbus_object_manager_client_set_property; + gobject_class->get_property = g_dbus_object_manager_client_get_property; + + /** + * GDBusObjectManagerClient:connection: + * + * The #GDBusConnection to use. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_CONNECTION, + g_param_spec_object ("connection", + "Connection", + "The connection to use", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectManagerClient:bus-type: + * + * If this property is not %G_BUS_TYPE_NONE, then + * #GDBusObjectManagerClient:connection must be %NULL and will be set to the + * #GDBusConnection obtained by calling g_bus_get() with the value + * of this property. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_BUS_TYPE, + g_param_spec_enum ("bus-type", + "Bus Type", + "The bus to connect to, if any", + G_TYPE_BUS_TYPE, + G_BUS_TYPE_NONE, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusObjectManagerClient:flags: + * + * Flags from the #GDBusObjectManagerClientFlags enumeration. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_FLAGS, + g_param_spec_flags ("flags", + "Flags", + "Flags for the proxy manager", + G_TYPE_DBUS_OBJECT_MANAGER_CLIENT_FLAGS, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusObjectManagerClient:object-path: + * + * The object path the manager is for. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_OBJECT_PATH, + g_param_spec_string ("object-path", + "Object Path", + "The object path of the control object", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectManagerClient:name: + * + * The well-known name or unique name that the manager is for. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "Name that the manager is for", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectManagerClient:name-owner: + * + * The unique name that owns #GDBusObjectManagerClient:name or %NULL if + * no-one is currently owning the name. Connect to the + * #GObject::notify signal to track changes to this property. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_NAME_OWNER, + g_param_spec_string ("name-owner", + "Name Owner", + "The owner of the name we are watching", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectManagerClient:get-proxy-type-func: + * + * The #GDBusProxyTypeFunc to use when determining what #GType to + * use for interface proxies or %NULL. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_GET_PROXY_TYPE_FUNC, + g_param_spec_pointer ("get-proxy-type-func", + "GDBusProxyTypeFunc Function Pointer", + "The GDBusProxyTypeFunc pointer to use", + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectManagerClient:get-proxy-type-user-data: + * + * The #gpointer user_data to pass to #GDBusObjectManagerClient:get-proxy-type-func. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_GET_PROXY_TYPE_USER_DATA, + g_param_spec_pointer ("get-proxy-type-user-data", + "GDBusProxyTypeFunc User Data", + "The GDBusProxyTypeFunc user_data", + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectManagerClient:get-proxy-type-destroy-notify: + * + * A #GDestroyNotify for the #gpointer user_data in #GDBusObjectManagerClient:get-proxy-type-user-data. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_GET_PROXY_TYPE_DESTROY_NOTIFY, + g_param_spec_pointer ("get-proxy-type-destroy-notify", + "GDBusProxyTypeFunc user data free function", + "The GDBusProxyTypeFunc user data free function", + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectManagerClient::interface-proxy-signal: + * @manager: The #GDBusObjectManagerClient emitting the signal. + * @object_proxy: The #GDBusObjectProxy on which an interface is emitting a D-Bus signal. + * @interface_proxy: The #GDBusProxy that is emitting a D-Bus signal. + * @sender_name: The sender of the signal or NULL if the connection is not a bus connection. + * @signal_name: The signal name. + * @parameters: A #GVariant tuple with parameters for the signal. + * + * Emitted when a D-Bus signal is received on @interface_proxy. + * + * This signal exists purely as a convenience to avoid having to + * connect signals to all interface proxies managed by @manager. + * + * This signal is emitted in the + * [thread-default main context][g-main-context-push-thread-default] + * that @manager was constructed in. + * + * Since: 2.30 + */ + signals[INTERFACE_PROXY_SIGNAL_SIGNAL] = + g_signal_new (I_("interface-proxy-signal"), + G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectManagerClientClass, interface_proxy_signal), + NULL, + NULL, + _g_cclosure_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT, + G_TYPE_NONE, + 5, + G_TYPE_DBUS_OBJECT_PROXY, + G_TYPE_DBUS_PROXY, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_VARIANT); + g_signal_set_va_marshaller (signals[INTERFACE_PROXY_SIGNAL_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANTv); + + /** + * GDBusObjectManagerClient::interface-proxy-properties-changed: + * @manager: The #GDBusObjectManagerClient emitting the signal. + * @object_proxy: The #GDBusObjectProxy on which an interface has properties that are changing. + * @interface_proxy: The #GDBusProxy that has properties that are changing. + * @changed_properties: A #GVariant containing the properties that changed (type: `a{sv}`). + * @invalidated_properties: (array zero-terminated=1) (element-type utf8): A %NULL terminated + * array of properties that were invalidated. + * + * Emitted when one or more D-Bus properties on proxy changes. The + * local cache has already been updated when this signal fires. Note + * that both @changed_properties and @invalidated_properties are + * guaranteed to never be %NULL (either may be empty though). + * + * This signal exists purely as a convenience to avoid having to + * connect signals to all interface proxies managed by @manager. + * + * This signal is emitted in the + * [thread-default main context][g-main-context-push-thread-default] + * that @manager was constructed in. + * + * Since: 2.30 + */ + signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL] = + g_signal_new (I_("interface-proxy-properties-changed"), + G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectManagerClientClass, interface_proxy_properties_changed), + NULL, + NULL, + _g_cclosure_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXED, + G_TYPE_NONE, + 4, + G_TYPE_DBUS_OBJECT_PROXY, + G_TYPE_DBUS_PROXY, + G_TYPE_VARIANT, + G_TYPE_STRV); + g_signal_set_va_marshaller (signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXEDv); +} + +static void +g_dbus_object_manager_client_init (GDBusObjectManagerClient *manager) +{ + manager->priv = g_dbus_object_manager_client_get_instance_private (manager); + g_mutex_init (&manager->priv->lock); + manager->priv->map_object_path_to_object_proxy = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_object_unref); + manager->priv->cancel = g_cancellable_new (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_object_manager_client_new_sync: + * @connection: A #GDBusConnection. + * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration. + * @name: (nullable): The owner of the control object (unique or well-known name), or %NULL when not using a message bus connection. + * @object_path: The object path of the control object. + * @get_proxy_type_func: (nullable): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies. + * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func. + * @get_proxy_type_destroy_notify: (nullable): Free function for @get_proxy_type_user_data or %NULL. + * @cancellable: (nullable): A #GCancellable or %NULL + * @error: Return location for error or %NULL. + * + * Creates a new #GDBusObjectManagerClient object. + * + * This is a synchronous failable constructor - the calling thread is + * blocked until a reply is received. See g_dbus_object_manager_client_new() + * for the asynchronous version. + * + * Returns: (transfer full) (type GDBusObjectManagerClient): A + * #GDBusObjectManagerClient object or %NULL if @error is set. Free + * with g_object_unref(). + * + * Since: 2.30 + */ +GDBusObjectManager * +g_dbus_object_manager_client_new_sync (GDBusConnection *connection, + GDBusObjectManagerClientFlags flags, + const gchar *name, + const gchar *object_path, + GDBusProxyTypeFunc get_proxy_type_func, + gpointer get_proxy_type_user_data, + GDestroyNotify get_proxy_type_destroy_notify, + GCancellable *cancellable, + GError **error) +{ + GInitable *initable; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) || + g_dbus_is_name (name), NULL); + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + initable = g_initable_new (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, + cancellable, + error, + "connection", connection, + "flags", flags, + "name", name, + "object-path", object_path, + "get-proxy-type-func", get_proxy_type_func, + "get-proxy-type-user-data", get_proxy_type_user_data, + "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify, + NULL); + if (initable != NULL) + return G_DBUS_OBJECT_MANAGER (initable); + else + return NULL; +} + +/** + * g_dbus_object_manager_client_new: + * @connection: A #GDBusConnection. + * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration. + * @name: The owner of the control object (unique or well-known name). + * @object_path: The object path of the control object. + * @get_proxy_type_func: (nullable): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies. + * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func. + * @get_proxy_type_destroy_notify: (nullable): Free function for @get_proxy_type_user_data or %NULL. + * @cancellable: (nullable): A #GCancellable or %NULL + * @callback: A #GAsyncReadyCallback to call when the request is satisfied. + * @user_data: The data to pass to @callback. + * + * Asynchronously creates a new #GDBusObjectManagerClient object. + * + * This is an asynchronous failable constructor. When the result is + * ready, @callback will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. You can + * then call g_dbus_object_manager_client_new_finish() to get the result. See + * g_dbus_object_manager_client_new_sync() for the synchronous version. + * + * Since: 2.30 + */ +void +g_dbus_object_manager_client_new (GDBusConnection *connection, + GDBusObjectManagerClientFlags flags, + const gchar *name, + const gchar *object_path, + GDBusProxyTypeFunc get_proxy_type_func, + gpointer get_proxy_type_user_data, + GDestroyNotify get_proxy_type_destroy_notify, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + g_return_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) || + g_dbus_is_name (name)); + g_return_if_fail (g_variant_is_object_path (object_path)); + + g_async_initable_new_async (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + "connection", connection, + "flags", flags, + "name", name, + "object-path", object_path, + "get-proxy-type-func", get_proxy_type_func, + "get-proxy-type-user-data", get_proxy_type_user_data, + "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify, + NULL); +} + +/** + * g_dbus_object_manager_client_new_finish: + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_object_manager_client_new(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with g_dbus_object_manager_client_new(). + * + * Returns: (transfer full) (type GDBusObjectManagerClient): A + * #GDBusObjectManagerClient object or %NULL if @error is set. Free + * with g_object_unref(). + * + * Since: 2.30 + */ +GDBusObjectManager * +g_dbus_object_manager_client_new_finish (GAsyncResult *res, + GError **error) +{ + GObject *object; + GObject *source_object; + + source_object = g_async_result_get_source_object (res); + g_assert (source_object != NULL); + + object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), + res, + error); + g_object_unref (source_object); + + if (object != NULL) + return G_DBUS_OBJECT_MANAGER (object); + else + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_object_manager_client_new_for_bus_sync: + * @bus_type: A #GBusType. + * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration. + * @name: The owner of the control object (unique or well-known name). + * @object_path: The object path of the control object. + * @get_proxy_type_func: (nullable): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies. + * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func. + * @get_proxy_type_destroy_notify: (nullable): Free function for @get_proxy_type_user_data or %NULL. + * @cancellable: (nullable): A #GCancellable or %NULL + * @error: Return location for error or %NULL. + * + * Like g_dbus_object_manager_client_new_sync() but takes a #GBusType instead + * of a #GDBusConnection. + * + * This is a synchronous failable constructor - the calling thread is + * blocked until a reply is received. See g_dbus_object_manager_client_new_for_bus() + * for the asynchronous version. + * + * Returns: (transfer full) (type GDBusObjectManagerClient): A + * #GDBusObjectManagerClient object or %NULL if @error is set. Free + * with g_object_unref(). + * + * Since: 2.30 + */ +GDBusObjectManager * +g_dbus_object_manager_client_new_for_bus_sync (GBusType bus_type, + GDBusObjectManagerClientFlags flags, + const gchar *name, + const gchar *object_path, + GDBusProxyTypeFunc get_proxy_type_func, + gpointer get_proxy_type_user_data, + GDestroyNotify get_proxy_type_destroy_notify, + GCancellable *cancellable, + GError **error) +{ + GInitable *initable; + + g_return_val_if_fail (bus_type != G_BUS_TYPE_NONE, NULL); + g_return_val_if_fail (g_dbus_is_name (name), NULL); + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + initable = g_initable_new (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, + cancellable, + error, + "bus-type", bus_type, + "flags", flags, + "name", name, + "object-path", object_path, + "get-proxy-type-func", get_proxy_type_func, + "get-proxy-type-user-data", get_proxy_type_user_data, + "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify, + NULL); + if (initable != NULL) + return G_DBUS_OBJECT_MANAGER (initable); + else + return NULL; +} + +/** + * g_dbus_object_manager_client_new_for_bus: + * @bus_type: A #GBusType. + * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration. + * @name: The owner of the control object (unique or well-known name). + * @object_path: The object path of the control object. + * @get_proxy_type_func: (nullable): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies. + * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func. + * @get_proxy_type_destroy_notify: (nullable): Free function for @get_proxy_type_user_data or %NULL. + * @cancellable: (nullable): A #GCancellable or %NULL + * @callback: A #GAsyncReadyCallback to call when the request is satisfied. + * @user_data: The data to pass to @callback. + * + * Like g_dbus_object_manager_client_new() but takes a #GBusType instead of a + * #GDBusConnection. + * + * This is an asynchronous failable constructor. When the result is + * ready, @callback will be invoked in the + * [thread-default main loop][g-main-context-push-thread-default] + * of the thread you are calling this method from. You can + * then call g_dbus_object_manager_client_new_for_bus_finish() to get the result. See + * g_dbus_object_manager_client_new_for_bus_sync() for the synchronous version. + * + * Since: 2.30 + */ +void +g_dbus_object_manager_client_new_for_bus (GBusType bus_type, + GDBusObjectManagerClientFlags flags, + const gchar *name, + const gchar *object_path, + GDBusProxyTypeFunc get_proxy_type_func, + gpointer get_proxy_type_user_data, + GDestroyNotify get_proxy_type_destroy_notify, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (bus_type != G_BUS_TYPE_NONE); + g_return_if_fail (g_dbus_is_name (name)); + g_return_if_fail (g_variant_is_object_path (object_path)); + + g_async_initable_new_async (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + "bus-type", bus_type, + "flags", flags, + "name", name, + "object-path", object_path, + "get-proxy-type-func", get_proxy_type_func, + "get-proxy-type-user-data", get_proxy_type_user_data, + "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify, + NULL); +} + +/** + * g_dbus_object_manager_client_new_for_bus_finish: + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_object_manager_client_new_for_bus(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with g_dbus_object_manager_client_new_for_bus(). + * + * Returns: (transfer full) (type GDBusObjectManagerClient): A + * #GDBusObjectManagerClient object or %NULL if @error is set. Free + * with g_object_unref(). + * + * Since: 2.30 + */ +GDBusObjectManager * +g_dbus_object_manager_client_new_for_bus_finish (GAsyncResult *res, + GError **error) +{ + GObject *object; + GObject *source_object; + + source_object = g_async_result_get_source_object (res); + g_assert (source_object != NULL); + + object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), + res, + error); + g_object_unref (source_object); + + if (object != NULL) + return G_DBUS_OBJECT_MANAGER (object); + else + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_object_manager_client_get_connection: + * @manager: A #GDBusObjectManagerClient + * + * Gets the #GDBusConnection used by @manager. + * + * Returns: (transfer none): A #GDBusConnection object. Do not free, + * the object belongs to @manager. + * + * Since: 2.30 + */ +GDBusConnection * +g_dbus_object_manager_client_get_connection (GDBusObjectManagerClient *manager) +{ + GDBusConnection *ret; + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL); + g_mutex_lock (&manager->priv->lock); + ret = manager->priv->connection; + g_mutex_unlock (&manager->priv->lock); + return ret; +} + +/** + * g_dbus_object_manager_client_get_name: + * @manager: A #GDBusObjectManagerClient + * + * Gets the name that @manager is for, or %NULL if not a message bus + * connection. + * + * Returns: A unique or well-known name. Do not free, the string + * belongs to @manager. + * + * Since: 2.30 + */ +const gchar * +g_dbus_object_manager_client_get_name (GDBusObjectManagerClient *manager) +{ + const gchar *ret; + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL); + g_mutex_lock (&manager->priv->lock); + ret = manager->priv->name; + g_mutex_unlock (&manager->priv->lock); + return ret; +} + +/** + * g_dbus_object_manager_client_get_flags: + * @manager: A #GDBusObjectManagerClient + * + * Gets the flags that @manager was constructed with. + * + * Returns: Zero of more flags from the #GDBusObjectManagerClientFlags + * enumeration. + * + * Since: 2.30 + */ +GDBusObjectManagerClientFlags +g_dbus_object_manager_client_get_flags (GDBusObjectManagerClient *manager) +{ + GDBusObjectManagerClientFlags ret; + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE); + g_mutex_lock (&manager->priv->lock); + ret = manager->priv->flags; + g_mutex_unlock (&manager->priv->lock); + return ret; +} + +/** + * g_dbus_object_manager_client_get_name_owner: + * @manager: A #GDBusObjectManagerClient. + * + * The unique name that owns the name that @manager is for or %NULL if + * no-one currently owns that name. You can connect to the + * #GObject::notify signal to track changes to the + * #GDBusObjectManagerClient:name-owner property. + * + * Returns: (nullable): The name owner or %NULL if no name owner + * exists. Free with g_free(). + * + * Since: 2.30 + */ +gchar * +g_dbus_object_manager_client_get_name_owner (GDBusObjectManagerClient *manager) +{ + gchar *ret; + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL); + g_mutex_lock (&manager->priv->lock); + ret = g_strdup (manager->priv->name_owner); + g_mutex_unlock (&manager->priv->lock); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* signal handler for all objects we manage - we dispatch signals + * from here to the objects + */ +static void +signal_cb (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (user_data); + GDBusObjectProxy *object_proxy; + GDBusInterface *interface; + + g_mutex_lock (&manager->priv->lock); + object_proxy = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path); + if (object_proxy == NULL) + { + g_mutex_unlock (&manager->priv->lock); + goto out; + } + g_object_ref (object_proxy); + g_mutex_unlock (&manager->priv->lock); + + //g_debug ("yay, signal_cb %s %s: %s\n", signal_name, object_path, g_variant_print (parameters, TRUE)); + + g_object_ref (manager); + if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Properties") == 0) + { + if (g_strcmp0 (signal_name, "PropertiesChanged") == 0) + { + const gchar *interface_name; + GVariant *changed_properties; + const gchar **invalidated_properties; + + g_variant_get (parameters, + "(&s@a{sv}^a&s)", + &interface_name, + &changed_properties, + &invalidated_properties); + + interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name); + if (interface != NULL) + { + GVariantIter property_iter; + const gchar *property_name; + GVariant *property_value; + guint n; + + /* update caches... */ + g_variant_iter_init (&property_iter, changed_properties); + while (g_variant_iter_next (&property_iter, + "{&sv}", + &property_name, + &property_value)) + { + g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface), + property_name, + property_value); + g_variant_unref (property_value); + } + + for (n = 0; invalidated_properties[n] != NULL; n++) + { + g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface), + invalidated_properties[n], + NULL); + } + /* ... and then synthesize the signal */ + g_signal_emit_by_name (interface, + "g-properties-changed", + changed_properties, + invalidated_properties); + g_signal_emit (manager, + signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL], + 0, + object_proxy, + interface, + changed_properties, + invalidated_properties); + g_object_unref (interface); + } + g_variant_unref (changed_properties); + g_free (invalidated_properties); + } + } + else + { + /* regular signal - just dispatch it */ + interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name); + if (interface != NULL) + { + g_signal_emit_by_name (interface, + "g-signal", + sender_name, + signal_name, + parameters); + g_signal_emit (manager, + signals[INTERFACE_PROXY_SIGNAL_SIGNAL], + 0, + object_proxy, + interface, + sender_name, + signal_name, + parameters); + g_object_unref (interface); + } + } + g_object_unref (manager); + + out: + g_clear_object (&object_proxy); +} + +static void +subscribe_signals (GDBusObjectManagerClient *manager, + const gchar *name_owner) +{ + GError *error = NULL; + GVariant *ret; + + g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager)); + g_return_if_fail (manager->priv->signal_subscription_id == 0); + g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner)); + + if (name_owner != NULL) + { + /* Only add path_namespace if it's non-'/'. This removes a no-op key from + * the match rule, and also works around a D-Bus bug where + * path_namespace='/' matches nothing in D-Bus versions < 1.6.18. + * + * See: https://bugs.freedesktop.org/show_bug.cgi?id=70799 */ + if (g_str_equal (manager->priv->object_path, "/")) + { + manager->priv->match_rule = g_strdup_printf ("type='signal',sender='%s'", + name_owner); + } + else + { + manager->priv->match_rule = g_strdup_printf ("type='signal',sender='%s',path_namespace='%s'", + name_owner, manager->priv->object_path); + } + + /* The bus daemon may not implement path_namespace so gracefully + * handle this by using a fallback triggered if @error is set. */ + ret = g_dbus_connection_call_sync (manager->priv->connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "AddMatch", + g_variant_new ("(s)", + manager->priv->match_rule), + NULL, /* reply_type */ + G_DBUS_CALL_FLAGS_NONE, + -1, /* default timeout */ + NULL, /* TODO: Cancellable */ + &error); + + /* yay, bus daemon supports path_namespace */ + if (ret != NULL) + g_variant_unref (ret); + } + + if (error == NULL) + { + /* still need to ask GDBusConnection for the callbacks */ + manager->priv->signal_subscription_id = + g_dbus_connection_signal_subscribe (manager->priv->connection, + name_owner, + NULL, /* interface */ + NULL, /* member */ + NULL, /* path - TODO: really want wildcard support here */ + NULL, /* arg0 */ + G_DBUS_SIGNAL_FLAGS_NONE | + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, + signal_cb, + manager, + NULL); /* user_data_free_func */ + + } + else + { + /* TODO: we could report this to the user + g_warning ("Message bus daemon does not support path_namespace: %s (%s %d)", + error->message, + g_quark_to_string (error->domain), + error->code); + */ + + g_error_free (error); + + /* no need to call RemoveMatch when done since it didn't work */ + g_free (manager->priv->match_rule); + manager->priv->match_rule = NULL; + + /* Fallback is to subscribe to *all* signals from the name owner which + * is rather wasteful. It's probably not a big practical problem because + * users typically want all objects that the name owner supplies. + */ + manager->priv->signal_subscription_id = + g_dbus_connection_signal_subscribe (manager->priv->connection, + name_owner, + NULL, /* interface */ + NULL, /* member */ + NULL, /* path - TODO: really want wildcard support here */ + NULL, /* arg0 */ + G_DBUS_SIGNAL_FLAGS_NONE, + signal_cb, + manager, + NULL); /* user_data_free_func */ + } +} + +static void +maybe_unsubscribe_signals (GDBusObjectManagerClient *manager) +{ + g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager)); + + if (manager->priv->signal_subscription_id > 0) + { + g_dbus_connection_signal_unsubscribe (manager->priv->connection, + manager->priv->signal_subscription_id); + manager->priv->signal_subscription_id = 0; + } + + if (manager->priv->match_rule != NULL) + { + /* Since the AddMatch call succeeded this is guaranteed to not + * fail - therefore, don't bother checking the return value + */ + g_dbus_connection_call (manager->priv->connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "RemoveMatch", + g_variant_new ("(s)", + manager->priv->match_rule), + NULL, /* reply_type */ + G_DBUS_CALL_FLAGS_NONE, + -1, /* default timeout */ + NULL, /* GCancellable */ + NULL, /* GAsyncReadyCallback */ + NULL); /* user data */ + g_free (manager->priv->match_rule); + manager->priv->match_rule = NULL; + } + +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GWeakRef * +weak_ref_new (GObject *object) +{ + GWeakRef *weak_ref = g_new0 (GWeakRef, 1); + g_weak_ref_init (weak_ref, object); + return g_steal_pointer (&weak_ref); +} + +static void +weak_ref_free (GWeakRef *weak_ref) +{ + g_weak_ref_clear (weak_ref); + g_free (weak_ref); +} + +static void +on_get_managed_objects_finish (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + + GDBusProxy *proxy = G_DBUS_PROXY (source); + GWeakRef *manager_weak = user_data; + GDBusObjectManagerClient *manager; + GError *error = NULL; + GVariant *value = NULL; + gchar *new_name_owner = NULL; + + value = g_dbus_proxy_call_finish (proxy, result, &error); + + manager = G_DBUS_OBJECT_MANAGER_CLIENT (g_weak_ref_get (manager_weak)); + /* Manager got disposed, nothing to do */ + if (manager == NULL) + { + goto out; + } + + new_name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy); + if (value == NULL) + { + maybe_unsubscribe_signals (manager); + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + { + g_warning ("Error calling GetManagedObjects() when name owner %s for name %s came back: %s", + new_name_owner, + manager->priv->name, + error->message); + } + } + else + { + process_get_all_result (manager, value, new_name_owner); + } + + /* do the :name-owner notify *AFTER* emitting ::object-proxy-added signals - this + * way the user knows that the signals were emitted because the name owner came back + */ + g_mutex_lock (&manager->priv->lock); + manager->priv->name_owner = g_steal_pointer (&new_name_owner); + g_mutex_unlock (&manager->priv->lock); + g_object_notify (G_OBJECT (manager), "name-owner"); + + g_object_unref (manager); + out: + g_clear_error (&error); + g_clear_pointer (&value, g_variant_unref); + weak_ref_free (manager_weak); +} + +static void +on_notify_g_name_owner (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + GWeakRef *manager_weak = user_data; + GDBusObjectManagerClient *manager = NULL; + gchar *old_name_owner; + gchar *new_name_owner; + + manager = G_DBUS_OBJECT_MANAGER_CLIENT (g_weak_ref_get (manager_weak)); + if (manager == NULL) + return; + + g_mutex_lock (&manager->priv->lock); + old_name_owner = manager->priv->name_owner; + new_name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy); + manager->priv->name_owner = NULL; + + if (g_strcmp0 (old_name_owner, new_name_owner) != 0) + { + GList *l; + GList *proxies; + + /* remote manager changed; nuke all local proxies */ + proxies = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy); + g_list_foreach (proxies, (GFunc) g_object_ref, NULL); + g_hash_table_remove_all (manager->priv->map_object_path_to_object_proxy); + + g_mutex_unlock (&manager->priv->lock); + + /* do the :name-owner notify with a NULL name - this way the user knows + * the ::object-proxy-removed following is because the name owner went + * away + */ + g_object_notify (G_OBJECT (manager), "name-owner"); + + for (l = proxies; l != NULL; l = l->next) + { + GDBusObjectProxy *object_proxy = G_DBUS_OBJECT_PROXY (l->data); + g_signal_emit_by_name (manager, "object-removed", object_proxy); + } + g_list_free_full (proxies, g_object_unref); + + /* nuke local filter */ + maybe_unsubscribe_signals (manager); + } + else + { + g_mutex_unlock (&manager->priv->lock); + } + + if (new_name_owner != NULL) + { + //g_debug ("repopulating for %s", new_name_owner); + + subscribe_signals (manager, + new_name_owner); + g_dbus_proxy_call (manager->priv->control_proxy, + "GetManagedObjects", + NULL, /* parameters */ + G_DBUS_CALL_FLAGS_NONE, + -1, + manager->priv->cancel, + on_get_managed_objects_finish, + weak_ref_new (G_OBJECT (manager))); + } + g_free (new_name_owner); + g_free (old_name_owner); + g_object_unref (manager); +} + +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (initable); + gboolean ret; + GVariant *value; + GDBusProxyFlags proxy_flags; + + ret = FALSE; + + if (manager->priv->bus_type != G_BUS_TYPE_NONE) + { + g_assert (manager->priv->connection == NULL); + manager->priv->connection = g_bus_get_sync (manager->priv->bus_type, cancellable, error); + if (manager->priv->connection == NULL) + goto out; + } + + proxy_flags = G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES; + if (manager->priv->flags & G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START) + proxy_flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START; + + manager->priv->control_proxy = g_dbus_proxy_new_sync (manager->priv->connection, + proxy_flags, + NULL, /* GDBusInterfaceInfo* */ + manager->priv->name, + manager->priv->object_path, + "org.freedesktop.DBus.ObjectManager", + cancellable, + error); + if (manager->priv->control_proxy == NULL) + goto out; + + /* Use weak refs here. The @control_proxy will emit its signals in the current + * #GMainContext (since we constructed it just above). However, the user may + * drop the last external reference to this #GDBusObjectManagerClient in + * another thread between a signal being emitted and scheduled in an idle + * callback in this #GMainContext, and that idle callback being invoked. We + * can’t use a strong reference here, as there’s no + * g_dbus_object_manager_client_disconnect() (or similar) method to tell us + * when the last external reference to this object has been dropped, so we + * can’t break a strong reference count cycle. So use weak refs. */ + manager->priv->name_owner_signal_id = + g_signal_connect_data (G_OBJECT (manager->priv->control_proxy), + "notify::g-name-owner", + G_CALLBACK (on_notify_g_name_owner), + weak_ref_new (G_OBJECT (manager)), + (GClosureNotify) weak_ref_free, + 0 /* flags */); + + manager->priv->signal_signal_id = + g_signal_connect_data (manager->priv->control_proxy, + "g-signal", + G_CALLBACK (on_control_proxy_g_signal), + weak_ref_new (G_OBJECT (manager)), + (GClosureNotify) weak_ref_free, + 0 /* flags */); + + manager->priv->name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy); + if (manager->priv->name_owner == NULL && manager->priv->name != NULL) + { + /* it's perfectly fine if there's no name owner.. we're just going to + * wait until one is ready + */ + } + else + { + /* yay, we can get the objects */ + subscribe_signals (manager, + manager->priv->name_owner); + value = g_dbus_proxy_call_sync (manager->priv->control_proxy, + "GetManagedObjects", + NULL, /* parameters */ + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + if (value == NULL) + { + maybe_unsubscribe_signals (manager); + + g_warn_if_fail (manager->priv->signal_signal_id != 0); + g_signal_handler_disconnect (manager->priv->control_proxy, + manager->priv->signal_signal_id); + manager->priv->signal_signal_id = 0; + + g_warn_if_fail (manager->priv->name_owner_signal_id != 0); + g_signal_handler_disconnect (manager->priv->control_proxy, + manager->priv->name_owner_signal_id); + manager->priv->name_owner_signal_id = 0; + + g_object_unref (manager->priv->control_proxy); + manager->priv->control_proxy = NULL; + + goto out; + } + + process_get_all_result (manager, value, manager->priv->name_owner); + g_variant_unref (value); + } + + ret = TRUE; + + out: + return ret; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = initable_init; +} + +static void +async_initable_iface_init (GAsyncInitableIface *async_initable_iface) +{ + /* for now, just use default: run GInitable code in thread */ +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +add_interfaces (GDBusObjectManagerClient *manager, + const gchar *object_path, + GVariant *ifaces_and_properties, + const gchar *name_owner) +{ + GDBusObjectProxy *op; + gboolean added; + GVariantIter iter; + const gchar *interface_name; + GVariant *properties; + GList *interface_added_signals, *l; + GDBusProxy *interface_proxy; + + g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner)); + + g_mutex_lock (&manager->priv->lock); + + interface_added_signals = NULL; + added = FALSE; + + op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path); + if (op == NULL) + { + GType object_proxy_type; + if (manager->priv->get_proxy_type_func != NULL) + { + object_proxy_type = manager->priv->get_proxy_type_func (manager, + object_path, + NULL, + manager->priv->get_proxy_type_user_data); + g_warn_if_fail (g_type_is_a (object_proxy_type, G_TYPE_DBUS_OBJECT_PROXY)); + } + else + { + object_proxy_type = G_TYPE_DBUS_OBJECT_PROXY; + } + op = g_object_new (object_proxy_type, + "g-connection", manager->priv->connection, + "g-object-path", object_path, + NULL); + added = TRUE; + } + g_object_ref (op); + + g_variant_iter_init (&iter, ifaces_and_properties); + while (g_variant_iter_next (&iter, + "{&s@a{sv}}", + &interface_name, + &properties)) + { + GError *error; + GType interface_proxy_type; + + if (manager->priv->get_proxy_type_func != NULL) + { + interface_proxy_type = manager->priv->get_proxy_type_func (manager, + object_path, + interface_name, + manager->priv->get_proxy_type_user_data); + g_warn_if_fail (g_type_is_a (interface_proxy_type, G_TYPE_DBUS_PROXY)); + } + else + { + interface_proxy_type = G_TYPE_DBUS_PROXY; + } + + /* this is fine - there is no blocking IO because we pass DO_NOT_LOAD_PROPERTIES and + * DO_NOT_CONNECT_SIGNALS and use a unique name + */ + error = NULL; + interface_proxy = g_initable_new (interface_proxy_type, + NULL, /* GCancellable */ + &error, + "g-connection", manager->priv->connection, + "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + "g-name", name_owner, + "g-object-path", object_path, + "g-interface-name", interface_name, + NULL); + if (interface_proxy == NULL) + { + g_warning ("%s: Error constructing proxy for path %s and interface %s: %s", + G_STRLOC, + object_path, + interface_name, + error->message); + g_error_free (error); + } + else + { + GVariantIter property_iter; + const gchar *property_name; + GVariant *property_value; + + /* associate the interface proxy with the object */ + g_dbus_interface_set_object (G_DBUS_INTERFACE (interface_proxy), + G_DBUS_OBJECT (op)); + + g_variant_iter_init (&property_iter, properties); + while (g_variant_iter_next (&property_iter, + "{&sv}", + &property_name, + &property_value)) + { + g_dbus_proxy_set_cached_property (interface_proxy, + property_name, + property_value); + g_variant_unref (property_value); + } + + _g_dbus_object_proxy_add_interface (op, interface_proxy); + if (!added) + interface_added_signals = g_list_append (interface_added_signals, g_object_ref (interface_proxy)); + g_object_unref (interface_proxy); + } + g_variant_unref (properties); + } + + if (added) + { + g_hash_table_insert (manager->priv->map_object_path_to_object_proxy, + g_strdup (object_path), + op); + } + + g_mutex_unlock (&manager->priv->lock); + + /* now that we don't hold the lock any more, emit signals */ + g_object_ref (manager); + for (l = interface_added_signals; l != NULL; l = l->next) + { + interface_proxy = G_DBUS_PROXY (l->data); + g_signal_emit_by_name (manager, "interface-added", op, interface_proxy); + g_object_unref (interface_proxy); + } + g_list_free (interface_added_signals); + + if (added) + g_signal_emit_by_name (manager, "object-added", op); + + g_object_unref (manager); + g_object_unref (op); +} + +static void +remove_interfaces (GDBusObjectManagerClient *manager, + const gchar *object_path, + const gchar *const *interface_names) +{ + GDBusObjectProxy *op; + GList *interfaces; + guint n; + guint num_interfaces; + guint num_interfaces_to_remove; + + g_mutex_lock (&manager->priv->lock); + + op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path); + if (op == NULL) + { + g_debug ("%s: Processing InterfaceRemoved signal for path %s but no object proxy exists", + G_STRLOC, + object_path); + g_mutex_unlock (&manager->priv->lock); + return; + } + + interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (op)); + num_interfaces = g_list_length (interfaces); + g_list_free_full (interfaces, g_object_unref); + + num_interfaces_to_remove = g_strv_length ((gchar **) interface_names); + + /* see if we are going to completety remove the object */ + g_object_ref (manager); + if (num_interfaces_to_remove == num_interfaces) + { + g_object_ref (op); + g_warn_if_fail (g_hash_table_remove (manager->priv->map_object_path_to_object_proxy, object_path)); + g_mutex_unlock (&manager->priv->lock); + g_signal_emit_by_name (manager, "object-removed", op); + g_object_unref (op); + } + else + { + g_object_ref (op); + g_mutex_unlock (&manager->priv->lock); + for (n = 0; interface_names != NULL && interface_names[n] != NULL; n++) + { + GDBusInterface *interface; + interface = g_dbus_object_get_interface (G_DBUS_OBJECT (op), interface_names[n]); + _g_dbus_object_proxy_remove_interface (op, interface_names[n]); + if (interface != NULL) + { + g_signal_emit_by_name (manager, "interface-removed", op, interface); + g_object_unref (interface); + } + } + g_object_unref (op); + } + g_object_unref (manager); +} + +static void +process_get_all_result (GDBusObjectManagerClient *manager, + GVariant *value, + const gchar *name_owner) +{ + GVariant *arg0; + const gchar *object_path; + GVariant *ifaces_and_properties; + GVariantIter iter; + + g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner)); + + arg0 = g_variant_get_child_value (value, 0); + g_variant_iter_init (&iter, arg0); + while (g_variant_iter_next (&iter, + "{&o@a{sa{sv}}}", + &object_path, + &ifaces_and_properties)) + { + add_interfaces (manager, object_path, ifaces_and_properties, name_owner); + g_variant_unref (ifaces_and_properties); + } + g_variant_unref (arg0); +} + +static void +on_control_proxy_g_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GWeakRef *manager_weak = user_data; + GDBusObjectManagerClient *manager = NULL; + const gchar *object_path; + + manager = G_DBUS_OBJECT_MANAGER_CLIENT (g_weak_ref_get (manager_weak)); + if (manager == NULL) + return; + + //g_debug ("yay, g_signal %s: %s\n", signal_name, g_variant_print (parameters, TRUE)); + + if (g_strcmp0 (signal_name, "InterfacesAdded") == 0) + { + GVariant *ifaces_and_properties; + g_variant_get (parameters, + "(&o@a{sa{sv}})", + &object_path, + &ifaces_and_properties); + add_interfaces (manager, object_path, ifaces_and_properties, manager->priv->name_owner); + g_variant_unref (ifaces_and_properties); + } + else if (g_strcmp0 (signal_name, "InterfacesRemoved") == 0) + { + const gchar **ifaces; + g_variant_get (parameters, + "(&o^a&s)", + &object_path, + &ifaces); + remove_interfaces (manager, object_path, ifaces); + g_free (ifaces); + } + + g_object_unref (manager); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static const gchar * +g_dbus_object_manager_client_get_object_path (GDBusObjectManager *_manager) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager); + return manager->priv->object_path; +} + +static GDBusObject * +g_dbus_object_manager_client_get_object (GDBusObjectManager *_manager, + const gchar *object_path) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager); + GDBusObject *ret; + + g_mutex_lock (&manager->priv->lock); + ret = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path); + if (ret != NULL) + g_object_ref (ret); + g_mutex_unlock (&manager->priv->lock); + return ret; +} + +static GDBusInterface * +g_dbus_object_manager_client_get_interface (GDBusObjectManager *_manager, + const gchar *object_path, + const gchar *interface_name) +{ + GDBusInterface *ret; + GDBusObject *object; + + ret = NULL; + + object = g_dbus_object_manager_get_object (_manager, object_path); + if (object == NULL) + goto out; + + ret = g_dbus_object_get_interface (object, interface_name); + g_object_unref (object); + + out: + return ret; +} + +static GList * +g_dbus_object_manager_client_get_objects (GDBusObjectManager *_manager) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager); + GList *ret; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL); + + g_mutex_lock (&manager->priv->lock); + ret = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy); + g_list_foreach (ret, (GFunc) g_object_ref, NULL); + g_mutex_unlock (&manager->priv->lock); + + return ret; +} + + +static void +dbus_object_manager_interface_init (GDBusObjectManagerIface *iface) +{ + iface->get_object_path = g_dbus_object_manager_client_get_object_path; + iface->get_objects = g_dbus_object_manager_client_get_objects; + iface->get_object = g_dbus_object_manager_client_get_object; + iface->get_interface = g_dbus_object_manager_client_get_interface; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusobjectmanagerclient.h b/gio/gdbusobjectmanagerclient.h new file mode 100644 index 0000000..eafabfb --- /dev/null +++ b/gio/gdbusobjectmanagerclient.h @@ -0,0 +1,146 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_OBJECT_MANAGER_CLIENT_H__ +#define __G_DBUS_OBJECT_MANAGER_CLIENT_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_OBJECT_MANAGER_CLIENT (g_dbus_object_manager_client_get_type ()) +#define G_DBUS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, GDBusObjectManagerClient)) +#define G_DBUS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, GDBusObjectManagerClientClass)) +#define G_DBUS_OBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, GDBusObjectManagerClientClass)) +#define G_IS_DBUS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT)) +#define G_IS_DBUS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT)) + +typedef struct _GDBusObjectManagerClientClass GDBusObjectManagerClientClass; +typedef struct _GDBusObjectManagerClientPrivate GDBusObjectManagerClientPrivate; + +/** + * GDBusObjectManagerClient: + * + * The #GDBusObjectManagerClient structure contains private data and should + * only be accessed using the provided API. + * + * Since: 2.30 + */ +struct _GDBusObjectManagerClient +{ + /*< private >*/ + GObject parent_instance; + GDBusObjectManagerClientPrivate *priv; +}; + +/** + * GDBusObjectManagerClientClass: + * @parent_class: The parent class. + * @interface_proxy_signal: Signal class handler for the #GDBusObjectManagerClient::interface-proxy-signal signal. + * @interface_proxy_properties_changed: Signal class handler for the #GDBusObjectManagerClient::interface-proxy-properties-changed signal. + * + * Class structure for #GDBusObjectManagerClient. + * + * Since: 2.30 + */ +struct _GDBusObjectManagerClientClass +{ + GObjectClass parent_class; + + /* signals */ + void (*interface_proxy_signal) (GDBusObjectManagerClient *manager, + GDBusObjectProxy *object_proxy, + GDBusProxy *interface_proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters); + + void (*interface_proxy_properties_changed) (GDBusObjectManagerClient *manager, + GDBusObjectProxy *object_proxy, + GDBusProxy *interface_proxy, + GVariant *changed_properties, + const gchar* const *invalidated_properties); + + /*< private >*/ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_object_manager_client_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_manager_client_new (GDBusConnection *connection, + GDBusObjectManagerClientFlags flags, + const gchar *name, + const gchar *object_path, + GDBusProxyTypeFunc get_proxy_type_func, + gpointer get_proxy_type_user_data, + GDestroyNotify get_proxy_type_destroy_notify, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GDBusObjectManager *g_dbus_object_manager_client_new_finish (GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusObjectManager *g_dbus_object_manager_client_new_sync (GDBusConnection *connection, + GDBusObjectManagerClientFlags flags, + const gchar *name, + const gchar *object_path, + GDBusProxyTypeFunc get_proxy_type_func, + gpointer get_proxy_type_user_data, + GDestroyNotify get_proxy_type_destroy_notify, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_manager_client_new_for_bus (GBusType bus_type, + GDBusObjectManagerClientFlags flags, + const gchar *name, + const gchar *object_path, + GDBusProxyTypeFunc get_proxy_type_func, + gpointer get_proxy_type_user_data, + GDestroyNotify get_proxy_type_destroy_notify, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GDBusObjectManager *g_dbus_object_manager_client_new_for_bus_finish (GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusObjectManager *g_dbus_object_manager_client_new_for_bus_sync (GBusType bus_type, + GDBusObjectManagerClientFlags flags, + const gchar *name, + const gchar *object_path, + GDBusProxyTypeFunc get_proxy_type_func, + gpointer get_proxy_type_user_data, + GDestroyNotify get_proxy_type_destroy_notify, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_object_manager_client_get_connection (GDBusObjectManagerClient *manager); +GLIB_AVAILABLE_IN_ALL +GDBusObjectManagerClientFlags g_dbus_object_manager_client_get_flags (GDBusObjectManagerClient *manager); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_object_manager_client_get_name (GDBusObjectManagerClient *manager); +GLIB_AVAILABLE_IN_ALL +gchar *g_dbus_object_manager_client_get_name_owner (GDBusObjectManagerClient *manager); + +G_END_DECLS + +#endif /* __G_DBUS_OBJECT_MANAGER_CLIENT_H */ diff --git a/gio/gdbusobjectmanagerserver.c b/gio/gdbusobjectmanagerserver.c new file mode 100644 index 0000000..0b875be --- /dev/null +++ b/gio/gdbusobjectmanagerserver.c @@ -0,0 +1,1190 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusobjectmanager.h" +#include "gdbusobjectmanagerserver.h" +#include "gdbusobject.h" +#include "gdbusobjectskeleton.h" +#include "gdbusinterfaceskeleton.h" +#include "gdbusconnection.h" +#include "gdbusintrospection.h" +#include "gdbusmethodinvocation.h" +#include "gdbuserror.h" + +#include "gioerror.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusobjectmanagerserver + * @short_description: Service-side object manager + * @include: gio/gio.h + * + * #GDBusObjectManagerServer is used to export #GDBusObject instances using + * the standardized + * [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager) + * interface. For example, remote D-Bus clients can get all objects + * and properties in a single call. Additionally, any change in the + * object hierarchy is broadcast using signals. This means that D-Bus + * clients can keep caches up to date by only listening to D-Bus + * signals. + * + * The recommended path to export an object manager at is the path form of the + * well-known name of a D-Bus service, or below. For example, if a D-Bus service + * is available at the well-known name `net.example.ExampleService1`, the object + * manager should typically be exported at `/net/example/ExampleService1`, or + * below (to allow for multiple object managers in a service). + * + * It is supported, but not recommended, to export an object manager at the root + * path, `/`. + * + * See #GDBusObjectManagerClient for the client-side code that is + * intended to be used with #GDBusObjectManagerServer or any D-Bus + * object implementing the org.freedesktop.DBus.ObjectManager + * interface. + */ + +typedef struct +{ + GDBusObjectSkeleton *object; + GDBusObjectManagerServer *manager; + GHashTable *map_iface_name_to_iface; + gboolean exported; +} RegistrationData; + +static void registration_data_free (RegistrationData *data); + +static void export_all (GDBusObjectManagerServer *manager); +static void unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager); + +static void g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager, + RegistrationData *data, + const gchar *const *interfaces, + const gchar *object_path); + +static void g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager, + RegistrationData *data, + const gchar *const *interfaces); + +static gboolean g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer *manager, + const gchar *object_path); + +struct _GDBusObjectManagerServerPrivate +{ + GMutex lock; + GDBusConnection *connection; + gchar *object_path; + gchar *object_path_ending_in_slash; + GHashTable *map_object_path_to_data; + guint manager_reg_id; +}; + +enum +{ + PROP_0, + PROP_CONNECTION, + PROP_OBJECT_PATH +}; + +static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerServer, g_dbus_object_manager_server, G_TYPE_OBJECT, + G_ADD_PRIVATE (GDBusObjectManagerServer) + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init)) + +static void g_dbus_object_manager_server_constructed (GObject *object); + +static void +g_dbus_object_manager_server_finalize (GObject *object) +{ + GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object); + + if (manager->priv->connection != NULL) + { + unexport_all (manager, TRUE); + g_object_unref (manager->priv->connection); + } + g_hash_table_unref (manager->priv->map_object_path_to_data); + g_free (manager->priv->object_path); + g_free (manager->priv->object_path_ending_in_slash); + + g_mutex_clear (&manager->priv->lock); + + if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize (object); +} + +static void +g_dbus_object_manager_server_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object); + + switch (prop_id) + { + case PROP_CONNECTION: + g_mutex_lock (&manager->priv->lock); + g_value_set_object (value, manager->priv->connection); + g_mutex_unlock (&manager->priv->lock); + break; + + case PROP_OBJECT_PATH: + g_value_set_string (value, g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_manager_server_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object); + + switch (prop_id) + { + case PROP_CONNECTION: + g_dbus_object_manager_server_set_connection (manager, g_value_get_object (value)); + break; + + case PROP_OBJECT_PATH: + g_assert (manager->priv->object_path == NULL); + g_assert (g_variant_is_object_path (g_value_get_string (value))); + manager->priv->object_path = g_value_dup_string (value); + if (g_str_equal (manager->priv->object_path, "/")) + manager->priv->object_path_ending_in_slash = g_strdup (manager->priv->object_path); + else + manager->priv->object_path_ending_in_slash = g_strdup_printf ("%s/", manager->priv->object_path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_manager_server_class_init (GDBusObjectManagerServerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_object_manager_server_finalize; + gobject_class->constructed = g_dbus_object_manager_server_constructed; + gobject_class->set_property = g_dbus_object_manager_server_set_property; + gobject_class->get_property = g_dbus_object_manager_server_get_property; + + /** + * GDBusObjectManagerServer:connection: + * + * The #GDBusConnection to export objects on. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_CONNECTION, + g_param_spec_object ("connection", + "Connection", + "The connection to export objects on", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectManagerServer:object-path: + * + * The object path to register the manager object at. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_OBJECT_PATH, + g_param_spec_string ("object-path", + "Object Path", + "The object path to register the manager object at", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_dbus_object_manager_server_init (GDBusObjectManagerServer *manager) +{ + manager->priv = g_dbus_object_manager_server_get_instance_private (manager); + g_mutex_init (&manager->priv->lock); + manager->priv->map_object_path_to_data = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) registration_data_free); +} + +/** + * g_dbus_object_manager_server_new: + * @object_path: The object path to export the manager object at. + * + * Creates a new #GDBusObjectManagerServer object. + * + * The returned server isn't yet exported on any connection. To do so, + * use g_dbus_object_manager_server_set_connection(). Normally you + * want to export all of your objects before doing so to avoid + * [InterfacesAdded](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager) + * signals being emitted. + * + * Returns: A #GDBusObjectManagerServer object. Free with g_object_unref(). + * + * Since: 2.30 + */ +GDBusObjectManagerServer * +g_dbus_object_manager_server_new (const gchar *object_path) +{ + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + return G_DBUS_OBJECT_MANAGER_SERVER (g_object_new (G_TYPE_DBUS_OBJECT_MANAGER_SERVER, + "object-path", object_path, + NULL)); +} + +/** + * g_dbus_object_manager_server_set_connection: + * @manager: A #GDBusObjectManagerServer. + * @connection: (nullable): A #GDBusConnection or %NULL. + * + * Exports all objects managed by @manager on @connection. If + * @connection is %NULL, stops exporting objects. + */ +void +g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager, + GDBusConnection *connection) +{ + g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager)); + g_return_if_fail (connection == NULL || G_IS_DBUS_CONNECTION (connection)); + + g_mutex_lock (&manager->priv->lock); + + if (manager->priv->connection == connection) + { + g_mutex_unlock (&manager->priv->lock); + goto out; + } + + if (manager->priv->connection != NULL) + { + unexport_all (manager, FALSE); + g_object_unref (manager->priv->connection); + manager->priv->connection = NULL; + } + + manager->priv->connection = connection != NULL ? g_object_ref (connection) : NULL; + if (manager->priv->connection != NULL) + export_all (manager); + + g_mutex_unlock (&manager->priv->lock); + + g_object_notify (G_OBJECT (manager), "connection"); + out: + ; +} + +/** + * g_dbus_object_manager_server_get_connection: + * @manager: A #GDBusObjectManagerServer + * + * Gets the #GDBusConnection used by @manager. + * + * Returns: (transfer full) (nullable): A #GDBusConnection object or %NULL if + * @manager isn't exported on a connection. The returned object should + * be freed with g_object_unref(). + * + * Since: 2.30 + */ +GDBusConnection * +g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager) +{ + GDBusConnection *ret; + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), NULL); + g_mutex_lock (&manager->priv->lock); + ret = manager->priv->connection != NULL ? g_object_ref (manager->priv->connection) : NULL; + g_mutex_unlock (&manager->priv->lock); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +registration_data_export_interface (RegistrationData *data, + GDBusInterfaceSkeleton *interface_skeleton, + const gchar *object_path) +{ + GDBusInterfaceInfo *info; + GError *error; + + info = g_dbus_interface_skeleton_get_info (interface_skeleton); + error = NULL; + if (data->manager->priv->connection != NULL) + { + if (!g_dbus_interface_skeleton_export (interface_skeleton, + data->manager->priv->connection, + object_path, + &error)) + { + g_warning ("%s: Error registering object at %s with interface %s: %s", + G_STRLOC, + object_path, + info->name, + error->message); + g_error_free (error); + } + } + + g_assert (g_hash_table_lookup (data->map_iface_name_to_iface, info->name) == NULL); + g_hash_table_insert (data->map_iface_name_to_iface, + info->name, + g_object_ref (interface_skeleton)); + + /* if we are already exported, then... */ + if (data->exported) + { + const gchar *interfaces[2]; + /* emit InterfacesAdded on the ObjectManager object */ + interfaces[0] = info->name; + interfaces[1] = NULL; + g_dbus_object_manager_server_emit_interfaces_added (data->manager, data, interfaces, object_path); + } +} + +static void +registration_data_unexport_interface (RegistrationData *data, + GDBusInterfaceSkeleton *interface_skeleton) +{ + GDBusInterfaceInfo *info; + GDBusInterfaceSkeleton *iface; + + info = g_dbus_interface_skeleton_get_info (interface_skeleton); + iface = g_hash_table_lookup (data->map_iface_name_to_iface, info->name); + g_assert (iface != NULL); + + if (data->manager->priv->connection != NULL) + g_dbus_interface_skeleton_unexport (iface); + + g_warn_if_fail (g_hash_table_remove (data->map_iface_name_to_iface, info->name)); + + /* if we are already exported, then... */ + if (data->exported) + { + const gchar *interfaces[2]; + /* emit InterfacesRemoved on the ObjectManager object */ + interfaces[0] = info->name; + interfaces[1] = NULL; + g_dbus_object_manager_server_emit_interfaces_removed (data->manager, data, interfaces); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_interface_added (GDBusObject *object, + GDBusInterface *interface, + gpointer user_data) +{ + RegistrationData *data = user_data; + const gchar *object_path; + g_mutex_lock (&data->manager->priv->lock); + object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object)); + registration_data_export_interface (data, G_DBUS_INTERFACE_SKELETON (interface), object_path); + g_mutex_unlock (&data->manager->priv->lock); +} + +static void +on_interface_removed (GDBusObject *object, + GDBusInterface *interface, + gpointer user_data) +{ + RegistrationData *data = user_data; + g_mutex_lock (&data->manager->priv->lock); + registration_data_unexport_interface (data, G_DBUS_INTERFACE_SKELETON (interface)); + g_mutex_unlock (&data->manager->priv->lock); +} + +/* ---------------------------------------------------------------------------------------------------- */ + + +static void +registration_data_free (RegistrationData *data) +{ + GHashTableIter iter; + GDBusInterfaceSkeleton *iface; + + data->exported = FALSE; + + g_hash_table_iter_init (&iter, data->map_iface_name_to_iface); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &iface)) + { + if (data->manager->priv->connection != NULL) + g_dbus_interface_skeleton_unexport (iface); + } + + g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_added), data); + g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_removed), data); + g_object_unref (data->object); + g_hash_table_destroy (data->map_iface_name_to_iface); + g_free (data); +} + +/* Validate whether an object path is valid as a child of the manager. According + * to the specification: + * https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager + * this means that: + * > All returned object paths are children of the object path implementing this + * > interface, i.e. their object paths start with the ObjectManager's object + * > path plus '/' + * + * For example, if the manager is at `/org/gnome/Example`, children will be + * `/org/gnome/Example/(.+)`. + * + * It is permissible (but not encouraged) for the manager to be at `/`. If so, + * children will be `/(.+)`. + */ +static gboolean +is_valid_child_object_path (GDBusObjectManagerServer *manager, + const gchar *child_object_path) +{ + /* Historically GDBus accepted @child_object_paths at `/` if the @manager + * itself is also at `/". This is not spec-compliant, but making GDBus enforce + * the spec more strictly would be an incompatible change. + * + * See https://gitlab.gnome.org/GNOME/glib/-/issues/2500 */ + g_warn_if_fail (!g_str_equal (child_object_path, manager->priv->object_path_ending_in_slash)); + + return g_str_has_prefix (child_object_path, manager->priv->object_path_ending_in_slash); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +g_dbus_object_manager_server_export_unlocked (GDBusObjectManagerServer *manager, + GDBusObjectSkeleton *object, + const gchar *object_path) +{ + RegistrationData *data; + GList *existing_interfaces; + GList *l; + GPtrArray *interface_names; + + g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager)); + g_return_if_fail (G_IS_DBUS_OBJECT (object)); + g_return_if_fail (is_valid_child_object_path (manager, object_path)); + + interface_names = g_ptr_array_new (); + + data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path); + if (data != NULL) + g_dbus_object_manager_server_unexport_unlocked (manager, object_path); + + data = g_new0 (RegistrationData, 1); + data->object = g_object_ref (object); + data->manager = manager; + data->map_iface_name_to_iface = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) g_object_unref); + + g_signal_connect (object, + "interface-added", + G_CALLBACK (on_interface_added), + data); + g_signal_connect (object, + "interface-removed", + G_CALLBACK (on_interface_removed), + data); + + /* Register all known interfaces - note that data->exported is FALSE so + * we don't emit any InterfacesAdded signals. + */ + existing_interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object)); + for (l = existing_interfaces; l != NULL; l = l->next) + { + GDBusInterfaceSkeleton *interface_skeleton = G_DBUS_INTERFACE_SKELETON (l->data); + registration_data_export_interface (data, interface_skeleton, object_path); + g_ptr_array_add (interface_names, g_dbus_interface_skeleton_get_info (interface_skeleton)->name); + } + g_list_free_full (existing_interfaces, g_object_unref); + g_ptr_array_add (interface_names, NULL); + + data->exported = TRUE; + + /* now emit InterfacesAdded() for all the interfaces */ + g_dbus_object_manager_server_emit_interfaces_added (manager, data, (const gchar *const *) interface_names->pdata, object_path); + g_ptr_array_unref (interface_names); + + g_hash_table_insert (manager->priv->map_object_path_to_data, + g_strdup (object_path), + data); +} + +/** + * g_dbus_object_manager_server_export: + * @manager: A #GDBusObjectManagerServer. + * @object: A #GDBusObjectSkeleton. + * + * Exports @object on @manager. + * + * If there is already a #GDBusObject exported at the object path, + * then the old object is removed. + * + * The object path for @object must be in the hierarchy rooted by the + * object path for @manager. + * + * Note that @manager will take a reference on @object for as long as + * it is exported. + * + * Since: 2.30 + */ +void +g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager, + GDBusObjectSkeleton *object) +{ + g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager)); + g_mutex_lock (&manager->priv->lock); + g_dbus_object_manager_server_export_unlocked (manager, object, + g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); + g_mutex_unlock (&manager->priv->lock); +} + +/** + * g_dbus_object_manager_server_export_uniquely: + * @manager: A #GDBusObjectManagerServer. + * @object: An object. + * + * Like g_dbus_object_manager_server_export() but appends a string of + * the form _N (with N being a natural number) to @object's object path + * if an object with the given path already exists. As such, the + * #GDBusObjectProxy:g-object-path property of @object may be modified. + * + * Since: 2.30 + */ +void +g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager, + GDBusObjectSkeleton *object) +{ + const gchar *orig_object_path; + gchar *object_path; + guint count; + gboolean modified; + + orig_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); + + g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager)); + g_return_if_fail (G_IS_DBUS_OBJECT (object)); + g_return_if_fail (is_valid_child_object_path (manager, orig_object_path)); + + g_mutex_lock (&manager->priv->lock); + + object_path = g_strdup (orig_object_path); + count = 1; + modified = FALSE; + while (TRUE) + { + RegistrationData *data; + data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path); + if (data == NULL) + { + break; + } + g_free (object_path); + object_path = g_strdup_printf ("%s_%d", orig_object_path, count++); + modified = TRUE; + } + + g_dbus_object_manager_server_export_unlocked (manager, object, object_path); + + g_mutex_unlock (&manager->priv->lock); + + if (modified) + g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path); + + g_free (object_path); + +} + +/** + * g_dbus_object_manager_server_is_exported: + * @manager: A #GDBusObjectManagerServer. + * @object: An object. + * + * Returns whether @object is currently exported on @manager. + * + * Returns: %TRUE if @object is exported + * + * Since: 2.34 + **/ +gboolean +g_dbus_object_manager_server_is_exported (GDBusObjectManagerServer *manager, + GDBusObjectSkeleton *object) +{ + RegistrationData *data = NULL; + const gchar *object_path; + gboolean object_is_exported; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE); + g_return_val_if_fail (G_IS_DBUS_OBJECT (object), FALSE); + + g_mutex_lock (&manager->priv->lock); + + object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); + if (object_path != NULL) + data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path); + object_is_exported = (data != NULL); + + g_mutex_unlock (&manager->priv->lock); + + return object_is_exported; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer *manager, + const gchar *object_path) +{ + RegistrationData *data; + gboolean ret; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE); + g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE); + g_return_val_if_fail (is_valid_child_object_path (manager, object_path), FALSE); + + ret = FALSE; + + data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path); + if (data != NULL) + { + GPtrArray *interface_names; + GHashTableIter iter; + const gchar *iface_name; + + interface_names = g_ptr_array_new (); + g_hash_table_iter_init (&iter, data->map_iface_name_to_iface); + while (g_hash_table_iter_next (&iter, (gpointer) &iface_name, NULL)) + g_ptr_array_add (interface_names, (gpointer) iface_name); + g_ptr_array_add (interface_names, NULL); + /* now emit InterfacesRemoved() for all the interfaces */ + g_dbus_object_manager_server_emit_interfaces_removed (manager, data, (const gchar *const *) interface_names->pdata); + g_ptr_array_unref (interface_names); + + g_hash_table_remove (manager->priv->map_object_path_to_data, object_path); + ret = TRUE; + } + + return ret; +} + +/** + * g_dbus_object_manager_server_unexport: + * @manager: A #GDBusObjectManagerServer. + * @object_path: An object path. + * + * If @manager has an object at @path, removes the object. Otherwise + * does nothing. + * + * Note that @object_path must be in the hierarchy rooted by the + * object path for @manager. + * + * Returns: %TRUE if object at @object_path was removed, %FALSE otherwise. + * + * Since: 2.30 + */ +gboolean +g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager, + const gchar *object_path) +{ + gboolean ret; + g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE); + g_mutex_lock (&manager->priv->lock); + ret = g_dbus_object_manager_server_unexport_unlocked (manager, object_path); + g_mutex_unlock (&manager->priv->lock); + return ret; +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +static const GDBusArgInfo manager_interfaces_added_signal_info_arg0 = +{ + -1, + "object_path", + "o", + (GDBusAnnotationInfo**) NULL, +}; + +static const GDBusArgInfo manager_interfaces_added_signal_info_arg1 = +{ + -1, + "interfaces_and_properties", + "a{sa{sv}}", + (GDBusAnnotationInfo**) NULL, +}; + +static const GDBusArgInfo * const manager_interfaces_added_signal_info_arg_pointers[] = +{ + &manager_interfaces_added_signal_info_arg0, + &manager_interfaces_added_signal_info_arg1, + NULL +}; + +static const GDBusSignalInfo manager_interfaces_added_signal_info = +{ + -1, + "InterfacesAdded", + (GDBusArgInfo**) &manager_interfaces_added_signal_info_arg_pointers, + (GDBusAnnotationInfo**) NULL +}; + +/* ---------- */ + +static const GDBusArgInfo manager_interfaces_removed_signal_info_arg0 = +{ + -1, + "object_path", + "o", + (GDBusAnnotationInfo**) NULL, +}; + +static const GDBusArgInfo manager_interfaces_removed_signal_info_arg1 = +{ + -1, + "interfaces", + "as", + (GDBusAnnotationInfo**) NULL, +}; + +static const GDBusArgInfo * const manager_interfaces_removed_signal_info_arg_pointers[] = +{ + &manager_interfaces_removed_signal_info_arg0, + &manager_interfaces_removed_signal_info_arg1, + NULL +}; + +static const GDBusSignalInfo manager_interfaces_removed_signal_info = +{ + -1, + "InterfacesRemoved", + (GDBusArgInfo**) &manager_interfaces_removed_signal_info_arg_pointers, + (GDBusAnnotationInfo**) NULL +}; + +/* ---------- */ + +static const GDBusSignalInfo * const manager_signal_info_pointers[] = +{ + &manager_interfaces_added_signal_info, + &manager_interfaces_removed_signal_info, + NULL +}; + +/* ---------- */ + +static const GDBusArgInfo manager_get_all_method_info_out_arg0 = +{ + -1, + "object_paths_interfaces_and_properties", + "a{oa{sa{sv}}}", + (GDBusAnnotationInfo**) NULL, +}; + +static const GDBusArgInfo * const manager_get_all_method_info_out_arg_pointers[] = +{ + &manager_get_all_method_info_out_arg0, + NULL +}; + +static const GDBusMethodInfo manager_get_all_method_info = +{ + -1, + "GetManagedObjects", + (GDBusArgInfo**) NULL, + (GDBusArgInfo**) &manager_get_all_method_info_out_arg_pointers, + (GDBusAnnotationInfo**) NULL +}; + +static const GDBusMethodInfo * const manager_method_info_pointers[] = +{ + &manager_get_all_method_info, + NULL +}; + +/* ---------- */ + +static const GDBusInterfaceInfo manager_interface_info = +{ + -1, + "org.freedesktop.DBus.ObjectManager", + (GDBusMethodInfo **) manager_method_info_pointers, + (GDBusSignalInfo **) manager_signal_info_pointers, + (GDBusPropertyInfo **) NULL, + (GDBusAnnotationInfo **) NULL +}; + +static void +manager_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (user_data); + GVariantBuilder array_builder; + GHashTableIter object_iter; + RegistrationData *data; + + g_mutex_lock (&manager->priv->lock); + + if (g_strcmp0 (method_name, "GetManagedObjects") == 0) + { + g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}")); + g_hash_table_iter_init (&object_iter, manager->priv->map_object_path_to_data); + while (g_hash_table_iter_next (&object_iter, NULL, (gpointer) &data)) + { + GVariantBuilder interfaces_builder; + GHashTableIter interface_iter; + GDBusInterfaceSkeleton *iface; + const gchar *iter_object_path; + + g_variant_builder_init (&interfaces_builder, G_VARIANT_TYPE ("a{sa{sv}}")); + g_hash_table_iter_init (&interface_iter, data->map_iface_name_to_iface); + while (g_hash_table_iter_next (&interface_iter, NULL, (gpointer) &iface)) + { + GVariant *properties = g_dbus_interface_skeleton_get_properties (iface); + g_variant_builder_add (&interfaces_builder, "{s@a{sv}}", + g_dbus_interface_skeleton_get_info (iface)->name, + properties); + g_variant_unref (properties); + } + iter_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object)); + g_variant_builder_add (&array_builder, + "{oa{sa{sv}}}", + iter_object_path, + &interfaces_builder); + } + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(a{oa{sa{sv}}})", + &array_builder)); + } + else + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s - only GetManagedObjects() is supported", + method_name); + } + g_mutex_unlock (&manager->priv->lock); +} + +static const GDBusInterfaceVTable manager_interface_vtable = +{ + manager_method_call, /* handle_method_call */ + NULL, /* get_property */ + NULL, /* set_property */ + { 0 } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +g_dbus_object_manager_server_constructed (GObject *object) +{ + GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object); + + if (manager->priv->connection != NULL) + export_all (manager); + + if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed != NULL) + G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed (object); +} + +static void +g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager, + RegistrationData *data, + const gchar *const *interfaces, + const gchar *object_path) +{ + GVariantBuilder array_builder; + GError *error; + guint n; + + if (data->manager->priv->connection == NULL) + goto out; + + g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{sa{sv}}")); + for (n = 0; interfaces[n] != NULL; n++) + { + GDBusInterfaceSkeleton *iface; + GVariant *properties; + + iface = g_hash_table_lookup (data->map_iface_name_to_iface, interfaces[n]); + g_assert (iface != NULL); + properties = g_dbus_interface_skeleton_get_properties (iface); + g_variant_builder_add (&array_builder, "{s@a{sv}}", interfaces[n], properties); + g_variant_unref (properties); + } + + error = NULL; + g_dbus_connection_emit_signal (data->manager->priv->connection, + NULL, /* destination_bus_name */ + manager->priv->object_path, + manager_interface_info.name, + "InterfacesAdded", + g_variant_new ("(oa{sa{sv}})", + object_path, + &array_builder), + &error); + if (error) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED)) + g_warning ("Couldn't emit InterfacesAdded signal: %s", error->message); + g_error_free (error); + } + out: + ; +} + +static void +g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager, + RegistrationData *data, + const gchar *const *interfaces) +{ + GVariantBuilder array_builder; + GError *error; + guint n; + const gchar *object_path; + + if (data->manager->priv->connection == NULL) + goto out; + + g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as")); + for (n = 0; interfaces[n] != NULL; n++) + g_variant_builder_add (&array_builder, "s", interfaces[n]); + + error = NULL; + object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object)); + g_dbus_connection_emit_signal (data->manager->priv->connection, + NULL, /* destination_bus_name */ + manager->priv->object_path, + manager_interface_info.name, + "InterfacesRemoved", + g_variant_new ("(oas)", + object_path, + &array_builder), + &error); + if (error) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED)) + g_warning ("Couldn't emit InterfacesRemoved signal: %s", error->message); + g_error_free (error); + } + out: + ; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GList * +g_dbus_object_manager_server_get_objects (GDBusObjectManager *_manager) +{ + GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager); + GList *ret; + GHashTableIter iter; + RegistrationData *data; + + g_mutex_lock (&manager->priv->lock); + + ret = NULL; + g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data)) + { + ret = g_list_prepend (ret, g_object_ref (data->object)); + } + + g_mutex_unlock (&manager->priv->lock); + + return ret; +} + +static const gchar * +g_dbus_object_manager_server_get_object_path (GDBusObjectManager *_manager) +{ + GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager); + return manager->priv->object_path; +} + +static GDBusObject * +g_dbus_object_manager_server_get_object (GDBusObjectManager *_manager, + const gchar *object_path) +{ + GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager); + GDBusObject *ret; + RegistrationData *data; + + ret = NULL; + + g_mutex_lock (&manager->priv->lock); + data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path); + if (data != NULL) + ret = g_object_ref (G_DBUS_OBJECT (data->object)); + g_mutex_unlock (&manager->priv->lock); + + return ret; +} + +static GDBusInterface * +g_dbus_object_manager_server_get_interface (GDBusObjectManager *_manager, + const gchar *object_path, + const gchar *interface_name) +{ + GDBusInterface *ret; + GDBusObject *object; + + ret = NULL; + + object = g_dbus_object_manager_get_object (_manager, object_path); + if (object == NULL) + goto out; + + ret = g_dbus_object_get_interface (object, interface_name); + g_object_unref (object); + + out: + return ret; +} + +static void +dbus_object_manager_interface_init (GDBusObjectManagerIface *iface) +{ + iface->get_object_path = g_dbus_object_manager_server_get_object_path; + iface->get_objects = g_dbus_object_manager_server_get_objects; + iface->get_object = g_dbus_object_manager_server_get_object; + iface->get_interface = g_dbus_object_manager_server_get_interface; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +export_all (GDBusObjectManagerServer *manager) +{ + GHashTableIter iter; + const gchar *object_path; + RegistrationData *data; + GHashTableIter iface_iter; + GDBusInterfaceSkeleton *iface; + GError *error; + + g_return_if_fail (manager->priv->connection != NULL); + + error = NULL; + g_warn_if_fail (manager->priv->manager_reg_id == 0); + manager->priv->manager_reg_id = g_dbus_connection_register_object (manager->priv->connection, + manager->priv->object_path, + (GDBusInterfaceInfo *) &manager_interface_info, + &manager_interface_vtable, + manager, + NULL, /* user_data_free_func */ + &error); + if (manager->priv->manager_reg_id == 0) + { + g_warning ("%s: Error registering manager at %s: %s", + G_STRLOC, + manager->priv->object_path, + error->message); + g_error_free (error); + } + + g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data); + while (g_hash_table_iter_next (&iter, (gpointer) &object_path, (gpointer) &data)) + { + g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface); + while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface)) + { + g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) == NULL); + error = NULL; + if (!g_dbus_interface_skeleton_export (iface, + manager->priv->connection, + object_path, + &error)) + { + g_warning ("%s: Error registering object at %s with interface %s: %s", + G_STRLOC, + object_path, + g_dbus_interface_skeleton_get_info (iface)->name, + error->message); + g_error_free (error); + } + } + } +} + +static void +unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager) +{ + GHashTableIter iter; + RegistrationData *data; + GHashTableIter iface_iter; + GDBusInterfaceSkeleton *iface; + + g_return_if_fail (manager->priv->connection != NULL); + + g_warn_if_fail (manager->priv->manager_reg_id > 0); + if (manager->priv->manager_reg_id > 0) + { + g_warn_if_fail (g_dbus_connection_unregister_object (manager->priv->connection, + manager->priv->manager_reg_id)); + manager->priv->manager_reg_id = 0; + } + if (only_manager) + goto out; + + g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data)) + { + g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface); + while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface)) + { + g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) != NULL); + g_dbus_interface_skeleton_unexport (iface); + } + } + out: + ; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusobjectmanagerserver.h b/gio/gdbusobjectmanagerserver.h new file mode 100644 index 0000000..dd725b7 --- /dev/null +++ b/gio/gdbusobjectmanagerserver.h @@ -0,0 +1,93 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_OBJECT_MANAGER_SERVER_H__ +#define __G_DBUS_OBJECT_MANAGER_SERVER_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_OBJECT_MANAGER_SERVER (g_dbus_object_manager_server_get_type ()) +#define G_DBUS_OBJECT_MANAGER_SERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_MANAGER_SERVER, GDBusObjectManagerServer)) +#define G_DBUS_OBJECT_MANAGER_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_MANAGER_SERVER, GDBusObjectManagerServerClass)) +#define G_DBUS_OBJECT_MANAGER_SERVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_MANAGER_SERVER, GDBusObjectManagerServerClass)) +#define G_IS_DBUS_OBJECT_MANAGER_SERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_MANAGER_SERVER)) +#define G_IS_DBUS_OBJECT_MANAGER_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_MANAGER_SERVER)) + +typedef struct _GDBusObjectManagerServerClass GDBusObjectManagerServerClass; +typedef struct _GDBusObjectManagerServerPrivate GDBusObjectManagerServerPrivate; + +/** + * GDBusObjectManagerServer: + * + * The #GDBusObjectManagerServer structure contains private data and should + * only be accessed using the provided API. + * + * Since: 2.30 + */ +struct _GDBusObjectManagerServer +{ + /*< private >*/ + GObject parent_instance; + GDBusObjectManagerServerPrivate *priv; +}; + +/** + * GDBusObjectManagerServerClass: + * @parent_class: The parent class. + * + * Class structure for #GDBusObjectManagerServer. + * + * Since: 2.30 + */ +struct _GDBusObjectManagerServerClass +{ + GObjectClass parent_class; + + /*< private >*/ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_object_manager_server_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDBusObjectManagerServer *g_dbus_object_manager_server_new (const gchar *object_path); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager, + GDBusConnection *connection); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager, + GDBusObjectSkeleton *object); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager, + GDBusObjectSkeleton *object); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_object_manager_server_is_exported (GDBusObjectManagerServer *manager, + GDBusObjectSkeleton *object); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager, + const gchar *object_path); + +G_END_DECLS + +#endif /* __G_DBUS_OBJECT_MANAGER_SERVER_H */ diff --git a/gio/gdbusobjectproxy.c b/gio/gdbusobjectproxy.c new file mode 100644 index 0000000..ae87b42 --- /dev/null +++ b/gio/gdbusobjectproxy.c @@ -0,0 +1,356 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusobject.h" +#include "gdbusobjectproxy.h" +#include "gdbusconnection.h" +#include "gdbusprivate.h" +#include "gdbusutils.h" +#include "gdbusproxy.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusobjectproxy + * @short_description: Client-side D-Bus object + * @include: gio/gio.h + * + * A #GDBusObjectProxy is an object used to represent a remote object + * with one or more D-Bus interfaces. Normally, you don't instantiate + * a #GDBusObjectProxy yourself - typically #GDBusObjectManagerClient + * is used to obtain it. + * + * Since: 2.30 + */ + +struct _GDBusObjectProxyPrivate +{ + GMutex lock; + GHashTable *map_name_to_iface; + gchar *object_path; + GDBusConnection *connection; +}; + +enum +{ + PROP_0, + PROP_G_OBJECT_PATH, + PROP_G_CONNECTION +}; + +static void dbus_object_interface_init (GDBusObjectIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GDBusObjectProxy, g_dbus_object_proxy, G_TYPE_OBJECT, + G_ADD_PRIVATE (GDBusObjectProxy) + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init)) + +static void +g_dbus_object_proxy_finalize (GObject *object) +{ + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); + + g_hash_table_unref (proxy->priv->map_name_to_iface); + + g_clear_object (&proxy->priv->connection); + + g_free (proxy->priv->object_path); + + g_mutex_clear (&proxy->priv->lock); + + if (G_OBJECT_CLASS (g_dbus_object_proxy_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_dbus_object_proxy_parent_class)->finalize (object); +} + +static void +g_dbus_object_proxy_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); + + switch (prop_id) + { + case PROP_G_OBJECT_PATH: + g_mutex_lock (&proxy->priv->lock); + g_value_set_string (value, proxy->priv->object_path); + g_mutex_unlock (&proxy->priv->lock); + break; + + case PROP_G_CONNECTION: + g_value_set_object (value, g_dbus_object_proxy_get_connection (proxy)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (proxy, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_proxy_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); + + switch (prop_id) + { + case PROP_G_OBJECT_PATH: + g_mutex_lock (&proxy->priv->lock); + proxy->priv->object_path = g_value_dup_string (value); + g_mutex_unlock (&proxy->priv->lock); + break; + + case PROP_G_CONNECTION: + g_mutex_lock (&proxy->priv->lock); + proxy->priv->connection = g_value_dup_object (value); + g_mutex_unlock (&proxy->priv->lock); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (proxy, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_proxy_class_init (GDBusObjectProxyClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_object_proxy_finalize; + gobject_class->set_property = g_dbus_object_proxy_set_property; + gobject_class->get_property = g_dbus_object_proxy_get_property; + + /** + * GDBusObjectProxy:g-object-path: + * + * The object path of the proxy. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_G_OBJECT_PATH, + g_param_spec_string ("g-object-path", + "Object Path", + "The object path of the proxy", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectProxy:g-connection: + * + * The connection of the proxy. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_G_CONNECTION, + g_param_spec_object ("g-connection", + "Connection", + "The connection of the proxy", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_dbus_object_proxy_init (GDBusObjectProxy *proxy) +{ + proxy->priv = g_dbus_object_proxy_get_instance_private (proxy); + g_mutex_init (&proxy->priv->lock); + proxy->priv->map_name_to_iface = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_object_unref); +} + +static const gchar * +g_dbus_object_proxy_get_object_path (GDBusObject *object) +{ + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); + const gchar *ret; + g_mutex_lock (&proxy->priv->lock); + ret = proxy->priv->object_path; + g_mutex_unlock (&proxy->priv->lock); + return ret; +} + +/** + * g_dbus_object_proxy_get_connection: + * @proxy: a #GDBusObjectProxy + * + * Gets the connection that @proxy is for. + * + * Returns: (transfer none): A #GDBusConnection. Do not free, the + * object is owned by @proxy. + * + * Since: 2.30 + */ +GDBusConnection * +g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy) +{ + GDBusConnection *ret; + g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); + g_mutex_lock (&proxy->priv->lock); + ret = proxy->priv->connection; + g_mutex_unlock (&proxy->priv->lock); + return ret; +} + +static GDBusInterface * +g_dbus_object_proxy_get_interface (GDBusObject *object, + const gchar *interface_name) +{ + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); + GDBusProxy *ret; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); + g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); + + g_mutex_lock (&proxy->priv->lock); + ret = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name); + if (ret != NULL) + g_object_ref (ret); + g_mutex_unlock (&proxy->priv->lock); + + return (GDBusInterface *) ret; /* TODO: proper cast */ +} + +static GList * +g_dbus_object_proxy_get_interfaces (GDBusObject *object) +{ + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); + GList *ret; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); + + ret = NULL; + + g_mutex_lock (&proxy->priv->lock); + ret = g_hash_table_get_values (proxy->priv->map_name_to_iface); + g_list_foreach (ret, (GFunc) g_object_ref, NULL); + g_mutex_unlock (&proxy->priv->lock); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_object_proxy_new: + * @connection: a #GDBusConnection + * @object_path: the object path + * + * Creates a new #GDBusObjectProxy for the given connection and + * object path. + * + * Returns: a new #GDBusObjectProxy + * + * Since: 2.30 + */ +GDBusObjectProxy * +g_dbus_object_proxy_new (GDBusConnection *connection, + const gchar *object_path) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + return G_DBUS_OBJECT_PROXY (g_object_new (G_TYPE_DBUS_OBJECT_PROXY, + "g-object-path", object_path, + "g-connection", connection, + NULL)); +} + +void +_g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy, + GDBusProxy *interface_proxy) +{ + const gchar *interface_name; + GDBusProxy *interface_proxy_to_remove; + + g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy)); + g_return_if_fail (G_IS_DBUS_PROXY (interface_proxy)); + + g_mutex_lock (&proxy->priv->lock); + + interface_name = g_dbus_proxy_get_interface_name (interface_proxy); + interface_proxy_to_remove = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name); + if (interface_proxy_to_remove != NULL) + { + g_object_ref (interface_proxy_to_remove); + g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name)); + } + g_hash_table_insert (proxy->priv->map_name_to_iface, + g_strdup (interface_name), + g_object_ref (interface_proxy)); + g_object_ref (interface_proxy); + + g_mutex_unlock (&proxy->priv->lock); + + if (interface_proxy_to_remove != NULL) + { + g_signal_emit_by_name (proxy, "interface-removed", interface_proxy_to_remove); + g_object_unref (interface_proxy_to_remove); + } + + g_signal_emit_by_name (proxy, "interface-added", interface_proxy); + g_object_unref (interface_proxy); +} + +void +_g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy, + const gchar *interface_name) +{ + GDBusProxy *interface_proxy; + + g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy)); + g_return_if_fail (g_dbus_is_interface_name (interface_name)); + + g_mutex_lock (&proxy->priv->lock); + + interface_proxy = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name); + if (interface_proxy != NULL) + { + g_object_ref (interface_proxy); + g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name)); + g_mutex_unlock (&proxy->priv->lock); + g_signal_emit_by_name (proxy, "interface-removed", interface_proxy); + g_object_unref (interface_proxy); + } + else + { + g_mutex_unlock (&proxy->priv->lock); + } +} + +static void +dbus_object_interface_init (GDBusObjectIface *iface) +{ + iface->get_object_path = g_dbus_object_proxy_get_object_path; + iface->get_interfaces = g_dbus_object_proxy_get_interfaces; + iface->get_interface = g_dbus_object_proxy_get_interface; +} diff --git a/gio/gdbusobjectproxy.h b/gio/gdbusobjectproxy.h new file mode 100644 index 0000000..38c8d51 --- /dev/null +++ b/gio/gdbusobjectproxy.h @@ -0,0 +1,79 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_OBJECT_PROXY_H__ +#define __G_DBUS_OBJECT_PROXY_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_OBJECT_PROXY (g_dbus_object_proxy_get_type ()) +#define G_DBUS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_PROXY, GDBusObjectProxy)) +#define G_DBUS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_PROXY, GDBusObjectProxyClass)) +#define G_DBUS_OBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_PROXY, GDBusObjectProxyClass)) +#define G_IS_DBUS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_PROXY)) +#define G_IS_DBUS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_PROXY)) + +typedef struct _GDBusObjectProxyClass GDBusObjectProxyClass; +typedef struct _GDBusObjectProxyPrivate GDBusObjectProxyPrivate; + +/** + * GDBusObjectProxy: + * + * The #GDBusObjectProxy structure contains private data and should + * only be accessed using the provided API. + * + * Since: 2.30 + */ +struct _GDBusObjectProxy +{ + /*< private >*/ + GObject parent_instance; + GDBusObjectProxyPrivate *priv; +}; + +/** + * GDBusObjectProxyClass: + * @parent_class: The parent class. + * + * Class structure for #GDBusObjectProxy. + * + * Since: 2.30 + */ +struct _GDBusObjectProxyClass +{ + GObjectClass parent_class; + + /*< private >*/ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_object_proxy_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDBusObjectProxy *g_dbus_object_proxy_new (GDBusConnection *connection, + const gchar *object_path); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy); + +G_END_DECLS + +#endif /* __G_DBUS_OBJECT_PROXY_H */ diff --git a/gio/gdbusobjectskeleton.c b/gio/gdbusobjectskeleton.c new file mode 100644 index 0000000..c0e5611 --- /dev/null +++ b/gio/gdbusobjectskeleton.c @@ -0,0 +1,509 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include "gdbusobject.h" +#include "gdbusobjectskeleton.h" +#include "gdbusinterfaceskeleton.h" +#include "gdbusprivate.h" +#include "gdbusmethodinvocation.h" +#include "gdbusintrospection.h" +#include "gdbusinterface.h" +#include "gdbusutils.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusobjectskeleton + * @short_description: Service-side D-Bus object + * @include: gio/gio.h + * + * A #GDBusObjectSkeleton instance is essentially a group of D-Bus + * interfaces. The set of exported interfaces on the object may be + * dynamic and change at runtime. + * + * This type is intended to be used with #GDBusObjectManager. + */ + +struct _GDBusObjectSkeletonPrivate +{ + GMutex lock; + gchar *object_path; + GHashTable *map_name_to_iface; +}; + +enum +{ + PROP_0, + PROP_G_OBJECT_PATH +}; + +enum +{ + AUTHORIZE_METHOD_SIGNAL, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = {0}; + +static void dbus_object_interface_init (GDBusObjectIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GDBusObjectSkeleton, g_dbus_object_skeleton, G_TYPE_OBJECT, + G_ADD_PRIVATE (GDBusObjectSkeleton) + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init)) + + +static void +g_dbus_object_skeleton_finalize (GObject *_object) +{ + GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (_object); + + g_free (object->priv->object_path); + g_hash_table_unref (object->priv->map_name_to_iface); + + g_mutex_clear (&object->priv->lock); + + if (G_OBJECT_CLASS (g_dbus_object_skeleton_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_dbus_object_skeleton_parent_class)->finalize (_object); +} + +static void +g_dbus_object_skeleton_get_property (GObject *_object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (_object); + + switch (prop_id) + { + case PROP_G_OBJECT_PATH: + g_mutex_lock (&object->priv->lock); + g_value_set_string (value, object->priv->object_path); + g_mutex_unlock (&object->priv->lock); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_skeleton_set_property (GObject *_object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (_object); + + switch (prop_id) + { + case PROP_G_OBJECT_PATH: + g_dbus_object_skeleton_set_object_path (object, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +g_dbus_object_skeleton_authorize_method_default (GDBusObjectSkeleton *object, + GDBusInterfaceSkeleton *interface, + GDBusMethodInvocation *invocation) +{ + return TRUE; +} + +static void +g_dbus_object_skeleton_class_init (GDBusObjectSkeletonClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_object_skeleton_finalize; + gobject_class->set_property = g_dbus_object_skeleton_set_property; + gobject_class->get_property = g_dbus_object_skeleton_get_property; + + klass->authorize_method = g_dbus_object_skeleton_authorize_method_default; + + /** + * GDBusObjectSkeleton:g-object-path: + * + * The object path where the object is exported. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, + PROP_G_OBJECT_PATH, + g_param_spec_string ("g-object-path", + "Object Path", + "The object path where the object is exported", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * GDBusObjectSkeleton::authorize-method: + * @object: The #GDBusObjectSkeleton emitting the signal. + * @interface: The #GDBusInterfaceSkeleton that @invocation is for. + * @invocation: A #GDBusMethodInvocation. + * + * Emitted when a method is invoked by a remote caller and used to + * determine if the method call is authorized. + * + * This signal is like #GDBusInterfaceSkeleton's + * #GDBusInterfaceSkeleton::g-authorize-method signal, + * except that it is for the enclosing object. + * + * The default class handler just returns %TRUE. + * + * Returns: %TRUE if the call is authorized, %FALSE otherwise. + * + * Since: 2.30 + */ + signals[AUTHORIZE_METHOD_SIGNAL] = + g_signal_new (I_("authorize-method"), + G_TYPE_DBUS_OBJECT_SKELETON, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusObjectSkeletonClass, authorize_method), + _g_signal_accumulator_false_handled, + NULL, + NULL, + G_TYPE_BOOLEAN, + 2, + G_TYPE_DBUS_INTERFACE_SKELETON, + G_TYPE_DBUS_METHOD_INVOCATION); +} + +static void +g_dbus_object_skeleton_init (GDBusObjectSkeleton *object) +{ + object->priv = g_dbus_object_skeleton_get_instance_private (object); + g_mutex_init (&object->priv->lock); + object->priv->map_name_to_iface = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_object_unref); +} + +/** + * g_dbus_object_skeleton_new: + * @object_path: An object path. + * + * Creates a new #GDBusObjectSkeleton. + * + * Returns: A #GDBusObjectSkeleton. Free with g_object_unref(). + * + * Since: 2.30 + */ +GDBusObjectSkeleton * +g_dbus_object_skeleton_new (const gchar *object_path) +{ + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + return G_DBUS_OBJECT_SKELETON (g_object_new (G_TYPE_DBUS_OBJECT_SKELETON, + "g-object-path", object_path, + NULL)); +} + +/** + * g_dbus_object_skeleton_set_object_path: + * @object: A #GDBusObjectSkeleton. + * @object_path: A valid D-Bus object path. + * + * Sets the object path for @object. + * + * Since: 2.30 + */ +void +g_dbus_object_skeleton_set_object_path (GDBusObjectSkeleton *object, + const gchar *object_path) +{ + g_return_if_fail (G_IS_DBUS_OBJECT_SKELETON (object)); + g_return_if_fail (object_path == NULL || g_variant_is_object_path (object_path)); + g_mutex_lock (&object->priv->lock); + /* TODO: fail if object is currently exported */ + if (g_strcmp0 (object->priv->object_path, object_path) != 0) + { + g_free (object->priv->object_path); + object->priv->object_path = g_strdup (object_path); + g_mutex_unlock (&object->priv->lock); + g_object_notify (G_OBJECT (object), "g-object-path"); + } + else + { + g_mutex_unlock (&object->priv->lock); + } +} + +static const gchar * +g_dbus_object_skeleton_get_object_path (GDBusObject *_object) +{ + GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (_object); + const gchar *ret; + g_mutex_lock (&object->priv->lock); + ret = object->priv->object_path; + g_mutex_unlock (&object->priv->lock); + return ret; +} + +/** + * g_dbus_object_skeleton_add_interface: + * @object: A #GDBusObjectSkeleton. + * @interface_: A #GDBusInterfaceSkeleton. + * + * Adds @interface_ to @object. + * + * If @object already contains a #GDBusInterfaceSkeleton with the same + * interface name, it is removed before @interface_ is added. + * + * Note that @object takes its own reference on @interface_ and holds + * it until removed. + * + * Since: 2.30 + */ +void +g_dbus_object_skeleton_add_interface (GDBusObjectSkeleton *object, + GDBusInterfaceSkeleton *interface_) +{ + GDBusInterfaceInfo *info; + GDBusInterface *interface_to_remove; + + g_return_if_fail (G_IS_DBUS_OBJECT_SKELETON (object)); + g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface_)); + + g_mutex_lock (&object->priv->lock); + + info = g_dbus_interface_skeleton_get_info (interface_); + g_object_ref (interface_); + + interface_to_remove = g_hash_table_lookup (object->priv->map_name_to_iface, info->name); + if (interface_to_remove != NULL) + { + g_object_ref (interface_to_remove); + g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, info->name)); + } + g_hash_table_insert (object->priv->map_name_to_iface, + g_strdup (info->name), + g_object_ref (interface_)); + g_dbus_interface_set_object (G_DBUS_INTERFACE (interface_), G_DBUS_OBJECT (object)); + + g_mutex_unlock (&object->priv->lock); + + if (interface_to_remove != NULL) + { + g_dbus_interface_set_object (interface_to_remove, NULL); + g_signal_emit_by_name (object, + "interface-removed", + interface_to_remove); + g_object_unref (interface_to_remove); + } + + g_signal_emit_by_name (object, + "interface-added", + interface_); + g_object_unref (interface_); +} + +/** + * g_dbus_object_skeleton_remove_interface: + * @object: A #GDBusObjectSkeleton. + * @interface_: A #GDBusInterfaceSkeleton. + * + * Removes @interface_ from @object. + * + * Since: 2.30 + */ +void +g_dbus_object_skeleton_remove_interface (GDBusObjectSkeleton *object, + GDBusInterfaceSkeleton *interface_) +{ + GDBusInterfaceSkeleton *other_interface; + GDBusInterfaceInfo *info; + + g_return_if_fail (G_IS_DBUS_OBJECT_SKELETON (object)); + g_return_if_fail (G_IS_DBUS_INTERFACE (interface_)); + + g_mutex_lock (&object->priv->lock); + + info = g_dbus_interface_skeleton_get_info (interface_); + + other_interface = g_hash_table_lookup (object->priv->map_name_to_iface, info->name); + if (other_interface == NULL) + { + g_mutex_unlock (&object->priv->lock); + g_warning ("Tried to remove interface with name %s from object " + "at path %s but no such interface exists", + info->name, + object->priv->object_path); + } + else if (other_interface != interface_) + { + g_mutex_unlock (&object->priv->lock); + g_warning ("Tried to remove interface %p with name %s from object " + "at path %s but the object has the interface %p", + interface_, + info->name, + object->priv->object_path, + other_interface); + } + else + { + g_object_ref (interface_); + g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, info->name)); + g_mutex_unlock (&object->priv->lock); + g_dbus_interface_set_object (G_DBUS_INTERFACE (interface_), NULL); + g_signal_emit_by_name (object, + "interface-removed", + interface_); + g_object_unref (interface_); + } +} + + +/** + * g_dbus_object_skeleton_remove_interface_by_name: + * @object: A #GDBusObjectSkeleton. + * @interface_name: A D-Bus interface name. + * + * Removes the #GDBusInterface with @interface_name from @object. + * + * If no D-Bus interface of the given interface exists, this function + * does nothing. + * + * Since: 2.30 + */ +void +g_dbus_object_skeleton_remove_interface_by_name (GDBusObjectSkeleton *object, + const gchar *interface_name) +{ + GDBusInterface *interface; + + g_return_if_fail (G_IS_DBUS_OBJECT_SKELETON (object)); + g_return_if_fail (g_dbus_is_interface_name (interface_name)); + + g_mutex_lock (&object->priv->lock); + interface = g_hash_table_lookup (object->priv->map_name_to_iface, interface_name); + if (interface != NULL) + { + g_object_ref (interface); + g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, interface_name)); + g_mutex_unlock (&object->priv->lock); + g_dbus_interface_set_object (interface, NULL); + g_signal_emit_by_name (object, + "interface-removed", + interface); + g_object_unref (interface); + } + else + { + g_mutex_unlock (&object->priv->lock); + } +} + +static GDBusInterface * +g_dbus_object_skeleton_get_interface (GDBusObject *_object, + const gchar *interface_name) +{ + GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (_object); + GDBusInterface *ret; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_SKELETON (object), NULL); + g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); + + g_mutex_lock (&object->priv->lock); + ret = g_hash_table_lookup (object->priv->map_name_to_iface, interface_name); + if (ret != NULL) + g_object_ref (ret); + g_mutex_unlock (&object->priv->lock); + return ret; +} + +static GList * +g_dbus_object_skeleton_get_interfaces (GDBusObject *_object) +{ + GDBusObjectSkeleton *object = G_DBUS_OBJECT_SKELETON (_object); + GList *ret; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_SKELETON (object), NULL); + + ret = NULL; + + g_mutex_lock (&object->priv->lock); + ret = g_hash_table_get_values (object->priv->map_name_to_iface); + g_list_foreach (ret, (GFunc) g_object_ref, NULL); + g_mutex_unlock (&object->priv->lock); + + return ret; +} + +/** + * g_dbus_object_skeleton_flush: + * @object: A #GDBusObjectSkeleton. + * + * This method simply calls g_dbus_interface_skeleton_flush() on all + * interfaces belonging to @object. See that method for when flushing + * is useful. + * + * Since: 2.30 + */ +void +g_dbus_object_skeleton_flush (GDBusObjectSkeleton *object) +{ + GList *to_flush, *l; + + g_mutex_lock (&object->priv->lock); + to_flush = g_hash_table_get_values (object->priv->map_name_to_iface); + g_list_foreach (to_flush, (GFunc) g_object_ref, NULL); + g_mutex_unlock (&object->priv->lock); + + for (l = to_flush; l != NULL; l = l->next) + g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (l->data)); + + g_list_free_full (to_flush, g_object_unref); +} + +static void +dbus_object_interface_init (GDBusObjectIface *iface) +{ + iface->get_object_path = g_dbus_object_skeleton_get_object_path; + iface->get_interfaces = g_dbus_object_skeleton_get_interfaces; + iface->get_interface = g_dbus_object_skeleton_get_interface; +} + +gboolean +_g_dbus_object_skeleton_has_authorize_method_handlers (GDBusObjectSkeleton *object) +{ + gboolean has_handlers; + gboolean has_default_class_handler; + + has_handlers = g_signal_has_handler_pending (object, + signals[AUTHORIZE_METHOD_SIGNAL], + 0, + TRUE); + has_default_class_handler = (G_DBUS_OBJECT_SKELETON_GET_CLASS (object)->authorize_method == + g_dbus_object_skeleton_authorize_method_default); + + return has_handlers || !has_default_class_handler; +} diff --git a/gio/gdbusobjectskeleton.h b/gio/gdbusobjectskeleton.h new file mode 100644 index 0000000..fe6952f --- /dev/null +++ b/gio/gdbusobjectskeleton.h @@ -0,0 +1,96 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_OBJECT_SKELETON_H__ +#define __G_DBUS_OBJECT_SKELETON_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_OBJECT_SKELETON (g_dbus_object_skeleton_get_type ()) +#define G_DBUS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_SKELETON, GDBusObjectSkeleton)) +#define G_DBUS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_SKELETON, GDBusObjectSkeletonClass)) +#define G_DBUS_OBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_SKELETON, GDBusObjectSkeletonClass)) +#define G_IS_DBUS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_SKELETON)) +#define G_IS_DBUS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_SKELETON)) + +typedef struct _GDBusObjectSkeletonClass GDBusObjectSkeletonClass; +typedef struct _GDBusObjectSkeletonPrivate GDBusObjectSkeletonPrivate; + +/** + * GDBusObjectSkeleton: + * + * The #GDBusObjectSkeleton structure contains private data and should only be + * accessed using the provided API. + * + * Since: 2.30 + */ +struct _GDBusObjectSkeleton +{ + /*< private >*/ + GObject parent_instance; + GDBusObjectSkeletonPrivate *priv; +}; + +/** + * GDBusObjectSkeletonClass: + * @parent_class: The parent class. + * @authorize_method: Signal class handler for the #GDBusObjectSkeleton::authorize-method signal. + * + * Class structure for #GDBusObjectSkeleton. + * + * Since: 2.30 + */ +struct _GDBusObjectSkeletonClass +{ + GObjectClass parent_class; + + /* Signals */ + gboolean (*authorize_method) (GDBusObjectSkeleton *object, + GDBusInterfaceSkeleton *interface_, + GDBusMethodInvocation *invocation); + + /*< private >*/ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_object_skeleton_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDBusObjectSkeleton *g_dbus_object_skeleton_new (const gchar *object_path); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_skeleton_flush (GDBusObjectSkeleton *object); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_skeleton_add_interface (GDBusObjectSkeleton *object, + GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_skeleton_remove_interface (GDBusObjectSkeleton *object, + GDBusInterfaceSkeleton *interface_); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_skeleton_remove_interface_by_name (GDBusObjectSkeleton *object, + const gchar *interface_name); +GLIB_AVAILABLE_IN_ALL +void g_dbus_object_skeleton_set_object_path (GDBusObjectSkeleton *object, + const gchar *object_path); + +G_END_DECLS + +#endif /* __G_DBUS_OBJECT_SKELETON_H */ diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c new file mode 100644 index 0000000..0b8630a --- /dev/null +++ b/gio/gdbusprivate.c @@ -0,0 +1,2629 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include + +#include "gdbusauthobserver.h" +#include "gdbusconnection.h" +#include "gdbusdaemon.h" +#include "gdbuserror.h" +#include "gdbusintrospection.h" +#include "gdbusmessage.h" +#include "gdbusprivate.h" +#include "gdbusproxy.h" +#include "ginputstream.h" +#include "gioenumtypes.h" +#include "giomodule-priv.h" +#include "giostream.h" +#include "giotypes.h" +#include "glib-private.h" +#include "glib/gstdio.h" +#include "gmemoryinputstream.h" +#include "gsocket.h" +#include "gsocketaddress.h" +#include "gsocketconnection.h" +#include "gsocketcontrolmessage.h" +#include "gsocketoutputstream.h" +#include "gtask.h" + +#ifdef G_OS_UNIX +#include "gunixfdmessage.h" +#include "gunixconnection.h" +#include "gunixcredentialsmessage.h" +#endif + +#ifdef G_OS_WIN32 +#include +#include +#include +#include "gwin32sid.h" +#endif + +#include "glibintl.h" + +static gboolean _g_dbus_worker_do_initial_read (gpointer data); +static void schedule_pending_close (GDBusWorker *worker); + +/* ---------------------------------------------------------------------------------------------------- */ + +gchar * +_g_dbus_hexdump (const gchar *data, gsize len, guint indent) +{ + guint n, m; + GString *ret; + + ret = g_string_new (NULL); + + for (n = 0; n < len; n += 16) + { + g_string_append_printf (ret, "%*s%04x: ", indent, "", n); + + for (m = n; m < n + 16; m++) + { + if (m > n && (m%4) == 0) + g_string_append_c (ret, ' '); + if (m < len) + g_string_append_printf (ret, "%02x ", (guchar) data[m]); + else + g_string_append (ret, " "); + } + + g_string_append (ret, " "); + + for (m = n; m < len && m < n + 16; m++) + g_string_append_c (ret, g_ascii_isprint (data[m]) ? data[m] : '.'); + + g_string_append_c (ret, '\n'); + } + + return g_string_free (ret, FALSE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Unfortunately ancillary messages are discarded when reading from a + * socket using the GSocketInputStream abstraction. So we provide a + * very GInputStream-ish API that uses GSocket in this case (very + * similar to GSocketInputStream). + */ + +typedef struct +{ + void *buffer; + gsize count; + + GSocketControlMessage ***messages; + gint *num_messages; +} ReadWithControlData; + +static void +read_with_control_data_free (ReadWithControlData *data) +{ + g_slice_free (ReadWithControlData, data); +} + +static gboolean +_g_socket_read_with_control_messages_ready (GSocket *socket, + GIOCondition condition, + gpointer user_data) +{ + GTask *task = user_data; + ReadWithControlData *data = g_task_get_task_data (task); + GError *error; + gssize result; + GInputVector vector; + + error = NULL; + vector.buffer = data->buffer; + vector.size = data->count; + result = g_socket_receive_message (socket, + NULL, /* address */ + &vector, + 1, + data->messages, + data->num_messages, + NULL, + g_task_get_cancellable (task), + &error); + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) + { + g_error_free (error); + return TRUE; + } + + g_assert (result >= 0 || error != NULL); + if (result >= 0) + g_task_return_int (task, result); + else + g_task_return_error (task, error); + g_object_unref (task); + + return FALSE; +} + +static void +_g_socket_read_with_control_messages (GSocket *socket, + void *buffer, + gsize count, + GSocketControlMessage ***messages, + gint *num_messages, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + ReadWithControlData *data; + GSource *source; + + data = g_slice_new0 (ReadWithControlData); + data->buffer = buffer; + data->count = count; + data->messages = messages; + data->num_messages = num_messages; + + task = g_task_new (socket, cancellable, callback, user_data); + g_task_set_source_tag (task, _g_socket_read_with_control_messages); + g_task_set_name (task, "[gio] D-Bus read"); + g_task_set_task_data (task, data, (GDestroyNotify) read_with_control_data_free); + + if (g_socket_condition_check (socket, G_IO_IN)) + { + if (!_g_socket_read_with_control_messages_ready (socket, G_IO_IN, task)) + return; + } + + source = g_socket_create_source (socket, + G_IO_IN | G_IO_HUP | G_IO_ERR, + cancellable); + g_task_attach_source (task, source, (GSourceFunc) _g_socket_read_with_control_messages_ready); + g_source_unref (source); +} + +static gssize +_g_socket_read_with_control_messages_finish (GSocket *socket, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), -1); + g_return_val_if_fail (g_task_is_valid (result, socket), -1); + + return g_task_propagate_int (G_TASK (result), error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Work-around for https://bugzilla.gnome.org/show_bug.cgi?id=674885 + and see also the original https://bugzilla.gnome.org/show_bug.cgi?id=627724 */ + +static GPtrArray *ensured_classes = NULL; + +static void +ensure_type (GType gtype) +{ + g_ptr_array_add (ensured_classes, g_type_class_ref (gtype)); +} + +static void +release_required_types (void) +{ + g_ptr_array_foreach (ensured_classes, (GFunc) g_type_class_unref, NULL); + g_ptr_array_unref (ensured_classes); + ensured_classes = NULL; +} + +static void +ensure_required_types (void) +{ + g_assert (ensured_classes == NULL); + ensured_classes = g_ptr_array_new (); + /* Generally in this list, you should initialize types which are used as + * properties first, then the class which has them. For example, GDBusProxy + * has a type of GDBusConnection, so we initialize GDBusConnection first. + * And because GDBusConnection has a property of type GDBusConnectionFlags, + * we initialize that first. + * + * Similarly, GSocket has a type of GSocketAddress. + * + * We don't fill out the whole dependency tree right now because in practice + * it tends to be just types that GDBus use that cause pain, and there + * is work on a more general approach in https://bugzilla.gnome.org/show_bug.cgi?id=674885 + */ + ensure_type (G_TYPE_TASK); + ensure_type (G_TYPE_MEMORY_INPUT_STREAM); + ensure_type (G_TYPE_DBUS_CONNECTION_FLAGS); + ensure_type (G_TYPE_DBUS_CAPABILITY_FLAGS); + ensure_type (G_TYPE_DBUS_AUTH_OBSERVER); + ensure_type (G_TYPE_DBUS_CONNECTION); + ensure_type (G_TYPE_DBUS_PROXY); + ensure_type (G_TYPE_SOCKET_FAMILY); + ensure_type (G_TYPE_SOCKET_TYPE); + ensure_type (G_TYPE_SOCKET_PROTOCOL); + ensure_type (G_TYPE_SOCKET_ADDRESS); + ensure_type (G_TYPE_SOCKET); +} +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + gint refcount; /* (atomic) */ + GThread *thread; + GMainContext *context; + GMainLoop *loop; +} SharedThreadData; + +static gpointer +gdbus_shared_thread_func (gpointer user_data) +{ + SharedThreadData *data = user_data; + + g_main_context_push_thread_default (data->context); + g_main_loop_run (data->loop); + g_main_context_pop_thread_default (data->context); + + release_required_types (); + + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static SharedThreadData * +_g_dbus_shared_thread_ref (void) +{ + static gsize shared_thread_data = 0; + SharedThreadData *ret; + + if (g_once_init_enter (&shared_thread_data)) + { + SharedThreadData *data; + + data = g_new0 (SharedThreadData, 1); + data->refcount = 0; + + data->context = g_main_context_new (); + data->loop = g_main_loop_new (data->context, FALSE); + data->thread = g_thread_new ("gdbus", + gdbus_shared_thread_func, + data); + /* We can cast between gsize and gpointer safely */ + g_once_init_leave (&shared_thread_data, (gsize) data); + } + + ret = (SharedThreadData*) shared_thread_data; + g_atomic_int_inc (&ret->refcount); + return ret; +} + +static void +_g_dbus_shared_thread_unref (SharedThreadData *data) +{ + /* TODO: actually destroy the shared thread here */ +#if 0 + g_assert (data != NULL); + if (g_atomic_int_dec_and_test (&data->refcount)) + { + g_main_loop_quit (data->loop); + //g_thread_join (data->thread); + g_main_loop_unref (data->loop); + g_main_context_unref (data->context); + } +#endif +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef enum { + PENDING_NONE = 0, + PENDING_WRITE, + PENDING_FLUSH, + PENDING_CLOSE +} OutputPending; + +struct GDBusWorker +{ + gint ref_count; /* (atomic) */ + + SharedThreadData *shared_thread_data; + + /* really a boolean, but GLib 2.28 lacks atomic boolean ops */ + gint stopped; /* (atomic) */ + + /* TODO: frozen (e.g. G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) currently + * only affects messages received from the other peer (since GDBusServer is the + * only user) - we might want it to affect messages sent to the other peer too? + */ + gboolean frozen; + GDBusCapabilityFlags capabilities; + GQueue *received_messages_while_frozen; + + GIOStream *stream; + GCancellable *cancellable; + GDBusWorkerMessageReceivedCallback message_received_callback; + GDBusWorkerMessageAboutToBeSentCallback message_about_to_be_sent_callback; + GDBusWorkerDisconnectedCallback disconnected_callback; + gpointer user_data; + + /* if not NULL, stream is GSocketConnection */ + GSocket *socket; + + /* used for reading */ + GMutex read_lock; + gchar *read_buffer; + gsize read_buffer_allocated_size; + gsize read_buffer_cur_size; + gsize read_buffer_bytes_wanted; + GUnixFDList *read_fd_list; + GSocketControlMessage **read_ancillary_messages; + gint read_num_ancillary_messages; + + /* Whether an async write, flush or close, or none of those, is pending. + * Only the worker thread may change its value, and only with the write_lock. + * Other threads may read its value when holding the write_lock. + * The worker thread may read its value at any time. + */ + OutputPending output_pending; + /* used for writing */ + GMutex write_lock; + /* queue of MessageToWriteData, protected by write_lock */ + GQueue *write_queue; + /* protected by write_lock */ + guint64 write_num_messages_written; + /* number of messages we'd written out last time we flushed; + * protected by write_lock + */ + guint64 write_num_messages_flushed; + /* list of FlushData, protected by write_lock */ + GList *write_pending_flushes; + /* list of CloseData, protected by write_lock */ + GList *pending_close_attempts; + /* no lock - only used from the worker thread */ + gboolean close_expected; +}; + +static void _g_dbus_worker_unref (GDBusWorker *worker); + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GMutex mutex; + GCond cond; + guint64 number_to_wait_for; + gboolean finished; + GError *error; +} FlushData; + +struct _MessageToWriteData ; +typedef struct _MessageToWriteData MessageToWriteData; + +static void message_to_write_data_free (MessageToWriteData *data); + +static void read_message_print_transport_debug (gssize bytes_read, + GDBusWorker *worker); + +static void write_message_print_transport_debug (gssize bytes_written, + MessageToWriteData *data); + +typedef struct { + GDBusWorker *worker; + GTask *task; +} CloseData; + +static void close_data_free (CloseData *close_data) +{ + g_clear_object (&close_data->task); + + _g_dbus_worker_unref (close_data->worker); + g_slice_free (CloseData, close_data); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusWorker * +_g_dbus_worker_ref (GDBusWorker *worker) +{ + g_atomic_int_inc (&worker->ref_count); + return worker; +} + +static void +_g_dbus_worker_unref (GDBusWorker *worker) +{ + if (g_atomic_int_dec_and_test (&worker->ref_count)) + { + g_assert (worker->write_pending_flushes == NULL); + + _g_dbus_shared_thread_unref (worker->shared_thread_data); + + g_object_unref (worker->stream); + + g_mutex_clear (&worker->read_lock); + g_object_unref (worker->cancellable); + if (worker->read_fd_list != NULL) + g_object_unref (worker->read_fd_list); + + g_queue_free_full (worker->received_messages_while_frozen, (GDestroyNotify) g_object_unref); + g_mutex_clear (&worker->write_lock); + g_queue_free_full (worker->write_queue, (GDestroyNotify) message_to_write_data_free); + g_free (worker->read_buffer); + + g_free (worker); + } +} + +static void +_g_dbus_worker_emit_disconnected (GDBusWorker *worker, + gboolean remote_peer_vanished, + GError *error) +{ + if (!g_atomic_int_get (&worker->stopped)) + worker->disconnected_callback (worker, remote_peer_vanished, error, worker->user_data); +} + +static void +_g_dbus_worker_emit_message_received (GDBusWorker *worker, + GDBusMessage *message) +{ + if (!g_atomic_int_get (&worker->stopped)) + worker->message_received_callback (worker, message, worker->user_data); +} + +static GDBusMessage * +_g_dbus_worker_emit_message_about_to_be_sent (GDBusWorker *worker, + GDBusMessage *message) +{ + GDBusMessage *ret; + if (!g_atomic_int_get (&worker->stopped)) + ret = worker->message_about_to_be_sent_callback (worker, g_steal_pointer (&message), worker->user_data); + else + ret = g_steal_pointer (&message); + return ret; +} + +/* can only be called from private thread with read-lock held - takes ownership of @message */ +static void +_g_dbus_worker_queue_or_deliver_received_message (GDBusWorker *worker, + GDBusMessage *message) +{ + if (worker->frozen || g_queue_get_length (worker->received_messages_while_frozen) > 0) + { + /* queue up */ + g_queue_push_tail (worker->received_messages_while_frozen, g_steal_pointer (&message)); + } + else + { + /* not frozen, nor anything in queue */ + _g_dbus_worker_emit_message_received (worker, message); + g_clear_object (&message); + } +} + +/* called in private thread shared by all GDBusConnection instances (without read-lock held) */ +static gboolean +unfreeze_in_idle_cb (gpointer user_data) +{ + GDBusWorker *worker = user_data; + GDBusMessage *message; + + g_mutex_lock (&worker->read_lock); + if (worker->frozen) + { + while ((message = g_queue_pop_head (worker->received_messages_while_frozen)) != NULL) + { + _g_dbus_worker_emit_message_received (worker, message); + g_clear_object (&message); + } + worker->frozen = FALSE; + } + else + { + g_assert (g_queue_get_length (worker->received_messages_while_frozen) == 0); + } + g_mutex_unlock (&worker->read_lock); + return FALSE; +} + +/* can be called from any thread */ +void +_g_dbus_worker_unfreeze (GDBusWorker *worker) +{ + GSource *idle_source; + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + unfreeze_in_idle_cb, + _g_dbus_worker_ref (worker), + (GDestroyNotify) _g_dbus_worker_unref); + g_source_set_static_name (idle_source, "[gio] unfreeze_in_idle_cb"); + g_source_attach (idle_source, worker->shared_thread_data->context); + g_source_unref (idle_source); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void _g_dbus_worker_do_read_unlocked (GDBusWorker *worker); + +/* called in private thread shared by all GDBusConnection instances (without read-lock held) */ +static void +_g_dbus_worker_do_read_cb (GInputStream *input_stream, + GAsyncResult *res, + gpointer user_data) +{ + GDBusWorker *worker = user_data; + GError *error; + gssize bytes_read; + + g_mutex_lock (&worker->read_lock); + + /* If already stopped, don't even process the reply */ + if (g_atomic_int_get (&worker->stopped)) + goto out; + + error = NULL; + if (worker->socket == NULL) + bytes_read = g_input_stream_read_finish (g_io_stream_get_input_stream (worker->stream), + res, + &error); + else + bytes_read = _g_socket_read_with_control_messages_finish (worker->socket, + res, + &error); + if (worker->read_num_ancillary_messages > 0) + { + gint n; + for (n = 0; n < worker->read_num_ancillary_messages; n++) + { + GSocketControlMessage *control_message = G_SOCKET_CONTROL_MESSAGE (worker->read_ancillary_messages[n]); + + if (FALSE) + { + } +#ifdef G_OS_UNIX + else if (G_IS_UNIX_FD_MESSAGE (control_message)) + { + GUnixFDMessage *fd_message; + gint *fds; + gint num_fds; + + fd_message = G_UNIX_FD_MESSAGE (control_message); + fds = g_unix_fd_message_steal_fds (fd_message, &num_fds); + if (worker->read_fd_list == NULL) + { + worker->read_fd_list = g_unix_fd_list_new_from_array (fds, num_fds); + } + else + { + gint n; + for (n = 0; n < num_fds; n++) + { + /* TODO: really want a append_steal() */ + g_unix_fd_list_append (worker->read_fd_list, fds[n], NULL); + (void) g_close (fds[n], NULL); + } + } + g_free (fds); + } + else if (G_IS_UNIX_CREDENTIALS_MESSAGE (control_message)) + { + /* do nothing */ + } +#endif + else + { + if (error == NULL) + { + g_set_error (&error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unexpected ancillary message of type %s received from peer", + g_type_name (G_TYPE_FROM_INSTANCE (control_message))); + _g_dbus_worker_emit_disconnected (worker, TRUE, error); + g_error_free (error); + g_object_unref (control_message); + n++; + while (n < worker->read_num_ancillary_messages) + g_object_unref (worker->read_ancillary_messages[n++]); + g_free (worker->read_ancillary_messages); + goto out; + } + } + g_object_unref (control_message); + } + g_free (worker->read_ancillary_messages); + } + + if (bytes_read == -1) + { + if (G_UNLIKELY (_g_dbus_debug_transport ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Transport:\n" + " ---- READ ERROR on stream of type %s:\n" + " ---- %s %d: %s\n", + g_type_name (G_TYPE_FROM_INSTANCE (g_io_stream_get_input_stream (worker->stream))), + g_quark_to_string (error->domain), error->code, + error->message); + _g_dbus_debug_print_unlock (); + } + + /* Every async read that uses this callback uses worker->cancellable + * as its GCancellable. worker->cancellable gets cancelled if and only + * if the GDBusConnection tells us to close (either via + * _g_dbus_worker_stop, which is called on last-unref, or directly), + * so a cancelled read must mean our connection was closed locally. + * + * If we're closing, other errors are possible - notably, + * G_IO_ERROR_CLOSED can be seen if we close the stream with an async + * read in-flight. It seems sensible to treat all read errors during + * closing as an expected thing that doesn't trip exit-on-close. + * + * Because close_expected can't be set until we get into the worker + * thread, but the cancellable is signalled sooner (from another + * thread), we do still need to check the error. + */ + if (worker->close_expected || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + _g_dbus_worker_emit_disconnected (worker, FALSE, NULL); + else + _g_dbus_worker_emit_disconnected (worker, TRUE, error); + + g_error_free (error); + goto out; + } + +#if 0 + g_debug ("read %d bytes (is_closed=%d blocking=%d condition=0x%02x) stream %p, %p", + (gint) bytes_read, + g_socket_is_closed (g_socket_connection_get_socket (G_SOCKET_CONNECTION (worker->stream))), + g_socket_get_blocking (g_socket_connection_get_socket (G_SOCKET_CONNECTION (worker->stream))), + g_socket_condition_check (g_socket_connection_get_socket (G_SOCKET_CONNECTION (worker->stream)), + G_IO_IN | G_IO_OUT | G_IO_HUP), + worker->stream, + worker); +#endif + + /* The read failed, which could mean the dbus-daemon was sent SIGTERM. */ + if (bytes_read == 0) + { + g_set_error (&error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Underlying GIOStream returned 0 bytes on an async read"); + _g_dbus_worker_emit_disconnected (worker, TRUE, error); + g_error_free (error); + goto out; + } + + read_message_print_transport_debug (bytes_read, worker); + + worker->read_buffer_cur_size += bytes_read; + if (worker->read_buffer_bytes_wanted == worker->read_buffer_cur_size) + { + /* OK, got what we asked for! */ + if (worker->read_buffer_bytes_wanted == 16) + { + gssize message_len; + /* OK, got the header - determine how many more bytes are needed */ + error = NULL; + message_len = g_dbus_message_bytes_needed ((guchar *) worker->read_buffer, + 16, + &error); + if (message_len == -1) + { + g_warning ("_g_dbus_worker_do_read_cb: error determining bytes needed: %s", error->message); + _g_dbus_worker_emit_disconnected (worker, FALSE, error); + g_error_free (error); + goto out; + } + + worker->read_buffer_bytes_wanted = message_len; + _g_dbus_worker_do_read_unlocked (worker); + } + else + { + GDBusMessage *message; + error = NULL; + + /* TODO: use connection->priv->auth to decode the message */ + + message = g_dbus_message_new_from_blob ((guchar *) worker->read_buffer, + worker->read_buffer_cur_size, + worker->capabilities, + &error); + if (message == NULL) + { + gchar *s; + s = _g_dbus_hexdump (worker->read_buffer, worker->read_buffer_cur_size, 2); + g_warning ("Error decoding D-Bus message of %" G_GSIZE_FORMAT " bytes\n" + "The error is: %s\n" + "The payload is as follows:\n" + "%s", + worker->read_buffer_cur_size, + error->message, + s); + g_free (s); + _g_dbus_worker_emit_disconnected (worker, FALSE, error); + g_error_free (error); + goto out; + } + +#ifdef G_OS_UNIX + if (worker->read_fd_list != NULL) + { + g_dbus_message_set_unix_fd_list (message, worker->read_fd_list); + g_object_unref (worker->read_fd_list); + worker->read_fd_list = NULL; + } +#endif + + if (G_UNLIKELY (_g_dbus_debug_message ())) + { + gchar *s; + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Message:\n" + " <<<< RECEIVED D-Bus message (%" G_GSIZE_FORMAT " bytes)\n", + worker->read_buffer_cur_size); + s = g_dbus_message_print (message, 2); + g_print ("%s", s); + g_free (s); + if (G_UNLIKELY (_g_dbus_debug_payload ())) + { + s = _g_dbus_hexdump (worker->read_buffer, worker->read_buffer_cur_size, 2); + g_print ("%s\n", s); + g_free (s); + } + _g_dbus_debug_print_unlock (); + } + + /* yay, got a message, go deliver it */ + _g_dbus_worker_queue_or_deliver_received_message (worker, g_steal_pointer (&message)); + + /* start reading another message! */ + worker->read_buffer_bytes_wanted = 0; + worker->read_buffer_cur_size = 0; + _g_dbus_worker_do_read_unlocked (worker); + } + } + else + { + /* didn't get all the bytes we requested - so repeat the request... */ + _g_dbus_worker_do_read_unlocked (worker); + } + + out: + g_mutex_unlock (&worker->read_lock); + + /* check if there is any pending close */ + schedule_pending_close (worker); + + /* gives up the reference acquired when calling g_input_stream_read_async() */ + _g_dbus_worker_unref (worker); +} + +/* called in private thread shared by all GDBusConnection instances (with read-lock held) */ +static void +_g_dbus_worker_do_read_unlocked (GDBusWorker *worker) +{ + /* Note that we do need to keep trying to read even if close_expected is + * true, because only failing a read causes us to signal 'closed'. + */ + + /* if bytes_wanted is zero, it means start reading a message */ + if (worker->read_buffer_bytes_wanted == 0) + { + worker->read_buffer_cur_size = 0; + worker->read_buffer_bytes_wanted = 16; + } + + /* ensure we have a (big enough) buffer */ + if (worker->read_buffer == NULL || worker->read_buffer_bytes_wanted > worker->read_buffer_allocated_size) + { + /* TODO: 4096 is randomly chosen; might want a better chosen default minimum */ + worker->read_buffer_allocated_size = MAX (worker->read_buffer_bytes_wanted, 4096); + worker->read_buffer = g_realloc (worker->read_buffer, worker->read_buffer_allocated_size); + } + + if (worker->socket == NULL) + g_input_stream_read_async (g_io_stream_get_input_stream (worker->stream), + worker->read_buffer + worker->read_buffer_cur_size, + worker->read_buffer_bytes_wanted - worker->read_buffer_cur_size, + G_PRIORITY_DEFAULT, + worker->cancellable, + (GAsyncReadyCallback) _g_dbus_worker_do_read_cb, + _g_dbus_worker_ref (worker)); + else + { + worker->read_ancillary_messages = NULL; + worker->read_num_ancillary_messages = 0; + _g_socket_read_with_control_messages (worker->socket, + worker->read_buffer + worker->read_buffer_cur_size, + worker->read_buffer_bytes_wanted - worker->read_buffer_cur_size, + &worker->read_ancillary_messages, + &worker->read_num_ancillary_messages, + G_PRIORITY_DEFAULT, + worker->cancellable, + (GAsyncReadyCallback) _g_dbus_worker_do_read_cb, + _g_dbus_worker_ref (worker)); + } +} + +/* called in private thread shared by all GDBusConnection instances (without read-lock held) */ +static gboolean +_g_dbus_worker_do_initial_read (gpointer data) +{ + GDBusWorker *worker = data; + g_mutex_lock (&worker->read_lock); + _g_dbus_worker_do_read_unlocked (worker); + g_mutex_unlock (&worker->read_lock); + return FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +struct _MessageToWriteData +{ + GDBusWorker *worker; + GDBusMessage *message; + gchar *blob; + gsize blob_size; + + gsize total_written; + GTask *task; +}; + +static void +message_to_write_data_free (MessageToWriteData *data) +{ + _g_dbus_worker_unref (data->worker); + if (data->message) + g_object_unref (data->message); + g_free (data->blob); + g_slice_free (MessageToWriteData, data); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void write_message_continue_writing (MessageToWriteData *data); + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending is PENDING_WRITE on entry + */ +static void +write_message_async_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + MessageToWriteData *data = user_data; + GTask *task; + gssize bytes_written; + GError *error; + + /* Note: we can't access data->task after calling g_task_return_* () because the + * callback can free @data and we're not completing in idle. So use a copy of the pointer. + */ + task = data->task; + + error = NULL; + bytes_written = g_output_stream_write_finish (G_OUTPUT_STREAM (source_object), + res, + &error); + if (bytes_written == -1) + { + g_task_return_error (task, error); + g_object_unref (task); + goto out; + } + g_assert (bytes_written > 0); /* zero is never returned */ + + write_message_print_transport_debug (bytes_written, data); + + data->total_written += bytes_written; + g_assert (data->total_written <= data->blob_size); + if (data->total_written == data->blob_size) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + goto out; + } + + write_message_continue_writing (data); + + out: + ; +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending is PENDING_WRITE on entry + */ +#ifdef G_OS_UNIX +static gboolean +on_socket_ready (GSocket *socket, + GIOCondition condition, + gpointer user_data) +{ + MessageToWriteData *data = user_data; + write_message_continue_writing (data); + return FALSE; /* remove source */ +} +#endif + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending is PENDING_WRITE on entry + */ +static void +write_message_continue_writing (MessageToWriteData *data) +{ + GOutputStream *ostream; +#ifdef G_OS_UNIX + GTask *task; + GUnixFDList *fd_list; +#endif + +#ifdef G_OS_UNIX + /* Note: we can't access data->task after calling g_task_return_* () because the + * callback can free @data and we're not completing in idle. So use a copy of the pointer. + */ + task = data->task; +#endif + + ostream = g_io_stream_get_output_stream (data->worker->stream); +#ifdef G_OS_UNIX + fd_list = g_dbus_message_get_unix_fd_list (data->message); +#endif + + g_assert (!g_output_stream_has_pending (ostream)); + g_assert_cmpint (data->total_written, <, data->blob_size); + + if (FALSE) + { + } +#ifdef G_OS_UNIX + else if (G_IS_SOCKET_OUTPUT_STREAM (ostream) && data->total_written == 0) + { + GOutputVector vector; + GSocketControlMessage *control_message; + gssize bytes_written; + GError *error; + + vector.buffer = data->blob; + vector.size = data->blob_size; + + control_message = NULL; + if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0) + { + if (!(data->worker->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)) + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Tried sending a file descriptor but remote peer does not support this capability"); + g_object_unref (task); + goto out; + } + control_message = g_unix_fd_message_new_with_fd_list (fd_list); + } + + error = NULL; + bytes_written = g_socket_send_message (data->worker->socket, + NULL, /* address */ + &vector, + 1, + control_message != NULL ? &control_message : NULL, + control_message != NULL ? 1 : 0, + G_SOCKET_MSG_NONE, + data->worker->cancellable, + &error); + if (control_message != NULL) + g_object_unref (control_message); + + if (bytes_written == -1) + { + /* Handle WOULD_BLOCK by waiting until there's room in the buffer */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) + { + GSource *source; + source = g_socket_create_source (data->worker->socket, + G_IO_OUT | G_IO_HUP | G_IO_ERR, + data->worker->cancellable); + g_source_set_callback (source, + (GSourceFunc) on_socket_ready, + data, + NULL); /* GDestroyNotify */ + g_source_attach (source, g_main_context_get_thread_default ()); + g_source_unref (source); + g_error_free (error); + goto out; + } + g_task_return_error (task, error); + g_object_unref (task); + goto out; + } + g_assert (bytes_written > 0); /* zero is never returned */ + + write_message_print_transport_debug (bytes_written, data); + + data->total_written += bytes_written; + g_assert (data->total_written <= data->blob_size); + if (data->total_written == data->blob_size) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + goto out; + } + + write_message_continue_writing (data); + } +#endif + else + { +#ifdef G_OS_UNIX + if (data->total_written == 0 && fd_list != NULL) + { + /* We were trying to write byte 0 of the message, which needs + * the fd list to be attached to it, but this connection doesn't + * support doing that. */ + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Tried sending a file descriptor on unsupported stream of type %s", + g_type_name (G_TYPE_FROM_INSTANCE (ostream))); + g_object_unref (task); + goto out; + } +#endif + + g_output_stream_write_async (ostream, + (const gchar *) data->blob + data->total_written, + data->blob_size - data->total_written, + G_PRIORITY_DEFAULT, + data->worker->cancellable, + write_message_async_cb, + data); + } +#ifdef G_OS_UNIX + out: +#endif + ; +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending is PENDING_WRITE on entry + */ +static void +write_message_async (GDBusWorker *worker, + MessageToWriteData *data, + GAsyncReadyCallback callback, + gpointer user_data) +{ + data->task = g_task_new (NULL, NULL, callback, user_data); + g_task_set_source_tag (data->task, write_message_async); + g_task_set_name (data->task, "[gio] D-Bus write message"); + data->total_written = 0; + write_message_continue_writing (data); +} + +/* called in private thread shared by all GDBusConnection instances (with write-lock held) */ +static gboolean +write_message_finish (GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, NULL), FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} +/* ---------------------------------------------------------------------------------------------------- */ + +static void continue_writing (GDBusWorker *worker); + +typedef struct +{ + GDBusWorker *worker; + GList *flushers; +} FlushAsyncData; + +static void +flush_data_list_complete (const GList *flushers, + const GError *error) +{ + const GList *l; + + for (l = flushers; l != NULL; l = l->next) + { + FlushData *f = l->data; + + f->error = error != NULL ? g_error_copy (error) : NULL; + + g_mutex_lock (&f->mutex); + f->finished = TRUE; + g_cond_signal (&f->cond); + g_mutex_unlock (&f->mutex); + } +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending is PENDING_FLUSH on entry + */ +static void +ostream_flush_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + FlushAsyncData *data = user_data; + GError *error; + + error = NULL; + g_output_stream_flush_finish (G_OUTPUT_STREAM (source_object), + res, + &error); + + if (error == NULL) + { + if (G_UNLIKELY (_g_dbus_debug_transport ())) + { + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Transport:\n" + " ---- FLUSHED stream of type %s\n", + g_type_name (G_TYPE_FROM_INSTANCE (g_io_stream_get_output_stream (data->worker->stream)))); + _g_dbus_debug_print_unlock (); + } + } + + /* Make sure we tell folks that we don't have additional + flushes pending */ + g_mutex_lock (&data->worker->write_lock); + data->worker->write_num_messages_flushed = data->worker->write_num_messages_written; + g_assert (data->worker->output_pending == PENDING_FLUSH); + data->worker->output_pending = PENDING_NONE; + g_mutex_unlock (&data->worker->write_lock); + + g_assert (data->flushers != NULL); + flush_data_list_complete (data->flushers, error); + g_list_free (data->flushers); + if (error != NULL) + g_error_free (error); + + /* OK, cool, finally kick off the next write */ + continue_writing (data->worker); + + _g_dbus_worker_unref (data->worker); + g_free (data); +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending is PENDING_FLUSH on entry + */ +static void +start_flush (FlushAsyncData *data) +{ + g_output_stream_flush_async (g_io_stream_get_output_stream (data->worker->stream), + G_PRIORITY_DEFAULT, + data->worker->cancellable, + ostream_flush_cb, + data); +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is held on entry + * output_pending is PENDING_NONE on entry + */ +static void +message_written_unlocked (GDBusWorker *worker, + MessageToWriteData *message_data) +{ + if (G_UNLIKELY (_g_dbus_debug_message ())) + { + gchar *s; + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Message:\n" + " >>>> SENT D-Bus message (%" G_GSIZE_FORMAT " bytes)\n", + message_data->blob_size); + s = g_dbus_message_print (message_data->message, 2); + g_print ("%s", s); + g_free (s); + if (G_UNLIKELY (_g_dbus_debug_payload ())) + { + s = _g_dbus_hexdump (message_data->blob, message_data->blob_size, 2); + g_print ("%s\n", s); + g_free (s); + } + _g_dbus_debug_print_unlock (); + } + + worker->write_num_messages_written += 1; +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is held on entry + * output_pending is PENDING_NONE on entry + * + * Returns: non-%NULL, setting @output_pending, if we need to flush now + */ +static FlushAsyncData * +prepare_flush_unlocked (GDBusWorker *worker) +{ + GList *l; + GList *ll; + GList *flushers; + + flushers = NULL; + for (l = worker->write_pending_flushes; l != NULL; l = ll) + { + FlushData *f = l->data; + ll = l->next; + + if (f->number_to_wait_for == worker->write_num_messages_written) + { + flushers = g_list_append (flushers, f); + worker->write_pending_flushes = g_list_delete_link (worker->write_pending_flushes, l); + } + } + if (flushers != NULL) + { + g_assert (worker->output_pending == PENDING_NONE); + worker->output_pending = PENDING_FLUSH; + } + + if (flushers != NULL) + { + FlushAsyncData *data; + + data = g_new0 (FlushAsyncData, 1); + data->worker = _g_dbus_worker_ref (worker); + data->flushers = flushers; + return data; + } + + return NULL; +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending is PENDING_WRITE on entry + */ +static void +write_message_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + MessageToWriteData *data = user_data; + GError *error; + + g_mutex_lock (&data->worker->write_lock); + g_assert (data->worker->output_pending == PENDING_WRITE); + data->worker->output_pending = PENDING_NONE; + + error = NULL; + if (!write_message_finish (res, &error)) + { + g_mutex_unlock (&data->worker->write_lock); + + /* TODO: handle */ + _g_dbus_worker_emit_disconnected (data->worker, TRUE, error); + g_error_free (error); + + g_mutex_lock (&data->worker->write_lock); + } + + message_written_unlocked (data->worker, data); + + g_mutex_unlock (&data->worker->write_lock); + + continue_writing (data->worker); + + message_to_write_data_free (data); +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending is PENDING_CLOSE on entry + */ +static void +iostream_close_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GDBusWorker *worker = user_data; + GError *error = NULL; + GList *pending_close_attempts, *pending_flush_attempts; + GQueue *send_queue; + + g_io_stream_close_finish (worker->stream, res, &error); + + g_mutex_lock (&worker->write_lock); + + pending_close_attempts = worker->pending_close_attempts; + worker->pending_close_attempts = NULL; + + pending_flush_attempts = worker->write_pending_flushes; + worker->write_pending_flushes = NULL; + + send_queue = worker->write_queue; + worker->write_queue = g_queue_new (); + + g_assert (worker->output_pending == PENDING_CLOSE); + worker->output_pending = PENDING_NONE; + + /* Ensure threads waiting for pending flushes to finish will be unblocked. */ + worker->write_num_messages_flushed = + worker->write_num_messages_written + g_list_length(pending_flush_attempts); + + g_mutex_unlock (&worker->write_lock); + + while (pending_close_attempts != NULL) + { + CloseData *close_data = pending_close_attempts->data; + + pending_close_attempts = g_list_delete_link (pending_close_attempts, + pending_close_attempts); + + if (close_data->task != NULL) + { + if (error != NULL) + g_task_return_error (close_data->task, g_error_copy (error)); + else + g_task_return_boolean (close_data->task, TRUE); + } + + close_data_free (close_data); + } + + g_clear_error (&error); + + /* all messages queued for sending are discarded */ + g_queue_free_full (send_queue, (GDestroyNotify) message_to_write_data_free); + /* all queued flushes fail */ + error = g_error_new (G_IO_ERROR, G_IO_ERROR_CANCELLED, + _("Operation was cancelled")); + flush_data_list_complete (pending_flush_attempts, error); + g_list_free (pending_flush_attempts); + g_clear_error (&error); + + _g_dbus_worker_unref (worker); +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending must be PENDING_NONE on entry + */ +static void +continue_writing (GDBusWorker *worker) +{ + MessageToWriteData *data; + FlushAsyncData *flush_async_data; + + write_next: + /* we mustn't try to write two things at once */ + g_assert (worker->output_pending == PENDING_NONE); + + g_mutex_lock (&worker->write_lock); + + data = NULL; + flush_async_data = NULL; + + /* if we want to close the connection, that takes precedence */ + if (worker->pending_close_attempts != NULL) + { + GInputStream *input = g_io_stream_get_input_stream (worker->stream); + + if (!g_input_stream_has_pending (input)) + { + worker->close_expected = TRUE; + worker->output_pending = PENDING_CLOSE; + + g_io_stream_close_async (worker->stream, G_PRIORITY_DEFAULT, + NULL, iostream_close_cb, + _g_dbus_worker_ref (worker)); + } + } + else + { + flush_async_data = prepare_flush_unlocked (worker); + + if (flush_async_data == NULL) + { + data = g_queue_pop_head (worker->write_queue); + + if (data != NULL) + worker->output_pending = PENDING_WRITE; + } + } + + g_mutex_unlock (&worker->write_lock); + + /* Note that write_lock is only used for protecting the @write_queue + * and @output_pending fields of the GDBusWorker struct ... which we + * need to modify from arbitrary threads in _g_dbus_worker_send_message(). + * + * Therefore, it's fine to drop it here when calling back into user + * code and then writing the message out onto the GIOStream since this + * function only runs on the worker thread. + */ + + if (flush_async_data != NULL) + { + start_flush (flush_async_data); + g_assert (data == NULL); + } + else if (data != NULL) + { + GDBusMessage *old_message; + guchar *new_blob; + gsize new_blob_size; + GError *error; + + old_message = data->message; + data->message = _g_dbus_worker_emit_message_about_to_be_sent (worker, data->message); + if (data->message == old_message) + { + /* filters had no effect - do nothing */ + } + else if (data->message == NULL) + { + /* filters dropped message */ + g_mutex_lock (&worker->write_lock); + worker->output_pending = PENDING_NONE; + g_mutex_unlock (&worker->write_lock); + message_to_write_data_free (data); + goto write_next; + } + else + { + /* filters altered the message -> re-encode */ + error = NULL; + new_blob = g_dbus_message_to_blob (data->message, + &new_blob_size, + worker->capabilities, + &error); + if (new_blob == NULL) + { + /* if filter make the GDBusMessage unencodeable, just complain on stderr and send + * the old message instead + */ + g_warning ("Error encoding GDBusMessage with serial %d altered by filter function: %s", + g_dbus_message_get_serial (data->message), + error->message); + g_error_free (error); + } + else + { + g_free (data->blob); + data->blob = (gchar *) new_blob; + data->blob_size = new_blob_size; + } + } + + write_message_async (worker, + data, + write_message_cb, + data); + } +} + +/* called in private thread shared by all GDBusConnection instances + * + * write-lock is not held on entry + * output_pending may be anything + */ +static gboolean +continue_writing_in_idle_cb (gpointer user_data) +{ + GDBusWorker *worker = user_data; + + /* Because this is the worker thread, we can read this struct member + * without holding the lock: no other thread ever modifies it. + */ + if (worker->output_pending == PENDING_NONE) + continue_writing (worker); + + return FALSE; +} + +/* + * @write_data: (transfer full) (nullable): + * @flush_data: (transfer full) (nullable): + * @close_data: (transfer full) (nullable): + * + * Can be called from any thread + * + * write_lock is held on entry + * output_pending may be anything + */ +static void +schedule_writing_unlocked (GDBusWorker *worker, + MessageToWriteData *write_data, + FlushData *flush_data, + CloseData *close_data) +{ + if (write_data != NULL) + g_queue_push_tail (worker->write_queue, write_data); + + if (flush_data != NULL) + worker->write_pending_flushes = g_list_prepend (worker->write_pending_flushes, flush_data); + + if (close_data != NULL) + worker->pending_close_attempts = g_list_prepend (worker->pending_close_attempts, + close_data); + + /* If we had output pending, the next bit of output will happen + * automatically when it finishes, so we only need to do this + * if nothing was pending. + * + * The idle callback will re-check that output_pending is still + * PENDING_NONE, to guard against output starting before the idle. + */ + if (worker->output_pending == PENDING_NONE) + { + GSource *idle_source; + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + continue_writing_in_idle_cb, + _g_dbus_worker_ref (worker), + (GDestroyNotify) _g_dbus_worker_unref); + g_source_set_static_name (idle_source, "[gio] continue_writing_in_idle_cb"); + g_source_attach (idle_source, worker->shared_thread_data->context); + g_source_unref (idle_source); + } +} + +static void +schedule_pending_close (GDBusWorker *worker) +{ + g_mutex_lock (&worker->write_lock); + if (worker->pending_close_attempts) + schedule_writing_unlocked (worker, NULL, NULL, NULL); + g_mutex_unlock (&worker->write_lock); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* can be called from any thread - steals blob + * + * write_lock is not held on entry + * output_pending may be anything + */ +void +_g_dbus_worker_send_message (GDBusWorker *worker, + GDBusMessage *message, + gchar *blob, + gsize blob_len) +{ + MessageToWriteData *data; + + g_return_if_fail (G_IS_DBUS_MESSAGE (message)); + g_return_if_fail (blob != NULL); + g_return_if_fail (blob_len > 16); + + data = g_slice_new0 (MessageToWriteData); + data->worker = _g_dbus_worker_ref (worker); + data->message = g_object_ref (message); + data->blob = blob; /* steal! */ + data->blob_size = blob_len; + + g_mutex_lock (&worker->write_lock); + schedule_writing_unlocked (worker, data, NULL, NULL); + g_mutex_unlock (&worker->write_lock); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +GDBusWorker * +_g_dbus_worker_new (GIOStream *stream, + GDBusCapabilityFlags capabilities, + gboolean initially_frozen, + GDBusWorkerMessageReceivedCallback message_received_callback, + GDBusWorkerMessageAboutToBeSentCallback message_about_to_be_sent_callback, + GDBusWorkerDisconnectedCallback disconnected_callback, + gpointer user_data) +{ + GDBusWorker *worker; + GSource *idle_source; + + g_return_val_if_fail (G_IS_IO_STREAM (stream), NULL); + g_return_val_if_fail (message_received_callback != NULL, NULL); + g_return_val_if_fail (message_about_to_be_sent_callback != NULL, NULL); + g_return_val_if_fail (disconnected_callback != NULL, NULL); + + worker = g_new0 (GDBusWorker, 1); + worker->ref_count = 1; + + g_mutex_init (&worker->read_lock); + worker->message_received_callback = message_received_callback; + worker->message_about_to_be_sent_callback = message_about_to_be_sent_callback; + worker->disconnected_callback = disconnected_callback; + worker->user_data = user_data; + worker->stream = g_object_ref (stream); + worker->capabilities = capabilities; + worker->cancellable = g_cancellable_new (); + worker->output_pending = PENDING_NONE; + + worker->frozen = initially_frozen; + worker->received_messages_while_frozen = g_queue_new (); + + g_mutex_init (&worker->write_lock); + worker->write_queue = g_queue_new (); + + if (G_IS_SOCKET_CONNECTION (worker->stream)) + worker->socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (worker->stream)); + + worker->shared_thread_data = _g_dbus_shared_thread_ref (); + + /* begin reading */ + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + _g_dbus_worker_do_initial_read, + _g_dbus_worker_ref (worker), + (GDestroyNotify) _g_dbus_worker_unref); + g_source_set_static_name (idle_source, "[gio] _g_dbus_worker_do_initial_read"); + g_source_attach (idle_source, worker->shared_thread_data->context); + g_source_unref (idle_source); + + return worker; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* can be called from any thread + * + * write_lock is not held on entry + * output_pending may be anything + */ +void +_g_dbus_worker_close (GDBusWorker *worker, + GTask *task) +{ + CloseData *close_data; + + close_data = g_slice_new0 (CloseData); + close_data->worker = _g_dbus_worker_ref (worker); + close_data->task = (task == NULL ? NULL : g_object_ref (task)); + + /* Don't set worker->close_expected here - we're in the wrong thread. + * It'll be set before the actual close happens. + */ + g_cancellable_cancel (worker->cancellable); + g_mutex_lock (&worker->write_lock); + schedule_writing_unlocked (worker, NULL, NULL, close_data); + g_mutex_unlock (&worker->write_lock); +} + +/* This can be called from any thread - frees worker. Note that + * callbacks might still happen if called from another thread than the + * worker - use your own synchronization primitive in the callbacks. + * + * write_lock is not held on entry + * output_pending may be anything + */ +void +_g_dbus_worker_stop (GDBusWorker *worker) +{ + g_atomic_int_set (&worker->stopped, TRUE); + + /* Cancel any pending operations and schedule a close of the underlying I/O + * stream in the worker thread + */ + _g_dbus_worker_close (worker, NULL); + + /* _g_dbus_worker_close holds a ref until after an idle in the worker + * thread has run, so we no longer need to unref in an idle like in + * commit 322e25b535 + */ + _g_dbus_worker_unref (worker); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* can be called from any thread (except the worker thread) - blocks + * calling thread until all queued outgoing messages are written and + * the transport has been flushed + * + * write_lock is not held on entry + * output_pending may be anything + */ +gboolean +_g_dbus_worker_flush_sync (GDBusWorker *worker, + GCancellable *cancellable, + GError **error) +{ + gboolean ret; + FlushData *data; + guint64 pending_writes; + + data = NULL; + ret = TRUE; + + g_mutex_lock (&worker->write_lock); + + /* if the queue is empty, no write is in-flight and we haven't written + * anything since the last flush, then there's nothing to wait for + */ + pending_writes = g_queue_get_length (worker->write_queue); + + /* if a write is in-flight, we shouldn't be satisfied until the first + * flush operation that follows it + */ + if (worker->output_pending == PENDING_WRITE) + pending_writes += 1; + + if (pending_writes > 0 || + worker->write_num_messages_written != worker->write_num_messages_flushed) + { + data = g_new0 (FlushData, 1); + g_mutex_init (&data->mutex); + g_cond_init (&data->cond); + data->number_to_wait_for = worker->write_num_messages_written + pending_writes; + data->finished = FALSE; + g_mutex_lock (&data->mutex); + + schedule_writing_unlocked (worker, NULL, data, NULL); + } + g_mutex_unlock (&worker->write_lock); + + if (data != NULL) + { + /* Wait for flush operations to finish. */ + while (!data->finished) + { + g_cond_wait (&data->cond, &data->mutex); + } + + g_mutex_unlock (&data->mutex); + g_cond_clear (&data->cond); + g_mutex_clear (&data->mutex); + if (data->error != NULL) + { + ret = FALSE; + g_propagate_error (error, data->error); + } + g_free (data); + } + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#define G_DBUS_DEBUG_AUTHENTICATION (1<<0) +#define G_DBUS_DEBUG_TRANSPORT (1<<1) +#define G_DBUS_DEBUG_MESSAGE (1<<2) +#define G_DBUS_DEBUG_PAYLOAD (1<<3) +#define G_DBUS_DEBUG_CALL (1<<4) +#define G_DBUS_DEBUG_SIGNAL (1<<5) +#define G_DBUS_DEBUG_INCOMING (1<<6) +#define G_DBUS_DEBUG_RETURN (1<<7) +#define G_DBUS_DEBUG_EMISSION (1<<8) +#define G_DBUS_DEBUG_ADDRESS (1<<9) +#define G_DBUS_DEBUG_PROXY (1<<10) + +static gint _gdbus_debug_flags = 0; + +gboolean +_g_dbus_debug_authentication (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_AUTHENTICATION) != 0; +} + +gboolean +_g_dbus_debug_transport (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_TRANSPORT) != 0; +} + +gboolean +_g_dbus_debug_message (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_MESSAGE) != 0; +} + +gboolean +_g_dbus_debug_payload (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_PAYLOAD) != 0; +} + +gboolean +_g_dbus_debug_call (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_CALL) != 0; +} + +gboolean +_g_dbus_debug_signal (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_SIGNAL) != 0; +} + +gboolean +_g_dbus_debug_incoming (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_INCOMING) != 0; +} + +gboolean +_g_dbus_debug_return (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_RETURN) != 0; +} + +gboolean +_g_dbus_debug_emission (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_EMISSION) != 0; +} + +gboolean +_g_dbus_debug_address (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_ADDRESS) != 0; +} + +gboolean +_g_dbus_debug_proxy (void) +{ + _g_dbus_initialize (); + return (_gdbus_debug_flags & G_DBUS_DEBUG_PROXY) != 0; +} + +G_LOCK_DEFINE_STATIC (print_lock); + +void +_g_dbus_debug_print_lock (void) +{ + G_LOCK (print_lock); +} + +void +_g_dbus_debug_print_unlock (void) +{ + G_UNLOCK (print_lock); +} + +/** + * _g_dbus_initialize: + * + * Does various one-time init things such as + * + * - registering the G_DBUS_ERROR error domain + * - parses the G_DBUS_DEBUG environment variable + */ +void +_g_dbus_initialize (void) +{ + static gsize initialized = 0; + + if (g_once_init_enter (&initialized)) + { + const gchar *debug; + + /* Ensure the domain is registered. */ + g_dbus_error_quark (); + + debug = g_getenv ("G_DBUS_DEBUG"); + if (debug != NULL) + { + const GDebugKey keys[] = { + { "authentication", G_DBUS_DEBUG_AUTHENTICATION }, + { "transport", G_DBUS_DEBUG_TRANSPORT }, + { "message", G_DBUS_DEBUG_MESSAGE }, + { "payload", G_DBUS_DEBUG_PAYLOAD }, + { "call", G_DBUS_DEBUG_CALL }, + { "signal", G_DBUS_DEBUG_SIGNAL }, + { "incoming", G_DBUS_DEBUG_INCOMING }, + { "return", G_DBUS_DEBUG_RETURN }, + { "emission", G_DBUS_DEBUG_EMISSION }, + { "address", G_DBUS_DEBUG_ADDRESS }, + { "proxy", G_DBUS_DEBUG_PROXY } + }; + + _gdbus_debug_flags = g_parse_debug_string (debug, keys, G_N_ELEMENTS (keys)); + if (_gdbus_debug_flags & G_DBUS_DEBUG_PAYLOAD) + _gdbus_debug_flags |= G_DBUS_DEBUG_MESSAGE; + } + + /* Work-around for https://bugzilla.gnome.org/show_bug.cgi?id=627724 */ + ensure_required_types (); + + g_once_init_leave (&initialized, 1); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +GVariantType * +_g_dbus_compute_complete_signature (GDBusArgInfo **args) +{ + const GVariantType *arg_types[256]; + guint n; + + if (args) + for (n = 0; args[n] != NULL; n++) + { + /* DBus places a hard limit of 255 on signature length. + * therefore number of args must be less than 256. + */ + g_assert (n < 256); + + arg_types[n] = G_VARIANT_TYPE (args[n]->signature); + + if G_UNLIKELY (arg_types[n] == NULL) + return NULL; + } + else + n = 0; + + return g_variant_type_new_tuple (arg_types, n); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_WIN32 + +#define DBUS_DAEMON_ADDRESS_INFO "DBusDaemonAddressInfo" +#define DBUS_DAEMON_MUTEX "DBusDaemonMutex" +#define UNIQUE_DBUS_INIT_MUTEX "UniqueDBusInitMutex" +#define DBUS_AUTOLAUNCH_MUTEX "DBusAutolaunchMutex" + +static void +release_mutex (HANDLE mutex) +{ + ReleaseMutex (mutex); + CloseHandle (mutex); +} + +static HANDLE +acquire_mutex (const char *mutexname) +{ + HANDLE mutex; + DWORD res; + + mutex = CreateMutexA (NULL, FALSE, mutexname); + if (!mutex) + return 0; + + res = WaitForSingleObject (mutex, INFINITE); + switch (res) + { + case WAIT_ABANDONED: + release_mutex (mutex); + return 0; + case WAIT_FAILED: + case WAIT_TIMEOUT: + return 0; + } + + return mutex; +} + +static gboolean +is_mutex_owned (const char *mutexname) +{ + HANDLE mutex; + gboolean res = FALSE; + + mutex = CreateMutexA (NULL, FALSE, mutexname); + if (WaitForSingleObject (mutex, 10) == WAIT_TIMEOUT) + res = TRUE; + else + ReleaseMutex (mutex); + CloseHandle (mutex); + + return res; +} + +static char * +read_shm (const char *shm_name) +{ + HANDLE shared_mem; + char *shared_data; + char *res; + int i; + + res = NULL; + + for (i = 0; i < 20; i++) + { + shared_mem = OpenFileMappingA (FILE_MAP_READ, FALSE, shm_name); + if (shared_mem != 0) + break; + Sleep (100); + } + + if (shared_mem != 0) + { + shared_data = MapViewOfFile (shared_mem, FILE_MAP_READ, 0, 0, 0); + /* It looks that a race is possible here: + * if the dbus process already created mapping but didn't fill it + * the code below may read incorrect address. + * Also this is a bit complicated by the fact that + * any change in the "synchronization contract" between processes + * should be accompanied with renaming all of used win32 named objects: + * otherwise libgio-2.0-0.dll of different versions shipped with + * different apps may break each other due to protocol difference. + */ + if (shared_data != NULL) + { + res = g_strdup (shared_data); + UnmapViewOfFile (shared_data); + } + CloseHandle (shared_mem); + } + + return res; +} + +static HANDLE +set_shm (const char *shm_name, const char *value) +{ + HANDLE shared_mem; + char *shared_data; + + shared_mem = CreateFileMappingA (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, strlen (value) + 1, shm_name); + if (shared_mem == 0) + return 0; + + shared_data = MapViewOfFile (shared_mem, FILE_MAP_WRITE, 0, 0, 0 ); + if (shared_data == NULL) + return 0; + + strcpy (shared_data, value); + + UnmapViewOfFile (shared_data); + + return shared_mem; +} + +/* These keep state between publish_session_bus and unpublish_session_bus */ +static HANDLE published_daemon_mutex; +static HANDLE published_shared_mem; + +static gboolean +publish_session_bus (const char *address) +{ + HANDLE init_mutex; + + init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); + + published_daemon_mutex = CreateMutexA (NULL, FALSE, DBUS_DAEMON_MUTEX); + if (WaitForSingleObject (published_daemon_mutex, 10 ) != WAIT_OBJECT_0) + { + release_mutex (init_mutex); + CloseHandle (published_daemon_mutex); + published_daemon_mutex = NULL; + return FALSE; + } + + published_shared_mem = set_shm (DBUS_DAEMON_ADDRESS_INFO, address); + if (!published_shared_mem) + { + release_mutex (init_mutex); + CloseHandle (published_daemon_mutex); + published_daemon_mutex = NULL; + return FALSE; + } + + release_mutex (init_mutex); + return TRUE; +} + +static void +unpublish_session_bus (void) +{ + HANDLE init_mutex; + + init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); + + CloseHandle (published_shared_mem); + published_shared_mem = NULL; + + release_mutex (published_daemon_mutex); + published_daemon_mutex = NULL; + + release_mutex (init_mutex); +} + +static void +wait_console_window (void) +{ + FILE *console = fopen ("CONOUT$", "w"); + + SetConsoleTitleW (L"gdbus-daemon output. Type any character to close this window."); + fprintf (console, _("(Type any character to close this window)\n")); + fflush (console); + _getch (); +} + +static void +open_console_window (void) +{ + if (((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE || + (HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) && AllocConsole ()) + { + if ((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE) + freopen ("CONOUT$", "w", stdout); + + if ((HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) + freopen ("CONOUT$", "w", stderr); + + SetConsoleTitleW (L"gdbus-daemon debug output."); + + atexit (wait_console_window); + } +} + +static void +idle_timeout_cb (GDBusDaemon *daemon, gpointer user_data) +{ + GMainLoop *loop = user_data; + g_main_loop_quit (loop); +} + +/* Satisfies STARTF_FORCEONFEEDBACK */ +static void +turn_off_the_starting_cursor (void) +{ + MSG msg; + BOOL bRet; + + PostQuitMessage (0); + + while ((bRet = GetMessage (&msg, 0, 0, 0)) != 0) + { + if (bRet == -1) + continue; + + TranslateMessage (&msg); + DispatchMessage (&msg); + } +} + +void __stdcall +g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdshow) +{ + GDBusDaemon *daemon; + GMainLoop *loop; + const char *address; + GError *error = NULL; + + turn_off_the_starting_cursor (); + + if (g_getenv ("GDBUS_DAEMON_DEBUG") != NULL) + open_console_window (); + + address = "nonce-tcp:"; + daemon = _g_dbus_daemon_new (address, NULL, &error); + if (daemon == NULL) + { + g_printerr ("Can't init bus: %s\n", error->message); + g_error_free (error); + return; + } + + loop = g_main_loop_new (NULL, FALSE); + + /* There is a subtle detail with "idle-timeout" signal of dbus daemon: + * It is fired on idle after last client disconnection, + * but (at least with glib 2.59.1) it is NEVER fired + * if no clients connect to daemon at all. + * This may lead to infinite run of this daemon process. + */ + g_signal_connect (daemon, "idle-timeout", G_CALLBACK (idle_timeout_cb), loop); + + if (publish_session_bus (_g_dbus_daemon_get_address (daemon))) + { + g_main_loop_run (loop); + + unpublish_session_bus (); + } + + g_main_loop_unref (loop); + g_object_unref (daemon); +} + +static gboolean autolaunch_binary_absent = FALSE; + +static wchar_t * +find_dbus_process_path (void) +{ + wchar_t *dbus_path; + gchar *exe_path = GLIB_PRIVATE_CALL (g_win32_find_helper_executable_path) ("gdbus.exe", _g_io_win32_get_module ()); + dbus_path = g_utf8_to_utf16 (exe_path, -1, NULL, NULL, NULL); + g_free (exe_path); + + if (dbus_path == NULL) + return NULL; + + if (GetFileAttributesW (dbus_path) == INVALID_FILE_ATTRIBUTES) + { + g_free (dbus_path); + return NULL; + } + + return dbus_path; +} + +gchar * +_g_dbus_win32_get_session_address_dbus_launch (GError **error) +{ + HANDLE autolaunch_mutex, init_mutex; + char *address = NULL; + + autolaunch_mutex = acquire_mutex (DBUS_AUTOLAUNCH_MUTEX); + + init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); + + if (is_mutex_owned (DBUS_DAEMON_MUTEX)) + address = read_shm (DBUS_DAEMON_ADDRESS_INFO); + + release_mutex (init_mutex); + + if (address == NULL && !autolaunch_binary_absent) + { + wchar_t *dbus_path = find_dbus_process_path (); + if (dbus_path == NULL) + { + /* warning won't be raised another time + * since autolaunch_binary_absent would be already set. + */ + autolaunch_binary_absent = TRUE; + g_warning ("win32 session dbus binary not found"); + } + else + { + PROCESS_INFORMATION pi = { 0 }; + STARTUPINFOW si = { 0 }; + BOOL res = FALSE; + wchar_t args[MAX_PATH * 2 + 100] = { 0 }; + wchar_t working_dir[MAX_PATH + 2] = { 0 }; + wchar_t *p; + + wcscpy (working_dir, dbus_path); + p = wcsrchr (working_dir, L'\\'); + if (p != NULL) + *p = L'\0'; + + wcscpy (args, L"\""); + wcscat (args, dbus_path); + wcscat (args, L"\" "); +#define _L_PREFIX_FOR_EXPANDED(arg) L##arg +#define _L_PREFIX(arg) _L_PREFIX_FOR_EXPANDED (arg) + wcscat (args, _L_PREFIX (_GDBUS_ARG_WIN32_RUN_SESSION_BUS)); +#undef _L_PREFIX +#undef _L_PREFIX_FOR_EXPANDED + + res = CreateProcessW (dbus_path, args, + 0, 0, FALSE, + NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | DETACHED_PROCESS, + 0, working_dir, + &si, &pi); + + if (res) + { + address = read_shm (DBUS_DAEMON_ADDRESS_INFO); + if (address == NULL) + g_warning ("%S dbus binary failed to launch bus, maybe incompatible version", dbus_path); + } + + g_free (dbus_path); + } + } + + release_mutex (autolaunch_mutex); + + if (address == NULL) + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Session dbus not running, and autolaunch failed")); + + return address; +} + +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +gchar * +_g_dbus_get_machine_id (GError **error) +{ +#ifdef G_OS_WIN32 + HW_PROFILE_INFOA info; + char *src, *dest, *res; + int i; + + if (!GetCurrentHwProfileA (&info)) + { + char *message = g_win32_error_message (GetLastError ()); + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to get Hardware profile: %s"), message); + g_free (message); + return NULL; + } + + /* Form: {12340001-4980-1920-6788-123456789012} */ + src = &info.szHwProfileGuid[0]; + + res = g_malloc (32+1); + dest = res; + + src++; /* Skip { */ + for (i = 0; i < 8; i++) + *dest++ = *src++; + src++; /* Skip - */ + for (i = 0; i < 4; i++) + *dest++ = *src++; + src++; /* Skip - */ + for (i = 0; i < 4; i++) + *dest++ = *src++; + src++; /* Skip - */ + for (i = 0; i < 4; i++) + *dest++ = *src++; + src++; /* Skip - */ + for (i = 0; i < 12; i++) + *dest++ = *src++; + *dest = 0; + + return res; +#else + gchar *ret = NULL; + GError *first_error = NULL; + gsize i; + gboolean non_zero = FALSE; + + /* Copy what dbus.git does: allow the /var/lib path to be configurable at + * build time, but hard-code the system-wide machine ID path in /etc. */ + const gchar *var_lib_path = LOCALSTATEDIR "/lib/dbus/machine-id"; + const gchar *etc_path = "/etc/machine-id"; + + if (!g_file_get_contents (var_lib_path, + &ret, + NULL, + &first_error) && + !g_file_get_contents (etc_path, + &ret, + NULL, + NULL)) + { + g_propagate_prefixed_error (error, g_steal_pointer (&first_error), + /* Translators: Both placeholders are file paths */ + _("Unable to load %s or %s: "), + var_lib_path, etc_path); + return NULL; + } + + /* ignore the error from the first try, if any */ + g_clear_error (&first_error); + + /* Validate the machine ID. From `man 5 machine-id`: + * > The machine ID is a single newline-terminated, hexadecimal, 32-character, + * > lowercase ID. When decoded from hexadecimal, this corresponds to a + * > 16-byte/128-bit value. This ID may not be all zeros. + */ + for (i = 0; ret[i] != '\0' && ret[i] != '\n'; i++) + { + /* Break early if it’s invalid. */ + if (!g_ascii_isxdigit (ret[i]) || g_ascii_isupper (ret[i])) + break; + + if (ret[i] != '0') + non_zero = TRUE; + } + + if (i != 32 || ret[i] != '\n' || ret[i + 1] != '\0' || !non_zero) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid machine ID in %s or %s", + var_lib_path, etc_path); + g_free (ret); + return NULL; + } + + /* Strip trailing newline. */ + ret[32] = '\0'; + + return g_steal_pointer (&ret); +#endif +} + +/* ---------------------------------------------------------------------------------------------------- */ + +gchar * +_g_dbus_enum_to_string (GType enum_type, gint value) +{ + gchar *ret; + GEnumClass *klass; + GEnumValue *enum_value; + + klass = g_type_class_ref (enum_type); + enum_value = g_enum_get_value (klass, value); + if (enum_value != NULL) + ret = g_strdup (enum_value->value_nick); + else + ret = g_strdup_printf ("unknown (value %d)", value); + g_type_class_unref (klass); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +write_message_print_transport_debug (gssize bytes_written, + MessageToWriteData *data) +{ + if (G_LIKELY (!_g_dbus_debug_transport ())) + goto out; + + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Transport:\n" + " >>>> WROTE %" G_GSSIZE_FORMAT " bytes of message with serial %d and\n" + " size %" G_GSIZE_FORMAT " from offset %" G_GSIZE_FORMAT " on a %s\n", + bytes_written, + g_dbus_message_get_serial (data->message), + data->blob_size, + data->total_written, + g_type_name (G_TYPE_FROM_INSTANCE (g_io_stream_get_output_stream (data->worker->stream)))); + _g_dbus_debug_print_unlock (); + out: + ; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +read_message_print_transport_debug (gssize bytes_read, + GDBusWorker *worker) +{ + gsize size; + gint32 serial; + gint32 message_length; + + if (G_LIKELY (!_g_dbus_debug_transport ())) + goto out; + + size = bytes_read + worker->read_buffer_cur_size; + serial = 0; + message_length = 0; + if (size >= 16) + message_length = g_dbus_message_bytes_needed ((guchar *) worker->read_buffer, size, NULL); + if (size >= 1) + { + switch (worker->read_buffer[0]) + { + case 'l': + if (size >= 12) + serial = GUINT32_FROM_LE (((guint32 *) worker->read_buffer)[2]); + break; + case 'B': + if (size >= 12) + serial = GUINT32_FROM_BE (((guint32 *) worker->read_buffer)[2]); + break; + default: + /* an error will be set elsewhere if this happens */ + goto out; + } + } + + _g_dbus_debug_print_lock (); + g_print ("========================================================================\n" + "GDBus-debug:Transport:\n" + " <<<< READ %" G_GSSIZE_FORMAT " bytes of message with serial %d and\n" + " size %d to offset %" G_GSIZE_FORMAT " from a %s\n", + bytes_read, + serial, + message_length, + worker->read_buffer_cur_size, + g_type_name (G_TYPE_FROM_INSTANCE (g_io_stream_get_input_stream (worker->stream)))); + _g_dbus_debug_print_unlock (); + out: + ; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +gboolean +_g_signal_accumulator_false_handled (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + gboolean continue_emission; + gboolean signal_return; + + signal_return = g_value_get_boolean (handler_return); + g_value_set_boolean (return_accu, signal_return); + continue_emission = signal_return; + + return continue_emission; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +append_nibble (GString *s, gint val) +{ + g_string_append_c (s, val >= 10 ? ('a' + val - 10) : ('0' + val)); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +gchar * +_g_dbus_hexencode (const gchar *str, + gsize str_len) +{ + gsize n; + GString *s; + + s = g_string_new (NULL); + for (n = 0; n < str_len; n++) + { + gint val; + gint upper_nibble; + gint lower_nibble; + + val = ((const guchar *) str)[n]; + upper_nibble = val >> 4; + lower_nibble = val & 0x0f; + + append_nibble (s, upper_nibble); + append_nibble (s, lower_nibble); + } + + return g_string_free (s, FALSE); +} diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h new file mode 100644 index 0000000..72d2c32 --- /dev/null +++ b/gio/gdbusprivate.h @@ -0,0 +1,165 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_PRIVATE_H__ +#define __G_DBUS_PRIVATE_H__ + +#if !defined (GIO_COMPILATION) +#error "gdbusprivate.h is a private header file." +#endif + +#include + +G_BEGIN_DECLS + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct GDBusWorker GDBusWorker; + +typedef void (*GDBusWorkerMessageReceivedCallback) (GDBusWorker *worker, + GDBusMessage *message, + gpointer user_data); + +typedef GDBusMessage *(*GDBusWorkerMessageAboutToBeSentCallback) (GDBusWorker *worker, + GDBusMessage *message, + gpointer user_data); + +typedef void (*GDBusWorkerDisconnectedCallback) (GDBusWorker *worker, + gboolean remote_peer_vanished, + GError *error, + gpointer user_data); + +/* This function may be called from any thread - callbacks will be in the shared private message thread + * and must not block. + */ +GDBusWorker *_g_dbus_worker_new (GIOStream *stream, + GDBusCapabilityFlags capabilities, + gboolean initially_frozen, + GDBusWorkerMessageReceivedCallback message_received_callback, + GDBusWorkerMessageAboutToBeSentCallback message_about_to_be_sent_callback, + GDBusWorkerDisconnectedCallback disconnected_callback, + gpointer user_data); + +/* can be called from any thread - steals blob */ +void _g_dbus_worker_send_message (GDBusWorker *worker, + GDBusMessage *message, + gchar *blob, + gsize blob_len); + +/* can be called from any thread */ +void _g_dbus_worker_stop (GDBusWorker *worker); + +/* can be called from any thread */ +void _g_dbus_worker_unfreeze (GDBusWorker *worker); + +/* can be called from any thread (except the worker thread) */ +gboolean _g_dbus_worker_flush_sync (GDBusWorker *worker, + GCancellable *cancellable, + GError **error); + +/* can be called from any thread */ +void _g_dbus_worker_close (GDBusWorker *worker, + GTask *task); + +/* ---------------------------------------------------------------------------------------------------- */ + +void _g_dbus_initialize (void); +gboolean _g_dbus_debug_authentication (void); +gboolean _g_dbus_debug_transport (void); +gboolean _g_dbus_debug_message (void); +gboolean _g_dbus_debug_payload (void); +gboolean _g_dbus_debug_call (void); +gboolean _g_dbus_debug_signal (void); +gboolean _g_dbus_debug_incoming (void); +gboolean _g_dbus_debug_return (void); +gboolean _g_dbus_debug_emission (void); +gboolean _g_dbus_debug_address (void); +gboolean _g_dbus_debug_proxy (void); + +void _g_dbus_debug_print_lock (void); +void _g_dbus_debug_print_unlock (void); + +gboolean _g_dbus_address_parse_entry (const gchar *address_entry, + gchar **out_transport_name, + GHashTable **out_key_value_pairs, + GError **error); + +GVariantType * _g_dbus_compute_complete_signature (GDBusArgInfo **args); + +gchar *_g_dbus_hexdump (const gchar *data, gsize len, guint indent); + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_WIN32 +gchar *_g_dbus_win32_get_user_sid (void); + +#define _GDBUS_ARG_WIN32_RUN_SESSION_BUS "_win32_run_session_bus" +/* The g_win32_run_session_bus is exported from libgio dll on win32, + * but still is NOT part of API/ABI since it is declared in private header + * and used only by tool built from same sources. + * Initially this function was introduces for usage with rundll, + * so the signature is kept rundll-compatible, though parameters aren't used. + */ +_GLIB_EXTERN void __stdcall +g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdshow); +gchar *_g_dbus_win32_get_session_address_dbus_launch (GError **error); +#endif + +gchar *_g_dbus_get_machine_id (GError **error); + +gchar *_g_dbus_enum_to_string (GType enum_type, gint value); + +/* ---------------------------------------------------------------------------------------------------- */ + +GDBusMethodInvocation *_g_dbus_method_invocation_new (const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + const GDBusMethodInfo *method_info, + const GDBusPropertyInfo *property_info, + GDBusConnection *connection, + GDBusMessage *message, + GVariant *parameters, + gpointer user_data); + +/* ---------------------------------------------------------------------------------------------------- */ + +gboolean _g_signal_accumulator_false_handled (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy); + +gboolean _g_dbus_object_skeleton_has_authorize_method_handlers (GDBusObjectSkeleton *object); + +void _g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy, + GDBusProxy *interface_proxy); +void _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy, + const gchar *interface_name); + +gchar *_g_dbus_hexencode (const gchar *str, + gsize str_len); + +/* Implemented in gdbusconnection.c */ +GDBusConnection *_g_bus_get_singleton_if_exists (GBusType bus_type); +void _g_bus_forget_singleton (GBusType bus_type); + +G_END_DECLS + +#endif /* __G_DBUS_PRIVATE_H__ */ diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c new file mode 100644 index 0000000..c095bc5 --- /dev/null +++ b/gio/gdbusproxy.c @@ -0,0 +1,3200 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include + +#include "gdbusutils.h" +#include "gdbusproxy.h" +#include "gioenumtypes.h" +#include "gdbusconnection.h" +#include "gdbuserror.h" +#include "gdbusprivate.h" +#include "ginitable.h" +#include "gasyncinitable.h" +#include "gioerror.h" +#include "gtask.h" +#include "gcancellable.h" +#include "gdbusinterface.h" +#include "gasyncresult.h" + +#ifdef G_OS_UNIX +#include "gunixfdlist.h" +#endif + +#include "glibintl.h" +#include "gmarshal-internal.h" + +/** + * SECTION:gdbusproxy + * @short_description: Client-side D-Bus interface proxy + * @include: gio/gio.h + * + * #GDBusProxy is a base class used for proxies to access a D-Bus + * interface on a remote object. A #GDBusProxy can be constructed for + * both well-known and unique names. + * + * By default, #GDBusProxy will cache all properties (and listen to + * changes) of the remote object, and proxy all signals that get + * emitted. This behaviour can be changed by passing suitable + * #GDBusProxyFlags when the proxy is created. If the proxy is for a + * well-known name, the property cache is flushed when the name owner + * vanishes and reloaded when a name owner appears. + * + * The unique name owner of the proxy's name is tracked and can be read from + * #GDBusProxy:g-name-owner. Connect to the #GObject::notify signal to + * get notified of changes. Additionally, only signals and property + * changes emitted from the current name owner are considered and + * calls are always sent to the current name owner. This avoids a + * number of race conditions when the name is lost by one owner and + * claimed by another. However, if no name owner currently exists, + * then calls will be sent to the well-known name which may result in + * the message bus launching an owner (unless + * %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is set). + * + * If the proxy is for a stateless D-Bus service, where the name owner may + * be started and stopped between calls, the #GDBusProxy:g-name-owner tracking + * of #GDBusProxy will cause the proxy to drop signal and property changes from + * the service after it has restarted for the first time. When interacting + * with a stateless D-Bus service, do not use #GDBusProxy — use direct D-Bus + * method calls and signal connections. + * + * The generic #GDBusProxy::g-properties-changed and + * #GDBusProxy::g-signal signals are not very convenient to work with. + * Therefore, the recommended way of working with proxies is to subclass + * #GDBusProxy, and have more natural properties and signals in your derived + * class. This [example][gdbus-example-gdbus-codegen] shows how this can + * easily be done using the [gdbus-codegen][gdbus-codegen] tool. + * + * A #GDBusProxy instance can be used from multiple threads but note + * that all signals (e.g. #GDBusProxy::g-signal, #GDBusProxy::g-properties-changed + * and #GObject::notify) are emitted in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread where the instance was constructed. + * + * An example using a proxy for a well-known name can be found in + * [gdbus-example-watch-proxy.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-watch-proxy.c) + */ + +/* lock protecting the mutable properties: name_owner, timeout_msec, + * expected_interface, and the properties hash table + */ +G_LOCK_DEFINE_STATIC (properties_lock); + +/* ---------------------------------------------------------------------------------------------------- */ + +static GWeakRef * +weak_ref_new (GObject *object) +{ + GWeakRef *weak_ref = g_new0 (GWeakRef, 1); + g_weak_ref_init (weak_ref, object); + return g_steal_pointer (&weak_ref); +} + +static void +weak_ref_free (GWeakRef *weak_ref) +{ + g_weak_ref_clear (weak_ref); + g_free (weak_ref); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +struct _GDBusProxyPrivate +{ + GBusType bus_type; + GDBusProxyFlags flags; + GDBusConnection *connection; + + gchar *name; + /* mutable, protected by properties_lock */ + gchar *name_owner; + gchar *object_path; + gchar *interface_name; + /* mutable, protected by properties_lock */ + gint timeout_msec; + + guint name_owner_changed_subscription_id; + + GCancellable *get_all_cancellable; + + /* gchar* -> GVariant*, protected by properties_lock */ + GHashTable *properties; + + /* mutable, protected by properties_lock */ + GDBusInterfaceInfo *expected_interface; + + guint properties_changed_subscription_id; + guint signals_subscription_id; + + gboolean initialized; + + /* mutable, protected by properties_lock */ + GDBusObject *object; +}; + +enum +{ + PROP_0, + PROP_G_CONNECTION, + PROP_G_BUS_TYPE, + PROP_G_NAME, + PROP_G_NAME_OWNER, + PROP_G_FLAGS, + PROP_G_OBJECT_PATH, + PROP_G_INTERFACE_NAME, + PROP_G_DEFAULT_TIMEOUT, + PROP_G_INTERFACE_INFO +}; + +enum +{ + PROPERTIES_CHANGED_SIGNAL, + SIGNAL_SIGNAL, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = {0}; + +static void dbus_interface_iface_init (GDBusInterfaceIface *dbus_interface_iface); +static void initable_iface_init (GInitableIface *initable_iface); +static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface); + +G_DEFINE_TYPE_WITH_CODE (GDBusProxy, g_dbus_proxy, G_TYPE_OBJECT, + G_ADD_PRIVATE (GDBusProxy) + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_INTERFACE, dbus_interface_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)) + +static void +g_dbus_proxy_finalize (GObject *object) +{ + GDBusProxy *proxy = G_DBUS_PROXY (object); + + g_warn_if_fail (proxy->priv->get_all_cancellable == NULL); + + if (proxy->priv->name_owner_changed_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (proxy->priv->connection, + proxy->priv->name_owner_changed_subscription_id); + + if (proxy->priv->properties_changed_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (proxy->priv->connection, + proxy->priv->properties_changed_subscription_id); + + if (proxy->priv->signals_subscription_id > 0) + g_dbus_connection_signal_unsubscribe (proxy->priv->connection, + proxy->priv->signals_subscription_id); + + if (proxy->priv->connection != NULL) + g_object_unref (proxy->priv->connection); + g_free (proxy->priv->name); + g_free (proxy->priv->name_owner); + g_free (proxy->priv->object_path); + g_free (proxy->priv->interface_name); + if (proxy->priv->properties != NULL) + g_hash_table_unref (proxy->priv->properties); + + if (proxy->priv->expected_interface != NULL) + { + g_dbus_interface_info_cache_release (proxy->priv->expected_interface); + g_dbus_interface_info_unref (proxy->priv->expected_interface); + } + + if (proxy->priv->object != NULL) + g_object_remove_weak_pointer (G_OBJECT (proxy->priv->object), (gpointer *) &proxy->priv->object); + + G_OBJECT_CLASS (g_dbus_proxy_parent_class)->finalize (object); +} + +static void +g_dbus_proxy_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusProxy *proxy = G_DBUS_PROXY (object); + + switch (prop_id) + { + case PROP_G_CONNECTION: + g_value_set_object (value, proxy->priv->connection); + break; + + case PROP_G_FLAGS: + g_value_set_flags (value, proxy->priv->flags); + break; + + case PROP_G_NAME: + g_value_set_string (value, proxy->priv->name); + break; + + case PROP_G_NAME_OWNER: + g_value_take_string (value, g_dbus_proxy_get_name_owner (proxy)); + break; + + case PROP_G_OBJECT_PATH: + g_value_set_string (value, proxy->priv->object_path); + break; + + case PROP_G_INTERFACE_NAME: + g_value_set_string (value, proxy->priv->interface_name); + break; + + case PROP_G_DEFAULT_TIMEOUT: + g_value_set_int (value, g_dbus_proxy_get_default_timeout (proxy)); + break; + + case PROP_G_INTERFACE_INFO: + g_value_set_boxed (value, g_dbus_proxy_get_interface_info (proxy)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_proxy_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusProxy *proxy = G_DBUS_PROXY (object); + + switch (prop_id) + { + case PROP_G_CONNECTION: + proxy->priv->connection = g_value_dup_object (value); + break; + + case PROP_G_FLAGS: + proxy->priv->flags = g_value_get_flags (value); + break; + + case PROP_G_NAME: + proxy->priv->name = g_value_dup_string (value); + break; + + case PROP_G_OBJECT_PATH: + proxy->priv->object_path = g_value_dup_string (value); + break; + + case PROP_G_INTERFACE_NAME: + proxy->priv->interface_name = g_value_dup_string (value); + break; + + case PROP_G_DEFAULT_TIMEOUT: + g_dbus_proxy_set_default_timeout (proxy, g_value_get_int (value)); + break; + + case PROP_G_INTERFACE_INFO: + g_dbus_proxy_set_interface_info (proxy, g_value_get_boxed (value)); + break; + + case PROP_G_BUS_TYPE: + proxy->priv->bus_type = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_proxy_class_init (GDBusProxyClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_proxy_finalize; + gobject_class->set_property = g_dbus_proxy_set_property; + gobject_class->get_property = g_dbus_proxy_get_property; + + /* Note that all property names are prefixed to avoid collisions with D-Bus property names + * in derived classes */ + + /** + * GDBusProxy:g-interface-info: + * + * Ensure that interactions with this proxy conform to the given + * interface. This is mainly to ensure that malformed data received + * from the other peer is ignored. The given #GDBusInterfaceInfo is + * said to be the "expected interface". + * + * The checks performed are: + * - When completing a method call, if the type signature of + * the reply message isn't what's expected, the reply is + * discarded and the #GError is set to %G_IO_ERROR_INVALID_ARGUMENT. + * + * - Received signals that have a type signature mismatch are dropped and + * a warning is logged via g_warning(). + * + * - Properties received via the initial `GetAll()` call or via the + * `::PropertiesChanged` signal (on the + * [org.freedesktop.DBus.Properties](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties) + * interface) or set using g_dbus_proxy_set_cached_property() + * with a type signature mismatch are ignored and a warning is + * logged via g_warning(). + * + * Note that these checks are never done on methods, signals and + * properties that are not referenced in the given + * #GDBusInterfaceInfo, since extending a D-Bus interface on the + * service-side is not considered an ABI break. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_INTERFACE_INFO, + g_param_spec_boxed ("g-interface-info", + P_("Interface Information"), + P_("Interface Information"), + G_TYPE_DBUS_INTERFACE_INFO, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy:g-connection: + * + * The #GDBusConnection the proxy is for. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_CONNECTION, + g_param_spec_object ("g-connection", + P_("g-connection"), + P_("The connection the proxy is for"), + G_TYPE_DBUS_CONNECTION, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy:g-bus-type: + * + * If this property is not %G_BUS_TYPE_NONE, then + * #GDBusProxy:g-connection must be %NULL and will be set to the + * #GDBusConnection obtained by calling g_bus_get() with the value + * of this property. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_BUS_TYPE, + g_param_spec_enum ("g-bus-type", + P_("Bus Type"), + P_("The bus to connect to, if any"), + G_TYPE_BUS_TYPE, + G_BUS_TYPE_NONE, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy:g-flags: + * + * Flags from the #GDBusProxyFlags enumeration. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_FLAGS, + g_param_spec_flags ("g-flags", + P_("g-flags"), + P_("Flags for the proxy"), + G_TYPE_DBUS_PROXY_FLAGS, + G_DBUS_PROXY_FLAGS_NONE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy:g-name: + * + * The well-known or unique name that the proxy is for. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_NAME, + g_param_spec_string ("g-name", + P_("g-name"), + P_("The well-known or unique name that the proxy is for"), + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy:g-name-owner: + * + * The unique name that owns #GDBusProxy:g-name or %NULL if no-one + * currently owns that name. You may connect to #GObject::notify signal to + * track changes to this property. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_NAME_OWNER, + g_param_spec_string ("g-name-owner", + P_("g-name-owner"), + P_("The unique name for the owner"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy:g-object-path: + * + * The object path the proxy is for. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_OBJECT_PATH, + g_param_spec_string ("g-object-path", + P_("g-object-path"), + P_("The object path the proxy is for"), + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy:g-interface-name: + * + * The D-Bus interface name the proxy is for. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_INTERFACE_NAME, + g_param_spec_string ("g-interface-name", + P_("g-interface-name"), + P_("The D-Bus interface name the proxy is for"), + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy:g-default-timeout: + * + * The timeout to use if -1 (specifying default timeout) is passed + * as @timeout_msec in the g_dbus_proxy_call() and + * g_dbus_proxy_call_sync() functions. + * + * This allows applications to set a proxy-wide timeout for all + * remote method invocations on the proxy. If this property is -1, + * the default timeout (typically 25 seconds) is used. If set to + * %G_MAXINT, then no timeout is used. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_G_DEFAULT_TIMEOUT, + g_param_spec_int ("g-default-timeout", + P_("Default Timeout"), + P_("Timeout for remote method invocation"), + -1, + G_MAXINT, + -1, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusProxy::g-properties-changed: + * @proxy: The #GDBusProxy emitting the signal. + * @changed_properties: A #GVariant containing the properties that changed (type: `a{sv}`) + * @invalidated_properties: A %NULL terminated array of properties that was invalidated + * + * Emitted when one or more D-Bus properties on @proxy changes. The + * local cache has already been updated when this signal fires. Note + * that both @changed_properties and @invalidated_properties are + * guaranteed to never be %NULL (either may be empty though). + * + * If the proxy has the flag + * %G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES set, then + * @invalidated_properties will always be empty. + * + * This signal corresponds to the + * `PropertiesChanged` D-Bus signal on the + * `org.freedesktop.DBus.Properties` interface. + * + * Since: 2.26 + */ + signals[PROPERTIES_CHANGED_SIGNAL] = g_signal_new (I_("g-properties-changed"), + G_TYPE_DBUS_PROXY, + G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT, + G_STRUCT_OFFSET (GDBusProxyClass, g_properties_changed), + NULL, + NULL, + _g_cclosure_marshal_VOID__VARIANT_BOXED, + G_TYPE_NONE, + 2, + G_TYPE_VARIANT, + G_TYPE_STRV | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (signals[PROPERTIES_CHANGED_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__VARIANT_BOXEDv); + + /** + * GDBusProxy::g-signal: + * @proxy: The #GDBusProxy emitting the signal. + * @sender_name: (nullable): The sender of the signal or %NULL if the connection is not a bus connection. + * @signal_name: The name of the signal. + * @parameters: A #GVariant tuple with parameters for the signal. + * + * Emitted when a signal from the remote object and interface that @proxy is for, has been received. + * + * Since 2.72 this signal supports detailed connections. You can connect to + * the detailed signal `g-signal::x` in order to receive callbacks only when + * signal `x` is received from the remote object. + * + * Since: 2.26 + */ + signals[SIGNAL_SIGNAL] = g_signal_new (I_("g-signal"), + G_TYPE_DBUS_PROXY, + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED | G_SIGNAL_MUST_COLLECT, + G_STRUCT_OFFSET (GDBusProxyClass, g_signal), + NULL, + NULL, + _g_cclosure_marshal_VOID__STRING_STRING_VARIANT, + G_TYPE_NONE, + 3, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_VARIANT); + g_signal_set_va_marshaller (signals[SIGNAL_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__STRING_STRING_VARIANTv); + +} + +static void +g_dbus_proxy_init (GDBusProxy *proxy) +{ + proxy->priv = g_dbus_proxy_get_instance_private (proxy); + proxy->priv->properties = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_variant_unref); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gint +property_name_sort_func (const gchar **a, + const gchar **b) +{ + return g_strcmp0 (*a, *b); +} + +/** + * g_dbus_proxy_get_cached_property_names: + * @proxy: A #GDBusProxy. + * + * Gets the names of all cached properties on @proxy. + * + * Returns: (transfer full) (nullable) (array zero-terminated=1): A + * %NULL-terminated array of strings or %NULL if + * @proxy has no cached properties. Free the returned array with + * g_strfreev(). + * + * Since: 2.26 + */ +gchar ** +g_dbus_proxy_get_cached_property_names (GDBusProxy *proxy) +{ + gchar **names; + GPtrArray *p; + GHashTableIter iter; + const gchar *key; + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + + G_LOCK (properties_lock); + + names = NULL; + if (g_hash_table_size (proxy->priv->properties) == 0) + goto out; + + p = g_ptr_array_new (); + + g_hash_table_iter_init (&iter, proxy->priv->properties); + while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) + g_ptr_array_add (p, g_strdup (key)); + g_ptr_array_sort (p, (GCompareFunc) property_name_sort_func); + g_ptr_array_add (p, NULL); + + names = (gchar **) g_ptr_array_free (p, FALSE); + + out: + G_UNLOCK (properties_lock); + return names; +} + +/* properties_lock must be held for as long as you will keep the + * returned value + */ +static const GDBusPropertyInfo * +lookup_property_info (GDBusProxy *proxy, + const gchar *property_name) +{ + const GDBusPropertyInfo *info = NULL; + + if (proxy->priv->expected_interface == NULL) + goto out; + + info = g_dbus_interface_info_lookup_property (proxy->priv->expected_interface, property_name); + + out: + return info; +} + +/** + * g_dbus_proxy_get_cached_property: + * @proxy: A #GDBusProxy. + * @property_name: Property name. + * + * Looks up the value for a property from the cache. This call does no + * blocking IO. + * + * If @proxy has an expected interface (see + * #GDBusProxy:g-interface-info) and @property_name is referenced by + * it, then @value is checked against the type of the property. + * + * Returns: (transfer full) (nullable): A reference to the #GVariant instance + * that holds the value for @property_name or %NULL if the value is not in + * the cache. The returned reference must be freed with g_variant_unref(). + * + * Since: 2.26 + */ +GVariant * +g_dbus_proxy_get_cached_property (GDBusProxy *proxy, + const gchar *property_name) +{ + const GDBusPropertyInfo *info; + GVariant *value; + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + + G_LOCK (properties_lock); + + value = g_hash_table_lookup (proxy->priv->properties, property_name); + if (value == NULL) + goto out; + + info = lookup_property_info (proxy, property_name); + if (info != NULL) + { + const gchar *type_string = g_variant_get_type_string (value); + if (g_strcmp0 (type_string, info->signature) != 0) + { + g_warning ("Trying to get property %s with type %s but according to the expected " + "interface the type is %s", + property_name, + type_string, + info->signature); + value = NULL; + goto out; + } + } + + g_variant_ref (value); + + out: + G_UNLOCK (properties_lock); + return value; +} + +/** + * g_dbus_proxy_set_cached_property: + * @proxy: A #GDBusProxy + * @property_name: Property name. + * @value: (nullable): Value for the property or %NULL to remove it from the cache. + * + * If @value is not %NULL, sets the cached value for the property with + * name @property_name to the value in @value. + * + * If @value is %NULL, then the cached value is removed from the + * property cache. + * + * If @proxy has an expected interface (see + * #GDBusProxy:g-interface-info) and @property_name is referenced by + * it, then @value is checked against the type of the property. + * + * If the @value #GVariant is floating, it is consumed. This allows + * convenient 'inline' use of g_variant_new(), e.g. + * |[ + * g_dbus_proxy_set_cached_property (proxy, + * "SomeProperty", + * g_variant_new ("(si)", + * "A String", + * 42)); + * ]| + * + * Normally you will not need to use this method since @proxy + * is tracking changes using the + * `org.freedesktop.DBus.Properties.PropertiesChanged` + * D-Bus signal. However, for performance reasons an object may + * decide to not use this signal for some properties and instead + * use a proprietary out-of-band mechanism to transmit changes. + * + * As a concrete example, consider an object with a property + * `ChatroomParticipants` which is an array of strings. Instead of + * transmitting the same (long) array every time the property changes, + * it is more efficient to only transmit the delta using e.g. signals + * `ChatroomParticipantJoined(String name)` and + * `ChatroomParticipantParted(String name)`. + * + * Since: 2.26 + */ +void +g_dbus_proxy_set_cached_property (GDBusProxy *proxy, + const gchar *property_name, + GVariant *value) +{ + const GDBusPropertyInfo *info; + + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); + g_return_if_fail (property_name != NULL); + + G_LOCK (properties_lock); + + if (value != NULL) + { + info = lookup_property_info (proxy, property_name); + if (info != NULL) + { + if (g_strcmp0 (info->signature, g_variant_get_type_string (value)) != 0) + { + g_warning ("Trying to set property %s of type %s but according to the expected " + "interface the type is %s", + property_name, + g_variant_get_type_string (value), + info->signature); + goto out; + } + } + g_hash_table_insert (proxy->priv->properties, + g_strdup (property_name), + g_variant_ref_sink (value)); + } + else + { + g_hash_table_remove (proxy->priv->properties, property_name); + } + + out: + G_UNLOCK (properties_lock); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_signal_received (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GWeakRef *proxy_weak = user_data; + GDBusProxy *proxy; + + proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak)); + if (proxy == NULL) + return; + + if (!proxy->priv->initialized) + goto out; + + G_LOCK (properties_lock); + + if (proxy->priv->name_owner != NULL && g_strcmp0 (sender_name, proxy->priv->name_owner) != 0) + { + G_UNLOCK (properties_lock); + goto out; + } + + if (proxy->priv->expected_interface != NULL) + { + const GDBusSignalInfo *info; + info = g_dbus_interface_info_lookup_signal (proxy->priv->expected_interface, signal_name); + if (info != NULL) + { + GVariantType *expected_type; + expected_type = _g_dbus_compute_complete_signature (info->args); + if (!g_variant_type_equal (expected_type, g_variant_get_type (parameters))) + { + gchar *expected_type_string = g_variant_type_dup_string (expected_type); + g_warning ("Dropping signal %s of type %s since the type from the expected interface is %s", + info->name, + g_variant_get_type_string (parameters), + expected_type_string); + g_free (expected_type_string); + g_variant_type_free (expected_type); + G_UNLOCK (properties_lock); + goto out; + } + g_variant_type_free (expected_type); + } + } + + G_UNLOCK (properties_lock); + + g_signal_emit (proxy, + signals[SIGNAL_SIGNAL], + g_quark_try_string (signal_name), + sender_name, + signal_name, + parameters); + + out: + g_clear_object (&proxy); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* must hold properties_lock */ +static void +insert_property_checked (GDBusProxy *proxy, + gchar *property_name, + GVariant *value) +{ + if (proxy->priv->expected_interface != NULL) + { + const GDBusPropertyInfo *info; + info = g_dbus_interface_info_lookup_property (proxy->priv->expected_interface, property_name); + /* Only check known properties */ + if (info != NULL) + { + /* Warn about properties with the wrong type */ + if (g_strcmp0 (info->signature, g_variant_get_type_string (value)) != 0) + { + g_warning ("Received property %s with type %s does not match expected type " + "%s in the expected interface", + property_name, + g_variant_get_type_string (value), + info->signature); + goto invalid; + } + } + } + + g_hash_table_insert (proxy->priv->properties, + property_name, /* adopts string */ + value); /* adopts value */ + + return; + + invalid: + g_variant_unref (value); + g_free (property_name); +} + +typedef struct +{ + GDBusProxy *proxy; + gchar *prop_name; +} InvalidatedPropGetData; + +static void +invalidated_property_get_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + InvalidatedPropGetData *data = user_data; + const gchar *invalidated_properties[] = {NULL}; + GVariantBuilder builder; + GVariant *value = NULL; + GVariant *unpacked_value = NULL; + + /* errors are fine, the other end could have disconnected */ + value = g_dbus_connection_call_finish (connection, res, NULL); + if (value == NULL) + { + goto out; + } + + if (!g_variant_is_of_type (value, G_VARIANT_TYPE ("(v)"))) + { + g_warning ("Expected type '(v)' for Get() reply, got '%s'", g_variant_get_type_string (value)); + goto out; + } + + g_variant_get (value, "(v)", &unpacked_value); + + /* synthesize the a{sv} in the PropertiesChanged signal */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", data->prop_name, unpacked_value); + + G_LOCK (properties_lock); + insert_property_checked (data->proxy, + data->prop_name, /* adopts string */ + unpacked_value); /* adopts value */ + data->prop_name = NULL; + G_UNLOCK (properties_lock); + + g_signal_emit (data->proxy, + signals[PROPERTIES_CHANGED_SIGNAL], 0, + g_variant_builder_end (&builder), /* consumed */ + invalidated_properties); + + + out: + if (value != NULL) + g_variant_unref (value); + g_object_unref (data->proxy); + g_free (data->prop_name); + g_slice_free (InvalidatedPropGetData, data); +} + +static void +on_properties_changed (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GWeakRef *proxy_weak = user_data; + gboolean emit_g_signal = FALSE; + GDBusProxy *proxy; + const gchar *interface_name_for_signal; + GVariant *changed_properties; + gchar **invalidated_properties; + GVariantIter iter; + gchar *key; + GVariant *value; + guint n; + + changed_properties = NULL; + invalidated_properties = NULL; + + proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak)); + if (proxy == NULL) + return; + + if (!proxy->priv->initialized) + goto out; + + G_LOCK (properties_lock); + + if (proxy->priv->name_owner != NULL && g_strcmp0 (sender_name, proxy->priv->name_owner) != 0) + { + G_UNLOCK (properties_lock); + goto out; + } + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sa{sv}as)"))) + { + g_warning ("Value for PropertiesChanged signal with type '%s' does not match '(sa{sv}as)'", + g_variant_get_type_string (parameters)); + G_UNLOCK (properties_lock); + goto out; + } + + g_variant_get (parameters, + "(&s@a{sv}^a&s)", + &interface_name_for_signal, + &changed_properties, + &invalidated_properties); + + if (g_strcmp0 (interface_name_for_signal, proxy->priv->interface_name) != 0) + { + G_UNLOCK (properties_lock); + goto out; + } + + g_variant_iter_init (&iter, changed_properties); + while (g_variant_iter_next (&iter, "{sv}", &key, &value)) + { + insert_property_checked (proxy, + key, /* adopts string */ + value); /* adopts value */ + emit_g_signal = TRUE; + } + + if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES) + { + if (proxy->priv->name_owner != NULL) + { + for (n = 0; invalidated_properties[n] != NULL; n++) + { + InvalidatedPropGetData *data; + data = g_slice_new0 (InvalidatedPropGetData); + data->proxy = g_object_ref (proxy); + data->prop_name = g_strdup (invalidated_properties[n]); + g_dbus_connection_call (proxy->priv->connection, + proxy->priv->name_owner, + proxy->priv->object_path, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new ("(ss)", proxy->priv->interface_name, data->prop_name), + G_VARIANT_TYPE ("(v)"), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + NULL, /* GCancellable */ + (GAsyncReadyCallback) invalidated_property_get_cb, + data); + } + } + } + else + { + emit_g_signal = TRUE; + for (n = 0; invalidated_properties[n] != NULL; n++) + { + g_hash_table_remove (proxy->priv->properties, invalidated_properties[n]); + } + } + + G_UNLOCK (properties_lock); + + if (emit_g_signal) + { + g_signal_emit (proxy, signals[PROPERTIES_CHANGED_SIGNAL], + 0, + changed_properties, + invalidated_properties); + } + + out: + g_clear_pointer (&changed_properties, g_variant_unref); + g_free (invalidated_properties); + g_clear_object (&proxy); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +process_get_all_reply (GDBusProxy *proxy, + GVariant *result) +{ + GVariantIter *iter; + gchar *key; + GVariant *value; + guint num_properties; + + if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(a{sv})"))) + { + g_warning ("Value for GetAll reply with type '%s' does not match '(a{sv})'", + g_variant_get_type_string (result)); + goto out; + } + + G_LOCK (properties_lock); + + g_variant_get (result, "(a{sv})", &iter); + while (g_variant_iter_next (iter, "{sv}", &key, &value)) + { + insert_property_checked (proxy, + key, /* adopts string */ + value); /* adopts value */ + } + g_variant_iter_free (iter); + + num_properties = g_hash_table_size (proxy->priv->properties); + G_UNLOCK (properties_lock); + + /* Synthesize ::g-properties-changed changed */ + if (num_properties > 0) + { + GVariant *changed_properties; + const gchar *invalidated_properties[1] = {NULL}; + + g_variant_get (result, + "(@a{sv})", + &changed_properties); + g_signal_emit (proxy, signals[PROPERTIES_CHANGED_SIGNAL], + 0, + changed_properties, + invalidated_properties); + g_variant_unref (changed_properties); + } + + out: + ; +} + +typedef struct +{ + GDBusProxy *proxy; + GCancellable *cancellable; + gchar *name_owner; +} LoadPropertiesOnNameOwnerChangedData; + +static void +on_name_owner_changed_get_all_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + LoadPropertiesOnNameOwnerChangedData *data = user_data; + GVariant *result; + GError *error; + gboolean cancelled; + + cancelled = FALSE; + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + if (result == NULL) + { + if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED) + cancelled = TRUE; + /* We just ignore if GetAll() is failing. Because this might happen + * if the object has no properties at all. Or if the caller is + * not authorized to see the properties. + * + * Either way, apps can know about this by using + * get_cached_property_names() or get_cached_property(). + */ + if (G_UNLIKELY (_g_dbus_debug_proxy ())) + { + g_debug ("error: %d %d %s", + error->domain, + error->code, + error->message); + } + g_error_free (error); + } + + /* and finally we can notify */ + if (!cancelled) + { + G_LOCK (properties_lock); + g_free (data->proxy->priv->name_owner); + data->proxy->priv->name_owner = g_steal_pointer (&data->name_owner); + g_hash_table_remove_all (data->proxy->priv->properties); + G_UNLOCK (properties_lock); + if (result != NULL) + { + process_get_all_reply (data->proxy, result); + g_variant_unref (result); + } + + g_object_notify (G_OBJECT (data->proxy), "g-name-owner"); + } + + if (data->cancellable == data->proxy->priv->get_all_cancellable) + data->proxy->priv->get_all_cancellable = NULL; + + g_object_unref (data->proxy); + g_object_unref (data->cancellable); + g_free (data->name_owner); + g_free (data); +} + +static void +on_name_owner_changed (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GWeakRef *proxy_weak = user_data; + GDBusProxy *proxy; + const gchar *old_owner; + const gchar *new_owner; + + proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak)); + if (proxy == NULL) + return; + + /* if we are already trying to load properties, cancel that */ + if (proxy->priv->get_all_cancellable != NULL) + { + g_cancellable_cancel (proxy->priv->get_all_cancellable); + proxy->priv->get_all_cancellable = NULL; + } + + g_variant_get (parameters, + "(&s&s&s)", + NULL, + &old_owner, + &new_owner); + + if (strlen (new_owner) == 0) + { + G_LOCK (properties_lock); + g_free (proxy->priv->name_owner); + proxy->priv->name_owner = NULL; + + /* Synthesize ::g-properties-changed changed */ + if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) && + g_hash_table_size (proxy->priv->properties) > 0) + { + GVariantBuilder builder; + GPtrArray *invalidated_properties; + GHashTableIter iter; + const gchar *key; + + /* Build changed_properties (always empty) and invalidated_properties ... */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + + invalidated_properties = g_ptr_array_new_with_free_func (g_free); + g_hash_table_iter_init (&iter, proxy->priv->properties); + while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) + g_ptr_array_add (invalidated_properties, g_strdup (key)); + g_ptr_array_add (invalidated_properties, NULL); + + /* ... throw out the properties ... */ + g_hash_table_remove_all (proxy->priv->properties); + + G_UNLOCK (properties_lock); + + /* ... and finally emit the ::g-properties-changed signal */ + g_signal_emit (proxy, signals[PROPERTIES_CHANGED_SIGNAL], + 0, + g_variant_builder_end (&builder) /* consumed */, + (const gchar* const *) invalidated_properties->pdata); + g_ptr_array_unref (invalidated_properties); + } + else + { + G_UNLOCK (properties_lock); + } + g_object_notify (G_OBJECT (proxy), "g-name-owner"); + } + else + { + G_LOCK (properties_lock); + + /* ignore duplicates - this can happen when activating the service */ + if (g_strcmp0 (new_owner, proxy->priv->name_owner) == 0) + { + G_UNLOCK (properties_lock); + goto out; + } + + if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) + { + g_free (proxy->priv->name_owner); + proxy->priv->name_owner = g_strdup (new_owner); + + g_hash_table_remove_all (proxy->priv->properties); + G_UNLOCK (properties_lock); + g_object_notify (G_OBJECT (proxy), "g-name-owner"); + } + else + { + LoadPropertiesOnNameOwnerChangedData *data; + + G_UNLOCK (properties_lock); + + /* start loading properties.. only then emit notify::g-name-owner .. we + * need to be able to cancel this in the event another NameOwnerChanged + * signal suddenly happens + */ + + g_assert (proxy->priv->get_all_cancellable == NULL); + proxy->priv->get_all_cancellable = g_cancellable_new (); + data = g_new0 (LoadPropertiesOnNameOwnerChangedData, 1); + data->proxy = g_object_ref (proxy); + data->cancellable = proxy->priv->get_all_cancellable; + data->name_owner = g_strdup (new_owner); + g_dbus_connection_call (proxy->priv->connection, + data->name_owner, + proxy->priv->object_path, + "org.freedesktop.DBus.Properties", + "GetAll", + g_variant_new ("(s)", proxy->priv->interface_name), + G_VARIANT_TYPE ("(a{sv})"), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + proxy->priv->get_all_cancellable, + (GAsyncReadyCallback) on_name_owner_changed_get_all_cb, + data); + } + } + + out: + g_clear_object (&proxy); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +async_init_get_all_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + GVariant *result; + GError *error; + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + if (result == NULL) + { + /* We just ignore if GetAll() is failing. Because this might happen + * if the object has no properties at all. Or if the caller is + * not authorized to see the properties. + * + * Either way, apps can know about this by using + * get_cached_property_names() or get_cached_property(). + */ + if (G_UNLIKELY (_g_dbus_debug_proxy ())) + { + g_debug ("error: %d %d %s", + error->domain, + error->code, + error->message); + } + g_error_free (error); + } + + g_task_return_pointer (task, result, + (GDestroyNotify) g_variant_unref); + g_object_unref (task); +} + +static void +async_init_data_set_name_owner (GTask *task, + const gchar *name_owner) +{ + GDBusProxy *proxy = g_task_get_source_object (task); + gboolean get_all; + + if (name_owner != NULL) + { + G_LOCK (properties_lock); + /* Must free first, since on_name_owner_changed() could run before us */ + g_free (proxy->priv->name_owner); + proxy->priv->name_owner = g_strdup (name_owner); + G_UNLOCK (properties_lock); + } + + get_all = TRUE; + + if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) + { + /* Don't load properties if the API user doesn't want them */ + get_all = FALSE; + } + else if (name_owner == NULL && proxy->priv->name != NULL) + { + /* Don't attempt to load properties if the name_owner is NULL (which + * usually means the name isn't owned), unless name is also NULL (which + * means we actually wanted to talk to the directly-connected process - + * either dbus-daemon or a peer - instead of going via dbus-daemon) + */ + get_all = FALSE; + } + + if (get_all) + { + /* load all properties asynchronously */ + g_dbus_connection_call (proxy->priv->connection, + name_owner, + proxy->priv->object_path, + "org.freedesktop.DBus.Properties", + "GetAll", + g_variant_new ("(s)", proxy->priv->interface_name), + G_VARIANT_TYPE ("(a{sv})"), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + g_task_get_cancellable (task), + (GAsyncReadyCallback) async_init_get_all_cb, + task); + } + else + { + g_task_return_pointer (task, NULL, NULL); + g_object_unref (task); + } +} + +static void +async_init_get_name_owner_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + GError *error; + GVariant *result; + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + if (result == NULL) + { + if (error->domain == G_DBUS_ERROR && + error->code == G_DBUS_ERROR_NAME_HAS_NO_OWNER) + { + g_error_free (error); + async_init_data_set_name_owner (task, NULL); + } + else + { + g_task_return_error (task, error); + g_object_unref (task); + } + } + else + { + /* borrowed from result to avoid an extra copy */ + const gchar *name_owner; + + g_variant_get (result, "(&s)", &name_owner); + async_init_data_set_name_owner (task, name_owner); + g_variant_unref (result); + } +} + +static void +async_init_call_get_name_owner (GTask *task) +{ + GDBusProxy *proxy = g_task_get_source_object (task); + + g_dbus_connection_call (proxy->priv->connection, + "org.freedesktop.DBus", /* name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface */ + "GetNameOwner", + g_variant_new ("(s)", + proxy->priv->name), + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + g_task_get_cancellable (task), + (GAsyncReadyCallback) async_init_get_name_owner_cb, + task); +} + +static void +async_init_start_service_by_name_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + GDBusProxy *proxy = g_task_get_source_object (task); + GError *error; + GVariant *result; + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + if (result == NULL) + { + /* Errors are not unexpected; the bus will reply e.g. + * + * org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.Epiphany2 + * was not provided by any .service files + * + * or (see #677718) + * + * org.freedesktop.systemd1.Masked: Unit polkit.service is masked. + * + * This doesn't mean that the name doesn't have an owner, just + * that it's not provided by a .service file or can't currently + * be started. + * + * In particular, in both cases, it could be that a service + * owner will actually appear later. So instead of erroring out, + * we just proceed to invoke GetNameOwner() if dealing with the + * kind of errors above. + */ + if (error->domain == G_DBUS_ERROR && error->code == G_DBUS_ERROR_SERVICE_UNKNOWN) + { + g_error_free (error); + } + else + { + gchar *remote_error = g_dbus_error_get_remote_error (error); + if (g_strcmp0 (remote_error, "org.freedesktop.systemd1.Masked") == 0) + { + g_error_free (error); + g_free (remote_error); + } + else + { + g_dbus_error_strip_remote_error (error); + g_prefix_error (&error, + _("Error calling StartServiceByName for %s: "), + proxy->priv->name); + g_free (remote_error); + goto failed; + } + } + } + else + { + guint32 start_service_result; + g_variant_get (result, + "(u)", + &start_service_result); + g_variant_unref (result); + if (start_service_result == 1 || /* DBUS_START_REPLY_SUCCESS */ + start_service_result == 2) /* DBUS_START_REPLY_ALREADY_RUNNING */ + { + /* continue to invoke GetNameOwner() */ + } + else + { + error = g_error_new (G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unexpected reply %d from StartServiceByName(\"%s\") method"), + start_service_result, + proxy->priv->name); + goto failed; + } + } + + async_init_call_get_name_owner (task); + return; + + failed: + g_warn_if_fail (error != NULL); + g_task_return_error (task, error); + g_object_unref (task); +} + +static void +async_init_call_start_service_by_name (GTask *task) +{ + GDBusProxy *proxy = g_task_get_source_object (task); + + g_dbus_connection_call (proxy->priv->connection, + "org.freedesktop.DBus", /* name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface */ + "StartServiceByName", + g_variant_new ("(su)", + proxy->priv->name, + 0), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + g_task_get_cancellable (task), + (GAsyncReadyCallback) async_init_start_service_by_name_cb, + task); +} + +static void +async_initable_init_second_async (GAsyncInitable *initable, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (initable); + GTask *task; + + task = g_task_new (proxy, cancellable, callback, user_data); + g_task_set_source_tag (task, async_initable_init_second_async); + g_task_set_name (task, "[gio] D-Bus proxy init"); + g_task_set_priority (task, io_priority); + + /* Check name ownership asynchronously - possibly also start the service */ + if (proxy->priv->name == NULL) + { + /* Do nothing */ + async_init_data_set_name_owner (task, NULL); + } + else if (g_dbus_is_unique_name (proxy->priv->name)) + { + async_init_data_set_name_owner (task, proxy->priv->name); + } + else + { + if ((proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) || + (proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION)) + { + async_init_call_get_name_owner (task); + } + else + { + async_init_call_start_service_by_name (task); + } + } +} + +static gboolean +async_initable_init_second_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error) +{ + GDBusProxy *proxy = G_DBUS_PROXY (initable); + GTask *task = G_TASK (res); + GVariant *result; + gboolean ret; + + ret = !g_task_had_error (task); + + result = g_task_propagate_pointer (task, error); + if (result != NULL) + { + process_get_all_reply (proxy, result); + g_variant_unref (result); + } + + proxy->priv->initialized = TRUE; + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +async_initable_init_first (GAsyncInitable *initable) +{ + GDBusProxy *proxy = G_DBUS_PROXY (initable); + GDBusSignalFlags signal_flags = G_DBUS_SIGNAL_FLAGS_NONE; + + if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_NO_MATCH_RULE) + signal_flags |= G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE; + + if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES)) + { + /* subscribe to PropertiesChanged() */ + proxy->priv->properties_changed_subscription_id = + g_dbus_connection_signal_subscribe (proxy->priv->connection, + proxy->priv->name, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + proxy->priv->object_path, + proxy->priv->interface_name, + signal_flags, + on_properties_changed, + weak_ref_new (G_OBJECT (proxy)), + (GDestroyNotify) weak_ref_free); + } + + if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS)) + { + /* subscribe to all signals for the object */ + proxy->priv->signals_subscription_id = + g_dbus_connection_signal_subscribe (proxy->priv->connection, + proxy->priv->name, + proxy->priv->interface_name, + NULL, /* member */ + proxy->priv->object_path, + NULL, /* arg0 */ + signal_flags, + on_signal_received, + weak_ref_new (G_OBJECT (proxy)), + (GDestroyNotify) weak_ref_free); + } + + if (proxy->priv->name != NULL && + (g_dbus_connection_get_flags (proxy->priv->connection) & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION)) + { + proxy->priv->name_owner_changed_subscription_id = + g_dbus_connection_signal_subscribe (proxy->priv->connection, + "org.freedesktop.DBus", /* name */ + "org.freedesktop.DBus", /* interface */ + "NameOwnerChanged", /* signal name */ + "/org/freedesktop/DBus", /* path */ + proxy->priv->name, /* arg0 */ + signal_flags, + on_name_owner_changed, + weak_ref_new (G_OBJECT (proxy)), + (GDestroyNotify) weak_ref_free); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* initialization is split into two parts - the first is the + * non-blocking part that requires the callers GMainContext - the + * second is a blocking part async part that doesn't require the + * callers GMainContext.. we do this split so the code can be reused + * in the GInitable implementation below. + * + * Note that obtaining a GDBusConnection is not shared between the two + * paths. + */ + +static void +init_second_async_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + GError *error = NULL; + + if (async_initable_init_second_finish (G_ASYNC_INITABLE (source_object), res, &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +static void +get_connection_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + GDBusProxy *proxy = g_task_get_source_object (task); + GError *error; + + error = NULL; + proxy->priv->connection = g_bus_get_finish (res, &error); + if (proxy->priv->connection == NULL) + { + g_task_return_error (task, error); + g_object_unref (task); + } + else + { + async_initable_init_first (G_ASYNC_INITABLE (proxy)); + async_initable_init_second_async (G_ASYNC_INITABLE (proxy), + g_task_get_priority (task), + g_task_get_cancellable (task), + init_second_async_cb, + task); + } +} + +static void +async_initable_init_async (GAsyncInitable *initable, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (initable); + GTask *task; + + task = g_task_new (proxy, cancellable, callback, user_data); + g_task_set_source_tag (task, async_initable_init_async); + g_task_set_name (task, "[gio] D-Bus proxy init"); + g_task_set_priority (task, io_priority); + + if (proxy->priv->bus_type != G_BUS_TYPE_NONE) + { + g_assert (proxy->priv->connection == NULL); + + g_bus_get (proxy->priv->bus_type, + cancellable, + get_connection_cb, + task); + } + else + { + async_initable_init_first (initable); + async_initable_init_second_async (initable, io_priority, cancellable, + init_second_async_cb, task); + } +} + +static gboolean +async_initable_init_finish (GAsyncInitable *initable, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +async_initable_iface_init (GAsyncInitableIface *async_initable_iface) +{ + async_initable_iface->init_async = async_initable_init_async; + async_initable_iface->init_finish = async_initable_init_finish; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GMainContext *context; + GMainLoop *loop; + GAsyncResult *res; +} InitableAsyncInitableData; + +static void +async_initable_init_async_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + InitableAsyncInitableData *data = user_data; + data->res = g_object_ref (res); + g_main_loop_quit (data->loop); +} + +/* Simply reuse the GAsyncInitable implementation but run the first + * part (that is non-blocking and requires the callers GMainContext) + * with the callers GMainContext.. and the second with a private + * GMainContext (bug 621310 is slightly related). + * + * Note that obtaining a GDBusConnection is not shared between the two + * paths. + */ +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GDBusProxy *proxy = G_DBUS_PROXY (initable); + InitableAsyncInitableData *data; + gboolean ret; + + ret = FALSE; + + if (proxy->priv->bus_type != G_BUS_TYPE_NONE) + { + g_assert (proxy->priv->connection == NULL); + proxy->priv->connection = g_bus_get_sync (proxy->priv->bus_type, + cancellable, + error); + if (proxy->priv->connection == NULL) + goto out; + } + + async_initable_init_first (G_ASYNC_INITABLE (initable)); + + data = g_new0 (InitableAsyncInitableData, 1); + data->context = g_main_context_new (); + data->loop = g_main_loop_new (data->context, FALSE); + + g_main_context_push_thread_default (data->context); + + async_initable_init_second_async (G_ASYNC_INITABLE (initable), + G_PRIORITY_DEFAULT, + cancellable, + async_initable_init_async_cb, + data); + + g_main_loop_run (data->loop); + + ret = async_initable_init_second_finish (G_ASYNC_INITABLE (initable), + data->res, + error); + + g_main_context_pop_thread_default (data->context); + + g_main_context_unref (data->context); + g_main_loop_unref (data->loop); + g_object_unref (data->res); + g_free (data); + + out: + + return ret; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = initable_init; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_proxy_new: + * @connection: A #GDBusConnection. + * @flags: Flags used when constructing the proxy. + * @info: (nullable): A #GDBusInterfaceInfo specifying the minimal interface that @proxy conforms to or %NULL. + * @name: (nullable): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. + * @object_path: An object path. + * @interface_name: A D-Bus interface name. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @callback: Callback function to invoke when the proxy is ready. + * @user_data: User data to pass to @callback. + * + * Creates a proxy for accessing @interface_name on the remote object + * at @object_path owned by @name at @connection and asynchronously + * loads D-Bus properties unless the + * %G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES flag is used. Connect to + * the #GDBusProxy::g-properties-changed signal to get notified about + * property changes. + * + * If the %G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS flag is not set, also sets up + * match rules for signals. Connect to the #GDBusProxy::g-signal signal + * to handle signals from the remote object. + * + * If both %G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES and + * %G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS are set, this constructor is + * guaranteed to complete immediately without blocking. + * + * If @name is a well-known name and the + * %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START and %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION + * flags aren't set and no name owner currently exists, the message bus + * will be requested to launch a name owner for the name. + * + * This is a failable asynchronous constructor - when the proxy is + * ready, @callback will be invoked and you can use + * g_dbus_proxy_new_finish() to get the result. + * + * See g_dbus_proxy_new_sync() and for a synchronous version of this constructor. + * + * #GDBusProxy is used in this [example][gdbus-wellknown-proxy]. + * + * Since: 2.26 + */ +void +g_dbus_proxy_new (GDBusConnection *connection, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + _g_dbus_initialize (); + + g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); + g_return_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) || g_dbus_is_name (name)); + g_return_if_fail (g_variant_is_object_path (object_path)); + g_return_if_fail (g_dbus_is_interface_name (interface_name)); + + g_async_initable_new_async (G_TYPE_DBUS_PROXY, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + "g-flags", flags, + "g-interface-info", info, + "g-name", name, + "g-connection", connection, + "g-object-path", object_path, + "g-interface-name", interface_name, + NULL); +} + +/** + * g_dbus_proxy_new_finish: + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback function passed to g_dbus_proxy_new(). + * @error: Return location for error or %NULL. + * + * Finishes creating a #GDBusProxy. + * + * Returns: (transfer full): A #GDBusProxy or %NULL if @error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusProxy * +g_dbus_proxy_new_finish (GAsyncResult *res, + GError **error) +{ + GObject *object; + GObject *source_object; + + source_object = g_async_result_get_source_object (res); + g_assert (source_object != NULL); + + object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), + res, + error); + g_object_unref (source_object); + + if (object != NULL) + return G_DBUS_PROXY (object); + else + return NULL; +} + +/** + * g_dbus_proxy_new_sync: + * @connection: A #GDBusConnection. + * @flags: Flags used when constructing the proxy. + * @info: (nullable): A #GDBusInterfaceInfo specifying the minimal interface that @proxy conforms to or %NULL. + * @name: (nullable): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. + * @object_path: An object path. + * @interface_name: A D-Bus interface name. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @error: (nullable): Return location for error or %NULL. + * + * Creates a proxy for accessing @interface_name on the remote object + * at @object_path owned by @name at @connection and synchronously + * loads D-Bus properties unless the + * %G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES flag is used. + * + * If the %G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS flag is not set, also sets up + * match rules for signals. Connect to the #GDBusProxy::g-signal signal + * to handle signals from the remote object. + * + * If both %G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES and + * %G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS are set, this constructor is + * guaranteed to return immediately without blocking. + * + * If @name is a well-known name and the + * %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START and %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION + * flags aren't set and no name owner currently exists, the message bus + * will be requested to launch a name owner for the name. + * + * This is a synchronous failable constructor. See g_dbus_proxy_new() + * and g_dbus_proxy_new_finish() for the asynchronous version. + * + * #GDBusProxy is used in this [example][gdbus-wellknown-proxy]. + * + * Returns: (transfer full): A #GDBusProxy or %NULL if error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusProxy * +g_dbus_proxy_new_sync (GDBusConnection *connection, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GError **error) +{ + GInitable *initable; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) || + g_dbus_is_name (name), NULL); + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); + + initable = g_initable_new (G_TYPE_DBUS_PROXY, + cancellable, + error, + "g-flags", flags, + "g-interface-info", info, + "g-name", name, + "g-connection", connection, + "g-object-path", object_path, + "g-interface-name", interface_name, + NULL); + if (initable != NULL) + return G_DBUS_PROXY (initable); + else + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_proxy_new_for_bus: + * @bus_type: A #GBusType. + * @flags: Flags used when constructing the proxy. + * @info: (nullable): A #GDBusInterfaceInfo specifying the minimal interface that @proxy conforms to or %NULL. + * @name: A bus name (well-known or unique). + * @object_path: An object path. + * @interface_name: A D-Bus interface name. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @callback: Callback function to invoke when the proxy is ready. + * @user_data: User data to pass to @callback. + * + * Like g_dbus_proxy_new() but takes a #GBusType instead of a #GDBusConnection. + * + * #GDBusProxy is used in this [example][gdbus-wellknown-proxy]. + * + * Since: 2.26 + */ +void +g_dbus_proxy_new_for_bus (GBusType bus_type, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + _g_dbus_initialize (); + + g_return_if_fail (g_dbus_is_name (name)); + g_return_if_fail (g_variant_is_object_path (object_path)); + g_return_if_fail (g_dbus_is_interface_name (interface_name)); + + g_async_initable_new_async (G_TYPE_DBUS_PROXY, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + "g-flags", flags, + "g-interface-info", info, + "g-name", name, + "g-bus-type", bus_type, + "g-object-path", object_path, + "g-interface-name", interface_name, + NULL); +} + +/** + * g_dbus_proxy_new_for_bus_finish: + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback function passed to g_dbus_proxy_new_for_bus(). + * @error: Return location for error or %NULL. + * + * Finishes creating a #GDBusProxy. + * + * Returns: (transfer full): A #GDBusProxy or %NULL if @error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusProxy * +g_dbus_proxy_new_for_bus_finish (GAsyncResult *res, + GError **error) +{ + return g_dbus_proxy_new_finish (res, error); +} + +/** + * g_dbus_proxy_new_for_bus_sync: + * @bus_type: A #GBusType. + * @flags: Flags used when constructing the proxy. + * @info: (nullable): A #GDBusInterfaceInfo specifying the minimal interface + * that @proxy conforms to or %NULL. + * @name: A bus name (well-known or unique). + * @object_path: An object path. + * @interface_name: A D-Bus interface name. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Like g_dbus_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection. + * + * #GDBusProxy is used in this [example][gdbus-wellknown-proxy]. + * + * Returns: (transfer full): A #GDBusProxy or %NULL if error is set. + * Free with g_object_unref(). + * + * Since: 2.26 + */ +GDBusProxy * +g_dbus_proxy_new_for_bus_sync (GBusType bus_type, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GError **error) +{ + GInitable *initable; + + _g_dbus_initialize (); + + g_return_val_if_fail (g_dbus_is_name (name), NULL); + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); + + initable = g_initable_new (G_TYPE_DBUS_PROXY, + cancellable, + error, + "g-flags", flags, + "g-interface-info", info, + "g-name", name, + "g-bus-type", bus_type, + "g-object-path", object_path, + "g-interface-name", interface_name, + NULL); + if (initable != NULL) + return G_DBUS_PROXY (initable); + else + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_proxy_get_connection: + * @proxy: A #GDBusProxy. + * + * Gets the connection @proxy is for. + * + * Returns: (transfer none) (not nullable): A #GDBusConnection owned by @proxy. Do not free. + * + * Since: 2.26 + */ +GDBusConnection * +g_dbus_proxy_get_connection (GDBusProxy *proxy) +{ + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + return proxy->priv->connection; +} + +/** + * g_dbus_proxy_get_flags: + * @proxy: A #GDBusProxy. + * + * Gets the flags that @proxy was constructed with. + * + * Returns: Flags from the #GDBusProxyFlags enumeration. + * + * Since: 2.26 + */ +GDBusProxyFlags +g_dbus_proxy_get_flags (GDBusProxy *proxy) +{ + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), 0); + return proxy->priv->flags; +} + +/** + * g_dbus_proxy_get_name: + * @proxy: A #GDBusProxy. + * + * Gets the name that @proxy was constructed for. + * + * When connected to a message bus, this will usually be non-%NULL. + * However, it may be %NULL for a proxy that communicates using a peer-to-peer + * pattern. + * + * Returns: (nullable): A string owned by @proxy. Do not free. + * + * Since: 2.26 + */ +const gchar * +g_dbus_proxy_get_name (GDBusProxy *proxy) +{ + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + return proxy->priv->name; +} + +/** + * g_dbus_proxy_get_name_owner: + * @proxy: A #GDBusProxy. + * + * The unique name that owns the name that @proxy is for or %NULL if + * no-one currently owns that name. You may connect to the + * #GObject::notify signal to track changes to the + * #GDBusProxy:g-name-owner property. + * + * Returns: (transfer full) (nullable): The name owner or %NULL if no name + * owner exists. Free with g_free(). + * + * Since: 2.26 + */ +gchar * +g_dbus_proxy_get_name_owner (GDBusProxy *proxy) +{ + gchar *ret; + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + + G_LOCK (properties_lock); + ret = g_strdup (proxy->priv->name_owner); + G_UNLOCK (properties_lock); + return ret; +} + +/** + * g_dbus_proxy_get_object_path: + * @proxy: A #GDBusProxy. + * + * Gets the object path @proxy is for. + * + * Returns: (not nullable): A string owned by @proxy. Do not free. + * + * Since: 2.26 + */ +const gchar * +g_dbus_proxy_get_object_path (GDBusProxy *proxy) +{ + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + return proxy->priv->object_path; +} + +/** + * g_dbus_proxy_get_interface_name: + * @proxy: A #GDBusProxy. + * + * Gets the D-Bus interface name @proxy is for. + * + * Returns: (not nullable): A string owned by @proxy. Do not free. + * + * Since: 2.26 + */ +const gchar * +g_dbus_proxy_get_interface_name (GDBusProxy *proxy) +{ + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + return proxy->priv->interface_name; +} + +/** + * g_dbus_proxy_get_default_timeout: + * @proxy: A #GDBusProxy. + * + * Gets the timeout to use if -1 (specifying default timeout) is + * passed as @timeout_msec in the g_dbus_proxy_call() and + * g_dbus_proxy_call_sync() functions. + * + * See the #GDBusProxy:g-default-timeout property for more details. + * + * Returns: Timeout to use for @proxy. + * + * Since: 2.26 + */ +gint +g_dbus_proxy_get_default_timeout (GDBusProxy *proxy) +{ + gint ret; + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), -1); + + G_LOCK (properties_lock); + ret = proxy->priv->timeout_msec; + G_UNLOCK (properties_lock); + return ret; +} + +/** + * g_dbus_proxy_set_default_timeout: + * @proxy: A #GDBusProxy. + * @timeout_msec: Timeout in milliseconds. + * + * Sets the timeout to use if -1 (specifying default timeout) is + * passed as @timeout_msec in the g_dbus_proxy_call() and + * g_dbus_proxy_call_sync() functions. + * + * See the #GDBusProxy:g-default-timeout property for more details. + * + * Since: 2.26 + */ +void +g_dbus_proxy_set_default_timeout (GDBusProxy *proxy, + gint timeout_msec) +{ + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); + g_return_if_fail (timeout_msec == -1 || timeout_msec >= 0); + + G_LOCK (properties_lock); + + if (proxy->priv->timeout_msec != timeout_msec) + { + proxy->priv->timeout_msec = timeout_msec; + G_UNLOCK (properties_lock); + + g_object_notify (G_OBJECT (proxy), "g-default-timeout"); + } + else + { + G_UNLOCK (properties_lock); + } +} + +/** + * g_dbus_proxy_get_interface_info: + * @proxy: A #GDBusProxy + * + * Returns the #GDBusInterfaceInfo, if any, specifying the interface + * that @proxy conforms to. See the #GDBusProxy:g-interface-info + * property for more details. + * + * Returns: (transfer none) (nullable): A #GDBusInterfaceInfo or %NULL. + * Do not unref the returned object, it is owned by @proxy. + * + * Since: 2.26 + */ +GDBusInterfaceInfo * +g_dbus_proxy_get_interface_info (GDBusProxy *proxy) +{ + GDBusInterfaceInfo *ret; + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + + G_LOCK (properties_lock); + ret = proxy->priv->expected_interface; + G_UNLOCK (properties_lock); + /* FIXME: returning a borrowed ref with no guarantee that nobody will + * call g_dbus_proxy_set_interface_info() and make it invalid... + */ + return ret; +} + +/** + * g_dbus_proxy_set_interface_info: + * @proxy: A #GDBusProxy + * @info: (transfer none) (nullable): Minimum interface this proxy conforms to + * or %NULL to unset. + * + * Ensure that interactions with @proxy conform to the given + * interface. See the #GDBusProxy:g-interface-info property for more + * details. + * + * Since: 2.26 + */ +void +g_dbus_proxy_set_interface_info (GDBusProxy *proxy, + GDBusInterfaceInfo *info) +{ + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); + G_LOCK (properties_lock); + + if (proxy->priv->expected_interface != NULL) + { + g_dbus_interface_info_cache_release (proxy->priv->expected_interface); + g_dbus_interface_info_unref (proxy->priv->expected_interface); + } + proxy->priv->expected_interface = info != NULL ? g_dbus_interface_info_ref (info) : NULL; + if (proxy->priv->expected_interface != NULL) + g_dbus_interface_info_cache_build (proxy->priv->expected_interface); + + G_UNLOCK (properties_lock); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +maybe_split_method_name (const gchar *method_name, + gchar **out_interface_name, + const gchar **out_method_name) +{ + gboolean was_split; + + was_split = FALSE; + g_assert (out_interface_name != NULL); + g_assert (out_method_name != NULL); + *out_interface_name = NULL; + *out_method_name = NULL; + + if (strchr (method_name, '.') != NULL) + { + gchar *p; + gchar *last_dot; + + p = g_strdup (method_name); + last_dot = strrchr (p, '.'); + *last_dot = '\0'; + + *out_interface_name = p; + *out_method_name = last_dot + 1; + + was_split = TRUE; + } + + return was_split; +} + +typedef struct +{ + GVariant *value; +#ifdef G_OS_UNIX + GUnixFDList *fd_list; +#endif +} ReplyData; + +static void +reply_data_free (ReplyData *data) +{ + g_variant_unref (data->value); +#ifdef G_OS_UNIX + if (data->fd_list != NULL) + g_object_unref (data->fd_list); +#endif + g_slice_free (ReplyData, data); +} + +static void +reply_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + GVariant *value; + GError *error; +#ifdef G_OS_UNIX + GUnixFDList *fd_list; +#endif + + error = NULL; +#ifdef G_OS_UNIX + value = g_dbus_connection_call_with_unix_fd_list_finish (connection, + &fd_list, + res, + &error); +#else + value = g_dbus_connection_call_finish (connection, + res, + &error); +#endif + if (error != NULL) + { + g_task_return_error (task, error); + } + else + { + ReplyData *data; + data = g_slice_new0 (ReplyData); + data->value = value; +#ifdef G_OS_UNIX + data->fd_list = fd_list; +#endif + g_task_return_pointer (task, data, (GDestroyNotify) reply_data_free); + } + + g_object_unref (task); +} + +/* properties_lock must be held for as long as you will keep the + * returned value + */ +static const GDBusMethodInfo * +lookup_method_info (GDBusProxy *proxy, + const gchar *method_name) +{ + const GDBusMethodInfo *info = NULL; + + if (proxy->priv->expected_interface == NULL) + goto out; + + info = g_dbus_interface_info_lookup_method (proxy->priv->expected_interface, method_name); + +out: + return info; +} + +/* properties_lock must be held for as long as you will keep the + * returned value + */ +static const gchar * +get_destination_for_call (GDBusProxy *proxy) +{ + const gchar *ret; + + ret = NULL; + + /* If proxy->priv->name is a unique name, then proxy->priv->name_owner + * is never NULL and always the same as proxy->priv->name. We use this + * knowledge to avoid checking if proxy->priv->name is a unique or + * well-known name. + */ + ret = proxy->priv->name_owner; + if (ret != NULL) + goto out; + + if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) + goto out; + + ret = proxy->priv->name; + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +g_dbus_proxy_call_internal (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + gboolean was_split; + gchar *split_interface_name; + const gchar *split_method_name; + const gchar *target_method_name; + const gchar *target_interface_name; + gchar *destination; + GVariantType *reply_type; + GAsyncReadyCallback my_callback; + + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); + g_return_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name)); + g_return_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); + g_return_if_fail (timeout_msec == -1 || timeout_msec >= 0); +#ifdef G_OS_UNIX + g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list)); +#else + g_return_if_fail (fd_list == NULL); +#endif + + reply_type = NULL; + split_interface_name = NULL; + + /* g_dbus_connection_call() is optimised for the case of a NULL + * callback. If we get a NULL callback from our user then make sure + * we pass along a NULL callback for ourselves as well. + */ + if (callback != NULL) + { + my_callback = (GAsyncReadyCallback) reply_cb; + task = g_task_new (proxy, cancellable, callback, user_data); + g_task_set_source_tag (task, g_dbus_proxy_call_internal); + g_task_set_name (task, "[gio] D-Bus proxy call"); + } + else + { + my_callback = NULL; + task = NULL; + } + + G_LOCK (properties_lock); + + was_split = maybe_split_method_name (method_name, &split_interface_name, &split_method_name); + target_method_name = was_split ? split_method_name : method_name; + target_interface_name = was_split ? split_interface_name : proxy->priv->interface_name; + + /* Warn if method is unexpected (cf. :g-interface-info) */ + if (!was_split) + { + const GDBusMethodInfo *expected_method_info; + expected_method_info = lookup_method_info (proxy, target_method_name); + if (expected_method_info != NULL) + reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args); + } + + destination = NULL; + if (proxy->priv->name != NULL) + { + destination = g_strdup (get_destination_for_call (proxy)); + if (destination == NULL) + { + if (task != NULL) + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Cannot invoke method; proxy is for the well-known name %s without an owner, and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"), + proxy->priv->name); + g_object_unref (task); + } + G_UNLOCK (properties_lock); + goto out; + } + } + + G_UNLOCK (properties_lock); + +#ifdef G_OS_UNIX + g_dbus_connection_call_with_unix_fd_list (proxy->priv->connection, + destination, + proxy->priv->object_path, + target_interface_name, + target_method_name, + parameters, + reply_type, + flags, + timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec, + fd_list, + cancellable, + my_callback, + task); +#else + g_dbus_connection_call (proxy->priv->connection, + destination, + proxy->priv->object_path, + target_interface_name, + target_method_name, + parameters, + reply_type, + flags, + timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec, + cancellable, + my_callback, + task); +#endif + + out: + if (reply_type != NULL) + g_variant_type_free (reply_type); + + g_free (destination); + g_free (split_interface_name); +} + +static GVariant * +g_dbus_proxy_call_finish_internal (GDBusProxy *proxy, + GUnixFDList **out_fd_list, + GAsyncResult *res, + GError **error) +{ + GVariant *value; + ReplyData *data; + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + g_return_val_if_fail (g_task_is_valid (res, proxy), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + value = NULL; + + data = g_task_propagate_pointer (G_TASK (res), error); + if (!data) + goto out; + + value = g_variant_ref (data->value); +#ifdef G_OS_UNIX + if (out_fd_list != NULL) + *out_fd_list = data->fd_list != NULL ? g_object_ref (data->fd_list) : NULL; +#endif + reply_data_free (data); + + out: + return value; +} + +static GVariant * +g_dbus_proxy_call_sync_internal (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GUnixFDList **out_fd_list, + GCancellable *cancellable, + GError **error) +{ + GVariant *ret; + gboolean was_split; + gchar *split_interface_name; + const gchar *split_method_name; + const gchar *target_method_name; + const gchar *target_interface_name; + gchar *destination; + GVariantType *reply_type; + + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL); + g_return_val_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name), NULL); + g_return_val_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL); + g_return_val_if_fail (timeout_msec == -1 || timeout_msec >= 0, NULL); +#ifdef G_OS_UNIX + g_return_val_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list), NULL); +#else + g_return_val_if_fail (fd_list == NULL, NULL); +#endif + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + reply_type = NULL; + + G_LOCK (properties_lock); + + was_split = maybe_split_method_name (method_name, &split_interface_name, &split_method_name); + target_method_name = was_split ? split_method_name : method_name; + target_interface_name = was_split ? split_interface_name : proxy->priv->interface_name; + + /* Warn if method is unexpected (cf. :g-interface-info) */ + if (!was_split) + { + const GDBusMethodInfo *expected_method_info; + expected_method_info = lookup_method_info (proxy, target_method_name); + if (expected_method_info != NULL) + reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args); + } + + destination = NULL; + if (proxy->priv->name != NULL) + { + destination = g_strdup (get_destination_for_call (proxy)); + if (destination == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Cannot invoke method; proxy is for the well-known name %s without an owner, and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"), + proxy->priv->name); + ret = NULL; + G_UNLOCK (properties_lock); + goto out; + } + } + + G_UNLOCK (properties_lock); + +#ifdef G_OS_UNIX + ret = g_dbus_connection_call_with_unix_fd_list_sync (proxy->priv->connection, + destination, + proxy->priv->object_path, + target_interface_name, + target_method_name, + parameters, + reply_type, + flags, + timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec, + fd_list, + out_fd_list, + cancellable, + error); +#else + ret = g_dbus_connection_call_sync (proxy->priv->connection, + destination, + proxy->priv->object_path, + target_interface_name, + target_method_name, + parameters, + reply_type, + flags, + timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec, + cancellable, + error); +#endif + + out: + if (reply_type != NULL) + g_variant_type_free (reply_type); + + g_free (destination); + g_free (split_interface_name); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_proxy_call: + * @proxy: A #GDBusProxy. + * @method_name: Name of method to invoke. + * @parameters: (nullable): A #GVariant tuple with parameters for the signal or %NULL if not passing parameters. + * @flags: Flags from the #GDBusCallFlags enumeration. + * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning + * "infinite") or -1 to use the proxy default timeout. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @callback: (nullable): A #GAsyncReadyCallback to call when the request is satisfied or %NULL if you don't + * care about the result of the method invocation. + * @user_data: The data to pass to @callback. + * + * Asynchronously invokes the @method_name method on @proxy. + * + * If @method_name contains any dots, then @name is split into interface and + * method name parts. This allows using @proxy for invoking methods on + * other interfaces. + * + * If the #GDBusConnection associated with @proxy is closed then + * the operation will fail with %G_IO_ERROR_CLOSED. If + * @cancellable is canceled, the operation will fail with + * %G_IO_ERROR_CANCELLED. If @parameters contains a value not + * compatible with the D-Bus protocol, the operation fails with + * %G_IO_ERROR_INVALID_ARGUMENT. + * + * If the @parameters #GVariant is floating, it is consumed. This allows + * convenient 'inline' use of g_variant_new(), e.g.: + * |[ + * g_dbus_proxy_call (proxy, + * "TwoStrings", + * g_variant_new ("(ss)", + * "Thing One", + * "Thing Two"), + * G_DBUS_CALL_FLAGS_NONE, + * -1, + * NULL, + * (GAsyncReadyCallback) two_strings_done, + * &data); + * ]| + * + * If @proxy has an expected interface (see + * #GDBusProxy:g-interface-info) and @method_name is referenced by it, + * then the return value is checked against the return type. + * + * This is an asynchronous method. When the operation is finished, + * @callback will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this method from. + * You can then call g_dbus_proxy_call_finish() to get the result of + * the operation. See g_dbus_proxy_call_sync() for the synchronous + * version of this method. + * + * If @callback is %NULL then the D-Bus method call message will be sent with + * the %G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED flag set. + * + * Since: 2.26 + */ +void +g_dbus_proxy_call (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_dbus_proxy_call_internal (proxy, method_name, parameters, flags, timeout_msec, NULL, cancellable, callback, user_data); +} + +/** + * g_dbus_proxy_call_finish: + * @proxy: A #GDBusProxy. + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_proxy_call(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with g_dbus_proxy_call(). + * + * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with + * return values. Free with g_variant_unref(). + * + * Since: 2.26 + */ +GVariant * +g_dbus_proxy_call_finish (GDBusProxy *proxy, + GAsyncResult *res, + GError **error) +{ + return g_dbus_proxy_call_finish_internal (proxy, NULL, res, error); +} + +/** + * g_dbus_proxy_call_sync: + * @proxy: A #GDBusProxy. + * @method_name: Name of method to invoke. + * @parameters: (nullable): A #GVariant tuple with parameters for the signal + * or %NULL if not passing parameters. + * @flags: Flags from the #GDBusCallFlags enumeration. + * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning + * "infinite") or -1 to use the proxy default timeout. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Synchronously invokes the @method_name method on @proxy. + * + * If @method_name contains any dots, then @name is split into interface and + * method name parts. This allows using @proxy for invoking methods on + * other interfaces. + * + * If the #GDBusConnection associated with @proxy is disconnected then + * the operation will fail with %G_IO_ERROR_CLOSED. If + * @cancellable is canceled, the operation will fail with + * %G_IO_ERROR_CANCELLED. If @parameters contains a value not + * compatible with the D-Bus protocol, the operation fails with + * %G_IO_ERROR_INVALID_ARGUMENT. + * + * If the @parameters #GVariant is floating, it is consumed. This allows + * convenient 'inline' use of g_variant_new(), e.g.: + * |[ + * g_dbus_proxy_call_sync (proxy, + * "TwoStrings", + * g_variant_new ("(ss)", + * "Thing One", + * "Thing Two"), + * G_DBUS_CALL_FLAGS_NONE, + * -1, + * NULL, + * &error); + * ]| + * + * The calling thread is blocked until a reply is received. See + * g_dbus_proxy_call() for the asynchronous version of this + * method. + * + * If @proxy has an expected interface (see + * #GDBusProxy:g-interface-info) and @method_name is referenced by it, + * then the return value is checked against the return type. + * + * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with + * return values. Free with g_variant_unref(). + * + * Since: 2.26 + */ +GVariant * +g_dbus_proxy_call_sync (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error) +{ + return g_dbus_proxy_call_sync_internal (proxy, method_name, parameters, flags, timeout_msec, NULL, NULL, cancellable, error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_UNIX + +/** + * g_dbus_proxy_call_with_unix_fd_list: + * @proxy: A #GDBusProxy. + * @method_name: Name of method to invoke. + * @parameters: (nullable): A #GVariant tuple with parameters for the signal or %NULL if not passing parameters. + * @flags: Flags from the #GDBusCallFlags enumeration. + * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning + * "infinite") or -1 to use the proxy default timeout. + * @fd_list: (nullable): A #GUnixFDList or %NULL. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @callback: (nullable): A #GAsyncReadyCallback to call when the request is satisfied or %NULL if you don't + * care about the result of the method invocation. + * @user_data: The data to pass to @callback. + * + * Like g_dbus_proxy_call() but also takes a #GUnixFDList object. + * + * This method is only available on UNIX. + * + * Since: 2.30 + */ +void +g_dbus_proxy_call_with_unix_fd_list (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_dbus_proxy_call_internal (proxy, method_name, parameters, flags, timeout_msec, fd_list, cancellable, callback, user_data); +} + +/** + * g_dbus_proxy_call_with_unix_fd_list_finish: + * @proxy: A #GDBusProxy. + * @out_fd_list: (out) (optional): Return location for a #GUnixFDList or %NULL. + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_proxy_call_with_unix_fd_list(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with g_dbus_proxy_call_with_unix_fd_list(). + * + * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with + * return values. Free with g_variant_unref(). + * + * Since: 2.30 + */ +GVariant * +g_dbus_proxy_call_with_unix_fd_list_finish (GDBusProxy *proxy, + GUnixFDList **out_fd_list, + GAsyncResult *res, + GError **error) +{ + return g_dbus_proxy_call_finish_internal (proxy, out_fd_list, res, error); +} + +/** + * g_dbus_proxy_call_with_unix_fd_list_sync: + * @proxy: A #GDBusProxy. + * @method_name: Name of method to invoke. + * @parameters: (nullable): A #GVariant tuple with parameters for the signal + * or %NULL if not passing parameters. + * @flags: Flags from the #GDBusCallFlags enumeration. + * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning + * "infinite") or -1 to use the proxy default timeout. + * @fd_list: (nullable): A #GUnixFDList or %NULL. + * @out_fd_list: (out) (optional): Return location for a #GUnixFDList or %NULL. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Like g_dbus_proxy_call_sync() but also takes and returns #GUnixFDList objects. + * + * This method is only available on UNIX. + * + * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with + * return values. Free with g_variant_unref(). + * + * Since: 2.30 + */ +GVariant * +g_dbus_proxy_call_with_unix_fd_list_sync (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GUnixFDList **out_fd_list, + GCancellable *cancellable, + GError **error) +{ + return g_dbus_proxy_call_sync_internal (proxy, method_name, parameters, flags, timeout_msec, fd_list, out_fd_list, cancellable, error); +} + +#endif /* G_OS_UNIX */ + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusInterfaceInfo * +_g_dbus_proxy_get_info (GDBusInterface *interface) +{ + GDBusProxy *proxy = G_DBUS_PROXY (interface); + return g_dbus_proxy_get_interface_info (proxy); +} + +static GDBusObject * +_g_dbus_proxy_get_object (GDBusInterface *interface) +{ + GDBusProxy *proxy = G_DBUS_PROXY (interface); + return proxy->priv->object; +} + +static GDBusObject * +_g_dbus_proxy_dup_object (GDBusInterface *interface) +{ + GDBusProxy *proxy = G_DBUS_PROXY (interface); + GDBusObject *ret = NULL; + + G_LOCK (properties_lock); + if (proxy->priv->object != NULL) + ret = g_object_ref (proxy->priv->object); + G_UNLOCK (properties_lock); + return ret; +} + +static void +_g_dbus_proxy_set_object (GDBusInterface *interface, + GDBusObject *object) +{ + GDBusProxy *proxy = G_DBUS_PROXY (interface); + G_LOCK (properties_lock); + if (proxy->priv->object != NULL) + g_object_remove_weak_pointer (G_OBJECT (proxy->priv->object), (gpointer *) &proxy->priv->object); + proxy->priv->object = object; + if (proxy->priv->object != NULL) + g_object_add_weak_pointer (G_OBJECT (proxy->priv->object), (gpointer *) &proxy->priv->object); + G_UNLOCK (properties_lock); +} + +static void +dbus_interface_iface_init (GDBusInterfaceIface *dbus_interface_iface) +{ + dbus_interface_iface->get_info = _g_dbus_proxy_get_info; + dbus_interface_iface->get_object = _g_dbus_proxy_get_object; + dbus_interface_iface->dup_object = _g_dbus_proxy_dup_object; + dbus_interface_iface->set_object = _g_dbus_proxy_set_object; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusproxy.h b/gio/gdbusproxy.h new file mode 100644 index 0000000..6be9871 --- /dev/null +++ b/gio/gdbusproxy.h @@ -0,0 +1,214 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_PROXY_H__ +#define __G_DBUS_PROXY_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_PROXY (g_dbus_proxy_get_type ()) +#define G_DBUS_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_PROXY, GDBusProxy)) +#define G_DBUS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_PROXY, GDBusProxyClass)) +#define G_DBUS_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_PROXY, GDBusProxyClass)) +#define G_IS_DBUS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_PROXY)) +#define G_IS_DBUS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_PROXY)) + +typedef struct _GDBusProxyClass GDBusProxyClass; +typedef struct _GDBusProxyPrivate GDBusProxyPrivate; + +/** + * GDBusProxy: + * + * The #GDBusProxy structure contains only private data and + * should only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GDBusProxy +{ + /*< private >*/ + GObject parent_instance; + GDBusProxyPrivate *priv; +}; + +/** + * GDBusProxyClass: + * @g_properties_changed: Signal class handler for the #GDBusProxy::g-properties-changed signal. + * @g_signal: Signal class handler for the #GDBusProxy::g-signal signal. + * + * Class structure for #GDBusProxy. + * + * Since: 2.26 + */ +struct _GDBusProxyClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + /* Signals */ + void (*g_properties_changed) (GDBusProxy *proxy, + GVariant *changed_properties, + const gchar* const *invalidated_properties); + void (*g_signal) (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters); + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[32]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_proxy_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +void g_dbus_proxy_new (GDBusConnection *connection, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GDBusProxy *g_dbus_proxy_new_finish (GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusProxy *g_dbus_proxy_new_sync (GDBusConnection *connection, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_dbus_proxy_new_for_bus (GBusType bus_type, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GDBusProxy *g_dbus_proxy_new_for_bus_finish (GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusProxy *g_dbus_proxy_new_for_bus_sync (GBusType bus_type, + GDBusProxyFlags flags, + GDBusInterfaceInfo *info, + const gchar *name, + const gchar *object_path, + const gchar *interface_name, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GDBusConnection *g_dbus_proxy_get_connection (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +GDBusProxyFlags g_dbus_proxy_get_flags (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_proxy_get_name (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +gchar *g_dbus_proxy_get_name_owner (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_proxy_get_object_path (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_proxy_get_interface_name (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +gint g_dbus_proxy_get_default_timeout (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +void g_dbus_proxy_set_default_timeout (GDBusProxy *proxy, + gint timeout_msec); +GLIB_AVAILABLE_IN_ALL +GDBusInterfaceInfo *g_dbus_proxy_get_interface_info (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +void g_dbus_proxy_set_interface_info (GDBusProxy *proxy, + GDBusInterfaceInfo *info); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_proxy_get_cached_property (GDBusProxy *proxy, + const gchar *property_name); +GLIB_AVAILABLE_IN_ALL +void g_dbus_proxy_set_cached_property (GDBusProxy *proxy, + const gchar *property_name, + GVariant *value); +GLIB_AVAILABLE_IN_ALL +gchar **g_dbus_proxy_get_cached_property_names (GDBusProxy *proxy); +GLIB_AVAILABLE_IN_ALL +void g_dbus_proxy_call (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_proxy_call_finish (GDBusProxy *proxy, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_proxy_call_sync (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_dbus_proxy_call_with_unix_fd_list (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_proxy_call_with_unix_fd_list_finish (GDBusProxy *proxy, + GUnixFDList **out_fd_list, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_proxy_call_with_unix_fd_list_sync (GDBusProxy *proxy, + const gchar *method_name, + GVariant *parameters, + GDBusCallFlags flags, + gint timeout_msec, + GUnixFDList *fd_list, + GUnixFDList **out_fd_list, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* __G_DBUS_PROXY_H__ */ diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c new file mode 100644 index 0000000..c83a647 --- /dev/null +++ b/gio/gdbusserver.c @@ -0,0 +1,1202 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include +#include + +#include "giotypes.h" +#include "gioerror.h" +#include "gdbusaddress.h" +#include "gdbusutils.h" +#include "gdbusconnection.h" +#include "gdbusserver.h" +#include "gioenumtypes.h" +#include "gdbusprivate.h" +#include "gdbusauthobserver.h" +#include "ginitable.h" +#include "gsocketservice.h" +#include "gthreadedsocketservice.h" +#include "gresolver.h" +#include "glib/gstdio.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "ginputstream.h" +#include "giostream.h" +#include "gmarshal-internal.h" + +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include +#endif + +#ifdef G_OS_UNIX +#include "gunixsocketaddress.h" +#endif + +#include "glibintl.h" + +#define G_DBUS_SERVER_FLAGS_ALL \ + (G_DBUS_SERVER_FLAGS_RUN_IN_THREAD | \ + G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS | \ + G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER) + +/** + * SECTION:gdbusserver + * @short_description: Helper for accepting connections + * @include: gio/gio.h + * + * #GDBusServer is a helper for listening to and accepting D-Bus + * connections. This can be used to create a new D-Bus server, allowing two + * peers to use the D-Bus protocol for their own specialized communication. + * A server instance provided in this way will not perform message routing or + * implement the org.freedesktop.DBus interface. + * + * To just export an object on a well-known name on a message bus, such as the + * session or system bus, you should instead use g_bus_own_name(). + * + * An example of peer-to-peer communication with GDBus can be found + * in [gdbus-example-peer.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-peer.c). + * + * Note that a minimal #GDBusServer will accept connections from any + * peer. In many use-cases it will be necessary to add a #GDBusAuthObserver + * that only accepts connections that have successfully authenticated + * as the same user that is running the #GDBusServer. Since GLib 2.68 this can + * be achieved more simply by passing the + * %G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER flag to the server. + */ + +/** + * GDBusServer: + * + * The #GDBusServer structure contains only private data and + * should only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GDBusServer +{ + /*< private >*/ + GObject parent_instance; + + GDBusServerFlags flags; + gchar *address; + gchar *guid; + + guchar *nonce; + gchar *nonce_file; + + gchar *client_address; + + gchar *unix_socket_path; + GSocketListener *listener; + gboolean is_using_listener; + gulong run_signal_handler_id; + + /* The result of g_main_context_ref_thread_default() when the object + * was created (the GObject _init() function) - this is used for delivery + * of the :new-connection GObject signal. + */ + GMainContext *main_context_at_construction; + + gboolean active; + + GDBusAuthObserver *authentication_observer; +}; + +typedef struct _GDBusServerClass GDBusServerClass; + +/** + * GDBusServerClass: + * @new_connection: Signal class handler for the #GDBusServer::new-connection signal. + * + * Class structure for #GDBusServer. + * + * Since: 2.26 + */ +struct _GDBusServerClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + /* Signals */ + gboolean (*new_connection) (GDBusServer *server, + GDBusConnection *connection); +}; + +enum +{ + PROP_0, + PROP_ADDRESS, + PROP_CLIENT_ADDRESS, + PROP_FLAGS, + PROP_GUID, + PROP_ACTIVE, + PROP_AUTHENTICATION_OBSERVER, +}; + +enum +{ + NEW_CONNECTION_SIGNAL, + LAST_SIGNAL, +}; + +static guint _signals[LAST_SIGNAL] = {0}; + +static void initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (GDBusServer, g_dbus_server, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)) + +static void +g_dbus_server_dispose (GObject *object) +{ + GDBusServer *server = G_DBUS_SERVER (object); + + if (server->active) + g_dbus_server_stop (server); + + G_OBJECT_CLASS (g_dbus_server_parent_class)->dispose (object); +} + +static void +g_dbus_server_finalize (GObject *object) +{ + GDBusServer *server = G_DBUS_SERVER (object); + + g_assert (!server->active); + + if (server->authentication_observer != NULL) + g_object_unref (server->authentication_observer); + + if (server->run_signal_handler_id > 0) + g_signal_handler_disconnect (server->listener, server->run_signal_handler_id); + + if (server->listener != NULL) + g_object_unref (server->listener); + + g_free (server->address); + g_free (server->guid); + g_free (server->client_address); + if (server->nonce != NULL) + { + memset (server->nonce, '\0', 16); + g_free (server->nonce); + } + + g_free (server->unix_socket_path); + g_free (server->nonce_file); + + g_main_context_unref (server->main_context_at_construction); + + G_OBJECT_CLASS (g_dbus_server_parent_class)->finalize (object); +} + +static void +g_dbus_server_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusServer *server = G_DBUS_SERVER (object); + + switch (prop_id) + { + case PROP_FLAGS: + g_value_set_flags (value, server->flags); + break; + + case PROP_GUID: + g_value_set_string (value, server->guid); + break; + + case PROP_ADDRESS: + g_value_set_string (value, server->address); + break; + + case PROP_CLIENT_ADDRESS: + g_value_set_string (value, server->client_address); + break; + + case PROP_ACTIVE: + g_value_set_boolean (value, server->active); + break; + + case PROP_AUTHENTICATION_OBSERVER: + g_value_set_object (value, server->authentication_observer); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_server_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusServer *server = G_DBUS_SERVER (object); + + switch (prop_id) + { + case PROP_FLAGS: + server->flags = g_value_get_flags (value); + break; + + case PROP_GUID: + server->guid = g_value_dup_string (value); + break; + + case PROP_ADDRESS: + server->address = g_value_dup_string (value); + break; + + case PROP_AUTHENTICATION_OBSERVER: + server->authentication_observer = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_dbus_server_class_init (GDBusServerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_dbus_server_dispose; + gobject_class->finalize = g_dbus_server_finalize; + gobject_class->set_property = g_dbus_server_set_property; + gobject_class->get_property = g_dbus_server_get_property; + + /** + * GDBusServer:flags: + * + * Flags from the #GDBusServerFlags enumeration. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_FLAGS, + g_param_spec_flags ("flags", + P_("Flags"), + P_("Flags for the server"), + G_TYPE_DBUS_SERVER_FLAGS, + G_DBUS_SERVER_FLAGS_NONE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusServer:guid: + * + * The GUID of the server. + * + * See #GDBusConnection:guid for more details. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_GUID, + g_param_spec_string ("guid", + P_("GUID"), + P_("The guid of the server"), + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusServer:address: + * + * The D-Bus address to listen on. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_ADDRESS, + g_param_spec_string ("address", + P_("Address"), + P_("The address to listen on"), + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusServer:client-address: + * + * The D-Bus address that clients can use. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_CLIENT_ADDRESS, + g_param_spec_string ("client-address", + P_("Client Address"), + P_("The address clients can use"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusServer:active: + * + * Whether the server is currently active. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_ACTIVE, + g_param_spec_boolean ("active", + P_("Active"), + P_("Whether the server is currently active"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusServer:authentication-observer: + * + * A #GDBusAuthObserver object to assist in the authentication process or %NULL. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_AUTHENTICATION_OBSERVER, + g_param_spec_object ("authentication-observer", + P_("Authentication Observer"), + P_("Object used to assist in the authentication process"), + G_TYPE_DBUS_AUTH_OBSERVER, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + + /** + * GDBusServer::new-connection: + * @server: The #GDBusServer emitting the signal. + * @connection: A #GDBusConnection for the new connection. + * + * Emitted when a new authenticated connection has been made. Use + * g_dbus_connection_get_peer_credentials() to figure out what + * identity (if any), was authenticated. + * + * If you want to accept the connection, take a reference to the + * @connection object and return %TRUE. When you are done with the + * connection call g_dbus_connection_close() and give up your + * reference. Note that the other peer may disconnect at any time - + * a typical thing to do when accepting a connection is to listen to + * the #GDBusConnection::closed signal. + * + * If #GDBusServer:flags contains %G_DBUS_SERVER_FLAGS_RUN_IN_THREAD + * then the signal is emitted in a new thread dedicated to the + * connection. Otherwise the signal is emitted in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread that @server was constructed in. + * + * You are guaranteed that signal handlers for this signal runs + * before incoming messages on @connection are processed. This means + * that it's suitable to call g_dbus_connection_register_object() or + * similar from the signal handler. + * + * Returns: %TRUE to claim @connection, %FALSE to let other handlers + * run. + * + * Since: 2.26 + */ + _signals[NEW_CONNECTION_SIGNAL] = g_signal_new (I_("new-connection"), + G_TYPE_DBUS_SERVER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDBusServerClass, new_connection), + g_signal_accumulator_true_handled, + NULL, /* accu_data */ + _g_cclosure_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, + 1, + G_TYPE_DBUS_CONNECTION); + g_signal_set_va_marshaller (_signals[NEW_CONNECTION_SIGNAL], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_BOOLEAN__OBJECTv); +} + +static void +g_dbus_server_init (GDBusServer *server) +{ + server->main_context_at_construction = g_main_context_ref_thread_default (); +} + +static gboolean +on_run (GSocketService *service, + GSocketConnection *socket_connection, + GObject *source_object, + gpointer user_data); + +/** + * g_dbus_server_new_sync: + * @address: A D-Bus address. + * @flags: Flags from the #GDBusServerFlags enumeration. + * @guid: A D-Bus GUID. + * @observer: (nullable): A #GDBusAuthObserver or %NULL. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @error: Return location for server or %NULL. + * + * Creates a new D-Bus server that listens on the first address in + * @address that works. + * + * Once constructed, you can use g_dbus_server_get_client_address() to + * get a D-Bus address string that clients can use to connect. + * + * To have control over the available authentication mechanisms and + * the users that are authorized to connect, it is strongly recommended + * to provide a non-%NULL #GDBusAuthObserver. + * + * Connect to the #GDBusServer::new-connection signal to handle + * incoming connections. + * + * The returned #GDBusServer isn't active - you have to start it with + * g_dbus_server_start(). + * + * #GDBusServer is used in this [example][gdbus-peer-to-peer]. + * + * This is a synchronous failable constructor. There is currently no + * asynchronous version. + * + * Returns: A #GDBusServer or %NULL if @error is set. Free with + * g_object_unref(). + * + * Since: 2.26 + */ +GDBusServer * +g_dbus_server_new_sync (const gchar *address, + GDBusServerFlags flags, + const gchar *guid, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GError **error) +{ + GDBusServer *server; + + g_return_val_if_fail (address != NULL, NULL); + g_return_val_if_fail (g_dbus_is_guid (guid), NULL); + g_return_val_if_fail ((flags & ~G_DBUS_SERVER_FLAGS_ALL) == 0, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + server = g_initable_new (G_TYPE_DBUS_SERVER, + cancellable, + error, + "address", address, + "flags", flags, + "guid", guid, + "authentication-observer", observer, + NULL); + + return server; +} + +/** + * g_dbus_server_get_client_address: + * @server: A #GDBusServer. + * + * Gets a + * [D-Bus address](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses) + * string that can be used by clients to connect to @server. + * + * This is valid and non-empty if initializing the #GDBusServer succeeded. + * + * Returns: (not nullable): A D-Bus address string. Do not free, the string is owned + * by @server. + * + * Since: 2.26 + */ +const gchar * +g_dbus_server_get_client_address (GDBusServer *server) +{ + g_return_val_if_fail (G_IS_DBUS_SERVER (server), NULL); + return server->client_address; +} + +/** + * g_dbus_server_get_guid: + * @server: A #GDBusServer. + * + * Gets the GUID for @server, as provided to g_dbus_server_new_sync(). + * + * Returns: (not nullable): A D-Bus GUID. Do not free this string, it is owned by @server. + * + * Since: 2.26 + */ +const gchar * +g_dbus_server_get_guid (GDBusServer *server) +{ + g_return_val_if_fail (G_IS_DBUS_SERVER (server), NULL); + return server->guid; +} + +/** + * g_dbus_server_get_flags: + * @server: A #GDBusServer. + * + * Gets the flags for @server. + * + * Returns: A set of flags from the #GDBusServerFlags enumeration. + * + * Since: 2.26 + */ +GDBusServerFlags +g_dbus_server_get_flags (GDBusServer *server) +{ + g_return_val_if_fail (G_IS_DBUS_SERVER (server), G_DBUS_SERVER_FLAGS_NONE); + return server->flags; +} + +/** + * g_dbus_server_is_active: + * @server: A #GDBusServer. + * + * Gets whether @server is active. + * + * Returns: %TRUE if server is active, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_server_is_active (GDBusServer *server) +{ + g_return_val_if_fail (G_IS_DBUS_SERVER (server), G_DBUS_SERVER_FLAGS_NONE); + return server->active; +} + +/** + * g_dbus_server_start: + * @server: A #GDBusServer. + * + * Starts @server. + * + * Since: 2.26 + */ +void +g_dbus_server_start (GDBusServer *server) +{ + g_return_if_fail (G_IS_DBUS_SERVER (server)); + if (server->active) + return; + /* Right now we don't have any transport not using the listener... */ + g_assert (server->is_using_listener); + server->run_signal_handler_id = g_signal_connect_data (G_SOCKET_SERVICE (server->listener), + "run", + G_CALLBACK (on_run), + g_object_ref (server), + (GClosureNotify) g_object_unref, + 0 /* flags */); + g_socket_service_start (G_SOCKET_SERVICE (server->listener)); + server->active = TRUE; + g_object_notify (G_OBJECT (server), "active"); +} + +/** + * g_dbus_server_stop: + * @server: A #GDBusServer. + * + * Stops @server. + * + * Since: 2.26 + */ +void +g_dbus_server_stop (GDBusServer *server) +{ + g_return_if_fail (G_IS_DBUS_SERVER (server)); + if (!server->active) + return; + /* Right now we don't have any transport not using the listener... */ + g_assert (server->is_using_listener); + g_assert (server->run_signal_handler_id > 0); + g_clear_signal_handler (&server->run_signal_handler_id, server->listener); + g_socket_service_stop (G_SOCKET_SERVICE (server->listener)); + server->active = FALSE; + g_object_notify (G_OBJECT (server), "active"); + + if (server->unix_socket_path) + { + if (g_unlink (server->unix_socket_path) != 0) + g_warning ("Failed to delete %s: %s", server->unix_socket_path, g_strerror (errno)); + } + + if (server->nonce_file) + { + if (g_unlink (server->nonce_file) != 0) + g_warning ("Failed to delete %s: %s", server->nonce_file, g_strerror (errno)); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_UNIX + +static gint +random_ascii (void) +{ + gint ret; + ret = g_random_int_range (0, 60); + if (ret < 25) + ret += 'A'; + else if (ret < 50) + ret += 'a' - 25; + else + ret += '0' - 50; + return ret; +} + +/* note that address_entry has already been validated => exactly one of path, dir, tmpdir, or abstract keys are set */ +static gboolean +try_unix (GDBusServer *server, + const gchar *address_entry, + GHashTable *key_value_pairs, + GError **error) +{ + gboolean ret; + const gchar *path; + const gchar *dir; + const gchar *tmpdir; + const gchar *abstract; + GSocketAddress *address; + + ret = FALSE; + address = NULL; + + path = g_hash_table_lookup (key_value_pairs, "path"); + dir = g_hash_table_lookup (key_value_pairs, "dir"); + tmpdir = g_hash_table_lookup (key_value_pairs, "tmpdir"); + abstract = g_hash_table_lookup (key_value_pairs, "abstract"); + + if (path != NULL) + { + address = g_unix_socket_address_new (path); + } + else if (dir != NULL || tmpdir != NULL) + { + gint n; + GString *s; + GError *local_error; + + retry: + s = g_string_new (tmpdir != NULL ? tmpdir : dir); + g_string_append (s, "/dbus-"); + for (n = 0; n < 8; n++) + g_string_append_c (s, random_ascii ()); + + /* prefer abstract namespace if available for tmpdir: addresses + * abstract namespace is disallowed for dir: addresses */ + if (tmpdir != NULL && g_unix_socket_address_abstract_names_supported ()) + address = g_unix_socket_address_new_with_type (s->str, + -1, + G_UNIX_SOCKET_ADDRESS_ABSTRACT); + else + address = g_unix_socket_address_new (s->str); + g_string_free (s, TRUE); + + local_error = NULL; + if (!g_socket_listener_add_address (server->listener, + address, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + NULL, /* source_object */ + NULL, /* effective_address */ + &local_error)) + { + if (local_error->domain == G_IO_ERROR && local_error->code == G_IO_ERROR_ADDRESS_IN_USE) + { + g_error_free (local_error); + goto retry; + } + g_propagate_error (error, local_error); + goto out; + } + ret = TRUE; + goto out; + } + else if (abstract != NULL) + { + if (!g_unix_socket_address_abstract_names_supported ()) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Abstract namespace not supported")); + goto out; + } + address = g_unix_socket_address_new_with_type (abstract, + -1, + G_UNIX_SOCKET_ADDRESS_ABSTRACT); + } + else + { + g_assert_not_reached (); + } + + if (!g_socket_listener_add_address (server->listener, + address, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + NULL, /* source_object */ + NULL, /* effective_address */ + error)) + goto out; + + ret = TRUE; + + out: + + if (address != NULL) + { + /* Fill out client_address if the connection attempt worked */ + if (ret) + { + const char *address_path; + char *escaped_path; + + server->is_using_listener = TRUE; + address_path = g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (address)); + escaped_path = g_dbus_address_escape_value (address_path); + + switch (g_unix_socket_address_get_address_type (G_UNIX_SOCKET_ADDRESS (address))) + { + case G_UNIX_SOCKET_ADDRESS_ABSTRACT: + server->client_address = g_strdup_printf ("unix:abstract=%s", escaped_path); + break; + + case G_UNIX_SOCKET_ADDRESS_PATH: + server->client_address = g_strdup_printf ("unix:path=%s", escaped_path); + server->unix_socket_path = g_strdup (address_path); + break; + + default: + g_assert_not_reached (); + break; + } + + g_free (escaped_path); + } + g_object_unref (address); + } + return ret; +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +/* note that address_entry has already been validated => + * both host and port (guaranteed to be a number in [0, 65535]) are set (family is optional) + */ +static gboolean +try_tcp (GDBusServer *server, + const gchar *address_entry, + GHashTable *key_value_pairs, + gboolean do_nonce, + GError **error) +{ + gboolean ret; + const gchar *host; + const gchar *port; + gint port_num; + GResolver *resolver; + GList *resolved_addresses; + GList *l; + + ret = FALSE; + resolver = NULL; + resolved_addresses = NULL; + + host = g_hash_table_lookup (key_value_pairs, "host"); + port = g_hash_table_lookup (key_value_pairs, "port"); + /* family = g_hash_table_lookup (key_value_pairs, "family"); */ + if (g_hash_table_lookup (key_value_pairs, "noncefile") != NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Cannot specify nonce file when creating a server")); + goto out; + } + + if (host == NULL) + host = "localhost"; + if (port == NULL) + port = "0"; + port_num = strtol (port, NULL, 10); + + resolver = g_resolver_get_default (); + resolved_addresses = g_resolver_lookup_by_name (resolver, + host, + NULL, + error); + if (resolved_addresses == NULL) + goto out; + + /* TODO: handle family */ + for (l = resolved_addresses; l != NULL; l = l->next) + { + GInetAddress *address = G_INET_ADDRESS (l->data); + GSocketAddress *socket_address; + GSocketAddress *effective_address; + + socket_address = g_inet_socket_address_new (address, port_num); + if (!g_socket_listener_add_address (server->listener, + socket_address, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, /* GObject *source_object */ + &effective_address, + error)) + { + g_object_unref (socket_address); + goto out; + } + if (port_num == 0) + /* make sure we allocate the same port number for other listeners */ + port_num = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (effective_address)); + + g_object_unref (effective_address); + g_object_unref (socket_address); + } + + if (do_nonce) + { + gint fd; + guint n; + gsize bytes_written; + gsize bytes_remaining; + char *file_escaped; + char *host_escaped; + + server->nonce = g_new0 (guchar, 16); + for (n = 0; n < 16; n++) + server->nonce[n] = g_random_int_range (0, 256); + fd = g_file_open_tmp ("gdbus-nonce-file-XXXXXX", + &server->nonce_file, + error); + if (fd == -1) + { + g_socket_listener_close (server->listener); + goto out; + } + again: + bytes_written = 0; + bytes_remaining = 16; + while (bytes_remaining > 0) + { + gssize ret; + int errsv; + + ret = write (fd, server->nonce + bytes_written, bytes_remaining); + errsv = errno; + if (ret == -1) + { + if (errsv == EINTR) + goto again; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing nonce file at “%sâ€: %s"), + server->nonce_file, + g_strerror (errsv)); + goto out; + } + bytes_written += ret; + bytes_remaining -= ret; + } + if (!g_close (fd, error)) + goto out; + host_escaped = g_dbus_address_escape_value (host); + file_escaped = g_dbus_address_escape_value (server->nonce_file); + server->client_address = g_strdup_printf ("nonce-tcp:host=%s,port=%d,noncefile=%s", + host_escaped, + port_num, + file_escaped); + g_free (host_escaped); + g_free (file_escaped); + } + else + { + server->client_address = g_strdup_printf ("tcp:host=%s,port=%d", host, port_num); + } + server->is_using_listener = TRUE; + ret = TRUE; + + out: + g_list_free_full (resolved_addresses, g_object_unref); + if (resolver) + g_object_unref (resolver); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GDBusServer *server; + GDBusConnection *connection; +} EmitIdleData; + +static void +emit_idle_data_free (EmitIdleData *data) +{ + g_object_unref (data->server); + g_object_unref (data->connection); + g_free (data); +} + +static gboolean +emit_new_connection_in_idle (gpointer user_data) +{ + EmitIdleData *data = user_data; + gboolean claimed; + + claimed = FALSE; + g_signal_emit (data->server, + _signals[NEW_CONNECTION_SIGNAL], + 0, + data->connection, + &claimed); + + if (claimed) + g_dbus_connection_start_message_processing (data->connection); + g_object_unref (data->connection); + + return FALSE; +} + +/* Called in new thread */ +static gboolean +on_run (GSocketService *service, + GSocketConnection *socket_connection, + GObject *source_object, + gpointer user_data) +{ + GDBusServer *server = G_DBUS_SERVER (user_data); + GDBusConnection *connection; + GDBusConnectionFlags connection_flags; + + if (server->nonce != NULL) + { + gchar buf[16]; + gsize bytes_read; + + if (!g_input_stream_read_all (g_io_stream_get_input_stream (G_IO_STREAM (socket_connection)), + buf, + 16, + &bytes_read, + NULL, /* GCancellable */ + NULL)) /* GError */ + goto out; + + if (bytes_read != 16) + goto out; + + if (memcmp (buf, server->nonce, 16) != 0) + goto out; + } + + connection_flags = + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | + G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING; + if (server->flags & G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS) + connection_flags |= G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; + if (server->flags & G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER) + connection_flags |= G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER; + + connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), + server->guid, + connection_flags, + server->authentication_observer, + NULL, /* GCancellable */ + NULL); /* GError */ + if (connection == NULL) + goto out; + + if (server->flags & G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) + { + gboolean claimed; + + claimed = FALSE; + g_signal_emit (server, + _signals[NEW_CONNECTION_SIGNAL], + 0, + connection, + &claimed); + if (claimed) + g_dbus_connection_start_message_processing (connection); + g_object_unref (connection); + } + else + { + GSource *idle_source; + EmitIdleData *data; + + data = g_new0 (EmitIdleData, 1); + data->server = g_object_ref (server); + data->connection = g_object_ref (connection); + + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); + g_source_set_callback (idle_source, + emit_new_connection_in_idle, + data, + (GDestroyNotify) emit_idle_data_free); + g_source_set_static_name (idle_source, "[gio] emit_new_connection_in_idle"); + g_source_attach (idle_source, server->main_context_at_construction); + g_source_unref (idle_source); + } + + out: + return TRUE; +} + +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GDBusServer *server = G_DBUS_SERVER (initable); + gboolean ret; + guint n; + gchar **addr_array; + GError *last_error; + + ret = FALSE; + addr_array = NULL; + last_error = NULL; + + if (!g_dbus_is_guid (server->guid)) + { + g_set_error (&last_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("The string “%s†is not a valid D-Bus GUID"), + server->guid); + goto out; + } + + server->listener = G_SOCKET_LISTENER (g_threaded_socket_service_new (-1)); + + addr_array = g_strsplit (server->address, ";", 0); + last_error = NULL; + for (n = 0; addr_array != NULL && addr_array[n] != NULL; n++) + { + const gchar *address_entry = addr_array[n]; + GHashTable *key_value_pairs; + gchar *transport_name; + GError *this_error; + + this_error = NULL; + if (g_dbus_is_supported_address (address_entry, + &this_error) && + _g_dbus_address_parse_entry (address_entry, + &transport_name, + &key_value_pairs, + &this_error)) + { + + if (FALSE) + { + } +#ifdef G_OS_UNIX + else if (g_strcmp0 (transport_name, "unix") == 0) + ret = try_unix (server, address_entry, key_value_pairs, &this_error); +#endif + else if (g_strcmp0 (transport_name, "tcp") == 0) + ret = try_tcp (server, address_entry, key_value_pairs, FALSE, &this_error); + else if (g_strcmp0 (transport_name, "nonce-tcp") == 0) + ret = try_tcp (server, address_entry, key_value_pairs, TRUE, &this_error); + else + g_set_error (&this_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Cannot listen on unsupported transport “%sâ€"), + transport_name); + + g_free (transport_name); + if (key_value_pairs != NULL) + g_hash_table_unref (key_value_pairs); + + if (ret) + { + g_assert (this_error == NULL); + goto out; + } + } + + if (this_error != NULL) + { + if (last_error != NULL) + g_error_free (last_error); + last_error = this_error; + } + } + + out: + + g_strfreev (addr_array); + + if (ret) + { + g_clear_error (&last_error); + } + else + { + g_assert (last_error != NULL); + g_propagate_error (error, last_error); + } + return ret; +} + + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = initable_init; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusserver.h b/gio/gdbusserver.h new file mode 100644 index 0000000..123eac4 --- /dev/null +++ b/gio/gdbusserver.h @@ -0,0 +1,60 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_SERVER_H__ +#define __G_DBUS_SERVER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_SERVER (g_dbus_server_get_type ()) +#define G_DBUS_SERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_SERVER, GDBusServer)) +#define G_IS_DBUS_SERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_SERVER)) + +GLIB_AVAILABLE_IN_ALL +GType g_dbus_server_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GDBusServer *g_dbus_server_new_sync (const gchar *address, + GDBusServerFlags flags, + const gchar *guid, + GDBusAuthObserver *observer, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_server_get_client_address (GDBusServer *server); +GLIB_AVAILABLE_IN_ALL +const gchar *g_dbus_server_get_guid (GDBusServer *server); +GLIB_AVAILABLE_IN_ALL +GDBusServerFlags g_dbus_server_get_flags (GDBusServer *server); +GLIB_AVAILABLE_IN_ALL +void g_dbus_server_start (GDBusServer *server); +GLIB_AVAILABLE_IN_ALL +void g_dbus_server_stop (GDBusServer *server); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_server_is_active (GDBusServer *server); + +G_END_DECLS + +#endif /* __G_DBUS_SERVER_H__ */ diff --git a/gio/gdbusutils.c b/gio/gdbusutils.c new file mode 100644 index 0000000..112c24e --- /dev/null +++ b/gio/gdbusutils.c @@ -0,0 +1,847 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include + +#include "gdbusutils.h" + +#include "glibintl.h" + +/** + * SECTION:gdbusutils + * @title: D-Bus Utilities + * @short_description: Various utilities related to D-Bus + * @include: gio/gio.h + * + * Various utility routines related to D-Bus. + */ + +static gboolean +is_valid_bus_name_character (gint c, + gboolean allow_hyphen) +{ + return + (c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c == '_') || + (allow_hyphen && c == '-'); +} + +static gboolean +is_valid_initial_bus_name_character (gint c, + gboolean allow_initial_digit, + gboolean allow_hyphen) +{ + if (allow_initial_digit) + return is_valid_bus_name_character (c, allow_hyphen); + else + return + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c == '_') || + (allow_hyphen && c == '-'); +} + +static gboolean +is_valid_name (const gchar *start, + guint len, + gboolean allow_initial_digit, + gboolean allow_hyphen) +{ + gboolean ret; + const gchar *s; + const gchar *end; + gboolean has_dot; + + ret = FALSE; + + if (len == 0) + goto out; + + s = start; + end = s + len; + has_dot = FALSE; + while (s != end) + { + if (*s == '.') + { + s += 1; + if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, allow_initial_digit, allow_hyphen))) + goto out; + has_dot = TRUE; + } + else if (G_UNLIKELY (!is_valid_bus_name_character (*s, allow_hyphen))) + { + goto out; + } + s += 1; + } + + if (G_UNLIKELY (!has_dot)) + goto out; + + ret = TRUE; + + out: + return ret; +} + +/** + * g_dbus_is_name: + * @string: The string to check. + * + * Checks if @string is a valid D-Bus bus name (either unique or well-known). + * + * Returns: %TRUE if valid, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_is_name (const gchar *string) +{ + guint len; + gboolean ret; + const gchar *s; + + g_return_val_if_fail (string != NULL, FALSE); + + ret = FALSE; + + len = strlen (string); + if (G_UNLIKELY (len == 0 || len > 255)) + goto out; + + s = string; + if (*s == ':') + { + /* handle unique name */ + if (!is_valid_name (s + 1, len - 1, TRUE, TRUE)) + goto out; + ret = TRUE; + goto out; + } + else if (G_UNLIKELY (*s == '.')) + { + /* can't start with a . */ + goto out; + } + else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, TRUE))) + goto out; + + ret = is_valid_name (s + 1, len - 1, FALSE, TRUE); + + out: + return ret; +} + +/** + * g_dbus_is_unique_name: + * @string: The string to check. + * + * Checks if @string is a valid D-Bus unique bus name. + * + * Returns: %TRUE if valid, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_is_unique_name (const gchar *string) +{ + gboolean ret; + guint len; + + g_return_val_if_fail (string != NULL, FALSE); + + ret = FALSE; + + len = strlen (string); + if (G_UNLIKELY (len == 0 || len > 255)) + goto out; + + if (G_UNLIKELY (*string != ':')) + goto out; + + if (G_UNLIKELY (!is_valid_name (string + 1, len - 1, TRUE, TRUE))) + goto out; + + ret = TRUE; + + out: + return ret; +} + +/** + * g_dbus_is_member_name: + * @string: The string to check. + * + * Checks if @string is a valid D-Bus member (e.g. signal or method) name. + * + * Returns: %TRUE if valid, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_is_member_name (const gchar *string) +{ + gboolean ret; + guint n; + + ret = FALSE; + if (G_UNLIKELY (string == NULL)) + goto out; + + if (G_UNLIKELY (!is_valid_initial_bus_name_character (string[0], FALSE, FALSE))) + goto out; + + for (n = 1; string[n] != '\0'; n++) + { + if (G_UNLIKELY (!is_valid_bus_name_character (string[n], FALSE))) + { + goto out; + } + } + + ret = TRUE; + + out: + return ret; +} + +/** + * g_dbus_is_interface_name: + * @string: The string to check. + * + * Checks if @string is a valid D-Bus interface name. + * + * Returns: %TRUE if valid, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_is_interface_name (const gchar *string) +{ + guint len; + gboolean ret; + const gchar *s; + + g_return_val_if_fail (string != NULL, FALSE); + + ret = FALSE; + + len = strlen (string); + if (G_UNLIKELY (len == 0 || len > 255)) + goto out; + + s = string; + if (G_UNLIKELY (*s == '.')) + { + /* can't start with a . */ + goto out; + } + else if (G_UNLIKELY (!is_valid_initial_bus_name_character (*s, FALSE, FALSE))) + goto out; + + ret = is_valid_name (s + 1, len - 1, FALSE, FALSE); + + out: + return ret; +} + +/** + * g_dbus_is_error_name: + * @string: The string to check. + * + * Check whether @string is a valid D-Bus error name. + * + * This function returns the same result as g_dbus_is_interface_name(), + * because D-Bus error names are defined to have exactly the + * same syntax as interface names. + * + * Returns: %TRUE if valid, %FALSE otherwise. + * + * Since: 2.70 + */ +gboolean +g_dbus_is_error_name (const gchar *string) +{ + /* Error names are the same syntax as interface names. + * See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-error */ + return g_dbus_is_interface_name (string); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* TODO: maybe move to glib? if so, it should conform to http://en.wikipedia.org/wiki/Guid and/or + * http://tools.ietf.org/html/rfc4122 - specifically it should have hyphens then. + */ + +/** + * g_dbus_generate_guid: + * + * Generate a D-Bus GUID that can be used with + * e.g. g_dbus_connection_new(). + * + * See the + * [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html#uuids) + * regarding what strings are valid D-Bus GUIDs. The specification refers to + * these as ‘UUIDs’ whereas GLib (for historical reasons) refers to them as + * ‘GUIDs’. The terms are interchangeable. + * + * Note that D-Bus GUIDs do not follow + * [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122). + * + * Returns: A valid D-Bus GUID. Free with g_free(). + * + * Since: 2.26 + */ +gchar * +g_dbus_generate_guid (void) +{ + GString *s; + guint32 r1; + guint32 r2; + guint32 r3; + gint64 now_us; + + s = g_string_new (NULL); + + r1 = g_random_int (); + r2 = g_random_int (); + r3 = g_random_int (); + now_us = g_get_real_time (); + + g_string_append_printf (s, "%08x", r1); + g_string_append_printf (s, "%08x", r2); + g_string_append_printf (s, "%08x", r3); + g_string_append_printf (s, "%08x", (guint32) (now_us / G_USEC_PER_SEC)); + + return g_string_free (s, FALSE); +} + +/** + * g_dbus_is_guid: + * @string: The string to check. + * + * Checks if @string is a D-Bus GUID. + * + * See the documentation for g_dbus_generate_guid() for more information about + * the format of a GUID. + * + * Returns: %TRUE if @string is a GUID, %FALSE otherwise. + * + * Since: 2.26 + */ +gboolean +g_dbus_is_guid (const gchar *string) +{ + gboolean ret; + guint n; + + g_return_val_if_fail (string != NULL, FALSE); + + ret = FALSE; + + for (n = 0; n < 32; n++) + { + if (!g_ascii_isxdigit (string[n])) + goto out; + } + if (string[32] != '\0') + goto out; + + ret = TRUE; + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_gvariant_to_gvalue: + * @value: A #GVariant. + * @out_gvalue: (out): Return location pointing to a zero-filled (uninitialized) #GValue. + * + * Converts a #GVariant to a #GValue. If @value is floating, it is consumed. + * + * The rules specified in the g_dbus_gvalue_to_gvariant() function are + * used - this function is essentially its reverse form. So, a #GVariant + * containing any basic or string array type will be converted to a #GValue + * containing a basic value or string array. Any other #GVariant (handle, + * variant, tuple, dict entry) will be converted to a #GValue containing that + * #GVariant. + * + * The conversion never fails - a valid #GValue is always returned in + * @out_gvalue. + * + * Since: 2.30 + */ +void +g_dbus_gvariant_to_gvalue (GVariant *value, + GValue *out_gvalue) +{ + const GVariantType *type; + gchar **array; + + g_return_if_fail (value != NULL); + g_return_if_fail (out_gvalue != NULL); + + memset (out_gvalue, '\0', sizeof (GValue)); + + switch (g_variant_classify (value)) + { + case G_VARIANT_CLASS_BOOLEAN: + g_value_init (out_gvalue, G_TYPE_BOOLEAN); + g_value_set_boolean (out_gvalue, g_variant_get_boolean (value)); + break; + + case G_VARIANT_CLASS_BYTE: + g_value_init (out_gvalue, G_TYPE_UCHAR); + g_value_set_uchar (out_gvalue, g_variant_get_byte (value)); + break; + + case G_VARIANT_CLASS_INT16: + g_value_init (out_gvalue, G_TYPE_INT); + g_value_set_int (out_gvalue, g_variant_get_int16 (value)); + break; + + case G_VARIANT_CLASS_UINT16: + g_value_init (out_gvalue, G_TYPE_UINT); + g_value_set_uint (out_gvalue, g_variant_get_uint16 (value)); + break; + + case G_VARIANT_CLASS_INT32: + g_value_init (out_gvalue, G_TYPE_INT); + g_value_set_int (out_gvalue, g_variant_get_int32 (value)); + break; + + case G_VARIANT_CLASS_UINT32: + g_value_init (out_gvalue, G_TYPE_UINT); + g_value_set_uint (out_gvalue, g_variant_get_uint32 (value)); + break; + + case G_VARIANT_CLASS_INT64: + g_value_init (out_gvalue, G_TYPE_INT64); + g_value_set_int64 (out_gvalue, g_variant_get_int64 (value)); + break; + + case G_VARIANT_CLASS_UINT64: + g_value_init (out_gvalue, G_TYPE_UINT64); + g_value_set_uint64 (out_gvalue, g_variant_get_uint64 (value)); + break; + + case G_VARIANT_CLASS_DOUBLE: + g_value_init (out_gvalue, G_TYPE_DOUBLE); + g_value_set_double (out_gvalue, g_variant_get_double (value)); + break; + + case G_VARIANT_CLASS_STRING: + g_value_init (out_gvalue, G_TYPE_STRING); + g_value_set_string (out_gvalue, g_variant_get_string (value, NULL)); + break; + + case G_VARIANT_CLASS_OBJECT_PATH: + g_value_init (out_gvalue, G_TYPE_STRING); + g_value_set_string (out_gvalue, g_variant_get_string (value, NULL)); + break; + + case G_VARIANT_CLASS_SIGNATURE: + g_value_init (out_gvalue, G_TYPE_STRING); + g_value_set_string (out_gvalue, g_variant_get_string (value, NULL)); + break; + + case G_VARIANT_CLASS_ARRAY: + type = g_variant_get_type (value); + switch (g_variant_type_peek_string (type)[1]) + { + case G_VARIANT_CLASS_BYTE: + g_value_init (out_gvalue, G_TYPE_STRING); + g_value_set_string (out_gvalue, g_variant_get_bytestring (value)); + break; + + case G_VARIANT_CLASS_STRING: + g_value_init (out_gvalue, G_TYPE_STRV); + array = g_variant_dup_strv (value, NULL); + g_value_take_boxed (out_gvalue, array); + break; + + case G_VARIANT_CLASS_OBJECT_PATH: + g_value_init (out_gvalue, G_TYPE_STRV); + array = g_variant_dup_objv (value, NULL); + g_value_take_boxed (out_gvalue, array); + break; + + case G_VARIANT_CLASS_ARRAY: + switch (g_variant_type_peek_string (type)[2]) + { + case G_VARIANT_CLASS_BYTE: + g_value_init (out_gvalue, G_TYPE_STRV); + array = g_variant_dup_bytestring_array (value, NULL); + g_value_take_boxed (out_gvalue, array); + break; + + default: + g_value_init (out_gvalue, G_TYPE_VARIANT); + g_value_set_variant (out_gvalue, value); + break; + } + break; + + default: + g_value_init (out_gvalue, G_TYPE_VARIANT); + g_value_set_variant (out_gvalue, value); + break; + } + break; + + case G_VARIANT_CLASS_HANDLE: + case G_VARIANT_CLASS_VARIANT: + case G_VARIANT_CLASS_MAYBE: + case G_VARIANT_CLASS_TUPLE: + case G_VARIANT_CLASS_DICT_ENTRY: + g_value_init (out_gvalue, G_TYPE_VARIANT); + g_value_set_variant (out_gvalue, value); + break; + } +} + + +/** + * g_dbus_gvalue_to_gvariant: + * @gvalue: A #GValue to convert to a #GVariant + * @type: A #GVariantType + * + * Converts a #GValue to a #GVariant of the type indicated by the @type + * parameter. + * + * The conversion is using the following rules: + * + * - `G_TYPE_STRING`: 's', 'o', 'g' or 'ay' + * - `G_TYPE_STRV`: 'as', 'ao' or 'aay' + * - `G_TYPE_BOOLEAN`: 'b' + * - `G_TYPE_UCHAR`: 'y' + * - `G_TYPE_INT`: 'i', 'n' + * - `G_TYPE_UINT`: 'u', 'q' + * - `G_TYPE_INT64`: 'x' + * - `G_TYPE_UINT64`: 't' + * - `G_TYPE_DOUBLE`: 'd' + * - `G_TYPE_VARIANT`: Any #GVariantType + * + * This can fail if e.g. @gvalue is of type %G_TYPE_STRING and @type + * is 'i', i.e. %G_VARIANT_TYPE_INT32. It will also fail for any #GType + * (including e.g. %G_TYPE_OBJECT and %G_TYPE_BOXED derived-types) not + * in the table above. + * + * Note that if @gvalue is of type %G_TYPE_VARIANT and its value is + * %NULL, the empty #GVariant instance (never %NULL) for @type is + * returned (e.g. 0 for scalar types, the empty string for string types, + * '/' for object path types, the empty array for any array type and so on). + * + * See the g_dbus_gvariant_to_gvalue() function for how to convert a + * #GVariant to a #GValue. + * + * Returns: (transfer full): A #GVariant (never floating) of + * #GVariantType @type holding the data from @gvalue or an empty #GVariant + * in case of failure. Free with g_variant_unref(). + * + * Since: 2.30 + */ +GVariant * +g_dbus_gvalue_to_gvariant (const GValue *gvalue, + const GVariantType *type) +{ + GVariant *ret; + const gchar *s; + const gchar * const *as; + const gchar *empty_strv[1] = {NULL}; + + g_return_val_if_fail (gvalue != NULL, NULL); + g_return_val_if_fail (type != NULL, NULL); + + ret = NULL; + + /* @type can easily be e.g. "s" with the GValue holding a GVariant - for example this + * can happen when using the org.gtk.GDBus.C.ForceGVariant annotation with the + * gdbus-codegen(1) tool. + */ + if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT) + { + ret = g_value_dup_variant (gvalue); + } + else + { + switch (g_variant_type_peek_string (type)[0]) + { + case G_VARIANT_CLASS_BOOLEAN: + ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue))); + break; + + case G_VARIANT_CLASS_BYTE: + ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue))); + break; + + case G_VARIANT_CLASS_INT16: + ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue))); + break; + + case G_VARIANT_CLASS_UINT16: + ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue))); + break; + + case G_VARIANT_CLASS_INT32: + ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue))); + break; + + case G_VARIANT_CLASS_UINT32: + ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue))); + break; + + case G_VARIANT_CLASS_INT64: + ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue))); + break; + + case G_VARIANT_CLASS_UINT64: + ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue))); + break; + + case G_VARIANT_CLASS_DOUBLE: + ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue))); + break; + + case G_VARIANT_CLASS_STRING: + s = g_value_get_string (gvalue); + if (s == NULL) + s = ""; + ret = g_variant_ref_sink (g_variant_new_string (s)); + break; + + case G_VARIANT_CLASS_OBJECT_PATH: + s = g_value_get_string (gvalue); + if (s == NULL) + s = "/"; + ret = g_variant_ref_sink (g_variant_new_object_path (s)); + break; + + case G_VARIANT_CLASS_SIGNATURE: + s = g_value_get_string (gvalue); + if (s == NULL) + s = ""; + ret = g_variant_ref_sink (g_variant_new_signature (s)); + break; + + case G_VARIANT_CLASS_ARRAY: + switch (g_variant_type_peek_string (type)[1]) + { + case G_VARIANT_CLASS_BYTE: + s = g_value_get_string (gvalue); + if (s == NULL) + s = ""; + ret = g_variant_ref_sink (g_variant_new_bytestring (s)); + break; + + case G_VARIANT_CLASS_STRING: + as = g_value_get_boxed (gvalue); + if (as == NULL) + as = empty_strv; + ret = g_variant_ref_sink (g_variant_new_strv (as, -1)); + break; + + case G_VARIANT_CLASS_OBJECT_PATH: + as = g_value_get_boxed (gvalue); + if (as == NULL) + as = empty_strv; + ret = g_variant_ref_sink (g_variant_new_objv (as, -1)); + break; + + case G_VARIANT_CLASS_ARRAY: + switch (g_variant_type_peek_string (type)[2]) + { + case G_VARIANT_CLASS_BYTE: + as = g_value_get_boxed (gvalue); + if (as == NULL) + as = empty_strv; + ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1)); + break; + + default: + ret = g_value_dup_variant (gvalue); + break; + } + break; + + default: + ret = g_value_dup_variant (gvalue); + break; + } + break; + + case G_VARIANT_CLASS_HANDLE: + case G_VARIANT_CLASS_VARIANT: + case G_VARIANT_CLASS_MAYBE: + case G_VARIANT_CLASS_TUPLE: + case G_VARIANT_CLASS_DICT_ENTRY: + ret = g_value_dup_variant (gvalue); + break; + } + } + + /* Could be that the GValue is holding a NULL GVariant - in that case, + * we return an "empty" GVariant instead of a NULL GVariant + */ + if (ret == NULL) + { + GVariant *untrusted_empty; + untrusted_empty = g_variant_new_from_data (type, NULL, 0, FALSE, NULL, NULL); + ret = g_variant_take_ref (g_variant_get_normal_form (untrusted_empty)); + g_variant_unref (untrusted_empty); + } + + g_assert (!g_variant_is_floating (ret)); + + return ret; +} + +/** + * g_dbus_escape_object_path_bytestring: + * @bytes: (array zero-terminated=1) (element-type guint8): the string of bytes to escape + * + * Escapes @bytes for use in a D-Bus object path component. + * @bytes is an array of zero or more nonzero bytes in an + * unspecified encoding, followed by a single zero byte. + * + * The escaping method consists of replacing all non-alphanumeric + * characters (see g_ascii_isalnum()) with their hexadecimal value + * preceded by an underscore (`_`). For example: + * `foo.bar.baz` will become `foo_2ebar_2ebaz`. + * + * This method is appropriate to use when the input is nearly + * a valid object path component but is not when your input + * is far from being a valid object path component. + * Other escaping algorithms are also valid to use with + * D-Bus object paths. + * + * This can be reversed with g_dbus_unescape_object_path(). + * + * Returns: an escaped version of @bytes. Free with g_free(). + * + * Since: 2.68 + * + */ +gchar * +g_dbus_escape_object_path_bytestring (const guint8 *bytes) +{ + GString *escaped; + const guint8 *p; + + g_return_val_if_fail (bytes != NULL, NULL); + + if (*bytes == '\0') + return g_strdup ("_"); + + escaped = g_string_new (NULL); + for (p = bytes; *p; p++) + { + if (g_ascii_isalnum (*p)) + g_string_append_c (escaped, *p); + else + g_string_append_printf (escaped, "_%02x", *p); + } + + return g_string_free (escaped, FALSE); +} + +/** + * g_dbus_escape_object_path: + * @s: the string to escape + * + * This is a language binding friendly version of g_dbus_escape_object_path_bytestring(). + * + * Returns: an escaped version of @s. Free with g_free(). + * + * Since: 2.68 + */ +gchar * +g_dbus_escape_object_path (const gchar *s) +{ + return (gchar *) g_dbus_escape_object_path_bytestring ((const guint8 *) s); +} + +/** + * g_dbus_unescape_object_path: + * @s: the string to unescape + * + * Unescapes an string that was previously escaped with + * g_dbus_escape_object_path(). If the string is in a format that could + * not have been returned by g_dbus_escape_object_path(), this function + * returns %NULL. + * + * Encoding alphanumeric characters which do not need to be + * encoded is not allowed (e.g `_63` is not valid, the string + * should contain `c` instead). + * + * Returns: (array zero-terminated=1) (element-type guint8) (nullable): an + * unescaped version of @s, or %NULL if @s is not a string returned + * from g_dbus_escape_object_path(). Free with g_free(). + * + * Since: 2.68 + */ +guint8 * +g_dbus_unescape_object_path (const gchar *s) +{ + GString *unescaped; + const gchar *p; + + g_return_val_if_fail (s != NULL, NULL); + + if (g_str_equal (s, "_")) + return (guint8 *) g_strdup (""); + + unescaped = g_string_new (NULL); + for (p = s; *p; p++) + { + gint hi, lo; + + if (g_ascii_isalnum (*p)) + { + g_string_append_c (unescaped, *p); + } + else if (*p == '_' && + ((hi = g_ascii_xdigit_value (p[1])) >= 0) && + ((lo = g_ascii_xdigit_value (p[2])) >= 0) && + (hi || lo) && /* \0 is not allowed */ + !g_ascii_isalnum ((hi << 4) | lo)) /* alnums must not be encoded */ + { + g_string_append_c (unescaped, (hi << 4) | lo); + p += 2; + } + else + { + /* the string was not encoded correctly */ + g_string_free (unescaped, TRUE); + return NULL; + } + } + + return (guint8 *) g_string_free (unescaped, FALSE); +} diff --git a/gio/gdbusutils.h b/gio/gdbusutils.h new file mode 100644 index 0000000..da8e422 --- /dev/null +++ b/gio/gdbusutils.h @@ -0,0 +1,63 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __G_DBUS_UTILS_H__ +#define __G_DBUS_UTILS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_is_guid (const gchar *string); +GLIB_AVAILABLE_IN_ALL +gchar *g_dbus_generate_guid (void); + +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_is_name (const gchar *string); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_is_unique_name (const gchar *string); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_is_member_name (const gchar *string); +GLIB_AVAILABLE_IN_ALL +gboolean g_dbus_is_interface_name (const gchar *string); +GLIB_AVAILABLE_IN_2_70 +gboolean g_dbus_is_error_name (const gchar *string); + +GLIB_AVAILABLE_IN_ALL +void g_dbus_gvariant_to_gvalue (GVariant *value, + GValue *out_gvalue); +GLIB_AVAILABLE_IN_ALL +GVariant *g_dbus_gvalue_to_gvariant (const GValue *gvalue, + const GVariantType *type); +GLIB_AVAILABLE_IN_2_68 +gchar *g_dbus_escape_object_path_bytestring (const guint8 *bytes); +GLIB_AVAILABLE_IN_2_68 +gchar *g_dbus_escape_object_path (const gchar *s); +GLIB_AVAILABLE_IN_2_68 +guint8 *g_dbus_unescape_object_path (const gchar *s); + +G_END_DECLS + +#endif /* __G_DBUS_UTILS_H__ */ diff --git a/gio/gdebugcontroller.c b/gio/gdebugcontroller.c new file mode 100644 index 0000000..c615616 --- /dev/null +++ b/gio/gdebugcontroller.c @@ -0,0 +1,119 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2021 Endless OS Foundation, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" +#include "glib.h" +#include "glibintl.h" + +#include "gdebugcontroller.h" +#include "ginitable.h" +#include "giomodule-priv.h" + +/** + * SECTION:gdebugcontroller + * @title: GDebugController + * @short_description: Debugging controller + * @include: gio/gio.h + * + * #GDebugController is an interface to expose control of debugging features and + * debug output. + * + * It is implemented on Linux using #GDebugControllerDBus, which exposes a D-Bus + * interface to allow authenticated peers to control debug features in this + * process. + * + * Whether debug output is enabled is exposed as + * #GDebugController:debug-enabled. This controls g_log_set_debug_enabled() by + * default. Application code may connect to the #GObject::notify signal for it + * to control other parts of its debug infrastructure as necessary. + * + * If your application or service is using the default GLib log writer function, + * creating one of the built-in implementations of #GDebugController should be + * all that’s needed to dynamically enable or disable debug output. + * + * Since: 2.72 + */ + +G_DEFINE_INTERFACE_WITH_CODE (GDebugController, g_debug_controller, G_TYPE_OBJECT, + g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE)) + +static void +g_debug_controller_default_init (GDebugControllerInterface *iface) +{ + /** + * GDebugController:debug-enabled: + * + * %TRUE if debug output should be exposed (for example by forwarding it to + * the journal), %FALSE otherwise. + * + * Since: 2.72 + */ + g_object_interface_install_property (iface, + g_param_spec_boolean ("debug-enabled", + "Debug Enabled", + "Whether to expose debug output", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_EXPLICIT_NOTIFY)); +} + +/** + * g_debug_controller_get_debug_enabled: + * @self: a #GDebugController + * + * Get the value of #GDebugController:debug-enabled. + * + * Returns: %TRUE if debug output should be exposed, %FALSE otherwise + * Since: 2.72 + */ +gboolean +g_debug_controller_get_debug_enabled (GDebugController *self) +{ + gboolean enabled; + + g_return_val_if_fail (G_IS_DEBUG_CONTROLLER (self), FALSE); + + g_object_get (G_OBJECT (self), + "debug-enabled", &enabled, + NULL); + + return enabled; +} + +/** + * g_debug_controller_set_debug_enabled: + * @self: a #GDebugController + * @debug_enabled: %TRUE if debug output should be exposed, %FALSE otherwise + * + * Set the value of #GDebugController:debug-enabled. + * + * Since: 2.72 + */ +void +g_debug_controller_set_debug_enabled (GDebugController *self, + gboolean debug_enabled) +{ + g_return_if_fail (G_IS_DEBUG_CONTROLLER (self)); + + g_object_set (G_OBJECT (self), + "debug-enabled", debug_enabled, + NULL); +} diff --git a/gio/gdebugcontroller.h b/gio/gdebugcontroller.h new file mode 100644 index 0000000..ca3a2d2 --- /dev/null +++ b/gio/gdebugcontroller.h @@ -0,0 +1,79 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2021 Endless OS Foundation, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef __G_DEBUG_CONTROLLER_H__ +#define __G_DEBUG_CONTROLLER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_DEBUG_CONTROLLER_EXTENSION_POINT_NAME: + * + * Extension point for debug control functionality. + * See [Extending GIO][extending-gio]. + * + * Since: 2.72 + */ +#define G_DEBUG_CONTROLLER_EXTENSION_POINT_NAME "gio-debug-controller" + +/** + * GDebugController: + * + * #GDebugController is an interface to expose control of debugging features and + * debug output. + * + * Since: 2.72 + */ +#define G_TYPE_DEBUG_CONTROLLER (g_debug_controller_get_type ()) +GLIB_AVAILABLE_IN_2_72 +G_DECLARE_INTERFACE(GDebugController, g_debug_controller, g, debug_controller, GObject) + +#define G_DEBUG_CONTROLLER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DEBUG_CONTROLLER, GDebugController)) +#define G_IS_DEBUG_CONTROLLER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DEBUG_CONTROLLER)) +#define G_DEBUG_CONTROLLER_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_DEBUG_CONTROLLER, GDebugControllerInterface)) + +/** + * GDebugControllerInterface: + * @g_iface: The parent interface. + * + * The virtual function table for #GDebugController. + * + * Since: 2.72 + */ +struct _GDebugControllerInterface { + /*< private >*/ + GTypeInterface g_iface; +}; + +GLIB_AVAILABLE_IN_2_72 +gboolean g_debug_controller_get_debug_enabled (GDebugController *self); +GLIB_AVAILABLE_IN_2_72 +void g_debug_controller_set_debug_enabled (GDebugController *self, + gboolean debug_enabled); + +G_END_DECLS + +#endif /* __G_DEBUG_CONTROLLER_H__ */ diff --git a/gio/gdebugcontrollerdbus.c b/gio/gdebugcontrollerdbus.c new file mode 100644 index 0000000..3c0ee00 --- /dev/null +++ b/gio/gdebugcontrollerdbus.c @@ -0,0 +1,709 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2021 Endless OS Foundation, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" + +#include +#include "gdebugcontroller.h" +#include "gdebugcontrollerdbus.h" +#include "giomodule-priv.h" +#include "gi18n.h" +#include "gio/gdbusprivate.h" +#include "gio/gmarshal-internal.h" + +/** + * SECTION:gdebugcontrollerdbus + * @title: GDebugControllerDBus + * @short_description: Debugging controller D-Bus implementation + * @include: gio/gio.h + * + * #GDebugControllerDBus is an implementation of #GDebugController which exposes + * debug settings as a D-Bus object. + * + * It is a #GInitable object, and will register an object at + * `/org/gtk/Debugging` on the bus given as + * #GDebugControllerDBus:connection once it’s initialized. The object will be + * unregistered when the last reference to the #GDebugControllerDBus is dropped. + * + * This D-Bus object can be used by remote processes to enable or disable debug + * output in this process. Remote processes calling + * `org.gtk.Debugging.SetDebugEnabled()` will affect the value of + * #GDebugController:debug-enabled and, by default, g_log_get_debug_enabled(). + * default. + * + * By default, all processes will be able to call `SetDebugEnabled()`. If this + * process is privileged, or might expose sensitive information in its debug + * output, you may want to restrict the ability to enable debug output to + * privileged users or processes. + * + * One option is to install a D-Bus security policy which restricts access to + * `SetDebugEnabled()`, installing something like the following in + * `$datadir/dbus-1/system.d/`: + * |[ + * + * + * + * + * + * + * + * + * + * + * ]| + * + * This will prevent the `SetDebugEnabled()` method from being called by all + * except root. It will not prevent the `DebugEnabled` property from being read, + * as it’s accessed through the `org.freedesktop.DBus.Properties` interface. + * + * Another option is to use polkit to allow or deny requests on a case-by-case + * basis, allowing for the possibility of dynamic authorisation. To do this, + * connect to the #GDebugControllerDBus::authorize signal and query polkit in + * it: + * |[ + * g_autoptr(GError) child_error = NULL; + * g_autoptr(GDBusConnection) connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); + * gulong debug_controller_authorize_id = 0; + * + * // Set up the debug controller. + * debug_controller = G_DEBUG_CONTROLLER (g_debug_controller_dbus_new (priv->connection, NULL, &child_error)); + * if (debug_controller == NULL) + * { + * g_error ("Could not register debug controller on bus: %s"), + * child_error->message); + * } + * + * debug_controller_authorize_id = g_signal_connect (debug_controller, + * "authorize", + * G_CALLBACK (debug_controller_authorize_cb), + * self); + * + * static gboolean + * debug_controller_authorize_cb (GDebugControllerDBus *debug_controller, + * GDBusMethodInvocation *invocation, + * gpointer user_data) + * { + * g_autoptr(PolkitAuthority) authority = NULL; + * g_autoptr(PolkitSubject) subject = NULL; + * g_autoptr(PolkitAuthorizationResult) auth_result = NULL; + * g_autoptr(GError) local_error = NULL; + * GDBusMessage *message; + * GDBusMessageFlags message_flags; + * PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; + * + * message = g_dbus_method_invocation_get_message (invocation); + * message_flags = g_dbus_message_get_flags (message); + * + * authority = polkit_authority_get_sync (NULL, &local_error); + * if (authority == NULL) + * { + * g_warning ("Failed to get polkit authority: %s", local_error->message); + * return FALSE; + * } + * + * if (message_flags & G_DBUS_MESSAGE_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION) + * flags |= POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION; + * + * subject = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation)); + * + * auth_result = polkit_authority_check_authorization_sync (authority, + * subject, + * "com.example.MyService.set-debug-enabled", + * NULL, + * flags, + * NULL, + * &local_error); + * if (auth_result == NULL) + * { + * g_warning ("Failed to get check polkit authorization: %s", local_error->message); + * return FALSE; + * } + * + * return polkit_authorization_result_get_is_authorized (auth_result); + * } + * ]| + * + * Since: 2.72 + */ + +static const gchar org_gtk_Debugging_xml[] = + "" + "" + "" + "" + "" + "" + "" + ""; + +static GDBusInterfaceInfo *org_gtk_Debugging; + +#define G_DEBUG_CONTROLLER_DBUS_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + +static void g_debug_controller_dbus_iface_init (GDebugControllerInterface *iface); +static void g_debug_controller_dbus_initable_iface_init (GInitableIface *iface); +static gboolean g_debug_controller_dbus_authorize_default (GDebugControllerDBus *self, + GDBusMethodInvocation *invocation); + +typedef enum +{ + PROP_CONNECTION = 1, + /* Overrides: */ + PROP_DEBUG_ENABLED, +} GDebugControllerDBusProperty; + +static GParamSpec *props[PROP_CONNECTION + 1] = { NULL, }; + +typedef enum +{ + SIGNAL_AUTHORIZE, +} GDebugControllerDBusSignal; + +static guint signals[SIGNAL_AUTHORIZE + 1] = {0}; + +typedef struct +{ + GObject parent_instance; + + GCancellable *cancellable; /* (owned) */ + GDBusConnection *connection; /* (owned) */ + guint object_id; + GPtrArray *pending_authorize_tasks; /* (element-type GWeakRef) (owned) (nullable) */ + + gboolean debug_enabled; +} GDebugControllerDBusPrivate; + +G_DEFINE_TYPE_WITH_CODE (GDebugControllerDBus, g_debug_controller_dbus, G_TYPE_OBJECT, + G_ADD_PRIVATE (GDebugControllerDBus) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_debug_controller_dbus_initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_DEBUG_CONTROLLER, + g_debug_controller_dbus_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_DEBUG_CONTROLLER_EXTENSION_POINT_NAME, + g_define_type_id, + "dbus", + 30)) + +static void +g_debug_controller_dbus_init (GDebugControllerDBus *self) +{ + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + + priv->cancellable = g_cancellable_new (); +} + +static void +set_debug_enabled (GDebugControllerDBus *self, + gboolean debug_enabled) +{ + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + + if (g_cancellable_is_cancelled (priv->cancellable)) + return; + + if (debug_enabled != priv->debug_enabled) + { + GVariantBuilder builder; + + priv->debug_enabled = debug_enabled; + + /* Change the default log writer’s behaviour in GLib. */ + g_log_set_debug_enabled (debug_enabled); + + /* Notify internally and externally of the property change. */ + g_object_notify (G_OBJECT (self), "debug-enabled"); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", "DebugEnabled", g_variant_new_boolean (priv->debug_enabled)); + + g_dbus_connection_emit_signal (priv->connection, + NULL, + "/org/gtk/Debugging", + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(sa{sv}as)", + "org.gtk.Debugging", + &builder, + NULL), + NULL); + + g_debug ("Debug output %s", debug_enabled ? "enabled" : "disabled"); + } +} + +/* Called in the #GMainContext which was default when the #GDebugControllerDBus + * was initialised. */ +static GVariant * +dbus_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + GDebugControllerDBus *self = user_data; + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + + if (g_str_equal (property_name, "DebugEnabled")) + return g_variant_new_boolean (priv->debug_enabled); + + g_assert_not_reached (); + + return NULL; +} + +static GWeakRef * +weak_ref_new (GObject *obj) +{ + GWeakRef *weak_ref = g_new0 (GWeakRef, 1); + + g_weak_ref_init (weak_ref, obj); + + return g_steal_pointer (&weak_ref); +} + +static void +weak_ref_free (GWeakRef *weak_ref) +{ + g_weak_ref_clear (weak_ref); + g_free (weak_ref); +} + +/* Called in the #GMainContext which was default when the #GDebugControllerDBus + * was initialised. */ +static void +garbage_collect_weak_refs (GDebugControllerDBus *self) +{ + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + guint i; + + if (priv->pending_authorize_tasks == NULL) + return; + + /* Iterate in reverse order so that if we remove an element the hole won’t be + * filled by an element we haven’t checked yet. */ + for (i = priv->pending_authorize_tasks->len; i > 0; i--) + { + GWeakRef *weak_ref = g_ptr_array_index (priv->pending_authorize_tasks, i - 1); + GObject *obj = g_weak_ref_get (weak_ref); + + if (obj == NULL) + g_ptr_array_remove_index_fast (priv->pending_authorize_tasks, i - 1); + else + g_object_unref (obj); + } + + /* Don’t need to keep the array around any more if it’s empty. */ + if (priv->pending_authorize_tasks->len == 0) + g_clear_pointer (&priv->pending_authorize_tasks, g_ptr_array_unref); +} + +/* Called in a worker thread. */ +static void +authorize_task_cb (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GDebugControllerDBus *self = G_DEBUG_CONTROLLER_DBUS (source_object); + GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (task_data); + gboolean authorized = TRUE; + + g_signal_emit (self, signals[SIGNAL_AUTHORIZE], 0, invocation, &authorized); + + g_task_return_boolean (task, authorized); +} + +/* Called in the #GMainContext which was default when the #GDebugControllerDBus + * was initialised. */ +static void +authorize_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GDebugControllerDBus *self = G_DEBUG_CONTROLLER_DBUS (object); + GDebugControllerDBusPrivate *priv G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + GTask *task = G_TASK (result); + GDBusMethodInvocation *invocation = g_task_get_task_data (task); + GVariant *parameters = g_dbus_method_invocation_get_parameters (invocation); + gboolean enabled = FALSE; + gboolean authorized; + + priv = g_debug_controller_dbus_get_instance_private (self); + authorized = g_task_propagate_boolean (task, NULL); + + if (!authorized) + { + GError *local_error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED, + _("Not authorized to change debug settings")); + g_dbus_method_invocation_take_error (invocation, g_steal_pointer (&local_error)); + } + else + { + /* Update the property value. */ + g_variant_get (parameters, "(b)", &enabled); + set_debug_enabled (self, enabled); + + g_dbus_method_invocation_return_value (invocation, NULL); + } + + /* The GTask will stay alive for a bit longer as the worker thread is + * potentially still in the process of dropping its reference to it. */ + g_assert (priv->pending_authorize_tasks != NULL && priv->pending_authorize_tasks->len > 0); +} + +/* Called in the #GMainContext which was default when the #GDebugControllerDBus + * was initialised. */ +static void +dbus_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GDebugControllerDBus *self = user_data; + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + GDebugControllerDBusClass *klass = G_DEBUG_CONTROLLER_DBUS_GET_CLASS (self); + + /* Only on the org.gtk.Debugging interface */ + if (g_str_equal (method_name, "SetDebugEnabled")) + { + GTask *task = NULL; + + task = g_task_new (self, priv->cancellable, authorize_cb, NULL); + g_task_set_source_tag (task, dbus_method_call); + g_task_set_task_data (task, g_object_ref (invocation), (GDestroyNotify) g_object_unref); + + /* Track the pending #GTask with a weak ref as its final strong ref could + * be dropped from this thread or an arbitrary #GTask worker thread. The + * weak refs will be evaluated in g_debug_controller_dbus_stop(). */ + if (priv->pending_authorize_tasks == NULL) + priv->pending_authorize_tasks = g_ptr_array_new_with_free_func ((GDestroyNotify) weak_ref_free); + g_ptr_array_add (priv->pending_authorize_tasks, weak_ref_new (G_OBJECT (task))); + + /* Take the opportunity to clean up a bit. */ + garbage_collect_weak_refs (self); + + /* Check the calling peer is authorised to change the debug mode. So that + * the signal handler can block on checking polkit authorisation (which + * definitely involves D-Bus calls, and might involve user interaction), + * emit the #GDebugControllerDBus::authorize signal in a worker thread, so + * that handlers can synchronously block it. This is similar to how + * #GDBusInterfaceSkeleton::g-authorize-method works. + * + * If no signal handlers are connected, don’t bother running the worker + * thread, and just return a default value of %FALSE. Fail closed. */ + if (g_signal_has_handler_pending (self, signals[SIGNAL_AUTHORIZE], 0, FALSE) || + klass->authorize != g_debug_controller_dbus_authorize_default) + g_task_run_in_thread (task, authorize_task_cb); + else + g_task_return_boolean (task, FALSE); + + g_clear_object (&task); + } + else + g_assert_not_reached (); +} + +static gboolean +g_debug_controller_dbus_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GDebugControllerDBus *self = G_DEBUG_CONTROLLER_DBUS (initable); + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + static const GDBusInterfaceVTable vtable = { + dbus_method_call, + dbus_get_property, + NULL /* set_property */, + { 0 } + }; + + if (org_gtk_Debugging == NULL) + { + GError *local_error = NULL; + GDBusNodeInfo *info; + + info = g_dbus_node_info_new_for_xml (org_gtk_Debugging_xml, &local_error); + if G_UNLIKELY (info == NULL) + g_error ("%s", local_error->message); + org_gtk_Debugging = g_dbus_node_info_lookup_interface (info, "org.gtk.Debugging"); + g_assert (org_gtk_Debugging != NULL); + g_dbus_interface_info_ref (org_gtk_Debugging); + g_dbus_node_info_unref (info); + } + + priv->object_id = g_dbus_connection_register_object (priv->connection, + "/org/gtk/Debugging", + org_gtk_Debugging, + &vtable, self, NULL, error); + if (priv->object_id == 0) + return FALSE; + + return TRUE; +} + +static void +g_debug_controller_dbus_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDebugControllerDBus *self = G_DEBUG_CONTROLLER_DBUS (object); + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + + switch ((GDebugControllerDBusProperty) prop_id) + { + case PROP_CONNECTION: + g_value_set_object (value, priv->connection); + break; + case PROP_DEBUG_ENABLED: + g_value_set_boolean (value, priv->debug_enabled); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_debug_controller_dbus_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDebugControllerDBus *self = G_DEBUG_CONTROLLER_DBUS (object); + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + + switch ((GDebugControllerDBusProperty) prop_id) + { + case PROP_CONNECTION: + /* Construct only */ + g_assert (priv->connection == NULL); + priv->connection = g_value_dup_object (value); + break; + case PROP_DEBUG_ENABLED: + set_debug_enabled (self, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_debug_controller_dbus_dispose (GObject *object) +{ + GDebugControllerDBus *self = G_DEBUG_CONTROLLER_DBUS (object); + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + + g_debug_controller_dbus_stop (self); + g_assert (priv->pending_authorize_tasks == NULL); + g_clear_object (&priv->connection); + g_clear_object (&priv->cancellable); + + G_OBJECT_CLASS (g_debug_controller_dbus_parent_class)->dispose (object); +} + +static gboolean +g_debug_controller_dbus_authorize_default (GDebugControllerDBus *self, + GDBusMethodInvocation *invocation) +{ + return TRUE; +} + +static void +g_debug_controller_dbus_class_init (GDebugControllerDBusClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = g_debug_controller_dbus_get_property; + gobject_class->set_property = g_debug_controller_dbus_set_property; + gobject_class->dispose = g_debug_controller_dbus_dispose; + + klass->authorize = g_debug_controller_dbus_authorize_default; + + /** + * GDebugControllerDBus:connection: + * + * The D-Bus connection to expose the debugging interface on. + * + * Typically this will be the same connection (to the system or session bus) + * which the rest of the application or service’s D-Bus objects are registered + * on. + * + * Since: 2.72 + */ + props[PROP_CONNECTION] = + g_param_spec_object ("connection", "D-Bus Connection", + "The D-Bus connection to expose the debugging interface on.", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, G_N_ELEMENTS (props), props); + + g_object_class_override_property (gobject_class, PROP_DEBUG_ENABLED, "debug-enabled"); + + /** + * GDebugControllerDBus::authorize: + * @controller: The #GDebugControllerDBus emitting the signal. + * @invocation: A #GDBusMethodInvocation. + * + * Emitted when a D-Bus peer is trying to change the debug settings and used + * to determine if that is authorized. + * + * This signal is emitted in a dedicated worker thread, so handlers are + * allowed to perform blocking I/O. This means that, for example, it is + * appropriate to call `polkit_authority_check_authorization_sync()` to check + * authorization using polkit. + * + * If %FALSE is returned then no further handlers are run and the request to + * change the debug settings is rejected. + * + * Otherwise, if %TRUE is returned, signal emission continues. If no handlers + * return %FALSE, then the debug settings are allowed to be changed. + * + * Signal handlers must not modify @invocation, or cause it to return a value. + * + * The default class handler just returns %TRUE. + * + * Returns: %TRUE if the call is authorized, %FALSE otherwise. + * + * Since: 2.72 + */ + signals[SIGNAL_AUTHORIZE] = + g_signal_new ("authorize", + G_TYPE_DEBUG_CONTROLLER_DBUS, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDebugControllerDBusClass, authorize), + _g_signal_accumulator_false_handled, + NULL, + _g_cclosure_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, + 1, + G_TYPE_DBUS_METHOD_INVOCATION); + g_signal_set_va_marshaller (signals[SIGNAL_AUTHORIZE], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_BOOLEAN__OBJECTv); +} + +static void +g_debug_controller_dbus_iface_init (GDebugControllerInterface *iface) +{ +} + +static void +g_debug_controller_dbus_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_debug_controller_dbus_initable_init; +} + +/** + * g_debug_controller_dbus_new: + * @connection: a #GDBusConnection to register the debug object on + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Create a new #GDebugControllerDBus and synchronously initialize it. + * + * Initializing the object will export the debug object on @connection. The + * object will remain registered until the last reference to the + * #GDebugControllerDBus is dropped. + * + * Initialization may fail if registering the object on @connection fails. + * + * Returns: (nullable) (transfer full): a new #GDebugControllerDBus, or %NULL + * on failure + * Since: 2.72 + */ +GDebugControllerDBus * +g_debug_controller_dbus_new (GDBusConnection *connection, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + return g_initable_new (G_TYPE_DEBUG_CONTROLLER_DBUS, + cancellable, + error, + "connection", connection, + NULL); +} + +/** + * g_debug_controller_dbus_stop: + * @self: a #GDebugControllerDBus + * + * Stop the debug controller, unregistering its object from the bus. + * + * Any pending method calls to the object will complete successfully, but new + * ones will return an error. This method will block until all pending + * #GDebugControllerDBus::authorize signals have been handled. This is expected + * to not take long, as it will just be waiting for threads to join. If any + * #GDebugControllerDBus::authorize signal handlers are still executing in other + * threads, this will block until after they have returned. + * + * This method will be called automatically when the final reference to the + * #GDebugControllerDBus is dropped. You may want to call it explicitly to know + * when the controller has been fully removed from the bus, or to break + * reference count cycles. + * + * Calling this method from within a #GDebugControllerDBus::authorize signal + * handler will cause a deadlock and must not be done. + * + * Since: 2.72 + */ +void +g_debug_controller_dbus_stop (GDebugControllerDBus *self) +{ + GDebugControllerDBusPrivate *priv = g_debug_controller_dbus_get_instance_private (self); + + g_cancellable_cancel (priv->cancellable); + + if (priv->object_id != 0) + { + g_dbus_connection_unregister_object (priv->connection, priv->object_id); + priv->object_id = 0; + } + + /* Wait for any pending authorize tasks to finish. These will just be waiting + * for threads to join at this point, as the D-Bus object has been + * unregistered and the cancellable cancelled. + * + * The loop will never terminate if g_debug_controller_dbus_stop() is + * called from within an ::authorize callback. + * + * See discussion in https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2486 */ + while (priv->pending_authorize_tasks != NULL) + { + garbage_collect_weak_refs (self); + g_thread_yield (); + } +} diff --git a/gio/gdebugcontrollerdbus.h b/gio/gdebugcontrollerdbus.h new file mode 100644 index 0000000..5e54bbf --- /dev/null +++ b/gio/gdebugcontrollerdbus.h @@ -0,0 +1,69 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2021 Endless OS Foundation, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef __G_DEBUG_CONTROLLER_DBUS_H__ +#define __G_DEBUG_CONTROLLER_DBUS_H__ + +#include +#include + +G_BEGIN_DECLS + +/** + * GDebugControllerDBus: + * + * #GDebugControllerDBus is an implementation of #GDebugController over D-Bus. + * + * Since: 2.72 + */ +#define G_TYPE_DEBUG_CONTROLLER_DBUS (g_debug_controller_dbus_get_type ()) +GLIB_AVAILABLE_IN_2_72 +G_DECLARE_DERIVABLE_TYPE (GDebugControllerDBus, g_debug_controller_dbus, G, DEBUG_CONTROLLER_DBUS, GObject) + +/** + * GDebugControllerDBusClass: + * @parent_class: The parent class. + * @authorize: Default handler for the #GDebugControllerDBus::authorize signal. + * + * The virtual function table for #GDebugControllerDBus. + * + * Since: 2.72 + */ +struct _GDebugControllerDBusClass +{ + GObjectClass parent_class; + + gboolean (*authorize) (GDebugControllerDBus *controller, + GDBusMethodInvocation *invocation); + + gpointer padding[12]; +}; + +GLIB_AVAILABLE_IN_2_72 +GDebugControllerDBus *g_debug_controller_dbus_new (GDBusConnection *connection, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_72 +void g_debug_controller_dbus_stop (GDebugControllerDBus *self); + +G_END_DECLS + +#endif /* __G_DEBUG_CONTROLLER_DBUS_H__ */ diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c new file mode 100644 index 0000000..6fff6f7 --- /dev/null +++ b/gio/gdelayedsettingsbackend.c @@ -0,0 +1,516 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gdelayedsettingsbackend.h" +#include "gsettingsbackendinternal.h" + +#include + + +struct _GDelayedSettingsBackendPrivate +{ + GSettingsBackend *backend; + GMutex lock; + GTree *delayed; + + GMainContext *owner_context; + gpointer owner; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GDelayedSettingsBackend, + g_delayed_settings_backend, + G_TYPE_SETTINGS_BACKEND) + +static gboolean +invoke_notify_unapplied (gpointer data) +{ + g_object_notify (data, "has-unapplied"); + g_object_unref (data); + + return FALSE; +} + +static void +g_delayed_settings_backend_notify_unapplied (GDelayedSettingsBackend *delayed) +{ + GMainContext *target_context; + GObject *target; + + g_mutex_lock (&delayed->priv->lock); + if (delayed->priv->owner) + { + target_context = delayed->priv->owner_context; + target = g_object_ref (delayed->priv->owner); + } + else + { + target_context = NULL; + target = NULL; + } + g_mutex_unlock (&delayed->priv->lock); + + if (target != NULL) + g_main_context_invoke (target_context, invoke_notify_unapplied, target); +} + + +static GVariant * +g_delayed_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gpointer result = NULL; + + if (!default_value) + { + g_mutex_lock (&delayed->priv->lock); + if (g_tree_lookup_extended (delayed->priv->delayed, key, NULL, &result)) + { + /* NULL in the tree means we should consult the default value */ + if (result != NULL) + g_variant_ref (result); + else + default_value = TRUE; + } + g_mutex_unlock (&delayed->priv->lock); + } + + if (result == NULL) + result = g_settings_backend_read (delayed->priv->backend, key, + expected_type, default_value); + + return result; +} + +static GVariant * +g_delayed_settings_backend_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gboolean value_found = FALSE; + gpointer result = NULL; + + /* If we find an explicit NULL in our changeset then we want to return + * NULL (because the user value has been reset). + * + * Otherwise, chain up. + */ + g_mutex_lock (&delayed->priv->lock); + value_found = g_tree_lookup_extended (delayed->priv->delayed, key, NULL, &result); + if (result) + g_variant_ref (result); + g_mutex_unlock (&delayed->priv->lock); + + if (value_found) + return result; + + return g_settings_backend_read_user_value (delayed->priv->backend, key, expected_type); +} + +static gboolean +g_delayed_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gboolean was_empty; + + g_mutex_lock (&delayed->priv->lock); + was_empty = g_tree_nnodes (delayed->priv->delayed) == 0; + g_tree_insert (delayed->priv->delayed, g_strdup (key), + g_variant_ref_sink (value)); + g_mutex_unlock (&delayed->priv->lock); + + g_settings_backend_changed (backend, key, origin_tag); + + if (was_empty) + g_delayed_settings_backend_notify_unapplied (delayed); + + return TRUE; +} + +static gboolean +add_to_tree (gpointer key, + gpointer value, + gpointer user_data) +{ + /* A value may be %NULL if its key has been reset */ + g_tree_insert (user_data, g_strdup (key), (value != NULL) ? g_variant_ref (value) : NULL); + return FALSE; +} + +static gboolean +g_delayed_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gboolean was_empty; + + g_mutex_lock (&delayed->priv->lock); + was_empty = g_tree_nnodes (delayed->priv->delayed) == 0; + + g_tree_foreach (tree, add_to_tree, delayed->priv->delayed); + g_mutex_unlock (&delayed->priv->lock); + + g_settings_backend_changed_tree (backend, tree, origin_tag); + + if (was_empty) + g_delayed_settings_backend_notify_unapplied (delayed); + + return TRUE; +} + +static gboolean +g_delayed_settings_backend_get_writable (GSettingsBackend *backend, + const gchar *name) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + + return g_settings_backend_get_writable (delayed->priv->backend, name); +} + +static void +g_delayed_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gboolean was_empty; + + g_mutex_lock (&delayed->priv->lock); + was_empty = g_tree_nnodes (delayed->priv->delayed) == 0; + g_tree_insert (delayed->priv->delayed, g_strdup (key), NULL); + g_mutex_unlock (&delayed->priv->lock); + + g_settings_backend_changed (backend, key, origin_tag); + + if (was_empty) + g_delayed_settings_backend_notify_unapplied (delayed); +} + +static void +g_delayed_settings_backend_subscribe (GSettingsBackend *backend, + const char *name) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + + g_settings_backend_subscribe (delayed->priv->backend, name); +} + +static void +g_delayed_settings_backend_unsubscribe (GSettingsBackend *backend, + const char *name) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + + g_settings_backend_unsubscribe (delayed->priv->backend, name); +} + +static GPermission * +g_delayed_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + + return g_settings_backend_get_permission (delayed->priv->backend, path); +} + + +/* method calls */ +gboolean +g_delayed_settings_backend_get_has_unapplied (GDelayedSettingsBackend *delayed) +{ + /* we don't need to lock for this... */ + + return g_tree_nnodes (delayed->priv->delayed) > 0; +} + +void +g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed) +{ + if (g_tree_nnodes (delayed->priv->delayed) > 0) + { + gboolean success; + GTree *tmp; + + g_mutex_lock (&delayed->priv->lock); + tmp = delayed->priv->delayed; + delayed->priv->delayed = g_settings_backend_create_tree (); + success = g_settings_backend_write_tree (delayed->priv->backend, + tmp, delayed->priv); + g_mutex_unlock (&delayed->priv->lock); + + if (!success) + g_settings_backend_changed_tree (G_SETTINGS_BACKEND (delayed), + tmp, NULL); + + g_tree_unref (tmp); + + g_delayed_settings_backend_notify_unapplied (delayed); + } +} + +void +g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed) +{ + if (g_tree_nnodes (delayed->priv->delayed) > 0) + { + GTree *tmp; + + g_mutex_lock (&delayed->priv->lock); + tmp = delayed->priv->delayed; + delayed->priv->delayed = g_settings_backend_create_tree (); + g_mutex_unlock (&delayed->priv->lock); + g_settings_backend_changed_tree (G_SETTINGS_BACKEND (delayed), tmp, NULL); + g_tree_unref (tmp); + + g_delayed_settings_backend_notify_unapplied (delayed); + } +} + +/* change notification */ +static void +delayed_backend_changed (GObject *target, + GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); + + if (origin_tag != delayed->priv) + g_settings_backend_changed (G_SETTINGS_BACKEND (delayed), + key, origin_tag); +} + +static void +delayed_backend_keys_changed (GObject *target, + GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag, + const gchar * const *items) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); + + if (origin_tag != delayed->priv) + g_settings_backend_keys_changed (G_SETTINGS_BACKEND (delayed), + path, items, origin_tag); +} + +static void +delayed_backend_path_changed (GObject *target, + GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); + + if (origin_tag != delayed->priv) + g_settings_backend_path_changed (G_SETTINGS_BACKEND (delayed), + path, origin_tag); +} + +static void +delayed_backend_writable_changed (GObject *target, + GSettingsBackend *backend, + const gchar *key) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); + gboolean last_one = FALSE; + + g_mutex_lock (&delayed->priv->lock); + + if (g_tree_lookup (delayed->priv->delayed, key) != NULL && + !g_settings_backend_get_writable (delayed->priv->backend, key)) + { + /* drop the key from our changeset if it just became read-only. + * no need to signal since the writable change below implies it. + * + * note that the item in the tree may very well be set to NULL in + * the case that the user stored a reset. we intentionally don't + * drop the key in this case since a reset will always succeed + * (even against a non-writable key). + */ + g_tree_remove (delayed->priv->delayed, key); + + /* if that was the only key... */ + last_one = g_tree_nnodes (delayed->priv->delayed) == 0; + } + + g_mutex_unlock (&delayed->priv->lock); + + if (last_one) + g_delayed_settings_backend_notify_unapplied (delayed); + + g_settings_backend_writable_changed (G_SETTINGS_BACKEND (delayed), key); +} + +/* slow method until we get foreach-with-remove in GTree + */ +typedef struct +{ + const gchar *path; + const gchar **keys; + gsize index; +} CheckPrefixState; + +static gboolean +check_prefix (gpointer key, + gpointer value, + gpointer data) +{ + CheckPrefixState *state = data; + + if (g_str_has_prefix (key, state->path)) + state->keys[state->index++] = key; + + return FALSE; +} + +static void +delayed_backend_path_writable_changed (GObject *target, + GSettingsBackend *backend, + const gchar *path) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); + gboolean last_one = FALSE; + gsize n_keys; + + g_mutex_lock (&delayed->priv->lock); + + n_keys = g_tree_nnodes (delayed->priv->delayed); + + if (n_keys > 0) + { + CheckPrefixState state = { path, g_new (const gchar *, n_keys), 0 }; + gsize i; + + /* collect a list of possibly-affected keys (ie: matching the path) */ + g_tree_foreach (delayed->priv->delayed, check_prefix, &state); + + /* drop the keys that have been affected. + * + * don't drop 'reset' keys (see above) */ + for (i = 0; i < state.index; i++) + if (g_tree_lookup (delayed->priv->delayed, state.keys[i]) != NULL && + !g_settings_backend_get_writable (delayed->priv->backend, + state.keys[i])) + g_tree_remove (delayed->priv->delayed, state.keys[i]); + + g_free (state.keys); + + last_one = g_tree_nnodes (delayed->priv->delayed) == 0; + } + + g_mutex_unlock (&delayed->priv->lock); + + if (last_one) + g_delayed_settings_backend_notify_unapplied (delayed); + + g_settings_backend_path_writable_changed (G_SETTINGS_BACKEND (delayed), + path); +} + +static void +g_delayed_settings_backend_finalize (GObject *object) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (object); + + g_mutex_clear (&delayed->priv->lock); + g_object_unref (delayed->priv->backend); + g_tree_unref (delayed->priv->delayed); + + /* if our owner is still alive, why are we finalizing? */ + g_assert (delayed->priv->owner == NULL); + + G_OBJECT_CLASS (g_delayed_settings_backend_parent_class) + ->finalize (object); +} + +static void +g_delayed_settings_backend_class_init (GDelayedSettingsBackendClass *class) +{ + GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (class); + + backend_class->read = g_delayed_settings_backend_read; + backend_class->read_user_value = g_delayed_settings_backend_read_user_value; + backend_class->write = g_delayed_settings_backend_write; + backend_class->write_tree = g_delayed_settings_backend_write_tree; + backend_class->reset = g_delayed_settings_backend_reset; + backend_class->get_writable = g_delayed_settings_backend_get_writable; + backend_class->subscribe = g_delayed_settings_backend_subscribe; + backend_class->unsubscribe = g_delayed_settings_backend_unsubscribe; + backend_class->get_permission = g_delayed_settings_backend_get_permission; + + object_class->finalize = g_delayed_settings_backend_finalize; +} + +static void +g_delayed_settings_backend_init (GDelayedSettingsBackend *delayed) +{ + delayed->priv = g_delayed_settings_backend_get_instance_private (delayed); + delayed->priv->delayed = g_settings_backend_create_tree (); + g_mutex_init (&delayed->priv->lock); +} + +static void +g_delayed_settings_backend_disown (gpointer data, + GObject *where_the_object_was) +{ + GDelayedSettingsBackend *delayed = data; + + g_mutex_lock (&delayed->priv->lock); + delayed->priv->owner_context = NULL; + delayed->priv->owner = NULL; + g_mutex_unlock (&delayed->priv->lock); +} + +GDelayedSettingsBackend * +g_delayed_settings_backend_new (GSettingsBackend *backend, + gpointer owner, + GMainContext *owner_context) +{ + static GSettingsListenerVTable vtable = { + delayed_backend_changed, + delayed_backend_path_changed, + delayed_backend_keys_changed, + delayed_backend_writable_changed, + delayed_backend_path_writable_changed + }; + GDelayedSettingsBackend *delayed; + + delayed = g_object_new (G_TYPE_DELAYED_SETTINGS_BACKEND, NULL); + delayed->priv->backend = g_object_ref (backend); + delayed->priv->owner_context = owner_context; + delayed->priv->owner = owner; + + g_object_weak_ref (owner, g_delayed_settings_backend_disown, delayed); + + g_settings_backend_watch (delayed->priv->backend, + &vtable, G_OBJECT (delayed), NULL); + + return delayed; +} diff --git a/gio/gdelayedsettingsbackend.h b/gio/gdelayedsettingsbackend.h new file mode 100644 index 0000000..1eb890a --- /dev/null +++ b/gio/gdelayedsettingsbackend.h @@ -0,0 +1,65 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_DELAYED_SETTINGS_BACKEND_H__ +#define __G_DELAYED_SETTINGS_BACKEND_H__ + +#include + +#include + +#define G_TYPE_DELAYED_SETTINGS_BACKEND (g_delayed_settings_backend_get_type ()) +#define G_DELAYED_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_DELAYED_SETTINGS_BACKEND, \ + GDelayedSettingsBackend)) +#define G_DELAYED_SETTINGS_BACKEND_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_DELAYED_SETTINGS_BACKEND, \ + GDelayedSettingsBackendClass)) +#define G_IS_DELAYED_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_DELAYED_SETTINGS_BACKEND)) +#define G_IS_DELAYED_SETTINGS_BACKEND_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_DELAYED_SETTINGS_BACKEND)) +#define G_DELAYED_SETTINGS_BACKEND_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_DELAYED_SETTINGS_BACKEND, \ + GDelayedSettingsBackendClass)) + +typedef struct _GDelayedSettingsBackendPrivate GDelayedSettingsBackendPrivate; +typedef struct _GDelayedSettingsBackendClass GDelayedSettingsBackendClass; +typedef struct _GDelayedSettingsBackend GDelayedSettingsBackend; + +struct _GDelayedSettingsBackendClass +{ + GSettingsBackendClass parent_class; +}; + +struct _GDelayedSettingsBackend +{ + GSettingsBackend parent_instance; + GDelayedSettingsBackendPrivate *priv; +}; + +GType g_delayed_settings_backend_get_type (void); +GDelayedSettingsBackend * g_delayed_settings_backend_new (GSettingsBackend *backend, + gpointer owner, + GMainContext *owner_context); +void g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed); +void g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed); +gboolean g_delayed_settings_backend_get_has_unapplied (GDelayedSettingsBackend *delayed); + +#endif /* __G_DELAYED_SETTINGS_BACKEND_H__ */ diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c new file mode 100644 index 0000000..994846e --- /dev/null +++ b/gio/gdesktopappinfo.c @@ -0,0 +1,5197 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright © 2007 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Ryan Lortie + */ + +/* Prelude {{{1 */ + +#include "config.h" + +/* For the #GDesktopAppInfoLookup macros; since macro deprecation is implemented + * in the preprocessor, we need to define this before including glib.h*/ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include +#include +#include + +#ifdef HAVE_CRT_EXTERNS_H +#include +#endif + +#include "gcontenttypeprivate.h" +#include "gdesktopappinfo.h" +#ifdef G_OS_UNIX +#include "glib-unix.h" +#endif +#include "gfile.h" +#include "gioerror.h" +#include "gthemedicon.h" +#include "gfileicon.h" +#include +#include "glibintl.h" +#include "giomodule-priv.h" +#include "gappinfo.h" +#include "gappinfoprivate.h" +#include "glocalfilemonitor.h" + +#ifdef G_OS_UNIX +#include "gdocumentportal.h" +#endif + +/** + * SECTION:gdesktopappinfo + * @title: GDesktopAppInfo + * @short_description: Application information from desktop files + * @include: gio/gdesktopappinfo.h + * + * #GDesktopAppInfo is an implementation of #GAppInfo based on + * desktop files. + * + * Note that `` belongs to the UNIX-specific + * GIO interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config + * file when using it. + */ + +#define DEFAULT_APPLICATIONS_GROUP "Default Applications" +#define ADDED_ASSOCIATIONS_GROUP "Added Associations" +#define REMOVED_ASSOCIATIONS_GROUP "Removed Associations" +#define MIME_CACHE_GROUP "MIME Cache" +#define GENERIC_NAME_KEY "GenericName" +#define FULL_NAME_KEY "X-GNOME-FullName" +#define KEYWORDS_KEY "Keywords" +#define STARTUP_WM_CLASS_KEY "StartupWMClass" + +enum { + PROP_0, + PROP_FILENAME +}; + +static void g_desktop_app_info_iface_init (GAppInfoIface *iface); +static gboolean g_desktop_app_info_ensure_saved (GDesktopAppInfo *info, + GError **error); +static gboolean g_desktop_app_info_load_file (GDesktopAppInfo *self); + +/** + * GDesktopAppInfo: + * + * Information about an installed application from a desktop file. + */ +struct _GDesktopAppInfo +{ + GObject parent_instance; + + char *desktop_id; + char *filename; + char *app_id; + + GKeyFile *keyfile; + + char *name; + char *generic_name; + char *fullname; + char *comment; + char *icon_name; + GIcon *icon; + char **keywords; + char **only_show_in; + char **not_show_in; + char *try_exec; + char *exec; + char *binary; + char *path; + char *categories; + char *startup_wm_class; + char **mime_types; + char **actions; + + guint nodisplay : 1; + guint hidden : 1; + guint terminal : 1; + guint startup_notify : 1; + guint no_fuse : 1; +}; + +typedef enum { + UPDATE_MIME_NONE = 1 << 0, + UPDATE_MIME_SET_DEFAULT = 1 << 1, + UPDATE_MIME_SET_NON_DEFAULT = 1 << 2, + UPDATE_MIME_REMOVE = 1 << 3, + UPDATE_MIME_SET_LAST_USED = 1 << 4, +} UpdateMimeFlags; + +G_DEFINE_TYPE_WITH_CODE (GDesktopAppInfo, g_desktop_app_info, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_APP_INFO, g_desktop_app_info_iface_init)) + +/* DesktopFileDir implementation {{{1 */ + +typedef struct +{ + gatomicrefcount ref_count; + gchar *path; + gchar *alternatively_watching; + gboolean is_config; + gboolean is_setup; + GFileMonitor *monitor; + GHashTable *app_names; + GHashTable *mime_tweaks; + GHashTable *memory_index; + GHashTable *memory_implementations; +} DesktopFileDir; + +static GPtrArray *desktop_file_dirs = NULL; +static const gchar *desktop_file_dirs_config_dir = NULL; +static DesktopFileDir *desktop_file_dir_user_config = NULL; /* (owned) */ +static DesktopFileDir *desktop_file_dir_user_data = NULL; /* (owned) */ +static GMutex desktop_file_dir_lock; + +/* Monitor 'changed' signal handler {{{2 */ +static void desktop_file_dir_reset (DesktopFileDir *dir); + +static DesktopFileDir * +desktop_file_dir_ref (DesktopFileDir *dir) +{ + g_atomic_ref_count_inc (&dir->ref_count); + + return dir; +} + +static void +desktop_file_dir_unref (DesktopFileDir *dir) +{ + if (g_atomic_ref_count_dec (&dir->ref_count)) + { + desktop_file_dir_reset (dir); + g_free (dir->path); + g_free (dir); + } +} + +/*< internal > + * desktop_file_dir_get_alternative_dir: + * @dir: a #DesktopFileDir + * + * Gets the "alternative" directory to monitor in case the path + * doesn't exist. + * + * If the path exists this will return NULL, otherwise it will return a + * parent directory of the path. + * + * This is used to avoid inotify on a non-existent directory (which + * results in polling). + * + * See https://bugzilla.gnome.org/show_bug.cgi?id=522314 for more info. + */ +static gchar * +desktop_file_dir_get_alternative_dir (DesktopFileDir *dir) +{ + gchar *parent; + + /* If the directory itself exists then we need no alternative. */ + if (g_access (dir->path, R_OK | X_OK) == 0) + return NULL; + + /* Otherwise, try the parent directories until we find one. */ + parent = g_path_get_dirname (dir->path); + + while (g_access (parent, R_OK | X_OK) != 0) + { + gchar *tmp = parent; + + parent = g_path_get_dirname (tmp); + + /* If somehow we get to '/' or '.' then just stop... */ + if (g_str_equal (parent, tmp)) + { + g_free (tmp); + break; + } + + g_free (tmp); + } + + return parent; +} + +static void +desktop_file_dir_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + DesktopFileDir *dir = user_data; + gboolean do_nothing = FALSE; + + /* We are not interested in receiving notifications forever just + * because someone asked about one desktop file once. + * + * After we receive the first notification, reset the dir, destroying + * the monitor. We will take this as a hint, next time that we are + * asked, that we need to check if everything is up to date. + * + * If this is a notification for a parent directory (because the + * desktop directory didn't exist) then we shouldn't fire the signal + * unless something actually changed. + */ + g_mutex_lock (&desktop_file_dir_lock); + + if (dir->alternatively_watching) + { + gchar *alternative_dir; + + alternative_dir = desktop_file_dir_get_alternative_dir (dir); + do_nothing = alternative_dir && g_str_equal (dir->alternatively_watching, alternative_dir); + g_free (alternative_dir); + } + + if (!do_nothing) + desktop_file_dir_reset (dir); + + g_mutex_unlock (&desktop_file_dir_lock); + + /* Notify anyone else who may be interested */ + if (!do_nothing) + g_app_info_monitor_fire (); +} + +/* Internal utility functions {{{2 */ + +/*< internal > + * desktop_file_dir_app_name_is_masked: + * @dir: a #DesktopFileDir + * @app_name: an application ID + * + * Checks if @app_name is masked for @dir. + * + * An application is masked if a similarly-named desktop file exists in + * a desktop file directory with higher precedence. Masked desktop + * files should be ignored. + */ +static gboolean +desktop_file_dir_app_name_is_masked (DesktopFileDir *dir, + const gchar *app_name) +{ + guint i; + + for (i = 0; i < desktop_file_dirs->len; i++) + { + DesktopFileDir *i_dir = g_ptr_array_index (desktop_file_dirs, i); + + if (dir == i_dir) + return FALSE; + if (i_dir->app_names && g_hash_table_contains (i_dir->app_names, app_name)) + return TRUE; + } + + return FALSE; +} + +/* Not much to go on from https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html + * so validate it as a non-empty alphanumeric ASCII string with `-` and `_` allowed. + * + * Validation is important as the desktop IDs are used to construct filenames, + * and may be set by an unprivileged caller if running in a setuid program. */ +static gboolean +validate_xdg_desktop (const gchar *desktop) +{ + gsize i; + + for (i = 0; desktop[i] != '\0'; i++) + if (desktop[i] != '-' && desktop[i] != '_' && + !g_ascii_isalnum (desktop[i])) + return FALSE; + + if (i == 0) + return FALSE; + + return TRUE; +} + +static char ** +get_valid_current_desktops (const char *value) +{ + char **tmp; + gsize i; + GPtrArray *valid_desktops; + + if (value == NULL) + value = g_getenv ("XDG_CURRENT_DESKTOP"); + if (value == NULL) + value = ""; + + tmp = g_strsplit (value, G_SEARCHPATH_SEPARATOR_S, 0); + valid_desktops = g_ptr_array_new_full (g_strv_length (tmp) + 1, g_free); + for (i = 0; tmp[i]; i++) + { + if (validate_xdg_desktop (tmp[i])) + g_ptr_array_add (valid_desktops, tmp[i]); + else + g_free (tmp[i]); + } + g_ptr_array_add (valid_desktops, NULL); + g_free (tmp); + tmp = (char **) g_ptr_array_steal (valid_desktops, NULL); + g_ptr_array_unref (valid_desktops); + return tmp; +} + +static const gchar * const * +get_lowercase_current_desktops (void) +{ + static gchar **result; + + if (g_once_init_enter (&result)) + { + char **tmp = get_valid_current_desktops (NULL); + gsize i, j; + + for (i = 0; tmp[i]; i++) + { + /* Convert to lowercase. */ + for (j = 0; tmp[i][j]; j++) + tmp[i][j] = g_ascii_tolower (tmp[i][j]); + } + + g_once_init_leave (&result, tmp); + } + + return (const gchar **) result; +} + +static const gchar * const * +get_current_desktops (const gchar *value) +{ + static gchar **result; + + if (g_once_init_enter (&result)) + { + char **tmp = get_valid_current_desktops (value); + + g_once_init_leave (&result, tmp); + } + + return (const gchar **) result; +} + +/*< internal > + * add_to_table_if_appropriate: + * @apps: a string to GDesktopAppInfo hash table + * @app_name: the name of the application + * @info: a #GDesktopAppInfo, or NULL + * + * If @info is non-%NULL and non-hidden, then add it to @apps, using + * @app_name as a key. + * + * If @info is non-%NULL then this function will consume the passed-in + * reference. + */ +static void +add_to_table_if_appropriate (GHashTable *apps, + const gchar *app_name, + GDesktopAppInfo *info) +{ + if (!info) + return; + + if (info->hidden) + { + g_object_unref (info); + return; + } + + g_free (info->desktop_id); + info->desktop_id = g_strdup (app_name); + + g_hash_table_insert (apps, g_strdup (info->desktop_id), info); +} + +enum +{ + DESKTOP_KEY_Comment, + DESKTOP_KEY_Exec, + DESKTOP_KEY_GenericName, + DESKTOP_KEY_Keywords, + DESKTOP_KEY_Name, + DESKTOP_KEY_X_GNOME_FullName, + + N_DESKTOP_KEYS +}; + +const gchar desktop_key_match_category[N_DESKTOP_KEYS] = { + /* Note: lower numbers are a better match. + * + * In case we want two keys to match at the same level, we can just + * use the same number for the two different keys. + */ + [DESKTOP_KEY_Name] = 1, + [DESKTOP_KEY_Exec] = 2, + [DESKTOP_KEY_Keywords] = 3, + [DESKTOP_KEY_GenericName] = 4, + [DESKTOP_KEY_X_GNOME_FullName] = 5, + [DESKTOP_KEY_Comment] = 6 +}; + +/* Common prefix commands to ignore from Exec= lines */ +const char * const exec_key_match_blocklist[] = { + "bash", + "env", + "flatpak", + "gjs", + "pkexec", + "python", + "python2", + "python3", + "sh", + "wine", + "wine64", + NULL +}; + +static gchar * +desktop_key_get_name (guint key_id) +{ + switch (key_id) + { + case DESKTOP_KEY_Comment: + return "Comment"; + case DESKTOP_KEY_Exec: + return "Exec"; + case DESKTOP_KEY_GenericName: + return GENERIC_NAME_KEY; + case DESKTOP_KEY_Keywords: + return KEYWORDS_KEY; + case DESKTOP_KEY_Name: + return "Name"; + case DESKTOP_KEY_X_GNOME_FullName: + return FULL_NAME_KEY; + default: + g_assert_not_reached (); + } +} + +/* Search global state {{{2 + * + * We only ever search under a global lock, so we can use (and reuse) + * some global data to reduce allocations made while searching. + * + * In short, we keep around arrays of results that we expand as needed + * (and never shrink). + * + * static_token_results: this is where we append the results for each + * token within a given desktop directory, as we handle it (which is + * a union of all matches for this term) + * + * static_search_results: this is where we build the complete results + * for a single directory (which is an intersection of the matches + * found for each term) + * + * static_total_results: this is where we build the complete results + * across all directories (which is a union of the matches found in + * each directory) + * + * The app_names that enter these tables are always pointer-unique (in + * the sense that string equality is the same as pointer equality). + * This can be guaranteed for two reasons: + * + * - we mask appids so that a given appid will only ever appear within + * the highest-precedence directory that contains it. We never + * return search results from a lower-level directory if a desktop + * file exists in a higher-level one. + * + * - within a given directory, the string is unique because it's the + * key in the hashtable of all app_ids for that directory. + * + * We perform a merging of the results in merge_token_results(). This + * works by ordering the two lists and moving through each of them (at + * the same time) looking for common elements, rejecting uncommon ones. + * "Order" here need not mean any particular thing, as long as it is + * some order. Because of the uniqueness of our strings, we can use + * pointer order. That's what's going on in compare_results() below. + */ +struct search_result +{ + const gchar *app_name; + gint category; +}; + +static struct search_result *static_token_results; +static gint static_token_results_size; +static gint static_token_results_allocated; +static struct search_result *static_search_results; +static gint static_search_results_size; +static gint static_search_results_allocated; +static struct search_result *static_total_results; +static gint static_total_results_size; +static gint static_total_results_allocated; + +/* And some functions for performing nice operations against it */ +static gint +compare_results (gconstpointer a, + gconstpointer b) +{ + const struct search_result *ra = a; + const struct search_result *rb = b; + + if (ra->app_name < rb->app_name) + return -1; + + else if (ra->app_name > rb->app_name) + return 1; + + else + return ra->category - rb->category; +} + +static gint +compare_categories (gconstpointer a, + gconstpointer b) +{ + const struct search_result *ra = a; + const struct search_result *rb = b; + + return ra->category - rb->category; +} + +static void +add_token_result (const gchar *app_name, + guint16 category) +{ + if G_UNLIKELY (static_token_results_size == static_token_results_allocated) + { + static_token_results_allocated = MAX (16, static_token_results_allocated * 2); + static_token_results = g_renew (struct search_result, static_token_results, static_token_results_allocated); + } + + static_token_results[static_token_results_size].app_name = app_name; + static_token_results[static_token_results_size].category = category; + static_token_results_size++; +} + +static void +merge_token_results (gboolean first) +{ + if (static_token_results_size != 0) + qsort (static_token_results, static_token_results_size, sizeof (struct search_result), compare_results); + + /* If this is the first token then we are basically merging a list with + * itself -- we only perform de-duplication. + * + * If this is not the first token then we are doing a real merge. + */ + if (first) + { + const gchar *last_name = NULL; + gint i; + + /* We must de-duplicate, but we do so by taking the best category + * in each case. + * + * The final list can be as large as the input here, so make sure + * we have enough room (even if it's too much room). + */ + + if G_UNLIKELY (static_search_results_allocated < static_token_results_size) + { + static_search_results_allocated = static_token_results_allocated; + static_search_results = g_renew (struct search_result, + static_search_results, + static_search_results_allocated); + } + + for (i = 0; i < static_token_results_size; i++) + { + /* The list is sorted so that the best match for a given id + * will be at the front, so once we have copied an id, skip + * the rest of the entries for the same id. + */ + if (static_token_results[i].app_name == last_name) + continue; + + last_name = static_token_results[i].app_name; + + static_search_results[static_search_results_size++] = static_token_results[i]; + } + } + else + { + const gchar *last_name = NULL; + gint i, j = 0; + gint k = 0; + + /* We only ever remove items from the results list, so no need to + * resize to ensure that we have enough room. + */ + for (i = 0; i < static_token_results_size; i++) + { + if (static_token_results[i].app_name == last_name) + continue; + + last_name = static_token_results[i].app_name; + + /* Now we only want to have a result in static_search_results + * if we already have it there *and* we have it in + * static_token_results as well. The category will be the + * lesser of the two. + * + * Skip past the results in static_search_results that are not + * going to be matches. + */ + while (k < static_search_results_size && + static_search_results[k].app_name < static_token_results[i].app_name) + k++; + + if (k < static_search_results_size && + static_search_results[k].app_name == static_token_results[i].app_name) + { + /* We have a match. + * + * Category should be the worse of the two (ie: + * numerically larger). + */ + static_search_results[j].app_name = static_search_results[k].app_name; + static_search_results[j].category = MAX (static_search_results[k].category, + static_token_results[i].category); + j++; + } + } + + static_search_results_size = j; + } + + /* Clear it out for next time... */ + static_token_results_size = 0; +} + +static void +reset_total_search_results (void) +{ + static_total_results_size = 0; +} + +static void +sort_total_search_results (void) +{ + if (static_total_results_size != 0) + qsort (static_total_results, static_total_results_size, sizeof (struct search_result), compare_categories); +} + +static void +merge_directory_results (void) +{ + if G_UNLIKELY (static_total_results_size + static_search_results_size > static_total_results_allocated) + { + static_total_results_allocated = MAX (16, static_total_results_allocated); + while (static_total_results_allocated < static_total_results_size + static_search_results_size) + static_total_results_allocated *= 2; + static_total_results = g_renew (struct search_result, static_total_results, static_total_results_allocated); + } + + if (static_search_results_size != 0) + memcpy (static_total_results + static_total_results_size, + static_search_results, + static_search_results_size * sizeof (struct search_result)); + + static_total_results_size += static_search_results_size; + + /* Clear it out for next time... */ + static_search_results_size = 0; +} + +/* Support for unindexed DesktopFileDirs {{{2 */ +static void +get_apps_from_dir (GHashTable **apps, + const char *dirname, + const char *prefix) +{ + const char *basename; + GDir *dir; + + dir = g_dir_open (dirname, 0, NULL); + + if (dir == NULL) + return; + + while ((basename = g_dir_read_name (dir)) != NULL) + { + gchar *filename; + + filename = g_build_filename (dirname, basename, NULL); + + if (g_str_has_suffix (basename, ".desktop")) + { + gchar *app_name; + + app_name = g_strconcat (prefix, basename, NULL); + + if (*apps == NULL) + *apps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + g_hash_table_insert (*apps, app_name, g_strdup (filename)); + } + else if (g_file_test (filename, G_FILE_TEST_IS_DIR)) + { + gchar *subprefix; + + subprefix = g_strconcat (prefix, basename, "-", NULL); + get_apps_from_dir (apps, filename, subprefix); + g_free (subprefix); + } + + g_free (filename); + } + + g_dir_close (dir); +} + +typedef struct +{ + gchar **additions; + gchar **removals; + gchar **defaults; +} UnindexedMimeTweaks; + +static void +free_mime_tweaks (gpointer data) +{ + UnindexedMimeTweaks *tweaks = data; + + g_strfreev (tweaks->additions); + g_strfreev (tweaks->removals); + g_strfreev (tweaks->defaults); + + g_slice_free (UnindexedMimeTweaks, tweaks); +} + +static UnindexedMimeTweaks * +desktop_file_dir_unindexed_get_tweaks (DesktopFileDir *dir, + const gchar *mime_type) +{ + UnindexedMimeTweaks *tweaks; + gchar *unaliased_type; + + unaliased_type = _g_unix_content_type_unalias (mime_type); + tweaks = g_hash_table_lookup (dir->mime_tweaks, unaliased_type); + + if (tweaks == NULL) + { + tweaks = g_slice_new0 (UnindexedMimeTweaks); + g_hash_table_insert (dir->mime_tweaks, unaliased_type, tweaks); + } + else + g_free (unaliased_type); + + return tweaks; +} + +/* consumes 'to_add' */ +static void +expand_strv (gchar ***strv_ptr, + gchar **to_add, + gchar * const *blocklist) +{ + guint strv_len, add_len; + gchar **strv; + guint i, j; + + if (!*strv_ptr) + { + *strv_ptr = to_add; + return; + } + + strv = *strv_ptr; + strv_len = g_strv_length (strv); + add_len = g_strv_length (to_add); + strv = g_renew (gchar *, strv, strv_len + add_len + 1); + + for (i = 0; to_add[i]; i++) + { + /* Don't add blocklisted strings */ + if (blocklist) + for (j = 0; blocklist[j]; j++) + if (g_str_equal (to_add[i], blocklist[j])) + goto no_add; + + /* Don't add duplicates already in the list */ + for (j = 0; j < strv_len; j++) + if (g_str_equal (to_add[i], strv[j])) + goto no_add; + + strv[strv_len++] = to_add[i]; + continue; + +no_add: + g_free (to_add[i]); + } + + strv[strv_len] = NULL; + *strv_ptr = strv; + + g_free (to_add); +} + +static void +desktop_file_dir_unindexed_read_mimeapps_list (DesktopFileDir *dir, + const gchar *filename, + const gchar *added_group, + gboolean tweaks_permitted) +{ + UnindexedMimeTweaks *tweaks; + char **desktop_file_ids; + GKeyFile *key_file; + gchar **mime_types; + int i; + + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL)) + { + g_key_file_free (key_file); + return; + } + + mime_types = g_key_file_get_keys (key_file, added_group, NULL, NULL); + + if G_UNLIKELY (mime_types != NULL && !tweaks_permitted) + { + g_warning ("%s contains a [%s] group, but it is not permitted here. Only the non-desktop-specific " + "mimeapps.list file may add or remove associations.", filename, added_group); + g_strfreev (mime_types); + mime_types = NULL; + } + + if (mime_types != NULL) + { + for (i = 0; mime_types[i] != NULL; i++) + { + desktop_file_ids = g_key_file_get_string_list (key_file, added_group, mime_types[i], NULL, NULL); + + if (desktop_file_ids) + { + tweaks = desktop_file_dir_unindexed_get_tweaks (dir, mime_types[i]); + expand_strv (&tweaks->additions, desktop_file_ids, tweaks->removals); + } + } + + g_strfreev (mime_types); + } + + mime_types = g_key_file_get_keys (key_file, REMOVED_ASSOCIATIONS_GROUP, NULL, NULL); + + if G_UNLIKELY (mime_types != NULL && !tweaks_permitted) + { + g_warning ("%s contains a [%s] group, but it is not permitted here. Only the non-desktop-specific " + "mimeapps.list file may add or remove associations.", filename, REMOVED_ASSOCIATIONS_GROUP); + g_strfreev (mime_types); + mime_types = NULL; + } + + if (mime_types != NULL) + { + for (i = 0; mime_types[i] != NULL; i++) + { + desktop_file_ids = g_key_file_get_string_list (key_file, REMOVED_ASSOCIATIONS_GROUP, mime_types[i], NULL, NULL); + + if (desktop_file_ids) + { + tweaks = desktop_file_dir_unindexed_get_tweaks (dir, mime_types[i]); + expand_strv (&tweaks->removals, desktop_file_ids, tweaks->additions); + } + } + + g_strfreev (mime_types); + } + + mime_types = g_key_file_get_keys (key_file, DEFAULT_APPLICATIONS_GROUP, NULL, NULL); + + if (mime_types != NULL) + { + for (i = 0; mime_types[i] != NULL; i++) + { + desktop_file_ids = g_key_file_get_string_list (key_file, DEFAULT_APPLICATIONS_GROUP, mime_types[i], NULL, NULL); + + if (desktop_file_ids) + { + tweaks = desktop_file_dir_unindexed_get_tweaks (dir, mime_types[i]); + expand_strv (&tweaks->defaults, desktop_file_ids, NULL); + } + } + + g_strfreev (mime_types); + } + + g_key_file_free (key_file); +} + +static void +desktop_file_dir_unindexed_read_mimeapps_lists (DesktopFileDir *dir) +{ + const gchar * const *desktops; + gchar *filename; + gint i; + + dir->mime_tweaks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_mime_tweaks); + + /* We process in order of precedence, using a blocklisting approach to + * avoid recording later instructions that conflict with ones we found + * earlier. + * + * We first start with the XDG_CURRENT_DESKTOP files, in precedence + * order. + */ + desktops = get_lowercase_current_desktops (); + for (i = 0; desktops[i]; i++) + { + filename = g_strdup_printf ("%s/%s-mimeapps.list", dir->path, desktops[i]); + desktop_file_dir_unindexed_read_mimeapps_list (dir, filename, ADDED_ASSOCIATIONS_GROUP, FALSE); + g_free (filename); + } + + /* Next, the non-desktop-specific mimeapps.list */ + filename = g_strdup_printf ("%s/mimeapps.list", dir->path); + desktop_file_dir_unindexed_read_mimeapps_list (dir, filename, ADDED_ASSOCIATIONS_GROUP, TRUE); + g_free (filename); + + /* The remaining files are only checked for in directories that might + * contain desktop files (ie: not the config dirs). + */ + if (dir->is_config) + return; + + /* We have 'defaults.list' which was only ever understood by GLib. It + * exists widely, but it has never been part of any spec and it should + * be treated as deprecated. This will be removed in a future + * version. + */ + filename = g_strdup_printf ("%s/defaults.list", dir->path); + desktop_file_dir_unindexed_read_mimeapps_list (dir, filename, ADDED_ASSOCIATIONS_GROUP, FALSE); + g_free (filename); + + /* Finally, the mimeinfo.cache, which is just a cached copy of what we + * would find in the MimeTypes= lines of all of the desktop files. + */ + filename = g_strdup_printf ("%s/mimeinfo.cache", dir->path); + desktop_file_dir_unindexed_read_mimeapps_list (dir, filename, MIME_CACHE_GROUP, TRUE); + g_free (filename); +} + +static void +desktop_file_dir_unindexed_init (DesktopFileDir *dir) +{ + if (!dir->is_config) + get_apps_from_dir (&dir->app_names, dir->path, ""); + + desktop_file_dir_unindexed_read_mimeapps_lists (dir); +} + +static GDesktopAppInfo * +g_desktop_app_info_new_from_filename_unlocked (const char *filename) +{ + GDesktopAppInfo *info = NULL; + + info = g_object_new (G_TYPE_DESKTOP_APP_INFO, "filename", filename, NULL); + + if (!g_desktop_app_info_load_file (info)) + g_clear_object (&info); + + return info; +} + +static GDesktopAppInfo * +desktop_file_dir_unindexed_get_app (DesktopFileDir *dir, + const gchar *desktop_id) +{ + const gchar *filename; + + filename = g_hash_table_lookup (dir->app_names, desktop_id); + + if (!filename) + return NULL; + + return g_desktop_app_info_new_from_filename_unlocked (filename); +} + +static void +desktop_file_dir_unindexed_get_all (DesktopFileDir *dir, + GHashTable *apps) +{ + GHashTableIter iter; + gpointer app_name; + gpointer filename; + + if (dir->app_names == NULL) + return; + + g_hash_table_iter_init (&iter, dir->app_names); + while (g_hash_table_iter_next (&iter, &app_name, &filename)) + { + if (desktop_file_dir_app_name_is_masked (dir, app_name)) + continue; + + add_to_table_if_appropriate (apps, app_name, g_desktop_app_info_new_from_filename_unlocked (filename)); + } +} + +typedef struct _MemoryIndexEntry MemoryIndexEntry; +typedef GHashTable MemoryIndex; + +struct _MemoryIndexEntry +{ + const gchar *app_name; /* pointer to the hashtable key */ + gint match_category; + MemoryIndexEntry *next; +}; + +static void +memory_index_entry_free (gpointer data) +{ + MemoryIndexEntry *mie = data; + + while (mie) + { + MemoryIndexEntry *next = mie->next; + + g_slice_free (MemoryIndexEntry, mie); + mie = next; + } +} + +static void +memory_index_add_token (MemoryIndex *mi, + const gchar *token, + gint match_category, + const gchar *app_name) +{ + MemoryIndexEntry *mie, *first; + + mie = g_slice_new (MemoryIndexEntry); + mie->app_name = app_name; + mie->match_category = match_category; + + first = g_hash_table_lookup (mi, token); + + if (first) + { + mie->next = first->next; + first->next = mie; + } + else + { + mie->next = NULL; + g_hash_table_insert (mi, g_strdup (token), mie); + } +} + +static void +memory_index_add_string (MemoryIndex *mi, + const gchar *string, + gint match_category, + const gchar *app_name) +{ + gchar **tokens, **alternates; + gint i; + + tokens = g_str_tokenize_and_fold (string, NULL, &alternates); + + for (i = 0; tokens[i]; i++) + memory_index_add_token (mi, tokens[i], match_category, app_name); + + for (i = 0; alternates[i]; i++) + memory_index_add_token (mi, alternates[i], match_category, app_name); + + g_strfreev (alternates); + g_strfreev (tokens); +} + +static MemoryIndex * +memory_index_new (void) +{ + return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, memory_index_entry_free); +} + +static void +desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir) +{ + GHashTableIter iter; + gpointer app, path; + + dir->memory_index = memory_index_new (); + dir->memory_implementations = memory_index_new (); + + /* Nothing to search? */ + if (dir->app_names == NULL) + return; + + g_hash_table_iter_init (&iter, dir->app_names); + while (g_hash_table_iter_next (&iter, &app, &path)) + { + GKeyFile *key_file; + + if (desktop_file_dir_app_name_is_masked (dir, app)) + continue; + + key_file = g_key_file_new (); + + if (g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, NULL) && + !g_key_file_get_boolean (key_file, "Desktop Entry", "Hidden", NULL)) + { + /* Index the interesting keys... */ + gchar **implements; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (desktop_key_match_category); i++) + { + const gchar *value; + gchar *raw; + + if (!desktop_key_match_category[i]) + continue; + + raw = g_key_file_get_locale_string (key_file, "Desktop Entry", desktop_key_get_name (i), NULL, NULL); + value = raw; + + if (i == DESKTOP_KEY_Exec && raw != NULL) + { + /* Special handling: only match basename of first field */ + gchar *space; + gchar *slash; + + /* Remove extra arguments, if any */ + space = raw + strcspn (raw, " \t\n"); /* IFS */ + *space = '\0'; + + /* Skip the pathname, if any */ + if ((slash = strrchr (raw, '/'))) + value = slash + 1; + + /* Don't match on blocklisted binaries like interpreters */ + if (g_strv_contains (exec_key_match_blocklist, value)) + value = NULL; + } + + if (value) + memory_index_add_string (dir->memory_index, value, desktop_key_match_category[i], app); + + g_free (raw); + } + + /* Make note of the Implements= line */ + implements = g_key_file_get_string_list (key_file, "Desktop Entry", "Implements", NULL, NULL); + for (i = 0; implements && implements[i]; i++) + memory_index_add_token (dir->memory_implementations, implements[i], 0, app); + g_strfreev (implements); + } + + g_key_file_free (key_file); + } +} + +static void +desktop_file_dir_unindexed_search (DesktopFileDir *dir, + const gchar *search_token) +{ + GHashTableIter iter; + gpointer key, value; + + if (!dir->memory_index) + desktop_file_dir_unindexed_setup_search (dir); + + g_hash_table_iter_init (&iter, dir->memory_index); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + MemoryIndexEntry *mie = value; + + if (!g_str_has_prefix (key, search_token)) + continue; + + while (mie) + { + add_token_result (mie->app_name, mie->match_category); + mie = mie->next; + } + } +} + +static gboolean +array_contains (GPtrArray *array, + const gchar *str) +{ + guint i; + + for (i = 0; i < array->len; i++) + if (g_str_equal (array->pdata[i], str)) + return TRUE; + + return FALSE; +} + +static void +desktop_file_dir_unindexed_mime_lookup (DesktopFileDir *dir, + const gchar *mime_type, + GPtrArray *hits, + GPtrArray *blocklist) +{ + UnindexedMimeTweaks *tweaks; + gint i; + + tweaks = g_hash_table_lookup (dir->mime_tweaks, mime_type); + + if (!tweaks) + return; + + if (tweaks->additions) + { + for (i = 0; tweaks->additions[i]; i++) + { + gchar *app_name = tweaks->additions[i]; + + if (!desktop_file_dir_app_name_is_masked (dir, app_name) && + !array_contains (blocklist, app_name) && !array_contains (hits, app_name)) + g_ptr_array_add (hits, app_name); + } + } + + if (tweaks->removals) + { + for (i = 0; tweaks->removals[i]; i++) + { + gchar *app_name = tweaks->removals[i]; + + if (!desktop_file_dir_app_name_is_masked (dir, app_name) && + !array_contains (blocklist, app_name) && !array_contains (hits, app_name)) + g_ptr_array_add (blocklist, app_name); + } + } +} + +static void +desktop_file_dir_unindexed_default_lookup (DesktopFileDir *dir, + const gchar *mime_type, + GPtrArray *results) +{ + UnindexedMimeTweaks *tweaks; + gint i; + + tweaks = g_hash_table_lookup (dir->mime_tweaks, mime_type); + + if (!tweaks || !tweaks->defaults) + return; + + for (i = 0; tweaks->defaults[i]; i++) + { + gchar *app_name = tweaks->defaults[i]; + + if (!array_contains (results, app_name)) + g_ptr_array_add (results, app_name); + } +} + +static void +desktop_file_dir_unindexed_get_implementations (DesktopFileDir *dir, + GList **results, + const gchar *interface) +{ + MemoryIndexEntry *mie; + + if (!dir->memory_index) + desktop_file_dir_unindexed_setup_search (dir); + + for (mie = g_hash_table_lookup (dir->memory_implementations, interface); mie; mie = mie->next) + *results = g_list_prepend (*results, g_strdup (mie->app_name)); +} + +/* DesktopFileDir "API" {{{2 */ + +/*< internal > + * desktop_file_dir_new: + * @data_dir: an XDG_DATA_DIR + * + * Creates a #DesktopFileDir for the corresponding @data_dir. + */ +static DesktopFileDir * +desktop_file_dir_new (const gchar *data_dir) +{ + DesktopFileDir *dir = g_new0 (DesktopFileDir, 1); + + g_atomic_ref_count_init (&dir->ref_count); + dir->path = g_build_filename (data_dir, "applications", NULL); + + return g_steal_pointer (&dir); +} + +/*< internal > + * desktop_file_dir_new_for_config: + * @config_dir: an XDG_CONFIG_DIR + * + * Just the same as desktop_file_dir_new() except that it does not + * add the "applications" directory. It also marks the directory as + * config-only, which prevents us from attempting to find desktop files + * here. + */ +static DesktopFileDir * +desktop_file_dir_new_for_config (const gchar *config_dir) +{ + DesktopFileDir *dir = g_new0 (DesktopFileDir, 1); + + g_atomic_ref_count_init (&dir->ref_count); + dir->path = g_strdup (config_dir); + dir->is_config = TRUE; + + return g_steal_pointer (&dir); +} + +/*< internal > + * desktop_file_dir_reset: + * @dir: a #DesktopFileDir + * + * Cleans up @dir, releasing most resources that it was using. + */ +static void +desktop_file_dir_reset (DesktopFileDir *dir) +{ + if (dir->alternatively_watching) + { + g_free (dir->alternatively_watching); + dir->alternatively_watching = NULL; + } + + if (dir->monitor) + { + g_signal_handlers_disconnect_by_func (dir->monitor, desktop_file_dir_changed, dir); + g_file_monitor_cancel (dir->monitor); + g_object_unref (dir->monitor); + dir->monitor = NULL; + } + + if (dir->app_names) + { + g_hash_table_unref (dir->app_names); + dir->app_names = NULL; + } + + if (dir->memory_index) + { + g_hash_table_unref (dir->memory_index); + dir->memory_index = NULL; + } + + if (dir->mime_tweaks) + { + g_hash_table_unref (dir->mime_tweaks); + dir->mime_tweaks = NULL; + } + + if (dir->memory_implementations) + { + g_hash_table_unref (dir->memory_implementations); + dir->memory_implementations = NULL; + } + + dir->is_setup = FALSE; +} + +static void +closure_notify_cb (gpointer data, + GClosure *closure) +{ + DesktopFileDir *dir = data; + desktop_file_dir_unref (dir); +} + +/*< internal > + * desktop_file_dir_init: + * @dir: a #DesktopFileDir + * + * Does initial setup for @dir + * + * You should only call this if @dir is not already setup. + */ +static void +desktop_file_dir_init (DesktopFileDir *dir) +{ + const gchar *watch_dir; + + g_assert (!dir->is_setup); + + g_assert (!dir->alternatively_watching); + g_assert (!dir->monitor); + + dir->alternatively_watching = desktop_file_dir_get_alternative_dir (dir); + watch_dir = dir->alternatively_watching ? dir->alternatively_watching : dir->path; + + /* There is a very thin race here if the watch_dir has been _removed_ + * between when we checked for it and when we establish the watch. + * Removes probably don't happen in usual operation, and even if it + * does (and we catch the unlikely race), the only degradation is that + * we will fall back to polling. + */ + dir->monitor = g_local_file_monitor_new_in_worker (watch_dir, TRUE, G_FILE_MONITOR_NONE, + desktop_file_dir_changed, + desktop_file_dir_ref (dir), + closure_notify_cb, NULL); + + desktop_file_dir_unindexed_init (dir); + + dir->is_setup = TRUE; +} + +/*< internal > + * desktop_file_dir_get_app: + * @dir: a DesktopFileDir + * @desktop_id: the desktop ID to load + * + * Creates the #GDesktopAppInfo for the given @desktop_id if it exists + * within @dir, even if it is hidden. + * + * This function does not check if @desktop_id would be masked by a + * directory with higher precedence. The caller must do so. + */ +static GDesktopAppInfo * +desktop_file_dir_get_app (DesktopFileDir *dir, + const gchar *desktop_id) +{ + if (!dir->app_names) + return NULL; + + return desktop_file_dir_unindexed_get_app (dir, desktop_id); +} + +/*< internal > + * desktop_file_dir_get_all: + * @dir: a DesktopFileDir + * @apps: a #GHashTable + * + * Loads all desktop files in @dir and adds them to @apps, careful to + * ensure we don't add any files masked by a similarly-named file in a + * higher-precedence directory. + */ +static void +desktop_file_dir_get_all (DesktopFileDir *dir, + GHashTable *apps) +{ + desktop_file_dir_unindexed_get_all (dir, apps); +} + +/*< internal > + * desktop_file_dir_mime_lookup: + * @dir: a #DesktopFileDir + * @mime_type: the mime type to look up + * @hits: the array to store the hits + * @blocklist: the array to store the blocklist + * + * Does a lookup of a mimetype against one desktop file directory, + * recording any hits and blocklisting and "Removed" associations (so + * later directories don't record them as hits). + * + * The items added to @hits are duplicated, but the ones in @blocklist + * are weak pointers. This facilitates simply freeing the blocklist + * (which is only used for internal bookkeeping) but using the pdata of + * @hits as the result of the operation. + */ +static void +desktop_file_dir_mime_lookup (DesktopFileDir *dir, + const gchar *mime_type, + GPtrArray *hits, + GPtrArray *blocklist) +{ + desktop_file_dir_unindexed_mime_lookup (dir, mime_type, hits, blocklist); +} + +/*< internal > + * desktop_file_dir_default_lookup: + * @dir: a #DesktopFileDir + * @mime_type: the mime type to look up + * @results: an array to store the results in + * + * Collects the "default" applications for a given mime type from @dir. + */ +static void +desktop_file_dir_default_lookup (DesktopFileDir *dir, + const gchar *mime_type, + GPtrArray *results) +{ + desktop_file_dir_unindexed_default_lookup (dir, mime_type, results); +} + +/*< internal > + * desktop_file_dir_search: + * @dir: a #DesktopFileDir + * @term: a normalised and casefolded search term + * + * Finds the names of applications in @dir that match @term. + */ +static void +desktop_file_dir_search (DesktopFileDir *dir, + const gchar *search_token) +{ + desktop_file_dir_unindexed_search (dir, search_token); +} + +static void +desktop_file_dir_get_implementations (DesktopFileDir *dir, + GList **results, + const gchar *interface) +{ + desktop_file_dir_unindexed_get_implementations (dir, results, interface); +} + +/* Lock/unlock and global setup API {{{2 */ + +static void +desktop_file_dirs_lock (void) +{ + guint i; + const gchar *user_config_dir = g_get_user_config_dir (); + + g_mutex_lock (&desktop_file_dir_lock); + + /* If the XDG dirs configuration has changed (expected only during tests), + * clear and reload the state. */ + if (desktop_file_dirs_config_dir != NULL && + g_strcmp0 (desktop_file_dirs_config_dir, user_config_dir) != 0) + { + g_debug ("%s: Resetting desktop app info dirs from %s to %s", + G_STRFUNC, desktop_file_dirs_config_dir, user_config_dir); + + g_ptr_array_set_size (desktop_file_dirs, 0); + g_clear_pointer (&desktop_file_dir_user_config, desktop_file_dir_unref); + g_clear_pointer (&desktop_file_dir_user_data, desktop_file_dir_unref); + } + + if (desktop_file_dirs == NULL || desktop_file_dirs->len == 0) + { + const char * const *dirs; + gint i; + + if (desktop_file_dirs == NULL) + desktop_file_dirs = g_ptr_array_new_with_free_func ((GDestroyNotify) desktop_file_dir_unref); + + /* First, the configs. Highest priority: the user's ~/.config */ + desktop_file_dir_user_config = desktop_file_dir_new_for_config (user_config_dir); + g_ptr_array_add (desktop_file_dirs, desktop_file_dir_ref (desktop_file_dir_user_config)); + + /* Next, the system configs (/etc/xdg, and so on). */ + dirs = g_get_system_config_dirs (); + for (i = 0; dirs[i]; i++) + g_ptr_array_add (desktop_file_dirs, desktop_file_dir_new_for_config (dirs[i])); + + /* Now the data. Highest priority: the user's ~/.local/share/applications */ + desktop_file_dir_user_data = desktop_file_dir_new (g_get_user_data_dir ()); + g_ptr_array_add (desktop_file_dirs, desktop_file_dir_ref (desktop_file_dir_user_data)); + + /* Following that, XDG_DATA_DIRS/applications, in order */ + dirs = g_get_system_data_dirs (); + for (i = 0; dirs[i]; i++) + g_ptr_array_add (desktop_file_dirs, desktop_file_dir_new (dirs[i])); + + /* The list of directories will never change after this, unless + * g_get_user_config_dir() changes due to %G_TEST_OPTION_ISOLATE_DIRS. */ + desktop_file_dirs_config_dir = user_config_dir; + } + + for (i = 0; i < desktop_file_dirs->len; i++) + if (!((DesktopFileDir *) g_ptr_array_index (desktop_file_dirs, i))->is_setup) + desktop_file_dir_init (g_ptr_array_index (desktop_file_dirs, i)); +} + +static void +desktop_file_dirs_unlock (void) +{ + g_mutex_unlock (&desktop_file_dir_lock); +} + +static void +desktop_file_dirs_invalidate_user_config (void) +{ + g_mutex_lock (&desktop_file_dir_lock); + + if (desktop_file_dir_user_config != NULL) + desktop_file_dir_reset (desktop_file_dir_user_config); + + g_mutex_unlock (&desktop_file_dir_lock); +} + +static void +desktop_file_dirs_invalidate_user_data (void) +{ + g_mutex_lock (&desktop_file_dir_lock); + + if (desktop_file_dir_user_data != NULL) + desktop_file_dir_reset (desktop_file_dir_user_data); + + g_mutex_unlock (&desktop_file_dir_lock); +} + +/* GDesktopAppInfo implementation {{{1 */ +/* GObject implementation {{{2 */ +static void +g_desktop_app_info_finalize (GObject *object) +{ + GDesktopAppInfo *info; + + info = G_DESKTOP_APP_INFO (object); + + g_free (info->desktop_id); + g_free (info->filename); + + if (info->keyfile) + g_key_file_unref (info->keyfile); + + g_free (info->name); + g_free (info->generic_name); + g_free (info->fullname); + g_free (info->comment); + g_free (info->icon_name); + if (info->icon) + g_object_unref (info->icon); + g_strfreev (info->keywords); + g_strfreev (info->only_show_in); + g_strfreev (info->not_show_in); + g_free (info->try_exec); + g_free (info->exec); + g_free (info->binary); + g_free (info->path); + g_free (info->categories); + g_free (info->startup_wm_class); + g_strfreev (info->mime_types); + g_free (info->app_id); + g_strfreev (info->actions); + + G_OBJECT_CLASS (g_desktop_app_info_parent_class)->finalize (object); +} + +static void +g_desktop_app_info_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDesktopAppInfo *self = G_DESKTOP_APP_INFO (object); + + switch (prop_id) + { + case PROP_FILENAME: + self->filename = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_desktop_app_info_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDesktopAppInfo *self = G_DESKTOP_APP_INFO (object); + + switch (prop_id) + { + case PROP_FILENAME: + g_value_set_string (value, self->filename); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_desktop_app_info_class_init (GDesktopAppInfoClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = g_desktop_app_info_get_property; + gobject_class->set_property = g_desktop_app_info_set_property; + gobject_class->finalize = g_desktop_app_info_finalize; + + /** + * GDesktopAppInfo:filename: + * + * The origin filename of this #GDesktopAppInfo + */ + g_object_class_install_property (gobject_class, + PROP_FILENAME, + g_param_spec_string ("filename", "Filename", "", NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + +static void +g_desktop_app_info_init (GDesktopAppInfo *local) +{ +} + +/* Construction... {{{2 */ + +/*< internal > + * binary_from_exec: + * @exec: an exec line + * + * Returns the first word in an exec line (ie: the binary name). + * + * If @exec is " progname --foo %F" then returns "progname". + */ +static char * +binary_from_exec (const char *exec) +{ + const char *p, *start; + + p = exec; + while (*p == ' ') + p++; + start = p; + while (*p != ' ' && *p != 0) + p++; + + return g_strndup (start, p - start); +} + +/*< internal > + * g_desktop_app_info_get_desktop_id_for_filename + * @self: #GDesktopAppInfo to get desktop id of + * + * Tries to find the desktop ID for a particular `.desktop` filename, as per the + * [Desktop Entry Specification](https://specifications.freedesktop.org/desktop- + * entry-spec/desktop-entry-spec-latest.html#desktop-file-id). + * + * Returns: desktop id or basename if filename is unknown. + */ +static char * +g_desktop_app_info_get_desktop_id_for_filename (GDesktopAppInfo *self) +{ + guint i; + gchar *desktop_id = NULL; + + g_return_val_if_fail (self->filename != NULL, NULL); + + for (i = 0; i < desktop_file_dirs->len; i++) + { + DesktopFileDir *dir = g_ptr_array_index (desktop_file_dirs, i); + GHashTable *app_names; + GHashTableIter iter; + gpointer key, value; + + app_names = dir->app_names; + + if (!app_names) + continue; + + g_hash_table_iter_init (&iter, app_names); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + if (!strcmp (value, self->filename)) + { + desktop_id = g_strdup (key); + break; + } + } + + if (desktop_id) + break; + } + + if (!desktop_id) + desktop_id = g_path_get_basename (self->filename); + + return g_steal_pointer (&desktop_id); +} + +static gboolean +g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, + GKeyFile *key_file) +{ + char *start_group; + char *type; + char *try_exec; + char *exec; + gboolean bus_activatable; + + start_group = g_key_file_get_start_group (key_file); + if (start_group == NULL || strcmp (start_group, G_KEY_FILE_DESKTOP_GROUP) != 0) + { + g_free (start_group); + return FALSE; + } + g_free (start_group); + + type = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TYPE, + NULL); + if (type == NULL || strcmp (type, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0) + { + g_free (type); + return FALSE; + } + g_free (type); + + try_exec = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, + NULL); + if (try_exec && try_exec[0] != '\0') + { + char *t; + t = g_find_program_in_path (try_exec); + if (t == NULL) + { + g_free (try_exec); + return FALSE; + } + g_free (t); + } + + exec = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, + NULL); + if (exec && exec[0] != '\0') + { + gint argc; + char **argv; + if (!g_shell_parse_argv (exec, &argc, &argv, NULL)) + { + g_free (exec); + g_free (try_exec); + return FALSE; + } + else + { + char *t; + + /* Since @exec is not an empty string, there must be at least one + * argument, so dereferencing argv[0] should return non-NULL. */ + g_assert (argc > 0); + t = g_find_program_in_path (argv[0]); + g_strfreev (argv); + + if (t == NULL) + { + g_free (exec); + g_free (try_exec); + return FALSE; + } + g_free (t); + } + } + + info->name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL); + info->generic_name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, GENERIC_NAME_KEY, NULL, NULL); + info->fullname = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, FULL_NAME_KEY, NULL, NULL); + info->keywords = g_key_file_get_locale_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, KEYWORDS_KEY, NULL, NULL, NULL); + info->comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL); + info->nodisplay = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL) != FALSE; + info->icon_name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL, NULL); + info->only_show_in = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, NULL, NULL); + info->not_show_in = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, NULL, NULL); + info->try_exec = try_exec; + info->exec = exec; + info->path = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_PATH, NULL); + info->terminal = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TERMINAL, NULL) != FALSE; + info->startup_notify = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, NULL) != FALSE; + info->no_fuse = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GIO-NoFuse", NULL) != FALSE; + info->hidden = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL) != FALSE; + info->categories = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_CATEGORIES, NULL); + info->startup_wm_class = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, STARTUP_WM_CLASS_KEY, NULL); + info->mime_types = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_MIME_TYPE, NULL, NULL); + bus_activatable = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE, NULL); + info->actions = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ACTIONS, NULL, NULL); + + /* Remove the special-case: no Actions= key just means 0 extra actions */ + if (info->actions == NULL) + info->actions = g_new0 (gchar *, 0 + 1); + + info->icon = NULL; + if (info->icon_name) + { + if (g_path_is_absolute (info->icon_name)) + { + GFile *file; + + file = g_file_new_for_path (info->icon_name); + info->icon = g_file_icon_new (file); + g_object_unref (file); + } + else + { + char *p; + + /* Work around a common mistake in desktop files */ + if ((p = strrchr (info->icon_name, '.')) != NULL && + (strcmp (p, ".png") == 0 || + strcmp (p, ".xpm") == 0 || + strcmp (p, ".svg") == 0)) + *p = 0; + + info->icon = g_themed_icon_new (info->icon_name); + } + } + + if (info->exec) + info->binary = binary_from_exec (info->exec); + + if (info->path && info->path[0] == '\0') + { + g_free (info->path); + info->path = NULL; + } + + /* Can only be DBusActivatable if we know the filename, which means + * that this won't work for the load-from-keyfile case. + */ + if (bus_activatable && info->filename) + { + gchar *basename; + gchar *last_dot; + + basename = g_path_get_basename (info->filename); + last_dot = strrchr (basename, '.'); + + if (last_dot && g_str_equal (last_dot, ".desktop")) + { + *last_dot = '\0'; + + if (g_dbus_is_name (basename) && basename[0] != ':') + info->app_id = g_strdup (basename); + } + + g_free (basename); + } + + if (info->filename) + info->desktop_id = g_desktop_app_info_get_desktop_id_for_filename (info); + + info->keyfile = g_key_file_ref (key_file); + + return TRUE; +} + +static gboolean +g_desktop_app_info_load_file (GDesktopAppInfo *self) +{ + GKeyFile *key_file; + gboolean retval = FALSE; + + g_return_val_if_fail (self->filename != NULL, FALSE); + + key_file = g_key_file_new (); + + if (g_key_file_load_from_file (key_file, self->filename, G_KEY_FILE_NONE, NULL)) + retval = g_desktop_app_info_load_from_keyfile (self, key_file); + + g_key_file_unref (key_file); + return retval; +} + +/** + * g_desktop_app_info_new_from_keyfile: + * @key_file: an opened #GKeyFile + * + * Creates a new #GDesktopAppInfo. + * + * Returns: (nullable): a new #GDesktopAppInfo or %NULL on error. + * + * Since: 2.18 + **/ +GDesktopAppInfo * +g_desktop_app_info_new_from_keyfile (GKeyFile *key_file) +{ + GDesktopAppInfo *info; + + info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL); + info->filename = NULL; + + desktop_file_dirs_lock (); + + if (!g_desktop_app_info_load_from_keyfile (info, key_file)) + g_clear_object (&info); + + desktop_file_dirs_unlock (); + + return info; +} + +/** + * g_desktop_app_info_new_from_filename: + * @filename: (type filename): the path of a desktop file, in the GLib + * filename encoding + * + * Creates a new #GDesktopAppInfo. + * + * Returns: (nullable): a new #GDesktopAppInfo or %NULL on error. + **/ +GDesktopAppInfo * +g_desktop_app_info_new_from_filename (const char *filename) +{ + GDesktopAppInfo *info = NULL; + + desktop_file_dirs_lock (); + + info = g_desktop_app_info_new_from_filename_unlocked (filename); + + desktop_file_dirs_unlock (); + + return info; +} + +/** + * g_desktop_app_info_new: + * @desktop_id: the desktop file id + * + * Creates a new #GDesktopAppInfo based on a desktop file id. + * + * A desktop file id is the basename of the desktop file, including the + * .desktop extension. GIO is looking for a desktop file with this name + * in the `applications` subdirectories of the XDG + * data directories (i.e. the directories specified in the `XDG_DATA_HOME` + * and `XDG_DATA_DIRS` environment variables). GIO also supports the + * prefix-to-subdirectory mapping that is described in the + * [Menu Spec](http://standards.freedesktop.org/menu-spec/latest/) + * (i.e. a desktop id of kde-foo.desktop will match + * `/usr/share/applications/kde/foo.desktop`). + * + * Returns: (nullable): a new #GDesktopAppInfo, or %NULL if no desktop + * file with that id exists. + */ +GDesktopAppInfo * +g_desktop_app_info_new (const char *desktop_id) +{ + GDesktopAppInfo *appinfo = NULL; + guint i; + + desktop_file_dirs_lock (); + + for (i = 0; i < desktop_file_dirs->len; i++) + { + appinfo = desktop_file_dir_get_app (g_ptr_array_index (desktop_file_dirs, i), desktop_id); + + if (appinfo) + break; + } + + desktop_file_dirs_unlock (); + + if (appinfo == NULL) + return NULL; + + g_free (appinfo->desktop_id); + appinfo->desktop_id = g_strdup (desktop_id); + + if (g_desktop_app_info_get_is_hidden (appinfo)) + { + g_object_unref (appinfo); + appinfo = NULL; + } + + return appinfo; +} + +static GAppInfo * +g_desktop_app_info_dup (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + GDesktopAppInfo *new_info; + + new_info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL); + + new_info->filename = g_strdup (info->filename); + new_info->desktop_id = g_strdup (info->desktop_id); + + if (info->keyfile) + new_info->keyfile = g_key_file_ref (info->keyfile); + + new_info->name = g_strdup (info->name); + new_info->generic_name = g_strdup (info->generic_name); + new_info->fullname = g_strdup (info->fullname); + new_info->keywords = g_strdupv (info->keywords); + new_info->comment = g_strdup (info->comment); + new_info->nodisplay = info->nodisplay; + new_info->icon_name = g_strdup (info->icon_name); + if (info->icon) + new_info->icon = g_object_ref (info->icon); + new_info->only_show_in = g_strdupv (info->only_show_in); + new_info->not_show_in = g_strdupv (info->not_show_in); + new_info->try_exec = g_strdup (info->try_exec); + new_info->exec = g_strdup (info->exec); + new_info->binary = g_strdup (info->binary); + new_info->path = g_strdup (info->path); + new_info->app_id = g_strdup (info->app_id); + new_info->hidden = info->hidden; + new_info->terminal = info->terminal; + new_info->startup_notify = info->startup_notify; + + return G_APP_INFO (new_info); +} + +/* GAppInfo interface implementation functions {{{2 */ + +static gboolean +g_desktop_app_info_equal (GAppInfo *appinfo1, + GAppInfo *appinfo2) +{ + GDesktopAppInfo *info1 = G_DESKTOP_APP_INFO (appinfo1); + GDesktopAppInfo *info2 = G_DESKTOP_APP_INFO (appinfo2); + + if (info1->desktop_id == NULL || + info2->desktop_id == NULL) + return info1 == info2; + + return strcmp (info1->desktop_id, info2->desktop_id) == 0; +} + +static const char * +g_desktop_app_info_get_id (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->desktop_id; +} + +static const char * +g_desktop_app_info_get_name (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->name == NULL) + return _("Unnamed"); + return info->name; +} + +static const char * +g_desktop_app_info_get_display_name (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->fullname == NULL) + return g_desktop_app_info_get_name (appinfo); + return info->fullname; +} + +/** + * g_desktop_app_info_get_is_hidden: + * @info: a #GDesktopAppInfo. + * + * A desktop file is hidden if the Hidden key in it is + * set to True. + * + * Returns: %TRUE if hidden, %FALSE otherwise. + **/ +gboolean +g_desktop_app_info_get_is_hidden (GDesktopAppInfo *info) +{ + return info->hidden; +} + +/** + * g_desktop_app_info_get_filename: + * @info: a #GDesktopAppInfo + * + * When @info was created from a known filename, return it. In some + * situations such as the #GDesktopAppInfo returned from + * g_desktop_app_info_new_from_keyfile(), this function will return %NULL. + * + * Returns: (nullable) (type filename): The full path to the file for @info, + * or %NULL if not known. + * Since: 2.24 + */ +const char * +g_desktop_app_info_get_filename (GDesktopAppInfo *info) +{ + return info->filename; +} + +static const char * +g_desktop_app_info_get_description (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->comment; +} + +static const char * +g_desktop_app_info_get_executable (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->binary; +} + +static const char * +g_desktop_app_info_get_commandline (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->exec; +} + +static GIcon * +g_desktop_app_info_get_icon (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->icon; +} + +/** + * g_desktop_app_info_get_categories: + * @info: a #GDesktopAppInfo + * + * Gets the categories from the desktop file. + * + * Returns: (nullable): The unparsed Categories key from the desktop file; + * i.e. no attempt is made to split it by ';' or validate it. + */ +const char * +g_desktop_app_info_get_categories (GDesktopAppInfo *info) +{ + return info->categories; +} + +/** + * g_desktop_app_info_get_keywords: + * @info: a #GDesktopAppInfo + * + * Gets the keywords from the desktop file. + * + * Returns: (transfer none): The value of the Keywords key + * + * Since: 2.32 + */ +const char * const * +g_desktop_app_info_get_keywords (GDesktopAppInfo *info) +{ + return (const char * const *)info->keywords; +} + +/** + * g_desktop_app_info_get_generic_name: + * @info: a #GDesktopAppInfo + * + * Gets the generic name from the desktop file. + * + * Returns: (nullable): The value of the GenericName key + */ +const char * +g_desktop_app_info_get_generic_name (GDesktopAppInfo *info) +{ + return info->generic_name; +} + +/** + * g_desktop_app_info_get_nodisplay: + * @info: a #GDesktopAppInfo + * + * Gets the value of the NoDisplay key, which helps determine if the + * application info should be shown in menus. See + * %G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY and g_app_info_should_show(). + * + * Returns: The value of the NoDisplay key + * + * Since: 2.30 + */ +gboolean +g_desktop_app_info_get_nodisplay (GDesktopAppInfo *info) +{ + return info->nodisplay; +} + +/** + * g_desktop_app_info_get_show_in: + * @info: a #GDesktopAppInfo + * @desktop_env: (nullable): a string specifying a desktop name + * + * Checks if the application info should be shown in menus that list available + * applications for a specific name of the desktop, based on the + * `OnlyShowIn` and `NotShowIn` keys. + * + * @desktop_env should typically be given as %NULL, in which case the + * `XDG_CURRENT_DESKTOP` environment variable is consulted. If you want + * to override the default mechanism then you may specify @desktop_env, + * but this is not recommended. + * + * Note that g_app_info_should_show() for @info will include this check (with + * %NULL for @desktop_env) as well as additional checks. + * + * Returns: %TRUE if the @info should be shown in @desktop_env according to the + * `OnlyShowIn` and `NotShowIn` keys, %FALSE + * otherwise. + * + * Since: 2.30 + */ +gboolean +g_desktop_app_info_get_show_in (GDesktopAppInfo *info, + const gchar *desktop_env) +{ + const gchar *specified_envs[] = { desktop_env, NULL }; + const gchar * const *envs; + gint i; + + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), FALSE); + + if (desktop_env) + envs = specified_envs; + else + envs = get_current_desktops (NULL); + + for (i = 0; envs[i]; i++) + { + gint j; + + if (info->only_show_in) + for (j = 0; info->only_show_in[j]; j++) + if (g_str_equal (info->only_show_in[j], envs[i])) + return TRUE; + + if (info->not_show_in) + for (j = 0; info->not_show_in[j]; j++) + if (g_str_equal (info->not_show_in[j], envs[i])) + return FALSE; + } + + return info->only_show_in == NULL; +} + +/* Launching... {{{2 */ + +static char * +expand_macro_single (char macro, const char *uri) +{ + GFile *file; + char *result = NULL; + char *path = NULL; + char *name; + + file = g_file_new_for_uri (uri); + + switch (macro) + { + case 'u': + case 'U': + result = g_shell_quote (uri); + break; + case 'f': + case 'F': + path = g_file_get_path (file); + if (path) + result = g_shell_quote (path); + break; + case 'd': + case 'D': + path = g_file_get_path (file); + if (path) + { + name = g_path_get_dirname (path); + result = g_shell_quote (name); + g_free (name); + } + break; + case 'n': + case 'N': + path = g_file_get_path (file); + if (path) + { + name = g_path_get_basename (path); + result = g_shell_quote (name); + g_free (name); + } + break; + } + + g_object_unref (file); + g_free (path); + + return result; +} + +static char * +expand_macro_uri (char macro, const char *uri, gboolean force_file_uri, char force_file_uri_macro) +{ + char *expanded = NULL; + + g_return_val_if_fail (uri != NULL, NULL); + + if (!force_file_uri || + /* Pass URI if it contains an anchor */ + strchr (uri, '#') != NULL) + { + expanded = expand_macro_single (macro, uri); + } + else + { + expanded = expand_macro_single (force_file_uri_macro, uri); + if (expanded == NULL) + expanded = expand_macro_single (macro, uri); + } + + return expanded; +} + +static void +expand_macro (char macro, + GString *exec, + GDesktopAppInfo *info, + GList **uri_list) +{ + GList *uris = *uri_list; + char *expanded = NULL; + gboolean force_file_uri; + char force_file_uri_macro; + const char *uri; + + g_return_if_fail (exec != NULL); + + /* On %u and %U, pass POSIX file path pointing to the URI via + * the FUSE mount in ~/.gvfs. Note that if the FUSE daemon isn't + * running or the URI doesn't have a POSIX file path via FUSE + * we'll just pass the URI. + */ + force_file_uri_macro = macro; + force_file_uri = FALSE; + if (!info->no_fuse) + { + switch (macro) + { + case 'u': + force_file_uri_macro = 'f'; + force_file_uri = TRUE; + break; + case 'U': + force_file_uri_macro = 'F'; + force_file_uri = TRUE; + break; + default: + break; + } + } + + switch (macro) + { + case 'u': + case 'f': + case 'd': + case 'n': + if (uris) + { + uri = uris->data; + expanded = expand_macro_uri (macro, uri, + force_file_uri, force_file_uri_macro); + if (expanded) + { + g_string_append (exec, expanded); + g_free (expanded); + } + uris = uris->next; + } + + break; + + case 'U': + case 'F': + case 'D': + case 'N': + while (uris) + { + uri = uris->data; + expanded = expand_macro_uri (macro, uri, + force_file_uri, force_file_uri_macro); + if (expanded) + { + g_string_append (exec, expanded); + g_free (expanded); + } + + uris = uris->next; + + if (uris != NULL && expanded) + g_string_append_c (exec, ' '); + } + + break; + + case 'i': + if (info->icon_name) + { + g_string_append (exec, "--icon "); + expanded = g_shell_quote (info->icon_name); + g_string_append (exec, expanded); + g_free (expanded); + } + break; + + case 'c': + if (info->name) + { + expanded = g_shell_quote (info->name); + g_string_append (exec, expanded); + g_free (expanded); + } + break; + + case 'k': + if (info->filename) + { + expanded = g_shell_quote (info->filename); + g_string_append (exec, expanded); + g_free (expanded); + } + break; + + case 'm': /* deprecated */ + break; + + case '%': + g_string_append_c (exec, '%'); + break; + } + + *uri_list = uris; +} + +static gboolean +expand_application_parameters (GDesktopAppInfo *info, + const gchar *exec_line, + GList **uris, + int *argc, + char ***argv, + GError **error) +{ + GList *uri_list = *uris; + const char *p = exec_line; + GString *expanded_exec; + gboolean res; + + if (exec_line == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Desktop file didn’t specify Exec field")); + return FALSE; + } + + expanded_exec = g_string_new (NULL); + + while (*p) + { + if (p[0] == '%' && p[1] != '\0') + { + expand_macro (p[1], expanded_exec, info, uris); + p++; + } + else + g_string_append_c (expanded_exec, *p); + + p++; + } + + /* No file substitutions */ + if (uri_list == *uris && uri_list != NULL) + { + /* If there is no macro default to %f. This is also what KDE does */ + g_string_append_c (expanded_exec, ' '); + expand_macro ('f', expanded_exec, info, uris); + } + + res = g_shell_parse_argv (expanded_exec->str, argc, argv, error); + g_string_free (expanded_exec, TRUE); + return res; +} + +static gboolean +prepend_terminal_to_vector (int *argc, + char ***argv) +{ +#ifndef G_OS_WIN32 + char **real_argv; + int real_argc; + int i, j; + char **term_argv = NULL; + int term_argc = 0; + char *check; + char **the_argv; + + g_return_val_if_fail (argc != NULL, FALSE); + g_return_val_if_fail (argv != NULL, FALSE); + + /* sanity */ + if(*argv == NULL) + *argc = 0; + + the_argv = *argv; + + /* compute size if not given */ + if (*argc < 0) + { + for (i = 0; the_argv[i] != NULL; i++) + ; + *argc = i; + } + + term_argc = 2; + term_argv = g_new0 (char *, 3); + + check = g_find_program_in_path ("gnome-terminal"); + if (check != NULL) + { + term_argv[0] = check; + /* Since 2017, gnome-terminal has preferred `--` over `-x` or `-e`. */ + term_argv[1] = g_strdup ("--"); + } + else + { + if (check == NULL) + check = g_find_program_in_path ("mate-terminal"); + if (check == NULL) + check = g_find_program_in_path ("xfce4-terminal"); + if (check != NULL) + { + term_argv[0] = check; + /* Note that gnome-terminal takes -x and + * as -e in gnome-terminal is broken we use that. */ + term_argv[1] = g_strdup ("-x"); + } + else + { + if (check == NULL) + check = g_find_program_in_path ("tilix"); + if (check == NULL) + check = g_find_program_in_path ("konsole"); + if (check == NULL) + check = g_find_program_in_path ("nxterm"); + if (check == NULL) + check = g_find_program_in_path ("color-xterm"); + if (check == NULL) + check = g_find_program_in_path ("rxvt"); + if (check == NULL) + check = g_find_program_in_path ("dtterm"); + if (check == NULL) + check = g_find_program_in_path ("xterm"); + if (check == NULL) + { + g_debug ("Couldn’t find a known terminal"); + g_free (term_argv); + return FALSE; + } + term_argv[0] = check; + term_argv[1] = g_strdup ("-e"); + } + } + + real_argc = term_argc + *argc; + real_argv = g_new (char *, real_argc + 1); + + for (i = 0; i < term_argc; i++) + real_argv[i] = term_argv[i]; + + for (j = 0; j < *argc; j++, i++) + real_argv[i] = (char *)the_argv[j]; + + real_argv[i] = NULL; + + g_free (*argv); + *argv = real_argv; + *argc = real_argc; + + /* we use g_free here as we sucked all the inner strings + * out from it into real_argv */ + g_free (term_argv); + return TRUE; +#else + return FALSE; +#endif /* G_OS_WIN32 */ +} + +static GList * +create_files_for_uris (GList *uris) +{ + GList *res; + GList *iter; + + res = NULL; + + for (iter = uris; iter; iter = iter->next) + { + GFile *file = g_file_new_for_uri ((char *)iter->data); + res = g_list_prepend (res, file); + } + + return g_list_reverse (res); +} + +static void +notify_desktop_launch (GDBusConnection *session_bus, + GDesktopAppInfo *info, + long pid, + const char *display, + const char *sn_id, + GList *uris) +{ + GDBusMessage *msg; + GVariantBuilder uri_variant; + GVariantBuilder extras_variant; + GList *iter; + const char *desktop_file_id; + const char *gio_desktop_file; + + if (session_bus == NULL) + return; + + g_variant_builder_init (&uri_variant, G_VARIANT_TYPE ("as")); + for (iter = uris; iter; iter = iter->next) + g_variant_builder_add (&uri_variant, "s", iter->data); + + g_variant_builder_init (&extras_variant, G_VARIANT_TYPE ("a{sv}")); + if (sn_id != NULL && g_utf8_validate (sn_id, -1, NULL)) + g_variant_builder_add (&extras_variant, "{sv}", + "startup-id", + g_variant_new ("s", + sn_id)); + gio_desktop_file = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE"); + if (gio_desktop_file != NULL) + g_variant_builder_add (&extras_variant, "{sv}", + "origin-desktop-file", + g_variant_new_bytestring (gio_desktop_file)); + if (g_get_prgname () != NULL) + g_variant_builder_add (&extras_variant, "{sv}", + "origin-prgname", + g_variant_new_bytestring (g_get_prgname ())); + g_variant_builder_add (&extras_variant, "{sv}", + "origin-pid", + g_variant_new ("x", + (gint64)getpid ())); + + if (info->filename) + desktop_file_id = info->filename; + else if (info->desktop_id) + desktop_file_id = info->desktop_id; + else + desktop_file_id = ""; + + msg = g_dbus_message_new_signal ("/org/gtk/gio/DesktopAppInfo", + "org.gtk.gio.DesktopAppInfo", + "Launched"); + g_dbus_message_set_body (msg, g_variant_new ("(@aysxasa{sv})", + g_variant_new_bytestring (desktop_file_id), + display ? display : "", + (gint64)pid, + &uri_variant, + &extras_variant)); + g_dbus_connection_send_message (session_bus, + msg, 0, + NULL, + NULL); + g_object_unref (msg); +} + +static void +emit_launch_started (GAppLaunchContext *context, + GDesktopAppInfo *info, + const gchar *startup_id) +{ + GVariantBuilder builder; + GVariant *platform_data = NULL; + + if (startup_id) + { + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (&builder, "{sv}", + "startup-notification-id", + g_variant_new_string (startup_id)); + platform_data = g_variant_ref_sink (g_variant_builder_end (&builder)); + } + g_signal_emit_by_name (context, "launch-started", info, platform_data); + g_clear_pointer (&platform_data, g_variant_unref); +} + +#define _SPAWN_FLAGS_DEFAULT (G_SPAWN_SEARCH_PATH) + +static gboolean +g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info, + GDBusConnection *session_bus, + const gchar *exec_line, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + GError **error) +{ + gboolean completed = FALSE; + GList *old_uris; + GList *dup_uris; + + char **argv, **envp; + int argc; + + g_return_val_if_fail (info != NULL, FALSE); + + argv = NULL; + + if (launch_context) + envp = g_app_launch_context_get_environment (launch_context); + else + envp = g_get_environ (); + + /* The GList* passed to expand_application_parameters() will be modified + * internally by expand_macro(), so we need to pass a copy of it instead, + * and also use that copy to control the exit condition of the loop below. + */ + dup_uris = uris; + do + { + GPid pid; + GList *launched_uris; + GList *iter; + char *sn_id = NULL; + char **wrapped_argv; + int i; + gsize j; + const gchar * const wrapper_argv[] = + { + "/bin/sh", + "-e", + "-u", + "-c", "export GIO_LAUNCHED_DESKTOP_FILE_PID=$$; exec \"$@\"", + "sh", /* argv[0] for sh */ + }; + + old_uris = dup_uris; + if (!expand_application_parameters (info, exec_line, &dup_uris, &argc, &argv, error)) + goto out; + + /* Get the subset of URIs we're launching with this process */ + launched_uris = NULL; + for (iter = old_uris; iter != NULL && iter != dup_uris; iter = iter->next) + launched_uris = g_list_prepend (launched_uris, iter->data); + launched_uris = g_list_reverse (launched_uris); + + if (info->terminal && !prepend_terminal_to_vector (&argc, &argv)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Unable to find terminal required for application")); + goto out; + } + + if (info->filename) + envp = g_environ_setenv (envp, + "GIO_LAUNCHED_DESKTOP_FILE", + info->filename, + TRUE); + + sn_id = NULL; + if (launch_context) + { + GList *launched_files = create_files_for_uris (launched_uris); + + if (info->startup_notify) + { + sn_id = g_app_launch_context_get_startup_notify_id (launch_context, + G_APP_INFO (info), + launched_files); + if (sn_id) + envp = g_environ_setenv (envp, "DESKTOP_STARTUP_ID", sn_id, TRUE); + } + + g_list_free_full (launched_files, g_object_unref); + + emit_launch_started (launch_context, info, sn_id); + } + + /* Wrap the @argv in a command which will set the + * `GIO_LAUNCHED_DESKTOP_FILE_PID` environment variable. We can’t set this + * in @envp along with `GIO_LAUNCHED_DESKTOP_FILE` because we need to know + * the PID of the new forked process. We can’t use setenv() between fork() + * and exec() because we’d rather use posix_spawn() for speed. + * + * `sh` should be available on all the platforms that `GDesktopAppInfo` + * currently supports (since they are all POSIX). If additional platforms + * need to be supported in future, it will probably have to be replaced + * with a wrapper program (grep the GLib git history for + * `gio-launch-desktop` for an example of this which could be + * resurrected). */ + wrapped_argv = g_new (char *, argc + G_N_ELEMENTS (wrapper_argv) + 1); + + for (j = 0; j < G_N_ELEMENTS (wrapper_argv); j++) + wrapped_argv[j] = g_strdup (wrapper_argv[j]); + for (i = 0; i < argc; i++) + wrapped_argv[i + G_N_ELEMENTS (wrapper_argv)] = g_steal_pointer (&argv[i]); + + wrapped_argv[i + G_N_ELEMENTS (wrapper_argv)] = NULL; + g_free (argv); + argv = NULL; + + if (!g_spawn_async_with_fds (info->path, + wrapped_argv, + envp, + spawn_flags, + user_setup, + user_setup_data, + &pid, + stdin_fd, + stdout_fd, + stderr_fd, + error)) + { + if (sn_id) + g_app_launch_context_launch_failed (launch_context, sn_id); + + g_free (sn_id); + g_list_free (launched_uris); + + goto out; + } + + if (pid_callback != NULL) + pid_callback (info, pid, pid_callback_data); + + if (launch_context != NULL) + { + GVariantBuilder builder; + GVariant *platform_data; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (&builder, "{sv}", "pid", g_variant_new_int32 (pid)); + if (sn_id) + g_variant_builder_add (&builder, "{sv}", "startup-notification-id", g_variant_new_string (sn_id)); + platform_data = g_variant_ref_sink (g_variant_builder_end (&builder)); + g_signal_emit_by_name (launch_context, "launched", info, platform_data); + g_variant_unref (platform_data); + } + + notify_desktop_launch (session_bus, + info, + pid, + NULL, + sn_id, + launched_uris); + + g_free (sn_id); + g_list_free (launched_uris); + + g_strfreev (wrapped_argv); + wrapped_argv = NULL; + } + while (dup_uris != NULL); + + completed = TRUE; + + out: + g_strfreev (argv); + g_strfreev (envp); + + return completed; +} + +static gchar * +object_path_from_appid (const gchar *appid) +{ + gchar *appid_path, *iter; + + appid_path = g_strconcat ("/", appid, NULL); + for (iter = appid_path; *iter; iter++) + { + if (*iter == '.') + *iter = '/'; + + if (*iter == '-') + *iter = '_'; + } + + return appid_path; +} + +static GVariant * +g_desktop_app_info_make_platform_data (GDesktopAppInfo *info, + GList *uris, + GAppLaunchContext *launch_context) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + + if (launch_context) + { + GList *launched_files = create_files_for_uris (uris); + + if (info->startup_notify) + { + gchar *sn_id; + + sn_id = g_app_launch_context_get_startup_notify_id (launch_context, G_APP_INFO (info), launched_files); + if (sn_id) + g_variant_builder_add (&builder, "{sv}", "desktop-startup-id", g_variant_new_take_string (sn_id)); + } + + g_list_free_full (launched_files, g_object_unref); + } + + return g_variant_builder_end (&builder); +} + +typedef struct +{ + GDesktopAppInfo *info; /* (owned) */ + GAppLaunchContext *launch_context; /* (owned) (nullable) */ + GAsyncReadyCallback callback; + gchar *startup_id; /* (owned) */ + gpointer user_data; +} LaunchUrisWithDBusData; + +static void +launch_uris_with_dbus_data_free (LaunchUrisWithDBusData *data) +{ + g_clear_object (&data->info); + g_clear_object (&data->launch_context); + g_free (data->startup_id); + + g_free (data); +} + +static void +launch_uris_with_dbus_signal_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + LaunchUrisWithDBusData *data = user_data; + GVariantBuilder builder; + + if (data->launch_context) + { + if (g_task_had_error (G_TASK (result))) + g_app_launch_context_launch_failed (data->launch_context, data->startup_id); + else + { + GVariant *platform_data; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + /* the docs guarantee `pid` will be set, but we can’t + * easily know it for a D-Bus process, so set it to zero */ + g_variant_builder_add (&builder, "{sv}", "pid", g_variant_new_int32 (0)); + if (data->startup_id) + g_variant_builder_add (&builder, "{sv}", + "startup-notification-id", + g_variant_new_string (data->startup_id)); + platform_data = g_variant_ref_sink (g_variant_builder_end (&builder)); + g_signal_emit_by_name (data->launch_context, + "launched", + data->info, + platform_data); + g_variant_unref (platform_data); + } + } + + if (data->callback) + data->callback (object, result, data->user_data); + else if (!g_task_had_error (G_TASK (result))) + g_variant_unref (g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), + result, NULL)); + + launch_uris_with_dbus_data_free (data); +} + +static void +launch_uris_with_dbus (GDesktopAppInfo *info, + GDBusConnection *session_bus, + GList *uris, + GAppLaunchContext *launch_context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVariant *platform_data; + GVariantBuilder builder; + GVariantDict dict; + gchar *object_path; + LaunchUrisWithDBusData *data; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + + if (uris) + { + GList *iter; + + g_variant_builder_open (&builder, G_VARIANT_TYPE_STRING_ARRAY); + for (iter = uris; iter; iter = iter->next) + g_variant_builder_add (&builder, "s", iter->data); + g_variant_builder_close (&builder); + } + + platform_data = g_desktop_app_info_make_platform_data (info, uris, launch_context); + + g_variant_builder_add_value (&builder, platform_data); + object_path = object_path_from_appid (info->app_id); + + data = g_new0 (LaunchUrisWithDBusData, 1); + data->info = g_object_ref (info); + data->callback = callback; + data->user_data = user_data; + data->launch_context = launch_context ? g_object_ref (launch_context) : NULL; + g_variant_dict_init (&dict, platform_data); + g_variant_dict_lookup (&dict, "desktop-startup-id", "s", &data->startup_id); + + if (launch_context) + emit_launch_started (launch_context, info, data->startup_id); + + g_dbus_connection_call (session_bus, info->app_id, object_path, "org.freedesktop.Application", + uris ? "Open" : "Activate", g_variant_builder_end (&builder), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + cancellable, launch_uris_with_dbus_signal_cb, g_steal_pointer (&data)); + g_free (object_path); + + g_variant_dict_clear (&dict); +} + +static gboolean +g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info, + GDBusConnection *session_bus, + GList *uris, + GAppLaunchContext *launch_context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GList *ruris = uris; + char *app_id = NULL; + + g_return_val_if_fail (info != NULL, FALSE); + +#ifdef G_OS_UNIX + app_id = g_desktop_app_info_get_string (info, "X-Flatpak"); + if (app_id && *app_id) + { + ruris = g_document_portal_add_documents (uris, app_id, NULL); + if (ruris == NULL) + ruris = uris; + } +#endif + + launch_uris_with_dbus (info, session_bus, ruris, launch_context, + cancellable, callback, user_data); + + if (ruris != uris) + g_list_free_full (ruris, g_free); + + g_free (app_id); + + return TRUE; +} + +static gboolean +g_desktop_app_info_launch_uris_internal (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + GDBusConnection *session_bus; + gboolean success = TRUE; + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + if (session_bus && info->app_id) + /* This is non-blocking API. Similar to launching via fork()/exec() + * we don't wait around to see if the program crashed during startup. + * This is what startup-notification's job is... + */ + g_desktop_app_info_launch_uris_with_dbus (info, session_bus, uris, launch_context, + NULL, NULL, NULL); + else + success = g_desktop_app_info_launch_uris_with_spawn (info, session_bus, info->exec, uris, launch_context, + spawn_flags, user_setup, user_setup_data, + pid_callback, pid_callback_data, + stdin_fd, stdout_fd, stderr_fd, error); + + if (session_bus != NULL) + { + /* This asynchronous flush holds a reference until it completes, + * which ensures that the following unref won't immediately kill + * the connection if we were the initial owner. + */ + g_dbus_connection_flush (session_bus, NULL, NULL, NULL); + g_object_unref (session_bus); + } + + return success; +} + +static gboolean +g_desktop_app_info_launch_uris (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GError **error) +{ + return g_desktop_app_info_launch_uris_internal (appinfo, uris, + launch_context, + _SPAWN_FLAGS_DEFAULT, + NULL, NULL, NULL, NULL, + -1, -1, -1, + error); +} + +typedef struct +{ + GAppInfo *appinfo; + GList *uris; + GAppLaunchContext *context; +} LaunchUrisData; + +static void +launch_uris_data_free (LaunchUrisData *data) +{ + g_clear_object (&data->context); + g_list_free_full (data->uris, g_free); + g_free (data); +} + +static void +launch_uris_with_dbus_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + GError *error = NULL; + GVariant *ret; + + ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); + if (error != NULL) + { + g_dbus_error_strip_remote_error (error); + g_task_return_error (task, g_steal_pointer (&error)); + } + else + { + g_task_return_boolean (task, TRUE); + g_variant_unref (ret); + } + + g_object_unref (task); +} + +static void +launch_uris_flush_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + + g_dbus_connection_flush_finish (G_DBUS_CONNECTION (object), result, NULL); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +launch_uris_bus_get_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (g_task_get_source_object (task)); + LaunchUrisData *data = g_task_get_task_data (task); + GCancellable *cancellable = g_task_get_cancellable (task); + GDBusConnection *session_bus; + GError *error = NULL; + + session_bus = g_bus_get_finish (result, NULL); + + if (session_bus && info->app_id) + { + /* FIXME: The g_document_portal_add_documents() function, which is called + * from the g_desktop_app_info_launch_uris_with_dbus() function, still + * uses blocking calls. + */ + g_desktop_app_info_launch_uris_with_dbus (info, session_bus, + data->uris, data->context, + cancellable, + launch_uris_with_dbus_cb, + g_steal_pointer (&task)); + } + else + { + /* FIXME: The D-Bus message from the notify_desktop_launch() function + * can be still lost even if flush is called later. See: + * https://gitlab.freedesktop.org/dbus/dbus/issues/72 + */ + g_desktop_app_info_launch_uris_with_spawn (info, session_bus, info->exec, + data->uris, data->context, + _SPAWN_FLAGS_DEFAULT, NULL, + NULL, NULL, NULL, -1, -1, -1, + &error); + if (error != NULL) + { + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + } + else if (session_bus) + g_dbus_connection_flush (session_bus, + cancellable, + launch_uris_flush_cb, + g_steal_pointer (&task)); + else + { + g_task_return_boolean (task, TRUE); + g_clear_object (&task); + } + } + + g_clear_object (&session_bus); +} + +static void +g_desktop_app_info_launch_uris_async (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + LaunchUrisData *data; + + task = g_task_new (appinfo, cancellable, callback, user_data); + g_task_set_source_tag (task, g_desktop_app_info_launch_uris_async); + + data = g_new0 (LaunchUrisData, 1); + data->uris = g_list_copy_deep (uris, (GCopyFunc) g_strdup, NULL); + data->context = (context != NULL) ? g_object_ref (context) : NULL; + g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) launch_uris_data_free); + + g_bus_get (G_BUS_TYPE_SESSION, cancellable, launch_uris_bus_get_cb, task); +} + +static gboolean +g_desktop_app_info_launch_uris_finish (GAppInfo *appinfo, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, appinfo), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static gboolean +g_desktop_app_info_supports_uris (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->exec && + ((strstr (info->exec, "%u") != NULL) || + (strstr (info->exec, "%U") != NULL)); +} + +static gboolean +g_desktop_app_info_supports_files (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->exec && + ((strstr (info->exec, "%f") != NULL) || + (strstr (info->exec, "%F") != NULL)); +} + +static gboolean +g_desktop_app_info_launch (GAppInfo *appinfo, + GList *files, + GAppLaunchContext *launch_context, + GError **error) +{ + GList *uris; + char *uri; + gboolean res; + + uris = NULL; + while (files) + { + uri = g_file_get_uri (files->data); + uris = g_list_prepend (uris, uri); + files = files->next; + } + + uris = g_list_reverse (uris); + + res = g_desktop_app_info_launch_uris (appinfo, uris, launch_context, error); + + g_list_free_full (uris, g_free); + + return res; +} + +/** + * g_desktop_app_info_launch_uris_as_manager_with_fds: + * @appinfo: a #GDesktopAppInfo + * @uris: (element-type utf8): List of URIs + * @launch_context: (nullable): a #GAppLaunchContext + * @spawn_flags: #GSpawnFlags, used for each process + * @user_setup: (scope async) (nullable): a #GSpawnChildSetupFunc, used once + * for each process. + * @user_setup_data: (closure user_setup) (nullable): User data for @user_setup + * @pid_callback: (scope call) (nullable): Callback for child processes + * @pid_callback_data: (closure pid_callback) (nullable): User data for @callback + * @stdin_fd: file descriptor to use for child's stdin, or -1 + * @stdout_fd: file descriptor to use for child's stdout, or -1 + * @stderr_fd: file descriptor to use for child's stderr, or -1 + * @error: return location for a #GError, or %NULL + * + * Equivalent to g_desktop_app_info_launch_uris_as_manager() but allows + * you to pass in file descriptors for the stdin, stdout and stderr streams + * of the launched process. + * + * If application launching occurs via some non-spawn mechanism (e.g. D-Bus + * activation) then @stdin_fd, @stdout_fd and @stderr_fd are ignored. + * + * Returns: %TRUE on successful launch, %FALSE otherwise. + * + * Since: 2.58 + */ +gboolean +g_desktop_app_info_launch_uris_as_manager_with_fds (GDesktopAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + GError **error) +{ + return g_desktop_app_info_launch_uris_internal ((GAppInfo*)appinfo, + uris, + launch_context, + spawn_flags, + user_setup, + user_setup_data, + pid_callback, + pid_callback_data, + stdin_fd, + stdout_fd, + stderr_fd, + error); +} + +/** + * g_desktop_app_info_launch_uris_as_manager: + * @appinfo: a #GDesktopAppInfo + * @uris: (element-type utf8): List of URIs + * @launch_context: (nullable): a #GAppLaunchContext + * @spawn_flags: #GSpawnFlags, used for each process + * @user_setup: (scope async) (nullable): a #GSpawnChildSetupFunc, used once + * for each process. + * @user_setup_data: (closure user_setup) (nullable): User data for @user_setup + * @pid_callback: (scope call) (nullable): Callback for child processes + * @pid_callback_data: (closure pid_callback) (nullable): User data for @callback + * @error: return location for a #GError, or %NULL + * + * This function performs the equivalent of g_app_info_launch_uris(), + * but is intended primarily for operating system components that + * launch applications. Ordinary applications should use + * g_app_info_launch_uris(). + * + * If the application is launched via GSpawn, then @spawn_flags, @user_setup + * and @user_setup_data are used for the call to g_spawn_async(). + * Additionally, @pid_callback (with @pid_callback_data) will be called to + * inform about the PID of the created process. See g_spawn_async_with_pipes() + * for information on certain parameter conditions that can enable an + * optimized posix_spawn() codepath to be used. + * + * If application launching occurs via some other mechanism (eg: D-Bus + * activation) then @spawn_flags, @user_setup, @user_setup_data, + * @pid_callback and @pid_callback_data are ignored. + * + * Returns: %TRUE on successful launch, %FALSE otherwise. + */ +gboolean +g_desktop_app_info_launch_uris_as_manager (GDesktopAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + GError **error) +{ + return g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo, + uris, + launch_context, + spawn_flags, + user_setup, + user_setup_data, + pid_callback, + pid_callback_data, + -1, -1, -1, + error); +} + +/* OnlyShowIn API support {{{2 */ + +/** + * g_desktop_app_info_set_desktop_env: + * @desktop_env: a string specifying what desktop this is + * + * Sets the name of the desktop that the application is running in. + * This is used by g_app_info_should_show() and + * g_desktop_app_info_get_show_in() to evaluate the + * `OnlyShowIn` and `NotShowIn` + * desktop entry fields. + * + * Should be called only once; subsequent calls are ignored. + * + * Deprecated:2.42:do not use this API. Since 2.42 the value of the + * `XDG_CURRENT_DESKTOP` environment variable will be used. + */ +void +g_desktop_app_info_set_desktop_env (const gchar *desktop_env) +{ + get_current_desktops (desktop_env); +} + +static gboolean +g_desktop_app_info_should_show (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->nodisplay) + return FALSE; + + return g_desktop_app_info_get_show_in (info, NULL); +} + +/* mime types/default apps support {{{2 */ + +typedef enum { + CONF_DIR, + APP_DIR, + MIMETYPE_DIR +} DirType; + +static char * +ensure_dir (DirType type, + GError **error) +{ + char *path, *display_name; + int errsv; + + switch (type) + { + case CONF_DIR: + path = g_build_filename (g_get_user_config_dir (), NULL); + break; + + case APP_DIR: + path = g_build_filename (g_get_user_data_dir (), "applications", NULL); + break; + + case MIMETYPE_DIR: + path = g_build_filename (g_get_user_data_dir (), "mime", "packages", NULL); + break; + + default: + g_assert_not_reached (); + } + + g_debug ("%s: Ensuring %s", G_STRFUNC, path); + + errno = 0; + if (g_mkdir_with_parents (path, 0700) == 0) + return path; + + errsv = errno; + display_name = g_filename_display_name (path); + if (type == APP_DIR) + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Can’t create user application configuration folder %s: %s"), + display_name, g_strerror (errsv)); + else + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Can’t create user MIME configuration folder %s: %s"), + display_name, g_strerror (errsv)); + + g_free (display_name); + g_free (path); + + return NULL; +} + +static gboolean +update_mimeapps_list (const char *desktop_id, + const char *content_type, + UpdateMimeFlags flags, + GError **error) +{ + char *dirname, *filename, *string; + GKeyFile *key_file; + gboolean load_succeeded, res; + char **old_list, **list; + gsize length, data_size; + char *data; + int i, j, k; + char **content_types; + + /* Don't add both at start and end */ + g_assert (!((flags & UPDATE_MIME_SET_DEFAULT) && + (flags & UPDATE_MIME_SET_NON_DEFAULT))); + + dirname = ensure_dir (CONF_DIR, error); + if (!dirname) + return FALSE; + + filename = g_build_filename (dirname, "mimeapps.list", NULL); + g_free (dirname); + + key_file = g_key_file_new (); + load_succeeded = g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL); + if (!load_succeeded || + (!g_key_file_has_group (key_file, ADDED_ASSOCIATIONS_GROUP) && + !g_key_file_has_group (key_file, REMOVED_ASSOCIATIONS_GROUP) && + !g_key_file_has_group (key_file, DEFAULT_APPLICATIONS_GROUP))) + { + g_key_file_free (key_file); + key_file = g_key_file_new (); + } + + if (content_type) + { + content_types = g_new (char *, 2); + content_types[0] = g_strdup (content_type); + content_types[1] = NULL; + } + else + { + content_types = g_key_file_get_keys (key_file, DEFAULT_APPLICATIONS_GROUP, NULL, NULL); + } + + for (k = 0; content_types && content_types[k]; k++) + { + /* set as default, if requested so */ + string = g_key_file_get_string (key_file, + DEFAULT_APPLICATIONS_GROUP, + content_types[k], + NULL); + + if (g_strcmp0 (string, desktop_id) != 0 && + (flags & UPDATE_MIME_SET_DEFAULT)) + { + g_free (string); + string = g_strdup (desktop_id); + + /* add in the non-default list too, if it's not already there */ + flags |= UPDATE_MIME_SET_NON_DEFAULT; + } + + if (string == NULL || desktop_id == NULL) + g_key_file_remove_key (key_file, + DEFAULT_APPLICATIONS_GROUP, + content_types[k], + NULL); + else + g_key_file_set_string (key_file, + DEFAULT_APPLICATIONS_GROUP, + content_types[k], + string); + + g_free (string); + } + + if (content_type) + { + /* reuse the list from above */ + } + else + { + g_strfreev (content_types); + content_types = g_key_file_get_keys (key_file, ADDED_ASSOCIATIONS_GROUP, NULL, NULL); + } + + for (k = 0; content_types && content_types[k]; k++) + { + /* Add to the right place in the list */ + + length = 0; + old_list = g_key_file_get_string_list (key_file, ADDED_ASSOCIATIONS_GROUP, + content_types[k], &length, NULL); + + list = g_new (char *, 1 + length + 1); + + i = 0; + + /* if we're adding a last-used hint, just put the application in front of the list */ + if (flags & UPDATE_MIME_SET_LAST_USED) + { + /* avoid adding this again as non-default later */ + if (flags & UPDATE_MIME_SET_NON_DEFAULT) + flags ^= UPDATE_MIME_SET_NON_DEFAULT; + + list[i++] = g_strdup (desktop_id); + } + + if (old_list) + { + for (j = 0; old_list[j] != NULL; j++) + { + if (g_strcmp0 (old_list[j], desktop_id) != 0) + { + /* rewrite other entries if they're different from the new one */ + list[i++] = g_strdup (old_list[j]); + } + else if (flags & UPDATE_MIME_SET_NON_DEFAULT) + { + /* we encountered an old entry which is equal to the one we're adding as non-default, + * don't change its position in the list. + */ + flags ^= UPDATE_MIME_SET_NON_DEFAULT; + list[i++] = g_strdup (old_list[j]); + } + } + } + + /* add it at the end of the list */ + if (flags & UPDATE_MIME_SET_NON_DEFAULT) + list[i++] = g_strdup (desktop_id); + + list[i] = NULL; + + g_strfreev (old_list); + + if (list[0] == NULL || desktop_id == NULL) + g_key_file_remove_key (key_file, + ADDED_ASSOCIATIONS_GROUP, + content_types[k], + NULL); + else + g_key_file_set_string_list (key_file, + ADDED_ASSOCIATIONS_GROUP, + content_types[k], + (const char * const *)list, i); + + g_strfreev (list); + } + + if (content_type) + { + /* reuse the list from above */ + } + else + { + g_strfreev (content_types); + content_types = g_key_file_get_keys (key_file, REMOVED_ASSOCIATIONS_GROUP, NULL, NULL); + } + + for (k = 0; content_types && content_types[k]; k++) + { + /* Remove from removed associations group (unless remove) */ + + length = 0; + old_list = g_key_file_get_string_list (key_file, REMOVED_ASSOCIATIONS_GROUP, + content_types[k], &length, NULL); + + list = g_new (char *, 1 + length + 1); + + i = 0; + if (flags & UPDATE_MIME_REMOVE) + list[i++] = g_strdup (desktop_id); + if (old_list) + { + for (j = 0; old_list[j] != NULL; j++) + { + if (g_strcmp0 (old_list[j], desktop_id) != 0) + list[i++] = g_strdup (old_list[j]); + } + } + list[i] = NULL; + + g_strfreev (old_list); + + if (list[0] == NULL || desktop_id == NULL) + g_key_file_remove_key (key_file, + REMOVED_ASSOCIATIONS_GROUP, + content_types[k], + NULL); + else + g_key_file_set_string_list (key_file, + REMOVED_ASSOCIATIONS_GROUP, + content_types[k], + (const char * const *)list, i); + + g_strfreev (list); + } + + g_strfreev (content_types); + + data = g_key_file_to_data (key_file, &data_size, error); + g_key_file_free (key_file); + + res = g_file_set_contents_full (filename, data, data_size, + G_FILE_SET_CONTENTS_CONSISTENT | G_FILE_SET_CONTENTS_ONLY_EXISTING, + 0600, error); + + desktop_file_dirs_invalidate_user_config (); + + g_free (filename); + g_free (data); + + return res; +} + +static gboolean +g_desktop_app_info_set_as_last_used_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (!g_desktop_app_info_ensure_saved (info, error)) + return FALSE; + + if (!info->desktop_id) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Application information lacks an identifier")); + return FALSE; + } + + /* both add support for the content type and set as last used */ + return update_mimeapps_list (info->desktop_id, content_type, + UPDATE_MIME_SET_NON_DEFAULT | + UPDATE_MIME_SET_LAST_USED, + error); +} + +static gboolean +g_desktop_app_info_set_as_default_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (!g_desktop_app_info_ensure_saved (info, error)) + return FALSE; + + if (!info->desktop_id) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Application information lacks an identifier")); + return FALSE; + } + + return update_mimeapps_list (info->desktop_id, content_type, + UPDATE_MIME_SET_DEFAULT, + error); +} + +static void +update_program_done (GPid pid, + gint status, + gpointer data) +{ + /* Did the application exit correctly */ + if (g_spawn_check_wait_status (status, NULL)) + { + /* Here we could clean out any caches in use */ + } +} + +static void +run_update_command (char *command, + char *subdir) +{ + char *argv[3] = { + NULL, + NULL, + NULL, + }; + GPid pid = 0; + GError *error = NULL; + + argv[0] = command; + argv[1] = g_build_filename (g_get_user_data_dir (), subdir, NULL); + + if (g_spawn_async ("/", argv, + NULL, /* envp */ + G_SPAWN_SEARCH_PATH | + G_SPAWN_STDOUT_TO_DEV_NULL | + G_SPAWN_STDERR_TO_DEV_NULL | + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, /* No setup function */ + &pid, + &error)) + g_child_watch_add (pid, update_program_done, NULL); + else + { + /* If we get an error at this point, it's quite likely the user doesn't + * have an installed copy of either 'update-mime-database' or + * 'update-desktop-database'. I don't think we want to popup an error + * dialog at this point, so we just do a g_warning to give the user a + * chance of debugging it. + */ + g_warning ("%s", error->message); + g_error_free (error); + } + + g_free (argv[1]); +} + +static gboolean +g_desktop_app_info_set_as_default_for_extension (GAppInfo *appinfo, + const char *extension, + GError **error) +{ + char *filename, *basename, *mimetype; + char *dirname; + gboolean res; + + if (!g_desktop_app_info_ensure_saved (G_DESKTOP_APP_INFO (appinfo), error)) + return FALSE; + + dirname = ensure_dir (MIMETYPE_DIR, error); + if (!dirname) + return FALSE; + + basename = g_strdup_printf ("user-extension-%s.xml", extension); + filename = g_build_filename (dirname, basename, NULL); + g_free (basename); + g_free (dirname); + + mimetype = g_strdup_printf ("application/x-extension-%s", extension); + + if (!g_file_test (filename, G_FILE_TEST_EXISTS)) + { + char *contents; + + contents = + g_strdup_printf ("\n" + "\n" + " \n" + " %s document\n" + " \n" + " \n" + "\n", mimetype, extension, extension); + + g_file_set_contents_full (filename, contents, -1, + G_FILE_SET_CONTENTS_CONSISTENT | G_FILE_SET_CONTENTS_ONLY_EXISTING, + 0600, NULL); + g_free (contents); + + run_update_command ("update-mime-database", "mime"); + } + g_free (filename); + + res = g_desktop_app_info_set_as_default_for_type (appinfo, + mimetype, + error); + + g_free (mimetype); + + return res; +} + +static gboolean +g_desktop_app_info_add_supports_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (!g_desktop_app_info_ensure_saved (G_DESKTOP_APP_INFO (info), error)) + return FALSE; + + return update_mimeapps_list (info->desktop_id, content_type, + UPDATE_MIME_SET_NON_DEFAULT, + error); +} + +static gboolean +g_desktop_app_info_can_remove_supports_type (GAppInfo *appinfo) +{ + return TRUE; +} + +static gboolean +g_desktop_app_info_remove_supports_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (!g_desktop_app_info_ensure_saved (G_DESKTOP_APP_INFO (info), error)) + return FALSE; + + return update_mimeapps_list (info->desktop_id, content_type, + UPDATE_MIME_REMOVE, + error); +} + +static const char ** +g_desktop_app_info_get_supported_types (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return (const char**) info->mime_types; +} + +/* Saving and deleting {{{2 */ + +static gboolean +g_desktop_app_info_ensure_saved (GDesktopAppInfo *info, + GError **error) +{ + GKeyFile *key_file; + char *dirname; + char *filename; + char *data, *desktop_id; + gsize data_size; + int fd; + gboolean res; + + if (info->filename != NULL) + return TRUE; + + /* This is only used for object created with + * g_app_info_create_from_commandline. All other + * object should have a filename + */ + + dirname = ensure_dir (APP_DIR, error); + if (!dirname) + return FALSE; + + key_file = g_key_file_new (); + + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + "Encoding", "UTF-8"); + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_VERSION, "1.0"); + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TYPE, + G_KEY_FILE_DESKTOP_TYPE_APPLICATION); + if (info->terminal) + g_key_file_set_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TERMINAL, TRUE); + if (info->nodisplay) + g_key_file_set_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, TRUE); + + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, info->exec); + + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NAME, info->name); + + if (info->generic_name != NULL) + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + GENERIC_NAME_KEY, info->generic_name); + + if (info->fullname != NULL) + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + FULL_NAME_KEY, info->fullname); + + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_COMMENT, info->comment); + + g_key_file_set_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, TRUE); + + data = g_key_file_to_data (key_file, &data_size, NULL); + g_key_file_free (key_file); + + desktop_id = g_strdup_printf ("userapp-%s-XXXXXX.desktop", info->name); + filename = g_build_filename (dirname, desktop_id, NULL); + g_free (desktop_id); + g_free (dirname); + + fd = g_mkstemp (filename); + if (fd == -1) + { + char *display_name; + + display_name = g_filename_display_name (filename); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Can’t create user desktop file %s"), display_name); + g_free (display_name); + g_free (filename); + g_free (data); + return FALSE; + } + + desktop_id = g_path_get_basename (filename); + + /* FIXME - actually handle error */ + (void) g_close (fd, NULL); + + res = g_file_set_contents_full (filename, data, data_size, + G_FILE_SET_CONTENTS_CONSISTENT | G_FILE_SET_CONTENTS_ONLY_EXISTING, + 0600, error); + g_free (data); + if (!res) + { + g_free (desktop_id); + g_free (filename); + return FALSE; + } + + info->filename = filename; + info->desktop_id = desktop_id; + + run_update_command ("update-desktop-database", "applications"); + + /* We just dropped a file in the user's desktop file directory. Save + * the monitor the bother of having to notice it and invalidate + * immediately. + * + * This means that calls directly following this will be able to see + * the results immediately. + */ + desktop_file_dirs_invalidate_user_data (); + + return TRUE; +} + +static gboolean +g_desktop_app_info_can_delete (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->filename) + { + if (strstr (info->filename, "/userapp-")) + return g_access (info->filename, W_OK) == 0; + } + + return FALSE; +} + +static gboolean +g_desktop_app_info_delete (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->filename) + { + if (g_remove (info->filename) == 0) + { + update_mimeapps_list (info->desktop_id, NULL, + UPDATE_MIME_NONE, + NULL); + + g_free (info->filename); + info->filename = NULL; + g_free (info->desktop_id); + info->desktop_id = NULL; + + return TRUE; + } + } + + return FALSE; +} + +/* Create for commandline {{{2 */ +/** + * g_app_info_create_from_commandline: + * @commandline: (type filename): the commandline to use + * @application_name: (nullable): the application name, or %NULL to use @commandline + * @flags: flags that can specify details of the created #GAppInfo + * @error: a #GError location to store the error occurring, %NULL to ignore. + * + * Creates a new #GAppInfo from the given information. + * + * Note that for @commandline, the quoting rules of the Exec key of the + * [freedesktop.org Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec) + * are applied. For example, if the @commandline contains + * percent-encoded URIs, the percent-character must be doubled in order to prevent it from + * being swallowed by Exec key unquoting. See the specification for exact quoting rules. + * + * Returns: (transfer full): new #GAppInfo for given command. + **/ +GAppInfo * +g_app_info_create_from_commandline (const char *commandline, + const char *application_name, + GAppInfoCreateFlags flags, + GError **error) +{ + char **split; + char *basename; + GDesktopAppInfo *info; + + g_return_val_if_fail (commandline, NULL); + + info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL); + + info->filename = NULL; + info->desktop_id = NULL; + + info->terminal = (flags & G_APP_INFO_CREATE_NEEDS_TERMINAL) != 0; + info->startup_notify = (flags & G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION) != 0; + info->hidden = FALSE; + if ((flags & G_APP_INFO_CREATE_SUPPORTS_URIS) != 0) + info->exec = g_strconcat (commandline, " %u", NULL); + else + info->exec = g_strconcat (commandline, " %f", NULL); + info->nodisplay = TRUE; + info->binary = binary_from_exec (info->exec); + + if (application_name) + info->name = g_strdup (application_name); + else + { + /* FIXME: this should be more robust. Maybe g_shell_parse_argv and use argv[0] */ + split = g_strsplit (commandline, " ", 2); + basename = split[0] ? g_path_get_basename (split[0]) : NULL; + g_strfreev (split); + info->name = basename; + if (info->name == NULL) + info->name = g_strdup ("custom"); + } + info->comment = g_strdup_printf (_("Custom definition for %s"), info->name); + + return G_APP_INFO (info); +} + +/* GAppInfo interface init */ + +static void +g_desktop_app_info_iface_init (GAppInfoIface *iface) +{ + iface->dup = g_desktop_app_info_dup; + iface->equal = g_desktop_app_info_equal; + iface->get_id = g_desktop_app_info_get_id; + iface->get_name = g_desktop_app_info_get_name; + iface->get_description = g_desktop_app_info_get_description; + iface->get_executable = g_desktop_app_info_get_executable; + iface->get_icon = g_desktop_app_info_get_icon; + iface->launch = g_desktop_app_info_launch; + iface->supports_uris = g_desktop_app_info_supports_uris; + iface->supports_files = g_desktop_app_info_supports_files; + iface->launch_uris = g_desktop_app_info_launch_uris; + iface->launch_uris_async = g_desktop_app_info_launch_uris_async; + iface->launch_uris_finish = g_desktop_app_info_launch_uris_finish; + iface->should_show = g_desktop_app_info_should_show; + iface->set_as_default_for_type = g_desktop_app_info_set_as_default_for_type; + iface->set_as_default_for_extension = g_desktop_app_info_set_as_default_for_extension; + iface->add_supports_type = g_desktop_app_info_add_supports_type; + iface->can_remove_supports_type = g_desktop_app_info_can_remove_supports_type; + iface->remove_supports_type = g_desktop_app_info_remove_supports_type; + iface->can_delete = g_desktop_app_info_can_delete; + iface->do_delete = g_desktop_app_info_delete; + iface->get_commandline = g_desktop_app_info_get_commandline; + iface->get_display_name = g_desktop_app_info_get_display_name; + iface->set_as_last_used_for_type = g_desktop_app_info_set_as_last_used_for_type; + iface->get_supported_types = g_desktop_app_info_get_supported_types; +} + +/* Recommended applications {{{2 */ + +/* Converts content_type into a list of itself with all of its parent + * types (if include_fallback is enabled) or just returns a single-item + * list with the unaliased content type. + */ +static gchar ** +get_list_of_mimetypes (const gchar *content_type, + gboolean include_fallback) +{ + gchar *unaliased; + GPtrArray *array; + + array = g_ptr_array_new (); + unaliased = _g_unix_content_type_unalias (content_type); + g_ptr_array_add (array, unaliased); + + if (include_fallback) + { + guint i; + + /* Iterate the array as we grow it, until we have nothing more to add */ + for (i = 0; i < array->len; i++) + { + gchar **parents = _g_unix_content_type_get_parents (g_ptr_array_index (array, i)); + gint j; + + for (j = 0; parents[j]; j++) + /* Don't add duplicates */ + if (!array_contains (array, parents[j])) + g_ptr_array_add (array, parents[j]); + else + g_free (parents[j]); + + /* We already stole or freed each element. Free the container. */ + g_free (parents); + } + } + + g_ptr_array_add (array, NULL); + + return (gchar **) g_ptr_array_free (array, FALSE); +} + +static gchar ** +g_desktop_app_info_get_desktop_ids_for_content_type (const gchar *content_type, + gboolean include_fallback) +{ + GPtrArray *hits, *blocklist; + gchar **types; + guint i, j; + + hits = g_ptr_array_new (); + blocklist = g_ptr_array_new (); + + types = get_list_of_mimetypes (content_type, include_fallback); + + desktop_file_dirs_lock (); + + for (i = 0; types[i]; i++) + for (j = 0; j < desktop_file_dirs->len; j++) + desktop_file_dir_mime_lookup (g_ptr_array_index (desktop_file_dirs, j), types[i], hits, blocklist); + + /* We will keep the hits past unlocking, so we must dup them */ + for (i = 0; i < hits->len; i++) + hits->pdata[i] = g_strdup (hits->pdata[i]); + + desktop_file_dirs_unlock (); + + g_ptr_array_add (hits, NULL); + + g_ptr_array_free (blocklist, TRUE); + g_strfreev (types); + + return (gchar **) g_ptr_array_free (hits, FALSE); +} + +/** + * g_app_info_get_recommended_for_type: + * @content_type: the content type to find a #GAppInfo for + * + * Gets a list of recommended #GAppInfos for a given content type, i.e. + * those applications which claim to support the given content type exactly, + * and not by MIME type subclassing. + * Note that the first application of the list is the last used one, i.e. + * the last one for which g_app_info_set_as_last_used_for_type() has been + * called. + * + * Returns: (element-type GAppInfo) (transfer full): #GList of #GAppInfos + * for given @content_type or %NULL on error. + * + * Since: 2.28 + **/ +GList * +g_app_info_get_recommended_for_type (const gchar *content_type) +{ + gchar **desktop_ids; + GList *infos; + gint i; + + g_return_val_if_fail (content_type != NULL, NULL); + + desktop_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, FALSE); + + infos = NULL; + for (i = 0; desktop_ids[i]; i++) + { + GDesktopAppInfo *info; + + info = g_desktop_app_info_new (desktop_ids[i]); + if (info) + infos = g_list_prepend (infos, info); + } + + g_strfreev (desktop_ids); + + return g_list_reverse (infos); +} + +/** + * g_app_info_get_fallback_for_type: + * @content_type: the content type to find a #GAppInfo for + * + * Gets a list of fallback #GAppInfos for a given content type, i.e. + * those applications which claim to support the given content type + * by MIME type subclassing and not directly. + * + * Returns: (element-type GAppInfo) (transfer full): #GList of #GAppInfos + * for given @content_type or %NULL on error. + * + * Since: 2.28 + **/ +GList * +g_app_info_get_fallback_for_type (const gchar *content_type) +{ + gchar **recommended_ids; + gchar **all_ids; + GList *infos; + gint i; + + g_return_val_if_fail (content_type != NULL, NULL); + + recommended_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, FALSE); + all_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, TRUE); + + infos = NULL; + for (i = 0; all_ids[i]; i++) + { + GDesktopAppInfo *info; + gint j; + + /* Don't return the ones on the recommended list */ + for (j = 0; recommended_ids[j]; j++) + if (g_str_equal (all_ids[i], recommended_ids[j])) + break; + + if (recommended_ids[j]) + continue; + + info = g_desktop_app_info_new (all_ids[i]); + + if (info) + infos = g_list_prepend (infos, info); + } + + g_strfreev (recommended_ids); + g_strfreev (all_ids); + + return g_list_reverse (infos); +} + +/** + * g_app_info_get_all_for_type: + * @content_type: the content type to find a #GAppInfo for + * + * Gets a list of all #GAppInfos for a given content type, + * including the recommended and fallback #GAppInfos. See + * g_app_info_get_recommended_for_type() and + * g_app_info_get_fallback_for_type(). + * + * Returns: (element-type GAppInfo) (transfer full): #GList of #GAppInfos + * for given @content_type or %NULL on error. + **/ +GList * +g_app_info_get_all_for_type (const char *content_type) +{ + gchar **desktop_ids; + GList *infos; + gint i; + + g_return_val_if_fail (content_type != NULL, NULL); + + desktop_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, TRUE); + + infos = NULL; + for (i = 0; desktop_ids[i]; i++) + { + GDesktopAppInfo *info; + + info = g_desktop_app_info_new (desktop_ids[i]); + if (info) + infos = g_list_prepend (infos, info); + } + + g_strfreev (desktop_ids); + + return g_list_reverse (infos); +} + +/** + * g_app_info_reset_type_associations: + * @content_type: a content type + * + * Removes all changes to the type associations done by + * g_app_info_set_as_default_for_type(), + * g_app_info_set_as_default_for_extension(), + * g_app_info_add_supports_type() or + * g_app_info_remove_supports_type(). + * + * Since: 2.20 + */ +void +g_app_info_reset_type_associations (const char *content_type) +{ + update_mimeapps_list (NULL, content_type, + UPDATE_MIME_NONE, + NULL); +} + +/** + * g_app_info_get_default_for_type: + * @content_type: the content type to find a #GAppInfo for + * @must_support_uris: if %TRUE, the #GAppInfo is expected to + * support URIs + * + * Gets the default #GAppInfo for a given content type. + * + * Returns: (transfer full) (nullable): #GAppInfo for given @content_type or + * %NULL on error. + */ +GAppInfo * +g_app_info_get_default_for_type (const char *content_type, + gboolean must_support_uris) +{ + GPtrArray *blocklist; + GPtrArray *results; + GAppInfo *info; + gchar **types; + guint i, j, k; + + g_return_val_if_fail (content_type != NULL, NULL); + + types = get_list_of_mimetypes (content_type, TRUE); + + blocklist = g_ptr_array_new (); + results = g_ptr_array_new (); + info = NULL; + + desktop_file_dirs_lock (); + + for (i = 0; types[i]; i++) + { + /* Collect all the default apps for this type */ + for (j = 0; j < desktop_file_dirs->len; j++) + desktop_file_dir_default_lookup (g_ptr_array_index (desktop_file_dirs, j), types[i], results); + + /* Consider the associations as well... */ + for (j = 0; j < desktop_file_dirs->len; j++) + desktop_file_dir_mime_lookup (g_ptr_array_index (desktop_file_dirs, j), types[i], results, blocklist); + + /* (If any), see if one of those apps is installed... */ + for (j = 0; j < results->len; j++) + { + const gchar *desktop_id = g_ptr_array_index (results, j); + + for (k = 0; k < desktop_file_dirs->len; k++) + { + info = (GAppInfo *) desktop_file_dir_get_app (g_ptr_array_index (desktop_file_dirs, k), desktop_id); + + if (info) + { + if (!must_support_uris || g_app_info_supports_uris (info)) + goto out; + + g_clear_object (&info); + } + } + } + + /* Reset the list, ready to try again with the next (parent) + * mimetype, but keep the blocklist in place. + */ + g_ptr_array_set_size (results, 0); + } + +out: + desktop_file_dirs_unlock (); + + g_ptr_array_unref (blocklist); + g_ptr_array_unref (results); + g_strfreev (types); + + return info; +} + +/** + * g_app_info_get_default_for_uri_scheme: + * @uri_scheme: a string containing a URI scheme. + * + * Gets the default application for handling URIs with + * the given URI scheme. A URI scheme is the initial part + * of the URI, up to but not including the ':', e.g. "http", + * "ftp" or "sip". + * + * Returns: (transfer full) (nullable): #GAppInfo for given @uri_scheme or + * %NULL on error. + */ +GAppInfo * +g_app_info_get_default_for_uri_scheme (const char *uri_scheme) +{ + GAppInfo *app_info; + char *content_type, *scheme_down; + + scheme_down = g_ascii_strdown (uri_scheme, -1); + content_type = g_strdup_printf ("x-scheme-handler/%s", scheme_down); + g_free (scheme_down); + app_info = g_app_info_get_default_for_type (content_type, FALSE); + g_free (content_type); + + return app_info; +} + +/* "Get all" API {{{2 */ + +/** + * g_desktop_app_info_get_implementations: + * @interface: the name of the interface + * + * Gets all applications that implement @interface. + * + * An application implements an interface if that interface is listed in + * the Implements= line of the desktop file of the application. + * + * Returns: (element-type GDesktopAppInfo) (transfer full): a list of #GDesktopAppInfo + * objects. + * + * Since: 2.42 + **/ +GList * +g_desktop_app_info_get_implementations (const gchar *interface) +{ + GList *result = NULL; + GList **ptr; + guint i; + + desktop_file_dirs_lock (); + + for (i = 0; i < desktop_file_dirs->len; i++) + desktop_file_dir_get_implementations (g_ptr_array_index (desktop_file_dirs, i), &result, interface); + + desktop_file_dirs_unlock (); + + ptr = &result; + while (*ptr) + { + gchar *name = (*ptr)->data; + GDesktopAppInfo *app; + + app = g_desktop_app_info_new (name); + g_free (name); + + if (app) + { + (*ptr)->data = app; + ptr = &(*ptr)->next; + } + else + *ptr = g_list_delete_link (*ptr, *ptr); + } + + return result; +} + +/** + * g_desktop_app_info_search: + * @search_string: the search string to use + * + * Searches desktop files for ones that match @search_string. + * + * The return value is an array of strvs. Each strv contains a list of + * applications that matched @search_string with an equal score. The + * outer list is sorted by score so that the first strv contains the + * best-matching applications, and so on. + * The algorithm for determining matches is undefined and may change at + * any time. + * + * None of the search results are subjected to the normal validation + * checks performed by g_desktop_app_info_new() (for example, checking that + * the executable referenced by a result exists), and so it is possible for + * g_desktop_app_info_new() to return %NULL when passed an app ID returned by + * this function. It is expected that calling code will do this when + * subsequently creating a #GDesktopAppInfo for each result. + * + * Returns: (array zero-terminated=1) (element-type GStrv) (transfer full): a + * list of strvs. Free each item with g_strfreev() and free the outer + * list with g_free(). + */ +gchar *** +g_desktop_app_info_search (const gchar *search_string) +{ + gchar **search_tokens; + gint last_category = -1; + gchar ***results; + gint n_categories = 0; + gint start_of_category; + gint i, j; + guint k; + + search_tokens = g_str_tokenize_and_fold (search_string, NULL, NULL); + + desktop_file_dirs_lock (); + + reset_total_search_results (); + + for (k = 0; k < desktop_file_dirs->len; k++) + { + for (j = 0; search_tokens[j]; j++) + { + desktop_file_dir_search (g_ptr_array_index (desktop_file_dirs, k), search_tokens[j]); + merge_token_results (j == 0); + } + merge_directory_results (); + } + + sort_total_search_results (); + + /* Count the total number of unique categories */ + for (i = 0; i < static_total_results_size; i++) + if (static_total_results[i].category != last_category) + { + last_category = static_total_results[i].category; + n_categories++; + } + + results = g_new (gchar **, n_categories + 1); + + /* Start loading into the results list */ + start_of_category = 0; + for (i = 0; i < n_categories; i++) + { + gint n_items_in_category = 0; + gint this_category; + gint j; + + this_category = static_total_results[start_of_category].category; + + while (start_of_category + n_items_in_category < static_total_results_size && + static_total_results[start_of_category + n_items_in_category].category == this_category) + n_items_in_category++; + + results[i] = g_new (gchar *, n_items_in_category + 1); + for (j = 0; j < n_items_in_category; j++) + results[i][j] = g_strdup (static_total_results[start_of_category + j].app_name); + results[i][j] = NULL; + + start_of_category += n_items_in_category; + } + results[i] = NULL; + + desktop_file_dirs_unlock (); + + g_strfreev (search_tokens); + + return results; +} + +/** + * g_app_info_get_all: + * + * Gets a list of all of the applications currently registered + * on this system. + * + * For desktop files, this includes applications that have + * `NoDisplay=true` set or are excluded from display by means + * of `OnlyShowIn` or `NotShowIn`. See g_app_info_should_show(). + * The returned list does not include applications which have + * the `Hidden` key set. + * + * Returns: (element-type GAppInfo) (transfer full): a newly allocated #GList of references to #GAppInfos. + **/ +GList * +g_app_info_get_all (void) +{ + GHashTable *apps; + GHashTableIter iter; + gpointer value; + guint i; + GList *infos; + + apps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + desktop_file_dirs_lock (); + + for (i = 0; i < desktop_file_dirs->len; i++) + desktop_file_dir_get_all (g_ptr_array_index (desktop_file_dirs, i), apps); + + desktop_file_dirs_unlock (); + + infos = NULL; + g_hash_table_iter_init (&iter, apps); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + if (value) + infos = g_list_prepend (infos, value); + } + + g_hash_table_destroy (apps); + + return infos; +} + +/* GDesktopAppInfoLookup interface {{{2 */ + +/** + * GDesktopAppInfoLookup: + * + * #GDesktopAppInfoLookup is an opaque data structure and can only be accessed + * using the following functions. + * + * Deprecated: 2.28: The #GDesktopAppInfoLookup interface is deprecated and + * unused by GIO. + **/ + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +typedef GDesktopAppInfoLookupIface GDesktopAppInfoLookupInterface; +G_DEFINE_INTERFACE (GDesktopAppInfoLookup, g_desktop_app_info_lookup, G_TYPE_OBJECT) + +static void +g_desktop_app_info_lookup_default_init (GDesktopAppInfoLookupInterface *iface) +{ +} + +/* "Get for mime type" APIs {{{2 */ + +/** + * g_desktop_app_info_lookup_get_default_for_uri_scheme: + * @lookup: a #GDesktopAppInfoLookup + * @uri_scheme: a string containing a URI scheme. + * + * Gets the default application for launching applications + * using this URI scheme for a particular #GDesktopAppInfoLookup + * implementation. + * + * The #GDesktopAppInfoLookup interface and this function is used + * to implement g_app_info_get_default_for_uri_scheme() backends + * in a GIO module. There is no reason for applications to use it + * directly. Applications should use g_app_info_get_default_for_uri_scheme(). + * + * Returns: (transfer full) (nullable): #GAppInfo for given @uri_scheme or + * %NULL on error. + * + * Deprecated: 2.28: The #GDesktopAppInfoLookup interface is deprecated and + * unused by GIO. + */ +GAppInfo * +g_desktop_app_info_lookup_get_default_for_uri_scheme (GDesktopAppInfoLookup *lookup, + const char *uri_scheme) +{ + GDesktopAppInfoLookupIface *iface; + + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO_LOOKUP (lookup), NULL); + + iface = G_DESKTOP_APP_INFO_LOOKUP_GET_IFACE (lookup); + + return (* iface->get_default_for_uri_scheme) (lookup, uri_scheme); +} + +G_GNUC_END_IGNORE_DEPRECATIONS + +/* Misc getter APIs {{{2 */ + +/** + * g_desktop_app_info_get_startup_wm_class: + * @info: a #GDesktopAppInfo that supports startup notify + * + * Retrieves the StartupWMClass field from @info. This represents the + * WM_CLASS property of the main window of the application, if launched + * through @info. + * + * Returns: (nullable) (transfer none): the startup WM class, or %NULL if none is set + * in the desktop file. + * + * Since: 2.34 + */ +const char * +g_desktop_app_info_get_startup_wm_class (GDesktopAppInfo *info) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + + return info->startup_wm_class; +} + +/** + * g_desktop_app_info_get_string: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * + * Looks up a string value in the keyfile backing @info. + * + * The @key is looked up in the "Desktop Entry" group. + * + * Returns: (nullable): a newly allocated string, or %NULL if the key + * is not found + * + * Since: 2.36 + */ +char * +g_desktop_app_info_get_string (GDesktopAppInfo *info, + const char *key) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + + return g_key_file_get_string (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, key, NULL); +} + +/** + * g_desktop_app_info_get_locale_string: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * + * Looks up a localized string value in the keyfile backing @info + * translated to the current locale. + * + * The @key is looked up in the "Desktop Entry" group. + * + * Returns: (nullable): a newly allocated string, or %NULL if the key + * is not found + * + * Since: 2.56 + */ +char * +g_desktop_app_info_get_locale_string (GDesktopAppInfo *info, + const char *key) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + g_return_val_if_fail (key != NULL && *key != '\0', NULL); + + return g_key_file_get_locale_string (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, + key, NULL, NULL); +} + +/** + * g_desktop_app_info_get_boolean: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * + * Looks up a boolean value in the keyfile backing @info. + * + * The @key is looked up in the "Desktop Entry" group. + * + * Returns: the boolean value, or %FALSE if the key + * is not found + * + * Since: 2.36 + */ +gboolean +g_desktop_app_info_get_boolean (GDesktopAppInfo *info, + const char *key) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), FALSE); + + return g_key_file_get_boolean (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, key, NULL); +} + +/** + * g_desktop_app_info_get_string_list: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * @length: (out) (optional): return location for the number of returned strings, or %NULL + * + * Looks up a string list value in the keyfile backing @info. + * + * The @key is looked up in the "Desktop Entry" group. + * + * Returns: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): + * a %NULL-terminated string array or %NULL if the specified + * key cannot be found. The array should be freed with g_strfreev(). + * + * Since: 2.60 + */ +gchar ** +g_desktop_app_info_get_string_list (GDesktopAppInfo *info, + const char *key, + gsize *length) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + + return g_key_file_get_string_list (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, key, length, NULL); +} + +/** + * g_desktop_app_info_has_key: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * + * Returns whether @key exists in the "Desktop Entry" group + * of the keyfile backing @info. + * + * Returns: %TRUE if the @key exists + * + * Since: 2.36 + */ +gboolean +g_desktop_app_info_has_key (GDesktopAppInfo *info, + const char *key) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), FALSE); + + return g_key_file_has_key (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, key, NULL); +} + +/* Desktop actions support {{{2 */ + +/** + * g_desktop_app_info_list_actions: + * @info: a #GDesktopAppInfo + * + * Returns the list of "additional application actions" supported on the + * desktop file, as per the desktop file specification. + * + * As per the specification, this is the list of actions that are + * explicitly listed in the "Actions" key of the [Desktop Entry] group. + * + * Returns: (array zero-terminated=1) (element-type utf8) (transfer none): a list of strings, always non-%NULL + * + * Since: 2.38 + **/ +const gchar * const * +g_desktop_app_info_list_actions (GDesktopAppInfo *info) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + + return (const gchar **) info->actions; +} + +static gboolean +app_info_has_action (GDesktopAppInfo *info, + const gchar *action_name) +{ + gint i; + + for (i = 0; info->actions[i]; i++) + if (g_str_equal (info->actions[i], action_name)) + return TRUE; + + return FALSE; +} + +/** + * g_desktop_app_info_get_action_name: + * @info: a #GDesktopAppInfo + * @action_name: the name of the action as from + * g_desktop_app_info_list_actions() + * + * Gets the user-visible display name of the "additional application + * action" specified by @action_name. + * + * This corresponds to the "Name" key within the keyfile group for the + * action. + * + * Returns: (transfer full): the locale-specific action name + * + * Since: 2.38 + */ +gchar * +g_desktop_app_info_get_action_name (GDesktopAppInfo *info, + const gchar *action_name) +{ + gchar *group_name; + gchar *result; + + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + g_return_val_if_fail (action_name != NULL, NULL); + g_return_val_if_fail (app_info_has_action (info, action_name), NULL); + + group_name = g_strdup_printf ("Desktop Action %s", action_name); + result = g_key_file_get_locale_string (info->keyfile, group_name, "Name", NULL, NULL); + g_free (group_name); + + /* The spec says that the Name field must be given. + * + * If it's not, let's follow the behaviour of our get_name() + * implementation above and never return %NULL. + */ + if (result == NULL) + result = g_strdup (_("Unnamed")); + + return result; +} + +/** + * g_desktop_app_info_launch_action: + * @info: a #GDesktopAppInfo + * @action_name: the name of the action as from + * g_desktop_app_info_list_actions() + * @launch_context: (nullable): a #GAppLaunchContext + * + * Activates the named application action. + * + * You may only call this function on action names that were + * returned from g_desktop_app_info_list_actions(). + * + * Note that if the main entry of the desktop file indicates that the + * application supports startup notification, and @launch_context is + * non-%NULL, then startup notification will be used when activating the + * action (and as such, invocation of the action on the receiving side + * must signal the end of startup notification when it is completed). + * This is the expected behaviour of applications declaring additional + * actions, as per the desktop file specification. + * + * As with g_app_info_launch() there is no way to detect failures that + * occur while using this function. + * + * Since: 2.38 + */ +void +g_desktop_app_info_launch_action (GDesktopAppInfo *info, + const gchar *action_name, + GAppLaunchContext *launch_context) +{ + GDBusConnection *session_bus; + + g_return_if_fail (G_IS_DESKTOP_APP_INFO (info)); + g_return_if_fail (action_name != NULL); + g_return_if_fail (app_info_has_action (info, action_name)); + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + if (session_bus && info->app_id) + { + gchar *object_path; + + object_path = object_path_from_appid (info->app_id); + g_dbus_connection_call (session_bus, info->app_id, object_path, + "org.freedesktop.Application", "ActivateAction", + g_variant_new ("(sav@a{sv})", action_name, NULL, + g_desktop_app_info_make_platform_data (info, NULL, launch_context)), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + g_free (object_path); + } + else + { + gchar *group_name; + gchar *exec_line; + + group_name = g_strdup_printf ("Desktop Action %s", action_name); + exec_line = g_key_file_get_string (info->keyfile, group_name, "Exec", NULL); + g_free (group_name); + + if (exec_line) + g_desktop_app_info_launch_uris_with_spawn (info, session_bus, exec_line, NULL, launch_context, + _SPAWN_FLAGS_DEFAULT, NULL, NULL, NULL, NULL, + -1, -1, -1, NULL); + + g_free (exec_line); + } + + if (session_bus != NULL) + { + g_dbus_connection_flush (session_bus, NULL, NULL, NULL); + g_object_unref (session_bus); + } +} +/* Epilogue {{{1 */ + +/* vim:set foldmethod=marker: */ diff --git a/gio/gdesktopappinfo.h b/gio/gdesktopappinfo.h new file mode 100644 index 0000000..591bdd2 --- /dev/null +++ b/gio/gdesktopappinfo.h @@ -0,0 +1,198 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_DESKTOP_APP_INFO_H__ +#define __G_DESKTOP_APP_INFO_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DESKTOP_APP_INFO (g_desktop_app_info_get_type ()) +#define G_DESKTOP_APP_INFO(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DESKTOP_APP_INFO, GDesktopAppInfo)) +#define G_DESKTOP_APP_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DESKTOP_APP_INFO, GDesktopAppInfoClass)) +#define G_IS_DESKTOP_APP_INFO(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DESKTOP_APP_INFO)) +#define G_IS_DESKTOP_APP_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DESKTOP_APP_INFO)) +#define G_DESKTOP_APP_INFO_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DESKTOP_APP_INFO, GDesktopAppInfoClass)) + +typedef struct _GDesktopAppInfo GDesktopAppInfo; +typedef struct _GDesktopAppInfoClass GDesktopAppInfoClass; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDesktopAppInfo, g_object_unref) + +struct _GDesktopAppInfoClass +{ + GObjectClass parent_class; +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_desktop_app_info_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GDesktopAppInfo *g_desktop_app_info_new_from_filename (const char *filename); +GLIB_AVAILABLE_IN_ALL +GDesktopAppInfo *g_desktop_app_info_new_from_keyfile (GKeyFile *key_file); + +GLIB_AVAILABLE_IN_ALL +const char * g_desktop_app_info_get_filename (GDesktopAppInfo *info); + +GLIB_AVAILABLE_IN_2_30 +const char * g_desktop_app_info_get_generic_name (GDesktopAppInfo *info); +GLIB_AVAILABLE_IN_2_30 +const char * g_desktop_app_info_get_categories (GDesktopAppInfo *info); +GLIB_AVAILABLE_IN_2_30 +const char * const *g_desktop_app_info_get_keywords (GDesktopAppInfo *info); +GLIB_AVAILABLE_IN_2_30 +gboolean g_desktop_app_info_get_nodisplay (GDesktopAppInfo *info); +GLIB_AVAILABLE_IN_2_30 +gboolean g_desktop_app_info_get_show_in (GDesktopAppInfo *info, + const gchar *desktop_env); +GLIB_AVAILABLE_IN_2_34 +const char * g_desktop_app_info_get_startup_wm_class (GDesktopAppInfo *info); + +GLIB_AVAILABLE_IN_ALL +GDesktopAppInfo *g_desktop_app_info_new (const char *desktop_id); +GLIB_AVAILABLE_IN_ALL +gboolean g_desktop_app_info_get_is_hidden (GDesktopAppInfo *info); + +GLIB_DEPRECATED_IN_2_42 +void g_desktop_app_info_set_desktop_env (const char *desktop_env); + +GLIB_AVAILABLE_IN_2_36 +gboolean g_desktop_app_info_has_key (GDesktopAppInfo *info, + const char *key); +GLIB_AVAILABLE_IN_2_36 +char * g_desktop_app_info_get_string (GDesktopAppInfo *info, + const char *key); +GLIB_AVAILABLE_IN_2_56 +char * g_desktop_app_info_get_locale_string (GDesktopAppInfo *info, + const char *key); +GLIB_AVAILABLE_IN_2_36 +gboolean g_desktop_app_info_get_boolean (GDesktopAppInfo *info, + const char *key); + +GLIB_AVAILABLE_IN_2_60 +gchar ** g_desktop_app_info_get_string_list (GDesktopAppInfo *info, + const char *key, + gsize *length); + +GLIB_AVAILABLE_IN_2_38 +const gchar * const * g_desktop_app_info_list_actions (GDesktopAppInfo *info); + +GLIB_AVAILABLE_IN_2_38 +void g_desktop_app_info_launch_action (GDesktopAppInfo *info, + const gchar *action_name, + GAppLaunchContext *launch_context); + +GLIB_AVAILABLE_IN_2_38 +gchar * g_desktop_app_info_get_action_name (GDesktopAppInfo *info, + const gchar *action_name); + +#define G_TYPE_DESKTOP_APP_INFO_LOOKUP (g_desktop_app_info_lookup_get_type ()) GLIB_DEPRECATED_MACRO_IN_2_28 +#define G_DESKTOP_APP_INFO_LOOKUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_DESKTOP_APP_INFO_LOOKUP, GDesktopAppInfoLookup)) GLIB_DEPRECATED_MACRO_IN_2_28 +#define G_IS_DESKTOP_APP_INFO_LOOKUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_DESKTOP_APP_INFO_LOOKUP)) GLIB_DEPRECATED_MACRO_IN_2_28 +#define G_DESKTOP_APP_INFO_LOOKUP_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_DESKTOP_APP_INFO_LOOKUP, GDesktopAppInfoLookupIface)) GLIB_DEPRECATED_MACRO_IN_2_28 + +/** + * G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME: + * + * Extension point for default handler to URI association. See + * [Extending GIO][extending-gio]. + * + * Deprecated: 2.28: The #GDesktopAppInfoLookup interface is deprecated and + * unused by GIO. + */ +#define G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME "gio-desktop-app-info-lookup" GLIB_DEPRECATED_MACRO_IN_2_28 + +/** + * GDesktopAppInfoLookupIface: + * @get_default_for_uri_scheme: Virtual method for + * g_desktop_app_info_lookup_get_default_for_uri_scheme(). + * + * Interface that is used by backends to associate default + * handlers with URI schemes. + */ +typedef struct _GDesktopAppInfoLookup GDesktopAppInfoLookup; +typedef struct _GDesktopAppInfoLookupIface GDesktopAppInfoLookupIface; + +struct _GDesktopAppInfoLookupIface +{ + GTypeInterface g_iface; + + GAppInfo * (* get_default_for_uri_scheme) (GDesktopAppInfoLookup *lookup, + const char *uri_scheme); +}; + +GLIB_DEPRECATED +GType g_desktop_app_info_lookup_get_type (void) G_GNUC_CONST; + +GLIB_DEPRECATED +GAppInfo *g_desktop_app_info_lookup_get_default_for_uri_scheme (GDesktopAppInfoLookup *lookup, + const char *uri_scheme); + +/** + * GDesktopAppLaunchCallback: + * @appinfo: a #GDesktopAppInfo + * @pid: Process identifier + * @user_data: User data + * + * During invocation, g_desktop_app_info_launch_uris_as_manager() may + * create one or more child processes. This callback is invoked once + * for each, providing the process ID. + */ +typedef void (*GDesktopAppLaunchCallback) (GDesktopAppInfo *appinfo, + GPid pid, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_28 +gboolean g_desktop_app_info_launch_uris_as_manager (GDesktopAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + GError **error); + +GLIB_AVAILABLE_IN_2_58 +gboolean g_desktop_app_info_launch_uris_as_manager_with_fds (GDesktopAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +gchar *** g_desktop_app_info_search (const gchar *search_string); + +GLIB_AVAILABLE_IN_2_42 +GList *g_desktop_app_info_get_implementations (const gchar *interface); + +G_END_DECLS + +#endif /* __G_DESKTOP_APP_INFO_H__ */ diff --git a/gio/gdocumentportal.c b/gio/gdocumentportal.c new file mode 100644 index 0000000..276a1dc --- /dev/null +++ b/gio/gdocumentportal.c @@ -0,0 +1,216 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "gdocumentportal.h" +#include "xdp-dbus.h" +#include "gstdio.h" + +#ifdef G_OS_UNIX +#include "gunixfdlist.h" +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#else +#define HAVE_O_CLOEXEC 1 +#endif + +static gboolean +get_document_portal (GXdpDocuments **documents, + char **documents_mountpoint, + GError **error) +{ + GDBusConnection *connection = NULL; + + *documents = NULL; + *documents_mountpoint = NULL; + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error); + if (connection == NULL) + { + g_prefix_error (error, "Cannot connect to session bus when initializing document portal: "); + goto out; + } + + *documents = gxdp_documents_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + "org.freedesktop.portal.Documents", + "/org/freedesktop/portal/documents", + NULL, error); + if (*documents == NULL) + { + g_prefix_error (error, "Cannot create document portal proxy: "); + goto out; + } + + if (!gxdp_documents_call_get_mount_point_sync (*documents, + documents_mountpoint, + NULL, error)) + { + g_clear_object (documents); + g_prefix_error (error, "Cannot get document portal mount point: "); + goto out; + } + +out: + g_clear_object (&connection); + return *documents != NULL; +} + +/* Flags accepted by org.freedesktop.portal.Documents.AddFull */ +enum { + XDP_ADD_FLAGS_REUSE_EXISTING = (1 << 0), + XDP_ADD_FLAGS_PERSISTENT = (1 << 1), + XDP_ADD_FLAGS_AS_NEEDED_BY_APP = (1 << 2), + XDP_ADD_FLAGS_FLAGS_ALL = ((1 << 3) - 1) +}; + +GList * +g_document_portal_add_documents (GList *uris, + const char *app_id, + GError **error) +{ + GXdpDocuments *documents = NULL; + char *documents_mountpoint = NULL; + int length; + GList *ruris = NULL; + gboolean *as_is; + GVariantBuilder builder; + GUnixFDList *fd_list = NULL; + GList *l; + gsize i, j; + const char *permissions[] = { "read", "write", NULL }; + char **doc_ids = NULL; + GVariant *extra_out = NULL; + + if (!get_document_portal (&documents, &documents_mountpoint, error)) + { + return NULL; + } + + length = g_list_length (uris); + as_is = g_new0 (gboolean, length); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("ah")); + + fd_list = g_unix_fd_list_new (); + for (l = uris, i = 0; l; l = l->next, i++) + { + const char *uri = l->data; + int idx = -1; + char *path = NULL; + + path = g_filename_from_uri (uri, NULL, NULL); + if (path != NULL) + { + int fd; + + fd = g_open (path, O_CLOEXEC | O_RDWR); + if (fd == -1 && (errno == EACCES || errno == EISDIR)) + { + /* If we don't have write access, fall back to read-only, + * and stop requesting the write permission */ + fd = g_open (path, O_CLOEXEC | O_RDONLY); + permissions[1] = NULL; + } + if (fd >= 0) + { +#ifndef HAVE_O_CLOEXEC + fcntl (fd, F_SETFD, FD_CLOEXEC); +#endif + idx = g_unix_fd_list_append (fd_list, fd, NULL); + close (fd); + } + } + + g_free (path); + + if (idx != -1) + g_variant_builder_add (&builder, "h", idx); + else + as_is[i] = TRUE; + } + + if (g_unix_fd_list_get_length (fd_list) > 0) + { + if (!gxdp_documents_call_add_full_sync (documents, + g_variant_builder_end (&builder), + XDP_ADD_FLAGS_AS_NEEDED_BY_APP, + app_id, + permissions, + fd_list, + &doc_ids, + &extra_out, + NULL, + NULL, + error)) + goto out; + + for (l = uris, i = 0, j = 0; l; l = l->next, i++) + { + const char *uri = l->data; + char *ruri; + + if (as_is[i]) /* use as-is, not a file uri */ + { + ruri = g_strdup (uri); + } + else if (strcmp (doc_ids[j], "") == 0) /* not rewritten */ + { + ruri = g_strdup (uri); + j++; + } + else + { + char *basename = g_path_get_basename (uri + strlen ("file:")); + char *doc_path = g_build_filename (documents_mountpoint, doc_ids[j], basename, NULL); + ruri = g_strconcat ("file:", doc_path, NULL); + g_free (basename); + g_free (doc_path); + j++; + } + + ruris = g_list_prepend (ruris, ruri); + } + + ruris = g_list_reverse (ruris); + } + else + { + ruris = g_list_copy_deep (uris, (GCopyFunc)g_strdup, NULL); + g_variant_builder_clear (&builder); + } + +out: + g_clear_object (&documents); + g_clear_pointer (&documents_mountpoint, g_free); + g_clear_object (&fd_list); + g_clear_pointer (&extra_out, g_variant_unref); + g_clear_pointer (&doc_ids, g_strfreev); + g_free (as_is); + + return ruris; +} diff --git a/gio/gdocumentportal.h b/gio/gdocumentportal.h new file mode 100644 index 0000000..82d3264 --- /dev/null +++ b/gio/gdocumentportal.h @@ -0,0 +1,32 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_DOCUMENT_PORTAL_H__ + +#include +#include + +G_BEGIN_DECLS + +GList * g_document_portal_add_documents (GList *uris, + const char *app_id, + GError **error); + +G_END_DECLS + +#endif diff --git a/gio/gdrive.c b/gio/gdrive.c new file mode 100644 index 0000000..c6c68dd --- /dev/null +++ b/gio/gdrive.c @@ -0,0 +1,943 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#include "config.h" +#include "gdrive.h" +#include "gtask.h" +#include "gthemedicon.h" +#include "gasyncresult.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gdrive + * @short_description: Drive management + * @include: gio/gio.h + * + * #GDrive - this represent a piece of hardware connected to the machine. + * It's generally only created for removable hardware or hardware with + * removable media. + * + * #GDrive is a container class for #GVolume objects that stem from + * the same piece of media. As such, #GDrive abstracts a drive with + * (or without) removable media and provides operations for querying + * whether media is available, determining whether media change is + * automatically detected and ejecting the media. + * + * If the #GDrive reports that media isn't automatically detected, one + * can poll for media; typically one should not do this periodically + * as a poll for media operation is potentially expensive and may + * spin up the drive creating noise. + * + * #GDrive supports starting and stopping drives with authentication + * support for the former. This can be used to support a diverse set + * of use cases including connecting/disconnecting iSCSI devices, + * powering down external disk enclosures and starting/stopping + * multi-disk devices such as RAID devices. Note that the actual + * semantics and side-effects of starting/stopping a #GDrive may vary + * according to implementation. To choose the correct verbs in e.g. a + * file manager, use g_drive_get_start_stop_type(). + * + * For porting from GnomeVFS note that there is no equivalent of + * #GDrive in that API. + **/ + +typedef GDriveIface GDriveInterface; +G_DEFINE_INTERFACE(GDrive, g_drive, G_TYPE_OBJECT) + +static void +g_drive_default_init (GDriveInterface *iface) +{ + /** + * GDrive::changed: + * @drive: a #GDrive. + * + * Emitted when the drive's state has changed. + **/ + g_signal_new (I_("changed"), + G_TYPE_DRIVE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDriveIface, changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + /** + * GDrive::disconnected: + * @drive: a #GDrive. + * + * This signal is emitted when the #GDrive have been + * disconnected. If the recipient is holding references to the + * object they should release them so the object can be + * finalized. + **/ + g_signal_new (I_("disconnected"), + G_TYPE_DRIVE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDriveIface, disconnected), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + /** + * GDrive::eject-button: + * @drive: a #GDrive. + * + * Emitted when the physical eject button (if any) of a drive has + * been pressed. + **/ + g_signal_new (I_("eject-button"), + G_TYPE_DRIVE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDriveIface, eject_button), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + /** + * GDrive::stop-button: + * @drive: a #GDrive. + * + * Emitted when the physical stop button (if any) of a drive has + * been pressed. + * + * Since: 2.22 + **/ + g_signal_new (I_("stop-button"), + G_TYPE_DRIVE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDriveIface, stop_button), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); +} + +/** + * g_drive_get_name: + * @drive: a #GDrive. + * + * Gets the name of @drive. + * + * Returns: a string containing @drive's name. The returned + * string should be freed when no longer needed. + **/ +char * +g_drive_get_name (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), NULL); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->get_name) (drive); +} + +/** + * g_drive_get_icon: + * @drive: a #GDrive. + * + * Gets the icon for @drive. + * + * Returns: (transfer full): #GIcon for the @drive. + * Free the returned object with g_object_unref(). + **/ +GIcon * +g_drive_get_icon (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), NULL); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->get_icon) (drive); +} + +/** + * g_drive_get_symbolic_icon: + * @drive: a #GDrive. + * + * Gets the icon for @drive. + * + * Returns: (transfer full): symbolic #GIcon for the @drive. + * Free the returned object with g_object_unref(). + * + * Since: 2.34 + **/ +GIcon * +g_drive_get_symbolic_icon (GDrive *drive) +{ + GDriveIface *iface; + GIcon *ret; + + g_return_val_if_fail (G_IS_DRIVE (drive), NULL); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->get_symbolic_icon != NULL) + ret = iface->get_symbolic_icon (drive); + else + ret = g_themed_icon_new_with_default_fallbacks ("drive-removable-media-symbolic"); + + return ret; +} + +/** + * g_drive_has_volumes: + * @drive: a #GDrive. + * + * Check if @drive has any mountable volumes. + * + * Returns: %TRUE if the @drive contains volumes, %FALSE otherwise. + **/ +gboolean +g_drive_has_volumes (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->has_volumes) (drive); +} + +/** + * g_drive_get_volumes: + * @drive: a #GDrive. + * + * Get a list of mountable volumes for @drive. + * + * The returned list should be freed with g_list_free(), after + * its elements have been unreffed with g_object_unref(). + * + * Returns: (element-type GVolume) (transfer full): #GList containing any #GVolume objects on the given @drive. + **/ +GList * +g_drive_get_volumes (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), NULL); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->get_volumes) (drive); +} + +/** + * g_drive_is_media_check_automatic: + * @drive: a #GDrive. + * + * Checks if @drive is capable of automatically detecting media changes. + * + * Returns: %TRUE if the @drive is capable of automatically detecting + * media changes, %FALSE otherwise. + **/ +gboolean +g_drive_is_media_check_automatic (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->is_media_check_automatic) (drive); +} + +/** + * g_drive_is_removable: + * @drive: a #GDrive. + * + * Checks if the #GDrive and/or its media is considered removable by the user. + * See g_drive_is_media_removable(). + * + * Returns: %TRUE if @drive and/or its media is considered removable, %FALSE otherwise. + * + * Since: 2.50 + **/ +gboolean +g_drive_is_removable (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + if (iface->is_removable != NULL) + return iface->is_removable (drive); + + return FALSE; +} + +/** + * g_drive_is_media_removable: + * @drive: a #GDrive. + * + * Checks if the @drive supports removable media. + * + * Returns: %TRUE if @drive supports removable media, %FALSE otherwise. + **/ +gboolean +g_drive_is_media_removable (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->is_media_removable) (drive); +} + +/** + * g_drive_has_media: + * @drive: a #GDrive. + * + * Checks if the @drive has media. Note that the OS may not be polling + * the drive for media changes; see g_drive_is_media_check_automatic() + * for more details. + * + * Returns: %TRUE if @drive has media, %FALSE otherwise. + **/ +gboolean +g_drive_has_media (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->has_media) (drive); +} + +/** + * g_drive_can_eject: + * @drive: a #GDrive. + * + * Checks if a drive can be ejected. + * + * Returns: %TRUE if the @drive can be ejected, %FALSE otherwise. + **/ +gboolean +g_drive_can_eject (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->can_eject == NULL) + return FALSE; + + return (* iface->can_eject) (drive); +} + +/** + * g_drive_can_poll_for_media: + * @drive: a #GDrive. + * + * Checks if a drive can be polled for media changes. + * + * Returns: %TRUE if the @drive can be polled for media changes, + * %FALSE otherwise. + **/ +gboolean +g_drive_can_poll_for_media (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->poll_for_media == NULL) + return FALSE; + + return (* iface->can_poll_for_media) (drive); +} + +/** + * g_drive_eject: + * @drive: a #GDrive. + * @flags: flags affecting the unmount if required for eject + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data to pass to @callback + * + * Asynchronously ejects a drive. + * + * When the operation is finished, @callback will be called. + * You can then call g_drive_eject_finish() to obtain the + * result of the operation. + * + * Deprecated: 2.22: Use g_drive_eject_with_operation() instead. + **/ +void +g_drive_eject (GDrive *drive, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDriveIface *iface; + + g_return_if_fail (G_IS_DRIVE (drive)); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->eject == NULL) + { + g_task_report_new_error (drive, callback, user_data, + g_drive_eject_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("drive doesn’t implement eject")); + return; + } + + (* iface->eject) (drive, flags, cancellable, callback, user_data); +} + +/** + * g_drive_eject_finish: + * @drive: a #GDrive. + * @result: a #GAsyncResult. + * @error: a #GError, or %NULL + * + * Finishes ejecting a drive. + * + * Returns: %TRUE if the drive has been ejected successfully, + * %FALSE otherwise. + * + * Deprecated: 2.22: Use g_drive_eject_with_operation_finish() instead. + **/ +gboolean +g_drive_eject_finish (GDrive *drive, + GAsyncResult *result, + GError **error) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_drive_eject_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->eject_finish) (drive, result, error); +} + +/** + * g_drive_eject_with_operation: + * @drive: a #GDrive. + * @flags: flags affecting the unmount if required for eject + * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid + * user interaction. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data passed to @callback. + * + * Ejects a drive. This is an asynchronous operation, and is + * finished by calling g_drive_eject_with_operation_finish() with the @drive + * and #GAsyncResult data returned in the @callback. + * + * Since: 2.22 + **/ +void +g_drive_eject_with_operation (GDrive *drive, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDriveIface *iface; + + g_return_if_fail (G_IS_DRIVE (drive)); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->eject == NULL && iface->eject_with_operation == NULL) + { + g_task_report_new_error (drive, callback, user_data, + g_drive_eject_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for drive objects that + * don't implement any of eject or eject_with_operation. */ + _("drive doesn’t implement eject or eject_with_operation")); + return; + } + + if (iface->eject_with_operation != NULL) + (* iface->eject_with_operation) (drive, flags, mount_operation, cancellable, callback, user_data); + else + (* iface->eject) (drive, flags, cancellable, callback, user_data); +} + +/** + * g_drive_eject_with_operation_finish: + * @drive: a #GDrive. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes ejecting a drive. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * Returns: %TRUE if the drive was successfully ejected. %FALSE otherwise. + * + * Since: 2.22 + **/ +gboolean +g_drive_eject_with_operation_finish (GDrive *drive, + GAsyncResult *result, + GError **error) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_drive_eject_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_DRIVE_GET_IFACE (drive); + if (iface->eject_with_operation_finish != NULL) + return (* iface->eject_with_operation_finish) (drive, result, error); + else + return (* iface->eject_finish) (drive, result, error); +} + +/** + * g_drive_poll_for_media: + * @drive: a #GDrive. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data to pass to @callback + * + * Asynchronously polls @drive to see if media has been inserted or removed. + * + * When the operation is finished, @callback will be called. + * You can then call g_drive_poll_for_media_finish() to obtain the + * result of the operation. + **/ +void +g_drive_poll_for_media (GDrive *drive, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDriveIface *iface; + + g_return_if_fail (G_IS_DRIVE (drive)); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->poll_for_media == NULL) + { + g_task_report_new_error (drive, callback, user_data, + g_drive_poll_for_media, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("drive doesn’t implement polling for media")); + return; + } + + (* iface->poll_for_media) (drive, cancellable, callback, user_data); +} + +/** + * g_drive_poll_for_media_finish: + * @drive: a #GDrive. + * @result: a #GAsyncResult. + * @error: a #GError, or %NULL + * + * Finishes an operation started with g_drive_poll_for_media() on a drive. + * + * Returns: %TRUE if the drive has been poll_for_mediaed successfully, + * %FALSE otherwise. + **/ +gboolean +g_drive_poll_for_media_finish (GDrive *drive, + GAsyncResult *result, + GError **error) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_drive_poll_for_media)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->poll_for_media_finish) (drive, result, error); +} + +/** + * g_drive_get_identifier: + * @drive: a #GDrive + * @kind: the kind of identifier to return + * + * Gets the identifier of the given kind for @drive. The only + * identifier currently available is + * %G_DRIVE_IDENTIFIER_KIND_UNIX_DEVICE. + * + * Returns: (nullable) (transfer full): a newly allocated string containing the + * requested identifier, or %NULL if the #GDrive + * doesn't have this kind of identifier. + */ +char * +g_drive_get_identifier (GDrive *drive, + const char *kind) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), NULL); + g_return_val_if_fail (kind != NULL, NULL); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->get_identifier == NULL) + return NULL; + + return (* iface->get_identifier) (drive, kind); +} + +/** + * g_drive_enumerate_identifiers: + * @drive: a #GDrive + * + * Gets the kinds of identifiers that @drive has. + * Use g_drive_get_identifier() to obtain the identifiers + * themselves. + * + * Returns: (transfer full) (array zero-terminated=1): a %NULL-terminated + * array of strings containing kinds of identifiers. Use g_strfreev() + * to free. + */ +char ** +g_drive_enumerate_identifiers (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), NULL); + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->enumerate_identifiers == NULL) + return NULL; + + return (* iface->enumerate_identifiers) (drive); +} + +/** + * g_drive_get_start_stop_type: + * @drive: a #GDrive. + * + * Gets a hint about how a drive can be started/stopped. + * + * Returns: A value from the #GDriveStartStopType enumeration. + * + * Since: 2.22 + */ +GDriveStartStopType +g_drive_get_start_stop_type (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->get_start_stop_type == NULL) + return G_DRIVE_START_STOP_TYPE_UNKNOWN; + + return (* iface->get_start_stop_type) (drive); +} + + +/** + * g_drive_can_start: + * @drive: a #GDrive. + * + * Checks if a drive can be started. + * + * Returns: %TRUE if the @drive can be started, %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_drive_can_start (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->can_start == NULL) + return FALSE; + + return (* iface->can_start) (drive); +} + +/** + * g_drive_can_start_degraded: + * @drive: a #GDrive. + * + * Checks if a drive can be started degraded. + * + * Returns: %TRUE if the @drive can be started degraded, %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_drive_can_start_degraded (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->can_start_degraded == NULL) + return FALSE; + + return (* iface->can_start_degraded) (drive); +} + +/** + * g_drive_start: + * @drive: a #GDrive. + * @flags: flags affecting the start operation. + * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid + * user interaction. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data to pass to @callback + * + * Asynchronously starts a drive. + * + * When the operation is finished, @callback will be called. + * You can then call g_drive_start_finish() to obtain the + * result of the operation. + * + * Since: 2.22 + */ +void +g_drive_start (GDrive *drive, + GDriveStartFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDriveIface *iface; + + g_return_if_fail (G_IS_DRIVE (drive)); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->start == NULL) + { + g_task_report_new_error (drive, callback, user_data, + g_drive_start, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("drive doesn’t implement start")); + return; + } + + (* iface->start) (drive, flags, mount_operation, cancellable, callback, user_data); +} + +/** + * g_drive_start_finish: + * @drive: a #GDrive. + * @result: a #GAsyncResult. + * @error: a #GError, or %NULL + * + * Finishes starting a drive. + * + * Returns: %TRUE if the drive has been started successfully, + * %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_drive_start_finish (GDrive *drive, + GAsyncResult *result, + GError **error) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_drive_start)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->start_finish) (drive, result, error); +} + +/** + * g_drive_can_stop: + * @drive: a #GDrive. + * + * Checks if a drive can be stopped. + * + * Returns: %TRUE if the @drive can be stopped, %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_drive_can_stop (GDrive *drive) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->can_stop == NULL) + return FALSE; + + return (* iface->can_stop) (drive); +} + +/** + * g_drive_stop: + * @drive: a #GDrive. + * @flags: flags affecting the unmount if required for stopping. + * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid + * user interaction. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data to pass to @callback + * + * Asynchronously stops a drive. + * + * When the operation is finished, @callback will be called. + * You can then call g_drive_stop_finish() to obtain the + * result of the operation. + * + * Since: 2.22 + */ +void +g_drive_stop (GDrive *drive, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDriveIface *iface; + + g_return_if_fail (G_IS_DRIVE (drive)); + + iface = G_DRIVE_GET_IFACE (drive); + + if (iface->stop == NULL) + { + g_task_report_new_error (drive, callback, user_data, + g_drive_start, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("drive doesn’t implement stop")); + return; + } + + (* iface->stop) (drive, flags, mount_operation, cancellable, callback, user_data); +} + +/** + * g_drive_stop_finish: + * @drive: a #GDrive. + * @result: a #GAsyncResult. + * @error: a #GError, or %NULL + * + * Finishes stopping a drive. + * + * Returns: %TRUE if the drive has been stopped successfully, + * %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_drive_stop_finish (GDrive *drive, + GAsyncResult *result, + GError **error) +{ + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_drive_start)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_DRIVE_GET_IFACE (drive); + + return (* iface->stop_finish) (drive, result, error); +} + +/** + * g_drive_get_sort_key: + * @drive: A #GDrive. + * + * Gets the sort key for @drive, if any. + * + * Returns: (nullable): Sorting key for @drive or %NULL if no such key is available. + * + * Since: 2.32 + */ +const gchar * +g_drive_get_sort_key (GDrive *drive) +{ + const gchar *ret = NULL; + GDriveIface *iface; + + g_return_val_if_fail (G_IS_DRIVE (drive), NULL); + + iface = G_DRIVE_GET_IFACE (drive); + if (iface->get_sort_key != NULL) + ret = iface->get_sort_key (drive); + + return ret; +} diff --git a/gio/gdrive.h b/gio/gdrive.h new file mode 100644 index 0000000..cd9b721 --- /dev/null +++ b/gio/gdrive.h @@ -0,0 +1,272 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#ifndef __G_DRIVE_H__ +#define __G_DRIVE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_DRIVE_IDENTIFIER_KIND_UNIX_DEVICE: + * + * The string used to obtain a Unix device path with g_drive_get_identifier(). + * + * Since: 2.58 + */ +#define G_DRIVE_IDENTIFIER_KIND_UNIX_DEVICE "unix-device" + +#define G_TYPE_DRIVE (g_drive_get_type ()) +#define G_DRIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_DRIVE, GDrive)) +#define G_IS_DRIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_DRIVE)) +#define G_DRIVE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_DRIVE, GDriveIface)) + +/** + * GDriveIface: + * @g_iface: The parent interface. + * @changed: Signal emitted when the drive is changed. + * @disconnected: The removed signal that is emitted when the #GDrive have been disconnected. If the recipient is holding references to the object they should release them so the object can be finalized. + * @eject_button: Signal emitted when the physical eject button (if any) of a drive have been pressed. + * @get_name: Returns the name for the given #GDrive. + * @get_icon: Returns a #GIcon for the given #GDrive. + * @has_volumes: Returns %TRUE if the #GDrive has mountable volumes. + * @get_volumes: Returns a list #GList of #GVolume for the #GDrive. + * @is_removable: Returns %TRUE if the #GDrive and/or its media is considered removable by the user. Since 2.50. + * @is_media_removable: Returns %TRUE if the #GDrive supports removal and insertion of media. + * @has_media: Returns %TRUE if the #GDrive has media inserted. + * @is_media_check_automatic: Returns %TRUE if the #GDrive is capable of automatically detecting media changes. + * @can_poll_for_media: Returns %TRUE if the #GDrive is capable of manually polling for media change. + * @can_eject: Returns %TRUE if the #GDrive can eject media. + * @eject: Ejects a #GDrive. + * @eject_finish: Finishes an eject operation. + * @poll_for_media: Poll for media insertion/removal on a #GDrive. + * @poll_for_media_finish: Finishes a media poll operation. + * @get_identifier: Returns the identifier of the given kind, or %NULL if + * the #GDrive doesn't have one. + * @enumerate_identifiers: Returns an array strings listing the kinds + * of identifiers which the #GDrive has. + * @get_start_stop_type: Gets a #GDriveStartStopType with details about starting/stopping the drive. Since 2.22. + * @can_stop: Returns %TRUE if a #GDrive can be stopped. Since 2.22. + * @stop: Stops a #GDrive. Since 2.22. + * @stop_finish: Finishes a stop operation. Since 2.22. + * @can_start: Returns %TRUE if a #GDrive can be started. Since 2.22. + * @can_start_degraded: Returns %TRUE if a #GDrive can be started degraded. Since 2.22. + * @start: Starts a #GDrive. Since 2.22. + * @start_finish: Finishes a start operation. Since 2.22. + * @stop_button: Signal emitted when the physical stop button (if any) of a drive have been pressed. Since 2.22. + * @eject_with_operation: Starts ejecting a #GDrive using a #GMountOperation. Since 2.22. + * @eject_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22. + * @get_sort_key: Gets a key used for sorting #GDrive instances or %NULL if no such key exists. Since 2.32. + * @get_symbolic_icon: Returns a symbolic #GIcon for the given #GDrive. Since 2.34. + * + * Interface for creating #GDrive implementations. + */ +typedef struct _GDriveIface GDriveIface; + +struct _GDriveIface +{ + GTypeInterface g_iface; + + /* signals */ + void (* changed) (GDrive *drive); + void (* disconnected) (GDrive *drive); + void (* eject_button) (GDrive *drive); + + /* Virtual Table */ + char * (* get_name) (GDrive *drive); + GIcon * (* get_icon) (GDrive *drive); + gboolean (* has_volumes) (GDrive *drive); + GList * (* get_volumes) (GDrive *drive); + gboolean (* is_media_removable) (GDrive *drive); + gboolean (* has_media) (GDrive *drive); + gboolean (* is_media_check_automatic) (GDrive *drive); + gboolean (* can_eject) (GDrive *drive); + gboolean (* can_poll_for_media) (GDrive *drive); + void (* eject) (GDrive *drive, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* eject_finish) (GDrive *drive, + GAsyncResult *result, + GError **error); + void (* poll_for_media) (GDrive *drive, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* poll_for_media_finish) (GDrive *drive, + GAsyncResult *result, + GError **error); + + char * (* get_identifier) (GDrive *drive, + const char *kind); + char ** (* enumerate_identifiers) (GDrive *drive); + + GDriveStartStopType (* get_start_stop_type) (GDrive *drive); + + gboolean (* can_start) (GDrive *drive); + gboolean (* can_start_degraded) (GDrive *drive); + void (* start) (GDrive *drive, + GDriveStartFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* start_finish) (GDrive *drive, + GAsyncResult *result, + GError **error); + + gboolean (* can_stop) (GDrive *drive); + void (* stop) (GDrive *drive, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* stop_finish) (GDrive *drive, + GAsyncResult *result, + GError **error); + /* signal, not VFunc */ + void (* stop_button) (GDrive *drive); + + void (* eject_with_operation) (GDrive *drive, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* eject_with_operation_finish) (GDrive *drive, + GAsyncResult *result, + GError **error); + + const gchar * (* get_sort_key) (GDrive *drive); + GIcon * (* get_symbolic_icon) (GDrive *drive); + gboolean (* is_removable) (GDrive *drive); + +}; + +GLIB_AVAILABLE_IN_ALL +GType g_drive_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +char * g_drive_get_name (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +GIcon * g_drive_get_icon (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +GIcon * g_drive_get_symbolic_icon (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_has_volumes (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +GList * g_drive_get_volumes (GDrive *drive); +GLIB_AVAILABLE_IN_2_50 +gboolean g_drive_is_removable (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_is_media_removable (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_has_media (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_is_media_check_automatic (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_can_poll_for_media (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_can_eject (GDrive *drive); +GLIB_DEPRECATED_FOR(g_drive_eject_with_operation) +void g_drive_eject (GDrive *drive, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_DEPRECATED_FOR(g_drive_eject_with_operation_finish) +gboolean g_drive_eject_finish (GDrive *drive, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_drive_poll_for_media (GDrive *drive, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_poll_for_media_finish (GDrive *drive, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +char * g_drive_get_identifier (GDrive *drive, + const char *kind); +GLIB_AVAILABLE_IN_ALL +char ** g_drive_enumerate_identifiers (GDrive *drive); + +GLIB_AVAILABLE_IN_ALL +GDriveStartStopType g_drive_get_start_stop_type (GDrive *drive); + +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_can_start (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_can_start_degraded (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +void g_drive_start (GDrive *drive, + GDriveStartFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_start_finish (GDrive *drive, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_can_stop (GDrive *drive); +GLIB_AVAILABLE_IN_ALL +void g_drive_stop (GDrive *drive, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_stop_finish (GDrive *drive, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_drive_eject_with_operation (GDrive *drive, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_drive_eject_with_operation_finish (GDrive *drive, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_32 +const gchar *g_drive_get_sort_key (GDrive *drive); + +G_END_DECLS + +#endif /* __G_DRIVE_H__ */ diff --git a/gio/gdtlsclientconnection.c b/gio/gdtlsclientconnection.c new file mode 100644 index 0000000..bdbf890 --- /dev/null +++ b/gio/gdtlsclientconnection.c @@ -0,0 +1,273 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" + +#include "gdtlsclientconnection.h" +#include "ginitable.h" +#include "gioenumtypes.h" +#include "gsocket.h" +#include "gsocketconnectable.h" +#include "gtlsbackend.h" +#include "gtlscertificate.h" +#include "glibintl.h" + +/** + * SECTION:gdtlsclientconnection + * @short_description: DTLS client-side connection + * @include: gio/gio.h + * + * #GDtlsClientConnection is the client-side subclass of + * #GDtlsConnection, representing a client-side DTLS connection. + * + * Since: 2.48 + */ + +/** + * GDtlsClientConnection: + * + * Abstract base class for the backend-specific client connection + * type. + * + * Since: 2.48 + */ + +G_DEFINE_INTERFACE (GDtlsClientConnection, g_dtls_client_connection, + G_TYPE_DTLS_CONNECTION) + +static void +g_dtls_client_connection_default_init (GDtlsClientConnectionInterface *iface) +{ + /** + * GDtlsClientConnection:validation-flags: + * + * What steps to perform when validating a certificate received from + * a server. Server certificates that fail to validate in any of the + * ways indicated here will be rejected unless the application + * overrides the default via #GDtlsConnection::accept-certificate. + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_flags ("validation-flags", + P_("Validation flags"), + P_("What certificate validation to perform"), + G_TYPE_TLS_CERTIFICATE_FLAGS, + G_TLS_CERTIFICATE_VALIDATE_ALL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * GDtlsClientConnection:server-identity: + * + * A #GSocketConnectable describing the identity of the server that + * is expected on the other end of the connection. + * + * If the %G_TLS_CERTIFICATE_BAD_IDENTITY flag is set in + * #GDtlsClientConnection:validation-flags, this object will be used + * to determine the expected identify of the remote end of the + * connection; if #GDtlsClientConnection:server-identity is not set, + * or does not match the identity presented by the server, then the + * %G_TLS_CERTIFICATE_BAD_IDENTITY validation will fail. + * + * In addition to its use in verifying the server certificate, + * this is also used to give a hint to the server about what + * certificate we expect, which is useful for servers that serve + * virtual hosts. + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_object ("server-identity", + P_("Server identity"), + P_("GSocketConnectable identifying the server"), + G_TYPE_SOCKET_CONNECTABLE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * GDtlsClientConnection:accepted-cas: (type GLib.List) (element-type GLib.ByteArray) + * + * A list of the distinguished names of the Certificate Authorities + * that the server will accept client certificates signed by. If the + * server requests a client certificate during the handshake, then + * this property will be set after the handshake completes. + * + * Each item in the list is a #GByteArray which contains the complete + * subject DN of the certificate authority. + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_pointer ("accepted-cas", + P_("Accepted CAs"), + P_("Distinguished names of the CAs the server accepts certificates from"), + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_dtls_client_connection_new: + * @base_socket: the #GDatagramBased to wrap + * @server_identity: (nullable): the expected identity of the server + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a new #GDtlsClientConnection wrapping @base_socket which is + * assumed to communicate with the server identified by @server_identity. + * + * Returns: (transfer full) (type GDtlsClientConnection): the new + * #GDtlsClientConnection, or %NULL on error + * + * Since: 2.48 + */ +GDatagramBased * +g_dtls_client_connection_new (GDatagramBased *base_socket, + GSocketConnectable *server_identity, + GError **error) +{ + GObject *conn; + GTlsBackend *backend; + + backend = g_tls_backend_get_default (); + conn = g_initable_new (g_tls_backend_get_dtls_client_connection_type (backend), + NULL, error, + "base-socket", base_socket, + "server-identity", server_identity, + NULL); + return G_DATAGRAM_BASED (conn); +} + +/** + * g_dtls_client_connection_get_validation_flags: + * @conn: the #GDtlsClientConnection + * + * Gets @conn's validation flags + * + * Returns: the validation flags + * + * Since: 2.48 + */ +GTlsCertificateFlags +g_dtls_client_connection_get_validation_flags (GDtlsClientConnection *conn) +{ + GTlsCertificateFlags flags = 0; + + g_return_val_if_fail (G_IS_DTLS_CLIENT_CONNECTION (conn), 0); + + g_object_get (G_OBJECT (conn), "validation-flags", &flags, NULL); + return flags; +} + +/** + * g_dtls_client_connection_set_validation_flags: + * @conn: the #GDtlsClientConnection + * @flags: the #GTlsCertificateFlags to use + * + * Sets @conn's validation flags, to override the default set of + * checks performed when validating a server certificate. By default, + * %G_TLS_CERTIFICATE_VALIDATE_ALL is used. + * + * Since: 2.48 + */ +void +g_dtls_client_connection_set_validation_flags (GDtlsClientConnection *conn, + GTlsCertificateFlags flags) +{ + g_return_if_fail (G_IS_DTLS_CLIENT_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), "validation-flags", flags, NULL); +} + +/** + * g_dtls_client_connection_get_server_identity: + * @conn: the #GDtlsClientConnection + * + * Gets @conn's expected server identity + * + * Returns: (transfer none): a #GSocketConnectable describing the + * expected server identity, or %NULL if the expected identity is not + * known. + * + * Since: 2.48 + */ +GSocketConnectable * +g_dtls_client_connection_get_server_identity (GDtlsClientConnection *conn) +{ + GSocketConnectable *identity = NULL; + + g_return_val_if_fail (G_IS_DTLS_CLIENT_CONNECTION (conn), 0); + + g_object_get (G_OBJECT (conn), "server-identity", &identity, NULL); + if (identity) + g_object_unref (identity); + return identity; +} + +/** + * g_dtls_client_connection_set_server_identity: + * @conn: the #GDtlsClientConnection + * @identity: a #GSocketConnectable describing the expected server identity + * + * Sets @conn's expected server identity, which is used both to tell + * servers on virtual hosts which certificate to present, and also + * to let @conn know what name to look for in the certificate when + * performing %G_TLS_CERTIFICATE_BAD_IDENTITY validation, if enabled. + * + * Since: 2.48 + */ +void +g_dtls_client_connection_set_server_identity (GDtlsClientConnection *conn, + GSocketConnectable *identity) +{ + g_return_if_fail (G_IS_DTLS_CLIENT_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), "server-identity", identity, NULL); +} + +/** + * g_dtls_client_connection_get_accepted_cas: + * @conn: the #GDtlsClientConnection + * + * Gets the list of distinguished names of the Certificate Authorities + * that the server will accept certificates from. This will be set + * during the TLS handshake if the server requests a certificate. + * Otherwise, it will be %NULL. + * + * Each item in the list is a #GByteArray which contains the complete + * subject DN of the certificate authority. + * + * Returns: (element-type GByteArray) (transfer full): the list of + * CA DNs. You should unref each element with g_byte_array_unref() and then + * the free the list with g_list_free(). + * + * Since: 2.48 + */ +GList * +g_dtls_client_connection_get_accepted_cas (GDtlsClientConnection *conn) +{ + GList *accepted_cas = NULL; + + g_return_val_if_fail (G_IS_DTLS_CLIENT_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), "accepted-cas", &accepted_cas, NULL); + return accepted_cas; +} diff --git a/gio/gdtlsclientconnection.h b/gio/gdtlsclientconnection.h new file mode 100644 index 0000000..daf8e54 --- /dev/null +++ b/gio/gdtlsclientconnection.h @@ -0,0 +1,75 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc. + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_DTLS_CLIENT_CONNECTION_H__ +#define __G_DTLS_CLIENT_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DTLS_CLIENT_CONNECTION (g_dtls_client_connection_get_type ()) +#define G_DTLS_CLIENT_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_DTLS_CLIENT_CONNECTION, GDtlsClientConnection)) +#define G_IS_DTLS_CLIENT_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_DTLS_CLIENT_CONNECTION)) +#define G_DTLS_CLIENT_CONNECTION_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_DTLS_CLIENT_CONNECTION, GDtlsClientConnectionInterface)) + +typedef struct _GDtlsClientConnectionInterface GDtlsClientConnectionInterface; + +/** + * GDtlsClientConnectionInterface: + * @g_iface: The parent interface. + * + * vtable for a #GDtlsClientConnection implementation. + * + * Since: 2.48 + */ +struct _GDtlsClientConnectionInterface +{ + GTypeInterface g_iface; +}; + +GLIB_AVAILABLE_IN_2_48 +GType g_dtls_client_connection_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_48 +GDatagramBased *g_dtls_client_connection_new (GDatagramBased *base_socket, + GSocketConnectable *server_identity, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +GTlsCertificateFlags g_dtls_client_connection_get_validation_flags (GDtlsClientConnection *conn); +GLIB_AVAILABLE_IN_2_48 +void g_dtls_client_connection_set_validation_flags (GDtlsClientConnection *conn, + GTlsCertificateFlags flags); +GLIB_AVAILABLE_IN_2_48 +GSocketConnectable *g_dtls_client_connection_get_server_identity (GDtlsClientConnection *conn); +GLIB_AVAILABLE_IN_2_48 +void g_dtls_client_connection_set_server_identity (GDtlsClientConnection *conn, + GSocketConnectable *identity); +GLIB_AVAILABLE_IN_2_48 +GList * g_dtls_client_connection_get_accepted_cas (GDtlsClientConnection *conn); + + +G_END_DECLS + +#endif /* __G_DTLS_CLIENT_CONNECTION_H__ */ diff --git a/gio/gdtlsconnection.c b/gio/gdtlsconnection.c new file mode 100644 index 0000000..1fd035c --- /dev/null +++ b/gio/gdtlsconnection.c @@ -0,0 +1,1254 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" + +#include "gdtlsconnection.h" +#include "gcancellable.h" +#include "gioenumtypes.h" +#include "gsocket.h" +#include "gtlsbackend.h" +#include "gtlscertificate.h" +#include "gtlsconnection.h" +#include "gdtlsclientconnection.h" +#include "gtlsdatabase.h" +#include "gtlsinteraction.h" +#include "glibintl.h" +#include "gmarshal-internal.h" + +/** + * SECTION:gdtlsconnection + * @short_description: DTLS connection type + * @include: gio/gio.h + * + * #GDtlsConnection is the base DTLS connection class type, which wraps + * a #GDatagramBased and provides DTLS encryption on top of it. Its + * subclasses, #GDtlsClientConnection and #GDtlsServerConnection, + * implement client-side and server-side DTLS, respectively. + * + * For TLS support, see #GTlsConnection. + * + * As DTLS is datagram based, #GDtlsConnection implements #GDatagramBased, + * presenting a datagram-socket-like API for the encrypted connection. This + * operates over a base datagram connection, which is also a #GDatagramBased + * (#GDtlsConnection:base-socket). + * + * To close a DTLS connection, use g_dtls_connection_close(). + * + * Neither #GDtlsServerConnection or #GDtlsClientConnection set the peer address + * on their base #GDatagramBased if it is a #GSocket — it is up to the caller to + * do that if they wish. If they do not, and g_socket_close() is called on the + * base socket, the #GDtlsConnection will not raise a %G_IO_ERROR_NOT_CONNECTED + * error on further I/O. + * + * Since: 2.48 + */ + +/** + * GDtlsConnection: + * + * Abstract base class for the backend-specific #GDtlsClientConnection + * and #GDtlsServerConnection types. + * + * Since: 2.48 + */ + +G_DEFINE_INTERFACE (GDtlsConnection, g_dtls_connection, G_TYPE_DATAGRAM_BASED) + +enum { + ACCEPT_CERTIFICATE, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_BASE_SOCKET = 1, + PROP_REQUIRE_CLOSE_NOTIFY, + PROP_REHANDSHAKE_MODE, + PROP_DATABASE, + PROP_INTERACTION, + PROP_CERTIFICATE, + PROP_PEER_CERTIFICATE, + PROP_PEER_CERTIFICATE_ERRORS, + PROP_PROTOCOL_VERSION, + PROP_CIPHERSUITE_NAME, +}; + +static void +g_dtls_connection_default_init (GDtlsConnectionInterface *iface) +{ + /** + * GDtlsConnection:base-socket: + * + * The #GDatagramBased that the connection wraps. Note that this may be any + * implementation of #GDatagramBased, not just a #GSocket. + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_object ("base-socket", + P_("Base Socket"), + P_("The GDatagramBased that the connection wraps"), + G_TYPE_DATAGRAM_BASED, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:database: (nullable) + * + * The certificate database to use when verifying this TLS connection. + * If no certificate database is set, then the default database will be + * used. See g_tls_backend_get_default_database(). + * + * When using a non-default database, #GDtlsConnection must fall back to using + * the #GTlsDatabase to perform certificate verification using + * g_tls_database_verify_chain(), which means certificate verification will + * not be able to make use of TLS session context. This may be less secure. + * For example, if you create your own #GTlsDatabase that just wraps the + * default #GTlsDatabase, you might expect that you have not changed anything, + * but this is not true because you may have altered the behavior of + * #GDtlsConnection by causing it to use g_tls_database_verify_chain(). See the + * documentation of g_tls_database_verify_chain() for more details on specific + * security checks that may not be performed. Accordingly, setting a + * non-default database is discouraged except for specialty applications with + * unusual security requirements. + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_object ("database", + P_("Database"), + P_("Certificate database to use for looking up or verifying certificates"), + G_TYPE_TLS_DATABASE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:interaction: (nullable) + * + * A #GTlsInteraction object to be used when the connection or certificate + * database need to interact with the user. This will be used to prompt the + * user for passwords where necessary. + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_object ("interaction", + P_("Interaction"), + P_("Optional object for user interaction"), + G_TYPE_TLS_INTERACTION, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:require-close-notify: + * + * Whether or not proper TLS close notification is required. + * See g_dtls_connection_set_require_close_notify(). + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_boolean ("require-close-notify", + P_("Require close notify"), + P_("Whether to require proper TLS close notification"), + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:rehandshake-mode: + * + * The rehandshaking mode. See + * g_dtls_connection_set_rehandshake_mode(). + * + * Since: 2.48 + * + * Deprecated: 2.60: The rehandshake mode is ignored. + */ + g_object_interface_install_property (iface, + g_param_spec_enum ("rehandshake-mode", + P_("Rehandshake mode"), + P_("When to allow rehandshaking"), + G_TYPE_TLS_REHANDSHAKE_MODE, + G_TLS_REHANDSHAKE_NEVER, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS | + G_PARAM_DEPRECATED)); + /** + * GDtlsConnection:certificate: + * + * The connection's certificate; see + * g_dtls_connection_set_certificate(). + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_object ("certificate", + P_("Certificate"), + P_("The connection’s certificate"), + G_TYPE_TLS_CERTIFICATE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:peer-certificate: (nullable) + * + * The connection's peer's certificate, after the TLS handshake has + * completed or failed. Note in particular that this is not yet set + * during the emission of #GDtlsConnection::accept-certificate. + * + * (You can watch for a #GObject::notify signal on this property to + * detect when a handshake has occurred.) + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_object ("peer-certificate", + P_("Peer Certificate"), + P_("The connection’s peer’s certificate"), + G_TYPE_TLS_CERTIFICATE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:peer-certificate-errors: + * + * The errors noticed while verifying + * #GDtlsConnection:peer-certificate. Normally this should be 0, but + * it may not be if #GDtlsClientConnection:validation-flags is not + * %G_TLS_CERTIFICATE_VALIDATE_ALL, or if + * #GDtlsConnection::accept-certificate overrode the default + * behavior. + * + * GLib guarantees that if certificate verification fails, at least + * one error will be set, but it does not guarantee that all possible + * errors will be set. Accordingly, you may not safely decide to + * ignore any particular type of error. For example, it would be + * incorrect to mask %G_TLS_CERTIFICATE_EXPIRED if you want to allow + * expired certificates, because this could potentially be the only + * error flag set even if other problems exist with the certificate. + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_flags ("peer-certificate-errors", + P_("Peer Certificate Errors"), + P_("Errors found with the peer’s certificate"), + G_TYPE_TLS_CERTIFICATE_FLAGS, + 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:advertised-protocols: (nullable) + * + * The list of application-layer protocols that the connection + * advertises that it is willing to speak. See + * g_dtls_connection_set_advertised_protocols(). + * + * Since: 2.60 + */ + g_object_interface_install_property (iface, + g_param_spec_boxed ("advertised-protocols", + P_("Advertised Protocols"), + P_("Application-layer protocols available on this connection"), + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:negotiated-protocol: + * + * The application-layer protocol negotiated during the TLS + * handshake. See g_dtls_connection_get_negotiated_protocol(). + * + * Since: 2.60 + */ + g_object_interface_install_property (iface, + g_param_spec_string ("negotiated-protocol", + P_("Negotiated Protocol"), + P_("Application-layer protocol negotiated for this connection"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GDtlsConnection:protocol-version: + * + * The DTLS protocol version in use. See g_dtls_connection_get_protocol_version(). + * + * Since: 2.70 + */ + g_object_interface_install_property (iface, + g_param_spec_enum ("protocol-version", + P_("Protocol Version"), + P_("DTLS protocol version negotiated for this connection"), + G_TYPE_TLS_PROTOCOL_VERSION, + G_TLS_PROTOCOL_VERSION_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GDtlsConnection:ciphersuite-name: (nullable) + * + * The name of the DTLS ciphersuite in use. See g_dtls_connection_get_ciphersuite_name(). + * + * Since: 2.70 + */ + g_object_interface_install_property (iface, + g_param_spec_string ("ciphersuite-name", + P_("Ciphersuite Name"), + P_("Name of ciphersuite negotiated for this connection"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GDtlsConnection::accept-certificate: + * @conn: a #GDtlsConnection + * @peer_cert: the peer's #GTlsCertificate + * @errors: the problems with @peer_cert. + * + * Emitted during the TLS handshake after the peer certificate has + * been received. You can examine @peer_cert's certification path by + * calling g_tls_certificate_get_issuer() on it. + * + * For a client-side connection, @peer_cert is the server's + * certificate, and the signal will only be emitted if the + * certificate was not acceptable according to @conn's + * #GDtlsClientConnection:validation_flags. If you would like the + * certificate to be accepted despite @errors, return %TRUE from the + * signal handler. Otherwise, if no handler accepts the certificate, + * the handshake will fail with %G_TLS_ERROR_BAD_CERTIFICATE. + * + * GLib guarantees that if certificate verification fails, this signal + * will be emitted with at least one error will be set in @errors, but + * it does not guarantee that all possible errors will be set. + * Accordingly, you may not safely decide to ignore any particular + * type of error. For example, it would be incorrect to ignore + * %G_TLS_CERTIFICATE_EXPIRED if you want to allow expired + * certificates, because this could potentially be the only error flag + * set even if other problems exist with the certificate. + * + * For a server-side connection, @peer_cert is the certificate + * presented by the client, if this was requested via the server's + * #GDtlsServerConnection:authentication_mode. On the server side, + * the signal is always emitted when the client presents a + * certificate, and the certificate will only be accepted if a + * handler returns %TRUE. + * + * Note that if this signal is emitted as part of asynchronous I/O + * in the main thread, then you should not attempt to interact with + * the user before returning from the signal handler. If you want to + * let the user decide whether or not to accept the certificate, you + * would have to return %FALSE from the signal handler on the first + * attempt, and then after the connection attempt returns a + * %G_TLS_ERROR_BAD_CERTIFICATE, you can interact with the user, and + * if the user decides to accept the certificate, remember that fact, + * create a new connection, and return %TRUE from the signal handler + * the next time. + * + * If you are doing I/O in another thread, you do not + * need to worry about this, and can simply block in the signal + * handler until the UI thread returns an answer. + * + * Returns: %TRUE to accept @peer_cert (which will also + * immediately end the signal emission). %FALSE to allow the signal + * emission to continue, which will cause the handshake to fail if + * no one else overrides it. + * + * Since: 2.48 + */ + signals[ACCEPT_CERTIFICATE] = + g_signal_new (I_("accept-certificate"), + G_TYPE_DTLS_CONNECTION, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GDtlsConnectionInterface, accept_certificate), + g_signal_accumulator_true_handled, NULL, + _g_cclosure_marshal_BOOLEAN__OBJECT_FLAGS, + G_TYPE_BOOLEAN, 2, + G_TYPE_TLS_CERTIFICATE, + G_TYPE_TLS_CERTIFICATE_FLAGS); + g_signal_set_va_marshaller (signals[ACCEPT_CERTIFICATE], + G_TYPE_FROM_INTERFACE (iface), + _g_cclosure_marshal_BOOLEAN__OBJECT_FLAGSv); +} + +/** + * g_dtls_connection_set_database: + * @conn: a #GDtlsConnection + * @database: (nullable): a #GTlsDatabase + * + * Sets the certificate database that is used to verify peer certificates. + * This is set to the default database by default. See + * g_tls_backend_get_default_database(). If set to %NULL, then + * peer certificate validation will always set the + * %G_TLS_CERTIFICATE_UNKNOWN_CA error (meaning + * #GDtlsConnection::accept-certificate will always be emitted on + * client-side connections, unless that bit is not set in + * #GDtlsClientConnection:validation-flags). + * + * There are nonintuitive security implications when using a non-default + * database. See #GDtlsConnection:database for details. + * + * Since: 2.48 + */ +void +g_dtls_connection_set_database (GDtlsConnection *conn, + GTlsDatabase *database) +{ + g_return_if_fail (G_IS_DTLS_CONNECTION (conn)); + g_return_if_fail (database == NULL || G_IS_TLS_DATABASE (database)); + + g_object_set (G_OBJECT (conn), + "database", database, + NULL); +} + +/** + * g_dtls_connection_get_database: + * @conn: a #GDtlsConnection + * + * Gets the certificate database that @conn uses to verify + * peer certificates. See g_dtls_connection_set_database(). + * + * Returns: (transfer none) (nullable): the certificate database that @conn uses or %NULL + * + * Since: 2.48 + */ +GTlsDatabase* +g_dtls_connection_get_database (GDtlsConnection *conn) +{ + GTlsDatabase *database = NULL; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), + "database", &database, + NULL); + if (database) + g_object_unref (database); + return database; +} + +/** + * g_dtls_connection_set_certificate: + * @conn: a #GDtlsConnection + * @certificate: the certificate to use for @conn + * + * This sets the certificate that @conn will present to its peer + * during the TLS handshake. For a #GDtlsServerConnection, it is + * mandatory to set this, and that will normally be done at construct + * time. + * + * For a #GDtlsClientConnection, this is optional. If a handshake fails + * with %G_TLS_ERROR_CERTIFICATE_REQUIRED, that means that the server + * requires a certificate, and if you try connecting again, you should + * call this method first. You can call + * g_dtls_client_connection_get_accepted_cas() on the failed connection + * to get a list of Certificate Authorities that the server will + * accept certificates from. + * + * (It is also possible that a server will allow the connection with + * or without a certificate; in that case, if you don't provide a + * certificate, you can tell that the server requested one by the fact + * that g_dtls_client_connection_get_accepted_cas() will return + * non-%NULL.) + * + * Since: 2.48 + */ +void +g_dtls_connection_set_certificate (GDtlsConnection *conn, + GTlsCertificate *certificate) +{ + g_return_if_fail (G_IS_DTLS_CONNECTION (conn)); + g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate)); + + g_object_set (G_OBJECT (conn), "certificate", certificate, NULL); +} + +/** + * g_dtls_connection_get_certificate: + * @conn: a #GDtlsConnection + * + * Gets @conn's certificate, as set by + * g_dtls_connection_set_certificate(). + * + * Returns: (transfer none) (nullable): @conn's certificate, or %NULL + * + * Since: 2.48 + */ +GTlsCertificate * +g_dtls_connection_get_certificate (GDtlsConnection *conn) +{ + GTlsCertificate *certificate; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), "certificate", &certificate, NULL); + if (certificate) + g_object_unref (certificate); + + return certificate; +} + +/** + * g_dtls_connection_set_interaction: + * @conn: a connection + * @interaction: (nullable): an interaction object, or %NULL + * + * Set the object that will be used to interact with the user. It will be used + * for things like prompting the user for passwords. + * + * The @interaction argument will normally be a derived subclass of + * #GTlsInteraction. %NULL can also be provided if no user interaction + * should occur for this connection. + * + * Since: 2.48 + */ +void +g_dtls_connection_set_interaction (GDtlsConnection *conn, + GTlsInteraction *interaction) +{ + g_return_if_fail (G_IS_DTLS_CONNECTION (conn)); + g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); + + g_object_set (G_OBJECT (conn), "interaction", interaction, NULL); +} + +/** + * g_dtls_connection_get_interaction: + * @conn: a connection + * + * Get the object that will be used to interact with the user. It will be used + * for things like prompting the user for passwords. If %NULL is returned, then + * no user interaction will occur for this connection. + * + * Returns: (transfer none) (nullable): The interaction object. + * + * Since: 2.48 + */ +GTlsInteraction * +g_dtls_connection_get_interaction (GDtlsConnection *conn) +{ + GTlsInteraction *interaction = NULL; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), "interaction", &interaction, NULL); + if (interaction) + g_object_unref (interaction); + + return interaction; +} + +/** + * g_dtls_connection_get_peer_certificate: + * @conn: a #GDtlsConnection + * + * Gets @conn's peer's certificate after the handshake has completed + * or failed. (It is not set during the emission of + * #GDtlsConnection::accept-certificate.) + * + * Returns: (transfer none) (nullable): @conn's peer's certificate, or %NULL + * + * Since: 2.48 + */ +GTlsCertificate * +g_dtls_connection_get_peer_certificate (GDtlsConnection *conn) +{ + GTlsCertificate *peer_certificate; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), "peer-certificate", &peer_certificate, NULL); + if (peer_certificate) + g_object_unref (peer_certificate); + + return peer_certificate; +} + +/** + * g_dtls_connection_get_peer_certificate_errors: + * @conn: a #GDtlsConnection + * + * Gets the errors associated with validating @conn's peer's + * certificate, after the handshake has completed or failed. (It is + * not set during the emission of #GDtlsConnection::accept-certificate.) + * + * Returns: @conn's peer's certificate errors + * + * Since: 2.48 + */ +GTlsCertificateFlags +g_dtls_connection_get_peer_certificate_errors (GDtlsConnection *conn) +{ + GTlsCertificateFlags errors; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), 0); + + g_object_get (G_OBJECT (conn), "peer-certificate-errors", &errors, NULL); + return errors; +} + +/** + * g_dtls_connection_set_require_close_notify: + * @conn: a #GDtlsConnection + * @require_close_notify: whether or not to require close notification + * + * Sets whether or not @conn expects a proper TLS close notification + * before the connection is closed. If this is %TRUE (the default), + * then @conn will expect to receive a TLS close notification from its + * peer before the connection is closed, and will return a + * %G_TLS_ERROR_EOF error if the connection is closed without proper + * notification (since this may indicate a network error, or + * man-in-the-middle attack). + * + * In some protocols, the application will know whether or not the + * connection was closed cleanly based on application-level data + * (because the application-level data includes a length field, or is + * somehow self-delimiting); in this case, the close notify is + * redundant and may be omitted. You + * can use g_dtls_connection_set_require_close_notify() to tell @conn + * to allow an "unannounced" connection close, in which case the close + * will show up as a 0-length read, as in a non-TLS + * #GDatagramBased, and it is up to the application to check that + * the data has been fully received. + * + * Note that this only affects the behavior when the peer closes the + * connection; when the application calls g_dtls_connection_close_async() on + * @conn itself, this will send a close notification regardless of the + * setting of this property. If you explicitly want to do an unclean + * close, you can close @conn's #GDtlsConnection:base-socket rather + * than closing @conn itself. + * + * Since: 2.48 + */ +void +g_dtls_connection_set_require_close_notify (GDtlsConnection *conn, + gboolean require_close_notify) +{ + g_return_if_fail (G_IS_DTLS_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), + "require-close-notify", require_close_notify, + NULL); +} + +/** + * g_dtls_connection_get_require_close_notify: + * @conn: a #GDtlsConnection + * + * Tests whether or not @conn expects a proper TLS close notification + * when the connection is closed. See + * g_dtls_connection_set_require_close_notify() for details. + * + * Returns: %TRUE if @conn requires a proper TLS close notification. + * + * Since: 2.48 + */ +gboolean +g_dtls_connection_get_require_close_notify (GDtlsConnection *conn) +{ + gboolean require_close_notify; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), TRUE); + + g_object_get (G_OBJECT (conn), + "require-close-notify", &require_close_notify, + NULL); + return require_close_notify; +} + +/** + * g_dtls_connection_set_rehandshake_mode: + * @conn: a #GDtlsConnection + * @mode: the rehandshaking mode + * + * Since GLib 2.64, changing the rehandshake mode is no longer supported + * and will have no effect. With TLS 1.3, rehandshaking has been removed from + * the TLS protocol, replaced by separate post-handshake authentication and + * rekey operations. + * + * Since: 2.48 + * + * Deprecated: 2.60. Changing the rehandshake mode is no longer + * required for compatibility. Also, rehandshaking has been removed + * from the TLS protocol in TLS 1.3. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +void +g_dtls_connection_set_rehandshake_mode (GDtlsConnection *conn, + GTlsRehandshakeMode mode) +{ + g_return_if_fail (G_IS_DTLS_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), + "rehandshake-mode", G_TLS_REHANDSHAKE_SAFELY, + NULL); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_dtls_connection_get_rehandshake_mode: + * @conn: a #GDtlsConnection + * + * Gets @conn rehandshaking mode. See + * g_dtls_connection_set_rehandshake_mode() for details. + * + * Returns: %G_TLS_REHANDSHAKE_SAFELY + * + * Since: 2.48 + * + * Deprecated: 2.64. Changing the rehandshake mode is no longer + * required for compatibility. Also, rehandshaking has been removed + * from the TLS protocol in TLS 1.3. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GTlsRehandshakeMode +g_dtls_connection_get_rehandshake_mode (GDtlsConnection *conn) +{ + GTlsRehandshakeMode mode; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), G_TLS_REHANDSHAKE_SAFELY); + + /* Continue to call g_object_get(), even though the return value is + * ignored, so that behavior doesn’t change for derived classes. + */ + g_object_get (G_OBJECT (conn), + "rehandshake-mode", &mode, + NULL); + return G_TLS_REHANDSHAKE_SAFELY; +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_dtls_connection_handshake: + * @conn: a #GDtlsConnection + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a #GError, or %NULL + * + * Attempts a TLS handshake on @conn. + * + * On the client side, it is never necessary to call this method; + * although the connection needs to perform a handshake after + * connecting, #GDtlsConnection will handle this for you automatically + * when you try to send or receive data on the connection. You can call + * g_dtls_connection_handshake() manually if you want to know whether + * the initial handshake succeeded or failed (as opposed to just + * immediately trying to use @conn to read or write, in which case, + * if it fails, it may not be possible to tell if it failed before + * or after completing the handshake), but beware that servers may reject + * client authentication after the handshake has completed, so a + * successful handshake does not indicate the connection will be usable. + * + * Likewise, on the server side, although a handshake is necessary at + * the beginning of the communication, you do not need to call this + * function explicitly unless you want clearer error reporting. + * + * Previously, calling g_dtls_connection_handshake() after the initial + * handshake would trigger a rehandshake; however, this usage was + * deprecated in GLib 2.60 because rehandshaking was removed from the + * TLS protocol in TLS 1.3. Since GLib 2.64, calling this function after + * the initial handshake will no longer do anything. + * + * #GDtlsConnection::accept_certificate may be emitted during the + * handshake. + * + * Returns: success or failure + * + * Since: 2.48 + */ +gboolean +g_dtls_connection_handshake (GDtlsConnection *conn, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), FALSE); + + return G_DTLS_CONNECTION_GET_INTERFACE (conn)->handshake (conn, cancellable, + error); +} + +/** + * g_dtls_connection_handshake_async: + * @conn: a #GDtlsConnection + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: callback to call when the handshake is complete + * @user_data: the data to pass to the callback function + * + * Asynchronously performs a TLS handshake on @conn. See + * g_dtls_connection_handshake() for more information. + * + * Since: 2.48 + */ +void +g_dtls_connection_handshake_async (GDtlsConnection *conn, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_DTLS_CONNECTION (conn)); + + G_DTLS_CONNECTION_GET_INTERFACE (conn)->handshake_async (conn, io_priority, + cancellable, + callback, user_data); +} + +/** + * g_dtls_connection_handshake_finish: + * @conn: a #GDtlsConnection + * @result: a #GAsyncResult. + * @error: a #GError pointer, or %NULL + * + * Finish an asynchronous TLS handshake operation. See + * g_dtls_connection_handshake() for more information. + * + * Returns: %TRUE on success, %FALSE on failure, in which + * case @error will be set. + * + * Since: 2.48 + */ +gboolean +g_dtls_connection_handshake_finish (GDtlsConnection *conn, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), FALSE); + + return G_DTLS_CONNECTION_GET_INTERFACE (conn)->handshake_finish (conn, + result, + error); +} + +/** + * g_dtls_connection_shutdown: + * @conn: a #GDtlsConnection + * @shutdown_read: %TRUE to stop reception of incoming datagrams + * @shutdown_write: %TRUE to stop sending outgoing datagrams + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a #GError, or %NULL + * + * Shut down part or all of a DTLS connection. + * + * If @shutdown_read is %TRUE then the receiving side of the connection is shut + * down, and further reading is disallowed. Subsequent calls to + * g_datagram_based_receive_messages() will return %G_IO_ERROR_CLOSED. + * + * If @shutdown_write is %TRUE then the sending side of the connection is shut + * down, and further writing is disallowed. Subsequent calls to + * g_datagram_based_send_messages() will return %G_IO_ERROR_CLOSED. + * + * It is allowed for both @shutdown_read and @shutdown_write to be TRUE — this + * is equivalent to calling g_dtls_connection_close(). + * + * If @cancellable is cancelled, the #GDtlsConnection may be left + * partially-closed and any pending untransmitted data may be lost. Call + * g_dtls_connection_shutdown() again to complete closing the #GDtlsConnection. + * + * Returns: %TRUE on success, %FALSE otherwise + * + * Since: 2.48 + */ +gboolean +g_dtls_connection_shutdown (GDtlsConnection *conn, + gboolean shutdown_read, + gboolean shutdown_write, + GCancellable *cancellable, + GError **error) +{ + GDtlsConnectionInterface *iface; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), + FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!shutdown_read && !shutdown_write) + return TRUE; + + iface = G_DTLS_CONNECTION_GET_INTERFACE (conn); + g_assert (iface->shutdown != NULL); + + return iface->shutdown (conn, shutdown_read, shutdown_write, + cancellable, error); +} + +/** + * g_dtls_connection_shutdown_async: + * @conn: a #GDtlsConnection + * @shutdown_read: %TRUE to stop reception of incoming datagrams + * @shutdown_write: %TRUE to stop sending outgoing datagrams + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: callback to call when the shutdown operation is complete + * @user_data: the data to pass to the callback function + * + * Asynchronously shut down part or all of the DTLS connection. See + * g_dtls_connection_shutdown() for more information. + * + * Since: 2.48 + */ +void +g_dtls_connection_shutdown_async (GDtlsConnection *conn, + gboolean shutdown_read, + gboolean shutdown_write, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDtlsConnectionInterface *iface; + + g_return_if_fail (G_IS_DTLS_CONNECTION (conn)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + iface = G_DTLS_CONNECTION_GET_INTERFACE (conn); + g_assert (iface->shutdown_async != NULL); + + iface->shutdown_async (conn, TRUE, TRUE, io_priority, cancellable, + callback, user_data); +} + +/** + * g_dtls_connection_shutdown_finish: + * @conn: a #GDtlsConnection + * @result: a #GAsyncResult + * @error: a #GError pointer, or %NULL + * + * Finish an asynchronous TLS shutdown operation. See + * g_dtls_connection_shutdown() for more information. + * + * Returns: %TRUE on success, %FALSE on failure, in which + * case @error will be set + * + * Since: 2.48 + */ +gboolean +g_dtls_connection_shutdown_finish (GDtlsConnection *conn, + GAsyncResult *result, + GError **error) +{ + GDtlsConnectionInterface *iface; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + iface = G_DTLS_CONNECTION_GET_INTERFACE (conn); + g_assert (iface->shutdown_finish != NULL); + + return iface->shutdown_finish (conn, result, error); +} + +/** + * g_dtls_connection_close: + * @conn: a #GDtlsConnection + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a #GError, or %NULL + * + * Close the DTLS connection. This is equivalent to calling + * g_dtls_connection_shutdown() to shut down both sides of the connection. + * + * Closing a #GDtlsConnection waits for all buffered but untransmitted data to + * be sent before it completes. It then sends a `close_notify` DTLS alert to the + * peer and may wait for a `close_notify` to be received from the peer. It does + * not close the underlying #GDtlsConnection:base-socket; that must be closed + * separately. + * + * Once @conn is closed, all other operations will return %G_IO_ERROR_CLOSED. + * Closing a #GDtlsConnection multiple times will not return an error. + * + * #GDtlsConnections will be automatically closed when the last reference is + * dropped, but you might want to call this function to make sure resources are + * released as early as possible. + * + * If @cancellable is cancelled, the #GDtlsConnection may be left + * partially-closed and any pending untransmitted data may be lost. Call + * g_dtls_connection_close() again to complete closing the #GDtlsConnection. + * + * Returns: %TRUE on success, %FALSE otherwise + * + * Since: 2.48 + */ +gboolean +g_dtls_connection_close (GDtlsConnection *conn, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), + FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return G_DTLS_CONNECTION_GET_INTERFACE (conn)->shutdown (conn, TRUE, TRUE, + cancellable, error); +} + +/** + * g_dtls_connection_close_async: + * @conn: a #GDtlsConnection + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: callback to call when the close operation is complete + * @user_data: the data to pass to the callback function + * + * Asynchronously close the DTLS connection. See g_dtls_connection_close() for + * more information. + * + * Since: 2.48 + */ +void +g_dtls_connection_close_async (GDtlsConnection *conn, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_DTLS_CONNECTION (conn)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + G_DTLS_CONNECTION_GET_INTERFACE (conn)->shutdown_async (conn, TRUE, TRUE, + io_priority, + cancellable, + callback, user_data); +} + +/** + * g_dtls_connection_close_finish: + * @conn: a #GDtlsConnection + * @result: a #GAsyncResult + * @error: a #GError pointer, or %NULL + * + * Finish an asynchronous TLS close operation. See g_dtls_connection_close() + * for more information. + * + * Returns: %TRUE on success, %FALSE on failure, in which + * case @error will be set + * + * Since: 2.48 + */ +gboolean +g_dtls_connection_close_finish (GDtlsConnection *conn, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return G_DTLS_CONNECTION_GET_INTERFACE (conn)->shutdown_finish (conn, result, + error); +} + +/** + * g_dtls_connection_emit_accept_certificate: + * @conn: a #GDtlsConnection + * @peer_cert: the peer's #GTlsCertificate + * @errors: the problems with @peer_cert + * + * Used by #GDtlsConnection implementations to emit the + * #GDtlsConnection::accept-certificate signal. + * + * Returns: %TRUE if one of the signal handlers has returned + * %TRUE to accept @peer_cert + * + * Since: 2.48 + */ +gboolean +g_dtls_connection_emit_accept_certificate (GDtlsConnection *conn, + GTlsCertificate *peer_cert, + GTlsCertificateFlags errors) +{ + gboolean accept = FALSE; + + g_signal_emit (conn, signals[ACCEPT_CERTIFICATE], 0, + peer_cert, errors, &accept); + return accept; +} + +/** + * g_dtls_connection_set_advertised_protocols: + * @conn: a #GDtlsConnection + * @protocols: (array zero-terminated=1) (nullable): a %NULL-terminated + * array of ALPN protocol names (eg, "http/1.1", "h2"), or %NULL + * + * Sets the list of application-layer protocols to advertise that the + * caller is willing to speak on this connection. The + * Application-Layer Protocol Negotiation (ALPN) extension will be + * used to negotiate a compatible protocol with the peer; use + * g_dtls_connection_get_negotiated_protocol() to find the negotiated + * protocol after the handshake. Specifying %NULL for the the value + * of @protocols will disable ALPN negotiation. + * + * See [IANA TLS ALPN Protocol IDs](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids) + * for a list of registered protocol IDs. + * + * Since: 2.60 + */ +void +g_dtls_connection_set_advertised_protocols (GDtlsConnection *conn, + const gchar * const *protocols) +{ + GDtlsConnectionInterface *iface; + + iface = G_DTLS_CONNECTION_GET_INTERFACE (conn); + if (iface->set_advertised_protocols == NULL) + return; + + iface->set_advertised_protocols (conn, protocols); +} + +/** + * g_dtls_connection_get_negotiated_protocol: + * @conn: a #GDtlsConnection + * + * Gets the name of the application-layer protocol negotiated during + * the handshake. + * + * If the peer did not use the ALPN extension, or did not advertise a + * protocol that matched one of @conn's protocols, or the TLS backend + * does not support ALPN, then this will be %NULL. See + * g_dtls_connection_set_advertised_protocols(). + * + * Returns: (nullable): the negotiated protocol, or %NULL + * + * Since: 2.60 + */ +const gchar * +g_dtls_connection_get_negotiated_protocol (GDtlsConnection *conn) +{ + GDtlsConnectionInterface *iface; + + iface = G_DTLS_CONNECTION_GET_INTERFACE (conn); + if (iface->get_negotiated_protocol == NULL) + return NULL; + + return iface->get_negotiated_protocol (conn); +} + +/** + * g_dtls_connection_get_channel_binding_data: + * @conn: a #GDtlsConnection + * @type: #GTlsChannelBindingType type of data to fetch + * @data: (out callee-allocates)(optional)(transfer none): #GByteArray is + * filled with the binding data, or %NULL + * @error: a #GError pointer, or %NULL + * + * Query the TLS backend for TLS channel binding data of @type for @conn. + * + * This call retrieves TLS channel binding data as specified in RFC + * [5056](https://tools.ietf.org/html/rfc5056), RFC + * [5929](https://tools.ietf.org/html/rfc5929), and related RFCs. The + * binding data is returned in @data. The @data is resized by the callee + * using #GByteArray buffer management and will be freed when the @data + * is destroyed by g_byte_array_unref(). If @data is %NULL, it will only + * check whether TLS backend is able to fetch the data (e.g. whether @type + * is supported by the TLS backend). It does not guarantee that the data + * will be available though. That could happen if TLS connection does not + * support @type or the binding data is not available yet due to additional + * negotiation or input required. + * + * Returns: %TRUE on success, %FALSE otherwise + * + * Since: 2.66 + */ +gboolean +g_dtls_connection_get_channel_binding_data (GDtlsConnection *conn, + GTlsChannelBindingType type, + GByteArray *data, + GError **error) +{ + GDtlsConnectionInterface *iface; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + iface = G_DTLS_CONNECTION_GET_INTERFACE (conn); + if (iface->get_binding_data == NULL) + { + g_set_error_literal (error, G_TLS_CHANNEL_BINDING_ERROR, + G_TLS_CHANNEL_BINDING_ERROR_NOT_IMPLEMENTED, + _("TLS backend does not implement TLS binding retrieval")); + return FALSE; + } + + return iface->get_binding_data (conn, type, data, error); +} + +/** + * g_dtls_connection_get_protocol_version: + * @conn: a #GDTlsConnection + * + * Returns the current DTLS protocol version, which may be + * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the connection has not handshaked, or + * has been closed, or if the TLS backend has implemented a protocol version + * that is not a recognized #GTlsProtocolVersion. + * + * Returns: The current DTLS protocol version + * + * Since: 2.70 + */ +GTlsProtocolVersion +g_dtls_connection_get_protocol_version (GDtlsConnection *conn) +{ + GTlsProtocolVersion protocol_version; + GEnumClass *enum_class; + GEnumValue *enum_value; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), G_TLS_PROTOCOL_VERSION_UNKNOWN); + + g_object_get (G_OBJECT (conn), + "protocol-version", &protocol_version, + NULL); + + /* Convert unknown values to G_TLS_PROTOCOL_VERSION_UNKNOWN. */ + enum_class = g_type_class_peek_static (G_TYPE_TLS_PROTOCOL_VERSION); + enum_value = g_enum_get_value (enum_class, protocol_version); + return enum_value ? protocol_version : G_TLS_PROTOCOL_VERSION_UNKNOWN; +} + +/** + * g_dtls_connection_get_ciphersuite_name: + * @conn: a #GDTlsConnection + * + * Returns the name of the current DTLS ciphersuite, or %NULL if the + * connection has not handshaked or has been closed. Beware that the TLS + * backend may use any of multiple different naming conventions, because + * OpenSSL and GnuTLS have their own ciphersuite naming conventions that + * are different from each other and different from the standard, IANA- + * registered ciphersuite names. The ciphersuite name is intended to be + * displayed to the user for informative purposes only, and parsing it + * is not recommended. + * + * Returns: (nullable): The name of the current DTLS ciphersuite, or %NULL + * + * Since: 2.70 + */ +gchar * +g_dtls_connection_get_ciphersuite_name (GDtlsConnection *conn) +{ + gchar *ciphersuite_name; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), + "ciphersuite-name", &ciphersuite_name, + NULL); + + return g_steal_pointer (&ciphersuite_name); +} diff --git a/gio/gdtlsconnection.h b/gio/gdtlsconnection.h new file mode 100644 index 0000000..8a5ca27 --- /dev/null +++ b/gio/gdtlsconnection.h @@ -0,0 +1,228 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc. + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_DTLS_CONNECTION_H__ +#define __G_DTLS_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DTLS_CONNECTION (g_dtls_connection_get_type ()) +#define G_DTLS_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_DTLS_CONNECTION, GDtlsConnection)) +#define G_IS_DTLS_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_DTLS_CONNECTION)) +#define G_DTLS_CONNECTION_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_DTLS_CONNECTION, GDtlsConnectionInterface)) + +typedef struct _GDtlsConnectionInterface GDtlsConnectionInterface; + +/** + * GDtlsConnectionInterface: + * @g_iface: The parent interface. + * @accept_certificate: Check whether to accept a certificate. + * @handshake: Perform a handshake operation. + * @handshake_async: Start an asynchronous handshake operation. + * @handshake_finish: Finish an asynchronous handshake operation. + * @shutdown: Shut down one or both directions of the connection. + * @shutdown_async: Start an asynchronous shutdown operation. + * @shutdown_finish: Finish an asynchronous shutdown operation. + * @set_advertised_protocols: Set APLN protocol list (Since: 2.60) + * @get_negotiated_protocol: Get ALPN-negotiated protocol (Since: 2.60) + * @get_binding_data: Retrieve TLS channel binding data (Since: 2.66) + * + * Virtual method table for a #GDtlsConnection implementation. + * + * Since: 2.48 + */ +struct _GDtlsConnectionInterface +{ + GTypeInterface g_iface; + + /* signals */ + gboolean (*accept_certificate) (GDtlsConnection *connection, + GTlsCertificate *peer_cert, + GTlsCertificateFlags errors); + + /* methods */ + gboolean (*handshake) (GDtlsConnection *conn, + GCancellable *cancellable, + GError **error); + + void (*handshake_async) (GDtlsConnection *conn, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*handshake_finish) (GDtlsConnection *conn, + GAsyncResult *result, + GError **error); + + gboolean (*shutdown) (GDtlsConnection *conn, + gboolean shutdown_read, + gboolean shutdown_write, + GCancellable *cancellable, + GError **error); + + void (*shutdown_async) (GDtlsConnection *conn, + gboolean shutdown_read, + gboolean shutdown_write, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*shutdown_finish) (GDtlsConnection *conn, + GAsyncResult *result, + GError **error); + + void (*set_advertised_protocols) (GDtlsConnection *conn, + const gchar * const *protocols); + const gchar *(*get_negotiated_protocol) (GDtlsConnection *conn); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + gboolean (*get_binding_data) (GDtlsConnection *conn, + GTlsChannelBindingType type, + GByteArray *data, + GError **error); +G_GNUC_END_IGNORE_DEPRECATIONS +}; + +GLIB_AVAILABLE_IN_2_48 +GType g_dtls_connection_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_48 +void g_dtls_connection_set_database (GDtlsConnection *conn, + GTlsDatabase *database); +GLIB_AVAILABLE_IN_2_48 +GTlsDatabase *g_dtls_connection_get_database (GDtlsConnection *conn); + +GLIB_AVAILABLE_IN_2_48 +void g_dtls_connection_set_certificate (GDtlsConnection *conn, + GTlsCertificate *certificate); +GLIB_AVAILABLE_IN_2_48 +GTlsCertificate *g_dtls_connection_get_certificate (GDtlsConnection *conn); + +GLIB_AVAILABLE_IN_2_48 +void g_dtls_connection_set_interaction (GDtlsConnection *conn, + GTlsInteraction *interaction); +GLIB_AVAILABLE_IN_2_48 +GTlsInteraction *g_dtls_connection_get_interaction (GDtlsConnection *conn); + +GLIB_AVAILABLE_IN_2_48 +GTlsCertificate *g_dtls_connection_get_peer_certificate (GDtlsConnection *conn); +GLIB_AVAILABLE_IN_2_48 +GTlsCertificateFlags g_dtls_connection_get_peer_certificate_errors (GDtlsConnection *conn); + +GLIB_AVAILABLE_IN_2_48 +void g_dtls_connection_set_require_close_notify (GDtlsConnection *conn, + gboolean require_close_notify); +GLIB_AVAILABLE_IN_2_48 +gboolean g_dtls_connection_get_require_close_notify (GDtlsConnection *conn); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_DEPRECATED_IN_2_60 +void g_dtls_connection_set_rehandshake_mode (GDtlsConnection *conn, + GTlsRehandshakeMode mode); +GLIB_DEPRECATED_IN_2_60 +GTlsRehandshakeMode g_dtls_connection_get_rehandshake_mode (GDtlsConnection *conn); +G_GNUC_END_IGNORE_DEPRECATIONS + +GLIB_AVAILABLE_IN_2_48 +gboolean g_dtls_connection_handshake (GDtlsConnection *conn, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +void g_dtls_connection_handshake_async (GDtlsConnection *conn, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_48 +gboolean g_dtls_connection_handshake_finish (GDtlsConnection *conn, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +gboolean g_dtls_connection_shutdown (GDtlsConnection *conn, + gboolean shutdown_read, + gboolean shutdown_write, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +void g_dtls_connection_shutdown_async (GDtlsConnection *conn, + gboolean shutdown_read, + gboolean shutdown_write, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_48 +gboolean g_dtls_connection_shutdown_finish (GDtlsConnection *conn, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +gboolean g_dtls_connection_close (GDtlsConnection *conn, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +void g_dtls_connection_close_async (GDtlsConnection *conn, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_48 +gboolean g_dtls_connection_close_finish (GDtlsConnection *conn, + GAsyncResult *result, + GError **error); + +/*< protected >*/ +GLIB_AVAILABLE_IN_2_48 +gboolean g_dtls_connection_emit_accept_certificate (GDtlsConnection *conn, + GTlsCertificate *peer_cert, + GTlsCertificateFlags errors); +GLIB_AVAILABLE_IN_2_60 +void g_dtls_connection_set_advertised_protocols (GDtlsConnection *conn, + const gchar * const *protocols); + +GLIB_AVAILABLE_IN_2_60 +const gchar * g_dtls_connection_get_negotiated_protocol (GDtlsConnection *conn); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_AVAILABLE_IN_2_66 +gboolean g_dtls_connection_get_channel_binding_data (GDtlsConnection *conn, + GTlsChannelBindingType type, + GByteArray *data, + GError **error); +G_GNUC_END_IGNORE_DEPRECATIONS + +GLIB_AVAILABLE_IN_2_70 +GTlsProtocolVersion g_dtls_connection_get_protocol_version (GDtlsConnection *conn); + +GLIB_AVAILABLE_IN_2_70 +gchar * g_dtls_connection_get_ciphersuite_name (GDtlsConnection *conn); + +G_END_DECLS + +#endif /* __G_DTLS_CONNECTION_H__ */ diff --git a/gio/gdtlsserverconnection.c b/gio/gdtlsserverconnection.c new file mode 100644 index 0000000..51074e2 --- /dev/null +++ b/gio/gdtlsserverconnection.c @@ -0,0 +1,95 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" + +#include "gdtlsserverconnection.h" +#include "ginitable.h" +#include "gioenumtypes.h" +#include "gsocket.h" +#include "gtlsbackend.h" +#include "gtlscertificate.h" +#include "glibintl.h" + +/** + * SECTION:gdtlsserverconnection + * @short_description: DTLS server-side connection + * @include: gio/gio.h + * + * #GDtlsServerConnection is the server-side subclass of #GDtlsConnection, + * representing a server-side DTLS connection. + * + * Since: 2.48 + */ + +G_DEFINE_INTERFACE (GDtlsServerConnection, g_dtls_server_connection, + G_TYPE_DTLS_CONNECTION) + +static void +g_dtls_server_connection_default_init (GDtlsServerConnectionInterface *iface) +{ + /** + * GDtlsServerConnection:authentication-mode: + * + * The #GTlsAuthenticationMode for the server. This can be changed + * before calling g_dtls_connection_handshake() if you want to + * rehandshake with a different mode from the initial handshake. + * + * Since: 2.48 + */ + g_object_interface_install_property (iface, + g_param_spec_enum ("authentication-mode", + P_("Authentication Mode"), + P_("The client authentication mode"), + G_TYPE_TLS_AUTHENTICATION_MODE, + G_TLS_AUTHENTICATION_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_dtls_server_connection_new: + * @base_socket: the #GDatagramBased to wrap + * @certificate: (nullable): the default server certificate, or %NULL + * @error: #GError for error reporting, or %NULL to ignore + * + * Creates a new #GDtlsServerConnection wrapping @base_socket. + * + * Returns: (transfer full) (type GDtlsServerConnection): the new + * #GDtlsServerConnection, or %NULL on error + * + * Since: 2.48 + */ +GDatagramBased * +g_dtls_server_connection_new (GDatagramBased *base_socket, + GTlsCertificate *certificate, + GError **error) +{ + GObject *conn; + GTlsBackend *backend; + + backend = g_tls_backend_get_default (); + conn = g_initable_new (g_tls_backend_get_dtls_server_connection_type (backend), + NULL, error, + "base-socket", base_socket, + "certificate", certificate, + NULL); + return G_DATAGRAM_BASED (conn); +} diff --git a/gio/gdtlsserverconnection.h b/gio/gdtlsserverconnection.h new file mode 100644 index 0000000..24ecb76 --- /dev/null +++ b/gio/gdtlsserverconnection.h @@ -0,0 +1,69 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc. + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_DTLS_SERVER_CONNECTION_H__ +#define __G_DTLS_SERVER_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DTLS_SERVER_CONNECTION (g_dtls_server_connection_get_type ()) +#define G_DTLS_SERVER_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_DTLS_SERVER_CONNECTION, GDtlsServerConnection)) +#define G_IS_DTLS_SERVER_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_DTLS_SERVER_CONNECTION)) +#define G_DTLS_SERVER_CONNECTION_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_DTLS_SERVER_CONNECTION, GDtlsServerConnectionInterface)) + +/** + * GDtlsServerConnection: + * + * DTLS server-side connection. This is the server-side implementation + * of a #GDtlsConnection. + * + * Since: 2.48 + */ +typedef struct _GDtlsServerConnectionInterface GDtlsServerConnectionInterface; + +/** + * GDtlsServerConnectionInterface: + * @g_iface: The parent interface. + * + * vtable for a #GDtlsServerConnection implementation. + * + * Since: 2.48 + */ +struct _GDtlsServerConnectionInterface +{ + GTypeInterface g_iface; +}; + +GLIB_AVAILABLE_IN_2_48 +GType g_dtls_server_connection_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_48 +GDatagramBased *g_dtls_server_connection_new (GDatagramBased *base_socket, + GTlsCertificate *certificate, + GError **error); + +G_END_DECLS + +#endif /* __G_DTLS_SERVER_CONNECTION_H__ */ diff --git a/gio/gdummyfile.c b/gio/gdummyfile.c new file mode 100644 index 0000000..3bf5ba9 --- /dev/null +++ b/gio/gdummyfile.c @@ -0,0 +1,748 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "gdummyfile.h" +#include "gfile.h" + + +static void g_dummy_file_file_iface_init (GFileIface *iface); + +typedef struct { + char *scheme; + char *userinfo; + char *host; + int port; /* -1 => not in uri */ + char *path; + char *query; + char *fragment; +} GDecodedUri; + +struct _GDummyFile +{ + GObject parent_instance; + + GDecodedUri *decoded_uri; + char *text_uri; +}; + +#define g_dummy_file_get_type _g_dummy_file_get_type +G_DEFINE_TYPE_WITH_CODE (GDummyFile, g_dummy_file, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_FILE, + g_dummy_file_file_iface_init)) + +#define SUB_DELIM_CHARS "!$&'()*+,;=" + +static char * _g_encode_uri (GDecodedUri *decoded); +static void _g_decoded_uri_free (GDecodedUri *decoded); +static GDecodedUri *_g_decode_uri (const char *uri); +static GDecodedUri *_g_decoded_uri_new (void); + +static char * unescape_string (const gchar *escaped_string, + const gchar *escaped_string_end, + const gchar *illegal_characters); + +static void g_string_append_encoded (GString *string, + const char *encoded, + const char *reserved_chars_allowed); + +static void +g_dummy_file_finalize (GObject *object) +{ + GDummyFile *dummy; + + dummy = G_DUMMY_FILE (object); + + if (dummy->decoded_uri) + _g_decoded_uri_free (dummy->decoded_uri); + + g_free (dummy->text_uri); + + G_OBJECT_CLASS (g_dummy_file_parent_class)->finalize (object); +} + +static void +g_dummy_file_class_init (GDummyFileClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dummy_file_finalize; +} + +static void +g_dummy_file_init (GDummyFile *dummy) +{ +} + +GFile * +_g_dummy_file_new (const char *uri) +{ + GDummyFile *dummy; + + g_return_val_if_fail (uri != NULL, NULL); + + dummy = g_object_new (G_TYPE_DUMMY_FILE, NULL); + dummy->text_uri = g_strdup (uri); + dummy->decoded_uri = _g_decode_uri (uri); + + return G_FILE (dummy); +} + +static gboolean +g_dummy_file_is_native (GFile *file) +{ + return FALSE; +} + +static char * +g_dummy_file_get_basename (GFile *file) +{ + GDummyFile *dummy = G_DUMMY_FILE (file); + + if (dummy->decoded_uri) + return g_path_get_basename (dummy->decoded_uri->path); + return NULL; +} + +static char * +g_dummy_file_get_path (GFile *file) +{ + return NULL; +} + +static char * +g_dummy_file_get_uri (GFile *file) +{ + return g_strdup (G_DUMMY_FILE (file)->text_uri); +} + +static char * +g_dummy_file_get_parse_name (GFile *file) +{ + return g_strdup (G_DUMMY_FILE (file)->text_uri); +} + +static GFile * +g_dummy_file_get_parent (GFile *file) +{ + GDummyFile *dummy = G_DUMMY_FILE (file); + GFile *parent; + char *dirname; + char *uri; + GDecodedUri new_decoded_uri; + + if (dummy->decoded_uri == NULL || + g_strcmp0 (dummy->decoded_uri->path, "/") == 0) + return NULL; + + dirname = g_path_get_dirname (dummy->decoded_uri->path); + + if (strcmp (dirname, ".") == 0) + { + g_free (dirname); + return NULL; + } + + new_decoded_uri = *dummy->decoded_uri; + new_decoded_uri.path = dirname; + uri = _g_encode_uri (&new_decoded_uri); + g_free (dirname); + + parent = _g_dummy_file_new (uri); + g_free (uri); + + return parent; +} + +static GFile * +g_dummy_file_dup (GFile *file) +{ + GDummyFile *dummy = G_DUMMY_FILE (file); + + return _g_dummy_file_new (dummy->text_uri); +} + +static guint +g_dummy_file_hash (GFile *file) +{ + GDummyFile *dummy = G_DUMMY_FILE (file); + + return g_str_hash (dummy->text_uri); +} + +static gboolean +g_dummy_file_equal (GFile *file1, + GFile *file2) +{ + GDummyFile *dummy1 = G_DUMMY_FILE (file1); + GDummyFile *dummy2 = G_DUMMY_FILE (file2); + + return g_str_equal (dummy1->text_uri, dummy2->text_uri); +} + +static int +safe_strcmp (const char *a, + const char *b) +{ + if (a == NULL) + a = ""; + if (b == NULL) + b = ""; + + return strcmp (a, b); +} + +static gboolean +uri_same_except_path (GDecodedUri *a, + GDecodedUri *b) +{ + if (safe_strcmp (a->scheme, b->scheme) != 0) + return FALSE; + if (safe_strcmp (a->userinfo, b->userinfo) != 0) + return FALSE; + if (safe_strcmp (a->host, b->host) != 0) + return FALSE; + if (a->port != b->port) + return FALSE; + + return TRUE; +} + +static const char * +match_prefix (const char *path, + const char *prefix) +{ + int prefix_len; + + prefix_len = strlen (prefix); + if (strncmp (path, prefix, prefix_len) != 0) + return NULL; + return path + prefix_len; +} + +static gboolean +g_dummy_file_prefix_matches (GFile *parent, GFile *descendant) +{ + GDummyFile *parent_dummy = G_DUMMY_FILE (parent); + GDummyFile *descendant_dummy = G_DUMMY_FILE (descendant); + const char *remainder; + + if (parent_dummy->decoded_uri != NULL && + descendant_dummy->decoded_uri != NULL) + { + if (uri_same_except_path (parent_dummy->decoded_uri, + descendant_dummy->decoded_uri)) + { + remainder = match_prefix (descendant_dummy->decoded_uri->path, + parent_dummy->decoded_uri->path); + if (remainder != NULL && *remainder == '/') + { + while (*remainder == '/') + remainder++; + if (*remainder != 0) + return TRUE; + } + } + } + else + { + remainder = match_prefix (descendant_dummy->text_uri, + parent_dummy->text_uri); + if (remainder != NULL && *remainder == '/') + { + while (*remainder == '/') + remainder++; + if (*remainder != 0) + return TRUE; + } + } + + return FALSE; +} + +static char * +g_dummy_file_get_relative_path (GFile *parent, + GFile *descendant) +{ + GDummyFile *parent_dummy = G_DUMMY_FILE (parent); + GDummyFile *descendant_dummy = G_DUMMY_FILE (descendant); + const char *remainder; + + if (parent_dummy->decoded_uri != NULL && + descendant_dummy->decoded_uri != NULL) + { + if (uri_same_except_path (parent_dummy->decoded_uri, + descendant_dummy->decoded_uri)) + { + remainder = match_prefix (descendant_dummy->decoded_uri->path, + parent_dummy->decoded_uri->path); + if (remainder != NULL && *remainder == '/') + { + while (*remainder == '/') + remainder++; + if (*remainder != 0) + return g_strdup (remainder); + } + } + } + else + { + remainder = match_prefix (descendant_dummy->text_uri, + parent_dummy->text_uri); + if (remainder != NULL && *remainder == '/') + { + while (*remainder == '/') + remainder++; + if (*remainder != 0) + return unescape_string (remainder, NULL, "/"); + } + } + + return NULL; +} + + +static GFile * +g_dummy_file_resolve_relative_path (GFile *file, + const char *relative_path) +{ + GDummyFile *dummy = G_DUMMY_FILE (file); + GFile *child; + char *uri; + GDecodedUri new_decoded_uri; + GString *str; + + if (dummy->decoded_uri == NULL) + { + str = g_string_new (dummy->text_uri); + g_string_append (str, "/"); + g_string_append_encoded (str, relative_path, SUB_DELIM_CHARS ":@/"); + child = _g_dummy_file_new (str->str); + g_string_free (str, TRUE); + } + else + { + new_decoded_uri = *dummy->decoded_uri; + + if (g_path_is_absolute (relative_path)) + new_decoded_uri.path = g_strdup (relative_path); + else + new_decoded_uri.path = g_build_filename (new_decoded_uri.path, relative_path, NULL); + + uri = _g_encode_uri (&new_decoded_uri); + g_free (new_decoded_uri.path); + + child = _g_dummy_file_new (uri); + g_free (uri); + } + + return child; +} + +static GFile * +g_dummy_file_get_child_for_display_name (GFile *file, + const char *display_name, + GError **error) +{ + return g_file_get_child (file, display_name); +} + +static gboolean +g_dummy_file_has_uri_scheme (GFile *file, + const char *uri_scheme) +{ + GDummyFile *dummy = G_DUMMY_FILE (file); + + if (dummy->decoded_uri) + return g_ascii_strcasecmp (uri_scheme, dummy->decoded_uri->scheme) == 0; + return FALSE; +} + +static char * +g_dummy_file_get_uri_scheme (GFile *file) +{ + GDummyFile *dummy = G_DUMMY_FILE (file); + + if (dummy->decoded_uri) + return g_strdup (dummy->decoded_uri->scheme); + + return NULL; +} + + +static void +g_dummy_file_file_iface_init (GFileIface *iface) +{ + iface->dup = g_dummy_file_dup; + iface->hash = g_dummy_file_hash; + iface->equal = g_dummy_file_equal; + iface->is_native = g_dummy_file_is_native; + iface->has_uri_scheme = g_dummy_file_has_uri_scheme; + iface->get_uri_scheme = g_dummy_file_get_uri_scheme; + iface->get_basename = g_dummy_file_get_basename; + iface->get_path = g_dummy_file_get_path; + iface->get_uri = g_dummy_file_get_uri; + iface->get_parse_name = g_dummy_file_get_parse_name; + iface->get_parent = g_dummy_file_get_parent; + iface->prefix_matches = g_dummy_file_prefix_matches; + iface->get_relative_path = g_dummy_file_get_relative_path; + iface->resolve_relative_path = g_dummy_file_resolve_relative_path; + iface->get_child_for_display_name = g_dummy_file_get_child_for_display_name; + + iface->supports_thread_contexts = TRUE; +} + +/* Uri handling helper functions: */ + +static int +unescape_character (const char *scanner) +{ + int first_digit; + int second_digit; + + first_digit = g_ascii_xdigit_value (*scanner++); + if (first_digit < 0) + return -1; + + second_digit = g_ascii_xdigit_value (*scanner++); + if (second_digit < 0) + return -1; + + return (first_digit << 4) | second_digit; +} + +static char * +unescape_string (const gchar *escaped_string, + const gchar *escaped_string_end, + const gchar *illegal_characters) +{ + const gchar *in; + gchar *out, *result; + gint character; + + if (escaped_string == NULL) + return NULL; + + if (escaped_string_end == NULL) + escaped_string_end = escaped_string + strlen (escaped_string); + + result = g_malloc (escaped_string_end - escaped_string + 1); + + out = result; + for (in = escaped_string; in < escaped_string_end; in++) + { + character = *in; + if (*in == '%') + { + in++; + if (escaped_string_end - in < 2) + { + g_free (result); + return NULL; + } + + character = unescape_character (in); + + /* Check for an illegal character. We consider '\0' illegal here. */ + if (character <= 0 || + (illegal_characters != NULL && + strchr (illegal_characters, (char)character) != NULL)) + { + g_free (result); + return NULL; + } + in++; /* The other char will be eaten in the loop header */ + } + *out++ = (char)character; + } + + *out = '\0'; + g_warn_if_fail ((gsize) (out - result) <= strlen (escaped_string)); + return result; +} + +void +_g_decoded_uri_free (GDecodedUri *decoded) +{ + if (decoded == NULL) + return; + + g_free (decoded->scheme); + g_free (decoded->query); + g_free (decoded->fragment); + g_free (decoded->userinfo); + g_free (decoded->host); + g_free (decoded->path); + g_free (decoded); +} + +GDecodedUri * +_g_decoded_uri_new (void) +{ + GDecodedUri *uri; + + uri = g_new0 (GDecodedUri, 1); + uri->port = -1; + + return uri; +} + +GDecodedUri * +_g_decode_uri (const char *uri) +{ + GDecodedUri *decoded; + const char *p, *in, *hier_part_start, *hier_part_end, *query_start, *fragment_start; + char *out; + char c; + + /* From RFC 3986 Decodes: + * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + */ + + p = uri; + + /* Decode scheme: + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ + + if (!g_ascii_isalpha (*p)) + return NULL; + + while (1) + { + c = *p++; + + if (c == ':') + break; + + if (!(g_ascii_isalnum(c) || + c == '+' || + c == '-' || + c == '.')) + return NULL; + } + + decoded = _g_decoded_uri_new (); + + decoded->scheme = g_malloc (p - uri); + out = decoded->scheme; + for (in = uri; in < p - 1; in++) + *out++ = g_ascii_tolower (*in); + *out = 0; + + hier_part_start = p; + + query_start = strchr (p, '?'); + if (query_start) + { + hier_part_end = query_start++; + fragment_start = strchr (query_start, '#'); + if (fragment_start) + { + decoded->query = g_strndup (query_start, fragment_start - query_start); + decoded->fragment = g_strdup (fragment_start+1); + } + else + { + decoded->query = g_strdup (query_start); + decoded->fragment = NULL; + } + } + else + { + /* No query */ + decoded->query = NULL; + fragment_start = strchr (p, '#'); + if (fragment_start) + { + hier_part_end = fragment_start++; + decoded->fragment = g_strdup (fragment_start); + } + else + { + hier_part_end = p + strlen (p); + decoded->fragment = NULL; + } + } + + /* 3: + hier-part = "//" authority path-abempty + / path-absolute + / path-rootless + / path-empty + + */ + + if (hier_part_start[0] == '/' && + hier_part_start[1] == '/') + { + const char *authority_start, *authority_end; + const char *userinfo_start, *userinfo_end; + const char *host_start, *host_end; + const char *port_start; + + authority_start = hier_part_start + 2; + /* authority is always followed by / or nothing */ + authority_end = memchr (authority_start, '/', hier_part_end - authority_start); + if (authority_end == NULL) + authority_end = hier_part_end; + + /* 3.2: + authority = [ userinfo "@" ] host [ ":" port ] + */ + + userinfo_end = memchr (authority_start, '@', authority_end - authority_start); + if (userinfo_end) + { + userinfo_start = authority_start; + decoded->userinfo = unescape_string (userinfo_start, userinfo_end, NULL); + if (decoded->userinfo == NULL) + { + _g_decoded_uri_free (decoded); + return NULL; + } + host_start = userinfo_end + 1; + } + else + host_start = authority_start; + + port_start = memchr (host_start, ':', authority_end - host_start); + if (port_start) + { + host_end = port_start++; + + decoded->port = atoi(port_start); + } + else + { + host_end = authority_end; + decoded->port = -1; + } + + decoded->host = g_strndup (host_start, host_end - host_start); + + hier_part_start = authority_end; + } + + decoded->path = unescape_string (hier_part_start, hier_part_end, "/"); + + if (decoded->path == NULL) + { + _g_decoded_uri_free (decoded); + return NULL; + } + + return decoded; +} + +static gboolean +is_valid (char c, const char *reserved_chars_allowed) +{ + if (g_ascii_isalnum (c) || + c == '-' || + c == '.' || + c == '_' || + c == '~') + return TRUE; + + if (reserved_chars_allowed && + strchr (reserved_chars_allowed, c) != NULL) + return TRUE; + + return FALSE; +} + +static void +g_string_append_encoded (GString *string, + const char *encoded, + const char *reserved_chars_allowed) +{ + unsigned char c; + static const gchar hex[16] = "0123456789ABCDEF"; + + while ((c = *encoded) != 0) + { + if (is_valid (c, reserved_chars_allowed)) + { + g_string_append_c (string, c); + encoded++; + } + else + { + g_string_append_c (string, '%'); + g_string_append_c (string, hex[((guchar)c) >> 4]); + g_string_append_c (string, hex[((guchar)c) & 0xf]); + encoded++; + } + } +} + +static char * +_g_encode_uri (GDecodedUri *decoded) +{ + GString *uri; + + uri = g_string_new (NULL); + + g_string_append (uri, decoded->scheme); + g_string_append (uri, "://"); + + if (decoded->host != NULL) + { + if (decoded->userinfo) + { + /* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */ + g_string_append_encoded (uri, decoded->userinfo, SUB_DELIM_CHARS ":"); + g_string_append_c (uri, '@'); + } + + g_string_append (uri, decoded->host); + + if (decoded->port != -1) + { + g_string_append_c (uri, ':'); + g_string_append_printf (uri, "%d", decoded->port); + } + } + + g_string_append_encoded (uri, decoded->path, SUB_DELIM_CHARS ":@/"); + + if (decoded->query) + { + g_string_append_c (uri, '?'); + g_string_append (uri, decoded->query); + } + + if (decoded->fragment) + { + g_string_append_c (uri, '#'); + g_string_append (uri, decoded->fragment); + } + + return g_string_free (uri, FALSE); +} diff --git a/gio/gdummyfile.h b/gio/gdummyfile.h new file mode 100644 index 0000000..57f058d --- /dev/null +++ b/gio/gdummyfile.h @@ -0,0 +1,49 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_DUMMY_FILE_H__ +#define __G_DUMMY_FILE_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DUMMY_FILE (_g_dummy_file_get_type ()) +#define G_DUMMY_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DUMMY_FILE, GDummyFile)) +#define G_DUMMY_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DUMMY_FILE, GDummyFileClass)) +#define G_IS_DUMMY_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DUMMY_FILE)) +#define G_IS_DUMMY_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DUMMY_FILE)) +#define G_DUMMY_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DUMMY_FILE, GDummyFileClass)) + +typedef struct _GDummyFile GDummyFile; +typedef struct _GDummyFileClass GDummyFileClass; + +struct _GDummyFileClass +{ + GObjectClass parent_class; +}; + +GType _g_dummy_file_get_type (void) G_GNUC_CONST; + +GFile * _g_dummy_file_new (const char *uri); + +G_END_DECLS + +#endif /* __G_DUMMY_FILE_H__ */ diff --git a/gio/gdummyproxyresolver.c b/gio/gdummyproxyresolver.c new file mode 100644 index 0000000..893f97d --- /dev/null +++ b/gio/gdummyproxyresolver.c @@ -0,0 +1,134 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#include "config.h" + +#include "gdummyproxyresolver.h" + +#include + +#include "gasyncresult.h" +#include "gcancellable.h" +#include "gproxyresolver.h" +#include "gtask.h" + +#include "giomodule.h" +#include "giomodule-priv.h" + +struct _GDummyProxyResolver { + GObject parent_instance; +}; + +static void g_dummy_proxy_resolver_iface_init (GProxyResolverInterface *iface); + +#define g_dummy_proxy_resolver_get_type _g_dummy_proxy_resolver_get_type +G_DEFINE_TYPE_WITH_CODE (GDummyProxyResolver, g_dummy_proxy_resolver, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER, + g_dummy_proxy_resolver_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME, + g_define_type_id, + "dummy", + -100)) + +static void +g_dummy_proxy_resolver_finalize (GObject *object) +{ + /* must chain up */ + G_OBJECT_CLASS (g_dummy_proxy_resolver_parent_class)->finalize (object); +} + +static void +g_dummy_proxy_resolver_init (GDummyProxyResolver *resolver) +{ +} + +static gboolean +g_dummy_proxy_resolver_is_supported (GProxyResolver *resolver) +{ + return TRUE; +} + +static gchar ** +g_dummy_proxy_resolver_lookup (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GError **error) +{ + gchar **proxies; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + proxies = g_new0 (gchar *, 2); + proxies[0] = g_strdup ("direct://"); + + return proxies; +} + +static void +g_dummy_proxy_resolver_lookup_async (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GError *error = NULL; + GTask *task; + gchar **proxies; + + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, g_dummy_proxy_resolver_lookup_async); + + proxies = g_dummy_proxy_resolver_lookup (resolver, uri, cancellable, &error); + if (proxies) + g_task_return_pointer (task, proxies, (GDestroyNotify) g_strfreev); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +static gchar ** +g_dummy_proxy_resolver_lookup_finish (GProxyResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, resolver), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +g_dummy_proxy_resolver_class_init (GDummyProxyResolverClass *resolver_class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (resolver_class); + object_class->finalize = g_dummy_proxy_resolver_finalize; +} + +static void +g_dummy_proxy_resolver_iface_init (GProxyResolverInterface *iface) +{ + iface->is_supported = g_dummy_proxy_resolver_is_supported; + iface->lookup = g_dummy_proxy_resolver_lookup; + iface->lookup_async = g_dummy_proxy_resolver_lookup_async; + iface->lookup_finish = g_dummy_proxy_resolver_lookup_finish; +} diff --git a/gio/gdummyproxyresolver.h b/gio/gdummyproxyresolver.h new file mode 100644 index 0000000..1f782bc --- /dev/null +++ b/gio/gdummyproxyresolver.h @@ -0,0 +1,52 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#ifndef __G_DUMMY_PROXY_RESOLVER_H__ +#define __G_DUMMY_PROXY_RESOLVER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DUMMY_PROXY_RESOLVER (_g_dummy_proxy_resolver_get_type ()) +#define G_DUMMY_PROXY_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DUMMY_PROXY_RESOLVER, GDummyProxyResolver)) +#define G_DUMMY_PROXY_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DUMMY_PROXY_RESOLVER, GDummyProxyResolverClass)) +#define G_IS_DUMMY_PROXY_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DUMMY_PROXY_RESOLVER)) +#define G_IS_DUMMY_PROXY_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DUMMY_PROXY_RESOLVER)) +#define G_DUMMY_PROXY_RESOLVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DUMMY_PROXY_RESOLVER, GDummyProxyResolverClass)) + +typedef struct _GDummyProxyResolver GDummyProxyResolver; +typedef struct _GDummyProxyResolverClass GDummyProxyResolverClass; + + +struct _GDummyProxyResolverClass { + GObjectClass parent_class; +}; + +GType _g_dummy_proxy_resolver_get_type (void); + + +G_END_DECLS + +#endif /* __G_DUMMY_PROXY_RESOLVER_H__ */ diff --git a/gio/gdummytlsbackend.c b/gio/gdummytlsbackend.c new file mode 100644 index 0000000..8744b83 --- /dev/null +++ b/gio/gdummytlsbackend.c @@ -0,0 +1,521 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gdummytlsbackend.h" + +#include + +#include "gasyncresult.h" +#include "gcancellable.h" +#include "ginitable.h" +#include "gdtlsclientconnection.h" +#include "gdtlsconnection.h" +#include "gdtlsserverconnection.h" +#include "gtlsbackend.h" +#include "gtlscertificate.h" +#include "gtlsclientconnection.h" +#include "gtlsdatabase.h" +#include "gtlsfiledatabase.h" +#include "gtlsserverconnection.h" + +#include "giomodule.h" +#include "giomodule-priv.h" + +#include "glibintl.h" + +static GType _g_dummy_tls_certificate_get_type (void); +static GType _g_dummy_tls_connection_get_type (void); +static GType _g_dummy_dtls_connection_get_type (void); +static GType _g_dummy_tls_database_get_type (void); + +struct _GDummyTlsBackend { + GObject parent_instance; + GTlsDatabase *database; +}; + +static void g_dummy_tls_backend_iface_init (GTlsBackendInterface *iface); + +#define g_dummy_tls_backend_get_type _g_dummy_tls_backend_get_type +G_DEFINE_TYPE_WITH_CODE (GDummyTlsBackend, g_dummy_tls_backend, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_TLS_BACKEND, + g_dummy_tls_backend_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_TLS_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, + "dummy", + -100);) + +static void +g_dummy_tls_backend_init (GDummyTlsBackend *dummy) +{ +} + +static void +g_dummy_tls_backend_finalize (GObject *object) +{ + GDummyTlsBackend *dummy = G_DUMMY_TLS_BACKEND (object); + + g_clear_object (&dummy->database); + + G_OBJECT_CLASS (g_dummy_tls_backend_parent_class)->finalize (object); +} + +static void +g_dummy_tls_backend_class_init (GDummyTlsBackendClass *backend_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (backend_class); + + object_class->finalize = g_dummy_tls_backend_finalize; +} + +static GTlsDatabase * +g_dummy_tls_backend_get_default_database (GTlsBackend *backend) +{ + GDummyTlsBackend *dummy = G_DUMMY_TLS_BACKEND (backend); + + if (g_once_init_enter (&dummy->database)) + { + GTlsDatabase *tlsdb; + + tlsdb = g_object_new (_g_dummy_tls_database_get_type (), NULL); + g_once_init_leave (&dummy->database, tlsdb); + } + + return g_object_ref (dummy->database); +} + +static void +g_dummy_tls_backend_iface_init (GTlsBackendInterface *iface) +{ + iface->get_certificate_type = _g_dummy_tls_certificate_get_type; + iface->get_client_connection_type = _g_dummy_tls_connection_get_type; + iface->get_server_connection_type = _g_dummy_tls_connection_get_type; + iface->get_dtls_client_connection_type = _g_dummy_dtls_connection_get_type; + iface->get_dtls_server_connection_type = _g_dummy_dtls_connection_get_type; + iface->get_file_database_type = _g_dummy_tls_database_get_type; + iface->get_default_database = g_dummy_tls_backend_get_default_database; +} + +/* Dummy certificate type */ + +typedef struct _GDummyTlsCertificate GDummyTlsCertificate; +typedef struct _GDummyTlsCertificateClass GDummyTlsCertificateClass; + +struct _GDummyTlsCertificate { + GTlsCertificate parent_instance; +}; + +struct _GDummyTlsCertificateClass { + GTlsCertificateClass parent_class; +}; + +enum +{ + PROP_CERTIFICATE_0, + + PROP_CERT_CERTIFICATE, + PROP_CERT_CERTIFICATE_PEM, + PROP_CERT_PRIVATE_KEY, + PROP_CERT_PRIVATE_KEY_PEM, + PROP_CERT_ISSUER +}; + +static void g_dummy_tls_certificate_initable_iface_init (GInitableIface *iface); + +#define g_dummy_tls_certificate_get_type _g_dummy_tls_certificate_get_type +G_DEFINE_TYPE_WITH_CODE (GDummyTlsCertificate, g_dummy_tls_certificate, G_TYPE_TLS_CERTIFICATE, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_dummy_tls_certificate_initable_iface_init)) + +static void +g_dummy_tls_certificate_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + /* We need to define this method to make GObject happy, but it will + * never be possible to construct a working GDummyTlsCertificate, so + * it doesn't have to do anything useful. + */ +} + +static void +g_dummy_tls_certificate_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + /* Just ignore all attempts to set properties. */ +} + +static void +g_dummy_tls_certificate_class_init (GDummyTlsCertificateClass *certificate_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (certificate_class); + + gobject_class->get_property = g_dummy_tls_certificate_get_property; + gobject_class->set_property = g_dummy_tls_certificate_set_property; + + g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE, "certificate"); + g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE_PEM, "certificate-pem"); + g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY, "private-key"); + g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PEM, "private-key-pem"); + g_object_class_override_property (gobject_class, PROP_CERT_ISSUER, "issuer"); +} + +static void +g_dummy_tls_certificate_init (GDummyTlsCertificate *certificate) +{ +} + +static gboolean +g_dummy_tls_certificate_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE, + _("TLS support is not available")); + return FALSE; +} + +static void +g_dummy_tls_certificate_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_dummy_tls_certificate_initable_init; +} + +/* Dummy connection type; since GTlsClientConnection and + * GTlsServerConnection are just interfaces, we can implement them + * both on a single object. + */ + +typedef struct _GDummyTlsConnection GDummyTlsConnection; +typedef struct _GDummyTlsConnectionClass GDummyTlsConnectionClass; + +struct _GDummyTlsConnection { + GTlsConnection parent_instance; +}; + +struct _GDummyTlsConnectionClass { + GTlsConnectionClass parent_class; +}; + +enum +{ + PROP_CONNECTION_0, + + PROP_CONN_BASE_IO_STREAM, + PROP_CONN_USE_SYSTEM_CERTDB, + PROP_CONN_REQUIRE_CLOSE_NOTIFY, + PROP_CONN_REHANDSHAKE_MODE, + PROP_CONN_CERTIFICATE, + PROP_CONN_DATABASE, + PROP_CONN_INTERACTION, + PROP_CONN_PEER_CERTIFICATE, + PROP_CONN_PEER_CERTIFICATE_ERRORS, + PROP_CONN_VALIDATION_FLAGS, + PROP_CONN_SERVER_IDENTITY, + PROP_CONN_USE_SSL3, + PROP_CONN_ACCEPTED_CAS, + PROP_CONN_AUTHENTICATION_MODE, + PROP_CONN_ADVERTISED_PROTOCOLS, + PROP_CONN_NEGOTIATED_PROTOCOL, +}; + +static void g_dummy_tls_connection_initable_iface_init (GInitableIface *iface); + +#define g_dummy_tls_connection_get_type _g_dummy_tls_connection_get_type +G_DEFINE_TYPE_WITH_CODE (GDummyTlsConnection, g_dummy_tls_connection, G_TYPE_TLS_CONNECTION, + G_IMPLEMENT_INTERFACE (G_TYPE_TLS_CLIENT_CONNECTION, NULL) + G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION, NULL) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_dummy_tls_connection_initable_iface_init)) + +static void +g_dummy_tls_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ +} + +static void +g_dummy_tls_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ +} + +static gboolean +g_dummy_tls_connection_close (GIOStream *stream, + GCancellable *cancellable, + GError **error) +{ + return TRUE; +} + +static void +g_dummy_tls_connection_class_init (GDummyTlsConnectionClass *connection_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (connection_class); + GIOStreamClass *io_stream_class = G_IO_STREAM_CLASS (connection_class); + + gobject_class->get_property = g_dummy_tls_connection_get_property; + gobject_class->set_property = g_dummy_tls_connection_set_property; + + /* Need to override this because when initable_init fails it will + * dispose the connection, which will close it, which would + * otherwise try to close its input/output streams, which don't + * exist. + */ + io_stream_class->close_fn = g_dummy_tls_connection_close; + + g_object_class_override_property (gobject_class, PROP_CONN_BASE_IO_STREAM, "base-io-stream"); + g_object_class_override_property (gobject_class, PROP_CONN_USE_SYSTEM_CERTDB, "use-system-certdb"); + g_object_class_override_property (gobject_class, PROP_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify"); + g_object_class_override_property (gobject_class, PROP_CONN_REHANDSHAKE_MODE, "rehandshake-mode"); + g_object_class_override_property (gobject_class, PROP_CONN_CERTIFICATE, "certificate"); + g_object_class_override_property (gobject_class, PROP_CONN_DATABASE, "database"); + g_object_class_override_property (gobject_class, PROP_CONN_INTERACTION, "interaction"); + g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE, "peer-certificate"); + g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors"); + g_object_class_override_property (gobject_class, PROP_CONN_VALIDATION_FLAGS, "validation-flags"); + g_object_class_override_property (gobject_class, PROP_CONN_SERVER_IDENTITY, "server-identity"); + g_object_class_override_property (gobject_class, PROP_CONN_USE_SSL3, "use-ssl3"); + g_object_class_override_property (gobject_class, PROP_CONN_ACCEPTED_CAS, "accepted-cas"); + g_object_class_override_property (gobject_class, PROP_CONN_AUTHENTICATION_MODE, "authentication-mode"); + g_object_class_override_property (gobject_class, PROP_CONN_ADVERTISED_PROTOCOLS, "advertised-protocols"); + g_object_class_override_property (gobject_class, PROP_CONN_NEGOTIATED_PROTOCOL, "negotiated-protocol"); +} + +static void +g_dummy_tls_connection_init (GDummyTlsConnection *connection) +{ +} + +static gboolean +g_dummy_tls_connection_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE, + _("TLS support is not available")); + return FALSE; +} + +static void +g_dummy_tls_connection_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_dummy_tls_connection_initable_init; +} + +/* Dummy DTLS connection type; since GDtlsClientConnection and + * GDtlsServerConnection are just interfaces, we can implement them + * both on a single object. + */ + +typedef struct _GDummyDtlsConnection GDummyDtlsConnection; +typedef struct _GDummyDtlsConnectionClass GDummyDtlsConnectionClass; + +struct _GDummyDtlsConnection { + GObject parent_instance; +}; + +struct _GDummyDtlsConnectionClass { + GObjectClass parent_class; +}; + +enum +{ + PROP_DTLS_CONN_BASE_SOCKET = 1, + PROP_DTLS_CONN_REQUIRE_CLOSE_NOTIFY, + PROP_DTLS_CONN_REHANDSHAKE_MODE, + PROP_DTLS_CONN_CERTIFICATE, + PROP_DTLS_CONN_DATABASE, + PROP_DTLS_CONN_INTERACTION, + PROP_DTLS_CONN_PEER_CERTIFICATE, + PROP_DTLS_CONN_PEER_CERTIFICATE_ERRORS, + PROP_DTLS_CONN_VALIDATION_FLAGS, + PROP_DTLS_CONN_SERVER_IDENTITY, + PROP_DTLS_CONN_ENABLE_NEGOTIATION, + PROP_DTLS_CONN_ACCEPTED_CAS, + PROP_DTLS_CONN_AUTHENTICATION_MODE, +}; + +static void g_dummy_dtls_connection_initable_iface_init (GInitableIface *iface); + +#define g_dummy_dtls_connection_get_type _g_dummy_dtls_connection_get_type +G_DEFINE_TYPE_WITH_CODE (GDummyDtlsConnection, g_dummy_dtls_connection, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_CONNECTION, NULL); + G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_CLIENT_CONNECTION, NULL); + G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_SERVER_CONNECTION, NULL); + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_dummy_dtls_connection_initable_iface_init);) + +static void +g_dummy_dtls_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ +} + +static void +g_dummy_dtls_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ +} + +static void +g_dummy_dtls_connection_class_init (GDummyDtlsConnectionClass *connection_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (connection_class); + + gobject_class->get_property = g_dummy_dtls_connection_get_property; + gobject_class->set_property = g_dummy_dtls_connection_set_property; + + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_BASE_SOCKET, "base-socket"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_REHANDSHAKE_MODE, "rehandshake-mode"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_CERTIFICATE, "certificate"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_DATABASE, "database"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_INTERACTION, "interaction"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_PEER_CERTIFICATE, "peer-certificate"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_VALIDATION_FLAGS, "validation-flags"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_SERVER_IDENTITY, "server-identity"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_ACCEPTED_CAS, "accepted-cas"); + g_object_class_override_property (gobject_class, PROP_DTLS_CONN_AUTHENTICATION_MODE, "authentication-mode"); +} + +static void +g_dummy_dtls_connection_init (GDummyDtlsConnection *connection) +{ +} + +static gboolean +g_dummy_dtls_connection_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE, + _("DTLS support is not available")); + return FALSE; +} + +static void +g_dummy_dtls_connection_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_dummy_dtls_connection_initable_init; +} + +/* Dummy database type. + */ + +typedef struct _GDummyTlsDatabase GDummyTlsDatabase; +typedef struct _GDummyTlsDatabaseClass GDummyTlsDatabaseClass; + +struct _GDummyTlsDatabase { + GTlsDatabase parent_instance; +}; + +struct _GDummyTlsDatabaseClass { + GTlsDatabaseClass parent_class; +}; + +enum +{ + PROP_DATABASE_0, + + PROP_ANCHORS, +}; + +static void g_dummy_tls_database_file_database_iface_init (GTlsFileDatabaseInterface *iface); +static void g_dummy_tls_database_initable_iface_init (GInitableIface *iface); + +#define g_dummy_tls_database_get_type _g_dummy_tls_database_get_type +G_DEFINE_TYPE_WITH_CODE (GDummyTlsDatabase, g_dummy_tls_database, G_TYPE_TLS_DATABASE, + G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE, + g_dummy_tls_database_file_database_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_dummy_tls_database_initable_iface_init)) + + +static void +g_dummy_tls_database_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + /* We need to define this method to make GObject happy, but it will + * never be possible to construct a working GDummyTlsDatabase, so + * it doesn't have to do anything useful. + */ +} + +static void +g_dummy_tls_database_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + /* Just ignore all attempts to set properties. */ +} + +static void +g_dummy_tls_database_class_init (GDummyTlsDatabaseClass *database_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (database_class); + + gobject_class->get_property = g_dummy_tls_database_get_property; + gobject_class->set_property = g_dummy_tls_database_set_property; + + g_object_class_override_property (gobject_class, PROP_ANCHORS, "anchors"); +} + +static void +g_dummy_tls_database_init (GDummyTlsDatabase *database) +{ +} + +static void +g_dummy_tls_database_file_database_iface_init (GTlsFileDatabaseInterface *iface) +{ +} + +static gboolean +g_dummy_tls_database_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE, + _("TLS support is not available")); + return FALSE; +} + +static void +g_dummy_tls_database_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_dummy_tls_database_initable_init; +} diff --git a/gio/gdummytlsbackend.h b/gio/gdummytlsbackend.h new file mode 100644 index 0000000..08e8f07 --- /dev/null +++ b/gio/gdummytlsbackend.h @@ -0,0 +1,44 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_DUMMY_TLS_BACKEND_H__ +#define __G_DUMMY_TLS_BACKEND_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_DUMMY_TLS_BACKEND (_g_dummy_tls_backend_get_type ()) +#define G_DUMMY_TLS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DUMMY_TLS_BACKEND, GDummyTlsBackend)) +#define G_DUMMY_TLS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DUMMY_TLS_BACKEND, GDummyTlsBackendClass)) +#define G_IS_DUMMY_TLS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DUMMY_TLS_BACKEND)) +#define G_IS_DUMMY_TLS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DUMMY_TLS_BACKEND)) +#define G_DUMMY_TLS_BACKEND_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DUMMY_TLS_BACKEND, GDummyTlsBackendClass)) + +typedef struct _GDummyTlsBackend GDummyTlsBackend; +typedef struct _GDummyTlsBackendClass GDummyTlsBackendClass; + +struct _GDummyTlsBackendClass { + GObjectClass parent_class; +}; + +GType _g_dummy_tls_backend_get_type (void); + +G_END_DECLS + +#endif /* __G_DUMMY_TLS_BACKEND_H__ */ diff --git a/gio/gemblem.c b/gio/gemblem.c new file mode 100644 index 0000000..e8c4d4e --- /dev/null +++ b/gio/gemblem.c @@ -0,0 +1,379 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Clemens N. Buss + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +#include "gicon.h" +#include "gemblem.h" +#include "glibintl.h" +#include "gioenums.h" +#include "gioenumtypes.h" +#include "gioerror.h" +#include +#include + + +/** + * SECTION:gemblem + * @short_description: An object for emblems + * @include: gio/gio.h + * @see_also: #GIcon, #GEmblemedIcon, #GLoadableIcon, #GThemedIcon + * + * #GEmblem is an implementation of #GIcon that supports + * having an emblem, which is an icon with additional properties. + * It can than be added to a #GEmblemedIcon. + * + * Currently, only metainformation about the emblem's origin is + * supported. More may be added in the future. + */ + +static void g_emblem_iface_init (GIconIface *iface); + +struct _GEmblem +{ + GObject parent_instance; + + GIcon *icon; + GEmblemOrigin origin; +}; + +struct _GEmblemClass +{ + GObjectClass parent_class; +}; + +enum +{ + PROP_0_GEMBLEM, + PROP_ICON, + PROP_ORIGIN +}; + +G_DEFINE_TYPE_WITH_CODE (GEmblem, g_emblem, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ICON, g_emblem_iface_init)) + +static void +g_emblem_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GEmblem *emblem = G_EMBLEM (object); + + switch (prop_id) + { + case PROP_ICON: + g_value_set_object (value, emblem->icon); + break; + + case PROP_ORIGIN: + g_value_set_enum (value, emblem->origin); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_emblem_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GEmblem *emblem = G_EMBLEM (object); + + switch (prop_id) + { + case PROP_ICON: + emblem->icon = g_value_dup_object (value); + break; + + case PROP_ORIGIN: + emblem->origin = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_emblem_finalize (GObject *object) +{ + GEmblem *emblem = G_EMBLEM (object); + + if (emblem->icon) + g_object_unref (emblem->icon); + + (*G_OBJECT_CLASS (g_emblem_parent_class)->finalize) (object); +} + +static void +g_emblem_class_init (GEmblemClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_emblem_finalize; + gobject_class->set_property = g_emblem_set_property; + gobject_class->get_property = g_emblem_get_property; + + g_object_class_install_property (gobject_class, + PROP_ORIGIN, + g_param_spec_enum ("origin", + P_("GEmblem’s origin"), + P_("Tells which origin the emblem is derived from"), + G_TYPE_EMBLEM_ORIGIN, + G_EMBLEM_ORIGIN_UNKNOWN, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_ICON, + g_param_spec_object ("icon", + P_("The icon of the emblem"), + P_("The actual icon of the emblem"), + G_TYPE_OBJECT, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + +} + +static void +g_emblem_init (GEmblem *emblem) +{ +} + +/** + * g_emblem_new: + * @icon: a GIcon containing the icon. + * + * Creates a new emblem for @icon. + * + * Returns: a new #GEmblem. + * + * Since: 2.18 + */ +GEmblem * +g_emblem_new (GIcon *icon) +{ + GEmblem* emblem; + + g_return_val_if_fail (icon != NULL, NULL); + g_return_val_if_fail (G_IS_ICON (icon), NULL); + g_return_val_if_fail (!G_IS_EMBLEM (icon), NULL); + + emblem = g_object_new (G_TYPE_EMBLEM, NULL); + emblem->icon = g_object_ref (icon); + emblem->origin = G_EMBLEM_ORIGIN_UNKNOWN; + + return emblem; +} + +/** + * g_emblem_new_with_origin: + * @icon: a GIcon containing the icon. + * @origin: a GEmblemOrigin enum defining the emblem's origin + * + * Creates a new emblem for @icon. + * + * Returns: a new #GEmblem. + * + * Since: 2.18 + */ +GEmblem * +g_emblem_new_with_origin (GIcon *icon, + GEmblemOrigin origin) +{ + GEmblem* emblem; + + g_return_val_if_fail (icon != NULL, NULL); + g_return_val_if_fail (G_IS_ICON (icon), NULL); + g_return_val_if_fail (!G_IS_EMBLEM (icon), NULL); + + emblem = g_object_new (G_TYPE_EMBLEM, NULL); + emblem->icon = g_object_ref (icon); + emblem->origin = origin; + + return emblem; +} + +/** + * g_emblem_get_icon: + * @emblem: a #GEmblem from which the icon should be extracted. + * + * Gives back the icon from @emblem. + * + * Returns: (transfer none): a #GIcon. The returned object belongs to + * the emblem and should not be modified or freed. + * + * Since: 2.18 + */ +GIcon * +g_emblem_get_icon (GEmblem *emblem) +{ + g_return_val_if_fail (G_IS_EMBLEM (emblem), NULL); + + return emblem->icon; +} + + +/** + * g_emblem_get_origin: + * @emblem: a #GEmblem + * + * Gets the origin of the emblem. + * + * Returns: (transfer none): the origin of the emblem + * + * Since: 2.18 + */ +GEmblemOrigin +g_emblem_get_origin (GEmblem *emblem) +{ + g_return_val_if_fail (G_IS_EMBLEM (emblem), G_EMBLEM_ORIGIN_UNKNOWN); + + return emblem->origin; +} + +static guint +g_emblem_hash (GIcon *icon) +{ + GEmblem *emblem = G_EMBLEM (icon); + guint hash; + + hash = g_icon_hash (g_emblem_get_icon (emblem)); + hash ^= emblem->origin; + + return hash; +} + +static gboolean +g_emblem_equal (GIcon *icon1, + GIcon *icon2) +{ + GEmblem *emblem1 = G_EMBLEM (icon1); + GEmblem *emblem2 = G_EMBLEM (icon2); + + return emblem1->origin == emblem2->origin && + g_icon_equal (emblem1->icon, emblem2->icon); +} + +static gboolean +g_emblem_to_tokens (GIcon *icon, + GPtrArray *tokens, + gint *out_version) +{ + GEmblem *emblem = G_EMBLEM (icon); + char *s; + + /* GEmblem are encoded as + * + * + */ + + g_return_val_if_fail (out_version != NULL, FALSE); + + *out_version = 0; + + s = g_icon_to_string (emblem->icon); + if (s == NULL) + return FALSE; + + g_ptr_array_add (tokens, s); + + s = g_strdup_printf ("%d", emblem->origin); + g_ptr_array_add (tokens, s); + + return TRUE; +} + +static GIcon * +g_emblem_from_tokens (gchar **tokens, + gint num_tokens, + gint version, + GError **error) +{ + GEmblem *emblem; + GIcon *icon; + GEmblemOrigin origin; + + emblem = NULL; + + if (version != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Can’t handle version %d of GEmblem encoding"), + version); + return NULL; + } + + if (num_tokens != 2) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Malformed number of tokens (%d) in GEmblem encoding"), + num_tokens); + return NULL; + } + + icon = g_icon_new_for_string (tokens[0], error); + + if (icon == NULL) + return NULL; + + origin = atoi (tokens[1]); + + emblem = g_emblem_new_with_origin (icon, origin); + g_object_unref (icon); + + return G_ICON (emblem); +} + +static GVariant * +g_emblem_serialize (GIcon *icon) +{ + GEmblem *emblem = G_EMBLEM (icon); + GVariant *icon_data; + GEnumValue *origin; + GVariant *result; + + icon_data = g_icon_serialize (emblem->icon); + if (!icon_data) + return NULL; + + origin = g_enum_get_value (g_type_class_peek (G_TYPE_EMBLEM_ORIGIN), emblem->origin); + result = g_variant_new_parsed ("('emblem', <(%v, {'origin': <%s>})>)", + icon_data, origin ? origin->value_nick : "unknown"); + g_variant_unref (icon_data); + + return result; +} + +static void +g_emblem_iface_init (GIconIface *iface) +{ + iface->hash = g_emblem_hash; + iface->equal = g_emblem_equal; + iface->to_tokens = g_emblem_to_tokens; + iface->from_tokens = g_emblem_from_tokens; + iface->serialize = g_emblem_serialize; +} diff --git a/gio/gemblem.h b/gio/gemblem.h new file mode 100644 index 0000000..094f9cb --- /dev/null +++ b/gio/gemblem.h @@ -0,0 +1,61 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Clemens N. Buss + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ + +#ifndef __G_EMBLEM_H__ +#define __G_EMBLEM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_EMBLEM (g_emblem_get_type ()) +#define G_EMBLEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_EMBLEM, GEmblem)) +#define G_EMBLEM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_EMBLEM, GEmblemClass)) +#define G_IS_EMBLEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_EMBLEM)) +#define G_IS_EMBLEM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_EMBLEM)) +#define G_EMBLEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_EMBLEM, GEmblemClass)) + +/** + * GEmblem: + * + * An object for Emblems + */ +typedef struct _GEmblem GEmblem; +typedef struct _GEmblemClass GEmblemClass; + +GLIB_AVAILABLE_IN_ALL +GType g_emblem_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GEmblem *g_emblem_new (GIcon *icon); +GLIB_AVAILABLE_IN_ALL +GEmblem *g_emblem_new_with_origin (GIcon *icon, + GEmblemOrigin origin); +GLIB_AVAILABLE_IN_ALL +GIcon *g_emblem_get_icon (GEmblem *emblem); +GLIB_AVAILABLE_IN_ALL +GEmblemOrigin g_emblem_get_origin (GEmblem *emblem); + +G_END_DECLS + +#endif /* __G_EMBLEM_H__ */ diff --git a/gio/gemblemedicon.c b/gio/gemblemedicon.c new file mode 100644 index 0000000..46fb95f --- /dev/null +++ b/gio/gemblemedicon.c @@ -0,0 +1,467 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Matthias Clasen + * Clemens N. Buss + */ + +#include + +#include + +#include "gemblemedicon.h" +#include "glibintl.h" +#include "gioerror.h" + + +/** + * SECTION:gemblemedicon + * @short_description: Icon with emblems + * @include: gio/gio.h + * @see_also: #GIcon, #GLoadableIcon, #GThemedIcon, #GEmblem + * + * #GEmblemedIcon is an implementation of #GIcon that supports + * adding an emblem to an icon. Adding multiple emblems to an + * icon is ensured via g_emblemed_icon_add_emblem(). + * + * Note that #GEmblemedIcon allows no control over the position + * of the emblems. See also #GEmblem for more information. + **/ + +enum { + PROP_GICON = 1, + NUM_PROPERTIES +}; + +struct _GEmblemedIconPrivate { + GIcon *icon; + GList *emblems; +}; + +static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; + +static void g_emblemed_icon_icon_iface_init (GIconIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GEmblemedIcon, g_emblemed_icon, G_TYPE_OBJECT, + G_ADD_PRIVATE (GEmblemedIcon) + G_IMPLEMENT_INTERFACE (G_TYPE_ICON, + g_emblemed_icon_icon_iface_init)) + + +static void +g_emblemed_icon_finalize (GObject *object) +{ + GEmblemedIcon *emblemed; + + emblemed = G_EMBLEMED_ICON (object); + + g_clear_object (&emblemed->priv->icon); + g_list_free_full (emblemed->priv->emblems, g_object_unref); + + (*G_OBJECT_CLASS (g_emblemed_icon_parent_class)->finalize) (object); +} + +static void +g_emblemed_icon_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GEmblemedIcon *self = G_EMBLEMED_ICON (object); + + switch (property_id) + { + case PROP_GICON: + self->priv->icon = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +g_emblemed_icon_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GEmblemedIcon *self = G_EMBLEMED_ICON (object); + + switch (property_id) + { + case PROP_GICON: + g_value_set_object (value, self->priv->icon); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +g_emblemed_icon_class_init (GEmblemedIconClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_emblemed_icon_finalize; + gobject_class->set_property = g_emblemed_icon_set_property; + gobject_class->get_property = g_emblemed_icon_get_property; + + properties[PROP_GICON] = + g_param_spec_object ("gicon", + P_("The base GIcon"), + P_("The GIcon to attach emblems to"), + G_TYPE_ICON, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); +} + +static void +g_emblemed_icon_init (GEmblemedIcon *emblemed) +{ + emblemed->priv = g_emblemed_icon_get_instance_private (emblemed); +} + +/** + * g_emblemed_icon_new: + * @icon: a #GIcon + * @emblem: (nullable): a #GEmblem, or %NULL + * + * Creates a new emblemed icon for @icon with the emblem @emblem. + * + * Returns: (transfer full) (type GEmblemedIcon): a new #GIcon + * + * Since: 2.18 + **/ +GIcon * +g_emblemed_icon_new (GIcon *icon, + GEmblem *emblem) +{ + GEmblemedIcon *emblemed; + + g_return_val_if_fail (G_IS_ICON (icon), NULL); + g_return_val_if_fail (!G_IS_EMBLEM (icon), NULL); + + emblemed = G_EMBLEMED_ICON (g_object_new (G_TYPE_EMBLEMED_ICON, + "gicon", icon, + NULL)); + + if (emblem != NULL) + g_emblemed_icon_add_emblem (emblemed, emblem); + + return G_ICON (emblemed); +} + + +/** + * g_emblemed_icon_get_icon: + * @emblemed: a #GEmblemedIcon + * + * Gets the main icon for @emblemed. + * + * Returns: (transfer none): a #GIcon that is owned by @emblemed + * + * Since: 2.18 + **/ +GIcon * +g_emblemed_icon_get_icon (GEmblemedIcon *emblemed) +{ + g_return_val_if_fail (G_IS_EMBLEMED_ICON (emblemed), NULL); + + return emblemed->priv->icon; +} + +/** + * g_emblemed_icon_get_emblems: + * @emblemed: a #GEmblemedIcon + * + * Gets the list of emblems for the @icon. + * + * Returns: (element-type Gio.Emblem) (transfer none): a #GList of + * #GEmblems that is owned by @emblemed + * + * Since: 2.18 + **/ + +GList * +g_emblemed_icon_get_emblems (GEmblemedIcon *emblemed) +{ + g_return_val_if_fail (G_IS_EMBLEMED_ICON (emblemed), NULL); + + return emblemed->priv->emblems; +} + +/** + * g_emblemed_icon_clear_emblems: + * @emblemed: a #GEmblemedIcon + * + * Removes all the emblems from @icon. + * + * Since: 2.28 + **/ +void +g_emblemed_icon_clear_emblems (GEmblemedIcon *emblemed) +{ + g_return_if_fail (G_IS_EMBLEMED_ICON (emblemed)); + + if (emblemed->priv->emblems == NULL) + return; + + g_list_free_full (emblemed->priv->emblems, g_object_unref); + emblemed->priv->emblems = NULL; +} + +static gint +g_emblem_comp (GEmblem *a, + GEmblem *b) +{ + guint hash_a = g_icon_hash (G_ICON (a)); + guint hash_b = g_icon_hash (G_ICON (b)); + + if(hash_a < hash_b) + return -1; + + if(hash_a == hash_b) + return 0; + + return 1; +} + +/** + * g_emblemed_icon_add_emblem: + * @emblemed: a #GEmblemedIcon + * @emblem: a #GEmblem + * + * Adds @emblem to the #GList of #GEmblems. + * + * Since: 2.18 + **/ +void +g_emblemed_icon_add_emblem (GEmblemedIcon *emblemed, + GEmblem *emblem) +{ + g_return_if_fail (G_IS_EMBLEMED_ICON (emblemed)); + g_return_if_fail (G_IS_EMBLEM (emblem)); + + g_object_ref (emblem); + emblemed->priv->emblems = g_list_insert_sorted (emblemed->priv->emblems, emblem, + (GCompareFunc) g_emblem_comp); +} + +static guint +g_emblemed_icon_hash (GIcon *icon) +{ + GEmblemedIcon *emblemed = G_EMBLEMED_ICON (icon); + GList *list; + guint hash = g_icon_hash (emblemed->priv->icon); + + for (list = emblemed->priv->emblems; list != NULL; list = list->next) + hash ^= g_icon_hash (G_ICON (list->data)); + + return hash; +} + +static gboolean +g_emblemed_icon_equal (GIcon *icon1, + GIcon *icon2) +{ + GEmblemedIcon *emblemed1 = G_EMBLEMED_ICON (icon1); + GEmblemedIcon *emblemed2 = G_EMBLEMED_ICON (icon2); + GList *list1, *list2; + + if (!g_icon_equal (emblemed1->priv->icon, emblemed2->priv->icon)) + return FALSE; + + list1 = emblemed1->priv->emblems; + list2 = emblemed2->priv->emblems; + + while (list1 && list2) + { + if (!g_icon_equal (G_ICON (list1->data), G_ICON (list2->data))) + return FALSE; + + list1 = list1->next; + list2 = list2->next; + } + + return list1 == NULL && list2 == NULL; +} + +static gboolean +g_emblemed_icon_to_tokens (GIcon *icon, + GPtrArray *tokens, + gint *out_version) +{ + GEmblemedIcon *emblemed_icon = G_EMBLEMED_ICON (icon); + GList *l; + char *s; + + /* GEmblemedIcons are encoded as + * + * []* + */ + + g_return_val_if_fail (out_version != NULL, FALSE); + + *out_version = 0; + + s = g_icon_to_string (emblemed_icon->priv->icon); + if (s == NULL) + return FALSE; + + g_ptr_array_add (tokens, s); + + for (l = emblemed_icon->priv->emblems; l != NULL; l = l->next) + { + GIcon *emblem_icon = G_ICON (l->data); + + s = g_icon_to_string (emblem_icon); + if (s == NULL) + return FALSE; + + g_ptr_array_add (tokens, s); + } + + return TRUE; +} + +static GIcon * +g_emblemed_icon_from_tokens (gchar **tokens, + gint num_tokens, + gint version, + GError **error) +{ + GEmblemedIcon *emblemed_icon; + int n; + + emblemed_icon = NULL; + + if (version != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Can’t handle version %d of GEmblemedIcon encoding"), + version); + goto fail; + } + + if (num_tokens < 1) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Malformed number of tokens (%d) in GEmblemedIcon encoding"), + num_tokens); + goto fail; + } + + emblemed_icon = g_object_new (G_TYPE_EMBLEMED_ICON, NULL); + emblemed_icon->priv->icon = g_icon_new_for_string (tokens[0], error); + if (emblemed_icon->priv->icon == NULL) + goto fail; + + for (n = 1; n < num_tokens; n++) + { + GIcon *emblem; + + emblem = g_icon_new_for_string (tokens[n], error); + if (emblem == NULL) + goto fail; + + if (!G_IS_EMBLEM (emblem)) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Expected a GEmblem for GEmblemedIcon")); + g_object_unref (emblem); + goto fail; + } + + emblemed_icon->priv->emblems = g_list_append (emblemed_icon->priv->emblems, emblem); + } + + return G_ICON (emblemed_icon); + + fail: + if (emblemed_icon != NULL) + g_object_unref (emblemed_icon); + return NULL; +} + +static GVariant * +g_emblemed_icon_serialize (GIcon *icon) +{ + GEmblemedIcon *emblemed_icon = G_EMBLEMED_ICON (icon); + GVariantBuilder builder; + GVariant *icon_data; + GList *node; + + icon_data = g_icon_serialize (emblemed_icon->priv->icon); + if (!icon_data) + return NULL; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(va(va{sv}))")); + + g_variant_builder_add (&builder, "v", icon_data); + g_variant_unref (icon_data); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(va{sv})")); + for (node = emblemed_icon->priv->emblems; node != NULL; node = node->next) + { + icon_data = g_icon_serialize (node->data); + if (icon_data) + { + /* We know how emblems serialize, so do a tweak here to + * reduce some of the variant wrapping and redundant storage + * of 'emblem' over and again... + */ + if (g_variant_is_of_type (icon_data, G_VARIANT_TYPE ("(sv)"))) + { + const gchar *name; + GVariant *content; + + g_variant_get (icon_data, "(&sv)", &name, &content); + + if (g_str_equal (name, "emblem") && g_variant_is_of_type (content, G_VARIANT_TYPE ("(va{sv})"))) + g_variant_builder_add (&builder, "@(va{sv})", content); + + g_variant_unref (content); + } + + g_variant_unref (icon_data); + } + } + g_variant_builder_close (&builder); + + return g_variant_new ("(sv)", "emblemed", g_variant_builder_end (&builder)); +} + +static void +g_emblemed_icon_icon_iface_init (GIconIface *iface) +{ + iface->hash = g_emblemed_icon_hash; + iface->equal = g_emblemed_icon_equal; + iface->to_tokens = g_emblemed_icon_to_tokens; + iface->from_tokens = g_emblemed_icon_from_tokens; + iface->serialize = g_emblemed_icon_serialize; +} diff --git a/gio/gemblemedicon.h b/gio/gemblemedicon.h new file mode 100644 index 0000000..3374e0a --- /dev/null +++ b/gio/gemblemedicon.h @@ -0,0 +1,81 @@ +/* Gio - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Matthias Clasen + * Clemens N. Buss + */ + +#ifndef __G_EMBLEMED_ICON_H__ +#define __G_EMBLEMED_ICON_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_EMBLEMED_ICON (g_emblemed_icon_get_type ()) +#define G_EMBLEMED_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_EMBLEMED_ICON, GEmblemedIcon)) +#define G_EMBLEMED_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_EMBLEMED_ICON, GEmblemedIconClass)) +#define G_IS_EMBLEMED_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_EMBLEMED_ICON)) +#define G_IS_EMBLEMED_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_EMBLEMED_ICON)) +#define G_EMBLEMED_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_EMBLEMED_ICON, GEmblemedIconClass)) + +/** + * GEmblemedIcon: + * + * An implementation of #GIcon for icons with emblems. + **/ +typedef struct _GEmblemedIcon GEmblemedIcon; +typedef struct _GEmblemedIconClass GEmblemedIconClass; +typedef struct _GEmblemedIconPrivate GEmblemedIconPrivate; + +struct _GEmblemedIcon +{ + GObject parent_instance; + + /*< private >*/ + GEmblemedIconPrivate *priv; +}; + +struct _GEmblemedIconClass +{ + GObjectClass parent_class; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_emblemed_icon_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GIcon *g_emblemed_icon_new (GIcon *icon, + GEmblem *emblem); +GLIB_AVAILABLE_IN_ALL +GIcon *g_emblemed_icon_get_icon (GEmblemedIcon *emblemed); +GLIB_AVAILABLE_IN_ALL +GList *g_emblemed_icon_get_emblems (GEmblemedIcon *emblemed); +GLIB_AVAILABLE_IN_ALL +void g_emblemed_icon_add_emblem (GEmblemedIcon *emblemed, + GEmblem *emblem); +GLIB_AVAILABLE_IN_ALL +void g_emblemed_icon_clear_emblems (GEmblemedIcon *emblemed); + +G_END_DECLS + +#endif /* __G_EMBLEMED_ICON_H__ */ diff --git a/gio/gfdonotificationbackend.c b/gio/gfdonotificationbackend.c new file mode 100644 index 0000000..312ad1e --- /dev/null +++ b/gio/gfdonotificationbackend.c @@ -0,0 +1,513 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#include "config.h" + +#include "gnotificationbackend.h" + +#include "gapplication.h" +#include "giomodule-priv.h" +#include "gnotification-private.h" +#include "gdbusconnection.h" +#include "gdbusnamewatching.h" +#include "gactiongroup.h" +#include "gaction.h" +#include "gthemedicon.h" +#include "gfileicon.h" +#include "gfile.h" +#include "gdbusutils.h" + +#define G_TYPE_FDO_NOTIFICATION_BACKEND (g_fdo_notification_backend_get_type ()) +#define G_FDO_NOTIFICATION_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FDO_NOTIFICATION_BACKEND, GFdoNotificationBackend)) + +typedef struct _GFdoNotificationBackend GFdoNotificationBackend; +typedef GNotificationBackendClass GFdoNotificationBackendClass; + +struct _GFdoNotificationBackend +{ + GNotificationBackend parent; + + guint bus_name_id; + + guint notify_subscription; + GSList *notifications; +}; + +GType g_fdo_notification_backend_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (GFdoNotificationBackend, g_fdo_notification_backend, G_TYPE_NOTIFICATION_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "freedesktop", 0)) + +typedef struct +{ + GFdoNotificationBackend *backend; + gchar *id; + guint32 notify_id; + gchar *default_action; + GVariant *default_action_target; +} FreedesktopNotification; + +static void +freedesktop_notification_free (gpointer data) +{ + FreedesktopNotification *n = data; + + g_object_unref (n->backend); + g_free (n->id); + g_free (n->default_action); + if (n->default_action_target) + g_variant_unref (n->default_action_target); + + g_slice_free (FreedesktopNotification, n); +} + +static FreedesktopNotification * +freedesktop_notification_new (GFdoNotificationBackend *backend, + const gchar *id, + GNotification *notification) +{ + FreedesktopNotification *n; + + n = g_slice_new0 (FreedesktopNotification); + n->backend = g_object_ref (backend); + n->id = g_strdup (id); + n->notify_id = 0; + g_notification_get_default_action (notification, + &n->default_action, + &n->default_action_target); + + return n; +} + +static FreedesktopNotification * +g_fdo_notification_backend_find_notification (GFdoNotificationBackend *backend, + const gchar *id) +{ + GSList *it; + + for (it = backend->notifications; it != NULL; it = it->next) + { + FreedesktopNotification *n = it->data; + if (g_str_equal (n->id, id)) + return n; + } + + return NULL; +} + +static FreedesktopNotification * +g_fdo_notification_backend_find_notification_by_notify_id (GFdoNotificationBackend *backend, + guint32 id) +{ + GSList *it; + + for (it = backend->notifications; it != NULL; it = it->next) + { + FreedesktopNotification *n = it->data; + if (n->notify_id == id) + return n; + } + + return NULL; +} + +static void +activate_action (GFdoNotificationBackend *backend, + const gchar *name, + GVariant *parameter) +{ + GNotificationBackend *g_backend = G_NOTIFICATION_BACKEND (backend); + + if (name) + { + if (g_str_has_prefix (name, "app.")) + g_action_group_activate_action (G_ACTION_GROUP (g_backend->application), name + 4, parameter); + } + else + { + g_application_activate (g_backend->application); + } +} + +static void +notify_signal (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GFdoNotificationBackend *backend = user_data; + guint32 id = 0; + const gchar *action = NULL; + FreedesktopNotification *n; + + if (g_str_equal (signal_name, "NotificationClosed") && + g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)"))) + { + g_variant_get (parameters, "(uu)", &id, NULL); + } + else if (g_str_equal (signal_name, "ActionInvoked") && + g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) + { + g_variant_get (parameters, "(u&s)", &id, &action); + } + else + return; + + n = g_fdo_notification_backend_find_notification_by_notify_id (backend, id); + if (n == NULL) + return; + + if (action) + { + if (g_str_equal (action, "default")) + { + activate_action (backend, n->default_action, n->default_action_target); + } + else + { + gchar *name; + GVariant *target; + + if (g_action_parse_detailed_name (action, &name, &target, NULL)) + { + activate_action (backend, name, target); + g_free (name); + if (target) + g_variant_unref (target); + } + } + } + + /* Get the notification again in case the action redrew it */ + n = g_fdo_notification_backend_find_notification_by_notify_id (backend, id); + if (n != NULL) + { + backend->notifications = g_slist_remove (backend->notifications, n); + freedesktop_notification_free (n); + } +} + +static void +name_vanished_handler_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GFdoNotificationBackend *backend = user_data; + + if (backend->notifications) + { + g_slist_free_full (backend->notifications, freedesktop_notification_free); + backend->notifications = NULL; + } +} + +/* Converts a GNotificationPriority to an urgency level as defined by + * the freedesktop spec (0: low, 1: normal, 2: critical). + */ +static guchar +urgency_from_priority (GNotificationPriority priority) +{ + switch (priority) + { + case G_NOTIFICATION_PRIORITY_LOW: + return 0; + + default: + case G_NOTIFICATION_PRIORITY_NORMAL: + case G_NOTIFICATION_PRIORITY_HIGH: + return 1; + + case G_NOTIFICATION_PRIORITY_URGENT: + return 2; + } +} + +static void +call_notify (GDBusConnection *con, + GApplication *app, + guint32 replace_id, + GNotification *notification, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVariantBuilder action_builder; + guint n_buttons; + guint i; + GVariantBuilder hints_builder; + GIcon *icon; + GVariant *parameters; + const gchar *app_name; + const gchar *body; + guchar urgency; + + g_variant_builder_init (&action_builder, G_VARIANT_TYPE_STRING_ARRAY); + if (g_notification_get_default_action (notification, NULL, NULL)) + { + g_variant_builder_add (&action_builder, "s", "default"); + g_variant_builder_add (&action_builder, "s", ""); + } + + n_buttons = g_notification_get_n_buttons (notification); + for (i = 0; i < n_buttons; i++) + { + gchar *label; + gchar *action; + GVariant *target; + gchar *detailed_name; + + g_notification_get_button (notification, i, &label, &action, &target); + detailed_name = g_action_print_detailed_name (action, target); + + /* Actions named 'default' collide with libnotify's naming of the + * default action. Rewriting them to something unique is enough, + * because those actions can never be activated (they aren't + * prefixed with 'app.'). + */ + if (g_str_equal (detailed_name, "default")) + { + g_free (detailed_name); + detailed_name = g_dbus_generate_guid (); + } + + g_variant_builder_add_value (&action_builder, g_variant_new_take_string (detailed_name)); + g_variant_builder_add_value (&action_builder, g_variant_new_take_string (label)); + + g_free (action); + if (target) + g_variant_unref (target); + } + + g_variant_builder_init (&hints_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&hints_builder, "{sv}", "desktop-entry", + g_variant_new_string (g_application_get_application_id (app))); + urgency = urgency_from_priority (g_notification_get_priority (notification)); + g_variant_builder_add (&hints_builder, "{sv}", "urgency", g_variant_new_byte (urgency)); + if (g_notification_get_category (notification)) + { + g_variant_builder_add (&hints_builder, "{sv}", "category", + g_variant_new_string (g_notification_get_category (notification))); + } + + icon = g_notification_get_icon (notification); + if (icon != NULL) + { + if (G_IS_FILE_ICON (icon)) + { + GFile *file; + + file = g_file_icon_get_file (G_FILE_ICON (icon)); + g_variant_builder_add (&hints_builder, "{sv}", "image-path", + g_variant_new_take_string (g_file_get_path (file))); + } + else if (G_IS_THEMED_ICON (icon)) + { + const gchar* const* icon_names = g_themed_icon_get_names(G_THEMED_ICON (icon)); + /* Take first name from GThemedIcon */ + g_variant_builder_add (&hints_builder, "{sv}", "image-path", + g_variant_new_string (icon_names[0])); + } + } + + app_name = g_get_application_name (); + body = g_notification_get_body (notification); + + parameters = g_variant_new ("(susssasa{sv}i)", + app_name ? app_name : "", + replace_id, + "", /* app icon */ + g_notification_get_title (notification), + body ? body : "", + &action_builder, + &hints_builder, + -1); /* expire_timeout */ + + g_dbus_connection_call (con, "org.freedesktop.Notifications", "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", "Notify", + parameters, G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, + callback, user_data); +} + +static void +notification_sent (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + FreedesktopNotification *n = user_data; + GVariant *val; + GError *error = NULL; + static gboolean warning_printed = FALSE; + + val = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), result, &error); + if (val) + { + GFdoNotificationBackend *backend = n->backend; + FreedesktopNotification *match; + + g_variant_get (val, "(u)", &n->notify_id); + g_variant_unref (val); + + match = g_fdo_notification_backend_find_notification_by_notify_id (backend, n->notify_id); + if (match != NULL) + { + backend->notifications = g_slist_remove (backend->notifications, match); + freedesktop_notification_free (match); + } + backend->notifications = g_slist_prepend (backend->notifications, n); + } + else + { + if (!warning_printed) + { + g_warning ("unable to send notifications through org.freedesktop.Notifications: %s", + error->message); + warning_printed = TRUE; + } + + freedesktop_notification_free (n); + g_error_free (error); + } +} + +static void +g_fdo_notification_backend_dispose (GObject *object) +{ + GFdoNotificationBackend *backend = G_FDO_NOTIFICATION_BACKEND (object); + + if (backend->bus_name_id) + { + g_bus_unwatch_name (backend->bus_name_id); + backend->bus_name_id = 0; + } + + if (backend->notify_subscription) + { + GDBusConnection *session_bus; + + session_bus = G_NOTIFICATION_BACKEND (backend)->dbus_connection; + g_dbus_connection_signal_unsubscribe (session_bus, backend->notify_subscription); + backend->notify_subscription = 0; + } + + if (backend->notifications) + { + g_slist_free_full (backend->notifications, freedesktop_notification_free); + backend->notifications = NULL; + } + + G_OBJECT_CLASS (g_fdo_notification_backend_parent_class)->dispose (object); +} + +static gboolean +g_fdo_notification_backend_is_supported (void) +{ + /* This is the fallback backend with the lowest priority. To avoid an + * unnecessary synchronous dbus call to check for + * org.freedesktop.Notifications, this function always succeeds. A + * warning will be printed when sending the first notification fails. + */ + return TRUE; +} + +static void +g_fdo_notification_backend_send_notification (GNotificationBackend *backend, + const gchar *id, + GNotification *notification) +{ + GFdoNotificationBackend *self = G_FDO_NOTIFICATION_BACKEND (backend); + FreedesktopNotification *n, *tmp; + + if (self->bus_name_id == 0) + { + self->bus_name_id = g_bus_watch_name_on_connection (backend->dbus_connection, + "org.freedesktop.Notifications", + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, + name_vanished_handler_cb, + backend, + NULL); + } + + if (self->notify_subscription == 0) + { + self->notify_subscription = + g_dbus_connection_signal_subscribe (backend->dbus_connection, + "org.freedesktop.Notifications", + "org.freedesktop.Notifications", NULL, + "/org/freedesktop/Notifications", NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + notify_signal, backend, NULL); + } + + n = freedesktop_notification_new (self, id, notification); + + tmp = g_fdo_notification_backend_find_notification (self, id); + if (tmp) + n->notify_id = tmp->notify_id; + + call_notify (backend->dbus_connection, backend->application, n->notify_id, notification, notification_sent, n); +} + +static void +g_fdo_notification_backend_withdraw_notification (GNotificationBackend *backend, + const gchar *id) +{ + GFdoNotificationBackend *self = G_FDO_NOTIFICATION_BACKEND (backend); + FreedesktopNotification *n; + + n = g_fdo_notification_backend_find_notification (self, id); + if (n) + { + if (n->notify_id > 0) + { + g_dbus_connection_call (backend->dbus_connection, + "org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", "CloseNotification", + g_variant_new ("(u)", n->notify_id), NULL, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + + self->notifications = g_slist_remove (self->notifications, n); + freedesktop_notification_free (n); + } +} + +static void +g_fdo_notification_backend_init (GFdoNotificationBackend *backend) +{ +} + +static void +g_fdo_notification_backend_class_init (GFdoNotificationBackendClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GNotificationBackendClass *backend_class = G_NOTIFICATION_BACKEND_CLASS (class); + + object_class->dispose = g_fdo_notification_backend_dispose; + + backend_class->is_supported = g_fdo_notification_backend_is_supported; + backend_class->send_notification = g_fdo_notification_backend_send_notification; + backend_class->withdraw_notification = g_fdo_notification_backend_withdraw_notification; +} diff --git a/gio/gfile.c b/gio/gfile.c new file mode 100644 index 0000000..1810e36 --- /dev/null +++ b/gio/gfile.c @@ -0,0 +1,8804 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#ifdef __linux__ +#include +#include +/* See linux.git/fs/btrfs/ioctl.h */ +#define BTRFS_IOCTL_MAGIC 0x94 +#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int) +#endif + +#ifdef HAVE_SPLICE +#include +#include +#include +#include + +/* + * We duplicate the following Linux kernel header defines here so we can still + * run at full speed on modern kernels in cases where an old toolchain was used + * to build GLib. This is often done deliberately to allow shipping binaries + * that need to run on a wide range of systems. + */ +#ifndef F_SETPIPE_SZ +#define F_SETPIPE_SZ 1031 +#endif +#ifndef F_GETPIPE_SZ +#define F_GETPIPE_SZ 1032 +#endif + +#endif + +#include +#include + +#include "gfile.h" +#include "glib/gstdio.h" +#ifdef G_OS_UNIX +#include "glib-unix.h" +#endif +#include "gvfs.h" +#include "gtask.h" +#include "gfileattribute-priv.h" +#include "gfiledescriptorbased.h" +#include "gpollfilemonitor.h" +#include "gappinfo.h" +#include "gfileinputstream.h" +#include "gfileoutputstream.h" +#include "glocalfileoutputstream.h" +#include "glocalfileiostream.h" +#include "glocalfile.h" +#include "gcancellable.h" +#include "gasyncresult.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gfile + * @short_description: File and Directory Handling + * @include: gio/gio.h + * @see_also: #GFileInfo, #GFileEnumerator + * + * #GFile is a high level abstraction for manipulating files on a + * virtual file system. #GFiles are lightweight, immutable objects + * that do no I/O upon creation. It is necessary to understand that + * #GFile objects do not represent files, merely an identifier for a + * file. All file content I/O is implemented as streaming operations + * (see #GInputStream and #GOutputStream). + * + * To construct a #GFile, you can use: + * - g_file_new_for_path() if you have a path. + * - g_file_new_for_uri() if you have a URI. + * - g_file_new_for_commandline_arg() for a command line argument. + * - g_file_new_tmp() to create a temporary file from a template. + * - g_file_parse_name() from a UTF-8 string gotten from g_file_get_parse_name(). + * - g_file_new_build_filename() to create a file from path elements. + * + * One way to think of a #GFile is as an abstraction of a pathname. For + * normal files the system pathname is what is stored internally, but as + * #GFiles are extensible it could also be something else that corresponds + * to a pathname in a userspace implementation of a filesystem. + * + * #GFiles make up hierarchies of directories and files that correspond to + * the files on a filesystem. You can move through the file system with + * #GFile using g_file_get_parent() to get an identifier for the parent + * directory, g_file_get_child() to get a child within a directory, + * g_file_resolve_relative_path() to resolve a relative path between two + * #GFiles. There can be multiple hierarchies, so you may not end up at + * the same root if you repeatedly call g_file_get_parent() on two different + * files. + * + * All #GFiles have a basename (get with g_file_get_basename()). These names + * are byte strings that are used to identify the file on the filesystem + * (relative to its parent directory) and there is no guarantees that they + * have any particular charset encoding or even make any sense at all. If + * you want to use filenames in a user interface you should use the display + * name that you can get by requesting the + * %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME attribute with g_file_query_info(). + * This is guaranteed to be in UTF-8 and can be used in a user interface. + * But always store the real basename or the #GFile to use to actually + * access the file, because there is no way to go from a display name to + * the actual name. + * + * Using #GFile as an identifier has the same weaknesses as using a path + * in that there may be multiple aliases for the same file. For instance, + * hard or soft links may cause two different #GFiles to refer to the same + * file. Other possible causes for aliases are: case insensitive filesystems, + * short and long names on FAT/NTFS, or bind mounts in Linux. If you want to + * check if two #GFiles point to the same file you can query for the + * %G_FILE_ATTRIBUTE_ID_FILE attribute. Note that #GFile does some trivial + * canonicalization of pathnames passed in, so that trivial differences in + * the path string used at creation (duplicated slashes, slash at end of + * path, "." or ".." path segments, etc) does not create different #GFiles. + * + * Many #GFile operations have both synchronous and asynchronous versions + * to suit your application. Asynchronous versions of synchronous functions + * simply have _async() appended to their function names. The asynchronous + * I/O functions call a #GAsyncReadyCallback which is then used to finalize + * the operation, producing a GAsyncResult which is then passed to the + * function's matching _finish() operation. + * + * It is highly recommended to use asynchronous calls when running within a + * shared main loop, such as in the main thread of an application. This avoids + * I/O operations blocking other sources on the main loop from being dispatched. + * Synchronous I/O operations should be performed from worker threads. See the + * [introduction to asynchronous programming section][async-programming] for + * more. + * + * Some #GFile operations almost always take a noticeable amount of time, and + * so do not have synchronous analogs. Notable cases include: + * - g_file_mount_mountable() to mount a mountable file. + * - g_file_unmount_mountable_with_operation() to unmount a mountable file. + * - g_file_eject_mountable_with_operation() to eject a mountable file. + * + * ## Entity Tags # {#gfile-etag} + * + * One notable feature of #GFiles are entity tags, or "etags" for + * short. Entity tags are somewhat like a more abstract version of the + * traditional mtime, and can be used to quickly determine if the file + * has been modified from the version on the file system. See the + * HTTP 1.1 + * [specification](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) + * for HTTP Etag headers, which are a very similar concept. + */ + +static void g_file_real_query_info_async (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileInfo * g_file_real_query_info_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_query_filesystem_info_async (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileInfo * g_file_real_query_filesystem_info_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_enumerate_children_async (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileEnumerator * g_file_real_enumerate_children_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_read_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileInputStream * g_file_real_read_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_append_to_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileOutputStream *g_file_real_append_to_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_create_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileOutputStream *g_file_real_create_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_replace_async (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileOutputStream *g_file_real_replace_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_delete_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_file_real_delete_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_trash_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_file_real_trash_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_move_async (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_file_real_move_finish (GFile *file, + GAsyncResult *result, + GError **error); +static void g_file_real_make_directory_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_file_real_make_directory_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_open_readwrite_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileIOStream * g_file_real_open_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_create_readwrite_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileIOStream * g_file_real_create_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_replace_readwrite_async (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileIOStream * g_file_real_replace_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error); +static gboolean g_file_real_set_attributes_from_info (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +static void g_file_real_set_display_name_async (GFile *file, + const char *display_name, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFile * g_file_real_set_display_name_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_set_attributes_async (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_file_real_set_attributes_finish (GFile *file, + GAsyncResult *res, + GFileInfo **info, + GError **error); +static void g_file_real_find_enclosing_mount_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GMount * g_file_real_find_enclosing_mount_finish (GFile *file, + GAsyncResult *res, + GError **error); +static void g_file_real_copy_async (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_file_real_copy_finish (GFile *file, + GAsyncResult *res, + GError **error); + +static gboolean g_file_real_measure_disk_usage (GFile *file, + GFileMeasureFlags flags, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error); +static void g_file_real_measure_disk_usage_async (GFile *file, + GFileMeasureFlags flags, + gint io_priority, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_file_real_measure_disk_usage_finish (GFile *file, + GAsyncResult *result, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error); + +typedef GFileIface GFileInterface; +G_DEFINE_INTERFACE (GFile, g_file, G_TYPE_OBJECT) + +static void +g_file_default_init (GFileIface *iface) +{ + iface->enumerate_children_async = g_file_real_enumerate_children_async; + iface->enumerate_children_finish = g_file_real_enumerate_children_finish; + iface->set_display_name_async = g_file_real_set_display_name_async; + iface->set_display_name_finish = g_file_real_set_display_name_finish; + iface->query_info_async = g_file_real_query_info_async; + iface->query_info_finish = g_file_real_query_info_finish; + iface->query_filesystem_info_async = g_file_real_query_filesystem_info_async; + iface->query_filesystem_info_finish = g_file_real_query_filesystem_info_finish; + iface->set_attributes_async = g_file_real_set_attributes_async; + iface->set_attributes_finish = g_file_real_set_attributes_finish; + iface->read_async = g_file_real_read_async; + iface->read_finish = g_file_real_read_finish; + iface->append_to_async = g_file_real_append_to_async; + iface->append_to_finish = g_file_real_append_to_finish; + iface->create_async = g_file_real_create_async; + iface->create_finish = g_file_real_create_finish; + iface->replace_async = g_file_real_replace_async; + iface->replace_finish = g_file_real_replace_finish; + iface->delete_file_async = g_file_real_delete_async; + iface->delete_file_finish = g_file_real_delete_finish; + iface->trash_async = g_file_real_trash_async; + iface->trash_finish = g_file_real_trash_finish; + iface->move_async = g_file_real_move_async; + iface->move_finish = g_file_real_move_finish; + iface->make_directory_async = g_file_real_make_directory_async; + iface->make_directory_finish = g_file_real_make_directory_finish; + iface->open_readwrite_async = g_file_real_open_readwrite_async; + iface->open_readwrite_finish = g_file_real_open_readwrite_finish; + iface->create_readwrite_async = g_file_real_create_readwrite_async; + iface->create_readwrite_finish = g_file_real_create_readwrite_finish; + iface->replace_readwrite_async = g_file_real_replace_readwrite_async; + iface->replace_readwrite_finish = g_file_real_replace_readwrite_finish; + iface->find_enclosing_mount_async = g_file_real_find_enclosing_mount_async; + iface->find_enclosing_mount_finish = g_file_real_find_enclosing_mount_finish; + iface->set_attributes_from_info = g_file_real_set_attributes_from_info; + iface->copy_async = g_file_real_copy_async; + iface->copy_finish = g_file_real_copy_finish; + iface->measure_disk_usage = g_file_real_measure_disk_usage; + iface->measure_disk_usage_async = g_file_real_measure_disk_usage_async; + iface->measure_disk_usage_finish = g_file_real_measure_disk_usage_finish; +} + + +/** + * g_file_is_native: + * @file: input #GFile + * + * Checks to see if a file is native to the platform. + * + * A native file is one expressed in the platform-native filename format, + * e.g. "C:\Windows" or "/usr/bin/". This does not mean the file is local, + * as it might be on a locally mounted remote filesystem. + * + * On some systems non-native files may be available using the native + * filesystem via a userspace filesystem (FUSE), in these cases this call + * will return %FALSE, but g_file_get_path() will still return a native path. + * + * This call does no blocking I/O. + * + * Returns: %TRUE if @file is native + */ +gboolean +g_file_is_native (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->is_native) (file); +} + + +/** + * g_file_has_uri_scheme: + * @file: input #GFile + * @uri_scheme: a string containing a URI scheme + * + * Checks to see if a #GFile has a given URI scheme. + * + * This call does no blocking I/O. + * + * Returns: %TRUE if #GFile's backend supports the + * given URI scheme, %FALSE if URI scheme is %NULL, + * not supported, or #GFile is invalid. + */ +gboolean +g_file_has_uri_scheme (GFile *file, + const char *uri_scheme) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (uri_scheme != NULL, FALSE); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->has_uri_scheme) (file, uri_scheme); +} + + +/** + * g_file_get_uri_scheme: + * @file: input #GFile + * + * Gets the URI scheme for a #GFile. + * RFC 3986 decodes the scheme as: + * |[ + * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + * ]| + * Common schemes include "file", "http", "ftp", etc. + * + * The scheme can be different from the one used to construct the #GFile, + * in that it might be replaced with one that is logically equivalent to the #GFile. + * + * This call does no blocking I/O. + * + * Returns: (nullable): a string containing the URI scheme for the given + * #GFile or %NULL if the #GFile was constructed with an invalid URI. The + * returned string should be freed with g_free() when no longer needed. + */ +char * +g_file_get_uri_scheme (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->get_uri_scheme) (file); +} + + +/** + * g_file_get_basename: (virtual get_basename) + * @file: input #GFile + * + * Gets the base name (the last component of the path) for a given #GFile. + * + * If called for the top level of a system (such as the filesystem root + * or a uri like sftp://host/) it will return a single directory separator + * (and on Windows, possibly a drive letter). + * + * The base name is a byte string (not UTF-8). It has no defined encoding + * or rules other than it may not contain zero bytes. If you want to use + * filenames in a user interface you should use the display name that you + * can get by requesting the %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME + * attribute with g_file_query_info(). + * + * This call does no blocking I/O. + * + * Returns: (type filename) (nullable): string containing the #GFile's + * base name, or %NULL if given #GFile is invalid. The returned string + * should be freed with g_free() when no longer needed. + */ +char * +g_file_get_basename (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->get_basename) (file); +} + +/** + * g_file_get_path: (virtual get_path) + * @file: input #GFile + * + * Gets the local pathname for #GFile, if one exists. If non-%NULL, this is + * guaranteed to be an absolute, canonical path. It might contain symlinks. + * + * This call does no blocking I/O. + * + * Returns: (type filename) (nullable): string containing the #GFile's path, + * or %NULL if no such path exists. The returned string should be freed + * with g_free() when no longer needed. + */ +char * +g_file_get_path (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->get_path) (file); +} + +static const char * +file_peek_path_generic (GFile *file) +{ + const char *path; + static GQuark _file_path_quark = 0; + + if (G_UNLIKELY (_file_path_quark) == 0) + _file_path_quark = g_quark_from_static_string ("gio-file-path"); + + /* We need to be careful about threading, as two threads calling + * g_file_peek_path() on the same file could race: both would see + * (g_object_get_qdata(…) == NULL) to begin with, both would generate and add + * the path, but the second thread to add it would end up freeing the path + * set by the first thread. The first thread would still return the pointer + * to that freed path, though, resulting an a read-after-free. Handle that + * with a compare-and-swap loop. The g_object_*_qdata() functions are atomic. */ + + while (TRUE) + { + gchar *new_path = NULL; + + path = g_object_get_qdata ((GObject*)file, _file_path_quark); + + if (path != NULL) + break; + + new_path = g_file_get_path (file); + if (new_path == NULL) + return NULL; + + /* By passing NULL here, we ensure we never replace existing data: */ + if (g_object_replace_qdata ((GObject *) file, _file_path_quark, + NULL, (gpointer) new_path, + (GDestroyNotify) g_free, NULL)) + { + path = new_path; + break; + } + else + g_free (new_path); + } + + return path; +} + +/** + * g_file_peek_path: + * @file: input #GFile + * + * Exactly like g_file_get_path(), but caches the result via + * g_object_set_qdata_full(). This is useful for example in C + * applications which mix `g_file_*` APIs with native ones. It + * also avoids an extra duplicated string when possible, so will be + * generally more efficient. + * + * This call does no blocking I/O. + * + * Returns: (type filename) (nullable): string containing the #GFile's path, + * or %NULL if no such path exists. The returned string is owned by @file. + * Since: 2.56 + */ +const char * +g_file_peek_path (GFile *file) +{ + if (G_IS_LOCAL_FILE (file)) + return _g_local_file_get_filename ((GLocalFile *) file); + return file_peek_path_generic (file); +} + +/** + * g_file_get_uri: + * @file: input #GFile + * + * Gets the URI for the @file. + * + * This call does no blocking I/O. + * + * Returns: a string containing the #GFile's URI. If the #GFile was constructed + * with an invalid URI, an invalid URI is returned. + * The returned string should be freed with g_free() + * when no longer needed. + */ +char * +g_file_get_uri (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->get_uri) (file); +} + +/** + * g_file_get_parse_name: + * @file: input #GFile + * + * Gets the parse name of the @file. + * A parse name is a UTF-8 string that describes the + * file such that one can get the #GFile back using + * g_file_parse_name(). + * + * This is generally used to show the #GFile as a nice + * full-pathname kind of string in a user interface, + * like in a location entry. + * + * For local files with names that can safely be converted + * to UTF-8 the pathname is used, otherwise the IRI is used + * (a form of URI that allows UTF-8 characters unescaped). + * + * This call does no blocking I/O. + * + * Returns: a string containing the #GFile's parse name. + * The returned string should be freed with g_free() + * when no longer needed. + */ +char * +g_file_get_parse_name (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->get_parse_name) (file); +} + +/** + * g_file_dup: + * @file: input #GFile + * + * Duplicates a #GFile handle. This operation does not duplicate + * the actual file or directory represented by the #GFile; see + * g_file_copy() if attempting to copy a file. + * + * g_file_dup() is useful when a second handle is needed to the same underlying + * file, for use in a separate thread (#GFile is not thread-safe). For use + * within the same thread, use g_object_ref() to increment the existing object’s + * reference count. + * + * This call does no blocking I/O. + * + * Returns: (transfer full): a new #GFile that is a duplicate + * of the given #GFile. + */ +GFile * +g_file_dup (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->dup) (file); +} + +/** + * g_file_hash: + * @file: (type GFile): #gconstpointer to a #GFile + * + * Creates a hash value for a #GFile. + * + * This call does no blocking I/O. + * + * Virtual: hash + * Returns: 0 if @file is not a valid #GFile, otherwise an + * integer that can be used as hash value for the #GFile. + * This function is intended for easily hashing a #GFile to + * add to a #GHashTable or similar data structure. + */ +guint +g_file_hash (gconstpointer file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), 0); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->hash) ((GFile *)file); +} + +/** + * g_file_equal: + * @file1: the first #GFile + * @file2: the second #GFile + * + * Checks if the two given #GFiles refer to the same file. + * + * Note that two #GFiles that differ can still refer to the same + * file on the filesystem due to various forms of filename + * aliasing. + * + * This call does no blocking I/O. + * + * Returns: %TRUE if @file1 and @file2 are equal. + */ +gboolean +g_file_equal (GFile *file1, + GFile *file2) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file1), FALSE); + g_return_val_if_fail (G_IS_FILE (file2), FALSE); + + if (file1 == file2) + return TRUE; + + if (G_TYPE_FROM_INSTANCE (file1) != G_TYPE_FROM_INSTANCE (file2)) + return FALSE; + + iface = G_FILE_GET_IFACE (file1); + + return (* iface->equal) (file1, file2); +} + + +/** + * g_file_get_parent: + * @file: input #GFile + * + * Gets the parent directory for the @file. + * If the @file represents the root directory of the + * file system, then %NULL will be returned. + * + * This call does no blocking I/O. + * + * Returns: (nullable) (transfer full): a #GFile structure to the + * parent of the given #GFile or %NULL if there is no parent. Free + * the returned object with g_object_unref(). + */ +GFile * +g_file_get_parent (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->get_parent) (file); +} + +/** + * g_file_has_parent: + * @file: input #GFile + * @parent: (nullable): the parent to check for, or %NULL + * + * Checks if @file has a parent, and optionally, if it is @parent. + * + * If @parent is %NULL then this function returns %TRUE if @file has any + * parent at all. If @parent is non-%NULL then %TRUE is only returned + * if @file is an immediate child of @parent. + * + * Returns: %TRUE if @file is an immediate child of @parent (or any parent in + * the case that @parent is %NULL). + * + * Since: 2.24 + */ +gboolean +g_file_has_parent (GFile *file, + GFile *parent) +{ + GFile *actual_parent; + gboolean result; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (parent == NULL || G_IS_FILE (parent), FALSE); + + actual_parent = g_file_get_parent (file); + + if (actual_parent != NULL) + { + if (parent != NULL) + result = g_file_equal (parent, actual_parent); + else + result = TRUE; + + g_object_unref (actual_parent); + } + else + result = FALSE; + + return result; +} + +/** + * g_file_get_child: + * @file: input #GFile + * @name: (type filename): string containing the child's basename + * + * Gets a child of @file with basename equal to @name. + * + * Note that the file with that specific name might not exist, but + * you can still have a #GFile that points to it. You can use this + * for instance to create that file. + * + * This call does no blocking I/O. + * + * Returns: (transfer full): a #GFile to a child specified by @name. + * Free the returned object with g_object_unref(). + */ +GFile * +g_file_get_child (GFile *file, + const char *name) +{ + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (!g_path_is_absolute (name), NULL); + + return g_file_resolve_relative_path (file, name); +} + +/** + * g_file_get_child_for_display_name: + * @file: input #GFile + * @display_name: string to a possible child + * @error: return location for an error + * + * Gets the child of @file for a given @display_name (i.e. a UTF-8 + * version of the name). If this function fails, it returns %NULL + * and @error will be set. This is very useful when constructing a + * #GFile for a new file and the user entered the filename in the + * user interface, for instance when you select a directory and + * type a filename in the file selector. + * + * This call does no blocking I/O. + * + * Returns: (transfer full): a #GFile to the specified child, or + * %NULL if the display name couldn't be converted. + * Free the returned object with g_object_unref(). + */ +GFile * +g_file_get_child_for_display_name (GFile *file, + const char *display_name, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (display_name != NULL, NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->get_child_for_display_name) (file, display_name, error); +} + +/** + * g_file_has_prefix: + * @file: input #GFile + * @prefix: input #GFile + * + * Checks whether @file has the prefix specified by @prefix. + * + * In other words, if the names of initial elements of @file's + * pathname match @prefix. Only full pathname elements are matched, + * so a path like /foo is not considered a prefix of /foobar, only + * of /foo/bar. + * + * A #GFile is not a prefix of itself. If you want to check for + * equality, use g_file_equal(). + * + * This call does no I/O, as it works purely on names. As such it can + * sometimes return %FALSE even if @file is inside a @prefix (from a + * filesystem point of view), because the prefix of @file is an alias + * of @prefix. + * + * Virtual: prefix_matches + * Returns: %TRUE if the @file's parent, grandparent, etc is @prefix, + * %FALSE otherwise. + */ +gboolean +g_file_has_prefix (GFile *file, + GFile *prefix) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_FILE (prefix), FALSE); + + if (G_TYPE_FROM_INSTANCE (file) != G_TYPE_FROM_INSTANCE (prefix)) + return FALSE; + + iface = G_FILE_GET_IFACE (file); + + /* The vtable function differs in arg order since + * we're using the old contains_file call + */ + return (* iface->prefix_matches) (prefix, file); +} + +/** + * g_file_get_relative_path: (virtual get_relative_path) + * @parent: input #GFile + * @descendant: input #GFile + * + * Gets the path for @descendant relative to @parent. + * + * This call does no blocking I/O. + * + * Returns: (type filename) (nullable): string with the relative path from + * @descendant to @parent, or %NULL if @descendant doesn't have @parent as + * prefix. The returned string should be freed with g_free() when + * no longer needed. + */ +char * +g_file_get_relative_path (GFile *parent, + GFile *descendant) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (parent), NULL); + g_return_val_if_fail (G_IS_FILE (descendant), NULL); + + if (G_TYPE_FROM_INSTANCE (parent) != G_TYPE_FROM_INSTANCE (descendant)) + return NULL; + + iface = G_FILE_GET_IFACE (parent); + + return (* iface->get_relative_path) (parent, descendant); +} + +/** + * g_file_resolve_relative_path: + * @file: input #GFile + * @relative_path: (type filename): a given relative path string + * + * Resolves a relative path for @file to an absolute path. + * + * This call does no blocking I/O. + * + * If the @relative_path is an absolute path name, the resolution + * is done absolutely (without taking @file path as base). + * + * Returns: (transfer full): a #GFile for the resolved path. + */ +GFile * +g_file_resolve_relative_path (GFile *file, + const char *relative_path) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (relative_path != NULL, NULL); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->resolve_relative_path) (file, relative_path); +} + +/** + * g_file_enumerate_children: + * @file: input #GFile + * @attributes: an attribute query string + * @flags: a set of #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: #GError for error reporting + * + * Gets the requested information about the files in a directory. + * The result is a #GFileEnumerator object that will give out + * #GFileInfo objects for all the files in the directory. + * + * The @attributes value is a string that specifies the file + * attributes that should be gathered. It is not an error if + * it's not possible to read a particular requested attribute + * from a file - it just won't be set. @attributes should + * be a comma-separated list of attributes or attribute wildcards. + * The wildcard "*" means all attributes, and a wildcard like + * "standard::*" means all attributes in the standard namespace. + * An example attribute query be "standard::*,owner::user". + * The standard attributes are available as defines, like + * %G_FILE_ATTRIBUTE_STANDARD_NAME. %G_FILE_ATTRIBUTE_STANDARD_NAME should + * always be specified if you plan to call g_file_enumerator_get_child() or + * g_file_enumerator_iterate() on the returned enumerator. + * + * If @cancellable is not %NULL, then the operation can be cancelled + * by triggering the cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be + * returned. + * + * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will + * be returned. If the file is not a directory, the %G_IO_ERROR_NOT_DIRECTORY + * error will be returned. Other errors are possible too. + * + * Returns: (transfer full): A #GFileEnumerator if successful, + * %NULL on error. Free the returned object with g_object_unref(). + */ +GFileEnumerator * +g_file_enumerate_children (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->enumerate_children == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->enumerate_children) (file, attributes, flags, + cancellable, error); +} + +/** + * g_file_enumerate_children_async: + * @file: input #GFile + * @attributes: an attribute query string + * @flags: a set of #GFileQueryInfoFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the + * request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously gets the requested information about the files + * in a directory. The result is a #GFileEnumerator object that will + * give out #GFileInfo objects for all the files in the directory. + * + * For more details, see g_file_enumerate_children() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. You can + * then call g_file_enumerate_children_finish() to get the result of + * the operation. + */ +void +g_file_enumerate_children_async (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->enumerate_children_async) (file, + attributes, + flags, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_enumerate_children_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError + * + * Finishes an async enumerate children operation. + * See g_file_enumerate_children_async(). + * + * Returns: (transfer full): a #GFileEnumerator or %NULL + * if an error occurred. + * Free the returned object with g_object_unref(). + */ +GFileEnumerator * +g_file_enumerate_children_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->enumerate_children_finish) (file, res, error); +} + +/** + * g_file_query_exists: + * @file: input #GFile + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * + * Utility function to check if a particular file exists. This is + * implemented using g_file_query_info() and as such does blocking I/O. + * + * Note that in many cases it is [racy to first check for file existence](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use) + * and then execute something based on the outcome of that, because the + * file might have been created or removed in between the operations. The + * general approach to handling that is to not check, but just do the + * operation and handle the errors as they come. + * + * As an example of race-free checking, take the case of reading a file, + * and if it doesn't exist, creating it. There are two racy versions: read + * it, and on error create it; and: check if it exists, if not create it. + * These can both result in two processes creating the file (with perhaps + * a partially written file as the result). The correct approach is to + * always try to create the file with g_file_create() which will either + * atomically create the file or fail with a %G_IO_ERROR_EXISTS error. + * + * However, in many cases an existence check is useful in a user interface, + * for instance to make a menu item sensitive/insensitive, so that you don't + * have to fool users that something is possible and then just show an error + * dialog. If you do this, you should make sure to also handle the errors + * that can happen due to races when you execute the operation. + * + * Returns: %TRUE if the file exists (and can be detected without error), + * %FALSE otherwise (or if cancelled). + */ +gboolean +g_file_query_exists (GFile *file, + GCancellable *cancellable) +{ + GFileInfo *info; + + g_return_val_if_fail (G_IS_FILE(file), FALSE); + + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, cancellable, NULL); + if (info != NULL) + { + g_object_unref (info); + return TRUE; + } + + return FALSE; +} + +/** + * g_file_query_file_type: + * @file: input #GFile + * @flags: a set of #GFileQueryInfoFlags passed to g_file_query_info() + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * + * Utility function to inspect the #GFileType of a file. This is + * implemented using g_file_query_info() and as such does blocking I/O. + * + * The primary use case of this method is to check if a file is + * a regular file, directory, or symlink. + * + * Returns: The #GFileType of the file and %G_FILE_TYPE_UNKNOWN + * if the file does not exist + * + * Since: 2.18 + */ +GFileType +g_file_query_file_type (GFile *file, + GFileQueryInfoFlags flags, + GCancellable *cancellable) +{ + GFileInfo *info; + GFileType file_type; + + g_return_val_if_fail (G_IS_FILE(file), G_FILE_TYPE_UNKNOWN); + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, flags, + cancellable, NULL); + if (info != NULL) + { + file_type = g_file_info_get_file_type (info); + g_object_unref (info); + } + else + file_type = G_FILE_TYPE_UNKNOWN; + + return file_type; +} + +/** + * g_file_query_info: + * @file: input #GFile + * @attributes: an attribute query string + * @flags: a set of #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError + * + * Gets the requested information about specified @file. + * The result is a #GFileInfo object that contains key-value + * attributes (such as the type or size of the file). + * + * The @attributes value is a string that specifies the file + * attributes that should be gathered. It is not an error if + * it's not possible to read a particular requested attribute + * from a file - it just won't be set. @attributes should be a + * comma-separated list of attributes or attribute wildcards. + * The wildcard "*" means all attributes, and a wildcard like + * "standard::*" means all attributes in the standard namespace. + * An example attribute query be "standard::*,owner::user". + * The standard attributes are available as defines, like + * %G_FILE_ATTRIBUTE_STANDARD_NAME. + * + * If @cancellable is not %NULL, then the operation can be cancelled + * by triggering the cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be + * returned. + * + * For symlinks, normally the information about the target of the + * symlink is returned, rather than information about the symlink + * itself. However if you pass %G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS + * in @flags the information about the symlink itself will be returned. + * Also, for symlinks that point to non-existing files the information + * about the symlink itself will be returned. + * + * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will be + * returned. Other errors are possible too, and depend on what kind of + * filesystem the file is on. + * + * Returns: (transfer full): a #GFileInfo for the given @file, or %NULL + * on error. Free the returned object with g_object_unref(). + */ +GFileInfo * +g_file_query_info (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->query_info == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->query_info) (file, attributes, flags, cancellable, error); +} + +/** + * g_file_query_info_async: + * @file: input #GFile + * @attributes: an attribute query string + * @flags: a set of #GFileQueryInfoFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the + * request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously gets the requested information about specified @file. + * The result is a #GFileInfo object that contains key-value attributes + * (such as type or size for the file). + * + * For more details, see g_file_query_info() which is the synchronous + * version of this call. + * + * When the operation is finished, @callback will be called. You can + * then call g_file_query_info_finish() to get the result of the operation. + */ +void +g_file_query_info_async (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->query_info_async) (file, + attributes, + flags, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_query_info_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError + * + * Finishes an asynchronous file info query. + * See g_file_query_info_async(). + * + * Returns: (transfer full): #GFileInfo for given @file + * or %NULL on error. Free the returned object with + * g_object_unref(). + */ +GFileInfo * +g_file_query_info_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->query_info_finish) (file, res, error); +} + +/** + * g_file_query_filesystem_info: + * @file: input #GFile + * @attributes: an attribute query string + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError + * + * Similar to g_file_query_info(), but obtains information + * about the filesystem the @file is on, rather than the file itself. + * For instance the amount of space available and the type of + * the filesystem. + * + * The @attributes value is a string that specifies the attributes + * that should be gathered. It is not an error if it's not possible + * to read a particular requested attribute from a file - it just + * won't be set. @attributes should be a comma-separated list of + * attributes or attribute wildcards. The wildcard "*" means all + * attributes, and a wildcard like "filesystem::*" means all attributes + * in the filesystem namespace. The standard namespace for filesystem + * attributes is "filesystem". Common attributes of interest are + * %G_FILE_ATTRIBUTE_FILESYSTEM_SIZE (the total size of the filesystem + * in bytes), %G_FILE_ATTRIBUTE_FILESYSTEM_FREE (number of bytes available), + * and %G_FILE_ATTRIBUTE_FILESYSTEM_TYPE (type of the filesystem). + * + * If @cancellable is not %NULL, then the operation can be cancelled + * by triggering the cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be + * returned. + * + * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will + * be returned. Other errors are possible too, and depend on what + * kind of filesystem the file is on. + * + * Returns: (transfer full): a #GFileInfo or %NULL if there was an error. + * Free the returned object with g_object_unref(). + */ +GFileInfo * +g_file_query_filesystem_info (GFile *file, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->query_filesystem_info == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->query_filesystem_info) (file, attributes, cancellable, error); +} + +/** + * g_file_query_filesystem_info_async: + * @file: input #GFile + * @attributes: an attribute query string + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously gets the requested information about the filesystem + * that the specified @file is on. The result is a #GFileInfo object + * that contains key-value attributes (such as type or size for the + * file). + * + * For more details, see g_file_query_filesystem_info() which is the + * synchronous version of this call. + * + * When the operation is finished, @callback will be called. You can + * then call g_file_query_info_finish() to get the result of the + * operation. + */ +void +g_file_query_filesystem_info_async (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->query_filesystem_info_async) (file, + attributes, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_query_filesystem_info_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError + * + * Finishes an asynchronous filesystem info query. + * See g_file_query_filesystem_info_async(). + * + * Returns: (transfer full): #GFileInfo for given @file + * or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileInfo * +g_file_query_filesystem_info_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->query_filesystem_info_finish) (file, res, error); +} + +/** + * g_file_find_enclosing_mount: + * @file: input #GFile + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError + * + * Gets a #GMount for the #GFile. + * + * #GMount is returned only for user interesting locations, see + * #GVolumeMonitor. If the #GFileIface for @file does not have a #mount, + * @error will be set to %G_IO_ERROR_NOT_FOUND and %NULL #will be returned. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (transfer full): a #GMount where the @file is located + * or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GMount * +g_file_find_enclosing_mount (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + if (iface->find_enclosing_mount == NULL) + { + + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + /* Translators: This is an error message when + * trying to find the enclosing (user visible) + * mount of a file, but none exists. + */ + _("Containing mount does not exist")); + return NULL; + } + + return (* iface->find_enclosing_mount) (file, cancellable, error); +} + +/** + * g_file_find_enclosing_mount_async: + * @file: a #GFile + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously gets the mount for the file. + * + * For more details, see g_file_find_enclosing_mount() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_find_enclosing_mount_finish() to + * get the result of the operation. + */ +void +g_file_find_enclosing_mount_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->find_enclosing_mount_async) (file, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_find_enclosing_mount_finish: + * @file: a #GFile + * @res: a #GAsyncResult + * @error: a #GError + * + * Finishes an asynchronous find mount request. + * See g_file_find_enclosing_mount_async(). + * + * Returns: (transfer full): #GMount for given @file or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GMount * +g_file_find_enclosing_mount_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->find_enclosing_mount_finish) (file, res, error); +} + + +/** + * g_file_read: + * @file: #GFile to read + * @cancellable: (nullable): a #GCancellable + * @error: a #GError, or %NULL + * + * Opens a file for reading. The result is a #GFileInputStream that + * can be used to read the contents of the file. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will be + * returned. If the file is a directory, the %G_IO_ERROR_IS_DIRECTORY + * error will be returned. Other errors are possible too, and depend + * on what kind of filesystem the file is on. + * + * Virtual: read_fn + * Returns: (transfer full): #GFileInputStream or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileInputStream * +g_file_read (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->read_fn == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->read_fn) (file, cancellable, error); +} + +/** + * g_file_append_to: + * @file: input #GFile + * @flags: a set of #GFileCreateFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Gets an output stream for appending data to the file. + * If the file doesn't already exist it is created. + * + * By default files created are generally readable by everyone, + * but if you pass %G_FILE_CREATE_PRIVATE in @flags the file + * will be made readable only to the current user, to the level that + * is supported on the target filesystem. + * + * If @cancellable is not %NULL, then the operation can be cancelled + * by triggering the cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be + * returned. + * + * Some file systems don't allow all file names, and may return an + * %G_IO_ERROR_INVALID_FILENAME error. If the file is a directory the + * %G_IO_ERROR_IS_DIRECTORY error will be returned. Other errors are + * possible too, and depend on what kind of filesystem the file is on. + * + * Returns: (transfer full): a #GFileOutputStream, or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileOutputStream * +g_file_append_to (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->append_to == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->append_to) (file, flags, cancellable, error); +} + +/** + * g_file_create: + * @file: input #GFile + * @flags: a set of #GFileCreateFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Creates a new file and returns an output stream for writing to it. + * The file must not already exist. + * + * By default files created are generally readable by everyone, + * but if you pass %G_FILE_CREATE_PRIVATE in @flags the file + * will be made readable only to the current user, to the level + * that is supported on the target filesystem. + * + * If @cancellable is not %NULL, then the operation can be cancelled + * by triggering the cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be + * returned. + * + * If a file or directory with this name already exists the + * %G_IO_ERROR_EXISTS error will be returned. Some file systems don't + * allow all file names, and may return an %G_IO_ERROR_INVALID_FILENAME + * error, and if the name is to long %G_IO_ERROR_FILENAME_TOO_LONG will + * be returned. Other errors are possible too, and depend on what kind + * of filesystem the file is on. + * + * Returns: (transfer full): a #GFileOutputStream for the newly created + * file, or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileOutputStream * +g_file_create (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->create == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->create) (file, flags, cancellable, error); +} + +/** + * g_file_replace: + * @file: input #GFile + * @etag: (nullable): an optional [entity tag][gfile-etag] + * for the current #GFile, or #NULL to ignore + * @make_backup: %TRUE if a backup should be created + * @flags: a set of #GFileCreateFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Returns an output stream for overwriting the file, possibly + * creating a backup copy of the file first. If the file doesn't exist, + * it will be created. + * + * This will try to replace the file in the safest way possible so + * that any errors during the writing will not affect an already + * existing copy of the file. For instance, for local files it + * may write to a temporary file and then atomically rename over + * the destination when the stream is closed. + * + * By default files created are generally readable by everyone, + * but if you pass %G_FILE_CREATE_PRIVATE in @flags the file + * will be made readable only to the current user, to the level that + * is supported on the target filesystem. + * + * If @cancellable is not %NULL, then the operation can be cancelled + * by triggering the cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be + * returned. + * + * If you pass in a non-%NULL @etag value and @file already exists, then + * this value is compared to the current entity tag of the file, and if + * they differ an %G_IO_ERROR_WRONG_ETAG error is returned. This + * generally means that the file has been changed since you last read + * it. You can get the new etag from g_file_output_stream_get_etag() + * after you've finished writing and closed the #GFileOutputStream. When + * you load a new file you can use g_file_input_stream_query_info() to + * get the etag of the file. + * + * If @make_backup is %TRUE, this function will attempt to make a + * backup of the current file before overwriting it. If this fails + * a %G_IO_ERROR_CANT_CREATE_BACKUP error will be returned. If you + * want to replace anyway, try again with @make_backup set to %FALSE. + * + * If the file is a directory the %G_IO_ERROR_IS_DIRECTORY error will + * be returned, and if the file is some other form of non-regular file + * then a %G_IO_ERROR_NOT_REGULAR_FILE error will be returned. Some + * file systems don't allow all file names, and may return an + * %G_IO_ERROR_INVALID_FILENAME error, and if the name is to long + * %G_IO_ERROR_FILENAME_TOO_LONG will be returned. Other errors are + * possible too, and depend on what kind of filesystem the file is on. + * + * Returns: (transfer full): a #GFileOutputStream or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileOutputStream * +g_file_replace (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->replace == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + /* Handle empty tag string as NULL in consistent way. */ + if (etag && *etag == 0) + etag = NULL; + + return (* iface->replace) (file, etag, make_backup, flags, cancellable, error); +} + +/** + * g_file_open_readwrite: + * @file: #GFile to open + * @cancellable: (nullable): a #GCancellable + * @error: a #GError, or %NULL + * + * Opens an existing file for reading and writing. The result is + * a #GFileIOStream that can be used to read and write the contents + * of the file. + * + * If @cancellable is not %NULL, then the operation can be cancelled + * by triggering the cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be + * returned. + * + * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will + * be returned. If the file is a directory, the %G_IO_ERROR_IS_DIRECTORY + * error will be returned. Other errors are possible too, and depend on + * what kind of filesystem the file is on. Note that in many non-local + * file cases read and write streams are not supported, so make sure you + * really need to do read and write streaming, rather than just opening + * for reading or writing. + * + * Returns: (transfer full): #GFileIOStream or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GFileIOStream * +g_file_open_readwrite (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->open_readwrite == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->open_readwrite) (file, cancellable, error); +} + +/** + * g_file_create_readwrite: + * @file: a #GFile + * @flags: a set of #GFileCreateFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: return location for a #GError, or %NULL + * + * Creates a new file and returns a stream for reading and + * writing to it. The file must not already exist. + * + * By default files created are generally readable by everyone, + * but if you pass %G_FILE_CREATE_PRIVATE in @flags the file + * will be made readable only to the current user, to the level + * that is supported on the target filesystem. + * + * If @cancellable is not %NULL, then the operation can be cancelled + * by triggering the cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be + * returned. + * + * If a file or directory with this name already exists, the + * %G_IO_ERROR_EXISTS error will be returned. Some file systems don't + * allow all file names, and may return an %G_IO_ERROR_INVALID_FILENAME + * error, and if the name is too long, %G_IO_ERROR_FILENAME_TOO_LONG + * will be returned. Other errors are possible too, and depend on what + * kind of filesystem the file is on. + * + * Note that in many non-local file cases read and write streams are + * not supported, so make sure you really need to do read and write + * streaming, rather than just opening for reading or writing. + * + * Returns: (transfer full): a #GFileIOStream for the newly created + * file, or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GFileIOStream * +g_file_create_readwrite (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->create_readwrite == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->create_readwrite) (file, flags, cancellable, error); +} + +/** + * g_file_replace_readwrite: + * @file: a #GFile + * @etag: (nullable): an optional [entity tag][gfile-etag] + * for the current #GFile, or #NULL to ignore + * @make_backup: %TRUE if a backup should be created + * @flags: a set of #GFileCreateFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: return location for a #GError, or %NULL + * + * Returns an output stream for overwriting the file in readwrite mode, + * possibly creating a backup copy of the file first. If the file doesn't + * exist, it will be created. + * + * For details about the behaviour, see g_file_replace() which does the + * same thing but returns an output stream only. + * + * Note that in many non-local file cases read and write streams are not + * supported, so make sure you really need to do read and write streaming, + * rather than just opening for reading or writing. + * + * Returns: (transfer full): a #GFileIOStream or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GFileIOStream * +g_file_replace_readwrite (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->replace_readwrite == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->replace_readwrite) (file, etag, make_backup, flags, cancellable, error); +} + +/** + * g_file_read_async: + * @file: input #GFile + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously opens @file for reading. + * + * For more details, see g_file_read() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_read_finish() to get the result + * of the operation. + */ +void +g_file_read_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->read_async) (file, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_read_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file read operation started with + * g_file_read_async(). + * + * Returns: (transfer full): a #GFileInputStream or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileInputStream * +g_file_read_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->read_finish) (file, res, error); +} + +/** + * g_file_append_to_async: + * @file: input #GFile + * @flags: a set of #GFileCreateFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously opens @file for appending. + * + * For more details, see g_file_append_to() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_append_to_finish() to get the result + * of the operation. + */ +void +g_file_append_to_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->append_to_async) (file, + flags, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_append_to_finish: + * @file: input #GFile + * @res: #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file append operation started with + * g_file_append_to_async(). + * + * Returns: (transfer full): a valid #GFileOutputStream + * or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileOutputStream * +g_file_append_to_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->append_to_finish) (file, res, error); +} + +/** + * g_file_create_async: + * @file: input #GFile + * @flags: a set of #GFileCreateFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously creates a new file and returns an output stream + * for writing to it. The file must not already exist. + * + * For more details, see g_file_create() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_create_finish() to get the result + * of the operation. + */ +void +g_file_create_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->create_async) (file, + flags, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_create_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file create operation started with + * g_file_create_async(). + * + * Returns: (transfer full): a #GFileOutputStream or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileOutputStream * +g_file_create_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->create_finish) (file, res, error); +} + +/** + * g_file_replace_async: + * @file: input #GFile + * @etag: (nullable): an [entity tag][gfile-etag] for the current #GFile, + * or %NULL to ignore + * @make_backup: %TRUE if a backup should be created + * @flags: a set of #GFileCreateFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously overwrites the file, replacing the contents, + * possibly creating a backup copy of the file first. + * + * For more details, see g_file_replace() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_replace_finish() to get the result + * of the operation. + */ +void +g_file_replace_async (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->replace_async) (file, + etag, + make_backup, + flags, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_replace_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file replace operation started with + * g_file_replace_async(). + * + * Returns: (transfer full): a #GFileOutputStream, or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileOutputStream * +g_file_replace_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->replace_finish) (file, res, error); +} + +/** + * g_file_open_readwrite_async + * @file: input #GFile + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously opens @file for reading and writing. + * + * For more details, see g_file_open_readwrite() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_open_readwrite_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_file_open_readwrite_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->open_readwrite_async) (file, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_open_readwrite_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file read operation started with + * g_file_open_readwrite_async(). + * + * Returns: (transfer full): a #GFileIOStream or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GFileIOStream * +g_file_open_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->open_readwrite_finish) (file, res, error); +} + +/** + * g_file_create_readwrite_async: + * @file: input #GFile + * @flags: a set of #GFileCreateFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously creates a new file and returns a stream + * for reading and writing to it. The file must not already exist. + * + * For more details, see g_file_create_readwrite() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_create_readwrite_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_file_create_readwrite_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->create_readwrite_async) (file, + flags, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_create_readwrite_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file create operation started with + * g_file_create_readwrite_async(). + * + * Returns: (transfer full): a #GFileIOStream or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GFileIOStream * +g_file_create_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->create_readwrite_finish) (file, res, error); +} + +/** + * g_file_replace_readwrite_async: + * @file: input #GFile + * @etag: (nullable): an [entity tag][gfile-etag] for the current #GFile, + * or %NULL to ignore + * @make_backup: %TRUE if a backup should be created + * @flags: a set of #GFileCreateFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously overwrites the file in read-write mode, + * replacing the contents, possibly creating a backup copy + * of the file first. + * + * For more details, see g_file_replace_readwrite() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_replace_readwrite_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_file_replace_readwrite_async (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->replace_readwrite_async) (file, + etag, + make_backup, + flags, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_replace_readwrite_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file replace operation started with + * g_file_replace_readwrite_async(). + * + * Returns: (transfer full): a #GFileIOStream, or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GFileIOStream * +g_file_replace_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->replace_readwrite_finish) (file, res, error); +} + +static gboolean +copy_symlink (GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + const char *target, + GError **error) +{ + GError *my_error; + gboolean tried_delete; + GFileInfo *info; + GFileType file_type; + + tried_delete = FALSE; + + retry: + my_error = NULL; + if (!g_file_make_symbolic_link (destination, target, cancellable, &my_error)) + { + /* Maybe it already existed, and we want to overwrite? */ + if (!tried_delete && (flags & G_FILE_COPY_OVERWRITE) && + my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_EXISTS) + { + g_clear_error (&my_error); + + /* Don't overwrite if the destination is a directory */ + info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, &my_error); + if (info != NULL) + { + file_type = g_file_info_get_file_type (info); + g_object_unref (info); + + if (file_type == G_FILE_TYPE_DIRECTORY) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, + _("Can’t copy over directory")); + return FALSE; + } + } + + if (!g_file_delete (destination, cancellable, error)) + return FALSE; + + tried_delete = TRUE; + goto retry; + } + /* Nah, fail */ + g_propagate_error (error, my_error); + return FALSE; + } + + return TRUE; +} + +static GFileInputStream * +open_source_for_copy (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GError **error) +{ + GError *my_error; + GFileInputStream *ret; + GFileInfo *info; + GFileType file_type; + + my_error = NULL; + ret = g_file_read (source, cancellable, &my_error); + if (ret != NULL) + return ret; + + /* There was an error opening the source, try to set a good error for it: */ + if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_IS_DIRECTORY) + { + /* The source is a directory, don't fail with WOULD_RECURSE immediately, + * as that is less useful to the app. Better check for errors on the + * target instead. + */ + g_error_free (my_error); + my_error = NULL; + + info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, &my_error); + if (info != NULL && + g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE)) + { + file_type = g_file_info_get_file_type (info); + g_object_unref (info); + + if (flags & G_FILE_COPY_OVERWRITE) + { + if (file_type == G_FILE_TYPE_DIRECTORY) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_MERGE, + _("Can’t copy directory over directory")); + return NULL; + } + /* continue to would_recurse error */ + } + else + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_EXISTS, + _("Target file exists")); + return NULL; + } + } + else + { + /* Error getting info from target, return that error + * (except for NOT_FOUND, which is no error here) + */ + g_clear_object (&info); + if (my_error != NULL && !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + g_propagate_error (error, my_error); + return NULL; + } + g_clear_error (&my_error); + } + + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE, + _("Can’t recursively copy directory")); + return NULL; + } + + g_propagate_error (error, my_error); + return NULL; +} + +static gboolean +should_copy (GFileAttributeInfo *info, + gboolean copy_all_attributes, + gboolean skip_perms) +{ + if (skip_perms && strcmp(info->name, "unix::mode") == 0) + return FALSE; + + if (copy_all_attributes) + return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED; + return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE; +} + +/** + * g_file_build_attribute_list_for_copy: + * @file: a #GFile to copy attributes to + * @flags: a set of #GFileCopyFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, %NULL to ignore + * + * Prepares the file attribute query string for copying to @file. + * + * This function prepares an attribute query string to be + * passed to g_file_query_info() to get a list of attributes + * normally copied with the file (see g_file_copy_attributes() + * for the detailed description). This function is used by the + * implementation of g_file_copy_attributes() and is useful + * when one needs to query and set the attributes in two + * stages (e.g., for recursive move of a directory). + * + * Returns: an attribute query string for g_file_query_info(), + * or %NULL if an error occurs. + * + * Since: 2.68 + */ +char * +g_file_build_attribute_list_for_copy (GFile *file, + GFileCopyFlags flags, + GCancellable *cancellable, + GError **error) +{ + char *ret = NULL; + GFileAttributeInfoList *attributes = NULL, *namespaces = NULL; + GString *s = NULL; + gboolean first; + int i; + gboolean copy_all_attributes; + gboolean skip_perms; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + copy_all_attributes = flags & G_FILE_COPY_ALL_METADATA; + skip_perms = (flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) != 0; + + /* Ignore errors here, if the target supports no attributes there is + * nothing to copy. We still honor the cancellable though. + */ + attributes = g_file_query_settable_attributes (file, cancellable, NULL); + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto out; + + namespaces = g_file_query_writable_namespaces (file, cancellable, NULL); + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto out; + + if (attributes == NULL && namespaces == NULL) + goto out; + + first = TRUE; + s = g_string_new (""); + + if (attributes) + { + for (i = 0; i < attributes->n_infos; i++) + { + if (should_copy (&attributes->infos[i], copy_all_attributes, skip_perms)) + { + if (first) + first = FALSE; + else + g_string_append_c (s, ','); + + g_string_append (s, attributes->infos[i].name); + } + } + } + + if (namespaces) + { + for (i = 0; i < namespaces->n_infos; i++) + { + if (should_copy (&namespaces->infos[i], copy_all_attributes, FALSE)) + { + if (first) + first = FALSE; + else + g_string_append_c (s, ','); + + g_string_append (s, namespaces->infos[i].name); + g_string_append (s, "::*"); + } + } + } + + ret = g_string_free (s, FALSE); + s = NULL; + out: + if (s) + g_string_free (s, TRUE); + if (attributes) + g_file_attribute_info_list_unref (attributes); + if (namespaces) + g_file_attribute_info_list_unref (namespaces); + + return ret; +} + +/** + * g_file_copy_attributes: + * @source: a #GFile with attributes + * @destination: a #GFile to copy attributes to + * @flags: a set of #GFileCopyFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, %NULL to ignore + * + * Copies the file attributes from @source to @destination. + * + * Normally only a subset of the file attributes are copied, + * those that are copies in a normal file copy operation + * (which for instance does not include e.g. owner). However + * if %G_FILE_COPY_ALL_METADATA is specified in @flags, then + * all the metadata that is possible to copy is copied. This + * is useful when implementing move by copy + delete source. + * + * Returns: %TRUE if the attributes were copied successfully, + * %FALSE otherwise. + */ +gboolean +g_file_copy_attributes (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GError **error) +{ + char *attrs_to_read; + gboolean res; + GFileInfo *info; + gboolean source_nofollow_symlinks; + + attrs_to_read = g_file_build_attribute_list_for_copy (destination, flags, + cancellable, error); + if (!attrs_to_read) + return FALSE; + + source_nofollow_symlinks = flags & G_FILE_COPY_NOFOLLOW_SYMLINKS; + + /* Ignore errors here, if we can't read some info (e.g. if it doesn't exist) + * we just don't copy it. + */ + info = g_file_query_info (source, attrs_to_read, + source_nofollow_symlinks ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS:0, + cancellable, + NULL); + + g_free (attrs_to_read); + + res = TRUE; + if (info) + { + res = g_file_set_attributes_from_info (destination, + info, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, + error); + g_object_unref (info); + } + + return res; +} + +/* 256k minus malloc overhead */ +#define STREAM_BUFFER_SIZE (1024*256 - 2 *sizeof(gpointer)) + +static gboolean +copy_stream_with_progress (GInputStream *in, + GOutputStream *out, + GFile *source, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + gssize n_read; + gsize n_written; + goffset current_size; + char *buffer; + gboolean res; + goffset total_size; + GFileInfo *info; + + total_size = -1; + /* avoid performance impact of querying total size when it's not needed */ + if (progress_callback) + { + info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (in), + G_FILE_ATTRIBUTE_STANDARD_SIZE, + cancellable, NULL); + if (info) + { + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)) + total_size = g_file_info_get_size (info); + g_object_unref (info); + } + + if (total_size == -1) + { + info = g_file_query_info (source, + G_FILE_ATTRIBUTE_STANDARD_SIZE, + G_FILE_QUERY_INFO_NONE, + cancellable, NULL); + if (info) + { + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)) + total_size = g_file_info_get_size (info); + g_object_unref (info); + } + } + } + + if (total_size == -1) + total_size = 0; + + buffer = g_malloc0 (STREAM_BUFFER_SIZE); + current_size = 0; + res = TRUE; + while (TRUE) + { + n_read = g_input_stream_read (in, buffer, STREAM_BUFFER_SIZE, cancellable, error); + if (n_read == -1) + { + res = FALSE; + break; + } + + if (n_read == 0) + break; + + current_size += n_read; + + res = g_output_stream_write_all (out, buffer, n_read, &n_written, cancellable, error); + if (!res) + break; + + if (progress_callback) + progress_callback (current_size, total_size, progress_callback_data); + } + g_free (buffer); + + /* Make sure we send full copied size */ + if (progress_callback) + progress_callback (current_size, total_size, progress_callback_data); + + return res; +} + +#ifdef HAVE_SPLICE + +static gboolean +do_splice (int fd_in, + loff_t *off_in, + int fd_out, + loff_t *off_out, + size_t len, + long *bytes_transferd, + GError **error) +{ + long result; + +retry: + result = splice (fd_in, off_in, fd_out, off_out, len, SPLICE_F_MORE); + + if (result == -1) + { + int errsv = errno; + + if (errsv == EINTR) + goto retry; + else if (errsv == ENOSYS || errsv == EINVAL || errsv == EOPNOTSUPP) + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Splice not supported")); + else + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error splicing file: %s"), + g_strerror (errsv)); + + return FALSE; + } + + *bytes_transferd = result; + return TRUE; +} + +static gboolean +splice_stream_with_progress (GInputStream *in, + GOutputStream *out, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + int buffer[2] = { -1, -1 }; + int buffer_size; + gboolean res; + goffset total_size; + loff_t offset_in; + loff_t offset_out; + int fd_in, fd_out; + + fd_in = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (in)); + fd_out = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (out)); + + if (!g_unix_open_pipe (buffer, FD_CLOEXEC, error)) + return FALSE; + + /* Try a 1MiB buffer for improved throughput. If that fails, use the default + * pipe size. See: https://bugzilla.gnome.org/791457 */ + buffer_size = fcntl (buffer[1], F_SETPIPE_SZ, 1024 * 1024); + if (buffer_size <= 0) + { + buffer_size = fcntl (buffer[1], F_GETPIPE_SZ); + if (buffer_size <= 0) + { + /* If #F_GETPIPE_SZ isn’t available, assume we’re on Linux < 2.6.35, + * but ≥ 2.6.11, meaning the pipe capacity is 64KiB. Ignore the + * possibility of running on Linux < 2.6.11 (where the capacity was + * the system page size, typically 4KiB) because it’s ancient. + * See pipe(7). */ + buffer_size = 1024 * 64; + } + } + + g_assert (buffer_size > 0); + + total_size = -1; + /* avoid performance impact of querying total size when it's not needed */ + if (progress_callback) + { + struct stat sbuf; + + if (fstat (fd_in, &sbuf) == 0) + total_size = sbuf.st_size; + } + + if (total_size == -1) + total_size = 0; + + offset_in = offset_out = 0; + res = FALSE; + while (TRUE) + { + long n_read; + long n_written; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + break; + + if (!do_splice (fd_in, &offset_in, buffer[1], NULL, buffer_size, &n_read, error)) + break; + + if (n_read == 0) + { + res = TRUE; + break; + } + + while (n_read > 0) + { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto out; + + if (!do_splice (buffer[0], NULL, fd_out, &offset_out, n_read, &n_written, error)) + goto out; + + n_read -= n_written; + } + + if (progress_callback) + progress_callback (offset_in, total_size, progress_callback_data); + } + + /* Make sure we send full copied size */ + if (progress_callback) + progress_callback (offset_in, total_size, progress_callback_data); + + if (!g_close (buffer[0], error)) + goto out; + buffer[0] = -1; + if (!g_close (buffer[1], error)) + goto out; + buffer[1] = -1; + out: + if (buffer[0] != -1) + (void) g_close (buffer[0], NULL); + if (buffer[1] != -1) + (void) g_close (buffer[1], NULL); + + return res; +} +#endif + +#ifdef __linux__ +static gboolean +btrfs_reflink_with_progress (GInputStream *in, + GOutputStream *out, + GFileInfo *info, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + goffset source_size; + int fd_in, fd_out; + int ret, errsv; + + fd_in = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (in)); + fd_out = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (out)); + + if (progress_callback) + source_size = g_file_info_get_size (info); + + /* Btrfs clone ioctl properties: + * - Works at the inode level + * - Doesn't work with directories + * - Always follows symlinks (source and destination) + * + * By the time we get here, *in and *out are both regular files */ + ret = ioctl (fd_out, BTRFS_IOC_CLONE, fd_in); + errsv = errno; + + if (ret < 0) + { + if (errsv == EXDEV) + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Copy (reflink/clone) between mounts is not supported")); + else if (errsv == EINVAL) + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Copy (reflink/clone) is not supported or invalid")); + else + /* Most probably something odd happened; retry with fallback */ + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Copy (reflink/clone) is not supported or didn’t work")); + /* We retry with fallback for all error cases because Btrfs is currently + * unstable, and so we can't trust it to do clone properly. + * In addition, any hard errors here would cause the same failure in the + * fallback manual copy as well. */ + return FALSE; + } + + /* Make sure we send full copied size */ + if (progress_callback) + progress_callback (source_size, source_size, progress_callback_data); + + return TRUE; +} +#endif + +static gboolean +file_copy_fallback (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + gboolean ret = FALSE; + GFileInputStream *file_in = NULL; + GInputStream *in = NULL; + GOutputStream *out = NULL; + GFileInfo *info = NULL; + const char *target; + char *attrs_to_read; + gboolean do_set_attributes = FALSE; + GFileCreateFlags create_flags; + GError *tmp_error = NULL; + + /* need to know the file type */ + info = g_file_query_info (source, + G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, + error); + if (!info) + goto out; + + /* Maybe copy the symlink? */ + if ((flags & G_FILE_COPY_NOFOLLOW_SYMLINKS) && + g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK) + { + target = g_file_info_get_symlink_target (info); + if (target) + { + if (!copy_symlink (destination, flags, cancellable, target, error)) + goto out; + + ret = TRUE; + goto out; + } + /* ... else fall back on a regular file copy */ + } + /* Handle "special" files (pipes, device nodes, ...)? */ + else if (g_file_info_get_file_type (info) == G_FILE_TYPE_SPECIAL) + { + /* FIXME: could try to recreate device nodes and others? */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Can’t copy special file")); + goto out; + } + + /* Everything else should just fall back on a regular copy. */ + + file_in = open_source_for_copy (source, destination, flags, cancellable, error); + if (!file_in) + goto out; + in = G_INPUT_STREAM (file_in); + + attrs_to_read = g_file_build_attribute_list_for_copy (destination, flags, + cancellable, error); + if (!attrs_to_read) + goto out; + + /* Ok, ditch the previous lightweight info (on Unix we just + * called lstat()); at this point we gather all the information + * we need about the source from the opened file descriptor. + */ + g_object_unref (info); + + info = g_file_input_stream_query_info (file_in, attrs_to_read, + cancellable, &tmp_error); + if (!info) + { + /* Not all gvfs backends implement query_info_on_read(), we + * can just fall back to the pathname again. + * https://bugzilla.gnome.org/706254 + */ + if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + g_clear_error (&tmp_error); + info = g_file_query_info (source, attrs_to_read, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, error); + } + else + { + g_free (attrs_to_read); + g_propagate_error (error, tmp_error); + goto out; + } + } + g_free (attrs_to_read); + if (!info) + goto out; + + do_set_attributes = TRUE; + + /* In the local file path, we pass down the source info which + * includes things like unix::mode, to ensure that the target file + * is not created with different permissions from the source file. + * + * If a future API like g_file_replace_with_info() is added, switch + * this code to use that. + * + * Use %G_FILE_CREATE_PRIVATE unless + * - we were told to create the file with default permissions (i.e. the + * process’ umask), + * - or if the source file is on a file system which doesn’t support + * `unix::mode` (in which case it probably also makes sense to create the + * destination with default permissions because the source cannot be + * private), + * - or if the destination file is a `GLocalFile`, in which case we can + * directly open() it with the permissions from the source file. + */ + create_flags = G_FILE_CREATE_NONE; + if (!(flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) && + g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_UNIX_MODE) && + !G_IS_LOCAL_FILE (destination)) + create_flags |= G_FILE_CREATE_PRIVATE; + if (flags & G_FILE_COPY_OVERWRITE) + create_flags |= G_FILE_CREATE_REPLACE_DESTINATION; + + if (G_IS_LOCAL_FILE (destination)) + { + if (flags & G_FILE_COPY_OVERWRITE) + out = (GOutputStream*)_g_local_file_output_stream_replace (_g_local_file_get_filename (G_LOCAL_FILE (destination)), + FALSE, NULL, + flags & G_FILE_COPY_BACKUP, + create_flags, + (flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) ? NULL : info, + cancellable, error); + else + out = (GOutputStream*)_g_local_file_output_stream_create (_g_local_file_get_filename (G_LOCAL_FILE (destination)), + FALSE, create_flags, + (flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) ? NULL : info, + cancellable, error); + } + else if (flags & G_FILE_COPY_OVERWRITE) + { + out = (GOutputStream *)g_file_replace (destination, + NULL, + flags & G_FILE_COPY_BACKUP, + create_flags, + cancellable, error); + } + else + { + out = (GOutputStream *)g_file_create (destination, create_flags, cancellable, error); + } + + if (!out) + goto out; + +#ifdef __linux__ + if (G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out)) + { + GError *reflink_err = NULL; + + if (!btrfs_reflink_with_progress (in, out, info, cancellable, + progress_callback, progress_callback_data, + &reflink_err)) + { + if (g_error_matches (reflink_err, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + g_clear_error (&reflink_err); + } + else + { + g_propagate_error (error, reflink_err); + goto out; + } + } + else + { + ret = TRUE; + goto out; + } + } +#endif + +#ifdef HAVE_SPLICE + if (G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out)) + { + GError *splice_err = NULL; + + if (!splice_stream_with_progress (in, out, cancellable, + progress_callback, progress_callback_data, + &splice_err)) + { + if (g_error_matches (splice_err, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + g_clear_error (&splice_err); + } + else + { + g_propagate_error (error, splice_err); + goto out; + } + } + else + { + ret = TRUE; + goto out; + } + } + +#endif + + /* A plain read/write loop */ + if (!copy_stream_with_progress (in, out, source, cancellable, + progress_callback, progress_callback_data, + error)) + goto out; + + ret = TRUE; + out: + if (in) + { + /* Don't care about errors in source here */ + (void) g_input_stream_close (in, cancellable, NULL); + g_object_unref (in); + } + + if (out) + { + /* But write errors on close are bad! */ + if (!g_output_stream_close (out, cancellable, ret ? error : NULL)) + ret = FALSE; + g_object_unref (out); + } + + /* Ignore errors here. Failure to copy metadata is not a hard error */ + /* TODO: set these attributes /before/ we do the rename() on Unix */ + if (ret && do_set_attributes) + { + g_file_set_attributes_from_info (destination, + info, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, + NULL); + } + + g_clear_object (&info); + + return ret; +} + +/** + * g_file_copy: + * @source: input #GFile + * @destination: destination #GFile + * @flags: set of #GFileCopyFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @progress_callback: (nullable) (scope call): function to callback with + * progress information, or %NULL if progress information is not needed + * @progress_callback_data: (closure): user data to pass to @progress_callback + * @error: #GError to set on error, or %NULL + * + * Copies the file @source to the location specified by @destination. + * Can not handle recursive copies of directories. + * + * If the flag %G_FILE_COPY_OVERWRITE is specified an already + * existing @destination file is overwritten. + * + * If the flag %G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks + * will be copied as symlinks, otherwise the target of the + * @source symlink will be copied. + * + * If the flag %G_FILE_COPY_ALL_METADATA is specified then all the metadata + * that is possible to copy is copied, not just the default subset (which, + * for instance, does not include the owner, see #GFileInfo). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * If @progress_callback is not %NULL, then the operation can be monitored + * by setting this to a #GFileProgressCallback function. + * @progress_callback_data will be passed to this function. It is guaranteed + * that this callback will be called after all data has been transferred with + * the total number of bytes copied during the operation. + * + * If the @source file does not exist, then the %G_IO_ERROR_NOT_FOUND error + * is returned, independent on the status of the @destination. + * + * If %G_FILE_COPY_OVERWRITE is not specified and the target exists, then + * the error %G_IO_ERROR_EXISTS is returned. + * + * If trying to overwrite a file over a directory, the %G_IO_ERROR_IS_DIRECTORY + * error is returned. If trying to overwrite a directory with a directory the + * %G_IO_ERROR_WOULD_MERGE error is returned. + * + * If the source is a directory and the target does not exist, or + * %G_FILE_COPY_OVERWRITE is specified and the target is a file, then the + * %G_IO_ERROR_WOULD_RECURSE error is returned. + * + * If you are interested in copying the #GFile object itself (not the on-disk + * file), see g_file_dup(). + * + * Returns: %TRUE on success, %FALSE otherwise. + */ +gboolean +g_file_copy (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + GFileIface *iface; + GError *my_error; + gboolean res; + + g_return_val_if_fail (G_IS_FILE (source), FALSE); + g_return_val_if_fail (G_IS_FILE (destination), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + iface = G_FILE_GET_IFACE (destination); + if (iface->copy) + { + my_error = NULL; + res = (* iface->copy) (source, destination, + flags, cancellable, + progress_callback, progress_callback_data, + &my_error); + + if (res) + return TRUE; + + if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED) + { + g_propagate_error (error, my_error); + return FALSE; + } + else + g_clear_error (&my_error); + } + + /* If the types are different, and the destination method failed + * also try the source method + */ + if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination)) + { + iface = G_FILE_GET_IFACE (source); + + if (iface->copy) + { + my_error = NULL; + res = (* iface->copy) (source, destination, + flags, cancellable, + progress_callback, progress_callback_data, + &my_error); + + if (res) + return TRUE; + + if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED) + { + g_propagate_error (error, my_error); + return FALSE; + } + else + g_clear_error (&my_error); + } + } + + return file_copy_fallback (source, destination, flags, cancellable, + progress_callback, progress_callback_data, + error); +} + +/** + * g_file_copy_async: + * @source: input #GFile + * @destination: destination #GFile + * @flags: set of #GFileCopyFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @progress_callback: (nullable) (scope notified): function to callback with progress + * information, or %NULL if progress information is not needed + * @progress_callback_data: (closure progress_callback) (nullable): user data to pass to @progress_callback + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure callback): the data to pass to callback function + * + * Copies the file @source to the location specified by @destination + * asynchronously. For details of the behaviour, see g_file_copy(). + * + * If @progress_callback is not %NULL, then that function that will be called + * just like in g_file_copy(). The callback will run in the default main context + * of the thread calling g_file_copy_async() — the same context as @callback is + * run in. + * + * When the operation is finished, @callback will be called. You can then call + * g_file_copy_finish() to get the result of the operation. + */ +void +g_file_copy_async (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (source)); + g_return_if_fail (G_IS_FILE (destination)); + + iface = G_FILE_GET_IFACE (source); + (* iface->copy_async) (source, + destination, + flags, + io_priority, + cancellable, + progress_callback, + progress_callback_data, + callback, + user_data); +} + +/** + * g_file_copy_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes copying the file started with g_file_copy_async(). + * + * Returns: a %TRUE on success, %FALSE on error. + */ +gboolean +g_file_copy_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE); + + if (g_async_result_legacy_propagate_error (res, error)) + return FALSE; + + iface = G_FILE_GET_IFACE (file); + return (* iface->copy_finish) (file, res, error); +} + +/** + * g_file_move: + * @source: #GFile pointing to the source location + * @destination: #GFile pointing to the destination location + * @flags: set of #GFileCopyFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @progress_callback: (nullable) (scope call): #GFileProgressCallback + * function for updates + * @progress_callback_data: (closure): gpointer to user data for + * the callback function + * @error: #GError for returning error conditions, or %NULL + * + * Tries to move the file or directory @source to the location specified + * by @destination. If native move operations are supported then this is + * used, otherwise a copy + delete fallback is used. The native + * implementation may support moving directories (for instance on moves + * inside the same filesystem), but the fallback code does not. + * + * If the flag %G_FILE_COPY_OVERWRITE is specified an already + * existing @destination file is overwritten. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * If @progress_callback is not %NULL, then the operation can be monitored + * by setting this to a #GFileProgressCallback function. + * @progress_callback_data will be passed to this function. It is + * guaranteed that this callback will be called after all data has been + * transferred with the total number of bytes copied during the operation. + * + * If the @source file does not exist, then the %G_IO_ERROR_NOT_FOUND + * error is returned, independent on the status of the @destination. + * + * If %G_FILE_COPY_OVERWRITE is not specified and the target exists, + * then the error %G_IO_ERROR_EXISTS is returned. + * + * If trying to overwrite a file over a directory, the %G_IO_ERROR_IS_DIRECTORY + * error is returned. If trying to overwrite a directory with a directory the + * %G_IO_ERROR_WOULD_MERGE error is returned. + * + * If the source is a directory and the target does not exist, or + * %G_FILE_COPY_OVERWRITE is specified and the target is a file, then + * the %G_IO_ERROR_WOULD_RECURSE error may be returned (if the native + * move operation isn't available). + * + * Returns: %TRUE on successful move, %FALSE otherwise. + */ +gboolean +g_file_move (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + GFileIface *iface; + GError *my_error; + gboolean res; + + g_return_val_if_fail (G_IS_FILE (source), FALSE); + g_return_val_if_fail (G_IS_FILE (destination), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + iface = G_FILE_GET_IFACE (destination); + if (iface->move) + { + my_error = NULL; + res = (* iface->move) (source, destination, + flags, cancellable, + progress_callback, progress_callback_data, + &my_error); + + if (res) + return TRUE; + + if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED) + { + g_propagate_error (error, my_error); + return FALSE; + } + else + g_clear_error (&my_error); + } + + /* If the types are different, and the destination method failed + * also try the source method + */ + if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination)) + { + iface = G_FILE_GET_IFACE (source); + + if (iface->move) + { + my_error = NULL; + res = (* iface->move) (source, destination, + flags, cancellable, + progress_callback, progress_callback_data, + &my_error); + + if (res) + return TRUE; + + if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED) + { + g_propagate_error (error, my_error); + return FALSE; + } + else + g_clear_error (&my_error); + } + } + + if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return FALSE; + } + + flags |= G_FILE_COPY_ALL_METADATA | G_FILE_COPY_NOFOLLOW_SYMLINKS; + if (!g_file_copy (source, destination, flags, cancellable, + progress_callback, progress_callback_data, + error)) + return FALSE; + + return g_file_delete (source, cancellable, error); +} + +/** + * g_file_move_async: + * @source: #GFile pointing to the source location + * @destination: #GFile pointing to the destination location + * @flags: set of #GFileCopyFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @progress_callback: (nullable) (scope call): #GFileProgressCallback + * function for updates + * @progress_callback_data: (closure): gpointer to user data for + * the callback function + * @callback: a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: the data to pass to callback function + * + * Asynchronously moves a file @source to the location of @destination. For details of the behaviour, see g_file_move(). + * + * If @progress_callback is not %NULL, then that function that will be called + * just like in g_file_move(). The callback will run in the default main context + * of the thread calling g_file_move_async() — the same context as @callback is + * run in. + * + * When the operation is finished, @callback will be called. You can then call + * g_file_move_finish() to get the result of the operation. + * + * Since: 2.72 + */ +void +g_file_move_async (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (source)); + g_return_if_fail (G_IS_FILE (destination)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + iface = G_FILE_GET_IFACE (source); + (* iface->move_async) (source, + destination, + flags, + io_priority, + cancellable, + progress_callback, + progress_callback_data, + callback, + user_data); +} + +/** + * g_file_move_finish: + * @file: input source #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file movement, started with + * g_file_move_async(). + * + * Returns: %TRUE on successful file move, %FALSE otherwise. + * + * Since: 2.72 + */ +gboolean +g_file_move_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + iface = G_FILE_GET_IFACE (file); + return (* iface->move_finish) (file, result, error); +} + +/** + * g_file_make_directory: + * @file: input #GFile + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Creates a directory. Note that this will only create a child directory + * of the immediate parent directory of the path or URI given by the #GFile. + * To recursively create directories, see g_file_make_directory_with_parents(). + * This function will fail if the parent directory does not exist, setting + * @error to %G_IO_ERROR_NOT_FOUND. If the file system doesn't support + * creating directories, this function will fail, setting @error to + * %G_IO_ERROR_NOT_SUPPORTED. + * + * For a local #GFile the newly created directory will have the default + * (current) ownership and permissions of the current process. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE on successful creation, %FALSE otherwise. + */ +gboolean +g_file_make_directory (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + iface = G_FILE_GET_IFACE (file); + + if (iface->make_directory == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return FALSE; + } + + return (* iface->make_directory) (file, cancellable, error); +} + +/** + * g_file_make_directory_async: + * @file: input #GFile + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: the data to pass to callback function + * + * Asynchronously creates a directory. + * + * Virtual: make_directory_async + * Since: 2.38 + */ +void +g_file_make_directory_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->make_directory_async) (file, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_make_directory_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous directory creation, started with + * g_file_make_directory_async(). + * + * Virtual: make_directory_finish + * Returns: %TRUE on successful directory creation, %FALSE otherwise. + * Since: 2.38 + */ +gboolean +g_file_make_directory_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + iface = G_FILE_GET_IFACE (file); + return (* iface->make_directory_finish) (file, result, error); +} + +/** + * g_file_make_directory_with_parents: + * @file: input #GFile + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Creates a directory and any parent directories that may not + * exist similar to 'mkdir -p'. If the file system does not support + * creating directories, this function will fail, setting @error to + * %G_IO_ERROR_NOT_SUPPORTED. If the directory itself already exists, + * this function will fail setting @error to %G_IO_ERROR_EXISTS, unlike + * the similar g_mkdir_with_parents(). + * + * For a local #GFile the newly created directories will have the default + * (current) ownership and permissions of the current process. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if all directories have been successfully created, %FALSE + * otherwise. + * + * Since: 2.18 + */ +gboolean +g_file_make_directory_with_parents (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFile *work_file = NULL; + GList *list = NULL, *l; + GError *my_error = NULL; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + /* Try for the simple case of not having to create any parent + * directories. If any parent directory needs to be created, this + * call will fail with NOT_FOUND. If that happens, then that value of + * my_error persists into the while loop below. + */ + g_file_make_directory (file, cancellable, &my_error); + if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + if (my_error) + g_propagate_error (error, my_error); + return my_error == NULL; + } + + work_file = g_object_ref (file); + + /* Creates the parent directories as needed. In case any particular + * creation operation fails for lack of other parent directories + * (NOT_FOUND), the directory is added to a list of directories to + * create later, and the value of my_error is retained until the next + * iteration of the loop. After the loop my_error should either be + * empty or contain a real failure condition. + */ + while (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + GFile *parent_file; + + parent_file = g_file_get_parent (work_file); + if (parent_file == NULL) + break; + + g_clear_error (&my_error); + g_file_make_directory (parent_file, cancellable, &my_error); + /* Another process may have created the directory in between the + * G_IO_ERROR_NOT_FOUND and now + */ + if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) + g_clear_error (&my_error); + + g_object_unref (work_file); + work_file = g_object_ref (parent_file); + + if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + list = g_list_prepend (list, parent_file); /* Transfer ownership of ref */ + else + g_object_unref (parent_file); + } + + /* All directories should be able to be created now, so an error at + * this point means the whole operation must fail -- except an EXISTS + * error, which means that another process already created the + * directory in between the previous failure and now. + */ + for (l = list; my_error == NULL && l; l = l->next) + { + g_file_make_directory ((GFile *) l->data, cancellable, &my_error); + if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) + g_clear_error (&my_error); + } + + if (work_file) + g_object_unref (work_file); + + /* Clean up */ + while (list != NULL) + { + g_object_unref ((GFile *) list->data); + list = g_list_remove (list, list->data); + } + + /* At this point an error in my_error means a that something + * unexpected failed in either of the loops above, so the whole + * operation must fail. + */ + if (my_error != NULL) + { + g_propagate_error (error, my_error); + return FALSE; + } + + return g_file_make_directory (file, cancellable, error); +} + +/** + * g_file_make_symbolic_link: + * @file: a #GFile with the name of the symlink to create + * @symlink_value: (type filename): a string with the path for the target + * of the new symlink + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError + * + * Creates a symbolic link named @file which contains the string + * @symlink_value. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE on the creation of a new symlink, %FALSE otherwise. + */ +gboolean +g_file_make_symbolic_link (GFile *file, + const char *symlink_value, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (symlink_value != NULL, FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + if (*symlink_value == '\0') + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid symlink value given")); + return FALSE; + } + + iface = G_FILE_GET_IFACE (file); + + if (iface->make_symbolic_link == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Symbolic links not supported")); + return FALSE; + } + + return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error); +} + +/** + * g_file_delete: + * @file: input #GFile + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Deletes a file. If the @file is a directory, it will only be + * deleted if it is empty. This has the same semantics as g_unlink(). + * + * If @file doesn’t exist, %G_IO_ERROR_NOT_FOUND will be returned. This allows + * for deletion to be implemented avoiding + * [time-of-check to time-of-use races](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use): + * |[ + * g_autoptr(GError) local_error = NULL; + * if (!g_file_delete (my_file, my_cancellable, &local_error) && + * !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + * { + * // deletion failed for some reason other than the file not existing: + * // so report the error + * g_warning ("Failed to delete %s: %s", + * g_file_peek_path (my_file), local_error->message); + * } + * ]| + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Virtual: delete_file + * Returns: %TRUE if the file was deleted. %FALSE otherwise. + */ +gboolean +g_file_delete (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + iface = G_FILE_GET_IFACE (file); + + if (iface->delete_file == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return FALSE; + } + + return (* iface->delete_file) (file, cancellable, error); +} + +/** + * g_file_delete_async: + * @file: input #GFile + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: the data to pass to callback function + * + * Asynchronously delete a file. If the @file is a directory, it will + * only be deleted if it is empty. This has the same semantics as + * g_unlink(). + * + * Virtual: delete_file_async + * Since: 2.34 + */ +void +g_file_delete_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->delete_file_async) (file, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_delete_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes deleting a file started with g_file_delete_async(). + * + * Virtual: delete_file_finish + * Returns: %TRUE if the file was deleted. %FALSE otherwise. + * Since: 2.34 + **/ +gboolean +g_file_delete_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + + iface = G_FILE_GET_IFACE (file); + return (* iface->delete_file_finish) (file, result, error); +} + +/** + * g_file_trash: + * @file: #GFile to send to trash + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Sends @file to the "Trashcan", if possible. This is similar to + * deleting it, but the user can recover it before emptying the trashcan. + * Not all file systems support trashing, so this call can return the + * %G_IO_ERROR_NOT_SUPPORTED error. Since GLib 2.66, the `x-gvfs-notrash` unix + * mount option can be used to disable g_file_trash() support for certain + * mounts, the %G_IO_ERROR_NOT_SUPPORTED error will be returned in that case. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Virtual: trash + * Returns: %TRUE on successful trash, %FALSE otherwise. + */ +gboolean +g_file_trash (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + iface = G_FILE_GET_IFACE (file); + + if (iface->trash == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Trash not supported")); + return FALSE; + } + + return (* iface->trash) (file, cancellable, error); +} + +/** + * g_file_trash_async: + * @file: input #GFile + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: the data to pass to callback function + * + * Asynchronously sends @file to the Trash location, if possible. + * + * Virtual: trash_async + * Since: 2.38 + */ +void +g_file_trash_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->trash_async) (file, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_trash_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous file trashing operation, started with + * g_file_trash_async(). + * + * Virtual: trash_finish + * Returns: %TRUE on successful trash, %FALSE otherwise. + * Since: 2.38 + */ +gboolean +g_file_trash_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + iface = G_FILE_GET_IFACE (file); + return (* iface->trash_finish) (file, result, error); +} + +/** + * g_file_set_display_name: + * @file: input #GFile + * @display_name: a string + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Renames @file to the specified display name. + * + * The display name is converted from UTF-8 to the correct encoding + * for the target filesystem if possible and the @file is renamed to this. + * + * If you want to implement a rename operation in the user interface the + * edit name (%G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME) should be used as the + * initial value in the rename widget, and then the result after editing + * should be passed to g_file_set_display_name(). + * + * On success the resulting converted filename is returned. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (transfer full): a #GFile specifying what @file was renamed to, + * or %NULL if there was an error. + * Free the returned object with g_object_unref(). + */ +GFile * +g_file_set_display_name (GFile *file, + const gchar *display_name, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (display_name != NULL, NULL); + + if (strchr (display_name, G_DIR_SEPARATOR) != NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("File names cannot contain “%câ€"), G_DIR_SEPARATOR); + return NULL; + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + return (* iface->set_display_name) (file, display_name, cancellable, error); +} + +/** + * g_file_set_display_name_async: + * @file: input #GFile + * @display_name: a string + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously sets the display name for a given #GFile. + * + * For more details, see g_file_set_display_name() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_set_display_name_finish() to get + * the result of the operation. + */ +void +g_file_set_display_name_async (GFile *file, + const gchar *display_name, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + g_return_if_fail (display_name != NULL); + + iface = G_FILE_GET_IFACE (file); + (* iface->set_display_name_async) (file, + display_name, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_set_display_name_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes setting a display name started with + * g_file_set_display_name_async(). + * + * Returns: (transfer full): a #GFile or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFile * +g_file_set_display_name_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + return (* iface->set_display_name_finish) (file, res, error); +} + +/** + * g_file_query_settable_attributes: + * @file: input #GFile + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Obtain the list of settable attributes for the file. + * + * Returns the type and full attribute name of all the attributes + * that can be set on this file. This doesn't mean setting it will + * always succeed though, you might get an access failure, or some + * specific file may not support a specific attribute. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (transfer full): a #GFileAttributeInfoList describing the settable attributes. + * When you are done with it, release it with + * g_file_attribute_info_list_unref() + */ +GFileAttributeInfoList * +g_file_query_settable_attributes (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + GError *my_error; + GFileAttributeInfoList *list; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->query_settable_attributes == NULL) + return g_file_attribute_info_list_new (); + + my_error = NULL; + list = (* iface->query_settable_attributes) (file, cancellable, &my_error); + + if (list == NULL) + { + if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED) + { + list = g_file_attribute_info_list_new (); + g_error_free (my_error); + } + else + g_propagate_error (error, my_error); + } + + return list; +} + +/** + * g_file_query_writable_namespaces: + * @file: input #GFile + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Obtain the list of attribute namespaces where new attributes + * can be created by a user. An example of this is extended + * attributes (in the "xattr" namespace). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (transfer full): a #GFileAttributeInfoList describing the writable namespaces. + * When you are done with it, release it with + * g_file_attribute_info_list_unref() + */ +GFileAttributeInfoList * +g_file_query_writable_namespaces (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + GError *my_error; + GFileAttributeInfoList *list; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->query_writable_namespaces == NULL) + return g_file_attribute_info_list_new (); + + my_error = NULL; + list = (* iface->query_writable_namespaces) (file, cancellable, &my_error); + + if (list == NULL) + { + g_warn_if_reached(); + list = g_file_attribute_info_list_new (); + } + + if (my_error != NULL) + { + if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED) + { + g_error_free (my_error); + } + else + g_propagate_error (error, my_error); + } + + return list; +} + +/** + * g_file_set_attribute: + * @file: input #GFile + * @attribute: a string containing the attribute's name + * @type: The type of the attribute + * @value_p: (nullable): a pointer to the value (or the pointer + * itself if the type is a pointer type) + * @flags: a set of #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Sets an attribute in the file with attribute name @attribute to @value_p. + * + * Some attributes can be unset by setting @type to + * %G_FILE_ATTRIBUTE_TYPE_INVALID and @value_p to %NULL. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if the attribute was set, %FALSE otherwise. + */ +gboolean +g_file_set_attribute (GFile *file, + const gchar *attribute, + GFileAttributeType type, + gpointer value_p, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + iface = G_FILE_GET_IFACE (file); + + if (iface->set_attribute == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return FALSE; + } + + return (* iface->set_attribute) (file, attribute, type, value_p, flags, cancellable, error); +} + +/** + * g_file_set_attributes_from_info: + * @file: input #GFile + * @info: a #GFileInfo + * @flags: #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Tries to set all attributes in the #GFileInfo on the target + * values, not stopping on the first error. + * + * If there is any error during this operation then @error will + * be set to the first error. Error on particular fields are flagged + * by setting the "status" field in the attribute value to + * %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING, which means you can + * also detect further errors. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %FALSE if there was any error, %TRUE otherwise. + */ +gboolean +g_file_set_attributes_from_info (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + g_file_info_clear_status (info); + + iface = G_FILE_GET_IFACE (file); + + return (* iface->set_attributes_from_info) (file, + info, + flags, + cancellable, + error); +} + +static gboolean +g_file_real_set_attributes_from_info (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + char **attributes; + int i; + gboolean res; + GFileAttributeValue *value; + + res = TRUE; + + attributes = g_file_info_list_attributes (info, NULL); + + for (i = 0; attributes[i] != NULL; i++) + { + value = _g_file_info_get_attribute_value (info, attributes[i]); + + if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET) + continue; + + if (!g_file_set_attribute (file, attributes[i], + value->type, _g_file_attribute_value_peek_as_pointer (value), + flags, cancellable, error)) + { + value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING; + res = FALSE; + /* Don't set error multiple times */ + error = NULL; + } + else + value->status = G_FILE_ATTRIBUTE_STATUS_SET; + } + + g_strfreev (attributes); + + return res; +} + +/** + * g_file_set_attributes_async: + * @file: input #GFile + * @info: a #GFileInfo + * @flags: a #GFileQueryInfoFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): a #gpointer + * + * Asynchronously sets the attributes of @file with @info. + * + * For more details, see g_file_set_attributes_from_info(), + * which is the synchronous version of this call. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_set_attributes_finish() to get + * the result of the operation. + */ +void +g_file_set_attributes_async (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + g_return_if_fail (G_IS_FILE_INFO (info)); + + iface = G_FILE_GET_IFACE (file); + (* iface->set_attributes_async) (file, + info, + flags, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_set_attributes_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @info: (out) (transfer full): a #GFileInfo + * @error: a #GError, or %NULL + * + * Finishes setting an attribute started in g_file_set_attributes_async(). + * + * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise. + */ +gboolean +g_file_set_attributes_finish (GFile *file, + GAsyncResult *result, + GFileInfo **info, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + /* No standard handling of errors here, as we must set info even + * on errors + */ + iface = G_FILE_GET_IFACE (file); + return (* iface->set_attributes_finish) (file, result, info, error); +} + +/** + * g_file_set_attribute_string: + * @file: input #GFile + * @attribute: a string containing the attribute's name + * @value: a string containing the attribute's value + * @flags: #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value. + * If @attribute is of a different type, this operation will fail. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise. + */ +gboolean +g_file_set_attribute_string (GFile *file, + const char *attribute, + const char *value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + return g_file_set_attribute (file, attribute, + G_FILE_ATTRIBUTE_TYPE_STRING, (gpointer)value, + flags, cancellable, error); +} + +/** + * g_file_set_attribute_byte_string: + * @file: input #GFile + * @attribute: a string containing the attribute's name + * @value: a string containing the attribute's new value + * @flags: a #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value. + * If @attribute is of a different type, this operation will fail, + * returning %FALSE. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if the @attribute was successfully set to @value + * in the @file, %FALSE otherwise. + */ +gboolean +g_file_set_attribute_byte_string (GFile *file, + const gchar *attribute, + const gchar *value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + return g_file_set_attribute (file, attribute, + G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, (gpointer)value, + flags, cancellable, error); +} + +/** + * g_file_set_attribute_uint32: + * @file: input #GFile + * @attribute: a string containing the attribute's name + * @value: a #guint32 containing the attribute's new value + * @flags: a #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value. + * If @attribute is of a different type, this operation will fail. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if the @attribute was successfully set to @value + * in the @file, %FALSE otherwise. + */ +gboolean +g_file_set_attribute_uint32 (GFile *file, + const gchar *attribute, + guint32 value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + return g_file_set_attribute (file, attribute, + G_FILE_ATTRIBUTE_TYPE_UINT32, &value, + flags, cancellable, error); +} + +/** + * g_file_set_attribute_int32: + * @file: input #GFile + * @attribute: a string containing the attribute's name + * @value: a #gint32 containing the attribute's new value + * @flags: a #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value. + * If @attribute is of a different type, this operation will fail. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if the @attribute was successfully set to @value + * in the @file, %FALSE otherwise. + */ +gboolean +g_file_set_attribute_int32 (GFile *file, + const gchar *attribute, + gint32 value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + return g_file_set_attribute (file, attribute, + G_FILE_ATTRIBUTE_TYPE_INT32, &value, + flags, cancellable, error); +} + +/** + * g_file_set_attribute_uint64: + * @file: input #GFile + * @attribute: a string containing the attribute's name + * @value: a #guint64 containing the attribute's new value + * @flags: a #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value. + * If @attribute is of a different type, this operation will fail. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if the @attribute was successfully set to @value + * in the @file, %FALSE otherwise. + */ +gboolean +g_file_set_attribute_uint64 (GFile *file, + const gchar *attribute, + guint64 value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) + { + return g_file_set_attribute (file, attribute, + G_FILE_ATTRIBUTE_TYPE_UINT64, &value, + flags, cancellable, error); +} + +/** + * g_file_set_attribute_int64: + * @file: input #GFile + * @attribute: a string containing the attribute's name + * @value: a #guint64 containing the attribute's new value + * @flags: a #GFileQueryInfoFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value. + * If @attribute is of a different type, this operation will fail. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise. + */ +gboolean +g_file_set_attribute_int64 (GFile *file, + const gchar *attribute, + gint64 value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + return g_file_set_attribute (file, attribute, + G_FILE_ATTRIBUTE_TYPE_INT64, &value, + flags, cancellable, error); +} + +/** + * g_file_mount_mountable: + * @file: input #GFile + * @flags: flags affecting the operation + * @mount_operation: (nullable): a #GMountOperation, + * or %NULL to avoid user interaction + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call + * when the request is satisfied, or %NULL + * @user_data: (closure): the data to pass to callback function + * + * Mounts a file of type G_FILE_TYPE_MOUNTABLE. + * Using @mount_operation, you can request callbacks when, for instance, + * passwords are needed during authentication. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_mount_mountable_finish() to get + * the result of the operation. + */ +void +g_file_mount_mountable (GFile *file, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + + if (iface->mount_mountable == NULL) + { + g_task_report_new_error (file, callback, user_data, + g_file_mount_mountable, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return; + } + + (* iface->mount_mountable) (file, + flags, + mount_operation, + cancellable, + callback, + user_data); +} + +/** + * g_file_mount_mountable_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes a mount operation. See g_file_mount_mountable() for details. + * + * Finish an asynchronous mount operation that was started + * with g_file_mount_mountable(). + * + * Returns: (transfer full): a #GFile or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFile * +g_file_mount_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + else if (g_async_result_is_tagged (result, g_file_mount_mountable)) + return g_task_propagate_pointer (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (file); + return (* iface->mount_mountable_finish) (file, result, error); +} + +/** + * g_file_unmount_mountable: + * @file: input #GFile + * @flags: flags affecting the operation + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call + * when the request is satisfied, or %NULL + * @user_data: (closure): the data to pass to callback function + * + * Unmounts a file of type G_FILE_TYPE_MOUNTABLE. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_unmount_mountable_finish() to get + * the result of the operation. + * + * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation() instead. + */ +void +g_file_unmount_mountable (GFile *file, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + + if (iface->unmount_mountable == NULL) + { + g_task_report_new_error (file, callback, user_data, + g_file_unmount_mountable_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return; + } + + (* iface->unmount_mountable) (file, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_file_unmount_mountable_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an unmount operation, see g_file_unmount_mountable() for details. + * + * Finish an asynchronous unmount operation that was started + * with g_file_unmount_mountable(). + * + * Returns: %TRUE if the operation finished successfully. + * %FALSE otherwise. + * + * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation_finish() + * instead. + */ +gboolean +g_file_unmount_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_unmount_mountable_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (file); + return (* iface->unmount_mountable_finish) (file, result, error); +} + +/** + * g_file_unmount_mountable_with_operation: + * @file: input #GFile + * @flags: flags affecting the operation + * @mount_operation: (nullable): a #GMountOperation, + * or %NULL to avoid user interaction + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call + * when the request is satisfied, or %NULL + * @user_data: (closure): the data to pass to callback function + * + * Unmounts a file of type %G_FILE_TYPE_MOUNTABLE. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_unmount_mountable_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_file_unmount_mountable_with_operation (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + + if (iface->unmount_mountable == NULL && iface->unmount_mountable_with_operation == NULL) + { + g_task_report_new_error (file, callback, user_data, + g_file_unmount_mountable_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return; + } + + if (iface->unmount_mountable_with_operation != NULL) + (* iface->unmount_mountable_with_operation) (file, + flags, + mount_operation, + cancellable, + callback, + user_data); + else + (* iface->unmount_mountable) (file, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_file_unmount_mountable_with_operation_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an unmount operation, + * see g_file_unmount_mountable_with_operation() for details. + * + * Finish an asynchronous unmount operation that was started + * with g_file_unmount_mountable_with_operation(). + * + * Returns: %TRUE if the operation finished successfully. + * %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_file_unmount_mountable_with_operation_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_unmount_mountable_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (file); + if (iface->unmount_mountable_with_operation_finish != NULL) + return (* iface->unmount_mountable_with_operation_finish) (file, result, error); + else + return (* iface->unmount_mountable_finish) (file, result, error); +} + +/** + * g_file_eject_mountable: + * @file: input #GFile + * @flags: flags affecting the operation + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call + * when the request is satisfied, or %NULL + * @user_data: (closure): the data to pass to callback function + * + * Starts an asynchronous eject on a mountable. + * When this operation has completed, @callback will be called with + * @user_user data, and the operation can be finalized with + * g_file_eject_mountable_finish(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Deprecated: 2.22: Use g_file_eject_mountable_with_operation() instead. + */ +void +g_file_eject_mountable (GFile *file, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + + if (iface->eject_mountable == NULL) + { + g_task_report_new_error (file, callback, user_data, + g_file_eject_mountable_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return; + } + + (* iface->eject_mountable) (file, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_file_eject_mountable_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous eject operation started by + * g_file_eject_mountable(). + * + * Returns: %TRUE if the @file was ejected successfully. + * %FALSE otherwise. + * + * Deprecated: 2.22: Use g_file_eject_mountable_with_operation_finish() + * instead. + */ +gboolean +g_file_eject_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_eject_mountable_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (file); + return (* iface->eject_mountable_finish) (file, result, error); +} + +/** + * g_file_eject_mountable_with_operation: + * @file: input #GFile + * @flags: flags affecting the operation + * @mount_operation: (nullable): a #GMountOperation, + * or %NULL to avoid user interaction + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call + * when the request is satisfied, or %NULL + * @user_data: (closure): the data to pass to callback function + * + * Starts an asynchronous eject on a mountable. + * When this operation has completed, @callback will be called with + * @user_user data, and the operation can be finalized with + * g_file_eject_mountable_with_operation_finish(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Since: 2.22 + */ +void +g_file_eject_mountable_with_operation (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + + if (iface->eject_mountable == NULL && iface->eject_mountable_with_operation == NULL) + { + g_task_report_new_error (file, callback, user_data, + g_file_eject_mountable_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return; + } + + if (iface->eject_mountable_with_operation != NULL) + (* iface->eject_mountable_with_operation) (file, + flags, + mount_operation, + cancellable, + callback, + user_data); + else + (* iface->eject_mountable) (file, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_file_eject_mountable_with_operation_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous eject operation started by + * g_file_eject_mountable_with_operation(). + * + * Returns: %TRUE if the @file was ejected successfully. + * %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_file_eject_mountable_with_operation_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_eject_mountable_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (file); + if (iface->eject_mountable_with_operation_finish != NULL) + return (* iface->eject_mountable_with_operation_finish) (file, result, error); + else + return (* iface->eject_mountable_finish) (file, result, error); +} + +/** + * g_file_monitor_directory: + * @file: input #GFile + * @flags: a set of #GFileMonitorFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Obtains a directory monitor for the given file. + * This may fail if directory monitoring is not supported. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * It does not make sense for @flags to contain + * %G_FILE_MONITOR_WATCH_HARD_LINKS, since hard links can not be made to + * directories. It is not possible to monitor all the files in a + * directory for changes made via hard links; if you want to do this then + * you must register individual watches with g_file_monitor(). + * + * Virtual: monitor_dir + * Returns: (transfer full): a #GFileMonitor for the given @file, + * or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileMonitor * +g_file_monitor_directory (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (~flags & G_FILE_MONITOR_WATCH_HARD_LINKS, NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + if (iface->monitor_dir == NULL) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return NULL; + } + + return (* iface->monitor_dir) (file, flags, cancellable, error); +} + +/** + * g_file_monitor_file: + * @file: input #GFile + * @flags: a set of #GFileMonitorFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Obtains a file monitor for the given file. If no file notification + * mechanism exists, then regular polling of the file is used. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * If @flags contains %G_FILE_MONITOR_WATCH_HARD_LINKS then the monitor + * will also attempt to report changes made to the file via another + * filename (ie, a hard link). Without this flag, you can only rely on + * changes made through the filename contained in @file to be + * reported. Using this flag may result in an increase in resource + * usage, and may not have any effect depending on the #GFileMonitor + * backend and/or filesystem type. + * + * Returns: (transfer full): a #GFileMonitor for the given @file, + * or %NULL on error. + * Free the returned object with g_object_unref(). + */ +GFileMonitor * +g_file_monitor_file (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileIface *iface; + GFileMonitor *monitor; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + iface = G_FILE_GET_IFACE (file); + + monitor = NULL; + + if (iface->monitor_file) + monitor = (* iface->monitor_file) (file, flags, cancellable, NULL); + + /* Fallback to polling */ + if (monitor == NULL) + monitor = _g_poll_file_monitor_new (file); + + return monitor; +} + +/** + * g_file_monitor: + * @file: input #GFile + * @flags: a set of #GFileMonitorFlags + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @error: a #GError, or %NULL + * + * Obtains a file or directory monitor for the given file, + * depending on the type of the file. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (transfer full): a #GFileMonitor for the given @file, + * or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.18 + */ +GFileMonitor * +g_file_monitor (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error) +{ + if (g_file_query_file_type (file, 0, cancellable) == G_FILE_TYPE_DIRECTORY) + return g_file_monitor_directory (file, + flags & ~G_FILE_MONITOR_WATCH_HARD_LINKS, + cancellable, error); + else + return g_file_monitor_file (file, flags, cancellable, error); +} + +/******************************************** + * Default implementation of async ops * + ********************************************/ + +typedef struct { + char *attributes; + GFileQueryInfoFlags flags; +} QueryInfoAsyncData; + +static void +query_info_data_free (QueryInfoAsyncData *data) +{ + g_free (data->attributes); + g_free (data); +} + +static void +query_info_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + QueryInfoAsyncData *data = task_data; + GFileInfo *info; + GError *error = NULL; + + info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error); + if (info) + g_task_return_pointer (task, info, g_object_unref); + else + g_task_return_error (task, error); +} + +static void +g_file_real_query_info_async (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + QueryInfoAsyncData *data; + + data = g_new0 (QueryInfoAsyncData, 1); + data->attributes = g_strdup (attributes); + data->flags = flags; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_query_info_async); + g_task_set_task_data (task, data, (GDestroyNotify)query_info_data_free); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, query_info_async_thread); + g_object_unref (task); +} + +static GFileInfo * +g_file_real_query_info_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +query_filesystem_info_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + const char *attributes = task_data; + GFileInfo *info; + GError *error = NULL; + + info = g_file_query_filesystem_info (G_FILE (object), attributes, cancellable, &error); + if (info) + g_task_return_pointer (task, info, g_object_unref); + else + g_task_return_error (task, error); +} + +static void +g_file_real_query_filesystem_info_async (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_query_filesystem_info_async); + g_task_set_task_data (task, g_strdup (attributes), g_free); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, query_filesystem_info_async_thread); + g_object_unref (task); +} + +static GFileInfo * +g_file_real_query_filesystem_info_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +enumerate_children_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + QueryInfoAsyncData *data = task_data; + GFileEnumerator *enumerator; + GError *error = NULL; + + enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error); + if (error) + g_task_return_error (task, error); + else + g_task_return_pointer (task, enumerator, g_object_unref); +} + +static void +g_file_real_enumerate_children_async (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + QueryInfoAsyncData *data; + + data = g_new0 (QueryInfoAsyncData, 1); + data->attributes = g_strdup (attributes); + data->flags = flags; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_enumerate_children_async); + g_task_set_task_data (task, data, (GDestroyNotify)query_info_data_free); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, enumerate_children_async_thread); + g_object_unref (task); +} + +static GFileEnumerator * +g_file_real_enumerate_children_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +open_read_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileInputStream *stream; + GError *error = NULL; + + stream = g_file_read (G_FILE (object), cancellable, &error); + if (stream) + g_task_return_pointer (task, stream, g_object_unref); + else + g_task_return_error (task, error); +} + +static void +g_file_real_read_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_read_async); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, open_read_async_thread); + g_object_unref (task); +} + +static GFileInputStream * +g_file_real_read_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +append_to_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileCreateFlags *data = task_data; + GFileOutputStream *stream; + GError *error = NULL; + + stream = g_file_append_to (G_FILE (source_object), *data, cancellable, &error); + if (stream) + g_task_return_pointer (task, stream, g_object_unref); + else + g_task_return_error (task, error); +} + +static void +g_file_real_append_to_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileCreateFlags *data; + GTask *task; + + data = g_new0 (GFileCreateFlags, 1); + *data = flags; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_append_to_async); + g_task_set_task_data (task, data, g_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, append_to_async_thread); + g_object_unref (task); +} + +static GFileOutputStream * +g_file_real_append_to_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +create_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileCreateFlags *data = task_data; + GFileOutputStream *stream; + GError *error = NULL; + + stream = g_file_create (G_FILE (source_object), *data, cancellable, &error); + if (stream) + g_task_return_pointer (task, stream, g_object_unref); + else + g_task_return_error (task, error); +} + +static void +g_file_real_create_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileCreateFlags *data; + GTask *task; + + data = g_new0 (GFileCreateFlags, 1); + *data = flags; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_create_async); + g_task_set_task_data (task, data, g_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, create_async_thread); + g_object_unref (task); +} + +static GFileOutputStream * +g_file_real_create_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +typedef struct { + GFileOutputStream *stream; + char *etag; + gboolean make_backup; + GFileCreateFlags flags; +} ReplaceAsyncData; + +static void +replace_async_data_free (ReplaceAsyncData *data) +{ + if (data->stream) + g_object_unref (data->stream); + g_free (data->etag); + g_free (data); +} + +static void +replace_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileOutputStream *stream; + ReplaceAsyncData *data = task_data; + GError *error = NULL; + + stream = g_file_replace (G_FILE (source_object), + data->etag, + data->make_backup, + data->flags, + cancellable, + &error); + + if (stream) + g_task_return_pointer (task, stream, g_object_unref); + else + g_task_return_error (task, error); +} + +static void +g_file_real_replace_async (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + ReplaceAsyncData *data; + + data = g_new0 (ReplaceAsyncData, 1); + data->etag = g_strdup (etag); + data->make_backup = make_backup; + data->flags = flags; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_replace_async); + g_task_set_task_data (task, data, (GDestroyNotify)replace_async_data_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, replace_async_thread); + g_object_unref (task); +} + +static GFileOutputStream * +g_file_real_replace_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +delete_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + + if (g_file_delete (G_FILE (object), cancellable, &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +static void +g_file_real_delete_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_delete_async); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, delete_async_thread); + g_object_unref (task); +} + +static gboolean +g_file_real_delete_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +trash_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + + if (g_file_trash (G_FILE (object), cancellable, &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +static void +g_file_real_trash_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_trash_async); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, trash_async_thread); + g_object_unref (task); +} + +static gboolean +g_file_real_trash_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} + + +typedef struct { + GFile *source; /* (owned) */ + GFile *destination; /* (owned) */ + GFileCopyFlags flags; + GFileProgressCallback progress_cb; + gpointer progress_cb_data; +} MoveAsyncData; + +static void +move_async_data_free (MoveAsyncData *data) +{ + g_object_unref (data->source); + g_object_unref (data->destination); + g_slice_free (MoveAsyncData, data); +} + +typedef struct { + MoveAsyncData *data; /* (unowned) */ + goffset current_num_bytes; + goffset total_num_bytes; +} MoveProgressData; + +static gboolean +move_async_progress_in_main (gpointer user_data) +{ + MoveProgressData *progress = user_data; + MoveAsyncData *data = progress->data; + + data->progress_cb (progress->current_num_bytes, + progress->total_num_bytes, + data->progress_cb_data); + + return G_SOURCE_REMOVE; +} + +static void +move_async_progress_callback (goffset current_num_bytes, + goffset total_num_bytes, + gpointer user_data) +{ + GTask *task = user_data; + MoveAsyncData *data = g_task_get_task_data (task); + MoveProgressData *progress; + + progress = g_new0 (MoveProgressData, 1); + progress->data = data; + progress->current_num_bytes = current_num_bytes; + progress->total_num_bytes = total_num_bytes; + + g_main_context_invoke_full (g_task_get_context (task), + g_task_get_priority (task), + move_async_progress_in_main, + g_steal_pointer (&progress), + g_free); +} + +static void +move_async_thread (GTask *task, + gpointer source, + gpointer task_data, + GCancellable *cancellable) +{ + MoveAsyncData *data = task_data; + gboolean result; + GError *error = NULL; + + result = g_file_move (data->source, + data->destination, + data->flags, + cancellable, + (data->progress_cb != NULL) ? move_async_progress_callback : NULL, + task, + &error); + if (result) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, g_steal_pointer (&error)); +} + +static void +g_file_real_move_async (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + MoveAsyncData *data; + + data = g_slice_new0 (MoveAsyncData); + data->source = g_object_ref (source); + data->destination = g_object_ref (destination); + data->flags = flags; + data->progress_cb = progress_callback; + data->progress_cb_data = progress_callback_data; + + task = g_task_new (source, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_move_async); + g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) move_async_data_free); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, move_async_thread); + g_object_unref (task); +} + +static gboolean +g_file_real_move_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, file), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +make_directory_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + + if (g_file_make_directory (G_FILE (object), cancellable, &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +static void +g_file_real_make_directory_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_make_directory_async); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, make_directory_async_thread); + g_object_unref (task); +} + +static gboolean +g_file_real_make_directory_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +open_readwrite_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileIOStream *stream; + GError *error = NULL; + + stream = g_file_open_readwrite (G_FILE (object), cancellable, &error); + + if (stream == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, stream, g_object_unref); +} + +static void +g_file_real_open_readwrite_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_open_readwrite_async); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, open_readwrite_async_thread); + g_object_unref (task); +} + +static GFileIOStream * +g_file_real_open_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +create_readwrite_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileCreateFlags *data = task_data; + GFileIOStream *stream; + GError *error = NULL; + + stream = g_file_create_readwrite (G_FILE (object), *data, cancellable, &error); + + if (stream == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, stream, g_object_unref); +} + +static void +g_file_real_create_readwrite_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileCreateFlags *data; + GTask *task; + + data = g_new0 (GFileCreateFlags, 1); + *data = flags; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_create_readwrite_async); + g_task_set_task_data (task, data, g_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, create_readwrite_async_thread); + g_object_unref (task); +} + +static GFileIOStream * +g_file_real_create_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +typedef struct { + char *etag; + gboolean make_backup; + GFileCreateFlags flags; +} ReplaceRWAsyncData; + +static void +replace_rw_async_data_free (ReplaceRWAsyncData *data) +{ + g_free (data->etag); + g_free (data); +} + +static void +replace_readwrite_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileIOStream *stream; + GError *error = NULL; + ReplaceRWAsyncData *data = task_data; + + stream = g_file_replace_readwrite (G_FILE (object), + data->etag, + data->make_backup, + data->flags, + cancellable, + &error); + + if (stream == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, stream, g_object_unref); +} + +static void +g_file_real_replace_readwrite_async (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + ReplaceRWAsyncData *data; + + data = g_new0 (ReplaceRWAsyncData, 1); + data->etag = g_strdup (etag); + data->make_backup = make_backup; + data->flags = flags; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_replace_readwrite_async); + g_task_set_task_data (task, data, (GDestroyNotify)replace_rw_async_data_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, replace_readwrite_async_thread); + g_object_unref (task); +} + +static GFileIOStream * +g_file_real_replace_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +set_display_name_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + char *name = task_data; + GFile *file; + + file = g_file_set_display_name (G_FILE (object), name, cancellable, &error); + + if (file == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, file, g_object_unref); +} + +static void +g_file_real_set_display_name_async (GFile *file, + const char *display_name, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_set_display_name_async); + g_task_set_task_data (task, g_strdup (display_name), g_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, set_display_name_async_thread); + g_object_unref (task); +} + +static GFile * +g_file_real_set_display_name_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +typedef struct { + GFileQueryInfoFlags flags; + GFileInfo *info; + gboolean res; + GError *error; +} SetInfoAsyncData; + +static void +set_info_data_free (SetInfoAsyncData *data) +{ + if (data->info) + g_object_unref (data->info); + if (data->error) + g_error_free (data->error); + g_free (data); +} + +static void +set_info_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + SetInfoAsyncData *data = task_data; + + data->error = NULL; + data->res = g_file_set_attributes_from_info (G_FILE (object), + data->info, + data->flags, + cancellable, + &data->error); +} + +static void +g_file_real_set_attributes_async (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + SetInfoAsyncData *data; + + data = g_new0 (SetInfoAsyncData, 1); + data->info = g_file_info_dup (info); + data->flags = flags; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_set_attributes_async); + g_task_set_task_data (task, data, (GDestroyNotify)set_info_data_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, set_info_async_thread); + g_object_unref (task); +} + +static gboolean +g_file_real_set_attributes_finish (GFile *file, + GAsyncResult *res, + GFileInfo **info, + GError **error) +{ + SetInfoAsyncData *data; + + g_return_val_if_fail (g_task_is_valid (res, file), FALSE); + + data = g_task_get_task_data (G_TASK (res)); + + if (info) + *info = g_object_ref (data->info); + + if (error != NULL && data->error) + *error = g_error_copy (data->error); + + return data->res; +} + +static void +find_enclosing_mount_async_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + GMount *mount; + + mount = g_file_find_enclosing_mount (G_FILE (object), cancellable, &error); + + if (mount == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, mount, g_object_unref); +} + +static void +g_file_real_find_enclosing_mount_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_find_enclosing_mount_async); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, find_enclosing_mount_async_thread); + g_object_unref (task); +} + +static GMount * +g_file_real_find_enclosing_mount_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + + +typedef struct { + GFile *source; + GFile *destination; + GFileCopyFlags flags; + GFileProgressCallback progress_cb; + gpointer progress_cb_data; +} CopyAsyncData; + +static void +copy_async_data_free (CopyAsyncData *data) +{ + g_object_unref (data->source); + g_object_unref (data->destination); + g_slice_free (CopyAsyncData, data); +} + +typedef struct { + CopyAsyncData *data; + goffset current_num_bytes; + goffset total_num_bytes; +} CopyProgressData; + +static gboolean +copy_async_progress_in_main (gpointer user_data) +{ + CopyProgressData *progress = user_data; + CopyAsyncData *data = progress->data; + + data->progress_cb (progress->current_num_bytes, + progress->total_num_bytes, + data->progress_cb_data); + + return FALSE; +} + +static void +copy_async_progress_callback (goffset current_num_bytes, + goffset total_num_bytes, + gpointer user_data) +{ + GTask *task = user_data; + CopyAsyncData *data = g_task_get_task_data (task); + CopyProgressData *progress; + + progress = g_new (CopyProgressData, 1); + progress->data = data; + progress->current_num_bytes = current_num_bytes; + progress->total_num_bytes = total_num_bytes; + + g_main_context_invoke_full (g_task_get_context (task), + g_task_get_priority (task), + copy_async_progress_in_main, + progress, + g_free); +} + +static void +copy_async_thread (GTask *task, + gpointer source, + gpointer task_data, + GCancellable *cancellable) +{ + CopyAsyncData *data = task_data; + gboolean result; + GError *error = NULL; + + result = g_file_copy (data->source, + data->destination, + data->flags, + cancellable, + (data->progress_cb != NULL) ? copy_async_progress_callback : NULL, + task, + &error); + if (result) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +static void +g_file_real_copy_async (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + CopyAsyncData *data; + + data = g_slice_new (CopyAsyncData); + data->source = g_object_ref (source); + data->destination = g_object_ref (destination); + data->flags = flags; + data->progress_cb = progress_callback; + data->progress_cb_data = progress_callback_data; + + task = g_task_new (source, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_copy_async); + g_task_set_task_data (task, data, (GDestroyNotify)copy_async_data_free); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, copy_async_thread); + g_object_unref (task); +} + +static gboolean +g_file_real_copy_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, file), FALSE); + + return g_task_propagate_boolean (G_TASK (res), error); +} + + +/******************************************** + * Default VFS operations * + ********************************************/ + +/** + * g_file_new_for_path: + * @path: (type filename): a string containing a relative or absolute path. + * The string must be encoded in the glib filename encoding. + * + * Constructs a #GFile for a given path. This operation never + * fails, but the returned object might not support any I/O + * operation if @path is malformed. + * + * Returns: (transfer full): a new #GFile for the given @path. + * Free the returned object with g_object_unref(). + */ +GFile * +g_file_new_for_path (const char *path) +{ + g_return_val_if_fail (path != NULL, NULL); + + return g_vfs_get_file_for_path (g_vfs_get_default (), path); +} + +/** + * g_file_new_for_uri: + * @uri: a UTF-8 string containing a URI + * + * Constructs a #GFile for a given URI. This operation never + * fails, but the returned object might not support any I/O + * operation if @uri is malformed or if the uri type is + * not supported. + * + * Returns: (transfer full): a new #GFile for the given @uri. + * Free the returned object with g_object_unref(). + */ +GFile * +g_file_new_for_uri (const char *uri) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return g_vfs_get_file_for_uri (g_vfs_get_default (), uri); +} + +/** + * g_file_new_tmp: + * @tmpl: (type filename) (nullable): Template for the file + * name, as in g_file_open_tmp(), or %NULL for a default template + * @iostream: (out): on return, a #GFileIOStream for the created file + * @error: a #GError, or %NULL + * + * Opens a file in the preferred directory for temporary files (as + * returned by g_get_tmp_dir()) and returns a #GFile and + * #GFileIOStream pointing to it. + * + * @tmpl should be a string in the GLib file name encoding + * containing a sequence of six 'X' characters, and containing no + * directory components. If it is %NULL, a default template is used. + * + * Unlike the other #GFile constructors, this will return %NULL if + * a temporary file could not be created. + * + * Returns: (transfer full): a new #GFile. + * Free the returned object with g_object_unref(). + * + * Since: 2.32 + */ +GFile * +g_file_new_tmp (const char *tmpl, + GFileIOStream **iostream, + GError **error) +{ + gint fd; + gchar *path; + GFile *file; + GFileOutputStream *output; + + g_return_val_if_fail (iostream != NULL, NULL); + + fd = g_file_open_tmp (tmpl, &path, error); + if (fd == -1) + return NULL; + + file = g_file_new_for_path (path); + + output = _g_local_file_output_stream_new (fd); + *iostream = _g_local_file_io_stream_new (G_LOCAL_FILE_OUTPUT_STREAM (output)); + + g_object_unref (output); + g_free (path); + + return file; +} + +/** + * g_file_parse_name: + * @parse_name: a file name or path to be parsed + * + * Constructs a #GFile with the given @parse_name (i.e. something + * given by g_file_get_parse_name()). This operation never fails, + * but the returned object might not support any I/O operation if + * the @parse_name cannot be parsed. + * + * Returns: (transfer full): a new #GFile. + */ +GFile * +g_file_parse_name (const char *parse_name) +{ + g_return_val_if_fail (parse_name != NULL, NULL); + + return g_vfs_parse_name (g_vfs_get_default (), parse_name); +} + +/** + * g_file_new_build_filename: + * @first_element: (type filename): the first element in the path + * @...: remaining elements in path, terminated by %NULL + * + * Constructs a #GFile from a series of elements using the correct + * separator for filenames. + * + * Using this function is equivalent to calling g_build_filename(), + * followed by g_file_new_for_path() on the result. + * + * Returns: (transfer full): a new #GFile + * + * Since: 2.56 + */ +GFile * +g_file_new_build_filename (const gchar *first_element, + ...) +{ + gchar *str; + GFile *file; + va_list args; + + g_return_val_if_fail (first_element != NULL, NULL); + + va_start (args, first_element); + str = g_build_filename_valist (first_element, &args); + va_end (args); + + file = g_file_new_for_path (str); + g_free (str); + + return file; +} + +static gboolean +is_valid_scheme_character (char c) +{ + return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.'; +} + +/* Following RFC 2396, valid schemes are built like: + * scheme = alpha *( alpha | digit | "+" | "-" | "." ) + */ +static gboolean +has_valid_scheme (const char *uri) +{ + const char *p; + + p = uri; + + if (!g_ascii_isalpha (*p)) + return FALSE; + + do { + p++; + } while (is_valid_scheme_character (*p)); + + return *p == ':'; +} + +static GFile * +new_for_cmdline_arg (const gchar *arg, + const gchar *cwd) +{ + GFile *file; + char *filename; + + if (g_path_is_absolute (arg)) + return g_file_new_for_path (arg); + + if (has_valid_scheme (arg)) + return g_file_new_for_uri (arg); + + if (cwd == NULL) + { + char *current_dir; + + current_dir = g_get_current_dir (); + filename = g_build_filename (current_dir, arg, NULL); + g_free (current_dir); + } + else + filename = g_build_filename (cwd, arg, NULL); + + file = g_file_new_for_path (filename); + g_free (filename); + + return file; +} + +/** + * g_file_new_for_commandline_arg: + * @arg: (type filename): a command line string + * + * Creates a #GFile with the given argument from the command line. + * The value of @arg can be either a URI, an absolute path or a + * relative path resolved relative to the current working directory. + * This operation never fails, but the returned object might not + * support any I/O operation if @arg points to a malformed path. + * + * Note that on Windows, this function expects its argument to be in + * UTF-8 -- not the system code page. This means that you + * should not use this function with string from argv as it is passed + * to main(). g_win32_get_command_line() will return a UTF-8 version of + * the commandline. #GApplication also uses UTF-8 but + * g_application_command_line_create_file_for_arg() may be more useful + * for you there. It is also always possible to use this function with + * #GOptionContext arguments of type %G_OPTION_ARG_FILENAME. + * + * Returns: (transfer full): a new #GFile. + * Free the returned object with g_object_unref(). + */ +GFile * +g_file_new_for_commandline_arg (const char *arg) +{ + g_return_val_if_fail (arg != NULL, NULL); + + return new_for_cmdline_arg (arg, NULL); +} + +/** + * g_file_new_for_commandline_arg_and_cwd: + * @arg: (type filename): a command line string + * @cwd: (type filename): the current working directory of the commandline + * + * Creates a #GFile with the given argument from the command line. + * + * This function is similar to g_file_new_for_commandline_arg() except + * that it allows for passing the current working directory as an + * argument instead of using the current working directory of the + * process. + * + * This is useful if the commandline argument was given in a context + * other than the invocation of the current process. + * + * See also g_application_command_line_create_file_for_arg(). + * + * Returns: (transfer full): a new #GFile + * + * Since: 2.36 + **/ +GFile * +g_file_new_for_commandline_arg_and_cwd (const gchar *arg, + const gchar *cwd) +{ + g_return_val_if_fail (arg != NULL, NULL); + g_return_val_if_fail (cwd != NULL, NULL); + + return new_for_cmdline_arg (arg, cwd); +} + +/** + * g_file_mount_enclosing_volume: + * @location: input #GFile + * @flags: flags affecting the operation + * @mount_operation: (nullable): a #GMountOperation + * or %NULL to avoid user interaction + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (nullable): a #GAsyncReadyCallback to call + * when the request is satisfied, or %NULL + * @user_data: the data to pass to callback function + * + * Starts a @mount_operation, mounting the volume that contains + * the file @location. + * + * When this operation has completed, @callback will be called with + * @user_user data, and the operation can be finalized with + * g_file_mount_enclosing_volume_finish(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + */ +void +g_file_mount_enclosing_volume (GFile *location, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (location)); + + iface = G_FILE_GET_IFACE (location); + + if (iface->mount_enclosing_volume == NULL) + { + g_task_report_new_error (location, callback, user_data, + g_file_mount_enclosing_volume, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("volume doesn’t implement mount")); + return; + } + + (* iface->mount_enclosing_volume) (location, flags, mount_operation, cancellable, callback, user_data); + +} + +/** + * g_file_mount_enclosing_volume_finish: + * @location: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes a mount operation started by g_file_mount_enclosing_volume(). + * + * Returns: %TRUE if successful. If an error has occurred, + * this function will return %FALSE and set @error + * appropriately if present. + */ +gboolean +g_file_mount_enclosing_volume_finish (GFile *location, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (location), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_mount_enclosing_volume)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (location); + + return (* iface->mount_enclosing_volume_finish) (location, result, error); +} + +/******************************************** + * Utility functions * + ********************************************/ + +/** + * g_file_query_default_handler: + * @file: a #GFile to open + * @cancellable: optional #GCancellable object, %NULL to ignore + * @error: a #GError, or %NULL + * + * Returns the #GAppInfo that is registered as the default + * application to handle the file specified by @file. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (transfer full): a #GAppInfo if the handle was found, + * %NULL if there were errors. + * When you are done with it, release it with g_object_unref() + */ +GAppInfo * +g_file_query_default_handler (GFile *file, + GCancellable *cancellable, + GError **error) +{ + char *uri_scheme; + const char *content_type; + GAppInfo *appinfo; + GFileInfo *info; + char *path; + + uri_scheme = g_file_get_uri_scheme (file); + if (uri_scheme && uri_scheme[0] != '\0') + { + appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme); + g_free (uri_scheme); + + if (appinfo != NULL) + return appinfo; + } + else + g_free (uri_scheme); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, + 0, + cancellable, + error); + if (info == NULL) + return NULL; + + appinfo = NULL; + + content_type = g_file_info_get_content_type (info); + if (content_type == NULL) + content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE); + if (content_type) + { + /* Don't use is_native(), as we want to support fuse paths if available */ + path = g_file_get_path (file); + appinfo = g_app_info_get_default_for_type (content_type, + path == NULL); + g_free (path); + } + + g_object_unref (info); + + if (appinfo != NULL) + return appinfo; + + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("No application is registered as handling this file")); + return NULL; +} + +static void +query_default_handler_query_info_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GFile *file = G_FILE (object); + GTask *task = G_TASK (user_data); + GError *error = NULL; + GFileInfo *info; + const char *content_type; + GAppInfo *appinfo = NULL; + + info = g_file_query_info_finish (file, result, &error); + if (info == NULL) + { + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + return; + } + + content_type = g_file_info_get_content_type (info); + if (content_type == NULL) + content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE); + if (content_type) + { + char *path; + + /* Don't use is_native(), as we want to support fuse paths if available */ + path = g_file_get_path (file); + + /* FIXME: The following still uses blocking calls. */ + appinfo = g_app_info_get_default_for_type (content_type, + path == NULL); + g_free (path); + } + + g_object_unref (info); + + if (appinfo != NULL) + g_task_return_pointer (task, g_steal_pointer (&appinfo), g_object_unref); + else + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("No application is registered as handling this file")); + g_object_unref (task); +} + +/** + * g_file_query_default_handler_async: + * @file: a #GFile to open + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: optional #GCancellable object, %NULL to ignore + * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done + * @user_data: (nullable): data to pass to @callback + * + * Async version of g_file_query_default_handler(). + * + * Since: 2.60 + */ +void +g_file_query_default_handler_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + char *uri_scheme; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_query_default_handler_async); + + uri_scheme = g_file_get_uri_scheme (file); + if (uri_scheme && uri_scheme[0] != '\0') + { + GAppInfo *appinfo; + + /* FIXME: The following still uses blocking calls. */ + appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme); + g_free (uri_scheme); + + if (appinfo != NULL) + { + g_task_return_pointer (task, g_steal_pointer (&appinfo), g_object_unref); + g_object_unref (task); + return; + } + } + else + g_free (uri_scheme); + + g_file_query_info_async (file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, + 0, + io_priority, + cancellable, + query_default_handler_query_info_cb, + g_steal_pointer (&task)); +} + +/** + * g_file_query_default_handler_finish: + * @file: a #GFile to open + * @result: a #GAsyncResult + * @error: (nullable): a #GError + * + * Finishes a g_file_query_default_handler_async() operation. + * + * Returns: (transfer full): a #GAppInfo if the handle was found, + * %NULL if there were errors. + * When you are done with it, release it with g_object_unref() + * + * Since: 2.60 + */ +GAppInfo * +g_file_query_default_handler_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (g_task_is_valid (result, file), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +#define GET_CONTENT_BLOCK_SIZE 8192 + +/** + * g_file_load_contents: + * @file: input #GFile + * @cancellable: optional #GCancellable object, %NULL to ignore + * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file + * @length: (out) (optional): a location to place the length of the contents of the file, + * or %NULL if the length is not needed + * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file, + * or %NULL if the entity tag is not needed + * @error: a #GError, or %NULL + * + * Loads the content of the file into memory. The data is always + * zero-terminated, but this is not included in the resultant @length. + * The returned @contents should be freed with g_free() when no longer + * needed. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if the @file's contents were successfully loaded. + * %FALSE if there were errors. + */ +gboolean +g_file_load_contents (GFile *file, + GCancellable *cancellable, + char **contents, + gsize *length, + char **etag_out, + GError **error) +{ + GFileInputStream *in; + GByteArray *content; + gsize pos; + gssize res; + GFileInfo *info; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (contents != NULL, FALSE); + + in = g_file_read (file, cancellable, error); + if (in == NULL) + return FALSE; + + content = g_byte_array_new (); + pos = 0; + + g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1); + while ((res = g_input_stream_read (G_INPUT_STREAM (in), + content->data + pos, + GET_CONTENT_BLOCK_SIZE, + cancellable, error)) > 0) + { + pos += res; + g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1); + } + + if (etag_out) + { + *etag_out = NULL; + + info = g_file_input_stream_query_info (in, + G_FILE_ATTRIBUTE_ETAG_VALUE, + cancellable, + NULL); + if (info) + { + *etag_out = g_strdup (g_file_info_get_etag (info)); + g_object_unref (info); + } + } + + /* Ignore errors on close */ + g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL); + g_object_unref (in); + + if (res < 0) + { + /* error is set already */ + g_byte_array_free (content, TRUE); + return FALSE; + } + + if (length) + *length = pos; + + /* Zero terminate (we got an extra byte allocated for this */ + content->data[pos] = 0; + + *contents = (char *)g_byte_array_free (content, FALSE); + + return TRUE; +} + +typedef struct { + GTask *task; + GFileReadMoreCallback read_more_callback; + GByteArray *content; + gsize pos; + char *etag; +} LoadContentsData; + + +static void +load_contents_data_free (LoadContentsData *data) +{ + if (data->content) + g_byte_array_free (data->content, TRUE); + g_free (data->etag); + g_free (data); +} + +static void +load_contents_close_callback (GObject *obj, + GAsyncResult *close_res, + gpointer user_data) +{ + GInputStream *stream = G_INPUT_STREAM (obj); + LoadContentsData *data = user_data; + + /* Ignore errors here, we're only reading anyway */ + g_input_stream_close_finish (stream, close_res, NULL); + g_object_unref (stream); + + g_task_return_boolean (data->task, TRUE); + g_object_unref (data->task); +} + +static void +load_contents_fstat_callback (GObject *obj, + GAsyncResult *stat_res, + gpointer user_data) +{ + GInputStream *stream = G_INPUT_STREAM (obj); + LoadContentsData *data = user_data; + GFileInfo *info; + + info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream), + stat_res, NULL); + if (info) + { + data->etag = g_strdup (g_file_info_get_etag (info)); + g_object_unref (info); + } + + g_input_stream_close_async (stream, 0, + g_task_get_cancellable (data->task), + load_contents_close_callback, data); +} + +static void +load_contents_read_callback (GObject *obj, + GAsyncResult *read_res, + gpointer user_data) +{ + GInputStream *stream = G_INPUT_STREAM (obj); + LoadContentsData *data = user_data; + GError *error = NULL; + gssize read_size; + + read_size = g_input_stream_read_finish (stream, read_res, &error); + + if (read_size < 0) + { + g_task_return_error (data->task, error); + g_object_unref (data->task); + + /* Close the file ignoring any error */ + g_input_stream_close_async (stream, 0, NULL, NULL, NULL); + g_object_unref (stream); + } + else if (read_size == 0) + { + g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream), + G_FILE_ATTRIBUTE_ETAG_VALUE, + 0, + g_task_get_cancellable (data->task), + load_contents_fstat_callback, + data); + } + else if (read_size > 0) + { + data->pos += read_size; + + g_byte_array_set_size (data->content, + data->pos + GET_CONTENT_BLOCK_SIZE); + + + if (data->read_more_callback && + !data->read_more_callback ((char *)data->content->data, data->pos, + g_async_result_get_user_data (G_ASYNC_RESULT (data->task)))) + g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream), + G_FILE_ATTRIBUTE_ETAG_VALUE, + 0, + g_task_get_cancellable (data->task), + load_contents_fstat_callback, + data); + else + g_input_stream_read_async (stream, + data->content->data + data->pos, + GET_CONTENT_BLOCK_SIZE, + 0, + g_task_get_cancellable (data->task), + load_contents_read_callback, + data); + } +} + +static void +load_contents_open_callback (GObject *obj, + GAsyncResult *open_res, + gpointer user_data) +{ + GFile *file = G_FILE (obj); + GFileInputStream *stream; + LoadContentsData *data = user_data; + GError *error = NULL; + + stream = g_file_read_finish (file, open_res, &error); + + if (stream) + { + g_byte_array_set_size (data->content, + data->pos + GET_CONTENT_BLOCK_SIZE); + g_input_stream_read_async (G_INPUT_STREAM (stream), + data->content->data + data->pos, + GET_CONTENT_BLOCK_SIZE, + 0, + g_task_get_cancellable (data->task), + load_contents_read_callback, + data); + } + else + { + g_task_return_error (data->task, error); + g_object_unref (data->task); + } +} + +/** + * g_file_load_partial_contents_async: (skip) + * @file: input #GFile + * @cancellable: optional #GCancellable object, %NULL to ignore + * @read_more_callback: (scope call) (closure user_data): a + * #GFileReadMoreCallback to receive partial data + * and to specify whether further data should be read + * @callback: (scope async) (closure user_data): a #GAsyncReadyCallback to call + * when the request is satisfied + * @user_data: the data to pass to the callback functions + * + * Reads the partial contents of a file. A #GFileReadMoreCallback should + * be used to stop reading from the file when appropriate, else this + * function will behave exactly as g_file_load_contents_async(). This + * operation can be finished by g_file_load_partial_contents_finish(). + * + * Users of this function should be aware that @user_data is passed to + * both the @read_more_callback and the @callback. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + */ +void +g_file_load_partial_contents_async (GFile *file, + GCancellable *cancellable, + GFileReadMoreCallback read_more_callback, + GAsyncReadyCallback callback, + gpointer user_data) +{ + LoadContentsData *data; + + g_return_if_fail (G_IS_FILE (file)); + + data = g_new0 (LoadContentsData, 1); + data->read_more_callback = read_more_callback; + data->content = g_byte_array_new (); + + data->task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (data->task, g_file_load_partial_contents_async); + g_task_set_task_data (data->task, data, (GDestroyNotify)load_contents_data_free); + + g_file_read_async (file, + 0, + g_task_get_cancellable (data->task), + load_contents_open_callback, + data); +} + +/** + * g_file_load_partial_contents_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file + * @length: (out) (optional): a location to place the length of the contents of the file, + * or %NULL if the length is not needed + * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file, + * or %NULL if the entity tag is not needed + * @error: a #GError, or %NULL + * + * Finishes an asynchronous partial load operation that was started + * with g_file_load_partial_contents_async(). The data is always + * zero-terminated, but this is not included in the resultant @length. + * The returned @contents should be freed with g_free() when no longer + * needed. + * + * Returns: %TRUE if the load was successful. If %FALSE and @error is + * present, it will be set appropriately. + */ +gboolean +g_file_load_partial_contents_finish (GFile *file, + GAsyncResult *res, + char **contents, + gsize *length, + char **etag_out, + GError **error) +{ + GTask *task; + LoadContentsData *data; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (g_task_is_valid (res, file), FALSE); + g_return_val_if_fail (contents != NULL, FALSE); + + task = G_TASK (res); + + if (!g_task_propagate_boolean (task, error)) + { + if (length) + *length = 0; + return FALSE; + } + + data = g_task_get_task_data (task); + + if (length) + *length = data->pos; + + if (etag_out) + { + *etag_out = data->etag; + data->etag = NULL; + } + + /* Zero terminate */ + g_byte_array_set_size (data->content, data->pos + 1); + data->content->data[data->pos] = 0; + + *contents = (char *)g_byte_array_free (data->content, FALSE); + data->content = NULL; + + return TRUE; +} + +/** + * g_file_load_contents_async: + * @file: input #GFile + * @cancellable: optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to callback function + * + * Starts an asynchronous load of the @file's contents. + * + * For more details, see g_file_load_contents() which is + * the synchronous version of this call. + * + * When the load operation has completed, @callback will be called + * with @user data. To finish the operation, call + * g_file_load_contents_finish() with the #GAsyncResult returned by + * the @callback. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + */ +void +g_file_load_contents_async (GFile *file, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_file_load_partial_contents_async (file, + cancellable, + NULL, + callback, user_data); +} + +/** + * g_file_load_contents_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file + * @length: (out) (optional): a location to place the length of the contents of the file, + * or %NULL if the length is not needed + * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file, + * or %NULL if the entity tag is not needed + * @error: a #GError, or %NULL + * + * Finishes an asynchronous load of the @file's contents. + * The contents are placed in @contents, and @length is set to the + * size of the @contents string. The @contents should be freed with + * g_free() when no longer needed. If @etag_out is present, it will be + * set to the new entity tag for the @file. + * + * Returns: %TRUE if the load was successful. If %FALSE and @error is + * present, it will be set appropriately. + */ +gboolean +g_file_load_contents_finish (GFile *file, + GAsyncResult *res, + char **contents, + gsize *length, + char **etag_out, + GError **error) +{ + return g_file_load_partial_contents_finish (file, + res, + contents, + length, + etag_out, + error); +} + +/** + * g_file_replace_contents: + * @file: input #GFile + * @contents: (element-type guint8) (array length=length): a string containing the new contents for @file + * @length: the length of @contents in bytes + * @etag: (nullable): the old [entity-tag][gfile-etag] for the document, + * or %NULL + * @make_backup: %TRUE if a backup should be created + * @flags: a set of #GFileCreateFlags + * @new_etag: (out) (optional) (nullable): a location to a new [entity tag][gfile-etag] + * for the document. This should be freed with g_free() when no longer + * needed, or %NULL + * @cancellable: optional #GCancellable object, %NULL to ignore + * @error: a #GError, or %NULL + * + * Replaces the contents of @file with @contents of @length bytes. + * + * If @etag is specified (not %NULL), any existing file must have that etag, + * or the error %G_IO_ERROR_WRONG_ETAG will be returned. + * + * If @make_backup is %TRUE, this function will attempt to make a backup + * of @file. Internally, it uses g_file_replace(), so will try to replace the + * file contents in the safest way possible. For example, atomic renames are + * used when replacing local files’ contents. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * The returned @new_etag can be used to verify that the file hasn't + * changed the next time it is saved over. + * + * Returns: %TRUE if successful. If an error has occurred, this function + * will return %FALSE and set @error appropriately if present. + */ +gboolean +g_file_replace_contents (GFile *file, + const char *contents, + gsize length, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + char **new_etag, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStream *out; + gsize pos, remainder; + gssize res; + gboolean ret; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (contents != NULL, FALSE); + + out = g_file_replace (file, etag, make_backup, flags, cancellable, error); + if (out == NULL) + return FALSE; + + pos = 0; + remainder = length; + while (remainder > 0 && + (res = g_output_stream_write (G_OUTPUT_STREAM (out), + contents + pos, + MIN (remainder, GET_CONTENT_BLOCK_SIZE), + cancellable, + error)) > 0) + { + pos += res; + remainder -= res; + } + + if (remainder > 0 && res < 0) + { + /* Ignore errors on close */ + g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL); + g_object_unref (out); + + /* error is set already */ + return FALSE; + } + + ret = g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error); + + if (new_etag) + *new_etag = g_file_output_stream_get_etag (out); + + g_object_unref (out); + + return ret; +} + +typedef struct { + GTask *task; + GBytes *content; + gsize pos; + char *etag; + gboolean failed; +} ReplaceContentsData; + +static void +replace_contents_data_free (ReplaceContentsData *data) +{ + g_bytes_unref (data->content); + g_free (data->etag); + g_free (data); +} + +static void +replace_contents_close_callback (GObject *obj, + GAsyncResult *close_res, + gpointer user_data) +{ + GOutputStream *stream = G_OUTPUT_STREAM (obj); + ReplaceContentsData *data = user_data; + + /* Ignore errors here, we're only reading anyway */ + g_output_stream_close_finish (stream, close_res, NULL); + + if (!data->failed) + { + data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream)); + g_task_return_boolean (data->task, TRUE); + } + g_object_unref (data->task); +} + +static void +replace_contents_write_callback (GObject *obj, + GAsyncResult *read_res, + gpointer user_data) +{ + GOutputStream *stream = G_OUTPUT_STREAM (obj); + ReplaceContentsData *data = user_data; + GError *error = NULL; + gssize write_size; + + write_size = g_output_stream_write_finish (stream, read_res, &error); + + if (write_size <= 0) + { + /* Error or EOF, close the file */ + if (write_size < 0) + { + data->failed = TRUE; + g_task_return_error (data->task, error); + } + g_output_stream_close_async (stream, 0, + g_task_get_cancellable (data->task), + replace_contents_close_callback, data); + } + else if (write_size > 0) + { + const gchar *content; + gsize length; + + content = g_bytes_get_data (data->content, &length); + data->pos += write_size; + + if (data->pos >= length) + g_output_stream_close_async (stream, 0, + g_task_get_cancellable (data->task), + replace_contents_close_callback, data); + else + g_output_stream_write_async (stream, + content + data->pos, + length - data->pos, + 0, + g_task_get_cancellable (data->task), + replace_contents_write_callback, + data); + } +} + +static void +replace_contents_open_callback (GObject *obj, + GAsyncResult *open_res, + gpointer user_data) +{ + GFile *file = G_FILE (obj); + GFileOutputStream *stream; + ReplaceContentsData *data = user_data; + GError *error = NULL; + + stream = g_file_replace_finish (file, open_res, &error); + + if (stream) + { + const gchar *content; + gsize length; + + content = g_bytes_get_data (data->content, &length); + g_output_stream_write_async (G_OUTPUT_STREAM (stream), + content + data->pos, + length - data->pos, + 0, + g_task_get_cancellable (data->task), + replace_contents_write_callback, + data); + g_object_unref (stream); /* ownership is transferred to the write_async() call above */ + } + else + { + g_task_return_error (data->task, error); + g_object_unref (data->task); + } +} + +/** + * g_file_replace_contents_async: + * @file: input #GFile + * @contents: (element-type guint8) (array length=length): string of contents to replace the file with + * @length: the length of @contents in bytes + * @etag: (nullable): a new [entity tag][gfile-etag] for the @file, or %NULL + * @make_backup: %TRUE if a backup should be created + * @flags: a set of #GFileCreateFlags + * @cancellable: optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to callback function + * + * Starts an asynchronous replacement of @file with the given + * @contents of @length bytes. @etag will replace the document's + * current entity tag. + * + * When this operation has completed, @callback will be called with + * @user_user data, and the operation can be finalized with + * g_file_replace_contents_finish(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * If @make_backup is %TRUE, this function will attempt to + * make a backup of @file. + * + * Note that no copy of @contents will be made, so it must stay valid + * until @callback is called. See g_file_replace_contents_bytes_async() + * for a #GBytes version that will automatically hold a reference to the + * contents (without copying) for the duration of the call. + */ +void +g_file_replace_contents_async (GFile *file, + const char *contents, + gsize length, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GBytes *bytes; + + bytes = g_bytes_new_static (contents, length); + g_file_replace_contents_bytes_async (file, bytes, etag, make_backup, flags, + cancellable, callback, user_data); + g_bytes_unref (bytes); +} + +/** + * g_file_replace_contents_bytes_async: + * @file: input #GFile + * @contents: a #GBytes + * @etag: (nullable): a new [entity tag][gfile-etag] for the @file, or %NULL + * @make_backup: %TRUE if a backup should be created + * @flags: a set of #GFileCreateFlags + * @cancellable: optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to callback function + * + * Same as g_file_replace_contents_async() but takes a #GBytes input instead. + * This function will keep a ref on @contents until the operation is done. + * Unlike g_file_replace_contents_async() this allows forgetting about the + * content without waiting for the callback. + * + * When this operation has completed, @callback will be called with + * @user_user data, and the operation can be finalized with + * g_file_replace_contents_finish(). + * + * Since: 2.40 + */ +void +g_file_replace_contents_bytes_async (GFile *file, + GBytes *contents, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + ReplaceContentsData *data; + + g_return_if_fail (G_IS_FILE (file)); + g_return_if_fail (contents != NULL); + + data = g_new0 (ReplaceContentsData, 1); + + data->content = g_bytes_ref (contents); + + data->task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (data->task, g_file_replace_contents_bytes_async); + g_task_set_task_data (data->task, data, (GDestroyNotify)replace_contents_data_free); + + g_file_replace_async (file, + etag, + make_backup, + flags, + 0, + g_task_get_cancellable (data->task), + replace_contents_open_callback, + data); +} + +/** + * g_file_replace_contents_finish: + * @file: input #GFile + * @res: a #GAsyncResult + * @new_etag: (out) (optional) (nullable): a location of a new [entity tag][gfile-etag] + * for the document. This should be freed with g_free() when it is no + * longer needed, or %NULL + * @error: a #GError, or %NULL + * + * Finishes an asynchronous replace of the given @file. See + * g_file_replace_contents_async(). Sets @new_etag to the new entity + * tag for the document, if present. + * + * Returns: %TRUE on success, %FALSE on failure. + */ +gboolean +g_file_replace_contents_finish (GFile *file, + GAsyncResult *res, + char **new_etag, + GError **error) +{ + GTask *task; + ReplaceContentsData *data; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (g_task_is_valid (res, file), FALSE); + + task = G_TASK (res); + + if (!g_task_propagate_boolean (task, error)) + return FALSE; + + data = g_task_get_task_data (task); + + if (new_etag) + { + *new_etag = data->etag; + data->etag = NULL; /* Take ownership */ + } + + return TRUE; +} + +gboolean +g_file_real_measure_disk_usage (GFile *file, + GFileMeasureFlags flags, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error) +{ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Operation not supported for the current backend."); + return FALSE; +} + +typedef struct +{ + GFileMeasureFlags flags; + GFileMeasureProgressCallback progress_callback; + gpointer progress_data; +} MeasureTaskData; + +typedef struct +{ + guint64 disk_usage; + guint64 num_dirs; + guint64 num_files; +} MeasureResult; + +typedef struct +{ + GFileMeasureProgressCallback callback; + gpointer user_data; + gboolean reporting; + guint64 current_size; + guint64 num_dirs; + guint64 num_files; +} MeasureProgress; + +static gboolean +measure_disk_usage_invoke_progress (gpointer user_data) +{ + MeasureProgress *progress = user_data; + + (* progress->callback) (progress->reporting, + progress->current_size, progress->num_dirs, progress->num_files, + progress->user_data); + + return FALSE; +} + +static void +measure_disk_usage_progress (gboolean reporting, + guint64 current_size, + guint64 num_dirs, + guint64 num_files, + gpointer user_data) +{ + MeasureProgress progress; + GTask *task = user_data; + MeasureTaskData *data; + + data = g_task_get_task_data (task); + + progress.callback = data->progress_callback; + progress.user_data = data->progress_data; + progress.reporting = reporting; + progress.current_size = current_size; + progress.num_dirs = num_dirs; + progress.num_files = num_files; + + g_main_context_invoke_full (g_task_get_context (task), + g_task_get_priority (task), + measure_disk_usage_invoke_progress, + g_memdup2 (&progress, sizeof progress), + g_free); +} + +static void +measure_disk_usage_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + MeasureTaskData *data = task_data; + GError *error = NULL; + MeasureResult result = { 0, }; + + if (g_file_measure_disk_usage (source_object, data->flags, cancellable, + data->progress_callback ? measure_disk_usage_progress : NULL, task, + &result.disk_usage, &result.num_dirs, &result.num_files, + &error)) + g_task_return_pointer (task, g_memdup2 (&result, sizeof result), g_free); + else + g_task_return_error (task, error); +} + +static void +g_file_real_measure_disk_usage_async (GFile *file, + GFileMeasureFlags flags, + gint io_priority, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MeasureTaskData data; + GTask *task; + + data.flags = flags; + data.progress_callback = progress_callback; + data.progress_data = progress_data; + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_real_measure_disk_usage_async); + g_task_set_task_data (task, g_memdup2 (&data, sizeof data), g_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, measure_disk_usage_thread); + g_object_unref (task); +} + +static gboolean +g_file_real_measure_disk_usage_finish (GFile *file, + GAsyncResult *result, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error) +{ + MeasureResult *measure_result; + + g_return_val_if_fail (g_task_is_valid (result, file), FALSE); + + measure_result = g_task_propagate_pointer (G_TASK (result), error); + + if (measure_result == NULL) + return FALSE; + + if (disk_usage) + *disk_usage = measure_result->disk_usage; + + if (num_dirs) + *num_dirs = measure_result->num_dirs; + + if (num_files) + *num_files = measure_result->num_files; + + g_free (measure_result); + + return TRUE; +} + +/** + * g_file_measure_disk_usage: + * @file: a #GFile + * @flags: #GFileMeasureFlags + * @cancellable: (nullable): optional #GCancellable + * @progress_callback: (nullable): a #GFileMeasureProgressCallback + * @progress_data: user_data for @progress_callback + * @disk_usage: (out) (optional): the number of bytes of disk space used + * @num_dirs: (out) (optional): the number of directories encountered + * @num_files: (out) (optional): the number of non-directories encountered + * @error: (nullable): %NULL, or a pointer to a %NULL #GError pointer + * + * Recursively measures the disk usage of @file. + * + * This is essentially an analog of the 'du' command, but it also + * reports the number of directories and non-directory files encountered + * (including things like symbolic links). + * + * By default, errors are only reported against the toplevel file + * itself. Errors found while recursing are silently ignored, unless + * %G_FILE_MEASURE_REPORT_ANY_ERROR is given in @flags. + * + * The returned size, @disk_usage, is in bytes and should be formatted + * with g_format_size() in order to get something reasonable for showing + * in a user interface. + * + * @progress_callback and @progress_data can be given to request + * periodic progress updates while scanning. See the documentation for + * #GFileMeasureProgressCallback for information about when and how the + * callback will be invoked. + * + * Returns: %TRUE if successful, with the out parameters set. + * %FALSE otherwise, with @error set. + * + * Since: 2.38 + **/ +gboolean +g_file_measure_disk_usage (GFile *file, + GFileMeasureFlags flags, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error) +{ + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return G_FILE_GET_IFACE (file)->measure_disk_usage (file, flags, cancellable, + progress_callback, progress_data, + disk_usage, num_dirs, num_files, + error); +} + +/** + * g_file_measure_disk_usage_async: + * @file: a #GFile + * @flags: #GFileMeasureFlags + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable + * @progress_callback: (nullable): a #GFileMeasureProgressCallback + * @progress_data: user_data for @progress_callback + * @callback: (nullable): a #GAsyncReadyCallback to call when complete + * @user_data: the data to pass to callback function + * + * Recursively measures the disk usage of @file. + * + * This is the asynchronous version of g_file_measure_disk_usage(). See + * there for more information. + * + * Since: 2.38 + **/ +void +g_file_measure_disk_usage_async (GFile *file, + GFileMeasureFlags flags, + gint io_priority, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_FILE (file)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + G_FILE_GET_IFACE (file)->measure_disk_usage_async (file, flags, io_priority, cancellable, + progress_callback, progress_data, + callback, user_data); +} + +/** + * g_file_measure_disk_usage_finish: + * @file: a #GFile + * @result: the #GAsyncResult passed to your #GAsyncReadyCallback + * @disk_usage: (out) (optional): the number of bytes of disk space used + * @num_dirs: (out) (optional): the number of directories encountered + * @num_files: (out) (optional): the number of non-directories encountered + * @error: (nullable): %NULL, or a pointer to a %NULL #GError pointer + * + * Collects the results from an earlier call to + * g_file_measure_disk_usage_async(). See g_file_measure_disk_usage() for + * more information. + * + * Returns: %TRUE if successful, with the out parameters set. + * %FALSE otherwise, with @error set. + * + * Since: 2.38 + **/ +gboolean +g_file_measure_disk_usage_finish (GFile *file, + GAsyncResult *result, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error) +{ + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return G_FILE_GET_IFACE (file)->measure_disk_usage_finish (file, result, disk_usage, num_dirs, num_files, error); +} + +/** + * g_file_start_mountable: + * @file: input #GFile + * @flags: flags affecting the operation + * @start_operation: (nullable): a #GMountOperation, or %NULL to avoid user interaction + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: (nullable): a #GAsyncReadyCallback to call when the request is satisfied, or %NULL + * @user_data: the data to pass to callback function + * + * Starts a file of type %G_FILE_TYPE_MOUNTABLE. + * Using @start_operation, you can request callbacks when, for instance, + * passwords are needed during authentication. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_mount_mountable_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_file_start_mountable (GFile *file, + GDriveStartFlags flags, + GMountOperation *start_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + + if (iface->start_mountable == NULL) + { + g_task_report_new_error (file, callback, user_data, + g_file_start_mountable, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return; + } + + (* iface->start_mountable) (file, + flags, + start_operation, + cancellable, + callback, + user_data); +} + +/** + * g_file_start_mountable_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes a start operation. See g_file_start_mountable() for details. + * + * Finish an asynchronous start operation that was started + * with g_file_start_mountable(). + * + * Returns: %TRUE if the operation finished successfully. %FALSE + * otherwise. + * + * Since: 2.22 + */ +gboolean +g_file_start_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_start_mountable)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (file); + return (* iface->start_mountable_finish) (file, result, error); +} + +/** + * g_file_stop_mountable: + * @file: input #GFile + * @flags: flags affecting the operation + * @mount_operation: (nullable): a #GMountOperation, + * or %NULL to avoid user interaction. + * @cancellable: (nullable): optional #GCancellable object, + * %NULL to ignore + * @callback: (nullable): a #GAsyncReadyCallback to call + * when the request is satisfied, or %NULL + * @user_data: the data to pass to callback function + * + * Stops a file of type %G_FILE_TYPE_MOUNTABLE. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_stop_mountable_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_file_stop_mountable (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + + if (iface->stop_mountable == NULL) + { + g_task_report_new_error (file, callback, user_data, + g_file_stop_mountable, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return; + } + + (* iface->stop_mountable) (file, + flags, + mount_operation, + cancellable, + callback, + user_data); +} + +/** + * g_file_stop_mountable_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes a stop operation, see g_file_stop_mountable() for details. + * + * Finish an asynchronous stop operation that was started + * with g_file_stop_mountable(). + * + * Returns: %TRUE if the operation finished successfully. + * %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_file_stop_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_stop_mountable)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (file); + return (* iface->stop_mountable_finish) (file, result, error); +} + +/** + * g_file_poll_mountable: + * @file: input #GFile + * @cancellable: optional #GCancellable object, %NULL to ignore + * @callback: (nullable): a #GAsyncReadyCallback to call + * when the request is satisfied, or %NULL + * @user_data: the data to pass to callback function + * + * Polls a file of type %G_FILE_TYPE_MOUNTABLE. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * When the operation is finished, @callback will be called. + * You can then call g_file_mount_mountable_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_file_poll_mountable (GFile *file, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + + if (iface->poll_mountable == NULL) + { + g_task_report_new_error (file, callback, user_data, + g_file_poll_mountable, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + return; + } + + (* iface->poll_mountable) (file, + cancellable, + callback, + user_data); +} + +/** + * g_file_poll_mountable_finish: + * @file: input #GFile + * @result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes a poll operation. See g_file_poll_mountable() for details. + * + * Finish an asynchronous poll operation that was polled + * with g_file_poll_mountable(). + * + * Returns: %TRUE if the operation finished successfully. %FALSE + * otherwise. + * + * Since: 2.22 + */ +gboolean +g_file_poll_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_poll_mountable)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_FILE_GET_IFACE (file); + return (* iface->poll_mountable_finish) (file, result, error); +} + +/** + * g_file_supports_thread_contexts: + * @file: a #GFile + * + * Checks if @file supports + * [thread-default contexts][g-main-context-push-thread-default-context]. + * If this returns %FALSE, you cannot perform asynchronous operations on + * @file in a thread that has a thread-default context. + * + * Returns: Whether or not @file supports thread-default contexts. + * + * Since: 2.22 + */ +gboolean +g_file_supports_thread_contexts (GFile *file) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + + iface = G_FILE_GET_IFACE (file); + return iface->supports_thread_contexts; +} + +/** + * g_file_load_bytes: + * @file: a #GFile + * @cancellable: (nullable): a #GCancellable or %NULL + * @etag_out: (out) (nullable) (optional): a location to place the current + * entity tag for the file, or %NULL if the entity tag is not needed + * @error: a location for a #GError or %NULL + * + * Loads the contents of @file and returns it as #GBytes. + * + * If @file is a resource:// based URI, the resulting bytes will reference the + * embedded resource instead of a copy. Otherwise, this is equivalent to calling + * g_file_load_contents() and g_bytes_new_take(). + * + * For resources, @etag_out will be set to %NULL. + * + * The data contained in the resulting #GBytes is always zero-terminated, but + * this is not included in the #GBytes length. The resulting #GBytes should be + * freed with g_bytes_unref() when no longer in use. + * + * Returns: (transfer full): a #GBytes or %NULL and @error is set + * + * Since: 2.56 + */ +GBytes * +g_file_load_bytes (GFile *file, + GCancellable *cancellable, + gchar **etag_out, + GError **error) +{ + gchar *contents; + gsize len; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (etag_out != NULL) + *etag_out = NULL; + + if (g_file_has_uri_scheme (file, "resource")) + { + GBytes *bytes; + gchar *uri, *unescaped; + + uri = g_file_get_uri (file); + unescaped = g_uri_unescape_string (uri + strlen ("resource://"), NULL); + g_free (uri); + + bytes = g_resources_lookup_data (unescaped, G_RESOURCE_LOOKUP_FLAGS_NONE, error); + g_free (unescaped); + + return bytes; + } + + /* contents is guaranteed to be \0 terminated */ + if (g_file_load_contents (file, cancellable, &contents, &len, etag_out, error)) + return g_bytes_new_take (g_steal_pointer (&contents), len); + + return NULL; +} + +static void +g_file_load_bytes_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GFile *file = G_FILE (object); + GTask *task = user_data; + GError *error = NULL; + gchar *etag = NULL; + gchar *contents = NULL; + gsize len = 0; + + g_file_load_contents_finish (file, result, &contents, &len, &etag, &error); + g_task_set_task_data (task, g_steal_pointer (&etag), g_free); + + if (error != NULL) + g_task_return_error (task, g_steal_pointer (&error)); + else + g_task_return_pointer (task, + g_bytes_new_take (g_steal_pointer (&contents), len), + (GDestroyNotify)g_bytes_unref); + + g_object_unref (task); +} + +/** + * g_file_load_bytes_async: + * @file: a #GFile + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (scope async): a #GAsyncReadyCallback to call when the + * request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously loads the contents of @file as #GBytes. + * + * If @file is a resource:// based URI, the resulting bytes will reference the + * embedded resource instead of a copy. Otherwise, this is equivalent to calling + * g_file_load_contents_async() and g_bytes_new_take(). + * + * @callback should call g_file_load_bytes_finish() to get the result of this + * asynchronous operation. + * + * See g_file_load_bytes() for more information. + * + * Since: 2.56 + */ +void +g_file_load_bytes_async (GFile *file, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GError *error = NULL; + GBytes *bytes; + GTask *task; + + g_return_if_fail (G_IS_FILE (file)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + task = g_task_new (file, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_load_bytes_async); + + if (!g_file_has_uri_scheme (file, "resource")) + { + g_file_load_contents_async (file, + cancellable, + g_file_load_bytes_cb, + g_steal_pointer (&task)); + return; + } + + bytes = g_file_load_bytes (file, cancellable, NULL, &error); + + if (bytes == NULL) + g_task_return_error (task, g_steal_pointer (&error)); + else + g_task_return_pointer (task, + g_steal_pointer (&bytes), + (GDestroyNotify)g_bytes_unref); + + g_object_unref (task); +} + +/** + * g_file_load_bytes_finish: + * @file: a #GFile + * @result: a #GAsyncResult provided to the callback + * @etag_out: (out) (nullable) (optional): a location to place the current + * entity tag for the file, or %NULL if the entity tag is not needed + * @error: a location for a #GError, or %NULL + * + * Completes an asynchronous request to g_file_load_bytes_async(). + * + * For resources, @etag_out will be set to %NULL. + * + * The data contained in the resulting #GBytes is always zero-terminated, but + * this is not included in the #GBytes length. The resulting #GBytes should be + * freed with g_bytes_unref() when no longer in use. + * + * See g_file_load_bytes() for more information. + * + * Returns: (transfer full): a #GBytes or %NULL and @error is set + * + * Since: 2.56 + */ +GBytes * +g_file_load_bytes_finish (GFile *file, + GAsyncResult *result, + gchar **etag_out, + GError **error) +{ + GBytes *bytes; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_TASK (result), NULL); + g_return_val_if_fail (g_task_is_valid (G_TASK (result), file), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + bytes = g_task_propagate_pointer (G_TASK (result), error); + + if (etag_out != NULL) + *etag_out = g_strdup (g_task_get_task_data (G_TASK (result))); + + return bytes; +} diff --git a/gio/gfile.h b/gio/gfile.h new file mode 100644 index 0000000..3a324cf --- /dev/null +++ b/gio/gfile.h @@ -0,0 +1,1318 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_H__ +#define __G_FILE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE (g_file_get_type ()) +#define G_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_FILE, GFile)) +#define G_IS_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_FILE)) +#define G_FILE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_FILE, GFileIface)) + +#if 0 +/** + * GFile: + * + * A handle to an object implementing the #GFileIface interface. + * Generally stores a location within the file system. Handles do not + * necessarily represent files or directories that currently exist. + **/ +typedef struct _GFile GFile; /* Dummy typedef */ +#endif +typedef struct _GFileIface GFileIface; + + +/** + * GFileIface: + * @g_iface: The parent interface. + * @dup: Duplicates a #GFile. + * @hash: Creates a hash of a #GFile. + * @equal: Checks equality of two given #GFiles. + * @is_native: Checks to see if a file is native to the system. + * @has_uri_scheme: Checks to see if a #GFile has a given URI scheme. + * @get_uri_scheme: Gets the URI scheme for a #GFile. + * @get_basename: Gets the basename for a given #GFile. + * @get_path: Gets the current path within a #GFile. + * @get_uri: Gets a URI for the path within a #GFile. + * @get_parse_name: Gets the parsed name for the #GFile. + * @get_parent: Gets the parent directory for the #GFile. + * @prefix_matches: Checks whether a #GFile contains a specified file. + * @get_relative_path: Gets the path for a #GFile relative to a given path. + * @resolve_relative_path: Resolves a relative path for a #GFile to an absolute path. + * @get_child_for_display_name: Gets the child #GFile for a given display name. + * @enumerate_children: Gets a #GFileEnumerator with the children of a #GFile. + * @enumerate_children_async: Asynchronously gets a #GFileEnumerator with the children of a #GFile. + * @enumerate_children_finish: Finishes asynchronously enumerating the children. + * @query_info: Gets the #GFileInfo for a #GFile. + * @query_info_async: Asynchronously gets the #GFileInfo for a #GFile. + * @query_info_finish: Finishes an asynchronous query info operation. + * @query_filesystem_info: Gets a #GFileInfo for the file system #GFile is on. + * @query_filesystem_info_async: Asynchronously gets a #GFileInfo for the file system #GFile is on. + * @query_filesystem_info_finish: Finishes asynchronously getting the file system info. + * @find_enclosing_mount: Gets a #GMount for the #GFile. + * @find_enclosing_mount_async: Asynchronously gets the #GMount for a #GFile. + * @find_enclosing_mount_finish: Finishes asynchronously getting the volume. + * @set_display_name: Sets the display name for a #GFile. + * @set_display_name_async: Asynchronously sets a #GFile's display name. + * @set_display_name_finish: Finishes asynchronously setting a #GFile's display name. + * @query_settable_attributes: Returns a list of #GFileAttributeInfos that can be set. + * @_query_settable_attributes_async: Asynchronously gets a list of #GFileAttributeInfos that can be set. + * @_query_settable_attributes_finish: Finishes asynchronously querying settable attributes. + * @query_writable_namespaces: Returns a list of #GFileAttributeInfo namespaces that are writable. + * @_query_writable_namespaces_async: Asynchronously gets a list of #GFileAttributeInfo namespaces that are writable. + * @_query_writable_namespaces_finish: Finishes asynchronously querying the writable namespaces. + * @set_attribute: Sets a #GFileAttributeInfo. + * @set_attributes_from_info: Sets a #GFileAttributeInfo with information from a #GFileInfo. + * @set_attributes_async: Asynchronously sets a file's attributes. + * @set_attributes_finish: Finishes setting a file's attributes asynchronously. + * @read_fn: Reads a file asynchronously. + * @read_async: Asynchronously reads a file. + * @read_finish: Finishes asynchronously reading a file. + * @append_to: Writes to the end of a file. + * @append_to_async: Asynchronously writes to the end of a file. + * @append_to_finish: Finishes an asynchronous file append operation. + * @create: Creates a new file. + * @create_async: Asynchronously creates a file. + * @create_finish: Finishes asynchronously creating a file. + * @replace: Replaces the contents of a file. + * @replace_async: Asynchronously replaces the contents of a file. + * @replace_finish: Finishes asynchronously replacing a file. + * @delete_file: Deletes a file. + * @delete_file_async: Asynchronously deletes a file. + * @delete_file_finish: Finishes an asynchronous delete. + * @trash: Sends a #GFile to the Trash location. + * @trash_async: Asynchronously sends a #GFile to the Trash location. + * @trash_finish: Finishes an asynchronous file trashing operation. + * @make_directory: Makes a directory. + * @make_directory_async: Asynchronously makes a directory. + * @make_directory_finish: Finishes making a directory asynchronously. + * @make_symbolic_link: (nullable): Makes a symbolic link. %NULL if symbolic + * links are unsupported. + * @_make_symbolic_link_async: Asynchronously makes a symbolic link + * @_make_symbolic_link_finish: Finishes making a symbolic link asynchronously. + * @copy: (nullable): Copies a file. %NULL if copying is unsupported, which will + * cause `GFile` to use a fallback copy method where it reads from the + * source and writes to the destination. + * @copy_async: Asynchronously copies a file. + * @copy_finish: Finishes an asynchronous copy operation. + * @move: Moves a file. + * @move_async: Asynchronously moves a file. Since: 2.72 + * @move_finish: Finishes an asynchronous move operation. Since: 2.72 + * @mount_mountable: Mounts a mountable object. + * @mount_mountable_finish: Finishes a mounting operation. + * @unmount_mountable: Unmounts a mountable object. + * @unmount_mountable_finish: Finishes an unmount operation. + * @eject_mountable: Ejects a mountable. + * @eject_mountable_finish: Finishes an eject operation. + * @mount_enclosing_volume: Mounts a specified location. + * @mount_enclosing_volume_finish: Finishes mounting a specified location. + * @monitor_dir: Creates a #GFileMonitor for the location. + * @monitor_file: Creates a #GFileMonitor for the location. + * @open_readwrite: Open file read/write. Since 2.22. + * @open_readwrite_async: Asynchronously opens file read/write. Since 2.22. + * @open_readwrite_finish: Finishes an asynchronous open read/write. Since 2.22. + * @create_readwrite: Creates file read/write. Since 2.22. + * @create_readwrite_async: Asynchronously creates file read/write. Since 2.22. + * @create_readwrite_finish: Finishes an asynchronous creates read/write. Since 2.22. + * @replace_readwrite: Replaces file read/write. Since 2.22. + * @replace_readwrite_async: Asynchronously replaces file read/write. Since 2.22. + * @replace_readwrite_finish: Finishes an asynchronous replace read/write. Since 2.22. + * @start_mountable: Starts a mountable object. Since 2.22. + * @start_mountable_finish: Finishes a start operation. Since 2.22. + * @stop_mountable: Stops a mountable. Since 2.22. + * @stop_mountable_finish: Finishes a stop operation. Since 2.22. + * @supports_thread_contexts: a boolean that indicates whether the #GFile implementation supports thread-default contexts. Since 2.22. + * @unmount_mountable_with_operation: Unmounts a mountable object using a #GMountOperation. Since 2.22. + * @unmount_mountable_with_operation_finish: Finishes an unmount operation using a #GMountOperation. Since 2.22. + * @eject_mountable_with_operation: Ejects a mountable object using a #GMountOperation. Since 2.22. + * @eject_mountable_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22. + * @poll_mountable: Polls a mountable object for media changes. Since 2.22. + * @poll_mountable_finish: Finishes a poll operation for media changes. Since 2.22. + * @measure_disk_usage: Recursively measures the disk usage of @file. Since 2.38 + * @measure_disk_usage_async: Asynchronously recursively measures the disk usage of @file. Since 2.38 + * @measure_disk_usage_finish: Finishes an asynchronous recursive measurement of the disk usage of @file. Since 2.38 + * + * An interface for writing VFS file handles. + **/ +struct _GFileIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + GFile * (* dup) (GFile *file); + guint (* hash) (GFile *file); + gboolean (* equal) (GFile *file1, + GFile *file2); + gboolean (* is_native) (GFile *file); + gboolean (* has_uri_scheme) (GFile *file, + const char *uri_scheme); + char * (* get_uri_scheme) (GFile *file); + char * (* get_basename) (GFile *file); + char * (* get_path) (GFile *file); + char * (* get_uri) (GFile *file); + char * (* get_parse_name) (GFile *file); + GFile * (* get_parent) (GFile *file); + gboolean (* prefix_matches) (GFile *prefix, + GFile *file); + char * (* get_relative_path) (GFile *parent, + GFile *descendant); + GFile * (* resolve_relative_path) (GFile *file, + const char *relative_path); + GFile * (* get_child_for_display_name) (GFile *file, + const char *display_name, + GError **error); + + GFileEnumerator * (* enumerate_children) (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + void (* enumerate_children_async) (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileEnumerator * (* enumerate_children_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + GFileInfo * (* query_info) (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + void (* query_info_async) (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileInfo * (* query_info_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + GFileInfo * (* query_filesystem_info) (GFile *file, + const char *attributes, + GCancellable *cancellable, + GError **error); + void (* query_filesystem_info_async) (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileInfo * (* query_filesystem_info_finish)(GFile *file, + GAsyncResult *res, + GError **error); + + GMount * (* find_enclosing_mount) (GFile *file, + GCancellable *cancellable, + GError **error); + void (* find_enclosing_mount_async) (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GMount * (* find_enclosing_mount_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + GFile * (* set_display_name) (GFile *file, + const char *display_name, + GCancellable *cancellable, + GError **error); + void (* set_display_name_async) (GFile *file, + const char *display_name, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFile * (* set_display_name_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + GFileAttributeInfoList * (* query_settable_attributes) (GFile *file, + GCancellable *cancellable, + GError **error); + void (* _query_settable_attributes_async) (void); + void (* _query_settable_attributes_finish) (void); + + GFileAttributeInfoList * (* query_writable_namespaces) (GFile *file, + GCancellable *cancellable, + GError **error); + void (* _query_writable_namespaces_async) (void); + void (* _query_writable_namespaces_finish) (void); + + gboolean (* set_attribute) (GFile *file, + const char *attribute, + GFileAttributeType type, + gpointer value_p, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + gboolean (* set_attributes_from_info) (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + void (* set_attributes_async) (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* set_attributes_finish) (GFile *file, + GAsyncResult *result, + GFileInfo **info, + GError **error); + + GFileInputStream * (* read_fn) (GFile *file, + GCancellable *cancellable, + GError **error); + void (* read_async) (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileInputStream * (* read_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + GFileOutputStream * (* append_to) (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); + void (* append_to_async) (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileOutputStream * (* append_to_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + GFileOutputStream * (* create) (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); + void (* create_async) (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileOutputStream * (* create_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + GFileOutputStream * (* replace) (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); + void (* replace_async) (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileOutputStream * (* replace_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + gboolean (* delete_file) (GFile *file, + GCancellable *cancellable, + GError **error); + void (* delete_file_async) (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* delete_file_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + gboolean (* trash) (GFile *file, + GCancellable *cancellable, + GError **error); + void (* trash_async) (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* trash_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + gboolean (* make_directory) (GFile *file, + GCancellable *cancellable, + GError **error); + void (* make_directory_async) (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* make_directory_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + gboolean (* make_symbolic_link) (GFile *file, + const char *symlink_value, + GCancellable *cancellable, + GError **error); + void (* _make_symbolic_link_async) (void); + void (* _make_symbolic_link_finish) (void); + + gboolean (* copy) (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error); + void (* copy_async) (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* copy_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + gboolean (* move) (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error); + void (* move_async) (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* move_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + void (* mount_mountable) (GFile *file, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFile * (* mount_mountable_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + void (* unmount_mountable) (GFile *file, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* unmount_mountable_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + void (* eject_mountable) (GFile *file, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* eject_mountable_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + void (* mount_enclosing_volume) (GFile *location, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* mount_enclosing_volume_finish) (GFile *location, + GAsyncResult *result, + GError **error); + + GFileMonitor * (* monitor_dir) (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error); + GFileMonitor * (* monitor_file) (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error); + + GFileIOStream * (* open_readwrite) (GFile *file, + GCancellable *cancellable, + GError **error); + void (* open_readwrite_async) (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileIOStream * (* open_readwrite_finish) (GFile *file, + GAsyncResult *res, + GError **error); + GFileIOStream * (* create_readwrite) (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); + void (* create_readwrite_async) (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileIOStream * (* create_readwrite_finish) (GFile *file, + GAsyncResult *res, + GError **error); + GFileIOStream * (* replace_readwrite) (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); + void (* replace_readwrite_async) (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileIOStream * (* replace_readwrite_finish) (GFile *file, + GAsyncResult *res, + GError **error); + + void (* start_mountable) (GFile *file, + GDriveStartFlags flags, + GMountOperation *start_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* start_mountable_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + void (* stop_mountable) (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* stop_mountable_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + gboolean supports_thread_contexts; + + void (* unmount_mountable_with_operation) (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* unmount_mountable_with_operation_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + void (* eject_mountable_with_operation) (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* eject_mountable_with_operation_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + void (* poll_mountable) (GFile *file, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* poll_mountable_finish) (GFile *file, + GAsyncResult *result, + GError **error); + + gboolean (* measure_disk_usage) (GFile *file, + GFileMeasureFlags flags, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error); + void (* measure_disk_usage_async) (GFile *file, + GFileMeasureFlags flags, + gint io_priority, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* measure_disk_usage_finish) (GFile *file, + GAsyncResult *result, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_file_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GFile * g_file_new_for_path (const char *path); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_new_for_uri (const char *uri); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_new_for_commandline_arg (const char *arg); +GLIB_AVAILABLE_IN_2_36 +GFile * g_file_new_for_commandline_arg_and_cwd (const gchar *arg, + const gchar *cwd); +GLIB_AVAILABLE_IN_2_32 +GFile * g_file_new_tmp (const char *tmpl, + GFileIOStream **iostream, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_parse_name (const char *parse_name); +GLIB_AVAILABLE_IN_2_56 +GFile * g_file_new_build_filename (const gchar *first_element, + ...) G_GNUC_NULL_TERMINATED; +GLIB_AVAILABLE_IN_ALL +GFile * g_file_dup (GFile *file); +GLIB_AVAILABLE_IN_ALL +guint g_file_hash (gconstpointer file); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_equal (GFile *file1, + GFile *file2); +GLIB_AVAILABLE_IN_ALL +char * g_file_get_basename (GFile *file); +GLIB_AVAILABLE_IN_ALL +char * g_file_get_path (GFile *file); +GLIB_AVAILABLE_IN_2_56 +const char * g_file_peek_path (GFile *file); +GLIB_AVAILABLE_IN_ALL +char * g_file_get_uri (GFile *file); +GLIB_AVAILABLE_IN_ALL +char * g_file_get_parse_name (GFile *file); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_get_parent (GFile *file); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_has_parent (GFile *file, + GFile *parent); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_get_child (GFile *file, + const char *name); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_get_child_for_display_name (GFile *file, + const char *display_name, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_has_prefix (GFile *file, + GFile *prefix); +GLIB_AVAILABLE_IN_ALL +char * g_file_get_relative_path (GFile *parent, + GFile *descendant); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_resolve_relative_path (GFile *file, + const char *relative_path); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_is_native (GFile *file); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_has_uri_scheme (GFile *file, + const char *uri_scheme); +GLIB_AVAILABLE_IN_ALL +char * g_file_get_uri_scheme (GFile *file); +GLIB_AVAILABLE_IN_ALL +GFileInputStream * g_file_read (GFile *file, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_read_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileInputStream * g_file_read_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileOutputStream * g_file_append_to (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileOutputStream * g_file_create (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileOutputStream * g_file_replace (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_append_to_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileOutputStream * g_file_append_to_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_create_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileOutputStream * g_file_create_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_replace_async (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileOutputStream * g_file_replace_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileIOStream * g_file_open_readwrite (GFile *file, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_open_readwrite_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileIOStream * g_file_open_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileIOStream * g_file_create_readwrite (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_create_readwrite_async (GFile *file, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileIOStream * g_file_create_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileIOStream * g_file_replace_readwrite (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_replace_readwrite_async (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileIOStream * g_file_replace_readwrite_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_query_exists (GFile *file, + GCancellable *cancellable); +GLIB_AVAILABLE_IN_ALL +GFileType g_file_query_file_type (GFile *file, + GFileQueryInfoFlags flags, + GCancellable *cancellable); +GLIB_AVAILABLE_IN_ALL +GFileInfo * g_file_query_info (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_query_info_async (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileInfo * g_file_query_info_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileInfo * g_file_query_filesystem_info (GFile *file, + const char *attributes, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_query_filesystem_info_async (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileInfo * g_file_query_filesystem_info_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GMount * g_file_find_enclosing_mount (GFile *file, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_find_enclosing_mount_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GMount * g_file_find_enclosing_mount_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileEnumerator * g_file_enumerate_children (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_enumerate_children_async (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileEnumerator * g_file_enumerate_children_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_set_display_name (GFile *file, + const char *display_name, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_set_display_name_async (GFile *file, + const char *display_name, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_set_display_name_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_delete (GFile *file, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_34 +void g_file_delete_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_34 +gboolean g_file_delete_finish (GFile *file, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_file_trash (GFile *file, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_38 +void g_file_trash_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_38 +gboolean g_file_trash_finish (GFile *file, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_file_copy (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_copy_async (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_copy_finish (GFile *file, + GAsyncResult *res, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_move (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error); +GLIB_AVAILABLE_IN_2_72 +void g_file_move_async (GFile *source, + GFile *destination, + GFileCopyFlags flags, + int io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_72 +gboolean g_file_move_finish (GFile *file, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_make_directory (GFile *file, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_38 +void g_file_make_directory_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_38 +gboolean g_file_make_directory_finish (GFile *file, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_file_make_directory_with_parents (GFile *file, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_make_symbolic_link (GFile *file, + const char *symlink_value, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileAttributeInfoList *g_file_query_settable_attributes (GFile *file, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileAttributeInfoList *g_file_query_writable_namespaces (GFile *file, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attribute (GFile *file, + const char *attribute, + GFileAttributeType type, + gpointer value_p, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attributes_from_info (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_set_attributes_async (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attributes_finish (GFile *file, + GAsyncResult *result, + GFileInfo **info, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attribute_string (GFile *file, + const char *attribute, + const char *value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attribute_byte_string (GFile *file, + const char *attribute, + const char *value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attribute_uint32 (GFile *file, + const char *attribute, + guint32 value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attribute_int32 (GFile *file, + const char *attribute, + gint32 value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attribute_uint64 (GFile *file, + const char *attribute, + guint64 value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_set_attribute_int64 (GFile *file, + const char *attribute, + gint64 value, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_mount_enclosing_volume (GFile *location, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_mount_enclosing_volume_finish (GFile *location, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_mount_mountable (GFile *file, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_mount_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error); +GLIB_DEPRECATED_FOR(g_file_unmount_mountable_with_operation) +void g_file_unmount_mountable (GFile *file, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_DEPRECATED_FOR(g_file_unmount_mountable_with_operation_finish) +gboolean g_file_unmount_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_unmount_mountable_with_operation (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_unmount_mountable_with_operation_finish (GFile *file, + GAsyncResult *result, + GError **error); +GLIB_DEPRECATED_FOR(g_file_eject_mountable_with_operation) +void g_file_eject_mountable (GFile *file, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_DEPRECATED_FOR(g_file_eject_mountable_with_operation_finish) +gboolean g_file_eject_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_eject_mountable_with_operation (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_eject_mountable_with_operation_finish (GFile *file, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_68 +char * g_file_build_attribute_list_for_copy (GFile *file, + GFileCopyFlags flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_file_copy_attributes (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GError **error); + + +GLIB_AVAILABLE_IN_ALL +GFileMonitor* g_file_monitor_directory (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileMonitor* g_file_monitor_file (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GFileMonitor* g_file_monitor (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_38 +gboolean g_file_measure_disk_usage (GFile *file, + GFileMeasureFlags flags, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error); + +GLIB_AVAILABLE_IN_2_38 +void g_file_measure_disk_usage_async (GFile *file, + GFileMeasureFlags flags, + gint io_priority, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_38 +gboolean g_file_measure_disk_usage_finish (GFile *file, + GAsyncResult *result, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_file_start_mountable (GFile *file, + GDriveStartFlags flags, + GMountOperation *start_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_start_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_stop_mountable (GFile *file, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_stop_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_file_poll_mountable (GFile *file, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_poll_mountable_finish (GFile *file, + GAsyncResult *result, + GError **error); + +/* Utilities */ + +GLIB_AVAILABLE_IN_ALL +GAppInfo *g_file_query_default_handler (GFile *file, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_60 +void g_file_query_default_handler_async (GFile *file, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_60 +GAppInfo *g_file_query_default_handler_finish (GFile *file, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_file_load_contents (GFile *file, + GCancellable *cancellable, + char **contents, + gsize *length, + char **etag_out, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_load_contents_async (GFile *file, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_load_contents_finish (GFile *file, + GAsyncResult *res, + char **contents, + gsize *length, + char **etag_out, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_load_partial_contents_async (GFile *file, + GCancellable *cancellable, + GFileReadMoreCallback read_more_callback, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_load_partial_contents_finish (GFile *file, + GAsyncResult *res, + char **contents, + gsize *length, + char **etag_out, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_replace_contents (GFile *file, + const char *contents, + gsize length, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + char **new_etag, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_replace_contents_async (GFile *file, + const char *contents, + gsize length, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_40 +void g_file_replace_contents_bytes_async (GFile *file, + GBytes *contents, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_replace_contents_finish (GFile *file, + GAsyncResult *res, + char **new_etag, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_file_supports_thread_contexts (GFile *file); + +GLIB_AVAILABLE_IN_2_56 +GBytes *g_file_load_bytes (GFile *file, + GCancellable *cancellable, + gchar **etag_out, + GError **error); +GLIB_AVAILABLE_IN_2_56 +void g_file_load_bytes_async (GFile *file, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_56 +GBytes *g_file_load_bytes_finish (GFile *file, + GAsyncResult *result, + gchar **etag_out, + GError **error); + +G_END_DECLS + +#endif /* __G_FILE_H__ */ diff --git a/gio/gfileattribute-priv.h b/gio/gfileattribute-priv.h new file mode 100644 index 0000000..c42f937 --- /dev/null +++ b/gio/gfileattribute-priv.h @@ -0,0 +1,91 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_ATTRIBUTE_PRIV_H__ +#define __G_FILE_ATTRIBUTE_PRIV_H__ + +#include "gfileattribute.h" +#include "gfileinfo.h" + +#define G_FILE_ATTRIBUTE_VALUE_INIT {0} + +typedef struct { + GFileAttributeType type : 8; + GFileAttributeStatus status : 8; + union { + gboolean boolean; + gint32 int32; + guint32 uint32; + gint64 int64; + guint64 uint64; + char *string; + GObject *obj; + char **stringv; + } u; +} GFileAttributeValue; + +GFileAttributeValue *_g_file_attribute_value_new (void); +void _g_file_attribute_value_free (GFileAttributeValue *attr); +void _g_file_attribute_value_clear (GFileAttributeValue *attr); +void _g_file_attribute_value_set (GFileAttributeValue *attr, + const GFileAttributeValue *new_value); +GFileAttributeValue *_g_file_attribute_value_dup (const GFileAttributeValue *other); +gpointer _g_file_attribute_value_peek_as_pointer (GFileAttributeValue *attr); + +char * _g_file_attribute_value_as_string (const GFileAttributeValue *attr); + +const char * _g_file_attribute_value_get_string (const GFileAttributeValue *attr); +const char * _g_file_attribute_value_get_byte_string (const GFileAttributeValue *attr); +gboolean _g_file_attribute_value_get_boolean (const GFileAttributeValue *attr); +guint32 _g_file_attribute_value_get_uint32 (const GFileAttributeValue *attr); +gint32 _g_file_attribute_value_get_int32 (const GFileAttributeValue *attr); +guint64 _g_file_attribute_value_get_uint64 (const GFileAttributeValue *attr); +gint64 _g_file_attribute_value_get_int64 (const GFileAttributeValue *attr); +GObject * _g_file_attribute_value_get_object (const GFileAttributeValue *attr); +char ** _g_file_attribute_value_get_stringv (const GFileAttributeValue *attr); + +void _g_file_attribute_value_set_from_pointer(GFileAttributeValue *attr, + GFileAttributeType type, + gpointer value_p, + gboolean dup); +void _g_file_attribute_value_set_string (GFileAttributeValue *attr, + const char *string); +void _g_file_attribute_value_set_byte_string (GFileAttributeValue *attr, + const char *string); +void _g_file_attribute_value_set_boolean (GFileAttributeValue *attr, + gboolean value); +void _g_file_attribute_value_set_uint32 (GFileAttributeValue *attr, + guint32 value); +void _g_file_attribute_value_set_int32 (GFileAttributeValue *attr, + gint32 value); +void _g_file_attribute_value_set_uint64 (GFileAttributeValue *attr, + guint64 value); +void _g_file_attribute_value_set_int64 (GFileAttributeValue *attr, + gint64 value); +void _g_file_attribute_value_set_object (GFileAttributeValue *attr, + GObject *obj); +void _g_file_attribute_value_set_stringv (GFileAttributeValue *attr, + char **value); + + +GFileAttributeValue *_g_file_info_get_attribute_value (GFileInfo *info, + const char *attribute); + +#endif /* __G_FILE_ATTRIBUTE_PRIV_H__ */ diff --git a/gio/gfileattribute.c b/gio/gfileattribute.c new file mode 100644 index 0000000..8075d1d --- /dev/null +++ b/gio/gfileattribute.c @@ -0,0 +1,981 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "gfileattribute.h" +#include "gfileattribute-priv.h" +#include +#include "glibintl.h" + + +/** + * SECTION:gfileattribute + * @short_description: Key-Value Paired File Attributes + * @include: gio/gio.h + * @see_also: #GFile, #GFileInfo + * + * File attributes in GIO consist of a list of key-value pairs. + * + * Keys are strings that contain a key namespace and a key name, separated + * by a colon, e.g. "namespace::keyname". Namespaces are included to sort + * key-value pairs by namespaces for relevance. Keys can be retrieved + * using wildcards, e.g. "standard::*" will return all of the keys in the + * "standard" namespace. + * + * The list of possible attributes for a filesystem (pointed to by a #GFile) is + * available as a #GFileAttributeInfoList. This list is queryable by key names + * as indicated earlier. + * + * Information is stored within the list in #GFileAttributeInfo structures. + * The info structure can store different types, listed in the enum + * #GFileAttributeType. Upon creation of a #GFileAttributeInfo, the type will + * be set to %G_FILE_ATTRIBUTE_TYPE_INVALID. + * + * Classes that implement #GFileIface will create a #GFileAttributeInfoList and + * install default keys and values for their given file system, architecture, + * and other possible implementation details (e.g., on a UNIX system, a file + * attribute key will be registered for the user id for a given file). + * + * ## Default Namespaces + * + * - `"standard"`: The "Standard" namespace. General file information that + * any application may need should be put in this namespace. Examples + * include the file's name, type, and size. + * - `"etag`: The [Entity Tag][gfile-etag] namespace. Currently, the only key + * in this namespace is "value", which contains the value of the current + * entity tag. + * - `"id"`: The "Identification" namespace. This namespace is used by file + * managers and applications that list directories to check for loops and + * to uniquely identify files. + * - `"access"`: The "Access" namespace. Used to check if a user has the + * proper privileges to access files and perform file operations. Keys in + * this namespace are made to be generic and easily understood, e.g. the + * "can_read" key is %TRUE if the current user has permission to read the + * file. UNIX permissions and NTFS ACLs in Windows should be mapped to + * these values. + * - `"mountable"`: The "Mountable" namespace. Includes simple boolean keys + * for checking if a file or path supports mount operations, e.g. mount, + * unmount, eject. These are used for files of type %G_FILE_TYPE_MOUNTABLE. + * - `"time"`: The "Time" namespace. Includes file access, changed, created + * times. + * - `"unix"`: The "Unix" namespace. Includes UNIX-specific information and + * may not be available for all files. Examples include the UNIX "UID", + * "GID", etc. + * - `"dos"`: The "DOS" namespace. Includes DOS-specific information and may + * not be available for all files. Examples include "is_system" for checking + * if a file is marked as a system file, and "is_archive" for checking if a + * file is marked as an archive file. + * - `"owner"`: The "Owner" namespace. Includes information about who owns a + * file. May not be available for all file systems. Examples include "user" + * for getting the user name of the file owner. This information is often + * mapped from some backend specific data such as a UNIX UID. + * - `"thumbnail"`: The "Thumbnail" namespace. Includes information about file + * thumbnails and their location within the file system. Examples of keys in + * this namespace include "path" to get the location of a thumbnail, "failed" + * to check if thumbnailing of the file failed, and "is-valid" to check if + * the thumbnail is outdated. + * - `"filesystem"`: The "Filesystem" namespace. Gets information about the + * file system where a file is located, such as its type, how much space is + * left available, and the overall size of the file system. + * - `"gvfs"`: The "GVFS" namespace. Keys in this namespace contain information + * about the current GVFS backend in use. + * - `"xattr"`: The "xattr" namespace. Gets information about extended + * user attributes. See attr(5). The "user." prefix of the extended user + * attribute name is stripped away when constructing keys in this namespace, + * e.g. "xattr::mime_type" for the extended attribute with the name + * "user.mime_type". Note that this information is only available if + * GLib has been built with extended attribute support. + * - `"xattr-sys"`: The "xattr-sys" namespace. Gets information about + * extended attributes which are not user-specific. See attr(5). Note + * that this information is only available if GLib has been built with + * extended attribute support. + * - `"selinux"`: The "SELinux" namespace. Includes information about the + * SELinux context of files. Note that this information is only available + * if GLib has been built with SELinux support. + * + * Please note that these are not all of the possible namespaces. + * More namespaces can be added from GIO modules or by individual applications. + * For more information about writing GIO modules, see #GIOModule. + * + * + * + * ## Default Keys + * + * For a list of the built-in keys and their types, see the + * [GFileInfo][GFileInfo] documentation. + * + * Note that there are no predefined keys in the "xattr" and "xattr-sys" + * namespaces. Keys for the "xattr" namespace are constructed by stripping + * away the "user." prefix from the extended user attribute, and prepending + * "xattr::". Keys for the "xattr-sys" namespace are constructed by + * concatenating "xattr-sys::" with the extended attribute name. All extended + * attribute values are returned as hex-encoded strings in which bytes outside + * the ASCII range are encoded as escape sequences of the form \x`nn` + * where `nn` is a 2-digit hexadecimal number. + */ + +/** + * _g_file_attribute_value_free: + * @attr: a #GFileAttributeValue. + * + * Frees the memory used by @attr. + * + **/ +void +_g_file_attribute_value_free (GFileAttributeValue *attr) +{ + g_return_if_fail (attr != NULL); + + _g_file_attribute_value_clear (attr); + g_free (attr); +} + +/** + * _g_file_attribute_value_clear: + * @attr: a #GFileAttributeValue. + * + * Clears the value of @attr and sets its type to + * %G_FILE_ATTRIBUTE_TYPE_INVALID. + * + **/ +void +_g_file_attribute_value_clear (GFileAttributeValue *attr) +{ + g_return_if_fail (attr != NULL); + + if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING || + attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING) + g_free (attr->u.string); + + if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRINGV) + g_strfreev (attr->u.stringv); + + if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT && + attr->u.obj != NULL) + g_object_unref (attr->u.obj); + + attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID; +} + +/** + * g_file_attribute_value_set: + * @attr: a #GFileAttributeValue to set the value in. + * @new_value: a #GFileAttributeValue to get the value from. + * + * Sets an attribute's value from another attribute. + **/ +void +_g_file_attribute_value_set (GFileAttributeValue *attr, + const GFileAttributeValue *new_value) +{ + g_return_if_fail (attr != NULL); + g_return_if_fail (new_value != NULL); + + _g_file_attribute_value_clear (attr); + *attr = *new_value; + + if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING || + attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING) + attr->u.string = g_strdup (attr->u.string); + + if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRINGV) + attr->u.stringv = g_strdupv (attr->u.stringv); + + if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT && + attr->u.obj != NULL) + g_object_ref (attr->u.obj); +} + +/** + * _g_file_attribute_value_new: + * + * Creates a new file attribute. + * + * Returns: a #GFileAttributeValue. + **/ +GFileAttributeValue * +_g_file_attribute_value_new (void) +{ + GFileAttributeValue *attr; + + attr = g_new (GFileAttributeValue, 1); + attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID; + return attr; +} + +gpointer +_g_file_attribute_value_peek_as_pointer (GFileAttributeValue *attr) +{ + switch (attr->type) { + case G_FILE_ATTRIBUTE_TYPE_STRING: + case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: + return attr->u.string; + case G_FILE_ATTRIBUTE_TYPE_STRINGV: + return attr->u.stringv; + case G_FILE_ATTRIBUTE_TYPE_OBJECT: + return attr->u.obj; + default: + return (gpointer) &attr->u; + } +} + +/** + * g_file_attribute_value_dup: + * @other: a #GFileAttributeValue to duplicate. + * + * Duplicates a file attribute. + * + * Returns: a duplicate of the @other. + **/ +GFileAttributeValue * +_g_file_attribute_value_dup (const GFileAttributeValue *other) +{ + GFileAttributeValue *attr; + + g_return_val_if_fail (other != NULL, NULL); + + attr = g_new (GFileAttributeValue, 1); + attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID; + _g_file_attribute_value_set (attr, other); + return attr; +} + +G_DEFINE_BOXED_TYPE (GFileAttributeInfoList, g_file_attribute_info_list, + g_file_attribute_info_list_dup, + g_file_attribute_info_list_unref) + +static gboolean +valid_char (char c) +{ + return c >= 32 && c <= 126 && c != '\\'; +} + +static char * +escape_byte_string (const char *str) +{ + size_t i, len; + int num_invalid; + char *escaped_val, *p; + unsigned char c; + const char hex_digits[] = "0123456789abcdef"; + + len = strlen (str); + + num_invalid = 0; + for (i = 0; i < len; i++) + { + if (!valid_char (str[i])) + num_invalid++; + } + + if (num_invalid == 0) + return g_strdup (str); + else + { + escaped_val = g_malloc (len + num_invalid*3 + 1); + + p = escaped_val; + for (i = 0; i < len; i++) + { + c = str[i]; + if (valid_char (c)) + *p++ = c; + else + { + *p++ = '\\'; + *p++ = 'x'; + *p++ = hex_digits[(c >> 4) & 0xf]; + *p++ = hex_digits[c & 0xf]; + } + } + *p++ = 0; + return escaped_val; + } +} + +/** + * _g_file_attribute_value_as_string: + * @attr: a #GFileAttributeValue. + * + * Converts a #GFileAttributeValue to a string for display. + * The returned string should be freed when no longer needed. + * + * Returns: a string from the @attr, %NULL on error, or "" + * if @attr is of type %G_FILE_ATTRIBUTE_TYPE_INVALID. + */ +char * +_g_file_attribute_value_as_string (const GFileAttributeValue *attr) +{ + GString *s; + int i; + char *str; + + g_return_val_if_fail (attr != NULL, NULL); + + switch (attr->type) + { + case G_FILE_ATTRIBUTE_TYPE_STRING: + str = g_strdup (attr->u.string); + break; + case G_FILE_ATTRIBUTE_TYPE_STRINGV: + s = g_string_new ("["); + for (i = 0; attr->u.stringv[i] != NULL; i++) + { + g_string_append (s, attr->u.stringv[i]); + if (attr->u.stringv[i+1] != NULL) + g_string_append (s, ", "); + } + g_string_append (s, "]"); + str = g_string_free (s, FALSE); + break; + case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: + str = escape_byte_string (attr->u.string); + break; + case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: + str = g_strdup_printf ("%s", attr->u.boolean?"TRUE":"FALSE"); + break; + case G_FILE_ATTRIBUTE_TYPE_UINT32: + str = g_strdup_printf ("%u", (unsigned int)attr->u.uint32); + break; + case G_FILE_ATTRIBUTE_TYPE_INT32: + str = g_strdup_printf ("%i", (int)attr->u.int32); + break; + case G_FILE_ATTRIBUTE_TYPE_UINT64: + str = g_strdup_printf ("%"G_GUINT64_FORMAT, attr->u.uint64); + break; + case G_FILE_ATTRIBUTE_TYPE_INT64: + str = g_strdup_printf ("%"G_GINT64_FORMAT, attr->u.int64); + break; + case G_FILE_ATTRIBUTE_TYPE_OBJECT: + str = g_strdup_printf ("%s:%p", g_type_name_from_instance + ((GTypeInstance *) attr->u.obj), + attr->u.obj); + break; + case G_FILE_ATTRIBUTE_TYPE_INVALID: + str = g_strdup (""); + break; + default: + g_warning ("Invalid type in GFileInfo attribute"); + str = g_strdup (""); + break; + } + + return str; +} + +/** + * _g_file_attribute_value_get_string: + * @attr: a #GFileAttributeValue. + * + * Gets the string from a file attribute value. If the value is not the + * right type then %NULL will be returned. + * + * Returns: the UTF-8 string value contained within the attribute, or %NULL. + */ +const char * +_g_file_attribute_value_get_string (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return NULL; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING, NULL); + + return attr->u.string; +} + +/** + * _g_file_attribute_value_get_byte_string: + * @attr: a #GFileAttributeValue. + * + * Gets the byte string from a file attribute value. If the value is not the + * right type then %NULL will be returned. + * + * Returns: the byte string contained within the attribute or %NULL. + */ +const char * +_g_file_attribute_value_get_byte_string (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return NULL; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, NULL); + + return attr->u.string; +} + +char ** +_g_file_attribute_value_get_stringv (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return NULL; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_STRINGV, NULL); + + return attr->u.stringv; +} + +/** + * _g_file_attribute_value_get_boolean: + * @attr: a #GFileAttributeValue. + * + * Gets the boolean value from a file attribute value. If the value is not the + * right type then %FALSE will be returned. + * + * Returns: the boolean value contained within the attribute, or %FALSE. + */ +gboolean +_g_file_attribute_value_get_boolean (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return FALSE; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BOOLEAN, FALSE); + + return attr->u.boolean; +} + +/** + * _g_file_attribute_value_get_uint32: + * @attr: a #GFileAttributeValue. + * + * Gets the unsigned 32-bit integer from a file attribute value. If the value + * is not the right type then 0 will be returned. + * + * Returns: the unsigned 32-bit integer from the attribute, or 0. + */ +guint32 +_g_file_attribute_value_get_uint32 (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return 0; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT32, 0); + + return attr->u.uint32; +} + +/** + * _g_file_attribute_value_get_int32: + * @attr: a #GFileAttributeValue. + * + * Gets the signed 32-bit integer from a file attribute value. If the value + * is not the right type then 0 will be returned. + * + * Returns: the signed 32-bit integer from the attribute, or 0. + */ +gint32 +_g_file_attribute_value_get_int32 (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return 0; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_INT32, 0); + + return attr->u.int32; +} + +/** + * _g_file_attribute_value_get_uint64: + * @attr: a #GFileAttributeValue. + * + * Gets the unsigned 64-bit integer from a file attribute value. If the value + * is not the right type then 0 will be returned. + * + * Returns: the unsigned 64-bit integer from the attribute, or 0. + */ +guint64 +_g_file_attribute_value_get_uint64 (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return 0; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT64, 0); + + return attr->u.uint64; +} + +/** + * _g_file_attribute_value_get_int64: + * @attr: a #GFileAttributeValue. + * + * Gets the signed 64-bit integer from a file attribute value. If the value + * is not the right type then 0 will be returned. + * + * Returns: the signed 64-bit integer from the attribute, or 0. + */ +gint64 +_g_file_attribute_value_get_int64 (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return 0; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_INT64, 0); + + return attr->u.int64; +} + +/** + * _g_file_attribute_value_get_object: + * @attr: a #GFileAttributeValue. + * + * Gets the GObject from a file attribute value. If the value + * is not the right type then %NULL will be returned. + * + * Returns: the GObject from the attribute, or %NULL. + **/ +GObject * +_g_file_attribute_value_get_object (const GFileAttributeValue *attr) +{ + if (attr == NULL) + return NULL; + + g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT, NULL); + + return attr->u.obj; +} + + +void +_g_file_attribute_value_set_from_pointer (GFileAttributeValue *value, + GFileAttributeType type, + gpointer value_p, + gboolean dup) +{ + _g_file_attribute_value_clear (value); + value->type = type; + switch (type) + { + case G_FILE_ATTRIBUTE_TYPE_STRING: + case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: + if (dup) + value->u.string = g_strdup (value_p); + else + value->u.string = value_p; + break; + + case G_FILE_ATTRIBUTE_TYPE_STRINGV: + if (dup) + value->u.stringv = g_strdupv (value_p); + else + value->u.stringv = value_p; + break; + + case G_FILE_ATTRIBUTE_TYPE_OBJECT: + if (dup) + value->u.obj = g_object_ref (value_p); + else + value->u.obj = value_p; + break; + + case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: + value->u.boolean = *(gboolean *)value_p; + break; + + case G_FILE_ATTRIBUTE_TYPE_UINT32: + value->u.uint32 = *(guint32 *)value_p; + break; + + case G_FILE_ATTRIBUTE_TYPE_INT32: + value->u.int32 = *(gint32 *)value_p; + break; + + case G_FILE_ATTRIBUTE_TYPE_UINT64: + value->u.uint64 = *(guint64 *)value_p; + break; + + case G_FILE_ATTRIBUTE_TYPE_INT64: + value->u.int64 = *(gint64 *)value_p; + break; + + case G_FILE_ATTRIBUTE_TYPE_INVALID: + break; + + default: + g_warning ("Unknown type specified in g_file_info_set_attribute"); + break; + } +} + +/** + * _g_file_attribute_value_set_string: + * @attr: a #GFileAttributeValue. + * @string: a UTF-8 string to set within the type. + * + * Sets the attribute value to a given UTF-8 string. + */ +void +_g_file_attribute_value_set_string (GFileAttributeValue *attr, + const char *string) +{ + g_return_if_fail (attr != NULL); + g_return_if_fail (string != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_STRING; + attr->u.string = g_strdup (string); +} + +/** + * _g_file_attribute_value_set_byte_string: + * @attr: a #GFileAttributeValue. + * @string: a byte string to set within the type. + * + * Sets the attribute value to a given byte string. + */ +void +_g_file_attribute_value_set_byte_string (GFileAttributeValue *attr, + const char *string) +{ + g_return_if_fail (attr != NULL); + g_return_if_fail (string != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_BYTE_STRING; + attr->u.string = g_strdup (string); +} + +void +_g_file_attribute_value_set_stringv (GFileAttributeValue *attr, + char **value) +{ + g_return_if_fail (attr != NULL); + g_return_if_fail (value != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_STRINGV; + attr->u.stringv = g_strdupv (value); +} + + +/** + * _g_file_attribute_value_set_boolean: + * @attr: a #GFileAttributeValue. + * @value: a #gboolean to set within the type. + * + * Sets the attribute value to the given boolean value. + */ +void +_g_file_attribute_value_set_boolean (GFileAttributeValue *attr, + gboolean value) +{ + g_return_if_fail (attr != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_BOOLEAN; + attr->u.boolean = !!value; +} + +/** + * _g_file_attribute_value_set_uint32: + * @attr: a #GFileAttributeValue. + * @value: a #guint32 to set within the type. + * + * Sets the attribute value to the given unsigned 32-bit integer. + */ +void +_g_file_attribute_value_set_uint32 (GFileAttributeValue *attr, + guint32 value) +{ + g_return_if_fail (attr != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_UINT32; + attr->u.uint32 = value; +} + +/** + * _g_file_attribute_value_set_int32: + * @attr: a #GFileAttributeValue. + * @value: a #gint32 to set within the type. + * + * Sets the attribute value to the given signed 32-bit integer. + */ +void +_g_file_attribute_value_set_int32 (GFileAttributeValue *attr, + gint32 value) +{ + g_return_if_fail (attr != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_INT32; + attr->u.int32 = value; +} + +/** + * _g_file_attribute_value_set_uint64: + * @attr: a #GFileAttributeValue. + * @value: a #guint64 to set within the type. + * + * Sets the attribute value to a given unsigned 64-bit integer. + */ +void +_g_file_attribute_value_set_uint64 (GFileAttributeValue *attr, + guint64 value) +{ + g_return_if_fail (attr != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_UINT64; + attr->u.uint64 = value; +} + +/** + * _g_file_attribute_value_set_int64: + * @attr: a #GFileAttributeValue. + * @value: a #gint64 to set within the type. + * + * Sets the attribute value to a given signed 64-bit integer. + */ +void +_g_file_attribute_value_set_int64 (GFileAttributeValue *attr, + gint64 value) +{ + g_return_if_fail (attr != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_INT64; + attr->u.int64 = value; +} + +/** + * _g_file_attribute_value_set_object: + * @attr: a #GFileAttributeValue. + * @obj: a #GObject. + * + * Sets the attribute to contain the value @obj. + * The @attr references the GObject internally. + */ +void +_g_file_attribute_value_set_object (GFileAttributeValue *attr, + GObject *obj) +{ + g_return_if_fail (attr != NULL); + g_return_if_fail (obj != NULL); + + _g_file_attribute_value_clear (attr); + attr->type = G_FILE_ATTRIBUTE_TYPE_OBJECT; + attr->u.obj = g_object_ref (obj); +} + +typedef struct { + GFileAttributeInfoList public; + GArray *array; + int ref_count; +} GFileAttributeInfoListPriv; + +static void +list_update_public (GFileAttributeInfoListPriv *priv) +{ + priv->public.infos = (GFileAttributeInfo *)priv->array->data; + priv->public.n_infos = priv->array->len; +} + +/** + * g_file_attribute_info_list_new: + * + * Creates a new file attribute info list. + * + * Returns: a #GFileAttributeInfoList. + */ +GFileAttributeInfoList * +g_file_attribute_info_list_new (void) +{ + GFileAttributeInfoListPriv *priv; + + priv = g_new0 (GFileAttributeInfoListPriv, 1); + + priv->ref_count = 1; + priv->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo)); + + list_update_public (priv); + + return (GFileAttributeInfoList *)priv; +} + +/** + * g_file_attribute_info_list_dup: + * @list: a #GFileAttributeInfoList to duplicate. + * + * Makes a duplicate of a file attribute info list. + * + * Returns: a copy of the given @list. + */ +GFileAttributeInfoList * +g_file_attribute_info_list_dup (GFileAttributeInfoList *list) +{ + GFileAttributeInfoListPriv *new; + int i; + + g_return_val_if_fail (list != NULL, NULL); + + new = g_new0 (GFileAttributeInfoListPriv, 1); + new->ref_count = 1; + new->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo)); + + g_array_set_size (new->array, list->n_infos); + list_update_public (new); + for (i = 0; i < list->n_infos; i++) + { + new->public.infos[i].name = g_strdup (list->infos[i].name); + new->public.infos[i].type = list->infos[i].type; + new->public.infos[i].flags = list->infos[i].flags; + } + + return (GFileAttributeInfoList *)new; +} + +/** + * g_file_attribute_info_list_ref: + * @list: a #GFileAttributeInfoList to reference. + * + * References a file attribute info list. + * + * Returns: #GFileAttributeInfoList or %NULL on error. + */ +GFileAttributeInfoList * +g_file_attribute_info_list_ref (GFileAttributeInfoList *list) +{ + GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list; + + g_return_val_if_fail (list != NULL, NULL); + g_return_val_if_fail (priv->ref_count > 0, NULL); + + g_atomic_int_inc (&priv->ref_count); + + return list; +} + +/** + * g_file_attribute_info_list_unref: + * @list: The #GFileAttributeInfoList to unreference. + * + * Removes a reference from the given @list. If the reference count + * falls to zero, the @list is deleted. + */ +void +g_file_attribute_info_list_unref (GFileAttributeInfoList *list) +{ + GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list; + int i; + + g_return_if_fail (list != NULL); + g_return_if_fail (priv->ref_count > 0); + + if (g_atomic_int_dec_and_test (&priv->ref_count)) + { + for (i = 0; i < list->n_infos; i++) + g_free (list->infos[i].name); + g_array_free (priv->array, TRUE); + g_free (list); + } +} + +static int +g_file_attribute_info_list_bsearch (GFileAttributeInfoList *list, + const char *name) +{ + int start, end, mid; + + start = 0; + end = list->n_infos; + + while (start != end) + { + mid = start + (end - start) / 2; + + if (strcmp (name, list->infos[mid].name) < 0) + end = mid; + else if (strcmp (name, list->infos[mid].name) > 0) + start = mid + 1; + else + return mid; + } + return start; +} + +/** + * g_file_attribute_info_list_lookup: + * @list: a #GFileAttributeInfoList. + * @name: the name of the attribute to look up. + * + * Gets the file attribute with the name @name from @list. + * + * Returns: a #GFileAttributeInfo for the @name, or %NULL if an + * attribute isn't found. + */ +const GFileAttributeInfo * +g_file_attribute_info_list_lookup (GFileAttributeInfoList *list, + const char *name) +{ + int i; + + g_return_val_if_fail (list != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + i = g_file_attribute_info_list_bsearch (list, name); + + if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0) + return &list->infos[i]; + + return NULL; +} + +/** + * g_file_attribute_info_list_add: + * @list: a #GFileAttributeInfoList. + * @name: the name of the attribute to add. + * @type: the #GFileAttributeType for the attribute. + * @flags: #GFileAttributeInfoFlags for the attribute. + * + * Adds a new attribute with @name to the @list, setting + * its @type and @flags. + */ +void +g_file_attribute_info_list_add (GFileAttributeInfoList *list, + const char *name, + GFileAttributeType type, + GFileAttributeInfoFlags flags) +{ + GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list; + GFileAttributeInfo info; + int i; + + g_return_if_fail (list != NULL); + g_return_if_fail (name != NULL); + + i = g_file_attribute_info_list_bsearch (list, name); + + if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0) + { + list->infos[i].type = type; + return; + } + + info.name = g_strdup (name); + info.type = type; + info.flags = flags; + g_array_insert_vals (priv->array, i, &info, 1); + + list_update_public (priv); +} diff --git a/gio/gfileattribute.h b/gio/gfileattribute.h new file mode 100644 index 0000000..a551047 --- /dev/null +++ b/gio/gfileattribute.h @@ -0,0 +1,84 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_ATTRIBUTE_H__ +#define __G_FILE_ATTRIBUTE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * GFileAttributeInfo: + * @name: the name of the attribute. + * @type: the #GFileAttributeType type of the attribute. + * @flags: a set of #GFileAttributeInfoFlags. + * + * Information about a specific attribute. + **/ +struct _GFileAttributeInfo +{ + char *name; + GFileAttributeType type; + GFileAttributeInfoFlags flags; +}; + +/** + * GFileAttributeInfoList: + * @infos: an array of #GFileAttributeInfos. + * @n_infos: the number of values in the array. + * + * Acts as a lightweight registry for possible valid file attributes. + * The registry stores Key-Value pair formats as #GFileAttributeInfos. + **/ +struct _GFileAttributeInfoList +{ + GFileAttributeInfo *infos; + int n_infos; +}; + +#define G_TYPE_FILE_ATTRIBUTE_INFO_LIST (g_file_attribute_info_list_get_type ()) +GLIB_AVAILABLE_IN_ALL +GType g_file_attribute_info_list_get_type (void); + +GLIB_AVAILABLE_IN_ALL +GFileAttributeInfoList * g_file_attribute_info_list_new (void); +GLIB_AVAILABLE_IN_ALL +GFileAttributeInfoList * g_file_attribute_info_list_ref (GFileAttributeInfoList *list); +GLIB_AVAILABLE_IN_ALL +void g_file_attribute_info_list_unref (GFileAttributeInfoList *list); +GLIB_AVAILABLE_IN_ALL +GFileAttributeInfoList * g_file_attribute_info_list_dup (GFileAttributeInfoList *list); +GLIB_AVAILABLE_IN_ALL +const GFileAttributeInfo *g_file_attribute_info_list_lookup (GFileAttributeInfoList *list, + const char *name); +GLIB_AVAILABLE_IN_ALL +void g_file_attribute_info_list_add (GFileAttributeInfoList *list, + const char *name, + GFileAttributeType type, + GFileAttributeInfoFlags flags); + +G_END_DECLS + +#endif /* __G_FILE_INFO_H__ */ diff --git a/gio/gfiledescriptorbased.c b/gio/gfiledescriptorbased.c new file mode 100644 index 0000000..54655dd --- /dev/null +++ b/gio/gfiledescriptorbased.c @@ -0,0 +1,71 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Christian Kellner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#include "config.h" +#include "gfiledescriptorbased.h" +#include "glibintl.h" + + +/** + * SECTION:gfiledescriptorbased + * @short_description: Interface for file descriptor based IO + * @include: gio/gfiledescriptorbased.h + * @see_also: #GInputStream, #GOutputStream + * + * #GFileDescriptorBased is implemented by streams (implementations of + * #GInputStream or #GOutputStream) that are based on file descriptors. + * + * Note that `` belongs to the UNIX-specific + * GIO interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config + * file when using it. + * + * Since: 2.24 + * + **/ + +typedef GFileDescriptorBasedIface GFileDescriptorBasedInterface; +G_DEFINE_INTERFACE (GFileDescriptorBased, g_file_descriptor_based, G_TYPE_OBJECT) + +static void +g_file_descriptor_based_default_init (GFileDescriptorBasedInterface *iface) +{ +} + +/** + * g_file_descriptor_based_get_fd: + * @fd_based: a #GFileDescriptorBased. + * + * Gets the underlying file descriptor. + * + * Returns: The file descriptor + * + * Since: 2.24 + **/ +int +g_file_descriptor_based_get_fd (GFileDescriptorBased *fd_based) +{ + GFileDescriptorBasedIface *iface; + + g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (fd_based), 0); + + iface = G_FILE_DESCRIPTOR_BASED_GET_IFACE (fd_based); + + return (* iface->get_fd) (fd_based); +} diff --git a/gio/gfiledescriptorbased.h b/gio/gfiledescriptorbased.h new file mode 100644 index 0000000..0a2516e --- /dev/null +++ b/gio/gfiledescriptorbased.h @@ -0,0 +1,65 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Christian Kellner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#ifndef __G_FILE_DESCRIPTOR_BASED_H__ +#define __G_FILE_DESCRIPTOR_BASED_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_DESCRIPTOR_BASED (g_file_descriptor_based_get_type ()) +#define G_FILE_DESCRIPTOR_BASED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_FILE_DESCRIPTOR_BASED, GFileDescriptorBased)) +#define G_IS_FILE_DESCRIPTOR_BASED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_FILE_DESCRIPTOR_BASED)) +#define G_FILE_DESCRIPTOR_BASED_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_FILE_DESCRIPTOR_BASED, GFileDescriptorBasedIface)) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileDescriptorBased, g_object_unref) + +/** + * GFileDescriptorBased: + * + * An interface for file descriptor based io objects. + **/ +typedef struct _GFileDescriptorBasedIface GFileDescriptorBasedIface; + +/** + * GFileDescriptorBasedIface: + * @g_iface: The parent interface. + * @get_fd: Gets the underlying file descriptor. + * + * An interface for file descriptor based io objects. + **/ +struct _GFileDescriptorBasedIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + int (*get_fd) (GFileDescriptorBased *fd_based); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_file_descriptor_based_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +int g_file_descriptor_based_get_fd (GFileDescriptorBased *fd_based); + +G_END_DECLS + + +#endif /* __G_FILE_DESCRIPTOR_BASED_H__ */ diff --git a/gio/gfileenumerator.c b/gio/gfileenumerator.c new file mode 100644 index 0000000..e0ed972 --- /dev/null +++ b/gio/gfileenumerator.c @@ -0,0 +1,887 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "gfileenumerator.h" +#include "gfile.h" +#include "gioscheduler.h" +#include "gasyncresult.h" +#include "gasynchelper.h" +#include "gioerror.h" +#include "glibintl.h" + +struct _GFileEnumeratorPrivate { + /* TODO: Should be public for subclasses? */ + GFile *container; + guint closed : 1; + guint pending : 1; + GAsyncReadyCallback outstanding_callback; + GError *outstanding_error; +}; + +/** + * SECTION:gfileenumerator + * @short_description: Enumerated Files Routines + * @include: gio/gio.h + * + * #GFileEnumerator allows you to operate on a set of #GFiles, + * returning a #GFileInfo structure for each file enumerated (e.g. + * g_file_enumerate_children() will return a #GFileEnumerator for each + * of the children within a directory). + * + * To get the next file's information from a #GFileEnumerator, use + * g_file_enumerator_next_file() or its asynchronous version, + * g_file_enumerator_next_files_async(). Note that the asynchronous + * version will return a list of #GFileInfos, whereas the + * synchronous will only return the next file in the enumerator. + * + * The ordering of returned files is unspecified for non-Unix + * platforms; for more information, see g_dir_read_name(). On Unix, + * when operating on local files, returned files will be sorted by + * inode number. Effectively you can assume that the ordering of + * returned files will be stable between successive calls (and + * applications) assuming the directory is unchanged. + * + * If your application needs a specific ordering, such as by name or + * modification time, you will have to implement that in your + * application code. + * + * To close a #GFileEnumerator, use g_file_enumerator_close(), or + * its asynchronous version, g_file_enumerator_close_async(). Once + * a #GFileEnumerator is closed, no further actions may be performed + * on it, and it should be freed with g_object_unref(). + * + **/ + +G_DEFINE_TYPE_WITH_PRIVATE (GFileEnumerator, g_file_enumerator, G_TYPE_OBJECT) + +enum { + PROP_0, + PROP_CONTAINER +}; + +static void g_file_enumerator_real_next_files_async (GFileEnumerator *enumerator, + int num_files, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GList * g_file_enumerator_real_next_files_finish (GFileEnumerator *enumerator, + GAsyncResult *res, + GError **error); +static void g_file_enumerator_real_close_async (GFileEnumerator *enumerator, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_file_enumerator_real_close_finish (GFileEnumerator *enumerator, + GAsyncResult *res, + GError **error); + +static void +g_file_enumerator_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GFileEnumerator *enumerator; + + enumerator = G_FILE_ENUMERATOR (object); + + switch (property_id) { + case PROP_CONTAINER: + enumerator->priv->container = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +g_file_enumerator_dispose (GObject *object) +{ + GFileEnumerator *enumerator; + + enumerator = G_FILE_ENUMERATOR (object); + + if (enumerator->priv->container) { + g_object_unref (enumerator->priv->container); + enumerator->priv->container = NULL; + } + + G_OBJECT_CLASS (g_file_enumerator_parent_class)->dispose (object); +} + +static void +g_file_enumerator_finalize (GObject *object) +{ + GFileEnumerator *enumerator; + + enumerator = G_FILE_ENUMERATOR (object); + + if (!enumerator->priv->closed) + g_file_enumerator_close (enumerator, NULL, NULL); + + G_OBJECT_CLASS (g_file_enumerator_parent_class)->finalize (object); +} + +static void +g_file_enumerator_class_init (GFileEnumeratorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = g_file_enumerator_set_property; + gobject_class->dispose = g_file_enumerator_dispose; + gobject_class->finalize = g_file_enumerator_finalize; + + klass->next_files_async = g_file_enumerator_real_next_files_async; + klass->next_files_finish = g_file_enumerator_real_next_files_finish; + klass->close_async = g_file_enumerator_real_close_async; + klass->close_finish = g_file_enumerator_real_close_finish; + + g_object_class_install_property + (gobject_class, PROP_CONTAINER, + g_param_spec_object ("container", P_("Container"), + P_("The container that is being enumerated"), + G_TYPE_FILE, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_file_enumerator_init (GFileEnumerator *enumerator) +{ + enumerator->priv = g_file_enumerator_get_instance_private (enumerator); +} + +/** + * g_file_enumerator_next_file: + * @enumerator: a #GFileEnumerator. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Returns information for the next file in the enumerated object. + * Will block until the information is available. The #GFileInfo + * returned from this function will contain attributes that match the + * attribute string that was passed when the #GFileEnumerator was created. + * + * See the documentation of #GFileEnumerator for information about the + * order of returned files. + * + * On error, returns %NULL and sets @error to the error. If the + * enumerator is at the end, %NULL will be returned and @error will + * be unset. + * + * Returns: (nullable) (transfer full): A #GFileInfo or %NULL on error + * or end of enumerator. Free the returned object with + * g_object_unref() when no longer needed. + **/ +GFileInfo * +g_file_enumerator_next_file (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GFileEnumeratorClass *class; + GFileInfo *info; + + g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (enumerator != NULL, NULL); + + if (enumerator->priv->closed) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Enumerator is closed")); + return NULL; + } + + if (enumerator->priv->pending) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING, + _("File enumerator has outstanding operation")); + return NULL; + } + + if (enumerator->priv->outstanding_error) + { + g_propagate_error (error, enumerator->priv->outstanding_error); + enumerator->priv->outstanding_error = NULL; + return NULL; + } + + class = G_FILE_ENUMERATOR_GET_CLASS (enumerator); + + if (cancellable) + g_cancellable_push_current (cancellable); + + enumerator->priv->pending = TRUE; + info = (* class->next_file) (enumerator, cancellable, error); + enumerator->priv->pending = FALSE; + + if (cancellable) + g_cancellable_pop_current (cancellable); + + return info; +} + +/** + * g_file_enumerator_close: + * @enumerator: a #GFileEnumerator. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Releases all resources used by this enumerator, making the + * enumerator return %G_IO_ERROR_CLOSED on all calls. + * + * This will be automatically called when the last reference + * is dropped, but you might want to call this function to make + * sure resources are released as early as possible. + * + * Returns: #TRUE on success or #FALSE on error. + **/ +gboolean +g_file_enumerator_close (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GFileEnumeratorClass *class; + + g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), FALSE); + g_return_val_if_fail (enumerator != NULL, FALSE); + + class = G_FILE_ENUMERATOR_GET_CLASS (enumerator); + + if (enumerator->priv->closed) + return TRUE; + + if (enumerator->priv->pending) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING, + _("File enumerator has outstanding operation")); + return FALSE; + } + + if (cancellable) + g_cancellable_push_current (cancellable); + + enumerator->priv->pending = TRUE; + (* class->close_fn) (enumerator, cancellable, error); + enumerator->priv->pending = FALSE; + enumerator->priv->closed = TRUE; + + if (cancellable) + g_cancellable_pop_current (cancellable); + + return TRUE; +} + +static void +next_async_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GFileEnumerator *enumerator = G_FILE_ENUMERATOR (source_object); + + enumerator->priv->pending = FALSE; + if (enumerator->priv->outstanding_callback) + (*enumerator->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (enumerator); +} + +/** + * g_file_enumerator_next_files_async: + * @enumerator: a #GFileEnumerator. + * @num_files: the number of file info objects to request + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request information for a number of files from the enumerator asynchronously. + * When all i/o for the operation is finished the @callback will be called with + * the requested information. + * + * See the documentation of #GFileEnumerator for information about the + * order of returned files. + * + * The callback can be called with less than @num_files files in case of error + * or at the end of the enumerator. In case of a partial error the callback will + * be called with any succeeding items and no error, and on the next request the + * error will be reported. If a request is cancelled the callback will be called + * with %G_IO_ERROR_CANCELLED. + * + * During an async request no other sync and async calls are allowed, and will + * result in %G_IO_ERROR_PENDING errors. + * + * Any outstanding i/o request with higher priority (lower numerical value) will + * be executed before an outstanding request with lower priority. Default + * priority is %G_PRIORITY_DEFAULT. + **/ +void +g_file_enumerator_next_files_async (GFileEnumerator *enumerator, + int num_files, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileEnumeratorClass *class; + + g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator)); + g_return_if_fail (enumerator != NULL); + g_return_if_fail (num_files >= 0); + + if (num_files == 0) + { + GTask *task; + + task = g_task_new (enumerator, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_enumerator_next_files_async); + g_task_return_pointer (task, NULL, NULL); + g_object_unref (task); + return; + } + + if (enumerator->priv->closed) + { + g_task_report_new_error (enumerator, callback, user_data, + g_file_enumerator_next_files_async, + G_IO_ERROR, G_IO_ERROR_CLOSED, + _("File enumerator is already closed")); + return; + } + + if (enumerator->priv->pending) + { + g_task_report_new_error (enumerator, callback, user_data, + g_file_enumerator_next_files_async, + G_IO_ERROR, G_IO_ERROR_PENDING, + _("File enumerator has outstanding operation")); + return; + } + + class = G_FILE_ENUMERATOR_GET_CLASS (enumerator); + + enumerator->priv->pending = TRUE; + enumerator->priv->outstanding_callback = callback; + g_object_ref (enumerator); + (* class->next_files_async) (enumerator, num_files, io_priority, cancellable, + next_async_callback_wrapper, user_data); +} + +/** + * g_file_enumerator_next_files_finish: + * @enumerator: a #GFileEnumerator. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes the asynchronous operation started with g_file_enumerator_next_files_async(). + * + * Returns: (transfer full) (element-type Gio.FileInfo): a #GList of #GFileInfos. You must free the list with + * g_list_free() and unref the infos with g_object_unref() when you're + * done with them. + **/ +GList * +g_file_enumerator_next_files_finish (GFileEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + GFileEnumeratorClass *class; + + g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + else if (g_async_result_is_tagged (result, g_file_enumerator_next_files_async)) + return g_task_propagate_pointer (G_TASK (result), error); + + class = G_FILE_ENUMERATOR_GET_CLASS (enumerator); + return class->next_files_finish (enumerator, result, error); +} + +static void +close_async_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GFileEnumerator *enumerator = G_FILE_ENUMERATOR (source_object); + + enumerator->priv->pending = FALSE; + enumerator->priv->closed = TRUE; + if (enumerator->priv->outstanding_callback) + (*enumerator->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (enumerator); +} + +/** + * g_file_enumerator_close_async: + * @enumerator: a #GFileEnumerator. + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously closes the file enumerator. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned in + * g_file_enumerator_close_finish(). + **/ +void +g_file_enumerator_close_async (GFileEnumerator *enumerator, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileEnumeratorClass *class; + + g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator)); + + if (enumerator->priv->closed) + { + g_task_report_new_error (enumerator, callback, user_data, + g_file_enumerator_close_async, + G_IO_ERROR, G_IO_ERROR_CLOSED, + _("File enumerator is already closed")); + return; + } + + if (enumerator->priv->pending) + { + g_task_report_new_error (enumerator, callback, user_data, + g_file_enumerator_close_async, + G_IO_ERROR, G_IO_ERROR_PENDING, + _("File enumerator has outstanding operation")); + return; + } + + class = G_FILE_ENUMERATOR_GET_CLASS (enumerator); + + enumerator->priv->pending = TRUE; + enumerator->priv->outstanding_callback = callback; + g_object_ref (enumerator); + (* class->close_async) (enumerator, io_priority, cancellable, + close_async_callback_wrapper, user_data); +} + +/** + * g_file_enumerator_close_finish: + * @enumerator: a #GFileEnumerator. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes closing a file enumerator, started from g_file_enumerator_close_async(). + * + * If the file enumerator was already closed when g_file_enumerator_close_async() + * was called, then this function will report %G_IO_ERROR_CLOSED in @error, and + * return %FALSE. If the file enumerator had pending operation when the close + * operation was started, then this function will report %G_IO_ERROR_PENDING, and + * return %FALSE. If @cancellable was not %NULL, then the operation may have been + * cancelled by triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be set, and %FALSE will be + * returned. + * + * Returns: %TRUE if the close operation has finished successfully. + **/ +gboolean +g_file_enumerator_close_finish (GFileEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + GFileEnumeratorClass *class; + + g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_file_enumerator_close_async)) + return g_task_propagate_boolean (G_TASK (result), error); + + class = G_FILE_ENUMERATOR_GET_CLASS (enumerator); + return class->close_finish (enumerator, result, error); +} + +/** + * g_file_enumerator_is_closed: + * @enumerator: a #GFileEnumerator. + * + * Checks if the file enumerator has been closed. + * + * Returns: %TRUE if the @enumerator is closed. + **/ +gboolean +g_file_enumerator_is_closed (GFileEnumerator *enumerator) +{ + g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), TRUE); + + return enumerator->priv->closed; +} + +/** + * g_file_enumerator_has_pending: + * @enumerator: a #GFileEnumerator. + * + * Checks if the file enumerator has pending operations. + * + * Returns: %TRUE if the @enumerator has pending operations. + **/ +gboolean +g_file_enumerator_has_pending (GFileEnumerator *enumerator) +{ + g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), TRUE); + + return enumerator->priv->pending; +} + +/** + * g_file_enumerator_set_pending: + * @enumerator: a #GFileEnumerator. + * @pending: a boolean value. + * + * Sets the file enumerator as having pending operations. + **/ +void +g_file_enumerator_set_pending (GFileEnumerator *enumerator, + gboolean pending) +{ + g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator)); + + enumerator->priv->pending = pending; +} + +/** + * g_file_enumerator_iterate: + * @direnum: an open #GFileEnumerator + * @out_info: (out) (transfer none) (optional): Output location for the next #GFileInfo, or %NULL + * @out_child: (out) (transfer none) (optional): Output location for the next #GFile, or %NULL + * @cancellable: a #GCancellable + * @error: a #GError + * + * This is a version of g_file_enumerator_next_file() that's easier to + * use correctly from C programs. With g_file_enumerator_next_file(), + * the gboolean return value signifies "end of iteration or error", which + * requires allocation of a temporary #GError. + * + * In contrast, with this function, a %FALSE return from + * g_file_enumerator_iterate() *always* means + * "error". End of iteration is signaled by @out_info or @out_child being %NULL. + * + * Another crucial difference is that the references for @out_info and + * @out_child are owned by @direnum (they are cached as hidden + * properties). You must not unref them in your own code. This makes + * memory management significantly easier for C code in combination + * with loops. + * + * Finally, this function optionally allows retrieving a #GFile as + * well. + * + * You must specify at least one of @out_info or @out_child. + * + * The code pattern for correctly using g_file_enumerator_iterate() from C + * is: + * + * |[ + * direnum = g_file_enumerate_children (file, ...); + * while (TRUE) + * { + * GFileInfo *info; + * if (!g_file_enumerator_iterate (direnum, &info, NULL, cancellable, error)) + * goto out; + * if (!info) + * break; + * ... do stuff with "info"; do not unref it! ... + * } + * + * out: + * g_object_unref (direnum); // Note: frees the last @info + * ]| + * + * + * Since: 2.44 + */ +gboolean +g_file_enumerator_iterate (GFileEnumerator *direnum, + GFileInfo **out_info, + GFile **out_child, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + GError *temp_error = NULL; + GFileInfo *ret_info = NULL; + + static GQuark cached_info_quark; + static GQuark cached_child_quark; + static gsize quarks_initialized; + + g_return_val_if_fail (direnum != NULL, FALSE); + g_return_val_if_fail (out_info != NULL || out_child != NULL, FALSE); + + if (g_once_init_enter (&quarks_initialized)) + { + cached_info_quark = g_quark_from_static_string ("g-cached-info"); + cached_child_quark = g_quark_from_static_string ("g-cached-child"); + g_once_init_leave (&quarks_initialized, 1); + } + + ret_info = g_file_enumerator_next_file (direnum, cancellable, &temp_error); + if (temp_error != NULL) + { + g_propagate_error (error, temp_error); + goto out; + } + + if (ret_info) + { + if (out_child != NULL) + { + const char *name = g_file_info_get_name (ret_info); + + if (G_UNLIKELY (name == NULL)) + { + g_critical ("g_file_enumerator_iterate() created without standard::name"); + g_return_val_if_reached (FALSE); + } + else + { + *out_child = g_file_get_child (g_file_enumerator_get_container (direnum), name); + g_object_set_qdata_full ((GObject*)direnum, cached_child_quark, *out_child, (GDestroyNotify)g_object_unref); + } + } + if (out_info != NULL) + { + g_object_set_qdata_full ((GObject*)direnum, cached_info_quark, ret_info, (GDestroyNotify)g_object_unref); + *out_info = ret_info; + } + else + g_object_unref (ret_info); + } + else + { + if (out_info) + *out_info = NULL; + if (out_child) + *out_child = NULL; + } + + ret = TRUE; + out: + return ret; +} + +/** + * g_file_enumerator_get_container: + * @enumerator: a #GFileEnumerator + * + * Get the #GFile container which is being enumerated. + * + * Returns: (transfer none): the #GFile which is being enumerated. + * + * Since: 2.18 + */ +GFile * +g_file_enumerator_get_container (GFileEnumerator *enumerator) +{ + g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), NULL); + + return enumerator->priv->container; +} + +/** + * g_file_enumerator_get_child: + * @enumerator: a #GFileEnumerator + * @info: a #GFileInfo gotten from g_file_enumerator_next_file() + * or the async equivalents. + * + * Return a new #GFile which refers to the file named by @info in the source + * directory of @enumerator. This function is primarily intended to be used + * inside loops with g_file_enumerator_next_file(). + * + * To use this, %G_FILE_ATTRIBUTE_STANDARD_NAME must have been listed in the + * attributes list used when creating the #GFileEnumerator. + * + * This is a convenience method that's equivalent to: + * |[ + * gchar *name = g_file_info_get_name (info); + * GFile *child = g_file_get_child (g_file_enumerator_get_container (enumr), + * name); + * ]| + * + * Returns: (transfer full): a #GFile for the #GFileInfo passed it. + * + * Since: 2.36 + */ +GFile * +g_file_enumerator_get_child (GFileEnumerator *enumerator, + GFileInfo *info) +{ + const gchar *name; + + g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), NULL); + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + name = g_file_info_get_name (info); + + if (G_UNLIKELY (name == NULL)) + { + g_critical ("GFileEnumerator created without standard::name"); + g_return_val_if_reached (NULL); + } + + return g_file_get_child (enumerator->priv->container, name); +} + +static void +next_async_op_free (GList *files) +{ + g_list_free_full (files, g_object_unref); +} + +static void +next_files_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileEnumerator *enumerator = source_object; + int num_files = GPOINTER_TO_INT (task_data); + GFileEnumeratorClass *class; + GList *files = NULL; + GError *error = NULL; + GFileInfo *info; + int i; + + class = G_FILE_ENUMERATOR_GET_CLASS (enumerator); + + for (i = 0; i < num_files; i++) + { + if (g_cancellable_set_error_if_cancelled (cancellable, &error)) + info = NULL; + else + info = class->next_file (enumerator, cancellable, &error); + + if (info == NULL) + { + /* If we get an error after first file, return that on next operation */ + if (error != NULL && i > 0) + { + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_error_free (error); /* Never propagate cancel errors to other call */ + else + enumerator->priv->outstanding_error = error; + error = NULL; + } + + break; + } + else + files = g_list_prepend (files, info); + } + + if (error) + { + g_list_free_full (files, g_object_unref); + g_task_return_error (task, error); + } + else + g_task_return_pointer (task, files, (GDestroyNotify)next_async_op_free); +} + +static void +g_file_enumerator_real_next_files_async (GFileEnumerator *enumerator, + int num_files, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (enumerator, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_enumerator_real_next_files_async); + g_task_set_task_data (task, GINT_TO_POINTER (num_files), NULL); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, next_files_thread); + g_object_unref (task); +} + +static GList * +g_file_enumerator_real_next_files_finish (GFileEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +close_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileEnumerator *enumerator = source_object; + GFileEnumeratorClass *class; + GError *error = NULL; + gboolean result; + + class = G_FILE_ENUMERATOR_GET_CLASS (enumerator); + result = class->close_fn (enumerator, cancellable, &error); + if (result) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +static void +g_file_enumerator_real_close_async (GFileEnumerator *enumerator, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (enumerator, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_enumerator_real_close_async); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, close_async_thread); + g_object_unref (task); +} + +static gboolean +g_file_enumerator_real_close_finish (GFileEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, enumerator), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} diff --git a/gio/gfileenumerator.h b/gio/gfileenumerator.h new file mode 100644 index 0000000..d4fd396 --- /dev/null +++ b/gio/gfileenumerator.h @@ -0,0 +1,152 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_ENUMERATOR_H__ +#define __G_FILE_ENUMERATOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_ENUMERATOR (g_file_enumerator_get_type ()) +#define G_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_ENUMERATOR, GFileEnumerator)) +#define G_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_ENUMERATOR, GFileEnumeratorClass)) +#define G_IS_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_ENUMERATOR)) +#define G_IS_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_ENUMERATOR)) +#define G_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_ENUMERATOR, GFileEnumeratorClass)) + +/** + * GFileEnumerator: + * + * A per matched file iterator. + **/ +typedef struct _GFileEnumeratorClass GFileEnumeratorClass; +typedef struct _GFileEnumeratorPrivate GFileEnumeratorPrivate; + +struct _GFileEnumerator +{ + GObject parent_instance; + + /*< private >*/ + GFileEnumeratorPrivate *priv; +}; + +struct _GFileEnumeratorClass +{ + GObjectClass parent_class; + + /* Virtual Table */ + + GFileInfo * (* next_file) (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error); + gboolean (* close_fn) (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error); + + void (* next_files_async) (GFileEnumerator *enumerator, + int num_files, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GList * (* next_files_finish) (GFileEnumerator *enumerator, + GAsyncResult *result, + GError **error); + void (* close_async) (GFileEnumerator *enumerator, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* close_finish) (GFileEnumerator *enumerator, + GAsyncResult *result, + GError **error); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); + void (*_g_reserved7) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_file_enumerator_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_file_enumerator_next_file (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_enumerator_close (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_enumerator_next_files_async (GFileEnumerator *enumerator, + int num_files, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GList * g_file_enumerator_next_files_finish (GFileEnumerator *enumerator, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_enumerator_close_async (GFileEnumerator *enumerator, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_enumerator_close_finish (GFileEnumerator *enumerator, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_enumerator_is_closed (GFileEnumerator *enumerator); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_enumerator_has_pending (GFileEnumerator *enumerator); +GLIB_AVAILABLE_IN_ALL +void g_file_enumerator_set_pending (GFileEnumerator *enumerator, + gboolean pending); +GLIB_AVAILABLE_IN_ALL +GFile * g_file_enumerator_get_container (GFileEnumerator *enumerator); +GLIB_AVAILABLE_IN_2_36 +GFile * g_file_enumerator_get_child (GFileEnumerator *enumerator, + GFileInfo *info); + +GLIB_AVAILABLE_IN_2_44 +gboolean g_file_enumerator_iterate (GFileEnumerator *direnum, + GFileInfo **out_info, + GFile **out_child, + GCancellable *cancellable, + GError **error); + + +G_END_DECLS + +#endif /* __G_FILE_ENUMERATOR_H__ */ diff --git a/gio/gfileicon.c b/gio/gfileicon.c new file mode 100644 index 0000000..2f28d48 --- /dev/null +++ b/gio/gfileicon.c @@ -0,0 +1,366 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gfileicon.h" +#include "gfile.h" +#include "gicon.h" +#include "glibintl.h" +#include "gloadableicon.h" +#include "ginputstream.h" +#include "gtask.h" +#include "gioerror.h" + + +/** + * SECTION:gfileicon + * @short_description: Icons pointing to an image file + * @include: gio/gio.h + * @see_also: #GIcon, #GLoadableIcon + * + * #GFileIcon specifies an icon by pointing to an image file + * to be used as icon. + * + **/ + +static void g_file_icon_icon_iface_init (GIconIface *iface); +static void g_file_icon_loadable_icon_iface_init (GLoadableIconIface *iface); +static void g_file_icon_load_async (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +struct _GFileIcon +{ + GObject parent_instance; + + GFile *file; +}; + +struct _GFileIconClass +{ + GObjectClass parent_class; +}; + +enum +{ + PROP_0, + PROP_FILE +}; + +G_DEFINE_TYPE_WITH_CODE (GFileIcon, g_file_icon, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ICON, + g_file_icon_icon_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON, + g_file_icon_loadable_icon_iface_init)) + +static void +g_file_icon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GFileIcon *icon = G_FILE_ICON (object); + + switch (prop_id) + { + case PROP_FILE: + g_value_set_object (value, icon->file); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_file_icon_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GFileIcon *icon = G_FILE_ICON (object); + + switch (prop_id) + { + case PROP_FILE: + icon->file = G_FILE (g_value_dup_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_file_icon_constructed (GObject *object) +{ +#ifndef G_DISABLE_ASSERT + GFileIcon *icon = G_FILE_ICON (object); +#endif + + G_OBJECT_CLASS (g_file_icon_parent_class)->constructed (object); + + /* Must have be set during construction */ + g_assert (icon->file != NULL); +} + +static void +g_file_icon_finalize (GObject *object) +{ + GFileIcon *icon; + + icon = G_FILE_ICON (object); + + if (icon->file) + g_object_unref (icon->file); + + G_OBJECT_CLASS (g_file_icon_parent_class)->finalize (object); +} + +static void +g_file_icon_class_init (GFileIconClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = g_file_icon_get_property; + gobject_class->set_property = g_file_icon_set_property; + gobject_class->finalize = g_file_icon_finalize; + gobject_class->constructed = g_file_icon_constructed; + + /** + * GFileIcon:file: + * + * The file containing the icon. + */ + g_object_class_install_property (gobject_class, PROP_FILE, + g_param_spec_object ("file", + P_("file"), + P_("The file containing the icon"), + G_TYPE_FILE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); +} + +static void +g_file_icon_init (GFileIcon *file) +{ +} + +/** + * g_file_icon_new: + * @file: a #GFile. + * + * Creates a new icon for a file. + * + * Returns: (transfer full) (type GFileIcon): a #GIcon for the given + * @file, or %NULL on error. + **/ +GIcon * +g_file_icon_new (GFile *file) +{ + g_return_val_if_fail (G_IS_FILE (file), NULL); + + return G_ICON (g_object_new (G_TYPE_FILE_ICON, "file", file, NULL)); +} + +/** + * g_file_icon_get_file: + * @icon: a #GIcon. + * + * Gets the #GFile associated with the given @icon. + * + * Returns: (transfer none): a #GFile. + **/ +GFile * +g_file_icon_get_file (GFileIcon *icon) +{ + g_return_val_if_fail (G_IS_FILE_ICON (icon), NULL); + + return icon->file; +} + +static guint +g_file_icon_hash (GIcon *icon) +{ + GFileIcon *file_icon = G_FILE_ICON (icon); + + return g_file_hash (file_icon->file); +} + +static gboolean +g_file_icon_equal (GIcon *icon1, + GIcon *icon2) +{ + GFileIcon *file1 = G_FILE_ICON (icon1); + GFileIcon *file2 = G_FILE_ICON (icon2); + + return g_file_equal (file1->file, file2->file); +} + +static gboolean +g_file_icon_to_tokens (GIcon *icon, + GPtrArray *tokens, + gint *out_version) +{ + GFileIcon *file_icon = G_FILE_ICON (icon); + + g_return_val_if_fail (out_version != NULL, FALSE); + + *out_version = 0; + + g_ptr_array_add (tokens, g_file_get_uri (file_icon->file)); + return TRUE; +} + +static GIcon * +g_file_icon_from_tokens (gchar **tokens, + gint num_tokens, + gint version, + GError **error) +{ + GIcon *icon; + GFile *file; + + icon = NULL; + + if (version != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Can’t handle version %d of GFileIcon encoding"), + version); + goto out; + } + + if (num_tokens != 1) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Malformed input data for GFileIcon")); + goto out; + } + + file = g_file_new_for_uri (tokens[0]); + icon = g_file_icon_new (file); + g_object_unref (file); + + out: + return icon; +} + +static GVariant * +g_file_icon_serialize (GIcon *icon) +{ + GFileIcon *file_icon = G_FILE_ICON (icon); + + return g_variant_new ("(sv)", "file", g_variant_new_take_string (g_file_get_uri (file_icon->file))); +} + +static void +g_file_icon_icon_iface_init (GIconIface *iface) +{ + iface->hash = g_file_icon_hash; + iface->equal = g_file_icon_equal; + iface->to_tokens = g_file_icon_to_tokens; + iface->from_tokens = g_file_icon_from_tokens; + iface->serialize = g_file_icon_serialize; +} + + +static GInputStream * +g_file_icon_load (GLoadableIcon *icon, + int size, + char **type, + GCancellable *cancellable, + GError **error) +{ + GFileInputStream *stream; + GFileIcon *file_icon = G_FILE_ICON (icon); + + stream = g_file_read (file_icon->file, + cancellable, + error); + + if (stream && type) + *type = NULL; + + return G_INPUT_STREAM (stream); +} + +static void +load_async_callback (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GFileInputStream *stream; + GError *error = NULL; + GTask *task = user_data; + + stream = g_file_read_finish (G_FILE (source_object), res, &error); + if (stream == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, stream, g_object_unref); + g_object_unref (task); +} + +static void +g_file_icon_load_async (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIcon *file_icon = G_FILE_ICON (icon); + GTask *task; + + task = g_task_new (icon, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_icon_load_async); + + g_file_read_async (file_icon->file, 0, + cancellable, + load_async_callback, task); +} + +static GInputStream * +g_file_icon_load_finish (GLoadableIcon *icon, + GAsyncResult *res, + char **type, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, icon), NULL); + + if (type) + *type = NULL; + + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +g_file_icon_loadable_icon_iface_init (GLoadableIconIface *iface) +{ + iface->load = g_file_icon_load; + iface->load_async = g_file_icon_load_async; + iface->load_finish = g_file_icon_load_finish; +} diff --git a/gio/gfileicon.h b/gio/gfileicon.h new file mode 100644 index 0000000..08a4ea6 --- /dev/null +++ b/gio/gfileicon.h @@ -0,0 +1,57 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_ICON_H__ +#define __G_FILE_ICON_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_ICON (g_file_icon_get_type ()) +#define G_FILE_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_ICON, GFileIcon)) +#define G_FILE_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_ICON, GFileIconClass)) +#define G_IS_FILE_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_ICON)) +#define G_IS_FILE_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_ICON)) +#define G_FILE_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_ICON, GFileIconClass)) + +/** + * GFileIcon: + * + * Gets an icon for a #GFile. Implements #GLoadableIcon. + **/ +typedef struct _GFileIconClass GFileIconClass; + +GLIB_AVAILABLE_IN_ALL +GType g_file_icon_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GIcon * g_file_icon_new (GFile *file); + +GLIB_AVAILABLE_IN_ALL +GFile * g_file_icon_get_file (GFileIcon *icon); + +G_END_DECLS + +#endif /* __G_FILE_ICON_H__ */ diff --git a/gio/gfileinfo-priv.h b/gio/gfileinfo-priv.h new file mode 100644 index 0000000..e2bdaa3 --- /dev/null +++ b/gio/gfileinfo-priv.h @@ -0,0 +1,144 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * 2009 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Benjamin Otte + */ + +#ifndef __G_FILE_INFO_PRIV_H__ +#define __G_FILE_INFO_PRIV_H__ + +#include "gfileinfo.h" + +#define G_FILE_ATTRIBUTE_ID_STANDARD_TYPE (1048576 + 1) +#define G_FILE_ATTRIBUTE_ID_STANDARD_IS_HIDDEN (1048576 + 2) +#define G_FILE_ATTRIBUTE_ID_STANDARD_IS_BACKUP (1048576 + 3) +#define G_FILE_ATTRIBUTE_ID_STANDARD_IS_SYMLINK (1048576 + 4) +#define G_FILE_ATTRIBUTE_ID_STANDARD_IS_VIRTUAL (1048576 + 5) +#define G_FILE_ATTRIBUTE_ID_STANDARD_NAME (1048576 + 6) +#define G_FILE_ATTRIBUTE_ID_STANDARD_DISPLAY_NAME (1048576 + 7) +#define G_FILE_ATTRIBUTE_ID_STANDARD_EDIT_NAME (1048576 + 8) +#define G_FILE_ATTRIBUTE_ID_STANDARD_COPY_NAME (1048576 + 9) +#define G_FILE_ATTRIBUTE_ID_STANDARD_DESCRIPTION (1048576 + 10) +#define G_FILE_ATTRIBUTE_ID_STANDARD_ICON (1048576 + 11) +#define G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE (1048576 + 12) +#define G_FILE_ATTRIBUTE_ID_STANDARD_FAST_CONTENT_TYPE (1048576 + 13) +#define G_FILE_ATTRIBUTE_ID_STANDARD_SIZE (1048576 + 14) +#define G_FILE_ATTRIBUTE_ID_STANDARD_ALLOCATED_SIZE (1048576 + 15) +#define G_FILE_ATTRIBUTE_ID_STANDARD_SYMLINK_TARGET (1048576 + 16) +#define G_FILE_ATTRIBUTE_ID_STANDARD_TARGET_URI (1048576 + 17) +#define G_FILE_ATTRIBUTE_ID_STANDARD_SORT_ORDER (1048576 + 18) +#define G_FILE_ATTRIBUTE_ID_STANDARD_SYMBOLIC_ICON (1048576 + 19) +#define G_FILE_ATTRIBUTE_ID_STANDARD_IS_VOLATILE (1048576 + 20) +#define G_FILE_ATTRIBUTE_ID_ETAG_VALUE (2097152 + 1) +#define G_FILE_ATTRIBUTE_ID_ID_FILE (3145728 + 1) +#define G_FILE_ATTRIBUTE_ID_ID_FILESYSTEM (3145728 + 2) +#define G_FILE_ATTRIBUTE_ID_ACCESS_CAN_READ (4194304 + 1) +#define G_FILE_ATTRIBUTE_ID_ACCESS_CAN_WRITE (4194304 + 2) +#define G_FILE_ATTRIBUTE_ID_ACCESS_CAN_EXECUTE (4194304 + 3) +#define G_FILE_ATTRIBUTE_ID_ACCESS_CAN_DELETE (4194304 + 4) +#define G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH (4194304 + 5) +#define G_FILE_ATTRIBUTE_ID_ACCESS_CAN_RENAME (4194304 + 6) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_CAN_MOUNT (5242880 + 1) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_CAN_UNMOUNT (5242880 + 2) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_CAN_EJECT (5242880 + 3) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_UNIX_DEVICE (5242880 + 4) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_UNIX_DEVICE_FILE (5242880 + 5) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_HAL_UDI (5242880 + 6) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_CAN_START (5242880 + 7) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_CAN_START_DEGRADED (5242880 + 8) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_CAN_STOP (5242880 + 9) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_START_STOP_TYPE (5242880 + 10) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_CAN_POLL (5242880 + 11) +#define G_FILE_ATTRIBUTE_ID_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC (5242880 + 12) +#define G_FILE_ATTRIBUTE_ID_TIME_MODIFIED (6291456 + 1) +#define G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_USEC (6291456 + 2) +#define G_FILE_ATTRIBUTE_ID_TIME_ACCESS (6291456 + 3) +#define G_FILE_ATTRIBUTE_ID_TIME_ACCESS_USEC (6291456 + 4) +#define G_FILE_ATTRIBUTE_ID_TIME_CHANGED (6291456 + 5) +#define G_FILE_ATTRIBUTE_ID_TIME_CHANGED_USEC (6291456 + 6) +#define G_FILE_ATTRIBUTE_ID_TIME_CREATED (6291456 + 7) +#define G_FILE_ATTRIBUTE_ID_TIME_CREATED_USEC (6291456 + 8) +#define G_FILE_ATTRIBUTE_ID_UNIX_DEVICE (7340032 + 1) +#define G_FILE_ATTRIBUTE_ID_UNIX_INODE (7340032 + 2) +#define G_FILE_ATTRIBUTE_ID_UNIX_MODE (7340032 + 3) +#define G_FILE_ATTRIBUTE_ID_UNIX_NLINK (7340032 + 4) +#define G_FILE_ATTRIBUTE_ID_UNIX_UID (7340032 + 5) +#define G_FILE_ATTRIBUTE_ID_UNIX_GID (7340032 + 6) +#define G_FILE_ATTRIBUTE_ID_UNIX_RDEV (7340032 + 7) +#define G_FILE_ATTRIBUTE_ID_UNIX_BLOCK_SIZE (7340032 + 8) +#define G_FILE_ATTRIBUTE_ID_UNIX_BLOCKS (7340032 + 9) +#define G_FILE_ATTRIBUTE_ID_UNIX_IS_MOUNTPOINT (7340032 + 10) +#define G_FILE_ATTRIBUTE_ID_DOS_IS_ARCHIVE (8388608 + 1) +#define G_FILE_ATTRIBUTE_ID_DOS_IS_SYSTEM (8388608 + 2) +#define G_FILE_ATTRIBUTE_ID_DOS_IS_MOUNTPOINT (8388608 + 3) +#define G_FILE_ATTRIBUTE_ID_DOS_REPARSE_POINT_TAG (8388608 + 4) +#define G_FILE_ATTRIBUTE_ID_OWNER_USER (9437184 + 1) +#define G_FILE_ATTRIBUTE_ID_OWNER_USER_REAL (9437184 + 2) +#define G_FILE_ATTRIBUTE_ID_OWNER_GROUP (9437184 + 3) +#define G_FILE_ATTRIBUTE_ID_THUMBNAIL_PATH (10485760 + 1) +#define G_FILE_ATTRIBUTE_ID_THUMBNAILING_FAILED (10485760 + 2) +#define G_FILE_ATTRIBUTE_ID_THUMBNAIL_IS_VALID (10485760 + 3) +#define G_FILE_ATTRIBUTE_ID_PREVIEW_ICON (11534336 + 1) +#define G_FILE_ATTRIBUTE_ID_FILESYSTEM_SIZE (12582912 + 1) +#define G_FILE_ATTRIBUTE_ID_FILESYSTEM_FREE (12582912 + 2) +#define G_FILE_ATTRIBUTE_ID_FILESYSTEM_TYPE (12582912 + 3) +#define G_FILE_ATTRIBUTE_ID_FILESYSTEM_READONLY (12582912 + 4) +#define G_FILE_ATTRIBUTE_ID_FILESYSTEM_USE_PREVIEW (12582912 + 5) +#define G_FILE_ATTRIBUTE_ID_GVFS_BACKEND (13631488 + 1) +#define G_FILE_ATTRIBUTE_ID_SELINUX_CONTEXT (14680064 + 1) +#define G_FILE_ATTRIBUTE_ID_TRASH_ITEM_COUNT (15728640 + 1) +#define G_FILE_ATTRIBUTE_ID_TRASH_ORIG_PATH (15728640 + 2) +#define G_FILE_ATTRIBUTE_ID_TRASH_DELETION_DATE (15728640 + 3) + +gboolean _g_file_attribute_matcher_matches_id (GFileAttributeMatcher *matcher, + guint32 id); + +void _g_file_info_set_attribute_by_id (GFileInfo *info, + guint32 attribute, + GFileAttributeType type, + gpointer value_p); +void _g_file_info_set_attribute_string_by_id (GFileInfo *info, + guint32 attribute, + const char *attr_value); +void _g_file_info_set_attribute_byte_string_by_id (GFileInfo *info, + guint32 attribute, + const char *attr_value); +void _g_file_info_set_attribute_boolean_by_id (GFileInfo *info, + guint32 attribute, + gboolean attr_value); +void _g_file_info_set_attribute_uint32_by_id (GFileInfo *info, + guint32 attribute, + guint32 attr_value); +void _g_file_info_set_attribute_int32_by_id (GFileInfo *info, + guint32 attribute, + gint32 attr_value); +void _g_file_info_set_attribute_uint64_by_id (GFileInfo *info, + guint32 attribute, + guint64 attr_value); +void _g_file_info_set_attribute_int64_by_id (GFileInfo *info, + guint32 attribute, + gint64 attr_value); +void _g_file_info_set_attribute_object_by_id (GFileInfo *info, + guint32 attribute, + GObject *attr_value); +void _g_file_info_set_attribute_stringv_by_id (GFileInfo *info, + guint32 attribute, + char **attr_value); + + +#endif /* __G_FILE_INFO_PRIV_H__ */ diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c new file mode 100644 index 0000000..a27c246 --- /dev/null +++ b/gio/gfileinfo.c @@ -0,0 +1,2971 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +/** + * SECTION:gfileinfo + * @short_description: File Information and Attributes + * @include: gio/gio.h + * @see_also: #GFile, [GFileAttribute][gio-GFileAttribute] + * + * Functionality for manipulating basic metadata for files. #GFileInfo + * implements methods for getting information that all files should + * contain, and allows for manipulation of extended attributes. + * + * See [GFileAttribute][gio-GFileAttribute] for more information on how + * GIO handles file attributes. + * + * To obtain a #GFileInfo for a #GFile, use g_file_query_info() (or its + * async variant). To obtain a #GFileInfo for a file input or output + * stream, use g_file_input_stream_query_info() or + * g_file_output_stream_query_info() (or their async variants). + * + * To change the actual attributes of a file, you should then set the + * attribute in the #GFileInfo and call g_file_set_attributes_from_info() + * or g_file_set_attributes_async() on a GFile. + * + * However, not all attributes can be changed in the file. For instance, + * the actual size of a file cannot be changed via g_file_info_set_size(). + * You may call g_file_query_settable_attributes() and + * g_file_query_writable_namespaces() to discover the settable attributes + * of a particular file at runtime. + * + * The direct accessors, such as g_file_info_get_name(), are slightly more + * optimized than the generic attribute accessors, such as + * g_file_info_get_attribute_byte_string().This optimization will matter + * only if calling the API in a tight loop. + * + * #GFileAttributeMatcher allows for searching through a #GFileInfo for + * attributes. + **/ + +#include "config.h" + +#include + +#include "gfileinfo.h" +#include "gfileinfo-priv.h" +#include "gfileattribute-priv.h" +#include "gicon.h" +#include "glibintl.h" + + +/* We use this nasty thing, because NULL is a valid attribute matcher (matches nothing) */ +#define NO_ATTRIBUTE_MASK ((GFileAttributeMatcher *)1) + +typedef struct { + guint32 attribute; + GFileAttributeValue value; +} GFileAttribute; + +struct _GFileInfo +{ + GObject parent_instance; + + GArray *attributes; + GFileAttributeMatcher *mask; +}; + +struct _GFileInfoClass +{ + GObjectClass parent_class; +}; + + +G_DEFINE_TYPE (GFileInfo, g_file_info, G_TYPE_OBJECT) + +typedef struct { + guint32 id; + guint32 attribute_id_counter; +} NSInfo; + +G_LOCK_DEFINE_STATIC (attribute_hash); +static int namespace_id_counter = 0; +static GHashTable *ns_hash = NULL; +static GHashTable *attribute_hash = NULL; +static char ***attributes = NULL; + +/* Attribute ids are 32bit, we split it up like this: + * |------------|--------------------| + * 12 bit 20 bit + * namespace attribute id + * + * This way the attributes gets sorted in namespace order + */ + +#define NS_POS 20 +#define NS_MASK ((guint32)((1<<12) - 1)) +#define ID_POS 0 +#define ID_MASK ((guint32)((1<<20) - 1)) + +#define GET_NS(_attr_id) \ + (((guint32) (_attr_id) >> NS_POS) & NS_MASK) +#define GET_ID(_attr_id) \ + (((guint32)(_attr_id) >> ID_POS) & ID_MASK) + +#define MAKE_ATTR_ID(_ns, _id) \ + ( ((((guint32) _ns) & NS_MASK) << NS_POS) | \ + ((((guint32) _id) & ID_MASK) << ID_POS) ) + +static NSInfo * +_lookup_namespace (const char *namespace) +{ + NSInfo *ns_info; + + ns_info = g_hash_table_lookup (ns_hash, namespace); + if (ns_info == NULL) + { + ns_info = g_new0 (NSInfo, 1); + ns_info->id = ++namespace_id_counter; + g_hash_table_insert (ns_hash, g_strdup (namespace), ns_info); + attributes = g_realloc (attributes, (ns_info->id + 1) * sizeof (char **)); + attributes[ns_info->id] = g_new (char *, 1); + attributes[ns_info->id][0] = g_strconcat (namespace, "::*", NULL); + } + return ns_info; +} + +static guint32 +_lookup_attribute (const char *attribute) +{ + guint32 attr_id, id; + char *ns; + const char *colon; + NSInfo *ns_info; + + attr_id = GPOINTER_TO_UINT (g_hash_table_lookup (attribute_hash, attribute)); + + if (attr_id != 0) + return attr_id; + + colon = strstr (attribute, "::"); + if (colon) + ns = g_strndup (attribute, colon - attribute); + else + ns = g_strdup (""); + + ns_info = _lookup_namespace (ns); + g_free (ns); + + id = ++ns_info->attribute_id_counter; + attributes[ns_info->id] = g_realloc (attributes[ns_info->id], (id + 1) * sizeof (char *)); + attributes[ns_info->id][id] = g_strdup (attribute); + + attr_id = MAKE_ATTR_ID (ns_info->id, id); + + g_hash_table_insert (attribute_hash, attributes[ns_info->id][id], GUINT_TO_POINTER (attr_id)); + + return attr_id; +} + +static void +ensure_attribute_hash (void) +{ + if (attribute_hash != NULL) + return; + + ns_hash = g_hash_table_new (g_str_hash, g_str_equal); + attribute_hash = g_hash_table_new (g_str_hash, g_str_equal); + +#define REGISTER_ATTRIBUTE(name) G_STMT_START{\ + guint _u G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; \ + _u = _lookup_attribute (G_FILE_ATTRIBUTE_ ## name); \ + /* use for generating the ID: g_print ("#define G_FILE_ATTRIBUTE_ID_%s (%u + %u)\n", #name + 17, _u & ~ID_MASK, _u & ID_MASK); */ \ + g_assert (_u == G_FILE_ATTRIBUTE_ID_ ## name); \ +}G_STMT_END + + REGISTER_ATTRIBUTE (STANDARD_TYPE); + REGISTER_ATTRIBUTE (STANDARD_IS_HIDDEN); + REGISTER_ATTRIBUTE (STANDARD_IS_BACKUP); + REGISTER_ATTRIBUTE (STANDARD_IS_SYMLINK); + REGISTER_ATTRIBUTE (STANDARD_IS_VIRTUAL); + REGISTER_ATTRIBUTE (STANDARD_NAME); + REGISTER_ATTRIBUTE (STANDARD_DISPLAY_NAME); + REGISTER_ATTRIBUTE (STANDARD_EDIT_NAME); + REGISTER_ATTRIBUTE (STANDARD_COPY_NAME); + REGISTER_ATTRIBUTE (STANDARD_DESCRIPTION); + REGISTER_ATTRIBUTE (STANDARD_ICON); + REGISTER_ATTRIBUTE (STANDARD_CONTENT_TYPE); + REGISTER_ATTRIBUTE (STANDARD_FAST_CONTENT_TYPE); + REGISTER_ATTRIBUTE (STANDARD_SIZE); + REGISTER_ATTRIBUTE (STANDARD_ALLOCATED_SIZE); + REGISTER_ATTRIBUTE (STANDARD_SYMLINK_TARGET); + REGISTER_ATTRIBUTE (STANDARD_TARGET_URI); + REGISTER_ATTRIBUTE (STANDARD_SORT_ORDER); + REGISTER_ATTRIBUTE (STANDARD_SYMBOLIC_ICON); + REGISTER_ATTRIBUTE (STANDARD_IS_VOLATILE); + REGISTER_ATTRIBUTE (ETAG_VALUE); + REGISTER_ATTRIBUTE (ID_FILE); + REGISTER_ATTRIBUTE (ID_FILESYSTEM); + REGISTER_ATTRIBUTE (ACCESS_CAN_READ); + REGISTER_ATTRIBUTE (ACCESS_CAN_WRITE); + REGISTER_ATTRIBUTE (ACCESS_CAN_EXECUTE); + REGISTER_ATTRIBUTE (ACCESS_CAN_DELETE); + REGISTER_ATTRIBUTE (ACCESS_CAN_TRASH); + REGISTER_ATTRIBUTE (ACCESS_CAN_RENAME); + REGISTER_ATTRIBUTE (MOUNTABLE_CAN_MOUNT); + REGISTER_ATTRIBUTE (MOUNTABLE_CAN_UNMOUNT); + REGISTER_ATTRIBUTE (MOUNTABLE_CAN_EJECT); + REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE); + REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE_FILE); + REGISTER_ATTRIBUTE (MOUNTABLE_HAL_UDI); + REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START); + REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START_DEGRADED); + REGISTER_ATTRIBUTE (MOUNTABLE_CAN_STOP); + REGISTER_ATTRIBUTE (MOUNTABLE_START_STOP_TYPE); + REGISTER_ATTRIBUTE (MOUNTABLE_CAN_POLL); + REGISTER_ATTRIBUTE (MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC); + REGISTER_ATTRIBUTE (TIME_MODIFIED); + REGISTER_ATTRIBUTE (TIME_MODIFIED_USEC); + REGISTER_ATTRIBUTE (TIME_ACCESS); + REGISTER_ATTRIBUTE (TIME_ACCESS_USEC); + REGISTER_ATTRIBUTE (TIME_CHANGED); + REGISTER_ATTRIBUTE (TIME_CHANGED_USEC); + REGISTER_ATTRIBUTE (TIME_CREATED); + REGISTER_ATTRIBUTE (TIME_CREATED_USEC); + REGISTER_ATTRIBUTE (UNIX_DEVICE); + REGISTER_ATTRIBUTE (UNIX_INODE); + REGISTER_ATTRIBUTE (UNIX_MODE); + REGISTER_ATTRIBUTE (UNIX_NLINK); + REGISTER_ATTRIBUTE (UNIX_UID); + REGISTER_ATTRIBUTE (UNIX_GID); + REGISTER_ATTRIBUTE (UNIX_RDEV); + REGISTER_ATTRIBUTE (UNIX_BLOCK_SIZE); + REGISTER_ATTRIBUTE (UNIX_BLOCKS); + REGISTER_ATTRIBUTE (UNIX_IS_MOUNTPOINT); + REGISTER_ATTRIBUTE (DOS_IS_ARCHIVE); + REGISTER_ATTRIBUTE (DOS_IS_SYSTEM); + REGISTER_ATTRIBUTE (DOS_IS_MOUNTPOINT); + REGISTER_ATTRIBUTE (DOS_REPARSE_POINT_TAG); + REGISTER_ATTRIBUTE (OWNER_USER); + REGISTER_ATTRIBUTE (OWNER_USER_REAL); + REGISTER_ATTRIBUTE (OWNER_GROUP); + REGISTER_ATTRIBUTE (THUMBNAIL_PATH); + REGISTER_ATTRIBUTE (THUMBNAILING_FAILED); + REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID); + REGISTER_ATTRIBUTE (PREVIEW_ICON); + REGISTER_ATTRIBUTE (FILESYSTEM_SIZE); + REGISTER_ATTRIBUTE (FILESYSTEM_FREE); + REGISTER_ATTRIBUTE (FILESYSTEM_TYPE); + REGISTER_ATTRIBUTE (FILESYSTEM_READONLY); + REGISTER_ATTRIBUTE (FILESYSTEM_USE_PREVIEW); + REGISTER_ATTRIBUTE (GVFS_BACKEND); + REGISTER_ATTRIBUTE (SELINUX_CONTEXT); + REGISTER_ATTRIBUTE (TRASH_ITEM_COUNT); + REGISTER_ATTRIBUTE (TRASH_ORIG_PATH); + REGISTER_ATTRIBUTE (TRASH_DELETION_DATE); + +#undef REGISTER_ATTRIBUTE +} + +static guint32 +lookup_namespace (const char *namespace) +{ + NSInfo *ns_info; + guint32 id; + + G_LOCK (attribute_hash); + + ensure_attribute_hash (); + + ns_info = _lookup_namespace (namespace); + id = 0; + if (ns_info) + id = ns_info->id; + + G_UNLOCK (attribute_hash); + + return id; +} + +static char * +get_attribute_for_id (int attribute) +{ + char *s; + G_LOCK (attribute_hash); + s = attributes[GET_NS(attribute)][GET_ID(attribute)]; + G_UNLOCK (attribute_hash); + return s; +} + +static guint32 +lookup_attribute (const char *attribute) +{ + guint32 attr_id; + + G_LOCK (attribute_hash); + ensure_attribute_hash (); + + attr_id = _lookup_attribute (attribute); + + G_UNLOCK (attribute_hash); + + return attr_id; +} + +static void +g_file_info_finalize (GObject *object) +{ + GFileInfo *info; + guint i; + GFileAttribute *attrs; + + info = G_FILE_INFO (object); + + attrs = (GFileAttribute *)info->attributes->data; + for (i = 0; i < info->attributes->len; i++) + _g_file_attribute_value_clear (&attrs[i].value); + g_array_free (info->attributes, TRUE); + + if (info->mask != NO_ATTRIBUTE_MASK) + g_file_attribute_matcher_unref (info->mask); + + G_OBJECT_CLASS (g_file_info_parent_class)->finalize (object); +} + +static void +g_file_info_class_init (GFileInfoClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_file_info_finalize; +} + +static void +g_file_info_init (GFileInfo *info) +{ + info->mask = NO_ATTRIBUTE_MASK; + info->attributes = g_array_new (FALSE, FALSE, + sizeof (GFileAttribute)); +} + +/** + * g_file_info_new: + * + * Creates a new file info structure. + * + * Returns: a #GFileInfo. + **/ +GFileInfo * +g_file_info_new (void) +{ + return g_object_new (G_TYPE_FILE_INFO, NULL); +} + +/** + * g_file_info_copy_into: + * @src_info: source to copy attributes from. + * @dest_info: destination to copy attributes to. + * + * First clears all of the [GFileAttribute][gio-GFileAttribute] of @dest_info, + * and then copies all of the file attributes from @src_info to @dest_info. + **/ +void +g_file_info_copy_into (GFileInfo *src_info, + GFileInfo *dest_info) +{ + GFileAttribute *source, *dest; + guint i; + + g_return_if_fail (G_IS_FILE_INFO (src_info)); + g_return_if_fail (G_IS_FILE_INFO (dest_info)); + + dest = (GFileAttribute *)dest_info->attributes->data; + for (i = 0; i < dest_info->attributes->len; i++) + _g_file_attribute_value_clear (&dest[i].value); + + g_array_set_size (dest_info->attributes, + src_info->attributes->len); + + source = (GFileAttribute *)src_info->attributes->data; + dest = (GFileAttribute *)dest_info->attributes->data; + + for (i = 0; i < src_info->attributes->len; i++) + { + dest[i].attribute = source[i].attribute; + dest[i].value.type = G_FILE_ATTRIBUTE_TYPE_INVALID; + _g_file_attribute_value_set (&dest[i].value, &source[i].value); + } + + if (dest_info->mask != NO_ATTRIBUTE_MASK) + g_file_attribute_matcher_unref (dest_info->mask); + + if (src_info->mask == NO_ATTRIBUTE_MASK) + dest_info->mask = NO_ATTRIBUTE_MASK; + else + dest_info->mask = g_file_attribute_matcher_ref (src_info->mask); +} + +/** + * g_file_info_dup: + * @other: a #GFileInfo. + * + * Duplicates a file info structure. + * + * Returns: (transfer full): a duplicate #GFileInfo of @other. + **/ +GFileInfo * +g_file_info_dup (GFileInfo *other) +{ + GFileInfo *new; + + g_return_val_if_fail (G_IS_FILE_INFO (other), NULL); + + new = g_file_info_new (); + g_file_info_copy_into (other, new); + return new; +} + +/** + * g_file_info_set_attribute_mask: + * @info: a #GFileInfo. + * @mask: a #GFileAttributeMatcher. + * + * Sets @mask on @info to match specific attribute types. + **/ +void +g_file_info_set_attribute_mask (GFileInfo *info, + GFileAttributeMatcher *mask) +{ + GFileAttribute *attr; + guint i; + + g_return_if_fail (G_IS_FILE_INFO (info)); + + if (mask != info->mask) + { + if (info->mask != NO_ATTRIBUTE_MASK) + g_file_attribute_matcher_unref (info->mask); + info->mask = g_file_attribute_matcher_ref (mask); + + /* Remove non-matching attributes */ + for (i = 0; i < info->attributes->len; i++) + { + attr = &g_array_index (info->attributes, GFileAttribute, i); + if (!_g_file_attribute_matcher_matches_id (mask, + attr->attribute)) + { + _g_file_attribute_value_clear (&attr->value); + g_array_remove_index (info->attributes, i); + i--; + } + } + } +} + +/** + * g_file_info_unset_attribute_mask: + * @info: #GFileInfo. + * + * Unsets a mask set by g_file_info_set_attribute_mask(), if one + * is set. + **/ +void +g_file_info_unset_attribute_mask (GFileInfo *info) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + + if (info->mask != NO_ATTRIBUTE_MASK) + g_file_attribute_matcher_unref (info->mask); + info->mask = NO_ATTRIBUTE_MASK; +} + +/** + * g_file_info_clear_status: + * @info: a #GFileInfo. + * + * Clears the status information from @info. + **/ +void +g_file_info_clear_status (GFileInfo *info) +{ + GFileAttribute *attrs; + guint i; + + g_return_if_fail (G_IS_FILE_INFO (info)); + + attrs = (GFileAttribute *)info->attributes->data; + for (i = 0; i < info->attributes->len; i++) + attrs[i].value.status = G_FILE_ATTRIBUTE_STATUS_UNSET; +} + +static int +g_file_info_find_place (GFileInfo *info, + guint32 attribute) +{ + int min, max, med; + GFileAttribute *attrs; + /* Binary search for the place where attribute would be, if it's + in the array */ + + min = 0; + max = info->attributes->len; + + attrs = (GFileAttribute *)info->attributes->data; + + while (min < max) + { + med = min + (max - min) / 2; + if (attrs[med].attribute == attribute) + { + min = med; + break; + } + else if (attrs[med].attribute < attribute) + min = med + 1; + else /* attrs[med].attribute > attribute */ + max = med; + } + + return min; +} + +static GFileAttributeValue * +g_file_info_find_value (GFileInfo *info, + guint32 attr_id) +{ + GFileAttribute *attrs; + guint i; + + i = g_file_info_find_place (info, attr_id); + attrs = (GFileAttribute *)info->attributes->data; + if (i < info->attributes->len && + attrs[i].attribute == attr_id) + return &attrs[i].value; + + return NULL; +} + +static GFileAttributeValue * +g_file_info_find_value_by_name (GFileInfo *info, + const char *attribute) +{ + guint32 attr_id; + + attr_id = lookup_attribute (attribute); + return g_file_info_find_value (info, attr_id); +} + +/** + * g_file_info_has_attribute: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Checks if a file info structure has an attribute named @attribute. + * + * Returns: %TRUE if @info has an attribute named @attribute, + * %FALSE otherwise. + **/ +gboolean +g_file_info_has_attribute (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE); + + value = g_file_info_find_value_by_name (info, attribute); + return value != NULL; +} + +/** + * g_file_info_has_namespace: + * @info: a #GFileInfo. + * @name_space: a file attribute namespace. + * + * Checks if a file info structure has an attribute in the + * specified @name_space. + * + * Returns: %TRUE if @info has an attribute in @name_space, + * %FALSE otherwise. + * + * Since: 2.22 + **/ +gboolean +g_file_info_has_namespace (GFileInfo *info, + const char *name_space) +{ + GFileAttribute *attrs; + guint32 ns_id; + guint i; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + g_return_val_if_fail (name_space != NULL, FALSE); + + ns_id = lookup_namespace (name_space); + + attrs = (GFileAttribute *)info->attributes->data; + for (i = 0; i < info->attributes->len; i++) + { + if (GET_NS (attrs[i].attribute) == ns_id) + return TRUE; + } + + return FALSE; +} + +/** + * g_file_info_list_attributes: + * @info: a #GFileInfo. + * @name_space: (nullable): a file attribute key's namespace, or %NULL to list + * all attributes. + * + * Lists the file info structure's attributes. + * + * Returns: (nullable) (array zero-terminated=1) (transfer full): a + * null-terminated array of strings of all of the possible attribute + * types for the given @name_space, or %NULL on error. + **/ +char ** +g_file_info_list_attributes (GFileInfo *info, + const char *name_space) +{ + GPtrArray *names; + GFileAttribute *attrs; + guint32 attribute; + guint32 ns_id = (name_space) ? lookup_namespace (name_space) : 0; + guint i; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + names = g_ptr_array_new (); + attrs = (GFileAttribute *)info->attributes->data; + for (i = 0; i < info->attributes->len; i++) + { + attribute = attrs[i].attribute; + if (ns_id == 0 || GET_NS (attribute) == ns_id) + g_ptr_array_add (names, g_strdup (get_attribute_for_id (attribute))); + } + + /* NULL terminate */ + g_ptr_array_add (names, NULL); + + return (char **)g_ptr_array_free (names, FALSE); +} + +/** + * g_file_info_get_attribute_type: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets the attribute type for an attribute key. + * + * Returns: a #GFileAttributeType for the given @attribute, or + * %G_FILE_ATTRIBUTE_TYPE_INVALID if the key is not set. + **/ +GFileAttributeType +g_file_info_get_attribute_type (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), G_FILE_ATTRIBUTE_TYPE_INVALID); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', G_FILE_ATTRIBUTE_TYPE_INVALID); + + value = g_file_info_find_value_by_name (info, attribute); + if (value) + return value->type; + else + return G_FILE_ATTRIBUTE_TYPE_INVALID; +} + +/** + * g_file_info_remove_attribute: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Removes all cases of @attribute from @info if it exists. + **/ +void +g_file_info_remove_attribute (GFileInfo *info, + const char *attribute) +{ + guint32 attr_id; + GFileAttribute *attrs; + guint i; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + + attr_id = lookup_attribute (attribute); + + i = g_file_info_find_place (info, attr_id); + attrs = (GFileAttribute *)info->attributes->data; + if (i < info->attributes->len && + attrs[i].attribute == attr_id) + { + _g_file_attribute_value_clear (&attrs[i].value); + g_array_remove_index (info->attributes, i); + } +} + +/** + * g_file_info_get_attribute_data: + * @info: a #GFileInfo + * @attribute: a file attribute key + * @type: (out) (optional): return location for the attribute type, or %NULL + * @value_pp: (out) (optional) (not nullable): return location for the + * attribute value, or %NULL; the attribute value will not be %NULL + * @status: (out) (optional): return location for the attribute status, or %NULL + * + * Gets the attribute type, value and status for an attribute key. + * + * Returns: (transfer none): %TRUE if @info has an attribute named @attribute, + * %FALSE otherwise. + */ +gboolean +g_file_info_get_attribute_data (GFileInfo *info, + const char *attribute, + GFileAttributeType *type, + gpointer *value_pp, + GFileAttributeStatus *status) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE); + + value = g_file_info_find_value_by_name (info, attribute); + if (value == NULL) + return FALSE; + + if (status) + *status = value->status; + + if (type) + *type = value->type; + + if (value_pp) + *value_pp = _g_file_attribute_value_peek_as_pointer (value); + + return TRUE; +} + +/** + * g_file_info_get_attribute_status: + * @info: a #GFileInfo + * @attribute: a file attribute key + * + * Gets the attribute status for an attribute key. + * + * Returns: a #GFileAttributeStatus for the given @attribute, or + * %G_FILE_ATTRIBUTE_STATUS_UNSET if the key is invalid. + * + */ +GFileAttributeStatus +g_file_info_get_attribute_status (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *val; + + g_return_val_if_fail (G_IS_FILE_INFO (info), 0); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0); + + val = g_file_info_find_value_by_name (info, attribute); + if (val) + return val->status; + + return G_FILE_ATTRIBUTE_STATUS_UNSET; +} + +/** + * g_file_info_set_attribute_status: + * @info: a #GFileInfo + * @attribute: a file attribute key + * @status: a #GFileAttributeStatus + * + * Sets the attribute status for an attribute key. This is only + * needed by external code that implement g_file_set_attributes_from_info() + * or similar functions. + * + * The attribute must exist in @info for this to work. Otherwise %FALSE + * is returned and @info is unchanged. + * + * Returns: %TRUE if the status was changed, %FALSE if the key was not set. + * + * Since: 2.22 + */ +gboolean +g_file_info_set_attribute_status (GFileInfo *info, + const char *attribute, + GFileAttributeStatus status) +{ + GFileAttributeValue *val; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE); + + val = g_file_info_find_value_by_name (info, attribute); + if (val) + { + val->status = status; + return TRUE; + } + + return FALSE; +} + +GFileAttributeValue * +_g_file_info_get_attribute_value (GFileInfo *info, + const char *attribute) + +{ + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL); + + return g_file_info_find_value_by_name (info, attribute); +} + +/** + * g_file_info_get_attribute_as_string: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets the value of a attribute, formatted as a string. + * This escapes things as needed to make the string valid + * UTF-8. + * + * Returns: (nullable): a UTF-8 string associated with the given @attribute, or + * %NULL if the attribute wasn’t set. + * When you're done with the string it must be freed with g_free(). + **/ +char * +g_file_info_get_attribute_as_string (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *val; + val = _g_file_info_get_attribute_value (info, attribute); + if (val) + return _g_file_attribute_value_as_string (val); + return NULL; +} + + +/** + * g_file_info_get_attribute_object: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets the value of a #GObject attribute. If the attribute does + * not contain a #GObject, %NULL will be returned. + * + * Returns: (transfer none) (nullable): a #GObject associated with the given @attribute, + * or %NULL otherwise. + **/ +GObject * +g_file_info_get_attribute_object (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_object (value); +} + +/** + * g_file_info_get_attribute_string: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets the value of a string attribute. If the attribute does + * not contain a string, %NULL will be returned. + * + * Returns: (nullable): the contents of the @attribute value as a UTF-8 string, + * or %NULL otherwise. + **/ +const char * +g_file_info_get_attribute_string (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_string (value); +} + +/** + * g_file_info_get_attribute_byte_string: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets the value of a byte string attribute. If the attribute does + * not contain a byte string, %NULL will be returned. + * + * Returns: (nullable): the contents of the @attribute value as a byte string, or + * %NULL otherwise. + **/ +const char * +g_file_info_get_attribute_byte_string (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_byte_string (value); +} + +/** + * g_file_info_get_attribute_stringv: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets the value of a stringv attribute. If the attribute does + * not contain a stringv, %NULL will be returned. + * + * Returns: (transfer none) (nullable): the contents of the @attribute value as a stringv, + * or %NULL otherwise. Do not free. These returned strings are UTF-8. + * + * Since: 2.22 + **/ +char ** +g_file_info_get_attribute_stringv (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_stringv (value); +} + +/** + * g_file_info_get_attribute_boolean: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets the value of a boolean attribute. If the attribute does not + * contain a boolean value, %FALSE will be returned. + * + * Returns: the boolean value contained within the attribute. + **/ +gboolean +g_file_info_get_attribute_boolean (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_boolean (value); +} + +/** + * g_file_info_get_attribute_uint32: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets an unsigned 32-bit integer contained within the attribute. If the + * attribute does not contain an unsigned 32-bit integer, or is invalid, + * 0 will be returned. + * + * Returns: an unsigned 32-bit integer from the attribute. + **/ +guint32 +g_file_info_get_attribute_uint32 (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), 0); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_uint32 (value); +} + +/** + * g_file_info_get_attribute_int32: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets a signed 32-bit integer contained within the attribute. If the + * attribute does not contain a signed 32-bit integer, or is invalid, + * 0 will be returned. + * + * Returns: a signed 32-bit integer from the attribute. + **/ +gint32 +g_file_info_get_attribute_int32 (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), 0); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_int32 (value); +} + +/** + * g_file_info_get_attribute_uint64: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets a unsigned 64-bit integer contained within the attribute. If the + * attribute does not contain an unsigned 64-bit integer, or is invalid, + * 0 will be returned. + * + * Returns: a unsigned 64-bit integer from the attribute. + **/ +guint64 +g_file_info_get_attribute_uint64 (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), 0); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_uint64 (value); +} + +/** + * g_file_info_get_attribute_int64: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * + * Gets a signed 64-bit integer contained within the attribute. If the + * attribute does not contain a signed 64-bit integer, or is invalid, + * 0 will be returned. + * + * Returns: a signed 64-bit integer from the attribute. + **/ +gint64 +g_file_info_get_attribute_int64 (GFileInfo *info, + const char *attribute) +{ + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), 0); + g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0); + + value = g_file_info_find_value_by_name (info, attribute); + return _g_file_attribute_value_get_int64 (value); +} + +static GFileAttributeValue * +g_file_info_create_value (GFileInfo *info, + guint32 attr_id) +{ + GFileAttribute *attrs; + guint i; + + if (info->mask != NO_ATTRIBUTE_MASK && + !_g_file_attribute_matcher_matches_id (info->mask, attr_id)) + return NULL; + + i = g_file_info_find_place (info, attr_id); + + attrs = (GFileAttribute *)info->attributes->data; + if (i < info->attributes->len && + attrs[i].attribute == attr_id) + return &attrs[i].value; + else + { + GFileAttribute attr = { 0 }; + attr.attribute = attr_id; + g_array_insert_val (info->attributes, i, attr); + + attrs = (GFileAttribute *)info->attributes->data; + return &attrs[i].value; + } +} + +void +_g_file_info_set_attribute_by_id (GFileInfo *info, + guint32 attribute, + GFileAttributeType type, + gpointer value_p) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + + if (value) + _g_file_attribute_value_set_from_pointer (value, type, value_p, TRUE); +} + +/** + * g_file_info_set_attribute: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * @type: a #GFileAttributeType + * @value_p: (not nullable): pointer to the value + * + * Sets the @attribute to contain the given value, if possible. To unset the + * attribute, use %G_FILE_ATTRIBUTE_TYPE_INVALID for @type. + **/ +void +g_file_info_set_attribute (GFileInfo *info, + const char *attribute, + GFileAttributeType type, + gpointer value_p) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + + _g_file_info_set_attribute_by_id (info, lookup_attribute (attribute), type, value_p); +} + +void +_g_file_info_set_attribute_object_by_id (GFileInfo *info, + guint32 attribute, + GObject *attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_object (value, attr_value); +} + +/** + * g_file_info_set_attribute_object: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * @attr_value: a #GObject. + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + **/ +void +g_file_info_set_attribute_object (GFileInfo *info, + const char *attribute, + GObject *attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + g_return_if_fail (G_IS_OBJECT (attr_value)); + + _g_file_info_set_attribute_object_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +void +_g_file_info_set_attribute_stringv_by_id (GFileInfo *info, + guint32 attribute, + char **attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_stringv (value, attr_value); +} + +/** + * g_file_info_set_attribute_stringv: + * @info: a #GFileInfo. + * @attribute: a file attribute key + * @attr_value: (array zero-terminated=1) (element-type utf8): a %NULL + * terminated array of UTF-8 strings. + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + * + * Sinze: 2.22 + **/ +void +g_file_info_set_attribute_stringv (GFileInfo *info, + const char *attribute, + char **attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + g_return_if_fail (attr_value != NULL); + + _g_file_info_set_attribute_stringv_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +void +_g_file_info_set_attribute_string_by_id (GFileInfo *info, + guint32 attribute, + const char *attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_string (value, attr_value); +} + +/** + * g_file_info_set_attribute_string: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * @attr_value: a UTF-8 string. + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + **/ +void +g_file_info_set_attribute_string (GFileInfo *info, + const char *attribute, + const char *attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + g_return_if_fail (attr_value != NULL); + + _g_file_info_set_attribute_string_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +void +_g_file_info_set_attribute_byte_string_by_id (GFileInfo *info, + guint32 attribute, + const char *attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_byte_string (value, attr_value); +} + +/** + * g_file_info_set_attribute_byte_string: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * @attr_value: a byte string. + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + **/ +void +g_file_info_set_attribute_byte_string (GFileInfo *info, + const char *attribute, + const char *attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + g_return_if_fail (attr_value != NULL); + + _g_file_info_set_attribute_byte_string_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +void +_g_file_info_set_attribute_boolean_by_id (GFileInfo *info, + guint32 attribute, + gboolean attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_boolean (value, attr_value); +} + +/** + * g_file_info_set_attribute_boolean: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * @attr_value: a boolean value. + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + **/ +void +g_file_info_set_attribute_boolean (GFileInfo *info, + const char *attribute, + gboolean attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + + _g_file_info_set_attribute_boolean_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +void +_g_file_info_set_attribute_uint32_by_id (GFileInfo *info, + guint32 attribute, + guint32 attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_uint32 (value, attr_value); +} + +/** + * g_file_info_set_attribute_uint32: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * @attr_value: an unsigned 32-bit integer. + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + **/ +void +g_file_info_set_attribute_uint32 (GFileInfo *info, + const char *attribute, + guint32 attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + + _g_file_info_set_attribute_uint32_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +void +_g_file_info_set_attribute_int32_by_id (GFileInfo *info, + guint32 attribute, + gint32 attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_int32 (value, attr_value); +} + +/** + * g_file_info_set_attribute_int32: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * @attr_value: a signed 32-bit integer + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + **/ +void +g_file_info_set_attribute_int32 (GFileInfo *info, + const char *attribute, + gint32 attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + + _g_file_info_set_attribute_int32_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +void +_g_file_info_set_attribute_uint64_by_id (GFileInfo *info, + guint32 attribute, + guint64 attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_uint64 (value, attr_value); +} + +/** + * g_file_info_set_attribute_uint64: + * @info: a #GFileInfo. + * @attribute: a file attribute key. + * @attr_value: an unsigned 64-bit integer. + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + **/ +void +g_file_info_set_attribute_uint64 (GFileInfo *info, + const char *attribute, + guint64 attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + + _g_file_info_set_attribute_uint64_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +void +_g_file_info_set_attribute_int64_by_id (GFileInfo *info, + guint32 attribute, + gint64 attr_value) +{ + GFileAttributeValue *value; + + value = g_file_info_create_value (info, attribute); + if (value) + _g_file_attribute_value_set_int64 (value, attr_value); +} + +/** + * g_file_info_set_attribute_int64: + * @info: a #GFileInfo. + * @attribute: attribute name to set. + * @attr_value: int64 value to set attribute to. + * + * Sets the @attribute to contain the given @attr_value, + * if possible. + * + **/ +void +g_file_info_set_attribute_int64 (GFileInfo *info, + const char *attribute, + gint64 attr_value) +{ + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (attribute != NULL && *attribute != '\0'); + + _g_file_info_set_attribute_int64_by_id (info, + lookup_attribute (attribute), + attr_value); +} + +/* Helper getters */ +/** + * g_file_info_get_deletion_date: + * @info: a #GFileInfo. + * + * Returns the #GDateTime representing the deletion date of the file, as + * available in G_FILE_ATTRIBUTE_TRASH_DELETION_DATE. If the + * G_FILE_ATTRIBUTE_TRASH_DELETION_DATE attribute is unset, %NULL is returned. + * + * Returns: (nullable): a #GDateTime, or %NULL. + * + * Since: 2.36 + **/ +GDateTime * +g_file_info_get_deletion_date (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + const char *date_str; + GTimeZone *local_tz = NULL; + GDateTime *dt = NULL; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_TRASH_DELETION_DATE); + + value = g_file_info_find_value (info, attr); + date_str = _g_file_attribute_value_get_string (value); + if (!date_str) + return NULL; + + local_tz = g_time_zone_new_local (); + dt = g_date_time_new_from_iso8601 (date_str, local_tz); + g_time_zone_unref (local_tz); + + return g_steal_pointer (&dt); +} + +/** + * g_file_info_get_file_type: + * @info: a #GFileInfo. + * + * Gets a file's type (whether it is a regular file, symlink, etc). + * This is different from the file's content type, see g_file_info_get_content_type(). + * + * Returns: a #GFileType for the given file. + **/ +GFileType +g_file_info_get_file_type (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), G_FILE_TYPE_UNKNOWN); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_TYPE); + + value = g_file_info_find_value (info, attr); + return (GFileType)_g_file_attribute_value_get_uint32 (value); +} + +/** + * g_file_info_get_is_hidden: + * @info: a #GFileInfo. + * + * Checks if a file is hidden. + * + * Returns: %TRUE if the file is a hidden file, %FALSE otherwise. + **/ +gboolean +g_file_info_get_is_hidden (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN); + + value = g_file_info_find_value (info, attr); + return (GFileType)_g_file_attribute_value_get_boolean (value); +} + +/** + * g_file_info_get_is_backup: + * @info: a #GFileInfo. + * + * Checks if a file is a backup file. + * + * Returns: %TRUE if file is a backup file, %FALSE otherwise. + **/ +gboolean +g_file_info_get_is_backup (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP); + + value = g_file_info_find_value (info, attr); + return (GFileType)_g_file_attribute_value_get_boolean (value); +} + +/** + * g_file_info_get_is_symlink: + * @info: a #GFileInfo. + * + * Checks if a file is a symlink. + * + * Returns: %TRUE if the given @info is a symlink. + **/ +gboolean +g_file_info_get_is_symlink (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK); + + value = g_file_info_find_value (info, attr); + return (GFileType)_g_file_attribute_value_get_boolean (value); +} + +/** + * g_file_info_get_name: + * @info: a #GFileInfo. + * + * Gets the name for a file. This is guaranteed to always be set. + * + * Returns: (type filename) (not nullable): a string containing the file name. + **/ +const char * +g_file_info_get_name (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_NAME); + + value = g_file_info_find_value (info, attr); + return _g_file_attribute_value_get_byte_string (value); +} + +/** + * g_file_info_get_display_name: + * @info: a #GFileInfo. + * + * Gets a display name for a file. This is guaranteed to always be set. + * + * Returns: (not nullable): a string containing the display name. + **/ +const char * +g_file_info_get_display_name (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME); + + value = g_file_info_find_value (info, attr); + return _g_file_attribute_value_get_string (value); +} + +/** + * g_file_info_get_edit_name: + * @info: a #GFileInfo. + * + * Gets the edit name for a file. + * + * Returns: a string containing the edit name. + **/ +const char * +g_file_info_get_edit_name (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME); + + value = g_file_info_find_value (info, attr); + return _g_file_attribute_value_get_string (value); +} + +/** + * g_file_info_get_icon: + * @info: a #GFileInfo. + * + * Gets the icon for a file. + * + * Returns: (nullable) (transfer none): #GIcon for the given @info. + **/ +GIcon * +g_file_info_get_icon (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + GObject *obj; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_ICON); + + value = g_file_info_find_value (info, attr); + obj = _g_file_attribute_value_get_object (value); + if (G_IS_ICON (obj)) + return G_ICON (obj); + return NULL; +} + +/** + * g_file_info_get_symbolic_icon: + * @info: a #GFileInfo. + * + * Gets the symbolic icon for a file. + * + * Returns: (nullable) (transfer none): #GIcon for the given @info. + * + * Since: 2.34 + **/ +GIcon * +g_file_info_get_symbolic_icon (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + GObject *obj; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON); + + value = g_file_info_find_value (info, attr); + obj = _g_file_attribute_value_get_object (value); + if (G_IS_ICON (obj)) + return G_ICON (obj); + return NULL; +} + +/** + * g_file_info_get_content_type: + * @info: a #GFileInfo. + * + * Gets the file's content type. + * + * Returns: (nullable): a string containing the file's content type, + * or %NULL if unknown. + **/ +const char * +g_file_info_get_content_type (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); + + value = g_file_info_find_value (info, attr); + return _g_file_attribute_value_get_string (value); +} + +/** + * g_file_info_get_size: + * @info: a #GFileInfo. + * + * Gets the file's size (in bytes). The size is retrieved through the value of + * the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute and is converted + * from #guint64 to #goffset before returning the result. + * + * Returns: a #goffset containing the file's size (in bytes). + **/ +goffset +g_file_info_get_size (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), (goffset) 0); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SIZE); + + value = g_file_info_find_value (info, attr); + return (goffset) _g_file_attribute_value_get_uint64 (value); +} + +/** + * g_file_info_get_modification_time: + * @info: a #GFileInfo. + * @result: (out caller-allocates): a #GTimeVal. + * + * Gets the modification time of the current @info and sets it + * in @result. + * + * Deprecated: 2.62: Use g_file_info_get_modification_date_time() instead, as + * #GTimeVal is deprecated due to the year 2038 problem. + **/ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +void +g_file_info_get_modification_time (GFileInfo *info, + GTimeVal *result) +{ + static guint32 attr_mtime = 0, attr_mtime_usec; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (result != NULL); + + if (attr_mtime == 0) + { + attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED); + attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC); + } + + value = g_file_info_find_value (info, attr_mtime); + result->tv_sec = _g_file_attribute_value_get_uint64 (value); + value = g_file_info_find_value (info, attr_mtime_usec); + result->tv_usec = _g_file_attribute_value_get_uint32 (value); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_file_info_get_modification_date_time: + * @info: a #GFileInfo. + * + * Gets the modification time of the current @info and returns it as a + * #GDateTime. + * + * This requires the %G_FILE_ATTRIBUTE_TIME_MODIFIED attribute. If + * %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is provided, the resulting #GDateTime + * will have microsecond precision. + * + * Returns: (transfer full) (nullable): modification time, or %NULL if unknown + * Since: 2.62 + */ +GDateTime * +g_file_info_get_modification_date_time (GFileInfo *info) +{ + static guint32 attr_mtime = 0, attr_mtime_usec; + GFileAttributeValue *value, *value_usec; + GDateTime *dt = NULL, *dt2 = NULL; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr_mtime == 0) + { + attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED); + attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC); + } + + value = g_file_info_find_value (info, attr_mtime); + if (value == NULL) + return NULL; + + dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value)); + + value_usec = g_file_info_find_value (info, attr_mtime_usec); + if (value_usec == NULL) + return g_steal_pointer (&dt); + + dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec)); + g_date_time_unref (dt); + + return g_steal_pointer (&dt2); +} + +/** + * g_file_info_get_access_date_time: + * @info: a #GFileInfo. + * + * Gets the access time of the current @info and returns it as a + * #GDateTime. + * + * This requires the %G_FILE_ATTRIBUTE_TIME_ACCESS attribute. If + * %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC is provided, the resulting #GDateTime + * will have microsecond precision. + * + * Returns: (transfer full) (nullable): access time, or %NULL if unknown + * Since: 2.70 + */ +GDateTime * +g_file_info_get_access_date_time (GFileInfo *info) +{ + static guint32 attr_atime = 0, attr_atime_usec; + GFileAttributeValue *value, *value_usec; + GDateTime *dt = NULL, *dt2 = NULL; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr_atime == 0) + { + attr_atime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS); + attr_atime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_USEC); + } + + value = g_file_info_find_value (info, attr_atime); + if (value == NULL) + return NULL; + + dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value)); + + value_usec = g_file_info_find_value (info, attr_atime_usec); + if (value_usec == NULL) + return g_steal_pointer (&dt); + + dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec)); + g_date_time_unref (dt); + + return g_steal_pointer (&dt2); +} + +/** + * g_file_info_get_creation_date_time: + * @info: a #GFileInfo. + * + * Gets the creation time of the current @info and returns it as a + * #GDateTime. + * + * This requires the %G_FILE_ATTRIBUTE_TIME_CREATED attribute. If + * %G_FILE_ATTRIBUTE_TIME_CREATED_USEC is provided, the resulting #GDateTime + * will have microsecond precision. + * + * Returns: (transfer full) (nullable): creation time, or %NULL if unknown + * Since: 2.70 + */ +GDateTime * +g_file_info_get_creation_date_time (GFileInfo *info) +{ + static guint32 attr_ctime = 0, attr_ctime_usec; + GFileAttributeValue *value, *value_usec; + GDateTime *dt = NULL, *dt2 = NULL; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr_ctime == 0) + { + attr_ctime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED); + attr_ctime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_USEC); + } + + value = g_file_info_find_value (info, attr_ctime); + if (value == NULL) + return NULL; + + dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value)); + + value_usec = g_file_info_find_value (info, attr_ctime_usec); + if (value_usec == NULL) + return g_steal_pointer (&dt); + + dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec)); + g_date_time_unref (dt); + + return g_steal_pointer (&dt2); +} + +/** + * g_file_info_get_symlink_target: + * @info: a #GFileInfo. + * + * Gets the symlink target for a given #GFileInfo. + * + * Returns: (nullable): a string containing the symlink target. + **/ +const char * +g_file_info_get_symlink_target (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET); + + value = g_file_info_find_value (info, attr); + return _g_file_attribute_value_get_byte_string (value); +} + +/** + * g_file_info_get_etag: + * @info: a #GFileInfo. + * + * Gets the [entity tag][gfile-etag] for a given + * #GFileInfo. See %G_FILE_ATTRIBUTE_ETAG_VALUE. + * + * Returns: (nullable): a string containing the value of the "etag:value" attribute. + **/ +const char * +g_file_info_get_etag (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_ETAG_VALUE); + + value = g_file_info_find_value (info, attr); + return _g_file_attribute_value_get_string (value); +} + +/** + * g_file_info_get_sort_order: + * @info: a #GFileInfo. + * + * Gets the value of the sort_order attribute from the #GFileInfo. + * See %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER. + * + * Returns: a #gint32 containing the value of the "standard::sort_order" attribute. + **/ +gint32 +g_file_info_get_sort_order (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_val_if_fail (G_IS_FILE_INFO (info), 0); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER); + + value = g_file_info_find_value (info, attr); + return _g_file_attribute_value_get_int32 (value); +} + +/* Helper setters: */ +/** + * g_file_info_set_file_type: + * @info: a #GFileInfo. + * @type: a #GFileType. + * + * Sets the file type in a #GFileInfo to @type. + * See %G_FILE_ATTRIBUTE_STANDARD_TYPE. + **/ +void +g_file_info_set_file_type (GFileInfo *info, + GFileType type) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_TYPE); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_uint32 (value, type); +} + +/** + * g_file_info_set_is_hidden: + * @info: a #GFileInfo. + * @is_hidden: a #gboolean. + * + * Sets the "is_hidden" attribute in a #GFileInfo according to @is_hidden. + * See %G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN. + **/ +void +g_file_info_set_is_hidden (GFileInfo *info, + gboolean is_hidden) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_boolean (value, is_hidden); +} + +/** + * g_file_info_set_is_symlink: + * @info: a #GFileInfo. + * @is_symlink: a #gboolean. + * + * Sets the "is_symlink" attribute in a #GFileInfo according to @is_symlink. + * See %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK. + **/ +void +g_file_info_set_is_symlink (GFileInfo *info, + gboolean is_symlink) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_boolean (value, is_symlink); +} + +/** + * g_file_info_set_name: + * @info: a #GFileInfo. + * @name: (type filename): a string containing a name. + * + * Sets the name attribute for the current #GFileInfo. + * See %G_FILE_ATTRIBUTE_STANDARD_NAME. + **/ +void +g_file_info_set_name (GFileInfo *info, + const char *name) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (name != NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_NAME); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_byte_string (value, name); +} + +/** + * g_file_info_set_display_name: + * @info: a #GFileInfo. + * @display_name: a string containing a display name. + * + * Sets the display name for the current #GFileInfo. + * See %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME. + **/ +void +g_file_info_set_display_name (GFileInfo *info, + const char *display_name) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (display_name != NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_string (value, display_name); +} + +/** + * g_file_info_set_edit_name: + * @info: a #GFileInfo. + * @edit_name: a string containing an edit name. + * + * Sets the edit name for the current file. + * See %G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME. + **/ +void +g_file_info_set_edit_name (GFileInfo *info, + const char *edit_name) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (edit_name != NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_string (value, edit_name); +} + +/** + * g_file_info_set_icon: + * @info: a #GFileInfo. + * @icon: a #GIcon. + * + * Sets the icon for a given #GFileInfo. + * See %G_FILE_ATTRIBUTE_STANDARD_ICON. + **/ +void +g_file_info_set_icon (GFileInfo *info, + GIcon *icon) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (G_IS_ICON (icon)); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_ICON); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_object (value, G_OBJECT (icon)); +} + +/** + * g_file_info_set_symbolic_icon: + * @info: a #GFileInfo. + * @icon: a #GIcon. + * + * Sets the symbolic icon for a given #GFileInfo. + * See %G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON. + * + * Since: 2.34 + **/ +void +g_file_info_set_symbolic_icon (GFileInfo *info, + GIcon *icon) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (G_IS_ICON (icon)); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_object (value, G_OBJECT (icon)); +} + +/** + * g_file_info_set_content_type: + * @info: a #GFileInfo. + * @content_type: a content type. See [GContentType][gio-GContentType] + * + * Sets the content type attribute for a given #GFileInfo. + * See %G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE. + **/ +void +g_file_info_set_content_type (GFileInfo *info, + const char *content_type) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (content_type != NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_string (value, content_type); +} + +/** + * g_file_info_set_size: + * @info: a #GFileInfo. + * @size: a #goffset containing the file's size. + * + * Sets the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute in the file info + * to the given size. + **/ +void +g_file_info_set_size (GFileInfo *info, + goffset size) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SIZE); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_uint64 (value, size); +} + +/** + * g_file_info_set_modification_time: + * @info: a #GFileInfo. + * @mtime: a #GTimeVal. + * + * Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED and + * %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attributes in the file info to the + * given time value. + * + * Deprecated: 2.62: Use g_file_info_set_modification_date_time() instead, as + * #GTimeVal is deprecated due to the year 2038 problem. + **/ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +void +g_file_info_set_modification_time (GFileInfo *info, + GTimeVal *mtime) +{ + static guint32 attr_mtime = 0, attr_mtime_usec; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (mtime != NULL); + + if (attr_mtime == 0) + { + attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED); + attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC); + } + + value = g_file_info_create_value (info, attr_mtime); + if (value) + _g_file_attribute_value_set_uint64 (value, mtime->tv_sec); + value = g_file_info_create_value (info, attr_mtime_usec); + if (value) + _g_file_attribute_value_set_uint32 (value, mtime->tv_usec); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_file_info_set_modification_date_time: + * @info: a #GFileInfo. + * @mtime: (not nullable): a #GDateTime. + * + * Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED and + * %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attributes in the file info to the + * given date/time value. + * + * Since: 2.62 + */ +void +g_file_info_set_modification_date_time (GFileInfo *info, + GDateTime *mtime) +{ + static guint32 attr_mtime = 0, attr_mtime_usec; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (mtime != NULL); + + if (attr_mtime == 0) + { + attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED); + attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC); + } + + value = g_file_info_create_value (info, attr_mtime); + if (value) + _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (mtime)); + value = g_file_info_create_value (info, attr_mtime_usec); + if (value) + _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (mtime)); +} + +/** + * g_file_info_set_access_date_time: + * @info: a #GFileInfo. + * @atime: (not nullable): a #GDateTime. + * + * Sets the %G_FILE_ATTRIBUTE_TIME_ACCESS and + * %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC attributes in the file info to the + * given date/time value. + * + * Since: 2.70 + */ +void +g_file_info_set_access_date_time (GFileInfo *info, + GDateTime *atime) +{ + static guint32 attr_atime = 0, attr_atime_usec; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (atime != NULL); + + if (attr_atime == 0) + { + attr_atime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS); + attr_atime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_USEC); + } + + value = g_file_info_create_value (info, attr_atime); + if (value) + _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (atime)); + value = g_file_info_create_value (info, attr_atime_usec); + if (value) + _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (atime)); +} + +/** + * g_file_info_set_creation_date_time: + * @info: a #GFileInfo. + * @creation_time: (not nullable): a #GDateTime. + * + * Sets the %G_FILE_ATTRIBUTE_TIME_CREATED and + * %G_FILE_ATTRIBUTE_TIME_CREATED_USEC attributes in the file info to the + * given date/time value. + * + * Since: 2.70 + */ +void +g_file_info_set_creation_date_time (GFileInfo *info, + GDateTime *creation_time) +{ + static guint32 attr_ctime = 0, attr_ctime_usec; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (creation_time != NULL); + + if (attr_ctime == 0) + { + attr_ctime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED); + attr_ctime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_USEC); + } + + value = g_file_info_create_value (info, attr_ctime); + if (value) + _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (creation_time)); + value = g_file_info_create_value (info, attr_ctime_usec); + if (value) + _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (creation_time)); +} + +/** + * g_file_info_set_symlink_target: + * @info: a #GFileInfo. + * @symlink_target: a static string containing a path to a symlink target. + * + * Sets the %G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET attribute in the file info + * to the given symlink target. + **/ +void +g_file_info_set_symlink_target (GFileInfo *info, + const char *symlink_target) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (symlink_target != NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_byte_string (value, symlink_target); +} + +/** + * g_file_info_set_sort_order: + * @info: a #GFileInfo. + * @sort_order: a sort order integer. + * + * Sets the sort order attribute in the file info structure. See + * %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER. + **/ +void +g_file_info_set_sort_order (GFileInfo *info, + gint32 sort_order) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_int32 (value, sort_order); +} + + +typedef struct { + guint32 id; + guint32 mask; +} SubMatcher; + +struct _GFileAttributeMatcher { + gboolean all; + gint ref; + + GArray *sub_matchers; + + /* Iterator */ + guint32 iterator_ns; + gint iterator_pos; +}; + +G_DEFINE_BOXED_TYPE (GFileAttributeMatcher, g_file_attribute_matcher, + g_file_attribute_matcher_ref, + g_file_attribute_matcher_unref) + +static gint +compare_sub_matchers (gconstpointer a, + gconstpointer b) +{ + const SubMatcher *suba = a; + const SubMatcher *subb = b; + int diff; + + diff = suba->id - subb->id; + + if (diff) + return diff; + + return suba->mask - subb->mask; +} + +static gboolean +sub_matcher_matches (SubMatcher *matcher, + SubMatcher *submatcher) +{ + if ((matcher->mask & submatcher->mask) != matcher->mask) + return FALSE; + + return matcher->id == (submatcher->id & matcher->mask); +} + +/* Call this function after modifying a matcher. + * It will ensure all the invariants other functions rely on. + */ +static GFileAttributeMatcher * +matcher_optimize (GFileAttributeMatcher *matcher) +{ + SubMatcher *submatcher, *compare; + guint i, j; + + /* remove sub_matchers if we match everything anyway */ + if (matcher->all) + { + if (matcher->sub_matchers) + { + g_array_free (matcher->sub_matchers, TRUE); + matcher->sub_matchers = NULL; + } + return matcher; + } + + if (matcher->sub_matchers->len == 0) + { + g_file_attribute_matcher_unref (matcher); + return NULL; + } + + /* sort sub_matchers by id (and then mask), so we can bsearch + * and compare matchers in O(N) instead of O(N²) */ + g_array_sort (matcher->sub_matchers, compare_sub_matchers); + + /* remove duplicates and specific matches when we match the whole namespace */ + j = 0; + compare = &g_array_index (matcher->sub_matchers, SubMatcher, j); + + for (i = 1; i < matcher->sub_matchers->len; i++) + { + submatcher = &g_array_index (matcher->sub_matchers, SubMatcher, i); + if (sub_matcher_matches (compare, submatcher)) + continue; + + j++; + compare++; + + if (j < i) + *compare = *submatcher; + } + + g_array_set_size (matcher->sub_matchers, j + 1); + + return matcher; +} + +/** + * g_file_attribute_matcher_new: + * @attributes: an attribute string to match. + * + * Creates a new file attribute matcher, which matches attributes + * against a given string. #GFileAttributeMatchers are reference + * counted structures, and are created with a reference count of 1. If + * the number of references falls to 0, the #GFileAttributeMatcher is + * automatically destroyed. + * + * The @attributes string should be formatted with specific keys separated + * from namespaces with a double colon. Several "namespace::key" strings may be + * concatenated with a single comma (e.g. "standard::type,standard::is-hidden"). + * The wildcard "*" may be used to match all keys and namespaces, or + * "namespace::*" will match all keys in a given namespace. + * + * ## Examples of file attribute matcher strings and results + * + * - `"*"`: matches all attributes. + * - `"standard::is-hidden"`: matches only the key is-hidden in the + * standard namespace. + * - `"standard::type,unix::*"`: matches the type key in the standard + * namespace and all keys in the unix namespace. + * + * Returns: a #GFileAttributeMatcher + */ +GFileAttributeMatcher * +g_file_attribute_matcher_new (const char *attributes) +{ + char **split; + char *colon; + int i; + GFileAttributeMatcher *matcher; + + if (attributes == NULL || *attributes == '\0') + return NULL; + + matcher = g_malloc0 (sizeof (GFileAttributeMatcher)); + matcher->ref = 1; + matcher->sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher)); + + split = g_strsplit (attributes, ",", -1); + + for (i = 0; split[i] != NULL; i++) + { + if (strcmp (split[i], "*") == 0) + matcher->all = TRUE; + else + { + SubMatcher s; + + colon = strstr (split[i], "::"); + if (colon != NULL && + !(colon[2] == 0 || + (colon[2] == '*' && + colon[3] == 0))) + { + s.id = lookup_attribute (split[i]); + s.mask = 0xffffffff; + } + else + { + if (colon) + *colon = 0; + + s.id = lookup_namespace (split[i]) << NS_POS; + s.mask = NS_MASK << NS_POS; + } + + g_array_append_val (matcher->sub_matchers, s); + } + } + + g_strfreev (split); + + matcher = matcher_optimize (matcher); + + return matcher; +} + +/** + * g_file_attribute_matcher_subtract: + * @matcher: (nullable): Matcher to subtract from + * @subtract: (nullable): The matcher to subtract + * + * Subtracts all attributes of @subtract from @matcher and returns + * a matcher that supports those attributes. + * + * Note that currently it is not possible to remove a single + * attribute when the @matcher matches the whole namespace - or remove + * a namespace or attribute when the matcher matches everything. This + * is a limitation of the current implementation, but may be fixed + * in the future. + * + * Returns: (nullable): A file attribute matcher matching all attributes of + * @matcher that are not matched by @subtract + **/ +GFileAttributeMatcher * +g_file_attribute_matcher_subtract (GFileAttributeMatcher *matcher, + GFileAttributeMatcher *subtract) +{ + GFileAttributeMatcher *result; + guint mi, si; + SubMatcher *msub, *ssub; + + if (matcher == NULL) + return NULL; + if (subtract == NULL) + return g_file_attribute_matcher_ref (matcher); + if (subtract->all) + return NULL; + if (matcher->all) + return g_file_attribute_matcher_ref (matcher); + + result = g_malloc0 (sizeof (GFileAttributeMatcher)); + result->ref = 1; + result->sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher)); + + si = 0; + g_assert (subtract->sub_matchers->len > 0); + ssub = &g_array_index (subtract->sub_matchers, SubMatcher, si); + + for (mi = 0; mi < matcher->sub_matchers->len; mi++) + { + msub = &g_array_index (matcher->sub_matchers, SubMatcher, mi); + +retry: + if (sub_matcher_matches (ssub, msub)) + continue; + + si++; + if (si >= subtract->sub_matchers->len) + break; + + ssub = &g_array_index (subtract->sub_matchers, SubMatcher, si); + if (ssub->id <= msub->id) + goto retry; + + g_array_append_val (result->sub_matchers, *msub); + } + + if (mi < matcher->sub_matchers->len) + g_array_append_vals (result->sub_matchers, + &g_array_index (matcher->sub_matchers, SubMatcher, mi), + matcher->sub_matchers->len - mi); + + result = matcher_optimize (result); + + return result; +} + +/** + * g_file_attribute_matcher_ref: + * @matcher: a #GFileAttributeMatcher. + * + * References a file attribute matcher. + * + * Returns: a #GFileAttributeMatcher. + **/ +GFileAttributeMatcher * +g_file_attribute_matcher_ref (GFileAttributeMatcher *matcher) +{ + if (matcher) + { + g_return_val_if_fail (matcher->ref > 0, NULL); + g_atomic_int_inc (&matcher->ref); + } + return matcher; +} + +/** + * g_file_attribute_matcher_unref: + * @matcher: a #GFileAttributeMatcher. + * + * Unreferences @matcher. If the reference count falls below 1, + * the @matcher is automatically freed. + * + **/ +void +g_file_attribute_matcher_unref (GFileAttributeMatcher *matcher) +{ + if (matcher) + { + g_return_if_fail (matcher->ref > 0); + + if (g_atomic_int_dec_and_test (&matcher->ref)) + { + if (matcher->sub_matchers) + g_array_free (matcher->sub_matchers, TRUE); + + g_free (matcher); + } + } +} + +/** + * g_file_attribute_matcher_matches_only: + * @matcher: a #GFileAttributeMatcher. + * @attribute: a file attribute key. + * + * Checks if a attribute matcher only matches a given attribute. Always + * returns %FALSE if "*" was used when creating the matcher. + * + * Returns: %TRUE if the matcher only matches @attribute. %FALSE otherwise. + **/ +gboolean +g_file_attribute_matcher_matches_only (GFileAttributeMatcher *matcher, + const char *attribute) +{ + SubMatcher *sub_matcher; + guint32 id; + + g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE); + + if (matcher == NULL || + matcher->all) + return FALSE; + + if (matcher->sub_matchers->len != 1) + return FALSE; + + id = lookup_attribute (attribute); + + sub_matcher = &g_array_index (matcher->sub_matchers, SubMatcher, 0); + + return sub_matcher->id == id && + sub_matcher->mask == 0xffffffff; +} + +static gboolean +matcher_matches_id (GFileAttributeMatcher *matcher, + guint32 id) +{ + SubMatcher *sub_matchers; + guint i; + + if (matcher->sub_matchers) + { + sub_matchers = (SubMatcher *)matcher->sub_matchers->data; + for (i = 0; i < matcher->sub_matchers->len; i++) + { + if (sub_matchers[i].id == (id & sub_matchers[i].mask)) + return TRUE; + } + } + + return FALSE; +} + +gboolean +_g_file_attribute_matcher_matches_id (GFileAttributeMatcher *matcher, + guint32 id) +{ + /* We return a NULL matcher for an empty match string, so handle this */ + if (matcher == NULL) + return FALSE; + + if (matcher->all) + return TRUE; + + return matcher_matches_id (matcher, id); +} + +/** + * g_file_attribute_matcher_matches: + * @matcher: a #GFileAttributeMatcher. + * @attribute: a file attribute key. + * + * Checks if an attribute will be matched by an attribute matcher. If + * the matcher was created with the "*" matching string, this function + * will always return %TRUE. + * + * Returns: %TRUE if @attribute matches @matcher. %FALSE otherwise. + **/ +gboolean +g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher, + const char *attribute) +{ + g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE); + + /* We return a NULL matcher for an empty match string, so handle this */ + if (matcher == NULL) + return FALSE; + + if (matcher->all) + return TRUE; + + return matcher_matches_id (matcher, lookup_attribute (attribute)); +} + +/* return TRUE -> all */ +/** + * g_file_attribute_matcher_enumerate_namespace: + * @matcher: a #GFileAttributeMatcher. + * @ns: a string containing a file attribute namespace. + * + * Checks if the matcher will match all of the keys in a given namespace. + * This will always return %TRUE if a wildcard character is in use (e.g. if + * matcher was created with "standard::*" and @ns is "standard", or if matcher was created + * using "*" and namespace is anything.) + * + * TODO: this is awkwardly worded. + * + * Returns: %TRUE if the matcher matches all of the entries + * in the given @ns, %FALSE otherwise. + **/ +gboolean +g_file_attribute_matcher_enumerate_namespace (GFileAttributeMatcher *matcher, + const char *ns) +{ + SubMatcher *sub_matchers; + guint ns_id; + guint i; + + g_return_val_if_fail (ns != NULL && *ns != '\0', FALSE); + + /* We return a NULL matcher for an empty match string, so handle this */ + if (matcher == NULL) + return FALSE; + + if (matcher->all) + return TRUE; + + ns_id = lookup_namespace (ns) << NS_POS; + + if (matcher->sub_matchers) + { + sub_matchers = (SubMatcher *)matcher->sub_matchers->data; + for (i = 0; i < matcher->sub_matchers->len; i++) + { + if (sub_matchers[i].id == ns_id) + return TRUE; + } + } + + matcher->iterator_ns = ns_id; + matcher->iterator_pos = 0; + + return FALSE; +} + +/** + * g_file_attribute_matcher_enumerate_next: + * @matcher: a #GFileAttributeMatcher. + * + * Gets the next matched attribute from a #GFileAttributeMatcher. + * + * Returns: (nullable): a string containing the next attribute or, %NULL if + * no more attribute exist. + **/ +const char * +g_file_attribute_matcher_enumerate_next (GFileAttributeMatcher *matcher) +{ + guint i; + SubMatcher *sub_matcher; + + /* We return a NULL matcher for an empty match string, so handle this */ + if (matcher == NULL) + return NULL; + + while (1) + { + i = matcher->iterator_pos++; + + if (matcher->sub_matchers == NULL) + return NULL; + + if (i < matcher->sub_matchers->len) + sub_matcher = &g_array_index (matcher->sub_matchers, SubMatcher, i); + else + return NULL; + + if (sub_matcher->mask == 0xffffffff && + (sub_matcher->id & (NS_MASK << NS_POS)) == matcher->iterator_ns) + return get_attribute_for_id (sub_matcher->id); + } +} + +/** + * g_file_attribute_matcher_to_string: + * @matcher: (nullable): a #GFileAttributeMatcher. + * + * Prints what the matcher is matching against. The format will be + * equal to the format passed to g_file_attribute_matcher_new(). + * The output however, might not be identical, as the matcher may + * decide to use a different order or omit needless parts. + * + * Returns: a string describing the attributes the matcher matches + * against or %NULL if @matcher was %NULL. + * + * Since: 2.32 + **/ +char * +g_file_attribute_matcher_to_string (GFileAttributeMatcher *matcher) +{ + GString *string; + guint i; + + if (matcher == NULL) + return NULL; + + if (matcher->all) + return g_strdup ("*"); + + string = g_string_new (""); + for (i = 0; i < matcher->sub_matchers->len; i++) + { + SubMatcher *submatcher = &g_array_index (matcher->sub_matchers, SubMatcher, i); + + if (i > 0) + g_string_append_c (string, ','); + + g_string_append (string, get_attribute_for_id (submatcher->id)); + } + + return g_string_free (string, FALSE); +} diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h new file mode 100644 index 0000000..086dda0 --- /dev/null +++ b/gio/gfileinfo.h @@ -0,0 +1,1313 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_INFO_H__ +#define __G_FILE_INFO_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_INFO (g_file_info_get_type ()) +#define G_FILE_INFO(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_INFO, GFileInfo)) +#define G_FILE_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_INFO, GFileInfoClass)) +#define G_IS_FILE_INFO(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_INFO)) +#define G_IS_FILE_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_INFO)) +#define G_FILE_INFO_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_INFO, GFileInfoClass)) + +/** + * GFileInfo: + * + * Stores information about a file system object referenced by a #GFile. + **/ +typedef struct _GFileInfoClass GFileInfoClass; + + +/* Common Attributes: */ +/** + * G_FILE_ATTRIBUTE_STANDARD_TYPE: + * + * A key in the "standard" namespace for storing file types. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + * + * The value for this key should contain a #GFileType. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_TYPE "standard::type" /* uint32 (GFileType) */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN: + * + * A key in the "standard" namespace for checking if a file is hidden. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "standard::is-hidden" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP: + * + * A key in the "standard" namespace for checking if a file is a backup file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP "standard::is-backup" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK: + * + * A key in the "standard" namespace for checking if the file is a symlink. + * Typically the actual type is something else, if we followed the symlink + * to get the type. + * + * On Windows NTFS mountpoints are considered to be symlinks as well. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "standard::is-symlink" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL: + * + * A key in the "standard" namespace for checking if a file is virtual. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL "standard::is-virtual" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE: + * + * A key in the "standard" namespace for checking if a file is + * volatile. This is meant for opaque, non-POSIX-like backends to + * indicate that the URI is not persistent. Applications should look + * at %G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET for the persistent URI. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * Since: 2.46 + **/ +#define G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE "standard::is-volatile" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_NAME: + * + * A key in the "standard" namespace for getting the name of the file. + * + * The name is the on-disk filename which may not be in any known encoding, + * and can thus not be generally displayed as is. It is guaranteed to be set on + * every file. + * + * Use %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME if you need to display the + * name in a user interface. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_NAME "standard::name" /* byte string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME: + * + * A key in the "standard" namespace for getting the display name of the file. + * + * A display name is guaranteed to be in UTF-8 and can thus be displayed in + * the UI. It is guaranteed to be set on every file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "standard::display-name" /* string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME: + * + * A key in the "standard" namespace for edit name of the file. + * + * An edit name is similar to the display name, but it is meant to be + * used when you want to rename the file in the UI. The display name + * might contain information you don't want in the new filename (such as + * "(invalid unicode)" if the filename was in an invalid encoding). + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME "standard::edit-name" /* string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_COPY_NAME: + * + * A key in the "standard" namespace for getting the copy name of the file. + * + * The copy name is an optional version of the name. If available it's always + * in UTF8, and corresponds directly to the original filename (only transcoded to + * UTF8). This is useful if you want to copy the file to another filesystem that + * might have a different encoding. If the filename is not a valid string in the + * encoding selected for the filesystem it is in then the copy name will not be set. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_COPY_NAME "standard::copy-name" /* string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION: + * + * A key in the "standard" namespace for getting the description of the file. + * + * The description is a utf8 string that describes the file, generally containing + * the filename, but can also contain further information. Example descriptions + * could be "filename (on hostname)" for a remote file or "filename (in trash)" + * for a file in the trash. This is useful for instance as the window title + * when displaying a directory or for a bookmarks menu. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_DESCRIPTION "standard::description" /* string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_ICON: + * + * A key in the "standard" namespace for getting the icon for the file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_OBJECT. + * + * The value for this key should contain a #GIcon. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_ICON "standard::icon" /* object (GIcon) */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON: + * + * A key in the "standard" namespace for getting the symbolic icon for the file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_OBJECT. + * + * The value for this key should contain a #GIcon. + * + * Since: 2.34 + **/ +#define G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON "standard::symbolic-icon" /* object (GIcon) */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE: + * + * A key in the "standard" namespace for getting the content type of the file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + * + * The value for this key should contain a valid content type. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "standard::content-type" /* string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE: + * + * A key in the "standard" namespace for getting the fast content type. + * + * The fast content type isn't as reliable as the regular one, as it + * only uses the filename to guess it, but it is faster to calculate than the + * regular content type. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + * + **/ +#define G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE "standard::fast-content-type" /* string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_SIZE: + * + * A key in the "standard" namespace for getting the file's size (in bytes). + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_SIZE "standard::size" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE: + * + * A key in the "standard" namespace for getting the amount of disk space + * that is consumed by the file (in bytes). + * + * This will generally be larger than the file size (due to block size + * overhead) but can occasionally be smaller (for example, for sparse files). + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64. + * + * Since: 2.20 + **/ +#define G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE "standard::allocated-size" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET: + * + * A key in the "standard" namespace for getting the symlink target, if the file + * is a symlink. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "standard::symlink-target" /* byte string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_TARGET_URI: + * + * A key in the "standard" namespace for getting the target URI for the file, in + * the case of %G_FILE_TYPE_SHORTCUT or %G_FILE_TYPE_MOUNTABLE files. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_TARGET_URI "standard::target-uri" /* string */ + +/** + * G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER: + * + * A key in the "standard" namespace for setting the sort order of a file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_INT32. + * + * An example use would be in file managers, which would use this key + * to set the order files are displayed. Files with smaller sort order + * should be sorted first, and files without sort order as if sort order + * was zero. + **/ +#define G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER "standard::sort-order" /* int32 */ + +/* Entity tags, used to avoid missing updates on save */ + +/** + * G_FILE_ATTRIBUTE_ETAG_VALUE: + * + * A key in the "etag" namespace for getting the value of the file's + * entity tag. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_ETAG_VALUE "etag::value" /* string */ + +/* File identifier, for e.g. avoiding loops when doing recursive + * directory scanning + */ + +/** + * G_FILE_ATTRIBUTE_ID_FILE: + * + * A key in the "id" namespace for getting a file identifier. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + * + * An example use would be during listing files, to avoid recursive + * directory scanning. + **/ +#define G_FILE_ATTRIBUTE_ID_FILE "id::file" /* string */ + +/** + * G_FILE_ATTRIBUTE_ID_FILESYSTEM: + * + * A key in the "id" namespace for getting the file system identifier. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + * + * An example use would be during drag and drop to see if the source + * and target are on the same filesystem (default to move) or not (default + * to copy). + **/ +#define G_FILE_ATTRIBUTE_ID_FILESYSTEM "id::filesystem" /* string */ + +/* Calculated Access Rights for current user */ + +/** + * G_FILE_ATTRIBUTE_ACCESS_CAN_READ: + * + * A key in the "access" namespace for getting read privileges. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * This attribute will be %TRUE if the user is able to read the file. + **/ +#define G_FILE_ATTRIBUTE_ACCESS_CAN_READ "access::can-read" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE: + * + * A key in the "access" namespace for getting write privileges. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * This attribute will be %TRUE if the user is able to write to the file. + **/ +#define G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "access::can-write" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE: + * + * A key in the "access" namespace for getting execution privileges. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * This attribute will be %TRUE if the user is able to execute the file. + **/ +#define G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE "access::can-execute" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE: + * + * A key in the "access" namespace for checking deletion privileges. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * This attribute will be %TRUE if the user is able to delete the file. + **/ +#define G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE "access::can-delete" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH: + * + * A key in the "access" namespace for checking trashing privileges. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * This attribute will be %TRUE if the user is able to move the file to + * the trash. + **/ +#define G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH "access::can-trash" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME: + * + * A key in the "access" namespace for checking renaming privileges. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * This attribute will be %TRUE if the user is able to rename the file. + **/ +#define G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME "access::can-rename" /* boolean */ + +/* TODO: Should we have special version for directories? can_enumerate, etc */ + +/* Mountable attributes */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT: + * + * A key in the "mountable" namespace for checking if a file (of + * type G_FILE_TYPE_MOUNTABLE) is mountable. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT "mountable::can-mount" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT: + * + * A key in the "mountable" namespace for checking if a file (of + * type G_FILE_TYPE_MOUNTABLE) is unmountable. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT "mountable::can-unmount" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT: + * + * A key in the "mountable" namespace for checking if a file (of + * type G_FILE_TYPE_MOUNTABLE) can be ejected. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT "mountable::can-eject" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE: + * + * A key in the "mountable" namespace for getting the unix device. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE "mountable::unix-device" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE_FILE: + * + * A key in the "mountable" namespace for getting the unix device file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + * + * Since: 2.22 + **/ +#define G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE_FILE "mountable::unix-device-file" /* string */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI: + * + * A key in the "mountable" namespace for getting the HAL UDI for the mountable + * file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI "mountable::hal-udi" /* string */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START: + * + * A key in the "mountable" namespace for checking if a file (of + * type G_FILE_TYPE_MOUNTABLE) can be started. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * Since: 2.22 + */ +#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START "mountable::can-start" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START_DEGRADED: + * + * A key in the "mountable" namespace for checking if a file (of + * type G_FILE_TYPE_MOUNTABLE) can be started degraded. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * Since: 2.22 + */ +#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START_DEGRADED "mountable::can-start-degraded" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP: + * + * A key in the "mountable" namespace for checking if a file (of + * type G_FILE_TYPE_MOUNTABLE) can be stopped. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * Since: 2.22 + */ +#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP "mountable::can-stop" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE: + * + * A key in the "mountable" namespace for getting the #GDriveStartStopType. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + * + * Since: 2.22 + */ +#define G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE "mountable::start-stop-type" /* uint32 (GDriveStartStopType) */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_POLL: + * + * A key in the "mountable" namespace for checking if a file (of + * type G_FILE_TYPE_MOUNTABLE) can be polled. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * Since: 2.22 + */ +#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_POLL "mountable::can-poll" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC: + * + * A key in the "mountable" namespace for checking if a file (of + * type G_FILE_TYPE_MOUNTABLE) is automatically polled for media. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * Since: 2.22 + */ +#define G_FILE_ATTRIBUTE_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC "mountable::is-media-check-automatic" /* boolean */ + +/* Time attributes */ + +/** + * G_FILE_ATTRIBUTE_TIME_MODIFIED: + * + * A key in the "time" namespace for getting the time the file was last + * modified. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64, and + * contains the time since the file was modified, in seconds since the UNIX + * epoch. + **/ +#define G_FILE_ATTRIBUTE_TIME_MODIFIED "time::modified" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC: + * + * A key in the "time" namespace for getting the microseconds of the time + * the file was last modified. + * + * This should be used in conjunction with %G_FILE_ATTRIBUTE_TIME_MODIFIED. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC "time::modified-usec" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_TIME_ACCESS: + * + * A key in the "time" namespace for getting the time the file was last + * accessed. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64, and + * contains the time since the file was last accessed, in seconds since the + * UNIX epoch. + **/ +#define G_FILE_ATTRIBUTE_TIME_ACCESS "time::access" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_TIME_ACCESS_USEC: + * + * A key in the "time" namespace for getting the microseconds of the time + * the file was last accessed. + * + * This should be used in conjunction with %G_FILE_ATTRIBUTE_TIME_ACCESS. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_TIME_ACCESS_USEC "time::access-usec" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_TIME_CHANGED: + * + * A key in the "time" namespace for getting the time the file was last + * changed. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64, + * and contains the time since the file was last changed, in seconds since + * the UNIX epoch. + * + * This corresponds to the traditional UNIX ctime. + **/ +#define G_FILE_ATTRIBUTE_TIME_CHANGED "time::changed" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_TIME_CHANGED_USEC: + * + * A key in the "time" namespace for getting the microseconds of the time + * the file was last changed. + * + * This should be used in conjunction with %G_FILE_ATTRIBUTE_TIME_CHANGED. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_TIME_CHANGED_USEC "time::changed-usec" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_TIME_CREATED: + * + * A key in the "time" namespace for getting the time the file was created. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64, + * and contains the time since the file was created, in seconds since the UNIX + * epoch. + * + * This may correspond to Linux `stx_btime`, FreeBSD `st_birthtim`, NetBSD + * `st_birthtime` or NTFS `ctime`. + **/ +#define G_FILE_ATTRIBUTE_TIME_CREATED "time::created" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_TIME_CREATED_USEC: + * + * A key in the "time" namespace for getting the microseconds of the time + * the file was created. + * + * This should be used in conjunction with %G_FILE_ATTRIBUTE_TIME_CREATED. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_TIME_CREATED_USEC "time::created-usec" /* uint32 */ + +/* Unix specific attributes */ + +/** + * G_FILE_ATTRIBUTE_UNIX_DEVICE: + * + * A key in the "unix" namespace for getting the device id of the device the + * file is located on (see stat() documentation). + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_UNIX_DEVICE "unix::device" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_INODE: + * + * A key in the "unix" namespace for getting the inode of the file. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64. + **/ +#define G_FILE_ATTRIBUTE_UNIX_INODE "unix::inode" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_MODE: + * + * A key in the "unix" namespace for getting the mode of the file + * (e.g. whether the file is a regular file, symlink, etc). + * + * See the documentation for `lstat()`: this attribute is equivalent to + * the `st_mode` member of `struct stat`, and includes both the file type + * and permissions. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_UNIX_MODE "unix::mode" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_NLINK: + * + * A key in the "unix" namespace for getting the number of hard links + * for a file. + * + * See the documentation for `lstat()`. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_UNIX_NLINK "unix::nlink" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_UID: + * + * A key in the "unix" namespace for getting the user ID for the file. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_UNIX_UID "unix::uid" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_GID: + * + * A key in the "unix" namespace for getting the group ID for the file. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_UNIX_GID "unix::gid" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_RDEV: + * + * A key in the "unix" namespace for getting the device ID for the file + * (if it is a special file). + * + * See the documentation for `lstat()`. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_UNIX_RDEV "unix::rdev" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE: + * + * A key in the "unix" namespace for getting the block size for the file + * system. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE "unix::block-size" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_BLOCKS: + * + * A key in the "unix" namespace for getting the number of blocks allocated + * for the file. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64. + **/ +#define G_FILE_ATTRIBUTE_UNIX_BLOCKS "unix::blocks" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT: + * + * A key in the "unix" namespace for checking if the file represents a + * UNIX mount point. + * + * This attribute is %TRUE if the file is a UNIX mount point. + * + * Since 2.58, `/` is considered to be a mount point. + * + * This attribute is only available for UNIX file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT "unix::is-mountpoint" /* boolean */ + +/* DOS specific attributes */ + +/** + * G_FILE_ATTRIBUTE_DOS_IS_ARCHIVE: + * + * A key in the "dos" namespace for checking if the file's archive flag + * is set. + * + * This attribute is %TRUE if the archive flag is set. + * + * This attribute is only available for DOS file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_DOS_IS_ARCHIVE "dos::is-archive" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_DOS_IS_SYSTEM: + * + * A key in the "dos" namespace for checking if the file's backup flag + * is set. + * + * This attribute is %TRUE if the backup flag is set. + * + * This attribute is only available for DOS file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_DOS_IS_SYSTEM "dos::is-system" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT: + * + * A key in the "dos" namespace for checking if the file is a NTFS mount point + * (a volume mount or a junction point). + * + * This attribute is %TRUE if file is a reparse point of type + * [IO_REPARSE_TAG_MOUNT_POINT](https://msdn.microsoft.com/en-us/library/dd541667.aspx). + * + * This attribute is only available for DOS file systems. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * Since: 2.60 + **/ +#define G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT "dos::is-mountpoint" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG: + * + * A key in the "dos" namespace for getting the file NTFS reparse tag. + * + * This value is 0 for files that are not reparse points. + * + * See the [Reparse Tags](https://msdn.microsoft.com/en-us/library/dd541667.aspx) + * page for possible reparse tag values. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + * + * Since: 2.60 + **/ +#define G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG "dos::reparse-point-tag" /* uint32 */ + +/* Owner attributes */ + +/** + * G_FILE_ATTRIBUTE_OWNER_USER: + * + * A key in the "owner" namespace for getting the user name of the + * file's owner. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_OWNER_USER "owner::user" /* string */ + +/** + * G_FILE_ATTRIBUTE_OWNER_USER_REAL: + * + * A key in the "owner" namespace for getting the real name of the + * user that owns the file. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_OWNER_USER_REAL "owner::user-real" /* string */ + +/** + * G_FILE_ATTRIBUTE_OWNER_GROUP: + * + * A key in the "owner" namespace for getting the file owner's group. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_OWNER_GROUP "owner::group" /* string */ + +/* Thumbnails */ + +/** + * G_FILE_ATTRIBUTE_THUMBNAIL_PATH: + * + * A key in the "thumbnail" namespace for getting the path to the thumbnail + * image. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING. + **/ +#define G_FILE_ATTRIBUTE_THUMBNAIL_PATH "thumbnail::path" /* bytestring */ +/** + * G_FILE_ATTRIBUTE_THUMBNAILING_FAILED: + * + * A key in the "thumbnail" namespace for checking if thumbnailing failed. + * + * This attribute is %TRUE if thumbnailing failed. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_THUMBNAILING_FAILED "thumbnail::failed" /* boolean */ +/** + * G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID: + * + * A key in the "thumbnail" namespace for checking whether the thumbnail is outdated. + * + * This attribute is %TRUE if the thumbnail is up-to-date with the file it represents, + * and %FALSE if the file has been modified since the thumbnail was generated. + * + * If %G_FILE_ATTRIBUTE_THUMBNAILING_FAILED is %TRUE and this attribute is %FALSE, + * it indicates that thumbnailing may be attempted again and may succeed. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + * + * Since: 2.40 + */ +#define G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID "thumbnail::is-valid" /* boolean */ + +/* Preview */ + +/** + * G_FILE_ATTRIBUTE_PREVIEW_ICON: + * + * A key in the "preview" namespace for getting a #GIcon that can be + * used to get preview of the file. + * + * For example, it may be a low resolution thumbnail without metadata. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_OBJECT. + * + * The value for this key should contain a #GIcon. + * + * Since: 2.20 + **/ +#define G_FILE_ATTRIBUTE_PREVIEW_ICON "preview::icon" /* object (GIcon) */ + +/* File system info (for g_file_get_filesystem_info) */ + +/** + * G_FILE_ATTRIBUTE_FILESYSTEM_SIZE: + * + * A key in the "filesystem" namespace for getting the total size (in + * bytes) of the file system, used in g_file_query_filesystem_info(). + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64. + **/ +#define G_FILE_ATTRIBUTE_FILESYSTEM_SIZE "filesystem::size" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_FILESYSTEM_FREE: + * + * A key in the "filesystem" namespace for getting the number of bytes + * of free space left on the file system. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64. + **/ +#define G_FILE_ATTRIBUTE_FILESYSTEM_FREE "filesystem::free" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_FILESYSTEM_USED: + * + * A key in the "filesystem" namespace for getting the number of bytes + * used by data on the file system. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT64. + * + * Since: 2.32 + */ +#define G_FILE_ATTRIBUTE_FILESYSTEM_USED "filesystem::used" /* uint64 */ + +/** + * G_FILE_ATTRIBUTE_FILESYSTEM_TYPE: + * + * A key in the "filesystem" namespace for getting the file system's type. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_FILESYSTEM_TYPE "filesystem::type" /* string */ + +/** + * G_FILE_ATTRIBUTE_FILESYSTEM_READONLY: + * + * A key in the "filesystem" namespace for checking if the file system + * is read only. + * + * Is set to %TRUE if the file system is read only. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_FILESYSTEM_READONLY "filesystem::readonly" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW: + * + * A key in the "filesystem" namespace for hinting a file manager + * application whether it should preview (e.g. thumbnail) files on the + * file system. + * + * The value for this key contain a #GFilesystemPreviewType. + **/ +#define G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW "filesystem::use-preview" /* uint32 (GFilesystemPreviewType) */ + +/** + * G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE: + * + * A key in the "filesystem" namespace for checking if the file system + * is remote. + * + * Is set to %TRUE if the file system is remote. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. + **/ +#define G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE "filesystem::remote" /* boolean */ + +/** + * G_FILE_ATTRIBUTE_GVFS_BACKEND: + * + * A key in the "gvfs" namespace that gets the name of the current + * GVFS backend in use. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + **/ +#define G_FILE_ATTRIBUTE_GVFS_BACKEND "gvfs::backend" /* string */ + +/** + * G_FILE_ATTRIBUTE_SELINUX_CONTEXT: + * + * A key in the "selinux" namespace for getting the file's SELinux + * context. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + * + * Note that this attribute is only available if GLib has been built + * with SELinux support. + **/ +#define G_FILE_ATTRIBUTE_SELINUX_CONTEXT "selinux::context" /* string */ + +/** + * G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT: + * + * A key in the "trash" namespace for getting the number of (toplevel) items + * that are present in the `trash:///` folder. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32. + **/ +#define G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT "trash::item-count" /* uint32 */ + +/** + * G_FILE_ATTRIBUTE_TRASH_ORIG_PATH: + * + * A key in the "trash" namespace for getting the original path of a file + * inside the `trash:///` folder before it was trashed. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING. + * + * Since: 2.24 + **/ +#define G_FILE_ATTRIBUTE_TRASH_ORIG_PATH "trash::orig-path" /* byte string */ + +/** + * G_FILE_ATTRIBUTE_TRASH_DELETION_DATE: + * + * A key in the "trash" namespace for getting the deletion date and time + * of a file inside the `trash:///` folder. + * + * The format of the returned string is `YYYY-MM-DDThh:mm:ss`. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING. + * + * Since: 2.24 + **/ +#define G_FILE_ATTRIBUTE_TRASH_DELETION_DATE "trash::deletion-date" /* string */ + +/** + * G_FILE_ATTRIBUTE_RECENT_MODIFIED: + * + * A key in the "recent" namespace for getting time, when the metadata for the + * file in `recent:///` was last changed. + * + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_INT64. + * + * Since: 2.52 + **/ +#define G_FILE_ATTRIBUTE_RECENT_MODIFIED "recent::modified" /* int64 (time_t) */ + +GLIB_AVAILABLE_IN_ALL +GType g_file_info_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GFileInfo * g_file_info_new (void); +GLIB_AVAILABLE_IN_ALL +GFileInfo * g_file_info_dup (GFileInfo *other); +GLIB_AVAILABLE_IN_ALL +void g_file_info_copy_into (GFileInfo *src_info, + GFileInfo *dest_info); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_info_has_attribute (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_info_has_namespace (GFileInfo *info, + const char *name_space); +GLIB_AVAILABLE_IN_ALL +char ** g_file_info_list_attributes (GFileInfo *info, + const char *name_space); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_info_get_attribute_data (GFileInfo *info, + const char *attribute, + GFileAttributeType *type, + gpointer *value_pp, + GFileAttributeStatus *status); +GLIB_AVAILABLE_IN_ALL +GFileAttributeType g_file_info_get_attribute_type (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +void g_file_info_remove_attribute (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +GFileAttributeStatus g_file_info_get_attribute_status (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_info_set_attribute_status (GFileInfo *info, + const char *attribute, + GFileAttributeStatus status); +GLIB_AVAILABLE_IN_ALL +char * g_file_info_get_attribute_as_string (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +const char * g_file_info_get_attribute_string (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +const char * g_file_info_get_attribute_byte_string (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_info_get_attribute_boolean (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +guint32 g_file_info_get_attribute_uint32 (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +gint32 g_file_info_get_attribute_int32 (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +guint64 g_file_info_get_attribute_uint64 (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +gint64 g_file_info_get_attribute_int64 (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +GObject * g_file_info_get_attribute_object (GFileInfo *info, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +char ** g_file_info_get_attribute_stringv (GFileInfo *info, + const char *attribute); + +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute (GFileInfo *info, + const char *attribute, + GFileAttributeType type, + gpointer value_p); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_string (GFileInfo *info, + const char *attribute, + const char *attr_value); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_byte_string (GFileInfo *info, + const char *attribute, + const char *attr_value); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_boolean (GFileInfo *info, + const char *attribute, + gboolean attr_value); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_uint32 (GFileInfo *info, + const char *attribute, + guint32 attr_value); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_int32 (GFileInfo *info, + const char *attribute, + gint32 attr_value); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_uint64 (GFileInfo *info, + const char *attribute, + guint64 attr_value); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_int64 (GFileInfo *info, + const char *attribute, + gint64 attr_value); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_object (GFileInfo *info, + const char *attribute, + GObject *attr_value); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_stringv (GFileInfo *info, + const char *attribute, + char **attr_value); + +GLIB_AVAILABLE_IN_ALL +void g_file_info_clear_status (GFileInfo *info); + +/* Helper getters: */ +GLIB_AVAILABLE_IN_2_36 +GDateTime * g_file_info_get_deletion_date (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +GFileType g_file_info_get_file_type (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_info_get_is_hidden (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_info_get_is_backup (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_info_get_is_symlink (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +const char * g_file_info_get_name (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +const char * g_file_info_get_display_name (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +const char * g_file_info_get_edit_name (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +GIcon * g_file_info_get_icon (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +GIcon * g_file_info_get_symbolic_icon (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +const char * g_file_info_get_content_type (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +goffset g_file_info_get_size (GFileInfo *info); +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_DEPRECATED_IN_2_62_FOR(g_file_info_get_modification_date_time) +void g_file_info_get_modification_time (GFileInfo *info, + GTimeVal *result); +G_GNUC_END_IGNORE_DEPRECATIONS +GLIB_AVAILABLE_IN_2_62 +GDateTime * g_file_info_get_modification_date_time (GFileInfo *info); +GLIB_AVAILABLE_IN_2_70 +GDateTime * g_file_info_get_access_date_time (GFileInfo *info); +GLIB_AVAILABLE_IN_2_70 +GDateTime * g_file_info_get_creation_date_time (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +const char * g_file_info_get_symlink_target (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +const char * g_file_info_get_etag (GFileInfo *info); +GLIB_AVAILABLE_IN_ALL +gint32 g_file_info_get_sort_order (GFileInfo *info); + +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_attribute_mask (GFileInfo *info, + GFileAttributeMatcher *mask); +GLIB_AVAILABLE_IN_ALL +void g_file_info_unset_attribute_mask (GFileInfo *info); + +/* Helper setters: */ +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_file_type (GFileInfo *info, + GFileType type); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_is_hidden (GFileInfo *info, + gboolean is_hidden); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_is_symlink (GFileInfo *info, + gboolean is_symlink); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_name (GFileInfo *info, + const char *name); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_display_name (GFileInfo *info, + const char *display_name); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_edit_name (GFileInfo *info, + const char *edit_name); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_icon (GFileInfo *info, + GIcon *icon); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_symbolic_icon (GFileInfo *info, + GIcon *icon); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_content_type (GFileInfo *info, + const char *content_type); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_size (GFileInfo *info, + goffset size); +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_DEPRECATED_IN_2_62_FOR(g_file_info_set_modification_date_time) +void g_file_info_set_modification_time (GFileInfo *info, + GTimeVal *mtime); +G_GNUC_END_IGNORE_DEPRECATIONS +GLIB_AVAILABLE_IN_2_62 +void g_file_info_set_modification_date_time (GFileInfo *info, + GDateTime *mtime); +GLIB_AVAILABLE_IN_2_70 +void g_file_info_set_access_date_time (GFileInfo *info, + GDateTime *atime); +GLIB_AVAILABLE_IN_2_70 +void g_file_info_set_creation_date_time (GFileInfo *info, + GDateTime *creation_time); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_symlink_target (GFileInfo *info, + const char *symlink_target); +GLIB_AVAILABLE_IN_ALL +void g_file_info_set_sort_order (GFileInfo *info, + gint32 sort_order); + +#define G_TYPE_FILE_ATTRIBUTE_MATCHER (g_file_attribute_matcher_get_type ()) +GLIB_AVAILABLE_IN_ALL +GType g_file_attribute_matcher_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GFileAttributeMatcher *g_file_attribute_matcher_new (const char *attributes); +GLIB_AVAILABLE_IN_ALL +GFileAttributeMatcher *g_file_attribute_matcher_ref (GFileAttributeMatcher *matcher); +GLIB_AVAILABLE_IN_ALL +void g_file_attribute_matcher_unref (GFileAttributeMatcher *matcher); +GLIB_AVAILABLE_IN_ALL +GFileAttributeMatcher *g_file_attribute_matcher_subtract (GFileAttributeMatcher *matcher, + GFileAttributeMatcher *subtract); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_attribute_matcher_matches_only (GFileAttributeMatcher *matcher, + const char *attribute); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_attribute_matcher_enumerate_namespace (GFileAttributeMatcher *matcher, + const char *ns); +GLIB_AVAILABLE_IN_ALL +const char * g_file_attribute_matcher_enumerate_next (GFileAttributeMatcher *matcher); +GLIB_AVAILABLE_IN_2_32 +char * g_file_attribute_matcher_to_string (GFileAttributeMatcher *matcher); + +G_END_DECLS + +#endif /* __G_FILE_INFO_H__ */ diff --git a/gio/gfileinputstream.c b/gio/gfileinputstream.c new file mode 100644 index 0000000..df956ae --- /dev/null +++ b/gio/gfileinputstream.c @@ -0,0 +1,429 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include "gcancellable.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gfileinputstream + * @short_description: File input streaming operations + * @include: gio/gio.h + * @see_also: #GInputStream, #GDataInputStream, #GSeekable + * + * GFileInputStream provides input streams that take their + * content from a file. + * + * GFileInputStream implements #GSeekable, which allows the input + * stream to jump to arbitrary positions in the file, provided the + * filesystem of the file allows it. To find the position of a file + * input stream, use g_seekable_tell(). To find out if a file input + * stream supports seeking, use g_seekable_can_seek(). + * To position a file input stream, use g_seekable_seek(). + **/ + +static void g_file_input_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_file_input_stream_seekable_tell (GSeekable *seekable); +static gboolean g_file_input_stream_seekable_can_seek (GSeekable *seekable); +static gboolean g_file_input_stream_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_file_input_stream_seekable_can_truncate (GSeekable *seekable); +static gboolean g_file_input_stream_seekable_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); +static void g_file_input_stream_real_query_info_async (GFileInputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileInfo *g_file_input_stream_real_query_info_finish (GFileInputStream *stream, + GAsyncResult *result, + GError **error); + + +struct _GFileInputStreamPrivate { + GAsyncReadyCallback outstanding_callback; +}; + +G_DEFINE_TYPE_WITH_CODE (GFileInputStream, g_file_input_stream, G_TYPE_INPUT_STREAM, + G_ADD_PRIVATE (GFileInputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_file_input_stream_seekable_iface_init)) + +static void +g_file_input_stream_class_init (GFileInputStreamClass *klass) +{ + klass->query_info_async = g_file_input_stream_real_query_info_async; + klass->query_info_finish = g_file_input_stream_real_query_info_finish; +} + +static void +g_file_input_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_file_input_stream_seekable_tell; + iface->can_seek = g_file_input_stream_seekable_can_seek; + iface->seek = g_file_input_stream_seekable_seek; + iface->can_truncate = g_file_input_stream_seekable_can_truncate; + iface->truncate_fn = g_file_input_stream_seekable_truncate; +} + +static void +g_file_input_stream_init (GFileInputStream *stream) +{ + stream->priv = g_file_input_stream_get_instance_private (stream); +} + +/** + * g_file_input_stream_query_info: + * @stream: a #GFileInputStream. + * @attributes: a file attribute query string. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Queries a file input stream the given @attributes. This function blocks + * while querying the stream. For the asynchronous (non-blocking) version + * of this function, see g_file_input_stream_query_info_async(). While the + * stream is blocked, the stream will set the pending flag internally, and + * any other operations on the stream will fail with %G_IO_ERROR_PENDING. + * + * Returns: (transfer full): a #GFileInfo, or %NULL on error. + **/ +GFileInfo * +g_file_input_stream_query_info (GFileInputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GFileInputStreamClass *class; + GInputStream *input_stream; + GFileInfo *info; + + g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), NULL); + + input_stream = G_INPUT_STREAM (stream); + + if (!g_input_stream_set_pending (input_stream, error)) + return NULL; + + info = NULL; + + if (cancellable) + g_cancellable_push_current (cancellable); + + class = G_FILE_INPUT_STREAM_GET_CLASS (stream); + if (class->query_info) + info = class->query_info (stream, attributes, cancellable, error); + else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Stream doesn’t support query_info")); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_input_stream_clear_pending (input_stream); + + return info; +} + +static void +async_ready_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GFileInputStream *stream = G_FILE_INPUT_STREAM (source_object); + + g_input_stream_clear_pending (G_INPUT_STREAM (stream)); + if (stream->priv->outstanding_callback) + (*stream->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (stream); +} + +/** + * g_file_input_stream_query_info_async: + * @stream: a #GFileInputStream. + * @attributes: a file attribute query string. + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Queries the stream information asynchronously. + * When the operation is finished @callback will be called. + * You can then call g_file_input_stream_query_info_finish() + * to get the result of the operation. + * + * For the synchronous version of this function, + * see g_file_input_stream_query_info(). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be set + * + **/ +void +g_file_input_stream_query_info_async (GFileInputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileInputStreamClass *klass; + GInputStream *input_stream; + GError *error = NULL; + + g_return_if_fail (G_IS_FILE_INPUT_STREAM (stream)); + + input_stream = G_INPUT_STREAM (stream); + + if (!g_input_stream_set_pending (input_stream, &error)) + { + g_task_report_error (stream, callback, user_data, + g_file_input_stream_query_info_async, + error); + return; + } + + klass = G_FILE_INPUT_STREAM_GET_CLASS (stream); + + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + klass->query_info_async (stream, attributes, io_priority, cancellable, + async_ready_callback_wrapper, user_data); +} + +/** + * g_file_input_stream_query_info_finish: + * @stream: a #GFileInputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, + * or %NULL to ignore. + * + * Finishes an asynchronous info query operation. + * + * Returns: (transfer full): #GFileInfo. + **/ +GFileInfo * +g_file_input_stream_query_info_finish (GFileInputStream *stream, + GAsyncResult *result, + GError **error) +{ + GFileInputStreamClass *class; + + g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + else if (g_async_result_is_tagged (result, g_file_input_stream_query_info_async)) + return g_task_propagate_pointer (G_TASK (result), error); + + class = G_FILE_INPUT_STREAM_GET_CLASS (stream); + return class->query_info_finish (stream, result, error); +} + +static goffset +g_file_input_stream_tell (GFileInputStream *stream) +{ + GFileInputStreamClass *class; + goffset offset; + + g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), 0); + + class = G_FILE_INPUT_STREAM_GET_CLASS (stream); + + offset = 0; + if (class->tell) + offset = class->tell (stream); + + return offset; +} + +static goffset +g_file_input_stream_seekable_tell (GSeekable *seekable) +{ + return g_file_input_stream_tell (G_FILE_INPUT_STREAM (seekable)); +} + +static gboolean +g_file_input_stream_can_seek (GFileInputStream *stream) +{ + GFileInputStreamClass *class; + gboolean can_seek; + + g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), FALSE); + + class = G_FILE_INPUT_STREAM_GET_CLASS (stream); + + can_seek = FALSE; + if (class->seek) + { + can_seek = TRUE; + if (class->can_seek) + can_seek = class->can_seek (stream); + } + + return can_seek; +} + +static gboolean +g_file_input_stream_seekable_can_seek (GSeekable *seekable) +{ + return g_file_input_stream_can_seek (G_FILE_INPUT_STREAM (seekable)); +} + +static gboolean +g_file_input_stream_seek (GFileInputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GFileInputStreamClass *class; + GInputStream *input_stream; + gboolean res; + + g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), FALSE); + + input_stream = G_INPUT_STREAM (stream); + class = G_FILE_INPUT_STREAM_GET_CLASS (stream); + + if (!class->seek) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Seek not supported on stream")); + return FALSE; + } + + if (!g_input_stream_set_pending (input_stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->seek (stream, offset, type, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_input_stream_clear_pending (input_stream); + + return res; +} + +static gboolean +g_file_input_stream_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + return g_file_input_stream_seek (G_FILE_INPUT_STREAM (seekable), + offset, type, cancellable, error); +} + +static gboolean +g_file_input_stream_seekable_can_truncate (GSeekable *seekable) +{ + return FALSE; +} + +static gboolean +g_file_input_stream_seekable_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Truncate not allowed on input stream")); + return FALSE; +} + +/******************************************** + * Default implementation of async ops * + ********************************************/ + +static void +query_info_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileInputStream *stream = source_object; + const char *attributes = task_data; + GFileInputStreamClass *class; + GError *error = NULL; + GFileInfo *info = NULL; + + class = G_FILE_INPUT_STREAM_GET_CLASS (stream); + if (class->query_info) + info = class->query_info (stream, attributes, cancellable, &error); + else + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Stream doesn’t support query_info")); + + if (info == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, info, g_object_unref); +} + +static void +g_file_input_stream_real_query_info_async (GFileInputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_input_stream_real_query_info_async); + g_task_set_task_data (task, g_strdup (attributes), g_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, query_info_async_thread); + g_object_unref (task); +} + +static GFileInfo * +g_file_input_stream_real_query_info_finish (GFileInputStream *stream, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, stream), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} diff --git a/gio/gfileinputstream.h b/gio/gfileinputstream.h new file mode 100644 index 0000000..f84eecc --- /dev/null +++ b/gio/gfileinputstream.h @@ -0,0 +1,114 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_INPUT_STREAM_H__ +#define __G_FILE_INPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_INPUT_STREAM (g_file_input_stream_get_type ()) +#define G_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_INPUT_STREAM, GFileInputStream)) +#define G_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_INPUT_STREAM, GFileInputStreamClass)) +#define G_IS_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_INPUT_STREAM)) +#define G_IS_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_INPUT_STREAM)) +#define G_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_INPUT_STREAM, GFileInputStreamClass)) + +/** + * GFileInputStream: + * + * A subclass of GInputStream for opened files. This adds + * a few file-specific operations and seeking. + * + * #GFileInputStream implements #GSeekable. + **/ +typedef struct _GFileInputStreamClass GFileInputStreamClass; +typedef struct _GFileInputStreamPrivate GFileInputStreamPrivate; + +struct _GFileInputStream +{ + GInputStream parent_instance; + + /*< private >*/ + GFileInputStreamPrivate *priv; +}; + +struct _GFileInputStreamClass +{ + GInputStreamClass parent_class; + + goffset (* tell) (GFileInputStream *stream); + gboolean (* can_seek) (GFileInputStream *stream); + gboolean (* seek) (GFileInputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); + GFileInfo * (* query_info) (GFileInputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); + void (* query_info_async) (GFileInputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileInfo * (* query_info_finish) (GFileInputStream *stream, + GAsyncResult *result, + GError **error); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_file_input_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_file_input_stream_query_info (GFileInputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_input_stream_query_info_async (GFileInputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_file_input_stream_query_info_finish (GFileInputStream *stream, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __G_FILE_FILE_INPUT_STREAM_H__ */ diff --git a/gio/gfileiostream.c b/gio/gfileiostream.c new file mode 100644 index 0000000..f599bcd --- /dev/null +++ b/gio/gfileiostream.c @@ -0,0 +1,662 @@ +/* GIO - GLib Input, IO and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include "gasyncresult.h" +#include "gtask.h" +#include "gcancellable.h" +#include "gioerror.h" +#include "gfileoutputstream.h" +#include "glibintl.h" + + +/** + * SECTION:gfileiostream + * @short_description: File read and write streaming operations + * @include: gio/gio.h + * @see_also: #GIOStream, #GFileInputStream, #GFileOutputStream, #GSeekable + * + * GFileIOStream provides io streams that both read and write to the same + * file handle. + * + * GFileIOStream implements #GSeekable, which allows the io + * stream to jump to arbitrary positions in the file and to truncate + * the file, provided the filesystem of the file supports these + * operations. + * + * To find the position of a file io stream, use + * g_seekable_tell(). + * + * To find out if a file io stream supports seeking, use g_seekable_can_seek(). + * To position a file io stream, use g_seekable_seek(). + * To find out if a file io stream supports truncating, use + * g_seekable_can_truncate(). To truncate a file io + * stream, use g_seekable_truncate(). + * + * The default implementation of all the #GFileIOStream operations + * and the implementation of #GSeekable just call into the same operations + * on the output stream. + * Since: 2.22 + **/ + +static void g_file_io_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_file_io_stream_seekable_tell (GSeekable *seekable); +static gboolean g_file_io_stream_seekable_can_seek (GSeekable *seekable); +static gboolean g_file_io_stream_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_file_io_stream_seekable_can_truncate (GSeekable *seekable); +static gboolean g_file_io_stream_seekable_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); +static void g_file_io_stream_real_query_info_async (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileInfo *g_file_io_stream_real_query_info_finish (GFileIOStream *stream, + GAsyncResult *result, + GError **error); + +struct _GFileIOStreamPrivate { + GAsyncReadyCallback outstanding_callback; +}; + +G_DEFINE_TYPE_WITH_CODE (GFileIOStream, g_file_io_stream, G_TYPE_IO_STREAM, + G_ADD_PRIVATE (GFileIOStream) + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_file_io_stream_seekable_iface_init)) + +static void +g_file_io_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_file_io_stream_seekable_tell; + iface->can_seek = g_file_io_stream_seekable_can_seek; + iface->seek = g_file_io_stream_seekable_seek; + iface->can_truncate = g_file_io_stream_seekable_can_truncate; + iface->truncate_fn = g_file_io_stream_seekable_truncate; +} + +static void +g_file_io_stream_init (GFileIOStream *stream) +{ + stream->priv = g_file_io_stream_get_instance_private (stream); +} + +/** + * g_file_io_stream_query_info: + * @stream: a #GFileIOStream. + * @attributes: a file attribute query string. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Queries a file io stream for the given @attributes. + * This function blocks while querying the stream. For the asynchronous + * version of this function, see g_file_io_stream_query_info_async(). + * While the stream is blocked, the stream will set the pending flag + * internally, and any other operations on the stream will fail with + * %G_IO_ERROR_PENDING. + * + * Can fail if the stream was already closed (with @error being set to + * %G_IO_ERROR_CLOSED), the stream has pending operations (with @error being + * set to %G_IO_ERROR_PENDING), or if querying info is not supported for + * the stream's interface (with @error being set to %G_IO_ERROR_NOT_SUPPORTED). I + * all cases of failure, %NULL will be returned. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be set, and %NULL will + * be returned. + * + * Returns: (transfer full): a #GFileInfo for the @stream, or %NULL on error. + * + * Since: 2.22 + **/ +GFileInfo * +g_file_io_stream_query_info (GFileIOStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GFileIOStreamClass *class; + GIOStream *io_stream; + GFileInfo *info; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), NULL); + + io_stream = G_IO_STREAM (stream); + + if (!g_io_stream_set_pending (io_stream, error)) + return NULL; + + info = NULL; + + if (cancellable) + g_cancellable_push_current (cancellable); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + if (class->query_info) + info = class->query_info (stream, attributes, cancellable, error); + else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Stream doesn’t support query_info")); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_io_stream_clear_pending (io_stream); + + return info; +} + +static void +async_ready_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GFileIOStream *stream = G_FILE_IO_STREAM (source_object); + + g_io_stream_clear_pending (G_IO_STREAM (stream)); + if (stream->priv->outstanding_callback) + (*stream->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (stream); +} + +/** + * g_file_io_stream_query_info_async: + * @stream: a #GFileIOStream. + * @attributes: a file attribute query string. + * @io_priority: the [I/O priority][gio-GIOScheduler] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously queries the @stream for a #GFileInfo. When completed, + * @callback will be called with a #GAsyncResult which can be used to + * finish the operation with g_file_io_stream_query_info_finish(). + * + * For the synchronous version of this function, see + * g_file_io_stream_query_info(). + * + * Since: 2.22 + **/ +void +g_file_io_stream_query_info_async (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIOStreamClass *klass; + GIOStream *io_stream; + GError *error = NULL; + + g_return_if_fail (G_IS_FILE_IO_STREAM (stream)); + + io_stream = G_IO_STREAM (stream); + + if (!g_io_stream_set_pending (io_stream, &error)) + { + g_task_report_error (stream, callback, user_data, + g_file_io_stream_query_info_async, + error); + return; + } + + klass = G_FILE_IO_STREAM_GET_CLASS (stream); + + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + klass->query_info_async (stream, attributes, io_priority, cancellable, + async_ready_callback_wrapper, user_data); +} + +/** + * g_file_io_stream_query_info_finish: + * @stream: a #GFileIOStream. + * @result: a #GAsyncResult. + * @error: a #GError, %NULL to ignore. + * + * Finalizes the asynchronous query started + * by g_file_io_stream_query_info_async(). + * + * Returns: (transfer full): A #GFileInfo for the finished query. + * + * Since: 2.22 + **/ +GFileInfo * +g_file_io_stream_query_info_finish (GFileIOStream *stream, + GAsyncResult *result, + GError **error) +{ + GFileIOStreamClass *class; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + else if (g_async_result_is_tagged (result, g_file_io_stream_query_info_async)) + return g_task_propagate_pointer (G_TASK (result), error); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + return class->query_info_finish (stream, result, error); +} + +/** + * g_file_io_stream_get_etag: + * @stream: a #GFileIOStream. + * + * Gets the entity tag for the file when it has been written. + * This must be called after the stream has been written + * and closed, as the etag can change while writing. + * + * Returns: (nullable) (transfer full): the entity tag for the stream. + * + * Since: 2.22 + **/ +char * +g_file_io_stream_get_etag (GFileIOStream *stream) +{ + GFileIOStreamClass *class; + GIOStream *io_stream; + char *etag; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), NULL); + + io_stream = G_IO_STREAM (stream); + + if (!g_io_stream_is_closed (io_stream)) + { + g_warning ("stream is not closed yet, can't get etag"); + return NULL; + } + + etag = NULL; + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + if (class->get_etag) + etag = class->get_etag (stream); + + return etag; +} + +static goffset +g_file_io_stream_tell (GFileIOStream *stream) +{ + GFileIOStreamClass *class; + goffset offset; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), 0); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + offset = 0; + if (class->tell) + offset = class->tell (stream); + + return offset; +} + +static goffset +g_file_io_stream_seekable_tell (GSeekable *seekable) +{ + return g_file_io_stream_tell (G_FILE_IO_STREAM (seekable)); +} + +static gboolean +g_file_io_stream_can_seek (GFileIOStream *stream) +{ + GFileIOStreamClass *class; + gboolean can_seek; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), FALSE); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + can_seek = FALSE; + if (class->seek) + { + can_seek = TRUE; + if (class->can_seek) + can_seek = class->can_seek (stream); + } + + return can_seek; +} + +static gboolean +g_file_io_stream_seekable_can_seek (GSeekable *seekable) +{ + return g_file_io_stream_can_seek (G_FILE_IO_STREAM (seekable)); +} + +static gboolean +g_file_io_stream_seek (GFileIOStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GFileIOStreamClass *class; + GIOStream *io_stream; + gboolean res; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), FALSE); + + io_stream = G_IO_STREAM (stream); + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + if (!class->seek) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Seek not supported on stream")); + return FALSE; + } + + if (!g_io_stream_set_pending (io_stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->seek (stream, offset, type, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_io_stream_clear_pending (io_stream); + + return res; +} + +static gboolean +g_file_io_stream_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + return g_file_io_stream_seek (G_FILE_IO_STREAM (seekable), + offset, type, cancellable, error); +} + +static gboolean +g_file_io_stream_can_truncate (GFileIOStream *stream) +{ + GFileIOStreamClass *class; + gboolean can_truncate; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), FALSE); + + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + can_truncate = FALSE; + if (class->truncate_fn) + { + can_truncate = TRUE; + if (class->can_truncate) + can_truncate = class->can_truncate (stream); + } + + return can_truncate; +} + +static gboolean +g_file_io_stream_seekable_can_truncate (GSeekable *seekable) +{ + return g_file_io_stream_can_truncate (G_FILE_IO_STREAM (seekable)); +} + +static gboolean +g_file_io_stream_truncate (GFileIOStream *stream, + goffset size, + GCancellable *cancellable, + GError **error) +{ + GFileIOStreamClass *class; + GIOStream *io_stream; + gboolean res; + + g_return_val_if_fail (G_IS_FILE_IO_STREAM (stream), FALSE); + + io_stream = G_IO_STREAM (stream); + class = G_FILE_IO_STREAM_GET_CLASS (stream); + + if (!class->truncate_fn) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Truncate not supported on stream")); + return FALSE; + } + + if (!g_io_stream_set_pending (io_stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->truncate_fn (stream, size, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_io_stream_clear_pending (io_stream); + + return res; +} + +static gboolean +g_file_io_stream_seekable_truncate (GSeekable *seekable, + goffset size, + GCancellable *cancellable, + GError **error) +{ + return g_file_io_stream_truncate (G_FILE_IO_STREAM (seekable), + size, cancellable, error); +} +/***************************************************** + * Default implementations based on output stream * + *****************************************************/ + +static goffset +g_file_io_stream_real_tell (GFileIOStream *stream) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_tell (seekable); +} + +static gboolean +g_file_io_stream_real_can_seek (GFileIOStream *stream) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_can_seek (seekable); +} + +static gboolean +g_file_io_stream_real_seek (GFileIOStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_seek (seekable, offset, type, cancellable, error); +} + +static gboolean +g_file_io_stream_real_can_truncate (GFileIOStream *stream) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_can_truncate (seekable); +} + +static gboolean +g_file_io_stream_real_truncate_fn (GFileIOStream *stream, + goffset size, + GCancellable *cancellable, + GError **error) +{ + GOutputStream *out; + GSeekable *seekable; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + seekable = G_SEEKABLE (out); + + return g_seekable_truncate (seekable, size, cancellable, error); +} + +static char * +g_file_io_stream_real_get_etag (GFileIOStream *stream) +{ + GOutputStream *out; + GFileOutputStream *file_out; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + file_out = G_FILE_OUTPUT_STREAM (out); + + return g_file_output_stream_get_etag (file_out); +} + +static GFileInfo * +g_file_io_stream_real_query_info (GFileIOStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GOutputStream *out; + GFileOutputStream *file_out; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + file_out = G_FILE_OUTPUT_STREAM (out); + + return g_file_output_stream_query_info (file_out, + attributes, cancellable, error); +} + +typedef struct { + GObject *object; + GAsyncReadyCallback callback; + gpointer user_data; +} AsyncOpWrapper; + +static AsyncOpWrapper * +async_op_wrapper_new (gpointer object, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AsyncOpWrapper *data; + + data = g_new0 (AsyncOpWrapper, 1); + data->object = g_object_ref (object); + data->callback = callback; + data->user_data = user_data; + + return data; +} + +static void +async_op_wrapper_callback (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + AsyncOpWrapper *data = user_data; + data->callback (data->object, res, data->user_data); + g_object_unref (data->object); + g_free (data); +} + +static void +g_file_io_stream_real_query_info_async (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GOutputStream *out; + GFileOutputStream *file_out; + AsyncOpWrapper *data; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + file_out = G_FILE_OUTPUT_STREAM (out); + + data = async_op_wrapper_new (stream, callback, user_data); + g_file_output_stream_query_info_async (file_out, + attributes, io_priority, + cancellable, async_op_wrapper_callback, data); +} + +static GFileInfo * +g_file_io_stream_real_query_info_finish (GFileIOStream *stream, + GAsyncResult *res, + GError **error) +{ + GOutputStream *out; + GFileOutputStream *file_out; + + out = g_io_stream_get_output_stream (G_IO_STREAM (stream)); + file_out = G_FILE_OUTPUT_STREAM (out); + + return g_file_output_stream_query_info_finish (file_out, res, error); +} + +static void +g_file_io_stream_class_init (GFileIOStreamClass *klass) +{ + klass->tell = g_file_io_stream_real_tell; + klass->can_seek = g_file_io_stream_real_can_seek; + klass->seek = g_file_io_stream_real_seek; + klass->can_truncate = g_file_io_stream_real_can_truncate; + klass->truncate_fn = g_file_io_stream_real_truncate_fn; + klass->query_info = g_file_io_stream_real_query_info; + klass->query_info_async = g_file_io_stream_real_query_info_async; + klass->query_info_finish = g_file_io_stream_real_query_info_finish; + klass->get_etag = g_file_io_stream_real_get_etag; +} diff --git a/gio/gfileiostream.h b/gio/gfileiostream.h new file mode 100644 index 0000000..ca61db6 --- /dev/null +++ b/gio/gfileiostream.h @@ -0,0 +1,121 @@ +/* GIO - GLib Input, Io and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_IO_STREAM_H__ +#define __G_FILE_IO_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_IO_STREAM (g_file_io_stream_get_type ()) +#define G_FILE_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_IO_STREAM, GFileIOStream)) +#define G_FILE_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_IO_STREAM, GFileIOStreamClass)) +#define G_IS_FILE_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_IO_STREAM)) +#define G_IS_FILE_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_IO_STREAM)) +#define G_FILE_IO_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_IO_STREAM, GFileIOStreamClass)) + +/** + * GFileIOStream: + * + * A subclass of GIOStream for opened files. This adds + * a few file-specific operations and seeking and truncating. + * + * #GFileIOStream implements GSeekable. + **/ +typedef struct _GFileIOStreamClass GFileIOStreamClass; +typedef struct _GFileIOStreamPrivate GFileIOStreamPrivate; + +struct _GFileIOStream +{ + GIOStream parent_instance; + + /*< private >*/ + GFileIOStreamPrivate *priv; +}; + +struct _GFileIOStreamClass +{ + GIOStreamClass parent_class; + + goffset (* tell) (GFileIOStream *stream); + gboolean (* can_seek) (GFileIOStream *stream); + gboolean (* seek) (GFileIOStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); + gboolean (* can_truncate) (GFileIOStream *stream); + gboolean (* truncate_fn) (GFileIOStream *stream, + goffset size, + GCancellable *cancellable, + GError **error); + GFileInfo * (* query_info) (GFileIOStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); + void (* query_info_async) (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileInfo * (* query_info_finish) (GFileIOStream *stream, + GAsyncResult *result, + GError **error); + char * (* get_etag) (GFileIOStream *stream); + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_file_io_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_file_io_stream_query_info (GFileIOStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_io_stream_query_info_async (GFileIOStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_file_io_stream_query_info_finish (GFileIOStream *stream, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +char * g_file_io_stream_get_etag (GFileIOStream *stream); + +G_END_DECLS + +#endif /* __G_FILE_FILE_IO_STREAM_H__ */ diff --git a/gio/gfilemonitor.c b/gio/gfilemonitor.c new file mode 100644 index 0000000..89c89d2 --- /dev/null +++ b/gio/gfilemonitor.c @@ -0,0 +1,295 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include + +#include "gfilemonitor.h" +#include "gioenumtypes.h" +#include "gmarshal-internal.h" +#include "gfile.h" +#include "gvfs.h" +#include "glibintl.h" + +/** + * SECTION:gfilemonitor + * @short_description: File Monitor + * @include: gio/gio.h + * + * Monitors a file or directory for changes. + * + * To obtain a #GFileMonitor for a file or directory, use + * g_file_monitor(), g_file_monitor_file(), or + * g_file_monitor_directory(). + * + * To get informed about changes to the file or directory you are + * monitoring, connect to the #GFileMonitor::changed signal. The + * signal will be emitted in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread that the monitor was created in + * (though if the global default main context is blocked, this may + * cause notifications to be blocked even if the thread-default + * context is still running). + **/ + +#define DEFAULT_RATE_LIMIT_MSECS 800 + +struct _GFileMonitorPrivate +{ + gboolean cancelled; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GFileMonitor, g_file_monitor, G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_RATE_LIMIT, + PROP_CANCELLED +}; + +static guint g_file_monitor_changed_signal; + +static void +g_file_monitor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + //GFileMonitor *monitor; + + //monitor = G_FILE_MONITOR (object); + + switch (prop_id) + { + case PROP_RATE_LIMIT: + /* not supported by default */ + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_file_monitor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_RATE_LIMIT: + /* we expect this to be overridden... */ + g_value_set_int (value, DEFAULT_RATE_LIMIT_MSECS); + break; + + case PROP_CANCELLED: + //g_mutex_lock (&fms->lock); + g_value_set_boolean (value, FALSE);//fms->cancelled); + //g_mutex_unlock (&fms->lock); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_file_monitor_dispose (GObject *object) +{ + GFileMonitor *monitor = G_FILE_MONITOR (object); + + /* Make sure we cancel on last unref */ + g_file_monitor_cancel (monitor); + + G_OBJECT_CLASS (g_file_monitor_parent_class)->dispose (object); +} + +static void +g_file_monitor_init (GFileMonitor *monitor) +{ + monitor->priv = g_file_monitor_get_instance_private (monitor); +} + +static void +g_file_monitor_class_init (GFileMonitorClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = g_file_monitor_dispose; + object_class->get_property = g_file_monitor_get_property; + object_class->set_property = g_file_monitor_set_property; + + /** + * GFileMonitor::changed: + * @monitor: a #GFileMonitor. + * @file: a #GFile. + * @other_file: (nullable): a #GFile or #NULL. + * @event_type: a #GFileMonitorEvent. + * + * Emitted when @file has been changed. + * + * If using %G_FILE_MONITOR_WATCH_MOVES on a directory monitor, and + * the information is available (and if supported by the backend), + * @event_type may be %G_FILE_MONITOR_EVENT_RENAMED, + * %G_FILE_MONITOR_EVENT_MOVED_IN or %G_FILE_MONITOR_EVENT_MOVED_OUT. + * + * In all cases @file will be a child of the monitored directory. For + * renames, @file will be the old name and @other_file is the new + * name. For "moved in" events, @file is the name of the file that + * appeared and @other_file is the old name that it was moved from (in + * another directory). For "moved out" events, @file is the name of + * the file that used to be in this directory and @other_file is the + * name of the file at its new location. + * + * It makes sense to treat %G_FILE_MONITOR_EVENT_MOVED_IN as + * equivalent to %G_FILE_MONITOR_EVENT_CREATED and + * %G_FILE_MONITOR_EVENT_MOVED_OUT as equivalent to + * %G_FILE_MONITOR_EVENT_DELETED, with extra information. + * %G_FILE_MONITOR_EVENT_RENAMED is equivalent to a delete/create + * pair. This is exactly how the events will be reported in the case + * that the %G_FILE_MONITOR_WATCH_MOVES flag is not in use. + * + * If using the deprecated flag %G_FILE_MONITOR_SEND_MOVED flag and @event_type is + * %G_FILE_MONITOR_EVENT_MOVED, @file will be set to a #GFile containing the + * old path, and @other_file will be set to a #GFile containing the new path. + * + * In all the other cases, @other_file will be set to #NULL. + **/ + g_file_monitor_changed_signal = g_signal_new (I_("changed"), + G_TYPE_FILE_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GFileMonitorClass, changed), + NULL, NULL, + _g_cclosure_marshal_VOID__OBJECT_OBJECT_ENUM, + G_TYPE_NONE, 3, + G_TYPE_FILE, G_TYPE_FILE, G_TYPE_FILE_MONITOR_EVENT); + g_signal_set_va_marshaller (g_file_monitor_changed_signal, + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_VOID__OBJECT_OBJECT_ENUMv); + + g_object_class_install_property (object_class, PROP_RATE_LIMIT, + g_param_spec_int ("rate-limit", + P_("Rate limit"), + P_("The limit of the monitor to watch for changes, in milliseconds"), + 0, G_MAXINT, DEFAULT_RATE_LIMIT_MSECS, G_PARAM_READWRITE | + G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_CANCELLED, + g_param_spec_boolean ("cancelled", + P_("Cancelled"), + P_("Whether the monitor has been cancelled"), + FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); +} + +/** + * g_file_monitor_is_cancelled: + * @monitor: a #GFileMonitor + * + * Returns whether the monitor is canceled. + * + * Returns: %TRUE if monitor is canceled. %FALSE otherwise. + **/ +gboolean +g_file_monitor_is_cancelled (GFileMonitor *monitor) +{ + gboolean res; + + g_return_val_if_fail (G_IS_FILE_MONITOR (monitor), FALSE); + + res = monitor->priv->cancelled; + + return res; +} + +/** + * g_file_monitor_cancel: + * @monitor: a #GFileMonitor. + * + * Cancels a file monitor. + * + * Returns: always %TRUE + **/ +gboolean +g_file_monitor_cancel (GFileMonitor *monitor) +{ + g_return_val_if_fail (G_IS_FILE_MONITOR (monitor), FALSE); + + if (!monitor->priv->cancelled) + { + G_FILE_MONITOR_GET_CLASS (monitor)->cancel (monitor); + + monitor->priv->cancelled = TRUE; + g_object_notify (G_OBJECT (monitor), "cancelled"); + } + + return TRUE; +} + +/** + * g_file_monitor_set_rate_limit: + * @monitor: a #GFileMonitor. + * @limit_msecs: a non-negative integer with the limit in milliseconds + * to poll for changes + * + * Sets the rate limit to which the @monitor will report + * consecutive change events to the same file. + */ +void +g_file_monitor_set_rate_limit (GFileMonitor *monitor, + gint limit_msecs) +{ + g_object_set (monitor, "rate-limit", limit_msecs, NULL); +} + +/** + * g_file_monitor_emit_event: + * @monitor: a #GFileMonitor. + * @child: a #GFile. + * @other_file: a #GFile. + * @event_type: a set of #GFileMonitorEvent flags. + * + * Emits the #GFileMonitor::changed signal if a change + * has taken place. Should be called from file monitor + * implementations only. + * + * Implementations are responsible to call this method from the + * [thread-default main context][g-main-context-push-thread-default] of the + * thread that the monitor was created in. + **/ +void +g_file_monitor_emit_event (GFileMonitor *monitor, + GFile *child, + GFile *other_file, + GFileMonitorEvent event_type) +{ + g_return_if_fail (G_IS_FILE_MONITOR (monitor)); + g_return_if_fail (G_IS_FILE (child)); + g_return_if_fail (!other_file || G_IS_FILE (other_file)); + + if (monitor->priv->cancelled) + return; + + g_signal_emit (monitor, g_file_monitor_changed_signal, 0, child, other_file, event_type); +} diff --git a/gio/gfilemonitor.h b/gio/gfilemonitor.h new file mode 100644 index 0000000..724d8de --- /dev/null +++ b/gio/gfilemonitor.h @@ -0,0 +1,98 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_MONITOR_H__ +#define __G_FILE_MONITOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_MONITOR (g_file_monitor_get_type ()) +#define G_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_MONITOR, GFileMonitor)) +#define G_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_MONITOR, GFileMonitorClass)) +#define G_IS_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_MONITOR)) +#define G_IS_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_MONITOR)) +#define G_FILE_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_MONITOR, GFileMonitorClass)) + +typedef struct _GFileMonitorClass GFileMonitorClass; +typedef struct _GFileMonitorPrivate GFileMonitorPrivate; + +/** + * GFileMonitor: + * + * Watches for changes to a file. + **/ +struct _GFileMonitor +{ + GObject parent_instance; + + /*< private >*/ + GFileMonitorPrivate *priv; +}; + +struct _GFileMonitorClass +{ + GObjectClass parent_class; + + /* Signals */ + void (* changed) (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type); + + /* Virtual Table */ + gboolean (* cancel) (GFileMonitor *monitor); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_file_monitor_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gboolean g_file_monitor_cancel (GFileMonitor *monitor); +GLIB_AVAILABLE_IN_ALL +gboolean g_file_monitor_is_cancelled (GFileMonitor *monitor); +GLIB_AVAILABLE_IN_ALL +void g_file_monitor_set_rate_limit (GFileMonitor *monitor, + gint limit_msecs); + + +/* For implementations */ +GLIB_AVAILABLE_IN_ALL +void g_file_monitor_emit_event (GFileMonitor *monitor, + GFile *child, + GFile *other_file, + GFileMonitorEvent event_type); + +G_END_DECLS + +#endif /* __G_FILE_MONITOR_H__ */ diff --git a/gio/gfilenamecompleter.c b/gio/gfilenamecompleter.c new file mode 100644 index 0000000..a290c03 --- /dev/null +++ b/gio/gfilenamecompleter.c @@ -0,0 +1,510 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "gfilenamecompleter.h" +#include "gfileenumerator.h" +#include "gfileattribute.h" +#include "gfile.h" +#include "gfileinfo.h" +#include "gcancellable.h" +#include +#include "glibintl.h" + + +/** + * SECTION:gfilenamecompleter + * @short_description: Filename Completer + * @include: gio/gio.h + * + * Completes partial file and directory names given a partial string by + * looking in the file system for clues. Can return a list of possible + * completion strings for widget implementations. + * + **/ + +enum { + GOT_COMPLETION_DATA, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +typedef struct { + GFilenameCompleter *completer; + GFileEnumerator *enumerator; + GCancellable *cancellable; + gboolean should_escape; + GFile *dir; + GList *basenames; + gboolean dirs_only; +} LoadBasenamesData; + +struct _GFilenameCompleter { + GObject parent; + + GFile *basenames_dir; + gboolean basenames_are_escaped; + gboolean dirs_only; + GList *basenames; + + LoadBasenamesData *basename_loader; +}; + +G_DEFINE_TYPE (GFilenameCompleter, g_filename_completer, G_TYPE_OBJECT) + +static void cancel_load_basenames (GFilenameCompleter *completer); + +static void +g_filename_completer_finalize (GObject *object) +{ + GFilenameCompleter *completer; + + completer = G_FILENAME_COMPLETER (object); + + cancel_load_basenames (completer); + + if (completer->basenames_dir) + g_object_unref (completer->basenames_dir); + + g_list_free_full (completer->basenames, g_free); + + G_OBJECT_CLASS (g_filename_completer_parent_class)->finalize (object); +} + +static void +g_filename_completer_class_init (GFilenameCompleterClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_filename_completer_finalize; + /** + * GFilenameCompleter::got-completion-data: + * + * Emitted when the file name completion information comes available. + **/ + signals[GOT_COMPLETION_DATA] = g_signal_new (I_("got-completion-data"), + G_TYPE_FILENAME_COMPLETER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GFilenameCompleterClass, got_completion_data), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); +} + +static void +g_filename_completer_init (GFilenameCompleter *completer) +{ +} + +/** + * g_filename_completer_new: + * + * Creates a new filename completer. + * + * Returns: a #GFilenameCompleter. + **/ +GFilenameCompleter * +g_filename_completer_new (void) +{ + return g_object_new (G_TYPE_FILENAME_COMPLETER, NULL); +} + +static char * +longest_common_prefix (char *a, char *b) +{ + char *start; + + start = a; + + while (g_utf8_get_char (a) == g_utf8_get_char (b)) + { + a = g_utf8_next_char (a); + b = g_utf8_next_char (b); + } + + return g_strndup (start, a - start); +} + +static void +load_basenames_data_free (LoadBasenamesData *data) +{ + if (data->enumerator) + g_object_unref (data->enumerator); + + g_object_unref (data->cancellable); + g_object_unref (data->dir); + + g_list_free_full (data->basenames, g_free); + + g_free (data); +} + +static void +got_more_files (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + LoadBasenamesData *data = user_data; + GList *infos, *l; + GFileInfo *info; + const char *name; + gboolean append_slash; + char *t; + char *basename; + + if (data->completer == NULL) + { + /* Was cancelled */ + load_basenames_data_free (data); + return; + } + + infos = g_file_enumerator_next_files_finish (data->enumerator, res, NULL); + + for (l = infos; l != NULL; l = l->next) + { + info = l->data; + + if (data->dirs_only && + g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY) + { + g_object_unref (info); + continue; + } + + append_slash = g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY; + name = g_file_info_get_name (info); + if (name == NULL) + { + g_object_unref (info); + continue; + } + + + if (data->should_escape) + basename = g_uri_escape_string (name, + G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, + TRUE); + else + /* If not should_escape, must be a local filename, convert to utf8 */ + basename = g_filename_to_utf8 (name, -1, NULL, NULL, NULL); + + if (basename) + { + if (append_slash) + { + t = basename; + basename = g_strconcat (basename, "/", NULL); + g_free (t); + } + + data->basenames = g_list_prepend (data->basenames, basename); + } + + g_object_unref (info); + } + + g_list_free (infos); + + if (infos) + { + /* Not last, get more files */ + g_file_enumerator_next_files_async (data->enumerator, + 100, + 0, + data->cancellable, + got_more_files, data); + } + else + { + data->completer->basename_loader = NULL; + + if (data->completer->basenames_dir) + g_object_unref (data->completer->basenames_dir); + g_list_free_full (data->completer->basenames, g_free); + + data->completer->basenames_dir = g_object_ref (data->dir); + data->completer->basenames = data->basenames; + data->completer->basenames_are_escaped = data->should_escape; + data->basenames = NULL; + + g_file_enumerator_close_async (data->enumerator, 0, NULL, NULL, NULL); + + g_signal_emit (data->completer, signals[GOT_COMPLETION_DATA], 0); + load_basenames_data_free (data); + } +} + + +static void +got_enum (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + LoadBasenamesData *data = user_data; + + if (data->completer == NULL) + { + /* Was cancelled */ + load_basenames_data_free (data); + return; + } + + data->enumerator = g_file_enumerate_children_finish (G_FILE (source_object), res, NULL); + + if (data->enumerator == NULL) + { + data->completer->basename_loader = NULL; + + if (data->completer->basenames_dir) + g_object_unref (data->completer->basenames_dir); + g_list_free_full (data->completer->basenames, g_free); + + /* Mark up-to-date with no basenames */ + data->completer->basenames_dir = g_object_ref (data->dir); + data->completer->basenames = NULL; + data->completer->basenames_are_escaped = data->should_escape; + + load_basenames_data_free (data); + return; + } + + g_file_enumerator_next_files_async (data->enumerator, + 100, + 0, + data->cancellable, + got_more_files, data); +} + +static void +schedule_load_basenames (GFilenameCompleter *completer, + GFile *dir, + gboolean should_escape) +{ + LoadBasenamesData *data; + + cancel_load_basenames (completer); + + data = g_new0 (LoadBasenamesData, 1); + data->completer = completer; + data->cancellable = g_cancellable_new (); + data->dir = g_object_ref (dir); + data->should_escape = should_escape; + data->dirs_only = completer->dirs_only; + + completer->basename_loader = data; + + g_file_enumerate_children_async (dir, + G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE, + 0, 0, + data->cancellable, + got_enum, data); +} + +static void +cancel_load_basenames (GFilenameCompleter *completer) +{ + LoadBasenamesData *loader; + + if (completer->basename_loader) + { + loader = completer->basename_loader; + loader->completer = NULL; + + g_cancellable_cancel (loader->cancellable); + + completer->basename_loader = NULL; + } +} + + +/* Returns a list of possible matches and the basename to use for it */ +static GList * +init_completion (GFilenameCompleter *completer, + const char *initial_text, + char **basename_out) +{ + gboolean should_escape; + GFile *file, *parent; + char *basename; + char *t; + int len; + + *basename_out = NULL; + + should_escape = ! (g_path_is_absolute (initial_text) || *initial_text == '~'); + + len = strlen (initial_text); + + if (len > 0 && + initial_text[len - 1] == '/') + return NULL; + + file = g_file_parse_name (initial_text); + parent = g_file_get_parent (file); + if (parent == NULL) + { + g_object_unref (file); + return NULL; + } + + if (completer->basenames_dir == NULL || + completer->basenames_are_escaped != should_escape || + !g_file_equal (parent, completer->basenames_dir)) + { + schedule_load_basenames (completer, parent, should_escape); + g_object_unref (file); + return NULL; + } + + basename = g_file_get_basename (file); + if (should_escape) + { + t = basename; + basename = g_uri_escape_string (basename, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE); + g_free (t); + } + else + { + t = basename; + basename = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL); + g_free (t); + + if (basename == NULL) + return NULL; + } + + *basename_out = basename; + + return completer->basenames; +} + +/** + * g_filename_completer_get_completion_suffix: + * @completer: the filename completer. + * @initial_text: text to be completed. + * + * Obtains a completion for @initial_text from @completer. + * + * Returns: (nullable) (transfer full): a completed string, or %NULL if no + * completion exists. This string is not owned by GIO, so remember to g_free() + * it when finished. + **/ +char * +g_filename_completer_get_completion_suffix (GFilenameCompleter *completer, + const char *initial_text) +{ + GList *possible_matches, *l; + char *prefix; + char *suffix; + char *possible_match; + char *lcp; + + g_return_val_if_fail (G_IS_FILENAME_COMPLETER (completer), NULL); + g_return_val_if_fail (initial_text != NULL, NULL); + + possible_matches = init_completion (completer, initial_text, &prefix); + + suffix = NULL; + + for (l = possible_matches; l != NULL; l = l->next) + { + possible_match = l->data; + + if (g_str_has_prefix (possible_match, prefix)) + { + if (suffix == NULL) + suffix = g_strdup (possible_match + strlen (prefix)); + else + { + lcp = longest_common_prefix (suffix, + possible_match + strlen (prefix)); + g_free (suffix); + suffix = lcp; + + if (*suffix == 0) + break; + } + } + } + + g_free (prefix); + + return suffix; +} + +/** + * g_filename_completer_get_completions: + * @completer: the filename completer. + * @initial_text: text to be completed. + * + * Gets an array of completion strings for a given initial text. + * + * Returns: (array zero-terminated=1) (transfer full): array of strings with possible completions for @initial_text. + * This array must be freed by g_strfreev() when finished. + **/ +char ** +g_filename_completer_get_completions (GFilenameCompleter *completer, + const char *initial_text) +{ + GList *possible_matches, *l; + char *prefix; + char *possible_match; + GPtrArray *res; + + g_return_val_if_fail (G_IS_FILENAME_COMPLETER (completer), NULL); + g_return_val_if_fail (initial_text != NULL, NULL); + + possible_matches = init_completion (completer, initial_text, &prefix); + + res = g_ptr_array_new (); + for (l = possible_matches; l != NULL; l = l->next) + { + possible_match = l->data; + + if (g_str_has_prefix (possible_match, prefix)) + g_ptr_array_add (res, + g_strconcat (initial_text, possible_match + strlen (prefix), NULL)); + } + + g_free (prefix); + + g_ptr_array_add (res, NULL); + + return (char**)g_ptr_array_free (res, FALSE); +} + +/** + * g_filename_completer_set_dirs_only: + * @completer: the filename completer. + * @dirs_only: a #gboolean. + * + * If @dirs_only is %TRUE, @completer will only + * complete directory names, and not file names. + **/ +void +g_filename_completer_set_dirs_only (GFilenameCompleter *completer, + gboolean dirs_only) +{ + g_return_if_fail (G_IS_FILENAME_COMPLETER (completer)); + + completer->dirs_only = dirs_only; +} diff --git a/gio/gfilenamecompleter.h b/gio/gfilenamecompleter.h new file mode 100644 index 0000000..b10f18d --- /dev/null +++ b/gio/gfilenamecompleter.h @@ -0,0 +1,79 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILENAME_COMPLETER_H__ +#define __G_FILENAME_COMPLETER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILENAME_COMPLETER (g_filename_completer_get_type ()) +#define G_FILENAME_COMPLETER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILENAME_COMPLETER, GFilenameCompleter)) +#define G_FILENAME_COMPLETER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILENAME_COMPLETER, GFilenameCompleterClass)) +#define G_FILENAME_COMPLETER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILENAME_COMPLETER, GFilenameCompleterClass)) +#define G_IS_FILENAME_COMPLETER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILENAME_COMPLETER)) +#define G_IS_FILENAME_COMPLETER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILENAME_COMPLETER)) + +/** + * GFilenameCompleter: + * + * Completes filenames based on files that exist within the file system. + **/ +typedef struct _GFilenameCompleterClass GFilenameCompleterClass; + +struct _GFilenameCompleterClass +{ + GObjectClass parent_class; + + /*< public >*/ + /* signals */ + void (* got_completion_data) (GFilenameCompleter *filename_completer); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_filename_completer_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GFilenameCompleter *g_filename_completer_new (void); + +GLIB_AVAILABLE_IN_ALL +char * g_filename_completer_get_completion_suffix (GFilenameCompleter *completer, + const char *initial_text); +GLIB_AVAILABLE_IN_ALL +char ** g_filename_completer_get_completions (GFilenameCompleter *completer, + const char *initial_text); +GLIB_AVAILABLE_IN_ALL +void g_filename_completer_set_dirs_only (GFilenameCompleter *completer, + gboolean dirs_only); + +G_END_DECLS + +#endif /* __G_FILENAME_COMPLETER_H__ */ diff --git a/gio/gfileoutputstream.c b/gio/gfileoutputstream.c new file mode 100644 index 0000000..1dc536f --- /dev/null +++ b/gio/gfileoutputstream.c @@ -0,0 +1,532 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include "gasyncresult.h" +#include "gtask.h" +#include "gcancellable.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gfileoutputstream + * @short_description: File output streaming operations + * @include: gio/gio.h + * @see_also: #GOutputStream, #GDataOutputStream, #GSeekable + * + * GFileOutputStream provides output streams that write their + * content to a file. + * + * GFileOutputStream implements #GSeekable, which allows the output + * stream to jump to arbitrary positions in the file and to truncate + * the file, provided the filesystem of the file supports these + * operations. + * + * To find the position of a file output stream, use g_seekable_tell(). + * To find out if a file output stream supports seeking, use + * g_seekable_can_seek().To position a file output stream, use + * g_seekable_seek(). To find out if a file output stream supports + * truncating, use g_seekable_can_truncate(). To truncate a file output + * stream, use g_seekable_truncate(). + **/ + +static void g_file_output_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_file_output_stream_seekable_tell (GSeekable *seekable); +static gboolean g_file_output_stream_seekable_can_seek (GSeekable *seekable); +static gboolean g_file_output_stream_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_file_output_stream_seekable_can_truncate (GSeekable *seekable); +static gboolean g_file_output_stream_seekable_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); +static void g_file_output_stream_real_query_info_async (GFileOutputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileInfo *g_file_output_stream_real_query_info_finish (GFileOutputStream *stream, + GAsyncResult *result, + GError **error); + +struct _GFileOutputStreamPrivate { + GAsyncReadyCallback outstanding_callback; +}; + +G_DEFINE_TYPE_WITH_CODE (GFileOutputStream, g_file_output_stream, G_TYPE_OUTPUT_STREAM, + G_ADD_PRIVATE (GFileOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_file_output_stream_seekable_iface_init)); + +static void +g_file_output_stream_class_init (GFileOutputStreamClass *klass) +{ + klass->query_info_async = g_file_output_stream_real_query_info_async; + klass->query_info_finish = g_file_output_stream_real_query_info_finish; +} + +static void +g_file_output_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_file_output_stream_seekable_tell; + iface->can_seek = g_file_output_stream_seekable_can_seek; + iface->seek = g_file_output_stream_seekable_seek; + iface->can_truncate = g_file_output_stream_seekable_can_truncate; + iface->truncate_fn = g_file_output_stream_seekable_truncate; +} + +static void +g_file_output_stream_init (GFileOutputStream *stream) +{ + stream->priv = g_file_output_stream_get_instance_private (stream); +} + +/** + * g_file_output_stream_query_info: + * @stream: a #GFileOutputStream. + * @attributes: a file attribute query string. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @error: a #GError, %NULL to ignore. + * + * Queries a file output stream for the given @attributes. + * This function blocks while querying the stream. For the asynchronous + * version of this function, see g_file_output_stream_query_info_async(). + * While the stream is blocked, the stream will set the pending flag + * internally, and any other operations on the stream will fail with + * %G_IO_ERROR_PENDING. + * + * Can fail if the stream was already closed (with @error being set to + * %G_IO_ERROR_CLOSED), the stream has pending operations (with @error being + * set to %G_IO_ERROR_PENDING), or if querying info is not supported for + * the stream's interface (with @error being set to %G_IO_ERROR_NOT_SUPPORTED). In + * all cases of failure, %NULL will be returned. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be set, and %NULL will + * be returned. + * + * Returns: (transfer full): a #GFileInfo for the @stream, or %NULL on error. + **/ +GFileInfo * +g_file_output_stream_query_info (GFileOutputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStreamClass *class; + GOutputStream *output_stream; + GFileInfo *info; + + g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), NULL); + + output_stream = G_OUTPUT_STREAM (stream); + + if (!g_output_stream_set_pending (output_stream, error)) + return NULL; + + info = NULL; + + if (cancellable) + g_cancellable_push_current (cancellable); + + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + if (class->query_info) + info = class->query_info (stream, attributes, cancellable, error); + else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Stream doesn’t support query_info")); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_output_stream_clear_pending (output_stream); + + return info; +} + +static void +async_ready_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GFileOutputStream *stream = G_FILE_OUTPUT_STREAM (source_object); + + g_output_stream_clear_pending (G_OUTPUT_STREAM (stream)); + if (stream->priv->outstanding_callback) + (*stream->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (stream); +} + +/** + * g_file_output_stream_query_info_async: + * @stream: a #GFileOutputStream. + * @attributes: a file attribute query string. + * @io_priority: the [I/O priority][gio-GIOScheduler] of the request + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @callback: callback to call when the request is satisfied + * @user_data: the data to pass to callback function + * + * Asynchronously queries the @stream for a #GFileInfo. When completed, + * @callback will be called with a #GAsyncResult which can be used to + * finish the operation with g_file_output_stream_query_info_finish(). + * + * For the synchronous version of this function, see + * g_file_output_stream_query_info(). + * + **/ +void +g_file_output_stream_query_info_async (GFileOutputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileOutputStreamClass *klass; + GOutputStream *output_stream; + GError *error = NULL; + + g_return_if_fail (G_IS_FILE_OUTPUT_STREAM (stream)); + + output_stream = G_OUTPUT_STREAM (stream); + + if (!g_output_stream_set_pending (output_stream, &error)) + { + g_task_report_error (stream, callback, user_data, + g_file_output_stream_query_info_async, + error); + return; + } + + klass = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + klass->query_info_async (stream, attributes, io_priority, cancellable, + async_ready_callback_wrapper, user_data); +} + +/** + * g_file_output_stream_query_info_finish: + * @stream: a #GFileOutputStream. + * @result: a #GAsyncResult. + * @error: a #GError, %NULL to ignore. + * + * Finalizes the asynchronous query started + * by g_file_output_stream_query_info_async(). + * + * Returns: (transfer full): A #GFileInfo for the finished query. + **/ +GFileInfo * +g_file_output_stream_query_info_finish (GFileOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + GFileOutputStreamClass *class; + + g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + else if (g_async_result_is_tagged (result, g_file_output_stream_query_info_async)) + return g_task_propagate_pointer (G_TASK (result), error); + + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + return class->query_info_finish (stream, result, error); +} + +/** + * g_file_output_stream_get_etag: + * @stream: a #GFileOutputStream. + * + * Gets the entity tag for the file when it has been written. + * This must be called after the stream has been written + * and closed, as the etag can change while writing. + * + * Returns: (nullable) (transfer full): the entity tag for the stream. + **/ +char * +g_file_output_stream_get_etag (GFileOutputStream *stream) +{ + GFileOutputStreamClass *class; + GOutputStream *output_stream; + char *etag; + + g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), NULL); + + output_stream = G_OUTPUT_STREAM (stream); + + if (!g_output_stream_is_closed (output_stream)) + { + g_warning ("stream is not closed yet, can't get etag"); + return NULL; + } + + etag = NULL; + + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + if (class->get_etag) + etag = class->get_etag (stream); + + return etag; +} + +static goffset +g_file_output_stream_tell (GFileOutputStream *stream) +{ + GFileOutputStreamClass *class; + goffset offset; + + g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), 0); + + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + + offset = 0; + if (class->tell) + offset = class->tell (stream); + + return offset; +} + +static goffset +g_file_output_stream_seekable_tell (GSeekable *seekable) +{ + return g_file_output_stream_tell (G_FILE_OUTPUT_STREAM (seekable)); +} + +static gboolean +g_file_output_stream_can_seek (GFileOutputStream *stream) +{ + GFileOutputStreamClass *class; + gboolean can_seek; + + g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE); + + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + + can_seek = FALSE; + if (class->seek) + { + can_seek = TRUE; + if (class->can_seek) + can_seek = class->can_seek (stream); + } + + return can_seek; +} + +static gboolean +g_file_output_stream_seekable_can_seek (GSeekable *seekable) +{ + return g_file_output_stream_can_seek (G_FILE_OUTPUT_STREAM (seekable)); +} + +static gboolean +g_file_output_stream_seek (GFileOutputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStreamClass *class; + GOutputStream *output_stream; + gboolean res; + + g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE); + + output_stream = G_OUTPUT_STREAM (stream); + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + + if (!class->seek) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Seek not supported on stream")); + return FALSE; + } + + if (!g_output_stream_set_pending (output_stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->seek (stream, offset, type, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_output_stream_clear_pending (output_stream); + + return res; +} + +static gboolean +g_file_output_stream_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + return g_file_output_stream_seek (G_FILE_OUTPUT_STREAM (seekable), + offset, type, cancellable, error); +} + +static gboolean +g_file_output_stream_can_truncate (GFileOutputStream *stream) +{ + GFileOutputStreamClass *class; + gboolean can_truncate; + + g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE); + + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + + can_truncate = FALSE; + if (class->truncate_fn) + { + can_truncate = TRUE; + if (class->can_truncate) + can_truncate = class->can_truncate (stream); + } + + return can_truncate; +} + +static gboolean +g_file_output_stream_seekable_can_truncate (GSeekable *seekable) +{ + return g_file_output_stream_can_truncate (G_FILE_OUTPUT_STREAM (seekable)); +} + +static gboolean +g_file_output_stream_truncate (GFileOutputStream *stream, + goffset size, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStreamClass *class; + GOutputStream *output_stream; + gboolean res; + + g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE); + + output_stream = G_OUTPUT_STREAM (stream); + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + + if (!class->truncate_fn) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Truncate not supported on stream")); + return FALSE; + } + + if (!g_output_stream_set_pending (output_stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->truncate_fn (stream, size, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_output_stream_clear_pending (output_stream); + + return res; +} + +static gboolean +g_file_output_stream_seekable_truncate (GSeekable *seekable, + goffset size, + GCancellable *cancellable, + GError **error) +{ + return g_file_output_stream_truncate (G_FILE_OUTPUT_STREAM (seekable), + size, cancellable, error); +} +/******************************************** + * Default implementation of async ops * + ********************************************/ + +static void +query_info_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GFileOutputStream *stream = source_object; + const char *attributes = task_data; + GFileOutputStreamClass *class; + GError *error = NULL; + GFileInfo *info = NULL; + + class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream); + if (class->query_info) + info = class->query_info (stream, attributes, cancellable, &error); + else + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Stream doesn’t support query_info")); + + if (info == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, info, g_object_unref); +} + +static void +g_file_output_stream_real_query_info_async (GFileOutputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_file_output_stream_real_query_info_async); + g_task_set_task_data (task, g_strdup (attributes), g_free); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, query_info_async_thread); + g_object_unref (task); +} + +static GFileInfo * +g_file_output_stream_real_query_info_finish (GFileOutputStream *stream, + GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, stream), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} diff --git a/gio/gfileoutputstream.h b/gio/gfileoutputstream.h new file mode 100644 index 0000000..5df63ef --- /dev/null +++ b/gio/gfileoutputstream.h @@ -0,0 +1,122 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_FILE_OUTPUT_STREAM_H__ +#define __G_FILE_OUTPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILE_OUTPUT_STREAM (g_file_output_stream_get_type ()) +#define G_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_OUTPUT_STREAM, GFileOutputStream)) +#define G_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_OUTPUT_STREAM, GFileOutputStreamClass)) +#define G_IS_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_OUTPUT_STREAM)) +#define G_IS_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_OUTPUT_STREAM)) +#define G_FILE_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_OUTPUT_STREAM, GFileOutputStreamClass)) + +/** + * GFileOutputStream: + * + * A subclass of GOutputStream for opened files. This adds + * a few file-specific operations and seeking and truncating. + * + * #GFileOutputStream implements GSeekable. + **/ +typedef struct _GFileOutputStreamClass GFileOutputStreamClass; +typedef struct _GFileOutputStreamPrivate GFileOutputStreamPrivate; + +struct _GFileOutputStream +{ + GOutputStream parent_instance; + + /*< private >*/ + GFileOutputStreamPrivate *priv; +}; + +struct _GFileOutputStreamClass +{ + GOutputStreamClass parent_class; + + goffset (* tell) (GFileOutputStream *stream); + gboolean (* can_seek) (GFileOutputStream *stream); + gboolean (* seek) (GFileOutputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); + gboolean (* can_truncate) (GFileOutputStream *stream); + gboolean (* truncate_fn) (GFileOutputStream *stream, + goffset size, + GCancellable *cancellable, + GError **error); + GFileInfo * (* query_info) (GFileOutputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); + void (* query_info_async) (GFileOutputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileInfo * (* query_info_finish) (GFileOutputStream *stream, + GAsyncResult *result, + GError **error); + char * (* get_etag) (GFileOutputStream *stream); + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_file_output_stream_get_type (void) G_GNUC_CONST; + + +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_file_output_stream_query_info (GFileOutputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_file_output_stream_query_info_async (GFileOutputStream *stream, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_file_output_stream_query_info_finish (GFileOutputStream *stream, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +char * g_file_output_stream_get_etag (GFileOutputStream *stream); + +G_END_DECLS + +#endif /* __G_FILE_FILE_OUTPUT_STREAM_H__ */ diff --git a/gio/gfilterinputstream.c b/gio/gfilterinputstream.c new file mode 100644 index 0000000..05e511c --- /dev/null +++ b/gio/gfilterinputstream.c @@ -0,0 +1,309 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#include "config.h" +#include "gfilterinputstream.h" +#include "ginputstream.h" +#include "glibintl.h" + + +/** + * SECTION:gfilterinputstream + * @short_description: Filter Input Stream + * @include: gio/gio.h + * + * Base class for input stream implementations that perform some + * kind of filtering operation on a base stream. Typical examples + * of filtering operations are character set conversion, compression + * and byte order flipping. + **/ + +enum { + PROP_0, + PROP_BASE_STREAM, + PROP_CLOSE_BASE +}; + +static void g_filter_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static void g_filter_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void g_filter_input_stream_finalize (GObject *object); + + +static gssize g_filter_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gssize g_filter_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_filter_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error); + +typedef struct +{ + gboolean close_base; +} GFilterInputStreamPrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GFilterInputStream, g_filter_input_stream, G_TYPE_INPUT_STREAM) + +static void +g_filter_input_stream_class_init (GFilterInputStreamClass *klass) +{ + GObjectClass *object_class; + GInputStreamClass *istream_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = g_filter_input_stream_get_property; + object_class->set_property = g_filter_input_stream_set_property; + object_class->finalize = g_filter_input_stream_finalize; + + istream_class = G_INPUT_STREAM_CLASS (klass); + istream_class->read_fn = g_filter_input_stream_read; + istream_class->skip = g_filter_input_stream_skip; + istream_class->close_fn = g_filter_input_stream_close; + + g_object_class_install_property (object_class, + PROP_BASE_STREAM, + g_param_spec_object ("base-stream", + P_("The Filter Base Stream"), + P_("The underlying base stream on which the io ops will be done."), + G_TYPE_INPUT_STREAM, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (object_class, + PROP_CLOSE_BASE, + g_param_spec_boolean ("close-base-stream", + P_("Close Base Stream"), + P_("If the base stream should be closed when the filter stream is closed."), + TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); +} + +static void +g_filter_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GFilterInputStream *filter_stream; + GObject *obj; + + filter_stream = G_FILTER_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_BASE_STREAM: + obj = g_value_dup_object (value); + filter_stream->base_stream = G_INPUT_STREAM (obj); + break; + + case PROP_CLOSE_BASE: + g_filter_input_stream_set_close_base_stream (filter_stream, + g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_filter_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GFilterInputStream *filter_stream; + GFilterInputStreamPrivate *priv; + + filter_stream = G_FILTER_INPUT_STREAM (object); + priv = g_filter_input_stream_get_instance_private (filter_stream); + + switch (prop_id) + { + case PROP_BASE_STREAM: + g_value_set_object (value, filter_stream->base_stream); + break; + + case PROP_CLOSE_BASE: + g_value_set_boolean (value, priv->close_base); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_filter_input_stream_finalize (GObject *object) +{ + GFilterInputStream *stream; + + stream = G_FILTER_INPUT_STREAM (object); + + g_object_unref (stream->base_stream); + + G_OBJECT_CLASS (g_filter_input_stream_parent_class)->finalize (object); +} + +static void +g_filter_input_stream_init (GFilterInputStream *stream) +{ +} + +/** + * g_filter_input_stream_get_base_stream: + * @stream: a #GFilterInputStream. + * + * Gets the base stream for the filter stream. + * + * Returns: (transfer none): a #GInputStream. + **/ +GInputStream * +g_filter_input_stream_get_base_stream (GFilterInputStream *stream) +{ + g_return_val_if_fail (G_IS_FILTER_INPUT_STREAM (stream), NULL); + + return stream->base_stream; +} + +/** + * g_filter_input_stream_get_close_base_stream: + * @stream: a #GFilterInputStream. + * + * Returns whether the base stream will be closed when @stream is + * closed. + * + * Returns: %TRUE if the base stream will be closed. + **/ +gboolean +g_filter_input_stream_get_close_base_stream (GFilterInputStream *stream) +{ + GFilterInputStreamPrivate *priv; + + g_return_val_if_fail (G_IS_FILTER_INPUT_STREAM (stream), FALSE); + + priv = g_filter_input_stream_get_instance_private (stream); + + return priv->close_base; +} + +/** + * g_filter_input_stream_set_close_base_stream: + * @stream: a #GFilterInputStream. + * @close_base: %TRUE to close the base stream. + * + * Sets whether the base stream will be closed when @stream is closed. + **/ +void +g_filter_input_stream_set_close_base_stream (GFilterInputStream *stream, + gboolean close_base) +{ + GFilterInputStreamPrivate *priv; + + g_return_if_fail (G_IS_FILTER_INPUT_STREAM (stream)); + + close_base = !!close_base; + + priv = g_filter_input_stream_get_instance_private (stream); + + if (priv->close_base != close_base) + { + priv->close_base = close_base; + g_object_notify (G_OBJECT (stream), "close-base-stream"); + } +} + +static gssize +g_filter_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GFilterInputStream *filter_stream; + GInputStream *base_stream; + gssize nread; + + filter_stream = G_FILTER_INPUT_STREAM (stream); + base_stream = filter_stream->base_stream; + + nread = g_input_stream_read (base_stream, + buffer, + count, + cancellable, + error); + + return nread; +} + +static gssize +g_filter_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GFilterInputStream *filter_stream; + GInputStream *base_stream; + gssize nskipped; + + filter_stream = G_FILTER_INPUT_STREAM (stream); + base_stream = filter_stream->base_stream; + + nskipped = g_input_stream_skip (base_stream, + count, + cancellable, + error); + return nskipped; +} + +static gboolean +g_filter_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GFilterInputStream *filter_stream = G_FILTER_INPUT_STREAM (stream); + GFilterInputStreamPrivate *priv = g_filter_input_stream_get_instance_private (filter_stream); + gboolean res = TRUE; + + if (priv->close_base) + { + res = g_input_stream_close (filter_stream->base_stream, + cancellable, + error); + } + + return res; +} diff --git a/gio/gfilterinputstream.h b/gio/gfilterinputstream.h new file mode 100644 index 0000000..b44a458 --- /dev/null +++ b/gio/gfilterinputstream.h @@ -0,0 +1,78 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#ifndef __G_FILTER_INPUT_STREAM_H__ +#define __G_FILTER_INPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILTER_INPUT_STREAM (g_filter_input_stream_get_type ()) +#define G_FILTER_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILTER_INPUT_STREAM, GFilterInputStream)) +#define G_FILTER_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILTER_INPUT_STREAM, GFilterInputStreamClass)) +#define G_IS_FILTER_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILTER_INPUT_STREAM)) +#define G_IS_FILTER_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILTER_INPUT_STREAM)) +#define G_FILTER_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILTER_INPUT_STREAM, GFilterInputStreamClass)) + +/** + * GFilterInputStream: + * + * A base class for all input streams that work on an underlying stream. + **/ +typedef struct _GFilterInputStreamClass GFilterInputStreamClass; + +struct _GFilterInputStream +{ + GInputStream parent_instance; + + /**/ + GInputStream *base_stream; +}; + +struct _GFilterInputStreamClass +{ + GInputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_filter_input_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GInputStream * g_filter_input_stream_get_base_stream (GFilterInputStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_filter_input_stream_get_close_base_stream (GFilterInputStream *stream); +GLIB_AVAILABLE_IN_ALL +void g_filter_input_stream_set_close_base_stream (GFilterInputStream *stream, + gboolean close_base); + +G_END_DECLS + +#endif /* __G_FILTER_INPUT_STREAM_H__ */ diff --git a/gio/gfilteroutputstream.c b/gio/gfilteroutputstream.c new file mode 100644 index 0000000..9d86493 --- /dev/null +++ b/gio/gfilteroutputstream.c @@ -0,0 +1,308 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#include "config.h" +#include "gfilteroutputstream.h" +#include "goutputstream.h" +#include "glibintl.h" + + +/** + * SECTION:gfilteroutputstream + * @short_description: Filter Output Stream + * @include: gio/gio.h + * + * Base class for output stream implementations that perform some + * kind of filtering operation on a base stream. Typical examples + * of filtering operations are character set conversion, compression + * and byte order flipping. + */ + +enum { + PROP_0, + PROP_BASE_STREAM, + PROP_CLOSE_BASE +}; + +static void g_filter_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static void g_filter_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void g_filter_output_stream_dispose (GObject *object); + + +static gssize g_filter_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_filter_output_stream_flush (GOutputStream *stream, + GCancellable *cancellable, + GError **error); +static gboolean g_filter_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error); + +typedef struct +{ + gboolean close_base; +} GFilterOutputStreamPrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GFilterOutputStream, g_filter_output_stream, G_TYPE_OUTPUT_STREAM) + +static void +g_filter_output_stream_class_init (GFilterOutputStreamClass *klass) +{ + GObjectClass *object_class; + GOutputStreamClass *ostream_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = g_filter_output_stream_get_property; + object_class->set_property = g_filter_output_stream_set_property; + object_class->dispose = g_filter_output_stream_dispose; + + ostream_class = G_OUTPUT_STREAM_CLASS (klass); + ostream_class->write_fn = g_filter_output_stream_write; + ostream_class->flush = g_filter_output_stream_flush; + ostream_class->close_fn = g_filter_output_stream_close; + + g_object_class_install_property (object_class, + PROP_BASE_STREAM, + g_param_spec_object ("base-stream", + P_("The Filter Base Stream"), + P_("The underlying base stream on which the io ops will be done."), + G_TYPE_OUTPUT_STREAM, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (object_class, + PROP_CLOSE_BASE, + g_param_spec_boolean ("close-base-stream", + P_("Close Base Stream"), + P_("If the base stream should be closed when the filter stream is closed."), + TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); +} + +static void +g_filter_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GFilterOutputStream *filter_stream; + GObject *obj; + + filter_stream = G_FILTER_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_BASE_STREAM: + obj = g_value_dup_object (value); + filter_stream->base_stream = G_OUTPUT_STREAM (obj); + break; + + case PROP_CLOSE_BASE: + g_filter_output_stream_set_close_base_stream (filter_stream, + g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_filter_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GFilterOutputStream *filter_stream; + GFilterOutputStreamPrivate *priv; + + filter_stream = G_FILTER_OUTPUT_STREAM (object); + priv = g_filter_output_stream_get_instance_private (filter_stream); + + switch (prop_id) + { + case PROP_BASE_STREAM: + g_value_set_object (value, filter_stream->base_stream); + break; + + case PROP_CLOSE_BASE: + g_value_set_boolean (value, priv->close_base); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_filter_output_stream_dispose (GObject *object) +{ + GFilterOutputStream *stream; + + stream = G_FILTER_OUTPUT_STREAM (object); + + G_OBJECT_CLASS (g_filter_output_stream_parent_class)->dispose (object); + + if (stream->base_stream) + { + g_object_unref (stream->base_stream); + stream->base_stream = NULL; + } +} + + +static void +g_filter_output_stream_init (GFilterOutputStream *stream) +{ +} + +/** + * g_filter_output_stream_get_base_stream: + * @stream: a #GFilterOutputStream. + * + * Gets the base stream for the filter stream. + * + * Returns: (transfer none): a #GOutputStream. + **/ +GOutputStream * +g_filter_output_stream_get_base_stream (GFilterOutputStream *stream) +{ + g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), NULL); + + return stream->base_stream; +} + +/** + * g_filter_output_stream_get_close_base_stream: + * @stream: a #GFilterOutputStream. + * + * Returns whether the base stream will be closed when @stream is + * closed. + * + * Returns: %TRUE if the base stream will be closed. + **/ +gboolean +g_filter_output_stream_get_close_base_stream (GFilterOutputStream *stream) +{ + GFilterOutputStreamPrivate *priv; + + g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), FALSE); + + priv = g_filter_output_stream_get_instance_private (stream); + + return priv->close_base; +} + +/** + * g_filter_output_stream_set_close_base_stream: + * @stream: a #GFilterOutputStream. + * @close_base: %TRUE to close the base stream. + * + * Sets whether the base stream will be closed when @stream is closed. + **/ +void +g_filter_output_stream_set_close_base_stream (GFilterOutputStream *stream, + gboolean close_base) +{ + GFilterOutputStreamPrivate *priv; + + g_return_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream)); + + close_base = !!close_base; + + priv = g_filter_output_stream_get_instance_private (stream); + + if (priv->close_base != close_base) + { + priv->close_base = close_base; + g_object_notify (G_OBJECT (stream), "close-base-stream"); + } +} + +static gssize +g_filter_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GFilterOutputStream *filter_stream; + gssize nwritten; + + filter_stream = G_FILTER_OUTPUT_STREAM (stream); + + nwritten = g_output_stream_write (filter_stream->base_stream, + buffer, + count, + cancellable, + error); + + return nwritten; +} + +static gboolean +g_filter_output_stream_flush (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GFilterOutputStream *filter_stream; + gboolean res; + + filter_stream = G_FILTER_OUTPUT_STREAM (stream); + + res = g_output_stream_flush (filter_stream->base_stream, + cancellable, + error); + + return res; +} + +static gboolean +g_filter_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GFilterOutputStream *filter_stream = G_FILTER_OUTPUT_STREAM (stream); + GFilterOutputStreamPrivate *priv = g_filter_output_stream_get_instance_private (filter_stream); + gboolean res = TRUE; + + if (priv->close_base) + { + res = g_output_stream_close (filter_stream->base_stream, + cancellable, + error); + } + + return res; +} diff --git a/gio/gfilteroutputstream.h b/gio/gfilteroutputstream.h new file mode 100644 index 0000000..105e72b --- /dev/null +++ b/gio/gfilteroutputstream.h @@ -0,0 +1,78 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#ifndef __G_FILTER_OUTPUT_STREAM_H__ +#define __G_FILTER_OUTPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_FILTER_OUTPUT_STREAM (g_filter_output_stream_get_type ()) +#define G_FILTER_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILTER_OUTPUT_STREAM, GFilterOutputStream)) +#define G_FILTER_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILTER_OUTPUT_STREAM, GFilterOutputStreamClass)) +#define G_IS_FILTER_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILTER_OUTPUT_STREAM)) +#define G_IS_FILTER_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILTER_OUTPUT_STREAM)) +#define G_FILTER_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILTER_OUTPUT_STREAM, GFilterOutputStreamClass)) + +/** + * GFilterOutputStream: + * + * A base class for all output streams that work on an underlying stream. + **/ +typedef struct _GFilterOutputStreamClass GFilterOutputStreamClass; + +struct _GFilterOutputStream +{ + GOutputStream parent_instance; + + /*< protected >*/ + GOutputStream *base_stream; +}; + +struct _GFilterOutputStreamClass +{ + GOutputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_filter_output_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GOutputStream * g_filter_output_stream_get_base_stream (GFilterOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_filter_output_stream_get_close_base_stream (GFilterOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +void g_filter_output_stream_set_close_base_stream (GFilterOutputStream *stream, + gboolean close_base); + +G_END_DECLS + +#endif /* __G_FILTER_OUTPUT_STREAM_H__ */ diff --git a/gio/ggtknotificationbackend.c b/gio/ggtknotificationbackend.c new file mode 100644 index 0000000..8d6eab2 --- /dev/null +++ b/gio/ggtknotificationbackend.c @@ -0,0 +1,122 @@ +/* +* Copyright © 2013 Lars Uebernickel +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General +* Public License along with this library; if not, see . +* +* Authors: Lars Uebernickel +*/ + +#include "config.h" +#include "gnotificationbackend.h" + +#include "giomodule-priv.h" +#include "gdbusconnection.h" +#include "gapplication.h" +#include "gnotification-private.h" + +#define G_TYPE_GTK_NOTIFICATION_BACKEND (g_gtk_notification_backend_get_type ()) +#define G_GTK_NOTIFICATION_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_GTK_NOTIFICATION_BACKEND, GGtkNotificationBackend)) + +typedef struct _GGtkNotificationBackend GGtkNotificationBackend; +typedef GNotificationBackendClass GGtkNotificationBackendClass; + +struct _GGtkNotificationBackend +{ + GNotificationBackend parent; +}; + +GType g_gtk_notification_backend_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (GGtkNotificationBackend, g_gtk_notification_backend, G_TYPE_NOTIFICATION_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "gtk", 100)) + +static gboolean +g_gtk_notification_backend_is_supported (void) +{ + GDBusConnection *session_bus; + GVariant *reply; + + /* Find out if the notification server is running. This is a + * synchronous call because gio extension points don't support asnyc + * backend verification. This is only run once and only contacts the + * dbus daemon. */ + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + if (session_bus == NULL) + return FALSE; + + reply = g_dbus_connection_call_sync (session_bus, "org.freedesktop.DBus", "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetNameOwner", g_variant_new ("(s)", "org.gtk.Notifications"), + G_VARIANT_TYPE ("(s)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + + g_object_unref (session_bus); + + if (reply) + { + g_variant_unref (reply); + return TRUE; + } + else + return FALSE; +} + +static void +g_gtk_notification_backend_send_notification (GNotificationBackend *backend, + const gchar *id, + GNotification *notification) +{ + GVariant *params; + + params = g_variant_new ("(ss@a{sv})", g_application_get_application_id (backend->application), + id, + g_notification_serialize (notification)); + + g_dbus_connection_call (backend->dbus_connection, + "org.gtk.Notifications", "/org/gtk/Notifications", + "org.gtk.Notifications", "AddNotification", params, + G_VARIANT_TYPE_UNIT, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +g_gtk_notification_backend_withdraw_notification (GNotificationBackend *backend, + const gchar *id) +{ + GVariant *params; + + params = g_variant_new ("(ss)", g_application_get_application_id (backend->application), id); + + g_dbus_connection_call (backend->dbus_connection, "org.gtk.Notifications", + "/org/gtk/Notifications", "org.gtk.Notifications", + "RemoveNotification", params, G_VARIANT_TYPE_UNIT, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +g_gtk_notification_backend_init (GGtkNotificationBackend *backend) +{ +} + +static void +g_gtk_notification_backend_class_init (GGtkNotificationBackendClass *class) +{ + GNotificationBackendClass *backend_class = G_NOTIFICATION_BACKEND_CLASS (class); + + backend_class->is_supported = g_gtk_notification_backend_is_supported; + backend_class->send_notification = g_gtk_notification_backend_send_notification; + backend_class->withdraw_notification = g_gtk_notification_backend_withdraw_notification; +} diff --git a/gio/ghttpproxy.c b/gio/ghttpproxy.c new file mode 100644 index 0000000..505a8fe --- /dev/null +++ b/gio/ghttpproxy.c @@ -0,0 +1,416 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * Copyright (C) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + * Marc-André Lureau + */ + +#include "config.h" + +#include "ghttpproxy.h" + +#include +#include + +#include "giomodule.h" +#include "giomodule-priv.h" +#include "giostream.h" +#include "ginputstream.h" +#include "glibintl.h" +#include "goutputstream.h" +#include "gproxy.h" +#include "gproxyaddress.h" +#include "gsocketconnectable.h" +#include "gtask.h" +#include "gtlsclientconnection.h" +#include "gtlsconnection.h" + + +struct _GHttpProxy +{ + GObject parent; +}; + +struct _GHttpProxyClass +{ + GObjectClass parent_class; +}; + +static void g_http_proxy_iface_init (GProxyInterface *proxy_iface); + +#define g_http_proxy_get_type _g_http_proxy_get_type +G_DEFINE_TYPE_WITH_CODE (GHttpProxy, g_http_proxy, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY, + g_http_proxy_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME, + g_define_type_id, + "http", + 0)) + +static void +g_http_proxy_init (GHttpProxy *proxy) +{ +} + +static gchar * +create_request (GProxyAddress *proxy_address, + gboolean *has_cred, + GError **error) +{ + const gchar *hostname; + gint port; + const gchar *username; + const gchar *password; + GString *request; + gchar *ascii_hostname; + + if (has_cred) + *has_cred = FALSE; + + hostname = g_proxy_address_get_destination_hostname (proxy_address); + ascii_hostname = g_hostname_to_ascii (hostname); + if (!ascii_hostname) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid hostname")); + return NULL; + } + port = g_proxy_address_get_destination_port (proxy_address); + username = g_proxy_address_get_username (proxy_address); + password = g_proxy_address_get_password (proxy_address); + + request = g_string_new (NULL); + + g_string_append_printf (request, + "CONNECT %s:%i HTTP/1.0\r\n" + "Host: %s:%i\r\n" + "Proxy-Connection: keep-alive\r\n" + "User-Agent: GLib/%i.%i\r\n", + ascii_hostname, port, + ascii_hostname, port, + GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION); + g_free (ascii_hostname); + + if (username != NULL && password != NULL) + { + gchar *cred; + gchar *base64_cred; + + if (has_cred) + *has_cred = TRUE; + + cred = g_strdup_printf ("%s:%s", username, password); + base64_cred = g_base64_encode ((guchar *) cred, strlen (cred)); + g_free (cred); + g_string_append_printf (request, + "Proxy-Authorization: Basic %s\r\n", + base64_cred); + g_free (base64_cred); + } + + g_string_append (request, "\r\n"); + + return g_string_free (request, FALSE); +} + +static gboolean +check_reply (const gchar *buffer, + gboolean has_cred, + GError **error) +{ + gint err_code; + const gchar *ptr = buffer + 7; + + if (strncmp (buffer, "HTTP/1.", 7) != 0 || (*ptr != '0' && *ptr != '1')) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("Bad HTTP proxy reply")); + return FALSE; + } + + ptr++; + while (*ptr == ' ') + ptr++; + + err_code = atoi (ptr); + + if (err_code < 200 || err_code >= 300) + { + switch (err_code) + { + case 403: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NOT_ALLOWED, + _("HTTP proxy connection not allowed")); + break; + case 407: + if (has_cred) + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED, + _("HTTP proxy authentication failed")); + else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NEED_AUTH, + _("HTTP proxy authentication required")); + break; + default: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("HTTP proxy connection failed: %i"), err_code); + } + + return FALSE; + } + + return TRUE; +} + +#define HTTP_END_MARKER "\r\n\r\n" + +static GIOStream * +g_http_proxy_connect (GProxy *proxy, + GIOStream *io_stream, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GError **error) +{ + GInputStream *in; + GOutputStream *out; + gchar *buffer = NULL; + gsize buffer_length; + gsize bytes_read; + gboolean has_cred; + GIOStream *tlsconn = NULL; + + if (G_IS_HTTPS_PROXY (proxy)) + { + tlsconn = g_tls_client_connection_new (io_stream, + G_SOCKET_CONNECTABLE (proxy_address), + error); + if (!tlsconn) + goto error; + +#ifdef DEBUG + { + GTlsCertificateFlags tls_validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL; + + tls_validation_flags &= ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY); + g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn), + tls_validation_flags); + } +#endif + + if (!g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn), cancellable, error)) + goto error; + + io_stream = tlsconn; + } + + in = g_io_stream_get_input_stream (io_stream); + out = g_io_stream_get_output_stream (io_stream); + + buffer = create_request (proxy_address, &has_cred, error); + if (!buffer) + goto error; + if (!g_output_stream_write_all (out, buffer, strlen (buffer), NULL, + cancellable, error)) + goto error; + + g_free (buffer); + + bytes_read = 0; + buffer_length = 1024; + buffer = g_malloc (buffer_length); + + /* Read byte-by-byte instead of using GDataInputStream + * since we do not want to read beyond the end marker + */ + do + { + gssize signed_nread; + gsize nread; + + signed_nread = + g_input_stream_read (in, buffer + bytes_read, 1, cancellable, error); + if (signed_nread == -1) + goto error; + + nread = signed_nread; + if (nread == 0) + break; + + ++bytes_read; + + if (bytes_read == buffer_length) + { + /* HTTP specifications does not defines any upper limit for + * headers. But, the most usual size used seems to be 8KB. + * Yet, the biggest we found was Tomcat's HTTP headers whose + * size is 48K. So, for a reasonable error margin, let's accept + * a header with a twice as large size but no more: 96KB */ + if (buffer_length > 98304) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("HTTP proxy response too big")); + goto error; + } + buffer_length = 2 * buffer_length; + buffer = g_realloc (buffer, buffer_length); + } + + *(buffer + bytes_read) = '\0'; + + if (g_str_has_suffix (buffer, HTTP_END_MARKER)) + break; + } + while (TRUE); + + if (bytes_read == 0) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("HTTP proxy server closed connection unexpectedly.")); + goto error; + } + + if (!check_reply (buffer, has_cred, error)) + goto error; + + g_free (buffer); + + g_object_ref (io_stream); + g_clear_object (&tlsconn); + + return io_stream; + +error: + g_clear_object (&tlsconn); + g_free (buffer); + return NULL; +} + +typedef struct +{ + GIOStream *io_stream; + GProxyAddress *proxy_address; +} ConnectAsyncData; + +static void +free_connect_data (ConnectAsyncData *data) +{ + g_object_unref (data->io_stream); + g_object_unref (data->proxy_address); + g_slice_free (ConnectAsyncData, data); +} + +static void +connect_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GProxy *proxy = source_object; + ConnectAsyncData *data = task_data; + GIOStream *res; + GError *error = NULL; + + res = g_http_proxy_connect (proxy, data->io_stream, data->proxy_address, + cancellable, &error); + + if (res == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, res, g_object_unref); +} + +static void +g_http_proxy_connect_async (GProxy *proxy, + GIOStream *io_stream, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + ConnectAsyncData *data; + GTask *task; + + data = g_slice_new0 (ConnectAsyncData); + data->io_stream = g_object_ref (io_stream); + data->proxy_address = g_object_ref (proxy_address); + + task = g_task_new (proxy, cancellable, callback, user_data); + g_task_set_source_tag (task, g_http_proxy_connect_async); + g_task_set_task_data (task, data, (GDestroyNotify) free_connect_data); + + g_task_run_in_thread (task, connect_thread); + g_object_unref (task); +} + +static GIOStream * +g_http_proxy_connect_finish (GProxy *proxy, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (result), error); +} + +static gboolean +g_http_proxy_supports_hostname (GProxy *proxy) +{ + return TRUE; +} + +static void +g_http_proxy_class_init (GHttpProxyClass *class) +{ +} + +static void +g_http_proxy_iface_init (GProxyInterface *proxy_iface) +{ + proxy_iface->connect = g_http_proxy_connect; + proxy_iface->connect_async = g_http_proxy_connect_async; + proxy_iface->connect_finish = g_http_proxy_connect_finish; + proxy_iface->supports_hostname = g_http_proxy_supports_hostname; +} + +struct _GHttpsProxy +{ + GHttpProxy parent; +}; + +struct _GHttpsProxyClass +{ + GHttpProxyClass parent_class; +}; + +#define g_https_proxy_get_type _g_https_proxy_get_type +G_DEFINE_TYPE_WITH_CODE (GHttpsProxy, g_https_proxy, G_TYPE_HTTP_PROXY, + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY, + g_http_proxy_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME, + g_define_type_id, + "https", + 0)) + +static void +g_https_proxy_init (GHttpsProxy *proxy) +{ +} + +static void +g_https_proxy_class_init (GHttpsProxyClass *class) +{ +} diff --git a/gio/ghttpproxy.h b/gio/ghttpproxy.h new file mode 100644 index 0000000..21c0100 --- /dev/null +++ b/gio/ghttpproxy.h @@ -0,0 +1,54 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#ifndef __G_HTTP_PROXY_H__ +#define __G_HTTP_PROXY_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_HTTP_PROXY (_g_http_proxy_get_type ()) +#define G_HTTP_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_HTTP_PROXY, GHttpProxy)) +#define G_HTTP_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_HTTP_PROXY, GHttpProxyClass)) +#define G_IS_HTTP_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_HTTP_PROXY)) +#define G_IS_HTTP_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_HTTP_PROXY)) +#define G_HTTP_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_HTTP_PROXY, GHttpProxyClass)) + +typedef struct _GHttpProxy GHttpProxy; +typedef struct _GHttpProxyClass GHttpProxyClass; + +GType _g_http_proxy_get_type (void); + +#define G_TYPE_HTTPS_PROXY (_g_https_proxy_get_type ()) +#define G_HTTPS_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_HTTPS_PROXY, GHttpsProxy)) +#define G_HTTPS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_HTTPS_PROXY, GHttpsProxyClass)) +#define G_IS_HTTPS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_HTTPS_PROXY)) +#define G_IS_HTTPS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_HTTPS_PROXY)) +#define G_HTTPS_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_HTTPS_PROXY, GHttpsProxyClass)) + +typedef struct _GHttpsProxy GHttpsProxy; +typedef struct _GHttpsProxyClass GHttpsProxyClass; + +GType _g_https_proxy_get_type (void); + +G_END_DECLS + +#endif /* __G_HTTP_PROXY_H__ */ diff --git a/gio/gicon.c b/gio/gicon.c new file mode 100644 index 0000000..29fae10 --- /dev/null +++ b/gio/gicon.c @@ -0,0 +1,690 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include +#include + +#include "gicon.h" +#include "gthemedicon.h" +#include "gfileicon.h" +#include "gemblemedicon.h" +#include "gbytesicon.h" +#include "gfile.h" +#include "gioerror.h" +#include "gioenumtypes.h" +#include "gvfs.h" + +#include "glibintl.h" + + +/* There versioning of this is implicit, version 1 would be ".1 " */ +#define G_ICON_SERIALIZATION_MAGIC0 ". " + +/** + * SECTION:gicon + * @short_description: Interface for icons + * @include: gio/gio.h + * + * #GIcon is a very minimal interface for icons. It provides functions + * for checking the equality of two icons, hashing of icons and + * serializing an icon to and from strings. + * + * #GIcon does not provide the actual pixmap for the icon as this is out + * of GIO's scope, however implementations of #GIcon may contain the name + * of an icon (see #GThemedIcon), or the path to an icon (see #GLoadableIcon). + * + * To obtain a hash of a #GIcon, see g_icon_hash(). + * + * To check if two #GIcons are equal, see g_icon_equal(). + * + * For serializing a #GIcon, use g_icon_serialize() and + * g_icon_deserialize(). + * + * If you want to consume #GIcon (for example, in a toolkit) you must + * be prepared to handle at least the three following cases: + * #GLoadableIcon, #GThemedIcon and #GEmblemedIcon. It may also make + * sense to have fast-paths for other cases (like handling #GdkPixbuf + * directly, for example) but all compliant #GIcon implementations + * outside of GIO must implement #GLoadableIcon. + * + * If your application or library provides one or more #GIcon + * implementations you need to ensure that your new implementation also + * implements #GLoadableIcon. Additionally, you must provide an + * implementation of g_icon_serialize() that gives a result that is + * understood by g_icon_deserialize(), yielding one of the built-in icon + * types. + **/ + +typedef GIconIface GIconInterface; +G_DEFINE_INTERFACE(GIcon, g_icon, G_TYPE_OBJECT) + +static void +g_icon_default_init (GIconInterface *iface) +{ +} + +/** + * g_icon_hash: + * @icon: (not nullable): #gconstpointer to an icon object. + * + * Gets a hash for an icon. + * + * Virtual: hash + * Returns: a #guint containing a hash for the @icon, suitable for + * use in a #GHashTable or similar data structure. + **/ +guint +g_icon_hash (gconstpointer icon) +{ + GIconIface *iface; + + g_return_val_if_fail (G_IS_ICON (icon), 0); + + iface = G_ICON_GET_IFACE (icon); + + return (* iface->hash) ((GIcon *)icon); +} + +/** + * g_icon_equal: + * @icon1: (nullable): pointer to the first #GIcon. + * @icon2: (nullable): pointer to the second #GIcon. + * + * Checks if two icons are equal. + * + * Returns: %TRUE if @icon1 is equal to @icon2. %FALSE otherwise. + **/ +gboolean +g_icon_equal (GIcon *icon1, + GIcon *icon2) +{ + GIconIface *iface; + + if (icon1 == NULL && icon2 == NULL) + return TRUE; + + if (icon1 == NULL || icon2 == NULL) + return FALSE; + + if (G_TYPE_FROM_INSTANCE (icon1) != G_TYPE_FROM_INSTANCE (icon2)) + return FALSE; + + iface = G_ICON_GET_IFACE (icon1); + + return (* iface->equal) (icon1, icon2); +} + +static gboolean +g_icon_to_string_tokenized (GIcon *icon, GString *s) +{ + GPtrArray *tokens; + gint version; + GIconIface *icon_iface; + guint i; + + g_return_val_if_fail (icon != NULL, FALSE); + g_return_val_if_fail (G_IS_ICON (icon), FALSE); + + icon_iface = G_ICON_GET_IFACE (icon); + if (icon_iface->to_tokens == NULL) + return FALSE; + + tokens = g_ptr_array_new (); + if (!icon_iface->to_tokens (icon, tokens, &version)) + { + g_ptr_array_free (tokens, TRUE); + return FALSE; + } + + /* format: TypeName[.Version] .. + version 0 is implicit and can be omitted + all the tokens are url escaped to ensure they have no spaces in them */ + + g_string_append (s, g_type_name_from_instance ((GTypeInstance *)icon)); + if (version != 0) + g_string_append_printf (s, ".%d", version); + + for (i = 0; i < tokens->len; i++) + { + char *token; + + token = g_ptr_array_index (tokens, i); + + g_string_append_c (s, ' '); + /* We really only need to escape spaces here, so allow lots of otherwise reserved chars */ + g_string_append_uri_escaped (s, token, + G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE); + + g_free (token); + } + + g_ptr_array_free (tokens, TRUE); + + return TRUE; +} + +/** + * g_icon_to_string: + * @icon: a #GIcon. + * + * Generates a textual representation of @icon that can be used for + * serialization such as when passing @icon to a different process or + * saving it to persistent storage. Use g_icon_new_for_string() to + * get @icon back from the returned string. + * + * The encoding of the returned string is proprietary to #GIcon except + * in the following two cases + * + * - If @icon is a #GFileIcon, the returned string is a native path + * (such as `/path/to/my icon.png`) without escaping + * if the #GFile for @icon is a native file. If the file is not + * native, the returned string is the result of g_file_get_uri() + * (such as `sftp://path/to/my%20icon.png`). + * + * - If @icon is a #GThemedIcon with exactly one name and no fallbacks, + * the encoding is simply the name (such as `network-server`). + * + * Virtual: to_tokens + * Returns: (nullable): An allocated NUL-terminated UTF8 string or + * %NULL if @icon can't be serialized. Use g_free() to free. + * + * Since: 2.20 + */ +gchar * +g_icon_to_string (GIcon *icon) +{ + gchar *ret; + + g_return_val_if_fail (icon != NULL, NULL); + g_return_val_if_fail (G_IS_ICON (icon), NULL); + + ret = NULL; + + if (G_IS_FILE_ICON (icon)) + { + GFile *file; + + file = g_file_icon_get_file (G_FILE_ICON (icon)); + if (g_file_is_native (file)) + { + ret = g_file_get_path (file); + if (!g_utf8_validate (ret, -1, NULL)) + { + g_free (ret); + ret = NULL; + } + } + else + ret = g_file_get_uri (file); + } + else if (G_IS_THEMED_ICON (icon)) + { + char **names = NULL; + gboolean use_default_fallbacks = FALSE; + + g_object_get (G_OBJECT (icon), + "names", &names, + "use-default-fallbacks", &use_default_fallbacks, + NULL); + /* Themed icon initialized with a single name and no fallbacks. */ + if (names != NULL && + names[0] != NULL && + names[0][0] != '.' && /* Allowing icons starting with dot would break G_ICON_SERIALIZATION_MAGIC0 */ + g_utf8_validate (names[0], -1, NULL) && /* Only return utf8 strings */ + names[1] == NULL && + ! use_default_fallbacks) + ret = g_strdup (names[0]); + + g_strfreev (names); + } + + if (ret == NULL) + { + GString *s; + + s = g_string_new (G_ICON_SERIALIZATION_MAGIC0); + + if (g_icon_to_string_tokenized (icon, s)) + ret = g_string_free (s, FALSE); + else + g_string_free (s, TRUE); + } + + return ret; +} + +static GIcon * +g_icon_new_from_tokens (char **tokens, + GError **error) +{ + GIcon *icon; + char *typename, *version_str; + GType type; + gpointer klass; + GIconIface *icon_iface; + gint version; + char *endp; + int num_tokens; + int i; + + icon = NULL; + klass = NULL; + + num_tokens = g_strv_length (tokens); + + if (num_tokens < 1) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Wrong number of tokens (%d)"), + num_tokens); + goto out; + } + + typename = tokens[0]; + version_str = strchr (typename, '.'); + if (version_str) + { + *version_str = 0; + version_str += 1; + } + + + type = g_type_from_name (tokens[0]); + if (type == 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("No type for class name %s"), + tokens[0]); + goto out; + } + + if (!g_type_is_a (type, G_TYPE_ICON)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Type %s does not implement the GIcon interface"), + tokens[0]); + goto out; + } + + klass = g_type_class_ref (type); + if (klass == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Type %s is not classed"), + tokens[0]); + goto out; + } + + version = 0; + if (version_str) + { + version = strtol (version_str, &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Malformed version number: %s"), + version_str); + goto out; + } + } + + icon_iface = g_type_interface_peek (klass, G_TYPE_ICON); + g_assert (icon_iface != NULL); + + if (icon_iface->from_tokens == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Type %s does not implement from_tokens() on the GIcon interface"), + tokens[0]); + goto out; + } + + for (i = 1; i < num_tokens; i++) + { + char *escaped; + + escaped = tokens[i]; + tokens[i] = g_uri_unescape_string (escaped, NULL); + g_free (escaped); + } + + icon = icon_iface->from_tokens (tokens + 1, num_tokens - 1, version, error); + + out: + if (klass != NULL) + g_type_class_unref (klass); + return icon; +} + +static void +ensure_builtin_icon_types (void) +{ + g_type_ensure (G_TYPE_THEMED_ICON); + g_type_ensure (G_TYPE_FILE_ICON); + g_type_ensure (G_TYPE_EMBLEMED_ICON); + g_type_ensure (G_TYPE_EMBLEM); +} + +/* handles the 'simple' cases: GFileIcon and GThemedIcon */ +static GIcon * +g_icon_new_for_string_simple (const gchar *str) +{ + gchar *scheme; + GIcon *icon; + + if (str[0] == '.') + return NULL; + + /* handle special GFileIcon and GThemedIcon cases */ + scheme = g_uri_parse_scheme (str); + if (scheme != NULL || str[0] == '/' || str[0] == G_DIR_SEPARATOR) + { + GFile *location; + location = g_file_new_for_commandline_arg (str); + icon = g_file_icon_new (location); + g_object_unref (location); + } + else + icon = g_themed_icon_new (str); + + g_free (scheme); + + return icon; +} + +/** + * g_icon_new_for_string: + * @str: A string obtained via g_icon_to_string(). + * @error: Return location for error. + * + * Generate a #GIcon instance from @str. This function can fail if + * @str is not valid - see g_icon_to_string() for discussion. + * + * If your application or library provides one or more #GIcon + * implementations you need to ensure that each #GType is registered + * with the type system prior to calling g_icon_new_for_string(). + * + * Returns: (transfer full): An object implementing the #GIcon + * interface or %NULL if @error is set. + * + * Since: 2.20 + **/ +GIcon * +g_icon_new_for_string (const gchar *str, + GError **error) +{ + GIcon *icon = NULL; + + g_return_val_if_fail (str != NULL, NULL); + + icon = g_icon_new_for_string_simple (str); + if (icon) + return icon; + + ensure_builtin_icon_types (); + + if (g_str_has_prefix (str, G_ICON_SERIALIZATION_MAGIC0)) + { + gchar **tokens; + + /* handle tokenized encoding */ + tokens = g_strsplit (str + sizeof (G_ICON_SERIALIZATION_MAGIC0) - 1, " ", 0); + icon = g_icon_new_from_tokens (tokens, error); + g_strfreev (tokens); + } + else + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Can’t handle the supplied version of the icon encoding")); + + return icon; +} + +static GEmblem * +g_icon_deserialize_emblem (GVariant *value) +{ + GVariant *emblem_metadata; + GVariant *emblem_data; + const gchar *origin_nick; + GIcon *emblem_icon; + GEmblem *emblem; + + g_variant_get (value, "(v@a{sv})", &emblem_data, &emblem_metadata); + + emblem = NULL; + + emblem_icon = g_icon_deserialize (emblem_data); + if (emblem_icon != NULL) + { + /* Check if we should create it with an origin. */ + if (g_variant_lookup (emblem_metadata, "origin", "&s", &origin_nick)) + { + GEnumClass *origin_class; + GEnumValue *origin_value; + + origin_class = g_type_class_ref (G_TYPE_EMBLEM_ORIGIN); + origin_value = g_enum_get_value_by_nick (origin_class, origin_nick); + if (origin_value) + emblem = g_emblem_new_with_origin (emblem_icon, origin_value->value); + g_type_class_unref (origin_class); + } + + /* We didn't create it with an origin, so do it without. */ + if (emblem == NULL) + emblem = g_emblem_new (emblem_icon); + + g_object_unref (emblem_icon); + } + + g_variant_unref (emblem_metadata); + g_variant_unref (emblem_data); + + return emblem; +} + +static GIcon * +g_icon_deserialize_emblemed (GVariant *value) +{ + GVariantIter *emblems; + GVariant *icon_data; + GIcon *main_icon; + GIcon *icon; + + g_variant_get (value, "(va(va{sv}))", &icon_data, &emblems); + main_icon = g_icon_deserialize (icon_data); + + if (main_icon) + { + GVariant *emblem_data; + + icon = g_emblemed_icon_new (main_icon, NULL); + + while ((emblem_data = g_variant_iter_next_value (emblems))) + { + GEmblem *emblem; + + emblem = g_icon_deserialize_emblem (emblem_data); + + if (emblem) + { + g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (icon), emblem); + g_object_unref (emblem); + } + + g_variant_unref (emblem_data); + } + + g_object_unref (main_icon); + } + else + icon = NULL; + + g_variant_iter_free (emblems); + g_variant_unref (icon_data); + + return icon; +} + +/** + * g_icon_deserialize: + * @value: (transfer none): a #GVariant created with g_icon_serialize() + * + * Deserializes a #GIcon previously serialized using g_icon_serialize(). + * + * Returns: (nullable) (transfer full): a #GIcon, or %NULL when deserialization fails. + * + * Since: 2.38 + */ +GIcon * +g_icon_deserialize (GVariant *value) +{ + const gchar *tag; + GVariant *val; + GIcon *icon; + + g_return_val_if_fail (value != NULL, NULL); + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) || + g_variant_is_of_type (value, G_VARIANT_TYPE ("(sv)")), NULL); + + /* Handle some special cases directly so that people can hard-code + * stuff into GMenuModel xml files without resorting to using GVariant + * text format to describe one of the explicitly-tagged possibilities + * below. + */ + if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) + return g_icon_new_for_string_simple (g_variant_get_string (value, NULL)); + + /* Otherwise, use the tagged union format */ + g_variant_get (value, "(&sv)", &tag, &val); + + icon = NULL; + + if (g_str_equal (tag, "file") && g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) + { + GFile *file; + + file = g_file_new_for_commandline_arg (g_variant_get_string (val, NULL)); + icon = g_file_icon_new (file); + g_object_unref (file); + } + else if (g_str_equal (tag, "themed") && g_variant_is_of_type (val, G_VARIANT_TYPE_STRING_ARRAY)) + { + const gchar **names; + gsize size; + + names = g_variant_get_strv (val, &size); + icon = g_themed_icon_new_from_names ((gchar **) names, size); + g_free (names); + } + else if (g_str_equal (tag, "bytes") && g_variant_is_of_type (val, G_VARIANT_TYPE_BYTESTRING)) + { + GBytes *bytes; + + bytes = g_variant_get_data_as_bytes (val); + icon = g_bytes_icon_new (bytes); + g_bytes_unref (bytes); + } + else if (g_str_equal (tag, "emblem") && g_variant_is_of_type (val, G_VARIANT_TYPE ("(va{sv})"))) + { + GEmblem *emblem; + + emblem = g_icon_deserialize_emblem (val); + if (emblem) + icon = G_ICON (emblem); + } + else if (g_str_equal (tag, "emblemed") && g_variant_is_of_type (val, G_VARIANT_TYPE ("(va(va{sv}))"))) + { + icon = g_icon_deserialize_emblemed (val); + } + else if (g_str_equal (tag, "gvfs")) + { + GVfsClass *class; + GVfs *vfs; + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->deserialize_icon) + icon = (* class->deserialize_icon) (vfs, val); + } + + g_variant_unref (val); + + return icon; +} + +/** + * g_icon_serialize: + * @icon: a #GIcon + * + * Serializes a #GIcon into a #GVariant. An equivalent #GIcon can be retrieved + * back by calling g_icon_deserialize() on the returned value. + * As serialization will avoid using raw icon data when possible, it only + * makes sense to transfer the #GVariant between processes on the same machine, + * (as opposed to over the network), and within the same file system namespace. + * + * Returns: (nullable) (transfer full): a #GVariant, or %NULL when serialization fails. The #GVariant will not be floating. + * + * Since: 2.38 + */ +GVariant * +g_icon_serialize (GIcon *icon) +{ + GIconInterface *iface; + GVariant *result; + + iface = G_ICON_GET_IFACE (icon); + + if (!iface->serialize) + { + g_critical ("g_icon_serialize() on icon type '%s' is not implemented", G_OBJECT_TYPE_NAME (icon)); + return NULL; + } + + result = (* iface->serialize) (icon); + + if (result) + { + g_variant_take_ref (result); + + if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(sv)"))) + { + g_critical ("g_icon_serialize() on icon type '%s' returned GVariant of type '%s' but it must return " + "one with type '(sv)'", G_OBJECT_TYPE_NAME (icon), g_variant_get_type_string (result)); + g_variant_unref (result); + result = NULL; + } + } + + return result; +} diff --git a/gio/gicon.h b/gio/gicon.h new file mode 100644 index 0000000..a4a03cb --- /dev/null +++ b/gio/gicon.h @@ -0,0 +1,102 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_ICON_H__ +#define __G_ICON_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_ICON (g_icon_get_type ()) +#define G_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ICON, GIcon)) +#define G_IS_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ICON)) +#define G_ICON_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_ICON, GIconIface)) + +/** + * GIcon: + * + * An abstract type that specifies an icon. + **/ +typedef struct _GIconIface GIconIface; + +/** + * GIconIface: + * @g_iface: The parent interface. + * @hash: A hash for a given #GIcon. + * @equal: Checks if two #GIcons are equal. + * @to_tokens: Serializes a #GIcon into tokens. The tokens must not + * contain any whitespace. Don't implement if the #GIcon can't be + * serialized (Since 2.20). + * @from_tokens: Constructs a #GIcon from tokens. Set the #GError if + * the tokens are malformed. Don't implement if the #GIcon can't be + * serialized (Since 2.20). + * @serialize: Serializes a #GIcon into a #GVariant. Since: 2.38 + * + * GIconIface is used to implement GIcon types for various + * different systems. See #GThemedIcon and #GLoadableIcon for + * examples of how to implement this interface. + */ +struct _GIconIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + guint (* hash) (GIcon *icon); + gboolean (* equal) (GIcon *icon1, + GIcon *icon2); + gboolean (* to_tokens) (GIcon *icon, + GPtrArray *tokens, + gint *out_version); + GIcon * (* from_tokens) (gchar **tokens, + gint num_tokens, + gint version, + GError **error); + + GVariant * (* serialize) (GIcon *icon); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_icon_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +guint g_icon_hash (gconstpointer icon); +GLIB_AVAILABLE_IN_ALL +gboolean g_icon_equal (GIcon *icon1, + GIcon *icon2); +GLIB_AVAILABLE_IN_ALL +gchar *g_icon_to_string (GIcon *icon); +GLIB_AVAILABLE_IN_ALL +GIcon *g_icon_new_for_string (const gchar *str, + GError **error); + +GLIB_AVAILABLE_IN_2_38 +GVariant * g_icon_serialize (GIcon *icon); +GLIB_AVAILABLE_IN_2_38 +GIcon * g_icon_deserialize (GVariant *value); + +G_END_DECLS + +#endif /* __G_ICON_H__ */ diff --git a/gio/ginetaddress.c b/gio/ginetaddress.c new file mode 100644 index 0000000..ada32f8 --- /dev/null +++ b/gio/ginetaddress.c @@ -0,0 +1,912 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#include + +#include + +#include + +#include "ginetaddress.h" +#include "gioenums.h" +#include "gioenumtypes.h" +#include "glibintl.h" +#include "gnetworkingprivate.h" + +struct _GInetAddressPrivate +{ + GSocketFamily family; + union { + struct in_addr ipv4; +#ifdef HAVE_IPV6 + struct in6_addr ipv6; +#endif + } addr; +}; + +/** + * SECTION:ginetaddress + * @short_description: An IPv4/IPv6 address + * @include: gio/gio.h + * + * #GInetAddress represents an IPv4 or IPv6 internet address. Use + * g_resolver_lookup_by_name() or g_resolver_lookup_by_name_async() to + * look up the #GInetAddress for a hostname. Use + * g_resolver_lookup_by_address() or + * g_resolver_lookup_by_address_async() to look up the hostname for a + * #GInetAddress. + * + * To actually connect to a remote host, you will need a + * #GInetSocketAddress (which includes a #GInetAddress as well as a + * port number). + */ + +/** + * GInetAddress: + * + * An IPv4 or IPv6 internet address. + */ + +G_DEFINE_TYPE_WITH_CODE (GInetAddress, g_inet_address, G_TYPE_OBJECT, + G_ADD_PRIVATE (GInetAddress) + g_networking_init ();) + +enum +{ + PROP_0, + PROP_FAMILY, + PROP_BYTES, + PROP_IS_ANY, + PROP_IS_LOOPBACK, + PROP_IS_LINK_LOCAL, + PROP_IS_SITE_LOCAL, + PROP_IS_MULTICAST, + PROP_IS_MC_GLOBAL, + PROP_IS_MC_LINK_LOCAL, + PROP_IS_MC_NODE_LOCAL, + PROP_IS_MC_ORG_LOCAL, + PROP_IS_MC_SITE_LOCAL, +}; + +static void +g_inet_address_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GInetAddress *address = G_INET_ADDRESS (object); + + switch (prop_id) + { + case PROP_FAMILY: + address->priv->family = g_value_get_enum (value); + break; + + case PROP_BYTES: +#ifdef HAVE_IPV6 + memcpy (&address->priv->addr, g_value_get_pointer (value), + address->priv->family == AF_INET ? + sizeof (address->priv->addr.ipv4) : + sizeof (address->priv->addr.ipv6)); +#else + g_assert (address->priv->family == AF_INET); + memcpy (&address->priv->addr, g_value_get_pointer (value), + sizeof (address->priv->addr.ipv4)); +#endif + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_inet_address_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GInetAddress *address = G_INET_ADDRESS (object); + + switch (prop_id) + { + case PROP_FAMILY: + g_value_set_enum (value, address->priv->family); + break; + + case PROP_BYTES: + g_value_set_pointer (value, &address->priv->addr); + break; + + case PROP_IS_ANY: + g_value_set_boolean (value, g_inet_address_get_is_any (address)); + break; + + case PROP_IS_LOOPBACK: + g_value_set_boolean (value, g_inet_address_get_is_loopback (address)); + break; + + case PROP_IS_LINK_LOCAL: + g_value_set_boolean (value, g_inet_address_get_is_link_local (address)); + break; + + case PROP_IS_SITE_LOCAL: + g_value_set_boolean (value, g_inet_address_get_is_site_local (address)); + break; + + case PROP_IS_MULTICAST: + g_value_set_boolean (value, g_inet_address_get_is_multicast (address)); + break; + + case PROP_IS_MC_GLOBAL: + g_value_set_boolean (value, g_inet_address_get_is_mc_global (address)); + break; + + case PROP_IS_MC_LINK_LOCAL: + g_value_set_boolean (value, g_inet_address_get_is_mc_link_local (address)); + break; + + case PROP_IS_MC_NODE_LOCAL: + g_value_set_boolean (value, g_inet_address_get_is_mc_node_local (address)); + break; + + case PROP_IS_MC_ORG_LOCAL: + g_value_set_boolean (value, g_inet_address_get_is_mc_org_local (address)); + break; + + case PROP_IS_MC_SITE_LOCAL: + g_value_set_boolean (value, g_inet_address_get_is_mc_site_local (address)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_inet_address_class_init (GInetAddressClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = g_inet_address_set_property; + gobject_class->get_property = g_inet_address_get_property; + + g_object_class_install_property (gobject_class, PROP_FAMILY, + g_param_spec_enum ("family", + P_("Address family"), + P_("The address family (IPv4 or IPv6)"), + G_TYPE_SOCKET_FAMILY, + G_SOCKET_FAMILY_INVALID, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_BYTES, + g_param_spec_pointer ("bytes", + P_("Bytes"), + P_("The raw address data"), + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-any: + * + * Whether this is the "any" address for its family. + * See g_inet_address_get_is_any(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_ANY, + g_param_spec_boolean ("is-any", + P_("Is any"), + P_("Whether this is the \"any\" address for its family"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-link-local: + * + * Whether this is a link-local address. + * See g_inet_address_get_is_link_local(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_LINK_LOCAL, + g_param_spec_boolean ("is-link-local", + P_("Is link-local"), + P_("Whether this is a link-local address"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-loopback: + * + * Whether this is the loopback address for its family. + * See g_inet_address_get_is_loopback(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_LOOPBACK, + g_param_spec_boolean ("is-loopback", + P_("Is loopback"), + P_("Whether this is the loopback address for its family"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-site-local: + * + * Whether this is a site-local address. + * See g_inet_address_get_is_loopback(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_SITE_LOCAL, + g_param_spec_boolean ("is-site-local", + P_("Is site-local"), + P_("Whether this is a site-local address"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-multicast: + * + * Whether this is a multicast address. + * See g_inet_address_get_is_multicast(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_MULTICAST, + g_param_spec_boolean ("is-multicast", + P_("Is multicast"), + P_("Whether this is a multicast address"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-mc-global: + * + * Whether this is a global multicast address. + * See g_inet_address_get_is_mc_global(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_MC_GLOBAL, + g_param_spec_boolean ("is-mc-global", + P_("Is multicast global"), + P_("Whether this is a global multicast address"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + + /** + * GInetAddress:is-mc-link-local: + * + * Whether this is a link-local multicast address. + * See g_inet_address_get_is_mc_link_local(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_MC_LINK_LOCAL, + g_param_spec_boolean ("is-mc-link-local", + P_("Is multicast link-local"), + P_("Whether this is a link-local multicast address"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-mc-node-local: + * + * Whether this is a node-local multicast address. + * See g_inet_address_get_is_mc_node_local(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_MC_NODE_LOCAL, + g_param_spec_boolean ("is-mc-node-local", + P_("Is multicast node-local"), + P_("Whether this is a node-local multicast address"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-mc-org-local: + * + * Whether this is an organization-local multicast address. + * See g_inet_address_get_is_mc_org_local(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_MC_ORG_LOCAL, + g_param_spec_boolean ("is-mc-org-local", + P_("Is multicast org-local"), + P_("Whether this is an organization-local multicast address"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetAddress:is-mc-site-local: + * + * Whether this is a site-local multicast address. + * See g_inet_address_get_is_mc_site_local(). + * + * Since: 2.22 + */ + g_object_class_install_property (gobject_class, PROP_IS_MC_SITE_LOCAL, + g_param_spec_boolean ("is-mc-site-local", + P_("Is multicast site-local"), + P_("Whether this is a site-local multicast address"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_inet_address_init (GInetAddress *address) +{ + address->priv = g_inet_address_get_instance_private (address); +} + +/** + * g_inet_address_new_from_string: + * @string: a string representation of an IP address + * + * Parses @string as an IP address and creates a new #GInetAddress. + * + * Returns: (nullable) (transfer full): a new #GInetAddress corresponding + * to @string, or %NULL if @string could not be parsed. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GInetAddress * +g_inet_address_new_from_string (const gchar *string) +{ + struct in_addr in_addr; +#ifdef HAVE_IPV6 + struct in6_addr in6_addr; +#endif + + g_return_val_if_fail (string != NULL, NULL); + + /* If this GInetAddress is the first networking-related object to be + * created, then we won't have called g_networking_init() yet at + * this point. + */ + g_networking_init (); + + if (inet_pton (AF_INET, string, &in_addr) > 0) + return g_inet_address_new_from_bytes ((guint8 *)&in_addr, AF_INET); +#ifdef HAVE_IPV6 + else if (inet_pton (AF_INET6, string, &in6_addr) > 0) + return g_inet_address_new_from_bytes ((guint8 *)&in6_addr, AF_INET6); +#endif + + return NULL; +} + +#define G_INET_ADDRESS_FAMILY_IS_VALID(family) ((family) == AF_INET || (family) == AF_INET6) + +/** + * g_inet_address_new_from_bytes: + * @bytes: (array) (element-type guint8): raw address data + * @family: the address family of @bytes + * + * Creates a new #GInetAddress from the given @family and @bytes. + * @bytes should be 4 bytes for %G_SOCKET_FAMILY_IPV4 and 16 bytes for + * %G_SOCKET_FAMILY_IPV6. + * + * Returns: a new #GInetAddress corresponding to @family and @bytes. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GInetAddress * +g_inet_address_new_from_bytes (const guint8 *bytes, + GSocketFamily family) +{ + g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL); + + return g_object_new (G_TYPE_INET_ADDRESS, + "family", family, + "bytes", bytes, + NULL); +} + +/** + * g_inet_address_new_loopback: + * @family: the address family + * + * Creates a #GInetAddress for the loopback address for @family. + * + * Returns: a new #GInetAddress corresponding to the loopback address + * for @family. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GInetAddress * +g_inet_address_new_loopback (GSocketFamily family) +{ + g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL); + + if (family == AF_INET) + { + guint8 addr[4] = {127, 0, 0, 1}; + + return g_inet_address_new_from_bytes (addr, family); + } + else +#ifdef HAVE_IPV6 + return g_inet_address_new_from_bytes (in6addr_loopback.s6_addr, family); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_new_any: + * @family: the address family + * + * Creates a #GInetAddress for the "any" address (unassigned/"don't + * care") for @family. + * + * Returns: a new #GInetAddress corresponding to the "any" address + * for @family. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GInetAddress * +g_inet_address_new_any (GSocketFamily family) +{ + g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL); + + if (family == AF_INET) + { + guint8 addr[4] = {0, 0, 0, 0}; + + return g_inet_address_new_from_bytes (addr, family); + } + else +#ifdef HAVE_IPV6 + return g_inet_address_new_from_bytes (in6addr_any.s6_addr, family); +#else + g_assert_not_reached (); +#endif +} + + +/** + * g_inet_address_to_string: + * @address: a #GInetAddress + * + * Converts @address to string form. + * + * Returns: a representation of @address as a string, which should be + * freed after use. + * + * Since: 2.22 + */ +gchar * +g_inet_address_to_string (GInetAddress *address) +{ + gchar buffer[INET6_ADDRSTRLEN]; + + g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL); + + if (address->priv->family == AF_INET) + { + inet_ntop (AF_INET, &address->priv->addr.ipv4, buffer, sizeof (buffer)); + return g_strdup (buffer); + } + else + { +#ifdef HAVE_IPV6 + inet_ntop (AF_INET6, &address->priv->addr.ipv6, buffer, sizeof (buffer)); + return g_strdup (buffer); +#else + g_assert_not_reached (); +#endif + } +} + +/** + * g_inet_address_to_bytes: (skip) + * @address: a #GInetAddress + * + * Gets the raw binary address data from @address. + * + * Returns: a pointer to an internal array of the bytes in @address, + * which should not be modified, stored, or freed. The size of this + * array can be gotten with g_inet_address_get_native_size(). + * + * Since: 2.22 + */ +const guint8 * +g_inet_address_to_bytes (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL); + + return (guint8 *)&address->priv->addr; +} + +/** + * g_inet_address_get_native_size: + * @address: a #GInetAddress + * + * Gets the size of the native raw binary address for @address. This + * is the size of the data that you get from g_inet_address_to_bytes(). + * + * Returns: the number of bytes used for the native version of @address. + * + * Since: 2.22 + */ +gsize +g_inet_address_get_native_size (GInetAddress *address) +{ + if (address->priv->family == AF_INET) + return sizeof (address->priv->addr.ipv4); +#ifdef HAVE_IPV6 + return sizeof (address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_family: + * @address: a #GInetAddress + * + * Gets @address's family + * + * Returns: @address's family + * + * Since: 2.22 + */ +GSocketFamily +g_inet_address_get_family (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + return address->priv->family; +} + +/** + * g_inet_address_get_is_any: + * @address: a #GInetAddress + * + * Tests whether @address is the "any" address for its family. + * + * Returns: %TRUE if @address is the "any" address for its family. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_any (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + { + guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr); + + return addr4 == INADDR_ANY; + } + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_UNSPECIFIED (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_loopback: + * @address: a #GInetAddress + * + * Tests whether @address is the loopback address for its family. + * + * Returns: %TRUE if @address is the loopback address for its family. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_loopback (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + { + guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr); + + /* 127.0.0.0/8 */ + return ((addr4 & 0xff000000) == 0x7f000000); + } + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_LOOPBACK (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_link_local: + * @address: a #GInetAddress + * + * Tests whether @address is a link-local address (that is, if it + * identifies a host on a local network that is not connected to the + * Internet). + * + * Returns: %TRUE if @address is a link-local address. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_link_local (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + { + guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr); + + /* 169.254.0.0/16 */ + return ((addr4 & 0xffff0000) == 0xa9fe0000); + } + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_LINKLOCAL (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_site_local: + * @address: a #GInetAddress + * + * Tests whether @address is a site-local address such as 10.0.0.1 + * (that is, the address identifies a host on a local network that can + * not be reached directly from the Internet, but which may have + * outgoing Internet connectivity via a NAT or firewall). + * + * Returns: %TRUE if @address is a site-local address. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_site_local (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + { + guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr); + + /* 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 */ + return ((addr4 & 0xff000000) == 0x0a000000 || + (addr4 & 0xfff00000) == 0xac100000 || + (addr4 & 0xffff0000) == 0xc0a80000); + } + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_SITELOCAL (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_multicast: + * @address: a #GInetAddress + * + * Tests whether @address is a multicast address. + * + * Returns: %TRUE if @address is a multicast address. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_multicast (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + { + guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr); + + return IN_MULTICAST (addr4); + } + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_MULTICAST (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_mc_global: + * @address: a #GInetAddress + * + * Tests whether @address is a global multicast address. + * + * Returns: %TRUE if @address is a global multicast address. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_mc_global (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + return FALSE; + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_MC_GLOBAL (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_mc_link_local: + * @address: a #GInetAddress + * + * Tests whether @address is a link-local multicast address. + * + * Returns: %TRUE if @address is a link-local multicast address. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_mc_link_local (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + return FALSE; + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_MC_LINKLOCAL (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_mc_node_local: + * @address: a #GInetAddress + * + * Tests whether @address is a node-local multicast address. + * + * Returns: %TRUE if @address is a node-local multicast address. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_mc_node_local (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + return FALSE; + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_MC_NODELOCAL (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_mc_org_local: + * @address: a #GInetAddress + * + * Tests whether @address is an organization-local multicast address. + * + * Returns: %TRUE if @address is an organization-local multicast address. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_mc_org_local (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + return FALSE; + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_MC_ORGLOCAL (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_get_is_mc_site_local: + * @address: a #GInetAddress + * + * Tests whether @address is a site-local multicast address. + * + * Returns: %TRUE if @address is a site-local multicast address. + * + * Since: 2.22 + */ +gboolean +g_inet_address_get_is_mc_site_local (GInetAddress *address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (address->priv->family == AF_INET) + return FALSE; + else +#ifdef HAVE_IPV6 + return IN6_IS_ADDR_MC_SITELOCAL (&address->priv->addr.ipv6); +#else + g_assert_not_reached (); +#endif +} + +/** + * g_inet_address_equal: + * @address: A #GInetAddress. + * @other_address: Another #GInetAddress. + * + * Checks if two #GInetAddress instances are equal, e.g. the same address. + * + * Returns: %TRUE if @address and @other_address are equal, %FALSE otherwise. + * + * Since: 2.30 + */ +gboolean +g_inet_address_equal (GInetAddress *address, + GInetAddress *other_address) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + g_return_val_if_fail (G_IS_INET_ADDRESS (other_address), FALSE); + + if (g_inet_address_get_family (address) != g_inet_address_get_family (other_address)) + return FALSE; + + if (memcmp (g_inet_address_to_bytes (address), + g_inet_address_to_bytes (other_address), + g_inet_address_get_native_size (address)) != 0) + return FALSE; + + return TRUE; +} diff --git a/gio/ginetaddress.h b/gio/ginetaddress.h new file mode 100644 index 0000000..87bb4e5 --- /dev/null +++ b/gio/ginetaddress.h @@ -0,0 +1,123 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#ifndef __G_INET_ADDRESS_H__ +#define __G_INET_ADDRESS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_INET_ADDRESS (g_inet_address_get_type ()) +#define G_INET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_INET_ADDRESS, GInetAddress)) +#define G_INET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_INET_ADDRESS, GInetAddressClass)) +#define G_IS_INET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_INET_ADDRESS)) +#define G_IS_INET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_INET_ADDRESS)) +#define G_INET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_INET_ADDRESS, GInetAddressClass)) + +typedef struct _GInetAddressClass GInetAddressClass; +typedef struct _GInetAddressPrivate GInetAddressPrivate; + +struct _GInetAddress +{ + GObject parent_instance; + + /*< private >*/ + GInetAddressPrivate *priv; +}; + +struct _GInetAddressClass +{ + GObjectClass parent_class; + + gchar * (*to_string) (GInetAddress *address); + const guint8 * (*to_bytes) (GInetAddress *address); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_inet_address_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GInetAddress * g_inet_address_new_from_string (const gchar *string); + +GLIB_AVAILABLE_IN_ALL +GInetAddress * g_inet_address_new_from_bytes (const guint8 *bytes, + GSocketFamily family); + +GLIB_AVAILABLE_IN_ALL +GInetAddress * g_inet_address_new_loopback (GSocketFamily family); + +GLIB_AVAILABLE_IN_ALL +GInetAddress * g_inet_address_new_any (GSocketFamily family); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_equal (GInetAddress *address, + GInetAddress *other_address); + +GLIB_AVAILABLE_IN_ALL +gchar * g_inet_address_to_string (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +const guint8 * g_inet_address_to_bytes (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gsize g_inet_address_get_native_size (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +GSocketFamily g_inet_address_get_family (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_any (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_loopback (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_link_local (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_site_local (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_multicast (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_mc_global (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_mc_link_local (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_mc_node_local (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_mc_org_local (GInetAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_inet_address_get_is_mc_site_local (GInetAddress *address); + +G_END_DECLS + +#endif /* __G_INET_ADDRESS_H__ */ diff --git a/gio/ginetaddressmask.c b/gio/ginetaddressmask.c new file mode 100644 index 0000000..058595e --- /dev/null +++ b/gio/ginetaddressmask.c @@ -0,0 +1,473 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +#include +#include + +#include "ginetaddressmask.h" +#include "ginetaddress.h" +#include "ginitable.h" +#include "gioerror.h" +#include "gioenumtypes.h" +#include "glibintl.h" + +/** + * SECTION:ginetaddressmask + * @short_description: An IPv4/IPv6 address mask + * @include: gio/gio.h + * + * #GInetAddressMask represents a range of IPv4 or IPv6 addresses + * described by a base address and a length indicating how many bits + * of the base address are relevant for matching purposes. These are + * often given in string form. Eg, "10.0.0.0/8", or "fe80::/10". + */ + +/** + * GInetAddressMask: + * + * A combination of an IPv4 or IPv6 base address and a length, + * representing a range of IP addresses. + * + * Since: 2.32 + */ + +struct _GInetAddressMaskPrivate +{ + GInetAddress *addr; + guint length; +}; + +static void g_inet_address_mask_initable_iface_init (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GInetAddressMask, g_inet_address_mask, G_TYPE_OBJECT, + G_ADD_PRIVATE (GInetAddressMask) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_inet_address_mask_initable_iface_init)) + +enum +{ + PROP_0, + PROP_FAMILY, + PROP_ADDRESS, + PROP_LENGTH +}; + +static void +g_inet_address_mask_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GInetAddressMask *mask = G_INET_ADDRESS_MASK (object); + + switch (prop_id) + { + case PROP_ADDRESS: + if (mask->priv->addr) + g_object_unref (mask->priv->addr); + mask->priv->addr = g_value_dup_object (value); + break; + + case PROP_LENGTH: + mask->priv->length = g_value_get_uint (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_inet_address_mask_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GInetAddressMask *mask = G_INET_ADDRESS_MASK (object); + + switch (prop_id) + { + case PROP_FAMILY: + g_value_set_enum (value, g_inet_address_get_family (mask->priv->addr)); + break; + + case PROP_ADDRESS: + g_value_set_object (value, mask->priv->addr); + break; + + case PROP_LENGTH: + g_value_set_uint (value, mask->priv->length); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_inet_address_mask_dispose (GObject *object) +{ + GInetAddressMask *mask = G_INET_ADDRESS_MASK (object); + + g_clear_object (&mask->priv->addr); + + G_OBJECT_CLASS (g_inet_address_mask_parent_class)->dispose (object); +} + +static void +g_inet_address_mask_class_init (GInetAddressMaskClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = g_inet_address_mask_set_property; + gobject_class->get_property = g_inet_address_mask_get_property; + gobject_class->dispose = g_inet_address_mask_dispose; + + g_object_class_install_property (gobject_class, PROP_FAMILY, + g_param_spec_enum ("family", + P_("Address family"), + P_("The address family (IPv4 or IPv6)"), + G_TYPE_SOCKET_FAMILY, + G_SOCKET_FAMILY_INVALID, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_ADDRESS, + g_param_spec_object ("address", + P_("Address"), + P_("The base address"), + G_TYPE_INET_ADDRESS, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_LENGTH, + g_param_spec_uint ("length", + P_("Length"), + P_("The prefix length"), + 0, 128, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static gboolean +g_inet_address_mask_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GInetAddressMask *mask = G_INET_ADDRESS_MASK (initable); + guint addrlen, nbytes, nbits; + const guint8 *bytes; + gboolean ok; + + if (!mask->priv->addr) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("No address specified")); + return FALSE; + } + + addrlen = g_inet_address_get_native_size (mask->priv->addr); + if (mask->priv->length > addrlen * 8) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Length %u is too long for address"), + mask->priv->length); + return FALSE; + } + + /* Make sure all the bits after @length are 0 */ + bytes = g_inet_address_to_bytes (mask->priv->addr); + ok = TRUE; + + nbytes = mask->priv->length / 8; + bytes += nbytes; + addrlen -= nbytes; + + nbits = mask->priv->length % 8; + if (nbits) + { + if (bytes[0] & (0xFF >> nbits)) + ok = FALSE; + bytes++; + addrlen--; + } + + while (addrlen) + { + if (bytes[0]) + ok = FALSE; + bytes++; + addrlen--; + } + + if (!ok) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Address has bits set beyond prefix length")); + return FALSE; + } + + return TRUE; +} + +static void +g_inet_address_mask_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_inet_address_mask_initable_init; +} + +static void +g_inet_address_mask_init (GInetAddressMask *mask) +{ + mask->priv = g_inet_address_mask_get_instance_private (mask); +} + +/** + * g_inet_address_mask_new: + * @addr: a #GInetAddress + * @length: number of bits of @addr to use + * @error: return location for #GError, or %NULL + * + * Creates a new #GInetAddressMask representing all addresses whose + * first @length bits match @addr. + * + * Returns: a new #GInetAddressMask, or %NULL on error + * + * Since: 2.32 + */ +GInetAddressMask * +g_inet_address_mask_new (GInetAddress *addr, + guint length, + GError **error) +{ + return g_initable_new (G_TYPE_INET_ADDRESS_MASK, NULL, error, + "address", addr, + "length", length, + NULL); +} + +/** + * g_inet_address_mask_new_from_string: + * @mask_string: an IP address or address/length string + * @error: return location for #GError, or %NULL + * + * Parses @mask_string as an IP address and (optional) length, and + * creates a new #GInetAddressMask. The length, if present, is + * delimited by a "/". If it is not present, then the length is + * assumed to be the full length of the address. + * + * Returns: a new #GInetAddressMask corresponding to @string, or %NULL + * on error. + * + * Since: 2.32 + */ +GInetAddressMask * +g_inet_address_mask_new_from_string (const gchar *mask_string, + GError **error) +{ + GInetAddressMask *mask; + GInetAddress *addr; + gchar *slash; + guint length; + + slash = strchr (mask_string, '/'); + if (slash) + { + gchar *address, *end; + + length = strtoul (slash + 1, &end, 10); + if (*end || !*(slash + 1)) + { + parse_error: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Could not parse “%s†as IP address mask"), + mask_string); + return NULL; + } + + address = g_strndup (mask_string, slash - mask_string); + addr = g_inet_address_new_from_string (address); + g_free (address); + + if (!addr) + goto parse_error; + } + else + { + addr = g_inet_address_new_from_string (mask_string); + if (!addr) + goto parse_error; + + length = g_inet_address_get_native_size (addr) * 8; + } + + mask = g_inet_address_mask_new (addr, length, error); + g_object_unref (addr); + + return mask; +} + +/** + * g_inet_address_mask_to_string: + * @mask: a #GInetAddressMask + * + * Converts @mask back to its corresponding string form. + * + * Returns: a string corresponding to @mask. + * + * Since: 2.32 + */ +gchar * +g_inet_address_mask_to_string (GInetAddressMask *mask) +{ + gchar *addr_string, *mask_string; + + g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), NULL); + + addr_string = g_inet_address_to_string (mask->priv->addr); + + if (mask->priv->length == (g_inet_address_get_native_size (mask->priv->addr) * 8)) + return addr_string; + + mask_string = g_strdup_printf ("%s/%u", addr_string, mask->priv->length); + g_free (addr_string); + + return mask_string; +} + +/** + * g_inet_address_mask_get_family: + * @mask: a #GInetAddressMask + * + * Gets the #GSocketFamily of @mask's address + * + * Returns: the #GSocketFamily of @mask's address + * + * Since: 2.32 + */ +GSocketFamily +g_inet_address_mask_get_family (GInetAddressMask *mask) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), G_SOCKET_FAMILY_INVALID); + + return g_inet_address_get_family (mask->priv->addr); +} + +/** + * g_inet_address_mask_get_address: + * @mask: a #GInetAddressMask + * + * Gets @mask's base address + * + * Returns: (transfer none): @mask's base address + * + * Since: 2.32 + */ +GInetAddress * +g_inet_address_mask_get_address (GInetAddressMask *mask) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), NULL); + + return mask->priv->addr; +} + +/** + * g_inet_address_mask_get_length: + * @mask: a #GInetAddressMask + * + * Gets @mask's length + * + * Returns: @mask's length + * + * Since: 2.32 + */ +guint +g_inet_address_mask_get_length (GInetAddressMask *mask) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), 0); + + return mask->priv->length; +} + +/** + * g_inet_address_mask_matches: + * @mask: a #GInetAddressMask + * @address: a #GInetAddress + * + * Tests if @address falls within the range described by @mask. + * + * Returns: whether @address falls within the range described by + * @mask. + * + * Since: 2.32 + */ +gboolean +g_inet_address_mask_matches (GInetAddressMask *mask, + GInetAddress *address) +{ + const guint8 *maskbytes, *addrbytes; + int nbytes, nbits; + + g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), FALSE); + g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); + + if (g_inet_address_get_family (mask->priv->addr) != + g_inet_address_get_family (address)) + return FALSE; + + if (mask->priv->length == 0) + return TRUE; + + maskbytes = g_inet_address_to_bytes (mask->priv->addr); + addrbytes = g_inet_address_to_bytes (address); + + nbytes = mask->priv->length / 8; + if (nbytes != 0 && memcmp (maskbytes, addrbytes, nbytes) != 0) + return FALSE; + + nbits = mask->priv->length % 8; + if (nbits == 0) + return TRUE; + + return maskbytes[nbytes] == (addrbytes[nbytes] & (0xFF << (8 - nbits))); +} + + +/** + * g_inet_address_mask_equal: + * @mask: a #GInetAddressMask + * @mask2: another #GInetAddressMask + * + * Tests if @mask and @mask2 are the same mask. + * + * Returns: whether @mask and @mask2 are the same mask + * + * Since: 2.32 + */ +gboolean +g_inet_address_mask_equal (GInetAddressMask *mask, + GInetAddressMask *mask2) +{ + g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), FALSE); + g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask2), FALSE); + + return ((mask->priv->length == mask2->priv->length) && + g_inet_address_equal (mask->priv->addr, mask2->priv->addr)); +} diff --git a/gio/ginetaddressmask.h b/gio/ginetaddressmask.h new file mode 100644 index 0000000..1e73281 --- /dev/null +++ b/gio/ginetaddressmask.h @@ -0,0 +1,84 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_INET_ADDRESS_MASK_H__ +#define __G_INET_ADDRESS_MASK_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_INET_ADDRESS_MASK (g_inet_address_mask_get_type ()) +#define G_INET_ADDRESS_MASK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_INET_ADDRESS_MASK, GInetAddressMask)) +#define G_INET_ADDRESS_MASK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_INET_ADDRESS_MASK, GInetAddressMaskClass)) +#define G_IS_INET_ADDRESS_MASK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_INET_ADDRESS_MASK)) +#define G_IS_INET_ADDRESS_MASK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_INET_ADDRESS_MASK)) +#define G_INET_ADDRESS_MASK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_INET_ADDRESS_MASK, GInetAddressMaskClass)) + +typedef struct _GInetAddressMaskClass GInetAddressMaskClass; +typedef struct _GInetAddressMaskPrivate GInetAddressMaskPrivate; + +struct _GInetAddressMask +{ + GObject parent_instance; + + /*< private >*/ + GInetAddressMaskPrivate *priv; +}; + +struct _GInetAddressMaskClass +{ + GObjectClass parent_class; + +}; + +GLIB_AVAILABLE_IN_2_32 +GType g_inet_address_mask_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +GInetAddressMask *g_inet_address_mask_new (GInetAddress *addr, + guint length, + GError **error); + +GLIB_AVAILABLE_IN_2_32 +GInetAddressMask *g_inet_address_mask_new_from_string (const gchar *mask_string, + GError **error); +GLIB_AVAILABLE_IN_2_32 +gchar *g_inet_address_mask_to_string (GInetAddressMask *mask); + +GLIB_AVAILABLE_IN_2_32 +GSocketFamily g_inet_address_mask_get_family (GInetAddressMask *mask); +GLIB_AVAILABLE_IN_2_32 +GInetAddress *g_inet_address_mask_get_address (GInetAddressMask *mask); +GLIB_AVAILABLE_IN_2_32 +guint g_inet_address_mask_get_length (GInetAddressMask *mask); + +GLIB_AVAILABLE_IN_2_32 +gboolean g_inet_address_mask_matches (GInetAddressMask *mask, + GInetAddress *address); +GLIB_AVAILABLE_IN_2_32 +gboolean g_inet_address_mask_equal (GInetAddressMask *mask, + GInetAddressMask *mask2); + +G_END_DECLS + +#endif /* __G_INET_ADDRESS_MASK_H__ */ diff --git a/gio/ginetsocketaddress.c b/gio/ginetsocketaddress.c new file mode 100644 index 0000000..d7c8134 --- /dev/null +++ b/gio/ginetsocketaddress.c @@ -0,0 +1,543 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#include +#include +#include + +#include "ginetsocketaddress.h" +#include "ginetaddress.h" +#include "gnetworkingprivate.h" +#include "gsocketconnectable.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:ginetsocketaddress + * @short_description: Internet GSocketAddress + * @include: gio/gio.h + * + * An IPv4 or IPv6 socket address; that is, the combination of a + * #GInetAddress and a port number. + */ + +/** + * GInetSocketAddress: + * + * An IPv4 or IPv6 socket address, corresponding to a struct + * sockaddr_in or struct sockaddr_in6. + */ + +struct _GInetSocketAddressPrivate +{ + GInetAddress *address; + guint16 port; + guint32 flowinfo; + guint32 scope_id; +}; + +static void g_inet_socket_address_connectable_iface_init (GSocketConnectableIface *iface); +static gchar *g_inet_socket_address_connectable_to_string (GSocketConnectable *connectable); + +G_DEFINE_TYPE_WITH_CODE (GInetSocketAddress, g_inet_socket_address, G_TYPE_SOCKET_ADDRESS, + G_ADD_PRIVATE (GInetSocketAddress) + G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE, + g_inet_socket_address_connectable_iface_init)) + +enum { + PROP_0, + PROP_ADDRESS, + PROP_PORT, + PROP_FLOWINFO, + PROP_SCOPE_ID +}; + +static void +g_inet_socket_address_dispose (GObject *object) +{ + GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object); + + g_clear_object (&(address->priv->address)); + + G_OBJECT_CLASS (g_inet_socket_address_parent_class)->dispose (object); +} + +static void +g_inet_socket_address_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object); + + switch (prop_id) + { + case PROP_ADDRESS: + g_value_set_object (value, address->priv->address); + break; + + case PROP_PORT: + g_value_set_uint (value, address->priv->port); + break; + + case PROP_FLOWINFO: + g_return_if_fail (g_inet_address_get_family (address->priv->address) == G_SOCKET_FAMILY_IPV6); + g_value_set_uint (value, address->priv->flowinfo); + break; + + case PROP_SCOPE_ID: + g_return_if_fail (g_inet_address_get_family (address->priv->address) == G_SOCKET_FAMILY_IPV6); + g_value_set_uint (value, address->priv->scope_id); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_inet_socket_address_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object); + + switch (prop_id) + { + case PROP_ADDRESS: + address->priv->address = g_object_ref (g_value_get_object (value)); + break; + + case PROP_PORT: + address->priv->port = (guint16) g_value_get_uint (value); + break; + + case PROP_FLOWINFO: + /* We can't test that address->priv->address is IPv6 here, + * since this property might get set before PROP_ADDRESS. + */ + address->priv->flowinfo = g_value_get_uint (value); + break; + + case PROP_SCOPE_ID: + address->priv->scope_id = g_value_get_uint (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static GSocketFamily +g_inet_socket_address_get_family (GSocketAddress *address) +{ + GInetSocketAddress *addr; + + g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0); + + addr = G_INET_SOCKET_ADDRESS (address); + + return g_inet_address_get_family (addr->priv->address); +} + +static gssize +g_inet_socket_address_get_native_size (GSocketAddress *address) +{ + GInetSocketAddress *addr; + GSocketFamily family; + + g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0); + + addr = G_INET_SOCKET_ADDRESS (address); + family = g_inet_address_get_family (addr->priv->address); + + if (family == AF_INET) + return sizeof (struct sockaddr_in); + else if (family == AF_INET6) + return sizeof (struct sockaddr_in6); + else + return -1; +} + +static gboolean +g_inet_socket_address_to_native (GSocketAddress *address, + gpointer dest, + gsize destlen, + GError **error) +{ + GInetSocketAddress *addr; + GSocketFamily family; + + g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), FALSE); + + addr = G_INET_SOCKET_ADDRESS (address); + family = g_inet_address_get_family (addr->priv->address); + + if (family == AF_INET) + { + struct sockaddr_in *sock = (struct sockaddr_in *) dest; + + if (destlen < sizeof (*sock)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, + _("Not enough space for socket address")); + return FALSE; + } + + sock->sin_family = AF_INET; + sock->sin_port = g_htons (addr->priv->port); + memcpy (&(sock->sin_addr.s_addr), g_inet_address_to_bytes (addr->priv->address), sizeof (sock->sin_addr)); + memset (sock->sin_zero, 0, sizeof (sock->sin_zero)); + return TRUE; + } + else if (family == AF_INET6) + { + struct sockaddr_in6 *sock = (struct sockaddr_in6 *) dest; + + if (destlen < sizeof (*sock)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, + _("Not enough space for socket address")); + return FALSE; + } + + memset (sock, 0, sizeof (*sock)); + sock->sin6_family = AF_INET6; + sock->sin6_port = g_htons (addr->priv->port); + sock->sin6_flowinfo = addr->priv->flowinfo; + sock->sin6_scope_id = addr->priv->scope_id; + memcpy (&(sock->sin6_addr.s6_addr), g_inet_address_to_bytes (addr->priv->address), sizeof (sock->sin6_addr)); + return TRUE; + } + else + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Unsupported socket address")); + return FALSE; + } +} + +static void +g_inet_socket_address_class_init (GInetSocketAddressClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass); + + gobject_class->dispose = g_inet_socket_address_dispose; + gobject_class->set_property = g_inet_socket_address_set_property; + gobject_class->get_property = g_inet_socket_address_get_property; + + gsocketaddress_class->get_family = g_inet_socket_address_get_family; + gsocketaddress_class->to_native = g_inet_socket_address_to_native; + gsocketaddress_class->get_native_size = g_inet_socket_address_get_native_size; + + g_object_class_install_property (gobject_class, PROP_ADDRESS, + g_param_spec_object ("address", + P_("Address"), + P_("The address"), + G_TYPE_INET_ADDRESS, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_PORT, + g_param_spec_uint ("port", + P_("Port"), + P_("The port"), + 0, + 65535, + 0, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetSocketAddress:flowinfo: + * + * The `sin6_flowinfo` field, for IPv6 addresses. + * + * Since: 2.32 + */ + g_object_class_install_property (gobject_class, PROP_FLOWINFO, + g_param_spec_uint ("flowinfo", + P_("Flow info"), + P_("IPv6 flow info"), + 0, + G_MAXUINT32, + 0, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GInetSocketAddress:scope_id: + * + * The `sin6_scope_id` field, for IPv6 addresses. + * + * Since: 2.32 + */ + g_object_class_install_property (gobject_class, PROP_SCOPE_ID, + g_param_spec_uint ("scope-id", + P_("Scope ID"), + P_("IPv6 scope ID"), + 0, + G_MAXUINT32, + 0, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_inet_socket_address_connectable_iface_init (GSocketConnectableIface *iface) +{ + GSocketConnectableIface *parent_iface = g_type_interface_peek_parent (iface); + + iface->enumerate = parent_iface->enumerate; + iface->proxy_enumerate = parent_iface->proxy_enumerate; + iface->to_string = g_inet_socket_address_connectable_to_string; +} + +static gchar * +g_inet_socket_address_connectable_to_string (GSocketConnectable *connectable) +{ + GInetSocketAddress *sa; + GInetAddress *a; + gchar *a_string; + GString *out; + guint16 port; + + sa = G_INET_SOCKET_ADDRESS (connectable); + a = g_inet_socket_address_get_address (sa); + out = g_string_new (""); + + /* Address. */ + a_string = g_inet_address_to_string (a); + g_string_append (out, a_string); + g_free (a_string); + + /* Scope ID (IPv6 only). */ + if (g_inet_address_get_family (a) == G_SOCKET_FAMILY_IPV6 && + g_inet_socket_address_get_scope_id (sa) != 0) + { + g_string_append_printf (out, "%%%u", + g_inet_socket_address_get_scope_id (sa)); + } + + /* Port. */ + port = g_inet_socket_address_get_port (sa); + if (port != 0) + { + /* Disambiguate ports from IPv6 addresses using square brackets. */ + if (g_inet_address_get_family (a) == G_SOCKET_FAMILY_IPV6) + { + g_string_prepend (out, "["); + g_string_append (out, "]"); + } + + g_string_append_printf (out, ":%u", port); + } + + return g_string_free (out, FALSE); +} + +static void +g_inet_socket_address_init (GInetSocketAddress *address) +{ + address->priv = g_inet_socket_address_get_instance_private (address); +} + +/** + * g_inet_socket_address_new: + * @address: a #GInetAddress + * @port: a port number + * + * Creates a new #GInetSocketAddress for @address and @port. + * + * Returns: a new #GInetSocketAddress + * + * Since: 2.22 + */ +GSocketAddress * +g_inet_socket_address_new (GInetAddress *address, + guint16 port) +{ + return g_object_new (G_TYPE_INET_SOCKET_ADDRESS, + "address", address, + "port", port, + NULL); +} + +/** + * g_inet_socket_address_new_from_string: + * @address: the string form of an IP address + * @port: a port number + * + * Creates a new #GInetSocketAddress for @address and @port. + * + * If @address is an IPv6 address, it can also contain a scope ID + * (separated from the address by a `%`). + * + * Returns: (nullable) (transfer full): a new #GInetSocketAddress, + * or %NULL if @address cannot be parsed. + * + * Since: 2.40 + */ +GSocketAddress * +g_inet_socket_address_new_from_string (const char *address, + guint port) +{ + static struct addrinfo *hints, hints_struct; + GSocketAddress *saddr; + GInetAddress *iaddr; + struct addrinfo *res; + gint status; + + if (strchr (address, ':')) + { + /* IPv6 address (or it's invalid). We use getaddrinfo() because + * it will handle parsing a scope_id as well. + */ + + if (G_UNLIKELY (g_once_init_enter (&hints))) + { + hints_struct.ai_family = AF_UNSPEC; + hints_struct.ai_socktype = SOCK_STREAM; + hints_struct.ai_protocol = 0; + hints_struct.ai_flags = AI_NUMERICHOST; + g_once_init_leave (&hints, &hints_struct); + } + + status = getaddrinfo (address, NULL, hints, &res); + if (status != 0) + return NULL; + + if (res->ai_family == AF_INET6 && + res->ai_addrlen == sizeof (struct sockaddr_in6)) + { + ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = g_htons (port); + saddr = g_socket_address_new_from_native (res->ai_addr, res->ai_addrlen); + } + else + saddr = NULL; + + freeaddrinfo (res); + } + else + { + /* IPv4 (or invalid). We don't want to use getaddrinfo() here, + * because it accepts the stupid "IPv4 numbers-and-dots + * notation" addresses that are never used for anything except + * phishing. Since we don't have to worry about scope IDs for + * IPv4, we can just use g_inet_address_new_from_string(). + */ + iaddr = g_inet_address_new_from_string (address); + if (!iaddr) + return NULL; + + g_warn_if_fail (g_inet_address_get_family (iaddr) == G_SOCKET_FAMILY_IPV4); + + saddr = g_inet_socket_address_new (iaddr, port); + g_object_unref (iaddr); + } + + return saddr; +} + +/** + * g_inet_socket_address_get_address: + * @address: a #GInetSocketAddress + * + * Gets @address's #GInetAddress. + * + * Returns: (transfer none): the #GInetAddress for @address, which must be + * g_object_ref()'d if it will be stored + * + * Since: 2.22 + */ +GInetAddress * +g_inet_socket_address_get_address (GInetSocketAddress *address) +{ + g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), NULL); + + return address->priv->address; +} + +/** + * g_inet_socket_address_get_port: + * @address: a #GInetSocketAddress + * + * Gets @address's port. + * + * Returns: the port for @address + * + * Since: 2.22 + */ +guint16 +g_inet_socket_address_get_port (GInetSocketAddress *address) +{ + g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0); + + return address->priv->port; +} + + +/** + * g_inet_socket_address_get_flowinfo: + * @address: a %G_SOCKET_FAMILY_IPV6 #GInetSocketAddress + * + * Gets the `sin6_flowinfo` field from @address, + * which must be an IPv6 address. + * + * Returns: the flowinfo field + * + * Since: 2.32 + */ +guint32 +g_inet_socket_address_get_flowinfo (GInetSocketAddress *address) +{ + g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0); + g_return_val_if_fail (g_inet_address_get_family (address->priv->address) == G_SOCKET_FAMILY_IPV6, 0); + + return address->priv->flowinfo; +} + +/** + * g_inet_socket_address_get_scope_id: + * @address: a %G_SOCKET_FAMILY_IPV6 #GInetAddress + * + * Gets the `sin6_scope_id` field from @address, + * which must be an IPv6 address. + * + * Returns: the scope id field + * + * Since: 2.32 + */ +guint32 +g_inet_socket_address_get_scope_id (GInetSocketAddress *address) +{ + g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0); + g_return_val_if_fail (g_inet_address_get_family (address->priv->address) == G_SOCKET_FAMILY_IPV6, 0); + + return address->priv->scope_id; +} diff --git a/gio/ginetsocketaddress.h b/gio/ginetsocketaddress.h new file mode 100644 index 0000000..e05ba09 --- /dev/null +++ b/gio/ginetsocketaddress.h @@ -0,0 +1,78 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#ifndef __G_INET_SOCKET_ADDRESS_H__ +#define __G_INET_SOCKET_ADDRESS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_INET_SOCKET_ADDRESS (g_inet_socket_address_get_type ()) +#define G_INET_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_INET_SOCKET_ADDRESS, GInetSocketAddress)) +#define G_INET_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_INET_SOCKET_ADDRESS, GInetSocketAddressClass)) +#define G_IS_INET_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_INET_SOCKET_ADDRESS)) +#define G_IS_INET_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_INET_SOCKET_ADDRESS)) +#define G_INET_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_INET_SOCKET_ADDRESS, GInetSocketAddressClass)) + +typedef struct _GInetSocketAddressClass GInetSocketAddressClass; +typedef struct _GInetSocketAddressPrivate GInetSocketAddressPrivate; + +struct _GInetSocketAddress +{ + GSocketAddress parent_instance; + + /*< private >*/ + GInetSocketAddressPrivate *priv; +}; + +struct _GInetSocketAddressClass +{ + GSocketAddressClass parent_class; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_inet_socket_address_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_inet_socket_address_new (GInetAddress *address, + guint16 port); +GLIB_AVAILABLE_IN_2_40 +GSocketAddress *g_inet_socket_address_new_from_string (const char *address, + guint port); + +GLIB_AVAILABLE_IN_ALL +GInetAddress * g_inet_socket_address_get_address (GInetSocketAddress *address); +GLIB_AVAILABLE_IN_ALL +guint16 g_inet_socket_address_get_port (GInetSocketAddress *address); + +GLIB_AVAILABLE_IN_2_32 +guint32 g_inet_socket_address_get_flowinfo (GInetSocketAddress *address); +GLIB_AVAILABLE_IN_2_32 +guint32 g_inet_socket_address_get_scope_id (GInetSocketAddress *address); + +G_END_DECLS + +#endif /* __G_INET_SOCKET_ADDRESS_H__ */ diff --git a/gio/ginitable.c b/gio/ginitable.c new file mode 100644 index 0000000..1670a43 --- /dev/null +++ b/gio/ginitable.c @@ -0,0 +1,255 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "ginitable.h" +#include "glibintl.h" + + +/** + * SECTION:ginitable + * @short_description: Failable object initialization interface + * @include: gio/gio.h + * @see_also: #GAsyncInitable + * + * #GInitable is implemented by objects that can fail during + * initialization. If an object implements this interface then + * it must be initialized as the first thing after construction, + * either via g_initable_init() or g_async_initable_init_async() + * (the latter is only available if it also implements #GAsyncInitable). + * + * If the object is not initialized, or initialization returns with an + * error, then all operations on the object except g_object_ref() and + * g_object_unref() are considered to be invalid, and have undefined + * behaviour. They will often fail with g_critical() or g_warning(), but + * this must not be relied on. + * + * Users of objects implementing this are not intended to use + * the interface method directly, instead it will be used automatically + * in various ways. For C applications you generally just call + * g_initable_new() directly, or indirectly via a foo_thing_new() wrapper. + * This will call g_initable_init() under the cover, returning %NULL and + * setting a #GError on failure (at which point the instance is + * unreferenced). + * + * For bindings in languages where the native constructor supports + * exceptions the binding could check for objects implementing %GInitable + * during normal construction and automatically initialize them, throwing + * an exception on failure. + */ + +typedef GInitableIface GInitableInterface; +G_DEFINE_INTERFACE (GInitable, g_initable, G_TYPE_OBJECT) + +static void +g_initable_default_init (GInitableInterface *iface) +{ +} + +/** + * g_initable_init: + * @initable: a #GInitable. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Initializes the object implementing the interface. + * + * This method is intended for language bindings. If writing in C, + * g_initable_new() should typically be used instead. + * + * The object must be initialized before any real use after initial + * construction, either with this function or g_async_initable_init_async(). + * + * Implementations may also support cancellation. If @cancellable is not %NULL, + * then initialization can be cancelled by triggering the cancellable object + * from another thread. If the operation was cancelled, the error + * %G_IO_ERROR_CANCELLED will be returned. If @cancellable is not %NULL and + * the object doesn't support cancellable initialization the error + * %G_IO_ERROR_NOT_SUPPORTED will be returned. + * + * If the object is not initialized, or initialization returns with an + * error, then all operations on the object except g_object_ref() and + * g_object_unref() are considered to be invalid, and have undefined + * behaviour. See the [introduction][ginitable] for more details. + * + * Callers should not assume that a class which implements #GInitable can be + * initialized multiple times, unless the class explicitly documents itself as + * supporting this. Generally, a class’ implementation of init() can assume + * (and assert) that it will only be called once. Previously, this documentation + * recommended all #GInitable implementations should be idempotent; that + * recommendation was relaxed in GLib 2.54. + * + * If a class explicitly supports being initialized multiple times, it is + * recommended that the method is idempotent: multiple calls with the same + * arguments should return the same results. Only the first call initializes + * the object; further calls return the result of the first call. + * + * One reason why a class might need to support idempotent initialization is if + * it is designed to be used via the singleton pattern, with a + * #GObjectClass.constructor that sometimes returns an existing instance. + * In this pattern, a caller would expect to be able to call g_initable_init() + * on the result of g_object_new(), regardless of whether it is in fact a new + * instance. + * + * Returns: %TRUE if successful. If an error has occurred, this function will + * return %FALSE and set @error appropriately if present. + * + * Since: 2.22 + */ +gboolean +g_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GInitableIface *iface; + + g_return_val_if_fail (G_IS_INITABLE (initable), FALSE); + + iface = G_INITABLE_GET_IFACE (initable); + + return (* iface->init) (initable, cancellable, error); +} + +/** + * g_initable_new: + * @object_type: a #GType supporting #GInitable. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * @first_property_name: (nullable): the name of the first property, or %NULL if no + * properties + * @...: the value if the first property, followed by and other property + * value pairs, and ended by %NULL. + * + * Helper function for constructing #GInitable object. This is + * similar to g_object_new() but also initializes the object + * and returns %NULL, setting an error on failure. + * + * Returns: (type GObject.Object) (transfer full): a newly allocated + * #GObject, or %NULL on error + * + * Since: 2.22 + */ +gpointer +g_initable_new (GType object_type, + GCancellable *cancellable, + GError **error, + const gchar *first_property_name, + ...) +{ + GObject *object; + va_list var_args; + + va_start (var_args, first_property_name); + object = g_initable_new_valist (object_type, + first_property_name, var_args, + cancellable, error); + va_end (var_args); + + return object; +} + +/** + * g_initable_newv: + * @object_type: a #GType supporting #GInitable. + * @n_parameters: the number of parameters in @parameters + * @parameters: (array length=n_parameters): the parameters to use to construct the object + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Helper function for constructing #GInitable object. This is + * similar to g_object_newv() but also initializes the object + * and returns %NULL, setting an error on failure. + * + * Returns: (type GObject.Object) (transfer full): a newly allocated + * #GObject, or %NULL on error + * + * Since: 2.22 + * Deprecated: 2.54: Use g_object_new_with_properties() and + * g_initable_init() instead. See #GParameter for more information. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +gpointer +g_initable_newv (GType object_type, + guint n_parameters, + GParameter *parameters, + GCancellable *cancellable, + GError **error) +{ + GObject *obj; + + g_return_val_if_fail (G_TYPE_IS_INITABLE (object_type), NULL); + + obj = g_object_newv (object_type, n_parameters, parameters); + + if (!g_initable_init (G_INITABLE (obj), cancellable, error)) + { + g_object_unref (obj); + return NULL; + } + + return (gpointer)obj; +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_initable_new_valist: + * @object_type: a #GType supporting #GInitable. + * @first_property_name: the name of the first property, followed by + * the value, and other property value pairs, and ended by %NULL. + * @var_args: The var args list generated from @first_property_name. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Helper function for constructing #GInitable object. This is + * similar to g_object_new_valist() but also initializes the object + * and returns %NULL, setting an error on failure. + * + * Returns: (type GObject.Object) (transfer full): a newly allocated + * #GObject, or %NULL on error + * + * Since: 2.22 + */ +GObject* +g_initable_new_valist (GType object_type, + const gchar *first_property_name, + va_list var_args, + GCancellable *cancellable, + GError **error) +{ + GObject *obj; + + g_return_val_if_fail (G_TYPE_IS_INITABLE (object_type), NULL); + + obj = g_object_new_valist (object_type, + first_property_name, + var_args); + + if (!g_initable_init (G_INITABLE (obj), cancellable, error)) + { + g_object_unref (obj); + return NULL; + } + + return obj; +} diff --git a/gio/ginitable.h b/gio/ginitable.h new file mode 100644 index 0000000..463bfcc --- /dev/null +++ b/gio/ginitable.h @@ -0,0 +1,105 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_INITABLE_H__ +#define __G_INITABLE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_INITABLE (g_initable_get_type ()) +#define G_INITABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_INITABLE, GInitable)) +#define G_IS_INITABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_INITABLE)) +#define G_INITABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_INITABLE, GInitableIface)) +#define G_TYPE_IS_INITABLE(type) (g_type_is_a ((type), G_TYPE_INITABLE)) + +/** + * GInitable: + * + * Interface for initializable objects. + * + * Since: 2.22 + **/ +typedef struct _GInitableIface GInitableIface; + +/** + * GInitableIface: + * @g_iface: The parent interface. + * @init: Initializes the object. + * + * Provides an interface for initializing object such that initialization + * may fail. + * + * Since: 2.22 + **/ +struct _GInitableIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + gboolean (* init) (GInitable *initable, + GCancellable *cancellable, + GError **error); +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_initable_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gboolean g_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gpointer g_initable_new (GType object_type, + GCancellable *cancellable, + GError **error, + const gchar *first_property_name, + ...); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +GLIB_DEPRECATED_IN_2_54_FOR(g_object_new_with_properties and g_initable_init) +gpointer g_initable_newv (GType object_type, + guint n_parameters, + GParameter *parameters, + GCancellable *cancellable, + GError **error); + +G_GNUC_END_IGNORE_DEPRECATIONS + +GLIB_AVAILABLE_IN_ALL +GObject* g_initable_new_valist (GType object_type, + const gchar *first_property_name, + va_list var_args, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + + +#endif /* __G_INITABLE_H__ */ diff --git a/gio/ginputstream.c b/gio/ginputstream.c new file mode 100644 index 0000000..8fda269 --- /dev/null +++ b/gio/ginputstream.c @@ -0,0 +1,1619 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include +#include "glibintl.h" + +#include "ginputstream.h" +#include "gioprivate.h" +#include "gseekable.h" +#include "gcancellable.h" +#include "gasyncresult.h" +#include "gioerror.h" +#include "gpollableinputstream.h" + +/** + * SECTION:ginputstream + * @short_description: Base class for implementing streaming input + * @include: gio/gio.h + * + * #GInputStream has functions to read from a stream (g_input_stream_read()), + * to close a stream (g_input_stream_close()) and to skip some content + * (g_input_stream_skip()). + * + * To copy the content of an input stream to an output stream without + * manually handling the reads and writes, use g_output_stream_splice(). + * + * See the documentation for #GIOStream for details of thread safety of + * streaming APIs. + * + * All of these functions have async variants too. + **/ + +struct _GInputStreamPrivate { + guint closed : 1; + guint pending : 1; + GAsyncReadyCallback outstanding_callback; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GInputStream, g_input_stream, G_TYPE_OBJECT) + +static gssize g_input_stream_real_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error); +static void g_input_stream_real_read_async (GInputStream *stream, + void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gssize g_input_stream_real_read_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); +static void g_input_stream_real_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gssize g_input_stream_real_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); +static void g_input_stream_real_close_async (GInputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_input_stream_real_close_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); + +static void +g_input_stream_dispose (GObject *object) +{ + GInputStream *stream; + + stream = G_INPUT_STREAM (object); + + if (!stream->priv->closed) + g_input_stream_close (stream, NULL, NULL); + + G_OBJECT_CLASS (g_input_stream_parent_class)->dispose (object); +} + + +static void +g_input_stream_class_init (GInputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_input_stream_dispose; + + klass->skip = g_input_stream_real_skip; + klass->read_async = g_input_stream_real_read_async; + klass->read_finish = g_input_stream_real_read_finish; + klass->skip_async = g_input_stream_real_skip_async; + klass->skip_finish = g_input_stream_real_skip_finish; + klass->close_async = g_input_stream_real_close_async; + klass->close_finish = g_input_stream_real_close_finish; +} + +static void +g_input_stream_init (GInputStream *stream) +{ + stream->priv = g_input_stream_get_instance_private (stream); +} + +/** + * g_input_stream_read: + * @stream: a #GInputStream. + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least count bytes long). + * @count: (in): the number of bytes that will be read from the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to read @count bytes from the stream into the buffer starting at + * @buffer. Will block during this read. + * + * If count is zero returns zero and does nothing. A value of @count + * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error. + * + * On success, the number of bytes read into the buffer is returned. + * It is not an error if this is not the same as the requested size, as it + * can happen e.g. near the end of a file. Zero is returned on end of file + * (or if @count is zero), but never otherwise. + * + * The returned @buffer is not a nul-terminated string, it can contain nul bytes + * at any position, and this function doesn't nul-terminate the @buffer. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an + * operation was partially finished when the operation was cancelled the + * partial result will be returned, without an error. + * + * On error -1 is returned and @error is set accordingly. + * + * Returns: Number of bytes read, or -1 on error, or 0 on end of file. + **/ +gssize +g_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GInputStreamClass *class; + gssize res; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1); + g_return_val_if_fail (buffer != NULL, 0); + + if (count == 0) + return 0; + + if (((gssize) count) < 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), G_STRFUNC); + return -1; + } + + class = G_INPUT_STREAM_GET_CLASS (stream); + + if (class->read_fn == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Input stream doesn’t implement read")); + return -1; + } + + if (!g_input_stream_set_pending (stream, error)) + return -1; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->read_fn (stream, buffer, count, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_input_stream_clear_pending (stream); + + return res; +} + +/** + * g_input_stream_read_all: + * @stream: a #GInputStream. + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least count bytes long). + * @count: (in): the number of bytes that will be read from the stream + * @bytes_read: (out): location to store the number of bytes that was read from the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to read @count bytes from the stream into the buffer starting at + * @buffer. Will block during this read. + * + * This function is similar to g_input_stream_read(), except it tries to + * read as many bytes as requested, only stopping on an error or end of stream. + * + * On a successful read of @count bytes, or if we reached the end of the + * stream, %TRUE is returned, and @bytes_read is set to the number of bytes + * read into @buffer. + * + * If there is an error during the operation %FALSE is returned and @error + * is set to indicate the error status. + * + * As a special exception to the normal conventions for functions that + * use #GError, if this function returns %FALSE (and sets @error) then + * @bytes_read will be set to the number of bytes that were successfully + * read before the error was encountered. This functionality is only + * available from C. If you need it from another language then you must + * write your own loop around g_input_stream_read(). + * + * Returns: %TRUE on success, %FALSE if there was an error + **/ +gboolean +g_input_stream_read_all (GInputStream *stream, + void *buffer, + gsize count, + gsize *bytes_read, + GCancellable *cancellable, + GError **error) +{ + gsize _bytes_read; + gssize res; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + g_return_val_if_fail (buffer != NULL, FALSE); + + _bytes_read = 0; + while (_bytes_read < count) + { + res = g_input_stream_read (stream, (char *)buffer + _bytes_read, count - _bytes_read, + cancellable, error); + if (res == -1) + { + if (bytes_read) + *bytes_read = _bytes_read; + return FALSE; + } + + if (res == 0) + break; + + _bytes_read += res; + } + + if (bytes_read) + *bytes_read = _bytes_read; + return TRUE; +} + +/** + * g_input_stream_read_bytes: + * @stream: a #GInputStream. + * @count: maximum number of bytes that will be read from the stream. Common + * values include 4096 and 8192. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Like g_input_stream_read(), this tries to read @count bytes from + * the stream in a blocking fashion. However, rather than reading into + * a user-supplied buffer, this will create a new #GBytes containing + * the data that was read. This may be easier to use from language + * bindings. + * + * If count is zero, returns a zero-length #GBytes and does nothing. A + * value of @count larger than %G_MAXSSIZE will cause a + * %G_IO_ERROR_INVALID_ARGUMENT error. + * + * On success, a new #GBytes is returned. It is not an error if the + * size of this object is not the same as the requested size, as it + * can happen e.g. near the end of a file. A zero-length #GBytes is + * returned on end of file (or if @count is zero), but never + * otherwise. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an + * operation was partially finished when the operation was cancelled the + * partial result will be returned, without an error. + * + * On error %NULL is returned and @error is set accordingly. + * + * Returns: (transfer full): a new #GBytes, or %NULL on error + * + * Since: 2.34 + **/ +GBytes * +g_input_stream_read_bytes (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error) +{ + guchar *buf; + gssize nread; + + buf = g_malloc (count); + nread = g_input_stream_read (stream, buf, count, cancellable, error); + if (nread == -1) + { + g_free (buf); + return NULL; + } + else if (nread == 0) + { + g_free (buf); + return g_bytes_new_static ("", 0); + } + else + return g_bytes_new_take (buf, nread); +} + +/** + * g_input_stream_skip: + * @stream: a #GInputStream. + * @count: the number of bytes that will be skipped from the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to skip @count bytes from the stream. Will block during the operation. + * + * This is identical to g_input_stream_read(), from a behaviour standpoint, + * but the bytes that are skipped are not returned to the user. Some + * streams have an implementation that is more efficient than reading the data. + * + * This function is optional for inherited classes, as the default implementation + * emulates it using read. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an + * operation was partially finished when the operation was cancelled the + * partial result will be returned, without an error. + * + * Returns: Number of bytes skipped, or -1 on error + **/ +gssize +g_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GInputStreamClass *class; + gssize res; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1); + + if (count == 0) + return 0; + + if (((gssize) count) < 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), G_STRFUNC); + return -1; + } + + class = G_INPUT_STREAM_GET_CLASS (stream); + + if (!g_input_stream_set_pending (stream, error)) + return -1; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->skip (stream, count, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_input_stream_clear_pending (stream); + + return res; +} + +static gssize +g_input_stream_real_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GInputStreamClass *class; + gssize ret, read_bytes; + char buffer[8192]; + GError *my_error; + + if (G_IS_SEEKABLE (stream) && g_seekable_can_seek (G_SEEKABLE (stream))) + { + GSeekable *seekable = G_SEEKABLE (stream); + goffset start, end; + gboolean success; + + /* g_seekable_seek() may try to set pending itself */ + stream->priv->pending = FALSE; + + start = g_seekable_tell (seekable); + + if (g_seekable_seek (G_SEEKABLE (stream), + 0, + G_SEEK_END, + cancellable, + NULL)) + { + end = g_seekable_tell (seekable); + g_assert (start >= 0); + g_assert (end >= start); + if (start > (goffset) (G_MAXOFFSET - count) || + (goffset) (start + count) > end) + { + stream->priv->pending = TRUE; + return end - start; + } + + success = g_seekable_seek (G_SEEKABLE (stream), + start + count, + G_SEEK_SET, + cancellable, + error); + stream->priv->pending = TRUE; + + if (success) + return count; + else + return -1; + } + } + + /* If not seekable, or seek failed, fall back to reading data: */ + + class = G_INPUT_STREAM_GET_CLASS (stream); + + read_bytes = 0; + while (1) + { + my_error = NULL; + + ret = class->read_fn (stream, buffer, MIN (sizeof (buffer), count), + cancellable, &my_error); + if (ret == -1) + { + if (read_bytes > 0 && + my_error->domain == G_IO_ERROR && + my_error->code == G_IO_ERROR_CANCELLED) + { + g_error_free (my_error); + return read_bytes; + } + + g_propagate_error (error, my_error); + return -1; + } + + count -= ret; + read_bytes += ret; + + if (ret == 0 || count == 0) + return read_bytes; + } +} + +/** + * g_input_stream_close: + * @stream: A #GInputStream. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Closes the stream, releasing resources related to it. + * + * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED. + * Closing a stream multiple times will not return an error. + * + * Streams will be automatically closed when the last reference + * is dropped, but you might want to call this function to make sure + * resources are released as early as possible. + * + * Some streams might keep the backing store of the stream (e.g. a file descriptor) + * open after the stream is closed. See the documentation for the individual + * stream for details. + * + * On failure the first error that happened will be reported, but the close + * operation will finish as much as possible. A stream that failed to + * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it + * is important to check and report the error to the user. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * Cancelling a close will still leave the stream closed, but some streams + * can use a faster close that doesn't block to e.g. check errors. + * + * Returns: %TRUE on success, %FALSE on failure + **/ +gboolean +g_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GInputStreamClass *class; + gboolean res; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + + class = G_INPUT_STREAM_GET_CLASS (stream); + + if (stream->priv->closed) + return TRUE; + + res = TRUE; + + if (!g_input_stream_set_pending (stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + if (class->close_fn) + res = class->close_fn (stream, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_input_stream_clear_pending (stream); + + stream->priv->closed = TRUE; + + return res; +} + +static void +async_ready_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GInputStream *stream = G_INPUT_STREAM (source_object); + + g_input_stream_clear_pending (stream); + if (stream->priv->outstanding_callback) + (*stream->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (stream); +} + +static void +async_ready_close_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GInputStream *stream = G_INPUT_STREAM (source_object); + + g_input_stream_clear_pending (stream); + stream->priv->closed = TRUE; + if (stream->priv->outstanding_callback) + (*stream->priv->outstanding_callback) (source_object, res, user_data); + g_object_unref (stream); +} + +/** + * g_input_stream_read_async: + * @stream: A #GInputStream. + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least count bytes long). + * @count: (in): the number of bytes that will be read from the stream + * @io_priority: the [I/O priority][io-priority] + * of the request. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request an asynchronous read of @count bytes from the stream into the buffer + * starting at @buffer. When the operation is finished @callback will be called. + * You can then call g_input_stream_read_finish() to get the result of the + * operation. + * + * During an async request no other sync and async calls are allowed on @stream, and will + * result in %G_IO_ERROR_PENDING errors. + * + * A value of @count larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error. + * + * On success, the number of bytes read into the buffer will be passed to the + * callback. It is not an error if this is not the same as the requested size, as it + * can happen e.g. near the end of a file, but generally we try to read + * as many bytes as requested. Zero is returned on end of file + * (or if @count is zero), but never otherwise. + * + * Any outstanding i/o request with higher priority (lower numerical value) will + * be executed before an outstanding request with lower priority. Default + * priority is %G_PRIORITY_DEFAULT. + * + * The asynchronous methods have a default fallback that uses threads to implement + * asynchronicity, so they are optional for inheriting classes. However, if you + * override one you must override all. + **/ +void +g_input_stream_read_async (GInputStream *stream, + void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GInputStreamClass *class; + GError *error = NULL; + + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + g_return_if_fail (buffer != NULL); + + if (count == 0) + { + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_input_stream_read_async); + g_task_return_int (task, 0); + g_object_unref (task); + return; + } + + if (((gssize) count) < 0) + { + g_task_report_new_error (stream, callback, user_data, + g_input_stream_read_async, + G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), + G_STRFUNC); + return; + } + + if (!g_input_stream_set_pending (stream, &error)) + { + g_task_report_error (stream, callback, user_data, + g_input_stream_read_async, + error); + return; + } + + class = G_INPUT_STREAM_GET_CLASS (stream); + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + class->read_async (stream, buffer, count, io_priority, cancellable, + async_ready_callback_wrapper, user_data); +} + +/** + * g_input_stream_read_finish: + * @stream: a #GInputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an asynchronous stream read operation. + * + * Returns: number of bytes read in, or -1 on error, or 0 on end of file. + **/ +gssize +g_input_stream_read_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + GInputStreamClass *class; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1); + + if (g_async_result_legacy_propagate_error (result, error)) + return -1; + else if (g_async_result_is_tagged (result, g_input_stream_read_async)) + return g_task_propagate_int (G_TASK (result), error); + + class = G_INPUT_STREAM_GET_CLASS (stream); + return class->read_finish (stream, result, error); +} + +typedef struct +{ + gchar *buffer; + gsize to_read; + gsize bytes_read; +} AsyncReadAll; + +static void +free_async_read_all (gpointer data) +{ + g_slice_free (AsyncReadAll, data); +} + +static void +read_all_callback (GObject *stream, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + AsyncReadAll *data = g_task_get_task_data (task); + gboolean got_eof = FALSE; + + if (result) + { + GError *error = NULL; + gssize nread; + + nread = g_input_stream_read_finish (G_INPUT_STREAM (stream), result, &error); + + if (nread == -1) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_assert_cmpint (nread, <=, data->to_read); + data->to_read -= nread; + data->bytes_read += nread; + got_eof = (nread == 0); + } + + if (got_eof || data->to_read == 0) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + } + + else + g_input_stream_read_async (G_INPUT_STREAM (stream), + data->buffer + data->bytes_read, + data->to_read, + g_task_get_priority (task), + g_task_get_cancellable (task), + read_all_callback, task); +} + + +static void +read_all_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GInputStream *stream = source_object; + AsyncReadAll *data = task_data; + GError *error = NULL; + + if (g_input_stream_read_all (stream, data->buffer, data->to_read, &data->bytes_read, + g_task_get_cancellable (task), &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +/** + * g_input_stream_read_all_async: + * @stream: A #GInputStream + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least count bytes long) + * @count: (in): the number of bytes that will be read from the stream + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request an asynchronous read of @count bytes from the stream into the + * buffer starting at @buffer. + * + * This is the asynchronous equivalent of g_input_stream_read_all(). + * + * Call g_input_stream_read_all_finish() to collect the result. + * + * Any outstanding I/O request with higher priority (lower numerical + * value) will be executed before an outstanding request with lower + * priority. Default priority is %G_PRIORITY_DEFAULT. + * + * Since: 2.44 + **/ +void +g_input_stream_read_all_async (GInputStream *stream, + void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AsyncReadAll *data; + GTask *task; + + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + g_return_if_fail (buffer != NULL || count == 0); + + task = g_task_new (stream, cancellable, callback, user_data); + data = g_slice_new0 (AsyncReadAll); + data->buffer = buffer; + data->to_read = count; + + g_task_set_source_tag (task, g_input_stream_read_all_async); + g_task_set_task_data (task, data, free_async_read_all); + g_task_set_priority (task, io_priority); + + /* If async reads are going to be handled via the threadpool anyway + * then we may as well do it with a single dispatch instead of + * bouncing in and out. + */ + if (g_input_stream_async_read_is_via_threads (stream)) + { + g_task_run_in_thread (task, read_all_async_thread); + g_object_unref (task); + } + else + read_all_callback (G_OBJECT (stream), NULL, task); +} + +/** + * g_input_stream_read_all_finish: + * @stream: a #GInputStream + * @result: a #GAsyncResult + * @bytes_read: (out): location to store the number of bytes that was read from the stream + * @error: a #GError location to store the error occurring, or %NULL to ignore + * + * Finishes an asynchronous stream read operation started with + * g_input_stream_read_all_async(). + * + * As a special exception to the normal conventions for functions that + * use #GError, if this function returns %FALSE (and sets @error) then + * @bytes_read will be set to the number of bytes that were successfully + * read before the error was encountered. This functionality is only + * available from C. If you need it from another language then you must + * write your own loop around g_input_stream_read_async(). + * + * Returns: %TRUE on success, %FALSE if there was an error + * + * Since: 2.44 + **/ +gboolean +g_input_stream_read_all_finish (GInputStream *stream, + GAsyncResult *result, + gsize *bytes_read, + GError **error) +{ + GTask *task; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + task = G_TASK (result); + + if (bytes_read) + { + AsyncReadAll *data = g_task_get_task_data (task); + + *bytes_read = data->bytes_read; + } + + return g_task_propagate_boolean (task, error); +} + +static void +read_bytes_callback (GObject *stream, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + guchar *buf = g_task_get_task_data (task); + GError *error = NULL; + gssize nread; + GBytes *bytes = NULL; + + nread = g_input_stream_read_finish (G_INPUT_STREAM (stream), + result, &error); + if (nread == -1) + { + g_free (buf); + g_task_return_error (task, error); + } + else if (nread == 0) + { + g_free (buf); + bytes = g_bytes_new_static ("", 0); + } + else + bytes = g_bytes_new_take (buf, nread); + + if (bytes) + g_task_return_pointer (task, bytes, (GDestroyNotify)g_bytes_unref); + + g_object_unref (task); +} + +/** + * g_input_stream_read_bytes_async: + * @stream: A #GInputStream. + * @count: the number of bytes that will be read from the stream + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request an asynchronous read of @count bytes from the stream into a + * new #GBytes. When the operation is finished @callback will be + * called. You can then call g_input_stream_read_bytes_finish() to get the + * result of the operation. + * + * During an async request no other sync and async calls are allowed + * on @stream, and will result in %G_IO_ERROR_PENDING errors. + * + * A value of @count larger than %G_MAXSSIZE will cause a + * %G_IO_ERROR_INVALID_ARGUMENT error. + * + * On success, the new #GBytes will be passed to the callback. It is + * not an error if this is smaller than the requested size, as it can + * happen e.g. near the end of a file, but generally we try to read as + * many bytes as requested. Zero is returned on end of file (or if + * @count is zero), but never otherwise. + * + * Any outstanding I/O request with higher priority (lower numerical + * value) will be executed before an outstanding request with lower + * priority. Default priority is %G_PRIORITY_DEFAULT. + * + * Since: 2.34 + **/ +void +g_input_stream_read_bytes_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + guchar *buf; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_input_stream_read_bytes_async); + + buf = g_malloc (count); + g_task_set_task_data (task, buf, NULL); + + g_input_stream_read_async (stream, buf, count, + io_priority, cancellable, + read_bytes_callback, task); +} + +/** + * g_input_stream_read_bytes_finish: + * @stream: a #GInputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an asynchronous stream read-into-#GBytes operation. + * + * Returns: (transfer full): the newly-allocated #GBytes, or %NULL on error + * + * Since: 2.34 + **/ +GBytes * +g_input_stream_read_bytes_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL); + g_return_val_if_fail (g_task_is_valid (result, stream), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +/** + * g_input_stream_skip_async: + * @stream: A #GInputStream. + * @count: the number of bytes that will be skipped from the stream + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request an asynchronous skip of @count bytes from the stream. + * When the operation is finished @callback will be called. + * You can then call g_input_stream_skip_finish() to get the result + * of the operation. + * + * During an async request no other sync and async calls are allowed, + * and will result in %G_IO_ERROR_PENDING errors. + * + * A value of @count larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error. + * + * On success, the number of bytes skipped will be passed to the callback. + * It is not an error if this is not the same as the requested size, as it + * can happen e.g. near the end of a file, but generally we try to skip + * as many bytes as requested. Zero is returned on end of file + * (or if @count is zero), but never otherwise. + * + * Any outstanding i/o request with higher priority (lower numerical value) + * will be executed before an outstanding request with lower priority. + * Default priority is %G_PRIORITY_DEFAULT. + * + * The asynchronous methods have a default fallback that uses threads to + * implement asynchronicity, so they are optional for inheriting classes. + * However, if you override one, you must override all. + **/ +void +g_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GInputStreamClass *class; + GError *error = NULL; + + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + + if (count == 0) + { + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_input_stream_skip_async); + g_task_return_int (task, 0); + g_object_unref (task); + return; + } + + if (((gssize) count) < 0) + { + g_task_report_new_error (stream, callback, user_data, + g_input_stream_skip_async, + G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), + G_STRFUNC); + return; + } + + if (!g_input_stream_set_pending (stream, &error)) + { + g_task_report_error (stream, callback, user_data, + g_input_stream_skip_async, + error); + return; + } + + class = G_INPUT_STREAM_GET_CLASS (stream); + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + class->skip_async (stream, count, io_priority, cancellable, + async_ready_callback_wrapper, user_data); +} + +/** + * g_input_stream_skip_finish: + * @stream: a #GInputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes a stream skip operation. + * + * Returns: the size of the bytes skipped, or `-1` on error. + **/ +gssize +g_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + GInputStreamClass *class; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1); + + if (g_async_result_legacy_propagate_error (result, error)) + return -1; + else if (g_async_result_is_tagged (result, g_input_stream_skip_async)) + return g_task_propagate_int (G_TASK (result), error); + + class = G_INPUT_STREAM_GET_CLASS (stream); + return class->skip_finish (stream, result, error); +} + +/** + * g_input_stream_close_async: + * @stream: A #GInputStream. + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): optional cancellable object + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Requests an asynchronous closes of the stream, releasing resources related to it. + * When the operation is finished @callback will be called. + * You can then call g_input_stream_close_finish() to get the result of the + * operation. + * + * For behaviour details see g_input_stream_close(). + * + * The asynchronous methods have a default fallback that uses threads to implement + * asynchronicity, so they are optional for inheriting classes. However, if you + * override one you must override all. + **/ +void +g_input_stream_close_async (GInputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GInputStreamClass *class; + GError *error = NULL; + + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + + if (stream->priv->closed) + { + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_input_stream_close_async); + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + if (!g_input_stream_set_pending (stream, &error)) + { + g_task_report_error (stream, callback, user_data, + g_input_stream_close_async, + error); + return; + } + + class = G_INPUT_STREAM_GET_CLASS (stream); + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + class->close_async (stream, io_priority, cancellable, + async_ready_close_callback_wrapper, user_data); +} + +/** + * g_input_stream_close_finish: + * @stream: a #GInputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes closing a stream asynchronously, started from g_input_stream_close_async(). + * + * Returns: %TRUE if the stream was closed successfully. + **/ +gboolean +g_input_stream_close_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + GInputStreamClass *class; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_input_stream_close_async)) + return g_task_propagate_boolean (G_TASK (result), error); + + class = G_INPUT_STREAM_GET_CLASS (stream); + return class->close_finish (stream, result, error); +} + +/** + * g_input_stream_is_closed: + * @stream: input stream. + * + * Checks if an input stream is closed. + * + * Returns: %TRUE if the stream is closed. + **/ +gboolean +g_input_stream_is_closed (GInputStream *stream) +{ + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), TRUE); + + return stream->priv->closed; +} + +/** + * g_input_stream_has_pending: + * @stream: input stream. + * + * Checks if an input stream has pending actions. + * + * Returns: %TRUE if @stream has pending actions. + **/ +gboolean +g_input_stream_has_pending (GInputStream *stream) +{ + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), TRUE); + + return stream->priv->pending; +} + +/** + * g_input_stream_set_pending: + * @stream: input stream + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Sets @stream to have actions pending. If the pending flag is + * already set or @stream is closed, it will return %FALSE and set + * @error. + * + * Returns: %TRUE if pending was previously unset and is now set. + **/ +gboolean +g_input_stream_set_pending (GInputStream *stream, GError **error) +{ + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + + if (stream->priv->closed) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Stream is already closed")); + return FALSE; + } + + if (stream->priv->pending) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING, + /* Translators: This is an error you get if there is already an + * operation running against this stream when you try to start + * one */ + _("Stream has outstanding operation")); + return FALSE; + } + + stream->priv->pending = TRUE; + return TRUE; +} + +/** + * g_input_stream_clear_pending: + * @stream: input stream + * + * Clears the pending flag on @stream. + **/ +void +g_input_stream_clear_pending (GInputStream *stream) +{ + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + + stream->priv->pending = FALSE; +} + +/*< internal > + * g_input_stream_async_read_is_via_threads: + * @stream: input stream + * + * Checks if an input stream's read_async function uses threads. + * + * Returns: %TRUE if @stream's read_async function uses threads. + **/ +gboolean +g_input_stream_async_read_is_via_threads (GInputStream *stream) +{ + GInputStreamClass *class; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + + class = G_INPUT_STREAM_GET_CLASS (stream); + + return (class->read_async == g_input_stream_real_read_async && + !(G_IS_POLLABLE_INPUT_STREAM (stream) && + g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (stream)))); +} + +/*< internal > + * g_input_stream_async_close_is_via_threads: + * @stream: input stream + * + * Checks if an input stream's close_async function uses threads. + * + * Returns: %TRUE if @stream's close_async function uses threads. + **/ +gboolean +g_input_stream_async_close_is_via_threads (GInputStream *stream) +{ + GInputStreamClass *class; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + + class = G_INPUT_STREAM_GET_CLASS (stream); + + return class->close_async == g_input_stream_real_close_async; +} + +/******************************************** + * Default implementation of async ops * + ********************************************/ + +typedef struct { + void *buffer; + gsize count; +} ReadData; + +static void +free_read_data (ReadData *op) +{ + g_slice_free (ReadData, op); +} + +static void +read_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GInputStream *stream = source_object; + ReadData *op = task_data; + GInputStreamClass *class; + GError *error = NULL; + gssize nread; + + class = G_INPUT_STREAM_GET_CLASS (stream); + + nread = class->read_fn (stream, + op->buffer, op->count, + g_task_get_cancellable (task), + &error); + if (nread == -1) + g_task_return_error (task, error); + else + g_task_return_int (task, nread); +} + +static void read_async_pollable (GPollableInputStream *stream, + GTask *task); + +static gboolean +read_async_pollable_ready (GPollableInputStream *stream, + gpointer user_data) +{ + GTask *task = user_data; + + read_async_pollable (stream, task); + return FALSE; +} + +static void +read_async_pollable (GPollableInputStream *stream, + GTask *task) +{ + ReadData *op = g_task_get_task_data (task); + GError *error = NULL; + gssize nread; + + if (g_task_return_error_if_cancelled (task)) + return; + + nread = G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)-> + read_nonblocking (stream, op->buffer, op->count, &error); + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) + { + GSource *source; + + g_error_free (error); + + source = g_pollable_input_stream_create_source (stream, + g_task_get_cancellable (task)); + g_task_attach_source (task, source, + (GSourceFunc) read_async_pollable_ready); + g_source_unref (source); + return; + } + + if (nread == -1) + g_task_return_error (task, error); + else + g_task_return_int (task, nread); + /* g_input_stream_real_read_async() unrefs task */ +} + + +static void +g_input_stream_real_read_async (GInputStream *stream, + void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + ReadData *op; + + op = g_slice_new0 (ReadData); + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_input_stream_real_read_async); + g_task_set_task_data (task, op, (GDestroyNotify) free_read_data); + g_task_set_priority (task, io_priority); + op->buffer = buffer; + op->count = count; + + if (!g_input_stream_async_read_is_via_threads (stream)) + read_async_pollable (G_POLLABLE_INPUT_STREAM (stream), task); + else + g_task_run_in_thread (task, read_async_thread); + g_object_unref (task); +} + +static gssize +g_input_stream_real_read_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), -1); + + return g_task_propagate_int (G_TASK (result), error); +} + + +static void +skip_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GInputStream *stream = source_object; + gsize count = GPOINTER_TO_SIZE (task_data); + GInputStreamClass *class; + GError *error = NULL; + gssize ret; + + class = G_INPUT_STREAM_GET_CLASS (stream); + ret = class->skip (stream, count, + g_task_get_cancellable (task), + &error); + if (ret == -1) + g_task_return_error (task, error); + else + g_task_return_int (task, ret); +} + +typedef struct { + char buffer[8192]; + gsize count; + gsize count_skipped; +} SkipFallbackAsyncData; + +static void +skip_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GInputStreamClass *class; + GTask *task = user_data; + SkipFallbackAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize ret; + + ret = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error); + + if (ret > 0) + { + data->count -= ret; + data->count_skipped += ret; + + if (data->count > 0) + { + class = G_INPUT_STREAM_GET_CLASS (source_object); + class->read_async (G_INPUT_STREAM (source_object), + data->buffer, MIN (8192, data->count), + g_task_get_priority (task), + g_task_get_cancellable (task), + skip_callback_wrapper, task); + return; + } + } + + if (ret == -1 && + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && + data->count_skipped) + { + /* No error, return partial read */ + g_clear_error (&error); + } + + if (error) + g_task_return_error (task, error); + else + g_task_return_int (task, data->count_skipped); + g_object_unref (task); + } + +static void +g_input_stream_real_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GInputStreamClass *class; + SkipFallbackAsyncData *data; + GTask *task; + + class = G_INPUT_STREAM_GET_CLASS (stream); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_input_stream_real_skip_async); + g_task_set_priority (task, io_priority); + + if (g_input_stream_async_read_is_via_threads (stream)) + { + /* Read is thread-using async fallback. + * Make skip use threads too, so that we can use a possible sync skip + * implementation. */ + g_task_set_task_data (task, GSIZE_TO_POINTER (count), NULL); + + g_task_run_in_thread (task, skip_async_thread); + g_object_unref (task); + } + else + { + /* TODO: Skip fallback uses too much memory, should do multiple read calls */ + + /* There is a custom async read function, lets use that. */ + data = g_new (SkipFallbackAsyncData, 1); + data->count = count; + data->count_skipped = 0; + g_task_set_task_data (task, data, g_free); + g_task_set_check_cancellable (task, FALSE); + class->read_async (stream, data->buffer, MIN (8192, count), io_priority, cancellable, + skip_callback_wrapper, task); + } + +} + +static gssize +g_input_stream_real_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), -1); + + return g_task_propagate_int (G_TASK (result), error); +} + +static void +close_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GInputStream *stream = source_object; + GInputStreamClass *class; + GError *error = NULL; + gboolean result; + + class = G_INPUT_STREAM_GET_CLASS (stream); + if (class->close_fn) + { + result = class->close_fn (stream, + g_task_get_cancellable (task), + &error); + if (!result) + { + g_task_return_error (task, error); + return; + } + } + + g_task_return_boolean (task, TRUE); +} + +static void +g_input_stream_real_close_async (GInputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_input_stream_real_close_async); + g_task_set_check_cancellable (task, FALSE); + g_task_set_priority (task, io_priority); + + g_task_run_in_thread (task, close_async_thread); + g_object_unref (task); +} + +static gboolean +g_input_stream_real_close_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} diff --git a/gio/ginputstream.h b/gio/ginputstream.h new file mode 100644 index 0000000..53b14e3 --- /dev/null +++ b/gio/ginputstream.h @@ -0,0 +1,216 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_INPUT_STREAM_H__ +#define __G_INPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_INPUT_STREAM (g_input_stream_get_type ()) +#define G_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_INPUT_STREAM, GInputStream)) +#define G_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_INPUT_STREAM, GInputStreamClass)) +#define G_IS_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_INPUT_STREAM)) +#define G_IS_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_INPUT_STREAM)) +#define G_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_INPUT_STREAM, GInputStreamClass)) + +/** + * GInputStream: + * + * Base class for streaming input operations. + **/ +typedef struct _GInputStreamClass GInputStreamClass; +typedef struct _GInputStreamPrivate GInputStreamPrivate; + +struct _GInputStream +{ + GObject parent_instance; + + /*< private >*/ + GInputStreamPrivate *priv; +}; + +struct _GInputStreamClass +{ + GObjectClass parent_class; + + /* Sync ops: */ + + gssize (* read_fn) (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); + gssize (* skip) (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error); + gboolean (* close_fn) (GInputStream *stream, + GCancellable *cancellable, + GError **error); + + /* Async ops: (optional in derived classes) */ + void (* read_async) (GInputStream *stream, + void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gssize (* read_finish) (GInputStream *stream, + GAsyncResult *result, + GError **error); + void (* skip_async) (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gssize (* skip_finish) (GInputStream *stream, + GAsyncResult *result, + GError **error); + void (* close_async) (GInputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* close_finish) (GInputStream *stream, + GAsyncResult *result, + GError **error); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_input_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gssize g_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_input_stream_read_all (GInputStream *stream, + void *buffer, + gsize count, + gsize *bytes_read, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_34 +GBytes *g_input_stream_read_bytes (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_input_stream_read_async (GInputStream *stream, + void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gssize g_input_stream_read_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_44 +void g_input_stream_read_all_async (GInputStream *stream, + void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_44 +gboolean g_input_stream_read_all_finish (GInputStream *stream, + GAsyncResult *result, + gsize *bytes_read, + GError **error); + +GLIB_AVAILABLE_IN_2_34 +void g_input_stream_read_bytes_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_34 +GBytes *g_input_stream_read_bytes_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gssize g_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_input_stream_close_async (GInputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_input_stream_close_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); + +/* For implementations: */ + +GLIB_AVAILABLE_IN_ALL +gboolean g_input_stream_is_closed (GInputStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_input_stream_has_pending (GInputStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_input_stream_set_pending (GInputStream *stream, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_input_stream_clear_pending (GInputStream *stream); + +G_END_DECLS + +#endif /* __G_INPUT_STREAM_H__ */ diff --git a/gio/gio-autocleanups.h b/gio/gio-autocleanups.h new file mode 100644 index 0000000..ff40729 --- /dev/null +++ b/gio/gio-autocleanups.h @@ -0,0 +1,153 @@ +/* + * Copyright © 2015 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAction, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GActionMap, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAppInfo, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAppLaunchContext, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAppInfoMonitor, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GApplicationCommandLine, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GApplication, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAsyncInitable, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAsyncResult, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBufferedInputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBufferedOutputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBytesIcon, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GCancellable, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GCharsetConverter, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GConverter, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GConverterInputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GConverterOutputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GCredentials, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDatagramBased, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDataInputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDataOutputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusActionGroup, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusAuthObserver, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusInterface, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusInterfaceSkeleton, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusMenuModel, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusMessage, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusMethodInvocation, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusNodeInfo, g_dbus_node_info_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusObject, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusObjectManagerClient, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusObjectManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusObjectManagerServer, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusObjectProxy, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusObjectSkeleton, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusProxy, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDBusServer, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GDrive, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GEmblemedIcon, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GEmblem, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileEnumerator, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFile, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileAttributeInfoList, g_file_attribute_info_list_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileIcon, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileInfo, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileInputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileIOStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileMonitor, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFilenameCompleter, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFileOutputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFilterInputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFilterOutputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GIcon, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GInetAddress, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GInetAddressMask, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GInetSocketAddress, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GInitable, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GInputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GIOModule, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GIOStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GLoadableIcon, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMemoryInputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMemoryOutputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMenu, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMenuItem, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMenuModel, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMenuAttributeIter, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMenuLinkIter, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMount, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMountOperation, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GNativeVolumeMonitor, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GNetworkAddress, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GNetworkMonitor, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GNetworkService, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GNotification, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GOutputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GPermission, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GPollableInputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GPollableOutputStream, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GPropertyAction, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GProxyAddressEnumerator, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GProxyAddress, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GProxy, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GProxyResolver, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GRemoteActionGroup, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GResolver, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GResource, g_resource_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSeekable, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettingsBackend, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettingsSchema, g_settings_schema_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettingsSchemaKey, g_settings_schema_key_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettingsSchemaSource, g_settings_schema_source_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettings, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSimpleActionGroup, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSimpleAction, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSimpleAsyncResult, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSimplePermission, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSimpleProxyResolver, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketAddressEnumerator, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketAddress, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketClient, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketConnectable, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketControlMessage, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocket, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketListener, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSocketService, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSubprocess, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSubprocessLauncher, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTask, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTcpConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTcpWrapperConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTestDBus, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GThemedIcon, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GThreadedSocketService, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsBackend, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsCertificate, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsClientConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsDatabase, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsFileDatabase, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsInteraction, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsPassword, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTlsServerConnection, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVfs, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVolume, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVolumeMonitor, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GZlibCompressor, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GZlibDecompressor, g_object_unref) diff --git a/gio/gio-querymodules-wrapper.py b/gio/gio-querymodules-wrapper.py new file mode 100644 index 0000000..351700d --- /dev/null +++ b/gio/gio-querymodules-wrapper.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import sys + +if not os.environ.get("DESTDIR"): + print("GIO module cache creation...") + subprocess.call([sys.argv[1], sys.argv[2]]) diff --git a/gio/gio-querymodules.c b/gio/gio-querymodules.c new file mode 100644 index 0000000..aff194b --- /dev/null +++ b/gio/gio-querymodules.c @@ -0,0 +1,180 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "giomodule.h" +#include "giomodule-priv.h" + +#include +#include +#include + +#include "glib/glib-private.h" + +static gboolean +is_valid_module_name (const gchar *basename) +{ +#if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN) + return + g_str_has_prefix (basename, "lib") && + g_str_has_suffix (basename, ".so"); +#else + return g_str_has_suffix (basename, ".dll"); +#endif +} + +static void +query_dir (const char *dirname) +{ + GString *data; + GDir *dir; + GList *list = NULL, *iterator = NULL; + const char *name; + char *cachename; + char **(* query) (void); + GError *error; + int i; + + if (!g_module_supported ()) + return; + + error = NULL; + dir = g_dir_open (dirname, 0, &error); + if (!dir) + { + g_printerr ("Unable to open directory %s: %s\n", dirname, error->message); + g_error_free (error); + return; + } + + data = g_string_new (""); + + while ((name = g_dir_read_name (dir))) + list = g_list_prepend (list, g_strdup (name)); + + list = g_list_sort (list, (GCompareFunc) g_strcmp0); + for (iterator = list; iterator; iterator = iterator->next) + { + GModule *module; + gchar *path; + char **extension_points; + + name = iterator->data; + if (!is_valid_module_name (name)) + continue; + + path = g_build_filename (dirname, name, NULL); + module = g_module_open_full (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL, &error); + g_free (path); + + if (module) + { + gchar *modulename; + gchar *symname; + + modulename = _g_io_module_extract_name (name); + symname = g_strconcat ("g_io_", modulename, "_query", NULL); + g_module_symbol (module, symname, (gpointer) &query); + g_free (symname); + g_free (modulename); + + if (!query) + { + /* Fallback to old name */ + g_module_symbol (module, "g_io_module_query", (gpointer) &query); + } + + if (query) + { + extension_points = query (); + + if (extension_points) + { + g_string_append_printf (data, "%s: ", name); + + for (i = 0; extension_points[i] != NULL; i++) + g_string_append_printf (data, "%s%s", i == 0 ? "" : ",", extension_points[i]); + + g_string_append (data, "\n"); + g_strfreev (extension_points); + } + } + + g_module_close (module); + } + else + { + g_debug ("Failed to open module %s: %s", name, error->message); + } + + g_clear_error (&error); + } + + g_dir_close (dir); + g_list_free_full (list, g_free); + + cachename = g_build_filename (dirname, "giomodule.cache", NULL); + + if (data->len > 0) + { + error = NULL; + + if (!g_file_set_contents (cachename, data->str, data->len, &error)) + { + g_printerr ("Unable to create %s: %s\n", cachename, error->message); + g_error_free (error); + } + } + else + { + if (g_unlink (cachename) != 0 && errno != ENOENT) + { + int errsv = errno; + g_printerr ("Unable to unlink %s: %s\n", cachename, g_strerror (errsv)); + } + } + + g_free (cachename); + g_string_free (data, TRUE); +} + +int +main (gint argc, + gchar *argv[]) +{ + int i; + + if (argc <= 1) + { + g_print ("Usage: gio-querymodules [ ...]\n"); + g_print ("Will update giomodule.cache in the listed directories\n"); + return 1; + } + + setlocale (LC_ALL, GLIB_DEFAULT_LOCALE); + + /* Be defensive and ensure we're linked to GObject */ + g_type_ensure (G_TYPE_OBJECT); + + for (i = 1; i < argc; i++) + query_dir (argv[i]); + + return 0; +} diff --git a/gio/gio-tool-cat.c b/gio/gio-tool-cat.c new file mode 100644 index 0000000..bb0c928 --- /dev/null +++ b/gio/gio-tool-cat.c @@ -0,0 +1,178 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#ifdef G_OS_WIN32 +#include +#endif + +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "gio-tool.h" + + +static const GOptionEntry entries[] = { + G_OPTION_ENTRY_NULL +}; + +/* 256k minus malloc overhead */ +#define STREAM_BUFFER_SIZE (1024*256 - 2*sizeof(gpointer)) + +static gboolean +cat (GFile *file) +{ + GInputStream *in; + char *buffer; + char *p; + gssize res; + gboolean close_res; + GError *error; + gboolean success; + + error = NULL; + in = (GInputStream *) g_file_read (file, NULL, &error); + if (in == NULL) + { + print_file_error (file, error->message); + g_error_free (error); + return FALSE; + } + + buffer = g_malloc (STREAM_BUFFER_SIZE); + success = TRUE; + while (1) + { + res = g_input_stream_read (in, buffer, STREAM_BUFFER_SIZE, NULL, &error); + if (res > 0) + { + gssize written; + + p = buffer; + while (res > 0) + { + int errsv; + + written = write (STDOUT_FILENO, p, res); + errsv = errno; + + if (written == -1 && errsv != EINTR) + { + print_error ("%s", _("Error writing to stdout")); + success = FALSE; + goto out; + } + res -= written; + p += written; + } + } + else if (res < 0) + { + print_file_error (file, error->message); + g_error_free (error); + error = NULL; + success = FALSE; + break; + } + else if (res == 0) + break; + } + + out: + close_res = g_input_stream_close (in, NULL, &error); + if (!close_res) + { + print_file_error (file, error->message); + g_error_free (error); + success = FALSE; + } + + g_free (buffer); + + return success; +} + +int +handle_cat (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + int i; + gboolean res; + GFile *file; + + g_set_prgname ("gio cat"); + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s…", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Concatenate files and print to standard output.")); + g_option_context_set_description (context, + _("gio cat works just like the traditional cat utility, but using GIO\n" + "locations instead of local files: for example, you can use something\n" + "like smb://server/resource/file.txt as location.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 2) + { + show_help (context, _("No locations given")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + res = TRUE; + for (i = 1; i < argc; i++) + { + file = g_file_new_for_commandline_arg (argv[i]); + res &= cat (file); + g_object_unref (file); + } + + return res ? 0 : 2; +} diff --git a/gio/gio-tool-copy.c b/gio/gio-tool-copy.c new file mode 100644 index 0000000..cbae0dc --- /dev/null +++ b/gio/gio-tool-copy.c @@ -0,0 +1,227 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include +#if 0 +#include +#include +#include +#include +#endif + +#include "gio-tool.h" + +static gboolean no_target_directory = FALSE; +static gboolean progress = FALSE; +static gboolean interactive = FALSE; +static gboolean preserve = FALSE; +static gboolean backup = FALSE; +static gboolean no_dereference = FALSE; +static gboolean default_permissions = FALSE; + +static const GOptionEntry entries[] = { + { "no-target-directory", 'T', 0, G_OPTION_ARG_NONE, &no_target_directory, N_("No target directory"), NULL }, + { "progress", 'p', 0, G_OPTION_ARG_NONE, &progress, N_("Show progress"), NULL }, + { "interactive", 'i', 0, G_OPTION_ARG_NONE, &interactive, N_("Prompt before overwrite"), NULL }, + { "preserve", 'p', 0, G_OPTION_ARG_NONE, &preserve, N_("Preserve all attributes"), NULL }, + { "backup", 'b', 0, G_OPTION_ARG_NONE, &backup, N_("Backup existing destination files"), NULL }, + { "no-dereference", 'P', 0, G_OPTION_ARG_NONE, &no_dereference, N_("Never follow symbolic links"), NULL }, + { "default-permissions", 0, 0, G_OPTION_ARG_NONE, &default_permissions, N_("Use default permissions for the destination"), NULL }, + G_OPTION_ENTRY_NULL +}; + +static gint64 start_time; +static gint64 previous_time; + +static void +show_progress (goffset current_num_bytes, + goffset total_num_bytes, + gpointer user_data) +{ + gint64 tv; + char *current_size, *total_size, *rate; + + tv = g_get_monotonic_time (); + if (tv - previous_time < (G_USEC_PER_SEC / 5) && + current_num_bytes != total_num_bytes) + return; + + current_size = g_format_size (current_num_bytes); + total_size = g_format_size (total_num_bytes); + rate = g_format_size (current_num_bytes / + MAX ((tv - start_time) / G_USEC_PER_SEC, 1)); + g_print ("\r\033[K"); + g_print (_("Transferred %s out of %s (%s/s)"), current_size, total_size, rate); + + previous_time = tv; + + g_free (current_size); + g_free (total_size); + g_free (rate); +} + +int +handle_copy (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + GError *error = NULL; + char *param; + GFile *source, *dest, *target; + gboolean dest_is_dir; + char *basename; + char *uri; + int i; + GFileCopyFlags flags; + int retval = 0; + + g_set_prgname ("gio copy"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s… %s", _("SOURCE"), _("DESTINATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Copy one or more files from SOURCE to DESTINATION.")); + g_option_context_set_description (context, + _("gio copy is similar to the traditional cp utility, but using GIO\n" + "locations instead of local files: for example, you can use something\n" + "like smb://server/resource/file.txt as location.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 3) + { + show_help (context, NULL); + g_option_context_free (context); + return 1; + } + + dest = g_file_new_for_commandline_arg (argv[argc - 1]); + + if (no_target_directory && argc > 3) + { + show_help (context, NULL); + g_object_unref (dest); + g_option_context_free (context); + return 1; + } + + dest_is_dir = file_is_dir (dest); + if (!dest_is_dir && argc > 3) + { + char *message; + + message = g_strdup_printf (_("Destination %s is not a directory"), argv[argc - 1]); + show_help (context, message); + g_free (message); + g_object_unref (dest); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + for (i = 1; i < argc - 1; i++) + { + source = g_file_new_for_commandline_arg (argv[i]); + if (dest_is_dir && !no_target_directory) + { + basename = g_file_get_basename (source); + target = g_file_get_child (dest, basename); + g_free (basename); + } + else + target = g_object_ref (dest); + + flags = 0; + if (backup) + flags |= G_FILE_COPY_BACKUP; + if (!interactive) + flags |= G_FILE_COPY_OVERWRITE; + if (no_dereference) + flags |= G_FILE_COPY_NOFOLLOW_SYMLINKS; + if (preserve) + flags |= G_FILE_COPY_ALL_METADATA; + if (default_permissions) + flags |= G_FILE_COPY_TARGET_DEFAULT_PERMS; + + error = NULL; + start_time = g_get_monotonic_time (); + + if (!g_file_copy (source, target, flags, NULL, progress ? show_progress : NULL, NULL, &error)) + { + if (interactive && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) + { + char line[16]; + + g_error_free (error); + error = NULL; + + uri = g_file_get_uri (target); + g_print (_("%s: overwrite “%sâ€? "), argv[0], uri); + g_free (uri); + + if (fgets (line, sizeof (line), stdin) && + (line[0] == 'y' || line[0] == 'Y')) + { + flags |= G_FILE_COPY_OVERWRITE; + start_time = g_get_monotonic_time (); + if (!g_file_copy (source, target, flags, NULL, progress ? show_progress : NULL, NULL, &error)) + goto copy_failed; + } + } + else + { + copy_failed: + print_file_error (source, error->message); + g_error_free (error); + retval = 1; + } + } + + if (progress && retval == 0) + g_print ("\n"); + + g_object_unref (source); + g_object_unref (target); + } + + g_object_unref (dest); + + return retval; +} diff --git a/gio/gio-tool-info.c b/gio/gio-tool-info.c new file mode 100644 index 0000000..336da64 --- /dev/null +++ b/gio/gio-tool-info.c @@ -0,0 +1,390 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#ifdef G_OS_UNIX +#include +#endif + +#include "gio-tool.h" + +static gboolean writable = FALSE; +static gboolean filesystem = FALSE; +static char *attributes = NULL; +static gboolean nofollow_symlinks = FALSE; + +static const GOptionEntry entries[] = { + { "query-writable", 'w', 0, G_OPTION_ARG_NONE, &writable, N_("List writable attributes"), NULL }, + { "filesystem", 'f', 0, G_OPTION_ARG_NONE, &filesystem, N_("Get file system info"), NULL }, + { "attributes", 'a', 0, G_OPTION_ARG_STRING, &attributes, N_("The attributes to get"), N_("ATTRIBUTES") }, + { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL }, + G_OPTION_ENTRY_NULL +}; + +static char * +escape_string (const char *in) +{ + GString *str; + static char *hex_digits = "0123456789abcdef"; + unsigned char c; + + + str = g_string_new (""); + + while ((c = *in++) != 0) + { + if (c >= 32 && c <= 126 && c != '\\') + g_string_append_c (str, c); + else + { + g_string_append (str, "\\x"); + g_string_append_c (str, hex_digits[(c >> 4) & 0xf]); + g_string_append_c (str, hex_digits[c & 0xf]); + } + } + + return g_string_free (str, FALSE); +} + +static void +show_attributes (GFileInfo *info) +{ + char **attributes; + char *s; + int i; + + attributes = g_file_info_list_attributes (info, NULL); + + g_print (_("attributes:\n")); + for (i = 0; attributes[i] != NULL; i++) + { + /* list the icons in order rather than displaying "GThemedIcon:0x8df7200" */ + if (strcmp (attributes[i], "standard::icon") == 0 || + strcmp (attributes[i], "standard::symbolic-icon") == 0) + { + GIcon *icon; + int j; + const char * const *names = NULL; + + if (strcmp (attributes[i], "standard::symbolic-icon") == 0) + icon = g_file_info_get_symbolic_icon (info); + else + icon = g_file_info_get_icon (info); + + /* only look up names if GThemedIcon */ + if (G_IS_THEMED_ICON(icon)) + { + names = g_themed_icon_get_names (G_THEMED_ICON (icon)); + g_print (" %s: ", attributes[i]); + for (j = 0; names[j] != NULL; j++) + g_print ("%s%s", names[j], (names[j+1] == NULL)?"":", "); + g_print ("\n"); + } + else + { + s = g_file_info_get_attribute_as_string (info, attributes[i]); + g_print (" %s: %s\n", attributes[i], s); + g_free (s); + } + } + else + { + s = g_file_info_get_attribute_as_string (info, attributes[i]); + g_print (" %s: %s\n", attributes[i], s); + g_free (s); + } + } + g_strfreev (attributes); +} + +static void +show_info (GFile *file, GFileInfo *info) +{ + const char *name, *type; + char *escaped, *uri; + goffset size; + const char *path; +#ifdef G_OS_UNIX + GUnixMountEntry *entry; +#endif + + name = g_file_info_get_display_name (info); + if (name) + /* Translators: This is a noun and represents and attribute of a file */ + g_print (_("display name: %s\n"), name); + + name = g_file_info_get_edit_name (info); + if (name) + /* Translators: This is a noun and represents and attribute of a file */ + g_print (_("edit name: %s\n"), name); + + name = g_file_info_get_name (info); + if (name) + { + escaped = escape_string (name); + g_print (_("name: %s\n"), escaped); + g_free (escaped); + } + + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE)) + { + type = file_type_to_string (g_file_info_get_file_type (info)); + g_print (_("type: %s\n"), type); + } + + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)) + { + size = g_file_info_get_size (info); + g_print (_("size: ")); + g_print (" %"G_GUINT64_FORMAT"\n", (guint64)size); + } + + if (g_file_info_get_is_hidden (info)) + g_print (_("hidden\n")); + + uri = g_file_get_uri (file); + g_print (_("uri: %s\n"), uri); + g_free (uri); + + path = g_file_peek_path (file); + if (path) + { + g_print (_("local path: %s\n"), path); + +#ifdef G_OS_UNIX + entry = g_unix_mount_at (path, NULL); + if (entry == NULL) + entry = g_unix_mount_for (path, NULL); + if (entry != NULL) + { + gchar *device; + const gchar *root; + gchar *root_string = NULL; + gchar *mount; + gchar *fs; + const gchar *options; + gchar *options_string = NULL; + + device = g_strescape (g_unix_mount_get_device_path (entry), NULL); + root = g_unix_mount_get_root_path (entry); + if (root != NULL && g_strcmp0 (root, "/") != 0) + { + escaped = g_strescape (root, NULL); + root_string = g_strconcat ("[", escaped, "]", NULL); + g_free (escaped); + } + mount = g_strescape (g_unix_mount_get_mount_path (entry), NULL); + fs = g_strescape (g_unix_mount_get_fs_type (entry), NULL); + + options = g_unix_mount_get_options (entry); + if (options != NULL) + { + options_string = g_strescape (options, NULL); + } + + g_print (_("unix mount: %s%s %s %s %s\n"), device, + root_string ? root_string : "", mount, fs, + options_string ? options_string : ""); + + g_free (device); + g_free (root_string); + g_free (mount); + g_free (fs); + g_free (options_string); + + g_unix_mount_free (entry); + } +#endif + } + + show_attributes (info); +} + +static gboolean +query_info (GFile *file) +{ + GFileQueryInfoFlags flags; + GFileInfo *info; + GError *error; + + if (file == NULL) + return FALSE; + + if (attributes == NULL) + attributes = "*"; + + flags = 0; + if (nofollow_symlinks) + flags |= G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS; + + error = NULL; + if (filesystem) + info = g_file_query_filesystem_info (file, attributes, NULL, &error); + else + info = g_file_query_info (file, attributes, flags, NULL, &error); + + if (info == NULL) + { + print_file_error (file, error->message); + g_error_free (error); + return FALSE; + } + + if (filesystem) + show_attributes (info); + else + show_info (file, info); + + g_object_unref (info); + + return TRUE; +} + +static gboolean +get_writable_info (GFile *file) +{ + GFileAttributeInfoList *list; + GError *error; + int i; + char *flags; + + if (file == NULL) + return FALSE; + + error = NULL; + + list = g_file_query_settable_attributes (file, NULL, &error); + if (list == NULL) + { + print_file_error (file, error->message); + g_error_free (error); + return FALSE; + } + + if (list->n_infos > 0) + { + g_print (_("Settable attributes:\n")); + for (i = 0; i < list->n_infos; i++) + { + flags = attribute_flags_to_string (list->infos[i].flags); + g_print (" %s (%s%s%s)\n", + list->infos[i].name, + attribute_type_to_string (list->infos[i].type), + (*flags != 0)?", ":"", flags); + g_free (flags); + } + } + + g_file_attribute_info_list_unref (list); + + list = g_file_query_writable_namespaces (file, NULL, &error); + if (list == NULL) + { + print_file_error (file, error->message); + g_error_free (error); + return FALSE; + } + + if (list->n_infos > 0) + { + g_print (_("Writable attribute namespaces:\n")); + for (i = 0; i < list->n_infos; i++) + { + flags = attribute_flags_to_string (list->infos[i].flags); + g_print (" %s (%s%s%s)\n", + list->infos[i].name, + attribute_type_to_string (list->infos[i].type), + (*flags != 0)?", ":"", flags); + g_free (flags); + } + } + + g_file_attribute_info_list_unref (list); + + return TRUE; +} + +int +handle_info (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + gboolean res; + gint i; + GFile *file; + + g_set_prgname ("gio info"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s…", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Show information about locations.")); + g_option_context_set_description (context, + _("gio info is similar to the traditional ls utility, but using GIO\n" + "locations instead of local files: for example, you can use something\n" + "like smb://server/resource/file.txt as location. File attributes can\n" + "be specified with their GIO name, e.g. standard::icon, or just by\n" + "namespace, e.g. unix, or by “*â€, which matches all attributes")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 2) + { + show_help (context, _("No locations given")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + res = TRUE; + for (i = 1; i < argc; i++) + { + file = g_file_new_for_commandline_arg (argv[i]); + if (writable) + res &= get_writable_info (file); + else + res &= query_info (file); + g_object_unref (file); + } + + return res ? 0 : 2; +} diff --git a/gio/gio-tool-launch.c b/gio/gio-tool-launch.c new file mode 100644 index 0000000..edc2cf2 --- /dev/null +++ b/gio/gio-tool-launch.c @@ -0,0 +1,131 @@ +/* + * Copyright 2020 Frederic Martinsons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Frederic Martinsons + */ + +#include "config.h" + +#include + +#if defined(G_OS_UNIX) && !defined(HAVE_COCOA) +#include +#endif + +#include + +#include "gio-tool.h" + +static const GOptionEntry entries[] = { + G_OPTION_ENTRY_NULL +}; + +int +handle_launch (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + GError *error = NULL; +#if defined(G_OS_UNIX) && !defined(HAVE_COCOA) + int i; + GAppInfo *app = NULL; + GAppLaunchContext *app_context = NULL; + GKeyFile *keyfile = NULL; + GList *args = NULL; + char *desktop_file = NULL; +#endif + int retval; + + g_set_prgname ("gio launch"); + + /* Translators: commandline placeholder */ + context = g_option_context_new (_("DESKTOP-FILE [FILE-ARG …]")); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Launch an application from a desktop file, passing optional filename arguments to it.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 2) + { + show_help (context, _("No desktop file given")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + +#if !defined(G_OS_UNIX) || defined(HAVE_COCOA) + print_error (_("The launch command is not currently supported on this platform")); + retval = 1; +#else + retval = 0; + desktop_file = argv[1]; + + /* Use keyfile api for loading desktop app in order to check for + * - not existing file. + * - invalid keyfile format. + */ + keyfile = g_key_file_new (); + if (!g_key_file_load_from_file (keyfile, desktop_file, G_KEY_FILE_NONE, &error)) + { + print_error (_("Unable to load ‘%s‘: %s"), desktop_file, error->message); + g_clear_error (&error); + retval = 1; + } + else + { + app = (GAppInfo*)g_desktop_app_info_new_from_keyfile (keyfile); + if (!app) + { + print_error (_("Unable to load application information for ‘%s‘"), desktop_file); + retval = 1; + } + else + { + for (i = 2; i < argc; i++) + { + args = g_list_append (args, g_file_new_for_commandline_arg (argv[i])); + } + app_context = g_app_launch_context_new (); + if (!g_app_info_launch (app, args, app_context, &error)) + { + print_error (_("Unable to launch application ‘%s’: %s"), desktop_file, error->message); + g_clear_error (&error); + retval = 1; + } + g_list_free_full (args, g_object_unref); + g_clear_object (&app_context); + } + g_clear_object (&app); + } + g_key_file_free (keyfile); +#endif + return retval; +} diff --git a/gio/gio-tool-list.c b/gio/gio-tool-list.c new file mode 100644 index 0000000..8e9409f --- /dev/null +++ b/gio/gio-tool-list.c @@ -0,0 +1,238 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#include "gio-tool.h" + + +static char *attributes = NULL; +static gboolean show_hidden = FALSE; +static gboolean show_long = FALSE; +static gboolean nofollow_symlinks = FALSE; +static gboolean print_display_names = FALSE; +static gboolean print_uris = FALSE; + +static const GOptionEntry entries[] = { + { "attributes", 'a', 0, G_OPTION_ARG_STRING, &attributes, N_("The attributes to get"), N_("ATTRIBUTES") }, + { "hidden", 'h', 0, G_OPTION_ARG_NONE, &show_hidden, N_("Show hidden files"), NULL }, + { "long", 'l', 0, G_OPTION_ARG_NONE, &show_long, N_("Use a long listing format"), NULL }, + { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL}, + { "print-display-names", 'd', 0, G_OPTION_ARG_NONE, &print_display_names, N_("Print display names"), NULL }, + { "print-uris", 'u', 0, G_OPTION_ARG_NONE, &print_uris, N_("Print full URIs"), NULL}, + G_OPTION_ENTRY_NULL +}; + +static void +show_file_listing (GFileInfo *info, GFile *parent) +{ + const char *name, *type; + char *uri = NULL; + goffset size; + char **attributes; + int i; + gboolean first_attr; + GFile *child; + + if ((g_file_info_get_is_hidden (info)) && !show_hidden) + return; + + if (print_display_names) + name = g_file_info_get_display_name (info); + else + name = g_file_info_get_name (info); + + if (name == NULL) + name = ""; + + if (print_uris) { + child = g_file_get_child (parent, name); + uri = g_file_get_uri (child); + g_object_unref (child); + } + + size = g_file_info_get_size (info); + type = file_type_to_string (g_file_info_get_file_type (info)); + if (show_long) + g_print ("%s\t%"G_GUINT64_FORMAT"\t(%s)", print_uris? uri: name, (guint64)size, type); + else + g_print ("%s", print_uris? uri: name); + + if (print_uris) + g_free (uri); + + first_attr = TRUE; + attributes = g_file_info_list_attributes (info, NULL); + for (i = 0 ; attributes[i] != NULL; i++) + { + char *val_as_string; + + if (!show_long || + (!print_display_names && strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_NAME) == 0) || + (print_display_names && strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME) == 0) || + strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_SIZE) == 0 || + strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_TYPE) == 0 || + strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) == 0) + continue; + + if (first_attr) + { + g_print ("\t"); + first_attr = FALSE; + } + else + g_print (" "); + val_as_string = g_file_info_get_attribute_as_string (info, attributes[i]); + g_print ("%s=%s", attributes[i], val_as_string); + g_free (val_as_string); + } + + g_strfreev (attributes); + + g_print ("\n"); +} + +static gboolean +list (GFile *file) +{ + GFileEnumerator *enumerator; + GFileInfo *info; + GError *error; + gboolean res; + + error = NULL; + enumerator = g_file_enumerate_children (file, + attributes, + nofollow_symlinks ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS : 0, + NULL, + &error); + if (enumerator == NULL) + { + print_file_error (file, error->message); + g_error_free (error); + return FALSE; + } + + res = TRUE; + while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL) + { + show_file_listing (info, file); + g_object_unref (info); + } + + if (error) + { + print_file_error (file, error->message); + g_clear_error (&error); + res = FALSE; + } + + if (!g_file_enumerator_close (enumerator, NULL, &error)) + { + print_file_error (file, error->message); + g_clear_error (&error); + res = FALSE; + } + + return res; +} + +int +handle_list (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + gboolean res; + gint i; + GFile *file; + + g_set_prgname ("gio list"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("[%s…]", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("List the contents of the locations.")); + g_option_context_set_description (context, + _("gio list is similar to the traditional ls utility, but using GIO\n" + "locations instead of local files: for example, you can use something\n" + "like smb://server/resource/file.txt as location. File attributes can\n" + "be specified with their GIO name, e.g. standard::icon")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + if (attributes != NULL) + show_long = TRUE; + + attributes = g_strconcat (!print_display_names ? G_FILE_ATTRIBUTE_STANDARD_NAME "," : "", + print_display_names ? G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," : "", + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN, + attributes != NULL ? "," : "", + attributes, + NULL); + + res = TRUE; + if (argc > 1) + { + for (i = 1; i < argc; i++) + { + file = g_file_new_for_commandline_arg (argv[i]); + res &= list (file); + g_object_unref (file); + } + } + else + { + char *cwd; + + cwd = g_get_current_dir (); + file = g_file_new_for_path (cwd); + res = list (file); + g_object_unref (file); + g_free (cwd); + } + + g_free (attributes); + + return res ? 0 : 2; +} diff --git a/gio/gio-tool-mime.c b/gio/gio-tool-mime.c new file mode 100644 index 0000000..be8a4a9 --- /dev/null +++ b/gio/gio-tool-mime.c @@ -0,0 +1,179 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "gio-tool.h" + +static const GOptionEntry entries[] = { + G_OPTION_ENTRY_NULL +}; + +static GAppInfo * +get_app_info_for_id (const char *id) +{ + GList *list, *l; + GAppInfo *ret_info; + + list = g_app_info_get_all (); + ret_info = NULL; + for (l = list; l != NULL; l = l->next) + { + GAppInfo *info; + + info = l->data; + if (ret_info == NULL && g_strcmp0 (g_app_info_get_id (info), id) == 0) + ret_info = info; + else + g_object_unref (info); + } + g_list_free (list); + + return ret_info; +} + +int +handle_mime (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + GError *error = NULL; + gchar *param; + const gchar *mimetype; + const char *handler; + + g_set_prgname ("gio mime"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s [%s]", _("MIMETYPE"), _("HANDLER")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Get or set the handler for a mimetype.")); + g_option_context_set_description (context, + _("If no handler is given, lists registered and recommended applications\n" + "for the mimetype. If a handler is given, it is set as the default\n" + "handler for the mimetype.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc != 2 && argc != 3) + { + show_help (context, _("Must specify a single mimetype, and maybe a handler")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + if (argc == 2) + { + GAppInfo *info; + + mimetype = argv[1]; + + info = g_app_info_get_default_for_type (mimetype, FALSE); + if (!info) + { + g_print (_("No default applications for “%sâ€\n"), mimetype); + } + else + { + GList *list, *l; + + g_print (_("Default application for “%sâ€: %s\n"), mimetype, g_app_info_get_id (info)); + g_object_unref (info); + + list = g_app_info_get_all_for_type (mimetype); + if (list != NULL) + g_print (_("Registered applications:\n")); + else + g_print (_("No registered applications\n")); + for (l = list; l != NULL; l = l->next) + { + info = l->data; + g_print ("\t%s\n", g_app_info_get_id (info)); + g_object_unref (info); + } + g_list_free (list); + + list = g_app_info_get_recommended_for_type (mimetype); + if (list != NULL) + g_print (_("Recommended applications:\n")); + else + g_print (_("No recommended applications\n")); + for (l = list; l != NULL; l = l->next) + { + info = l->data; + g_print ("\t%s\n", g_app_info_get_id (info)); + g_object_unref (info); + } + g_list_free (list); + } + } + else + { + GAppInfo *info; + + mimetype = argv[1]; + handler = argv[2]; + + info = get_app_info_for_id (handler); + if (info == NULL) + { + print_error (_("Failed to load info for handler “%sâ€"), handler); + return 1; + } + + if (g_app_info_set_as_default_for_type (info, mimetype, &error) == FALSE) + { + print_error (_("Failed to set “%s†as the default handler for “%sâ€: %s\n"), + handler, mimetype, error->message); + g_error_free (error); + g_object_unref (info); + return 1; + } + g_print ("Set %s as the default for %s\n", g_app_info_get_id (info), mimetype); + g_object_unref (info); + } + + return 0; +} diff --git a/gio/gio-tool-mkdir.c b/gio/gio-tool-mkdir.c new file mode 100644 index 0000000..49cb0c3 --- /dev/null +++ b/gio/gio-tool-mkdir.c @@ -0,0 +1,110 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#include "gio-tool.h" + + +static gboolean parent = FALSE; + +static const GOptionEntry entries[] = { + { "parent", 'p', 0, G_OPTION_ARG_NONE, &parent, N_("Create parent directories"), NULL }, + G_OPTION_ENTRY_NULL +}; + +int +handle_mkdir (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + GFile *file; + int retval = 0; + int i; + + g_set_prgname ("gio mkdir"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s…", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, _("Create directories.")); + g_option_context_set_description (context, + _("gio mkdir is similar to the traditional mkdir utility, but using GIO\n" + "locations instead of local files: for example, you can use something\n" + "like smb://server/resource/mydir as location.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 2) + { + show_help (context, _("No locations given")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + for (i = 1; i < argc; i++) + { + file = g_file_new_for_commandline_arg (argv[i]); + error = NULL; + if (parent) + { + if (!g_file_make_directory_with_parents (file, NULL, &error)) + { + print_file_error (file, error->message); + g_error_free (error); + retval = 1; + } + } + else + { + if (!g_file_make_directory (file, NULL, &error)) + { + print_file_error (file, error->message); + g_error_free (error); + retval = 1; + } + g_object_unref (file); + } + } + + return retval; + +} diff --git a/gio/gio-tool-monitor.c b/gio/gio-tool-monitor.c new file mode 100644 index 0000000..9eacfbf --- /dev/null +++ b/gio/gio-tool-monitor.c @@ -0,0 +1,278 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#include "gio-tool.h" + +static gchar **watch_dirs; +static gchar **watch_files; +static gchar **watch_direct; +static gchar **watch_silent; +static gchar **watch_default; +static gboolean no_moves; +static gboolean mounts; + +static const GOptionEntry entries[] = { + { "dir", 'd', 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_dirs, + N_("Monitor a directory (default: depends on type)"), N_("LOCATION") }, + { "file", 'f', 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_files, + N_("Monitor a file (default: depends on type)"), N_("LOCATION") }, + { "direct", 'D', 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_direct, + N_("Monitor a file directly (notices changes made via hardlinks)"), N_("LOCATION") }, + { "silent", 's', 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_silent, + N_("Monitors a file directly, but doesn’t report changes"), N_("LOCATION") }, + { "no-moves", 'n', 0, G_OPTION_ARG_NONE, &no_moves, + N_("Report moves and renames as simple deleted/created events"), NULL }, + { "mounts", 'm', 0, G_OPTION_ARG_NONE, &mounts, + N_("Watch for mount events"), NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_default, + NULL, NULL }, + G_OPTION_ENTRY_NULL +}; + +static void +watch_callback (GFileMonitor *monitor, + GFile *child, + GFile *other, + GFileMonitorEvent event_type, + gpointer user_data) +{ + gchar *child_str; + gchar *other_str; + + g_assert (child); + + if (g_file_is_native (child)) + child_str = g_file_get_path (child); + else + child_str = g_file_get_uri (child); + + if (other) + { + if (g_file_is_native (other)) + other_str = g_file_get_path (other); + else + other_str = g_file_get_uri (other); + } + else + other_str = g_strdup ("(none)"); + + g_print ("%s: ", (gchar *) user_data); + switch (event_type) + { + case G_FILE_MONITOR_EVENT_CHANGED: + g_assert (!other); + g_print ("%s: changed", child_str); + break; + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + g_assert (!other); + g_print ("%s: changes done", child_str); + break; + case G_FILE_MONITOR_EVENT_DELETED: + g_assert (!other); + g_print ("%s: deleted", child_str); + break; + case G_FILE_MONITOR_EVENT_CREATED: + g_assert (!other); + g_print ("%s: created", child_str); + break; + case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: + g_assert (!other); + g_print ("%s: attributes changed", child_str); + break; + case G_FILE_MONITOR_EVENT_PRE_UNMOUNT: + g_assert (!other); + g_print ("%s: pre-unmount", child_str); + break; + case G_FILE_MONITOR_EVENT_UNMOUNTED: + g_assert (!other); + g_print ("%s: unmounted", child_str); + break; + case G_FILE_MONITOR_EVENT_MOVED_IN: + g_print ("%s: moved in", child_str); + if (other) + g_print (" (from %s)", other_str); + break; + case G_FILE_MONITOR_EVENT_MOVED_OUT: + g_print ("%s: moved out", child_str); + if (other) + g_print (" (to %s)", other_str); + break; + case G_FILE_MONITOR_EVENT_RENAMED: + g_assert (other); + g_print ("%s: renamed to %s\n", child_str, other_str); + break; + + case G_FILE_MONITOR_EVENT_MOVED: + default: + g_assert_not_reached (); + } + + g_free (child_str); + g_free (other_str); + g_print ("\n"); +} + +typedef enum +{ + WATCH_DIR, + WATCH_FILE, + WATCH_AUTO +} WatchType; + +static gboolean +add_watch (const gchar *cmdline, + WatchType watch_type, + GFileMonitorFlags flags, + gboolean connect_handler) +{ + GFileMonitor *monitor = NULL; + GError *error = NULL; + GFile *file; + + file = g_file_new_for_commandline_arg (cmdline); + + if (watch_type == WATCH_AUTO) + { + GFileInfo *info; + guint32 type; + + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &error); + if (!info) + goto err; + + type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE); + watch_type = (type == G_FILE_TYPE_DIRECTORY) ? WATCH_DIR : WATCH_FILE; + } + + if (watch_type == WATCH_DIR) + monitor = g_file_monitor_directory (file, flags, NULL, &error); + else + monitor = g_file_monitor (file, flags, NULL, &error); + + if (!monitor) + goto err; + + if (connect_handler) + g_signal_connect (monitor, "changed", G_CALLBACK (watch_callback), g_strdup (cmdline)); + + monitor = NULL; /* leak */ + g_object_unref (file); + + return TRUE; + +err: + print_file_error (file, error->message); + g_error_free (error); + g_object_unref (file); + + return FALSE; +} + +int +handle_monitor (int argc, gchar *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + GFileMonitorFlags flags; + guint i; + + g_set_prgname ("gio monitor"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s…", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Monitor files or directories for changes.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (!watch_dirs && !watch_files && !watch_direct && !watch_silent && !watch_default) + { + show_help (context, _("No locations given")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + flags = (no_moves ? 0 : G_FILE_MONITOR_WATCH_MOVES) | + (mounts ? G_FILE_MONITOR_WATCH_MOUNTS : 0); + + if (watch_dirs) + { + for (i = 0; watch_dirs[i]; i++) + if (!add_watch (watch_dirs[i], WATCH_DIR, flags, TRUE)) + return 1; + } + + if (watch_files) + { + for (i = 0; watch_files[i]; i++) + if (!add_watch (watch_files[i], WATCH_FILE, flags, TRUE)) + return 1; + } + + if (watch_direct) + { + for (i = 0; watch_direct[i]; i++) + if (!add_watch (watch_direct[i], WATCH_FILE, flags | G_FILE_MONITOR_WATCH_HARD_LINKS, TRUE)) + return 1; + } + + if (watch_silent) + { + for (i = 0; watch_silent[i]; i++) + if (!add_watch (watch_silent[i], WATCH_FILE, flags | G_FILE_MONITOR_WATCH_HARD_LINKS, FALSE)) + return 1; + } + + if (watch_default) + { + for (i = 0; watch_default[i]; i++) + if (!add_watch (watch_default[i], WATCH_AUTO, flags, TRUE)) + return 1; + } + + while (TRUE) + g_main_context_iteration (NULL, TRUE); + + return 0; +} diff --git a/gio/gio-tool-mount.c b/gio/gio-tool-mount.c new file mode 100644 index 0000000..c624268 --- /dev/null +++ b/gio/gio-tool-mount.c @@ -0,0 +1,1264 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include +#include +#ifdef HAVE_TERMIOS_H +#include +#endif + +#include "gio-tool.h" + +#define STDIN_FILENO 0 + +typedef enum { + MOUNT_OP_NONE, + MOUNT_OP_ASKED, + MOUNT_OP_ABORTED +} MountOpState; + +static int outstanding_mounts = 0; +static GMainLoop *main_loop; +static GVolumeMonitor *volume_monitor; + +static gboolean mount_mountable = FALSE; +static gboolean mount_unmount = FALSE; +static gboolean mount_eject = FALSE; +static gboolean force = FALSE; +static gboolean anonymous = FALSE; +static gboolean mount_list = FALSE; +static gboolean extra_detail = FALSE; +static gboolean mount_monitor = FALSE; +static gboolean tcrypt_hidden = FALSE; +static gboolean tcrypt_system = FALSE; +static guint tcrypt_pim = 0; +static const char *unmount_scheme = NULL; +static const char *mount_id = NULL; +static const char *stop_device_file = NULL; +static gboolean success = TRUE; + + +static const GOptionEntry entries[] = +{ + { "mountable", 'm', 0, G_OPTION_ARG_NONE, &mount_mountable, N_("Mount as mountable"), NULL }, + { "device", 'd', 0, G_OPTION_ARG_STRING, &mount_id, N_("Mount volume with device file, or other identifier"), N_("ID") }, + { "unmount", 'u', 0, G_OPTION_ARG_NONE, &mount_unmount, N_("Unmount"), NULL}, + { "eject", 'e', 0, G_OPTION_ARG_NONE, &mount_eject, N_("Eject"), NULL}, + { "stop", 't', 0, G_OPTION_ARG_STRING, &stop_device_file, N_("Stop drive with device file"), N_("DEVICE") }, + { "unmount-scheme", 's', 0, G_OPTION_ARG_STRING, &unmount_scheme, N_("Unmount all mounts with the given scheme"), N_("SCHEME") }, + { "force", 'f', 0, G_OPTION_ARG_NONE, &force, N_("Ignore outstanding file operations when unmounting or ejecting"), NULL }, + { "anonymous", 'a', 0, G_OPTION_ARG_NONE, &anonymous, N_("Use an anonymous user when authenticating"), NULL }, + /* Translator: List here is a verb as in 'List all mounts' */ + { "list", 'l', 0, G_OPTION_ARG_NONE, &mount_list, N_("List"), NULL}, + { "monitor", 'o', 0, G_OPTION_ARG_NONE, &mount_monitor, N_("Monitor events"), NULL}, + { "detail", 'i', 0, G_OPTION_ARG_NONE, &extra_detail, N_("Show extra information"), NULL}, + { "tcrypt-pim", 0, 0, G_OPTION_ARG_INT, &tcrypt_pim, N_("The numeric PIM when unlocking a VeraCrypt volume"), N_("PIM")}, + { "tcrypt-hidden", 0, 0, G_OPTION_ARG_NONE, &tcrypt_hidden, N_("Mount a TCRYPT hidden volume"), NULL}, + { "tcrypt-system", 0, 0, G_OPTION_ARG_NONE, &tcrypt_system, N_("Mount a TCRYPT system volume"), NULL}, + G_OPTION_ENTRY_NULL +}; + +static char * +prompt_for (const char *prompt, const char *default_value, gboolean echo) +{ +#ifdef HAVE_TERMIOS_H + struct termios term_attr; + int old_flags; + gboolean restore_flags; +#endif + char data[256]; + int len; + + if (default_value && *default_value != 0) + g_print ("%s [%s]: ", prompt, default_value); + else + g_print ("%s: ", prompt); + + data[0] = 0; + +#ifdef HAVE_TERMIOS_H + restore_flags = FALSE; + if (!echo && tcgetattr (STDIN_FILENO, &term_attr) == 0) + { + old_flags = term_attr.c_lflag; + term_attr.c_lflag &= ~ECHO; + restore_flags = TRUE; + + if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &term_attr) != 0) + g_print ("Warning! Password will be echoed"); + } + +#endif + + fgets(data, sizeof (data), stdin); + +#ifdef HAVE_TERMIOS_H + if (restore_flags) + { + term_attr.c_lflag = old_flags; + tcsetattr (STDIN_FILENO, TCSAFLUSH, &term_attr); + } +#endif + + len = strlen (data); + if (len == 0) + { + g_print ("\n"); + return NULL; + } + if (data[len-1] == '\n') + data[len-1] = 0; + + if (!echo) + g_print ("\n"); + + if (*data == 0 && default_value) + return g_strdup (default_value); + return g_strdup (data); +} + +static void +ask_password_cb (GMountOperation *op, + const char *message, + const char *default_user, + const char *default_domain, + GAskPasswordFlags flags) +{ + if ((flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED) && anonymous) + { + g_mount_operation_set_anonymous (op, TRUE); + } + else + { + char *s; + g_print ("%s\n", message); + + if (flags & G_ASK_PASSWORD_NEED_USERNAME) + { + s = prompt_for ("User", default_user, TRUE); + if (!s) + goto error; + g_mount_operation_set_username (op, s); + g_free (s); + } + + if (flags & G_ASK_PASSWORD_NEED_DOMAIN) + { + s = prompt_for ("Domain", default_domain, TRUE); + if (!s) + goto error; + g_mount_operation_set_domain (op, s); + g_free (s); + } + + if (flags & G_ASK_PASSWORD_NEED_PASSWORD) + { + s = prompt_for ("Password", NULL, FALSE); + if (!s) + goto error; + g_mount_operation_set_password (op, s); + g_free (s); + } + } + + if (flags & G_ASK_PASSWORD_TCRYPT) + { + if (tcrypt_pim) + g_mount_operation_set_pim (op, tcrypt_pim); + if (tcrypt_hidden) + g_mount_operation_set_is_tcrypt_hidden_volume (op, TRUE); + if (tcrypt_system) + g_mount_operation_set_is_tcrypt_system_volume (op, TRUE); + } + + /* Only try anonymous access once. */ + if (anonymous && + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op), "state")) == MOUNT_OP_ASKED) + { + g_object_set_data (G_OBJECT (op), "state", GINT_TO_POINTER (MOUNT_OP_ABORTED)); + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); + } + else + { + g_object_set_data (G_OBJECT (op), "state", GINT_TO_POINTER (MOUNT_OP_ASKED)); + g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); + } + + return; + +error: + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); +} + +static void +ask_question_cb (GMountOperation *op, + char *message, + char **choices, + gpointer user_data) +{ + char **ptr = choices; + char *s; + int i, choice; + + g_print ("%s\n", message); + + i = 1; + while (*ptr) + { + g_print ("[%d] %s\n", i, *ptr++); + i++; + } + + s = prompt_for ("Choice", NULL, TRUE); + if (!s) + goto error; + + choice = atoi (s); + if (choice > 0 && choice < i) + { + g_mount_operation_set_choice (op, choice - 1); + g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); + } + g_free (s); + + return; + +error: + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); +} + +static void +mount_mountable_done_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + GFile *target; + GError *error = NULL; + GMountOperation *op = user_data; + + target = g_file_mount_mountable_finish (G_FILE (object), res, &error); + + if (target == NULL) + { + success = FALSE; + if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op), "state")) == MOUNT_OP_ABORTED) + print_file_error (G_FILE (object), _("Anonymous access denied")); + else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) + print_file_error (G_FILE (object), error->message); + + g_error_free (error); + } + else + g_object_unref (target); + + g_object_unref (op); + + outstanding_mounts--; + + if (outstanding_mounts == 0) + g_main_loop_quit (main_loop); +} + +static void +mount_done_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + gboolean succeeded; + GError *error = NULL; + GMountOperation *op = user_data; + + succeeded = g_file_mount_enclosing_volume_finish (G_FILE (object), res, &error); + + if (!succeeded) + { + success = FALSE; + if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op), "state")) == MOUNT_OP_ABORTED) + print_file_error (G_FILE (object), _("Anonymous access denied")); + else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) + print_file_error (G_FILE (object), error->message); + + g_error_free (error); + } + + g_object_unref (op); + + outstanding_mounts--; + + if (outstanding_mounts == 0) + g_main_loop_quit (main_loop); +} + +static GMountOperation * +new_mount_op (void) +{ + GMountOperation *op; + + op = g_mount_operation_new (); + + g_object_set_data (G_OBJECT (op), "state", GINT_TO_POINTER (MOUNT_OP_NONE)); + + g_signal_connect (op, "ask_password", G_CALLBACK (ask_password_cb), NULL); + g_signal_connect (op, "ask_question", G_CALLBACK (ask_question_cb), NULL); + + /* TODO: we *should* also connect to the "aborted" signal but since the + * main thread is blocked handling input we won't get that signal anyway... + */ + + return op; +} + + +static void +mount (GFile *file) +{ + GMountOperation *op; + + if (file == NULL) + return; + + op = new_mount_op (); + + if (mount_mountable) + g_file_mount_mountable (file, 0, op, NULL, mount_mountable_done_cb, op); + else + g_file_mount_enclosing_volume (file, 0, op, NULL, mount_done_cb, op); + + outstanding_mounts++; +} + +static void +unmount_done_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + gboolean succeeded; + GError *error = NULL; + GFile *file = G_FILE (user_data); + + succeeded = g_mount_unmount_with_operation_finish (G_MOUNT (object), res, &error); + + g_object_unref (G_MOUNT (object)); + + if (!succeeded) + { + print_file_error (file, error->message); + success = FALSE; + g_error_free (error); + } + + g_object_unref (file); + + outstanding_mounts--; + + if (outstanding_mounts == 0) + g_main_loop_quit (main_loop); +} + +static void +unmount (GFile *file) +{ + GMount *mount; + GError *error = NULL; + GMountOperation *mount_op; + GMountUnmountFlags flags; + + if (file == NULL) + return; + + mount = g_file_find_enclosing_mount (file, NULL, &error); + if (mount == NULL) + { + print_file_error (file, error->message); + success = FALSE; + g_error_free (error); + return; + } + + mount_op = new_mount_op (); + flags = force ? G_MOUNT_UNMOUNT_FORCE : G_MOUNT_UNMOUNT_NONE; + g_mount_unmount_with_operation (mount, flags, mount_op, NULL, unmount_done_cb, g_object_ref (file)); + g_object_unref (mount_op); + + outstanding_mounts++; +} + +static void +eject_done_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + gboolean succeeded; + GError *error = NULL; + GFile *file = G_FILE (user_data); + + succeeded = g_mount_eject_with_operation_finish (G_MOUNT (object), res, &error); + + g_object_unref (G_MOUNT (object)); + + if (!succeeded) + { + print_file_error (file, error->message); + success = FALSE; + g_error_free (error); + } + + g_object_unref (file); + + outstanding_mounts--; + + if (outstanding_mounts == 0) + g_main_loop_quit (main_loop); +} + +static void +eject (GFile *file) +{ + GMount *mount; + GError *error = NULL; + GMountOperation *mount_op; + GMountUnmountFlags flags; + + if (file == NULL) + return; + + mount = g_file_find_enclosing_mount (file, NULL, &error); + if (mount == NULL) + { + print_file_error (file, error->message); + success = FALSE; + g_error_free (error); + return; + } + + mount_op = new_mount_op (); + flags = force ? G_MOUNT_UNMOUNT_FORCE : G_MOUNT_UNMOUNT_NONE; + g_mount_eject_with_operation (mount, flags, mount_op, NULL, eject_done_cb, g_object_ref (file)); + g_object_unref (mount_op); + + outstanding_mounts++; +} + +static void +stop_with_device_file_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + gchar *device_path = user_data; + + if (!g_drive_stop_finish (G_DRIVE (object), res, &error)) + { + print_error ("%s: %s", device_path, error->message); + g_error_free (error); + success = FALSE; + } + + g_free (device_path); + + outstanding_mounts--; + + if (outstanding_mounts == 0) + g_main_loop_quit (main_loop); +} + +static void +stop_with_device_file (const char *device_file) +{ + GList *drives; + GList *l; + + drives = g_volume_monitor_get_connected_drives (volume_monitor); + for (l = drives; l != NULL; l = l->next) + { + GDrive *drive = G_DRIVE (l->data); + gchar *id; + + id = g_drive_get_identifier (drive, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); + if (g_strcmp0 (id, device_file) == 0) + { + GMountOperation *op; + GMountUnmountFlags flags; + + op = new_mount_op (); + flags = force ? G_MOUNT_UNMOUNT_FORCE : G_MOUNT_UNMOUNT_NONE; + g_drive_stop (drive, + flags, + op, + NULL, + stop_with_device_file_cb, + g_steal_pointer (&id)); + g_object_unref (op); + + outstanding_mounts++; + } + + g_free (id); + } + g_list_free_full (drives, g_object_unref); + + if (outstanding_mounts == 0) + { + print_error ("%s: %s", device_file, _("No drive for device file")); + success = FALSE; + } +} + +static gboolean +iterate_gmain_timeout_function (gpointer data) +{ + g_main_loop_quit (main_loop); + return FALSE; +} + +static void +iterate_gmain(void) +{ + g_timeout_add (500, iterate_gmain_timeout_function, NULL); + g_main_loop_run (main_loop); +} + +static void +show_themed_icon_names (GThemedIcon *icon, gboolean symbolic, int indent) +{ + char **names; + char **iter; + + g_print ("%*s%sthemed icons:", indent, " ", symbolic ? "symbolic " : ""); + + names = NULL; + + g_object_get (icon, "names", &names, NULL); + + for (iter = names; *iter; iter++) + g_print (" [%s]", *iter); + + g_print ("\n"); + g_strfreev (names); +} + +/* don't copy-paste this code */ +static char * +get_type_name (gpointer object) +{ + const char *type_name; + char *ret; + + type_name = g_type_name (G_TYPE_FROM_INSTANCE (object)); + if (strcmp ("GProxyDrive", type_name) == 0) + { + ret = g_strdup_printf ("%s (%s)", + type_name, + (const char *) g_object_get_data (G_OBJECT (object), + "g-proxy-drive-volume-monitor-name")); + } + else if (strcmp ("GProxyVolume", type_name) == 0) + { + ret = g_strdup_printf ("%s (%s)", + type_name, + (const char *) g_object_get_data (G_OBJECT (object), + "g-proxy-volume-volume-monitor-name")); + } + else if (strcmp ("GProxyMount", type_name) == 0) + { + ret = g_strdup_printf ("%s (%s)", + type_name, + (const char *) g_object_get_data (G_OBJECT (object), + "g-proxy-mount-volume-monitor-name")); + } + else if (strcmp ("GProxyShadowMount", type_name) == 0) + { + ret = g_strdup_printf ("%s (%s)", + type_name, + (const char *) g_object_get_data (G_OBJECT (object), + "g-proxy-shadow-mount-volume-monitor-name")); + } + else + { + ret = g_strdup (type_name); + } + + return ret; +} + +static void +list_mounts (GList *mounts, + int indent, + gboolean only_with_no_volume) +{ + GList *l; + int c; + GMount *mount; + GVolume *volume; + char *name, *uuid, *uri; + GFile *root, *default_location; + GIcon *icon; + char **x_content_types; + char *type_name; + const gchar *sort_key; + + for (c = 0, l = mounts; l != NULL; l = l->next, c++) + { + mount = (GMount *) l->data; + + if (only_with_no_volume) + { + volume = g_mount_get_volume (mount); + if (volume != NULL) + { + g_object_unref (volume); + continue; + } + } + + name = g_mount_get_name (mount); + root = g_mount_get_root (mount); + uri = g_file_get_uri (root); + + g_print ("%*sMount(%d): %s -> %s\n", indent, "", c, name, uri); + + type_name = get_type_name (mount); + g_print ("%*sType: %s\n", indent+2, "", type_name); + g_free (type_name); + + if (extra_detail) + { + uuid = g_mount_get_uuid (mount); + if (uuid) + g_print ("%*suuid=%s\n", indent + 2, "", uuid); + + default_location = g_mount_get_default_location (mount); + if (default_location) + { + char *loc_uri = g_file_get_uri (default_location); + g_print ("%*sdefault_location=%s\n", indent + 2, "", loc_uri); + g_free (loc_uri); + g_object_unref (default_location); + } + + icon = g_mount_get_icon (mount); + if (icon) + { + if (G_IS_THEMED_ICON (icon)) + show_themed_icon_names (G_THEMED_ICON (icon), FALSE, indent + 2); + + g_object_unref (icon); + } + + icon = g_mount_get_symbolic_icon (mount); + if (icon) + { + if (G_IS_THEMED_ICON (icon)) + show_themed_icon_names (G_THEMED_ICON (icon), TRUE, indent + 2); + + g_object_unref (icon); + } + + x_content_types = g_mount_guess_content_type_sync (mount, FALSE, NULL, NULL); + if (x_content_types != NULL && g_strv_length (x_content_types) > 0) + { + int n; + g_print ("%*sx_content_types:", indent + 2, ""); + for (n = 0; x_content_types[n] != NULL; n++) + g_print (" %s", x_content_types[n]); + g_print ("\n"); + } + g_strfreev (x_content_types); + + g_print ("%*scan_unmount=%d\n", indent + 2, "", g_mount_can_unmount (mount)); + g_print ("%*scan_eject=%d\n", indent + 2, "", g_mount_can_eject (mount)); + g_print ("%*sis_shadowed=%d\n", indent + 2, "", g_mount_is_shadowed (mount)); + sort_key = g_mount_get_sort_key (mount); + if (sort_key != NULL) + g_print ("%*ssort_key=%s\n", indent + 2, "", sort_key); + g_free (uuid); + } + + g_object_unref (root); + g_free (name); + g_free (uri); + } +} + +static void +list_volumes (GList *volumes, + int indent, + gboolean only_with_no_drive) +{ + GList *l, *mounts; + int c, i; + GMount *mount; + GVolume *volume; + GDrive *drive; + char *name; + char *uuid; + GFile *activation_root; + char **ids; + GIcon *icon; + char *type_name; + const gchar *sort_key; + + for (c = 0, l = volumes; l != NULL; l = l->next, c++) + { + volume = (GVolume *) l->data; + + if (only_with_no_drive) + { + drive = g_volume_get_drive (volume); + if (drive != NULL) + { + g_object_unref (drive); + continue; + } + } + + name = g_volume_get_name (volume); + + g_print ("%*sVolume(%d): %s\n", indent, "", c, name); + g_free (name); + + type_name = get_type_name (volume); + g_print ("%*sType: %s\n", indent+2, "", type_name); + g_free (type_name); + + if (extra_detail) + { + ids = g_volume_enumerate_identifiers (volume); + if (ids && ids[0] != NULL) + { + g_print ("%*sids:\n", indent+2, ""); + for (i = 0; ids[i] != NULL; i++) + { + char *id = g_volume_get_identifier (volume, + ids[i]); + g_print ("%*s %s: '%s'\n", indent+2, "", ids[i], id); + g_free (id); + } + } + g_strfreev (ids); + + uuid = g_volume_get_uuid (volume); + if (uuid) + g_print ("%*suuid=%s\n", indent + 2, "", uuid); + activation_root = g_volume_get_activation_root (volume); + if (activation_root) + { + char *uri; + uri = g_file_get_uri (activation_root); + g_print ("%*sactivation_root=%s\n", indent + 2, "", uri); + g_free (uri); + g_object_unref (activation_root); + } + icon = g_volume_get_icon (volume); + if (icon) + { + if (G_IS_THEMED_ICON (icon)) + show_themed_icon_names (G_THEMED_ICON (icon), FALSE, indent + 2); + + g_object_unref (icon); + } + + icon = g_volume_get_symbolic_icon (volume); + if (icon) + { + if (G_IS_THEMED_ICON (icon)) + show_themed_icon_names (G_THEMED_ICON (icon), TRUE, indent + 2); + + g_object_unref (icon); + } + + g_print ("%*scan_mount=%d\n", indent + 2, "", g_volume_can_mount (volume)); + g_print ("%*scan_eject=%d\n", indent + 2, "", g_volume_can_eject (volume)); + g_print ("%*sshould_automount=%d\n", indent + 2, "", g_volume_should_automount (volume)); + sort_key = g_volume_get_sort_key (volume); + if (sort_key != NULL) + g_print ("%*ssort_key=%s\n", indent + 2, "", sort_key); + g_free (uuid); + } + + mount = g_volume_get_mount (volume); + if (mount) + { + mounts = g_list_prepend (NULL, mount); + list_mounts (mounts, indent + 2, FALSE); + g_list_free (mounts); + g_object_unref (mount); + } + } +} + +static void +list_drives (GList *drives, + int indent) +{ + GList *volumes, *l; + int c, i; + GDrive *drive; + char *name; + char **ids; + GIcon *icon; + char *type_name; + const gchar *sort_key; + + for (c = 0, l = drives; l != NULL; l = l->next, c++) + { + drive = (GDrive *) l->data; + name = g_drive_get_name (drive); + + g_print ("%*sDrive(%d): %s\n", indent, "", c, name); + g_free (name); + + type_name = get_type_name (drive); + g_print ("%*sType: %s\n", indent+2, "", type_name); + g_free (type_name); + + if (extra_detail) + { + GEnumValue *enum_value; + gpointer klass; + + ids = g_drive_enumerate_identifiers (drive); + if (ids && ids[0] != NULL) + { + g_print ("%*sids:\n", indent+2, ""); + for (i = 0; ids[i] != NULL; i++) + { + char *id = g_drive_get_identifier (drive, + ids[i]); + g_print ("%*s %s: '%s'\n", indent+2, "", ids[i], id); + g_free (id); + } + } + g_strfreev (ids); + + icon = g_drive_get_icon (drive); + if (icon) + { + if (G_IS_THEMED_ICON (icon)) + show_themed_icon_names (G_THEMED_ICON (icon), FALSE, indent + 2); + g_object_unref (icon); + } + + icon = g_drive_get_symbolic_icon (drive); + if (icon) + { + if (G_IS_THEMED_ICON (icon)) + show_themed_icon_names (G_THEMED_ICON (icon), TRUE, indent + 2); + + g_object_unref (icon); + } + + g_print ("%*sis_removable=%d\n", indent + 2, "", g_drive_is_removable (drive)); + g_print ("%*sis_media_removable=%d\n", indent + 2, "", g_drive_is_media_removable (drive)); + g_print ("%*shas_media=%d\n", indent + 2, "", g_drive_has_media (drive)); + g_print ("%*sis_media_check_automatic=%d\n", indent + 2, "", g_drive_is_media_check_automatic (drive)); + g_print ("%*scan_poll_for_media=%d\n", indent + 2, "", g_drive_can_poll_for_media (drive)); + g_print ("%*scan_eject=%d\n", indent + 2, "", g_drive_can_eject (drive)); + g_print ("%*scan_start=%d\n", indent + 2, "", g_drive_can_start (drive)); + g_print ("%*scan_stop=%d\n", indent + 2, "", g_drive_can_stop (drive)); + + enum_value = NULL; + klass = g_type_class_ref (G_TYPE_DRIVE_START_STOP_TYPE); + if (klass != NULL) + { + enum_value = g_enum_get_value (klass, g_drive_get_start_stop_type (drive)); + g_print ("%*sstart_stop_type=%s\n", indent + 2, "", + enum_value != NULL ? enum_value->value_nick : "UNKNOWN"); + g_type_class_unref (klass); + } + + sort_key = g_drive_get_sort_key (drive); + if (sort_key != NULL) + g_print ("%*ssort_key=%s\n", indent + 2, "", sort_key); + } + volumes = g_drive_get_volumes (drive); + list_volumes (volumes, indent + 2, FALSE); + g_list_free_full (volumes, g_object_unref); + } +} + + +static void +list_monitor_items (void) +{ + GList *drives, *volumes, *mounts; + + /* populate gvfs network mounts */ + iterate_gmain(); + + drives = g_volume_monitor_get_connected_drives (volume_monitor); + list_drives (drives, 0); + g_list_free_full (drives, g_object_unref); + + volumes = g_volume_monitor_get_volumes (volume_monitor); + list_volumes (volumes, 0, TRUE); + g_list_free_full (volumes, g_object_unref); + + mounts = g_volume_monitor_get_mounts (volume_monitor); + list_mounts (mounts, 0, TRUE); + g_list_free_full (mounts, g_object_unref); +} + +static void +unmount_all_with_scheme (const char *scheme) +{ + GList *mounts; + GList *l; + + /* populate gvfs network mounts */ + iterate_gmain(); + + mounts = g_volume_monitor_get_mounts (volume_monitor); + for (l = mounts; l != NULL; l = l->next) { + GMount *mount = G_MOUNT (l->data); + GFile *root; + + root = g_mount_get_root (mount); + if (g_file_has_uri_scheme (root, scheme)) { + unmount (root); + } + g_object_unref (root); + } + g_list_free_full (mounts, g_object_unref); +} + +static void +mount_with_device_file_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + GVolume *volume; + gboolean succeeded; + GError *error = NULL; + gchar *id = (gchar *)user_data; + + volume = G_VOLUME (object); + + succeeded = g_volume_mount_finish (volume, res, &error); + + if (!succeeded) + { + print_error ("%s: %s", id, error->message); + g_error_free (error); + success = FALSE; + } + + g_free (id); + + outstanding_mounts--; + + if (outstanding_mounts == 0) + g_main_loop_quit (main_loop); +} + +static void +mount_with_id (const char *id) +{ + GList *volumes; + GList *l; + + volumes = g_volume_monitor_get_volumes (volume_monitor); + for (l = volumes; l != NULL; l = l->next) + { + GVolume *volume = G_VOLUME (l->data); + gchar *device; + gchar *uuid; + + device = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); + uuid = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UUID); + if (g_strcmp0 (device, id) == 0 || g_strcmp0 (uuid, id) == 0) + { + GMountOperation *op; + + op = new_mount_op (); + + g_volume_mount (volume, + G_MOUNT_MOUNT_NONE, + op, + NULL, + mount_with_device_file_cb, + g_strdup (id)); + + g_object_unref (op); + + outstanding_mounts++; + } + + g_free (device); + g_free (uuid); + } + g_list_free_full (volumes, g_object_unref); + + if (outstanding_mounts == 0) + { + print_error ("%s: %s", id, _("No volume for given ID")); + success = FALSE; + } +} + +static void +monitor_print_mount (GMount *mount) +{ + if (extra_detail) + { + GList *l; + l = g_list_prepend (NULL, mount); + list_mounts (l, 2, FALSE); + g_list_free (l); + g_print ("\n"); + } +} + +static void +monitor_print_volume (GVolume *volume) +{ + if (extra_detail) + { + GList *l; + l = g_list_prepend (NULL, volume); + list_volumes (l, 2, FALSE); + g_list_free (l); + g_print ("\n"); + } +} + +static void +monitor_print_drive (GDrive *drive) +{ + if (extra_detail) + { + GList *l; + l = g_list_prepend (NULL, drive); + list_drives (l, 2); + g_list_free (l); + g_print ("\n"); + } +} + +static void +monitor_mount_added (GVolumeMonitor *volume_monitor, GMount *mount) +{ + char *name; + name = g_mount_get_name (mount); + g_print ("Mount added: '%s'\n", name); + g_free (name); + monitor_print_mount (mount); +} + +static void +monitor_mount_removed (GVolumeMonitor *volume_monitor, GMount *mount) +{ + char *name; + name = g_mount_get_name (mount); + g_print ("Mount removed: '%s'\n", name); + g_free (name); + monitor_print_mount (mount); +} + +static void +monitor_mount_changed (GVolumeMonitor *volume_monitor, GMount *mount) +{ + char *name; + name = g_mount_get_name (mount); + g_print ("Mount changed: '%s'\n", name); + g_free (name); + monitor_print_mount (mount); +} + +static void +monitor_mount_pre_unmount (GVolumeMonitor *volume_monitor, GMount *mount) +{ + char *name; + name = g_mount_get_name (mount); + g_print ("Mount pre-unmount: '%s'\n", name); + g_free (name); + monitor_print_mount (mount); +} + +static void +monitor_volume_added (GVolumeMonitor *volume_monitor, GVolume *volume) +{ + char *name; + name = g_volume_get_name (volume); + g_print ("Volume added: '%s'\n", name); + g_free (name); + monitor_print_volume (volume); +} + +static void +monitor_volume_removed (GVolumeMonitor *volume_monitor, GVolume *volume) +{ + char *name; + name = g_volume_get_name (volume); + g_print ("Volume removed: '%s'\n", name); + g_free (name); + monitor_print_volume (volume); +} + +static void +monitor_volume_changed (GVolumeMonitor *volume_monitor, GVolume *volume) +{ + char *name; + name = g_volume_get_name (volume); + g_print ("Volume changed: '%s'\n", name); + g_free (name); + monitor_print_volume (volume); +} + +static void +monitor_drive_connected (GVolumeMonitor *volume_monitor, GDrive *drive) +{ + char *name; + name = g_drive_get_name (drive); + g_print ("Drive connected: '%s'\n", name); + g_free (name); + monitor_print_drive (drive); +} + +static void +monitor_drive_disconnected (GVolumeMonitor *volume_monitor, GDrive *drive) +{ + char *name; + name = g_drive_get_name (drive); + g_print ("Drive disconnected: '%s'\n", name); + g_free (name); + monitor_print_drive (drive); +} + +static void +monitor_drive_changed (GVolumeMonitor *volume_monitor, GDrive *drive) +{ + char *name; + name = g_drive_get_name (drive); + g_print ("Drive changed: '%s'\n", name); + g_free (name); + monitor_print_drive (drive); +} + +static void +monitor_drive_eject_button (GVolumeMonitor *volume_monitor, GDrive *drive) +{ + char *name; + name = g_drive_get_name (drive); + g_print ("Drive eject button: '%s'\n", name); + g_free (name); +} + +static void +monitor (void) +{ + g_signal_connect (volume_monitor, "mount-added", (GCallback) monitor_mount_added, NULL); + g_signal_connect (volume_monitor, "mount-removed", (GCallback) monitor_mount_removed, NULL); + g_signal_connect (volume_monitor, "mount-changed", (GCallback) monitor_mount_changed, NULL); + g_signal_connect (volume_monitor, "mount-pre-unmount", (GCallback) monitor_mount_pre_unmount, NULL); + g_signal_connect (volume_monitor, "volume-added", (GCallback) monitor_volume_added, NULL); + g_signal_connect (volume_monitor, "volume-removed", (GCallback) monitor_volume_removed, NULL); + g_signal_connect (volume_monitor, "volume-changed", (GCallback) monitor_volume_changed, NULL); + g_signal_connect (volume_monitor, "drive-connected", (GCallback) monitor_drive_connected, NULL); + g_signal_connect (volume_monitor, "drive-disconnected", (GCallback) monitor_drive_disconnected, NULL); + g_signal_connect (volume_monitor, "drive-changed", (GCallback) monitor_drive_changed, NULL); + g_signal_connect (volume_monitor, "drive-eject-button", (GCallback) monitor_drive_eject_button, NULL); + + g_print ("Monitoring events. Press Ctrl+C to quit.\n"); + + g_main_loop_run (main_loop); +} + +int +handle_mount (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + GFile *file; + int i; + + g_set_prgname ("gio mount"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("[%s…]", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, _("Mount or unmount the locations.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + main_loop = g_main_loop_new (NULL, FALSE); + volume_monitor = g_volume_monitor_get (); + + if (mount_list) + list_monitor_items (); + else if (mount_id != NULL) + mount_with_id (mount_id); + else if (stop_device_file) + stop_with_device_file (stop_device_file); + else if (unmount_scheme != NULL) + unmount_all_with_scheme (unmount_scheme); + else if (mount_monitor) + monitor (); + else if (argc > 1) + { + for (i = 1; i < argc; i++) + { + file = g_file_new_for_commandline_arg (argv[i]); + if (mount_unmount) + unmount (file); + else if (mount_eject) + eject (file); + else + mount (file); + g_object_unref (file); + } + } + else + { + show_help (context, _("No locations given")); + g_option_context_free (context); + g_object_unref (volume_monitor); + return 1; + } + + g_option_context_free (context); + + if (outstanding_mounts > 0) + g_main_loop_run (main_loop); + + g_object_unref (volume_monitor); + + return success ? 0 : 2; +} diff --git a/gio/gio-tool-move.c b/gio/gio-tool-move.c new file mode 100644 index 0000000..9be51bc --- /dev/null +++ b/gio/gio-tool-move.c @@ -0,0 +1,216 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#include "gio-tool.h" + + +/* statics {{{1 */ + +static gboolean no_target_directory = FALSE; +static gboolean progress = FALSE; +static gboolean interactive = FALSE; +static gboolean backup = FALSE; +static gboolean no_copy_fallback = FALSE; + +static const GOptionEntry entries[] = { + { "no-target-directory", 'T', 0, G_OPTION_ARG_NONE, &no_target_directory, N_("No target directory"), NULL }, + { "progress", 'p', 0, G_OPTION_ARG_NONE, &progress, N_("Show progress"), NULL }, + { "interactive", 'i', 0, G_OPTION_ARG_NONE, &interactive, N_("Prompt before overwrite"), NULL }, + { "backup", 'b', 0, G_OPTION_ARG_NONE, &backup, N_("Backup existing destination files"), NULL }, + { "no-copy-fallback", 'C', 0, G_OPTION_ARG_NONE, &no_copy_fallback, N_("Don’t use copy and delete fallback"), NULL }, + G_OPTION_ENTRY_NULL +}; + +static gint64 start_time; +static gint64 previous_time; + +static void +show_progress (goffset current_num_bytes, + goffset total_num_bytes, + gpointer user_data) +{ + gint64 tv; + char *current_size, *total_size, *rate; + + tv = g_get_monotonic_time (); + if (tv - previous_time < (G_USEC_PER_SEC / 5) && + current_num_bytes != total_num_bytes) + return; + + current_size = g_format_size (current_num_bytes); + total_size = g_format_size (total_num_bytes); + rate = g_format_size (current_num_bytes / + MAX ((tv - start_time) / G_USEC_PER_SEC, 1)); + g_print ("\r\033[K"); + g_print (_("Transferred %s out of %s (%s/s)"), + current_size, total_size, rate); + + previous_time = tv; + + g_free (current_size); + g_free (total_size); + g_free (rate); +} + +int +handle_move (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + GFile *source, *dest, *target; + gboolean dest_is_dir; + char *basename; + char *uri; + int i; + GFileCopyFlags flags; + int retval = 0; + + g_set_prgname ("gio move"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s… %s", _("SOURCE"), _("DESTINATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Move one or more files from SOURCE to DEST.")); + g_option_context_set_description (context, + _("gio move is similar to the traditional mv utility, but using GIO\n" + "locations instead of local files: for example, you can use something\n" + "like smb://server/resource/file.txt as location")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 3) + { + show_help (context, NULL); + g_option_context_free (context); + return 1; + } + + dest = g_file_new_for_commandline_arg (argv[argc - 1]); + + if (no_target_directory && argc > 3) + { + show_help (context, NULL); + g_object_unref (dest); + g_option_context_free (context); + return 1; + } + + dest_is_dir = file_is_dir (dest); + + if (!dest_is_dir && argc > 3) + { + char *message; + message = g_strdup_printf (_("Target %s is not a directory"), argv[argc - 1]); + show_help (context, message); + g_free (message); + g_object_unref (dest); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + for (i = 1; i < argc - 1; i++) + { + source = g_file_new_for_commandline_arg (argv[i]); + + if (dest_is_dir && !no_target_directory) + { + basename = g_file_get_basename (source); + target = g_file_get_child (dest, basename); + g_free (basename); + } + else + target = g_object_ref (dest); + + flags = 0; + if (backup) + flags |= G_FILE_COPY_BACKUP; + if (!interactive) + flags |= G_FILE_COPY_OVERWRITE; + if (no_copy_fallback) + flags |= G_FILE_COPY_NO_FALLBACK_FOR_MOVE; + + error = NULL; + start_time = g_get_monotonic_time (); + if (!g_file_move (source, target, flags, NULL, progress ? show_progress : NULL, NULL, &error)) + { + if (interactive && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) + { + char line[16]; + + g_error_free (error); + error = NULL; + + uri = g_file_get_uri (target); + g_print (_("%s: overwrite “%sâ€? "), argv[0], uri); + g_free (uri); + if (fgets (line, sizeof (line), stdin) && + (line[0] == 'y' || line[0] == 'Y')) + { + flags |= G_FILE_COPY_OVERWRITE; + start_time = g_get_monotonic_time (); + if (!g_file_move (source, target, flags, NULL, progress ? show_progress : NULL, NULL, &error)) + goto move_failed; + } + } + else + { + move_failed: + print_file_error (source, error->message); + g_error_free (error); + retval = 1; + } + } + + if (progress && retval == 0) + g_print("\n"); + + g_object_unref (source); + g_object_unref (target); + } + + g_object_unref (dest); + + return retval; +} diff --git a/gio/gio-tool-open.c b/gio/gio-tool-open.c new file mode 100644 index 0000000..f55057b --- /dev/null +++ b/gio/gio-tool-open.c @@ -0,0 +1,140 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include + +#if defined(G_OS_UNIX) && !defined(HAVE_COCOA) +#include +#endif + +#include + +#include "gio-tool.h" + +static int n_outstanding = 0; +static gboolean success = TRUE; + +static const GOptionEntry entries[] = { + G_OPTION_ENTRY_NULL +}; + +static void +launch_default_for_uri_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + gchar *uri = user_data; + + if (!g_app_info_launch_default_for_uri_finish (res, &error)) + { + print_error ("%s: %s", uri, error->message); + g_clear_error (&error); + success = FALSE; + } + + n_outstanding--; + + g_free (uri); +} + +int +handle_open (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + int i; + + g_set_prgname ("gio open"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s…", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Open files with the default application that\n" + "is registered to handle files of this type.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 2) + { + show_help (context, _("No locations given")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + for (i = 1; i < argc; i++) + { + char *uri = NULL; + char *uri_scheme; + + /* Workaround to handle non-URI locations. We still use the original + * location for other cases, because GFile might modify the URI in ways + * we don't want. See: + * https://bugzilla.gnome.org/show_bug.cgi?id=779182 */ + uri_scheme = g_uri_parse_scheme (argv[i]); + if (!uri_scheme || uri_scheme[0] == '\0') + { + GFile *file; + + file = g_file_new_for_commandline_arg (argv[i]); + uri = g_file_get_uri (file); + g_object_unref (file); + } + else + uri = g_strdup (argv[i]); + g_free (uri_scheme); + + g_app_info_launch_default_for_uri_async (uri, + NULL, + NULL, + launch_default_for_uri_cb, + g_strdup (uri)); + + n_outstanding++; + + g_free (uri); + } + + while (n_outstanding > 0) + g_main_context_iteration (NULL, TRUE); + + return success ? 0 : 2; +} diff --git a/gio/gio-tool-remove.c b/gio/gio-tool-remove.c new file mode 100644 index 0000000..fb995bf --- /dev/null +++ b/gio/gio-tool-remove.c @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#include "gio-tool.h" + + +static gboolean force = FALSE; + +static const GOptionEntry entries[] = { + {"force", 'f', 0, G_OPTION_ARG_NONE, &force, N_("Ignore nonexistent files, never prompt"), NULL}, + G_OPTION_ENTRY_NULL +}; + +int +handle_remove (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + GFile *file; + int retval; + int i; + + g_set_prgname ("gio remove"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s…", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, _("Delete the given files.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc == 1) + { + show_help (context, _("No locations given")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + retval = 0; + for (i = 1; i < argc; i++) + { + file = g_file_new_for_commandline_arg (argv[i]); + if (!g_file_delete (file, NULL, &error)) + { + if (!force || + !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + print_file_error (file, error->message); + retval = 1; + } + g_clear_error (&error); + } + g_object_unref (file); + } + + return retval; +} diff --git a/gio/gio-tool-rename.c b/gio/gio-tool-rename.c new file mode 100644 index 0000000..0070b6c --- /dev/null +++ b/gio/gio-tool-rename.c @@ -0,0 +1,103 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#include "gio-tool.h" + + +static const GOptionEntry entries[] = { + G_OPTION_ENTRY_NULL +}; + +int +handle_rename (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + GError *error = NULL; + GFile *file; + GFile *new_file; + int retval = 0; + gchar *param; + + g_set_prgname ("gio rename"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s %s", _("LOCATION"), _("NAME")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + + g_option_context_set_summary (context, _("Rename a file.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 3) + { + show_help (context, _("Missing argument")); + g_option_context_free (context); + return 1; + } + if (argc > 3) + { + show_help (context, _("Too many arguments")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + file = g_file_new_for_commandline_arg (argv[1]); + new_file = g_file_set_display_name (file, argv[2], NULL, &error); + + if (new_file == NULL) + { + print_error ("%s", error->message); + g_error_free (error); + retval = 1; + } + else + { + char *uri = g_file_get_uri (new_file); + g_print (_("Rename successful. New uri: %s\n"), uri); + g_object_unref (new_file); + g_free (uri); + } + + g_object_unref (file); + + return retval; +} diff --git a/gio/gio-tool-save.c b/gio/gio-tool-save.c new file mode 100644 index 0000000..30fb3f9 --- /dev/null +++ b/gio/gio-tool-save.c @@ -0,0 +1,202 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#ifdef G_OS_WIN32 +#include +#endif + +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "gio-tool.h" + +static char *etag = NULL; +static gboolean backup = FALSE; +static gboolean create = FALSE; +static gboolean append = FALSE; +static gboolean priv = FALSE; +static gboolean replace_dest = FALSE; +static gboolean print_etag = FALSE; + +static const GOptionEntry entries[] = +{ + { "backup", 'b', 0, G_OPTION_ARG_NONE, &backup, N_("Backup existing destination files"), NULL }, + { "create", 'c', 0, G_OPTION_ARG_NONE, &create, N_("Only create if not existing"), NULL }, + { "append", 'a', 0, G_OPTION_ARG_NONE, &append, N_("Append to end of file"), NULL }, + { "private", 'p', 0, G_OPTION_ARG_NONE, &priv, N_("When creating, restrict access to the current user"), NULL }, + { "unlink", 'u', 0, G_OPTION_ARG_NONE, &replace_dest, N_("When replacing, replace as if the destination did not exist"), NULL }, + /* Translators: The "etag" is a token allowing to verify whether a file has been modified */ + { "print-etag", 'v', 0, G_OPTION_ARG_NONE, &print_etag, N_("Print new etag at end"), NULL }, + /* Translators: The "etag" is a token allowing to verify whether a file has been modified */ + { "etag", 'e', 0, G_OPTION_ARG_STRING, &etag, N_("The etag of the file being overwritten"), N_("ETAG") }, + G_OPTION_ENTRY_NULL +}; + +/* 256k minus malloc overhead */ +#define STREAM_BUFFER_SIZE (1024*256 - 2*sizeof(gpointer)) + +static gboolean +save (GFile *file) +{ + GOutputStream *out; + GFileCreateFlags flags; + char *buffer; + gssize res; + gboolean close_res; + GError *error; + gboolean save_res; + + error = NULL; + + flags = priv ? G_FILE_CREATE_PRIVATE : G_FILE_CREATE_NONE; + flags |= replace_dest ? G_FILE_CREATE_REPLACE_DESTINATION : 0; + + if (create) + out = (GOutputStream *)g_file_create (file, flags, NULL, &error); + else if (append) + out = (GOutputStream *)g_file_append_to (file, flags, NULL, &error); + else + out = (GOutputStream *)g_file_replace (file, etag, backup, flags, NULL, &error); + if (out == NULL) + { + print_file_error (file, error->message); + g_error_free (error); + return FALSE; + } + + buffer = g_malloc (STREAM_BUFFER_SIZE); + save_res = TRUE; + + while (1) + { + res = read (STDIN_FILENO, buffer, STREAM_BUFFER_SIZE); + if (res > 0) + { + g_output_stream_write_all (out, buffer, res, NULL, NULL, &error); + if (error != NULL) + { + save_res = FALSE; + print_file_error (file, error->message); + g_clear_error (&error); + goto out; + } + } + else if (res < 0) + { + save_res = FALSE; + print_error ("%s", _("Error reading from standard input")); + break; + } + else if (res == 0) + break; + } + + out: + + close_res = g_output_stream_close (out, NULL, &error); + if (!close_res) + { + save_res = FALSE; + print_file_error (file, error->message); + g_error_free (error); + } + + if (close_res && print_etag) + { + char *etag; + etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (out)); + + if (etag) + g_print ("Etag: %s\n", etag); + else + /* Translators: The "etag" is a token allowing to verify whether a file has been modified */ + g_print (_("Etag not available\n")); + g_free (etag); + } + + g_object_unref (out); + g_free (buffer); + + return save_res; +} + +int +handle_save (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + GError *error = NULL; + GFile *file; + gboolean res; + + g_set_prgname ("gio save"); + + /* Translators: commandline placeholder */ + context = g_option_context_new (_("DESTINATION")); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Read from standard input and save to DEST.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 2) + { + show_help (context, _("No destination given")); + g_option_context_free (context); + return 1; + } + + if (argc > 2) + { + show_help (context, _("Too many arguments")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + file = g_file_new_for_commandline_arg (argv[1]); + res = save (file); + g_object_unref (file); + + return res ? 0 : 2; +} diff --git a/gio/gio-tool-set.c b/gio/gio-tool-set.c new file mode 100644 index 0000000..c2a9431 --- /dev/null +++ b/gio/gio-tool-set.c @@ -0,0 +1,206 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#include "gio-tool.h" + + +static char *attr_type = "string"; +static gboolean nofollow_symlinks = FALSE; + +static const GOptionEntry entries[] = { + { "type", 't', 0, G_OPTION_ARG_STRING, &attr_type, N_("Type of the attribute"), N_("TYPE") }, + { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL }, + G_OPTION_ENTRY_NULL +}; + +static char * +hex_unescape (const char *str) +{ + int i; + char *unescaped_str, *p; + unsigned char c; + int len; + + len = strlen (str); + unescaped_str = g_malloc (len + 1); + + p = unescaped_str; + for (i = 0; i < len; i++) + { + if (str[i] == '\\' && + str[i+1] == 'x' && + len - i >= 4) + { + c = + (g_ascii_xdigit_value (str[i+2]) << 4) | + g_ascii_xdigit_value (str[i+3]); + *p++ = c; + i += 3; + } + else + *p++ = str[i]; + } + *p++ = 0; + + return unescaped_str; +} + +int +handle_set (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + GError *error = NULL; + GFile *file; + const char *attribute; + GFileAttributeType type; + gpointer value; + gpointer value_allocated = NULL; + gboolean b; + guint32 uint32; + gint32 int32; + guint64 uint64; + gint64 int64; + gchar *param; + int retval = 0; + + g_set_prgname ("gio set"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("%s %s %s…", _("LOCATION"), _("ATTRIBUTE"), _("VALUE")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, _("Set a file attribute of LOCATION.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc < 2) + { + show_help (context, _("Location not specified")); + g_option_context_free (context); + return 1; + } + + if (argc < 3) + { + show_help (context, _("Attribute not specified")); + g_option_context_free (context); + return 1; + } + + attribute = argv[2]; + + type = attribute_type_from_string (attr_type); + if ((argc < 4) && (type != G_FILE_ATTRIBUTE_TYPE_INVALID)) + { + show_help (context, _("Value not specified")); + g_option_context_free (context); + return 1; + } + + if ((argc > 4) && (type != G_FILE_ATTRIBUTE_TYPE_STRINGV)) + { + show_help (context, _("Too many arguments")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + switch (type) + { + case G_FILE_ATTRIBUTE_TYPE_STRING: + value = argv[3]; + break; + case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: + value = value_allocated = hex_unescape (argv[3]); + break; + case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: + b = g_ascii_strcasecmp (argv[3], "true") == 0; + value = &b; + break; + case G_FILE_ATTRIBUTE_TYPE_UINT32: + uint32 = atol (argv[3]); + value = &uint32; + break; + case G_FILE_ATTRIBUTE_TYPE_INT32: + int32 = atol (argv[3]); + value = &int32; + break; + case G_FILE_ATTRIBUTE_TYPE_UINT64: + uint64 = g_ascii_strtoull (argv[3], NULL, 10); + value = &uint64; + break; + case G_FILE_ATTRIBUTE_TYPE_INT64: + int64 = g_ascii_strtoll (argv[3], NULL, 10); + value = &int64; + break; + case G_FILE_ATTRIBUTE_TYPE_STRINGV: + value = &argv[3]; + break; + case G_FILE_ATTRIBUTE_TYPE_INVALID: + value = NULL; + break; + case G_FILE_ATTRIBUTE_TYPE_OBJECT: + default: + print_error (_("Invalid attribute type “%sâ€"), attr_type); + return 1; + } + + file = g_file_new_for_commandline_arg (argv[1]); + + if (!g_file_set_attribute (file, + attribute, + type, + value, + nofollow_symlinks ? + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS : + G_FILE_QUERY_INFO_NONE, + NULL, &error)) + { + print_error ("%s", error->message); + g_error_free (error); + retval = 1; + } + + g_clear_pointer (&value_allocated, g_free); + g_object_unref (file); + + return retval; +} diff --git a/gio/gio-tool-trash.c b/gio/gio-tool-trash.c new file mode 100644 index 0000000..449fa95 --- /dev/null +++ b/gio/gio-tool-trash.c @@ -0,0 +1,311 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#include "gio-tool.h" + + +static gboolean force = FALSE; +static gboolean empty = FALSE; +static gboolean restore = FALSE; +static gboolean list = FALSE; +static const GOptionEntry entries[] = { + { "force", 'f', 0, G_OPTION_ARG_NONE, &force, N_("Ignore nonexistent files, never prompt"), NULL }, + { "empty", 0, 0, G_OPTION_ARG_NONE, &empty, N_("Empty the trash"), NULL }, + { "list", 0, 0, G_OPTION_ARG_NONE, &list, N_("List files in the trash with their original locations"), NULL }, + { "restore", 0, 0, G_OPTION_ARG_NONE, &restore, N_("Restore a file from trash to its original location (possibly " + "recreating the directory)"), NULL }, + G_OPTION_ENTRY_NULL +}; + +static void +delete_trash_file (GFile *file, gboolean del_file, gboolean del_children) +{ + GFileInfo *info; + GFile *child; + GFileEnumerator *enumerator; + + g_return_if_fail (g_file_has_uri_scheme (file, "trash")); + + if (del_children) + { + enumerator = g_file_enumerate_children (file, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, + NULL); + if (enumerator) + { + while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) + { + child = g_file_get_child (file, g_file_info_get_name (info)); + + /* The g_file_delete operation works differently for locations + * provided by the trash backend as it prevents modifications of + * trashed items. For that reason, it is enough to call + * g_file_delete on top-level items only. + */ + delete_trash_file (child, TRUE, FALSE); + + g_object_unref (child); + g_object_unref (info); + } + g_file_enumerator_close (enumerator, NULL, NULL); + g_object_unref (enumerator); + } + } + + if (del_file) + g_file_delete (file, NULL, NULL); +} + +static gboolean +restore_trash (GFile *file, + gboolean force, + GCancellable *cancellable, + GError **error) +{ + GFileInfo *info = NULL; + GFile *target = NULL; + GFile *dir_target = NULL; + gboolean ret = FALSE; + gchar *orig_path = NULL; + GError *local_error = NULL; + + info = g_file_query_info (file, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH, G_FILE_QUERY_INFO_NONE, cancellable, &local_error); + if (local_error) + { + g_propagate_error (error, local_error); + goto exit_func; + } + + orig_path = g_file_info_get_attribute_as_string (info, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH); + if (!orig_path) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Unable to find original path")); + goto exit_func; + } + + target = g_file_new_for_commandline_arg (orig_path); + g_free (orig_path); + + dir_target = g_file_get_parent (target); + if (dir_target) + { + g_file_make_directory_with_parents (dir_target, cancellable, &local_error); + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) + { + g_clear_error (&local_error); + } + else if (local_error != NULL) + { + g_propagate_prefixed_error (error, local_error, _("Unable to recreate original location: ")); + goto exit_func; + } + } + + if (!g_file_move (file, + target, + force ? G_FILE_COPY_OVERWRITE : G_FILE_COPY_NONE, + cancellable, + NULL, + NULL, + &local_error)) + { + g_propagate_prefixed_error (error, local_error, _("Unable to move file to its original location: ")); + goto exit_func; + } + ret = TRUE; + +exit_func: + g_clear_object (&target); + g_clear_object (&dir_target); + g_clear_object (&info); + return ret; +} + +static gboolean +trash_list (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileEnumerator *enumerator; + GFileInfo *info; + GError *local_error = NULL; + gboolean res; + + enumerator = g_file_enumerate_children (file, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_TRASH_ORIG_PATH, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, + &local_error); + if (!enumerator) + { + g_propagate_error (error, local_error); + return FALSE; + } + + res = TRUE; + while ((info = g_file_enumerator_next_file (enumerator, cancellable, &local_error)) != NULL) + { + const char *name; + char *orig_path; + char *uri; + GFile* child; + + name = g_file_info_get_name (info); + child = g_file_get_child (file, name); + uri = g_file_get_uri (child); + g_object_unref (child); + orig_path = g_file_info_get_attribute_as_string (info, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH); + + g_print ("%s\t%s\n", uri, orig_path); + + g_object_unref (info); + g_free (orig_path); + g_free (uri); + } + + if (local_error) + { + g_propagate_error (error, local_error); + local_error = NULL; + res = FALSE; + } + + if (!g_file_enumerator_close (enumerator, cancellable, &local_error)) + { + print_file_error (file, local_error->message); + g_clear_error (&local_error); + res = FALSE; + } + + return res; +} + +int +handle_trash (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + gchar *param; + GError *error = NULL; + int retval = 0; + GFile *file; + + g_set_prgname ("gio trash"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("[%s…]", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("Move/Restore files or directories to the trash.")); + g_option_context_set_description (context, + _("Note: for --restore switch, if the original location of the trashed file \n" + "already exists, it will not be overwritten unless --force is set.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + if (argc > 1) + { + int i; + + for (i = 1; i < argc; i++) + { + file = g_file_new_for_commandline_arg (argv[i]); + error = NULL; + if (restore) + { + if (!g_file_has_uri_scheme (file, "trash")) + { + print_file_error (file, _("Location given doesn't start with trash:///")); + retval = 1; + } + else if (!restore_trash (file, force, NULL, &error)) + { + print_file_error (file, error->message); + retval = 1; + } + } + else if (!g_file_trash (file, NULL, &error)) + { + if (!force || + !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + print_file_error (file, error->message); + retval = 1; + } + } + g_clear_error (&error); + g_object_unref (file); + } + } + else if (list) + { + GFile *file; + file = g_file_new_for_uri ("trash:"); + trash_list (file, NULL, &error); + if (error) + { + print_file_error (file, error->message); + g_clear_error (&error); + retval = 1; + } + g_object_unref (file); + } + else if (empty) + { + GFile *file; + file = g_file_new_for_uri ("trash:"); + delete_trash_file (file, FALSE, TRUE); + g_object_unref (file); + } + + if (argc == 1 && !empty && !list) + { + show_help (context, _("No locations given")); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + return retval; +} diff --git a/gio/gio-tool-tree.c b/gio/gio-tool-tree.c new file mode 100644 index 0000000..c572afc --- /dev/null +++ b/gio/gio-tool-tree.c @@ -0,0 +1,287 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#include "gio-tool.h" + + +static gboolean show_hidden = FALSE; +static gboolean follow_symlinks = FALSE; + +static const GOptionEntry entries[] = { + { "hidden", 'h', 0, G_OPTION_ARG_NONE, &show_hidden, N_("Show hidden files"), NULL }, + { "follow-symlinks", 'l', 0, G_OPTION_ARG_NONE, &follow_symlinks, N_("Follow symbolic links, mounts and shortcuts"), NULL }, + G_OPTION_ENTRY_NULL +}; + +static gint +sort_info_by_name (GFileInfo *a, GFileInfo *b) +{ + const char *na; + const char *nb; + + na = g_file_info_get_name (a); + nb = g_file_info_get_name (b); + + if (na == NULL) + na = ""; + if (nb == NULL) + nb = ""; + + return strcmp (na, nb); +} + +static void +do_tree (GFile *f, unsigned int level, guint64 pattern) +{ + GFileEnumerator *enumerator; + GError *error = NULL; + unsigned int n; + GFileInfo *info; + + info = g_file_query_info (f, + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, + 0, + NULL, NULL); + if (info != NULL) + { + if (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) == G_FILE_TYPE_MOUNTABLE) + { + /* don't process mountables; we avoid these by getting the target_uri below */ + g_object_unref (info); + return; + } + g_object_unref (info); + } + + enumerator = g_file_enumerate_children (f, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," + G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," + G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," + G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, + 0, + NULL, + &error); + if (enumerator != NULL) + { + GList *l; + GList *info_list; + + info_list = NULL; + while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) + { + if (g_file_info_get_is_hidden (info) && !show_hidden) + { + g_object_unref (info); + } + else + { + info_list = g_list_prepend (info_list, info); + } + } + g_file_enumerator_close (enumerator, NULL, NULL); + + info_list = g_list_sort (info_list, (GCompareFunc) sort_info_by_name); + + for (l = info_list; l != NULL; l = l->next) + { + const char *name; + const char *target_uri; + GFileType type; + gboolean is_last_item; + + info = l->data; + is_last_item = (l->next == NULL); + + name = g_file_info_get_name (info); + type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE); + if (name != NULL) + { + + for (n = 0; n < level; n++) + { + if (pattern & (1< %s", target_uri); + } + else + { + if (g_file_info_get_is_symlink (info)) + { + const char *target; + target = g_file_info_get_symlink_target (info); + g_print (" -> %s", target); + } + } + + g_print ("\n"); + + if ((type & G_FILE_TYPE_DIRECTORY) && + (follow_symlinks || !g_file_info_get_is_symlink (info))) + { + guint64 new_pattern; + GFile *child; + + if (is_last_item) + new_pattern = pattern; + else + new_pattern = pattern | (1<message); + + g_error_free (error); + } +} + +static void +tree (GFile *f) +{ + char *uri; + + uri = g_file_get_uri (f); + g_print ("%s\n", uri); + g_free (uri); + + do_tree (f, 0, 0); +} + +int +handle_tree (int argc, char *argv[], gboolean do_help) +{ + GOptionContext *context; + GError *error = NULL; + GFile *file; + gchar *param; + int i; + + g_set_prgname ("gio tree"); + + /* Translators: commandline placeholder */ + param = g_strdup_printf ("[%s…]", _("LOCATION")); + context = g_option_context_new (param); + g_free (param); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_summary (context, + _("List contents of directories in a tree-like format.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (do_help) + { + show_help (context, NULL); + g_option_context_free (context); + return 0; + } + + g_option_context_parse (context, &argc, &argv, &error); + + if (error != NULL) + { + show_help (context, error->message); + g_error_free (error); + g_option_context_free (context); + return 1; + } + + g_option_context_free (context); + + if (argc > 1) + { + for (i = 1; i < argc; i++) + { + file = g_file_new_for_commandline_arg (argv[i]); + tree (file); + g_object_unref (file); + } + } + else + { + char *cwd; + + cwd = g_get_current_dir (); + file = g_file_new_for_path (cwd); + g_free (cwd); + tree (file); + g_object_unref (file); + } + + return 0; +} diff --git a/gio/gio-tool.c b/gio/gio-tool.c new file mode 100644 index 0000000..e60d567 --- /dev/null +++ b/gio/gio-tool.c @@ -0,0 +1,348 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "gio-tool.h" +#include "glib/glib-private.h" + +void +print_error (const gchar *format, ...) +{ + gchar *message; + va_list args; + + va_start (args, format); + message = g_strdup_vprintf (format, args); + va_end (args); + + g_printerr ("gio: %s\n", message); + g_free (message); +} + +void +print_file_error (GFile *file, const gchar *message) +{ + gchar *uri; + + uri = g_file_get_uri (file); + print_error ("%s: %s", uri, message); + g_free (uri); +} + +void +show_help (GOptionContext *context, const char *message) +{ + char *help; + + if (message) + g_printerr ("gio: %s\n\n", message); + + help = g_option_context_get_help (context, TRUE, NULL); + g_printerr ("%s", help); + g_free (help); +} + +const char * +file_type_to_string (GFileType type) +{ + switch (type) + { + case G_FILE_TYPE_UNKNOWN: + return "unknown"; + case G_FILE_TYPE_REGULAR: + return "regular"; + case G_FILE_TYPE_DIRECTORY: + return "directory"; + case G_FILE_TYPE_SYMBOLIC_LINK: + return "symlink"; + case G_FILE_TYPE_SPECIAL: + return "special"; + case G_FILE_TYPE_SHORTCUT: + return "shortcut"; + case G_FILE_TYPE_MOUNTABLE: + return "mountable"; + default: + return "invalid type"; + } +} + +const char * +attribute_type_to_string (GFileAttributeType type) +{ + switch (type) + { + case G_FILE_ATTRIBUTE_TYPE_INVALID: + return "invalid"; + case G_FILE_ATTRIBUTE_TYPE_STRING: + return "string"; + case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: + return "bytestring"; + case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: + return "boolean"; + case G_FILE_ATTRIBUTE_TYPE_UINT32: + return "uint32"; + case G_FILE_ATTRIBUTE_TYPE_INT32: + return "int32"; + case G_FILE_ATTRIBUTE_TYPE_UINT64: + return "uint64"; + case G_FILE_ATTRIBUTE_TYPE_INT64: + return "int64"; + case G_FILE_ATTRIBUTE_TYPE_OBJECT: + return "object"; + default: + return "unknown type"; + } +} + +GFileAttributeType +attribute_type_from_string (const char *str) +{ + if (strcmp (str, "string") == 0) + return G_FILE_ATTRIBUTE_TYPE_STRING; + if (strcmp (str, "stringv") == 0) + return G_FILE_ATTRIBUTE_TYPE_STRINGV; + if (strcmp (str, "bytestring") == 0) + return G_FILE_ATTRIBUTE_TYPE_BYTE_STRING; + if (strcmp (str, "boolean") == 0) + return G_FILE_ATTRIBUTE_TYPE_BOOLEAN; + if (strcmp (str, "uint32") == 0) + return G_FILE_ATTRIBUTE_TYPE_UINT32; + if (strcmp (str, "int32") == 0) + return G_FILE_ATTRIBUTE_TYPE_INT32; + if (strcmp (str, "uint64") == 0) + return G_FILE_ATTRIBUTE_TYPE_UINT64; + if (strcmp (str, "int64") == 0) + return G_FILE_ATTRIBUTE_TYPE_INT64; + if (strcmp (str, "object") == 0) + return G_FILE_ATTRIBUTE_TYPE_OBJECT; + if (strcmp (str, "unset") == 0) + return G_FILE_ATTRIBUTE_TYPE_INVALID; + return -1; +} + +char * +attribute_flags_to_string (GFileAttributeInfoFlags flags) +{ + GString *s; + gsize i; + gboolean first; + struct { + guint32 mask; + char *descr; + } flag_descr[] = { + { + G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE, + N_("Copy with file") + }, + { + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED, + N_("Keep with file when moved") + } + }; + + first = TRUE; + + s = g_string_new (""); + for (i = 0; i < G_N_ELEMENTS (flag_descr); i++) + { + if (flags & flag_descr[i].mask) + { + if (!first) + g_string_append (s, ", "); + g_string_append (s, gettext (flag_descr[i].descr)); + first = FALSE; + } + } + + return g_string_free (s, FALSE); +} + +gboolean +file_is_dir (GFile *file) +{ + GFileInfo *info; + gboolean res; + + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, 0, NULL, NULL); + res = info && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY; + if (info) + g_object_unref (info); + return res; +} + + +static int +handle_version (int argc, char *argv[], gboolean do_help) +{ + if (do_help || argc > 1) + { + if (!do_help) + g_printerr ("gio: %s\n\n", _("“version†takes no arguments")); + + g_printerr ("%s\n", _("Usage:")); + g_printerr (" gio version\n"); + g_printerr ("\n"); + g_printerr ("%s\n", _("Print version information and exit.")); + + return do_help ? 0 : 2; + } + + g_print ("%d.%d.%d\n", glib_major_version, glib_minor_version, glib_micro_version); + + return 0; +} + +static void +usage (void) +{ + g_printerr ("%s\n", _("Usage:")); + g_printerr (" gio %s %s\n", _("COMMAND"), _("[ARGS…]")); + g_printerr ("\n"); + g_printerr ("%s\n", _("Commands:")); + g_printerr (" help %s\n", _("Print help")); + g_printerr (" version %s\n", _("Print version")); + g_printerr (" cat %s\n", _("Concatenate files to standard output")); + g_printerr (" copy %s\n", _("Copy one or more files")); + g_printerr (" info %s\n", _("Show information about locations")); + g_printerr (" launch %s\n", _("Launch an application from a desktop file")); + g_printerr (" list %s\n", _("List the contents of locations")); + g_printerr (" mime %s\n", _("Get or set the handler for a mimetype")); + g_printerr (" mkdir %s\n", _("Create directories")); + g_printerr (" monitor %s\n", _("Monitor files and directories for changes")); + g_printerr (" mount %s\n", _("Mount or unmount the locations")); + g_printerr (" move %s\n", _("Move one or more files")); + g_printerr (" open %s\n", _("Open files with the default application")); + g_printerr (" rename %s\n", _("Rename a file")); + g_printerr (" remove %s\n", _("Delete one or more files")); + g_printerr (" save %s\n", _("Read from standard input and save")); + g_printerr (" set %s\n", _("Set a file attribute")); + g_printerr (" trash %s\n", _("Move files or directories to the trash")); + g_printerr (" tree %s\n", _("Lists the contents of locations in a tree")); + g_printerr ("\n"); + g_printerr (_("Use %s to get detailed help.\n"), "“gio help COMMANDâ€"); + exit (1); +} + +int +main (int argc, char **argv) +{ + const char *command; + gboolean do_help; + +#ifdef G_OS_WIN32 + gchar *localedir; +#endif + + setlocale (LC_ALL, GLIB_DEFAULT_LOCALE); + textdomain (GETTEXT_PACKAGE); + +#ifdef G_OS_WIN32 + localedir = _glib_get_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, localedir); + g_free (localedir); +#else + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#endif + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + + if (argc < 2) + { + usage (); + return 1; + } + + command = argv[1]; + argc -= 1; + argv += 1; + + do_help = FALSE; + if (g_str_equal (command, "help")) + { + if (argc == 1) + { + usage (); + return 0; + } + else + { + command = argv[1]; + do_help = TRUE; + } + } + else if (g_str_equal (command, "--help")) + { + usage (); + return 0; + } + else if (g_str_equal (command, "--version")) + command = "version"; + + if (g_str_equal (command, "version")) + return handle_version (argc, argv, do_help); + else if (g_str_equal (command, "cat")) + return handle_cat (argc, argv, do_help); + else if (g_str_equal (command, "copy")) + return handle_copy (argc, argv, do_help); + else if (g_str_equal (command, "info")) + return handle_info (argc, argv, do_help); + else if (g_str_equal (command, "launch")) + return handle_launch (argc, argv, do_help); + else if (g_str_equal (command, "list")) + return handle_list (argc, argv, do_help); + else if (g_str_equal (command, "mime")) + return handle_mime (argc, argv, do_help); + else if (g_str_equal (command, "mkdir")) + return handle_mkdir (argc, argv, do_help); + else if (g_str_equal (command, "monitor")) + return handle_monitor (argc, argv, do_help); + else if (g_str_equal (command, "mount")) + return handle_mount (argc, argv, do_help); + else if (g_str_equal (command, "move")) + return handle_move (argc, argv, do_help); + else if (g_str_equal (command, "open")) + return handle_open (argc, argv, do_help); + else if (g_str_equal (command, "rename")) + return handle_rename (argc, argv, do_help); + else if (g_str_equal (command, "remove")) + return handle_remove (argc, argv, do_help); + else if (g_str_equal (command, "save")) + return handle_save (argc, argv, do_help); + else if (g_str_equal (command, "set")) + return handle_set (argc, argv, do_help); + else if (g_str_equal (command, "trash")) + return handle_trash (argc, argv, do_help); + else if (g_str_equal (command, "tree")) + return handle_tree (argc, argv, do_help); + else + usage (); + + return 1; +} diff --git a/gio/gio-tool.h b/gio/gio-tool.h new file mode 100644 index 0000000..6cd1d94 --- /dev/null +++ b/gio/gio-tool.h @@ -0,0 +1,55 @@ +/* + * Copyright 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#ifndef __GIO_TOOL_H__ +#define __GIO_TOOL_H__ + +void print_error (const gchar *format, + ...) G_GNUC_PRINTF (1, 2); +void print_file_error (GFile *file, + const gchar *message); +void show_help (GOptionContext *context, + const char *message); + +const char *file_type_to_string (GFileType type); +const char *attribute_type_to_string (GFileAttributeType type); +GFileAttributeType attribute_type_from_string (const char *str); +char *attribute_flags_to_string (GFileAttributeInfoFlags flags); + +gboolean file_is_dir (GFile *file); + +int handle_cat (int argc, char *argv[], gboolean do_help); +int handle_copy (int argc, char *argv[], gboolean do_help); +int handle_info (int argc, char *argv[], gboolean do_help); +int handle_launch (int argc, char *argv[], gboolean do_help); +int handle_list (int argc, char *argv[], gboolean do_help); +int handle_mime (int argc, char *argv[], gboolean do_help); +int handle_mkdir (int argc, char *argv[], gboolean do_help); +int handle_monitor (int argc, char *argv[], gboolean do_help); +int handle_mount (int argc, char *argv[], gboolean do_help); +int handle_move (int argc, char *argv[], gboolean do_help); +int handle_open (int argc, char *argv[], gboolean do_help); +int handle_rename (int argc, char *argv[], gboolean do_help); +int handle_remove (int argc, char *argv[], gboolean do_help); +int handle_save (int argc, char *argv[], gboolean do_help); +int handle_set (int argc, char *argv[], gboolean do_help); +int handle_trash (int argc, char *argv[], gboolean do_help); +int handle_tree (int argc, char *argv[], gboolean do_help); + +#endif /* __GIO_TOOL_H__ */ diff --git a/gio/gio.h b/gio/gio.h new file mode 100644 index 0000000..2d0a9c2 --- /dev/null +++ b/gio/gio.h @@ -0,0 +1,180 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_IO_H__ +#define __G_IO_H__ + +#define __GIO_GIO_H_INSIDE__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#undef __GIO_GIO_H_INSIDE__ + +#endif /* __G_IO_H__ */ diff --git a/gio/gio.rc.in b/gio/gio.rc.in new file mode 100644 index 0000000..3b19b3e --- /dev/null +++ b/gio/gio.rc.in @@ -0,0 +1,30 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + FILEFLAGSMASK 0 + FILEFLAGS 0 + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "The GLib developer community" + VALUE "FileDescription", "Gio" + VALUE "FileVersion", "@GLIB_VERSION@.0" + VALUE "InternalName", "libgio-2.0-@LT_CURRENT_MINUS_AGE@" + VALUE "LegalCopyright", "Copyright 2006-2011 Red Hat, Inc. and others." + VALUE "OriginalFilename", "libgio-2.0-@LT_CURRENT_MINUS_AGE@.dll" + VALUE "ProductName", "GLib" + VALUE "ProductVersion", "@GLIB_VERSION@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END + END diff --git a/gio/gio.stp.in b/gio/gio.stp.in new file mode 100644 index 0000000..3ca0cd3 --- /dev/null +++ b/gio/gio.stp.in @@ -0,0 +1,107 @@ +/** + * probe gio.task_new - Called when a new #GTask is created + * @task: the new #GTask object + * @source_object: the source object + * @cancellable: the #GCancellable + * @callback: the task’s callback + * @callback_data: data for @callback + */ +probe gio.task_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__new") +{ + task = $arg1; + source_object = $arg2; + cancellable = $arg3; + callback = $arg4; + callback_data = $arg5; + probestr = sprintf("gio.task_new(%p, %p, %p, %p) -> %p", source_object, cancellable, callback, callback_data, task); +} + +/** + * probe gio.task_set_task_data - Called when the task data is set on a #GTask + * @task: the #GTask object + * @task_data: the task data + * @task_data_destroy: the destroy notify function for the data + */ +probe gio.task_set_task_data = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__set_task_data") +{ + task = $arg1; + task_data = $arg2; + task_data_destroy = $arg3; + probestr = sprintf("gio.task_set_task_data(%p, %p, %p)", task, task_data, task_data_destroy); +} + +/** + * probe gio.task_set_priority - Called when the priority of a #GTask is set + * @task: the #GTask object + * @priority: the priority + */ +probe gio.task_set_priority = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__set_priority") +{ + task = $arg1; + priority = $arg2; + probestr = sprintf("gio.task_set_priority(%p, %i)", task, priority); +} + +/** + * probe gio.task_set_source_tag - Called when the source tag of a #GTask is set + * @task: the #GTask object + * @source_tag: the source tag + */ +probe gio.task_set_source_tag = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__set_source_tag") +{ + task = $arg1; + source_tag = $arg2; + probestr = sprintf("gio.task_set_source_tag(%p, %p)", task, source_tag); +} + +/** + * probe gio.task_before_return - Called before a #GTask invokes its callback or returns from g_task_run_in_thread_sync() + * @task: the #GTask object + * @source_object: the source object passed to the callback + * @callback: the callback about to be invoked + * @callback_data: data passed to @callback + */ +probe gio.task_before_return = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__before_return") +{ + task = $arg1; + source_object = $arg2; + callback = $arg3; + callback_data = $arg4; + probestr = sprintf("gio.task_before_return(%p, %p, %p, %p)", task, source_object, callback, callback_data); +} + +/** + * probe gio.task_propagate - Called when a #GTask’s result is propagated + * @task: the #GTask object + * @error_set: %TRUE if propagating an error, %FALSE otherwise + */ +probe gio.task_propagate = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__propagate") +{ + task = $arg1; + error_set = $arg2; + probestr = sprintf("gio.task_propagate(%p) -> %u", task, error_set); +} + +/** + * probe gio.task_before_run_in_thread - Called before a #GTask’s function is run in a thread + * @task: the #GTask object + * @task_func: the task function being run + */ +probe gio.task_before_run_in_thread = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__before_run_in_thread") +{ + task = $arg1; + task_func = $arg2; + probestr = sprintf("gio.task_before_run_in_thread(%p, %p)", task, task_func); +} + +/** + * probe gio.task_after_run_in_thread - Called after a #GTask’s function is run in a thread + * @task: the #GTask object + * @thread_cancelled: %TRUE if the thread was cancelled, %FALSE otherwise + */ +probe gio.task_after_run_in_thread = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__after_run_in_thread") +{ + task = $arg1; + thread_cancelled = $arg2; + probestr = sprintf("gio.task_after_run_in_thread(%p) -> %u", task, thread_cancelled); +} diff --git a/gio/gio_probes.d b/gio/gio_probes.d new file mode 100644 index 0000000..8747d8d --- /dev/null +++ b/gio/gio_probes.d @@ -0,0 +1,10 @@ +provider gio { + probe task__new(void*, void*, void*, void*, void*); + probe task__set_task_data(void*, void*, void*); + probe task__set_priority(void*, int); + probe task__set_source_tag(void*, void*); + probe task__before_return(void*, void*, void*, void*); + probe task__propagate(void*, unsigned int); + probe task__before_run_in_thread(void*, void*); + probe task__after_run_in_thread(void*, unsigned int); +}; diff --git a/gio/gio_trace.h b/gio/gio_trace.h new file mode 100644 index 0000000..addb70a --- /dev/null +++ b/gio/gio_trace.h @@ -0,0 +1,43 @@ +/* GLIB - Library of useful routines for C programming + * + * Copyright (C) 2009,2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __GIOTRACE_H__ +#define __GIOTRACE_H__ + +#ifndef SIZEOF_CHAR +#error "config.h must be included prior to gio_trace.h" +#endif + +/* Ignore probes when doing static analysis, as they do weird things which + * confuses the analyser. */ +#if defined(HAVE_DTRACE) && !defined(__clang_analyzer__) + +/* include the generated probes header and put markers in code */ +#include "gio_probes.h" +#define TRACE(probe) probe + +#else + +/* Wrap the probe to allow it to be removed when no systemtap available */ +#define TRACE(probe) + +#endif + +#endif /* __GIOTRACE_H__ */ diff --git a/gio/gioenums.h b/gio/gioenums.h new file mode 100644 index 0000000..efc4301 --- /dev/null +++ b/gio/gioenums.h @@ -0,0 +1,2125 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __GIO_ENUMS_H__ +#define __GIO_ENUMS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + + +/** + * GAppInfoCreateFlags: + * @G_APP_INFO_CREATE_NONE: No flags. + * @G_APP_INFO_CREATE_NEEDS_TERMINAL: Application opens in a terminal window. + * @G_APP_INFO_CREATE_SUPPORTS_URIS: Application supports URI arguments. + * @G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION: Application supports startup notification. Since 2.26 + * + * Flags used when creating a #GAppInfo. + */ +typedef enum { + G_APP_INFO_CREATE_NONE = 0, /*< nick=none >*/ + G_APP_INFO_CREATE_NEEDS_TERMINAL = (1 << 0), /*< nick=needs-terminal >*/ + G_APP_INFO_CREATE_SUPPORTS_URIS = (1 << 1), /*< nick=supports-uris >*/ + G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION = (1 << 2) /*< nick=supports-startup-notification >*/ +} GAppInfoCreateFlags; + +/** + * GConverterFlags: + * @G_CONVERTER_NO_FLAGS: No flags. + * @G_CONVERTER_INPUT_AT_END: At end of input data + * @G_CONVERTER_FLUSH: Flush data + * + * Flags used when calling a g_converter_convert(). + * + * Since: 2.24 + */ +typedef enum { + G_CONVERTER_NO_FLAGS = 0, /*< nick=none >*/ + G_CONVERTER_INPUT_AT_END = (1 << 0), /*< nick=input-at-end >*/ + G_CONVERTER_FLUSH = (1 << 1) /*< nick=flush >*/ +} GConverterFlags; + +/** + * GConverterResult: + * @G_CONVERTER_ERROR: There was an error during conversion. + * @G_CONVERTER_CONVERTED: Some data was consumed or produced + * @G_CONVERTER_FINISHED: The conversion is finished + * @G_CONVERTER_FLUSHED: Flushing is finished + * + * Results returned from g_converter_convert(). + * + * Since: 2.24 + */ +typedef enum { + G_CONVERTER_ERROR = 0, /*< nick=error >*/ + G_CONVERTER_CONVERTED = 1, /*< nick=converted >*/ + G_CONVERTER_FINISHED = 2, /*< nick=finished >*/ + G_CONVERTER_FLUSHED = 3 /*< nick=flushed >*/ +} GConverterResult; + + +/** + * GDataStreamByteOrder: + * @G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN: Selects Big Endian byte order. + * @G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN: Selects Little Endian byte order. + * @G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN: Selects endianness based on host machine's architecture. + * + * #GDataStreamByteOrder is used to ensure proper endianness of streaming data sources + * across various machine architectures. + * + **/ +typedef enum { + G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN, + G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN, + G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN +} GDataStreamByteOrder; + + +/** + * GDataStreamNewlineType: + * @G_DATA_STREAM_NEWLINE_TYPE_LF: Selects "LF" line endings, common on most modern UNIX platforms. + * @G_DATA_STREAM_NEWLINE_TYPE_CR: Selects "CR" line endings. + * @G_DATA_STREAM_NEWLINE_TYPE_CR_LF: Selects "CR, LF" line ending, common on Microsoft Windows. + * @G_DATA_STREAM_NEWLINE_TYPE_ANY: Automatically try to handle any line ending type. + * + * #GDataStreamNewlineType is used when checking for or setting the line endings for a given file. + **/ +typedef enum { + G_DATA_STREAM_NEWLINE_TYPE_LF, + G_DATA_STREAM_NEWLINE_TYPE_CR, + G_DATA_STREAM_NEWLINE_TYPE_CR_LF, + G_DATA_STREAM_NEWLINE_TYPE_ANY +} GDataStreamNewlineType; + + +/** + * GFileAttributeType: + * @G_FILE_ATTRIBUTE_TYPE_INVALID: indicates an invalid or uninitialized type. + * @G_FILE_ATTRIBUTE_TYPE_STRING: a null terminated UTF8 string. + * @G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: a zero terminated string of non-zero bytes. + * @G_FILE_ATTRIBUTE_TYPE_BOOLEAN: a boolean value. + * @G_FILE_ATTRIBUTE_TYPE_UINT32: an unsigned 4-byte/32-bit integer. + * @G_FILE_ATTRIBUTE_TYPE_INT32: a signed 4-byte/32-bit integer. + * @G_FILE_ATTRIBUTE_TYPE_UINT64: an unsigned 8-byte/64-bit integer. + * @G_FILE_ATTRIBUTE_TYPE_INT64: a signed 8-byte/64-bit integer. + * @G_FILE_ATTRIBUTE_TYPE_OBJECT: a #GObject. + * @G_FILE_ATTRIBUTE_TYPE_STRINGV: a %NULL terminated char **. Since 2.22 + * + * The data types for file attributes. + **/ +typedef enum { + G_FILE_ATTRIBUTE_TYPE_INVALID = 0, + G_FILE_ATTRIBUTE_TYPE_STRING, + G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, /* zero terminated string of non-zero bytes */ + G_FILE_ATTRIBUTE_TYPE_BOOLEAN, + G_FILE_ATTRIBUTE_TYPE_UINT32, + G_FILE_ATTRIBUTE_TYPE_INT32, + G_FILE_ATTRIBUTE_TYPE_UINT64, + G_FILE_ATTRIBUTE_TYPE_INT64, + G_FILE_ATTRIBUTE_TYPE_OBJECT, + G_FILE_ATTRIBUTE_TYPE_STRINGV +} GFileAttributeType; + + +/** + * GFileAttributeInfoFlags: + * @G_FILE_ATTRIBUTE_INFO_NONE: no flags set. + * @G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE: copy the attribute values when the file is copied. + * @G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED: copy the attribute values when the file is moved. + * + * Flags specifying the behaviour of an attribute. + **/ +typedef enum { + G_FILE_ATTRIBUTE_INFO_NONE = 0, + G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE = (1 << 0), + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED = (1 << 1) +} GFileAttributeInfoFlags; + + +/** + * GFileAttributeStatus: + * @G_FILE_ATTRIBUTE_STATUS_UNSET: Attribute value is unset (empty). + * @G_FILE_ATTRIBUTE_STATUS_SET: Attribute value is set. + * @G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING: Indicates an error in setting the value. + * + * Used by g_file_set_attributes_from_info() when setting file attributes. + **/ +typedef enum { + G_FILE_ATTRIBUTE_STATUS_UNSET = 0, + G_FILE_ATTRIBUTE_STATUS_SET, + G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING +} GFileAttributeStatus; + + +/** + * GFileQueryInfoFlags: + * @G_FILE_QUERY_INFO_NONE: No flags set. + * @G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS: Don't follow symlinks. + * + * Flags used when querying a #GFileInfo. + */ +typedef enum { + G_FILE_QUERY_INFO_NONE = 0, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS = (1 << 0) /*< nick=nofollow-symlinks >*/ +} GFileQueryInfoFlags; + + +/** + * GFileCreateFlags: + * @G_FILE_CREATE_NONE: No flags set. + * @G_FILE_CREATE_PRIVATE: Create a file that can only be + * accessed by the current user. + * @G_FILE_CREATE_REPLACE_DESTINATION: Replace the destination + * as if it didn't exist before. Don't try to keep any old + * permissions, replace instead of following links. This + * is generally useful if you're doing a "copy over" + * rather than a "save new version of" replace operation. + * You can think of it as "unlink destination" before + * writing to it, although the implementation may not + * be exactly like that. This flag can only be used with + * g_file_replace() and its variants, including g_file_replace_contents(). + * Since 2.20 + * + * Flags used when an operation may create a file. + */ +typedef enum { + G_FILE_CREATE_NONE = 0, + G_FILE_CREATE_PRIVATE = (1 << 0), + G_FILE_CREATE_REPLACE_DESTINATION = (1 << 1) +} GFileCreateFlags; + +/** + * GFileMeasureFlags: + * @G_FILE_MEASURE_NONE: No flags set. + * @G_FILE_MEASURE_REPORT_ANY_ERROR: Report any error encountered + * while traversing the directory tree. Normally errors are only + * reported for the toplevel file. + * @G_FILE_MEASURE_APPARENT_SIZE: Tally usage based on apparent file + * sizes. Normally, the block-size is used, if available, as this is a + * more accurate representation of disk space used. + * Compare with `du --apparent-size`. + * @G_FILE_MEASURE_NO_XDEV: Do not cross mount point boundaries. + * Compare with `du -x`. + * + * Flags that can be used with g_file_measure_disk_usage(). + * + * Since: 2.38 + **/ +typedef enum { + G_FILE_MEASURE_NONE = 0, + G_FILE_MEASURE_REPORT_ANY_ERROR = (1 << 1), + G_FILE_MEASURE_APPARENT_SIZE = (1 << 2), + G_FILE_MEASURE_NO_XDEV = (1 << 3) +} GFileMeasureFlags; + +/** + * GMountMountFlags: + * @G_MOUNT_MOUNT_NONE: No flags set. + * + * Flags used when mounting a mount. + */ +typedef enum /*< flags >*/ { + G_MOUNT_MOUNT_NONE = 0 +} GMountMountFlags; + + +/** + * GMountUnmountFlags: + * @G_MOUNT_UNMOUNT_NONE: No flags set. + * @G_MOUNT_UNMOUNT_FORCE: Unmount even if there are outstanding + * file operations on the mount. + * + * Flags used when an unmounting a mount. + */ +typedef enum { + G_MOUNT_UNMOUNT_NONE = 0, + G_MOUNT_UNMOUNT_FORCE = (1 << 0) +} GMountUnmountFlags; + +/** + * GDriveStartFlags: + * @G_DRIVE_START_NONE: No flags set. + * + * Flags used when starting a drive. + * + * Since: 2.22 + */ +typedef enum /*< flags >*/ { + G_DRIVE_START_NONE = 0 +} GDriveStartFlags; + +/** + * GDriveStartStopType: + * @G_DRIVE_START_STOP_TYPE_UNKNOWN: Unknown or drive doesn't support + * start/stop. + * @G_DRIVE_START_STOP_TYPE_SHUTDOWN: The stop method will physically + * shut down the drive and e.g. power down the port the drive is + * attached to. + * @G_DRIVE_START_STOP_TYPE_NETWORK: The start/stop methods are used + * for connecting/disconnect to the drive over the network. + * @G_DRIVE_START_STOP_TYPE_MULTIDISK: The start/stop methods will + * assemble/disassemble a virtual drive from several physical + * drives. + * @G_DRIVE_START_STOP_TYPE_PASSWORD: The start/stop methods will + * unlock/lock the disk (for example using the ATA SECURITY + * UNLOCK DEVICE command) + * + * Enumeration describing how a drive can be started/stopped. + * + * Since: 2.22 + */ +typedef enum { + G_DRIVE_START_STOP_TYPE_UNKNOWN, + G_DRIVE_START_STOP_TYPE_SHUTDOWN, + G_DRIVE_START_STOP_TYPE_NETWORK, + G_DRIVE_START_STOP_TYPE_MULTIDISK, + G_DRIVE_START_STOP_TYPE_PASSWORD +} GDriveStartStopType; + +/** + * GFileCopyFlags: + * @G_FILE_COPY_NONE: No flags set. + * @G_FILE_COPY_OVERWRITE: Overwrite any existing files + * @G_FILE_COPY_BACKUP: Make a backup of any existing files. + * @G_FILE_COPY_NOFOLLOW_SYMLINKS: Don't follow symlinks. + * @G_FILE_COPY_ALL_METADATA: Copy all file metadata instead of just default set used for copy (see #GFileInfo). + * @G_FILE_COPY_NO_FALLBACK_FOR_MOVE: Don't use copy and delete fallback if native move not supported. + * @G_FILE_COPY_TARGET_DEFAULT_PERMS: Leaves target file with default perms, instead of setting the source file perms. + * + * Flags used when copying or moving files. + */ +typedef enum { + G_FILE_COPY_NONE = 0, /*< nick=none >*/ + G_FILE_COPY_OVERWRITE = (1 << 0), + G_FILE_COPY_BACKUP = (1 << 1), + G_FILE_COPY_NOFOLLOW_SYMLINKS = (1 << 2), + G_FILE_COPY_ALL_METADATA = (1 << 3), + G_FILE_COPY_NO_FALLBACK_FOR_MOVE = (1 << 4), + G_FILE_COPY_TARGET_DEFAULT_PERMS = (1 << 5) +} GFileCopyFlags; + + +/** + * GFileMonitorFlags: + * @G_FILE_MONITOR_NONE: No flags set. + * @G_FILE_MONITOR_WATCH_MOUNTS: Watch for mount events. + * @G_FILE_MONITOR_SEND_MOVED: Pair DELETED and CREATED events caused + * by file renames (moves) and send a single G_FILE_MONITOR_EVENT_MOVED + * event instead (NB: not supported on all backends; the default + * behaviour -without specifying this flag- is to send single DELETED + * and CREATED events). Deprecated since 2.46: use + * %G_FILE_MONITOR_WATCH_MOVES instead. + * @G_FILE_MONITOR_WATCH_HARD_LINKS: Watch for changes to the file made + * via another hard link. Since 2.36. + * @G_FILE_MONITOR_WATCH_MOVES: Watch for rename operations on a + * monitored directory. This causes %G_FILE_MONITOR_EVENT_RENAMED, + * %G_FILE_MONITOR_EVENT_MOVED_IN and %G_FILE_MONITOR_EVENT_MOVED_OUT + * events to be emitted when possible. Since: 2.46. + * + * Flags used to set what a #GFileMonitor will watch for. + */ +typedef enum { + G_FILE_MONITOR_NONE = 0, + G_FILE_MONITOR_WATCH_MOUNTS = (1 << 0), + G_FILE_MONITOR_SEND_MOVED = (1 << 1), + G_FILE_MONITOR_WATCH_HARD_LINKS = (1 << 2), + G_FILE_MONITOR_WATCH_MOVES = (1 << 3) +} GFileMonitorFlags; + + +/** + * GFileType: + * @G_FILE_TYPE_UNKNOWN: File's type is unknown. + * @G_FILE_TYPE_REGULAR: File handle represents a regular file. + * @G_FILE_TYPE_DIRECTORY: File handle represents a directory. + * @G_FILE_TYPE_SYMBOLIC_LINK: File handle represents a symbolic link + * (Unix systems). + * @G_FILE_TYPE_SPECIAL: File is a "special" file, such as a socket, fifo, + * block device, or character device. + * @G_FILE_TYPE_SHORTCUT: File is a shortcut (Windows systems). + * @G_FILE_TYPE_MOUNTABLE: File is a mountable location. + * + * Indicates the file's on-disk type. + * + * On Windows systems a file will never have %G_FILE_TYPE_SYMBOLIC_LINK type; + * use #GFileInfo and %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK to determine + * whether a file is a symlink or not. This is due to the fact that NTFS does + * not have a single filesystem object type for symbolic links - it has + * files that symlink to files, and directories that symlink to directories. + * #GFileType enumeration cannot precisely represent this important distinction, + * which is why all Windows symlinks will continue to be reported as + * %G_FILE_TYPE_REGULAR or %G_FILE_TYPE_DIRECTORY. + **/ +typedef enum { + G_FILE_TYPE_UNKNOWN = 0, + G_FILE_TYPE_REGULAR, + G_FILE_TYPE_DIRECTORY, + G_FILE_TYPE_SYMBOLIC_LINK, + G_FILE_TYPE_SPECIAL, /* socket, fifo, blockdev, chardev */ + G_FILE_TYPE_SHORTCUT, + G_FILE_TYPE_MOUNTABLE +} GFileType; + + +/** + * GFilesystemPreviewType: + * @G_FILESYSTEM_PREVIEW_TYPE_IF_ALWAYS: Only preview files if user has explicitly requested it. + * @G_FILESYSTEM_PREVIEW_TYPE_IF_LOCAL: Preview files if user has requested preview of "local" files. + * @G_FILESYSTEM_PREVIEW_TYPE_NEVER: Never preview files. + * + * Indicates a hint from the file system whether files should be + * previewed in a file manager. Returned as the value of the key + * %G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW. + **/ +typedef enum { + G_FILESYSTEM_PREVIEW_TYPE_IF_ALWAYS = 0, + G_FILESYSTEM_PREVIEW_TYPE_IF_LOCAL, + G_FILESYSTEM_PREVIEW_TYPE_NEVER +} GFilesystemPreviewType; + + +/** + * GFileMonitorEvent: + * @G_FILE_MONITOR_EVENT_CHANGED: a file changed. + * @G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: a hint that this was probably the last change in a set of changes. + * @G_FILE_MONITOR_EVENT_DELETED: a file was deleted. + * @G_FILE_MONITOR_EVENT_CREATED: a file was created. + * @G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: a file attribute was changed. + * @G_FILE_MONITOR_EVENT_PRE_UNMOUNT: the file location will soon be unmounted. + * @G_FILE_MONITOR_EVENT_UNMOUNTED: the file location was unmounted. + * @G_FILE_MONITOR_EVENT_MOVED: the file was moved -- only sent if the + * (deprecated) %G_FILE_MONITOR_SEND_MOVED flag is set + * @G_FILE_MONITOR_EVENT_RENAMED: the file was renamed within the + * current directory -- only sent if the %G_FILE_MONITOR_WATCH_MOVES + * flag is set. Since: 2.46. + * @G_FILE_MONITOR_EVENT_MOVED_IN: the file was moved into the + * monitored directory from another location -- only sent if the + * %G_FILE_MONITOR_WATCH_MOVES flag is set. Since: 2.46. + * @G_FILE_MONITOR_EVENT_MOVED_OUT: the file was moved out of the + * monitored directory to another location -- only sent if the + * %G_FILE_MONITOR_WATCH_MOVES flag is set. Since: 2.46 + * + * Specifies what type of event a monitor event is. + **/ +typedef enum { + G_FILE_MONITOR_EVENT_CHANGED, + G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, + G_FILE_MONITOR_EVENT_DELETED, + G_FILE_MONITOR_EVENT_CREATED, + G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED, + G_FILE_MONITOR_EVENT_PRE_UNMOUNT, + G_FILE_MONITOR_EVENT_UNMOUNTED, + G_FILE_MONITOR_EVENT_MOVED, + G_FILE_MONITOR_EVENT_RENAMED, + G_FILE_MONITOR_EVENT_MOVED_IN, + G_FILE_MONITOR_EVENT_MOVED_OUT +} GFileMonitorEvent; + + +/* This enumeration conflicts with GIOError in giochannel.h. However, + * that is only used as a return value in some deprecated functions. + * So, we reuse the same prefix for the enumeration values, but call + * the actual enumeration (which is rarely used) GIOErrorEnum. + */ +/** + * GIOErrorEnum: + * @G_IO_ERROR_FAILED: Generic error condition for when an operation fails + * and no more specific #GIOErrorEnum value is defined. + * @G_IO_ERROR_NOT_FOUND: File not found. + * @G_IO_ERROR_EXISTS: File already exists. + * @G_IO_ERROR_IS_DIRECTORY: File is a directory. + * @G_IO_ERROR_NOT_DIRECTORY: File is not a directory. + * @G_IO_ERROR_NOT_EMPTY: File is a directory that isn't empty. + * @G_IO_ERROR_NOT_REGULAR_FILE: File is not a regular file. + * @G_IO_ERROR_NOT_SYMBOLIC_LINK: File is not a symbolic link. + * @G_IO_ERROR_NOT_MOUNTABLE_FILE: File cannot be mounted. + * @G_IO_ERROR_FILENAME_TOO_LONG: Filename is too many characters. + * @G_IO_ERROR_INVALID_FILENAME: Filename is invalid or contains invalid characters. + * @G_IO_ERROR_TOO_MANY_LINKS: File contains too many symbolic links. + * @G_IO_ERROR_NO_SPACE: No space left on drive. + * @G_IO_ERROR_INVALID_ARGUMENT: Invalid argument. + * @G_IO_ERROR_PERMISSION_DENIED: Permission denied. + * @G_IO_ERROR_NOT_SUPPORTED: Operation (or one of its parameters) not supported + * @G_IO_ERROR_NOT_MOUNTED: File isn't mounted. + * @G_IO_ERROR_ALREADY_MOUNTED: File is already mounted. + * @G_IO_ERROR_CLOSED: File was closed. + * @G_IO_ERROR_CANCELLED: Operation was cancelled. See #GCancellable. + * @G_IO_ERROR_PENDING: Operations are still pending. + * @G_IO_ERROR_READ_ONLY: File is read only. + * @G_IO_ERROR_CANT_CREATE_BACKUP: Backup couldn't be created. + * @G_IO_ERROR_WRONG_ETAG: File's Entity Tag was incorrect. + * @G_IO_ERROR_TIMED_OUT: Operation timed out. + * @G_IO_ERROR_WOULD_RECURSE: Operation would be recursive. + * @G_IO_ERROR_BUSY: File is busy. + * @G_IO_ERROR_WOULD_BLOCK: Operation would block. + * @G_IO_ERROR_HOST_NOT_FOUND: Host couldn't be found (remote operations). + * @G_IO_ERROR_WOULD_MERGE: Operation would merge files. + * @G_IO_ERROR_FAILED_HANDLED: Operation failed and a helper program has + * already interacted with the user. Do not display any error dialog. + * @G_IO_ERROR_TOO_MANY_OPEN_FILES: The current process has too many files + * open and can't open any more. Duplicate descriptors do count toward + * this limit. Since 2.20 + * @G_IO_ERROR_NOT_INITIALIZED: The object has not been initialized. Since 2.22 + * @G_IO_ERROR_ADDRESS_IN_USE: The requested address is already in use. Since 2.22 + * @G_IO_ERROR_PARTIAL_INPUT: Need more input to finish operation. Since 2.24 + * @G_IO_ERROR_INVALID_DATA: The input data was invalid. Since 2.24 + * @G_IO_ERROR_DBUS_ERROR: A remote object generated an error that + * doesn't correspond to a locally registered #GError error + * domain. Use g_dbus_error_get_remote_error() to extract the D-Bus + * error name and g_dbus_error_strip_remote_error() to fix up the + * message so it matches what was received on the wire. Since 2.26. + * @G_IO_ERROR_HOST_UNREACHABLE: Host unreachable. Since 2.26 + * @G_IO_ERROR_NETWORK_UNREACHABLE: Network unreachable. Since 2.26 + * @G_IO_ERROR_CONNECTION_REFUSED: Connection refused. Since 2.26 + * @G_IO_ERROR_PROXY_FAILED: Connection to proxy server failed. Since 2.26 + * @G_IO_ERROR_PROXY_AUTH_FAILED: Proxy authentication failed. Since 2.26 + * @G_IO_ERROR_PROXY_NEED_AUTH: Proxy server needs authentication. Since 2.26 + * @G_IO_ERROR_PROXY_NOT_ALLOWED: Proxy connection is not allowed by ruleset. + * Since 2.26 + * @G_IO_ERROR_BROKEN_PIPE: Broken pipe. Since 2.36 + * @G_IO_ERROR_CONNECTION_CLOSED: Connection closed by peer. Note that this + * is the same code as %G_IO_ERROR_BROKEN_PIPE; before 2.44 some + * "connection closed" errors returned %G_IO_ERROR_BROKEN_PIPE, but others + * returned %G_IO_ERROR_FAILED. Now they should all return the same + * value, which has this more logical name. Since 2.44. + * @G_IO_ERROR_NOT_CONNECTED: Transport endpoint is not connected. Since 2.44 + * @G_IO_ERROR_MESSAGE_TOO_LARGE: Message too large. Since 2.48. + * + * Error codes returned by GIO functions. + * + * Note that this domain may be extended in future GLib releases. In + * general, new error codes either only apply to new APIs, or else + * replace %G_IO_ERROR_FAILED in cases that were not explicitly + * distinguished before. You should therefore avoid writing code like + * |[ + * if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED)) + * { + * // Assume that this is EPRINTERONFIRE + * ... + * } + * ]| + * but should instead treat all unrecognized error codes the same as + * %G_IO_ERROR_FAILED. + * + * See also #GPollableReturn for a cheaper way of returning + * %G_IO_ERROR_WOULD_BLOCK to callers without allocating a #GError. + **/ +typedef enum { + G_IO_ERROR_FAILED, + G_IO_ERROR_NOT_FOUND, + G_IO_ERROR_EXISTS, + G_IO_ERROR_IS_DIRECTORY, + G_IO_ERROR_NOT_DIRECTORY, + G_IO_ERROR_NOT_EMPTY, + G_IO_ERROR_NOT_REGULAR_FILE, + G_IO_ERROR_NOT_SYMBOLIC_LINK, + G_IO_ERROR_NOT_MOUNTABLE_FILE, + G_IO_ERROR_FILENAME_TOO_LONG, + G_IO_ERROR_INVALID_FILENAME, + G_IO_ERROR_TOO_MANY_LINKS, + G_IO_ERROR_NO_SPACE, + G_IO_ERROR_INVALID_ARGUMENT, + G_IO_ERROR_PERMISSION_DENIED, + G_IO_ERROR_NOT_SUPPORTED, + G_IO_ERROR_NOT_MOUNTED, + G_IO_ERROR_ALREADY_MOUNTED, + G_IO_ERROR_CLOSED, + G_IO_ERROR_CANCELLED, + G_IO_ERROR_PENDING, + G_IO_ERROR_READ_ONLY, + G_IO_ERROR_CANT_CREATE_BACKUP, + G_IO_ERROR_WRONG_ETAG, + G_IO_ERROR_TIMED_OUT, + G_IO_ERROR_WOULD_RECURSE, + G_IO_ERROR_BUSY, + G_IO_ERROR_WOULD_BLOCK, + G_IO_ERROR_HOST_NOT_FOUND, + G_IO_ERROR_WOULD_MERGE, + G_IO_ERROR_FAILED_HANDLED, + G_IO_ERROR_TOO_MANY_OPEN_FILES, + G_IO_ERROR_NOT_INITIALIZED, + G_IO_ERROR_ADDRESS_IN_USE, + G_IO_ERROR_PARTIAL_INPUT, + G_IO_ERROR_INVALID_DATA, + G_IO_ERROR_DBUS_ERROR, + G_IO_ERROR_HOST_UNREACHABLE, + G_IO_ERROR_NETWORK_UNREACHABLE, + G_IO_ERROR_CONNECTION_REFUSED, + G_IO_ERROR_PROXY_FAILED, + G_IO_ERROR_PROXY_AUTH_FAILED, + G_IO_ERROR_PROXY_NEED_AUTH, + G_IO_ERROR_PROXY_NOT_ALLOWED, + G_IO_ERROR_BROKEN_PIPE, + G_IO_ERROR_CONNECTION_CLOSED = G_IO_ERROR_BROKEN_PIPE, + G_IO_ERROR_NOT_CONNECTED, + G_IO_ERROR_MESSAGE_TOO_LARGE +} GIOErrorEnum; + + +/** + * GAskPasswordFlags: + * @G_ASK_PASSWORD_NEED_PASSWORD: operation requires a password. + * @G_ASK_PASSWORD_NEED_USERNAME: operation requires a username. + * @G_ASK_PASSWORD_NEED_DOMAIN: operation requires a domain. + * @G_ASK_PASSWORD_SAVING_SUPPORTED: operation supports saving settings. + * @G_ASK_PASSWORD_ANONYMOUS_SUPPORTED: operation supports anonymous users. + * @G_ASK_PASSWORD_TCRYPT: operation takes TCRYPT parameters (Since: 2.58) + * + * #GAskPasswordFlags are used to request specific information from the + * user, or to notify the user of their choices in an authentication + * situation. + **/ +typedef enum { + G_ASK_PASSWORD_NEED_PASSWORD = (1 << 0), + G_ASK_PASSWORD_NEED_USERNAME = (1 << 1), + G_ASK_PASSWORD_NEED_DOMAIN = (1 << 2), + G_ASK_PASSWORD_SAVING_SUPPORTED = (1 << 3), + G_ASK_PASSWORD_ANONYMOUS_SUPPORTED = (1 << 4), + G_ASK_PASSWORD_TCRYPT = (1 << 5), +} GAskPasswordFlags; + + +/** + * GPasswordSave: + * @G_PASSWORD_SAVE_NEVER: never save a password. + * @G_PASSWORD_SAVE_FOR_SESSION: save a password for the session. + * @G_PASSWORD_SAVE_PERMANENTLY: save a password permanently. + * + * #GPasswordSave is used to indicate the lifespan of a saved password. + * + * #Gvfs stores passwords in the Gnome keyring when this flag allows it + * to, and later retrieves it again from there. + **/ +typedef enum { + G_PASSWORD_SAVE_NEVER, + G_PASSWORD_SAVE_FOR_SESSION, + G_PASSWORD_SAVE_PERMANENTLY +} GPasswordSave; + + +/** + * GMountOperationResult: + * @G_MOUNT_OPERATION_HANDLED: The request was fulfilled and the + * user specified data is now available + * @G_MOUNT_OPERATION_ABORTED: The user requested the mount operation + * to be aborted + * @G_MOUNT_OPERATION_UNHANDLED: The request was unhandled (i.e. not + * implemented) + * + * #GMountOperationResult is returned as a result when a request for + * information is send by the mounting operation. + **/ +typedef enum { + G_MOUNT_OPERATION_HANDLED, + G_MOUNT_OPERATION_ABORTED, + G_MOUNT_OPERATION_UNHANDLED +} GMountOperationResult; + + +/** + * GOutputStreamSpliceFlags: + * @G_OUTPUT_STREAM_SPLICE_NONE: Do not close either stream. + * @G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE: Close the source stream after + * the splice. + * @G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET: Close the target stream after + * the splice. + * + * GOutputStreamSpliceFlags determine how streams should be spliced. + **/ +typedef enum { + G_OUTPUT_STREAM_SPLICE_NONE = 0, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE = (1 << 0), + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET = (1 << 1) +} GOutputStreamSpliceFlags; + + +/** + * GIOStreamSpliceFlags: + * @G_IO_STREAM_SPLICE_NONE: Do not close either stream. + * @G_IO_STREAM_SPLICE_CLOSE_STREAM1: Close the first stream after + * the splice. + * @G_IO_STREAM_SPLICE_CLOSE_STREAM2: Close the second stream after + * the splice. + * @G_IO_STREAM_SPLICE_WAIT_FOR_BOTH: Wait for both splice operations to finish + * before calling the callback. + * + * GIOStreamSpliceFlags determine how streams should be spliced. + * + * Since: 2.28 + **/ +typedef enum { + G_IO_STREAM_SPLICE_NONE = 0, + G_IO_STREAM_SPLICE_CLOSE_STREAM1 = (1 << 0), + G_IO_STREAM_SPLICE_CLOSE_STREAM2 = (1 << 1), + G_IO_STREAM_SPLICE_WAIT_FOR_BOTH = (1 << 2) +} GIOStreamSpliceFlags; + +/** + * GEmblemOrigin: + * @G_EMBLEM_ORIGIN_UNKNOWN: Emblem of unknown origin + * @G_EMBLEM_ORIGIN_DEVICE: Emblem adds device-specific information + * @G_EMBLEM_ORIGIN_LIVEMETADATA: Emblem depicts live metadata, such as "readonly" + * @G_EMBLEM_ORIGIN_TAG: Emblem comes from a user-defined tag, e.g. set by nautilus (in the future) + * + * GEmblemOrigin is used to add information about the origin of the emblem + * to #GEmblem. + * + * Since: 2.18 + */ +typedef enum { + G_EMBLEM_ORIGIN_UNKNOWN, + G_EMBLEM_ORIGIN_DEVICE, + G_EMBLEM_ORIGIN_LIVEMETADATA, + G_EMBLEM_ORIGIN_TAG +} GEmblemOrigin; + +/** + * GResolverError: + * @G_RESOLVER_ERROR_NOT_FOUND: the requested name/address/service was not + * found + * @G_RESOLVER_ERROR_TEMPORARY_FAILURE: the requested information could not + * be looked up due to a network error or similar problem + * @G_RESOLVER_ERROR_INTERNAL: unknown error + * + * An error code used with %G_RESOLVER_ERROR in a #GError returned + * from a #GResolver routine. + * + * Since: 2.22 + */ +typedef enum { + G_RESOLVER_ERROR_NOT_FOUND, + G_RESOLVER_ERROR_TEMPORARY_FAILURE, + G_RESOLVER_ERROR_INTERNAL +} GResolverError; + +/** + * GResolverRecordType: + * @G_RESOLVER_RECORD_SRV: look up DNS SRV records for a domain + * @G_RESOLVER_RECORD_MX: look up DNS MX records for a domain + * @G_RESOLVER_RECORD_TXT: look up DNS TXT records for a name + * @G_RESOLVER_RECORD_SOA: look up DNS SOA records for a zone + * @G_RESOLVER_RECORD_NS: look up DNS NS records for a domain + * + * The type of record that g_resolver_lookup_records() or + * g_resolver_lookup_records_async() should retrieve. The records are returned + * as lists of #GVariant tuples. Each record type has different values in + * the variant tuples returned. + * + * %G_RESOLVER_RECORD_SRV records are returned as variants with the signature + * `(qqqs)`, containing a `guint16` with the priority, a `guint16` with the + * weight, a `guint16` with the port, and a string of the hostname. + * + * %G_RESOLVER_RECORD_MX records are returned as variants with the signature + * `(qs)`, representing a `guint16` with the preference, and a string containing + * the mail exchanger hostname. + * + * %G_RESOLVER_RECORD_TXT records are returned as variants with the signature + * `(as)`, representing an array of the strings in the text record. Note: Most TXT + * records only contain a single string, but + * [RFC 1035](https://tools.ietf.org/html/rfc1035#section-3.3.14) does allow a + * record to contain multiple strings. The RFC which defines the interpretation + * of a specific TXT record will likely require concatenation of multiple + * strings if they are present, as with + * [RFC 7208](https://tools.ietf.org/html/rfc7208#section-3.3). + * + * %G_RESOLVER_RECORD_SOA records are returned as variants with the signature + * `(ssuuuuu)`, representing a string containing the primary name server, a + * string containing the administrator, the serial as a `guint32`, the refresh + * interval as a `guint32`, the retry interval as a `guint32`, the expire timeout + * as a `guint32`, and the TTL as a `guint32`. + * + * %G_RESOLVER_RECORD_NS records are returned as variants with the signature + * `(s)`, representing a string of the hostname of the name server. + * + * Since: 2.34 + */ +typedef enum { + G_RESOLVER_RECORD_SRV = 1, + G_RESOLVER_RECORD_MX, + G_RESOLVER_RECORD_TXT, + G_RESOLVER_RECORD_SOA, + G_RESOLVER_RECORD_NS +} GResolverRecordType; + +/** + * GResourceError: + * @G_RESOURCE_ERROR_NOT_FOUND: no file was found at the requested path + * @G_RESOURCE_ERROR_INTERNAL: unknown error + * + * An error code used with %G_RESOURCE_ERROR in a #GError returned + * from a #GResource routine. + * + * Since: 2.32 + */ +typedef enum { + G_RESOURCE_ERROR_NOT_FOUND, + G_RESOURCE_ERROR_INTERNAL +} GResourceError; + +/** + * GResourceFlags: + * @G_RESOURCE_FLAGS_NONE: No flags set. + * @G_RESOURCE_FLAGS_COMPRESSED: The file is compressed. + * + * GResourceFlags give information about a particular file inside a resource + * bundle. + * + * Since: 2.32 + **/ +typedef enum { + G_RESOURCE_FLAGS_NONE = 0, + G_RESOURCE_FLAGS_COMPRESSED = (1<<0) +} GResourceFlags; + +/** + * GResourceLookupFlags: + * @G_RESOURCE_LOOKUP_FLAGS_NONE: No flags set. + * + * GResourceLookupFlags determine how resource path lookups are handled. + * + * Since: 2.32 + **/ +typedef enum /*< flags >*/ { + G_RESOURCE_LOOKUP_FLAGS_NONE = 0 +} GResourceLookupFlags; + +/** + * GSocketFamily: + * @G_SOCKET_FAMILY_INVALID: no address family + * @G_SOCKET_FAMILY_IPV4: the IPv4 family + * @G_SOCKET_FAMILY_IPV6: the IPv6 family + * @G_SOCKET_FAMILY_UNIX: the UNIX domain family + * + * The protocol family of a #GSocketAddress. (These values are + * identical to the system defines %AF_INET, %AF_INET6 and %AF_UNIX, + * if available.) + * + * Since: 2.22 + */ +typedef enum { + G_SOCKET_FAMILY_INVALID, + G_SOCKET_FAMILY_UNIX = GLIB_SYSDEF_AF_UNIX, + G_SOCKET_FAMILY_IPV4 = GLIB_SYSDEF_AF_INET, + G_SOCKET_FAMILY_IPV6 = GLIB_SYSDEF_AF_INET6 +} GSocketFamily; + +/** + * GSocketType: + * @G_SOCKET_TYPE_INVALID: Type unknown or wrong + * @G_SOCKET_TYPE_STREAM: Reliable connection-based byte streams (e.g. TCP). + * @G_SOCKET_TYPE_DATAGRAM: Connectionless, unreliable datagram passing. + * (e.g. UDP) + * @G_SOCKET_TYPE_SEQPACKET: Reliable connection-based passing of datagrams + * of fixed maximum length (e.g. SCTP). + * + * Flags used when creating a #GSocket. Some protocols may not implement + * all the socket types. + * + * Since: 2.22 + */ +typedef enum +{ + G_SOCKET_TYPE_INVALID, + G_SOCKET_TYPE_STREAM, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_TYPE_SEQPACKET +} GSocketType; + +/** + * GSocketMsgFlags: + * @G_SOCKET_MSG_NONE: No flags. + * @G_SOCKET_MSG_OOB: Request to send/receive out of band data. + * @G_SOCKET_MSG_PEEK: Read data from the socket without removing it from + * the queue. + * @G_SOCKET_MSG_DONTROUTE: Don't use a gateway to send out the packet, + * only send to hosts on directly connected networks. + * + * Flags used in g_socket_receive_message() and g_socket_send_message(). + * The flags listed in the enum are some commonly available flags, but the + * values used for them are the same as on the platform, and any other flags + * are passed in/out as is. So to use a platform specific flag, just include + * the right system header and pass in the flag. + * + * Since: 2.22 + */ +typedef enum /*< flags >*/ +{ + G_SOCKET_MSG_NONE, + G_SOCKET_MSG_OOB = GLIB_SYSDEF_MSG_OOB, + G_SOCKET_MSG_PEEK = GLIB_SYSDEF_MSG_PEEK, + G_SOCKET_MSG_DONTROUTE = GLIB_SYSDEF_MSG_DONTROUTE +} GSocketMsgFlags; + +/** + * GSocketProtocol: + * @G_SOCKET_PROTOCOL_UNKNOWN: The protocol type is unknown + * @G_SOCKET_PROTOCOL_DEFAULT: The default protocol for the family/type + * @G_SOCKET_PROTOCOL_TCP: TCP over IP + * @G_SOCKET_PROTOCOL_UDP: UDP over IP + * @G_SOCKET_PROTOCOL_SCTP: SCTP over IP + * + * A protocol identifier is specified when creating a #GSocket, which is a + * family/type specific identifier, where 0 means the default protocol for + * the particular family/type. + * + * This enum contains a set of commonly available and used protocols. You + * can also pass any other identifiers handled by the platform in order to + * use protocols not listed here. + * + * Since: 2.22 + */ +typedef enum { + G_SOCKET_PROTOCOL_UNKNOWN = -1, + G_SOCKET_PROTOCOL_DEFAULT = 0, + G_SOCKET_PROTOCOL_TCP = 6, + G_SOCKET_PROTOCOL_UDP = 17, + G_SOCKET_PROTOCOL_SCTP = 132 +} GSocketProtocol; + +/** + * GZlibCompressorFormat: + * @G_ZLIB_COMPRESSOR_FORMAT_ZLIB: deflate compression with zlib header + * @G_ZLIB_COMPRESSOR_FORMAT_GZIP: gzip file format + * @G_ZLIB_COMPRESSOR_FORMAT_RAW: deflate compression with no header + * + * Used to select the type of data format to use for #GZlibDecompressor + * and #GZlibCompressor. + * + * Since: 2.24 + */ +typedef enum { + G_ZLIB_COMPRESSOR_FORMAT_ZLIB, + G_ZLIB_COMPRESSOR_FORMAT_GZIP, + G_ZLIB_COMPRESSOR_FORMAT_RAW +} GZlibCompressorFormat; + +/** + * GUnixSocketAddressType: + * @G_UNIX_SOCKET_ADDRESS_INVALID: invalid + * @G_UNIX_SOCKET_ADDRESS_ANONYMOUS: anonymous + * @G_UNIX_SOCKET_ADDRESS_PATH: a filesystem path + * @G_UNIX_SOCKET_ADDRESS_ABSTRACT: an abstract name + * @G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED: an abstract name, 0-padded + * to the full length of a unix socket name + * + * The type of name used by a #GUnixSocketAddress. + * %G_UNIX_SOCKET_ADDRESS_PATH indicates a traditional unix domain + * socket bound to a filesystem path. %G_UNIX_SOCKET_ADDRESS_ANONYMOUS + * indicates a socket not bound to any name (eg, a client-side socket, + * or a socket created with socketpair()). + * + * For abstract sockets, there are two incompatible ways of naming + * them; the man pages suggest using the entire `struct sockaddr_un` + * as the name, padding the unused parts of the %sun_path field with + * zeroes; this corresponds to %G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED. + * However, many programs instead just use a portion of %sun_path, and + * pass an appropriate smaller length to bind() or connect(). This is + * %G_UNIX_SOCKET_ADDRESS_ABSTRACT. + * + * Since: 2.26 + */ +typedef enum { + G_UNIX_SOCKET_ADDRESS_INVALID, + G_UNIX_SOCKET_ADDRESS_ANONYMOUS, + G_UNIX_SOCKET_ADDRESS_PATH, + G_UNIX_SOCKET_ADDRESS_ABSTRACT, + G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED +} GUnixSocketAddressType; + +/** + * GBusType: + * @G_BUS_TYPE_STARTER: An alias for the message bus that activated the process, if any. + * @G_BUS_TYPE_NONE: Not a message bus. + * @G_BUS_TYPE_SYSTEM: The system-wide message bus. + * @G_BUS_TYPE_SESSION: The login session message bus. + * + * An enumeration for well-known message buses. + * + * Since: 2.26 + */ +typedef enum +{ + G_BUS_TYPE_STARTER = -1, + G_BUS_TYPE_NONE = 0, + G_BUS_TYPE_SYSTEM = 1, + G_BUS_TYPE_SESSION = 2 +} GBusType; + +/** + * GBusNameOwnerFlags: + * @G_BUS_NAME_OWNER_FLAGS_NONE: No flags set. + * @G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT: Allow another message bus connection to claim the name. + * @G_BUS_NAME_OWNER_FLAGS_REPLACE: If another message bus connection owns the name and have + * specified %G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, then take the name from the other connection. + * @G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE: If another message bus connection owns the name, immediately + * return an error from g_bus_own_name() rather than entering the waiting queue for that name. (Since 2.54) + * + * Flags used in g_bus_own_name(). + * + * Since: 2.26 + */ +typedef enum +{ + G_BUS_NAME_OWNER_FLAGS_NONE = 0, /*< nick=none >*/ + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT = (1<<0), /*< nick=allow-replacement >*/ + G_BUS_NAME_OWNER_FLAGS_REPLACE = (1<<1), /*< nick=replace >*/ + G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE = (1<<2) /*< nick=do-not-queue >*/ +} GBusNameOwnerFlags; +/* When adding new flags, their numeric values must currently match those + * used in the D-Bus Specification. */ + +/** + * GBusNameWatcherFlags: + * @G_BUS_NAME_WATCHER_FLAGS_NONE: No flags set. + * @G_BUS_NAME_WATCHER_FLAGS_AUTO_START: If no-one owns the name when + * beginning to watch the name, ask the bus to launch an owner for the + * name. + * + * Flags used in g_bus_watch_name(). + * + * Since: 2.26 + */ +typedef enum +{ + G_BUS_NAME_WATCHER_FLAGS_NONE = 0, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START = (1<<0) +} GBusNameWatcherFlags; + +/** + * GDBusProxyFlags: + * @G_DBUS_PROXY_FLAGS_NONE: No flags set. + * @G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES: Don't load properties. + * @G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS: Don't connect to signals on the remote object. + * @G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START: If the proxy is for a well-known name, + * do not ask the bus to launch an owner during proxy initialization or a method call. + * This flag is only meaningful in proxies for well-known names. + * @G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES: If set, the property value for any __invalidated property__ will be (asynchronously) retrieved upon receiving the [`PropertiesChanged`](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties) D-Bus signal and the property will not cause emission of the #GDBusProxy::g-properties-changed signal. When the value is received the #GDBusProxy::g-properties-changed signal is emitted for the property along with the retrieved value. Since 2.32. + * @G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION: If the proxy is for a well-known name, + * do not ask the bus to launch an owner during proxy initialization, but allow it to be + * autostarted by a method call. This flag is only meaningful in proxies for well-known names, + * and only if %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is not also specified. + * @G_DBUS_PROXY_FLAGS_NO_MATCH_RULE: Don't actually send the AddMatch D-Bus + * call for this signal subscription. This gives you more control + * over which match rules you add (but you must add them manually). (Since: 2.72) + * + * Flags used when constructing an instance of a #GDBusProxy derived class. + * + * Since: 2.26 + */ +typedef enum +{ + G_DBUS_PROXY_FLAGS_NONE = 0, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES = (1<<0), + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS = (1<<1), + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START = (1<<2), + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES = (1<<3), + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION = (1<<4), + G_DBUS_PROXY_FLAGS_NO_MATCH_RULE GLIB_AVAILABLE_ENUMERATOR_IN_2_72 = (1<<5) +} GDBusProxyFlags; + +/** + * GDBusError: + * @G_DBUS_ERROR_FAILED: + * A generic error; "something went wrong" - see the error message for + * more. + * @G_DBUS_ERROR_NO_MEMORY: + * There was not enough memory to complete an operation. + * @G_DBUS_ERROR_SERVICE_UNKNOWN: + * The bus doesn't know how to launch a service to supply the bus name + * you wanted. + * @G_DBUS_ERROR_NAME_HAS_NO_OWNER: + * The bus name you referenced doesn't exist (i.e. no application owns + * it). + * @G_DBUS_ERROR_NO_REPLY: + * No reply to a message expecting one, usually means a timeout occurred. + * @G_DBUS_ERROR_IO_ERROR: + * Something went wrong reading or writing to a socket, for example. + * @G_DBUS_ERROR_BAD_ADDRESS: + * A D-Bus bus address was malformed. + * @G_DBUS_ERROR_NOT_SUPPORTED: + * Requested operation isn't supported (like ENOSYS on UNIX). + * @G_DBUS_ERROR_LIMITS_EXCEEDED: + * Some limited resource is exhausted. + * @G_DBUS_ERROR_ACCESS_DENIED: + * Security restrictions don't allow doing what you're trying to do. + * @G_DBUS_ERROR_AUTH_FAILED: + * Authentication didn't work. + * @G_DBUS_ERROR_NO_SERVER: + * Unable to connect to server (probably caused by ECONNREFUSED on a + * socket). + * @G_DBUS_ERROR_TIMEOUT: + * Certain timeout errors, possibly ETIMEDOUT on a socket. Note that + * %G_DBUS_ERROR_NO_REPLY is used for message reply timeouts. Warning: + * this is confusingly-named given that %G_DBUS_ERROR_TIMED_OUT also + * exists. We can't fix it for compatibility reasons so just be + * careful. + * @G_DBUS_ERROR_NO_NETWORK: + * No network access (probably ENETUNREACH on a socket). + * @G_DBUS_ERROR_ADDRESS_IN_USE: + * Can't bind a socket since its address is in use (i.e. EADDRINUSE). + * @G_DBUS_ERROR_DISCONNECTED: + * The connection is disconnected and you're trying to use it. + * @G_DBUS_ERROR_INVALID_ARGS: + * Invalid arguments passed to a method call. + * @G_DBUS_ERROR_FILE_NOT_FOUND: + * Missing file. + * @G_DBUS_ERROR_FILE_EXISTS: + * Existing file and the operation you're using does not silently overwrite. + * @G_DBUS_ERROR_UNKNOWN_METHOD: + * Method name you invoked isn't known by the object you invoked it on. + * @G_DBUS_ERROR_UNKNOWN_OBJECT: + * Object you invoked a method on isn't known. Since 2.42 + * @G_DBUS_ERROR_UNKNOWN_INTERFACE: + * Interface you invoked a method on isn't known by the object. Since 2.42 + * @G_DBUS_ERROR_UNKNOWN_PROPERTY: + * Property you tried to access isn't known by the object. Since 2.42 + * @G_DBUS_ERROR_PROPERTY_READ_ONLY: + * Property you tried to set is read-only. Since 2.42 + * @G_DBUS_ERROR_TIMED_OUT: + * Certain timeout errors, e.g. while starting a service. Warning: this is + * confusingly-named given that %G_DBUS_ERROR_TIMEOUT also exists. We + * can't fix it for compatibility reasons so just be careful. + * @G_DBUS_ERROR_MATCH_RULE_NOT_FOUND: + * Tried to remove or modify a match rule that didn't exist. + * @G_DBUS_ERROR_MATCH_RULE_INVALID: + * The match rule isn't syntactically valid. + * @G_DBUS_ERROR_SPAWN_EXEC_FAILED: + * While starting a new process, the exec() call failed. + * @G_DBUS_ERROR_SPAWN_FORK_FAILED: + * While starting a new process, the fork() call failed. + * @G_DBUS_ERROR_SPAWN_CHILD_EXITED: + * While starting a new process, the child exited with a status code. + * @G_DBUS_ERROR_SPAWN_CHILD_SIGNALED: + * While starting a new process, the child exited on a signal. + * @G_DBUS_ERROR_SPAWN_FAILED: + * While starting a new process, something went wrong. + * @G_DBUS_ERROR_SPAWN_SETUP_FAILED: + * We failed to setup the environment correctly. + * @G_DBUS_ERROR_SPAWN_CONFIG_INVALID: + * We failed to setup the config parser correctly. + * @G_DBUS_ERROR_SPAWN_SERVICE_INVALID: + * Bus name was not valid. + * @G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND: + * Service file not found in system-services directory. + * @G_DBUS_ERROR_SPAWN_PERMISSIONS_INVALID: + * Permissions are incorrect on the setuid helper. + * @G_DBUS_ERROR_SPAWN_FILE_INVALID: + * Service file invalid (Name, User or Exec missing). + * @G_DBUS_ERROR_SPAWN_NO_MEMORY: + * Tried to get a UNIX process ID and it wasn't available. + * @G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN: + * Tried to get a UNIX process ID and it wasn't available. + * @G_DBUS_ERROR_INVALID_SIGNATURE: + * A type signature is not valid. + * @G_DBUS_ERROR_INVALID_FILE_CONTENT: + * A file contains invalid syntax or is otherwise broken. + * @G_DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN: + * Asked for SELinux security context and it wasn't available. + * @G_DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN: + * Asked for ADT audit data and it wasn't available. + * @G_DBUS_ERROR_OBJECT_PATH_IN_USE: + * There's already an object with the requested object path. + * + * Error codes for the %G_DBUS_ERROR error domain. + * + * Since: 2.26 + */ +typedef enum +{ + /* Well-known errors in the org.freedesktop.DBus.Error namespace */ + G_DBUS_ERROR_FAILED, /* org.freedesktop.DBus.Error.Failed */ + G_DBUS_ERROR_NO_MEMORY, /* org.freedesktop.DBus.Error.NoMemory */ + G_DBUS_ERROR_SERVICE_UNKNOWN, /* org.freedesktop.DBus.Error.ServiceUnknown */ + G_DBUS_ERROR_NAME_HAS_NO_OWNER, /* org.freedesktop.DBus.Error.NameHasNoOwner */ + G_DBUS_ERROR_NO_REPLY, /* org.freedesktop.DBus.Error.NoReply */ + G_DBUS_ERROR_IO_ERROR, /* org.freedesktop.DBus.Error.IOError */ + G_DBUS_ERROR_BAD_ADDRESS, /* org.freedesktop.DBus.Error.BadAddress */ + G_DBUS_ERROR_NOT_SUPPORTED, /* org.freedesktop.DBus.Error.NotSupported */ + G_DBUS_ERROR_LIMITS_EXCEEDED, /* org.freedesktop.DBus.Error.LimitsExceeded */ + G_DBUS_ERROR_ACCESS_DENIED, /* org.freedesktop.DBus.Error.AccessDenied */ + G_DBUS_ERROR_AUTH_FAILED, /* org.freedesktop.DBus.Error.AuthFailed */ + G_DBUS_ERROR_NO_SERVER, /* org.freedesktop.DBus.Error.NoServer */ + G_DBUS_ERROR_TIMEOUT, /* org.freedesktop.DBus.Error.Timeout */ + G_DBUS_ERROR_NO_NETWORK, /* org.freedesktop.DBus.Error.NoNetwork */ + G_DBUS_ERROR_ADDRESS_IN_USE, /* org.freedesktop.DBus.Error.AddressInUse */ + G_DBUS_ERROR_DISCONNECTED, /* org.freedesktop.DBus.Error.Disconnected */ + G_DBUS_ERROR_INVALID_ARGS, /* org.freedesktop.DBus.Error.InvalidArgs */ + G_DBUS_ERROR_FILE_NOT_FOUND, /* org.freedesktop.DBus.Error.FileNotFound */ + G_DBUS_ERROR_FILE_EXISTS, /* org.freedesktop.DBus.Error.FileExists */ + G_DBUS_ERROR_UNKNOWN_METHOD, /* org.freedesktop.DBus.Error.UnknownMethod */ + G_DBUS_ERROR_TIMED_OUT, /* org.freedesktop.DBus.Error.TimedOut */ + G_DBUS_ERROR_MATCH_RULE_NOT_FOUND, /* org.freedesktop.DBus.Error.MatchRuleNotFound */ + G_DBUS_ERROR_MATCH_RULE_INVALID, /* org.freedesktop.DBus.Error.MatchRuleInvalid */ + G_DBUS_ERROR_SPAWN_EXEC_FAILED, /* org.freedesktop.DBus.Error.Spawn.ExecFailed */ + G_DBUS_ERROR_SPAWN_FORK_FAILED, /* org.freedesktop.DBus.Error.Spawn.ForkFailed */ + G_DBUS_ERROR_SPAWN_CHILD_EXITED, /* org.freedesktop.DBus.Error.Spawn.ChildExited */ + G_DBUS_ERROR_SPAWN_CHILD_SIGNALED, /* org.freedesktop.DBus.Error.Spawn.ChildSignaled */ + G_DBUS_ERROR_SPAWN_FAILED, /* org.freedesktop.DBus.Error.Spawn.Failed */ + G_DBUS_ERROR_SPAWN_SETUP_FAILED, /* org.freedesktop.DBus.Error.Spawn.FailedToSetup */ + G_DBUS_ERROR_SPAWN_CONFIG_INVALID, /* org.freedesktop.DBus.Error.Spawn.ConfigInvalid */ + G_DBUS_ERROR_SPAWN_SERVICE_INVALID, /* org.freedesktop.DBus.Error.Spawn.ServiceNotValid */ + G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND, /* org.freedesktop.DBus.Error.Spawn.ServiceNotFound */ + G_DBUS_ERROR_SPAWN_PERMISSIONS_INVALID, /* org.freedesktop.DBus.Error.Spawn.PermissionsInvalid */ + G_DBUS_ERROR_SPAWN_FILE_INVALID, /* org.freedesktop.DBus.Error.Spawn.FileInvalid */ + G_DBUS_ERROR_SPAWN_NO_MEMORY, /* org.freedesktop.DBus.Error.Spawn.NoMemory */ + G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, /* org.freedesktop.DBus.Error.UnixProcessIdUnknown */ + G_DBUS_ERROR_INVALID_SIGNATURE, /* org.freedesktop.DBus.Error.InvalidSignature */ + G_DBUS_ERROR_INVALID_FILE_CONTENT, /* org.freedesktop.DBus.Error.InvalidFileContent */ + G_DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN, /* org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown */ + G_DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN, /* org.freedesktop.DBus.Error.AdtAuditDataUnknown */ + G_DBUS_ERROR_OBJECT_PATH_IN_USE, /* org.freedesktop.DBus.Error.ObjectPathInUse */ + G_DBUS_ERROR_UNKNOWN_OBJECT, /* org.freedesktop.DBus.Error.UnknownObject */ + G_DBUS_ERROR_UNKNOWN_INTERFACE, /* org.freedesktop.DBus.Error.UnknownInterface */ + G_DBUS_ERROR_UNKNOWN_PROPERTY, /* org.freedesktop.DBus.Error.UnknownProperty */ + G_DBUS_ERROR_PROPERTY_READ_ONLY /* org.freedesktop.DBus.Error.PropertyReadOnly */ +} GDBusError; +/* Remember to update g_dbus_error_quark() in gdbuserror.c if you extend this enumeration */ + +/** + * GDBusConnectionFlags: + * @G_DBUS_CONNECTION_FLAGS_NONE: No flags set. + * @G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT: Perform authentication against server. + * @G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER: Perform authentication against client. + * @G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS: When + * authenticating as a server, allow the anonymous authentication + * method. + * @G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION: Pass this flag if connecting to a peer that is a + * message bus. This means that the Hello() method will be invoked as part of the connection setup. + * @G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING: If set, processing of D-Bus messages is + * delayed until g_dbus_connection_start_message_processing() is called. + * @G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER: When authenticating + * as a server, require the UID of the peer to be the same as the UID of the server. (Since: 2.68) + * + * Flags used when creating a new #GDBusConnection. + * + * Since: 2.26 + */ +typedef enum { + G_DBUS_CONNECTION_FLAGS_NONE = 0, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT = (1<<0), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER = (1<<1), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS = (1<<2), + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION = (1<<3), + G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING = (1<<4), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_AVAILABLE_ENUMERATOR_IN_2_68 = (1<<5) +} GDBusConnectionFlags; + +/** + * GDBusCapabilityFlags: + * @G_DBUS_CAPABILITY_FLAGS_NONE: No flags set. + * @G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING: The connection + * supports exchanging UNIX file descriptors with the remote peer. + * + * Capabilities negotiated with the remote peer. + * + * Since: 2.26 + */ +typedef enum { + G_DBUS_CAPABILITY_FLAGS_NONE = 0, + G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING = (1<<0) +} GDBusCapabilityFlags; + +/** + * GDBusCallFlags: + * @G_DBUS_CALL_FLAGS_NONE: No flags set. + * @G_DBUS_CALL_FLAGS_NO_AUTO_START: The bus must not launch + * an owner for the destination name in response to this method + * invocation. + * @G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION: the caller is prepared to + * wait for interactive authorization. Since 2.46. + * + * Flags used in g_dbus_connection_call() and similar APIs. + * + * Since: 2.26 + */ +typedef enum { + G_DBUS_CALL_FLAGS_NONE = 0, + G_DBUS_CALL_FLAGS_NO_AUTO_START = (1<<0), + G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION = (1<<1) +} GDBusCallFlags; +/* (1<<31) is reserved for internal use by GDBusConnection, do not use it. */ + +/** + * GDBusMessageType: + * @G_DBUS_MESSAGE_TYPE_INVALID: Message is of invalid type. + * @G_DBUS_MESSAGE_TYPE_METHOD_CALL: Method call. + * @G_DBUS_MESSAGE_TYPE_METHOD_RETURN: Method reply. + * @G_DBUS_MESSAGE_TYPE_ERROR: Error reply. + * @G_DBUS_MESSAGE_TYPE_SIGNAL: Signal emission. + * + * Message types used in #GDBusMessage. + * + * Since: 2.26 + */ +typedef enum { + G_DBUS_MESSAGE_TYPE_INVALID, + G_DBUS_MESSAGE_TYPE_METHOD_CALL, + G_DBUS_MESSAGE_TYPE_METHOD_RETURN, + G_DBUS_MESSAGE_TYPE_ERROR, + G_DBUS_MESSAGE_TYPE_SIGNAL +} GDBusMessageType; + +/** + * GDBusMessageFlags: + * @G_DBUS_MESSAGE_FLAGS_NONE: No flags set. + * @G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED: A reply is not expected. + * @G_DBUS_MESSAGE_FLAGS_NO_AUTO_START: The bus must not launch an + * owner for the destination name in response to this message. + * @G_DBUS_MESSAGE_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION: If set on a method + * call, this flag means that the caller is prepared to wait for interactive + * authorization. Since 2.46. + * + * Message flags used in #GDBusMessage. + * + * Since: 2.26 + */ +typedef enum { + G_DBUS_MESSAGE_FLAGS_NONE = 0, + G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED = (1<<0), + G_DBUS_MESSAGE_FLAGS_NO_AUTO_START = (1<<1), + G_DBUS_MESSAGE_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION = (1<<2) +} GDBusMessageFlags; + +/** + * GDBusMessageHeaderField: + * @G_DBUS_MESSAGE_HEADER_FIELD_INVALID: Not a valid header field. + * @G_DBUS_MESSAGE_HEADER_FIELD_PATH: The object path. + * @G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE: The interface name. + * @G_DBUS_MESSAGE_HEADER_FIELD_MEMBER: The method or signal name. + * @G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME: The name of the error that occurred. + * @G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL: The serial number the message is a reply to. + * @G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION: The name the message is intended for. + * @G_DBUS_MESSAGE_HEADER_FIELD_SENDER: Unique name of the sender of the message (filled in by the bus). + * @G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE: The signature of the message body. + * @G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS: The number of UNIX file descriptors that accompany the message. + * + * Header fields used in #GDBusMessage. + * + * Since: 2.26 + */ +typedef enum { + G_DBUS_MESSAGE_HEADER_FIELD_INVALID, + G_DBUS_MESSAGE_HEADER_FIELD_PATH, + G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, + G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, + G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, + G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, + G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, + G_DBUS_MESSAGE_HEADER_FIELD_SENDER, + G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, + G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS +} GDBusMessageHeaderField; + +/** + * GDBusPropertyInfoFlags: + * @G_DBUS_PROPERTY_INFO_FLAGS_NONE: No flags set. + * @G_DBUS_PROPERTY_INFO_FLAGS_READABLE: Property is readable. + * @G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE: Property is writable. + * + * Flags describing the access control of a D-Bus property. + * + * Since: 2.26 + */ +typedef enum +{ + G_DBUS_PROPERTY_INFO_FLAGS_NONE = 0, + G_DBUS_PROPERTY_INFO_FLAGS_READABLE = (1<<0), + G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE = (1<<1) +} GDBusPropertyInfoFlags; + +/** + * GDBusSubtreeFlags: + * @G_DBUS_SUBTREE_FLAGS_NONE: No flags set. + * @G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES: Method calls to objects not in the enumerated range + * will still be dispatched. This is useful if you want + * to dynamically spawn objects in the subtree. + * + * Flags passed to g_dbus_connection_register_subtree(). + * + * Since: 2.26 + */ +typedef enum +{ + G_DBUS_SUBTREE_FLAGS_NONE = 0, + G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES = (1<<0) +} GDBusSubtreeFlags; + +/** + * GDBusServerFlags: + * @G_DBUS_SERVER_FLAGS_NONE: No flags set. + * @G_DBUS_SERVER_FLAGS_RUN_IN_THREAD: All #GDBusServer::new-connection + * signals will run in separated dedicated threads (see signal for + * details). + * @G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS: Allow the anonymous + * authentication method. + * @G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER: Require the UID of the + * peer to be the same as the UID of the server when authenticating. (Since: 2.68) + * + * Flags used when creating a #GDBusServer. + * + * Since: 2.26 + */ +typedef enum +{ + G_DBUS_SERVER_FLAGS_NONE = 0, + G_DBUS_SERVER_FLAGS_RUN_IN_THREAD = (1<<0), + G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS = (1<<1), + G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_AVAILABLE_ENUMERATOR_IN_2_68 = (1<<2) +} GDBusServerFlags; + +/** + * GDBusSignalFlags: + * @G_DBUS_SIGNAL_FLAGS_NONE: No flags set. + * @G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE: Don't actually send the AddMatch + * D-Bus call for this signal subscription. This gives you more control + * over which match rules you add (but you must add them manually). + * @G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE: Match first arguments that + * contain a bus or interface name with the given namespace. + * @G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH: Match first arguments that + * contain an object path that is either equivalent to the given path, + * or one of the paths is a subpath of the other. + * + * Flags used when subscribing to signals via g_dbus_connection_signal_subscribe(). + * + * Since: 2.26 + */ +typedef enum /*< flags >*/ +{ + G_DBUS_SIGNAL_FLAGS_NONE = 0, + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE = (1<<0), + G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE = (1<<1), + G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH = (1<<2) +} GDBusSignalFlags; + +/** + * GDBusSendMessageFlags: + * @G_DBUS_SEND_MESSAGE_FLAGS_NONE: No flags set. + * @G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL: Do not automatically + * assign a serial number from the #GDBusConnection object when + * sending a message. + * + * Flags used when sending #GDBusMessages on a #GDBusConnection. + * + * Since: 2.26 + */ +typedef enum +{ + G_DBUS_SEND_MESSAGE_FLAGS_NONE = 0, + G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL = (1<<0) +} GDBusSendMessageFlags; +/* (1<<31) is reserved for internal use by GDBusConnection, do not use it. */ + +/** + * GCredentialsType: + * @G_CREDENTIALS_TYPE_INVALID: Indicates an invalid native credential type. + * @G_CREDENTIALS_TYPE_LINUX_UCRED: The native credentials type is a `struct ucred`. + * @G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED: The native credentials type is a `struct cmsgcred`. + * @G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED: The native credentials type is a `struct sockpeercred`. Added in 2.30. + * @G_CREDENTIALS_TYPE_SOLARIS_UCRED: The native credentials type is a `ucred_t`. Added in 2.40. + * @G_CREDENTIALS_TYPE_NETBSD_UNPCBID: The native credentials type is a `struct unpcbid`. Added in 2.42. + * @G_CREDENTIALS_TYPE_APPLE_XUCRED: The native credentials type is a `struct xucred`. Added in 2.66. + * @G_CREDENTIALS_TYPE_WIN32_PID: The native credentials type is a PID `DWORD`. Added in 2.72. + * + * Enumeration describing different kinds of native credential types. + * + * Since: 2.26 + */ +typedef enum +{ + G_CREDENTIALS_TYPE_INVALID, + G_CREDENTIALS_TYPE_LINUX_UCRED, + G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, + G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED, + G_CREDENTIALS_TYPE_SOLARIS_UCRED, + G_CREDENTIALS_TYPE_NETBSD_UNPCBID, + G_CREDENTIALS_TYPE_APPLE_XUCRED, + G_CREDENTIALS_TYPE_WIN32_PID, +} GCredentialsType; + +/** + * GDBusMessageByteOrder: + * @G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN: The byte order is big endian. + * @G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN: The byte order is little endian. + * + * Enumeration used to describe the byte order of a D-Bus message. + * + * Since: 2.26 + */ +typedef enum +{ + G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN = 'B', + G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN = 'l' +} GDBusMessageByteOrder; + +/** + * GApplicationFlags: + * @G_APPLICATION_FLAGS_NONE: Default + * @G_APPLICATION_IS_SERVICE: Run as a service. In this mode, registration + * fails if the service is already running, and the application + * will initially wait up to 10 seconds for an initial activation + * message to arrive. + * @G_APPLICATION_IS_LAUNCHER: Don't try to become the primary instance. + * @G_APPLICATION_HANDLES_OPEN: This application handles opening files (in + * the primary instance). Note that this flag only affects the default + * implementation of local_command_line(), and has no effect if + * %G_APPLICATION_HANDLES_COMMAND_LINE is given. + * See g_application_run() for details. + * @G_APPLICATION_HANDLES_COMMAND_LINE: This application handles command line + * arguments (in the primary instance). Note that this flag only affect + * the default implementation of local_command_line(). + * See g_application_run() for details. + * @G_APPLICATION_SEND_ENVIRONMENT: Send the environment of the + * launching process to the primary instance. Set this flag if your + * application is expected to behave differently depending on certain + * environment variables. For instance, an editor might be expected + * to use the `GIT_COMMITTER_NAME` environment variable + * when editing a git commit message. The environment is available + * to the #GApplication::command-line signal handler, via + * g_application_command_line_getenv(). + * @G_APPLICATION_NON_UNIQUE: Make no attempts to do any of the typical + * single-instance application negotiation, even if the application + * ID is given. The application neither attempts to become the + * owner of the application ID nor does it check if an existing + * owner already exists. Everything occurs in the local process. + * Since: 2.30. + * @G_APPLICATION_CAN_OVERRIDE_APP_ID: Allow users to override the + * application ID from the command line with `--gapplication-app-id`. + * Since: 2.48 + * @G_APPLICATION_ALLOW_REPLACEMENT: Allow another instance to take over + * the bus name. Since: 2.60 + * @G_APPLICATION_REPLACE: Take over from another instance. This flag is + * usually set by passing `--gapplication-replace` on the commandline. + * Since: 2.60 + * + * Flags used to define the behaviour of a #GApplication. + * + * Since: 2.28 + **/ +typedef enum +{ + G_APPLICATION_FLAGS_NONE, + G_APPLICATION_IS_SERVICE = (1 << 0), + G_APPLICATION_IS_LAUNCHER = (1 << 1), + + G_APPLICATION_HANDLES_OPEN = (1 << 2), + G_APPLICATION_HANDLES_COMMAND_LINE = (1 << 3), + G_APPLICATION_SEND_ENVIRONMENT = (1 << 4), + + G_APPLICATION_NON_UNIQUE = (1 << 5), + + G_APPLICATION_CAN_OVERRIDE_APP_ID = (1 << 6), + G_APPLICATION_ALLOW_REPLACEMENT = (1 << 7), + G_APPLICATION_REPLACE = (1 << 8) +} GApplicationFlags; + +/** + * GTlsError: + * @G_TLS_ERROR_UNAVAILABLE: No TLS provider is available + * @G_TLS_ERROR_MISC: Miscellaneous TLS error + * @G_TLS_ERROR_BAD_CERTIFICATE: The certificate presented could not + * be parsed or failed validation. + * @G_TLS_ERROR_NOT_TLS: The TLS handshake failed because the + * peer does not seem to be a TLS server. + * @G_TLS_ERROR_HANDSHAKE: The TLS handshake failed because the + * peer's certificate was not acceptable. + * @G_TLS_ERROR_CERTIFICATE_REQUIRED: The TLS handshake failed because + * the server requested a client-side certificate, but none was + * provided. See g_tls_connection_set_certificate(). + * @G_TLS_ERROR_EOF: The TLS connection was closed without proper + * notice, which may indicate an attack. See + * g_tls_connection_set_require_close_notify(). + * @G_TLS_ERROR_INAPPROPRIATE_FALLBACK: The TLS handshake failed + * because the client sent the fallback SCSV, indicating a protocol + * downgrade attack. Since: 2.60 + * @G_TLS_ERROR_BAD_CERTIFICATE_PASSWORD: The certificate failed + * to load because a password was incorrect. Since: 2.72 + * + * An error code used with %G_TLS_ERROR in a #GError returned from a + * TLS-related routine. + * + * Since: 2.28 + */ +typedef enum { + G_TLS_ERROR_UNAVAILABLE, + G_TLS_ERROR_MISC, + G_TLS_ERROR_BAD_CERTIFICATE, + G_TLS_ERROR_NOT_TLS, + G_TLS_ERROR_HANDSHAKE, + G_TLS_ERROR_CERTIFICATE_REQUIRED, + G_TLS_ERROR_EOF, + G_TLS_ERROR_INAPPROPRIATE_FALLBACK, + G_TLS_ERROR_BAD_CERTIFICATE_PASSWORD +} GTlsError; + +/** + * GTlsCertificateFlags: + * @G_TLS_CERTIFICATE_UNKNOWN_CA: The signing certificate authority is + * not known. + * @G_TLS_CERTIFICATE_BAD_IDENTITY: The certificate does not match the + * expected identity of the site that it was retrieved from. + * @G_TLS_CERTIFICATE_NOT_ACTIVATED: The certificate's activation time + * is still in the future + * @G_TLS_CERTIFICATE_EXPIRED: The certificate has expired + * @G_TLS_CERTIFICATE_REVOKED: The certificate has been revoked + * according to the #GTlsConnection's certificate revocation list. + * @G_TLS_CERTIFICATE_INSECURE: The certificate's algorithm is + * considered insecure. + * @G_TLS_CERTIFICATE_GENERIC_ERROR: Some other error occurred validating + * the certificate + * @G_TLS_CERTIFICATE_VALIDATE_ALL: the combination of all of the above + * flags + * + * A set of flags describing TLS certification validation. This can be + * used to describe why a particular certificate was rejected (for + * example, in #GTlsConnection::accept-certificate). + * + * GLib guarantees that if certificate verification fails, at least one + * flag will be set, but it does not guarantee that all possible flags + * will be set. Accordingly, you may not safely decide to ignore any + * particular type of error. For example, it would be incorrect to mask + * %G_TLS_CERTIFICATE_EXPIRED if you want to allow expired certificates, + * because this could potentially be the only error flag set even if + * other problems exist with the certificate. + * + * Since: 2.28 + */ +typedef enum { + G_TLS_CERTIFICATE_UNKNOWN_CA = (1 << 0), + G_TLS_CERTIFICATE_BAD_IDENTITY = (1 << 1), + G_TLS_CERTIFICATE_NOT_ACTIVATED = (1 << 2), + G_TLS_CERTIFICATE_EXPIRED = (1 << 3), + G_TLS_CERTIFICATE_REVOKED = (1 << 4), + G_TLS_CERTIFICATE_INSECURE = (1 << 5), + G_TLS_CERTIFICATE_GENERIC_ERROR = (1 << 6), + + G_TLS_CERTIFICATE_VALIDATE_ALL = 0x007f +} GTlsCertificateFlags; + +/** + * GTlsAuthenticationMode: + * @G_TLS_AUTHENTICATION_NONE: client authentication not required + * @G_TLS_AUTHENTICATION_REQUESTED: client authentication is requested + * @G_TLS_AUTHENTICATION_REQUIRED: client authentication is required + * + * The client authentication mode for a #GTlsServerConnection. + * + * Since: 2.28 + */ +typedef enum { + G_TLS_AUTHENTICATION_NONE, + G_TLS_AUTHENTICATION_REQUESTED, + G_TLS_AUTHENTICATION_REQUIRED +} GTlsAuthenticationMode; + +/** + * GTlsChannelBindingType: + * @G_TLS_CHANNEL_BINDING_TLS_UNIQUE: + * [`tls-unique`](https://tools.ietf.org/html/rfc5929#section-3) binding + * type + * @G_TLS_CHANNEL_BINDING_TLS_SERVER_END_POINT: + * [`tls-server-end-point`](https://tools.ietf.org/html/rfc5929#section-4) + * binding type + * + * The type of TLS channel binding data to retrieve from #GTlsConnection + * or #GDtlsConnection, as documented by RFC 5929. The + * [`tls-unique-for-telnet`](https://tools.ietf.org/html/rfc5929#section-5) + * binding type is not currently implemented. + * + * Since: 2.66 + */ +GLIB_AVAILABLE_TYPE_IN_2_66 +typedef enum { + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, + G_TLS_CHANNEL_BINDING_TLS_SERVER_END_POINT +} GTlsChannelBindingType; + +/** + * GTlsChannelBindingError: + * @G_TLS_CHANNEL_BINDING_ERROR_NOT_IMPLEMENTED: Either entire binding + * retrieval facility or specific binding type is not implemented in the + * TLS backend. + * @G_TLS_CHANNEL_BINDING_ERROR_INVALID_STATE: The handshake is not yet + * complete on the connection which is a strong requirement for any existing + * binding type. + * @G_TLS_CHANNEL_BINDING_ERROR_NOT_AVAILABLE: Handshake is complete but + * binding data is not available. That normally indicates the TLS + * implementation failed to provide the binding data. For example, some + * implementations do not provide a peer certificate for resumed connections. + * @G_TLS_CHANNEL_BINDING_ERROR_NOT_SUPPORTED: Binding type is not supported + * on the current connection. This error could be triggered when requesting + * `tls-server-end-point` binding data for a certificate which has no hash + * function or uses multiple hash functions. + * @G_TLS_CHANNEL_BINDING_ERROR_GENERAL_ERROR: Any other backend error + * preventing binding data retrieval. + * + * An error code used with %G_TLS_CHANNEL_BINDING_ERROR in a #GError to + * indicate a TLS channel binding retrieval error. + * + * Since: 2.66 + */ +GLIB_AVAILABLE_TYPE_IN_2_66 +typedef enum { + G_TLS_CHANNEL_BINDING_ERROR_NOT_IMPLEMENTED, + G_TLS_CHANNEL_BINDING_ERROR_INVALID_STATE, + G_TLS_CHANNEL_BINDING_ERROR_NOT_AVAILABLE, + G_TLS_CHANNEL_BINDING_ERROR_NOT_SUPPORTED, + G_TLS_CHANNEL_BINDING_ERROR_GENERAL_ERROR +} GTlsChannelBindingError; + +/** + * GTlsRehandshakeMode: + * @G_TLS_REHANDSHAKE_NEVER: Never allow rehandshaking + * @G_TLS_REHANDSHAKE_SAFELY: Allow safe rehandshaking only + * @G_TLS_REHANDSHAKE_UNSAFELY: Allow unsafe rehandshaking + * + * When to allow rehandshaking. See + * g_tls_connection_set_rehandshake_mode(). + * + * Since: 2.28 + * + * Deprecated: 2.60. Changing the rehandshake mode is no longer + * required for compatibility. Also, rehandshaking has been removed + * from the TLS protocol in TLS 1.3. + */ +typedef enum { + G_TLS_REHANDSHAKE_NEVER, + G_TLS_REHANDSHAKE_SAFELY, + G_TLS_REHANDSHAKE_UNSAFELY +} GTlsRehandshakeMode GLIB_DEPRECATED_TYPE_IN_2_60; + +/** + * GTlsPasswordFlags: + * @G_TLS_PASSWORD_NONE: No flags + * @G_TLS_PASSWORD_RETRY: The password was wrong, and the user should retry. + * @G_TLS_PASSWORD_MANY_TRIES: Hint to the user that the password has been + * wrong many times, and the user may not have many chances left. + * @G_TLS_PASSWORD_FINAL_TRY: Hint to the user that this is the last try to get + * this password right. + * @G_TLS_PASSWORD_PKCS11_USER: For PKCS #11, the user PIN is required. + * Since: 2.70. + * @G_TLS_PASSWORD_PKCS11_SECURITY_OFFICER: For PKCS #11, the security officer + * PIN is required. Since: 2.70. + * @G_TLS_PASSWORD_PKCS11_CONTEXT_SPECIFIC: For PKCS #11, the context-specific + * PIN is required. Since: 2.70. + * + * Various flags for the password. + * + * Since: 2.30 + */ + +typedef enum _GTlsPasswordFlags +{ + G_TLS_PASSWORD_NONE = 0, + G_TLS_PASSWORD_RETRY = 1 << 1, + G_TLS_PASSWORD_MANY_TRIES = 1 << 2, + G_TLS_PASSWORD_FINAL_TRY = 1 << 3, + G_TLS_PASSWORD_PKCS11_USER = 1 << 4, + G_TLS_PASSWORD_PKCS11_SECURITY_OFFICER = 1 << 5, + G_TLS_PASSWORD_PKCS11_CONTEXT_SPECIFIC = 1 << 6 +} GTlsPasswordFlags; + +/** + * GTlsInteractionResult: + * @G_TLS_INTERACTION_UNHANDLED: The interaction was unhandled (i.e. not + * implemented). + * @G_TLS_INTERACTION_HANDLED: The interaction completed, and resulting data + * is available. + * @G_TLS_INTERACTION_FAILED: The interaction has failed, or was cancelled. + * and the operation should be aborted. + * + * #GTlsInteractionResult is returned by various functions in #GTlsInteraction + * when finishing an interaction request. + * + * Since: 2.30 + */ +typedef enum { + G_TLS_INTERACTION_UNHANDLED, + G_TLS_INTERACTION_HANDLED, + G_TLS_INTERACTION_FAILED +} GTlsInteractionResult; + +/** + * GDBusInterfaceSkeletonFlags: + * @G_DBUS_INTERFACE_SKELETON_FLAGS_NONE: No flags set. + * @G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD: Each method invocation is handled in + * a thread dedicated to the invocation. This means that the method implementation can use blocking IO + * without blocking any other part of the process. It also means that the method implementation must + * use locking to access data structures used by other threads. + * + * Flags describing the behavior of a #GDBusInterfaceSkeleton instance. + * + * Since: 2.30 + */ +typedef enum +{ + G_DBUS_INTERFACE_SKELETON_FLAGS_NONE = 0, + G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD = (1<<0) +} GDBusInterfaceSkeletonFlags; + +/** + * GDBusObjectManagerClientFlags: + * @G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE: No flags set. + * @G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START: If not set and the + * manager is for a well-known name, then request the bus to launch + * an owner for the name if no-one owns the name. This flag can only + * be used in managers for well-known names. + * + * Flags used when constructing a #GDBusObjectManagerClient. + * + * Since: 2.30 + */ +typedef enum +{ + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE = 0, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START = (1<<0) +} GDBusObjectManagerClientFlags; + +/** + * GTlsDatabaseVerifyFlags: + * @G_TLS_DATABASE_VERIFY_NONE: No verification flags + * + * Flags for g_tls_database_verify_chain(). + * + * Since: 2.30 + */ +typedef enum /*< flags >*/ { + G_TLS_DATABASE_VERIFY_NONE = 0 +} GTlsDatabaseVerifyFlags; + +/** + * GTlsDatabaseLookupFlags: + * @G_TLS_DATABASE_LOOKUP_NONE: No lookup flags + * @G_TLS_DATABASE_LOOKUP_KEYPAIR: Restrict lookup to certificates that have + * a private key. + * + * Flags for g_tls_database_lookup_certificate_for_handle(), + * g_tls_database_lookup_certificate_issuer(), + * and g_tls_database_lookup_certificates_issued_by(). + * + * Since: 2.30 + */ +typedef enum { + G_TLS_DATABASE_LOOKUP_NONE = 0, + G_TLS_DATABASE_LOOKUP_KEYPAIR = 1 +} GTlsDatabaseLookupFlags; + +/** + * GTlsCertificateRequestFlags: + * @G_TLS_CERTIFICATE_REQUEST_NONE: No flags + * + * Flags for g_tls_interaction_request_certificate(), + * g_tls_interaction_request_certificate_async(), and + * g_tls_interaction_invoke_request_certificate(). + * + * Since: 2.40 + */ +typedef enum { + G_TLS_CERTIFICATE_REQUEST_NONE = 0 +} GTlsCertificateRequestFlags; + +/** + * GTlsProtocolVersion: + * @G_TLS_PROTOCOL_VERSION_UNKNOWN: No protocol version or unknown protocol version + * @G_TLS_PROTOCOL_VERSION_SSL_3_0: SSL 3.0, which is insecure and should not be used + * @G_TLS_PROTOCOL_VERSION_TLS_1_0: TLS 1.0, which is insecure and should not be used + * @G_TLS_PROTOCOL_VERSION_TLS_1_1: TLS 1.1, which is insecure and should not be used + * @G_TLS_PROTOCOL_VERSION_TLS_1_2: TLS 1.2, defined by [RFC 5246](https://datatracker.ietf.org/doc/html/rfc5246) + * @G_TLS_PROTOCOL_VERSION_TLS_1_3: TLS 1.3, defined by [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446) + * @G_TLS_PROTOCOL_VERSION_DTLS_1_0: DTLS 1.0, which is insecure and should not be used + * @G_TLS_PROTOCOL_VERSION_DTLS_1_2: DTLS 1.2, defined by [RFC 6347](https://datatracker.ietf.org/doc/html/rfc6347) + * + * The TLS or DTLS protocol version used by a #GTlsConnection or + * #GDtlsConnection. The integer values of these versions are sequential + * to ensure newer known protocol versions compare greater than older + * known versions. Any known DTLS protocol version will compare greater + * than any SSL or TLS protocol version. The protocol version may be + * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the TLS backend supports a newer + * protocol version that GLib does not yet know about. This means that + * it's possible for an unknown DTLS protocol version to compare less + * than the TLS protocol versions. + * + * Since: 2.70 + */ +typedef enum { + G_TLS_PROTOCOL_VERSION_UNKNOWN = 0, + G_TLS_PROTOCOL_VERSION_SSL_3_0 = 1, + G_TLS_PROTOCOL_VERSION_TLS_1_0 = 2, + G_TLS_PROTOCOL_VERSION_TLS_1_1 = 3, + G_TLS_PROTOCOL_VERSION_TLS_1_2 = 4, + G_TLS_PROTOCOL_VERSION_TLS_1_3 = 5, + G_TLS_PROTOCOL_VERSION_DTLS_1_0 = 201, + G_TLS_PROTOCOL_VERSION_DTLS_1_2 = 202, +} GTlsProtocolVersion; + +/** + * GIOModuleScopeFlags: + * @G_IO_MODULE_SCOPE_NONE: No module scan flags + * @G_IO_MODULE_SCOPE_BLOCK_DUPLICATES: When using this scope to load or + * scan modules, automatically block a modules which has the same base + * basename as previously loaded module. + * + * Flags for use with g_io_module_scope_new(). + * + * Since: 2.30 + */ +typedef enum { + G_IO_MODULE_SCOPE_NONE, + G_IO_MODULE_SCOPE_BLOCK_DUPLICATES +} GIOModuleScopeFlags; + +/** + * GSocketClientEvent: + * @G_SOCKET_CLIENT_RESOLVING: The client is doing a DNS lookup. + * @G_SOCKET_CLIENT_RESOLVED: The client has completed a DNS lookup. + * @G_SOCKET_CLIENT_CONNECTING: The client is connecting to a remote + * host (either a proxy or the destination server). + * @G_SOCKET_CLIENT_CONNECTED: The client has connected to a remote + * host. + * @G_SOCKET_CLIENT_PROXY_NEGOTIATING: The client is negotiating + * with a proxy to connect to the destination server. + * @G_SOCKET_CLIENT_PROXY_NEGOTIATED: The client has negotiated + * with the proxy server. + * @G_SOCKET_CLIENT_TLS_HANDSHAKING: The client is performing a + * TLS handshake. + * @G_SOCKET_CLIENT_TLS_HANDSHAKED: The client has performed a + * TLS handshake. + * @G_SOCKET_CLIENT_COMPLETE: The client is done with a particular + * #GSocketConnectable. + * + * Describes an event occurring on a #GSocketClient. See the + * #GSocketClient::event signal for more details. + * + * Additional values may be added to this type in the future. + * + * Since: 2.32 + */ +typedef enum { + G_SOCKET_CLIENT_RESOLVING, + G_SOCKET_CLIENT_RESOLVED, + G_SOCKET_CLIENT_CONNECTING, + G_SOCKET_CLIENT_CONNECTED, + G_SOCKET_CLIENT_PROXY_NEGOTIATING, + G_SOCKET_CLIENT_PROXY_NEGOTIATED, + G_SOCKET_CLIENT_TLS_HANDSHAKING, + G_SOCKET_CLIENT_TLS_HANDSHAKED, + G_SOCKET_CLIENT_COMPLETE +} GSocketClientEvent; + +/** + * GSocketListenerEvent: + * @G_SOCKET_LISTENER_BINDING: The listener is about to bind a socket. + * @G_SOCKET_LISTENER_BOUND: The listener has bound a socket. + * @G_SOCKET_LISTENER_LISTENING: The listener is about to start + * listening on this socket. + * @G_SOCKET_LISTENER_LISTENED: The listener is now listening on + * this socket. + * + * Describes an event occurring on a #GSocketListener. See the + * #GSocketListener::event signal for more details. + * + * Additional values may be added to this type in the future. + * + * Since: 2.46 + */ +typedef enum { + G_SOCKET_LISTENER_BINDING, + G_SOCKET_LISTENER_BOUND, + G_SOCKET_LISTENER_LISTENING, + G_SOCKET_LISTENER_LISTENED +} GSocketListenerEvent; + +/** + * GTestDBusFlags: + * @G_TEST_DBUS_NONE: No flags. + * + * Flags to define future #GTestDBus behaviour. + * + * Since: 2.34 + */ +typedef enum /*< flags >*/ { + G_TEST_DBUS_NONE = 0 +} GTestDBusFlags; + +/** + * GSubprocessFlags: + * @G_SUBPROCESS_FLAGS_NONE: No flags. + * @G_SUBPROCESS_FLAGS_STDIN_PIPE: create a pipe for the stdin of the + * spawned process that can be accessed with + * g_subprocess_get_stdin_pipe(). + * @G_SUBPROCESS_FLAGS_STDIN_INHERIT: stdin is inherited from the + * calling process. + * @G_SUBPROCESS_FLAGS_STDOUT_PIPE: create a pipe for the stdout of the + * spawned process that can be accessed with + * g_subprocess_get_stdout_pipe(). + * @G_SUBPROCESS_FLAGS_STDOUT_SILENCE: silence the stdout of the spawned + * process (ie: redirect to `/dev/null`). + * @G_SUBPROCESS_FLAGS_STDERR_PIPE: create a pipe for the stderr of the + * spawned process that can be accessed with + * g_subprocess_get_stderr_pipe(). + * @G_SUBPROCESS_FLAGS_STDERR_SILENCE: silence the stderr of the spawned + * process (ie: redirect to `/dev/null`). + * @G_SUBPROCESS_FLAGS_STDERR_MERGE: merge the stderr of the spawned + * process with whatever the stdout happens to be. This is a good way + * of directing both streams to a common log file, for example. + * @G_SUBPROCESS_FLAGS_INHERIT_FDS: spawned processes will inherit the + * file descriptors of their parent, unless those descriptors have + * been explicitly marked as close-on-exec. This flag has no effect + * over the "standard" file descriptors (stdin, stdout, stderr). + * @G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP: if path searching is + * needed when spawning the subprocess, use the `PATH` in the launcher + * environment. (Since: 2.72) + * + * Flags to define the behaviour of a #GSubprocess. + * + * Note that the default for stdin is to redirect from `/dev/null`. For + * stdout and stderr the default are for them to inherit the + * corresponding descriptor from the calling process. + * + * Note that it is a programmer error to mix 'incompatible' flags. For + * example, you may not request both %G_SUBPROCESS_FLAGS_STDOUT_PIPE and + * %G_SUBPROCESS_FLAGS_STDOUT_SILENCE. + * + * Since: 2.40 + **/ +typedef enum { + G_SUBPROCESS_FLAGS_NONE = 0, + G_SUBPROCESS_FLAGS_STDIN_PIPE = (1u << 0), + G_SUBPROCESS_FLAGS_STDIN_INHERIT = (1u << 1), + G_SUBPROCESS_FLAGS_STDOUT_PIPE = (1u << 2), + G_SUBPROCESS_FLAGS_STDOUT_SILENCE = (1u << 3), + G_SUBPROCESS_FLAGS_STDERR_PIPE = (1u << 4), + G_SUBPROCESS_FLAGS_STDERR_SILENCE = (1u << 5), + G_SUBPROCESS_FLAGS_STDERR_MERGE = (1u << 6), + G_SUBPROCESS_FLAGS_INHERIT_FDS = (1u << 7), + G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP = (1u << 8) +} GSubprocessFlags; + +/** + * GNotificationPriority: + * @G_NOTIFICATION_PRIORITY_LOW: for notifications that do not require + * immediate attention - typically used for contextual background + * information, such as contact birthdays or local weather + * @G_NOTIFICATION_PRIORITY_NORMAL: the default priority, to be used for the + * majority of notifications (for example email messages, software updates, + * completed download/sync operations) + * @G_NOTIFICATION_PRIORITY_HIGH: for events that require more attention, + * usually because responses are time-sensitive (for example chat and SMS + * messages or alarms) + * @G_NOTIFICATION_PRIORITY_URGENT: for urgent notifications, or notifications + * that require a response in a short space of time (for example phone calls + * or emergency warnings) + * + * Priority levels for #GNotifications. + * + * Since: 2.42 + */ +typedef enum { + G_NOTIFICATION_PRIORITY_NORMAL, + G_NOTIFICATION_PRIORITY_LOW, + G_NOTIFICATION_PRIORITY_HIGH, + G_NOTIFICATION_PRIORITY_URGENT +} GNotificationPriority; + +/** + * GNetworkConnectivity: + * @G_NETWORK_CONNECTIVITY_LOCAL: The host is not configured with a + * route to the Internet; it may or may not be connected to a local + * network. + * @G_NETWORK_CONNECTIVITY_LIMITED: The host is connected to a network, but + * does not appear to be able to reach the full Internet, perhaps + * due to upstream network problems. + * @G_NETWORK_CONNECTIVITY_PORTAL: The host is behind a captive portal and + * cannot reach the full Internet. + * @G_NETWORK_CONNECTIVITY_FULL: The host is connected to a network, and + * appears to be able to reach the full Internet. + * + * The host's network connectivity state, as reported by #GNetworkMonitor. + * + * Since: 2.44 + */ +typedef enum { + G_NETWORK_CONNECTIVITY_LOCAL = 1, + G_NETWORK_CONNECTIVITY_LIMITED = 2, + G_NETWORK_CONNECTIVITY_PORTAL = 3, + G_NETWORK_CONNECTIVITY_FULL = 4 +} GNetworkConnectivity; + +/** + * GPollableReturn: + * @G_POLLABLE_RETURN_FAILED: Generic error condition for when an operation fails. + * @G_POLLABLE_RETURN_OK: The operation was successfully finished. + * @G_POLLABLE_RETURN_WOULD_BLOCK: The operation would block. + * + * Return value for various IO operations that signal errors via the + * return value and not necessarily via a #GError. + * + * This enum exists to be able to return errors to callers without having to + * allocate a #GError. Allocating #GErrors can be quite expensive for + * regularly happening errors like %G_IO_ERROR_WOULD_BLOCK. + * + * In case of %G_POLLABLE_RETURN_FAILED a #GError should be set for the + * operation to give details about the error that happened. + * + * Since: 2.60 + */ +typedef enum { + G_POLLABLE_RETURN_FAILED = 0, + G_POLLABLE_RETURN_OK = 1, + G_POLLABLE_RETURN_WOULD_BLOCK = -G_IO_ERROR_WOULD_BLOCK +} GPollableReturn; + +/** + * GMemoryMonitorWarningLevel: + * @G_MEMORY_MONITOR_WARNING_LEVEL_LOW: Memory on the device is low, processes + * should free up unneeded resources (for example, in-memory caches) so they can + * be used elsewhere. + * @G_MEMORY_MONITOR_WARNING_LEVEL_MEDIUM: Same as @G_MEMORY_MONITOR_WARNING_LEVEL_LOW + * but the device has even less free memory, so processes should try harder to free + * up unneeded resources. If your process does not need to stay running, it is a + * good time for it to quit. + * @G_MEMORY_MONITOR_WARNING_LEVEL_CRITICAL: The system will soon start terminating + * processes to reclaim memory, including background processes. + * + * Memory availability warning levels. + * + * Note that because new values might be added, it is recommended that applications check + * #GMemoryMonitorWarningLevel as ranges, for example: + * |[ + * if (warning_level > G_MEMORY_MONITOR_WARNING_LEVEL_LOW) + * drop_caches (); + * ]| + * + * Since: 2.64 + */ +typedef enum { + G_MEMORY_MONITOR_WARNING_LEVEL_LOW = 50, + G_MEMORY_MONITOR_WARNING_LEVEL_MEDIUM = 100, + G_MEMORY_MONITOR_WARNING_LEVEL_CRITICAL = 255 +} GMemoryMonitorWarningLevel; + +G_END_DECLS + +#endif /* __GIO_ENUMS_H__ */ diff --git a/gio/gioenumtypes.c.template b/gio/gioenumtypes.c.template new file mode 100644 index 0000000..948a012 --- /dev/null +++ b/gio/gioenumtypes.c.template @@ -0,0 +1,38 @@ +/*** BEGIN file-header ***/ +#include "config.h" +#include "gioenumtypes.h" +#include + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static gsize static_g_define_type_id = 0; + + if (g_once_init_enter (&static_g_define_type_id)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + + return static_g_define_type_id; +} + +/*** END value-tail ***/ diff --git a/gio/gioenumtypes.h.template b/gio/gioenumtypes.h.template new file mode 100644 index 0000000..4baa6df --- /dev/null +++ b/gio/gioenumtypes.h.template @@ -0,0 +1,24 @@ +/*** BEGIN file-header ***/ +#ifndef __GIO_ENUM_TYPES_H__ +#define __GIO_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS +/*** END file-header ***/ + +/*** BEGIN file-production ***/ + +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GLIB_AVAILABLE_IN_ALL GType @enum_name@_get_type (void) G_GNUC_CONST; +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) +/*** END value-header ***/ + +/*** BEGIN file-tail ***/ +G_END_DECLS + +#endif /* __GIO_ENUM_TYPES_H__ */ +/*** END file-tail ***/ diff --git a/gio/gioerror.c b/gio/gioerror.c new file mode 100644 index 0000000..7566c49 --- /dev/null +++ b/gio/gioerror.c @@ -0,0 +1,392 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include +#include "gioerror.h" + +#ifdef G_OS_WIN32 +#include +#endif + +/** + * SECTION:gioerror + * @short_description: Error helper functions + * @include: gio/gio.h + * + * Contains helper functions for reporting errors to the user. + **/ + +/** + * g_io_error_quark: + * + * Gets the GIO Error Quark. + * + * Returns: a #GQuark. + **/ +G_DEFINE_QUARK (g-io-error-quark, g_io_error) + +/** + * g_io_error_from_errno: + * @err_no: Error number as defined in errno.h. + * + * Converts errno.h error codes into GIO error codes. The fallback + * value %G_IO_ERROR_FAILED is returned for error codes not currently + * handled (but note that future GLib releases may return a more + * specific value instead). + * + * As %errno is global and may be modified by intermediate function + * calls, you should save its value as soon as the call which sets it + * returns: + * |[ + * int saved_errno; + * + * ret = read (blah); + * saved_errno = errno; + * + * g_io_error_from_errno (saved_errno); + * ]| + * + * Returns: #GIOErrorEnum value for the given errno.h error number. + **/ +GIOErrorEnum +g_io_error_from_errno (gint err_no) +{ + switch (err_no) + { +#ifdef EEXIST + case EEXIST: + return G_IO_ERROR_EXISTS; + break; +#endif + +#ifdef EISDIR + case EISDIR: + return G_IO_ERROR_IS_DIRECTORY; + break; +#endif + +#ifdef EACCES + case EACCES: + return G_IO_ERROR_PERMISSION_DENIED; + break; +#endif + +#ifdef ENAMETOOLONG + case ENAMETOOLONG: + return G_IO_ERROR_FILENAME_TOO_LONG; + break; +#endif + +#ifdef ENOENT + case ENOENT: + return G_IO_ERROR_NOT_FOUND; + break; +#endif + +#ifdef ENOTDIR + case ENOTDIR: + return G_IO_ERROR_NOT_DIRECTORY; + break; +#endif + +#ifdef ENXIO + case ENXIO: + return G_IO_ERROR_NOT_REGULAR_FILE; + break; +#endif + +#ifdef EROFS + case EROFS: + return G_IO_ERROR_READ_ONLY; + break; +#endif + +#ifdef EMLINK + case EMLINK: + return G_IO_ERROR_TOO_MANY_LINKS; + break; +#endif + +#ifdef ELOOP + case ELOOP: + return G_IO_ERROR_TOO_MANY_LINKS; + break; +#endif + +#ifdef ENOSPC + case ENOSPC: + return G_IO_ERROR_NO_SPACE; + break; +#endif + +#ifdef ENOMEM + case ENOMEM: + return G_IO_ERROR_NO_SPACE; + break; +#endif + +#ifdef EINVAL + case EINVAL: + return G_IO_ERROR_INVALID_ARGUMENT; + break; +#endif + +#ifdef EPERM + case EPERM: + return G_IO_ERROR_PERMISSION_DENIED; + break; +#endif + +#ifdef ECANCELED + case ECANCELED: + return G_IO_ERROR_CANCELLED; + break; +#endif + + /* ENOTEMPTY == EEXIST on AIX for backward compatibility reasons */ +#if defined (ENOTEMPTY) && (!defined (EEXIST) || (ENOTEMPTY != EEXIST)) + case ENOTEMPTY: + return G_IO_ERROR_NOT_EMPTY; + break; +#endif + +#ifdef ENOTSUP + case ENOTSUP: + return G_IO_ERROR_NOT_SUPPORTED; + break; +#endif + + /* EOPNOTSUPP == ENOTSUP on Linux, but POSIX considers them distinct */ +#if defined (EOPNOTSUPP) && (!defined (ENOTSUP) || (EOPNOTSUPP != ENOTSUP)) + case EOPNOTSUPP: + return G_IO_ERROR_NOT_SUPPORTED; + break; +#endif + +#ifdef EPROTONOSUPPORT + case EPROTONOSUPPORT: + return G_IO_ERROR_NOT_SUPPORTED; + break; +#endif + +#ifdef ESOCKTNOSUPPORT + case ESOCKTNOSUPPORT: + return G_IO_ERROR_NOT_SUPPORTED; + break; +#endif + +#ifdef EPFNOSUPPORT + case EPFNOSUPPORT: + return G_IO_ERROR_NOT_SUPPORTED; + break; +#endif + +#ifdef EAFNOSUPPORT + case EAFNOSUPPORT: + return G_IO_ERROR_NOT_SUPPORTED; + break; +#endif + +#ifdef ETIMEDOUT + case ETIMEDOUT: + return G_IO_ERROR_TIMED_OUT; + break; +#endif + +#ifdef EBUSY + case EBUSY: + return G_IO_ERROR_BUSY; + break; +#endif + +#ifdef ETXTBSY + case ETXTBSY: + return G_IO_ERROR_BUSY; + break; +#endif + +#ifdef EWOULDBLOCK + case EWOULDBLOCK: + return G_IO_ERROR_WOULD_BLOCK; + break; +#endif + + /* EWOULDBLOCK == EAGAIN on most systems, but POSIX considers them distinct */ +#if defined (EAGAIN) && (!defined (EWOULDBLOCK) || (EWOULDBLOCK != EAGAIN)) + case EAGAIN: + return G_IO_ERROR_WOULD_BLOCK; + break; +#endif + +#ifdef EMFILE + case EMFILE: + return G_IO_ERROR_TOO_MANY_OPEN_FILES; + break; +#endif + +#ifdef EADDRINUSE + case EADDRINUSE: + return G_IO_ERROR_ADDRESS_IN_USE; + break; +#endif + +#ifdef EHOSTUNREACH + case EHOSTUNREACH: + return G_IO_ERROR_HOST_UNREACHABLE; + break; +#endif + +#ifdef ENETUNREACH + case ENETUNREACH: + return G_IO_ERROR_NETWORK_UNREACHABLE; + break; +#endif + +#ifdef ECONNREFUSED + case ECONNREFUSED: + return G_IO_ERROR_CONNECTION_REFUSED; + break; +#endif + +#ifdef EPIPE + case EPIPE: + return G_IO_ERROR_BROKEN_PIPE; + break; +#endif + +#ifdef ECONNRESET + case ECONNRESET: + return G_IO_ERROR_CONNECTION_CLOSED; + break; +#endif + +#ifdef ENOTCONN + case ENOTCONN: + return G_IO_ERROR_NOT_CONNECTED; + break; +#endif + +#ifdef EMSGSIZE + case EMSGSIZE: + return G_IO_ERROR_MESSAGE_TOO_LARGE; + break; +#endif + +#ifdef ENOTSOCK + case ENOTSOCK: + return G_IO_ERROR_INVALID_ARGUMENT; + break; +#endif + + default: + return G_IO_ERROR_FAILED; + break; + } +} + +#ifdef G_OS_WIN32 + +/** + * g_io_error_from_win32_error: + * @error_code: Windows error number. + * + * Converts some common error codes (as returned from GetLastError() + * or WSAGetLastError()) into GIO error codes. The fallback value + * %G_IO_ERROR_FAILED is returned for error codes not currently + * handled (but note that future GLib releases may return a more + * specific value instead). + * + * You can use g_win32_error_message() to get a localized string + * corresponding to @error_code. (But note that unlike g_strerror(), + * g_win32_error_message() returns a string that must be freed.) + * + * Returns: #GIOErrorEnum value for the given error number. + * + * Since: 2.26 + **/ +GIOErrorEnum +g_io_error_from_win32_error (gint error_code) +{ + /* Note: Winsock errors are a subset of Win32 error codes as a + * whole. (The fact that the Winsock API makes them look like they + * aren't is just because the API predates Win32.) + */ + + switch (error_code) + { + case WSAEADDRINUSE: + return G_IO_ERROR_ADDRESS_IN_USE; + + case WSAEWOULDBLOCK: + return G_IO_ERROR_WOULD_BLOCK; + + case WSAEACCES: + return G_IO_ERROR_PERMISSION_DENIED; + + case WSA_INVALID_HANDLE: + case WSA_INVALID_PARAMETER: + case WSAEINVAL: + case WSAEBADF: + case WSAENOTSOCK: + return G_IO_ERROR_INVALID_ARGUMENT; + + case WSAEPROTONOSUPPORT: + return G_IO_ERROR_NOT_SUPPORTED; + + case WSAECANCELLED: + return G_IO_ERROR_CANCELLED; + + case WSAESOCKTNOSUPPORT: + case WSAEOPNOTSUPP: + case WSAEPFNOSUPPORT: + case WSAEAFNOSUPPORT: + return G_IO_ERROR_NOT_SUPPORTED; + + case WSAECONNRESET: + case WSAENETRESET: + case WSAESHUTDOWN: + return G_IO_ERROR_CONNECTION_CLOSED; + + case WSAEHOSTUNREACH: + return G_IO_ERROR_HOST_UNREACHABLE; + + case WSAENETUNREACH: + return G_IO_ERROR_NETWORK_UNREACHABLE; + + case WSAECONNREFUSED: + return G_IO_ERROR_CONNECTION_REFUSED; + + case WSAETIMEDOUT: + return G_IO_ERROR_TIMED_OUT; + + case WSAENOTCONN: + case ERROR_PIPE_LISTENING: + return G_IO_ERROR_NOT_CONNECTED; + + case WSAEMSGSIZE: + return G_IO_ERROR_MESSAGE_TOO_LARGE; + + default: + return G_IO_ERROR_FAILED; + } +} + +#endif diff --git a/gio/gioerror.h b/gio/gioerror.h new file mode 100644 index 0000000..b3d6446 --- /dev/null +++ b/gio/gioerror.h @@ -0,0 +1,53 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_IO_ERROR_H__ +#define __G_IO_ERROR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +/** + * G_IO_ERROR: + * + * Error domain for GIO. Errors in this domain will be from the #GIOErrorEnum enumeration. + * See #GError for more information on error domains. + **/ +#define G_IO_ERROR g_io_error_quark() + +GLIB_AVAILABLE_IN_ALL +GQuark g_io_error_quark (void); +GLIB_AVAILABLE_IN_ALL +GIOErrorEnum g_io_error_from_errno (gint err_no); + +#ifdef G_OS_WIN32 +GLIB_AVAILABLE_IN_ALL +GIOErrorEnum g_io_error_from_win32_error (gint error_code); +#endif + +G_END_DECLS + +#endif /* __G_IO_ERROR_H__ */ diff --git a/gio/giomodule-priv.c b/gio/giomodule-priv.c new file mode 100644 index 0000000..d4ddd36 --- /dev/null +++ b/gio/giomodule-priv.c @@ -0,0 +1,70 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2017 Collabora Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Xavier Claessens + */ + +#include "config.h" +#include "giomodule.h" +#include "giomodule-priv.h" + +#include + +/** + * _g_io_module_extract_name: + * @filename: filename of a GIOModule + * + * Extract the plugin name from its filename. It removes optional "lib" or + * "libgio" prefix, and removes everything after the first dot. For example: + * "libgiognutls.so" -> "gnutls". + * + * Returns: (transfer full): the module's name + */ +gchar * +_g_io_module_extract_name (const char *filename) +{ + gchar *bname, *name; + const gchar *dot; + gsize prefix_len, len; + gsize i; + + bname = g_path_get_basename (filename); + for (i = 0; bname[i]; ++i) + { + if (bname[i] == '-') + bname[i] = '_'; + } + + if (g_str_has_prefix (bname, "libgio")) + prefix_len = 6; + /* DLLs built with MSVC generally do not have the 'lib' prefix */ + else if (g_str_has_prefix (bname, "lib") || g_str_has_prefix (bname, "gio")) + prefix_len = 3; + else + prefix_len = 0; /* use whole name (minus suffix) as plugin name */ + + dot = strchr (bname, '.'); + if (dot != NULL) + len = dot - bname - prefix_len; + else + len = strlen (bname + prefix_len); + + name = g_strndup (bname + prefix_len, len); + g_free (bname); + + return name; +} diff --git a/gio/giomodule-priv.h b/gio/giomodule-priv.h new file mode 100644 index 0000000..68d46f2 --- /dev/null +++ b/gio/giomodule-priv.h @@ -0,0 +1,49 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_IO_MODULE_PRIV_H__ +#define __G_IO_MODULE_PRIV_H__ + +#include "giomodule.h" + +G_BEGIN_DECLS + +void _g_io_modules_ensure_extension_points_registered (void); +void _g_io_modules_ensure_loaded (void); + +typedef gboolean (*GIOModuleVerifyFunc) (gpointer); +gpointer _g_io_module_get_default (const gchar *extension_point, + const gchar *envvar, + GIOModuleVerifyFunc verify_func); + +GType _g_io_module_get_default_type (const gchar *extension_point, + const gchar *envvar, + guint is_supported_offset); + +#ifdef G_PLATFORM_WIN32 +void *_g_io_win32_get_module (void); +#endif + +gchar *_g_io_module_extract_name (const char *filename); + + +G_END_DECLS + +#endif /* __G_IO_MODULE_PRIV_H__ */ diff --git a/gio/giomodule.c b/gio/giomodule.c new file mode 100644 index 0000000..2a043cc --- /dev/null +++ b/gio/giomodule.c @@ -0,0 +1,1694 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +/* For the #GDesktopAppInfoLookup macros; since macro deprecation is implemented + * in the preprocessor, we need to define this before including glib.h*/ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +#include "giomodule.h" +#include "giomodule-priv.h" +#include "glib-private.h" +#include "glocalfilemonitor.h" +#include "gnativevolumemonitor.h" +#include "gproxyresolver.h" +#include "gproxy.h" +#include "gsettingsbackendinternal.h" +#include "ghttpproxy.h" +#include "gsocks4proxy.h" +#include "gsocks4aproxy.h" +#include "gsocks5proxy.h" +#include "gtlsbackend.h" +#include "gvfs.h" +#include "gnotificationbackend.h" +#include "ginitable.h" +#include "gnetworkmonitor.h" +#include "gdebugcontroller.h" +#include "gdebugcontrollerdbus.h" +#include "gmemorymonitor.h" +#include "gmemorymonitorportal.h" +#include "gmemorymonitordbus.h" +#include "gpowerprofilemonitor.h" +#include "gpowerprofilemonitordbus.h" +#include "gpowerprofilemonitorportal.h" +#ifdef G_OS_WIN32 +#include "gregistrysettingsbackend.h" +#include "giowin32-priv.h" +#endif +#include + +#if defined(G_OS_UNIX) && !defined(HAVE_COCOA) +#include "gdesktopappinfo.h" +#endif +#ifdef HAVE_COCOA +#include "gosxappinfo.h" +#endif + +#ifdef HAVE_COCOA +#include +#endif + +#define __GLIB_H_INSIDE__ +#include "gconstructor.h" +#undef __GLIB_H_INSIDE__ + +/** + * SECTION:giomodule + * @short_description: Loadable GIO Modules + * @include: gio/gio.h + * + * Provides an interface and default functions for loading and unloading + * modules. This is used internally to make GIO extensible, but can also + * be used by others to implement module loading. + * + **/ + +/** + * SECTION:extensionpoints + * @short_description: Extension Points + * @include: gio.h + * @see_also: [Extending GIO][extending-gio] + * + * #GIOExtensionPoint provides a mechanism for modules to extend the + * functionality of the library or application that loaded it in an + * organized fashion. + * + * An extension point is identified by a name, and it may optionally + * require that any implementation must be of a certain type (or derived + * thereof). Use g_io_extension_point_register() to register an + * extension point, and g_io_extension_point_set_required_type() to + * set a required type. + * + * A module can implement an extension point by specifying the #GType + * that implements the functionality. Additionally, each implementation + * of an extension point has a name, and a priority. Use + * g_io_extension_point_implement() to implement an extension point. + * + * |[ + * GIOExtensionPoint *ep; + * + * // Register an extension point + * ep = g_io_extension_point_register ("my-extension-point"); + * g_io_extension_point_set_required_type (ep, MY_TYPE_EXAMPLE); + * ]| + * + * |[ + * // Implement an extension point + * G_DEFINE_TYPE (MyExampleImpl, my_example_impl, MY_TYPE_EXAMPLE) + * g_io_extension_point_implement ("my-extension-point", + * my_example_impl_get_type (), + * "my-example", + * 10); + * ]| + * + * It is up to the code that registered the extension point how + * it uses the implementations that have been associated with it. + * Depending on the use case, it may use all implementations, or + * only the one with the highest priority, or pick a specific + * one by name. + * + * To avoid opening all modules just to find out what extension + * points they implement, GIO makes use of a caching mechanism, + * see [gio-querymodules][gio-querymodules]. + * You are expected to run this command after installing a + * GIO module. + * + * The `GIO_EXTRA_MODULES` environment variable can be used to + * specify additional directories to automatically load modules + * from. This environment variable has the same syntax as the + * `PATH`. If two modules have the same base name in different + * directories, then the latter one will be ignored. If additional + * directories are specified GIO will load modules from the built-in + * directory last. + */ + +/** + * GIOModuleScope: + * + * Represents a scope for loading IO modules. A scope can be used for blocking + * duplicate modules, or blocking a module you don't want to load. + * + * The scope can be used with g_io_modules_load_all_in_directory_with_scope() + * or g_io_modules_scan_all_in_directory_with_scope(). + * + * Since: 2.30 + */ +struct _GIOModuleScope { + GIOModuleScopeFlags flags; + GHashTable *basenames; +}; + +/** + * g_io_module_scope_new: + * @flags: flags for the new scope + * + * Create a new scope for loading of IO modules. A scope can be used for + * blocking duplicate modules, or blocking a module you don't want to load. + * + * Specify the %G_IO_MODULE_SCOPE_BLOCK_DUPLICATES flag to block modules + * which have the same base name as a module that has already been seen + * in this scope. + * + * Returns: (transfer full): the new module scope + * + * Since: 2.30 + */ +GIOModuleScope * +g_io_module_scope_new (GIOModuleScopeFlags flags) +{ + GIOModuleScope *scope = g_new0 (GIOModuleScope, 1); + scope->flags = flags; + scope->basenames = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + return scope; +} + +/** + * g_io_module_scope_free: + * @scope: a module loading scope + * + * Free a module scope. + * + * Since: 2.30 + */ +void +g_io_module_scope_free (GIOModuleScope *scope) +{ + if (!scope) + return; + g_hash_table_destroy (scope->basenames); + g_free (scope); +} + +/** + * g_io_module_scope_block: + * @scope: a module loading scope + * @basename: the basename to block + * + * Block modules with the given @basename from being loaded when + * this scope is used with g_io_modules_scan_all_in_directory_with_scope() + * or g_io_modules_load_all_in_directory_with_scope(). + * + * Since: 2.30 + */ +void +g_io_module_scope_block (GIOModuleScope *scope, + const gchar *basename) +{ + gchar *key; + + g_return_if_fail (scope != NULL); + g_return_if_fail (basename != NULL); + + key = g_strdup (basename); + g_hash_table_add (scope->basenames, key); +} + +static gboolean +_g_io_module_scope_contains (GIOModuleScope *scope, + const gchar *basename) +{ + return g_hash_table_contains (scope->basenames, basename); +} + +struct _GIOModule { + GTypeModule parent_instance; + + gchar *filename; + GModule *library; + gboolean initialized; /* The module was loaded at least once */ + + void (* load) (GIOModule *module); + void (* unload) (GIOModule *module); +}; + +struct _GIOModuleClass +{ + GTypeModuleClass parent_class; + +}; + +static void g_io_module_finalize (GObject *object); +static gboolean g_io_module_load_module (GTypeModule *gmodule); +static void g_io_module_unload_module (GTypeModule *gmodule); + +/** + * GIOExtension: + * + * #GIOExtension is an opaque data structure and can only be accessed + * using the following functions. + */ +struct _GIOExtension { + char *name; + GType type; + gint priority; +}; + +/** + * GIOExtensionPoint: + * + * #GIOExtensionPoint is an opaque data structure and can only be accessed + * using the following functions. + */ +struct _GIOExtensionPoint { + GType required_type; + char *name; + GList *extensions; + GList *lazy_load_modules; +}; + +static GHashTable *extension_points = NULL; +G_LOCK_DEFINE_STATIC(extension_points); + +G_DEFINE_TYPE (GIOModule, g_io_module, G_TYPE_TYPE_MODULE) + +static void +g_io_module_class_init (GIOModuleClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class); + + object_class->finalize = g_io_module_finalize; + + type_module_class->load = g_io_module_load_module; + type_module_class->unload = g_io_module_unload_module; +} + +static void +g_io_module_init (GIOModule *module) +{ +} + +static void +g_io_module_finalize (GObject *object) +{ + GIOModule *module = G_IO_MODULE (object); + + g_free (module->filename); + + G_OBJECT_CLASS (g_io_module_parent_class)->finalize (object); +} + +static gboolean +load_symbols (GIOModule *module) +{ + gchar *name; + gchar *load_symname; + gchar *unload_symname; + gboolean ret; + + name = _g_io_module_extract_name (module->filename); + load_symname = g_strconcat ("g_io_", name, "_load", NULL); + unload_symname = g_strconcat ("g_io_", name, "_unload", NULL); + + ret = g_module_symbol (module->library, + load_symname, + (gpointer) &module->load) && + g_module_symbol (module->library, + unload_symname, + (gpointer) &module->unload); + + if (!ret) + { + /* Fallback to old names */ + ret = g_module_symbol (module->library, + "g_io_module_load", + (gpointer) &module->load) && + g_module_symbol (module->library, + "g_io_module_unload", + (gpointer) &module->unload); + } + + g_free (name); + g_free (load_symname); + g_free (unload_symname); + + return ret; +} + +static gboolean +g_io_module_load_module (GTypeModule *gmodule) +{ + GIOModule *module = G_IO_MODULE (gmodule); + GError *error = NULL; + + if (!module->filename) + { + g_warning ("GIOModule path not set"); + return FALSE; + } + + module->library = g_module_open_full (module->filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL, &error); + + if (!module->library) + { + g_printerr ("%s\n", error->message); + g_clear_error (&error); + return FALSE; + } + + /* Make sure that the loaded library contains the required methods */ + if (!load_symbols (module)) + { + g_printerr ("%s\n", g_module_error ()); + g_module_close (module->library); + + return FALSE; + } + + /* Initialize the loaded module */ + module->load (module); + module->initialized = TRUE; + + return TRUE; +} + +static void +g_io_module_unload_module (GTypeModule *gmodule) +{ + GIOModule *module = G_IO_MODULE (gmodule); + + module->unload (module); + + g_module_close (module->library); + module->library = NULL; + + module->load = NULL; + module->unload = NULL; +} + +/** + * g_io_module_new: + * @filename: (type filename): filename of the shared library module. + * + * Creates a new GIOModule that will load the specific + * shared library when in use. + * + * Returns: a #GIOModule from given @filename, + * or %NULL on error. + **/ +GIOModule * +g_io_module_new (const gchar *filename) +{ + GIOModule *module; + + g_return_val_if_fail (filename != NULL, NULL); + + module = g_object_new (G_IO_TYPE_MODULE, NULL); + module->filename = g_strdup (filename); + + return module; +} + +static gboolean +is_valid_module_name (const gchar *basename, + GIOModuleScope *scope) +{ + gboolean result; + +#if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN) + if (!g_str_has_prefix (basename, "lib") || + !g_str_has_suffix (basename, ".so")) + return FALSE; +#else + if (!g_str_has_suffix (basename, ".dll")) + return FALSE; +#endif + + result = TRUE; + if (scope) + { + result = _g_io_module_scope_contains (scope, basename) ? FALSE : TRUE; + if (result && (scope->flags & G_IO_MODULE_SCOPE_BLOCK_DUPLICATES)) + g_io_module_scope_block (scope, basename); + } + + return result; +} + + +/** + * g_io_modules_scan_all_in_directory_with_scope: + * @dirname: (type filename): pathname for a directory containing modules + * to scan. + * @scope: a scope to use when scanning the modules + * + * Scans all the modules in the specified directory, ensuring that + * any extension point implemented by a module is registered. + * + * This may not actually load and initialize all the types in each + * module, some modules may be lazily loaded and initialized when + * an extension point it implements is used with e.g. + * g_io_extension_point_get_extensions() or + * g_io_extension_point_get_extension_by_name(). + * + * If you need to guarantee that all types are loaded in all the modules, + * use g_io_modules_load_all_in_directory(). + * + * Since: 2.30 + **/ +void +g_io_modules_scan_all_in_directory_with_scope (const char *dirname, + GIOModuleScope *scope) +{ + const gchar *name; + char *filename; + GDir *dir; + GStatBuf statbuf; + char *data; + time_t cache_time; + GHashTable *cache; + + if (!g_module_supported ()) + return; + + dir = g_dir_open (dirname, 0, NULL); + if (!dir) + return; + + filename = g_build_filename (dirname, "giomodule.cache", NULL); + + cache = NULL; + cache_time = 0; + if (g_stat (filename, &statbuf) == 0 && + g_file_get_contents (filename, &data, NULL, NULL)) + { + char **lines; + int i; + + /* cache_time is the time the cache file was created; we also take + * into account the change time because in ostree based systems, all + * system file have mtime equal to epoch 0. + * + * Any file that has a ctime before this was created then and not modified + * since then (userspace can't change ctime). Its possible to change the + * ctime forward without changing the file content, by e.g. chmoding the + * file, but this is uncommon and will only cause us to not use the cache + * so will not cause bugs. + */ + cache_time = MAX(statbuf.st_mtime, statbuf.st_ctime); + + lines = g_strsplit (data, "\n", -1); + g_free (data); + + for (i = 0; lines[i] != NULL; i++) + { + char *line = lines[i]; + char *file; + char *colon; + char **extension_points; + + if (line[0] == '#') + continue; + + colon = strchr (line, ':'); + if (colon == NULL || line == colon) + continue; /* Invalid line, ignore */ + + *colon = 0; /* terminate filename */ + file = g_strdup (line); + colon++; /* after colon */ + + while (g_ascii_isspace (*colon)) + colon++; + + if (G_UNLIKELY (!cache)) + cache = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify)g_strfreev); + + extension_points = g_strsplit (colon, ",", -1); + g_hash_table_insert (cache, file, extension_points); + } + g_strfreev (lines); + } + + while ((name = g_dir_read_name (dir))) + { + if (is_valid_module_name (name, scope)) + { + GIOExtensionPoint *extension_point; + GIOModule *module; + gchar *path; + char **extension_points = NULL; + int i; + + path = g_build_filename (dirname, name, NULL); + module = g_io_module_new (path); + + if (cache) + extension_points = g_hash_table_lookup (cache, name); + + if (extension_points != NULL && + g_stat (path, &statbuf) == 0 && + statbuf.st_ctime <= cache_time) + { + /* Lazy load/init the library when first required */ + for (i = 0; extension_points[i] != NULL; i++) + { + extension_point = + g_io_extension_point_register (extension_points[i]); + extension_point->lazy_load_modules = + g_list_prepend (extension_point->lazy_load_modules, + module); + } + } + else + { + /* Try to load and init types */ + if (g_type_module_use (G_TYPE_MODULE (module))) + g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */ + else + { /* Failure to load */ + g_printerr ("Failed to load module: %s\n", path); + g_object_unref (module); + g_free (path); + continue; + } + } + + g_free (path); + } + } + + g_dir_close (dir); + + if (cache) + g_hash_table_destroy (cache); + + g_free (filename); +} + +/** + * g_io_modules_scan_all_in_directory: + * @dirname: (type filename): pathname for a directory containing modules + * to scan. + * + * Scans all the modules in the specified directory, ensuring that + * any extension point implemented by a module is registered. + * + * This may not actually load and initialize all the types in each + * module, some modules may be lazily loaded and initialized when + * an extension point it implements is used with e.g. + * g_io_extension_point_get_extensions() or + * g_io_extension_point_get_extension_by_name(). + * + * If you need to guarantee that all types are loaded in all the modules, + * use g_io_modules_load_all_in_directory(). + * + * Since: 2.24 + **/ +void +g_io_modules_scan_all_in_directory (const char *dirname) +{ + g_io_modules_scan_all_in_directory_with_scope (dirname, NULL); +} + +/** + * g_io_modules_load_all_in_directory_with_scope: + * @dirname: (type filename): pathname for a directory containing modules + * to load. + * @scope: a scope to use when scanning the modules. + * + * Loads all the modules in the specified directory. + * + * If don't require all modules to be initialized (and thus registering + * all gtypes) then you can use g_io_modules_scan_all_in_directory() + * which allows delayed/lazy loading of modules. + * + * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded + * from the directory, + * All the modules are loaded into memory, if you want to + * unload them (enabling on-demand loading) you must call + * g_type_module_unuse() on all the modules. Free the list + * with g_list_free(). + * + * Since: 2.30 + **/ +GList * +g_io_modules_load_all_in_directory_with_scope (const char *dirname, + GIOModuleScope *scope) +{ + const gchar *name; + GDir *dir; + GList *modules; + + if (!g_module_supported ()) + return NULL; + + dir = g_dir_open (dirname, 0, NULL); + if (!dir) + return NULL; + + modules = NULL; + while ((name = g_dir_read_name (dir))) + { + if (is_valid_module_name (name, scope)) + { + GIOModule *module; + gchar *path; + + path = g_build_filename (dirname, name, NULL); + module = g_io_module_new (path); + + if (!g_type_module_use (G_TYPE_MODULE (module))) + { + g_printerr ("Failed to load module: %s\n", path); + g_object_unref (module); + g_free (path); + continue; + } + + g_free (path); + + modules = g_list_prepend (modules, module); + } + } + + g_dir_close (dir); + + return modules; +} + +/** + * g_io_modules_load_all_in_directory: + * @dirname: (type filename): pathname for a directory containing modules + * to load. + * + * Loads all the modules in the specified directory. + * + * If don't require all modules to be initialized (and thus registering + * all gtypes) then you can use g_io_modules_scan_all_in_directory() + * which allows delayed/lazy loading of modules. + * + * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded + * from the directory, + * All the modules are loaded into memory, if you want to + * unload them (enabling on-demand loading) you must call + * g_type_module_unuse() on all the modules. Free the list + * with g_list_free(). + **/ +GList * +g_io_modules_load_all_in_directory (const char *dirname) +{ + return g_io_modules_load_all_in_directory_with_scope (dirname, NULL); +} + +static gpointer +try_class (GIOExtension *extension, + guint is_supported_offset) +{ + GType type = g_io_extension_get_type (extension); + typedef gboolean (*verify_func) (void); + gpointer class; + + class = g_type_class_ref (type); + if (!is_supported_offset || (* G_STRUCT_MEMBER(verify_func, class, is_supported_offset)) ()) + return class; + + g_type_class_unref (class); + return NULL; +} + +static void +print_help (const char *envvar, + GIOExtensionPoint *ep) +{ + g_print ("Supported arguments for %s environment variable:\n", envvar); + + if (g_io_extension_point_get_extensions (ep) == NULL) + g_print (" (none)\n"); + else + { + GList *l; + GIOExtension *extension; + gsize width = 0; + + for (l = g_io_extension_point_get_extensions (ep); l; l = l->next) + { + extension = l->data; + width = MAX (width, strlen (g_io_extension_get_name (extension))); + } + + for (l = g_io_extension_point_get_extensions (ep); l; l = l->next) + { + extension = l->data; + + g_print (" %*s - %d\n", (int) MIN (width, G_MAXINT), + g_io_extension_get_name (extension), + g_io_extension_get_priority (extension)); + } + } +} + +/** + * _g_io_module_get_default_type: + * @extension_point: the name of an extension point + * @envvar: (nullable): the name of an environment variable to + * override the default implementation. + * @is_supported_offset: a vtable offset, or zero + * + * Retrieves the default class implementing @extension_point. + * + * If @envvar is not %NULL, and the environment variable with that + * name is set, then the implementation it specifies will be tried + * first. After that, or if @envvar is not set, all other + * implementations will be tried in order of decreasing priority. + * + * If @is_supported_offset is non-zero, then it is the offset into the + * class vtable at which there is a function that takes no arguments and + * returns a boolean. This function will be called on each candidate + * implementation to check if it is actually usable or not. + * + * The result is cached after it is generated the first time, and + * the function is thread-safe. + * + * Returns: (transfer none): the type to instantiate to implement + * @extension_point, or %G_TYPE_INVALID if there are no usable + * implementations. + */ +GType +_g_io_module_get_default_type (const gchar *extension_point, + const gchar *envvar, + guint is_supported_offset) +{ + static GRecMutex default_modules_lock; + static GHashTable *default_modules; + const char *use_this; + GList *l; + GIOExtensionPoint *ep; + GIOExtension *extension, *preferred; + gpointer impl; + + g_rec_mutex_lock (&default_modules_lock); + if (default_modules) + { + gpointer key; + + if (g_hash_table_lookup_extended (default_modules, extension_point, &key, &impl)) + { + g_rec_mutex_unlock (&default_modules_lock); + return impl ? G_OBJECT_CLASS_TYPE (impl) : G_TYPE_INVALID; + } + } + else + { + default_modules = g_hash_table_new (g_str_hash, g_str_equal); + } + + _g_io_modules_ensure_loaded (); + ep = g_io_extension_point_lookup (extension_point); + + if (!ep) + { + g_warn_if_reached (); + g_rec_mutex_unlock (&default_modules_lock); + return G_TYPE_INVALID; + } + + /* It’s OK to query the environment here, even when running as setuid, because + * it only allows a choice between existing already-loaded modules. No new + * code is loaded based on the environment variable value. */ + use_this = envvar ? g_getenv (envvar) : NULL; + if (g_strcmp0 (use_this, "help") == 0) + { + print_help (envvar, ep); + use_this = NULL; + } + + if (use_this) + { + preferred = g_io_extension_point_get_extension_by_name (ep, use_this); + if (preferred) + { + impl = try_class (preferred, is_supported_offset); + if (impl) + goto done; + } + else + g_warning ("Can't find module '%s' specified in %s", use_this, envvar); + } + else + preferred = NULL; + + for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next) + { + extension = l->data; + if (extension == preferred) + continue; + + impl = try_class (extension, is_supported_offset); + if (impl) + goto done; + } + + impl = NULL; + + done: + g_hash_table_insert (default_modules, g_strdup (extension_point), impl); + g_rec_mutex_unlock (&default_modules_lock); + + return impl ? G_OBJECT_CLASS_TYPE (impl) : G_TYPE_INVALID; +} + +static gpointer +try_implementation (const char *extension_point, + GIOExtension *extension, + GIOModuleVerifyFunc verify_func) +{ + GType type = g_io_extension_get_type (extension); + gpointer impl; + + if (g_type_is_a (type, G_TYPE_INITABLE)) + { + GError *error = NULL; + + impl = g_initable_new (type, NULL, &error, NULL); + if (impl) + return impl; + + g_debug ("Failed to initialize %s (%s) for %s: %s", + g_io_extension_get_name (extension), + g_type_name (type), + extension_point, + error ? error->message : ""); + g_clear_error (&error); + return NULL; + } + else + { + impl = g_object_new (type, NULL); + if (!verify_func || verify_func (impl)) + return impl; + + g_object_unref (impl); + return NULL; + } +} + +static void +weak_ref_free (GWeakRef *weak_ref) +{ + g_weak_ref_clear (weak_ref); + g_free (weak_ref); +} + +/** + * _g_io_module_get_default: + * @extension_point: the name of an extension point + * @envvar: (nullable): the name of an environment variable to + * override the default implementation. + * @verify_func: (nullable): a function to call to verify that + * a given implementation is usable in the current environment. + * + * Retrieves the default object implementing @extension_point. + * + * If @envvar is not %NULL, and the environment variable with that + * name is set, then the implementation it specifies will be tried + * first. After that, or if @envvar is not set, all other + * implementations will be tried in order of decreasing priority. + * + * If an extension point implementation implements #GInitable, then + * that implementation will only be used if it initializes + * successfully. Otherwise, if @verify_func is not %NULL, then it will + * be called on each candidate implementation after construction, to + * check if it is actually usable or not. + * + * The result is cached after it is generated the first time (but the cache does + * not keep a strong reference to the object), and + * the function is thread-safe. + * + * Returns: (transfer full) (nullable): an object implementing + * @extension_point, or %NULL if there are no usable + * implementations. + */ +gpointer +_g_io_module_get_default (const gchar *extension_point, + const gchar *envvar, + GIOModuleVerifyFunc verify_func) +{ + static GRecMutex default_modules_lock; + static GHashTable *default_modules; + const char *use_this; + GList *l; + GIOExtensionPoint *ep; + GIOExtension *extension = NULL, *preferred; + gpointer impl, value; + GWeakRef *impl_weak_ref = NULL; + + g_rec_mutex_lock (&default_modules_lock); + if (default_modules) + { + if (g_hash_table_lookup_extended (default_modules, extension_point, + NULL, &value)) + { + /* Don’t debug here, since we’re returning a cached object which was + * already printed earlier. */ + impl_weak_ref = value; + impl = g_weak_ref_get (impl_weak_ref); + + /* If the object has been finalised (impl == NULL), fall through and + * instantiate a new one. */ + if (impl != NULL) + { + g_rec_mutex_unlock (&default_modules_lock); + return g_steal_pointer (&impl); + } + } + } + else + { + default_modules = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) weak_ref_free); + } + + _g_io_modules_ensure_loaded (); + ep = g_io_extension_point_lookup (extension_point); + + if (!ep) + { + g_debug ("%s: Failed to find extension point ‘%s’", + G_STRFUNC, extension_point); + g_warn_if_reached (); + g_rec_mutex_unlock (&default_modules_lock); + return NULL; + } + + /* It’s OK to query the environment here, even when running as setuid, because + * it only allows a choice between existing already-loaded modules. No new + * code is loaded based on the environment variable value. */ + use_this = envvar ? g_getenv (envvar) : NULL; + if (g_strcmp0 (use_this, "help") == 0) + { + print_help (envvar, ep); + use_this = NULL; + } + + if (use_this) + { + preferred = g_io_extension_point_get_extension_by_name (ep, use_this); + if (preferred) + { + impl = try_implementation (extension_point, preferred, verify_func); + extension = preferred; + if (impl) + goto done; + } + else + g_warning ("Can't find module '%s' specified in %s", use_this, envvar); + } + else + preferred = NULL; + + for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next) + { + extension = l->data; + if (extension == preferred) + continue; + + impl = try_implementation (extension_point, extension, verify_func); + if (impl) + goto done; + } + + impl = NULL; + + done: + if (impl_weak_ref == NULL) + { + impl_weak_ref = g_new0 (GWeakRef, 1); + g_weak_ref_init (impl_weak_ref, impl); + g_hash_table_insert (default_modules, g_strdup (extension_point), + g_steal_pointer (&impl_weak_ref)); + } + else + { + g_weak_ref_set (impl_weak_ref, impl); + } + + g_rec_mutex_unlock (&default_modules_lock); + + if (impl != NULL) + { + g_assert (extension != NULL); + g_debug ("%s: Found default implementation %s (%s) for ‘%s’", + G_STRFUNC, g_io_extension_get_name (extension), + G_OBJECT_TYPE_NAME (impl), extension_point); + } + else + g_debug ("%s: Failed to find default implementation for ‘%s’", + G_STRFUNC, extension_point); + + return g_steal_pointer (&impl); +} + +G_LOCK_DEFINE_STATIC (registered_extensions); +G_LOCK_DEFINE_STATIC (loaded_dirs); + +extern GType g_fen_file_monitor_get_type (void); +extern GType g_inotify_file_monitor_get_type (void); +extern GType g_kqueue_file_monitor_get_type (void); +extern GType g_win32_file_monitor_get_type (void); + +extern GType _g_unix_volume_monitor_get_type (void); +extern GType _g_local_vfs_get_type (void); + +extern GType _g_win32_volume_monitor_get_type (void); +extern GType _g_winhttp_vfs_get_type (void); + +extern GType _g_dummy_proxy_resolver_get_type (void); +extern GType _g_dummy_tls_backend_get_type (void); +extern GType g_network_monitor_base_get_type (void); +#ifdef HAVE_NETLINK +extern GType _g_network_monitor_netlink_get_type (void); +extern GType _g_network_monitor_nm_get_type (void); +#endif + +extern GType g_debug_controller_dbus_get_type (void); +extern GType g_memory_monitor_dbus_get_type (void); +extern GType g_memory_monitor_portal_get_type (void); +extern GType g_memory_monitor_win32_get_type (void); +extern GType g_power_profile_monitor_dbus_get_type (void); + +#ifdef G_OS_UNIX +extern GType g_fdo_notification_backend_get_type (void); +extern GType g_gtk_notification_backend_get_type (void); +extern GType g_portal_notification_backend_get_type (void); +extern GType g_proxy_resolver_portal_get_type (void); +extern GType g_network_monitor_portal_get_type (void); +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 +extern GType g_cocoa_notification_backend_get_type (void); +#endif + +#ifdef G_PLATFORM_WIN32 +extern GType g_win32_notification_backend_get_type (void); + +#include +extern GType _g_win32_network_monitor_get_type (void); + +static HMODULE gio_dll = NULL; + +#ifndef GLIB_STATIC_COMPILATION + +BOOL WINAPI DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved); + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_ATTACH) + { + gio_dll = hinstDLL; + gio_win32_appinfo_init (FALSE); + } + + return TRUE; +} + +#elif defined(G_HAS_CONSTRUCTORS) /* && G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION */ +extern void glib_win32_init (void); +extern void gobject_win32_init (void); + +#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(giomodule_init_ctor) +#endif + +G_DEFINE_CONSTRUCTOR (giomodule_init_ctor) + +static void +giomodule_init_ctor (void) +{ + /* When built dynamically, module initialization is done through DllMain + * function which is called when the dynamic library is loaded by the glib + * module AFTER loading gobject. So, in dynamic configuration glib and + * gobject are always initialized BEFORE gio. + * + * When built statically, initialization mechanism relies on hooking + * functions to the CRT section directly at compilation time. As we don't + * control how each compilation unit will be built and in which order, we + * obtain the same kind of issue as the "static initialization order fiasco". + * In this case, we must ensure explicitly that glib and gobject are always + * well initialized BEFORE gio. + */ + glib_win32_init (); + gobject_win32_init (); + gio_win32_appinfo_init (FALSE); +} + +#else /* G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION && !G_HAS_CONSTRUCTORS */ +#error Your platform/compiler is missing constructor support +#endif /* GLIB_STATIC_COMPILATION */ + +void * +_g_io_win32_get_module (void) +{ + if (!gio_dll) + GetModuleHandleExA (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (const char *) _g_io_win32_get_module, + &gio_dll); + return gio_dll; +} + +#endif /* G_PLATFORM_WIN32 */ + +void +_g_io_modules_ensure_extension_points_registered (void) +{ + static gboolean registered_extensions = FALSE; + GIOExtensionPoint *ep; + + G_LOCK (registered_extensions); + + if (!registered_extensions) + { + registered_extensions = TRUE; + +#if defined(G_OS_UNIX) && !defined(HAVE_COCOA) +#if !GLIB_CHECK_VERSION (3, 0, 0) + ep = g_io_extension_point_register (G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_DESKTOP_APP_INFO_LOOKUP); +#endif +#endif + + ep = g_io_extension_point_register (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR); + + ep = g_io_extension_point_register (G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR); + + ep = g_io_extension_point_register (G_VOLUME_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_VOLUME_MONITOR); + + ep = g_io_extension_point_register (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_NATIVE_VOLUME_MONITOR); + + ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_VFS); + + ep = g_io_extension_point_register ("gsettings-backend"); + g_io_extension_point_set_required_type (ep, G_TYPE_OBJECT); + + ep = g_io_extension_point_register (G_PROXY_RESOLVER_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_PROXY_RESOLVER); + + ep = g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_PROXY); + + ep = g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_TLS_BACKEND); + + ep = g_io_extension_point_register (G_NETWORK_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_NETWORK_MONITOR); + + ep = g_io_extension_point_register (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_NOTIFICATION_BACKEND); + + ep = g_io_extension_point_register (G_DEBUG_CONTROLLER_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_DEBUG_CONTROLLER); + + ep = g_io_extension_point_register (G_MEMORY_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_MEMORY_MONITOR); + + ep = g_io_extension_point_register (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_POWER_PROFILE_MONITOR); + } + + G_UNLOCK (registered_extensions); +} + +static gchar * +get_gio_module_dir (void) +{ + gchar *module_dir; + gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) (); + + /* If running as setuid, loading modules from an arbitrary directory + * controlled by the unprivileged user who is running the program could allow + * for execution of arbitrary code (in constructors in modules). + * Don’t allow it. + * + * If a setuid program somehow needs to load additional GIO modules, it should + * explicitly call g_io_modules_scan_all_in_directory(). */ + module_dir = !is_setuid ? g_strdup (g_getenv ("GIO_MODULE_DIR")) : NULL; + if (module_dir == NULL) + { +#ifdef G_OS_WIN32 + gchar *install_dir; + + install_dir = g_win32_get_package_installation_directory_of_module (gio_dll); + module_dir = g_build_filename (install_dir, + "lib", "gio", "modules", + NULL); + g_free (install_dir); +#else + module_dir = g_strdup (GIO_MODULE_DIR); +#endif + } + + return module_dir; +} + +void +_g_io_modules_ensure_loaded (void) +{ + static gboolean loaded_dirs = FALSE; + const char *module_path; + GIOModuleScope *scope; + + _g_io_modules_ensure_extension_points_registered (); + + G_LOCK (loaded_dirs); + + if (!loaded_dirs) + { + gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) (); + gchar *module_dir; + + loaded_dirs = TRUE; + scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES); + + /* First load any overrides, extras (but not if running as setuid!) */ + module_path = !is_setuid ? g_getenv ("GIO_EXTRA_MODULES") : NULL; + if (module_path) + { + gchar **paths; + int i; + + paths = g_strsplit (module_path, G_SEARCHPATH_SEPARATOR_S, 0); + + for (i = 0; paths[i] != NULL; i++) + { + g_io_modules_scan_all_in_directory_with_scope (paths[i], scope); + } + + g_strfreev (paths); + } + + /* Then load the compiled in path */ + module_dir = get_gio_module_dir (); + + g_io_modules_scan_all_in_directory_with_scope (module_dir, scope); + g_free (module_dir); + + g_io_module_scope_free (scope); + + /* Initialize types from built-in "modules" */ + g_type_ensure (g_null_settings_backend_get_type ()); + g_type_ensure (g_memory_settings_backend_get_type ()); + g_type_ensure (g_keyfile_settings_backend_get_type ()); + g_type_ensure (g_power_profile_monitor_dbus_get_type ()); +#if defined(HAVE_INOTIFY_INIT1) + g_type_ensure (g_inotify_file_monitor_get_type ()); +#endif +#if defined(HAVE_KQUEUE) + g_type_ensure (g_kqueue_file_monitor_get_type ()); +#endif +#if defined(HAVE_FEN) + g_type_ensure (g_fen_file_monitor_get_type ()); +#endif +#ifdef G_OS_WIN32 + g_type_ensure (_g_win32_volume_monitor_get_type ()); + g_type_ensure (g_win32_file_monitor_get_type ()); + g_type_ensure (g_registry_backend_get_type ()); +#endif +#ifdef HAVE_COCOA + g_type_ensure (g_nextstep_settings_backend_get_type ()); + g_type_ensure (g_osx_app_info_get_type ()); +#endif +#ifdef G_OS_UNIX + g_type_ensure (_g_unix_volume_monitor_get_type ()); + g_type_ensure (g_debug_controller_dbus_get_type ()); + g_type_ensure (g_fdo_notification_backend_get_type ()); + g_type_ensure (g_gtk_notification_backend_get_type ()); + g_type_ensure (g_portal_notification_backend_get_type ()); + g_type_ensure (g_memory_monitor_dbus_get_type ()); + g_type_ensure (g_memory_monitor_portal_get_type ()); + g_type_ensure (g_network_monitor_portal_get_type ()); + g_type_ensure (g_power_profile_monitor_portal_get_type ()); + g_type_ensure (g_proxy_resolver_portal_get_type ()); +#endif +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + g_type_ensure (g_cocoa_notification_backend_get_type ()); +#endif +#ifdef G_OS_WIN32 + g_type_ensure (g_win32_notification_backend_get_type ()); + g_type_ensure (_g_winhttp_vfs_get_type ()); + g_type_ensure (g_memory_monitor_win32_get_type ()); +#endif + g_type_ensure (_g_local_vfs_get_type ()); + g_type_ensure (_g_dummy_proxy_resolver_get_type ()); + g_type_ensure (_g_http_proxy_get_type ()); + g_type_ensure (_g_https_proxy_get_type ()); + g_type_ensure (_g_socks4a_proxy_get_type ()); + g_type_ensure (_g_socks4_proxy_get_type ()); + g_type_ensure (_g_socks5_proxy_get_type ()); + g_type_ensure (_g_dummy_tls_backend_get_type ()); + g_type_ensure (g_network_monitor_base_get_type ()); +#ifdef HAVE_NETLINK + g_type_ensure (_g_network_monitor_netlink_get_type ()); + g_type_ensure (_g_network_monitor_nm_get_type ()); +#endif +#ifdef G_OS_WIN32 + g_type_ensure (_g_win32_network_monitor_get_type ()); +#endif + } + + G_UNLOCK (loaded_dirs); +} + +static void +g_io_extension_point_free (GIOExtensionPoint *ep) +{ + g_free (ep->name); + g_free (ep); +} + +/** + * g_io_extension_point_register: + * @name: The name of the extension point + * + * Registers an extension point. + * + * Returns: (transfer none): the new #GIOExtensionPoint. This object is + * owned by GIO and should not be freed. + */ +GIOExtensionPoint * +g_io_extension_point_register (const char *name) +{ + GIOExtensionPoint *ep; + + G_LOCK (extension_points); + if (extension_points == NULL) + extension_points = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify)g_io_extension_point_free); + + ep = g_hash_table_lookup (extension_points, name); + if (ep != NULL) + { + G_UNLOCK (extension_points); + return ep; + } + + ep = g_new0 (GIOExtensionPoint, 1); + ep->name = g_strdup (name); + + g_hash_table_insert (extension_points, ep->name, ep); + + G_UNLOCK (extension_points); + + return ep; +} + +/** + * g_io_extension_point_lookup: + * @name: the name of the extension point + * + * Looks up an existing extension point. + * + * Returns: (transfer none): the #GIOExtensionPoint, or %NULL if there + * is no registered extension point with the given name. + */ +GIOExtensionPoint * +g_io_extension_point_lookup (const char *name) +{ + GIOExtensionPoint *ep; + + G_LOCK (extension_points); + ep = NULL; + if (extension_points != NULL) + ep = g_hash_table_lookup (extension_points, name); + + G_UNLOCK (extension_points); + + return ep; + +} + +/** + * g_io_extension_point_set_required_type: + * @extension_point: a #GIOExtensionPoint + * @type: the #GType to require + * + * Sets the required type for @extension_point to @type. + * All implementations must henceforth have this type. + */ +void +g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point, + GType type) +{ + extension_point->required_type = type; +} + +/** + * g_io_extension_point_get_required_type: + * @extension_point: a #GIOExtensionPoint + * + * Gets the required type for @extension_point. + * + * Returns: the #GType that all implementations must have, + * or %G_TYPE_INVALID if the extension point has no required type + */ +GType +g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point) +{ + return extension_point->required_type; +} + +static void +lazy_load_modules (GIOExtensionPoint *extension_point) +{ + GIOModule *module; + GList *l; + + for (l = extension_point->lazy_load_modules; l != NULL; l = l->next) + { + module = l->data; + + if (!module->initialized) + { + if (g_type_module_use (G_TYPE_MODULE (module))) + g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */ + else + g_printerr ("Failed to load module: %s\n", + module->filename); + } + } +} + +/** + * g_io_extension_point_get_extensions: + * @extension_point: a #GIOExtensionPoint + * + * Gets a list of all extensions that implement this extension point. + * The list is sorted by priority, beginning with the highest priority. + * + * Returns: (element-type GIOExtension) (transfer none): a #GList of + * #GIOExtensions. The list is owned by GIO and should not be + * modified. + */ +GList * +g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point) +{ + g_return_val_if_fail (extension_point != NULL, NULL); + + lazy_load_modules (extension_point); + return extension_point->extensions; +} + +/** + * g_io_extension_point_get_extension_by_name: + * @extension_point: a #GIOExtensionPoint + * @name: the name of the extension to get + * + * Finds a #GIOExtension for an extension point by name. + * + * Returns: (transfer none): the #GIOExtension for @extension_point that has the + * given name, or %NULL if there is no extension with that name + */ +GIOExtension * +g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point, + const char *name) +{ + GList *l; + + g_return_val_if_fail (name != NULL, NULL); + + lazy_load_modules (extension_point); + for (l = extension_point->extensions; l != NULL; l = l->next) + { + GIOExtension *e = l->data; + + if (e->name != NULL && + strcmp (e->name, name) == 0) + return e; + } + + return NULL; +} + +static gint +extension_prio_compare (gconstpointer a, + gconstpointer b) +{ + const GIOExtension *extension_a = a, *extension_b = b; + + if (extension_a->priority > extension_b->priority) + return -1; + + if (extension_b->priority > extension_a->priority) + return 1; + + return 0; +} + +/** + * g_io_extension_point_implement: + * @extension_point_name: the name of the extension point + * @type: the #GType to register as extension + * @extension_name: the name for the extension + * @priority: the priority for the extension + * + * Registers @type as extension for the extension point with name + * @extension_point_name. + * + * If @type has already been registered as an extension for this + * extension point, the existing #GIOExtension object is returned. + * + * Returns: (transfer none): a #GIOExtension object for #GType + */ +GIOExtension * +g_io_extension_point_implement (const char *extension_point_name, + GType type, + const char *extension_name, + gint priority) +{ + GIOExtensionPoint *extension_point; + GIOExtension *extension; + GList *l; + + g_return_val_if_fail (extension_point_name != NULL, NULL); + + extension_point = g_io_extension_point_lookup (extension_point_name); + if (extension_point == NULL) + { + g_warning ("Tried to implement non-registered extension point %s", extension_point_name); + return NULL; + } + + if (extension_point->required_type != 0 && + !g_type_is_a (type, extension_point->required_type)) + { + g_warning ("Tried to register an extension of the type %s to extension point %s. " + "Expected type is %s.", + g_type_name (type), + extension_point_name, + g_type_name (extension_point->required_type)); + return NULL; + } + + /* It's safe to register the same type multiple times */ + for (l = extension_point->extensions; l != NULL; l = l->next) + { + extension = l->data; + if (extension->type == type) + return extension; + } + + extension = g_slice_new0 (GIOExtension); + extension->type = type; + extension->name = g_strdup (extension_name); + extension->priority = priority; + + extension_point->extensions = g_list_insert_sorted (extension_point->extensions, + extension, extension_prio_compare); + + return extension; +} + +/** + * g_io_extension_ref_class: + * @extension: a #GIOExtension + * + * Gets a reference to the class for the type that is + * associated with @extension. + * + * Returns: (transfer full): the #GTypeClass for the type of @extension + */ +GTypeClass * +g_io_extension_ref_class (GIOExtension *extension) +{ + return g_type_class_ref (extension->type); +} + +/** + * g_io_extension_get_type: + * @extension: a #GIOExtension + * + * Gets the type associated with @extension. + * + * Returns: the type of @extension + */ +GType +g_io_extension_get_type (GIOExtension *extension) +{ + return extension->type; +} + +/** + * g_io_extension_get_name: + * @extension: a #GIOExtension + * + * Gets the name under which @extension was registered. + * + * Note that the same type may be registered as extension + * for multiple extension points, under different names. + * + * Returns: the name of @extension. + */ +const char * +g_io_extension_get_name (GIOExtension *extension) +{ + return extension->name; +} + +/** + * g_io_extension_get_priority: + * @extension: a #GIOExtension + * + * Gets the priority with which @extension was registered. + * + * Returns: the priority of @extension + */ +gint +g_io_extension_get_priority (GIOExtension *extension) +{ + return extension->priority; +} diff --git a/gio/giomodule.h b/gio/giomodule.h new file mode 100644 index 0000000..4457c49 --- /dev/null +++ b/gio/giomodule.h @@ -0,0 +1,193 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_IO_MODULE_H__ +#define __G_IO_MODULE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GIOModuleScope GIOModuleScope; + +GLIB_AVAILABLE_IN_2_30 +GIOModuleScope * g_io_module_scope_new (GIOModuleScopeFlags flags); +GLIB_AVAILABLE_IN_2_30 +void g_io_module_scope_free (GIOModuleScope *scope); +GLIB_AVAILABLE_IN_2_30 +void g_io_module_scope_block (GIOModuleScope *scope, + const gchar *basename); + +#define G_IO_TYPE_MODULE (g_io_module_get_type ()) +#define G_IO_MODULE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_IO_TYPE_MODULE, GIOModule)) +#define G_IO_MODULE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_IO_TYPE_MODULE, GIOModuleClass)) +#define G_IO_IS_MODULE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_IO_TYPE_MODULE)) +#define G_IO_IS_MODULE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_IO_TYPE_MODULE)) +#define G_IO_MODULE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_IO_TYPE_MODULE, GIOModuleClass)) + +/** + * GIOModule: + * + * Opaque module base class for extending GIO. + **/ +typedef struct _GIOModuleClass GIOModuleClass; + +GLIB_AVAILABLE_IN_ALL +GType g_io_module_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GIOModule *g_io_module_new (const gchar *filename); + +GLIB_AVAILABLE_IN_ALL +void g_io_modules_scan_all_in_directory (const char *dirname); +GLIB_AVAILABLE_IN_ALL +GList *g_io_modules_load_all_in_directory (const gchar *dirname); + +GLIB_AVAILABLE_IN_2_30 +void g_io_modules_scan_all_in_directory_with_scope (const gchar *dirname, + GIOModuleScope *scope); +GLIB_AVAILABLE_IN_2_30 +GList *g_io_modules_load_all_in_directory_with_scope (const gchar *dirname, + GIOModuleScope *scope); + +GLIB_AVAILABLE_IN_ALL +GIOExtensionPoint *g_io_extension_point_register (const char *name); +GLIB_AVAILABLE_IN_ALL +GIOExtensionPoint *g_io_extension_point_lookup (const char *name); +GLIB_AVAILABLE_IN_ALL +void g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point, + GType type); +GLIB_AVAILABLE_IN_ALL +GType g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point); +GLIB_AVAILABLE_IN_ALL +GList *g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point); +GLIB_AVAILABLE_IN_ALL +GIOExtension * g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point, + const char *name); +GLIB_AVAILABLE_IN_ALL +GIOExtension * g_io_extension_point_implement (const char *extension_point_name, + GType type, + const char *extension_name, + gint priority); + +GLIB_AVAILABLE_IN_ALL +GType g_io_extension_get_type (GIOExtension *extension); +GLIB_AVAILABLE_IN_ALL +const char * g_io_extension_get_name (GIOExtension *extension); +GLIB_AVAILABLE_IN_ALL +gint g_io_extension_get_priority (GIOExtension *extension); +GLIB_AVAILABLE_IN_ALL +GTypeClass* g_io_extension_ref_class (GIOExtension *extension); + + +/* API for the modules to implement */ + +/** + * g_io_module_load: (skip) + * @module: a #GIOModule. + * + * Required API for GIO modules to implement. + * + * This function is run after the module has been loaded into GIO, + * to initialize the module. Typically, this function will call + * g_io_extension_point_implement(). + * + * Since 2.56, this function should be named `g_io__load`, where + * `modulename` is the plugin’s filename with the `lib` or `libgio` prefix and + * everything after the first dot removed, and with `-` replaced with `_` + * throughout. For example, `libgiognutls-helper.so` becomes `gnutls_helper`. + * Using the new symbol names avoids name clashes when building modules + * statically. The old symbol names continue to be supported, but cannot be used + * for static builds. + **/ +GLIB_AVAILABLE_IN_ALL +void g_io_module_load (GIOModule *module); + +/** + * g_io_module_unload: (skip) + * @module: a #GIOModule. + * + * Required API for GIO modules to implement. + * + * This function is run when the module is being unloaded from GIO, + * to finalize the module. + * + * Since 2.56, this function should be named `g_io__unload`, where + * `modulename` is the plugin’s filename with the `lib` or `libgio` prefix and + * everything after the first dot removed, and with `-` replaced with `_` + * throughout. For example, `libgiognutls-helper.so` becomes `gnutls_helper`. + * Using the new symbol names avoids name clashes when building modules + * statically. The old symbol names continue to be supported, but cannot be used + * for static builds. + **/ +GLIB_AVAILABLE_IN_ALL +void g_io_module_unload (GIOModule *module); + +/** + * g_io_module_query: + * + * Optional API for GIO modules to implement. + * + * Should return a list of all the extension points that may be + * implemented in this module. + * + * This method will not be called in normal use, however it may be + * called when probing existing modules and recording which extension + * points that this model is used for. This means we won't have to + * load and initialize this module unless its needed. + * + * If this function is not implemented by the module the module will + * always be loaded, initialized and then unloaded on application + * startup so that it can register its extension points during init. + * + * Note that a module need not actually implement all the extension + * points that g_io_module_query() returns, since the exact list of + * extension may depend on runtime issues. However all extension + * points actually implemented must be returned by g_io_module_query() + * (if defined). + * + * When installing a module that implements g_io_module_query() you must + * run gio-querymodules in order to build the cache files required for + * lazy loading. + * + * Since 2.56, this function should be named `g_io__query`, where + * `modulename` is the plugin’s filename with the `lib` or `libgio` prefix and + * everything after the first dot removed, and with `-` replaced with `_` + * throughout. For example, `libgiognutls-helper.so` becomes `gnutls_helper`. + * Using the new symbol names avoids name clashes when building modules + * statically. The old symbol names continue to be supported, but cannot be used + * for static builds. + * + * Returns: (transfer full): A %NULL-terminated array of strings, + * listing the supported extension points of the module. The array + * must be suitable for freeing with g_strfreev(). + * + * Since: 2.24 + **/ +GLIB_AVAILABLE_IN_ALL +char **g_io_module_query (void); + +G_END_DECLS + +#endif /* __G_IO_MODULE_H__ */ diff --git a/gio/gioprivate.h b/gio/gioprivate.h new file mode 100644 index 0000000..608d912 --- /dev/null +++ b/gio/gioprivate.h @@ -0,0 +1,62 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2013 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_IO_PRIVATE_H__ +#define __G_IO_PRIVATE_H__ + +#include "ginputstream.h" +#include "goutputstream.h" +#include "gsocketconnection.h" +#include "gsocketaddress.h" + +G_BEGIN_DECLS + +gboolean g_input_stream_async_read_is_via_threads (GInputStream *stream); +gboolean g_input_stream_async_close_is_via_threads (GInputStream *stream); +gboolean g_output_stream_async_write_is_via_threads (GOutputStream *stream); +gboolean g_output_stream_async_writev_is_via_threads (GOutputStream *stream); +gboolean g_output_stream_async_close_is_via_threads (GOutputStream *stream); + +void g_socket_connection_set_cached_remote_address (GSocketConnection *connection, + GSocketAddress *address); + +/* POSIX defines IOV_MAX/UIO_MAXIOV as the maximum number of iovecs that can + * be sent in one go. We define our own version of it here as there are two + * possible names, and also define a fall-back value if none of the constants + * are defined */ +#if defined(IOV_MAX) +#define G_IOV_MAX IOV_MAX +#elif defined(UIO_MAXIOV) +#define G_IOV_MAX UIO_MAXIOV +#elif defined(__APPLE__) +/* For macOS/iOS, UIO_MAXIOV is documented in writev(2), but + * only declares it if defined(KERNEL) */ +#define G_IOV_MAX 512 +#else +/* 16 is the minimum value required by POSIX */ +#define G_IOV_MAX 16 +#endif + +/* The various functions taking iovecs as parameter use a plain int + * for the number of vectors. Limit it to G_MAXINT for this reason. + */ +G_STATIC_ASSERT (G_IOV_MAX <= G_MAXINT); + +G_END_DECLS + +#endif /* __G_IO_PRIVATE__ */ diff --git a/gio/gioscheduler.c b/gio/gioscheduler.c new file mode 100644 index 0000000..0367ede --- /dev/null +++ b/gio/gioscheduler.c @@ -0,0 +1,325 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gioscheduler.h" +#include "gcancellable.h" +#include "gtask.h" + +/** + * SECTION:gioscheduler + * @short_description: I/O Scheduler + * @include: gio/gio.h + * + * As of GLib 2.36, #GIOScheduler is deprecated in favor of + * #GThreadPool and #GTask. + * + * Schedules asynchronous I/O operations. #GIOScheduler integrates + * into the main event loop (#GMainLoop) and uses threads. + */ + +struct _GIOSchedulerJob { + GList *active_link; + GTask *task; + + GIOSchedulerJobFunc job_func; + gpointer data; + GDestroyNotify destroy_notify; + + GCancellable *cancellable; + gulong cancellable_id; + GMainContext *context; +}; + +G_LOCK_DEFINE_STATIC(active_jobs); +static GList *active_jobs = NULL; + +static void +g_io_job_free (GIOSchedulerJob *job) +{ + if (job->destroy_notify) + job->destroy_notify (job->data); + + G_LOCK (active_jobs); + active_jobs = g_list_delete_link (active_jobs, job->active_link); + G_UNLOCK (active_jobs); + + if (job->cancellable) + g_object_unref (job->cancellable); + g_main_context_unref (job->context); + g_slice_free (GIOSchedulerJob, job); +} + +static void +io_job_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GIOSchedulerJob *job = task_data; + gboolean result; + + if (job->cancellable) + g_cancellable_push_current (job->cancellable); + + do + { + result = job->job_func (job, job->cancellable, job->data); + } + while (result); + + if (job->cancellable) + g_cancellable_pop_current (job->cancellable); +} + +/** + * g_io_scheduler_push_job: + * @job_func: a #GIOSchedulerJobFunc. + * @user_data: data to pass to @job_func + * @notify: (nullable): a #GDestroyNotify for @user_data, or %NULL + * @io_priority: the [I/O priority][io-priority] + * of the request. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * + * Schedules the I/O job to run in another thread. + * + * @notify will be called on @user_data after @job_func has returned, + * regardless whether the job was cancelled or has run to completion. + * + * If @cancellable is not %NULL, it can be used to cancel the I/O job + * by calling g_cancellable_cancel() or by calling + * g_io_scheduler_cancel_all_jobs(). + * + * Deprecated: use #GThreadPool or g_task_run_in_thread() + **/ +void +g_io_scheduler_push_job (GIOSchedulerJobFunc job_func, + gpointer user_data, + GDestroyNotify notify, + gint io_priority, + GCancellable *cancellable) +{ + GIOSchedulerJob *job; + GTask *task; + + g_return_if_fail (job_func != NULL); + + job = g_slice_new0 (GIOSchedulerJob); + job->job_func = job_func; + job->data = user_data; + job->destroy_notify = notify; + + if (cancellable) + job->cancellable = g_object_ref (cancellable); + + job->context = g_main_context_ref_thread_default (); + + G_LOCK (active_jobs); + active_jobs = g_list_prepend (active_jobs, job); + job->active_link = active_jobs; + G_UNLOCK (active_jobs); + + task = g_task_new (NULL, cancellable, NULL, NULL); +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_task_set_source_tag (task, g_io_scheduler_push_job); +G_GNUC_END_IGNORE_DEPRECATIONS + g_task_set_task_data (task, job, (GDestroyNotify)g_io_job_free); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, io_job_thread); + g_object_unref (task); +} + +/** + * g_io_scheduler_cancel_all_jobs: + * + * Cancels all cancellable I/O jobs. + * + * A job is cancellable if a #GCancellable was passed into + * g_io_scheduler_push_job(). + * + * Deprecated: You should never call this function, since you don't + * know how other libraries in your program might be making use of + * gioscheduler. + **/ +void +g_io_scheduler_cancel_all_jobs (void) +{ + GList *cancellable_list, *l; + + G_LOCK (active_jobs); + cancellable_list = NULL; + for (l = active_jobs; l != NULL; l = l->next) + { + GIOSchedulerJob *job = l->data; + if (job->cancellable) + cancellable_list = g_list_prepend (cancellable_list, + g_object_ref (job->cancellable)); + } + G_UNLOCK (active_jobs); + + for (l = cancellable_list; l != NULL; l = l->next) + { + GCancellable *c = l->data; + g_cancellable_cancel (c); + g_object_unref (c); + } + g_list_free (cancellable_list); +} + +typedef struct { + GSourceFunc func; + gboolean ret_val; + gpointer data; + GDestroyNotify notify; + + GMutex ack_lock; + GCond ack_condition; + gboolean ack; +} MainLoopProxy; + +static gboolean +mainloop_proxy_func (gpointer data) +{ + MainLoopProxy *proxy = data; + + proxy->ret_val = proxy->func (proxy->data); + + if (proxy->notify) + proxy->notify (proxy->data); + + g_mutex_lock (&proxy->ack_lock); + proxy->ack = TRUE; + g_cond_signal (&proxy->ack_condition); + g_mutex_unlock (&proxy->ack_lock); + + return FALSE; +} + +static void +mainloop_proxy_free (MainLoopProxy *proxy) +{ + g_mutex_clear (&proxy->ack_lock); + g_cond_clear (&proxy->ack_condition); + g_free (proxy); +} + +/** + * g_io_scheduler_job_send_to_mainloop: + * @job: a #GIOSchedulerJob + * @func: a #GSourceFunc callback that will be called in the original thread + * @user_data: data to pass to @func + * @notify: (nullable): a #GDestroyNotify for @user_data, or %NULL + * + * Used from an I/O job to send a callback to be run in the thread + * that the job was started from, waiting for the result (and thus + * blocking the I/O job). + * + * Returns: The return value of @func + * + * Deprecated: Use g_main_context_invoke(). + **/ +gboolean +g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job, + GSourceFunc func, + gpointer user_data, + GDestroyNotify notify) +{ + GSource *source; + MainLoopProxy *proxy; + gboolean ret_val; + + g_return_val_if_fail (job != NULL, FALSE); + g_return_val_if_fail (func != NULL, FALSE); + + proxy = g_new0 (MainLoopProxy, 1); + proxy->func = func; + proxy->data = user_data; + proxy->notify = notify; + g_mutex_init (&proxy->ack_lock); + g_cond_init (&proxy->ack_condition); + g_mutex_lock (&proxy->ack_lock); + + source = g_idle_source_new (); + g_source_set_priority (source, G_PRIORITY_DEFAULT); + g_source_set_callback (source, mainloop_proxy_func, proxy, + NULL); + g_source_set_static_name (source, "[gio] mainloop_proxy_func"); + + g_source_attach (source, job->context); + g_source_unref (source); + + while (!proxy->ack) + g_cond_wait (&proxy->ack_condition, &proxy->ack_lock); + g_mutex_unlock (&proxy->ack_lock); + + ret_val = proxy->ret_val; + mainloop_proxy_free (proxy); + + return ret_val; +} + +/** + * g_io_scheduler_job_send_to_mainloop_async: + * @job: a #GIOSchedulerJob + * @func: a #GSourceFunc callback that will be called in the original thread + * @user_data: data to pass to @func + * @notify: (nullable): a #GDestroyNotify for @user_data, or %NULL + * + * Used from an I/O job to send a callback to be run asynchronously in + * the thread that the job was started from. The callback will be run + * when the main loop is available, but at that time the I/O job might + * have finished. The return value from the callback is ignored. + * + * Note that if you are passing the @user_data from g_io_scheduler_push_job() + * on to this function you have to ensure that it is not freed before + * @func is called, either by passing %NULL as @notify to + * g_io_scheduler_push_job() or by using refcounting for @user_data. + * + * Deprecated: Use g_main_context_invoke(). + **/ +void +g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job, + GSourceFunc func, + gpointer user_data, + GDestroyNotify notify) +{ + GSource *source; + MainLoopProxy *proxy; + + g_return_if_fail (job != NULL); + g_return_if_fail (func != NULL); + + proxy = g_new0 (MainLoopProxy, 1); + proxy->func = func; + proxy->data = user_data; + proxy->notify = notify; + g_mutex_init (&proxy->ack_lock); + g_cond_init (&proxy->ack_condition); + + source = g_idle_source_new (); + g_source_set_priority (source, G_PRIORITY_DEFAULT); + g_source_set_callback (source, mainloop_proxy_func, proxy, + (GDestroyNotify)mainloop_proxy_free); + g_source_set_static_name (source, "[gio] mainloop_proxy_func"); + + g_source_attach (source, job->context); + g_source_unref (source); +} diff --git a/gio/gioscheduler.h b/gio/gioscheduler.h new file mode 100644 index 0000000..d58cff6 --- /dev/null +++ b/gio/gioscheduler.h @@ -0,0 +1,54 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_IO_SCHEDULER_H__ +#define __G_IO_SCHEDULER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + + +GLIB_DEPRECATED_IN_2_36_FOR ("GThreadPool or g_task_run_in_thread") +void g_io_scheduler_push_job (GIOSchedulerJobFunc job_func, + gpointer user_data, + GDestroyNotify notify, + gint io_priority, + GCancellable *cancellable); +GLIB_DEPRECATED_IN_2_36 +void g_io_scheduler_cancel_all_jobs (void); +GLIB_DEPRECATED_IN_2_36_FOR (g_main_context_invoke) +gboolean g_io_scheduler_job_send_to_mainloop (GIOSchedulerJob *job, + GSourceFunc func, + gpointer user_data, + GDestroyNotify notify); +GLIB_DEPRECATED_IN_2_36_FOR (g_main_context_invoke) +void g_io_scheduler_job_send_to_mainloop_async (GIOSchedulerJob *job, + GSourceFunc func, + gpointer user_data, + GDestroyNotify notify); + +G_END_DECLS + +#endif /* __G_IO_SCHEDULER_H__ */ diff --git a/gio/giostream.c b/gio/giostream.c new file mode 100644 index 0000000..f708e77 --- /dev/null +++ b/gio/giostream.c @@ -0,0 +1,920 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008 codethink + * Copyright © 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Alexander Larsson + */ + +#include "config.h" +#include +#include "glibintl.h" + +#include "giostream.h" +#include "gasyncresult.h" +#include "gioprivate.h" +#include "gtask.h" + +/** + * SECTION:giostream + * @short_description: Base class for implementing read/write streams + * @include: gio/gio.h + * @see_also: #GInputStream, #GOutputStream + * + * GIOStream represents an object that has both read and write streams. + * Generally the two streams act as separate input and output streams, + * but they share some common resources and state. For instance, for + * seekable streams, both streams may use the same position. + * + * Examples of #GIOStream objects are #GSocketConnection, which represents + * a two-way network connection; and #GFileIOStream, which represents a + * file handle opened in read-write mode. + * + * To do the actual reading and writing you need to get the substreams + * with g_io_stream_get_input_stream() and g_io_stream_get_output_stream(). + * + * The #GIOStream object owns the input and the output streams, not the other + * way around, so keeping the substreams alive will not keep the #GIOStream + * object alive. If the #GIOStream object is freed it will be closed, thus + * closing the substreams, so even if the substreams stay alive they will + * always return %G_IO_ERROR_CLOSED for all operations. + * + * To close a stream use g_io_stream_close() which will close the common + * stream object and also the individual substreams. You can also close + * the substreams themselves. In most cases this only marks the + * substream as closed, so further I/O on it fails but common state in the + * #GIOStream may still be open. However, some streams may support + * "half-closed" states where one direction of the stream is actually shut down. + * + * Operations on #GIOStreams cannot be started while another operation on the + * #GIOStream or its substreams is in progress. Specifically, an application can + * read from the #GInputStream and write to the #GOutputStream simultaneously + * (either in separate threads, or as asynchronous operations in the same + * thread), but an application cannot start any #GIOStream operation while there + * is a #GIOStream, #GInputStream or #GOutputStream operation in progress, and + * an application can’t start any #GInputStream or #GOutputStream operation + * while there is a #GIOStream operation in progress. + * + * This is a product of individual stream operations being associated with a + * given #GMainContext (the thread-default context at the time the operation was + * started), rather than entire streams being associated with a single + * #GMainContext. + * + * GIO may run operations on #GIOStreams from other (worker) threads, and this + * may be exposed to application code in the behaviour of wrapper streams, such + * as #GBufferedInputStream or #GTlsConnection. With such wrapper APIs, + * application code may only run operations on the base (wrapped) stream when + * the wrapper stream is idle. Note that the semantics of such operations may + * not be well-defined due to the state the wrapper stream leaves the base + * stream in (though they are guaranteed not to crash). + * + * Since: 2.22 + */ + +enum +{ + PROP_0, + PROP_INPUT_STREAM, + PROP_OUTPUT_STREAM, + PROP_CLOSED +}; + +struct _GIOStreamPrivate { + guint closed : 1; + guint pending : 1; +}; + +static gboolean g_io_stream_real_close (GIOStream *stream, + GCancellable *cancellable, + GError **error); +static void g_io_stream_real_close_async (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_io_stream_real_close_finish (GIOStream *stream, + GAsyncResult *result, + GError **error); + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GIOStream, g_io_stream, G_TYPE_OBJECT) + +static void +g_io_stream_dispose (GObject *object) +{ + GIOStream *stream; + + stream = G_IO_STREAM (object); + + if (!stream->priv->closed) + g_io_stream_close (stream, NULL, NULL); + + G_OBJECT_CLASS (g_io_stream_parent_class)->dispose (object); +} + +static void +g_io_stream_init (GIOStream *stream) +{ + stream->priv = g_io_stream_get_instance_private (stream); +} + +static void +g_io_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GIOStream *stream = G_IO_STREAM (object); + + switch (prop_id) + { + case PROP_CLOSED: + g_value_set_boolean (value, stream->priv->closed); + break; + + case PROP_INPUT_STREAM: + g_value_set_object (value, g_io_stream_get_input_stream (stream)); + break; + + case PROP_OUTPUT_STREAM: + g_value_set_object (value, g_io_stream_get_output_stream (stream)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_io_stream_class_init (GIOStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_io_stream_dispose; + gobject_class->get_property = g_io_stream_get_property; + + klass->close_fn = g_io_stream_real_close; + klass->close_async = g_io_stream_real_close_async; + klass->close_finish = g_io_stream_real_close_finish; + + g_object_class_install_property (gobject_class, PROP_CLOSED, + g_param_spec_boolean ("closed", + P_("Closed"), + P_("Is the stream closed"), + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_INPUT_STREAM, + g_param_spec_object ("input-stream", + P_("Input stream"), + P_("The GInputStream to read from"), + G_TYPE_INPUT_STREAM, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_OUTPUT_STREAM, + g_param_spec_object ("output-stream", + P_("Output stream"), + P_("The GOutputStream to write to"), + G_TYPE_OUTPUT_STREAM, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); +} + +/** + * g_io_stream_is_closed: + * @stream: a #GIOStream + * + * Checks if a stream is closed. + * + * Returns: %TRUE if the stream is closed. + * + * Since: 2.22 + */ +gboolean +g_io_stream_is_closed (GIOStream *stream) +{ + g_return_val_if_fail (G_IS_IO_STREAM (stream), TRUE); + + return stream->priv->closed; +} + +/** + * g_io_stream_get_input_stream: + * @stream: a #GIOStream + * + * Gets the input stream for this object. This is used + * for reading. + * + * Returns: (transfer none): a #GInputStream, owned by the #GIOStream. + * Do not free. + * + * Since: 2.22 + */ +GInputStream * +g_io_stream_get_input_stream (GIOStream *stream) +{ + GIOStreamClass *klass; + + klass = G_IO_STREAM_GET_CLASS (stream); + + g_assert (klass->get_input_stream != NULL); + + return klass->get_input_stream (stream); +} + +/** + * g_io_stream_get_output_stream: + * @stream: a #GIOStream + * + * Gets the output stream for this object. This is used for + * writing. + * + * Returns: (transfer none): a #GOutputStream, owned by the #GIOStream. + * Do not free. + * + * Since: 2.22 + */ +GOutputStream * +g_io_stream_get_output_stream (GIOStream *stream) +{ + GIOStreamClass *klass; + + klass = G_IO_STREAM_GET_CLASS (stream); + + g_assert (klass->get_output_stream != NULL); + return klass->get_output_stream (stream); +} + +/** + * g_io_stream_has_pending: + * @stream: a #GIOStream + * + * Checks if a stream has pending actions. + * + * Returns: %TRUE if @stream has pending actions. + * + * Since: 2.22 + **/ +gboolean +g_io_stream_has_pending (GIOStream *stream) +{ + g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE); + + return stream->priv->pending; +} + +/** + * g_io_stream_set_pending: + * @stream: a #GIOStream + * @error: a #GError location to store the error occurring, or %NULL to + * ignore + * + * Sets @stream to have actions pending. If the pending flag is + * already set or @stream is closed, it will return %FALSE and set + * @error. + * + * Returns: %TRUE if pending was previously unset and is now set. + * + * Since: 2.22 + */ +gboolean +g_io_stream_set_pending (GIOStream *stream, + GError **error) +{ + g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE); + + if (stream->priv->closed) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Stream is already closed")); + return FALSE; + } + + if (stream->priv->pending) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING, + /* Translators: This is an error you get if there is + * already an operation running against this stream when + * you try to start one */ + _("Stream has outstanding operation")); + return FALSE; + } + + stream->priv->pending = TRUE; + return TRUE; +} + +/** + * g_io_stream_clear_pending: + * @stream: a #GIOStream + * + * Clears the pending flag on @stream. + * + * Since: 2.22 + */ +void +g_io_stream_clear_pending (GIOStream *stream) +{ + g_return_if_fail (G_IS_IO_STREAM (stream)); + + stream->priv->pending = FALSE; +} + +static gboolean +g_io_stream_real_close (GIOStream *stream, + GCancellable *cancellable, + GError **error) +{ + gboolean res; + + res = g_output_stream_close (g_io_stream_get_output_stream (stream), + cancellable, error); + + /* If this errored out, unset error so that we don't report + further errors, but still do the following ops */ + if (error != NULL && *error != NULL) + error = NULL; + + res &= g_input_stream_close (g_io_stream_get_input_stream (stream), + cancellable, error); + + return res; +} + +/** + * g_io_stream_close: + * @stream: a #GIOStream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @error: location to store the error occurring, or %NULL to ignore + * + * Closes the stream, releasing resources related to it. This will also + * close the individual input and output streams, if they are not already + * closed. + * + * Once the stream is closed, all other operations will return + * %G_IO_ERROR_CLOSED. Closing a stream multiple times will not + * return an error. + * + * Closing a stream will automatically flush any outstanding buffers + * in the stream. + * + * Streams will be automatically closed when the last reference + * is dropped, but you might want to call this function to make sure + * resources are released as early as possible. + * + * Some streams might keep the backing store of the stream (e.g. a file + * descriptor) open after the stream is closed. See the documentation for + * the individual stream for details. + * + * On failure the first error that happened will be reported, but the + * close operation will finish as much as possible. A stream that failed + * to close will still return %G_IO_ERROR_CLOSED for all operations. + * Still, it is important to check and report the error to the user, + * otherwise there might be a loss of data as all data might not be written. + * + * If @cancellable is not NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * Cancelling a close will still leave the stream closed, but some streams + * can use a faster close that doesn't block to e.g. check errors. + * + * The default implementation of this method just calls close on the + * individual input/output streams. + * + * Returns: %TRUE on success, %FALSE on failure + * + * Since: 2.22 + */ +gboolean +g_io_stream_close (GIOStream *stream, + GCancellable *cancellable, + GError **error) +{ + GIOStreamClass *class; + gboolean res; + + g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE); + + class = G_IO_STREAM_GET_CLASS (stream); + + if (stream->priv->closed) + return TRUE; + + if (!g_io_stream_set_pending (stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = TRUE; + if (class->close_fn) + res = class->close_fn (stream, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + stream->priv->closed = TRUE; + g_io_stream_clear_pending (stream); + + return res; +} + +static void +async_ready_close_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GIOStream *stream = G_IO_STREAM (source_object); + GIOStreamClass *klass = G_IO_STREAM_GET_CLASS (stream); + GTask *task = user_data; + GError *error = NULL; + gboolean success; + + stream->priv->closed = TRUE; + g_io_stream_clear_pending (stream); + + if (g_async_result_legacy_propagate_error (res, &error)) + success = FALSE; + else + success = klass->close_finish (stream, res, &error); + + if (error) + g_task_return_error (task, error); + else + g_task_return_boolean (task, success); + + g_object_unref (task); +} + +/** + * g_io_stream_close_async: + * @stream: a #GIOStream + * @io_priority: the io priority of the request + * @cancellable: (nullable): optional cancellable object + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Requests an asynchronous close of the stream, releasing resources + * related to it. When the operation is finished @callback will be + * called. You can then call g_io_stream_close_finish() to get + * the result of the operation. + * + * For behaviour details see g_io_stream_close(). + * + * The asynchronous methods have a default fallback that uses threads + * to implement asynchronicity, so they are optional for inheriting + * classes. However, if you override one you must override all. + * + * Since: 2.22 + */ +void +g_io_stream_close_async (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GIOStreamClass *class; + GError *error = NULL; + GTask *task; + + g_return_if_fail (G_IS_IO_STREAM (stream)); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_io_stream_close_async); + + if (stream->priv->closed) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + if (!g_io_stream_set_pending (stream, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + class = G_IO_STREAM_GET_CLASS (stream); + + class->close_async (stream, io_priority, cancellable, + async_ready_close_callback_wrapper, task); +} + +/** + * g_io_stream_close_finish: + * @stream: a #GIOStream + * @result: a #GAsyncResult + * @error: a #GError location to store the error occurring, or %NULL to + * ignore + * + * Closes a stream. + * + * Returns: %TRUE if stream was successfully closed, %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_io_stream_close_finish (GIOStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_IO_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + + +static void +close_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GIOStream *stream = source_object; + GIOStreamClass *class; + GError *error = NULL; + gboolean result; + + class = G_IO_STREAM_GET_CLASS (stream); + if (class->close_fn) + { + result = class->close_fn (stream, + g_task_get_cancellable (task), + &error); + if (!result) + { + g_task_return_error (task, error); + return; + } + } + + g_task_return_boolean (task, TRUE); +} + +typedef struct +{ + GError *error; + gint pending; +} CloseAsyncData; + +static void +stream_close_complete (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + CloseAsyncData *data; + + data = g_task_get_task_data (task); + data->pending--; + + if (G_IS_OUTPUT_STREAM (source)) + { + GError *error = NULL; + + /* Match behaviour with the sync route and give precedent to the + * error returned from closing the output stream. + */ + g_output_stream_close_finish (G_OUTPUT_STREAM (source), result, &error); + if (error) + { + if (data->error) + g_error_free (data->error); + data->error = error; + } + } + else + g_input_stream_close_finish (G_INPUT_STREAM (source), result, data->error ? NULL : &data->error); + + if (data->pending == 0) + { + if (data->error) + g_task_return_error (task, data->error); + else + g_task_return_boolean (task, TRUE); + + g_slice_free (CloseAsyncData, data); + g_object_unref (task); + } +} + +static void +g_io_stream_real_close_async (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GInputStream *input; + GOutputStream *output; + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_io_stream_real_close_async); + g_task_set_check_cancellable (task, FALSE); + g_task_set_priority (task, io_priority); + + input = g_io_stream_get_input_stream (stream); + output = g_io_stream_get_output_stream (stream); + + if (g_input_stream_async_close_is_via_threads (input) && g_output_stream_async_close_is_via_threads (output)) + { + /* No sense in dispatching to the thread twice -- just do it all + * in one go. + */ + g_task_run_in_thread (task, close_async_thread); + g_object_unref (task); + } + else + { + CloseAsyncData *data; + + /* We should avoid dispatching to another thread in case either + * object that would not do it for itself because it may not be + * threadsafe. + */ + data = g_slice_new (CloseAsyncData); + data->error = NULL; + data->pending = 2; + + g_task_set_task_data (task, data, NULL); + g_input_stream_close_async (input, io_priority, cancellable, stream_close_complete, task); + g_output_stream_close_async (output, io_priority, cancellable, stream_close_complete, task); + } +} + +static gboolean +g_io_stream_real_close_finish (GIOStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +typedef struct +{ + GIOStream *stream1; + GIOStream *stream2; + GIOStreamSpliceFlags flags; + gint io_priority; + GCancellable *cancellable; + gulong cancelled_id; + GCancellable *op1_cancellable; + GCancellable *op2_cancellable; + guint completed; + GError *error; +} SpliceContext; + +static void +splice_context_free (SpliceContext *ctx) +{ + g_object_unref (ctx->stream1); + g_object_unref (ctx->stream2); + if (ctx->cancellable != NULL) + g_object_unref (ctx->cancellable); + g_object_unref (ctx->op1_cancellable); + g_object_unref (ctx->op2_cancellable); + g_clear_error (&ctx->error); + g_slice_free (SpliceContext, ctx); +} + +static void +splice_complete (GTask *task, + SpliceContext *ctx) +{ + if (ctx->cancelled_id != 0) + g_cancellable_disconnect (ctx->cancellable, ctx->cancelled_id); + ctx->cancelled_id = 0; + + if (ctx->error != NULL) + { + g_task_return_error (task, ctx->error); + ctx->error = NULL; + } + else + g_task_return_boolean (task, TRUE); +} + +static void +splice_close_cb (GObject *iostream, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + SpliceContext *ctx = g_task_get_task_data (task); + GError *error = NULL; + + g_io_stream_close_finish (G_IO_STREAM (iostream), res, &error); + + ctx->completed++; + + /* Keep the first error that occurred */ + if (error != NULL && ctx->error == NULL) + ctx->error = error; + else + g_clear_error (&error); + + /* If all operations are done, complete now */ + if (ctx->completed == 4) + splice_complete (task, ctx); + + g_object_unref (task); +} + +static void +splice_cb (GObject *ostream, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + SpliceContext *ctx = g_task_get_task_data (task); + GError *error = NULL; + + g_output_stream_splice_finish (G_OUTPUT_STREAM (ostream), res, &error); + + ctx->completed++; + + /* ignore cancellation error if it was not requested by the user */ + if (error != NULL && + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && + (ctx->cancellable == NULL || + !g_cancellable_is_cancelled (ctx->cancellable))) + g_clear_error (&error); + + /* Keep the first error that occurred */ + if (error != NULL && ctx->error == NULL) + ctx->error = error; + else + g_clear_error (&error); + + if (ctx->completed == 1 && + (ctx->flags & G_IO_STREAM_SPLICE_WAIT_FOR_BOTH) == 0) + { + /* We don't want to wait for the 2nd operation to finish, cancel it */ + g_cancellable_cancel (ctx->op1_cancellable); + g_cancellable_cancel (ctx->op2_cancellable); + } + else if (ctx->completed == 2) + { + if (ctx->cancellable == NULL || + !g_cancellable_is_cancelled (ctx->cancellable)) + { + g_cancellable_reset (ctx->op1_cancellable); + g_cancellable_reset (ctx->op2_cancellable); + } + + /* Close the IO streams if needed */ + if ((ctx->flags & G_IO_STREAM_SPLICE_CLOSE_STREAM1) != 0) + { + g_io_stream_close_async (ctx->stream1, + g_task_get_priority (task), + ctx->op1_cancellable, + splice_close_cb, g_object_ref (task)); + } + else + ctx->completed++; + + if ((ctx->flags & G_IO_STREAM_SPLICE_CLOSE_STREAM2) != 0) + { + g_io_stream_close_async (ctx->stream2, + g_task_get_priority (task), + ctx->op2_cancellable, + splice_close_cb, g_object_ref (task)); + } + else + ctx->completed++; + + /* If all operations are done, complete now */ + if (ctx->completed == 4) + splice_complete (task, ctx); + } + + g_object_unref (task); +} + +static void +splice_cancelled_cb (GCancellable *cancellable, + GTask *task) +{ + SpliceContext *ctx; + + ctx = g_task_get_task_data (task); + g_cancellable_cancel (ctx->op1_cancellable); + g_cancellable_cancel (ctx->op2_cancellable); +} + +/** + * g_io_stream_splice_async: + * @stream1: a #GIOStream. + * @stream2: a #GIOStream. + * @flags: a set of #GIOStreamSpliceFlags. + * @io_priority: the io priority of the request. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback. + * @user_data: (closure): user data passed to @callback. + * + * Asynchronously splice the output stream of @stream1 to the input stream of + * @stream2, and splice the output stream of @stream2 to the input stream of + * @stream1. + * + * When the operation is finished @callback will be called. + * You can then call g_io_stream_splice_finish() to get the + * result of the operation. + * + * Since: 2.28 + **/ +void +g_io_stream_splice_async (GIOStream *stream1, + GIOStream *stream2, + GIOStreamSpliceFlags flags, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + SpliceContext *ctx; + GInputStream *istream; + GOutputStream *ostream; + + if (cancellable != NULL && g_cancellable_is_cancelled (cancellable)) + { + g_task_report_new_error (NULL, callback, user_data, + g_io_stream_splice_async, + G_IO_ERROR, G_IO_ERROR_CANCELLED, + "Operation has been cancelled"); + return; + } + + ctx = g_slice_new0 (SpliceContext); + ctx->stream1 = g_object_ref (stream1); + ctx->stream2 = g_object_ref (stream2); + ctx->flags = flags; + ctx->op1_cancellable = g_cancellable_new (); + ctx->op2_cancellable = g_cancellable_new (); + ctx->completed = 0; + + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (task, g_io_stream_splice_async); + g_task_set_task_data (task, ctx, (GDestroyNotify) splice_context_free); + + if (cancellable != NULL) + { + ctx->cancellable = g_object_ref (cancellable); + ctx->cancelled_id = g_cancellable_connect (cancellable, + G_CALLBACK (splice_cancelled_cb), g_object_ref (task), + g_object_unref); + } + + istream = g_io_stream_get_input_stream (stream1); + ostream = g_io_stream_get_output_stream (stream2); + g_output_stream_splice_async (ostream, istream, G_OUTPUT_STREAM_SPLICE_NONE, + io_priority, ctx->op1_cancellable, splice_cb, + g_object_ref (task)); + + istream = g_io_stream_get_input_stream (stream2); + ostream = g_io_stream_get_output_stream (stream1); + g_output_stream_splice_async (ostream, istream, G_OUTPUT_STREAM_SPLICE_NONE, + io_priority, ctx->op2_cancellable, splice_cb, + g_object_ref (task)); + + g_object_unref (task); +} + +/** + * g_io_stream_splice_finish: + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an asynchronous io stream splice operation. + * + * Returns: %TRUE on success, %FALSE otherwise. + * + * Since: 2.28 + **/ +gboolean +g_io_stream_splice_finish (GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} diff --git a/gio/giostream.h b/gio/giostream.h new file mode 100644 index 0000000..5dbe0e6 --- /dev/null +++ b/gio/giostream.h @@ -0,0 +1,135 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008, 2009 Codethink Limited + * Copyright © 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Ryan Lortie + * Alexander Larsson + */ + +#ifndef __G_IO_STREAM_H__ +#define __G_IO_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_IO_STREAM (g_io_stream_get_type ()) +#define G_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_IO_STREAM, GIOStream)) +#define G_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_IO_STREAM, GIOStreamClass)) +#define G_IS_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_IO_STREAM)) +#define G_IS_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_IO_STREAM)) +#define G_IO_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_IO_STREAM, GIOStreamClass)) + +typedef struct _GIOStreamPrivate GIOStreamPrivate; +typedef struct _GIOStreamClass GIOStreamClass; + +/** + * GIOStream: + * + * Base class for read-write streams. + **/ +struct _GIOStream +{ + GObject parent_instance; + + /*< private >*/ + GIOStreamPrivate *priv; +}; + +struct _GIOStreamClass +{ + GObjectClass parent_class; + + GInputStream * (*get_input_stream) (GIOStream *stream); + GOutputStream * (*get_output_stream) (GIOStream *stream); + + gboolean (* close_fn) (GIOStream *stream, + GCancellable *cancellable, + GError **error); + void (* close_async) (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* close_finish) (GIOStream *stream, + GAsyncResult *result, + GError **error); + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); + void (*_g_reserved7) (void); + void (*_g_reserved8) (void); + void (*_g_reserved9) (void); + void (*_g_reserved10) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_io_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GInputStream * g_io_stream_get_input_stream (GIOStream *stream); +GLIB_AVAILABLE_IN_ALL +GOutputStream *g_io_stream_get_output_stream (GIOStream *stream); + +GLIB_AVAILABLE_IN_ALL +void g_io_stream_splice_async (GIOStream *stream1, + GIOStream *stream2, + GIOStreamSpliceFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +gboolean g_io_stream_splice_finish (GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_io_stream_close (GIOStream *stream, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_io_stream_close_async (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_io_stream_close_finish (GIOStream *stream, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_io_stream_is_closed (GIOStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_io_stream_has_pending (GIOStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_io_stream_set_pending (GIOStream *stream, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_io_stream_clear_pending (GIOStream *stream); + +G_END_DECLS + +#endif /* __G_IO_STREAM_H__ */ diff --git a/gio/giotypes.h b/gio/giotypes.h new file mode 100644 index 0000000..da6a10a --- /dev/null +++ b/gio/giotypes.h @@ -0,0 +1,658 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __GIO_TYPES_H__ +#define __GIO_TYPES_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GAppLaunchContext GAppLaunchContext; +typedef struct _GAppInfo GAppInfo; /* Dummy typedef */ +typedef struct _GAsyncResult GAsyncResult; /* Dummy typedef */ +typedef struct _GAsyncInitable GAsyncInitable; +typedef struct _GBufferedInputStream GBufferedInputStream; +typedef struct _GBufferedOutputStream GBufferedOutputStream; +typedef struct _GCancellable GCancellable; +typedef struct _GCharsetConverter GCharsetConverter; +typedef struct _GConverter GConverter; +typedef struct _GConverterInputStream GConverterInputStream; +typedef struct _GConverterOutputStream GConverterOutputStream; +typedef struct _GDatagramBased GDatagramBased; +typedef struct _GDataInputStream GDataInputStream; +typedef struct _GSimplePermission GSimplePermission; +typedef struct _GZlibCompressor GZlibCompressor; +typedef struct _GZlibDecompressor GZlibDecompressor; + +typedef struct _GSimpleActionGroup GSimpleActionGroup; +typedef struct _GRemoteActionGroup GRemoteActionGroup; +typedef struct _GDBusActionGroup GDBusActionGroup; +typedef struct _GActionMap GActionMap; +typedef struct _GActionGroup GActionGroup; +typedef struct _GPropertyAction GPropertyAction; +typedef struct _GSimpleAction GSimpleAction; +typedef struct _GAction GAction; +typedef struct _GApplication GApplication; +typedef struct _GApplicationCommandLine GApplicationCommandLine; +typedef struct _GSettingsBackend GSettingsBackend; +typedef struct _GSettings GSettings; +typedef struct _GPermission GPermission; + +typedef struct _GMenuModel GMenuModel; +typedef struct _GNotification GNotification; + +/** + * GDrive: + * + * Opaque drive object. + **/ +typedef struct _GDrive GDrive; /* Dummy typedef */ +typedef struct _GFileEnumerator GFileEnumerator; +typedef struct _GFileMonitor GFileMonitor; +typedef struct _GFilterInputStream GFilterInputStream; +typedef struct _GFilterOutputStream GFilterOutputStream; + +/** + * GFile: + * + * A handle to an object implementing the #GFileIface interface. + * Generally stores a location within the file system. Handles do not + * necessarily represent files or directories that currently exist. + **/ +typedef struct _GFile GFile; /* Dummy typedef */ +typedef struct _GFileInfo GFileInfo; + +/** + * GFileAttributeMatcher: + * + * Determines if a string matches a file attribute. + **/ +typedef struct _GFileAttributeMatcher GFileAttributeMatcher; +typedef struct _GFileAttributeInfo GFileAttributeInfo; +typedef struct _GFileAttributeInfoList GFileAttributeInfoList; +typedef struct _GFileDescriptorBased GFileDescriptorBased; +typedef struct _GFileInputStream GFileInputStream; +typedef struct _GFileOutputStream GFileOutputStream; +typedef struct _GFileIOStream GFileIOStream; +typedef struct _GFileIcon GFileIcon; +typedef struct _GFilenameCompleter GFilenameCompleter; + + +typedef struct _GIcon GIcon; /* Dummy typedef */ +typedef struct _GInetAddress GInetAddress; +typedef struct _GInetAddressMask GInetAddressMask; +typedef struct _GInetSocketAddress GInetSocketAddress; +typedef struct _GNativeSocketAddress GNativeSocketAddress; +typedef struct _GInputStream GInputStream; +typedef struct _GInitable GInitable; +typedef struct _GIOModule GIOModule; +typedef struct _GIOExtensionPoint GIOExtensionPoint; +typedef struct _GIOExtension GIOExtension; + +/** + * GIOSchedulerJob: + * + * Opaque class for defining and scheduling IO jobs. + **/ +typedef struct _GIOSchedulerJob GIOSchedulerJob; +typedef struct _GIOStreamAdapter GIOStreamAdapter; +typedef struct _GLoadableIcon GLoadableIcon; /* Dummy typedef */ +typedef struct _GBytesIcon GBytesIcon; +typedef struct _GMemoryInputStream GMemoryInputStream; +typedef struct _GMemoryOutputStream GMemoryOutputStream; + +/** + * GMount: + * + * A handle to an object implementing the #GMountIface interface. + **/ +typedef struct _GMount GMount; /* Dummy typedef */ +typedef struct _GMountOperation GMountOperation; +typedef struct _GNetworkAddress GNetworkAddress; +typedef struct _GNetworkMonitor GNetworkMonitor; +typedef struct _GNetworkService GNetworkService; +typedef struct _GOutputStream GOutputStream; +typedef struct _GIOStream GIOStream; +typedef struct _GSimpleIOStream GSimpleIOStream; +typedef struct _GPollableInputStream GPollableInputStream; /* Dummy typedef */ +typedef struct _GPollableOutputStream GPollableOutputStream; /* Dummy typedef */ +typedef struct _GResolver GResolver; + +/** + * GResource: + * + * A resource bundle. + * + * Since: 2.32 + */ +typedef struct _GResource GResource; +typedef struct _GSeekable GSeekable; +typedef struct _GSimpleAsyncResult GSimpleAsyncResult; + +/** + * GSocket: + * + * A lowlevel network socket object. + * + * Since: 2.22 + **/ +typedef struct _GSocket GSocket; + +/** + * GSocketControlMessage: + * + * Base class for socket-type specific control messages that can be sent and + * received over #GSocket. + **/ +typedef struct _GSocketControlMessage GSocketControlMessage; +/** + * GSocketClient: + * + * A helper class for network clients to make connections. + * + * Since: 2.22 + **/ +typedef struct _GSocketClient GSocketClient; +/** + * GSocketConnection: + * + * A socket connection GIOStream object for connection-oriented sockets. + * + * Since: 2.22 + **/ +typedef struct _GSocketConnection GSocketConnection; +/** + * GSocketListener: + * + * A helper class for network servers to listen for and accept connections. + * + * Since: 2.22 + **/ +typedef struct _GSocketListener GSocketListener; +/** + * GSocketService: + * + * A helper class for handling accepting incoming connections in the + * glib mainloop. + * + * Since: 2.22 + **/ +typedef struct _GSocketService GSocketService; +typedef struct _GSocketAddress GSocketAddress; +typedef struct _GSocketAddressEnumerator GSocketAddressEnumerator; +typedef struct _GSocketConnectable GSocketConnectable; +typedef struct _GSrvTarget GSrvTarget; +typedef struct _GTask GTask; +/** + * GTcpConnection: + * + * A #GSocketConnection for TCP/IP connections. + * + * Since: 2.22 + **/ +typedef struct _GTcpConnection GTcpConnection; +typedef struct _GTcpWrapperConnection GTcpWrapperConnection; +/** + * GThreadedSocketService: + * + * A helper class for handling accepting incoming connections in the + * glib mainloop and handling them in a thread. + * + * Since: 2.22 + **/ +typedef struct _GThreadedSocketService GThreadedSocketService; +typedef struct _GDtlsConnection GDtlsConnection; +typedef struct _GDtlsClientConnection GDtlsClientConnection; /* Dummy typedef */ +typedef struct _GDtlsServerConnection GDtlsServerConnection; /* Dummy typedef */ +typedef struct _GThemedIcon GThemedIcon; +typedef struct _GTlsCertificate GTlsCertificate; +typedef struct _GTlsClientConnection GTlsClientConnection; /* Dummy typedef */ +typedef struct _GTlsConnection GTlsConnection; +typedef struct _GTlsDatabase GTlsDatabase; +typedef struct _GTlsFileDatabase GTlsFileDatabase; +typedef struct _GTlsInteraction GTlsInteraction; +typedef struct _GTlsPassword GTlsPassword; +typedef struct _GTlsServerConnection GTlsServerConnection; /* Dummy typedef */ +typedef struct _GVfs GVfs; /* Dummy typedef */ + +/** + * GProxyResolver: + * + * A helper class to enumerate proxies base on URI. + * + * Since: 2.26 + **/ +typedef struct _GProxyResolver GProxyResolver; +typedef struct _GProxy GProxy; +typedef struct _GProxyAddress GProxyAddress; +typedef struct _GProxyAddressEnumerator GProxyAddressEnumerator; + +/** + * GVolume: + * + * Opaque mountable volume object. + **/ +typedef struct _GVolume GVolume; /* Dummy typedef */ +typedef struct _GVolumeMonitor GVolumeMonitor; + +/** + * GAsyncReadyCallback: + * @source_object: (nullable): the object the asynchronous operation was started with. + * @res: a #GAsyncResult. + * @user_data: user data passed to the callback. + * + * Type definition for a function that will be called back when an asynchronous + * operation within GIO has been completed. #GAsyncReadyCallback + * callbacks from #GTask are guaranteed to be invoked in a later + * iteration of the + * [thread-default main context][g-main-context-push-thread-default] + * where the #GTask was created. All other users of + * #GAsyncReadyCallback must likewise call it asynchronously in a + * later iteration of the main context. + * + * The asynchronous operation is guaranteed to have held a reference to + * @source_object from the time when the `*_async()` function was called, until + * after this callback returns. + **/ +typedef void (*GAsyncReadyCallback) (GObject *source_object, + GAsyncResult *res, + gpointer user_data); + +/** + * GFileProgressCallback: + * @current_num_bytes: the current number of bytes in the operation. + * @total_num_bytes: the total number of bytes in the operation. + * @user_data: user data passed to the callback. + * + * When doing file operations that may take a while, such as moving + * a file or copying a file, a progress callback is used to pass how + * far along that operation is to the application. + **/ +typedef void (*GFileProgressCallback) (goffset current_num_bytes, + goffset total_num_bytes, + gpointer user_data); + +/** + * GFileReadMoreCallback: + * @file_contents: the data as currently read. + * @file_size: the size of the data currently read. + * @callback_data: (closure): data passed to the callback. + * + * When loading the partial contents of a file with g_file_load_partial_contents_async(), + * it may become necessary to determine if any more data from the file should be loaded. + * A #GFileReadMoreCallback function facilitates this by returning %TRUE if more data + * should be read, or %FALSE otherwise. + * + * Returns: %TRUE if more data should be read back. %FALSE otherwise. + **/ +typedef gboolean (* GFileReadMoreCallback) (const char *file_contents, + goffset file_size, + gpointer callback_data); + +/** + * GFileMeasureProgressCallback: + * @reporting: %TRUE if more reports will come + * @current_size: the current cumulative size measurement + * @num_dirs: the number of directories visited so far + * @num_files: the number of non-directory files encountered + * @user_data: the data passed to the original request for this callback + * + * This callback type is used by g_file_measure_disk_usage() to make + * periodic progress reports when measuring the amount of disk spaced + * used by a directory. + * + * These calls are made on a best-effort basis and not all types of + * #GFile will support them. At the minimum, however, one call will + * always be made immediately. + * + * In the case that there is no support, @reporting will be set to + * %FALSE (and the other values undefined) and no further calls will be + * made. Otherwise, the @reporting will be %TRUE and the other values + * all-zeros during the first (immediate) call. In this way, you can + * know which type of progress UI to show without a delay. + * + * For g_file_measure_disk_usage() the callback is made directly. For + * g_file_measure_disk_usage_async() the callback is made via the + * default main context of the calling thread (ie: the same way that the + * final async result would be reported). + * + * @current_size is in the same units as requested by the operation (see + * %G_FILE_MEASURE_APPARENT_SIZE). + * + * The frequency of the updates is implementation defined, but is + * ideally about once every 200ms. + * + * The last progress callback may or may not be equal to the final + * result. Always check the async result to get the final value. + * + * Since: 2.38 + **/ +typedef void (* GFileMeasureProgressCallback) (gboolean reporting, + guint64 current_size, + guint64 num_dirs, + guint64 num_files, + gpointer user_data); + +/** + * GIOSchedulerJobFunc: + * @job: a #GIOSchedulerJob. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @user_data: the data to pass to callback function + * + * I/O Job function. + * + * Long-running jobs should periodically check the @cancellable + * to see if they have been cancelled. + * + * Returns: %TRUE if this function should be called again to + * complete the job, %FALSE if the job is complete (or cancelled) + **/ +typedef gboolean (*GIOSchedulerJobFunc) (GIOSchedulerJob *job, + GCancellable *cancellable, + gpointer user_data); + +/** + * GSimpleAsyncThreadFunc: + * @res: a #GSimpleAsyncResult. + * @object: a #GObject. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * + * Simple thread function that runs an asynchronous operation and + * checks for cancellation. + **/ +typedef void (*GSimpleAsyncThreadFunc) (GSimpleAsyncResult *res, + GObject *object, + GCancellable *cancellable); + +/** + * GSocketSourceFunc: + * @socket: the #GSocket + * @condition: the current condition at the source fired. + * @user_data: data passed in by the user. + * + * This is the function type of the callback used for the #GSource + * returned by g_socket_create_source(). + * + * Returns: it should return %FALSE if the source should be removed. + * + * Since: 2.22 + */ +typedef gboolean (*GSocketSourceFunc) (GSocket *socket, + GIOCondition condition, + gpointer user_data); + +/** + * GDatagramBasedSourceFunc: + * @datagram_based: the #GDatagramBased + * @condition: the current condition at the source fired + * @user_data: data passed in by the user + * + * This is the function type of the callback used for the #GSource + * returned by g_datagram_based_create_source(). + * + * Returns: %G_SOURCE_REMOVE if the source should be removed, + * %G_SOURCE_CONTINUE otherwise + * + * Since: 2.48 + */ +typedef gboolean (*GDatagramBasedSourceFunc) (GDatagramBased *datagram_based, + GIOCondition condition, + gpointer user_data); + +/** + * GInputVector: + * @buffer: Pointer to a buffer where data will be written. + * @size: the available size in @buffer. + * + * Structure used for scatter/gather data input. + * You generally pass in an array of #GInputVectors + * and the operation will store the read data starting in the + * first buffer, switching to the next as needed. + * + * Since: 2.22 + */ +typedef struct _GInputVector GInputVector; + +struct _GInputVector { + gpointer buffer; + gsize size; +}; + +/** + * GInputMessage: + * @address: (optional) (out) (transfer full): return location + * for a #GSocketAddress, or %NULL + * @vectors: (array length=num_vectors) (out): pointer to an + * array of input vectors + * @num_vectors: the number of input vectors pointed to by @vectors + * @bytes_received: (out): will be set to the number of bytes that have been + * received + * @flags: (out): collection of #GSocketMsgFlags for the received message, + * outputted by the call + * @control_messages: (array length=num_control_messages) (optional) + * (out) (transfer full): return location for a + * caller-allocated array of #GSocketControlMessages, or %NULL + * @num_control_messages: (out) (optional): return location for the number of + * elements in @control_messages + * + * Structure used for scatter/gather data input when receiving multiple + * messages or packets in one go. You generally pass in an array of empty + * #GInputVectors and the operation will use all the buffers as if they + * were one buffer, and will set @bytes_received to the total number of bytes + * received across all #GInputVectors. + * + * This structure closely mirrors `struct mmsghdr` and `struct msghdr` from + * the POSIX sockets API (see `man 2 recvmmsg`). + * + * If @address is non-%NULL then it is set to the source address the message + * was received from, and the caller must free it afterwards. + * + * If @control_messages is non-%NULL then it is set to an array of control + * messages received with the message (if any), and the caller must free it + * afterwards. @num_control_messages is set to the number of elements in + * this array, which may be zero. + * + * Flags relevant to this message will be returned in @flags. For example, + * `MSG_EOR` or `MSG_TRUNC`. + * + * Since: 2.48 + */ +typedef struct _GInputMessage GInputMessage; + +struct _GInputMessage { + GSocketAddress **address; + + GInputVector *vectors; + guint num_vectors; + + gsize bytes_received; + gint flags; + + GSocketControlMessage ***control_messages; + guint *num_control_messages; +}; + +/** + * GOutputVector: + * @buffer: Pointer to a buffer of data to read. + * @size: the size of @buffer. + * + * Structure used for scatter/gather data output. + * You generally pass in an array of #GOutputVectors + * and the operation will use all the buffers as if they were + * one buffer. + * + * Since: 2.22 + */ +typedef struct _GOutputVector GOutputVector; + +struct _GOutputVector { + gconstpointer buffer; + gsize size; +}; + +/** + * GOutputMessage: + * @address: (nullable): a #GSocketAddress, or %NULL + * @vectors: pointer to an array of output vectors + * @num_vectors: the number of output vectors pointed to by @vectors. + * @bytes_sent: initialize to 0. Will be set to the number of bytes + * that have been sent + * @control_messages: (array length=num_control_messages) (nullable): a pointer + * to an array of #GSocketControlMessages, or %NULL. + * @num_control_messages: number of elements in @control_messages. + * + * Structure used for scatter/gather data output when sending multiple + * messages or packets in one go. You generally pass in an array of + * #GOutputVectors and the operation will use all the buffers as if they + * were one buffer. + * + * If @address is %NULL then the message is sent to the default receiver + * (as previously set by g_socket_connect()). + * + * Since: 2.44 + */ +typedef struct _GOutputMessage GOutputMessage; + +struct _GOutputMessage { + GSocketAddress *address; + + GOutputVector *vectors; + guint num_vectors; + + guint bytes_sent; + + GSocketControlMessage **control_messages; + guint num_control_messages; +}; + +typedef struct _GCredentials GCredentials; +typedef struct _GUnixCredentialsMessage GUnixCredentialsMessage; +typedef struct _GUnixFDList GUnixFDList; +typedef struct _GDBusMessage GDBusMessage; +typedef struct _GDBusConnection GDBusConnection; +typedef struct _GDBusProxy GDBusProxy; +typedef struct _GDBusMethodInvocation GDBusMethodInvocation; +typedef struct _GDBusServer GDBusServer; +typedef struct _GDBusAuthObserver GDBusAuthObserver; +typedef struct _GDBusErrorEntry GDBusErrorEntry; +typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable; +typedef struct _GDBusSubtreeVTable GDBusSubtreeVTable; +typedef struct _GDBusAnnotationInfo GDBusAnnotationInfo; +typedef struct _GDBusArgInfo GDBusArgInfo; +typedef struct _GDBusMethodInfo GDBusMethodInfo; +typedef struct _GDBusSignalInfo GDBusSignalInfo; +typedef struct _GDBusPropertyInfo GDBusPropertyInfo; +typedef struct _GDBusInterfaceInfo GDBusInterfaceInfo; +typedef struct _GDBusNodeInfo GDBusNodeInfo; + +/** + * GCancellableSourceFunc: + * @cancellable: the #GCancellable + * @user_data: data passed in by the user. + * + * This is the function type of the callback used for the #GSource + * returned by g_cancellable_source_new(). + * + * Returns: it should return %FALSE if the source should be removed. + * + * Since: 2.28 + */ +typedef gboolean (*GCancellableSourceFunc) (GCancellable *cancellable, + gpointer user_data); + +/** + * GPollableSourceFunc: + * @pollable_stream: the #GPollableInputStream or #GPollableOutputStream + * @user_data: data passed in by the user. + * + * This is the function type of the callback used for the #GSource + * returned by g_pollable_input_stream_create_source() and + * g_pollable_output_stream_create_source(). + * + * Returns: it should return %FALSE if the source should be removed. + * + * Since: 2.28 + */ +typedef gboolean (*GPollableSourceFunc) (GObject *pollable_stream, + gpointer user_data); + +typedef struct _GDBusInterface GDBusInterface; /* Dummy typedef */ +typedef struct _GDBusInterfaceSkeleton GDBusInterfaceSkeleton; +typedef struct _GDBusObject GDBusObject; /* Dummy typedef */ +typedef struct _GDBusObjectSkeleton GDBusObjectSkeleton; +typedef struct _GDBusObjectProxy GDBusObjectProxy; +typedef struct _GDBusObjectManager GDBusObjectManager; /* Dummy typedef */ +typedef struct _GDBusObjectManagerClient GDBusObjectManagerClient; +typedef struct _GDBusObjectManagerServer GDBusObjectManagerServer; + +/** + * GDBusProxyTypeFunc: + * @manager: A #GDBusObjectManagerClient. + * @object_path: The object path of the remote object. + * @interface_name: (nullable): The interface name of the remote object or %NULL if a #GDBusObjectProxy #GType is requested. + * @user_data: User data. + * + * Function signature for a function used to determine the #GType to + * use for an interface proxy (if @interface_name is not %NULL) or + * object proxy (if @interface_name is %NULL). + * + * This function is called in the + * [thread-default main loop][g-main-context-push-thread-default] + * that @manager was constructed in. + * + * Returns: A #GType to use for the remote object. The returned type + * must be a #GDBusProxy or #GDBusObjectProxy -derived + * type. + * + * Since: 2.30 + */ +typedef GType (*GDBusProxyTypeFunc) (GDBusObjectManagerClient *manager, + const gchar *object_path, + const gchar *interface_name, + gpointer user_data); + +typedef struct _GTestDBus GTestDBus; + +/** + * GSubprocess: + * + * A child process. + * + * Since: 2.40 + */ +typedef struct _GSubprocess GSubprocess; +/** + * GSubprocessLauncher: + * + * Options for launching a child process. + * + * Since: 2.40 + */ +typedef struct _GSubprocessLauncher GSubprocessLauncher; + +G_END_DECLS + +#endif /* __GIO_TYPES_H__ */ diff --git a/gio/giounix-private.c b/gio/giounix-private.c new file mode 100644 index 0000000..c535a08 --- /dev/null +++ b/gio/giounix-private.c @@ -0,0 +1,145 @@ +/* + * Copyright © 2021 Ole André Vadla RavnÃ¥s + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include +#include +#include +#if defined (HAVE_EPOLL_CREATE) +#include +#elif defined (HAVE_KQUEUE) +#include +#include +#endif + +#include "giounix-private.h" + +#define G_TEMP_FAILURE_RETRY(expression) \ + ({ \ + gssize __result; \ + \ + do \ + __result = (gssize) (expression); \ + while (__result == -1 && errno == EINTR); \ + \ + __result; \ + }) + +static gboolean g_fd_is_regular_file (int fd) G_GNUC_UNUSED; + +gboolean +_g_fd_is_pollable (int fd) +{ + /* + * Determining whether a file-descriptor (FD) is pollable turns out to be + * quite hard. + * + * We used to detect this by attempting to lseek() and check if it failed with + * ESPIPE, and if so we'd consider the FD pollable. But this turned out to not + * work on e.g. PTYs and other devices that are pollable. + * + * Another approach that was considered was to call fstat() and if it failed + * we'd assume that the FD is pollable, and if it succeeded we'd consider it + * pollable as long as it's not a regular file. This seemed to work alright + * except for FDs backed by simple devices, such as /dev/null. + * + * There are however OS-specific methods that allow us to figure this out with + * absolute certainty: + */ + +#if defined (HAVE_EPOLL_CREATE) + /* + * Linux + * + * The answer we seek is provided by the kernel's file_can_poll(): + * https://github.com/torvalds/linux/blob/2ab38c17aac10bf55ab3efde4c4db3893d8691d2/include/linux/poll.h#L81-L84 + * But we cannot probe that by using poll() as the returned events for + * non-pollable FDs are always IN | OUT. + * + * The best option then seems to be using epoll, as it will refuse to add FDs + * where file_can_poll() returns FALSE. + */ + + int efd; + struct epoll_event ev = { 0, }; + gboolean add_succeeded; + + efd = epoll_create (1); + if (efd == -1) + g_error ("epoll_create () failed: %s", g_strerror (errno)); + + ev.events = EPOLLIN; + + add_succeeded = epoll_ctl (efd, EPOLL_CTL_ADD, fd, &ev) == 0; + + close (efd); + + return add_succeeded; +#elif defined (HAVE_KQUEUE) + /* + * Apple OSes and BSDs + * + * Like on Linux, we cannot use poll() to do the probing, but kqueue does + * the trick as it will refuse to add non-pollable FDs. (Except for regular + * files, which we need to special-case. Even though kqueue does support them, + * poll() does not.) + */ + + int kfd; + struct kevent ev; + gboolean add_succeeded; + + if (g_fd_is_regular_file (fd)) + return FALSE; + + kfd = kqueue (); + if (kfd == -1) + g_error ("kqueue () failed: %s", g_strerror (errno)); + + EV_SET (&ev, fd, EVFILT_READ, EV_ADD, 0, 0, NULL); + + add_succeeded = + G_TEMP_FAILURE_RETRY (kevent (kfd, &ev, 1, NULL, 0, NULL)) == 0; + + close (kfd); + + return add_succeeded; +#else + /* + * Other UNIXes (AIX, QNX, Solaris, etc.) + * + * We can rule out regular files, but devices such as /dev/null will be + * reported as pollable even though they're not. This is hopefully good + * enough for most use-cases, but easy to expand on later if needed. + */ + + return !g_fd_is_regular_file (fd); +#endif +} + +static gboolean +g_fd_is_regular_file (int fd) +{ + struct stat st; + + if (G_TEMP_FAILURE_RETRY (fstat (fd, &st)) == -1) + return FALSE; + + return S_ISREG (st.st_mode); +} diff --git a/gio/giounix-private.h b/gio/giounix-private.h new file mode 100644 index 0000000..aa56b07 --- /dev/null +++ b/gio/giounix-private.h @@ -0,0 +1,26 @@ +/* + * Copyright © 2021 Ole André Vadla RavnÃ¥s + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#pragma once + +#include "gio.h" + +G_BEGIN_DECLS + +gboolean _g_fd_is_pollable (int fd); + +G_END_DECLS diff --git a/gio/giowin32-afunix.h b/gio/giowin32-afunix.h new file mode 100644 index 0000000..0e8e27f --- /dev/null +++ b/gio/giowin32-afunix.h @@ -0,0 +1,40 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2022 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef GIOWIN32_AFUNIX_H_ +#define GIOWIN32_AFUNIX_H_ + +#ifdef HAVE_AFUNIX_H +#include +#else + +/* + * Fallback definitions of things we need in afunix.h, if not available from the + * used Windows SDK or MinGW headers. + */ +#define UNIX_PATH_MAX 108 + +typedef struct sockaddr_un { + ADDRESS_FAMILY sun_family; + char sun_path[UNIX_PATH_MAX]; +} SOCKADDR_UN, *PSOCKADDR_UN; + +#define SIO_AF_UNIX_GETPEERPID _WSAIOR(IOC_VENDOR, 256) +#endif + +#endif /* GIOWIN32_AFUNIX_H_*/ diff --git a/gio/giowin32-priv.h b/gio/giowin32-priv.h new file mode 100644 index 0000000..6f20a95 --- /dev/null +++ b/gio/giowin32-priv.h @@ -0,0 +1,42 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Colin Walters + */ + +#ifndef __G_IO_WIN32_PRIV_H__ +#define __G_IO_WIN32_PRIV_H__ + +#include "gwin32inputstream.h" +#include "gwin32outputstream.h" + +G_BEGIN_DECLS + +G_GNUC_INTERNAL +GInputStream * +g_win32_input_stream_new_from_fd (gint fd, + gboolean close_fd); + +GOutputStream * +g_win32_output_stream_new_from_fd (gint fd, + gboolean close_fd); + +void +gio_win32_appinfo_init (gboolean do_wait); +G_END_DECLS + +#endif /* __G_IO_MODULE_PRIV_H__ */ diff --git a/gio/giowin32-private.c b/gio/giowin32-private.c new file mode 100644 index 0000000..6e1926d --- /dev/null +++ b/gio/giowin32-private.c @@ -0,0 +1,450 @@ +/* giowin32-private.c - private glib-gio functions for W32 GAppInfo + * + * Copyright 2019 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + + +static gsize +g_utf16_len (const gunichar2 *str) +{ + gsize result; + + for (result = 0; str[0] != 0; str++, result++) + ; + + return result; +} + +static gunichar2 * +g_wcsdup (const gunichar2 *str, gssize str_len) +{ + gsize str_len_unsigned; + gsize str_size; + + g_return_val_if_fail (str != NULL, NULL); + + if (str_len < 0) + str_len_unsigned = g_utf16_len (str); + else + str_len_unsigned = (gsize) str_len; + + g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1); + str_size = (str_len_unsigned + 1) * sizeof (gunichar2); + + return g_memdup2 (str, str_size); +} + +static const gunichar2 * +g_utf16_wchr (const gunichar2 *str, const wchar_t wchr) +{ + for (; str != NULL && str[0] != 0; str++) + if ((wchar_t) str[0] == wchr) + return str; + + return NULL; +} + +static gboolean +g_utf16_to_utf8_and_fold (const gunichar2 *str, + gssize length, + gchar **str_u8, + gchar **str_u8_folded) +{ + gchar *u8; + gchar *folded; + u8 = g_utf16_to_utf8 (str, length, NULL, NULL, NULL); + + if (u8 == NULL) + return FALSE; + + folded = g_utf8_casefold (u8, -1); + + if (str_u8) + *str_u8 = g_steal_pointer (&u8); + + g_free (u8); + + if (str_u8_folded) + *str_u8_folded = g_steal_pointer (&folded); + + g_free (folded); + + return TRUE; +} + +/* Finds the last directory separator in @filename, + * returns a pointer to the position after that separator. + * If the string ends with a separator, returned value + * will be pointing at the NUL terminator. + * If the string does not contain separators, returns the + * string itself. + */ +static const gunichar2 * +g_utf16_find_basename (const gunichar2 *filename, + gssize len) +{ + const gunichar2 *result; + + if (len < 0) + len = g_utf16_len (filename); + if (len == 0) + return filename; + + result = &filename[len - 1]; + + while (result > filename) + { + if ((wchar_t) result[0] == L'/' || + (wchar_t) result[0] == L'\\') + { + result += 1; + break; + } + + result -= 1; + } + + return result; +} + +/* Finds the last directory separator in @filename, + * returns a pointer to the position after that separator. + * If the string ends with a separator, returned value + * will be pointing at the NUL terminator. + * If the string does not contain separators, returns the + * string itself. + */ +static const gchar * +g_utf8_find_basename (const gchar *filename, + gssize len) +{ + const gchar *result; + + if (len < 0) + len = strlen (filename); + if (len == 0) + return filename; + + result = &filename[len - 1]; + + while (result > filename) + { + if (result[0] == '/' || + result[0] == '\\') + { + result += 1; + break; + } + + result -= 1; + } + + return result; +} + +/** + * Parses @commandline, figuring out what the filename being invoked + * is. All returned strings are pointers into @commandline. + * @commandline must be a valid UTF-16 string and not be NULL. + * @after_executable is the first character after executable + * (usually a space, but not always). + * If @comma_separator is TRUE, accepts ',' as a separator between + * the filename and the following argument. + */ +static void +_g_win32_parse_filename (const gunichar2 *commandline, + gboolean comma_separator, + const gunichar2 **executable_start, + gssize *executable_len, + const gunichar2 **executable_basename, + const gunichar2 **after_executable) +{ + const gunichar2 *p; + const gunichar2 *first_argument; + gboolean quoted; + gssize len; + gssize execlen; + gboolean found; + + while ((wchar_t) commandline[0] == L' ') + commandline++; + + quoted = FALSE; + execlen = 0; + found = FALSE; + first_argument = NULL; + + if ((wchar_t) commandline[0] == L'"') + { + quoted = TRUE; + commandline += 1; + } + + len = g_utf16_len (commandline); + p = commandline; + + while (p < &commandline[len]) + { + switch ((wchar_t) p[0]) + { + case L'"': + if (quoted) + { + first_argument = p + 1; + /* Note: this is a valid commandline for opening "c:/file.txt": + * > "notepad"c:/file.txt + */ + p = &commandline[len]; + found = TRUE; + } + else + execlen += 1; + break; + case L' ': + if (!quoted) + { + first_argument = p; + p = &commandline[len]; + found = TRUE; + } + else + execlen += 1; + break; + case L',': + if (!quoted && comma_separator) + { + first_argument = p; + p = &commandline[len]; + found = TRUE; + } + else + execlen += 1; + break; + default: + execlen += 1; + break; + } + p += 1; + } + + if (!found) + first_argument = &commandline[len]; + + if (executable_start) + *executable_start = commandline; + + if (executable_len) + *executable_len = execlen; + + if (executable_basename) + *executable_basename = g_utf16_find_basename (commandline, execlen); + + if (after_executable) + *after_executable = first_argument; +} + +/* Make sure @commandline is a valid UTF-16 string before + * calling this function! + * follow_class_chain_to_handler() does perform such validation. + */ +static void +_g_win32_extract_executable (const gunichar2 *commandline, + gchar **ex_out, + gchar **ex_basename_out, + gchar **ex_folded_out, + gchar **ex_folded_basename_out, + gchar **dll_function_out) +{ + gchar *ex; + gchar *ex_folded; + const gunichar2 *first_argument; + const gunichar2 *executable; + const gunichar2 *executable_basename; + gboolean quoted; + gboolean folded; + gssize execlen; + + _g_win32_parse_filename (commandline, FALSE, &executable, &execlen, &executable_basename, &first_argument); + + commandline = executable; + + while ((wchar_t) first_argument[0] == L' ') + first_argument++; + + folded = g_utf16_to_utf8_and_fold (executable, (gssize) execlen, &ex, &ex_folded); + /* This should never fail as @executable has to be valid UTF-16. */ + g_assert (folded); + + if (dll_function_out) + *dll_function_out = NULL; + + /* See if the executable basename is "rundll32.exe". If so, then + * parse the rest of the commandline as r'"?path-to-dll"?[ ]*,*[ ]*dll_function_to_invoke' + */ + /* Using just "rundll32.exe", without an absolute path, seems + * very exploitable, but MS does that sometimes, so we have + * to accept that. + */ + if ((g_strcmp0 (ex_folded, "rundll32.exe") == 0 || + g_str_has_suffix (ex_folded, "\\rundll32.exe") || + g_str_has_suffix (ex_folded, "/rundll32.exe")) && + first_argument[0] != 0 && + dll_function_out != NULL) + { + /* Corner cases: + * > rundll32.exe c:\some,file,with,commas.dll,some_function + * is treated by rundll32 as: + * dll=c:\some + * function=file,with,commas.dll,some_function + * unless the dll name is surrounded by double quotation marks: + * > rundll32.exe "c:\some,file,with,commas.dll",some_function + * in which case everything works normally. + * Also, quoting only works if it surrounds the file name, i.e: + * > rundll32.exe "c:\some,file"",with,commas.dll",some_function + * will not work. + * Also, comma is optional when filename is quoted or when function + * name is separated from the filename by space(s): + * > rundll32.exe "c:\some,file,with,commas.dll"some_function + * will work, + * > rundll32.exe c:\some_dll_without_commas_or_spaces.dll some_function + * will work too. + * Also, any number of commas is accepted: + * > rundll32.exe c:\some_dll_without_commas_or_spaces.dll , , ,,, , some_function + * works just fine. + * And the ultimate example is: + * > "rundll32.exe""c:\some,file,with,commas.dll"some_function + * and it also works. + * Good job, Microsoft! + */ + const gunichar2 *filename_end = NULL; + gssize filename_len = 0; + gssize function_len = 0; + const gunichar2 *dllpart; + + quoted = FALSE; + + if ((wchar_t) first_argument[0] == L'"') + quoted = TRUE; + + _g_win32_parse_filename (first_argument, TRUE, &dllpart, &filename_len, NULL, &filename_end); + + if (filename_end[0] != 0 && filename_len > 0) + { + const gunichar2 *function_begin = filename_end; + + while ((wchar_t) function_begin[0] == L',' || (wchar_t) function_begin[0] == L' ') + function_begin += 1; + + if (function_begin[0] != 0) + { + gchar *dllpart_utf8; + gchar *dllpart_utf8_folded; + gchar *function_utf8; + gboolean folded; + const gunichar2 *space = g_utf16_wchr (function_begin, L' '); + + if (space) + function_len = space - function_begin; + else + function_len = g_utf16_len (function_begin); + + if (quoted) + first_argument += 1; + + folded = g_utf16_to_utf8_and_fold (first_argument, filename_len, &dllpart_utf8, &dllpart_utf8_folded); + g_assert (folded); + + function_utf8 = g_utf16_to_utf8 (function_begin, function_len, NULL, NULL, NULL); + + /* We only take this branch when dll_function_out is not NULL */ + *dll_function_out = g_steal_pointer (&function_utf8); + + g_free (function_utf8); + + /* + * Free our previous output candidate (rundll32) and replace it with the DLL path, + * then proceed forward as if nothing has changed. + */ + g_free (ex); + g_free (ex_folded); + + ex = dllpart_utf8; + ex_folded = dllpart_utf8_folded; + } + } + } + + if (ex_out) + { + if (ex_basename_out) + *ex_basename_out = (gchar *) g_utf8_find_basename (ex, -1); + + *ex_out = g_steal_pointer (&ex); + } + + g_free (ex); + + if (ex_folded_out) + { + if (ex_folded_basename_out) + *ex_folded_basename_out = (gchar *) g_utf8_find_basename (ex_folded, -1); + + *ex_folded_out = g_steal_pointer (&ex_folded); + } + + g_free (ex_folded); +} + +/** + * rundll32 accepts many different commandlines. Among them is this: + * > rundll32.exe "c:/program files/foo/bar.dll",,, , ,,,, , function_name %1 + * rundll32 just reads the first argument as a potentially quoted + * filename until the quotation ends (if quoted) or until a comma, + * or until a space. Then ignores all subsequent spaces (if any) and commas (if any; + * at least one comma is mandatory only if the filename is not quoted), + * and then interprets the rest of the commandline (until a space or a NUL-byte) + * as a name of a function. + * When GLib tries to run a program, it attempts to correctly re-quote the arguments, + * turning the first argument into "c:/program files/foo/bar.dll,,,". + * This breaks rundll32 parsing logic. + * Try to work around this by ensuring that the syntax is like this: + * > rundll32.exe "c:/program files/foo/bar.dll" function_name + * This syntax is valid for rundll32 *and* GLib spawn routines won't break it. + * + * @commandline must have at least 2 arguments, and the second argument + * must contain a (possibly quoted) filename, followed by a space or + * a comma. This can be checked for with an extract_executable() call - + * it should return a non-null dll_function. + */ +static void +_g_win32_fixup_broken_microsoft_rundll_commandline (gunichar2 *commandline) +{ + const gunichar2 *first_argument; + gunichar2 *after_first_argument; + + _g_win32_parse_filename (commandline, FALSE, NULL, NULL, NULL, &first_argument); + + while ((wchar_t) first_argument[0] == L' ') + first_argument++; + + _g_win32_parse_filename (first_argument, TRUE, NULL, NULL, NULL, (const gunichar2 **) &after_first_argument); + + if ((wchar_t) after_first_argument[0] == L',') + after_first_argument[0] = 0x0020; + /* Else everything is ok (first char after filename is ' ' or the first char + * of the function name - either way this will work). + */ +} diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c new file mode 100644 index 0000000..9319491 --- /dev/null +++ b/gio/gkeyfilesettingsbackend.c @@ -0,0 +1,1033 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2010 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Authors: Vincent Untz + * Ryan Lortie + */ + +#include "config.h" + +#include +#include + +#include +#include + +#include "gfile.h" +#include "gfileinfo.h" +#include "gfileenumerator.h" +#include "gfilemonitor.h" +#include "gsimplepermission.h" +#include "gsettingsbackendinternal.h" +#include "giomodule-priv.h" +#include "gportalsupport.h" + + +#define G_TYPE_KEYFILE_SETTINGS_BACKEND (g_keyfile_settings_backend_get_type ()) +#define G_KEYFILE_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_KEYFILE_SETTINGS_BACKEND, \ + GKeyfileSettingsBackend)) +#define G_IS_KEYFILE_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_KEYFILE_SETTINGS_BACKEND)) + + +typedef GSettingsBackendClass GKeyfileSettingsBackendClass; + +typedef enum { + PROP_FILENAME = 1, + PROP_ROOT_PATH, + PROP_ROOT_GROUP, + PROP_DEFAULTS_DIR +} GKeyfileSettingsBackendProperty; + +typedef struct +{ + GSettingsBackend parent_instance; + + GKeyFile *keyfile; + GPermission *permission; + gboolean writable; + char *defaults_dir; + GKeyFile *system_keyfile; + GHashTable *system_locks; /* Used as a set, owning the strings it contains */ + + gchar *prefix; + gsize prefix_len; + gchar *root_group; + gsize root_group_len; + + GFile *file; + GFileMonitor *file_monitor; + guint8 digest[32]; + GFile *dir; + GFileMonitor *dir_monitor; +} GKeyfileSettingsBackend; + +#ifdef G_OS_WIN32 +#define EXTENSION_PRIORITY 10 +#else +#define EXTENSION_PRIORITY (glib_should_use_portal () && !glib_has_dconf_access_in_sandbox () ? 110 : 10) +#endif + +G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend, + g_keyfile_settings_backend, + G_TYPE_SETTINGS_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "keyfile", EXTENSION_PRIORITY)) + +static void +compute_checksum (guint8 *digest, + gconstpointer contents, + gsize length) +{ + GChecksum *checksum; + gsize len = 32; + + checksum = g_checksum_new (G_CHECKSUM_SHA256); + g_checksum_update (checksum, contents, length); + g_checksum_get_digest (checksum, digest, &len); + g_checksum_free (checksum); + g_assert (len == 32); +} + +static gboolean +g_keyfile_settings_backend_keyfile_write (GKeyfileSettingsBackend *kfsb, + GError **error) +{ + gchar *contents; + gsize length; + gboolean success; + + contents = g_key_file_to_data (kfsb->keyfile, &length, NULL); + success = g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION | + G_FILE_CREATE_PRIVATE, + NULL, NULL, error); + + compute_checksum (kfsb->digest, contents, length); + g_free (contents); + + return success; +} + +static gboolean +group_name_matches (const gchar *group_name, + const gchar *prefix) +{ + /* sort of like g_str_has_prefix() except that it must be an exact + * match or the prefix followed by '/'. + * + * for example 'a' is a prefix of 'a' and 'a/b' but not 'ab'. + */ + gint i; + + for (i = 0; prefix[i]; i++) + if (prefix[i] != group_name[i]) + return FALSE; + + return group_name[i] == '\0' || group_name[i] == '/'; +} + +static gboolean +convert_path (GKeyfileSettingsBackend *kfsb, + const gchar *key, + gchar **group, + gchar **basename) +{ + gsize key_len = strlen (key); + const gchar *last_slash; + + if (key_len < kfsb->prefix_len || + memcmp (key, kfsb->prefix, kfsb->prefix_len) != 0) + return FALSE; + + key_len -= kfsb->prefix_len; + key += kfsb->prefix_len; + + last_slash = strrchr (key, '/'); + + /* Disallow empty group names or key names */ + if (key_len == 0 || + (last_slash != NULL && + (*(last_slash + 1) == '\0' || + last_slash == key))) + return FALSE; + + if (kfsb->root_group) + { + /* if a root_group was specified, make sure the user hasn't given + * a path that ghosts that group name + */ + if (last_slash != NULL && last_slash - key >= 0 && + (gsize) (last_slash - key) == kfsb->root_group_len && + memcmp (key, kfsb->root_group, last_slash - key) == 0) + return FALSE; + } + else + { + /* if no root_group was given, ensure that the user gave a path */ + if (last_slash == NULL) + return FALSE; + } + + if (group) + { + if (last_slash != NULL) + { + *group = g_memdup2 (key, (last_slash - key) + 1); + (*group)[(last_slash - key)] = '\0'; + } + else + *group = g_strdup (kfsb->root_group); + } + + if (basename) + { + if (last_slash != NULL) + *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key)); + else + *basename = g_strdup (key); + } + + return TRUE; +} + +static gboolean +path_is_valid (GKeyfileSettingsBackend *kfsb, + const gchar *path) +{ + return convert_path (kfsb, path, NULL, NULL); +} + +static GVariant * +get_from_keyfile (GKeyfileSettingsBackend *kfsb, + const GVariantType *type, + const gchar *key) +{ + GVariant *return_value = NULL; + gchar *group, *name; + + if (convert_path (kfsb, key, &group, &name)) + { + gchar *str; + gchar *sysstr; + + g_assert (*name); + + sysstr = g_key_file_get_value (kfsb->system_keyfile, group, name, NULL); + str = g_key_file_get_value (kfsb->keyfile, group, name, NULL); + if (sysstr && + (g_hash_table_contains (kfsb->system_locks, key) || + str == NULL)) + { + g_free (str); + str = g_steal_pointer (&sysstr); + } + + if (str) + { + return_value = g_variant_parse (type, str, NULL, NULL, NULL); + + /* As a special case, support values of type %G_VARIANT_TYPE_STRING + * not being quoted, since users keep forgetting to do it and then + * getting confused. */ + if (return_value == NULL && + g_variant_type_equal (type, G_VARIANT_TYPE_STRING) && + str[0] != '\"') + { + GString *s = g_string_sized_new (strlen (str) + 2); + char *p = str; + + g_string_append_c (s, '\"'); + while (*p) + { + if (*p == '\"') + g_string_append_c (s, '\\'); + g_string_append_c (s, *p); + p++; + } + g_string_append_c (s, '\"'); + return_value = g_variant_parse (type, s->str, NULL, NULL, NULL); + g_string_free (s, TRUE); + } + g_free (str); + } + + g_free (sysstr); + + g_free (group); + g_free (name); + } + + return return_value; +} + +static gboolean +set_to_keyfile (GKeyfileSettingsBackend *kfsb, + const gchar *key, + GVariant *value) +{ + gchar *group, *name; + + if (g_hash_table_contains (kfsb->system_locks, key)) + return FALSE; + + if (convert_path (kfsb, key, &group, &name)) + { + if (value) + { + gchar *str = g_variant_print (value, FALSE); + g_key_file_set_value (kfsb->keyfile, group, name, str); + g_variant_unref (g_variant_ref_sink (value)); + g_free (str); + } + else + { + if (*name == '\0') + { + gchar **groups; + gint i; + + groups = g_key_file_get_groups (kfsb->keyfile, NULL); + + for (i = 0; groups[i]; i++) + if (group_name_matches (groups[i], group)) + g_key_file_remove_group (kfsb->keyfile, groups[i], NULL); + + g_strfreev (groups); + } + else + g_key_file_remove_key (kfsb->keyfile, group, name, NULL); + } + + g_free (group); + g_free (name); + + return TRUE; + } + + return FALSE; +} + +static GVariant * +g_keyfile_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); + + if (default_value) + return NULL; + + return get_from_keyfile (kfsb, expected_type, key); +} + +typedef struct +{ + GKeyfileSettingsBackend *kfsb; + gboolean failed; +} WriteManyData; + +static gboolean +g_keyfile_settings_backend_write_one (gpointer key, + gpointer value, + gpointer user_data) +{ + WriteManyData *data = user_data; + gboolean success G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + success = set_to_keyfile (data->kfsb, key, value); + g_assert (success); + + return FALSE; +} + +static gboolean +g_keyfile_settings_backend_check_one (gpointer key, + gpointer value, + gpointer user_data) +{ + WriteManyData *data = user_data; + + return data->failed = g_hash_table_contains (data->kfsb->system_locks, key) || + !path_is_valid (data->kfsb, key); +} + +static gboolean +g_keyfile_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag) +{ + WriteManyData data = { G_KEYFILE_SETTINGS_BACKEND (backend), 0 }; + gboolean success; + GError *error = NULL; + + if (!data.kfsb->writable) + return FALSE; + + g_tree_foreach (tree, g_keyfile_settings_backend_check_one, &data); + + if (data.failed) + return FALSE; + + g_tree_foreach (tree, g_keyfile_settings_backend_write_one, &data); + success = g_keyfile_settings_backend_keyfile_write (data.kfsb, &error); + if (error) + { + g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (data.kfsb->file), error->message); + g_error_free (error); + } + + g_settings_backend_changed_tree (backend, tree, origin_tag); + + return success; +} + +static gboolean +g_keyfile_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); + gboolean success; + GError *error = NULL; + + if (!kfsb->writable) + return FALSE; + + success = set_to_keyfile (kfsb, key, value); + + if (success) + { + g_settings_backend_changed (backend, key, origin_tag); + success = g_keyfile_settings_backend_keyfile_write (kfsb, &error); + if (error) + { + g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (kfsb->file), error->message); + g_error_free (error); + } + } + + return success; +} + +static void +g_keyfile_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); + GError *error = NULL; + + if (set_to_keyfile (kfsb, key, NULL)) + { + g_keyfile_settings_backend_keyfile_write (kfsb, &error); + if (error) + { + g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (kfsb->file), error->message); + g_error_free (error); + } + } + + g_settings_backend_changed (backend, key, origin_tag); +} + +static gboolean +g_keyfile_settings_backend_get_writable (GSettingsBackend *backend, + const gchar *name) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); + + return kfsb->writable && + !g_hash_table_contains (kfsb->system_locks, name) && + path_is_valid (kfsb, name); +} + +static GPermission * +g_keyfile_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); + + return g_object_ref (kfsb->permission); +} + +static void +keyfile_to_tree (GKeyfileSettingsBackend *kfsb, + GTree *tree, + GKeyFile *keyfile, + gboolean dup_check) +{ + gchar **groups; + gint i; + + groups = g_key_file_get_groups (keyfile, NULL); + for (i = 0; groups[i]; i++) + { + gboolean is_root_group; + gchar **keys; + gint j; + + is_root_group = g_strcmp0 (kfsb->root_group, groups[i]) == 0; + + /* reject group names that will form invalid key names */ + if (!is_root_group && + (g_str_has_prefix (groups[i], "/") || + g_str_has_suffix (groups[i], "/") || strstr (groups[i], "//"))) + continue; + + keys = g_key_file_get_keys (keyfile, groups[i], NULL, NULL); + g_assert (keys != NULL); + + for (j = 0; keys[j]; j++) + { + gchar *path, *value; + + /* reject key names with slashes in them */ + if (strchr (keys[j], '/')) + continue; + + if (is_root_group) + path = g_strdup_printf ("%s%s", kfsb->prefix, keys[j]); + else + path = g_strdup_printf ("%s%s/%s", kfsb->prefix, groups[i], keys[j]); + + value = g_key_file_get_value (keyfile, groups[i], keys[j], NULL); + + if (dup_check && g_strcmp0 (g_tree_lookup (tree, path), value) == 0) + { + g_tree_remove (tree, path); + g_free (value); + g_free (path); + } + else + g_tree_insert (tree, path, value); + } + + g_strfreev (keys); + } + g_strfreev (groups); +} + +static void +g_keyfile_settings_backend_keyfile_reload (GKeyfileSettingsBackend *kfsb) +{ + guint8 digest[32]; + gchar *contents; + gsize length; + + contents = NULL; + length = 0; + + g_file_load_contents (kfsb->file, NULL, &contents, &length, NULL, NULL); + compute_checksum (digest, contents, length); + + if (memcmp (kfsb->digest, digest, sizeof digest) != 0) + { + GKeyFile *keyfiles[2]; + GTree *tree; + + tree = g_tree_new_full ((GCompareDataFunc) strcmp, NULL, + g_free, g_free); + + keyfiles[0] = kfsb->keyfile; + keyfiles[1] = g_key_file_new (); + + if (length > 0) + g_key_file_load_from_data (keyfiles[1], contents, length, + G_KEY_FILE_KEEP_COMMENTS | + G_KEY_FILE_KEEP_TRANSLATIONS, NULL); + + keyfile_to_tree (kfsb, tree, keyfiles[0], FALSE); + keyfile_to_tree (kfsb, tree, keyfiles[1], TRUE); + g_key_file_free (keyfiles[0]); + kfsb->keyfile = keyfiles[1]; + + if (g_tree_nnodes (tree) > 0) + g_settings_backend_changed_tree (&kfsb->parent_instance, tree, NULL); + + g_tree_unref (tree); + + memcpy (kfsb->digest, digest, sizeof digest); + } + + g_free (contents); +} + +static void +g_keyfile_settings_backend_keyfile_writable (GKeyfileSettingsBackend *kfsb) +{ + GFileInfo *fileinfo; + gboolean writable; + + fileinfo = g_file_query_info (kfsb->dir, "access::*", 0, NULL, NULL); + + if (fileinfo) + { + writable = + g_file_info_get_attribute_boolean (fileinfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) && + g_file_info_get_attribute_boolean (fileinfo, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE); + g_object_unref (fileinfo); + } + else + writable = FALSE; + + if (writable != kfsb->writable) + { + kfsb->writable = writable; + g_settings_backend_path_writable_changed (&kfsb->parent_instance, "/"); + } +} + +static void +g_keyfile_settings_backend_finalize (GObject *object) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); + + g_key_file_free (kfsb->keyfile); + g_object_unref (kfsb->permission); + g_key_file_unref (kfsb->system_keyfile); + g_hash_table_unref (kfsb->system_locks); + g_free (kfsb->defaults_dir); + + if (kfsb->file_monitor) + { + g_file_monitor_cancel (kfsb->file_monitor); + g_object_unref (kfsb->file_monitor); + } + g_object_unref (kfsb->file); + + if (kfsb->dir_monitor) + { + g_file_monitor_cancel (kfsb->dir_monitor); + g_object_unref (kfsb->dir_monitor); + } + g_object_unref (kfsb->dir); + + g_free (kfsb->root_group); + g_free (kfsb->prefix); + + G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)->finalize (object); +} + +static void +g_keyfile_settings_backend_init (GKeyfileSettingsBackend *kfsb) +{ +} + +static void +file_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + GKeyfileSettingsBackend *kfsb = user_data; + + /* Ignore file deletions, let the GKeyFile content remain in tact. */ + if (event_type != G_FILE_MONITOR_EVENT_DELETED) + g_keyfile_settings_backend_keyfile_reload (kfsb); +} + +static void +dir_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + GKeyfileSettingsBackend *kfsb = user_data; + + g_keyfile_settings_backend_keyfile_writable (kfsb); +} + +static void +load_system_settings (GKeyfileSettingsBackend *kfsb) +{ + GError *error = NULL; + const char *dir = "/etc/glib-2.0/settings"; + char *path; + char *contents; + + kfsb->system_keyfile = g_key_file_new (); + kfsb->system_locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + if (kfsb->defaults_dir) + dir = kfsb->defaults_dir; + + path = g_build_filename (dir, "defaults", NULL); + + /* The defaults are in the same keyfile format that we use for the settings. + * It can be produced from a dconf database using: dconf dump + */ + if (!g_key_file_load_from_file (kfsb->system_keyfile, path, G_KEY_FILE_NONE, &error)) + { + if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_warning ("Failed to read %s: %s", path, error->message); + g_clear_error (&error); + } + else + g_debug ("Loading default settings from %s", path); + + g_free (path); + + path = g_build_filename (dir, "locks", NULL); + + /* The locks file is a text file containing a list paths to lock, one per line. + * It can be produced from a dconf database using: dconf list-locks + */ + if (!g_file_get_contents (path, &contents, NULL, &error)) + { + if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_warning ("Failed to read %s: %s", path, error->message); + g_clear_error (&error); + } + else + { + char **lines; + gsize i; + + g_debug ("Loading locks from %s", path); + + lines = g_strsplit (contents, "\n", 0); + for (i = 0; lines[i]; i++) + { + char *line = lines[i]; + if (line[0] == '#' || line[0] == '\0') + { + g_free (line); + continue; + } + + g_debug ("Locking key %s", line); + g_hash_table_add (kfsb->system_locks, g_steal_pointer (&line)); + } + + g_free (lines); + } + g_free (contents); + + g_free (path); +} + +static void +g_keyfile_settings_backend_constructed (GObject *object) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); + GError *error = NULL; + const char *path; + + if (kfsb->file == NULL) + { + char *filename = g_build_filename (g_get_user_config_dir (), + "glib-2.0", "settings", "keyfile", + NULL); + kfsb->file = g_file_new_for_path (filename); + g_free (filename); + } + + if (kfsb->prefix == NULL) + { + kfsb->prefix = g_strdup ("/"); + kfsb->prefix_len = 1; + } + + kfsb->keyfile = g_key_file_new (); + kfsb->permission = g_simple_permission_new (TRUE); + + kfsb->dir = g_file_get_parent (kfsb->file); + path = g_file_peek_path (kfsb->dir); + if (g_mkdir_with_parents (path, 0700) == -1) + g_warning ("Failed to create %s: %s", path, g_strerror (errno)); + + kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, &error); + if (!kfsb->file_monitor) + { + g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message); + g_clear_error (&error); + } + else + { + g_signal_connect (kfsb->file_monitor, "changed", + G_CALLBACK (file_changed), kfsb); + } + + kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, &error); + if (!kfsb->dir_monitor) + { + g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message); + g_clear_error (&error); + } + else + { + g_signal_connect (kfsb->dir_monitor, "changed", + G_CALLBACK (dir_changed), kfsb); + } + + compute_checksum (kfsb->digest, NULL, 0); + + g_keyfile_settings_backend_keyfile_writable (kfsb); + g_keyfile_settings_backend_keyfile_reload (kfsb); + + load_system_settings (kfsb); +} + +static void +g_keyfile_settings_backend_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); + + switch ((GKeyfileSettingsBackendProperty)prop_id) + { + case PROP_FILENAME: + /* Construct only. */ + g_assert (kfsb->file == NULL); + if (g_value_get_string (value)) + kfsb->file = g_file_new_for_path (g_value_get_string (value)); + break; + + case PROP_ROOT_PATH: + /* Construct only. */ + g_assert (kfsb->prefix == NULL); + kfsb->prefix = g_value_dup_string (value); + if (kfsb->prefix) + kfsb->prefix_len = strlen (kfsb->prefix); + break; + + case PROP_ROOT_GROUP: + /* Construct only. */ + g_assert (kfsb->root_group == NULL); + kfsb->root_group = g_value_dup_string (value); + if (kfsb->root_group) + kfsb->root_group_len = strlen (kfsb->root_group); + break; + + case PROP_DEFAULTS_DIR: + /* Construct only. */ + g_assert (kfsb->defaults_dir == NULL); + kfsb->defaults_dir = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_keyfile_settings_backend_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); + + switch ((GKeyfileSettingsBackendProperty)prop_id) + { + case PROP_FILENAME: + g_value_set_string (value, g_file_peek_path (kfsb->file)); + break; + + case PROP_ROOT_PATH: + g_value_set_string (value, kfsb->prefix); + break; + + case PROP_ROOT_GROUP: + g_value_set_string (value, kfsb->root_group); + break; + + case PROP_DEFAULTS_DIR: + g_value_set_string (value, kfsb->defaults_dir); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_keyfile_settings_backend_finalize; + object_class->constructed = g_keyfile_settings_backend_constructed; + object_class->get_property = g_keyfile_settings_backend_get_property; + object_class->set_property = g_keyfile_settings_backend_set_property; + + class->read = g_keyfile_settings_backend_read; + class->write = g_keyfile_settings_backend_write; + class->write_tree = g_keyfile_settings_backend_write_tree; + class->reset = g_keyfile_settings_backend_reset; + class->get_writable = g_keyfile_settings_backend_get_writable; + class->get_permission = g_keyfile_settings_backend_get_permission; + /* No need to implement subscribed/unsubscribe: the only point would be to + * stop monitoring the file when there's no GSettings anymore, which is no + * big win. + */ + + /** + * GKeyfileSettingsBackend:filename: + * + * The location where the settings are stored on disk. + * + * Defaults to `$XDG_CONFIG_HOME/glib-2.0/settings/keyfile`. + */ + g_object_class_install_property (object_class, + PROP_FILENAME, + g_param_spec_string ("filename", + P_("Filename"), + P_("The filename"), + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GKeyfileSettingsBackend:root-path: + * + * All settings read to or written from the backend must fall under the + * path given in @root_path (which must start and end with a slash and + * not contain two consecutive slashes). @root_path may be "/". + * + * Defaults to "/". + */ + g_object_class_install_property (object_class, + PROP_ROOT_PATH, + g_param_spec_string ("root-path", + P_("Root path"), + P_("The root path"), + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GKeyfileSettingsBackend:root-group: + * + * If @root_group is non-%NULL then it specifies the name of the keyfile + * group used for keys that are written directly below the root path. + * + * Defaults to NULL. + */ + g_object_class_install_property (object_class, + PROP_ROOT_GROUP, + g_param_spec_string ("root-group", + P_("Root group"), + P_("The root group"), + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GKeyfileSettingsBackend:default-dir: + * + * The directory where the system defaults and locks are located. + * + * Defaults to `/etc/glib-2.0/settings`. + */ + g_object_class_install_property (object_class, + PROP_DEFAULTS_DIR, + g_param_spec_string ("defaults-dir", + P_("Default dir"), + P_("Defaults dir"), + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_keyfile_settings_backend_new: + * @filename: the filename of the keyfile + * @root_path: the path under which all settings keys appear + * @root_group: (nullable): the group name corresponding to + * @root_path, or %NULL + * + * Creates a keyfile-backed #GSettingsBackend. + * + * The filename of the keyfile to use is given by @filename. + * + * All settings read to or written from the backend must fall under the + * path given in @root_path (which must start and end with a slash and + * not contain two consecutive slashes). @root_path may be "/". + * + * If @root_group is non-%NULL then it specifies the name of the keyfile + * group used for keys that are written directly below @root_path. For + * example, if @root_path is "/apps/example/" and @root_group is + * "toplevel", then settings the key "/apps/example/enabled" to a value + * of %TRUE will cause the following to appear in the keyfile: + * + * |[ + * [toplevel] + * enabled=true + * ]| + * + * If @root_group is %NULL then it is not permitted to store keys + * directly below the @root_path. + * + * For keys not stored directly below @root_path (ie: in a sub-path), + * the name of the subpath (with the final slash stripped) is used as + * the name of the keyfile group. To continue the example, if + * "/apps/example/profiles/default/font-size" were set to + * 12 then the following would appear in the keyfile: + * + * |[ + * [profiles/default] + * font-size=12 + * ]| + * + * The backend will refuse writes (and return writability as being + * %FALSE) for keys outside of @root_path and, in the event that + * @root_group is %NULL, also for keys directly under @root_path. + * Writes will also be refused if the backend detects that it has the + * inability to rewrite the keyfile (ie: the containing directory is not + * writable). + * + * There is no checking done for your key namespace clashing with the + * syntax of the key file format. For example, if you have '[' or ']' + * characters in your path names or '=' in your key names you may be in + * trouble. + * + * The backend reads default values from a keyfile called `defaults` in + * the directory specified by the #GKeyfileSettingsBackend:defaults-dir property, + * and a list of locked keys from a text file with the name `locks` in + * the same location. + * + * Returns: (transfer full): a keyfile-backed #GSettingsBackend + **/ +GSettingsBackend * +g_keyfile_settings_backend_new (const gchar *filename, + const gchar *root_path, + const gchar *root_group) +{ + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (root_path != NULL, NULL); + g_return_val_if_fail (g_str_has_prefix (root_path, "/"), NULL); + g_return_val_if_fail (g_str_has_suffix (root_path, "/"), NULL); + g_return_val_if_fail (strstr (root_path, "//") == NULL, NULL); + + return G_SETTINGS_BACKEND (g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, + "filename", filename, + "root-path", root_path, + "root-group", root_group, + NULL)); +} diff --git a/gio/glib-compile-resources.c b/gio/glib-compile-resources.c new file mode 100644 index 0000000..82f1956 --- /dev/null +++ b/gio/glib-compile-resources.c @@ -0,0 +1,1312 @@ +/* + * Copyright © 2011 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include +#endif + +#include +#include +#include + +#include +#include "gvdb/gvdb-builder.h" + +#include "gconstructor_as_data.h" +#include "glib/glib-private.h" + +typedef struct +{ + char *filename; + char *content; + gsize content_size; + gsize size; + guint32 flags; +} FileData; + +typedef struct +{ + GHashTable *table; /* resource path -> FileData */ + + gboolean collect_data; + + /* per gresource */ + char *prefix; + + /* per file */ + char *alias; + gboolean compressed; + char *preproc_options; + + GString *string; /* non-NULL when accepting text */ +} ParseState; + +static gchar **sourcedirs = NULL; +static gchar *xmllint = NULL; +static gchar *jsonformat = NULL; +static gchar *gdk_pixbuf_pixdata = NULL; + +static void +file_data_free (FileData *data) +{ + g_free (data->filename); + g_free (data->content); + g_free (data); +} + +static void +start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + const GSList *element_stack; + const gchar *container; + + element_stack = g_markup_parse_context_get_element_stack (context); + container = element_stack->next ? element_stack->next->data : NULL; + +#define COLLECT(first, ...) \ + g_markup_collect_attributes (element_name, \ + attribute_names, attribute_values, error, \ + first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID) +#define OPTIONAL G_MARKUP_COLLECT_OPTIONAL +#define STRDUP G_MARKUP_COLLECT_STRDUP +#define STRING G_MARKUP_COLLECT_STRING +#define BOOL G_MARKUP_COLLECT_BOOLEAN +#define NO_ATTRS() COLLECT (G_MARKUP_COLLECT_INVALID, NULL) + + if (container == NULL) + { + if (strcmp (element_name, "gresources") == 0) + return; + } + else if (strcmp (container, "gresources") == 0) + { + if (strcmp (element_name, "gresource") == 0) + { + COLLECT (OPTIONAL | STRDUP, + "prefix", &state->prefix); + return; + } + } + else if (strcmp (container, "gresource") == 0) + { + if (strcmp (element_name, "file") == 0) + { + COLLECT (OPTIONAL | STRDUP, "alias", &state->alias, + OPTIONAL | BOOL, "compressed", &state->compressed, + OPTIONAL | STRDUP, "preprocess", &state->preproc_options); + state->string = g_string_new (""); + return; + } + } + + if (container) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Element <%s> not allowed inside <%s>"), + element_name, container); + else + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Element <%s> not allowed at toplevel"), element_name); + +} + +static GvdbItem * +get_parent (GHashTable *table, + gchar *key, + gint length) +{ + GvdbItem *grandparent, *parent; + + if (length == 1) + return NULL; + + while (key[--length - 1] != '/'); + key[length] = '\0'; + + parent = g_hash_table_lookup (table, key); + + if (parent == NULL) + { + parent = gvdb_hash_table_insert (table, key); + + grandparent = get_parent (table, key, length); + + if (grandparent != NULL) + gvdb_item_set_parent (parent, grandparent); + } + + return parent; +} + +static gchar * +find_file (const gchar *filename) +{ + guint i; + gchar *real_file; + gboolean exists; + + if (g_path_is_absolute (filename)) + return g_strdup (filename); + + /* search all the sourcedirs for the correct files in order */ + for (i = 0; sourcedirs[i] != NULL; i++) + { + real_file = g_build_path ("/", sourcedirs[i], filename, NULL); + exists = g_file_test (real_file, G_FILE_TEST_EXISTS); + if (exists) + return real_file; + g_free (real_file); + } + return NULL; +} + +static void +end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + GError *my_error = NULL; + + if (strcmp (element_name, "gresource") == 0) + { + g_free (state->prefix); + state->prefix = NULL; + } + + else if (strcmp (element_name, "file") == 0) + { + gchar *file; + gchar *real_file = NULL; + gchar *key; + FileData *data = NULL; + char *tmp_file = NULL; + + file = state->string->str; + key = file; + if (state->alias) + key = state->alias; + + if (state->prefix) + key = g_build_path ("/", "/", state->prefix, key, NULL); + else + key = g_build_path ("/", "/", key, NULL); + + if (g_hash_table_lookup (state->table, key) != NULL) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("File %s appears multiple times in the resource"), + key); + return; + } + + if (sourcedirs != NULL) + { + real_file = find_file (file); + if (real_file == NULL && state->collect_data) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Failed to locate “%s†in any source directory"), file); + return; + } + } + else + { + gboolean exists; + exists = g_file_test (file, G_FILE_TEST_EXISTS); + if (!exists && state->collect_data) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Failed to locate “%s†in current directory"), file); + return; + } + } + + if (real_file == NULL) + real_file = g_strdup (file); + + data = g_new0 (FileData, 1); + data->filename = g_strdup (real_file); + if (!state->collect_data) + goto done; + + if (state->preproc_options) + { + gchar **options; + guint i; + gboolean xml_stripblanks = FALSE; + gboolean json_stripblanks = FALSE; + gboolean to_pixdata = FALSE; + + options = g_strsplit (state->preproc_options, ",", -1); + + for (i = 0; options[i]; i++) + { + if (!strcmp (options[i], "xml-stripblanks")) + xml_stripblanks = TRUE; + else if (!strcmp (options[i], "to-pixdata")) + to_pixdata = TRUE; + else if (!strcmp (options[i], "json-stripblanks")) + json_stripblanks = TRUE; + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Unknown processing option “%sâ€"), options[i]); + g_strfreev (options); + goto cleanup; + } + } + g_strfreev (options); + + if (xml_stripblanks) + { + /* This is not fatal: pretty-printed XML is still valid XML */ + if (xmllint == NULL) + { + static gboolean xmllint_warned = FALSE; + + if (!xmllint_warned) + { + /* Translators: the first %s is a gresource XML attribute, + * the second %s is an environment variable, and the third + * %s is a command line tool + */ + char *warn = g_strdup_printf (_("%s preprocessing requested, but %s is not set, and %s is not in PATH"), + "xml-stripblanks", + "XMLLINT", + "xmllint"); + g_printerr ("%s\n", warn); + g_free (warn); + + /* Only warn once */ + xmllint_warned = TRUE; + } + } + else + { + GSubprocess *proc; + int fd; + + fd = g_file_open_tmp ("resource-XXXXXXXX", &tmp_file, error); + if (fd < 0) + goto cleanup; + + close (fd); + + proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error, + xmllint, "--nonet", "--noblanks", "--output", tmp_file, real_file, NULL); + g_free (real_file); + real_file = NULL; + + if (!proc) + goto cleanup; + + if (!g_subprocess_wait_check (proc, NULL, error)) + { + g_object_unref (proc); + goto cleanup; + } + + g_object_unref (proc); + + real_file = g_strdup (tmp_file); + } + } + + if (json_stripblanks) + { + /* As above, this is not fatal: pretty-printed JSON is still + * valid JSON + */ + if (jsonformat == NULL) + { + static gboolean jsonformat_warned = FALSE; + + if (!jsonformat_warned) + { + /* Translators: the first %s is a gresource XML attribute, + * the second %s is an environment variable, and the third + * %s is a command line tool + */ + char *warn = g_strdup_printf (_("%s preprocessing requested, but %s is not set, and %s is not in PATH"), + "json-stripblanks", + "JSON_GLIB_FORMAT", + "json-glib-format"); + g_printerr ("%s\n", warn); + g_free (warn); + + /* Only warn once */ + jsonformat_warned = TRUE; + } + } + else + { + GSubprocess *proc; + int fd; + + fd = g_file_open_tmp ("resource-XXXXXXXX", &tmp_file, error); + if (fd < 0) + goto cleanup; + + close (fd); + + proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error, + jsonformat, "--output", tmp_file, real_file, NULL); + g_free (real_file); + real_file = NULL; + + if (!proc) + goto cleanup; + + if (!g_subprocess_wait_check (proc, NULL, error)) + { + g_object_unref (proc); + goto cleanup; + } + + g_object_unref (proc); + + real_file = g_strdup (tmp_file); + } + } + + if (to_pixdata) + { + GSubprocess *proc; + int fd; + + /* This is a fatal error: if to-pixdata is used it means that + * the code loading the GResource expects a specific data format + */ + if (gdk_pixbuf_pixdata == NULL) + { + /* Translators: the first %s is a gresource XML attribute, + * the second %s is an environment variable, and the third + * %s is a command line tool + */ + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("%s preprocessing requested, but %s is not set, and %s is not in PATH"), + "to-pixdata", + "GDK_PIXBUF_PIXDATA", + "gdk-pixbuf-pixdata"); + goto cleanup; + } + + fd = g_file_open_tmp ("resource-XXXXXXXX", &tmp_file, error); + if (fd < 0) + goto cleanup; + + close (fd); + + proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error, + gdk_pixbuf_pixdata, real_file, tmp_file, NULL); + g_free (real_file); + real_file = NULL; + + if (!g_subprocess_wait_check (proc, NULL, error)) + { + g_object_unref (proc); + goto cleanup; + } + + g_object_unref (proc); + + real_file = g_strdup (tmp_file); + } + } + + if (!g_file_get_contents (real_file, &data->content, &data->size, &my_error)) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Error reading file %s: %s"), + real_file, my_error->message); + g_clear_error (&my_error); + goto cleanup; + } + /* Include zero termination in content_size for uncompressed files (but not in size) */ + data->content_size = data->size + 1; + + if (state->compressed) + { + GOutputStream *out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + GZlibCompressor *compressor = + g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9); + GOutputStream *out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor)); + + if (!g_output_stream_write_all (out2, data->content, data->size, + NULL, NULL, NULL) || + !g_output_stream_close (out2, NULL, NULL)) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Error compressing file %s"), + real_file); + g_object_unref (compressor); + g_object_unref (out); + g_object_unref (out2); + goto cleanup; + } + + g_free (data->content); + data->content_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (out)); + data->content = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out)); + + g_object_unref (compressor); + g_object_unref (out); + g_object_unref (out2); + + data->flags |= G_RESOURCE_FLAGS_COMPRESSED; + } + +done: + g_hash_table_insert (state->table, key, data); + data = NULL; + + cleanup: + /* Cleanup */ + + g_free (state->alias); + state->alias = NULL; + g_string_free (state->string, TRUE); + state->string = NULL; + g_free (state->preproc_options); + state->preproc_options = NULL; + + g_free (real_file); + + if (tmp_file) + { + unlink (tmp_file); + g_free (tmp_file); + } + + if (data != NULL) + file_data_free (data); + } +} + +static void +text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + gsize i; + + for (i = 0; i < text_len; i++) + if (!g_ascii_isspace (text[i])) + { + if (state->string) + g_string_append_len (state->string, text, text_len); + + else + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("text may not appear inside <%s>"), + g_markup_parse_context_get_element (context)); + + break; + } +} + +static GHashTable * +parse_resource_file (const gchar *filename, + gboolean collect_data, + GHashTable *files) +{ + GMarkupParser parser = { start_element, end_element, text, NULL, NULL }; + ParseState state = { 0, }; + GMarkupParseContext *context; + GError *error = NULL; + gchar *contents; + GHashTable *table = NULL; + gsize size; + + if (!g_file_get_contents (filename, &contents, &size, &error)) + { + g_printerr ("%s\n", error->message); + g_clear_error (&error); + return NULL; + } + + state.collect_data = collect_data; + state.table = g_hash_table_ref (files); + + context = g_markup_parse_context_new (&parser, + G_MARKUP_TREAT_CDATA_AS_TEXT | + G_MARKUP_PREFIX_ERROR_POSITION, + &state, NULL); + + if (!g_markup_parse_context_parse (context, contents, size, &error) || + !g_markup_parse_context_end_parse (context, &error)) + { + g_printerr ("%s: %s.\n", filename, error->message); + g_clear_error (&error); + } + else + { + GHashTableIter iter; + const char *key; + char *mykey; + gsize key_len; + FileData *data; + GVariant *v_data; + GVariantBuilder builder; + GvdbItem *item; + + table = gvdb_hash_table_new (NULL, NULL); + + g_hash_table_iter_init (&iter, state.table); + while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&data)) + { + key_len = strlen (key); + mykey = g_strdup (key); + + item = gvdb_hash_table_insert (table, key); + gvdb_item_set_parent (item, + get_parent (table, mykey, key_len)); + + g_free (mykey); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(uuay)")); + + g_variant_builder_add (&builder, "u", data->size); /* Size */ + g_variant_builder_add (&builder, "u", data->flags); /* Flags */ + + v_data = g_variant_new_from_data (G_VARIANT_TYPE("ay"), + data->content, data->content_size, TRUE, + g_free, data->content); + g_variant_builder_add_value (&builder, v_data); + data->content = NULL; /* Take ownership */ + + gvdb_item_set_value (item, + g_variant_builder_end (&builder)); + } + } + + g_hash_table_unref (state.table); + g_markup_parse_context_free (context); + g_free (contents); + + return table; +} + +static gboolean +write_to_file (GHashTable *table, + const gchar *filename, + GError **error) +{ + gboolean success; + + success = gvdb_table_write_contents (table, filename, + G_BYTE_ORDER != G_LITTLE_ENDIAN, + error); + + return success; +} + +static gboolean +extension_in_set (const char *str, + ...) +{ + va_list list; + const char *ext, *value; + gboolean rv = FALSE; + + ext = strrchr (str, '.'); + if (ext == NULL) + return FALSE; + + ext++; + va_start (list, str); + while ((value = va_arg (list, const char *)) != NULL) + { + if (g_ascii_strcasecmp (ext, value) != 0) + continue; + + rv = TRUE; + break; + } + + va_end (list); + return rv; +} + +/* + * We must escape any characters that `make` finds significant. + * This is largely a duplicate of the logic in gcc's `mkdeps.c:munge()`. + */ +static char * +escape_makefile_string (const char *string) +{ + GString *str; + const char *p, *q; + + str = g_string_sized_new (strlen (string) + 1); + for (p = string; *p != '\0'; ++p) + { + switch (*p) + { + case ' ': + case '\t': + /* GNU make uses a weird quoting scheme for white space. + A space or tab preceded by 2N+1 backslashes represents + N backslashes followed by space; a space or tab + preceded by 2N backslashes represents N backslashes at + the end of a file name; and backslashes in other + contexts should not be doubled. */ + for (q = p - 1; string <= q && *q == '\\'; q--) + g_string_append_c (str, '\\'); + g_string_append_c (str, '\\'); + break; + + case '$': + g_string_append_c (str, '$'); + break; + + case '#': + g_string_append_c (str, '\\'); + break; + } + g_string_append_c (str, *p); + } + + return g_string_free (str, FALSE); +} + +typedef enum { + COMPILER_GCC, + COMPILER_CLANG, + COMPILER_MSVC, + COMPILER_UNKNOWN +} CompilerType; + +/* Get the compiler id from the platform, environment, or command line + * + * Keep compiler IDs consistent with https://mesonbuild.com/Reference-tables.html#compiler-ids + * for simplicity + */ +static CompilerType +get_compiler_id (const char *compiler) +{ + char *base, *ext_p; + CompilerType compiler_type; + + if (compiler == NULL) + { +#ifdef G_OS_UNIX + const char *compiler_env = g_getenv ("CC"); + +# ifdef __APPLE__ + if (compiler_env == NULL || *compiler_env == '\0') + compiler = "clang"; + else + compiler = compiler_env; +# elif __linux__ + if (compiler_env == NULL || *compiler_env == '\0') + compiler = "gcc"; + else + compiler = compiler_env; +# else + if (compiler_env == NULL || *compiler_env == '\0') + compiler = "unknown"; + else + compiler = compiler_env; +# endif +#endif + +#ifdef G_OS_WIN32 + if (g_getenv ("MSYSTEM") != NULL) + { + const char *compiler_env = g_getenv ("CC"); + + if (compiler_env == NULL || *compiler_env == '\0') + compiler = "gcc"; + else + compiler = compiler_env; + } + else + compiler = "msvc"; +#endif + } + + base = g_path_get_basename (compiler); + ext_p = strrchr (base, '.'); + if (ext_p != NULL) + { + gsize offset = ext_p - base; + base[offset] = '\0'; + } + + compiler = base; + + if (g_strcmp0 (compiler, "gcc") == 0) + compiler_type = COMPILER_GCC; + else if (g_strcmp0 (compiler, "clang") == 0) + compiler_type = COMPILER_CLANG; + else if (g_strcmp0 (compiler, "msvc") == 0) + compiler_type = COMPILER_MSVC; + else + compiler_type = COMPILER_UNKNOWN; + + g_free (base); + + return compiler_type; +} + +int +main (int argc, char **argv) +{ + GError *error; + GHashTable *table; + GHashTable *files; + gchar *srcfile; + gboolean show_version_and_exit = FALSE; + gchar *target = NULL; + gchar *binary_target = NULL; + gboolean generate_automatic = FALSE; + gboolean generate_source = FALSE; + gboolean generate_header = FALSE; + gboolean manual_register = FALSE; + gboolean internal = FALSE; + gboolean external_data = FALSE; + gboolean generate_dependencies = FALSE; + gboolean generate_phony_targets = FALSE; + char *dependency_file = NULL; + char *c_name = NULL; + char *c_name_no_underscores; + const char *linkage = "extern"; + char *compiler = NULL; + CompilerType compiler_type = COMPILER_GCC; + GOptionContext *context; + GOptionEntry entries[] = { + { "version", 0, 0, G_OPTION_ARG_NONE, &show_version_and_exit, N_("Show program version and exit"), NULL }, + { "target", 0, 0, G_OPTION_ARG_FILENAME, &target, N_("Name of the output file"), N_("FILE") }, + { "sourcedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &sourcedirs, N_("The directories to load files referenced in FILE from (default: current directory)"), N_("DIRECTORY") }, + { "generate", 0, 0, G_OPTION_ARG_NONE, &generate_automatic, N_("Generate output in the format selected for by the target filename extension"), NULL }, + { "generate-header", 0, 0, G_OPTION_ARG_NONE, &generate_header, N_("Generate source header"), NULL }, + { "generate-source", 0, 0, G_OPTION_ARG_NONE, &generate_source, N_("Generate source code used to link in the resource file into your code"), NULL }, + { "generate-dependencies", 0, 0, G_OPTION_ARG_NONE, &generate_dependencies, N_("Generate dependency list"), NULL }, + { "dependency-file", 0, 0, G_OPTION_ARG_FILENAME, &dependency_file, N_("Name of the dependency file to generate"), N_("FILE") }, + { "generate-phony-targets", 0, 0, G_OPTION_ARG_NONE, &generate_phony_targets, N_("Include phony targets in the generated dependency file"), NULL }, + { "manual-register", 0, 0, G_OPTION_ARG_NONE, &manual_register, N_("Don’t automatically create and register resource"), NULL }, + { "internal", 0, 0, G_OPTION_ARG_NONE, &internal, N_("Don’t export functions; declare them G_GNUC_INTERNAL"), NULL }, + { "external-data", 0, 0, G_OPTION_ARG_NONE, &external_data, N_("Don’t embed resource data in the C file; assume it's linked externally instead"), NULL }, + { "c-name", 0, 0, G_OPTION_ARG_STRING, &c_name, N_("C identifier name used for the generated source code"), NULL }, + { "compiler", 'C', 0, G_OPTION_ARG_STRING, &compiler, N_("The target C compiler (default: the CC environment variable)"), NULL }, + G_OPTION_ENTRY_NULL + }; + +#ifdef G_OS_WIN32 + gchar *tmp; +#endif + + setlocale (LC_ALL, GLIB_DEFAULT_LOCALE); + textdomain (GETTEXT_PACKAGE); + +#ifdef G_OS_WIN32 + tmp = _glib_get_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, tmp); + g_free (tmp); +#else + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#endif + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + + context = g_option_context_new (N_("FILE")); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_set_summary (context, + N_("Compile a resource specification into a resource file.\n" + "Resource specification files have the extension .gresource.xml,\n" + "and the resource file have the extension called .gresource.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + error = NULL; + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s\n", error->message); + return 1; + } + + g_option_context_free (context); + + if (show_version_and_exit) + { + g_print (PACKAGE_VERSION "\n"); + return 0; + } + + if (argc != 2) + { + g_printerr (_("You should give exactly one file name\n")); + g_free (c_name); + return 1; + } + + if (internal) + linkage = "G_GNUC_INTERNAL"; + + compiler_type = get_compiler_id (compiler); + g_free (compiler); + + srcfile = argv[1]; + + xmllint = g_strdup (g_getenv ("XMLLINT")); + if (xmllint == NULL) + xmllint = g_find_program_in_path ("xmllint"); + + jsonformat = g_strdup (g_getenv ("JSON_GLIB_FORMAT")); + if (jsonformat == NULL) + jsonformat = g_find_program_in_path ("json-glib-format"); + + gdk_pixbuf_pixdata = g_strdup (g_getenv ("GDK_PIXBUF_PIXDATA")); + if (gdk_pixbuf_pixdata == NULL) + gdk_pixbuf_pixdata = g_find_program_in_path ("gdk-pixbuf-pixdata"); + + if (target == NULL) + { + char *dirname = g_path_get_dirname (srcfile); + char *base = g_path_get_basename (srcfile); + char *target_basename; + if (g_str_has_suffix (base, ".xml")) + base[strlen(base) - strlen (".xml")] = 0; + + if (generate_source) + { + if (g_str_has_suffix (base, ".gresource")) + base[strlen(base) - strlen (".gresource")] = 0; + target_basename = g_strconcat (base, ".c", NULL); + } + else if (generate_header) + { + if (g_str_has_suffix (base, ".gresource")) + base[strlen(base) - strlen (".gresource")] = 0; + target_basename = g_strconcat (base, ".h", NULL); + } + else + { + if (g_str_has_suffix (base, ".gresource")) + target_basename = g_strdup (base); + else + target_basename = g_strconcat (base, ".gresource", NULL); + } + + target = g_build_filename (dirname, target_basename, NULL); + g_free (target_basename); + g_free (dirname); + g_free (base); + } + else if (generate_automatic) + { + if (extension_in_set (target, "c", "cc", "cpp", "cxx", "c++", NULL)) + generate_source = TRUE; + else if (extension_in_set (target, "h", "hh", "hpp", "hxx", "h++", NULL)) + generate_header = TRUE; + else if (extension_in_set (target, "gresource", NULL)) + { } + } + + files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)file_data_free); + + if ((table = parse_resource_file (srcfile, !generate_dependencies, files)) == NULL) + { + g_free (target); + g_free (c_name); + g_hash_table_unref (files); + return 1; + } + + /* This can be used in the same invocation + as other generate commands */ + if (dependency_file != NULL) + { + /* Generate a .d file that describes the dependencies for + * build tools, gcc -M -MF style */ + GString *dep_string; + GHashTableIter iter; + gpointer key, data; + FileData *file_data; + char *escaped; + + g_hash_table_iter_init (&iter, files); + + dep_string = g_string_new (NULL); + escaped = escape_makefile_string (srcfile); + g_string_printf (dep_string, "%s:", escaped); + g_free (escaped); + + /* First rule: foo.xml: resource1 resource2.. */ + while (g_hash_table_iter_next (&iter, &key, &data)) + { + file_data = data; + if (!g_str_equal (file_data->filename, srcfile)) + { + escaped = escape_makefile_string (file_data->filename); + g_string_append_printf (dep_string, " %s", escaped); + g_free (escaped); + } + } + + g_string_append (dep_string, "\n"); + + /* Optionally include phony targets as it silences `make` but + * isn't supported on `ninja` at the moment. See also: `gcc -MP` + */ + if (generate_phony_targets) + { + g_string_append (dep_string, "\n"); + + /* One rule for every resource: resourceN: */ + g_hash_table_iter_init (&iter, files); + while (g_hash_table_iter_next (&iter, &key, &data)) + { + file_data = data; + if (!g_str_equal (file_data->filename, srcfile)) + { + escaped = escape_makefile_string (file_data->filename); + g_string_append_printf (dep_string, "%s:\n\n", escaped); + g_free (escaped); + } + } + } + + if (g_str_equal (dependency_file, "-")) + { + g_print ("%s\n", dep_string->str); + } + else + { + if (!g_file_set_contents (dependency_file, dep_string->str, dep_string->len, &error)) + { + g_printerr ("Error writing dependency file: %s\n", error->message); + g_string_free (dep_string, TRUE); + g_free (dependency_file); + g_error_free (error); + g_hash_table_unref (files); + return 1; + } + } + + g_string_free (dep_string, TRUE); + g_free (dependency_file); + } + + if (generate_dependencies) + { + GHashTableIter iter; + gpointer key, data; + FileData *file_data; + + g_hash_table_iter_init (&iter, files); + + /* Generate list of files for direct use as dependencies in a Makefile */ + while (g_hash_table_iter_next (&iter, &key, &data)) + { + file_data = data; + g_print ("%s\n", file_data->filename); + } + } + else if (generate_source || generate_header) + { + if (generate_source) + { + int fd = g_file_open_tmp (NULL, &binary_target, NULL); + if (fd == -1) + { + g_printerr ("Can't open temp file\n"); + g_free (c_name); + g_hash_table_unref (files); + return 1; + } + close (fd); + } + + if (c_name == NULL) + { + char *base = g_path_get_basename (srcfile); + GString *s; + char *dot; + int i; + + /* Remove extensions */ + dot = strchr (base, '.'); + if (dot) + *dot = 0; + + s = g_string_new (""); + + for (i = 0; base[i] != 0; i++) + { + const char *first = G_CSET_A_2_Z G_CSET_a_2_z "_"; + const char *rest = G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_"; + if (strchr ((s->len == 0) ? first : rest, base[i]) != NULL) + g_string_append_c (s, base[i]); + else if (base[i] == '-') + g_string_append_c (s, '_'); + + } + + g_free (base); + c_name = g_string_free (s, FALSE); + } + } + else + binary_target = g_strdup (target); + + c_name_no_underscores = c_name; + while (c_name_no_underscores && *c_name_no_underscores == '_') + c_name_no_underscores++; + + if (binary_target != NULL && + !write_to_file (table, binary_target, &error)) + { + g_printerr ("%s\n", error->message); + g_free (target); + g_free (c_name); + g_hash_table_unref (files); + return 1; + } + + if (generate_header) + { + FILE *file; + + file = fopen (target, "w"); + if (file == NULL) + { + g_printerr ("can't write to file %s", target); + g_free (c_name); + g_hash_table_unref (files); + return 1; + } + + g_fprintf (file, + "#ifndef __RESOURCE_%s_H__\n" + "#define __RESOURCE_%s_H__\n" + "\n" + "#include \n" + "\n" + "%s GResource *%s_get_resource (void);\n", + c_name, c_name, linkage, c_name); + + if (manual_register) + g_fprintf (file, + "\n" + "%s void %s_register_resource (void);\n" + "%s void %s_unregister_resource (void);\n" + "\n", + linkage, c_name, linkage, c_name); + + g_fprintf (file, + "#endif\n"); + + fclose (file); + } + else if (generate_source) + { + FILE *file; + guint8 *data; + gsize data_size; + gsize i; + const char *export = "G_MODULE_EXPORT"; + + if (!g_file_get_contents (binary_target, (char **)&data, + &data_size, NULL)) + { + g_printerr ("can't read back temporary file"); + g_free (c_name); + g_hash_table_unref (files); + return 1; + } + g_unlink (binary_target); + + file = fopen (target, "w"); + if (file == NULL) + { + g_printerr ("can't write to file %s", target); + g_free (c_name); + g_hash_table_unref (files); + return 1; + } + + if (internal) + export = "G_GNUC_INTERNAL"; + + g_fprintf (file, + "#include \n" + "\n" + "#if defined (__ELF__) && ( __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6))\n" + "# define SECTION __attribute__ ((section (\".gresource.%s\"), aligned (8)))\n" + "#else\n" + "# define SECTION\n" + "#endif\n" + "\n", + c_name_no_underscores); + + if (external_data) + { + g_fprintf (file, + "extern const SECTION union { const guint8 data[%"G_GSIZE_FORMAT"]; const double alignment; void * const ptr;} %s_resource_data;" + "\n", + data_size, c_name); + } + else + { + if (compiler_type == COMPILER_MSVC || compiler_type == COMPILER_UNKNOWN) + { + /* For Visual Studio builds: Avoid surpassing the 65535-character limit for a string, GitLab issue #1580 */ + g_fprintf (file, + "static const SECTION union { const guint8 data[%"G_GSIZE_FORMAT"]; const double alignment; void * const ptr;} %s_resource_data = { {\n", + data_size + 1 /* nul terminator */, c_name); + + for (i = 0; i < data_size; i++) + { + if (i % 16 == 0) + g_fprintf (file, " "); + g_fprintf (file, "0%3.3o", (int)data[i]); + if (i != data_size - 1) + g_fprintf (file, ", "); + if (i % 16 == 15 || i == data_size - 1) + g_fprintf (file, "\n"); + } + + g_fprintf (file, "} };\n"); + } + else + { + g_fprintf (file, + "static const SECTION union { const guint8 data[%"G_GSIZE_FORMAT"]; const double alignment; void * const ptr;} %s_resource_data = {\n \"", + data_size + 1 /* nul terminator */, c_name); + + for (i = 0; i < data_size; i++) + { + g_fprintf (file, "\\%3.3o", (int)data[i]); + if (i % 16 == 15) + g_fprintf (file, "\"\n \""); + } + + g_fprintf (file, "\" };\n"); + } + } + + g_fprintf (file, + "\n" + "static GStaticResource static_resource = { %s_resource_data.data, sizeof (%s_resource_data.data)%s, NULL, NULL, NULL };\n" + "\n" + "%s\n" + "GResource *%s_get_resource (void);\n" + "GResource *%s_get_resource (void)\n" + "{\n" + " return g_static_resource_get_resource (&static_resource);\n" + "}\n", + c_name, c_name, (external_data ? "" : " - 1 /* nul terminator */"), + export, c_name, c_name); + + + if (manual_register) + { + g_fprintf (file, + "\n" + "%s\n" + "void %s_unregister_resource (void);\n" + "void %s_unregister_resource (void)\n" + "{\n" + " g_static_resource_fini (&static_resource);\n" + "}\n" + "\n" + "%s\n" + "void %s_register_resource (void);\n" + "void %s_register_resource (void)\n" + "{\n" + " g_static_resource_init (&static_resource);\n" + "}\n", + export, c_name, c_name, + export, c_name, c_name); + } + else + { + g_fprintf (file, "%s", gconstructor_code); + g_fprintf (file, + "\n" + "#ifdef G_HAS_CONSTRUCTORS\n" + "\n" + "#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA\n" + "#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(%sresource_constructor)\n" + "#endif\n" + "G_DEFINE_CONSTRUCTOR(%sresource_constructor)\n" + "#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA\n" + "#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(%sresource_destructor)\n" + "#endif\n" + "G_DEFINE_DESTRUCTOR(%sresource_destructor)\n" + "\n" + "#else\n" + "#warning \"Constructor not supported on this compiler, linking in resources will not work\"\n" + "#endif\n" + "\n" + "static void %sresource_constructor (void)\n" + "{\n" + " g_static_resource_init (&static_resource);\n" + "}\n" + "\n" + "static void %sresource_destructor (void)\n" + "{\n" + " g_static_resource_fini (&static_resource);\n" + "}\n", + c_name, c_name, c_name, + c_name, c_name, c_name); + } + + fclose (file); + + g_free (data); + } + + g_free (binary_target); + g_free (target); + g_hash_table_destroy (table); + g_free (xmllint); + g_free (jsonformat); + g_free (c_name); + g_hash_table_unref (files); + + return 0; +} diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c new file mode 100644 index 0000000..83184e1 --- /dev/null +++ b/gio/glib-compile-schemas.c @@ -0,0 +1,2331 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +/* Prologue {{{1 */ +#include "config.h" + +#include +#include + +#include +#include +#include + +#include "gvdb/gvdb-builder.h" +#include "strinfo.c" +#include "glib/glib-private.h" + +static void +strip_string (GString *string) +{ + gint i; + + for (i = 0; g_ascii_isspace (string->str[i]); i++); + g_string_erase (string, 0, i); + + if (string->len > 0) + { + /* len > 0, so there must be at least one non-whitespace character */ + for (i = string->len - 1; g_ascii_isspace (string->str[i]); i--); + g_string_truncate (string, i + 1); + } +} + +/* Handling of {{{1 */ +typedef struct +{ + GString *strinfo; + + gboolean is_flags; +} EnumState; + +static void +enum_state_free (gpointer data) +{ + EnumState *state = data; + + g_string_free (state->strinfo, TRUE); + g_slice_free (EnumState, state); +} + +static EnumState * +enum_state_new (gboolean is_flags) +{ + EnumState *state; + + state = g_slice_new (EnumState); + state->strinfo = g_string_new (NULL); + state->is_flags = is_flags; + + return state; +} + +static void +enum_state_add_value (EnumState *state, + const gchar *nick, + const gchar *valuestr, + GError **error) +{ + gint64 value; + gchar *end; + + if (nick[0] == '\0' || nick[1] == '\0') + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("nick must be a minimum of 2 characters")); + return; + } + + value = g_ascii_strtoll (valuestr, &end, 0); + if (*end || (state->is_flags ? + (value > G_MAXUINT32 || value < 0) : + (value > G_MAXINT32 || value < G_MININT32))) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid numeric value")); + return; + } + + if (strinfo_builder_contains (state->strinfo, nick)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), nick); + return; + } + + if (strinfo_builder_contains_value (state->strinfo, value)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("value='%s' already specified"), valuestr); + return; + } + + /* Silently drop the null case if it is mentioned. + * It is properly denoted with an empty array. + */ + if (state->is_flags && value == 0) + return; + + if (state->is_flags && (value & (value - 1))) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("flags values must have at most 1 bit set")); + return; + } + + /* Since we reject exact duplicates of value='' and we only allow one + * bit to be set, it's not possible to have overlaps. + * + * If we loosen the one-bit-set restriction we need an overlap check. + */ + + strinfo_builder_append_item (state->strinfo, nick, value); +} + +static void +enum_state_end (EnumState **state_ptr, + GError **error) +{ + EnumState *state; + + state = *state_ptr; + *state_ptr = NULL; + + if (state->strinfo->len == 0) + g_set_error (error, + G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> must contain at least one "), + state->is_flags ? "flags" : "enum"); +} + +/* Handling of {{{1 */ +typedef struct +{ + /* for , @child_schema will be set. + * for , everything else will be set. + */ + gchar *child_schema; + + + GVariantType *type; + gboolean have_gettext_domain; + + gchar l10n; + gchar *l10n_context; + GString *unparsed_default_value; + GVariant *default_value; + + GVariantDict *desktop_overrides; + + GString *strinfo; + gboolean is_enum; + gboolean is_flags; + + GVariant *minimum; + GVariant *maximum; + + gboolean has_choices; + gboolean has_aliases; + gboolean is_override; + + gboolean checked; + GVariant *serialised; + + gboolean summary_seen; + gboolean description_seen; +} KeyState; + +static KeyState * +key_state_new (const gchar *type_string, + const gchar *gettext_domain, + gboolean is_enum, + gboolean is_flags, + GString *strinfo) +{ + KeyState *state; + + state = g_slice_new0 (KeyState); + state->type = g_variant_type_new (type_string); + state->have_gettext_domain = gettext_domain != NULL; + state->is_enum = is_enum; + state->is_flags = is_flags; + state->summary_seen = FALSE; + state->description_seen = FALSE; + + if (strinfo) + state->strinfo = g_string_new_len (strinfo->str, strinfo->len); + else + state->strinfo = g_string_new (NULL); + + return state; +} + +static KeyState * +key_state_override (KeyState *state, + const gchar *gettext_domain) +{ + KeyState *copy; + + copy = g_slice_new0 (KeyState); + copy->type = g_variant_type_copy (state->type); + copy->have_gettext_domain = gettext_domain != NULL; + copy->strinfo = g_string_new_len (state->strinfo->str, + state->strinfo->len); + copy->is_enum = state->is_enum; + copy->is_flags = state->is_flags; + copy->is_override = TRUE; + + if (state->minimum) + { + copy->minimum = g_variant_ref (state->minimum); + copy->maximum = g_variant_ref (state->maximum); + } + + return copy; +} + +static KeyState * +key_state_new_child (const gchar *child_schema) +{ + KeyState *state; + + state = g_slice_new0 (KeyState); + state->child_schema = g_strdup (child_schema); + + return state; +} + +static gboolean +is_valid_choices (GVariant *variant, + GString *strinfo) +{ + switch (g_variant_classify (variant)) + { + case G_VARIANT_CLASS_MAYBE: + case G_VARIANT_CLASS_ARRAY: + { + gboolean valid = TRUE; + GVariantIter iter; + + g_variant_iter_init (&iter, variant); + + while (valid && (variant = g_variant_iter_next_value (&iter))) + { + valid = is_valid_choices (variant, strinfo); + g_variant_unref (variant); + } + + return valid; + } + + case G_VARIANT_CLASS_STRING: + return strinfo_is_string_valid ((const guint32 *) strinfo->str, + strinfo->len / 4, + g_variant_get_string (variant, NULL)); + + default: + g_assert_not_reached (); + } +} + + +/* Gets called at or to check for + * validity of the default value so that any inconsistency is + * reported as soon as it is encountered. + */ +static void +key_state_check_range (KeyState *state, + GError **error) +{ + if (state->default_value) + { + const gchar *tag; + + tag = state->is_override ? "override" : "default"; + + if (state->minimum) + { + if (g_variant_compare (state->default_value, state->minimum) < 0 || + g_variant_compare (state->default_value, state->maximum) > 0) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> is not contained in " + "the specified range"), tag); + } + } + + else if (state->strinfo->len) + { + if (!is_valid_choices (state->default_value, state->strinfo)) + { + if (state->is_enum) + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> is not a valid member of " + "the specified enumerated type"), tag); + + else if (state->is_flags) + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> contains string not in the " + "specified flags type"), tag); + + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> contains a string not in " + ""), tag); + } + } + } +} + +static void +key_state_set_range (KeyState *state, + const gchar *min_str, + const gchar *max_str, + GError **error) +{ + const struct { + const gchar type; + const gchar *min; + const gchar *max; + } table[] = { + { 'y', "0", "255" }, + { 'n', "-32768", "32767" }, + { 'q', "0", "65535" }, + { 'i', "-2147483648", "2147483647" }, + { 'u', "0", "4294967295" }, + { 'x', "-9223372036854775808", "9223372036854775807" }, + { 't', "0", "18446744073709551615" }, + { 'd', "-inf", "inf" }, + }; + gboolean type_ok = FALSE; + gsize i; + + if (state->minimum) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified for this key")); + return; + } + + for (i = 0; i < G_N_ELEMENTS (table); i++) + if (*(char *) state->type == table[i].type) + { + min_str = min_str ? min_str : table[i].min; + max_str = max_str ? max_str : table[i].max; + type_ok = TRUE; + break; + } + + if (!type_ok) + { + gchar *type = g_variant_type_dup_string (state->type); + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" not allowed for keys of type “%sâ€"), type); + g_free (type); + return; + } + + state->minimum = g_variant_parse (state->type, min_str, NULL, NULL, error); + if (state->minimum == NULL) + return; + + state->maximum = g_variant_parse (state->type, max_str, NULL, NULL, error); + if (state->maximum == NULL) + return; + + if (g_variant_compare (state->minimum, state->maximum) > 0) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" specified minimum is greater than maximum")); + return; + } + + key_state_check_range (state, error); +} + +static GString * +key_state_start_default (KeyState *state, + const gchar *l10n, + const gchar *context, + GError **error) +{ + if (l10n != NULL) + { + if (strcmp (l10n, "messages") == 0) + state->l10n = 'm'; + + else if (strcmp (l10n, "time") == 0) + state->l10n = 't'; + + else + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("unsupported l10n category: %s"), l10n); + return NULL; + } + + if (!state->have_gettext_domain) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("l10n requested, but no " + "gettext domain given")); + return NULL; + } + + state->l10n_context = g_strdup (context); + } + + else if (context != NULL) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("translation context given for " + "value without l10n enabled")); + return NULL; + } + + return g_string_new (NULL); +} + +static void +key_state_end_default (KeyState *state, + GString **string, + GError **error) +{ + state->unparsed_default_value = *string; + *string = NULL; + + state->default_value = g_variant_parse (state->type, + state->unparsed_default_value->str, + NULL, NULL, error); + if (!state->default_value) + { + gchar *type = g_variant_type_dup_string (state->type); + g_prefix_error (error, _("Failed to parse value of type “%sâ€: "), type); + g_free (type); + } + + key_state_check_range (state, error); +} + +static void +key_state_start_choices (KeyState *state, + GError **error) +{ + const GVariantType *type = state->type; + + if (state->is_enum) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" cannot be specified for keys " + "tagged as having an enumerated type")); + return; + } + + if (state->has_choices) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified for this key")); + return; + } + + while (g_variant_type_is_maybe (type) || g_variant_type_is_array (type)) + type = g_variant_type_element (type); + + if (!g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) + { + gchar *type_string = g_variant_type_dup_string (state->type); + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" not allowed for keys of type “%sâ€"), + type_string); + g_free (type_string); + return; + } +} + +static void +key_state_add_choice (KeyState *state, + const gchar *choice, + GError **error) +{ + if (strinfo_builder_contains (state->strinfo, choice)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already given"), choice); + return; + } + + strinfo_builder_append_item (state->strinfo, choice, 0); + state->has_choices = TRUE; +} + +static void +key_state_end_choices (KeyState *state, + GError **error) +{ + if (!state->has_choices) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _(" must contain at least one ")); + return; + } + + key_state_check_range (state, error); +} + +static void +key_state_start_aliases (KeyState *state, + GError **error) +{ + if (state->has_aliases) + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified for this key")); + else if (!state->is_flags && !state->is_enum && !state->has_choices) + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" can only be specified for keys with " + "enumerated or flags types or after ")); +} + +static void +key_state_add_alias (KeyState *state, + const gchar *alias, + const gchar *target, + GError **error) +{ + if (strinfo_builder_contains (state->strinfo, alias)) + { + if (strinfo_is_string_valid ((guint32 *) state->strinfo->str, + state->strinfo->len / 4, + alias)) + { + if (state->is_enum) + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" given when “%s†is already " + "a member of the enumerated type"), alias, alias); + + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" given when " + " was already given"), + alias, alias); + } + + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), alias); + + return; + } + + if (!strinfo_builder_append_alias (state->strinfo, alias, target)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + state->is_enum ? + _("alias target “%s†is not in enumerated type") : + _("alias target “%s†is not in "), + target); + return; + } + + state->has_aliases = TRUE; +} + +static void +key_state_end_aliases (KeyState *state, + GError **error) +{ + if (!state->has_aliases) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _(" must contain at least one ")); + return; + } +} + +static gboolean +key_state_check (KeyState *state, + GError **error) +{ + if (state->checked) + return TRUE; + + return state->checked = TRUE; +} + +static GVariant * +key_state_serialise (KeyState *state) +{ + if (state->serialised == NULL) + { + if (state->child_schema) + { + state->serialised = g_variant_new_string (state->child_schema); + } + + else + { + GVariantBuilder builder; + gboolean checked G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + checked = key_state_check (state, NULL); + g_assert (checked); + + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + + /* default value */ + g_variant_builder_add_value (&builder, state->default_value); + + /* translation */ + if (state->l10n) + { + /* We are going to store the untranslated default for + * runtime translation according to the current locale. + * We need to strip leading and trailing whitespace from + * the string so that it's exactly the same as the one + * that ended up in the .po file for translation. + * + * We want to do this so that + * + * + * ['a', 'b', 'c'] + * + * + * ends up in the .po file like "['a', 'b', 'c']", + * omitting the extra whitespace at the start and end. + */ + strip_string (state->unparsed_default_value); + + if (state->l10n_context) + { + gint len; + + /* Contextified messages are supported by prepending + * the context, followed by '\004' to the start of the + * message string. We do that here to save GSettings + * the work later on. + */ + len = strlen (state->l10n_context); + state->l10n_context[len] = '\004'; + g_string_prepend_len (state->unparsed_default_value, + state->l10n_context, len + 1); + g_free (state->l10n_context); + state->l10n_context = NULL; + } + + g_variant_builder_add (&builder, "(y(y&s))", 'l', state->l10n, + state->unparsed_default_value->str); + g_string_free (state->unparsed_default_value, TRUE); + state->unparsed_default_value = NULL; + } + + /* choice, aliases, enums */ + if (state->strinfo->len) + { + GVariant *array; + guint32 *words; + gpointer data; + gsize size; + gsize i; + + data = state->strinfo->str; + size = state->strinfo->len; + + words = data; + for (i = 0; i < size / sizeof (guint32); i++) + words[i] = GUINT32_TO_LE (words[i]); + + array = g_variant_new_from_data (G_VARIANT_TYPE ("au"), + data, size, TRUE, + g_free, data); + + g_string_free (state->strinfo, FALSE); + state->strinfo = NULL; + + g_variant_builder_add (&builder, "(y@au)", + state->is_flags ? 'f' : + state->is_enum ? 'e' : 'c', + array); + } + + /* range */ + if (state->minimum || state->maximum) + g_variant_builder_add (&builder, "(y(**))", 'r', + state->minimum, state->maximum); + + /* per-desktop overrides */ + if (state->desktop_overrides) + g_variant_builder_add (&builder, "(y@a{sv})", 'd', + g_variant_dict_end (state->desktop_overrides)); + + state->serialised = g_variant_builder_end (&builder); + } + + g_variant_ref_sink (state->serialised); + } + + return g_variant_ref (state->serialised); +} + +static void +key_state_free (gpointer data) +{ + KeyState *state = data; + + g_free (state->child_schema); + + if (state->type) + g_variant_type_free (state->type); + + g_free (state->l10n_context); + + if (state->unparsed_default_value) + g_string_free (state->unparsed_default_value, TRUE); + + if (state->default_value) + g_variant_unref (state->default_value); + + if (state->strinfo) + g_string_free (state->strinfo, TRUE); + + if (state->minimum) + g_variant_unref (state->minimum); + + if (state->maximum) + g_variant_unref (state->maximum); + + if (state->serialised) + g_variant_unref (state->serialised); + + if (state->desktop_overrides) + g_variant_dict_unref (state->desktop_overrides); + + g_slice_free (KeyState, state); +} + +/* Key name validity {{{1 */ +static gboolean allow_any_name = FALSE; + +static gboolean +is_valid_keyname (const gchar *key, + GError **error) +{ + gint i; + + if (key[0] == '\0') + { + g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Empty names are not permitted")); + return FALSE; + } + + if (allow_any_name) + return TRUE; + + if (!g_ascii_islower (key[0])) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%sâ€: names must begin " + "with a lowercase letter"), key); + return FALSE; + } + + for (i = 1; key[i]; i++) + { + if (key[i] != '-' && + !g_ascii_islower (key[i]) && + !g_ascii_isdigit (key[i])) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%sâ€: invalid character “%câ€; " + "only lowercase letters, numbers and hyphen (“-â€) " + "are permitted"), key, key[i]); + return FALSE; + } + + if (key[i] == '-' && key[i + 1] == '-') + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%sâ€: two successive hyphens (“--â€) " + "are not permitted"), key); + return FALSE; + } + } + + if (key[i - 1] == '-') + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%sâ€: the last character may not be a " + "hyphen (“-â€)"), key); + return FALSE; + } + + if (i > 1024) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%sâ€: maximum length is 1024"), key); + return FALSE; + } + + return TRUE; +} + +/* Handling of {{{1 */ +typedef struct _SchemaState SchemaState; +struct _SchemaState +{ + SchemaState *extends; + + gchar *path; + gchar *gettext_domain; + gchar *extends_name; + gchar *list_of; + + GHashTable *keys; +}; + +static SchemaState * +schema_state_new (const gchar *path, + const gchar *gettext_domain, + SchemaState *extends, + const gchar *extends_name, + const gchar *list_of) +{ + SchemaState *state; + + state = g_slice_new (SchemaState); + state->path = g_strdup (path); + state->gettext_domain = g_strdup (gettext_domain); + state->extends = extends; + state->extends_name = g_strdup (extends_name); + state->list_of = g_strdup (list_of); + state->keys = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, key_state_free); + + return state; +} + +static void +schema_state_free (gpointer data) +{ + SchemaState *state = data; + + g_free (state->path); + g_free (state->gettext_domain); + g_free (state->extends_name); + g_free (state->list_of); + g_hash_table_unref (state->keys); + g_slice_free (SchemaState, state); +} + +static void +schema_state_add_child (SchemaState *state, + const gchar *name, + const gchar *schema, + GError **error) +{ + gchar *childname; + + if (!is_valid_keyname (name, error)) + return; + + childname = g_strconcat (name, "/", NULL); + + if (g_hash_table_lookup (state->keys, childname)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), name); + return; + } + + g_hash_table_insert (state->keys, childname, + key_state_new_child (schema)); +} + +static KeyState * +schema_state_add_key (SchemaState *state, + GHashTable *enum_table, + GHashTable *flags_table, + const gchar *name, + const gchar *type_string, + const gchar *enum_type, + const gchar *flags_type, + GError **error) +{ + SchemaState *node; + GString *strinfo; + KeyState *key; + + if (state->list_of) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Cannot add keys to a “list-of†schema")); + return NULL; + } + + if (!is_valid_keyname (name, error)) + return NULL; + + if (g_hash_table_lookup (state->keys, name)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), name); + return NULL; + } + + for (node = state; node; node = node->extends) + if (node->extends) + { + KeyState *shadow; + + shadow = g_hash_table_lookup (node->extends->keys, name); + + /* in case of make sure we report the + * location of the original , not the . + */ + if (shadow && !shadow->is_override) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" shadows in " + "; use to modify value"), + name, name, node->extends_name); + return NULL; + } + } + + if ((type_string != NULL) + (enum_type != NULL) + (flags_type != NULL) != 1) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_MISSING_ATTRIBUTE, + _("Exactly one of “typeâ€, “enum†or “flags†must " + "be specified as an attribute to ")); + return NULL; + } + + if (type_string == NULL) /* flags or enums was specified */ + { + EnumState *enum_state; + + if (enum_type) + enum_state = g_hash_table_lookup (enum_table, enum_type); + else + enum_state = g_hash_table_lookup (flags_table, flags_type); + + + if (enum_state == NULL) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s id='%s'> not (yet) defined."), + flags_type ? "flags" : "enum", + flags_type ? flags_type : enum_type); + return NULL; + } + + type_string = flags_type ? "as" : "s"; + strinfo = enum_state->strinfo; + } + else + { + if (!g_variant_type_string_is_valid (type_string)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid GVariant type string “%sâ€"), type_string); + return NULL; + } + + strinfo = NULL; + } + + key = key_state_new (type_string, state->gettext_domain, + enum_type != NULL, flags_type != NULL, strinfo); + g_hash_table_insert (state->keys, g_strdup (name), key); + + return key; +} + +static void +schema_state_add_override (SchemaState *state, + KeyState **key_state, + GString **string, + const gchar *key, + const gchar *l10n, + const gchar *context, + GError **error) +{ + SchemaState *parent; + KeyState *original = NULL; + + if (state->extends == NULL) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" given but schema isn’t " + "extending anything")); + return; + } + + for (parent = state->extends; parent; parent = parent->extends) + if ((original = g_hash_table_lookup (parent->keys, key))) + break; + + if (original == NULL) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("No to override"), key); + return; + } + + if (g_hash_table_lookup (state->keys, key)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), key); + return; + } + + *key_state = key_state_override (original, state->gettext_domain); + *string = key_state_start_default (*key_state, l10n, context, error); + g_hash_table_insert (state->keys, g_strdup (key), *key_state); +} + +static void +override_state_end (KeyState **key_state, + GString **string, + GError **error) +{ + key_state_end_default (*key_state, string, error); + *key_state = NULL; +} + +/* Handling of toplevel state {{{1 */ +typedef struct +{ + gboolean strict; /* TRUE if --strict was given */ + + GHashTable *schema_table; /* string -> SchemaState */ + GHashTable *flags_table; /* string -> EnumState */ + GHashTable *enum_table; /* string -> EnumState */ + + GSList *this_file_schemas; /* strings: s in this file */ + GSList *this_file_flagss; /* strings: s in this file */ + GSList *this_file_enums; /* strings: s in this file */ + + gchar *schemalist_domain; /* the gettext domain */ + + SchemaState *schema_state; /* non-NULL when inside */ + KeyState *key_state; /* non-NULL when inside */ + EnumState *enum_state; /* non-NULL when inside */ + + GString *string; /* non-NULL when accepting text */ +} ParseState; + +static gboolean +is_subclass (const gchar *class_name, + const gchar *possible_parent, + GHashTable *schema_table) +{ + SchemaState *class; + + if (strcmp (class_name, possible_parent) == 0) + return TRUE; + + class = g_hash_table_lookup (schema_table, class_name); + g_assert (class != NULL); + + return class->extends_name && + is_subclass (class->extends_name, possible_parent, schema_table); +} + +static void +parse_state_start_schema (ParseState *state, + const gchar *id, + const gchar *path, + const gchar *gettext_domain, + const gchar *extends_name, + const gchar *list_of, + GError **error) +{ + SchemaState *extends; + gchar *my_id; + + if (g_hash_table_lookup (state->schema_table, id)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), id); + return; + } + + if (extends_name) + { + extends = g_hash_table_lookup (state->schema_table, extends_name); + + if (extends == NULL) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" extends not yet existing " + "schema “%sâ€"), id, extends_name); + return; + } + } + else + extends = NULL; + + if (list_of) + { + SchemaState *tmp; + + if (!(tmp = g_hash_table_lookup (state->schema_table, list_of))) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" is list of not yet existing " + "schema “%sâ€"), id, list_of); + return; + } + + if (tmp->path) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Cannot be a list of a schema with a path")); + return; + } + } + + if (extends) + { + if (extends->path) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Cannot extend a schema with a path")); + return; + } + + if (list_of) + { + if (extends->list_of == NULL) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" is a list, extending " + " which is not a list"), + id, extends_name); + return; + } + + if (!is_subclass (list_of, extends->list_of, state->schema_table)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" extends but “%s†does not " + "extend “%sâ€"), id, list_of, extends_name, + extends->list_of, list_of, extends->list_of); + return; + } + } + else + /* by default we are a list of the same thing that the schema + * we are extending is a list of (which might be nothing) + */ + list_of = extends->list_of; + } + + if (path && !(g_str_has_prefix (path, "/") && g_str_has_suffix (path, "/"))) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("A path, if given, must begin and end with a slash")); + return; + } + + if (path && list_of && !g_str_has_suffix (path, ":/")) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("The path of a list must end with “:/â€")); + return; + } + + if (path && (g_str_has_prefix (path, "/apps/") || + g_str_has_prefix (path, "/desktop/") || + g_str_has_prefix (path, "/system/"))) + { + gchar *message = NULL; + message = g_strdup_printf (_("Warning: Schema “%s†has path “%sâ€. " + "Paths starting with " + "“/apps/â€, “/desktop/†or “/system/†are deprecated."), + id, path); + g_printerr ("%s\n", message); + g_free (message); + } + + state->schema_state = schema_state_new (path, gettext_domain, + extends, extends_name, list_of); + + my_id = g_strdup (id); + state->this_file_schemas = g_slist_prepend (state->this_file_schemas, my_id); + g_hash_table_insert (state->schema_table, my_id, state->schema_state); +} + +static void +parse_state_start_enum (ParseState *state, + const gchar *id, + gboolean is_flags, + GError **error) +{ + GSList **list = is_flags ? &state->this_file_flagss : &state->this_file_enums; + GHashTable *table = is_flags ? state->flags_table : state->enum_table; + gchar *my_id; + + if (g_hash_table_lookup (table, id)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s id='%s'> already specified"), + is_flags ? "flags" : "enum", id); + return; + } + + state->enum_state = enum_state_new (is_flags); + + my_id = g_strdup (id); + *list = g_slist_prepend (*list, my_id); + g_hash_table_insert (table, my_id, state->enum_state); +} + +/* GMarkup Parser Functions {{{1 */ + +/* Start element {{{2 */ +static void +start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + const GSList *element_stack; + const gchar *container; + + element_stack = g_markup_parse_context_get_element_stack (context); + container = element_stack->next ? element_stack->next->data : NULL; + +#define COLLECT(first, ...) \ + g_markup_collect_attributes (element_name, \ + attribute_names, attribute_values, error, \ + first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID) +#define OPTIONAL G_MARKUP_COLLECT_OPTIONAL +#define STRDUP G_MARKUP_COLLECT_STRDUP +#define STRING G_MARKUP_COLLECT_STRING +#define NO_ATTRS() COLLECT (G_MARKUP_COLLECT_INVALID, NULL) + + /* Toplevel items {{{3 */ + if (container == NULL) + { + if (strcmp (element_name, "schemalist") == 0) + { + COLLECT (OPTIONAL | STRDUP, + "gettext-domain", + &state->schemalist_domain); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "schemalist") == 0) + { + if (strcmp (element_name, "schema") == 0) + { + const gchar *id, *path, *gettext_domain, *extends, *list_of; + if (COLLECT (STRING, "id", &id, + OPTIONAL | STRING, "path", &path, + OPTIONAL | STRING, "gettext-domain", &gettext_domain, + OPTIONAL | STRING, "extends", &extends, + OPTIONAL | STRING, "list-of", &list_of)) + parse_state_start_schema (state, id, path, + gettext_domain ? gettext_domain + : state->schemalist_domain, + extends, list_of, error); + return; + } + + else if (strcmp (element_name, "enum") == 0) + { + const gchar *id; + if (COLLECT (STRING, "id", &id)) + parse_state_start_enum (state, id, FALSE, error); + return; + } + + else if (strcmp (element_name, "flags") == 0) + { + const gchar *id; + if (COLLECT (STRING, "id", &id)) + parse_state_start_enum (state, id, TRUE, error); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "schema") == 0) + { + if (strcmp (element_name, "key") == 0) + { + const gchar *name, *type_string, *enum_type, *flags_type; + + if (COLLECT (STRING, "name", &name, + OPTIONAL | STRING, "type", &type_string, + OPTIONAL | STRING, "enum", &enum_type, + OPTIONAL | STRING, "flags", &flags_type)) + + state->key_state = schema_state_add_key (state->schema_state, + state->enum_table, + state->flags_table, + name, type_string, + enum_type, flags_type, + error); + return; + } + else if (strcmp (element_name, "child") == 0) + { + const gchar *name, *schema; + + if (COLLECT (STRING, "name", &name, STRING, "schema", &schema)) + schema_state_add_child (state->schema_state, + name, schema, error); + return; + } + else if (strcmp (element_name, "override") == 0) + { + const gchar *name, *l10n, *str_context; + + if (COLLECT (STRING, "name", &name, + OPTIONAL | STRING, "l10n", &l10n, + OPTIONAL | STRING, "context", &str_context)) + schema_state_add_override (state->schema_state, + &state->key_state, &state->string, + name, l10n, str_context, error); + return; + } + } + + /* children of {{{3 */ + else if (strcmp (container, "key") == 0) + { + if (strcmp (element_name, "default") == 0) + { + const gchar *l10n, *str_context; + if (COLLECT (STRING | OPTIONAL, "l10n", &l10n, + STRING | OPTIONAL, "context", &str_context)) + state->string = key_state_start_default (state->key_state, + l10n, str_context, error); + return; + } + + else if (strcmp (element_name, "summary") == 0) + { + if (NO_ATTRS ()) + { + if (state->key_state->summary_seen && state->strict) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Only one <%s> element allowed inside <%s>"), + element_name, container); + else + state->string = g_string_new (NULL); + + state->key_state->summary_seen = TRUE; + } + return; + } + + else if (strcmp (element_name, "description") == 0) + { + if (NO_ATTRS ()) + { + if (state->key_state->description_seen && state->strict) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Only one <%s> element allowed inside <%s>"), + element_name, container); + else + state->string = g_string_new (NULL); + + state->key_state->description_seen = TRUE; + } + return; + } + + else if (strcmp (element_name, "range") == 0) + { + const gchar *min, *max; + if (COLLECT (STRING | OPTIONAL, "min", &min, + STRING | OPTIONAL, "max", &max)) + key_state_set_range (state->key_state, min, max, error); + return; + } + + else if (strcmp (element_name, "choices") == 0) + { + if (NO_ATTRS ()) + key_state_start_choices (state->key_state, error); + return; + } + + else if (strcmp (element_name, "aliases") == 0) + { + if (NO_ATTRS ()) + key_state_start_aliases (state->key_state, error); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "choices") == 0) + { + if (strcmp (element_name, "choice") == 0) + { + const gchar *value; + if (COLLECT (STRING, "value", &value)) + key_state_add_choice (state->key_state, value, error); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "aliases") == 0) + { + if (strcmp (element_name, "alias") == 0) + { + const gchar *value, *target; + if (COLLECT (STRING, "value", &value, STRING, "target", &target)) + key_state_add_alias (state->key_state, value, target, error); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "enum") == 0 || + strcmp (container, "flags") == 0) + { + if (strcmp (element_name, "value") == 0) + { + const gchar *nick, *valuestr; + if (COLLECT (STRING, "nick", &nick, + STRING, "value", &valuestr)) + enum_state_add_value (state->enum_state, nick, valuestr, error); + return; + } + } + /* 3}}} */ + + if (container) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Element <%s> not allowed inside <%s>"), + element_name, container); + else + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Element <%s> not allowed at the top level"), element_name); +} +/* 2}}} */ +/* End element {{{2 */ + +static void +key_state_end (KeyState **state_ptr, + GError **error) +{ + KeyState *state; + + state = *state_ptr; + *state_ptr = NULL; + + if (state->default_value == NULL) + { + g_set_error_literal (error, + G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Element is required in ")); + return; + } +} + +static void +schema_state_end (SchemaState **state_ptr, + GError **error) +{ + *state_ptr = NULL; +} + +static void +end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + + if (strcmp (element_name, "schemalist") == 0) + { + g_free (state->schemalist_domain); + state->schemalist_domain = NULL; + } + + else if (strcmp (element_name, "enum") == 0 || + strcmp (element_name, "flags") == 0) + enum_state_end (&state->enum_state, error); + + else if (strcmp (element_name, "schema") == 0) + schema_state_end (&state->schema_state, error); + + else if (strcmp (element_name, "override") == 0) + override_state_end (&state->key_state, &state->string, error); + + else if (strcmp (element_name, "key") == 0) + key_state_end (&state->key_state, error); + + else if (strcmp (element_name, "default") == 0) + key_state_end_default (state->key_state, &state->string, error); + + else if (strcmp (element_name, "choices") == 0) + key_state_end_choices (state->key_state, error); + + else if (strcmp (element_name, "aliases") == 0) + key_state_end_aliases (state->key_state, error); + + if (state->string) + { + g_string_free (state->string, TRUE); + state->string = NULL; + } +} +/* Text {{{2 */ +static void +text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + + if (state->string) + { + /* we are expecting a string, so store the text data. + * + * we store the data verbatim here and deal with whitespace + * later on. there are two reasons for that: + * + * 1) whitespace is handled differently depending on the tag + * type. + * + * 2) we could do leading whitespace removal by refusing to + * insert it into state->string if it's at the start, but for + * trailing whitespace, we have no idea if there is another + * text() call coming or not. + */ + g_string_append_len (state->string, text, text_len); + } + else + { + /* string is not expected: accept (and ignore) pure whitespace */ + gsize i; + + for (i = 0; i < text_len; i++) + if (!g_ascii_isspace (text[i])) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Text may not appear inside <%s>"), + g_markup_parse_context_get_element (context)); + break; + } + } +} + +/* Write to GVDB {{{1 */ +typedef struct +{ + GHashTable *table; + GvdbItem *root; +} GvdbPair; + +static void +gvdb_pair_init (GvdbPair *pair) +{ + pair->table = gvdb_hash_table_new (NULL, NULL); + pair->root = gvdb_hash_table_insert (pair->table, ""); +} + +static void +gvdb_pair_clear (GvdbPair *pair) +{ + g_hash_table_unref (pair->table); +} + +typedef struct +{ + GHashTable *schema_table; + GvdbPair root_pair; +} WriteToFileData; + +typedef struct +{ + GHashTable *schema_table; + GvdbPair pair; + gboolean l10n; +} OutputSchemaData; + +static void +output_key (gpointer key, + gpointer value, + gpointer user_data) +{ + OutputSchemaData *data; + const gchar *name; + KeyState *state; + GvdbItem *item; + GVariant *serialised = NULL; + + name = key; + state = value; + data = user_data; + + item = gvdb_hash_table_insert (data->pair.table, name); + gvdb_item_set_parent (item, data->pair.root); + serialised = key_state_serialise (state); + gvdb_item_set_value (item, serialised); + g_variant_unref (serialised); + + if (state->l10n) + data->l10n = TRUE; + + if (state->child_schema && + !g_hash_table_lookup (data->schema_table, state->child_schema)) + { + gchar *message = NULL; + message = g_strdup_printf (_("Warning: undefined reference to "), + state->child_schema); + g_printerr ("%s\n", message); + g_free (message); + } +} + +static void +output_schema (gpointer key, + gpointer value, + gpointer user_data) +{ + WriteToFileData *wtf_data = user_data; + OutputSchemaData data; + GvdbPair *root_pair; + SchemaState *state; + const gchar *id; + GvdbItem *item; + + id = key; + state = value; + root_pair = &wtf_data->root_pair; + + data.schema_table = wtf_data->schema_table; + gvdb_pair_init (&data.pair); + data.l10n = FALSE; + + item = gvdb_hash_table_insert (root_pair->table, id); + gvdb_item_set_parent (item, root_pair->root); + gvdb_item_set_hash_table (item, data.pair.table); + + g_hash_table_foreach (state->keys, output_key, &data); + + if (state->path) + gvdb_hash_table_insert_string (data.pair.table, ".path", state->path); + + if (state->extends_name) + gvdb_hash_table_insert_string (data.pair.table, ".extends", + state->extends_name); + + if (state->list_of) + gvdb_hash_table_insert_string (data.pair.table, ".list-of", + state->list_of); + + if (data.l10n) + gvdb_hash_table_insert_string (data.pair.table, + ".gettext-domain", + state->gettext_domain); + + gvdb_pair_clear (&data.pair); +} + +static gboolean +write_to_file (GHashTable *schema_table, + const gchar *filename, + GError **error) +{ + WriteToFileData data; + gboolean success; + + data.schema_table = schema_table; + + gvdb_pair_init (&data.root_pair); + + g_hash_table_foreach (schema_table, output_schema, &data); + + success = gvdb_table_write_contents (data.root_pair.table, filename, + G_BYTE_ORDER != G_LITTLE_ENDIAN, + error); + g_hash_table_unref (data.root_pair.table); + + return success; +} + +/* Parser driver {{{1 */ +static GHashTable * +parse_gschema_files (gchar **files, + gboolean strict) +{ + GMarkupParser parser = { start_element, end_element, text, NULL, NULL }; + ParseState state = { 0, }; + const gchar *filename; + GError *error = NULL; + + state.strict = strict; + + state.enum_table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, enum_state_free); + + state.flags_table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, enum_state_free); + + state.schema_table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, schema_state_free); + + while ((filename = *files++) != NULL) + { + GMarkupParseContext *context; + gchar *contents; + gsize size; + gint line, col; + + if (!g_file_get_contents (filename, &contents, &size, &error)) + { + fprintf (stderr, "%s\n", error->message); + g_clear_error (&error); + continue; + } + + context = g_markup_parse_context_new (&parser, + G_MARKUP_TREAT_CDATA_AS_TEXT | + G_MARKUP_PREFIX_ERROR_POSITION | + G_MARKUP_IGNORE_QUALIFIED, + &state, NULL); + + + if (!g_markup_parse_context_parse (context, contents, size, &error) || + !g_markup_parse_context_end_parse (context, &error)) + { + GSList *item; + + /* back out any changes from this file */ + for (item = state.this_file_schemas; item; item = item->next) + g_hash_table_remove (state.schema_table, item->data); + + for (item = state.this_file_flagss; item; item = item->next) + g_hash_table_remove (state.flags_table, item->data); + + for (item = state.this_file_enums; item; item = item->next) + g_hash_table_remove (state.enum_table, item->data); + + /* let them know */ + g_markup_parse_context_get_position (context, &line, &col); + fprintf (stderr, "%s:%d:%d %s. ", filename, line, col, error->message); + g_clear_error (&error); + + if (strict) + { + /* Translators: Do not translate "--strict". */ + fprintf (stderr, "%s\n", _("--strict was specified; exiting.")); + + g_hash_table_unref (state.schema_table); + g_hash_table_unref (state.flags_table); + g_hash_table_unref (state.enum_table); + + g_free (contents); + + return NULL; + } + else + { + fprintf (stderr, "%s\n", _("This entire file has been ignored.")); + } + } + + /* cleanup */ + g_free (contents); + g_markup_parse_context_free (context); + g_slist_free (state.this_file_schemas); + g_slist_free (state.this_file_flagss); + g_slist_free (state.this_file_enums); + state.this_file_schemas = NULL; + state.this_file_flagss = NULL; + state.this_file_enums = NULL; + } + + g_hash_table_unref (state.flags_table); + g_hash_table_unref (state.enum_table); + + return state.schema_table; +} + +static gint +compare_strings (gconstpointer a, + gconstpointer b) +{ + gchar *one = *(gchar **) a; + gchar *two = *(gchar **) b; + gint cmp; + + cmp = g_str_has_suffix (two, ".enums.xml") - + g_str_has_suffix (one, ".enums.xml"); + + if (!cmp) + cmp = strcmp (one, two); + + return cmp; +} + +static gboolean +set_overrides (GHashTable *schema_table, + gchar **files, + gboolean strict) +{ + const gchar *filename; + GError *error = NULL; + + while ((filename = *files++)) + { + GKeyFile *key_file; + gchar **groups; + gint i; + + g_debug ("Processing override file '%s'", filename); + + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, filename, 0, &error)) + { + fprintf (stderr, "%s: %s. ", filename, error->message); + g_key_file_free (key_file); + g_clear_error (&error); + + if (!strict) + { + fprintf (stderr, "%s\n", _("Ignoring this file.")); + continue; + } + + fprintf (stderr, "%s\n", _("--strict was specified; exiting.")); + return FALSE; + } + + groups = g_key_file_get_groups (key_file, NULL); + + for (i = 0; groups[i]; i++) + { + const gchar *group = groups[i]; + const gchar *schema_name; + const gchar *desktop_id; + SchemaState *schema; + gchar **pieces; + gchar **keys; + gint j; + + pieces = g_strsplit (group, ":", 2); + schema_name = pieces[0]; + desktop_id = pieces[1]; + + g_debug ("Processing group '%s' (schema '%s', %s)", + group, schema_name, desktop_id ? desktop_id : "all desktops"); + + schema = g_hash_table_lookup (schema_table, schema_name); + + if (schema == NULL) + { + /* Having the schema not be installed is expected to be a + * common case. Don't even emit an error message about + * that. + */ + g_strfreev (pieces); + continue; + } + + keys = g_key_file_get_keys (key_file, group, NULL, NULL); + g_assert (keys != NULL); + + for (j = 0; keys[j]; j++) + { + const gchar *key = keys[j]; + KeyState *state; + GVariant *value; + gchar *string; + + state = g_hash_table_lookup (schema->keys, key); + + if (state == NULL) + { + if (!strict) + { + fprintf (stderr, _("No such key “%s†in schema “%s†as " + "specified in override file “%sâ€; " + "ignoring override for this key."), + key, group, filename); + fprintf (stderr, "\n"); + continue; + } + + fprintf (stderr, _("No such key “%s†in schema “%s†as " + "specified in override file “%s†and " + "--strict was specified; exiting."), + key, group, filename); + fprintf (stderr, "\n"); + + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + + if (desktop_id != NULL && state->l10n) + { + /* Let's avoid the n*m case of per-desktop localised + * default values, and just forbid it. + */ + if (!strict) + { + fprintf (stderr, + _("Cannot provide per-desktop overrides for " + "localized key “%s†in schema “%s†(override " + "file “%sâ€); ignoring override for this key."), + key, group, filename); + fprintf (stderr, "\n"); + continue; + } + + fprintf (stderr, + _("Cannot provide per-desktop overrides for " + "localized key “%s†in schema “%s†(override " + "file “%sâ€) and --strict was specified; exiting."), + key, group, filename); + fprintf (stderr, "\n"); + + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + + string = g_key_file_get_value (key_file, group, key, NULL); + g_assert (string != NULL); + + value = g_variant_parse (state->type, string, + NULL, NULL, &error); + + if (value == NULL) + { + if (!strict) + { + fprintf (stderr, _("Error parsing key “%s†in schema “%s†" + "as specified in override file “%sâ€: " + "%s. Ignoring override for this key."), + key, group, filename, error->message); + fprintf (stderr, "\n"); + + g_clear_error (&error); + g_free (string); + + continue; + } + + fprintf (stderr, _("Error parsing key “%s†in schema “%s†" + "as specified in override file “%sâ€: " + "%s. --strict was specified; exiting."), + key, group, filename, error->message); + fprintf (stderr, "\n"); + + g_clear_error (&error); + g_free (string); + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + + if (state->minimum) + { + if (g_variant_compare (value, state->minimum) < 0 || + g_variant_compare (value, state->maximum) > 0) + { + g_variant_unref (value); + g_free (string); + + if (!strict) + { + fprintf (stderr, + _("Override for key “%s†in schema “%s†in " + "override file “%s†is outside the range " + "given in the schema; ignoring override " + "for this key."), + key, group, filename); + fprintf (stderr, "\n"); + continue; + } + + fprintf (stderr, + _("Override for key “%s†in schema “%s†in " + "override file “%s†is outside the range " + "given in the schema and --strict was " + "specified; exiting."), + key, group, filename); + fprintf (stderr, "\n"); + + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + } + + else if (state->strinfo->len) + { + if (!is_valid_choices (value, state->strinfo)) + { + g_variant_unref (value); + g_free (string); + + if (!strict) + { + fprintf (stderr, + _("Override for key “%s†in schema “%s†in " + "override file “%s†is not in the list " + "of valid choices; ignoring override for " + "this key."), + key, group, filename); + fprintf (stderr, "\n"); + continue; + } + + fprintf (stderr, + _("Override for key “%s†in schema “%s†in " + "override file “%s†is not in the list " + "of valid choices and --strict was specified; " + "exiting."), + key, group, filename); + fprintf (stderr, "\n"); + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + } + + if (desktop_id != NULL) + { + if (state->desktop_overrides == NULL) + state->desktop_overrides = g_variant_dict_new (NULL); + + g_variant_dict_insert_value (state->desktop_overrides, desktop_id, value); + g_variant_unref (value); + } + else + { + g_variant_unref (state->default_value); + state->default_value = value; + } + + g_free (string); + } + + g_strfreev (pieces); + g_strfreev (keys); + } + + g_strfreev (groups); + g_key_file_free (key_file); + } + + return TRUE; +} + +int +main (int argc, char **argv) +{ + GError *error = NULL; + GHashTable *table = NULL; + GDir *dir = NULL; + const gchar *file; + const gchar *srcdir; + gboolean show_version_and_exit = FALSE; + gchar *targetdir = NULL; + gchar *target = NULL; + gboolean dry_run = FALSE; + gboolean strict = FALSE; + gchar **schema_files = NULL; + gchar **override_files = NULL; + GOptionContext *context = NULL; + gint retval; + GOptionEntry entries[] = { + { "version", 0, 0, G_OPTION_ARG_NONE, &show_version_and_exit, N_("Show program version and exit"), NULL }, + { "targetdir", 0, 0, G_OPTION_ARG_FILENAME, &targetdir, N_("Where to store the gschemas.compiled file"), N_("DIRECTORY") }, + { "strict", 0, 0, G_OPTION_ARG_NONE, &strict, N_("Abort on any errors in schemas"), NULL }, + { "dry-run", 0, 0, G_OPTION_ARG_NONE, &dry_run, N_("Do not write the gschema.compiled file"), NULL }, + { "allow-any-name", 0, 0, G_OPTION_ARG_NONE, &allow_any_name, N_("Do not enforce key name restrictions"), NULL }, + + /* These options are only for use in the gschema-compile tests */ + { "schema-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &schema_files, NULL, NULL }, + { "override-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &override_files, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + +#ifdef G_OS_WIN32 + gchar *tmp = NULL; +#endif + + setlocale (LC_ALL, GLIB_DEFAULT_LOCALE); + textdomain (GETTEXT_PACKAGE); + +#ifdef G_OS_WIN32 + tmp = _glib_get_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, tmp); +#else + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#endif + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + + context = g_option_context_new (N_("DIRECTORY")); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_set_summary (context, + N_("Compile all GSettings schema files into a schema cache.\n" + "Schema files are required to have the extension .gschema.xml,\n" + "and the cache file is called gschemas.compiled.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + fprintf (stderr, "%s\n", error->message); + retval = 1; + goto done; + } + + if (show_version_and_exit) + { + g_print (PACKAGE_VERSION "\n"); + retval = 0; + goto done; + } + + if (!schema_files && argc != 2) + { + fprintf (stderr, "%s\n", _("You should give exactly one directory name")); + retval = 1; + goto done; + } + + srcdir = argv[1]; + + target = g_build_filename (targetdir ? targetdir : srcdir, "gschemas.compiled", NULL); + + if (!schema_files) + { + GPtrArray *overrides; + GPtrArray *files; + + files = g_ptr_array_new (); + overrides = g_ptr_array_new (); + + dir = g_dir_open (srcdir, 0, &error); + if (dir == NULL) + { + fprintf (stderr, "%s\n", error->message); + + g_ptr_array_unref (files); + g_ptr_array_unref (overrides); + + retval = 1; + goto done; + } + + while ((file = g_dir_read_name (dir)) != NULL) + { + if (g_str_has_suffix (file, ".gschema.xml") || + g_str_has_suffix (file, ".enums.xml")) + g_ptr_array_add (files, g_build_filename (srcdir, file, NULL)); + + else if (g_str_has_suffix (file, ".gschema.override")) + g_ptr_array_add (overrides, + g_build_filename (srcdir, file, NULL)); + } + + if (files->len == 0) + { + if (g_unlink (target)) + fprintf (stdout, "%s\n", _("No schema files found: doing nothing.")); + else + fprintf (stdout, "%s\n", _("No schema files found: removed existing output file.")); + + g_ptr_array_unref (files); + g_ptr_array_unref (overrides); + + retval = 0; + goto done; + } + g_ptr_array_sort (files, compare_strings); + g_ptr_array_add (files, NULL); + + g_ptr_array_sort (overrides, compare_strings); + g_ptr_array_add (overrides, NULL); + + schema_files = (char **) g_ptr_array_free (files, FALSE); + override_files = (gchar **) g_ptr_array_free (overrides, FALSE); + } + + if ((table = parse_gschema_files (schema_files, strict)) == NULL) + { + retval = 1; + goto done; + } + + if (override_files != NULL && + !set_overrides (table, override_files, strict)) + { + retval = 1; + goto done; + } + + if (!dry_run && !write_to_file (table, target, &error)) + { + fprintf (stderr, "%s\n", error->message); + retval = 1; + goto done; + } + + /* Success. */ + retval = 0; + +done: + g_clear_error (&error); + g_clear_pointer (&table, g_hash_table_unref); + g_clear_pointer (&dir, g_dir_close); + g_free (targetdir); + g_free (target); + g_strfreev (schema_files); + g_strfreev (override_files); + g_option_context_free (context); + +#ifdef G_OS_WIN32 + g_free (tmp); +#endif + + return retval; +} + +/* Epilogue {{{1 */ + +/* vim:set foldmethod=marker: */ diff --git a/gio/glistmodel.c b/gio/glistmodel.c new file mode 100644 index 0000000..0411353 --- /dev/null +++ b/gio/glistmodel.c @@ -0,0 +1,305 @@ +/* + * Copyright 2015 Lars Uebernickel + * Copyright 2015 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: + * Lars Uebernickel + * Ryan Lortie + */ + +#include "config.h" + +#include "glistmodel.h" +#include "glibintl.h" +#include "gmarshal-internal.h" + +G_DEFINE_INTERFACE (GListModel, g_list_model, G_TYPE_OBJECT) + +/** + * SECTION:glistmodel + * @title: GListModel + * @short_description: An interface describing a dynamic list of objects + * @include: gio/gio.h + * @see_also: #GListStore + * + * #GListModel is an interface that represents a mutable list of + * #GObjects. Its main intention is as a model for various widgets in + * user interfaces, such as list views, but it can also be used as a + * convenient method of returning lists of data, with support for + * updates. + * + * Each object in the list may also report changes in itself via some + * mechanism (normally the #GObject::notify signal). Taken together + * with the #GListModel::items-changed signal, this provides for a list + * that can change its membership, and in which the members can change + * their individual properties. + * + * A good example would be the list of visible wireless network access + * points, where each access point can report dynamic properties such as + * signal strength. + * + * It is important to note that the #GListModel itself does not report + * changes to the individual items. It only reports changes to the list + * membership. If you want to observe changes to the objects themselves + * then you need to connect signals to the objects that you are + * interested in. + * + * All items in a #GListModel are of (or derived from) the same type. + * g_list_model_get_item_type() returns that type. The type may be an + * interface, in which case all objects in the list must implement it. + * + * The semantics are close to that of an array: + * g_list_model_get_n_items() returns the number of items in the list and + * g_list_model_get_item() returns an item at a (0-based) position. In + * order to allow implementations to calculate the list length lazily, + * you can also iterate over items: starting from 0, repeatedly call + * g_list_model_get_item() until it returns %NULL. + * + * An implementation may create objects lazily, but must take care to + * return the same object for a given position until all references to + * it are gone. + * + * On the other side, a consumer is expected only to hold references on + * objects that are currently "user visible", in order to facilitate the + * maximum level of laziness in the implementation of the list and to + * reduce the required number of signal connections at a given time. + * + * This interface is intended only to be used from a single thread. The + * thread in which it is appropriate to use it depends on the particular + * implementation, but typically it will be from the thread that owns + * the [thread-default main context][g-main-context-push-thread-default] + * in effect at the time that the model was created. + */ + +/** + * GListModelInterface: + * @g_iface: parent #GTypeInterface + * @get_item_type: the virtual function pointer for g_list_model_get_item_type() + * @get_n_items: the virtual function pointer for g_list_model_get_n_items() + * @get_item: the virtual function pointer for g_list_model_get_item() + * + * The virtual function table for #GListModel. + * + * Since: 2.44 + */ + +/** + * GListModelInterface::get_item: + * @list: a #GListModel + * @position: the position of the item to fetch + * + * Get the item at @position. If @position is greater than the number of + * items in @list, %NULL is returned. + * + * %NULL is never returned for an index that is smaller than the length + * of the list. See g_list_model_get_n_items(). + * + * Returns: (type GObject) (transfer full) (nullable): the object at @position. + * + * Since: 2.44 + */ + +/** + * GListModel: + * + * #GListModel is an opaque data structure and can only be accessed + * using the following functions. + **/ + +static guint g_list_model_changed_signal; + +static void +g_list_model_default_init (GListModelInterface *iface) +{ + /** + * GListModel::items-changed: + * @list: the #GListModel that changed + * @position: the position at which @list changed + * @removed: the number of items removed + * @added: the number of items added + * + * This signal is emitted whenever items were added to or removed + * from @list. At @position, @removed items were removed and @added + * items were added in their place. + * + * Note: If `removed != added`, the positions of all later items + * in the model change. + * + * Since: 2.44 + */ + g_list_model_changed_signal = g_signal_new (I_("items-changed"), + G_TYPE_LIST_MODEL, + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _g_cclosure_marshal_VOID__UINT_UINT_UINT, + G_TYPE_NONE, + 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); + g_signal_set_va_marshaller (g_list_model_changed_signal, + G_TYPE_FROM_INTERFACE (iface), + _g_cclosure_marshal_VOID__UINT_UINT_UINTv); +} + +/** + * g_list_model_get_item_type: + * @list: a #GListModel + * + * Gets the type of the items in @list. + * + * All items returned from g_list_model_get_item() are of the type + * returned by this function, or a subtype, or if the type is an + * interface, they are an implementation of that interface. + * + * The item type of a #GListModel can not change during the life of the + * model. + * + * Returns: the #GType of the items contained in @list. + * + * Since: 2.44 + */ +GType +g_list_model_get_item_type (GListModel *list) +{ + g_return_val_if_fail (G_IS_LIST_MODEL (list), G_TYPE_NONE); + + return G_LIST_MODEL_GET_IFACE (list)->get_item_type (list); +} + +/** + * g_list_model_get_n_items: + * @list: a #GListModel + * + * Gets the number of items in @list. + * + * Depending on the model implementation, calling this function may be + * less efficient than iterating the list with increasing values for + * @position until g_list_model_get_item() returns %NULL. + * + * Returns: the number of items in @list. + * + * Since: 2.44 + */ +guint +g_list_model_get_n_items (GListModel *list) +{ + g_return_val_if_fail (G_IS_LIST_MODEL (list), 0); + + return G_LIST_MODEL_GET_IFACE (list)->get_n_items (list); +} + +/** + * g_list_model_get_item: (skip) + * @list: a #GListModel + * @position: the position of the item to fetch + * + * Get the item at @position. + * + * If @position is greater than the number of items in @list, %NULL is + * returned. + * + * %NULL is never returned for an index that is smaller than the length + * of the list. + * + * See also: g_list_model_get_n_items() + * + * Returns: (transfer full) (nullable): the item at @position. + * + * Since: 2.44 + */ +gpointer +g_list_model_get_item (GListModel *list, + guint position) +{ + g_return_val_if_fail (G_IS_LIST_MODEL (list), NULL); + + return G_LIST_MODEL_GET_IFACE (list)->get_item (list, position); +} + +/** + * g_list_model_get_object: (rename-to g_list_model_get_item) + * @list: a #GListModel + * @position: the position of the item to fetch + * + * Get the item at @position. + * + * If @position is greater than the number of items in @list, %NULL is + * returned. + * + * %NULL is never returned for an index that is smaller than the length + * of the list. + * + * This function is meant to be used by language bindings in place + * of g_list_model_get_item(). + * + * See also: g_list_model_get_n_items() + * + * Returns: (transfer full) (nullable): the object at @position. + * + * Since: 2.44 + */ +GObject * +g_list_model_get_object (GListModel *list, + guint position) +{ + gpointer item; + + g_return_val_if_fail (G_IS_LIST_MODEL (list), NULL); + + item = g_list_model_get_item (list, position); + + return G_OBJECT (item); +} + +/** + * g_list_model_items_changed: + * @list: a #GListModel + * @position: the position at which @list changed + * @removed: the number of items removed + * @added: the number of items added + * + * Emits the #GListModel::items-changed signal on @list. + * + * This function should only be called by classes implementing + * #GListModel. It has to be called after the internal representation + * of @list has been updated, because handlers connected to this signal + * might query the new state of the list. + * + * Implementations must only make changes to the model (as visible to + * its consumer) in places that will not cause problems for that + * consumer. For models that are driven directly by a write API (such + * as #GListStore), changes can be reported in response to uses of that + * API. For models that represent remote data, changes should only be + * made from a fresh mainloop dispatch. It is particularly not + * permitted to make changes in response to a call to the #GListModel + * consumer API. + * + * Stated another way: in general, it is assumed that code making a + * series of accesses to the model via the API, without returning to the + * mainloop, and without calling other code, will continue to view the + * same contents of the model. + * + * Since: 2.44 + */ +void +g_list_model_items_changed (GListModel *list, + guint position, + guint removed, + guint added) +{ + g_return_if_fail (G_IS_LIST_MODEL (list)); + + g_signal_emit (list, g_list_model_changed_signal, 0, position, removed, added); +} diff --git a/gio/glistmodel.h b/gio/glistmodel.h new file mode 100644 index 0000000..48348af --- /dev/null +++ b/gio/glistmodel.h @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Lars Uebernickel + * Copyright 2015 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: + * Lars Uebernickel + * Ryan Lortie + */ + +#ifndef __G_LIST_MODEL_H__ +#define __G_LIST_MODEL_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_LIST_MODEL g_list_model_get_type () +GLIB_AVAILABLE_IN_2_44 +G_DECLARE_INTERFACE(GListModel, g_list_model, G, LIST_MODEL, GObject) + +struct _GListModelInterface +{ + GTypeInterface g_iface; + + GType (* get_item_type) (GListModel *list); + + guint (* get_n_items) (GListModel *list); + + gpointer (* get_item) (GListModel *list, + guint position); +}; + +GLIB_AVAILABLE_IN_2_44 +GType g_list_model_get_item_type (GListModel *list); + +GLIB_AVAILABLE_IN_2_44 +guint g_list_model_get_n_items (GListModel *list); + +GLIB_AVAILABLE_IN_2_44 +gpointer g_list_model_get_item (GListModel *list, + guint position); + +GLIB_AVAILABLE_IN_2_44 +GObject * g_list_model_get_object (GListModel *list, + guint position); + +GLIB_AVAILABLE_IN_2_44 +void g_list_model_items_changed (GListModel *list, + guint position, + guint removed, + guint added); + +G_END_DECLS + +#endif /* __G_LIST_MODEL_H__ */ diff --git a/gio/gliststore.c b/gio/gliststore.c new file mode 100644 index 0000000..da7d12c --- /dev/null +++ b/gio/gliststore.c @@ -0,0 +1,579 @@ +/* + * Copyright 2015 Lars Uebernickel + * Copyright 2015 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: + * Lars Uebernickel + * Ryan Lortie + */ + +#include "config.h" + +#include "gliststore.h" +#include "glistmodel.h" + +/** + * SECTION:gliststore + * @title: GListStore + * @short_description: A simple implementation of #GListModel + * @include: gio/gio.h + * + * #GListStore is a simple implementation of #GListModel that stores all + * items in memory. + * + * It provides insertions, deletions, and lookups in logarithmic time + * with a fast path for the common case of iterating the list linearly. + */ + +/** + * GListStore: + * + * #GListStore is an opaque data structure and can only be accessed + * using the following functions. + **/ + +struct _GListStore +{ + GObject parent_instance; + + GType item_type; + GSequence *items; + + /* cache */ + guint last_position; + GSequenceIter *last_iter; + gboolean last_position_valid; +}; + +enum +{ + PROP_0, + PROP_ITEM_TYPE, + N_PROPERTIES +}; + +static void g_list_store_iface_init (GListModelInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GListStore, g_list_store, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, g_list_store_iface_init)); + +static void +g_list_store_items_changed (GListStore *store, + guint position, + guint removed, + guint added) +{ + /* check if the iter cache may have been invalidated */ + if (position <= store->last_position) + { + store->last_iter = NULL; + store->last_position = 0; + store->last_position_valid = FALSE; + } + + g_list_model_items_changed (G_LIST_MODEL (store), position, removed, added); +} + +static void +g_list_store_dispose (GObject *object) +{ + GListStore *store = G_LIST_STORE (object); + + g_clear_pointer (&store->items, g_sequence_free); + + G_OBJECT_CLASS (g_list_store_parent_class)->dispose (object); +} + +static void +g_list_store_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GListStore *store = G_LIST_STORE (object); + + switch (property_id) + { + case PROP_ITEM_TYPE: + g_value_set_gtype (value, store->item_type); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +g_list_store_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GListStore *store = G_LIST_STORE (object); + + switch (property_id) + { + case PROP_ITEM_TYPE: /* construct-only */ + g_assert (g_type_is_a (g_value_get_gtype (value), G_TYPE_OBJECT)); + store->item_type = g_value_get_gtype (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +g_list_store_class_init (GListStoreClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = g_list_store_dispose; + object_class->get_property = g_list_store_get_property; + object_class->set_property = g_list_store_set_property; + + /** + * GListStore:item-type: + * + * The type of items contained in this list store. Items must be + * subclasses of #GObject. + * + * Since: 2.44 + **/ + g_object_class_install_property (object_class, PROP_ITEM_TYPE, + g_param_spec_gtype ("item-type", "", "", G_TYPE_OBJECT, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static GType +g_list_store_get_item_type (GListModel *list) +{ + GListStore *store = G_LIST_STORE (list); + + return store->item_type; +} + +static guint +g_list_store_get_n_items (GListModel *list) +{ + GListStore *store = G_LIST_STORE (list); + + return g_sequence_get_length (store->items); +} + +static gpointer +g_list_store_get_item (GListModel *list, + guint position) +{ + GListStore *store = G_LIST_STORE (list); + GSequenceIter *it = NULL; + + if (store->last_position_valid) + { + if (position < G_MAXUINT && store->last_position == position + 1) + it = g_sequence_iter_prev (store->last_iter); + else if (position > 0 && store->last_position == position - 1) + it = g_sequence_iter_next (store->last_iter); + else if (store->last_position == position) + it = store->last_iter; + } + + if (it == NULL) + it = g_sequence_get_iter_at_pos (store->items, position); + + store->last_iter = it; + store->last_position = position; + store->last_position_valid = TRUE; + + if (g_sequence_iter_is_end (it)) + return NULL; + else + return g_object_ref (g_sequence_get (it)); +} + +static void +g_list_store_iface_init (GListModelInterface *iface) +{ + iface->get_item_type = g_list_store_get_item_type; + iface->get_n_items = g_list_store_get_n_items; + iface->get_item = g_list_store_get_item; +} + +static void +g_list_store_init (GListStore *store) +{ + store->items = g_sequence_new (g_object_unref); + store->last_position = 0; + store->last_position_valid = FALSE; +} + +/** + * g_list_store_new: + * @item_type: the #GType of items in the list + * + * Creates a new #GListStore with items of type @item_type. @item_type + * must be a subclass of #GObject. + * + * Returns: a new #GListStore + * Since: 2.44 + */ +GListStore * +g_list_store_new (GType item_type) +{ + /* We only allow GObjects as item types right now. This might change + * in the future. + */ + g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL); + + return g_object_new (G_TYPE_LIST_STORE, + "item-type", item_type, + NULL); +} + +/** + * g_list_store_insert: + * @store: a #GListStore + * @position: the position at which to insert the new item + * @item: (type GObject): the new item + * + * Inserts @item into @store at @position. @item must be of type + * #GListStore:item-type or derived from it. @position must be smaller + * than the length of the list, or equal to it to append. + * + * This function takes a ref on @item. + * + * Use g_list_store_splice() to insert multiple items at the same time + * efficiently. + * + * Since: 2.44 + */ +void +g_list_store_insert (GListStore *store, + guint position, + gpointer item) +{ + GSequenceIter *it; + + g_return_if_fail (G_IS_LIST_STORE (store)); + g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (item), store->item_type)); + g_return_if_fail (position <= (guint) g_sequence_get_length (store->items)); + + it = g_sequence_get_iter_at_pos (store->items, position); + g_sequence_insert_before (it, g_object_ref (item)); + + g_list_store_items_changed (store, position, 0, 1); +} + +/** + * g_list_store_insert_sorted: + * @store: a #GListStore + * @item: (type GObject): the new item + * @compare_func: (scope call): pairwise comparison function for sorting + * @user_data: (closure): user data for @compare_func + * + * Inserts @item into @store at a position to be determined by the + * @compare_func. + * + * The list must already be sorted before calling this function or the + * result is undefined. Usually you would approach this by only ever + * inserting items by way of this function. + * + * This function takes a ref on @item. + * + * Returns: the position at which @item was inserted + * + * Since: 2.44 + */ +guint +g_list_store_insert_sorted (GListStore *store, + gpointer item, + GCompareDataFunc compare_func, + gpointer user_data) +{ + GSequenceIter *it; + guint position; + + g_return_val_if_fail (G_IS_LIST_STORE (store), 0); + g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (item), store->item_type), 0); + g_return_val_if_fail (compare_func != NULL, 0); + + it = g_sequence_insert_sorted (store->items, g_object_ref (item), compare_func, user_data); + position = g_sequence_iter_get_position (it); + + g_list_store_items_changed (store, position, 0, 1); + + return position; +} + +/** + * g_list_store_sort: + * @store: a #GListStore + * @compare_func: (scope call): pairwise comparison function for sorting + * @user_data: (closure): user data for @compare_func + * + * Sort the items in @store according to @compare_func. + * + * Since: 2.46 + */ +void +g_list_store_sort (GListStore *store, + GCompareDataFunc compare_func, + gpointer user_data) +{ + gint n_items; + + g_return_if_fail (G_IS_LIST_STORE (store)); + g_return_if_fail (compare_func != NULL); + + g_sequence_sort (store->items, compare_func, user_data); + + n_items = g_sequence_get_length (store->items); + g_list_store_items_changed (store, 0, n_items, n_items); +} + +/** + * g_list_store_append: + * @store: a #GListStore + * @item: (type GObject): the new item + * + * Appends @item to @store. @item must be of type #GListStore:item-type. + * + * This function takes a ref on @item. + * + * Use g_list_store_splice() to append multiple items at the same time + * efficiently. + * + * Since: 2.44 + */ +void +g_list_store_append (GListStore *store, + gpointer item) +{ + guint n_items; + + g_return_if_fail (G_IS_LIST_STORE (store)); + g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (item), store->item_type)); + + n_items = g_sequence_get_length (store->items); + g_sequence_append (store->items, g_object_ref (item)); + + g_list_store_items_changed (store, n_items, 0, 1); +} + +/** + * g_list_store_remove: + * @store: a #GListStore + * @position: the position of the item that is to be removed + * + * Removes the item from @store that is at @position. @position must be + * smaller than the current length of the list. + * + * Use g_list_store_splice() to remove multiple items at the same time + * efficiently. + * + * Since: 2.44 + */ +void +g_list_store_remove (GListStore *store, + guint position) +{ + GSequenceIter *it; + + g_return_if_fail (G_IS_LIST_STORE (store)); + + it = g_sequence_get_iter_at_pos (store->items, position); + g_return_if_fail (!g_sequence_iter_is_end (it)); + + g_sequence_remove (it); + g_list_store_items_changed (store, position, 1, 0); +} + +/** + * g_list_store_remove_all: + * @store: a #GListStore + * + * Removes all items from @store. + * + * Since: 2.44 + */ +void +g_list_store_remove_all (GListStore *store) +{ + guint n_items; + + g_return_if_fail (G_IS_LIST_STORE (store)); + + n_items = g_sequence_get_length (store->items); + g_sequence_remove_range (g_sequence_get_begin_iter (store->items), + g_sequence_get_end_iter (store->items)); + + g_list_store_items_changed (store, 0, n_items, 0); +} + +/** + * g_list_store_splice: + * @store: a #GListStore + * @position: the position at which to make the change + * @n_removals: the number of items to remove + * @additions: (array length=n_additions) (element-type GObject): the items to add + * @n_additions: the number of items to add + * + * Changes @store by removing @n_removals items and adding @n_additions + * items to it. @additions must contain @n_additions items of type + * #GListStore:item-type. %NULL is not permitted. + * + * This function is more efficient than g_list_store_insert() and + * g_list_store_remove(), because it only emits + * #GListModel::items-changed once for the change. + * + * This function takes a ref on each item in @additions. + * + * The parameters @position and @n_removals must be correct (ie: + * @position + @n_removals must be less than or equal to the length of + * the list at the time this function is called). + * + * Since: 2.44 + */ +void +g_list_store_splice (GListStore *store, + guint position, + guint n_removals, + gpointer *additions, + guint n_additions) +{ + GSequenceIter *it; + guint n_items; + + g_return_if_fail (G_IS_LIST_STORE (store)); + g_return_if_fail (position + n_removals >= position); /* overflow */ + + n_items = g_sequence_get_length (store->items); + g_return_if_fail (position + n_removals <= n_items); + + it = g_sequence_get_iter_at_pos (store->items, position); + + if (n_removals) + { + GSequenceIter *end; + + end = g_sequence_iter_move (it, n_removals); + g_sequence_remove_range (it, end); + + it = end; + } + + if (n_additions) + { + guint i; + + for (i = 0; i < n_additions; i++) + { + if G_UNLIKELY (!g_type_is_a (G_OBJECT_TYPE (additions[i]), store->item_type)) + { + g_critical ("%s: item %d is a %s instead of a %s. GListStore is now in an undefined state.", + G_STRFUNC, i, G_OBJECT_TYPE_NAME (additions[i]), g_type_name (store->item_type)); + return; + } + + g_sequence_insert_before (it, g_object_ref (additions[i])); + } + } + + g_list_store_items_changed (store, position, n_removals, n_additions); +} + +/** + * g_list_store_find_with_equal_func: + * @store: a #GListStore + * @item: (type GObject): an item + * @equal_func: (scope call): A custom equality check function + * @position: (out) (optional): the first position of @item, if it was found. + * + * Looks up the given @item in the list store by looping over the items and + * comparing them with @compare_func until the first occurrence of @item which + * matches. If @item was not found, then @position will not be set, and this + * method will return %FALSE. + * + * Returns: Whether @store contains @item. If it was found, @position will be + * set to the position where @item occurred for the first time. + * + * Since: 2.64 + */ +gboolean +g_list_store_find_with_equal_func (GListStore *store, + gpointer item, + GEqualFunc equal_func, + guint *position) +{ + GSequenceIter *iter, *begin, *end; + + g_return_val_if_fail (G_IS_LIST_STORE (store), FALSE); + g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (item), store->item_type), + FALSE); + g_return_val_if_fail (equal_func != NULL, FALSE); + + /* NOTE: We can't use g_sequence_lookup() or g_sequence_search(), because we + * can't assume the sequence is sorted. */ + begin = g_sequence_get_begin_iter (store->items); + end = g_sequence_get_end_iter (store->items); + + iter = begin; + while (iter != end) + { + gpointer iter_item; + + iter_item = g_sequence_get (iter); + if (equal_func (iter_item, item)) + { + if (position) + *position = g_sequence_iter_get_position (iter); + return TRUE; + } + + iter = g_sequence_iter_next (iter); + } + + return FALSE; +} + +/** + * g_list_store_find: + * @store: a #GListStore + * @item: (type GObject): an item + * @position: (out) (optional): the first position of @item, if it was found. + * + * Looks up the given @item in the list store by looping over the items until + * the first occurrence of @item. If @item was not found, then @position will + * not be set, and this method will return %FALSE. + * + * If you need to compare the two items with a custom comparison function, use + * g_list_store_find_with_equal_func() with a custom #GEqualFunc instead. + * + * Returns: Whether @store contains @item. If it was found, @position will be + * set to the position where @item occurred for the first time. + * + * Since: 2.64 + */ +gboolean +g_list_store_find (GListStore *store, + gpointer item, + guint *position) +{ + return g_list_store_find_with_equal_func (store, + item, + g_direct_equal, + position); +} diff --git a/gio/gliststore.h b/gio/gliststore.h new file mode 100644 index 0000000..ef3b839 --- /dev/null +++ b/gio/gliststore.h @@ -0,0 +1,88 @@ +/* + * Copyright 2015 Lars Uebernickel + * Copyright 2015 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: + * Lars Uebernickel + * Ryan Lortie + */ + +#ifndef __G_LIST_STORE_H__ +#define __G_LIST_STORE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_LIST_STORE (g_list_store_get_type ()) +GLIB_AVAILABLE_IN_2_44 +G_DECLARE_FINAL_TYPE(GListStore, g_list_store, G, LIST_STORE, GObject) + +GLIB_AVAILABLE_IN_2_44 +GListStore * g_list_store_new (GType item_type); + +GLIB_AVAILABLE_IN_2_44 +void g_list_store_insert (GListStore *store, + guint position, + gpointer item); + +GLIB_AVAILABLE_IN_2_44 +guint g_list_store_insert_sorted (GListStore *store, + gpointer item, + GCompareDataFunc compare_func, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_46 +void g_list_store_sort (GListStore *store, + GCompareDataFunc compare_func, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_44 +void g_list_store_append (GListStore *store, + gpointer item); + +GLIB_AVAILABLE_IN_2_44 +void g_list_store_remove (GListStore *store, + guint position); + +GLIB_AVAILABLE_IN_2_44 +void g_list_store_remove_all (GListStore *store); + +GLIB_AVAILABLE_IN_2_44 +void g_list_store_splice (GListStore *store, + guint position, + guint n_removals, + gpointer *additions, + guint n_additions); + +GLIB_AVAILABLE_IN_2_64 +gboolean g_list_store_find (GListStore *store, + gpointer item, + guint *position); + +GLIB_AVAILABLE_IN_2_64 +gboolean g_list_store_find_with_equal_func (GListStore *store, + gpointer item, + GEqualFunc equal_func, + guint *position); + +G_END_DECLS + +#endif /* __G_LIST_STORE_H__ */ diff --git a/gio/gloadableicon.c b/gio/gloadableicon.c new file mode 100644 index 0000000..2465453 --- /dev/null +++ b/gio/gloadableicon.c @@ -0,0 +1,233 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "gicon.h" +#include "gloadableicon.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "glibintl.h" + + +/** + * SECTION:gloadableicon + * @short_description: Loadable Icons + * @include: gio/gio.h + * @see_also: #GIcon, #GThemedIcon + * + * Extends the #GIcon interface and adds the ability to + * load icons from streams. + **/ + +static void g_loadable_icon_real_load_async (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GInputStream *g_loadable_icon_real_load_finish (GLoadableIcon *icon, + GAsyncResult *res, + char **type, + GError **error); + +typedef GLoadableIconIface GLoadableIconInterface; +G_DEFINE_INTERFACE(GLoadableIcon, g_loadable_icon, G_TYPE_ICON) + +static void +g_loadable_icon_default_init (GLoadableIconIface *iface) +{ + iface->load_async = g_loadable_icon_real_load_async; + iface->load_finish = g_loadable_icon_real_load_finish; +} + +/** + * g_loadable_icon_load: + * @icon: a #GLoadableIcon. + * @size: an integer. + * @type: (out) (optional): a location to store the type of the loaded + * icon, %NULL to ignore. + * @cancellable: (nullable): optional #GCancellable object, %NULL to + * ignore. + * @error: a #GError location to store the error occurring, or %NULL + * to ignore. + * + * Loads a loadable icon. For the asynchronous version of this function, + * see g_loadable_icon_load_async(). + * + * Returns: (transfer full): a #GInputStream to read the icon from. + **/ +GInputStream * +g_loadable_icon_load (GLoadableIcon *icon, + int size, + char **type, + GCancellable *cancellable, + GError **error) +{ + GLoadableIconIface *iface; + + g_return_val_if_fail (G_IS_LOADABLE_ICON (icon), NULL); + + iface = G_LOADABLE_ICON_GET_IFACE (icon); + + return (* iface->load) (icon, size, type, cancellable, error); +} + +/** + * g_loadable_icon_load_async: + * @icon: a #GLoadableIcon. + * @size: an integer. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the + * request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Loads an icon asynchronously. To finish this function, see + * g_loadable_icon_load_finish(). For the synchronous, blocking + * version of this function, see g_loadable_icon_load(). + **/ +void +g_loadable_icon_load_async (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GLoadableIconIface *iface; + + g_return_if_fail (G_IS_LOADABLE_ICON (icon)); + + iface = G_LOADABLE_ICON_GET_IFACE (icon); + + (* iface->load_async) (icon, size, cancellable, callback, user_data); +} + +/** + * g_loadable_icon_load_finish: + * @icon: a #GLoadableIcon. + * @res: a #GAsyncResult. + * @type: (out) (optional): a location to store the type of the loaded + * icon, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an asynchronous icon load started in g_loadable_icon_load_async(). + * + * Returns: (transfer full): a #GInputStream to read the icon from. + **/ +GInputStream * +g_loadable_icon_load_finish (GLoadableIcon *icon, + GAsyncResult *res, + char **type, + GError **error) +{ + GLoadableIconIface *iface; + + g_return_val_if_fail (G_IS_LOADABLE_ICON (icon), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (g_async_result_legacy_propagate_error (res, error)) + return NULL; + + iface = G_LOADABLE_ICON_GET_IFACE (icon); + + return (* iface->load_finish) (icon, res, type, error); +} + +/******************************************** + * Default implementation of async load * + ********************************************/ + +typedef struct { + int size; + char *type; +} LoadData; + +static void +load_data_free (LoadData *data) +{ + g_free (data->type); + g_free (data); +} + +static void +load_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GLoadableIcon *icon = source_object; + LoadData *data = task_data; + GLoadableIconIface *iface; + GInputStream *stream; + GError *error = NULL; + + iface = G_LOADABLE_ICON_GET_IFACE (icon); + stream = iface->load (icon, data->size, &data->type, + cancellable, &error); + + if (stream) + g_task_return_pointer (task, stream, g_object_unref); + else + g_task_return_error (task, error); +} + + + +static void +g_loadable_icon_real_load_async (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + LoadData *data; + + task = g_task_new (icon, cancellable, callback, user_data); + g_task_set_source_tag (task, g_loadable_icon_real_load_async); + data = g_new0 (LoadData, 1); + g_task_set_task_data (task, data, (GDestroyNotify) load_data_free); + g_task_run_in_thread (task, load_async_thread); + g_object_unref (task); +} + +static GInputStream * +g_loadable_icon_real_load_finish (GLoadableIcon *icon, + GAsyncResult *res, + char **type, + GError **error) +{ + GTask *task; + LoadData *data; + GInputStream *stream; + + g_return_val_if_fail (g_task_is_valid (res, icon), NULL); + + task = G_TASK (res); + data = g_task_get_task_data (task); + + stream = g_task_propagate_pointer (task, error); + if (stream && type) + { + *type = data->type; + data->type = NULL; + } + + return stream; +} diff --git a/gio/gloadableicon.h b/gio/gloadableicon.h new file mode 100644 index 0000000..c2951c9 --- /dev/null +++ b/gio/gloadableicon.h @@ -0,0 +1,99 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOADABLE_ICON_H__ +#define __G_LOADABLE_ICON_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_LOADABLE_ICON (g_loadable_icon_get_type ()) +#define G_LOADABLE_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_LOADABLE_ICON, GLoadableIcon)) +#define G_IS_LOADABLE_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_LOADABLE_ICON)) +#define G_LOADABLE_ICON_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_LOADABLE_ICON, GLoadableIconIface)) + +/** + * GLoadableIcon: + * + * Generic type for all kinds of icons that can be loaded + * as a stream. + **/ +typedef struct _GLoadableIconIface GLoadableIconIface; + +/** + * GLoadableIconIface: + * @g_iface: The parent interface. + * @load: Loads an icon. + * @load_async: Loads an icon asynchronously. + * @load_finish: Finishes an asynchronous icon load. + * + * Interface for icons that can be loaded as a stream. + **/ +struct _GLoadableIconIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + GInputStream * (* load) (GLoadableIcon *icon, + int size, + char **type, + GCancellable *cancellable, + GError **error); + void (* load_async) (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GInputStream * (* load_finish) (GLoadableIcon *icon, + GAsyncResult *res, + char **type, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_loadable_icon_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GInputStream *g_loadable_icon_load (GLoadableIcon *icon, + int size, + char **type, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_loadable_icon_load_async (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GInputStream *g_loadable_icon_load_finish (GLoadableIcon *icon, + GAsyncResult *res, + char **type, + GError **error); + +G_END_DECLS + +#endif /* __G_LOADABLE_ICON_H__ */ diff --git a/gio/glocalfile.c b/gio/glocalfile.c new file mode 100644 index 0000000..da38ade --- /dev/null +++ b/gio/glocalfile.c @@ -0,0 +1,3019 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#if G_OS_UNIX +#include +#include +#endif + +#if HAVE_SYS_STATFS_H +#include +#endif +#if HAVE_SYS_STATVFS_H +#include +#endif +#if HAVE_SYS_VFS_H +#include +#elif HAVE_SYS_MOUNT_H +#if HAVE_SYS_PARAM_H +#include +#endif +#include +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#include "gfileattribute.h" +#include "glocalfile.h" +#include "glocalfileinfo.h" +#include "glocalfileenumerator.h" +#include "glocalfileinputstream.h" +#include "glocalfileoutputstream.h" +#include "glocalfileiostream.h" +#include "glocalfilemonitor.h" +#include "gmountprivate.h" +#include "gunixmounts.h" +#include "gioerror.h" +#include +#include +#include "glibintl.h" +#ifdef G_OS_UNIX +#include "glib-unix.h" +#include "gportalsupport.h" +#include "gtrashportal.h" +#endif + +#include "glib-private.h" + +#ifdef G_OS_WIN32 +#include +#include +#include + +#ifndef FILE_READ_ONLY_VOLUME +#define FILE_READ_ONLY_VOLUME 0x00080000 +#endif + +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#endif +#ifndef S_ISLNK +#define S_ISLNK(m) (0) +#endif + +#ifndef ECANCELED +#define ECANCELED 105 +#endif +#endif + + +static void g_local_file_file_iface_init (GFileIface *iface); + +static GFileAttributeInfoList *local_writable_attributes = NULL; +static /* GFileAttributeInfoList * */ gsize local_writable_namespaces = 0; + +struct _GLocalFile +{ + GObject parent_instance; + + char *filename; +}; + +#define g_local_file_get_type _g_local_file_get_type +G_DEFINE_TYPE_WITH_CODE (GLocalFile, g_local_file, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_FILE, + g_local_file_file_iface_init)) + +static char *find_mountpoint_for (const char *file, dev_t dev, gboolean resolve_basename_symlink); + +#ifndef G_OS_WIN32 +static gboolean is_remote_fs_type (const gchar *fsname); +#endif + +static void +g_local_file_finalize (GObject *object) +{ + GLocalFile *local; + + local = G_LOCAL_FILE (object); + + g_free (local->filename); + + G_OBJECT_CLASS (g_local_file_parent_class)->finalize (object); +} + +static void +g_local_file_class_init (GLocalFileClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GFileAttributeInfoList *list; + + gobject_class->finalize = g_local_file_finalize; + + /* Set up attribute lists */ + + /* Writable attributes: */ + + list = g_file_attribute_info_list_new (); + + g_file_attribute_info_list_add (list, + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_ATTRIBUTE_TYPE_UINT32, + G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE | + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); + +#ifdef G_OS_UNIX + g_file_attribute_info_list_add (list, + G_FILE_ATTRIBUTE_UNIX_UID, + G_FILE_ATTRIBUTE_TYPE_UINT32, + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); + g_file_attribute_info_list_add (list, + G_FILE_ATTRIBUTE_UNIX_GID, + G_FILE_ATTRIBUTE_TYPE_UINT32, + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); +#endif + +#ifdef HAVE_SYMLINK + g_file_attribute_info_list_add (list, + G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, + G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, + 0); +#endif + +#ifdef HAVE_UTIMES + g_file_attribute_info_list_add (list, + G_FILE_ATTRIBUTE_TIME_MODIFIED, + G_FILE_ATTRIBUTE_TYPE_UINT64, + G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE | + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); + g_file_attribute_info_list_add (list, + G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, + G_FILE_ATTRIBUTE_TYPE_UINT32, + G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE | + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); + /* When copying, the target file is accessed. Replicating + * the source access time does not make sense in this case. + */ + g_file_attribute_info_list_add (list, + G_FILE_ATTRIBUTE_TIME_ACCESS, + G_FILE_ATTRIBUTE_TYPE_UINT64, + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); + g_file_attribute_info_list_add (list, + G_FILE_ATTRIBUTE_TIME_ACCESS_USEC, + G_FILE_ATTRIBUTE_TYPE_UINT32, + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); +#endif + + local_writable_attributes = list; +} + +static void +g_local_file_init (GLocalFile *local) +{ +} + +const char * +_g_local_file_get_filename (GLocalFile *file) +{ + return file->filename; +} + +GFile * +_g_local_file_new (const char *filename) +{ + GLocalFile *local; + + local = g_object_new (G_TYPE_LOCAL_FILE, NULL); + local->filename = g_canonicalize_filename (filename, NULL); + + return G_FILE (local); +} + +/*< internal > + * g_local_file_new_from_dirname_and_basename: + * @dirname: an absolute, canonical directory name + * @basename: the name of a child inside @dirname + * + * Creates a #GFile from @dirname and @basename. + * + * This is more efficient than pasting the fields together for yourself + * and creating a #GFile from the result, and also more efficient than + * creating a #GFile for the dirname and using g_file_get_child(). + * + * @dirname must be canonical, as per GLocalFile's opinion of what + * canonical means. This means that you should only pass strings that + * were returned by _g_local_file_get_filename(). + * + * Returns: a #GFile + */ +GFile * +g_local_file_new_from_dirname_and_basename (const gchar *dirname, + const gchar *basename) +{ + GLocalFile *local; + + g_return_val_if_fail (dirname != NULL, NULL); + g_return_val_if_fail (basename && basename[0] && !strchr (basename, '/'), NULL); + + local = g_object_new (G_TYPE_LOCAL_FILE, NULL); + local->filename = g_build_filename (dirname, basename, NULL); + + return G_FILE (local); +} + +static gboolean +g_local_file_is_native (GFile *file) +{ + return TRUE; +} + +static gboolean +g_local_file_has_uri_scheme (GFile *file, + const char *uri_scheme) +{ + return g_ascii_strcasecmp (uri_scheme, "file") == 0; +} + +static char * +g_local_file_get_uri_scheme (GFile *file) +{ + return g_strdup ("file"); +} + +static char * +g_local_file_get_basename (GFile *file) +{ + return g_path_get_basename (G_LOCAL_FILE (file)->filename); +} + +static char * +g_local_file_get_path (GFile *file) +{ + return g_strdup (G_LOCAL_FILE (file)->filename); +} + +static char * +g_local_file_get_uri (GFile *file) +{ + return g_filename_to_uri (G_LOCAL_FILE (file)->filename, NULL, NULL); +} + +static gboolean +get_filename_charset (const gchar **filename_charset) +{ + const gchar **charsets; + gboolean is_utf8; + + is_utf8 = g_get_filename_charsets (&charsets); + + if (filename_charset) + *filename_charset = charsets[0]; + + return is_utf8; +} + +static gboolean +name_is_valid_for_display (const char *string, + gboolean is_valid_utf8) +{ + char c; + + if (!is_valid_utf8 && + !g_utf8_validate (string, -1, NULL)) + return FALSE; + + while ((c = *string++) != 0) + { + if (g_ascii_iscntrl (c)) + return FALSE; + } + + return TRUE; +} + +static char * +g_local_file_get_parse_name (GFile *file) +{ + const char *filename; + char *parse_name; + const gchar *charset; + char *utf8_filename; + char *roundtripped_filename; + gboolean free_utf8_filename; + gboolean is_valid_utf8; + char *escaped_path; + + filename = G_LOCAL_FILE (file)->filename; + if (get_filename_charset (&charset)) + { + utf8_filename = (char *)filename; + free_utf8_filename = FALSE; + is_valid_utf8 = FALSE; /* Can't guarantee this */ + } + else + { + utf8_filename = g_convert (filename, -1, + "UTF-8", charset, NULL, NULL, NULL); + free_utf8_filename = TRUE; + is_valid_utf8 = TRUE; + + if (utf8_filename != NULL) + { + /* Make sure we can roundtrip: */ + roundtripped_filename = g_convert (utf8_filename, -1, + charset, "UTF-8", NULL, NULL, NULL); + + if (roundtripped_filename == NULL || + strcmp (filename, roundtripped_filename) != 0) + { + g_free (utf8_filename); + utf8_filename = NULL; + } + + g_free (roundtripped_filename); + } + } + + if (utf8_filename != NULL && + name_is_valid_for_display (utf8_filename, is_valid_utf8)) + { + if (free_utf8_filename) + parse_name = utf8_filename; + else + parse_name = g_strdup (utf8_filename); + } + else + { +#ifdef G_OS_WIN32 + char *dup_filename, *p, *backslash; + + /* Turn backslashes into forward slashes like + * g_filename_to_uri() would do (but we can't use that because + * it doesn't output IRIs). + */ + dup_filename = g_strdup (filename); + filename = p = dup_filename; + + while ((backslash = strchr (p, '\\')) != NULL) + { + *backslash = '/'; + p = backslash + 1; + } +#endif + + escaped_path = g_uri_escape_string (filename, + G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT "/", + TRUE); + parse_name = g_strconcat ("file://", + (*escaped_path != '/') ? "/" : "", + escaped_path, + NULL); + + g_free (escaped_path); +#ifdef G_OS_WIN32 + g_free (dup_filename); +#endif + if (free_utf8_filename) + g_free (utf8_filename); + } + + return parse_name; +} + +static GFile * +g_local_file_get_parent (GFile *file) +{ + GLocalFile *local = G_LOCAL_FILE (file); + const char *non_root; + char *dirname; + GFile *parent; + + /* Check for root; local->filename is guaranteed to be absolute, so + * g_path_skip_root() should never return NULL. */ + non_root = g_path_skip_root (local->filename); + g_assert (non_root != NULL); + + if (*non_root == 0) + return NULL; + + dirname = g_path_get_dirname (local->filename); + parent = _g_local_file_new (dirname); + g_free (dirname); + return parent; +} + +static GFile * +g_local_file_dup (GFile *file) +{ + GLocalFile *local = G_LOCAL_FILE (file); + + return _g_local_file_new (local->filename); +} + +static guint +g_local_file_hash (GFile *file) +{ + GLocalFile *local = G_LOCAL_FILE (file); + + return g_str_hash (local->filename); +} + +static gboolean +g_local_file_equal (GFile *file1, + GFile *file2) +{ + GLocalFile *local1 = G_LOCAL_FILE (file1); + GLocalFile *local2 = G_LOCAL_FILE (file2); + + return g_str_equal (local1->filename, local2->filename); +} + +static const char * +match_prefix (const char *path, + const char *prefix) +{ + int prefix_len; + + prefix_len = strlen (prefix); + if (strncmp (path, prefix, prefix_len) != 0) + return NULL; + + /* Handle the case where prefix is the root, so that + * the IS_DIR_SEPRARATOR check below works */ + if (prefix_len > 0 && + G_IS_DIR_SEPARATOR (prefix[prefix_len-1])) + prefix_len--; + + return path + prefix_len; +} + +static gboolean +g_local_file_prefix_matches (GFile *parent, + GFile *descendant) +{ + GLocalFile *parent_local = G_LOCAL_FILE (parent); + GLocalFile *descendant_local = G_LOCAL_FILE (descendant); + const char *remainder; + + remainder = match_prefix (descendant_local->filename, parent_local->filename); + if (remainder != NULL && G_IS_DIR_SEPARATOR (*remainder)) + return TRUE; + return FALSE; +} + +static char * +g_local_file_get_relative_path (GFile *parent, + GFile *descendant) +{ + GLocalFile *parent_local = G_LOCAL_FILE (parent); + GLocalFile *descendant_local = G_LOCAL_FILE (descendant); + const char *remainder; + + remainder = match_prefix (descendant_local->filename, parent_local->filename); + + if (remainder != NULL && G_IS_DIR_SEPARATOR (*remainder)) + return g_strdup (remainder + 1); + return NULL; +} + +static GFile * +g_local_file_resolve_relative_path (GFile *file, + const char *relative_path) +{ + GLocalFile *local = G_LOCAL_FILE (file); + char *filename; + GFile *child; + + if (g_path_is_absolute (relative_path)) + return _g_local_file_new (relative_path); + + filename = g_build_filename (local->filename, relative_path, NULL); + child = _g_local_file_new (filename); + g_free (filename); + + return child; +} + +static GFileEnumerator * +g_local_file_enumerate_children (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + return _g_local_file_enumerator_new (local, + attributes, flags, + cancellable, error); +} + +static GFile * +g_local_file_get_child_for_display_name (GFile *file, + const char *display_name, + GError **error) +{ + GFile *new_file; + char *basename; + + basename = g_filename_from_utf8 (display_name, -1, NULL, NULL, NULL); + if (basename == NULL) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_FILENAME, + _("Invalid filename %s"), display_name); + return NULL; + } + + new_file = g_file_get_child (file, basename); + g_free (basename); + + return new_file; +} + +#if defined(USE_STATFS) && !defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) +static const char * +get_fs_type (long f_type) +{ + /* filesystem ids taken from linux manpage */ + switch (f_type) + { + case 0xadf5: + return "adfs"; + case 0x5346414f: + return "afs"; + case 0x0187: + return "autofs"; + case 0xADFF: + return "affs"; + case 0x62646576: + return "bdevfs"; + case 0x42465331: + return "befs"; + case 0x1BADFACE: + return "bfs"; + case 0x42494e4d: + return "binfmt_misc"; + case 0x9123683E: + return "btrfs"; + case 0x73727279: + return "btrfs_test_fs"; + case 0x27e0eb: + return "cgroup"; + case 0x63677270: + return "cgroup2"; + case 0xFF534D42: + return "cifs"; + case 0x73757245: + return "coda"; + case 0x012FF7B7: + return "coh"; + case 0x62656570: + return "configfs"; + case 0x28cd3d45: + return "cramfs"; + case 0x64626720: + return "debugfs"; + case 0x1373: + return "devfs"; + case 0x1cd1: + return "devpts"; + case 0xf15f: + return "ecryptfs"; + case 0xde5e81e4: + return "efivarfs"; + case 0x00414A53: + return "efs"; + case 0x2011BAB0UL: + return "exfat"; + case 0x137D: + return "ext"; + case 0xEF51: + return "ext2"; + case 0xEF53: + return "ext3/ext4"; + case 0xF2F52010: + return "f2fs"; + case 0x65735546: + return "fuse"; + case 0x65735543: + return "fusectl"; + case 0xBAD1DEA: + return "futexfs"; + case 0x4244: + return "hfs"; + case 0x00c0ffee: + return "hostfs"; + case 0xF995E849: + return "hpfs"; + case 0x958458f6: + return "hugetlbfs"; + case 0x9660: + return "isofs"; + case 0x72b6: + return "jffs2"; + case 0x3153464a: + return "jfs"; + case 0x137F: + return "minix"; + case 0x138F: + return "minix2"; + case 0x2468: + return "minix2"; + case 0x2478: + return "minix22"; + case 0x4d5a: + return "minix3"; + case 0x19800202: + return "mqueue"; + case 0x4d44: + return "msdos"; + case 0x564c: + return "ncp"; + case 0x6969: + return "nfs"; + case 0x3434: + return "nilfs"; + case 0x6e736673: + return "nsfs"; + case 0x5346544e: + return "ntfs"; + case 0x7461636f: + return "ocfs2"; + case 0x9fa1: + return "openprom"; + case 0x794c7630: + return "overlay"; + case 0x50495045: + return "pipefs"; + case 0x9fa0: + return "proc"; + case 0x6165676C: + return "pstore"; + case 0x002f: + return "qnx4"; + case 0x68191122: + return "qnx6"; + case 0x858458f6: + return "ramfs"; + case 0x52654973: + return "reiserfs"; + case 0x7275: + return "romfs"; + case 0x67596969: + return "rpc_pipefs"; + case 0x73636673: + return "securityfs"; + case 0xf97cff8c: + return "selinuxfs"; + case 0x43415d53: + return "smackfs"; + case 0x517B: + return "smb"; + case 0xfe534d42: + return "smb2"; + case 0x534F434B: + return "sockfs"; + case 0x73717368: + return "squashfs"; + case 0x62656572: + return "sysfs"; + case 0x012FF7B6: + return "sysv2"; + case 0x012FF7B5: + return "sysv4"; + case 0x01021994: + return "tmpfs"; + case 0x74726163: + return "tracefs"; + case 0x15013346: + return "udf"; + case 0x00011954: + return "ufs"; + case 0x9fa2: + return "usbdevice"; + case 0x01021997: + return "v9fs"; + case 0xa501FCF5: + return "vxfs"; + case 0xabba1974: + return "xenfs"; + case 0x012FF7B4: + return "xenix"; + case 0x58465342: + return "xfs"; + case 0x012FD16D: + return "xiafs"; + case 0x52345362: + return "reiser4"; + default: + return NULL; + } +} +#endif + +#ifndef G_OS_WIN32 + +G_LOCK_DEFINE_STATIC(mount_info_hash); +static GHashTable *mount_info_hash = NULL; +static guint64 mount_info_hash_cache_time = 0; + +typedef enum { + MOUNT_INFO_READONLY = 1<<0 +} MountInfo; + +static gboolean +device_equal (gconstpointer v1, + gconstpointer v2) +{ + return *(dev_t *)v1 == *(dev_t *)v2; +} + +static guint +device_hash (gconstpointer v) +{ + return (guint) *(dev_t *)v; +} + +static void +get_mount_info (GFileInfo *fs_info, + const char *path, + GFileAttributeMatcher *matcher) +{ + GStatBuf buf; + gboolean got_info; + gpointer info_as_ptr; + guint mount_info; + char *mountpoint; + dev_t *dev; + GUnixMountEntry *mount; + guint64 cache_time; + + if (g_lstat (path, &buf) != 0) + return; + + G_LOCK (mount_info_hash); + + if (mount_info_hash == NULL) + mount_info_hash = g_hash_table_new_full (device_hash, device_equal, + g_free, NULL); + + + if (g_unix_mounts_changed_since (mount_info_hash_cache_time)) + g_hash_table_remove_all (mount_info_hash); + + got_info = g_hash_table_lookup_extended (mount_info_hash, + &buf.st_dev, + NULL, + &info_as_ptr); + + G_UNLOCK (mount_info_hash); + + mount_info = GPOINTER_TO_UINT (info_as_ptr); + + if (!got_info) + { + mount_info = 0; + + mountpoint = find_mountpoint_for (path, buf.st_dev, FALSE); + if (mountpoint == NULL) + mountpoint = g_strdup ("/"); + + mount = g_unix_mount_at (mountpoint, &cache_time); + if (mount) + { + if (g_unix_mount_is_readonly (mount)) + mount_info |= MOUNT_INFO_READONLY; + + g_unix_mount_free (mount); + } + + g_free (mountpoint); + + dev = g_new0 (dev_t, 1); + *dev = buf.st_dev; + + G_LOCK (mount_info_hash); + mount_info_hash_cache_time = cache_time; + g_hash_table_insert (mount_info_hash, dev, GUINT_TO_POINTER (mount_info)); + G_UNLOCK (mount_info_hash); + } + + if (mount_info & MOUNT_INFO_READONLY) + g_file_info_set_attribute_boolean (fs_info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, TRUE); +} + +#endif + +#ifdef G_OS_WIN32 + +static wchar_t * +get_volume_for_path (const char *path) +{ + long len; + wchar_t *wpath; + wchar_t *result; + + wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL); + result = g_new (wchar_t, MAX_PATH); + + if (!GetVolumePathNameW (wpath, result, MAX_PATH)) + { + char *msg = g_win32_error_message (GetLastError ()); + g_critical ("GetVolumePathName failed: %s", msg); + g_free (msg); + g_free (result); + g_free (wpath); + return NULL; + } + + len = wcslen (result); + if (len > 0 && result[len-1] != L'\\') + { + result = g_renew (wchar_t, result, len + 2); + result[len] = L'\\'; + result[len + 1] = 0; + } + + g_free (wpath); + return result; +} + +static char * +find_mountpoint_for (const char *file, dev_t dev, gboolean resolve_basename_symlink) +{ + wchar_t *wpath; + char *utf8_path; + + wpath = get_volume_for_path (file); + if (!wpath) + return NULL; + + utf8_path = g_utf16_to_utf8 (wpath, -1, NULL, NULL, NULL); + + g_free (wpath); + return utf8_path; +} + +static void +get_filesystem_readonly (GFileInfo *info, + const char *path) +{ + wchar_t *rootdir; + + rootdir = get_volume_for_path (path); + + if (rootdir) + { + DWORD flags; + if (GetVolumeInformationW (rootdir, NULL, 0, NULL, NULL, &flags, NULL, 0)) + g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, + (flags & FILE_READ_ONLY_VOLUME) != 0); + } + + g_free (rootdir); +} + +#endif /* G_OS_WIN32 */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void +g_set_io_error (GError **error, + const gchar *msg, + GFile *file, + gint errsv) +{ + GLocalFile *local = G_LOCAL_FILE (file); + gchar *display_name; + + display_name = g_filename_display_name (local->filename); + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + msg, display_name, g_strerror (errsv)); + g_free (display_name); +} +#pragma GCC diagnostic pop + +static GFileInfo * +g_local_file_query_filesystem_info (GFile *file, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + GFileInfo *info; + int statfs_result = 0; + gboolean no_size; +#ifndef G_OS_WIN32 + const char *fstype; +#ifdef USE_STATFS + guint64 block_size; + struct statfs statfs_buffer; +#elif defined(USE_STATVFS) + guint64 block_size; + struct statvfs statfs_buffer; +#endif /* USE_STATFS */ +#endif /* G_OS_WIN32 */ + GFileAttributeMatcher *attribute_matcher; + + no_size = FALSE; + +#ifdef USE_STATFS + +#if STATFS_ARGS == 2 + statfs_result = statfs (local->filename, &statfs_buffer); +#elif STATFS_ARGS == 4 + statfs_result = statfs (local->filename, &statfs_buffer, + sizeof (statfs_buffer), 0); +#endif /* STATFS_ARGS == 2 */ + block_size = statfs_buffer.f_bsize; + + /* Many backends can't report free size (for instance the gvfs fuse + * backend for backend not supporting this), and set f_bfree to 0, + * but it can be 0 for real too. We treat the available == 0 and + * free == 0 case as "both of these are invalid", but only on file systems + * which are known to not support this (otherwise we can omit metadata for + * systems which are legitimately full). */ +#if defined(__linux__) + if (statfs_result == 0 && + statfs_buffer.f_bavail == 0 && statfs_buffer.f_bfree == 0 && + (/* linux/ncp_fs.h: NCP_SUPER_MAGIC == 0x564c */ + statfs_buffer.f_type == 0x564c || + /* man statfs: FUSE_SUPER_MAGIC == 0x65735546 */ + statfs_buffer.f_type == 0x65735546)) + no_size = TRUE; +#endif /* __linux__ */ + +#elif defined(USE_STATVFS) + statfs_result = statvfs (local->filename, &statfs_buffer); + block_size = statfs_buffer.f_frsize; +#endif /* USE_STATFS */ + + if (statfs_result == -1) + { + int errsv = errno; + + g_set_io_error (error, + _("Error getting filesystem info for %s: %s"), + file, errsv); + return NULL; + } + + info = g_file_info_new (); + + attribute_matcher = g_file_attribute_matcher_new (attributes); + + if (!no_size && + g_file_attribute_matcher_matches (attribute_matcher, + G_FILE_ATTRIBUTE_FILESYSTEM_FREE)) + { +#ifdef G_OS_WIN32 + gchar *localdir = g_path_get_dirname (local->filename); + wchar_t *wdirname = g_utf8_to_utf16 (localdir, -1, NULL, NULL, NULL); + ULARGE_INTEGER li; + + g_free (localdir); + if (GetDiskFreeSpaceExW (wdirname, &li, NULL, NULL)) + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, (guint64)li.QuadPart); + g_free (wdirname); +#else +#if defined(USE_STATFS) || defined(USE_STATVFS) + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, block_size * statfs_buffer.f_bavail); +#endif +#endif + } + if (!no_size && + g_file_attribute_matcher_matches (attribute_matcher, + G_FILE_ATTRIBUTE_FILESYSTEM_SIZE)) + { +#ifdef G_OS_WIN32 + gchar *localdir = g_path_get_dirname (local->filename); + wchar_t *wdirname = g_utf8_to_utf16 (localdir, -1, NULL, NULL, NULL); + ULARGE_INTEGER li; + + g_free (localdir); + if (GetDiskFreeSpaceExW (wdirname, NULL, &li, NULL)) + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, (guint64)li.QuadPart); + g_free (wdirname); +#else +#if defined(USE_STATFS) || defined(USE_STATVFS) + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, block_size * statfs_buffer.f_blocks); +#endif +#endif /* G_OS_WIN32 */ + } + + if (!no_size && + g_file_attribute_matcher_matches (attribute_matcher, + G_FILE_ATTRIBUTE_FILESYSTEM_USED)) + { +#ifdef G_OS_WIN32 + gchar *localdir = g_path_get_dirname (local->filename); + wchar_t *wdirname = g_utf8_to_utf16 (localdir, -1, NULL, NULL, NULL); + ULARGE_INTEGER li_free; + ULARGE_INTEGER li_total; + + g_free (localdir); + if (GetDiskFreeSpaceExW (wdirname, &li_free, &li_total, NULL)) + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_USED, (guint64)li_total.QuadPart - (guint64)li_free.QuadPart); + g_free (wdirname); +#else + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_USED, block_size * (statfs_buffer.f_blocks - statfs_buffer.f_bfree)); +#endif /* G_OS_WIN32 */ + } + +#ifndef G_OS_WIN32 +#ifdef USE_STATFS +#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) + fstype = statfs_buffer.f_fstypename; +#else + fstype = get_fs_type (statfs_buffer.f_type); +#endif + +#elif defined(USE_STATVFS) +#if defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) + fstype = statfs_buffer.f_fstypename; +#elif defined(HAVE_STRUCT_STATVFS_F_BASETYPE) + fstype = statfs_buffer.f_basetype; +#else + fstype = NULL; +#endif +#endif /* USE_STATFS */ + + if (fstype && + g_file_attribute_matcher_matches (attribute_matcher, + G_FILE_ATTRIBUTE_FILESYSTEM_TYPE)) + g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, fstype); +#endif /* G_OS_WIN32 */ + + if (g_file_attribute_matcher_matches (attribute_matcher, + G_FILE_ATTRIBUTE_FILESYSTEM_READONLY)) + { +#ifdef G_OS_WIN32 + get_filesystem_readonly (info, local->filename); +#else + get_mount_info (info, local->filename, attribute_matcher); +#endif /* G_OS_WIN32 */ + } + +#ifndef G_OS_WIN32 + if (g_file_attribute_matcher_matches (attribute_matcher, + G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE)) + g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, + is_remote_fs_type (fstype)); +#endif + + g_file_attribute_matcher_unref (attribute_matcher); + + return info; +} + +static GMount * +g_local_file_find_enclosing_mount (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + GStatBuf buf; + char *mountpoint; + GMount *mount; + + if (g_lstat (local->filename, &buf) != 0) + goto error; + + mountpoint = find_mountpoint_for (local->filename, buf.st_dev, FALSE); + if (mountpoint == NULL) + goto error; + + mount = _g_mount_get_for_mount_path (mountpoint, cancellable); + g_free (mountpoint); + if (mount) + return mount; + +error: + g_set_io_error (error, + /* Translators: This is an error message when trying to find + * the enclosing (user visible) mount of a file, but none + * exists. + */ + _("Containing mount for file %s not found"), + file, 0); + + return NULL; +} + +static GFile * +g_local_file_set_display_name (GFile *file, + const char *display_name, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local, *new_local; + GFile *new_file, *parent; + GStatBuf statbuf; + GVfsClass *class; + GVfs *vfs; + int errsv; + + parent = g_file_get_parent (file); + if (parent == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Can’t rename root directory")); + return NULL; + } + + new_file = g_file_get_child_for_display_name (parent, display_name, error); + g_object_unref (parent); + + if (new_file == NULL) + return NULL; + local = G_LOCAL_FILE (file); + new_local = G_LOCAL_FILE (new_file); + + if (g_lstat (new_local->filename, &statbuf) == -1) + { + errsv = errno; + + if (errsv != ENOENT) + { + g_set_io_error (error, _("Error renaming file %s: %s"), new_file, errsv); + return NULL; + } + } + else + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_EXISTS, + _("Can’t rename file, filename already exists")); + return NULL; + } + + if (g_rename (local->filename, new_local->filename) == -1) + { + errsv = errno; + + if (errsv == EINVAL) + /* We can't get a rename file into itself error here, + * so this must be an invalid filename, on e.g. FAT + */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, + _("Invalid filename")); + else + g_set_io_error (error, + _("Error renaming file %s: %s"), + file, errsv); + g_object_unref (new_file); + return NULL; + } + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_moved) + class->local_file_moved (vfs, local->filename, new_local->filename); + + return new_file; +} + +static GFileInfo * +g_local_file_query_info (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + GFileInfo *info; + GFileAttributeMatcher *matcher; + char *basename, *dirname; + GLocalParentFileInfo parent_info; + + matcher = g_file_attribute_matcher_new (attributes); + + basename = g_path_get_basename (local->filename); + + dirname = g_path_get_dirname (local->filename); + _g_local_file_info_get_parent_info (dirname, matcher, &parent_info); + g_free (dirname); + + info = _g_local_file_info_get (basename, local->filename, + matcher, flags, &parent_info, + error); + + + _g_local_file_info_free_parent_info (&parent_info); + g_free (basename); + + g_file_attribute_matcher_unref (matcher); + + return info; +} + +static GFileAttributeInfoList * +g_local_file_query_settable_attributes (GFile *file, + GCancellable *cancellable, + GError **error) +{ + return g_file_attribute_info_list_ref (local_writable_attributes); +} + +static GFileAttributeInfoList * +g_local_file_query_writable_namespaces (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileAttributeInfoList *list; + GVfsClass *class; + GVfs *vfs; + + if (g_once_init_enter (&local_writable_namespaces)) + { + /* Writable namespaces: */ + + list = g_file_attribute_info_list_new (); + +#ifdef HAVE_XATTR + g_file_attribute_info_list_add (list, + "xattr", + G_FILE_ATTRIBUTE_TYPE_STRING, + G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE | + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); + g_file_attribute_info_list_add (list, + "xattr-sys", + G_FILE_ATTRIBUTE_TYPE_STRING, + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); +#endif + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->add_writable_namespaces) + class->add_writable_namespaces (vfs, list); + + g_once_init_leave (&local_writable_namespaces, (gsize)list); + } + list = (GFileAttributeInfoList *)local_writable_namespaces; + + return g_file_attribute_info_list_ref (list); +} + +static gboolean +g_local_file_set_attribute (GFile *file, + const char *attribute, + GFileAttributeType type, + gpointer value_p, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + + return _g_local_file_info_set_attribute (local->filename, + attribute, + type, + value_p, + flags, + cancellable, + error); +} + +static gboolean +g_local_file_set_attributes_from_info (GFile *file, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + int res, chained_res; + GFileIface *default_iface; + + res = _g_local_file_info_set_attributes (local->filename, + info, flags, + cancellable, + error); + + if (!res) + error = NULL; /* Don't write over error if further errors */ + + default_iface = g_type_default_interface_peek (G_TYPE_FILE); + + chained_res = (default_iface->set_attributes_from_info) (file, info, flags, cancellable, error); + + return res && chained_res; +} + +static GFileInputStream * +g_local_file_read (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + int fd, ret; + GLocalFileStat buf; + + fd = g_open (local->filename, O_RDONLY|O_BINARY, 0); + if (fd == -1) + { + int errsv = errno; + +#ifdef G_OS_WIN32 + if (errsv == EACCES) + { + /* Exploit the fact that on W32 the glib filename encoding is UTF8 */ + ret = GLIB_PRIVATE_CALL (g_win32_stat_utf8) (local->filename, &buf); + if (ret == 0 && S_ISDIR (buf.st_mode)) + errsv = EISDIR; + } +#endif + g_set_io_error (error, + _("Error opening file %s: %s"), + file, errsv); + return NULL; + } + + ret = g_local_file_fstat (fd, G_LOCAL_FILE_STAT_FIELD_TYPE, G_LOCAL_FILE_STAT_FIELD_ALL, &buf); + + if (ret == 0 && S_ISDIR (_g_stat_mode (&buf))) + { + (void) g_close (fd, NULL); + g_set_io_error (error, + _("Error opening file %s: %s"), + file, EISDIR); + return NULL; + } + + return _g_local_file_input_stream_new (fd); +} + +static GFileOutputStream * +g_local_file_append_to (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + return _g_local_file_output_stream_append (G_LOCAL_FILE (file)->filename, + flags, cancellable, error); +} + +static GFileOutputStream * +g_local_file_create (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + return _g_local_file_output_stream_create (G_LOCAL_FILE (file)->filename, + FALSE, flags, NULL, + cancellable, error); +} + +static GFileOutputStream * +g_local_file_replace (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + return _g_local_file_output_stream_replace (G_LOCAL_FILE (file)->filename, + FALSE, + etag, make_backup, flags, NULL, + cancellable, error); +} + +static GFileIOStream * +g_local_file_open_readwrite (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStream *output; + GFileIOStream *res; + + output = _g_local_file_output_stream_open (G_LOCAL_FILE (file)->filename, + TRUE, + cancellable, error); + if (output == NULL) + return NULL; + + res = _g_local_file_io_stream_new (G_LOCAL_FILE_OUTPUT_STREAM (output)); + g_object_unref (output); + return res; +} + +static GFileIOStream * +g_local_file_create_readwrite (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStream *output; + GFileIOStream *res; + + output = _g_local_file_output_stream_create (G_LOCAL_FILE (file)->filename, + TRUE, flags, NULL, + cancellable, error); + if (output == NULL) + return NULL; + + res = _g_local_file_io_stream_new (G_LOCAL_FILE_OUTPUT_STREAM (output)); + g_object_unref (output); + return res; +} + +static GFileIOStream * +g_local_file_replace_readwrite (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStream *output; + GFileIOStream *res; + + output = _g_local_file_output_stream_replace (G_LOCAL_FILE (file)->filename, + TRUE, + etag, make_backup, flags, NULL, + cancellable, error); + if (output == NULL) + return NULL; + + res = _g_local_file_io_stream_new (G_LOCAL_FILE_OUTPUT_STREAM (output)); + g_object_unref (output); + return res; +} + +static gboolean +g_local_file_delete (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + GVfsClass *class; + GVfs *vfs; + + if (g_remove (local->filename) == -1) + { + int errsv = errno; + + /* Posix allows EEXIST too, but the clearer error + is G_IO_ERROR_NOT_FOUND, and it's what nautilus + expects */ + if (errsv == EEXIST) + errsv = ENOTEMPTY; + + g_set_io_error (error, + _("Error removing file %s: %s"), + file, errsv); + return FALSE; + } + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_removed) + class->local_file_removed (vfs, local->filename); + + return TRUE; +} + +#ifndef G_OS_WIN32 + +static char * +strip_trailing_slashes (const char *path) +{ + char *path_copy; + int len; + + path_copy = g_strdup (path); + len = strlen (path_copy); + while (len > 1 && path_copy[len-1] == '/') + path_copy[--len] = 0; + + return path_copy; + } + +static char * +expand_symlink (const char *link) +{ + char *resolved, *canonical, *parent, *link2; + char symlink_value[4096]; +#ifdef G_OS_WIN32 +#else + gssize res; +#endif + +#ifdef G_OS_WIN32 +#else + res = readlink (link, symlink_value, sizeof (symlink_value) - 1); + + if (res == -1) + return g_strdup (link); + symlink_value[res] = 0; +#endif + + if (g_path_is_absolute (symlink_value)) + return g_canonicalize_filename (symlink_value, NULL); + else + { + link2 = strip_trailing_slashes (link); + parent = g_path_get_dirname (link2); + g_free (link2); + + resolved = g_build_filename (parent, symlink_value, NULL); + g_free (parent); + + canonical = g_canonicalize_filename (resolved, NULL); + + g_free (resolved); + + return canonical; + } +} + +static char * +expand_symlinks (const char *path, + dev_t *dev) +{ + char *tmp, *target; + GStatBuf target_stat; + int num_recursions; + + target = g_strdup (path); + + num_recursions = 0; + do + { + if (g_lstat (target, &target_stat) != 0) + { + g_free (target); + return NULL; + } + + if (S_ISLNK (target_stat.st_mode)) + { + tmp = target; + target = expand_symlink (target); + g_free (tmp); + } + + num_recursions++; + +#ifdef MAXSYMLINKS + if (num_recursions > MAXSYMLINKS) +#else + /* 40 is used in kernel sources currently: + * https://github.com/torvalds/linux/include/linux/namei.h + */ + if (num_recursions > 40) +#endif + { + g_free (target); + return NULL; + } + } + while (S_ISLNK (target_stat.st_mode)); + + if (dev) + *dev = target_stat.st_dev; + + return target; +} + +static char * +get_parent (const char *path, + dev_t *parent_dev) +{ + char *parent, *res; + char *path_copy; + + path_copy = strip_trailing_slashes (path); + + parent = g_path_get_dirname (path_copy); + if (strcmp (parent, ".") == 0) + { + g_free (parent); + g_free (path_copy); + return NULL; + } + g_free (path_copy); + + res = expand_symlinks (parent, parent_dev); + g_free (parent); + + return res; +} + +static char * +expand_all_symlinks (const char *path) +{ + char *parent, *parent_expanded; + char *basename, *res; + dev_t parent_dev; + + parent = get_parent (path, &parent_dev); + if (parent == NULL) + return NULL; + + if (g_strcmp0 (parent, "/") != 0) + { + parent_expanded = expand_all_symlinks (parent); + basename = g_path_get_basename (path); + res = g_build_filename (parent_expanded, basename, NULL); + g_free (basename); + g_free (parent_expanded); + } + else + res = g_strdup (path); + + g_free (parent); + + return res; +} + +static char * +find_mountpoint_for (const char *file, + dev_t dev, + gboolean resolve_basename_symlink) +{ + char *dir, *parent; + dev_t dir_dev, parent_dev; + + if (resolve_basename_symlink) + { + dir = expand_symlinks (file, NULL); + if (dir == NULL) + return NULL; + } + else + dir = g_strdup (file); + + dir_dev = dev; + + while (g_strcmp0 (dir, "/") != 0) + { + parent = get_parent (dir, &parent_dev); + if (parent == NULL) + { + g_free (dir); + return NULL; + } + + if (parent_dev != dir_dev) + { + g_free (parent); + return dir; + } + + g_free (dir); + dir = parent; + } + + return dir; +} + +char * +_g_local_file_find_topdir_for (const char *file) +{ + char *dir; + char *mountpoint = NULL; + dev_t dir_dev; + + dir = get_parent (file, &dir_dev); + if (dir == NULL) + return NULL; + + mountpoint = find_mountpoint_for (dir, dir_dev, TRUE); + g_free (dir); + + return mountpoint; +} + +static char * +get_unique_filename (const char *basename, + int id) +{ + const char *dot; + + if (id == 1) + return g_strdup (basename); + + dot = strchr (basename, '.'); + if (dot) + return g_strdup_printf ("%.*s.%d%s", (int)(dot - basename), basename, id, dot); + else + return g_strdup_printf ("%s.%d", basename, id); +} + +static gboolean +path_has_prefix (const char *path, + const char *prefix) +{ + int prefix_len; + + if (prefix == NULL) + return TRUE; + + prefix_len = strlen (prefix); + + if (strncmp (path, prefix, prefix_len) == 0 && + (prefix_len == 0 || /* empty prefix always matches */ + prefix[prefix_len - 1] == '/' || /* last char in prefix was a /, so it must be in path too */ + path[prefix_len] == 0 || + path[prefix_len] == '/')) + return TRUE; + + return FALSE; +} + +static char * +try_make_relative (const char *path, + const char *base) +{ + char *path2, *base2; + char *relative; + + path2 = expand_all_symlinks (path); + base2 = expand_all_symlinks (base); + + relative = NULL; + if (path2 != NULL && base2 != NULL && path_has_prefix (path2, base2)) + { + relative = path2 + strlen (base2); + while (*relative == '/') + relative ++; + relative = g_strdup (relative); + } + g_free (path2); + g_free (base2); + + if (relative) + return relative; + + /* Failed, use abs path */ + return g_strdup (path); +} + +static gboolean +ignore_trash_mount (GUnixMountEntry *mount) +{ + GUnixMountPoint *mount_point = NULL; + const gchar *mount_options; + gboolean retval = TRUE; + + if (g_unix_mount_is_system_internal (mount)) + return TRUE; + + mount_options = g_unix_mount_get_options (mount); + if (mount_options == NULL) + { + mount_point = g_unix_mount_point_at (g_unix_mount_get_mount_path (mount), + NULL); + if (mount_point != NULL) + mount_options = g_unix_mount_point_get_options (mount_point); + } + + if (mount_options == NULL || + strstr (mount_options, "x-gvfs-notrash") == NULL) + retval = FALSE; + + g_clear_pointer (&mount_point, g_unix_mount_point_free); + + return retval; +} + +static gboolean +ignore_trash_path (const gchar *topdir) +{ + GUnixMountEntry *mount; + gboolean retval = TRUE; + + mount = g_unix_mount_at (topdir, NULL); + if (mount == NULL) + goto out; + + retval = ignore_trash_mount (mount); + + out: + g_clear_pointer (&mount, g_unix_mount_free); + + return retval; +} + +gboolean +_g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev) +{ + static gsize home_dev_set = 0; + static dev_t home_dev; + static gboolean home_dev_valid = FALSE; + char *topdir, *globaldir, *trashdir, *tmpname; + uid_t uid; + char uid_str[32]; + GStatBuf global_stat, trash_stat; + gboolean res; + + if (g_once_init_enter (&home_dev_set)) + { + GStatBuf home_stat; + + if (g_stat (g_get_home_dir (), &home_stat) == 0) + { + home_dev = home_stat.st_dev; + home_dev_valid = TRUE; + } + else + { + home_dev_valid = FALSE; + } + + g_once_init_leave (&home_dev_set, 1); + } + + /* Assume we can trash to the home */ + if (!home_dev_valid) + return FALSE; + else if (dir_dev == home_dev) + return TRUE; + + topdir = find_mountpoint_for (dirname, dir_dev, TRUE); + if (topdir == NULL) + return FALSE; + + if (ignore_trash_path (topdir)) + { + g_free (topdir); + + return FALSE; + } + + globaldir = g_build_filename (topdir, ".Trash", NULL); + if (g_lstat (globaldir, &global_stat) == 0 && + S_ISDIR (global_stat.st_mode) && + (global_stat.st_mode & S_ISVTX) != 0) + { + /* got a toplevel sysadmin created dir, assume we + * can trash to it (we should be able to create a dir) + * This fails for the FAT case where the ownership of + * that dir would be wrong though.. + */ + g_free (globaldir); + g_free (topdir); + return TRUE; + } + g_free (globaldir); + + /* No global trash dir, or it failed the tests, fall back to $topdir/.Trash-$uid */ + uid = geteuid (); + g_snprintf (uid_str, sizeof (uid_str), "%lu", (unsigned long) uid); + + tmpname = g_strdup_printf (".Trash-%s", uid_str); + trashdir = g_build_filename (topdir, tmpname, NULL); + g_free (tmpname); + + if (g_lstat (trashdir, &trash_stat) == 0) + { + g_free (topdir); + g_free (trashdir); + return S_ISDIR (trash_stat.st_mode) && + trash_stat.st_uid == uid; + } + g_free (trashdir); + + /* User specific trash didn't exist, can we create it? */ + res = g_access (topdir, W_OK) == 0; + g_free (topdir); + + return res; +} + +#ifdef G_OS_UNIX +gboolean +_g_local_file_is_lost_found_dir (const char *path, dev_t path_dev) +{ + gboolean ret = FALSE; + gchar *mount_dir = NULL; + size_t mount_dir_len; + GStatBuf statbuf; + + if (!g_str_has_suffix (path, "/lost+found")) + goto out; + + mount_dir = find_mountpoint_for (path, path_dev, FALSE); + if (mount_dir == NULL) + goto out; + + mount_dir_len = strlen (mount_dir); + /* We special-case rootfs ('/') since it's the only case where + * mount_dir ends in '/' + */ + if (mount_dir_len == 1) + mount_dir_len--; + if (mount_dir_len + strlen ("/lost+found") != strlen (path)) + goto out; + + if (g_lstat (path, &statbuf) != 0) + goto out; + + if (!(S_ISDIR (statbuf.st_mode) && + statbuf.st_uid == 0 && + statbuf.st_gid == 0)) + goto out; + + ret = TRUE; + + out: + g_free (mount_dir); + return ret; +} +#endif + +static gboolean +g_local_file_trash (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + GStatBuf file_stat, home_stat; + const char *homedir; + char *trashdir, *topdir, *infodir, *filesdir; + char *basename, *trashname, *trashfile, *infoname, *infofile; + char *original_name, *original_name_escaped; + int i; + char *data; + char *path; + gboolean is_homedir_trash; + char *delete_time = NULL; + int fd; + GStatBuf trash_stat, global_stat; + char *dirname, *globaldir; + GVfsClass *class; + GVfs *vfs; + int errsv; + + if (glib_should_use_portal ()) + return g_trash_portal_trash_file (file, error); + + if (g_lstat (local->filename, &file_stat) != 0) + { + errsv = errno; + + g_set_io_error (error, + _("Error trashing file %s: %s"), + file, errsv); + return FALSE; + } + + homedir = g_get_home_dir (); + if (g_stat (homedir, &home_stat) != 0) + { + errsv = errno; + + g_set_io_error (error, + _("Error trashing file %s: %s"), + file, errsv); + return FALSE; + } + + is_homedir_trash = FALSE; + trashdir = NULL; + + /* On overlayfs, a file's st_dev will be different to the home directory's. + * We still want to create our trash directory under the home directory, so + * instead we should stat the directory that the file we're deleting is in as + * this will have the same st_dev. + */ + if (!S_ISDIR (file_stat.st_mode)) + { + path = g_path_get_dirname (local->filename); + /* If the parent is a symlink to a different device then it might have + * st_dev equal to the home directory's, in which case we will end up + * trying to rename across a filesystem boundary, which doesn't work. So + * we use g_stat here instead of g_lstat, to know where the symlink + * points to. */ + if (g_stat (path, &file_stat)) + { + errsv = errno; + g_free (path); + + g_set_io_error (error, + _("Error trashing file %s: %s"), + file, errsv); + return FALSE; + } + g_free (path); + } + + if (file_stat.st_dev == home_stat.st_dev) + { + is_homedir_trash = TRUE; + errno = 0; + trashdir = g_build_filename (g_get_user_data_dir (), "Trash", NULL); + if (g_mkdir_with_parents (trashdir, 0700) < 0) + { + char *display_name; + errsv = errno; + + display_name = g_filename_display_name (trashdir); + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Unable to create trash directory %s: %s"), + display_name, g_strerror (errsv)); + g_free (display_name); + g_free (trashdir); + return FALSE; + } + topdir = g_strdup (g_get_user_data_dir ()); + } + else + { + uid_t uid; + char uid_str[32]; + gboolean success = FALSE; + + uid = geteuid (); + g_snprintf (uid_str, sizeof (uid_str), "%lu", (unsigned long)uid); + + topdir = _g_local_file_find_topdir_for (local->filename); + if (topdir == NULL) + { + g_set_io_error (error, + _("Unable to find toplevel directory to trash %s"), + file, ENOTSUP); + return FALSE; + } + + if (ignore_trash_path (topdir)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Trashing on system internal mounts is not supported")); + g_free (topdir); + + return FALSE; + } + + /* Try looking for global trash dir $topdir/.Trash/$uid */ + globaldir = g_build_filename (topdir, ".Trash", NULL); + if (g_lstat (globaldir, &global_stat) == 0 && + S_ISDIR (global_stat.st_mode) && + (global_stat.st_mode & S_ISVTX) != 0) + { + trashdir = g_build_filename (globaldir, uid_str, NULL); + success = TRUE; + + if (g_lstat (trashdir, &trash_stat) == 0) + { + if (!S_ISDIR (trash_stat.st_mode) || + trash_stat.st_uid != uid) + { + /* Not a directory or not owned by user, ignore */ + g_free (trashdir); + trashdir = NULL; + success = FALSE; + } + } + else if (g_mkdir (trashdir, 0700) == -1) + { + g_free (trashdir); + trashdir = NULL; + success = FALSE; + } + } + g_free (globaldir); + + if (trashdir == NULL) + { + gboolean tried_create; + + /* No global trash dir, or it failed the tests, fall back to $topdir/.Trash-$uid */ + dirname = g_strdup_printf (".Trash-%s", uid_str); + trashdir = g_build_filename (topdir, dirname, NULL); + success = TRUE; + g_free (dirname); + + tried_create = FALSE; + + retry: + if (g_lstat (trashdir, &trash_stat) == 0) + { + if (!S_ISDIR (trash_stat.st_mode) || + trash_stat.st_uid != uid) + { + /* Remove the failed directory */ + if (tried_create) + g_remove (trashdir); + + /* Not a directory or not owned by user, ignore */ + success = FALSE; + } + } + else + { + if (!tried_create && + g_mkdir (trashdir, 0700) != -1) + { + /* Ensure that the created dir has the right uid etc. + This might fail on e.g. a FAT dir */ + tried_create = TRUE; + goto retry; + } + else + { + success = FALSE; + } + } + } + + if (!success) + { + gchar *trashdir_display_name = NULL, *file_display_name = NULL; + + trashdir_display_name = g_filename_display_name (trashdir); + file_display_name = g_filename_display_name (local->filename); + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Unable to find or create trash directory %s to trash %s"), + trashdir_display_name, file_display_name); + + g_free (trashdir_display_name); + g_free (file_display_name); + + g_free (topdir); + g_free (trashdir); + + return FALSE; + } + } + + /* Trashdir points to the trash dir with the "info" and "files" subdirectories */ + + infodir = g_build_filename (trashdir, "info", NULL); + filesdir = g_build_filename (trashdir, "files", NULL); + + /* Make sure we have the subdirectories */ + if ((g_mkdir (infodir, 0700) == -1 && errno != EEXIST) || + (g_mkdir (filesdir, 0700) == -1 && errno != EEXIST)) + { + gchar *trashdir_display_name = NULL, *file_display_name = NULL; + + trashdir_display_name = g_filename_display_name (trashdir); + file_display_name = g_filename_display_name (local->filename); + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Unable to find or create trash directory %s to trash %s"), + trashdir_display_name, file_display_name); + + g_free (trashdir_display_name); + g_free (file_display_name); + + g_free (topdir); + g_free (trashdir); + g_free (infodir); + g_free (filesdir); + + return FALSE; + } + + g_free (trashdir); + + basename = g_path_get_basename (local->filename); + i = 1; + trashname = NULL; + infofile = NULL; + do { + g_free (trashname); + g_free (infofile); + + trashname = get_unique_filename (basename, i++); + infoname = g_strconcat (trashname, ".trashinfo", NULL); + infofile = g_build_filename (infodir, infoname, NULL); + g_free (infoname); + + fd = g_open (infofile, O_CREAT | O_EXCL, 0666); + errsv = errno; + } while (fd == -1 && errsv == EEXIST); + + g_free (basename); + g_free (infodir); + + if (fd == -1) + { + errsv = errno; + + g_free (filesdir); + g_free (topdir); + g_free (trashname); + g_free (infofile); + + g_set_io_error (error, + _("Unable to create trashing info file for %s: %s"), + file, errsv); + return FALSE; + } + + (void) g_close (fd, NULL); + + /* Write the full content of the info file before trashing to make + * sure someone doesn't read an empty file. See #749314 + */ + + /* Use absolute names for homedir */ + if (is_homedir_trash) + original_name = g_strdup (local->filename); + else + original_name = try_make_relative (local->filename, topdir); + original_name_escaped = g_uri_escape_string (original_name, "/", FALSE); + + g_free (original_name); + g_free (topdir); + + { + GDateTime *now = g_date_time_new_now_local (); + if (now != NULL) + delete_time = g_date_time_format (now, "%Y-%m-%dT%H:%M:%S"); + else + delete_time = g_strdup ("9999-12-31T23:59:59"); + g_date_time_unref (now); + } + + data = g_strdup_printf ("[Trash Info]\nPath=%s\nDeletionDate=%s\n", + original_name_escaped, delete_time); + g_free (delete_time); + + g_file_set_contents_full (infofile, data, -1, + G_FILE_SET_CONTENTS_CONSISTENT | G_FILE_SET_CONTENTS_ONLY_EXISTING, + 0600, NULL); + + /* TODO: Maybe we should verify that you can delete the file from the trash + * before moving it? OTOH, that is hard, as it needs a recursive scan + */ + + trashfile = g_build_filename (filesdir, trashname, NULL); + + g_free (filesdir); + + if (g_rename (local->filename, trashfile) == -1) + { + errsv = errno; + + g_unlink (infofile); + + g_free (trashname); + g_free (infofile); + g_free (trashfile); + + if (errsv == EXDEV) + /* The trash dir was actually on another fs anyway!? + * This can happen when the same device is mounted multiple + * times, or with bind mounts of the same fs. + */ + g_set_io_error (error, + _("Unable to trash file %s across filesystem boundaries"), + file, ENOTSUP); + else + g_set_io_error (error, + _("Unable to trash file %s: %s"), + file, errsv); + return FALSE; + } + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_moved) + class->local_file_moved (vfs, local->filename, trashfile); + + g_free (trashfile); + + /* TODO: Do we need to update mtime/atime here after the move? */ + + g_free (infofile); + g_free (data); + + g_free (original_name_escaped); + g_free (trashname); + + return TRUE; +} +#else /* G_OS_WIN32 */ +gboolean +_g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev) +{ + return FALSE; /* XXX ??? */ +} + +static gboolean +g_local_file_trash (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + SHFILEOPSTRUCTW op = {0}; + gboolean success; + wchar_t *wfilename; + long len; + + wfilename = g_utf8_to_utf16 (local->filename, -1, NULL, &len, NULL); + /* SHFILEOPSTRUCT.pFrom is double-zero-terminated */ + wfilename = g_renew (wchar_t, wfilename, len + 2); + wfilename[len + 1] = 0; + + op.wFunc = FO_DELETE; + op.pFrom = wfilename; + op.fFlags = FOF_ALLOWUNDO; + + success = SHFileOperationW (&op) == 0; + + if (success && op.fAnyOperationsAborted) + { + if (cancellable && !g_cancellable_is_cancelled (cancellable)) + g_cancellable_cancel (cancellable); + g_set_io_error (error, + _("Unable to trash file %s: %s"), + file, ECANCELED); + success = FALSE; + } + else if (!success) + g_set_io_error (error, + _("Unable to trash file %s"), + file, 0); + + g_free (wfilename); + return success; +} +#endif /* G_OS_WIN32 */ + +static gboolean +g_local_file_make_directory (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + + if (g_mkdir (local->filename, 0777) == -1) + { + int errsv = errno; + + if (errsv == EINVAL) + /* This must be an invalid filename, on e.g. FAT */ + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_INVALID_FILENAME, + _("Invalid filename")); + else + g_set_io_error (error, + _("Error creating directory %s: %s"), + file, errsv); + return FALSE; + } + + return TRUE; +} + +#ifdef HAVE_SYMLINK +static gboolean +g_local_file_make_symbolic_link (GFile *file, + const char *symlink_value, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local = G_LOCAL_FILE (file); + + if (symlink (symlink_value, local->filename) == -1) + { + int errsv = errno; + + if (errsv == EINVAL) + /* This must be an invalid filename, on e.g. FAT */ + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_INVALID_FILENAME, + _("Invalid filename")); + else if (errsv == EPERM) + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Filesystem does not support symbolic links")); + else + g_set_io_error (error, + _("Error making symbolic link %s: %s"), + file, errsv); + return FALSE; + } + return TRUE; +} +#endif + +static gboolean +g_local_file_move (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + GLocalFile *local_source, *local_destination; + GStatBuf statbuf; + gboolean destination_exist, source_is_dir; + char *backup_name; + int res; + off_t source_size; + GVfsClass *class; + GVfs *vfs; + + if (!G_IS_LOCAL_FILE (source) || + !G_IS_LOCAL_FILE (destination)) + { + /* Fall back to default move */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Move not supported"); + return FALSE; + } + + local_source = G_LOCAL_FILE (source); + local_destination = G_LOCAL_FILE (destination); + + res = g_lstat (local_source->filename, &statbuf); + if (res == -1) + { + int errsv = errno; + + g_set_io_error (error, + _("Error moving file %s: %s"), + source, errsv); + return FALSE; + } + + source_is_dir = S_ISDIR (statbuf.st_mode); + source_size = statbuf.st_size; + + destination_exist = FALSE; + res = g_lstat (local_destination->filename, &statbuf); + if (res == 0) + { + destination_exist = TRUE; /* Target file exists */ + + if (flags & G_FILE_COPY_OVERWRITE) + { + /* Always fail on dirs, even with overwrite */ + if (S_ISDIR (statbuf.st_mode)) + { + if (source_is_dir) + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_WOULD_MERGE, + _("Can’t move directory over directory")); + else + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_IS_DIRECTORY, + _("Can’t copy over directory")); + return FALSE; + } + } + else + { + g_set_io_error (error, + _("Error moving file %s: %s"), + source, EEXIST); + return FALSE; + } + } + + if (flags & G_FILE_COPY_BACKUP && destination_exist) + { + backup_name = g_strconcat (local_destination->filename, "~", NULL); + if (g_rename (local_destination->filename, backup_name) == -1) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Backup file creation failed")); + g_free (backup_name); + return FALSE; + } + g_free (backup_name); + destination_exist = FALSE; /* It did, but no more */ + } + + if (source_is_dir && destination_exist && (flags & G_FILE_COPY_OVERWRITE)) + { + /* Source is a dir, destination exists (and is not a dir, because that would have failed + earlier), and we're overwriting. Manually remove the target so we can do the rename. */ + res = g_unlink (local_destination->filename); + if (res == -1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error removing target file: %s"), + g_strerror (errsv)); + return FALSE; + } + } + + if (g_rename (local_source->filename, local_destination->filename) == -1) + { + int errsv = errno; + + if (errsv == EXDEV) + /* This will cause the fallback code to run */ + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Move between mounts not supported")); + else if (errsv == EINVAL) + /* This must be an invalid filename, on e.g. FAT, or + we're trying to move the file into itself... + We return invalid filename for both... */ + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_INVALID_FILENAME, + _("Invalid filename")); + else + g_set_io_error (error, + _("Error moving file %s: %s"), + source, errsv); + return FALSE; + } + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_moved) + class->local_file_moved (vfs, local_source->filename, local_destination->filename); + + /* Make sure we send full copied size */ + if (progress_callback) + progress_callback (source_size, source_size, progress_callback_data); + + return TRUE; +} + +#ifdef G_OS_WIN32 + +gboolean +g_local_file_is_nfs_home (const gchar *filename) +{ + return FALSE; +} + +#else + +static gboolean +is_remote_fs_type (const gchar *fsname) +{ + if (fsname != NULL) + { + if (strcmp (fsname, "nfs") == 0) + return TRUE; + if (strcmp (fsname, "nfs4") == 0) + return TRUE; + if (strcmp (fsname, "cifs") == 0) + return TRUE; + if (strcmp (fsname, "smb") == 0) + return TRUE; + if (strcmp (fsname, "smb2") == 0) + return TRUE; + } + + return FALSE; +} + +gboolean +g_local_file_is_nfs_home (const gchar *filename) +{ + static gboolean remote_home = FALSE; + static gsize initialized; + const gchar *home; + + home = g_get_home_dir (); + if (path_has_prefix (filename, home)) + { + if (g_once_init_enter (&initialized)) + { + GFile *file; + GFileInfo *info; + const gchar *fs_type = NULL; + + file = _g_local_file_new (home); + info = g_local_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, NULL, NULL); + if (info != NULL) + fs_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE); + if (g_strcmp0 (fs_type, "nfs") == 0 || g_strcmp0 (fs_type, "nfs4") == 0) + remote_home = TRUE; + g_clear_object (&info); + g_object_unref (file); + + g_once_init_leave (&initialized, TRUE); + } + return remote_home; + } + + return FALSE; +} +#endif /* !G_OS_WIN32 */ + +static GFileMonitor* +g_local_file_monitor_dir (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local_file = G_LOCAL_FILE (file); + + return g_local_file_monitor_new_for_path (local_file->filename, TRUE, flags, error); +} + +static GFileMonitor* +g_local_file_monitor_file (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error) +{ + GLocalFile *local_file = G_LOCAL_FILE (file); + + return g_local_file_monitor_new_for_path (local_file->filename, FALSE, flags, error); +} + +/* Here is the GLocalFile implementation of g_file_measure_disk_usage(). + * + * If available, we use fopenat() in preference to filenames for + * efficiency and safety reasons. We know that fopenat() is available + * based on if AT_FDCWD is defined. POSIX guarantees that this will be + * defined as a macro. + * + * We use a linked list of stack-allocated GSList nodes in order to be + * able to reconstruct the filename for error messages. We actually + * pass the filename to operate on through the top node of the list. + * + * In case we're using openat(), this top filename will be a basename + * which should be opened in the directory which has also had its fd + * passed along. If we're not using openat() then it will be a full + * absolute filename. + */ + +static gboolean +g_local_file_measure_size_error (GFileMeasureFlags flags, + gint saved_errno, + GSList *name, + GError **error) +{ + /* Only report an error if we were at the toplevel or if the caller + * requested reporting of all errors. + */ + if ((name->next == NULL) || (flags & G_FILE_MEASURE_REPORT_ANY_ERROR)) + { + GString *filename; + GSList *node; + + /* Skip some work if there is no error return */ + if (!error) + return FALSE; + +#ifdef AT_FDCWD + /* If using openat() we need to rebuild the filename for the message */ + filename = g_string_new (name->data); + for (node = name->next; node; node = node->next) + { + gchar *utf8; + + g_string_prepend_c (filename, G_DIR_SEPARATOR); + utf8 = g_filename_display_name (node->data); + g_string_prepend (filename, utf8); + g_free (utf8); + } +#else + { + gchar *utf8; + + /* Otherwise, we already have it, so just use it. */ + node = name; + filename = g_string_new (NULL); + utf8 = g_filename_display_name (node->data); + g_string_append (filename, utf8); + g_free (utf8); + } +#endif + + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), + _("Could not determine the disk usage of %s: %s"), + filename->str, g_strerror (saved_errno)); + + g_string_free (filename, TRUE); + + return FALSE; + } + + else + /* We're not reporting this error... */ + return TRUE; +} + +typedef struct +{ + GFileMeasureFlags flags; + dev_t contained_on; + GCancellable *cancellable; + + GFileMeasureProgressCallback progress_callback; + gpointer progress_data; + + guint64 disk_usage; + guint64 num_dirs; + guint64 num_files; + + guint64 last_progress_report; +} MeasureState; + +static gboolean +g_local_file_measure_size_of_contents (gint fd, + GSList *dir_name, + MeasureState *state, + GError **error); + +static gboolean +g_local_file_measure_size_of_file (gint parent_fd, + GSList *name, + MeasureState *state, + GError **error) +{ + GLocalFileStat buf; + + if (g_cancellable_set_error_if_cancelled (state->cancellable, error)) + return FALSE; + +#if defined (AT_FDCWD) + if (g_local_file_fstatat (parent_fd, name->data, AT_SYMLINK_NOFOLLOW, + G_LOCAL_FILE_STAT_FIELD_BASIC_STATS, + G_LOCAL_FILE_STAT_FIELD_ALL & (~G_LOCAL_FILE_STAT_FIELD_ATIME), + &buf) != 0) + { + int errsv = errno; + return g_local_file_measure_size_error (state->flags, errsv, name, error); + } +#elif defined (HAVE_LSTAT) || !defined (G_OS_WIN32) + if (g_lstat (name->data, &buf) != 0) + { + int errsv = errno; + return g_local_file_measure_size_error (state->flags, errsv, name, error); + } +#else /* !AT_FDCWD && !HAVE_LSTAT && G_OS_WIN32 */ + if (GLIB_PRIVATE_CALL (g_win32_lstat_utf8) (name->data, &buf) != 0) + { + int errsv = errno; + return g_local_file_measure_size_error (state->flags, errsv, name, error); + } +#endif + + if (name->next) + { + /* If not at the toplevel, check for a device boundary. */ + + if (state->flags & G_FILE_MEASURE_NO_XDEV) + if (state->contained_on != _g_stat_dev (&buf)) + return TRUE; + } + else + { + /* If, however, this is the toplevel, set the device number so + * that recursive invocations can compare against it. + */ + state->contained_on = _g_stat_dev (&buf); + } + +#if defined (G_OS_WIN32) + if (~state->flags & G_FILE_MEASURE_APPARENT_SIZE) + state->disk_usage += buf.allocated_size; + else +#elif defined (HAVE_STRUCT_STAT_ST_BLOCKS) + if (~state->flags & G_FILE_MEASURE_APPARENT_SIZE) + state->disk_usage += _g_stat_blocks (&buf) * G_GUINT64_CONSTANT (512); + else +#endif + state->disk_usage += _g_stat_size (&buf); + + if (S_ISDIR (_g_stat_mode (&buf))) + state->num_dirs++; + else + state->num_files++; + + if (state->progress_callback) + { + /* We could attempt to do some cleverness here in order to avoid + * calling clock_gettime() so much, but we're doing stats and opens + * all over the place already... + */ + if (state->last_progress_report) + { + guint64 now; + + now = g_get_monotonic_time (); + + if (state->last_progress_report + 200 * G_TIME_SPAN_MILLISECOND < now) + { + (* state->progress_callback) (TRUE, + state->disk_usage, state->num_dirs, state->num_files, + state->progress_data); + state->last_progress_report = now; + } + } + else + { + /* We must do an initial report to inform that more reports + * will be coming. + */ + (* state->progress_callback) (TRUE, 0, 0, 0, state->progress_data); + state->last_progress_report = g_get_monotonic_time (); + } + } + + if (S_ISDIR (_g_stat_mode (&buf))) + { + int dir_fd = -1; +#ifdef AT_FDCWD + int errsv; +#endif + + if (g_cancellable_set_error_if_cancelled (state->cancellable, error)) + return FALSE; + +#ifdef AT_FDCWD +#ifdef HAVE_OPEN_O_DIRECTORY + dir_fd = openat (parent_fd, name->data, O_RDONLY|O_DIRECTORY); +#else + dir_fd = openat (parent_fd, name->data, O_RDONLY); +#endif + errsv = errno; + if (dir_fd < 0) + return g_local_file_measure_size_error (state->flags, errsv, name, error); +#endif + + if (!g_local_file_measure_size_of_contents (dir_fd, name, state, error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +g_local_file_measure_size_of_contents (gint fd, + GSList *dir_name, + MeasureState *state, + GError **error) +{ + gboolean success = TRUE; + const gchar *name; + GDir *dir; + gint saved_errno; + +#ifdef AT_FDCWD + { + /* If this fails, we want to preserve the errno from fdopendir() */ + DIR *dirp; + dirp = fdopendir (fd); + saved_errno = errno; + dir = dirp ? GLIB_PRIVATE_CALL(g_dir_new_from_dirp) (dirp) : NULL; + g_assert ((dirp == NULL) == (dir == NULL)); + } +#else + dir = GLIB_PRIVATE_CALL(g_dir_open_with_errno) (dir_name->data, 0); + saved_errno = errno; +#endif + + if (dir == NULL) + { +#ifdef AT_FDCWD + close (fd); +#endif + + return g_local_file_measure_size_error (state->flags, saved_errno, dir_name, error); + } + + while (success && (name = g_dir_read_name (dir))) + { + GSList node; + + node.next = dir_name; +#ifdef AT_FDCWD + node.data = (gchar *) name; +#else + node.data = g_build_filename (dir_name->data, name, NULL); +#endif + + success = g_local_file_measure_size_of_file (fd, &node, state, error); + +#ifndef AT_FDCWD + g_free (node.data); +#endif + } + + g_dir_close (dir); + + return success; +} + +static gboolean +g_local_file_measure_disk_usage (GFile *file, + GFileMeasureFlags flags, + GCancellable *cancellable, + GFileMeasureProgressCallback progress_callback, + gpointer progress_data, + guint64 *disk_usage, + guint64 *num_dirs, + guint64 *num_files, + GError **error) +{ + GLocalFile *local_file = G_LOCAL_FILE (file); + MeasureState state = { 0, }; + gint root_fd = -1; + GSList node; + + state.flags = flags; + state.cancellable = cancellable; + state.progress_callback = progress_callback; + state.progress_data = progress_data; + +#ifdef AT_FDCWD + root_fd = AT_FDCWD; +#endif + + node.data = local_file->filename; + node.next = NULL; + + if (!g_local_file_measure_size_of_file (root_fd, &node, &state, error)) + return FALSE; + + if (disk_usage) + *disk_usage = state.disk_usage; + + if (num_dirs) + *num_dirs = state.num_dirs; + + if (num_files) + *num_files = state.num_files; + + return TRUE; +} + +static void +g_local_file_file_iface_init (GFileIface *iface) +{ + iface->dup = g_local_file_dup; + iface->hash = g_local_file_hash; + iface->equal = g_local_file_equal; + iface->is_native = g_local_file_is_native; + iface->has_uri_scheme = g_local_file_has_uri_scheme; + iface->get_uri_scheme = g_local_file_get_uri_scheme; + iface->get_basename = g_local_file_get_basename; + iface->get_path = g_local_file_get_path; + iface->get_uri = g_local_file_get_uri; + iface->get_parse_name = g_local_file_get_parse_name; + iface->get_parent = g_local_file_get_parent; + iface->prefix_matches = g_local_file_prefix_matches; + iface->get_relative_path = g_local_file_get_relative_path; + iface->resolve_relative_path = g_local_file_resolve_relative_path; + iface->get_child_for_display_name = g_local_file_get_child_for_display_name; + iface->set_display_name = g_local_file_set_display_name; + iface->enumerate_children = g_local_file_enumerate_children; + iface->query_info = g_local_file_query_info; + iface->query_filesystem_info = g_local_file_query_filesystem_info; + iface->find_enclosing_mount = g_local_file_find_enclosing_mount; + iface->query_settable_attributes = g_local_file_query_settable_attributes; + iface->query_writable_namespaces = g_local_file_query_writable_namespaces; + iface->set_attribute = g_local_file_set_attribute; + iface->set_attributes_from_info = g_local_file_set_attributes_from_info; + iface->read_fn = g_local_file_read; + iface->append_to = g_local_file_append_to; + iface->create = g_local_file_create; + iface->replace = g_local_file_replace; + iface->open_readwrite = g_local_file_open_readwrite; + iface->create_readwrite = g_local_file_create_readwrite; + iface->replace_readwrite = g_local_file_replace_readwrite; + iface->delete_file = g_local_file_delete; + iface->trash = g_local_file_trash; + iface->make_directory = g_local_file_make_directory; +#ifdef HAVE_SYMLINK + iface->make_symbolic_link = g_local_file_make_symbolic_link; +#endif + iface->move = g_local_file_move; + iface->monitor_dir = g_local_file_monitor_dir; + iface->monitor_file = g_local_file_monitor_file; + iface->measure_disk_usage = g_local_file_measure_disk_usage; + + iface->supports_thread_contexts = TRUE; +} diff --git a/gio/glocalfile.h b/gio/glocalfile.h new file mode 100644 index 0000000..ac0ad9d --- /dev/null +++ b/gio/glocalfile.h @@ -0,0 +1,58 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOCAL_FILE_H__ +#define __G_LOCAL_FILE_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_LOCAL_FILE (_g_local_file_get_type ()) +#define G_LOCAL_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE, GLocalFile)) +#define G_LOCAL_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE, GLocalFileClass)) +#define G_IS_LOCAL_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE)) +#define G_IS_LOCAL_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE)) +#define G_LOCAL_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE, GLocalFileClass)) + +typedef struct _GLocalFile GLocalFile; +typedef struct _GLocalFileClass GLocalFileClass; + +struct _GLocalFileClass +{ + GObjectClass parent_class; +}; + +GType _g_local_file_get_type (void) G_GNUC_CONST; + +GFile * _g_local_file_new (const char *filename); + +const char * _g_local_file_get_filename (GLocalFile *file); + +gboolean g_local_file_is_nfs_home (const gchar *filename); + +GFile * g_local_file_new_from_dirname_and_basename (const char *dirname, + const char *basename); + +gchar *_g_local_file_find_topdir_for (const char *file_path); + +G_END_DECLS + +#endif /* __G_LOCAL_FILE_H__ */ diff --git a/gio/glocalfileenumerator.c b/gio/glocalfileenumerator.c new file mode 100644 index 0000000..4f316f7 --- /dev/null +++ b/gio/glocalfileenumerator.c @@ -0,0 +1,458 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include "glibintl.h" + + +#define CHUNK_SIZE 1000 + +#ifdef G_OS_WIN32 +#define USE_GDIR +#endif + +#ifndef USE_GDIR + +#include +#include +#include + +typedef struct { + char *name; + long inode; + GFileType type; +} DirEntry; + +#endif + +struct _GLocalFileEnumerator +{ + GFileEnumerator parent; + + GFileAttributeMatcher *matcher; + GFileAttributeMatcher *reduced_matcher; + char *filename; + char *attributes; + GFileQueryInfoFlags flags; + + gboolean got_parent_info; + GLocalParentFileInfo parent_info; + +#ifdef USE_GDIR + GDir *dir; +#else + DIR *dir; + DirEntry *entries; + int entries_pos; + gboolean at_end; +#endif + + gboolean follow_symlinks; +}; + +#define g_local_file_enumerator_get_type _g_local_file_enumerator_get_type +G_DEFINE_TYPE (GLocalFileEnumerator, g_local_file_enumerator, G_TYPE_FILE_ENUMERATOR) + +static GFileInfo *g_local_file_enumerator_next_file (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error); +static gboolean g_local_file_enumerator_close (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error); + + +static void +free_entries (GLocalFileEnumerator *local) +{ +#ifndef USE_GDIR + int i; + + if (local->entries != NULL) + { + for (i = 0; local->entries[i].name != NULL; i++) + g_free (local->entries[i].name); + + g_free (local->entries); + } +#endif +} + +static void +g_local_file_enumerator_finalize (GObject *object) +{ + GLocalFileEnumerator *local; + + local = G_LOCAL_FILE_ENUMERATOR (object); + + if (local->got_parent_info) + _g_local_file_info_free_parent_info (&local->parent_info); + g_free (local->filename); + g_file_attribute_matcher_unref (local->matcher); + g_file_attribute_matcher_unref (local->reduced_matcher); + if (local->dir) + { +#ifdef USE_GDIR + g_dir_close (local->dir); +#else + closedir (local->dir); +#endif + local->dir = NULL; + } + + free_entries (local); + + G_OBJECT_CLASS (g_local_file_enumerator_parent_class)->finalize (object); +} + + +static void +g_local_file_enumerator_class_init (GLocalFileEnumeratorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GFileEnumeratorClass *enumerator_class = G_FILE_ENUMERATOR_CLASS (klass); + + gobject_class->finalize = g_local_file_enumerator_finalize; + + enumerator_class->next_file = g_local_file_enumerator_next_file; + enumerator_class->close_fn = g_local_file_enumerator_close; +} + +static void +g_local_file_enumerator_init (GLocalFileEnumerator *local) +{ +} + +#ifdef USE_GDIR +static void +convert_file_to_io_error (GError **error, + GError *file_error) +{ + int new_code; + + if (file_error == NULL) + return; + + new_code = G_IO_ERROR_FAILED; + + if (file_error->domain == G_FILE_ERROR) + { + switch (file_error->code) + { + case G_FILE_ERROR_NOENT: + new_code = G_IO_ERROR_NOT_FOUND; + break; + case G_FILE_ERROR_ACCES: + new_code = G_IO_ERROR_PERMISSION_DENIED; + break; + case G_FILE_ERROR_NOTDIR: + new_code = G_IO_ERROR_NOT_DIRECTORY; + break; + case G_FILE_ERROR_MFILE: + new_code = G_IO_ERROR_TOO_MANY_OPEN_FILES; + break; + default: + break; + } + } + + g_set_error_literal (error, G_IO_ERROR, + new_code, + file_error->message); +} +#else +static GFileAttributeMatcher * +g_file_attribute_matcher_subtract_attributes (GFileAttributeMatcher *matcher, + const char * attributes) +{ + GFileAttributeMatcher *result, *tmp; + + tmp = g_file_attribute_matcher_new (attributes); + result = g_file_attribute_matcher_subtract (matcher, tmp); + g_file_attribute_matcher_unref (tmp); + + return result; +} +#endif + +GFileEnumerator * +_g_local_file_enumerator_new (GLocalFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GLocalFileEnumerator *local; + char *filename = g_file_get_path (G_FILE (file)); + +#ifdef USE_GDIR + GError *dir_error; + GDir *dir; + + dir_error = NULL; + dir = g_dir_open (filename, 0, error != NULL ? &dir_error : NULL); + if (dir == NULL) + { + if (error != NULL) + { + convert_file_to_io_error (error, dir_error); + g_error_free (dir_error); + } + g_free (filename); + return NULL; + } +#else + DIR *dir; + int errsv; + + dir = opendir (filename); + if (dir == NULL) + { + gchar *utf8_filename; + errsv = errno; + + utf8_filename = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL); + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + "Error opening directory '%s': %s", + utf8_filename, g_strerror (errsv)); + g_free (utf8_filename); + g_free (filename); + return NULL; + } + +#endif + + local = g_object_new (G_TYPE_LOCAL_FILE_ENUMERATOR, + "container", file, + NULL); + + local->dir = dir; + local->filename = filename; + local->matcher = g_file_attribute_matcher_new (attributes); +#ifndef USE_GDIR + local->reduced_matcher = g_file_attribute_matcher_subtract_attributes (local->matcher, + G_LOCAL_FILE_INFO_NOSTAT_ATTRIBUTES"," + "standard::type"); +#endif + local->flags = flags; + + return G_FILE_ENUMERATOR (local); +} + +#ifndef USE_GDIR +static int +sort_by_inode (const void *_a, const void *_b) +{ + const DirEntry *a, *b; + + a = _a; + b = _b; + return a->inode - b->inode; +} + +#ifdef HAVE_STRUCT_DIRENT_D_TYPE +static GFileType +file_type_from_dirent (char d_type) +{ + switch (d_type) + { + case DT_BLK: + case DT_CHR: + case DT_FIFO: + case DT_SOCK: + return G_FILE_TYPE_SPECIAL; + case DT_DIR: + return G_FILE_TYPE_DIRECTORY; + case DT_LNK: + return G_FILE_TYPE_SYMBOLIC_LINK; + case DT_REG: + return G_FILE_TYPE_REGULAR; + case DT_UNKNOWN: + default: + return G_FILE_TYPE_UNKNOWN; + } +} +#endif + +static const char * +next_file_helper (GLocalFileEnumerator *local, GFileType *file_type) +{ + struct dirent *entry; + const char *filename; + int i; + + if (local->at_end) + return NULL; + + if (local->entries == NULL || + (local->entries[local->entries_pos].name == NULL)) + { + if (local->entries == NULL) + local->entries = g_new (DirEntry, CHUNK_SIZE + 1); + else + { + /* Restart by clearing old names */ + for (i = 0; local->entries[i].name != NULL; i++) + g_free (local->entries[i].name); + } + + for (i = 0; i < CHUNK_SIZE; i++) + { + entry = readdir (local->dir); + while (entry + && (0 == strcmp (entry->d_name, ".") || + 0 == strcmp (entry->d_name, ".."))) + entry = readdir (local->dir); + + if (entry) + { + local->entries[i].name = g_strdup (entry->d_name); + local->entries[i].inode = entry->d_ino; +#if HAVE_STRUCT_DIRENT_D_TYPE + local->entries[i].type = file_type_from_dirent (entry->d_type); +#else + local->entries[i].type = G_FILE_TYPE_UNKNOWN; +#endif + } + else + break; + } + local->entries[i].name = NULL; + local->entries_pos = 0; + + qsort (local->entries, i, sizeof (DirEntry), sort_by_inode); + } + + filename = local->entries[local->entries_pos].name; + if (filename == NULL) + local->at_end = TRUE; + + *file_type = local->entries[local->entries_pos].type; + + local->entries_pos++; + + return filename; +} + +#endif + +static GFileInfo * +g_local_file_enumerator_next_file (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GLocalFileEnumerator *local = G_LOCAL_FILE_ENUMERATOR (enumerator); + const char *filename; + char *path; + GFileInfo *info; + GError *my_error; + GFileType file_type; + + if (!local->got_parent_info) + { + _g_local_file_info_get_parent_info (local->filename, local->matcher, &local->parent_info); + local->got_parent_info = TRUE; + } + + next_file: + +#ifdef USE_GDIR + filename = g_dir_read_name (local->dir); + file_type = G_FILE_TYPE_UNKNOWN; +#else + filename = next_file_helper (local, &file_type); +#endif + + if (filename == NULL) + return NULL; + + my_error = NULL; + path = g_build_filename (local->filename, filename, NULL); + if (file_type == G_FILE_TYPE_UNKNOWN || + (file_type == G_FILE_TYPE_SYMBOLIC_LINK && !(local->flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS))) + { + info = _g_local_file_info_get (filename, path, + local->matcher, + local->flags, + &local->parent_info, + &my_error); + } + else + { + info = _g_local_file_info_get (filename, path, + local->reduced_matcher, + local->flags, + &local->parent_info, + &my_error); + if (info) + { + _g_local_file_info_get_nostat (info, filename, path, local->matcher); + g_file_info_set_file_type (info, file_type); + if (file_type == G_FILE_TYPE_SYMBOLIC_LINK) + g_file_info_set_is_symlink (info, TRUE); + } + } + g_free (path); + + if (info == NULL) + { + /* Failed to get info */ + /* If the file does not exist there might have been a race where + * the file was removed between the readdir and the stat, so we + * ignore the file. */ + if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + g_error_free (my_error); + goto next_file; + } + else + g_propagate_error (error, my_error); + } + + return info; +} + +static gboolean +g_local_file_enumerator_close (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GLocalFileEnumerator *local = G_LOCAL_FILE_ENUMERATOR (enumerator); + + if (local->dir) + { +#ifdef USE_GDIR + g_dir_close (local->dir); +#else + closedir (local->dir); +#endif + local->dir = NULL; + } + + return TRUE; +} diff --git a/gio/glocalfileenumerator.h b/gio/glocalfileenumerator.h new file mode 100644 index 0000000..7277bf3 --- /dev/null +++ b/gio/glocalfileenumerator.h @@ -0,0 +1,55 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOCAL_FILE_ENUMERATOR_H__ +#define __G_LOCAL_FILE_ENUMERATOR_H__ + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_LOCAL_FILE_ENUMERATOR (_g_local_file_enumerator_get_type ()) +#define G_LOCAL_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_ENUMERATOR, GLocalFileEnumerator)) +#define G_LOCAL_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE_ENUMERATOR, GLocalFileEnumeratorClass)) +#define G_IS_LOCAL_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_ENUMERATOR)) +#define G_IS_LOCAL_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_ENUMERATOR)) +#define G_LOCAL_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE_ENUMERATOR, GLocalFileEnumeratorClass)) + +typedef struct _GLocalFileEnumerator GLocalFileEnumerator; +typedef struct _GLocalFileEnumeratorClass GLocalFileEnumeratorClass; +typedef struct _GLocalFileEnumeratorPrivate GLocalFileEnumeratorPrivate; + +struct _GLocalFileEnumeratorClass +{ + GFileEnumeratorClass parent_class; +}; + +GType _g_local_file_enumerator_get_type (void) G_GNUC_CONST; + +GFileEnumerator * _g_local_file_enumerator_new (GLocalFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* __G_FILE_LOCAL_FILE_ENUMERATOR_H__ */ diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c new file mode 100644 index 0000000..d3b327a --- /dev/null +++ b/gio/glocalfileinfo.c @@ -0,0 +1,2996 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#include +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#include +#endif +#ifdef HAVE_SELINUX +#include +#endif + +#ifdef HAVE_XATTR + +#if defined HAVE_SYS_XATTR_H + #include +#elif defined HAVE_ATTR_XATTR_H + #include +#else + #error "Neither nor is present but extended attribute support is enabled." +#endif /* defined HAVE_SYS_XATTR_H || HAVE_ATTR_XATTR_H */ + +#endif /* HAVE_XATTR */ + +#include +#include +#include +#include +#include + +#ifdef G_OS_UNIX +#include +#include "glib-unix.h" +#endif + +#include "glib-private.h" + +#include "thumbnail-verify.h" + +#ifdef G_OS_WIN32 +#include +#include +#ifndef W_OK +#define W_OK 2 +#endif +#ifndef R_OK +#define R_OK 4 +#endif +#ifndef X_OK +#define X_OK 0 /* not really */ +#endif +#ifndef S_ISREG +#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#endif +#ifndef S_IXUSR +#define S_IXUSR _S_IEXEC +#endif +#endif + +#include "glocalfileinfo.h" +#include "gioerror.h" +#include "gthemedicon.h" +#include "gcontenttypeprivate.h" +#include "glibintl.h" + + +struct ThumbMD5Context { + guint32 buf[4]; + guint32 bits[2]; + unsigned char in[64]; +}; + +#ifndef G_OS_WIN32 + +typedef struct { + char *user_name; + char *real_name; +} UidData; + +G_LOCK_DEFINE_STATIC (uid_cache); +static GHashTable *uid_cache = NULL; + +G_LOCK_DEFINE_STATIC (gid_cache); +static GHashTable *gid_cache = NULL; + +#endif /* !G_OS_WIN32 */ + +char * +_g_local_file_info_create_etag (GLocalFileStat *statbuf) +{ + glong sec, usec; + + g_return_val_if_fail (_g_stat_has_field (statbuf, G_LOCAL_FILE_STAT_FIELD_MTIME), NULL); + +#if defined (G_OS_WIN32) + sec = statbuf->st_mtim.tv_sec; + usec = statbuf->st_mtim.tv_nsec / 1000; +#else + sec = _g_stat_mtime (statbuf); +#if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC) + usec = statbuf->st_mtimensec / 1000; +#elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + usec = _g_stat_mtim_nsec (statbuf) / 1000; +#else + usec = 0; +#endif +#endif + + return g_strdup_printf ("%lu:%lu", sec, usec); +} + +static char * +_g_local_file_info_create_file_id (GLocalFileStat *statbuf) +{ + guint64 ino; +#ifdef G_OS_WIN32 + ino = statbuf->file_index; +#else + ino = _g_stat_ino (statbuf); +#endif + return g_strdup_printf ("l%" G_GUINT64_FORMAT ":%" G_GUINT64_FORMAT, + (guint64) _g_stat_dev (statbuf), + ino); +} + +static char * +_g_local_file_info_create_fs_id (GLocalFileStat *statbuf) +{ + return g_strdup_printf ("l%" G_GUINT64_FORMAT, + (guint64) _g_stat_dev (statbuf)); +} + +#if defined (S_ISLNK) || defined (G_OS_WIN32) + +static gchar * +read_link (const gchar *full_name) +{ +#if defined (HAVE_READLINK) + gchar *buffer; + gsize size; + + size = 256; + buffer = g_malloc (size); + + while (1) + { + gssize read_size; + + read_size = readlink (full_name, buffer, size); + if (read_size < 0) + { + g_free (buffer); + return NULL; + } + if ((gsize) read_size < size) + { + buffer[read_size] = 0; + return buffer; + } + size *= 2; + buffer = g_realloc (buffer, size); + } +#elif defined (G_OS_WIN32) + gchar *buffer; + int read_size; + + read_size = GLIB_PRIVATE_CALL (g_win32_readlink_utf8) (full_name, NULL, 0, &buffer, TRUE); + if (read_size < 0) + return NULL; + else if (read_size == 0) + return strdup (""); + else + return buffer; +#else + return NULL; +#endif +} + +#endif /* S_ISLNK || G_OS_WIN32 */ + +#ifdef HAVE_SELINUX +/* Get the SELinux security context */ +static void +get_selinux_context (const char *path, + GFileInfo *info, + GFileAttributeMatcher *attribute_matcher, + gboolean follow_symlinks) +{ + char *context; + + if (!_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_SELINUX_CONTEXT)) + return; + + if (is_selinux_enabled ()) + { + if (follow_symlinks) + { + if (lgetfilecon_raw (path, &context) < 0) + return; + } + else + { + if (getfilecon_raw (path, &context) < 0) + return; + } + + if (context) + { + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_SELINUX_CONTEXT, context); + freecon (context); + } + } +} +#endif + +#ifdef HAVE_XATTR + +/* Wrappers to hide away differences between (Linux) getxattr/lgetxattr and + * (Mac) getxattr(..., XATTR_NOFOLLOW) + */ +#ifdef HAVE_XATTR_NOFOLLOW +#define g_fgetxattr(fd,name,value,size) fgetxattr(fd,name,value,size,0,0) +#define g_flistxattr(fd,name,size) flistxattr(fd,name,size,0) +#define g_setxattr(path,name,value,size) setxattr(path,name,value,size,0,0) +#else +#define g_fgetxattr fgetxattr +#define g_flistxattr flistxattr +#define g_setxattr(path,name,value,size) setxattr(path,name,value,size,0) +#endif + +static gssize +g_getxattr (const char *path, const char *name, void *value, size_t size, + gboolean follow_symlinks) +{ +#ifdef HAVE_XATTR_NOFOLLOW + return getxattr (path, name, value, size, 0, follow_symlinks ? 0 : XATTR_NOFOLLOW); +#else + if (follow_symlinks) + return getxattr (path, name, value, size); + else + return lgetxattr (path, name, value, size); +#endif +} + +static gssize +g_listxattr(const char *path, char *namebuf, size_t size, + gboolean follow_symlinks) +{ +#ifdef HAVE_XATTR_NOFOLLOW + return listxattr (path, namebuf, size, follow_symlinks ? 0 : XATTR_NOFOLLOW); +#else + if (follow_symlinks) + return listxattr (path, namebuf, size); + else + return llistxattr (path, namebuf, size); +#endif +} + +static gboolean +valid_char (char c) +{ + return c >= 32 && c <= 126 && c != '\\'; +} + +static gboolean +name_is_valid (const char *str) +{ + while (*str) + { + if (!valid_char (*str++)) + return FALSE; + } + return TRUE; +} + +static char * +hex_escape_buffer (const char *str, + size_t len, + gboolean *free_return) +{ + size_t num_invalid, i; + char *escaped_str, *p; + unsigned char c; + static char *hex_digits = "0123456789abcdef"; + + num_invalid = 0; + for (i = 0; i < len; i++) + { + if (!valid_char (str[i])) + num_invalid++; + } + + if (num_invalid == 0) + { + *free_return = FALSE; + return (char *)str; + } + + escaped_str = g_malloc (len + num_invalid*3 + 1); + + p = escaped_str; + for (i = 0; i < len; i++) + { + if (valid_char (str[i])) + *p++ = str[i]; + else + { + c = str[i]; + *p++ = '\\'; + *p++ = 'x'; + *p++ = hex_digits[(c >> 4) & 0xf]; + *p++ = hex_digits[c & 0xf]; + } + } + *p = 0; + + *free_return = TRUE; + return escaped_str; +} + +static char * +hex_escape_string (const char *str, + gboolean *free_return) +{ + return hex_escape_buffer (str, strlen (str), free_return); +} + +static char * +hex_unescape_string (const char *str, + int *out_len, + gboolean *free_return) +{ + int i; + char *unescaped_str, *p; + unsigned char c; + int len; + + len = strlen (str); + + if (strchr (str, '\\') == NULL) + { + if (out_len) + *out_len = len; + *free_return = FALSE; + return (char *)str; + } + + unescaped_str = g_malloc (len + 1); + + p = unescaped_str; + for (i = 0; i < len; i++) + { + if (str[i] == '\\' && + str[i+1] == 'x' && + len - i >= 4) + { + c = + (g_ascii_xdigit_value (str[i+2]) << 4) | + g_ascii_xdigit_value (str[i+3]); + *p++ = c; + i += 3; + } + else + *p++ = str[i]; + } + if (out_len) + *out_len = p - unescaped_str; + *p++ = 0; + + *free_return = TRUE; + return unescaped_str; +} + +static void +escape_xattr (GFileInfo *info, + const char *gio_attr, /* gio attribute name */ + const char *value, /* Is zero terminated */ + size_t len /* not including zero termination */) +{ + char *escaped_val; + gboolean free_escaped_val; + + escaped_val = hex_escape_buffer (value, len, &free_escaped_val); + + g_file_info_set_attribute_string (info, gio_attr, escaped_val); + + if (free_escaped_val) + g_free (escaped_val); +} + +static void +get_one_xattr (const char *path, + GFileInfo *info, + const char *gio_attr, + const char *xattr, + gboolean follow_symlinks) +{ + char value[64]; + char *value_p; + gssize len; + int errsv; + + len = g_getxattr (path, xattr, value, sizeof (value)-1, follow_symlinks); + errsv = errno; + + value_p = NULL; + if (len >= 0) + value_p = value; + else if (len == -1 && errsv == ERANGE) + { + len = g_getxattr (path, xattr, NULL, 0, follow_symlinks); + + if (len < 0) + return; + + value_p = g_malloc (len+1); + + len = g_getxattr (path, xattr, value_p, len, follow_symlinks); + + if (len < 0) + { + g_free (value_p); + return; + } + } + else + return; + + /* Null terminate */ + value_p[len] = 0; + + escape_xattr (info, gio_attr, value_p, len); + + if (value_p != value) + g_free (value_p); +} + +#endif /* defined HAVE_XATTR */ + +static void +get_xattrs (const char *path, + gboolean user, + GFileInfo *info, + GFileAttributeMatcher *matcher, + gboolean follow_symlinks) +{ +#ifdef HAVE_XATTR + gboolean all; + gsize list_size; + gssize list_res_size; + size_t len; + char *list; + const char *attr, *attr2; + + if (user) + all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr"); + else + all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr-sys"); + + if (all) + { + int errsv; + + list_res_size = g_listxattr (path, NULL, 0, follow_symlinks); + + if (list_res_size == -1 || + list_res_size == 0) + return; + + list_size = list_res_size; + list = g_malloc (list_size); + + retry: + + list_res_size = g_listxattr (path, list, list_size, follow_symlinks); + errsv = errno; + + if (list_res_size == -1 && errsv == ERANGE) + { + list_size = list_size * 2; + list = g_realloc (list, list_size); + goto retry; + } + + if (list_res_size == -1) + { + g_free (list); + return; + } + + attr = list; + while (list_res_size > 0) + { + if ((user && g_str_has_prefix (attr, "user.")) || + (!user && !g_str_has_prefix (attr, "user."))) + { + char *escaped_attr, *gio_attr; + gboolean free_escaped_attr; + + if (user) + { + escaped_attr = hex_escape_string (attr + 5, &free_escaped_attr); + gio_attr = g_strconcat ("xattr::", escaped_attr, NULL); + } + else + { + escaped_attr = hex_escape_string (attr, &free_escaped_attr); + gio_attr = g_strconcat ("xattr-sys::", escaped_attr, NULL); + } + + if (free_escaped_attr) + g_free (escaped_attr); + + get_one_xattr (path, info, gio_attr, attr, follow_symlinks); + + g_free (gio_attr); + } + + len = strlen (attr) + 1; + attr += len; + list_res_size -= len; + } + + g_free (list); + } + else + { + while ((attr = g_file_attribute_matcher_enumerate_next (matcher)) != NULL) + { + char *unescaped_attribute, *a; + gboolean free_unescaped_attribute; + + attr2 = strchr (attr, ':'); + if (attr2) + { + attr2 += 2; /* Skip '::' */ + unescaped_attribute = hex_unescape_string (attr2, NULL, &free_unescaped_attribute); + if (user) + a = g_strconcat ("user.", unescaped_attribute, NULL); + else + a = unescaped_attribute; + + get_one_xattr (path, info, attr, a, follow_symlinks); + + if (user) + g_free (a); + + if (free_unescaped_attribute) + g_free (unescaped_attribute); + } + } + } +#endif /* defined HAVE_XATTR */ +} + +#ifdef HAVE_XATTR +static void +get_one_xattr_from_fd (int fd, + GFileInfo *info, + const char *gio_attr, + const char *xattr) +{ + char value[64]; + char *value_p; + gssize len; + int errsv; + + len = g_fgetxattr (fd, xattr, value, sizeof (value) - 1); + errsv = errno; + + value_p = NULL; + if (len >= 0) + value_p = value; + else if (len == -1 && errsv == ERANGE) + { + len = g_fgetxattr (fd, xattr, NULL, 0); + + if (len < 0) + return; + + value_p = g_malloc (len + 1); + + len = g_fgetxattr (fd, xattr, value_p, len); + + if (len < 0) + { + g_free (value_p); + return; + } + } + else + return; + + /* Null terminate */ + value_p[len] = 0; + + escape_xattr (info, gio_attr, value_p, len); + + if (value_p != value) + g_free (value_p); +} +#endif /* defined HAVE_XATTR */ + +static void +get_xattrs_from_fd (int fd, + gboolean user, + GFileInfo *info, + GFileAttributeMatcher *matcher) +{ +#ifdef HAVE_XATTR + gboolean all; + gsize list_size; + gssize list_res_size; + size_t len; + char *list; + const char *attr, *attr2; + + if (user) + all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr"); + else + all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr-sys"); + + if (all) + { + int errsv; + + list_res_size = g_flistxattr (fd, NULL, 0); + + if (list_res_size == -1 || + list_res_size == 0) + return; + + list_size = list_res_size; + list = g_malloc (list_size); + + retry: + + list_res_size = g_flistxattr (fd, list, list_size); + errsv = errno; + + if (list_res_size == -1 && errsv == ERANGE) + { + list_size = list_size * 2; + list = g_realloc (list, list_size); + goto retry; + } + + if (list_res_size == -1) + { + g_free (list); + return; + } + + attr = list; + while (list_res_size > 0) + { + if ((user && g_str_has_prefix (attr, "user.")) || + (!user && !g_str_has_prefix (attr, "user."))) + { + char *escaped_attr, *gio_attr; + gboolean free_escaped_attr; + + if (user) + { + escaped_attr = hex_escape_string (attr + 5, &free_escaped_attr); + gio_attr = g_strconcat ("xattr::", escaped_attr, NULL); + } + else + { + escaped_attr = hex_escape_string (attr, &free_escaped_attr); + gio_attr = g_strconcat ("xattr-sys::", escaped_attr, NULL); + } + + if (free_escaped_attr) + g_free (escaped_attr); + + get_one_xattr_from_fd (fd, info, gio_attr, attr); + g_free (gio_attr); + } + + len = strlen (attr) + 1; + attr += len; + list_res_size -= len; + } + + g_free (list); + } + else + { + while ((attr = g_file_attribute_matcher_enumerate_next (matcher)) != NULL) + { + char *unescaped_attribute, *a; + gboolean free_unescaped_attribute; + + attr2 = strchr (attr, ':'); + if (attr2) + { + attr2++; /* Skip ':' */ + unescaped_attribute = hex_unescape_string (attr2, NULL, &free_unescaped_attribute); + if (user) + a = g_strconcat ("user.", unescaped_attribute, NULL); + else + a = unescaped_attribute; + + get_one_xattr_from_fd (fd, info, attr, a); + + if (user) + g_free (a); + + if (free_unescaped_attribute) + g_free (unescaped_attribute); + } + } + } +#endif /* defined HAVE_XATTR */ +} + +#ifdef HAVE_XATTR +static gboolean +set_xattr (char *filename, + const char *escaped_attribute, + const GFileAttributeValue *attr_value, + GError **error) +{ + char *attribute, *value; + gboolean free_attribute, free_value; + int val_len, res, errsv; + gboolean is_user; + char *a; + + if (attr_value == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Attribute value must be non-NULL")); + return FALSE; + } + + if (attr_value->type != G_FILE_ATTRIBUTE_TYPE_STRING) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid attribute type (string expected)")); + return FALSE; + } + + if (!name_is_valid (escaped_attribute)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid extended attribute name")); + return FALSE; + } + + if (g_str_has_prefix (escaped_attribute, "xattr::")) + { + escaped_attribute += strlen ("xattr::"); + is_user = TRUE; + } + else + { + g_warn_if_fail (g_str_has_prefix (escaped_attribute, "xattr-sys::")); + escaped_attribute += strlen ("xattr-sys::"); + is_user = FALSE; + } + + attribute = hex_unescape_string (escaped_attribute, NULL, &free_attribute); + value = hex_unescape_string (attr_value->u.string, &val_len, &free_value); + + if (is_user) + a = g_strconcat ("user.", attribute, NULL); + else + a = attribute; + + res = g_setxattr (filename, a, value, val_len); + errsv = errno; + + if (is_user) + g_free (a); + + if (free_attribute) + g_free (attribute); + + if (free_value) + g_free (value); + + if (res == -1) + { + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error setting extended attribute “%sâ€: %s"), + escaped_attribute, g_strerror (errsv)); + return FALSE; + } + + return TRUE; +} + +#endif + + +void +_g_local_file_info_get_parent_info (const char *dir, + GFileAttributeMatcher *attribute_matcher, + GLocalParentFileInfo *parent_info) +{ + GStatBuf statbuf; + int res; + + parent_info->extra_data = NULL; + parent_info->free_extra_data = NULL; + parent_info->writable = FALSE; + parent_info->is_sticky = FALSE; + parent_info->has_trash_dir = FALSE; + parent_info->device = 0; + parent_info->inode = 0; + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_RENAME) || + _g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_DELETE) || + _g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH) || + _g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_UNIX_IS_MOUNTPOINT)) + { + /* FIXME: Windows: The underlying _waccess() call in the C + * library is mostly pointless as it only looks at the READONLY + * FAT-style attribute of the file, it doesn't check the ACL at + * all. + */ + parent_info->writable = (g_access (dir, W_OK) == 0); + + res = g_stat (dir, &statbuf); + + /* + * The sticky bit (S_ISVTX) on a directory means that a file in that directory can be + * renamed or deleted only by the owner of the file, by the owner of the directory, and + * by a privileged process. + */ + if (res == 0) + { +#ifdef S_ISVTX + parent_info->is_sticky = (statbuf.st_mode & S_ISVTX) != 0; +#else + parent_info->is_sticky = FALSE; +#endif + parent_info->owner = statbuf.st_uid; + parent_info->device = statbuf.st_dev; + parent_info->inode = statbuf.st_ino; + /* No need to find trash dir if it's not writable anyway */ + if (parent_info->writable && + _g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH)) + parent_info->has_trash_dir = _g_local_file_has_trash_dir (dir, statbuf.st_dev); + } + } +} + +void +_g_local_file_info_free_parent_info (GLocalParentFileInfo *parent_info) +{ + if (parent_info->extra_data && + parent_info->free_extra_data) + parent_info->free_extra_data (parent_info->extra_data); +} + +static void +get_access_rights (GFileAttributeMatcher *attribute_matcher, + GFileInfo *info, + const gchar *path, + GLocalFileStat *statbuf, + GLocalParentFileInfo *parent_info) +{ + /* FIXME: Windows: The underlyin _waccess() is mostly pointless */ + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_ACCESS_CAN_READ)) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_READ, + g_access (path, R_OK) == 0); + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_ACCESS_CAN_WRITE)) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_WRITE, + g_access (path, W_OK) == 0); + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_ACCESS_CAN_EXECUTE)) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_EXECUTE, + g_access (path, X_OK) == 0); + + + if (parent_info) + { + gboolean writable; + + writable = FALSE; + if (parent_info->writable) + { +#ifdef G_OS_WIN32 + writable = TRUE; +#else + if (parent_info->is_sticky) + { + uid_t uid = geteuid (); + + if (uid == _g_stat_uid (statbuf) || + uid == (uid_t) parent_info->owner || + uid == 0) + writable = TRUE; + } + else + writable = TRUE; +#endif + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_RENAME)) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_RENAME, + writable); + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_DELETE)) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_DELETE, + writable); + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH)) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH, + writable && parent_info->has_trash_dir); + } +} + +static void +set_info_from_stat (GFileInfo *info, + GLocalFileStat *statbuf, + GFileAttributeMatcher *attribute_matcher) +{ + GFileType file_type; + + file_type = G_FILE_TYPE_UNKNOWN; + + if (S_ISREG (_g_stat_mode (statbuf))) + file_type = G_FILE_TYPE_REGULAR; + else if (S_ISDIR (_g_stat_mode (statbuf))) + file_type = G_FILE_TYPE_DIRECTORY; +#ifndef G_OS_WIN32 + else if (S_ISCHR (_g_stat_mode (statbuf)) || + S_ISBLK (_g_stat_mode (statbuf)) || + S_ISFIFO (_g_stat_mode (statbuf)) +#ifdef S_ISSOCK + || S_ISSOCK (_g_stat_mode (statbuf)) +#endif + ) + file_type = G_FILE_TYPE_SPECIAL; +#endif +#ifdef S_ISLNK + else if (S_ISLNK (_g_stat_mode (statbuf))) + file_type = G_FILE_TYPE_SYMBOLIC_LINK; +#elif defined (G_OS_WIN32) + else if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK || + statbuf->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT) + file_type = G_FILE_TYPE_SYMBOLIC_LINK; +#endif + + g_file_info_set_file_type (info, file_type); + g_file_info_set_size (info, _g_stat_size (statbuf)); + + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_DEVICE, _g_stat_dev (statbuf)); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_NLINK, _g_stat_nlink (statbuf)); +#ifndef G_OS_WIN32 + /* Pointless setting these on Windows even if they exist in the struct */ + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_INODE, _g_stat_ino (statbuf)); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_UID, _g_stat_uid (statbuf)); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_GID, _g_stat_gid (statbuf)); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_RDEV, _g_stat_rdev (statbuf)); +#endif + /* Mostly pointless on Windows. + * Still, it allows for S_ISREG/S_ISDIR and IWRITE (read-only) checks. + */ + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_MODE, _g_stat_mode (statbuf)); +#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE) + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_BLOCK_SIZE, _g_stat_blksize (statbuf)); +#endif +#if defined (HAVE_STRUCT_STAT_ST_BLOCKS) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_BLOCKS, _g_stat_blocks (statbuf)); + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_ALLOCATED_SIZE, + _g_stat_blocks (statbuf) * G_GUINT64_CONSTANT (512)); +#elif defined (G_OS_WIN32) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_ALLOCATED_SIZE, + statbuf->allocated_size); + +#endif + +#if defined (G_OS_WIN32) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED, statbuf->st_mtim.tv_sec); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_USEC, statbuf->st_mtim.tv_nsec / 1000); + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS, statbuf->st_atim.tv_sec); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_USEC, statbuf->st_atim.tv_nsec / 1000); +#else + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED, _g_stat_mtime (statbuf)); +#if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC) + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_USEC, statbuf->st_mtimensec / 1000); +#elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_USEC, _g_stat_mtim_nsec (statbuf) / 1000); +#endif + + if (_g_stat_has_field (statbuf, G_LOCAL_FILE_STAT_FIELD_ATIME)) + { + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS, _g_stat_atime (statbuf)); +#if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC) + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_USEC, statbuf->st_atimensec / 1000); +#elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC) + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_USEC, _g_stat_atim_nsec (statbuf) / 1000); +#endif + } +#endif + +#ifndef G_OS_WIN32 + /* Microsoft uses st_ctime for file creation time, + * instead of file change time: + * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions#generic-text-routine-mappings + * Thank you, Microsoft! + */ + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED, _g_stat_ctime (statbuf)); +#if defined (HAVE_STRUCT_STAT_ST_CTIMENSEC) + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED_USEC, statbuf->st_ctimensec / 1000); +#elif defined (HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC) + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED_USEC, _g_stat_ctim_nsec (statbuf) / 1000); +#endif +#endif + +#if defined (HAVE_STATX) + if (_g_stat_has_field (statbuf, G_LOCAL_FILE_STAT_FIELD_BTIME)) + { + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->stx_btime.tv_sec); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED_USEC, statbuf->stx_btime.tv_nsec / 1000); + } +#elif defined (HAVE_STRUCT_STAT_ST_BIRTHTIME) && defined (HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtime); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED_USEC, statbuf->st_birthtimensec / 1000); +#elif defined (HAVE_STRUCT_STAT_ST_BIRTHTIM) && defined (HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtim.tv_sec); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED_USEC, statbuf->st_birthtim.tv_nsec / 1000); +#elif defined (HAVE_STRUCT_STAT_ST_BIRTHTIME) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtime); +#elif defined (HAVE_STRUCT_STAT_ST_BIRTHTIM) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtim); +#elif defined (G_OS_WIN32) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_ctim.tv_sec); + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED_USEC, statbuf->st_ctim.tv_nsec / 1000); +#endif + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_ETAG_VALUE)) + { + char *etag = _g_local_file_info_create_etag (statbuf); + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_ETAG_VALUE, etag); + g_free (etag); + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_ID_FILE)) + { + char *id = _g_local_file_info_create_file_id (statbuf); + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_ID_FILE, id); + g_free (id); + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_ID_FILESYSTEM)) + { + char *id = _g_local_file_info_create_fs_id (statbuf); + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_ID_FILESYSTEM, id); + g_free (id); + } +} + +#ifndef G_OS_WIN32 + +static char * +make_valid_utf8 (const char *name) +{ + GString *string; + const gchar *remainder, *invalid; + gsize remaining_bytes, valid_bytes; + + string = NULL; + remainder = name; + remaining_bytes = strlen (name); + + while (remaining_bytes != 0) + { + if (g_utf8_validate_len (remainder, remaining_bytes, &invalid)) + break; + valid_bytes = invalid - remainder; + + if (string == NULL) + string = g_string_sized_new (remaining_bytes); + + g_string_append_len (string, remainder, valid_bytes); + /* append U+FFFD REPLACEMENT CHARACTER */ + g_string_append (string, "\357\277\275"); + + remaining_bytes -= valid_bytes + 1; + remainder = invalid + 1; + } + + if (string == NULL) + return g_strdup (name); + + g_string_append (string, remainder); + + g_warn_if_fail (g_utf8_validate (string->str, -1, NULL)); + + return g_string_free (string, FALSE); +} + +static char * +convert_pwd_string_to_utf8 (char *pwd_str) +{ + char *utf8_string; + + if (!g_utf8_validate (pwd_str, -1, NULL)) + { + utf8_string = g_locale_to_utf8 (pwd_str, -1, NULL, NULL, NULL); + if (utf8_string == NULL) + utf8_string = make_valid_utf8 (pwd_str); + } + else + utf8_string = g_strdup (pwd_str); + + return utf8_string; +} + +static void +uid_data_free (UidData *data) +{ + g_free (data->user_name); + g_free (data->real_name); + g_free (data); +} + +/* called with lock held */ +static UidData * +lookup_uid_data (uid_t uid) +{ + UidData *data; + char buffer[4096]; + struct passwd pwbuf; + struct passwd *pwbufp; +#ifndef __BIONIC__ + char *gecos, *comma; +#endif + + if (uid_cache == NULL) + uid_cache = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)uid_data_free); + + data = g_hash_table_lookup (uid_cache, GINT_TO_POINTER (uid)); + + if (data) + return data; + + data = g_new0 (UidData, 1); + +#if defined(HAVE_GETPWUID_R) + getpwuid_r (uid, &pwbuf, buffer, sizeof(buffer), &pwbufp); +#else + pwbufp = getpwuid (uid); +#endif + + if (pwbufp != NULL) + { + if (pwbufp->pw_name != NULL && pwbufp->pw_name[0] != 0) + data->user_name = convert_pwd_string_to_utf8 (pwbufp->pw_name); + +#ifndef __BIONIC__ + gecos = pwbufp->pw_gecos; + + if (gecos) + { + comma = strchr (gecos, ','); + if (comma) + *comma = 0; + data->real_name = convert_pwd_string_to_utf8 (gecos); + } +#endif + } + + /* Default fallbacks */ + if (data->real_name == NULL) + { + if (data->user_name != NULL) + data->real_name = g_strdup (data->user_name); + else + data->real_name = g_strdup_printf ("user #%d", (int)uid); + } + + if (data->user_name == NULL) + data->user_name = g_strdup_printf ("%d", (int)uid); + + g_hash_table_replace (uid_cache, GINT_TO_POINTER (uid), data); + + return data; +} + +static char * +get_username_from_uid (uid_t uid) +{ + char *res; + UidData *data; + + G_LOCK (uid_cache); + data = lookup_uid_data (uid); + res = g_strdup (data->user_name); + G_UNLOCK (uid_cache); + + return res; +} + +static char * +get_realname_from_uid (uid_t uid) +{ + char *res; + UidData *data; + + G_LOCK (uid_cache); + data = lookup_uid_data (uid); + res = g_strdup (data->real_name); + G_UNLOCK (uid_cache); + + return res; +} + +/* called with lock held */ +static char * +lookup_gid_name (gid_t gid) +{ + char *name; +#if defined (HAVE_GETGRGID_R) + char buffer[4096]; + struct group gbuf; +#endif + struct group *gbufp; + + if (gid_cache == NULL) + gid_cache = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_free); + + name = g_hash_table_lookup (gid_cache, GINT_TO_POINTER (gid)); + + if (name) + return name; + +#if defined (HAVE_GETGRGID_R) + getgrgid_r (gid, &gbuf, buffer, sizeof(buffer), &gbufp); +#else + gbufp = getgrgid (gid); +#endif + + if (gbufp != NULL && + gbufp->gr_name != NULL && + gbufp->gr_name[0] != 0) + name = convert_pwd_string_to_utf8 (gbufp->gr_name); + else + name = g_strdup_printf("%d", (int)gid); + + g_hash_table_replace (gid_cache, GINT_TO_POINTER (gid), name); + + return name; +} + +static char * +get_groupname_from_gid (gid_t gid) +{ + char *res; + char *name; + + G_LOCK (gid_cache); + name = lookup_gid_name (gid); + res = g_strdup (name); + G_UNLOCK (gid_cache); + return res; +} + +#endif /* !G_OS_WIN32 */ + +static char * +get_content_type (const char *basename, + const char *path, + GLocalFileStat *statbuf, + gboolean is_symlink, + gboolean symlink_broken, + GFileQueryInfoFlags flags, + gboolean fast) +{ + if (is_symlink && + (symlink_broken || (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS))) + return g_content_type_from_mime_type ("inode/symlink"); + else if (statbuf != NULL && S_ISDIR(_g_stat_mode (statbuf))) + return g_content_type_from_mime_type ("inode/directory"); +#ifndef G_OS_WIN32 + else if (statbuf != NULL && S_ISCHR(_g_stat_mode (statbuf))) + return g_content_type_from_mime_type ("inode/chardevice"); + else if (statbuf != NULL && S_ISBLK(_g_stat_mode (statbuf))) + return g_content_type_from_mime_type ("inode/blockdevice"); + else if (statbuf != NULL && S_ISFIFO(_g_stat_mode (statbuf))) + return g_content_type_from_mime_type ("inode/fifo"); + else if (statbuf != NULL && S_ISREG(_g_stat_mode (statbuf)) && _g_stat_size (statbuf) == 0) + { + /* Don't sniff zero-length files in order to avoid reading files + * that appear normal but are not (eg: files in /proc and /sys) + * + * Note that we need to return text/plain here so that + * newly-created text files are opened by the text editor. + * See https://bugzilla.gnome.org/show_bug.cgi?id=755795 + */ + return g_content_type_from_mime_type ("text/plain"); + } +#endif +#ifdef S_ISSOCK + else if (statbuf != NULL && S_ISSOCK(_g_stat_mode (statbuf))) + return g_content_type_from_mime_type ("inode/socket"); +#endif + else + { + char *content_type; + gboolean result_uncertain; + + content_type = g_content_type_guess (basename, NULL, 0, &result_uncertain); + +#if !defined(G_OS_WIN32) && !defined(HAVE_COCOA) + if (!fast && result_uncertain && path != NULL) + { + guchar sniff_buffer[4096]; + gsize sniff_length; + int fd, errsv; + + sniff_length = _g_unix_content_type_get_sniff_len (); + if (sniff_length > 4096) + sniff_length = 4096; + +#ifdef O_NOATIME + fd = g_open (path, O_RDONLY | O_NOATIME, 0); + errsv = errno; + if (fd < 0 && errsv == EPERM) +#endif + fd = g_open (path, O_RDONLY, 0); + + if (fd != -1) + { + gssize res; + + res = read (fd, sniff_buffer, sniff_length); + (void) g_close (fd, NULL); + if (res >= 0) + { + g_free (content_type); + content_type = g_content_type_guess (basename, sniff_buffer, res, NULL); + } + } + } +#endif + + return content_type; + } + +} + +/* @stat_buf is the pre-calculated result of stat(path), or %NULL if that failed. */ +static void +get_thumbnail_attributes (const char *path, + GFileInfo *info, + const GLocalFileStat *stat_buf) +{ + GChecksum *checksum; + char *uri; + char *filename; + char *basename; + + uri = g_filename_to_uri (path, NULL, NULL); + + checksum = g_checksum_new (G_CHECKSUM_MD5); + g_checksum_update (checksum, (const guchar *) uri, strlen (uri)); + + basename = g_strconcat (g_checksum_get_string (checksum), ".png", NULL); + g_checksum_free (checksum); + + filename = g_build_filename (g_get_user_cache_dir (), + "thumbnails", "large", basename, + NULL); + + if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + { + _g_file_info_set_attribute_byte_string_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_PATH, filename); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_IS_VALID, + thumbnail_verify (filename, uri, stat_buf)); + } + else + { + g_free (filename); + filename = g_build_filename (g_get_user_cache_dir (), + "thumbnails", "normal", basename, + NULL); + + if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + { + _g_file_info_set_attribute_byte_string_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_PATH, filename); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_IS_VALID, + thumbnail_verify (filename, uri, stat_buf)); + } + else + { + g_free (filename); + filename = g_build_filename (g_get_user_cache_dir (), + "thumbnails", "fail", + "gnome-thumbnail-factory", + basename, + NULL); + + if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + { + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAILING_FAILED, TRUE); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_THUMBNAIL_IS_VALID, + thumbnail_verify (filename, uri, stat_buf)); + } + } + } + g_free (basename); + g_free (filename); + g_free (uri); +} + +#ifdef G_OS_WIN32 +static void +win32_get_file_user_info (const gchar *filename, + gchar **group_name, + gchar **user_name, + gchar **real_name) +{ + PSECURITY_DESCRIPTOR psd = NULL; + DWORD sd_size = 0; /* first call calculates the size required */ + + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + if ((GetFileSecurityW (wfilename, + GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, + NULL, + sd_size, + &sd_size) || (ERROR_INSUFFICIENT_BUFFER == GetLastError())) && + (psd = g_try_malloc (sd_size)) != NULL && + GetFileSecurityW (wfilename, + GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, + psd, + sd_size, + &sd_size)) + { + PSID psid = 0; + BOOL defaulted; + SID_NAME_USE name_use = 0; /* don't care? */ + wchar_t *name = NULL; + wchar_t *domain = NULL; + DWORD name_len = 0; + DWORD domain_len = 0; + /* get the user name */ + do { + if (!user_name) + break; + if (!GetSecurityDescriptorOwner (psd, &psid, &defaulted)) + break; + if (!LookupAccountSidW (NULL, /* local machine */ + psid, + name, &name_len, + domain, &domain_len, /* no domain info yet */ + &name_use) && (ERROR_INSUFFICIENT_BUFFER != GetLastError())) + break; + name = g_try_malloc (name_len * sizeof (wchar_t)); + domain = g_try_malloc (domain_len * sizeof (wchar_t)); + if (name && domain && + LookupAccountSidW (NULL, /* local machine */ + psid, + name, &name_len, + domain, &domain_len, /* no domain info yet */ + &name_use)) + { + *user_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL); + } + g_free (name); + g_free (domain); + } while (FALSE); + + /* get the group name */ + do { + if (!group_name) + break; + if (!GetSecurityDescriptorGroup (psd, &psid, &defaulted)) + break; + if (!LookupAccountSidW (NULL, /* local machine */ + psid, + name, &name_len, + domain, &domain_len, /* no domain info yet */ + &name_use) && (ERROR_INSUFFICIENT_BUFFER != GetLastError())) + break; + name = g_try_malloc (name_len * sizeof (wchar_t)); + domain = g_try_malloc (domain_len * sizeof (wchar_t)); + if (name && domain && + LookupAccountSidW (NULL, /* local machine */ + psid, + name, &name_len, + domain, &domain_len, /* no domain info yet */ + &name_use)) + { + *group_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL); + } + g_free (name); + g_free (domain); + } while (FALSE); + + /* TODO: get real name */ + + g_free (psd); + } + g_free (wfilename); +} +#endif /* G_OS_WIN32 */ + +#ifndef G_OS_WIN32 +/* support for '.hidden' files */ +G_LOCK_DEFINE_STATIC (hidden_cache); +static GHashTable *hidden_cache; +static GSource *hidden_cache_source = NULL; /* Under the hidden_cache lock */ +static guint hidden_cache_ttl_secs = 5; +static guint hidden_cache_ttl_jitter_secs = 2; + +typedef struct +{ + GHashTable *hidden_files; + gint64 timestamp_secs; +} HiddenCacheData; + +static gboolean +remove_from_hidden_cache (gpointer user_data) +{ + HiddenCacheData *data; + GHashTableIter iter; + gboolean retval; + gint64 timestamp_secs; + + G_LOCK (hidden_cache); + timestamp_secs = g_source_get_time (hidden_cache_source) / G_USEC_PER_SEC; + + g_hash_table_iter_init (&iter, hidden_cache); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &data)) + { + if (timestamp_secs > data->timestamp_secs + hidden_cache_ttl_secs) + g_hash_table_iter_remove (&iter); + } + + if (g_hash_table_size (hidden_cache) == 0) + { + g_clear_pointer (&hidden_cache_source, g_source_unref); + retval = G_SOURCE_REMOVE; + } + else + retval = G_SOURCE_CONTINUE; + + G_UNLOCK (hidden_cache); + + return retval; +} + +static GHashTable * +read_hidden_file (const gchar *dirname) +{ + gchar *contents = NULL; + gchar *filename; + + filename = g_build_path ("/", dirname, ".hidden", NULL); + (void) g_file_get_contents (filename, &contents, NULL, NULL); + g_free (filename); + + if (contents != NULL) + { + GHashTable *table; + gchar **lines; + gint i; + + table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + lines = g_strsplit (contents, "\n", 0); + g_free (contents); + + for (i = 0; lines[i]; i++) + /* hash table takes the individual strings... */ + g_hash_table_add (table, lines[i]); + + /* ... so we only free the container. */ + g_free (lines); + + return table; + } + else + return NULL; +} + +static void +free_hidden_file_data (gpointer user_data) +{ + HiddenCacheData *data = user_data; + + g_clear_pointer (&data->hidden_files, g_hash_table_unref); + g_free (data); +} + +static gboolean +file_is_hidden (const gchar *path, + const gchar *basename) +{ + HiddenCacheData *data; + gboolean result; + gchar *dirname; + gpointer table; + + dirname = g_path_get_dirname (path); + + G_LOCK (hidden_cache); + + if G_UNLIKELY (hidden_cache == NULL) + hidden_cache = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, free_hidden_file_data); + + if (!g_hash_table_lookup_extended (hidden_cache, dirname, + NULL, (gpointer *) &data)) + { + gchar *mydirname; + + data = g_new0 (HiddenCacheData, 1); + data->hidden_files = table = read_hidden_file (dirname); + data->timestamp_secs = g_get_monotonic_time () / G_USEC_PER_SEC; + + g_hash_table_insert (hidden_cache, + mydirname = g_strdup (dirname), + data); + + if (!hidden_cache_source) + { + hidden_cache_source = + g_timeout_source_new_seconds (hidden_cache_ttl_secs + + hidden_cache_ttl_jitter_secs); + g_source_set_priority (hidden_cache_source, G_PRIORITY_DEFAULT); + g_source_set_static_name (hidden_cache_source, + "[gio] remove_from_hidden_cache"); + g_source_set_callback (hidden_cache_source, + remove_from_hidden_cache, + NULL, NULL); + g_source_attach (hidden_cache_source, + GLIB_PRIVATE_CALL (g_get_worker_context) ()); + } + } + else + table = data->hidden_files; + + result = table != NULL && g_hash_table_contains (table, basename); + + G_UNLOCK (hidden_cache); + + g_free (dirname); + + return result; +} +#endif /* !G_OS_WIN32 */ + +void +_g_local_file_info_get_nostat (GFileInfo *info, + const char *basename, + const char *path, + GFileAttributeMatcher *attribute_matcher) +{ + g_file_info_set_name (info, basename); + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_DISPLAY_NAME)) + { + char *display_name = g_filename_display_basename (path); + + /* look for U+FFFD REPLACEMENT CHARACTER */ + if (strstr (display_name, "\357\277\275") != NULL) + { + char *p = display_name; + display_name = g_strconcat (display_name, _(" (invalid encoding)"), NULL); + g_free (p); + } + g_file_info_set_display_name (info, display_name); + g_free (display_name); + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_EDIT_NAME)) + { + char *edit_name = g_filename_display_basename (path); + g_file_info_set_edit_name (info, edit_name); + g_free (edit_name); + } + + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_COPY_NAME)) + { + char *copy_name = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL); + if (copy_name) + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_COPY_NAME, copy_name); + g_free (copy_name); + } +} + +static const char * +get_icon_name (const char *path, + gboolean use_symbolic, + gboolean *with_fallbacks_out) +{ + const char *name = NULL; + gboolean with_fallbacks = TRUE; + + if (g_strcmp0 (path, g_get_home_dir ()) == 0) + { + name = use_symbolic ? "user-home-symbolic" : "user-home"; + with_fallbacks = FALSE; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)) == 0) + { + name = use_symbolic ? "user-desktop-symbolic" : "user-desktop"; + with_fallbacks = FALSE; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)) == 0) + { + name = use_symbolic ? "folder-documents-symbolic" : "folder-documents"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD)) == 0) + { + name = use_symbolic ? "folder-download-symbolic" : "folder-download"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_MUSIC)) == 0) + { + name = use_symbolic ? "folder-music-symbolic" : "folder-music"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PICTURES)) == 0) + { + name = use_symbolic ? "folder-pictures-symbolic" : "folder-pictures"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PUBLIC_SHARE)) == 0) + { + name = use_symbolic ? "folder-publicshare-symbolic" : "folder-publicshare"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES)) == 0) + { + name = use_symbolic ? "folder-templates-symbolic" : "folder-templates"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS)) == 0) + { + name = use_symbolic ? "folder-videos-symbolic" : "folder-videos"; + } + else + { + name = NULL; + } + + if (with_fallbacks_out != NULL) + *with_fallbacks_out = with_fallbacks; + + return name; +} + +static GIcon * +get_icon (const char *path, + const char *content_type, + gboolean use_symbolic) +{ + GIcon *icon = NULL; + const char *icon_name; + gboolean with_fallbacks; + + icon_name = get_icon_name (path, use_symbolic, &with_fallbacks); + if (icon_name != NULL) + { + if (with_fallbacks) + icon = g_themed_icon_new_with_default_fallbacks (icon_name); + else + icon = g_themed_icon_new (icon_name); + } + else + { + if (use_symbolic) + icon = g_content_type_get_symbolic_icon (content_type); + else + icon = g_content_type_get_icon (content_type); + } + + return icon; +} + +GFileInfo * +_g_local_file_info_get (const char *basename, + const char *path, + GFileAttributeMatcher *attribute_matcher, + GFileQueryInfoFlags flags, + GLocalParentFileInfo *parent_info, + GError **error) +{ + GFileInfo *info; + GLocalFileStat statbuf; + GLocalFileStat statbuf2; + int res; + gboolean stat_ok; + gboolean is_symlink, symlink_broken; + char *symlink_target; + GVfs *vfs; + GVfsClass *class; + guint64 device; + + info = g_file_info_new (); + + /* Make sure we don't set any unwanted attributes */ + g_file_info_set_attribute_mask (info, attribute_matcher); + + _g_local_file_info_get_nostat (info, basename, path, attribute_matcher); + + if (attribute_matcher == NULL) + { + g_file_info_unset_attribute_mask (info); + return info; + } + + res = g_local_file_lstat (path, + G_LOCAL_FILE_STAT_FIELD_BASIC_STATS | G_LOCAL_FILE_STAT_FIELD_BTIME, + G_LOCAL_FILE_STAT_FIELD_ALL & (~G_LOCAL_FILE_STAT_FIELD_BTIME) & (~G_LOCAL_FILE_STAT_FIELD_ATIME), + &statbuf); + + if (res == -1) + { + int errsv = errno; + + /* Don't bail out if we get Permission denied (SELinux?) */ + if (errsv != EACCES) + { + char *display_name = g_filename_display_name (path); + g_object_unref (info); + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error when getting information for file “%sâ€: %s"), + display_name, g_strerror (errsv)); + g_free (display_name); + return NULL; + } + } + + /* Even if stat() fails, try to get as much as other attributes possible */ + stat_ok = res != -1; + + if (stat_ok) + device = _g_stat_dev (&statbuf); + else + device = 0; + +#ifdef S_ISLNK + is_symlink = stat_ok && S_ISLNK (_g_stat_mode (&statbuf)); +#elif defined (G_OS_WIN32) + /* glib already checked the FILE_ATTRIBUTE_REPARSE_POINT for us */ + is_symlink = stat_ok && + (statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK || + statbuf.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT); +#else + is_symlink = FALSE; +#endif + symlink_broken = FALSE; + + if (is_symlink) + { + g_file_info_set_is_symlink (info, TRUE); + + /* Unless NOFOLLOW was set we default to following symlinks */ + if (!(flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS)) + { + res = g_local_file_stat (path, + G_LOCAL_FILE_STAT_FIELD_BASIC_STATS | G_LOCAL_FILE_STAT_FIELD_BTIME, + G_LOCAL_FILE_STAT_FIELD_ALL & (~G_LOCAL_FILE_STAT_FIELD_BTIME) & (~G_LOCAL_FILE_STAT_FIELD_ATIME), + &statbuf2); + + /* Report broken links as symlinks */ + if (res != -1) + { + statbuf = statbuf2; + stat_ok = TRUE; + } + else + symlink_broken = TRUE; + } + } + + if (stat_ok) + set_info_from_stat (info, &statbuf, attribute_matcher); + +#ifdef G_OS_UNIX + if (stat_ok && _g_local_file_is_lost_found_dir (path, _g_stat_dev (&statbuf))) + g_file_info_set_is_hidden (info, TRUE); +#endif + +#ifndef G_OS_WIN32 + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_IS_HIDDEN)) + { + if (basename != NULL && + (basename[0] == '.' || + file_is_hidden (path, basename))) + g_file_info_set_is_hidden (info, TRUE); + } + + if (basename != NULL && basename[strlen (basename) -1] == '~' && + (stat_ok && S_ISREG (_g_stat_mode (&statbuf)))) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_IS_BACKUP, TRUE); +#else + if (statbuf.attributes & FILE_ATTRIBUTE_HIDDEN) + g_file_info_set_is_hidden (info, TRUE); + + if (statbuf.attributes & FILE_ATTRIBUTE_ARCHIVE) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_IS_ARCHIVE, TRUE); + + if (statbuf.attributes & FILE_ATTRIBUTE_SYSTEM) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_IS_SYSTEM, TRUE); + + if (statbuf.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_IS_MOUNTPOINT, TRUE); + + if (statbuf.reparse_tag != 0) + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_REPARSE_POINT_TAG, statbuf.reparse_tag); +#endif + + symlink_target = NULL; + if (is_symlink) + { +#if defined (S_ISLNK) || defined (G_OS_WIN32) + symlink_target = read_link (path); +#endif + if (symlink_target && + _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_SYMLINK_TARGET)) + g_file_info_set_symlink_target (info, symlink_target); + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE) || + _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_ICON) || + _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_SYMBOLIC_ICON)) + { + char *content_type = get_content_type (basename, path, stat_ok ? &statbuf : NULL, is_symlink, symlink_broken, flags, FALSE); + + if (content_type) + { + g_file_info_set_content_type (info, content_type); + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_ICON) + || _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_SYMBOLIC_ICON)) + { + GIcon *icon; + + /* non symbolic icon */ + icon = get_icon (path, content_type, FALSE); + if (icon != NULL) + { + g_file_info_set_icon (info, icon); + g_object_unref (icon); + } + + /* symbolic icon */ + icon = get_icon (path, content_type, TRUE); + if (icon != NULL) + { + g_file_info_set_symbolic_icon (info, icon); + g_object_unref (icon); + } + + } + + g_free (content_type); + } + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_FAST_CONTENT_TYPE)) + { + char *content_type = get_content_type (basename, path, stat_ok ? &statbuf : NULL, is_symlink, symlink_broken, flags, TRUE); + + if (content_type) + { + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_FAST_CONTENT_TYPE, content_type); + g_free (content_type); + } + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_OWNER_USER)) + { + char *name = NULL; + +#ifdef G_OS_WIN32 + win32_get_file_user_info (path, NULL, &name, NULL); +#else + if (stat_ok) + name = get_username_from_uid (_g_stat_uid (&statbuf)); +#endif + if (name) + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_OWNER_USER, name); + g_free (name); + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_OWNER_USER_REAL)) + { + char *name = NULL; +#ifdef G_OS_WIN32 + win32_get_file_user_info (path, NULL, NULL, &name); +#else + if (stat_ok) + name = get_realname_from_uid (_g_stat_uid (&statbuf)); +#endif + if (name) + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_OWNER_USER_REAL, name); + g_free (name); + } + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_OWNER_GROUP)) + { + char *name = NULL; +#ifdef G_OS_WIN32 + win32_get_file_user_info (path, &name, NULL, NULL); +#else + if (stat_ok) + name = get_groupname_from_gid (_g_stat_gid (&statbuf)); +#endif + if (name) + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_OWNER_GROUP, name); + g_free (name); + } + + if (stat_ok && parent_info && parent_info->device != 0 && + _g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_UNIX_IS_MOUNTPOINT) && + (_g_stat_dev (&statbuf) != parent_info->device || _g_stat_ino (&statbuf) == parent_info->inode)) + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_IS_MOUNTPOINT, TRUE); + + if (stat_ok) + get_access_rights (attribute_matcher, info, path, &statbuf, parent_info); + +#ifdef HAVE_SELINUX + get_selinux_context (path, info, attribute_matcher, (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) == 0); +#endif + get_xattrs (path, TRUE, info, attribute_matcher, (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) == 0); + get_xattrs (path, FALSE, info, attribute_matcher, (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) == 0); + + if (_g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_THUMBNAIL_PATH) || + _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_THUMBNAIL_IS_VALID) || + _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_THUMBNAILING_FAILED)) + { + if (stat_ok) + get_thumbnail_attributes (path, info, &statbuf); + else + get_thumbnail_attributes (path, info, NULL); + } + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_add_info) + { + class->local_file_add_info (vfs, + path, + device, + attribute_matcher, + info, + NULL, + &parent_info->extra_data, + &parent_info->free_extra_data); + } + + g_file_info_unset_attribute_mask (info); + + g_free (symlink_target); + + return info; +} + +GFileInfo * +_g_local_file_info_get_from_fd (int fd, + const char *attributes, + GError **error) +{ + GLocalFileStat stat_buf; + GFileAttributeMatcher *matcher; + GFileInfo *info; + + if (g_local_file_fstat (fd, + G_LOCAL_FILE_STAT_FIELD_BASIC_STATS | G_LOCAL_FILE_STAT_FIELD_BTIME, + G_LOCAL_FILE_STAT_FIELD_ALL & (~G_LOCAL_FILE_STAT_FIELD_BTIME) & (~G_LOCAL_FILE_STAT_FIELD_ATIME), + &stat_buf) == -1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error when getting information for file descriptor: %s"), + g_strerror (errsv)); + return NULL; + } + + info = g_file_info_new (); + + matcher = g_file_attribute_matcher_new (attributes); + + /* Make sure we don't set any unwanted attributes */ + g_file_info_set_attribute_mask (info, matcher); + + set_info_from_stat (info, &stat_buf, matcher); + +#ifdef HAVE_SELINUX + if (_g_file_attribute_matcher_matches_id (matcher, G_FILE_ATTRIBUTE_ID_SELINUX_CONTEXT) && + is_selinux_enabled ()) + { + char *context; + if (fgetfilecon_raw (fd, &context) >= 0) + { + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_SELINUX_CONTEXT, context); + freecon (context); + } + } +#endif + + get_xattrs_from_fd (fd, TRUE, info, matcher); + get_xattrs_from_fd (fd, FALSE, info, matcher); + + g_file_attribute_matcher_unref (matcher); + + g_file_info_unset_attribute_mask (info); + + return info; +} + +static gboolean +get_uint32 (const GFileAttributeValue *value, + guint32 *val_out, + GError **error) +{ + if (value->type != G_FILE_ATTRIBUTE_TYPE_UINT32) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid attribute type (uint32 expected)")); + return FALSE; + } + + *val_out = value->u.uint32; + + return TRUE; +} + +#if defined (HAVE_UTIMES) || defined (G_OS_WIN32) +static gboolean +get_uint64 (const GFileAttributeValue *value, + guint64 *val_out, + GError **error) +{ + if (value->type != G_FILE_ATTRIBUTE_TYPE_UINT64) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid attribute type (uint64 expected)")); + return FALSE; + } + + *val_out = value->u.uint64; + + return TRUE; +} +#endif + +#if defined(HAVE_SYMLINK) +static gboolean +get_byte_string (const GFileAttributeValue *value, + const char **val_out, + GError **error) +{ + if (value->type != G_FILE_ATTRIBUTE_TYPE_BYTE_STRING) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid attribute type (byte string expected)")); + return FALSE; + } + + *val_out = value->u.string; + + return TRUE; +} +#endif + +#ifdef HAVE_SELINUX +static gboolean +get_string (const GFileAttributeValue *value, + const char **val_out, + GError **error) +{ + if (value->type != G_FILE_ATTRIBUTE_TYPE_STRING) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid attribute type (byte string expected)")); + return FALSE; + } + + *val_out = value->u.string; + + return TRUE; +} +#endif + +static gboolean +set_unix_mode (char *filename, + GFileQueryInfoFlags flags, + const GFileAttributeValue *value, + GError **error) +{ + guint32 val = 0; + int res = 0; + + if (!get_uint32 (value, &val, error)) + return FALSE; + +#if defined (HAVE_SYMLINK) || defined (G_OS_WIN32) + if (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) { +#ifdef HAVE_LCHMOD + res = lchmod (filename, val); +#else + gboolean is_symlink; +#ifndef G_OS_WIN32 + struct stat statbuf; + /* Calling chmod on a symlink changes permissions on the symlink. + * We don't want to do this, so we need to check for a symlink */ + res = g_lstat (filename, &statbuf); + is_symlink = (res == 0 && S_ISLNK (statbuf.st_mode)); +#else + /* FIXME: implement lchmod for W32, should be doable */ + GWin32PrivateStat statbuf; + + res = GLIB_PRIVATE_CALL (g_win32_lstat_utf8) (filename, &statbuf); + is_symlink = (res == 0 && + (statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK || + statbuf.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT)); +#endif + if (is_symlink) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Cannot set permissions on symlinks")); + return FALSE; + } + else if (res == 0) + res = g_chmod (filename, val); +#endif + } else +#endif + res = g_chmod (filename, val); + + if (res == -1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error setting permissions: %s"), + g_strerror (errsv)); + return FALSE; + } + return TRUE; +} + +#ifdef G_OS_UNIX +static gboolean +set_unix_uid_gid (char *filename, + const GFileAttributeValue *uid_value, + const GFileAttributeValue *gid_value, + GFileQueryInfoFlags flags, + GError **error) +{ + int res; + guint32 val = 0; + uid_t uid; + gid_t gid; + + if (uid_value) + { + if (!get_uint32 (uid_value, &val, error)) + return FALSE; + uid = val; + } + else + uid = -1; + + if (gid_value) + { + if (!get_uint32 (gid_value, &val, error)) + return FALSE; + gid = val; + } + else + gid = -1; + +#ifdef HAVE_LCHOWN + if (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) + res = lchown (filename, uid, gid); + else +#endif + res = chown (filename, uid, gid); + + if (res == -1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error setting owner: %s"), + g_strerror (errsv)); + return FALSE; + } + return TRUE; +} +#endif + +#ifdef HAVE_SYMLINK +static gboolean +set_symlink (char *filename, + const GFileAttributeValue *value, + GError **error) +{ + const char *val; + struct stat statbuf; + + if (!get_byte_string (value, &val, error)) + return FALSE; + + if (val == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("symlink must be non-NULL")); + return FALSE; + } + + if (g_lstat (filename, &statbuf)) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error setting symlink: %s"), + g_strerror (errsv)); + return FALSE; + } + + if (!S_ISLNK (statbuf.st_mode)) + { + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NOT_SYMBOLIC_LINK, + _("Error setting symlink: file is not a symlink")); + return FALSE; + } + + if (g_unlink (filename)) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error setting symlink: %s"), + g_strerror (errsv)); + return FALSE; + } + + if (symlink (filename, val) != 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error setting symlink: %s"), + g_strerror (errsv)); + return FALSE; + } + + return TRUE; +} +#endif + +#if defined (G_OS_WIN32) +/* From + * https://support.microsoft.com/en-ca/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime + * FT = UT * 10000000 + 116444736000000000. + * Converts unix epoch time (a signed 64-bit integer) to FILETIME. + * Can optionally use a more precise timestamp that has + * a fraction of a second expressed in nanoseconds. + * UT must be between January 1st of year 1601 and December 31st of year 30827. + * nsec must be non-negative and < 1000000000. + * Returns TRUE if conversion succeeded, FALSE otherwise. + * + * The function that does the reverse can be found in + * glib/gstdio.c. + */ +static gboolean +_g_win32_unix_time_to_filetime (gint64 ut, + gint32 nsec, + FILETIME *ft, + GError **error) +{ + gint64 result; + /* 1 unit of FILETIME is 100ns */ + const gint64 hundreds_of_nsec_per_sec = 10000000; + /* The difference between January 1, 1601 UTC (FILETIME epoch) and UNIX epoch + * in hundreds of nanoseconds. + */ + const gint64 filetime_unix_epoch_offset = 116444736000000000; + /* This is the maximum timestamp that SYSTEMTIME can + * represent (last millisecond of the year 30827). + * Since FILETIME and SYSTEMTIME are both used on Windows, + * we use this as a limit (FILETIME can support slightly + * larger interval, up to year 30828). + */ + const gint64 max_systemtime = 0x7fff35f4f06c58f0; + + g_return_val_if_fail (ft != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (nsec < 0) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("Extra nanoseconds %d for UNIX timestamp %lld are negative"), + nsec, ut); + return FALSE; + } + + if (nsec >= hundreds_of_nsec_per_sec * 100) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("Extra nanoseconds %d for UNIX timestamp %lld reach 1 second"), + nsec, ut); + return FALSE; + } + + if (ut >= (G_MAXINT64 / hundreds_of_nsec_per_sec) || + (ut * hundreds_of_nsec_per_sec) >= (G_MAXINT64 - filetime_unix_epoch_offset)) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("UNIX timestamp %lld does not fit into 64 bits"), + ut); + return FALSE; + } + + result = ut * hundreds_of_nsec_per_sec + filetime_unix_epoch_offset + nsec / 100; + + if (result >= max_systemtime || result < 0) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("UNIX timestamp %lld is outside of the range supported by Windows"), + ut); + return FALSE; + } + + ft->dwLowDateTime = (DWORD) (result); + ft->dwHighDateTime = (DWORD) (result >> 32); + + return TRUE; +} + +static gboolean +set_mtime_atime (const char *filename, + const GFileAttributeValue *mtime_value, + const GFileAttributeValue *mtime_usec_value, + const GFileAttributeValue *atime_value, + const GFileAttributeValue *atime_usec_value, + GError **error) +{ + BOOL res; + guint64 val = 0; + guint32 val_usec = 0; + guint32 val_nsec = 0; + gunichar2 *filename_utf16; + SECURITY_ATTRIBUTES sec = { sizeof (SECURITY_ATTRIBUTES), NULL, FALSE }; + HANDLE file_handle; + FILETIME mtime; + FILETIME atime; + FILETIME *p_mtime = NULL; + FILETIME *p_atime = NULL; + DWORD gle; + + /* ATIME */ + if (atime_value) + { + if (!get_uint64 (atime_value, &val, error)) + return FALSE; + val_usec = 0; + if (atime_usec_value && + !get_uint32 (atime_usec_value, &val_usec, error)) + return FALSE; + + /* Convert to nanoseconds. Clamp the usec value if it’s going to overflow, + * as %G_MAXINT32 will trigger a ‘too big’ error in + * _g_win32_unix_time_to_filetime() anyway. */ + val_nsec = (val_usec > G_MAXINT32 / 1000) ? G_MAXINT32 : (val_usec * 1000); + + if (!_g_win32_unix_time_to_filetime (val, val_nsec, &atime, error)) + return FALSE; + p_atime = &atime; + } + + /* MTIME */ + if (mtime_value) + { + if (!get_uint64 (mtime_value, &val, error)) + return FALSE; + val_usec = 0; + if (mtime_usec_value && + !get_uint32 (mtime_usec_value, &val_usec, error)) + return FALSE; + + /* Convert to nanoseconds. Clamp the usec value if it’s going to overflow, + * as %G_MAXINT32 will trigger a ‘too big’ error in + * _g_win32_unix_time_to_filetime() anyway. */ + val_nsec = (val_usec > G_MAXINT32 / 1000) ? G_MAXINT32 : (val_usec * 1000); + + if (!_g_win32_unix_time_to_filetime (val, val_nsec, &mtime, error)) + return FALSE; + p_mtime = &mtime; + } + + filename_utf16 = g_utf8_to_utf16 (filename, -1, NULL, NULL, error); + + if (filename_utf16 == NULL) + { + g_prefix_error (error, + _("File name “%s†cannot be converted to UTF-16"), + filename); + return FALSE; + } + + file_handle = CreateFileW (filename_utf16, + FILE_WRITE_ATTRIBUTES, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + &sec, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + gle = GetLastError (); + g_clear_pointer (&filename_utf16, g_free); + + if (file_handle == INVALID_HANDLE_VALUE) + { + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (gle), + _("File “%s†cannot be opened: Windows Error %lu"), + filename, gle); + + return FALSE; + } + + res = SetFileTime (file_handle, NULL, p_atime, p_mtime); + gle = GetLastError (); + CloseHandle (file_handle); + + if (!res) + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (gle), + _("Error setting modification or access time for file “%sâ€: %lu"), + filename, gle); + + return res; +} +#elif defined (HAVE_UTIMES) +static int +lazy_stat (char *filename, + struct stat *statbuf, + gboolean *called_stat) +{ + int res; + + if (*called_stat) + return 0; + + res = g_stat (filename, statbuf); + + if (res == 0) + *called_stat = TRUE; + + return res; +} + + +static gboolean +set_mtime_atime (char *filename, + const GFileAttributeValue *mtime_value, + const GFileAttributeValue *mtime_usec_value, + const GFileAttributeValue *atime_value, + const GFileAttributeValue *atime_usec_value, + GError **error) +{ + int res; + guint64 val = 0; + guint32 val_usec = 0; + struct stat statbuf; + gboolean got_stat = FALSE; + struct timeval times[2] = { {0, 0}, {0, 0} }; + + /* ATIME */ + if (atime_value) + { + if (!get_uint64 (atime_value, &val, error)) + return FALSE; + times[0].tv_sec = val; + } + else + { + if (lazy_stat (filename, &statbuf, &got_stat) == 0) + { + times[0].tv_sec = statbuf.st_atime; +#if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC) + times[0].tv_usec = statbuf.st_atimensec / 1000; +#elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC) + times[0].tv_usec = statbuf.st_atim.tv_nsec / 1000; +#endif + } + } + + if (atime_usec_value) + { + if (!get_uint32 (atime_usec_value, &val_usec, error)) + return FALSE; + times[0].tv_usec = val_usec; + } + + /* MTIME */ + if (mtime_value) + { + if (!get_uint64 (mtime_value, &val, error)) + return FALSE; + times[1].tv_sec = val; + } + else + { + if (lazy_stat (filename, &statbuf, &got_stat) == 0) + { + times[1].tv_sec = statbuf.st_mtime; +#if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC) + times[1].tv_usec = statbuf.st_mtimensec / 1000; +#elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + times[1].tv_usec = statbuf.st_mtim.tv_nsec / 1000; +#endif + } + } + + if (mtime_usec_value) + { + if (!get_uint32 (mtime_usec_value, &val_usec, error)) + return FALSE; + times[1].tv_usec = val_usec; + } + + res = utimes (filename, times); + if (res == -1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error setting modification or access time: %s"), + g_strerror (errsv)); + return FALSE; + } + return TRUE; +} +#endif + + +#ifdef HAVE_SELINUX +static gboolean +set_selinux_context (char *filename, + const GFileAttributeValue *value, + GError **error) +{ + const char *val; + + if (!get_string (value, &val, error)) + return FALSE; + + if (val == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("SELinux context must be non-NULL")); + return FALSE; + } + + if (!is_selinux_enabled ()) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("SELinux is not enabled on this system")); + return FALSE; + } + + if (setfilecon_raw (filename, val) < 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error setting SELinux context: %s"), + g_strerror (errsv)); + return FALSE; + } + + return TRUE; +} +#endif + + +gboolean +_g_local_file_info_set_attribute (char *filename, + const char *attribute, + GFileAttributeType type, + gpointer value_p, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileAttributeValue value = { 0 }; + GVfsClass *class; + GVfs *vfs; + + _g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE); + + if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0) + return set_unix_mode (filename, flags, &value, error); + +#ifdef G_OS_UNIX + else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0) + return set_unix_uid_gid (filename, &value, NULL, flags, error); + else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_GID) == 0) + return set_unix_uid_gid (filename, NULL, &value, flags, error); +#endif + +#ifdef HAVE_SYMLINK + else if (strcmp (attribute, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET) == 0) + return set_symlink (filename, &value, error); +#endif + +#if defined (HAVE_UTIMES) || defined (G_OS_WIN32) + else if (strcmp (attribute, G_FILE_ATTRIBUTE_TIME_MODIFIED) == 0) + return set_mtime_atime (filename, &value, NULL, NULL, NULL, error); + else if (strcmp (attribute, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC) == 0) + return set_mtime_atime (filename, NULL, &value, NULL, NULL, error); + else if (strcmp (attribute, G_FILE_ATTRIBUTE_TIME_ACCESS) == 0) + return set_mtime_atime (filename, NULL, NULL, &value, NULL, error); + else if (strcmp (attribute, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC) == 0) + return set_mtime_atime (filename, NULL, NULL, NULL, &value, error); +#endif + +#ifdef HAVE_XATTR + else if (g_str_has_prefix (attribute, "xattr::")) + return set_xattr (filename, attribute, &value, error); + else if (g_str_has_prefix (attribute, "xattr-sys::")) + return set_xattr (filename, attribute, &value, error); +#endif + +#ifdef HAVE_SELINUX + else if (strcmp (attribute, G_FILE_ATTRIBUTE_SELINUX_CONTEXT) == 0) + return set_selinux_context (filename, &value, error); +#endif + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_set_attributes) + { + GFileInfo *info; + + info = g_file_info_new (); + g_file_info_set_attribute (info, + attribute, + type, + value_p); + if (!class->local_file_set_attributes (vfs, filename, + info, + flags, cancellable, + error)) + { + g_object_unref (info); + return FALSE; + } + + if (g_file_info_get_attribute_status (info, attribute) == G_FILE_ATTRIBUTE_STATUS_SET) + { + g_object_unref (info); + return TRUE; + } + + g_object_unref (info); + } + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Setting attribute %s not supported"), attribute); + return FALSE; +} + +gboolean +_g_local_file_info_set_attributes (char *filename, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GFileAttributeValue *value; +#ifdef G_OS_UNIX + GFileAttributeValue *uid, *gid; +#endif +#if defined (HAVE_UTIMES) || defined (G_OS_WIN32) + GFileAttributeValue *mtime, *mtime_usec, *atime, *atime_usec; +#endif +#if defined (G_OS_UNIX) || defined (G_OS_WIN32) + GFileAttributeStatus status; +#endif + gboolean res; + GVfsClass *class; + GVfs *vfs; + + /* Handles setting multiple specified data in a single set, and takes care + of ordering restrictions when setting attributes */ + + res = TRUE; + + /* Set symlink first, since this recreates the file */ +#ifdef HAVE_SYMLINK + value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET); + if (value) + { + if (!set_symlink (filename, value, error)) + { + value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING; + res = FALSE; + /* Don't set error multiple times */ + error = NULL; + } + else + value->status = G_FILE_ATTRIBUTE_STATUS_SET; + + } +#endif + +#ifdef G_OS_UNIX + /* Group uid and gid setting into one call + * Change ownership before permissions, since ownership changes can + change permissions (e.g. setuid) + */ + uid = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_UID); + gid = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_GID); + + if (uid || gid) + { + if (!set_unix_uid_gid (filename, uid, gid, flags, error)) + { + status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING; + res = FALSE; + /* Don't set error multiple times */ + error = NULL; + } + else + status = G_FILE_ATTRIBUTE_STATUS_SET; + if (uid) + uid->status = status; + if (gid) + gid->status = status; + } +#endif + + value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_MODE); + if (value) + { + if (!set_unix_mode (filename, flags, value, error)) + { + value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING; + res = FALSE; + /* Don't set error multiple times */ + error = NULL; + } + else + value->status = G_FILE_ATTRIBUTE_STATUS_SET; + + } + +#if defined (HAVE_UTIMES) || defined (G_OS_WIN32) + /* Group all time settings into one call + * Change times as the last thing to avoid it changing due to metadata changes + */ + + mtime = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_TIME_MODIFIED); + mtime_usec = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC); + atime = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_TIME_ACCESS); + atime_usec = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC); + + if (mtime || mtime_usec || atime || atime_usec) + { + if (!set_mtime_atime (filename, mtime, mtime_usec, atime, atime_usec, error)) + { + status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING; + res = FALSE; + /* Don't set error multiple times */ + error = NULL; + } + else + status = G_FILE_ATTRIBUTE_STATUS_SET; + + if (mtime) + mtime->status = status; + if (mtime_usec) + mtime_usec->status = status; + if (atime) + atime->status = status; + if (atime_usec) + atime_usec->status = status; + } +#endif + + /* xattrs are handled by default callback */ + + + /* SELinux context */ +#ifdef HAVE_SELINUX + if (is_selinux_enabled ()) { + value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_SELINUX_CONTEXT); + if (value) + { + if (!set_selinux_context (filename, value, error)) + { + value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING; + res = FALSE; + /* Don't set error multiple times */ + error = NULL; + } + else + value->status = G_FILE_ATTRIBUTE_STATUS_SET; + } + } +#endif + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_set_attributes) + { + if (!class->local_file_set_attributes (vfs, filename, + info, + flags, cancellable, + error)) + { + res = FALSE; + /* Don't set error multiple times */ + error = NULL; + } + } + + return res; +} diff --git a/gio/glocalfileinfo.h b/gio/glocalfileinfo.h new file mode 100644 index 0000000..f738045 --- /dev/null +++ b/gio/glocalfileinfo.h @@ -0,0 +1,382 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOCAL_FILE_INFO_H__ +#define __G_LOCAL_FILE_INFO_H__ + +/* Needed for statx() */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_STATX +#include +#endif + +G_BEGIN_DECLS + +typedef struct +{ + gboolean writable; + gboolean is_sticky; + gboolean has_trash_dir; + /* owner should be uid_t but it breaks compliance with MS-Windows */ + int owner; + dev_t device; + ino_t inode; + gpointer extra_data; + GDestroyNotify free_extra_data; +} GLocalParentFileInfo; + +#ifdef HAVE_STATX +#define GLocalFileStat struct statx + +typedef enum +{ + G_LOCAL_FILE_STAT_FIELD_TYPE = STATX_TYPE, + G_LOCAL_FILE_STAT_FIELD_MODE = STATX_MODE, + G_LOCAL_FILE_STAT_FIELD_NLINK = STATX_NLINK, + G_LOCAL_FILE_STAT_FIELD_UID = STATX_UID, + G_LOCAL_FILE_STAT_FIELD_GID = STATX_GID, + G_LOCAL_FILE_STAT_FIELD_ATIME = STATX_ATIME, + G_LOCAL_FILE_STAT_FIELD_MTIME = STATX_MTIME, + G_LOCAL_FILE_STAT_FIELD_CTIME = STATX_CTIME, + G_LOCAL_FILE_STAT_FIELD_INO = STATX_INO, + G_LOCAL_FILE_STAT_FIELD_SIZE = STATX_SIZE, + G_LOCAL_FILE_STAT_FIELD_BLOCKS = STATX_BLOCKS, + G_LOCAL_FILE_STAT_FIELD_BTIME = STATX_BTIME, +} GLocalFileStatField; + +#define G_LOCAL_FILE_STAT_FIELD_BASIC_STATS STATX_BASIC_STATS +#define G_LOCAL_FILE_STAT_FIELD_ALL STATX_ALL + +static inline int +g_local_file_statx (int dirfd, + const char *pathname, + int flags, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + int retval; + + /* Allow the caller to set mask_required==G_LOCAL_FILE_STAT_FIELD_ALL as a + * shortcut for saying it’s equal to @mask. */ + mask_required &= mask; + + retval = statx (dirfd, pathname, flags, mask, stat_buf); + if (retval == 0 && (stat_buf->stx_mask & mask_required) != mask_required) + { + /* Not all required fields could be returned. */ + errno = ERANGE; + return -1; + } + + return retval; +} + +static inline int +g_local_file_fstat (int fd, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + return g_local_file_statx (fd, "", AT_EMPTY_PATH, mask, mask_required, stat_buf); +} + +static inline int +g_local_file_fstatat (int fd, + const char *path, + int flags, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + return g_local_file_statx (fd, path, flags, mask, mask_required, stat_buf); +} + +static inline int +g_local_file_lstat (const char *path, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + return g_local_file_statx (AT_FDCWD, path, + AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT, + mask, mask_required, stat_buf); +} + +static inline int +g_local_file_stat (const char *path, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + return g_local_file_statx (AT_FDCWD, path, + AT_NO_AUTOMOUNT | AT_STATX_SYNC_AS_STAT, + mask, mask_required, stat_buf); +} + +inline static gboolean _g_stat_has_field (const GLocalFileStat *buf, GLocalFileStatField field) { return buf->stx_mask & field; } + +inline static guint16 _g_stat_mode (const GLocalFileStat *buf) { return buf->stx_mode; } +inline static guint32 _g_stat_nlink (const GLocalFileStat *buf) { return buf->stx_nlink; } +inline static dev_t _g_stat_dev (const GLocalFileStat *buf) { return makedev (buf->stx_dev_major, buf->stx_dev_minor); } +inline static guint64 _g_stat_ino (const GLocalFileStat *buf) { return buf->stx_ino; } +inline static guint64 _g_stat_size (const GLocalFileStat *buf) { return buf->stx_size; } + +inline static guint32 _g_stat_uid (const GLocalFileStat *buf) { return buf->stx_uid; } +inline static guint32 _g_stat_gid (const GLocalFileStat *buf) { return buf->stx_gid; } +inline static dev_t _g_stat_rdev (const GLocalFileStat *buf) { return makedev (buf->stx_rdev_major, buf->stx_rdev_minor); } +inline static guint32 _g_stat_blksize (const GLocalFileStat *buf) { return buf->stx_blksize; } + +inline static guint64 _g_stat_blocks (const GLocalFileStat *buf) { return buf->stx_blocks; } + +inline static gint64 _g_stat_atime (const GLocalFileStat *buf) { return buf->stx_atime.tv_sec; } +inline static gint64 _g_stat_ctime (const GLocalFileStat *buf) { return buf->stx_ctime.tv_sec; } +inline static gint64 _g_stat_mtime (const GLocalFileStat *buf) { return buf->stx_mtime.tv_sec; } +inline static guint32 _g_stat_atim_nsec (const GLocalFileStat *buf) { return buf->stx_atime.tv_nsec; } +inline static guint32 _g_stat_ctim_nsec (const GLocalFileStat *buf) { return buf->stx_ctime.tv_nsec; } +inline static guint32 _g_stat_mtim_nsec (const GLocalFileStat *buf) { return buf->stx_mtime.tv_nsec; } + +#else /* if !HAVE_STATX */ + +#ifdef G_OS_WIN32 +/* We want 64-bit file size, file ID and symlink support */ +#define GLocalFileStat GWin32PrivateStat +#else +#define GLocalFileStat struct stat +#endif + +/* If the system doesn’t have statx() support, emulate it using traditional + * stat(). It supports fields %G_LOCAL_FILE_STAT_FIELD_BASIC_STATS only, and + * always returns all of them. */ +typedef enum +{ + G_LOCAL_FILE_STAT_FIELD_TYPE = (1 << 0), + G_LOCAL_FILE_STAT_FIELD_MODE = (1 << 1), + G_LOCAL_FILE_STAT_FIELD_NLINK = (1 << 2), + G_LOCAL_FILE_STAT_FIELD_UID = (1 << 3), + G_LOCAL_FILE_STAT_FIELD_GID = (1 << 4), + G_LOCAL_FILE_STAT_FIELD_ATIME = (1 << 5), + G_LOCAL_FILE_STAT_FIELD_MTIME = (1 << 6), + G_LOCAL_FILE_STAT_FIELD_CTIME = (1 << 7), + G_LOCAL_FILE_STAT_FIELD_INO = (1 << 8), + G_LOCAL_FILE_STAT_FIELD_SIZE = (1 << 9), + G_LOCAL_FILE_STAT_FIELD_BLOCKS = (1 << 10), + G_LOCAL_FILE_STAT_FIELD_BTIME = (1 << 11), +} GLocalFileStatField; + +#define G_LOCAL_FILE_STAT_FIELD_BASIC_STATS \ + (G_LOCAL_FILE_STAT_FIELD_TYPE | G_LOCAL_FILE_STAT_FIELD_MODE | \ + G_LOCAL_FILE_STAT_FIELD_NLINK | G_LOCAL_FILE_STAT_FIELD_UID | \ + G_LOCAL_FILE_STAT_FIELD_GID | G_LOCAL_FILE_STAT_FIELD_ATIME | \ + G_LOCAL_FILE_STAT_FIELD_MTIME | G_LOCAL_FILE_STAT_FIELD_CTIME | \ + G_LOCAL_FILE_STAT_FIELD_INO | G_LOCAL_FILE_STAT_FIELD_SIZE | \ + G_LOCAL_FILE_STAT_FIELD_BLOCKS) +#define G_LOCAL_FILE_STAT_FIELD_ALL (G_LOCAL_FILE_STAT_FIELD_BASIC_STATS | G_LOCAL_FILE_STAT_FIELD_BTIME) + +static inline int +g_local_file_fstat (int fd, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + if ((G_LOCAL_FILE_STAT_FIELD_BASIC_STATS & (mask_required & mask)) != (mask_required & mask)) + { + /* Only G_LOCAL_FILE_STAT_FIELD_BASIC_STATS are supported. */ + errno = ERANGE; + return -1; + } + +#ifdef G_OS_WIN32 + return GLIB_PRIVATE_CALL (g_win32_fstat) (fd, stat_buf); +#else + return fstat (fd, stat_buf); +#endif +} + +static inline int +g_local_file_fstatat (int fd, + const char *path, + int flags, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + if ((G_LOCAL_FILE_STAT_FIELD_BASIC_STATS & (mask_required & mask)) != (mask_required & mask)) + { + /* Only G_LOCAL_FILE_STAT_FIELD_BASIC_STATS are supported. */ + errno = ERANGE; + return -1; + } + +#if !defined(G_OS_WIN32) && defined(AT_FDCWD) + return fstatat (fd, path, stat_buf, flags); +#else + /* Currently not supported on Windows or macOS < 10.10 */ + errno = ENOSYS; + return -1; +#endif +} + +static inline int +g_local_file_lstat (const char *path, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + if ((G_LOCAL_FILE_STAT_FIELD_BASIC_STATS & (mask_required & mask)) != (mask_required & mask)) + { + /* Only G_LOCAL_FILE_STAT_FIELD_BASIC_STATS are supported. */ + errno = ERANGE; + return -1; + } + +#ifdef G_OS_WIN32 + return GLIB_PRIVATE_CALL (g_win32_lstat_utf8) (path, stat_buf); +#else + return g_lstat (path, stat_buf); +#endif +} + +static inline int +g_local_file_stat (const char *path, + GLocalFileStatField mask, + GLocalFileStatField mask_required, + GLocalFileStat *stat_buf) +{ + if ((G_LOCAL_FILE_STAT_FIELD_BASIC_STATS & (mask_required & mask)) != (mask_required & mask)) + { + /* Only G_LOCAL_FILE_STAT_FIELD_BASIC_STATS are supported. */ + errno = ERANGE; + return -1; + } + +#ifdef G_OS_WIN32 + return GLIB_PRIVATE_CALL (g_win32_stat_utf8) (path, stat_buf); +#else + return stat (path, stat_buf); +#endif +} + +inline static gboolean _g_stat_has_field (const GLocalFileStat *buf, GLocalFileStatField field) { return (G_LOCAL_FILE_STAT_FIELD_BASIC_STATS & field) == field; } + +#ifndef G_OS_WIN32 +inline static mode_t _g_stat_mode (const GLocalFileStat *buf) { return buf->st_mode; } +inline static nlink_t _g_stat_nlink (const GLocalFileStat *buf) { return buf->st_nlink; } +#else +inline static guint16 _g_stat_mode (const GLocalFileStat *buf) { return buf->st_mode; } +inline static guint32 _g_stat_nlink (const GLocalFileStat *buf) { return buf->st_nlink; } +#endif +inline static dev_t _g_stat_dev (const GLocalFileStat *buf) { return buf->st_dev; } +inline static ino_t _g_stat_ino (const GLocalFileStat *buf) { return buf->st_ino; } +inline static goffset _g_stat_size (const GLocalFileStat *buf) { return buf->st_size; } + +#ifndef G_OS_WIN32 +inline static uid_t _g_stat_uid (const GLocalFileStat *buf) { return buf->st_uid; } +inline static gid_t _g_stat_gid (const GLocalFileStat *buf) { return buf->st_gid; } +inline static dev_t _g_stat_rdev (const GLocalFileStat *buf) { return buf->st_rdev; } +inline static blksize_t _g_stat_blksize (const GLocalFileStat *buf) { return buf->st_blksize; } +#else +inline static guint16 _g_stat_uid (const GLocalFileStat *buf) { return buf->st_uid; } +inline static guint16 _g_stat_gid (const GLocalFileStat *buf) { return buf->st_gid; } +#endif + +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS +inline static blkcnt_t _g_stat_blocks (const GLocalFileStat *buf) { return buf->st_blocks; } +#endif + +#ifndef G_OS_WIN32 +inline static time_t _g_stat_atime (const GLocalFileStat *buf) { return buf->st_atime; } +inline static time_t _g_stat_ctime (const GLocalFileStat *buf) { return buf->st_ctime; } +inline static time_t _g_stat_mtime (const GLocalFileStat *buf) { return buf->st_mtime; } +#else +inline static time_t _g_stat_atime (const GLocalFileStat *buf) { return buf->st_atim.tv_sec; } +inline static time_t _g_stat_ctime (const GLocalFileStat *buf) { return buf->st_ctim.tv_sec; } +inline static time_t _g_stat_mtime (const GLocalFileStat *buf) { return buf->st_mtim.tv_sec; } +#endif +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) || defined(G_OS_WIN32) +inline static guint32 _g_stat_atim_nsec (const GLocalFileStat *buf) { return buf->st_atim.tv_nsec; } +inline static guint32 _g_stat_ctim_nsec (const GLocalFileStat *buf) { return buf->st_ctim.tv_nsec; } +inline static guint32 _g_stat_mtim_nsec (const GLocalFileStat *buf) { return buf->st_mtim.tv_nsec; } +#else +inline static guint32 _g_stat_atim_nsec (const GLocalFileStat *buf) { return 0; } +inline static guint32 _g_stat_ctim_nsec (const GLocalFileStat *buf) { return 0; } +inline static guint32 _g_stat_mtim_nsec (const GLocalFileStat *buf) { return 0; } +#endif + +#endif /* !HAVE_STATX */ + +#define G_LOCAL_FILE_INFO_NOSTAT_ATTRIBUTES \ + G_FILE_ATTRIBUTE_STANDARD_NAME "," \ + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," \ + G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME "," \ + G_FILE_ATTRIBUTE_STANDARD_COPY_NAME + +gboolean _g_local_file_has_trash_dir (const char *dirname, + dev_t dir_dev); +#ifdef G_OS_UNIX +gboolean _g_local_file_is_lost_found_dir (const char *path, + dev_t path_dev); +#endif +void _g_local_file_info_get_parent_info (const char *dir, + GFileAttributeMatcher *attribute_matcher, + GLocalParentFileInfo *parent_info); +void _g_local_file_info_free_parent_info (GLocalParentFileInfo *parent_info); +void _g_local_file_info_get_nostat (GFileInfo *info, + const char *basename, + const char *path, + GFileAttributeMatcher *attribute_matcher); +GFileInfo *_g_local_file_info_get (const char *basename, + const char *path, + GFileAttributeMatcher *attribute_matcher, + GFileQueryInfoFlags flags, + GLocalParentFileInfo *parent_info, + GError **error); +GFileInfo *_g_local_file_info_get_from_fd (int fd, + const char *attributes, + GError **error); +char * _g_local_file_info_create_etag (GLocalFileStat *statbuf); +gboolean _g_local_file_info_set_attribute (char *filename, + const char *attribute, + GFileAttributeType type, + gpointer value_p, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); +gboolean _g_local_file_info_set_attributes (char *filename, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* __G_FILE_LOCAL_FILE_INFO_H__ */ diff --git a/gio/glocalfileinputstream.c b/gio/glocalfileinputstream.c new file mode 100644 index 0000000..07532a2 --- /dev/null +++ b/gio/glocalfileinputstream.c @@ -0,0 +1,305 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include "gcancellable.h" +#include "gioerror.h" +#include "glocalfileinputstream.h" +#include "glocalfileinfo.h" +#include "glibintl.h" + +#ifdef G_OS_UNIX +#include +#include "glib-unix.h" +#include "gfiledescriptorbased.h" +#endif + +#ifdef G_OS_WIN32 +#include +#endif + +struct _GLocalFileInputStreamPrivate { + int fd; + guint do_close : 1; +}; + +#ifdef G_OS_UNIX +static void g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface); +#endif + +#define g_local_file_input_stream_get_type _g_local_file_input_stream_get_type +#ifdef G_OS_UNIX +G_DEFINE_TYPE_WITH_CODE (GLocalFileInputStream, g_local_file_input_stream, G_TYPE_FILE_INPUT_STREAM, + G_ADD_PRIVATE (GLocalFileInputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, + g_file_descriptor_based_iface_init)) +#else +G_DEFINE_TYPE_WITH_CODE (GLocalFileInputStream, g_local_file_input_stream, G_TYPE_FILE_INPUT_STREAM, + G_ADD_PRIVATE (GLocalFileInputStream)) +#endif + +static gssize g_local_file_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_local_file_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error); +static goffset g_local_file_input_stream_tell (GFileInputStream *stream); +static gboolean g_local_file_input_stream_can_seek (GFileInputStream *stream); +static gboolean g_local_file_input_stream_seek (GFileInputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static GFileInfo *g_local_file_input_stream_query_info (GFileInputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); +#ifdef G_OS_UNIX +static int g_local_file_input_stream_get_fd (GFileDescriptorBased *stream); +#endif + +void +_g_local_file_input_stream_set_do_close (GLocalFileInputStream *in, + gboolean do_close) +{ + in->priv->do_close = do_close; +} + +static void +g_local_file_input_stream_class_init (GLocalFileInputStreamClass *klass) +{ + GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass); + GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass); + + stream_class->read_fn = g_local_file_input_stream_read; + stream_class->close_fn = g_local_file_input_stream_close; + file_stream_class->tell = g_local_file_input_stream_tell; + file_stream_class->can_seek = g_local_file_input_stream_can_seek; + file_stream_class->seek = g_local_file_input_stream_seek; + file_stream_class->query_info = g_local_file_input_stream_query_info; +} + +#ifdef G_OS_UNIX +static void +g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface) +{ + iface->get_fd = g_local_file_input_stream_get_fd; +} +#endif + +static void +g_local_file_input_stream_init (GLocalFileInputStream *info) +{ + info->priv = g_local_file_input_stream_get_instance_private (info); + info->priv->do_close = TRUE; +} + +GFileInputStream * +_g_local_file_input_stream_new (int fd) +{ + GLocalFileInputStream *stream; + + stream = g_object_new (G_TYPE_LOCAL_FILE_INPUT_STREAM, NULL); + stream->priv->fd = fd; + + return G_FILE_INPUT_STREAM (stream); +} + +static gssize +g_local_file_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GLocalFileInputStream *file; + gssize res; + + file = G_LOCAL_FILE_INPUT_STREAM (stream); + + res = -1; + while (1) + { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + break; + res = read (file->priv->fd, buffer, count); + if (res == -1) + { + int errsv = errno; + + if (errsv == EINTR) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error reading from file: %s"), + g_strerror (errsv)); + } + + break; + } + + return res; +} + +static gboolean +g_local_file_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GLocalFileInputStream *file; + + file = G_LOCAL_FILE_INPUT_STREAM (stream); + + if (!file->priv->do_close) + return TRUE; + + if (file->priv->fd == -1) + return TRUE; + + if (!g_close (file->priv->fd, NULL)) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error closing file: %s"), + g_strerror (errsv)); + return FALSE; + } + + return TRUE; +} + + +static goffset +g_local_file_input_stream_tell (GFileInputStream *stream) +{ + GLocalFileInputStream *file; + off_t pos; + + file = G_LOCAL_FILE_INPUT_STREAM (stream); + + pos = lseek (file->priv->fd, 0, SEEK_CUR); + + if (pos == (off_t)-1) + return 0; + + return pos; +} + +static gboolean +g_local_file_input_stream_can_seek (GFileInputStream *stream) +{ + GLocalFileInputStream *file; + off_t pos; + + file = G_LOCAL_FILE_INPUT_STREAM (stream); + + pos = lseek (file->priv->fd, 0, SEEK_CUR); + + if (pos == (off_t)-1 && errno == ESPIPE) + return FALSE; + + return TRUE; +} + +static int +seek_type_to_lseek (GSeekType type) +{ + switch (type) + { + default: + case G_SEEK_CUR: + return SEEK_CUR; + + case G_SEEK_SET: + return SEEK_SET; + + case G_SEEK_END: + return SEEK_END; + } +} + +static gboolean +g_local_file_input_stream_seek (GFileInputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GLocalFileInputStream *file; + off_t pos; + + file = G_LOCAL_FILE_INPUT_STREAM (stream); + + pos = lseek (file->priv->fd, offset, seek_type_to_lseek (type)); + + if (pos == (off_t)-1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error seeking in file: %s"), + g_strerror (errsv)); + return FALSE; + } + + return TRUE; +} + +static GFileInfo * +g_local_file_input_stream_query_info (GFileInputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GLocalFileInputStream *file; + + file = G_LOCAL_FILE_INPUT_STREAM (stream); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + return _g_local_file_info_get_from_fd (file->priv->fd, + attributes, + error); +} + +#ifdef G_OS_UNIX +static int +g_local_file_input_stream_get_fd (GFileDescriptorBased *fd_based) +{ + GLocalFileInputStream *stream = G_LOCAL_FILE_INPUT_STREAM (fd_based); + return stream->priv->fd; +} +#endif diff --git a/gio/glocalfileinputstream.h b/gio/glocalfileinputstream.h new file mode 100644 index 0000000..ee8c960 --- /dev/null +++ b/gio/glocalfileinputstream.h @@ -0,0 +1,61 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOCAL_FILE_INPUT_STREAM_H__ +#define __G_LOCAL_FILE_INPUT_STREAM_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_LOCAL_FILE_INPUT_STREAM (_g_local_file_input_stream_get_type ()) +#define G_LOCAL_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_INPUT_STREAM, GLocalFileInputStream)) +#define G_LOCAL_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE_INPUT_STREAM, GLocalFileInputStreamClass)) +#define G_IS_LOCAL_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_INPUT_STREAM)) +#define G_IS_LOCAL_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_INPUT_STREAM)) +#define G_LOCAL_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE_INPUT_STREAM, GLocalFileInputStreamClass)) + +typedef struct _GLocalFileInputStream GLocalFileInputStream; +typedef struct _GLocalFileInputStreamClass GLocalFileInputStreamClass; +typedef struct _GLocalFileInputStreamPrivate GLocalFileInputStreamPrivate; + +struct _GLocalFileInputStream +{ + GFileInputStream parent_instance; + + /*< private >*/ + GLocalFileInputStreamPrivate *priv; +}; + +struct _GLocalFileInputStreamClass +{ + GFileInputStreamClass parent_class; +}; + +GType _g_local_file_input_stream_get_type (void) G_GNUC_CONST; + +GFileInputStream *_g_local_file_input_stream_new (int fd); +void _g_local_file_input_stream_set_do_close (GLocalFileInputStream *in, + gboolean do_close); + + +G_END_DECLS + +#endif /* __G_LOCAL_FILE_INPUT_STREAM_H__ */ diff --git a/gio/glocalfileiostream.c b/gio/glocalfileiostream.c new file mode 100644 index 0000000..779137f --- /dev/null +++ b/gio/glocalfileiostream.c @@ -0,0 +1,116 @@ +/* GIO - GLib Input, IO and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include "glibintl.h" +#include "gioerror.h" +#include "gcancellable.h" +#include "glocalfileiostream.h" +#include "glocalfileinputstream.h" +#include "glocalfileinfo.h" + +#ifdef G_OS_UNIX +#include "gfiledescriptorbased.h" +#endif + + +#define g_local_file_io_stream_get_type _g_local_file_io_stream_get_type +G_DEFINE_TYPE (GLocalFileIOStream, g_local_file_io_stream, G_TYPE_FILE_IO_STREAM) + +static void +g_local_file_io_stream_finalize (GObject *object) +{ + GLocalFileIOStream *file; + + file = G_LOCAL_FILE_IO_STREAM (object); + + g_object_unref (file->input_stream); + g_object_unref (file->output_stream); + + G_OBJECT_CLASS (g_local_file_io_stream_parent_class)->finalize (object); +} + +GFileIOStream * +_g_local_file_io_stream_new (GLocalFileOutputStream *output_stream) +{ + GLocalFileIOStream *stream; + int fd; + + stream = g_object_new (G_TYPE_LOCAL_FILE_IO_STREAM, NULL); + stream->output_stream = g_object_ref (G_OUTPUT_STREAM (output_stream)); + _g_local_file_output_stream_set_do_close (output_stream, FALSE); + fd = _g_local_file_output_stream_get_fd (output_stream); + stream->input_stream = (GInputStream *)_g_local_file_input_stream_new (fd); + + _g_local_file_input_stream_set_do_close (G_LOCAL_FILE_INPUT_STREAM (stream->input_stream), + FALSE); + + return G_FILE_IO_STREAM (stream); +} + +static GInputStream * +g_local_file_io_stream_get_input_stream (GIOStream *stream) +{ + return G_LOCAL_FILE_IO_STREAM (stream)->input_stream; +} + +static GOutputStream * +g_local_file_io_stream_get_output_stream (GIOStream *stream) +{ + return G_LOCAL_FILE_IO_STREAM (stream)->output_stream; +} + + +static gboolean +g_local_file_io_stream_close (GIOStream *stream, + GCancellable *cancellable, + GError **error) +{ + GLocalFileIOStream *file = G_LOCAL_FILE_IO_STREAM (stream); + + /* There are shortcutted and can't fail */ + g_output_stream_close (file->output_stream, cancellable, NULL); + g_input_stream_close (file->input_stream, cancellable, NULL); + + return + _g_local_file_output_stream_really_close (G_LOCAL_FILE_OUTPUT_STREAM (file->output_stream), + cancellable, error); +} + +static void +g_local_file_io_stream_class_init (GLocalFileIOStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass); + + gobject_class->finalize = g_local_file_io_stream_finalize; + + stream_class->get_input_stream = g_local_file_io_stream_get_input_stream; + stream_class->get_output_stream = g_local_file_io_stream_get_output_stream; + stream_class->close_fn = g_local_file_io_stream_close; +} + +static void +g_local_file_io_stream_init (GLocalFileIOStream *stream) +{ +} diff --git a/gio/glocalfileiostream.h b/gio/glocalfileiostream.h new file mode 100644 index 0000000..8c95920 --- /dev/null +++ b/gio/glocalfileiostream.h @@ -0,0 +1,58 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOCAL_FILE_IO_STREAM_H__ +#define __G_LOCAL_FILE_IO_STREAM_H__ + +#include +#include "glocalfileoutputstream.h" + +G_BEGIN_DECLS + +#define G_TYPE_LOCAL_FILE_IO_STREAM (_g_local_file_io_stream_get_type ()) +#define G_LOCAL_FILE_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_IO_STREAM, GLocalFileIOStream)) +#define G_LOCAL_FILE_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE_IO_STREAM, GLocalFileIOStreamClass)) +#define G_IS_LOCAL_FILE_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_IO_STREAM)) +#define G_IS_LOCAL_FILE_IO_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_IO_STREAM)) +#define G_LOCAL_FILE_IO_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE_IO_STREAM, GLocalFileIOStreamClass)) + +typedef struct _GLocalFileIOStream GLocalFileIOStream; +typedef struct _GLocalFileIOStreamClass GLocalFileIOStreamClass; +typedef struct _GLocalFileIOStreamPrivate GLocalFileIOStreamPrivate; + +struct _GLocalFileIOStream +{ + GFileIOStream parent_instance; + + GInputStream *input_stream; + GOutputStream *output_stream; +}; + +struct _GLocalFileIOStreamClass +{ + GFileIOStreamClass parent_class; +}; + +GType _g_local_file_io_stream_get_type (void) G_GNUC_CONST; +GFileIOStream * _g_local_file_io_stream_new (GLocalFileOutputStream *output_stream); + +G_END_DECLS + +#endif /* __G_LOCAL_FILE_IO_STREAM_H__ */ diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c new file mode 100644 index 0000000..68afd7b --- /dev/null +++ b/gio/glocalfilemonitor.c @@ -0,0 +1,931 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gioenumtypes.h" +#include "glocalfilemonitor.h" +#include "giomodule-priv.h" +#include "gioerror.h" +#include "glibintl.h" +#include "glocalfile.h" +#include "glib-private.h" + +#include + +#define DEFAULT_RATE_LIMIT 800 * G_TIME_SPAN_MILLISECOND +#define VIRTUAL_CHANGES_DONE_DELAY 2 * G_TIME_SPAN_SECOND + +/* GFileMonitorSource is a GSource responsible for emitting the changed + * signals in the owner-context of the GFileMonitor. + * + * It contains functionality for cross-thread queuing of events. It + * also handles merging of CHANGED events and emission of CHANGES_DONE + * events. + * + * We use the "priv" pointer in the external struct to store it. + */ +struct _GFileMonitorSource { + GSource source; + + GMutex lock; + GWeakRef instance_ref; + GFileMonitorFlags flags; + gchar *dirname; + gchar *basename; + gchar *filename; + GSequence *pending_changes; /* sorted by ready time */ + GHashTable *pending_changes_table; + GQueue event_queue; + gint64 rate_limit; +}; + +/* PendingChange is a struct to keep track of a file that needs to have + * (at least) a CHANGES_DONE_HINT event sent for it in the near future. + * + * If 'dirty' is TRUE then a CHANGED event also needs to be sent. + * + * last_emission is the last time a CHANGED event was emitted. It is + * used to calculate the time to send the next event. + */ +typedef struct { + gchar *child; + guint64 last_emission : 63; + guint64 dirty : 1; +} PendingChange; + +/* QueuedEvent is a signal that will be sent immediately, as soon as the + * source gets a chance to dispatch. The existence of any queued event + * implies that the source is ready now. + */ +typedef struct +{ + GFileMonitorEvent event_type; + GFile *child; + GFile *other; +} QueuedEvent; + +static gint64 +pending_change_get_ready_time (const PendingChange *change, + GFileMonitorSource *fms) +{ + if (change->dirty) + return change->last_emission + fms->rate_limit; + else + return change->last_emission + VIRTUAL_CHANGES_DONE_DELAY; +} + +static int +pending_change_compare_ready_time (gconstpointer a_p, + gconstpointer b_p, + gpointer user_data) +{ + GFileMonitorSource *fms = user_data; + const PendingChange *a = a_p; + const PendingChange *b = b_p; + gint64 ready_time_a; + gint64 ready_time_b; + + ready_time_a = pending_change_get_ready_time (a, fms); + ready_time_b = pending_change_get_ready_time (b, fms); + + if (ready_time_a < ready_time_b) + return -1; + else + return ready_time_a > ready_time_b; +} + +static void +pending_change_free (gpointer data) +{ + PendingChange *change = data; + + g_free (change->child); + + g_slice_free (PendingChange, change); +} + +static void +queued_event_free (QueuedEvent *event) +{ + g_object_unref (event->child); + if (event->other) + g_object_unref (event->other); + + g_slice_free (QueuedEvent, event); +} + +static gint64 +g_file_monitor_source_get_ready_time (GFileMonitorSource *fms) +{ + GSequenceIter *iter; + + if (fms->event_queue.length) + return 0; + + iter = g_sequence_get_begin_iter (fms->pending_changes); + if (g_sequence_iter_is_end (iter)) + return -1; + + return pending_change_get_ready_time (g_sequence_get (iter), fms); +} + +static void +g_file_monitor_source_update_ready_time (GFileMonitorSource *fms) +{ + g_source_set_ready_time ((GSource *) fms, g_file_monitor_source_get_ready_time (fms)); +} + +static GSequenceIter * +g_file_monitor_source_find_pending_change (GFileMonitorSource *fms, + const gchar *child) +{ + return g_hash_table_lookup (fms->pending_changes_table, child); +} + +static void +g_file_monitor_source_add_pending_change (GFileMonitorSource *fms, + const gchar *child, + gint64 now) +{ + PendingChange *change; + GSequenceIter *iter; + + change = g_slice_new (PendingChange); + change->child = g_strdup (child); + change->last_emission = now; + change->dirty = FALSE; + + iter = g_sequence_insert_sorted (fms->pending_changes, change, pending_change_compare_ready_time, fms); + g_hash_table_insert (fms->pending_changes_table, change->child, iter); +} + +static gboolean +g_file_monitor_source_set_pending_change_dirty (GFileMonitorSource *fms, + GSequenceIter *iter) +{ + PendingChange *change; + + change = g_sequence_get (iter); + + /* if it was already dirty then this change is 'uninteresting' */ + if (change->dirty) + return FALSE; + + change->dirty = TRUE; + + g_sequence_sort_changed (iter, pending_change_compare_ready_time, fms); + + return TRUE; +} + +static gboolean +g_file_monitor_source_get_pending_change_dirty (GFileMonitorSource *fms, + GSequenceIter *iter) +{ + PendingChange *change; + + change = g_sequence_get (iter); + + return change->dirty; +} + +static void +g_file_monitor_source_remove_pending_change (GFileMonitorSource *fms, + GSequenceIter *iter, + const gchar *child) +{ + /* must remove the hash entry first -- its key is owned by the data + * which will be freed when removing the sequence iter + */ + g_hash_table_remove (fms->pending_changes_table, child); + g_sequence_remove (iter); +} + +static void +g_file_monitor_source_queue_event (GFileMonitorSource *fms, + GFileMonitorEvent event_type, + const gchar *child, + GFile *other) +{ + QueuedEvent *event; + + event = g_slice_new (QueuedEvent); + event->event_type = event_type; + if (child != NULL && fms->dirname != NULL) + event->child = g_local_file_new_from_dirname_and_basename (fms->dirname, child); + else if (child != NULL) + { + gchar *dirname = g_path_get_dirname (fms->filename); + event->child = g_local_file_new_from_dirname_and_basename (dirname, child); + g_free (dirname); + } + else if (fms->dirname) + event->child = _g_local_file_new (fms->dirname); + else if (fms->filename) + event->child = _g_local_file_new (fms->filename); + event->other = other; + if (other) + g_object_ref (other); + + g_queue_push_tail (&fms->event_queue, event); +} + +static gboolean +g_file_monitor_source_file_changed (GFileMonitorSource *fms, + const gchar *child, + gint64 now) +{ + GSequenceIter *pending; + gboolean interesting; + + pending = g_file_monitor_source_find_pending_change (fms, child); + + /* If there is no pending change, emit one and create a record, + * else: just mark the existing record as dirty. + */ + if (!pending) + { + g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGED, child, NULL); + g_file_monitor_source_add_pending_change (fms, child, now); + interesting = TRUE; + } + else + interesting = g_file_monitor_source_set_pending_change_dirty (fms, pending); + + g_file_monitor_source_update_ready_time (fms); + + return interesting; +} + +static void +g_file_monitor_source_file_changes_done (GFileMonitorSource *fms, + const gchar *child) +{ + GSequenceIter *pending; + + pending = g_file_monitor_source_find_pending_change (fms, child); + if (pending) + { + /* If it is dirty, make sure we push out the last CHANGED event */ + if (g_file_monitor_source_get_pending_change_dirty (fms, pending)) + g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGED, child, NULL); + + g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, child, NULL); + g_file_monitor_source_remove_pending_change (fms, pending, child); + } +} + +static void +g_file_monitor_source_file_created (GFileMonitorSource *fms, + const gchar *child, + gint64 event_time) +{ + /* Unlikely, but if we have pending changes for this filename, make + * sure we flush those out first, before creating the new ones. + */ + g_file_monitor_source_file_changes_done (fms, child); + + /* Emit CREATE and add a pending changes record */ + g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CREATED, child, NULL); + g_file_monitor_source_add_pending_change (fms, child, event_time); +} + +static void +g_file_monitor_source_send_event (GFileMonitorSource *fms, + GFileMonitorEvent event_type, + const gchar *child, + GFile *other) +{ + /* always flush any pending changes before we queue a new event */ + g_file_monitor_source_file_changes_done (fms, child); + g_file_monitor_source_queue_event (fms, event_type, child, other); +} + +static void +g_file_monitor_source_send_synthetic_created (GFileMonitorSource *fms, + const gchar *child) +{ + g_file_monitor_source_file_changes_done (fms, child); + g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CREATED, child, NULL); + g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, child, NULL); +} + +#ifndef G_DISABLE_ASSERT +static gboolean +is_basename (const gchar *name) +{ + if (name[0] == '.' && ((name[1] == '.' && name[2] == '\0') || name[1] == '\0')) + return FALSE; + + return !strchr (name, '/'); +} +#endif /* !G_DISABLE_ASSERT */ + +gboolean +g_file_monitor_source_handle_event (GFileMonitorSource *fms, + GFileMonitorEvent event_type, + const gchar *child, + const gchar *rename_to, + GFile *other, + gint64 event_time) +{ + gboolean interesting = TRUE; + + g_assert (!child || is_basename (child)); + g_assert (!rename_to || is_basename (rename_to)); + + if (fms->basename && (!child || !g_str_equal (child, fms->basename)) + && (!rename_to || !g_str_equal (rename_to, fms->basename))) + return TRUE; + + g_mutex_lock (&fms->lock); + + /* NOTE: + * + * We process events even if the file monitor has already been disposed. + * The reason is that we must not take a reference to the instance here as + * destroying it from the event handling thread will lead to a deadlock when + * taking the lock in _ih_sub_cancel. + * + * This results in seemingly-unbounded growth of the `event_queue` with the + * calls to `g_file_monitor_source_queue_event()`. However, each of those sets + * the ready time on the #GSource, which means that it will be dispatched in + * a subsequent iteration of the #GMainContext it’s attached to. At that + * point, `g_file_monitor_source_dispatch()` will return %FALSE, and this will + * trigger finalisation of the source. That will clear the `event_queue`. + * + * If the source is no longer attached, this will return early to prevent + * unbounded queueing. + */ + if (g_source_is_destroyed ((GSource *) fms)) + { + g_mutex_unlock (&fms->lock); + return TRUE; + } + + switch (event_type) + { + case G_FILE_MONITOR_EVENT_CREATED: + g_assert (!other && !rename_to); + g_file_monitor_source_file_created (fms, child, event_time); + break; + + case G_FILE_MONITOR_EVENT_CHANGED: + g_assert (!other && !rename_to); + interesting = g_file_monitor_source_file_changed (fms, child, event_time); + break; + + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + g_assert (!other && !rename_to); + g_file_monitor_source_file_changes_done (fms, child); + break; + + case G_FILE_MONITOR_EVENT_MOVED_IN: + g_assert (!rename_to); + if (fms->flags & G_FILE_MONITOR_WATCH_MOVES) + g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_MOVED_IN, child, other); + else + g_file_monitor_source_send_synthetic_created (fms, child); + break; + + case G_FILE_MONITOR_EVENT_MOVED_OUT: + g_assert (!rename_to); + if (fms->flags & G_FILE_MONITOR_WATCH_MOVES) + g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_MOVED_OUT, child, other); + else if (other && (fms->flags & G_FILE_MONITOR_SEND_MOVED)) + g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_MOVED, child, other); + else + g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_DELETED, child, NULL); + break; + + case G_FILE_MONITOR_EVENT_RENAMED: + g_assert (!other && rename_to); + if (fms->flags & (G_FILE_MONITOR_WATCH_MOVES | G_FILE_MONITOR_SEND_MOVED)) + { + GFile *other_file; + const gchar *dirname; + gchar *allocated_dirname = NULL; + GFileMonitorEvent event; + + event = (fms->flags & G_FILE_MONITOR_WATCH_MOVES) ? G_FILE_MONITOR_EVENT_RENAMED : G_FILE_MONITOR_EVENT_MOVED; + + if (fms->dirname != NULL) + dirname = fms->dirname; + else + { + allocated_dirname = g_path_get_dirname (fms->filename); + dirname = allocated_dirname; + } + + other_file = g_local_file_new_from_dirname_and_basename (dirname, rename_to); + g_file_monitor_source_file_changes_done (fms, rename_to); + g_file_monitor_source_send_event (fms, event, child, other_file); + + g_object_unref (other_file); + g_free (allocated_dirname); + } + else + { + g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_DELETED, child, NULL); + g_file_monitor_source_send_synthetic_created (fms, rename_to); + } + break; + + case G_FILE_MONITOR_EVENT_DELETED: + case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: + case G_FILE_MONITOR_EVENT_PRE_UNMOUNT: + case G_FILE_MONITOR_EVENT_UNMOUNTED: + g_assert (!other && !rename_to); + g_file_monitor_source_send_event (fms, event_type, child, NULL); + break; + + case G_FILE_MONITOR_EVENT_MOVED: + /* was never available in this API */ + default: + g_assert_not_reached (); + } + + g_file_monitor_source_update_ready_time (fms); + + g_mutex_unlock (&fms->lock); + + return interesting; +} + +static gint64 +g_file_monitor_source_get_rate_limit (GFileMonitorSource *fms) +{ + gint64 rate_limit; + + g_mutex_lock (&fms->lock); + rate_limit = fms->rate_limit; + g_mutex_unlock (&fms->lock); + + return rate_limit; +} + +static gboolean +g_file_monitor_source_set_rate_limit (GFileMonitorSource *fms, + gint64 rate_limit) +{ + gboolean changed; + + g_mutex_lock (&fms->lock); + + if (rate_limit != fms->rate_limit) + { + fms->rate_limit = rate_limit; + + g_sequence_sort (fms->pending_changes, pending_change_compare_ready_time, fms); + g_file_monitor_source_update_ready_time (fms); + + changed = TRUE; + } + else + changed = FALSE; + + g_mutex_unlock (&fms->lock); + + return changed; +} + +static gboolean +g_file_monitor_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GFileMonitorSource *fms = (GFileMonitorSource *) source; + QueuedEvent *event; + GQueue event_queue; + gint64 now; + GFileMonitor *instance = NULL; + + /* make sure the monitor still exists */ + instance = g_weak_ref_get (&fms->instance_ref); + if (instance == NULL) + return FALSE; + + now = g_source_get_time (source); + + /* Acquire the lock once and grab all events in one go, handling the + * queued events first. This avoids strange possibilities in cases of + * long delays, such as CHANGED events coming before CREATED events. + * + * We do this by converting the applicable pending changes into queued + * events (after the ones already queued) and then stealing the entire + * event queue in one go. + */ + g_mutex_lock (&fms->lock); + + /* Create events for any pending changes that are due to fire */ + while (!g_sequence_is_empty (fms->pending_changes)) + { + GSequenceIter *iter = g_sequence_get_begin_iter (fms->pending_changes); + PendingChange *pending = g_sequence_get (iter); + + /* We've gotten to a pending change that's not ready. Stop. */ + if (pending_change_get_ready_time (pending, fms) > now) + break; + + if (pending->dirty) + { + /* It's time to send another CHANGED and update the record */ + g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGED, pending->child, NULL); + pending->last_emission = now; + pending->dirty = FALSE; + + g_sequence_sort_changed (iter, pending_change_compare_ready_time, fms); + } + else + { + /* It's time to send CHANGES_DONE and remove the pending record */ + g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, pending->child, NULL); + g_file_monitor_source_remove_pending_change (fms, iter, pending->child); + } + } + + /* Steal the queue */ + memcpy (&event_queue, &fms->event_queue, sizeof event_queue); + memset (&fms->event_queue, 0, sizeof fms->event_queue); + + g_file_monitor_source_update_ready_time (fms); + + g_mutex_unlock (&fms->lock); + g_clear_object (&instance); + + /* We now have our list of events to deliver */ + while ((event = g_queue_pop_head (&event_queue))) + { + /* an event handler could destroy 'instance', so check each time */ + instance = g_weak_ref_get (&fms->instance_ref); + if (instance != NULL) + g_file_monitor_emit_event (instance, event->child, event->other, event->event_type); + + g_clear_object (&instance); + queued_event_free (event); + } + + return TRUE; +} + +static void +g_file_monitor_source_dispose (GFileMonitorSource *fms) +{ + GHashTableIter iter; + gpointer seqiter; + QueuedEvent *event; + + g_mutex_lock (&fms->lock); + + g_hash_table_iter_init (&iter, fms->pending_changes_table); + while (g_hash_table_iter_next (&iter, NULL, &seqiter)) + { + g_hash_table_iter_remove (&iter); + g_sequence_remove (seqiter); + } + + while ((event = g_queue_pop_head (&fms->event_queue))) + queued_event_free (event); + + g_assert (g_sequence_is_empty (fms->pending_changes)); + g_assert (g_hash_table_size (fms->pending_changes_table) == 0); + g_assert (fms->event_queue.length == 0); + g_weak_ref_set (&fms->instance_ref, NULL); + + g_file_monitor_source_update_ready_time (fms); + + g_source_destroy ((GSource *) fms); + + g_mutex_unlock (&fms->lock); +} + +static void +g_file_monitor_source_finalize (GSource *source) +{ + GFileMonitorSource *fms = (GFileMonitorSource *) source; + + /* should already have been cleared in dispose of the monitor */ + g_assert (g_weak_ref_get (&fms->instance_ref) == NULL); + g_weak_ref_clear (&fms->instance_ref); + + g_assert (g_sequence_is_empty (fms->pending_changes)); + g_assert (g_hash_table_size (fms->pending_changes_table) == 0); + g_assert (fms->event_queue.length == 0); + + g_hash_table_unref (fms->pending_changes_table); + g_sequence_free (fms->pending_changes); + + g_free (fms->dirname); + g_free (fms->basename); + g_free (fms->filename); + + g_mutex_clear (&fms->lock); +} + +static guint +str_hash0 (gconstpointer str) +{ + return str ? g_str_hash (str) : 0; +} + +static gboolean +str_equal0 (gconstpointer a, + gconstpointer b) +{ + return g_strcmp0 (a, b) == 0; +} + +static GFileMonitorSource * +g_file_monitor_source_new (gpointer instance, + const gchar *filename, + gboolean is_directory, + GFileMonitorFlags flags) +{ + static GSourceFuncs source_funcs = { + NULL, NULL, + g_file_monitor_source_dispatch, + g_file_monitor_source_finalize, + NULL, NULL + }; + GFileMonitorSource *fms; + GSource *source; + + source = g_source_new (&source_funcs, sizeof (GFileMonitorSource)); + fms = (GFileMonitorSource *) source; + + g_source_set_static_name (source, "GFileMonitorSource"); + + g_mutex_init (&fms->lock); + g_weak_ref_init (&fms->instance_ref, instance); + fms->pending_changes = g_sequence_new (pending_change_free); + fms->pending_changes_table = g_hash_table_new (str_hash0, str_equal0); + fms->rate_limit = DEFAULT_RATE_LIMIT; + fms->flags = flags; + + if (is_directory) + { + fms->dirname = g_strdup (filename); + fms->basename = NULL; + fms->filename = NULL; + } + else if (flags & G_FILE_MONITOR_WATCH_HARD_LINKS) + { + fms->dirname = NULL; + fms->basename = NULL; + fms->filename = g_strdup (filename); + } + else + { + fms->dirname = g_path_get_dirname (filename); + fms->basename = g_path_get_basename (filename); + fms->filename = NULL; + } + + return fms; +} + +G_DEFINE_ABSTRACT_TYPE (GLocalFileMonitor, g_local_file_monitor, G_TYPE_FILE_MONITOR) + +enum { + PROP_0, + PROP_RATE_LIMIT, +}; + +static void +g_local_file_monitor_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GLocalFileMonitor *monitor = G_LOCAL_FILE_MONITOR (object); + gint64 rate_limit; + + g_assert (prop_id == PROP_RATE_LIMIT); + + rate_limit = g_file_monitor_source_get_rate_limit (monitor->source); + rate_limit /= G_TIME_SPAN_MILLISECOND; + + g_value_set_int (value, rate_limit); +} + +static void +g_local_file_monitor_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + GLocalFileMonitor *monitor = G_LOCAL_FILE_MONITOR (object); + gint64 rate_limit; + + g_assert (prop_id == PROP_RATE_LIMIT); + + rate_limit = g_value_get_int (value); + rate_limit *= G_TIME_SPAN_MILLISECOND; + + if (g_file_monitor_source_set_rate_limit (monitor->source, rate_limit)) + g_object_notify (object, "rate-limit"); +} + +#ifndef G_OS_WIN32 +static void +g_local_file_monitor_mounts_changed (GUnixMountMonitor *mount_monitor, + gpointer user_data) +{ + GLocalFileMonitor *local_monitor = user_data; + GUnixMountEntry *mount; + gboolean is_mounted; + GFile *file; + + /* Emulate unmount detection */ + mount = g_unix_mount_at (local_monitor->source->dirname, NULL); + + is_mounted = mount != NULL; + + if (mount) + g_unix_mount_free (mount); + + if (local_monitor->was_mounted != is_mounted) + { + if (local_monitor->was_mounted && !is_mounted) + { + file = g_file_new_for_path (local_monitor->source->dirname); + g_file_monitor_emit_event (G_FILE_MONITOR (local_monitor), file, NULL, G_FILE_MONITOR_EVENT_UNMOUNTED); + g_object_unref (file); + } + local_monitor->was_mounted = is_mounted; + } +} +#endif + +static void +g_local_file_monitor_start (GLocalFileMonitor *local_monitor, + const gchar *filename, + gboolean is_directory, + GFileMonitorFlags flags, + GMainContext *context) +{ + GLocalFileMonitorClass *class = G_LOCAL_FILE_MONITOR_GET_CLASS (local_monitor); + GFileMonitorSource *source; + + g_return_if_fail (G_IS_LOCAL_FILE_MONITOR (local_monitor)); + + g_assert (!local_monitor->source); + + source = g_file_monitor_source_new (local_monitor, filename, is_directory, flags); + local_monitor->source = source; /* owns the ref */ + + if (is_directory && !class->mount_notify && (flags & G_FILE_MONITOR_WATCH_MOUNTS)) + { +#ifdef G_OS_WIN32 + /*claim everything was mounted */ + local_monitor->was_mounted = TRUE; +#else + GUnixMountEntry *mount; + + /* Emulate unmount detection */ + + mount = g_unix_mount_at (local_monitor->source->dirname, NULL); + + local_monitor->was_mounted = mount != NULL; + + if (mount) + g_unix_mount_free (mount); + + local_monitor->mount_monitor = g_unix_mount_monitor_get (); + g_signal_connect_object (local_monitor->mount_monitor, "mounts-changed", + G_CALLBACK (g_local_file_monitor_mounts_changed), local_monitor, 0); +#endif + } + + g_source_attach ((GSource *) source, context); + + G_LOCAL_FILE_MONITOR_GET_CLASS (local_monitor)->start (local_monitor, + source->dirname, source->basename, source->filename, + source); +} + +static void +g_local_file_monitor_dispose (GObject *object) +{ + GLocalFileMonitor *local_monitor = G_LOCAL_FILE_MONITOR (object); + + g_file_monitor_source_dispose (local_monitor->source); + + G_OBJECT_CLASS (g_local_file_monitor_parent_class)->dispose (object); +} + +static void +g_local_file_monitor_finalize (GObject *object) +{ + GLocalFileMonitor *local_monitor = G_LOCAL_FILE_MONITOR (object); + + g_source_unref ((GSource *) local_monitor->source); + + G_OBJECT_CLASS (g_local_file_monitor_parent_class)->finalize (object); +} + +static void +g_local_file_monitor_init (GLocalFileMonitor* local_monitor) +{ +} + +static void g_local_file_monitor_class_init (GLocalFileMonitorClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->get_property = g_local_file_monitor_get_property; + gobject_class->set_property = g_local_file_monitor_set_property; + gobject_class->dispose = g_local_file_monitor_dispose; + gobject_class->finalize = g_local_file_monitor_finalize; + + g_object_class_override_property (gobject_class, PROP_RATE_LIMIT, "rate-limit"); +} + +static GLocalFileMonitor * +g_local_file_monitor_new (gboolean is_remote_fs, + gboolean is_directory, + GError **error) +{ + GType type = G_TYPE_INVALID; + + if (is_remote_fs) + type = _g_io_module_get_default_type (G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME, + "GIO_USE_FILE_MONITOR", + G_STRUCT_OFFSET (GLocalFileMonitorClass, is_supported)); + + /* Fallback rather to poll file monitor for remote files, see gfile.c. */ + if (type == G_TYPE_INVALID && (!is_remote_fs || is_directory)) + type = _g_io_module_get_default_type (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + "GIO_USE_FILE_MONITOR", + G_STRUCT_OFFSET (GLocalFileMonitorClass, is_supported)); + + if (type == G_TYPE_INVALID) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Unable to find default local file monitor type")); + return NULL; + } + + return g_object_new (type, NULL); +} + +GFileMonitor * +g_local_file_monitor_new_for_path (const gchar *pathname, + gboolean is_directory, + GFileMonitorFlags flags, + GError **error) +{ + GLocalFileMonitor *monitor; + gboolean is_remote_fs; + + is_remote_fs = g_local_file_is_nfs_home (pathname); + + monitor = g_local_file_monitor_new (is_remote_fs, is_directory, error); + + if (monitor) + g_local_file_monitor_start (monitor, pathname, is_directory, flags, g_main_context_get_thread_default ()); + + return G_FILE_MONITOR (monitor); +} + +GFileMonitor * +g_local_file_monitor_new_in_worker (const gchar *pathname, + gboolean is_directory, + GFileMonitorFlags flags, + GFileMonitorCallback callback, + gpointer user_data, + GClosureNotify destroy_user_data, + GError **error) +{ + GLocalFileMonitor *monitor; + gboolean is_remote_fs; + + is_remote_fs = g_local_file_is_nfs_home (pathname); + + monitor = g_local_file_monitor_new (is_remote_fs, is_directory, error); + + if (monitor) + { + if (callback) + g_signal_connect_data (monitor, "changed", G_CALLBACK (callback), + user_data, destroy_user_data, 0 /* flags */); + + g_local_file_monitor_start (monitor, pathname, is_directory, flags, GLIB_PRIVATE_CALL(g_get_worker_context) ()); + } + + return G_FILE_MONITOR (monitor); +} diff --git a/gio/glocalfilemonitor.h b/gio/glocalfilemonitor.h new file mode 100644 index 0000000..3d3cf75 --- /dev/null +++ b/gio/glocalfilemonitor.h @@ -0,0 +1,106 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOCAL_FILE_MONITOR_H__ +#define __G_LOCAL_FILE_MONITOR_H__ + +#include +#include "gunixmounts.h" + +G_BEGIN_DECLS + +#define G_TYPE_LOCAL_FILE_MONITOR (g_local_file_monitor_get_type ()) +#define G_LOCAL_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_MONITOR, GLocalFileMonitor)) +#define G_LOCAL_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_LOCAL_FILE_MONITOR, GLocalFileMonitorClass)) +#define G_IS_LOCAL_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_MONITOR)) +#define G_IS_LOCAL_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_MONITOR)) +#define G_LOCAL_FILE_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE_MONITOR, GLocalFileMonitorClass)) + +#define G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME "gio-local-file-monitor" +#define G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME "gio-nfs-file-monitor" + +typedef struct _GLocalFileMonitor GLocalFileMonitor; +typedef struct _GLocalFileMonitorClass GLocalFileMonitorClass; +typedef struct _GFileMonitorSource GFileMonitorSource; + +struct _GLocalFileMonitor +{ + GFileMonitor parent_instance; + + GFileMonitorSource *source; + GUnixMountMonitor *mount_monitor; + gboolean was_mounted; +}; + +struct _GLocalFileMonitorClass +{ + GFileMonitorClass parent_class; + + gboolean (* is_supported) (void); + void (* start) (GLocalFileMonitor *local_monitor, + const gchar *dirname, + const gchar *basename, + const gchar *filename, + GFileMonitorSource *source); + + gboolean mount_notify; +}; + +#ifdef G_OS_UNIX +GLIB_AVAILABLE_IN_ALL +#endif +GType g_local_file_monitor_get_type (void) G_GNUC_CONST; + +/* for glocalfile.c */ +GFileMonitor * +g_local_file_monitor_new_for_path (const gchar *pathname, + gboolean is_directory, + GFileMonitorFlags flags, + GError **error); + +/* for various users in glib */ +typedef void (* GFileMonitorCallback) (GFileMonitor *monitor, + GFile *child, + GFile *other, + GFileMonitorEvent event, + gpointer user_data); +GFileMonitor * +g_local_file_monitor_new_in_worker (const gchar *pathname, + gboolean is_directory, + GFileMonitorFlags flags, + GFileMonitorCallback callback, + gpointer user_data, + GClosureNotify destroy_user_data, + GError **error); + +/* for implementations of GLocalFileMonitor */ +GLIB_AVAILABLE_IN_2_44 +gboolean +g_file_monitor_source_handle_event (GFileMonitorSource *fms, + GFileMonitorEvent event_type, + const gchar *child, + const gchar *rename_to, + GFile *other, + gint64 event_time); + + +G_END_DECLS + +#endif /* __G_LOCAL_FILE_MONITOR_H__ */ diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c new file mode 100644 index 0000000..5d6a488 --- /dev/null +++ b/gio/glocalfileoutputstream.c @@ -0,0 +1,1340 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +/* Needed for the statx() calls in inline functions in glocalfileinfo.h */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include "glibintl.h" +#include "gioerror.h" +#include "gcancellable.h" +#include "glocalfileoutputstream.h" +#include "gfileinfo.h" +#include "glocalfileinfo.h" + +#ifdef G_OS_UNIX +#include +#include "gfiledescriptorbased.h" +#include +#endif + +#include "glib-private.h" +#include "gioprivate.h" + +#ifdef G_OS_WIN32 +#include +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#endif +#ifndef S_ISREG +#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#else +#define HAVE_O_CLOEXEC 1 +#endif + +struct _GLocalFileOutputStreamPrivate { + char *tmp_filename; + char *original_filename; + char *backup_filename; + char *etag; + guint sync_on_close : 1; + guint do_close : 1; + int fd; +}; + +#ifdef G_OS_UNIX +static void g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface); +#endif + +#define g_local_file_output_stream_get_type _g_local_file_output_stream_get_type +#ifdef G_OS_UNIX +G_DEFINE_TYPE_WITH_CODE (GLocalFileOutputStream, g_local_file_output_stream, G_TYPE_FILE_OUTPUT_STREAM, + G_ADD_PRIVATE (GLocalFileOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, + g_file_descriptor_based_iface_init)) +#else +G_DEFINE_TYPE_WITH_CODE (GLocalFileOutputStream, g_local_file_output_stream, G_TYPE_FILE_OUTPUT_STREAM, + G_ADD_PRIVATE (GLocalFileOutputStream)) +#endif + + +/* Some of the file replacement code was based on the code from gedit, + * relicenced to LGPL with permissions from the authors. + */ + +#define BACKUP_EXTENSION "~" + +static gssize g_local_file_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +#ifdef G_OS_UNIX +static gboolean g_local_file_output_stream_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); +#endif +static gboolean g_local_file_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error); +static GFileInfo *g_local_file_output_stream_query_info (GFileOutputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); +static char * g_local_file_output_stream_get_etag (GFileOutputStream *stream); +static goffset g_local_file_output_stream_tell (GFileOutputStream *stream); +static gboolean g_local_file_output_stream_can_seek (GFileOutputStream *stream); +static gboolean g_local_file_output_stream_seek (GFileOutputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_local_file_output_stream_can_truncate (GFileOutputStream *stream); +static gboolean g_local_file_output_stream_truncate (GFileOutputStream *stream, + goffset size, + GCancellable *cancellable, + GError **error); +#ifdef G_OS_UNIX +static int g_local_file_output_stream_get_fd (GFileDescriptorBased *stream); +#endif + +static void +g_local_file_output_stream_finalize (GObject *object) +{ + GLocalFileOutputStream *file; + + file = G_LOCAL_FILE_OUTPUT_STREAM (object); + + g_free (file->priv->tmp_filename); + g_free (file->priv->original_filename); + g_free (file->priv->backup_filename); + g_free (file->priv->etag); + + G_OBJECT_CLASS (g_local_file_output_stream_parent_class)->finalize (object); +} + +static void +g_local_file_output_stream_class_init (GLocalFileOutputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass); + GFileOutputStreamClass *file_stream_class = G_FILE_OUTPUT_STREAM_CLASS (klass); + + gobject_class->finalize = g_local_file_output_stream_finalize; + + stream_class->write_fn = g_local_file_output_stream_write; +#ifdef G_OS_UNIX + stream_class->writev_fn = g_local_file_output_stream_writev; +#endif + stream_class->close_fn = g_local_file_output_stream_close; + file_stream_class->query_info = g_local_file_output_stream_query_info; + file_stream_class->get_etag = g_local_file_output_stream_get_etag; + file_stream_class->tell = g_local_file_output_stream_tell; + file_stream_class->can_seek = g_local_file_output_stream_can_seek; + file_stream_class->seek = g_local_file_output_stream_seek; + file_stream_class->can_truncate = g_local_file_output_stream_can_truncate; + file_stream_class->truncate_fn = g_local_file_output_stream_truncate; +} + +#ifdef G_OS_UNIX +static void +g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface) +{ + iface->get_fd = g_local_file_output_stream_get_fd; +} +#endif + +static void +g_local_file_output_stream_init (GLocalFileOutputStream *stream) +{ + stream->priv = g_local_file_output_stream_get_instance_private (stream); + stream->priv->do_close = TRUE; +} + +static gssize +g_local_file_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GLocalFileOutputStream *file; + gssize res; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + while (1) + { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + res = write (file->priv->fd, buffer, count); + if (res == -1) + { + int errsv = errno; + + if (errsv == EINTR) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file: %s"), + g_strerror (errsv)); + } + + break; + } + + return res; +} + +/* On Windows there is no equivalent API for files. The closest API to that is + * WriteFileGather() but it is useless in general: it requires, among other + * things, that each chunk is the size of a whole page and in memory aligned + * to a page. We can't possibly guarantee that in GLib. + */ +#ifdef G_OS_UNIX +/* Macro to check if struct iovec and GOutputVector have the same ABI */ +#define G_OUTPUT_VECTOR_IS_IOVEC (sizeof (struct iovec) == sizeof (GOutputVector) && \ + G_SIZEOF_MEMBER (struct iovec, iov_base) == G_SIZEOF_MEMBER (GOutputVector, buffer) && \ + G_STRUCT_OFFSET (struct iovec, iov_base) == G_STRUCT_OFFSET (GOutputVector, buffer) && \ + G_SIZEOF_MEMBER (struct iovec, iov_len) == G_SIZEOF_MEMBER (GOutputVector, size) && \ + G_STRUCT_OFFSET (struct iovec, iov_len) == G_STRUCT_OFFSET (GOutputVector, size)) + +static gboolean +g_local_file_output_stream_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + GLocalFileOutputStream *file; + gssize res; + struct iovec *iov; + + if (bytes_written) + *bytes_written = 0; + + /* Clamp the number of vectors if more given than we can write in one go. + * The caller has to handle short writes anyway. + */ + if (n_vectors > G_IOV_MAX) + n_vectors = G_IOV_MAX; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + if (G_OUTPUT_VECTOR_IS_IOVEC) + { + /* ABI is compatible */ + iov = (struct iovec *) vectors; + } + else + { + gsize i; + + /* ABI is incompatible */ + iov = g_newa (struct iovec, n_vectors); + for (i = 0; i < n_vectors; i++) + { + iov[i].iov_base = (void *)vectors[i].buffer; + iov[i].iov_len = vectors[i].size; + } + } + + while (1) + { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + res = writev (file->priv->fd, iov, n_vectors); + if (res == -1) + { + int errsv = errno; + + if (errsv == EINTR) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file: %s"), + g_strerror (errsv)); + } + else if (bytes_written) + { + *bytes_written = res; + } + + break; + } + + return res != -1; +} +#endif + +void +_g_local_file_output_stream_set_do_close (GLocalFileOutputStream *out, + gboolean do_close) +{ + out->priv->do_close = do_close; +} + +gboolean +_g_local_file_output_stream_really_close (GLocalFileOutputStream *file, + GCancellable *cancellable, + GError **error) +{ + GLocalFileStat final_stat; + + if (file->priv->sync_on_close && + g_fsync (file->priv->fd) != 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file: %s"), + g_strerror (errsv)); + goto err_out; + } + +#ifdef G_OS_WIN32 + + /* Must close before renaming on Windows, so just do the close first + * in all cases for now. + */ + if (GLIB_PRIVATE_CALL (g_win32_fstat) (file->priv->fd, &final_stat) == 0) + file->priv->etag = _g_local_file_info_create_etag (&final_stat); + + if (!g_close (file->priv->fd, NULL)) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error closing file: %s"), + g_strerror (errsv)); + return FALSE; + } + +#endif + + if (file->priv->tmp_filename) + { + /* We need to move the temp file to its final place, + * and possibly create the backup file + */ + + if (file->priv->backup_filename) + { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto err_out; + +#ifdef G_OS_UNIX + /* create original -> backup link, the original is then renamed over */ + if (g_unlink (file->priv->backup_filename) != 0 && + errno != ENOENT) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Error removing old backup link: %s"), + g_strerror (errsv)); + goto err_out; + } + + if (link (file->priv->original_filename, file->priv->backup_filename) != 0) + { + /* link failed or is not supported, try rename */ + if (g_rename (file->priv->original_filename, file->priv->backup_filename) != 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Error creating backup copy: %s"), + g_strerror (errsv)); + goto err_out; + } + } +#else + /* If link not supported, just rename... */ + if (g_rename (file->priv->original_filename, file->priv->backup_filename) != 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Error creating backup copy: %s"), + g_strerror (errsv)); + goto err_out; + } +#endif + } + + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto err_out; + + /* tmp -> original */ + if (g_rename (file->priv->tmp_filename, file->priv->original_filename) != 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error renaming temporary file: %s"), + g_strerror (errsv)); + goto err_out; + } + + g_clear_pointer (&file->priv->tmp_filename, g_free); + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto err_out; + +#ifndef G_OS_WIN32 /* Already did the fstat() and close() above on Win32 */ + + if (g_local_file_fstat (file->priv->fd, G_LOCAL_FILE_STAT_FIELD_MTIME, G_LOCAL_FILE_STAT_FIELD_ALL, &final_stat) == 0) + file->priv->etag = _g_local_file_info_create_etag (&final_stat); + + if (!g_close (file->priv->fd, NULL)) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error closing file: %s"), + g_strerror (errsv)); + goto err_out; + } + +#endif + + return TRUE; + err_out: + +#ifndef G_OS_WIN32 + /* A simple try to close the fd in case we fail before the actual close */ + g_close (file->priv->fd, NULL); +#endif + if (file->priv->tmp_filename) + g_unlink (file->priv->tmp_filename); + + return FALSE; +} + + +static gboolean +g_local_file_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GLocalFileOutputStream *file; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + if (file->priv->do_close) + return _g_local_file_output_stream_really_close (file, + cancellable, + error); + return TRUE; +} + +static char * +g_local_file_output_stream_get_etag (GFileOutputStream *stream) +{ + GLocalFileOutputStream *file; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + return g_strdup (file->priv->etag); +} + +static goffset +g_local_file_output_stream_tell (GFileOutputStream *stream) +{ + GLocalFileOutputStream *file; + off_t pos; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + pos = lseek (file->priv->fd, 0, SEEK_CUR); + + if (pos == (off_t)-1) + return 0; + + return pos; +} + +static gboolean +g_local_file_output_stream_can_seek (GFileOutputStream *stream) +{ + GLocalFileOutputStream *file; + off_t pos; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + pos = lseek (file->priv->fd, 0, SEEK_CUR); + + if (pos == (off_t)-1 && errno == ESPIPE) + return FALSE; + + return TRUE; +} + +static int +seek_type_to_lseek (GSeekType type) +{ + switch (type) + { + default: + case G_SEEK_CUR: + return SEEK_CUR; + + case G_SEEK_SET: + return SEEK_SET; + + case G_SEEK_END: + return SEEK_END; + } +} + +static gboolean +g_local_file_output_stream_seek (GFileOutputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GLocalFileOutputStream *file; + off_t pos; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + pos = lseek (file->priv->fd, offset, seek_type_to_lseek (type)); + + if (pos == (off_t)-1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error seeking in file: %s"), + g_strerror (errsv)); + return FALSE; + } + + return TRUE; +} + +static gboolean +g_local_file_output_stream_can_truncate (GFileOutputStream *stream) +{ + /* We can't truncate pipes and stuff where we can't seek */ + return g_local_file_output_stream_can_seek (stream); +} + +static gboolean +g_local_file_output_stream_truncate (GFileOutputStream *stream, + goffset size, + GCancellable *cancellable, + GError **error) +{ + GLocalFileOutputStream *file; + int res; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + restart: +#ifdef G_OS_WIN32 + res = g_win32_ftruncate (file->priv->fd, size); +#else + res = ftruncate (file->priv->fd, size); +#endif + + if (res == -1) + { + int errsv = errno; + + if (errsv == EINTR) + { + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + goto restart; + } + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error truncating file: %s"), + g_strerror (errsv)); + return FALSE; + } + + return TRUE; +} + + +static GFileInfo * +g_local_file_output_stream_query_info (GFileOutputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GLocalFileOutputStream *file; + + file = G_LOCAL_FILE_OUTPUT_STREAM (stream); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + return _g_local_file_info_get_from_fd (file->priv->fd, + attributes, + error); +} + +GFileOutputStream * +_g_local_file_output_stream_new (int fd) +{ + GLocalFileOutputStream *stream; + + stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL); + stream->priv->fd = fd; + return G_FILE_OUTPUT_STREAM (stream); +} + +static void +set_error_from_open_errno (const char *filename, + GError **error) +{ + int errsv = errno; + + if (errsv == EINVAL) + /* This must be an invalid filename, on e.g. FAT */ + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_INVALID_FILENAME, + _("Invalid filename")); + else + { + char *display_name = g_filename_display_name (filename); + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error opening file “%sâ€: %s"), + display_name, g_strerror (errsv)); + g_free (display_name); + } +} + +static GFileOutputStream * +output_stream_open (const char *filename, + gint open_flags, + guint mode, + GCancellable *cancellable, + GError **error) +{ + GLocalFileOutputStream *stream; + gint fd; + + fd = g_open (filename, open_flags, mode); + if (fd == -1) + { + set_error_from_open_errno (filename, error); + return NULL; + } + + stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL); + stream->priv->fd = fd; + return G_FILE_OUTPUT_STREAM (stream); +} + +GFileOutputStream * +_g_local_file_output_stream_open (const char *filename, + gboolean readable, + GCancellable *cancellable, + GError **error) +{ + int open_flags; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + open_flags = O_BINARY; + if (readable) + open_flags |= O_RDWR; + else + open_flags |= O_WRONLY; + + return output_stream_open (filename, open_flags, 0666, cancellable, error); +} + +static gint +mode_from_flags_or_info (GFileCreateFlags flags, + GFileInfo *reference_info) +{ + if (flags & G_FILE_CREATE_PRIVATE) + return 0600; + else if (reference_info && g_file_info_has_attribute (reference_info, "unix::mode")) + return g_file_info_get_attribute_uint32 (reference_info, "unix::mode") & (~S_IFMT); + else + return 0666; +} + +GFileOutputStream * +_g_local_file_output_stream_create (const char *filename, + gboolean readable, + GFileCreateFlags flags, + GFileInfo *reference_info, + GCancellable *cancellable, + GError **error) +{ + int mode; + int open_flags; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + mode = mode_from_flags_or_info (flags, reference_info); + + open_flags = O_CREAT | O_EXCL | O_BINARY; + if (readable) + open_flags |= O_RDWR; + else + open_flags |= O_WRONLY; + + return output_stream_open (filename, open_flags, mode, cancellable, error); +} + +GFileOutputStream * +_g_local_file_output_stream_append (const char *filename, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + int mode; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + if (flags & G_FILE_CREATE_PRIVATE) + mode = 0600; + else + mode = 0666; + + return output_stream_open (filename, O_CREAT | O_APPEND | O_WRONLY | O_BINARY, mode, + cancellable, error); +} + +static char * +create_backup_filename (const char *filename) +{ + return g_strconcat (filename, BACKUP_EXTENSION, NULL); +} + +#define BUFSIZE 8192 /* size of normal write buffer */ + +static gboolean +copy_file_data (gint sfd, + gint dfd, + GError **error) +{ + gboolean ret = TRUE; + gpointer buffer; + const gchar *write_buffer; + gssize bytes_read; + gssize bytes_to_write; + gssize bytes_written; + + buffer = g_malloc (BUFSIZE); + + do + { + bytes_read = read (sfd, buffer, BUFSIZE); + if (bytes_read == -1) + { + int errsv = errno; + + if (errsv == EINTR) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error reading from file: %s"), + g_strerror (errsv)); + ret = FALSE; + break; + } + + bytes_to_write = bytes_read; + write_buffer = buffer; + + do + { + bytes_written = write (dfd, write_buffer, bytes_to_write); + if (bytes_written == -1) + { + int errsv = errno; + + if (errsv == EINTR) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file: %s"), + g_strerror (errsv)); + ret = FALSE; + break; + } + + bytes_to_write -= bytes_written; + write_buffer += bytes_written; + } + while (bytes_to_write > 0); + + } while ((bytes_read != 0) && (ret == TRUE)); + + g_free (buffer); + + return ret; +} + +static int +handle_overwrite_open (const char *filename, + gboolean readable, + const char *etag, + gboolean create_backup, + char **temp_filename, + GFileCreateFlags flags, + GFileInfo *reference_info, + GCancellable *cancellable, + GError **error) +{ + int fd = -1; + GLocalFileStat original_stat; + char *current_etag; + gboolean is_symlink; + int open_flags; + int res; + int mode; + int errsv = 0; + gboolean replace_destination_set = (flags & G_FILE_CREATE_REPLACE_DESTINATION); + + mode = mode_from_flags_or_info (flags, reference_info); + + /* We only need read access to the original file if we are creating a backup. + * We also add O_CREAT to avoid a race if the file was just removed */ + if (create_backup || readable) + open_flags = O_RDWR | O_CREAT | O_BINARY; + else + open_flags = O_WRONLY | O_CREAT | O_BINARY; + + /* Some systems have O_NOFOLLOW, which lets us avoid some races + * when finding out if the file we opened was a symlink */ +#ifdef O_NOFOLLOW + is_symlink = FALSE; + fd = g_open (filename, open_flags | O_NOFOLLOW, mode); + errsv = errno; +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + if (fd == -1 && errsv == EMLINK) +#elif defined(__NetBSD__) + if (fd == -1 && errsv == EFTYPE) +#else + if (fd == -1 && errsv == ELOOP) +#endif + { + /* Could be a symlink, or it could be a regular ELOOP error, + * but then the next open will fail too. */ + is_symlink = TRUE; + if (!replace_destination_set) + fd = g_open (filename, open_flags, mode); + } +#else /* if !O_NOFOLLOW */ + /* This is racy, but we do it as soon as possible to minimize the race */ + is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK); + + if (!is_symlink || !replace_destination_set) + { + fd = g_open (filename, open_flags, mode); + errsv = errno; + } +#endif + + if (fd == -1 && + (!is_symlink || !replace_destination_set)) + { + char *display_name = g_filename_display_name (filename); + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error opening file “%sâ€: %s"), + display_name, g_strerror (errsv)); + g_free (display_name); + return -1; + } + + if (!is_symlink) + { + res = g_local_file_fstat (fd, + G_LOCAL_FILE_STAT_FIELD_TYPE | + G_LOCAL_FILE_STAT_FIELD_MODE | + G_LOCAL_FILE_STAT_FIELD_UID | + G_LOCAL_FILE_STAT_FIELD_GID | + G_LOCAL_FILE_STAT_FIELD_MTIME | + G_LOCAL_FILE_STAT_FIELD_NLINK, + G_LOCAL_FILE_STAT_FIELD_ALL, &original_stat); + errsv = errno; + } + else + { + res = g_local_file_lstat (filename, + G_LOCAL_FILE_STAT_FIELD_TYPE | + G_LOCAL_FILE_STAT_FIELD_MODE | + G_LOCAL_FILE_STAT_FIELD_UID | + G_LOCAL_FILE_STAT_FIELD_GID | + G_LOCAL_FILE_STAT_FIELD_MTIME | + G_LOCAL_FILE_STAT_FIELD_NLINK, + G_LOCAL_FILE_STAT_FIELD_ALL, &original_stat); + errsv = errno; + } + + if (res != 0) + { + char *display_name = g_filename_display_name (filename); + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error when getting information for file “%sâ€: %s"), + display_name, g_strerror (errsv)); + g_free (display_name); + goto error; + } + + /* not a regular file */ + if (!S_ISREG (_g_stat_mode (&original_stat))) + { + if (S_ISDIR (_g_stat_mode (&original_stat))) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_IS_DIRECTORY, + _("Target file is a directory")); + goto error; + } + else if (!is_symlink || +#ifdef S_ISLNK + !S_ISLNK (_g_stat_mode (&original_stat)) +#else + FALSE +#endif + ) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_REGULAR_FILE, + _("Target file is not a regular file")); + goto error; + } + } + + if (etag != NULL) + { + GLocalFileStat etag_stat; + GLocalFileStat *etag_stat_pointer; + + /* The ETag is calculated on the details of the target file, for symlinks, + * so we might need to stat() again. */ + if (is_symlink) + { + res = g_local_file_stat (filename, + G_LOCAL_FILE_STAT_FIELD_MTIME, + G_LOCAL_FILE_STAT_FIELD_ALL, &etag_stat); + errsv = errno; + + if (res != 0) + { + char *display_name = g_filename_display_name (filename); + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error when getting information for file “%sâ€: %s"), + display_name, g_strerror (errsv)); + g_free (display_name); + goto error; + } + + etag_stat_pointer = &etag_stat; + } + else + etag_stat_pointer = &original_stat; + + /* Compare the ETags */ + current_etag = _g_local_file_info_create_etag (etag_stat_pointer); + if (strcmp (etag, current_etag) != 0) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_WRONG_ETAG, + _("The file was externally modified")); + g_free (current_etag); + goto error; + } + g_free (current_etag); + } + + /* We use two backup strategies. + * The first one (which is faster) consist in saving to a + * tmp file then rename the original file to the backup and the + * tmp file to the original name. This is fast but doesn't work + * when the file is a link (hard or symbolic) or when we can't + * write to the current dir or can't set the permissions on the + * new file. + * The second strategy consist simply in copying the old file + * to a backup file and rewrite the contents of the file. + */ + + if (replace_destination_set || + (!(_g_stat_nlink (&original_stat) > 1) && !is_symlink)) + { + char *dirname, *tmp_filename; + int tmpfd; + + dirname = g_path_get_dirname (filename); + tmp_filename = g_build_filename (dirname, ".goutputstream-XXXXXX", NULL); + g_free (dirname); + + tmpfd = g_mkstemp_full (tmp_filename, (readable ? O_RDWR : O_WRONLY) | O_BINARY, mode); + if (tmpfd == -1) + { + g_free (tmp_filename); + goto fallback_strategy; + } + + /* try to keep permissions (unless replacing) */ + + if (!replace_destination_set && + ( +#ifdef HAVE_FCHOWN + fchown (tmpfd, _g_stat_uid (&original_stat), _g_stat_gid (&original_stat)) == -1 || +#endif +#ifdef HAVE_FCHMOD + fchmod (tmpfd, _g_stat_mode (&original_stat) & ~S_IFMT) == -1 || +#endif + 0 + ) + ) + { + GLocalFileStat tmp_statbuf; + int tres; + + tres = g_local_file_fstat (tmpfd, + G_LOCAL_FILE_STAT_FIELD_TYPE | + G_LOCAL_FILE_STAT_FIELD_MODE | + G_LOCAL_FILE_STAT_FIELD_UID | + G_LOCAL_FILE_STAT_FIELD_GID, + G_LOCAL_FILE_STAT_FIELD_ALL, &tmp_statbuf); + + /* Check that we really needed to change something */ + if (tres != 0 || + _g_stat_uid (&original_stat) != _g_stat_uid (&tmp_statbuf) || + _g_stat_gid (&original_stat) != _g_stat_gid (&tmp_statbuf) || + _g_stat_mode (&original_stat) != _g_stat_mode (&tmp_statbuf)) + { + g_close (tmpfd, NULL); + g_unlink (tmp_filename); + g_free (tmp_filename); + goto fallback_strategy; + } + } + + if (fd >= 0) + g_close (fd, NULL); + *temp_filename = tmp_filename; + return tmpfd; + } + + fallback_strategy: + + if (create_backup) + { +#if defined(HAVE_FCHOWN) && defined(HAVE_FCHMOD) + GLocalFileStat tmp_statbuf; +#endif + char *backup_filename; + int bfd; + + backup_filename = create_backup_filename (filename); + + if (g_unlink (backup_filename) == -1 && errno != ENOENT) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Backup file creation failed")); + g_free (backup_filename); + goto error; + } + + bfd = g_open (backup_filename, + O_WRONLY | O_CREAT | O_EXCL | O_BINARY, + _g_stat_mode (&original_stat) & 0777); + + if (bfd == -1) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Backup file creation failed")); + g_free (backup_filename); + goto error; + } + + /* If needed, Try to set the group of the backup same as the + * original file. If this fails, set the protection + * bits for the group same as the protection bits for + * others. */ +#if defined(HAVE_FCHOWN) && defined(HAVE_FCHMOD) + if (g_local_file_fstat (bfd, G_LOCAL_FILE_STAT_FIELD_GID, G_LOCAL_FILE_STAT_FIELD_ALL, &tmp_statbuf) != 0) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Backup file creation failed")); + g_unlink (backup_filename); + g_close (bfd, NULL); + g_free (backup_filename); + goto error; + } + + if ((_g_stat_gid (&original_stat) != _g_stat_gid (&tmp_statbuf)) && + fchown (bfd, (uid_t) -1, _g_stat_gid (&original_stat)) != 0) + { + if (fchmod (bfd, + (_g_stat_mode (&original_stat) & 0707) | + ((_g_stat_mode (&original_stat) & 07) << 3)) != 0) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Backup file creation failed")); + g_unlink (backup_filename); + g_close (bfd, NULL); + g_free (backup_filename); + goto error; + } + } +#endif + + if (!copy_file_data (fd, bfd, NULL)) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_CANT_CREATE_BACKUP, + _("Backup file creation failed")); + g_unlink (backup_filename); + g_close (bfd, NULL); + g_free (backup_filename); + + goto error; + } + + g_close (bfd, NULL); + g_free (backup_filename); + + /* Seek back to the start of the file after the backup copy */ + if (lseek (fd, 0, SEEK_SET) == -1) + { + errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error seeking in file: %s"), + g_strerror (errsv)); + goto error; + } + } + + if (replace_destination_set) + { + g_close (fd, NULL); + + if (g_unlink (filename) != 0) + { + errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error removing old file: %s"), + g_strerror (errsv)); + goto error; + } + + if (readable) + open_flags = O_RDWR | O_CREAT | O_BINARY; + else + open_flags = O_WRONLY | O_CREAT | O_BINARY; + fd = g_open (filename, open_flags, mode); + if (fd == -1) + { + char *display_name; + errsv = errno; + display_name = g_filename_display_name (filename); + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error opening file “%sâ€: %s"), + display_name, g_strerror (errsv)); + g_free (display_name); + goto error; + } + } + else + { + /* Truncate the file at the start */ +#ifdef G_OS_WIN32 + if (g_win32_ftruncate (fd, 0) == -1) +#else + if (ftruncate (fd, 0) == -1) +#endif + { + errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error truncating file: %s"), + g_strerror (errsv)); + goto error; + } + } + + return fd; + +error: + if (fd >= 0) + g_close (fd, NULL); + + return -1; +} + +GFileOutputStream * +_g_local_file_output_stream_replace (const char *filename, + gboolean readable, + const char *etag, + gboolean create_backup, + GFileCreateFlags flags, + GFileInfo *reference_info, + GCancellable *cancellable, + GError **error) +{ + GLocalFileOutputStream *stream; + int mode; + int fd; + char *temp_file; + gboolean sync_on_close; + int open_flags; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + temp_file = NULL; + + mode = mode_from_flags_or_info (flags, reference_info); + sync_on_close = FALSE; + + /* If the file doesn't exist, create it */ + open_flags = O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC; + if (readable) + open_flags |= O_RDWR; + else + open_flags |= O_WRONLY; + fd = g_open (filename, open_flags, mode); + + if (fd == -1 && errno == EEXIST) + { + /* The file already exists */ + fd = handle_overwrite_open (filename, readable, etag, + create_backup, &temp_file, + flags, reference_info, + cancellable, error); + if (fd == -1) + return NULL; + + /* If the final destination exists, we want to sync the newly written + * file to ensure the data is on disk when we rename over the destination. + * otherwise if we get a system crash we can lose both the new and the + * old file on some filesystems. (I.E. those that don't guarantee the + * data is written to the disk before the metadata.) + */ + sync_on_close = TRUE; + } + else if (fd == -1) + { + set_error_from_open_errno (filename, error); + return NULL; + } +#if !defined(HAVE_O_CLOEXEC) && defined(F_SETFD) + else + fcntl (fd, F_SETFD, FD_CLOEXEC); +#endif + + stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL); + stream->priv->fd = fd; + stream->priv->sync_on_close = sync_on_close; + stream->priv->tmp_filename = temp_file; + if (create_backup) + stream->priv->backup_filename = create_backup_filename (filename); + stream->priv->original_filename = g_strdup (filename); + + return G_FILE_OUTPUT_STREAM (stream); +} + +gint +_g_local_file_output_stream_get_fd (GLocalFileOutputStream *stream) +{ + g_return_val_if_fail (G_IS_LOCAL_FILE_OUTPUT_STREAM (stream), -1); + return stream->priv->fd; +} + +#ifdef G_OS_UNIX +static int +g_local_file_output_stream_get_fd (GFileDescriptorBased *fd_based) +{ + GLocalFileOutputStream *stream = G_LOCAL_FILE_OUTPUT_STREAM (fd_based); + return _g_local_file_output_stream_get_fd (stream); +} +#endif diff --git a/gio/glocalfileoutputstream.h b/gio/glocalfileoutputstream.h new file mode 100644 index 0000000..d530292 --- /dev/null +++ b/gio/glocalfileoutputstream.h @@ -0,0 +1,92 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOCAL_FILE_OUTPUT_STREAM_H__ +#define __G_LOCAL_FILE_OUTPUT_STREAM_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_LOCAL_FILE_OUTPUT_STREAM (_g_local_file_output_stream_get_type ()) +#define G_LOCAL_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_OUTPUT_STREAM, GLocalFileOutputStream)) +#define G_LOCAL_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE_OUTPUT_STREAM, GLocalFileOutputStreamClass)) +#define G_IS_LOCAL_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_OUTPUT_STREAM)) +#define G_IS_LOCAL_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_OUTPUT_STREAM)) +#define G_LOCAL_FILE_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE_OUTPUT_STREAM, GLocalFileOutputStreamClass)) + +typedef struct _GLocalFileOutputStream GLocalFileOutputStream; +typedef struct _GLocalFileOutputStreamClass GLocalFileOutputStreamClass; +typedef struct _GLocalFileOutputStreamPrivate GLocalFileOutputStreamPrivate; + +struct _GLocalFileOutputStream +{ + GFileOutputStream parent_instance; + + /*< private >*/ + GLocalFileOutputStreamPrivate *priv; +}; + +struct _GLocalFileOutputStreamClass +{ + GFileOutputStreamClass parent_class; +}; + +GType _g_local_file_output_stream_get_type (void) G_GNUC_CONST; + +void _g_local_file_output_stream_set_do_close (GLocalFileOutputStream *out, + gboolean do_close); +gboolean _g_local_file_output_stream_really_close (GLocalFileOutputStream *out, + GCancellable *cancellable, + GError **error); + +GFileOutputStream * _g_local_file_output_stream_new (int fd); +GFileOutputStream * _g_local_file_output_stream_open (const char *filename, + gboolean readable, + GCancellable *cancellable, + GError **error); +GFileOutputStream * _g_local_file_output_stream_create (const char *filename, + gboolean readable, + GFileCreateFlags flags, + GFileInfo *reference_info, + GCancellable *cancellable, + GError **error); +GFileOutputStream * _g_local_file_output_stream_append (const char *filename, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error); +GFileOutputStream * _g_local_file_output_stream_replace (const char *filename, + gboolean readable, + const char *etag, + gboolean create_backup, + GFileCreateFlags flags, + GFileInfo *reference_info, + GCancellable *cancellable, + GError **error); + +/* Hack to get the fd since GFileDescriptorBased (which is how you + * _should_ get the fd) is only available on UNIX but things like + * win32 needs this as well + */ +gint _g_local_file_output_stream_get_fd (GLocalFileOutputStream *output_stream); + +G_END_DECLS + +#endif /* __G_LOCAL_FILE_OUTPUT_STREAM_H__ */ diff --git a/gio/glocalvfs.c b/gio/glocalvfs.c new file mode 100644 index 0000000..2dc0f2d --- /dev/null +++ b/gio/glocalvfs.c @@ -0,0 +1,227 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "glocalvfs.h" +#include "glocalfile.h" +#include "giomodule.h" +#include "giomodule-priv.h" +#include "gvfs.h" +#include +#include +#ifdef G_OS_UNIX +#include "glib-unix.h" +#include +#endif +#include + + +struct _GLocalVfs +{ + GVfs parent; +}; + +struct _GLocalVfsClass +{ + GVfsClass parent_class; + +}; + +#define g_local_vfs_get_type _g_local_vfs_get_type +G_DEFINE_TYPE_WITH_CODE (GLocalVfs, g_local_vfs, G_TYPE_VFS, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME, + g_define_type_id, + "local", + 0)) +static void +g_local_vfs_finalize (GObject *object) +{ + /* must chain up */ + G_OBJECT_CLASS (g_local_vfs_parent_class)->finalize (object); +} + +static void +g_local_vfs_init (GLocalVfs *vfs) +{ +} + +/** + * g_local_vfs_new: + * + * Returns a new #GVfs handle for a local vfs. + * + * Returns: a new #GVfs handle. + **/ +GVfs * +_g_local_vfs_new (void) +{ + return g_object_new (G_TYPE_LOCAL_VFS, NULL); +} + +static GFile * +g_local_vfs_get_file_for_path (GVfs *vfs, + const char *path) +{ + if (*path == '\0') + return _g_dummy_file_new (path); + else + return _g_local_file_new (path); +} + +static GFile * +g_local_vfs_get_file_for_uri (GVfs *vfs, + const char *uri) +{ + char *path; + GFile *file; + char *stripped_uri, *hash; + + if (strchr (uri, '#') != NULL) + { + stripped_uri = g_strdup (uri); + hash = strchr (stripped_uri, '#'); + *hash = 0; + } + else + stripped_uri = (char *)uri; + + path = g_filename_from_uri (stripped_uri, NULL, NULL); + + if (stripped_uri != uri) + g_free (stripped_uri); + + if (path != NULL) + file = _g_local_file_new (path); + else + file = _g_dummy_file_new (uri); + + g_free (path); + + return file; +} + +static const gchar * const * +g_local_vfs_get_supported_uri_schemes (GVfs *vfs) +{ + static const gchar * uri_schemes[] = { "file", NULL }; + + return uri_schemes; +} + +static GFile * +g_local_vfs_parse_name (GVfs *vfs, + const char *parse_name) +{ + GFile *file; + char *filename; + char *user_prefix; + const char *user_end; + char *rest; + + g_return_val_if_fail (G_IS_VFS (vfs), NULL); + g_return_val_if_fail (parse_name != NULL, NULL); + + if (g_ascii_strncasecmp ("file:", parse_name, 5) == 0) + filename = g_filename_from_uri (parse_name, NULL, NULL); + else + { + if (*parse_name == '~') + { +#ifdef G_OS_UNIX + const char *user_start; + user_start = parse_name + 1; +#endif + parse_name ++; + + while (*parse_name != 0 && *parse_name != '/') + parse_name++; + + user_end = parse_name; + +#ifdef G_OS_UNIX + if (user_end == user_start) + user_prefix = g_strdup (g_get_home_dir ()); + else + { + struct passwd *passwd_file_entry; + char *user_name; + + user_name = g_strndup (user_start, user_end - user_start); + passwd_file_entry = g_unix_get_passwd_entry (user_name, NULL); + g_free (user_name); + + if (passwd_file_entry != NULL && + passwd_file_entry->pw_dir != NULL) + user_prefix = g_strdup (passwd_file_entry->pw_dir); + else + user_prefix = g_strdup (g_get_home_dir ()); + + g_free (passwd_file_entry); + } +#else + user_prefix = g_strdup (g_get_home_dir ()); +#endif + + rest = NULL; + if (*user_end != 0) + rest = g_filename_from_utf8 (user_end, -1, NULL, NULL, NULL); + + filename = g_build_filename (user_prefix, rest, NULL); + g_free (rest); + g_free (user_prefix); + } + else + filename = g_filename_from_utf8 (parse_name, -1, NULL, NULL, NULL); + } + + if (filename == NULL) + filename = g_strdup (parse_name); + + file = _g_local_file_new (filename); + g_free (filename); + + return file; +} + +static gboolean +g_local_vfs_is_active (GVfs *vfs) +{ + return TRUE; +} + +static void +g_local_vfs_class_init (GLocalVfsClass *class) +{ + GObjectClass *object_class; + GVfsClass *vfs_class; + + object_class = (GObjectClass *) class; + + object_class->finalize = g_local_vfs_finalize; + + vfs_class = G_VFS_CLASS (class); + + vfs_class->is_active = g_local_vfs_is_active; + vfs_class->get_file_for_path = g_local_vfs_get_file_for_path; + vfs_class->get_file_for_uri = g_local_vfs_get_file_for_uri; + vfs_class->get_supported_uri_schemes = g_local_vfs_get_supported_uri_schemes; + vfs_class->parse_name = g_local_vfs_parse_name; +} diff --git a/gio/glocalvfs.h b/gio/glocalvfs.h new file mode 100644 index 0000000..8d65049 --- /dev/null +++ b/gio/glocalvfs.h @@ -0,0 +1,44 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_LOCAL_VFS_H__ +#define __G_LOCAL_VFS_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_LOCAL_VFS (_g_local_vfs_get_type ()) +#define G_LOCAL_VFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_LOCAL_VFS, GLocalVfs)) +#define G_LOCAL_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_LOCAL_VFS, GLocalVfsClass)) +#define G_IS_LOCAL_VFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_LOCAL_VFS)) +#define G_IS_LOCAL_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_LOCAL_VFS)) +#define G_LOCAL_VFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_LOCAL_VFS, GLocalVfsClass)) + +typedef struct _GLocalVfs GLocalVfs; +typedef struct _GLocalVfsClass GLocalVfsClass; + +GType _g_local_vfs_get_type (void) G_GNUC_CONST; + +GVfs * _g_local_vfs_new (void); + +G_END_DECLS + +#endif /* __G_LOCAL_VFS_H__ */ diff --git a/gio/gmarshal-internal.c b/gio/gmarshal-internal.c new file mode 100644 index 0000000..f3f7800 --- /dev/null +++ b/gio/gmarshal-internal.c @@ -0,0 +1,2631 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include "gmarshal-internal.h" + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + +/* BOOLEAN:OBJECT */ +void +_g_cclosure_marshal_BOOLEAN__OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__OBJECT callback; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__OBJECT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_object (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +void +_g_cclosure_marshal_BOOLEAN__OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__OBJECT callback; + gboolean v_return; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + va_end (args_copy); + + g_return_if_fail (return_value != NULL); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__OBJECT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:OBJECT,FLAGS */ +void +_g_cclosure_marshal_BOOLEAN__OBJECT_FLAGS (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT_FLAGS) (gpointer data1, + gpointer arg1, + guint arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__OBJECT_FLAGS callback; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__OBJECT_FLAGS) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_flags (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +void +_g_cclosure_marshal_BOOLEAN__OBJECT_FLAGSv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT_FLAGS) (gpointer data1, + gpointer arg1, + guint arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__OBJECT_FLAGS callback; + gboolean v_return; + gpointer arg0; + guint arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + arg1 = (guint) va_arg (args_copy, guint); + va_end (args_copy); + + g_return_if_fail (return_value != NULL); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__OBJECT_FLAGS) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + arg1, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:OBJECT,OBJECT */ +void +_g_cclosure_marshal_BOOLEAN__OBJECT_OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT_OBJECT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__OBJECT_OBJECT callback; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +void +_g_cclosure_marshal_BOOLEAN__OBJECT_OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT_OBJECT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__OBJECT_OBJECT callback; + gboolean v_return; + gpointer arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if (arg1 != NULL) + arg1 = g_object_ref (arg1); + va_end (args_copy); + + g_return_if_fail (return_value != NULL); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + arg1, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + if (arg1 != NULL) + g_object_unref (arg1); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:POINTER,INT */ +void +_g_cclosure_marshal_BOOLEAN__POINTER_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_INT) (gpointer data1, + gpointer arg1, + gint arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__POINTER_INT callback; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__POINTER_INT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +void +_g_cclosure_marshal_BOOLEAN__POINTER_INTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_INT) (gpointer data1, + gpointer arg1, + gint arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__POINTER_INT callback; + gboolean v_return; + gpointer arg0; + gint arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + arg1 = (gint) va_arg (args_copy, gint); + va_end (args_copy); + + g_return_if_fail (return_value != NULL); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__POINTER_INT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + arg1, + data2); + + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:STRING */ +void +_g_cclosure_marshal_BOOLEAN__STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__STRING) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__STRING callback; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__STRING) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_string (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +void +_g_cclosure_marshal_BOOLEAN__STRINGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__STRING) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__STRING callback; + gboolean v_return; + gpointer arg0; + va_list args_copy; + + g_return_if_fail (return_value != NULL); + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__STRING) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:UINT */ +void +_g_cclosure_marshal_BOOLEAN__UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__UINT) (gpointer data1, + guint arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__UINT callback; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__UINT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_uint (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +void +_g_cclosure_marshal_BOOLEAN__UINTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__UINT) (gpointer data1, + guint arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__UINT callback; + gboolean v_return; + guint arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (guint) va_arg (args_copy, guint); + va_end (args_copy); + + g_return_if_fail (return_value != NULL); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__UINT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + data2); + + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:VOID */ +void +_g_cclosure_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__VOID callback; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 1); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + data2); + + g_value_set_boolean (return_value, v_return); +} + +void +_g_cclosure_marshal_BOOLEAN__VOIDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__VOID callback; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + data2); + + + g_value_set_boolean (return_value, v_return); +} + +/* INT:BOXED */ +void +_g_cclosure_marshal_INT__BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gint (*GMarshalFunc_INT__BOXED) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_INT__BOXED callback; + gint v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_INT__BOXED) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_boxed (param_values + 1), + data2); + + g_value_set_int (return_value, v_return); +} + +void +_g_cclosure_marshal_INT__BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gint (*GMarshalFunc_INT__BOXED) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_INT__BOXED callback; + gint v_return; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_boxed_copy (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg0); + va_end (args_copy); + + g_return_if_fail (return_value != NULL); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_INT__BOXED) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_boxed_free (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg0); + + g_value_set_int (return_value, v_return); +} + +/* INT:OBJECT */ +void +_g_cclosure_marshal_INT__OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gint (*GMarshalFunc_INT__OBJECT) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_INT__OBJECT callback; + gint v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_INT__OBJECT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_object (param_values + 1), + data2); + + g_value_set_int (return_value, v_return); +} + +void +_g_cclosure_marshal_INT__OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gint (*GMarshalFunc_INT__OBJECT) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_INT__OBJECT callback; + gint v_return; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + va_end (args_copy); + + g_return_if_fail (return_value != NULL); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_INT__OBJECT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + + g_value_set_int (return_value, v_return); +} + +/* VOID:BOOLEAN,BOXED */ +void +_g_cclosure_marshal_VOID__BOOLEAN_BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__BOOLEAN_BOXED) (gpointer data1, + gboolean arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__BOOLEAN_BOXED callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__BOOLEAN_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_boolean (param_values + 1), + g_marshal_value_peek_boxed (param_values + 2), + data2); +} + +void +_g_cclosure_marshal_VOID__BOOLEAN_BOXEDv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__BOOLEAN_BOXED) (gpointer data1, + gboolean arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__BOOLEAN_BOXED callback; + gboolean arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gboolean) va_arg (args_copy, gboolean); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_boxed_copy (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__BOOLEAN_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_boxed_free (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); +} + +/* VOID:ENUM,OBJECT */ +void +_g_cclosure_marshal_VOID__ENUM_OBJECT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__ENUM_OBJECT) (gpointer data1, + gint arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__ENUM_OBJECT callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__ENUM_OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_enum (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + data2); +} + +void +_g_cclosure_marshal_VOID__ENUM_OBJECTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__ENUM_OBJECT) (gpointer data1, + gint arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__ENUM_OBJECT callback; + gint arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gint) va_arg (args_copy, gint); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if (arg1 != NULL) + arg1 = g_object_ref (arg1); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__ENUM_OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); + if (arg1 != NULL) + g_object_unref (arg1); +} + +/* VOID:ENUM,OBJECT,OBJECT */ +void +_g_cclosure_marshal_VOID__ENUM_OBJECT_OBJECT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__ENUM_OBJECT_OBJECT) (gpointer data1, + gint arg1, + gpointer arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__ENUM_OBJECT_OBJECT callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__ENUM_OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_enum (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + g_marshal_value_peek_object (param_values + 3), + data2); +} + +void +_g_cclosure_marshal_VOID__ENUM_OBJECT_OBJECTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__ENUM_OBJECT_OBJECT) (gpointer data1, + gint arg1, + gpointer arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__ENUM_OBJECT_OBJECT callback; + gint arg0; + gpointer arg1; + gpointer arg2; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gint) va_arg (args_copy, gint); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if (arg1 != NULL) + arg1 = g_object_ref (arg1); + arg2 = (gpointer) va_arg (args_copy, gpointer); + if (arg2 != NULL) + arg2 = g_object_ref (arg2); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__ENUM_OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + data2); + if (arg1 != NULL) + g_object_unref (arg1); + if (arg2 != NULL) + g_object_unref (arg2); +} + +/* VOID:INT,INT,INT */ +void +_g_cclosure_marshal_VOID__INT_INT_INT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INT_INT_INT) (gpointer data1, + gint arg1, + gint arg2, + gint arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__INT_INT_INT callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INT_INT_INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_int (param_values + 3), + data2); +} + +void +_g_cclosure_marshal_VOID__INT_INT_INTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__INT_INT_INT) (gpointer data1, + gint arg1, + gint arg2, + gint arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__INT_INT_INT callback; + gint arg0; + gint arg1; + gint arg2; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gint) va_arg (args_copy, gint); + arg1 = (gint) va_arg (args_copy, gint); + arg2 = (gint) va_arg (args_copy, gint); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INT_INT_INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + data2); + +} + +/* VOID:OBJECT,OBJECT */ +void +_g_cclosure_marshal_VOID__OBJECT_OBJECT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_OBJECT callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + data2); +} + +void +_g_cclosure_marshal_VOID__OBJECT_OBJECTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_OBJECT callback; + gpointer arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if (arg1 != NULL) + arg1 = g_object_ref (arg1); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + if (arg1 != NULL) + g_object_unref (arg1); +} + +/* VOID:OBJECT,OBJECT,ENUM */ +void +_g_cclosure_marshal_VOID__OBJECT_OBJECT_ENUM (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT_ENUM) (gpointer data1, + gpointer arg1, + gpointer arg2, + gint arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_OBJECT_ENUM callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_OBJECT_ENUM) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + g_marshal_value_peek_enum (param_values + 3), + data2); +} + +void +_g_cclosure_marshal_VOID__OBJECT_OBJECT_ENUMv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT_ENUM) (gpointer data1, + gpointer arg1, + gpointer arg2, + gint arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_OBJECT_ENUM callback; + gpointer arg0; + gpointer arg1; + gint arg2; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if (arg1 != NULL) + arg1 = g_object_ref (arg1); + arg2 = (gint) va_arg (args_copy, gint); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_OBJECT_ENUM) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + if (arg1 != NULL) + g_object_unref (arg1); +} + +/* VOID:OBJECT,OBJECT,STRING,STRING,VARIANT */ +void +_g_cclosure_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer arg4, + gpointer arg5, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT callback; + + g_return_if_fail (n_param_values == 6); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + g_marshal_value_peek_string (param_values + 3), + g_marshal_value_peek_string (param_values + 4), + g_marshal_value_peek_variant (param_values + 5), + data2); +} + +void +_g_cclosure_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer arg4, + gpointer arg5, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT callback; + gpointer arg0; + gpointer arg1; + gpointer arg2; + gpointer arg3; + gpointer arg4; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if (arg1 != NULL) + arg1 = g_object_ref (arg1); + arg2 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + arg2 = g_strdup (arg2); + arg3 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[3] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg3 != NULL) + arg3 = g_strdup (arg3); + arg4 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[4] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg4 != NULL) + arg4 = g_variant_ref_sink (arg4); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + arg3, + arg4, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + if (arg1 != NULL) + g_object_unref (arg1); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + g_free (arg2); + if ((param_types[3] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg3 != NULL) + g_free (arg3); + if ((param_types[4] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg4 != NULL) + g_variant_unref (arg4); +} + +/* VOID:OBJECT,OBJECT,VARIANT,BOXED */ +void +_g_cclosure_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT_VARIANT_BOXED) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer arg4, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_OBJECT_VARIANT_BOXED callback; + + g_return_if_fail (n_param_values == 5); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_OBJECT_VARIANT_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + g_marshal_value_peek_variant (param_values + 3), + g_marshal_value_peek_boxed (param_values + 4), + data2); +} + +void +_g_cclosure_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXEDv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT_VARIANT_BOXED) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer arg4, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_OBJECT_VARIANT_BOXED callback; + gpointer arg0; + gpointer arg1; + gpointer arg2; + gpointer arg3; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if (arg1 != NULL) + arg1 = g_object_ref (arg1); + arg2 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + arg2 = g_variant_ref_sink (arg2); + arg3 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[3] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg3 != NULL) + arg3 = g_boxed_copy (param_types[3] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg3); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_OBJECT_VARIANT_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + arg3, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + if (arg1 != NULL) + g_object_unref (arg1); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + g_variant_unref (arg2); + if ((param_types[3] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg3 != NULL) + g_boxed_free (param_types[3] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg3); +} + +/* VOID:OBJECT,VARIANT */ +void +_g_cclosure_marshal_VOID__OBJECT_VARIANT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_VARIANT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_VARIANT callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_variant (param_values + 2), + data2); +} + +void +_g_cclosure_marshal_VOID__OBJECT_VARIANTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_VARIANT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT_VARIANT callback; + gpointer arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_variant_ref_sink (arg1); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT_VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_variant_unref (arg1); +} + +/* VOID:POINTER,INT,STRING */ +void +_g_cclosure_marshal_VOID__POINTER_INT_STRING (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER_INT_STRING) (gpointer data1, + gpointer arg1, + gint arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__POINTER_INT_STRING callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_INT_STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_string (param_values + 3), + data2); +} + +void +_g_cclosure_marshal_VOID__POINTER_INT_STRINGv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__POINTER_INT_STRING) (gpointer data1, + gpointer arg1, + gint arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__POINTER_INT_STRING callback; + gpointer arg0; + gint arg1; + gpointer arg2; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + arg1 = (gint) va_arg (args_copy, gint); + arg2 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + arg2 = g_strdup (arg2); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_INT_STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + data2); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + g_free (arg2); +} + +/* VOID:STRING,BOOLEAN */ +void +_g_cclosure_marshal_VOID__STRING_BOOLEAN (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOOLEAN) (gpointer data1, + gpointer arg1, + gboolean arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_BOOLEAN callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOOLEAN) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boolean (param_values + 2), + data2); +} + +void +_g_cclosure_marshal_VOID__STRING_BOOLEANv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOOLEAN) (gpointer data1, + gpointer arg1, + gboolean arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_BOOLEAN callback; + gpointer arg0; + gboolean arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + arg1 = (gboolean) va_arg (args_copy, gboolean); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOOLEAN) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); +} + +/* VOID:STRING,BOXED */ +void +_g_cclosure_marshal_VOID__STRING_BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOXED) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_BOXED callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boxed (param_values + 2), + data2); +} + +void +_g_cclosure_marshal_VOID__STRING_BOXEDv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOXED) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_BOXED callback; + gpointer arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_boxed_copy (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_boxed_free (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); +} + +/* VOID:STRING,BOXED,BOXED */ +void +_g_cclosure_marshal_VOID__STRING_BOXED_BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOXED_BOXED) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_BOXED_BOXED callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOXED_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boxed (param_values + 2), + g_marshal_value_peek_boxed (param_values + 3), + data2); +} + +void +_g_cclosure_marshal_VOID__STRING_BOXED_BOXEDv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOXED_BOXED) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_BOXED_BOXED callback; + gpointer arg0; + gpointer arg1; + gpointer arg2; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_boxed_copy (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); + arg2 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + arg2 = g_boxed_copy (param_types[2] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg2); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOXED_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_boxed_free (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + g_boxed_free (param_types[2] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg2); +} + +/* VOID:STRING,INT64,INT64 */ +void +_g_cclosure_marshal_VOID__STRING_INT64_INT64 (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_INT64_INT64) (gpointer data1, + gpointer arg1, + gint64 arg2, + gint64 arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_INT64_INT64 callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_INT64_INT64) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_int64 (param_values + 2), + g_marshal_value_peek_int64 (param_values + 3), + data2); +} + +void +_g_cclosure_marshal_VOID__STRING_INT64_INT64v (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__STRING_INT64_INT64) (gpointer data1, + gpointer arg1, + gint64 arg2, + gint64 arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_INT64_INT64 callback; + gpointer arg0; + gint64 arg1; + gint64 arg2; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + arg1 = (gint64) va_arg (args_copy, gint64); + arg2 = (gint64) va_arg (args_copy, gint64); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_INT64_INT64) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); +} + +/* VOID:STRING,STRING,STRING,FLAGS */ +void +_g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGS (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING_FLAGS) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + guint arg4, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_STRING_STRING_FLAGS callback; + + g_return_if_fail (n_param_values == 5); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_STRING_STRING_FLAGS) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_string (param_values + 2), + g_marshal_value_peek_string (param_values + 3), + g_marshal_value_peek_flags (param_values + 4), + data2); +} + +void +_g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGSv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING_FLAGS) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + guint arg4, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_STRING_STRING_FLAGS callback; + gpointer arg0; + gpointer arg1; + gpointer arg2; + guint arg3; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_strdup (arg1); + arg2 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + arg2 = g_strdup (arg2); + arg3 = (guint) va_arg (args_copy, guint); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_STRING_STRING_FLAGS) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + arg3, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_free (arg1); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + g_free (arg2); +} + +/* VOID:STRING,STRING,VARIANT */ +void +_g_cclosure_marshal_VOID__STRING_STRING_VARIANT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_STRING_VARIANT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_STRING_VARIANT callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_STRING_VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_string (param_values + 2), + g_marshal_value_peek_variant (param_values + 3), + data2); +} + +void +_g_cclosure_marshal_VOID__STRING_STRING_VARIANTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__STRING_STRING_VARIANT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_STRING_VARIANT callback; + gpointer arg0; + gpointer arg1; + gpointer arg2; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_strdup (arg1); + arg2 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + arg2 = g_variant_ref_sink (arg2); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_STRING_VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_free (arg1); + if ((param_types[2] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg2 != NULL) + g_variant_unref (arg2); +} + +/* VOID:STRING,VARIANT */ +void +_g_cclosure_marshal_VOID__STRING_VARIANT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_VARIANT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_VARIANT callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_variant (param_values + 2), + data2); +} + +void +_g_cclosure_marshal_VOID__STRING_VARIANTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__STRING_VARIANT) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING_VARIANT callback; + gpointer arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_variant_ref_sink (arg1); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_variant_unref (arg1); +} + +/* VOID:UINT,UINT,UINT */ +void +_g_cclosure_marshal_VOID__UINT_UINT_UINT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__UINT_UINT_UINT) (gpointer data1, + guint arg1, + guint arg2, + guint arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__UINT_UINT_UINT callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UINT_UINT_UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_uint (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + g_marshal_value_peek_uint (param_values + 3), + data2); +} + +void +_g_cclosure_marshal_VOID__UINT_UINT_UINTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__UINT_UINT_UINT) (gpointer data1, + guint arg1, + guint arg2, + guint arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__UINT_UINT_UINT callback; + guint arg0; + guint arg1; + guint arg2; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (guint) va_arg (args_copy, guint); + arg1 = (guint) va_arg (args_copy, guint); + arg2 = (guint) va_arg (args_copy, guint); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UINT_UINT_UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + arg2, + data2); + +} + +/* VOID:VARIANT,BOXED */ +void +_g_cclosure_marshal_VOID__VARIANT_BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__VARIANT_BOXED) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__VARIANT_BOXED callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__VARIANT_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_variant (param_values + 1), + g_marshal_value_peek_boxed (param_values + 2), + data2); +} + +void +_g_cclosure_marshal_VOID__VARIANT_BOXEDv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__VARIANT_BOXED) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__VARIANT_BOXED callback; + gpointer arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_variant_ref_sink (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_boxed_copy (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__VARIANT_BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_variant_unref (arg0); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_boxed_free (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); +} diff --git a/gio/gmarshal-internal.h b/gio/gmarshal-internal.h new file mode 100644 index 0000000..ec5c3e8 --- /dev/null +++ b/gio/gmarshal-internal.h @@ -0,0 +1,503 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef ___G_CCLOSURE_MARSHAL_MARSHAL_H__ +#define ___G_CCLOSURE_MARSHAL_MARSHAL_H__ + +#include + +G_BEGIN_DECLS + +/* BOOLEAN:OBJECT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* BOOLEAN:OBJECT,FLAGS */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__OBJECT_FLAGS (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__OBJECT_FLAGSv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* BOOLEAN:OBJECT,OBJECT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* BOOLEAN:POINTER,INT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__POINTER_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__POINTER_INTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* BOOLEAN:STRING */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__STRINGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* BOOLEAN:UINT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__UINTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* BOOLEAN:VOID */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_BOOLEAN__VOIDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* INT:BOXED */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_INT__BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_INT__BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* INT:OBJECT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_INT__OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_INT__OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:BOOLEAN,BOXED */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__BOOLEAN_BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__BOOLEAN_BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:ENUM,OBJECT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__ENUM_OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__ENUM_OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:ENUM,OBJECT,OBJECT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__ENUM_OBJECT_OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__ENUM_OBJECT_OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:INT,INT,INT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__INT_INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__INT_INT_INTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:OBJECT,OBJECT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:OBJECT,OBJECT,ENUM */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_OBJECT_ENUM (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_OBJECT_ENUMv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:OBJECT,OBJECT,STRING,STRING,VARIANT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:OBJECT,OBJECT,VARIANT,BOXED */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:OBJECT,VARIANT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_VARIANT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__OBJECT_VARIANTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:POINTER,INT,STRING */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__POINTER_INT_STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__POINTER_INT_STRINGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:STRING,BOOLEAN */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_BOOLEAN (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_BOOLEANv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:STRING,BOXED */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:STRING,BOXED,BOXED */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_BOXED_BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_BOXED_BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:STRING,INT64,INT64 */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_INT64_INT64 (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_INT64_INT64v (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:STRING,STRING,STRING,FLAGS */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGS (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGSv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:STRING,STRING,VARIANT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_STRING_VARIANT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_STRING_VARIANTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:STRING,VARIANT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_VARIANT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__STRING_VARIANTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:UINT,UINT,UINT */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__UINT_UINT_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__UINT_UINT_UINTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:VARIANT,BOXED */ +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__VARIANT_BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +G_GNUC_INTERNAL +void _g_cclosure_marshal_VOID__VARIANT_BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + + +G_END_DECLS + +#endif /* ___G_CCLOSURE_MARSHAL_MARSHAL_H__ */ diff --git a/gio/gmarshal-internal.list b/gio/gmarshal-internal.list new file mode 100644 index 0000000..925ae42 --- /dev/null +++ b/gio/gmarshal-internal.list @@ -0,0 +1,28 @@ +BOOLEAN:OBJECT +BOOLEAN:OBJECT,FLAGS +BOOLEAN:OBJECT,OBJECT +BOOLEAN:POINTER,INT +BOOLEAN:STRING +BOOLEAN:UINT +BOOLEAN:VOID +INT:BOXED +INT:OBJECT +VOID:BOOLEAN,BOXED +VOID:ENUM,OBJECT +VOID:ENUM,OBJECT,OBJECT +VOID:INT,INT,INT +VOID:OBJECT,OBJECT +VOID:OBJECT,OBJECT,ENUM +VOID:OBJECT,OBJECT,STRING,STRING,VARIANT +VOID:OBJECT,OBJECT,VARIANT,BOXED +VOID:OBJECT,VARIANT +VOID:POINTER,INT,STRING +VOID:STRING,BOOLEAN +VOID:STRING,BOXED +VOID:STRING,BOXED,BOXED +VOID:STRING,INT64,INT64 +VOID:STRING,STRING,STRING,FLAGS +VOID:STRING,STRING,VARIANT +VOID:STRING,VARIANT +VOID:UINT,UINT,UINT +VOID:VARIANT,BOXED diff --git a/gio/gmemoryinputstream.c b/gio/gmemoryinputstream.c new file mode 100644 index 0000000..a9e855c --- /dev/null +++ b/gio/gmemoryinputstream.c @@ -0,0 +1,530 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#include "config.h" +#include "gmemoryinputstream.h" +#include "gpollableinputstream.h" +#include "ginputstream.h" +#include "gseekable.h" +#include "string.h" +#include "gtask.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gmemoryinputstream + * @short_description: Streaming input operations on memory chunks + * @include: gio/gio.h + * @see_also: #GMemoryOutputStream + * + * #GMemoryInputStream is a class for using arbitrary + * memory chunks as input for GIO streaming input operations. + * + * As of GLib 2.34, #GMemoryInputStream implements + * #GPollableInputStream. + */ + +struct _GMemoryInputStreamPrivate { + GSList *chunks; + gsize len; + gsize pos; +}; + +static gssize g_memory_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gssize g_memory_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_memory_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error); +static void g_memory_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellabl, + GAsyncReadyCallback callback, + gpointer datae); +static gssize g_memory_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); +static void g_memory_input_stream_close_async (GInputStream *stream, + int io_priority, + GCancellable *cancellabl, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_memory_input_stream_close_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); + +static void g_memory_input_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_memory_input_stream_tell (GSeekable *seekable); +static gboolean g_memory_input_stream_can_seek (GSeekable *seekable); +static gboolean g_memory_input_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_memory_input_stream_can_truncate (GSeekable *seekable); +static gboolean g_memory_input_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); + +static void g_memory_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface); +static gboolean g_memory_input_stream_is_readable (GPollableInputStream *stream); +static GSource *g_memory_input_stream_create_source (GPollableInputStream *stream, + GCancellable *cancellable); + +static void g_memory_input_stream_finalize (GObject *object); + +G_DEFINE_TYPE_WITH_CODE (GMemoryInputStream, g_memory_input_stream, G_TYPE_INPUT_STREAM, + G_ADD_PRIVATE (GMemoryInputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_memory_input_stream_seekable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, + g_memory_input_stream_pollable_iface_init); + ) + + +static void +g_memory_input_stream_class_init (GMemoryInputStreamClass *klass) +{ + GObjectClass *object_class; + GInputStreamClass *istream_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = g_memory_input_stream_finalize; + + istream_class = G_INPUT_STREAM_CLASS (klass); + istream_class->read_fn = g_memory_input_stream_read; + istream_class->skip = g_memory_input_stream_skip; + istream_class->close_fn = g_memory_input_stream_close; + + istream_class->skip_async = g_memory_input_stream_skip_async; + istream_class->skip_finish = g_memory_input_stream_skip_finish; + istream_class->close_async = g_memory_input_stream_close_async; + istream_class->close_finish = g_memory_input_stream_close_finish; +} + +static void +g_memory_input_stream_finalize (GObject *object) +{ + GMemoryInputStream *stream; + GMemoryInputStreamPrivate *priv; + + stream = G_MEMORY_INPUT_STREAM (object); + priv = stream->priv; + + g_slist_free_full (priv->chunks, (GDestroyNotify)g_bytes_unref); + + G_OBJECT_CLASS (g_memory_input_stream_parent_class)->finalize (object); +} + +static void +g_memory_input_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_memory_input_stream_tell; + iface->can_seek = g_memory_input_stream_can_seek; + iface->seek = g_memory_input_stream_seek; + iface->can_truncate = g_memory_input_stream_can_truncate; + iface->truncate_fn = g_memory_input_stream_truncate; +} + +static void +g_memory_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface) +{ + iface->is_readable = g_memory_input_stream_is_readable; + iface->create_source = g_memory_input_stream_create_source; +} + +static void +g_memory_input_stream_init (GMemoryInputStream *stream) +{ + stream->priv = g_memory_input_stream_get_instance_private (stream); +} + +/** + * g_memory_input_stream_new: + * + * Creates a new empty #GMemoryInputStream. + * + * Returns: a new #GInputStream + */ +GInputStream * +g_memory_input_stream_new (void) +{ + GInputStream *stream; + + stream = g_object_new (G_TYPE_MEMORY_INPUT_STREAM, NULL); + + return stream; +} + +/** + * g_memory_input_stream_new_from_data: + * @data: (array length=len) (element-type guint8) (transfer full): input data + * @len: length of the data, may be -1 if @data is a nul-terminated string + * @destroy: (nullable): function that is called to free @data, or %NULL + * + * Creates a new #GMemoryInputStream with data in memory of a given size. + * + * Returns: new #GInputStream read from @data of @len bytes. + **/ +GInputStream * +g_memory_input_stream_new_from_data (const void *data, + gssize len, + GDestroyNotify destroy) +{ + GInputStream *stream; + + stream = g_memory_input_stream_new (); + + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data, len, destroy); + + return stream; +} + +/** + * g_memory_input_stream_new_from_bytes: + * @bytes: a #GBytes + * + * Creates a new #GMemoryInputStream with data from the given @bytes. + * + * Returns: new #GInputStream read from @bytes + * + * Since: 2.34 + **/ +GInputStream * +g_memory_input_stream_new_from_bytes (GBytes *bytes) +{ + + GInputStream *stream; + + stream = g_memory_input_stream_new (); + + g_memory_input_stream_add_bytes (G_MEMORY_INPUT_STREAM (stream), + bytes); + + return stream; +} + +/** + * g_memory_input_stream_add_data: + * @stream: a #GMemoryInputStream + * @data: (array length=len) (element-type guint8) (transfer full): input data + * @len: length of the data, may be -1 if @data is a nul-terminated string + * @destroy: (nullable): function that is called to free @data, or %NULL + * + * Appends @data to data that can be read from the input stream + */ +void +g_memory_input_stream_add_data (GMemoryInputStream *stream, + const void *data, + gssize len, + GDestroyNotify destroy) +{ + GBytes *bytes; + + if (len == -1) + len = strlen (data); + + /* It's safe to discard the const here because we're chaining the + * destroy callback. + */ + bytes = g_bytes_new_with_free_func (data, len, destroy, (void*)data); + + g_memory_input_stream_add_bytes (stream, bytes); + + g_bytes_unref (bytes); +} + +/** + * g_memory_input_stream_add_bytes: + * @stream: a #GMemoryInputStream + * @bytes: input data + * + * Appends @bytes to data that can be read from the input stream. + * + * Since: 2.34 + */ +void +g_memory_input_stream_add_bytes (GMemoryInputStream *stream, + GBytes *bytes) +{ + GMemoryInputStreamPrivate *priv; + + g_return_if_fail (G_IS_MEMORY_INPUT_STREAM (stream)); + g_return_if_fail (bytes != NULL); + + priv = stream->priv; + + priv->chunks = g_slist_append (priv->chunks, g_bytes_ref (bytes)); + priv->len += g_bytes_get_size (bytes); +} + +static gssize +g_memory_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GMemoryInputStream *memory_stream; + GMemoryInputStreamPrivate *priv; + GSList *l; + GBytes *chunk; + gsize len; + gsize offset, start, rest, size; + + memory_stream = G_MEMORY_INPUT_STREAM (stream); + priv = memory_stream->priv; + + count = MIN (count, priv->len - priv->pos); + + offset = 0; + for (l = priv->chunks; l; l = l->next) + { + chunk = (GBytes *)l->data; + len = g_bytes_get_size (chunk); + + if (offset + len > priv->pos) + break; + + offset += len; + } + + start = priv->pos - offset; + rest = count; + + for (; l && rest > 0; l = l->next) + { + const guint8* chunk_data; + chunk = (GBytes *)l->data; + + chunk_data = g_bytes_get_data (chunk, &len); + + size = MIN (rest, len - start); + + memcpy ((guint8 *)buffer + (count - rest), chunk_data + start, size); + rest -= size; + + start = 0; + } + + priv->pos += count; + + return count; +} + +static gssize +g_memory_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GMemoryInputStream *memory_stream; + GMemoryInputStreamPrivate *priv; + + memory_stream = G_MEMORY_INPUT_STREAM (stream); + priv = memory_stream->priv; + + count = MIN (count, priv->len - priv->pos); + priv->pos += count; + + return count; +} + +static gboolean +g_memory_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + return TRUE; +} + +static void +g_memory_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + gssize nskipped; + GError *error = NULL; + + nskipped = G_INPUT_STREAM_GET_CLASS (stream)->skip (stream, count, cancellable, &error); + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_memory_input_stream_skip_async); + + if (error) + g_task_return_error (task, error); + else + g_task_return_int (task, nskipped); + g_object_unref (task); +} + +static gssize +g_memory_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), -1); + + return g_task_propagate_int (G_TASK (result), error); +} + +static void +g_memory_input_stream_close_async (GInputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_memory_input_stream_close_async); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static gboolean +g_memory_input_stream_close_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + return TRUE; +} + +static goffset +g_memory_input_stream_tell (GSeekable *seekable) +{ + GMemoryInputStream *memory_stream; + GMemoryInputStreamPrivate *priv; + + memory_stream = G_MEMORY_INPUT_STREAM (seekable); + priv = memory_stream->priv; + + return priv->pos; +} + +static +gboolean g_memory_input_stream_can_seek (GSeekable *seekable) +{ + return TRUE; +} + +static gboolean +g_memory_input_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GMemoryInputStream *memory_stream; + GMemoryInputStreamPrivate *priv; + goffset absolute; + + memory_stream = G_MEMORY_INPUT_STREAM (seekable); + priv = memory_stream->priv; + + switch (type) + { + case G_SEEK_CUR: + absolute = priv->pos + offset; + break; + + case G_SEEK_SET: + absolute = offset; + break; + + case G_SEEK_END: + absolute = priv->len + offset; + break; + + default: + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid GSeekType supplied")); + + return FALSE; + } + + if (absolute < 0 || (gsize) absolute > priv->len) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid seek request")); + return FALSE; + } + + priv->pos = absolute; + + return TRUE; +} + +static gboolean +g_memory_input_stream_can_truncate (GSeekable *seekable) +{ + return FALSE; +} + +static gboolean +g_memory_input_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Cannot truncate GMemoryInputStream")); + return FALSE; +} + +static gboolean +g_memory_input_stream_is_readable (GPollableInputStream *stream) +{ + return TRUE; +} + +static GSource * +g_memory_input_stream_create_source (GPollableInputStream *stream, + GCancellable *cancellable) +{ + GSource *base_source, *pollable_source; + + base_source = g_timeout_source_new (0); + pollable_source = g_pollable_source_new_full (stream, base_source, + cancellable); + g_source_unref (base_source); + + return pollable_source; +} diff --git a/gio/gmemoryinputstream.h b/gio/gmemoryinputstream.h new file mode 100644 index 0000000..7563fd6 --- /dev/null +++ b/gio/gmemoryinputstream.h @@ -0,0 +1,90 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#ifndef __G_MEMORY_INPUT_STREAM_H__ +#define __G_MEMORY_INPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_MEMORY_INPUT_STREAM (g_memory_input_stream_get_type ()) +#define G_MEMORY_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_MEMORY_INPUT_STREAM, GMemoryInputStream)) +#define G_MEMORY_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_MEMORY_INPUT_STREAM, GMemoryInputStreamClass)) +#define G_IS_MEMORY_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_MEMORY_INPUT_STREAM)) +#define G_IS_MEMORY_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_MEMORY_INPUT_STREAM)) +#define G_MEMORY_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_MEMORY_INPUT_STREAM, GMemoryInputStreamClass)) + +/** + * GMemoryInputStream: + * + * Implements #GInputStream for arbitrary memory chunks. + **/ +typedef struct _GMemoryInputStreamClass GMemoryInputStreamClass; +typedef struct _GMemoryInputStreamPrivate GMemoryInputStreamPrivate; + +struct _GMemoryInputStream +{ + GInputStream parent_instance; + + /*< private >*/ + GMemoryInputStreamPrivate *priv; +}; + +struct _GMemoryInputStreamClass +{ + GInputStreamClass parent_class; + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_memory_input_stream_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GInputStream * g_memory_input_stream_new (void); +GLIB_AVAILABLE_IN_ALL +GInputStream * g_memory_input_stream_new_from_data (const void *data, + gssize len, + GDestroyNotify destroy); +GLIB_AVAILABLE_IN_2_34 +GInputStream * g_memory_input_stream_new_from_bytes (GBytes *bytes); + +GLIB_AVAILABLE_IN_ALL +void g_memory_input_stream_add_data (GMemoryInputStream *stream, + const void *data, + gssize len, + GDestroyNotify destroy); +GLIB_AVAILABLE_IN_2_34 +void g_memory_input_stream_add_bytes (GMemoryInputStream *stream, + GBytes *bytes); + +G_END_DECLS + +#endif /* __G_MEMORY_INPUT_STREAM_H__ */ diff --git a/gio/gmemorymonitor.c b/gio/gmemorymonitor.c new file mode 100644 index 0000000..cef89f7 --- /dev/null +++ b/gio/gmemorymonitor.c @@ -0,0 +1,158 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" +#include "glibintl.h" + +#include "gmemorymonitor.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "ginitable.h" +#include "gioenumtypes.h" +#include "giomodule-priv.h" +#include "gtask.h" + +/** + * SECTION:gmemorymonitor + * @title: GMemoryMonitor + * @short_description: Memory usage monitor + * @include: gio/gio.h + * + * #GMemoryMonitor will monitor system memory and suggest to the application + * when to free memory so as to leave more room for other applications. + * It is implemented on Linux using the [Low Memory Monitor](https://gitlab.freedesktop.org/hadess/low-memory-monitor/) + * ([API documentation](https://hadess.pages.freedesktop.org/low-memory-monitor/)). + * + * There is also an implementation for use inside Flatpak sandboxes. + * + * Possible actions to take when the signal is received are: + * + * - Free caches + * - Save files that haven't been looked at in a while to disk, ready to be reopened when needed + * - Run a garbage collection cycle + * - Try and compress fragmented allocations + * - Exit on idle if the process has no reason to stay around + * - Call [`malloc_trim(3)`](man:malloc_trim) to return cached heap pages to + * the kernel (if supported by your libc) + * + * Note that some actions may not always improve system performance, and so + * should be profiled for your application. `malloc_trim()`, for example, may + * make future heap allocations slower (due to releasing cached heap pages back + * to the kernel). + * + * See #GMemoryMonitorWarningLevel for details on the various warning levels. + * + * |[ + * static void + * warning_cb (GMemoryMonitor *m, GMemoryMonitorWarningLevel level) + * { + * g_debug ("Warning level: %d", level); + * if (warning_level > G_MEMORY_MONITOR_WARNING_LEVEL_LOW) + * drop_caches (); + * } + * + * static GMemoryMonitor * + * monitor_low_memory (void) + * { + * GMemoryMonitor *m; + * m = g_memory_monitor_dup_default (); + * g_signal_connect (G_OBJECT (m), "low-memory-warning", + * G_CALLBACK (warning_cb), NULL); + * return m; + * } + * ]| + * + * Don't forget to disconnect the #GMemoryMonitor::low-memory-warning + * signal, and unref the #GMemoryMonitor itself when exiting. + * + * Since: 2.64 + */ + +/** + * GMemoryMonitor: + * + * #GMemoryMonitor monitors system memory and indicates when + * the system is low on memory. + * + * Since: 2.64 + */ + +/** + * GMemoryMonitorInterface: + * @g_iface: The parent interface. + * @low_memory_warning: the virtual function pointer for the + * #GMemoryMonitor::low-memory-warning signal. + * + * The virtual function table for #GMemoryMonitor. + * + * Since: 2.64 + */ + +G_DEFINE_INTERFACE_WITH_CODE (GMemoryMonitor, g_memory_monitor, G_TYPE_OBJECT, + g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE)) + +enum { + LOW_MEMORY_WARNING, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/** + * g_memory_monitor_dup_default: + * + * Gets a reference to the default #GMemoryMonitor for the system. + * + * Returns: (not nullable) (transfer full): a new reference to the default #GMemoryMonitor + * + * Since: 2.64 + */ +GMemoryMonitor * +g_memory_monitor_dup_default (void) +{ + return g_object_ref (_g_io_module_get_default (G_MEMORY_MONITOR_EXTENSION_POINT_NAME, + "GIO_USE_MEMORY_MONITOR", + NULL)); +} + +static void +g_memory_monitor_default_init (GMemoryMonitorInterface *iface) +{ + /** + * GMemoryMonitor::low-memory-warning: + * @monitor: a #GMemoryMonitor + * @level: the #GMemoryMonitorWarningLevel warning level + * + * Emitted when the system is running low on free memory. The signal + * handler should then take the appropriate action depending on the + * warning level. See the #GMemoryMonitorWarningLevel documentation for + * details. + * + * Since: 2.64 + */ + signals[LOW_MEMORY_WARNING] = + g_signal_new (I_("low-memory-warning"), + G_TYPE_MEMORY_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMemoryMonitorInterface, low_memory_warning), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_MEMORY_MONITOR_WARNING_LEVEL); +} diff --git a/gio/gmemorymonitor.h b/gio/gmemorymonitor.h new file mode 100644 index 0000000..a3ad216 --- /dev/null +++ b/gio/gmemorymonitor.h @@ -0,0 +1,62 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_MEMORY_MONITOR_H__ +#define __G_MEMORY_MONITOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_MEMORY_MONITOR_EXTENSION_POINT_NAME: + * + * Extension point for memory usage monitoring functionality. + * See [Extending GIO][extending-gio]. + * + * Since: 2.64 + */ +#define G_MEMORY_MONITOR_EXTENSION_POINT_NAME "gio-memory-monitor" + +#define G_TYPE_MEMORY_MONITOR (g_memory_monitor_get_type ()) +GLIB_AVAILABLE_IN_2_64 +G_DECLARE_INTERFACE(GMemoryMonitor, g_memory_monitor, g, memory_monitor, GObject) + +#define G_MEMORY_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_MEMORY_MONITOR, GMemoryMonitor)) +#define G_IS_MEMORY_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_MEMORY_MONITOR)) +#define G_MEMORY_MONITOR_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_MEMORY_MONITOR, GMemoryMonitorInterface)) + +struct _GMemoryMonitorInterface { + /*< private >*/ + GTypeInterface g_iface; + + /*< public >*/ + void (*low_memory_warning) (GMemoryMonitor *monitor, + GMemoryMonitorWarningLevel level); +}; + +GLIB_AVAILABLE_IN_2_64 +GMemoryMonitor *g_memory_monitor_dup_default (void); + +G_END_DECLS + +#endif /* __G_MEMORY_MONITOR_H__ */ diff --git a/gio/gmemorymonitordbus.c b/gio/gmemorymonitordbus.c new file mode 100644 index 0000000..739b832 --- /dev/null +++ b/gio/gmemorymonitordbus.c @@ -0,0 +1,185 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gmemorymonitor.h" +#include "gmemorymonitordbus.h" +#include "gioerror.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "glibintl.h" +#include "glib/gstdio.h" +#include "gcancellable.h" +#include "gdbusproxy.h" +#include "gdbusnamewatching.h" + +#define G_MEMORY_MONITOR_DBUS_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + +static void g_memory_monitor_dbus_iface_init (GMemoryMonitorInterface *iface); +static void g_memory_monitor_dbus_initable_iface_init (GInitableIface *iface); + +struct _GMemoryMonitorDBus +{ + GObject parent_instance; + + guint watch_id; + GCancellable *cancellable; + GDBusProxy *proxy; + gulong signal_id; +}; + +G_DEFINE_TYPE_WITH_CODE (GMemoryMonitorDBus, g_memory_monitor_dbus, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_memory_monitor_dbus_initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_MEMORY_MONITOR, + g_memory_monitor_dbus_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_MEMORY_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "dbus", + 30)) + +static void +g_memory_monitor_dbus_init (GMemoryMonitorDBus *dbus) +{ +} + +static void +proxy_signal_cb (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + GMemoryMonitorDBus *dbus) +{ + guint8 level; + + if (g_strcmp0 (signal_name, "LowMemoryWarning") != 0) + return; + if (parameters == NULL) + return; + + g_variant_get (parameters, "(y)", &level); + g_signal_emit_by_name (dbus, "low-memory-warning", level); +} + +static void +lmm_proxy_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GMemoryMonitorDBus *dbus = user_data; + GDBusProxy *proxy; + GError *error = NULL; + + proxy = g_dbus_proxy_new_finish (res, &error); + if (!proxy) + { + g_debug ("Failed to create LowMemoryMonitor D-Bus proxy: %s", + error->message); + g_error_free (error); + return; + } + + dbus->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal", + G_CALLBACK (proxy_signal_cb), dbus); + dbus->proxy = proxy; + +} + +static void +lmm_appeared_cb (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + GMemoryMonitorDBus *dbus = user_data; + + g_dbus_proxy_new (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "org.freedesktop.LowMemoryMonitor", + "/org/freedesktop/LowMemoryMonitor", + "org.freedesktop.LowMemoryMonitor", + dbus->cancellable, + lmm_proxy_cb, + dbus); +} + +static void +lmm_vanished_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GMemoryMonitorDBus *dbus = user_data; + + g_clear_signal_handler (&dbus->signal_id, dbus->proxy); + g_clear_object (&dbus->proxy); +} + +static gboolean +g_memory_monitor_dbus_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (initable); + + dbus->cancellable = g_cancellable_new (); + dbus->watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, + "org.freedesktop.LowMemoryMonitor", + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + lmm_appeared_cb, + lmm_vanished_cb, + dbus, + NULL); + + return TRUE; +} + +static void +g_memory_monitor_dbus_finalize (GObject *object) +{ + GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (object); + + g_cancellable_cancel (dbus->cancellable); + g_clear_object (&dbus->cancellable); + g_clear_signal_handler (&dbus->signal_id, dbus->proxy); + g_clear_object (&dbus->proxy); + g_clear_handle_id (&dbus->watch_id, g_bus_unwatch_name); + + G_OBJECT_CLASS (g_memory_monitor_dbus_parent_class)->finalize (object); +} + +static void +g_memory_monitor_dbus_class_init (GMemoryMonitorDBusClass *nl_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); + + gobject_class->finalize = g_memory_monitor_dbus_finalize; +} + +static void +g_memory_monitor_dbus_iface_init (GMemoryMonitorInterface *monitor_iface) +{ +} + +static void +g_memory_monitor_dbus_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_memory_monitor_dbus_initable_init; +} diff --git a/gio/gmemorymonitordbus.h b/gio/gmemorymonitordbus.h new file mode 100644 index 0000000..e48e755 --- /dev/null +++ b/gio/gmemorymonitordbus.h @@ -0,0 +1,31 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_MEMORY_MONITOR_DBUS_H__ +#define __G_MEMORY_MONITOR_DBUS_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_MEMORY_MONITOR_DBUS (g_memory_monitor_dbus_get_type ()) +G_DECLARE_FINAL_TYPE (GMemoryMonitorDBus, g_memory_monitor_dbus, G, MEMORY_MONITOR_DBUS, GObject) + +G_END_DECLS + +#endif /* __G_MEMORY_MONITOR_DBUS_H__ */ diff --git a/gio/gmemorymonitorportal.c b/gio/gmemorymonitorportal.c new file mode 100644 index 0000000..440629f --- /dev/null +++ b/gio/gmemorymonitorportal.c @@ -0,0 +1,152 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gmemorymonitor.h" +#include "gmemorymonitorportal.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "xdp-dbus.h" +#include "gportalsupport.h" + +#define G_MEMORY_MONITOR_PORTAL_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + +static void g_memory_monitor_portal_iface_init (GMemoryMonitorInterface *iface); +static void g_memory_monitor_portal_initable_iface_init (GInitableIface *iface); + +struct _GMemoryMonitorPortal +{ + GObject parent_instance; + + GDBusProxy *proxy; + gulong signal_id; +}; + +G_DEFINE_TYPE_WITH_CODE (GMemoryMonitorPortal, g_memory_monitor_portal, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_memory_monitor_portal_initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_MEMORY_MONITOR, + g_memory_monitor_portal_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_MEMORY_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "portal", + 40)) + +static void +g_memory_monitor_portal_init (GMemoryMonitorPortal *portal) +{ +} + +static void +proxy_signal (GDBusProxy *proxy, + const char *sender, + const char *signal, + GVariant *parameters, + GMemoryMonitorPortal *portal) +{ + guint8 level; + + if (strcmp (signal, "LowMemoryWarning") != 0) + return; + if (!parameters) + return; + + g_variant_get (parameters, "(y)", &level); + g_signal_emit_by_name (portal, "low-memory-warning", level); +} + +static gboolean +g_memory_monitor_portal_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GMemoryMonitorPortal *portal = G_MEMORY_MONITOR_PORTAL (initable); + GDBusProxy *proxy; + gchar *name_owner = NULL; + + if (!glib_should_use_portal ()) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not using portals"); + return FALSE; + } + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.MemoryMonitor", + cancellable, + error); + if (!proxy) + return FALSE; + + name_owner = g_dbus_proxy_get_name_owner (proxy); + + if (name_owner == NULL) + { + g_object_unref (proxy); + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_NAME_HAS_NO_OWNER, + "Desktop portal not found"); + return FALSE; + } + + g_free (name_owner); + + portal->signal_id = g_signal_connect (proxy, "g-signal", + G_CALLBACK (proxy_signal), portal); + + portal->proxy = proxy; + + return TRUE; +} + +static void +g_memory_monitor_portal_finalize (GObject *object) +{ + GMemoryMonitorPortal *portal = G_MEMORY_MONITOR_PORTAL (object); + + if (portal->proxy != NULL) + g_clear_signal_handler (&portal->signal_id, portal->proxy); + g_clear_object (&portal->proxy); + + G_OBJECT_CLASS (g_memory_monitor_portal_parent_class)->finalize (object); +} + +static void +g_memory_monitor_portal_class_init (GMemoryMonitorPortalClass *nl_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); + + gobject_class->finalize = g_memory_monitor_portal_finalize; +} + +static void +g_memory_monitor_portal_iface_init (GMemoryMonitorInterface *monitor_iface) +{ +} + +static void +g_memory_monitor_portal_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_memory_monitor_portal_initable_init; +} diff --git a/gio/gmemorymonitorportal.h b/gio/gmemorymonitorportal.h new file mode 100644 index 0000000..57074b4 --- /dev/null +++ b/gio/gmemorymonitorportal.h @@ -0,0 +1,31 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_MEMORY_MONITOR_PORTAL_H__ +#define __G_MEMORY_MONITOR_PORTAL_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_MEMORY_MONITOR_PORTAL (g_memory_monitor_portal_get_type ()) +G_DECLARE_FINAL_TYPE (GMemoryMonitorPortal, g_memory_monitor_portal, G, MEMORY_MONITOR_PORTAL, GObject) + +G_END_DECLS + +#endif /* __G_MEMORY_MONITOR_PORTAL_H__ */ diff --git a/gio/gmemorymonitorwin32.c b/gio/gmemorymonitorwin32.c new file mode 100644 index 0000000..c0e09a5 --- /dev/null +++ b/gio/gmemorymonitorwin32.c @@ -0,0 +1,261 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2022 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gmemorymonitor.h" +#include "gioerror.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "glibintl.h" +#include "glib/gstdio.h" +#include "gcancellable.h" + +#include + +#define G_TYPE_MEMORY_MONITOR_WIN32 (g_memory_monitor_win32_get_type ()) +G_DECLARE_FINAL_TYPE (GMemoryMonitorWin32, g_memory_monitor_win32, G, MEMORY_MONITOR_WIN32, GObject) + +#define G_MEMORY_MONITOR_WIN32_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + +static void g_memory_monitor_win32_iface_init (GMemoryMonitorInterface *iface); +static void g_memory_monitor_win32_initable_iface_init (GInitableIface *iface); + +struct _GMemoryMonitorWin32 +{ + GObject parent_instance; + + HANDLE event; + HANDLE mem; + HANDLE thread; +}; + +G_DEFINE_TYPE_WITH_CODE (GMemoryMonitorWin32, g_memory_monitor_win32, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_memory_monitor_win32_initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_MEMORY_MONITOR, + g_memory_monitor_win32_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_MEMORY_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "win32", + 30)) + +static void +g_memory_monitor_win32_init (GMemoryMonitorWin32 *win32) +{ +} + +static gboolean +watch_handler (gpointer user_data) +{ + GMemoryMonitorWin32 *win32 = user_data; + + g_signal_emit_by_name (win32, "low-memory-warning", + G_MEMORY_MONITOR_WARNING_LEVEL_LOW); + + return G_SOURCE_REMOVE; +} + +/* Thread which watches for win32 memory resource events */ +static DWORD WINAPI +watch_thread_function (LPVOID parameter) +{ + GWeakRef *weak_ref = parameter; + GMemoryMonitorWin32 *win32 = NULL; + HANDLE handles[2] = { 0, }; + DWORD result; + BOOL low_memory_state; + + win32 = g_weak_ref_get (weak_ref); + if (!win32) + goto end; + + if (!DuplicateHandle (GetCurrentProcess (), + win32->event, + GetCurrentProcess (), + &handles[0], + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) + { + gchar *emsg; + + emsg = g_win32_error_message (GetLastError ()); + g_debug ("DuplicateHandle failed: %s", emsg); + g_free (emsg); + goto end; + } + + if (!DuplicateHandle (GetCurrentProcess (), + win32->mem, + GetCurrentProcess (), + &handles[1], + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) + { + gchar *emsg; + + emsg = g_win32_error_message (GetLastError ()); + g_debug ("DuplicateHandle failed: %s", emsg); + g_free (emsg); + goto end; + } + + g_clear_object (&win32); + + while (1) + { + if (!QueryMemoryResourceNotification (handles[1], &low_memory_state)) + { + gchar *emsg; + + emsg = g_win32_error_message (GetLastError ()); + g_debug ("QueryMemoryResourceNotification failed: %s", emsg); + g_free (emsg); + break; + } + + win32 = g_weak_ref_get (weak_ref); + if (!win32) + break; + + if (low_memory_state) + { + g_idle_add_full (G_PRIORITY_DEFAULT, + watch_handler, + g_steal_pointer (&win32), + g_object_unref); + /* throttle a bit the loop */ + g_usleep (G_USEC_PER_SEC); + continue; + } + + g_clear_object (&win32); + + result = WaitForMultipleObjects (G_N_ELEMENTS (handles), handles, FALSE, INFINITE); + switch (result) + { + case WAIT_OBJECT_0 + 1: + continue; + + case WAIT_FAILED: + { + gchar *emsg; + + emsg = g_win32_error_message (GetLastError ()); + g_debug ("WaitForMultipleObjects failed: %s", emsg); + g_free (emsg); + } + G_GNUC_FALLTHROUGH; + default: + goto end; + } + } + +end: + if (handles[0]) + CloseHandle (handles[0]); + if (handles[1]) + CloseHandle (handles[1]); + g_clear_object (&win32); + g_weak_ref_clear (weak_ref); + g_free (weak_ref); + return 0; +} + +static gboolean +g_memory_monitor_win32_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GMemoryMonitorWin32 *win32 = G_MEMORY_MONITOR_WIN32 (initable); + GWeakRef *weak_ref = NULL; + + win32->event = CreateEvent (NULL, FALSE, FALSE, NULL); + if (win32->event == NULL) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to create event"); + return FALSE; + } + + win32->mem = CreateMemoryResourceNotification (LowMemoryResourceNotification); + if (win32->mem == NULL) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to create resource notification handle"); + return FALSE; + } + + weak_ref = g_new0 (GWeakRef, 1); + g_weak_ref_init (weak_ref, win32); + /* Use CreateThread (not GThread) with a small stack to make it more lightweight. */ + win32->thread = CreateThread (NULL, 1024, watch_thread_function, weak_ref, 0, NULL); + if (win32->thread == NULL) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to create memory resource notification thread"); + g_weak_ref_clear (weak_ref); + g_free (weak_ref); + return FALSE; + } + + return TRUE; +} + +static void +g_memory_monitor_win32_finalize (GObject *object) +{ + GMemoryMonitorWin32 *win32 = G_MEMORY_MONITOR_WIN32 (object); + + if (win32->thread) + { + SetEvent (win32->event); + WaitForSingleObject (win32->thread, INFINITE); + CloseHandle (win32->thread); + } + + if (win32->event) + CloseHandle (win32->event); + + if (win32->mem) + CloseHandle (win32->mem); + + G_OBJECT_CLASS (g_memory_monitor_win32_parent_class)->finalize (object); +} + +static void +g_memory_monitor_win32_class_init (GMemoryMonitorWin32Class *nl_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); + + gobject_class->finalize = g_memory_monitor_win32_finalize; +} + +static void +g_memory_monitor_win32_iface_init (GMemoryMonitorInterface *monitor_iface) +{ +} + +static void +g_memory_monitor_win32_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_memory_monitor_win32_initable_init; +} diff --git a/gio/gmemoryoutputstream.c b/gio/gmemoryoutputstream.c new file mode 100644 index 0000000..6a410eb --- /dev/null +++ b/gio/gmemoryoutputstream.c @@ -0,0 +1,842 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: + * Christian Kellner + * Krzysztof KosiÅ„ski + */ + +#include "config.h" +#include "gmemoryoutputstream.h" +#include "goutputstream.h" +#include "gpollableoutputstream.h" +#include "gseekable.h" +#include "gtask.h" +#include "gioerror.h" +#include "string.h" +#include "glibintl.h" +#include "gutilsprivate.h" + + +/** + * SECTION:gmemoryoutputstream + * @short_description: Streaming output operations on memory chunks + * @include: gio/gio.h + * @see_also: #GMemoryInputStream + * + * #GMemoryOutputStream is a class for using arbitrary + * memory chunks as output for GIO streaming output operations. + * + * As of GLib 2.34, #GMemoryOutputStream trivially implements + * #GPollableOutputStream: it always polls as ready. + */ + +#define MIN_ARRAY_SIZE 16 + +enum { + PROP_0, + PROP_DATA, + PROP_SIZE, + PROP_DATA_SIZE, + PROP_REALLOC_FUNCTION, + PROP_DESTROY_FUNCTION +}; + +struct _GMemoryOutputStreamPrivate +{ + gpointer data; /* Write buffer */ + gsize len; /* Current length of the data buffer. Can change with resizing. */ + gsize valid_len; /* The part of data that has been written to */ + gsize pos; /* Current position in the stream. Distinct from valid_len, + because the stream is seekable. */ + + GReallocFunc realloc_fn; + GDestroyNotify destroy; +}; + +static void g_memory_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_memory_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void g_memory_output_stream_finalize (GObject *object); + +static gssize g_memory_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); + +static gboolean g_memory_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error); + +static void g_memory_output_stream_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_memory_output_stream_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); + +static void g_memory_output_stream_seekable_iface_init (GSeekableIface *iface); +static goffset g_memory_output_stream_tell (GSeekable *seekable); +static gboolean g_memory_output_stream_can_seek (GSeekable *seekable); +static gboolean g_memory_output_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static gboolean g_memory_output_stream_can_truncate (GSeekable *seekable); +static gboolean g_memory_output_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); + +static gboolean g_memory_output_stream_is_writable (GPollableOutputStream *stream); +static GSource *g_memory_output_stream_create_source (GPollableOutputStream *stream, + GCancellable *cancellable); + +static void g_memory_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GMemoryOutputStream, g_memory_output_stream, G_TYPE_OUTPUT_STREAM, + G_ADD_PRIVATE (GMemoryOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, + g_memory_output_stream_seekable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, + g_memory_output_stream_pollable_iface_init)) + + +static void +g_memory_output_stream_class_init (GMemoryOutputStreamClass *klass) +{ + GOutputStreamClass *ostream_class; + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->set_property = g_memory_output_stream_set_property; + gobject_class->get_property = g_memory_output_stream_get_property; + gobject_class->finalize = g_memory_output_stream_finalize; + + ostream_class = G_OUTPUT_STREAM_CLASS (klass); + + ostream_class->write_fn = g_memory_output_stream_write; + ostream_class->close_fn = g_memory_output_stream_close; + ostream_class->close_async = g_memory_output_stream_close_async; + ostream_class->close_finish = g_memory_output_stream_close_finish; + + /** + * GMemoryOutputStream:data: + * + * Pointer to buffer where data will be written. + * + * Since: 2.24 + **/ + g_object_class_install_property (gobject_class, + PROP_DATA, + g_param_spec_pointer ("data", + P_("Data Buffer"), + P_("Pointer to buffer where data will be written."), + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GMemoryOutputStream:size: + * + * Current size of the data buffer. + * + * Since: 2.24 + **/ + g_object_class_install_property (gobject_class, + PROP_SIZE, + g_param_spec_ulong ("size", + P_("Data Buffer Size"), + P_("Current size of the data buffer."), + 0, G_MAXULONG, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GMemoryOutputStream:data-size: + * + * Size of data written to the buffer. + * + * Since: 2.24 + **/ + g_object_class_install_property (gobject_class, + PROP_DATA_SIZE, + g_param_spec_ulong ("data-size", + P_("Data Size"), + P_("Size of data written to the buffer."), + 0, G_MAXULONG, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GMemoryOutputStream:realloc-function: (skip) + * + * Function with realloc semantics called to enlarge the buffer. + * + * Since: 2.24 + **/ + g_object_class_install_property (gobject_class, + PROP_REALLOC_FUNCTION, + g_param_spec_pointer ("realloc-function", + P_("Memory Reallocation Function"), + P_("Function with realloc semantics called to enlarge the buffer."), + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GMemoryOutputStream:destroy-function: (skip) + * + * Function called with the buffer as argument when the stream is destroyed. + * + * Since: 2.24 + **/ + g_object_class_install_property (gobject_class, + PROP_DESTROY_FUNCTION, + g_param_spec_pointer ("destroy-function", + P_("Destroy Notification Function"), + P_("Function called with the buffer as argument when the stream is destroyed."), + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_memory_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface) +{ + iface->is_writable = g_memory_output_stream_is_writable; + iface->create_source = g_memory_output_stream_create_source; +} + +static void +g_memory_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GMemoryOutputStream *stream; + GMemoryOutputStreamPrivate *priv; + + stream = G_MEMORY_OUTPUT_STREAM (object); + priv = stream->priv; + + switch (prop_id) + { + case PROP_DATA: + priv->data = g_value_get_pointer (value); + break; + case PROP_SIZE: + priv->len = g_value_get_ulong (value); + break; + case PROP_REALLOC_FUNCTION: + priv->realloc_fn = g_value_get_pointer (value); + break; + case PROP_DESTROY_FUNCTION: + priv->destroy = g_value_get_pointer (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_memory_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GMemoryOutputStream *stream; + GMemoryOutputStreamPrivate *priv; + + stream = G_MEMORY_OUTPUT_STREAM (object); + priv = stream->priv; + + switch (prop_id) + { + case PROP_DATA: + g_value_set_pointer (value, priv->data); + break; + case PROP_SIZE: + g_value_set_ulong (value, priv->len); + break; + case PROP_DATA_SIZE: + g_value_set_ulong (value, priv->valid_len); + break; + case PROP_REALLOC_FUNCTION: + g_value_set_pointer (value, priv->realloc_fn); + break; + case PROP_DESTROY_FUNCTION: + g_value_set_pointer (value, priv->destroy); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_memory_output_stream_finalize (GObject *object) +{ + GMemoryOutputStream *stream; + GMemoryOutputStreamPrivate *priv; + + stream = G_MEMORY_OUTPUT_STREAM (object); + priv = stream->priv; + + if (priv->destroy) + priv->destroy (priv->data); + + G_OBJECT_CLASS (g_memory_output_stream_parent_class)->finalize (object); +} + +static void +g_memory_output_stream_seekable_iface_init (GSeekableIface *iface) +{ + iface->tell = g_memory_output_stream_tell; + iface->can_seek = g_memory_output_stream_can_seek; + iface->seek = g_memory_output_stream_seek; + iface->can_truncate = g_memory_output_stream_can_truncate; + iface->truncate_fn = g_memory_output_stream_truncate; +} + + +static void +g_memory_output_stream_init (GMemoryOutputStream *stream) +{ + stream->priv = g_memory_output_stream_get_instance_private (stream); + stream->priv->pos = 0; + stream->priv->valid_len = 0; +} + +/** + * g_memory_output_stream_new: (skip) + * @data: (nullable): pointer to a chunk of memory to use, or %NULL + * @size: the size of @data + * @realloc_function: (nullable): a function with realloc() semantics (like g_realloc()) + * to be called when @data needs to be grown, or %NULL + * @destroy_function: (nullable): a function to be called on @data when the stream is + * finalized, or %NULL + * + * Creates a new #GMemoryOutputStream. + * + * In most cases this is not the function you want. See + * g_memory_output_stream_new_resizable() instead. + * + * If @data is non-%NULL, the stream will use that for its internal storage. + * + * If @realloc_fn is non-%NULL, it will be used for resizing the internal + * storage when necessary and the stream will be considered resizable. + * In that case, the stream will start out being (conceptually) empty. + * @size is used only as a hint for how big @data is. Specifically, + * seeking to the end of a newly-created stream will seek to zero, not + * @size. Seeking past the end of the stream and then writing will + * introduce a zero-filled gap. + * + * If @realloc_fn is %NULL then the stream is fixed-sized. Seeking to + * the end will seek to @size exactly. Writing past the end will give + * an 'out of space' error. Attempting to seek past the end will fail. + * Unlike the resizable case, seeking to an offset within the stream and + * writing will preserve the bytes passed in as @data before that point + * and will return them as part of g_memory_output_stream_steal_data(). + * If you intend to seek you should probably therefore ensure that @data + * is properly initialised. + * + * It is probably only meaningful to provide @data and @size in the case + * that you want a fixed-sized stream. Put another way: if @realloc_fn + * is non-%NULL then it makes most sense to give @data as %NULL and + * @size as 0 (allowing #GMemoryOutputStream to do the initial + * allocation for itself). + * + * |[ + * // a stream that can grow + * stream = g_memory_output_stream_new (NULL, 0, realloc, free); + * + * // another stream that can grow + * stream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + * + * // a fixed-size stream + * data = malloc (200); + * stream3 = g_memory_output_stream_new (data, 200, NULL, free); + * ]| + * + * Returns: A newly created #GMemoryOutputStream object. + **/ +GOutputStream * +g_memory_output_stream_new (gpointer data, + gsize size, + GReallocFunc realloc_function, + GDestroyNotify destroy_function) +{ + GOutputStream *stream; + + stream = g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM, + "data", data, + "size", size, + "realloc-function", realloc_function, + "destroy-function", destroy_function, + NULL); + + return stream; +} + +/** + * g_memory_output_stream_new_resizable: + * + * Creates a new #GMemoryOutputStream, using g_realloc() and g_free() + * for memory allocation. + * + * Since: 2.36 + */ +GOutputStream * +g_memory_output_stream_new_resizable (void) +{ + return g_memory_output_stream_new (NULL, 0, g_realloc, g_free); +} + +/** + * g_memory_output_stream_get_data: + * @ostream: a #GMemoryOutputStream + * + * Gets any loaded data from the @ostream. + * + * Note that the returned pointer may become invalid on the next + * write or truncate operation on the stream. + * + * Returns: (transfer none): pointer to the stream's data, or %NULL if the data + * has been stolen + **/ +gpointer +g_memory_output_stream_get_data (GMemoryOutputStream *ostream) +{ + g_return_val_if_fail (G_IS_MEMORY_OUTPUT_STREAM (ostream), NULL); + + return ostream->priv->data; +} + +/** + * g_memory_output_stream_get_size: + * @ostream: a #GMemoryOutputStream + * + * Gets the size of the currently allocated data area (available from + * g_memory_output_stream_get_data()). + * + * You probably don't want to use this function on resizable streams. + * See g_memory_output_stream_get_data_size() instead. For resizable + * streams the size returned by this function is an implementation + * detail and may be change at any time in response to operations on the + * stream. + * + * If the stream is fixed-sized (ie: no realloc was passed to + * g_memory_output_stream_new()) then this is the maximum size of the + * stream and further writes will return %G_IO_ERROR_NO_SPACE. + * + * In any case, if you want the number of bytes currently written to the + * stream, use g_memory_output_stream_get_data_size(). + * + * Returns: the number of bytes allocated for the data buffer + */ +gsize +g_memory_output_stream_get_size (GMemoryOutputStream *ostream) +{ + g_return_val_if_fail (G_IS_MEMORY_OUTPUT_STREAM (ostream), 0); + + return ostream->priv->len; +} + +/** + * g_memory_output_stream_get_data_size: + * @ostream: a #GMemoryOutputStream + * + * Returns the number of bytes from the start up to including the last + * byte written in the stream that has not been truncated away. + * + * Returns: the number of bytes written to the stream + * + * Since: 2.18 + */ +gsize +g_memory_output_stream_get_data_size (GMemoryOutputStream *ostream) +{ + g_return_val_if_fail (G_IS_MEMORY_OUTPUT_STREAM (ostream), 0); + + return ostream->priv->valid_len; +} + +/** + * g_memory_output_stream_steal_data: + * @ostream: a #GMemoryOutputStream + * + * Gets any loaded data from the @ostream. Ownership of the data + * is transferred to the caller; when no longer needed it must be + * freed using the free function set in @ostream's + * #GMemoryOutputStream:destroy-function property. + * + * @ostream must be closed before calling this function. + * + * Returns: (transfer full): the stream's data, or %NULL if it has previously + * been stolen + * + * Since: 2.26 + **/ +gpointer +g_memory_output_stream_steal_data (GMemoryOutputStream *ostream) +{ + gpointer data; + + g_return_val_if_fail (G_IS_MEMORY_OUTPUT_STREAM (ostream), NULL); + g_return_val_if_fail (g_output_stream_is_closed (G_OUTPUT_STREAM (ostream)), NULL); + + data = ostream->priv->data; + ostream->priv->data = NULL; + + return data; +} + +/** + * g_memory_output_stream_steal_as_bytes: + * @ostream: a #GMemoryOutputStream + * + * Returns data from the @ostream as a #GBytes. @ostream must be + * closed before calling this function. + * + * Returns: (transfer full): the stream's data + * + * Since: 2.34 + **/ +GBytes * +g_memory_output_stream_steal_as_bytes (GMemoryOutputStream *ostream) +{ + GBytes *result; + + g_return_val_if_fail (G_IS_MEMORY_OUTPUT_STREAM (ostream), NULL); + g_return_val_if_fail (g_output_stream_is_closed (G_OUTPUT_STREAM (ostream)), NULL); + + result = g_bytes_new_with_free_func (ostream->priv->data, + ostream->priv->valid_len, + ostream->priv->destroy, + ostream->priv->data); + ostream->priv->data = NULL; + + return result; +} + +static gboolean +array_resize (GMemoryOutputStream *ostream, + gsize size, + gboolean allow_partial, + GError **error) +{ + GMemoryOutputStreamPrivate *priv; + gpointer data; + gsize len; + + priv = ostream->priv; + + if (priv->len == size) + return TRUE; + + if (!priv->realloc_fn) + { + if (allow_partial && + priv->pos < priv->len) + return TRUE; /* Short write */ + + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NO_SPACE, + _("Memory output stream not resizable")); + return FALSE; + } + + len = priv->len; + data = priv->realloc_fn (priv->data, size); + + if (size > 0 && !data) + { + if (allow_partial && + priv->pos < priv->len) + return TRUE; /* Short write */ + + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NO_SPACE, + _("Failed to resize memory output stream")); + return FALSE; + } + + if (size > len) + memset ((guint8 *)data + len, 0, size - len); + + priv->data = data; + priv->len = size; + + if (priv->len < priv->valid_len) + priv->valid_len = priv->len; + + return TRUE; +} + +static gssize +g_memory_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GMemoryOutputStream *ostream; + GMemoryOutputStreamPrivate *priv; + guint8 *dest; + gsize new_size; + + ostream = G_MEMORY_OUTPUT_STREAM (stream); + priv = ostream->priv; + + if (count == 0) + return 0; + + /* Check for address space overflow, but only if the buffer is resizable. + Otherwise we just do a short write and don't worry. */ + if (priv->realloc_fn && priv->pos + count < priv->pos) + goto overflow; + + if (priv->pos + count > priv->len) + { + /* At least enough to fit the write, rounded up for greater than + * linear growth. + * + * Assuming that we're using something like realloc(), the kernel + * will overcommit memory to us, so doubling the size each time + * will keep the number of realloc calls low without wasting too + * much memory. + */ + new_size = g_nearest_pow (priv->pos + count); + /* Check for overflow again. We have checked if + pos + count > G_MAXSIZE, but now check if g_nearest_pow () has + overflowed */ + if (new_size == 0) + goto overflow; + + new_size = MAX (new_size, MIN_ARRAY_SIZE); + if (!array_resize (ostream, new_size, TRUE, error)) + return -1; + } + + /* Make sure we handle short writes if the array_resize + only added part of the required memory */ + count = MIN (count, priv->len - priv->pos); + + dest = (guint8 *)priv->data + priv->pos; + memcpy (dest, buffer, count); + priv->pos += count; + + if (priv->pos > priv->valid_len) + priv->valid_len = priv->pos; + + return count; + + overflow: + /* Overflow: buffer size would need to be bigger than G_MAXSIZE. */ + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NO_SPACE, + _("Amount of memory required to process the write is " + "larger than available address space")); + return -1; +} + +static gboolean +g_memory_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + return TRUE; +} + +static void +g_memory_output_stream_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, data); + g_task_set_source_tag (task, g_memory_output_stream_close_async); + + /* will always return TRUE */ + g_memory_output_stream_close (stream, cancellable, NULL); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static gboolean +g_memory_output_stream_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static goffset +g_memory_output_stream_tell (GSeekable *seekable) +{ + GMemoryOutputStream *stream; + GMemoryOutputStreamPrivate *priv; + + stream = G_MEMORY_OUTPUT_STREAM (seekable); + priv = stream->priv; + + return priv->pos; +} + +static gboolean +g_memory_output_stream_can_seek (GSeekable *seekable) +{ + return TRUE; +} + +static gboolean +g_memory_output_stream_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GMemoryOutputStream *stream; + GMemoryOutputStreamPrivate *priv; + goffset absolute; + + stream = G_MEMORY_OUTPUT_STREAM (seekable); + priv = stream->priv; + + switch (type) + { + case G_SEEK_CUR: + absolute = priv->pos + offset; + break; + + case G_SEEK_SET: + absolute = offset; + break; + + case G_SEEK_END: + /* For resizable streams, we consider the end to be the data + * length. For fixed-sized streams, we consider the end to be the + * size of the buffer. + */ + if (priv->realloc_fn) + absolute = priv->valid_len + offset; + else + absolute = priv->len + offset; + break; + + default: + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid GSeekType supplied")); + + return FALSE; + } + + if (absolute < 0) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Requested seek before the beginning of the stream")); + return FALSE; + } + + /* Can't seek past the end of a fixed-size stream. + * + * Note: seeking to the non-existent byte at the end of a fixed-sized + * stream is valid (eg: a 1-byte fixed sized stream can have position + * 0 or 1). Therefore '>' is what we want. + * */ + if (priv->realloc_fn == NULL && (gsize) absolute > priv->len) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Requested seek beyond the end of the stream")); + return FALSE; + } + + priv->pos = absolute; + + return TRUE; +} + +static gboolean +g_memory_output_stream_can_truncate (GSeekable *seekable) +{ + GMemoryOutputStream *ostream; + GMemoryOutputStreamPrivate *priv; + + ostream = G_MEMORY_OUTPUT_STREAM (seekable); + priv = ostream->priv; + + /* We do not allow truncation of fixed-sized streams */ + return priv->realloc_fn != NULL; +} + +static gboolean +g_memory_output_stream_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error) +{ + GMemoryOutputStream *ostream = G_MEMORY_OUTPUT_STREAM (seekable); + + if (!array_resize (ostream, offset, FALSE, error)) + return FALSE; + + ostream->priv->valid_len = offset; + + return TRUE; +} + +static gboolean +g_memory_output_stream_is_writable (GPollableOutputStream *stream) +{ + return TRUE; +} + +static GSource * +g_memory_output_stream_create_source (GPollableOutputStream *stream, + GCancellable *cancellable) +{ + GSource *base_source, *pollable_source; + + base_source = g_timeout_source_new (0); + pollable_source = g_pollable_source_new_full (stream, base_source, cancellable); + g_source_unref (base_source); + + return pollable_source; +} diff --git a/gio/gmemoryoutputstream.h b/gio/gmemoryoutputstream.h new file mode 100644 index 0000000..5418d23 --- /dev/null +++ b/gio/gmemoryoutputstream.h @@ -0,0 +1,107 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Christian Kellner + */ + +#ifndef __G_MEMORY_OUTPUT_STREAM_H__ +#define __G_MEMORY_OUTPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_MEMORY_OUTPUT_STREAM (g_memory_output_stream_get_type ()) +#define G_MEMORY_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_MEMORY_OUTPUT_STREAM, GMemoryOutputStream)) +#define G_MEMORY_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_MEMORY_OUTPUT_STREAM, GMemoryOutputStreamClass)) +#define G_IS_MEMORY_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_MEMORY_OUTPUT_STREAM)) +#define G_IS_MEMORY_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_MEMORY_OUTPUT_STREAM)) +#define G_MEMORY_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_MEMORY_OUTPUT_STREAM, GMemoryOutputStreamClass)) + +/** + * GMemoryOutputStream: + * + * Implements #GOutputStream for arbitrary memory chunks. + **/ +typedef struct _GMemoryOutputStreamClass GMemoryOutputStreamClass; +typedef struct _GMemoryOutputStreamPrivate GMemoryOutputStreamPrivate; + +struct _GMemoryOutputStream +{ + GOutputStream parent_instance; + + /*< private >*/ + GMemoryOutputStreamPrivate *priv; +}; + +struct _GMemoryOutputStreamClass +{ + GOutputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +/** + * GReallocFunc: + * @data: memory block to reallocate + * @size: size to reallocate @data to + * + * Changes the size of the memory block pointed to by @data to + * @size bytes. + * + * The function should have the same semantics as realloc(). + * + * Returns: a pointer to the reallocated memory + */ +typedef gpointer (* GReallocFunc) (gpointer data, + gsize size); + +GLIB_AVAILABLE_IN_ALL +GType g_memory_output_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GOutputStream *g_memory_output_stream_new (gpointer data, + gsize size, + GReallocFunc realloc_function, + GDestroyNotify destroy_function); +GLIB_AVAILABLE_IN_2_36 +GOutputStream *g_memory_output_stream_new_resizable (void); +GLIB_AVAILABLE_IN_ALL +gpointer g_memory_output_stream_get_data (GMemoryOutputStream *ostream); +GLIB_AVAILABLE_IN_ALL +gsize g_memory_output_stream_get_size (GMemoryOutputStream *ostream); +GLIB_AVAILABLE_IN_ALL +gsize g_memory_output_stream_get_data_size (GMemoryOutputStream *ostream); +GLIB_AVAILABLE_IN_ALL +gpointer g_memory_output_stream_steal_data (GMemoryOutputStream *ostream); + +GLIB_AVAILABLE_IN_2_34 +GBytes * g_memory_output_stream_steal_as_bytes (GMemoryOutputStream *ostream); + +G_END_DECLS + +#endif /* __G_MEMORY_OUTPUT_STREAM_H__ */ diff --git a/gio/gmemorysettingsbackend.c b/gio/gmemorysettingsbackend.c new file mode 100644 index 0000000..8f8297a --- /dev/null +++ b/gio/gmemorysettingsbackend.c @@ -0,0 +1,193 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gsimplepermission.h" +#include "gsettingsbackendinternal.h" +#include "giomodule-priv.h" + + +#define G_TYPE_MEMORY_SETTINGS_BACKEND (g_memory_settings_backend_get_type()) +#define G_MEMORY_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_MEMORY_SETTINGS_BACKEND, \ + GMemorySettingsBackend)) + +typedef GSettingsBackendClass GMemorySettingsBackendClass; +typedef struct +{ + GSettingsBackend parent_instance; + GHashTable *table; +} GMemorySettingsBackend; + +G_DEFINE_TYPE_WITH_CODE (GMemorySettingsBackend, + g_memory_settings_backend, + G_TYPE_SETTINGS_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "memory", 10)) + +static GVariant * +g_memory_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value) +{ + GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend); + GVariant *value; + + if (default_value) + return NULL; + + value = g_hash_table_lookup (memory->table, key); + + if (value != NULL) + g_variant_ref (value); + + return value; +} + +static gboolean +g_memory_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag) +{ + GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend); + GVariant *old_value; + + old_value = g_hash_table_lookup (memory->table, key); + g_variant_ref_sink (value); + + if (old_value == NULL || !g_variant_equal (value, old_value)) + { + g_hash_table_insert (memory->table, g_strdup (key), value); + g_settings_backend_changed (backend, key, origin_tag); + } + else + g_variant_unref (value); + + return TRUE; +} + +static gboolean +g_memory_settings_backend_write_one (gpointer key, + gpointer value, + gpointer data) +{ + GMemorySettingsBackend *memory = data; + + if (value != NULL) + g_hash_table_insert (memory->table, g_strdup (key), g_variant_ref (value)); + else + g_hash_table_remove (memory->table, key); + + return FALSE; +} + +static gboolean +g_memory_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag) +{ + g_tree_foreach (tree, g_memory_settings_backend_write_one, backend); + g_settings_backend_changed_tree (backend, tree, origin_tag); + + return TRUE; +} + +static void +g_memory_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend); + + if (g_hash_table_lookup (memory->table, key)) + { + g_hash_table_remove (memory->table, key); + g_settings_backend_changed (backend, key, origin_tag); + } +} + +static gboolean +g_memory_settings_backend_get_writable (GSettingsBackend *backend, + const gchar *name) +{ + return TRUE; +} + +static GPermission * +g_memory_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path) +{ + return g_simple_permission_new (TRUE); +} + +static void +g_memory_settings_backend_finalize (GObject *object) +{ + GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (object); + + g_hash_table_unref (memory->table); + + G_OBJECT_CLASS (g_memory_settings_backend_parent_class) + ->finalize (object); +} + +static void +g_memory_settings_backend_init (GMemorySettingsBackend *memory) +{ + memory->table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify) g_variant_unref); +} + +static void +g_memory_settings_backend_class_init (GMemorySettingsBackendClass *class) +{ + GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (class); + + backend_class->read = g_memory_settings_backend_read; + backend_class->write = g_memory_settings_backend_write; + backend_class->write_tree = g_memory_settings_backend_write_tree; + backend_class->reset = g_memory_settings_backend_reset; + backend_class->get_writable = g_memory_settings_backend_get_writable; + backend_class->get_permission = g_memory_settings_backend_get_permission; + object_class->finalize = g_memory_settings_backend_finalize; +} + +/** + * g_memory_settings_backend_new: + * + * Creates a memory-backed #GSettingsBackend. + * + * This backend allows changes to settings, but does not write them + * to any backing storage, so the next time you run your application, + * the memory backend will start out with the default values again. + * + * Returns: (transfer full): a newly created #GSettingsBackend + * + * Since: 2.28 + */ +GSettingsBackend * +g_memory_settings_backend_new (void) +{ + return g_object_new (G_TYPE_MEMORY_SETTINGS_BACKEND, NULL); +} diff --git a/gio/gmenu.c b/gio/gmenu.c new file mode 100644 index 0000000..2c8c6c9 --- /dev/null +++ b/gio/gmenu.c @@ -0,0 +1,1388 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gmenu.h" + +#include "gaction.h" +#include + +#include "gicon.h" + +/** + * SECTION:gmenu + * @title: GMenu + * @short_description: A simple implementation of GMenuModel + * @include: gio/gio.h + * + * #GMenu is a simple implementation of #GMenuModel. + * You populate a #GMenu by adding #GMenuItem instances to it. + * + * There are some convenience functions to allow you to directly + * add items (avoiding #GMenuItem) for the common cases. To add + * a regular item, use g_menu_insert(). To add a section, use + * g_menu_insert_section(). To add a submenu, use + * g_menu_insert_submenu(). + */ + +/** + * GMenu: + * + * #GMenu is an opaque structure type. You must access it using the + * functions below. + * + * Since: 2.32 + */ + +/** + * GMenuItem: + * + * #GMenuItem is an opaque structure type. You must access it using the + * functions below. + * + * Since: 2.32 + */ + +struct _GMenuItem +{ + GObject parent_instance; + + GHashTable *attributes; + GHashTable *links; + gboolean cow; +}; + +typedef GObjectClass GMenuItemClass; + +struct _GMenu +{ + GMenuModel parent_instance; + + GArray *items; + gboolean mutable; +}; + +typedef GMenuModelClass GMenuClass; + +G_DEFINE_TYPE (GMenu, g_menu, G_TYPE_MENU_MODEL) +G_DEFINE_TYPE (GMenuItem, g_menu_item, G_TYPE_OBJECT) + +struct item +{ + GHashTable *attributes; + GHashTable *links; +}; + +static gboolean +g_menu_is_mutable (GMenuModel *model) +{ + GMenu *menu = G_MENU (model); + + return menu->mutable; +} + +static gint +g_menu_get_n_items (GMenuModel *model) +{ + GMenu *menu = G_MENU (model); + + return menu->items->len; +} + +static void +g_menu_get_item_attributes (GMenuModel *model, + gint position, + GHashTable **table) +{ + GMenu *menu = G_MENU (model); + + *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).attributes); +} + +static void +g_menu_get_item_links (GMenuModel *model, + gint position, + GHashTable **table) +{ + GMenu *menu = G_MENU (model); + + *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).links); +} + +/** + * g_menu_insert_item: + * @menu: a #GMenu + * @position: the position at which to insert the item + * @item: the #GMenuItem to insert + * + * Inserts @item into @menu. + * + * The "insertion" is actually done by copying all of the attribute and + * link values of @item and using them to form a new item within @menu. + * As such, @item itself is not really inserted, but rather, a menu item + * that is exactly the same as the one presently described by @item. + * + * This means that @item is essentially useless after the insertion + * occurs. Any changes you make to it are ignored unless it is inserted + * again (at which point its updated values will be copied). + * + * You should probably just free @item once you're done. + * + * There are many convenience functions to take care of common cases. + * See g_menu_insert(), g_menu_insert_section() and + * g_menu_insert_submenu() as well as "prepend" and "append" variants of + * each of these functions. + * + * Since: 2.32 + */ +void +g_menu_insert_item (GMenu *menu, + gint position, + GMenuItem *item) +{ + struct item new_item; + + g_return_if_fail (G_IS_MENU (menu)); + g_return_if_fail (G_IS_MENU_ITEM (item)); + + if (position < 0 || (guint) position > menu->items->len) + position = menu->items->len; + + new_item.attributes = g_hash_table_ref (item->attributes); + new_item.links = g_hash_table_ref (item->links); + item->cow = TRUE; + + g_array_insert_val (menu->items, position, new_item); + g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1); +} + +/** + * g_menu_prepend_item: + * @menu: a #GMenu + * @item: a #GMenuItem to prepend + * + * Prepends @item to the start of @menu. + * + * See g_menu_insert_item() for more information. + * + * Since: 2.32 + */ +void +g_menu_prepend_item (GMenu *menu, + GMenuItem *item) +{ + g_menu_insert_item (menu, 0, item); +} + +/** + * g_menu_append_item: + * @menu: a #GMenu + * @item: a #GMenuItem to append + * + * Appends @item to the end of @menu. + * + * See g_menu_insert_item() for more information. + * + * Since: 2.32 + */ +void +g_menu_append_item (GMenu *menu, + GMenuItem *item) +{ + g_menu_insert_item (menu, -1, item); +} + +/** + * g_menu_freeze: + * @menu: a #GMenu + * + * Marks @menu as frozen. + * + * After the menu is frozen, it is an error to attempt to make any + * changes to it. In effect this means that the #GMenu API must no + * longer be used. + * + * This function causes g_menu_model_is_mutable() to begin returning + * %FALSE, which has some positive performance implications. + * + * Since: 2.32 + */ +void +g_menu_freeze (GMenu *menu) +{ + g_return_if_fail (G_IS_MENU (menu)); + + menu->mutable = FALSE; +} + +/** + * g_menu_new: + * + * Creates a new #GMenu. + * + * The new menu has no items. + * + * Returns: a new #GMenu + * + * Since: 2.32 + */ +GMenu * +g_menu_new (void) +{ + return g_object_new (G_TYPE_MENU, NULL); +} + +/** + * g_menu_insert: + * @menu: a #GMenu + * @position: the position at which to insert the item + * @label: (nullable): the section label, or %NULL + * @detailed_action: (nullable): the detailed action string, or %NULL + * + * Convenience function for inserting a normal menu item into @menu. + * Combine g_menu_item_new() and g_menu_insert_item() for a more flexible + * alternative. + * + * Since: 2.32 + */ +void +g_menu_insert (GMenu *menu, + gint position, + const gchar *label, + const gchar *detailed_action) +{ + GMenuItem *menu_item; + + menu_item = g_menu_item_new (label, detailed_action); + g_menu_insert_item (menu, position, menu_item); + g_object_unref (menu_item); +} + +/** + * g_menu_prepend: + * @menu: a #GMenu + * @label: (nullable): the section label, or %NULL + * @detailed_action: (nullable): the detailed action string, or %NULL + * + * Convenience function for prepending a normal menu item to the start + * of @menu. Combine g_menu_item_new() and g_menu_insert_item() for a more + * flexible alternative. + * + * Since: 2.32 + */ +void +g_menu_prepend (GMenu *menu, + const gchar *label, + const gchar *detailed_action) +{ + g_menu_insert (menu, 0, label, detailed_action); +} + +/** + * g_menu_append: + * @menu: a #GMenu + * @label: (nullable): the section label, or %NULL + * @detailed_action: (nullable): the detailed action string, or %NULL + * + * Convenience function for appending a normal menu item to the end of + * @menu. Combine g_menu_item_new() and g_menu_insert_item() for a more + * flexible alternative. + * + * Since: 2.32 + */ +void +g_menu_append (GMenu *menu, + const gchar *label, + const gchar *detailed_action) +{ + g_menu_insert (menu, -1, label, detailed_action); +} + +/** + * g_menu_insert_section: + * @menu: a #GMenu + * @position: the position at which to insert the item + * @label: (nullable): the section label, or %NULL + * @section: a #GMenuModel with the items of the section + * + * Convenience function for inserting a section menu item into @menu. + * Combine g_menu_item_new_section() and g_menu_insert_item() for a more + * flexible alternative. + * + * Since: 2.32 + */ +void +g_menu_insert_section (GMenu *menu, + gint position, + const gchar *label, + GMenuModel *section) +{ + GMenuItem *menu_item; + + menu_item = g_menu_item_new_section (label, section); + g_menu_insert_item (menu, position, menu_item); + g_object_unref (menu_item); +} + + +/** + * g_menu_prepend_section: + * @menu: a #GMenu + * @label: (nullable): the section label, or %NULL + * @section: a #GMenuModel with the items of the section + * + * Convenience function for prepending a section menu item to the start + * of @menu. Combine g_menu_item_new_section() and g_menu_insert_item() for + * a more flexible alternative. + * + * Since: 2.32 + */ +void +g_menu_prepend_section (GMenu *menu, + const gchar *label, + GMenuModel *section) +{ + g_menu_insert_section (menu, 0, label, section); +} + +/** + * g_menu_append_section: + * @menu: a #GMenu + * @label: (nullable): the section label, or %NULL + * @section: a #GMenuModel with the items of the section + * + * Convenience function for appending a section menu item to the end of + * @menu. Combine g_menu_item_new_section() and g_menu_insert_item() for a + * more flexible alternative. + * + * Since: 2.32 + */ +void +g_menu_append_section (GMenu *menu, + const gchar *label, + GMenuModel *section) +{ + g_menu_insert_section (menu, -1, label, section); +} + +/** + * g_menu_insert_submenu: + * @menu: a #GMenu + * @position: the position at which to insert the item + * @label: (nullable): the section label, or %NULL + * @submenu: a #GMenuModel with the items of the submenu + * + * Convenience function for inserting a submenu menu item into @menu. + * Combine g_menu_item_new_submenu() and g_menu_insert_item() for a more + * flexible alternative. + * + * Since: 2.32 + */ +void +g_menu_insert_submenu (GMenu *menu, + gint position, + const gchar *label, + GMenuModel *submenu) +{ + GMenuItem *menu_item; + + menu_item = g_menu_item_new_submenu (label, submenu); + g_menu_insert_item (menu, position, menu_item); + g_object_unref (menu_item); +} + +/** + * g_menu_prepend_submenu: + * @menu: a #GMenu + * @label: (nullable): the section label, or %NULL + * @submenu: a #GMenuModel with the items of the submenu + * + * Convenience function for prepending a submenu menu item to the start + * of @menu. Combine g_menu_item_new_submenu() and g_menu_insert_item() for + * a more flexible alternative. + * + * Since: 2.32 + */ +void +g_menu_prepend_submenu (GMenu *menu, + const gchar *label, + GMenuModel *submenu) +{ + g_menu_insert_submenu (menu, 0, label, submenu); +} + +/** + * g_menu_append_submenu: + * @menu: a #GMenu + * @label: (nullable): the section label, or %NULL + * @submenu: a #GMenuModel with the items of the submenu + * + * Convenience function for appending a submenu menu item to the end of + * @menu. Combine g_menu_item_new_submenu() and g_menu_insert_item() for a + * more flexible alternative. + * + * Since: 2.32 + */ +void +g_menu_append_submenu (GMenu *menu, + const gchar *label, + GMenuModel *submenu) +{ + g_menu_insert_submenu (menu, -1, label, submenu); +} + +static void +g_menu_clear_item (struct item *item) +{ + if (item->attributes != NULL) + g_hash_table_unref (item->attributes); + if (item->links != NULL) + g_hash_table_unref (item->links); +} + +/** + * g_menu_remove: + * @menu: a #GMenu + * @position: the position of the item to remove + * + * Removes an item from the menu. + * + * @position gives the index of the item to remove. + * + * It is an error if position is not in range the range from 0 to one + * less than the number of items in the menu. + * + * It is not possible to remove items by identity since items are added + * to the menu simply by copying their links and attributes (ie: + * identity of the item itself is not preserved). + * + * Since: 2.32 + */ +void +g_menu_remove (GMenu *menu, + gint position) +{ + g_return_if_fail (G_IS_MENU (menu)); + g_return_if_fail (0 <= position && (guint) position < menu->items->len); + + g_menu_clear_item (&g_array_index (menu->items, struct item, position)); + g_array_remove_index (menu->items, position); + g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 0); +} + +/** + * g_menu_remove_all: + * @menu: a #GMenu + * + * Removes all items in the menu. + * + * Since: 2.38 + **/ +void +g_menu_remove_all (GMenu *menu) +{ + gint i, n; + + g_return_if_fail (G_IS_MENU (menu)); + n = menu->items->len; + + for (i = 0; i < n; i++) + g_menu_clear_item (&g_array_index (menu->items, struct item, i)); + g_array_set_size (menu->items, 0); + + g_menu_model_items_changed (G_MENU_MODEL (menu), 0, n, 0); +} + +static void +g_menu_finalize (GObject *object) +{ + GMenu *menu = G_MENU (object); + struct item *items; + gint n_items; + gint i; + + n_items = menu->items->len; + items = (struct item *) g_array_free (menu->items, FALSE); + for (i = 0; i < n_items; i++) + g_menu_clear_item (&items[i]); + g_free (items); + + G_OBJECT_CLASS (g_menu_parent_class) + ->finalize (object); +} + +static void +g_menu_init (GMenu *menu) +{ + menu->items = g_array_new (FALSE, FALSE, sizeof (struct item)); + menu->mutable = TRUE; +} + +static void +g_menu_class_init (GMenuClass *class) +{ + GMenuModelClass *model_class = G_MENU_MODEL_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_menu_finalize; + + model_class->is_mutable = g_menu_is_mutable; + model_class->get_n_items = g_menu_get_n_items; + model_class->get_item_attributes = g_menu_get_item_attributes; + model_class->get_item_links = g_menu_get_item_links; +} + + +static void +g_menu_item_clear_cow (GMenuItem *menu_item) +{ + if (menu_item->cow) + { + GHashTableIter iter; + GHashTable *new; + gpointer key; + gpointer val; + + new = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + g_hash_table_iter_init (&iter, menu_item->attributes); + while (g_hash_table_iter_next (&iter, &key, &val)) + g_hash_table_insert (new, g_strdup (key), g_variant_ref (val)); + g_hash_table_unref (menu_item->attributes); + menu_item->attributes = new; + + new = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); + g_hash_table_iter_init (&iter, menu_item->links); + while (g_hash_table_iter_next (&iter, &key, &val)) + g_hash_table_insert (new, g_strdup (key), g_object_ref (val)); + g_hash_table_unref (menu_item->links); + menu_item->links = new; + + menu_item->cow = FALSE; + } +} + +static void +g_menu_item_finalize (GObject *object) +{ + GMenuItem *menu_item = G_MENU_ITEM (object); + + g_hash_table_unref (menu_item->attributes); + g_hash_table_unref (menu_item->links); + + G_OBJECT_CLASS (g_menu_item_parent_class) + ->finalize (object); +} + +static void +g_menu_item_init (GMenuItem *menu_item) +{ + menu_item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + menu_item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + menu_item->cow = FALSE; +} + +static void +g_menu_item_class_init (GMenuItemClass *class) +{ + class->finalize = g_menu_item_finalize; +} + +/* We treat attribute names the same as GSettings keys: + * - only lowercase ascii, digits and '-' + * - must start with lowercase + * - must not end with '-' + * - no consecutive '-' + * - not longer than 1024 chars + */ +static gboolean +valid_attribute_name (const gchar *name) +{ + gint i; + + if (!g_ascii_islower (name[0])) + return FALSE; + + for (i = 1; name[i]; i++) + { + if (name[i] != '-' && + !g_ascii_islower (name[i]) && + !g_ascii_isdigit (name[i])) + return FALSE; + + if (name[i] == '-' && name[i + 1] == '-') + return FALSE; + } + + if (name[i - 1] == '-') + return FALSE; + + if (i > 1024) + return FALSE; + + return TRUE; +} + +/** + * g_menu_item_set_attribute_value: + * @menu_item: a #GMenuItem + * @attribute: the attribute to set + * @value: (nullable): a #GVariant to use as the value, or %NULL + * + * Sets or unsets an attribute on @menu_item. + * + * The attribute to set or unset is specified by @attribute. This + * can be one of the standard attribute names %G_MENU_ATTRIBUTE_LABEL, + * %G_MENU_ATTRIBUTE_ACTION, %G_MENU_ATTRIBUTE_TARGET, or a custom + * attribute name. + * Attribute names are restricted to lowercase characters, numbers + * and '-'. Furthermore, the names must begin with a lowercase character, + * must not end with a '-', and must not contain consecutive dashes. + * + * must consist only of lowercase + * ASCII characters, digits and '-'. + * + * If @value is non-%NULL then it is used as the new value for the + * attribute. If @value is %NULL then the attribute is unset. If + * the @value #GVariant is floating, it is consumed. + * + * See also g_menu_item_set_attribute() for a more convenient way to do + * the same. + * + * Since: 2.32 + */ +void +g_menu_item_set_attribute_value (GMenuItem *menu_item, + const gchar *attribute, + GVariant *value) +{ + g_return_if_fail (G_IS_MENU_ITEM (menu_item)); + g_return_if_fail (attribute != NULL); + g_return_if_fail (valid_attribute_name (attribute)); + + g_menu_item_clear_cow (menu_item); + + if (value != NULL) + g_hash_table_insert (menu_item->attributes, g_strdup (attribute), g_variant_ref_sink (value)); + else + g_hash_table_remove (menu_item->attributes, attribute); +} + +/** + * g_menu_item_set_attribute: + * @menu_item: a #GMenuItem + * @attribute: the attribute to set + * @format_string: (nullable): a #GVariant format string, or %NULL + * @...: positional parameters, as per @format_string + * + * Sets or unsets an attribute on @menu_item. + * + * The attribute to set or unset is specified by @attribute. This + * can be one of the standard attribute names %G_MENU_ATTRIBUTE_LABEL, + * %G_MENU_ATTRIBUTE_ACTION, %G_MENU_ATTRIBUTE_TARGET, or a custom + * attribute name. + * Attribute names are restricted to lowercase characters, numbers + * and '-'. Furthermore, the names must begin with a lowercase character, + * must not end with a '-', and must not contain consecutive dashes. + * + * If @format_string is non-%NULL then the proper position parameters + * are collected to create a #GVariant instance to use as the attribute + * value. If it is %NULL then the positional parameterrs are ignored + * and the named attribute is unset. + * + * See also g_menu_item_set_attribute_value() for an equivalent call + * that directly accepts a #GVariant. + * + * Since: 2.32 + */ +void +g_menu_item_set_attribute (GMenuItem *menu_item, + const gchar *attribute, + const gchar *format_string, + ...) +{ + GVariant *value; + + if (format_string != NULL) + { + va_list ap; + + va_start (ap, format_string); + value = g_variant_new_va (format_string, NULL, &ap); + va_end (ap); + } + else + value = NULL; + + g_menu_item_set_attribute_value (menu_item, attribute, value); +} + +/** + * g_menu_item_set_link: + * @menu_item: a #GMenuItem + * @link: type of link to establish or unset + * @model: (nullable): the #GMenuModel to link to (or %NULL to unset) + * + * Creates a link from @menu_item to @model if non-%NULL, or unsets it. + * + * Links are used to establish a relationship between a particular menu + * item and another menu. For example, %G_MENU_LINK_SUBMENU is used to + * associate a submenu with a particular menu item, and %G_MENU_LINK_SECTION + * is used to create a section. Other types of link can be used, but there + * is no guarantee that clients will be able to make sense of them. + * Link types are restricted to lowercase characters, numbers + * and '-'. Furthermore, the names must begin with a lowercase character, + * must not end with a '-', and must not contain consecutive dashes. + * + * Since: 2.32 + */ +void +g_menu_item_set_link (GMenuItem *menu_item, + const gchar *link, + GMenuModel *model) +{ + g_return_if_fail (G_IS_MENU_ITEM (menu_item)); + g_return_if_fail (link != NULL); + g_return_if_fail (valid_attribute_name (link)); + + g_menu_item_clear_cow (menu_item); + + if (model != NULL) + g_hash_table_insert (menu_item->links, g_strdup (link), g_object_ref (model)); + else + g_hash_table_remove (menu_item->links, link); +} + +/** + * g_menu_item_get_attribute_value: + * @menu_item: a #GMenuItem + * @attribute: the attribute name to query + * @expected_type: (nullable): the expected type of the attribute + * + * Queries the named @attribute on @menu_item. + * + * If @expected_type is specified and the attribute does not have this + * type, %NULL is returned. %NULL is also returned if the attribute + * simply does not exist. + * + * Returns: (nullable) (transfer full): the attribute value, or %NULL + * + * Since: 2.34 + */ +GVariant * +g_menu_item_get_attribute_value (GMenuItem *menu_item, + const gchar *attribute, + const GVariantType *expected_type) +{ + GVariant *value; + + g_return_val_if_fail (G_IS_MENU_ITEM (menu_item), NULL); + g_return_val_if_fail (attribute != NULL, NULL); + + value = g_hash_table_lookup (menu_item->attributes, attribute); + + if (value != NULL) + { + if (expected_type == NULL || g_variant_is_of_type (value, expected_type)) + g_variant_ref (value); + else + value = NULL; + } + + return value; +} + +/** + * g_menu_item_get_attribute: + * @menu_item: a #GMenuItem + * @attribute: the attribute name to query + * @format_string: a #GVariant format string + * @...: positional parameters, as per @format_string + * + * Queries the named @attribute on @menu_item. + * + * If the attribute exists and matches the #GVariantType corresponding + * to @format_string then @format_string is used to deconstruct the + * value into the positional parameters and %TRUE is returned. + * + * If the attribute does not exist, or it does exist but has the wrong + * type, then the positional parameters are ignored and %FALSE is + * returned. + * + * Returns: %TRUE if the named attribute was found with the expected + * type + * + * Since: 2.34 + */ +gboolean +g_menu_item_get_attribute (GMenuItem *menu_item, + const gchar *attribute, + const gchar *format_string, + ...) +{ + GVariant *value; + va_list ap; + + g_return_val_if_fail (G_IS_MENU_ITEM (menu_item), FALSE); + g_return_val_if_fail (attribute != NULL, FALSE); + g_return_val_if_fail (format_string != NULL, FALSE); + + value = g_hash_table_lookup (menu_item->attributes, attribute); + + if (value == NULL) + return FALSE; + + if (!g_variant_check_format_string (value, format_string, FALSE)) + return FALSE; + + va_start (ap, format_string); + g_variant_get_va (value, format_string, NULL, &ap); + va_end (ap); + + return TRUE; +} + +/** + * g_menu_item_get_link: + * @menu_item: a #GMenuItem + * @link: the link name to query + * + * Queries the named @link on @menu_item. + * + * Returns: (nullable) (transfer full): the link, or %NULL + * + * Since: 2.34 + */ +GMenuModel * +g_menu_item_get_link (GMenuItem *menu_item, + const gchar *link) +{ + GMenuModel *model; + + g_return_val_if_fail (G_IS_MENU_ITEM (menu_item), NULL); + g_return_val_if_fail (link != NULL, NULL); + g_return_val_if_fail (valid_attribute_name (link), NULL); + + model = g_hash_table_lookup (menu_item->links, link); + + if (model) + g_object_ref (model); + + return model; +} + +/** + * g_menu_item_set_label: + * @menu_item: a #GMenuItem + * @label: (nullable): the label to set, or %NULL to unset + * + * Sets or unsets the "label" attribute of @menu_item. + * + * If @label is non-%NULL it is used as the label for the menu item. If + * it is %NULL then the label attribute is unset. + * + * Since: 2.32 + */ +void +g_menu_item_set_label (GMenuItem *menu_item, + const gchar *label) +{ + GVariant *value; + + if (label != NULL) + value = g_variant_new_string (label); + else + value = NULL; + + g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_LABEL, value); +} + +/** + * g_menu_item_set_submenu: + * @menu_item: a #GMenuItem + * @submenu: (nullable): a #GMenuModel, or %NULL + * + * Sets or unsets the "submenu" link of @menu_item to @submenu. + * + * If @submenu is non-%NULL, it is linked to. If it is %NULL then the + * link is unset. + * + * The effect of having one menu appear as a submenu of another is + * exactly as it sounds. + * + * Since: 2.32 + */ +void +g_menu_item_set_submenu (GMenuItem *menu_item, + GMenuModel *submenu) +{ + g_menu_item_set_link (menu_item, G_MENU_LINK_SUBMENU, submenu); +} + +/** + * g_menu_item_set_section: + * @menu_item: a #GMenuItem + * @section: (nullable): a #GMenuModel, or %NULL + * + * Sets or unsets the "section" link of @menu_item to @section. + * + * The effect of having one menu appear as a section of another is + * exactly as it sounds: the items from @section become a direct part of + * the menu that @menu_item is added to. See g_menu_item_new_section() + * for more information about what it means for a menu item to be a + * section. + * + * Since: 2.32 + */ +void +g_menu_item_set_section (GMenuItem *menu_item, + GMenuModel *section) +{ + g_menu_item_set_link (menu_item, G_MENU_LINK_SECTION, section); +} + +/** + * g_menu_item_set_action_and_target_value: + * @menu_item: a #GMenuItem + * @action: (nullable): the name of the action for this item + * @target_value: (nullable): a #GVariant to use as the action target + * + * Sets or unsets the "action" and "target" attributes of @menu_item. + * + * If @action is %NULL then both the "action" and "target" attributes + * are unset (and @target_value is ignored). + * + * If @action is non-%NULL then the "action" attribute is set. The + * "target" attribute is then set to the value of @target_value if it is + * non-%NULL or unset otherwise. + * + * Normal menu items (ie: not submenu, section or other custom item + * types) are expected to have the "action" attribute set to identify + * the action that they are associated with. The state type of the + * action help to determine the disposition of the menu item. See + * #GAction and #GActionGroup for an overview of actions. + * + * In general, clicking on the menu item will result in activation of + * the named action with the "target" attribute given as the parameter + * to the action invocation. If the "target" attribute is not set then + * the action is invoked with no parameter. + * + * If the action has no state then the menu item is usually drawn as a + * plain menu item (ie: with no additional decoration). + * + * If the action has a boolean state then the menu item is usually drawn + * as a toggle menu item (ie: with a checkmark or equivalent + * indication). The item should be marked as 'toggled' or 'checked' + * when the boolean state is %TRUE. + * + * If the action has a string state then the menu item is usually drawn + * as a radio menu item (ie: with a radio bullet or equivalent + * indication). The item should be marked as 'selected' when the string + * state is equal to the value of the @target property. + * + * See g_menu_item_set_action_and_target() or + * g_menu_item_set_detailed_action() for two equivalent calls that are + * probably more convenient for most uses. + * + * Since: 2.32 + */ +void +g_menu_item_set_action_and_target_value (GMenuItem *menu_item, + const gchar *action, + GVariant *target_value) +{ + GVariant *action_value; + + if (action != NULL) + { + action_value = g_variant_new_string (action); + } + else + { + action_value = NULL; + target_value = NULL; + } + + g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ACTION, action_value); + g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_TARGET, target_value); +} + +/** + * g_menu_item_set_action_and_target: + * @menu_item: a #GMenuItem + * @action: (nullable): the name of the action for this item + * @format_string: (nullable): a GVariant format string + * @...: positional parameters, as per @format_string + * + * Sets or unsets the "action" and "target" attributes of @menu_item. + * + * If @action is %NULL then both the "action" and "target" attributes + * are unset (and @format_string is ignored along with the positional + * parameters). + * + * If @action is non-%NULL then the "action" attribute is set. + * @format_string is then inspected. If it is non-%NULL then the proper + * position parameters are collected to create a #GVariant instance to + * use as the target value. If it is %NULL then the positional + * parameters are ignored and the "target" attribute is unset. + * + * See also g_menu_item_set_action_and_target_value() for an equivalent + * call that directly accepts a #GVariant. See + * g_menu_item_set_detailed_action() for a more convenient version that + * works with string-typed targets. + * + * See also g_menu_item_set_action_and_target_value() for a + * description of the semantics of the action and target attributes. + * + * Since: 2.32 + */ +void +g_menu_item_set_action_and_target (GMenuItem *menu_item, + const gchar *action, + const gchar *format_string, + ...) +{ + GVariant *value; + + if (format_string != NULL) + { + va_list ap; + + va_start (ap, format_string); + value = g_variant_new_va (format_string, NULL, &ap); + va_end (ap); + } + else + value = NULL; + + g_menu_item_set_action_and_target_value (menu_item, action, value); +} + +/** + * g_menu_item_set_detailed_action: + * @menu_item: a #GMenuItem + * @detailed_action: the "detailed" action string + * + * Sets the "action" and possibly the "target" attribute of @menu_item. + * + * The format of @detailed_action is the same format parsed by + * g_action_parse_detailed_name(). + * + * See g_menu_item_set_action_and_target() or + * g_menu_item_set_action_and_target_value() for more flexible (but + * slightly less convenient) alternatives. + * + * See also g_menu_item_set_action_and_target_value() for a description of + * the semantics of the action and target attributes. + * + * Since: 2.32 + */ +void +g_menu_item_set_detailed_action (GMenuItem *menu_item, + const gchar *detailed_action) +{ + GError *error = NULL; + GVariant *target; + gchar *name; + + if (!g_action_parse_detailed_name (detailed_action, &name, &target, &error)) + g_error ("g_menu_item_set_detailed_action: %s", error->message); + + g_menu_item_set_action_and_target_value (menu_item, name, target); + if (target) + g_variant_unref (target); + g_free (name); +} + +/** + * g_menu_item_new: + * @label: (nullable): the section label, or %NULL + * @detailed_action: (nullable): the detailed action string, or %NULL + * + * Creates a new #GMenuItem. + * + * If @label is non-%NULL it is used to set the "label" attribute of the + * new item. + * + * If @detailed_action is non-%NULL it is used to set the "action" and + * possibly the "target" attribute of the new item. See + * g_menu_item_set_detailed_action() for more information. + * + * Returns: a new #GMenuItem + * + * Since: 2.32 + */ +GMenuItem * +g_menu_item_new (const gchar *label, + const gchar *detailed_action) +{ + GMenuItem *menu_item; + + menu_item = g_object_new (G_TYPE_MENU_ITEM, NULL); + + if (label != NULL) + g_menu_item_set_label (menu_item, label); + + if (detailed_action != NULL) + g_menu_item_set_detailed_action (menu_item, detailed_action); + + return menu_item; +} + +/** + * g_menu_item_new_submenu: + * @label: (nullable): the section label, or %NULL + * @submenu: a #GMenuModel with the items of the submenu + * + * Creates a new #GMenuItem representing a submenu. + * + * This is a convenience API around g_menu_item_new() and + * g_menu_item_set_submenu(). + * + * Returns: a new #GMenuItem + * + * Since: 2.32 + */ +GMenuItem * +g_menu_item_new_submenu (const gchar *label, + GMenuModel *submenu) +{ + GMenuItem *menu_item; + + menu_item = g_object_new (G_TYPE_MENU_ITEM, NULL); + + if (label != NULL) + g_menu_item_set_label (menu_item, label); + + g_menu_item_set_submenu (menu_item, submenu); + + return menu_item; +} + +/** + * g_menu_item_new_section: + * @label: (nullable): the section label, or %NULL + * @section: a #GMenuModel with the items of the section + * + * Creates a new #GMenuItem representing a section. + * + * This is a convenience API around g_menu_item_new() and + * g_menu_item_set_section(). + * + * The effect of having one menu appear as a section of another is + * exactly as it sounds: the items from @section become a direct part of + * the menu that @menu_item is added to. + * + * Visual separation is typically displayed between two non-empty + * sections. If @label is non-%NULL then it will be encorporated into + * this visual indication. This allows for labeled subsections of a + * menu. + * + * As a simple example, consider a typical "Edit" menu from a simple + * program. It probably contains an "Undo" and "Redo" item, followed by + * a separator, followed by "Cut", "Copy" and "Paste". + * + * This would be accomplished by creating three #GMenu instances. The + * first would be populated with the "Undo" and "Redo" items, and the + * second with the "Cut", "Copy" and "Paste" items. The first and + * second menus would then be added as submenus of the third. In XML + * format, this would look something like the following: + * |[ + * + *
+ * + * + *
+ *
+ * + * + * + *
+ *
+ * ]| + * + * The following example is exactly equivalent. It is more illustrative + * of the exact relationship between the menus and items (keeping in + * mind that the 'link' element defines a new menu that is linked to the + * containing one). The style of the second example is more verbose and + * difficult to read (and therefore not recommended except for the + * purpose of understanding what is really going on). + * |[ + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * ]| + * + * Returns: a new #GMenuItem + * + * Since: 2.32 + */ +GMenuItem * +g_menu_item_new_section (const gchar *label, + GMenuModel *section) +{ + GMenuItem *menu_item; + + menu_item = g_object_new (G_TYPE_MENU_ITEM, NULL); + + if (label != NULL) + g_menu_item_set_label (menu_item, label); + + g_menu_item_set_section (menu_item, section); + + return menu_item; +} + +/** + * g_menu_item_new_from_model: + * @model: a #GMenuModel + * @item_index: the index of an item in @model + * + * Creates a #GMenuItem as an exact copy of an existing menu item in a + * #GMenuModel. + * + * @item_index must be valid (ie: be sure to call + * g_menu_model_get_n_items() first). + * + * Returns: a new #GMenuItem. + * + * Since: 2.34 + */ +GMenuItem * +g_menu_item_new_from_model (GMenuModel *model, + gint item_index) +{ + GMenuModelClass *class = G_MENU_MODEL_GET_CLASS (model); + GMenuItem *menu_item; + + menu_item = g_object_new (G_TYPE_MENU_ITEM, NULL); + + /* With some trickery we can be pretty efficient. + * + * A GMenuModel must either implement iterate_item_attributes() or + * get_item_attributes(). If it implements get_item_attributes() then + * we are in luck -- we can just take a reference on the returned + * hashtable and mark ourselves as copy-on-write. + * + * In the case that the model is based on get_item_attributes (which + * is the case for both GMenu and GDBusMenuModel) then this is + * basically just g_hash_table_ref(). + */ + if (class->get_item_attributes) + { + GHashTable *attributes = NULL; + + class->get_item_attributes (model, item_index, &attributes); + if (attributes) + { + g_hash_table_unref (menu_item->attributes); + menu_item->attributes = attributes; + menu_item->cow = TRUE; + } + } + else + { + GMenuAttributeIter *iter; + const gchar *attribute; + GVariant *value; + + iter = g_menu_model_iterate_item_attributes (model, item_index); + while (g_menu_attribute_iter_get_next (iter, &attribute, &value)) + g_hash_table_insert (menu_item->attributes, g_strdup (attribute), value); + g_object_unref (iter); + } + + /* Same story for the links... */ + if (class->get_item_links) + { + GHashTable *links = NULL; + + class->get_item_links (model, item_index, &links); + if (links) + { + g_hash_table_unref (menu_item->links); + menu_item->links = links; + menu_item->cow = TRUE; + } + } + else + { + GMenuLinkIter *iter; + const gchar *link; + GMenuModel *value; + + iter = g_menu_model_iterate_item_links (model, item_index); + while (g_menu_link_iter_get_next (iter, &link, &value)) + g_hash_table_insert (menu_item->links, g_strdup (link), value); + g_object_unref (iter); + } + + return menu_item; +} + +/** + * g_menu_item_set_icon: + * @menu_item: a #GMenuItem + * @icon: a #GIcon, or %NULL + * + * Sets (or unsets) the icon on @menu_item. + * + * This call is the same as calling g_icon_serialize() and using the + * result as the value to g_menu_item_set_attribute_value() for + * %G_MENU_ATTRIBUTE_ICON. + * + * This API is only intended for use with "noun" menu items; things like + * bookmarks or applications in an "Open With" menu. Don't use it on + * menu items corresponding to verbs (eg: stock icons for 'Save' or + * 'Quit'). + * + * If @icon is %NULL then the icon is unset. + * + * Since: 2.38 + **/ +void +g_menu_item_set_icon (GMenuItem *menu_item, + GIcon *icon) +{ + GVariant *value; + + g_return_if_fail (G_IS_MENU_ITEM (menu_item)); + g_return_if_fail (icon == NULL || G_IS_ICON (icon)); + + if (icon != NULL) + value = g_icon_serialize (icon); + else + value = NULL; + + g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ICON, value); + if (value) + g_variant_unref (value); +} diff --git a/gio/gmenu.h b/gio/gmenu.h new file mode 100644 index 0000000..6609438 --- /dev/null +++ b/gio/gmenu.h @@ -0,0 +1,182 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_MENU_H__ +#define __G_MENU_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_MENU (g_menu_get_type ()) +#define G_MENU(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_MENU, GMenu)) +#define G_IS_MENU(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_MENU)) + +#define G_TYPE_MENU_ITEM (g_menu_item_get_type ()) +#define G_MENU_ITEM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_MENU_ITEM, GMenuItem)) +#define G_IS_MENU_ITEM(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_MENU_ITEM)) + +typedef struct _GMenuItem GMenuItem; +typedef struct _GMenu GMenu; + +GLIB_AVAILABLE_IN_2_32 +GType g_menu_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_32 +GMenu * g_menu_new (void); + +GLIB_AVAILABLE_IN_2_32 +void g_menu_freeze (GMenu *menu); + +GLIB_AVAILABLE_IN_2_32 +void g_menu_insert_item (GMenu *menu, + gint position, + GMenuItem *item); +GLIB_AVAILABLE_IN_2_32 +void g_menu_prepend_item (GMenu *menu, + GMenuItem *item); +GLIB_AVAILABLE_IN_2_32 +void g_menu_append_item (GMenu *menu, + GMenuItem *item); +GLIB_AVAILABLE_IN_2_32 +void g_menu_remove (GMenu *menu, + gint position); + +GLIB_AVAILABLE_IN_2_38 +void g_menu_remove_all (GMenu *menu); + +GLIB_AVAILABLE_IN_2_32 +void g_menu_insert (GMenu *menu, + gint position, + const gchar *label, + const gchar *detailed_action); +GLIB_AVAILABLE_IN_2_32 +void g_menu_prepend (GMenu *menu, + const gchar *label, + const gchar *detailed_action); +GLIB_AVAILABLE_IN_2_32 +void g_menu_append (GMenu *menu, + const gchar *label, + const gchar *detailed_action); + +GLIB_AVAILABLE_IN_2_32 +void g_menu_insert_section (GMenu *menu, + gint position, + const gchar *label, + GMenuModel *section); +GLIB_AVAILABLE_IN_2_32 +void g_menu_prepend_section (GMenu *menu, + const gchar *label, + GMenuModel *section); +GLIB_AVAILABLE_IN_2_32 +void g_menu_append_section (GMenu *menu, + const gchar *label, + GMenuModel *section); + +GLIB_AVAILABLE_IN_2_32 +void g_menu_insert_submenu (GMenu *menu, + gint position, + const gchar *label, + GMenuModel *submenu); +GLIB_AVAILABLE_IN_2_32 +void g_menu_prepend_submenu (GMenu *menu, + const gchar *label, + GMenuModel *submenu); +GLIB_AVAILABLE_IN_2_32 +void g_menu_append_submenu (GMenu *menu, + const gchar *label, + GMenuModel *submenu); + + +GLIB_AVAILABLE_IN_2_32 +GType g_menu_item_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_32 +GMenuItem * g_menu_item_new (const gchar *label, + const gchar *detailed_action); + +GLIB_AVAILABLE_IN_2_34 +GMenuItem * g_menu_item_new_from_model (GMenuModel *model, + gint item_index); + +GLIB_AVAILABLE_IN_2_32 +GMenuItem * g_menu_item_new_submenu (const gchar *label, + GMenuModel *submenu); + +GLIB_AVAILABLE_IN_2_32 +GMenuItem * g_menu_item_new_section (const gchar *label, + GMenuModel *section); + +GLIB_AVAILABLE_IN_2_34 +GVariant * g_menu_item_get_attribute_value (GMenuItem *menu_item, + const gchar *attribute, + const GVariantType *expected_type); +GLIB_AVAILABLE_IN_2_34 +gboolean g_menu_item_get_attribute (GMenuItem *menu_item, + const gchar *attribute, + const gchar *format_string, + ...); +GLIB_AVAILABLE_IN_2_34 +GMenuModel *g_menu_item_get_link (GMenuItem *menu_item, + const gchar *link); + +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_attribute_value (GMenuItem *menu_item, + const gchar *attribute, + GVariant *value); +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_attribute (GMenuItem *menu_item, + const gchar *attribute, + const gchar *format_string, + ...); +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_link (GMenuItem *menu_item, + const gchar *link, + GMenuModel *model); +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_label (GMenuItem *menu_item, + const gchar *label); +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_submenu (GMenuItem *menu_item, + GMenuModel *submenu); +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_section (GMenuItem *menu_item, + GMenuModel *section); +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_action_and_target_value (GMenuItem *menu_item, + const gchar *action, + GVariant *target_value); +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_action_and_target (GMenuItem *menu_item, + const gchar *action, + const gchar *format_string, + ...); +GLIB_AVAILABLE_IN_2_32 +void g_menu_item_set_detailed_action (GMenuItem *menu_item, + const gchar *detailed_action); + +GLIB_AVAILABLE_IN_2_38 +void g_menu_item_set_icon (GMenuItem *menu_item, + GIcon *icon); + +G_END_DECLS + +#endif /* __G_MENU_H__ */ diff --git a/gio/gmenuexporter.c b/gio/gmenuexporter.c new file mode 100644 index 0000000..a212b29 --- /dev/null +++ b/gio/gmenuexporter.c @@ -0,0 +1,833 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gmenuexporter.h" + +#include "gdbusmethodinvocation.h" +#include "gdbusintrospection.h" +#include "gdbusnamewatching.h" +#include "gdbuserror.h" + +/** + * SECTION:gmenuexporter + * @title: GMenuModel exporter + * @short_description: Export GMenuModels on D-Bus + * @include: gio/gio.h + * @see_also: #GMenuModel, #GDBusMenuModel + * + * These functions support exporting a #GMenuModel on D-Bus. + * The D-Bus interface that is used is a private implementation + * detail. + * + * To access an exported #GMenuModel remotely, use + * g_dbus_menu_model_get() to obtain a #GDBusMenuModel. + */ + +/* {{{1 D-Bus Interface description */ + +/* For documentation of this interface, see + * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI + */ + +static GDBusInterfaceInfo * +org_gtk_Menus_get_interface (void) +{ + static GDBusInterfaceInfo *interface_info; + + if (interface_info == NULL) + { + GError *error = NULL; + GDBusNodeInfo *info; + + info = g_dbus_node_info_new_for_xml ("" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " arg type='a(uuuuaa{sv})' name='changes'/>" + " " + " " + "", &error); + if (info == NULL) + g_error ("%s", error->message); + interface_info = g_dbus_node_info_lookup_interface (info, "org.gtk.Menus"); + g_assert (interface_info != NULL); + g_dbus_interface_info_ref (interface_info); + g_dbus_node_info_unref (info); + } + + return interface_info; +} + +/* {{{1 Forward declarations */ +typedef struct _GMenuExporterMenu GMenuExporterMenu; +typedef struct _GMenuExporterLink GMenuExporterLink; +typedef struct _GMenuExporterGroup GMenuExporterGroup; +typedef struct _GMenuExporterRemote GMenuExporterRemote; +typedef struct _GMenuExporterWatch GMenuExporterWatch; +typedef struct _GMenuExporter GMenuExporter; + +static gboolean g_menu_exporter_group_is_subscribed (GMenuExporterGroup *group); +static guint g_menu_exporter_group_get_id (GMenuExporterGroup *group); +static GMenuExporter * g_menu_exporter_group_get_exporter (GMenuExporterGroup *group); +static GMenuExporterMenu * g_menu_exporter_group_add_menu (GMenuExporterGroup *group, + GMenuModel *model); +static void g_menu_exporter_group_remove_menu (GMenuExporterGroup *group, + guint id); + +static GMenuExporterGroup * g_menu_exporter_create_group (GMenuExporter *exporter); +static GMenuExporterGroup * g_menu_exporter_lookup_group (GMenuExporter *exporter, + guint group_id); +static void g_menu_exporter_report (GMenuExporter *exporter, + GVariant *report); +static void g_menu_exporter_remove_group (GMenuExporter *exporter, + guint id); + +/* {{{1 GMenuExporterLink, GMenuExporterMenu */ + +struct _GMenuExporterMenu +{ + GMenuExporterGroup *group; + guint id; + + GMenuModel *model; + gulong handler_id; + GSequence *item_links; +}; + +struct _GMenuExporterLink +{ + gchar *name; + GMenuExporterMenu *menu; + GMenuExporterLink *next; +}; + +static void +g_menu_exporter_menu_free (GMenuExporterMenu *menu) +{ + g_menu_exporter_group_remove_menu (menu->group, menu->id); + + if (menu->handler_id != 0) + g_signal_handler_disconnect (menu->model, menu->handler_id); + + if (menu->item_links != NULL) + g_sequence_free (menu->item_links); + + g_object_unref (menu->model); + + g_slice_free (GMenuExporterMenu, menu); +} + +static void +g_menu_exporter_link_free (gpointer data) +{ + GMenuExporterLink *link = data; + + while (link != NULL) + { + GMenuExporterLink *tmp = link; + link = tmp->next; + + g_menu_exporter_menu_free (tmp->menu); + g_free (tmp->name); + + g_slice_free (GMenuExporterLink, tmp); + } +} + +static GMenuExporterLink * +g_menu_exporter_menu_create_links (GMenuExporterMenu *menu, + gint position) +{ + GMenuExporterLink *list = NULL; + GMenuLinkIter *iter; + const char *name; + GMenuModel *model; + + iter = g_menu_model_iterate_item_links (menu->model, position); + + while (g_menu_link_iter_get_next (iter, &name, &model)) + { + GMenuExporterGroup *group; + GMenuExporterLink *tmp; + + /* keep sections in the same group, but create new groups + * otherwise + */ + if (!g_str_equal (name, "section")) + group = g_menu_exporter_create_group (g_menu_exporter_group_get_exporter (menu->group)); + else + group = menu->group; + + tmp = g_slice_new (GMenuExporterLink); + tmp->name = g_strconcat (":", name, NULL); + tmp->menu = g_menu_exporter_group_add_menu (group, model); + tmp->next = list; + list = tmp; + + g_object_unref (model); + } + + g_object_unref (iter); + + return list; +} + +static GVariant * +g_menu_exporter_menu_describe_item (GMenuExporterMenu *menu, + gint position) +{ + GMenuAttributeIter *attr_iter; + GVariantBuilder builder; + GSequenceIter *iter; + GMenuExporterLink *link; + const char *name; + GVariant *value; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + + attr_iter = g_menu_model_iterate_item_attributes (menu->model, position); + while (g_menu_attribute_iter_get_next (attr_iter, &name, &value)) + { + g_variant_builder_add (&builder, "{sv}", name, value); + g_variant_unref (value); + } + g_object_unref (attr_iter); + + iter = g_sequence_get_iter_at_pos (menu->item_links, position); + for (link = g_sequence_get (iter); link; link = link->next) + g_variant_builder_add (&builder, "{sv}", link->name, + g_variant_new ("(uu)", g_menu_exporter_group_get_id (link->menu->group), link->menu->id)); + + return g_variant_builder_end (&builder); +} + +static GVariant * +g_menu_exporter_menu_list (GMenuExporterMenu *menu) +{ + GVariantBuilder builder; + gint i, n; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + n = g_sequence_get_length (menu->item_links); + for (i = 0; i < n; i++) + g_variant_builder_add_value (&builder, g_menu_exporter_menu_describe_item (menu, i)); + + return g_variant_builder_end (&builder); +} + +static void +g_menu_exporter_menu_items_changed (GMenuModel *model, + gint position, + gint removed, + gint added, + gpointer user_data) +{ + GMenuExporterMenu *menu = user_data; + GSequenceIter *point; + gint i; + + g_assert (menu->model == model); + g_assert (menu->item_links != NULL); + g_assert (position + removed <= g_sequence_get_length (menu->item_links)); + + point = g_sequence_get_iter_at_pos (menu->item_links, position + removed); + g_sequence_remove_range (g_sequence_get_iter_at_pos (menu->item_links, position), point); + + for (i = position; i < position + added; i++) + g_sequence_insert_before (point, g_menu_exporter_menu_create_links (menu, i)); + + if (g_menu_exporter_group_is_subscribed (menu->group)) + { + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(uuuuaa{sv})")); + g_variant_builder_add (&builder, "u", g_menu_exporter_group_get_id (menu->group)); + g_variant_builder_add (&builder, "u", menu->id); + g_variant_builder_add (&builder, "u", position); + g_variant_builder_add (&builder, "u", removed); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("aa{sv}")); + for (i = position; i < position + added; i++) + g_variant_builder_add_value (&builder, g_menu_exporter_menu_describe_item (menu, i)); + g_variant_builder_close (&builder); + + g_menu_exporter_report (g_menu_exporter_group_get_exporter (menu->group), g_variant_builder_end (&builder)); + } +} + +static void +g_menu_exporter_menu_prepare (GMenuExporterMenu *menu) +{ + gint n_items; + + g_assert (menu->item_links == NULL); + + if (g_menu_model_is_mutable (menu->model)) + menu->handler_id = g_signal_connect (menu->model, "items-changed", + G_CALLBACK (g_menu_exporter_menu_items_changed), menu); + + menu->item_links = g_sequence_new (g_menu_exporter_link_free); + + n_items = g_menu_model_get_n_items (menu->model); + if (n_items) + g_menu_exporter_menu_items_changed (menu->model, 0, 0, n_items, menu); +} + +static GMenuExporterMenu * +g_menu_exporter_menu_new (GMenuExporterGroup *group, + guint id, + GMenuModel *model) +{ + GMenuExporterMenu *menu; + + menu = g_slice_new0 (GMenuExporterMenu); + menu->group = group; + menu->id = id; + menu->model = g_object_ref (model); + + return menu; +} + +/* {{{1 GMenuExporterGroup */ + +struct _GMenuExporterGroup +{ + GMenuExporter *exporter; + guint id; + + GHashTable *menus; + guint next_menu_id; + gboolean prepared; + + gint subscribed; +}; + +static void +g_menu_exporter_group_check_if_useless (GMenuExporterGroup *group) +{ + if (g_hash_table_size (group->menus) == 0 && group->subscribed == 0) + { + g_menu_exporter_remove_group (group->exporter, group->id); + + g_hash_table_unref (group->menus); + + g_slice_free (GMenuExporterGroup, group); + } +} + +static void +g_menu_exporter_group_subscribe (GMenuExporterGroup *group, + GVariantBuilder *builder) +{ + GHashTableIter iter; + gpointer key, val; + + if (!group->prepared) + { + GMenuExporterMenu *menu; + + /* set this first, so that any menus created during the + * preparation of the first menu also end up in the prepared + * state. + * */ + group->prepared = TRUE; + + menu = g_hash_table_lookup (group->menus, 0); + + /* If the group was created by a subscription and does not yet + * exist, it won't have a root menu... + * + * That menu will be prepared if it is ever added (due to + * group->prepared == TRUE). + */ + if (menu) + g_menu_exporter_menu_prepare (menu); + } + + group->subscribed++; + + g_hash_table_iter_init (&iter, group->menus); + while (g_hash_table_iter_next (&iter, &key, &val)) + { + guint id = GPOINTER_TO_INT (key); + GMenuExporterMenu *menu = val; + + if (!g_sequence_is_empty (menu->item_links)) + { + g_variant_builder_open (builder, G_VARIANT_TYPE ("(uuaa{sv})")); + g_variant_builder_add (builder, "u", group->id); + g_variant_builder_add (builder, "u", id); + g_variant_builder_add_value (builder, g_menu_exporter_menu_list (menu)); + g_variant_builder_close (builder); + } + } +} + +static void +g_menu_exporter_group_unsubscribe (GMenuExporterGroup *group, + gint count) +{ + g_assert (group->subscribed >= count); + + group->subscribed -= count; + + g_menu_exporter_group_check_if_useless (group); +} + +static GMenuExporter * +g_menu_exporter_group_get_exporter (GMenuExporterGroup *group) +{ + return group->exporter; +} + +static gboolean +g_menu_exporter_group_is_subscribed (GMenuExporterGroup *group) +{ + return group->subscribed > 0; +} + +static guint +g_menu_exporter_group_get_id (GMenuExporterGroup *group) +{ + return group->id; +} + +static void +g_menu_exporter_group_remove_menu (GMenuExporterGroup *group, + guint id) +{ + g_hash_table_remove (group->menus, GINT_TO_POINTER (id)); + + g_menu_exporter_group_check_if_useless (group); +} + +static GMenuExporterMenu * +g_menu_exporter_group_add_menu (GMenuExporterGroup *group, + GMenuModel *model) +{ + GMenuExporterMenu *menu; + guint id; + + id = group->next_menu_id++; + menu = g_menu_exporter_menu_new (group, id, model); + g_hash_table_insert (group->menus, GINT_TO_POINTER (id), menu); + + if (group->prepared) + g_menu_exporter_menu_prepare (menu); + + return menu; +} + +static GMenuExporterGroup * +g_menu_exporter_group_new (GMenuExporter *exporter, + guint id) +{ + GMenuExporterGroup *group; + + group = g_slice_new0 (GMenuExporterGroup); + group->menus = g_hash_table_new (NULL, NULL); + group->exporter = exporter; + group->id = id; + + return group; +} + +/* {{{1 GMenuExporterRemote */ + +struct _GMenuExporterRemote +{ + GMenuExporter *exporter; + GHashTable *watches; + guint watch_id; +}; + +static void +g_menu_exporter_remote_subscribe (GMenuExporterRemote *remote, + guint group_id, + GVariantBuilder *builder) +{ + GMenuExporterGroup *group; + guint count; + + count = (gsize) g_hash_table_lookup (remote->watches, GINT_TO_POINTER (group_id)); + g_hash_table_insert (remote->watches, GINT_TO_POINTER (group_id), GINT_TO_POINTER (count + 1)); + + /* Group will be created (as empty/unsubscribed if it does not exist) */ + group = g_menu_exporter_lookup_group (remote->exporter, group_id); + g_menu_exporter_group_subscribe (group, builder); +} + +static void +g_menu_exporter_remote_unsubscribe (GMenuExporterRemote *remote, + guint group_id) +{ + GMenuExporterGroup *group; + guint count; + + count = (gsize) g_hash_table_lookup (remote->watches, GINT_TO_POINTER (group_id)); + + if (count == 0) + return; + + if (count != 1) + g_hash_table_insert (remote->watches, GINT_TO_POINTER (group_id), GINT_TO_POINTER (count - 1)); + else + g_hash_table_remove (remote->watches, GINT_TO_POINTER (group_id)); + + group = g_menu_exporter_lookup_group (remote->exporter, group_id); + g_menu_exporter_group_unsubscribe (group, 1); +} + +static gboolean +g_menu_exporter_remote_has_subscriptions (GMenuExporterRemote *remote) +{ + return g_hash_table_size (remote->watches) != 0; +} + +static void +g_menu_exporter_remote_free (gpointer data) +{ + GMenuExporterRemote *remote = data; + GHashTableIter iter; + gpointer key, val; + + g_hash_table_iter_init (&iter, remote->watches); + while (g_hash_table_iter_next (&iter, &key, &val)) + { + GMenuExporterGroup *group; + + group = g_menu_exporter_lookup_group (remote->exporter, GPOINTER_TO_INT (key)); + g_menu_exporter_group_unsubscribe (group, GPOINTER_TO_INT (val)); + } + + if (remote->watch_id > 0) + g_bus_unwatch_name (remote->watch_id); + + g_hash_table_unref (remote->watches); + + g_slice_free (GMenuExporterRemote, remote); +} + +static GMenuExporterRemote * +g_menu_exporter_remote_new (GMenuExporter *exporter, + guint watch_id) +{ + GMenuExporterRemote *remote; + + remote = g_slice_new0 (GMenuExporterRemote); + remote->exporter = exporter; + remote->watches = g_hash_table_new (NULL, NULL); + remote->watch_id = watch_id; + + return remote; +} + +/* {{{1 GMenuExporter */ + +struct _GMenuExporter +{ + GDBusConnection *connection; + gchar *object_path; + guint registration_id; + GHashTable *groups; + guint next_group_id; + + GMenuExporterMenu *root; + GMenuExporterRemote *peer_remote; + GHashTable *remotes; +}; + +static void +g_menu_exporter_name_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GMenuExporter *exporter = user_data; + + /* connection == NULL when we get called because the connection closed */ + g_assert (exporter->connection == connection || connection == NULL); + + g_hash_table_remove (exporter->remotes, name); +} + +static GVariant * +g_menu_exporter_subscribe (GMenuExporter *exporter, + const gchar *sender, + GVariant *group_ids) +{ + GMenuExporterRemote *remote; + GVariantBuilder builder; + GVariantIter iter; + guint32 id; + + if (sender != NULL) + remote = g_hash_table_lookup (exporter->remotes, sender); + else + remote = exporter->peer_remote; + + if (remote == NULL) + { + if (sender != NULL) + { + guint watch_id; + + watch_id = g_bus_watch_name_on_connection (exporter->connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, g_menu_exporter_name_vanished, exporter, NULL); + remote = g_menu_exporter_remote_new (exporter, watch_id); + g_hash_table_insert (exporter->remotes, g_strdup (sender), remote); + } + else + remote = exporter->peer_remote = + g_menu_exporter_remote_new (exporter, 0); + } + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a(uuaa{sv}))")); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(uuaa{sv})")); + + g_variant_iter_init (&iter, group_ids); + while (g_variant_iter_next (&iter, "u", &id)) + g_menu_exporter_remote_subscribe (remote, id, &builder); + + g_variant_builder_close (&builder); + + return g_variant_builder_end (&builder); +} + +static void +g_menu_exporter_unsubscribe (GMenuExporter *exporter, + const gchar *sender, + GVariant *group_ids) +{ + GMenuExporterRemote *remote; + GVariantIter iter; + guint32 id; + + if (sender != NULL) + remote = g_hash_table_lookup (exporter->remotes, sender); + else + remote = exporter->peer_remote; + + if (remote == NULL) + return; + + g_variant_iter_init (&iter, group_ids); + while (g_variant_iter_next (&iter, "u", &id)) + g_menu_exporter_remote_unsubscribe (remote, id); + + if (!g_menu_exporter_remote_has_subscriptions (remote)) + { + if (sender != NULL) + g_hash_table_remove (exporter->remotes, sender); + else + g_clear_pointer (&exporter->peer_remote, g_menu_exporter_remote_free); + } +} + +static void +g_menu_exporter_report (GMenuExporter *exporter, + GVariant *report) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_open (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add_value (&builder, report); + g_variant_builder_close (&builder); + + g_dbus_connection_emit_signal (exporter->connection, + NULL, + exporter->object_path, + "org.gtk.Menus", "Changed", + g_variant_builder_end (&builder), + NULL); +} + +static void +g_menu_exporter_remove_group (GMenuExporter *exporter, + guint id) +{ + g_hash_table_remove (exporter->groups, GINT_TO_POINTER (id)); +} + +static GMenuExporterGroup * +g_menu_exporter_lookup_group (GMenuExporter *exporter, + guint group_id) +{ + GMenuExporterGroup *group; + + group = g_hash_table_lookup (exporter->groups, GINT_TO_POINTER (group_id)); + + if (group == NULL) + { + group = g_menu_exporter_group_new (exporter, group_id); + g_hash_table_insert (exporter->groups, GINT_TO_POINTER (group_id), group); + } + + return group; +} + +static GMenuExporterGroup * +g_menu_exporter_create_group (GMenuExporter *exporter) +{ + GMenuExporterGroup *group; + guint id; + + id = exporter->next_group_id++; + group = g_menu_exporter_group_new (exporter, id); + g_hash_table_insert (exporter->groups, GINT_TO_POINTER (id), group); + + return group; +} + +static void +g_menu_exporter_free (gpointer user_data) +{ + GMenuExporter *exporter = user_data; + + g_menu_exporter_menu_free (exporter->root); + g_clear_pointer (&exporter->peer_remote, g_menu_exporter_remote_free); + g_hash_table_unref (exporter->remotes); + g_hash_table_unref (exporter->groups); + g_object_unref (exporter->connection); + g_free (exporter->object_path); + + g_slice_free (GMenuExporter, exporter); +} + +static void +g_menu_exporter_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GMenuExporter *exporter = user_data; + GVariant *group_ids; + + group_ids = g_variant_get_child_value (parameters, 0); + + if (g_str_equal (method_name, "Start")) + g_dbus_method_invocation_return_value (invocation, g_menu_exporter_subscribe (exporter, sender, group_ids)); + + else if (g_str_equal (method_name, "End")) + { + g_menu_exporter_unsubscribe (exporter, sender, group_ids); + g_dbus_method_invocation_return_value (invocation, NULL); + } + + else + g_assert_not_reached (); + + g_variant_unref (group_ids); +} + +/* {{{1 Public API */ + +/** + * g_dbus_connection_export_menu_model: + * @connection: a #GDBusConnection + * @object_path: a D-Bus object path + * @menu: a #GMenuModel + * @error: return location for an error, or %NULL + * + * Exports @menu on @connection at @object_path. + * + * The implemented D-Bus API should be considered private. + * It is subject to change in the future. + * + * An object path can only have one menu model exported on it. If this + * constraint is violated, the export will fail and 0 will be + * returned (with @error set accordingly). + * + * You can unexport the menu model using + * g_dbus_connection_unexport_menu_model() with the return value of + * this function. + * + * Returns: the ID of the export (never zero), or 0 in case of failure + * + * Since: 2.32 + */ +guint +g_dbus_connection_export_menu_model (GDBusConnection *connection, + const gchar *object_path, + GMenuModel *menu, + GError **error) +{ + const GDBusInterfaceVTable vtable = { + g_menu_exporter_method_call, NULL, NULL, { 0 } + }; + GMenuExporter *exporter; + guint id; + + exporter = g_slice_new0 (GMenuExporter); + + id = g_dbus_connection_register_object (connection, object_path, org_gtk_Menus_get_interface (), + &vtable, exporter, g_menu_exporter_free, error); + + if (id == 0) + { + g_slice_free (GMenuExporter, exporter); + return 0; + } + + exporter->connection = g_object_ref (connection); + exporter->object_path = g_strdup (object_path); + exporter->groups = g_hash_table_new (NULL, NULL); + exporter->remotes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_menu_exporter_remote_free); + exporter->root = g_menu_exporter_group_add_menu (g_menu_exporter_create_group (exporter), menu); + + return id; +} + +/** + * g_dbus_connection_unexport_menu_model: + * @connection: a #GDBusConnection + * @export_id: the ID from g_dbus_connection_export_menu_model() + * + * Reverses the effect of a previous call to + * g_dbus_connection_export_menu_model(). + * + * It is an error to call this function with an ID that wasn't returned + * from g_dbus_connection_export_menu_model() or to call it with the + * same ID more than once. + * + * Since: 2.32 + */ +void +g_dbus_connection_unexport_menu_model (GDBusConnection *connection, + guint export_id) +{ + g_dbus_connection_unregister_object (connection, export_id); +} + +/* {{{1 Epilogue */ +/* vim:set foldmethod=marker: */ diff --git a/gio/gmenuexporter.h b/gio/gmenuexporter.h new file mode 100644 index 0000000..650aaf0 --- /dev/null +++ b/gio/gmenuexporter.h @@ -0,0 +1,40 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_MENU_EXPORTER_H__ +#define __G_MENU_EXPORTER_H__ + +#include +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_2_32 +guint g_dbus_connection_export_menu_model (GDBusConnection *connection, + const gchar *object_path, + GMenuModel *menu, + GError **error); + +GLIB_AVAILABLE_IN_2_32 +void g_dbus_connection_unexport_menu_model (GDBusConnection *connection, + guint export_id); + +G_END_DECLS + +#endif /* __G_MENU_EXPORTER_H__ */ diff --git a/gio/gmenumodel.c b/gio/gmenumodel.c new file mode 100644 index 0000000..bd60dc5 --- /dev/null +++ b/gio/gmenumodel.c @@ -0,0 +1,1006 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gmenumodel.h" + +#include "glibintl.h" +#include "gmarshal-internal.h" + +/** + * SECTION:gmenumodel + * @title: GMenuModel + * @short_description: An abstract class representing the contents of a menu + * @include: gio/gio.h + * @see_also: #GActionGroup + * + * #GMenuModel represents the contents of a menu -- an ordered list of + * menu items. The items are associated with actions, which can be + * activated through them. Items can be grouped in sections, and may + * have submenus associated with them. Both items and sections usually + * have some representation data, such as labels or icons. The type of + * the associated action (ie whether it is stateful, and what kind of + * state it has) can influence the representation of the item. + * + * The conceptual model of menus in #GMenuModel is hierarchical: + * sections and submenus are again represented by #GMenuModels. + * Menus themselves do not define their own roles. Rather, the role + * of a particular #GMenuModel is defined by the item that references + * it (or, in the case of the 'root' menu, is defined by the context + * in which it is used). + * + * As an example, consider the visible portions of this menu: + * + * ## An example menu # {#menu-example} + * + * ![](menu-example.png) + * + * There are 8 "menus" visible in the screenshot: one menubar, two + * submenus and 5 sections: + * + * - the toplevel menubar (containing 4 items) + * - the View submenu (containing 3 sections) + * - the first section of the View submenu (containing 2 items) + * - the second section of the View submenu (containing 1 item) + * - the final section of the View submenu (containing 1 item) + * - the Highlight Mode submenu (containing 2 sections) + * - the Sources section (containing 2 items) + * - the Markup section (containing 2 items) + * + * The [example][menu-model] illustrates the conceptual connection between + * these 8 menus. Each large block in the figure represents a menu and the + * smaller blocks within the large block represent items in that menu. Some + * items contain references to other menus. + * + * ## A menu example # {#menu-model} + * + * ![](menu-model.png) + * + * Notice that the separators visible in the [example][menu-example] + * appear nowhere in the [menu model][menu-model]. This is because + * separators are not explicitly represented in the menu model. Instead, + * a separator is inserted between any two non-empty sections of a menu. + * Section items can have labels just like any other item. In that case, + * a display system may show a section header instead of a separator. + * + * The motivation for this abstract model of application controls is + * that modern user interfaces tend to make these controls available + * outside the application. Examples include global menus, jumplists, + * dash boards, etc. To support such uses, it is necessary to 'export' + * information about actions and their representation in menus, which + * is exactly what the [GActionGroup exporter][gio-GActionGroup-exporter] + * and the [GMenuModel exporter][gio-GMenuModel-exporter] do for + * #GActionGroup and #GMenuModel. The client-side counterparts to + * make use of the exported information are #GDBusActionGroup and + * #GDBusMenuModel. + * + * The API of #GMenuModel is very generic, with iterators for the + * attributes and links of an item, see g_menu_model_iterate_item_attributes() + * and g_menu_model_iterate_item_links(). The 'standard' attributes and + * link types have predefined names: %G_MENU_ATTRIBUTE_LABEL, + * %G_MENU_ATTRIBUTE_ACTION, %G_MENU_ATTRIBUTE_TARGET, %G_MENU_LINK_SECTION + * and %G_MENU_LINK_SUBMENU. + * + * Items in a #GMenuModel represent active controls if they refer to + * an action that can get activated when the user interacts with the + * menu item. The reference to the action is encoded by the string id + * in the %G_MENU_ATTRIBUTE_ACTION attribute. An action id uniquely + * identifies an action in an action group. Which action group(s) provide + * actions depends on the context in which the menu model is used. + * E.g. when the model is exported as the application menu of a + * #GtkApplication, actions can be application-wide or window-specific + * (and thus come from two different action groups). By convention, the + * application-wide actions have names that start with "app.", while the + * names of window-specific actions start with "win.". + * + * While a wide variety of stateful actions is possible, the following + * is the minimum that is expected to be supported by all users of exported + * menu information: + * - an action with no parameter type and no state + * - an action with no parameter type and boolean state + * - an action with string parameter type and string state + * + * ## Stateless + * + * A stateless action typically corresponds to an ordinary menu item. + * + * Selecting such a menu item will activate the action (with no parameter). + * + * ## Boolean State + * + * An action with a boolean state will most typically be used with a "toggle" + * or "switch" menu item. The state can be set directly, but activating the + * action (with no parameter) results in the state being toggled. + * + * Selecting a toggle menu item will activate the action. The menu item should + * be rendered as "checked" when the state is true. + * + * ## String Parameter and State + * + * Actions with string parameters and state will most typically be used to + * represent an enumerated choice over the items available for a group of + * radio menu items. Activating the action with a string parameter is + * equivalent to setting that parameter as the state. + * + * Radio menu items, in addition to being associated with the action, will + * have a target value. Selecting that menu item will result in activation + * of the action with the target value as the parameter. The menu item should + * be rendered as "selected" when the state of the action is equal to the + * target value of the menu item. + */ + +/** + * GMenuModel: + * + * #GMenuModel is an opaque structure type. You must access it using the + * functions below. + * + * Since: 2.32 + */ + +/** + * GMenuAttributeIter: + * + * #GMenuAttributeIter is an opaque structure type. You must access it + * using the functions below. + * + * Since: 2.32 + */ + +/** + * GMenuLinkIter: + * + * #GMenuLinkIter is an opaque structure type. You must access it using + * the functions below. + * + * Since: 2.32 + */ + +typedef struct +{ + GMenuLinkIter parent_instance; + GHashTableIter iter; + GHashTable *table; +} GMenuLinkHashIter; + +typedef GMenuLinkIterClass GMenuLinkHashIterClass; + +static GType g_menu_link_hash_iter_get_type (void); + +G_DEFINE_TYPE (GMenuLinkHashIter, g_menu_link_hash_iter, G_TYPE_MENU_LINK_ITER) + +static gboolean +g_menu_link_hash_iter_get_next (GMenuLinkIter *link_iter, + const gchar **out_name, + GMenuModel **value) +{ + GMenuLinkHashIter *iter = (GMenuLinkHashIter *) link_iter; + gpointer keyptr, valueptr; + + if (!g_hash_table_iter_next (&iter->iter, &keyptr, &valueptr)) + return FALSE; + + *out_name = keyptr; + *value = g_object_ref (valueptr); + + return TRUE; +} + +static void +g_menu_link_hash_iter_finalize (GObject *object) +{ + GMenuLinkHashIter *iter = (GMenuLinkHashIter *) object; + + g_hash_table_unref (iter->table); + + G_OBJECT_CLASS (g_menu_link_hash_iter_parent_class) + ->finalize (object); +} + +static void +g_menu_link_hash_iter_init (GMenuLinkHashIter *iter) +{ +} + +static void +g_menu_link_hash_iter_class_init (GMenuLinkHashIterClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_menu_link_hash_iter_finalize; + class->get_next = g_menu_link_hash_iter_get_next; +} + + +typedef struct +{ + GMenuAttributeIter parent_instance; + GHashTableIter iter; + GHashTable *table; +} GMenuAttributeHashIter; + +typedef GMenuAttributeIterClass GMenuAttributeHashIterClass; + +static GType g_menu_attribute_hash_iter_get_type (void); + +G_DEFINE_TYPE (GMenuAttributeHashIter, g_menu_attribute_hash_iter, G_TYPE_MENU_ATTRIBUTE_ITER) + +static gboolean +g_menu_attribute_hash_iter_get_next (GMenuAttributeIter *attr_iter, + const gchar **name, + GVariant **value) +{ + GMenuAttributeHashIter *iter = (GMenuAttributeHashIter *) attr_iter; + gpointer keyptr, valueptr; + + if (!g_hash_table_iter_next (&iter->iter, &keyptr, &valueptr)) + return FALSE; + + *name = keyptr; + + *value = g_variant_ref (valueptr); + + return TRUE; +} + +static void +g_menu_attribute_hash_iter_finalize (GObject *object) +{ + GMenuAttributeHashIter *iter = (GMenuAttributeHashIter *) object; + + g_hash_table_unref (iter->table); + + G_OBJECT_CLASS (g_menu_attribute_hash_iter_parent_class) + ->finalize (object); +} + +static void +g_menu_attribute_hash_iter_init (GMenuAttributeHashIter *iter) +{ +} + +static void +g_menu_attribute_hash_iter_class_init (GMenuAttributeHashIterClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_menu_attribute_hash_iter_finalize; + class->get_next = g_menu_attribute_hash_iter_get_next; +} + +G_DEFINE_ABSTRACT_TYPE (GMenuModel, g_menu_model, G_TYPE_OBJECT) + + +static guint g_menu_model_items_changed_signal; + +static GMenuAttributeIter * +g_menu_model_real_iterate_item_attributes (GMenuModel *model, + gint item_index) +{ + GHashTable *table = NULL; + GMenuAttributeIter *result; + + G_MENU_MODEL_GET_CLASS (model)->get_item_attributes (model, item_index, &table); + + if (table) + { + GMenuAttributeHashIter *iter = g_object_new (g_menu_attribute_hash_iter_get_type (), NULL); + g_hash_table_iter_init (&iter->iter, table); + iter->table = g_hash_table_ref (table); + result = G_MENU_ATTRIBUTE_ITER (iter); + } + else + { + g_critical ("GMenuModel implementation '%s' doesn't override iterate_item_attributes() " + "and fails to return valid values from get_item_attributes()", + G_OBJECT_TYPE_NAME (model)); + result = NULL; + } + + if (table != NULL) + g_hash_table_unref (table); + + return result; +} + +static GVariant * +g_menu_model_real_get_item_attribute_value (GMenuModel *model, + gint item_index, + const gchar *attribute, + const GVariantType *expected_type) +{ + GHashTable *table = NULL; + GVariant *value = NULL; + + G_MENU_MODEL_GET_CLASS (model) + ->get_item_attributes (model, item_index, &table); + + if (table != NULL) + { + value = g_hash_table_lookup (table, attribute); + + if (value != NULL) + { + if (expected_type == NULL || g_variant_is_of_type (value, expected_type)) + value = g_variant_ref (value); + else + value = NULL; + } + } + else + g_assert_not_reached (); + + if (table != NULL) + g_hash_table_unref (table); + + return value; +} + +static GMenuLinkIter * +g_menu_model_real_iterate_item_links (GMenuModel *model, + gint item_index) +{ + GHashTable *table = NULL; + GMenuLinkIter *result; + + G_MENU_MODEL_GET_CLASS (model) + ->get_item_links (model, item_index, &table); + + if (table) + { + GMenuLinkHashIter *iter = g_object_new (g_menu_link_hash_iter_get_type (), NULL); + g_hash_table_iter_init (&iter->iter, table); + iter->table = g_hash_table_ref (table); + result = G_MENU_LINK_ITER (iter); + } + else + { + g_critical ("GMenuModel implementation '%s' doesn't override iterate_item_links() " + "and fails to return valid values from get_item_links()", + G_OBJECT_TYPE_NAME (model)); + result = NULL; + } + + if (table != NULL) + g_hash_table_unref (table); + + return result; +} + +static GMenuModel * +g_menu_model_real_get_item_link (GMenuModel *model, + gint item_index, + const gchar *link) +{ + GHashTable *table = NULL; + GMenuModel *value = NULL; + + G_MENU_MODEL_GET_CLASS (model) + ->get_item_links (model, item_index, &table); + + if (table != NULL) + value = g_hash_table_lookup (table, link); + else + g_assert_not_reached (); + + if (value != NULL) + g_object_ref (value); + + if (table != NULL) + g_hash_table_unref (table); + + return value; +} + +static void +g_menu_model_init (GMenuModel *model) +{ +} + +static void +g_menu_model_class_init (GMenuModelClass *class) +{ + class->iterate_item_attributes = g_menu_model_real_iterate_item_attributes; + class->get_item_attribute_value = g_menu_model_real_get_item_attribute_value; + class->iterate_item_links = g_menu_model_real_iterate_item_links; + class->get_item_link = g_menu_model_real_get_item_link; + + /** + * GMenuModel::items-changed: + * @model: the #GMenuModel that is changing + * @position: the position of the change + * @removed: the number of items removed + * @added: the number of items added + * + * Emitted when a change has occurred to the menu. + * + * The only changes that can occur to a menu is that items are removed + * or added. Items may not change (except by being removed and added + * back in the same location). This signal is capable of describing + * both of those changes (at the same time). + * + * The signal means that starting at the index @position, @removed + * items were removed and @added items were added in their place. If + * @removed is zero then only items were added. If @added is zero + * then only items were removed. + * + * As an example, if the menu contains items a, b, c, d (in that + * order) and the signal (2, 1, 3) occurs then the new composition of + * the menu will be a, b, _, _, _, d (with each _ representing some + * new item). + * + * Signal handlers may query the model (particularly the added items) + * and expect to see the results of the modification that is being + * reported. The signal is emitted after the modification. + **/ + g_menu_model_items_changed_signal = + g_signal_new (I_("items-changed"), G_TYPE_MENU_MODEL, + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + _g_cclosure_marshal_VOID__INT_INT_INT, + G_TYPE_NONE, + 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); + g_signal_set_va_marshaller (g_menu_model_items_changed_signal, + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_VOID__INT_INT_INTv); +} + +/** + * g_menu_model_is_mutable: + * @model: a #GMenuModel + * + * Queries if @model is mutable. + * + * An immutable #GMenuModel will never emit the #GMenuModel::items-changed + * signal. Consumers of the model may make optimisations accordingly. + * + * Returns: %TRUE if the model is mutable (ie: "items-changed" may be + * emitted). + * + * Since: 2.32 + */ +gboolean +g_menu_model_is_mutable (GMenuModel *model) +{ + return G_MENU_MODEL_GET_CLASS (model) + ->is_mutable (model); +} + +/** + * g_menu_model_get_n_items: + * @model: a #GMenuModel + * + * Query the number of items in @model. + * + * Returns: the number of items + * + * Since: 2.32 + */ +gint +g_menu_model_get_n_items (GMenuModel *model) +{ + return G_MENU_MODEL_GET_CLASS (model) + ->get_n_items (model); +} + +/** + * g_menu_model_iterate_item_attributes: + * @model: a #GMenuModel + * @item_index: the index of the item + * + * Creates a #GMenuAttributeIter to iterate over the attributes of + * the item at position @item_index in @model. + * + * You must free the iterator with g_object_unref() when you are done. + * + * Returns: (transfer full): a new #GMenuAttributeIter + * + * Since: 2.32 + */ +GMenuAttributeIter * +g_menu_model_iterate_item_attributes (GMenuModel *model, + gint item_index) +{ + return G_MENU_MODEL_GET_CLASS (model) + ->iterate_item_attributes (model, item_index); +} + +/** + * g_menu_model_get_item_attribute_value: + * @model: a #GMenuModel + * @item_index: the index of the item + * @attribute: the attribute to query + * @expected_type: (nullable): the expected type of the attribute, or + * %NULL + * + * Queries the item at position @item_index in @model for the attribute + * specified by @attribute. + * + * If @expected_type is non-%NULL then it specifies the expected type of + * the attribute. If it is %NULL then any type will be accepted. + * + * If the attribute exists and matches @expected_type (or if the + * expected type is unspecified) then the value is returned. + * + * If the attribute does not exist, or does not match the expected type + * then %NULL is returned. + * + * Returns: (nullable) (transfer full): the value of the attribute + * + * Since: 2.32 + */ +GVariant * +g_menu_model_get_item_attribute_value (GMenuModel *model, + gint item_index, + const gchar *attribute, + const GVariantType *expected_type) +{ + return G_MENU_MODEL_GET_CLASS (model) + ->get_item_attribute_value (model, item_index, attribute, expected_type); +} + +/** + * g_menu_model_get_item_attribute: + * @model: a #GMenuModel + * @item_index: the index of the item + * @attribute: the attribute to query + * @format_string: a #GVariant format string + * @...: positional parameters, as per @format_string + * + * Queries item at position @item_index in @model for the attribute + * specified by @attribute. + * + * If the attribute exists and matches the #GVariantType corresponding + * to @format_string then @format_string is used to deconstruct the + * value into the positional parameters and %TRUE is returned. + * + * If the attribute does not exist, or it does exist but has the wrong + * type, then the positional parameters are ignored and %FALSE is + * returned. + * + * This function is a mix of g_menu_model_get_item_attribute_value() and + * g_variant_get(), followed by a g_variant_unref(). As such, + * @format_string must make a complete copy of the data (since the + * #GVariant may go away after the call to g_variant_unref()). In + * particular, no '&' characters are allowed in @format_string. + * + * Returns: %TRUE if the named attribute was found with the expected + * type + * + * Since: 2.32 + */ +gboolean +g_menu_model_get_item_attribute (GMenuModel *model, + gint item_index, + const gchar *attribute, + const gchar *format_string, + ...) +{ + GVariant *value; + va_list ap; + + value = g_menu_model_get_item_attribute_value (model, item_index, attribute, NULL); + + if (value == NULL) + return FALSE; + + if (!g_variant_check_format_string (value, format_string, TRUE)) + { + g_variant_unref (value); + return FALSE; + } + + va_start (ap, format_string); + g_variant_get_va (value, format_string, NULL, &ap); + g_variant_unref (value); + va_end (ap); + + return TRUE; +} + +/** + * g_menu_model_iterate_item_links: + * @model: a #GMenuModel + * @item_index: the index of the item + * + * Creates a #GMenuLinkIter to iterate over the links of the item at + * position @item_index in @model. + * + * You must free the iterator with g_object_unref() when you are done. + * + * Returns: (transfer full): a new #GMenuLinkIter + * + * Since: 2.32 + */ +GMenuLinkIter * +g_menu_model_iterate_item_links (GMenuModel *model, + gint item_index) +{ + return G_MENU_MODEL_GET_CLASS (model) + ->iterate_item_links (model, item_index); +} + +/** + * g_menu_model_get_item_link: + * @model: a #GMenuModel + * @item_index: the index of the item + * @link: the link to query + * + * Queries the item at position @item_index in @model for the link + * specified by @link. + * + * If the link exists, the linked #GMenuModel is returned. If the link + * does not exist, %NULL is returned. + * + * Returns: (nullable) (transfer full): the linked #GMenuModel, or %NULL + * + * Since: 2.32 + */ +GMenuModel * +g_menu_model_get_item_link (GMenuModel *model, + gint item_index, + const gchar *link) +{ + return G_MENU_MODEL_GET_CLASS (model) + ->get_item_link (model, item_index, link); +} + +/** + * g_menu_model_items_changed: + * @model: a #GMenuModel + * @position: the position of the change + * @removed: the number of items removed + * @added: the number of items added + * + * Requests emission of the #GMenuModel::items-changed signal on @model. + * + * This function should never be called except by #GMenuModel + * subclasses. Any other calls to this function will very likely lead + * to a violation of the interface of the model. + * + * The implementation should update its internal representation of the + * menu before emitting the signal. The implementation should further + * expect to receive queries about the new state of the menu (and + * particularly added menu items) while signal handlers are running. + * + * The implementation must dispatch this call directly from a mainloop + * entry and not in response to calls -- particularly those from the + * #GMenuModel API. Said another way: the menu must not change while + * user code is running without returning to the mainloop. + * + * Since: 2.32 + */ +void +g_menu_model_items_changed (GMenuModel *model, + gint position, + gint removed, + gint added) +{ + g_signal_emit (model, g_menu_model_items_changed_signal, 0, position, removed, added); +} + +struct _GMenuAttributeIterPrivate +{ + GQuark name; + GVariant *value; + gboolean valid; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GMenuAttributeIter, g_menu_attribute_iter, G_TYPE_OBJECT) + +/** + * g_menu_attribute_iter_get_next: + * @iter: a #GMenuAttributeIter + * @out_name: (out) (optional) (transfer none): the type of the attribute + * @value: (out) (optional) (transfer full): the attribute value + * + * This function combines g_menu_attribute_iter_next() with + * g_menu_attribute_iter_get_name() and g_menu_attribute_iter_get_value(). + * + * First the iterator is advanced to the next (possibly first) attribute. + * If that fails, then %FALSE is returned and there are no other + * effects. + * + * If successful, @name and @value are set to the name and value of the + * attribute that has just been advanced to. At this point, + * g_menu_attribute_iter_get_name() and g_menu_attribute_iter_get_value() will + * return the same values again. + * + * The value returned in @name remains valid for as long as the iterator + * remains at the current position. The value returned in @value must + * be unreffed using g_variant_unref() when it is no longer in use. + * + * Returns: %TRUE on success, or %FALSE if there is no additional + * attribute + * + * Since: 2.32 + */ +gboolean +g_menu_attribute_iter_get_next (GMenuAttributeIter *iter, + const gchar **out_name, + GVariant **value) +{ + const gchar *name; + + if (iter->priv->value) + { + g_variant_unref (iter->priv->value); + iter->priv->value = NULL; + } + + iter->priv->valid = G_MENU_ATTRIBUTE_ITER_GET_CLASS (iter) + ->get_next (iter, &name, &iter->priv->value); + + if (iter->priv->valid) + { + iter->priv->name = g_quark_from_string (name); + if (out_name) + *out_name = g_quark_to_string (iter->priv->name); + + if (value) + *value = g_variant_ref (iter->priv->value); + } + + return iter->priv->valid; +} + +/** + * g_menu_attribute_iter_next: + * @iter: a #GMenuAttributeIter + * + * Attempts to advance the iterator to the next (possibly first) + * attribute. + * + * %TRUE is returned on success, or %FALSE if there are no more + * attributes. + * + * You must call this function when you first acquire the iterator + * to advance it to the first attribute (and determine if the first + * attribute exists at all). + * + * Returns: %TRUE on success, or %FALSE when there are no more attributes + * + * Since: 2.32 + */ +gboolean +g_menu_attribute_iter_next (GMenuAttributeIter *iter) +{ + return g_menu_attribute_iter_get_next (iter, NULL, NULL); +} + +/** + * g_menu_attribute_iter_get_name: + * @iter: a #GMenuAttributeIter + * + * Gets the name of the attribute at the current iterator position, as + * a string. + * + * The iterator is not advanced. + * + * Returns: the name of the attribute + * + * Since: 2.32 + */ +const gchar * +g_menu_attribute_iter_get_name (GMenuAttributeIter *iter) +{ + g_return_val_if_fail (iter->priv->valid, 0); + + return g_quark_to_string (iter->priv->name); +} + +/** + * g_menu_attribute_iter_get_value: + * @iter: a #GMenuAttributeIter + * + * Gets the value of the attribute at the current iterator position. + * + * The iterator is not advanced. + * + * Returns: (transfer full): the value of the current attribute + * + * Since: 2.32 + */ +GVariant * +g_menu_attribute_iter_get_value (GMenuAttributeIter *iter) +{ + g_return_val_if_fail (iter->priv->valid, NULL); + + return g_variant_ref (iter->priv->value); +} + +static void +g_menu_attribute_iter_finalize (GObject *object) +{ + GMenuAttributeIter *iter = G_MENU_ATTRIBUTE_ITER (object); + + if (iter->priv->value) + g_variant_unref (iter->priv->value); + + G_OBJECT_CLASS (g_menu_attribute_iter_parent_class) + ->finalize (object); +} + +static void +g_menu_attribute_iter_init (GMenuAttributeIter *iter) +{ + iter->priv = g_menu_attribute_iter_get_instance_private (iter); +} + +static void +g_menu_attribute_iter_class_init (GMenuAttributeIterClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_menu_attribute_iter_finalize; +} + +struct _GMenuLinkIterPrivate +{ + GQuark name; + GMenuModel *value; + gboolean valid; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GMenuLinkIter, g_menu_link_iter, G_TYPE_OBJECT) + +/** + * g_menu_link_iter_get_next: + * @iter: a #GMenuLinkIter + * @out_link: (out) (optional) (transfer none): the name of the link + * @value: (out) (optional) (transfer full): the linked #GMenuModel + * + * This function combines g_menu_link_iter_next() with + * g_menu_link_iter_get_name() and g_menu_link_iter_get_value(). + * + * First the iterator is advanced to the next (possibly first) link. + * If that fails, then %FALSE is returned and there are no other effects. + * + * If successful, @out_link and @value are set to the name and #GMenuModel + * of the link that has just been advanced to. At this point, + * g_menu_link_iter_get_name() and g_menu_link_iter_get_value() will return the + * same values again. + * + * The value returned in @out_link remains valid for as long as the iterator + * remains at the current position. The value returned in @value must + * be unreffed using g_object_unref() when it is no longer in use. + * + * Returns: %TRUE on success, or %FALSE if there is no additional link + * + * Since: 2.32 + */ +gboolean +g_menu_link_iter_get_next (GMenuLinkIter *iter, + const gchar **out_link, + GMenuModel **value) +{ + const gchar *name; + + if (iter->priv->value) + { + g_object_unref (iter->priv->value); + iter->priv->value = NULL; + } + + iter->priv->valid = G_MENU_LINK_ITER_GET_CLASS (iter) + ->get_next (iter, &name, &iter->priv->value); + + if (iter->priv->valid) + { + g_assert (name != NULL); + + iter->priv->name = g_quark_from_string (name); + if (out_link) + *out_link = g_quark_to_string (iter->priv->name); + + if (value) + *value = g_object_ref (iter->priv->value); + } + + return iter->priv->valid; +} + +/** + * g_menu_link_iter_next: + * @iter: a #GMenuLinkIter + * + * Attempts to advance the iterator to the next (possibly first) + * link. + * + * %TRUE is returned on success, or %FALSE if there are no more links. + * + * You must call this function when you first acquire the iterator to + * advance it to the first link (and determine if the first link exists + * at all). + * + * Returns: %TRUE on success, or %FALSE when there are no more links + * + * Since: 2.32 + */ +gboolean +g_menu_link_iter_next (GMenuLinkIter *iter) +{ + return g_menu_link_iter_get_next (iter, NULL, NULL); +} + +/** + * g_menu_link_iter_get_name: + * @iter: a #GMenuLinkIter + * + * Gets the name of the link at the current iterator position. + * + * The iterator is not advanced. + * + * Returns: the type of the link + * + * Since: 2.32 + */ +const gchar * +g_menu_link_iter_get_name (GMenuLinkIter *iter) +{ + g_return_val_if_fail (iter->priv->valid, 0); + + return g_quark_to_string (iter->priv->name); +} + +/** + * g_menu_link_iter_get_value: + * @iter: a #GMenuLinkIter + * + * Gets the linked #GMenuModel at the current iterator position. + * + * The iterator is not advanced. + * + * Returns: (transfer full): the #GMenuModel that is linked to + * + * Since: 2.32 + */ +GMenuModel * +g_menu_link_iter_get_value (GMenuLinkIter *iter) +{ + g_return_val_if_fail (iter->priv->valid, NULL); + + return g_object_ref (iter->priv->value); +} + +static void +g_menu_link_iter_finalize (GObject *object) +{ + GMenuLinkIter *iter = G_MENU_LINK_ITER (object); + + if (iter->priv->value) + g_object_unref (iter->priv->value); + + G_OBJECT_CLASS (g_menu_link_iter_parent_class) + ->finalize (object); +} + +static void +g_menu_link_iter_init (GMenuLinkIter *iter) +{ + iter->priv = g_menu_link_iter_get_instance_private (iter); +} + +static void +g_menu_link_iter_class_init (GMenuLinkIterClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_menu_link_iter_finalize; +} diff --git a/gio/gmenumodel.h b/gio/gmenumodel.h new file mode 100644 index 0000000..34c8d0f --- /dev/null +++ b/gio/gmenumodel.h @@ -0,0 +1,305 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_MENU_MODEL_H__ +#define __G_MENU_MODEL_H__ + +#include + +#include + +G_BEGIN_DECLS + +/** + * G_MENU_ATTRIBUTE_ACTION: + * + * The menu item attribute which holds the action name of the item. Action + * names are namespaced with an identifier for the action group in which the + * action resides. For example, "win." for window-specific actions and "app." + * for application-wide actions. + * + * See also g_menu_model_get_item_attribute() and g_menu_item_set_attribute(). + * + * Since: 2.32 + **/ +#define G_MENU_ATTRIBUTE_ACTION "action" + +/** + * G_MENU_ATTRIBUTE_ACTION_NAMESPACE: + * + * The menu item attribute that holds the namespace for all action names in + * menus that are linked from this item. + * + * Since: 2.36 + **/ +#define G_MENU_ATTRIBUTE_ACTION_NAMESPACE "action-namespace" + +/** + * G_MENU_ATTRIBUTE_TARGET: + * + * The menu item attribute which holds the target with which the item's action + * will be activated. + * + * See also g_menu_item_set_action_and_target() + * + * Since: 2.32 + **/ +#define G_MENU_ATTRIBUTE_TARGET "target" + +/** + * G_MENU_ATTRIBUTE_LABEL: + * + * The menu item attribute which holds the label of the item. + * + * Since: 2.32 + **/ +#define G_MENU_ATTRIBUTE_LABEL "label" + +/** + * G_MENU_ATTRIBUTE_ICON: + * + * The menu item attribute which holds the icon of the item. + * + * The icon is stored in the format returned by g_icon_serialize(). + * + * This attribute is intended only to represent 'noun' icons such as + * favicons for a webpage, or application icons. It should not be used + * for 'verbs' (ie: stock icons). + * + * Since: 2.38 + **/ +#define G_MENU_ATTRIBUTE_ICON "icon" + +/** + * G_MENU_LINK_SUBMENU: + * + * The name of the link that associates a menu item with a submenu. + * + * See also g_menu_item_set_link(). + * + * Since: 2.32 + **/ +#define G_MENU_LINK_SUBMENU "submenu" + +/** + * G_MENU_LINK_SECTION: + * + * The name of the link that associates a menu item with a section. The linked + * menu will usually be shown in place of the menu item, using the item's label + * as a header. + * + * See also g_menu_item_set_link(). + * + * Since: 2.32 + **/ +#define G_MENU_LINK_SECTION "section" + +#define G_TYPE_MENU_MODEL (g_menu_model_get_type ()) +#define G_MENU_MODEL(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_MENU_MODEL, GMenuModel)) +#define G_MENU_MODEL_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_MENU_MODEL, GMenuModelClass)) +#define G_IS_MENU_MODEL(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_MENU_MODEL)) +#define G_IS_MENU_MODEL_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_MENU_MODEL)) +#define G_MENU_MODEL_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_MENU_MODEL, GMenuModelClass)) + +typedef struct _GMenuModelPrivate GMenuModelPrivate; +typedef struct _GMenuModelClass GMenuModelClass; + +typedef struct _GMenuAttributeIterPrivate GMenuAttributeIterPrivate; +typedef struct _GMenuAttributeIterClass GMenuAttributeIterClass; +typedef struct _GMenuAttributeIter GMenuAttributeIter; + +typedef struct _GMenuLinkIterPrivate GMenuLinkIterPrivate; +typedef struct _GMenuLinkIterClass GMenuLinkIterClass; +typedef struct _GMenuLinkIter GMenuLinkIter; + +struct _GMenuModel +{ + GObject parent_instance; + GMenuModelPrivate *priv; +}; + +/** + * GMenuModelClass::get_item_attributes: + * @model: the #GMenuModel to query + * @item_index: The #GMenuItem to query + * @attributes: (out) (element-type utf8 GLib.Variant): Attributes on the item + * + * Gets all the attributes associated with the item in the menu model. + */ +/** + * GMenuModelClass::get_item_links: + * @model: the #GMenuModel to query + * @item_index: The #GMenuItem to query + * @links: (out) (element-type utf8 Gio.MenuModel): Links from the item + * + * Gets all the links associated with the item in the menu model. + */ +struct _GMenuModelClass +{ + GObjectClass parent_class; + + gboolean (*is_mutable) (GMenuModel *model); + gint (*get_n_items) (GMenuModel *model); + void (*get_item_attributes) (GMenuModel *model, + gint item_index, + GHashTable **attributes); + GMenuAttributeIter * (*iterate_item_attributes) (GMenuModel *model, + gint item_index); + GVariant * (*get_item_attribute_value) (GMenuModel *model, + gint item_index, + const gchar *attribute, + const GVariantType *expected_type); + void (*get_item_links) (GMenuModel *model, + gint item_index, + GHashTable **links); + GMenuLinkIter * (*iterate_item_links) (GMenuModel *model, + gint item_index); + GMenuModel * (*get_item_link) (GMenuModel *model, + gint item_index, + const gchar *link); +}; + +GLIB_AVAILABLE_IN_2_32 +GType g_menu_model_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +gboolean g_menu_model_is_mutable (GMenuModel *model); +GLIB_AVAILABLE_IN_2_32 +gint g_menu_model_get_n_items (GMenuModel *model); + +GLIB_AVAILABLE_IN_2_32 +GMenuAttributeIter * g_menu_model_iterate_item_attributes (GMenuModel *model, + gint item_index); +GLIB_AVAILABLE_IN_2_32 +GVariant * g_menu_model_get_item_attribute_value (GMenuModel *model, + gint item_index, + const gchar *attribute, + const GVariantType *expected_type); +GLIB_AVAILABLE_IN_2_32 +gboolean g_menu_model_get_item_attribute (GMenuModel *model, + gint item_index, + const gchar *attribute, + const gchar *format_string, + ...); +GLIB_AVAILABLE_IN_2_32 +GMenuLinkIter * g_menu_model_iterate_item_links (GMenuModel *model, + gint item_index); +GLIB_AVAILABLE_IN_2_32 +GMenuModel * g_menu_model_get_item_link (GMenuModel *model, + gint item_index, + const gchar *link); + +GLIB_AVAILABLE_IN_2_32 +void g_menu_model_items_changed (GMenuModel *model, + gint position, + gint removed, + gint added); + + +#define G_TYPE_MENU_ATTRIBUTE_ITER (g_menu_attribute_iter_get_type ()) +#define G_MENU_ATTRIBUTE_ITER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_MENU_ATTRIBUTE_ITER, GMenuAttributeIter)) +#define G_MENU_ATTRIBUTE_ITER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_MENU_ATTRIBUTE_ITER, GMenuAttributeIterClass)) +#define G_IS_MENU_ATTRIBUTE_ITER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_MENU_ATTRIBUTE_ITER)) +#define G_IS_MENU_ATTRIBUTE_ITER_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_MENU_ATTRIBUTE_ITER)) +#define G_MENU_ATTRIBUTE_ITER_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_MENU_ATTRIBUTE_ITER, GMenuAttributeIterClass)) + +struct _GMenuAttributeIter +{ + GObject parent_instance; + GMenuAttributeIterPrivate *priv; +}; + +struct _GMenuAttributeIterClass +{ + GObjectClass parent_class; + + gboolean (*get_next) (GMenuAttributeIter *iter, + const gchar **out_name, + GVariant **value); +}; + +GLIB_AVAILABLE_IN_2_32 +GType g_menu_attribute_iter_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +gboolean g_menu_attribute_iter_get_next (GMenuAttributeIter *iter, + const gchar **out_name, + GVariant **value); +GLIB_AVAILABLE_IN_2_32 +gboolean g_menu_attribute_iter_next (GMenuAttributeIter *iter); +GLIB_AVAILABLE_IN_2_32 +const gchar * g_menu_attribute_iter_get_name (GMenuAttributeIter *iter); +GLIB_AVAILABLE_IN_2_32 +GVariant * g_menu_attribute_iter_get_value (GMenuAttributeIter *iter); + + +#define G_TYPE_MENU_LINK_ITER (g_menu_link_iter_get_type ()) +#define G_MENU_LINK_ITER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_MENU_LINK_ITER, GMenuLinkIter)) +#define G_MENU_LINK_ITER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_MENU_LINK_ITER, GMenuLinkIterClass)) +#define G_IS_MENU_LINK_ITER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_MENU_LINK_ITER)) +#define G_IS_MENU_LINK_ITER_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_MENU_LINK_ITER)) +#define G_MENU_LINK_ITER_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_MENU_LINK_ITER, GMenuLinkIterClass)) + +struct _GMenuLinkIter +{ + GObject parent_instance; + GMenuLinkIterPrivate *priv; +}; + +struct _GMenuLinkIterClass +{ + GObjectClass parent_class; + + gboolean (*get_next) (GMenuLinkIter *iter, + const gchar **out_link, + GMenuModel **value); +}; + +GLIB_AVAILABLE_IN_2_32 +GType g_menu_link_iter_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +gboolean g_menu_link_iter_get_next (GMenuLinkIter *iter, + const gchar **out_link, + GMenuModel **value); +GLIB_AVAILABLE_IN_2_32 +gboolean g_menu_link_iter_next (GMenuLinkIter *iter); +GLIB_AVAILABLE_IN_2_32 +const gchar * g_menu_link_iter_get_name (GMenuLinkIter *iter); +GLIB_AVAILABLE_IN_2_32 +GMenuModel * g_menu_link_iter_get_value (GMenuLinkIter *iter); + +G_END_DECLS + +#endif /* __G_MENU_MODEL_H__ */ diff --git a/gio/gmount.c b/gio/gmount.c new file mode 100644 index 0000000..8dfa1d7 --- /dev/null +++ b/gio/gmount.c @@ -0,0 +1,1060 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#include "config.h" + +#include + +#include "gmount.h" +#include "gmountprivate.h" +#include "gthemedicon.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gmount + * @short_description: Mount management + * @include: gio/gio.h + * @see_also: GVolume, GUnixMountEntry, GUnixMountPoint + * + * The #GMount interface represents user-visible mounts. Note, when + * porting from GnomeVFS, #GMount is the moral equivalent of #GnomeVFSVolume. + * + * #GMount is a "mounted" filesystem that you can access. Mounted is in + * quotes because it's not the same as a unix mount, it might be a gvfs + * mount, but you can still access the files on it if you use GIO. Might or + * might not be related to a volume object. + * + * Unmounting a #GMount instance is an asynchronous operation. For + * more information about asynchronous operations, see #GAsyncResult + * and #GTask. To unmount a #GMount instance, first call + * g_mount_unmount_with_operation() with (at least) the #GMount instance and a + * #GAsyncReadyCallback. The callback will be fired when the + * operation has resolved (either with success or failure), and a + * #GAsyncResult structure will be passed to the callback. That + * callback should then call g_mount_unmount_with_operation_finish() with the #GMount + * and the #GAsyncResult data to see if the operation was completed + * successfully. If an @error is present when g_mount_unmount_with_operation_finish() + * is called, then it will be filled with any error information. + **/ + +typedef GMountIface GMountInterface; +G_DEFINE_INTERFACE (GMount, g_mount, G_TYPE_OBJECT) + +static void +g_mount_default_init (GMountInterface *iface) +{ + /** + * GMount::changed: + * @mount: the object on which the signal is emitted + * + * Emitted when the mount has been changed. + **/ + g_signal_new (I_("changed"), + G_TYPE_MOUNT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountIface, changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + /** + * GMount::unmounted: + * @mount: the object on which the signal is emitted + * + * This signal is emitted when the #GMount have been + * unmounted. If the recipient is holding references to the + * object they should release them so the object can be + * finalized. + **/ + g_signal_new (I_("unmounted"), + G_TYPE_MOUNT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountIface, unmounted), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + /** + * GMount::pre-unmount: + * @mount: the object on which the signal is emitted + * + * This signal may be emitted when the #GMount is about to be + * unmounted. + * + * This signal depends on the backend and is only emitted if + * GIO was used to unmount. + * + * Since: 2.22 + **/ + g_signal_new (I_("pre-unmount"), + G_TYPE_MOUNT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountIface, pre_unmount), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); +} + +/** + * g_mount_get_root: + * @mount: a #GMount. + * + * Gets the root directory on @mount. + * + * Returns: (transfer full): a #GFile. + * The returned object should be unreffed with + * g_object_unref() when no longer needed. + **/ +GFile * +g_mount_get_root (GMount *mount) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + return (* iface->get_root) (mount); +} + +/** + * g_mount_get_default_location: + * @mount: a #GMount. + * + * Gets the default location of @mount. The default location of the given + * @mount is a path that reflects the main entry point for the user (e.g. + * the home directory, or the root of the volume). + * + * Returns: (transfer full): a #GFile. + * The returned object should be unreffed with + * g_object_unref() when no longer needed. + **/ +GFile * +g_mount_get_default_location (GMount *mount) +{ + GMountIface *iface; + GFile *file; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + /* Fallback to get_root when default_location () is not available */ + if (iface->get_default_location) + file = (* iface->get_default_location) (mount); + else + file = (* iface->get_root) (mount); + + return file; +} + +/** + * g_mount_get_name: + * @mount: a #GMount. + * + * Gets the name of @mount. + * + * Returns: the name for the given @mount. + * The returned string should be freed with g_free() + * when no longer needed. + **/ +char * +g_mount_get_name (GMount *mount) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + return (* iface->get_name) (mount); +} + +/** + * g_mount_get_icon: + * @mount: a #GMount. + * + * Gets the icon for @mount. + * + * Returns: (transfer full): a #GIcon. + * The returned object should be unreffed with + * g_object_unref() when no longer needed. + **/ +GIcon * +g_mount_get_icon (GMount *mount) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + return (* iface->get_icon) (mount); +} + + +/** + * g_mount_get_symbolic_icon: + * @mount: a #GMount. + * + * Gets the symbolic icon for @mount. + * + * Returns: (transfer full): a #GIcon. + * The returned object should be unreffed with + * g_object_unref() when no longer needed. + * + * Since: 2.34 + **/ +GIcon * +g_mount_get_symbolic_icon (GMount *mount) +{ + GMountIface *iface; + GIcon *ret; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + if (iface->get_symbolic_icon != NULL) + ret = iface->get_symbolic_icon (mount); + else + ret = g_themed_icon_new_with_default_fallbacks ("folder-remote-symbolic"); + + return ret; +} + +/** + * g_mount_get_uuid: + * @mount: a #GMount. + * + * Gets the UUID for the @mount. The reference is typically based on + * the file system UUID for the mount in question and should be + * considered an opaque string. Returns %NULL if there is no UUID + * available. + * + * Returns: (nullable) (transfer full): the UUID for @mount or %NULL if no UUID + * can be computed. + * The returned string should be freed with g_free() + * when no longer needed. + **/ +char * +g_mount_get_uuid (GMount *mount) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + return (* iface->get_uuid) (mount); +} + +/** + * g_mount_get_volume: + * @mount: a #GMount. + * + * Gets the volume for the @mount. + * + * Returns: (transfer full) (nullable): a #GVolume or %NULL if @mount is not + * associated with a volume. + * The returned object should be unreffed with + * g_object_unref() when no longer needed. + **/ +GVolume * +g_mount_get_volume (GMount *mount) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + return (* iface->get_volume) (mount); +} + +/** + * g_mount_get_drive: + * @mount: a #GMount. + * + * Gets the drive for the @mount. + * + * This is a convenience method for getting the #GVolume and then + * using that object to get the #GDrive. + * + * Returns: (transfer full) (nullable): a #GDrive or %NULL if @mount is not + * associated with a volume or a drive. + * The returned object should be unreffed with + * g_object_unref() when no longer needed. + **/ +GDrive * +g_mount_get_drive (GMount *mount) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + return (* iface->get_drive) (mount); +} + +/** + * g_mount_can_unmount: + * @mount: a #GMount. + * + * Checks if @mount can be unmounted. + * + * Returns: %TRUE if the @mount can be unmounted. + **/ +gboolean +g_mount_can_unmount (GMount *mount) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); + + iface = G_MOUNT_GET_IFACE (mount); + + return (* iface->can_unmount) (mount); +} + +/** + * g_mount_can_eject: + * @mount: a #GMount. + * + * Checks if @mount can be ejected. + * + * Returns: %TRUE if the @mount can be ejected. + **/ +gboolean +g_mount_can_eject (GMount *mount) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); + + iface = G_MOUNT_GET_IFACE (mount); + + return (* iface->can_eject) (mount); +} + +/** + * g_mount_unmount: + * @mount: a #GMount. + * @flags: flags affecting the operation + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data passed to @callback. + * + * Unmounts a mount. This is an asynchronous operation, and is + * finished by calling g_mount_unmount_finish() with the @mount + * and #GAsyncResult data returned in the @callback. + * + * Deprecated: 2.22: Use g_mount_unmount_with_operation() instead. + **/ +void +g_mount_unmount (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GMountIface *iface; + + g_return_if_fail (G_IS_MOUNT (mount)); + + iface = G_MOUNT_GET_IFACE (mount); + + if (iface->unmount == NULL) + { + g_task_report_new_error (mount, callback, user_data, + g_mount_unmount_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for mount objects that + * don't implement unmount. */ + _("mount doesn’t implement “unmountâ€")); + return; + } + + (* iface->unmount) (mount, flags, cancellable, callback, user_data); +} + +/** + * g_mount_unmount_finish: + * @mount: a #GMount. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes unmounting a mount. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise. + * + * Deprecated: 2.22: Use g_mount_unmount_with_operation_finish() instead. + **/ +gboolean +g_mount_unmount_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_mount_unmount_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_MOUNT_GET_IFACE (mount); + return (* iface->unmount_finish) (mount, result, error); +} + + +/** + * g_mount_eject: + * @mount: a #GMount. + * @flags: flags affecting the unmount if required for eject + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data passed to @callback. + * + * Ejects a mount. This is an asynchronous operation, and is + * finished by calling g_mount_eject_finish() with the @mount + * and #GAsyncResult data returned in the @callback. + * + * Deprecated: 2.22: Use g_mount_eject_with_operation() instead. + **/ +void +g_mount_eject (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GMountIface *iface; + + g_return_if_fail (G_IS_MOUNT (mount)); + + iface = G_MOUNT_GET_IFACE (mount); + + if (iface->eject == NULL) + { + g_task_report_new_error (mount, callback, user_data, + g_mount_eject_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for mount objects that + * don't implement eject. */ + _("mount doesn’t implement “ejectâ€")); + return; + } + + (* iface->eject) (mount, flags, cancellable, callback, user_data); +} + +/** + * g_mount_eject_finish: + * @mount: a #GMount. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes ejecting a mount. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise. + * + * Deprecated: 2.22: Use g_mount_eject_with_operation_finish() instead. + **/ +gboolean +g_mount_eject_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_mount_eject_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_MOUNT_GET_IFACE (mount); + return (* iface->eject_finish) (mount, result, error); +} + +/** + * g_mount_unmount_with_operation: + * @mount: a #GMount. + * @flags: flags affecting the operation + * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid + * user interaction. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data passed to @callback. + * + * Unmounts a mount. This is an asynchronous operation, and is + * finished by calling g_mount_unmount_with_operation_finish() with the @mount + * and #GAsyncResult data returned in the @callback. + * + * Since: 2.22 + **/ +void +g_mount_unmount_with_operation (GMount *mount, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GMountIface *iface; + + g_return_if_fail (G_IS_MOUNT (mount)); + + iface = G_MOUNT_GET_IFACE (mount); + + if (iface->unmount == NULL && iface->unmount_with_operation == NULL) + { + g_task_report_new_error (mount, callback, user_data, + g_mount_unmount_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for mount objects that + * don't implement any of unmount or unmount_with_operation. */ + _("mount doesn’t implement “unmount†or “unmount_with_operationâ€")); + return; + } + + if (iface->unmount_with_operation != NULL) + (* iface->unmount_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data); + else + (* iface->unmount) (mount, flags, cancellable, callback, user_data); +} + +/** + * g_mount_unmount_with_operation_finish: + * @mount: a #GMount. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes unmounting a mount. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise. + * + * Since: 2.22 + **/ +gboolean +g_mount_unmount_with_operation_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_mount_unmount_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_MOUNT_GET_IFACE (mount); + if (iface->unmount_with_operation_finish != NULL) + return (* iface->unmount_with_operation_finish) (mount, result, error); + else + return (* iface->unmount_finish) (mount, result, error); +} + + +/** + * g_mount_eject_with_operation: + * @mount: a #GMount. + * @flags: flags affecting the unmount if required for eject + * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid + * user interaction. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data passed to @callback. + * + * Ejects a mount. This is an asynchronous operation, and is + * finished by calling g_mount_eject_with_operation_finish() with the @mount + * and #GAsyncResult data returned in the @callback. + * + * Since: 2.22 + **/ +void +g_mount_eject_with_operation (GMount *mount, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GMountIface *iface; + + g_return_if_fail (G_IS_MOUNT (mount)); + + iface = G_MOUNT_GET_IFACE (mount); + + if (iface->eject == NULL && iface->eject_with_operation == NULL) + { + g_task_report_new_error (mount, callback, user_data, + g_mount_eject_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for mount objects that + * don't implement any of eject or eject_with_operation. */ + _("mount doesn’t implement “eject†or “eject_with_operationâ€")); + return; + } + + if (iface->eject_with_operation != NULL) + (* iface->eject_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data); + else + (* iface->eject) (mount, flags, cancellable, callback, user_data); +} + +/** + * g_mount_eject_with_operation_finish: + * @mount: a #GMount. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes ejecting a mount. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise. + * + * Since: 2.22 + **/ +gboolean +g_mount_eject_with_operation_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_mount_eject_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_MOUNT_GET_IFACE (mount); + if (iface->eject_with_operation_finish != NULL) + return (* iface->eject_with_operation_finish) (mount, result, error); + else + return (* iface->eject_finish) (mount, result, error); +} + +/** + * g_mount_remount: + * @mount: a #GMount. + * @flags: flags affecting the operation + * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid + * user interaction. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL. + * @user_data: user data passed to @callback. + * + * Remounts a mount. This is an asynchronous operation, and is + * finished by calling g_mount_remount_finish() with the @mount + * and #GAsyncResults data returned in the @callback. + * + * Remounting is useful when some setting affecting the operation + * of the volume has been changed, as these may need a remount to + * take affect. While this is semantically equivalent with unmounting + * and then remounting not all backends might need to actually be + * unmounted. + **/ +void +g_mount_remount (GMount *mount, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GMountIface *iface; + + g_return_if_fail (G_IS_MOUNT (mount)); + + iface = G_MOUNT_GET_IFACE (mount); + + if (iface->remount == NULL) + { + g_task_report_new_error (mount, callback, user_data, + g_mount_remount, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for mount objects that + * don't implement remount. */ + _("mount doesn’t implement “remountâ€")); + return; + } + + (* iface->remount) (mount, flags, mount_operation, cancellable, callback, user_data); +} + +/** + * g_mount_remount_finish: + * @mount: a #GMount. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes remounting a mount. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * Returns: %TRUE if the mount was successfully remounted. %FALSE otherwise. + **/ +gboolean +g_mount_remount_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_mount_remount)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_MOUNT_GET_IFACE (mount); + return (* iface->remount_finish) (mount, result, error); +} + +/** + * g_mount_guess_content_type: + * @mount: a #GMount + * @force_rescan: Whether to force a rescan of the content. + * Otherwise a cached result will be used if available + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback + * @user_data: user data passed to @callback + * + * Tries to guess the type of content stored on @mount. Returns one or + * more textual identifiers of well-known content types (typically + * prefixed with "x-content/"), e.g. x-content/image-dcf for camera + * memory cards. See the + * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec) + * specification for more on x-content types. + * + * This is an asynchronous operation (see + * g_mount_guess_content_type_sync() for the synchronous version), and + * is finished by calling g_mount_guess_content_type_finish() with the + * @mount and #GAsyncResult data returned in the @callback. + * + * Since: 2.18 + */ +void +g_mount_guess_content_type (GMount *mount, + gboolean force_rescan, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GMountIface *iface; + + g_return_if_fail (G_IS_MOUNT (mount)); + + iface = G_MOUNT_GET_IFACE (mount); + + if (iface->guess_content_type == NULL) + { + g_task_report_new_error (mount, callback, user_data, + g_mount_guess_content_type, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for mount objects that + * don't implement content type guessing. */ + _("mount doesn’t implement content type guessing")); + return; + } + + (* iface->guess_content_type) (mount, force_rescan, cancellable, callback, user_data); +} + +/** + * g_mount_guess_content_type_finish: + * @mount: a #GMount + * @result: a #GAsyncResult + * @error: a #GError location to store the error occurring, or %NULL to + * ignore + * + * Finishes guessing content types of @mount. If any errors occurred + * during the operation, @error will be set to contain the errors and + * %FALSE will be returned. In particular, you may get an + * %G_IO_ERROR_NOT_SUPPORTED if the mount does not support content + * guessing. + * + * Returns: (transfer full) (element-type utf8): a %NULL-terminated array of content types or %NULL on error. + * Caller should free this array with g_strfreev() when done with it. + * + * Since: 2.18 + **/ +gchar ** +g_mount_guess_content_type_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + else if (g_async_result_is_tagged (result, g_mount_guess_content_type)) + return g_task_propagate_pointer (G_TASK (result), error); + + iface = G_MOUNT_GET_IFACE (mount); + return (* iface->guess_content_type_finish) (mount, result, error); +} + +/** + * g_mount_guess_content_type_sync: + * @mount: a #GMount + * @force_rescan: Whether to force a rescan of the content. + * Otherwise a cached result will be used if available + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @error: a #GError location to store the error occurring, or %NULL to + * ignore + * + * Tries to guess the type of content stored on @mount. Returns one or + * more textual identifiers of well-known content types (typically + * prefixed with "x-content/"), e.g. x-content/image-dcf for camera + * memory cards. See the + * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec) + * specification for more on x-content types. + * + * This is a synchronous operation and as such may block doing IO; + * see g_mount_guess_content_type() for the asynchronous version. + * + * Returns: (transfer full) (element-type utf8): a %NULL-terminated array of content types or %NULL on error. + * Caller should free this array with g_strfreev() when done with it. + * + * Since: 2.18 + */ +char ** +g_mount_guess_content_type_sync (GMount *mount, + gboolean force_rescan, + GCancellable *cancellable, + GError **error) +{ + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + + if (iface->guess_content_type_sync == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for mount objects that + * don't implement content type guessing. */ + _("mount doesn’t implement synchronous content type guessing")); + + return NULL; + } + + return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error); +} + +G_LOCK_DEFINE_STATIC (priv_lock); + +/* only access this structure when holding priv_lock */ +typedef struct +{ + gint shadow_ref_count; +} GMountPrivate; + +static void +free_private (GMountPrivate *private) +{ + G_LOCK (priv_lock); + g_free (private); + G_UNLOCK (priv_lock); +} + +/* may only be called when holding priv_lock */ +static GMountPrivate * +get_private (GMount *mount) +{ + GMountPrivate *private; + + private = g_object_get_data (G_OBJECT (mount), "g-mount-private"); + if (G_LIKELY (private != NULL)) + goto out; + + private = g_new0 (GMountPrivate, 1); + g_object_set_data_full (G_OBJECT (mount), + "g-mount-private", + private, + (GDestroyNotify) free_private); + + out: + return private; +} + +/** + * g_mount_is_shadowed: + * @mount: A #GMount. + * + * Determines if @mount is shadowed. Applications or libraries should + * avoid displaying @mount in the user interface if it is shadowed. + * + * A mount is said to be shadowed if there exists one or more user + * visible objects (currently #GMount objects) with a root that is + * inside the root of @mount. + * + * One application of shadow mounts is when exposing a single file + * system that is used to address several logical volumes. In this + * situation, a #GVolumeMonitor implementation would create two + * #GVolume objects (for example, one for the camera functionality of + * the device and one for a SD card reader on the device) with + * activation URIs `gphoto2://[usb:001,002]/store1/` + * and `gphoto2://[usb:001,002]/store2/`. When the + * underlying mount (with root + * `gphoto2://[usb:001,002]/`) is mounted, said + * #GVolumeMonitor implementation would create two #GMount objects + * (each with their root matching the corresponding volume activation + * root) that would shadow the original mount. + * + * The proxy monitor in GVfs 2.26 and later, automatically creates and + * manage shadow mounts (and shadows the underlying mount) if the + * activation root on a #GVolume is set. + * + * Returns: %TRUE if @mount is shadowed. + * + * Since: 2.20 + **/ +gboolean +g_mount_is_shadowed (GMount *mount) +{ + GMountPrivate *priv; + gboolean ret; + + g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); + + G_LOCK (priv_lock); + priv = get_private (mount); + ret = (priv->shadow_ref_count > 0); + G_UNLOCK (priv_lock); + + return ret; +} + +/** + * g_mount_shadow: + * @mount: A #GMount. + * + * Increments the shadow count on @mount. Usually used by + * #GVolumeMonitor implementations when creating a shadow mount for + * @mount, see g_mount_is_shadowed() for more information. The caller + * will need to emit the #GMount::changed signal on @mount manually. + * + * Since: 2.20 + **/ +void +g_mount_shadow (GMount *mount) +{ + GMountPrivate *priv; + + g_return_if_fail (G_IS_MOUNT (mount)); + + G_LOCK (priv_lock); + priv = get_private (mount); + priv->shadow_ref_count += 1; + G_UNLOCK (priv_lock); +} + +/** + * g_mount_unshadow: + * @mount: A #GMount. + * + * Decrements the shadow count on @mount. Usually used by + * #GVolumeMonitor implementations when destroying a shadow mount for + * @mount, see g_mount_is_shadowed() for more information. The caller + * will need to emit the #GMount::changed signal on @mount manually. + * + * Since: 2.20 + **/ +void +g_mount_unshadow (GMount *mount) +{ + GMountPrivate *priv; + + g_return_if_fail (G_IS_MOUNT (mount)); + + G_LOCK (priv_lock); + priv = get_private (mount); + priv->shadow_ref_count -= 1; + if (priv->shadow_ref_count < 0) + g_warning ("Shadow ref count on GMount is negative"); + G_UNLOCK (priv_lock); +} + +/** + * g_mount_get_sort_key: + * @mount: A #GMount. + * + * Gets the sort key for @mount, if any. + * + * Returns: (nullable): Sorting key for @mount or %NULL if no such key is available. + * + * Since: 2.32 + */ +const gchar * +g_mount_get_sort_key (GMount *mount) +{ + const gchar *ret = NULL; + GMountIface *iface; + + g_return_val_if_fail (G_IS_MOUNT (mount), NULL); + + iface = G_MOUNT_GET_IFACE (mount); + if (iface->get_sort_key != NULL) + ret = iface->get_sort_key (mount); + + return ret; +} diff --git a/gio/gmount.h b/gio/gmount.h new file mode 100644 index 0000000..c376a61 --- /dev/null +++ b/gio/gmount.h @@ -0,0 +1,276 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#ifndef __G_MOUNT_H__ +#define __G_MOUNT_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_MOUNT (g_mount_get_type ()) +#define G_MOUNT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_MOUNT, GMount)) +#define G_IS_MOUNT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_MOUNT)) +#define G_MOUNT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_MOUNT, GMountIface)) + +typedef struct _GMountIface GMountIface; + +/** + * GMountIface: + * @g_iface: The parent interface. + * @changed: Changed signal that is emitted when the mount's state has changed. + * @unmounted: The unmounted signal that is emitted when the #GMount have been unmounted. If the recipient is holding references to the object they should release them so the object can be finalized. + * @pre_unmount: The ::pre-unmount signal that is emitted when the #GMount will soon be emitted. If the recipient is somehow holding the mount open by keeping an open file on it it should close the file. + * @get_root: Gets a #GFile to the root directory of the #GMount. + * @get_name: Gets a string containing the name of the #GMount. + * @get_icon: Gets a #GIcon for the #GMount. + * @get_uuid: Gets the UUID for the #GMount. The reference is typically based on the file system UUID for the mount in question and should be considered an opaque string. Returns %NULL if there is no UUID available. + * @get_volume: Gets a #GVolume the mount is located on. Returns %NULL if the #GMount is not associated with a #GVolume. + * @get_drive: Gets a #GDrive the volume of the mount is located on. Returns %NULL if the #GMount is not associated with a #GDrive or a #GVolume. This is convenience method for getting the #GVolume and using that to get the #GDrive. + * @can_unmount: Checks if a #GMount can be unmounted. + * @can_eject: Checks if a #GMount can be ejected. + * @unmount: Starts unmounting a #GMount. + * @unmount_finish: Finishes an unmounting operation. + * @eject: Starts ejecting a #GMount. + * @eject_finish: Finishes an eject operation. + * @remount: Starts remounting a #GMount. + * @remount_finish: Finishes a remounting operation. + * @guess_content_type: Starts guessing the type of the content of a #GMount. + * See g_mount_guess_content_type() for more information on content + * type guessing. This operation was added in 2.18. + * @guess_content_type_finish: Finishes a content type guessing operation. Added in 2.18. + * @guess_content_type_sync: Synchronous variant of @guess_content_type. Added in 2.18 + * @unmount_with_operation: Starts unmounting a #GMount using a #GMountOperation. Since 2.22. + * @unmount_with_operation_finish: Finishes an unmounting operation using a #GMountOperation. Since 2.22. + * @eject_with_operation: Starts ejecting a #GMount using a #GMountOperation. Since 2.22. + * @eject_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22. + * @get_default_location: Gets a #GFile indication a start location that can be use as the entry point for this mount. Since 2.24. + * @get_sort_key: Gets a key used for sorting #GMount instance or %NULL if no such key exists. Since 2.32. + * @get_symbolic_icon: Gets a symbolic #GIcon for the #GMount. Since 2.34. + * + * Interface for implementing operations for mounts. + **/ +struct _GMountIface +{ + GTypeInterface g_iface; + + /* signals */ + + void (* changed) (GMount *mount); + void (* unmounted) (GMount *mount); + + /* Virtual Table */ + + GFile * (* get_root) (GMount *mount); + char * (* get_name) (GMount *mount); + GIcon * (* get_icon) (GMount *mount); + char * (* get_uuid) (GMount *mount); + GVolume * (* get_volume) (GMount *mount); + GDrive * (* get_drive) (GMount *mount); + gboolean (* can_unmount) (GMount *mount); + gboolean (* can_eject) (GMount *mount); + + void (* unmount) (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* unmount_finish) (GMount *mount, + GAsyncResult *result, + GError **error); + + void (* eject) (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* eject_finish) (GMount *mount, + GAsyncResult *result, + GError **error); + + void (* remount) (GMount *mount, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* remount_finish) (GMount *mount, + GAsyncResult *result, + GError **error); + + void (* guess_content_type) (GMount *mount, + gboolean force_rescan, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gchar ** (* guess_content_type_finish) (GMount *mount, + GAsyncResult *result, + GError **error); + gchar ** (* guess_content_type_sync) (GMount *mount, + gboolean force_rescan, + GCancellable *cancellable, + GError **error); + + /* Signal, not VFunc */ + void (* pre_unmount) (GMount *mount); + + void (* unmount_with_operation) (GMount *mount, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* unmount_with_operation_finish) (GMount *mount, + GAsyncResult *result, + GError **error); + + void (* eject_with_operation) (GMount *mount, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* eject_with_operation_finish) (GMount *mount, + GAsyncResult *result, + GError **error); + GFile * (* get_default_location) (GMount *mount); + + const gchar * (* get_sort_key) (GMount *mount); + GIcon * (* get_symbolic_icon) (GMount *mount); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_mount_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GFile * g_mount_get_root (GMount *mount); +GLIB_AVAILABLE_IN_ALL +GFile * g_mount_get_default_location (GMount *mount); +GLIB_AVAILABLE_IN_ALL +char * g_mount_get_name (GMount *mount); +GLIB_AVAILABLE_IN_ALL +GIcon * g_mount_get_icon (GMount *mount); +GLIB_AVAILABLE_IN_ALL +GIcon * g_mount_get_symbolic_icon (GMount *mount); +GLIB_AVAILABLE_IN_ALL +char * g_mount_get_uuid (GMount *mount); +GLIB_AVAILABLE_IN_ALL +GVolume * g_mount_get_volume (GMount *mount); +GLIB_AVAILABLE_IN_ALL +GDrive * g_mount_get_drive (GMount *mount); +GLIB_AVAILABLE_IN_ALL +gboolean g_mount_can_unmount (GMount *mount); +GLIB_AVAILABLE_IN_ALL +gboolean g_mount_can_eject (GMount *mount); + +GLIB_DEPRECATED_FOR(g_mount_unmount_with_operation) +void g_mount_unmount (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_DEPRECATED_FOR(g_mount_unmount_with_operation_finish) +gboolean g_mount_unmount_finish (GMount *mount, + GAsyncResult *result, + GError **error); + +GLIB_DEPRECATED_FOR(g_mount_eject_with_operation) +void g_mount_eject (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_DEPRECATED_FOR(g_mount_eject_with_operation_finish) +gboolean g_mount_eject_finish (GMount *mount, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_mount_remount (GMount *mount, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_mount_remount_finish (GMount *mount, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_mount_guess_content_type (GMount *mount, + gboolean force_rescan, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gchar ** g_mount_guess_content_type_finish (GMount *mount, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +gchar ** g_mount_guess_content_type_sync (GMount *mount, + gboolean force_rescan, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_mount_is_shadowed (GMount *mount); +GLIB_AVAILABLE_IN_ALL +void g_mount_shadow (GMount *mount); +GLIB_AVAILABLE_IN_ALL +void g_mount_unshadow (GMount *mount); + +GLIB_AVAILABLE_IN_ALL +void g_mount_unmount_with_operation (GMount *mount, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_mount_unmount_with_operation_finish (GMount *mount, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_mount_eject_with_operation (GMount *mount, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_mount_eject_with_operation_finish (GMount *mount, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_mount_get_sort_key (GMount *mount); + +G_END_DECLS + +#endif /* __G_MOUNT_H__ */ diff --git a/gio/gmountoperation.c b/gio/gmountoperation.c new file mode 100644 index 0000000..4bc19a8 --- /dev/null +++ b/gio/gmountoperation.c @@ -0,0 +1,983 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "gmountoperation.h" +#include "gioenumtypes.h" +#include "glibintl.h" +#include "gmarshal-internal.h" + + +/** + * SECTION:gmountoperation + * @short_description: Object used for authentication and user interaction + * @include: gio/gio.h + * + * #GMountOperation provides a mechanism for interacting with the user. + * It can be used for authenticating mountable operations, such as loop + * mounting files, hard drive partitions or server locations. It can + * also be used to ask the user questions or show a list of applications + * preventing unmount or eject operations from completing. + * + * Note that #GMountOperation is used for more than just #GMount + * objects – for example it is also used in g_drive_start() and + * g_drive_stop(). + * + * Users should instantiate a subclass of this that implements all the + * various callbacks to show the required dialogs, such as + * #GtkMountOperation. If no user interaction is desired (for example + * when automounting filesystems at login time), usually %NULL can be + * passed, see each method taking a #GMountOperation for details. + * + * The term ‘TCRYPT’ is used to mean ‘compatible with TrueCrypt and VeraCrypt’. + * [TrueCrypt](https://en.wikipedia.org/wiki/TrueCrypt) is a discontinued system for + * encrypting file containers, partitions or whole disks, typically used with Windows. + * [VeraCrypt](https://www.veracrypt.fr/) is a maintained fork of TrueCrypt with various + * improvements and auditing fixes. + */ + +enum { + ASK_PASSWORD, + ASK_QUESTION, + REPLY, + ABORTED, + SHOW_PROCESSES, + SHOW_UNMOUNT_PROGRESS, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +struct _GMountOperationPrivate { + char *password; + char *user; + char *domain; + gboolean anonymous; + GPasswordSave password_save; + int choice; + gboolean hidden_volume; + gboolean system_volume; + guint pim; +}; + +enum { + PROP_0, + PROP_USERNAME, + PROP_PASSWORD, + PROP_ANONYMOUS, + PROP_DOMAIN, + PROP_PASSWORD_SAVE, + PROP_CHOICE, + PROP_IS_TCRYPT_HIDDEN_VOLUME, + PROP_IS_TCRYPT_SYSTEM_VOLUME, + PROP_PIM +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GMountOperation, g_mount_operation, G_TYPE_OBJECT) + +static void +g_mount_operation_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GMountOperation *operation; + + operation = G_MOUNT_OPERATION (object); + + switch (prop_id) + { + case PROP_USERNAME: + g_mount_operation_set_username (operation, + g_value_get_string (value)); + break; + + case PROP_PASSWORD: + g_mount_operation_set_password (operation, + g_value_get_string (value)); + break; + + case PROP_ANONYMOUS: + g_mount_operation_set_anonymous (operation, + g_value_get_boolean (value)); + break; + + case PROP_DOMAIN: + g_mount_operation_set_domain (operation, + g_value_get_string (value)); + break; + + case PROP_PASSWORD_SAVE: + g_mount_operation_set_password_save (operation, + g_value_get_enum (value)); + break; + + case PROP_CHOICE: + g_mount_operation_set_choice (operation, + g_value_get_int (value)); + break; + + case PROP_IS_TCRYPT_HIDDEN_VOLUME: + g_mount_operation_set_is_tcrypt_hidden_volume (operation, + g_value_get_boolean (value)); + break; + + case PROP_IS_TCRYPT_SYSTEM_VOLUME: + g_mount_operation_set_is_tcrypt_system_volume (operation, + g_value_get_boolean (value)); + break; + + case PROP_PIM: + g_mount_operation_set_pim (operation, + g_value_get_uint (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +g_mount_operation_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GMountOperation *operation; + GMountOperationPrivate *priv; + + operation = G_MOUNT_OPERATION (object); + priv = operation->priv; + + switch (prop_id) + { + case PROP_USERNAME: + g_value_set_string (value, priv->user); + break; + + case PROP_PASSWORD: + g_value_set_string (value, priv->password); + break; + + case PROP_ANONYMOUS: + g_value_set_boolean (value, priv->anonymous); + break; + + case PROP_DOMAIN: + g_value_set_string (value, priv->domain); + break; + + case PROP_PASSWORD_SAVE: + g_value_set_enum (value, priv->password_save); + break; + + case PROP_CHOICE: + g_value_set_int (value, priv->choice); + break; + + case PROP_IS_TCRYPT_HIDDEN_VOLUME: + g_value_set_boolean (value, priv->hidden_volume); + break; + + case PROP_IS_TCRYPT_SYSTEM_VOLUME: + g_value_set_boolean (value, priv->system_volume); + break; + + case PROP_PIM: + g_value_set_uint (value, priv->pim); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +g_mount_operation_finalize (GObject *object) +{ + GMountOperation *operation; + GMountOperationPrivate *priv; + + operation = G_MOUNT_OPERATION (object); + + priv = operation->priv; + + g_free (priv->password); + g_free (priv->user); + g_free (priv->domain); + + G_OBJECT_CLASS (g_mount_operation_parent_class)->finalize (object); +} + +static gboolean +reply_non_handled_in_idle (gpointer data) +{ + GMountOperation *op = data; + + g_mount_operation_reply (op, G_MOUNT_OPERATION_UNHANDLED); + return G_SOURCE_REMOVE; +} + +static void +ask_password (GMountOperation *op, + const char *message, + const char *default_user, + const char *default_domain, + GAskPasswordFlags flags) +{ + g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + reply_non_handled_in_idle, + g_object_ref (op), + g_object_unref); +} + +static void +ask_question (GMountOperation *op, + const char *message, + const char *choices[]) +{ + g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + reply_non_handled_in_idle, + g_object_ref (op), + g_object_unref); +} + +static void +show_processes (GMountOperation *op, + const gchar *message, + GArray *processes, + const gchar *choices[]) +{ + g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + reply_non_handled_in_idle, + g_object_ref (op), + g_object_unref); +} + +static void +show_unmount_progress (GMountOperation *op, + const gchar *message, + gint64 time_left, + gint64 bytes_left) +{ + /* nothing to do */ +} + +static void +g_mount_operation_class_init (GMountOperationClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = g_mount_operation_finalize; + object_class->get_property = g_mount_operation_get_property; + object_class->set_property = g_mount_operation_set_property; + + klass->ask_password = ask_password; + klass->ask_question = ask_question; + klass->show_processes = show_processes; + klass->show_unmount_progress = show_unmount_progress; + + /** + * GMountOperation::ask-password: + * @op: a #GMountOperation requesting a password. + * @message: string containing a message to display to the user. + * @default_user: string containing the default user name. + * @default_domain: string containing the default domain. + * @flags: a set of #GAskPasswordFlags. + * + * Emitted when a mount operation asks the user for a password. + * + * If the message contains a line break, the first line should be + * presented as a heading. For example, it may be used as the + * primary text in a #GtkMessageDialog. + */ + signals[ASK_PASSWORD] = + g_signal_new (I_("ask-password"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountOperationClass, ask_password), + NULL, NULL, + _g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGS, + G_TYPE_NONE, 4, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ASK_PASSWORD_FLAGS); + g_signal_set_va_marshaller (signals[ASK_PASSWORD], + G_TYPE_FROM_CLASS (object_class), + _g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGSv); + + /** + * GMountOperation::ask-question: + * @op: a #GMountOperation asking a question. + * @message: string containing a message to display to the user. + * @choices: an array of strings for each possible choice. + * + * Emitted when asking the user a question and gives a list of + * choices for the user to choose from. + * + * If the message contains a line break, the first line should be + * presented as a heading. For example, it may be used as the + * primary text in a #GtkMessageDialog. + */ + signals[ASK_QUESTION] = + g_signal_new (I_("ask-question"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountOperationClass, ask_question), + NULL, NULL, + _g_cclosure_marshal_VOID__STRING_BOXED, + G_TYPE_NONE, 2, + G_TYPE_STRING, G_TYPE_STRV); + g_signal_set_va_marshaller (signals[ASK_QUESTION], + G_TYPE_FROM_CLASS (object_class), + _g_cclosure_marshal_VOID__STRING_BOXEDv); + + /** + * GMountOperation::reply: + * @op: a #GMountOperation. + * @result: a #GMountOperationResult indicating how the request was handled + * + * Emitted when the user has replied to the mount operation. + */ + signals[REPLY] = + g_signal_new (I_("reply"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountOperationClass, reply), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_MOUNT_OPERATION_RESULT); + + /** + * GMountOperation::aborted: + * + * Emitted by the backend when e.g. a device becomes unavailable + * while a mount operation is in progress. + * + * Implementations of GMountOperation should handle this signal + * by dismissing open password dialogs. + * + * Since: 2.20 + */ + signals[ABORTED] = + g_signal_new (I_("aborted"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountOperationClass, aborted), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + /** + * GMountOperation::show-processes: + * @op: a #GMountOperation. + * @message: string containing a message to display to the user. + * @processes: (element-type GPid): an array of #GPid for processes + * blocking the operation. + * @choices: an array of strings for each possible choice. + * + * Emitted when one or more processes are blocking an operation + * e.g. unmounting/ejecting a #GMount or stopping a #GDrive. + * + * Note that this signal may be emitted several times to update the + * list of blocking processes as processes close files. The + * application should only respond with g_mount_operation_reply() to + * the latest signal (setting #GMountOperation:choice to the choice + * the user made). + * + * If the message contains a line break, the first line should be + * presented as a heading. For example, it may be used as the + * primary text in a #GtkMessageDialog. + * + * Since: 2.22 + */ + signals[SHOW_PROCESSES] = + g_signal_new (I_("show-processes"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountOperationClass, show_processes), + NULL, NULL, + _g_cclosure_marshal_VOID__STRING_BOXED_BOXED, + G_TYPE_NONE, 3, + G_TYPE_STRING, G_TYPE_ARRAY, G_TYPE_STRV); + g_signal_set_va_marshaller (signals[SHOW_PROCESSES], + G_TYPE_FROM_CLASS (object_class), + _g_cclosure_marshal_VOID__STRING_BOXED_BOXEDv); + + /** + * GMountOperation::show-unmount-progress: + * @op: a #GMountOperation: + * @message: string containing a message to display to the user + * @time_left: the estimated time left before the operation completes, + * in microseconds, or -1 + * @bytes_left: the amount of bytes to be written before the operation + * completes (or -1 if such amount is not known), or zero if the operation + * is completed + * + * Emitted when an unmount operation has been busy for more than some time + * (typically 1.5 seconds). + * + * When unmounting or ejecting a volume, the kernel might need to flush + * pending data in its buffers to the volume stable storage, and this operation + * can take a considerable amount of time. This signal may be emitted several + * times as long as the unmount operation is outstanding, and then one + * last time when the operation is completed, with @bytes_left set to zero. + * + * Implementations of GMountOperation should handle this signal by + * showing an UI notification, and then dismiss it, or show another notification + * of completion, when @bytes_left reaches zero. + * + * If the message contains a line break, the first line should be + * presented as a heading. For example, it may be used as the + * primary text in a #GtkMessageDialog. + * + * Since: 2.34 + */ + signals[SHOW_UNMOUNT_PROGRESS] = + g_signal_new (I_("show-unmount-progress"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GMountOperationClass, show_unmount_progress), + NULL, NULL, + _g_cclosure_marshal_VOID__STRING_INT64_INT64, + G_TYPE_NONE, 3, + G_TYPE_STRING, G_TYPE_INT64, G_TYPE_INT64); + g_signal_set_va_marshaller (signals[SHOW_UNMOUNT_PROGRESS], + G_TYPE_FROM_CLASS (object_class), + _g_cclosure_marshal_VOID__STRING_INT64_INT64v); + + /** + * GMountOperation:username: + * + * The user name that is used for authentication when carrying out + * the mount operation. + */ + g_object_class_install_property (object_class, + PROP_USERNAME, + g_param_spec_string ("username", + P_("Username"), + P_("The user name"), + NULL, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GMountOperation:password: + * + * The password that is used for authentication when carrying out + * the mount operation. + */ + g_object_class_install_property (object_class, + PROP_PASSWORD, + g_param_spec_string ("password", + P_("Password"), + P_("The password"), + NULL, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GMountOperation:anonymous: + * + * Whether to use an anonymous user when authenticating. + */ + g_object_class_install_property (object_class, + PROP_ANONYMOUS, + g_param_spec_boolean ("anonymous", + P_("Anonymous"), + P_("Whether to use an anonymous user"), + FALSE, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GMountOperation:domain: + * + * The domain to use for the mount operation. + */ + g_object_class_install_property (object_class, + PROP_DOMAIN, + g_param_spec_string ("domain", + P_("Domain"), + P_("The domain of the mount operation"), + NULL, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GMountOperation:password-save: + * + * Determines if and how the password information should be saved. + */ + g_object_class_install_property (object_class, + PROP_PASSWORD_SAVE, + g_param_spec_enum ("password-save", + P_("Password save"), + P_("How passwords should be saved"), + G_TYPE_PASSWORD_SAVE, + G_PASSWORD_SAVE_NEVER, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GMountOperation:choice: + * + * The index of the user's choice when a question is asked during the + * mount operation. See the #GMountOperation::ask-question signal. + */ + g_object_class_install_property (object_class, + PROP_CHOICE, + g_param_spec_int ("choice", + P_("Choice"), + P_("The users choice"), + 0, G_MAXINT, 0, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GMountOperation:is-tcrypt-hidden-volume: + * + * Whether the device to be unlocked is a TCRYPT hidden volume. + * See [the VeraCrypt documentation](https://www.veracrypt.fr/en/Hidden%20Volume.html). + * + * Since: 2.58 + */ + g_object_class_install_property (object_class, + PROP_IS_TCRYPT_HIDDEN_VOLUME, + g_param_spec_boolean ("is-tcrypt-hidden-volume", + P_("TCRYPT Hidden Volume"), + P_("Whether to unlock a TCRYPT hidden volume. See https://www.veracrypt.fr/en/Hidden%20Volume.html."), + FALSE, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GMountOperation:is-tcrypt-system-volume: + * + * Whether the device to be unlocked is a TCRYPT system volume. + * In this context, a system volume is a volume with a bootloader + * and operating system installed. This is only supported for Windows + * operating systems. For further documentation, see + * [the VeraCrypt documentation](https://www.veracrypt.fr/en/System%20Encryption.html). + * + * Since: 2.58 + */ + g_object_class_install_property (object_class, + PROP_IS_TCRYPT_SYSTEM_VOLUME, + g_param_spec_boolean ("is-tcrypt-system-volume", + P_("TCRYPT System Volume"), + P_("Whether to unlock a TCRYPT system volume. Only supported for unlocking Windows system volumes. See https://www.veracrypt.fr/en/System%20Encryption.html."), + FALSE, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GMountOperation:pim: + * + * The VeraCrypt PIM value, when unlocking a VeraCrypt volume. See + * [the VeraCrypt documentation](https://www.veracrypt.fr/en/Personal%20Iterations%20Multiplier%20(PIM).html). + * + * Since: 2.58 + */ + g_object_class_install_property (object_class, + PROP_PIM, + g_param_spec_uint ("pim", + P_("PIM"), + P_("The VeraCrypt PIM value"), + 0, G_MAXUINT, 0, + G_PARAM_READWRITE| + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); +} + +static void +g_mount_operation_init (GMountOperation *operation) +{ + operation->priv = g_mount_operation_get_instance_private (operation); +} + +/** + * g_mount_operation_new: + * + * Creates a new mount operation. + * + * Returns: a #GMountOperation. + **/ +GMountOperation * +g_mount_operation_new (void) +{ + return g_object_new (G_TYPE_MOUNT_OPERATION, NULL); +} + +/** + * g_mount_operation_get_username: + * @op: a #GMountOperation. + * + * Get the user name from the mount operation. + * + * Returns: (nullable): a string containing the user name. + **/ +const char * +g_mount_operation_get_username (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL); + return op->priv->user; +} + +/** + * g_mount_operation_set_username: + * @op: a #GMountOperation. + * @username: (nullable): input username. + * + * Sets the user name within @op to @username. + **/ +void +g_mount_operation_set_username (GMountOperation *op, + const char *username) +{ + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + g_free (op->priv->user); + op->priv->user = g_strdup (username); + g_object_notify (G_OBJECT (op), "username"); +} + +/** + * g_mount_operation_get_password: + * @op: a #GMountOperation. + * + * Gets a password from the mount operation. + * + * Returns: (nullable): a string containing the password within @op. + **/ +const char * +g_mount_operation_get_password (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL); + return op->priv->password; +} + +/** + * g_mount_operation_set_password: + * @op: a #GMountOperation. + * @password: (nullable): password to set. + * + * Sets the mount operation's password to @password. + * + **/ +void +g_mount_operation_set_password (GMountOperation *op, + const char *password) +{ + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + g_free (op->priv->password); + op->priv->password = g_strdup (password); + g_object_notify (G_OBJECT (op), "password"); +} + +/** + * g_mount_operation_get_anonymous: + * @op: a #GMountOperation. + * + * Check to see whether the mount operation is being used + * for an anonymous user. + * + * Returns: %TRUE if mount operation is anonymous. + **/ +gboolean +g_mount_operation_get_anonymous (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE); + return op->priv->anonymous; +} + +/** + * g_mount_operation_set_anonymous: + * @op: a #GMountOperation. + * @anonymous: boolean value. + * + * Sets the mount operation to use an anonymous user if @anonymous is %TRUE. + **/ +void +g_mount_operation_set_anonymous (GMountOperation *op, + gboolean anonymous) +{ + GMountOperationPrivate *priv; + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + priv = op->priv; + + if (priv->anonymous != anonymous) + { + priv->anonymous = anonymous; + g_object_notify (G_OBJECT (op), "anonymous"); + } +} + +/** + * g_mount_operation_get_domain: + * @op: a #GMountOperation. + * + * Gets the domain of the mount operation. + * + * Returns: (nullable): a string set to the domain. + **/ +const char * +g_mount_operation_get_domain (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL); + return op->priv->domain; +} + +/** + * g_mount_operation_set_domain: + * @op: a #GMountOperation. + * @domain: (nullable): the domain to set. + * + * Sets the mount operation's domain. + **/ +void +g_mount_operation_set_domain (GMountOperation *op, + const char *domain) +{ + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + g_free (op->priv->domain); + op->priv->domain = g_strdup (domain); + g_object_notify (G_OBJECT (op), "domain"); +} + +/** + * g_mount_operation_get_password_save: + * @op: a #GMountOperation. + * + * Gets the state of saving passwords for the mount operation. + * + * Returns: a #GPasswordSave flag. + **/ + +GPasswordSave +g_mount_operation_get_password_save (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), G_PASSWORD_SAVE_NEVER); + return op->priv->password_save; +} + +/** + * g_mount_operation_set_password_save: + * @op: a #GMountOperation. + * @save: a set of #GPasswordSave flags. + * + * Sets the state of saving passwords for the mount operation. + * + **/ +void +g_mount_operation_set_password_save (GMountOperation *op, + GPasswordSave save) +{ + GMountOperationPrivate *priv; + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + priv = op->priv; + + if (priv->password_save != save) + { + priv->password_save = save; + g_object_notify (G_OBJECT (op), "password-save"); + } +} + +/** + * g_mount_operation_get_choice: + * @op: a #GMountOperation. + * + * Gets a choice from the mount operation. + * + * Returns: an integer containing an index of the user's choice from + * the choice's list, or `0`. + **/ +int +g_mount_operation_get_choice (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), 0); + return op->priv->choice; +} + +/** + * g_mount_operation_set_choice: + * @op: a #GMountOperation. + * @choice: an integer. + * + * Sets a default choice for the mount operation. + **/ +void +g_mount_operation_set_choice (GMountOperation *op, + int choice) +{ + GMountOperationPrivate *priv; + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + priv = op->priv; + if (priv->choice != choice) + { + priv->choice = choice; + g_object_notify (G_OBJECT (op), "choice"); + } +} + +/** + * g_mount_operation_get_is_tcrypt_hidden_volume: + * @op: a #GMountOperation. + * + * Check to see whether the mount operation is being used + * for a TCRYPT hidden volume. + * + * Returns: %TRUE if mount operation is for hidden volume. + * + * Since: 2.58 + **/ +gboolean +g_mount_operation_get_is_tcrypt_hidden_volume (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE); + return op->priv->hidden_volume; +} + +/** + * g_mount_operation_set_is_tcrypt_hidden_volume: + * @op: a #GMountOperation. + * @hidden_volume: boolean value. + * + * Sets the mount operation to use a hidden volume if @hidden_volume is %TRUE. + * + * Since: 2.58 + **/ +void +g_mount_operation_set_is_tcrypt_hidden_volume (GMountOperation *op, + gboolean hidden_volume) +{ + GMountOperationPrivate *priv; + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + priv = op->priv; + + if (priv->hidden_volume != hidden_volume) + { + priv->hidden_volume = hidden_volume; + g_object_notify (G_OBJECT (op), "is-tcrypt-hidden-volume"); + } +} + +/** + * g_mount_operation_get_is_tcrypt_system_volume: + * @op: a #GMountOperation. + * + * Check to see whether the mount operation is being used + * for a TCRYPT system volume. + * + * Returns: %TRUE if mount operation is for system volume. + * + * Since: 2.58 + **/ +gboolean +g_mount_operation_get_is_tcrypt_system_volume (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE); + return op->priv->system_volume; +} + +/** + * g_mount_operation_set_is_tcrypt_system_volume: + * @op: a #GMountOperation. + * @system_volume: boolean value. + * + * Sets the mount operation to use a system volume if @system_volume is %TRUE. + * + * Since: 2.58 + **/ +void +g_mount_operation_set_is_tcrypt_system_volume (GMountOperation *op, + gboolean system_volume) +{ + GMountOperationPrivate *priv; + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + priv = op->priv; + + if (priv->system_volume != system_volume) + { + priv->system_volume = system_volume; + g_object_notify (G_OBJECT (op), "is-tcrypt-system-volume"); + } +} + +/** + * g_mount_operation_get_pim: + * @op: a #GMountOperation. + * + * Gets a PIM from the mount operation. + * + * Returns: The VeraCrypt PIM within @op. + * + * Since: 2.58 + **/ +guint +g_mount_operation_get_pim (GMountOperation *op) +{ + g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), 0); + return op->priv->pim; +} + +/** + * g_mount_operation_set_pim: + * @op: a #GMountOperation. + * @pim: an unsigned integer. + * + * Sets the mount operation's PIM to @pim. + * + * Since: 2.58 + **/ +void +g_mount_operation_set_pim (GMountOperation *op, + guint pim) +{ + GMountOperationPrivate *priv; + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + priv = op->priv; + if (priv->pim != pim) + { + priv->pim = pim; + g_object_notify (G_OBJECT (op), "pim"); + } +} + +/** + * g_mount_operation_reply: + * @op: a #GMountOperation + * @result: a #GMountOperationResult + * + * Emits the #GMountOperation::reply signal. + **/ +void +g_mount_operation_reply (GMountOperation *op, + GMountOperationResult result) +{ + g_return_if_fail (G_IS_MOUNT_OPERATION (op)); + g_signal_emit (op, signals[REPLY], 0, result); +} diff --git a/gio/gmountoperation.h b/gio/gmountoperation.h new file mode 100644 index 0000000..56db2a5 --- /dev/null +++ b/gio/gmountoperation.h @@ -0,0 +1,177 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_MOUNT_OPERATION_H__ +#define __G_MOUNT_OPERATION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_MOUNT_OPERATION (g_mount_operation_get_type ()) +#define G_MOUNT_OPERATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_MOUNT_OPERATION, GMountOperation)) +#define G_MOUNT_OPERATION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_MOUNT_OPERATION, GMountOperationClass)) +#define G_IS_MOUNT_OPERATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_MOUNT_OPERATION)) +#define G_IS_MOUNT_OPERATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_MOUNT_OPERATION)) +#define G_MOUNT_OPERATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_MOUNT_OPERATION, GMountOperationClass)) + +/** + * GMountOperation: + * + * Class for providing authentication methods for mounting operations, + * such as mounting a file locally, or authenticating with a server. + **/ +typedef struct _GMountOperationClass GMountOperationClass; +typedef struct _GMountOperationPrivate GMountOperationPrivate; + +struct _GMountOperation +{ + GObject parent_instance; + + GMountOperationPrivate *priv; +}; + +struct _GMountOperationClass +{ + GObjectClass parent_class; + + /* signals: */ + + void (* ask_password) (GMountOperation *op, + const char *message, + const char *default_user, + const char *default_domain, + GAskPasswordFlags flags); + + /** + * GMountOperationClass::ask_question: + * @op: a #GMountOperation + * @message: string containing a message to display to the user + * @choices: (array zero-terminated=1) (element-type utf8): an array of + * strings for each possible choice + * + * Virtual implementation of #GMountOperation::ask-question. + */ + void (* ask_question) (GMountOperation *op, + const char *message, + const char *choices[]); + + void (* reply) (GMountOperation *op, + GMountOperationResult result); + + void (* aborted) (GMountOperation *op); + + /** + * GMountOperationClass::show_processes: + * @op: a #GMountOperation + * @message: string containing a message to display to the user + * @processes: (element-type GPid): an array of #GPid for processes blocking + * the operation + * @choices: (array zero-terminated=1) (element-type utf8): an array of + * strings for each possible choice + * + * Virtual implementation of #GMountOperation::show-processes. + * + * Since: 2.22 + */ + void (* show_processes) (GMountOperation *op, + const gchar *message, + GArray *processes, + const gchar *choices[]); + + void (* show_unmount_progress) (GMountOperation *op, + const gchar *message, + gint64 time_left, + gint64 bytes_left); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); + void (*_g_reserved7) (void); + void (*_g_reserved8) (void); + void (*_g_reserved9) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_mount_operation_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GMountOperation * g_mount_operation_new (void); + +GLIB_AVAILABLE_IN_ALL +const char * g_mount_operation_get_username (GMountOperation *op); +GLIB_AVAILABLE_IN_ALL +void g_mount_operation_set_username (GMountOperation *op, + const char *username); +GLIB_AVAILABLE_IN_ALL +const char * g_mount_operation_get_password (GMountOperation *op); +GLIB_AVAILABLE_IN_ALL +void g_mount_operation_set_password (GMountOperation *op, + const char *password); +GLIB_AVAILABLE_IN_ALL +gboolean g_mount_operation_get_anonymous (GMountOperation *op); +GLIB_AVAILABLE_IN_ALL +void g_mount_operation_set_anonymous (GMountOperation *op, + gboolean anonymous); +GLIB_AVAILABLE_IN_ALL +const char * g_mount_operation_get_domain (GMountOperation *op); +GLIB_AVAILABLE_IN_ALL +void g_mount_operation_set_domain (GMountOperation *op, + const char *domain); +GLIB_AVAILABLE_IN_ALL +GPasswordSave g_mount_operation_get_password_save (GMountOperation *op); +GLIB_AVAILABLE_IN_ALL +void g_mount_operation_set_password_save (GMountOperation *op, + GPasswordSave save); +GLIB_AVAILABLE_IN_ALL +int g_mount_operation_get_choice (GMountOperation *op); +GLIB_AVAILABLE_IN_ALL +void g_mount_operation_set_choice (GMountOperation *op, + int choice); +GLIB_AVAILABLE_IN_ALL +void g_mount_operation_reply (GMountOperation *op, + GMountOperationResult result); +GLIB_AVAILABLE_IN_2_58 +gboolean g_mount_operation_get_is_tcrypt_hidden_volume (GMountOperation *op); +GLIB_AVAILABLE_IN_2_58 +void g_mount_operation_set_is_tcrypt_hidden_volume (GMountOperation *op, + gboolean hidden_volume); +GLIB_AVAILABLE_IN_2_58 +gboolean g_mount_operation_get_is_tcrypt_system_volume (GMountOperation *op); +GLIB_AVAILABLE_IN_2_58 +void g_mount_operation_set_is_tcrypt_system_volume (GMountOperation *op, + gboolean system_volume); +GLIB_AVAILABLE_IN_2_58 +guint g_mount_operation_get_pim (GMountOperation *op); +GLIB_AVAILABLE_IN_2_58 +void g_mount_operation_set_pim (GMountOperation *op, + guint pim); + +G_END_DECLS + +#endif /* __G_MOUNT_OPERATION_H__ */ diff --git a/gio/gmountprivate.h b/gio/gmountprivate.h new file mode 100644 index 0000000..cbe917c --- /dev/null +++ b/gio/gmountprivate.h @@ -0,0 +1,33 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_VOLUMEPRIV_H__ +#define __G_VOLUMEPRIV_H__ + +#include + +G_BEGIN_DECLS + +GMount *_g_mount_get_for_mount_path (const char *mount_path, + GCancellable *cancellable); + +G_END_DECLS + +#endif /* __G_VOLUMEPRIV_H__ */ diff --git a/gio/gnativesocketaddress.c b/gio/gnativesocketaddress.c new file mode 100644 index 0000000..ac2ce62 --- /dev/null +++ b/gio/gnativesocketaddress.c @@ -0,0 +1,163 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#include +#include +#include + +#include "gnativesocketaddress.h" +#include "gnetworkingprivate.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gnativesocketaddress + * @short_description: Native GSocketAddress + * @include: gio/gio.h + * + * A socket address of some unknown native type. + */ + +/** + * GNativeSocketAddress: + * + * A socket address, corresponding to a general struct + * sockadd address of a type not otherwise handled by glib. + */ + +struct _GNativeSocketAddressPrivate +{ + struct sockaddr *sockaddr; + union { + struct sockaddr_storage storage; + struct sockaddr sa; + } storage; + gsize sockaddr_len; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GNativeSocketAddress, g_native_socket_address, G_TYPE_SOCKET_ADDRESS) + +static void +g_native_socket_address_dispose (GObject *object) +{ + GNativeSocketAddress *address = G_NATIVE_SOCKET_ADDRESS (object); + + if (address->priv->sockaddr != &address->priv->storage.sa) + g_free (address->priv->sockaddr); + + G_OBJECT_CLASS (g_native_socket_address_parent_class)->dispose (object); +} + +static GSocketFamily +g_native_socket_address_get_family (GSocketAddress *address) +{ + GNativeSocketAddress *addr; + + g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), 0); + + addr = G_NATIVE_SOCKET_ADDRESS (address); + + return addr->priv->sockaddr->sa_family; +} + +static gssize +g_native_socket_address_get_native_size (GSocketAddress *address) +{ + GNativeSocketAddress *addr; + + g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), 0); + + addr = G_NATIVE_SOCKET_ADDRESS (address); + + return addr->priv->sockaddr_len; +} + +static gboolean +g_native_socket_address_to_native (GSocketAddress *address, + gpointer dest, + gsize destlen, + GError **error) +{ + GNativeSocketAddress *addr; + + g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), FALSE); + + addr = G_NATIVE_SOCKET_ADDRESS (address); + + if (destlen < addr->priv->sockaddr_len) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, + _("Not enough space for socket address")); + return FALSE; + } + + memcpy (dest, addr->priv->sockaddr, addr->priv->sockaddr_len); + return TRUE; +} + +static void +g_native_socket_address_class_init (GNativeSocketAddressClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass); + + gobject_class->dispose = g_native_socket_address_dispose; + + gsocketaddress_class->get_family = g_native_socket_address_get_family; + gsocketaddress_class->to_native = g_native_socket_address_to_native; + gsocketaddress_class->get_native_size = g_native_socket_address_get_native_size; +} + +static void +g_native_socket_address_init (GNativeSocketAddress *address) +{ + address->priv = g_native_socket_address_get_instance_private (address); +} + +/** + * g_native_socket_address_new: + * @native: a native address object + * @len: the length of @native, in bytes + * + * Creates a new #GNativeSocketAddress for @native and @len. + * + * Returns: a new #GNativeSocketAddress + * + * Since: 2.46 + */ +GSocketAddress * +g_native_socket_address_new (gpointer native, + gsize len) +{ + GNativeSocketAddress *addr; + + addr = g_object_new (G_TYPE_NATIVE_SOCKET_ADDRESS, NULL); + + if (len <= sizeof(addr->priv->storage)) + addr->priv->sockaddr = &addr->priv->storage.sa; + else + addr->priv->sockaddr = g_malloc (len); + + memcpy (addr->priv->sockaddr, native, len); + addr->priv->sockaddr_len = len; + return G_SOCKET_ADDRESS (addr); +} diff --git a/gio/gnativesocketaddress.h b/gio/gnativesocketaddress.h new file mode 100644 index 0000000..032cd00 --- /dev/null +++ b/gio/gnativesocketaddress.h @@ -0,0 +1,65 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#ifndef __G_NATIVE_SOCKET_ADDRESS_H__ +#define __G_NATIVE_SOCKET_ADDRESS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_NATIVE_SOCKET_ADDRESS (g_native_socket_address_get_type ()) +#define G_NATIVE_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NATIVE_SOCKET_ADDRESS, GNativeSocketAddress)) +#define G_NATIVE_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NATIVE_SOCKET_ADDRESS, GNativeSocketAddressClass)) +#define G_IS_NATIVE_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NATIVE_SOCKET_ADDRESS)) +#define G_IS_NATIVE_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NATIVE_SOCKET_ADDRESS)) +#define G_NATIVE_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NATIVE_SOCKET_ADDRESS, GNativeSocketAddressClass)) + +typedef struct _GNativeSocketAddressClass GNativeSocketAddressClass; +typedef struct _GNativeSocketAddressPrivate GNativeSocketAddressPrivate; + +struct _GNativeSocketAddress +{ + GSocketAddress parent_instance; + + /*< private >*/ + GNativeSocketAddressPrivate *priv; +}; + +struct _GNativeSocketAddressClass +{ + GSocketAddressClass parent_class; +}; + +GLIB_AVAILABLE_IN_2_46 +GType g_native_socket_address_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_46 +GSocketAddress *g_native_socket_address_new (gpointer native, + gsize len); + +G_END_DECLS + +#endif /* __G_NATIVE_SOCKET_ADDRESS_H__ */ diff --git a/gio/gnativevolumemonitor.c b/gio/gnativevolumemonitor.c new file mode 100644 index 0000000..1997f2e --- /dev/null +++ b/gio/gnativevolumemonitor.c @@ -0,0 +1,50 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include +#include "gnativevolumemonitor.h" + + +G_DEFINE_ABSTRACT_TYPE (GNativeVolumeMonitor, g_native_volume_monitor, G_TYPE_VOLUME_MONITOR) + +static void +g_native_volume_monitor_finalize (GObject *object) +{ + G_OBJECT_CLASS (g_native_volume_monitor_parent_class)->finalize (object); +} + + +static void +g_native_volume_monitor_class_init (GNativeVolumeMonitorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_native_volume_monitor_finalize; +} + + +static void +g_native_volume_monitor_init (GNativeVolumeMonitor *native_monitor) +{ +} diff --git a/gio/gnativevolumemonitor.h b/gio/gnativevolumemonitor.h new file mode 100644 index 0000000..7390547 --- /dev/null +++ b/gio/gnativevolumemonitor.h @@ -0,0 +1,61 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_NATIVE_VOLUME_MONITOR_H__ +#define __G_NATIVE_VOLUME_MONITOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_NATIVE_VOLUME_MONITOR (g_native_volume_monitor_get_type ()) +#define G_NATIVE_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NATIVE_VOLUME_MONITOR, GNativeVolumeMonitor)) +#define G_NATIVE_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NATIVE_VOLUME_MONITOR, GNativeVolumeMonitorClass)) +#define G_IS_NATIVE_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NATIVE_VOLUME_MONITOR)) +#define G_IS_NATIVE_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NATIVE_VOLUME_MONITOR)) + +#define G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME "gio-native-volume-monitor" + +typedef struct _GNativeVolumeMonitor GNativeVolumeMonitor; +typedef struct _GNativeVolumeMonitorClass GNativeVolumeMonitorClass; + +struct _GNativeVolumeMonitor +{ + GVolumeMonitor parent_instance; +}; + +struct _GNativeVolumeMonitorClass +{ + GVolumeMonitorClass parent_class; + + GMount * (* get_mount_for_mount_path) (const char *mount_path, + GCancellable *cancellable); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_native_volume_monitor_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __G_NATIVE_VOLUME_MONITOR_H__ */ diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c new file mode 100644 index 0000000..ef1940a --- /dev/null +++ b/gio/gnetworkaddress.c @@ -0,0 +1,1219 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include +#include "glibintl.h" + +#include +#include "gnetworkaddress.h" +#include "gasyncresult.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "gnetworkingprivate.h" +#include "gproxyaddressenumerator.h" +#include "gresolver.h" +#include "gtask.h" +#include "gsocketaddressenumerator.h" +#include "gioerror.h" +#include "gsocketconnectable.h" + +#include + +/* As recommended by RFC 8305 this is the time it waits for a following + DNS response to come in (ipv4 waiting on ipv6 generally) + */ +#define HAPPY_EYEBALLS_RESOLUTION_DELAY_MS 50 + +/** + * SECTION:gnetworkaddress + * @short_description: A GSocketConnectable for resolving hostnames + * @include: gio/gio.h + * + * #GNetworkAddress provides an easy way to resolve a hostname and + * then attempt to connect to that host, handling the possibility of + * multiple IP addresses and multiple address families. + * + * The enumeration results of resolved addresses *may* be cached as long + * as this object is kept alive which may have unexpected results if + * alive for too long. + * + * See #GSocketConnectable for an example of using the connectable + * interface. + */ + +/** + * GNetworkAddress: + * + * A #GSocketConnectable for resolving a hostname and connecting to + * that host. + */ + +struct _GNetworkAddressPrivate { + gchar *hostname; + guint16 port; + GList *cached_sockaddrs; + gchar *scheme; + + gint64 resolver_serial; +}; + +enum { + PROP_0, + PROP_HOSTNAME, + PROP_PORT, + PROP_SCHEME, +}; + +static void g_network_address_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_network_address_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void g_network_address_connectable_iface_init (GSocketConnectableIface *iface); +static GSocketAddressEnumerator *g_network_address_connectable_enumerate (GSocketConnectable *connectable); +static GSocketAddressEnumerator *g_network_address_connectable_proxy_enumerate (GSocketConnectable *connectable); +static gchar *g_network_address_connectable_to_string (GSocketConnectable *connectable); + +G_DEFINE_TYPE_WITH_CODE (GNetworkAddress, g_network_address, G_TYPE_OBJECT, + G_ADD_PRIVATE (GNetworkAddress) + G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE, + g_network_address_connectable_iface_init)) + +static void +g_network_address_finalize (GObject *object) +{ + GNetworkAddress *addr = G_NETWORK_ADDRESS (object); + + g_free (addr->priv->hostname); + g_free (addr->priv->scheme); + g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref); + + G_OBJECT_CLASS (g_network_address_parent_class)->finalize (object); +} + +static void +g_network_address_class_init (GNetworkAddressClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = g_network_address_set_property; + gobject_class->get_property = g_network_address_get_property; + gobject_class->finalize = g_network_address_finalize; + + g_object_class_install_property (gobject_class, PROP_HOSTNAME, + g_param_spec_string ("hostname", + P_("Hostname"), + P_("Hostname to resolve"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PORT, + g_param_spec_uint ("port", + P_("Port"), + P_("Network port"), + 0, 65535, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_SCHEME, + g_param_spec_string ("scheme", + P_("Scheme"), + P_("URI Scheme"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_network_address_connectable_iface_init (GSocketConnectableIface *connectable_iface) +{ + connectable_iface->enumerate = g_network_address_connectable_enumerate; + connectable_iface->proxy_enumerate = g_network_address_connectable_proxy_enumerate; + connectable_iface->to_string = g_network_address_connectable_to_string; +} + +static void +g_network_address_init (GNetworkAddress *addr) +{ + addr->priv = g_network_address_get_instance_private (addr); +} + +static void +g_network_address_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GNetworkAddress *addr = G_NETWORK_ADDRESS (object); + + switch (prop_id) + { + case PROP_HOSTNAME: + g_free (addr->priv->hostname); + addr->priv->hostname = g_value_dup_string (value); + break; + + case PROP_PORT: + addr->priv->port = g_value_get_uint (value); + break; + + case PROP_SCHEME: + g_free (addr->priv->scheme); + addr->priv->scheme = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_network_address_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GNetworkAddress *addr = G_NETWORK_ADDRESS (object); + + switch (prop_id) + { + case PROP_HOSTNAME: + g_value_set_string (value, addr->priv->hostname); + break; + + case PROP_PORT: + g_value_set_uint (value, addr->priv->port); + break; + + case PROP_SCHEME: + g_value_set_string (value, addr->priv->scheme); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +/* + * inet_addresses_to_inet_socket_addresses: + * @addresses: (transfer full): #GList of #GInetAddress + * + * Returns: (transfer full): #GList of #GInetSocketAddress + */ +static GList * +inet_addresses_to_inet_socket_addresses (GNetworkAddress *addr, + GList *addresses) +{ + GList *a, *socket_addresses = NULL; + + for (a = addresses; a; a = a->next) + { + GSocketAddress *sockaddr = g_inet_socket_address_new (a->data, addr->priv->port); + socket_addresses = g_list_append (socket_addresses, g_steal_pointer (&sockaddr)); + g_object_unref (a->data); + } + + g_list_free (addresses); + return socket_addresses; +} + +/* + * g_network_address_set_cached_addresses: + * @addr: A #GNetworkAddress + * @addresses: (transfer full): List of #GInetAddress or #GInetSocketAddress + * @resolver_serial: Serial of #GResolver used + * + * Consumes @addresses and uses them to replace the current internal list. + */ +static void +g_network_address_set_cached_addresses (GNetworkAddress *addr, + GList *addresses, + guint64 resolver_serial) +{ + g_assert (addresses != NULL); + + if (addr->priv->cached_sockaddrs) + g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref); + + if (G_IS_INET_SOCKET_ADDRESS (addresses->data)) + addr->priv->cached_sockaddrs = g_steal_pointer (&addresses); + else + addr->priv->cached_sockaddrs = inet_addresses_to_inet_socket_addresses (addr, g_steal_pointer (&addresses)); + addr->priv->resolver_serial = resolver_serial; +} + +static gboolean +g_network_address_parse_sockaddr (GNetworkAddress *addr) +{ + GSocketAddress *sockaddr; + + g_assert (addr->priv->cached_sockaddrs == NULL); + + sockaddr = g_inet_socket_address_new_from_string (addr->priv->hostname, + addr->priv->port); + if (sockaddr) + { + addr->priv->cached_sockaddrs = g_list_append (addr->priv->cached_sockaddrs, sockaddr); + return TRUE; + } + else + return FALSE; +} + +/** + * g_network_address_new: + * @hostname: the hostname + * @port: the port + * + * Creates a new #GSocketConnectable for connecting to the given + * @hostname and @port. + * + * Note that depending on the configuration of the machine, a + * @hostname of `localhost` may refer to the IPv4 loopback address + * only, or to both IPv4 and IPv6; use + * g_network_address_new_loopback() to create a #GNetworkAddress that + * is guaranteed to resolve to both addresses. + * + * Returns: (transfer full) (type GNetworkAddress): the new #GNetworkAddress + * + * Since: 2.22 + */ +GSocketConnectable * +g_network_address_new (const gchar *hostname, + guint16 port) +{ + return g_object_new (G_TYPE_NETWORK_ADDRESS, + "hostname", hostname, + "port", port, + NULL); +} + +/** + * g_network_address_new_loopback: + * @port: the port + * + * Creates a new #GSocketConnectable for connecting to the local host + * over a loopback connection to the given @port. This is intended for + * use in connecting to local services which may be running on IPv4 or + * IPv6. + * + * The connectable will return IPv4 and IPv6 loopback addresses, + * regardless of how the host resolves `localhost`. By contrast, + * g_network_address_new() will often only return an IPv4 address when + * resolving `localhost`, and an IPv6 address for `localhost6`. + * + * g_network_address_get_hostname() will always return `localhost` for + * a #GNetworkAddress created with this constructor. + * + * Returns: (transfer full) (type GNetworkAddress): the new #GNetworkAddress + * + * Since: 2.44 + */ +GSocketConnectable * +g_network_address_new_loopback (guint16 port) +{ + GNetworkAddress *addr; + GList *addrs = NULL; + + addr = g_object_new (G_TYPE_NETWORK_ADDRESS, + "hostname", "localhost", + "port", port, + NULL); + + addrs = g_list_append (addrs, g_inet_address_new_loopback (AF_INET6)); + addrs = g_list_append (addrs, g_inet_address_new_loopback (AF_INET)); + g_network_address_set_cached_addresses (addr, g_steal_pointer (&addrs), 0); + + return G_SOCKET_CONNECTABLE (addr); +} + +/** + * g_network_address_parse: + * @host_and_port: the hostname and optionally a port + * @default_port: the default port if not in @host_and_port + * @error: a pointer to a #GError, or %NULL + * + * Creates a new #GSocketConnectable for connecting to the given + * @hostname and @port. May fail and return %NULL in case + * parsing @host_and_port fails. + * + * @host_and_port may be in any of a number of recognised formats; an IPv6 + * address, an IPv4 address, or a domain name (in which case a DNS + * lookup is performed). Quoting with [] is supported for all address + * types. A port override may be specified in the usual way with a + * colon. + * + * If no port is specified in @host_and_port then @default_port will be + * used as the port number to connect to. + * + * In general, @host_and_port is expected to be provided by the user + * (allowing them to give the hostname, and a port override if necessary) + * and @default_port is expected to be provided by the application. + * + * (The port component of @host_and_port can also be specified as a + * service name rather than as a numeric port, but this functionality + * is deprecated, because it depends on the contents of /etc/services, + * which is generally quite sparse on platforms other than Linux.) + * + * Returns: (transfer full) (type GNetworkAddress): the new + * #GNetworkAddress, or %NULL on error + * + * Since: 2.22 + */ +GSocketConnectable * +g_network_address_parse (const gchar *host_and_port, + guint16 default_port, + GError **error) +{ + GSocketConnectable *connectable; + const gchar *port; + guint16 portnum; + gchar *name; + + g_return_val_if_fail (host_and_port != NULL, NULL); + + port = NULL; + if (host_and_port[0] == '[') + /* escaped host part (to allow, eg. "[2001:db8::1]:888") */ + { + const gchar *end; + + end = strchr (host_and_port, ']'); + if (end == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Hostname “%s†contains “[†but not “]â€"), host_and_port); + return NULL; + } + + if (end[1] == '\0') + port = NULL; + else if (end[1] == ':') + port = &end[2]; + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "The ']' character (in hostname '%s') must come at the" + " end or be immediately followed by ':' and a port", + host_and_port); + return NULL; + } + + name = g_strndup (host_and_port + 1, end - host_and_port - 1); + } + + else if ((port = strchr (host_and_port, ':'))) + /* string has a ':' in it */ + { + /* skip ':' */ + port++; + + if (strchr (port, ':')) + /* more than one ':' in string */ + { + /* this is actually an unescaped IPv6 address */ + name = g_strdup (host_and_port); + port = NULL; + } + else + name = g_strndup (host_and_port, port - host_and_port - 1); + } + + else + /* plain hostname, no port */ + name = g_strdup (host_and_port); + + if (port != NULL) + { + if (port[0] == '\0') + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "If a ':' character is given, it must be followed by a " + "port (in hostname '%s').", host_and_port); + g_free (name); + return NULL; + } + + else if ('0' <= port[0] && port[0] <= '9') + { + char *end; + long value; + + value = strtol (port, &end, 10); + if (*end != '\0' || value < 0 || value > G_MAXUINT16) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "Invalid numeric port '%s' specified in hostname '%s'", + port, host_and_port); + g_free (name); + return NULL; + } + + portnum = value; + } + + else + { + struct servent *entry; + + entry = getservbyname (port, "tcp"); + if (entry == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "Unknown service '%s' specified in hostname '%s'", + port, host_and_port); +#ifdef HAVE_ENDSERVENT + endservent (); +#endif + g_free (name); + return NULL; + } + + portnum = g_ntohs (entry->s_port); + +#ifdef HAVE_ENDSERVENT + endservent (); +#endif + } + } + else + { + /* No port in host_and_port */ + portnum = default_port; + } + + connectable = g_network_address_new (name, portnum); + g_free (name); + + return connectable; +} + +/** + * g_network_address_parse_uri: + * @uri: the hostname and optionally a port + * @default_port: The default port if none is found in the URI + * @error: a pointer to a #GError, or %NULL + * + * Creates a new #GSocketConnectable for connecting to the given + * @uri. May fail and return %NULL in case parsing @uri fails. + * + * Using this rather than g_network_address_new() or + * g_network_address_parse() allows #GSocketClient to determine + * when to use application-specific proxy protocols. + * + * Returns: (transfer full) (type GNetworkAddress): the new + * #GNetworkAddress, or %NULL on error + * + * Since: 2.26 + */ +GSocketConnectable * +g_network_address_parse_uri (const gchar *uri, + guint16 default_port, + GError **error) +{ + GSocketConnectable *conn = NULL; + gchar *scheme = NULL; + gchar *hostname = NULL; + gint port; + + if (!g_uri_split_network (uri, G_URI_FLAGS_NONE, + &scheme, &hostname, &port, NULL)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "Invalid URI ‘%s’", uri); + return NULL; + } + + if (port <= 0) + port = default_port; + + conn = g_object_new (G_TYPE_NETWORK_ADDRESS, + "hostname", hostname, + "port", (guint) port, + "scheme", scheme, + NULL); + g_free (scheme); + g_free (hostname); + + return conn; +} + +/** + * g_network_address_get_hostname: + * @addr: a #GNetworkAddress + * + * Gets @addr's hostname. This might be either UTF-8 or ASCII-encoded, + * depending on what @addr was created with. + * + * Returns: @addr's hostname + * + * Since: 2.22 + */ +const gchar * +g_network_address_get_hostname (GNetworkAddress *addr) +{ + g_return_val_if_fail (G_IS_NETWORK_ADDRESS (addr), NULL); + + return addr->priv->hostname; +} + +/** + * g_network_address_get_port: + * @addr: a #GNetworkAddress + * + * Gets @addr's port number + * + * Returns: @addr's port (which may be 0) + * + * Since: 2.22 + */ +guint16 +g_network_address_get_port (GNetworkAddress *addr) +{ + g_return_val_if_fail (G_IS_NETWORK_ADDRESS (addr), 0); + + return addr->priv->port; +} + +/** + * g_network_address_get_scheme: + * @addr: a #GNetworkAddress + * + * Gets @addr's scheme + * + * Returns: (nullable): @addr's scheme (%NULL if not built from URI) + * + * Since: 2.26 + */ +const gchar * +g_network_address_get_scheme (GNetworkAddress *addr) +{ + g_return_val_if_fail (G_IS_NETWORK_ADDRESS (addr), NULL); + + return addr->priv->scheme; +} + +#define G_TYPE_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (_g_network_address_address_enumerator_get_type ()) +#define G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_NETWORK_ADDRESS_ADDRESS_ENUMERATOR, GNetworkAddressAddressEnumerator)) + +typedef enum { + RESOLVE_STATE_NONE = 0, + RESOLVE_STATE_WAITING_ON_IPV4 = 1 << 0, + RESOLVE_STATE_WAITING_ON_IPV6 = 1 << 1, +} ResolveState; + +typedef struct { + GSocketAddressEnumerator parent_instance; + + GNetworkAddress *addr; /* (owned) */ + GList *addresses; /* (owned) (nullable) */ + GList *current_item; /* (unowned) (nullable) */ + GTask *queued_task; /* (owned) (nullable) */ + GTask *waiting_task; /* (owned) (nullable) */ + GError *last_error; /* (owned) (nullable) */ + GSource *wait_source; /* (owned) (nullable) */ + GMainContext *context; /* (owned) (nullable) */ + ResolveState state; +} GNetworkAddressAddressEnumerator; + +typedef struct { + GSocketAddressEnumeratorClass parent_class; + +} GNetworkAddressAddressEnumeratorClass; + +static GType _g_network_address_address_enumerator_get_type (void); +G_DEFINE_TYPE (GNetworkAddressAddressEnumerator, _g_network_address_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR) + +static void +g_network_address_address_enumerator_finalize (GObject *object) +{ + GNetworkAddressAddressEnumerator *addr_enum = + G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (object); + + if (addr_enum->wait_source) + { + g_source_destroy (addr_enum->wait_source); + g_clear_pointer (&addr_enum->wait_source, g_source_unref); + } + g_clear_object (&addr_enum->queued_task); + g_clear_object (&addr_enum->waiting_task); + g_clear_error (&addr_enum->last_error); + g_object_unref (addr_enum->addr); + g_clear_pointer (&addr_enum->context, g_main_context_unref); + g_list_free_full (addr_enum->addresses, g_object_unref); + + G_OBJECT_CLASS (_g_network_address_address_enumerator_parent_class)->finalize (object); +} + +static inline GSocketFamily +get_address_family (GInetSocketAddress *address) +{ + return g_inet_address_get_family (g_inet_socket_address_get_address (address)); +} + +static void +list_split_families (GList *list, + GList **out_ipv4, + GList **out_ipv6) +{ + g_assert (out_ipv4); + g_assert (out_ipv6); + + while (list) + { + GSocketFamily family = get_address_family (list->data); + switch (family) + { + case G_SOCKET_FAMILY_IPV4: + *out_ipv4 = g_list_prepend (*out_ipv4, list->data); + break; + case G_SOCKET_FAMILY_IPV6: + *out_ipv6 = g_list_prepend (*out_ipv6, list->data); + break; + case G_SOCKET_FAMILY_INVALID: + case G_SOCKET_FAMILY_UNIX: + g_assert_not_reached (); + } + + list = g_list_next (list); + } + + *out_ipv4 = g_list_reverse (*out_ipv4); + *out_ipv6 = g_list_reverse (*out_ipv6); +} + +static GList * +list_interleave_families (GList *list1, + GList *list2) +{ + GList *interleaved = NULL; + + while (list1 || list2) + { + if (list1) + { + interleaved = g_list_append (interleaved, list1->data); + list1 = g_list_delete_link (list1, list1); + } + if (list2) + { + interleaved = g_list_append (interleaved, list2->data); + list2 = g_list_delete_link (list2, list2); + } + } + + return interleaved; +} + +/* list_copy_interleaved: + * @list: (transfer container): List to copy + * + * Does a shallow copy of a list with address families interleaved. + * + * For example: + * Input: [ipv6, ipv6, ipv4, ipv4] + * Output: [ipv6, ipv4, ipv6, ipv4] + * + * Returns: (transfer container): A new list + */ +static GList * +list_copy_interleaved (GList *list) +{ + GList *ipv4 = NULL, *ipv6 = NULL; + + list_split_families (list, &ipv4, &ipv6); + return list_interleave_families (ipv6, ipv4); +} + +/* list_concat_interleaved: + * @parent_list: (transfer container): Already existing list + * @current_item: (transfer container): Item after which to resort + * @new_list: (transfer container): New list to be interleaved and concatenated + * + * This differs from g_list_concat() + list_copy_interleaved() in that it sorts + * items in the previous list starting from @current_item and concats the results + * to @parent_list. + * + * Returns: (transfer container): New start of list + */ +static GList * +list_concat_interleaved (GList *parent_list, + GList *current_item, + GList *new_list) +{ + GList *ipv4 = NULL, *ipv6 = NULL, *interleaved, *trailing = NULL; + GSocketFamily last_family = G_SOCKET_FAMILY_IPV4; /* Default to starting with ipv6 */ + + if (current_item) + { + last_family = get_address_family (current_item->data); + + /* Unused addresses will get removed, resorted, then readded */ + trailing = g_list_next (current_item); + current_item->next = NULL; + } + + list_split_families (trailing, &ipv4, &ipv6); + list_split_families (new_list, &ipv4, &ipv6); + g_list_free (new_list); + + if (trailing) + g_list_free (trailing); + + if (last_family == G_SOCKET_FAMILY_IPV4) + interleaved = list_interleave_families (ipv6, ipv4); + else + interleaved = list_interleave_families (ipv4, ipv6); + + return g_list_concat (parent_list, interleaved); +} + +static void +maybe_update_address_cache (GNetworkAddressAddressEnumerator *addr_enum, + GResolver *resolver) +{ + GList *addresses, *p; + + /* Only cache complete results */ + if (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4 || addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV6) + return; + + /* The enumerators list will not necessarily be fully sorted */ + addresses = list_copy_interleaved (addr_enum->addresses); + for (p = addresses; p; p = p->next) + g_object_ref (p->data); + + g_network_address_set_cached_addresses (addr_enum->addr, g_steal_pointer (&addresses), g_resolver_get_serial (resolver)); +} + +static void +g_network_address_address_enumerator_add_addresses (GNetworkAddressAddressEnumerator *addr_enum, + GList *addresses, + GResolver *resolver) +{ + GList *new_addresses = inet_addresses_to_inet_socket_addresses (addr_enum->addr, addresses); + + if (addr_enum->addresses == NULL) + addr_enum->addresses = g_steal_pointer (&new_addresses); + else + addr_enum->addresses = list_concat_interleaved (addr_enum->addresses, addr_enum->current_item, g_steal_pointer (&new_addresses)); + + maybe_update_address_cache (addr_enum, resolver); +} + +static gpointer +copy_object (gconstpointer src, + gpointer user_data) +{ + return g_object_ref (G_OBJECT (src)); +} + +static GSocketAddress * +init_and_query_next_address (GNetworkAddressAddressEnumerator *addr_enum) +{ + GList *next_item; + + if (addr_enum->addresses == NULL) + addr_enum->addresses = g_list_copy_deep (addr_enum->addr->priv->cached_sockaddrs, + copy_object, NULL); + + /* We always want to look at the next item at call time to get the latest results. + That means that sometimes ->next is NULL this call but is valid next call. + */ + if (addr_enum->current_item == NULL) + next_item = addr_enum->current_item = addr_enum->addresses; + else + next_item = g_list_next (addr_enum->current_item); + + if (next_item) + { + addr_enum->current_item = next_item; + return g_object_ref (addr_enum->current_item->data); + } + else + return NULL; +} + +static GSocketAddress * +g_network_address_address_enumerator_next (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GNetworkAddressAddressEnumerator *addr_enum = + G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (enumerator); + + if (addr_enum->addresses == NULL) + { + GNetworkAddress *addr = addr_enum->addr; + GResolver *resolver = g_resolver_get_default (); + gint64 serial = g_resolver_get_serial (resolver); + + if (addr->priv->resolver_serial != 0 && + addr->priv->resolver_serial != serial) + { + /* Resolver has reloaded, discard cached addresses */ + g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref); + addr->priv->cached_sockaddrs = NULL; + } + + if (!addr->priv->cached_sockaddrs) + g_network_address_parse_sockaddr (addr); + if (!addr->priv->cached_sockaddrs) + { + GList *addresses; + + addresses = g_resolver_lookup_by_name (resolver, + addr->priv->hostname, + cancellable, error); + if (!addresses) + { + g_object_unref (resolver); + return NULL; + } + + g_network_address_set_cached_addresses (addr, g_steal_pointer (&addresses), serial); + } + + g_object_unref (resolver); + } + + return init_and_query_next_address (addr_enum); +} + +static void +complete_queued_task (GNetworkAddressAddressEnumerator *addr_enum, + GTask *task, + GError *error) +{ + if (error) + g_task_return_error (task, error); + else + { + GSocketAddress *sockaddr = init_and_query_next_address (addr_enum); + g_task_return_pointer (task, g_steal_pointer (&sockaddr), g_object_unref); + } + g_object_unref (task); +} + +static int +on_address_timeout (gpointer user_data) +{ + GNetworkAddressAddressEnumerator *addr_enum = user_data; + + /* Upon completion it may get unref'd by the owner */ + g_object_ref (addr_enum); + + if (addr_enum->queued_task != NULL) + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task), + g_steal_pointer (&addr_enum->last_error)); + else if (addr_enum->waiting_task != NULL) + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task), + NULL); + + g_clear_pointer (&addr_enum->wait_source, g_source_unref); + g_object_unref (addr_enum); + + return G_SOURCE_REMOVE; +} + +static void +got_ipv6_addresses (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GNetworkAddressAddressEnumerator *addr_enum = user_data; + GResolver *resolver = G_RESOLVER (source_object); + GList *addresses; + GError *error = NULL; + + addr_enum->state ^= RESOLVE_STATE_WAITING_ON_IPV6; + + addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error); + if (!error) + g_network_address_address_enumerator_add_addresses (addr_enum, g_steal_pointer (&addresses), resolver); + else + g_debug ("IPv6 DNS error: %s", error->message); + + /* If ipv4 was first and waiting on us it can stop waiting */ + if (addr_enum->wait_source) + { + g_source_destroy (addr_enum->wait_source); + g_clear_pointer (&addr_enum->wait_source, g_source_unref); + } + + /* If we got an error before ipv4 then let its response handle it. + * If we get ipv6 response first or error second then + * immediately complete the task. + */ + if (error != NULL && !addr_enum->last_error && (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4)) + { + /* ipv6 lookup failed, but ipv4 is still outstanding. wait. */ + addr_enum->last_error = g_steal_pointer (&error); + } + else if (addr_enum->waiting_task != NULL) + { + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task), NULL); + } + else if (addr_enum->queued_task != NULL) + { + GError *task_error = NULL; + + /* If both errored just use the ipv6 one, + but if ipv6 errored and ipv4 didn't we don't error */ + if (error != NULL && addr_enum->last_error) + task_error = g_steal_pointer (&error); + + g_clear_error (&addr_enum->last_error); + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task), + g_steal_pointer (&task_error)); + } + + g_clear_error (&error); + g_object_unref (addr_enum); +} + +static void +got_ipv4_addresses (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GNetworkAddressAddressEnumerator *addr_enum = user_data; + GResolver *resolver = G_RESOLVER (source_object); + GList *addresses; + GError *error = NULL; + + addr_enum->state ^= RESOLVE_STATE_WAITING_ON_IPV4; + + addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error); + if (!error) + g_network_address_address_enumerator_add_addresses (addr_enum, g_steal_pointer (&addresses), resolver); + else + g_debug ("IPv4 DNS error: %s", error->message); + + if (addr_enum->wait_source) + { + g_source_destroy (addr_enum->wait_source); + g_clear_pointer (&addr_enum->wait_source, g_source_unref); + } + + /* If ipv6 already came in and errored then we return. + * If ipv6 returned successfully then we don't need to do anything unless + * another enumeration was waiting on us. + * If ipv6 hasn't come we should wait a short while for it as RFC 8305 suggests. + */ + if (addr_enum->last_error) + { + g_assert (addr_enum->queued_task); + g_clear_error (&addr_enum->last_error); + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task), + g_steal_pointer (&error)); + } + else if (addr_enum->waiting_task != NULL) + { + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task), NULL); + } + else if (addr_enum->queued_task != NULL) + { + addr_enum->last_error = g_steal_pointer (&error); + addr_enum->wait_source = g_timeout_source_new (HAPPY_EYEBALLS_RESOLUTION_DELAY_MS); + g_source_set_callback (addr_enum->wait_source, + on_address_timeout, + addr_enum, NULL); + g_source_attach (addr_enum->wait_source, addr_enum->context); + } + + g_clear_error (&error); + g_object_unref (addr_enum); +} + +static void +g_network_address_address_enumerator_next_async (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GNetworkAddressAddressEnumerator *addr_enum = + G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (enumerator); + GSocketAddress *sockaddr; + GTask *task; + + task = g_task_new (addr_enum, cancellable, callback, user_data); + g_task_set_source_tag (task, g_network_address_address_enumerator_next_async); + + if (addr_enum->addresses == NULL && addr_enum->state == RESOLVE_STATE_NONE) + { + GNetworkAddress *addr = addr_enum->addr; + GResolver *resolver = g_resolver_get_default (); + gint64 serial = g_resolver_get_serial (resolver); + + if (addr->priv->resolver_serial != 0 && + addr->priv->resolver_serial != serial) + { + /* Resolver has reloaded, discard cached addresses */ + g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref); + addr->priv->cached_sockaddrs = NULL; + } + + if (addr->priv->cached_sockaddrs == NULL) + { + if (g_network_address_parse_sockaddr (addr)) + complete_queued_task (addr_enum, task, NULL); + else + { + /* It does not make sense for this to be called multiple + * times before the initial callback has been called */ + g_assert (addr_enum->queued_task == NULL); + + addr_enum->state = RESOLVE_STATE_WAITING_ON_IPV4 | RESOLVE_STATE_WAITING_ON_IPV6; + addr_enum->queued_task = g_steal_pointer (&task); + /* Look up in parallel as per RFC 8305 */ + g_resolver_lookup_by_name_with_flags_async (resolver, + addr->priv->hostname, + G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY, + cancellable, + got_ipv6_addresses, g_object_ref (addr_enum)); + g_resolver_lookup_by_name_with_flags_async (resolver, + addr->priv->hostname, + G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY, + cancellable, + got_ipv4_addresses, g_object_ref (addr_enum)); + } + g_object_unref (resolver); + return; + } + + g_object_unref (resolver); + } + + sockaddr = init_and_query_next_address (addr_enum); + if (sockaddr == NULL && (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4 || + addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV6)) + { + addr_enum->waiting_task = task; + } + else + { + g_task_return_pointer (task, sockaddr, g_object_unref); + g_object_unref (task); + } +} + +static GSocketAddress * +g_network_address_address_enumerator_next_finish (GSocketAddressEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +_g_network_address_address_enumerator_init (GNetworkAddressAddressEnumerator *enumerator) +{ + enumerator->context = g_main_context_ref_thread_default (); +} + +static void +_g_network_address_address_enumerator_class_init (GNetworkAddressAddressEnumeratorClass *addrenum_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (addrenum_class); + GSocketAddressEnumeratorClass *enumerator_class = + G_SOCKET_ADDRESS_ENUMERATOR_CLASS (addrenum_class); + + enumerator_class->next = g_network_address_address_enumerator_next; + enumerator_class->next_async = g_network_address_address_enumerator_next_async; + enumerator_class->next_finish = g_network_address_address_enumerator_next_finish; + object_class->finalize = g_network_address_address_enumerator_finalize; +} + +static GSocketAddressEnumerator * +g_network_address_connectable_enumerate (GSocketConnectable *connectable) +{ + GNetworkAddressAddressEnumerator *addr_enum; + + addr_enum = g_object_new (G_TYPE_NETWORK_ADDRESS_ADDRESS_ENUMERATOR, NULL); + addr_enum->addr = g_object_ref (G_NETWORK_ADDRESS (connectable)); + + return (GSocketAddressEnumerator *)addr_enum; +} + +static GSocketAddressEnumerator * +g_network_address_connectable_proxy_enumerate (GSocketConnectable *connectable) +{ + GNetworkAddress *self = G_NETWORK_ADDRESS (connectable); + GSocketAddressEnumerator *proxy_enum; + gchar *uri; + + uri = g_uri_join (G_URI_FLAGS_NONE, + self->priv->scheme ? self->priv->scheme : "none", + NULL, + self->priv->hostname, + self->priv->port, + "", + NULL, + NULL); + + proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, + "connectable", connectable, + "uri", uri, + NULL); + + g_free (uri); + + return proxy_enum; +} + +static gchar * +g_network_address_connectable_to_string (GSocketConnectable *connectable) +{ + GNetworkAddress *addr; + const gchar *scheme; + guint16 port; + GString *out; /* owned */ + + addr = G_NETWORK_ADDRESS (connectable); + out = g_string_new (""); + + scheme = g_network_address_get_scheme (addr); + if (scheme != NULL) + g_string_append_printf (out, "%s:", scheme); + + g_string_append (out, g_network_address_get_hostname (addr)); + + port = g_network_address_get_port (addr); + if (port != 0) + g_string_append_printf (out, ":%u", port); + + return g_string_free (out, FALSE); +} diff --git a/gio/gnetworkaddress.h b/gio/gnetworkaddress.h new file mode 100644 index 0000000..10bb0b5 --- /dev/null +++ b/gio/gnetworkaddress.h @@ -0,0 +1,80 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_NETWORK_ADDRESS_H__ +#define __G_NETWORK_ADDRESS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_NETWORK_ADDRESS (g_network_address_get_type ()) +#define G_NETWORK_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_ADDRESS, GNetworkAddress)) +#define G_NETWORK_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_ADDRESS, GNetworkAddressClass)) +#define G_IS_NETWORK_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_ADDRESS)) +#define G_IS_NETWORK_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NETWORK_ADDRESS)) +#define G_NETWORK_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NETWORK_ADDRESS, GNetworkAddressClass)) + +typedef struct _GNetworkAddressClass GNetworkAddressClass; +typedef struct _GNetworkAddressPrivate GNetworkAddressPrivate; + +struct _GNetworkAddress +{ + GObject parent_instance; + + /*< private >*/ + GNetworkAddressPrivate *priv; +}; + +struct _GNetworkAddressClass +{ + GObjectClass parent_class; + +}; + +GLIB_AVAILABLE_IN_ALL +GType g_network_address_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketConnectable *g_network_address_new (const gchar *hostname, + guint16 port); +GLIB_AVAILABLE_IN_2_44 +GSocketConnectable *g_network_address_new_loopback (guint16 port); +GLIB_AVAILABLE_IN_ALL +GSocketConnectable *g_network_address_parse (const gchar *host_and_port, + guint16 default_port, + GError **error); +GLIB_AVAILABLE_IN_ALL +GSocketConnectable *g_network_address_parse_uri (const gchar *uri, + guint16 default_port, + GError **error); +GLIB_AVAILABLE_IN_ALL +const gchar *g_network_address_get_hostname (GNetworkAddress *addr); +GLIB_AVAILABLE_IN_ALL +guint16 g_network_address_get_port (GNetworkAddress *addr); +GLIB_AVAILABLE_IN_ALL +const gchar *g_network_address_get_scheme (GNetworkAddress *addr); + + +G_END_DECLS + +#endif /* __G_NETWORK_ADDRESS_H__ */ diff --git a/gio/gnetworking.c b/gio/gnetworking.c new file mode 100644 index 0000000..7bc6d73 --- /dev/null +++ b/gio/gnetworking.c @@ -0,0 +1,76 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gnetworking.h" + +/** + * SECTION:gnetworking + * @title: gnetworking.h + * @short_description: System networking includes + * @include: gio/gnetworking.h + * + * The `` header can be included to get + * various low-level networking-related system headers, automatically + * taking care of certain portability issues for you. + * + * This can be used, for example, if you want to call setsockopt() + * on a #GSocket. + * + * Note that while WinSock has many of the same APIs as the + * traditional UNIX socket API, most of them behave at least slightly + * differently (particularly with respect to error handling). If you + * want your code to work under both UNIX and Windows, you will need + * to take these differences into account. + * + * Also, under GNU libc, certain non-portable functions are only visible + * in the headers if you define %_GNU_SOURCE before including them. Note + * that this symbol must be defined before including any headers, or it + * may not take effect. + */ + +/** + * g_networking_init: + * + * Initializes the platform networking libraries (eg, on Windows, this + * calls WSAStartup()). GLib will call this itself if it is needed, so + * you only need to call it if you directly call system networking + * functions (without calling any GLib networking functions first). + * + * Since: 2.36 + */ +void +g_networking_init (void) +{ +#ifdef G_OS_WIN32 + static gsize inited = 0; + + if (g_once_init_enter (&inited)) + { + WSADATA wsadata; + + if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0) + g_error ("Windows Sockets could not be initialized"); + + g_once_init_leave (&inited, 1); + } +#endif +} diff --git a/gio/gnetworking.h.in b/gio/gnetworking.h.in new file mode 100644 index 0000000..2fa95ff --- /dev/null +++ b/gio/gnetworking.h.in @@ -0,0 +1,78 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __G_NETWORKING_H__ +#define __G_NETWORKING_H__ + +#include + +#ifdef G_OS_WIN32 +#include +#include +#include +#include +#include +#include +#undef interface + +#else /* !G_OS_WIN32 */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +@NAMESER_COMPAT_INCLUDE@ + +#ifndef T_SRV +#define T_SRV 33 +#endif + +#ifndef _PATH_RESCONF +#define _PATH_RESCONF "/etc/resolv.conf" +#endif + +#ifndef CMSG_LEN +/* CMSG_LEN and CMSG_SPACE are defined by RFC 2292, but missing on + * some older platforms. + */ +#define CMSG_LEN(len) ((size_t)CMSG_DATA((struct cmsghdr *)NULL) + (len)) + +/* CMSG_SPACE must add at least as much padding as CMSG_NXTHDR() + * adds. We overestimate here. + */ +#define GLIB_ALIGN_TO_SIZEOF(len, obj) (((len) + sizeof (obj) - 1) & ~(sizeof (obj) - 1)) +#define CMSG_SPACE(len) GLIB_ALIGN_TO_SIZEOF (CMSG_LEN (len), struct cmsghdr) +#endif +#endif + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_2_36 +void g_networking_init (void); + +G_END_DECLS + +#endif /* __G_NETWORKING_H__ */ diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h new file mode 100644 index 0000000..dd8a277 --- /dev/null +++ b/gio/gnetworkingprivate.h @@ -0,0 +1,35 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_NETWORKINGPRIVATE_H__ +#define __G_NETWORKINGPRIVATE_H__ + +#include "gnetworking.h" + +G_BEGIN_DECLS + +guint64 g_resolver_get_serial (GResolver *resolver); + +gint g_socket (gint domain, + gint type, + gint protocol, + GError **error); + +G_END_DECLS + +#endif /* __G_NETWORKINGPRIVATE_H__ */ diff --git a/gio/gnetworkmonitor.c b/gio/gnetworkmonitor.c new file mode 100644 index 0000000..d32c601 --- /dev/null +++ b/gio/gnetworkmonitor.c @@ -0,0 +1,418 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" +#include "glibintl.h" + +#include "gnetworkmonitor.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "ginitable.h" +#include "gioenumtypes.h" +#include "giomodule-priv.h" +#include "gtask.h" + +/** + * SECTION:gnetworkmonitor + * @title: GNetworkMonitor + * @short_description: Network status monitor + * @include: gio/gio.h + * + * #GNetworkMonitor provides an easy-to-use cross-platform API + * for monitoring network connectivity. On Linux, the available + * implementations are based on the kernel's netlink interface and + * on NetworkManager. + * + * There is also an implementation for use inside Flatpak sandboxes. + */ + +/** + * GNetworkMonitor: + * + * #GNetworkMonitor monitors the status of network connections and + * indicates when a possibly-user-visible change has occurred. + * + * Since: 2.32 + */ + +/** + * GNetworkMonitorInterface: + * @g_iface: The parent interface. + * @network_changed: the virtual function pointer for the + * GNetworkMonitor::network-changed signal. + * @can_reach: the virtual function pointer for g_network_monitor_can_reach() + * @can_reach_async: the virtual function pointer for + * g_network_monitor_can_reach_async() + * @can_reach_finish: the virtual function pointer for + * g_network_monitor_can_reach_finish() + * + * The virtual function table for #GNetworkMonitor. + * + * Since: 2.32 + */ + +G_DEFINE_INTERFACE_WITH_CODE (GNetworkMonitor, g_network_monitor, G_TYPE_OBJECT, + g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE)) + + +enum { + NETWORK_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; +static GNetworkMonitor *network_monitor_default_singleton = NULL; /* (owned) (atomic) */ + +/** + * g_network_monitor_get_default: + * + * Gets the default #GNetworkMonitor for the system. + * + * Returns: (not nullable) (transfer none): a #GNetworkMonitor, which will be + * a dummy object if no network monitor is available + * + * Since: 2.32 + */ +GNetworkMonitor * +g_network_monitor_get_default (void) +{ + if (g_once_init_enter (&network_monitor_default_singleton)) + { + GNetworkMonitor *singleton; + + singleton = _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME, + "GIO_USE_NETWORK_MONITOR", + NULL); + + g_once_init_leave (&network_monitor_default_singleton, singleton); + } + + return network_monitor_default_singleton; +} + +/** + * g_network_monitor_get_network_available: + * @monitor: the #GNetworkMonitor + * + * Checks if the network is available. "Available" here means that the + * system has a default route available for at least one of IPv4 or + * IPv6. It does not necessarily imply that the public Internet is + * reachable. See #GNetworkMonitor:network-available for more details. + * + * Returns: whether the network is available + * + * Since: 2.32 + */ +gboolean +g_network_monitor_get_network_available (GNetworkMonitor *monitor) +{ + gboolean available = FALSE; + + g_object_get (G_OBJECT (monitor), "network-available", &available, NULL); + return available; +} + +/** + * g_network_monitor_get_network_metered: + * @monitor: the #GNetworkMonitor + * + * Checks if the network is metered. + * See #GNetworkMonitor:network-metered for more details. + * + * Returns: whether the connection is metered + * + * Since: 2.46 + */ +gboolean +g_network_monitor_get_network_metered (GNetworkMonitor *monitor) +{ + gboolean metered = FALSE; + + g_object_get (G_OBJECT (monitor), "network-metered", &metered, NULL); + return metered; +} + +/** + * g_network_monitor_get_connectivity: + * @monitor: the #GNetworkMonitor + * + * Gets a more detailed networking state than + * g_network_monitor_get_network_available(). + * + * If #GNetworkMonitor:network-available is %FALSE, then the + * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL. + * + * If #GNetworkMonitor:network-available is %TRUE, then the + * connectivity state will be %G_NETWORK_CONNECTIVITY_FULL (if there + * is full Internet connectivity), %G_NETWORK_CONNECTIVITY_LIMITED (if + * the host has a default route, but appears to be unable to actually + * reach the full Internet), or %G_NETWORK_CONNECTIVITY_PORTAL (if the + * host is trapped behind a "captive portal" that requires some sort + * of login or acknowledgement before allowing full Internet access). + * + * Note that in the case of %G_NETWORK_CONNECTIVITY_LIMITED and + * %G_NETWORK_CONNECTIVITY_PORTAL, it is possible that some sites are + * reachable but others are not. In this case, applications can + * attempt to connect to remote servers, but should gracefully fall + * back to their "offline" behavior if the connection attempt fails. + * + * Return value: the network connectivity state + * + * Since: 2.44 + */ +GNetworkConnectivity +g_network_monitor_get_connectivity (GNetworkMonitor *monitor) +{ + GNetworkConnectivity connectivity; + + g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL); + + return connectivity; +} + +/** + * g_network_monitor_can_reach: + * @monitor: a #GNetworkMonitor + * @connectable: a #GSocketConnectable + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Attempts to determine whether or not the host pointed to by + * @connectable can be reached, without actually trying to connect to + * it. + * + * This may return %TRUE even when #GNetworkMonitor:network-available + * is %FALSE, if, for example, @monitor can determine that + * @connectable refers to a host on a local network. + * + * If @monitor believes that an attempt to connect to @connectable + * will succeed, it will return %TRUE. Otherwise, it will return + * %FALSE and set @error to an appropriate error (such as + * %G_IO_ERROR_HOST_UNREACHABLE). + * + * Note that although this does not attempt to connect to + * @connectable, it may still block for a brief period of time (eg, + * trying to do multicast DNS on the local network), so if you do not + * want to block, you should use g_network_monitor_can_reach_async(). + * + * Returns: %TRUE if @connectable is reachable, %FALSE if not. + * + * Since: 2.32 + */ +gboolean +g_network_monitor_can_reach (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorInterface *iface; + + iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor); + return iface->can_reach (monitor, connectable, cancellable, error); +} + +static void +g_network_monitor_real_can_reach_async (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + GError *error = NULL; + + task = g_task_new (monitor, cancellable, callback, user_data); + g_task_set_source_tag (task, g_network_monitor_real_can_reach_async); + + if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +/** + * g_network_monitor_can_reach_async: + * @monitor: a #GNetworkMonitor + * @connectable: a #GSocketConnectable + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback to call when the + * request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously attempts to determine whether or not the host + * pointed to by @connectable can be reached, without actually + * trying to connect to it. + * + * For more details, see g_network_monitor_can_reach(). + * + * When the operation is finished, @callback will be called. + * You can then call g_network_monitor_can_reach_finish() + * to get the result of the operation. + */ +void +g_network_monitor_can_reach_async (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GNetworkMonitorInterface *iface; + + iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor); + iface->can_reach_async (monitor, connectable, cancellable, callback, user_data); +} + +static gboolean +g_network_monitor_real_can_reach_finish (GNetworkMonitor *monitor, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +/** + * g_network_monitor_can_reach_finish: + * @monitor: a #GNetworkMonitor + * @result: a #GAsyncResult + * @error: return location for errors, or %NULL + * + * Finishes an async network connectivity test. + * See g_network_monitor_can_reach_async(). + * + * Returns: %TRUE if network is reachable, %FALSE if not. + */ +gboolean +g_network_monitor_can_reach_finish (GNetworkMonitor *monitor, + GAsyncResult *result, + GError **error) +{ + GNetworkMonitorInterface *iface; + + iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor); + return iface->can_reach_finish (monitor, result, error); +} + +static void +g_network_monitor_default_init (GNetworkMonitorInterface *iface) +{ + iface->can_reach_async = g_network_monitor_real_can_reach_async; + iface->can_reach_finish = g_network_monitor_real_can_reach_finish; + + /** + * GNetworkMonitor::network-changed: + * @monitor: a #GNetworkMonitor + * @network_available: the current value of #GNetworkMonitor:network-available + * + * Emitted when the network configuration changes. + * + * Since: 2.32 + */ + signals[NETWORK_CHANGED] = + g_signal_new (I_("network-changed"), + G_TYPE_NETWORK_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GNetworkMonitorInterface, network_changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); + + /** + * GNetworkMonitor:network-available: + * + * Whether the network is considered available. That is, whether the + * system has a default route for at least one of IPv4 or IPv6. + * + * Real-world networks are of course much more complicated than + * this; the machine may be connected to a wifi hotspot that + * requires payment before allowing traffic through, or may be + * connected to a functioning router that has lost its own upstream + * connectivity. Some hosts might only be accessible when a VPN is + * active. Other hosts might only be accessible when the VPN is + * not active. Thus, it is best to use g_network_monitor_can_reach() + * or g_network_monitor_can_reach_async() to test for reachability + * on a host-by-host basis. (On the other hand, when the property is + * %FALSE, the application can reasonably expect that no remote + * hosts at all are reachable, and should indicate this to the user + * in its UI.) + * + * See also #GNetworkMonitor::network-changed. + * + * Since: 2.32 + */ + g_object_interface_install_property (iface, + g_param_spec_boolean ("network-available", + P_("Network available"), + P_("Whether the network is available"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GNetworkMonitor:network-metered: + * + * Whether the network is considered metered. That is, whether the + * system has traffic flowing through the default connection that is + * subject to limitations set by service providers. For example, traffic + * might be billed by the amount of data transmitted, or there might be a + * quota on the amount of traffic per month. This is typical with tethered + * connections (3G and 4G) and in such situations, bandwidth intensive + * applications may wish to avoid network activity where possible if it will + * cost the user money or use up their limited quota. + * + * If more information is required about specific devices then the + * system network management API should be used instead (for example, + * NetworkManager or ConnMan). + * + * If this information is not available then no networks will be + * marked as metered. + * + * See also #GNetworkMonitor:network-available. + * + * Since: 2.46 + */ + g_object_interface_install_property (iface, + g_param_spec_boolean ("network-metered", + P_("Network metered"), + P_("Whether the network is metered"), + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GNetworkMonitor:connectivity: + * + * More detailed information about the host's network connectivity. + * See g_network_monitor_get_connectivity() and + * #GNetworkConnectivity for more details. + * + * Since: 2.44 + */ + g_object_interface_install_property (iface, + g_param_spec_enum ("connectivity", + P_("Network connectivity"), + P_("Level of network connectivity"), + G_TYPE_NETWORK_CONNECTIVITY, + G_NETWORK_CONNECTIVITY_FULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/gio/gnetworkmonitor.h b/gio/gnetworkmonitor.h new file mode 100644 index 0000000..dcaeaad --- /dev/null +++ b/gio/gnetworkmonitor.h @@ -0,0 +1,99 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_NETWORK_MONITOR_H__ +#define __G_NETWORK_MONITOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_NETWORK_MONITOR_EXTENSION_POINT_NAME: + * + * Extension point for network status monitoring functionality. + * See [Extending GIO][extending-gio]. + * + * Since: 2.30 + */ +#define G_NETWORK_MONITOR_EXTENSION_POINT_NAME "gio-network-monitor" + +#define G_TYPE_NETWORK_MONITOR (g_network_monitor_get_type ()) +#define G_NETWORK_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_MONITOR, GNetworkMonitor)) +#define G_IS_NETWORK_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_MONITOR)) +#define G_NETWORK_MONITOR_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_NETWORK_MONITOR, GNetworkMonitorInterface)) + +typedef struct _GNetworkMonitorInterface GNetworkMonitorInterface; + +struct _GNetworkMonitorInterface { + GTypeInterface g_iface; + + void (*network_changed) (GNetworkMonitor *monitor, + gboolean network_available); + + gboolean (*can_reach) (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GError **error); + void (*can_reach_async) (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*can_reach_finish) (GNetworkMonitor *monitor, + GAsyncResult *result, + GError **error); +}; + +GLIB_AVAILABLE_IN_2_32 +GType g_network_monitor_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_32 +GNetworkMonitor *g_network_monitor_get_default (void); + +GLIB_AVAILABLE_IN_2_32 +gboolean g_network_monitor_get_network_available (GNetworkMonitor *monitor); + +GLIB_AVAILABLE_IN_2_46 +gboolean g_network_monitor_get_network_metered (GNetworkMonitor *monitor); + +GLIB_AVAILABLE_IN_2_44 +GNetworkConnectivity g_network_monitor_get_connectivity (GNetworkMonitor *monitor); + +GLIB_AVAILABLE_IN_2_32 +gboolean g_network_monitor_can_reach (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_32 +void g_network_monitor_can_reach_async (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_32 +gboolean g_network_monitor_can_reach_finish (GNetworkMonitor *monitor, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __G_NETWORK_MONITOR_H__ */ diff --git a/gio/gnetworkmonitorbase.c b/gio/gnetworkmonitorbase.c new file mode 100644 index 0000000..3ad2f9b --- /dev/null +++ b/gio/gnetworkmonitorbase.c @@ -0,0 +1,583 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gnetworkmonitorbase.h" +#include "ginetaddress.h" +#include "ginetaddressmask.h" +#include "ginetsocketaddress.h" +#include "ginitable.h" +#include "gioerror.h" +#include "giomodule-priv.h" +#include "gnetworkmonitor.h" +#include "gsocketaddressenumerator.h" +#include "gsocketconnectable.h" +#include "gtask.h" +#include "glibintl.h" + +static void g_network_monitor_base_iface_init (GNetworkMonitorInterface *iface); +static void g_network_monitor_base_initable_iface_init (GInitableIface *iface); + +enum +{ + PROP_0, + + PROP_NETWORK_AVAILABLE, + PROP_NETWORK_METERED, + PROP_CONNECTIVITY +}; + +struct _GNetworkMonitorBasePrivate +{ + GHashTable *networks /* (element-type GInetAddressMask) (owned) */; + gboolean have_ipv4_default_route; + gboolean have_ipv6_default_route; + gboolean is_available; + + GMainContext *context; + GSource *network_changed_source; + gboolean initializing; +}; + +static guint network_changed_signal = 0; + +static void queue_network_changed (GNetworkMonitorBase *monitor); +static guint inet_address_mask_hash (gconstpointer key); +static gboolean inet_address_mask_equal (gconstpointer a, + gconstpointer b); + +G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorBase, g_network_monitor_base, G_TYPE_OBJECT, + G_ADD_PRIVATE (GNetworkMonitorBase) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_network_monitor_base_initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR, + g_network_monitor_base_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "base", + 0)) + +static void +g_network_monitor_base_init (GNetworkMonitorBase *monitor) +{ + monitor->priv = g_network_monitor_base_get_instance_private (monitor); + monitor->priv->networks = g_hash_table_new_full (inet_address_mask_hash, + inet_address_mask_equal, + g_object_unref, NULL); + monitor->priv->context = g_main_context_get_thread_default (); + if (monitor->priv->context) + g_main_context_ref (monitor->priv->context); + + monitor->priv->initializing = TRUE; +} + +static void +g_network_monitor_base_constructed (GObject *object) +{ + GNetworkMonitorBase *monitor = G_NETWORK_MONITOR_BASE (object); + + if (G_OBJECT_TYPE (monitor) == G_TYPE_NETWORK_MONITOR_BASE) + { + GInetAddressMask *mask; + + /* We're the dumb base class, not a smarter subclass. So just + * assume that the network is available. + */ + mask = g_inet_address_mask_new_from_string ("0.0.0.0/0", NULL); + g_network_monitor_base_add_network (monitor, mask); + g_object_unref (mask); + + mask = g_inet_address_mask_new_from_string ("::/0", NULL); + if (mask) + { + /* On some environments (for example Windows without IPv6 support + * enabled) the string "::/0" can't be processed and causes + * g_inet_address_mask_new_from_string to return NULL */ + g_network_monitor_base_add_network (monitor, mask); + g_object_unref (mask); + } + } +} + +static void +g_network_monitor_base_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GNetworkMonitorBase *monitor = G_NETWORK_MONITOR_BASE (object); + + switch (prop_id) + { + case PROP_NETWORK_AVAILABLE: + g_value_set_boolean (value, monitor->priv->is_available); + break; + + case PROP_NETWORK_METERED: + /* Default to FALSE in the unknown case. */ + g_value_set_boolean (value, FALSE); + break; + + case PROP_CONNECTIVITY: + g_value_set_enum (value, + monitor->priv->is_available ? + G_NETWORK_CONNECTIVITY_FULL : + G_NETWORK_CONNECTIVITY_LOCAL); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_network_monitor_base_finalize (GObject *object) +{ + GNetworkMonitorBase *monitor = G_NETWORK_MONITOR_BASE (object); + + g_hash_table_unref (monitor->priv->networks); + if (monitor->priv->network_changed_source) + { + g_source_destroy (monitor->priv->network_changed_source); + g_source_unref (monitor->priv->network_changed_source); + } + if (monitor->priv->context) + g_main_context_unref (monitor->priv->context); + + G_OBJECT_CLASS (g_network_monitor_base_parent_class)->finalize (object); +} + +static void +g_network_monitor_base_class_init (GNetworkMonitorBaseClass *monitor_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (monitor_class); + + gobject_class->constructed = g_network_monitor_base_constructed; + gobject_class->get_property = g_network_monitor_base_get_property; + gobject_class->finalize = g_network_monitor_base_finalize; + + g_object_class_override_property (gobject_class, PROP_NETWORK_AVAILABLE, "network-available"); + g_object_class_override_property (gobject_class, PROP_NETWORK_METERED, "network-metered"); + g_object_class_override_property (gobject_class, PROP_CONNECTIVITY, "connectivity"); +} + +static gboolean +g_network_monitor_base_can_reach_sockaddr (GNetworkMonitorBase *base, + GSocketAddress *sockaddr) +{ + GInetAddress *iaddr; + GHashTableIter iter; + gpointer key; + + if (!G_IS_INET_SOCKET_ADDRESS (sockaddr)) + return FALSE; + + iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (sockaddr)); + g_hash_table_iter_init (&iter, base->priv->networks); + while (g_hash_table_iter_next (&iter, &key, NULL)) + { + GInetAddressMask *mask = key; + if (g_inet_address_mask_matches (mask, iaddr)) + return TRUE; + } + + return FALSE; +} + +static gboolean +g_network_monitor_base_can_reach (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorBase *base = G_NETWORK_MONITOR_BASE (monitor); + GSocketAddressEnumerator *enumerator; + GSocketAddress *addr; + + if (g_hash_table_size (base->priv->networks) == 0) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE, + _("Network unreachable")); + return FALSE; + } + + enumerator = g_socket_connectable_proxy_enumerate (connectable); + addr = g_socket_address_enumerator_next (enumerator, cancellable, error); + if (!addr) + { + /* Either the user cancelled, or DNS resolution failed */ + g_object_unref (enumerator); + return FALSE; + } + + if (base->priv->have_ipv4_default_route && + base->priv->have_ipv6_default_route) + { + g_object_unref (enumerator); + g_object_unref (addr); + return TRUE; + } + + while (addr) + { + if (g_network_monitor_base_can_reach_sockaddr (base, addr)) + { + g_object_unref (addr); + g_object_unref (enumerator); + return TRUE; + } + + g_object_unref (addr); + addr = g_socket_address_enumerator_next (enumerator, cancellable, error); + } + g_object_unref (enumerator); + + if (error && !*error) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, + _("Host unreachable")); + } + return FALSE; +} + +static void +can_reach_async_got_address (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object); + GTask *task = user_data; + GNetworkMonitorBase *base = g_task_get_source_object (task); + GSocketAddress *addr; + GError *error = NULL; + + addr = g_socket_address_enumerator_next_finish (enumerator, result, &error); + if (!addr) + { + if (error) + { + /* Either the user cancelled, or DNS resolution failed */ + g_task_return_error (task, error); + g_object_unref (task); + return; + } + else + { + /* Resolved all addresses, none matched */ + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, + _("Host unreachable")); + g_object_unref (task); + return; + } + } + + if (g_network_monitor_base_can_reach_sockaddr (base, addr)) + { + g_object_unref (addr); + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + g_object_unref (addr); + + g_socket_address_enumerator_next_async (enumerator, + g_task_get_cancellable (task), + can_reach_async_got_address, task); +} + +static void +g_network_monitor_base_can_reach_async (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + GSocketAddressEnumerator *enumerator; + + task = g_task_new (monitor, cancellable, callback, user_data); + g_task_set_source_tag (task, g_network_monitor_base_can_reach_async); + + if (g_hash_table_size (G_NETWORK_MONITOR_BASE (monitor)->priv->networks) == 0) + { + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE, + _("Network unreachable")); + g_object_unref (task); + return; + } + + enumerator = g_socket_connectable_proxy_enumerate (connectable); + g_socket_address_enumerator_next_async (enumerator, cancellable, + can_reach_async_got_address, task); + g_object_unref (enumerator); +} + +static gboolean +g_network_monitor_base_can_reach_finish (GNetworkMonitor *monitor, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +g_network_monitor_base_iface_init (GNetworkMonitorInterface *monitor_iface) +{ + monitor_iface->can_reach = g_network_monitor_base_can_reach; + monitor_iface->can_reach_async = g_network_monitor_base_can_reach_async; + monitor_iface->can_reach_finish = g_network_monitor_base_can_reach_finish; + + network_changed_signal = g_signal_lookup ("network-changed", G_TYPE_NETWORK_MONITOR); +} + +static gboolean +g_network_monitor_base_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorBase *base = G_NETWORK_MONITOR_BASE (initable); + + base->priv->initializing = FALSE; + + return TRUE; +} + +static void +g_network_monitor_base_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_network_monitor_base_initable_init; +} + +static guint +inet_address_mask_hash (gconstpointer key) +{ + GInetAddressMask *mask = G_INET_ADDRESS_MASK (key); + guint addr_hash; + guint mask_length = g_inet_address_mask_get_length (mask); + GInetAddress *addr = g_inet_address_mask_get_address (mask); + const guint8 *bytes = g_inet_address_to_bytes (addr); + gsize bytes_length = g_inet_address_get_native_size (addr); + + union + { + const guint8 *bytes; + guint32 *hash32; + guint64 *hash64; + } integerifier; + + /* If we can fit the entire address into the hash key, do it. Don’t worry + * about endianness; the address should always be in network endianness. */ + if (bytes_length == sizeof (guint32)) + { + integerifier.bytes = bytes; + addr_hash = *integerifier.hash32; + } + else if (bytes_length == sizeof (guint64)) + { + integerifier.bytes = bytes; + addr_hash = *integerifier.hash64; + } + else + { + gsize i; + + /* Otherwise, fall back to adding the bytes together. We do this, rather + * than XORing them, as routes often have repeated tuples which would + * cancel out under XOR. */ + addr_hash = 0; + for (i = 0; i < bytes_length; i++) + addr_hash += bytes[i]; + } + + return addr_hash + mask_length;; +} + +static gboolean +inet_address_mask_equal (gconstpointer a, + gconstpointer b) +{ + GInetAddressMask *mask_a = G_INET_ADDRESS_MASK (a); + GInetAddressMask *mask_b = G_INET_ADDRESS_MASK (b); + + return g_inet_address_mask_equal (mask_a, mask_b); +} + +static gboolean +emit_network_changed (gpointer user_data) +{ + GNetworkMonitorBase *monitor = user_data; + gboolean is_available; + + if (g_source_is_destroyed (g_main_current_source ())) + return FALSE; + + g_object_ref (monitor); + + is_available = (monitor->priv->have_ipv4_default_route || + monitor->priv->have_ipv6_default_route); + if (monitor->priv->is_available != is_available) + { + monitor->priv->is_available = is_available; + g_object_notify (G_OBJECT (monitor), "network-available"); + } + + g_signal_emit (monitor, network_changed_signal, 0, is_available); + + g_source_unref (monitor->priv->network_changed_source); + monitor->priv->network_changed_source = NULL; + + g_object_unref (monitor); + return FALSE; +} + +static void +queue_network_changed (GNetworkMonitorBase *monitor) +{ + if (!monitor->priv->network_changed_source && + !monitor->priv->initializing) + { + GSource *source; + + source = g_idle_source_new (); + /* Use G_PRIORITY_HIGH_IDLE priority so that multiple + * network-change-related notifications coming in at + * G_PRIORITY_DEFAULT will get coalesced into one signal + * emission. + */ + g_source_set_priority (source, G_PRIORITY_HIGH_IDLE); + g_source_set_callback (source, emit_network_changed, monitor, NULL); + g_source_set_static_name (source, "[gio] emit_network_changed"); + g_source_attach (source, monitor->priv->context); + monitor->priv->network_changed_source = source; + } + + /* Normally we wait to update is_available until we emit the signal, + * to keep things consistent. But when we're first creating the + * object, we want it to be correct right away. + */ + if (monitor->priv->initializing) + { + monitor->priv->is_available = (monitor->priv->have_ipv4_default_route || + monitor->priv->have_ipv6_default_route); + } +} + +/** + * g_network_monitor_base_add_network: + * @monitor: the #GNetworkMonitorBase + * @network: (transfer none): a #GInetAddressMask + * + * Adds @network to @monitor's list of available networks. + * + * Since: 2.32 + */ +void +g_network_monitor_base_add_network (GNetworkMonitorBase *monitor, + GInetAddressMask *network) +{ + if (!g_hash_table_add (monitor->priv->networks, g_object_ref (network))) + return; + + if (g_inet_address_mask_get_length (network) == 0) + { + switch (g_inet_address_mask_get_family (network)) + { + case G_SOCKET_FAMILY_IPV4: + monitor->priv->have_ipv4_default_route = TRUE; + break; + case G_SOCKET_FAMILY_IPV6: + monitor->priv->have_ipv6_default_route = TRUE; + break; + default: + break; + } + } + + /* Don't emit network-changed when multicast-link-local routing + * changes. This rather arbitrary decision is mostly because it + * seems to change quite often... + */ + if (g_inet_address_get_is_mc_link_local (g_inet_address_mask_get_address (network))) + return; + + queue_network_changed (monitor); +} + +/** + * g_network_monitor_base_remove_network: + * @monitor: the #GNetworkMonitorBase + * @network: a #GInetAddressMask + * + * Removes @network from @monitor's list of available networks. + * + * Since: 2.32 + */ +void +g_network_monitor_base_remove_network (GNetworkMonitorBase *monitor, + GInetAddressMask *network) +{ + if (!g_hash_table_remove (monitor->priv->networks, network)) + return; + + if (g_inet_address_mask_get_length (network) == 0) + { + switch (g_inet_address_mask_get_family (network)) + { + case G_SOCKET_FAMILY_IPV4: + monitor->priv->have_ipv4_default_route = FALSE; + break; + case G_SOCKET_FAMILY_IPV6: + monitor->priv->have_ipv6_default_route = FALSE; + break; + default: + break; + } + } + + queue_network_changed (monitor); +} + +/** + * g_network_monitor_base_set_networks: + * @monitor: the #GNetworkMonitorBase + * @networks: (array length=length): an array of #GInetAddressMask + * @length: length of @networks + * + * Drops @monitor's current list of available networks and replaces + * it with @networks. + */ +void +g_network_monitor_base_set_networks (GNetworkMonitorBase *monitor, + GInetAddressMask **networks, + gint length) +{ + int i; + + g_hash_table_remove_all (monitor->priv->networks); + monitor->priv->have_ipv4_default_route = FALSE; + monitor->priv->have_ipv6_default_route = FALSE; + + for (i = 0; i < length; i++) + g_network_monitor_base_add_network (monitor, networks[i]); +} diff --git a/gio/gnetworkmonitorbase.h b/gio/gnetworkmonitorbase.h new file mode 100644 index 0000000..20a84fc --- /dev/null +++ b/gio/gnetworkmonitorbase.h @@ -0,0 +1,68 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_NETWORK_MONITOR_BASE_H__ +#define __G_NETWORK_MONITOR_BASE_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_NETWORK_MONITOR_BASE (g_network_monitor_base_get_type ()) +#define G_NETWORK_MONITOR_BASE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_MONITOR_BASE, GNetworkMonitorBase)) +#define G_NETWORK_MONITOR_BASE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_MONITOR_BASE, GNetworkMonitorBaseClass)) +#define G_IS_NETWORK_MONITOR_BASE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_MONITOR_BASE)) +#define G_IS_NETWORK_MONITOR_BASE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NETWORK_MONITOR_BASE)) +#define G_NETWORK_MONITOR_BASE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NETWORK_MONITOR_BASE, GNetworkMonitorBaseClass)) + +typedef struct _GNetworkMonitorBase GNetworkMonitorBase; +typedef struct _GNetworkMonitorBaseClass GNetworkMonitorBaseClass; +typedef struct _GNetworkMonitorBasePrivate GNetworkMonitorBasePrivate; + +struct _GNetworkMonitorBase { + GObject parent_instance; + + GNetworkMonitorBasePrivate *priv; +}; + +struct _GNetworkMonitorBaseClass { + GObjectClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_network_monitor_base_get_type (void); + +/*< protected >*/ +GLIB_AVAILABLE_IN_2_32 +void g_network_monitor_base_add_network (GNetworkMonitorBase *monitor, + GInetAddressMask *network); +GLIB_AVAILABLE_IN_2_32 +void g_network_monitor_base_remove_network (GNetworkMonitorBase *monitor, + GInetAddressMask *network); +GLIB_AVAILABLE_IN_ALL +void g_network_monitor_base_set_networks (GNetworkMonitorBase *monitor, + GInetAddressMask **networks, + gint length); + +G_END_DECLS + +#endif /* __G_NETWORK_MONITOR_BASE_H__ */ diff --git a/gio/gnetworkmonitornetlink.c b/gio/gnetworkmonitornetlink.c new file mode 100644 index 0000000..53eab33 --- /dev/null +++ b/gio/gnetworkmonitornetlink.c @@ -0,0 +1,513 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include +#include + +#include "gnetworkmonitornetlink.h" +#include "gcredentials.h" +#include "ginetaddressmask.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "glibintl.h" +#include "glib/gstdio.h" +#include "gnetworkingprivate.h" +#include "gnetworkmonitor.h" +#include "gsocket.h" +#include "gunixcredentialsmessage.h" + +/* must come at the end to pick system includes from + * gnetworkingprivate.h */ +#include +#include + +static GInitableIface *initable_parent_iface; +static void g_network_monitor_netlink_iface_init (GNetworkMonitorInterface *iface); +static void g_network_monitor_netlink_initable_iface_init (GInitableIface *iface); + +struct _GNetworkMonitorNetlinkPrivate +{ + GSocket *sock; + GSource *source, *dump_source; + GMainContext *context; + + GPtrArray *dump_networks; +}; + +static gboolean read_netlink_messages (GNetworkMonitorNetlink *nl, + GError **error); +static gboolean read_netlink_messages_callback (GSocket *socket, + GIOCondition condition, + gpointer user_data); +static gboolean request_dump (GNetworkMonitorNetlink *nl, + GError **error); + +#define g_network_monitor_netlink_get_type _g_network_monitor_netlink_get_type +G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorNetlink, g_network_monitor_netlink, G_TYPE_NETWORK_MONITOR_BASE, + G_ADD_PRIVATE (GNetworkMonitorNetlink) + G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR, + g_network_monitor_netlink_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_network_monitor_netlink_initable_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "netlink", + 20)) + +static void +g_network_monitor_netlink_init (GNetworkMonitorNetlink *nl) +{ + nl->priv = g_network_monitor_netlink_get_instance_private (nl); +} + +static gboolean +g_network_monitor_netlink_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (initable); + gint sockfd; + struct sockaddr_nl snl; + + /* We create the socket the old-school way because sockaddr_netlink + * can't be represented as a GSocketAddress + */ + sockfd = g_socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, NULL); + if (sockfd == -1) + { + int errsv = errno; + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Could not create network monitor: %s"), + g_strerror (errsv)); + return FALSE; + } + + snl.nl_family = AF_NETLINK; + snl.nl_pid = snl.nl_pad = 0; + snl.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE; + if (bind (sockfd, (struct sockaddr *)&snl, sizeof (snl)) != 0) + { + int errsv = errno; + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Could not create network monitor: %s"), + g_strerror (errsv)); + (void) g_close (sockfd, NULL); + return FALSE; + } + + nl->priv->sock = g_socket_new_from_fd (sockfd, error); + if (!nl->priv->sock) + { + g_prefix_error (error, "%s", _("Could not create network monitor: ")); + (void) g_close (sockfd, NULL); + return FALSE; + } + + if (!g_socket_set_option (nl->priv->sock, SOL_SOCKET, SO_PASSCRED, + TRUE, NULL)) + { + int errsv = errno; + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Could not create network monitor: %s"), + g_strerror (errsv)); + return FALSE; + } + + /* Request the current state */ + if (!request_dump (nl, error)) + return FALSE; + + /* And read responses; since we haven't yet marked the socket + * non-blocking, each call will block until a message is received. + */ + while (nl->priv->dump_networks) + { + GError *local_error = NULL; + if (!read_netlink_messages (nl, &local_error)) + { + g_warning ("%s", local_error->message); + g_clear_error (&local_error); + break; + } + } + + g_socket_set_blocking (nl->priv->sock, FALSE); + nl->priv->context = g_main_context_ref_thread_default (); + nl->priv->source = g_socket_create_source (nl->priv->sock, G_IO_IN, NULL); + g_source_set_callback (nl->priv->source, + (GSourceFunc) read_netlink_messages_callback, nl, NULL); + g_source_attach (nl->priv->source, nl->priv->context); + + return initable_parent_iface->init (initable, cancellable, error); +} + +static gboolean +request_dump (GNetworkMonitorNetlink *nl, + GError **error) +{ + struct nlmsghdr *n; + struct rtgenmsg *gen; + gchar buf[NLMSG_SPACE (sizeof (*gen))]; + + memset (buf, 0, sizeof (buf)); + n = (struct nlmsghdr*) buf; + n->nlmsg_len = NLMSG_LENGTH (sizeof (*gen)); + n->nlmsg_type = RTM_GETROUTE; + n->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; + n->nlmsg_pid = 0; + gen = NLMSG_DATA (n); + gen->rtgen_family = AF_UNSPEC; + + if (g_socket_send (nl->priv->sock, buf, sizeof (buf), + NULL, error) < 0) + { + g_prefix_error (error, "%s", _("Could not get network status: ")); + return FALSE; + } + + nl->priv->dump_networks = g_ptr_array_new_with_free_func (g_object_unref); + return TRUE; +} + +static gboolean +timeout_request_dump (gpointer user_data) +{ + GNetworkMonitorNetlink *nl = user_data; + + g_source_destroy (nl->priv->dump_source); + g_source_unref (nl->priv->dump_source); + nl->priv->dump_source = NULL; + + request_dump (nl, NULL); + + return FALSE; +} + +static void +queue_request_dump (GNetworkMonitorNetlink *nl) +{ + if (nl->priv->dump_networks) + return; + + if (nl->priv->dump_source) + { + g_source_destroy (nl->priv->dump_source); + g_source_unref (nl->priv->dump_source); + } + + nl->priv->dump_source = g_timeout_source_new_seconds (1); + g_source_set_callback (nl->priv->dump_source, + (GSourceFunc) timeout_request_dump, nl, NULL); + g_source_attach (nl->priv->dump_source, nl->priv->context); +} + +static GInetAddressMask * +create_inet_address_mask (GSocketFamily family, + const guint8 *dest, + gsize dest_len) +{ + GInetAddress *dest_addr; + GInetAddressMask *network; + + if (dest) + dest_addr = g_inet_address_new_from_bytes (dest, family); + else + dest_addr = g_inet_address_new_any (family); + network = g_inet_address_mask_new (dest_addr, dest_len, NULL); + g_object_unref (dest_addr); + + return network; +} + +static void +add_network (GNetworkMonitorNetlink *nl, + GSocketFamily family, + const guint8 *dest, + gsize dest_len) +{ + GInetAddressMask *network = create_inet_address_mask (family, dest, dest_len); + g_return_if_fail (network != NULL); + + if (nl->priv->dump_networks) + g_ptr_array_add (nl->priv->dump_networks, g_object_ref (network)); + else + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (nl), network); + + g_object_unref (network); +} + +static void +remove_network (GNetworkMonitorNetlink *nl, + GSocketFamily family, + const guint8 *dest, + gsize dest_len) +{ + GInetAddressMask *network = create_inet_address_mask (family, dest, dest_len); + g_return_if_fail (network != NULL); + + if (nl->priv->dump_networks) + { + GInetAddressMask **dump_networks = (GInetAddressMask **)nl->priv->dump_networks->pdata; + guint i; + + for (i = 0; i < nl->priv->dump_networks->len; i++) + { + if (g_inet_address_mask_equal (network, dump_networks[i])) + g_ptr_array_remove_index_fast (nl->priv->dump_networks, i--); + } + } + else + { + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (nl), network); + } + + g_object_unref (network); +} + +static void +finish_dump (GNetworkMonitorNetlink *nl) +{ + g_network_monitor_base_set_networks (G_NETWORK_MONITOR_BASE (nl), + (GInetAddressMask **)nl->priv->dump_networks->pdata, + nl->priv->dump_networks->len); + g_ptr_array_free (nl->priv->dump_networks, TRUE); + nl->priv->dump_networks = NULL; +} + +static gboolean +read_netlink_messages (GNetworkMonitorNetlink *nl, + GError **error) +{ + GInputVector iv; + gssize len; + gint flags; + GError *local_error = NULL; + GSocketAddress *addr = NULL; + struct nlmsghdr *msg; + struct rtmsg *rtmsg; + struct rtattr *attr; + struct sockaddr_nl source_sockaddr; + gsize attrlen; + guint8 *dest, *gateway, *oif; + gboolean retval = TRUE; + + iv.buffer = NULL; + iv.size = 0; + + flags = MSG_PEEK | MSG_TRUNC; + len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1, + NULL, NULL, &flags, NULL, &local_error); + if (len < 0) + { + retval = FALSE; + goto done; + } + + iv.buffer = g_malloc (len); + iv.size = len; + len = g_socket_receive_message (nl->priv->sock, &addr, &iv, 1, + NULL, NULL, NULL, NULL, &local_error); + if (len < 0) + { + retval = FALSE; + goto done; + } + + if (!g_socket_address_to_native (addr, &source_sockaddr, sizeof (source_sockaddr), &local_error)) + { + retval = FALSE; + goto done; + } + + /* If the sender port id is 0 (not fakeable) then the message is from the kernel */ + if (source_sockaddr.nl_pid != 0) + goto done; + + msg = (struct nlmsghdr *) iv.buffer; + for (; len > 0; msg = NLMSG_NEXT (msg, len)) + { + if (!NLMSG_OK (msg, (size_t) len)) + { + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_PARTIAL_INPUT, + "netlink message was truncated; shouldn't happen..."); + retval = FALSE; + goto done; + } + + switch (msg->nlmsg_type) + { + case RTM_NEWROUTE: + case RTM_DELROUTE: + rtmsg = NLMSG_DATA (msg); + + if (rtmsg->rtm_family != AF_INET && rtmsg->rtm_family != AF_INET6) + continue; + if (rtmsg->rtm_type == RTN_UNREACHABLE) + continue; + + attrlen = NLMSG_PAYLOAD (msg, sizeof (struct rtmsg)); + attr = RTM_RTA (rtmsg); + dest = gateway = oif = NULL; + while (RTA_OK (attr, attrlen)) + { + if (attr->rta_type == RTA_DST) + dest = RTA_DATA (attr); + else if (attr->rta_type == RTA_GATEWAY) + gateway = RTA_DATA (attr); + else if (attr->rta_type == RTA_OIF) + oif = RTA_DATA (attr); + attr = RTA_NEXT (attr, attrlen); + } + + if (dest || gateway || oif) + { + /* Unless we're processing the results of a dump, ignore + * IPv6 link-local multicast routes, which are added and + * removed all the time for some reason. + */ +#define UNALIGNED_IN6_IS_ADDR_MC_LINKLOCAL(a) \ + ((a[0] == 0xff) && ((a[1] & 0xf) == 0x2)) + + if (!nl->priv->dump_networks && + rtmsg->rtm_family == AF_INET6 && + rtmsg->rtm_dst_len != 0 && + (dest && UNALIGNED_IN6_IS_ADDR_MC_LINKLOCAL (dest))) + continue; + + if (msg->nlmsg_type == RTM_NEWROUTE) + add_network (nl, rtmsg->rtm_family, dest, rtmsg->rtm_dst_len); + else + remove_network (nl, rtmsg->rtm_family, dest, rtmsg->rtm_dst_len); + queue_request_dump (nl); + } + break; + + case NLMSG_DONE: + finish_dump (nl); + goto done; + + case NLMSG_ERROR: + { + struct nlmsgerr *e = NLMSG_DATA (msg); + + g_set_error (&local_error, + G_IO_ERROR, + g_io_error_from_errno (-e->error), + "netlink error: %s", + g_strerror (-e->error)); + } + retval = FALSE; + goto done; + + default: + g_set_error (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "unexpected netlink message %d", + msg->nlmsg_type); + retval = FALSE; + goto done; + } + } + + done: + g_free (iv.buffer); + g_clear_object (&addr); + + if (!retval && nl->priv->dump_networks) + finish_dump (nl); + + if (local_error) + g_propagate_prefixed_error (error, local_error, "Error on netlink socket: "); + + return retval; +} + +static void +g_network_monitor_netlink_finalize (GObject *object) +{ + GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (object); + + if (nl->priv->source) + { + g_source_destroy (nl->priv->source); + g_source_unref (nl->priv->source); + } + + if (nl->priv->dump_source) + { + g_source_destroy (nl->priv->dump_source); + g_source_unref (nl->priv->dump_source); + } + + if (nl->priv->sock) + { + g_socket_close (nl->priv->sock, NULL); + g_object_unref (nl->priv->sock); + } + + g_clear_pointer (&nl->priv->context, g_main_context_unref); + g_clear_pointer (&nl->priv->dump_networks, g_ptr_array_unref); + + G_OBJECT_CLASS (g_network_monitor_netlink_parent_class)->finalize (object); +} + +static gboolean +read_netlink_messages_callback (GSocket *socket, + GIOCondition condition, + gpointer user_data) +{ + GError *error = NULL; + GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (user_data); + + if (!read_netlink_messages (nl, &error)) + { + g_warning ("Error reading netlink message: %s", error->message); + g_clear_error (&error); + return FALSE; + } + + return TRUE; +} + +static void +g_network_monitor_netlink_class_init (GNetworkMonitorNetlinkClass *nl_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); + + gobject_class->finalize = g_network_monitor_netlink_finalize; +} + +static void +g_network_monitor_netlink_iface_init (GNetworkMonitorInterface *monitor_iface) +{ +} + +static void +g_network_monitor_netlink_initable_iface_init (GInitableIface *iface) +{ + initable_parent_iface = g_type_interface_peek_parent (iface); + + iface->init = g_network_monitor_netlink_initable_init; +} diff --git a/gio/gnetworkmonitornetlink.h b/gio/gnetworkmonitornetlink.h new file mode 100644 index 0000000..e6aedf0 --- /dev/null +++ b/gio/gnetworkmonitornetlink.h @@ -0,0 +1,55 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_NETWORK_MONITOR_NETLINK_H__ +#define __G_NETWORK_MONITOR_NETLINK_H__ + +#include "gnetworkmonitorbase.h" + +G_BEGIN_DECLS + +#define G_TYPE_NETWORK_MONITOR_NETLINK (_g_network_monitor_netlink_get_type ()) +#define G_NETWORK_MONITOR_NETLINK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_MONITOR_NETLINK, GNetworkMonitorNetlink)) +#define G_NETWORK_MONITOR_NETLINK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_MONITOR_NETLINK, GNetworkMonitorNetlinkClass)) +#define G_IS_NETWORK_MONITOR_NETLINK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_MONITOR_NETLINK)) +#define G_IS_NETWORK_MONITOR_NETLINK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NETWORK_MONITOR_NETLINK)) +#define G_NETWORK_MONITOR_NETLINK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NETWORK_MONITOR_NETLINK, GNetworkMonitorNetlinkClass)) + +typedef struct _GNetworkMonitorNetlink GNetworkMonitorNetlink; +typedef struct _GNetworkMonitorNetlinkClass GNetworkMonitorNetlinkClass; +typedef struct _GNetworkMonitorNetlinkPrivate GNetworkMonitorNetlinkPrivate; + +struct _GNetworkMonitorNetlink { + GNetworkMonitorBase parent_instance; + + GNetworkMonitorNetlinkPrivate *priv; +}; + +struct _GNetworkMonitorNetlinkClass { + GNetworkMonitorBaseClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[8]; +}; + +GType _g_network_monitor_netlink_get_type (void); + +G_END_DECLS + +#endif /* __G_NETWORK_MONITOR_NETLINK_H__ */ diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c new file mode 100644 index 0000000..a8040fb --- /dev/null +++ b/gio/gnetworkmonitornm.c @@ -0,0 +1,374 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include +#include + +#include "gnetworkmonitornm.h" +#include "gioerror.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "glibintl.h" +#include "glib/gstdio.h" +#include "gnetworkingprivate.h" +#include "gnetworkmonitor.h" +#include "gdbusproxy.h" + +static void g_network_monitor_nm_iface_init (GNetworkMonitorInterface *iface); +static void g_network_monitor_nm_initable_iface_init (GInitableIface *iface); + +enum +{ + PROP_0, + + PROP_NETWORK_AVAILABLE, + PROP_NETWORK_METERED, + PROP_CONNECTIVITY +}; + +typedef enum { + NM_CONNECTIVITY_UNKNOWN, + NM_CONNECTIVITY_NONE, + NM_CONNECTIVITY_PORTAL, + NM_CONNECTIVITY_LIMITED, + NM_CONNECTIVITY_FULL +} NMConnectivityState; + +/* Copied from https://developer.gnome.org/libnm-util/stable/libnm-util-NetworkManager.html#NMState; + * used inline to avoid a NetworkManager dependency from GLib. */ +typedef enum { + NM_STATE_UNKNOWN = 0, + NM_STATE_ASLEEP = 10, + NM_STATE_DISCONNECTED = 20, + NM_STATE_DISCONNECTING = 30, + NM_STATE_CONNECTING = 40, + NM_STATE_CONNECTED_LOCAL = 50, + NM_STATE_CONNECTED_SITE = 60, + NM_STATE_CONNECTED_GLOBAL = 70, +} NMState; + +struct _GNetworkMonitorNMPrivate +{ + GDBusProxy *proxy; + guint signal_id; + + GNetworkConnectivity connectivity; + gboolean network_available; + gboolean network_metered; +}; + +#define g_network_monitor_nm_get_type _g_network_monitor_nm_get_type +G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorNM, g_network_monitor_nm, G_TYPE_NETWORK_MONITOR_NETLINK, + G_ADD_PRIVATE (GNetworkMonitorNM) + G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR, + g_network_monitor_nm_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_network_monitor_nm_initable_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "networkmanager", + 30)) + +static void +g_network_monitor_nm_init (GNetworkMonitorNM *nm) +{ + nm->priv = g_network_monitor_nm_get_instance_private (nm); +} + +static void +g_network_monitor_nm_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GNetworkMonitorNM *nm = G_NETWORK_MONITOR_NM (object); + + switch (prop_id) + { + case PROP_NETWORK_AVAILABLE: + g_value_set_boolean (value, nm->priv->network_available); + break; + + case PROP_NETWORK_METERED: + g_value_set_boolean (value, nm->priv->network_metered); + break; + + case PROP_CONNECTIVITY: + g_value_set_enum (value, nm->priv->connectivity); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GNetworkConnectivity +nm_conn_to_g_conn (int nm_state) +{ + switch (nm_state) + { + case NM_CONNECTIVITY_UNKNOWN: + return G_NETWORK_CONNECTIVITY_LOCAL; + case NM_CONNECTIVITY_NONE: + return G_NETWORK_CONNECTIVITY_LOCAL; + case NM_CONNECTIVITY_PORTAL: + return G_NETWORK_CONNECTIVITY_PORTAL; + case NM_CONNECTIVITY_LIMITED: + return G_NETWORK_CONNECTIVITY_LIMITED; + case NM_CONNECTIVITY_FULL: + return G_NETWORK_CONNECTIVITY_FULL; + default: + g_warning ("Unknown NM connectivity state %d", nm_state); + return G_NETWORK_CONNECTIVITY_LOCAL; + } +} + +static gboolean +nm_metered_to_bool (guint nm_metered) +{ + switch (nm_metered) + { + case 1: /* yes */ + case 3: /* guess-yes */ + return TRUE; + case 0: /* unknown */ + /* We default to FALSE in the unknown-because-you're-not-running-NM + * case, so we should return FALSE in the + * unknown-when-you-are-running-NM case too. */ + case 2: /* no */ + case 4: /* guess-no */ + return FALSE; + default: + g_warning ("Unknown NM metered state %d", nm_metered); + return FALSE; + } +} + +static void +sync_properties (GNetworkMonitorNM *nm, + gboolean emit_signals) +{ + GVariant *v; + NMState nm_state; + NMConnectivityState nm_connectivity; + gboolean new_network_available; + gboolean new_network_metered; + GNetworkConnectivity new_connectivity; + + v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "State"); + if (!v) + return; + + nm_state = g_variant_get_uint32 (v); + g_variant_unref (v); + + v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "Connectivity"); + if (!v) + return; + + nm_connectivity = g_variant_get_uint32 (v); + g_variant_unref (v); + + if (nm_state <= NM_STATE_CONNECTED_LOCAL) + { + new_network_available = FALSE; + new_network_metered = FALSE; + new_connectivity = G_NETWORK_CONNECTIVITY_LOCAL; + } + else if (nm_state <= NM_STATE_CONNECTED_SITE) + { + new_network_available = TRUE; + new_network_metered = FALSE; + if (nm_connectivity == NM_CONNECTIVITY_PORTAL) + { + new_connectivity = G_NETWORK_CONNECTIVITY_PORTAL; + } + else + { + new_connectivity = G_NETWORK_CONNECTIVITY_LIMITED; + } + } + else /* nm_state == NM_STATE_CONNECTED_FULL */ + { + + /* this is only available post NM 1.0 */ + v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "Metered"); + if (v == NULL) + { + new_network_metered = FALSE; + } + else + { + new_network_metered = nm_metered_to_bool (g_variant_get_uint32 (v)); + g_variant_unref (v); + } + + new_network_available = TRUE; + new_connectivity = nm_conn_to_g_conn (nm_connectivity); + } + + if (!emit_signals) + { + nm->priv->network_metered = new_network_metered; + nm->priv->network_available = new_network_available; + nm->priv->connectivity = new_connectivity; + return; + } + + if (new_network_available != nm->priv->network_available) + { + nm->priv->network_available = new_network_available; + g_object_notify (G_OBJECT (nm), "network-available"); + } + if (new_network_metered != nm->priv->network_metered) + { + nm->priv->network_metered = new_network_metered; + g_object_notify (G_OBJECT (nm), "network-metered"); + } + if (new_connectivity != nm->priv->connectivity) + { + nm->priv->connectivity = new_connectivity; + g_object_notify (G_OBJECT (nm), "connectivity"); + } +} + +static void +proxy_properties_changed_cb (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + GNetworkMonitorNM *nm) +{ + sync_properties (nm, TRUE); +} + +static gboolean +has_property (GDBusProxy *proxy, + const char *property_name) +{ + char **props; + gboolean prop_found = FALSE; + + props = g_dbus_proxy_get_cached_property_names (proxy); + + if (!props) + return FALSE; + + prop_found = g_strv_contains ((const gchar * const *) props, property_name); + g_strfreev (props); + return prop_found; +} + +static gboolean +g_network_monitor_nm_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorNM *nm = G_NETWORK_MONITOR_NM (initable); + GDBusProxy *proxy; + GInitableIface *parent_iface; + gchar *name_owner = NULL; + + parent_iface = g_type_interface_peek_parent (G_NETWORK_MONITOR_NM_GET_INITABLE_IFACE (initable)); + if (!parent_iface->init (initable, cancellable, error)) + return FALSE; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + NULL, + "org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.NetworkManager", + cancellable, + error); + if (!proxy) + return FALSE; + + name_owner = g_dbus_proxy_get_name_owner (proxy); + + if (!name_owner) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("NetworkManager not running")); + g_object_unref (proxy); + return FALSE; + } + + g_free (name_owner); + + /* Verify it has the PrimaryConnection and Connectivity properties */ + if (!has_property (proxy, "Connectivity")) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("NetworkManager version too old")); + g_object_unref (proxy); + return FALSE; + } + + nm->priv->signal_id = g_signal_connect (G_OBJECT (proxy), "g-properties-changed", + G_CALLBACK (proxy_properties_changed_cb), nm); + nm->priv->proxy = proxy; + sync_properties (nm, FALSE); + + return TRUE; +} + +static void +g_network_monitor_nm_finalize (GObject *object) +{ + GNetworkMonitorNM *nm = G_NETWORK_MONITOR_NM (object); + + if (nm->priv->proxy != NULL && + nm->priv->signal_id != 0) + { + g_signal_handler_disconnect (nm->priv->proxy, + nm->priv->signal_id); + nm->priv->signal_id = 0; + } + g_clear_object (&nm->priv->proxy); + + G_OBJECT_CLASS (g_network_monitor_nm_parent_class)->finalize (object); +} + +static void +g_network_monitor_nm_class_init (GNetworkMonitorNMClass *nl_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); + + gobject_class->finalize = g_network_monitor_nm_finalize; + gobject_class->get_property = g_network_monitor_nm_get_property; + + g_object_class_override_property (gobject_class, PROP_NETWORK_AVAILABLE, "network-available"); + g_object_class_override_property (gobject_class, PROP_NETWORK_METERED, "network-metered"); + g_object_class_override_property (gobject_class, PROP_CONNECTIVITY, "connectivity"); +} + +static void +g_network_monitor_nm_iface_init (GNetworkMonitorInterface *monitor_iface) +{ +} + +static void +g_network_monitor_nm_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_network_monitor_nm_initable_init; +} diff --git a/gio/gnetworkmonitornm.h b/gio/gnetworkmonitornm.h new file mode 100644 index 0000000..b800089 --- /dev/null +++ b/gio/gnetworkmonitornm.h @@ -0,0 +1,53 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_NETWORK_MONITOR_NM_H__ +#define __G_NETWORK_MONITOR_NM_H__ + +#include "gnetworkmonitornetlink.h" + +G_BEGIN_DECLS + +#define G_TYPE_NETWORK_MONITOR_NM (_g_network_monitor_nm_get_type ()) +#define G_NETWORK_MONITOR_NM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_MONITOR_NM, GNetworkMonitorNM)) +#define G_NETWORK_MONITOR_NM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_MONITOR_NM, GNetworkMonitorNMClass)) +#define G_IS_NETWORK_MONITOR_NM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_MONITOR_NM)) +#define G_IS_NETWORK_MONITOR_NM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NETWORK_MONITOR_NM)) +#define G_NETWORK_MONITOR_NM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NETWORK_MONITOR_NM, GNetworkMonitorNMClass)) +#define G_NETWORK_MONITOR_NM_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + + +typedef struct _GNetworkMonitorNM GNetworkMonitorNM; +typedef struct _GNetworkMonitorNMClass GNetworkMonitorNMClass; +typedef struct _GNetworkMonitorNMPrivate GNetworkMonitorNMPrivate; + +struct _GNetworkMonitorNM { + GNetworkMonitorNetlink parent_instance; + + GNetworkMonitorNMPrivate *priv; +}; + +struct _GNetworkMonitorNMClass { + GNetworkMonitorNetlinkClass parent_class; +}; + +GType _g_network_monitor_nm_get_type (void); + +G_END_DECLS + +#endif /* __G_NETWORK_MONITOR_NM_H__ */ diff --git a/gio/gnetworkmonitorportal.c b/gio/gnetworkmonitorportal.c new file mode 100644 index 0000000..2c0eb8a --- /dev/null +++ b/gio/gnetworkmonitorportal.c @@ -0,0 +1,627 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gnetworkmonitorportal.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "xdp-dbus.h" +#include "gportalsupport.h" + +static GInitableIface *initable_parent_iface; +static void g_network_monitor_portal_iface_init (GNetworkMonitorInterface *iface); +static void g_network_monitor_portal_initable_iface_init (GInitableIface *iface); + +enum +{ + PROP_0, + PROP_NETWORK_AVAILABLE, + PROP_NETWORK_METERED, + PROP_CONNECTIVITY +}; + +struct _GNetworkMonitorPortalPrivate +{ + GDBusProxy *proxy; + gboolean has_network; + + gboolean available; + gboolean metered; + GNetworkConnectivity connectivity; +}; + +G_DEFINE_TYPE_WITH_CODE (GNetworkMonitorPortal, g_network_monitor_portal, G_TYPE_NETWORK_MONITOR_BASE, + G_ADD_PRIVATE (GNetworkMonitorPortal) + G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR, + g_network_monitor_portal_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_network_monitor_portal_initable_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "portal", + 40)) + +static void +g_network_monitor_portal_init (GNetworkMonitorPortal *nm) +{ + nm->priv = g_network_monitor_portal_get_instance_private (nm); +} + +static void +g_network_monitor_portal_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (object); + + switch (prop_id) + { + case PROP_NETWORK_AVAILABLE: + g_value_set_boolean (value, nm->priv->available); + break; + + case PROP_NETWORK_METERED: + g_value_set_boolean (value, nm->priv->metered); + break; + + case PROP_CONNECTIVITY: + g_value_set_enum (value, nm->priv->connectivity); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +is_valid_connectivity (guint32 value) +{ + GEnumValue *enum_value; + GEnumClass *enum_klass; + + enum_klass = g_type_class_ref (G_TYPE_NETWORK_CONNECTIVITY); + enum_value = g_enum_get_value (enum_klass, value); + + g_type_class_unref (enum_klass); + + return enum_value != NULL; +} + +static void +got_available (GObject *source, + GAsyncResult *res, + gpointer data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (source); + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (data); + GError *error = NULL; + GVariant *ret; + gboolean available; + + ret = g_dbus_proxy_call_finish (proxy, res, &error); + if (ret == NULL) + { + if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) + { + g_warning ("%s", error->message); + g_clear_error (&error); + return; + } + + g_clear_error (&error); + + /* Fall back to version 1 */ + ret = g_dbus_proxy_get_cached_property (nm->priv->proxy, "available"); + if (ret == NULL) + { + g_warning ("Failed to get the '%s' property", "available"); + return; + } + + available = g_variant_get_boolean (ret); + g_variant_unref (ret); + } + else + { + g_variant_get (ret, "(b)", &available); + g_variant_unref (ret); + } + + if (nm->priv->available != available) + { + nm->priv->available = available; + g_object_notify (G_OBJECT (nm), "network-available"); + g_signal_emit_by_name (nm, "network-changed", available); + } +} + +static void +got_metered (GObject *source, + GAsyncResult *res, + gpointer data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (source); + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (data); + GError *error = NULL; + GVariant *ret; + gboolean metered; + + ret = g_dbus_proxy_call_finish (proxy, res, &error); + if (ret == NULL) + { + if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) + { + g_warning ("%s", error->message); + g_clear_error (&error); + return; + } + + g_clear_error (&error); + + /* Fall back to version 1 */ + ret = g_dbus_proxy_get_cached_property (nm->priv->proxy, "metered"); + if (ret == NULL) + { + g_warning ("Failed to get the '%s' property", "metered"); + return; + } + + metered = g_variant_get_boolean (ret); + g_variant_unref (ret); + } + else + { + g_variant_get (ret, "(b)", &metered); + g_variant_unref (ret); + } + + if (nm->priv->metered != metered) + { + nm->priv->metered = metered; + g_object_notify (G_OBJECT (nm), "network-metered"); + g_signal_emit_by_name (nm, "network-changed", nm->priv->available); + } +} + +static void +got_connectivity (GObject *source, + GAsyncResult *res, + gpointer data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (source); + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (data); + GError *error = NULL; + GVariant *ret; + GNetworkConnectivity connectivity; + + ret = g_dbus_proxy_call_finish (proxy, res, &error); + if (ret == NULL) + { + if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) + { + g_warning ("%s", error->message); + g_clear_error (&error); + return; + } + + g_clear_error (&error); + + /* Fall back to version 1 */ + ret = g_dbus_proxy_get_cached_property (nm->priv->proxy, "connectivity"); + if (ret == NULL) + { + g_warning ("Failed to get the '%s' property", "connectivity"); + return; + } + + connectivity = g_variant_get_uint32 (ret); + g_variant_unref (ret); + } + else + { + g_variant_get (ret, "(u)", &connectivity); + g_variant_unref (ret); + } + + if (nm->priv->connectivity != connectivity && + is_valid_connectivity (connectivity)) + { + nm->priv->connectivity = connectivity; + g_object_notify (G_OBJECT (nm), "connectivity"); + g_signal_emit_by_name (nm, "network-changed", nm->priv->available); + } +} + +static void +got_status (GObject *source, + GAsyncResult *res, + gpointer data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (source); + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (data); + GError *error = NULL; + GVariant *ret; + GVariant *status; + gboolean available; + gboolean metered; + GNetworkConnectivity connectivity; + + ret = g_dbus_proxy_call_finish (proxy, res, &error); + if (ret == NULL) + { + if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) + { + /* Fall back to version 2 */ + g_dbus_proxy_call (proxy, "GetConnectivity", NULL, 0, -1, NULL, got_connectivity, nm); + g_dbus_proxy_call (proxy, "GetMetered", NULL, 0, -1, NULL, got_metered, nm); + g_dbus_proxy_call (proxy, "GetAvailable", NULL, 0, -1, NULL, got_available, nm); + } + else + g_warning ("%s", error->message); + + g_clear_error (&error); + return; + } + + g_variant_get (ret, "(@a{sv})", &status); + g_variant_unref (ret); + + g_variant_lookup (status, "available", "b", &available); + g_variant_lookup (status, "metered", "b", &metered); + g_variant_lookup (status, "connectivity", "u", &connectivity); + g_variant_unref (status); + + g_object_freeze_notify (G_OBJECT (nm)); + + if (nm->priv->available != available) + { + nm->priv->available = available; + g_object_notify (G_OBJECT (nm), "network-available"); + } + + if (nm->priv->metered != metered) + { + nm->priv->metered = metered; + g_object_notify (G_OBJECT (nm), "network-metered"); + } + + if (nm->priv->connectivity != connectivity && + is_valid_connectivity (connectivity)) + { + nm->priv->connectivity = connectivity; + g_object_notify (G_OBJECT (nm), "connectivity"); + } + + g_object_thaw_notify (G_OBJECT (nm)); + + g_signal_emit_by_name (nm, "network-changed", available); +} + +static void +update_properties (GDBusProxy *proxy, + GNetworkMonitorPortal *nm) +{ + /* Try version 3 first */ + g_dbus_proxy_call (proxy, "GetStatus", NULL, 0, -1, NULL, got_status, nm); +} + +static void +proxy_signal (GDBusProxy *proxy, + const char *sender, + const char *signal, + GVariant *parameters, + GNetworkMonitorPortal *nm) +{ + if (!nm->priv->has_network) + return; + + if (strcmp (signal, "changed") != 0) + return; + + /* Version 1 updates "available" with the "changed" signal */ + if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(b)"))) + { + gboolean available; + + g_variant_get (parameters, "(b)", &available); + if (nm->priv->available != available) + { + nm->priv->available = available; + g_object_notify (G_OBJECT (nm), "available"); + } + g_signal_emit_by_name (nm, "network-changed", available); + } + else + { + update_properties (proxy, nm); + } +} + +static void +proxy_properties_changed (GDBusProxy *proxy, + GVariant *changed, + GVariant *invalidated, + GNetworkMonitorPortal *nm) +{ + gboolean should_emit_changed = FALSE; + GVariant *ret; + + if (!nm->priv->has_network) + return; + + ret = g_dbus_proxy_get_cached_property (proxy, "connectivity"); + if (ret) + { + GNetworkConnectivity connectivity = g_variant_get_uint32 (ret); + if (nm->priv->connectivity != connectivity && + is_valid_connectivity (connectivity)) + { + nm->priv->connectivity = connectivity; + g_object_notify (G_OBJECT (nm), "connectivity"); + should_emit_changed = TRUE; + } + g_variant_unref (ret); + } + + ret = g_dbus_proxy_get_cached_property (proxy, "metered"); + if (ret) + { + gboolean metered = g_variant_get_boolean (ret); + if (nm->priv->metered != metered) + { + nm->priv->metered = metered; + g_object_notify (G_OBJECT (nm), "network-metered"); + should_emit_changed = TRUE; + } + g_variant_unref (ret); + } + + ret = g_dbus_proxy_get_cached_property (proxy, "available"); + if (ret) + { + gboolean available = g_variant_get_boolean (ret); + if (nm->priv->available != available) + { + nm->priv->available = available; + g_object_notify (G_OBJECT (nm), "network-available"); + should_emit_changed = TRUE; + } + g_variant_unref (ret); + } + + if (should_emit_changed) + g_signal_emit_by_name (nm, "network-changed", nm->priv->available); +} + +static gboolean +g_network_monitor_portal_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (initable); + GDBusProxy *proxy; + gchar *name_owner = NULL; + + nm->priv->available = FALSE; + nm->priv->metered = FALSE; + nm->priv->connectivity = G_NETWORK_CONNECTIVITY_LOCAL; + + if (!glib_should_use_portal ()) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not using portals"); + return FALSE; + } + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.NetworkMonitor", + cancellable, + error); + if (!proxy) + return FALSE; + + name_owner = g_dbus_proxy_get_name_owner (proxy); + + if (!name_owner) + { + g_object_unref (proxy); + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_NAME_HAS_NO_OWNER, + "Desktop portal not found"); + return FALSE; + } + + g_free (name_owner); + + g_signal_connect (proxy, "g-signal", G_CALLBACK (proxy_signal), nm); + g_signal_connect (proxy, "g-properties-changed", G_CALLBACK (proxy_properties_changed), nm); + + nm->priv->proxy = proxy; + nm->priv->has_network = glib_network_available_in_sandbox (); + + if (!initable_parent_iface->init (initable, cancellable, error)) + return FALSE; + + if (nm->priv->has_network) + update_properties (proxy, nm); + + return TRUE; +} + +static void +g_network_monitor_portal_finalize (GObject *object) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (object); + + g_clear_object (&nm->priv->proxy); + + G_OBJECT_CLASS (g_network_monitor_portal_parent_class)->finalize (object); +} + +static void +g_network_monitor_portal_class_init (GNetworkMonitorPortalClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->finalize = g_network_monitor_portal_finalize; + gobject_class->get_property = g_network_monitor_portal_get_property; + + g_object_class_override_property (gobject_class, PROP_NETWORK_AVAILABLE, "network-available"); + g_object_class_override_property (gobject_class, PROP_NETWORK_METERED, "network-metered"); + g_object_class_override_property (gobject_class, PROP_CONNECTIVITY, "connectivity"); +} + +static gboolean +g_network_monitor_portal_can_reach (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GError **error) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (monitor); + GVariant *ret; + GNetworkAddress *address; + gboolean reachable = FALSE; + + if (!G_IS_NETWORK_ADDRESS (connectable)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Can't handle this kind of GSocketConnectable (%s)", + G_OBJECT_TYPE_NAME (connectable)); + return FALSE; + } + + address = G_NETWORK_ADDRESS (connectable); + + ret = g_dbus_proxy_call_sync (nm->priv->proxy, + "CanReach", + g_variant_new ("(su)", + g_network_address_get_hostname (address), + g_network_address_get_port (address)), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + + if (ret) + { + g_variant_get (ret, "(b)", &reachable); + g_variant_unref (ret); + } + + return reachable; +} + +static void +can_reach_done (GObject *source, + GAsyncResult *result, + gpointer data) +{ + GTask *task = data; + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (g_task_get_source_object (task)); + GError *error = NULL; + GVariant *ret; + gboolean reachable; + + ret = g_dbus_proxy_call_finish (nm->priv->proxy, result, &error); + if (ret == NULL) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_variant_get (ret, "(b)", &reachable); + g_variant_unref (ret); + + if (reachable) + g_task_return_boolean (task, TRUE); + else + g_task_return_new_error (task, + G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, + "Can't reach host"); + + g_object_unref (task); +} + +static void +g_network_monitor_portal_can_reach_async (GNetworkMonitor *monitor, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data) +{ + GNetworkMonitorPortal *nm = G_NETWORK_MONITOR_PORTAL (monitor); + GTask *task; + GNetworkAddress *address; + + task = g_task_new (monitor, cancellable, callback, data); + + if (!G_IS_NETWORK_ADDRESS (connectable)) + { + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Can't handle this kind of GSocketConnectable (%s)", + G_OBJECT_TYPE_NAME (connectable)); + g_object_unref (task); + return; + } + + address = G_NETWORK_ADDRESS (connectable); + + g_dbus_proxy_call (nm->priv->proxy, + "CanReach", + g_variant_new ("(su)", + g_network_address_get_hostname (address), + g_network_address_get_port (address)), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + can_reach_done, + task); +} + +static gboolean +g_network_monitor_portal_can_reach_finish (GNetworkMonitor *monitor, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +g_network_monitor_portal_iface_init (GNetworkMonitorInterface *monitor_iface) +{ + monitor_iface->can_reach = g_network_monitor_portal_can_reach; + monitor_iface->can_reach_async = g_network_monitor_portal_can_reach_async; + monitor_iface->can_reach_finish = g_network_monitor_portal_can_reach_finish; +} + +static void +g_network_monitor_portal_initable_iface_init (GInitableIface *iface) +{ + initable_parent_iface = g_type_interface_peek_parent (iface); + + iface->init = g_network_monitor_portal_initable_init; +} diff --git a/gio/gnetworkmonitorportal.h b/gio/gnetworkmonitorportal.h new file mode 100644 index 0000000..3b2a391 --- /dev/null +++ b/gio/gnetworkmonitorportal.h @@ -0,0 +1,53 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_NETWORK_MONITOR_PORTAL_H__ +#define __G_NETWORK_MONITOR_PORTAL_H__ + +#include "gnetworkmonitorbase.h" + +G_BEGIN_DECLS + +#define G_TYPE_NETWORK_MONITOR_PORTAL (g_network_monitor_portal_get_type ()) +#define G_NETWORK_MONITOR_PORTAL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_MONITOR_PORTAL, GNetworkMonitorPortal)) +#define G_NETWORK_MONITOR_PORTAL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_MONITOR_PORTAL, GNetworkMonitorPortalClass)) +#define G_IS_NETWORK_MONITOR_PORTAL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_MONITOR_PORTAL)) +#define G_IS_NETWORK_MONITOR_PORTAL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NETWORK_MONITOR_PORTAL)) +#define G_NETWORK_MONITOR_PORTAL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NETWORK_MONITOR_PORTAL, GNetworkMonitorPortalClass)) +#define G_NETWORK_MONITOR_PORTAL_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + + +typedef struct _GNetworkMonitorPortal GNetworkMonitorPortal; +typedef struct _GNetworkMonitorPortalClass GNetworkMonitorPortalClass; +typedef struct _GNetworkMonitorPortalPrivate GNetworkMonitorPortalPrivate; + +struct _GNetworkMonitorPortal { + GNetworkMonitorBase parent_instance; + + GNetworkMonitorPortalPrivate *priv; +}; + +struct _GNetworkMonitorPortalClass { + GNetworkMonitorBaseClass parent_class; +}; + +GType g_network_monitor_portal_get_type (void); + +G_END_DECLS + +#endif /* __G_NETWORK_MONITOR_PORTAL_H__ */ diff --git a/gio/gnetworkservice.c b/gio/gnetworkservice.c new file mode 100644 index 0000000..f5ba9d8 --- /dev/null +++ b/gio/gnetworkservice.c @@ -0,0 +1,766 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include +#include "glibintl.h" + +#include "gnetworkservice.h" + +#include "gcancellable.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "gioerror.h" +#include "gnetworkaddress.h" +#include "gnetworkingprivate.h" +#include "gresolver.h" +#include "gtask.h" +#include "gsocketaddressenumerator.h" +#include "gsocketconnectable.h" +#include "gsrvtarget.h" + +#include +#include + + +/** + * SECTION:gnetworkservice + * @short_description: A GSocketConnectable for resolving SRV records + * @include: gio/gio.h + * + * Like #GNetworkAddress does with hostnames, #GNetworkService + * provides an easy way to resolve a SRV record, and then attempt to + * connect to one of the hosts that implements that service, handling + * service priority/weighting, multiple IP addresses, and multiple + * address families. + * + * See #GSrvTarget for more information about SRV records, and see + * #GSocketConnectable for an example of using the connectable + * interface. + */ + +/** + * GNetworkService: + * + * A #GSocketConnectable for resolving a SRV record and connecting to + * that service. + */ + +struct _GNetworkServicePrivate +{ + gchar *service, *protocol, *domain, *scheme; + GList *targets; +}; + +enum { + PROP_0, + PROP_SERVICE, + PROP_PROTOCOL, + PROP_DOMAIN, + PROP_SCHEME +}; + +static void g_network_service_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_network_service_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void g_network_service_connectable_iface_init (GSocketConnectableIface *iface); +static GSocketAddressEnumerator *g_network_service_connectable_enumerate (GSocketConnectable *connectable); +static GSocketAddressEnumerator *g_network_service_connectable_proxy_enumerate (GSocketConnectable *connectable); +static gchar *g_network_service_connectable_to_string (GSocketConnectable *connectable); + +G_DEFINE_TYPE_WITH_CODE (GNetworkService, g_network_service, G_TYPE_OBJECT, + G_ADD_PRIVATE (GNetworkService) + G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE, + g_network_service_connectable_iface_init)) + +static void +g_network_service_finalize (GObject *object) +{ + GNetworkService *srv = G_NETWORK_SERVICE (object); + + g_free (srv->priv->service); + g_free (srv->priv->protocol); + g_free (srv->priv->domain); + g_free (srv->priv->scheme); + + if (srv->priv->targets) + g_resolver_free_targets (srv->priv->targets); + + G_OBJECT_CLASS (g_network_service_parent_class)->finalize (object); +} + +static void +g_network_service_class_init (GNetworkServiceClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = g_network_service_set_property; + gobject_class->get_property = g_network_service_get_property; + gobject_class->finalize = g_network_service_finalize; + + g_object_class_install_property (gobject_class, PROP_SERVICE, + g_param_spec_string ("service", + P_("Service"), + P_("Service name, eg \"ldap\""), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PROTOCOL, + g_param_spec_string ("protocol", + P_("Protocol"), + P_("Network protocol, eg \"tcp\""), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_DOMAIN, + g_param_spec_string ("domain", + P_("Domain"), + P_("Network domain, eg, \"example.com\""), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_DOMAIN, + g_param_spec_string ("scheme", + P_("Scheme"), + P_("Network scheme (default is to use service)"), + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + +} + +static void +g_network_service_connectable_iface_init (GSocketConnectableIface *connectable_iface) +{ + connectable_iface->enumerate = g_network_service_connectable_enumerate; + connectable_iface->proxy_enumerate = g_network_service_connectable_proxy_enumerate; + connectable_iface->to_string = g_network_service_connectable_to_string; +} + +static void +g_network_service_init (GNetworkService *srv) +{ + srv->priv = g_network_service_get_instance_private (srv); +} + +static void +g_network_service_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GNetworkService *srv = G_NETWORK_SERVICE (object); + + switch (prop_id) + { + case PROP_SERVICE: + srv->priv->service = g_value_dup_string (value); + break; + + case PROP_PROTOCOL: + srv->priv->protocol = g_value_dup_string (value); + break; + + case PROP_DOMAIN: + srv->priv->domain = g_value_dup_string (value); + break; + + case PROP_SCHEME: + g_network_service_set_scheme (srv, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_network_service_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GNetworkService *srv = G_NETWORK_SERVICE (object); + + switch (prop_id) + { + case PROP_SERVICE: + g_value_set_string (value, g_network_service_get_service (srv)); + break; + + case PROP_PROTOCOL: + g_value_set_string (value, g_network_service_get_protocol (srv)); + break; + + case PROP_DOMAIN: + g_value_set_string (value, g_network_service_get_domain (srv)); + break; + + case PROP_SCHEME: + g_value_set_string (value, g_network_service_get_scheme (srv)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/** + * g_network_service_new: + * @service: the service type to look up (eg, "ldap") + * @protocol: the networking protocol to use for @service (eg, "tcp") + * @domain: the DNS domain to look up the service in + * + * Creates a new #GNetworkService representing the given @service, + * @protocol, and @domain. This will initially be unresolved; use the + * #GSocketConnectable interface to resolve it. + * + * Returns: (transfer full) (type GNetworkService): a new #GNetworkService + * + * Since: 2.22 + */ +GSocketConnectable * +g_network_service_new (const gchar *service, + const gchar *protocol, + const gchar *domain) +{ + return g_object_new (G_TYPE_NETWORK_SERVICE, + "service", service, + "protocol", protocol, + "domain", domain, + NULL); +} + +/** + * g_network_service_get_service: + * @srv: a #GNetworkService + * + * Gets @srv's service name (eg, "ldap"). + * + * Returns: @srv's service name + * + * Since: 2.22 + */ +const gchar * +g_network_service_get_service (GNetworkService *srv) +{ + g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL); + + return srv->priv->service; +} + +/** + * g_network_service_get_protocol: + * @srv: a #GNetworkService + * + * Gets @srv's protocol name (eg, "tcp"). + * + * Returns: @srv's protocol name + * + * Since: 2.22 + */ +const gchar * +g_network_service_get_protocol (GNetworkService *srv) +{ + g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL); + + return srv->priv->protocol; +} + +/** + * g_network_service_get_domain: + * @srv: a #GNetworkService + * + * Gets the domain that @srv serves. This might be either UTF-8 or + * ASCII-encoded, depending on what @srv was created with. + * + * Returns: @srv's domain name + * + * Since: 2.22 + */ +const gchar * +g_network_service_get_domain (GNetworkService *srv) +{ + g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL); + + return srv->priv->domain; +} + +/** + * g_network_service_get_scheme: + * @srv: a #GNetworkService + * + * Gets the URI scheme used to resolve proxies. By default, the service name + * is used as scheme. + * + * Returns: @srv's scheme name + * + * Since: 2.26 + */ +const gchar * +g_network_service_get_scheme (GNetworkService *srv) +{ + g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL); + + if (srv->priv->scheme) + return srv->priv->scheme; + else + return srv->priv->service; +} + +/** + * g_network_service_set_scheme: + * @srv: a #GNetworkService + * @scheme: a URI scheme + * + * Set's the URI scheme used to resolve proxies. By default, the service name + * is used as scheme. + * + * Since: 2.26 + */ +void +g_network_service_set_scheme (GNetworkService *srv, + const gchar *scheme) +{ + g_return_if_fail (G_IS_NETWORK_SERVICE (srv)); + + g_free (srv->priv->scheme); + srv->priv->scheme = g_strdup (scheme); + + g_object_notify (G_OBJECT (srv), "scheme"); +} + +static GList * +g_network_service_fallback_targets (GNetworkService *srv) +{ + GSrvTarget *target; + struct servent *entry; + guint16 port; + + entry = getservbyname (srv->priv->service, "tcp"); + port = entry ? g_ntohs (entry->s_port) : 0; +#ifdef HAVE_ENDSERVENT + endservent (); +#endif + + if (entry == NULL) + return NULL; + + target = g_srv_target_new (srv->priv->domain, port, 0, 0); + return g_list_append (NULL, target); +} + +#define G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR (_g_network_service_address_enumerator_get_type ()) +#define G_NETWORK_SERVICE_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR, GNetworkServiceAddressEnumerator)) + +typedef struct { + GSocketAddressEnumerator parent_instance; + + GResolver *resolver; + GNetworkService *srv; + GSocketAddressEnumerator *addr_enum; + GList *t; + gboolean use_proxy; + + GError *error; + +} GNetworkServiceAddressEnumerator; + +typedef struct { + GSocketAddressEnumeratorClass parent_class; + +} GNetworkServiceAddressEnumeratorClass; + +static GType _g_network_service_address_enumerator_get_type (void); +G_DEFINE_TYPE (GNetworkServiceAddressEnumerator, _g_network_service_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR) + +static GSocketAddress * +g_network_service_address_enumerator_next (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GNetworkServiceAddressEnumerator *srv_enum = + G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (enumerator); + GSocketAddress *ret = NULL; + + /* If we haven't yet resolved srv, do that */ + if (!srv_enum->srv->priv->targets) + { + GList *targets; + GError *my_error = NULL; + + targets = g_resolver_lookup_service (srv_enum->resolver, + srv_enum->srv->priv->service, + srv_enum->srv->priv->protocol, + srv_enum->srv->priv->domain, + cancellable, &my_error); + if (!targets && g_error_matches (my_error, G_RESOLVER_ERROR, + G_RESOLVER_ERROR_NOT_FOUND)) + { + targets = g_network_service_fallback_targets (srv_enum->srv); + if (targets) + g_clear_error (&my_error); + } + + if (my_error) + { + g_propagate_error (error, my_error); + return NULL; + } + + srv_enum->srv->priv->targets = targets; + srv_enum->t = srv_enum->srv->priv->targets; + } + + /* Delegate to GNetworkAddress */ + do + { + if (srv_enum->addr_enum == NULL && srv_enum->t) + { + GError *my_error = NULL; + gchar *uri; + gchar *hostname; + GSocketConnectable *addr; + GSrvTarget *target = srv_enum->t->data; + + srv_enum->t = g_list_next (srv_enum->t); + + hostname = g_hostname_to_ascii (g_srv_target_get_hostname (target)); + + if (hostname == NULL) + { + if (srv_enum->error == NULL) + srv_enum->error = + g_error_new (G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "Received invalid hostname '%s' from GSrvTarget", + g_srv_target_get_hostname (target)); + continue; + } + + uri = g_uri_join (G_URI_FLAGS_NONE, + g_network_service_get_scheme (srv_enum->srv), + NULL, + hostname, + g_srv_target_get_port (target), + "", + NULL, + NULL); + g_free (hostname); + + addr = g_network_address_parse_uri (uri, + g_srv_target_get_port (target), + &my_error); + g_free (uri); + + if (addr == NULL) + { + if (srv_enum->error == NULL) + srv_enum->error = my_error; + else + g_error_free (my_error); + continue; + } + + if (srv_enum->use_proxy) + srv_enum->addr_enum = g_socket_connectable_proxy_enumerate (addr); + else + srv_enum->addr_enum = g_socket_connectable_enumerate (addr); + g_object_unref (addr); + } + + if (srv_enum->addr_enum) + { + GError *my_error = NULL; + + ret = g_socket_address_enumerator_next (srv_enum->addr_enum, + cancellable, + &my_error); + + if (my_error) + { + if (srv_enum->error == NULL) + srv_enum->error = my_error; + else + g_error_free (my_error); + } + + if (!ret) + { + g_object_unref (srv_enum->addr_enum); + srv_enum->addr_enum = NULL; + } + } + } + while (srv_enum->addr_enum == NULL && srv_enum->t); + + if (ret == NULL && srv_enum->error) + { + g_propagate_error (error, srv_enum->error); + srv_enum->error = NULL; + } + + return ret; +} + +static void next_async_resolved_targets (GObject *source_object, + GAsyncResult *result, + gpointer user_data); +static void next_async_have_targets (GTask *srv_enum); +static void next_async_have_address (GObject *source_object, + GAsyncResult *result, + gpointer user_data); + +static void +g_network_service_address_enumerator_next_async (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GNetworkServiceAddressEnumerator *srv_enum = + G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (enumerator); + GTask *task; + + task = g_task_new (enumerator, cancellable, callback, user_data); + g_task_set_source_tag (task, g_network_service_address_enumerator_next_async); + + /* If we haven't yet resolved srv, do that */ + if (!srv_enum->srv->priv->targets) + { + g_resolver_lookup_service_async (srv_enum->resolver, + srv_enum->srv->priv->service, + srv_enum->srv->priv->protocol, + srv_enum->srv->priv->domain, + cancellable, + next_async_resolved_targets, + task); + } + else + next_async_have_targets (task); +} + +static void +next_async_resolved_targets (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task); + GError *error = NULL; + GList *targets; + + targets = g_resolver_lookup_service_finish (srv_enum->resolver, + result, &error); + + if (!targets && g_error_matches (error, G_RESOLVER_ERROR, + G_RESOLVER_ERROR_NOT_FOUND)) + { + targets = g_network_service_fallback_targets (srv_enum->srv); + if (targets) + g_clear_error (&error); + } + + if (error) + { + g_task_return_error (task, error); + g_object_unref (task); + } + else + { + srv_enum->t = srv_enum->srv->priv->targets = targets; + next_async_have_targets (task); + } +} + +static void +next_async_have_targets (GTask *task) +{ + GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task); + + /* Delegate to GNetworkAddress */ + if (srv_enum->addr_enum == NULL && srv_enum->t) + { + GSocketConnectable *addr; + GSrvTarget *target = srv_enum->t->data; + + srv_enum->t = g_list_next (srv_enum->t); + addr = g_network_address_new (g_srv_target_get_hostname (target), + (guint16) g_srv_target_get_port (target)); + + if (srv_enum->use_proxy) + srv_enum->addr_enum = g_socket_connectable_proxy_enumerate (addr); + else + srv_enum->addr_enum = g_socket_connectable_enumerate (addr); + + g_object_unref (addr); + } + + if (srv_enum->addr_enum) + { + g_socket_address_enumerator_next_async (srv_enum->addr_enum, + g_task_get_cancellable (task), + next_async_have_address, + task); + } + else + { + if (srv_enum->error) + { + g_task_return_error (task, srv_enum->error); + srv_enum->error = NULL; + } + else + g_task_return_pointer (task, NULL, NULL); + + g_object_unref (task); + } +} + +static void +next_async_have_address (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task); + GSocketAddress *address; + GError *error = NULL; + + address = g_socket_address_enumerator_next_finish (srv_enum->addr_enum, + result, + &error); + + if (error) + { + if (srv_enum->error == NULL) + srv_enum->error = error; + else + g_error_free (error); + } + + if (!address) + { + g_object_unref (srv_enum->addr_enum); + srv_enum->addr_enum = NULL; + + next_async_have_targets (task); + } + else + { + g_task_return_pointer (task, address, g_object_unref); + g_object_unref (task); + } +} + +static GSocketAddress * +g_network_service_address_enumerator_next_finish (GSocketAddressEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +_g_network_service_address_enumerator_init (GNetworkServiceAddressEnumerator *enumerator) +{ +} + +static void +g_network_service_address_enumerator_finalize (GObject *object) +{ + GNetworkServiceAddressEnumerator *srv_enum = + G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (object); + + if (srv_enum->srv) + g_object_unref (srv_enum->srv); + + if (srv_enum->addr_enum) + g_object_unref (srv_enum->addr_enum); + + if (srv_enum->resolver) + g_object_unref (srv_enum->resolver); + + if (srv_enum->error) + g_error_free (srv_enum->error); + + G_OBJECT_CLASS (_g_network_service_address_enumerator_parent_class)->finalize (object); +} + +static void +_g_network_service_address_enumerator_class_init (GNetworkServiceAddressEnumeratorClass *srvenum_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (srvenum_class); + GSocketAddressEnumeratorClass *enumerator_class = + G_SOCKET_ADDRESS_ENUMERATOR_CLASS (srvenum_class); + + enumerator_class->next = g_network_service_address_enumerator_next; + enumerator_class->next_async = g_network_service_address_enumerator_next_async; + enumerator_class->next_finish = g_network_service_address_enumerator_next_finish; + + object_class->finalize = g_network_service_address_enumerator_finalize; +} + +static GSocketAddressEnumerator * +g_network_service_connectable_enumerate (GSocketConnectable *connectable) +{ + GNetworkServiceAddressEnumerator *srv_enum; + + srv_enum = g_object_new (G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR, NULL); + srv_enum->srv = g_object_ref (G_NETWORK_SERVICE (connectable)); + srv_enum->resolver = g_resolver_get_default (); + srv_enum->use_proxy = FALSE; + + return G_SOCKET_ADDRESS_ENUMERATOR (srv_enum); +} + +static GSocketAddressEnumerator * +g_network_service_connectable_proxy_enumerate (GSocketConnectable *connectable) +{ + GSocketAddressEnumerator *addr_enum; + GNetworkServiceAddressEnumerator *srv_enum; + + addr_enum = g_network_service_connectable_enumerate (connectable); + srv_enum = G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (addr_enum); + srv_enum->use_proxy = TRUE; + + return addr_enum; +} + +static gchar * +g_network_service_connectable_to_string (GSocketConnectable *connectable) +{ + GNetworkService *service; + + service = G_NETWORK_SERVICE (connectable); + + return g_strdup_printf ("(%s, %s, %s, %s)", service->priv->service, + service->priv->protocol, service->priv->domain, + service->priv->scheme); +} diff --git a/gio/gnetworkservice.h b/gio/gnetworkservice.h new file mode 100644 index 0000000..e4d76cb --- /dev/null +++ b/gio/gnetworkservice.h @@ -0,0 +1,75 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_NETWORK_SERVICE_H__ +#define __G_NETWORK_SERVICE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_NETWORK_SERVICE (g_network_service_get_type ()) +#define G_NETWORK_SERVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_SERVICE, GNetworkService)) +#define G_NETWORK_SERVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_SERVICE, GNetworkServiceClass)) +#define G_IS_NETWORK_SERVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_SERVICE)) +#define G_IS_NETWORK_SERVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NETWORK_SERVICE)) +#define G_NETWORK_SERVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NETWORK_SERVICE, GNetworkServiceClass)) + +typedef struct _GNetworkServiceClass GNetworkServiceClass; +typedef struct _GNetworkServicePrivate GNetworkServicePrivate; + +struct _GNetworkService +{ + GObject parent_instance; + + /*< private >*/ + GNetworkServicePrivate *priv; +}; + +struct _GNetworkServiceClass +{ + GObjectClass parent_class; + +}; + +GLIB_AVAILABLE_IN_ALL +GType g_network_service_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketConnectable *g_network_service_new (const gchar *service, + const gchar *protocol, + const gchar *domain); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_network_service_get_service (GNetworkService *srv); +GLIB_AVAILABLE_IN_ALL +const gchar *g_network_service_get_protocol (GNetworkService *srv); +GLIB_AVAILABLE_IN_ALL +const gchar *g_network_service_get_domain (GNetworkService *srv); +GLIB_AVAILABLE_IN_ALL +const gchar *g_network_service_get_scheme (GNetworkService *srv); +GLIB_AVAILABLE_IN_ALL +void g_network_service_set_scheme (GNetworkService *srv, const gchar *scheme); + +G_END_DECLS + +#endif /* __G_NETWORK_SERVICE_H__ */ diff --git a/gio/gnextstepsettingsbackend.m b/gio/gnextstepsettingsbackend.m new file mode 100644 index 0000000..cde636c --- /dev/null +++ b/gio/gnextstepsettingsbackend.m @@ -0,0 +1,481 @@ +/* + * Copyright © 2011 William Hua + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: William Hua + */ + +#include "config.h" + +#include "gsettingsbackendinternal.h" +#include "gsimplepermission.h" +#include "giomodule-priv.h" + +#import + +GType g_nextstep_settings_backend_get_type (void); + +#define G_NEXTSTEP_SETTINGS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), g_nextstep_settings_backend_get_type (), GNextstepSettingsBackend)) + +typedef struct _GNextstepSettingsBackend GNextstepSettingsBackend; +typedef GSettingsBackendClass GNextstepSettingsBackendClass; + +struct _GNextstepSettingsBackend +{ + GSettingsBackend parent_instance; + + /*< private >*/ + NSUserDefaults *user_defaults; + GMutex mutex; +}; + +G_DEFINE_TYPE_WITH_CODE (GNextstepSettingsBackend, + g_nextstep_settings_backend, + G_TYPE_SETTINGS_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "nextstep", 90)); + +static void g_nextstep_settings_backend_finalize (GObject *backend); + +static GVariant * g_nextstep_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value); + +static gboolean g_nextstep_settings_backend_get_writable (GSettingsBackend *backend, + const gchar *key); + +static gboolean g_nextstep_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag); + +static gboolean g_nextstep_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag); + +static void g_nextstep_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag); + +static void g_nextstep_settings_backend_subscribe (GSettingsBackend *backend, + const gchar *name); + +static void g_nextstep_settings_backend_unsubscribe (GSettingsBackend *backend, + const gchar *name); + +static void g_nextstep_settings_backend_sync (GSettingsBackend *backend); + +static GPermission * g_nextstep_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path); + +static gboolean g_nextstep_settings_backend_write_pair (gpointer name, + gpointer value, + gpointer data); + +static GVariant * g_nextstep_settings_backend_get_g_variant (id object, + const GVariantType *type); + +static id g_nextstep_settings_backend_get_ns_object (GVariant *variant); + +static void +g_nextstep_settings_backend_class_init (GNextstepSettingsBackendClass *class) +{ + G_OBJECT_CLASS (class)->finalize = g_nextstep_settings_backend_finalize; + class->read = g_nextstep_settings_backend_read; + class->get_writable = g_nextstep_settings_backend_get_writable; + class->write = g_nextstep_settings_backend_write; + class->write_tree = g_nextstep_settings_backend_write_tree; + class->reset = g_nextstep_settings_backend_reset; + class->subscribe = g_nextstep_settings_backend_subscribe; + class->unsubscribe = g_nextstep_settings_backend_unsubscribe; + class->sync = g_nextstep_settings_backend_sync; + class->get_permission = g_nextstep_settings_backend_get_permission; +} + +static void +g_nextstep_settings_backend_init (GNextstepSettingsBackend *self) +{ + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; + + self->user_defaults = [[NSUserDefaults standardUserDefaults] retain]; + + g_mutex_init (&self->mutex); + + [pool drain]; +} + +static void +g_nextstep_settings_backend_finalize (GObject *self) +{ + GNextstepSettingsBackend *backend = G_NEXTSTEP_SETTINGS_BACKEND (self); + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; + + g_mutex_clear (&backend->mutex); + + [backend->user_defaults release]; + + [pool drain]; + + G_OBJECT_CLASS (g_nextstep_settings_backend_parent_class)->finalize (self); +} + +static GVariant * +g_nextstep_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value) +{ + GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend); + NSAutoreleasePool *pool; + NSString *name; + id value; + GVariant *variant; + + if (default_value) + return NULL; + + pool = [[NSAutoreleasePool alloc] init]; + name = [NSString stringWithUTF8String:key]; + + g_mutex_lock (&self->mutex); + value = [self->user_defaults objectForKey:name]; + g_mutex_unlock (&self->mutex); + + variant = g_nextstep_settings_backend_get_g_variant (value, expected_type); + + [pool drain]; + + return variant; +} + +static gboolean +g_nextstep_settings_backend_get_writable (GSettingsBackend *backend, + const gchar *key) +{ + return TRUE; +} + +static gboolean +g_nextstep_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag) +{ + GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend); + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; + + g_mutex_lock (&self->mutex); + g_nextstep_settings_backend_write_pair ((gpointer) key, value, self); + g_mutex_unlock (&self->mutex); + + g_settings_backend_changed (backend, key, origin_tag); + + [pool drain]; + + return TRUE; +} + +static gboolean +g_nextstep_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag) +{ + GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend); + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; + + g_mutex_lock (&self->mutex); + g_tree_foreach (tree, g_nextstep_settings_backend_write_pair, self); + g_mutex_unlock (&self->mutex); + g_settings_backend_changed_tree (backend, tree, origin_tag); + + [pool drain]; + + return TRUE; +} + +static void +g_nextstep_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend); + NSAutoreleasePool *pool; + NSString *name; + + pool = [[NSAutoreleasePool alloc] init]; + name = [NSString stringWithUTF8String:key]; + + g_mutex_lock (&self->mutex); + [self->user_defaults removeObjectForKey:name]; + g_mutex_unlock (&self->mutex); + + g_settings_backend_changed (backend, key, origin_tag); + + [pool drain]; +} + +static void +g_nextstep_settings_backend_subscribe (GSettingsBackend *backend, + const gchar *name) +{ +} + +static void +g_nextstep_settings_backend_unsubscribe (GSettingsBackend *backend, + const gchar *name) +{ +} + +static void +g_nextstep_settings_backend_sync (GSettingsBackend *backend) +{ + GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend); + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; + + g_mutex_lock (&self->mutex); + [self->user_defaults synchronize]; + g_mutex_unlock (&self->mutex); + + [pool drain]; +} + +static GPermission * +g_nextstep_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path) +{ + return g_simple_permission_new (TRUE); +} + +static gboolean +g_nextstep_settings_backend_write_pair (gpointer name, + gpointer value, + gpointer data) +{ + GNextstepSettingsBackend *backend = G_NEXTSTEP_SETTINGS_BACKEND (data); + NSString *key; + id object; + + key = [NSString stringWithUTF8String:name]; + object = g_nextstep_settings_backend_get_ns_object (value); + + [backend->user_defaults setObject:object forKey:key]; + + return FALSE; +} + +static GVariant * +g_nextstep_settings_backend_get_g_variant (id object, + const GVariantType *type) +{ + if ([object isKindOfClass:[NSData class]]) + return g_variant_parse (type, [[[[NSString alloc] initWithData:object encoding:NSUTF8StringEncoding] autorelease] UTF8String], NULL, NULL, NULL); + else if ([object isKindOfClass:[NSNumber class]]) + { + if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN)) + return g_variant_new_boolean ([object boolValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE)) + return g_variant_new_byte ([object unsignedCharValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16)) + return g_variant_new_int16 ([object shortValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16)) + return g_variant_new_uint16 ([object unsignedShortValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) + return g_variant_new_int32 ([object longValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32)) + return g_variant_new_uint32 ([object unsignedLongValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64)) + return g_variant_new_int64 ([object longLongValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64)) + return g_variant_new_uint64 ([object unsignedLongLongValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE)) + return g_variant_new_handle ([object longValue]); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE)) + return g_variant_new_double ([object doubleValue]); + } + else if ([object isKindOfClass:[NSString class]]) + { + const char *string; + + string = [object UTF8String]; + + if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) + return g_variant_new_string (string); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH)) + return g_variant_is_object_path (string) ? + g_variant_new_object_path (string) : NULL; + else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE)) + return g_variant_is_signature (string) ? + g_variant_new_signature (string) : NULL; + } + else if ([object isKindOfClass:[NSDictionary class]]) + { + if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE ("a{s*}"))) + { + const GVariantType *value_type; + GVariantBuilder builder; + NSString *key; + + value_type = g_variant_type_value (g_variant_type_element (type)); + + g_variant_builder_init (&builder, type); + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + for(key in object) +#else + NSEnumerator *enumerator = [object objectEnumerator]; + while((key = [enumerator nextObject])) +#endif + { + GVariant *name; + id value; + GVariant *variant; + GVariant *entry; + + name = g_variant_new_string ([key UTF8String]); + value = [object objectForKey:key]; + variant = g_nextstep_settings_backend_get_g_variant (value, value_type); + + if (variant == NULL) + { + g_variant_builder_clear (&builder); + + return NULL; + } + + entry = g_variant_new_dict_entry (name, variant); + g_variant_builder_add_value (&builder, entry); + } + + return g_variant_builder_end (&builder); + } + } + else if ([object isKindOfClass:[NSArray class]]) + { + if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_ARRAY)) + { + const GVariantType *value_type; + GVariantBuilder builder; + id value; + + value_type = g_variant_type_element (type); + g_variant_builder_init (&builder, type); + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + for(value in object) +#else + NSEnumerator *enumerator = [object objectEnumerator]; + while((value = [enumerator nextObject])) +#endif + { + GVariant *variant = g_nextstep_settings_backend_get_g_variant (value, value_type); + + if (variant == NULL) + { + g_variant_builder_clear (&builder); + + return NULL; + } + + g_variant_builder_add_value (&builder, variant); + } + + return g_variant_builder_end (&builder); + } + } + + return NULL; +} + +static id +g_nextstep_settings_backend_get_ns_object (GVariant *variant) +{ + if (variant == NULL) + return nil; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)) + return [NSNumber numberWithBool:g_variant_get_boolean (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE)) + return [NSNumber numberWithUnsignedChar:g_variant_get_byte (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16)) + return [NSNumber numberWithShort:g_variant_get_int16 (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16)) + return [NSNumber numberWithUnsignedShort:g_variant_get_uint16 (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32)) + return [NSNumber numberWithLong:g_variant_get_int32 (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)) + return [NSNumber numberWithUnsignedLong:g_variant_get_uint32 (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64)) + return [NSNumber numberWithLongLong:g_variant_get_int64 (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64)) + return [NSNumber numberWithUnsignedLongLong:g_variant_get_uint64 (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE)) + return [NSNumber numberWithLong:g_variant_get_handle (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE)) + return [NSNumber numberWithDouble:g_variant_get_double (variant)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)) + return [NSString stringWithUTF8String:g_variant_get_string (variant, NULL)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH)) + return [NSString stringWithUTF8String:g_variant_get_string (variant, NULL)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE)) + return [NSString stringWithUTF8String:g_variant_get_string (variant, NULL)]; + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("a{s*}"))) + { + NSMutableDictionary *dictionary; + GVariantIter iter; + const gchar *name; + GVariant *value; + + dictionary = [NSMutableDictionary dictionaryWithCapacity:g_variant_iter_init (&iter, variant)]; + + while (g_variant_iter_loop (&iter, "{&s*}", &name, &value)) + { + NSString *key; + id object; + + key = [NSString stringWithUTF8String:name]; + object = g_nextstep_settings_backend_get_ns_object (value); + + [dictionary setObject:object forKey:key]; + } + + return dictionary; + } + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_ARRAY)) + { + NSMutableArray *array; + GVariantIter iter; + GVariant *value; + + array = [NSMutableArray arrayWithCapacity:g_variant_iter_init (&iter, variant)]; + + while ((value = g_variant_iter_next_value (&iter)) != NULL) + [array addObject:g_nextstep_settings_backend_get_ns_object (value)]; + + return array; + } + else + return [[NSString stringWithUTF8String:g_variant_print (variant, TRUE)] dataUsingEncoding:NSUTF8StringEncoding]; +} diff --git a/gio/gnotification-private.h b/gio/gnotification-private.h new file mode 100644 index 0000000..ee38457 --- /dev/null +++ b/gio/gnotification-private.h @@ -0,0 +1,54 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#ifndef __G_NOTIFICATION_PRIVATE_H__ +#define __G_NOTIFICATION_PRIVATE_H__ + +#include "gnotification.h" + +const gchar * g_notification_get_id (GNotification *notification); + +const gchar * g_notification_get_title (GNotification *notification); + +const gchar * g_notification_get_body (GNotification *notification); + +const gchar * g_notification_get_category (GNotification *notification); + +GIcon * g_notification_get_icon (GNotification *notification); + +GNotificationPriority g_notification_get_priority (GNotification *notification); + +guint g_notification_get_n_buttons (GNotification *notification); + +void g_notification_get_button (GNotification *notification, + gint index, + gchar **label, + gchar **action, + GVariant **target); + +gint g_notification_get_button_with_action (GNotification *notification, + const gchar *action); + +gboolean g_notification_get_default_action (GNotification *notification, + gchar **action, + GVariant **target); + +GVariant * g_notification_serialize (GNotification *notification); + +#endif diff --git a/gio/gnotification.c b/gio/gnotification.c new file mode 100644 index 0000000..f77cd4e --- /dev/null +++ b/gio/gnotification.c @@ -0,0 +1,859 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#include "config.h" + +#include "gnotification-private.h" +#include "gdbusutils.h" +#include "gicon.h" +#include "gaction.h" +#include "gioenumtypes.h" + +/** + * SECTION:gnotification + * @short_description: User Notifications (pop up messages) + * @include: gio/gio.h + * + * #GNotification is a mechanism for creating a notification to be shown + * to the user -- typically as a pop-up notification presented by the + * desktop environment shell. + * + * The key difference between #GNotification and other similar APIs is + * that, if supported by the desktop environment, notifications sent + * with #GNotification will persist after the application has exited, + * and even across system reboots. + * + * Since the user may click on a notification while the application is + * not running, applications using #GNotification should be able to be + * started as a D-Bus service, using #GApplication. + * + * In order for #GNotification to work, the application must have installed + * a `.desktop` file. For example: + * |[ + * [Desktop Entry] + * Name=Test Application + * Comment=Description of what Test Application does + * Exec=gnome-test-application + * Icon=org.gnome.TestApplication + * Terminal=false + * Type=Application + * Categories=GNOME;GTK;TestApplication Category; + * StartupNotify=true + * DBusActivatable=true + * X-GNOME-UsesNotifications=true + * ]| + * + * The `X-GNOME-UsesNotifications` key indicates to GNOME Control Center + * that this application uses notifications, so it can be listed in the + * Control Center’s ‘Notifications’ panel. + * + * The `.desktop` file must be named as `org.gnome.TestApplication.desktop`, + * where `org.gnome.TestApplication` is the ID passed to g_application_new(). + * + * User interaction with a notification (either the default action, or + * buttons) must be associated with actions on the application (ie: + * "app." actions). It is not possible to route user interaction + * through the notification itself, because the object will not exist if + * the application is autostarted as a result of a notification being + * clicked. + * + * A notification can be sent with g_application_send_notification(). + * + * Since: 2.40 + **/ + +/** + * GNotification: + * + * This structure type is private and should only be accessed using the + * public APIs. + * + * Since: 2.40 + **/ + +typedef GObjectClass GNotificationClass; + +struct _GNotification +{ + GObject parent; + + gchar *title; + gchar *body; + GIcon *icon; + GNotificationPriority priority; + gchar *category; + GPtrArray *buttons; + gchar *default_action; + GVariant *default_action_target; +}; + +typedef struct +{ + gchar *label; + gchar *action_name; + GVariant *target; +} Button; + +G_DEFINE_TYPE (GNotification, g_notification, G_TYPE_OBJECT) + +static void +button_free (gpointer data) +{ + Button *button = data; + + g_free (button->label); + g_free (button->action_name); + if (button->target) + g_variant_unref (button->target); + + g_slice_free (Button, button); +} + +static void +g_notification_dispose (GObject *object) +{ + GNotification *notification = G_NOTIFICATION (object); + + g_clear_object (¬ification->icon); + + G_OBJECT_CLASS (g_notification_parent_class)->dispose (object); +} + +static void +g_notification_finalize (GObject *object) +{ + GNotification *notification = G_NOTIFICATION (object); + + g_free (notification->title); + g_free (notification->body); + g_free (notification->category); + g_free (notification->default_action); + if (notification->default_action_target) + g_variant_unref (notification->default_action_target); + g_ptr_array_free (notification->buttons, TRUE); + + G_OBJECT_CLASS (g_notification_parent_class)->finalize (object); +} + +static void +g_notification_class_init (GNotificationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = g_notification_dispose; + object_class->finalize = g_notification_finalize; +} + +static void +g_notification_init (GNotification *notification) +{ + notification->buttons = g_ptr_array_new_full (2, button_free); +} + +/** + * g_notification_new: + * @title: the title of the notification + * + * Creates a new #GNotification with @title as its title. + * + * After populating @notification with more details, it can be sent to + * the desktop shell with g_application_send_notification(). Changing + * any properties after this call will not have any effect until + * resending @notification. + * + * Returns: a new #GNotification instance + * + * Since: 2.40 + */ +GNotification * +g_notification_new (const gchar *title) +{ + GNotification *notification; + + g_return_val_if_fail (title != NULL, NULL); + + notification = g_object_new (G_TYPE_NOTIFICATION, NULL); + notification->title = g_strdup (title); + + return notification; +} + +/*< private > + * g_notification_get_title: + * @notification: a #GNotification + * + * Gets the title of @notification. + * + * Returns: the title of @notification + * + * Since: 2.40 + */ +const gchar * +g_notification_get_title (GNotification *notification) +{ + g_return_val_if_fail (G_IS_NOTIFICATION (notification), NULL); + + return notification->title; +} + +/** + * g_notification_set_title: + * @notification: a #GNotification + * @title: the new title for @notification + * + * Sets the title of @notification to @title. + * + * Since: 2.40 + */ +void +g_notification_set_title (GNotification *notification, + const gchar *title) +{ + g_return_if_fail (G_IS_NOTIFICATION (notification)); + g_return_if_fail (title != NULL); + + g_free (notification->title); + + notification->title = g_strdup (title); +} + +/*< private > + * g_notification_get_body: + * @notification: a #GNotification + * + * Gets the current body of @notification. + * + * Returns: (nullable): the body of @notification + * + * Since: 2.40 + */ +const gchar * +g_notification_get_body (GNotification *notification) +{ + g_return_val_if_fail (G_IS_NOTIFICATION (notification), NULL); + + return notification->body; +} + +/** + * g_notification_set_body: + * @notification: a #GNotification + * @body: (nullable): the new body for @notification, or %NULL + * + * Sets the body of @notification to @body. + * + * Since: 2.40 + */ +void +g_notification_set_body (GNotification *notification, + const gchar *body) +{ + g_return_if_fail (G_IS_NOTIFICATION (notification)); + g_return_if_fail (body != NULL); + + g_free (notification->body); + + notification->body = g_strdup (body); +} + +/*< private > + * g_notification_get_icon: + * @notification: a #GNotification + * + * Gets the icon currently set on @notification. + * + * Returns: (transfer none): the icon associated with @notification + * + * Since: 2.40 + */ +GIcon * +g_notification_get_icon (GNotification *notification) +{ + g_return_val_if_fail (G_IS_NOTIFICATION (notification), NULL); + + return notification->icon; +} + +/** + * g_notification_set_icon: + * @notification: a #GNotification + * @icon: the icon to be shown in @notification, as a #GIcon + * + * Sets the icon of @notification to @icon. + * + * Since: 2.40 + */ +void +g_notification_set_icon (GNotification *notification, + GIcon *icon) +{ + g_return_if_fail (G_IS_NOTIFICATION (notification)); + + if (notification->icon) + g_object_unref (notification->icon); + + notification->icon = g_object_ref (icon); +} + +/*< private > + * g_notification_get_priority: + * @notification: a #GNotification + * + * Returns the priority of @notification + * + * Since: 2.42 + */ +GNotificationPriority +g_notification_get_priority (GNotification *notification) +{ + g_return_val_if_fail (G_IS_NOTIFICATION (notification), G_NOTIFICATION_PRIORITY_NORMAL); + + return notification->priority; +} + +/** + * g_notification_set_urgent: + * @notification: a #GNotification + * @urgent: %TRUE if @notification is urgent + * + * Deprecated in favor of g_notification_set_priority(). + * + * Since: 2.40 + * Deprecated: 2.42: Since 2.42, this has been deprecated in favour of + * g_notification_set_priority(). + */ +void +g_notification_set_urgent (GNotification *notification, + gboolean urgent) +{ + g_return_if_fail (G_IS_NOTIFICATION (notification)); + + notification->priority = urgent ? + G_NOTIFICATION_PRIORITY_URGENT : + G_NOTIFICATION_PRIORITY_NORMAL; +} + +/*< private > + * g_notification_get_category: + * @notification: a #GNotification + * + * Gets the cateogry of @notification. + * + * This will be %NULL if no category is set. + * + * Returns: (nullable): the cateogry of @notification + * + * Since: 2.70 + */ +const gchar * +g_notification_get_category (GNotification *notification) +{ + g_return_val_if_fail (G_IS_NOTIFICATION (notification), NULL); + + return notification->category; +} + +/** + * g_notification_set_category: + * @notification: a #GNotification + * @category: (nullable): the category for @notification, or %NULL for no category + * + * Sets the type of @notification to @category. Categories have a main + * type like `email`, `im` or `device` and can have a detail separated + * by a `.`, e.g. `im.received` or `email.arrived`. Setting the category + * helps the notification server to select proper feedback to the user. + * + * Standard categories are [listed in the specification](https://specifications.freedesktop.org/notification-spec/latest/ar01s06.html). + * + * Since: 2.70 + */ +void +g_notification_set_category (GNotification *notification, + const gchar *category) +{ + g_return_if_fail (G_IS_NOTIFICATION (notification)); + g_return_if_fail (category == NULL || *category != '\0'); + + g_free (notification->category); + + notification->category = g_strdup (category); +} + +/** + * g_notification_set_priority: + * @notification: a #GNotification + * @priority: a #GNotificationPriority + * + * Sets the priority of @notification to @priority. See + * #GNotificationPriority for possible values. + */ +void +g_notification_set_priority (GNotification *notification, + GNotificationPriority priority) +{ + g_return_if_fail (G_IS_NOTIFICATION (notification)); + + notification->priority = priority; +} + +/** + * g_notification_add_button: + * @notification: a #GNotification + * @label: label of the button + * @detailed_action: a detailed action name + * + * Adds a button to @notification that activates the action in + * @detailed_action when clicked. That action must be an + * application-wide action (starting with "app."). If @detailed_action + * contains a target, the action will be activated with that target as + * its parameter. + * + * See g_action_parse_detailed_name() for a description of the format + * for @detailed_action. + * + * Since: 2.40 + */ +void +g_notification_add_button (GNotification *notification, + const gchar *label, + const gchar *detailed_action) +{ + gchar *action; + GVariant *target; + GError *error = NULL; + + g_return_if_fail (detailed_action != NULL); + + if (!g_action_parse_detailed_name (detailed_action, &action, &target, &error)) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + return; + } + + g_notification_add_button_with_target_value (notification, label, action, target); + + g_free (action); + if (target) + g_variant_unref (target); +} + +/** + * g_notification_add_button_with_target: (skip) + * @notification: a #GNotification + * @label: label of the button + * @action: an action name + * @target_format: (nullable): a #GVariant format string, or %NULL + * @...: positional parameters, as determined by @target_format + * + * Adds a button to @notification that activates @action when clicked. + * @action must be an application-wide action (it must start with "app."). + * + * If @target_format is given, it is used to collect remaining + * positional parameters into a #GVariant instance, similar to + * g_variant_new(). @action will be activated with that #GVariant as its + * parameter. + * + * Since: 2.40 + */ +void +g_notification_add_button_with_target (GNotification *notification, + const gchar *label, + const gchar *action, + const gchar *target_format, + ...) +{ + va_list args; + GVariant *target = NULL; + + if (target_format) + { + va_start (args, target_format); + target = g_variant_new_va (target_format, NULL, &args); + va_end (args); + } + + g_notification_add_button_with_target_value (notification, label, action, target); +} + +/** + * g_notification_add_button_with_target_value: (rename-to g_notification_add_button_with_target) + * @notification: a #GNotification + * @label: label of the button + * @action: an action name + * @target: (nullable): a #GVariant to use as @action's parameter, or %NULL + * + * Adds a button to @notification that activates @action when clicked. + * @action must be an application-wide action (it must start with "app."). + * + * If @target is non-%NULL, @action will be activated with @target as + * its parameter. + * + * Since: 2.40 + */ +void +g_notification_add_button_with_target_value (GNotification *notification, + const gchar *label, + const gchar *action, + GVariant *target) +{ + Button *button; + + g_return_if_fail (G_IS_NOTIFICATION (notification)); + g_return_if_fail (label != NULL); + g_return_if_fail (action != NULL && g_action_name_is_valid (action)); + + if (!g_str_has_prefix (action, "app.")) + { + g_warning ("%s: action '%s' does not start with 'app.'." + "This is unlikely to work properly.", G_STRFUNC, action); + } + + button = g_slice_new0 (Button); + button->label = g_strdup (label); + button->action_name = g_strdup (action); + + if (target) + button->target = g_variant_ref_sink (target); + + g_ptr_array_add (notification->buttons, button); +} + +/*< private > + * g_notification_get_n_buttons: + * @notification: a #GNotification + * + * Returns: the amount of buttons added to @notification. + */ +guint +g_notification_get_n_buttons (GNotification *notification) +{ + return notification->buttons->len; +} + +/*< private > + * g_notification_get_button: + * @notification: a #GNotification + * @index: index of the button + * @label: (): return location for the button's label + * @action: (): return location for the button's associated action + * @target: (): return location for the target @action should be + * activated with + * + * Returns a description of a button that was added to @notification + * with g_notification_add_button(). + * + * @index must be smaller than the value returned by + * g_notification_get_n_buttons(). + */ +void +g_notification_get_button (GNotification *notification, + gint index, + gchar **label, + gchar **action, + GVariant **target) +{ + Button *button; + + button = g_ptr_array_index (notification->buttons, index); + + if (label) + *label = g_strdup (button->label); + + if (action) + *action = g_strdup (button->action_name); + + if (target) + *target = button->target ? g_variant_ref (button->target) : NULL; +} + +/*< private > + * g_notification_get_button_with_action: + * @notification: a #GNotification + * @action: an action name + * + * Returns the index of the button in @notification that is associated + * with @action, or -1 if no such button exists. + */ +gint +g_notification_get_button_with_action (GNotification *notification, + const gchar *action) +{ + guint i; + + for (i = 0; i < notification->buttons->len; i++) + { + Button *button; + + button = g_ptr_array_index (notification->buttons, i); + if (g_str_equal (action, button->action_name)) + return i; + } + + return -1; +} + + +/*< private > + * g_notification_get_default_action: + * @notification: a #GNotification + * @action: (nullable): return location for the default action + * @target: (nullable): return location for the target of the default action + * + * Gets the action and target for the default action of @notification. + * + * Returns: %TRUE if @notification has a default action + */ +gboolean +g_notification_get_default_action (GNotification *notification, + gchar **action, + GVariant **target) +{ + if (notification->default_action == NULL) + return FALSE; + + if (action) + *action = g_strdup (notification->default_action); + + if (target) + { + if (notification->default_action_target) + *target = g_variant_ref (notification->default_action_target); + else + *target = NULL; + } + + return TRUE; +} + +/** + * g_notification_set_default_action: + * @notification: a #GNotification + * @detailed_action: a detailed action name + * + * Sets the default action of @notification to @detailed_action. This + * action is activated when the notification is clicked on. + * + * The action in @detailed_action must be an application-wide action (it + * must start with "app."). If @detailed_action contains a target, the + * given action will be activated with that target as its parameter. + * See g_action_parse_detailed_name() for a description of the format + * for @detailed_action. + * + * When no default action is set, the application that the notification + * was sent on is activated. + * + * Since: 2.40 + */ +void +g_notification_set_default_action (GNotification *notification, + const gchar *detailed_action) +{ + gchar *action; + GVariant *target; + GError *error = NULL; + + if (!g_action_parse_detailed_name (detailed_action, &action, &target, &error)) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + return; + } + + g_notification_set_default_action_and_target_value (notification, action, target); + + g_free (action); + if (target) + g_variant_unref (target); +} + +/** + * g_notification_set_default_action_and_target: (skip) + * @notification: a #GNotification + * @action: an action name + * @target_format: (nullable): a #GVariant format string, or %NULL + * @...: positional parameters, as determined by @target_format + * + * Sets the default action of @notification to @action. This action is + * activated when the notification is clicked on. It must be an + * application-wide action (it must start with "app."). + * + * If @target_format is given, it is used to collect remaining + * positional parameters into a #GVariant instance, similar to + * g_variant_new(). @action will be activated with that #GVariant as its + * parameter. + * + * When no default action is set, the application that the notification + * was sent on is activated. + * + * Since: 2.40 + */ +void +g_notification_set_default_action_and_target (GNotification *notification, + const gchar *action, + const gchar *target_format, + ...) +{ + va_list args; + GVariant *target = NULL; + + if (target_format) + { + va_start (args, target_format); + target = g_variant_new_va (target_format, NULL, &args); + va_end (args); + } + + g_notification_set_default_action_and_target_value (notification, action, target); +} + +/** + * g_notification_set_default_action_and_target_value: (rename-to g_notification_set_default_action_and_target) + * @notification: a #GNotification + * @action: an action name + * @target: (nullable): a #GVariant to use as @action's parameter, or %NULL + * + * Sets the default action of @notification to @action. This action is + * activated when the notification is clicked on. It must be an + * application-wide action (start with "app."). + * + * If @target is non-%NULL, @action will be activated with @target as + * its parameter. + * + * When no default action is set, the application that the notification + * was sent on is activated. + * + * Since: 2.40 + */ +void +g_notification_set_default_action_and_target_value (GNotification *notification, + const gchar *action, + GVariant *target) +{ + g_return_if_fail (G_IS_NOTIFICATION (notification)); + g_return_if_fail (action != NULL && g_action_name_is_valid (action)); + + if (!g_str_has_prefix (action, "app.")) + { + g_warning ("%s: action '%s' does not start with 'app.'." + "This is unlikely to work properly.", G_STRFUNC, action); + } + + g_free (notification->default_action); + g_clear_pointer (¬ification->default_action_target, g_variant_unref); + + notification->default_action = g_strdup (action); + + if (target) + notification->default_action_target = g_variant_ref_sink (target); +} + +static GVariant * +g_notification_serialize_button (Button *button) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + + g_variant_builder_add (&builder, "{sv}", "label", g_variant_new_string (button->label)); + g_variant_builder_add (&builder, "{sv}", "action", g_variant_new_string (button->action_name)); + + if (button->target) + g_variant_builder_add (&builder, "{sv}", "target", button->target); + + return g_variant_builder_end (&builder); +} + +static GVariant * +g_notification_get_priority_nick (GNotification *notification) +{ + GEnumClass *enum_class; + GEnumValue *value; + GVariant *nick; + + enum_class = g_type_class_ref (G_TYPE_NOTIFICATION_PRIORITY); + value = g_enum_get_value (enum_class, g_notification_get_priority (notification)); + g_assert (value != NULL); + nick = g_variant_new_string (value->value_nick); + g_type_class_unref (enum_class); + + return nick; +} + +/*< private > + * g_notification_serialize: + * + * Serializes @notification into a floating variant of type a{sv}. + * + * Returns: the serialized @notification as a floating variant. + */ +GVariant * +g_notification_serialize (GNotification *notification) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + + if (notification->title) + g_variant_builder_add (&builder, "{sv}", "title", g_variant_new_string (notification->title)); + + if (notification->body) + g_variant_builder_add (&builder, "{sv}", "body", g_variant_new_string (notification->body)); + + if (notification->icon) + { + GVariant *serialized_icon; + + if ((serialized_icon = g_icon_serialize (notification->icon))) + { + g_variant_builder_add (&builder, "{sv}", "icon", serialized_icon); + g_variant_unref (serialized_icon); + } + } + + g_variant_builder_add (&builder, "{sv}", "priority", g_notification_get_priority_nick (notification)); + + if (notification->default_action) + { + g_variant_builder_add (&builder, "{sv}", "default-action", + g_variant_new_string (notification->default_action)); + + if (notification->default_action_target) + g_variant_builder_add (&builder, "{sv}", "default-action-target", + notification->default_action_target); + } + + if (notification->buttons->len > 0) + { + GVariantBuilder actions_builder; + guint i; + + g_variant_builder_init (&actions_builder, G_VARIANT_TYPE ("aa{sv}")); + + for (i = 0; i < notification->buttons->len; i++) + { + Button *button = g_ptr_array_index (notification->buttons, i); + g_variant_builder_add (&actions_builder, "@a{sv}", g_notification_serialize_button (button)); + } + + g_variant_builder_add (&builder, "{sv}", "buttons", g_variant_builder_end (&actions_builder)); + } + + return g_variant_builder_end (&builder); +} diff --git a/gio/gnotification.h b/gio/gnotification.h new file mode 100644 index 0000000..0b10354 --- /dev/null +++ b/gio/gnotification.h @@ -0,0 +1,101 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#ifndef __G_NOTIFICATION_H__ +#define __G_NOTIFICATION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_NOTIFICATION (g_notification_get_type ()) +#define G_NOTIFICATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NOTIFICATION, GNotification)) +#define G_IS_NOTIFICATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NOTIFICATION)) + +GLIB_AVAILABLE_IN_2_40 +GType g_notification_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_40 +GNotification * g_notification_new (const gchar *title); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_set_title (GNotification *notification, + const gchar *title); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_set_body (GNotification *notification, + const gchar *body); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_set_icon (GNotification *notification, + GIcon *icon); + +GLIB_DEPRECATED_IN_2_42_FOR(g_notification_set_priority) +void g_notification_set_urgent (GNotification *notification, + gboolean urgent); + +GLIB_AVAILABLE_IN_2_42 +void g_notification_set_priority (GNotification *notification, + GNotificationPriority priority); + +GLIB_AVAILABLE_IN_2_70 +void g_notification_set_category (GNotification *notification, + const gchar *category); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_add_button (GNotification *notification, + const gchar *label, + const gchar *detailed_action); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_add_button_with_target (GNotification *notification, + const gchar *label, + const gchar *action, + const gchar *target_format, + ...); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_add_button_with_target_value (GNotification *notification, + const gchar *label, + const gchar *action, + GVariant *target); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_set_default_action (GNotification *notification, + const gchar *detailed_action); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_set_default_action_and_target (GNotification *notification, + const gchar *action, + const gchar *target_format, + ...); + +GLIB_AVAILABLE_IN_2_40 +void g_notification_set_default_action_and_target_value (GNotification *notification, + const gchar *action, + GVariant *target); + +G_END_DECLS + +#endif diff --git a/gio/gnotificationbackend.c b/gio/gnotificationbackend.c new file mode 100644 index 0000000..b2c0729 --- /dev/null +++ b/gio/gnotificationbackend.c @@ -0,0 +1,84 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#include "gnotificationbackend.h" + +#include "gnotification.h" +#include "gapplication.h" +#include "gactiongroup.h" +#include "giomodule-priv.h" + +G_DEFINE_TYPE (GNotificationBackend, g_notification_backend, G_TYPE_OBJECT) + +static void +g_notification_backend_class_init (GNotificationBackendClass *class) +{ +} + +static void +g_notification_backend_init (GNotificationBackend *backend) +{ +} + +GNotificationBackend * +g_notification_backend_new_default (GApplication *application) +{ + GType backend_type; + GNotificationBackend *backend; + + g_return_val_if_fail (G_IS_APPLICATION (application), NULL); + + backend_type = _g_io_module_get_default_type (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, + "GNOTIFICATION_BACKEND", + G_STRUCT_OFFSET (GNotificationBackendClass, is_supported)); + + backend = g_object_new (backend_type, NULL); + + /* Avoid ref cycle by not taking a ref to the application at all. The + * backend only lives as long as the application does. + */ + backend->application = application; + + backend->dbus_connection = g_application_get_dbus_connection (application); + if (backend->dbus_connection) + g_object_ref (backend->dbus_connection); + + return backend; +} + +void +g_notification_backend_send_notification (GNotificationBackend *backend, + const gchar *id, + GNotification *notification) +{ + g_return_if_fail (G_IS_NOTIFICATION_BACKEND (backend)); + g_return_if_fail (G_IS_NOTIFICATION (notification)); + + G_NOTIFICATION_BACKEND_GET_CLASS (backend)->send_notification (backend, id, notification); +} + +void +g_notification_backend_withdraw_notification (GNotificationBackend *backend, + const gchar *id) +{ + g_return_if_fail (G_IS_NOTIFICATION_BACKEND (backend)); + g_return_if_fail (id != NULL); + + G_NOTIFICATION_BACKEND_GET_CLASS (backend)->withdraw_notification (backend, id); +} diff --git a/gio/gnotificationbackend.h b/gio/gnotificationbackend.h new file mode 100644 index 0000000..85c0f2d --- /dev/null +++ b/gio/gnotificationbackend.h @@ -0,0 +1,73 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#ifndef __G_NOTIFICATION_BACKEND_H__ +#define __G_NOTIFICATION_BACKEND_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_NOTIFICATION_BACKEND (g_notification_backend_get_type ()) +#define G_NOTIFICATION_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NOTIFICATION_BACKEND, GNotificationBackend)) +#define G_IS_NOTIFICATION_BACKEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NOTIFICATION_BACKEND)) +#define G_NOTIFICATION_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_NOTIFICATION_BACKEND, GNotificationBackendClass)) +#define G_NOTIFICATION_BACKEND_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NOTIFICATION_BACKEND, GNotificationBackendClass)) + +#define G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME "gnotification-backend" + +typedef struct _GNotificationBackend GNotificationBackend; +typedef struct _GNotificationBackendClass GNotificationBackendClass; + +struct _GNotificationBackend +{ + GObject parent_instance; + + GApplication *application; + GDBusConnection *dbus_connection; +}; + +struct _GNotificationBackendClass +{ + GObjectClass parent_class; + + gboolean (*is_supported) (void); + + void (*send_notification) (GNotificationBackend *backend, + const gchar *id, + GNotification *notification); + + void (*withdraw_notification) (GNotificationBackend *backend, + const gchar *id); +}; + +GType g_notification_backend_get_type (void); + +GNotificationBackend * g_notification_backend_new_default (GApplication *application); + +void g_notification_backend_send_notification (GNotificationBackend *backend, + const gchar *id, + GNotification *notification); + +void g_notification_backend_withdraw_notification (GNotificationBackend *backend, + const gchar *id); + +G_END_DECLS + +#endif diff --git a/gio/gnullsettingsbackend.c b/gio/gnullsettingsbackend.c new file mode 100644 index 0000000..4881996 --- /dev/null +++ b/gio/gnullsettingsbackend.c @@ -0,0 +1,138 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gsettingsbackendinternal.h" +#include "giomodule-priv.h" +#include "gsimplepermission.h" + + +#define G_TYPE_NULL_SETTINGS_BACKEND (g_null_settings_backend_get_type ()) +#define G_NULL_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_NULL_SETTINGS_BACKEND, \ + GNullSettingsBackend)) + + +typedef GSettingsBackendClass GNullSettingsBackendClass; +typedef GSettingsBackend GNullSettingsBackend; + +G_DEFINE_TYPE_WITH_CODE (GNullSettingsBackend, + g_null_settings_backend, + G_TYPE_SETTINGS_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "null", 10)) + +static GVariant * +g_null_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value) +{ + return NULL; +} + +static gboolean +g_null_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag) +{ + if (value) + g_variant_unref (g_variant_ref_sink (value)); + return FALSE; +} + +static gboolean +g_null_settings_backend_write_one (gpointer key, + gpointer value, + gpointer data) +{ + if (value) + g_variant_unref (g_variant_ref_sink (value)); + return FALSE; +} + +static gboolean +g_null_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag) +{ + g_tree_foreach (tree, g_null_settings_backend_write_one, backend); + return FALSE; +} + +static void +g_null_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ +} + +static gboolean +g_null_settings_backend_get_writable (GSettingsBackend *backend, + const gchar *name) +{ + return FALSE; +} + +static GPermission * +g_null_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path) +{ + return g_simple_permission_new (FALSE); +} + +static void +g_null_settings_backend_init (GNullSettingsBackend *memory) +{ +} + +static void +g_null_settings_backend_class_init (GNullSettingsBackendClass *class) +{ + GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class); + + backend_class->read = g_null_settings_backend_read; + backend_class->write = g_null_settings_backend_write; + backend_class->write_tree = g_null_settings_backend_write_tree; + backend_class->reset = g_null_settings_backend_reset; + backend_class->get_writable = g_null_settings_backend_get_writable; + backend_class->get_permission = g_null_settings_backend_get_permission; +} + +/** + * g_null_settings_backend_new: + * + * + * Creates a readonly #GSettingsBackend. + * + * This backend does not allow changes to settings, so all settings + * will always have their default values. + * + * Returns: (transfer full): a newly created #GSettingsBackend + * + * Since: 2.28 + */ +GSettingsBackend * +g_null_settings_backend_new (void) +{ + return g_object_new (G_TYPE_NULL_SETTINGS_BACKEND, NULL); +} diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c new file mode 100644 index 0000000..2f527d8 --- /dev/null +++ b/gio/gopenuriportal.c @@ -0,0 +1,367 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "gopenuriportal.h" +#include "xdp-dbus.h" +#include "gstdio.h" + +#ifdef G_OS_UNIX +#include "gunixfdlist.h" +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#else +#define HAVE_O_CLOEXEC 1 +#endif + + +static GXdpOpenURI *openuri; + +static gboolean +init_openuri_portal (void) +{ + static gsize openuri_inited = 0; + + if (g_once_init_enter (&openuri_inited)) + { + GError *error = NULL; + GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + + if (connection != NULL) + { + openuri = gxdp_open_uri_proxy_new_sync (connection, 0, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + NULL, &error); + if (openuri == NULL) + { + g_warning ("Cannot create document portal proxy: %s", error->message); + g_error_free (error); + } + + g_object_unref (connection); + } + else + { + g_warning ("Cannot connect to session bus when initializing document portal: %s", + error->message); + g_error_free (error); + } + + g_once_init_leave (&openuri_inited, 1); + } + + return openuri != NULL; +} + +gboolean +g_openuri_portal_open_uri (const char *uri, + const char *parent_window, + GError **error) +{ + GFile *file = NULL; + GVariantBuilder opt_builder; + gboolean res; + + if (!init_openuri_portal ()) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, + "OpenURI portal is not available"); + return FALSE; + } + + g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); + + file = g_file_new_for_uri (uri); + if (g_file_is_native (file)) + { + char *path = NULL; + GUnixFDList *fd_list = NULL; + int fd, fd_id, errsv; + + path = g_file_get_path (file); + + fd = g_open (path, O_RDONLY | O_CLOEXEC); + errsv = errno; + if (fd == -1) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + "Failed to open '%s'", path); + g_free (path); + g_variant_builder_clear (&opt_builder); + return FALSE; + } + +#ifndef HAVE_O_CLOEXEC + fcntl (fd, F_SETFD, FD_CLOEXEC); +#endif + fd_list = g_unix_fd_list_new_from_array (&fd, 1); + fd = -1; + fd_id = 0; + + res = gxdp_open_uri_call_open_file_sync (openuri, + parent_window ? parent_window : "", + g_variant_new ("h", fd_id), + g_variant_builder_end (&opt_builder), + fd_list, + NULL, + NULL, + NULL, + error); + g_free (path); + g_object_unref (fd_list); + } + else + { + res = gxdp_open_uri_call_open_uri_sync (openuri, + parent_window ? parent_window : "", + uri, + g_variant_builder_end (&opt_builder), + NULL, + NULL, + error); + } + + g_object_unref (file); + + return res; +} + +enum { + XDG_DESKTOP_PORTAL_SUCCESS = 0, + XDG_DESKTOP_PORTAL_CANCELLED = 1, + XDG_DESKTOP_PORTAL_FAILED = 2 +}; + +static void +response_received (GDBusConnection *connection, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GTask *task = user_data; + guint32 response; + guint signal_id; + + signal_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "signal-id")); + g_dbus_connection_signal_unsubscribe (connection, signal_id); + + g_variant_get (parameters, "(u@a{sv})", &response, NULL); + + switch (response) + { + case XDG_DESKTOP_PORTAL_SUCCESS: + g_task_return_boolean (task, TRUE); + break; + case XDG_DESKTOP_PORTAL_CANCELLED: + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Launch cancelled"); + break; + case XDG_DESKTOP_PORTAL_FAILED: + default: + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Launch failed"); + break; + } + + g_object_unref (task); +} + +static void +open_call_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GXdpOpenURI *openuri = GXDP_OPEN_URI (source); + GDBusConnection *connection; + GTask *task = user_data; + GError *error = NULL; + gboolean open_file; + gboolean res; + char *path = NULL; + const char *handle; + guint signal_id; + + connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (openuri)); + open_file = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "open-file")); + + if (open_file) + res = gxdp_open_uri_call_open_file_finish (openuri, &path, NULL, result, &error); + else + res = gxdp_open_uri_call_open_uri_finish (openuri, &path, result, &error); + + if (!res) + { + g_task_return_error (task, error); + g_object_unref (task); + g_free (path); + return; + } + + handle = (const char *)g_object_get_data (G_OBJECT (task), "handle"); + if (g_strcmp0 (handle, path) != 0) + { + signal_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "signal-id")); + g_dbus_connection_signal_unsubscribe (connection, signal_id); + + signal_id = g_dbus_connection_signal_subscribe (connection, + "org.freedesktop.portal.Desktop", + "org.freedesktop.portal.Request", + "Response", + path, + NULL, + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, + response_received, + task, + NULL); + g_object_set_data (G_OBJECT (task), "signal-id", GINT_TO_POINTER (signal_id)); + } +} + +void +g_openuri_portal_open_uri_async (const char *uri, + const char *parent_window, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GDBusConnection *connection; + GTask *task; + GFile *file; + GVariant *opts = NULL; + int i; + guint signal_id; + + if (!init_openuri_portal ()) + { + g_task_report_new_error (NULL, callback, user_data, NULL, + G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, + "OpenURI portal is not available"); + return; + } + + connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (openuri)); + + if (callback) + { + GVariantBuilder opt_builder; + char *token; + char *sender; + char *handle; + + task = g_task_new (NULL, cancellable, callback, user_data); + + token = g_strdup_printf ("gio%d", g_random_int_range (0, G_MAXINT)); + sender = g_strdup (g_dbus_connection_get_unique_name (connection) + 1); + for (i = 0; sender[i]; i++) + if (sender[i] == '.') + sender[i] = '_'; + + handle = g_strdup_printf ("/org/freedesktop/portal/desktop/request/%s/%s", sender, token); + g_object_set_data_full (G_OBJECT (task), "handle", handle, g_free); + g_free (sender); + + signal_id = g_dbus_connection_signal_subscribe (connection, + "org.freedesktop.portal.Desktop", + "org.freedesktop.portal.Request", + "Response", + handle, + NULL, + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, + response_received, + task, + NULL); + g_object_set_data (G_OBJECT (task), "signal-id", GINT_TO_POINTER (signal_id)); + + g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&opt_builder, "{sv}", "handle_token", g_variant_new_string (token)); + g_free (token); + + opts = g_variant_builder_end (&opt_builder); + } + else + task = NULL; + + file = g_file_new_for_uri (uri); + if (g_file_is_native (file)) + { + char *path = NULL; + GUnixFDList *fd_list = NULL; + int fd, fd_id, errsv; + + if (task) + g_object_set_data (G_OBJECT (task), "open-file", GINT_TO_POINTER (TRUE)); + + path = g_file_get_path (file); + fd = g_open (path, O_RDONLY | O_CLOEXEC); + errsv = errno; + if (fd == -1) + { + g_task_report_new_error (NULL, callback, user_data, NULL, + G_IO_ERROR, g_io_error_from_errno (errsv), + "OpenURI portal is not available"); + return; + } + +#ifndef HAVE_O_CLOEXEC + fcntl (fd, F_SETFD, FD_CLOEXEC); +#endif + fd_list = g_unix_fd_list_new_from_array (&fd, 1); + fd = -1; + fd_id = 0; + + gxdp_open_uri_call_open_file (openuri, + parent_window ? parent_window : "", + g_variant_new ("h", fd_id), + opts, + fd_list, + cancellable, + task ? open_call_done : NULL, + task); + g_object_unref (fd_list); + g_free (path); + } + else + { + gxdp_open_uri_call_open_uri (openuri, + parent_window ? parent_window : "", + uri, + opts, + cancellable, + task ? open_call_done : NULL, + task); + } + + g_object_unref (file); +} + +gboolean +g_openuri_portal_open_uri_finish (GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} diff --git a/gio/gopenuriportal.h b/gio/gopenuriportal.h new file mode 100644 index 0000000..00863ef --- /dev/null +++ b/gio/gopenuriportal.h @@ -0,0 +1,41 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __G_OPEN_URI_PORTAL_H__ + +#include +#include + +G_BEGIN_DECLS + +gboolean g_openuri_portal_open_uri (const char *uri, + const char *parent_window, + GError **error); + +void g_openuri_portal_open_uri_async (const char *uri, + const char *parent_window, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean g_openuri_portal_open_uri_finish (GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif diff --git a/gio/gosxappinfo.h b/gio/gosxappinfo.h new file mode 100644 index 0000000..793ce1f --- /dev/null +++ b/gio/gosxappinfo.h @@ -0,0 +1,54 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2014 Patrick Griffis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ + +#ifndef __G_OSX_APP_INFO_H__ +#define __G_OSX_APP_INFO_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_OSX_APP_INFO (g_osx_app_info_get_type ()) +#define G_OSX_APP_INFO(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_OSX_APP_INFO, GOsxAppInfo)) +#define G_OSX_APP_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_OSX_APP_INFO, GOsxAppInfoClass)) +#define G_IS_OSX_APP_INFO(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_OSX_APP_INFO)) +#define G_IS_OSX_APP_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_OSX_APP_INFO)) +#define G_OSX_APP_INFO_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_OSX_APP_INFO, GOsxAppInfoClass)) + +typedef struct _GOsxAppInfo GOsxAppInfo; +typedef struct _GOsxAppInfoClass GOsxAppInfoClass; + +struct _GOsxAppInfoClass +{ + GObjectClass parent_class; +}; + +GLIB_AVAILABLE_IN_2_52 +GType g_osx_app_info_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_52 +const char *g_osx_app_info_get_filename (GOsxAppInfo *info); + +GLIB_AVAILABLE_IN_2_52 +GList * g_osx_app_info_get_all_for_scheme (const gchar *scheme); + +G_END_DECLS + + +#endif /* __G_OSX_APP_INFO_H__ */ diff --git a/gio/gosxappinfo.m b/gio/gosxappinfo.m new file mode 100644 index 0000000..03c3737 --- /dev/null +++ b/gio/gosxappinfo.m @@ -0,0 +1,772 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2014 Patrick Griffis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ + +#include "config.h" + +#include "gappinfo.h" +#include "gosxappinfo.h" +#include "gcontenttype.h" +#include "gfile.h" +#include "gfileicon.h" +#include "gioerror.h" + +#import +#import +#import + +/** + * SECTION:gosxappinfo + * @title: GOsxAppInfo + * @short_description: Application information from NSBundles + * @include: gio/gosxappinfo.h + * + * #GOsxAppInfo is an implementation of #GAppInfo based on NSBundle information. + * + * Note that `` is unique to OSX. + */ + +static void g_osx_app_info_iface_init (GAppInfoIface *iface); +static const char *g_osx_app_info_get_id (GAppInfo *appinfo); + +/** + * GOsxAppInfo: + * + * Information about an installed application from a NSBundle. + */ +struct _GOsxAppInfo +{ + GObject parent_instance; + + NSBundle *bundle; + + /* Note that these are all NULL until first call + * to getter at which point they are cached here + */ + gchar *id; + gchar *name; + gchar *executable; + gchar *filename; + GIcon *icon; +}; + +G_DEFINE_TYPE_WITH_CODE (GOsxAppInfo, g_osx_app_info, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_APP_INFO, g_osx_app_info_iface_init)) + +static GOsxAppInfo * +g_osx_app_info_new (NSBundle *bundle) +{ + GOsxAppInfo *info = g_object_new (G_TYPE_OSX_APP_INFO, NULL); + + info->bundle = [bundle retain]; + + return info; +} + +static void +g_osx_app_info_init (GOsxAppInfo *info) +{ +} + +static void +g_osx_app_info_finalize (GObject *object) +{ + GOsxAppInfo *info = G_OSX_APP_INFO (object); + + g_free (info->id); + g_free (info->name); + g_free (info->executable); + g_free (info->filename); + g_clear_object (&info->icon); + + [info->bundle release]; + + G_OBJECT_CLASS (g_osx_app_info_parent_class)->finalize (object); +} + +static void +g_osx_app_info_class_init (GOsxAppInfoClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_osx_app_info_finalize; +} + +static GAppInfo * +g_osx_app_info_dup (GAppInfo *appinfo) +{ + GOsxAppInfo *info; + GOsxAppInfo *new_info; + + g_return_val_if_fail (appinfo != NULL, NULL); + + info = G_OSX_APP_INFO (appinfo); + new_info = g_osx_app_info_new ([info->bundle retain]); + + return G_APP_INFO (new_info); +} + +static gboolean +g_osx_app_info_equal (GAppInfo *appinfo1, + GAppInfo *appinfo2) +{ + const gchar *str1, *str2; + + g_return_val_if_fail (appinfo1 != NULL, FALSE); + g_return_val_if_fail (appinfo2 != NULL, FALSE); + + str1 = g_osx_app_info_get_id (appinfo1); + str2 = g_osx_app_info_get_id (appinfo2); + + return (g_strcmp0 (str1, str2) == 0); +} + +/*< internal > + * get_bundle_string_value: + * @bundle: a #NSBundle + * @key: an #NSString key + * + * Returns a value from a bundles info.plist file. + * It will be utf8 encoded and it must be g_free()'d. + * + */ +static gchar * +get_bundle_string_value (NSBundle *bundle, + NSString *key) +{ + NSString *value; + const gchar *cvalue; + gchar *ret; + + g_return_val_if_fail (bundle != NULL, NULL); + + value = (NSString *)[bundle objectForInfoDictionaryKey: key]; + if (!value) + return NULL; + + cvalue = [value cStringUsingEncoding: NSUTF8StringEncoding]; + ret = g_strdup (cvalue); + + return ret; +} + +static CFStringRef +create_cfstring_from_cstr (const gchar *cstr) +{ + g_return_val_if_fail (cstr != NULL, NULL); + return CFStringCreateWithCString (NULL, cstr, kCFStringEncodingUTF8); +} + +#ifdef G_ENABLE_DEBUG +static gchar * +create_cstr_from_cfstring (CFStringRef str) +{ + g_return_val_if_fail (str != NULL, NULL); + + CFIndex length = CFStringGetLength (str); + CFIndex maxlen = CFStringGetMaximumSizeForEncoding (length, kCFStringEncodingUTF8); + gchar *buffer = g_malloc (maxlen + 1); + Boolean success = CFStringGetCString (str, (char *) buffer, maxlen, + kCFStringEncodingUTF8); + if (success) + return buffer; + else + { + g_free (buffer); + return NULL; + } +} +#endif + +static char * +url_escape_hostname (const char *url) +{ + char *host_start, *ret; + + host_start = strstr (url, "://"); + if (host_start != NULL) + { + char *host_end, *scheme, *host, *hostname; + + scheme = g_strndup (url, host_start - url); + host_start += 3; + host_end = strchr (host_start, '/'); + + if (host_end != NULL) + host = g_strndup (host_start, host_end - host_start); + else + host = g_strdup (host_start); + + hostname = g_hostname_to_ascii (host); + + ret = g_strconcat (scheme, "://", hostname, host_end, NULL); + + g_free (scheme); + g_free (host); + g_free (hostname); + + return ret; + } + + return g_strdup (url); +} + +static CFURLRef +create_url_from_cstr (const gchar *cstr, + gboolean is_file) +{ + gchar *puny_cstr; + CFStringRef str; + CFURLRef url; + + puny_cstr = url_escape_hostname (cstr); + str = CFStringCreateWithCString (NULL, puny_cstr ? puny_cstr : cstr, kCFStringEncodingUTF8); + + if (is_file) + url = CFURLCreateWithFileSystemPath (NULL, str, kCFURLPOSIXPathStyle, FALSE); + else + url = CFURLCreateWithString (NULL, str, NULL); + + if (!url) + g_debug ("Creating CFURL from %s %s failed!", cstr, is_file ? "file" : "uri"); + + g_free (puny_cstr); + CFRelease(str); + return url; +} + +static CFArrayRef +create_url_list_from_glist (GList *uris, + gboolean are_files) +{ + GList *lst; + int len = g_list_length (uris); + CFMutableArrayRef array; + + if (!len) + return NULL; + + array = CFArrayCreateMutable (NULL, len, &kCFTypeArrayCallBacks); + if (!array) + return NULL; + + for (lst = uris; lst != NULL && lst->data; lst = lst->next) + { + CFURLRef url = create_url_from_cstr ((char*)lst->data, are_files); + if (url) + CFArrayAppendValue (array, url); + } + + return (CFArrayRef)array; +} + +static LSLaunchURLSpec * +create_urlspec_for_appinfo (GOsxAppInfo *info, + GList *uris, + gboolean are_files) +{ + LSLaunchURLSpec *urlspec = NULL; + const gchar *app_cstr; + + g_return_val_if_fail (G_IS_OSX_APP_INFO (info), NULL); + + urlspec = g_new0 (LSLaunchURLSpec, 1); + app_cstr = g_osx_app_info_get_filename (info); + g_assert (app_cstr != NULL); + + /* Strip file:// from app url but ensure filesystem url */ + urlspec->appURL = create_url_from_cstr (app_cstr + strlen ("file://"), TRUE); + urlspec->launchFlags = kLSLaunchDefaults; + urlspec->itemURLs = create_url_list_from_glist (uris, are_files); + + return urlspec; +} + +static void +free_urlspec (LSLaunchURLSpec *urlspec) +{ + if (urlspec->itemURLs) + { + CFArrayRemoveAllValues ((CFMutableArrayRef)urlspec->itemURLs); + CFRelease (urlspec->itemURLs); + } + CFRelease (urlspec->appURL); + g_free (urlspec); +} + +static NSBundle * +get_bundle_for_url (CFURLRef app_url) +{ + NSBundle *bundle = [NSBundle bundleWithURL: (NSURL*)app_url]; + + if (!bundle) + { + g_debug ("Bundle not found for url."); + return NULL; + } + + return bundle; +} + +static NSBundle * +get_bundle_for_id (CFStringRef bundle_id) +{ + CFURLRef app_url; + NSBundle *bundle; + +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER + CFArrayRef urls = LSCopyApplicationURLsForBundleIdentifier (bundle_id, NULL); + if (urls) + { + /* TODO: if there's multiple, we should perhaps prefer one that's in $HOME, + * instead of just always picking the first. + */ + app_url = CFArrayGetValueAtIndex (urls, 0); + CFRetain (app_url); + CFRelease (urls); + } + else +#else + if (LSFindApplicationForInfo (kLSUnknownCreator, bundle_id, NULL, NULL, &app_url) == kLSApplicationNotFoundErr) +#endif + { +#ifdef G_ENABLE_DEBUG /* This can fail often, no reason to alloc strings */ + gchar *id_str = create_cstr_from_cfstring (bundle_id); + if (id_str) + { + g_debug ("Application not found for id \"%s\".", id_str); + g_free (id_str); + } + else + g_debug ("Application not found for unconvertable bundle id."); +#endif + return NULL; + } + + bundle = get_bundle_for_url (app_url); + CFRelease (app_url); + return bundle; +} + +static const char * +g_osx_app_info_get_id (GAppInfo *appinfo) +{ + GOsxAppInfo *info = G_OSX_APP_INFO (appinfo); + + if (!info->id) + info->id = get_bundle_string_value (info->bundle, @"CFBundleIdentifier"); + + return info->id; +} + +static const char * +g_osx_app_info_get_name (GAppInfo *appinfo) +{ + GOsxAppInfo *info = G_OSX_APP_INFO (appinfo); + + if (!info->name) + info->name = get_bundle_string_value (info->bundle, @"CFBundleName"); + + return info->name; +} + +static const char * +g_osx_app_info_get_display_name (GAppInfo *appinfo) +{ + return g_osx_app_info_get_name (appinfo); +} + +static const char * +g_osx_app_info_get_description (GAppInfo *appinfo) +{ + /* Bundles do not contain descriptions */ + return NULL; +} + +static const char * +g_osx_app_info_get_executable (GAppInfo *appinfo) +{ + GOsxAppInfo *info = G_OSX_APP_INFO (appinfo); + + if (!info->executable) + info->executable = get_bundle_string_value (info->bundle, @"CFBundleExecutable"); + + return info->executable; +} + +const char * +g_osx_app_info_get_filename (GOsxAppInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + + if (!info->filename) + { + info->filename = g_strconcat ("file://", [[info->bundle bundlePath] + cStringUsingEncoding: NSUTF8StringEncoding], + NULL); + } + + return info->filename; +} + +static const char * +g_osx_app_info_get_commandline (GAppInfo *appinfo) +{ + /* There isn't really a command line value */ + return NULL; +} + +static GIcon * +g_osx_app_info_get_icon (GAppInfo *appinfo) +{ + GOsxAppInfo *info = G_OSX_APP_INFO (appinfo); + + if (!info->icon) + { + const gchar *app_uri; + gchar *icon_name, *icon_uri; + GFile *file; + + icon_name = get_bundle_string_value (info->bundle, @"CFBundleIconFile"); + if (!icon_name) + return NULL; + + app_uri = g_osx_app_info_get_filename (info); + icon_uri = g_strconcat (app_uri + strlen ("file://"), "/Contents/Resources/", icon_name, + g_str_has_suffix (icon_name, ".icns") ? NULL : ".icns", NULL); + g_free (icon_name); + + file = g_file_new_for_path (icon_uri); + info->icon = g_file_icon_new (file); + g_object_unref (file); + g_free (icon_uri); + } + + return info->icon; +} + +static gboolean +g_osx_app_info_launch_internal (GAppInfo *appinfo, + GList *uris, + gboolean are_files, + GError **error) +{ + GOsxAppInfo *info = G_OSX_APP_INFO (appinfo); + LSLaunchURLSpec *urlspec; + gint ret, success = TRUE; + + g_return_val_if_fail (G_IS_OSX_APP_INFO (appinfo), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + urlspec = create_urlspec_for_appinfo (info, uris, are_files); + + if ((ret = LSOpenFromURLSpec (urlspec, NULL))) + { + /* TODO: Better error codes */ + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Opening application failed with code %d", ret); + success = FALSE; + } + + free_urlspec (urlspec); + return success; +} + +static gboolean +g_osx_app_info_supports_uris (GAppInfo *appinfo) +{ + return TRUE; +} + +static gboolean +g_osx_app_info_supports_files (GAppInfo *appinfo) +{ + return TRUE; +} + +static gboolean +g_osx_app_info_launch (GAppInfo *appinfo, + GList *files, + GAppLaunchContext *launch_context, + GError **error) +{ + return g_osx_app_info_launch_internal (appinfo, files, TRUE, error); +} + +static gboolean +g_osx_app_info_launch_uris (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GError **error) +{ + return g_osx_app_info_launch_internal (appinfo, uris, FALSE, error); +} + +static gboolean +g_osx_app_info_should_show (GAppInfo *appinfo) +{ + /* Bundles don't have hidden attribute */ + return TRUE; +} + +static gboolean +g_osx_app_info_set_as_default_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + return FALSE; +} + +static const char ** +g_osx_app_info_get_supported_types (GAppInfo *appinfo) +{ + /* TODO: get CFBundleDocumentTypes */ + return NULL; +} + +static gboolean +g_osx_app_info_set_as_last_used_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + /* Not supported. */ + return FALSE; +} + +static gboolean +g_osx_app_info_can_delete (GAppInfo *appinfo) +{ + return FALSE; +} + +static void +g_osx_app_info_iface_init (GAppInfoIface *iface) +{ + iface->dup = g_osx_app_info_dup; + iface->equal = g_osx_app_info_equal; + + iface->get_id = g_osx_app_info_get_id; + iface->get_name = g_osx_app_info_get_name; + iface->get_display_name = g_osx_app_info_get_display_name; + iface->get_description = g_osx_app_info_get_description; + iface->get_executable = g_osx_app_info_get_executable; + iface->get_commandline = g_osx_app_info_get_commandline; + iface->get_icon = g_osx_app_info_get_icon; + iface->get_supported_types = g_osx_app_info_get_supported_types; + + iface->set_as_last_used_for_type = g_osx_app_info_set_as_last_used_for_type; + iface->set_as_default_for_type = g_osx_app_info_set_as_default_for_type; + + iface->launch = g_osx_app_info_launch; + iface->launch_uris = g_osx_app_info_launch_uris; + + iface->supports_uris = g_osx_app_info_supports_uris; + iface->supports_files = g_osx_app_info_supports_files; + iface->should_show = g_osx_app_info_should_show; + iface->can_delete = g_osx_app_info_can_delete; +} + +GAppInfo * +g_app_info_create_from_commandline (const char *commandline, + const char *application_name, + GAppInfoCreateFlags flags, + GError **error) +{ + return NULL; +} + +GList * +g_osx_app_info_get_all_for_scheme (const char *cscheme) +{ + CFArrayRef bundle_list; + CFStringRef scheme; + NSBundle *bundle; + GList *info_list = NULL; + gint i; + + scheme = create_cfstring_from_cstr (cscheme); + bundle_list = LSCopyAllHandlersForURLScheme (scheme); + CFRelease (scheme); + + if (!bundle_list) + return NULL; + + for (i = 0; i < CFArrayGetCount (bundle_list); i++) + { + CFStringRef bundle_id = CFArrayGetValueAtIndex (bundle_list, i); + GAppInfo *info; + + bundle = get_bundle_for_id (bundle_id); + + if (!bundle) + continue; + + info = G_APP_INFO (g_osx_app_info_new (bundle)); + info_list = g_list_append (info_list, info); + } + CFRelease (bundle_list); + return info_list; +} + +GList * +g_app_info_get_all_for_type (const char *content_type) +{ + gchar *mime_type; + CFArrayRef bundle_list; + CFStringRef type; + NSBundle *bundle; + GList *info_list = NULL; + gint i; + + mime_type = g_content_type_get_mime_type (content_type); + if (g_str_has_prefix (mime_type, "x-scheme-handler/")) + { + gchar *scheme = strchr (mime_type, '/') + 1; + GList *ret = g_osx_app_info_get_all_for_scheme (scheme); + + g_free (mime_type); + return ret; + } + g_free (mime_type); + + type = create_cfstring_from_cstr (content_type); + bundle_list = LSCopyAllRoleHandlersForContentType (type, kLSRolesAll); + CFRelease (type); + + if (!bundle_list) + return NULL; + + for (i = 0; i < CFArrayGetCount (bundle_list); i++) + { + CFStringRef bundle_id = CFArrayGetValueAtIndex (bundle_list, i); + GAppInfo *info; + + bundle = get_bundle_for_id (bundle_id); + + if (!bundle) + continue; + + info = G_APP_INFO (g_osx_app_info_new (bundle)); + info_list = g_list_append (info_list, info); + } + CFRelease (bundle_list); + return info_list; +} + +GList * +g_app_info_get_recommended_for_type (const char *content_type) +{ + return g_app_info_get_all_for_type (content_type); +} + +GList * +g_app_info_get_fallback_for_type (const char *content_type) +{ + return g_app_info_get_all_for_type (content_type); +} + +GAppInfo * +g_app_info_get_default_for_type (const char *content_type, + gboolean must_support_uris) +{ + gchar *mime_type; + CFStringRef type; + NSBundle *bundle; +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER + CFURLRef bundle_id; +#else + CFStringRef bundle_id; +#endif + + mime_type = g_content_type_get_mime_type (content_type); + if (g_str_has_prefix (mime_type, "x-scheme-handler/")) + { + gchar *scheme = strchr (mime_type, '/') + 1; + GAppInfo *ret = g_app_info_get_default_for_uri_scheme (scheme); + + g_free (mime_type); + return ret; + } + g_free (mime_type); + + type = create_cfstring_from_cstr (content_type); + +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER + bundle_id = LSCopyDefaultApplicationURLForContentType (type, kLSRolesAll, NULL); +#else + bundle_id = LSCopyDefaultRoleHandlerForContentType (type, kLSRolesAll); +#endif + CFRelease (type); + + if (!bundle_id) + { + g_warning ("No default handler found for content type '%s'.", content_type); + return NULL; + } + +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER + bundle = get_bundle_for_url (bundle_id); +#else + bundle = get_bundle_for_id (bundle_id); +#endif + CFRelease (bundle_id); + + if (!bundle) + return NULL; + + return G_APP_INFO (g_osx_app_info_new (bundle)); +} + +GAppInfo * +g_app_info_get_default_for_uri_scheme (const char *uri_scheme) +{ + CFStringRef scheme, bundle_id; + NSBundle *bundle; + + scheme = create_cfstring_from_cstr (uri_scheme); + bundle_id = LSCopyDefaultHandlerForURLScheme (scheme); + CFRelease (scheme); + + if (!bundle_id) + { + g_warning ("No default handler found for url scheme '%s'.", uri_scheme); + return NULL; + } + + bundle = get_bundle_for_id (bundle_id); + CFRelease (bundle_id); + + if (!bundle) + return NULL; + + return G_APP_INFO (g_osx_app_info_new (bundle)); +} + +GList * +g_app_info_get_all (void) +{ + /* There is no API for this afaict + * could manually do it... + */ + return NULL; +} + +void +g_app_info_reset_type_associations (const char *content_type) +{ +} diff --git a/gio/gosxcontenttype.m b/gio/gosxcontenttype.m new file mode 100644 index 0000000..6119bbc --- /dev/null +++ b/gio/gosxcontenttype.m @@ -0,0 +1,597 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2014 Patrick Griffis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ + +#include "config.h" + +#include "gcontenttype.h" +#include "gicon.h" +#include "gthemedicon.h" + +#include + +#define XDG_PREFIX _gio_xdg +#include "xdgmime/xdgmime.h" + +/* We lock this mutex whenever we modify global state in this module. */ +G_LOCK_DEFINE_STATIC (gio_xdgmime); + + +/*< internal > + * create_cfstring_from_cstr: + * @cstr: a #gchar + * + * Converts a cstr to a utf8 cfstring + * It must be CFReleased()'d. + * + */ +static CFStringRef +create_cfstring_from_cstr (const gchar *cstr) +{ + return CFStringCreateWithCString (NULL, cstr, kCFStringEncodingUTF8); +} + +/*< internal > + * create_cstr_from_cfstring: + * @str: a #CFStringRef + * + * Converts a cfstring to a utf8 cstring. + * The incoming cfstring is released for you. + * The returned string must be g_free()'d. + * + */ +static gchar * +create_cstr_from_cfstring (CFStringRef str) +{ + g_return_val_if_fail (str != NULL, NULL); + + CFIndex length = CFStringGetLength (str); + CFIndex maxlen = CFStringGetMaximumSizeForEncoding (length, kCFStringEncodingUTF8); + gchar *buffer = g_malloc (maxlen + 1); + Boolean success = CFStringGetCString (str, (char *) buffer, maxlen, + kCFStringEncodingUTF8); + CFRelease (str); + if (success) + return buffer; + else + { + g_free (buffer); + return NULL; + } +} + +/*< internal > + * create_cstr_from_cfstring_with_fallback: + * @str: a #CFStringRef + * @fallback: a #gchar + * + * Tries to convert a cfstring to a utf8 cstring. + * If @str is NULL or conversion fails @fallback is returned. + * The incoming cfstring is released for you. + * The returned string must be g_free()'d. + * + */ +static gchar * +create_cstr_from_cfstring_with_fallback (CFStringRef str, + const gchar *fallback) +{ + gchar *cstr = NULL; + + if (str) + cstr = create_cstr_from_cfstring (str); + if (!cstr) + return g_strdup (fallback); + + return cstr; +} + +/*< private >*/ +void +g_content_type_set_mime_dirs (const gchar * const *dirs) +{ + /* noop on macOS */ +} + +/*< private >*/ +const gchar * const * +g_content_type_get_mime_dirs (void) +{ + const gchar * const *mime_dirs = { NULL }; + return mime_dirs; +} + +gboolean +g_content_type_equals (const gchar *type1, + const gchar *type2) +{ + CFStringRef str1, str2; + gboolean ret; + + g_return_val_if_fail (type1 != NULL, FALSE); + g_return_val_if_fail (type2 != NULL, FALSE); + + if (g_ascii_strcasecmp (type1, type2) == 0) + return TRUE; + + str1 = create_cfstring_from_cstr (type1); + str2 = create_cfstring_from_cstr (type2); + + ret = UTTypeEqual (str1, str2); + + CFRelease (str1); + CFRelease (str2); + + return ret; +} + +gboolean +g_content_type_is_a (const gchar *ctype, + const gchar *csupertype) +{ + CFStringRef type, supertype; + gboolean ret; + + g_return_val_if_fail (ctype != NULL, FALSE); + g_return_val_if_fail (csupertype != NULL, FALSE); + + type = create_cfstring_from_cstr (ctype); + supertype = create_cfstring_from_cstr (csupertype); + + ret = UTTypeConformsTo (type, supertype); + + CFRelease (type); + CFRelease (supertype); + + return ret; +} + +gboolean +g_content_type_is_mime_type (const gchar *type, + const gchar *mime_type) +{ + gchar *content_type; + gboolean ret; + + g_return_val_if_fail (type != NULL, FALSE); + g_return_val_if_fail (mime_type != NULL, FALSE); + + content_type = g_content_type_from_mime_type (mime_type); + ret = g_content_type_is_a (type, content_type); + g_free (content_type); + + return ret; +} + +gboolean +g_content_type_is_unknown (const gchar *type) +{ + g_return_val_if_fail (type != NULL, FALSE); + + /* Should dynamic types be considered "unknown"? */ + if (g_str_has_prefix (type, "dyn.")) + return TRUE; + /* application/octet-stream */ + else if (g_strcmp0 (type, "public.data") == 0) + return TRUE; + + return FALSE; +} + +gchar * +g_content_type_get_description (const gchar *type) +{ + CFStringRef str; + CFStringRef desc_str; + + g_return_val_if_fail (type != NULL, NULL); + + str = create_cfstring_from_cstr (type); + desc_str = UTTypeCopyDescription (str); + + CFRelease (str); + return create_cstr_from_cfstring_with_fallback (desc_str, "unknown"); +} + +/* + * _get_generic_icon_name_from_mime_type + * + * This function produces a generic icon name from a @mime_type. + * If no generic icon name is found in the xdg mime database, the + * generic icon name is constructed. + * + * Background: + * generic-icon elements specify the icon to use as a generic icon for this + * particular mime-type, given by the name attribute. This is used if there + * is no specific icon (see icon for how these are found). These are used + * for categories of similar types (like spreadsheets or archives) that can + * use a common icon. The Icon Naming Specification lists a set of such + * icon names. If this element is not specified then the mimetype is used + * to generate the generic icon by using the top-level media type + * (e.g. "video" in "video/ogg") and appending "-x-generic" + * (i.e. "video-x-generic" in the previous example). + * + * From: https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.18.html + */ + +static gchar * +_get_generic_icon_name_from_mime_type (const gchar *mime_type) +{ + const gchar *xdg_icon_name; + gchar *icon_name; + + G_LOCK (gio_xdgmime); + xdg_icon_name = xdg_mime_get_generic_icon (mime_type); + G_UNLOCK (gio_xdgmime); + + if (xdg_icon_name == NULL) + { + const char *p; + const char *suffix = "-x-generic"; + gsize prefix_len; + + p = strchr (mime_type, '/'); + if (p == NULL) + prefix_len = strlen (mime_type); + else + prefix_len = p - mime_type; + + icon_name = g_malloc (prefix_len + strlen (suffix) + 1); + memcpy (icon_name, mime_type, prefix_len); + memcpy (icon_name + prefix_len, suffix, strlen (suffix)); + icon_name[prefix_len + strlen (suffix)] = 0; + } + else + { + icon_name = g_strdup (xdg_icon_name); + } + + return icon_name; +} + + +static GIcon * +g_content_type_get_icon_internal (const gchar *uti, + gboolean symbolic) +{ + char *mimetype_icon; + char *mime_type; + char *generic_mimetype_icon = NULL; + char *q; + char *icon_names[6]; + int n = 0; + GIcon *themed_icon; + const char *xdg_icon; + int i; + + g_return_val_if_fail (uti != NULL, NULL); + + mime_type = g_content_type_get_mime_type (uti); + + G_LOCK (gio_xdgmime); + xdg_icon = xdg_mime_get_icon (mime_type); + G_UNLOCK (gio_xdgmime); + + if (xdg_icon) + icon_names[n++] = g_strdup (xdg_icon); + + mimetype_icon = g_strdup (mime_type); + while ((q = strchr (mimetype_icon, '/')) != NULL) + *q = '-'; + + icon_names[n++] = mimetype_icon; + + generic_mimetype_icon = _get_generic_icon_name_from_mime_type (mime_type); + + if (generic_mimetype_icon) + icon_names[n++] = generic_mimetype_icon; + + if (symbolic) + { + for (i = 0; i < n; i++) + { + icon_names[n + i] = icon_names[i]; + icon_names[i] = g_strconcat (icon_names[i], "-symbolic", NULL); + } + + n += n; + } + + themed_icon = g_themed_icon_new_from_names (icon_names, n); + + for (i = 0; i < n; i++) + g_free (icon_names[i]); + + g_free(mime_type); + + return themed_icon; +} + +GIcon * +g_content_type_get_icon (const gchar *type) +{ + return g_content_type_get_icon_internal (type, FALSE); +} + +GIcon * +g_content_type_get_symbolic_icon (const gchar *type) +{ + return g_content_type_get_icon_internal (type, TRUE); +} + +gchar * +g_content_type_get_generic_icon_name (const gchar *type) +{ + return NULL; +} + +gboolean +g_content_type_can_be_executable (const gchar *type) +{ + CFStringRef uti; + gboolean ret = FALSE; + + g_return_val_if_fail (type != NULL, FALSE); + + uti = create_cfstring_from_cstr (type); + + if (UTTypeConformsTo (uti, kUTTypeApplication)) + ret = TRUE; + else if (UTTypeConformsTo (uti, CFSTR("public.executable"))) + ret = TRUE; + else if (UTTypeConformsTo (uti, CFSTR("public.script"))) + ret = TRUE; + /* Our tests assert that all text can be executable... */ + else if (UTTypeConformsTo (uti, CFSTR("public.text"))) + ret = TRUE; + + CFRelease (uti); + return ret; +} + +gchar * +g_content_type_from_mime_type (const gchar *mime_type) +{ + CFStringRef mime_str; + CFStringRef uti_str; + + g_return_val_if_fail (mime_type != NULL, NULL); + + /* Their api does not handle globs but they are common. */ + if (g_str_has_suffix (mime_type, "*")) + { + if (g_str_has_prefix (mime_type, "audio")) + return g_strdup ("public.audio"); + if (g_str_has_prefix (mime_type, "image")) + return g_strdup ("public.image"); + if (g_str_has_prefix (mime_type, "text")) + return g_strdup ("public.text"); + if (g_str_has_prefix (mime_type, "video")) + return g_strdup ("public.movie"); + } + + /* Some exceptions are needed for gdk-pixbuf. + * This list is not exhaustive. + */ + if (g_str_has_prefix (mime_type, "image")) + { + if (g_str_has_suffix (mime_type, "x-icns")) + return g_strdup ("com.apple.icns"); + if (g_str_has_suffix (mime_type, "x-tga")) + return g_strdup ("com.truevision.tga-image"); + if (g_str_has_suffix (mime_type, "x-ico")) + return g_strdup ("com.microsoft.ico "); + } + + /* These are also not supported... + * Used in glocalfileinfo.c + */ + if (g_str_has_prefix (mime_type, "inode")) + { + if (g_str_has_suffix (mime_type, "directory")) + return g_strdup ("public.folder"); + if (g_str_has_suffix (mime_type, "symlink")) + return g_strdup ("public.symlink"); + } + + /* This is correct according to the Apple docs: + https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html + */ + if (strcmp (mime_type, "text/plain") == 0) + return g_strdup ("public.text"); + + /* Non standard type */ + if (strcmp (mime_type, "application/x-executable") == 0) + return g_strdup ("public.executable"); + + mime_str = create_cfstring_from_cstr (mime_type); + uti_str = UTTypeCreatePreferredIdentifierForTag (kUTTagClassMIMEType, mime_str, NULL); + + CFRelease (mime_str); + return create_cstr_from_cfstring_with_fallback (uti_str, "public.data"); +} + +gchar * +g_content_type_get_mime_type (const gchar *type) +{ + CFStringRef uti_str; + CFStringRef mime_str; + + g_return_val_if_fail (type != NULL, NULL); + + /* We must match the additions above + * so conversions back and forth work. + */ + if (g_str_has_prefix (type, "public")) + { + if (g_str_has_suffix (type, ".image")) + return g_strdup ("image/*"); + if (g_str_has_suffix (type, ".movie")) + return g_strdup ("video/*"); + if (g_str_has_suffix (type, ".text")) + return g_strdup ("text/*"); + if (g_str_has_suffix (type, ".audio")) + return g_strdup ("audio/*"); + if (g_str_has_suffix (type, ".folder")) + return g_strdup ("inode/directory"); + if (g_str_has_suffix (type, ".symlink")) + return g_strdup ("inode/symlink"); + if (g_str_has_suffix (type, ".executable")) + return g_strdup ("application/x-executable"); + } + + uti_str = create_cfstring_from_cstr (type); + mime_str = UTTypeCopyPreferredTagWithClass(uti_str, kUTTagClassMIMEType); + + CFRelease (uti_str); + return create_cstr_from_cfstring_with_fallback (mime_str, "application/octet-stream"); +} + +static gboolean +looks_like_text (const guchar *data, + gsize data_size) +{ + gsize i; + guchar c; + + for (i = 0; i < data_size; i++) + { + c = data[i]; + if (g_ascii_iscntrl (c) && !g_ascii_isspace (c) && c != '\b') + return FALSE; + } + return TRUE; +} + +gchar * +g_content_type_guess (const gchar *filename, + const guchar *data, + gsize data_size, + gboolean *result_uncertain) +{ + CFStringRef uti = NULL; + gchar *cextension; + CFStringRef extension; + int uncertain = -1; + + g_return_val_if_fail (data_size != (gsize) -1, NULL); + + if (filename && *filename) + { + gchar *basename = g_path_get_basename (filename); + gchar *dirname = g_path_get_dirname (filename); + gsize i = strlen (filename); + + if (filename[i - 1] == '/') + { + if (g_strcmp0 (dirname, "/Volumes") == 0) + { + uti = CFStringCreateCopy (NULL, kUTTypeVolume); + } + else if ((cextension = strrchr (basename, '.')) != NULL) + { + cextension++; + extension = create_cfstring_from_cstr (cextension); + uti = UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension, + extension, NULL); + CFRelease (extension); + + if (CFStringHasPrefix (uti, CFSTR ("dyn."))) + { + CFRelease (uti); + uti = CFStringCreateCopy (NULL, kUTTypeFolder); + uncertain = TRUE; + } + } + else + { + uti = CFStringCreateCopy (NULL, kUTTypeFolder); + uncertain = TRUE; /* Matches Unix backend */ + } + } + else + { + /* GTK needs this... */ + if (g_str_has_suffix (basename, ".ui")) + { + uti = CFStringCreateCopy (NULL, kUTTypeXML); + } + else if (g_str_has_suffix (basename, ".txt")) + { + uti = CFStringCreateCopy (NULL, CFSTR ("public.text")); + } + else if ((cextension = strrchr (basename, '.')) != NULL) + { + cextension++; + extension = create_cfstring_from_cstr (cextension); + uti = UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension, + extension, NULL); + CFRelease (extension); + } + g_free (basename); + g_free (dirname); + } + } + if (data && (!filename || !uti || + CFStringCompare (uti, CFSTR ("public.data"), 0) == kCFCompareEqualTo)) + { + const char *sniffed_mimetype; + G_LOCK (gio_xdgmime); + sniffed_mimetype = xdg_mime_get_mime_type_for_data (data, data_size, NULL); + G_UNLOCK (gio_xdgmime); + if (sniffed_mimetype != XDG_MIME_TYPE_UNKNOWN) + { + gchar *uti_str = g_content_type_from_mime_type (sniffed_mimetype); + uti = create_cfstring_from_cstr (uti_str); + g_free (uti_str); + } + if (!uti && looks_like_text (data, data_size)) + { + if (g_str_has_prefix ((const gchar*)data, "#!/")) + uti = CFStringCreateCopy (NULL, CFSTR ("public.script")); + else + uti = CFStringCreateCopy (NULL, CFSTR ("public.text")); + } + } + + if (!uti) + { + /* Generic data type */ + uti = CFStringCreateCopy (NULL, CFSTR ("public.data")); + if (result_uncertain) + *result_uncertain = TRUE; + } + else if (result_uncertain) + { + *result_uncertain = uncertain == -1 ? FALSE : uncertain; + } + + return create_cstr_from_cfstring (uti); +} + +GList * +g_content_types_get_registered (void) +{ + /* TODO: UTTypeCreateAllIdentifiersForTag? */ + return NULL; +} + +gchar ** +g_content_type_guess_for_tree (GFile *root) +{ + return NULL; +} diff --git a/gio/goutputstream.c b/gio/goutputstream.c new file mode 100644 index 0000000..3547b8f --- /dev/null +++ b/gio/goutputstream.c @@ -0,0 +1,3004 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include +#include "goutputstream.h" +#include "gcancellable.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "ginputstream.h" +#include "gioerror.h" +#include "gioprivate.h" +#include "glibintl.h" +#include "gpollableoutputstream.h" + +/** + * SECTION:goutputstream + * @short_description: Base class for implementing streaming output + * @include: gio/gio.h + * + * #GOutputStream has functions to write to a stream (g_output_stream_write()), + * to close a stream (g_output_stream_close()) and to flush pending writes + * (g_output_stream_flush()). + * + * To copy the content of an input stream to an output stream without + * manually handling the reads and writes, use g_output_stream_splice(). + * + * See the documentation for #GIOStream for details of thread safety of + * streaming APIs. + * + * All of these functions have async variants too. + **/ + +struct _GOutputStreamPrivate { + guint closed : 1; + guint pending : 1; + guint closing : 1; + GAsyncReadyCallback outstanding_callback; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GOutputStream, g_output_stream, G_TYPE_OBJECT) + +static gssize g_output_stream_real_splice (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + GCancellable *cancellable, + GError **error); +static void g_output_stream_real_write_async (GOutputStream *stream, + const void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gssize g_output_stream_real_write_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); +static gboolean g_output_stream_real_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); +static void g_output_stream_real_writev_async (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_output_stream_real_writev_finish (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error); +static void g_output_stream_real_splice_async (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gssize g_output_stream_real_splice_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); +static void g_output_stream_real_flush_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_output_stream_real_flush_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); +static void g_output_stream_real_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_output_stream_real_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); +static gboolean g_output_stream_internal_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error); +static void g_output_stream_internal_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gboolean g_output_stream_internal_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); + +static void +g_output_stream_dispose (GObject *object) +{ + GOutputStream *stream; + + stream = G_OUTPUT_STREAM (object); + + if (!stream->priv->closed) + g_output_stream_close (stream, NULL, NULL); + + G_OBJECT_CLASS (g_output_stream_parent_class)->dispose (object); +} + +static void +g_output_stream_class_init (GOutputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_output_stream_dispose; + + klass->splice = g_output_stream_real_splice; + + klass->write_async = g_output_stream_real_write_async; + klass->write_finish = g_output_stream_real_write_finish; + klass->writev_fn = g_output_stream_real_writev; + klass->writev_async = g_output_stream_real_writev_async; + klass->writev_finish = g_output_stream_real_writev_finish; + klass->splice_async = g_output_stream_real_splice_async; + klass->splice_finish = g_output_stream_real_splice_finish; + klass->flush_async = g_output_stream_real_flush_async; + klass->flush_finish = g_output_stream_real_flush_finish; + klass->close_async = g_output_stream_real_close_async; + klass->close_finish = g_output_stream_real_close_finish; +} + +static void +g_output_stream_init (GOutputStream *stream) +{ + stream->priv = g_output_stream_get_instance_private (stream); +} + +/** + * g_output_stream_write: + * @stream: a #GOutputStream. + * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. + * @count: the number of bytes to write + * @cancellable: (nullable): optional cancellable object + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to write @count bytes from @buffer into the stream. Will block + * during the operation. + * + * If count is 0, returns 0 and does nothing. A value of @count + * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error. + * + * On success, the number of bytes written to the stream is returned. + * It is not an error if this is not the same as the requested size, as it + * can happen e.g. on a partial I/O error, or if there is not enough + * storage in the stream. All writes block until at least one byte + * is written or an error occurs; 0 is never returned (unless + * @count is 0). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an + * operation was partially finished when the operation was cancelled the + * partial result will be returned, without an error. + * + * On error -1 is returned and @error is set accordingly. + * + * Virtual: write_fn + * + * Returns: Number of bytes written, or -1 on error + **/ +gssize +g_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GOutputStreamClass *class; + gssize res; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1); + g_return_val_if_fail (buffer != NULL, 0); + + if (count == 0) + return 0; + + if (((gssize) count) < 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), G_STRFUNC); + return -1; + } + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + if (class->write_fn == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Output stream doesn’t implement write")); + return -1; + } + + if (!g_output_stream_set_pending (stream, error)) + return -1; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->write_fn (stream, buffer, count, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_output_stream_clear_pending (stream); + + return res; +} + +/** + * g_output_stream_write_all: + * @stream: a #GOutputStream. + * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. + * @count: the number of bytes to write + * @bytes_written: (out) (optional): location to store the number of bytes that was + * written to the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to write @count bytes from @buffer into the stream. Will block + * during the operation. + * + * This function is similar to g_output_stream_write(), except it tries to + * write as many bytes as requested, only stopping on an error. + * + * On a successful write of @count bytes, %TRUE is returned, and @bytes_written + * is set to @count. + * + * If there is an error during the operation %FALSE is returned and @error + * is set to indicate the error status. + * + * As a special exception to the normal conventions for functions that + * use #GError, if this function returns %FALSE (and sets @error) then + * @bytes_written will be set to the number of bytes that were + * successfully written before the error was encountered. This + * functionality is only available from C. If you need it from another + * language then you must write your own loop around + * g_output_stream_write(). + * + * Returns: %TRUE on success, %FALSE if there was an error + **/ +gboolean +g_output_stream_write_all (GOutputStream *stream, + const void *buffer, + gsize count, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + gsize _bytes_written; + gssize res; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (buffer != NULL || count == 0, FALSE); + + _bytes_written = 0; + while (_bytes_written < count) + { + res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written, + cancellable, error); + if (res == -1) + { + if (bytes_written) + *bytes_written = _bytes_written; + return FALSE; + } + g_return_val_if_fail (res > 0, FALSE); + + _bytes_written += res; + } + + if (bytes_written) + *bytes_written = _bytes_written; + + return TRUE; +} + +/** + * g_output_stream_writev: + * @stream: a #GOutputStream. + * @vectors: (array length=n_vectors): the buffer containing the #GOutputVectors to write. + * @n_vectors: the number of vectors to write + * @bytes_written: (out) (optional): location to store the number of bytes that were + * written to the stream + * @cancellable: (nullable): optional cancellable object + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to write the bytes contained in the @n_vectors @vectors into the + * stream. Will block during the operation. + * + * If @n_vectors is 0 or the sum of all bytes in @vectors is 0, returns 0 and + * does nothing. + * + * On success, the number of bytes written to the stream is returned. + * It is not an error if this is not the same as the requested size, as it + * can happen e.g. on a partial I/O error, or if there is not enough + * storage in the stream. All writes block until at least one byte + * is written or an error occurs; 0 is never returned (unless + * @n_vectors is 0 or the sum of all bytes in @vectors is 0). + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an + * operation was partially finished when the operation was cancelled the + * partial result will be returned, without an error. + * + * Some implementations of g_output_stream_writev() may have limitations on the + * aggregate buffer size, and will return %G_IO_ERROR_INVALID_ARGUMENT if these + * are exceeded. For example, when writing to a local file on UNIX platforms, + * the aggregate buffer size must not exceed %G_MAXSSIZE bytes. + * + * Virtual: writev_fn + * + * Returns: %TRUE on success, %FALSE if there was an error + * + * Since: 2.60 + */ +gboolean +g_output_stream_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + GOutputStreamClass *class; + gboolean res; + gsize _bytes_written = 0; + + if (bytes_written) + *bytes_written = 0; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (vectors != NULL || n_vectors == 0, FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (n_vectors == 0) + return TRUE; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + g_return_val_if_fail (class->writev_fn != NULL, FALSE); + + if (!g_output_stream_set_pending (stream, error)) + return FALSE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->writev_fn (stream, vectors, n_vectors, &_bytes_written, cancellable, error); + + g_warn_if_fail (res || _bytes_written == 0); + g_warn_if_fail (res || (error == NULL || *error != NULL)); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_output_stream_clear_pending (stream); + + if (bytes_written) + *bytes_written = _bytes_written; + + return res; +} + +/** + * g_output_stream_writev_all: + * @stream: a #GOutputStream. + * @vectors: (array length=n_vectors): the buffer containing the #GOutputVectors to write. + * @n_vectors: the number of vectors to write + * @bytes_written: (out) (optional): location to store the number of bytes that were + * written to the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to write the bytes contained in the @n_vectors @vectors into the + * stream. Will block during the operation. + * + * This function is similar to g_output_stream_writev(), except it tries to + * write as many bytes as requested, only stopping on an error. + * + * On a successful write of all @n_vectors vectors, %TRUE is returned, and + * @bytes_written is set to the sum of all the sizes of @vectors. + * + * If there is an error during the operation %FALSE is returned and @error + * is set to indicate the error status. + * + * As a special exception to the normal conventions for functions that + * use #GError, if this function returns %FALSE (and sets @error) then + * @bytes_written will be set to the number of bytes that were + * successfully written before the error was encountered. This + * functionality is only available from C. If you need it from another + * language then you must write your own loop around + * g_output_stream_write(). + * + * The content of the individual elements of @vectors might be changed by this + * function. + * + * Returns: %TRUE on success, %FALSE if there was an error + * + * Since: 2.60 + */ +gboolean +g_output_stream_writev_all (GOutputStream *stream, + GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + gsize _bytes_written = 0; + gsize i, to_be_written = 0; + + if (bytes_written) + *bytes_written = 0; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (vectors != NULL || n_vectors == 0, FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* We can't write more than G_MAXSIZE bytes overall, otherwise we + * would overflow the bytes_written counter */ + for (i = 0; i < n_vectors; i++) + { + if (to_be_written > G_MAXSIZE - vectors[i].size) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Sum of vectors passed to %s too large"), G_STRFUNC); + return FALSE; + } + to_be_written += vectors[i].size; + } + + _bytes_written = 0; + while (n_vectors > 0 && to_be_written > 0) + { + gsize n_written = 0; + gboolean res; + + res = g_output_stream_writev (stream, vectors, n_vectors, &n_written, cancellable, error); + + if (!res) + { + if (bytes_written) + *bytes_written = _bytes_written; + return FALSE; + } + + g_return_val_if_fail (n_written > 0, FALSE); + _bytes_written += n_written; + + /* skip vectors that have been written in full */ + while (n_vectors > 0 && n_written >= vectors[0].size) + { + n_written -= vectors[0].size; + ++vectors; + --n_vectors; + } + /* skip partially written vector data */ + if (n_written > 0 && n_vectors > 0) + { + vectors[0].size -= n_written; + vectors[0].buffer = ((guint8 *) vectors[0].buffer) + n_written; + } + } + + if (bytes_written) + *bytes_written = _bytes_written; + + return TRUE; +} + +/** + * g_output_stream_printf: + * @stream: a #GOutputStream. + * @bytes_written: (out) (optional): location to store the number of bytes that was + * written to the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * @format: the format string. See the printf() documentation + * @...: the parameters to insert into the format string + * + * This is a utility function around g_output_stream_write_all(). It + * uses g_strdup_vprintf() to turn @format and @... into a string that + * is then written to @stream. + * + * See the documentation of g_output_stream_write_all() about the + * behavior of the actual write operation. + * + * Note that partial writes cannot be properly checked with this + * function due to the variable length of the written string, if you + * need precise control over partial write failures, you need to + * create you own printf()-like wrapper around g_output_stream_write() + * or g_output_stream_write_all(). + * + * Since: 2.40 + * + * Returns: %TRUE on success, %FALSE if there was an error + **/ +gboolean +g_output_stream_printf (GOutputStream *stream, + gsize *bytes_written, + GCancellable *cancellable, + GError **error, + const gchar *format, + ...) +{ + va_list args; + gboolean success; + + va_start (args, format); + success = g_output_stream_vprintf (stream, bytes_written, cancellable, + error, format, args); + va_end (args); + + return success; +} + +/** + * g_output_stream_vprintf: + * @stream: a #GOutputStream. + * @bytes_written: (out) (optional): location to store the number of bytes that was + * written to the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * @format: the format string. See the printf() documentation + * @args: the parameters to insert into the format string + * + * This is a utility function around g_output_stream_write_all(). It + * uses g_strdup_vprintf() to turn @format and @args into a string that + * is then written to @stream. + * + * See the documentation of g_output_stream_write_all() about the + * behavior of the actual write operation. + * + * Note that partial writes cannot be properly checked with this + * function due to the variable length of the written string, if you + * need precise control over partial write failures, you need to + * create you own printf()-like wrapper around g_output_stream_write() + * or g_output_stream_write_all(). + * + * Since: 2.40 + * + * Returns: %TRUE on success, %FALSE if there was an error + **/ +gboolean +g_output_stream_vprintf (GOutputStream *stream, + gsize *bytes_written, + GCancellable *cancellable, + GError **error, + const gchar *format, + va_list args) +{ + gchar *text; + gboolean success; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (format != NULL, FALSE); + + text = g_strdup_vprintf (format, args); + success = g_output_stream_write_all (stream, + text, strlen (text), + bytes_written, cancellable, error); + g_free (text); + + return success; +} + +/** + * g_output_stream_write_bytes: + * @stream: a #GOutputStream. + * @bytes: the #GBytes to write + * @cancellable: (nullable): optional cancellable object + * @error: location to store the error occurring, or %NULL to ignore + * + * A wrapper function for g_output_stream_write() which takes a + * #GBytes as input. This can be more convenient for use by language + * bindings or in other cases where the refcounted nature of #GBytes + * is helpful over a bare pointer interface. + * + * However, note that this function may still perform partial writes, + * just like g_output_stream_write(). If that occurs, to continue + * writing, you will need to create a new #GBytes containing just the + * remaining bytes, using g_bytes_new_from_bytes(). Passing the same + * #GBytes instance multiple times potentially can result in duplicated + * data in the output stream. + * + * Returns: Number of bytes written, or -1 on error + **/ +gssize +g_output_stream_write_bytes (GOutputStream *stream, + GBytes *bytes, + GCancellable *cancellable, + GError **error) +{ + gsize size; + gconstpointer data; + + data = g_bytes_get_data (bytes, &size); + + return g_output_stream_write (stream, + data, size, + cancellable, + error); +} + +/** + * g_output_stream_flush: + * @stream: a #GOutputStream. + * @cancellable: (nullable): optional cancellable object + * @error: location to store the error occurring, or %NULL to ignore + * + * Forces a write of all user-space buffered data for the given + * @stream. Will block during the operation. Closing the stream will + * implicitly cause a flush. + * + * This function is optional for inherited classes. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE on success, %FALSE on error + **/ +gboolean +g_output_stream_flush (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GOutputStreamClass *class; + gboolean res; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + + if (!g_output_stream_set_pending (stream, error)) + return FALSE; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + res = TRUE; + if (class->flush) + { + if (cancellable) + g_cancellable_push_current (cancellable); + + res = class->flush (stream, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + } + + g_output_stream_clear_pending (stream); + + return res; +} + +/** + * g_output_stream_splice: + * @stream: a #GOutputStream. + * @source: a #GInputStream. + * @flags: a set of #GOutputStreamSpliceFlags. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Splices an input stream into an output stream. + * + * Returns: a #gssize containing the size of the data spliced, or + * -1 if an error occurred. Note that if the number of bytes + * spliced is greater than %G_MAXSSIZE, then that will be + * returned, and there is no way to determine the actual number + * of bytes spliced. + **/ +gssize +g_output_stream_splice (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + GCancellable *cancellable, + GError **error) +{ + GOutputStreamClass *class; + gssize bytes_copied; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1); + g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1); + + if (g_input_stream_is_closed (source)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Source stream is already closed")); + return -1; + } + + if (!g_output_stream_set_pending (stream, error)) + return -1; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + if (cancellable) + g_cancellable_push_current (cancellable); + + bytes_copied = class->splice (stream, source, flags, cancellable, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + g_output_stream_clear_pending (stream); + + return bytes_copied; +} + +static gssize +g_output_stream_real_splice (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + GCancellable *cancellable, + GError **error) +{ + GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream); + gssize n_read, n_written; + gsize bytes_copied; + char buffer[8192], *p; + gboolean res; + + bytes_copied = 0; + if (class->write_fn == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Output stream doesn’t implement write")); + res = FALSE; + goto notsupported; + } + + res = TRUE; + do + { + n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error); + if (n_read == -1) + { + res = FALSE; + break; + } + + if (n_read == 0) + break; + + p = buffer; + while (n_read > 0) + { + n_written = class->write_fn (stream, p, n_read, cancellable, error); + if (n_written == -1) + { + res = FALSE; + break; + } + + p += n_written; + n_read -= n_written; + bytes_copied += n_written; + } + + if (bytes_copied > G_MAXSSIZE) + bytes_copied = G_MAXSSIZE; + } + while (res); + + notsupported: + if (!res) + error = NULL; /* Ignore further errors */ + + if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE) + { + /* Don't care about errors in source here */ + g_input_stream_close (source, cancellable, NULL); + } + + if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET) + { + /* But write errors on close are bad! */ + if (!g_output_stream_internal_close (stream, cancellable, error)) + res = FALSE; + } + + if (res) + return bytes_copied; + + return -1; +} + +/* Must always be called inside + * g_output_stream_set_pending()/g_output_stream_clear_pending(). */ +static gboolean +g_output_stream_internal_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GOutputStreamClass *class; + gboolean res; + + if (stream->priv->closed) + return TRUE; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + stream->priv->closing = TRUE; + + if (cancellable) + g_cancellable_push_current (cancellable); + + if (class->flush) + res = class->flush (stream, cancellable, error); + else + res = TRUE; + + if (!res) + { + /* flushing caused the error that we want to return, + * but we still want to close the underlying stream if possible + */ + if (class->close_fn) + class->close_fn (stream, cancellable, NULL); + } + else + { + res = TRUE; + if (class->close_fn) + res = class->close_fn (stream, cancellable, error); + } + + if (cancellable) + g_cancellable_pop_current (cancellable); + + stream->priv->closing = FALSE; + stream->priv->closed = TRUE; + + return res; +} + +/** + * g_output_stream_close: + * @stream: A #GOutputStream. + * @cancellable: (nullable): optional cancellable object + * @error: location to store the error occurring, or %NULL to ignore + * + * Closes the stream, releasing resources related to it. + * + * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED. + * Closing a stream multiple times will not return an error. + * + * Closing a stream will automatically flush any outstanding buffers in the + * stream. + * + * Streams will be automatically closed when the last reference + * is dropped, but you might want to call this function to make sure + * resources are released as early as possible. + * + * Some streams might keep the backing store of the stream (e.g. a file descriptor) + * open after the stream is closed. See the documentation for the individual + * stream for details. + * + * On failure the first error that happened will be reported, but the close + * operation will finish as much as possible. A stream that failed to + * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it + * is important to check and report the error to the user, otherwise + * there might be a loss of data as all data might not be written. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * Cancelling a close will still leave the stream closed, but there some streams + * can use a faster close that doesn't block to e.g. check errors. On + * cancellation (as with any error) there is no guarantee that all written + * data will reach the target. + * + * Returns: %TRUE on success, %FALSE on failure + **/ +gboolean +g_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + gboolean res; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + + if (stream->priv->closed) + return TRUE; + + if (!g_output_stream_set_pending (stream, error)) + return FALSE; + + res = g_output_stream_internal_close (stream, cancellable, error); + + g_output_stream_clear_pending (stream); + + return res; +} + +static void +async_ready_write_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source_object); + GOutputStreamClass *class; + GTask *task = user_data; + gssize nwrote; + GError *error = NULL; + + g_output_stream_clear_pending (stream); + + if (g_async_result_legacy_propagate_error (res, &error)) + nwrote = -1; + else + { + class = G_OUTPUT_STREAM_GET_CLASS (stream); + nwrote = class->write_finish (stream, res, &error); + } + + if (nwrote >= 0) + g_task_return_int (task, nwrote); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +/** + * g_output_stream_write_async: + * @stream: A #GOutputStream. + * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. + * @count: the number of bytes to write + * @io_priority: the io priority of the request. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request an asynchronous write of @count bytes from @buffer into + * the stream. When the operation is finished @callback will be called. + * You can then call g_output_stream_write_finish() to get the result of the + * operation. + * + * During an async request no other sync and async calls are allowed, + * and will result in %G_IO_ERROR_PENDING errors. + * + * A value of @count larger than %G_MAXSSIZE will cause a + * %G_IO_ERROR_INVALID_ARGUMENT error. + * + * On success, the number of bytes written will be passed to the + * @callback. It is not an error if this is not the same as the + * requested size, as it can happen e.g. on a partial I/O error, + * but generally we try to write as many bytes as requested. + * + * You are guaranteed that this method will never fail with + * %G_IO_ERROR_WOULD_BLOCK - if @stream can't accept more data, the + * method will just wait until this changes. + * + * Any outstanding I/O request with higher priority (lower numerical + * value) will be executed before an outstanding request with lower + * priority. Default priority is %G_PRIORITY_DEFAULT. + * + * The asynchronous methods have a default fallback that uses threads + * to implement asynchronicity, so they are optional for inheriting + * classes. However, if you override one you must override all. + * + * For the synchronous, blocking version of this function, see + * g_output_stream_write(). + * + * Note that no copy of @buffer will be made, so it must stay valid + * until @callback is called. See g_output_stream_write_bytes_async() + * for a #GBytes version that will automatically hold a reference to + * the contents (without copying) for the duration of the call. + */ +void +g_output_stream_write_async (GOutputStream *stream, + const void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GOutputStreamClass *class; + GError *error = NULL; + GTask *task; + + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + g_return_if_fail (buffer != NULL); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_output_stream_write_async); + g_task_set_priority (task, io_priority); + + if (count == 0) + { + g_task_return_int (task, 0); + g_object_unref (task); + return; + } + + if (((gssize) count) < 0) + { + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), + G_STRFUNC); + g_object_unref (task); + return; + } + + if (!g_output_stream_set_pending (stream, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + class->write_async (stream, buffer, count, io_priority, cancellable, + async_ready_write_callback_wrapper, task); +} + +/** + * g_output_stream_write_finish: + * @stream: a #GOutputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes a stream write operation. + * + * Returns: a #gssize containing the number of bytes written to the stream. + **/ +gssize +g_output_stream_write_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_write_async), FALSE); + + /* @result is always the GTask created by g_output_stream_write_async(); + * we called class->write_finish() from async_ready_write_callback_wrapper. + */ + return g_task_propagate_int (G_TASK (result), error); +} + +typedef struct +{ + const guint8 *buffer; + gsize to_write; + gsize bytes_written; +} AsyncWriteAll; + +static void +free_async_write_all (gpointer data) +{ + g_slice_free (AsyncWriteAll, data); +} + +static void +write_all_callback (GObject *stream, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + AsyncWriteAll *data = g_task_get_task_data (task); + + if (result) + { + GError *error = NULL; + gssize nwritten; + + nwritten = g_output_stream_write_finish (G_OUTPUT_STREAM (stream), result, &error); + + if (nwritten == -1) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_assert_cmpint (nwritten, <=, data->to_write); + g_warn_if_fail (nwritten > 0); + + data->to_write -= nwritten; + data->bytes_written += nwritten; + } + + if (data->to_write == 0) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + } + else + g_output_stream_write_async (G_OUTPUT_STREAM (stream), + data->buffer + data->bytes_written, + data->to_write, + g_task_get_priority (task), + g_task_get_cancellable (task), + write_all_callback, task); +} + +static void +write_all_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GOutputStream *stream = source_object; + AsyncWriteAll *data = task_data; + GError *error = NULL; + + if (g_output_stream_write_all (stream, data->buffer, data->to_write, &data->bytes_written, + g_task_get_cancellable (task), &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +/** + * g_output_stream_write_all_async: + * @stream: A #GOutputStream + * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write + * @count: the number of bytes to write + * @io_priority: the io priority of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request an asynchronous write of @count bytes from @buffer into + * the stream. When the operation is finished @callback will be called. + * You can then call g_output_stream_write_all_finish() to get the result of the + * operation. + * + * This is the asynchronous version of g_output_stream_write_all(). + * + * Call g_output_stream_write_all_finish() to collect the result. + * + * Any outstanding I/O request with higher priority (lower numerical + * value) will be executed before an outstanding request with lower + * priority. Default priority is %G_PRIORITY_DEFAULT. + * + * Note that no copy of @buffer will be made, so it must stay valid + * until @callback is called. + * + * Since: 2.44 + */ +void +g_output_stream_write_all_async (GOutputStream *stream, + const void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AsyncWriteAll *data; + GTask *task; + + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + g_return_if_fail (buffer != NULL || count == 0); + + task = g_task_new (stream, cancellable, callback, user_data); + data = g_slice_new0 (AsyncWriteAll); + data->buffer = buffer; + data->to_write = count; + + g_task_set_source_tag (task, g_output_stream_write_all_async); + g_task_set_task_data (task, data, free_async_write_all); + g_task_set_priority (task, io_priority); + + /* If async writes are going to be handled via the threadpool anyway + * then we may as well do it with a single dispatch instead of + * bouncing in and out. + */ + if (g_output_stream_async_write_is_via_threads (stream)) + { + g_task_run_in_thread (task, write_all_async_thread); + g_object_unref (task); + } + else + write_all_callback (G_OBJECT (stream), NULL, task); +} + +/** + * g_output_stream_write_all_finish: + * @stream: a #GOutputStream + * @result: a #GAsyncResult + * @bytes_written: (out) (optional): location to store the number of bytes that was written to the stream + * @error: a #GError location to store the error occurring, or %NULL to ignore. + * + * Finishes an asynchronous stream write operation started with + * g_output_stream_write_all_async(). + * + * As a special exception to the normal conventions for functions that + * use #GError, if this function returns %FALSE (and sets @error) then + * @bytes_written will be set to the number of bytes that were + * successfully written before the error was encountered. This + * functionality is only available from C. If you need it from another + * language then you must write your own loop around + * g_output_stream_write_async(). + * + * Returns: %TRUE on success, %FALSE if there was an error + * + * Since: 2.44 + **/ +gboolean +g_output_stream_write_all_finish (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error) +{ + GTask *task; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + task = G_TASK (result); + + if (bytes_written) + { + AsyncWriteAll *data = (AsyncWriteAll *)g_task_get_task_data (task); + + *bytes_written = data->bytes_written; + } + + return g_task_propagate_boolean (task, error); +} + +/** + * g_output_stream_writev_async: + * @stream: A #GOutputStream. + * @vectors: (array length=n_vectors): the buffer containing the #GOutputVectors to write. + * @n_vectors: the number of vectors to write + * @io_priority: the I/O priority of the request. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request an asynchronous write of the bytes contained in @n_vectors @vectors into + * the stream. When the operation is finished @callback will be called. + * You can then call g_output_stream_writev_finish() to get the result of the + * operation. + * + * During an async request no other sync and async calls are allowed, + * and will result in %G_IO_ERROR_PENDING errors. + * + * On success, the number of bytes written will be passed to the + * @callback. It is not an error if this is not the same as the + * requested size, as it can happen e.g. on a partial I/O error, + * but generally we try to write as many bytes as requested. + * + * You are guaranteed that this method will never fail with + * %G_IO_ERROR_WOULD_BLOCK — if @stream can't accept more data, the + * method will just wait until this changes. + * + * Any outstanding I/O request with higher priority (lower numerical + * value) will be executed before an outstanding request with lower + * priority. Default priority is %G_PRIORITY_DEFAULT. + * + * The asynchronous methods have a default fallback that uses threads + * to implement asynchronicity, so they are optional for inheriting + * classes. However, if you override one you must override all. + * + * For the synchronous, blocking version of this function, see + * g_output_stream_writev(). + * + * Note that no copy of @vectors will be made, so it must stay valid + * until @callback is called. + * + * Since: 2.60 + */ +void +g_output_stream_writev_async (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GOutputStreamClass *class; + + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + g_return_if_fail (vectors != NULL || n_vectors == 0); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + g_return_if_fail (class->writev_async != NULL); + + class->writev_async (stream, vectors, n_vectors, io_priority, cancellable, + callback, user_data); +} + +/** + * g_output_stream_writev_finish: + * @stream: a #GOutputStream. + * @result: a #GAsyncResult. + * @bytes_written: (out) (optional): location to store the number of bytes that were written to the stream + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes a stream writev operation. + * + * Returns: %TRUE on success, %FALSE if there was an error + * + * Since: 2.60 + */ +gboolean +g_output_stream_writev_finish (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error) +{ + GOutputStreamClass *class; + gboolean res; + gsize _bytes_written = 0; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + g_return_val_if_fail (class->writev_finish != NULL, FALSE); + + res = class->writev_finish (stream, result, &_bytes_written, error); + + g_warn_if_fail (res || _bytes_written == 0); + g_warn_if_fail (res || (error == NULL || *error != NULL)); + + if (bytes_written) + *bytes_written = _bytes_written; + + return res; +} + +typedef struct +{ + GOutputVector *vectors; + gsize n_vectors; /* (unowned) */ + gsize bytes_written; +} AsyncWritevAll; + +static void +free_async_writev_all (gpointer data) +{ + g_slice_free (AsyncWritevAll, data); +} + +static void +writev_all_callback (GObject *stream, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + AsyncWritevAll *data = g_task_get_task_data (task); + gint priority = g_task_get_priority (task); + GCancellable *cancellable = g_task_get_cancellable (task); + + if (result) + { + GError *error = NULL; + gboolean res; + gsize n_written = 0; + + res = g_output_stream_writev_finish (G_OUTPUT_STREAM (stream), result, &n_written, &error); + + if (!res) + { + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + return; + } + + g_warn_if_fail (n_written > 0); + data->bytes_written += n_written; + + /* skip vectors that have been written in full */ + while (data->n_vectors > 0 && n_written >= data->vectors[0].size) + { + n_written -= data->vectors[0].size; + ++data->vectors; + --data->n_vectors; + } + /* skip partially written vector data */ + if (n_written > 0 && data->n_vectors > 0) + { + data->vectors[0].size -= n_written; + data->vectors[0].buffer = ((guint8 *) data->vectors[0].buffer) + n_written; + } + } + + if (data->n_vectors == 0) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + } + else + g_output_stream_writev_async (G_OUTPUT_STREAM (stream), + data->vectors, + data->n_vectors, + priority, + cancellable, + writev_all_callback, g_steal_pointer (&task)); +} + +static void +writev_all_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source_object); + AsyncWritevAll *data = task_data; + GError *error = NULL; + + if (g_output_stream_writev_all (stream, data->vectors, data->n_vectors, &data->bytes_written, + g_task_get_cancellable (task), &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, g_steal_pointer (&error)); +} + +/** + * g_output_stream_writev_all_async: + * @stream: A #GOutputStream + * @vectors: (array length=n_vectors): the buffer containing the #GOutputVectors to write. + * @n_vectors: the number of vectors to write + * @io_priority: the I/O priority of the request + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Request an asynchronous write of the bytes contained in the @n_vectors @vectors into + * the stream. When the operation is finished @callback will be called. + * You can then call g_output_stream_writev_all_finish() to get the result of the + * operation. + * + * This is the asynchronous version of g_output_stream_writev_all(). + * + * Call g_output_stream_writev_all_finish() to collect the result. + * + * Any outstanding I/O request with higher priority (lower numerical + * value) will be executed before an outstanding request with lower + * priority. Default priority is %G_PRIORITY_DEFAULT. + * + * Note that no copy of @vectors will be made, so it must stay valid + * until @callback is called. The content of the individual elements + * of @vectors might be changed by this function. + * + * Since: 2.60 + */ +void +g_output_stream_writev_all_async (GOutputStream *stream, + GOutputVector *vectors, + gsize n_vectors, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AsyncWritevAll *data; + GTask *task; + gsize i, to_be_written = 0; + + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + g_return_if_fail (vectors != NULL || n_vectors == 0); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + task = g_task_new (stream, cancellable, callback, user_data); + data = g_slice_new0 (AsyncWritevAll); + data->vectors = vectors; + data->n_vectors = n_vectors; + + g_task_set_source_tag (task, g_output_stream_writev_all_async); + g_task_set_task_data (task, data, free_async_writev_all); + g_task_set_priority (task, io_priority); + + /* We can't write more than G_MAXSIZE bytes overall, otherwise we + * would overflow the bytes_written counter */ + for (i = 0; i < n_vectors; i++) + { + if (to_be_written > G_MAXSIZE - vectors[i].size) + { + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Sum of vectors passed to %s too large"), + G_STRFUNC); + g_object_unref (task); + return; + } + to_be_written += vectors[i].size; + } + + /* If async writes are going to be handled via the threadpool anyway + * then we may as well do it with a single dispatch instead of + * bouncing in and out. + */ + if (g_output_stream_async_writev_is_via_threads (stream)) + { + g_task_run_in_thread (task, writev_all_async_thread); + g_object_unref (task); + } + else + writev_all_callback (G_OBJECT (stream), NULL, g_steal_pointer (&task)); +} + +/** + * g_output_stream_writev_all_finish: + * @stream: a #GOutputStream + * @result: a #GAsyncResult + * @bytes_written: (out) (optional): location to store the number of bytes that were written to the stream + * @error: a #GError location to store the error occurring, or %NULL to ignore. + * + * Finishes an asynchronous stream write operation started with + * g_output_stream_writev_all_async(). + * + * As a special exception to the normal conventions for functions that + * use #GError, if this function returns %FALSE (and sets @error) then + * @bytes_written will be set to the number of bytes that were + * successfully written before the error was encountered. This + * functionality is only available from C. If you need it from another + * language then you must write your own loop around + * g_output_stream_writev_async(). + * + * Returns: %TRUE on success, %FALSE if there was an error + * + * Since: 2.60 + */ +gboolean +g_output_stream_writev_all_finish (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error) +{ + GTask *task; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + task = G_TASK (result); + + if (bytes_written) + { + AsyncWritevAll *data = (AsyncWritevAll *)g_task_get_task_data (task); + + *bytes_written = data->bytes_written; + } + + return g_task_propagate_boolean (task, error); +} + +static void +write_bytes_callback (GObject *stream, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + GError *error = NULL; + gssize nwrote; + + nwrote = g_output_stream_write_finish (G_OUTPUT_STREAM (stream), + result, &error); + if (nwrote == -1) + g_task_return_error (task, error); + else + g_task_return_int (task, nwrote); + g_object_unref (task); +} + +/** + * g_output_stream_write_bytes_async: + * @stream: A #GOutputStream. + * @bytes: The bytes to write + * @io_priority: the io priority of the request. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * This function is similar to g_output_stream_write_async(), but + * takes a #GBytes as input. Due to the refcounted nature of #GBytes, + * this allows the stream to avoid taking a copy of the data. + * + * However, note that this function may still perform partial writes, + * just like g_output_stream_write_async(). If that occurs, to continue + * writing, you will need to create a new #GBytes containing just the + * remaining bytes, using g_bytes_new_from_bytes(). Passing the same + * #GBytes instance multiple times potentially can result in duplicated + * data in the output stream. + * + * For the synchronous, blocking version of this function, see + * g_output_stream_write_bytes(). + **/ +void +g_output_stream_write_bytes_async (GOutputStream *stream, + GBytes *bytes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + gsize size; + gconstpointer data; + + data = g_bytes_get_data (bytes, &size); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_output_stream_write_bytes_async); + g_task_set_task_data (task, g_bytes_ref (bytes), + (GDestroyNotify) g_bytes_unref); + + g_output_stream_write_async (stream, + data, size, + io_priority, + cancellable, + write_bytes_callback, + task); +} + +/** + * g_output_stream_write_bytes_finish: + * @stream: a #GOutputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes a stream write-from-#GBytes operation. + * + * Returns: a #gssize containing the number of bytes written to the stream. + **/ +gssize +g_output_stream_write_bytes_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1); + g_return_val_if_fail (g_task_is_valid (result, stream), -1); + + return g_task_propagate_int (G_TASK (result), error); +} + +static void +async_ready_splice_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer _data) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source_object); + GOutputStreamClass *class; + GTask *task = _data; + gssize nspliced; + GError *error = NULL; + + g_output_stream_clear_pending (stream); + + if (g_async_result_legacy_propagate_error (res, &error)) + nspliced = -1; + else + { + class = G_OUTPUT_STREAM_GET_CLASS (stream); + nspliced = class->splice_finish (stream, res, &error); + } + + if (nspliced >= 0) + g_task_return_int (task, nspliced); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +/** + * g_output_stream_splice_async: + * @stream: a #GOutputStream. + * @source: a #GInputStream. + * @flags: a set of #GOutputStreamSpliceFlags. + * @io_priority: the io priority of the request. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback. + * @user_data: (closure): user data passed to @callback. + * + * Splices a stream asynchronously. + * When the operation is finished @callback will be called. + * You can then call g_output_stream_splice_finish() to get the + * result of the operation. + * + * For the synchronous, blocking version of this function, see + * g_output_stream_splice(). + **/ +void +g_output_stream_splice_async (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GOutputStreamClass *class; + GTask *task; + GError *error = NULL; + + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + g_return_if_fail (G_IS_INPUT_STREAM (source)); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_output_stream_splice_async); + g_task_set_priority (task, io_priority); + g_task_set_task_data (task, g_object_ref (source), g_object_unref); + + if (g_input_stream_is_closed (source)) + { + g_task_return_new_error (task, + G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Source stream is already closed")); + g_object_unref (task); + return; + } + + if (!g_output_stream_set_pending (stream, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + class->splice_async (stream, source, flags, io_priority, cancellable, + async_ready_splice_callback_wrapper, task); +} + +/** + * g_output_stream_splice_finish: + * @stream: a #GOutputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an asynchronous stream splice operation. + * + * Returns: a #gssize of the number of bytes spliced. Note that if the + * number of bytes spliced is greater than %G_MAXSSIZE, then that + * will be returned, and there is no way to determine the actual + * number of bytes spliced. + **/ +gssize +g_output_stream_splice_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_splice_async), FALSE); + + /* @result is always the GTask created by g_output_stream_splice_async(); + * we called class->splice_finish() from async_ready_splice_callback_wrapper. + */ + return g_task_propagate_int (G_TASK (result), error); +} + +static void +async_ready_flush_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source_object); + GOutputStreamClass *class; + GTask *task = user_data; + gboolean flushed; + GError *error = NULL; + + g_output_stream_clear_pending (stream); + + if (g_async_result_legacy_propagate_error (res, &error)) + flushed = FALSE; + else + { + class = G_OUTPUT_STREAM_GET_CLASS (stream); + flushed = class->flush_finish (stream, res, &error); + } + + if (flushed) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +/** + * g_output_stream_flush_async: + * @stream: a #GOutputStream. + * @io_priority: the io priority of the request. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Forces an asynchronous write of all user-space buffered data for + * the given @stream. + * For behaviour details see g_output_stream_flush(). + * + * When the operation is finished @callback will be + * called. You can then call g_output_stream_flush_finish() to get the + * result of the operation. + **/ +void +g_output_stream_flush_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GOutputStreamClass *class; + GTask *task; + GError *error = NULL; + + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_output_stream_flush_async); + g_task_set_priority (task, io_priority); + + if (!g_output_stream_set_pending (stream, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + if (class->flush_async == NULL) + { + g_output_stream_clear_pending (stream); + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + class->flush_async (stream, io_priority, cancellable, + async_ready_flush_callback_wrapper, task); +} + +/** + * g_output_stream_flush_finish: + * @stream: a #GOutputStream. + * @result: a GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes flushing an output stream. + * + * Returns: %TRUE if flush operation succeeded, %FALSE otherwise. + **/ +gboolean +g_output_stream_flush_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_flush_async), FALSE); + + /* @result is always the GTask created by g_output_stream_flush_async(); + * we called class->flush_finish() from async_ready_flush_callback_wrapper. + */ + return g_task_propagate_boolean (G_TASK (result), error); +} + + +static void +async_ready_close_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source_object); + GOutputStreamClass *class; + GTask *task = user_data; + GError *error = g_task_get_task_data (task); + + stream->priv->closing = FALSE; + stream->priv->closed = TRUE; + + if (!error && !g_async_result_legacy_propagate_error (res, &error)) + { + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + class->close_finish (stream, res, + error ? NULL : &error); + } + + if (error != NULL) + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +async_ready_close_flushed_callback_wrapper (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source_object); + GOutputStreamClass *class; + GTask *task = user_data; + GError *error = NULL; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + if (!g_async_result_legacy_propagate_error (res, &error)) + { + class->flush_finish (stream, res, &error); + } + + /* propagate the possible error */ + if (error) + g_task_set_task_data (task, error, NULL); + + /* we still close, even if there was a flush error */ + class->close_async (stream, + g_task_get_priority (task), + g_task_get_cancellable (task), + async_ready_close_callback_wrapper, task); +} + +static void +real_close_async_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source_object); + GTask *task = user_data; + GError *error = NULL; + gboolean ret; + + g_output_stream_clear_pending (stream); + + ret = g_output_stream_internal_close_finish (stream, res, &error); + + if (error != NULL) + g_task_return_error (task, error); + else + g_task_return_boolean (task, ret); + + g_object_unref (task); +} + +/** + * g_output_stream_close_async: + * @stream: A #GOutputStream. + * @io_priority: the io priority of the request. + * @cancellable: (nullable): optional cancellable object + * @callback: (scope async): callback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Requests an asynchronous close of the stream, releasing resources + * related to it. When the operation is finished @callback will be + * called. You can then call g_output_stream_close_finish() to get + * the result of the operation. + * + * For behaviour details see g_output_stream_close(). + * + * The asynchronous methods have a default fallback that uses threads + * to implement asynchronicity, so they are optional for inheriting + * classes. However, if you override one you must override all. + **/ +void +g_output_stream_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + GError *error = NULL; + + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_output_stream_close_async); + g_task_set_priority (task, io_priority); + + if (!g_output_stream_set_pending (stream, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_output_stream_internal_close_async (stream, io_priority, cancellable, + real_close_async_cb, task); +} + +/* Must always be called inside + * g_output_stream_set_pending()/g_output_stream_clear_pending(). + */ +void +g_output_stream_internal_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GOutputStreamClass *class; + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_output_stream_internal_close_async); + g_task_set_priority (task, io_priority); + + if (stream->priv->closed) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + stream->priv->closing = TRUE; + + /* Call close_async directly if there is no need to flush, or if the flush + can be done sync (in the output stream async close thread) */ + if (class->flush_async == NULL || + (class->flush_async == g_output_stream_real_flush_async && + (class->flush == NULL || class->close_async == g_output_stream_real_close_async))) + { + class->close_async (stream, io_priority, cancellable, + async_ready_close_callback_wrapper, task); + } + else + { + /* First do an async flush, then do the async close in the callback + wrapper (see async_ready_close_flushed_callback_wrapper) */ + class->flush_async (stream, io_priority, cancellable, + async_ready_close_flushed_callback_wrapper, task); + } +} + +static gboolean +g_output_stream_internal_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_internal_close_async), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +/** + * g_output_stream_close_finish: + * @stream: a #GOutputStream. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Closes an output stream. + * + * Returns: %TRUE if stream was successfully closed, %FALSE otherwise. + **/ +gboolean +g_output_stream_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_close_async), FALSE); + + /* @result is always the GTask created by g_output_stream_close_async(); + * we called class->close_finish() from async_ready_close_callback_wrapper. + */ + return g_task_propagate_boolean (G_TASK (result), error); +} + +/** + * g_output_stream_is_closed: + * @stream: a #GOutputStream. + * + * Checks if an output stream has already been closed. + * + * Returns: %TRUE if @stream is closed. %FALSE otherwise. + **/ +gboolean +g_output_stream_is_closed (GOutputStream *stream) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE); + + return stream->priv->closed; +} + +/** + * g_output_stream_is_closing: + * @stream: a #GOutputStream. + * + * Checks if an output stream is being closed. This can be + * used inside e.g. a flush implementation to see if the + * flush (or other i/o operation) is called from within + * the closing operation. + * + * Returns: %TRUE if @stream is being closed. %FALSE otherwise. + * + * Since: 2.24 + **/ +gboolean +g_output_stream_is_closing (GOutputStream *stream) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE); + + return stream->priv->closing; +} + +/** + * g_output_stream_has_pending: + * @stream: a #GOutputStream. + * + * Checks if an output stream has pending actions. + * + * Returns: %TRUE if @stream has pending actions. + **/ +gboolean +g_output_stream_has_pending (GOutputStream *stream) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + + return stream->priv->pending; +} + +/** + * g_output_stream_set_pending: + * @stream: a #GOutputStream. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Sets @stream to have actions pending. If the pending flag is + * already set or @stream is closed, it will return %FALSE and set + * @error. + * + * Returns: %TRUE if pending was previously unset and is now set. + **/ +gboolean +g_output_stream_set_pending (GOutputStream *stream, + GError **error) +{ + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + + if (stream->priv->closed) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Stream is already closed")); + return FALSE; + } + + if (stream->priv->pending) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING, + /* Translators: This is an error you get if there is + * already an operation running against this stream when + * you try to start one */ + _("Stream has outstanding operation")); + return FALSE; + } + + stream->priv->pending = TRUE; + return TRUE; +} + +/** + * g_output_stream_clear_pending: + * @stream: output stream + * + * Clears the pending flag on @stream. + **/ +void +g_output_stream_clear_pending (GOutputStream *stream) +{ + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + + stream->priv->pending = FALSE; +} + +/*< internal > + * g_output_stream_async_write_is_via_threads: + * @stream: a #GOutputStream. + * + * Checks if an output stream's write_async function uses threads. + * + * Returns: %TRUE if @stream's write_async function uses threads. + **/ +gboolean +g_output_stream_async_write_is_via_threads (GOutputStream *stream) +{ + GOutputStreamClass *class; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + return (class->write_async == g_output_stream_real_write_async && + !(G_IS_POLLABLE_OUTPUT_STREAM (stream) && + g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (stream)))); +} + +/*< internal > + * g_output_stream_async_writev_is_via_threads: + * @stream: a #GOutputStream. + * + * Checks if an output stream's writev_async function uses threads. + * + * Returns: %TRUE if @stream's writev_async function uses threads. + **/ +gboolean +g_output_stream_async_writev_is_via_threads (GOutputStream *stream) +{ + GOutputStreamClass *class; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + return (class->writev_async == g_output_stream_real_writev_async && + !(G_IS_POLLABLE_OUTPUT_STREAM (stream) && + g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (stream)))); +} + +/*< internal > + * g_output_stream_async_close_is_via_threads: + * @stream: output stream + * + * Checks if an output stream's close_async function uses threads. + * + * Returns: %TRUE if @stream's close_async function uses threads. + **/ +gboolean +g_output_stream_async_close_is_via_threads (GOutputStream *stream) +{ + GOutputStreamClass *class; + + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + return class->close_async == g_output_stream_real_close_async; +} + +/******************************************** + * Default implementation of sync ops * + ********************************************/ +static gboolean +g_output_stream_real_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + GOutputStreamClass *class; + gsize _bytes_written = 0; + gsize i; + GError *err = NULL; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + if (bytes_written) + *bytes_written = 0; + + for (i = 0; i < n_vectors; i++) + { + gssize res = 0; + + /* Would we overflow here? In that case simply return and let the caller + * handle this like a short write */ + if (_bytes_written > G_MAXSIZE - vectors[i].size) + break; + + res = class->write_fn (stream, vectors[i].buffer, vectors[i].size, cancellable, &err); + + if (res == -1) + { + /* If we already wrote something we handle this like a short write + * and assume that on the next call the same error happens again, or + * everything finishes successfully without data loss then + */ + if (_bytes_written > 0) + { + if (bytes_written) + *bytes_written = _bytes_written; + + g_clear_error (&err); + return TRUE; + } + + g_propagate_error (error, err); + return FALSE; + } + + _bytes_written += res; + /* if we had a short write break the loop here */ + if ((gsize) res < vectors[i].size) + break; + } + + if (bytes_written) + *bytes_written = _bytes_written; + + return TRUE; +} + +/******************************************** + * Default implementation of async ops * + ********************************************/ + +typedef struct { + const void *buffer; + gsize count_requested; + gssize count_written; +} WriteData; + +static void +free_write_data (WriteData *op) +{ + g_slice_free (WriteData, op); +} + +static void +write_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GOutputStream *stream = source_object; + WriteData *op = task_data; + GOutputStreamClass *class; + GError *error = NULL; + gssize count_written; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + count_written = class->write_fn (stream, op->buffer, op->count_requested, + cancellable, &error); + if (count_written == -1) + g_task_return_error (task, error); + else + g_task_return_int (task, count_written); +} + +static void write_async_pollable (GPollableOutputStream *stream, + GTask *task); + +static gboolean +write_async_pollable_ready (GPollableOutputStream *stream, + gpointer user_data) +{ + GTask *task = user_data; + + write_async_pollable (stream, task); + return FALSE; +} + +static void +write_async_pollable (GPollableOutputStream *stream, + GTask *task) +{ + GError *error = NULL; + WriteData *op = g_task_get_task_data (task); + gssize count_written; + + if (g_task_return_error_if_cancelled (task)) + return; + + count_written = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)-> + write_nonblocking (stream, op->buffer, op->count_requested, &error); + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) + { + GSource *source; + + g_error_free (error); + + source = g_pollable_output_stream_create_source (stream, + g_task_get_cancellable (task)); + g_task_attach_source (task, source, + (GSourceFunc) write_async_pollable_ready); + g_source_unref (source); + return; + } + + if (count_written == -1) + g_task_return_error (task, error); + else + g_task_return_int (task, count_written); +} + +static void +g_output_stream_real_write_async (GOutputStream *stream, + const void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + WriteData *op; + + op = g_slice_new0 (WriteData); + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_check_cancellable (task, FALSE); + g_task_set_task_data (task, op, (GDestroyNotify) free_write_data); + op->buffer = buffer; + op->count_requested = count; + + if (!g_output_stream_async_write_is_via_threads (stream)) + write_async_pollable (G_POLLABLE_OUTPUT_STREAM (stream), task); + else + g_task_run_in_thread (task, write_async_thread); + g_object_unref (task); +} + +static gssize +g_output_stream_real_write_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_int (G_TASK (result), error); +} + +typedef struct { + const GOutputVector *vectors; + gsize n_vectors; /* (unowned) */ + gsize bytes_written; +} WritevData; + +static void +free_writev_data (WritevData *op) +{ + g_slice_free (WritevData, op); +} + +static void +writev_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GOutputStream *stream = source_object; + WritevData *op = task_data; + GOutputStreamClass *class; + GError *error = NULL; + gboolean res; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + res = class->writev_fn (stream, op->vectors, op->n_vectors, + &op->bytes_written, cancellable, &error); + + g_warn_if_fail (res || op->bytes_written == 0); + g_warn_if_fail (res || error != NULL); + + if (!res) + g_task_return_error (task, g_steal_pointer (&error)); + else + g_task_return_boolean (task, TRUE); +} + +static void writev_async_pollable (GPollableOutputStream *stream, + GTask *task); + +static gboolean +writev_async_pollable_ready (GPollableOutputStream *stream, + gpointer user_data) +{ + GTask *task = user_data; + + writev_async_pollable (stream, task); + return G_SOURCE_REMOVE; +} + +static void +writev_async_pollable (GPollableOutputStream *stream, + GTask *task) +{ + GError *error = NULL; + WritevData *op = g_task_get_task_data (task); + GPollableReturn res; + gsize bytes_written = 0; + + if (g_task_return_error_if_cancelled (task)) + return; + + res = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)-> + writev_nonblocking (stream, op->vectors, op->n_vectors, &bytes_written, &error); + + switch (res) + { + case G_POLLABLE_RETURN_WOULD_BLOCK: + { + GSource *source; + + g_warn_if_fail (error == NULL); + g_warn_if_fail (bytes_written == 0); + + source = g_pollable_output_stream_create_source (stream, + g_task_get_cancellable (task)); + g_task_attach_source (task, source, + (GSourceFunc) writev_async_pollable_ready); + g_source_unref (source); + } + break; + case G_POLLABLE_RETURN_OK: + g_warn_if_fail (error == NULL); + op->bytes_written = bytes_written; + g_task_return_boolean (task, TRUE); + break; + case G_POLLABLE_RETURN_FAILED: + g_warn_if_fail (bytes_written == 0); + g_warn_if_fail (error != NULL); + g_task_return_error (task, g_steal_pointer (&error)); + break; + default: + g_assert_not_reached (); + } +} + +static void +g_output_stream_real_writev_async (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + WritevData *op; + GError *error = NULL; + + op = g_slice_new0 (WritevData); + task = g_task_new (stream, cancellable, callback, user_data); + op->vectors = vectors; + op->n_vectors = n_vectors; + + g_task_set_check_cancellable (task, FALSE); + g_task_set_source_tag (task, g_output_stream_writev_async); + g_task_set_priority (task, io_priority); + g_task_set_task_data (task, op, (GDestroyNotify) free_writev_data); + + if (n_vectors == 0) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + if (!g_output_stream_set_pending (stream, &error)) + { + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + return; + } + + if (!g_output_stream_async_writev_is_via_threads (stream)) + writev_async_pollable (G_POLLABLE_OUTPUT_STREAM (stream), task); + else + g_task_run_in_thread (task, writev_async_thread); + + g_object_unref (task); +} + +static gboolean +g_output_stream_real_writev_finish (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error) +{ + GTask *task; + + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_writev_async), FALSE); + + g_output_stream_clear_pending (stream); + + task = G_TASK (result); + + if (bytes_written) + { + WritevData *op = g_task_get_task_data (task); + + *bytes_written = op->bytes_written; + } + + return g_task_propagate_boolean (task, error); +} + +typedef struct { + GInputStream *source; + GOutputStreamSpliceFlags flags; + guint istream_closed : 1; + guint ostream_closed : 1; + gssize n_read; + gssize n_written; + gsize bytes_copied; + GError *error; + guint8 *buffer; +} SpliceData; + +static void +free_splice_data (SpliceData *op) +{ + g_clear_pointer (&op->buffer, g_free); + g_object_unref (op->source); + g_clear_error (&op->error); + g_free (op); +} + +static void +real_splice_async_complete_cb (GTask *task) +{ + SpliceData *op = g_task_get_task_data (task); + + if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE && + !op->istream_closed) + return; + + if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET && + !op->ostream_closed) + return; + + if (op->error != NULL) + { + g_task_return_error (task, op->error); + op->error = NULL; + } + else + { + g_task_return_int (task, op->bytes_copied); + } + + g_object_unref (task); +} + +static void +real_splice_async_close_input_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + SpliceData *op = g_task_get_task_data (task); + + g_input_stream_close_finish (G_INPUT_STREAM (source), res, NULL); + op->istream_closed = TRUE; + + real_splice_async_complete_cb (task); +} + +static void +real_splice_async_close_output_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + SpliceData *op = g_task_get_task_data (task); + GError **error = (op->error == NULL) ? &op->error : NULL; + + g_output_stream_internal_close_finish (G_OUTPUT_STREAM (source), res, error); + op->ostream_closed = TRUE; + + real_splice_async_complete_cb (task); +} + +static void +real_splice_async_complete (GTask *task) +{ + SpliceData *op = g_task_get_task_data (task); + gboolean done = TRUE; + + if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE) + { + done = FALSE; + g_input_stream_close_async (op->source, g_task_get_priority (task), + g_task_get_cancellable (task), + real_splice_async_close_input_cb, task); + } + + if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET) + { + done = FALSE; + g_output_stream_internal_close_async (g_task_get_source_object (task), + g_task_get_priority (task), + g_task_get_cancellable (task), + real_splice_async_close_output_cb, + task); + } + + if (done) + real_splice_async_complete_cb (task); +} + +static void real_splice_async_read_cb (GObject *source, + GAsyncResult *res, + gpointer user_data); + +static void +real_splice_async_write_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GOutputStreamClass *class; + GTask *task = G_TASK (user_data); + SpliceData *op = g_task_get_task_data (task); + gssize ret; + + class = G_OUTPUT_STREAM_GET_CLASS (g_task_get_source_object (task)); + + ret = class->write_finish (G_OUTPUT_STREAM (source), res, &op->error); + + if (ret == -1) + { + real_splice_async_complete (task); + return; + } + + op->n_written += ret; + op->bytes_copied += ret; + if (op->bytes_copied > G_MAXSSIZE) + op->bytes_copied = G_MAXSSIZE; + + if (op->n_written < op->n_read) + { + class->write_async (g_task_get_source_object (task), + op->buffer + op->n_written, + op->n_read - op->n_written, + g_task_get_priority (task), + g_task_get_cancellable (task), + real_splice_async_write_cb, task); + return; + } + + g_input_stream_read_async (op->source, op->buffer, 8192, + g_task_get_priority (task), + g_task_get_cancellable (task), + real_splice_async_read_cb, task); +} + +static void +real_splice_async_read_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GOutputStreamClass *class; + GTask *task = G_TASK (user_data); + SpliceData *op = g_task_get_task_data (task); + gssize ret; + + class = G_OUTPUT_STREAM_GET_CLASS (g_task_get_source_object (task)); + + ret = g_input_stream_read_finish (op->source, res, &op->error); + if (ret == -1 || ret == 0) + { + real_splice_async_complete (task); + return; + } + + op->n_read = ret; + op->n_written = 0; + + class->write_async (g_task_get_source_object (task), op->buffer, + op->n_read, g_task_get_priority (task), + g_task_get_cancellable (task), + real_splice_async_write_cb, task); +} + +static void +splice_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GOutputStream *stream = source_object; + SpliceData *op = task_data; + GOutputStreamClass *class; + GError *error = NULL; + gssize bytes_copied; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + bytes_copied = class->splice (stream, + op->source, + op->flags, + cancellable, + &error); + if (bytes_copied == -1) + g_task_return_error (task, error); + else + g_task_return_int (task, bytes_copied); +} + +static void +g_output_stream_real_splice_async (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + SpliceData *op; + + op = g_new0 (SpliceData, 1); + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_task_data (task, op, (GDestroyNotify)free_splice_data); + op->flags = flags; + op->source = g_object_ref (source); + + if (g_input_stream_async_read_is_via_threads (source) && + g_output_stream_async_write_is_via_threads (stream)) + { + g_task_run_in_thread (task, splice_async_thread); + g_object_unref (task); + } + else + { + op->buffer = g_malloc (8192); + g_input_stream_read_async (op->source, op->buffer, 8192, + g_task_get_priority (task), + g_task_get_cancellable (task), + real_splice_async_read_cb, task); + } +} + +static gssize +g_output_stream_real_splice_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_int (G_TASK (result), error); +} + + +static void +flush_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GOutputStream *stream = source_object; + GOutputStreamClass *class; + gboolean result; + GError *error = NULL; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + result = TRUE; + if (class->flush) + result = class->flush (stream, cancellable, &error); + + if (result) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +static void +g_output_stream_real_flush_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, flush_async_thread); + g_object_unref (task); +} + +static gboolean +g_output_stream_real_flush_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +close_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GOutputStream *stream = source_object; + GOutputStreamClass *class; + GError *error = NULL; + gboolean result = TRUE; + + class = G_OUTPUT_STREAM_GET_CLASS (stream); + + /* Do a flush here if there is a flush function, and we did not have to do + * an async flush before (see g_output_stream_close_async) + */ + if (class->flush != NULL && + (class->flush_async == NULL || + class->flush_async == g_output_stream_real_flush_async)) + { + result = class->flush (stream, cancellable, &error); + } + + /* Auto handling of cancellation disabled, and ignore + cancellation, since we want to close things anyway, although + possibly in a quick-n-dirty way. At least we never want to leak + open handles */ + + if (class->close_fn) + { + /* Make sure to close, even if the flush failed (see sync close) */ + if (!result) + class->close_fn (stream, cancellable, NULL); + else + result = class->close_fn (stream, cancellable, &error); + } + + if (result) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); +} + +static void +g_output_stream_real_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_priority (task, io_priority); + g_task_run_in_thread (task, close_async_thread); + g_object_unref (task); +} + +static gboolean +g_output_stream_real_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} diff --git a/gio/goutputstream.h b/gio/goutputstream.h new file mode 100644 index 0000000..dc0f492 --- /dev/null +++ b/gio/goutputstream.h @@ -0,0 +1,332 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_OUTPUT_STREAM_H__ +#define __G_OUTPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_OUTPUT_STREAM (g_output_stream_get_type ()) +#define G_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_OUTPUT_STREAM, GOutputStream)) +#define G_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_OUTPUT_STREAM, GOutputStreamClass)) +#define G_IS_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_OUTPUT_STREAM)) +#define G_IS_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_OUTPUT_STREAM)) +#define G_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_OUTPUT_STREAM, GOutputStreamClass)) + +/** + * GOutputStream: + * + * Base class for writing output. + * + * All classes derived from GOutputStream should implement synchronous + * writing, splicing, flushing and closing streams, but may implement + * asynchronous versions. + **/ +typedef struct _GOutputStreamClass GOutputStreamClass; +typedef struct _GOutputStreamPrivate GOutputStreamPrivate; + +struct _GOutputStream +{ + GObject parent_instance; + + /*< private >*/ + GOutputStreamPrivate *priv; +}; + + +struct _GOutputStreamClass +{ + GObjectClass parent_class; + + /* Sync ops: */ + + gssize (* write_fn) (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); + gssize (* splice) (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + GCancellable *cancellable, + GError **error); + gboolean (* flush) (GOutputStream *stream, + GCancellable *cancellable, + GError **error); + gboolean (* close_fn) (GOutputStream *stream, + GCancellable *cancellable, + GError **error); + + /* Async ops: (optional in derived classes) */ + + void (* write_async) (GOutputStream *stream, + const void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gssize (* write_finish) (GOutputStream *stream, + GAsyncResult *result, + GError **error); + void (* splice_async) (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gssize (* splice_finish) (GOutputStream *stream, + GAsyncResult *result, + GError **error); + void (* flush_async) (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* flush_finish) (GOutputStream *stream, + GAsyncResult *result, + GError **error); + void (* close_async) (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* close_finish) (GOutputStream *stream, + GAsyncResult *result, + GError **error); + + gboolean (* writev_fn) (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); + + void (* writev_async) (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + gboolean (* writev_finish) (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); + void (*_g_reserved7) (void); + void (*_g_reserved8) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_output_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gssize g_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_write_all (GOutputStream *stream, + const void *buffer, + gsize count, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_60 +gboolean g_output_stream_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_60 +gboolean g_output_stream_writev_all (GOutputStream *stream, + GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_output_stream_printf (GOutputStream *stream, + gsize *bytes_written, + GCancellable *cancellable, + GError **error, + const gchar *format, + ...) G_GNUC_PRINTF (5, 6); +GLIB_AVAILABLE_IN_2_40 +gboolean g_output_stream_vprintf (GOutputStream *stream, + gsize *bytes_written, + GCancellable *cancellable, + GError **error, + const gchar *format, + va_list args) G_GNUC_PRINTF (5, 0); +GLIB_AVAILABLE_IN_2_34 +gssize g_output_stream_write_bytes (GOutputStream *stream, + GBytes *bytes, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_output_stream_splice (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_flush (GOutputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_output_stream_write_async (GOutputStream *stream, + const void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gssize g_output_stream_write_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_44 +void g_output_stream_write_all_async (GOutputStream *stream, + const void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_44 +gboolean g_output_stream_write_all_finish (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error); + +GLIB_AVAILABLE_IN_2_60 +void g_output_stream_writev_async (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_60 +gboolean g_output_stream_writev_finish (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error); + +GLIB_AVAILABLE_IN_2_60 +void g_output_stream_writev_all_async (GOutputStream *stream, + GOutputVector *vectors, + gsize n_vectors, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_60 +gboolean g_output_stream_writev_all_finish (GOutputStream *stream, + GAsyncResult *result, + gsize *bytes_written, + GError **error); + +GLIB_AVAILABLE_IN_2_34 +void g_output_stream_write_bytes_async (GOutputStream *stream, + GBytes *bytes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_34 +gssize g_output_stream_write_bytes_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_output_stream_splice_async (GOutputStream *stream, + GInputStream *source, + GOutputStreamSpliceFlags flags, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gssize g_output_stream_splice_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_output_stream_flush_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_flush_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_output_stream_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_is_closed (GOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_is_closing (GOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_has_pending (GOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +gboolean g_output_stream_set_pending (GOutputStream *stream, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_output_stream_clear_pending (GOutputStream *stream); + + +G_END_DECLS + +#endif /* __G_OUTPUT_STREAM_H__ */ diff --git a/gio/gpermission.c b/gio/gpermission.c new file mode 100644 index 0000000..966fc6c --- /dev/null +++ b/gio/gpermission.c @@ -0,0 +1,476 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gpermission.h" + +#include "gioerror.h" +#include "gioenums.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "glibintl.h" + + +/** + * SECTION:gpermission + * @title: GPermission + * @short_description: An object representing the permission + * to perform a certain action + * @include: gio/gio.h + * + * A #GPermission represents the status of the caller's permission to + * perform a certain action. + * + * You can query if the action is currently allowed and if it is + * possible to acquire the permission so that the action will be allowed + * in the future. + * + * There is also an API to actually acquire the permission and one to + * release it. + * + * As an example, a #GPermission might represent the ability for the + * user to write to a #GSettings object. This #GPermission object could + * then be used to decide if it is appropriate to show a "Click here to + * unlock" button in a dialog and to provide the mechanism to invoke + * when that button is clicked. + **/ + +/** + * GPermission: + * + * #GPermission is an opaque data structure and can only be accessed + * using the following functions. + **/ + +struct _GPermissionPrivate +{ + gboolean allowed; + gboolean can_acquire; + gboolean can_release; +}; + +enum { + PROP_NONE, + PROP_ALLOWED, + PROP_CAN_ACQUIRE, + PROP_CAN_RELEASE +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GPermission, g_permission, G_TYPE_OBJECT) + +/** + * g_permission_acquire: + * @permission: a #GPermission instance + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a pointer to a %NULL #GError, or %NULL + * + * Attempts to acquire the permission represented by @permission. + * + * The precise method by which this happens depends on the permission + * and the underlying authentication mechanism. A simple example is + * that a dialog may appear asking the user to enter their password. + * + * You should check with g_permission_get_can_acquire() before calling + * this function. + * + * If the permission is acquired then %TRUE is returned. Otherwise, + * %FALSE is returned and @error is set appropriately. + * + * This call is blocking, likely for a very long time (in the case that + * user interaction is required). See g_permission_acquire_async() for + * the non-blocking version. + * + * Returns: %TRUE if the permission was successfully acquired + * + * Since: 2.26 + */ +gboolean +g_permission_acquire (GPermission *permission, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_PERMISSION (permission), FALSE); + return G_PERMISSION_GET_CLASS (permission) + ->acquire (permission, cancellable, error); +} + +/** + * g_permission_acquire_async: + * @permission: a #GPermission instance + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: the #GAsyncReadyCallback to call when done + * @user_data: the user data to pass to @callback + * + * Attempts to acquire the permission represented by @permission. + * + * This is the first half of the asynchronous version of + * g_permission_acquire(). + * + * Since: 2.26 + **/ +void +g_permission_acquire_async (GPermission *permission, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_PERMISSION (permission)); + G_PERMISSION_GET_CLASS (permission) + ->acquire_async (permission, cancellable, callback, user_data); +} + +/** + * g_permission_acquire_finish: + * @permission: a #GPermission instance + * @result: the #GAsyncResult given to the #GAsyncReadyCallback + * @error: a pointer to a %NULL #GError, or %NULL + * + * Collects the result of attempting to acquire the permission + * represented by @permission. + * + * This is the second half of the asynchronous version of + * g_permission_acquire(). + * + * Returns: %TRUE if the permission was successfully acquired + * + * Since: 2.26 + **/ +gboolean +g_permission_acquire_finish (GPermission *permission, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_PERMISSION (permission), FALSE); + return G_PERMISSION_GET_CLASS (permission) + ->acquire_finish (permission, result, error); +} + +/** + * g_permission_release: + * @permission: a #GPermission instance + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a pointer to a %NULL #GError, or %NULL + * + * Attempts to release the permission represented by @permission. + * + * The precise method by which this happens depends on the permission + * and the underlying authentication mechanism. In most cases the + * permission will be dropped immediately without further action. + * + * You should check with g_permission_get_can_release() before calling + * this function. + * + * If the permission is released then %TRUE is returned. Otherwise, + * %FALSE is returned and @error is set appropriately. + * + * This call is blocking, likely for a very long time (in the case that + * user interaction is required). See g_permission_release_async() for + * the non-blocking version. + * + * Returns: %TRUE if the permission was successfully released + * + * Since: 2.26 + **/ +gboolean +g_permission_release (GPermission *permission, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_PERMISSION (permission), FALSE); + return G_PERMISSION_GET_CLASS (permission) + ->release (permission, cancellable, error); +} + +/** + * g_permission_release_async: + * @permission: a #GPermission instance + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: the #GAsyncReadyCallback to call when done + * @user_data: the user data to pass to @callback + * + * Attempts to release the permission represented by @permission. + * + * This is the first half of the asynchronous version of + * g_permission_release(). + * + * Since: 2.26 + **/ +void +g_permission_release_async (GPermission *permission, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_PERMISSION (permission)); + G_PERMISSION_GET_CLASS (permission) + ->release_async (permission, cancellable, callback, user_data); +} + +/** + * g_permission_release_finish: + * @permission: a #GPermission instance + * @result: the #GAsyncResult given to the #GAsyncReadyCallback + * @error: a pointer to a %NULL #GError, or %NULL + * + * Collects the result of attempting to release the permission + * represented by @permission. + * + * This is the second half of the asynchronous version of + * g_permission_release(). + * + * Returns: %TRUE if the permission was successfully released + * + * Since: 2.26 + **/ +gboolean +g_permission_release_finish (GPermission *permission, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_PERMISSION (permission), FALSE); + return G_PERMISSION_GET_CLASS (permission) + ->release_finish (permission, result, error); +} + +/** + * g_permission_get_allowed: + * @permission: a #GPermission instance + * + * Gets the value of the 'allowed' property. This property is %TRUE if + * the caller currently has permission to perform the action that + * @permission represents the permission to perform. + * + * Returns: the value of the 'allowed' property + * + * Since: 2.26 + **/ +gboolean +g_permission_get_allowed (GPermission *permission) +{ + g_return_val_if_fail (G_IS_PERMISSION (permission), FALSE); + return permission->priv->allowed; +} + +/** + * g_permission_get_can_acquire: + * @permission: a #GPermission instance + * + * Gets the value of the 'can-acquire' property. This property is %TRUE + * if it is generally possible to acquire the permission by calling + * g_permission_acquire(). + * + * Returns: the value of the 'can-acquire' property + * + * Since: 2.26 + **/ +gboolean +g_permission_get_can_acquire (GPermission *permission) +{ + g_return_val_if_fail (G_IS_PERMISSION (permission), FALSE); + return permission->priv->can_acquire; +} + +/** + * g_permission_get_can_release: + * @permission: a #GPermission instance + * + * Gets the value of the 'can-release' property. This property is %TRUE + * if it is generally possible to release the permission by calling + * g_permission_release(). + * + * Returns: the value of the 'can-release' property + * + * Since: 2.26 + **/ +gboolean +g_permission_get_can_release (GPermission *permission) +{ + g_return_val_if_fail (G_IS_PERMISSION (permission), FALSE); + return permission->priv->can_release; +} + +/** + * g_permission_impl_update: + * @permission: a #GPermission instance + * @allowed: the new value for the 'allowed' property + * @can_acquire: the new value for the 'can-acquire' property + * @can_release: the new value for the 'can-release' property + * + * This function is called by the #GPermission implementation to update + * the properties of the permission. You should never call this + * function except from a #GPermission implementation. + * + * GObject notify signals are generated, as appropriate. + * + * Since: 2.26 + **/ +void +g_permission_impl_update (GPermission *permission, + gboolean allowed, + gboolean can_acquire, + gboolean can_release) +{ + GObject *object; + + g_return_if_fail (G_IS_PERMISSION (permission)); + + object = G_OBJECT (permission); + g_object_freeze_notify (object); + + allowed = allowed != FALSE; + if (allowed != permission->priv->allowed) + { + permission->priv->allowed = allowed; + g_object_notify (object, "allowed"); + } + + can_acquire = can_acquire != FALSE; + if (can_acquire != permission->priv->can_acquire) + { + permission->priv->can_acquire = can_acquire; + g_object_notify (object, "can-acquire"); + } + + can_release = can_release != FALSE; + if (can_release != permission->priv->can_release) + { + permission->priv->can_release = can_release; + g_object_notify (object, "can-release"); + } + + g_object_thaw_notify (object); +} + +static void +g_permission_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GPermission *permission = G_PERMISSION (object); + + switch (prop_id) + { + case PROP_ALLOWED: + g_value_set_boolean (value, permission->priv->allowed); + break; + + case PROP_CAN_ACQUIRE: + g_value_set_boolean (value, permission->priv->can_acquire); + break; + + case PROP_CAN_RELEASE: + g_value_set_boolean (value, permission->priv->can_release); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_permission_init (GPermission *permission) +{ + permission->priv = g_permission_get_instance_private (permission); +} + +static gboolean +acquire_or_release (GPermission *permission, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Can't acquire or release permission"); + return FALSE; +} + +static void +acquire_or_release_async (GPermission *permission, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_task_report_new_error (permission, + callback, user_data, + NULL, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Can't acquire or release permission"); +} + +static gboolean +acquire_or_release_finish (GPermission *permission, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +g_permission_class_init (GPermissionClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->get_property = g_permission_get_property; + + class->acquire = acquire_or_release; + class->release = acquire_or_release; + class->acquire_async = acquire_or_release_async; + class->release_async = acquire_or_release_async; + class->acquire_finish = acquire_or_release_finish; + class->release_finish = acquire_or_release_finish; + + /** + * GPermission:allowed: + * + * %TRUE if the caller currently has permission to perform the action that + * @permission represents the permission to perform. + */ + g_object_class_install_property (object_class, PROP_ALLOWED, + g_param_spec_boolean ("allowed", + P_("Is allowed"), + P_("If the caller is allowed to perform the action"), + FALSE, + G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); + + /** + * GPermission:can-acquire: + * + * %TRUE if it is generally possible to acquire the permission by calling + * g_permission_acquire(). + */ + g_object_class_install_property (object_class, PROP_CAN_ACQUIRE, + g_param_spec_boolean ("can-acquire", + P_("Can acquire"), + P_("If calling g_permission_acquire() makes sense"), + FALSE, + G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); + + /** + * GPermission:can-release: + * + * %TRUE if it is generally possible to release the permission by calling + * g_permission_release(). + */ + g_object_class_install_property (object_class, PROP_CAN_RELEASE, + g_param_spec_boolean ("can-release", + P_("Can release"), + P_("If calling g_permission_release() makes sense"), + FALSE, + G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); +} diff --git a/gio/gpermission.h b/gio/gpermission.h new file mode 100644 index 0000000..0c2b0bd --- /dev/null +++ b/gio/gpermission.h @@ -0,0 +1,127 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_PERMISSION_H__ +#define __G_PERMISSION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_PERMISSION (g_permission_get_type ()) +#define G_PERMISSION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_PERMISSION, GPermission)) +#define G_PERMISSION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_PERMISSION, GPermissionClass)) +#define G_IS_PERMISSION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_PERMISSION)) +#define G_IS_PERMISSION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_PERMISSION)) +#define G_PERMISSION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_PERMISSION, GPermissionClass)) + +typedef struct _GPermissionPrivate GPermissionPrivate; +typedef struct _GPermissionClass GPermissionClass; + +struct _GPermission +{ + GObject parent_instance; + + /*< private >*/ + GPermissionPrivate *priv; +}; + +struct _GPermissionClass { + GObjectClass parent_class; + + gboolean (*acquire) (GPermission *permission, + GCancellable *cancellable, + GError **error); + void (*acquire_async) (GPermission *permission, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*acquire_finish) (GPermission *permission, + GAsyncResult *result, + GError **error); + + gboolean (*release) (GPermission *permission, + GCancellable *cancellable, + GError **error); + void (*release_async) (GPermission *permission, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*release_finish) (GPermission *permission, + GAsyncResult *result, + GError **error); + + gpointer reserved[16]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_permission_get_type (void); +GLIB_AVAILABLE_IN_ALL +gboolean g_permission_acquire (GPermission *permission, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_permission_acquire_async (GPermission *permission, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_permission_acquire_finish (GPermission *permission, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_permission_release (GPermission *permission, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_permission_release_async (GPermission *permission, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_permission_release_finish (GPermission *permission, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_permission_get_allowed (GPermission *permission); +GLIB_AVAILABLE_IN_ALL +gboolean g_permission_get_can_acquire (GPermission *permission); +GLIB_AVAILABLE_IN_ALL +gboolean g_permission_get_can_release (GPermission *permission); + +GLIB_AVAILABLE_IN_ALL +void g_permission_impl_update (GPermission *permission, + gboolean allowed, + gboolean can_acquire, + gboolean can_release); + +G_END_DECLS + +#endif /* __G_PERMISSION_H__ */ diff --git a/gio/gpollableinputstream.c b/gio/gpollableinputstream.c new file mode 100644 index 0000000..d040193 --- /dev/null +++ b/gio/gpollableinputstream.c @@ -0,0 +1,219 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include + +#include "gpollableinputstream.h" +#include "gasynchelper.h" +#include "glibintl.h" + +/** + * SECTION:gpollableinputstream + * @short_description: Interface for pollable input streams + * @include: gio/gio.h + * @see_also: #GInputStream, #GPollableOutputStream, #GFileDescriptorBased + * + * #GPollableInputStream is implemented by #GInputStreams that + * can be polled for readiness to read. This can be used when + * interfacing with a non-GIO API that expects + * UNIX-file-descriptor-style asynchronous I/O rather than GIO-style. + * + * Since: 2.28 + */ + +G_DEFINE_INTERFACE (GPollableInputStream, g_pollable_input_stream, G_TYPE_INPUT_STREAM) + +static gboolean g_pollable_input_stream_default_can_poll (GPollableInputStream *stream); +static gssize g_pollable_input_stream_default_read_nonblocking (GPollableInputStream *stream, + void *buffer, + gsize count, + GError **error); + +static void +g_pollable_input_stream_default_init (GPollableInputStreamInterface *iface) +{ + iface->can_poll = g_pollable_input_stream_default_can_poll; + iface->read_nonblocking = g_pollable_input_stream_default_read_nonblocking; +} + +static gboolean +g_pollable_input_stream_default_can_poll (GPollableInputStream *stream) +{ + return TRUE; +} + +/** + * g_pollable_input_stream_can_poll: + * @stream: a #GPollableInputStream. + * + * Checks if @stream is actually pollable. Some classes may implement + * #GPollableInputStream but have only certain instances of that class + * be pollable. If this method returns %FALSE, then the behavior of + * other #GPollableInputStream methods is undefined. + * + * For any given stream, the value returned by this method is constant; + * a stream cannot switch from pollable to non-pollable or vice versa. + * + * Returns: %TRUE if @stream is pollable, %FALSE if not. + * + * Since: 2.28 + */ +gboolean +g_pollable_input_stream_can_poll (GPollableInputStream *stream) +{ + g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (stream), FALSE); + + return G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->can_poll (stream); +} + +/** + * g_pollable_input_stream_is_readable: + * @stream: a #GPollableInputStream. + * + * Checks if @stream can be read. + * + * Note that some stream types may not be able to implement this 100% + * reliably, and it is possible that a call to g_input_stream_read() + * after this returns %TRUE would still block. To guarantee + * non-blocking behavior, you should always use + * g_pollable_input_stream_read_nonblocking(), which will return a + * %G_IO_ERROR_WOULD_BLOCK error rather than blocking. + * + * Returns: %TRUE if @stream is readable, %FALSE if not. If an error + * has occurred on @stream, this will result in + * g_pollable_input_stream_is_readable() returning %TRUE, and the + * next attempt to read will return the error. + * + * Since: 2.28 + */ +gboolean +g_pollable_input_stream_is_readable (GPollableInputStream *stream) +{ + g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (stream), FALSE); + + return G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->is_readable (stream); +} + +/** + * g_pollable_input_stream_create_source: + * @stream: a #GPollableInputStream. + * @cancellable: (nullable): a #GCancellable, or %NULL + * + * Creates a #GSource that triggers when @stream can be read, or + * @cancellable is triggered or an error occurs. The callback on the + * source is of the #GPollableSourceFunc type. + * + * As with g_pollable_input_stream_is_readable(), it is possible that + * the stream may not actually be readable even after the source + * triggers, so you should use g_pollable_input_stream_read_nonblocking() + * rather than g_input_stream_read() from the callback. + * + * Returns: (transfer full): a new #GSource + * + * Since: 2.28 + */ +GSource * +g_pollable_input_stream_create_source (GPollableInputStream *stream, + GCancellable *cancellable) +{ + g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (stream), NULL); + + return G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)-> + create_source (stream, cancellable); +} + +static gssize +g_pollable_input_stream_default_read_nonblocking (GPollableInputStream *stream, + void *buffer, + gsize count, + GError **error) +{ + if (!g_pollable_input_stream_is_readable (stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, + g_strerror (EAGAIN)); + return -1; + } + + return G_INPUT_STREAM_GET_CLASS (stream)-> + read_fn (G_INPUT_STREAM (stream), buffer, count, NULL, error); +} + +/** + * g_pollable_input_stream_read_nonblocking: + * @stream: a #GPollableInputStream + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): a + * buffer to read data into (which should be at least @count bytes long). + * @count: (in): the number of bytes you want to read + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Attempts to read up to @count bytes from @stream into @buffer, as + * with g_input_stream_read(). If @stream is not currently readable, + * this will immediately return %G_IO_ERROR_WOULD_BLOCK, and you can + * use g_pollable_input_stream_create_source() to create a #GSource + * that will be triggered when @stream is readable. + * + * Note that since this method never blocks, you cannot actually + * use @cancellable to cancel it. However, it will return an error + * if @cancellable has already been cancelled when you call, which + * may happen if you call this method after a source triggers due + * to having been cancelled. + * + * Virtual: read_nonblocking + * Returns: the number of bytes read, or -1 on error (including + * %G_IO_ERROR_WOULD_BLOCK). + */ +gssize +g_pollable_input_stream_read_nonblocking (GPollableInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + gssize res; + + g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (stream), -1); + g_return_val_if_fail (buffer != NULL, 0); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (count == 0) + return 0; + + if (((gssize) count) < 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), G_STRFUNC); + return -1; + } + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)-> + read_nonblocking (stream, buffer, count, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + return res; +} diff --git a/gio/gpollableinputstream.h b/gio/gpollableinputstream.h new file mode 100644 index 0000000..823c83c --- /dev/null +++ b/gio/gpollableinputstream.h @@ -0,0 +1,104 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_POLLABLE_INPUT_STREAM_H__ +#define __G_POLLABLE_INPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_POLLABLE_INPUT_STREAM (g_pollable_input_stream_get_type ()) +#define G_POLLABLE_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_POLLABLE_INPUT_STREAM, GPollableInputStream)) +#define G_IS_POLLABLE_INPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_POLLABLE_INPUT_STREAM)) +#define G_POLLABLE_INPUT_STREAM_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_POLLABLE_INPUT_STREAM, GPollableInputStreamInterface)) + +/** + * GPollableInputStream: + * + * An interface for a #GInputStream that can be polled for readability. + * + * Since: 2.28 + */ +typedef struct _GPollableInputStreamInterface GPollableInputStreamInterface; + +/** + * GPollableInputStreamInterface: + * @g_iface: The parent interface. + * @can_poll: Checks if the #GPollableInputStream instance is actually pollable + * @is_readable: Checks if the stream is readable + * @create_source: Creates a #GSource to poll the stream + * @read_nonblocking: Does a non-blocking read or returns + * %G_IO_ERROR_WOULD_BLOCK + * + * The interface for pollable input streams. + * + * The default implementation of @can_poll always returns %TRUE. + * + * The default implementation of @read_nonblocking calls + * g_pollable_input_stream_is_readable(), and then calls + * g_input_stream_read() if it returns %TRUE. This means you only need + * to override it if it is possible that your @is_readable + * implementation may return %TRUE when the stream is not actually + * readable. + * + * Since: 2.28 + */ +struct _GPollableInputStreamInterface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + gboolean (*can_poll) (GPollableInputStream *stream); + + gboolean (*is_readable) (GPollableInputStream *stream); + GSource * (*create_source) (GPollableInputStream *stream, + GCancellable *cancellable); + gssize (*read_nonblocking) (GPollableInputStream *stream, + void *buffer, + gsize count, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_pollable_input_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gboolean g_pollable_input_stream_can_poll (GPollableInputStream *stream); + +GLIB_AVAILABLE_IN_ALL +gboolean g_pollable_input_stream_is_readable (GPollableInputStream *stream); +GLIB_AVAILABLE_IN_ALL +GSource *g_pollable_input_stream_create_source (GPollableInputStream *stream, + GCancellable *cancellable); + +GLIB_AVAILABLE_IN_ALL +gssize g_pollable_input_stream_read_nonblocking (GPollableInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + + +#endif /* __G_POLLABLE_INPUT_STREAM_H__ */ diff --git a/gio/gpollableoutputstream.c b/gio/gpollableoutputstream.c new file mode 100644 index 0000000..2d36144 --- /dev/null +++ b/gio/gpollableoutputstream.c @@ -0,0 +1,379 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include + +#include "gpollableoutputstream.h" +#include "gasynchelper.h" +#include "gfiledescriptorbased.h" +#include "glibintl.h" + +/** + * SECTION:gpollableoutputstream + * @short_description: Interface for pollable output streams + * @include: gio/gio.h + * @see_also: #GOutputStream, #GFileDescriptorBased, #GPollableInputStream + * + * #GPollableOutputStream is implemented by #GOutputStreams that + * can be polled for readiness to write. This can be used when + * interfacing with a non-GIO API that expects + * UNIX-file-descriptor-style asynchronous I/O rather than GIO-style. + * + * Since: 2.28 + */ + +G_DEFINE_INTERFACE (GPollableOutputStream, g_pollable_output_stream, G_TYPE_OUTPUT_STREAM) + +static gboolean g_pollable_output_stream_default_can_poll (GPollableOutputStream *stream); +static gssize g_pollable_output_stream_default_write_nonblocking (GPollableOutputStream *stream, + const void *buffer, + gsize count, + GError **error); +static GPollableReturn g_pollable_output_stream_default_writev_nonblocking (GPollableOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GError **error); + +static void +g_pollable_output_stream_default_init (GPollableOutputStreamInterface *iface) +{ + iface->can_poll = g_pollable_output_stream_default_can_poll; + iface->write_nonblocking = g_pollable_output_stream_default_write_nonblocking; + iface->writev_nonblocking = g_pollable_output_stream_default_writev_nonblocking; +} + +static gboolean +g_pollable_output_stream_default_can_poll (GPollableOutputStream *stream) +{ + return TRUE; +} + +/** + * g_pollable_output_stream_can_poll: + * @stream: a #GPollableOutputStream. + * + * Checks if @stream is actually pollable. Some classes may implement + * #GPollableOutputStream but have only certain instances of that + * class be pollable. If this method returns %FALSE, then the behavior + * of other #GPollableOutputStream methods is undefined. + * + * For any given stream, the value returned by this method is constant; + * a stream cannot switch from pollable to non-pollable or vice versa. + * + * Returns: %TRUE if @stream is pollable, %FALSE if not. + * + * Since: 2.28 + */ +gboolean +g_pollable_output_stream_can_poll (GPollableOutputStream *stream) +{ + g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), FALSE); + + return G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->can_poll (stream); +} + +/** + * g_pollable_output_stream_is_writable: + * @stream: a #GPollableOutputStream. + * + * Checks if @stream can be written. + * + * Note that some stream types may not be able to implement this 100% + * reliably, and it is possible that a call to g_output_stream_write() + * after this returns %TRUE would still block. To guarantee + * non-blocking behavior, you should always use + * g_pollable_output_stream_write_nonblocking(), which will return a + * %G_IO_ERROR_WOULD_BLOCK error rather than blocking. + * + * Returns: %TRUE if @stream is writable, %FALSE if not. If an error + * has occurred on @stream, this will result in + * g_pollable_output_stream_is_writable() returning %TRUE, and the + * next attempt to write will return the error. + * + * Since: 2.28 + */ +gboolean +g_pollable_output_stream_is_writable (GPollableOutputStream *stream) +{ + g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), FALSE); + + return G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->is_writable (stream); +} + +/** + * g_pollable_output_stream_create_source: + * @stream: a #GPollableOutputStream. + * @cancellable: (nullable): a #GCancellable, or %NULL + * + * Creates a #GSource that triggers when @stream can be written, or + * @cancellable is triggered or an error occurs. The callback on the + * source is of the #GPollableSourceFunc type. + * + * As with g_pollable_output_stream_is_writable(), it is possible that + * the stream may not actually be writable even after the source + * triggers, so you should use g_pollable_output_stream_write_nonblocking() + * rather than g_output_stream_write() from the callback. + * + * Returns: (transfer full): a new #GSource + * + * Since: 2.28 + */ +GSource * +g_pollable_output_stream_create_source (GPollableOutputStream *stream, + GCancellable *cancellable) +{ + g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), NULL); + + return G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)-> + create_source (stream, cancellable); +} + +static gssize +g_pollable_output_stream_default_write_nonblocking (GPollableOutputStream *stream, + const void *buffer, + gsize count, + GError **error) +{ + if (!g_pollable_output_stream_is_writable (stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, + g_strerror (EAGAIN)); + return -1; + } + + return G_OUTPUT_STREAM_GET_CLASS (stream)-> + write_fn (G_OUTPUT_STREAM (stream), buffer, count, NULL, error); +} + +static GPollableReturn +g_pollable_output_stream_default_writev_nonblocking (GPollableOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GError **error) +{ + gsize _bytes_written = 0; + GPollableOutputStreamInterface *iface = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream); + gsize i; + GError *err = NULL; + + for (i = 0; i < n_vectors; i++) + { + gssize res; + + /* Would we overflow here? In that case simply return and let the caller + * handle this like a short write */ + if (_bytes_written > G_MAXSIZE - vectors[i].size) + break; + + res = iface->write_nonblocking (stream, vectors[i].buffer, vectors[i].size, &err); + if (res == -1) + { + if (bytes_written) + *bytes_written = _bytes_written; + + /* If something was written already we handle this like a short + * write and assume that the next call would either give the same + * error again or successfully finish writing without errors or data + * loss + */ + if (_bytes_written > 0) + { + g_clear_error (&err); + return G_POLLABLE_RETURN_OK; + } + else if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) + { + g_clear_error (&err); + return G_POLLABLE_RETURN_WOULD_BLOCK; + } + else + { + g_propagate_error (error, err); + return G_POLLABLE_RETURN_FAILED; + } + } + + _bytes_written += res; + /* if we had a short write break the loop here */ + if ((gsize) res < vectors[i].size) + break; + } + + if (bytes_written) + *bytes_written = _bytes_written; + + return G_POLLABLE_RETURN_OK; +} + +/** + * g_pollable_output_stream_write_nonblocking: + * @stream: a #GPollableOutputStream + * @buffer: (array length=count) (element-type guint8): a buffer to write + * data from + * @count: the number of bytes you want to write + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Attempts to write up to @count bytes from @buffer to @stream, as + * with g_output_stream_write(). If @stream is not currently writable, + * this will immediately return %G_IO_ERROR_WOULD_BLOCK, and you can + * use g_pollable_output_stream_create_source() to create a #GSource + * that will be triggered when @stream is writable. + * + * Note that since this method never blocks, you cannot actually + * use @cancellable to cancel it. However, it will return an error + * if @cancellable has already been cancelled when you call, which + * may happen if you call this method after a source triggers due + * to having been cancelled. + * + * Also note that if %G_IO_ERROR_WOULD_BLOCK is returned some underlying + * transports like D/TLS require that you re-send the same @buffer and + * @count in the next write call. + * + * Virtual: write_nonblocking + * Returns: the number of bytes written, or -1 on error (including + * %G_IO_ERROR_WOULD_BLOCK). + */ +gssize +g_pollable_output_stream_write_nonblocking (GPollableOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + gssize res; + + g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), -1); + g_return_val_if_fail (buffer != NULL, 0); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (count == 0) + return 0; + + if (((gssize) count) < 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Too large count value passed to %s"), G_STRFUNC); + return -1; + } + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)-> + write_nonblocking (stream, buffer, count, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + return res; +} + +/** + * g_pollable_output_stream_writev_nonblocking: + * @stream: a #GPollableOutputStream + * @vectors: (array length=n_vectors): the buffer containing the #GOutputVectors to write. + * @n_vectors: the number of vectors to write + * @bytes_written: (out) (optional): location to store the number of bytes that were + * written to the stream + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Attempts to write the bytes contained in the @n_vectors @vectors to @stream, + * as with g_output_stream_writev(). If @stream is not currently writable, + * this will immediately return %@G_POLLABLE_RETURN_WOULD_BLOCK, and you can + * use g_pollable_output_stream_create_source() to create a #GSource + * that will be triggered when @stream is writable. @error will *not* be + * set in that case. + * + * Note that since this method never blocks, you cannot actually + * use @cancellable to cancel it. However, it will return an error + * if @cancellable has already been cancelled when you call, which + * may happen if you call this method after a source triggers due + * to having been cancelled. + * + * Also note that if %G_POLLABLE_RETURN_WOULD_BLOCK is returned some underlying + * transports like D/TLS require that you re-send the same @vectors and + * @n_vectors in the next write call. + * + * Virtual: writev_nonblocking + * + * Returns: %@G_POLLABLE_RETURN_OK on success, %G_POLLABLE_RETURN_WOULD_BLOCK + * if the stream is not currently writable (and @error is *not* set), or + * %G_POLLABLE_RETURN_FAILED if there was an error in which case @error will + * be set. + * + * Since: 2.60 + */ +GPollableReturn +g_pollable_output_stream_writev_nonblocking (GPollableOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + GPollableOutputStreamInterface *iface; + GPollableReturn res; + gsize _bytes_written = 0; + + if (bytes_written) + *bytes_written = 0; + + g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), G_POLLABLE_RETURN_FAILED); + g_return_val_if_fail (vectors != NULL || n_vectors == 0, G_POLLABLE_RETURN_FAILED); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_POLLABLE_RETURN_FAILED); + g_return_val_if_fail (error == NULL || *error == NULL, G_POLLABLE_RETURN_FAILED); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return G_POLLABLE_RETURN_FAILED; + + if (n_vectors == 0) + return G_POLLABLE_RETURN_OK; + + iface = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream); + g_return_val_if_fail (iface->writev_nonblocking != NULL, G_POLLABLE_RETURN_FAILED); + + if (cancellable) + g_cancellable_push_current (cancellable); + + res = iface-> + writev_nonblocking (stream, vectors, n_vectors, &_bytes_written, error); + + if (cancellable) + g_cancellable_pop_current (cancellable); + + if (res == G_POLLABLE_RETURN_FAILED) + g_warn_if_fail (error == NULL || (*error != NULL && !g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))); + else if (res == G_POLLABLE_RETURN_WOULD_BLOCK) + g_warn_if_fail (error == NULL || *error == NULL); + + /* in case of not-OK nothing must've been written */ + g_warn_if_fail (res == G_POLLABLE_RETURN_OK || _bytes_written == 0); + + if (bytes_written) + *bytes_written = _bytes_written; + + return res; +} diff --git a/gio/gpollableoutputstream.h b/gio/gpollableoutputstream.h new file mode 100644 index 0000000..e27841e --- /dev/null +++ b/gio/gpollableoutputstream.h @@ -0,0 +1,125 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_POLLABLE_OUTPUT_STREAM_H__ +#define __G_POLLABLE_OUTPUT_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_POLLABLE_OUTPUT_STREAM (g_pollable_output_stream_get_type ()) +#define G_POLLABLE_OUTPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_POLLABLE_OUTPUT_STREAM, GPollableOutputStream)) +#define G_IS_POLLABLE_OUTPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_POLLABLE_OUTPUT_STREAM)) +#define G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_POLLABLE_OUTPUT_STREAM, GPollableOutputStreamInterface)) + +/** + * GPollableOutputStream: + * + * An interface for a #GOutputStream that can be polled for writeability. + * + * Since: 2.28 + */ +typedef struct _GPollableOutputStreamInterface GPollableOutputStreamInterface; + +/** + * GPollableOutputStreamInterface: + * @g_iface: The parent interface. + * @can_poll: Checks if the #GPollableOutputStream instance is actually pollable + * @is_writable: Checks if the stream is writable + * @create_source: Creates a #GSource to poll the stream + * @write_nonblocking: Does a non-blocking write or returns + * %G_IO_ERROR_WOULD_BLOCK + * @writev_nonblocking: Does a vectored non-blocking write, or returns + * %G_POLLABLE_RETURN_WOULD_BLOCK + * + * The interface for pollable output streams. + * + * The default implementation of @can_poll always returns %TRUE. + * + * The default implementation of @write_nonblocking calls + * g_pollable_output_stream_is_writable(), and then calls + * g_output_stream_write() if it returns %TRUE. This means you only + * need to override it if it is possible that your @is_writable + * implementation may return %TRUE when the stream is not actually + * writable. + * + * The default implementation of @writev_nonblocking calls + * g_pollable_output_stream_write_nonblocking() for each vector, and converts + * its return value and error (if set) to a #GPollableReturn. You should + * override this where possible to avoid having to allocate a #GError to return + * %G_IO_ERROR_WOULD_BLOCK. + * + * Since: 2.28 + */ +struct _GPollableOutputStreamInterface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + gboolean (*can_poll) (GPollableOutputStream *stream); + + gboolean (*is_writable) (GPollableOutputStream *stream); + GSource * (*create_source) (GPollableOutputStream *stream, + GCancellable *cancellable); + gssize (*write_nonblocking) (GPollableOutputStream *stream, + const void *buffer, + gsize count, + GError **error); + GPollableReturn (*writev_nonblocking) (GPollableOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_pollable_output_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gboolean g_pollable_output_stream_can_poll (GPollableOutputStream *stream); + +GLIB_AVAILABLE_IN_ALL +gboolean g_pollable_output_stream_is_writable (GPollableOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +GSource *g_pollable_output_stream_create_source (GPollableOutputStream *stream, + GCancellable *cancellable); + +GLIB_AVAILABLE_IN_ALL +gssize g_pollable_output_stream_write_nonblocking (GPollableOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_60 +GPollableReturn g_pollable_output_stream_writev_nonblocking (GPollableOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + + +#endif /* __G_POLLABLE_OUTPUT_STREAM_H__ */ diff --git a/gio/gpollableutils.c b/gio/gpollableutils.c new file mode 100644 index 0000000..a20d150 --- /dev/null +++ b/gio/gpollableutils.c @@ -0,0 +1,335 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include + +#include "gpollableinputstream.h" +#include "gasynchelper.h" +#include "glibintl.h" + +/** + * SECTION:gpollableutils + * @short_description: Utilities for pollable streams + * @include: gio/gio.h + * + * Utility functions for #GPollableInputStream and + * #GPollableOutputStream implementations. + */ + +typedef struct { + GSource source; + + GObject *stream; +} GPollableSource; + +static gboolean +pollable_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GPollableSourceFunc func = (GPollableSourceFunc)callback; + GPollableSource *pollable_source = (GPollableSource *)source; + + return (*func) (pollable_source->stream, user_data); +} + +static void +pollable_source_finalize (GSource *source) +{ + GPollableSource *pollable_source = (GPollableSource *)source; + + g_object_unref (pollable_source->stream); +} + +static gboolean +pollable_source_closure_callback (GObject *stream, + gpointer data) +{ + GClosure *closure = data; + + GValue param = G_VALUE_INIT; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_value_init (¶m, G_TYPE_OBJECT); + g_value_set_object (¶m, stream); + + g_closure_invoke (closure, &result_value, 1, ¶m, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + g_value_unset (¶m); + + return result; +} + +static GSourceFuncs pollable_source_funcs = +{ + NULL, + NULL, + pollable_source_dispatch, + pollable_source_finalize, + (GSourceFunc)pollable_source_closure_callback, + NULL, +}; + +/** + * g_pollable_source_new: + * @pollable_stream: the stream associated with the new source + * + * Utility method for #GPollableInputStream and #GPollableOutputStream + * implementations. Creates a new #GSource that expects a callback of + * type #GPollableSourceFunc. The new source does not actually do + * anything on its own; use g_source_add_child_source() to add other + * sources to it to cause it to trigger. + * + * Returns: (transfer full): the new #GSource. + * + * Since: 2.28 + */ +GSource * +g_pollable_source_new (GObject *pollable_stream) +{ + GSource *source; + GPollableSource *pollable_source; + + g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (pollable_stream) || + G_IS_POLLABLE_OUTPUT_STREAM (pollable_stream), NULL); + + source = g_source_new (&pollable_source_funcs, sizeof (GPollableSource)); + g_source_set_static_name (source, "GPollableSource"); + pollable_source = (GPollableSource *)source; + pollable_source->stream = g_object_ref (pollable_stream); + + return source; +} + +/** + * g_pollable_source_new_full: + * @pollable_stream: (type GObject): the stream associated with the + * new source + * @child_source: (nullable): optional child source to attach + * @cancellable: (nullable): optional #GCancellable to attach + * + * Utility method for #GPollableInputStream and #GPollableOutputStream + * implementations. Creates a new #GSource, as with + * g_pollable_source_new(), but also attaching @child_source (with a + * dummy callback), and @cancellable, if they are non-%NULL. + * + * Returns: (transfer full): the new #GSource. + * + * Since: 2.34 + */ +GSource * +g_pollable_source_new_full (gpointer pollable_stream, + GSource *child_source, + GCancellable *cancellable) +{ + GSource *source; + + g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (pollable_stream) || + G_IS_POLLABLE_OUTPUT_STREAM (pollable_stream), NULL); + + source = g_pollable_source_new (pollable_stream); + if (child_source) + { + g_source_set_dummy_callback (child_source); + g_source_add_child_source (source, child_source); + } + if (cancellable) + { + GSource *cancellable_source = g_cancellable_source_new (cancellable); + + g_source_set_dummy_callback (cancellable_source); + g_source_add_child_source (source, cancellable_source); + g_source_unref (cancellable_source); + } + + return source; +} + +/** + * g_pollable_stream_read: + * @stream: a #GInputStream + * @buffer: (array length=count) (element-type guint8): a buffer to + * read data into + * @count: the number of bytes to read + * @blocking: whether to do blocking I/O + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to read from @stream, as with g_input_stream_read() (if + * @blocking is %TRUE) or g_pollable_input_stream_read_nonblocking() + * (if @blocking is %FALSE). This can be used to more easily share + * code between blocking and non-blocking implementations of a method. + * + * If @blocking is %FALSE, then @stream must be a + * #GPollableInputStream for which g_pollable_input_stream_can_poll() + * returns %TRUE, or else the behavior is undefined. If @blocking is + * %TRUE, then @stream does not need to be a #GPollableInputStream. + * + * Returns: the number of bytes read, or -1 on error. + * + * Since: 2.34 + */ +gssize +g_pollable_stream_read (GInputStream *stream, + void *buffer, + gsize count, + gboolean blocking, + GCancellable *cancellable, + GError **error) +{ + if (blocking) + { + return g_input_stream_read (stream, + buffer, count, + cancellable, error); + } + else + { + return g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (stream), + buffer, count, + cancellable, error); + } +} + +/** + * g_pollable_stream_write: + * @stream: a #GOutputStream. + * @buffer: (array length=count) (element-type guint8): the buffer + * containing the data to write. + * @count: the number of bytes to write + * @blocking: whether to do blocking I/O + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to write to @stream, as with g_output_stream_write() (if + * @blocking is %TRUE) or g_pollable_output_stream_write_nonblocking() + * (if @blocking is %FALSE). This can be used to more easily share + * code between blocking and non-blocking implementations of a method. + * + * If @blocking is %FALSE, then @stream must be a + * #GPollableOutputStream for which + * g_pollable_output_stream_can_poll() returns %TRUE or else the + * behavior is undefined. If @blocking is %TRUE, then @stream does not + * need to be a #GPollableOutputStream. + * + * Returns: the number of bytes written, or -1 on error. + * + * Since: 2.34 + */ +gssize +g_pollable_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + gboolean blocking, + GCancellable *cancellable, + GError **error) +{ + if (blocking) + { + return g_output_stream_write (stream, + buffer, count, + cancellable, error); + } + else + { + return g_pollable_output_stream_write_nonblocking (G_POLLABLE_OUTPUT_STREAM (stream), + buffer, count, + cancellable, error); + } +} + +/** + * g_pollable_stream_write_all: + * @stream: a #GOutputStream. + * @buffer: (array length=count) (element-type guint8): the buffer + * containing the data to write. + * @count: the number of bytes to write + * @blocking: whether to do blocking I/O + * @bytes_written: (out): location to store the number of bytes that was + * written to the stream + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: location to store the error occurring, or %NULL to ignore + * + * Tries to write @count bytes to @stream, as with + * g_output_stream_write_all(), but using g_pollable_stream_write() + * rather than g_output_stream_write(). + * + * On a successful write of @count bytes, %TRUE is returned, and + * @bytes_written is set to @count. + * + * If there is an error during the operation (including + * %G_IO_ERROR_WOULD_BLOCK in the non-blocking case), %FALSE is + * returned and @error is set to indicate the error status, + * @bytes_written is updated to contain the number of bytes written + * into the stream before the error occurred. + * + * As with g_pollable_stream_write(), if @blocking is %FALSE, then + * @stream must be a #GPollableOutputStream for which + * g_pollable_output_stream_can_poll() returns %TRUE or else the + * behavior is undefined. If @blocking is %TRUE, then @stream does not + * need to be a #GPollableOutputStream. + * + * Returns: %TRUE on success, %FALSE if there was an error + * + * Since: 2.34 + */ +gboolean +g_pollable_stream_write_all (GOutputStream *stream, + const void *buffer, + gsize count, + gboolean blocking, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + gsize _bytes_written; + gssize res; + + _bytes_written = 0; + while (_bytes_written < count) + { + res = g_pollable_stream_write (stream, + (char *)buffer + _bytes_written, + count - _bytes_written, + blocking, + cancellable, error); + if (res == -1) + { + if (bytes_written) + *bytes_written = _bytes_written; + return FALSE; + } + + if (res == 0) + g_warning ("Write returned zero without error"); + + _bytes_written += res; + } + + if (bytes_written) + *bytes_written = _bytes_written; + + return TRUE; +} diff --git a/gio/gpollableutils.h b/gio/gpollableutils.h new file mode 100644 index 0000000..007048c --- /dev/null +++ b/gio/gpollableutils.h @@ -0,0 +1,64 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_POLLABLE_UTILS_H__ +#define __G_POLLABLE_UTILS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +GSource *g_pollable_source_new (GObject *pollable_stream); + +GLIB_AVAILABLE_IN_2_34 +GSource *g_pollable_source_new_full (gpointer pollable_stream, + GSource *child_source, + GCancellable *cancellable); + +GLIB_AVAILABLE_IN_2_34 +gssize g_pollable_stream_read (GInputStream *stream, + void *buffer, + gsize count, + gboolean blocking, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_34 +gssize g_pollable_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + gboolean blocking, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_34 +gboolean g_pollable_stream_write_all (GOutputStream *stream, + const void *buffer, + gsize count, + gboolean blocking, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + +#endif /* _G_POLLABLE_UTILS_H_ */ diff --git a/gio/gpollfilemonitor.c b/gio/gpollfilemonitor.c new file mode 100644 index 0000000..bd3d78a --- /dev/null +++ b/gio/gpollfilemonitor.c @@ -0,0 +1,221 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include + +#include "gpollfilemonitor.h" +#include "gfile.h" +#include "gfilemonitor.h" +#include "gfileinfo.h" + + +static gboolean g_poll_file_monitor_cancel (GFileMonitor* monitor); +static void schedule_poll_timeout (GPollFileMonitor* poll_monitor); + +struct _GPollFileMonitor +{ + GFileMonitor parent_instance; + GFile *file; + GFileInfo *last_info; + GSource *timeout; +}; + +#define POLL_TIME_SECS 5 + +#define g_poll_file_monitor_get_type _g_poll_file_monitor_get_type +G_DEFINE_TYPE (GPollFileMonitor, g_poll_file_monitor, G_TYPE_FILE_MONITOR) + +static void +g_poll_file_monitor_finalize (GObject* object) +{ + GPollFileMonitor* poll_monitor; + + poll_monitor = G_POLL_FILE_MONITOR (object); + + g_poll_file_monitor_cancel (G_FILE_MONITOR (poll_monitor)); + g_object_unref (poll_monitor->file); + g_clear_object (&poll_monitor->last_info); + + G_OBJECT_CLASS (g_poll_file_monitor_parent_class)->finalize (object); +} + + +static void +g_poll_file_monitor_class_init (GPollFileMonitorClass* klass) +{ + GObjectClass* gobject_class = G_OBJECT_CLASS (klass); + GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass); + + gobject_class->finalize = g_poll_file_monitor_finalize; + + file_monitor_class->cancel = g_poll_file_monitor_cancel; +} + +static void +g_poll_file_monitor_init (GPollFileMonitor* poll_monitor) +{ +} + +static int +calc_event_type (GFileInfo *last, + GFileInfo *new) +{ + if (last == NULL && new == NULL) + return -1; + + if (last == NULL && new != NULL) + return G_FILE_MONITOR_EVENT_CREATED; + + if (last != NULL && new == NULL) + return G_FILE_MONITOR_EVENT_DELETED; + + if (g_strcmp0 (g_file_info_get_etag (last), g_file_info_get_etag (new))) + return G_FILE_MONITOR_EVENT_CHANGED; + + if (g_file_info_get_size (last) != g_file_info_get_size (new)) + return G_FILE_MONITOR_EVENT_CHANGED; + + return -1; +} + +static void +got_new_info (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GPollFileMonitor* poll_monitor = user_data; + GFileInfo *info; + int event; + + info = g_file_query_info_finish (poll_monitor->file, res, NULL); + + if (!g_file_monitor_is_cancelled (G_FILE_MONITOR (poll_monitor))) + { + event = calc_event_type (poll_monitor->last_info, info); + + if (event != -1) + { + g_file_monitor_emit_event (G_FILE_MONITOR (poll_monitor), + poll_monitor->file, + NULL, event); + /* We're polling so slowly anyway, so always emit the done hint */ + if (!g_file_monitor_is_cancelled (G_FILE_MONITOR (poll_monitor)) && + (event == G_FILE_MONITOR_EVENT_CHANGED || event == G_FILE_MONITOR_EVENT_CREATED)) + g_file_monitor_emit_event (G_FILE_MONITOR (poll_monitor), + poll_monitor->file, + NULL, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT); + } + + if (poll_monitor->last_info) + { + g_object_unref (poll_monitor->last_info); + poll_monitor->last_info = NULL; + } + + if (info) + poll_monitor->last_info = g_object_ref (info); + + schedule_poll_timeout (poll_monitor); + } + + if (info) + g_object_unref (info); + + g_object_unref (poll_monitor); +} + +static gboolean +poll_file_timeout (gpointer data) +{ + GPollFileMonitor* poll_monitor = data; + + g_source_unref (poll_monitor->timeout); + poll_monitor->timeout = NULL; + + g_file_query_info_async (poll_monitor->file, G_FILE_ATTRIBUTE_ETAG_VALUE "," G_FILE_ATTRIBUTE_STANDARD_SIZE, + 0, 0, NULL, got_new_info, g_object_ref (poll_monitor)); + + return G_SOURCE_REMOVE; +} + +static void +schedule_poll_timeout (GPollFileMonitor* poll_monitor) +{ + poll_monitor->timeout = g_timeout_source_new_seconds (POLL_TIME_SECS); + g_source_set_callback (poll_monitor->timeout, poll_file_timeout, poll_monitor, NULL); + g_source_attach (poll_monitor->timeout, g_main_context_get_thread_default ()); +} + +static void +got_initial_info (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GPollFileMonitor* poll_monitor = user_data; + GFileInfo *info; + + info = g_file_query_info_finish (poll_monitor->file, res, NULL); + + poll_monitor->last_info = info; + + if (!g_file_monitor_is_cancelled (G_FILE_MONITOR (poll_monitor))) + schedule_poll_timeout (poll_monitor); + + g_object_unref (poll_monitor); +} + +/** + * _g_poll_file_monitor_new: + * @file: a #GFile. + * + * Polls @file for changes. + * + * Returns: a new #GFileMonitor for the given #GFile. + **/ +GFileMonitor* +_g_poll_file_monitor_new (GFile *file) +{ + GPollFileMonitor* poll_monitor; + + poll_monitor = g_object_new (G_TYPE_POLL_FILE_MONITOR, NULL); + + poll_monitor->file = g_object_ref (file); + + g_file_query_info_async (file, G_FILE_ATTRIBUTE_ETAG_VALUE "," G_FILE_ATTRIBUTE_STANDARD_SIZE, + 0, 0, NULL, got_initial_info, g_object_ref (poll_monitor)); + + return G_FILE_MONITOR (poll_monitor); +} + +static gboolean +g_poll_file_monitor_cancel (GFileMonitor* monitor) +{ + GPollFileMonitor *poll_monitor = G_POLL_FILE_MONITOR (monitor); + + if (poll_monitor->timeout) + { + g_source_destroy (poll_monitor->timeout); + g_source_unref (poll_monitor->timeout); + poll_monitor->timeout = NULL; + } + + return TRUE; +} diff --git a/gio/gpollfilemonitor.h b/gio/gpollfilemonitor.h new file mode 100644 index 0000000..227c20a --- /dev/null +++ b/gio/gpollfilemonitor.h @@ -0,0 +1,48 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_POLL_FILE_MONITOR_H__ +#define __G_POLL_FILE_MONITOR_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_POLL_FILE_MONITOR (_g_poll_file_monitor_get_type ()) +#define G_POLL_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_POLL_FILE_MONITOR, GPollFileMonitor)) +#define G_POLL_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_POLL_FILE_MONITOR, GPollFileMonitorClass)) +#define G_IS_POLL_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_POLL_FILE_MONITOR)) +#define G_IS_POLL_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_POLL_FILE_MONITOR)) + +typedef struct _GPollFileMonitor GPollFileMonitor; +typedef struct _GPollFileMonitorClass GPollFileMonitorClass; + +struct _GPollFileMonitorClass +{ + GFileMonitorClass parent_class; +}; + +GType _g_poll_file_monitor_get_type (void) G_GNUC_CONST; + +GFileMonitor * _g_poll_file_monitor_new (GFile *file); + +G_END_DECLS + +#endif /* __G_POLL_FILE_MONITOR_H__ */ diff --git a/gio/gportalnotificationbackend.c b/gio/gportalnotificationbackend.c new file mode 100644 index 0000000..b0d67aa --- /dev/null +++ b/gio/gportalnotificationbackend.c @@ -0,0 +1,97 @@ +/* +* Copyright © 2016 Red Hat, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General +* Public License along with this library; if not, see . +* +* Author: Matthias Clasen +*/ + +#include "config.h" +#include "gnotificationbackend.h" + +#include "giomodule-priv.h" +#include "gdbusconnection.h" +#include "gapplication.h" +#include "gnotification-private.h" +#include "gportalsupport.h" + +#define G_TYPE_PORTAL_NOTIFICATION_BACKEND (g_portal_notification_backend_get_type ()) +#define G_PORTAL_NOTIFICATION_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_PORTAL_NOTIFICATION_BACKEND, GPortalNotificationBackend)) + +typedef struct _GPortalNotificationBackend GPortalNotificationBackend; +typedef GNotificationBackendClass GPortalNotificationBackendClass; + +struct _GPortalNotificationBackend +{ + GNotificationBackend parent; +}; + +GType g_portal_notification_backend_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (GPortalNotificationBackend, g_portal_notification_backend, G_TYPE_NOTIFICATION_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "portal", 110)) + +static gboolean +g_portal_notification_backend_is_supported (void) +{ + return glib_should_use_portal (); +} + +static void +g_portal_notification_backend_send_notification (GNotificationBackend *backend, + const gchar *id, + GNotification *notification) +{ + g_dbus_connection_call (backend->dbus_connection, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.Notification", + "AddNotification", + g_variant_new ("(s@a{sv})", + id, + g_notification_serialize (notification)), + G_VARIANT_TYPE_UNIT, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +g_portal_notification_backend_withdraw_notification (GNotificationBackend *backend, + const gchar *id) +{ + g_dbus_connection_call (backend->dbus_connection, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.Notification", + "RemoveNotification", + g_variant_new ("(s)", id), + G_VARIANT_TYPE_UNIT, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +g_portal_notification_backend_init (GPortalNotificationBackend *backend) +{ +} + +static void +g_portal_notification_backend_class_init (GPortalNotificationBackendClass *class) +{ + GNotificationBackendClass *backend_class = G_NOTIFICATION_BACKEND_CLASS (class); + + backend_class->is_supported = g_portal_notification_backend_is_supported; + backend_class->send_notification = g_portal_notification_backend_send_notification; + backend_class->withdraw_notification = g_portal_notification_backend_withdraw_notification; +} diff --git a/gio/gportalsupport.c b/gio/gportalsupport.c new file mode 100644 index 0000000..233f6af --- /dev/null +++ b/gio/gportalsupport.c @@ -0,0 +1,101 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gportalsupport.h" + +static gboolean use_portal; +static gboolean network_available; +static gboolean dconf_access; + +static void +read_flatpak_info (void) +{ + static gsize flatpak_info_read = 0; + const gchar *path = "/.flatpak-info"; + + if (!g_once_init_enter (&flatpak_info_read)) + return; + + if (g_file_test (path, G_FILE_TEST_EXISTS)) + { + GKeyFile *keyfile; + + use_portal = TRUE; + network_available = FALSE; + dconf_access = FALSE; + + keyfile = g_key_file_new (); + if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL)) + { + char **shared = NULL; + char *dconf_policy = NULL; + + shared = g_key_file_get_string_list (keyfile, "Context", "shared", NULL, NULL); + if (shared) + { + network_available = g_strv_contains ((const char * const *)shared, "network"); + g_strfreev (shared); + } + + dconf_policy = g_key_file_get_string (keyfile, "Session Bus Policy", "ca.desrt.dconf", NULL); + if (dconf_policy) + { + if (strcmp (dconf_policy, "talk") == 0) + dconf_access = TRUE; + g_free (dconf_policy); + } + } + + g_key_file_unref (keyfile); + } + else + { + const char *var; + + var = g_getenv ("GTK_USE_PORTAL"); + if (var && var[0] == '1') + use_portal = TRUE; + network_available = TRUE; + dconf_access = TRUE; + } + + g_once_init_leave (&flatpak_info_read, 1); +} + +gboolean +glib_should_use_portal (void) +{ + read_flatpak_info (); + return use_portal; +} + +gboolean +glib_network_available_in_sandbox (void) +{ + read_flatpak_info (); + return network_available; +} + +gboolean +glib_has_dconf_access_in_sandbox (void) +{ + read_flatpak_info (); + return dconf_access; +} diff --git a/gio/gportalsupport.h b/gio/gportalsupport.h new file mode 100644 index 0000000..746f1fd --- /dev/null +++ b/gio/gportalsupport.h @@ -0,0 +1,31 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_PORTAL_SUPPORT_H__ + +#include + +G_BEGIN_DECLS + +gboolean glib_should_use_portal (void); +gboolean glib_network_available_in_sandbox (void); +gboolean glib_has_dconf_access_in_sandbox (void); + +G_END_DECLS + +#endif diff --git a/gio/gpowerprofilemonitor.c b/gio/gpowerprofilemonitor.c new file mode 100644 index 0000000..00bdc94 --- /dev/null +++ b/gio/gpowerprofilemonitor.c @@ -0,0 +1,141 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc + * Copyright 2021 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" +#include "glibintl.h" + +#include "gpowerprofilemonitor.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "ginitable.h" +#include "gioenumtypes.h" +#include "giomodule-priv.h" +#include "gtask.h" + +/** + * SECTION:gpowerprofilemonitor + * @title: GPowerProfileMonitor + * @short_description: Power profile monitor + * @include: gio/gio.h + * + * #GPowerProfileMonitor makes it possible for applications as well as OS components + * to monitor system power profiles and act upon them. It currently only exports + * whether the system is in “Power Saver†mode (known as “Low Power†mode on + * some systems). + * + * When in “Low Power†mode, it is recommended that applications: + * - disable automatic downloads; + * - reduce the rate of refresh from online sources such as calendar or + * email synchronisation; + * - reduce the use of expensive visual effects. + * + * It is also likely that OS components providing services to applications will + * lower their own background activity, for the sake of the system. + * + * There are a variety of tools that exist for power consumption analysis, but those + * usually depend on the OS and hardware used. On Linux, one could use `upower` to + * monitor the battery discharge rate, `powertop` to check on the background activity + * or activity at all), `sysprof` to inspect CPU usage, and `intel_gpu_time` to + * profile GPU usage. + * + * Don't forget to disconnect the #GPowerProfileMonitor::notify::power-saver-enabled + * signal, and unref the #GPowerProfileMonitor itself when exiting. + * + * Since: 2.70 + */ + +/** + * GPowerProfileMonitor: + * + * #GPowerProfileMonitor monitors system power profile and notifies on + * changes. + * + * Since: 2.70 + */ + +/** + * GPowerProfileMonitorInterface: + * @g_iface: The parent interface. + * + * The virtual function table for #GPowerProfileMonitor. + * + * Since: 2.70 + */ + +G_DEFINE_INTERFACE_WITH_CODE (GPowerProfileMonitor, g_power_profile_monitor, G_TYPE_OBJECT, + g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE)) + + +/** + * g_power_profile_monitor_dup_default: + * + * Gets a reference to the default #GPowerProfileMonitor for the system. + * + * Returns: (not nullable) (transfer full): a new reference to the default #GPowerProfileMonitor + * + * Since: 2.70 + */ +GPowerProfileMonitor * +g_power_profile_monitor_dup_default (void) +{ + return g_object_ref (_g_io_module_get_default (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME, + "GIO_USE_POWER_PROFILE_MONITOR", + NULL)); +} + +/** + * g_power_profile_monitor_get_power_saver_enabled: + * @monitor: a #GPowerProfileMonitor + * + * Gets whether the system is in “Power Saver†mode. + * + * You are expected to listen to the + * #GPowerProfileMonitor::notify::power-saver-enabled signal to know when the profile has + * changed. + * + * Returns: Whether the system is in “Power Saver†mode. + * + * Since: 2.70 + */ +gboolean +g_power_profile_monitor_get_power_saver_enabled (GPowerProfileMonitor *monitor) +{ + gboolean enabled; + g_object_get (monitor, "power-saver-enabled", &enabled, NULL); + return enabled; +} + +static void +g_power_profile_monitor_default_init (GPowerProfileMonitorInterface *iface) +{ + /** + * GPowerProfileMonitor:power-saver-enabled: + * + * Whether “Power Saver†mode is enabled on the system. + * + * Since: 2.70 + */ + g_object_interface_install_property (iface, + g_param_spec_boolean ("power-saver-enabled", + "power-saver-enabled", + "Power Saver Enabled", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); +} diff --git a/gio/gpowerprofilemonitor.h b/gio/gpowerprofilemonitor.h new file mode 100644 index 0000000..0891fc3 --- /dev/null +++ b/gio/gpowerprofilemonitor.h @@ -0,0 +1,63 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * Copyright 2021 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_POWER_PROFILE_MONITOR_H__ +#define __G_POWER_PROFILE_MONITOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME: + * + * Extension point for power profile usage monitoring functionality. + * See [Extending GIO][extending-gio]. + * + * Since: 2.70 + */ +#define G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME "gio-power-profile-monitor" + +#define G_TYPE_POWER_PROFILE_MONITOR (g_power_profile_monitor_get_type ()) +GLIB_AVAILABLE_IN_2_70 +G_DECLARE_INTERFACE (GPowerProfileMonitor, g_power_profile_monitor, g, power_profile_monitor, GObject) + +#define G_POWER_PROFILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_POWER_PROFILE_MONITOR, GPowerProfileMonitor)) +#define G_IS_POWER_PROFILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_POWER_PROFILE_MONITOR)) +#define G_POWER_PROFILE_MONITOR_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_POWER_PROFILE_MONITOR, GPowerProfileMonitorInterface)) + +struct _GPowerProfileMonitorInterface +{ + /*< private >*/ + GTypeInterface g_iface; +}; + +GLIB_AVAILABLE_IN_2_70 +GPowerProfileMonitor *g_power_profile_monitor_dup_default (void); + +GLIB_AVAILABLE_IN_2_70 +gboolean g_power_profile_monitor_get_power_saver_enabled (GPowerProfileMonitor *monitor); + +G_END_DECLS + +#endif /* __G_POWER_PROFILE_MONITOR_H__ */ diff --git a/gio/gpowerprofilemonitordbus.c b/gio/gpowerprofilemonitordbus.c new file mode 100644 index 0000000..cbd9f4a --- /dev/null +++ b/gio/gpowerprofilemonitordbus.c @@ -0,0 +1,242 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * Copyrgith 2021 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gpowerprofilemonitor.h" +#include "gpowerprofilemonitordbus.h" +#include "gioerror.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "glibintl.h" +#include "glib/gstdio.h" +#include "gcancellable.h" +#include "gdbusproxy.h" +#include "gdbusnamewatching.h" + +#define G_POWER_PROFILE_MONITOR_DBUS_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + +static void g_power_profile_monitor_dbus_iface_init (GPowerProfileMonitorInterface *iface); +static void g_power_profile_monitor_dbus_initable_iface_init (GInitableIface *iface); + +struct _GPowerProfileMonitorDBus +{ + GObject parent_instance; + + guint watch_id; + GCancellable *cancellable; + GDBusProxy *proxy; + gulong signal_id; + + gboolean power_saver_enabled; +}; + +typedef enum +{ + PROP_POWER_SAVER_ENABLED = 1, +} GPowerProfileMonitorDBusProperty; + +#define POWERPROFILES_DBUS_NAME "net.hadess.PowerProfiles" +#define POWERPROFILES_DBUS_IFACE "net.hadess.PowerProfiles" +#define POWERPROFILES_DBUS_PATH "/net/hadess/PowerProfiles" + +G_DEFINE_TYPE_WITH_CODE (GPowerProfileMonitorDBus, g_power_profile_monitor_dbus, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_power_profile_monitor_dbus_initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_POWER_PROFILE_MONITOR, + g_power_profile_monitor_dbus_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "dbus", + 30)) + +static void +g_power_profile_monitor_dbus_init (GPowerProfileMonitorDBus *dbus) +{ + dbus->power_saver_enabled = FALSE; +} + +static void +ppd_properties_changed_cb (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv *invalidated_properties, + gpointer user_data) +{ + GPowerProfileMonitorDBus *dbus = user_data; + const char *active_profile; + gboolean enabled; + + if (!g_variant_lookup (changed_properties, "ActiveProfile", "&s", &active_profile)) + return; + + enabled = g_strcmp0 (active_profile, "power-saver") == 0; + if (enabled == dbus->power_saver_enabled) + return; + + dbus->power_saver_enabled = enabled; + g_object_notify (G_OBJECT (dbus), "power-saver-enabled"); +} + +static void +ppd_proxy_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GPowerProfileMonitorDBus *dbus = user_data; + GVariant *active_profile_variant; + GDBusProxy *proxy; + GError *error = NULL; + const char *active_profile; + gboolean power_saver_enabled; + + proxy = g_dbus_proxy_new_finish (res, &error); + if (!proxy) + { + g_debug ("GPowerProfileMonitorDBus: Failed to create PowerProfiles D-Bus proxy: %s", + error->message); + g_error_free (error); + return; + } + + active_profile_variant = g_dbus_proxy_get_cached_property (proxy, "ActiveProfile"); + if (active_profile_variant != NULL && + g_variant_is_of_type (active_profile_variant, G_VARIANT_TYPE_STRING)) + { + active_profile = g_variant_get_string (active_profile_variant, NULL); + power_saver_enabled = g_strcmp0 (active_profile, "power-saver") == 0; + if (power_saver_enabled != dbus->power_saver_enabled) + { + dbus->power_saver_enabled = power_saver_enabled; + g_object_notify (G_OBJECT (dbus), "power-saver-enabled"); + } + } + g_clear_pointer (&active_profile_variant, g_variant_unref); + + dbus->signal_id = g_signal_connect (G_OBJECT (proxy), "g-properties-changed", + G_CALLBACK (ppd_properties_changed_cb), dbus); + dbus->proxy = g_steal_pointer (&proxy); +} + +static void +ppd_appeared_cb (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + GPowerProfileMonitorDBus *dbus = user_data; + + g_dbus_proxy_new (connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + POWERPROFILES_DBUS_NAME, + POWERPROFILES_DBUS_PATH, + POWERPROFILES_DBUS_IFACE, + dbus->cancellable, + ppd_proxy_cb, + dbus); +} + +static void +ppd_vanished_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GPowerProfileMonitorDBus *dbus = user_data; + + g_clear_signal_handler (&dbus->signal_id, dbus->proxy); + g_clear_object (&dbus->proxy); + + dbus->power_saver_enabled = FALSE; + g_object_notify (G_OBJECT (dbus), "power-saver-enabled"); +} + +static void +g_power_profile_monitor_dbus_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (object); + + switch ((GPowerProfileMonitorDBusProperty) prop_id) + { + case PROP_POWER_SAVER_ENABLED: + g_value_set_boolean (value, dbus->power_saver_enabled); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static gboolean +g_power_profile_monitor_dbus_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (initable); + + dbus->cancellable = g_cancellable_new (); + dbus->watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, + POWERPROFILES_DBUS_NAME, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + ppd_appeared_cb, + ppd_vanished_cb, + dbus, + NULL); + + return TRUE; +} + +static void +g_power_profile_monitor_dbus_finalize (GObject *object) +{ + GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (object); + + g_cancellable_cancel (dbus->cancellable); + g_clear_object (&dbus->cancellable); + g_clear_signal_handler (&dbus->signal_id, dbus->proxy); + g_clear_object (&dbus->proxy); + g_clear_handle_id (&dbus->watch_id, g_bus_unwatch_name); + + G_OBJECT_CLASS (g_power_profile_monitor_dbus_parent_class)->finalize (object); +} + +static void +g_power_profile_monitor_dbus_class_init (GPowerProfileMonitorDBusClass *nl_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); + + gobject_class->get_property = g_power_profile_monitor_dbus_get_property; + gobject_class->finalize = g_power_profile_monitor_dbus_finalize; + + g_object_class_override_property (gobject_class, PROP_POWER_SAVER_ENABLED, "power-saver-enabled"); +} + +static void +g_power_profile_monitor_dbus_iface_init (GPowerProfileMonitorInterface *monitor_iface) +{ +} + +static void +g_power_profile_monitor_dbus_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_power_profile_monitor_dbus_initable_init; +} diff --git a/gio/gpowerprofilemonitordbus.h b/gio/gpowerprofilemonitordbus.h new file mode 100644 index 0000000..ecf7246 --- /dev/null +++ b/gio/gpowerprofilemonitordbus.h @@ -0,0 +1,32 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * Copyright 2021 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_POWER_PROFILE_MONITOR_DBUS_H__ +#define __G_POWER_PROFILE_MONITOR_DBUS_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_POWER_PROFILE_MONITOR_DBUS (g_power_profile_monitor_dbus_get_type ()) +G_DECLARE_FINAL_TYPE (GPowerProfileMonitorDBus, g_power_profile_monitor_dbus, G, POWER_PROFILE_MONITOR_DBUS, GObject) + +G_END_DECLS + +#endif /* __G_POWER_PROFILE_MONITOR_DBUS_H__ */ diff --git a/gio/gpowerprofilemonitorportal.c b/gio/gpowerprofilemonitorportal.c new file mode 100644 index 0000000..6bc251f --- /dev/null +++ b/gio/gpowerprofilemonitorportal.c @@ -0,0 +1,189 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2021 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gpowerprofilemonitor.h" +#include "gpowerprofilemonitorportal.h" +#include "gdbuserror.h" +#include "gdbusproxy.h" +#include "ginitable.h" +#include "gioerror.h" +#include "giomodule-priv.h" +#include "gportalsupport.h" + +#define G_POWER_PROFILE_MONITOR_PORTAL_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable)) + +static void g_power_profile_monitor_portal_iface_init (GPowerProfileMonitorInterface *iface); +static void g_power_profile_monitor_portal_initable_iface_init (GInitableIface *iface); + +typedef enum +{ + PROP_POWER_SAVER_ENABLED = 1, +} GPowerProfileMonitorPortalProperty; + +struct _GPowerProfileMonitorPortal +{ + GObject parent_instance; + + GDBusProxy *proxy; + gulong signal_id; + gboolean power_saver_enabled; +}; + +G_DEFINE_TYPE_WITH_CODE (GPowerProfileMonitorPortal, g_power_profile_monitor_portal, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_power_profile_monitor_portal_initable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_POWER_PROFILE_MONITOR, + g_power_profile_monitor_portal_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "portal", + 40)) + +static void +g_power_profile_monitor_portal_init (GPowerProfileMonitorPortal *portal) +{ +} + +static void +proxy_properties_changed (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + gpointer user_data) +{ + GPowerProfileMonitorPortal *ppm = user_data; + gboolean power_saver_enabled; + + if (!g_variant_lookup (changed_properties, "power-saver-enabled", "b", &power_saver_enabled)) + return; + + if (power_saver_enabled == ppm->power_saver_enabled) + return; + + ppm->power_saver_enabled = power_saver_enabled; + g_object_notify (G_OBJECT (ppm), "power-saver-enabled"); +} + +static void +g_power_profile_monitor_portal_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GPowerProfileMonitorPortal *ppm = G_POWER_PROFILE_MONITOR_PORTAL (object); + + switch ((GPowerProfileMonitorPortalProperty) prop_id) + { + case PROP_POWER_SAVER_ENABLED: + g_value_set_boolean (value, ppm->power_saver_enabled); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static gboolean +g_power_profile_monitor_portal_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GPowerProfileMonitorPortal *ppm = G_POWER_PROFILE_MONITOR_PORTAL (initable); + GDBusProxy *proxy; + gchar *name_owner; + GVariant *power_saver_enabled_v = NULL; + + if (!glib_should_use_portal ()) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not using portals"); + return FALSE; + } + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.PowerProfileMonitor", + cancellable, + error); + if (!proxy) + return FALSE; + + name_owner = g_dbus_proxy_get_name_owner (proxy); + + if (name_owner == NULL) + { + g_object_unref (proxy); + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_NAME_HAS_NO_OWNER, + "Desktop portal not found"); + return FALSE; + } + + g_free (name_owner); + + ppm->signal_id = g_signal_connect (proxy, "g-properties-changed", + G_CALLBACK (proxy_properties_changed), ppm); + + power_saver_enabled_v = g_dbus_proxy_get_cached_property (proxy, "power-saver-enabled"); + if (power_saver_enabled_v != NULL && + g_variant_is_of_type (power_saver_enabled_v, G_VARIANT_TYPE_BOOLEAN)) + ppm->power_saver_enabled = g_variant_get_boolean (power_saver_enabled_v); + g_clear_pointer (&power_saver_enabled_v, g_variant_unref); + + ppm->proxy = g_steal_pointer (&proxy); + + return TRUE; +} + +static void +g_power_profile_monitor_portal_finalize (GObject *object) +{ + GPowerProfileMonitorPortal *ppm = G_POWER_PROFILE_MONITOR_PORTAL (object); + + g_clear_signal_handler (&ppm->signal_id, ppm->proxy); + g_clear_object (&ppm->proxy); + + G_OBJECT_CLASS (g_power_profile_monitor_portal_parent_class)->finalize (object); +} + +static void +g_power_profile_monitor_portal_class_init (GPowerProfileMonitorPortalClass *nl_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class); + + gobject_class->get_property = g_power_profile_monitor_portal_get_property; + gobject_class->finalize = g_power_profile_monitor_portal_finalize; + + g_object_class_override_property (gobject_class, PROP_POWER_SAVER_ENABLED, "power-saver-enabled"); +} + +static void +g_power_profile_monitor_portal_iface_init (GPowerProfileMonitorInterface *monitor_iface) +{ +} + +static void +g_power_profile_monitor_portal_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_power_profile_monitor_portal_initable_init; +} diff --git a/gio/gpowerprofilemonitorportal.h b/gio/gpowerprofilemonitorportal.h new file mode 100644 index 0000000..b91a146 --- /dev/null +++ b/gio/gpowerprofilemonitorportal.h @@ -0,0 +1,31 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2021 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_POWER_PROFILE_MONITOR_PORTAL_H__ +#define __G_POWER_PROFILE_MONITOR_PORTAL_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_POWER_PROFILE_MONITOR_PORTAL (g_power_profile_monitor_portal_get_type ()) +G_DECLARE_FINAL_TYPE (GPowerProfileMonitorPortal, g_power_profile_monitor_portal, G, POWER_PROFILE_MONITOR_PORTAL, GObject) + +G_END_DECLS + +#endif /* __G_POWER_PROFILE_MONITOR_PORTAL_H__ */ diff --git a/gio/gpropertyaction.c b/gio/gpropertyaction.c new file mode 100644 index 0000000..9ce9ab5 --- /dev/null +++ b/gio/gpropertyaction.c @@ -0,0 +1,620 @@ +/* + * Copyright © 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gpropertyaction.h" + +#include "gsettings-mapping.h" +#include "gaction.h" +#include "glibintl.h" + +/** + * SECTION:gpropertyaction + * @title: GPropertyAction + * @short_description: A GAction reflecting a GObject property + * @include: gio/gio.h + * + * A #GPropertyAction is a way to get a #GAction with a state value + * reflecting and controlling the value of a #GObject property. + * + * The state of the action will correspond to the value of the property. + * Changing it will change the property (assuming the requested value + * matches the requirements as specified in the #GParamSpec). + * + * Only the most common types are presently supported. Booleans are + * mapped to booleans, strings to strings, signed/unsigned integers to + * int32/uint32 and floats and doubles to doubles. + * + * If the property is an enum then the state will be string-typed and + * conversion will automatically be performed between the enum value and + * "nick" string as per the #GEnumValue table. + * + * Flags types are not currently supported. + * + * Properties of object types, boxed types and pointer types are not + * supported and probably never will be. + * + * Properties of #GVariant types are not currently supported. + * + * If the property is boolean-valued then the action will have a NULL + * parameter type, and activating the action (with no parameter) will + * toggle the value of the property. + * + * In all other cases, the parameter type will correspond to the type of + * the property. + * + * The general idea here is to reduce the number of locations where a + * particular piece of state is kept (and therefore has to be synchronised + * between). #GPropertyAction does not have a separate state that is kept + * in sync with the property value -- its state is the property value. + * + * For example, it might be useful to create a #GAction corresponding to + * the "visible-child-name" property of a #GtkStack so that the current + * page can be switched from a menu. The active radio indication in the + * menu is then directly determined from the active page of the + * #GtkStack. + * + * An anti-example would be binding the "active-id" property on a + * #GtkComboBox. This is because the state of the combobox itself is + * probably uninteresting and is actually being used to control + * something else. + * + * Another anti-example would be to bind to the "visible-child-name" + * property of a #GtkStack if this value is actually stored in + * #GSettings. In that case, the real source of the value is + * #GSettings. If you want a #GAction to control a setting stored in + * #GSettings, see g_settings_create_action() instead, and possibly + * combine its use with g_settings_bind(). + * + * Since: 2.38 + **/ +struct _GPropertyAction +{ + GObject parent_instance; + + gchar *name; + gpointer object; + GParamSpec *pspec; + const GVariantType *state_type; + gboolean invert_boolean; +}; + +/** + * GPropertyAction: + * + * This type is opaque. + * + * Since: 2.38 + **/ + +typedef GObjectClass GPropertyActionClass; + +static void g_property_action_iface_init (GActionInterface *iface); +G_DEFINE_TYPE_WITH_CODE (GPropertyAction, g_property_action, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_property_action_iface_init)) + +enum +{ + PROP_NONE, + PROP_NAME, + PROP_PARAMETER_TYPE, + PROP_ENABLED, + PROP_STATE_TYPE, + PROP_STATE, + PROP_OBJECT, + PROP_PROPERTY_NAME, + PROP_INVERT_BOOLEAN +}; + +static gboolean +g_property_action_get_invert_boolean (GAction *action) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + + return paction->invert_boolean; +} + +static const gchar * +g_property_action_get_name (GAction *action) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + + return paction->name; +} + +static const GVariantType * +g_property_action_get_parameter_type (GAction *action) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + + return paction->pspec->value_type == G_TYPE_BOOLEAN ? NULL : paction->state_type; +} + +static const GVariantType * +g_property_action_get_state_type (GAction *action) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + + return paction->state_type; +} + +static GVariant * +g_property_action_get_state_hint (GAction *action) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + + if (paction->pspec->value_type == G_TYPE_INT) + { + GParamSpecInt *pspec = (GParamSpecInt *)paction->pspec; + return g_variant_new ("(ii)", pspec->minimum, pspec->maximum); + } + else if (paction->pspec->value_type == G_TYPE_UINT) + { + GParamSpecUInt *pspec = (GParamSpecUInt *)paction->pspec; + return g_variant_new ("(uu)", pspec->minimum, pspec->maximum); + } + else if (paction->pspec->value_type == G_TYPE_FLOAT) + { + GParamSpecFloat *pspec = (GParamSpecFloat *)paction->pspec; + return g_variant_new ("(dd)", (double)pspec->minimum, (double)pspec->maximum); + } + else if (paction->pspec->value_type == G_TYPE_DOUBLE) + { + GParamSpecDouble *pspec = (GParamSpecDouble *)paction->pspec; + return g_variant_new ("(dd)", pspec->minimum, pspec->maximum); + } + + return NULL; +} + +static gboolean +g_property_action_get_enabled (GAction *action) +{ + return TRUE; +} + +static void +g_property_action_set_state (GPropertyAction *paction, + GVariant *variant) +{ + GValue value = G_VALUE_INIT; + + g_value_init (&value, paction->pspec->value_type); + g_settings_get_mapping (&value, variant, NULL); + + if (paction->pspec->value_type == G_TYPE_BOOLEAN && paction->invert_boolean) + g_value_set_boolean (&value, !g_value_get_boolean (&value)); + + g_object_set_property (paction->object, paction->pspec->name, &value); + g_value_unset (&value); +} + +static void +g_property_action_change_state (GAction *action, + GVariant *value) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + + g_return_if_fail (g_variant_is_of_type (value, paction->state_type)); + + g_property_action_set_state (paction, value); +} + +static GVariant * +g_property_action_get_state (GAction *action) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + GValue value = G_VALUE_INIT; + GVariant *result; + + g_value_init (&value, paction->pspec->value_type); + g_object_get_property (paction->object, paction->pspec->name, &value); + + if (paction->pspec->value_type == G_TYPE_BOOLEAN && paction->invert_boolean) + g_value_set_boolean (&value, !g_value_get_boolean (&value)); + + result = g_settings_set_mapping (&value, paction->state_type, NULL); + g_value_unset (&value); + + return g_variant_ref_sink (result); +} + +static void +g_property_action_activate (GAction *action, + GVariant *parameter) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (action); + + if (paction->pspec->value_type == G_TYPE_BOOLEAN) + { + gboolean value; + + g_return_if_fail (paction->pspec->value_type == G_TYPE_BOOLEAN && parameter == NULL); + + g_object_get (paction->object, paction->pspec->name, &value, NULL); + value = !value; + g_object_set (paction->object, paction->pspec->name, value, NULL); + } + else + { + g_return_if_fail (parameter != NULL && g_variant_is_of_type (parameter, paction->state_type)); + + g_property_action_set_state (paction, parameter); + } +} + +static const GVariantType * +g_property_action_determine_type (GParamSpec *pspec) +{ + if (G_TYPE_IS_ENUM (pspec->value_type)) + return G_VARIANT_TYPE_STRING; + + switch (pspec->value_type) + { + case G_TYPE_BOOLEAN: + return G_VARIANT_TYPE_BOOLEAN; + + case G_TYPE_INT: + return G_VARIANT_TYPE_INT32; + + case G_TYPE_UINT: + return G_VARIANT_TYPE_UINT32; + + case G_TYPE_DOUBLE: + case G_TYPE_FLOAT: + return G_VARIANT_TYPE_DOUBLE; + + case G_TYPE_STRING: + return G_VARIANT_TYPE_STRING; + + default: + g_critical ("Unable to use GPropertyAction with property '%s::%s' of type '%s'", + g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->value_type)); + return NULL; + } +} + +static void +g_property_action_notify (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + GPropertyAction *paction = user_data; + + g_assert (object == paction->object); + g_assert (pspec == paction->pspec); + + g_object_notify (G_OBJECT (paction), "state"); +} + +static void +g_property_action_set_property_name (GPropertyAction *paction, + const gchar *property_name) +{ + GParamSpec *pspec; + gchar *detailed; + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (paction->object), property_name); + + if (pspec == NULL) + { + g_critical ("Attempted to use non-existent property '%s::%s' for GPropertyAction", + G_OBJECT_TYPE_NAME (paction->object), property_name); + return; + } + + if (~pspec->flags & G_PARAM_READABLE || ~pspec->flags & G_PARAM_WRITABLE || pspec->flags & G_PARAM_CONSTRUCT_ONLY) + { + g_critical ("Property '%s::%s' used with GPropertyAction must be readable, writable, and not construct-only", + G_OBJECT_TYPE_NAME (paction->object), property_name); + return; + } + + paction->pspec = pspec; + + detailed = g_strconcat ("notify::", paction->pspec->name, NULL); + paction->state_type = g_property_action_determine_type (paction->pspec); + g_signal_connect (paction->object, detailed, G_CALLBACK (g_property_action_notify), paction); + g_free (detailed); +} + +static void +g_property_action_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (object); + + switch (prop_id) + { + case PROP_NAME: + paction->name = g_value_dup_string (value); + break; + + case PROP_OBJECT: + paction->object = g_value_dup_object (value); + break; + + case PROP_PROPERTY_NAME: + g_property_action_set_property_name (paction, g_value_get_string (value)); + break; + + case PROP_INVERT_BOOLEAN: + paction->invert_boolean = g_value_get_boolean (value); + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_property_action_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GAction *action = G_ACTION (object); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, g_property_action_get_name (action)); + break; + + case PROP_PARAMETER_TYPE: + g_value_set_boxed (value, g_property_action_get_parameter_type (action)); + break; + + case PROP_ENABLED: + g_value_set_boolean (value, g_property_action_get_enabled (action)); + break; + + case PROP_STATE_TYPE: + g_value_set_boxed (value, g_property_action_get_state_type (action)); + break; + + case PROP_STATE: + g_value_take_variant (value, g_property_action_get_state (action)); + break; + + case PROP_INVERT_BOOLEAN: + g_value_set_boolean (value, g_property_action_get_invert_boolean (action)); + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_property_action_finalize (GObject *object) +{ + GPropertyAction *paction = G_PROPERTY_ACTION (object); + + g_signal_handlers_disconnect_by_func (paction->object, g_property_action_notify, paction); + g_object_unref (paction->object); + g_free (paction->name); + + G_OBJECT_CLASS (g_property_action_parent_class) + ->finalize (object); +} + +void +g_property_action_init (GPropertyAction *property) +{ +} + +void +g_property_action_iface_init (GActionInterface *iface) +{ + iface->get_name = g_property_action_get_name; + iface->get_parameter_type = g_property_action_get_parameter_type; + iface->get_state_type = g_property_action_get_state_type; + iface->get_state_hint = g_property_action_get_state_hint; + iface->get_enabled = g_property_action_get_enabled; + iface->get_state = g_property_action_get_state; + iface->change_state = g_property_action_change_state; + iface->activate = g_property_action_activate; +} + +void +g_property_action_class_init (GPropertyActionClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->set_property = g_property_action_set_property; + object_class->get_property = g_property_action_get_property; + object_class->finalize = g_property_action_finalize; + + /** + * GPropertyAction:name: + * + * The name of the action. This is mostly meaningful for identifying + * the action once it has been added to a #GActionMap. + * + * Since: 2.38 + **/ + g_object_class_install_property (object_class, PROP_NAME, + g_param_spec_string ("name", + P_("Action Name"), + P_("The name used to invoke the action"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GPropertyAction:parameter-type: + * + * The type of the parameter that must be given when activating the + * action. + * + * Since: 2.38 + **/ + g_object_class_install_property (object_class, PROP_PARAMETER_TYPE, + g_param_spec_boxed ("parameter-type", + P_("Parameter Type"), + P_("The type of GVariant passed to activate()"), + G_TYPE_VARIANT_TYPE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GPropertyAction:enabled: + * + * If @action is currently enabled. + * + * If the action is disabled then calls to g_action_activate() and + * g_action_change_state() have no effect. + * + * Since: 2.38 + **/ + g_object_class_install_property (object_class, PROP_ENABLED, + g_param_spec_boolean ("enabled", + P_("Enabled"), + P_("If the action can be activated"), + TRUE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GPropertyAction:state-type: + * + * The #GVariantType of the state that the action has, or %NULL if the + * action is stateless. + * + * Since: 2.38 + **/ + g_object_class_install_property (object_class, PROP_STATE_TYPE, + g_param_spec_boxed ("state-type", + P_("State Type"), + P_("The type of the state kept by the action"), + G_TYPE_VARIANT_TYPE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GPropertyAction:state: + * + * The state of the action, or %NULL if the action is stateless. + * + * Since: 2.38 + **/ + g_object_class_install_property (object_class, PROP_STATE, + g_param_spec_variant ("state", + P_("State"), + P_("The state the action is in"), + G_VARIANT_TYPE_ANY, + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GPropertyAction:object: + * + * The object to wrap a property on. + * + * The object must be a non-%NULL #GObject with properties. + * + * Since: 2.38 + **/ + g_object_class_install_property (object_class, PROP_OBJECT, + g_param_spec_object ("object", + P_("Object"), + P_("The object with the property to wrap"), + G_TYPE_OBJECT, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GPropertyAction:property-name: + * + * The name of the property to wrap on the object. + * + * The property must exist on the passed-in object and it must be + * readable and writable (and not construct-only). + * + * Since: 2.38 + **/ + g_object_class_install_property (object_class, PROP_PROPERTY_NAME, + g_param_spec_string ("property-name", + P_("Property name"), + P_("The name of the property to wrap"), + NULL, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GPropertyAction:invert-boolean: + * + * If %TRUE, the state of the action will be the negation of the + * property value, provided the property is boolean. + * + * Since: 2.46 + */ + g_object_class_install_property (object_class, PROP_INVERT_BOOLEAN, + g_param_spec_boolean ("invert-boolean", + P_("Invert boolean"), + P_("Whether to invert the value of a boolean property"), + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_property_action_new: + * @name: the name of the action to create + * @object: (type GObject.Object): the object that has the property + * to wrap + * @property_name: the name of the property + * + * Creates a #GAction corresponding to the value of property + * @property_name on @object. + * + * The property must be existent and readable and writable (and not + * construct-only). + * + * This function takes a reference on @object and doesn't release it + * until the action is destroyed. + * + * Returns: a new #GPropertyAction + * + * Since: 2.38 + **/ +GPropertyAction * +g_property_action_new (const gchar *name, + gpointer object, + const gchar *property_name) +{ + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + + return g_object_new (G_TYPE_PROPERTY_ACTION, + "name", name, + "object", object, + "property-name", property_name, + NULL); +} diff --git a/gio/gpropertyaction.h b/gio/gpropertyaction.h new file mode 100644 index 0000000..6fb4e63 --- /dev/null +++ b/gio/gpropertyaction.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_PROPERTY_ACTION_H__ +#define __G_PROPERTY_ACTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_PROPERTY_ACTION (g_property_action_get_type ()) +#define G_PROPERTY_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_PROPERTY_ACTION, GPropertyAction)) +#define G_IS_PROPERTY_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_PROPERTY_ACTION)) + +GLIB_AVAILABLE_IN_2_38 +GType g_property_action_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_38 +GPropertyAction * g_property_action_new (const gchar *name, + gpointer object, + const gchar *property_name); + +G_END_DECLS + +#endif /* __G_PROPERTY_ACTION_H__ */ diff --git a/gio/gproxy.c b/gio/gproxy.c new file mode 100644 index 0000000..4c80a47 --- /dev/null +++ b/gio/gproxy.c @@ -0,0 +1,208 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#include "config.h" + +#include "gproxy.h" + +#include "giomodule.h" +#include "giomodule-priv.h" +#include "glibintl.h" + +/** + * SECTION:gproxy + * @short_description: Interface for proxy handling + * @include: gio/gio.h + * + * A #GProxy handles connecting to a remote host via a given type of + * proxy server. It is implemented by the 'gio-proxy' extension point. + * The extensions are named after their proxy protocol name. As an + * example, a SOCKS5 proxy implementation can be retrieved with the + * name 'socks5' using the function + * g_io_extension_point_get_extension_by_name(). + * + * Since: 2.26 + **/ + +G_DEFINE_INTERFACE (GProxy, g_proxy, G_TYPE_OBJECT) + +static void +g_proxy_default_init (GProxyInterface *iface) +{ +} + +/** + * g_proxy_get_default_for_protocol: + * @protocol: the proxy protocol name (e.g. http, socks, etc) + * + * Find the `gio-proxy` extension point for a proxy implementation that supports + * the specified protocol. + * + * Returns: (nullable) (transfer full): return a #GProxy or NULL if protocol + * is not supported. + * + * Since: 2.26 + **/ +GProxy * +g_proxy_get_default_for_protocol (const gchar *protocol) +{ + GIOExtensionPoint *ep; + GIOExtension *extension; + + /* Ensure proxy modules loaded */ + _g_io_modules_ensure_loaded (); + + ep = g_io_extension_point_lookup (G_PROXY_EXTENSION_POINT_NAME); + + extension = g_io_extension_point_get_extension_by_name (ep, protocol); + + if (extension) + return g_object_new (g_io_extension_get_type (extension), NULL); + + return NULL; +} + +/** + * g_proxy_connect: + * @proxy: a #GProxy + * @connection: a #GIOStream + * @proxy_address: a #GProxyAddress + * @cancellable: (nullable): a #GCancellable + * @error: return #GError + * + * Given @connection to communicate with a proxy (eg, a + * #GSocketConnection that is connected to the proxy server), this + * does the necessary handshake to connect to @proxy_address, and if + * required, wraps the #GIOStream to handle proxy payload. + * + * Returns: (transfer full): a #GIOStream that will replace @connection. This might + * be the same as @connection, in which case a reference + * will be added. + * + * Since: 2.26 + */ +GIOStream * +g_proxy_connect (GProxy *proxy, + GIOStream *connection, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GError **error) +{ + GProxyInterface *iface; + + g_return_val_if_fail (G_IS_PROXY (proxy), NULL); + + iface = G_PROXY_GET_IFACE (proxy); + + return (* iface->connect) (proxy, + connection, + proxy_address, + cancellable, + error); +} + +/** + * g_proxy_connect_async: + * @proxy: a #GProxy + * @connection: a #GIOStream + * @proxy_address: a #GProxyAddress + * @cancellable: (nullable): a #GCancellable + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): callback data + * + * Asynchronous version of g_proxy_connect(). + * + * Since: 2.26 + */ +void +g_proxy_connect_async (GProxy *proxy, + GIOStream *connection, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GProxyInterface *iface; + + g_return_if_fail (G_IS_PROXY (proxy)); + + iface = G_PROXY_GET_IFACE (proxy); + + (* iface->connect_async) (proxy, + connection, + proxy_address, + cancellable, + callback, + user_data); +} + +/** + * g_proxy_connect_finish: + * @proxy: a #GProxy + * @result: a #GAsyncResult + * @error: return #GError + * + * See g_proxy_connect(). + * + * Returns: (transfer full): a #GIOStream. + * + * Since: 2.26 + */ +GIOStream * +g_proxy_connect_finish (GProxy *proxy, + GAsyncResult *result, + GError **error) +{ + GProxyInterface *iface; + + g_return_val_if_fail (G_IS_PROXY (proxy), NULL); + + iface = G_PROXY_GET_IFACE (proxy); + + return (* iface->connect_finish) (proxy, result, error); +} + +/** + * g_proxy_supports_hostname: + * @proxy: a #GProxy + * + * Some proxy protocols expect to be passed a hostname, which they + * will resolve to an IP address themselves. Others, like SOCKS4, do + * not allow this. This function will return %FALSE if @proxy is + * implementing such a protocol. When %FALSE is returned, the caller + * should resolve the destination hostname first, and then pass a + * #GProxyAddress containing the stringified IP address to + * g_proxy_connect() or g_proxy_connect_async(). + * + * Returns: %TRUE if hostname resolution is supported. + * + * Since: 2.26 + */ +gboolean +g_proxy_supports_hostname (GProxy *proxy) +{ + GProxyInterface *iface; + + g_return_val_if_fail (G_IS_PROXY (proxy), FALSE); + + iface = G_PROXY_GET_IFACE (proxy); + + return (* iface->supports_hostname) (proxy); +} diff --git a/gio/gproxy.h b/gio/gproxy.h new file mode 100644 index 0000000..5589f21 --- /dev/null +++ b/gio/gproxy.h @@ -0,0 +1,128 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#ifndef __G_PROXY_H__ +#define __G_PROXY_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_PROXY (g_proxy_get_type ()) +#define G_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_PROXY, GProxy)) +#define G_IS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_PROXY)) +#define G_PROXY_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_PROXY, GProxyInterface)) + +/** + * G_PROXY_EXTENSION_POINT_NAME: + * + * Extension point for proxy functionality. + * See [Extending GIO][extending-gio]. + * + * Since: 2.26 + */ +#define G_PROXY_EXTENSION_POINT_NAME "gio-proxy" + +/** + * GProxy: + * + * Interface that handles proxy connection and payload. + * + * Since: 2.26 + */ +typedef struct _GProxyInterface GProxyInterface; + +/** + * GProxyInterface: + * @g_iface: The parent interface. + * @connect: Connect to proxy server and wrap (if required) the #connection + * to handle payload. + * @connect_async: Same as connect() but asynchronous. + * @connect_finish: Returns the result of connect_async() + * @supports_hostname: Returns whether the proxy supports hostname lookups. + * + * Provides an interface for handling proxy connection and payload. + * + * Since: 2.26 + */ +struct _GProxyInterface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + GIOStream * (* connect) (GProxy *proxy, + GIOStream *connection, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GError **error); + + void (* connect_async) (GProxy *proxy, + GIOStream *connection, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + GIOStream * (* connect_finish) (GProxy *proxy, + GAsyncResult *result, + GError **error); + + gboolean (* supports_hostname) (GProxy *proxy); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_proxy_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GProxy *g_proxy_get_default_for_protocol (const gchar *protocol); + +GLIB_AVAILABLE_IN_ALL +GIOStream *g_proxy_connect (GProxy *proxy, + GIOStream *connection, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_proxy_connect_async (GProxy *proxy, + GIOStream *connection, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GIOStream *g_proxy_connect_finish (GProxy *proxy, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_proxy_supports_hostname (GProxy *proxy); + +G_END_DECLS + +#endif /* __G_PROXY_H__ */ diff --git a/gio/gproxyaddress.c b/gio/gproxyaddress.c new file mode 100644 index 0000000..a9405eb --- /dev/null +++ b/gio/gproxyaddress.c @@ -0,0 +1,453 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Nicolas Dufresne + */ + +#include +#include +#include + +#include + +#include "gproxyaddress.h" +#include "glibintl.h" + +/** + * SECTION:gproxyaddress + * @short_description: An internet address with proxy information + * @include: gio/gio.h + * + * Support for proxied #GInetSocketAddress. + */ + +/** + * GProxyAddress: + * + * A #GInetSocketAddress representing a connection via a proxy server + * + * Since: 2.26 + **/ + +/** + * GProxyAddressClass: + * + * Class structure for #GProxyAddress. + * + * Since: 2.26 + **/ + +enum +{ + PROP_0, + PROP_PROTOCOL, + PROP_DESTINATION_PROTOCOL, + PROP_DESTINATION_HOSTNAME, + PROP_DESTINATION_PORT, + PROP_USERNAME, + PROP_PASSWORD, + PROP_URI +}; + +struct _GProxyAddressPrivate +{ + gchar *uri; + gchar *protocol; + gchar *username; + gchar *password; + gchar *dest_protocol; + gchar *dest_hostname; + guint16 dest_port; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GProxyAddress, g_proxy_address, G_TYPE_INET_SOCKET_ADDRESS) + +static void +g_proxy_address_finalize (GObject *object) +{ + GProxyAddress *proxy = G_PROXY_ADDRESS (object); + + g_free (proxy->priv->uri); + g_free (proxy->priv->protocol); + g_free (proxy->priv->username); + g_free (proxy->priv->password); + g_free (proxy->priv->dest_hostname); + g_free (proxy->priv->dest_protocol); + + G_OBJECT_CLASS (g_proxy_address_parent_class)->finalize (object); +} + +static void +g_proxy_address_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GProxyAddress *proxy = G_PROXY_ADDRESS (object); + + switch (prop_id) + { + case PROP_PROTOCOL: + g_free (proxy->priv->protocol); + proxy->priv->protocol = g_value_dup_string (value); + break; + + case PROP_DESTINATION_PROTOCOL: + g_free (proxy->priv->dest_protocol); + proxy->priv->dest_protocol = g_value_dup_string (value); + break; + + case PROP_DESTINATION_HOSTNAME: + g_free (proxy->priv->dest_hostname); + proxy->priv->dest_hostname = g_value_dup_string (value); + break; + + case PROP_DESTINATION_PORT: + proxy->priv->dest_port = g_value_get_uint (value); + break; + + case PROP_USERNAME: + g_free (proxy->priv->username); + proxy->priv->username = g_value_dup_string (value); + break; + + case PROP_PASSWORD: + g_free (proxy->priv->password); + proxy->priv->password = g_value_dup_string (value); + break; + + case PROP_URI: + g_free (proxy->priv->uri); + proxy->priv->uri = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_proxy_address_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GProxyAddress *proxy = G_PROXY_ADDRESS (object); + + switch (prop_id) + { + case PROP_PROTOCOL: + g_value_set_string (value, proxy->priv->protocol); + break; + + case PROP_DESTINATION_PROTOCOL: + g_value_set_string (value, proxy->priv->dest_protocol); + break; + + case PROP_DESTINATION_HOSTNAME: + g_value_set_string (value, proxy->priv->dest_hostname); + break; + + case PROP_DESTINATION_PORT: + g_value_set_uint (value, proxy->priv->dest_port); + break; + + case PROP_USERNAME: + g_value_set_string (value, proxy->priv->username); + break; + + case PROP_PASSWORD: + g_value_set_string (value, proxy->priv->password); + break; + + case PROP_URI: + g_value_set_string (value, proxy->priv->uri); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_proxy_address_class_init (GProxyAddressClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_proxy_address_finalize; + gobject_class->set_property = g_proxy_address_set_property; + gobject_class->get_property = g_proxy_address_get_property; + + g_object_class_install_property (gobject_class, + PROP_PROTOCOL, + g_param_spec_string ("protocol", + P_("Protocol"), + P_("The proxy protocol"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_USERNAME, + g_param_spec_string ("username", + P_("Username"), + P_("The proxy username"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_PASSWORD, + g_param_spec_string ("password", + P_("Password"), + P_("The proxy password"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GProxyAddress:destination-protocol: + * + * The protocol being spoke to the destination host, or %NULL if + * the #GProxyAddress doesn't know. + * + * Since: 2.34 + */ + g_object_class_install_property (gobject_class, + PROP_DESTINATION_PROTOCOL, + g_param_spec_string ("destination-protocol", + P_("Destination Protocol"), + P_("The proxy destination protocol"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_DESTINATION_HOSTNAME, + g_param_spec_string ("destination-hostname", + P_("Destination Hostname"), + P_("The proxy destination hostname"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_DESTINATION_PORT, + g_param_spec_uint ("destination-port", + P_("Destination Port"), + P_("The proxy destination port"), + 0, 65535, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GProxyAddress:uri: + * + * The URI string that the proxy was constructed from (or %NULL + * if the creator didn't specify this). + * + * Since: 2.34 + */ + g_object_class_install_property (gobject_class, + PROP_URI, + g_param_spec_string ("uri", + P_("URI"), + P_("The proxy’s URI"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_proxy_address_init (GProxyAddress *proxy) +{ + proxy->priv = g_proxy_address_get_instance_private (proxy); + proxy->priv->protocol = NULL; + proxy->priv->username = NULL; + proxy->priv->password = NULL; + proxy->priv->dest_hostname = NULL; + proxy->priv->dest_port = 0; +} + +/** + * g_proxy_address_new: + * @inetaddr: The proxy server #GInetAddress. + * @port: The proxy server port. + * @protocol: The proxy protocol to support, in lower case (e.g. socks, http). + * @dest_hostname: The destination hostname the proxy should tunnel to. + * @dest_port: The destination port to tunnel to. + * @username: (nullable): The username to authenticate to the proxy server + * (or %NULL). + * @password: (nullable): The password to authenticate to the proxy server + * (or %NULL). + * + * Creates a new #GProxyAddress for @inetaddr with @protocol that should + * tunnel through @dest_hostname and @dest_port. + * + * (Note that this method doesn't set the #GProxyAddress:uri or + * #GProxyAddress:destination-protocol fields; use g_object_new() + * directly if you want to set those.) + * + * Returns: a new #GProxyAddress + * + * Since: 2.26 + */ +GSocketAddress * +g_proxy_address_new (GInetAddress *inetaddr, + guint16 port, + const gchar *protocol, + const gchar *dest_hostname, + guint16 dest_port, + const gchar *username, + const gchar *password) +{ + return g_object_new (G_TYPE_PROXY_ADDRESS, + "address", inetaddr, + "port", port, + "protocol", protocol, + "destination-hostname", dest_hostname, + "destination-port", dest_port, + "username", username, + "password", password, + NULL); +} + + +/** + * g_proxy_address_get_protocol: + * @proxy: a #GProxyAddress + * + * Gets @proxy's protocol. eg, "socks" or "http" + * + * Returns: the @proxy's protocol + * + * Since: 2.26 + */ +const gchar * +g_proxy_address_get_protocol (GProxyAddress *proxy) +{ + return proxy->priv->protocol; +} + +/** + * g_proxy_address_get_destination_protocol: + * @proxy: a #GProxyAddress + * + * Gets the protocol that is being spoken to the destination + * server; eg, "http" or "ftp". + * + * Returns: the @proxy's destination protocol + * + * Since: 2.34 + */ +const gchar * +g_proxy_address_get_destination_protocol (GProxyAddress *proxy) +{ + return proxy->priv->dest_protocol; +} + +/** + * g_proxy_address_get_destination_hostname: + * @proxy: a #GProxyAddress + * + * Gets @proxy's destination hostname; that is, the name of the host + * that will be connected to via the proxy, not the name of the proxy + * itself. + * + * Returns: the @proxy's destination hostname + * + * Since: 2.26 + */ +const gchar * +g_proxy_address_get_destination_hostname (GProxyAddress *proxy) +{ + return proxy->priv->dest_hostname; +} + +/** + * g_proxy_address_get_destination_port: + * @proxy: a #GProxyAddress + * + * Gets @proxy's destination port; that is, the port on the + * destination host that will be connected to via the proxy, not the + * port number of the proxy itself. + * + * Returns: the @proxy's destination port + * + * Since: 2.26 + */ +guint16 +g_proxy_address_get_destination_port (GProxyAddress *proxy) +{ + return proxy->priv->dest_port; +} + +/** + * g_proxy_address_get_username: + * @proxy: a #GProxyAddress + * + * Gets @proxy's username. + * + * Returns: (nullable): the @proxy's username + * + * Since: 2.26 + */ +const gchar * +g_proxy_address_get_username (GProxyAddress *proxy) +{ + return proxy->priv->username; +} + +/** + * g_proxy_address_get_password: + * @proxy: a #GProxyAddress + * + * Gets @proxy's password. + * + * Returns: (nullable): the @proxy's password + * + * Since: 2.26 + */ +const gchar * +g_proxy_address_get_password (GProxyAddress *proxy) +{ + return proxy->priv->password; +} + + +/** + * g_proxy_address_get_uri: + * @proxy: a #GProxyAddress + * + * Gets the proxy URI that @proxy was constructed from. + * + * Returns: (nullable): the @proxy's URI, or %NULL if unknown + * + * Since: 2.34 + */ +const gchar * +g_proxy_address_get_uri (GProxyAddress *proxy) +{ + return proxy->priv->uri; +} diff --git a/gio/gproxyaddress.h b/gio/gproxyaddress.h new file mode 100644 index 0000000..21b1992 --- /dev/null +++ b/gio/gproxyaddress.h @@ -0,0 +1,86 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Nicolas Dufresne + */ + +#ifndef __G_PROXY_ADDRESS_H__ +#define __G_PROXY_ADDRESS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_PROXY_ADDRESS (g_proxy_address_get_type ()) +#define G_PROXY_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_PROXY_ADDRESS, GProxyAddress)) +#define G_PROXY_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_PROXY_ADDRESS, GProxyAddressClass)) +#define G_IS_PROXY_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_PROXY_ADDRESS)) +#define G_IS_PROXY_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_PROXY_ADDRESS)) +#define G_PROXY_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_PROXY_ADDRESS, GProxyAddressClass)) + +typedef struct _GProxyAddressClass GProxyAddressClass; +typedef struct _GProxyAddressPrivate GProxyAddressPrivate; + +struct _GProxyAddress +{ + GInetSocketAddress parent_instance; + + /*< private >*/ + GProxyAddressPrivate *priv; +}; + +struct _GProxyAddressClass +{ + GInetSocketAddressClass parent_class; +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_proxy_address_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_proxy_address_new (GInetAddress *inetaddr, + guint16 port, + const gchar *protocol, + const gchar *dest_hostname, + guint16 dest_port, + const gchar *username, + const gchar *password); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_proxy_address_get_protocol (GProxyAddress *proxy); +GLIB_AVAILABLE_IN_2_34 +const gchar *g_proxy_address_get_destination_protocol (GProxyAddress *proxy); +GLIB_AVAILABLE_IN_ALL +const gchar *g_proxy_address_get_destination_hostname (GProxyAddress *proxy); +GLIB_AVAILABLE_IN_ALL +guint16 g_proxy_address_get_destination_port (GProxyAddress *proxy); +GLIB_AVAILABLE_IN_ALL +const gchar *g_proxy_address_get_username (GProxyAddress *proxy); +GLIB_AVAILABLE_IN_ALL +const gchar *g_proxy_address_get_password (GProxyAddress *proxy); + +GLIB_AVAILABLE_IN_2_34 +const gchar *g_proxy_address_get_uri (GProxyAddress *proxy); + +G_END_DECLS + +#endif /* __G_PROXY_ADDRESS_H__ */ diff --git a/gio/gproxyaddressenumerator.c b/gio/gproxyaddressenumerator.c new file mode 100644 index 0000000..de932ff --- /dev/null +++ b/gio/gproxyaddressenumerator.c @@ -0,0 +1,799 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#include "config.h" +#include "gproxyaddressenumerator.h" + +#include + +#include "gasyncresult.h" +#include "ginetaddress.h" +#include "gioerror.h" +#include "glibintl.h" +#include "gnetworkaddress.h" +#include "gnetworkingprivate.h" +#include "gproxy.h" +#include "gproxyaddress.h" +#include "gproxyresolver.h" +#include "gtask.h" +#include "gresolver.h" +#include "gsocketaddress.h" +#include "gsocketaddressenumerator.h" +#include "gsocketconnectable.h" + +/** + * SECTION:gproxyaddressenumerator + * @short_description: Proxy wrapper enumerator for socket addresses + * @include: gio/gio.h + * + * #GProxyAddressEnumerator is a wrapper around #GSocketAddressEnumerator which + * takes the #GSocketAddress instances returned by the #GSocketAddressEnumerator + * and wraps them in #GProxyAddress instances, using the given + * #GProxyAddressEnumerator:proxy-resolver. + * + * This enumerator will be returned (for example, by + * g_socket_connectable_enumerate()) as appropriate when a proxy is configured; + * there should be no need to manually wrap a #GSocketAddressEnumerator instance + * with one. + */ + +#define GET_PRIVATE(o) (G_PROXY_ADDRESS_ENUMERATOR (o)->priv) + +enum +{ + PROP_0, + PROP_URI, + PROP_DEFAULT_PORT, + PROP_CONNECTABLE, + PROP_PROXY_RESOLVER +}; + +struct _GProxyAddressEnumeratorPrivate +{ + /* Destination address */ + GSocketConnectable *connectable; + gchar *dest_uri; + guint16 default_port; + gchar *dest_hostname; + guint16 dest_port; + GList *dest_ips; + + /* Proxy enumeration */ + GProxyResolver *proxy_resolver; + gchar **proxies; + gchar **next_proxy; + GSocketAddressEnumerator *addr_enum; + GSocketAddress *proxy_address; + const gchar *proxy_uri; + gchar *proxy_type; + gchar *proxy_username; + gchar *proxy_password; + gboolean supports_hostname; + GList *next_dest_ip; + GError *last_error; + + /* ever_enumerated is TRUE after we've returned a result for the first time + * via g_proxy_address_enumerator_next() or _next_async(). If FALSE, we have + * never returned yet, and should return an error if returning NULL because + * it does not make sense for a proxy resolver to return NULL except on error. + * (Whereas a DNS resolver would return NULL with no error to indicate "no + * results", a proxy resolver would want to return "direct://" instead, so + * NULL without error does not make sense for us.) + * + * But if ever_enumerated is TRUE, then we must not report any further errors + * (except for G_IO_ERROR_CANCELLED), because this is an API contract of + * GSocketAddressEnumerator. + */ + gboolean ever_enumerated; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GProxyAddressEnumerator, g_proxy_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR) + +static void +save_userinfo (GProxyAddressEnumeratorPrivate *priv, + const gchar *proxy) +{ + g_clear_pointer (&priv->proxy_username, g_free); + g_clear_pointer (&priv->proxy_password, g_free); + + g_uri_split_with_user (proxy, G_URI_FLAGS_HAS_PASSWORD, NULL, + &priv->proxy_username, &priv->proxy_password, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); +} + +static void +next_enumerator (GProxyAddressEnumeratorPrivate *priv) +{ + if (priv->proxy_address) + return; + + while (priv->addr_enum == NULL && *priv->next_proxy) + { + GSocketConnectable *connectable = NULL; + GProxy *proxy; + + priv->proxy_uri = *priv->next_proxy++; + g_free (priv->proxy_type); + priv->proxy_type = g_uri_parse_scheme (priv->proxy_uri); + + if (priv->proxy_type == NULL) + continue; + + /* Assumes hostnames are supported for unknown protocols */ + priv->supports_hostname = TRUE; + proxy = g_proxy_get_default_for_protocol (priv->proxy_type); + if (proxy) + { + priv->supports_hostname = g_proxy_supports_hostname (proxy); + g_object_unref (proxy); + } + + if (strcmp ("direct", priv->proxy_type) == 0) + { + if (priv->connectable) + connectable = g_object_ref (priv->connectable); + else + connectable = g_network_address_new (priv->dest_hostname, + priv->dest_port); + } + else + { + GError *error = NULL; + + connectable = g_network_address_parse_uri (priv->proxy_uri, 0, &error); + + if (error) + { + g_warning ("Invalid proxy URI '%s': %s", + priv->proxy_uri, error->message); + g_error_free (error); + } + + save_userinfo (priv, priv->proxy_uri); + } + + if (connectable) + { + priv->addr_enum = g_socket_connectable_enumerate (connectable); + g_object_unref (connectable); + } + } +} + +static GSocketAddress * +g_proxy_address_enumerator_next (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (enumerator); + GSocketAddress *result = NULL; + GError *first_error = NULL; + + if (!priv->ever_enumerated) + { + g_assert (priv->proxies == NULL); + priv->proxies = g_proxy_resolver_lookup (priv->proxy_resolver, + priv->dest_uri, + cancellable, + error); + priv->next_proxy = priv->proxies; + + if (priv->proxies == NULL) + { + priv->ever_enumerated = TRUE; + return NULL; + } + } + + while (result == NULL && (*priv->next_proxy || priv->addr_enum)) + { + gchar *dest_hostname; + gchar *dest_protocol; + GInetSocketAddress *inetsaddr; + GInetAddress *inetaddr; + guint16 port; + + next_enumerator (priv); + + if (!priv->addr_enum) + continue; + + if (priv->proxy_address == NULL) + { + priv->proxy_address = g_socket_address_enumerator_next ( + priv->addr_enum, + cancellable, + first_error ? NULL : &first_error); + } + + if (priv->proxy_address == NULL) + { + g_object_unref (priv->addr_enum); + priv->addr_enum = NULL; + + if (priv->dest_ips) + { + g_resolver_free_addresses (priv->dest_ips); + priv->dest_ips = NULL; + } + + continue; + } + + if (strcmp ("direct", priv->proxy_type) == 0) + { + result = priv->proxy_address; + priv->proxy_address = NULL; + continue; + } + + if (!priv->supports_hostname) + { + GInetAddress *dest_ip; + + if (!priv->dest_ips) + { + GResolver *resolver; + + resolver = g_resolver_get_default(); + priv->dest_ips = g_resolver_lookup_by_name (resolver, + priv->dest_hostname, + cancellable, + first_error ? NULL : &first_error); + g_object_unref (resolver); + + if (!priv->dest_ips) + { + g_object_unref (priv->proxy_address); + priv->proxy_address = NULL; + continue; + } + } + + if (!priv->next_dest_ip) + priv->next_dest_ip = priv->dest_ips; + + dest_ip = G_INET_ADDRESS (priv->next_dest_ip->data); + dest_hostname = g_inet_address_to_string (dest_ip); + + priv->next_dest_ip = g_list_next (priv->next_dest_ip); + } + else + { + dest_hostname = g_strdup (priv->dest_hostname); + } + dest_protocol = g_uri_parse_scheme (priv->dest_uri); + + if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address)) + { + g_free (dest_hostname); + g_free (dest_protocol); + } + g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address), NULL); + + inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address); + inetaddr = g_inet_socket_address_get_address (inetsaddr); + port = g_inet_socket_address_get_port (inetsaddr); + + result = g_object_new (G_TYPE_PROXY_ADDRESS, + "address", inetaddr, + "port", port, + "protocol", priv->proxy_type, + "destination-protocol", dest_protocol, + "destination-hostname", dest_hostname, + "destination-port", priv->dest_port, + "username", priv->proxy_username, + "password", priv->proxy_password, + "uri", priv->proxy_uri, + NULL); + g_free (dest_hostname); + g_free (dest_protocol); + + if (priv->supports_hostname || priv->next_dest_ip == NULL) + { + g_object_unref (priv->proxy_address); + priv->proxy_address = NULL; + } + } + + if (result == NULL && first_error && (!priv->ever_enumerated || g_error_matches (first_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))) + g_propagate_error (error, first_error); + else if (first_error) + g_error_free (first_error); + + if (result == NULL && error != NULL && *error == NULL && !priv->ever_enumerated) + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unspecified proxy lookup failure"); + + priv->ever_enumerated = TRUE; + + return result; +} + +static void +complete_async (GTask *task) +{ + GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); + + if (priv->last_error && (!priv->ever_enumerated || g_error_matches (priv->last_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))) + { + g_task_return_error (task, priv->last_error); + priv->last_error = NULL; + } + else if (!priv->ever_enumerated) + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Unspecified proxy lookup failure"); + else + g_task_return_pointer (task, NULL, NULL); + + priv->ever_enumerated = TRUE; + + g_clear_error (&priv->last_error); + g_object_unref (task); +} + +static void +return_result (GTask *task) +{ + GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); + GSocketAddress *result; + + if (strcmp ("direct", priv->proxy_type) == 0) + { + result = priv->proxy_address; + priv->proxy_address = NULL; + } + else + { + gchar *dest_hostname, *dest_protocol; + GInetSocketAddress *inetsaddr; + GInetAddress *inetaddr; + guint16 port; + + if (!priv->supports_hostname) + { + GInetAddress *dest_ip; + + if (!priv->next_dest_ip) + priv->next_dest_ip = priv->dest_ips; + + dest_ip = G_INET_ADDRESS (priv->next_dest_ip->data); + dest_hostname = g_inet_address_to_string (dest_ip); + + priv->next_dest_ip = g_list_next (priv->next_dest_ip); + } + else + { + dest_hostname = g_strdup (priv->dest_hostname); + } + dest_protocol = g_uri_parse_scheme (priv->dest_uri); + + if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address)) + { + g_free (dest_hostname); + g_free (dest_protocol); + } + g_return_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address)); + + inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address); + inetaddr = g_inet_socket_address_get_address (inetsaddr); + port = g_inet_socket_address_get_port (inetsaddr); + + result = g_object_new (G_TYPE_PROXY_ADDRESS, + "address", inetaddr, + "port", port, + "protocol", priv->proxy_type, + "destination-protocol", dest_protocol, + "destination-hostname", dest_hostname, + "destination-port", priv->dest_port, + "username", priv->proxy_username, + "password", priv->proxy_password, + "uri", priv->proxy_uri, + NULL); + g_free (dest_hostname); + g_free (dest_protocol); + + if (priv->supports_hostname || priv->next_dest_ip == NULL) + { + g_object_unref (priv->proxy_address); + priv->proxy_address = NULL; + } + } + + priv->ever_enumerated = TRUE; + g_task_return_pointer (task, result, g_object_unref); + g_object_unref (task); +} + +static void address_enumerate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data); + +static void +next_proxy (GTask *task) +{ + GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); + + if (*priv->next_proxy) + { + g_object_unref (priv->addr_enum); + priv->addr_enum = NULL; + + if (priv->dest_ips) + { + g_resolver_free_addresses (priv->dest_ips); + priv->dest_ips = NULL; + } + + next_enumerator (priv); + + if (priv->addr_enum) + { + g_socket_address_enumerator_next_async (priv->addr_enum, + g_task_get_cancellable (task), + address_enumerate_cb, + task); + return; + } + } + + complete_async (task); +} + +static void +dest_hostname_lookup_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); + + g_clear_error (&priv->last_error); + priv->dest_ips = g_resolver_lookup_by_name_finish (G_RESOLVER (object), + result, + &priv->last_error); + if (priv->dest_ips) + return_result (task); + else + { + g_clear_object (&priv->proxy_address); + next_proxy (task); + } +} + +static void +address_enumerate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); + + g_clear_error (&priv->last_error); + priv->proxy_address = + g_socket_address_enumerator_next_finish (priv->addr_enum, + result, + &priv->last_error); + if (priv->proxy_address) + { + if (!priv->supports_hostname && !priv->dest_ips) + { + GResolver *resolver; + resolver = g_resolver_get_default(); + g_resolver_lookup_by_name_async (resolver, + priv->dest_hostname, + g_task_get_cancellable (task), + dest_hostname_lookup_cb, + task); + g_object_unref (resolver); + return; + } + + return_result (task); + } + else + next_proxy (task); +} + +static void +proxy_lookup_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); + + g_clear_error (&priv->last_error); + priv->proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (object), + result, + &priv->last_error); + priv->next_proxy = priv->proxies; + + if (priv->last_error) + { + complete_async (task); + return; + } + else + { + next_enumerator (priv); + if (priv->addr_enum) + { + g_socket_address_enumerator_next_async (priv->addr_enum, + g_task_get_cancellable (task), + address_enumerate_cb, + task); + return; + } + } + + complete_async (task); +} + +static void +g_proxy_address_enumerator_next_async (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (enumerator); + GTask *task; + + task = g_task_new (enumerator, cancellable, callback, user_data); + g_task_set_source_tag (task, g_proxy_address_enumerator_next_async); + g_task_set_task_data (task, priv, NULL); + + if (priv->proxies == NULL) + { + g_proxy_resolver_lookup_async (priv->proxy_resolver, + priv->dest_uri, + cancellable, + proxy_lookup_cb, + task); + return; + } + + if (priv->addr_enum) + { + if (priv->proxy_address) + { + return_result (task); + return; + } + else + { + g_socket_address_enumerator_next_async (priv->addr_enum, + cancellable, + address_enumerate_cb, + task); + return; + } + } + + complete_async (task); +} + +static GSocketAddress * +g_proxy_address_enumerator_next_finish (GSocketAddressEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +g_proxy_address_enumerator_constructed (GObject *object) +{ + GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (object); + GSocketConnectable *conn; + guint port; + + if (priv->dest_uri) + { + conn = g_network_address_parse_uri (priv->dest_uri, priv->default_port, NULL); + if (conn) + { + g_object_get (conn, + "hostname", &priv->dest_hostname, + "port", &port, + NULL); + priv->dest_port = port; + + g_object_unref (conn); + } + else + g_warning ("Invalid URI '%s'", priv->dest_uri); + } + + G_OBJECT_CLASS (g_proxy_address_enumerator_parent_class)->constructed (object); +} + +static void +g_proxy_address_enumerator_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (object); + switch (property_id) + { + case PROP_URI: + g_value_set_string (value, priv->dest_uri); + break; + + case PROP_DEFAULT_PORT: + g_value_set_uint (value, priv->default_port); + break; + + case PROP_CONNECTABLE: + g_value_set_object (value, priv->connectable); + break; + + case PROP_PROXY_RESOLVER: + g_value_set_object (value, priv->proxy_resolver); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +g_proxy_address_enumerator_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (object); + switch (property_id) + { + case PROP_URI: + priv->dest_uri = g_value_dup_string (value); + break; + + case PROP_DEFAULT_PORT: + priv->default_port = g_value_get_uint (value); + break; + + case PROP_CONNECTABLE: + priv->connectable = g_value_dup_object (value); + break; + + case PROP_PROXY_RESOLVER: + if (priv->proxy_resolver) + g_object_unref (priv->proxy_resolver); + priv->proxy_resolver = g_value_get_object (value); + if (!priv->proxy_resolver) + priv->proxy_resolver = g_proxy_resolver_get_default (); + g_object_ref (priv->proxy_resolver); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +g_proxy_address_enumerator_finalize (GObject *object) +{ + GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (object); + + if (priv->connectable) + g_object_unref (priv->connectable); + + if (priv->proxy_resolver) + g_object_unref (priv->proxy_resolver); + + g_free (priv->dest_uri); + g_free (priv->dest_hostname); + + if (priv->dest_ips) + g_resolver_free_addresses (priv->dest_ips); + + g_strfreev (priv->proxies); + + if (priv->addr_enum) + g_object_unref (priv->addr_enum); + + g_free (priv->proxy_type); + g_free (priv->proxy_username); + g_free (priv->proxy_password); + + g_clear_error (&priv->last_error); + + G_OBJECT_CLASS (g_proxy_address_enumerator_parent_class)->finalize (object); +} + +static void +g_proxy_address_enumerator_init (GProxyAddressEnumerator *self) +{ + self->priv = g_proxy_address_enumerator_get_instance_private (self); +} + +static void +g_proxy_address_enumerator_class_init (GProxyAddressEnumeratorClass *proxy_enumerator_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (proxy_enumerator_class); + GSocketAddressEnumeratorClass *enumerator_class = G_SOCKET_ADDRESS_ENUMERATOR_CLASS (proxy_enumerator_class); + + object_class->constructed = g_proxy_address_enumerator_constructed; + object_class->set_property = g_proxy_address_enumerator_set_property; + object_class->get_property = g_proxy_address_enumerator_get_property; + object_class->finalize = g_proxy_address_enumerator_finalize; + + enumerator_class->next = g_proxy_address_enumerator_next; + enumerator_class->next_async = g_proxy_address_enumerator_next_async; + enumerator_class->next_finish = g_proxy_address_enumerator_next_finish; + + g_object_class_install_property (object_class, + PROP_URI, + g_param_spec_string ("uri", + P_("URI"), + P_("The destination URI, use none:// for generic socket"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GProxyAddressEnumerator:default-port: + * + * The default port to use if #GProxyAddressEnumerator:uri does not + * specify one. + * + * Since: 2.38 + */ + g_object_class_install_property (object_class, + PROP_DEFAULT_PORT, + g_param_spec_uint ("default-port", + P_("Default port"), + P_("The default port to use if uri does not specify one"), + 0, 65535, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_CONNECTABLE, + g_param_spec_object ("connectable", + P_("Connectable"), + P_("The connectable being enumerated."), + G_TYPE_SOCKET_CONNECTABLE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GProxyAddressEnumerator:proxy-resolver: + * + * The proxy resolver to use. + * + * Since: 2.36 + */ + g_object_class_install_property (object_class, + PROP_PROXY_RESOLVER, + g_param_spec_object ("proxy-resolver", + P_("Proxy resolver"), + P_("The proxy resolver to use."), + G_TYPE_PROXY_RESOLVER, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); +} diff --git a/gio/gproxyaddressenumerator.h b/gio/gproxyaddressenumerator.h new file mode 100644 index 0000000..470f1dc --- /dev/null +++ b/gio/gproxyaddressenumerator.h @@ -0,0 +1,81 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#ifndef __G_PROXY_ADDRESS_ENUMERATOR_H__ +#define __G_PROXY_ADDRESS_ENUMERATOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_PROXY_ADDRESS_ENUMERATOR (g_proxy_address_enumerator_get_type ()) +#define G_PROXY_ADDRESS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_PROXY_ADDRESS_ENUMERATOR, GProxyAddressEnumerator)) +#define G_PROXY_ADDRESS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_PROXY_ADDRESS_ENUMERATOR, GProxyAddressEnumeratorClass)) +#define G_IS_PROXY_ADDRESS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_PROXY_ADDRESS_ENUMERATOR)) +#define G_IS_PROXY_ADDRESS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_PROXY_ADDRESS_ENUMERATOR)) +#define G_PROXY_ADDRESS_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_PROXY_ADDRESS_ENUMERATOR, GProxyAddressEnumeratorClass)) + +/** + * GProxyAddressEnumerator: + * + * A subclass of #GSocketAddressEnumerator that takes another address + * enumerator and wraps each of its results in a #GProxyAddress as + * directed by the default #GProxyResolver. + */ + +typedef struct _GProxyAddressEnumeratorClass GProxyAddressEnumeratorClass; +typedef struct _GProxyAddressEnumeratorPrivate GProxyAddressEnumeratorPrivate; + +struct _GProxyAddressEnumerator +{ + /*< private >*/ + GSocketAddressEnumerator parent_instance; + GProxyAddressEnumeratorPrivate *priv; +}; + +/** + * GProxyAddressEnumeratorClass: + * + * Class structure for #GProxyAddressEnumerator. + */ +struct _GProxyAddressEnumeratorClass +{ + /*< private >*/ + GSocketAddressEnumeratorClass parent_class; + + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); + void (*_g_reserved7) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_proxy_address_enumerator_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __G_PROXY_ADDRESS_ENUMERATOR_H__ */ diff --git a/gio/gproxyresolver.c b/gio/gproxyresolver.c new file mode 100644 index 0000000..0df51eb --- /dev/null +++ b/gio/gproxyresolver.c @@ -0,0 +1,244 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#include "config.h" + +#include "gproxyresolver.h" + +#include +#include "glibintl.h" + +#include "gasyncresult.h" +#include "gcancellable.h" +#include "gtask.h" +#include "giomodule.h" +#include "gioerror.h" +#include "giomodule-priv.h" +#include "gnetworkingprivate.h" + +/** + * SECTION:gproxyresolver + * @short_description: Asynchronous and cancellable network proxy resolver + * @include: gio/gio.h + * + * #GProxyResolver provides synchronous and asynchronous network proxy + * resolution. #GProxyResolver is used within #GSocketClient through + * the method g_socket_connectable_proxy_enumerate(). + * + * Implementations of #GProxyResolver based on libproxy and GNOME settings can + * be found in glib-networking. GIO comes with an implementation for use inside + * Flatpak portals. + */ + +/** + * GProxyResolverInterface: + * @g_iface: The parent interface. + * @is_supported: the virtual function pointer for g_proxy_resolver_is_supported() + * @lookup: the virtual function pointer for g_proxy_resolver_lookup() + * @lookup_async: the virtual function pointer for + * g_proxy_resolver_lookup_async() + * @lookup_finish: the virtual function pointer for + * g_proxy_resolver_lookup_finish() + * + * The virtual function table for #GProxyResolver. + */ + +G_DEFINE_INTERFACE (GProxyResolver, g_proxy_resolver, G_TYPE_OBJECT) + +static void +g_proxy_resolver_default_init (GProxyResolverInterface *iface) +{ +} + +static GProxyResolver *proxy_resolver_default_singleton = NULL; /* (owned) (atomic) */ + +/** + * g_proxy_resolver_get_default: + * + * Gets the default #GProxyResolver for the system. + * + * Returns: (not nullable) (transfer none): the default #GProxyResolver, which + * will be a dummy object if no proxy resolver is available + * + * Since: 2.26 + */ +GProxyResolver * +g_proxy_resolver_get_default (void) +{ + if (g_once_init_enter (&proxy_resolver_default_singleton)) + { + GProxyResolver *singleton; + + singleton = _g_io_module_get_default (G_PROXY_RESOLVER_EXTENSION_POINT_NAME, + "GIO_USE_PROXY_RESOLVER", + (GIOModuleVerifyFunc) g_proxy_resolver_is_supported); + + g_once_init_leave (&proxy_resolver_default_singleton, singleton); + } + + return proxy_resolver_default_singleton; +} + +/** + * g_proxy_resolver_is_supported: + * @resolver: a #GProxyResolver + * + * Checks if @resolver can be used on this system. (This is used + * internally; g_proxy_resolver_get_default() will only return a proxy + * resolver that returns %TRUE for this method.) + * + * Returns: %TRUE if @resolver is supported. + * + * Since: 2.26 + */ +gboolean +g_proxy_resolver_is_supported (GProxyResolver *resolver) +{ + GProxyResolverInterface *iface; + + g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), FALSE); + + iface = G_PROXY_RESOLVER_GET_IFACE (resolver); + + return (* iface->is_supported) (resolver); +} + +/** + * g_proxy_resolver_lookup: + * @resolver: a #GProxyResolver + * @uri: a URI representing the destination to connect to + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Looks into the system proxy configuration to determine what proxy, + * if any, to use to connect to @uri. The returned proxy URIs are of + * the form `://[user[:password]@]host:port` or + * `direct://`, where could be http, rtsp, socks + * or other proxying protocol. + * + * If you don't know what network protocol is being used on the + * socket, you should use `none` as the URI protocol. + * In this case, the resolver might still return a generic proxy type + * (such as SOCKS), but would not return protocol-specific proxy types + * (such as http). + * + * `direct://` is used when no proxy is needed. + * Direct connection should not be attempted unless it is part of the + * returned array of proxies. + * + * Returns: (transfer full) (array zero-terminated=1): A + * NULL-terminated array of proxy URIs. Must be freed + * with g_strfreev(). + * + * Since: 2.26 + */ +gchar ** +g_proxy_resolver_lookup (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GError **error) +{ + GProxyResolverInterface *iface; + + g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL); + g_return_val_if_fail (uri != NULL, NULL); + + if (!g_uri_is_valid (uri, G_URI_FLAGS_NONE, NULL)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "Invalid URI ‘%s’", uri); + return NULL; + } + + iface = G_PROXY_RESOLVER_GET_IFACE (resolver); + + return (* iface->lookup) (resolver, uri, cancellable, error); +} + +/** + * g_proxy_resolver_lookup_async: + * @resolver: a #GProxyResolver + * @uri: a URI representing the destination to connect to + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): callback to call after resolution completes + * @user_data: (closure): data for @callback + * + * Asynchronous lookup of proxy. See g_proxy_resolver_lookup() for more + * details. + * + * Since: 2.26 + */ +void +g_proxy_resolver_lookup_async (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GProxyResolverInterface *iface; + GError *error = NULL; + + g_return_if_fail (G_IS_PROXY_RESOLVER (resolver)); + g_return_if_fail (uri != NULL); + + if (!g_uri_is_valid (uri, G_URI_FLAGS_NONE, NULL)) + { + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "Invalid URI ‘%s’", uri); + g_task_report_error (resolver, callback, user_data, + g_proxy_resolver_lookup_async, + g_steal_pointer (&error)); + return; + } + + iface = G_PROXY_RESOLVER_GET_IFACE (resolver); + + (* iface->lookup_async) (resolver, uri, cancellable, callback, user_data); +} + +/** + * g_proxy_resolver_lookup_finish: + * @resolver: a #GProxyResolver + * @result: the result passed to your #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Call this function to obtain the array of proxy URIs when + * g_proxy_resolver_lookup_async() is complete. See + * g_proxy_resolver_lookup() for more details. + * + * Returns: (transfer full) (array zero-terminated=1): A + * NULL-terminated array of proxy URIs. Must be freed + * with g_strfreev(). + * + * Since: 2.26 + */ +gchar ** +g_proxy_resolver_lookup_finish (GProxyResolver *resolver, + GAsyncResult *result, + GError **error) +{ + GProxyResolverInterface *iface; + + g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL); + + iface = G_PROXY_RESOLVER_GET_IFACE (resolver); + + return (* iface->lookup_finish) (resolver, result, error); +} diff --git a/gio/gproxyresolver.h b/gio/gproxyresolver.h new file mode 100644 index 0000000..c8ed828 --- /dev/null +++ b/gio/gproxyresolver.h @@ -0,0 +1,95 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#ifndef __G_PROXY_RESOLVER_H__ +#define __G_PROXY_RESOLVER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_PROXY_RESOLVER (g_proxy_resolver_get_type ()) +#define G_PROXY_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_PROXY_RESOLVER, GProxyResolver)) +#define G_IS_PROXY_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_PROXY_RESOLVER)) +#define G_PROXY_RESOLVER_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_PROXY_RESOLVER, GProxyResolverInterface)) + +/** + * G_PROXY_RESOLVER_EXTENSION_POINT_NAME: + * + * Extension point for proxy resolving functionality. + * See [Extending GIO][extending-gio]. + */ +#define G_PROXY_RESOLVER_EXTENSION_POINT_NAME "gio-proxy-resolver" + +typedef struct _GProxyResolverInterface GProxyResolverInterface; + +struct _GProxyResolverInterface { + GTypeInterface g_iface; + + /* Virtual Table */ + gboolean (* is_supported) (GProxyResolver *resolver); + + gchar ** (* lookup) (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GError **error); + + void (* lookup_async) (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + gchar ** (* lookup_finish) (GProxyResolver *resolver, + GAsyncResult *result, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_proxy_resolver_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GProxyResolver *g_proxy_resolver_get_default (void); + +GLIB_AVAILABLE_IN_ALL +gboolean g_proxy_resolver_is_supported (GProxyResolver *resolver); +GLIB_AVAILABLE_IN_ALL +gchar **g_proxy_resolver_lookup (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_proxy_resolver_lookup_async (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gchar **g_proxy_resolver_lookup_finish (GProxyResolver *resolver, + GAsyncResult *result, + GError **error); + + +G_END_DECLS + +#endif /* __G_PROXY_RESOLVER_H__ */ diff --git a/gio/gproxyresolverportal.c b/gio/gproxyresolverportal.c new file mode 100644 index 0000000..2c28a03 --- /dev/null +++ b/gio/gproxyresolverportal.c @@ -0,0 +1,208 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + */ + +#include "config.h" + +#include "xdp-dbus.h" +#include "giomodule-priv.h" +#include "gportalsupport.h" +#include "gproxyresolverportal.h" + +struct _GProxyResolverPortal { + GObject parent_instance; + + GXdpProxyResolver *resolver; + gboolean network_available; +}; + +static void g_proxy_resolver_portal_iface_init (GProxyResolverInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GProxyResolverPortal, g_proxy_resolver_portal, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER, + g_proxy_resolver_portal_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME, + g_define_type_id, + "portal", + 90)) + +static gboolean +ensure_resolver_proxy (GProxyResolverPortal *resolver) +{ + if (resolver->resolver) + return TRUE; + + if (!glib_should_use_portal ()) + return FALSE; + + resolver->resolver = gxdp_proxy_resolver_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + NULL, + NULL); + + resolver->network_available = glib_network_available_in_sandbox (); + + return resolver->resolver != NULL; +} + +static void +g_proxy_resolver_portal_init (GProxyResolverPortal *resolver) +{ +} + +static gboolean +g_proxy_resolver_portal_is_supported (GProxyResolver *object) +{ + GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (object); + char *name_owner; + gboolean has_portal; + + if (!ensure_resolver_proxy (resolver)) + return FALSE; + + name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (resolver->resolver)); + has_portal = name_owner != NULL; + g_free (name_owner); + + return has_portal; +} + +static const char *no_proxy[2] = { "direct://", NULL }; + +static gchar ** +g_proxy_resolver_portal_lookup (GProxyResolver *proxy_resolver, + const gchar *uri, + GCancellable *cancellable, + GError **error) +{ + GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (proxy_resolver); + char **proxy = NULL; + + ensure_resolver_proxy (resolver); + g_assert (resolver->resolver); + + if (!gxdp_proxy_resolver_call_lookup_sync (resolver->resolver, + uri, + &proxy, + cancellable, + error)) + return NULL; + + if (!resolver->network_available) + { + g_strfreev (proxy); + proxy = g_strdupv ((gchar **)no_proxy); + } + + return proxy; +} + +static void +lookup_done (GObject *source, + GAsyncResult *result, + gpointer data) +{ + GTask *task = data; + GError *error = NULL; + gchar **proxies = NULL; + + if (!gxdp_proxy_resolver_call_lookup_finish (GXDP_PROXY_RESOLVER (source), + &proxies, + result, + &error)) + g_task_return_error (task, error); + else + g_task_return_pointer (task, proxies, NULL); + + g_object_unref (task); +} + +static void +g_proxy_resolver_portal_lookup_async (GProxyResolver *proxy_resolver, + const gchar *uri, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (proxy_resolver); + GTask *task; + + ensure_resolver_proxy (resolver); + g_assert (resolver->resolver); + + task = g_task_new (proxy_resolver, cancellable, callback, user_data); + gxdp_proxy_resolver_call_lookup (resolver->resolver, + uri, + cancellable, + lookup_done, + g_object_ref (task)); + g_object_unref (task); +} + +static gchar ** +g_proxy_resolver_portal_lookup_finish (GProxyResolver *proxy_resolver, + GAsyncResult *result, + GError **error) +{ + GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (proxy_resolver); + GTask *task = G_TASK (result); + char **proxies; + + proxies = g_task_propagate_pointer (task, error); + if (proxies == NULL) + return NULL; + + if (!resolver->network_available) + { + g_strfreev (proxies); + proxies = g_strdupv ((gchar **)no_proxy); + } + + return proxies; +} + +static void +g_proxy_resolver_portal_finalize (GObject *object) +{ + GProxyResolverPortal *resolver = G_PROXY_RESOLVER_PORTAL (object); + + g_clear_object (&resolver->resolver); + + G_OBJECT_CLASS (g_proxy_resolver_portal_parent_class)->finalize (object); +} + +static void +g_proxy_resolver_portal_class_init (GProxyResolverPortalClass *resolver_class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (resolver_class); + object_class->finalize = g_proxy_resolver_portal_finalize; +} + +static void +g_proxy_resolver_portal_iface_init (GProxyResolverInterface *iface) +{ + iface->is_supported = g_proxy_resolver_portal_is_supported; + iface->lookup = g_proxy_resolver_portal_lookup; + iface->lookup_async = g_proxy_resolver_portal_lookup_async; + iface->lookup_finish = g_proxy_resolver_portal_lookup_finish; +} diff --git a/gio/gproxyresolverportal.h b/gio/gproxyresolverportal.h new file mode 100644 index 0000000..ae00599 --- /dev/null +++ b/gio/gproxyresolverportal.h @@ -0,0 +1,46 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + */ + +#ifndef __G_PROXY_RESOLVER_PORTAL_H__ +#define __G_PROXY_RESOLVER_PORTAL_H__ + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_PROXY_RESOLVER_PORTAL (g_proxy_resolver_portal_get_type ()) +#define G_PROXY_RESOLVER_PORTAL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_PROXY_RESOLVER_PORTAL, GProxyResolverPortal)) +#define G_PROXY_RESOLVER_PORTAL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_PROXY_RESOLVER_PORTAL, GProxyResolverPortalClass)) +#define G_IS_PROXY_RESOLVER_PORTAL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_PROXY_RESOLVER_PORTAL)) +#define G_IS_PROXY_RESOLVER_PORTAL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_PROXY_RESOLVER_PORTAL)) +#define G_PROXY_RESOLVER_PORTAL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_PROXY_RESOLVER_PORTAL, GProxyResolverPortalClass)) + +typedef struct _GProxyResolverPortal GProxyResolverPortal; +typedef struct _GProxyResolverPortalClass GProxyResolverPortalClass; + +struct _GProxyResolverPortalClass { + GObjectClass parent_class; +}; + +GType g_proxy_resolver_portal_get_type (void); + +G_END_DECLS + +#endif /* __G_PROXY_RESOLVER_PORTAL_H__ */ diff --git a/gio/gregistrysettingsbackend.c b/gio/gregistrysettingsbackend.c new file mode 100644 index 0000000..fd87cdb --- /dev/null +++ b/gio/gregistrysettingsbackend.c @@ -0,0 +1,2167 @@ +/* + * Copyright © 2009-10 Sam Thursfield + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Sam Thursfield + */ + +/* GRegistryBackend implementation notes: + * + * - All settings are stored under the path: + * HKEY_CURRENT_USER\Software\GSettings\ + * This means all settings are per-user. Permissions and system-wide + * defaults are not implemented and will probably always be out of scope of + * the Windows port of GLib. + * + * - The registry type system is limited. Most GVariant types are stored as + * literals via g_variant_print/parse(). Strings are stored without the + * quotes that GVariant requires. Integer types are stored as native + * REG_DWORD or REG_QWORD. The REG_MULTI_SZ (string array) type could be + * used to avoid flattening container types. + * + * - Notifications are handled; the change event is watched for in a separate + * thread (Windows does not provide a callback API) which sends them with + * g_idle_add to the GLib main loop. The threading is done using Windows + * API functions, so there is no dependence on GThread. + * + * - Windows doesn't tell us which value has changed. This means we have to + * maintain a cache of every stored value so we can play spot the + * difference. This should not be a performance issue because if you are + * storing thousands of values in GSettings, you are probably using it + * wrong. + * + * - The cache stores the value as a registry type. Because many variants are + * stored as string representations, values which have changed equality but + * not equivalence may trigger spurious change notifications. GSettings + * users must already deal with this possibility and converting all data to + * GVariant values would be more effort. + * + * - Because we have to cache every registry value locally, reads are done + * from the cache rather than directly from the registry. Writes update + * both. This means that the backend will not work if the watch thread is + * not running. A GSettings object always subscribes to changes so we can + * be sure that the watch thread will be running, but if for some reason + * the backend is being used directly you should bear that in mind. + * + * - The registry is totally user-editable, so we are very forgiving about + * errors in the data we get. + * + * - The registry uses backslashes as path separators. GSettings keys only + * allow [A-Za-z\-] so no escaping is needed. No attempt is made to solve + * clashes between keys differing only in case. + * + * - RegCreateKeyW is used - We should always make the UTF-8 -> UTF-16 + * conversion ourselves to avoid problems when the system language changes. + * + * - The Windows registry has the following limitations: a key may not exceed + * 255 characters, an entry's value may not exceed 16,383 characters, and + * all the values of a key may not exceed 65,535 characters. + * + * - Terminology: + * * in GSettings, a 'key' is eg. /desktop/gnome/background/primary-color + * * in the registry, the 'key' is path, which contains some 'values'. + * * in this file, any GSettings key is a 'key', while a registry key is + * termed a 'path', which contains 'values'. + * + * - My set of tests for this backend are currently at: + * http://gitorious.org/gsettings-gtk/gsettings-test.git + * + * - There is an undocumented function in ntdll.dll which might be more + * than RegNotifyChangeKeyValue(), NtNotifyChangeKey: + * http://source.winehq.org/source/dlls/ntdll/reg.c#L618 + * http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Key/NtNotifyChangeKey.html + * + * - If updating the cache ever becomes a performance issue it may make sense + * to use a red-black tree, but I don't currently think it's worth the time + */ + +#include "config.h" + +#include "gregistrysettingsbackend.h" +#include "gsettingsbackend.h" +#include "giomodule-priv.h" + +#include + +//#define TRACE + +/* GSettings' limit */ +#define MAX_KEY_NAME_LENGTH 128 + +/* Testing (on Windows XP SP3) shows that WaitForMultipleObjects fails with + * "The parameter is incorrect" after 64 watches. We need one for the + * message_sent cond, which is allowed for in the way the watches_remaining + * variable is used. + */ +#define MAX_WATCHES 64 + +/* A watch on one registry path and its subkeys */ +typedef struct +{ + HANDLE event; + HKEY hpath; + char *prefix; + GNode *cache_node; +} RegistryWatch; + +/* Simple message passing for the watch thread. Not enough traffic to + * justify a queue. + */ +typedef enum +{ + WATCH_THREAD_NONE, + WATCH_THREAD_ADD_WATCH, + WATCH_THREAD_REMOVE_WATCH, + WATCH_THREAD_STOP +} WatchThreadMessageType; + +typedef struct +{ + WatchThreadMessageType type; + RegistryWatch watch; +} WatchThreadMessage; + +typedef struct +{ + GSettingsBackend *owner; + HANDLE *thread; + + /* Details of the things we are watching. */ + int watches_remaining; + GPtrArray *events, *handles, *prefixes, *cache_nodes; + + /* Communication with the main thread. Only one message is stored at a time, + * to make sure that messages are acknowledged before being overwritten we + * create two events - one is signalled when a new message is set, the + * other is signalled by the thread when it has processed the message. + */ + WatchThreadMessage message; + CRITICAL_SECTION *message_lock; + HANDLE message_sent_event, message_received_event; +} WatchThreadState; + +#define G_TYPE_REGISTRY_BACKEND (g_registry_backend_get_type ()) +#define G_REGISTRY_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_REGISTRY_BACKEND, GRegistryBackend)) +#define G_IS_REGISTRY_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_REGISTRY_BACKEND)) + +typedef GSettingsBackendClass GRegistryBackendClass; + +typedef struct { + GSettingsBackend parent_instance; + + gchar *base_path; + gunichar2 *base_pathw; + + /* A stored copy of the whole tree being watched. When we receive a change notification + * we have to check against this to see what has changed ... every time ...*/ + CRITICAL_SECTION *cache_lock; + GNode *cache_root; + + WatchThreadState *watch; +} GRegistryBackend; + +G_DEFINE_TYPE_WITH_CODE (GRegistryBackend, + g_registry_backend, + G_TYPE_SETTINGS_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "registry", 90)) + +/********************************************************************************** + * Utility functions + **********************************************************************************/ + +#include +static void +trace (const char *format, + ...) +{ +#ifdef TRACE + va_list va; va_start (va, format); + vprintf (format, va); + fflush (stdout); + va_end (va); +#endif +} + +/* g_message including a windows error message. It is not useful to have an + * equivalent function for g_warning because none of the registry errors can + * result from programmer error (Microsoft programmers don't count), instead + * they will mostly occur from people messing with the registry by hand. */ +static void G_GNUC_PRINTF (2, 3) +g_message_win32_error (DWORD result_code, + const gchar *format, + ...) +{ + va_list va; + gchar *message; + gchar *win32_error; + gchar *win32_message; + + g_return_if_fail (result_code != 0); + + va_start (va, format); + message = g_strdup_vprintf (format, va); + win32_error = g_win32_error_message (result_code); + win32_message = g_strdup_printf ("%s: %s", message, win32_error); + g_free (message); + g_free (win32_error); + + if (result_code == ERROR_KEY_DELETED) + trace ("(%s)", win32_message); + else + g_message ("%s", win32_message); + + g_free (win32_message); +} + +/* Make gsettings key into a registry path & value pair. + * + * Note that the return value *only* needs freeing - registry_value_name + * is a pointer to further inside the same block of memory. + */ +static gchar * +parse_key (const gchar *key_name, + const gchar *registry_prefix, + gchar **value_name) +{ + gchar *path_name, *c; + + /* All key paths are treated as absolute; gsettings doesn't seem to enforce a + * preceding /. + */ + if (key_name[0] == '/') + key_name++; + + if (registry_prefix == NULL) + path_name = g_strdup (key_name); + else + path_name = g_strjoin ("/", registry_prefix, key_name, NULL); + + /* Prefix is expected to be in registry format (\ separators) so don't escape that. */ + for (c = path_name + (registry_prefix ? strlen (registry_prefix) : 0); *c != 0; c++) + { + if (*c == '/') + { + *c = '\\'; + *value_name = c; + } + } + + **value_name = 0; + (*value_name)++; + + return path_name; +} + +static DWORD +g_variant_get_as_dword (GVariant *variant) +{ + switch (g_variant_get_type_string (variant)[0]) + { + case 'b': + return g_variant_get_boolean (variant); + case 'y': + return g_variant_get_byte (variant); + case 'n': + return g_variant_get_int16 (variant); + case 'q': + return g_variant_get_uint16 (variant); + case 'i': + return g_variant_get_int32 (variant); + case 'u': + return g_variant_get_uint32 (variant); + default: + g_warn_if_reached (); + } + return 0; +} + +static DWORDLONG +g_variant_get_as_qword (GVariant *variant) +{ + switch (g_variant_get_type_string (variant)[0]) + { + case 'x': + return g_variant_get_int64 (variant); + case 't': + return g_variant_get_uint64 (variant); + default: + g_warn_if_reached (); + } + return 0; +} + +static void +handle_read_error (LONG result, + const gchar *path_name, + const gchar *value_name) +{ + /* file not found means key value not set, this isn't an error for us. */ + if (result != ERROR_FILE_NOT_FOUND) + g_message_win32_error (result, "Unable to query value %s/%s", + path_name, value_name); +} + +/*************************************************************************** + * Cache of registry values + ***************************************************************************/ + +/* Generic container for registry values */ +typedef struct { + DWORD type; + + union { + gint dword; /* FIXME: could inline QWORD on 64-bit systems too */ + void *ptr; + }; +} RegistryValue; + +static char * +registry_value_dump (RegistryValue value) +{ + if (value.type == REG_DWORD) + return g_strdup_printf ("%d", value.dword); + else if (value.type == REG_QWORD) + return g_strdup_printf ("%"G_GINT64_FORMAT, value.ptr == NULL ? 0: *(DWORDLONG *)value.ptr); + else if (value.type == REG_SZ) + return g_strdup_printf ("%s", (char *)value.ptr); + else if (value.type == REG_NONE) + return g_strdup_printf (""); + else + return g_strdup_printf (""); +} + +static void +registry_value_free (RegistryValue value) +{ + if (value.type == REG_SZ || value.type == REG_QWORD) + g_free (value.ptr); + + value.type = REG_NONE; + value.ptr = NULL; +} + +/* The registry cache is stored as a tree, for easy traversal. Right now we + * don't sort it in a clever way. Each node corresponds to a path element + * ('key' in registry terms) or a value. + * + * Each subscription uses the same cache. Because GSettings can subscribe to + * the tree at any node any number of times, we need to reference count the + * nodes. + */ +typedef struct +{ + /* Component of path that this node represents */ + gchar *name; + + /* If a watch is subscribed at this point (subscription_count > 0) we can + * block its next notification. This is useful because if two watches cover + * the same path, both will trigger when it changes. It also allows changes + * done by the application to be ignored by the watch thread. + */ + gint32 block_count : 8; + + /* Number of times g_settings_subscribe has been called for this location + * (I guess you can't subscribe more than 16383 times) */ + gint32 subscription_count : 14; + + gint32 ref_count : 9; + + gint32 readable : 1; + RegistryValue value; +} RegistryCacheItem; + +static GNode * +registry_cache_add_item (GNode *parent, + gchar *name, + RegistryValue value, + gint ref_count) +{ + RegistryCacheItem *item; + GNode *cache_node; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (parent != NULL, NULL); + + item = g_slice_new (RegistryCacheItem); + + /* Ref count should be the number of watch points above this node */ + item->ref_count = ref_count; + + item->name = g_strdup (name); + item->value = value; + item->subscription_count = 0; + item->block_count = 0; + item->readable = FALSE; + + trace ("\tregistry cache: adding %s to %s\n", + name, ((RegistryCacheItem *)parent->data)->name); + + cache_node = g_node_new (item); + g_node_append (parent, cache_node); + + return cache_node; +} + +/* The reference counting of cache tree nodes works like this: when a node is + * subscribed to (GSettings wants us to watch that path and everything below + * it) the reference count of that node and everything below is increased, as + * well as each parent up to the root. + */ + +static void +_ref_down (GNode *node) +{ + RegistryCacheItem *item = node->data; + + g_node_children_foreach (node, G_TRAVERSE_ALL, + (GNodeForeachFunc)_ref_down, NULL); + item->ref_count++; +} + +static void +registry_cache_ref_tree (GNode *tree) +{ + RegistryCacheItem *item = tree->data; + GNode *node = tree->parent; + + g_return_if_fail (tree != NULL); + + item->ref_count++; + + g_node_children_foreach (tree, G_TRAVERSE_ALL, + (GNodeForeachFunc)_ref_down, NULL); + + for (node = tree->parent; node; node = node->parent) + { + item = node->data; + item->ref_count++; + } +} + +static void +registry_cache_item_free (RegistryCacheItem *item) +{ + trace ("\t -- Free node %s\n", item->name); + + g_free (item->name); + registry_value_free (item->value); + g_slice_free (RegistryCacheItem, item); +} + +/* Unreferencing has to be done bottom-up */ +static void +_unref_node (GNode *node) +{ + RegistryCacheItem *item = node->data; + + item->ref_count--; + + g_warn_if_fail (item->ref_count >= 0); + + if (item->ref_count == 0) + { + registry_cache_item_free (item); + g_node_destroy (node); + } +} + +static void +_unref_down (GNode *node) +{ + g_node_children_foreach (node, G_TRAVERSE_ALL, + (GNodeForeachFunc)_unref_down, NULL); + _unref_node (node); +} + +static void +registry_cache_unref_tree (GNode *tree) +{ + GNode *parent = tree->parent, *next_parent; + + _unref_down (tree); + + while (parent) + { + next_parent = parent->parent; + _unref_node (parent); + parent = next_parent; + } +} + +#if 0 +static void +registry_cache_dump (GNode *cache_node, + gpointer data) +{ + RegistryCacheItem *item = cache_node->data; + + int depth = GPOINTER_TO_INT(data), + new_depth = depth+1, + i; + + g_return_if_fail (cache_node != NULL); + + for (i=0; iname, item->ref_count, (guint)cache_node, + registry_value_dump (item->value)); + g_node_children_foreach (cache_node, G_TRAVERSE_ALL, registry_cache_dump, + GINT_TO_POINTER (new_depth)); +} +#endif + +typedef struct +{ + gchar *name; + GNode *result; +} RegistryCacheSearch; + +static gboolean +registry_cache_find_compare (GNode *node, + gpointer data) +{ + RegistryCacheSearch *search = data; + RegistryCacheItem *item = node->data; + + if (item == NULL) /* root node */ + return FALSE; + + g_return_val_if_fail (search->name != NULL, FALSE); + g_return_val_if_fail (item->name != NULL, FALSE); + + if (strcmp (search->name, item->name) == 0) + { + search->result = node; + return TRUE; + } + + return FALSE; +} + +static GNode * +registry_cache_find_immediate_child (GNode *node, + gchar *name) +{ + RegistryCacheSearch search; + + search.result = NULL; + search.name = name; + + g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, 2, + registry_cache_find_compare, &search); + + return search.result; +} + +static GNode * +registry_cache_get_node_for_key_recursive (GNode *node, + gchar *key_name, + gboolean create_if_not_found, + gint n_parent_watches) +{ + RegistryCacheItem *item; + gchar *component = key_name; + gchar *c = strchr (component, '/'); + GNode *child; + + if (c != NULL) + *c = 0; + + /* We count up how many watch points we travel through finding this node, + * because a new node should have as many references as there are watches at + * points above it in the tree. + */ + item = node->data; + if (item->subscription_count > 0) + n_parent_watches++; + + child = registry_cache_find_immediate_child (node, component); + if (child == NULL && create_if_not_found) + { + RegistryValue null_value = { REG_NONE, {0} }; + + child = registry_cache_add_item (node, component, + null_value, n_parent_watches); + + trace ("\tget node for key recursive: new %x = %s.\n", node, component); + } + + /* We are done if there are no more path components. Allow for a trailing /. */ + if (child == NULL || c == NULL || *(c + 1) == 0) + return child; + + trace ("get node for key recursive: next: %s.\n", c + 1); + + return registry_cache_get_node_for_key_recursive (child, c + 1, + create_if_not_found, + n_parent_watches); +} + +/* Look up a GSettings key in the cache. */ +static GNode * +registry_cache_get_node_for_key (GNode *root, + const gchar *key_name, + gboolean create_if_not_found) +{ + GNode *child = NULL; + GNode *result = NULL; + gchar *component, *c; + + g_return_val_if_fail (key_name != NULL, NULL); + + if (key_name[0] == '/') + key_name++; + + /* Ignore preceding / */ + component = g_strdup (key_name); + c = strchr (component, '/'); + + if (c == NULL) + { + g_free (component); + return root; + } + + if (c != NULL) + *c = 0; + + child = registry_cache_find_immediate_child (root, component); + if (child == NULL && create_if_not_found) + { + RegistryValue null_value = { REG_NONE, {0} }; + + /* Reference count is set to 0, tree should be referenced by the caller */ + child = registry_cache_add_item (root, component, + null_value, 0); + + trace ("get_node_for_key: New node for component '%s'\n", component); + } + + if (*(c + 1) == 0) + result = child; + else if (child != NULL) + result = registry_cache_get_node_for_key_recursive (child, c + 1, + create_if_not_found, 0); + + g_free (component); + + return result; +} + +/* Check the cache node against the registry key it represents. Return TRUE if + * they differ, and update the cache with the new value. + */ +static gboolean +registry_cache_update_node (GNode *cache_node, + RegistryValue registry_value) +{ + RegistryCacheItem *cache_item; + + g_return_val_if_fail (cache_node != NULL, FALSE); + g_return_val_if_fail (cache_node->data != NULL, FALSE); + + cache_item = cache_node->data; + + if (registry_value.type != cache_item->value.type) + { + /* The type has changed. Update cache item and register it as changed. + * Either the schema has changed and this is entirely legitimate, or + * whenever the app reads the key it will get the default value due to + * the type mismatch. + */ + cache_item->value = registry_value; + return TRUE; + } + + switch (registry_value.type) + { + case REG_DWORD: + { + if (cache_item->value.dword == registry_value.dword) + return FALSE; + else + { + cache_item->value.dword = registry_value.dword; + return TRUE; + } + } + case REG_QWORD: + { + g_return_val_if_fail (registry_value.ptr != NULL && + cache_item->value.ptr != NULL, FALSE); + + if (memcmp (registry_value.ptr, cache_item->value.ptr, 8)==0) + { + g_free (registry_value.ptr); + return FALSE; + } + else + { + g_free (cache_item->value.ptr); + cache_item->value.ptr = registry_value.ptr; + return TRUE; + } + } + case REG_SZ: + { + /* Value should not exist if it is NULL, an empty string is "" */ + g_return_val_if_fail (cache_item->value.ptr != NULL, FALSE); + g_return_val_if_fail (registry_value.ptr != NULL, FALSE); + + if (strcmp (registry_value.ptr, cache_item->value.ptr) == 0) + { + g_free (registry_value.ptr); + return FALSE; + } + else + { + g_free (cache_item->value.ptr); + cache_item->value.ptr = registry_value.ptr; + return TRUE; + } + } + default: + g_warning ("gregistrybackend: registry_cache_update_node: Unhandled value type"); + return FALSE; + } +} + +/* Blocking notifications is a useful optimisation. When a change is made + * through GSettings we update the cache manually, but a notification is + * triggered as well. This function is also used for nested notifications, + * eg. if /test and /test/foo are watched, and /test/foo/value is changed then + * we will get notified both for /test/foo and /test and it is helpful to block + * the second. + */ +static void +registry_cache_block_notification (GNode *node) +{ + RegistryCacheItem *item = node->data; + + g_return_if_fail (node != NULL); + + if (item->subscription_count > 0) + item->block_count++; + + if (node->parent != NULL) + registry_cache_block_notification (node->parent); +} + +static void registry_cache_destroy_tree (GNode *node, + WatchThreadState *self); + +/*************************************************************************** + * Reading and writing + ***************************************************************************/ + +static gboolean +registry_read (HKEY hpath, + const gchar *path_name, + const gchar *value_name, + RegistryValue *p_value) +{ + LONG result; + DWORD value_data_size; + gpointer *buffer; + gunichar2 *value_namew; + + g_return_val_if_fail (p_value != NULL, FALSE); + + p_value->type = REG_NONE; + p_value->ptr = NULL; + + value_namew = g_utf8_to_utf16 (value_name, -1, NULL, NULL, NULL); + + result = RegQueryValueExW (hpath, value_namew, 0, &p_value->type, NULL, &value_data_size); + if (result != ERROR_SUCCESS) + { + handle_read_error (result, path_name, value_name); + g_free (value_namew); + return FALSE; + } + + if (p_value->type == REG_SZ && value_data_size == 0) + { + p_value->ptr = g_strdup (""); + g_free (value_namew); + return TRUE; + } + + if (p_value->type == REG_DWORD) + /* REG_DWORD is inlined */ + buffer = (void *)&p_value->dword; + else + buffer = p_value->ptr = g_malloc (value_data_size); + + result = RegQueryValueExW (hpath, value_namew, 0, NULL, (LPBYTE)buffer, &value_data_size); + g_free (value_namew); + + if (result != ERROR_SUCCESS) + { + handle_read_error (result, path_name, value_name); + + if (p_value->type != REG_DWORD) + g_free (buffer); + + return FALSE; + } + + if (p_value->type == REG_SZ) + { + gchar *valueu8 = g_utf16_to_utf8 (p_value->ptr, -1, NULL, NULL, NULL); + g_free (p_value->ptr); + p_value->ptr = valueu8; + } + + return TRUE; +} + +static GVariant * +g_registry_backend_read (GSettingsBackend *backend, + const gchar *key_name, + const GVariantType *expected_type, + gboolean default_value) +{ + GRegistryBackend *self = G_REGISTRY_BACKEND (backend); + GNode *cache_node; + RegistryValue registry_value; + GVariant *gsettings_value = NULL; + gchar *gsettings_type; + + g_return_val_if_fail (expected_type != NULL, NULL); + + if (default_value) + return NULL; + + /* Simply read from the cache, which is updated from the registry by the + * watch thread as soon as changes can propagate. Any changes not yet in the + * cache will have the 'changed' signal emitted after this function returns. + */ + EnterCriticalSection (self->cache_lock); + cache_node = registry_cache_get_node_for_key (self->cache_root, key_name, FALSE); + LeaveCriticalSection (self->cache_lock); + + trace ("Reading key %s, cache node %x\n", key_name, cache_node); + + /* Maybe it's not set, we can return to default */ + if (cache_node == NULL) + return NULL; + + trace ("\t- cached value %s\n", registry_value_dump (((RegistryCacheItem *)cache_node->data)->value)); + + registry_value = ((RegistryCacheItem *)cache_node->data)->value; + + gsettings_type = g_variant_type_dup_string (expected_type); + + /* The registry is user-editable, so we need to be fault-tolerant here. */ + switch (gsettings_type[0]) + { + case 'b': + case 'y': + case 'n': + case 'q': + case 'i': + case 'u': + if (registry_value.type == REG_DWORD) + gsettings_value = g_variant_new (gsettings_type, registry_value.dword); + break; + + case 't': + case 'x': + if (registry_value.type == REG_QWORD) + { + DWORDLONG qword_value = *(DWORDLONG *)registry_value.ptr; + gsettings_value = g_variant_new (gsettings_type, qword_value); + } + break; + + default: + if (registry_value.type == REG_SZ) + { + if (gsettings_type[0] == 's') + gsettings_value = g_variant_new_string ((char *)registry_value.ptr); + else + { + GError *error = NULL; + + gsettings_value = g_variant_parse (expected_type, registry_value.ptr, + NULL, NULL, &error); + + if (error != NULL) + g_message ("gregistrysettingsbackend: error parsing key %s: %s", + key_name, error->message); + } + } + break; + } + + g_free (gsettings_type); + + return gsettings_value; +} + + +typedef struct +{ + GRegistryBackend *self; + HKEY hroot; +} RegistryWrite; + +static gboolean +g_registry_backend_write_one (const char *key_name, + GVariant *variant, + gpointer user_data) +{ + GRegistryBackend *self; + RegistryWrite *action; + RegistryValue value; + HKEY hroot; + HKEY hpath; + gchar *path_name; + gunichar2 *path_namew; + gchar *value_name = NULL; + gunichar2 *value_namew; + DWORD value_data_size; + LPVOID value_data; + gunichar2 *value_dataw; + LONG result; + GNode *node; + gboolean changed; + const gchar *type_string; + + type_string = g_variant_get_type_string (variant); + action = user_data; + self = G_REGISTRY_BACKEND (action->self); + hroot = action->hroot; + + value.type = REG_NONE; + value.ptr = NULL; + + switch (type_string[0]) + { + case 'b': + case 'y': + case 'n': + case 'q': + case 'i': + case 'u': + value.type = REG_DWORD; + value.dword = g_variant_get_as_dword (variant); + value_data_size = 4; + value_data = &value.dword; + break; + + case 'x': + case 't': + value.type = REG_QWORD; + value.ptr = g_malloc (8); + *(DWORDLONG *)value.ptr = g_variant_get_as_qword (variant); + value_data_size = 8; + value_data = value.ptr; + break; + + default: + value.type = REG_SZ; + if (type_string[0] == 's') + { + gsize length; + value.ptr = g_strdup (g_variant_get_string (variant, &length)); + value_data_size = length + 1; + value_data = value.ptr; + } + else + { + GString *value_string; + value_string = g_variant_print_string (variant, NULL, FALSE); + value_data_size = value_string->len + 1; + value.ptr = value_data = g_string_free (value_string, FALSE); + } + break; + } + + /* First update the cache, because the value may not have changed and we can + * save a write. + * + * If 'value' has changed then its memory will not be freed by update_node(), + * because it will be stored in the node. + */ + EnterCriticalSection (self->cache_lock); + node = registry_cache_get_node_for_key (self->cache_root, key_name, TRUE); + changed = registry_cache_update_node (node, value); + LeaveCriticalSection (self->cache_lock); + + if (!changed) + return FALSE; + + /* Block the next notification to any watch points above this location, + * because they will each get triggered on a change that is already updated + * in the cache. + */ + registry_cache_block_notification (node); + + path_name = parse_key (key_name, NULL, &value_name); + + trace ("Set key: %s / %s\n", path_name, value_name); + + path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL); + + /* Store the value in the registry */ + result = RegCreateKeyExW (hroot, path_namew, 0, NULL, 0, KEY_WRITE, NULL, &hpath, NULL); + if (result != ERROR_SUCCESS) + { + g_message_win32_error (result, "gregistrybackend: opening key %s failed", + path_name + 1); + registry_value_free (value); + g_free (path_namew); + g_free (path_name); + return FALSE; + } + + g_free (path_namew); + + value_namew = g_utf8_to_utf16 (value_name, -1, NULL, NULL, NULL); + + value_dataw = NULL; + + switch (type_string[0]) + { + case 'b': + case 'y': + case 'n': + case 'q': + case 'i': + case 'u': + case 'x': + case 't': + break; + default: + value_dataw = g_utf8_to_utf16 (value_data, -1, NULL, NULL, NULL); + value_data = value_dataw; + value_data_size = (DWORD)((wcslen (value_data) + 1) * sizeof (gunichar2)); + break; + } + + result = RegSetValueExW (hpath, value_namew, 0, value.type, value_data, value_data_size); + + if (result != ERROR_SUCCESS) + g_message_win32_error (result, "gregistrybackend: setting value %s\\%s\\%s failed.\n", + self->base_path, path_name, value_name); + + /* If the write fails then it will seem like the value has changed until the + * next execution (because we wrote to the cache first). There's no reason + * for it to fail unless something is weirdly broken, however. + */ + + RegCloseKey (hpath); + g_free (path_name); + g_free (value_namew); + g_free (value_dataw); + + return FALSE; +} + +/* The dconf write policy is to do the write while making out it succeeded, + * and then backtrack if it didn't. The registry functions are synchronous so + * we can't do that. */ + +static gboolean +g_registry_backend_write (GSettingsBackend *backend, + const gchar *key_name, + GVariant *value, + gpointer origin_tag) +{ + GRegistryBackend *self = G_REGISTRY_BACKEND (backend); + LONG result; + HKEY hroot; + RegistryWrite action; + + result = RegCreateKeyExW (HKEY_CURRENT_USER, self->base_pathw, 0, NULL, 0, + KEY_WRITE, NULL, &hroot, NULL); + if (result != ERROR_SUCCESS) + { + trace ("Error opening/creating key %s.\n", self->base_path); + return FALSE; + } + + action.self = self; + action.hroot = hroot; + g_registry_backend_write_one (key_name, value, &action); + g_settings_backend_changed (backend, key_name, origin_tag); + + RegCloseKey (hroot); + + return TRUE; +} + +static gboolean +g_registry_backend_write_tree (GSettingsBackend *backend, + GTree *values, + gpointer origin_tag) +{ + GRegistryBackend *self = G_REGISTRY_BACKEND (backend); + LONG result; + HKEY hroot; + RegistryWrite action; + + result = RegCreateKeyExW (HKEY_CURRENT_USER, self->base_pathw, 0, NULL, 0, + KEY_WRITE, NULL, &hroot, NULL); + if (result != ERROR_SUCCESS) + { + trace ("Error opening/creating key %s.\n", self->base_path); + return FALSE; + } + + action.self = self; + action.hroot = hroot; + g_tree_foreach (values, (GTraverseFunc)g_registry_backend_write_one, + &action); + + g_settings_backend_changed_tree (backend, values, origin_tag); + RegCloseKey (hroot); + + return TRUE; +} + +static void +g_registry_backend_reset (GSettingsBackend *backend, + const gchar *key_name, + gpointer origin_tag) +{ + GRegistryBackend *self = G_REGISTRY_BACKEND (backend); + gchar *path_name; + gunichar2 *path_namew; + gchar *value_name = NULL; + gunichar2 *value_namew; + GNode *cache_node; + LONG result; + HKEY hpath; + + /* Remove from cache */ + EnterCriticalSection (self->cache_lock); + cache_node = registry_cache_get_node_for_key (self->cache_root, key_name, FALSE); + if (cache_node) + registry_cache_destroy_tree (cache_node, self->watch); + LeaveCriticalSection (self->cache_lock); + + /* Remove from the registry */ + path_name = parse_key (key_name, self->base_path, &value_name); + path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL); + + result = RegOpenKeyExW (HKEY_CURRENT_USER, path_namew, 0, KEY_SET_VALUE, &hpath); + g_free (path_namew); + + if (result != ERROR_SUCCESS) + { + g_message_win32_error (result, "Registry: resetting key '%s'", path_name); + g_free (path_name); + return; + } + + value_namew = g_utf8_to_utf16 (value_name, -1, NULL, NULL, NULL); + + result = RegDeleteValueW (hpath, value_namew); + g_free (value_namew); + RegCloseKey (hpath); + + if (result != ERROR_SUCCESS) + { + g_message_win32_error (result, "Registry: resetting key '%s'", path_name); + g_free (path_name); + return; + } + + g_free (path_name); + + g_settings_backend_changed (backend, key_name, origin_tag); +} + +static gboolean +g_registry_backend_get_writable (GSettingsBackend *backend, + const gchar *key_name) +{ + GRegistryBackend *self = G_REGISTRY_BACKEND (backend); + gchar *path_name; + gunichar2 *path_namew; + gchar *value_name = NULL; + HKEY hpath; + LONG result; + + path_name = parse_key (key_name, self->base_path, &value_name); + path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL); + + /* Note: we create the key if it wasn't created yet, but it is not much + * of a problem since at the end of the day we have to create it anyway + * to read or to write from it + */ + result = RegCreateKeyExW (HKEY_CURRENT_USER, path_namew, 0, NULL, 0, + KEY_WRITE, NULL, &hpath, NULL); + g_free (path_namew); + + if (result != ERROR_SUCCESS) + { + trace ("Error opening/creating key to check writability: %s.\n", + path_name); + g_free (path_name); + + return FALSE; + } + + g_free (path_name); + RegCloseKey (hpath); + + return TRUE; +} + +/******************************************************************************** + * Spot-the-difference engine + ********************************************************************************/ + +static void +_free_watch (WatchThreadState *self, + guint index, + GNode *cache_node); + +static void +registry_cache_item_reset_readable (GNode *node, + gpointer data) +{ + RegistryCacheItem *item = node->data; + item->readable = FALSE; +} + +/* Delete a node and any children, for when it has been deleted from the registry */ +static void +registry_cache_destroy_tree (GNode *node, + WatchThreadState *self) +{ + RegistryCacheItem *item = node->data; + + g_node_children_foreach (node, G_TRAVERSE_ALL, + (GNodeForeachFunc)registry_cache_destroy_tree, self); + + if (item->subscription_count > 0) + { + guint i; + + /* There must be some watches active if this node is a watch point */ + g_warn_if_fail (self->cache_nodes->len > 1); + + /* This is a watch point that has been deleted. Let's free the watch! */ + for (i = 1; i < self->cache_nodes->len; i++) + { + if (g_ptr_array_index (self->cache_nodes, i) == node) + break; + } + + if (i >= self->cache_nodes->len) + g_warning ("watch thread: a watch point was deleted, but unable to " + "find '%s' in the list of %i watch nodes\n", item->name, + self->cache_nodes->len - 1); + else + { + _free_watch (self, i, node); + g_atomic_int_inc (&self->watches_remaining); + } + } + registry_cache_item_free (node->data); + g_node_destroy (node); +} + +/* One of these is sent down the pipe when something happens in the registry. */ +typedef struct +{ + GRegistryBackend *self; + gchar *prefix; /* prefix is a gsettings path, all items are subkeys of this. */ + GPtrArray *items; /* each item is a subkey below prefix that has changed. */ +} RegistryEvent; + +typedef struct +{ + RegistryEvent *event; + gchar *current_key_name; +} DeletedItemData; + +static void +mark_all_subkeys_as_changed (GNode *node, + gpointer data) +{ + RegistryCacheItem *item = node->data; + DeletedItemData *item_data = data; + + if (item_data->current_key_name == NULL) + item_data->current_key_name = g_strdup (item->name); + else + { + gchar *name; + + name = g_build_path ("/", item_data->current_key_name, item->name, NULL); + g_free (item_data->current_key_name); + item_data->current_key_name = name; + } + + /* Iterate until we find an item that is a value */ + if (item->value.type == REG_NONE) + g_node_children_foreach (node, G_TRAVERSE_ALL, + mark_all_subkeys_as_changed, data); + else + g_ptr_array_add (item_data->event->items, item_data->current_key_name); +} + +static void +registry_cache_remove_deleted (GNode *node, + gpointer data) +{ + RegistryCacheItem *item = node->data; + RegistryEvent *event = data; + + if (!item->readable) + { + DeletedItemData item_data; + + item_data.event = event; + item_data.current_key_name = NULL; + + mark_all_subkeys_as_changed (node, &item_data); + registry_cache_destroy_tree (node, event->self->watch); + } +} + +/* Update cache from registry, and optionally report on the changes. + * + * This function is sometimes called from the watch thread, with no locking. It + * does call g_registry_backend functions, but this is okay because they only + * access self->base which is constant. + * + * When looking at this code bear in mind the terminology: in the registry, keys + * are containers that contain values, and other keys. Keys have a 'default' + * value which we always ignore. + * + * n_parent_watches: a counter used to set the reference count of any new nodes + * that are created - they should have as many references as + * there are notifications that are watching them. + */ +static void +registry_cache_update (GRegistryBackend *self, + HKEY hpath, + const gchar *prefix, + const gchar *partial_key_name, + GNode *cache_node, + int n_watches, + RegistryEvent *event) +{ + gunichar2 bufferw[MAX_KEY_NAME_LENGTH + 1]; + gchar *buffer; + gchar *key_name; + gint i; + LONG result; + RegistryCacheItem *item; + + item = cache_node->data; + + if (item->subscription_count > 0) + n_watches++; + + /* prefix is the level that all changes occur below; partial_key_name should + * be NULL on the first call to this function */ + key_name = g_build_path ("/", prefix, partial_key_name, NULL); + + trace ("registry cache update: %s. Node %x has %i children\n", key_name, + cache_node, g_node_n_children (cache_node)); + + /* Start by zeroing 'readable' flag. When the registry traversal is done, any unreadable nodes + * must have been deleted from the registry. + */ + g_node_children_foreach (cache_node, G_TRAVERSE_ALL, + registry_cache_item_reset_readable, NULL); + + /* Recurse into each subpath at the current level, if any */ + i = 0; + while (1) + { + DWORD bufferw_size = MAX_KEY_NAME_LENGTH + 1; + HKEY hsubpath; + + result = RegEnumKeyExW (hpath, i++, bufferw, &bufferw_size, NULL, NULL, NULL, NULL); + if (result != ERROR_SUCCESS) + break; + + result = RegOpenKeyExW (hpath, bufferw, 0, KEY_READ, &hsubpath); + if (result == ERROR_SUCCESS) + { + GNode *subkey_node; + RegistryCacheItem *child_item; + gchar *new_partial_key_name; + + buffer = g_utf16_to_utf8 (bufferw, -1, NULL, NULL, NULL); + if (buffer == NULL) + continue; + + subkey_node = registry_cache_find_immediate_child (cache_node, buffer); + if (subkey_node == NULL) + { + RegistryValue null_value = {REG_NONE, {0}}; + subkey_node = registry_cache_add_item (cache_node, buffer, + null_value, n_watches); + } + + new_partial_key_name = g_build_path ("/", partial_key_name, buffer, NULL); + registry_cache_update (self, hsubpath, prefix, new_partial_key_name, + subkey_node, n_watches, event); + g_free (new_partial_key_name); + + child_item = subkey_node->data; + child_item->readable = TRUE; + + g_free (buffer); + RegCloseKey (hsubpath); + } + } + + if (result != ERROR_NO_MORE_ITEMS) + g_message_win32_error (result, "gregistrybackend: error enumerating subkeys for cache."); + + /* Enumerate each value at 'path' and check if it has changed */ + i = 0; + while (1) + { + DWORD bufferw_size = MAX_KEY_NAME_LENGTH + 1; + GNode *cache_child_node; + RegistryCacheItem *child_item; + RegistryValue value; + gboolean changed = FALSE; + + result = RegEnumValueW (hpath, i++, bufferw, &bufferw_size, NULL, NULL, NULL, NULL); + if (result != ERROR_SUCCESS) + break; + + buffer = g_utf16_to_utf8 (bufferw, -1, NULL, NULL, NULL); + + if (buffer == NULL || buffer[0] == 0) + { + /* This is the key's 'default' value, for which we have no use. */ + g_free (buffer); + continue; + } + + cache_child_node = registry_cache_find_immediate_child (cache_node, buffer); + + if (!registry_read (hpath, key_name, buffer, &value)) + { + g_free (buffer); + continue; + } + + trace ("\tgot value %s for %s, node %x\n", + registry_value_dump (value), buffer, cache_child_node); + + if (cache_child_node == NULL) + { + /* This is a new value */ + cache_child_node = registry_cache_add_item (cache_node, buffer, value, + n_watches); + changed = TRUE; + } + else + { + /* For efficiency, instead of converting every value back to a GVariant to + * compare it, we compare them as registry values (integers, or string + * representations of the variant). The spurious change notifications that may + * result should not be a big issue. + * + * Note that 'value' is swallowed or freed. + */ + changed = registry_cache_update_node (cache_child_node, value); + } + + child_item = cache_child_node->data; + child_item->readable = TRUE; + if (changed && event != NULL) + { + gchar *item_path; + + if (partial_key_name == NULL) + item_path = g_strdup (buffer); + else + item_path = g_build_path ("/", partial_key_name, buffer, NULL); + + g_ptr_array_add (event->items, item_path); + } + + g_free (buffer); + } + + if (result != ERROR_NO_MORE_ITEMS) + g_message_win32_error (result, "gregistrybackend: error enumerating values for cache"); + + /* Any nodes now left unreadable must have been deleted, remove them from cache */ + g_node_children_foreach (cache_node, G_TRAVERSE_ALL, + registry_cache_remove_deleted, event); + + trace ("registry cache update complete.\n"); + + g_free (key_name); +} + +/*********************************************************************************** + * Thread to watch for registry change events + ***********************************************************************************/ + +/* Called by watch thread. Apply for notifications on a registry key and its subkeys. */ +static DWORD +registry_watch_key (HKEY hpath, + HANDLE event) +{ + return RegNotifyChangeKeyValue (hpath, TRUE, + REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, + event, TRUE); +} + +/* This handler runs in the main thread to emit the changed signals */ +static gboolean +watch_handler (RegistryEvent *event) +{ + trace ("Watch handler: got event in %s, items %i.\n", event->prefix, event->items->len); + + /* GSettings requires us to NULL-terminate the array. */ + g_ptr_array_add (event->items, NULL); + g_settings_backend_keys_changed (G_SETTINGS_BACKEND (event->self), event->prefix, + (gchar const **)event->items->pdata, NULL); + + g_ptr_array_free (event->items, TRUE); + g_free (event->prefix); + g_object_unref (event->self); + g_slice_free (RegistryEvent, event); + + return G_SOURCE_REMOVE; +} + +static void +_free_watch (WatchThreadState *self, + guint index, + GNode *cache_node) +{ + HKEY hpath; + HANDLE cond; + gchar *prefix; + + g_return_if_fail (index > 0 && index < self->events->len); + + cond = g_ptr_array_index (self->events, index); + hpath = g_ptr_array_index (self->handles, index); + prefix = g_ptr_array_index (self->prefixes, index); + + trace ("Freeing watch %i [%s]\n", index, prefix); + + /* These can be NULL if the watch was already dead, this can happen when eg. + * a key is deleted but GSettings is still subscribed to it - the watch is + * kept alive so that the unsubscribe function works properly, but does not + * do anything. + */ + if (hpath != NULL) + RegCloseKey (hpath); + + if (cache_node != NULL) + { + //registry_cache_dump (G_REGISTRY_BACKEND (self->owner)->cache_root, NULL); + registry_cache_unref_tree (cache_node); + } + + CloseHandle (cond); + g_free (prefix); + + /* As long as we remove from each array at the same time, it doesn't matter that + * their orders get messed up - they all get messed up the same. + */ + g_ptr_array_remove_index_fast (self->handles, index); + g_ptr_array_remove_index_fast (self->events, index); + g_ptr_array_remove_index_fast (self->prefixes, index); + g_ptr_array_remove_index_fast (self->cache_nodes, index); +} + +static void +watch_thread_handle_message (WatchThreadState *self) +{ + switch (self->message.type) + { + case WATCH_THREAD_NONE: + trace ("watch thread: you woke me up for nothin', man!"); + break; + + case WATCH_THREAD_ADD_WATCH: + { + RegistryWatch *watch = &self->message.watch; + LONG result; + + result = registry_watch_key (watch->hpath, watch->event); + + if (result == ERROR_SUCCESS) + { + g_ptr_array_add (self->events, watch->event); + g_ptr_array_add (self->handles, watch->hpath); + g_ptr_array_add (self->prefixes, watch->prefix); + g_ptr_array_add (self->cache_nodes, watch->cache_node); + + trace ("watch thread: new watch on %s, %i total\n", watch->prefix, + self->events->len); + } + else + { + g_message_win32_error (result, "watch thread: could not watch %s", watch->prefix); + + CloseHandle (watch->event); + RegCloseKey (watch->hpath); + g_free (watch->prefix); + registry_cache_unref_tree (watch->cache_node); + } + break; + } + + case WATCH_THREAD_REMOVE_WATCH: + { + GNode *cache_node; + RegistryCacheItem *cache_item; + guint i; + + for (i = 1; i < self->prefixes->len; i++) + { + if (strcmp (g_ptr_array_index (self->prefixes, i), + self->message.watch.prefix) == 0) + break; + } + + if (i >= self->prefixes->len) + { + /* Don't make a fuss if the prefix is not being watched because + * maybe the path was deleted so we removed the watch. + */ + trace ("unsubscribe: prefix %s is not being watched [%i things are]!\n", + self->message.watch.prefix, self->prefixes->len); + g_free (self->message.watch.prefix); + break; + } + + cache_node = g_ptr_array_index (self->cache_nodes, i); + + trace ("watch thread: unsubscribe: freeing node %p, prefix %s, index %i\n", + cache_node, self->message.watch.prefix, i); + + if (cache_node != NULL) + { + cache_item = cache_node->data; + + /* There may be more than one GSettings object subscribed to this + * path, only free the watch when the last one unsubscribes. + */ + cache_item->subscription_count--; + if (cache_item->subscription_count > 0) + break; + } + + _free_watch (self, i, cache_node); + g_free (self->message.watch.prefix); + + g_atomic_int_inc (&self->watches_remaining); + break; + } + + case WATCH_THREAD_STOP: + { + guint i; + + /* Free any remaining cache and watch handles */ + for (i = 1; i < self->events->len; i++) + _free_watch (self, i, g_ptr_array_index (self->cache_nodes, i)); + + SetEvent (self->message_received_event); + ExitThread (0); + } + } + + self->message.type = WATCH_THREAD_NONE; + SetEvent (self->message_received_event); +} + +/* Thread which watches for win32 registry events */ +static DWORD WINAPI +watch_thread_function (LPVOID parameter) +{ + WatchThreadState *self = (WatchThreadState *)parameter; + DWORD result; + + self->events = g_ptr_array_new (); + self->handles = g_ptr_array_new (); + self->prefixes = g_ptr_array_new (); + self->cache_nodes = g_ptr_array_new (); + g_ptr_array_add (self->events, self->message_sent_event); + g_ptr_array_add (self->handles, NULL); + g_ptr_array_add (self->prefixes, NULL); + g_ptr_array_add (self->cache_nodes, NULL); + + while (1) + { + trace ("watch thread: going to sleep; %i events watched.\n", self->events->len); + result = WaitForMultipleObjects (self->events->len, self->events->pdata, FALSE, INFINITE); + + if (result == WAIT_OBJECT_0) + { + /* A message to you. The sender (main thread) will block until we signal the received + * event, so there should be no danger of it sending another before we receive the + * first. + */ + watch_thread_handle_message (self); + } + else if (result > WAIT_OBJECT_0 && result <= WAIT_OBJECT_0 + self->events->len) + { + HKEY hpath; + HANDLE cond; + gchar *prefix; + GNode *cache_node; + RegistryCacheItem *cache_item; + RegistryEvent *event; + gint notify_index; + + /* One of our notifications has triggered. All we know is which one, and which key + * this is for. We do most of the processing here, because we may as well. If the + * registry changes further while we are processing it doesn't matter - we will then + * receive another change notification from the OS anyway. + */ + notify_index = result - WAIT_OBJECT_0; + hpath = g_ptr_array_index (self->handles, notify_index); + cond = g_ptr_array_index (self->events, notify_index); + prefix = g_ptr_array_index (self->prefixes, notify_index); + cache_node = g_ptr_array_index (self->cache_nodes, notify_index); + + trace ("Watch thread: notify received on prefix %i: %s.\n", notify_index, prefix); + + if (cache_node == NULL) + { + /* This path has been deleted */ + trace ("Notify received on a path that was deleted\n"); + continue; + } + + /* Firstly we need to reapply for the notification, because (what a + * sensible API) we won't receive any more. MSDN is pretty + * inconsistent on this matter: + * http://msdn.microsoft.com/en-us/library/ms724892%28VS.85%29.aspx + * http://support.microsoft.com/kb/236570 + * But my tests (on Windows XP SP3) show that we need to reapply + * each time. + */ + result = registry_watch_key (hpath, cond); + + if (result != ERROR_SUCCESS) + { + /* Watch failed, most likely because the key has just been + * deleted. Free the watch and unref the cache nodes. + */ + if (result != ERROR_KEY_DELETED) + g_message_win32_error (result, "watch thread: failed to watch %s", prefix); + + _free_watch (self, notify_index, cache_node); + g_atomic_int_inc (&self->watches_remaining); + continue; + } + + /* The notification may have been blocked because we just changed + * some data ourselves. + */ + cache_item = cache_node->data; + if (cache_item->block_count) + { + cache_item->block_count--; + trace ("Watch thread: notify blocked at %s\n", prefix); + continue; + } + + /* Now we update our stored cache from registry data, and find which keys have + * actually changed. If more changes happen while we are processing, we will get + * another event because we have reapplied for change notifications already. + * + * Working here rather than in the main thread is preferable because the UI is less + * likely to block (only when changing notification subscriptions). + */ + event = g_slice_new (RegistryEvent); + event->self = G_REGISTRY_BACKEND (g_object_ref (self->owner)); + event->prefix = g_strdup (prefix); + event->items = g_ptr_array_new_with_free_func (g_free); + + EnterCriticalSection (G_REGISTRY_BACKEND (self->owner)->cache_lock); + registry_cache_update (G_REGISTRY_BACKEND (self->owner), hpath, + prefix, NULL, cache_node, 0, event); + LeaveCriticalSection (G_REGISTRY_BACKEND (self->owner)->cache_lock); + + if (event->items->len > 0) + g_idle_add ((GSourceFunc) watch_handler, event); + else + { + g_object_unref (event->self); + g_free (event->prefix); + g_ptr_array_free (event->items, TRUE); + g_slice_free (RegistryEvent, event); + } + } + else + { + /* God knows what has happened */ + g_message_win32_error (GetLastError(), "watch thread: WaitForMultipleObjects error"); + } + } + + return -1; +} + +static gboolean +watch_start (GRegistryBackend *self) +{ + WatchThreadState *watch; + + g_return_val_if_fail (self->watch == NULL, FALSE); + + watch = g_slice_new (WatchThreadState); + watch->owner = G_SETTINGS_BACKEND (self); + + watch->watches_remaining = MAX_WATCHES; + + watch->message_lock = g_slice_new (CRITICAL_SECTION); + InitializeCriticalSection (watch->message_lock); + watch->message_sent_event = CreateEvent (NULL, FALSE, FALSE, NULL); + watch->message_received_event = CreateEvent (NULL, FALSE, FALSE, NULL); + if (watch->message_sent_event == NULL || watch->message_received_event == NULL) + { + g_message_win32_error (GetLastError (), "gregistrybackend: Failed to create sync objects."); + goto fail; + } + + /* Use a small stack to make the thread more lightweight. */ + watch->thread = CreateThread (NULL, 1024, watch_thread_function, watch, 0, NULL); + if (watch->thread == NULL) + { + g_message_win32_error (GetLastError (), "gregistrybackend: Failed to create notify watch thread."); + goto fail; + } + + self->watch = watch; + + return TRUE; + +fail: + DeleteCriticalSection (watch->message_lock); + g_slice_free (CRITICAL_SECTION, watch->message_lock); + if (watch->message_sent_event != NULL) + CloseHandle (watch->message_sent_event); + if (watch->message_received_event != NULL) + CloseHandle (watch->message_received_event); + g_slice_free (WatchThreadState, watch); + + return FALSE; +} + +/* This function assumes you hold the message lock! */ +static void +watch_stop_unlocked (GRegistryBackend *self) +{ + WatchThreadState *watch = self->watch; + DWORD result; + + g_return_if_fail (watch != NULL); + + watch->message.type = WATCH_THREAD_STOP; + SetEvent (watch->message_sent_event); + + /* This is signalled as soon as the message is received. We must not return + * while the watch thread is still firing off callbacks. Freeing all of the + * memory is done in the watch thread after this is signalled. + */ + result = WaitForSingleObject (watch->message_received_event, INFINITE); + if (result != WAIT_OBJECT_0) + { + g_warning ("gregistrybackend: unable to stop watch thread."); + return; + } + + LeaveCriticalSection (watch->message_lock); + DeleteCriticalSection (watch->message_lock); + g_slice_free (CRITICAL_SECTION, watch->message_lock); + CloseHandle (watch->message_sent_event); + CloseHandle (watch->message_received_event); + CloseHandle (watch->thread); + g_slice_free (WatchThreadState, watch); + + trace ("\nwatch thread: %x: all data freed.\n", self); + self->watch = NULL; +} + +static gboolean +watch_add_notify (GRegistryBackend *self, + HANDLE event, + HKEY hpath, + gchar *gsettings_prefix) +{ + WatchThreadState *watch = self->watch; + GNode *cache_node; + RegistryCacheItem *cache_item; +#ifdef TRACE + DWORD result; +#endif + + g_return_val_if_fail (watch != NULL, FALSE); + + trace ("watch_add_notify: prefix %s.\n", gsettings_prefix); + + /* Duplicate tree into the cache in the main thread, before we add the notify: if we do it in the + * thread we can miss changes while we are caching. + */ + EnterCriticalSection (self->cache_lock); + cache_node = registry_cache_get_node_for_key (self->cache_root, gsettings_prefix, TRUE); + + if (cache_node == NULL || cache_node->data == NULL) + { + LeaveCriticalSection (self->cache_lock); + g_warn_if_reached (); + return FALSE; + } + + cache_item = cache_node->data; + + cache_item->subscription_count++; + if (cache_item->subscription_count > 1) + { + trace ("watch_add_notify: prefix %s already watched, %i subscribers.\n", + gsettings_prefix, cache_item->subscription_count); + LeaveCriticalSection (self->cache_lock); + return FALSE; + } + + registry_cache_ref_tree (cache_node); + registry_cache_update (self, hpath, gsettings_prefix, NULL, cache_node, 0, NULL); + //registry_cache_dump (self->cache_root, NULL); + LeaveCriticalSection (self->cache_lock); + + EnterCriticalSection (watch->message_lock); + watch->message.type = WATCH_THREAD_ADD_WATCH; + watch->message.watch.event = event; + watch->message.watch.hpath = hpath; + watch->message.watch.prefix = gsettings_prefix; + watch->message.watch.cache_node = cache_node; + + SetEvent (watch->message_sent_event); + + /* Wait for the received event in return, to avoid sending another message before the first + * one was received. If it takes > 200ms there is a possible race but the worst outcome is + * a notification is ignored. + */ +#ifdef TRACE + result = +#endif + WaitForSingleObject (watch->message_received_event, 200); +#ifdef TRACE + if (result != WAIT_OBJECT_0) + trace ("watch thread is slow to respond - notification may not be added."); +#endif + + LeaveCriticalSection (watch->message_lock); + + return TRUE; +} + +static void +watch_remove_notify (GRegistryBackend *self, + const gchar *key_name) +{ + WatchThreadState *watch = self->watch; + LONG result; + + if (self->watch == NULL) + /* Here we assume that the unsubscribe message is for somewhere that was + * deleted, and so it has already been removed and the watch thread has + * stopped. + */ + return; + + EnterCriticalSection (watch->message_lock); + watch->message.type = WATCH_THREAD_REMOVE_WATCH; + watch->message.watch.prefix = g_strdup (key_name); + + SetEvent (watch->message_sent_event); + + /* Wait for the received event in return, to avoid sending another message before the first + * one was received. + */ + result = WaitForSingleObject (watch->message_received_event, INFINITE); + + if (result != ERROR_SUCCESS) + g_warning ("unsubscribe from %s: message not acknowledged", key_name); + + if (g_atomic_int_get (&watch->watches_remaining) >= MAX_WATCHES) + /* Stop it before any new ones can get added and confuse things */ + watch_stop_unlocked (self); + else + LeaveCriticalSection (watch->message_lock); +} + +/* dconf semantics are: if the key ends in /, watch the keys underneath it - if not, watch that + * key. Our job is easier because keys and values are separate. + */ +static void +g_registry_backend_subscribe (GSettingsBackend *backend, + const char *key_name) +{ + GRegistryBackend *self = G_REGISTRY_BACKEND (backend); + gchar *path_name; + gunichar2 *path_namew; + gchar *value_name = NULL; + HKEY hpath; + HANDLE event; + LONG result; + + if (self->watch == NULL && !watch_start (self)) + return; + + if (g_atomic_int_dec_and_test (&self->watch->watches_remaining)) + { + g_atomic_int_inc (&self->watch->watches_remaining); + g_warning ("subscribe() failed: only %i different paths may be watched.", MAX_WATCHES); + return; + } + + path_name = parse_key (key_name, self->base_path, &value_name); + + /* Must check for this, otherwise strange crashes occur because the cache + * node that is being watched gets freed. All path names to subscribe must + * end in a slash! + */ + if (value_name != NULL && *value_name != 0) + g_warning ("subscribe() failed: path must end in a /, got %s", key_name); + + trace ("Subscribing to %s [registry %s / %s] - watch %x\n", key_name, path_name, value_name, self->watch); + + path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL); + g_free (path_name); + + /* Give the caller the benefit of the doubt if the key doesn't exist and create it. The caller + * is almost certainly a new g_settings with this path as base path. */ + result = RegCreateKeyExW (HKEY_CURRENT_USER, path_namew, 0, NULL, 0, KEY_READ, NULL, &hpath, + NULL); + g_free (path_namew); + + if (result != ERROR_SUCCESS) + { + g_message_win32_error (result, "gregistrybackend: Unable to subscribe to key %s.", key_name); + g_atomic_int_inc (&self->watch->watches_remaining); + return; + } + + event = CreateEvent (NULL, FALSE, FALSE, NULL); + if (event == NULL) + { + g_message_win32_error (result, "gregistrybackend: CreateEvent failed."); + g_atomic_int_inc (&self->watch->watches_remaining); + RegCloseKey (hpath); + return; + } + + /* The actual watch is added by the thread, which has to re-subscribe each time it + * receives a change. */ + if (!watch_add_notify (self, event, hpath, g_strdup (key_name))) + { + g_atomic_int_inc (&self->watch->watches_remaining); + RegCloseKey (hpath); + CloseHandle (event); + } +} + +static void +g_registry_backend_unsubscribe (GSettingsBackend *backend, + const char *key_name) +{ + trace ("unsubscribe: %s.\n", key_name); + + watch_remove_notify (G_REGISTRY_BACKEND (backend), key_name); +} + +/******************************************************************************** + * Object management junk + ********************************************************************************/ + +static void +g_registry_backend_finalize (GObject *object) +{ + GRegistryBackend *self = G_REGISTRY_BACKEND (object); + RegistryCacheItem *item; + + item = self->cache_root->data; + g_warn_if_fail (item->ref_count == 1); + + registry_cache_item_free (item); + g_node_destroy (self->cache_root); + + if (self->watch != NULL) + { + EnterCriticalSection (self->watch->message_lock); + watch_stop_unlocked (self); + } + + DeleteCriticalSection (self->cache_lock); + g_slice_free (CRITICAL_SECTION, self->cache_lock); + + g_free (self->base_path); + g_free (self->base_pathw); +} + +static void +g_registry_backend_class_init (GRegistryBackendClass *class) +{ + GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_registry_backend_finalize; + + backend_class->read = g_registry_backend_read; + backend_class->write = g_registry_backend_write; + backend_class->write_tree = g_registry_backend_write_tree; + backend_class->reset = g_registry_backend_reset; + backend_class->get_writable = g_registry_backend_get_writable; + backend_class->subscribe = g_registry_backend_subscribe; + backend_class->unsubscribe = g_registry_backend_unsubscribe; +} + +static void +g_registry_backend_init (GRegistryBackend *self) +{ + RegistryCacheItem *item; + + self->base_path = g_strdup_printf ("Software\\GSettings"); + self->base_pathw = g_utf8_to_utf16 (self->base_path, -1, NULL, NULL, NULL); + + item = g_slice_new (RegistryCacheItem); + item->value.type = REG_NONE; + item->value.ptr = NULL; + item->name = g_strdup (""); + item->ref_count = 1; + self->cache_root = g_node_new (item); + + self->cache_lock = g_slice_new (CRITICAL_SECTION); + InitializeCriticalSection (self->cache_lock); + + self->watch = NULL; +} diff --git a/gio/gregistrysettingsbackend.h b/gio/gregistrysettingsbackend.h new file mode 100644 index 0000000..13f8b4a --- /dev/null +++ b/gio/gregistrysettingsbackend.h @@ -0,0 +1,28 @@ +/* + * Copyright © 2009-10 Sam Thursfield + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Sam Thursfield + */ + +#ifndef __G_REGISTRY_SETTINGS_BACKEND_H__ +#define __G_REGISTRY_SETTINGS_BACKEND_H__ + +#include + +GType g_registry_backend_get_type (void); + + +#endif /* __G_REGISTRY_SETTINGS_BACKEND_H__ */ diff --git a/gio/gremoteactiongroup.c b/gio/gremoteactiongroup.c new file mode 100644 index 0000000..b8e2c0b --- /dev/null +++ b/gio/gremoteactiongroup.c @@ -0,0 +1,142 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gsimpleaction.h" +#include "gactiongroup.h" +#include "gactionmap.h" +#include "gaction.h" + +/** + * SECTION:gremoteactiongroup + * @title: GRemoteActionGroup + * @short_description: A GActionGroup that interacts with other processes + * @include: gio/gio.h + * + * The GRemoteActionGroup interface is implemented by #GActionGroup + * instances that either transmit action invocations to other processes + * or receive action invocations in the local process from other + * processes. + * + * The interface has `_full` variants of the two + * methods on #GActionGroup used to activate actions: + * g_action_group_activate_action() and + * g_action_group_change_action_state(). These variants allow a + * "platform data" #GVariant to be specified: a dictionary providing + * context for the action invocation (for example: timestamps, startup + * notification IDs, etc). + * + * #GDBusActionGroup implements #GRemoteActionGroup. This provides a + * mechanism to send platform data for action invocations over D-Bus. + * + * Additionally, g_dbus_connection_export_action_group() will check if + * the exported #GActionGroup implements #GRemoteActionGroup and use the + * `_full` variants of the calls if available. This + * provides a mechanism by which to receive platform data for action + * invocations that arrive by way of D-Bus. + * + * Since: 2.32 + **/ + +/** + * GRemoteActionGroup: + * + * #GRemoteActionGroup is an opaque data structure and can only be accessed + * using the following functions. + **/ + +/** + * GRemoteActionGroupInterface: + * @activate_action_full: the virtual function pointer for g_remote_action_group_activate_action_full() + * @change_action_state_full: the virtual function pointer for g_remote_action_group_change_action_state_full() + * + * The virtual function table for #GRemoteActionGroup. + * + * Since: 2.32 + **/ + +#include "config.h" + +#include "gremoteactiongroup.h" + +G_DEFINE_INTERFACE (GRemoteActionGroup, g_remote_action_group, G_TYPE_ACTION_GROUP) + +static void +g_remote_action_group_default_init (GRemoteActionGroupInterface *iface) +{ +} + +/** + * g_remote_action_group_activate_action_full: + * @remote: a #GDBusActionGroup + * @action_name: the name of the action to activate + * @parameter: (nullable): the optional parameter to the activation + * @platform_data: the platform data to send + * + * Activates the remote action. + * + * This is the same as g_action_group_activate_action() except that it + * allows for provision of "platform data" to be sent along with the + * activation request. This typically contains details such as the user + * interaction timestamp or startup notification information. + * + * @platform_data must be non-%NULL and must have the type + * %G_VARIANT_TYPE_VARDICT. If it is floating, it will be consumed. + * + * Since: 2.32 + **/ +void +g_remote_action_group_activate_action_full (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *parameter, + GVariant *platform_data) +{ + G_REMOTE_ACTION_GROUP_GET_IFACE (remote) + ->activate_action_full (remote, action_name, parameter, platform_data); +} + +/** + * g_remote_action_group_change_action_state_full: + * @remote: a #GRemoteActionGroup + * @action_name: the name of the action to change the state of + * @value: the new requested value for the state + * @platform_data: the platform data to send + * + * Changes the state of a remote action. + * + * This is the same as g_action_group_change_action_state() except that + * it allows for provision of "platform data" to be sent along with the + * state change request. This typically contains details such as the + * user interaction timestamp or startup notification information. + * + * @platform_data must be non-%NULL and must have the type + * %G_VARIANT_TYPE_VARDICT. If it is floating, it will be consumed. + * + * Since: 2.32 + **/ +void +g_remote_action_group_change_action_state_full (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *value, + GVariant *platform_data) +{ + G_REMOTE_ACTION_GROUP_GET_IFACE (remote) + ->change_action_state_full (remote, action_name, value, platform_data); +} diff --git a/gio/gremoteactiongroup.h b/gio/gremoteactiongroup.h new file mode 100644 index 0000000..206c737 --- /dev/null +++ b/gio/gremoteactiongroup.h @@ -0,0 +1,75 @@ +/* + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_REMOTE_ACTION_GROUP_H__ +#define __G_REMOTE_ACTION_GROUP_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + + +#define G_TYPE_REMOTE_ACTION_GROUP (g_remote_action_group_get_type ()) +#define G_REMOTE_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_REMOTE_ACTION_GROUP, GRemoteActionGroup)) +#define G_IS_REMOTE_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_REMOTE_ACTION_GROUP)) +#define G_REMOTE_ACTION_GROUP_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \ + G_TYPE_REMOTE_ACTION_GROUP, \ + GRemoteActionGroupInterface)) + +typedef struct _GRemoteActionGroupInterface GRemoteActionGroupInterface; + +struct _GRemoteActionGroupInterface +{ + GTypeInterface g_iface; + + void (* activate_action_full) (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *parameter, + GVariant *platform_data); + + void (* change_action_state_full) (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *value, + GVariant *platform_data); +}; + +GLIB_AVAILABLE_IN_2_32 +GType g_remote_action_group_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +void g_remote_action_group_activate_action_full (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *parameter, + GVariant *platform_data); + +GLIB_AVAILABLE_IN_2_32 +void g_remote_action_group_change_action_state_full (GRemoteActionGroup *remote, + const gchar *action_name, + GVariant *value, + GVariant *platform_data); + +G_END_DECLS + +#endif /* __G_REMOTE_ACTION_GROUP_H__ */ diff --git a/gio/gresolver.c b/gio/gresolver.c new file mode 100644 index 0000000..90b057c --- /dev/null +++ b/gio/gresolver.c @@ -0,0 +1,1254 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include +#include "glibintl.h" + +#include "gresolver.h" +#include "gnetworkingprivate.h" +#include "gasyncresult.h" +#include "ginetaddress.h" +#include "gtask.h" +#include "gsrvtarget.h" +#include "gthreadedresolver.h" +#include "gioerror.h" +#include "gcancellable.h" + +#ifdef G_OS_UNIX +#include +#endif + +#include + + +/** + * SECTION:gresolver + * @short_description: Asynchronous and cancellable DNS resolver + * @include: gio/gio.h + * + * #GResolver provides cancellable synchronous and asynchronous DNS + * resolution, for hostnames (g_resolver_lookup_by_address(), + * g_resolver_lookup_by_name() and their async variants) and SRV + * (service) records (g_resolver_lookup_service()). + * + * #GNetworkAddress and #GNetworkService provide wrappers around + * #GResolver functionality that also implement #GSocketConnectable, + * making it easy to connect to a remote host/service. + */ + +enum { + RELOAD, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +struct _GResolverPrivate { +#ifdef G_OS_UNIX + GMutex mutex; + time_t resolv_conf_timestamp; /* protected by @mutex */ +#else + int dummy; +#endif +}; + +/** + * GResolver: + * + * The object that handles DNS resolution. Use g_resolver_get_default() + * to get the default resolver. + * + * This is an abstract type; subclasses of it implement different resolvers for + * different platforms and situations. + */ +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GResolver, g_resolver, G_TYPE_OBJECT, + G_ADD_PRIVATE (GResolver) + g_networking_init ();) + +static GList * +srv_records_to_targets (GList *records) +{ + const gchar *hostname; + guint16 port, priority, weight; + GSrvTarget *target; + GList *l; + + for (l = records; l != NULL; l = g_list_next (l)) + { + g_variant_get (l->data, "(qqq&s)", &priority, &weight, &port, &hostname); + target = g_srv_target_new (hostname, port, priority, weight); + g_variant_unref (l->data); + l->data = target; + } + + return g_srv_target_list_sort (records); +} + +static GList * +g_resolver_real_lookup_service (GResolver *resolver, + const gchar *rrname, + GCancellable *cancellable, + GError **error) +{ + GList *records; + + records = G_RESOLVER_GET_CLASS (resolver)->lookup_records (resolver, + rrname, + G_RESOLVER_RECORD_SRV, + cancellable, + error); + + return srv_records_to_targets (records); +} + +static void +g_resolver_real_lookup_service_async (GResolver *resolver, + const gchar *rrname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + G_RESOLVER_GET_CLASS (resolver)->lookup_records_async (resolver, + rrname, + G_RESOLVER_RECORD_SRV, + cancellable, + callback, + user_data); +} + +static GList * +g_resolver_real_lookup_service_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + GList *records; + + records = G_RESOLVER_GET_CLASS (resolver)->lookup_records_finish (resolver, + result, + error); + + return srv_records_to_targets (records); +} + +static void +g_resolver_finalize (GObject *object) +{ +#ifdef G_OS_UNIX + GResolver *resolver = G_RESOLVER (object); + + g_mutex_clear (&resolver->priv->mutex); +#endif + + G_OBJECT_CLASS (g_resolver_parent_class)->finalize (object); +} + +static void +g_resolver_class_init (GResolverClass *resolver_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (resolver_class); + + object_class->finalize = g_resolver_finalize; + + /* Automatically pass these over to the lookup_records methods */ + resolver_class->lookup_service = g_resolver_real_lookup_service; + resolver_class->lookup_service_async = g_resolver_real_lookup_service_async; + resolver_class->lookup_service_finish = g_resolver_real_lookup_service_finish; + + /** + * GResolver::reload: + * @resolver: a #GResolver + * + * Emitted when the resolver notices that the system resolver + * configuration has changed. + **/ + signals[RELOAD] = + g_signal_new (I_("reload"), + G_TYPE_RESOLVER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GResolverClass, reload), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); +} + +static void +g_resolver_init (GResolver *resolver) +{ +#ifdef G_OS_UNIX + struct stat st; +#endif + + resolver->priv = g_resolver_get_instance_private (resolver); + +#ifdef G_OS_UNIX + if (stat (_PATH_RESCONF, &st) == 0) + resolver->priv->resolv_conf_timestamp = st.st_mtime; + + g_mutex_init (&resolver->priv->mutex); +#endif +} + +G_LOCK_DEFINE_STATIC (default_resolver); +static GResolver *default_resolver; + +/** + * g_resolver_get_default: + * + * Gets the default #GResolver. You should unref it when you are done + * with it. #GResolver may use its reference count as a hint about how + * many threads it should allocate for concurrent DNS resolutions. + * + * Returns: (transfer full): the default #GResolver. + * + * Since: 2.22 + */ +GResolver * +g_resolver_get_default (void) +{ + GResolver *ret; + + G_LOCK (default_resolver); + if (!default_resolver) + default_resolver = g_object_new (G_TYPE_THREADED_RESOLVER, NULL); + ret = g_object_ref (default_resolver); + G_UNLOCK (default_resolver); + + return ret; +} + +/** + * g_resolver_set_default: + * @resolver: the new default #GResolver + * + * Sets @resolver to be the application's default resolver (reffing + * @resolver, and unreffing the previous default resolver, if any). + * Future calls to g_resolver_get_default() will return this resolver. + * + * This can be used if an application wants to perform any sort of DNS + * caching or "pinning"; it can implement its own #GResolver that + * calls the original default resolver for DNS operations, and + * implements its own cache policies on top of that, and then set + * itself as the default resolver for all later code to use. + * + * Since: 2.22 + */ +void +g_resolver_set_default (GResolver *resolver) +{ + G_LOCK (default_resolver); + if (default_resolver) + g_object_unref (default_resolver); + default_resolver = g_object_ref (resolver); + G_UNLOCK (default_resolver); +} + +static void +maybe_emit_reload (GResolver *resolver) +{ +#ifdef G_OS_UNIX + struct stat st; + + if (stat (_PATH_RESCONF, &st) == 0) + { + g_mutex_lock (&resolver->priv->mutex); + if (st.st_mtime != resolver->priv->resolv_conf_timestamp) + { + resolver->priv->resolv_conf_timestamp = st.st_mtime; + g_mutex_unlock (&resolver->priv->mutex); + g_signal_emit (resolver, signals[RELOAD], 0); + } + else + g_mutex_unlock (&resolver->priv->mutex); + } +#endif +} + +/* filter out duplicates, cf. https://bugzilla.gnome.org/show_bug.cgi?id=631379 */ +static void +remove_duplicates (GList *addrs) +{ + GList *l; + GList *ll; + GList *lll; + + /* TODO: if this is too slow (it's O(n^2) but n is typically really + * small), we can do something more clever but note that we must not + * change the order of elements... + */ + for (l = addrs; l != NULL; l = l->next) + { + GInetAddress *address = G_INET_ADDRESS (l->data); + for (ll = l->next; ll != NULL; ll = lll) + { + GInetAddress *other_address = G_INET_ADDRESS (ll->data); + lll = ll->next; + if (g_inet_address_equal (address, other_address)) + { + g_object_unref (other_address); + /* we never return the first element */ + g_warn_if_fail (g_list_delete_link (addrs, ll) == addrs); + } + } + } +} + +static gboolean +hostname_is_localhost (const char *hostname) +{ + size_t len = strlen (hostname); + const char *p; + + /* Match "localhost", "localhost.", "*.localhost" and "*.localhost." */ + if (len < strlen ("localhost")) + return FALSE; + + if (hostname[len - 1] == '.') + len--; + + /* Scan backwards in @hostname to find the right-most dot (excluding the final dot, if it exists, as it was chopped off above). + * We can’t use strrchr() because because we need to operate with string lengths. + * End with @p pointing to the character after the right-most dot. */ + p = hostname + len - 1; + while (p >= hostname) + { + if (*p == '.') + { + p++; + break; + } + else if (p == hostname) + break; + p--; + } + + len -= p - hostname; + + return g_ascii_strncasecmp (p, "localhost", MAX (len, strlen ("localhost"))) == 0; +} + +/* Note that this does not follow the "FALSE means @error is set" + * convention. The return value tells the caller whether it should + * return @addrs and @error to the caller right away, or if it should + * continue and trying to resolve the name as a hostname. + */ +static gboolean +handle_ip_address_or_localhost (const char *hostname, + GList **addrs, + GResolverNameLookupFlags flags, + GError **error) +{ + GInetAddress *addr; + +#ifndef G_OS_WIN32 + struct in_addr ip4addr; +#endif + + addr = g_inet_address_new_from_string (hostname); + if (addr) + { + *addrs = g_list_append (NULL, addr); + return TRUE; + } + + *addrs = NULL; + +#ifdef G_OS_WIN32 + + /* Reject IPv6 addresses that have brackets ('[' or ']') and/or port numbers, + * as no valid addresses should contain these at this point. + * Non-standard IPv4 addresses would be rejected during the call to + * getaddrinfo() later. + */ + if (strrchr (hostname, '[') != NULL || + strrchr (hostname, ']') != NULL) +#else + + /* Reject non-standard IPv4 numbers-and-dots addresses. + * g_inet_address_new_from_string() will have accepted any "real" IP + * address, so if inet_aton() succeeds, then it's an address we want + * to reject. + */ + if (inet_aton (hostname, &ip4addr)) +#endif + { +#ifdef G_OS_WIN32 + gchar *error_message = g_win32_error_message (WSAHOST_NOT_FOUND); +#else + gchar *error_message = g_locale_to_utf8 (gai_strerror (EAI_NONAME), -1, NULL, NULL, NULL); + if (error_message == NULL) + error_message = g_strdup ("[Invalid UTF-8]"); +#endif + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + _("Error resolving “%sâ€: %s"), + hostname, error_message); + g_free (error_message); + + return TRUE; + } + + /* Always resolve localhost to a loopback address so it can be reliably considered secure. + This behavior is being adopted by browsers: + - https://w3c.github.io/webappsec-secure-contexts/ + - https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/RC9dSw-O3fE/E3_0XaT0BAAJ + - https://chromium.googlesource.com/chromium/src.git/+/8da2a80724a9b896890602ff77ef2216cb951399 + - https://bugs.webkit.org/show_bug.cgi?id=171934 + - https://tools.ietf.org/html/draft-west-let-localhost-be-localhost-06 + */ + if (hostname_is_localhost (hostname)) + { + if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY) + *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6)); + if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY) + *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4)); + if (*addrs == NULL) + { + *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6)); + *addrs = g_list_append (*addrs, g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4)); + } + return TRUE; + } + + return FALSE; +} + +static GList * +lookup_by_name_real (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GError **error) +{ + GList *addrs; + gchar *ascii_hostname = NULL; + + g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL); + g_return_val_if_fail (hostname != NULL, NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + /* Check if @hostname is just an IP address */ + if (handle_ip_address_or_localhost (hostname, &addrs, flags, error)) + return addrs; + + if (g_hostname_is_non_ascii (hostname)) + hostname = ascii_hostname = g_hostname_to_ascii (hostname); + + if (!hostname) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid hostname")); + return NULL; + } + + maybe_emit_reload (resolver); + + if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT) + { + if (!G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: The placeholder is for a function name. */ + _("%s not implemented"), "lookup_by_name_with_flags"); + g_free (ascii_hostname); + return NULL; + } + addrs = G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_name_with_flags (resolver, hostname, flags, cancellable, error); + } + else + addrs = G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_name (resolver, hostname, cancellable, error); + + remove_duplicates (addrs); + + g_free (ascii_hostname); + return addrs; +} + +/** + * g_resolver_lookup_by_name: + * @resolver: a #GResolver + * @hostname: the hostname to look up + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Synchronously resolves @hostname to determine its associated IP + * address(es). @hostname may be an ASCII-only or UTF-8 hostname, or + * the textual form of an IP address (in which case this just becomes + * a wrapper around g_inet_address_new_from_string()). + * + * On success, g_resolver_lookup_by_name() will return a non-empty #GList of + * #GInetAddress, sorted in order of preference and guaranteed to not + * contain duplicates. That is, if using the result to connect to + * @hostname, you should attempt to connect to the first address + * first, then the second if the first fails, etc. If you are using + * the result to listen on a socket, it is appropriate to add each + * result using e.g. g_socket_listener_add_address(). + * + * If the DNS resolution fails, @error (if non-%NULL) will be set to a + * value from #GResolverError and %NULL will be returned. + * + * If @cancellable is non-%NULL, it can be used to cancel the + * operation, in which case @error (if non-%NULL) will be set to + * %G_IO_ERROR_CANCELLED. + * + * If you are planning to connect to a socket on the resolved IP + * address, it may be easier to create a #GNetworkAddress and use its + * #GSocketConnectable interface. + * + * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList + * of #GInetAddress, or %NULL on error. You + * must unref each of the addresses and free the list when you are + * done with it. (You can use g_resolver_free_addresses() to do this.) + * + * Since: 2.22 + */ +GList * +g_resolver_lookup_by_name (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GError **error) +{ + return lookup_by_name_real (resolver, + hostname, + G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, + cancellable, + error); +} + +/** + * g_resolver_lookup_by_name_with_flags: + * @resolver: a #GResolver + * @hostname: the hostname to look up + * @flags: extra #GResolverNameLookupFlags for the lookup + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: (nullable): return location for a #GError, or %NULL + * + * This differs from g_resolver_lookup_by_name() in that you can modify + * the lookup behavior with @flags. For example this can be used to limit + * results with %G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY. + * + * Returns: (element-type GInetAddress) (transfer full): a non-empty #GList + * of #GInetAddress, or %NULL on error. You + * must unref each of the addresses and free the list when you are + * done with it. (You can use g_resolver_free_addresses() to do this.) + * + * Since: 2.60 + */ +GList * +g_resolver_lookup_by_name_with_flags (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GError **error) +{ + return lookup_by_name_real (resolver, + hostname, + flags, + cancellable, + error); +} + +static void +lookup_by_name_async_real (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + gchar *ascii_hostname = NULL; + GList *addrs; + GError *error = NULL; + + g_return_if_fail (G_IS_RESOLVER (resolver)); + g_return_if_fail (hostname != NULL); + g_return_if_fail (!(flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY && flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY)); + + /* Check if @hostname is just an IP address */ + if (handle_ip_address_or_localhost (hostname, &addrs, flags, &error)) + { + GTask *task; + + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, lookup_by_name_async_real); + g_task_set_name (task, "[gio] resolver lookup"); + if (addrs) + g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses); + else + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (g_hostname_is_non_ascii (hostname)) + hostname = ascii_hostname = g_hostname_to_ascii (hostname); + + if (!hostname) + { + GTask *task; + + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid hostname")); + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, lookup_by_name_async_real); + g_task_set_name (task, "[gio] resolver lookup"); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + maybe_emit_reload (resolver); + + if (flags != G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT) + { + if (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_async == NULL) + { + GTask *task; + + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: The placeholder is for a function name. */ + _("%s not implemented"), "lookup_by_name_with_flags_async"); + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, lookup_by_name_async_real); + g_task_set_name (task, "[gio] resolver lookup"); + g_task_return_error (task, error); + g_object_unref (task); + } + else + G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_name_with_flags_async (resolver, hostname, flags, cancellable, callback, user_data); + } + else + G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_name_async (resolver, hostname, cancellable, callback, user_data); + + g_free (ascii_hostname); +} + +static GList * +lookup_by_name_finish_real (GResolver *resolver, + GAsyncResult *result, + GError **error, + gboolean with_flags) +{ + GList *addrs; + + g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + else if (g_async_result_is_tagged (result, lookup_by_name_async_real)) + { + /* Handle the stringified-IP-addr case */ + return g_task_propagate_pointer (G_TASK (result), error); + } + + if (with_flags) + { + g_assert (G_RESOLVER_GET_CLASS (resolver)->lookup_by_name_with_flags_finish != NULL); + addrs = G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_name_with_flags_finish (resolver, result, error); + } + else + addrs = G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_name_finish (resolver, result, error); + + remove_duplicates (addrs); + + return addrs; +} + +/** + * g_resolver_lookup_by_name_with_flags_async: + * @resolver: a #GResolver + * @hostname: the hostname to look up the address of + * @flags: extra #GResolverNameLookupFlags for the lookup + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): callback to call after resolution completes + * @user_data: (closure): data for @callback + * + * Begins asynchronously resolving @hostname to determine its + * associated IP address(es), and eventually calls @callback, which + * must call g_resolver_lookup_by_name_with_flags_finish() to get the result. + * See g_resolver_lookup_by_name() for more details. + * + * Since: 2.60 + */ +void +g_resolver_lookup_by_name_with_flags_async (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + lookup_by_name_async_real (resolver, + hostname, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_resolver_lookup_by_name_async: + * @resolver: a #GResolver + * @hostname: the hostname to look up the address of + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): callback to call after resolution completes + * @user_data: (closure): data for @callback + * + * Begins asynchronously resolving @hostname to determine its + * associated IP address(es), and eventually calls @callback, which + * must call g_resolver_lookup_by_name_finish() to get the result. + * See g_resolver_lookup_by_name() for more details. + * + * Since: 2.22 + */ +void +g_resolver_lookup_by_name_async (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + lookup_by_name_async_real (resolver, + hostname, + 0, + cancellable, + callback, + user_data); +} + +/** + * g_resolver_lookup_by_name_finish: + * @resolver: a #GResolver + * @result: the result passed to your #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Retrieves the result of a call to + * g_resolver_lookup_by_name_async(). + * + * If the DNS resolution failed, @error (if non-%NULL) will be set to + * a value from #GResolverError. If the operation was cancelled, + * @error will be set to %G_IO_ERROR_CANCELLED. + * + * Returns: (element-type GInetAddress) (transfer full): a #GList + * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name() + * for more details. + * + * Since: 2.22 + */ +GList * +g_resolver_lookup_by_name_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + return lookup_by_name_finish_real (resolver, + result, + error, + FALSE); +} + +/** + * g_resolver_lookup_by_name_with_flags_finish: + * @resolver: a #GResolver + * @result: the result passed to your #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Retrieves the result of a call to + * g_resolver_lookup_by_name_with_flags_async(). + * + * If the DNS resolution failed, @error (if non-%NULL) will be set to + * a value from #GResolverError. If the operation was cancelled, + * @error will be set to %G_IO_ERROR_CANCELLED. + * + * Returns: (element-type GInetAddress) (transfer full): a #GList + * of #GInetAddress, or %NULL on error. See g_resolver_lookup_by_name() + * for more details. + * + * Since: 2.60 + */ +GList * +g_resolver_lookup_by_name_with_flags_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + return lookup_by_name_finish_real (resolver, + result, + error, + TRUE); +} + +/** + * g_resolver_free_addresses: (skip) + * @addresses: a #GList of #GInetAddress + * + * Frees @addresses (which should be the return value from + * g_resolver_lookup_by_name() or g_resolver_lookup_by_name_finish()). + * (This is a convenience method; you can also simply free the results + * by hand.) + * + * Since: 2.22 + */ +void +g_resolver_free_addresses (GList *addresses) +{ + GList *a; + + for (a = addresses; a; a = a->next) + g_object_unref (a->data); + g_list_free (addresses); +} + +/** + * g_resolver_lookup_by_address: + * @resolver: a #GResolver + * @address: the address to reverse-resolve + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Synchronously reverse-resolves @address to determine its + * associated hostname. + * + * If the DNS resolution fails, @error (if non-%NULL) will be set to + * a value from #GResolverError. + * + * If @cancellable is non-%NULL, it can be used to cancel the + * operation, in which case @error (if non-%NULL) will be set to + * %G_IO_ERROR_CANCELLED. + * + * Returns: a hostname (either ASCII-only, or in ASCII-encoded + * form), or %NULL on error. + * + * Since: 2.22 + */ +gchar * +g_resolver_lookup_by_address (GResolver *resolver, + GInetAddress *address, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL); + g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL); + + maybe_emit_reload (resolver); + return G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_address (resolver, address, cancellable, error); +} + +/** + * g_resolver_lookup_by_address_async: + * @resolver: a #GResolver + * @address: the address to reverse-resolve + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): callback to call after resolution completes + * @user_data: (closure): data for @callback + * + * Begins asynchronously reverse-resolving @address to determine its + * associated hostname, and eventually calls @callback, which must + * call g_resolver_lookup_by_address_finish() to get the final result. + * + * Since: 2.22 + */ +void +g_resolver_lookup_by_address_async (GResolver *resolver, + GInetAddress *address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_RESOLVER (resolver)); + g_return_if_fail (G_IS_INET_ADDRESS (address)); + + maybe_emit_reload (resolver); + G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_address_async (resolver, address, cancellable, callback, user_data); +} + +/** + * g_resolver_lookup_by_address_finish: + * @resolver: a #GResolver + * @result: the result passed to your #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Retrieves the result of a previous call to + * g_resolver_lookup_by_address_async(). + * + * If the DNS resolution failed, @error (if non-%NULL) will be set to + * a value from #GResolverError. If the operation was cancelled, + * @error will be set to %G_IO_ERROR_CANCELLED. + * + * Returns: a hostname (either ASCII-only, or in ASCII-encoded + * form), or %NULL on error. + * + * Since: 2.22 + */ +gchar * +g_resolver_lookup_by_address_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + + return G_RESOLVER_GET_CLASS (resolver)-> + lookup_by_address_finish (resolver, result, error); +} + +static gchar * +g_resolver_get_service_rrname (const char *service, + const char *protocol, + const char *domain) +{ + gchar *rrname, *ascii_domain = NULL; + + if (g_hostname_is_non_ascii (domain)) + domain = ascii_domain = g_hostname_to_ascii (domain); + if (!domain) + return NULL; + + rrname = g_strdup_printf ("_%s._%s.%s", service, protocol, domain); + + g_free (ascii_domain); + return rrname; +} + +/** + * g_resolver_lookup_service: + * @resolver: a #GResolver + * @service: the service type to look up (eg, "ldap") + * @protocol: the networking protocol to use for @service (eg, "tcp") + * @domain: the DNS domain to look up the service in + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Synchronously performs a DNS SRV lookup for the given @service and + * @protocol in the given @domain and returns an array of #GSrvTarget. + * @domain may be an ASCII-only or UTF-8 hostname. Note also that the + * @service and @protocol arguments do not include the leading underscore + * that appears in the actual DNS entry. + * + * On success, g_resolver_lookup_service() will return a non-empty #GList of + * #GSrvTarget, sorted in order of preference. (That is, you should + * attempt to connect to the first target first, then the second if + * the first fails, etc.) + * + * If the DNS resolution fails, @error (if non-%NULL) will be set to + * a value from #GResolverError and %NULL will be returned. + * + * If @cancellable is non-%NULL, it can be used to cancel the + * operation, in which case @error (if non-%NULL) will be set to + * %G_IO_ERROR_CANCELLED. + * + * If you are planning to connect to the service, it is usually easier + * to create a #GNetworkService and use its #GSocketConnectable + * interface. + * + * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of + * #GSrvTarget, or %NULL on error. You must free each of the targets and the + * list when you are done with it. (You can use g_resolver_free_targets() to do + * this.) + * + * Since: 2.22 + */ +GList * +g_resolver_lookup_service (GResolver *resolver, + const gchar *service, + const gchar *protocol, + const gchar *domain, + GCancellable *cancellable, + GError **error) +{ + GList *targets; + gchar *rrname; + + g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL); + g_return_val_if_fail (service != NULL, NULL); + g_return_val_if_fail (protocol != NULL, NULL); + g_return_val_if_fail (domain != NULL, NULL); + + rrname = g_resolver_get_service_rrname (service, protocol, domain); + if (!rrname) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid domain")); + return NULL; + } + + maybe_emit_reload (resolver); + targets = G_RESOLVER_GET_CLASS (resolver)-> + lookup_service (resolver, rrname, cancellable, error); + + g_free (rrname); + return targets; +} + +/** + * g_resolver_lookup_service_async: + * @resolver: a #GResolver + * @service: the service type to look up (eg, "ldap") + * @protocol: the networking protocol to use for @service (eg, "tcp") + * @domain: the DNS domain to look up the service in + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): callback to call after resolution completes + * @user_data: (closure): data for @callback + * + * Begins asynchronously performing a DNS SRV lookup for the given + * @service and @protocol in the given @domain, and eventually calls + * @callback, which must call g_resolver_lookup_service_finish() to + * get the final result. See g_resolver_lookup_service() for more + * details. + * + * Since: 2.22 + */ +void +g_resolver_lookup_service_async (GResolver *resolver, + const gchar *service, + const gchar *protocol, + const gchar *domain, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + gchar *rrname; + + g_return_if_fail (G_IS_RESOLVER (resolver)); + g_return_if_fail (service != NULL); + g_return_if_fail (protocol != NULL); + g_return_if_fail (domain != NULL); + + rrname = g_resolver_get_service_rrname (service, protocol, domain); + if (!rrname) + { + g_task_report_new_error (resolver, callback, user_data, + g_resolver_lookup_service_async, + G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid domain")); + return; + } + + maybe_emit_reload (resolver); + G_RESOLVER_GET_CLASS (resolver)-> + lookup_service_async (resolver, rrname, cancellable, callback, user_data); + + g_free (rrname); +} + +/** + * g_resolver_lookup_service_finish: + * @resolver: a #GResolver + * @result: the result passed to your #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Retrieves the result of a previous call to + * g_resolver_lookup_service_async(). + * + * If the DNS resolution failed, @error (if non-%NULL) will be set to + * a value from #GResolverError. If the operation was cancelled, + * @error will be set to %G_IO_ERROR_CANCELLED. + * + * Returns: (element-type GSrvTarget) (transfer full): a non-empty #GList of + * #GSrvTarget, or %NULL on error. See g_resolver_lookup_service() for more + * details. + * + * Since: 2.22 + */ +GList * +g_resolver_lookup_service_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL); + + if (g_async_result_legacy_propagate_error (result, error)) + return NULL; + + return G_RESOLVER_GET_CLASS (resolver)-> + lookup_service_finish (resolver, result, error); +} + +/** + * g_resolver_free_targets: (skip) + * @targets: a #GList of #GSrvTarget + * + * Frees @targets (which should be the return value from + * g_resolver_lookup_service() or g_resolver_lookup_service_finish()). + * (This is a convenience method; you can also simply free the + * results by hand.) + * + * Since: 2.22 + */ +void +g_resolver_free_targets (GList *targets) +{ + GList *t; + + for (t = targets; t; t = t->next) + g_srv_target_free (t->data); + g_list_free (targets); +} + +/** + * g_resolver_lookup_records: + * @resolver: a #GResolver + * @rrname: the DNS name to look up the record for + * @record_type: the type of DNS record to look up + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Synchronously performs a DNS record lookup for the given @rrname and returns + * a list of records as #GVariant tuples. See #GResolverRecordType for + * information on what the records contain for each @record_type. + * + * If the DNS resolution fails, @error (if non-%NULL) will be set to + * a value from #GResolverError and %NULL will be returned. + * + * If @cancellable is non-%NULL, it can be used to cancel the + * operation, in which case @error (if non-%NULL) will be set to + * %G_IO_ERROR_CANCELLED. + * + * Returns: (element-type GVariant) (transfer full): a non-empty #GList of + * #GVariant, or %NULL on error. You must free each of the records and the list + * when you are done with it. (You can use g_list_free_full() with + * g_variant_unref() to do this.) + * + * Since: 2.34 + */ +GList * +g_resolver_lookup_records (GResolver *resolver, + const gchar *rrname, + GResolverRecordType record_type, + GCancellable *cancellable, + GError **error) +{ + GList *records; + + g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL); + g_return_val_if_fail (rrname != NULL, NULL); + + maybe_emit_reload (resolver); + records = G_RESOLVER_GET_CLASS (resolver)-> + lookup_records (resolver, rrname, record_type, cancellable, error); + + return records; +} + +/** + * g_resolver_lookup_records_async: + * @resolver: a #GResolver + * @rrname: the DNS name to look up the record for + * @record_type: the type of DNS record to look up + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): callback to call after resolution completes + * @user_data: (closure): data for @callback + * + * Begins asynchronously performing a DNS lookup for the given + * @rrname, and eventually calls @callback, which must call + * g_resolver_lookup_records_finish() to get the final result. See + * g_resolver_lookup_records() for more details. + * + * Since: 2.34 + */ +void +g_resolver_lookup_records_async (GResolver *resolver, + const gchar *rrname, + GResolverRecordType record_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_RESOLVER (resolver)); + g_return_if_fail (rrname != NULL); + + maybe_emit_reload (resolver); + G_RESOLVER_GET_CLASS (resolver)-> + lookup_records_async (resolver, rrname, record_type, cancellable, callback, user_data); +} + +/** + * g_resolver_lookup_records_finish: + * @resolver: a #GResolver + * @result: the result passed to your #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Retrieves the result of a previous call to + * g_resolver_lookup_records_async(). Returns a non-empty list of records as + * #GVariant tuples. See #GResolverRecordType for information on what the + * records contain. + * + * If the DNS resolution failed, @error (if non-%NULL) will be set to + * a value from #GResolverError. If the operation was cancelled, + * @error will be set to %G_IO_ERROR_CANCELLED. + * + * Returns: (element-type GVariant) (transfer full): a non-empty #GList of + * #GVariant, or %NULL on error. You must free each of the records and the list + * when you are done with it. (You can use g_list_free_full() with + * g_variant_unref() to do this.) + * + * Since: 2.34 + */ +GList * +g_resolver_lookup_records_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_RESOLVER (resolver), NULL); + return G_RESOLVER_GET_CLASS (resolver)-> + lookup_records_finish (resolver, result, error); +} + +guint64 +g_resolver_get_serial (GResolver *resolver) +{ + guint64 result; + + g_return_val_if_fail (G_IS_RESOLVER (resolver), 0); + + maybe_emit_reload (resolver); + +#ifdef G_OS_UNIX + g_mutex_lock (&resolver->priv->mutex); + result = resolver->priv->resolv_conf_timestamp; + g_mutex_unlock (&resolver->priv->mutex); +#else + result = 1; +#endif + + return result; +} + +/** + * g_resolver_error_quark: + * + * Gets the #GResolver Error Quark. + * + * Returns: a #GQuark. + * + * Since: 2.22 + */ +G_DEFINE_QUARK (g-resolver-error-quark, g_resolver_error) diff --git a/gio/gresolver.h b/gio/gresolver.h new file mode 100644 index 0000000..dc4ba59 --- /dev/null +++ b/gio/gresolver.h @@ -0,0 +1,292 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_RESOLVER_H__ +#define __G_RESOLVER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_RESOLVER (g_resolver_get_type ()) +#define G_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_RESOLVER, GResolver)) +#define G_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_RESOLVER, GResolverClass)) +#define G_IS_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_RESOLVER)) +#define G_IS_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_RESOLVER)) +#define G_RESOLVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_RESOLVER, GResolverClass)) + +typedef struct _GResolverPrivate GResolverPrivate; +typedef struct _GResolverClass GResolverClass; + +struct _GResolver { + GObject parent_instance; + + GResolverPrivate *priv; +}; + +/** + * GResolverNameLookupFlags: + * @G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT: default behavior (same as g_resolver_lookup_by_name()) + * @G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY: only resolve ipv4 addresses + * @G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY: only resolve ipv6 addresses + * + * Flags to modify lookup behavior. + * + * Since: 2.60 + */ +typedef enum { + G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT = 0, + G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY = 1 << 0, + G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY = 1 << 1, +} GResolverNameLookupFlags; + +struct _GResolverClass { + GObjectClass parent_class; + + /* Signals */ + void ( *reload) (GResolver *resolver); + + /* Virtual methods */ + GList * ( *lookup_by_name) (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GError **error); + void ( *lookup_by_name_async) (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GList * ( *lookup_by_name_finish) (GResolver *resolver, + GAsyncResult *result, + GError **error); + + gchar * ( *lookup_by_address) (GResolver *resolver, + GInetAddress *address, + GCancellable *cancellable, + GError **error); + void ( *lookup_by_address_async) (GResolver *resolver, + GInetAddress *address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gchar * ( *lookup_by_address_finish) (GResolver *resolver, + GAsyncResult *result, + GError **error); + + GList * ( *lookup_service) (GResolver *resolver, + const gchar *rrname, + GCancellable *cancellable, + GError **error); + void ( *lookup_service_async) (GResolver *resolver, + const gchar *rrname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GList * ( *lookup_service_finish) (GResolver *resolver, + GAsyncResult *result, + GError **error); + + GList * ( *lookup_records) (GResolver *resolver, + const gchar *rrname, + GResolverRecordType record_type, + GCancellable *cancellable, + GError **error); + + void ( *lookup_records_async) (GResolver *resolver, + const gchar *rrname, + GResolverRecordType record_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + GList * ( *lookup_records_finish) (GResolver *resolver, + GAsyncResult *result, + GError **error); + /** + * GResolverClass::lookup_by_name_with_flags_async: + * @resolver: a #GResolver + * @hostname: the hostname to resolve + * @flags: extra #GResolverNameLookupFlags to modify the lookup + * @cancellable: (nullable): a #GCancellable + * @callback: (scope async): a #GAsyncReadyCallback to call when completed + * @user_data: (closure): data to pass to @callback + * + * Asynchronous version of GResolverClass::lookup_by_name_with_flags + * + * GResolverClass::lookup_by_name_with_flags_finish will be called to get + * the result. + * + * Since: 2.60 + */ + void ( *lookup_by_name_with_flags_async) (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + /** + * GResolverClass::lookup_by_name_with_flags_finish: + * @resolver: a #GResolver + * @result: a #GAsyncResult + * @error: (nullable): a pointer to a %NULL #GError + * + * Gets the result from GResolverClass::lookup_by_name_with_flags_async + * + * Returns: (element-type GInetAddress) (transfer full): List of #GInetAddress. + * Since: 2.60 + */ + GList * ( *lookup_by_name_with_flags_finish) (GResolver *resolver, + GAsyncResult *result, + GError **error); + /** + * GResolverClass::lookup_by_name_with_flags: + * @resolver: a #GResolver + * @hostname: the hostname to resolve + * @flags: extra #GResolverNameLookupFlags to modify the lookup + * @cancellable: (nullable): a #GCancellable + * @error: (nullable): a pointer to a %NULL #GError + * + * This is identical to GResolverClass::lookup_by_name except it takes + * @flags which modifies the behavior of the lookup. See #GResolverNameLookupFlags + * for more details. + * + * Returns: (element-type GInetAddress) (transfer full): List of #GInetAddress. + * Since: 2.60 + */ + GList * ( *lookup_by_name_with_flags) (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GError **error); + +}; + +GLIB_AVAILABLE_IN_ALL +GType g_resolver_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GResolver *g_resolver_get_default (void); +GLIB_AVAILABLE_IN_ALL +void g_resolver_set_default (GResolver *resolver); +GLIB_AVAILABLE_IN_ALL +GList *g_resolver_lookup_by_name (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_resolver_lookup_by_name_async (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GList *g_resolver_lookup_by_name_finish (GResolver *resolver, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_2_60 +void g_resolver_lookup_by_name_with_flags_async (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_60 +GList *g_resolver_lookup_by_name_with_flags_finish (GResolver *resolver, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_2_60 +GList *g_resolver_lookup_by_name_with_flags (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_resolver_free_addresses (GList *addresses); +GLIB_AVAILABLE_IN_ALL +gchar *g_resolver_lookup_by_address (GResolver *resolver, + GInetAddress *address, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_resolver_lookup_by_address_async (GResolver *resolver, + GInetAddress *address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gchar *g_resolver_lookup_by_address_finish (GResolver *resolver, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +GList *g_resolver_lookup_service (GResolver *resolver, + const gchar *service, + const gchar *protocol, + const gchar *domain, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_resolver_lookup_service_async (GResolver *resolver, + const gchar *service, + const gchar *protocol, + const gchar *domain, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GList *g_resolver_lookup_service_finish (GResolver *resolver, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_2_34 +GList *g_resolver_lookup_records (GResolver *resolver, + const gchar *rrname, + GResolverRecordType record_type, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_34 +void g_resolver_lookup_records_async (GResolver *resolver, + const gchar *rrname, + GResolverRecordType record_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_34 +GList *g_resolver_lookup_records_finish (GResolver *resolver, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_resolver_free_targets (GList *targets); + + +/** + * G_RESOLVER_ERROR: + * + * Error domain for #GResolver. Errors in this domain will be from the + * #GResolverError enumeration. See #GError for more information on + * error domains. + */ +#define G_RESOLVER_ERROR (g_resolver_error_quark ()) +GLIB_AVAILABLE_IN_ALL +GQuark g_resolver_error_quark (void); + +G_END_DECLS + +#endif /* __G_RESOLVER_H__ */ diff --git a/gio/gresource-tool.c b/gio/gresource-tool.c new file mode 100644 index 0000000..7ebddda --- /dev/null +++ b/gio/gresource-tool.c @@ -0,0 +1,664 @@ +/* + * Copyright © 2012 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef HAVE_LIBELF +#include +#include +#endif + +#ifdef HAVE_MMAP +#include +#endif + +#include +#include +#include + +#include "glib/glib-private.h" + +#if defined(HAVE_LIBELF) && defined(HAVE_MMAP) +#define USE_LIBELF +#endif + +/* GResource functions {{{1 */ +static GResource * +get_resource (const gchar *file) +{ + gchar *content; + gsize size; + GResource *resource; + GBytes *data; + + resource = NULL; + + if (g_file_get_contents (file, &content, &size, NULL)) + { + data = g_bytes_new_take (content, size); + resource = g_resource_new_from_data (data, NULL); + g_bytes_unref (data); + } + + return resource; +} + +static void +list_resource (GResource *resource, + const gchar *path, + const gchar *section, + const gchar *prefix, + gboolean details) +{ + gchar **children; + gsize size; + guint32 flags; + gint i; + gchar *child; + GError *error = NULL; + gint len; + + children = g_resource_enumerate_children (resource, path, 0, &error); + if (error) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + return; + } + for (i = 0; children[i]; i++) + { + child = g_strconcat (path, children[i], NULL); + + len = MIN (strlen (child), strlen (prefix)); + if (strncmp (child, prefix, len) != 0) + { + g_free (child); + continue; + } + + if (g_resource_get_info (resource, child, 0, &size, &flags, NULL)) + { + if (details) + g_print ("%s%s%6"G_GSIZE_FORMAT " %s %s\n", section, section[0] ? " " : "", size, (flags & G_RESOURCE_FLAGS_COMPRESSED) ? "c" : "u", child); + else + g_print ("%s\n", child); + } + else + list_resource (resource, child, section, prefix, details); + + g_free (child); + } + g_strfreev (children); +} + +static void +extract_resource (GResource *resource, + const gchar *path) +{ + GBytes *bytes; + + bytes = g_resource_lookup_data (resource, path, 0, NULL); + if (bytes != NULL) + { + gconstpointer data; + gsize size, written; + + data = g_bytes_get_data (bytes, &size); + written = fwrite (data, 1, size, stdout); + if (written < size) + g_printerr ("Data truncated\n"); + g_bytes_unref (bytes); + } +} + +/* Elf functions {{{1 */ + +#ifdef USE_LIBELF + +static Elf * +get_elf (const gchar *file, + gint *fd) +{ + Elf *elf; + + if (elf_version (EV_CURRENT) == EV_NONE ) + return NULL; + + *fd = g_open (file, O_RDONLY, 0); + if (*fd < 0) + return NULL; + + elf = elf_begin (*fd, ELF_C_READ, NULL); + if (elf == NULL) + { + g_close (*fd, NULL); + *fd = -1; + return NULL; + } + + if (elf_kind (elf) != ELF_K_ELF) + { + g_close (*fd, NULL); + *fd = -1; + return NULL; + } + + return elf; +} + +typedef gboolean (*SectionCallback) (GElf_Shdr *shdr, + const gchar *name, + gpointer data); + +static void +elf_foreach_resource_section (Elf *elf, + SectionCallback callback, + gpointer data) +{ + int ret G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + size_t shstrndx, shnum; + size_t scnidx; + Elf_Scn *scn; + GElf_Shdr *shdr, shdr_mem; + const gchar *section_name; + + ret = elf_getshdrstrndx (elf, &shstrndx); + g_assert (ret == 0); + + ret = elf_getshdrnum (elf, &shnum); + g_assert (ret == 0); + + for (scnidx = 1; scnidx < shnum; scnidx++) + { + scn = elf_getscn (elf, scnidx); + if (scn == NULL) + continue; + + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + continue; + + if (shdr->sh_type != SHT_PROGBITS) + continue; + + section_name = elf_strptr (elf, shstrndx, shdr->sh_name); + if (section_name == NULL || + !g_str_has_prefix (section_name, ".gresource.")) + continue; + + if (!callback (shdr, section_name + strlen (".gresource."), data)) + break; + } +} + +static GResource * +resource_from_section (GElf_Shdr *shdr, + int fd) +{ + gsize page_size, page_offset; + char *contents; + GResource *resource; + + resource = NULL; + + page_size = sysconf(_SC_PAGE_SIZE); + page_offset = shdr->sh_offset % page_size; + contents = mmap (NULL, shdr->sh_size + page_offset, + PROT_READ, MAP_PRIVATE, fd, shdr->sh_offset - page_offset); + if (contents != MAP_FAILED) + { + GBytes *bytes; + GError *error = NULL; + + bytes = g_bytes_new_static (contents + page_offset, shdr->sh_size); + resource = g_resource_new_from_data (bytes, &error); + g_bytes_unref (bytes); + if (error) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + } + } + else + { + g_printerr ("Can't mmap resource section"); + } + + return resource; +} + +typedef struct +{ + int fd; + const gchar *section; + const gchar *path; + gboolean details; + gboolean found; +} CallbackData; + +static gboolean +list_resources_cb (GElf_Shdr *shdr, + const gchar *section, + gpointer data) +{ + CallbackData *d = data; + GResource *resource; + + if (d->section && strcmp (section, d->section) != 0) + return TRUE; + + d->found = TRUE; + + resource = resource_from_section (shdr, d->fd); + list_resource (resource, "/", + d->section ? "" : section, + d->path, + d->details); + g_resource_unref (resource); + + if (d->section) + return FALSE; + + return TRUE; +} + +static void +elf_list_resources (Elf *elf, + int fd, + const gchar *section, + const gchar *path, + gboolean details) +{ + CallbackData data; + + data.fd = fd; + data.section = section; + data.path = path; + data.details = details; + data.found = FALSE; + + elf_foreach_resource_section (elf, list_resources_cb, &data); + + if (!data.found) + g_printerr ("Can't find resource section %s\n", section); +} + +static gboolean +extract_resource_cb (GElf_Shdr *shdr, + const gchar *section, + gpointer data) +{ + CallbackData *d = data; + GResource *resource; + + if (d->section && strcmp (section, d->section) != 0) + return TRUE; + + d->found = TRUE; + + resource = resource_from_section (shdr, d->fd); + extract_resource (resource, d->path); + g_resource_unref (resource); + + if (d->section) + return FALSE; + + return TRUE; +} + +static void +elf_extract_resource (Elf *elf, + int fd, + const gchar *section, + const gchar *path) +{ + CallbackData data; + + data.fd = fd; + data.section = section; + data.path = path; + data.found = FALSE; + + elf_foreach_resource_section (elf, extract_resource_cb, &data); + + if (!data.found) + g_printerr ("Can't find resource section %s\n", section); +} + +static gboolean +print_section_name (GElf_Shdr *shdr, + const gchar *name, + gpointer data) +{ + g_print ("%s\n", name); + return TRUE; +} + +#endif /* USE_LIBELF */ + + /* Toplevel commands {{{1 */ + +static void +cmd_sections (const gchar *file, + const gchar *section, + const gchar *path, + gboolean details) +{ + GResource *resource; + +#ifdef USE_LIBELF + + Elf *elf; + gint fd; + + if ((elf = get_elf (file, &fd))) + { + elf_foreach_resource_section (elf, print_section_name, NULL); + elf_end (elf); + close (fd); + } + else + +#endif + + if ((resource = get_resource (file))) + { + /* No sections */ + g_resource_unref (resource); + } + else + { + g_printerr ("Don't know how to handle %s\n", file); +#ifndef USE_LIBELF + g_printerr ("gresource is built without elf support\n"); +#endif + } +} + +static void +cmd_list (const gchar *file, + const gchar *section, + const gchar *path, + gboolean details) +{ + GResource *resource; + +#ifdef USE_LIBELF + Elf *elf; + int fd; + + if ((elf = get_elf (file, &fd))) + { + elf_list_resources (elf, fd, section, path ? path : "", details); + elf_end (elf); + close (fd); + } + else + +#endif + + if ((resource = get_resource (file))) + { + list_resource (resource, "/", "", path ? path : "", details); + g_resource_unref (resource); + } + else + { + g_printerr ("Don't know how to handle %s\n", file); +#ifndef USE_LIBELF + g_printerr ("gresource is built without elf support\n"); +#endif + } +} + +static void +cmd_extract (const gchar *file, + const gchar *section, + const gchar *path, + gboolean details) +{ + GResource *resource; + +#ifdef USE_LIBELF + + Elf *elf; + int fd; + + if ((elf = get_elf (file, &fd))) + { + elf_extract_resource (elf, fd, section, path); + elf_end (elf); + close (fd); + } + else + +#endif + + if ((resource = get_resource (file))) + { + extract_resource (resource, path); + g_resource_unref (resource); + } + else + { + g_printerr ("Don't know how to handle %s\n", file); +#ifndef USE_LIBELF + g_printerr ("gresource is built without elf support\n"); +#endif + } +} + +static gint +cmd_help (gboolean requested, + const gchar *command) +{ + const gchar *description = NULL; + const gchar *synopsis = NULL; + gchar *option; + GString *string; + + option = NULL; + + string = g_string_new (NULL); + + if (command == NULL) + ; + + else if (strcmp (command, "help") == 0) + { + description = _("Print help"); + synopsis = _("[COMMAND]"); + } + + else if (strcmp (command, "sections") == 0) + { + description = _("List sections containing resources in an elf FILE"); + synopsis = _("FILE"); + } + + else if (strcmp (command, "list") == 0) + { + description = _("List resources\n" + "If SECTION is given, only list resources in this section\n" + "If PATH is given, only list matching resources"); + synopsis = _("FILE [PATH]"); + option = g_strdup_printf ("[--section %s]", _("SECTION")); + } + + else if (strcmp (command, "details") == 0) + { + description = _("List resources with details\n" + "If SECTION is given, only list resources in this section\n" + "If PATH is given, only list matching resources\n" + "Details include the section, size and compression"); + synopsis = _("FILE [PATH]"); + option = g_strdup_printf ("[--section %s]", _("SECTION")); + } + + else if (strcmp (command, "extract") == 0) + { + description = _("Extract a resource file to stdout"); + synopsis = _("FILE PATH"); + option = g_strdup_printf ("[--section %s]", _("SECTION")); + } + + else + { + g_string_printf (string, _("Unknown command %s\n\n"), command); + requested = FALSE; + command = NULL; + } + + if (command == NULL) + { + g_string_append (string, + _("Usage:\n" + " gresource [--section SECTION] COMMAND [ARGS…]\n" + "\n" + "Commands:\n" + " help Show this information\n" + " sections List resource sections\n" + " list List resources\n" + " details List resources with details\n" + " extract Extract a resource\n" + "\n" + "Use “gresource help COMMAND†to get detailed help.\n\n")); + } + else + { + g_string_append_printf (string, _("Usage:\n gresource %s%s%s %s\n\n%s\n\n"), + option ? option : "", option ? " " : "", command, synopsis[0] ? synopsis : "", description); + + g_string_append (string, _("Arguments:\n")); + + if (option) + g_string_append (string, + _(" SECTION An (optional) elf section name\n")); + + if (strstr (synopsis, _("[COMMAND]"))) + g_string_append (string, + _(" COMMAND The (optional) command to explain\n")); + + if (strstr (synopsis, _("FILE"))) + { + if (strcmp (command, "sections") == 0) + g_string_append (string, + _(" FILE An elf file (a binary or a shared library)\n")); + else + g_string_append (string, + _(" FILE An elf file (a binary or a shared library)\n" + " or a compiled resource file\n")); + } + + if (strstr (synopsis, _("[PATH]"))) + g_string_append (string, + _(" PATH An (optional) resource path (may be partial)\n")); + else if (strstr (synopsis, _("PATH"))) + g_string_append (string, + _(" PATH A resource path\n")); + + g_string_append (string, "\n"); + } + + if (requested) + g_print ("%s", string->str); + else + g_printerr ("%s\n", string->str); + + g_free (option); + g_string_free (string, TRUE); + + return requested ? 0 : 1; +} + +/* main {{{1 */ + +int +main (int argc, char *argv[]) +{ + gchar *section = NULL; + gboolean details = FALSE; + void (* function) (const gchar *, const gchar *, const gchar *, gboolean); + +#ifdef G_OS_WIN32 + gchar *tmp; +#endif + + setlocale (LC_ALL, GLIB_DEFAULT_LOCALE); + textdomain (GETTEXT_PACKAGE); + +#ifdef G_OS_WIN32 + tmp = _glib_get_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, tmp); + g_free (tmp); +#else + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#endif + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + + if (argc < 2) + return cmd_help (FALSE, NULL); + + if (argc > 3 && strcmp (argv[1], "--section") == 0) + { + section = argv[2]; + argv = argv + 2; + argc -= 2; + } + + if (strcmp (argv[1], "help") == 0) + return cmd_help (TRUE, argv[2]); + + else if (argc == 4 && strcmp (argv[1], "extract") == 0) + function = cmd_extract; + + else if (argc == 3 && strcmp (argv[1], "sections") == 0) + function = cmd_sections; + + else if ((argc == 3 || argc == 4) && strcmp (argv[1], "list") == 0) + { + function = cmd_list; + details = FALSE; + } + else if ((argc == 3 || argc == 4) && strcmp (argv[1], "details") == 0) + { + function = cmd_list; + details = TRUE; + } + else + return cmd_help (FALSE, argv[1]); + + (* function) (argv[2], section, argc > 3 ? argv[3] : NULL, details); + + return 0; +} + +/* vim:set foldmethod=marker: */ diff --git a/gio/gresource.c b/gio/gresource.c new file mode 100644 index 0000000..45ca92b --- /dev/null +++ b/gio/gresource.c @@ -0,0 +1,1475 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2011 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "gresource.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "glib-private.h" + +struct _GResource +{ + int ref_count; + + GvdbTable *table; +}; + +static void register_lazy_static_resources (void); + +G_DEFINE_BOXED_TYPE (GResource, g_resource, g_resource_ref, g_resource_unref) + +/** + * SECTION:gresource + * @short_description: Resource framework + * @include: gio/gio.h + * + * Applications and libraries often contain binary or textual data that is + * really part of the application, rather than user data. For instance + * #GtkBuilder .ui files, splashscreen images, GMenu markup XML, CSS files, + * icons, etc. These are often shipped as files in `$datadir/appname`, or + * manually included as literal strings in the code. + * + * The #GResource API and the [glib-compile-resources][glib-compile-resources] program + * provide a convenient and efficient alternative to this which has some nice properties. You + * maintain the files as normal files, so its easy to edit them, but during the build the files + * are combined into a binary bundle that is linked into the executable. This means that loading + * the resource files are efficient (as they are already in memory, shared with other instances) and + * simple (no need to check for things like I/O errors or locate the files in the filesystem). It + * also makes it easier to create relocatable applications. + * + * Resource files can also be marked as compressed. Such files will be included in the resource bundle + * in a compressed form, but will be automatically uncompressed when the resource is used. This + * is very useful e.g. for larger text files that are parsed once (or rarely) and then thrown away. + * + * Resource files can also be marked to be preprocessed, by setting the value of the + * `preprocess` attribute to a comma-separated list of preprocessing options. + * The only options currently supported are: + * + * `xml-stripblanks` which will use the xmllint command + * to strip ignorable whitespace from the XML file. For this to work, + * the `XMLLINT` environment variable must be set to the full path to + * the xmllint executable, or xmllint must be in the `PATH`; otherwise + * the preprocessing step is skipped. + * + * `to-pixdata` (deprecated since gdk-pixbuf 2.32) which will use the + * `gdk-pixbuf-pixdata` command to convert images to the #GdkPixdata format, + * which allows you to create pixbufs directly using the data inside the + * resource file, rather than an (uncompressed) copy of it. For this, the + * `gdk-pixbuf-pixdata` program must be in the `PATH`, or the + * `GDK_PIXBUF_PIXDATA` environment variable must be set to the full path to the + * `gdk-pixbuf-pixdata` executable; otherwise the resource compiler will abort. + * `to-pixdata` has been deprecated since gdk-pixbuf 2.32, as #GResource + * supports embedding modern image formats just as well. Instead of using it, + * embed a PNG or SVG file in your #GResource. + * + * `json-stripblanks` which will use the `json-glib-format` command to strip + * ignorable whitespace from the JSON file. For this to work, the + * `JSON_GLIB_FORMAT` environment variable must be set to the full path to the + * `json-glib-format` executable, or it must be in the `PATH`; + * otherwise the preprocessing step is skipped. In addition, at least version + * 1.6 of `json-glib-format` is required. + * + * Resource files will be exported in the GResource namespace using the + * combination of the given `prefix` and the filename from the `file` element. + * The `alias` attribute can be used to alter the filename to expose them at a + * different location in the resource namespace. Typically, this is used to + * include files from a different source directory without exposing the source + * directory in the resource namespace, as in the example below. + * + * Resource bundles are created by the [glib-compile-resources][glib-compile-resources] program + * which takes an XML file that describes the bundle, and a set of files that the XML references. These + * are combined into a binary resource bundle. + * + * An example resource description: + * |[ + * + * + * + * data/splashscreen.png + * dialog.ui + * menumarkup.xml + * data/example.css + * + * + * ]| + * + * This will create a resource bundle with the following files: + * |[ + * /org/gtk/Example/data/splashscreen.png + * /org/gtk/Example/dialog.ui + * /org/gtk/Example/menumarkup.xml + * /org/gtk/Example/example.css + * ]| + * + * Note that all resources in the process share the same namespace, so use Java-style + * path prefixes (like in the above example) to avoid conflicts. + * + * You can then use [glib-compile-resources][glib-compile-resources] to compile the XML to a + * binary bundle that you can load with g_resource_load(). However, its more common to use the --generate-source and + * --generate-header arguments to create a source file and header to link directly into your application. + * This will generate `get_resource()`, `register_resource()` and + * `unregister_resource()` functions, prefixed by the `--c-name` argument passed + * to [glib-compile-resources][glib-compile-resources]. `get_resource()` returns + * the generated #GResource object. The register and unregister functions + * register the resource so its files can be accessed using + * g_resources_lookup_data(). + * + * Once a #GResource has been created and registered all the data in it can be accessed globally in the process by + * using API calls like g_resources_open_stream() to stream the data or g_resources_lookup_data() to get a direct pointer + * to the data. You can also use URIs like "resource:///org/gtk/Example/data/splashscreen.png" with #GFile to access + * the resource data. + * + * Some higher-level APIs, such as #GtkApplication, will automatically load + * resources from certain well-known paths in the resource namespace as a + * convenience. See the documentation for those APIs for details. + * + * There are two forms of the generated source, the default version uses the compiler support for constructor + * and destructor functions (where available) to automatically create and register the #GResource on startup + * or library load time. If you pass `--manual-register`, two functions to register/unregister the resource are created + * instead. This requires an explicit initialization call in your application/library, but it works on all platforms, + * even on the minor ones where constructors are not supported. (Constructor support is available for at least Win32, Mac OS and Linux.) + * + * Note that resource data can point directly into the data segment of e.g. a library, so if you are unloading libraries + * during runtime you need to be very careful with keeping around pointers to data from a resource, as this goes away + * when the library is unloaded. However, in practice this is not generally a problem, since most resource accesses + * are for your own resources, and resource data is often used once, during parsing, and then released. + * + * When debugging a program or testing a change to an installed version, it is often useful to be able to + * replace resources in the program or library, without recompiling, for debugging or quick hacking and testing + * purposes. Since GLib 2.50, it is possible to use the `G_RESOURCE_OVERLAYS` environment variable to selectively overlay + * resources with replacements from the filesystem. It is a %G_SEARCHPATH_SEPARATOR-separated list of substitutions to perform + * during resource lookups. It is ignored when running in a setuid process. + * + * A substitution has the form + * + * |[ + * /org/gtk/libgtk=/home/desrt/gtk-overlay + * ]| + * + * The part before the `=` is the resource subpath for which the overlay applies. The part after is a + * filesystem path which contains files and subdirectories as you would like to be loaded as resources with the + * equivalent names. + * + * In the example above, if an application tried to load a resource with the resource path + * `/org/gtk/libgtk/ui/gtkdialog.ui` then GResource would check the filesystem path + * `/home/desrt/gtk-overlay/ui/gtkdialog.ui`. If a file was found there, it would be used instead. This is an + * overlay, not an outright replacement, which means that if a file is not found at that path, the built-in + * version will be used instead. Whiteouts are not currently supported. + * + * Substitutions must start with a slash, and must not contain a trailing slash before the '='. The path after + * the slash should ideally be absolute, but this is not strictly required. It is possible to overlay the + * location of a single resource with an individual file. + * + * Since: 2.32 + */ + +/** + * GStaticResource: + * + * #GStaticResource is an opaque data structure and can only be accessed + * using the following functions. + **/ +typedef gboolean (* CheckCandidate) (const gchar *candidate, gpointer user_data); + +static gboolean +open_overlay_stream (const gchar *candidate, + gpointer user_data) +{ + GInputStream **res = (GInputStream **) user_data; + GError *error = NULL; + GFile *file; + + file = g_file_new_for_path (candidate); + *res = (GInputStream *) g_file_read (file, NULL, &error); + + if (*res) + { + g_message ("Opened file '%s' as a resource overlay", candidate); + } + else + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + g_warning ("Can't open overlay file '%s': %s", candidate, error->message); + g_error_free (error); + } + + g_object_unref (file); + + return *res != NULL; +} + +static gboolean +get_overlay_bytes (const gchar *candidate, + gpointer user_data) +{ + GBytes **res = (GBytes **) user_data; + GMappedFile *mapped_file; + GError *error = NULL; + + mapped_file = g_mapped_file_new (candidate, FALSE, &error); + + if (mapped_file) + { + g_message ("Mapped file '%s' as a resource overlay", candidate); + *res = g_mapped_file_get_bytes (mapped_file); + g_mapped_file_unref (mapped_file); + } + else + { + if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_warning ("Can't mmap overlay file '%s': %s", candidate, error->message); + g_error_free (error); + } + + return *res != NULL; +} + +static gboolean +enumerate_overlay_dir (const gchar *candidate, + gpointer user_data) +{ + GHashTable **hash = (GHashTable **) user_data; + GError *error = NULL; + GDir *dir; + const gchar *name; + + dir = g_dir_open (candidate, 0, &error); + if (dir) + { + if (*hash == NULL) + /* note: keep in sync with same line below */ + *hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + g_message ("Enumerating directory '%s' as resource overlay", candidate); + + while ((name = g_dir_read_name (dir))) + { + gchar *fullname = g_build_filename (candidate, name, NULL); + + /* match gvdb behaviour by suffixing "/" on dirs */ + if (g_file_test (fullname, G_FILE_TEST_IS_DIR)) + g_hash_table_add (*hash, g_strconcat (name, "/", NULL)); + else + g_hash_table_add (*hash, g_strdup (name)); + + g_free (fullname); + } + + g_dir_close (dir); + } + else + { + if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_warning ("Can't enumerate overlay directory '%s': %s", candidate, error->message); + g_error_free (error); + return FALSE; + } + + /* We may want to enumerate results from more than one overlay + * directory. + */ + return FALSE; +} + +typedef struct { + gsize size; + guint32 flags; +} InfoData; + +static gboolean +get_overlay_info (const gchar *candidate, + gpointer user_data) +{ + InfoData *info = user_data; + GStatBuf buf; + + if (g_stat (candidate, &buf) < 0) + return FALSE; + + info->size = buf.st_size; + info->flags = G_RESOURCE_FLAGS_NONE; + + return TRUE; +} + +static gboolean +g_resource_find_overlay (const gchar *path, + CheckCandidate check, + gpointer user_data) +{ + /* This is a null-terminated array of replacement strings (with '=' inside) */ + static const gchar * const *overlay_dirs; + gboolean res = FALSE; + gint path_len = -1; + gint i; + + /* We try to be very fast in case there are no overlays. Otherwise, + * we can take a bit more time... + */ + + if (g_once_init_enter (&overlay_dirs)) + { + gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) (); + const gchar * const *result; + const gchar *envvar; + + /* Don’t load overlays if setuid, as they could allow reading privileged + * files. */ + envvar = !is_setuid ? g_getenv ("G_RESOURCE_OVERLAYS") : NULL; + if (envvar != NULL) + { + gchar **parts; + gint j; + + parts = g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, 0); + + /* Sanity check the parts, dropping those that are invalid. + * 'i' may grow faster than 'j'. + */ + for (i = j = 0; parts[i]; i++) + { + gchar *part = parts[i]; + gchar *eq; + + eq = strchr (part, '='); + if (eq == NULL) + { + g_critical ("G_RESOURCE_OVERLAYS segment '%s' lacks '='. Ignoring.", part); + g_free (part); + continue; + } + + if (eq == part) + { + g_critical ("G_RESOURCE_OVERLAYS segment '%s' lacks path before '='. Ignoring.", part); + g_free (part); + continue; + } + + if (eq[1] == '\0') + { + g_critical ("G_RESOURCE_OVERLAYS segment '%s' lacks path after '='. Ignoring", part); + g_free (part); + continue; + } + + if (part[0] != '/') + { + g_critical ("G_RESOURCE_OVERLAYS segment '%s' lacks leading '/'. Ignoring.", part); + g_free (part); + continue; + } + + if (eq[-1] == '/') + { + g_critical ("G_RESOURCE_OVERLAYS segment '%s' has trailing '/' before '='. Ignoring", part); + g_free (part); + continue; + } + + if (!g_path_is_absolute (eq + 1)) + { + g_critical ("G_RESOURCE_OVERLAYS segment '%s' does not have an absolute path after '='. Ignoring", part); + g_free (part); + continue; + } + + g_message ("Adding GResources overlay '%s'", part); + parts[j++] = part; + } + + parts[j] = NULL; + + result = (const gchar **) parts; + } + else + { + /* We go out of the way to avoid malloc() in the normal case + * where the environment variable is not set. + */ + static const gchar *const empty_strv[0 + 1] = { 0 }; + result = empty_strv; + } + + g_once_init_leave (&overlay_dirs, result); + } + + for (i = 0; overlay_dirs[i]; i++) + { + const gchar *src; + gint src_len; + const gchar *dst; + gint dst_len; + gchar *candidate; + + { + gchar *eq; + + /* split the overlay into src/dst */ + src = overlay_dirs[i]; + eq = strchr (src, '='); + g_assert (eq); /* we checked this already */ + src_len = eq - src; + dst = eq + 1; + /* hold off on dst_len because we will probably fail the checks below */ + } + + if (path_len == -1) + path_len = strlen (path); + + /* The entire path is too short to match the source */ + if (path_len < src_len) + continue; + + /* It doesn't match the source */ + if (memcmp (path, src, src_len) != 0) + continue; + + /* The prefix matches, but it's not a complete path component */ + if (path[src_len] && path[src_len] != '/') + continue; + + /* OK. Now we need this. */ + dst_len = strlen (dst); + + /* The candidate will be composed of: + * + * dst + remaining_path + nul + */ + candidate = g_malloc (dst_len + (path_len - src_len) + 1); + memcpy (candidate, dst, dst_len); + memcpy (candidate + dst_len, path + src_len, path_len - src_len); + candidate[dst_len + (path_len - src_len)] = '\0'; + + /* No matter what, 'r' is what we need, including the case where + * we are trying to enumerate a directory. + */ + res = (* check) (candidate, user_data); + g_free (candidate); + + if (res) + break; + } + + return res; +} + +/** + * g_resource_error_quark: + * + * Gets the #GResource Error Quark. + * + * Returns: a #GQuark + * + * Since: 2.32 + */ +G_DEFINE_QUARK (g-resource-error-quark, g_resource_error) + +/** + * g_resource_ref: + * @resource: A #GResource + * + * Atomically increments the reference count of @resource by one. This + * function is MT-safe and may be called from any thread. + * + * Returns: The passed in #GResource + * + * Since: 2.32 + **/ +GResource * +g_resource_ref (GResource *resource) +{ + g_atomic_int_inc (&resource->ref_count); + return resource; +} + +/** + * g_resource_unref: + * @resource: A #GResource + * + * Atomically decrements the reference count of @resource by one. If the + * reference count drops to 0, all memory allocated by the resource is + * released. This function is MT-safe and may be called from any + * thread. + * + * Since: 2.32 + **/ +void +g_resource_unref (GResource *resource) +{ + if (g_atomic_int_dec_and_test (&resource->ref_count)) + { + gvdb_table_free (resource->table); + g_free (resource); + } +} + +/*< internal > + * g_resource_new_from_table: + * @table: (transfer full): a GvdbTable + * + * Returns: (transfer full): a new #GResource for @table + */ +static GResource * +g_resource_new_from_table (GvdbTable *table) +{ + GResource *resource; + + resource = g_new (GResource, 1); + resource->ref_count = 1; + resource->table = table; + + return resource; +} + +static void +g_resource_error_from_gvdb_table_error (GError **g_resource_error, + GError *gvdb_table_error /* (transfer full) */) +{ + if (g_error_matches (gvdb_table_error, G_FILE_ERROR, G_FILE_ERROR_INVAL)) + g_set_error_literal (g_resource_error, + G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL, + gvdb_table_error->message); + else + g_propagate_error (g_resource_error, g_steal_pointer (&gvdb_table_error)); + g_clear_error (&gvdb_table_error); +} + +/** + * g_resource_new_from_data: + * @data: A #GBytes + * @error: return location for a #GError, or %NULL + * + * Creates a GResource from a reference to the binary resource bundle. + * This will keep a reference to @data while the resource lives, so + * the data should not be modified or freed. + * + * If you want to use this resource in the global resource namespace you need + * to register it with g_resources_register(). + * + * Note: @data must be backed by memory that is at least pointer aligned. + * Otherwise this function will internally create a copy of the memory since + * GLib 2.56, or in older versions fail and exit the process. + * + * If @data is empty or corrupt, %G_RESOURCE_ERROR_INTERNAL will be returned. + * + * Returns: (transfer full): a new #GResource, or %NULL on error + * + * Since: 2.32 + **/ +GResource * +g_resource_new_from_data (GBytes *data, + GError **error) +{ + GvdbTable *table; + gboolean unref_data = FALSE; + GError *local_error = NULL; + + if (((guintptr) g_bytes_get_data (data, NULL)) % sizeof (gpointer) != 0) + { + data = g_bytes_new (g_bytes_get_data (data, NULL), + g_bytes_get_size (data)); + unref_data = TRUE; + } + + table = gvdb_table_new_from_bytes (data, TRUE, &local_error); + + if (unref_data) + g_bytes_unref (data); + + if (table == NULL) + { + g_resource_error_from_gvdb_table_error (error, g_steal_pointer (&local_error)); + return NULL; + } + + return g_resource_new_from_table (table); +} + +/** + * g_resource_load: + * @filename: (type filename): the path of a filename to load, in the GLib filename encoding + * @error: return location for a #GError, or %NULL + * + * Loads a binary resource bundle and creates a #GResource representation of it, allowing + * you to query it for data. + * + * If you want to use this resource in the global resource namespace you need + * to register it with g_resources_register(). + * + * If @filename is empty or the data in it is corrupt, + * %G_RESOURCE_ERROR_INTERNAL will be returned. If @filename doesn’t exist, or + * there is an error in reading it, an error from g_mapped_file_new() will be + * returned. + * + * Returns: (transfer full): a new #GResource, or %NULL on error + * + * Since: 2.32 + **/ +GResource * +g_resource_load (const gchar *filename, + GError **error) +{ + GvdbTable *table; + GError *local_error = NULL; + + table = gvdb_table_new (filename, FALSE, &local_error); + if (table == NULL) + { + g_resource_error_from_gvdb_table_error (error, g_steal_pointer (&local_error)); + return NULL; + } + + return g_resource_new_from_table (table); +} + +static gboolean +do_lookup (GResource *resource, + const gchar *path, + GResourceLookupFlags lookup_flags, + gsize *size, + guint32 *flags, + const void **data, + gsize *data_size, + GError **error) +{ + char *free_path = NULL; + gsize path_len; + gboolean res = FALSE; + GVariant *value; + + /* Drop any trailing slash. */ + path_len = strlen (path); + if (path_len >= 1 && path[path_len-1] == '/') + { + path = free_path = g_strdup (path); + free_path[path_len-1] = 0; + } + + value = gvdb_table_get_raw_value (resource->table, path); + + if (value == NULL) + { + g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + path); + } + else + { + guint32 _size, _flags; + GVariant *array; + + g_variant_get (value, "(uu@ay)", + &_size, + &_flags, + &array); + + _size = GUINT32_FROM_LE (_size); + _flags = GUINT32_FROM_LE (_flags); + + if (size) + *size = _size; + if (flags) + *flags = _flags; + if (data) + *data = g_variant_get_data (array); + if (data_size) + { + /* Don't report trailing newline that non-compressed files has */ + if (_flags & G_RESOURCE_FLAGS_COMPRESSED) + *data_size = g_variant_get_size (array); + else + *data_size = g_variant_get_size (array) - 1; + } + g_variant_unref (array); + g_variant_unref (value); + + res = TRUE; + } + + g_free (free_path); + return res; +} + +/** + * g_resource_open_stream: + * @resource: A #GResource + * @path: A pathname inside the resource + * @lookup_flags: A #GResourceLookupFlags + * @error: return location for a #GError, or %NULL + * + * Looks for a file at the specified @path in the resource and + * returns a #GInputStream that lets you read the data. + * + * @lookup_flags controls the behaviour of the lookup. + * + * Returns: (transfer full): #GInputStream or %NULL on error. + * Free the returned object with g_object_unref() + * + * Since: 2.32 + **/ +GInputStream * +g_resource_open_stream (GResource *resource, + const gchar *path, + GResourceLookupFlags lookup_flags, + GError **error) +{ + const void *data; + gsize data_size; + guint32 flags; + GInputStream *stream, *stream2; + + if (!do_lookup (resource, path, lookup_flags, NULL, &flags, &data, &data_size, error)) + return NULL; + + stream = g_memory_input_stream_new_from_data (data, data_size, NULL); + g_object_set_data_full (G_OBJECT (stream), "g-resource", + g_resource_ref (resource), + (GDestroyNotify)g_resource_unref); + + if (flags & G_RESOURCE_FLAGS_COMPRESSED) + { + GZlibDecompressor *decompressor = + g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB); + + stream2 = g_converter_input_stream_new (stream, G_CONVERTER (decompressor)); + g_object_unref (decompressor); + g_object_unref (stream); + stream = stream2; + } + + return stream; +} + +/** + * g_resource_lookup_data: + * @resource: A #GResource + * @path: A pathname inside the resource + * @lookup_flags: A #GResourceLookupFlags + * @error: return location for a #GError, or %NULL + * + * Looks for a file at the specified @path in the resource and + * returns a #GBytes that lets you directly access the data in + * memory. + * + * The data is always followed by a zero byte, so you + * can safely use the data as a C string. However, that byte + * is not included in the size of the GBytes. + * + * For uncompressed resource files this is a pointer directly into + * the resource bundle, which is typically in some readonly data section + * in the program binary. For compressed files we allocate memory on + * the heap and automatically uncompress the data. + * + * @lookup_flags controls the behaviour of the lookup. + * + * Returns: (transfer full): #GBytes or %NULL on error. + * Free the returned object with g_bytes_unref() + * + * Since: 2.32 + **/ +GBytes * +g_resource_lookup_data (GResource *resource, + const gchar *path, + GResourceLookupFlags lookup_flags, + GError **error) +{ + const void *data; + guint32 flags; + gsize data_size; + gsize size; + + if (!do_lookup (resource, path, lookup_flags, &size, &flags, &data, &data_size, error)) + return NULL; + + if (size == 0) + return g_bytes_new_with_free_func ("", 0, (GDestroyNotify) g_resource_unref, g_resource_ref (resource)); + else if (flags & G_RESOURCE_FLAGS_COMPRESSED) + { + char *uncompressed, *d; + const char *s; + GConverterResult res; + gsize d_size, s_size; + gsize bytes_read, bytes_written; + + + GZlibDecompressor *decompressor = + g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB); + + uncompressed = g_malloc (size + 1); + + s = data; + s_size = data_size; + d = uncompressed; + d_size = size; + + do + { + res = g_converter_convert (G_CONVERTER (decompressor), + s, s_size, + d, d_size, + G_CONVERTER_INPUT_AT_END, + &bytes_read, + &bytes_written, + NULL); + if (res == G_CONVERTER_ERROR) + { + g_free (uncompressed); + g_object_unref (decompressor); + + g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL, + _("The resource at “%s†failed to decompress"), + path); + return NULL; + + } + s += bytes_read; + s_size -= bytes_read; + d += bytes_written; + d_size -= bytes_written; + } + while (res != G_CONVERTER_FINISHED); + + uncompressed[size] = 0; /* Zero terminate */ + + g_object_unref (decompressor); + + return g_bytes_new_take (uncompressed, size); + } + else + return g_bytes_new_with_free_func (data, data_size, (GDestroyNotify)g_resource_unref, g_resource_ref (resource)); +} + +/** + * g_resource_get_info: + * @resource: A #GResource + * @path: A pathname inside the resource + * @lookup_flags: A #GResourceLookupFlags + * @size: (out) (optional): a location to place the length of the contents of the file, + * or %NULL if the length is not needed + * @flags: (out) (optional): a location to place the flags about the file, + * or %NULL if the length is not needed + * @error: return location for a #GError, or %NULL + * + * Looks for a file at the specified @path in the resource and + * if found returns information about it. + * + * @lookup_flags controls the behaviour of the lookup. + * + * Returns: %TRUE if the file was found. %FALSE if there were errors + * + * Since: 2.32 + **/ +gboolean +g_resource_get_info (GResource *resource, + const gchar *path, + GResourceLookupFlags lookup_flags, + gsize *size, + guint32 *flags, + GError **error) +{ + return do_lookup (resource, path, lookup_flags, size, flags, NULL, NULL, error); +} + +/** + * g_resource_enumerate_children: + * @resource: A #GResource + * @path: A pathname inside the resource + * @lookup_flags: A #GResourceLookupFlags + * @error: return location for a #GError, or %NULL + * + * Returns all the names of children at the specified @path in the resource. + * The return result is a %NULL terminated list of strings which should + * be released with g_strfreev(). + * + * If @path is invalid or does not exist in the #GResource, + * %G_RESOURCE_ERROR_NOT_FOUND will be returned. + * + * @lookup_flags controls the behaviour of the lookup. + * + * Returns: (array zero-terminated=1) (transfer full): an array of constant strings + * + * Since: 2.32 + **/ +gchar ** +g_resource_enumerate_children (GResource *resource, + const gchar *path, + GResourceLookupFlags lookup_flags, + GError **error) +{ + gchar local_str[256]; + const gchar *path_with_slash; + gchar **children; + gchar *free_path = NULL; + gsize path_len; + + /* + * Size of 256 is arbitrarily chosen based on being large enough + * for pretty much everything we come across, but not cumbersome + * on the stack. It also matches common cacheline sizes. + */ + + if (*path == 0) + { + if (error) + g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + path); + return NULL; + } + + path_len = strlen (path); + + if G_UNLIKELY (path[path_len-1] != '/') + { + if (path_len < sizeof (local_str) - 2) + { + /* + * We got a path that does not have a trailing /. It is not the + * ideal use of this API as we require trailing / for our lookup + * into gvdb. Some degenerate application configurations can hit + * this code path quite a bit, so we try to avoid using the + * g_strconcat()/g_free(). + */ + memcpy (local_str, path, path_len); + local_str[path_len] = '/'; + local_str[path_len+1] = 0; + path_with_slash = local_str; + } + else + { + path_with_slash = free_path = g_strconcat (path, "/", NULL); + } + } + else + { + path_with_slash = path; + } + + children = gvdb_table_list (resource->table, path_with_slash); + g_free (free_path); + + if (children == NULL) + { + if (error) + g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + path); + return NULL; + } + + return children; +} + +static GRWLock resources_lock; +static GList *registered_resources; + +/* This is updated atomically, so we can append to it and check for NULL outside the + lock, but all other accesses are done under the write lock */ +static GStaticResource *lazy_register_resources; + +static void +g_resources_register_unlocked (GResource *resource) +{ + registered_resources = g_list_prepend (registered_resources, g_resource_ref (resource)); +} + +static void +g_resources_unregister_unlocked (GResource *resource) +{ + if (g_list_find (registered_resources, resource) == NULL) + { + g_warning ("Tried to remove not registered resource"); + } + else + { + registered_resources = g_list_remove (registered_resources, resource); + g_resource_unref (resource); + } +} + +/** + * g_resources_register: + * @resource: A #GResource + * + * Registers the resource with the process-global set of resources. + * Once a resource is registered the files in it can be accessed + * with the global resource lookup functions like g_resources_lookup_data(). + * + * Since: 2.32 + **/ +void +g_resources_register (GResource *resource) +{ + g_rw_lock_writer_lock (&resources_lock); + g_resources_register_unlocked (resource); + g_rw_lock_writer_unlock (&resources_lock); +} + +/** + * g_resources_unregister: + * @resource: A #GResource + * + * Unregisters the resource from the process-global set of resources. + * + * Since: 2.32 + **/ +void +g_resources_unregister (GResource *resource) +{ + g_rw_lock_writer_lock (&resources_lock); + g_resources_unregister_unlocked (resource); + g_rw_lock_writer_unlock (&resources_lock); +} + +/** + * g_resources_open_stream: + * @path: A pathname inside the resource + * @lookup_flags: A #GResourceLookupFlags + * @error: return location for a #GError, or %NULL + * + * Looks for a file at the specified @path in the set of + * globally registered resources and returns a #GInputStream + * that lets you read the data. + * + * @lookup_flags controls the behaviour of the lookup. + * + * Returns: (transfer full): #GInputStream or %NULL on error. + * Free the returned object with g_object_unref() + * + * Since: 2.32 + **/ +GInputStream * +g_resources_open_stream (const gchar *path, + GResourceLookupFlags lookup_flags, + GError **error) +{ + GInputStream *res = NULL; + GList *l; + GInputStream *stream; + + if (g_resource_find_overlay (path, open_overlay_stream, &res)) + return res; + + register_lazy_static_resources (); + + g_rw_lock_reader_lock (&resources_lock); + + for (l = registered_resources; l != NULL; l = l->next) + { + GResource *r = l->data; + GError *my_error = NULL; + + stream = g_resource_open_stream (r, path, lookup_flags, &my_error); + if (stream == NULL && + g_error_matches (my_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND)) + { + g_clear_error (&my_error); + } + else + { + if (stream == NULL) + g_propagate_error (error, my_error); + res = stream; + break; + } + } + + if (l == NULL) + g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + path); + + g_rw_lock_reader_unlock (&resources_lock); + + return res; +} + +/** + * g_resources_lookup_data: + * @path: A pathname inside the resource + * @lookup_flags: A #GResourceLookupFlags + * @error: return location for a #GError, or %NULL + * + * Looks for a file at the specified @path in the set of + * globally registered resources and returns a #GBytes that + * lets you directly access the data in memory. + * + * The data is always followed by a zero byte, so you + * can safely use the data as a C string. However, that byte + * is not included in the size of the GBytes. + * + * For uncompressed resource files this is a pointer directly into + * the resource bundle, which is typically in some readonly data section + * in the program binary. For compressed files we allocate memory on + * the heap and automatically uncompress the data. + * + * @lookup_flags controls the behaviour of the lookup. + * + * Returns: (transfer full): #GBytes or %NULL on error. + * Free the returned object with g_bytes_unref() + * + * Since: 2.32 + **/ +GBytes * +g_resources_lookup_data (const gchar *path, + GResourceLookupFlags lookup_flags, + GError **error) +{ + GBytes *res = NULL; + GList *l; + GBytes *data; + + if (g_resource_find_overlay (path, get_overlay_bytes, &res)) + return res; + + register_lazy_static_resources (); + + g_rw_lock_reader_lock (&resources_lock); + + for (l = registered_resources; l != NULL; l = l->next) + { + GResource *r = l->data; + GError *my_error = NULL; + + data = g_resource_lookup_data (r, path, lookup_flags, &my_error); + if (data == NULL && + g_error_matches (my_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND)) + { + g_clear_error (&my_error); + } + else + { + if (data == NULL) + g_propagate_error (error, my_error); + res = data; + break; + } + } + + if (l == NULL) + g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + path); + + g_rw_lock_reader_unlock (&resources_lock); + + return res; +} + +/** + * g_resources_enumerate_children: + * @path: A pathname inside the resource + * @lookup_flags: A #GResourceLookupFlags + * @error: return location for a #GError, or %NULL + * + * Returns all the names of children at the specified @path in the set of + * globally registered resources. + * The return result is a %NULL terminated list of strings which should + * be released with g_strfreev(). + * + * @lookup_flags controls the behaviour of the lookup. + * + * Returns: (array zero-terminated=1) (transfer full): an array of constant strings + * + * Since: 2.32 + **/ +gchar ** +g_resources_enumerate_children (const gchar *path, + GResourceLookupFlags lookup_flags, + GError **error) +{ + GHashTable *hash = NULL; + GList *l; + char **children; + int i; + + /* This will enumerate actual files found in overlay directories but + * will not enumerate the overlays themselves. For example, if we + * have an overlay "/org/gtk=/path/to/files" and we enumerate "/org" + * then we will not see "gtk" in the result set unless it is provided + * by another resource file. + * + * This is probably not going to be a problem since if we are doing + * such an overlay, we probably will already have that path. + */ + g_resource_find_overlay (path, enumerate_overlay_dir, &hash); + + register_lazy_static_resources (); + + g_rw_lock_reader_lock (&resources_lock); + + for (l = registered_resources; l != NULL; l = l->next) + { + GResource *r = l->data; + + children = g_resource_enumerate_children (r, path, 0, NULL); + + if (children != NULL) + { + if (hash == NULL) + /* note: keep in sync with same line above */ + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + for (i = 0; children[i] != NULL; i++) + g_hash_table_add (hash, children[i]); + g_free (children); + } + } + + g_rw_lock_reader_unlock (&resources_lock); + + if (hash == NULL) + { + if (error) + g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + path); + return NULL; + } + else + { + children = (gchar **) g_hash_table_get_keys_as_array (hash, NULL); + g_hash_table_steal_all (hash); + g_hash_table_destroy (hash); + + return children; + } +} + +/** + * g_resources_get_info: + * @path: A pathname inside the resource + * @lookup_flags: A #GResourceLookupFlags + * @size: (out) (optional): a location to place the length of the contents of the file, + * or %NULL if the length is not needed + * @flags: (out) (optional): a location to place the #GResourceFlags about the file, + * or %NULL if the flags are not needed + * @error: return location for a #GError, or %NULL + * + * Looks for a file at the specified @path in the set of + * globally registered resources and if found returns information about it. + * + * @lookup_flags controls the behaviour of the lookup. + * + * Returns: %TRUE if the file was found. %FALSE if there were errors + * + * Since: 2.32 + **/ +gboolean +g_resources_get_info (const gchar *path, + GResourceLookupFlags lookup_flags, + gsize *size, + guint32 *flags, + GError **error) +{ + gboolean res = FALSE; + GList *l; + gboolean r_res; + InfoData info; + + if (g_resource_find_overlay (path, get_overlay_info, &info)) + { + if (size) + *size = info.size; + if (flags) + *flags = info.flags; + + return TRUE; + } + + register_lazy_static_resources (); + + g_rw_lock_reader_lock (&resources_lock); + + for (l = registered_resources; l != NULL; l = l->next) + { + GResource *r = l->data; + GError *my_error = NULL; + + r_res = g_resource_get_info (r, path, lookup_flags, size, flags, &my_error); + if (!r_res && + g_error_matches (my_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND)) + { + g_clear_error (&my_error); + } + else + { + if (!r_res) + g_propagate_error (error, my_error); + res = r_res; + break; + } + } + + if (l == NULL) + g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + path); + + g_rw_lock_reader_unlock (&resources_lock); + + return res; +} + +/* This code is to handle registration of resources very early, from a constructor. + * At that point we'd like to do minimal work, to avoid ordering issues. For instance, + * we're not allowed to use g_malloc, as the user need to be able to call g_mem_set_vtable + * before the first call to g_malloc. + * + * So, what we do at construction time is that we just register a static structure on + * a list of resources that need to be initialized, and then later, when doing any lookups + * in the global list of registered resources, or when getting a reference to the + * lazily initialized resource we lazily create and register all the GResources on + * the lazy list. + * + * To avoid having to use locks in the constructor, and having to grab the writer lock + * when checking the lazy registering list we update lazy_register_resources in + * a lock-less fashion (atomic prepend-only, atomic replace with NULL). However, all + * operations except: + * * check if there are any resources to lazily initialize + * * Add a static resource to the lazy init list + * Do use the full writer lock for protection. + */ + +static void +register_lazy_static_resources_unlocked (void) +{ + GStaticResource *list; + + do + list = lazy_register_resources; + while (!g_atomic_pointer_compare_and_exchange (&lazy_register_resources, list, NULL)); + + while (list != NULL) + { + GBytes *bytes = g_bytes_new_static (list->data, list->data_len); + GResource *resource = g_resource_new_from_data (bytes, NULL); + if (resource) + { + g_resources_register_unlocked (resource); + g_atomic_pointer_set (&list->resource, resource); + } + g_bytes_unref (bytes); + + list = list->next; + } +} + +static void +register_lazy_static_resources (void) +{ + if (g_atomic_pointer_get (&lazy_register_resources) == NULL) + return; + + g_rw_lock_writer_lock (&resources_lock); + register_lazy_static_resources_unlocked (); + g_rw_lock_writer_unlock (&resources_lock); +} + +/** + * g_static_resource_init: + * @static_resource: pointer to a static #GStaticResource + * + * Initializes a GResource from static data using a + * GStaticResource. + * + * This is normally used by code generated by + * [glib-compile-resources][glib-compile-resources] + * and is not typically used by other code. + * + * Since: 2.32 + **/ +void +g_static_resource_init (GStaticResource *static_resource) +{ + GStaticResource *next; + + do + { + next = lazy_register_resources; + static_resource->next = next; + } + while (!g_atomic_pointer_compare_and_exchange (&lazy_register_resources, next, static_resource)); +} + +/** + * g_static_resource_fini: + * @static_resource: pointer to a static #GStaticResource + * + * Finalized a GResource initialized by g_static_resource_init(). + * + * This is normally used by code generated by + * [glib-compile-resources][glib-compile-resources] + * and is not typically used by other code. + * + * Since: 2.32 + **/ +void +g_static_resource_fini (GStaticResource *static_resource) +{ + GResource *resource; + + g_rw_lock_writer_lock (&resources_lock); + + register_lazy_static_resources_unlocked (); + + resource = g_atomic_pointer_get (&static_resource->resource); + if (resource) + { + g_atomic_pointer_set (&static_resource->resource, NULL); + g_resources_unregister_unlocked (resource); + g_resource_unref (resource); + } + + g_rw_lock_writer_unlock (&resources_lock); +} + +/** + * g_static_resource_get_resource: + * @static_resource: pointer to a static #GStaticResource + * + * Gets the GResource that was registered by a call to g_static_resource_init(). + * + * This is normally used by code generated by + * [glib-compile-resources][glib-compile-resources] + * and is not typically used by other code. + * + * Returns: (transfer none): a #GResource + * + * Since: 2.32 + **/ +GResource * +g_static_resource_get_resource (GStaticResource *static_resource) +{ + register_lazy_static_resources (); + + return g_atomic_pointer_get (&static_resource->resource); +} diff --git a/gio/gresource.h b/gio/gresource.h new file mode 100644 index 0000000..e9870c1 --- /dev/null +++ b/gio/gresource.h @@ -0,0 +1,130 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_RESOURCE_H__ +#define __G_RESOURCE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_TYPE_RESOURCE: + * + * The #GType for #GResource. + */ +#define G_TYPE_RESOURCE (g_resource_get_type ()) + + +/** + * G_RESOURCE_ERROR: + * + * Error domain for #GResource. Errors in this domain will be from the + * #GResourceError enumeration. See #GError for more information on + * error domains. + */ +#define G_RESOURCE_ERROR (g_resource_error_quark ()) +GLIB_AVAILABLE_IN_2_32 +GQuark g_resource_error_quark (void); + +typedef struct _GStaticResource GStaticResource; + +struct _GStaticResource { + /*< private >*/ + const guint8 *data; + gsize data_len; + GResource *resource; + GStaticResource *next; + gpointer padding; +}; + +GLIB_AVAILABLE_IN_2_32 +GType g_resource_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_32 +GResource * g_resource_new_from_data (GBytes *data, + GError **error); +GLIB_AVAILABLE_IN_2_32 +GResource * g_resource_ref (GResource *resource); +GLIB_AVAILABLE_IN_2_32 +void g_resource_unref (GResource *resource); +GLIB_AVAILABLE_IN_2_32 +GResource * g_resource_load (const gchar *filename, + GError **error); +GLIB_AVAILABLE_IN_2_32 +GInputStream *g_resource_open_stream (GResource *resource, + const char *path, + GResourceLookupFlags lookup_flags, + GError **error); +GLIB_AVAILABLE_IN_2_32 +GBytes * g_resource_lookup_data (GResource *resource, + const char *path, + GResourceLookupFlags lookup_flags, + GError **error); +GLIB_AVAILABLE_IN_2_32 +char ** g_resource_enumerate_children (GResource *resource, + const char *path, + GResourceLookupFlags lookup_flags, + GError **error); +GLIB_AVAILABLE_IN_2_32 +gboolean g_resource_get_info (GResource *resource, + const char *path, + GResourceLookupFlags lookup_flags, + gsize *size, + guint32 *flags, + GError **error); + +GLIB_AVAILABLE_IN_2_32 +void g_resources_register (GResource *resource); +GLIB_AVAILABLE_IN_2_32 +void g_resources_unregister (GResource *resource); +GLIB_AVAILABLE_IN_2_32 +GInputStream *g_resources_open_stream (const char *path, + GResourceLookupFlags lookup_flags, + GError **error); +GLIB_AVAILABLE_IN_2_32 +GBytes * g_resources_lookup_data (const char *path, + GResourceLookupFlags lookup_flags, + GError **error); +GLIB_AVAILABLE_IN_2_32 +char ** g_resources_enumerate_children (const char *path, + GResourceLookupFlags lookup_flags, + GError **error); +GLIB_AVAILABLE_IN_2_32 +gboolean g_resources_get_info (const char *path, + GResourceLookupFlags lookup_flags, + gsize *size, + guint32 *flags, + GError **error); + + +GLIB_AVAILABLE_IN_2_32 +void g_static_resource_init (GStaticResource *static_resource); +GLIB_AVAILABLE_IN_2_32 +void g_static_resource_fini (GStaticResource *static_resource); +GLIB_AVAILABLE_IN_2_32 +GResource *g_static_resource_get_resource (GStaticResource *static_resource); + +G_END_DECLS + +#endif /* __G_RESOURCE_H__ */ diff --git a/gio/gresourcefile.c b/gio/gresourcefile.c new file mode 100644 index 0000000..35dffeb --- /dev/null +++ b/gio/gresourcefile.c @@ -0,0 +1,957 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "gresource.h" +#include "gresourcefile.h" +#include "gfileattribute.h" +#include +#include +#include "gfile.h" +#include "gfilemonitor.h" +#include "gseekable.h" +#include "gfileinputstream.h" +#include "gfileinfo.h" +#include "gfileenumerator.h" +#include "gcontenttype.h" +#include "gioerror.h" +#include +#include "glibintl.h" + +struct _GResourceFile +{ + GObject parent_instance; + + char *path; +}; + +struct _GResourceFileEnumerator +{ + GFileEnumerator parent; + + GFileAttributeMatcher *matcher; + char *path; + char *attributes; + GFileQueryInfoFlags flags; + int index; + + char **children; +}; + +struct _GResourceFileEnumeratorClass +{ + GFileEnumeratorClass parent_class; +}; + +typedef struct _GResourceFileEnumerator GResourceFileEnumerator; +typedef struct _GResourceFileEnumeratorClass GResourceFileEnumeratorClass; + +static void g_resource_file_file_iface_init (GFileIface *iface); + +static GFileAttributeInfoList *resource_writable_attributes = NULL; +static GFileAttributeInfoList *resource_writable_namespaces = NULL; + +static GType _g_resource_file_enumerator_get_type (void); + +#define G_TYPE_RESOURCE_FILE_ENUMERATOR (_g_resource_file_enumerator_get_type ()) +#define G_RESOURCE_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_RESOURCE_FILE_ENUMERATOR, GResourceFileEnumerator)) +#define G_RESOURCE_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_RESOURCE_FILE_ENUMERATOR, GResourceFileEnumeratorClass)) +#define G_IS_RESOURCE_FILE_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_RESOURCE_FILE_ENUMERATOR)) +#define G_IS_RESOURCE_FILE_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_RESOURCE_FILE_ENUMERATOR)) +#define G_RESOURCE_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_RESOURCE_FILE_ENUMERATOR, GResourceFileEnumeratorClass)) + +#define G_TYPE_RESOURCE_FILE_INPUT_STREAM (_g_resource_file_input_stream_get_type ()) +#define G_RESOURCE_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_RESOURCE_FILE_INPUT_STREAM, GResourceFileInputStream)) +#define G_RESOURCE_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_RESOURCE_FILE_INPUT_STREAM, GResourceFileInputStreamClass)) +#define G_IS_RESOURCE_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_RESOURCE_FILE_INPUT_STREAM)) +#define G_IS_RESOURCE_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_RESOURCE_FILE_INPUT_STREAM)) +#define G_RESOURCE_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_RESOURCE_FILE_INPUT_STREAM, GResourceFileInputStreamClass)) + +typedef struct _GResourceFileInputStream GResourceFileInputStream; +typedef struct _GResourceFileInputStreamClass GResourceFileInputStreamClass; + +#define g_resource_file_get_type _g_resource_file_get_type +G_DEFINE_TYPE_WITH_CODE (GResourceFile, g_resource_file, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_FILE, + g_resource_file_file_iface_init)) + +#define g_resource_file_enumerator_get_type _g_resource_file_enumerator_get_type +G_DEFINE_TYPE (GResourceFileEnumerator, g_resource_file_enumerator, G_TYPE_FILE_ENUMERATOR) + +static GFileEnumerator *_g_resource_file_enumerator_new (GResourceFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + + +static GType _g_resource_file_input_stream_get_type (void) G_GNUC_CONST; + +static GFileInputStream *_g_resource_file_input_stream_new (GInputStream *stream, GFile *file); + + +static void +g_resource_file_finalize (GObject *object) +{ + GResourceFile *resource; + + resource = G_RESOURCE_FILE (object); + + g_free (resource->path); + + G_OBJECT_CLASS (g_resource_file_parent_class)->finalize (object); +} + +static void +g_resource_file_class_init (GResourceFileClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_resource_file_finalize; + + resource_writable_attributes = g_file_attribute_info_list_new (); + resource_writable_namespaces = g_file_attribute_info_list_new (); +} + +static void +g_resource_file_init (GResourceFile *resource) +{ +} + +static inline gchar * +scan_backwards (const gchar *begin, + const gchar *end, + gchar c) +{ + while (end >= begin) + { + if (*end == c) + return (gchar *)end; + end--; + } + + return NULL; +} + +static inline void +pop_to_previous_part (const gchar *begin, + gchar **out) +{ + if (*out > begin) + *out = scan_backwards (begin, *out - 1, '/'); +} + +/* + * canonicalize_filename: + * @in: the path to be canonicalized + * + * The path @in may contain non-canonical path pieces such as "../" + * or duplicated "/". This will resolve those into a form that only + * contains a single / at a time and resolves all "../". The resulting + * path must also start with a /. + * + * Returns: the canonical form of the path + */ +static char * +canonicalize_filename (const char *in) +{ + gchar *bptr; + char *out; + + bptr = out = g_malloc (strlen (in) + 2); + *out = '/'; + + while (*in != 0) + { + g_assert (*out == '/'); + + /* move past slashes */ + while (*in == '/') + in++; + + /* Handle ./ ../ .\0 ..\0 */ + if (*in == '.') + { + /* If this is ../ or ..\0 move up */ + if (in[1] == '.' && (in[2] == '/' || in[2] == 0)) + { + pop_to_previous_part (bptr, &out); + in += 2; + continue; + } + + /* If this is ./ skip past it */ + if (in[1] == '/' || in[1] == 0) + { + in += 1; + continue; + } + } + + /* Scan to the next path piece */ + while (*in != 0 && *in != '/') + *(++out) = *(in++); + + /* Add trailing /, compress the rest on the next go round. */ + if (*in == '/') + *(++out) = *(in++); + } + + /* Trim trailing / from path */ + if (out > bptr && *out == '/') + *out = 0; + else + *(++out) = 0; + + return bptr; +} + +static GFile * +g_resource_file_new_for_path (const char *path) +{ + GResourceFile *resource = g_object_new (G_TYPE_RESOURCE_FILE, NULL); + + resource->path = canonicalize_filename (path); + + return G_FILE (resource); +} + +GFile * +_g_resource_file_new (const char *uri) +{ + GFile *resource; + char *path; + + path = g_uri_unescape_string (uri + strlen ("resource:"), NULL); + resource = g_resource_file_new_for_path (path); + g_free (path); + + return G_FILE (resource); +} + +static gboolean +g_resource_file_is_native (GFile *file) +{ + return FALSE; +} + +static gboolean +g_resource_file_has_uri_scheme (GFile *file, + const char *uri_scheme) +{ + return g_ascii_strcasecmp (uri_scheme, "resource") == 0; +} + +static char * +g_resource_file_get_uri_scheme (GFile *file) +{ + return g_strdup ("resource"); +} + +static char * +g_resource_file_get_basename (GFile *file) +{ + gchar *base; + + base = strrchr (G_RESOURCE_FILE (file)->path, '/'); + return g_strdup (base + 1); +} + +static char * +g_resource_file_get_path (GFile *file) +{ + return NULL; +} + +static char * +g_resource_file_get_uri (GFile *file) +{ + char *escaped, *res; + escaped = g_uri_escape_string (G_RESOURCE_FILE (file)->path, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE); + res = g_strconcat ("resource://", escaped, NULL); + g_free (escaped); + return res; +} + +static char * +g_resource_file_get_parse_name (GFile *file) +{ + return g_resource_file_get_uri (file); +} + +static GFile * +g_resource_file_get_parent (GFile *file) +{ + GResourceFile *resource = G_RESOURCE_FILE (file); + GResourceFile *parent; + gchar *end; + + end = strrchr (resource->path, '/'); + + if (end == G_RESOURCE_FILE (file)->path) + return NULL; + + parent = g_object_new (G_TYPE_RESOURCE_FILE, NULL); + parent->path = g_strndup (resource->path, + end - resource->path); + + return G_FILE (parent); +} + +static GFile * +g_resource_file_dup (GFile *file) +{ + GResourceFile *resource = G_RESOURCE_FILE (file); + + return g_resource_file_new_for_path (resource->path); +} + +static guint +g_resource_file_hash (GFile *file) +{ + GResourceFile *resource = G_RESOURCE_FILE (file); + + return g_str_hash (resource->path); +} + +static gboolean +g_resource_file_equal (GFile *file1, + GFile *file2) +{ + GResourceFile *resource1 = G_RESOURCE_FILE (file1); + GResourceFile *resource2 = G_RESOURCE_FILE (file2); + + return g_str_equal (resource1->path, resource2->path); +} + +static const char * +match_prefix (const char *path, + const char *prefix) +{ + int prefix_len; + + prefix_len = strlen (prefix); + if (strncmp (path, prefix, prefix_len) != 0) + return NULL; + + /* Handle the case where prefix is the root, so that + * the IS_DIR_SEPRARATOR check below works */ + if (prefix_len > 0 && + prefix[prefix_len-1] == '/') + prefix_len--; + + return path + prefix_len; +} + +static gboolean +g_resource_file_prefix_matches (GFile *parent, + GFile *descendant) +{ + GResourceFile *parent_resource = G_RESOURCE_FILE (parent); + GResourceFile *descendant_resource = G_RESOURCE_FILE (descendant); + const char *remainder; + + remainder = match_prefix (descendant_resource->path, parent_resource->path); + if (remainder != NULL && *remainder == '/') + return TRUE; + return FALSE; +} + +static char * +g_resource_file_get_relative_path (GFile *parent, + GFile *descendant) +{ + GResourceFile *parent_resource = G_RESOURCE_FILE (parent); + GResourceFile *descendant_resource = G_RESOURCE_FILE (descendant); + const char *remainder; + + remainder = match_prefix (descendant_resource->path, parent_resource->path); + + if (remainder != NULL && *remainder == '/') + return g_strdup (remainder + 1); + return NULL; +} + +static GFile * +g_resource_file_resolve_relative_path (GFile *file, + const char *relative_path) +{ + GResourceFile *resource = G_RESOURCE_FILE (file); + char *filename; + GFile *child; + + if (relative_path[0] == '/') + return g_resource_file_new_for_path (relative_path); + + filename = g_build_path ("/", resource->path, relative_path, NULL); + child = g_resource_file_new_for_path (filename); + g_free (filename); + + return child; +} + +static GFileEnumerator * +g_resource_file_enumerate_children (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GResourceFile *resource = G_RESOURCE_FILE (file); + return _g_resource_file_enumerator_new (resource, + attributes, flags, + cancellable, error); +} + +static GFile * +g_resource_file_get_child_for_display_name (GFile *file, + const char *display_name, + GError **error) +{ + GFile *new_file; + + new_file = g_file_get_child (file, display_name); + + return new_file; +} + +static GFileInfo * +g_resource_file_query_info (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GResourceFile *resource = G_RESOURCE_FILE (file); + GError *my_error = NULL; + GFileInfo *info; + GFileAttributeMatcher *matcher; + gboolean res; + gsize size = 0; + guint32 resource_flags = 0; + char **children; + gboolean is_dir; + char *base; + + is_dir = FALSE; + children = g_resources_enumerate_children (resource->path, 0, NULL); + if (children != NULL) + { + g_strfreev (children); + is_dir = TRUE; + } + + /* root is always there */ + if (strcmp ("/", resource->path) == 0) + is_dir = TRUE; + + if (!is_dir) + { + res = g_resources_get_info (resource->path, 0, &size, &resource_flags, &my_error); + if (!res) + { + if (g_error_matches (my_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + resource->path); + } + else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + my_error->message); + g_clear_error (&my_error); + return FALSE; + } + } + + matcher = g_file_attribute_matcher_new (attributes); + + info = g_file_info_new (); + base = g_resource_file_get_basename (file); + g_file_info_set_name (info, base); + g_file_info_set_display_name (info, base); + + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_READ, TRUE); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_WRITE, FALSE); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_EXECUTE, FALSE); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_RENAME, FALSE); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_DELETE, FALSE); + _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH, FALSE); + + if (is_dir) + { + g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY); + } + else + { + GBytes *bytes; + char *content_type; + + g_file_info_set_file_type (info, G_FILE_TYPE_REGULAR); + g_file_info_set_size (info, size); + + if ((_g_file_attribute_matcher_matches_id (matcher, G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE) || + ((~resource_flags & G_RESOURCE_FLAGS_COMPRESSED) && + _g_file_attribute_matcher_matches_id (matcher, G_FILE_ATTRIBUTE_ID_STANDARD_FAST_CONTENT_TYPE))) && + (bytes = g_resources_lookup_data (resource->path, 0, NULL))) + { + const guchar *data; + gsize data_size; + + data = g_bytes_get_data (bytes, &data_size); + content_type = g_content_type_guess (base, data, data_size, NULL); + + g_bytes_unref (bytes); + } + else + content_type = NULL; + + if (content_type) + { + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE, content_type); + _g_file_info_set_attribute_string_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_FAST_CONTENT_TYPE, content_type); + + g_free (content_type); + } + } + + g_free (base); + g_file_attribute_matcher_unref (matcher); + + return info; +} + +static GFileInfo * +g_resource_file_query_filesystem_info (GFile *file, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GFileInfo *info; + GFileAttributeMatcher *matcher; + + info = g_file_info_new (); + + matcher = g_file_attribute_matcher_new (attributes); + if (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE)) + g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, "resource"); + + if (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY)) g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, TRUE); + + g_file_attribute_matcher_unref (matcher); + + return info; +} + +static GFileAttributeInfoList * +g_resource_file_query_settable_attributes (GFile *file, + GCancellable *cancellable, + GError **error) +{ + return g_file_attribute_info_list_ref (resource_writable_attributes); +} + +static GFileAttributeInfoList * +g_resource_file_query_writable_namespaces (GFile *file, + GCancellable *cancellable, + GError **error) +{ + return g_file_attribute_info_list_ref (resource_writable_namespaces); +} + +static GFileInputStream * +g_resource_file_read (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GResourceFile *resource = G_RESOURCE_FILE (file); + GError *my_error = NULL; + GInputStream *stream; + GFileInputStream *res; + + stream = g_resources_open_stream (resource->path, 0, &my_error); + + if (stream == NULL) + { + if (g_error_matches (my_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + resource->path); + } + else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + my_error->message); + g_clear_error (&my_error); + return NULL; + } + + res = _g_resource_file_input_stream_new (stream, file); + g_object_unref (stream); + return res; +} + +typedef GFileMonitor GResourceFileMonitor; +typedef GFileMonitorClass GResourceFileMonitorClass; + +GType g_resource_file_monitor_get_type (void); + +G_DEFINE_TYPE (GResourceFileMonitor, g_resource_file_monitor, G_TYPE_FILE_MONITOR) + +static gboolean +g_resource_file_monitor_cancel (GFileMonitor *monitor) +{ + return TRUE; +} + +static void +g_resource_file_monitor_init (GResourceFileMonitor *monitor) +{ +} + +static void +g_resource_file_monitor_class_init (GResourceFileMonitorClass *class) +{ + class->cancel = g_resource_file_monitor_cancel; +} + +static GFileMonitor * +g_resource_file_monitor_file (GFile *file, + GFileMonitorFlags flags, + GCancellable *cancellable, + GError **error) +{ + return g_object_new (g_resource_file_monitor_get_type (), NULL); +} + +static void +g_resource_file_file_iface_init (GFileIface *iface) +{ + iface->dup = g_resource_file_dup; + iface->hash = g_resource_file_hash; + iface->equal = g_resource_file_equal; + iface->is_native = g_resource_file_is_native; + iface->has_uri_scheme = g_resource_file_has_uri_scheme; + iface->get_uri_scheme = g_resource_file_get_uri_scheme; + iface->get_basename = g_resource_file_get_basename; + iface->get_path = g_resource_file_get_path; + iface->get_uri = g_resource_file_get_uri; + iface->get_parse_name = g_resource_file_get_parse_name; + iface->get_parent = g_resource_file_get_parent; + iface->prefix_matches = g_resource_file_prefix_matches; + iface->get_relative_path = g_resource_file_get_relative_path; + iface->resolve_relative_path = g_resource_file_resolve_relative_path; + iface->get_child_for_display_name = g_resource_file_get_child_for_display_name; + iface->enumerate_children = g_resource_file_enumerate_children; + iface->query_info = g_resource_file_query_info; + iface->query_filesystem_info = g_resource_file_query_filesystem_info; + iface->query_settable_attributes = g_resource_file_query_settable_attributes; + iface->query_writable_namespaces = g_resource_file_query_writable_namespaces; + iface->read_fn = g_resource_file_read; + iface->monitor_file = g_resource_file_monitor_file; + + iface->supports_thread_contexts = TRUE; +} + +static GFileInfo *g_resource_file_enumerator_next_file (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error); +static gboolean g_resource_file_enumerator_close (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error); + +static void +g_resource_file_enumerator_finalize (GObject *object) +{ + GResourceFileEnumerator *resource; + + resource = G_RESOURCE_FILE_ENUMERATOR (object); + + g_strfreev (resource->children); + g_free (resource->path); + g_free (resource->attributes); + + G_OBJECT_CLASS (g_resource_file_enumerator_parent_class)->finalize (object); +} + +static void +g_resource_file_enumerator_class_init (GResourceFileEnumeratorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GFileEnumeratorClass *enumerator_class = G_FILE_ENUMERATOR_CLASS (klass); + + gobject_class->finalize = g_resource_file_enumerator_finalize; + + enumerator_class->next_file = g_resource_file_enumerator_next_file; + enumerator_class->close_fn = g_resource_file_enumerator_close; +} + +static void +g_resource_file_enumerator_init (GResourceFileEnumerator *resource) +{ +} + +static GFileEnumerator * +_g_resource_file_enumerator_new (GResourceFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GResourceFileEnumerator *resource; + char **children; + gboolean res; + + children = g_resources_enumerate_children (file->path, 0, NULL); + if (children == NULL && + strcmp ("/", file->path) != 0) + { + res = g_resources_get_info (file->path, 0, NULL, NULL, NULL); + if (res) + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, + _("The resource at “%s†is not a directory"), + file->path); + else + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + _("The resource at “%s†does not exist"), + file->path); + return NULL; + } + + resource = g_object_new (G_TYPE_RESOURCE_FILE_ENUMERATOR, + "container", file, + NULL); + + resource->children = children; + resource->path = g_strdup (file->path); + resource->attributes = g_strdup (attributes); + resource->flags = flags; + + return G_FILE_ENUMERATOR (resource); +} + +static GFileInfo * +g_resource_file_enumerator_next_file (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GResourceFileEnumerator *resource = G_RESOURCE_FILE_ENUMERATOR (enumerator); + char *path; + GFileInfo *info; + GFile *file; + + if (resource->children == NULL || + resource->children[resource->index] == NULL) + return NULL; + + path = g_build_path ("/", resource->path, resource->children[resource->index++], NULL); + file = g_resource_file_new_for_path (path); + g_free (path); + + info = g_file_query_info (file, + resource->attributes, + resource->flags, + cancellable, + error); + + g_object_unref (file); + + return info; +} + +static gboolean +g_resource_file_enumerator_close (GFileEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + return TRUE; +} + + +struct _GResourceFileInputStream +{ + GFileInputStream parent_instance; + GInputStream *stream; + GFile *file; +}; + +struct _GResourceFileInputStreamClass +{ + GFileInputStreamClass parent_class; +}; + +#define g_resource_file_input_stream_get_type _g_resource_file_input_stream_get_type +G_DEFINE_TYPE (GResourceFileInputStream, g_resource_file_input_stream, G_TYPE_FILE_INPUT_STREAM) + +static gssize g_resource_file_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gssize g_resource_file_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_resource_file_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error); +static goffset g_resource_file_input_stream_tell (GFileInputStream *stream); +static gboolean g_resource_file_input_stream_can_seek (GFileInputStream *stream); +static gboolean g_resource_file_input_stream_seek (GFileInputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +static GFileInfo *g_resource_file_input_stream_query_info (GFileInputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error); + +static void +g_resource_file_input_stream_finalize (GObject *object) +{ + GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (object); + + g_object_unref (file->stream); + g_object_unref (file->file); + G_OBJECT_CLASS (g_resource_file_input_stream_parent_class)->finalize (object); +} + +static void +g_resource_file_input_stream_class_init (GResourceFileInputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass); + GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass); + + gobject_class->finalize = g_resource_file_input_stream_finalize; + + stream_class->read_fn = g_resource_file_input_stream_read; + stream_class->skip = g_resource_file_input_stream_skip; + stream_class->close_fn = g_resource_file_input_stream_close; + file_stream_class->tell = g_resource_file_input_stream_tell; + file_stream_class->can_seek = g_resource_file_input_stream_can_seek; + file_stream_class->seek = g_resource_file_input_stream_seek; + file_stream_class->query_info = g_resource_file_input_stream_query_info; +} + +static void +g_resource_file_input_stream_init (GResourceFileInputStream *info) +{ +} + +static GFileInputStream * +_g_resource_file_input_stream_new (GInputStream *in_stream, GFile *file) +{ + GResourceFileInputStream *stream; + + stream = g_object_new (G_TYPE_RESOURCE_FILE_INPUT_STREAM, NULL); + stream->stream = g_object_ref (in_stream); + stream->file = g_object_ref (file); + + return G_FILE_INPUT_STREAM (stream); +} + +static gssize +g_resource_file_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream); + return g_input_stream_read (file->stream, + buffer, count, cancellable, error); +} + +static gssize +g_resource_file_input_stream_skip (GInputStream *stream, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream); + return g_input_stream_skip (file->stream, + count, cancellable, error); +} + +static gboolean +g_resource_file_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream); + return g_input_stream_close (file->stream, + cancellable, error); +} + + +static goffset +g_resource_file_input_stream_tell (GFileInputStream *stream) +{ + GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream); + + if (!G_IS_SEEKABLE (file->stream)) + return 0; + + return g_seekable_tell (G_SEEKABLE (file->stream)); +} + +static gboolean +g_resource_file_input_stream_can_seek (GFileInputStream *stream) +{ + GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream); + + return G_IS_SEEKABLE (file->stream) && g_seekable_can_seek (G_SEEKABLE (file->stream)); +} + +static gboolean +g_resource_file_input_stream_seek (GFileInputStream *stream, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream); + + if (!G_IS_SEEKABLE (file->stream)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Input stream doesn’t implement seek")); + return FALSE; + } + + return g_seekable_seek (G_SEEKABLE (file->stream), + offset, type, cancellable, error); +} + +static GFileInfo * +g_resource_file_input_stream_query_info (GFileInputStream *stream, + const char *attributes, + GCancellable *cancellable, + GError **error) +{ + GResourceFileInputStream *file = G_RESOURCE_FILE_INPUT_STREAM (stream); + + return g_file_query_info (file->file, attributes, 0, cancellable, error); +} diff --git a/gio/gresourcefile.h b/gio/gresourcefile.h new file mode 100644 index 0000000..cdf5a0a --- /dev/null +++ b/gio/gresourcefile.h @@ -0,0 +1,49 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_RESOURCE_FILE_H__ +#define __G_RESOURCE_FILE_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_RESOURCE_FILE (_g_resource_file_get_type ()) +#define G_RESOURCE_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_RESOURCE_FILE, GResourceFile)) +#define G_RESOURCE_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_RESOURCE_FILE, GResourceFileClass)) +#define G_IS_RESOURCE_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_RESOURCE_FILE)) +#define G_IS_RESOURCE_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_RESOURCE_FILE)) +#define G_RESOURCE_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_RESOURCE_FILE, GResourceFileClass)) + +typedef struct _GResourceFile GResourceFile; +typedef struct _GResourceFileClass GResourceFileClass; + +struct _GResourceFileClass +{ + GObjectClass parent_class; +}; + +GType _g_resource_file_get_type (void) G_GNUC_CONST; + +GFile * _g_resource_file_new (const char *uri); + +G_END_DECLS + +#endif /* __G_RESOURCE_FILE_H__ */ diff --git a/gio/gschema.dtd b/gio/gschema.dtd new file mode 100644 index 0000000..3a903e7 --- /dev/null +++ b/gio/gschema.dtd @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gio/gschema.its b/gio/gschema.its new file mode 100644 index 0000000..344c54b --- /dev/null +++ b/gio/gschema.its @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/gio/gschema.loc b/gio/gschema.loc new file mode 100644 index 0000000..8945230 --- /dev/null +++ b/gio/gschema.loc @@ -0,0 +1,10 @@ + + + + + + + diff --git a/gio/gseekable.c b/gio/gseekable.c new file mode 100644 index 0000000..9689a77 --- /dev/null +++ b/gio/gseekable.c @@ -0,0 +1,197 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include "gseekable.h" +#include "glibintl.h" + + +/** + * SECTION:gseekable + * @short_description: Stream seeking interface + * @include: gio/gio.h + * @see_also: #GInputStream, #GOutputStream + * + * #GSeekable is implemented by streams (implementations of + * #GInputStream or #GOutputStream) that support seeking. + * + * Seekable streams largely fall into two categories: resizable and + * fixed-size. + * + * #GSeekable on fixed-sized streams is approximately the same as POSIX + * lseek() on a block device (for example: attempting to seek past the + * end of the device is an error). Fixed streams typically cannot be + * truncated. + * + * #GSeekable on resizable streams is approximately the same as POSIX + * lseek() on a normal file. Seeking past the end and writing data will + * usually cause the stream to resize by introducing zero bytes. + **/ + +typedef GSeekableIface GSeekableInterface; +G_DEFINE_INTERFACE (GSeekable, g_seekable, G_TYPE_OBJECT) + +static void +g_seekable_default_init (GSeekableInterface *iface) +{ +} + +/** + * g_seekable_tell: + * @seekable: a #GSeekable. + * + * Tells the current position within the stream. + * + * Returns: the (positive or zero) offset from the beginning of the + * buffer, zero if the target is not seekable. + **/ +goffset +g_seekable_tell (GSeekable *seekable) +{ + GSeekableIface *iface; + + g_return_val_if_fail (G_IS_SEEKABLE (seekable), 0); + + iface = G_SEEKABLE_GET_IFACE (seekable); + + return (* iface->tell) (seekable); +} + +/** + * g_seekable_can_seek: + * @seekable: a #GSeekable. + * + * Tests if the stream supports the #GSeekableIface. + * + * Returns: %TRUE if @seekable can be seeked. %FALSE otherwise. + **/ +gboolean +g_seekable_can_seek (GSeekable *seekable) +{ + GSeekableIface *iface; + + g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE); + + iface = G_SEEKABLE_GET_IFACE (seekable); + + return (* iface->can_seek) (seekable); +} + +/** + * g_seekable_seek: + * @seekable: a #GSeekable. + * @offset: a #goffset. + * @type: a #GSeekType. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Seeks in the stream by the given @offset, modified by @type. + * + * Attempting to seek past the end of the stream will have different + * results depending on if the stream is fixed-sized or resizable. If + * the stream is resizable then seeking past the end and then writing + * will result in zeros filling the empty space. Seeking past the end + * of a resizable stream and reading will result in EOF. Seeking past + * the end of a fixed-sized stream will fail. + * + * Any operation that would result in a negative offset will fail. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if successful. If an error + * has occurred, this function will return %FALSE and set @error + * appropriately if present. + **/ +gboolean +g_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error) +{ + GSeekableIface *iface; + + g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE); + + iface = G_SEEKABLE_GET_IFACE (seekable); + + return (* iface->seek) (seekable, offset, type, cancellable, error); +} + +/** + * g_seekable_can_truncate: + * @seekable: a #GSeekable. + * + * Tests if the length of the stream can be adjusted with + * g_seekable_truncate(). + * + * Returns: %TRUE if the stream can be truncated, %FALSE otherwise. + **/ +gboolean +g_seekable_can_truncate (GSeekable *seekable) +{ + GSeekableIface *iface; + + g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE); + + iface = G_SEEKABLE_GET_IFACE (seekable); + + return (* iface->can_truncate) (seekable); +} + +/** + * g_seekable_truncate: (virtual truncate_fn) + * @seekable: a #GSeekable. + * @offset: new length for @seekable, in bytes. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Sets the length of the stream to @offset. If the stream was previously + * larger than @offset, the extra data is discarded. If the stream was + * previously shorter than @offset, it is extended with NUL ('\0') bytes. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an + * operation was partially finished when the operation was cancelled the + * partial result will be returned, without an error. + * + * Returns: %TRUE if successful. If an error + * has occurred, this function will return %FALSE and set @error + * appropriately if present. + **/ +gboolean +g_seekable_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error) +{ + GSeekableIface *iface; + + g_return_val_if_fail (G_IS_SEEKABLE (seekable), FALSE); + + iface = G_SEEKABLE_GET_IFACE (seekable); + + return (* iface->truncate_fn) (seekable, offset, cancellable, error); +} diff --git a/gio/gseekable.h b/gio/gseekable.h new file mode 100644 index 0000000..191f3cc --- /dev/null +++ b/gio/gseekable.h @@ -0,0 +1,103 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_SEEKABLE_H__ +#define __G_SEEKABLE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SEEKABLE (g_seekable_get_type ()) +#define G_SEEKABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SEEKABLE, GSeekable)) +#define G_IS_SEEKABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SEEKABLE)) +#define G_SEEKABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_SEEKABLE, GSeekableIface)) + +/** + * GSeekable: + * + * Seek object for streaming operations. + **/ +typedef struct _GSeekableIface GSeekableIface; + +/** + * GSeekableIface: + * @g_iface: The parent interface. + * @tell: Tells the current location within a stream. + * @can_seek: Checks if seeking is supported by the stream. + * @seek: Seeks to a location within a stream. + * @can_truncate: Checks if truncation is supported by the stream. + * @truncate_fn: Truncates a stream. + * + * Provides an interface for implementing seekable functionality on I/O Streams. + **/ +struct _GSeekableIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + goffset (* tell) (GSeekable *seekable); + + gboolean (* can_seek) (GSeekable *seekable); + gboolean (* seek) (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); + + gboolean (* can_truncate) (GSeekable *seekable); + gboolean (* truncate_fn) (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); + + /* TODO: Async seek/truncate */ +}; + +GLIB_AVAILABLE_IN_ALL +GType g_seekable_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +goffset g_seekable_tell (GSeekable *seekable); +GLIB_AVAILABLE_IN_ALL +gboolean g_seekable_can_seek (GSeekable *seekable); +GLIB_AVAILABLE_IN_ALL +gboolean g_seekable_seek (GSeekable *seekable, + goffset offset, + GSeekType type, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_seekable_can_truncate (GSeekable *seekable); +GLIB_AVAILABLE_IN_ALL +gboolean g_seekable_truncate (GSeekable *seekable, + goffset offset, + GCancellable *cancellable, + GError **error); + +G_END_DECLS + + +#endif /* __G_SEEKABLE_H__ */ diff --git a/gio/gsettings-mapping.c b/gio/gsettings-mapping.c new file mode 100644 index 0000000..c4ffc9b --- /dev/null +++ b/gio/gsettings-mapping.c @@ -0,0 +1,592 @@ +/* + * Copyright © 2010 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Vincent Untz + */ + +#include "config.h" + +#include "gsettings-mapping.h" + +static GVariant * +g_settings_set_mapping_int (const GValue *value, + const GVariantType *expected_type) +{ + GVariant *variant = NULL; + gint64 l; + + if (G_VALUE_HOLDS_INT (value)) + l = g_value_get_int (value); + else if (G_VALUE_HOLDS_INT64 (value)) + l = g_value_get_int64 (value); + else + return NULL; + + if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16)) + { + if (G_MININT16 <= l && l <= G_MAXINT16) + variant = g_variant_new_int16 ((gint16) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16)) + { + if (0 <= l && l <= G_MAXUINT16) + variant = g_variant_new_uint16 ((guint16) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32)) + { + if (G_MININT32 <= l && l <= G_MAXINT32) + variant = g_variant_new_int32 ((gint) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32)) + { + if (0 <= l && l <= G_MAXUINT32) + variant = g_variant_new_uint32 ((guint) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64)) + { + if (G_MININT64 <= l && l <= G_MAXINT64) + variant = g_variant_new_int64 ((gint64) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64)) + { + if (0 <= l && (guint64) l <= G_MAXUINT64) + variant = g_variant_new_uint64 ((guint64) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE)) + { + if (0 <= l && l <= G_MAXUINT32) + variant = g_variant_new_handle ((guint) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE)) + variant = g_variant_new_double ((gdouble) l); + + return variant; +} + +static GVariant * +g_settings_set_mapping_float (const GValue *value, + const GVariantType *expected_type) +{ + GVariant *variant = NULL; + gdouble d; + gint64 l; + + if (G_VALUE_HOLDS_DOUBLE (value)) + d = g_value_get_double (value); + else + return NULL; + + l = (gint64) d; + if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16)) + { + if (G_MININT16 <= l && l <= G_MAXINT16) + variant = g_variant_new_int16 ((gint16) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16)) + { + if (0 <= l && l <= G_MAXUINT16) + variant = g_variant_new_uint16 ((guint16) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32)) + { + if (G_MININT32 <= l && l <= G_MAXINT32) + variant = g_variant_new_int32 ((gint) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32)) + { + if (0 <= l && l <= G_MAXUINT32) + variant = g_variant_new_uint32 ((guint) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64)) + { + if (G_MININT64 <= l && l <= G_MAXINT64) + variant = g_variant_new_int64 ((gint64) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64)) + { + if (0 <= l && (guint64) l <= G_MAXUINT64) + variant = g_variant_new_uint64 ((guint64) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE)) + { + if (0 <= l && l <= G_MAXUINT32) + variant = g_variant_new_handle ((guint) l); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE)) + variant = g_variant_new_double ((gdouble) d); + + return variant; +} +static GVariant * +g_settings_set_mapping_unsigned_int (const GValue *value, + const GVariantType *expected_type) +{ + GVariant *variant = NULL; + guint64 u; + + if (G_VALUE_HOLDS_UINT (value)) + u = g_value_get_uint (value); + else if (G_VALUE_HOLDS_UINT64 (value)) + u = g_value_get_uint64 (value); + else + return NULL; + + if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16)) + { + if (u <= G_MAXINT16) + variant = g_variant_new_int16 ((gint16) u); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16)) + { + if (u <= G_MAXUINT16) + variant = g_variant_new_uint16 ((guint16) u); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32)) + { + if (u <= G_MAXINT32) + variant = g_variant_new_int32 ((gint) u); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32)) + { + if (u <= G_MAXUINT32) + variant = g_variant_new_uint32 ((guint) u); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64)) + { + if (u <= G_MAXINT64) + variant = g_variant_new_int64 ((gint64) u); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64)) + { + if (u <= G_MAXUINT64) + variant = g_variant_new_uint64 ((guint64) u); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE)) + { + if (u <= G_MAXUINT32) + variant = g_variant_new_handle ((guint) u); + } + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE)) + variant = g_variant_new_double ((gdouble) u); + + return variant; +} + +static gboolean +g_settings_get_mapping_int (GValue *value, + GVariant *variant) +{ + const GVariantType *type; + gint64 l; + + type = g_variant_get_type (variant); + + if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16)) + l = g_variant_get_int16 (variant); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) + l = g_variant_get_int32 (variant); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64)) + l = g_variant_get_int64 (variant); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE)) + l = g_variant_get_handle (variant); + else + return FALSE; + + if (G_VALUE_HOLDS_INT (value)) + { + g_value_set_int (value, l); + return (G_MININT32 <= l && l <= G_MAXINT32); + } + else if (G_VALUE_HOLDS_UINT (value)) + { + g_value_set_uint (value, l); + return (0 <= l && l <= G_MAXUINT32); + } + else if (G_VALUE_HOLDS_INT64 (value)) + { + g_value_set_int64 (value, l); + return (G_MININT64 <= l && l <= G_MAXINT64); + } + else if (G_VALUE_HOLDS_UINT64 (value)) + { + g_value_set_uint64 (value, l); + return (0 <= l && (guint64) l <= G_MAXUINT64); + } + else if (G_VALUE_HOLDS_DOUBLE (value)) + { + g_value_set_double (value, l); + return TRUE; + } + + return FALSE; +} + +static gboolean +g_settings_get_mapping_float (GValue *value, + GVariant *variant) +{ + const GVariantType *type; + gdouble d; + gint64 l; + + type = g_variant_get_type (variant); + + if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE)) + d = g_variant_get_double (variant); + else + return FALSE; + + l = (gint64)d; + if (G_VALUE_HOLDS_INT (value)) + { + g_value_set_int (value, l); + return (G_MININT32 <= l && l <= G_MAXINT32); + } + else if (G_VALUE_HOLDS_UINT (value)) + { + g_value_set_uint (value, l); + return (0 <= l && l <= G_MAXUINT32); + } + else if (G_VALUE_HOLDS_INT64 (value)) + { + g_value_set_int64 (value, l); + return (G_MININT64 <= l && l <= G_MAXINT64); + } + else if (G_VALUE_HOLDS_UINT64 (value)) + { + g_value_set_uint64 (value, l); + return (0 <= l && (guint64) l <= G_MAXUINT64); + } + else if (G_VALUE_HOLDS_DOUBLE (value)) + { + g_value_set_double (value, d); + return TRUE; + } + + return FALSE; +} +static gboolean +g_settings_get_mapping_unsigned_int (GValue *value, + GVariant *variant) +{ + const GVariantType *type; + guint64 u; + + type = g_variant_get_type (variant); + + if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16)) + u = g_variant_get_uint16 (variant); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32)) + u = g_variant_get_uint32 (variant); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64)) + u = g_variant_get_uint64 (variant); + else + return FALSE; + + if (G_VALUE_HOLDS_INT (value)) + { + g_value_set_int (value, u); + return (u <= G_MAXINT32); + } + else if (G_VALUE_HOLDS_UINT (value)) + { + g_value_set_uint (value, u); + return (u <= G_MAXUINT32); + } + else if (G_VALUE_HOLDS_INT64 (value)) + { + g_value_set_int64 (value, u); + return (u <= G_MAXINT64); + } + else if (G_VALUE_HOLDS_UINT64 (value)) + { + g_value_set_uint64 (value, u); + return (u <= G_MAXUINT64); + } + else if (G_VALUE_HOLDS_DOUBLE (value)) + { + g_value_set_double (value, u); + return TRUE; + } + + return FALSE; +} + +GVariant * +g_settings_set_mapping (const GValue *value, + const GVariantType *expected_type, + gpointer user_data) +{ + gchar *type_string; + + if (G_VALUE_HOLDS_BOOLEAN (value)) + { + if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN)) + return g_variant_new_boolean (g_value_get_boolean (value)); + } + + else if (G_VALUE_HOLDS_CHAR (value) || + G_VALUE_HOLDS_UCHAR (value)) + { + if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE)) + { + if (G_VALUE_HOLDS_CHAR (value)) + return g_variant_new_byte (g_value_get_schar (value)); + else + return g_variant_new_byte (g_value_get_uchar (value)); + } + } + + else if (G_VALUE_HOLDS_INT (value) || + G_VALUE_HOLDS_INT64 (value)) + return g_settings_set_mapping_int (value, expected_type); + + else if (G_VALUE_HOLDS_DOUBLE (value)) + return g_settings_set_mapping_float (value, expected_type); + + else if (G_VALUE_HOLDS_UINT (value) || + G_VALUE_HOLDS_UINT64 (value)) + return g_settings_set_mapping_unsigned_int (value, expected_type); + + else if (G_VALUE_HOLDS_STRING (value)) + { + if (g_value_get_string (value) == NULL) + return NULL; + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING)) + return g_variant_new_string (g_value_get_string (value)); + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING)) + return g_variant_new_bytestring (g_value_get_string (value)); + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH)) + return g_variant_new_object_path (g_value_get_string (value)); + else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE)) + return g_variant_new_signature (g_value_get_string (value)); + } + + else if (G_VALUE_HOLDS (value, G_TYPE_STRV)) + { + if (g_value_get_boxed (value) == NULL) + return NULL; + return g_variant_new_strv ((const gchar **) g_value_get_boxed (value), + -1); + } + + else if (G_VALUE_HOLDS_ENUM (value)) + { + GEnumValue *enumval; + GEnumClass *eclass; + + /* GParamSpecEnum holds a ref on the class so we just peek... */ + eclass = g_type_class_peek (G_VALUE_TYPE (value)); + enumval = g_enum_get_value (eclass, g_value_get_enum (value)); + + if (enumval) + return g_variant_new_string (enumval->value_nick); + else + return NULL; + } + + else if (G_VALUE_HOLDS_FLAGS (value)) + { + GVariantBuilder builder; + GFlagsValue *flagsval; + GFlagsClass *fclass; + guint flags; + + fclass = g_type_class_peek (G_VALUE_TYPE (value)); + flags = g_value_get_flags (value); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); + while (flags) + { + flagsval = g_flags_get_first_value (fclass, flags); + + if (flagsval == NULL) + { + g_variant_builder_clear (&builder); + return NULL; + } + + g_variant_builder_add (&builder, "s", flagsval->value_nick); + flags &= ~flagsval->value; + } + + return g_variant_builder_end (&builder); + } + + type_string = g_variant_type_dup_string (expected_type); + g_critical ("No GSettings bind handler for type \"%s\".", type_string); + g_free (type_string); + + return NULL; +} + +gboolean +g_settings_get_mapping (GValue *value, + GVariant *variant, + gpointer user_data) +{ + if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)) + { + if (!G_VALUE_HOLDS_BOOLEAN (value)) + return FALSE; + g_value_set_boolean (value, g_variant_get_boolean (variant)); + return TRUE; + } + + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE)) + { + if (G_VALUE_HOLDS_UCHAR (value)) + g_value_set_uchar (value, g_variant_get_byte (variant)); + else if (G_VALUE_HOLDS_CHAR (value)) + g_value_set_schar (value, (gint8)g_variant_get_byte (variant)); + else + return FALSE; + return TRUE; + } + + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16) || + g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32) || + g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64) || + g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE)) + return g_settings_get_mapping_int (value, variant); + + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE)) + return g_settings_get_mapping_float (value, variant); + + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) || + g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) || + g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64)) + return g_settings_get_mapping_unsigned_int (value, variant); + + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING) || + g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH) || + g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE)) + { + if (G_VALUE_HOLDS_STRING (value)) + { + g_value_set_string (value, g_variant_get_string (variant, NULL)); + return TRUE; + } + + else if (G_VALUE_HOLDS_ENUM (value)) + { + GEnumClass *eclass; + GEnumValue *evalue; + const gchar *nick; + + /* GParamSpecEnum holds a ref on the class so we just peek... */ + eclass = g_type_class_peek (G_VALUE_TYPE (value)); + nick = g_variant_get_string (variant, NULL); + evalue = g_enum_get_value_by_nick (eclass, nick); + + if (evalue) + { + g_value_set_enum (value, evalue->value); + return TRUE; + } + + g_warning ("Unable to look up enum nick ‘%s’ via GType", nick); + return FALSE; + } + } + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("as"))) + { + if (G_VALUE_HOLDS (value, G_TYPE_STRV)) + { + g_value_take_boxed (value, g_variant_dup_strv (variant, NULL)); + return TRUE; + } + + else if (G_VALUE_HOLDS_FLAGS (value)) + { + GFlagsClass *fclass; + GFlagsValue *fvalue; + const gchar *nick; + GVariantIter iter; + guint flags = 0; + + fclass = g_type_class_peek (G_VALUE_TYPE (value)); + + g_variant_iter_init (&iter, variant); + while (g_variant_iter_next (&iter, "&s", &nick)) + { + fvalue = g_flags_get_value_by_nick (fclass, nick); + + if (fvalue) + flags |= fvalue->value; + + else + { + g_warning ("Unable to lookup flags nick '%s' via GType", + nick); + return FALSE; + } + } + + g_value_set_flags (value, flags); + return TRUE; + } + } + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTESTRING)) + { + g_value_set_string (value, g_variant_get_bytestring (variant)); + return TRUE; + } + + g_critical ("No GSettings bind handler for type \"%s\".", + g_variant_get_type_string (variant)); + + return FALSE; +} + +gboolean +g_settings_mapping_is_compatible (GType gvalue_type, + const GVariantType *variant_type) +{ + gboolean ok = FALSE; + + if (gvalue_type == G_TYPE_BOOLEAN) + ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN); + else if (gvalue_type == G_TYPE_CHAR || + gvalue_type == G_TYPE_UCHAR) + ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BYTE); + else if (gvalue_type == G_TYPE_INT || + gvalue_type == G_TYPE_UINT || + gvalue_type == G_TYPE_INT64 || + gvalue_type == G_TYPE_UINT64 || + gvalue_type == G_TYPE_DOUBLE) + ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT16) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT16) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT32) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT64) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_HANDLE) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_DOUBLE)); + else if (gvalue_type == G_TYPE_STRING) + ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE ("ay")) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_OBJECT_PATH) || + g_variant_type_equal (variant_type, G_VARIANT_TYPE_SIGNATURE)); + else if (gvalue_type == G_TYPE_STRV) + ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as")); + else if (G_TYPE_IS_ENUM (gvalue_type)) + ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING); + else if (G_TYPE_IS_FLAGS (gvalue_type)) + ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as")); + + return ok; +} diff --git a/gio/gsettings-mapping.h b/gio/gsettings-mapping.h new file mode 100644 index 0000000..8a26684 --- /dev/null +++ b/gio/gsettings-mapping.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2010 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Vincent Untz + */ + +#ifndef __G_SETTINGS_MAPPING_H__ +#define __G_SETTINGS_MAPPING_H__ + +#include + +GVariant * g_settings_set_mapping (const GValue *value, + const GVariantType *expected_type, + gpointer user_data); +gboolean g_settings_get_mapping (GValue *value, + GVariant *variant, + gpointer user_data); +gboolean g_settings_mapping_is_compatible (GType gvalue_type, + const GVariantType *variant_type); + +#endif /* __G_SETTINGS_MAPPING_H__ */ diff --git a/gio/gsettings-tool.c b/gio/gsettings-tool.c new file mode 100644 index 0000000..9352b70 --- /dev/null +++ b/gio/gsettings-tool.c @@ -0,0 +1,956 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "glib/glib-private.h" + +static GSettingsSchemaSource *global_schema_source; +static GSettings *global_settings; +static GSettingsSchema *global_schema; +static GSettingsSchemaKey *global_schema_key; +const gchar *global_key; +const gchar *global_value; + +static gboolean +is_relocatable_schema (GSettingsSchema *schema) +{ + return g_settings_schema_get_path (schema) == NULL; +} + +static gboolean +check_relocatable_schema (GSettingsSchema *schema, + const gchar *schema_id) +{ + if (schema == NULL) + { + g_printerr (_("No such schema “%sâ€\n"), schema_id); + return FALSE; + } + + if (!is_relocatable_schema (schema)) + { + g_printerr (_("Schema “%s†is not relocatable " + "(path must not be specified)\n"), + schema_id); + return FALSE; + } + + return TRUE; +} + +static gboolean +check_schema (GSettingsSchema *schema, + const gchar *schema_id) +{ + if (schema == NULL) + { + g_printerr (_("No such schema “%sâ€\n"), schema_id); + return FALSE; + } + + if (is_relocatable_schema (schema)) + { + g_printerr (_("Schema “%s†is relocatable " + "(path must be specified)\n"), + schema_id); + return FALSE; + } + + return TRUE; +} + +static gboolean +check_path (const gchar *path) +{ + if (path[0] == '\0') + { + g_printerr (_("Empty path given.\n")); + return FALSE; + } + + if (path[0] != '/') + { + g_printerr (_("Path must begin with a slash (/)\n")); + return FALSE; + } + + if (!g_str_has_suffix (path, "/")) + { + g_printerr (_("Path must end with a slash (/)\n")); + return FALSE; + } + + if (strstr (path, "//")) + { + g_printerr (_("Path must not contain two adjacent slashes (//)\n")); + return FALSE; + } + + return TRUE; +} + +static int +qsort_cmp (const void *a, + const void *b) +{ + return g_strcmp0 (*(gchar* const*)a, *(gchar* const*)b); +} + +static void +output_list (gchar **list) +{ + gint i; + + qsort (list, g_strv_length (list), sizeof (gchar*), qsort_cmp); + for (i = 0; list[i]; i++) + g_print ("%s\n", list[i]); +} + +static void +gsettings_print_version (void) +{ + g_print ("%d.%d.%d\n", glib_major_version, glib_minor_version, + glib_micro_version); +} + +static void +gsettings_list_schemas (void) +{ + gchar **schemas; + + g_settings_schema_source_list_schemas (global_schema_source, TRUE, &schemas, NULL); + output_list (schemas); + g_strfreev (schemas); +} + +static void +gsettings_list_schemas_with_paths (void) +{ + gchar **schemas; + gsize i; + + g_settings_schema_source_list_schemas (global_schema_source, TRUE, &schemas, NULL); + + for (i = 0; schemas[i] != NULL; i++) + { + GSettingsSchema *schema; + gchar *schema_name; + const gchar *schema_path; + + schema_name = g_steal_pointer (&schemas[i]); + + schema = g_settings_schema_source_lookup (global_schema_source, schema_name, TRUE); + schema_path = g_settings_schema_get_path (schema); + + schemas[i] = g_strconcat (schema_name, " ", schema_path, NULL); + + g_settings_schema_unref (schema); + g_free (schema_name); + } + + output_list (schemas); + g_strfreev (schemas); +} + +static void +gsettings_list_relocatable_schemas (void) +{ + gchar **schemas; + + g_settings_schema_source_list_schemas (global_schema_source, TRUE, NULL, &schemas); + output_list (schemas); + g_strfreev (schemas); +} + +static void +gsettings_list_keys (void) +{ + gchar **keys; + + keys = g_settings_schema_list_keys (global_schema); + output_list (keys); + g_strfreev (keys); +} + +static void +gsettings_list_children (void) +{ + gchar **children; + gsize max = 0; + gint i; + + children = g_settings_list_children (global_settings); + qsort (children, g_strv_length (children), sizeof (gchar*), qsort_cmp); + for (i = 0; children[i]; i++) + { + gsize len = strlen (children[i]); + if (len > max) + max = len; + } + + for (i = 0; children[i]; i++) + { + GSettings *child; + GSettingsSchema *schema; + gchar *path; + + child = g_settings_get_child (global_settings, children[i]); + g_object_get (child, + "settings-schema", &schema, + "path", &path, + NULL); + + if (g_settings_schema_get_path (schema) != NULL) + g_print ("%-*s %s\n", (int) MIN (max, G_MAXINT), children[i], + g_settings_schema_get_id (schema)); + else + g_print ("%-*s %s:%s\n", (int) MIN (max, G_MAXINT), children[i], + g_settings_schema_get_id (schema), path); + + g_object_unref (child); + g_settings_schema_unref (schema); + g_free (path); + } + + g_strfreev (children); +} + +static void +enumerate (GSettings *settings) +{ + gchar **keys; + GSettingsSchema *schema; + gint i; + + g_object_get (settings, "settings-schema", &schema, NULL); + + keys = g_settings_schema_list_keys (schema); + qsort (keys, g_strv_length (keys), sizeof (gchar*), qsort_cmp); + for (i = 0; keys[i]; i++) + { + GVariant *value; + gchar *printed; + + value = g_settings_get_value (settings, keys[i]); + printed = g_variant_print (value, TRUE); + g_print ("%s %s %s\n", g_settings_schema_get_id (schema), keys[i], printed); + g_variant_unref (value); + g_free (printed); + } + + g_settings_schema_unref (schema); + g_strfreev (keys); +} + +static void +list_recursively (GSettings *settings) +{ + gchar **children; + gint i; + + enumerate (settings); + children = g_settings_list_children (settings); + qsort (children, g_strv_length (children), sizeof (gchar*), qsort_cmp); + for (i = 0; children[i]; i++) + { + gboolean will_see_elsewhere = FALSE; + GSettings *child; + + child = g_settings_get_child (settings, children[i]); + + if (global_settings == NULL) + { + /* we're listing all non-relocatable settings objects from the + * top-level, so if this one is non-relocatable, don't recurse, + * because we will pick it up later on. + */ + + GSettingsSchema *child_schema; + + g_object_get (child, "settings-schema", &child_schema, NULL); + will_see_elsewhere = !is_relocatable_schema (child_schema); + g_settings_schema_unref (child_schema); + } + + if (!will_see_elsewhere) + list_recursively (child); + + g_object_unref (child); + } + + g_strfreev (children); +} + +static void +gsettings_list_recursively (void) +{ + if (global_settings) + { + list_recursively (global_settings); + } + else + { + gchar **schemas; + gint i; + + g_settings_schema_source_list_schemas (global_schema_source, TRUE, &schemas, NULL); + qsort (schemas, g_strv_length (schemas), sizeof (gchar*), qsort_cmp); + + for (i = 0; schemas[i]; i++) + { + GSettings *settings; + + settings = g_settings_new (schemas[i]); + list_recursively (settings); + g_object_unref (settings); + } + + g_strfreev (schemas); + } +} + +static void +gsettings_description (void) +{ + const gchar *description; + description = g_settings_schema_key_get_description (global_schema_key); + if (description == NULL) + description = g_settings_schema_key_get_summary (global_schema_key); + g_print ("%s\n", description); +} + +static void +gsettings_range (void) +{ + GVariant *range, *detail; + const gchar *type; + + range = g_settings_schema_key_get_range (global_schema_key); + g_variant_get (range, "(&sv)", &type, &detail); + + if (strcmp (type, "type") == 0) + g_print ("type %s\n", g_variant_get_type_string (detail) + 1); + + else if (strcmp (type, "range") == 0) + { + GVariant *min, *max; + gchar *smin, *smax; + + g_variant_get (detail, "(**)", &min, &max); + smin = g_variant_print (min, FALSE); + smax = g_variant_print (max, FALSE); + + g_print ("range %s %s %s\n", + g_variant_get_type_string (min), smin, smax); + g_variant_unref (min); + g_variant_unref (max); + g_free (smin); + g_free (smax); + } + + else if (strcmp (type, "enum") == 0 || strcmp (type, "flags") == 0) + { + GVariantIter iter; + GVariant *item; + + g_print ("%s\n", type); + + g_variant_iter_init (&iter, detail); + while (g_variant_iter_loop (&iter, "*", &item)) + { + gchar *printed; + + printed = g_variant_print (item, FALSE); + g_print ("%s\n", printed); + g_free (printed); + } + } + + g_variant_unref (detail); + g_variant_unref (range); +} + +static void +gsettings_get (void) +{ + GVariant *value; + gchar *printed; + + value = g_settings_get_value (global_settings, global_key); + printed = g_variant_print (value, TRUE); + g_print ("%s\n", printed); + g_variant_unref (value); + g_free (printed); +} + +static void +gsettings_reset (void) +{ + g_settings_reset (global_settings, global_key); + g_settings_sync (); +} + +static void +reset_all_keys (GSettings *settings) +{ + GSettingsSchema *schema; + gchar **keys; + gint i; + + g_object_get (settings, "settings-schema", &schema, NULL); + + keys = g_settings_schema_list_keys (schema); + for (i = 0; keys[i]; i++) + { + g_settings_reset (settings, keys[i]); + } + + g_settings_schema_unref (schema); + g_strfreev (keys); +} + +static void +gsettings_reset_recursively (void) +{ + gchar **children; + gint i; + + g_settings_delay (global_settings); + + reset_all_keys (global_settings); + children = g_settings_list_children (global_settings); + for (i = 0; children[i]; i++) + { + GSettings *child; + child = g_settings_get_child (global_settings, children[i]); + + reset_all_keys (child); + + g_object_unref (child); + } + + g_strfreev (children); + + g_settings_apply (global_settings); + g_settings_sync (); +} + +static void +gsettings_writable (void) +{ + g_print ("%s\n", + g_settings_is_writable (global_settings, global_key) ? + "true" : "false"); +} + +static void +value_changed (GSettings *settings, + const gchar *key, + gpointer user_data) +{ + GVariant *value; + gchar *printed; + + value = g_settings_get_value (settings, key); + printed = g_variant_print (value, TRUE); + g_print ("%s: %s\n", key, printed); + g_variant_unref (value); + g_free (printed); +} + +static void +gsettings_monitor (void) +{ + if (global_key) + { + gchar *name; + + name = g_strdup_printf ("changed::%s", global_key); + g_signal_connect (global_settings, name, G_CALLBACK (value_changed), NULL); + } + else + g_signal_connect (global_settings, "changed", G_CALLBACK (value_changed), NULL); + + for (;;) + g_main_context_iteration (NULL, TRUE); +} + +static void +gsettings_set (void) +{ + const GVariantType *type; + GError *error = NULL; + GVariant *new; + gchar *freeme = NULL; + + type = g_settings_schema_key_get_value_type (global_schema_key); + + new = g_variant_parse (type, global_value, NULL, NULL, &error); + + /* If that didn't work and the type is string then we should assume + * that the user is just trying to set a string directly and forgot + * the quotes (or had them consumed by the shell). + * + * If the user started with a quote then we assume that some deeper + * problem is at play and we want the failure in that case. + * + * Consider: + * + * gsettings set x.y.z key "'i don't expect this to work'" + * + * Note that we should not just add quotes and try parsing again, but + * rather assume that the user is providing us with a bare string. + * Assume we added single quotes, then consider this case: + * + * gsettings set x.y.z key "i'd expect this to work" + * + * A similar example could be given for double quotes. + * + * Avoid that whole mess by just using g_variant_new_string(). + */ + if (new == NULL && + g_variant_type_equal (type, G_VARIANT_TYPE_STRING) && + global_value[0] != '\'' && global_value[0] != '"') + { + g_clear_error (&error); + new = g_variant_new_string (global_value); + } + + if (new == NULL) + { + gchar *context; + + context = g_variant_parse_error_print_context (error, global_value); + g_printerr ("%s", context); + exit (1); + } + + if (!g_settings_schema_key_range_check (global_schema_key, new)) + { + g_printerr (_("The provided value is outside of the valid range\n")); + g_variant_unref (new); + exit (1); + } + + if (!g_settings_set_value (global_settings, global_key, new)) + { + g_printerr (_("The key is not writable\n")); + exit (1); + } + + g_settings_sync (); + + g_free (freeme); +} + +static int +gsettings_help (gboolean requested, + const gchar *command) +{ + const gchar *description = NULL; + const gchar *synopsis = NULL; + GString *string; + + string = g_string_new (NULL); + + if (command == NULL) + ; + + else if (strcmp (command, "help") == 0) + { + description = _("Print help"); + synopsis = "[COMMAND]"; + } + + else if (strcmp (command, "--version") == 0) + { + description = _("Print version information and exit"); + synopsis = ""; + } + + else if (strcmp (command, "list-schemas") == 0) + { + description = _("List the installed (non-relocatable) schemas"); + synopsis = "[--print-paths]"; + } + + else if (strcmp (command, "list-relocatable-schemas") == 0) + { + description = _("List the installed relocatable schemas"); + synopsis = ""; + } + + else if (strcmp (command, "list-keys") == 0) + { + description = _("List the keys in SCHEMA"); + synopsis = N_("SCHEMA[:PATH]"); + } + + else if (strcmp (command, "list-children") == 0) + { + description = _("List the children of SCHEMA"); + synopsis = N_("SCHEMA[:PATH]"); + } + + else if (strcmp (command, "list-recursively") == 0) + { + description = _("List keys and values, recursively\n" + "If no SCHEMA is given, list all keys\n"); + synopsis = N_("[SCHEMA[:PATH]]"); + } + + else if (strcmp (command, "get") == 0) + { + description = _("Get the value of KEY"); + synopsis = N_("SCHEMA[:PATH] KEY"); + } + + else if (strcmp (command, "range") == 0) + { + description = _("Query the range of valid values for KEY"); + synopsis = N_("SCHEMA[:PATH] KEY"); + } + + else if (strcmp (command, "describe") == 0) + { + description = _("Query the description for KEY"); + synopsis = N_("SCHEMA[:PATH] KEY"); + } + + else if (strcmp (command, "set") == 0) + { + description = _("Set the value of KEY to VALUE"); + synopsis = N_("SCHEMA[:PATH] KEY VALUE"); + } + + else if (strcmp (command, "reset") == 0) + { + description = _("Reset KEY to its default value"); + synopsis = N_("SCHEMA[:PATH] KEY"); + } + + else if (strcmp (command, "reset-recursively") == 0) + { + description = _("Reset all keys in SCHEMA to their defaults"); + synopsis = N_("SCHEMA[:PATH]"); + } + + else if (strcmp (command, "writable") == 0) + { + description = _("Check if KEY is writable"); + synopsis = N_("SCHEMA[:PATH] KEY"); + } + + else if (strcmp (command, "monitor") == 0) + { + description = _("Monitor KEY for changes.\n" + "If no KEY is specified, monitor all keys in SCHEMA.\n" + "Use ^C to stop monitoring.\n"); + synopsis = N_("SCHEMA[:PATH] [KEY]"); + } + else + { + g_string_printf (string, _("Unknown command %s\n\n"), command); + requested = FALSE; + command = NULL; + } + + if (command == NULL) + { + g_string_append (string, + _("Usage:\n" + " gsettings --version\n" + " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" + "\n" + "Commands:\n" + " help Show this information\n" + " list-schemas List installed schemas\n" + " list-relocatable-schemas List relocatable schemas\n" + " list-keys List keys in a schema\n" + " list-children List children of a schema\n" + " list-recursively List keys and values, recursively\n" + " range Queries the range of a key\n" + " describe Queries the description of a key\n" + " get Get the value of a key\n" + " set Set the value of a key\n" + " reset Reset the value of a key\n" + " reset-recursively Reset all values in a given schema\n" + " writable Check if a key is writable\n" + " monitor Watch for changes\n" + "\n" + "Use “gsettings help COMMAND†to get detailed help.\n\n")); + } + else + { + g_string_append_printf (string, _("Usage:\n gsettings [--schemadir SCHEMADIR] %s %s\n\n%s\n\n"), + command, synopsis[0] ? _(synopsis) : "", description); + + g_string_append (string, _("Arguments:\n")); + + g_string_append (string, + _(" SCHEMADIR A directory to search for additional schemas\n")); + + if (strstr (synopsis, "[COMMAND]")) + g_string_append (string, + _(" COMMAND The (optional) command to explain\n")); + + else if (strstr (synopsis, "SCHEMA")) + g_string_append (string, + _(" SCHEMA The name of the schema\n" + " PATH The path, for relocatable schemas\n")); + + if (strstr (synopsis, "[KEY]")) + g_string_append (string, + _(" KEY The (optional) key within the schema\n")); + + else if (strstr (synopsis, "KEY")) + g_string_append (string, + _(" KEY The key within the schema\n")); + + if (strstr (synopsis, "VALUE")) + g_string_append (string, + _(" VALUE The value to set\n")); + + g_string_append (string, "\n"); + } + + if (requested) + g_print ("%s", string->str); + else + g_printerr ("%s\n", string->str); + + g_string_free (string, TRUE); + + return requested ? 0 : 1; +} + + +int +main (int argc, char **argv) +{ + void (* function) (void); + gboolean need_settings, skip_third_arg_test; + +#ifdef G_OS_WIN32 + gchar *tmp; +#endif + + setlocale (LC_ALL, GLIB_DEFAULT_LOCALE); + textdomain (GETTEXT_PACKAGE); + +#ifdef G_OS_WIN32 + tmp = _glib_get_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, tmp); + g_free (tmp); +#else + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#endif + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + + if (argc < 2) + return gsettings_help (FALSE, NULL); + + global_schema_source = g_settings_schema_source_get_default (); + + if (argc > 3 && g_str_equal (argv[1], "--schemadir")) + { + GSettingsSchemaSource *parent = global_schema_source; + GError *error = NULL; + + global_schema_source = g_settings_schema_source_new_from_directory (argv[2], parent, FALSE, &error); + + if (global_schema_source == NULL) + { + g_printerr (_("Could not load schemas from %s: %s\n"), argv[2], error->message); + g_clear_error (&error); + + return 1; + } + + /* shift remaining arguments (not correct wrt argv[0], but doesn't matter) */ + argv = argv + 2; + argc -= 2; + } + else if (global_schema_source == NULL) + { + g_printerr (_("No schemas installed\n")); + return 1; + } + else + g_settings_schema_source_ref (global_schema_source); + + need_settings = TRUE; + skip_third_arg_test = FALSE; + + if (strcmp (argv[1], "help") == 0) + return gsettings_help (TRUE, argv[2]); + + else if (argc == 2 && strcmp (argv[1], "--version") == 0) + function = gsettings_print_version; + + else if (argc == 2 && strcmp (argv[1], "list-schemas") == 0) + function = gsettings_list_schemas; + + else if (argc == 3 && strcmp (argv[1], "list-schemas") == 0 + && strcmp (argv[2], "--print-paths") == 0) + { + skip_third_arg_test = TRUE; + function = gsettings_list_schemas_with_paths; + } + + else if (argc == 2 && strcmp (argv[1], "list-relocatable-schemas") == 0) + function = gsettings_list_relocatable_schemas; + + else if (argc == 3 && strcmp (argv[1], "list-keys") == 0) + { + need_settings = FALSE; + function = gsettings_list_keys; + } + + else if (argc == 3 && strcmp (argv[1], "list-children") == 0) + function = gsettings_list_children; + + else if ((argc == 2 || argc == 3) && strcmp (argv[1], "list-recursively") == 0) + function = gsettings_list_recursively; + + else if (argc == 4 && strcmp (argv[1], "describe") == 0) + { + need_settings = FALSE; + function = gsettings_description; + } + + else if (argc == 4 && strcmp (argv[1], "range") == 0) + { + need_settings = FALSE; + function = gsettings_range; + } + + else if (argc == 4 && strcmp (argv[1], "get") == 0) + function = gsettings_get; + + else if (argc == 5 && strcmp (argv[1], "set") == 0) + function = gsettings_set; + + else if (argc == 4 && strcmp (argv[1], "reset") == 0) + function = gsettings_reset; + + else if (argc == 3 && strcmp (argv[1], "reset-recursively") == 0) + function = gsettings_reset_recursively; + + else if (argc == 4 && strcmp (argv[1], "writable") == 0) + function = gsettings_writable; + + else if ((argc == 3 || argc == 4) && strcmp (argv[1], "monitor") == 0) + function = gsettings_monitor; + + else + return gsettings_help (FALSE, argv[1]); + + if (argc > 2 && !skip_third_arg_test) + { + gchar **parts; + + if (argv[2][0] == '\0') + { + g_printerr (_("Empty schema name given\n")); + return 1; + } + + parts = g_strsplit (argv[2], ":", 2); + + global_schema = g_settings_schema_source_lookup (global_schema_source, parts[0], TRUE); + + if (need_settings) + { + if (parts[1]) + { + if (!check_relocatable_schema (global_schema, parts[0]) || !check_path (parts[1])) + return 1; + + global_settings = g_settings_new_full (global_schema, NULL, parts[1]); + } + else + { + if (!check_schema (global_schema, parts[0])) + return 1; + + global_settings = g_settings_new_full (global_schema, NULL, NULL); + } + } + else + { + /* If the user has given a path then we enforce that we have a + * relocatable schema, but if they didn't give a path then it + * doesn't matter what type of schema we have (since it's + * reasonable to ask for introspection information on a + * relocatable schema without having to give the path). + */ + if (parts[1]) + { + if (!check_relocatable_schema (global_schema, parts[0]) || !check_path (parts[1])) + return 1; + } + else + { + if (global_schema == NULL) + { + g_printerr (_("No such schema “%sâ€\n"), parts[0]); + return 1; + } + } + } + + g_strfreev (parts); + } + + if (argc > 3) + { + if (!g_settings_schema_has_key (global_schema, argv[3])) + { + g_printerr (_("No such key “%sâ€\n"), argv[3]); + return 1; + } + + global_key = argv[3]; + global_schema_key = g_settings_schema_get_key (global_schema, global_key); + } + + if (argc > 4) + global_value = argv[4]; + + (* function) (); + + + g_clear_pointer (&global_schema_source, g_settings_schema_source_unref); + g_clear_pointer (&global_schema_key, g_settings_schema_key_unref); + g_clear_pointer (&global_schema, g_settings_schema_unref); + g_clear_object (&global_settings); + + return 0; +} diff --git a/gio/gsettings.c b/gio/gsettings.c new file mode 100644 index 0000000..21ae2ff --- /dev/null +++ b/gio/gsettings.c @@ -0,0 +1,3415 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +/* Prelude {{{1 */ +#include "config.h" + +#include +#include + +#include "gsettings.h" + +#include "gdelayedsettingsbackend.h" +#include "gsettingsbackendinternal.h" +#include "gsettings-mapping.h" +#include "gsettingsschema-internal.h" +#include "gaction.h" +#include "gmarshal-internal.h" + +#include "strinfo.c" + +/** + * SECTION:gsettings + * @short_description: High-level API for application settings + * @include: gio/gio.h + * + * The #GSettings class provides a convenient API for storing and retrieving + * application settings. + * + * Reads and writes can be considered to be non-blocking. Reading + * settings with #GSettings is typically extremely fast: on + * approximately the same order of magnitude (but slower than) a + * #GHashTable lookup. Writing settings is also extremely fast in terms + * of time to return to your application, but can be extremely expensive + * for other threads and other processes. Many settings backends + * (including dconf) have lazy initialisation which means in the common + * case of the user using their computer without modifying any settings + * a lot of work can be avoided. For dconf, the D-Bus service doesn't + * even need to be started in this case. For this reason, you should + * only ever modify #GSettings keys in response to explicit user action. + * Particular care should be paid to ensure that modifications are not + * made during startup -- for example, when setting the initial value + * of preferences widgets. The built-in g_settings_bind() functionality + * is careful not to write settings in response to notify signals as a + * result of modifications that it makes to widgets. + * + * When creating a GSettings instance, you have to specify a schema + * that describes the keys in your settings and their types and default + * values, as well as some other information. + * + * Normally, a schema has a fixed path that determines where the settings + * are stored in the conceptual global tree of settings. However, schemas + * can also be '[relocatable][gsettings-relocatable]', i.e. not equipped with + * a fixed path. This is + * useful e.g. when the schema describes an 'account', and you want to be + * able to store a arbitrary number of accounts. + * + * Paths must start with and end with a forward slash character ('/') + * and must not contain two sequential slash characters. Paths should + * be chosen based on a domain name associated with the program or + * library to which the settings belong. Examples of paths are + * "/org/gtk/settings/file-chooser/" and "/ca/desrt/dconf-editor/". + * Paths should not start with "/apps/", "/desktop/" or "/system/" as + * they often did in GConf. + * + * Unlike other configuration systems (like GConf), GSettings does not + * restrict keys to basic types like strings and numbers. GSettings stores + * values as #GVariant, and allows any #GVariantType for keys. Key names + * are restricted to lowercase characters, numbers and '-'. Furthermore, + * the names must begin with a lowercase character, must not end + * with a '-', and must not contain consecutive dashes. + * + * Similar to GConf, the default values in GSettings schemas can be + * localized, but the localized values are stored in gettext catalogs + * and looked up with the domain that is specified in the + * `gettext-domain` attribute of the or + * elements and the category that is specified in the `l10n` attribute of + * the element. The string which is translated includes all text in + * the element, including any surrounding quotation marks. + * + * The `l10n` attribute must be set to `messages` or `time`, and sets the + * [locale category for + * translation](https://www.gnu.org/software/gettext/manual/html_node/Aspects.html#index-locale-categories-1). + * The `messages` category should be used by default; use `time` for + * translatable date or time formats. A translation comment can be added as an + * XML comment immediately above the element — it is recommended to + * add these comments to aid translators understand the meaning and + * implications of the default value. An optional translation `context` + * attribute can be set on the element to disambiguate multiple + * defaults which use the same string. + * + * For example: + * |[ + * + * ['bad', 'words'] + * ]| + * + * Translations of default values must remain syntactically valid serialized + * #GVariants (e.g. retaining any surrounding quotation marks) or runtime + * errors will occur. + * + * GSettings uses schemas in a compact binary form that is created + * by the [glib-compile-schemas][glib-compile-schemas] + * utility. The input is a schema description in an XML format. + * + * A DTD for the gschema XML format can be found here: + * [gschema.dtd](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/gschema.dtd) + * + * The [glib-compile-schemas][glib-compile-schemas] tool expects schema + * files to have the extension `.gschema.xml`. + * + * At runtime, schemas are identified by their id (as specified in the + * id attribute of the element). The convention for schema + * ids is to use a dotted name, similar in style to a D-Bus bus name, + * e.g. "org.gnome.SessionManager". In particular, if the settings are + * for a specific service that owns a D-Bus bus name, the D-Bus bus name + * and schema id should match. For schemas which deal with settings not + * associated with one named application, the id should not use + * StudlyCaps, e.g. "org.gnome.font-rendering". + * + * In addition to #GVariant types, keys can have types that have + * enumerated types. These can be described by a , + * or element, as seen in the + * [example][schema-enumerated]. The underlying type of such a key + * is string, but you can use g_settings_get_enum(), g_settings_set_enum(), + * g_settings_get_flags(), g_settings_set_flags() access the numeric values + * corresponding to the string value of enum and flags keys. + * + * An example for default value: + * |[ + * + * + * + * + * "Hello, earthlings" + * A greeting + * + * Greeting of the invading martians + * + * + * + * + * (20,30) + * + * + * + * "" + * Empty strings have to be provided in GVariant form + * + * + * + * + * ]| + * + * An example for ranges, choices and enumerated types: + * |[ + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * 10 + * + * + * + * + * + * + * + * + * + * + * + * + * 'Joe' + * + * + * + * 'first' + * + * + * + * ["flag1","flag2"] + * + * + * + * ]| + * + * ## Vendor overrides + * + * Default values are defined in the schemas that get installed by + * an application. Sometimes, it is necessary for a vendor or distributor + * to adjust these defaults. Since patching the XML source for the schema + * is inconvenient and error-prone, + * [glib-compile-schemas][glib-compile-schemas] reads so-called vendor + * override' files. These are keyfiles in the same directory as the XML + * schema sources which can override default values. The schema id serves + * as the group name in the key file, and the values are expected in + * serialized GVariant form, as in the following example: + * |[ + * [org.gtk.Example] + * key1='string' + * key2=1.5 + * ]| + * + * glib-compile-schemas expects schema files to have the extension + * `.gschema.override`. + * + * ## Binding + * + * A very convenient feature of GSettings lets you bind #GObject properties + * directly to settings, using g_settings_bind(). Once a GObject property + * has been bound to a setting, changes on either side are automatically + * propagated to the other side. GSettings handles details like mapping + * between GObject and GVariant types, and preventing infinite cycles. + * + * This makes it very easy to hook up a preferences dialog to the + * underlying settings. To make this even more convenient, GSettings + * looks for a boolean property with the name "sensitivity" and + * automatically binds it to the writability of the bound setting. + * If this 'magic' gets in the way, it can be suppressed with the + * %G_SETTINGS_BIND_NO_SENSITIVITY flag. + * + * ## Relocatable schemas # {#gsettings-relocatable} + * + * A relocatable schema is one with no `path` attribute specified on its + * element. By using g_settings_new_with_path(), a #GSettings object + * can be instantiated for a relocatable schema, assigning a path to the + * instance. Paths passed to g_settings_new_with_path() will typically be + * constructed dynamically from a constant prefix plus some form of instance + * identifier; but they must still be valid GSettings paths. Paths could also + * be constant and used with a globally installed schema originating from a + * dependency library. + * + * For example, a relocatable schema could be used to store geometry information + * for different windows in an application. If the schema ID was + * `org.foo.MyApp.Window`, it could be instantiated for paths + * `/org/foo/MyApp/main/`, `/org/foo/MyApp/document-1/`, + * `/org/foo/MyApp/document-2/`, etc. If any of the paths are well-known + * they can be specified as elements in the parent schema, e.g.: + * |[ + * + * + * + * ]| + * + * ## Build system integration # {#gsettings-build-system} + * + * GSettings comes with autotools integration to simplify compiling and + * installing schemas. To add GSettings support to an application, add the + * following to your `configure.ac`: + * |[ + * GLIB_GSETTINGS + * ]| + * + * In the appropriate `Makefile.am`, use the following snippet to compile and + * install the named schema: + * |[ + * gsettings_SCHEMAS = org.foo.MyApp.gschema.xml + * EXTRA_DIST = $(gsettings_SCHEMAS) + * + * @GSETTINGS_RULES@ + * ]| + * + * No changes are needed to the build system to mark a schema XML file for + * translation. Assuming it sets the `gettext-domain` attribute, a schema may + * be marked for translation by adding it to `POTFILES.in`, assuming gettext + * 0.19 is in use (the preferred method for translation): + * |[ + * data/org.foo.MyApp.gschema.xml + * ]| + * + * Alternatively, if intltool 0.50.1 is in use: + * |[ + * [type: gettext/gsettings]data/org.foo.MyApp.gschema.xml + * ]| + * + * GSettings will use gettext to look up translations for the and + * elements, and also any elements which have a `l10n` + * attribute set. Translations must not be included in the `.gschema.xml` file + * by the build system, for example by using intltool XML rules with a + * `.gschema.xml.in` template. + * + * If an enumerated type defined in a C header file is to be used in a GSettings + * schema, it can either be defined manually using an element in the + * schema XML, or it can be extracted automatically from the C header. This + * approach is preferred, as it ensures the two representations are always + * synchronised. To do so, add the following to the relevant `Makefile.am`: + * |[ + * gsettings_ENUM_NAMESPACE = org.foo.MyApp + * gsettings_ENUM_FILES = my-app-enums.h my-app-misc.h + * ]| + * + * `gsettings_ENUM_NAMESPACE` specifies the schema namespace for the enum files, + * which are specified in `gsettings_ENUM_FILES`. This will generate a + * `org.foo.MyApp.enums.xml` file containing the extracted enums, which will be + * automatically included in the schema compilation, install and uninstall + * rules. It should not be committed to version control or included in + * `EXTRA_DIST`. + */ + +/** + * GSettings: + * + * #GSettings is an opaque data structure and can only be accessed + * using the following functions. + **/ + +struct _GSettingsPrivate +{ + /* where the signals go... */ + GMainContext *main_context; + + GSettingsBackend *backend; + GSettingsSchema *schema; + gchar *path; +}; + +enum +{ + PROP_0, + PROP_SCHEMA, + PROP_SCHEMA_ID, + PROP_BACKEND, + PROP_PATH, + PROP_HAS_UNAPPLIED, + PROP_DELAY_APPLY +}; + +enum +{ + SIGNAL_WRITABLE_CHANGE_EVENT, + SIGNAL_WRITABLE_CHANGED, + SIGNAL_CHANGE_EVENT, + SIGNAL_CHANGED, + N_SIGNALS +}; + +static guint g_settings_signals[N_SIGNALS]; + +G_DEFINE_TYPE_WITH_PRIVATE (GSettings, g_settings, G_TYPE_OBJECT) + +/* Signals {{{1 */ +static gboolean +g_settings_real_change_event (GSettings *settings, + const GQuark *keys, + gint n_keys) +{ + gint i; + + if (keys == NULL) + keys = g_settings_schema_list (settings->priv->schema, &n_keys); + + for (i = 0; i < n_keys; i++) + { + const gchar *key = g_quark_to_string (keys[i]); + + if (g_str_has_suffix (key, "/")) + continue; + + g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGED], keys[i], key); + } + + return FALSE; +} + +static gboolean +g_settings_real_writable_change_event (GSettings *settings, + GQuark key) +{ + const GQuark *keys = &key; + gint n_keys = 1; + gint i; + + if (key == 0) + keys = g_settings_schema_list (settings->priv->schema, &n_keys); + + for (i = 0; i < n_keys; i++) + { + const gchar *key_name = g_quark_to_string (keys[i]); + + if (g_str_has_suffix (key_name, "/")) + continue; + + g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], keys[i], key_name); + } + + return FALSE; +} + +static void +settings_backend_changed (GObject *target, + GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + GSettings *settings = G_SETTINGS (target); + gboolean ignore_this; + gint i; + + /* We used to assert here: + * + * settings->priv->backend == backend + * + * but it could be the case that a notification is queued for delivery + * while someone calls g_settings_delay() (which changes the backend). + * + * Since the delay backend would just pass that straight through + * anyway, it doesn't make sense to try to detect this case. + * Therefore, we just accept it. + */ + + for (i = 0; key[i] == settings->priv->path[i]; i++); + + if (settings->priv->path[i] == '\0' && + g_settings_schema_has_key (settings->priv->schema, key + i)) + { + GQuark quark; + + quark = g_quark_from_string (key + i); + g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT], + 0, &quark, 1, &ignore_this); + } +} + +static void +settings_backend_path_changed (GObject *target, + GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag) +{ + GSettings *settings = G_SETTINGS (target); + gboolean ignore_this; + + if (g_str_has_prefix (settings->priv->path, path)) + g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT], + 0, NULL, 0, &ignore_this); +} + +static void +settings_backend_keys_changed (GObject *target, + GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag, + const gchar * const *items) +{ + GSettings *settings = G_SETTINGS (target); + gboolean ignore_this; + gint i; + + for (i = 0; settings->priv->path[i] && + settings->priv->path[i] == path[i]; i++); + + if (path[i] == '\0') + { + GQuark quarks[256]; + gint j, l = 0; + + for (j = 0; items[j]; j++) + { + const gchar *item = items[j]; + gint k; + + for (k = 0; item[k] == settings->priv->path[i + k]; k++); + + if (settings->priv->path[i + k] == '\0' && + g_settings_schema_has_key (settings->priv->schema, item + k)) + quarks[l++] = g_quark_from_string (item + k); + + /* "256 quarks ought to be enough for anybody!" + * If this bites you, I'm sorry. Please file a bug. + */ + g_assert (l < 256); + } + + if (l > 0) + g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT], + 0, quarks, l, &ignore_this); + } +} + +static void +settings_backend_writable_changed (GObject *target, + GSettingsBackend *backend, + const gchar *key) +{ + GSettings *settings = G_SETTINGS (target); + gboolean ignore_this; + gint i; + + for (i = 0; key[i] == settings->priv->path[i]; i++); + + if (settings->priv->path[i] == '\0' && + g_settings_schema_has_key (settings->priv->schema, key + i)) + g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT], + 0, g_quark_from_string (key + i), &ignore_this); +} + +static void +settings_backend_path_writable_changed (GObject *target, + GSettingsBackend *backend, + const gchar *path) +{ + GSettings *settings = G_SETTINGS (target); + gboolean ignore_this; + + if (g_str_has_prefix (settings->priv->path, path)) + g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT], + 0, (GQuark) 0, &ignore_this); +} + +/* Properties, Construction, Destruction {{{1 */ +static void +g_settings_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSettings *settings = G_SETTINGS (object); + + switch (prop_id) + { + case PROP_SCHEMA: + { + GSettingsSchema *schema; + + schema = g_value_dup_boxed (value); + + /* we receive a set_property() call for "settings-schema" even + * if it was not specified (ie: with NULL value). ->schema + * could already be set at this point (ie: via "schema-id"). + * check for NULL to avoid clobbering the existing value. + */ + if (schema != NULL) + { + g_assert (settings->priv->schema == NULL); + settings->priv->schema = schema; + } + } + break; + + case PROP_SCHEMA_ID: + { + const gchar *schema_id; + + schema_id = g_value_get_string (value); + + /* we receive a set_property() call for both "schema" and + * "schema-id", even if they are not set. Hopefully only one of + * them is non-NULL. + */ + if (schema_id != NULL) + { + GSettingsSchemaSource *default_source; + + g_assert (settings->priv->schema == NULL); + default_source = g_settings_schema_source_get_default (); + + if (default_source == NULL) + g_error ("No GSettings schemas are installed on the system"); + + settings->priv->schema = g_settings_schema_source_lookup (default_source, schema_id, TRUE); + + if (settings->priv->schema == NULL) + g_error ("Settings schema '%s' is not installed", schema_id); + } + } + break; + + case PROP_PATH: + settings->priv->path = g_value_dup_string (value); + break; + + case PROP_BACKEND: + settings->priv->backend = g_value_dup_object (value); + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_settings_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSettings *settings = G_SETTINGS (object); + + switch (prop_id) + { + case PROP_SCHEMA: + g_value_set_boxed (value, settings->priv->schema); + break; + + case PROP_SCHEMA_ID: + g_value_set_string (value, g_settings_schema_get_id (settings->priv->schema)); + break; + + case PROP_BACKEND: + g_value_set_object (value, settings->priv->backend); + break; + + case PROP_PATH: + g_value_set_string (value, settings->priv->path); + break; + + case PROP_HAS_UNAPPLIED: + g_value_set_boolean (value, g_settings_get_has_unapplied (settings)); + break; + + case PROP_DELAY_APPLY: + g_value_set_boolean (value, G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend)); + break; + + default: + g_assert_not_reached (); + } +} + +static const GSettingsListenerVTable listener_vtable = { + settings_backend_changed, + settings_backend_path_changed, + settings_backend_keys_changed, + settings_backend_writable_changed, + settings_backend_path_writable_changed +}; + +static void +g_settings_constructed (GObject *object) +{ + GSettings *settings = G_SETTINGS (object); + const gchar *schema_path; + + schema_path = g_settings_schema_get_path (settings->priv->schema); + + if (settings->priv->path && schema_path && strcmp (settings->priv->path, schema_path) != 0) + g_error ("settings object created with schema '%s' and path '%s', but path '%s' is specified by schema", + g_settings_schema_get_id (settings->priv->schema), settings->priv->path, schema_path); + + if (settings->priv->path == NULL) + { + if (schema_path == NULL) + g_error ("attempting to create schema '%s' without a path", + g_settings_schema_get_id (settings->priv->schema)); + + settings->priv->path = g_strdup (schema_path); + } + + if (settings->priv->backend == NULL) + settings->priv->backend = g_settings_backend_get_default (); + + g_settings_backend_watch (settings->priv->backend, + &listener_vtable, G_OBJECT (settings), + settings->priv->main_context); + g_settings_backend_subscribe (settings->priv->backend, + settings->priv->path); +} + +static void +g_settings_finalize (GObject *object) +{ + GSettings *settings = G_SETTINGS (object); + + g_settings_backend_unsubscribe (settings->priv->backend, + settings->priv->path); + g_main_context_unref (settings->priv->main_context); + g_object_unref (settings->priv->backend); + g_settings_schema_unref (settings->priv->schema); + g_free (settings->priv->path); + + G_OBJECT_CLASS (g_settings_parent_class)->finalize (object); +} + +static void +g_settings_init (GSettings *settings) +{ + settings->priv = g_settings_get_instance_private (settings); + settings->priv->main_context = g_main_context_ref_thread_default (); +} + +static void +g_settings_class_init (GSettingsClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + class->writable_change_event = g_settings_real_writable_change_event; + class->change_event = g_settings_real_change_event; + + object_class->set_property = g_settings_set_property; + object_class->get_property = g_settings_get_property; + object_class->constructed = g_settings_constructed; + object_class->finalize = g_settings_finalize; + + /** + * GSettings::changed: + * @settings: the object on which the signal was emitted + * @key: the name of the key that changed + * + * The "changed" signal is emitted when a key has potentially changed. + * You should call one of the g_settings_get() calls to check the new + * value. + * + * This signal supports detailed connections. You can connect to the + * detailed signal "changed::x" in order to only receive callbacks + * when key "x" changes. + * + * Note that @settings only emits this signal if you have read @key at + * least once while a signal handler was already connected for @key. + */ + g_settings_signals[SIGNAL_CHANGED] = + g_signal_new (I_("changed"), G_TYPE_SETTINGS, + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_STRUCT_OFFSET (GSettingsClass, changed), + NULL, NULL, NULL, G_TYPE_NONE, + 1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); + + /** + * GSettings::change-event: + * @settings: the object on which the signal was emitted + * @keys: (array length=n_keys) (element-type GQuark) (nullable): + * an array of #GQuarks for the changed keys, or %NULL + * @n_keys: the length of the @keys array, or 0 + * + * The "change-event" signal is emitted once per change event that + * affects this settings object. You should connect to this signal + * only if you are interested in viewing groups of changes before they + * are split out into multiple emissions of the "changed" signal. + * For most use cases it is more appropriate to use the "changed" signal. + * + * In the event that the change event applies to one or more specified + * keys, @keys will be an array of #GQuark of length @n_keys. In the + * event that the change event applies to the #GSettings object as a + * whole (ie: potentially every key has been changed) then @keys will + * be %NULL and @n_keys will be 0. + * + * The default handler for this signal invokes the "changed" signal + * for each affected key. If any other connected handler returns + * %TRUE then this default functionality will be suppressed. + * + * Returns: %TRUE to stop other handlers from being invoked for the + * event. FALSE to propagate the event further. + */ + g_settings_signals[SIGNAL_CHANGE_EVENT] = + g_signal_new (I_("change-event"), G_TYPE_SETTINGS, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GSettingsClass, change_event), + g_signal_accumulator_true_handled, NULL, + _g_cclosure_marshal_BOOLEAN__POINTER_INT, + G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_INT); + g_signal_set_va_marshaller (g_settings_signals[SIGNAL_CHANGE_EVENT], + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_BOOLEAN__POINTER_INTv); + + /** + * GSettings::writable-changed: + * @settings: the object on which the signal was emitted + * @key: the key + * + * The "writable-changed" signal is emitted when the writability of a + * key has potentially changed. You should call + * g_settings_is_writable() in order to determine the new status. + * + * This signal supports detailed connections. You can connect to the + * detailed signal "writable-changed::x" in order to only receive + * callbacks when the writability of "x" changes. + */ + g_settings_signals[SIGNAL_WRITABLE_CHANGED] = + g_signal_new (I_("writable-changed"), G_TYPE_SETTINGS, + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_STRUCT_OFFSET (GSettingsClass, writable_changed), + NULL, NULL, NULL, G_TYPE_NONE, + 1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); + + /** + * GSettings::writable-change-event: + * @settings: the object on which the signal was emitted + * @key: the quark of the key, or 0 + * + * The "writable-change-event" signal is emitted once per writability + * change event that affects this settings object. You should connect + * to this signal if you are interested in viewing groups of changes + * before they are split out into multiple emissions of the + * "writable-changed" signal. For most use cases it is more + * appropriate to use the "writable-changed" signal. + * + * In the event that the writability change applies only to a single + * key, @key will be set to the #GQuark for that key. In the event + * that the writability change affects the entire settings object, + * @key will be 0. + * + * The default handler for this signal invokes the "writable-changed" + * and "changed" signals for each affected key. This is done because + * changes in writability might also imply changes in value (if for + * example, a new mandatory setting is introduced). If any other + * connected handler returns %TRUE then this default functionality + * will be suppressed. + * + * Returns: %TRUE to stop other handlers from being invoked for the + * event. FALSE to propagate the event further. + */ + g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT] = + g_signal_new (I_("writable-change-event"), G_TYPE_SETTINGS, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GSettingsClass, writable_change_event), + g_signal_accumulator_true_handled, NULL, + _g_cclosure_marshal_BOOLEAN__UINT, + G_TYPE_BOOLEAN, 1, G_TYPE_UINT); + g_signal_set_va_marshaller (g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT], + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_BOOLEAN__UINTv); + + /** + * GSettings:backend: + * + * The name of the context that the settings are stored in. + */ + g_object_class_install_property (object_class, PROP_BACKEND, + g_param_spec_object ("backend", + P_("GSettingsBackend"), + P_("The GSettingsBackend for this settings object"), + G_TYPE_SETTINGS_BACKEND, G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GSettings:settings-schema: + * + * The #GSettingsSchema describing the types of keys for this + * #GSettings object. + * + * Ideally, this property would be called 'schema'. #GSettingsSchema + * has only existed since version 2.32, however, and before then the + * 'schema' property was used to refer to the ID of the schema rather + * than the schema itself. Take care. + */ + g_object_class_install_property (object_class, PROP_SCHEMA, + g_param_spec_boxed ("settings-schema", + P_("schema"), + P_("The GSettingsSchema for this settings object"), + G_TYPE_SETTINGS_SCHEMA, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GSettings:schema: + * + * The name of the schema that describes the types of keys + * for this #GSettings object. + * + * The type of this property is *not* #GSettingsSchema. + * #GSettingsSchema has only existed since version 2.32 and + * unfortunately this name was used in previous versions to refer to + * the schema ID rather than the schema itself. Take care to use the + * 'settings-schema' property if you wish to pass in a + * #GSettingsSchema. + * + * Deprecated:2.32:Use the 'schema-id' property instead. In a future + * version, this property may instead refer to a #GSettingsSchema. + */ + g_object_class_install_property (object_class, PROP_SCHEMA_ID, + g_param_spec_string ("schema", + P_("Schema name"), + P_("The name of the schema for this settings object"), + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GSettings:schema-id: + * + * The name of the schema that describes the types of keys + * for this #GSettings object. + */ + g_object_class_install_property (object_class, PROP_SCHEMA_ID, + g_param_spec_string ("schema-id", + P_("Schema name"), + P_("The name of the schema for this settings object"), + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GSettings:path: + * + * The path within the backend where the settings are stored. + */ + g_object_class_install_property (object_class, PROP_PATH, + g_param_spec_string ("path", + P_("Base path"), + P_("The path within the backend where the settings are"), + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GSettings:has-unapplied: + * + * If this property is %TRUE, the #GSettings object has outstanding + * changes that will be applied when g_settings_apply() is called. + */ + g_object_class_install_property (object_class, PROP_HAS_UNAPPLIED, + g_param_spec_boolean ("has-unapplied", + P_("Has unapplied changes"), + P_("TRUE if there are outstanding changes to apply()"), + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + /** + * GSettings:delay-apply: + * + * Whether the #GSettings object is in 'delay-apply' mode. See + * g_settings_delay() for details. + * + * Since: 2.28 + */ + g_object_class_install_property (object_class, PROP_DELAY_APPLY, + g_param_spec_boolean ("delay-apply", + P_("Delay-apply mode"), + P_("Whether this settings object is in “delay-apply†mode"), + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); +} + +/* Construction (new, new_with_path, etc.) {{{1 */ +/** + * g_settings_new: + * @schema_id: the id of the schema + * + * Creates a new #GSettings object with the schema specified by + * @schema_id. + * + * It is an error for the schema to not exist: schemas are an + * essential part of a program, as they provide type information. + * If schemas need to be dynamically loaded (for example, from an + * optional runtime dependency), g_settings_schema_source_lookup() + * can be used to test for their existence before loading them. + * + * Signals on the newly created #GSettings object will be dispatched + * via the thread-default #GMainContext in effect at the time of the + * call to g_settings_new(). The new #GSettings will hold a reference + * on the context. See g_main_context_push_thread_default(). + * + * Returns: (not nullable) (transfer full): a new #GSettings object + * + * Since: 2.26 + */ +GSettings * +g_settings_new (const gchar *schema_id) +{ + g_return_val_if_fail (schema_id != NULL, NULL); + + return g_object_new (G_TYPE_SETTINGS, + "schema-id", schema_id, + NULL); +} + +static gboolean +path_is_valid (const gchar *path) +{ + if (!path) + return FALSE; + + if (path[0] != '/') + return FALSE; + + if (!g_str_has_suffix (path, "/")) + return FALSE; + + return strstr (path, "//") == NULL; +} + +/** + * g_settings_new_with_path: + * @schema_id: the id of the schema + * @path: the path to use + * + * Creates a new #GSettings object with the relocatable schema specified + * by @schema_id and a given path. + * + * You only need to do this if you want to directly create a settings + * object with a schema that doesn't have a specified path of its own. + * That's quite rare. + * + * It is a programmer error to call this function for a schema that + * has an explicitly specified path. + * + * It is a programmer error if @path is not a valid path. A valid path + * begins and ends with '/' and does not contain two consecutive '/' + * characters. + * + * Returns: (not nullable) (transfer full): a new #GSettings object + * + * Since: 2.26 + */ +GSettings * +g_settings_new_with_path (const gchar *schema_id, + const gchar *path) +{ + g_return_val_if_fail (schema_id != NULL, NULL); + g_return_val_if_fail (path_is_valid (path), NULL); + + return g_object_new (G_TYPE_SETTINGS, + "schema-id", schema_id, + "path", path, + NULL); +} + +/** + * g_settings_new_with_backend: + * @schema_id: the id of the schema + * @backend: the #GSettingsBackend to use + * + * Creates a new #GSettings object with the schema specified by + * @schema_id and a given #GSettingsBackend. + * + * Creating a #GSettings object with a different backend allows accessing + * settings from a database other than the usual one. For example, it may make + * sense to pass a backend corresponding to the "defaults" settings database on + * the system to get a settings object that modifies the system default + * settings instead of the settings for this user. + * + * Returns: (not nullable) (transfer full): a new #GSettings object + * + * Since: 2.26 + */ +GSettings * +g_settings_new_with_backend (const gchar *schema_id, + GSettingsBackend *backend) +{ + g_return_val_if_fail (schema_id != NULL, NULL); + g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL); + + return g_object_new (G_TYPE_SETTINGS, + "schema-id", schema_id, + "backend", backend, + NULL); +} + +/** + * g_settings_new_with_backend_and_path: + * @schema_id: the id of the schema + * @backend: the #GSettingsBackend to use + * @path: the path to use + * + * Creates a new #GSettings object with the schema specified by + * @schema_id and a given #GSettingsBackend and path. + * + * This is a mix of g_settings_new_with_backend() and + * g_settings_new_with_path(). + * + * Returns: (not nullable) (transfer full): a new #GSettings object + * + * Since: 2.26 + */ +GSettings * +g_settings_new_with_backend_and_path (const gchar *schema_id, + GSettingsBackend *backend, + const gchar *path) +{ + g_return_val_if_fail (schema_id != NULL, NULL); + g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL); + g_return_val_if_fail (path_is_valid (path), NULL); + + return g_object_new (G_TYPE_SETTINGS, + "schema-id", schema_id, + "backend", backend, + "path", path, + NULL); +} + +/** + * g_settings_new_full: + * @schema: a #GSettingsSchema + * @backend: (nullable): a #GSettingsBackend + * @path: (nullable): the path to use + * + * Creates a new #GSettings object with a given schema, backend and + * path. + * + * It should be extremely rare that you ever want to use this function. + * It is made available for advanced use-cases (such as plugin systems + * that want to provide access to schemas loaded from custom locations, + * etc). + * + * At the most basic level, a #GSettings object is a pure composition of + * 4 things: a #GSettingsSchema, a #GSettingsBackend, a path within that + * backend, and a #GMainContext to which signals are dispatched. + * + * This constructor therefore gives you full control over constructing + * #GSettings instances. The first 3 parameters are given directly as + * @schema, @backend and @path, and the main context is taken from the + * thread-default (as per g_settings_new()). + * + * If @backend is %NULL then the default backend is used. + * + * If @path is %NULL then the path from the schema is used. It is an + * error if @path is %NULL and the schema has no path of its own or if + * @path is non-%NULL and not equal to the path that the schema does + * have. + * + * Returns: (not nullable) (transfer full): a new #GSettings object + * + * Since: 2.32 + */ +GSettings * +g_settings_new_full (GSettingsSchema *schema, + GSettingsBackend *backend, + const gchar *path) +{ + g_return_val_if_fail (schema != NULL, NULL); + g_return_val_if_fail (backend == NULL || G_IS_SETTINGS_BACKEND (backend), NULL); + g_return_val_if_fail (path == NULL || path_is_valid (path), NULL); + + return g_object_new (G_TYPE_SETTINGS, + "settings-schema", schema, + "backend", backend, + "path", path, + NULL); +} + +/* Internal read/write utilities {{{1 */ + +/* @value will be sunk */ +static gboolean +g_settings_write_to_backend (GSettings *settings, + GSettingsSchemaKey *key, + GVariant *value) +{ + gboolean success; + gchar *path; + + path = g_strconcat (settings->priv->path, key->name, NULL); + success = g_settings_backend_write (settings->priv->backend, path, value, NULL); + g_free (path); + + return success; +} + +static GVariant * +g_settings_read_from_backend (GSettings *settings, + GSettingsSchemaKey *key, + gboolean user_value_only, + gboolean default_value) +{ + GVariant *value; + GVariant *fixup; + gchar *path; + + path = g_strconcat (settings->priv->path, key->name, NULL); + if (user_value_only) + value = g_settings_backend_read_user_value (settings->priv->backend, path, key->type); + else + value = g_settings_backend_read (settings->priv->backend, path, key->type, default_value); + g_free (path); + + if (value != NULL) + { + fixup = g_settings_schema_key_range_fixup (key, value); + g_variant_unref (value); + } + else + fixup = NULL; + + return fixup; +} + +/* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */ +/** + * g_settings_get_value: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored in @settings for @key. + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings. + * + * Returns: (not nullable) (transfer full): a new #GVariant + * + * Since: 2.26 + */ +GVariant * +g_settings_get_value (GSettings *settings, + const gchar *key) +{ + GSettingsSchemaKey skey; + GVariant *value; + + g_return_val_if_fail (G_IS_SETTINGS (settings), NULL); + g_return_val_if_fail (key != NULL, NULL); + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE); + + if (value == NULL) + value = g_settings_schema_key_get_default_value (&skey); + + g_settings_schema_key_clear (&skey); + + return value; +} + +/** + * g_settings_get_user_value: + * @settings: a #GSettings object + * @key: the key to get the user value for + * + * Checks the "user value" of a key, if there is one. + * + * The user value of a key is the last value that was set by the user. + * + * After calling g_settings_reset() this function should always return + * %NULL (assuming something is not wrong with the system + * configuration). + * + * It is possible that g_settings_get_value() will return a different + * value than this function. This can happen in the case that the user + * set a value for a key that was subsequently locked down by the system + * administrator -- this function will return the user's old value. + * + * This function may be useful for adding a "reset" option to a UI or + * for providing indication that a particular value has been changed. + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings. + * + * Returns: (nullable) (transfer full): the user's value, if set + * + * Since: 2.40 + **/ +GVariant * +g_settings_get_user_value (GSettings *settings, + const gchar *key) +{ + GSettingsSchemaKey skey; + GVariant *value; + + g_return_val_if_fail (G_IS_SETTINGS (settings), NULL); + g_return_val_if_fail (key != NULL, NULL); + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + value = g_settings_read_from_backend (settings, &skey, TRUE, FALSE); + g_settings_schema_key_clear (&skey); + + return value; +} + +/** + * g_settings_get_default_value: + * @settings: a #GSettings object + * @key: the key to get the default value for + * + * Gets the "default value" of a key. + * + * This is the value that would be read if g_settings_reset() were to be + * called on the key. + * + * Note that this may be a different value than returned by + * g_settings_schema_key_get_default_value() if the system administrator + * has provided a default value. + * + * Comparing the return values of g_settings_get_default_value() and + * g_settings_get_value() is not sufficient for determining if a value + * has been set because the user may have explicitly set the value to + * something that happens to be equal to the default. The difference + * here is that if the default changes in the future, the user's key + * will still be set. + * + * This function may be useful for adding an indication to a UI of what + * the default value was before the user set it. + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings. + * + * Returns: (nullable) (transfer full): the default value + * + * Since: 2.40 + **/ +GVariant * +g_settings_get_default_value (GSettings *settings, + const gchar *key) +{ + GSettingsSchemaKey skey; + GVariant *value; + + g_return_val_if_fail (G_IS_SETTINGS (settings), NULL); + g_return_val_if_fail (key != NULL, NULL); + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + value = g_settings_read_from_backend (settings, &skey, FALSE, TRUE); + + if (value == NULL) + value = g_settings_schema_key_get_default_value (&skey); + + g_settings_schema_key_clear (&skey); + + return value; +} + +/** + * g_settings_get_enum: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored in @settings for @key and converts it + * to the enum value that it represents. + * + * In order to use this function the type of the value must be a string + * and it must be marked in the schema file as an enumerated type. + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings or is not marked as an enumerated type. + * + * If the value stored in the configuration database is not a valid + * value for the enumerated type then this function will return the + * default value. + * + * Returns: the enum value + * + * Since: 2.26 + **/ +gint +g_settings_get_enum (GSettings *settings, + const gchar *key) +{ + GSettingsSchemaKey skey; + GVariant *value; + gint result; + + g_return_val_if_fail (G_IS_SETTINGS (settings), -1); + g_return_val_if_fail (key != NULL, -1); + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + + if (!skey.is_enum) + { + g_critical ("g_settings_get_enum() called on key '%s' which is not " + "associated with an enumerated type", skey.name); + g_settings_schema_key_clear (&skey); + return -1; + } + + value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE); + + if (value == NULL) + value = g_settings_schema_key_get_default_value (&skey); + + result = g_settings_schema_key_to_enum (&skey, value); + g_settings_schema_key_clear (&skey); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_enum: + * @settings: a #GSettings object + * @key: a key, within @settings + * @value: an enumerated value + * + * Looks up the enumerated type nick for @value and writes it to @key, + * within @settings. + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings or is not marked as an enumerated type, or for + * @value not to be a valid value for the named type. + * + * After performing the write, accessing @key directly with + * g_settings_get_string() will return the 'nick' associated with + * @value. + * + * Returns: %TRUE, if the set succeeds + **/ +gboolean +g_settings_set_enum (GSettings *settings, + const gchar *key, + gint value) +{ + GSettingsSchemaKey skey; + GVariant *variant; + gboolean success; + + g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + + if (!skey.is_enum) + { + g_critical ("g_settings_set_enum() called on key '%s' which is not " + "associated with an enumerated type", skey.name); + return FALSE; + } + + if (!(variant = g_settings_schema_key_from_enum (&skey, value))) + { + g_critical ("g_settings_set_enum(): invalid enum value %d for key '%s' " + "in schema '%s'. Doing nothing.", value, skey.name, + g_settings_schema_get_id (skey.schema)); + g_settings_schema_key_clear (&skey); + return FALSE; + } + + success = g_settings_write_to_backend (settings, &skey, g_steal_pointer (&variant)); + g_settings_schema_key_clear (&skey); + + return success; +} + +/** + * g_settings_get_flags: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored in @settings for @key and converts it + * to the flags value that it represents. + * + * In order to use this function the type of the value must be an array + * of strings and it must be marked in the schema file as a flags type. + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings or is not marked as a flags type. + * + * If the value stored in the configuration database is not a valid + * value for the flags type then this function will return the default + * value. + * + * Returns: the flags value + * + * Since: 2.26 + **/ +guint +g_settings_get_flags (GSettings *settings, + const gchar *key) +{ + GSettingsSchemaKey skey; + GVariant *value; + guint result; + + g_return_val_if_fail (G_IS_SETTINGS (settings), -1); + g_return_val_if_fail (key != NULL, -1); + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + + if (!skey.is_flags) + { + g_critical ("g_settings_get_flags() called on key '%s' which is not " + "associated with a flags type", skey.name); + g_settings_schema_key_clear (&skey); + return -1; + } + + value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE); + + if (value == NULL) + value = g_settings_schema_key_get_default_value (&skey); + + result = g_settings_schema_key_to_flags (&skey, value); + g_settings_schema_key_clear (&skey); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_flags: + * @settings: a #GSettings object + * @key: a key, within @settings + * @value: a flags value + * + * Looks up the flags type nicks for the bits specified by @value, puts + * them in an array of strings and writes the array to @key, within + * @settings. + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings or is not marked as a flags type, or for @value + * to contain any bits that are not value for the named type. + * + * After performing the write, accessing @key directly with + * g_settings_get_strv() will return an array of 'nicks'; one for each + * bit in @value. + * + * Returns: %TRUE, if the set succeeds + **/ +gboolean +g_settings_set_flags (GSettings *settings, + const gchar *key, + guint value) +{ + GSettingsSchemaKey skey; + GVariant *variant; + gboolean success; + + g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + + if (!skey.is_flags) + { + g_critical ("g_settings_set_flags() called on key '%s' which is not " + "associated with a flags type", skey.name); + return FALSE; + } + + if (!(variant = g_settings_schema_key_from_flags (&skey, value))) + { + g_critical ("g_settings_set_flags(): invalid flags value 0x%08x " + "for key '%s' in schema '%s'. Doing nothing.", + value, skey.name, g_settings_schema_get_id (skey.schema)); + g_settings_schema_key_clear (&skey); + return FALSE; + } + + success = g_settings_write_to_backend (settings, &skey, g_steal_pointer (&variant)); + g_settings_schema_key_clear (&skey); + + return success; +} + +/** + * g_settings_set_value: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: a #GVariant of the correct type + * + * Sets @key in @settings to @value. + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings or for @value to have the incorrect type, per + * the schema. + * + * If @value is floating then this function consumes the reference. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.26 + **/ +gboolean +g_settings_set_value (GSettings *settings, + const gchar *key, + GVariant *value) +{ + GSettingsSchemaKey skey; + gboolean success; + + g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + g_variant_ref_sink (value); + g_settings_schema_key_init (&skey, settings->priv->schema, key); + + if (!g_settings_schema_key_type_check (&skey, value)) + { + g_critical ("g_settings_set_value: key '%s' in '%s' expects type '%s', but a GVariant of type '%s' was given", + key, + g_settings_schema_get_id (settings->priv->schema), + g_variant_type_peek_string (skey.type), + g_variant_get_type_string (value)); + success = FALSE; + } + else if (!g_settings_schema_key_range_check (&skey, value)) + { + g_warning ("g_settings_set_value: value for key '%s' in schema '%s' " + "is outside of valid range", + key, + g_settings_schema_get_id (settings->priv->schema)); + success = FALSE; + } + else + { + success = g_settings_write_to_backend (settings, &skey, value); + } + + g_settings_schema_key_clear (&skey); + g_variant_unref (value); + + return success; +} + +/** + * g_settings_get: + * @settings: a #GSettings object + * @key: the key to get the value for + * @format: a #GVariant format string + * @...: arguments as per @format + * + * Gets the value that is stored at @key in @settings. + * + * A convenience function that combines g_settings_get_value() with + * g_variant_get(). + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings or for the #GVariantType of @format to mismatch + * the type given in the schema. + * + * Since: 2.26 + */ +void +g_settings_get (GSettings *settings, + const gchar *key, + const gchar *format, + ...) +{ + GVariant *value; + va_list ap; + + value = g_settings_get_value (settings, key); + + if (strchr (format, '&')) + { + g_critical ("%s: the format string may not contain '&' (key '%s' from schema '%s'). " + "This call will probably stop working with a future version of glib.", + G_STRFUNC, key, g_settings_schema_get_id (settings->priv->schema)); + } + + va_start (ap, format); + g_variant_get_va (value, format, NULL, &ap); + va_end (ap); + + g_variant_unref (value); +} + +/** + * g_settings_set: + * @settings: a #GSettings object + * @key: the name of the key to set + * @format: a #GVariant format string + * @...: arguments as per @format + * + * Sets @key in @settings to @value. + * + * A convenience function that combines g_settings_set_value() with + * g_variant_new(). + * + * It is a programmer error to give a @key that isn't contained in the + * schema for @settings or for the #GVariantType of @format to mismatch + * the type given in the schema. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.26 + */ +gboolean +g_settings_set (GSettings *settings, + const gchar *key, + const gchar *format, + ...) +{ + GVariant *value; + va_list ap; + + va_start (ap, format); + value = g_variant_new_va (format, NULL, &ap); + va_end (ap); + + return g_settings_set_value (settings, key, g_steal_pointer (&value)); +} + +/** + * g_settings_get_mapped: + * @settings: a #GSettings object + * @key: the key to get the value for + * @mapping: (scope call): the function to map the value in the + * settings database to the value used by the application + * @user_data: user data for @mapping + * + * Gets the value that is stored at @key in @settings, subject to + * application-level validation/mapping. + * + * You should use this function when the application needs to perform + * some processing on the value of the key (for example, parsing). The + * @mapping function performs that processing. If the function + * indicates that the processing was unsuccessful (due to a parse error, + * for example) then the mapping is tried again with another value. + * + * This allows a robust 'fall back to defaults' behaviour to be + * implemented somewhat automatically. + * + * The first value that is tried is the user's setting for the key. If + * the mapping function fails to map this value, other values may be + * tried in an unspecified order (system or site defaults, translated + * schema default values, untranslated schema default values, etc). + * + * If the mapping function fails for all possible values, one additional + * attempt is made: the mapping function is called with a %NULL value. + * If the mapping function still indicates failure at this point then + * the application will be aborted. + * + * The result parameter for the @mapping function is pointed to a + * #gpointer which is initially set to %NULL. The same pointer is given + * to each invocation of @mapping. The final value of that #gpointer is + * what is returned by this function. %NULL is valid; it is returned + * just as any other value would be. + * + * Returns: (nullable) (transfer full): the result, which may be %NULL + **/ +gpointer +g_settings_get_mapped (GSettings *settings, + const gchar *key, + GSettingsGetMapping mapping, + gpointer user_data) +{ + gpointer result = NULL; + GSettingsSchemaKey skey; + GVariant *value; + gboolean okay; + + g_return_val_if_fail (G_IS_SETTINGS (settings), NULL); + g_return_val_if_fail (key != NULL, NULL); + g_return_val_if_fail (mapping != NULL, NULL); + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + + if ((value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE))) + { + okay = mapping (value, &result, user_data); + g_variant_unref (value); + if (okay) goto okay; + } + + if ((value = g_settings_schema_key_get_translated_default (&skey))) + { + okay = mapping (value, &result, user_data); + g_variant_unref (value); + if (okay) goto okay; + } + + if ((value = g_settings_schema_key_get_per_desktop_default (&skey))) + { + okay = mapping (value, &result, user_data); + g_variant_unref (value); + if (okay) goto okay; + } + + if (mapping (skey.default_value, &result, user_data)) + goto okay; + + if (!mapping (NULL, &result, user_data)) + g_error ("The mapping function given to g_settings_get_mapped() for key " + "'%s' in schema '%s' returned FALSE when given a NULL value.", + key, g_settings_schema_get_id (settings->priv->schema)); + + okay: + g_settings_schema_key_clear (&skey); + + return result; +} + +/* Convenience API (get, set_string, int, double, boolean, strv) {{{1 */ +/** + * g_settings_get_string: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored at @key in @settings. + * + * A convenience variant of g_settings_get() for strings. + * + * It is a programmer error to give a @key that isn't specified as + * having a string type in the schema for @settings. + * + * Returns: (not nullable) (transfer full): a newly-allocated string + * + * Since: 2.26 + */ +gchar * +g_settings_get_string (GSettings *settings, + const gchar *key) +{ + GVariant *value; + gchar *result; + + value = g_settings_get_value (settings, key); + result = g_variant_dup_string (value, NULL); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_string: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: the value to set it to + * + * Sets @key in @settings to @value. + * + * A convenience variant of g_settings_set() for strings. + * + * It is a programmer error to give a @key that isn't specified as + * having a string type in the schema for @settings. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.26 + */ +gboolean +g_settings_set_string (GSettings *settings, + const gchar *key, + const gchar *value) +{ + return g_settings_set_value (settings, key, g_variant_new_string (value)); +} + +/** + * g_settings_get_int: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored at @key in @settings. + * + * A convenience variant of g_settings_get() for 32-bit integers. + * + * It is a programmer error to give a @key that isn't specified as + * having a int32 type in the schema for @settings. + * + * Returns: an integer + * + * Since: 2.26 + */ +gint +g_settings_get_int (GSettings *settings, + const gchar *key) +{ + GVariant *value; + gint result; + + value = g_settings_get_value (settings, key); + result = g_variant_get_int32 (value); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_int: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: the value to set it to + * + * Sets @key in @settings to @value. + * + * A convenience variant of g_settings_set() for 32-bit integers. + * + * It is a programmer error to give a @key that isn't specified as + * having a int32 type in the schema for @settings. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.26 + */ +gboolean +g_settings_set_int (GSettings *settings, + const gchar *key, + gint value) +{ + return g_settings_set_value (settings, key, g_variant_new_int32 (value)); +} + +/** + * g_settings_get_int64: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored at @key in @settings. + * + * A convenience variant of g_settings_get() for 64-bit integers. + * + * It is a programmer error to give a @key that isn't specified as + * having a int64 type in the schema for @settings. + * + * Returns: a 64-bit integer + * + * Since: 2.50 + */ +gint64 +g_settings_get_int64 (GSettings *settings, + const gchar *key) +{ + GVariant *value; + gint64 result; + + value = g_settings_get_value (settings, key); + result = g_variant_get_int64 (value); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_int64: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: the value to set it to + * + * Sets @key in @settings to @value. + * + * A convenience variant of g_settings_set() for 64-bit integers. + * + * It is a programmer error to give a @key that isn't specified as + * having a int64 type in the schema for @settings. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.50 + */ +gboolean +g_settings_set_int64 (GSettings *settings, + const gchar *key, + gint64 value) +{ + return g_settings_set_value (settings, key, g_variant_new_int64 (value)); +} + +/** + * g_settings_get_uint: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored at @key in @settings. + * + * A convenience variant of g_settings_get() for 32-bit unsigned + * integers. + * + * It is a programmer error to give a @key that isn't specified as + * having a uint32 type in the schema for @settings. + * + * Returns: an unsigned integer + * + * Since: 2.30 + */ +guint +g_settings_get_uint (GSettings *settings, + const gchar *key) +{ + GVariant *value; + guint result; + + value = g_settings_get_value (settings, key); + result = g_variant_get_uint32 (value); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_uint: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: the value to set it to + * + * Sets @key in @settings to @value. + * + * A convenience variant of g_settings_set() for 32-bit unsigned + * integers. + * + * It is a programmer error to give a @key that isn't specified as + * having a uint32 type in the schema for @settings. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.30 + */ +gboolean +g_settings_set_uint (GSettings *settings, + const gchar *key, + guint value) +{ + return g_settings_set_value (settings, key, g_variant_new_uint32 (value)); +} + +/** + * g_settings_get_uint64: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored at @key in @settings. + * + * A convenience variant of g_settings_get() for 64-bit unsigned + * integers. + * + * It is a programmer error to give a @key that isn't specified as + * having a uint64 type in the schema for @settings. + * + * Returns: a 64-bit unsigned integer + * + * Since: 2.50 + */ +guint64 +g_settings_get_uint64 (GSettings *settings, + const gchar *key) +{ + GVariant *value; + guint64 result; + + value = g_settings_get_value (settings, key); + result = g_variant_get_uint64 (value); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_uint64: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: the value to set it to + * + * Sets @key in @settings to @value. + * + * A convenience variant of g_settings_set() for 64-bit unsigned + * integers. + * + * It is a programmer error to give a @key that isn't specified as + * having a uint64 type in the schema for @settings. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.50 + */ +gboolean +g_settings_set_uint64 (GSettings *settings, + const gchar *key, + guint64 value) +{ + return g_settings_set_value (settings, key, g_variant_new_uint64 (value)); +} + +/** + * g_settings_get_double: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored at @key in @settings. + * + * A convenience variant of g_settings_get() for doubles. + * + * It is a programmer error to give a @key that isn't specified as + * having a 'double' type in the schema for @settings. + * + * Returns: a double + * + * Since: 2.26 + */ +gdouble +g_settings_get_double (GSettings *settings, + const gchar *key) +{ + GVariant *value; + gdouble result; + + value = g_settings_get_value (settings, key); + result = g_variant_get_double (value); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_double: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: the value to set it to + * + * Sets @key in @settings to @value. + * + * A convenience variant of g_settings_set() for doubles. + * + * It is a programmer error to give a @key that isn't specified as + * having a 'double' type in the schema for @settings. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.26 + */ +gboolean +g_settings_set_double (GSettings *settings, + const gchar *key, + gdouble value) +{ + return g_settings_set_value (settings, key, g_variant_new_double (value)); +} + +/** + * g_settings_get_boolean: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * Gets the value that is stored at @key in @settings. + * + * A convenience variant of g_settings_get() for booleans. + * + * It is a programmer error to give a @key that isn't specified as + * having a boolean type in the schema for @settings. + * + * Returns: a boolean + * + * Since: 2.26 + */ +gboolean +g_settings_get_boolean (GSettings *settings, + const gchar *key) +{ + GVariant *value; + gboolean result; + + value = g_settings_get_value (settings, key); + result = g_variant_get_boolean (value); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_boolean: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: the value to set it to + * + * Sets @key in @settings to @value. + * + * A convenience variant of g_settings_set() for booleans. + * + * It is a programmer error to give a @key that isn't specified as + * having a boolean type in the schema for @settings. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.26 + */ +gboolean +g_settings_set_boolean (GSettings *settings, + const gchar *key, + gboolean value) +{ + return g_settings_set_value (settings, key, g_variant_new_boolean (value)); +} + +/** + * g_settings_get_strv: + * @settings: a #GSettings object + * @key: the key to get the value for + * + * A convenience variant of g_settings_get() for string arrays. + * + * It is a programmer error to give a @key that isn't specified as + * having an array of strings type in the schema for @settings. + * + * Returns: (array zero-terminated=1) (not nullable) (transfer full): a + * newly-allocated, %NULL-terminated array of strings, the value that + * is stored at @key in @settings. + * + * Since: 2.26 + */ +gchar ** +g_settings_get_strv (GSettings *settings, + const gchar *key) +{ + GVariant *value; + gchar **result; + + value = g_settings_get_value (settings, key); + result = g_variant_dup_strv (value, NULL); + g_variant_unref (value); + + return result; +} + +/** + * g_settings_set_strv: + * @settings: a #GSettings object + * @key: the name of the key to set + * @value: (nullable) (array zero-terminated=1): the value to set it to, or %NULL + * + * Sets @key in @settings to @value. + * + * A convenience variant of g_settings_set() for string arrays. If + * @value is %NULL, then @key is set to be the empty array. + * + * It is a programmer error to give a @key that isn't specified as + * having an array of strings type in the schema for @settings. + * + * Returns: %TRUE if setting the key succeeded, + * %FALSE if the key was not writable + * + * Since: 2.26 + */ +gboolean +g_settings_set_strv (GSettings *settings, + const gchar *key, + const gchar * const *value) +{ + GVariant *array; + + if (value != NULL) + array = g_variant_new_strv (value, -1); + else + array = g_variant_new_strv (NULL, 0); + + return g_settings_set_value (settings, key, array); +} + +/* Delayed apply (delay, apply, revert, get_has_unapplied) {{{1 */ +/** + * g_settings_delay: + * @settings: a #GSettings object + * + * Changes the #GSettings object into 'delay-apply' mode. In this + * mode, changes to @settings are not immediately propagated to the + * backend, but kept locally until g_settings_apply() is called. + * + * Since: 2.26 + */ +void +g_settings_delay (GSettings *settings) +{ + GDelayedSettingsBackend *delayed = NULL; + + g_return_if_fail (G_IS_SETTINGS (settings)); + + if (G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend)) + return; + + delayed = g_delayed_settings_backend_new (settings->priv->backend, + settings, + settings->priv->main_context); + g_settings_backend_unwatch (settings->priv->backend, G_OBJECT (settings)); + g_object_unref (settings->priv->backend); + + settings->priv->backend = G_SETTINGS_BACKEND (delayed); + g_settings_backend_watch (settings->priv->backend, + &listener_vtable, G_OBJECT (settings), + settings->priv->main_context); + + g_object_notify (G_OBJECT (settings), "delay-apply"); +} + +/** + * g_settings_apply: + * @settings: a #GSettings instance + * + * Applies any changes that have been made to the settings. This + * function does nothing unless @settings is in 'delay-apply' mode; + * see g_settings_delay(). In the normal case settings are always + * applied immediately. + **/ +void +g_settings_apply (GSettings *settings) +{ + if (G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend)) + { + GDelayedSettingsBackend *delayed; + + delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend); + g_delayed_settings_backend_apply (delayed); + } +} + +/** + * g_settings_revert: + * @settings: a #GSettings instance + * + * Reverts all non-applied changes to the settings. This function + * does nothing unless @settings is in 'delay-apply' mode; see + * g_settings_delay(). In the normal case settings are always applied + * immediately. + * + * Change notifications will be emitted for affected keys. + **/ +void +g_settings_revert (GSettings *settings) +{ + if (G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend)) + { + GDelayedSettingsBackend *delayed; + + delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend); + g_delayed_settings_backend_revert (delayed); + } +} + +/** + * g_settings_get_has_unapplied: + * @settings: a #GSettings object + * + * Returns whether the #GSettings object has any unapplied + * changes. This can only be the case if it is in 'delayed-apply' mode. + * + * Returns: %TRUE if @settings has unapplied changes + * + * Since: 2.26 + */ +gboolean +g_settings_get_has_unapplied (GSettings *settings) +{ + g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE); + + return G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend) && + g_delayed_settings_backend_get_has_unapplied ( + G_DELAYED_SETTINGS_BACKEND (settings->priv->backend)); +} + +/* Extra API (reset, sync, get_child, is_writable, list_*, ranges) {{{1 */ +/** + * g_settings_reset: + * @settings: a #GSettings object + * @key: the name of a key + * + * Resets @key to its default value. + * + * This call resets the key, as much as possible, to its default value. + * That might be the value specified in the schema or the one set by the + * administrator. + **/ +void +g_settings_reset (GSettings *settings, + const gchar *key) +{ + gchar *path; + + g_return_if_fail (G_IS_SETTINGS (settings)); + g_return_if_fail (key != NULL); + + path = g_strconcat (settings->priv->path, key, NULL); + g_settings_backend_reset (settings->priv->backend, path, NULL); + g_free (path); +} + +/** + * g_settings_sync: + * + * Ensures that all pending operations are complete for the default backend. + * + * Writes made to a #GSettings are handled asynchronously. For this + * reason, it is very unlikely that the changes have it to disk by the + * time g_settings_set() returns. + * + * This call will block until all of the writes have made it to the + * backend. Since the mainloop is not running, no change notifications + * will be dispatched during this call (but some may be queued by the + * time the call is done). + **/ +void +g_settings_sync (void) +{ + g_settings_backend_sync_default (); +} + +/** + * g_settings_is_writable: + * @settings: a #GSettings object + * @name: the name of a key + * + * Finds out if a key can be written or not + * + * Returns: %TRUE if the key @name is writable + * + * Since: 2.26 + */ +gboolean +g_settings_is_writable (GSettings *settings, + const gchar *name) +{ + gboolean writable; + gchar *path; + + g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE); + + path = g_strconcat (settings->priv->path, name, NULL); + writable = g_settings_backend_get_writable (settings->priv->backend, path); + g_free (path); + + return writable; +} + +/** + * g_settings_get_child: + * @settings: a #GSettings object + * @name: the name of the child schema + * + * Creates a child settings object which has a base path of + * `base-path/@name`, where `base-path` is the base path of + * @settings. + * + * The schema for the child settings object must have been declared + * in the schema of @settings using a `` element. + * + * The created child settings object will inherit the #GSettings:delay-apply + * mode from @settings. + * + * Returns: (not nullable) (transfer full): a 'child' settings object + * + * Since: 2.26 + */ +GSettings * +g_settings_get_child (GSettings *settings, + const gchar *name) +{ + GSettingsSchema *child_schema; + gchar *child_path; + GSettings *child; + + g_return_val_if_fail (G_IS_SETTINGS (settings), NULL); + + child_schema = g_settings_schema_get_child_schema (settings->priv->schema, + name); + if (child_schema == NULL) + g_error ("Schema '%s' has no child '%s' or child schema not found", + g_settings_schema_get_id (settings->priv->schema), name); + + child_path = g_strconcat (settings->priv->path, name, "/", NULL); + child = g_settings_new_full (child_schema, + settings->priv->backend, + child_path); + g_settings_schema_unref (child_schema); + g_free (child_path); + + return child; +} + +/** + * g_settings_list_keys: + * @settings: a #GSettings object + * + * Introspects the list of keys on @settings. + * + * You should probably not be calling this function from "normal" code + * (since you should already know what keys are in your schema). This + * function is intended for introspection reasons. + * + * You should free the return value with g_strfreev() when you are done + * with it. + * + * Returns: (not nullable) (transfer full) (element-type utf8): a list + * of the keys on @settings, in no defined order + * Deprecated: 2.46: Use g_settings_schema_list_keys() instead. + */ +gchar ** +g_settings_list_keys (GSettings *settings) +{ + return g_settings_schema_list_keys (settings->priv->schema); +} + +/** + * g_settings_list_children: + * @settings: a #GSettings object + * + * Gets the list of children on @settings. + * + * The list is exactly the list of strings for which it is not an error + * to call g_settings_get_child(). + * + * There is little reason to call this function from "normal" code, since + * you should already know what children are in your schema. This function + * may still be useful there for introspection reasons, however. + * + * You should free the return value with g_strfreev() when you are done + * with it. + * + * Returns: (not nullable) (transfer full) (element-type utf8): a list of the children + * on @settings, in no defined order + */ +gchar ** +g_settings_list_children (GSettings *settings) +{ + return g_settings_schema_list_children (settings->priv->schema); +} + +/** + * g_settings_get_range: + * @settings: a #GSettings + * @key: the key to query the range of + * + * Queries the range of a key. + * + * Since: 2.28 + * + * Deprecated:2.40:Use g_settings_schema_key_get_range() instead. + **/ +GVariant * +g_settings_get_range (GSettings *settings, + const gchar *key) +{ + GSettingsSchemaKey skey; + GVariant *range; + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + range = g_settings_schema_key_get_range (&skey); + g_settings_schema_key_clear (&skey); + + return range; +} + +/** + * g_settings_range_check: + * @settings: a #GSettings + * @key: the key to check + * @value: the value to check + * + * Checks if the given @value is of the correct type and within the + * permitted range for @key. + * + * Returns: %TRUE if @value is valid for @key + * + * Since: 2.28 + * + * Deprecated:2.40:Use g_settings_schema_key_range_check() instead. + **/ +gboolean +g_settings_range_check (GSettings *settings, + const gchar *key, + GVariant *value) +{ + GSettingsSchemaKey skey; + gboolean good; + + g_settings_schema_key_init (&skey, settings->priv->schema, key); + good = g_settings_schema_key_range_check (&skey, value); + g_settings_schema_key_clear (&skey); + + return good; +} + +/* Binding {{{1 */ +typedef struct +{ + GSettingsSchemaKey key; + GSettings *settings; + GObject *object; + + GSettingsBindGetMapping get_mapping; + GSettingsBindSetMapping set_mapping; + gpointer user_data; + GDestroyNotify destroy; + + guint writable_handler_id; + guint property_handler_id; + const GParamSpec *property; + guint key_handler_id; + + /* prevent recursion */ + gboolean running; +} GSettingsBinding; + +static void +g_settings_binding_free (gpointer data) +{ + GSettingsBinding *binding = data; + + g_assert (!binding->running); + + if (binding->writable_handler_id) + g_signal_handler_disconnect (binding->settings, + binding->writable_handler_id); + + if (binding->key_handler_id) + g_signal_handler_disconnect (binding->settings, + binding->key_handler_id); + + if (g_signal_handler_is_connected (binding->object, + binding->property_handler_id)) + g_signal_handler_disconnect (binding->object, + binding->property_handler_id); + + g_settings_schema_key_clear (&binding->key); + + if (binding->destroy) + binding->destroy (binding->user_data); + + g_object_unref (binding->settings); + + g_slice_free (GSettingsBinding, binding); +} + +static GQuark +g_settings_binding_quark (const char *property) +{ + GQuark quark; + gchar *tmp; + + tmp = g_strdup_printf ("gsettingsbinding-%s", property); + quark = g_quark_from_string (tmp); + g_free (tmp); + + return quark; +} + +static void +g_settings_binding_key_changed (GSettings *settings, + const gchar *key, + gpointer user_data) +{ + GSettingsBinding *binding = user_data; + GValue value = G_VALUE_INIT; + GVariant *variant; + + g_assert (settings == binding->settings); + g_assert (key == binding->key.name); + + if (binding->running) + return; + + binding->running = TRUE; + + g_value_init (&value, binding->property->value_type); + + variant = g_settings_read_from_backend (binding->settings, &binding->key, FALSE, FALSE); + if (variant && !binding->get_mapping (&value, variant, binding->user_data)) + { + /* silently ignore errors in the user's config database */ + g_variant_unref (variant); + variant = NULL; + } + + if (variant == NULL) + { + variant = g_settings_schema_key_get_translated_default (&binding->key); + if (variant && + !binding->get_mapping (&value, variant, binding->user_data)) + { + /* flag translation errors with a warning */ + g_warning ("Translated default '%s' for key '%s' in schema '%s' " + "was rejected by the binding mapping function", + binding->key.unparsed, binding->key.name, + g_settings_schema_get_id (binding->key.schema)); + g_variant_unref (variant); + variant = NULL; + } + } + + if (variant == NULL) + { + variant = g_settings_schema_key_get_per_desktop_default (&binding->key); + if (variant && + !binding->get_mapping (&value, variant, binding->user_data)) + { + g_error ("Per-desktop default value for key '%s' in schema '%s' " + "was rejected by the binding mapping function.", + binding->key.name, g_settings_schema_get_id (binding->key.schema)); + g_variant_unref (variant); + variant = NULL; + } + } + + if (variant == NULL) + { + variant = g_variant_ref (binding->key.default_value); + if (!binding->get_mapping (&value, variant, binding->user_data)) + g_error ("The schema default value for key '%s' in schema '%s' " + "was rejected by the binding mapping function.", + binding->key.name, g_settings_schema_get_id (binding->key.schema)); + } + + g_object_set_property (binding->object, binding->property->name, &value); + g_variant_unref (variant); + g_value_unset (&value); + + binding->running = FALSE; +} + +static void +g_settings_binding_property_changed (GObject *object, + const GParamSpec *pspec, + gpointer user_data) +{ + GSettingsBinding *binding = user_data; + GValue value = G_VALUE_INIT; + GVariant *variant; + gboolean valid = TRUE; + + g_assert (object == binding->object); + g_assert (pspec == binding->property); + + if (binding->running) + return; + + binding->running = TRUE; + + g_value_init (&value, pspec->value_type); + g_object_get_property (object, pspec->name, &value); + if ((variant = binding->set_mapping (&value, binding->key.type, + binding->user_data))) + { + g_variant_take_ref (variant); + + if (!g_settings_schema_key_type_check (&binding->key, variant)) + { + gchar *type_str; + type_str = g_variant_type_dup_string (binding->key.type); + g_critical ("binding mapping function for key '%s' returned " + "GVariant of type '%s' when type '%s' was requested", + binding->key.name, g_variant_get_type_string (variant), + type_str); + g_free (type_str); + valid = FALSE; + } + + if (valid && !g_settings_schema_key_range_check (&binding->key, variant)) + { + gchar *variant_str; + variant_str = g_variant_print (variant, TRUE); + g_critical ("GObject property '%s' on a '%s' object is out of " + "schema-specified range for key '%s' of '%s': %s", + binding->property->name, g_type_name (binding->property->owner_type), + binding->key.name, g_settings_schema_get_id (binding->key.schema), + variant_str); + g_free (variant_str); + valid = FALSE; + } + + if (valid) + { + g_settings_write_to_backend (binding->settings, &binding->key, variant); + } + g_variant_unref (variant); + } + g_value_unset (&value); + + binding->running = FALSE; +} + +static gboolean +g_settings_bind_invert_boolean_get_mapping (GValue *value, + GVariant *variant, + gpointer user_data) +{ + g_value_set_boolean (value, !g_variant_get_boolean (variant)); + return TRUE; +} + +static GVariant * +g_settings_bind_invert_boolean_set_mapping (const GValue *value, + const GVariantType *expected_type, + gpointer user_data) +{ + return g_variant_new_boolean (!g_value_get_boolean (value)); +} + +/** + * g_settings_bind: + * @settings: a #GSettings object + * @key: the key to bind + * @object: (type GObject.Object): a #GObject + * @property: the name of the property to bind + * @flags: flags for the binding + * + * Create a binding between the @key in the @settings object + * and the property @property of @object. + * + * The binding uses the default GIO mapping functions to map + * between the settings and property values. These functions + * handle booleans, numeric types and string types in a + * straightforward way. Use g_settings_bind_with_mapping() if + * you need a custom mapping, or map between types that are not + * supported by the default mapping functions. + * + * Unless the @flags include %G_SETTINGS_BIND_NO_SENSITIVITY, this + * function also establishes a binding between the writability of + * @key and the "sensitive" property of @object (if @object has + * a boolean property by that name). See g_settings_bind_writable() + * for more details about writable bindings. + * + * Note that the lifecycle of the binding is tied to @object, + * and that you can have only one binding per object property. + * If you bind the same property twice on the same object, the second + * binding overrides the first one. + * + * Since: 2.26 + */ +void +g_settings_bind (GSettings *settings, + const gchar *key, + gpointer object, + const gchar *property, + GSettingsBindFlags flags) +{ + GSettingsBindGetMapping get_mapping = NULL; + GSettingsBindSetMapping set_mapping = NULL; + + if (flags & G_SETTINGS_BIND_INVERT_BOOLEAN) + { + get_mapping = g_settings_bind_invert_boolean_get_mapping; + set_mapping = g_settings_bind_invert_boolean_set_mapping; + + /* can't pass this flag to g_settings_bind_with_mapping() */ + flags &= ~G_SETTINGS_BIND_INVERT_BOOLEAN; + } + + g_settings_bind_with_mapping (settings, key, object, property, flags, + get_mapping, set_mapping, NULL, NULL); +} + +/** + * g_settings_bind_with_mapping: (skip) + * @settings: a #GSettings object + * @key: the key to bind + * @object: (type GObject.Object): a #GObject + * @property: the name of the property to bind + * @flags: flags for the binding + * @get_mapping: a function that gets called to convert values + * from @settings to @object, or %NULL to use the default GIO mapping + * @set_mapping: a function that gets called to convert values + * from @object to @settings, or %NULL to use the default GIO mapping + * @user_data: data that gets passed to @get_mapping and @set_mapping + * @destroy: #GDestroyNotify function for @user_data + * + * Create a binding between the @key in the @settings object + * and the property @property of @object. + * + * The binding uses the provided mapping functions to map between + * settings and property values. + * + * Note that the lifecycle of the binding is tied to @object, + * and that you can have only one binding per object property. + * If you bind the same property twice on the same object, the second + * binding overrides the first one. + * + * Since: 2.26 + */ +void +g_settings_bind_with_mapping (GSettings *settings, + const gchar *key, + gpointer object, + const gchar *property, + GSettingsBindFlags flags, + GSettingsBindGetMapping get_mapping, + GSettingsBindSetMapping set_mapping, + gpointer user_data, + GDestroyNotify destroy) +{ + GSettingsBinding *binding; + GObjectClass *objectclass; + gchar *detailed_signal; + GQuark binding_quark; + + g_return_if_fail (G_IS_SETTINGS (settings)); + g_return_if_fail (key != NULL); + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (property != NULL); + g_return_if_fail (~flags & G_SETTINGS_BIND_INVERT_BOOLEAN); + + objectclass = G_OBJECT_GET_CLASS (object); + + binding = g_slice_new0 (GSettingsBinding); + g_settings_schema_key_init (&binding->key, settings->priv->schema, key); + binding->settings = g_object_ref (settings); + binding->object = object; + binding->property = g_object_class_find_property (objectclass, property); + binding->user_data = user_data; + binding->destroy = destroy; + binding->get_mapping = get_mapping ? get_mapping : g_settings_get_mapping; + binding->set_mapping = set_mapping ? set_mapping : g_settings_set_mapping; + + if (!(flags & (G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET))) + flags |= G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET; + + if (binding->property == NULL) + { + g_critical ("g_settings_bind: no property '%s' on class '%s'", + property, G_OBJECT_TYPE_NAME (object)); + return; + } + + if ((flags & G_SETTINGS_BIND_GET) && + (binding->property->flags & G_PARAM_WRITABLE) == 0) + { + g_critical ("g_settings_bind: property '%s' on class '%s' is not " + "writable", binding->property->name, G_OBJECT_TYPE_NAME (object)); + return; + } + if ((flags & G_SETTINGS_BIND_SET) && + (binding->property->flags & G_PARAM_READABLE) == 0) + { + g_critical ("g_settings_bind: property '%s' on class '%s' is not " + "readable", binding->property->name, G_OBJECT_TYPE_NAME (object)); + return; + } + + if (get_mapping == g_settings_bind_invert_boolean_get_mapping) + { + /* g_settings_bind_invert_boolean_get_mapping() is a private + * function, so if we are here it means that g_settings_bind() was + * called with G_SETTINGS_BIND_INVERT_BOOLEAN. + * + * Ensure that both sides are boolean. + */ + + if (binding->property->value_type != G_TYPE_BOOLEAN) + { + g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN " + "was specified, but property '%s' on type '%s' has " + "type '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object), + g_type_name ((binding->property->value_type))); + return; + } + + if (!g_variant_type_equal (binding->key.type, G_VARIANT_TYPE_BOOLEAN)) + { + gchar *type_string = g_variant_type_dup_string (binding->key.type); + g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN " + "was specified, but key '%s' on schema '%s' has " + "type '%s'", key, g_settings_schema_get_id (settings->priv->schema), + type_string); + g_free (type_string); + return; + } + + } + + else if (((get_mapping == NULL && (flags & G_SETTINGS_BIND_GET)) || + (set_mapping == NULL && (flags & G_SETTINGS_BIND_SET))) && + !g_settings_mapping_is_compatible (binding->property->value_type, + binding->key.type)) + { + gchar *type_string = g_variant_type_dup_string (binding->key.type); + g_critical ("g_settings_bind: property '%s' on class '%s' has type " + "'%s' which is not compatible with type '%s' of key '%s' " + "on schema '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object), + g_type_name (binding->property->value_type), + type_string, key, + g_settings_schema_get_id (settings->priv->schema)); + g_free (type_string); + return; + } + + if ((flags & G_SETTINGS_BIND_SET) && + (~flags & G_SETTINGS_BIND_NO_SENSITIVITY)) + { + GParamSpec *sensitive; + + sensitive = g_object_class_find_property (objectclass, "sensitive"); + + if (sensitive && sensitive->value_type == G_TYPE_BOOLEAN && + (sensitive->flags & G_PARAM_WRITABLE)) + g_settings_bind_writable (settings, binding->key.name, object, "sensitive", FALSE); + } + + if (flags & G_SETTINGS_BIND_SET) + { + detailed_signal = g_strdup_printf ("notify::%s", binding->property->name); + binding->property_handler_id = + g_signal_connect (object, detailed_signal, + G_CALLBACK (g_settings_binding_property_changed), + binding); + g_free (detailed_signal); + + if (~flags & G_SETTINGS_BIND_GET) + g_settings_binding_property_changed (object, + binding->property, + binding); + } + + if (flags & G_SETTINGS_BIND_GET) + { + if (~flags & G_SETTINGS_BIND_GET_NO_CHANGES) + { + detailed_signal = g_strdup_printf ("changed::%s", key); + binding->key_handler_id = + g_signal_connect (settings, detailed_signal, + G_CALLBACK (g_settings_binding_key_changed), + binding); + g_free (detailed_signal); + } + + g_settings_binding_key_changed (settings, binding->key.name, binding); + } + + binding_quark = g_settings_binding_quark (binding->property->name); + g_object_set_qdata_full (object, binding_quark, + binding, g_settings_binding_free); +} + +/* Writability binding {{{1 */ +typedef struct +{ + GSettings *settings; + gpointer object; + const gchar *key; + const gchar *property; + gboolean inverted; + gulong handler_id; +} GSettingsWritableBinding; + +static void +g_settings_writable_binding_free (gpointer data) +{ + GSettingsWritableBinding *binding = data; + + g_signal_handler_disconnect (binding->settings, binding->handler_id); + g_object_unref (binding->settings); + g_slice_free (GSettingsWritableBinding, binding); +} + +static void +g_settings_binding_writable_changed (GSettings *settings, + const gchar *key, + gpointer user_data) +{ + GSettingsWritableBinding *binding = user_data; + gboolean writable; + + g_assert (settings == binding->settings); + g_assert (key == binding->key); + + writable = g_settings_is_writable (settings, key); + + if (binding->inverted) + writable = !writable; + + g_object_set (binding->object, binding->property, writable, NULL); +} + +/** + * g_settings_bind_writable: + * @settings: a #GSettings object + * @key: the key to bind + * @object: (type GObject.Object):a #GObject + * @property: the name of a boolean property to bind + * @inverted: whether to 'invert' the value + * + * Create a binding between the writability of @key in the + * @settings object and the property @property of @object. + * The property must be boolean; "sensitive" or "visible" + * properties of widgets are the most likely candidates. + * + * Writable bindings are always uni-directional; changes of the + * writability of the setting will be propagated to the object + * property, not the other way. + * + * When the @inverted argument is %TRUE, the binding inverts the + * value as it passes from the setting to the object, i.e. @property + * will be set to %TRUE if the key is not writable. + * + * Note that the lifecycle of the binding is tied to @object, + * and that you can have only one binding per object property. + * If you bind the same property twice on the same object, the second + * binding overrides the first one. + * + * Since: 2.26 + */ +void +g_settings_bind_writable (GSettings *settings, + const gchar *key, + gpointer object, + const gchar *property, + gboolean inverted) +{ + GSettingsWritableBinding *binding; + gchar *detailed_signal; + GParamSpec *pspec; + + g_return_if_fail (G_IS_SETTINGS (settings)); + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property); + if (pspec == NULL) + { + g_critical ("g_settings_bind_writable: no property '%s' on class '%s'", + property, G_OBJECT_TYPE_NAME (object)); + return; + } + if ((pspec->flags & G_PARAM_WRITABLE) == 0) + { + g_critical ("g_settings_bind_writable: property '%s' on class '%s' is not writable", + property, G_OBJECT_TYPE_NAME (object)); + return; + } + + binding = g_slice_new (GSettingsWritableBinding); + binding->settings = g_object_ref (settings); + binding->object = object; + binding->key = g_intern_string (key); + binding->property = g_intern_string (property); + binding->inverted = inverted; + + detailed_signal = g_strdup_printf ("writable-changed::%s", key); + binding->handler_id = + g_signal_connect (settings, detailed_signal, + G_CALLBACK (g_settings_binding_writable_changed), + binding); + g_free (detailed_signal); + + g_object_set_qdata_full (object, g_settings_binding_quark (property), + binding, g_settings_writable_binding_free); + + g_settings_binding_writable_changed (settings, binding->key, binding); +} + +/** + * g_settings_unbind: + * @object: (type GObject.Object): the object + * @property: the property whose binding is removed + * + * Removes an existing binding for @property on @object. + * + * Note that bindings are automatically removed when the + * object is finalized, so it is rarely necessary to call this + * function. + * + * Since: 2.26 + */ +void +g_settings_unbind (gpointer object, + const gchar *property) +{ + GQuark binding_quark; + + binding_quark = g_settings_binding_quark (property); + g_object_set_qdata (object, binding_quark, NULL); +} + +/* GAction {{{1 */ + +typedef struct +{ + GObject parent_instance; + + GSettingsSchemaKey key; + GSettings *settings; +} GSettingsAction; + +typedef GObjectClass GSettingsActionClass; + +static GType g_settings_action_get_type (void); +static void g_settings_action_iface_init (GActionInterface *iface); +G_DEFINE_TYPE_WITH_CODE (GSettingsAction, g_settings_action, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_settings_action_iface_init)) + +enum +{ + ACTION_PROP_0, + ACTION_PROP_NAME, + ACTION_PROP_PARAMETER_TYPE, + ACTION_PROP_ENABLED, + ACTION_PROP_STATE_TYPE, + ACTION_PROP_STATE +}; + +static const gchar * +g_settings_action_get_name (GAction *action) +{ + GSettingsAction *gsa = (GSettingsAction *) action; + + return gsa->key.name; +} + +static const GVariantType * +g_settings_action_get_parameter_type (GAction *action) +{ + GSettingsAction *gsa = (GSettingsAction *) action; + const GVariantType *type; + + type = g_variant_get_type (gsa->key.default_value); + if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN)) + type = NULL; + + return type; +} + +static gboolean +g_settings_action_get_enabled (GAction *action) +{ + GSettingsAction *gsa = (GSettingsAction *) action; + + return g_settings_is_writable (gsa->settings, gsa->key.name); +} + +static const GVariantType * +g_settings_action_get_state_type (GAction *action) +{ + GSettingsAction *gsa = (GSettingsAction *) action; + + return g_variant_get_type (gsa->key.default_value); +} + +static GVariant * +g_settings_action_get_state (GAction *action) +{ + GSettingsAction *gsa = (GSettingsAction *) action; + GVariant *value; + + value = g_settings_read_from_backend (gsa->settings, &gsa->key, FALSE, FALSE); + + if (value == NULL) + value = g_settings_schema_key_get_translated_default (&gsa->key); + + if (value == NULL) + value = g_variant_ref (gsa->key.default_value); + + return value; +} + +static GVariant * +g_settings_action_get_state_hint (GAction *action) +{ + GSettingsAction *gsa = (GSettingsAction *) action; + + /* no point in reimplementing this... */ + return g_settings_schema_key_get_range (&gsa->key); +} + +static void +g_settings_action_change_state (GAction *action, + GVariant *value) +{ + GSettingsAction *gsa = (GSettingsAction *) action; + + if (g_settings_schema_key_type_check (&gsa->key, value) && g_settings_schema_key_range_check (&gsa->key, value)) + g_settings_write_to_backend (gsa->settings, &gsa->key, value); +} + +static void +g_settings_action_activate (GAction *action, + GVariant *parameter) +{ + GSettingsAction *gsa = (GSettingsAction *) action; + + if (g_variant_is_of_type (gsa->key.default_value, G_VARIANT_TYPE_BOOLEAN)) + { + GVariant *old; + + if (parameter != NULL) + return; + + old = g_settings_action_get_state (action); + parameter = g_variant_new_boolean (!g_variant_get_boolean (old)); + g_variant_unref (old); + } + + g_action_change_state (action, parameter); +} + +static void +g_settings_action_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GAction *action = G_ACTION (object); + + switch (prop_id) + { + case ACTION_PROP_NAME: + g_value_set_string (value, g_settings_action_get_name (action)); + break; + + case ACTION_PROP_PARAMETER_TYPE: + g_value_set_boxed (value, g_settings_action_get_parameter_type (action)); + break; + + case ACTION_PROP_ENABLED: + g_value_set_boolean (value, g_settings_action_get_enabled (action)); + break; + + case ACTION_PROP_STATE_TYPE: + g_value_set_boxed (value, g_settings_action_get_state_type (action)); + break; + + case ACTION_PROP_STATE: + g_value_take_variant (value, g_settings_action_get_state (action)); + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_settings_action_finalize (GObject *object) +{ + GSettingsAction *gsa = (GSettingsAction *) object; + + g_signal_handlers_disconnect_by_data (gsa->settings, gsa); + g_object_unref (gsa->settings); + g_settings_schema_key_clear (&gsa->key); + + G_OBJECT_CLASS (g_settings_action_parent_class) + ->finalize (object); +} + +static void +g_settings_action_init (GSettingsAction *gsa) +{ +} + +static void +g_settings_action_iface_init (GActionInterface *iface) +{ + iface->get_name = g_settings_action_get_name; + iface->get_parameter_type = g_settings_action_get_parameter_type; + iface->get_enabled = g_settings_action_get_enabled; + iface->get_state_type = g_settings_action_get_state_type; + iface->get_state = g_settings_action_get_state; + iface->get_state_hint = g_settings_action_get_state_hint; + iface->change_state = g_settings_action_change_state; + iface->activate = g_settings_action_activate; +} + +static void +g_settings_action_class_init (GSettingsActionClass *class) +{ + class->get_property = g_settings_action_get_property; + class->finalize = g_settings_action_finalize; + + g_object_class_override_property (class, ACTION_PROP_NAME, "name"); + g_object_class_override_property (class, ACTION_PROP_PARAMETER_TYPE, "parameter-type"); + g_object_class_override_property (class, ACTION_PROP_ENABLED, "enabled"); + g_object_class_override_property (class, ACTION_PROP_STATE_TYPE, "state-type"); + g_object_class_override_property (class, ACTION_PROP_STATE, "state"); +} + +static void +g_settings_action_changed (GSettings *settings, + const gchar *key, + gpointer user_data) +{ + g_object_notify (user_data, "state"); +} + +static void +g_settings_action_enabled_changed (GSettings *settings, + const gchar *key, + gpointer user_data) +{ + g_object_notify (user_data, "enabled"); +} + +/** + * g_settings_create_action: + * @settings: a #GSettings + * @key: the name of a key in @settings + * + * Creates a #GAction corresponding to a given #GSettings key. + * + * The action has the same name as the key. + * + * The value of the key becomes the state of the action and the action + * is enabled when the key is writable. Changing the state of the + * action results in the key being written to. Changes to the value or + * writability of the key cause appropriate change notifications to be + * emitted for the action. + * + * For boolean-valued keys, action activations take no parameter and + * result in the toggling of the value. For all other types, + * activations take the new value for the key (which must have the + * correct type). + * + * Returns: (not nullable) (transfer full): a new #GAction + * + * Since: 2.32 + **/ +GAction * +g_settings_create_action (GSettings *settings, + const gchar *key) +{ + GSettingsAction *gsa; + gchar *detailed_signal; + + g_return_val_if_fail (G_IS_SETTINGS (settings), NULL); + g_return_val_if_fail (key != NULL, NULL); + + gsa = g_object_new (g_settings_action_get_type (), NULL); + gsa->settings = g_object_ref (settings); + g_settings_schema_key_init (&gsa->key, settings->priv->schema, key); + + detailed_signal = g_strdup_printf ("changed::%s", key); + g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_changed), gsa); + g_free (detailed_signal); + detailed_signal = g_strdup_printf ("writable-changed::%s", key); + g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_enabled_changed), gsa); + g_free (detailed_signal); + + return G_ACTION (gsa); +} + +/* Epilogue {{{1 */ + +/* vim:set foldmethod=marker: */ diff --git a/gio/gsettings.h b/gio/gsettings.h new file mode 100644 index 0000000..cb35d28 --- /dev/null +++ b/gio/gsettings.h @@ -0,0 +1,345 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_SETTINGS_H__ +#define __G_SETTINGS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_SETTINGS (g_settings_get_type ()) +#define G_SETTINGS(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SETTINGS, GSettings)) +#define G_SETTINGS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SETTINGS, GSettingsClass)) +#define G_IS_SETTINGS(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_SETTINGS)) +#define G_IS_SETTINGS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_SETTINGS)) +#define G_SETTINGS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SETTINGS, GSettingsClass)) + +typedef struct _GSettingsPrivate GSettingsPrivate; +typedef struct _GSettingsClass GSettingsClass; + +struct _GSettingsClass +{ + GObjectClass parent_class; + + /* Signals */ + void (*writable_changed) (GSettings *settings, + const gchar *key); + void (*changed) (GSettings *settings, + const gchar *key); + gboolean (*writable_change_event) (GSettings *settings, + GQuark key); + gboolean (*change_event) (GSettings *settings, + const GQuark *keys, + gint n_keys); + + gpointer padding[20]; +}; + +struct _GSettings +{ + GObject parent_instance; + GSettingsPrivate *priv; +}; + + +GLIB_AVAILABLE_IN_ALL +GType g_settings_get_type (void); + +GLIB_DEPRECATED_IN_2_40_FOR(g_settings_schema_source_list_schemas) +const gchar * const * g_settings_list_schemas (void); +GLIB_DEPRECATED_IN_2_40_FOR(g_settings_schema_source_list_schemas) +const gchar * const * g_settings_list_relocatable_schemas (void); +GLIB_AVAILABLE_IN_ALL +GSettings * g_settings_new (const gchar *schema_id); +GLIB_AVAILABLE_IN_ALL +GSettings * g_settings_new_with_path (const gchar *schema_id, + const gchar *path); +GLIB_AVAILABLE_IN_ALL +GSettings * g_settings_new_with_backend (const gchar *schema_id, + GSettingsBackend *backend); +GLIB_AVAILABLE_IN_ALL +GSettings * g_settings_new_with_backend_and_path (const gchar *schema_id, + GSettingsBackend *backend, + const gchar *path); +GLIB_AVAILABLE_IN_2_32 +GSettings * g_settings_new_full (GSettingsSchema *schema, + GSettingsBackend *backend, + const gchar *path); +GLIB_AVAILABLE_IN_ALL +gchar ** g_settings_list_children (GSettings *settings); +GLIB_DEPRECATED_IN_2_46_FOR(g_settings_schema_list_keys) +gchar ** g_settings_list_keys (GSettings *settings); +GLIB_DEPRECATED_IN_2_40_FOR(g_settings_schema_key_get_range) +GVariant * g_settings_get_range (GSettings *settings, + const gchar *key); +GLIB_DEPRECATED_IN_2_40_FOR(g_settings_schema_key_range_check) +gboolean g_settings_range_check (GSettings *settings, + const gchar *key, + GVariant *value); + +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set_value (GSettings *settings, + const gchar *key, + GVariant *value); +GLIB_AVAILABLE_IN_ALL +GVariant * g_settings_get_value (GSettings *settings, + const gchar *key); + +GLIB_AVAILABLE_IN_2_40 +GVariant * g_settings_get_user_value (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_2_40 +GVariant * g_settings_get_default_value (GSettings *settings, + const gchar *key); + +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set (GSettings *settings, + const gchar *key, + const gchar *format, + ...); +GLIB_AVAILABLE_IN_ALL +void g_settings_get (GSettings *settings, + const gchar *key, + const gchar *format, + ...); +GLIB_AVAILABLE_IN_ALL +void g_settings_reset (GSettings *settings, + const gchar *key); + +GLIB_AVAILABLE_IN_ALL +gint g_settings_get_int (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set_int (GSettings *settings, + const gchar *key, + gint value); +GLIB_AVAILABLE_IN_2_50 +gint64 g_settings_get_int64 (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_2_50 +gboolean g_settings_set_int64 (GSettings *settings, + const gchar *key, + gint64 value); +GLIB_AVAILABLE_IN_2_32 +guint g_settings_get_uint (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_2_32 +gboolean g_settings_set_uint (GSettings *settings, + const gchar *key, + guint value); +GLIB_AVAILABLE_IN_2_50 +guint64 g_settings_get_uint64 (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_2_50 +gboolean g_settings_set_uint64 (GSettings *settings, + const gchar *key, + guint64 value); +GLIB_AVAILABLE_IN_ALL +gchar * g_settings_get_string (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set_string (GSettings *settings, + const gchar *key, + const gchar *value); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_get_boolean (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set_boolean (GSettings *settings, + const gchar *key, + gboolean value); +GLIB_AVAILABLE_IN_ALL +gdouble g_settings_get_double (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set_double (GSettings *settings, + const gchar *key, + gdouble value); +GLIB_AVAILABLE_IN_ALL +gchar ** g_settings_get_strv (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set_strv (GSettings *settings, + const gchar *key, + const gchar *const *value); +GLIB_AVAILABLE_IN_ALL +gint g_settings_get_enum (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set_enum (GSettings *settings, + const gchar *key, + gint value); +GLIB_AVAILABLE_IN_ALL +guint g_settings_get_flags (GSettings *settings, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_set_flags (GSettings *settings, + const gchar *key, + guint value); +GLIB_AVAILABLE_IN_ALL +GSettings * g_settings_get_child (GSettings *settings, + const gchar *name); + +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_is_writable (GSettings *settings, + const gchar *name); + +GLIB_AVAILABLE_IN_ALL +void g_settings_delay (GSettings *settings); +GLIB_AVAILABLE_IN_ALL +void g_settings_apply (GSettings *settings); +GLIB_AVAILABLE_IN_ALL +void g_settings_revert (GSettings *settings); +GLIB_AVAILABLE_IN_ALL +gboolean g_settings_get_has_unapplied (GSettings *settings); +GLIB_AVAILABLE_IN_ALL +void g_settings_sync (void); + +/** + * GSettingsBindSetMapping: + * @value: a #GValue containing the property value to map + * @expected_type: the #GVariantType to create + * @user_data: user data that was specified when the binding was created + * + * The type for the function that is used to convert an object property + * value to a #GVariant for storing it in #GSettings. + * + * Returns: a new #GVariant holding the data from @value, + * or %NULL in case of an error + */ +typedef GVariant * (*GSettingsBindSetMapping) (const GValue *value, + const GVariantType *expected_type, + gpointer user_data); + +/** + * GSettingsBindGetMapping: + * @value: return location for the property value + * @variant: the #GVariant + * @user_data: user data that was specified when the binding was created + * + * The type for the function that is used to convert from #GSettings to + * an object property. The @value is already initialized to hold values + * of the appropriate type. + * + * Returns: %TRUE if the conversion succeeded, %FALSE in case of an error + */ +typedef gboolean (*GSettingsBindGetMapping) (GValue *value, + GVariant *variant, + gpointer user_data); + +/** + * GSettingsGetMapping: + * @value: the #GVariant to map, or %NULL + * @result: (out): the result of the mapping + * @user_data: (closure): the user data that was passed to + * g_settings_get_mapped() + * + * The type of the function that is used to convert from a value stored + * in a #GSettings to a value that is useful to the application. + * + * If the value is successfully mapped, the result should be stored at + * @result and %TRUE returned. If mapping fails (for example, if @value + * is not in the right format) then %FALSE should be returned. + * + * If @value is %NULL then it means that the mapping function is being + * given a "last chance" to successfully return a valid value. %TRUE + * must be returned in this case. + * + * Returns: %TRUE if the conversion succeeded, %FALSE in case of an error + **/ +typedef gboolean (*GSettingsGetMapping) (GVariant *value, + gpointer *result, + gpointer user_data); + +/** + * GSettingsBindFlags: + * @G_SETTINGS_BIND_DEFAULT: Equivalent to `G_SETTINGS_BIND_GET|G_SETTINGS_BIND_SET` + * @G_SETTINGS_BIND_GET: Update the #GObject property when the setting changes. + * It is an error to use this flag if the property is not writable. + * @G_SETTINGS_BIND_SET: Update the setting when the #GObject property changes. + * It is an error to use this flag if the property is not readable. + * @G_SETTINGS_BIND_NO_SENSITIVITY: Do not try to bind a "sensitivity" property to the writability of the setting + * @G_SETTINGS_BIND_GET_NO_CHANGES: When set in addition to %G_SETTINGS_BIND_GET, set the #GObject property + * value initially from the setting, but do not listen for changes of the setting + * @G_SETTINGS_BIND_INVERT_BOOLEAN: When passed to g_settings_bind(), uses a pair of mapping functions that invert + * the boolean value when mapping between the setting and the property. The setting and property must both + * be booleans. You cannot pass this flag to g_settings_bind_with_mapping(). + * + * Flags used when creating a binding. These flags determine in which + * direction the binding works. The default is to synchronize in both + * directions. + */ +typedef enum +{ + G_SETTINGS_BIND_DEFAULT, + G_SETTINGS_BIND_GET = (1<<0), + G_SETTINGS_BIND_SET = (1<<1), + G_SETTINGS_BIND_NO_SENSITIVITY = (1<<2), + G_SETTINGS_BIND_GET_NO_CHANGES = (1<<3), + G_SETTINGS_BIND_INVERT_BOOLEAN = (1<<4) +} GSettingsBindFlags; + +GLIB_AVAILABLE_IN_ALL +void g_settings_bind (GSettings *settings, + const gchar *key, + gpointer object, + const gchar *property, + GSettingsBindFlags flags); +GLIB_AVAILABLE_IN_ALL +void g_settings_bind_with_mapping (GSettings *settings, + const gchar *key, + gpointer object, + const gchar *property, + GSettingsBindFlags flags, + GSettingsBindGetMapping get_mapping, + GSettingsBindSetMapping set_mapping, + gpointer user_data, + GDestroyNotify destroy); +GLIB_AVAILABLE_IN_ALL +void g_settings_bind_writable (GSettings *settings, + const gchar *key, + gpointer object, + const gchar *property, + gboolean inverted); +GLIB_AVAILABLE_IN_ALL +void g_settings_unbind (gpointer object, + const gchar *property); + +GLIB_AVAILABLE_IN_2_32 +GAction * g_settings_create_action (GSettings *settings, + const gchar *key); + +GLIB_AVAILABLE_IN_ALL +gpointer g_settings_get_mapped (GSettings *settings, + const gchar *key, + GSettingsGetMapping mapping, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_SETTINGS_H__ */ diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c new file mode 100644 index 0000000..a1a23cc --- /dev/null +++ b/gio/gsettingsbackend.c @@ -0,0 +1,1080 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * Copyright © 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Matthias Clasen + */ + +#include "config.h" + +#include "gsettingsbackendinternal.h" +#include "gsimplepermission.h" +#include "giomodule-priv.h" + +#include +#include +#include +#include + + +typedef struct _GSettingsBackendClosure GSettingsBackendClosure; +typedef struct _GSettingsBackendWatch GSettingsBackendWatch; + +struct _GSettingsBackendPrivate +{ + GSettingsBackendWatch *watches; + GMutex lock; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT) + +/* For g_settings_backend_sync_default(), we only want to actually do + * the sync if the backend already exists. This avoids us creating an + * entire GSettingsBackend in order to call a do-nothing sync() + * operation on it. This variable lets us avoid that. + */ +static gboolean g_settings_has_backend; + +/** + * SECTION:gsettingsbackend + * @title: GSettingsBackend + * @short_description: Interface for settings backend implementations + * @include: gio/gsettingsbackend.h + * @see_also: #GSettings, #GIOExtensionPoint + * + * The #GSettingsBackend interface defines a generic interface for + * non-strictly-typed data that is stored in a hierarchy. To implement + * an alternative storage backend for #GSettings, you need to implement + * the #GSettingsBackend interface and then make it implement the + * extension point %G_SETTINGS_BACKEND_EXTENSION_POINT_NAME. + * + * The interface defines methods for reading and writing values, a + * method for determining if writing of certain values will fail + * (lockdown) and a change notification mechanism. + * + * The semantics of the interface are very precisely defined and + * implementations must carefully adhere to the expectations of + * callers that are documented on each of the interface methods. + * + * Some of the #GSettingsBackend functions accept or return a #GTree. + * These trees always have strings as keys and #GVariant as values. + * g_settings_backend_create_tree() is a convenience function to create + * suitable trees. + * + * The #GSettingsBackend API is exported to allow third-party + * implementations, but does not carry the same stability guarantees + * as the public GIO API. For this reason, you have to define the + * C preprocessor symbol %G_SETTINGS_ENABLE_BACKEND before including + * `gio/gsettingsbackend.h`. + **/ + +static gboolean +is_key (const gchar *key) +{ + gint length; + gint i; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (key[0] == '/', FALSE); + + for (i = 1; key[i]; i++) + g_return_val_if_fail (key[i] != '/' || key[i + 1] != '/', FALSE); + + length = i; + + g_return_val_if_fail (key[length - 1] != '/', FALSE); + + return TRUE; +} + +static gboolean +is_path (const gchar *path) +{ + gint length; + gint i; + + g_return_val_if_fail (path != NULL, FALSE); + g_return_val_if_fail (path[0] == '/', FALSE); + + for (i = 1; path[i]; i++) + g_return_val_if_fail (path[i] != '/' || path[i + 1] != '/', FALSE); + + length = i; + + g_return_val_if_fail (path[length - 1] == '/', FALSE); + + return TRUE; +} + +struct _GSettingsBackendWatch +{ + /* Always access the target via the weak reference */ + GWeakRef target; + /* The pointer is only for comparison from the weak notify, + * at which point the target might already be close to + * destroyed. It's not safe to use it for anything anymore + * at that point */ + GObject *target_ptr; + const GSettingsListenerVTable *vtable; + GMainContext *context; + GSettingsBackendWatch *next; +}; + +struct _GSettingsBackendClosure +{ + void (*function) (GObject *target, + GSettingsBackend *backend, + const gchar *name, + gpointer origin_tag, + gchar **names); + + GMainContext *context; + GObject *target; + GSettingsBackend *backend; + gchar *name; + gpointer origin_tag; + gchar **names; +}; + +static void +g_settings_backend_watch_weak_notify (gpointer data, + GObject *where_the_object_was) +{ + GSettingsBackend *backend = data; + GSettingsBackendWatch **ptr; + + /* search and remove */ + g_mutex_lock (&backend->priv->lock); + for (ptr = &backend->priv->watches; *ptr; ptr = &(*ptr)->next) + if ((*ptr)->target_ptr == where_the_object_was) + { + GSettingsBackendWatch *tmp = *ptr; + + *ptr = tmp->next; + g_weak_ref_clear (&tmp->target); + g_slice_free (GSettingsBackendWatch, tmp); + + g_mutex_unlock (&backend->priv->lock); + return; + } + + /* we didn't find it. that shouldn't happen. */ + g_assert_not_reached (); +} + +/*< private > + * g_settings_backend_watch: + * @backend: a #GSettingsBackend + * @target: the GObject (typically GSettings instance) to call back to + * @context: (nullable): a #GMainContext, or %NULL + * ...: callbacks... + * + * Registers a new watch on a #GSettingsBackend. + * + * note: %NULL @context does not mean "default main context" but rather, + * "it is okay to dispatch in any context". If the default main context + * is specifically desired then it must be given. + * + * note also: if you want to get meaningful values for the @origin_tag + * that appears as an argument to some of the callbacks, you *must* have + * @context as %NULL. Otherwise, you are subject to cross-thread + * dispatching and whatever owned @origin_tag at the time that the event + * occurred may no longer own it. This is a problem if you consider that + * you may now be the new owner of that address and mistakenly think + * that the event in question originated from yourself. + * + * tl;dr: If you give a non-%NULL @context then you must ignore the + * value of @origin_tag given to any callbacks. + **/ +void +g_settings_backend_watch (GSettingsBackend *backend, + const GSettingsListenerVTable *vtable, + GObject *target, + GMainContext *context) +{ + GSettingsBackendWatch *watch; + + /* For purposes of discussion, we assume that our target is a + * GSettings instance. + * + * Our strategy to defend against the final reference dropping on the + * GSettings object in a thread other than the one that is doing the + * dispatching is as follows: + * + * 1) hold a strong reference on the GSettings during an outstanding + * dispatch. This ensures that the delivery is always possible while + * the GSettings object is alive, and if this was the last reference + * then it will be dropped from the dispatch thread. + * + * 2) hold a weak reference on the GSettings at other times. This + * allows us to receive early notification of pending destruction + * of the object. At this point, it is still safe to obtain a + * reference on the GObject to keep it alive, so #1 will work up + * to that point. After that point, we'll have been able to drop + * the watch from the list. + * + * Note, in particular, that it's not possible to simply have an + * "unwatch" function that gets called from the finalize function of + * the GSettings instance because, by that point it is no longer + * possible to keep the object alive using g_object_ref() and we would + * have no way of knowing this. + * + * Note also that we need to hold a reference on the main context here + * since the GSettings instance may be finalized before the closure runs. + * + * All access to the list holds a mutex. We have some strategies to + * avoid some of the pain that would be associated with that. + */ + + watch = g_slice_new (GSettingsBackendWatch); + watch->context = context; + watch->vtable = vtable; + g_weak_ref_init (&watch->target, target); + watch->target_ptr = target; + g_object_weak_ref (target, g_settings_backend_watch_weak_notify, backend); + + /* linked list prepend */ + g_mutex_lock (&backend->priv->lock); + watch->next = backend->priv->watches; + backend->priv->watches = watch; + g_mutex_unlock (&backend->priv->lock); +} + +void +g_settings_backend_unwatch (GSettingsBackend *backend, + GObject *target) +{ + /* Our caller surely owns a reference on 'target', so the order of + * these two calls is unimportant. + */ + g_object_weak_unref (target, g_settings_backend_watch_weak_notify, backend); + g_settings_backend_watch_weak_notify (backend, target); +} + +static gboolean +g_settings_backend_invoke_closure (gpointer user_data) +{ + GSettingsBackendClosure *closure = user_data; + + closure->function (closure->target, closure->backend, closure->name, + closure->origin_tag, closure->names); + + if (closure->context) + g_main_context_unref (closure->context); + g_object_unref (closure->backend); + g_object_unref (closure->target); + g_strfreev (closure->names); + g_free (closure->name); + + g_slice_free (GSettingsBackendClosure, closure); + + return FALSE; +} + +static void +g_settings_backend_dispatch_signal (GSettingsBackend *backend, + gsize function_offset, + const gchar *name, + gpointer origin_tag, + const gchar * const *names) +{ + GSettingsBackendWatch *watch; + GSList *closures = NULL; + + /* We're in a little bit of a tricky situation here. We need to hold + * a lock while traversing the list, but we don't want to hold the + * lock while calling back into user code. + * + * We work around this by creating a bunch of GSettingsBackendClosure + * objects while holding the lock and dispatching them after. We + * never touch the list without holding the lock. + */ + g_mutex_lock (&backend->priv->lock); + for (watch = backend->priv->watches; watch; watch = watch->next) + { + GSettingsBackendClosure *closure; + GObject *target = g_weak_ref_get (&watch->target); + + /* If the target was destroyed in the meantime, just skip it here */ + if (!target) + continue; + + closure = g_slice_new (GSettingsBackendClosure); + closure->context = watch->context; + if (closure->context) + g_main_context_ref (closure->context); + closure->backend = g_object_ref (backend); + closure->target = g_steal_pointer (&target); + closure->function = G_STRUCT_MEMBER (void *, watch->vtable, + function_offset); + closure->name = g_strdup (name); + closure->origin_tag = origin_tag; + closure->names = g_strdupv ((gchar **) names); + + closures = g_slist_prepend (closures, closure); + } + g_mutex_unlock (&backend->priv->lock); + + while (closures) + { + GSettingsBackendClosure *closure = closures->data; + + if (closure->context) + g_main_context_invoke (closure->context, + g_settings_backend_invoke_closure, + closure); + else + g_settings_backend_invoke_closure (closure); + + closures = g_slist_delete_link (closures, closures); + } +} + +/** + * g_settings_backend_changed: + * @backend: a #GSettingsBackend implementation + * @key: the name of the key + * @origin_tag: the origin tag + * + * Signals that a single key has possibly changed. Backend + * implementations should call this if a key has possibly changed its + * value. + * + * @key must be a valid key (ie starting with a slash, not containing + * '//', and not ending with a slash). + * + * The implementation must call this function during any call to + * g_settings_backend_write(), before the call returns (except in the + * case that no keys are actually changed and it cares to detect this + * fact). It may not rely on the existence of a mainloop for + * dispatching the signal later. + * + * The implementation may call this function at any other time it likes + * in response to other events (such as changes occurring outside of the + * program). These calls may originate from a mainloop or may originate + * in response to any other action (including from calls to + * g_settings_backend_write()). + * + * In the case that this call is in response to a call to + * g_settings_backend_write() then @origin_tag must be set to the same + * value that was passed to that call. + * + * Since: 2.26 + **/ +void +g_settings_backend_changed (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); + g_return_if_fail (is_key (key)); + + g_settings_backend_dispatch_signal (backend, + G_STRUCT_OFFSET (GSettingsListenerVTable, + changed), + key, origin_tag, NULL); +} + +/** + * g_settings_backend_keys_changed: + * @backend: a #GSettingsBackend implementation + * @path: the path containing the changes + * @items: (array zero-terminated=1): the %NULL-terminated list of changed keys + * @origin_tag: the origin tag + * + * Signals that a list of keys have possibly changed. Backend + * implementations should call this if keys have possibly changed their + * values. + * + * @path must be a valid path (ie starting and ending with a slash and + * not containing '//'). Each string in @items must form a valid key + * name when @path is prefixed to it (ie: each item must not start or + * end with '/' and must not contain '//'). + * + * The meaning of this signal is that any of the key names resulting + * from the contatenation of @path with each item in @items may have + * changed. + * + * The same rules for when notifications must occur apply as per + * g_settings_backend_changed(). These two calls can be used + * interchangeably if exactly one item has changed (although in that + * case g_settings_backend_changed() is definitely preferred). + * + * For efficiency reasons, the implementation should strive for @path to + * be as long as possible (ie: the longest common prefix of all of the + * keys that were changed) but this is not strictly required. + * + * Since: 2.26 + */ +void +g_settings_backend_keys_changed (GSettingsBackend *backend, + const gchar *path, + gchar const * const *items, + gpointer origin_tag) +{ + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); + g_return_if_fail (is_path (path)); + + /* XXX: should do stricter checking (ie: inspect each item) */ + g_return_if_fail (items != NULL); + + g_settings_backend_dispatch_signal (backend, + G_STRUCT_OFFSET (GSettingsListenerVTable, + keys_changed), + path, origin_tag, items); +} + +/** + * g_settings_backend_path_changed: + * @backend: a #GSettingsBackend implementation + * @path: the path containing the changes + * @origin_tag: the origin tag + * + * Signals that all keys below a given path may have possibly changed. + * Backend implementations should call this if an entire path of keys + * have possibly changed their values. + * + * @path must be a valid path (ie starting and ending with a slash and + * not containing '//'). + * + * The meaning of this signal is that any of the key which has a name + * starting with @path may have changed. + * + * The same rules for when notifications must occur apply as per + * g_settings_backend_changed(). This call might be an appropriate + * reasponse to a 'reset' call but implementations are also free to + * explicitly list the keys that were affected by that call if they can + * easily do so. + * + * For efficiency reasons, the implementation should strive for @path to + * be as long as possible (ie: the longest common prefix of all of the + * keys that were changed) but this is not strictly required. As an + * example, if this function is called with the path of "/" then every + * single key in the application will be notified of a possible change. + * + * Since: 2.26 + */ +void +g_settings_backend_path_changed (GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag) +{ + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); + g_return_if_fail (is_path (path)); + + g_settings_backend_dispatch_signal (backend, + G_STRUCT_OFFSET (GSettingsListenerVTable, + path_changed), + path, origin_tag, NULL); +} + +/** + * g_settings_backend_writable_changed: + * @backend: a #GSettingsBackend implementation + * @key: the name of the key + * + * Signals that the writability of a single key has possibly changed. + * + * Since GSettings performs no locking operations for itself, this call + * will always be made in response to external events. + * + * Since: 2.26 + **/ +void +g_settings_backend_writable_changed (GSettingsBackend *backend, + const gchar *key) +{ + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); + g_return_if_fail (is_key (key)); + + g_settings_backend_dispatch_signal (backend, + G_STRUCT_OFFSET (GSettingsListenerVTable, + writable_changed), + key, NULL, NULL); +} + +/** + * g_settings_backend_path_writable_changed: + * @backend: a #GSettingsBackend implementation + * @path: the name of the path + * + * Signals that the writability of all keys below a given path may have + * changed. + * + * Since GSettings performs no locking operations for itself, this call + * will always be made in response to external events. + * + * Since: 2.26 + **/ +void +g_settings_backend_path_writable_changed (GSettingsBackend *backend, + const gchar *path) +{ + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); + g_return_if_fail (is_path (path)); + + g_settings_backend_dispatch_signal (backend, + G_STRUCT_OFFSET (GSettingsListenerVTable, + path_writable_changed), + path, NULL, NULL); +} + +typedef struct +{ + const gchar **keys; + GVariant **values; + gint prefix_len; + gchar *prefix; +} FlattenState; + +static gboolean +g_settings_backend_flatten_one (gpointer key, + gpointer value, + gpointer user_data) +{ + FlattenState *state = user_data; + const gchar *skey = key; + gint i; + + g_return_val_if_fail (is_key (key), TRUE); + + /* calculate longest common prefix */ + if (state->prefix == NULL) + { + gchar *last_byte; + + /* first key? just take the prefix up to the last '/' */ + state->prefix = g_strdup (skey); + last_byte = strrchr (state->prefix, '/') + 1; + state->prefix_len = last_byte - state->prefix; + *last_byte = '\0'; + } + else + { + /* find the first character that does not match. we will + * definitely find one because the prefix ends in '/' and the key + * does not. also: no two keys in the tree are the same. + */ + for (i = 0; state->prefix[i] == skey[i]; i++); + + /* check if we need to shorten the prefix */ + if (state->prefix[i] != '\0') + { + /* find the nearest '/', terminate after it */ + while (state->prefix[i - 1] != '/') + i--; + + state->prefix[i] = '\0'; + state->prefix_len = i; + } + } + + + /* save the entire item into the array. + * the prefixes will be removed later. + */ + *state->keys++ = key; + + if (state->values) + *state->values++ = value; + + return FALSE; +} + +/** + * g_settings_backend_flatten_tree: + * @tree: a #GTree containing the changes + * @path: (out): the location to save the path + * @keys: (out) (transfer container) (array zero-terminated=1): the + * location to save the relative keys + * @values: (out) (optional) (transfer container) (array zero-terminated=1): + * the location to save the values, or %NULL + * + * Calculate the longest common prefix of all keys in a tree and write + * out an array of the key names relative to that prefix and, + * optionally, the value to store at each of those keys. + * + * You must free the value returned in @path, @keys and @values using + * g_free(). You should not attempt to free or unref the contents of + * @keys or @values. + * + * Since: 2.26 + **/ +void +g_settings_backend_flatten_tree (GTree *tree, + gchar **path, + const gchar ***keys, + GVariant ***values) +{ + FlattenState state = { 0, }; + gsize nnodes; + + nnodes = g_tree_nnodes (tree); + + *keys = state.keys = g_new (const gchar *, nnodes + 1); + state.keys[nnodes] = NULL; + + if (values != NULL) + { + *values = state.values = g_new (GVariant *, nnodes + 1); + state.values[nnodes] = NULL; + } + + g_tree_foreach (tree, g_settings_backend_flatten_one, &state); + g_return_if_fail (*keys + nnodes == state.keys); + + *path = state.prefix; + while (nnodes--) + *--state.keys += state.prefix_len; +} + +/** + * g_settings_backend_changed_tree: + * @backend: a #GSettingsBackend implementation + * @tree: a #GTree containing the changes + * @origin_tag: the origin tag + * + * This call is a convenience wrapper. It gets the list of changes from + * @tree, computes the longest common prefix and calls + * g_settings_backend_changed(). + * + * Since: 2.26 + **/ +void +g_settings_backend_changed_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag) +{ + const gchar **keys; + gchar *path; + + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); + + g_settings_backend_flatten_tree (tree, &path, &keys, NULL); + +#ifdef DEBUG_CHANGES + { + gint i; + + g_print ("----\n"); + g_print ("changed_tree(): prefix %s\n", path); + for (i = 0; keys[i]; i++) + g_print (" %s\n", keys[i]); + g_print ("----\n"); + } +#endif + + g_settings_backend_keys_changed (backend, path, keys, origin_tag); + g_free (path); + g_free (keys); +} + +/*< private > + * g_settings_backend_read: + * @backend: a #GSettingsBackend implementation + * @key: the key to read + * @expected_type: a #GVariantType + * @default_value: if the default value should be returned + * + * Reads a key. This call will never block. + * + * If the key exists, the value associated with it will be returned. + * If the key does not exist, %NULL will be returned. + * + * The returned value will be of the type given in @expected_type. If + * the backend stored a value of a different type then %NULL will be + * returned. + * + * If @default_value is %TRUE then this gets the default value from the + * backend (ie: the one that the backend would contain if + * g_settings_reset() were called). + * + * Returns: (nullable) (transfer full): the value that was read, or %NULL + */ +GVariant * +g_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value) +{ + GVariant *value; + + value = G_SETTINGS_BACKEND_GET_CLASS (backend) + ->read (backend, key, expected_type, default_value); + + if (value != NULL) + value = g_variant_take_ref (value); + + if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type)) + { + g_variant_unref (value); + value = NULL; + } + + return value; +} + +/*< private > + * g_settings_backend_read_user_value: + * @backend: a #GSettingsBackend implementation + * @key: the key to read + * @expected_type: a #GVariantType + * + * Reads the 'user value' of a key. + * + * This is the value of the key that the user has control over and has + * set for themselves. Put another way: if the user did not set the + * value for themselves, then this will return %NULL (even if the + * sysadmin has provided a default value). + * + * Returns: (nullable) (transfer full): the value that was read, or %NULL + */ +GVariant * +g_settings_backend_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type) +{ + GVariant *value; + + value = G_SETTINGS_BACKEND_GET_CLASS (backend) + ->read_user_value (backend, key, expected_type); + + if (value != NULL) + value = g_variant_take_ref (value); + + if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type)) + { + g_variant_unref (value); + value = NULL; + } + + return value; +} + +/*< private > + * g_settings_backend_write: + * @backend: a #GSettingsBackend implementation + * @key: the name of the key + * @value: a #GVariant value to write to this key + * @origin_tag: the origin tag + * + * Writes exactly one key. + * + * This call does not fail. During this call a + * #GSettingsBackend::changed signal will be emitted if the value of the + * key has changed. The updated key value will be visible to any signal + * callbacks. + * + * One possible method that an implementation might deal with failures is + * to emit a second "changed" signal (either during this call, or later) + * to indicate that the affected keys have suddenly "changed back" to their + * old values. + * + * If @value has a floating reference, it will be sunk. + * + * Returns: %TRUE if the write succeeded, %FALSE if the key was not writable + */ +gboolean +g_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag) +{ + gboolean success; + + g_variant_ref_sink (value); + success = G_SETTINGS_BACKEND_GET_CLASS (backend) + ->write (backend, key, value, origin_tag); + g_variant_unref (value); + + return success; +} + +/*< private > + * g_settings_backend_write_tree: + * @backend: a #GSettingsBackend implementation + * @tree: a #GTree containing key-value pairs to write + * @origin_tag: the origin tag + * + * Writes one or more keys. This call will never block. + * + * The key of each item in the tree is the key name to write to and the + * value is a #GVariant to write. The proper type of #GTree for this + * call can be created with g_settings_backend_create_tree(). This call + * might take a reference to the tree; you must not modified the #GTree + * after passing it to this call. + * + * This call does not fail. During this call a #GSettingsBackend::changed + * signal will be emitted if any keys have been changed. The new values of + * all updated keys will be visible to any signal callbacks. + * + * One possible method that an implementation might deal with failures is + * to emit a second "changed" signal (either during this call, or later) + * to indicate that the affected keys have suddenly "changed back" to their + * old values. + */ +gboolean +g_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag) +{ + return G_SETTINGS_BACKEND_GET_CLASS (backend) + ->write_tree (backend, tree, origin_tag); +} + +/*< private > + * g_settings_backend_reset: + * @backend: a #GSettingsBackend implementation + * @key: the name of a key + * @origin_tag: the origin tag + * + * "Resets" the named key to its "default" value (ie: after system-wide + * defaults, mandatory keys, etc. have been taken into account) or possibly + * unsets it. + */ +void +g_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag) +{ + G_SETTINGS_BACKEND_GET_CLASS (backend) + ->reset (backend, key, origin_tag); +} + +/*< private > + * g_settings_backend_get_writable: + * @backend: a #GSettingsBackend implementation + * @key: the name of a key + * + * Finds out if a key is available for writing to. This is the + * interface through which 'lockdown' is implemented. Locked down + * keys will have %FALSE returned by this call. + * + * You should not write to locked-down keys, but if you do, the + * implementation will deal with it. + * + * Returns: %TRUE if the key is writable + */ +gboolean +g_settings_backend_get_writable (GSettingsBackend *backend, + const gchar *key) +{ + return G_SETTINGS_BACKEND_GET_CLASS (backend) + ->get_writable (backend, key); +} + +/*< private > + * g_settings_backend_unsubscribe: + * @backend: a #GSettingsBackend + * @name: a key or path to subscribe to + * + * Reverses the effect of a previous call to + * g_settings_backend_subscribe(). + */ +void +g_settings_backend_unsubscribe (GSettingsBackend *backend, + const char *name) +{ + G_SETTINGS_BACKEND_GET_CLASS (backend) + ->unsubscribe (backend, name); +} + +/*< private > + * g_settings_backend_subscribe: + * @backend: a #GSettingsBackend + * @name: a key or path to subscribe to + * + * Requests that change signals be emitted for events on @name. + */ +void +g_settings_backend_subscribe (GSettingsBackend *backend, + const gchar *name) +{ + G_SETTINGS_BACKEND_GET_CLASS (backend) + ->subscribe (backend, name); +} + +static void +g_settings_backend_finalize (GObject *object) +{ + GSettingsBackend *backend = G_SETTINGS_BACKEND (object); + + g_mutex_clear (&backend->priv->lock); + + G_OBJECT_CLASS (g_settings_backend_parent_class) + ->finalize (object); +} + +static void +ignore_subscription (GSettingsBackend *backend, + const gchar *key) +{ +} + +static GVariant * +g_settings_backend_real_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type) +{ + return g_settings_backend_read (backend, key, expected_type, FALSE); +} + +static void +g_settings_backend_init (GSettingsBackend *backend) +{ + backend->priv = g_settings_backend_get_instance_private (backend); + g_mutex_init (&backend->priv->lock); +} + +static void +g_settings_backend_class_init (GSettingsBackendClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + class->subscribe = ignore_subscription; + class->unsubscribe = ignore_subscription; + + class->read_user_value = g_settings_backend_real_read_user_value; + + gobject_class->finalize = g_settings_backend_finalize; +} + +static void +g_settings_backend_variant_unref0 (gpointer data) +{ + if (data != NULL) + g_variant_unref (data); +} + +/*< private > + * g_settings_backend_create_tree: + * + * This is a convenience function for creating a tree that is compatible + * with g_settings_backend_write(). It merely calls g_tree_new_full() + * with strcmp(), g_free() and g_variant_unref(). + * + * Returns: a new #GTree + */ +GTree * +g_settings_backend_create_tree (void) +{ + return g_tree_new_full ((GCompareDataFunc) strcmp, NULL, + g_free, g_settings_backend_variant_unref0); +} + +static gboolean +g_settings_backend_verify (gpointer impl) +{ + GSettingsBackend *backend = impl; + + if (strcmp (G_OBJECT_TYPE_NAME (backend), "GMemorySettingsBackend") == 0 && + g_strcmp0 (g_getenv ("GSETTINGS_BACKEND"), "memory") != 0) + { + g_message ("Using the 'memory' GSettings backend. Your settings " + "will not be saved or shared with other applications."); + } + + g_settings_has_backend = TRUE; + return TRUE; +} + +/* We need to cache the default #GSettingsBackend for the entire process + * lifetime, especially if the backend is #GMemorySettingsBackend: it needs to + * keep the in-memory settings around even while there are no #GSettings + * instances alive. */ +static GSettingsBackend *settings_backend_default_singleton = NULL; /* (owned) (atomic) */ + +/** + * g_settings_backend_get_default: + * + * Returns the default #GSettingsBackend. It is possible to override + * the default by setting the `GSETTINGS_BACKEND` environment variable + * to the name of a settings backend. + * + * The user gets a reference to the backend. + * + * Returns: (not nullable) (transfer full): the default #GSettingsBackend, + * which will be a dummy (memory) settings backend if no other settings + * backend is available. + * + * Since: 2.28 + */ +GSettingsBackend * +g_settings_backend_get_default (void) +{ + if (g_once_init_enter (&settings_backend_default_singleton)) + { + GSettingsBackend *singleton; + + singleton = _g_io_module_get_default (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, + "GSETTINGS_BACKEND", + g_settings_backend_verify); + + g_once_init_leave (&settings_backend_default_singleton, singleton); + } + + return g_object_ref (settings_backend_default_singleton); +} + +/*< private > + * g_settings_backend_get_permission: + * @backend: a #GSettingsBackend + * @path: a path + * + * Gets the permission object associated with writing to keys below + * @path on @backend. + * + * If this is not implemented in the backend, then a %TRUE + * #GSimplePermission is returned. + * + * Returns: (not nullable) (transfer full): a non-%NULL #GPermission. + * Free with g_object_unref() + */ +GPermission * +g_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path) +{ + GSettingsBackendClass *class = G_SETTINGS_BACKEND_GET_CLASS (backend); + + if (class->get_permission) + return class->get_permission (backend, path); + + return g_simple_permission_new (TRUE); +} + +/*< private > + * g_settings_backend_sync_default: + * + * Syncs the default backend. + */ +void +g_settings_backend_sync_default (void) +{ + if (g_settings_has_backend) + { + GSettingsBackendClass *class; + GSettingsBackend *backend; + + backend = g_settings_backend_get_default (); + class = G_SETTINGS_BACKEND_GET_CLASS (backend); + + if (class->sync) + class->sync (backend); + + g_object_unref (backend); + } +} diff --git a/gio/gsettingsbackend.h b/gio/gsettingsbackend.h new file mode 100644 index 0000000..34bae6b --- /dev/null +++ b/gio/gsettingsbackend.h @@ -0,0 +1,174 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * Copyright © 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Matthias Clasen + */ + +#ifndef __G_SETTINGS_BACKEND_H__ +#define __G_SETTINGS_BACKEND_H__ + +#if !defined (G_SETTINGS_ENABLE_BACKEND) && !defined (GIO_COMPILATION) +#error "You must define G_SETTINGS_ENABLE_BACKEND before including ." +#endif + +#define __GIO_GIO_H_INSIDE__ +#include +#undef __GIO_GIO_H_INSIDE__ + +G_BEGIN_DECLS + +#define G_TYPE_SETTINGS_BACKEND (g_settings_backend_get_type ()) +#define G_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SETTINGS_BACKEND, GSettingsBackend)) +#define G_SETTINGS_BACKEND_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SETTINGS_BACKEND, GSettingsBackendClass)) +#define G_IS_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SETTINGS_BACKEND)) +#define G_IS_SETTINGS_BACKEND_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SETTINGS_BACKEND)) +#define G_SETTINGS_BACKEND_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SETTINGS_BACKEND, GSettingsBackendClass)) + +/** + * G_SETTINGS_BACKEND_EXTENSION_POINT_NAME: + * + * Extension point for #GSettingsBackend functionality. + **/ +#define G_SETTINGS_BACKEND_EXTENSION_POINT_NAME "gsettings-backend" + +/** + * GSettingsBackend: + * + * An implementation of a settings storage repository. + **/ +typedef struct _GSettingsBackendPrivate GSettingsBackendPrivate; +typedef struct _GSettingsBackendClass GSettingsBackendClass; + +/** + * GSettingsBackendClass: + * @read: virtual method to read a key's value + * @get_writable: virtual method to get if a key is writable + * @write: virtual method to change key's value + * @write_tree: virtual method to change a tree of keys + * @reset: virtual method to reset state + * @subscribe: virtual method to subscribe to key changes + * @unsubscribe: virtual method to unsubscribe to key changes + * @sync: virtual method to sync state + * @get_permission: virtual method to get permission of a key + * @read_user_value: virtual method to read user's key value + * + * Class structure for #GSettingsBackend. + */ +struct _GSettingsBackendClass +{ + GObjectClass parent_class; + + GVariant * (*read) (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value); + + gboolean (*get_writable) (GSettingsBackend *backend, + const gchar *key); + + gboolean (*write) (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag); + gboolean (*write_tree) (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag); + void (*reset) (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag); + + void (*subscribe) (GSettingsBackend *backend, + const gchar *name); + void (*unsubscribe) (GSettingsBackend *backend, + const gchar *name); + void (*sync) (GSettingsBackend *backend); + + GPermission * (*get_permission) (GSettingsBackend *backend, + const gchar *path); + + GVariant * (*read_user_value) (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type); + + /*< private >*/ + gpointer padding[23]; +}; + +struct _GSettingsBackend +{ + GObject parent_instance; + + /*< private >*/ + GSettingsBackendPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_settings_backend_get_type (void); + +GLIB_AVAILABLE_IN_ALL +void g_settings_backend_changed (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag); +GLIB_AVAILABLE_IN_ALL +void g_settings_backend_path_changed (GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag); +GLIB_AVAILABLE_IN_ALL +void g_settings_backend_flatten_tree (GTree *tree, + gchar **path, + const gchar ***keys, + GVariant ***values); +GLIB_AVAILABLE_IN_ALL +void g_settings_backend_keys_changed (GSettingsBackend *backend, + const gchar *path, + gchar const * const *items, + gpointer origin_tag); + +GLIB_AVAILABLE_IN_ALL +void g_settings_backend_path_writable_changed (GSettingsBackend *backend, + const gchar *path); +GLIB_AVAILABLE_IN_ALL +void g_settings_backend_writable_changed (GSettingsBackend *backend, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +void g_settings_backend_changed_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag); + +GLIB_AVAILABLE_IN_ALL +GSettingsBackend * g_settings_backend_get_default (void); + +GLIB_AVAILABLE_IN_ALL +GSettingsBackend * g_keyfile_settings_backend_new (const gchar *filename, + const gchar *root_path, + const gchar *root_group); + +GLIB_AVAILABLE_IN_ALL +GSettingsBackend * g_null_settings_backend_new (void); + +GLIB_AVAILABLE_IN_ALL +GSettingsBackend * g_memory_settings_backend_new (void); + +G_END_DECLS + +#endif /* __G_SETTINGS_BACKEND_H__ */ diff --git a/gio/gsettingsbackendinternal.h b/gio/gsettingsbackendinternal.h new file mode 100644 index 0000000..9e1d51d --- /dev/null +++ b/gio/gsettingsbackendinternal.h @@ -0,0 +1,96 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * Copyright © 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Matthias Clasen + */ + +#ifndef __G_SETTINGS_BACKEND_INTERNAL_H__ +#define __G_SETTINGS_BACKEND_INTERNAL_H__ + +#include "gsettingsbackend.h" + +typedef struct +{ + void (* changed) (GObject *target, + GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag); + void (* path_changed) (GObject *target, + GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag); + void (* keys_changed) (GObject *target, + GSettingsBackend *backend, + const gchar *prefix, + gpointer origin_tag, + const gchar * const *names); + void (* writable_changed) (GObject *target, + GSettingsBackend *backend, + const gchar *key); + void (* path_writable_changed) (GObject *target, + GSettingsBackend *backend, + const gchar *path); +} GSettingsListenerVTable; + +void g_settings_backend_watch (GSettingsBackend *backend, + const GSettingsListenerVTable *vtable, + GObject *target, + GMainContext *context); +void g_settings_backend_unwatch (GSettingsBackend *backend, + GObject *target); + +GTree * g_settings_backend_create_tree (void); + +GVariant * g_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value); +GVariant * g_settings_backend_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type); +gboolean g_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag); +gboolean g_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag); +void g_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag); +gboolean g_settings_backend_get_writable (GSettingsBackend *backend, + const char *key); +void g_settings_backend_unsubscribe (GSettingsBackend *backend, + const char *name); +void g_settings_backend_subscribe (GSettingsBackend *backend, + const char *name); +GPermission * g_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path); +void g_settings_backend_sync_default (void); + +GType g_null_settings_backend_get_type (void); + +GType g_memory_settings_backend_get_type (void); + +GType g_keyfile_settings_backend_get_type (void); + +#ifdef HAVE_COCOA +GType g_nextstep_settings_backend_get_type (void); +#endif + +#endif /* __G_SETTINGS_BACKEND_INTERNAL_H__ */ diff --git a/gio/gsettingsschema-internal.h b/gio/gsettingsschema-internal.h new file mode 100644 index 0000000..416cf2d --- /dev/null +++ b/gio/gsettingsschema-internal.h @@ -0,0 +1,76 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __G_SETTINGS_SCHEMA_INTERNAL_H__ +#define __G_SETTINGS_SCHEMA_INTERNAL_H__ + +#include "gsettingsschema.h" + +struct _GSettingsSchemaKey +{ + GSettingsSchema *schema; + const gchar *name; + + guint is_flags : 1; + guint is_enum : 1; + + const guint32 *strinfo; + gsize strinfo_length; + + const gchar *unparsed; + gchar lc_char; + + const GVariantType *type; + GVariant *minimum, *maximum; + GVariant *default_value; + GVariant *desktop_overrides; + + gint ref_count; +}; + +const gchar * g_settings_schema_get_gettext_domain (GSettingsSchema *schema); +GVariantIter * g_settings_schema_get_value (GSettingsSchema *schema, + const gchar *key); +const GQuark * g_settings_schema_list (GSettingsSchema *schema, + gint *n_items); +const gchar * g_settings_schema_get_string (GSettingsSchema *schema, + const gchar *key); + +GSettingsSchema * g_settings_schema_get_child_schema (GSettingsSchema *schema, + const gchar *name); + +void g_settings_schema_key_init (GSettingsSchemaKey *key, + GSettingsSchema *schema, + const gchar *name); +void g_settings_schema_key_clear (GSettingsSchemaKey *key); +gboolean g_settings_schema_key_type_check (GSettingsSchemaKey *key, + GVariant *value); +GVariant * g_settings_schema_key_range_fixup (GSettingsSchemaKey *key, + GVariant *value); +GVariant * g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key); +GVariant * g_settings_schema_key_get_per_desktop_default (GSettingsSchemaKey *key); + +gint g_settings_schema_key_to_enum (GSettingsSchemaKey *key, + GVariant *value); +GVariant * g_settings_schema_key_from_enum (GSettingsSchemaKey *key, + gint value); +guint g_settings_schema_key_to_flags (GSettingsSchemaKey *key, + GVariant *value); +GVariant * g_settings_schema_key_from_flags (GSettingsSchemaKey *key, + guint value); + +#endif /* __G_SETTINGS_SCHEMA_INTERNAL_H__ */ diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c new file mode 100644 index 0000000..ef4ec17 --- /dev/null +++ b/gio/gsettingsschema.c @@ -0,0 +1,1901 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" + +#include "glib-private.h" +#include "gsettingsschema-internal.h" +#include "gsettings.h" + +#include "gvdb/gvdb-reader.h" +#include "strinfo.c" + +#include +#include +#include +#include + +/** + * SECTION:gsettingsschema + * @short_description: Introspecting and controlling the loading + * of GSettings schemas + * @include: gio/gio.h + * + * The #GSettingsSchemaSource and #GSettingsSchema APIs provide a + * mechanism for advanced control over the loading of schemas and a + * mechanism for introspecting their content. + * + * Plugin loading systems that wish to provide plugins a way to access + * settings face the problem of how to make the schemas for these + * settings visible to GSettings. Typically, a plugin will want to ship + * the schema along with itself and it won't be installed into the + * standard system directories for schemas. + * + * #GSettingsSchemaSource provides a mechanism for dealing with this by + * allowing the creation of a new 'schema source' from which schemas can + * be acquired. This schema source can then become part of the metadata + * associated with the plugin and queried whenever the plugin requires + * access to some settings. + * + * Consider the following example: + * + * |[ + * typedef struct + * { + * ... + * GSettingsSchemaSource *schema_source; + * ... + * } Plugin; + * + * Plugin * + * initialise_plugin (const gchar *dir) + * { + * Plugin *plugin; + * + * ... + * + * plugin->schema_source = + * g_settings_schema_source_new_from_directory (dir, + * g_settings_schema_source_get_default (), FALSE, NULL); + * + * ... + * + * return plugin; + * } + * + * ... + * + * GSettings * + * plugin_get_settings (Plugin *plugin, + * const gchar *schema_id) + * { + * GSettingsSchema *schema; + * + * if (schema_id == NULL) + * schema_id = plugin->identifier; + * + * schema = g_settings_schema_source_lookup (plugin->schema_source, + * schema_id, FALSE); + * + * if (schema == NULL) + * { + * ... disable the plugin or abort, etc ... + * } + * + * return g_settings_new_full (schema, NULL, NULL); + * } + * ]| + * + * The code above shows how hooks should be added to the code that + * initialises (or enables) the plugin to create the schema source and + * how an API can be added to the plugin system to provide a convenient + * way for the plugin to access its settings, using the schemas that it + * ships. + * + * From the standpoint of the plugin, it would need to ensure that it + * ships a gschemas.compiled file as part of itself, and then simply do + * the following: + * + * |[ + * { + * GSettings *settings; + * gint some_value; + * + * settings = plugin_get_settings (self, NULL); + * some_value = g_settings_get_int (settings, "some-value"); + * ... + * } + * ]| + * + * It's also possible that the plugin system expects the schema source + * files (ie: .gschema.xml files) instead of a gschemas.compiled file. + * In that case, the plugin loading system must compile the schemas for + * itself before attempting to create the settings source. + * + * Since: 2.32 + **/ + +/** + * GSettingsSchemaKey: + * + * #GSettingsSchemaKey is an opaque data structure and can only be accessed + * using the following functions. + **/ + +/** + * GSettingsSchema: + * + * This is an opaque structure type. You may not access it directly. + * + * Since: 2.32 + **/ +struct _GSettingsSchema +{ + GSettingsSchemaSource *source; + const gchar *gettext_domain; + const gchar *path; + GQuark *items; + gint n_items; + GvdbTable *table; + gchar *id; + + GSettingsSchema *extends; + + gint ref_count; +}; + +/** + * G_TYPE_SETTINGS_SCHEMA_SOURCE: + * + * A boxed #GType corresponding to #GSettingsSchemaSource. + * + * Since: 2.32 + **/ +G_DEFINE_BOXED_TYPE (GSettingsSchemaSource, g_settings_schema_source, g_settings_schema_source_ref, g_settings_schema_source_unref) + +/** + * G_TYPE_SETTINGS_SCHEMA: + * + * A boxed #GType corresponding to #GSettingsSchema. + * + * Since: 2.32 + **/ +G_DEFINE_BOXED_TYPE (GSettingsSchema, g_settings_schema, g_settings_schema_ref, g_settings_schema_unref) + +/** + * GSettingsSchemaSource: + * + * This is an opaque structure type. You may not access it directly. + * + * Since: 2.32 + **/ +struct _GSettingsSchemaSource +{ + GSettingsSchemaSource *parent; + gchar *directory; + GvdbTable *table; + GHashTable **text_tables; + + gint ref_count; +}; + +static GSettingsSchemaSource *schema_sources; + +/** + * g_settings_schema_source_ref: + * @source: a #GSettingsSchemaSource + * + * Increase the reference count of @source, returning a new reference. + * + * Returns: (transfer full) (not nullable): a new reference to @source + * + * Since: 2.32 + **/ +GSettingsSchemaSource * +g_settings_schema_source_ref (GSettingsSchemaSource *source) +{ + g_atomic_int_inc (&source->ref_count); + + return source; +} + +/** + * g_settings_schema_source_unref: + * @source: a #GSettingsSchemaSource + * + * Decrease the reference count of @source, possibly freeing it. + * + * Since: 2.32 + **/ +void +g_settings_schema_source_unref (GSettingsSchemaSource *source) +{ + if (g_atomic_int_dec_and_test (&source->ref_count)) + { + if (source == schema_sources) + g_error ("g_settings_schema_source_unref() called too many times on the default schema source"); + + if (source->parent) + g_settings_schema_source_unref (source->parent); + gvdb_table_free (source->table); + g_free (source->directory); + + if (source->text_tables) + { + g_hash_table_unref (source->text_tables[0]); + g_hash_table_unref (source->text_tables[1]); + g_free (source->text_tables); + } + + g_slice_free (GSettingsSchemaSource, source); + } +} + +/** + * g_settings_schema_source_new_from_directory: + * @directory: (type filename): the filename of a directory + * @parent: (nullable): a #GSettingsSchemaSource, or %NULL + * @trusted: %TRUE, if the directory is trusted + * @error: a pointer to a #GError pointer set to %NULL, or %NULL + * + * Attempts to create a new schema source corresponding to the contents + * of the given directory. + * + * This function is not required for normal uses of #GSettings but it + * may be useful to authors of plugin management systems. + * + * The directory should contain a file called `gschemas.compiled` as + * produced by the [glib-compile-schemas][glib-compile-schemas] tool. + * + * If @trusted is %TRUE then `gschemas.compiled` is trusted not to be + * corrupted. This assumption has a performance advantage, but can result + * in crashes or inconsistent behaviour in the case of a corrupted file. + * Generally, you should set @trusted to %TRUE for files installed by the + * system and to %FALSE for files in the home directory. + * + * In either case, an empty file or some types of corruption in the file will + * result in %G_FILE_ERROR_INVAL being returned. + * + * If @parent is non-%NULL then there are two effects. + * + * First, if g_settings_schema_source_lookup() is called with the + * @recursive flag set to %TRUE and the schema can not be found in the + * source, the lookup will recurse to the parent. + * + * Second, any references to other schemas specified within this + * source (ie: `child` or `extends`) references may be resolved + * from the @parent. + * + * For this second reason, except in very unusual situations, the + * @parent should probably be given as the default schema source, as + * returned by g_settings_schema_source_get_default(). + * + * Since: 2.32 + **/ +GSettingsSchemaSource * +g_settings_schema_source_new_from_directory (const gchar *directory, + GSettingsSchemaSource *parent, + gboolean trusted, + GError **error) +{ + GSettingsSchemaSource *source; + GvdbTable *table; + gchar *filename; + + filename = g_build_filename (directory, "gschemas.compiled", NULL); + table = gvdb_table_new (filename, trusted, error); + g_free (filename); + + if (table == NULL) + return NULL; + + source = g_slice_new (GSettingsSchemaSource); + source->directory = g_strdup (directory); + source->parent = parent ? g_settings_schema_source_ref (parent) : NULL; + source->text_tables = NULL; + source->table = table; + source->ref_count = 1; + + return source; +} + +static void +try_prepend_dir (const gchar *directory) +{ + GSettingsSchemaSource *source; + + source = g_settings_schema_source_new_from_directory (directory, schema_sources, TRUE, NULL); + + /* If we successfully created it then prepend it to the global list */ + if (source != NULL) + schema_sources = source; +} + +static void +try_prepend_data_dir (const gchar *directory) +{ + gchar *dirname = g_build_filename (directory, "glib-2.0", "schemas", NULL); + try_prepend_dir (dirname); + g_free (dirname); +} + +static void +initialise_schema_sources (void) +{ + static gsize initialised; + + /* need a separate variable because 'schema_sources' may legitimately + * be null if we have zero valid schema sources + */ + if G_UNLIKELY (g_once_init_enter (&initialised)) + { + gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) (); + const gchar * const *dirs; + const gchar *path; + gchar **extra_schema_dirs; + gint i; + + /* iterate in reverse: count up, then count down */ + dirs = g_get_system_data_dirs (); + for (i = 0; dirs[i]; i++); + + while (i--) + try_prepend_data_dir (dirs[i]); + + try_prepend_data_dir (g_get_user_data_dir ()); + + /* Disallow loading extra schemas if running as setuid, as that could + * allow reading privileged files. */ + if (!is_setuid && (path = g_getenv ("GSETTINGS_SCHEMA_DIR")) != NULL) + { + extra_schema_dirs = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, 0); + for (i = 0; extra_schema_dirs[i]; i++); + + while (i--) + try_prepend_dir (extra_schema_dirs[i]); + + g_strfreev (extra_schema_dirs); + } + + g_once_init_leave (&initialised, TRUE); + } +} + +/** + * g_settings_schema_source_get_default: + * + * Gets the default system schema source. + * + * This function is not required for normal uses of #GSettings but it + * may be useful to authors of plugin management systems or to those who + * want to introspect the content of schemas. + * + * If no schemas are installed, %NULL will be returned. + * + * The returned source may actually consist of multiple schema sources + * from different directories, depending on which directories were given + * in `XDG_DATA_DIRS` and `GSETTINGS_SCHEMA_DIR`. For this reason, all + * lookups performed against the default source should probably be done + * recursively. + * + * Returns: (transfer none) (nullable): the default schema source + * + * Since: 2.32 + **/ +GSettingsSchemaSource * +g_settings_schema_source_get_default (void) +{ + initialise_schema_sources (); + + return schema_sources; +} + +/** + * g_settings_schema_source_lookup: + * @source: a #GSettingsSchemaSource + * @schema_id: a schema ID + * @recursive: %TRUE if the lookup should be recursive + * + * Looks up a schema with the identifier @schema_id in @source. + * + * This function is not required for normal uses of #GSettings but it + * may be useful to authors of plugin management systems or to those who + * want to introspect the content of schemas. + * + * If the schema isn't found directly in @source and @recursive is %TRUE + * then the parent sources will also be checked. + * + * If the schema isn't found, %NULL is returned. + * + * Returns: (nullable) (transfer full): a new #GSettingsSchema + * + * Since: 2.32 + **/ +GSettingsSchema * +g_settings_schema_source_lookup (GSettingsSchemaSource *source, + const gchar *schema_id, + gboolean recursive) +{ + GSettingsSchema *schema; + GvdbTable *table; + const gchar *extends; + + g_return_val_if_fail (source != NULL, NULL); + g_return_val_if_fail (schema_id != NULL, NULL); + + table = gvdb_table_get_table (source->table, schema_id); + + if (table == NULL && recursive) + for (source = source->parent; source; source = source->parent) + if ((table = gvdb_table_get_table (source->table, schema_id))) + break; + + if (table == NULL) + return NULL; + + schema = g_slice_new0 (GSettingsSchema); + schema->source = g_settings_schema_source_ref (source); + schema->ref_count = 1; + schema->id = g_strdup (schema_id); + schema->table = table; + schema->path = g_settings_schema_get_string (schema, ".path"); + schema->gettext_domain = g_settings_schema_get_string (schema, ".gettext-domain"); + + if (schema->gettext_domain) + bind_textdomain_codeset (schema->gettext_domain, "UTF-8"); + + extends = g_settings_schema_get_string (schema, ".extends"); + if (extends) + { + schema->extends = g_settings_schema_source_lookup (source, extends, TRUE); + if (schema->extends == NULL) + g_warning ("Schema '%s' extends schema '%s' but we could not find it", schema_id, extends); + } + + return schema; +} + +typedef struct +{ + GHashTable *summaries; + GHashTable *descriptions; + GSList *gettext_domain; + GSList *schema_id; + GSList *key_name; + GString *string; +} TextTableParseInfo; + +static const gchar * +get_attribute_value (GSList *list) +{ + GSList *node; + + for (node = list; node; node = node->next) + if (node->data) + return node->data; + + return NULL; +} + +static void +pop_attribute_value (GSList **list) +{ + gchar *top; + + top = (*list)->data; + *list = g_slist_remove (*list, top); + + g_free (top); +} + +static void +push_attribute_value (GSList **list, + const gchar *value) +{ + *list = g_slist_prepend (*list, g_strdup (value)); +} + +static void +start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + TextTableParseInfo *info = user_data; + const gchar *gettext_domain = NULL; + const gchar *schema_id = NULL; + const gchar *key_name = NULL; + gint i; + + for (i = 0; attribute_names[i]; i++) + { + if (g_str_equal (attribute_names[i], "gettext-domain")) + gettext_domain = attribute_values[i]; + else if (g_str_equal (attribute_names[i], "id")) + schema_id = attribute_values[i]; + else if (g_str_equal (attribute_names[i], "name")) + key_name = attribute_values[i]; + } + + push_attribute_value (&info->gettext_domain, gettext_domain); + push_attribute_value (&info->schema_id, schema_id); + push_attribute_value (&info->key_name, key_name); + + if (info->string) + { + g_string_free (info->string, TRUE); + info->string = NULL; + } + + if (g_str_equal (element_name, "summary") || g_str_equal (element_name, "description")) + info->string = g_string_new (NULL); +} + +static gchar * +normalise_whitespace (const gchar *orig) +{ + /* We normalise by the same rules as in intltool: + * + * sub cleanup { + * s/^\s+//; + * s/\s+$//; + * s/\s+/ /g; + * return $_; + * } + * + * $message = join "\n\n", map &cleanup, split/\n\s*\n+/, $message; + * + * Where \s is an ascii space character. + * + * We aim for ease of implementation over efficiency -- this code is + * not run in normal applications. + */ + static GRegex *cleanup[3]; + static GRegex *splitter; + gchar **lines; + gchar *result; + gint i; + + if (g_once_init_enter (&splitter)) + { + GRegex *s; + + cleanup[0] = g_regex_new ("^\\s+", 0, 0, 0); + cleanup[1] = g_regex_new ("\\s+$", 0, 0, 0); + cleanup[2] = g_regex_new ("\\s+", 0, 0, 0); + s = g_regex_new ("\\n\\s*\\n+", 0, 0, 0); + + g_once_init_leave (&splitter, s); + } + + lines = g_regex_split (splitter, orig, 0); + for (i = 0; lines[i]; i++) + { + gchar *a, *b, *c; + + a = g_regex_replace_literal (cleanup[0], lines[i], -1, 0, "", 0, 0); + b = g_regex_replace_literal (cleanup[1], a, -1, 0, "", 0, 0); + c = g_regex_replace_literal (cleanup[2], b, -1, 0, " ", 0, 0); + g_free (lines[i]); + g_free (a); + g_free (b); + lines[i] = c; + } + + result = g_strjoinv ("\n\n", lines); + g_strfreev (lines); + + return result; +} + +static void +end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + TextTableParseInfo *info = user_data; + + pop_attribute_value (&info->gettext_domain); + pop_attribute_value (&info->schema_id); + pop_attribute_value (&info->key_name); + + if (info->string) + { + GHashTable *source_table = NULL; + const gchar *gettext_domain; + const gchar *schema_id; + const gchar *key_name; + + gettext_domain = get_attribute_value (info->gettext_domain); + schema_id = get_attribute_value (info->schema_id); + key_name = get_attribute_value (info->key_name); + + if (g_str_equal (element_name, "summary")) + source_table = info->summaries; + else if (g_str_equal (element_name, "description")) + source_table = info->descriptions; + + if (source_table && schema_id && key_name) + { + GHashTable *schema_table; + gchar *normalised; + + schema_table = g_hash_table_lookup (source_table, schema_id); + + if (schema_table == NULL) + { + schema_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + g_hash_table_insert (source_table, g_strdup (schema_id), schema_table); + } + + normalised = normalise_whitespace (info->string->str); + + if (gettext_domain && normalised[0]) + { + gchar *translated; + + translated = g_strdup (g_dgettext (gettext_domain, normalised)); + g_free (normalised); + normalised = translated; + } + + g_hash_table_insert (schema_table, g_strdup (key_name), normalised); + } + + g_string_free (info->string, TRUE); + info->string = NULL; + } +} + +static void +text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + TextTableParseInfo *info = user_data; + + if (info->string) + g_string_append_len (info->string, text, text_len); +} + +static void +parse_into_text_tables (const gchar *directory, + GHashTable *summaries, + GHashTable *descriptions) +{ + GMarkupParser parser = { start_element, end_element, text, NULL, NULL }; + TextTableParseInfo info = { summaries, descriptions, NULL, NULL, NULL, NULL }; + const gchar *basename; + GDir *dir; + + dir = g_dir_open (directory, 0, NULL); + while ((basename = g_dir_read_name (dir))) + { + gchar *filename; + gchar *contents; + gsize size; + + filename = g_build_filename (directory, basename, NULL); + if (g_file_get_contents (filename, &contents, &size, NULL)) + { + GMarkupParseContext *context; + + context = g_markup_parse_context_new (&parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &info, NULL); + /* Ignore errors here, this is best effort only. */ + if (g_markup_parse_context_parse (context, contents, size, NULL)) + (void) g_markup_parse_context_end_parse (context, NULL); + g_markup_parse_context_free (context); + + /* Clean up dangling stuff in case there was an error. */ + g_slist_free_full (info.gettext_domain, g_free); + g_slist_free_full (info.schema_id, g_free); + g_slist_free_full (info.key_name, g_free); + + info.gettext_domain = NULL; + info.schema_id = NULL; + info.key_name = NULL; + + if (info.string) + { + g_string_free (info.string, TRUE); + info.string = NULL; + } + + g_free (contents); + } + + g_free (filename); + } + + g_dir_close (dir); +} + +static GHashTable ** +g_settings_schema_source_get_text_tables (GSettingsSchemaSource *source) +{ + if (g_once_init_enter (&source->text_tables)) + { + GHashTable **text_tables; + + text_tables = g_new (GHashTable *, 2); + text_tables[0] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_unref); + text_tables[1] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_unref); + + if (source->directory) + parse_into_text_tables (source->directory, text_tables[0], text_tables[1]); + + g_once_init_leave (&source->text_tables, text_tables); + } + + return source->text_tables; +} + +/** + * g_settings_schema_source_list_schemas: + * @source: a #GSettingsSchemaSource + * @recursive: if we should recurse + * @non_relocatable: (out) (transfer full) (array zero-terminated=1): the + * list of non-relocatable schemas, in no defined order + * @relocatable: (out) (transfer full) (array zero-terminated=1): the list + * of relocatable schemas, in no defined order + * + * Lists the schemas in a given source. + * + * If @recursive is %TRUE then include parent sources. If %FALSE then + * only include the schemas from one source (ie: one directory). You + * probably want %TRUE. + * + * Non-relocatable schemas are those for which you can call + * g_settings_new(). Relocatable schemas are those for which you must + * use g_settings_new_with_path(). + * + * Do not call this function from normal programs. This is designed for + * use by database editors, commandline tools, etc. + * + * Since: 2.40 + **/ +void +g_settings_schema_source_list_schemas (GSettingsSchemaSource *source, + gboolean recursive, + gchar ***non_relocatable, + gchar ***relocatable) +{ + GHashTable *single, *reloc; + GSettingsSchemaSource *s; + + /* We use hash tables to avoid duplicate listings for schemas that + * appear in more than one file. + */ + single = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + reloc = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + for (s = source; s; s = s->parent) + { + gchar **list; + gint i; + + list = gvdb_table_list (s->table, ""); + + /* empty schema cache file? */ + if (list == NULL) + continue; + + for (i = 0; list[i]; i++) + { + if (!g_hash_table_contains (single, list[i]) && + !g_hash_table_contains (reloc, list[i])) + { + gchar *schema; + GvdbTable *table; + + schema = g_strdup (list[i]); + + table = gvdb_table_get_table (s->table, list[i]); + g_assert (table != NULL); + + if (gvdb_table_has_value (table, ".path")) + g_hash_table_add (single, schema); + else + g_hash_table_add (reloc, schema); + + gvdb_table_free (table); + } + } + + g_strfreev (list); + + /* Only the first source if recursive not requested */ + if (!recursive) + break; + } + + if (non_relocatable) + { + *non_relocatable = (gchar **) g_hash_table_get_keys_as_array (single, NULL); + g_hash_table_steal_all (single); + } + + if (relocatable) + { + *relocatable = (gchar **) g_hash_table_get_keys_as_array (reloc, NULL); + g_hash_table_steal_all (reloc); + } + + g_hash_table_unref (single); + g_hash_table_unref (reloc); +} + +static gchar **non_relocatable_schema_list; +static gchar **relocatable_schema_list; +static gsize schema_lists_initialised; + +static void +ensure_schema_lists (void) +{ + if (g_once_init_enter (&schema_lists_initialised)) + { + initialise_schema_sources (); + + g_settings_schema_source_list_schemas (schema_sources, TRUE, + &non_relocatable_schema_list, + &relocatable_schema_list); + + g_once_init_leave (&schema_lists_initialised, TRUE); + } +} + +/** + * g_settings_list_schemas: + * + * Deprecated. + * + * Returns: (element-type utf8) (transfer none) (not nullable): a list of + * #GSettings schemas that are available, in no defined order. The list + * must not be modified or freed. + * + * Since: 2.26 + * + * Deprecated: 2.40: Use g_settings_schema_source_list_schemas() instead. + * If you used g_settings_list_schemas() to check for the presence of + * a particular schema, use g_settings_schema_source_lookup() instead + * of your whole loop. + **/ +const gchar * const * +g_settings_list_schemas (void) +{ + ensure_schema_lists (); + + return (const gchar **) non_relocatable_schema_list; +} + +/** + * g_settings_list_relocatable_schemas: + * + * Deprecated. + * + * Returns: (element-type utf8) (transfer none) (not nullable): a list of + * relocatable #GSettings schemas that are available, in no defined order. + * The list must not be modified or freed. + * + * Since: 2.28 + * + * Deprecated: 2.40: Use g_settings_schema_source_list_schemas() instead + **/ +const gchar * const * +g_settings_list_relocatable_schemas (void) +{ + ensure_schema_lists (); + + return (const gchar **) relocatable_schema_list; +} + +/** + * g_settings_schema_ref: + * @schema: a #GSettingsSchema + * + * Increase the reference count of @schema, returning a new reference. + * + * Returns: (transfer full) (not nullable): a new reference to @schema + * + * Since: 2.32 + **/ +GSettingsSchema * +g_settings_schema_ref (GSettingsSchema *schema) +{ + g_atomic_int_inc (&schema->ref_count); + + return schema; +} + +/** + * g_settings_schema_unref: + * @schema: a #GSettingsSchema + * + * Decrease the reference count of @schema, possibly freeing it. + * + * Since: 2.32 + **/ +void +g_settings_schema_unref (GSettingsSchema *schema) +{ + if (g_atomic_int_dec_and_test (&schema->ref_count)) + { + if (schema->extends) + g_settings_schema_unref (schema->extends); + + g_settings_schema_source_unref (schema->source); + gvdb_table_free (schema->table); + g_free (schema->items); + g_free (schema->id); + + g_slice_free (GSettingsSchema, schema); + } +} + +const gchar * +g_settings_schema_get_string (GSettingsSchema *schema, + const gchar *key) +{ + const gchar *result = NULL; + GVariant *value; + + if ((value = gvdb_table_get_raw_value (schema->table, key))) + { + result = g_variant_get_string (value, NULL); + g_variant_unref (value); + } + + return result; +} + +GSettingsSchema * +g_settings_schema_get_child_schema (GSettingsSchema *schema, + const gchar *name) +{ + const gchar *child_id; + gchar *child_name; + + child_name = g_strconcat (name, "/", NULL); + child_id = g_settings_schema_get_string (schema, child_name); + + g_free (child_name); + + if (child_id == NULL) + return NULL; + + return g_settings_schema_source_lookup (schema->source, child_id, TRUE); +} + +GVariantIter * +g_settings_schema_get_value (GSettingsSchema *schema, + const gchar *key) +{ + GSettingsSchema *s = schema; + GVariantIter *iter; + GVariant *value = NULL; + + g_return_val_if_fail (schema != NULL, NULL); + + for (s = schema; s; s = s->extends) + if ((value = gvdb_table_get_raw_value (s->table, key))) + break; + + if G_UNLIKELY (value == NULL || !g_variant_is_of_type (value, G_VARIANT_TYPE_TUPLE)) + g_error ("Settings schema '%s' does not contain a key named '%s'", schema->id, key); + + iter = g_variant_iter_new (value); + g_variant_unref (value); + + return iter; +} + +/** + * g_settings_schema_get_path: + * @schema: a #GSettingsSchema + * + * Gets the path associated with @schema, or %NULL. + * + * Schemas may be single-instance or relocatable. Single-instance + * schemas correspond to exactly one set of keys in the backend + * database: those located at the path returned by this function. + * + * Relocatable schemas can be referenced by other schemas and can + * therefore describe multiple sets of keys at different locations. For + * relocatable schemas, this function will return %NULL. + * + * Returns: (nullable) (transfer none): the path of the schema, or %NULL + * + * Since: 2.32 + **/ +const gchar * +g_settings_schema_get_path (GSettingsSchema *schema) +{ + return schema->path; +} + +const gchar * +g_settings_schema_get_gettext_domain (GSettingsSchema *schema) +{ + return schema->gettext_domain; +} + +/** + * g_settings_schema_has_key: + * @schema: a #GSettingsSchema + * @name: the name of a key + * + * Checks if @schema has a key named @name. + * + * Returns: %TRUE if such a key exists + * + * Since: 2.40 + **/ +gboolean +g_settings_schema_has_key (GSettingsSchema *schema, + const gchar *key) +{ + return gvdb_table_has_value (schema->table, key); +} + +/** + * g_settings_schema_list_children: + * @schema: a #GSettingsSchema + * + * Gets the list of children in @schema. + * + * You should free the return value with g_strfreev() when you are done + * with it. + * + * Returns: (not nullable) (transfer full) (element-type utf8): a list of + * the children on @settings, in no defined order + * + * Since: 2.44 + */ +gchar ** +g_settings_schema_list_children (GSettingsSchema *schema) +{ + const GQuark *keys; + gchar **strv; + gint n_keys; + gint i, j; + + g_return_val_if_fail (schema != NULL, NULL); + + keys = g_settings_schema_list (schema, &n_keys); + strv = g_new (gchar *, n_keys + 1); + for (i = j = 0; i < n_keys; i++) + { + const gchar *key = g_quark_to_string (keys[i]); + + if (g_str_has_suffix (key, "/")) + { + gsize length = strlen (key); + + strv[j] = g_memdup2 (key, length); + strv[j][length - 1] = '\0'; + j++; + } + } + strv[j] = NULL; + + return strv; +} + +/** + * g_settings_schema_list_keys: + * @schema: a #GSettingsSchema + * + * Introspects the list of keys on @schema. + * + * You should probably not be calling this function from "normal" code + * (since you should already know what keys are in your schema). This + * function is intended for introspection reasons. + * + * Returns: (not nullable) (transfer full) (element-type utf8): a list + * of the keys on @schema, in no defined order + * + * Since: 2.46 + */ +gchar ** +g_settings_schema_list_keys (GSettingsSchema *schema) +{ + const GQuark *keys; + gchar **strv; + gint n_keys; + gint i, j; + + g_return_val_if_fail (schema != NULL, NULL); + + keys = g_settings_schema_list (schema, &n_keys); + strv = g_new (gchar *, n_keys + 1); + for (i = j = 0; i < n_keys; i++) + { + const gchar *key = g_quark_to_string (keys[i]); + + if (!g_str_has_suffix (key, "/")) + strv[j++] = g_strdup (key); + } + strv[j] = NULL; + + return strv; +} + +const GQuark * +g_settings_schema_list (GSettingsSchema *schema, + gint *n_items) +{ + if (schema->items == NULL) + { + GSettingsSchema *s; + GHashTableIter iter; + GHashTable *items; + gpointer name; + gint len; + gint i; + + items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + for (s = schema; s; s = s->extends) + { + gchar **list; + + list = gvdb_table_list (s->table, ""); + + if (list) + { + for (i = 0; list[i]; i++) + g_hash_table_add (items, list[i]); /* transfer ownership */ + + g_free (list); /* free container only */ + } + } + + /* Do a first pass to eliminate child items that do not map to + * valid schemas (ie: ones that would crash us if we actually + * tried to create them). + */ + g_hash_table_iter_init (&iter, items); + while (g_hash_table_iter_next (&iter, &name, NULL)) + if (g_str_has_suffix (name, "/")) + { + GSettingsSchemaSource *source; + GVariant *child_schema; + GvdbTable *child_table; + + child_schema = gvdb_table_get_raw_value (schema->table, name); + if (!child_schema) + continue; + + child_table = NULL; + + for (source = schema->source; source; source = source->parent) + if ((child_table = gvdb_table_get_table (source->table, g_variant_get_string (child_schema, NULL)))) + break; + + g_variant_unref (child_schema); + + /* Schema is not found -> remove it from the list */ + if (child_table == NULL) + { + g_hash_table_iter_remove (&iter); + continue; + } + + /* Make sure the schema is relocatable or at the + * expected path + */ + if (gvdb_table_has_value (child_table, ".path")) + { + GVariant *path; + gchar *expected; + gboolean same; + + path = gvdb_table_get_raw_value (child_table, ".path"); + expected = g_strconcat (schema->path, name, NULL); + same = g_str_equal (expected, g_variant_get_string (path, NULL)); + g_variant_unref (path); + g_free (expected); + + /* Schema is non-relocatable and did not have the + * expected path -> remove it from the list + */ + if (!same) + g_hash_table_iter_remove (&iter); + } + + gvdb_table_free (child_table); + } + + /* Now create the list */ + len = g_hash_table_size (items); + schema->items = g_new (GQuark, len); + i = 0; + g_hash_table_iter_init (&iter, items); + + while (g_hash_table_iter_next (&iter, &name, NULL)) + schema->items[i++] = g_quark_from_string (name); + schema->n_items = i; + g_assert (i == len); + + g_hash_table_unref (items); + } + + *n_items = schema->n_items; + return schema->items; +} + +/** + * g_settings_schema_get_id: + * @schema: a #GSettingsSchema + * + * Get the ID of @schema. + * + * Returns: (not nullable) (transfer none): the ID + **/ +const gchar * +g_settings_schema_get_id (GSettingsSchema *schema) +{ + return schema->id; +} + +static inline void +endian_fixup (GVariant **value) +{ +#if G_BYTE_ORDER == G_BIG_ENDIAN + GVariant *tmp; + + tmp = g_variant_byteswap (*value); + g_variant_unref (*value); + *value = tmp; +#endif +} + +void +g_settings_schema_key_init (GSettingsSchemaKey *key, + GSettingsSchema *schema, + const gchar *name) +{ + GVariantIter *iter; + GVariant *data; + guchar code; + + memset (key, 0, sizeof *key); + + iter = g_settings_schema_get_value (schema, name); + + key->schema = g_settings_schema_ref (schema); + key->default_value = g_variant_iter_next_value (iter); + endian_fixup (&key->default_value); + key->type = g_variant_get_type (key->default_value); + key->name = g_intern_string (name); + + while (g_variant_iter_next (iter, "(y*)", &code, &data)) + { + switch (code) + { + case 'l': + /* translation requested */ + g_variant_get (data, "(y&s)", &key->lc_char, &key->unparsed); + break; + + case 'e': + /* enumerated types... */ + key->is_enum = TRUE; + goto choice; + + case 'f': + /* flags... */ + key->is_flags = TRUE; + goto choice; + + choice: case 'c': + /* ..., choices, aliases */ + key->strinfo = g_variant_get_fixed_array (data, &key->strinfo_length, sizeof (guint32)); + break; + + case 'r': + g_variant_get (data, "(**)", &key->minimum, &key->maximum); + endian_fixup (&key->minimum); + endian_fixup (&key->maximum); + break; + + case 'd': + g_variant_get (data, "@a{sv}", &key->desktop_overrides); + endian_fixup (&key->desktop_overrides); + break; + + default: + g_warning ("unknown schema extension '%c'", code); + break; + } + + g_variant_unref (data); + } + + g_variant_iter_free (iter); +} + +void +g_settings_schema_key_clear (GSettingsSchemaKey *key) +{ + if (key->minimum) + g_variant_unref (key->minimum); + + if (key->maximum) + g_variant_unref (key->maximum); + + if (key->desktop_overrides) + g_variant_unref (key->desktop_overrides); + + g_variant_unref (key->default_value); + + g_settings_schema_unref (key->schema); +} + +gboolean +g_settings_schema_key_type_check (GSettingsSchemaKey *key, + GVariant *value) +{ + g_return_val_if_fail (value != NULL, FALSE); + + return g_variant_is_of_type (value, key->type); +} + +GVariant * +g_settings_schema_key_range_fixup (GSettingsSchemaKey *key, + GVariant *value) +{ + const gchar *target; + + if (g_settings_schema_key_range_check (key, value)) + return g_variant_ref (value); + + if (key->strinfo == NULL) + return NULL; + + if (g_variant_is_container (value)) + { + GVariantBuilder builder; + GVariantIter iter; + GVariant *child; + + g_variant_iter_init (&iter, value); + g_variant_builder_init (&builder, g_variant_get_type (value)); + + while ((child = g_variant_iter_next_value (&iter))) + { + GVariant *fixed; + + fixed = g_settings_schema_key_range_fixup (key, child); + g_variant_unref (child); + + if (fixed == NULL) + { + g_variant_builder_clear (&builder); + return NULL; + } + + g_variant_builder_add_value (&builder, fixed); + g_variant_unref (fixed); + } + + return g_variant_ref_sink (g_variant_builder_end (&builder)); + } + + target = strinfo_string_from_alias (key->strinfo, key->strinfo_length, + g_variant_get_string (value, NULL)); + return target ? g_variant_ref_sink (g_variant_new_string (target)) : NULL; +} + +GVariant * +g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key) +{ + const gchar *translated; + GError *error = NULL; + const gchar *domain; + GVariant *value; + + domain = g_settings_schema_get_gettext_domain (key->schema); + + if (key->lc_char == '\0') + /* translation not requested for this key */ + return NULL; + + if (key->lc_char == 't') + translated = g_dcgettext (domain, key->unparsed, LC_TIME); + else + translated = g_dgettext (domain, key->unparsed); + + if (translated == key->unparsed) + /* the default value was not translated */ + return NULL; + + /* try to parse the translation of the unparsed default */ + value = g_variant_parse (key->type, translated, NULL, NULL, &error); + + if (value == NULL) + { + g_warning ("Failed to parse translated string '%s' for " + "key '%s' in schema '%s': %s", translated, key->name, + g_settings_schema_get_id (key->schema), error->message); + g_warning ("Using untranslated default instead."); + g_error_free (error); + } + + else if (!g_settings_schema_key_range_check (key, value)) + { + g_warning ("Translated default '%s' for key '%s' in schema '%s' " + "is outside of valid range", key->unparsed, key->name, + g_settings_schema_get_id (key->schema)); + g_variant_unref (value); + value = NULL; + } + + return value; +} + +GVariant * +g_settings_schema_key_get_per_desktop_default (GSettingsSchemaKey *key) +{ + static const gchar * const *current_desktops; + GVariant *value = NULL; + gint i; + + if (!key->desktop_overrides) + return NULL; + + if (g_once_init_enter (¤t_desktops)) + { + const gchar *xdg_current_desktop = g_getenv ("XDG_CURRENT_DESKTOP"); + gchar **tmp; + + if (xdg_current_desktop != NULL && xdg_current_desktop[0] != '\0') + tmp = g_strsplit (xdg_current_desktop, G_SEARCHPATH_SEPARATOR_S, -1); + else + tmp = g_new0 (gchar *, 0 + 1); + + g_once_init_leave (¤t_desktops, (const gchar **) tmp); + } + + for (i = 0; value == NULL && current_desktops[i] != NULL; i++) + value = g_variant_lookup_value (key->desktop_overrides, current_desktops[i], NULL); + + return value; +} + +gint +g_settings_schema_key_to_enum (GSettingsSchemaKey *key, + GVariant *value) +{ + gboolean it_worked G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + guint result; + + it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length, + g_variant_get_string (value, NULL), + &result); + + /* 'value' can only come from the backend after being filtered for validity, + * from the translation after being filtered for validity, or from the schema + * itself (which the schema compiler checks for validity). If this assertion + * fails then it's really a bug in GSettings or the schema compiler... + */ + g_assert (it_worked); + + return result; +} + +/* Returns a new floating #GVariant. */ +GVariant * +g_settings_schema_key_from_enum (GSettingsSchemaKey *key, + gint value) +{ + const gchar *string; + + string = strinfo_string_from_enum (key->strinfo, key->strinfo_length, value); + + if (string == NULL) + return NULL; + + return g_variant_new_string (string); +} + +guint +g_settings_schema_key_to_flags (GSettingsSchemaKey *key, + GVariant *value) +{ + GVariantIter iter; + const gchar *flag; + guint result; + + result = 0; + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "&s", &flag)) + { + gboolean it_worked G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + guint flag_value; + + it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length, flag, &flag_value); + /* as in g_settings_to_enum() */ + g_assert (it_worked); + + result |= flag_value; + } + + return result; +} + +/* Returns a new floating #GVariant. */ +GVariant * +g_settings_schema_key_from_flags (GSettingsSchemaKey *key, + guint value) +{ + GVariantBuilder builder; + gint i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); + + for (i = 0; i < 32; i++) + if (value & (1u << i)) + { + const gchar *string; + + string = strinfo_string_from_enum (key->strinfo, key->strinfo_length, 1u << i); + + if (string == NULL) + { + g_variant_builder_clear (&builder); + return NULL; + } + + g_variant_builder_add (&builder, "s", string); + } + + return g_variant_builder_end (&builder); +} + +G_DEFINE_BOXED_TYPE (GSettingsSchemaKey, g_settings_schema_key, g_settings_schema_key_ref, g_settings_schema_key_unref) + +/** + * g_settings_schema_key_ref: + * @key: a #GSettingsSchemaKey + * + * Increase the reference count of @key, returning a new reference. + * + * Returns: (not nullable) (transfer full): a new reference to @key + * + * Since: 2.40 + **/ +GSettingsSchemaKey * +g_settings_schema_key_ref (GSettingsSchemaKey *key) +{ + g_return_val_if_fail (key != NULL, NULL); + + g_atomic_int_inc (&key->ref_count); + + return key; +} + +/** + * g_settings_schema_key_unref: + * @key: a #GSettingsSchemaKey + * + * Decrease the reference count of @key, possibly freeing it. + * + * Since: 2.40 + **/ +void +g_settings_schema_key_unref (GSettingsSchemaKey *key) +{ + g_return_if_fail (key != NULL); + + if (g_atomic_int_dec_and_test (&key->ref_count)) + { + g_settings_schema_key_clear (key); + + g_slice_free (GSettingsSchemaKey, key); + } +} + +/** + * g_settings_schema_get_key: + * @schema: a #GSettingsSchema + * @name: the name of a key + * + * Gets the key named @name from @schema. + * + * It is a programmer error to request a key that does not exist. See + * g_settings_schema_list_keys(). + * + * Returns: (not nullable) (transfer full): the #GSettingsSchemaKey for @name + * + * Since: 2.40 + **/ +GSettingsSchemaKey * +g_settings_schema_get_key (GSettingsSchema *schema, + const gchar *name) +{ + GSettingsSchemaKey *key; + + g_return_val_if_fail (schema != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + key = g_slice_new (GSettingsSchemaKey); + g_settings_schema_key_init (key, schema, name); + key->ref_count = 1; + + return key; +} + +/** + * g_settings_schema_key_get_name: + * @key: a #GSettingsSchemaKey + * + * Gets the name of @key. + * + * Returns: (not nullable) (transfer none): the name of @key. + * + * Since: 2.44 + */ +const gchar * +g_settings_schema_key_get_name (GSettingsSchemaKey *key) +{ + g_return_val_if_fail (key != NULL, NULL); + + return key->name; +} + +/** + * g_settings_schema_key_get_summary: + * @key: a #GSettingsSchemaKey + * + * Gets the summary for @key. + * + * If no summary has been provided in the schema for @key, returns + * %NULL. + * + * The summary is a short description of the purpose of the key; usually + * one short sentence. Summaries can be translated and the value + * returned from this function is is the current locale. + * + * This function is slow. The summary and description information for + * the schemas is not stored in the compiled schema database so this + * function has to parse all of the source XML files in the schema + * directory. + * + * Returns: (nullable) (transfer none): the summary for @key, or %NULL + * + * Since: 2.34 + **/ +const gchar * +g_settings_schema_key_get_summary (GSettingsSchemaKey *key) +{ + GHashTable **text_tables; + GHashTable *summaries; + + text_tables = g_settings_schema_source_get_text_tables (key->schema->source); + summaries = g_hash_table_lookup (text_tables[0], key->schema->id); + + return summaries ? g_hash_table_lookup (summaries, key->name) : NULL; +} + +/** + * g_settings_schema_key_get_description: + * @key: a #GSettingsSchemaKey + * + * Gets the description for @key. + * + * If no description has been provided in the schema for @key, returns + * %NULL. + * + * The description can be one sentence to several paragraphs in length. + * Paragraphs are delimited with a double newline. Descriptions can be + * translated and the value returned from this function is is the + * current locale. + * + * This function is slow. The summary and description information for + * the schemas is not stored in the compiled schema database so this + * function has to parse all of the source XML files in the schema + * directory. + * + * Returns: (nullable) (transfer none): the description for @key, or %NULL + * + * Since: 2.34 + **/ +const gchar * +g_settings_schema_key_get_description (GSettingsSchemaKey *key) +{ + GHashTable **text_tables; + GHashTable *descriptions; + + text_tables = g_settings_schema_source_get_text_tables (key->schema->source); + descriptions = g_hash_table_lookup (text_tables[1], key->schema->id); + + return descriptions ? g_hash_table_lookup (descriptions, key->name) : NULL; +} + +/** + * g_settings_schema_key_get_value_type: + * @key: a #GSettingsSchemaKey + * + * Gets the #GVariantType of @key. + * + * Returns: (not nullable) (transfer none): the type of @key + * + * Since: 2.40 + **/ +const GVariantType * +g_settings_schema_key_get_value_type (GSettingsSchemaKey *key) +{ + g_return_val_if_fail (key, NULL); + + return key->type; +} + +/** + * g_settings_schema_key_get_default_value: + * @key: a #GSettingsSchemaKey + * + * Gets the default value for @key. + * + * Note that this is the default value according to the schema. System + * administrator defaults and lockdown are not visible via this API. + * + * Returns: (not nullable) (transfer full): the default value for the key + * + * Since: 2.40 + **/ +GVariant * +g_settings_schema_key_get_default_value (GSettingsSchemaKey *key) +{ + GVariant *value; + + g_return_val_if_fail (key, NULL); + + value = g_settings_schema_key_get_translated_default (key); + + if (!value) + value = g_settings_schema_key_get_per_desktop_default (key); + + if (!value) + value = g_variant_ref (key->default_value); + + return value; +} + +/** + * g_settings_schema_key_get_range: + * @key: a #GSettingsSchemaKey + * + * Queries the range of a key. + * + * This function will return a #GVariant that fully describes the range + * of values that are valid for @key. + * + * The type of #GVariant returned is `(sv)`. The string describes + * the type of range restriction in effect. The type and meaning of + * the value contained in the variant depends on the string. + * + * If the string is `'type'` then the variant contains an empty array. + * The element type of that empty array is the expected type of value + * and all values of that type are valid. + * + * If the string is `'enum'` then the variant contains an array + * enumerating the possible values. Each item in the array is + * a possible valid value and no other values are valid. + * + * If the string is `'flags'` then the variant contains an array. Each + * item in the array is a value that may appear zero or one times in an + * array to be used as the value for this key. For example, if the + * variant contained the array `['x', 'y']` then the valid values for + * the key would be `[]`, `['x']`, `['y']`, `['x', 'y']` and + * `['y', 'x']`. + * + * Finally, if the string is `'range'` then the variant contains a pair + * of like-typed values -- the minimum and maximum permissible values + * for this key. + * + * This information should not be used by normal programs. It is + * considered to be a hint for introspection purposes. Normal programs + * should already know what is permitted by their own schema. The + * format may change in any way in the future -- but particularly, new + * forms may be added to the possibilities described above. + * + * You should free the returned value with g_variant_unref() when it is + * no longer needed. + * + * Returns: (not nullable) (transfer full): a #GVariant describing the range + * + * Since: 2.40 + **/ +GVariant * +g_settings_schema_key_get_range (GSettingsSchemaKey *key) +{ + const gchar *type; + GVariant *range; + + if (key->minimum) + { + range = g_variant_new ("(**)", key->minimum, key->maximum); + type = "range"; + } + else if (key->strinfo) + { + range = strinfo_enumerate (key->strinfo, key->strinfo_length); + type = key->is_flags ? "flags" : "enum"; + } + else + { + range = g_variant_new_array (key->type, NULL, 0); + type = "type"; + } + + return g_variant_ref_sink (g_variant_new ("(sv)", type, range)); +} + +/** + * g_settings_schema_key_range_check: + * @key: a #GSettingsSchemaKey + * @value: the value to check + * + * Checks if the given @value is within the + * permitted range for @key. + * + * It is a programmer error if @value is not of the correct type — you + * must check for this first. + * + * Returns: %TRUE if @value is valid for @key + * + * Since: 2.40 + **/ +gboolean +g_settings_schema_key_range_check (GSettingsSchemaKey *key, + GVariant *value) +{ + if (key->minimum == NULL && key->strinfo == NULL) + return TRUE; + + if (g_variant_is_container (value)) + { + gboolean ok = TRUE; + GVariantIter iter; + GVariant *child; + + g_variant_iter_init (&iter, value); + while (ok && (child = g_variant_iter_next_value (&iter))) + { + ok = g_settings_schema_key_range_check (key, child); + g_variant_unref (child); + } + + return ok; + } + + if (key->minimum) + { + return g_variant_compare (key->minimum, value) <= 0 && + g_variant_compare (value, key->maximum) <= 0; + } + + return strinfo_is_string_valid (key->strinfo, key->strinfo_length, + g_variant_get_string (value, NULL)); +} diff --git a/gio/gsettingsschema.h b/gio/gsettingsschema.h new file mode 100644 index 0000000..219e309 --- /dev/null +++ b/gio/gsettingsschema.h @@ -0,0 +1,112 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __G_SETTINGS_SCHEMA_H__ +#define __G_SETTINGS_SCHEMA_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GSettingsSchemaSource GSettingsSchemaSource; +typedef struct _GSettingsSchema GSettingsSchema; +typedef struct _GSettingsSchemaKey GSettingsSchemaKey; + +#define G_TYPE_SETTINGS_SCHEMA_SOURCE (g_settings_schema_source_get_type ()) +GLIB_AVAILABLE_IN_2_32 +GType g_settings_schema_source_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +GSettingsSchemaSource * g_settings_schema_source_get_default (void); +GLIB_AVAILABLE_IN_2_32 +GSettingsSchemaSource * g_settings_schema_source_ref (GSettingsSchemaSource *source); +GLIB_AVAILABLE_IN_2_32 +void g_settings_schema_source_unref (GSettingsSchemaSource *source); + +GLIB_AVAILABLE_IN_2_32 +GSettingsSchemaSource * g_settings_schema_source_new_from_directory (const gchar *directory, + GSettingsSchemaSource *parent, + gboolean trusted, + GError **error); + +GLIB_AVAILABLE_IN_2_32 +GSettingsSchema * g_settings_schema_source_lookup (GSettingsSchemaSource *source, + const gchar *schema_id, + gboolean recursive); + +GLIB_AVAILABLE_IN_2_40 +void g_settings_schema_source_list_schemas (GSettingsSchemaSource *source, + gboolean recursive, + gchar ***non_relocatable, + gchar ***relocatable); + +#define G_TYPE_SETTINGS_SCHEMA (g_settings_schema_get_type ()) +GLIB_AVAILABLE_IN_2_32 +GType g_settings_schema_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +GSettingsSchema * g_settings_schema_ref (GSettingsSchema *schema); +GLIB_AVAILABLE_IN_2_32 +void g_settings_schema_unref (GSettingsSchema *schema); + +GLIB_AVAILABLE_IN_2_32 +const gchar * g_settings_schema_get_id (GSettingsSchema *schema); +GLIB_AVAILABLE_IN_2_32 +const gchar * g_settings_schema_get_path (GSettingsSchema *schema); +GLIB_AVAILABLE_IN_2_40 +GSettingsSchemaKey * g_settings_schema_get_key (GSettingsSchema *schema, + const gchar *name); +GLIB_AVAILABLE_IN_2_40 +gboolean g_settings_schema_has_key (GSettingsSchema *schema, + const gchar *name); +GLIB_AVAILABLE_IN_2_46 +gchar** g_settings_schema_list_keys (GSettingsSchema *schema); + + +GLIB_AVAILABLE_IN_2_44 +gchar ** g_settings_schema_list_children (GSettingsSchema *schema); + +#define G_TYPE_SETTINGS_SCHEMA_KEY (g_settings_schema_key_get_type ()) +GLIB_AVAILABLE_IN_2_40 +GType g_settings_schema_key_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_40 +GSettingsSchemaKey * g_settings_schema_key_ref (GSettingsSchemaKey *key); +GLIB_AVAILABLE_IN_2_40 +void g_settings_schema_key_unref (GSettingsSchemaKey *key); + +GLIB_AVAILABLE_IN_2_40 +const GVariantType * g_settings_schema_key_get_value_type (GSettingsSchemaKey *key); +GLIB_AVAILABLE_IN_2_40 +GVariant * g_settings_schema_key_get_default_value (GSettingsSchemaKey *key); +GLIB_AVAILABLE_IN_2_40 +GVariant * g_settings_schema_key_get_range (GSettingsSchemaKey *key); +GLIB_AVAILABLE_IN_2_40 +gboolean g_settings_schema_key_range_check (GSettingsSchemaKey *key, + GVariant *value); + +GLIB_AVAILABLE_IN_2_44 +const gchar * g_settings_schema_key_get_name (GSettingsSchemaKey *key); +GLIB_AVAILABLE_IN_2_40 +const gchar * g_settings_schema_key_get_summary (GSettingsSchemaKey *key); +GLIB_AVAILABLE_IN_2_40 +const gchar * g_settings_schema_key_get_description (GSettingsSchemaKey *key); + +G_END_DECLS + +#endif /* __G_SETTINGS_SCHEMA_H__ */ diff --git a/gio/gsimpleaction.c b/gio/gsimpleaction.c new file mode 100644 index 0000000..499adb2 --- /dev/null +++ b/gio/gsimpleaction.c @@ -0,0 +1,650 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gsimpleaction.h" + +#include "gaction.h" +#include "glibintl.h" + +/** + * SECTION:gsimpleaction + * @title: GSimpleAction + * @short_description: A simple GAction implementation + * @include: gio/gio.h + * + * A #GSimpleAction is the obvious simple implementation of the #GAction + * interface. This is the easiest way to create an action for purposes of + * adding it to a #GSimpleActionGroup. + * + * See also #GtkAction. + */ + +/** + * GSimpleAction: + * + * #GSimpleAction is an opaque data structure and can only be accessed + * using the following functions. + **/ + +struct _GSimpleAction +{ + GObject parent_instance; + + gchar *name; + GVariantType *parameter_type; + gboolean enabled; + GVariant *state; + GVariant *state_hint; + gboolean state_set_already; +}; + +typedef GObjectClass GSimpleActionClass; + +static void g_simple_action_iface_init (GActionInterface *iface); +G_DEFINE_TYPE_WITH_CODE (GSimpleAction, g_simple_action, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_simple_action_iface_init)) + +enum +{ + PROP_NONE, + PROP_NAME, + PROP_PARAMETER_TYPE, + PROP_ENABLED, + PROP_STATE_TYPE, + PROP_STATE +}; + +enum +{ + SIGNAL_CHANGE_STATE, + SIGNAL_ACTIVATE, + NR_SIGNALS +}; + +static guint g_simple_action_signals[NR_SIGNALS]; + +static const gchar * +g_simple_action_get_name (GAction *action) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (action); + + return simple->name; +} + +static const GVariantType * +g_simple_action_get_parameter_type (GAction *action) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (action); + + return simple->parameter_type; +} + +static const GVariantType * +g_simple_action_get_state_type (GAction *action) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (action); + + if (simple->state != NULL) + return g_variant_get_type (simple->state); + else + return NULL; +} + +static GVariant * +g_simple_action_get_state_hint (GAction *action) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (action); + + if (simple->state_hint != NULL) + return g_variant_ref (simple->state_hint); + else + return NULL; +} + +static gboolean +g_simple_action_get_enabled (GAction *action) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (action); + + return simple->enabled; +} + +static void +g_simple_action_change_state (GAction *action, + GVariant *value) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (action); + + /* If the user connected a signal handler then they are responsible + * for handling state changes. + */ + if (g_signal_has_handler_pending (action, g_simple_action_signals[SIGNAL_CHANGE_STATE], 0, TRUE)) + g_signal_emit (action, g_simple_action_signals[SIGNAL_CHANGE_STATE], 0, value); + + /* If not, then the default behaviour is to just set the state. */ + else + g_simple_action_set_state (simple, value); +} + +/** + * g_simple_action_set_state: + * @simple: a #GSimpleAction + * @value: the new #GVariant for the state + * + * Sets the state of the action. + * + * This directly updates the 'state' property to the given value. + * + * This should only be called by the implementor of the action. Users + * of the action should not attempt to directly modify the 'state' + * property. Instead, they should call g_action_change_state() to + * request the change. + * + * If the @value GVariant is floating, it is consumed. + * + * Since: 2.30 + **/ +void +g_simple_action_set_state (GSimpleAction *simple, + GVariant *value) +{ + g_return_if_fail (G_IS_SIMPLE_ACTION (simple)); + g_return_if_fail (value != NULL); + + { + const GVariantType *state_type; + + state_type = simple->state ? + g_variant_get_type (simple->state) : NULL; + g_return_if_fail (state_type != NULL); + g_return_if_fail (g_variant_is_of_type (value, state_type)); + } + + g_variant_ref_sink (value); + + if (!simple->state || !g_variant_equal (simple->state, value)) + { + if (simple->state) + g_variant_unref (simple->state); + + simple->state = g_variant_ref (value); + + g_object_notify (G_OBJECT (simple), "state"); + } + + g_variant_unref (value); +} + +static GVariant * +g_simple_action_get_state (GAction *action) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (action); + + return simple->state ? g_variant_ref (simple->state) : NULL; +} + +static void +g_simple_action_activate (GAction *action, + GVariant *parameter) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (action); + + g_return_if_fail (simple->parameter_type == NULL ? + parameter == NULL : + (parameter != NULL && + g_variant_is_of_type (parameter, + simple->parameter_type))); + + if (parameter != NULL) + g_variant_ref_sink (parameter); + + if (simple->enabled) + { + /* If the user connected a signal handler then they are responsible + * for handling activation. + */ + if (g_signal_has_handler_pending (action, g_simple_action_signals[SIGNAL_ACTIVATE], 0, TRUE)) + g_signal_emit (action, g_simple_action_signals[SIGNAL_ACTIVATE], 0, parameter); + + /* If not, do some reasonable defaults for stateful actions. */ + else if (simple->state) + { + /* If we have no parameter and this is a boolean action, toggle. */ + if (parameter == NULL && g_variant_is_of_type (simple->state, G_VARIANT_TYPE_BOOLEAN)) + { + gboolean was_enabled = g_variant_get_boolean (simple->state); + g_simple_action_change_state (action, g_variant_new_boolean (!was_enabled)); + } + + /* else, if the parameter and state type are the same, do a change-state */ + else if (g_variant_is_of_type (simple->state, g_variant_get_type (parameter))) + g_simple_action_change_state (action, parameter); + } + } + + if (parameter != NULL) + g_variant_unref (parameter); +} + +static void +g_simple_action_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSimpleAction *action = G_SIMPLE_ACTION (object); + + switch (prop_id) + { + case PROP_NAME: + action->name = g_strdup (g_value_get_string (value)); + break; + + case PROP_PARAMETER_TYPE: + action->parameter_type = g_value_dup_boxed (value); + break; + + case PROP_ENABLED: + action->enabled = g_value_get_boolean (value); + break; + + case PROP_STATE: + /* The first time we see this (during construct) we should just + * take the state as it was handed to us. + * + * After that, we should make sure we go through the same checks + * as the C API. + */ + if (!action->state_set_already) + { + action->state = g_value_dup_variant (value); + action->state_set_already = TRUE; + } + else + g_simple_action_set_state (action, g_value_get_variant (value)); + + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_simple_action_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GAction *action = G_ACTION (object); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, g_simple_action_get_name (action)); + break; + + case PROP_PARAMETER_TYPE: + g_value_set_boxed (value, g_simple_action_get_parameter_type (action)); + break; + + case PROP_ENABLED: + g_value_set_boolean (value, g_simple_action_get_enabled (action)); + break; + + case PROP_STATE_TYPE: + g_value_set_boxed (value, g_simple_action_get_state_type (action)); + break; + + case PROP_STATE: + g_value_take_variant (value, g_simple_action_get_state (action)); + break; + + default: + g_assert_not_reached (); + } +} + +static void +g_simple_action_finalize (GObject *object) +{ + GSimpleAction *simple = G_SIMPLE_ACTION (object); + + g_free (simple->name); + if (simple->parameter_type) + g_variant_type_free (simple->parameter_type); + if (simple->state) + g_variant_unref (simple->state); + if (simple->state_hint) + g_variant_unref (simple->state_hint); + + G_OBJECT_CLASS (g_simple_action_parent_class) + ->finalize (object); +} + +void +g_simple_action_init (GSimpleAction *simple) +{ + simple->enabled = TRUE; +} + +void +g_simple_action_iface_init (GActionInterface *iface) +{ + iface->get_name = g_simple_action_get_name; + iface->get_parameter_type = g_simple_action_get_parameter_type; + iface->get_state_type = g_simple_action_get_state_type; + iface->get_state_hint = g_simple_action_get_state_hint; + iface->get_enabled = g_simple_action_get_enabled; + iface->get_state = g_simple_action_get_state; + iface->change_state = g_simple_action_change_state; + iface->activate = g_simple_action_activate; +} + +void +g_simple_action_class_init (GSimpleActionClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->set_property = g_simple_action_set_property; + object_class->get_property = g_simple_action_get_property; + object_class->finalize = g_simple_action_finalize; + + /** + * GSimpleAction::activate: + * @simple: the #GSimpleAction + * @parameter: (nullable): the parameter to the activation, or %NULL if it has + * no parameter + * + * Indicates that the action was just activated. + * + * @parameter will always be of the expected type, i.e. the parameter type + * specified when the action was created. If an incorrect type is given when + * activating the action, this signal is not emitted. + * + * Since GLib 2.40, if no handler is connected to this signal then the + * default behaviour for boolean-stated actions with a %NULL parameter + * type is to toggle them via the #GSimpleAction::change-state signal. + * For stateful actions where the state type is equal to the parameter + * type, the default is to forward them directly to + * #GSimpleAction::change-state. This should allow almost all users + * of #GSimpleAction to connect only one handler or the other. + * + * Since: 2.28 + */ + g_simple_action_signals[SIGNAL_ACTIVATE] = + g_signal_new (I_("activate"), + G_TYPE_SIMPLE_ACTION, + G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT, + 0, NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT); + + /** + * GSimpleAction::change-state: + * @simple: the #GSimpleAction + * @value: (nullable): the requested value for the state + * + * Indicates that the action just received a request to change its + * state. + * + * @value will always be of the correct state type, i.e. the type of the + * initial state passed to g_simple_action_new_stateful(). If an incorrect + * type is given when requesting to change the state, this signal is not + * emitted. + * + * If no handler is connected to this signal then the default + * behaviour is to call g_simple_action_set_state() to set the state + * to the requested value. If you connect a signal handler then no + * default action is taken. If the state should change then you must + * call g_simple_action_set_state() from the handler. + * + * An example of a 'change-state' handler: + * |[ + * static void + * change_volume_state (GSimpleAction *action, + * GVariant *value, + * gpointer user_data) + * { + * gint requested; + * + * requested = g_variant_get_int32 (value); + * + * // Volume only goes from 0 to 10 + * if (0 <= requested && requested <= 10) + * g_simple_action_set_state (action, value); + * } + * ]| + * + * The handler need not set the state to the requested value. + * It could set it to any value at all, or take some other action. + * + * Since: 2.30 + */ + g_simple_action_signals[SIGNAL_CHANGE_STATE] = + g_signal_new (I_("change-state"), + G_TYPE_SIMPLE_ACTION, + G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT, + 0, NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT); + + /** + * GSimpleAction:name: + * + * The name of the action. This is mostly meaningful for identifying + * the action once it has been added to a #GSimpleActionGroup. + * + * Since: 2.28 + **/ + g_object_class_install_property (object_class, PROP_NAME, + g_param_spec_string ("name", + P_("Action Name"), + P_("The name used to invoke the action"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GSimpleAction:parameter-type: + * + * The type of the parameter that must be given when activating the + * action. + * + * Since: 2.28 + **/ + g_object_class_install_property (object_class, PROP_PARAMETER_TYPE, + g_param_spec_boxed ("parameter-type", + P_("Parameter Type"), + P_("The type of GVariant passed to activate()"), + G_TYPE_VARIANT_TYPE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GSimpleAction:enabled: + * + * If @action is currently enabled. + * + * If the action is disabled then calls to g_action_activate() and + * g_action_change_state() have no effect. + * + * Since: 2.28 + **/ + g_object_class_install_property (object_class, PROP_ENABLED, + g_param_spec_boolean ("enabled", + P_("Enabled"), + P_("If the action can be activated"), + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSimpleAction:state-type: + * + * The #GVariantType of the state that the action has, or %NULL if the + * action is stateless. + * + * Since: 2.28 + **/ + g_object_class_install_property (object_class, PROP_STATE_TYPE, + g_param_spec_boxed ("state-type", + P_("State Type"), + P_("The type of the state kept by the action"), + G_TYPE_VARIANT_TYPE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSimpleAction:state: + * + * The state of the action, or %NULL if the action is stateless. + * + * Since: 2.28 + **/ + g_object_class_install_property (object_class, PROP_STATE, + g_param_spec_variant ("state", + P_("State"), + P_("The state the action is in"), + G_VARIANT_TYPE_ANY, + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_simple_action_set_enabled: + * @simple: a #GSimpleAction + * @enabled: whether the action is enabled + * + * Sets the action as enabled or not. + * + * An action must be enabled in order to be activated or in order to + * have its state changed from outside callers. + * + * This should only be called by the implementor of the action. Users + * of the action should not attempt to modify its enabled flag. + * + * Since: 2.28 + **/ +void +g_simple_action_set_enabled (GSimpleAction *simple, + gboolean enabled) +{ + g_return_if_fail (G_IS_SIMPLE_ACTION (simple)); + + enabled = !!enabled; + + if (simple->enabled != enabled) + { + simple->enabled = enabled; + g_object_notify (G_OBJECT (simple), "enabled"); + } +} + +/** + * g_simple_action_set_state_hint: + * @simple: a #GSimpleAction + * @state_hint: (nullable): a #GVariant representing the state hint + * + * Sets the state hint for the action. + * + * See g_action_get_state_hint() for more information about + * action state hints. + * + * Since: 2.44 + **/ +void +g_simple_action_set_state_hint (GSimpleAction *simple, + GVariant *state_hint) +{ + g_return_if_fail (G_IS_SIMPLE_ACTION (simple)); + + if (simple->state_hint != NULL) + { + g_variant_unref (simple->state_hint); + simple->state_hint = NULL; + } + + if (state_hint != NULL) + simple->state_hint = g_variant_ref (state_hint); +} + +/** + * g_simple_action_new: + * @name: the name of the action + * @parameter_type: (nullable): the type of parameter that will be passed to + * handlers for the #GSimpleAction::activate signal, or %NULL for no parameter + * + * Creates a new action. + * + * The created action is stateless. See g_simple_action_new_stateful() to create + * an action that has state. + * + * Returns: a new #GSimpleAction + * + * Since: 2.28 + **/ +GSimpleAction * +g_simple_action_new (const gchar *name, + const GVariantType *parameter_type) +{ + g_return_val_if_fail (name != NULL, NULL); + + return g_object_new (G_TYPE_SIMPLE_ACTION, + "name", name, + "parameter-type", parameter_type, + NULL); +} + +/** + * g_simple_action_new_stateful: + * @name: the name of the action + * @parameter_type: (nullable): the type of the parameter that will be passed to + * handlers for the #GSimpleAction::activate signal, or %NULL for no parameter + * @state: the initial state of the action + * + * Creates a new stateful action. + * + * All future state values must have the same #GVariantType as the initial + * @state. + * + * If the @state #GVariant is floating, it is consumed. + * + * Returns: a new #GSimpleAction + * + * Since: 2.28 + **/ +GSimpleAction * +g_simple_action_new_stateful (const gchar *name, + const GVariantType *parameter_type, + GVariant *state) +{ + return g_object_new (G_TYPE_SIMPLE_ACTION, + "name", name, + "parameter-type", parameter_type, + "state", state, + NULL); +} diff --git a/gio/gsimpleaction.h b/gio/gsimpleaction.h new file mode 100644 index 0000000..041eb7e --- /dev/null +++ b/gio/gsimpleaction.h @@ -0,0 +1,63 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_SIMPLE_ACTION_H__ +#define __G_SIMPLE_ACTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SIMPLE_ACTION (g_simple_action_get_type ()) +#define G_SIMPLE_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SIMPLE_ACTION, GSimpleAction)) +#define G_IS_SIMPLE_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SIMPLE_ACTION)) + +GLIB_AVAILABLE_IN_ALL +GType g_simple_action_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSimpleAction * g_simple_action_new (const gchar *name, + const GVariantType *parameter_type); + +GLIB_AVAILABLE_IN_ALL +GSimpleAction * g_simple_action_new_stateful (const gchar *name, + const GVariantType *parameter_type, + GVariant *state); + +GLIB_AVAILABLE_IN_ALL +void g_simple_action_set_enabled (GSimpleAction *simple, + gboolean enabled); + +GLIB_AVAILABLE_IN_2_30 +void g_simple_action_set_state (GSimpleAction *simple, + GVariant *value); + +GLIB_AVAILABLE_IN_2_44 +void g_simple_action_set_state_hint (GSimpleAction *simple, + GVariant *state_hint); + +G_END_DECLS + +#endif /* __G_SIMPLE_ACTION_H__ */ diff --git a/gio/gsimpleactiongroup.c b/gio/gsimpleactiongroup.c new file mode 100644 index 0000000..11bc193 --- /dev/null +++ b/gio/gsimpleactiongroup.c @@ -0,0 +1,400 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gsimpleactiongroup.h" + +#include "gsimpleaction.h" +#include "gactionmap.h" +#include "gaction.h" + +/** + * SECTION:gsimpleactiongroup + * @title: GSimpleActionGroup + * @short_description: A simple GActionGroup implementation + * @include: gio/gio.h + * + * #GSimpleActionGroup is a hash table filled with #GAction objects, + * implementing the #GActionGroup and #GActionMap interfaces. + **/ + +struct _GSimpleActionGroupPrivate +{ + GHashTable *table; /* string -> GAction */ +}; + +static void g_simple_action_group_iface_init (GActionGroupInterface *); +static void g_simple_action_group_map_iface_init (GActionMapInterface *); +G_DEFINE_TYPE_WITH_CODE (GSimpleActionGroup, + g_simple_action_group, G_TYPE_OBJECT, + G_ADD_PRIVATE (GSimpleActionGroup) + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, + g_simple_action_group_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_MAP, + g_simple_action_group_map_iface_init)) + +static gchar ** +g_simple_action_group_list_actions (GActionGroup *group) +{ + GSimpleActionGroup *simple = G_SIMPLE_ACTION_GROUP (group); + GHashTableIter iter; + gint n, i = 0; + gchar **keys; + gpointer key; + + n = g_hash_table_size (simple->priv->table); + keys = g_new (gchar *, n + 1); + + g_hash_table_iter_init (&iter, simple->priv->table); + while (g_hash_table_iter_next (&iter, &key, NULL)) + keys[i++] = g_strdup (key); + g_assert_cmpint (i, ==, n); + keys[n] = NULL; + + return keys; +} + +static gboolean +g_simple_action_group_query_action (GActionGroup *group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state) +{ + GSimpleActionGroup *simple = G_SIMPLE_ACTION_GROUP (group); + GAction *action; + + action = g_hash_table_lookup (simple->priv->table, action_name); + + if (action == NULL) + return FALSE; + + if (enabled) + *enabled = g_action_get_enabled (action); + + if (parameter_type) + *parameter_type = g_action_get_parameter_type (action); + + if (state_type) + *state_type = g_action_get_state_type (action); + + if (state_hint) + *state_hint = g_action_get_state_hint (action); + + if (state) + *state = g_action_get_state (action); + + return TRUE; +} + +static void +g_simple_action_group_change_state (GActionGroup *group, + const gchar *action_name, + GVariant *value) +{ + GSimpleActionGroup *simple = G_SIMPLE_ACTION_GROUP (group); + GAction *action; + + action = g_hash_table_lookup (simple->priv->table, action_name); + + if (action == NULL) + return; + + g_action_change_state (action, value); +} + +static void +g_simple_action_group_activate (GActionGroup *group, + const gchar *action_name, + GVariant *parameter) +{ + GSimpleActionGroup *simple = G_SIMPLE_ACTION_GROUP (group); + GAction *action; + + action = g_hash_table_lookup (simple->priv->table, action_name); + + if (action == NULL) + return; + + g_action_activate (action, parameter); +} + +static void +action_enabled_notify (GAction *action, + GParamSpec *pspec, + gpointer user_data) +{ + g_action_group_action_enabled_changed (user_data, + g_action_get_name (action), + g_action_get_enabled (action)); +} + +static void +action_state_notify (GAction *action, + GParamSpec *pspec, + gpointer user_data) +{ + GVariant *value; + + value = g_action_get_state (action); + g_action_group_action_state_changed (user_data, + g_action_get_name (action), + value); + g_variant_unref (value); +} + +static void +g_simple_action_group_disconnect (gpointer key, + gpointer value, + gpointer user_data) +{ + g_signal_handlers_disconnect_by_func (value, action_enabled_notify, + user_data); + g_signal_handlers_disconnect_by_func (value, action_state_notify, + user_data); +} + +static GAction * +g_simple_action_group_lookup_action (GActionMap *action_map, + const gchar *action_name) +{ + GSimpleActionGroup *simple = G_SIMPLE_ACTION_GROUP (action_map); + + return g_hash_table_lookup (simple->priv->table, action_name); +} + +static void +g_simple_action_group_add_action (GActionMap *action_map, + GAction *action) +{ + GSimpleActionGroup *simple = G_SIMPLE_ACTION_GROUP (action_map); + const gchar *action_name; + GAction *old_action; + + action_name = g_action_get_name (action); + if (action_name == NULL) + { + g_critical ("The supplied action has no name. You must set the " + "GAction:name property when creating an action."); + return; + } + + old_action = g_hash_table_lookup (simple->priv->table, action_name); + + if (old_action != action) + { + if (old_action != NULL) + { + g_action_group_action_removed (G_ACTION_GROUP (simple), + action_name); + g_simple_action_group_disconnect (NULL, old_action, simple); + } + + g_signal_connect (action, "notify::enabled", + G_CALLBACK (action_enabled_notify), simple); + + if (g_action_get_state_type (action) != NULL) + g_signal_connect (action, "notify::state", + G_CALLBACK (action_state_notify), simple); + + g_hash_table_insert (simple->priv->table, + g_strdup (action_name), + g_object_ref (action)); + + g_action_group_action_added (G_ACTION_GROUP (simple), action_name); + } +} + +static void +g_simple_action_group_remove_action (GActionMap *action_map, + const gchar *action_name) +{ + GSimpleActionGroup *simple = G_SIMPLE_ACTION_GROUP (action_map); + GAction *action; + + action = g_hash_table_lookup (simple->priv->table, action_name); + + if (action != NULL) + { + g_action_group_action_removed (G_ACTION_GROUP (simple), action_name); + g_simple_action_group_disconnect (NULL, action, simple); + g_hash_table_remove (simple->priv->table, action_name); + } +} + +static void +g_simple_action_group_finalize (GObject *object) +{ + GSimpleActionGroup *simple = G_SIMPLE_ACTION_GROUP (object); + + g_hash_table_foreach (simple->priv->table, + g_simple_action_group_disconnect, + simple); + g_hash_table_unref (simple->priv->table); + + G_OBJECT_CLASS (g_simple_action_group_parent_class) + ->finalize (object); +} + +static void +g_simple_action_group_init (GSimpleActionGroup *simple) +{ + simple->priv = g_simple_action_group_get_instance_private (simple); + simple->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_object_unref); +} + +static void +g_simple_action_group_class_init (GSimpleActionGroupClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_simple_action_group_finalize; +} + +static void +g_simple_action_group_iface_init (GActionGroupInterface *iface) +{ + iface->list_actions = g_simple_action_group_list_actions; + iface->query_action = g_simple_action_group_query_action; + iface->change_action_state = g_simple_action_group_change_state; + iface->activate_action = g_simple_action_group_activate; +} + +static void +g_simple_action_group_map_iface_init (GActionMapInterface *iface) +{ + iface->add_action = g_simple_action_group_add_action; + iface->remove_action = g_simple_action_group_remove_action; + iface->lookup_action = g_simple_action_group_lookup_action; +} + +/** + * g_simple_action_group_new: + * + * Creates a new, empty, #GSimpleActionGroup. + * + * Returns: a new #GSimpleActionGroup + * + * Since: 2.28 + **/ +GSimpleActionGroup * +g_simple_action_group_new (void) +{ + return g_object_new (G_TYPE_SIMPLE_ACTION_GROUP, NULL); +} + +/** + * g_simple_action_group_lookup: + * @simple: a #GSimpleActionGroup + * @action_name: the name of an action + * + * Looks up the action with the name @action_name in the group. + * + * If no such action exists, returns %NULL. + * + * Returns: (transfer none): a #GAction, or %NULL + * + * Since: 2.28 + * + * Deprecated: 2.38: Use g_action_map_lookup_action() + */ +GAction * +g_simple_action_group_lookup (GSimpleActionGroup *simple, + const gchar *action_name) +{ + g_return_val_if_fail (G_IS_SIMPLE_ACTION_GROUP (simple), NULL); + + return g_action_map_lookup_action (G_ACTION_MAP (simple), action_name); +} + +/** + * g_simple_action_group_insert: + * @simple: a #GSimpleActionGroup + * @action: a #GAction + * + * Adds an action to the action group. + * + * If the action group already contains an action with the same name as + * @action then the old action is dropped from the group. + * + * The action group takes its own reference on @action. + * + * Since: 2.28 + * + * Deprecated: 2.38: Use g_action_map_add_action() + **/ +void +g_simple_action_group_insert (GSimpleActionGroup *simple, + GAction *action) +{ + g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP (simple)); + + g_action_map_add_action (G_ACTION_MAP (simple), action); +} + +/** + * g_simple_action_group_remove: + * @simple: a #GSimpleActionGroup + * @action_name: the name of the action + * + * Removes the named action from the action group. + * + * If no action of this name is in the group then nothing happens. + * + * Since: 2.28 + * + * Deprecated: 2.38: Use g_action_map_remove_action() + **/ +void +g_simple_action_group_remove (GSimpleActionGroup *simple, + const gchar *action_name) +{ + g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP (simple)); + + g_action_map_remove_action (G_ACTION_MAP (simple), action_name); +} + + +/** + * g_simple_action_group_add_entries: + * @simple: a #GSimpleActionGroup + * @entries: (array length=n_entries): a pointer to the first item in + * an array of #GActionEntry structs + * @n_entries: the length of @entries, or -1 + * @user_data: the user data for signal connections + * + * A convenience function for creating multiple #GSimpleAction instances + * and adding them to the action group. + * + * Since: 2.30 + * + * Deprecated: 2.38: Use g_action_map_add_action_entries() + **/ +void +g_simple_action_group_add_entries (GSimpleActionGroup *simple, + const GActionEntry *entries, + gint n_entries, + gpointer user_data) +{ + g_action_map_add_action_entries (G_ACTION_MAP (simple), entries, n_entries, user_data); +} diff --git a/gio/gsimpleactiongroup.h b/gio/gsimpleactiongroup.h new file mode 100644 index 0000000..6ad46e7 --- /dev/null +++ b/gio/gsimpleactiongroup.h @@ -0,0 +1,97 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_SIMPLE_ACTION_GROUP_H__ +#define __G_SIMPLE_ACTION_GROUP_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include "gactiongroup.h" +#include "gactionmap.h" + +G_BEGIN_DECLS + +#define G_TYPE_SIMPLE_ACTION_GROUP (g_simple_action_group_get_type ()) +#define G_SIMPLE_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SIMPLE_ACTION_GROUP, GSimpleActionGroup)) +#define G_SIMPLE_ACTION_GROUP_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SIMPLE_ACTION_GROUP, GSimpleActionGroupClass)) +#define G_IS_SIMPLE_ACTION_GROUP(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SIMPLE_ACTION_GROUP)) +#define G_IS_SIMPLE_ACTION_GROUP_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SIMPLE_ACTION_GROUP)) +#define G_SIMPLE_ACTION_GROUP_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SIMPLE_ACTION_GROUP, GSimpleActionGroupClass)) + +typedef struct _GSimpleActionGroupPrivate GSimpleActionGroupPrivate; +typedef struct _GSimpleActionGroupClass GSimpleActionGroupClass; + +/** + * GSimpleActionGroup: + * + * The #GSimpleActionGroup structure contains private data and should only be accessed using the provided API. + * + * Since: 2.28 + */ +struct _GSimpleActionGroup +{ + /*< private >*/ + GObject parent_instance; + + GSimpleActionGroupPrivate *priv; +}; + +struct _GSimpleActionGroupClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< private >*/ + gpointer padding[12]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_simple_action_group_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSimpleActionGroup * g_simple_action_group_new (void); + +GLIB_DEPRECATED_IN_2_38_FOR (g_action_map_lookup_action) +GAction * g_simple_action_group_lookup (GSimpleActionGroup *simple, + const gchar *action_name); + +GLIB_DEPRECATED_IN_2_38_FOR (g_action_map_add_action) +void g_simple_action_group_insert (GSimpleActionGroup *simple, + GAction *action); + +GLIB_DEPRECATED_IN_2_38_FOR (g_action_map_remove_action) +void g_simple_action_group_remove (GSimpleActionGroup *simple, + const gchar *action_name); + +GLIB_DEPRECATED_IN_2_38_FOR (g_action_map_add_action_entries) +void g_simple_action_group_add_entries (GSimpleActionGroup *simple, + const GActionEntry *entries, + gint n_entries, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_SIMPLE_ACTION_GROUP_H__ */ diff --git a/gio/gsimpleasyncresult.c b/gio/gsimpleasyncresult.c new file mode 100644 index 0000000..7fd9b43 --- /dev/null +++ b/gio/gsimpleasyncresult.c @@ -0,0 +1,1151 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "gsimpleasyncresult.h" +#include "gasyncresult.h" +#include "gcancellable.h" +#include "gioscheduler.h" +#include +#include "glibintl.h" + + +/** + * SECTION:gsimpleasyncresult + * @short_description: Simple asynchronous results implementation + * @include: gio/gio.h + * @see_also: #GAsyncResult, #GTask + * + * As of GLib 2.46, #GSimpleAsyncResult is deprecated in favor of + * #GTask, which provides a simpler API. + * + * #GSimpleAsyncResult implements #GAsyncResult. + * + * GSimpleAsyncResult handles #GAsyncReadyCallbacks, error + * reporting, operation cancellation and the final state of an operation, + * completely transparent to the application. Results can be returned + * as a pointer e.g. for functions that return data that is collected + * asynchronously, a boolean value for checking the success or failure + * of an operation, or a #gssize for operations which return the number + * of bytes modified by the operation; all of the simple return cases + * are covered. + * + * Most of the time, an application will not need to know of the details + * of this API; it is handled transparently, and any necessary operations + * are handled by #GAsyncResult's interface. However, if implementing a + * new GIO module, for writing language bindings, or for complex + * applications that need better control of how asynchronous operations + * are completed, it is important to understand this functionality. + * + * GSimpleAsyncResults are tagged with the calling function to ensure + * that asynchronous functions and their finishing functions are used + * together correctly. + * + * To create a new #GSimpleAsyncResult, call g_simple_async_result_new(). + * If the result needs to be created for a #GError, use + * g_simple_async_result_new_from_error() or + * g_simple_async_result_new_take_error(). If a #GError is not available + * (e.g. the asynchronous operation's doesn't take a #GError argument), + * but the result still needs to be created for an error condition, use + * g_simple_async_result_new_error() (or g_simple_async_result_set_error_va() + * if your application or binding requires passing a variable argument list + * directly), and the error can then be propagated through the use of + * g_simple_async_result_propagate_error(). + * + * An asynchronous operation can be made to ignore a cancellation event by + * calling g_simple_async_result_set_handle_cancellation() with a + * #GSimpleAsyncResult for the operation and %FALSE. This is useful for + * operations that are dangerous to cancel, such as close (which would + * cause a leak if cancelled before being run). + * + * GSimpleAsyncResult can integrate into GLib's event loop, #GMainLoop, + * or it can use #GThreads. + * g_simple_async_result_complete() will finish an I/O task directly + * from the point where it is called. g_simple_async_result_complete_in_idle() + * will finish it from an idle handler in the + * [thread-default main context][g-main-context-push-thread-default] + * where the #GSimpleAsyncResult was created. + * g_simple_async_result_run_in_thread() will run the job in a + * separate thread and then use + * g_simple_async_result_complete_in_idle() to deliver the result. + * + * To set the results of an asynchronous function, + * g_simple_async_result_set_op_res_gpointer(), + * g_simple_async_result_set_op_res_gboolean(), and + * g_simple_async_result_set_op_res_gssize() + * are provided, setting the operation's result to a gpointer, gboolean, or + * gssize, respectively. + * + * Likewise, to get the result of an asynchronous function, + * g_simple_async_result_get_op_res_gpointer(), + * g_simple_async_result_get_op_res_gboolean(), and + * g_simple_async_result_get_op_res_gssize() are + * provided, getting the operation's result as a gpointer, gboolean, and + * gssize, respectively. + * + * For the details of the requirements implementations must respect, see + * #GAsyncResult. A typical implementation of an asynchronous operation + * using GSimpleAsyncResult looks something like this: + * + * |[ + * static void + * baked_cb (Cake *cake, + * gpointer user_data) + * { + * // In this example, this callback is not given a reference to the cake, + * // so the GSimpleAsyncResult has to take a reference to it. + * GSimpleAsyncResult *result = user_data; + * + * if (cake == NULL) + * g_simple_async_result_set_error (result, + * BAKER_ERRORS, + * BAKER_ERROR_NO_FLOUR, + * "Go to the supermarket"); + * else + * g_simple_async_result_set_op_res_gpointer (result, + * g_object_ref (cake), + * g_object_unref); + * + * + * // In this example, we assume that baked_cb is called as a callback from + * // the mainloop, so it's safe to complete the operation synchronously here. + * // If, however, _baker_prepare_cake () might call its callback without + * // first returning to the mainloop — inadvisable, but some APIs do so — + * // we would need to use g_simple_async_result_complete_in_idle(). + * g_simple_async_result_complete (result); + * g_object_unref (result); + * } + * + * void + * baker_bake_cake_async (Baker *self, + * guint radius, + * GAsyncReadyCallback callback, + * gpointer user_data) + * { + * GSimpleAsyncResult *simple; + * Cake *cake; + * + * if (radius < 3) + * { + * g_simple_async_report_error_in_idle (G_OBJECT (self), + * callback, + * user_data, + * BAKER_ERRORS, + * BAKER_ERROR_TOO_SMALL, + * "%ucm radius cakes are silly", + * radius); + * return; + * } + * + * simple = g_simple_async_result_new (G_OBJECT (self), + * callback, + * user_data, + * baker_bake_cake_async); + * cake = _baker_get_cached_cake (self, radius); + * + * if (cake != NULL) + * { + * g_simple_async_result_set_op_res_gpointer (simple, + * g_object_ref (cake), + * g_object_unref); + * g_simple_async_result_complete_in_idle (simple); + * g_object_unref (simple); + * // Drop the reference returned by _baker_get_cached_cake(); + * // the GSimpleAsyncResult has taken its own reference. + * g_object_unref (cake); + * return; + * } + * + * _baker_prepare_cake (self, radius, baked_cb, simple); + * } + * + * Cake * + * baker_bake_cake_finish (Baker *self, + * GAsyncResult *result, + * GError **error) + * { + * GSimpleAsyncResult *simple; + * Cake *cake; + * + * g_return_val_if_fail (g_simple_async_result_is_valid (result, + * G_OBJECT (self), + * baker_bake_cake_async), + * NULL); + * + * simple = (GSimpleAsyncResult *) result; + * + * if (g_simple_async_result_propagate_error (simple, error)) + * return NULL; + * + * cake = CAKE (g_simple_async_result_get_op_res_gpointer (simple)); + * return g_object_ref (cake); + * } + * ]| + */ + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +static void g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface); + +struct _GSimpleAsyncResult +{ + GObject parent_instance; + + GObject *source_object; + GAsyncReadyCallback callback; + gpointer user_data; + GMainContext *context; + GError *error; + gboolean failed; + gboolean handle_cancellation; + GCancellable *check_cancellable; + + gpointer source_tag; + + union { + gpointer v_pointer; + gboolean v_boolean; + gssize v_ssize; + } op_res; + + GDestroyNotify destroy_op_res; +}; + +struct _GSimpleAsyncResultClass +{ + GObjectClass parent_class; +}; + + +G_DEFINE_TYPE_WITH_CODE (GSimpleAsyncResult, g_simple_async_result, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, + g_simple_async_result_async_result_iface_init)) + +static void +clear_op_res (GSimpleAsyncResult *simple) +{ + if (simple->destroy_op_res) + simple->destroy_op_res (simple->op_res.v_pointer); + simple->destroy_op_res = NULL; + simple->op_res.v_ssize = 0; +} + +static void +g_simple_async_result_finalize (GObject *object) +{ + GSimpleAsyncResult *simple; + + simple = G_SIMPLE_ASYNC_RESULT (object); + + if (simple->source_object) + g_object_unref (simple->source_object); + + if (simple->check_cancellable) + g_object_unref (simple->check_cancellable); + + g_main_context_unref (simple->context); + + clear_op_res (simple); + + if (simple->error) + g_error_free (simple->error); + + G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize (object); +} + +static void +g_simple_async_result_class_init (GSimpleAsyncResultClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_simple_async_result_finalize; +} + +static void +g_simple_async_result_init (GSimpleAsyncResult *simple) +{ + simple->handle_cancellation = TRUE; + + simple->context = g_main_context_ref_thread_default (); +} + +/** + * g_simple_async_result_new: + * @source_object: (nullable): a #GObject, or %NULL. + * @callback: (scope async): a #GAsyncReadyCallback. + * @user_data: (closure): user data passed to @callback. + * @source_tag: the asynchronous function. + * + * Creates a #GSimpleAsyncResult. + * + * The common convention is to create the #GSimpleAsyncResult in the + * function that starts the asynchronous operation and use that same + * function as the @source_tag. + * + * If your operation supports cancellation with #GCancellable (which it + * probably should) then you should provide the user's cancellable to + * g_simple_async_result_set_check_cancellable() immediately after + * this function returns. + * + * Returns: a #GSimpleAsyncResult. + * + * Deprecated: 2.46: Use g_task_new() instead. + **/ +GSimpleAsyncResult * +g_simple_async_result_new (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + gpointer source_tag) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL); + + simple = g_object_new (G_TYPE_SIMPLE_ASYNC_RESULT, NULL); + simple->callback = callback; + if (source_object) + simple->source_object = g_object_ref (source_object); + else + simple->source_object = NULL; + simple->user_data = user_data; + simple->source_tag = source_tag; + + return simple; +} + +/** + * g_simple_async_result_new_from_error: + * @source_object: (nullable): a #GObject, or %NULL. + * @callback: (scope async): a #GAsyncReadyCallback. + * @user_data: (closure): user data passed to @callback. + * @error: a #GError + * + * Creates a #GSimpleAsyncResult from an error condition. + * + * Returns: a #GSimpleAsyncResult. + * + * Deprecated: 2.46: Use g_task_new() and g_task_return_error() instead. + **/ +GSimpleAsyncResult * +g_simple_async_result_new_from_error (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + const GError *error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL); + + simple = g_simple_async_result_new (source_object, + callback, + user_data, NULL); + g_simple_async_result_set_from_error (simple, error); + + return simple; +} + +/** + * g_simple_async_result_new_take_error: (skip) + * @source_object: (nullable): a #GObject, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data passed to @callback + * @error: a #GError + * + * Creates a #GSimpleAsyncResult from an error condition, and takes over the + * caller's ownership of @error, so the caller does not need to free it anymore. + * + * Returns: a #GSimpleAsyncResult + * + * Since: 2.28 + * + * Deprecated: 2.46: Use g_task_new() and g_task_return_error() instead. + **/ +GSimpleAsyncResult * +g_simple_async_result_new_take_error (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL); + + simple = g_simple_async_result_new (source_object, + callback, + user_data, NULL); + g_simple_async_result_take_error (simple, error); + + return simple; +} + +/** + * g_simple_async_result_new_error: + * @source_object: (nullable): a #GObject, or %NULL. + * @callback: (scope async): a #GAsyncReadyCallback. + * @user_data: (closure): user data passed to @callback. + * @domain: a #GQuark. + * @code: an error code. + * @format: a string with format characters. + * @...: a list of values to insert into @format. + * + * Creates a new #GSimpleAsyncResult with a set error. + * + * Returns: a #GSimpleAsyncResult. + * + * Deprecated: 2.46: Use g_task_new() and g_task_return_new_error() instead. + **/ +GSimpleAsyncResult * +g_simple_async_result_new_error (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + GQuark domain, + gint code, + const char *format, + ...) +{ + GSimpleAsyncResult *simple; + va_list args; + + g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL); + g_return_val_if_fail (domain != 0, NULL); + g_return_val_if_fail (format != NULL, NULL); + + simple = g_simple_async_result_new (source_object, + callback, + user_data, NULL); + + va_start (args, format); + g_simple_async_result_set_error_va (simple, domain, code, format, args); + va_end (args); + + return simple; +} + + +static gpointer +g_simple_async_result_get_user_data (GAsyncResult *res) +{ + return G_SIMPLE_ASYNC_RESULT (res)->user_data; +} + +static GObject * +g_simple_async_result_get_source_object (GAsyncResult *res) +{ + if (G_SIMPLE_ASYNC_RESULT (res)->source_object) + return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object); + return NULL; +} + +static gboolean +g_simple_async_result_is_tagged (GAsyncResult *res, + gpointer source_tag) +{ + return G_SIMPLE_ASYNC_RESULT (res)->source_tag == source_tag; +} + +static void +g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface) +{ + iface->get_user_data = g_simple_async_result_get_user_data; + iface->get_source_object = g_simple_async_result_get_source_object; + iface->is_tagged = g_simple_async_result_is_tagged; +} + +/** + * g_simple_async_result_set_handle_cancellation: + * @simple: a #GSimpleAsyncResult. + * @handle_cancellation: a #gboolean. + * + * Sets whether to handle cancellation within the asynchronous operation. + * + * This function has nothing to do with + * g_simple_async_result_set_check_cancellable(). It only refers to the + * #GCancellable passed to g_simple_async_result_run_in_thread(). + * + * Deprecated: 2.46 + **/ +void +g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple, + gboolean handle_cancellation) +{ + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + simple->handle_cancellation = handle_cancellation; +} + +/** + * g_simple_async_result_get_source_tag: (skip) + * @simple: a #GSimpleAsyncResult. + * + * Gets the source tag for the #GSimpleAsyncResult. + * + * Returns: a #gpointer to the source object for the #GSimpleAsyncResult. + * + * Deprecated: 2.46. Use #GTask and g_task_get_source_tag() instead. + **/ +gpointer +g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple) +{ + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL); + return simple->source_tag; +} + +/** + * g_simple_async_result_propagate_error: + * @simple: a #GSimpleAsyncResult. + * @dest: (out): a location to propagate the error to. + * + * Propagates an error from within the simple asynchronous result to + * a given destination. + * + * If the #GCancellable given to a prior call to + * g_simple_async_result_set_check_cancellable() is cancelled then this + * function will return %TRUE with @dest set appropriately. + * + * Returns: %TRUE if the error was propagated to @dest. %FALSE otherwise. + * + * Deprecated: 2.46: Use #GTask instead. + **/ +gboolean +g_simple_async_result_propagate_error (GSimpleAsyncResult *simple, + GError **dest) +{ + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE); + + if (g_cancellable_set_error_if_cancelled (simple->check_cancellable, dest)) + return TRUE; + + if (simple->failed) + { + g_propagate_error (dest, simple->error); + simple->error = NULL; + return TRUE; + } + + return FALSE; +} + +/** + * g_simple_async_result_set_op_res_gpointer: (skip) + * @simple: a #GSimpleAsyncResult. + * @op_res: a pointer result from an asynchronous function. + * @destroy_op_res: a #GDestroyNotify function. + * + * Sets the operation result within the asynchronous result to a pointer. + * + * Deprecated: 2.46: Use #GTask and g_task_return_pointer() instead. + **/ +void +g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple, + gpointer op_res, + GDestroyNotify destroy_op_res) +{ + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + + clear_op_res (simple); + simple->op_res.v_pointer = op_res; + simple->destroy_op_res = destroy_op_res; +} + +/** + * g_simple_async_result_get_op_res_gpointer: (skip) + * @simple: a #GSimpleAsyncResult. + * + * Gets a pointer result as returned by the asynchronous function. + * + * Returns: a pointer from the result. + * + * Deprecated: 2.46: Use #GTask and g_task_propagate_pointer() instead. + **/ +gpointer +g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple) +{ + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL); + return simple->op_res.v_pointer; +} + +/** + * g_simple_async_result_set_op_res_gssize: + * @simple: a #GSimpleAsyncResult. + * @op_res: a #gssize. + * + * Sets the operation result within the asynchronous result to + * the given @op_res. + * + * Deprecated: 2.46: Use #GTask and g_task_return_int() instead. + **/ +void +g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple, + gssize op_res) +{ + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + clear_op_res (simple); + simple->op_res.v_ssize = op_res; +} + +/** + * g_simple_async_result_get_op_res_gssize: + * @simple: a #GSimpleAsyncResult. + * + * Gets a gssize from the asynchronous result. + * + * Returns: a gssize returned from the asynchronous function. + * + * Deprecated: 2.46: Use #GTask and g_task_propagate_int() instead. + **/ +gssize +g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple) +{ + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0); + return simple->op_res.v_ssize; +} + +/** + * g_simple_async_result_set_op_res_gboolean: + * @simple: a #GSimpleAsyncResult. + * @op_res: a #gboolean. + * + * Sets the operation result to a boolean within the asynchronous result. + * + * Deprecated: 2.46: Use #GTask and g_task_return_boolean() instead. + **/ +void +g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple, + gboolean op_res) +{ + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + clear_op_res (simple); + simple->op_res.v_boolean = !!op_res; +} + +/** + * g_simple_async_result_get_op_res_gboolean: + * @simple: a #GSimpleAsyncResult. + * + * Gets the operation result boolean from within the asynchronous result. + * + * Returns: %TRUE if the operation's result was %TRUE, %FALSE + * if the operation's result was %FALSE. + * + * Deprecated: 2.46: Use #GTask and g_task_propagate_boolean() instead. + **/ +gboolean +g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple) +{ + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE); + return simple->op_res.v_boolean; +} + +/** + * g_simple_async_result_set_from_error: + * @simple: a #GSimpleAsyncResult. + * @error: #GError. + * + * Sets the result from a #GError. + * + * Deprecated: 2.46: Use #GTask and g_task_return_error() instead. + **/ +void +g_simple_async_result_set_from_error (GSimpleAsyncResult *simple, + const GError *error) +{ + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + g_return_if_fail (error != NULL); + + if (simple->error) + g_error_free (simple->error); + simple->error = g_error_copy (error); + simple->failed = TRUE; +} + +/** + * g_simple_async_result_take_error: (skip) + * @simple: a #GSimpleAsyncResult + * @error: a #GError + * + * Sets the result from @error, and takes over the caller's ownership + * of @error, so the caller does not need to free it any more. + * + * Since: 2.28 + * + * Deprecated: 2.46: Use #GTask and g_task_return_error() instead. + **/ +void +g_simple_async_result_take_error (GSimpleAsyncResult *simple, + GError *error) +{ + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + g_return_if_fail (error != NULL); + + if (simple->error) + g_error_free (simple->error); + simple->error = error; + simple->failed = TRUE; +} + +/** + * g_simple_async_result_set_error_va: (skip) + * @simple: a #GSimpleAsyncResult. + * @domain: a #GQuark (usually %G_IO_ERROR). + * @code: an error code. + * @format: a formatted error reporting string. + * @args: va_list of arguments. + * + * Sets an error within the asynchronous result without a #GError. + * Unless writing a binding, see g_simple_async_result_set_error(). + * + * Deprecated: 2.46: Use #GTask and g_task_return_error() instead. + **/ +void +g_simple_async_result_set_error_va (GSimpleAsyncResult *simple, + GQuark domain, + gint code, + const char *format, + va_list args) +{ + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + g_return_if_fail (domain != 0); + g_return_if_fail (format != NULL); + + if (simple->error) + g_error_free (simple->error); + simple->error = g_error_new_valist (domain, code, format, args); + simple->failed = TRUE; +} + +/** + * g_simple_async_result_set_error: (skip) + * @simple: a #GSimpleAsyncResult. + * @domain: a #GQuark (usually %G_IO_ERROR). + * @code: an error code. + * @format: a formatted error reporting string. + * @...: a list of variables to fill in @format. + * + * Sets an error within the asynchronous result without a #GError. + * + * Deprecated: 2.46: Use #GTask and g_task_return_new_error() instead. + **/ +void +g_simple_async_result_set_error (GSimpleAsyncResult *simple, + GQuark domain, + gint code, + const char *format, + ...) +{ + va_list args; + + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + g_return_if_fail (domain != 0); + g_return_if_fail (format != NULL); + + va_start (args, format); + g_simple_async_result_set_error_va (simple, domain, code, format, args); + va_end (args); +} + +/** + * g_simple_async_result_complete: + * @simple: a #GSimpleAsyncResult. + * + * Completes an asynchronous I/O job immediately. Must be called in + * the thread where the asynchronous result was to be delivered, as it + * invokes the callback directly. If you are in a different thread use + * g_simple_async_result_complete_in_idle(). + * + * Calling this function takes a reference to @simple for as long as + * is needed to complete the call. + * + * Deprecated: 2.46: Use #GTask instead. + **/ +void +g_simple_async_result_complete (GSimpleAsyncResult *simple) +{ +#ifndef G_DISABLE_CHECKS + GSource *current_source; + GMainContext *current_context; +#endif + + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + +#ifndef G_DISABLE_CHECKS + current_source = g_main_current_source (); + if (current_source && !g_source_is_destroyed (current_source)) + { + current_context = g_source_get_context (current_source); + if (simple->context != current_context) + g_warning ("g_simple_async_result_complete() called from wrong context!"); + } +#endif + + if (simple->callback) + { + g_main_context_push_thread_default (simple->context); + simple->callback (simple->source_object, + G_ASYNC_RESULT (simple), + simple->user_data); + g_main_context_pop_thread_default (simple->context); + } +} + +static gboolean +complete_in_idle_cb (gpointer data) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data); + + g_simple_async_result_complete (simple); + + return FALSE; +} + +/** + * g_simple_async_result_complete_in_idle: + * @simple: a #GSimpleAsyncResult. + * + * Completes an asynchronous function in an idle handler in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread that @simple was initially created in + * (and re-pushes that context around the invocation of the callback). + * + * Calling this function takes a reference to @simple for as long as + * is needed to complete the call. + * + * Deprecated: 2.46: Use #GTask instead. + */ +void +g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple) +{ + GSource *source; + + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + + g_object_ref (simple); + + source = g_idle_source_new (); + g_source_set_priority (source, G_PRIORITY_DEFAULT); + g_source_set_callback (source, complete_in_idle_cb, simple, g_object_unref); + g_source_set_static_name (source, "[gio] complete_in_idle_cb"); + + g_source_attach (source, simple->context); + g_source_unref (source); +} + +typedef struct { + GSimpleAsyncResult *simple; + GCancellable *cancellable; + GSimpleAsyncThreadFunc func; +} RunInThreadData; + + +static gboolean +complete_in_idle_cb_for_thread (gpointer _data) +{ + RunInThreadData *data = _data; + GSimpleAsyncResult *simple; + + simple = data->simple; + + if (simple->handle_cancellation && + g_cancellable_is_cancelled (data->cancellable)) + g_simple_async_result_set_error (simple, + G_IO_ERROR, + G_IO_ERROR_CANCELLED, + "%s", _("Operation was cancelled")); + + g_simple_async_result_complete (simple); + + if (data->cancellable) + g_object_unref (data->cancellable); + g_object_unref (data->simple); + g_free (data); + + return FALSE; +} + +static gboolean +run_in_thread (GIOSchedulerJob *job, + GCancellable *c, + gpointer _data) +{ + RunInThreadData *data = _data; + GSimpleAsyncResult *simple = data->simple; + GSource *source; + + if (simple->handle_cancellation && + g_cancellable_is_cancelled (c)) + g_simple_async_result_set_error (simple, + G_IO_ERROR, + G_IO_ERROR_CANCELLED, + "%s", _("Operation was cancelled")); + else + data->func (simple, + simple->source_object, + c); + + source = g_idle_source_new (); + g_source_set_priority (source, G_PRIORITY_DEFAULT); + g_source_set_callback (source, complete_in_idle_cb_for_thread, data, NULL); + g_source_set_static_name (source, "[gio] complete_in_idle_cb_for_thread"); + + g_source_attach (source, simple->context); + g_source_unref (source); + + return FALSE; +} + +/** + * g_simple_async_result_run_in_thread: (skip) + * @simple: a #GSimpleAsyncResult. + * @func: a #GSimpleAsyncThreadFunc. + * @io_priority: the io priority of the request. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * + * Runs the asynchronous job in a separate thread and then calls + * g_simple_async_result_complete_in_idle() on @simple to return + * the result to the appropriate main loop. + * + * Calling this function takes a reference to @simple for as long as + * is needed to run the job and report its completion. + * + * Deprecated: 2.46: Use #GTask and g_task_run_in_thread() instead. + */ +void +g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple, + GSimpleAsyncThreadFunc func, + int io_priority, + GCancellable *cancellable) +{ + RunInThreadData *data; + + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + g_return_if_fail (func != NULL); + + data = g_new (RunInThreadData, 1); + data->func = func; + data->simple = g_object_ref (simple); + data->cancellable = cancellable; + if (cancellable) + g_object_ref (cancellable); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable); + G_GNUC_END_IGNORE_DEPRECATIONS; +} + +/** + * g_simple_async_result_is_valid: + * @result: the #GAsyncResult passed to the _finish function. + * @source: (nullable): the #GObject passed to the _finish function. + * @source_tag: (nullable): the asynchronous function. + * + * Ensures that the data passed to the _finish function of an async + * operation is consistent. Three checks are performed. + * + * First, @result is checked to ensure that it is really a + * #GSimpleAsyncResult. Second, @source is checked to ensure that it + * matches the source object of @result. Third, @source_tag is + * checked to ensure that it is equal to the @source_tag argument given + * to g_simple_async_result_new() (which, by convention, is a pointer + * to the _async function corresponding to the _finish function from + * which this function is called). (Alternatively, if either + * @source_tag or @result's source tag is %NULL, then the source tag + * check is skipped.) + * + * Returns: #TRUE if all checks passed or #FALSE if any failed. + * + * Since: 2.20 + * + * Deprecated: 2.46: Use #GTask and g_task_is_valid() instead. + **/ +gboolean +g_simple_async_result_is_valid (GAsyncResult *result, + GObject *source, + gpointer source_tag) +{ + GSimpleAsyncResult *simple; + GObject *cmp_source; + gpointer result_source_tag; + + if (!G_IS_SIMPLE_ASYNC_RESULT (result)) + return FALSE; + simple = (GSimpleAsyncResult *)result; + + cmp_source = g_async_result_get_source_object (result); + if (cmp_source != source) + { + if (cmp_source != NULL) + g_object_unref (cmp_source); + return FALSE; + } + if (cmp_source != NULL) + g_object_unref (cmp_source); + + result_source_tag = g_simple_async_result_get_source_tag (simple); + return source_tag == NULL || result_source_tag == NULL || + source_tag == result_source_tag; +} + +/** + * g_simple_async_report_error_in_idle: (skip) + * @object: (nullable): a #GObject, or %NULL. + * @callback: a #GAsyncReadyCallback. + * @user_data: user data passed to @callback. + * @domain: a #GQuark containing the error domain (usually %G_IO_ERROR). + * @code: a specific error code. + * @format: a formatted error reporting string. + * @...: a list of variables to fill in @format. + * + * Reports an error in an asynchronous function in an idle function by + * directly setting the contents of the #GAsyncResult with the given error + * information. + * + * Deprecated: 2.46: Use g_task_report_error(). + **/ +void +g_simple_async_report_error_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GQuark domain, + gint code, + const char *format, + ...) +{ + GSimpleAsyncResult *simple; + va_list args; + + g_return_if_fail (!object || G_IS_OBJECT (object)); + g_return_if_fail (domain != 0); + g_return_if_fail (format != NULL); + + simple = g_simple_async_result_new (object, + callback, + user_data, NULL); + + va_start (args, format); + g_simple_async_result_set_error_va (simple, domain, code, format, args); + va_end (args); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + +/** + * g_simple_async_report_gerror_in_idle: + * @object: (nullable): a #GObject, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback. + * @user_data: (closure): user data passed to @callback. + * @error: the #GError to report + * + * Reports an error in an idle function. Similar to + * g_simple_async_report_error_in_idle(), but takes a #GError rather + * than building a new one. + * + * Deprecated: 2.46: Use g_task_report_error(). + **/ +void +g_simple_async_report_gerror_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + const GError *error) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (!object || G_IS_OBJECT (object)); + g_return_if_fail (error != NULL); + + simple = g_simple_async_result_new_from_error (object, + callback, + user_data, + error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + +/** + * g_simple_async_report_take_gerror_in_idle: (skip) + * @object: (nullable): a #GObject, or %NULL + * @callback: a #GAsyncReadyCallback. + * @user_data: user data passed to @callback. + * @error: the #GError to report + * + * Reports an error in an idle function. Similar to + * g_simple_async_report_gerror_in_idle(), but takes over the caller's + * ownership of @error, so the caller does not have to free it any more. + * + * Since: 2.28 + * + * Deprecated: 2.46: Use g_task_report_error(). + **/ +void +g_simple_async_report_take_gerror_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (!object || G_IS_OBJECT (object)); + g_return_if_fail (error != NULL); + + simple = g_simple_async_result_new_take_error (object, + callback, + user_data, + error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + +/** + * g_simple_async_result_set_check_cancellable: + * @simple: a #GSimpleAsyncResult + * @check_cancellable: (nullable): a #GCancellable to check, or %NULL to unset + * + * Sets a #GCancellable to check before dispatching results. + * + * This function has one very specific purpose: the provided cancellable + * is checked at the time of g_simple_async_result_propagate_error() If + * it is cancelled, these functions will return an "Operation was + * cancelled" error (%G_IO_ERROR_CANCELLED). + * + * Implementors of cancellable asynchronous functions should use this in + * order to provide a guarantee to their callers that cancelling an + * async operation will reliably result in an error being returned for + * that operation (even if a positive result for the operation has + * already been sent as an idle to the main context to be dispatched). + * + * The checking described above is done regardless of any call to the + * unrelated g_simple_async_result_set_handle_cancellation() function. + * + * Since: 2.32 + * + * Deprecated: 2.46: Use #GTask instead. + **/ +void +g_simple_async_result_set_check_cancellable (GSimpleAsyncResult *simple, + GCancellable *check_cancellable) +{ + g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); + g_return_if_fail (check_cancellable == NULL || G_IS_CANCELLABLE (check_cancellable)); + + g_clear_object (&simple->check_cancellable); + if (check_cancellable) + simple->check_cancellable = g_object_ref (check_cancellable); +} + +G_GNUC_END_IGNORE_DEPRECATIONS diff --git a/gio/gsimpleasyncresult.h b/gio/gsimpleasyncresult.h new file mode 100644 index 0000000..8daa91d --- /dev/null +++ b/gio/gsimpleasyncresult.h @@ -0,0 +1,162 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_SIMPLE_ASYNC_RESULT_H__ +#define __G_SIMPLE_ASYNC_RESULT_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SIMPLE_ASYNC_RESULT (g_simple_async_result_get_type ()) +#define G_SIMPLE_ASYNC_RESULT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SIMPLE_ASYNC_RESULT, GSimpleAsyncResult)) +#define G_SIMPLE_ASYNC_RESULT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SIMPLE_ASYNC_RESULT, GSimpleAsyncResultClass)) +#define G_IS_SIMPLE_ASYNC_RESULT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SIMPLE_ASYNC_RESULT)) +#define G_IS_SIMPLE_ASYNC_RESULT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SIMPLE_ASYNC_RESULT)) +#define G_SIMPLE_ASYNC_RESULT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SIMPLE_ASYNC_RESULT, GSimpleAsyncResultClass)) + +/** + * GSimpleAsyncResult: + * + * A simple implementation of #GAsyncResult. + **/ +typedef struct _GSimpleAsyncResultClass GSimpleAsyncResultClass; + + +GLIB_AVAILABLE_IN_ALL +GType g_simple_async_result_get_type (void) G_GNUC_CONST; + +GLIB_DEPRECATED_IN_2_46_FOR(g_task_new) +GSimpleAsyncResult *g_simple_async_result_new (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + gpointer source_tag); +GLIB_DEPRECATED_IN_2_46_FOR(g_task_new) +GSimpleAsyncResult *g_simple_async_result_new_error (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + GQuark domain, + gint code, + const char *format, + ...) G_GNUC_PRINTF (6, 7); +GLIB_DEPRECATED_IN_2_46_FOR(g_task_new) +GSimpleAsyncResult *g_simple_async_result_new_from_error (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + const GError *error); +GLIB_DEPRECATED_IN_2_46_FOR(g_task_new) +GSimpleAsyncResult *g_simple_async_result_new_take_error (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error); + +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple, + gpointer op_res, + GDestroyNotify destroy_op_res); +GLIB_DEPRECATED_IN_2_46 +gpointer g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple); + +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple, + gssize op_res); +GLIB_DEPRECATED_IN_2_46 +gssize g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple); + +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple, + gboolean op_res); +GLIB_DEPRECATED_IN_2_46 +gboolean g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple); + + + +GLIB_AVAILABLE_IN_2_32 /* Also deprecated, but can't mark something both AVAILABLE and DEPRECATED */ +void g_simple_async_result_set_check_cancellable (GSimpleAsyncResult *simple, + GCancellable *check_cancellable); +GLIB_DEPRECATED_IN_2_46 +gpointer g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple); +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple, + gboolean handle_cancellation); +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_complete (GSimpleAsyncResult *simple); +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple); +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple, + GSimpleAsyncThreadFunc func, + int io_priority, + GCancellable *cancellable); +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_set_from_error (GSimpleAsyncResult *simple, + const GError *error); +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_take_error (GSimpleAsyncResult *simple, + GError *error); +GLIB_DEPRECATED_IN_2_46 +gboolean g_simple_async_result_propagate_error (GSimpleAsyncResult *simple, + GError **dest); +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_set_error (GSimpleAsyncResult *simple, + GQuark domain, + gint code, + const char *format, + ...) G_GNUC_PRINTF (4, 5); +GLIB_DEPRECATED_IN_2_46 +void g_simple_async_result_set_error_va (GSimpleAsyncResult *simple, + GQuark domain, + gint code, + const char *format, + va_list args) + G_GNUC_PRINTF(4, 0); +GLIB_DEPRECATED_IN_2_46 +gboolean g_simple_async_result_is_valid (GAsyncResult *result, + GObject *source, + gpointer source_tag); + +GLIB_DEPRECATED_IN_2_46_FOR(g_task_report_error) +void g_simple_async_report_error_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GQuark domain, + gint code, + const char *format, + ...) G_GNUC_PRINTF(6, 7); +GLIB_DEPRECATED_IN_2_46_FOR(g_task_report_error) +void g_simple_async_report_gerror_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + const GError *error); +GLIB_DEPRECATED_IN_2_46_FOR(g_task_report_error) +void g_simple_async_report_take_gerror_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error); + +G_END_DECLS + + + +#endif /* __G_SIMPLE_ASYNC_RESULT_H__ */ diff --git a/gio/gsimpleiostream.c b/gio/gsimpleiostream.c new file mode 100644 index 0000000..77f65cc --- /dev/null +++ b/gio/gsimpleiostream.c @@ -0,0 +1,222 @@ +/* + * Copyright © 2014 NICE s.r.l. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ignacio Casal Quinteiro + */ + + +#include "config.h" +#include +#include "glibintl.h" + +#include "gsimpleiostream.h" +#include "gtask.h" + +/** + * SECTION:gsimpleiostream + * @short_description: A wrapper around an input and an output stream. + * @include: gio/gio.h + * @see_also: #GIOStream + * + * GSimpleIOStream creates a #GIOStream from an arbitrary #GInputStream and + * #GOutputStream. This allows any pair of input and output streams to be used + * with #GIOStream methods. + * + * This is useful when you obtained a #GInputStream and a #GOutputStream + * by other means, for instance creating them with platform specific methods as + * g_unix_input_stream_new() or g_win32_input_stream_new(), and you want + * to take advantage of the methods provided by #GIOStream. + * + * Since: 2.44 + */ + +/** + * GSimpleIOStream: + * + * A wrapper around a #GInputStream and a #GOutputStream. + * + * Since: 2.44 + */ +struct _GSimpleIOStream +{ + GIOStream parent; + + GInputStream *input_stream; + GOutputStream *output_stream; +}; + +struct _GSimpleIOStreamClass +{ + GIOStreamClass parent; +}; + +typedef struct _GSimpleIOStreamClass GSimpleIOStreamClass; + +enum +{ + PROP_0, + PROP_INPUT_STREAM, + PROP_OUTPUT_STREAM +}; + +G_DEFINE_TYPE (GSimpleIOStream, g_simple_io_stream, G_TYPE_IO_STREAM) + +static void +g_simple_io_stream_finalize (GObject *object) +{ + GSimpleIOStream *stream = G_SIMPLE_IO_STREAM (object); + + if (stream->input_stream) + g_object_unref (stream->input_stream); + + if (stream->output_stream) + g_object_unref (stream->output_stream); + + G_OBJECT_CLASS (g_simple_io_stream_parent_class)->finalize (object); +} + +static void +g_simple_io_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSimpleIOStream *stream = G_SIMPLE_IO_STREAM (object); + + switch (prop_id) + { + case PROP_INPUT_STREAM: + stream->input_stream = g_value_dup_object (value); + break; + + case PROP_OUTPUT_STREAM: + stream->output_stream = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_simple_io_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSimpleIOStream *stream = G_SIMPLE_IO_STREAM (object); + + switch (prop_id) + { + case PROP_INPUT_STREAM: + g_value_set_object (value, stream->input_stream); + break; + + case PROP_OUTPUT_STREAM: + g_value_set_object (value, stream->output_stream); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GInputStream * +g_simple_io_stream_get_input_stream (GIOStream *stream) +{ + GSimpleIOStream *simple_stream = G_SIMPLE_IO_STREAM (stream); + + return simple_stream->input_stream; +} + +static GOutputStream * +g_simple_io_stream_get_output_stream (GIOStream *stream) +{ + GSimpleIOStream *simple_stream = G_SIMPLE_IO_STREAM (stream); + + return simple_stream->output_stream; +} + +static void +g_simple_io_stream_class_init (GSimpleIOStreamClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + GIOStreamClass *io_class = G_IO_STREAM_CLASS (class); + + gobject_class->finalize = g_simple_io_stream_finalize; + gobject_class->get_property = g_simple_io_stream_get_property; + gobject_class->set_property = g_simple_io_stream_set_property; + + io_class->get_input_stream = g_simple_io_stream_get_input_stream; + io_class->get_output_stream = g_simple_io_stream_get_output_stream; + + /** + * GSimpleIOStream:input-stream: + * + * Since: 2.44 + */ + g_object_class_install_property (gobject_class, PROP_INPUT_STREAM, + g_param_spec_object ("input-stream", + P_("Input stream"), + P_("The GInputStream to read from"), + G_TYPE_INPUT_STREAM, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY)); + + /** + * GSimpleIOStream:output-stream: + * + * Since: 2.44 + */ + g_object_class_install_property (gobject_class, PROP_OUTPUT_STREAM, + g_param_spec_object ("output-stream", + P_("Output stream"), + P_("The GOutputStream to write to"), + G_TYPE_OUTPUT_STREAM, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +g_simple_io_stream_init (GSimpleIOStream *stream) +{ +} + +/** + * g_simple_io_stream_new: + * @input_stream: a #GInputStream. + * @output_stream: a #GOutputStream. + * + * Creates a new #GSimpleIOStream wrapping @input_stream and @output_stream. + * See also #GIOStream. + * + * Returns: a new #GSimpleIOStream instance. + * + * Since: 2.44 + */ +GIOStream * +g_simple_io_stream_new (GInputStream *input_stream, + GOutputStream *output_stream) +{ + return g_object_new (G_TYPE_SIMPLE_IO_STREAM, + "input-stream", input_stream, + "output-stream", output_stream, + NULL); +} diff --git a/gio/gsimpleiostream.h b/gio/gsimpleiostream.h new file mode 100644 index 0000000..37919d3 --- /dev/null +++ b/gio/gsimpleiostream.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2014 NICE s.r.l. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ignacio Casal Quinteiro + */ + +#ifndef __G_SIMPLE_IO_STREAM_H__ +#define __G_SIMPLE_IO_STREAM_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_SIMPLE_IO_STREAM (g_simple_io_stream_get_type ()) +#define G_SIMPLE_IO_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SIMPLE_IO_STREAM, GSimpleIOStream)) +#define G_IS_SIMPLE_IO_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SIMPLE_IO_STREAM)) + +GLIB_AVAILABLE_IN_2_44 +GType g_simple_io_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_44 +GIOStream *g_simple_io_stream_new (GInputStream *input_stream, + GOutputStream *output_stream); + +G_END_DECLS + +#endif /* __G_SIMPLE_IO_STREAM_H__ */ diff --git a/gio/gsimplepermission.c b/gio/gsimplepermission.c new file mode 100644 index 0000000..5ec88b8 --- /dev/null +++ b/gio/gsimplepermission.c @@ -0,0 +1,84 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gsimplepermission.h" +#include "gpermission.h" + + +/** + * SECTION:gsimplepermission + * @title: GSimplePermission + * @short_description: A GPermission that doesn't change value + * @include: gio/gio.h + * + * #GSimplePermission is a trivial implementation of #GPermission that + * represents a permission that is either always or never allowed. The + * value is given at construction and doesn't change. + * + * Calling request or release will result in errors. + **/ + +/** + * GSimplePermission: + * + * #GSimplePermission is an opaque data structure. There are no methods + * except for those defined by #GPermission. + **/ + +typedef GPermissionClass GSimplePermissionClass; + +struct _GSimplePermission +{ + GPermission parent_instance; +}; + +G_DEFINE_TYPE (GSimplePermission, g_simple_permission, G_TYPE_PERMISSION) + +static void +g_simple_permission_init (GSimplePermission *simple) +{ +} + +static void +g_simple_permission_class_init (GSimplePermissionClass *class) +{ +} + +/** + * g_simple_permission_new: + * @allowed: %TRUE if the action is allowed + * + * Creates a new #GPermission instance that represents an action that is + * either always or never allowed. + * + * Returns: the #GSimplePermission, as a #GPermission + * + * Since: 2.26 + **/ +GPermission * +g_simple_permission_new (gboolean allowed) +{ + GPermission *permission = g_object_new (G_TYPE_SIMPLE_PERMISSION, NULL); + + g_permission_impl_update (permission, allowed, FALSE, FALSE); + + return permission; +} diff --git a/gio/gsimplepermission.h b/gio/gsimplepermission.h new file mode 100644 index 0000000..11b8d12 --- /dev/null +++ b/gio/gsimplepermission.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_SIMPLE_PERMISSION_H__ +#define __G_SIMPLE_PERMISSION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SIMPLE_PERMISSION (g_simple_permission_get_type ()) +#define G_SIMPLE_PERMISSION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SIMPLE_PERMISSION, \ + GSimplePermission)) +#define G_IS_SIMPLE_PERMISSION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SIMPLE_PERMISSION)) + +GLIB_AVAILABLE_IN_ALL +GType g_simple_permission_get_type (void); +GLIB_AVAILABLE_IN_ALL +GPermission * g_simple_permission_new (gboolean allowed); + +G_END_DECLS + +#endif /* __G_SIMPLE_PERMISSION_H__ */ diff --git a/gio/gsimpleproxyresolver.c b/gio/gsimpleproxyresolver.c new file mode 100644 index 0000000..4cd3960 --- /dev/null +++ b/gio/gsimpleproxyresolver.c @@ -0,0 +1,597 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2010, 2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + */ + +#include "config.h" + +#include +#include + +#include "gsimpleproxyresolver.h" +#include "ginetaddress.h" +#include "ginetaddressmask.h" +#include "gnetworkingprivate.h" +#include "gtask.h" + +#include "glibintl.h" + +/** + * SECTION:gsimpleproxyresolver + * @short_description: Simple proxy resolver implementation + * @include: gio/gio.h + * @see_also: g_socket_client_set_proxy_resolver() + * + * #GSimpleProxyResolver is a simple #GProxyResolver implementation + * that handles a single default proxy, multiple URI-scheme-specific + * proxies, and a list of hosts that proxies should not be used for. + * + * #GSimpleProxyResolver is never the default proxy resolver, but it + * can be used as the base class for another proxy resolver + * implementation, or it can be created and used manually, such as + * with g_socket_client_set_proxy_resolver(). + * + * Since: 2.36 + */ + +typedef struct { + gchar *name; + gsize length; + gushort port; +} GSimpleProxyResolverDomain; + +struct _GSimpleProxyResolverPrivate { + gchar *default_proxy, **ignore_hosts; + GHashTable *uri_proxies; + + GPtrArray *ignore_ips; + GSimpleProxyResolverDomain *ignore_domains; +}; + +static void g_simple_proxy_resolver_iface_init (GProxyResolverInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GSimpleProxyResolver, g_simple_proxy_resolver, G_TYPE_OBJECT, + G_ADD_PRIVATE (GSimpleProxyResolver) + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER, + g_simple_proxy_resolver_iface_init)) + +enum +{ + PROP_0, + PROP_DEFAULT_PROXY, + PROP_IGNORE_HOSTS +}; + +static void reparse_ignore_hosts (GSimpleProxyResolver *resolver); + +static void +g_simple_proxy_resolver_finalize (GObject *object) +{ + GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object); + GSimpleProxyResolverPrivate *priv = resolver->priv; + + g_free (priv->default_proxy); + g_hash_table_destroy (priv->uri_proxies); + + g_clear_pointer (&priv->ignore_hosts, g_strfreev); + /* This will free ignore_ips and ignore_domains */ + reparse_ignore_hosts (resolver); + + G_OBJECT_CLASS (g_simple_proxy_resolver_parent_class)->finalize (object); +} + +static void +g_simple_proxy_resolver_init (GSimpleProxyResolver *resolver) +{ + resolver->priv = g_simple_proxy_resolver_get_instance_private (resolver); + resolver->priv->uri_proxies = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); +} + +static void +g_simple_proxy_resolver_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object); + + switch (prop_id) + { + case PROP_DEFAULT_PROXY: + g_simple_proxy_resolver_set_default_proxy (resolver, g_value_get_string (value)); + break; + + case PROP_IGNORE_HOSTS: + g_simple_proxy_resolver_set_ignore_hosts (resolver, g_value_get_boxed (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_simple_proxy_resolver_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object); + + switch (prop_id) + { + case PROP_DEFAULT_PROXY: + g_value_set_string (value, resolver->priv->default_proxy); + break; + + case PROP_IGNORE_HOSTS: + g_value_set_boxed (value, resolver->priv->ignore_hosts); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +reparse_ignore_hosts (GSimpleProxyResolver *resolver) +{ + GSimpleProxyResolverPrivate *priv = resolver->priv; + GPtrArray *ignore_ips; + GArray *ignore_domains; + gchar *host, *tmp, *colon, *bracket; + GInetAddress *iaddr; + GInetAddressMask *mask; + GSimpleProxyResolverDomain domain; + gushort port; + int i; + + if (priv->ignore_ips) + g_ptr_array_free (priv->ignore_ips, TRUE); + if (priv->ignore_domains) + { + for (i = 0; priv->ignore_domains[i].name; i++) + g_free (priv->ignore_domains[i].name); + g_free (priv->ignore_domains); + } + priv->ignore_ips = NULL; + priv->ignore_domains = NULL; + + if (!priv->ignore_hosts || !priv->ignore_hosts[0]) + return; + + ignore_ips = g_ptr_array_new_with_free_func (g_object_unref); + ignore_domains = g_array_new (TRUE, FALSE, sizeof (GSimpleProxyResolverDomain)); + + for (i = 0; priv->ignore_hosts[i]; i++) + { + host = g_strchomp (priv->ignore_hosts[i]); + + /* See if it's an IP address or IP/length mask */ + mask = g_inet_address_mask_new_from_string (host, NULL); + if (mask) + { + g_ptr_array_add (ignore_ips, mask); + continue; + } + + port = 0; + + if (*host == '[') + { + /* [IPv6]:port */ + host++; + bracket = strchr (host, ']'); + if (!bracket || !bracket[1] || bracket[1] != ':') + goto bad; + + port = strtoul (bracket + 2, &tmp, 10); + if (*tmp) + goto bad; + + *bracket = '\0'; + } + else + { + colon = strchr (host, ':'); + if (colon && !strchr (colon + 1, ':')) + { + /* hostname:port or IPv4:port */ + port = strtoul (colon + 1, &tmp, 10); + if (*tmp) + goto bad; + *colon = '\0'; + } + } + + iaddr = g_inet_address_new_from_string (host); + if (iaddr) + g_object_unref (iaddr); + else + { + if (g_str_has_prefix (host, "*.")) + host += 2; + else if (*host == '.') + host++; + } + + memset (&domain, 0, sizeof (domain)); + domain.name = g_strdup (host); + domain.length = strlen (domain.name); + domain.port = port; + g_array_append_val (ignore_domains, domain); + continue; + + bad: + g_warning ("Ignoring invalid ignore_hosts value '%s'", host); + } + + if (ignore_ips->len) + priv->ignore_ips = ignore_ips; + else + g_ptr_array_free (ignore_ips, TRUE); + + if (ignore_domains->len) + priv->ignore_domains = (GSimpleProxyResolverDomain *)ignore_domains->data; + g_array_free (ignore_domains, ignore_domains->len == 0); +} + +static gboolean +ignore_host (GSimpleProxyResolver *resolver, + const gchar *host, + gushort port) +{ + GSimpleProxyResolverPrivate *priv = resolver->priv; + gchar *ascii_host = NULL; + gboolean ignore = FALSE; + gsize offset, length; + guint i; + + if (priv->ignore_ips) + { + GInetAddress *iaddr; + + iaddr = g_inet_address_new_from_string (host); + if (iaddr) + { + for (i = 0; i < priv->ignore_ips->len; i++) + { + GInetAddressMask *mask = priv->ignore_ips->pdata[i]; + + if (g_inet_address_mask_matches (mask, iaddr)) + { + ignore = TRUE; + break; + } + } + + g_object_unref (iaddr); + if (ignore) + return TRUE; + } + } + + if (priv->ignore_domains) + { + length = 0; + if (g_hostname_is_non_ascii (host)) + host = ascii_host = g_hostname_to_ascii (host); + if (host) + length = strlen (host); + + for (i = 0; length > 0 && priv->ignore_domains[i].length; i++) + { + GSimpleProxyResolverDomain *domain = &priv->ignore_domains[i]; + + if (domain->length > length) + continue; + + offset = length - domain->length; + if ((domain->port == 0 || domain->port == port) && + (offset == 0 || (offset > 0 && host[offset - 1] == '.')) && + (g_ascii_strcasecmp (domain->name, host + offset) == 0)) + { + ignore = TRUE; + break; + } + } + + g_free (ascii_host); + } + + return ignore; +} + +static gchar ** +g_simple_proxy_resolver_lookup (GProxyResolver *proxy_resolver, + const gchar *uri, + GCancellable *cancellable, + GError **error) +{ + GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (proxy_resolver); + GSimpleProxyResolverPrivate *priv = resolver->priv; + const gchar *proxy = NULL; + gchar **proxies; + + if (priv->ignore_ips || priv->ignore_domains) + { + gchar *host = NULL; + gint port; + + if (g_uri_split_network (uri, G_URI_FLAGS_NONE, NULL, + &host, &port, NULL) && + ignore_host (resolver, host, port > 0 ? port : 0)) + proxy = "direct://"; + + g_free (host); + } + + if (!proxy && g_hash_table_size (priv->uri_proxies)) + { + gchar *scheme = g_ascii_strdown (uri, strcspn (uri, ":")); + + proxy = g_hash_table_lookup (priv->uri_proxies, scheme); + g_free (scheme); + } + + if (!proxy) + proxy = priv->default_proxy; + if (!proxy) + proxy = "direct://"; + + if (!strncmp (proxy, "socks://", 8)) + { + proxies = g_new0 (gchar *, 4); + proxies[0] = g_strdup_printf ("socks5://%s", proxy + 8); + proxies[1] = g_strdup_printf ("socks4a://%s", proxy + 8); + proxies[2] = g_strdup_printf ("socks4://%s", proxy + 8); + proxies[3] = NULL; + } + else + { + proxies = g_new0 (gchar *, 2); + proxies[0] = g_strdup (proxy); + } + + return proxies; +} + +static void +g_simple_proxy_resolver_lookup_async (GProxyResolver *proxy_resolver, + const gchar *uri, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (proxy_resolver); + GTask *task; + GError *error = NULL; + char **proxies; + + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, g_simple_proxy_resolver_lookup_async); + + proxies = g_simple_proxy_resolver_lookup (proxy_resolver, uri, + cancellable, &error); + if (proxies) + g_task_return_pointer (task, proxies, (GDestroyNotify)g_strfreev); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +static gchar ** +g_simple_proxy_resolver_lookup_finish (GProxyResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, resolver), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +g_simple_proxy_resolver_class_init (GSimpleProxyResolverClass *resolver_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (resolver_class); + + object_class->get_property = g_simple_proxy_resolver_get_property; + object_class->set_property = g_simple_proxy_resolver_set_property; + object_class->finalize = g_simple_proxy_resolver_finalize; + + /** + * GSimpleProxyResolver:default-proxy: (nullable) + * + * The default proxy URI that will be used for any URI that doesn't + * match #GSimpleProxyResolver:ignore-hosts, and doesn't match any + * of the schemes set with g_simple_proxy_resolver_set_uri_proxy(). + * + * Note that as a special case, if this URI starts with + * "socks://", #GSimpleProxyResolver will treat it as referring + * to all three of the socks5, socks4a, and socks4 proxy types. + */ + g_object_class_install_property (object_class, PROP_DEFAULT_PROXY, + g_param_spec_string ("default-proxy", + P_("Default proxy"), + P_("The default proxy URI"), + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSimpleProxyResolver:ignore-hosts: + * + * A list of hostnames and IP addresses that the resolver should + * allow direct connections to. + * + * Entries can be in one of 4 formats: + * + * - A hostname, such as "example.com", ".example.com", or + * "*.example.com", any of which match "example.com" or + * any subdomain of it. + * + * - An IPv4 or IPv6 address, such as "192.168.1.1", + * which matches only that address. + * + * - A hostname or IP address followed by a port, such as + * "example.com:80", which matches whatever the hostname or IP + * address would match, but only for URLs with the (explicitly) + * indicated port. In the case of an IPv6 address, the address + * part must appear in brackets: "[::1]:443" + * + * - An IP address range, given by a base address and prefix length, + * such as "fe80::/10", which matches any address in that range. + * + * Note that when dealing with Unicode hostnames, the matching is + * done against the ASCII form of the name. + * + * Also note that hostname exclusions apply only to connections made + * to hosts identified by name, and IP address exclusions apply only + * to connections made to hosts identified by address. That is, if + * example.com has an address of 192.168.1.1, and the :ignore-hosts list + * contains only "192.168.1.1", then a connection to "example.com" + * (eg, via a #GNetworkAddress) will use the proxy, and a connection to + * "192.168.1.1" (eg, via a #GInetSocketAddress) will not. + * + * These rules match the "ignore-hosts"/"noproxy" rules most + * commonly used by other applications. + */ + g_object_class_install_property (object_class, PROP_IGNORE_HOSTS, + g_param_spec_boxed ("ignore-hosts", + P_("Ignore hosts"), + P_("Hosts that will not use the proxy"), + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + +} + +static void +g_simple_proxy_resolver_iface_init (GProxyResolverInterface *iface) +{ + iface->lookup = g_simple_proxy_resolver_lookup; + iface->lookup_async = g_simple_proxy_resolver_lookup_async; + iface->lookup_finish = g_simple_proxy_resolver_lookup_finish; +} + +/** + * g_simple_proxy_resolver_new: + * @default_proxy: (nullable): the default proxy to use, eg + * "socks://192.168.1.1" + * @ignore_hosts: (array zero-terminated=1) (nullable): an optional list of hosts/IP addresses + * to not use a proxy for. + * + * Creates a new #GSimpleProxyResolver. See + * #GSimpleProxyResolver:default-proxy and + * #GSimpleProxyResolver:ignore-hosts for more details on how the + * arguments are interpreted. + * + * Returns: (transfer full) a new #GSimpleProxyResolver + * + * Since: 2.36 + */ +GProxyResolver * +g_simple_proxy_resolver_new (const gchar *default_proxy, + gchar **ignore_hosts) +{ + return g_object_new (G_TYPE_SIMPLE_PROXY_RESOLVER, + "default-proxy", default_proxy, + "ignore-hosts", ignore_hosts, + NULL); +} + +/** + * g_simple_proxy_resolver_set_default_proxy: + * @resolver: a #GSimpleProxyResolver + * @default_proxy: (nullable): the default proxy to use + * + * Sets the default proxy on @resolver, to be used for any URIs that + * don't match #GSimpleProxyResolver:ignore-hosts or a proxy set + * via g_simple_proxy_resolver_set_uri_proxy(). + * + * If @default_proxy starts with "socks://", + * #GSimpleProxyResolver will treat it as referring to all three of + * the socks5, socks4a, and socks4 proxy types. + * + * Since: 2.36 + */ +void +g_simple_proxy_resolver_set_default_proxy (GSimpleProxyResolver *resolver, + const gchar *default_proxy) +{ + g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver)); + g_return_if_fail (default_proxy == NULL || g_uri_is_valid (default_proxy, G_URI_FLAGS_NONE, NULL)); + + g_free (resolver->priv->default_proxy); + resolver->priv->default_proxy = g_strdup (default_proxy); + g_object_notify (G_OBJECT (resolver), "default-proxy"); +} + +/** + * g_simple_proxy_resolver_set_ignore_hosts: + * @resolver: a #GSimpleProxyResolver + * @ignore_hosts: (array zero-terminated=1): %NULL-terminated list of hosts/IP addresses + * to not use a proxy for + * + * Sets the list of ignored hosts. + * + * See #GSimpleProxyResolver:ignore-hosts for more details on how the + * @ignore_hosts argument is interpreted. + * + * Since: 2.36 + */ +void +g_simple_proxy_resolver_set_ignore_hosts (GSimpleProxyResolver *resolver, + gchar **ignore_hosts) +{ + g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver)); + + g_strfreev (resolver->priv->ignore_hosts); + resolver->priv->ignore_hosts = g_strdupv (ignore_hosts); + reparse_ignore_hosts (resolver); + g_object_notify (G_OBJECT (resolver), "ignore-hosts"); +} + +/** + * g_simple_proxy_resolver_set_uri_proxy: + * @resolver: a #GSimpleProxyResolver + * @uri_scheme: the URI scheme to add a proxy for + * @proxy: the proxy to use for @uri_scheme + * + * Adds a URI-scheme-specific proxy to @resolver; URIs whose scheme + * matches @uri_scheme (and which don't match + * #GSimpleProxyResolver:ignore-hosts) will be proxied via @proxy. + * + * As with #GSimpleProxyResolver:default-proxy, if @proxy starts with + * "socks://", #GSimpleProxyResolver will treat it + * as referring to all three of the socks5, socks4a, and socks4 proxy + * types. + * + * Since: 2.36 + */ +void +g_simple_proxy_resolver_set_uri_proxy (GSimpleProxyResolver *resolver, + const gchar *uri_scheme, + const gchar *proxy) +{ + g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver)); + + g_hash_table_replace (resolver->priv->uri_proxies, + g_ascii_strdown (uri_scheme, -1), + g_strdup (proxy)); +} diff --git a/gio/gsimpleproxyresolver.h b/gio/gsimpleproxyresolver.h new file mode 100644 index 0000000..e1bb199 --- /dev/null +++ b/gio/gsimpleproxyresolver.h @@ -0,0 +1,89 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2010, 2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_SIMPLE_PROXY_RESOLVER_H__ +#define __G_SIMPLE_PROXY_RESOLVER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SIMPLE_PROXY_RESOLVER (g_simple_proxy_resolver_get_type ()) +#define G_SIMPLE_PROXY_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SIMPLE_PROXY_RESOLVER, GSimpleProxyResolver)) +#define G_SIMPLE_PROXY_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SIMPLE_PROXY_RESOLVER, GSimpleProxyResolverClass)) +#define G_IS_SIMPLE_PROXY_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SIMPLE_PROXY_RESOLVER)) +#define G_IS_SIMPLE_PROXY_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SIMPLE_PROXY_RESOLVER)) +#define G_SIMPLE_PROXY_RESOLVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SIMPLE_PROXY_RESOLVER, GSimpleProxyResolverClass)) + +/** + * GSimpleProxyResolver: + * + * A #GProxyResolver implementation for using a fixed set of proxies. + **/ +typedef struct _GSimpleProxyResolver GSimpleProxyResolver; +typedef struct _GSimpleProxyResolverPrivate GSimpleProxyResolverPrivate; +typedef struct _GSimpleProxyResolverClass GSimpleProxyResolverClass; + +struct _GSimpleProxyResolver +{ + GObject parent_instance; + + /*< private >*/ + GSimpleProxyResolverPrivate *priv; +}; + +struct _GSimpleProxyResolverClass +{ + GObjectClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_2_36 +GType g_simple_proxy_resolver_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_36 +GProxyResolver *g_simple_proxy_resolver_new (const gchar *default_proxy, + gchar **ignore_hosts); + +GLIB_AVAILABLE_IN_2_36 +void g_simple_proxy_resolver_set_default_proxy (GSimpleProxyResolver *resolver, + const gchar *default_proxy); + +GLIB_AVAILABLE_IN_2_36 +void g_simple_proxy_resolver_set_ignore_hosts (GSimpleProxyResolver *resolver, + gchar **ignore_hosts); + +GLIB_AVAILABLE_IN_2_36 +void g_simple_proxy_resolver_set_uri_proxy (GSimpleProxyResolver *resolver, + const gchar *uri_scheme, + const gchar *proxy); + +G_END_DECLS + +#endif /* __G_SIMPLE_PROXY_RESOLVER_H__ */ diff --git a/gio/gsocket.c b/gio/gsocket.c new file mode 100644 index 0000000..be5b96a --- /dev/null +++ b/gio/gsocket.c @@ -0,0 +1,6320 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * Copyright © 2009 Codethink Limited + * Copyright © 2009 Red Hat, Inc + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + * Alexander Larsson + * Philip Withnall + */ + +#include "config.h" + +#include "gsocket.h" + +#ifdef G_OS_UNIX +#include "glib-unix.h" +#endif + +#include +#include +#include +#include + +#ifndef G_OS_WIN32 +# include +# include +# include +#endif + +#ifdef HAVE_SIOCGIFADDR +#include +#endif + +#ifdef HAVE_SYS_FILIO_H +# include +#endif + +#ifdef G_OS_UNIX +#include +#endif + +#define GOBJECT_COMPILATION +#include "gobject/gtype-private.h" /* For _PRELUDE type define */ +#undef GOBJECT_COMPILATION +#include "gcancellable.h" +#include "gdatagrambased.h" +#include "gioenumtypes.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "ginitable.h" +#include "gioerror.h" +#include "gioenums.h" +#include "gioerror.h" +#include "gnetworkingprivate.h" +#include "gsocketaddress.h" +#include "gsocketcontrolmessage.h" +#include "gcredentials.h" +#include "gcredentialsprivate.h" +#include "glibintl.h" +#include "gioprivate.h" + +#ifdef G_OS_WIN32 +#include "giowin32-afunix.h" +#endif + +/** + * SECTION:gsocket + * @short_description: Low-level socket object + * @include: gio/gio.h + * @see_also: #GInitable, [][gio-gnetworking.h] + * + * A #GSocket is a low-level networking primitive. It is a more or less + * direct mapping of the BSD socket API in a portable GObject based API. + * It supports both the UNIX socket implementations and winsock2 on Windows. + * + * #GSocket is the platform independent base upon which the higher level + * network primitives are based. Applications are not typically meant to + * use it directly, but rather through classes like #GSocketClient, + * #GSocketService and #GSocketConnection. However there may be cases where + * direct use of #GSocket is useful. + * + * #GSocket implements the #GInitable interface, so if it is manually constructed + * by e.g. g_object_new() you must call g_initable_init() and check the + * results before using the object. This is done automatically in + * g_socket_new() and g_socket_new_from_fd(), so these functions can return + * %NULL. + * + * Sockets operate in two general modes, blocking or non-blocking. When + * in blocking mode all operations (which don’t take an explicit blocking + * parameter) block until the requested operation + * is finished or there is an error. In non-blocking mode all calls that + * would block return immediately with a %G_IO_ERROR_WOULD_BLOCK error. + * To know when a call would successfully run you can call g_socket_condition_check(), + * or g_socket_condition_wait(). You can also use g_socket_create_source() and + * attach it to a #GMainContext to get callbacks when I/O is possible. + * Note that all sockets are always set to non blocking mode in the system, and + * blocking mode is emulated in GSocket. + * + * When working in non-blocking mode applications should always be able to + * handle getting a %G_IO_ERROR_WOULD_BLOCK error even when some other + * function said that I/O was possible. This can easily happen in case + * of a race condition in the application, but it can also happen for other + * reasons. For instance, on Windows a socket is always seen as writable + * until a write returns %G_IO_ERROR_WOULD_BLOCK. + * + * #GSockets can be either connection oriented or datagram based. + * For connection oriented types you must first establish a connection by + * either connecting to an address or accepting a connection from another + * address. For connectionless socket types the target/source address is + * specified or received in each I/O operation. + * + * All socket file descriptors are set to be close-on-exec. + * + * Note that creating a #GSocket causes the signal %SIGPIPE to be + * ignored for the remainder of the program. If you are writing a + * command-line utility that uses #GSocket, you may need to take into + * account the fact that your program will not automatically be killed + * if it tries to write to %stdout after it has been closed. + * + * Like most other APIs in GLib, #GSocket is not inherently thread safe. To use + * a #GSocket concurrently from multiple threads, you must implement your own + * locking. + * + * Since: 2.22 + */ + +static void g_socket_initable_iface_init (GInitableIface *iface); +static gboolean g_socket_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error); + +static void g_socket_datagram_based_iface_init (GDatagramBasedInterface *iface); +static gint g_socket_datagram_based_receive_messages (GDatagramBased *self, + GInputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error); +static gint g_socket_datagram_based_send_messages (GDatagramBased *self, + GOutputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error); +static GSource *g_socket_datagram_based_create_source (GDatagramBased *self, + GIOCondition condition, + GCancellable *cancellable); +static GIOCondition g_socket_datagram_based_condition_check (GDatagramBased *datagram_based, + GIOCondition condition); +static gboolean g_socket_datagram_based_condition_wait (GDatagramBased *datagram_based, + GIOCondition condition, + gint64 timeout_us, + GCancellable *cancellable, + GError **error); + +static GSocketAddress * +cache_recv_address (GSocket *socket, struct sockaddr *native, size_t native_len); + +static gssize +g_socket_receive_message_with_timeout (GSocket *socket, + GSocketAddress **address, + GInputVector *vectors, + gint num_vectors, + GSocketControlMessage ***messages, + gint *num_messages, + gint *flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error); +static gint +g_socket_receive_messages_with_timeout (GSocket *socket, + GInputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error); +static gint +g_socket_send_messages_with_timeout (GSocket *socket, + GOutputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error); + +enum +{ + PROP_0, + PROP_FAMILY, + PROP_TYPE, + PROP_PROTOCOL, + PROP_FD, + PROP_BLOCKING, + PROP_LISTEN_BACKLOG, + PROP_KEEPALIVE, + PROP_LOCAL_ADDRESS, + PROP_REMOTE_ADDRESS, + PROP_TIMEOUT, + PROP_TTL, + PROP_BROADCAST, + PROP_MULTICAST_LOOPBACK, + PROP_MULTICAST_TTL +}; + +/* Size of the receiver cache for g_socket_receive_from() */ +#define RECV_ADDR_CACHE_SIZE 8 + +struct _GSocketPrivate +{ + GSocketFamily family; + GSocketType type; + GSocketProtocol protocol; + gint fd; + gint listen_backlog; + guint timeout; + GError *construct_error; + GSocketAddress *remote_address; + guint inited : 1; + guint blocking : 1; + guint keepalive : 1; + guint closed : 1; + guint connected_read : 1; + guint connected_write : 1; + guint listening : 1; + guint timed_out : 1; + guint connect_pending : 1; +#ifdef G_OS_WIN32 + WSAEVENT event; + gboolean waiting; + DWORD waiting_result; + int current_events; + int current_errors; + int selected_events; + GList *requested_conditions; /* list of requested GIOCondition * */ + GMutex win32_source_lock; + GCond win32_source_cond; +#endif + + struct { + GSocketAddress *addr; + struct sockaddr *native; + gsize native_len; + guint64 last_used; + } recv_addr_cache[RECV_ADDR_CACHE_SIZE]; +}; + +_G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE (GSocket, g_socket, G_TYPE_OBJECT, 0, + /* Need a prelude for https://bugzilla.gnome.org/show_bug.cgi?id=674885 */ + g_type_ensure (G_TYPE_SOCKET_FAMILY); + g_type_ensure (G_TYPE_SOCKET_TYPE); + g_type_ensure (G_TYPE_SOCKET_PROTOCOL); + g_type_ensure (G_TYPE_SOCKET_ADDRESS); + /* And networking init is appropriate for the prelude */ + g_networking_init (); + , /* And now the regular type init code */ + G_ADD_PRIVATE (GSocket) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_socket_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED, + g_socket_datagram_based_iface_init)); + +static int +get_socket_errno (void) +{ +#ifndef G_OS_WIN32 + return errno; +#else + return WSAGetLastError (); +#endif +} + +static GIOErrorEnum +socket_io_error_from_errno (int err) +{ +#ifdef G_OS_WIN32 + return g_io_error_from_win32_error (err); +#else + return g_io_error_from_errno (err); +#endif +} + +static const char * +socket_strerror (int err) +{ +#ifndef G_OS_WIN32 + return g_strerror (err); +#else + const char *msg_ret; + char *msg; + + msg = g_win32_error_message (err); + + msg_ret = g_intern_string (msg); + g_free (msg); + + return msg_ret; +#endif +} + +/* Wrapper around g_set_error() to avoid doing excess work */ +#define socket_set_error_lazy(err, errsv, fmt) \ + G_STMT_START { \ + GError **__err = (err); \ + int __errsv = (errsv); \ + \ + if (__err) \ + { \ + int __code = socket_io_error_from_errno (__errsv); \ + const char *__strerr = socket_strerror (__errsv); \ + \ + if (__code == G_IO_ERROR_WOULD_BLOCK) \ + g_set_error_literal (__err, G_IO_ERROR, __code, __strerr); \ + else \ + g_set_error (__err, G_IO_ERROR, __code, fmt, __strerr); \ + } \ + } G_STMT_END + +#ifdef G_OS_WIN32 +#define win32_unset_event_mask(_socket, _mask) _win32_unset_event_mask (_socket, _mask) +static void +_win32_unset_event_mask (GSocket *socket, int mask) +{ + g_mutex_lock (&socket->priv->win32_source_lock); + socket->priv->current_events &= ~mask; + socket->priv->current_errors &= ~mask; + g_mutex_unlock (&socket->priv->win32_source_lock); +} +#else +#define win32_unset_event_mask(_socket, _mask) +#endif + +/* Windows has broken prototypes... */ +#ifdef G_OS_WIN32 +#define getsockopt(sockfd, level, optname, optval, optlen) \ + getsockopt (sockfd, level, optname, (gpointer) optval, (int*) optlen) +#define setsockopt(sockfd, level, optname, optval, optlen) \ + setsockopt (sockfd, level, optname, (gpointer) optval, optlen) +#define getsockname(sockfd, addr, addrlen) \ + getsockname (sockfd, addr, (int *)addrlen) +#define getpeername(sockfd, addr, addrlen) \ + getpeername (sockfd, addr, (int *)addrlen) +#define recv(sockfd, buf, len, flags) \ + recv (sockfd, (gpointer)buf, len, flags) +#endif + +static gchar * +address_to_string (GSocketAddress *address) +{ + GString *ret = g_string_new (""); + + if (G_IS_INET_SOCKET_ADDRESS (address)) + { + GInetSocketAddress *isa = G_INET_SOCKET_ADDRESS (address); + GInetAddress *ia = g_inet_socket_address_get_address (isa); + GSocketFamily family = g_inet_address_get_family (ia); + gchar *tmp; + + /* Represent IPv6 addresses in URL style: + * ::1 port 12345 -> [::1]:12345 */ + if (family == G_SOCKET_FAMILY_IPV6) + g_string_append_c (ret, '['); + + tmp = g_inet_address_to_string (ia); + g_string_append (ret, tmp); + g_free (tmp); + + if (family == G_SOCKET_FAMILY_IPV6) + { + guint32 scope = g_inet_socket_address_get_scope_id (isa); + + if (scope != 0) + g_string_append_printf (ret, "%%%u", scope); + + g_string_append_c (ret, ']'); + } + + g_string_append_c (ret, ':'); + + g_string_append_printf (ret, "%u", g_inet_socket_address_get_port (isa)); + } + else + { + /* For unknown address types, just show the type */ + g_string_append_printf (ret, "(%s)", G_OBJECT_TYPE_NAME (address)); + } + + return g_string_free (ret, FALSE); +} + +static gboolean +check_socket (GSocket *socket, + GError **error) +{ + if (!socket->priv->inited) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, + _("Invalid socket, not initialized")); + return FALSE; + } + + if (socket->priv->construct_error) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, + _("Invalid socket, initialization failed due to: %s"), + socket->priv->construct_error->message); + return FALSE; + } + + if (socket->priv->closed) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Socket is already closed")); + return FALSE; + } + + return TRUE; +} + +static gboolean +check_timeout (GSocket *socket, + GError **error) +{ + if (socket->priv->timed_out) + { + socket->priv->timed_out = FALSE; + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Socket I/O timed out")); + return FALSE; + } + + return TRUE; +} + +static void +g_socket_details_from_fd (GSocket *socket) +{ + union { + struct sockaddr_storage storage; + struct sockaddr sa; + } address; + gint fd; + guint addrlen; + int value, family; + int errsv; + + fd = socket->priv->fd; + if (!g_socket_get_option (socket, SOL_SOCKET, SO_TYPE, &value, NULL)) + { + errsv = get_socket_errno (); + goto err; + } + + switch (value) + { + case SOCK_STREAM: + socket->priv->type = G_SOCKET_TYPE_STREAM; + break; + + case SOCK_DGRAM: + socket->priv->type = G_SOCKET_TYPE_DATAGRAM; + break; + + case SOCK_SEQPACKET: + socket->priv->type = G_SOCKET_TYPE_SEQPACKET; + break; + + default: + socket->priv->type = G_SOCKET_TYPE_INVALID; + break; + } + + addrlen = sizeof address; + if (getsockname (fd, &address.sa, &addrlen) != 0) + { + errsv = get_socket_errno (); + goto err; + } + + if (addrlen > 0) + { + g_assert (G_STRUCT_OFFSET (struct sockaddr, sa_family) + + sizeof address.storage.ss_family <= addrlen); + family = address.storage.ss_family; + } + else + { + /* On Solaris, this happens if the socket is not yet connected. + * But we can use SO_DOMAIN as a workaround there. + */ +#ifdef SO_DOMAIN + if (!g_socket_get_option (socket, SOL_SOCKET, SO_DOMAIN, &family, NULL)) + { + errsv = get_socket_errno (); + goto err; + } +#else + /* This will translate to G_IO_ERROR_FAILED on either unix or windows */ + errsv = -1; + goto err; +#endif + } + + switch (family) + { + case G_SOCKET_FAMILY_IPV4: + case G_SOCKET_FAMILY_IPV6: + socket->priv->family = address.storage.ss_family; + switch (socket->priv->type) + { + case G_SOCKET_TYPE_STREAM: + socket->priv->protocol = G_SOCKET_PROTOCOL_TCP; + break; + + case G_SOCKET_TYPE_DATAGRAM: + socket->priv->protocol = G_SOCKET_PROTOCOL_UDP; + break; + + case G_SOCKET_TYPE_SEQPACKET: + socket->priv->protocol = G_SOCKET_PROTOCOL_SCTP; + break; + + default: + break; + } + break; + + case G_SOCKET_FAMILY_UNIX: + socket->priv->family = G_SOCKET_FAMILY_UNIX; + socket->priv->protocol = G_SOCKET_PROTOCOL_DEFAULT; + break; + + default: + socket->priv->family = G_SOCKET_FAMILY_INVALID; + break; + } + + if (socket->priv->family != G_SOCKET_FAMILY_INVALID) + { + addrlen = sizeof address; + if (getpeername (fd, &address.sa, &addrlen) >= 0) + { + socket->priv->connected_read = TRUE; + socket->priv->connected_write = TRUE; + } + } + + if (g_socket_get_option (socket, SOL_SOCKET, SO_KEEPALIVE, &value, NULL)) + { + socket->priv->keepalive = !!value; + } + else + { + /* Can't read, maybe not supported, assume FALSE */ + socket->priv->keepalive = FALSE; + } + + return; + + err: + g_set_error (&socket->priv->construct_error, G_IO_ERROR, + socket_io_error_from_errno (errsv), + _("creating GSocket from fd: %s"), + socket_strerror (errsv)); +} + +/* Wrapper around socket() that is shared with gnetworkmonitornetlink.c */ +gint +g_socket (gint domain, + gint type, + gint protocol, + GError **error) +{ + int fd, errsv; + +#ifdef SOCK_CLOEXEC + fd = socket (domain, type | SOCK_CLOEXEC, protocol); + errsv = errno; + if (fd != -1) + return fd; + + /* It's possible that libc has SOCK_CLOEXEC but the kernel does not */ + if (fd < 0 && (errsv == EINVAL || errsv == EPROTOTYPE)) +#endif + fd = socket (domain, type, protocol); + + if (fd < 0) + { + errsv = get_socket_errno (); + + g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), + _("Unable to create socket: %s"), socket_strerror (errsv)); + errno = errsv; + return -1; + } + +#ifndef G_OS_WIN32 + { + int flags; + + /* We always want to set close-on-exec to protect users. If you + need to so some weird inheritance to exec you can re-enable this + using lower level hacks with g_socket_get_fd(). */ + flags = fcntl (fd, F_GETFD, 0); + if (flags != -1 && + (flags & FD_CLOEXEC) == 0) + { + flags |= FD_CLOEXEC; + (void) fcntl (fd, F_SETFD, flags); + } + } +#else + if ((domain == AF_INET || domain == AF_INET6) && type == SOCK_DGRAM) + { + BOOL new_behavior = FALSE; + DWORD bytes_returned = 0; + + /* Disable connection reset error on ICMP port unreachable. */ + WSAIoctl (fd, SIO_UDP_CONNRESET, &new_behavior, sizeof (new_behavior), + NULL, 0, &bytes_returned, NULL, NULL); + } +#endif + + return fd; +} + +static gint +g_socket_create_socket (GSocketFamily family, + GSocketType type, + int protocol, + GError **error) +{ + gint native_type; + + switch (type) + { + case G_SOCKET_TYPE_STREAM: + native_type = SOCK_STREAM; + break; + + case G_SOCKET_TYPE_DATAGRAM: + native_type = SOCK_DGRAM; + break; + + case G_SOCKET_TYPE_SEQPACKET: + native_type = SOCK_SEQPACKET; + break; + + default: + g_assert_not_reached (); + } + + if (family <= 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Unable to create socket: %s"), _("Unknown family was specified")); + return -1; + } + + if (protocol == -1) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Unable to create socket: %s"), _("Unknown protocol was specified")); + return -1; + } + + return g_socket (family, native_type, protocol, error); +} + +static void +g_socket_constructed (GObject *object) +{ + GSocket *socket = G_SOCKET (object); + + if (socket->priv->fd >= 0) + /* create socket->priv info from the fd */ + g_socket_details_from_fd (socket); + + else + /* create the fd from socket->priv info */ + socket->priv->fd = g_socket_create_socket (socket->priv->family, + socket->priv->type, + socket->priv->protocol, + &socket->priv->construct_error); + + if (socket->priv->fd != -1) + { +#ifndef G_OS_WIN32 + GError *error = NULL; +#else + gulong arg; +#endif + + /* Always use native nonblocking sockets, as Windows sets sockets to + * nonblocking automatically in certain operations. This way we make + * things work the same on all platforms. + */ +#ifndef G_OS_WIN32 + if (!g_unix_set_fd_nonblocking (socket->priv->fd, TRUE, &error)) + { + g_warning ("Error setting socket nonblocking: %s", error->message); + g_clear_error (&error); + } +#else + arg = TRUE; + + if (ioctlsocket (socket->priv->fd, FIONBIO, &arg) == SOCKET_ERROR) + { + int errsv = get_socket_errno (); + g_warning ("Error setting socket status flags: %s", socket_strerror (errsv)); + } +#endif + +#ifdef SO_NOSIGPIPE + /* See note about SIGPIPE below. */ + g_socket_set_option (socket, SOL_SOCKET, SO_NOSIGPIPE, TRUE, NULL); +#endif + } +} + +static void +g_socket_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSocket *socket = G_SOCKET (object); + GSocketAddress *address; + + switch (prop_id) + { + case PROP_FAMILY: + g_value_set_enum (value, socket->priv->family); + break; + + case PROP_TYPE: + g_value_set_enum (value, socket->priv->type); + break; + + case PROP_PROTOCOL: + g_value_set_enum (value, socket->priv->protocol); + break; + + case PROP_FD: + g_value_set_int (value, socket->priv->fd); + break; + + case PROP_BLOCKING: + g_value_set_boolean (value, socket->priv->blocking); + break; + + case PROP_LISTEN_BACKLOG: + g_value_set_int (value, socket->priv->listen_backlog); + break; + + case PROP_KEEPALIVE: + g_value_set_boolean (value, socket->priv->keepalive); + break; + + case PROP_LOCAL_ADDRESS: + address = g_socket_get_local_address (socket, NULL); + g_value_take_object (value, address); + break; + + case PROP_REMOTE_ADDRESS: + address = g_socket_get_remote_address (socket, NULL); + g_value_take_object (value, address); + break; + + case PROP_TIMEOUT: + g_value_set_uint (value, socket->priv->timeout); + break; + + case PROP_TTL: + g_value_set_uint (value, g_socket_get_ttl (socket)); + break; + + case PROP_BROADCAST: + g_value_set_boolean (value, g_socket_get_broadcast (socket)); + break; + + case PROP_MULTICAST_LOOPBACK: + g_value_set_boolean (value, g_socket_get_multicast_loopback (socket)); + break; + + case PROP_MULTICAST_TTL: + g_value_set_uint (value, g_socket_get_multicast_ttl (socket)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSocket *socket = G_SOCKET (object); + + switch (prop_id) + { + case PROP_FAMILY: + socket->priv->family = g_value_get_enum (value); + break; + + case PROP_TYPE: + socket->priv->type = g_value_get_enum (value); + break; + + case PROP_PROTOCOL: + socket->priv->protocol = g_value_get_enum (value); + break; + + case PROP_FD: + socket->priv->fd = g_value_get_int (value); + break; + + case PROP_BLOCKING: + g_socket_set_blocking (socket, g_value_get_boolean (value)); + break; + + case PROP_LISTEN_BACKLOG: + g_socket_set_listen_backlog (socket, g_value_get_int (value)); + break; + + case PROP_KEEPALIVE: + g_socket_set_keepalive (socket, g_value_get_boolean (value)); + break; + + case PROP_TIMEOUT: + g_socket_set_timeout (socket, g_value_get_uint (value)); + break; + + case PROP_TTL: + g_socket_set_ttl (socket, g_value_get_uint (value)); + break; + + case PROP_BROADCAST: + g_socket_set_broadcast (socket, g_value_get_boolean (value)); + break; + + case PROP_MULTICAST_LOOPBACK: + g_socket_set_multicast_loopback (socket, g_value_get_boolean (value)); + break; + + case PROP_MULTICAST_TTL: + g_socket_set_multicast_ttl (socket, g_value_get_uint (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_finalize (GObject *object) +{ + GSocket *socket = G_SOCKET (object); + gint i; + + g_clear_error (&socket->priv->construct_error); + + if (socket->priv->fd != -1 && + !socket->priv->closed) + g_socket_close (socket, NULL); + + if (socket->priv->remote_address) + g_object_unref (socket->priv->remote_address); + +#ifdef G_OS_WIN32 + if (socket->priv->event != WSA_INVALID_EVENT) + { + WSACloseEvent (socket->priv->event); + socket->priv->event = WSA_INVALID_EVENT; + } + + g_assert (socket->priv->requested_conditions == NULL); + g_mutex_clear (&socket->priv->win32_source_lock); + g_cond_clear (&socket->priv->win32_source_cond); +#endif + + for (i = 0; i < RECV_ADDR_CACHE_SIZE; i++) + { + if (socket->priv->recv_addr_cache[i].addr) + { + g_object_unref (socket->priv->recv_addr_cache[i].addr); + g_free (socket->priv->recv_addr_cache[i].native); + } + } + + if (G_OBJECT_CLASS (g_socket_parent_class)->finalize) + (*G_OBJECT_CLASS (g_socket_parent_class)->finalize) (object); +} + +static void +g_socket_class_init (GSocketClass *klass) +{ + GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass); + +#ifdef SIGPIPE + /* There is no portable, thread-safe way to avoid having the process + * be killed by SIGPIPE when calling send() or sendmsg(), so we are + * forced to simply ignore the signal process-wide. + * + * Even if we ignore it though, gdb will still stop if the app + * receives a SIGPIPE, which can be confusing and annoying. So when + * possible, we also use MSG_NOSIGNAL / SO_NOSIGPIPE elsewhere to + * prevent the signal from occurring at all. + */ + signal (SIGPIPE, SIG_IGN); +#endif + + gobject_class->finalize = g_socket_finalize; + gobject_class->constructed = g_socket_constructed; + gobject_class->set_property = g_socket_set_property; + gobject_class->get_property = g_socket_get_property; + + g_object_class_install_property (gobject_class, PROP_FAMILY, + g_param_spec_enum ("family", + P_("Socket family"), + P_("The sockets address family"), + G_TYPE_SOCKET_FAMILY, + G_SOCKET_FAMILY_INVALID, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_TYPE, + g_param_spec_enum ("type", + P_("Socket type"), + P_("The sockets type"), + G_TYPE_SOCKET_TYPE, + G_SOCKET_TYPE_STREAM, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_PROTOCOL, + g_param_spec_enum ("protocol", + P_("Socket protocol"), + P_("The id of the protocol to use, or -1 for unknown"), + G_TYPE_SOCKET_PROTOCOL, + G_SOCKET_PROTOCOL_UNKNOWN, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_FD, + g_param_spec_int ("fd", + P_("File descriptor"), + P_("The sockets file descriptor"), + G_MININT, + G_MAXINT, + -1, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_BLOCKING, + g_param_spec_boolean ("blocking", + P_("blocking"), + P_("Whether or not I/O on this socket is blocking"), + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_LISTEN_BACKLOG, + g_param_spec_int ("listen-backlog", + P_("Listen backlog"), + P_("Outstanding connections in the listen queue"), + 0, + SOMAXCONN, + 10, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_KEEPALIVE, + g_param_spec_boolean ("keepalive", + P_("Keep connection alive"), + P_("Keep connection alive by sending periodic pings"), + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS, + g_param_spec_object ("local-address", + P_("Local address"), + P_("The local address the socket is bound to"), + G_TYPE_SOCKET_ADDRESS, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_REMOTE_ADDRESS, + g_param_spec_object ("remote-address", + P_("Remote address"), + P_("The remote address the socket is connected to"), + G_TYPE_SOCKET_ADDRESS, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSocket:timeout: + * + * The timeout in seconds on socket I/O + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, PROP_TIMEOUT, + g_param_spec_uint ("timeout", + P_("Timeout"), + P_("The timeout in seconds on socket I/O"), + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSocket:broadcast: + * + * Whether the socket should allow sending to broadcast addresses. + * + * Since: 2.32 + */ + g_object_class_install_property (gobject_class, PROP_BROADCAST, + g_param_spec_boolean ("broadcast", + P_("Broadcast"), + P_("Whether to allow sending to broadcast addresses"), + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSocket:ttl: + * + * Time-to-live for outgoing unicast packets + * + * Since: 2.32 + */ + g_object_class_install_property (gobject_class, PROP_TTL, + g_param_spec_uint ("ttl", + P_("TTL"), + P_("Time-to-live of outgoing unicast packets"), + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSocket:multicast-loopback: + * + * Whether outgoing multicast packets loop back to the local host. + * + * Since: 2.32 + */ + g_object_class_install_property (gobject_class, PROP_MULTICAST_LOOPBACK, + g_param_spec_boolean ("multicast-loopback", + P_("Multicast loopback"), + P_("Whether outgoing multicast packets loop back to the local host"), + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSocket:multicast-ttl: + * + * Time-to-live out outgoing multicast packets + * + * Since: 2.32 + */ + g_object_class_install_property (gobject_class, PROP_MULTICAST_TTL, + g_param_spec_uint ("multicast-ttl", + P_("Multicast TTL"), + P_("Time-to-live of outgoing multicast packets"), + 0, G_MAXUINT, 1, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_socket_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_socket_initable_init; +} + +static void +g_socket_datagram_based_iface_init (GDatagramBasedInterface *iface) +{ + iface->receive_messages = g_socket_datagram_based_receive_messages; + iface->send_messages = g_socket_datagram_based_send_messages; + iface->create_source = g_socket_datagram_based_create_source; + iface->condition_check = g_socket_datagram_based_condition_check; + iface->condition_wait = g_socket_datagram_based_condition_wait; +} + +static void +g_socket_init (GSocket *socket) +{ + socket->priv = g_socket_get_instance_private (socket); + + socket->priv->fd = -1; + socket->priv->blocking = TRUE; + socket->priv->listen_backlog = 10; + socket->priv->construct_error = NULL; +#ifdef G_OS_WIN32 + socket->priv->event = WSA_INVALID_EVENT; + g_mutex_init (&socket->priv->win32_source_lock); + g_cond_init (&socket->priv->win32_source_cond); +#endif +} + +static gboolean +g_socket_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GSocket *socket; + + g_return_val_if_fail (G_IS_SOCKET (initable), FALSE); + + socket = G_SOCKET (initable); + + if (cancellable != NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Cancellable initialization not supported")); + return FALSE; + } + + socket->priv->inited = TRUE; + + if (socket->priv->construct_error) + { + if (error) + *error = g_error_copy (socket->priv->construct_error); + return FALSE; + } + + + return TRUE; +} + +static gboolean +check_datagram_based (GDatagramBased *self, + GError **error) +{ + switch (g_socket_get_socket_type (G_SOCKET (self))) + { + case G_SOCKET_TYPE_INVALID: + case G_SOCKET_TYPE_STREAM: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Cannot use datagram operations on a non-datagram " + "socket.")); + return FALSE; + case G_SOCKET_TYPE_DATAGRAM: + case G_SOCKET_TYPE_SEQPACKET: + /* Fall through. */ + break; + } + + /* Due to us sharing #GSocketSource with the #GSocket implementation, it is + * pretty tricky to split out #GSocket:timeout so that it does not affect + * #GDatagramBased operations (but still affects #GSocket operations). It is + * not worth that effort — just disallow it and require the user to specify + * timeouts on a per-operation basis. */ + if (g_socket_get_timeout (G_SOCKET (self)) != 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Cannot use datagram operations on a socket with a " + "timeout set.")); + return FALSE; + } + + return TRUE; +} + +static gint +g_socket_datagram_based_receive_messages (GDatagramBased *self, + GInputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + if (!check_datagram_based (self, error)) + return FALSE; + + return g_socket_receive_messages_with_timeout (G_SOCKET (self), messages, + num_messages, flags, timeout_us, + cancellable, error); +} + +static gint +g_socket_datagram_based_send_messages (GDatagramBased *self, + GOutputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + if (!check_datagram_based (self, error)) + return FALSE; + + return g_socket_send_messages_with_timeout (G_SOCKET (self), messages, + num_messages, flags, timeout_us, + cancellable, error); +} + +static GSource * +g_socket_datagram_based_create_source (GDatagramBased *self, + GIOCondition condition, + GCancellable *cancellable) +{ + if (!check_datagram_based (self, NULL)) + return NULL; + + return g_socket_create_source (G_SOCKET (self), condition, cancellable); +} + +static GIOCondition +g_socket_datagram_based_condition_check (GDatagramBased *datagram_based, + GIOCondition condition) +{ + if (!check_datagram_based (datagram_based, NULL)) + return G_IO_ERR; + + return g_socket_condition_check (G_SOCKET (datagram_based), condition); +} + +static gboolean +g_socket_datagram_based_condition_wait (GDatagramBased *datagram_based, + GIOCondition condition, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + if (!check_datagram_based (datagram_based, error)) + return FALSE; + + return g_socket_condition_timed_wait (G_SOCKET (datagram_based), condition, + timeout_us, cancellable, error); +} + +/** + * g_socket_new: + * @family: the socket family to use, e.g. %G_SOCKET_FAMILY_IPV4. + * @type: the socket type to use. + * @protocol: the id of the protocol to use, or 0 for default. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a new #GSocket with the defined family, type and protocol. + * If @protocol is 0 (%G_SOCKET_PROTOCOL_DEFAULT) the default protocol type + * for the family and type is used. + * + * The @protocol is a family and type specific int that specifies what + * kind of protocol to use. #GSocketProtocol lists several common ones. + * Many families only support one protocol, and use 0 for this, others + * support several and using 0 means to use the default protocol for + * the family and type. + * + * The protocol id is passed directly to the operating + * system, so you can use protocols not listed in #GSocketProtocol if you + * know the protocol number used for it. + * + * Returns: a #GSocket or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GSocket * +g_socket_new (GSocketFamily family, + GSocketType type, + GSocketProtocol protocol, + GError **error) +{ + return G_SOCKET (g_initable_new (G_TYPE_SOCKET, + NULL, error, + "family", family, + "type", type, + "protocol", protocol, + NULL)); +} + +/** + * g_socket_new_from_fd: + * @fd: a native socket file descriptor. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a new #GSocket from a native file descriptor + * or winsock SOCKET handle. + * + * This reads all the settings from the file descriptor so that + * all properties should work. Note that the file descriptor + * will be set to non-blocking mode, independent on the blocking + * mode of the #GSocket. + * + * On success, the returned #GSocket takes ownership of @fd. On failure, the + * caller must close @fd themselves. + * + * Since GLib 2.46, it is no longer a fatal error to call this on a non-socket + * descriptor. Instead, a GError will be set with code %G_IO_ERROR_FAILED + * + * Returns: a #GSocket or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GSocket * +g_socket_new_from_fd (gint fd, + GError **error) +{ + return G_SOCKET (g_initable_new (G_TYPE_SOCKET, + NULL, error, + "fd", fd, + NULL)); +} + +/** + * g_socket_set_blocking: + * @socket: a #GSocket. + * @blocking: Whether to use blocking I/O or not. + * + * Sets the blocking mode of the socket. In blocking mode + * all operations (which don’t take an explicit blocking parameter) block until + * they succeed or there is an error. In + * non-blocking mode all functions return results immediately or + * with a %G_IO_ERROR_WOULD_BLOCK error. + * + * All sockets are created in blocking mode. However, note that the + * platform level socket is always non-blocking, and blocking mode + * is a GSocket level feature. + * + * Since: 2.22 + */ +void +g_socket_set_blocking (GSocket *socket, + gboolean blocking) +{ + g_return_if_fail (G_IS_SOCKET (socket)); + + blocking = !!blocking; + + if (socket->priv->blocking == blocking) + return; + + socket->priv->blocking = blocking; + g_object_notify (G_OBJECT (socket), "blocking"); +} + +/** + * g_socket_get_blocking: + * @socket: a #GSocket. + * + * Gets the blocking mode of the socket. For details on blocking I/O, + * see g_socket_set_blocking(). + * + * Returns: %TRUE if blocking I/O is used, %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_socket_get_blocking (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + return socket->priv->blocking; +} + +/** + * g_socket_set_keepalive: + * @socket: a #GSocket. + * @keepalive: Value for the keepalive flag + * + * Sets or unsets the %SO_KEEPALIVE flag on the underlying socket. When + * this flag is set on a socket, the system will attempt to verify that the + * remote socket endpoint is still present if a sufficiently long period of + * time passes with no data being exchanged. If the system is unable to + * verify the presence of the remote endpoint, it will automatically close + * the connection. + * + * This option is only functional on certain kinds of sockets. (Notably, + * %G_SOCKET_PROTOCOL_TCP sockets.) + * + * The exact time between pings is system- and protocol-dependent, but will + * normally be at least two hours. Most commonly, you would set this flag + * on a server socket if you want to allow clients to remain idle for long + * periods of time, but also want to ensure that connections are eventually + * garbage-collected if clients crash or become unreachable. + * + * Since: 2.22 + */ +void +g_socket_set_keepalive (GSocket *socket, + gboolean keepalive) +{ + GError *error = NULL; + + g_return_if_fail (G_IS_SOCKET (socket)); + + keepalive = !!keepalive; + if (socket->priv->keepalive == keepalive) + return; + + if (!g_socket_set_option (socket, SOL_SOCKET, SO_KEEPALIVE, + keepalive, &error)) + { + g_warning ("error setting keepalive: %s", error->message); + g_error_free (error); + return; + } + + socket->priv->keepalive = keepalive; + g_object_notify (G_OBJECT (socket), "keepalive"); +} + +/** + * g_socket_get_keepalive: + * @socket: a #GSocket. + * + * Gets the keepalive mode of the socket. For details on this, + * see g_socket_set_keepalive(). + * + * Returns: %TRUE if keepalive is active, %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_socket_get_keepalive (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + return socket->priv->keepalive; +} + +/** + * g_socket_get_listen_backlog: + * @socket: a #GSocket. + * + * Gets the listen backlog setting of the socket. For details on this, + * see g_socket_set_listen_backlog(). + * + * Returns: the maximum number of pending connections. + * + * Since: 2.22 + */ +gint +g_socket_get_listen_backlog (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), 0); + + return socket->priv->listen_backlog; +} + +/** + * g_socket_set_listen_backlog: + * @socket: a #GSocket. + * @backlog: the maximum number of pending connections. + * + * Sets the maximum number of outstanding connections allowed + * when listening on this socket. If more clients than this are + * connecting to the socket and the application is not handling them + * on time then the new connections will be refused. + * + * Note that this must be called before g_socket_listen() and has no + * effect if called after that. + * + * Since: 2.22 + */ +void +g_socket_set_listen_backlog (GSocket *socket, + gint backlog) +{ + g_return_if_fail (G_IS_SOCKET (socket)); + g_return_if_fail (!socket->priv->listening); + + if (backlog != socket->priv->listen_backlog) + { + socket->priv->listen_backlog = backlog; + g_object_notify (G_OBJECT (socket), "listen-backlog"); + } +} + +/** + * g_socket_get_timeout: + * @socket: a #GSocket. + * + * Gets the timeout setting of the socket. For details on this, see + * g_socket_set_timeout(). + * + * Returns: the timeout in seconds + * + * Since: 2.26 + */ +guint +g_socket_get_timeout (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), 0); + + return socket->priv->timeout; +} + +/** + * g_socket_set_timeout: + * @socket: a #GSocket. + * @timeout: the timeout for @socket, in seconds, or 0 for none + * + * Sets the time in seconds after which I/O operations on @socket will + * time out if they have not yet completed. + * + * On a blocking socket, this means that any blocking #GSocket + * operation will time out after @timeout seconds of inactivity, + * returning %G_IO_ERROR_TIMED_OUT. + * + * On a non-blocking socket, calls to g_socket_condition_wait() will + * also fail with %G_IO_ERROR_TIMED_OUT after the given time. Sources + * created with g_socket_create_source() will trigger after + * @timeout seconds of inactivity, with the requested condition + * set, at which point calling g_socket_receive(), g_socket_send(), + * g_socket_check_connect_result(), etc, will fail with + * %G_IO_ERROR_TIMED_OUT. + * + * If @timeout is 0 (the default), operations will never time out + * on their own. + * + * Note that if an I/O operation is interrupted by a signal, this may + * cause the timeout to be reset. + * + * Since: 2.26 + */ +void +g_socket_set_timeout (GSocket *socket, + guint timeout) +{ + g_return_if_fail (G_IS_SOCKET (socket)); + + if (timeout != socket->priv->timeout) + { + socket->priv->timeout = timeout; + g_object_notify (G_OBJECT (socket), "timeout"); + } +} + +/** + * g_socket_get_ttl: + * @socket: a #GSocket. + * + * Gets the unicast time-to-live setting on @socket; see + * g_socket_set_ttl() for more details. + * + * Returns: the time-to-live setting on @socket + * + * Since: 2.32 + */ +guint +g_socket_get_ttl (GSocket *socket) +{ + GError *error = NULL; + gint value; + + g_return_val_if_fail (G_IS_SOCKET (socket), 0); + + if (socket->priv->family == G_SOCKET_FAMILY_IPV4) + { + g_socket_get_option (socket, IPPROTO_IP, IP_TTL, + &value, &error); + } + else if (socket->priv->family == G_SOCKET_FAMILY_IPV6) + { + g_socket_get_option (socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + &value, &error); + } + else + g_return_val_if_reached (0); + + if (error) + { + g_warning ("error getting unicast ttl: %s", error->message); + g_error_free (error); + return 0; + } + + return value; +} + +/** + * g_socket_set_ttl: + * @socket: a #GSocket. + * @ttl: the time-to-live value for all unicast packets on @socket + * + * Sets the time-to-live for outgoing unicast packets on @socket. + * By default the platform-specific default value is used. + * + * Since: 2.32 + */ +void +g_socket_set_ttl (GSocket *socket, + guint ttl) +{ + GError *error = NULL; + + g_return_if_fail (G_IS_SOCKET (socket)); + + if (socket->priv->family == G_SOCKET_FAMILY_IPV4) + { + g_socket_set_option (socket, IPPROTO_IP, IP_TTL, + ttl, &error); + } + else if (socket->priv->family == G_SOCKET_FAMILY_IPV6) + { + g_socket_set_option (socket, IPPROTO_IP, IP_TTL, + ttl, NULL); + g_socket_set_option (socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + ttl, &error); + } + else + g_return_if_reached (); + + if (error) + { + g_warning ("error setting unicast ttl: %s", error->message); + g_error_free (error); + return; + } + + g_object_notify (G_OBJECT (socket), "ttl"); +} + +/** + * g_socket_get_broadcast: + * @socket: a #GSocket. + * + * Gets the broadcast setting on @socket; if %TRUE, + * it is possible to send packets to broadcast + * addresses. + * + * Returns: the broadcast setting on @socket + * + * Since: 2.32 + */ +gboolean +g_socket_get_broadcast (GSocket *socket) +{ + GError *error = NULL; + gint value; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + if (!g_socket_get_option (socket, SOL_SOCKET, SO_BROADCAST, + &value, &error)) + { + g_warning ("error getting broadcast: %s", error->message); + g_error_free (error); + return FALSE; + } + + return !!value; +} + +/** + * g_socket_set_broadcast: + * @socket: a #GSocket. + * @broadcast: whether @socket should allow sending to broadcast + * addresses + * + * Sets whether @socket should allow sending to broadcast addresses. + * This is %FALSE by default. + * + * Since: 2.32 + */ +void +g_socket_set_broadcast (GSocket *socket, + gboolean broadcast) +{ + GError *error = NULL; + + g_return_if_fail (G_IS_SOCKET (socket)); + + broadcast = !!broadcast; + + if (!g_socket_set_option (socket, SOL_SOCKET, SO_BROADCAST, + broadcast, &error)) + { + g_warning ("error setting broadcast: %s", error->message); + g_error_free (error); + return; + } + + g_object_notify (G_OBJECT (socket), "broadcast"); +} + +/** + * g_socket_get_multicast_loopback: + * @socket: a #GSocket. + * + * Gets the multicast loopback setting on @socket; if %TRUE (the + * default), outgoing multicast packets will be looped back to + * multicast listeners on the same host. + * + * Returns: the multicast loopback setting on @socket + * + * Since: 2.32 + */ +gboolean +g_socket_get_multicast_loopback (GSocket *socket) +{ + GError *error = NULL; + gint value; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + if (socket->priv->family == G_SOCKET_FAMILY_IPV4) + { + g_socket_get_option (socket, IPPROTO_IP, IP_MULTICAST_LOOP, + &value, &error); + } + else if (socket->priv->family == G_SOCKET_FAMILY_IPV6) + { + g_socket_get_option (socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + &value, &error); + } + else + g_return_val_if_reached (FALSE); + + if (error) + { + g_warning ("error getting multicast loopback: %s", error->message); + g_error_free (error); + return FALSE; + } + + return !!value; +} + +/** + * g_socket_set_multicast_loopback: + * @socket: a #GSocket. + * @loopback: whether @socket should receive messages sent to its + * multicast groups from the local host + * + * Sets whether outgoing multicast packets will be received by sockets + * listening on that multicast address on the same host. This is %TRUE + * by default. + * + * Since: 2.32 + */ +void +g_socket_set_multicast_loopback (GSocket *socket, + gboolean loopback) +{ + GError *error = NULL; + + g_return_if_fail (G_IS_SOCKET (socket)); + + loopback = !!loopback; + + if (socket->priv->family == G_SOCKET_FAMILY_IPV4) + { + g_socket_set_option (socket, IPPROTO_IP, IP_MULTICAST_LOOP, + loopback, &error); + } + else if (socket->priv->family == G_SOCKET_FAMILY_IPV6) + { + g_socket_set_option (socket, IPPROTO_IP, IP_MULTICAST_LOOP, + loopback, NULL); + g_socket_set_option (socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + loopback, &error); + } + else + g_return_if_reached (); + + if (error) + { + g_warning ("error setting multicast loopback: %s", error->message); + g_error_free (error); + return; + } + + g_object_notify (G_OBJECT (socket), "multicast-loopback"); +} + +/** + * g_socket_get_multicast_ttl: + * @socket: a #GSocket. + * + * Gets the multicast time-to-live setting on @socket; see + * g_socket_set_multicast_ttl() for more details. + * + * Returns: the multicast time-to-live setting on @socket + * + * Since: 2.32 + */ +guint +g_socket_get_multicast_ttl (GSocket *socket) +{ + GError *error = NULL; + gint value; + + g_return_val_if_fail (G_IS_SOCKET (socket), 0); + + if (socket->priv->family == G_SOCKET_FAMILY_IPV4) + { + g_socket_get_option (socket, IPPROTO_IP, IP_MULTICAST_TTL, + &value, &error); + } + else if (socket->priv->family == G_SOCKET_FAMILY_IPV6) + { + g_socket_get_option (socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + &value, &error); + } + else + g_return_val_if_reached (FALSE); + + if (error) + { + g_warning ("error getting multicast ttl: %s", error->message); + g_error_free (error); + return FALSE; + } + + return value; +} + +/** + * g_socket_set_multicast_ttl: + * @socket: a #GSocket. + * @ttl: the time-to-live value for all multicast datagrams on @socket + * + * Sets the time-to-live for outgoing multicast datagrams on @socket. + * By default, this is 1, meaning that multicast packets will not leave + * the local network. + * + * Since: 2.32 + */ +void +g_socket_set_multicast_ttl (GSocket *socket, + guint ttl) +{ + GError *error = NULL; + + g_return_if_fail (G_IS_SOCKET (socket)); + + if (socket->priv->family == G_SOCKET_FAMILY_IPV4) + { + g_socket_set_option (socket, IPPROTO_IP, IP_MULTICAST_TTL, + ttl, &error); + } + else if (socket->priv->family == G_SOCKET_FAMILY_IPV6) + { + g_socket_set_option (socket, IPPROTO_IP, IP_MULTICAST_TTL, + ttl, NULL); + g_socket_set_option (socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + ttl, &error); + } + else + g_return_if_reached (); + + if (error) + { + g_warning ("error setting multicast ttl: %s", error->message); + g_error_free (error); + return; + } + + g_object_notify (G_OBJECT (socket), "multicast-ttl"); +} + +/** + * g_socket_get_family: + * @socket: a #GSocket. + * + * Gets the socket family of the socket. + * + * Returns: a #GSocketFamily + * + * Since: 2.22 + */ +GSocketFamily +g_socket_get_family (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), G_SOCKET_FAMILY_INVALID); + + return socket->priv->family; +} + +/** + * g_socket_get_socket_type: + * @socket: a #GSocket. + * + * Gets the socket type of the socket. + * + * Returns: a #GSocketType + * + * Since: 2.22 + */ +GSocketType +g_socket_get_socket_type (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), G_SOCKET_TYPE_INVALID); + + return socket->priv->type; +} + +/** + * g_socket_get_protocol: + * @socket: a #GSocket. + * + * Gets the socket protocol id the socket was created with. + * In case the protocol is unknown, -1 is returned. + * + * Returns: a protocol id, or -1 if unknown + * + * Since: 2.22 + */ +GSocketProtocol +g_socket_get_protocol (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), -1); + + return socket->priv->protocol; +} + +/** + * g_socket_get_fd: + * @socket: a #GSocket. + * + * Returns the underlying OS socket object. On unix this + * is a socket file descriptor, and on Windows this is + * a Winsock2 SOCKET handle. This may be useful for + * doing platform specific or otherwise unusual operations + * on the socket. + * + * Returns: the file descriptor of the socket. + * + * Since: 2.22 + */ +int +g_socket_get_fd (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), -1); + + return socket->priv->fd; +} + +/** + * g_socket_get_local_address: + * @socket: a #GSocket. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Try to get the local address of a bound socket. This is only + * useful if the socket has been bound to a local address, + * either explicitly or implicitly when connecting. + * + * Returns: (transfer full): a #GSocketAddress or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GSocketAddress * +g_socket_get_local_address (GSocket *socket, + GError **error) +{ + union { + struct sockaddr_storage storage; + struct sockaddr sa; + } buffer; + guint len = sizeof (buffer); + + g_return_val_if_fail (G_IS_SOCKET (socket), NULL); + + if (getsockname (socket->priv->fd, &buffer.sa, &len) < 0) + { + int errsv = get_socket_errno (); + g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), + _("could not get local address: %s"), socket_strerror (errsv)); + return NULL; + } + + return g_socket_address_new_from_native (&buffer.storage, len); +} + +/** + * g_socket_get_remote_address: + * @socket: a #GSocket. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Try to get the remote address of a connected socket. This is only + * useful for connection oriented sockets that have been connected. + * + * Returns: (transfer full): a #GSocketAddress or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GSocketAddress * +g_socket_get_remote_address (GSocket *socket, + GError **error) +{ + union { + struct sockaddr_storage storage; + struct sockaddr sa; + } buffer; + guint len = sizeof (buffer); + + g_return_val_if_fail (G_IS_SOCKET (socket), NULL); + + if (socket->priv->connect_pending) + { + if (!g_socket_check_connect_result (socket, error)) + return NULL; + else + socket->priv->connect_pending = FALSE; + } + + if (!socket->priv->remote_address) + { + if (getpeername (socket->priv->fd, &buffer.sa, &len) < 0) + { + int errsv = get_socket_errno (); + g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), + _("could not get remote address: %s"), socket_strerror (errsv)); + return NULL; + } + + socket->priv->remote_address = g_socket_address_new_from_native (&buffer.storage, len); + } + + return g_object_ref (socket->priv->remote_address); +} + +/** + * g_socket_is_connected: + * @socket: a #GSocket. + * + * Check whether the socket is connected. This is only useful for + * connection-oriented sockets. + * + * If using g_socket_shutdown(), this function will return %TRUE until the + * socket has been shut down for reading and writing. If you do a non-blocking + * connect, this function will not return %TRUE until after you call + * g_socket_check_connect_result(). + * + * Returns: %TRUE if socket is connected, %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +g_socket_is_connected (GSocket *socket) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + return (socket->priv->connected_read || socket->priv->connected_write); +} + +/** + * g_socket_listen: + * @socket: a #GSocket. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Marks the socket as a server socket, i.e. a socket that is used + * to accept incoming requests using g_socket_accept(). + * + * Before calling this the socket must be bound to a local address using + * g_socket_bind(). + * + * To set the maximum amount of outstanding clients, use + * g_socket_set_listen_backlog(). + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.22 + */ +gboolean +g_socket_listen (GSocket *socket, + GError **error) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + if (!check_socket (socket, error)) + return FALSE; + + if (listen (socket->priv->fd, socket->priv->listen_backlog) < 0) + { + int errsv = get_socket_errno (); + + g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), + _("could not listen: %s"), socket_strerror (errsv)); + return FALSE; + } + + socket->priv->listening = TRUE; + + return TRUE; +} + +/** + * g_socket_bind: + * @socket: a #GSocket. + * @address: a #GSocketAddress specifying the local address. + * @allow_reuse: whether to allow reusing this address + * @error: #GError for error reporting, or %NULL to ignore. + * + * When a socket is created it is attached to an address family, but it + * doesn't have an address in this family. g_socket_bind() assigns the + * address (sometimes called name) of the socket. + * + * It is generally required to bind to a local address before you can + * receive connections. (See g_socket_listen() and g_socket_accept() ). + * In certain situations, you may also want to bind a socket that will be + * used to initiate connections, though this is not normally required. + * + * If @socket is a TCP socket, then @allow_reuse controls the setting + * of the `SO_REUSEADDR` socket option; normally it should be %TRUE for + * server sockets (sockets that you will eventually call + * g_socket_accept() on), and %FALSE for client sockets. (Failing to + * set this flag on a server socket may cause g_socket_bind() to return + * %G_IO_ERROR_ADDRESS_IN_USE if the server program is stopped and then + * immediately restarted.) + * + * If @socket is a UDP socket, then @allow_reuse determines whether or + * not other UDP sockets can be bound to the same address at the same + * time. In particular, you can have several UDP sockets bound to the + * same address, and they will all receive all of the multicast and + * broadcast packets sent to that address. (The behavior of unicast + * UDP packets to an address with multiple listeners is not defined.) + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.22 + */ +gboolean +g_socket_bind (GSocket *socket, + GSocketAddress *address, + gboolean reuse_address, + GError **error) +{ + union { + struct sockaddr_storage storage; + struct sockaddr sa; + } addr; + gboolean so_reuseaddr; +#ifdef SO_REUSEPORT + gboolean so_reuseport; +#endif + + g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE); + + if (!check_socket (socket, error)) + return FALSE; + + if (!g_socket_address_to_native (address, &addr.storage, sizeof addr, error)) + return FALSE; + + /* On Windows, SO_REUSEADDR has the semantics we want for UDP + * sockets, but has nasty side effects we don't want for TCP + * sockets. + * + * On other platforms, we set SO_REUSEPORT, if it exists, for + * UDP sockets, and SO_REUSEADDR for all sockets, hoping that + * if SO_REUSEPORT doesn't exist, then SO_REUSEADDR will have + * the desired semantics on UDP (as it does on Linux, although + * Linux has SO_REUSEPORT too as of 3.9). + */ + +#ifdef G_OS_WIN32 + so_reuseaddr = reuse_address && (socket->priv->type == G_SOCKET_TYPE_DATAGRAM); +#else + so_reuseaddr = !!reuse_address; +#endif + +#ifdef SO_REUSEPORT + so_reuseport = reuse_address && (socket->priv->type == G_SOCKET_TYPE_DATAGRAM); +#endif + + /* Ignore errors here, the only likely error is "not supported", and + * this is a "best effort" thing mainly. + */ + g_socket_set_option (socket, SOL_SOCKET, SO_REUSEADDR, so_reuseaddr, NULL); +#ifdef SO_REUSEPORT + g_socket_set_option (socket, SOL_SOCKET, SO_REUSEPORT, so_reuseport, NULL); +#endif + + if (bind (socket->priv->fd, &addr.sa, + g_socket_address_get_native_size (address)) < 0) + { + int errsv = get_socket_errno (); + gchar *address_string = address_to_string (address); + + g_set_error (error, + G_IO_ERROR, socket_io_error_from_errno (errsv), + _("Error binding to address %s: %s"), + address_string, socket_strerror (errsv)); + g_free (address_string); + return FALSE; + } + + return TRUE; +} + +#ifdef G_OS_WIN32 +static gulong +g_socket_w32_get_adapter_ipv4_addr (const gchar *name_or_ip) +{ + ULONG bufsize = 15000; /* MS-recommended initial bufsize */ + DWORD ret = ERROR_BUFFER_OVERFLOW; + unsigned int malloc_iterations = 0; + PIP_ADAPTER_ADDRESSES addr_buf = NULL, eth_adapter; + wchar_t *wchar_name_or_ip = NULL; + gulong ip_result; + NET_IFINDEX if_index; + + /* + * For Windows OS only - return adapter IPv4 address in network byte order. + * + * Input string can be either friendly name of adapter, IP address of adapter, + * indextoname, or fullname of adapter. + * Example: + * 192.168.1.109 ===> IP address given directly, + * convert directly with inet_addr() function + * Wi-Fi ===> Adapter friendly name "Wi-Fi", + * scan with GetAdapterAddresses and adapter->FriendlyName + * ethernet_32774 ===> Adapter name as returned by if_indextoname + * {33E8F5CD-BAEA-4214-BE13-B79AB8080CAB} ===> Adaptername, + * as returned in GetAdapterAddresses and adapter->AdapterName + */ + + /* Step 1: Check if string is an IP address: */ + ip_result = inet_addr (name_or_ip); + if (ip_result != INADDR_NONE) + return ip_result; /* Success, IP address string was given directly */ + + /* + * Step 2: Check if name represents a valid Interface index (e.g. ethernet_75521) + * function if_nametoindex will return >=1 if a valid index, or 0=no match + * valid index will be used later in GetAdaptersAddress loop for lookup of adapter IP address + */ + if_index = if_nametoindex (name_or_ip); + + /* Step 3: Prepare wchar string for friendly name comparison */ + if (if_index == 0) + { + size_t if_name_len = strlen (name_or_ip); + if (if_name_len >= MAX_ADAPTER_NAME_LENGTH + 4) + return INADDR_NONE; + /* Name-check only needed if index=0... */ + wchar_name_or_ip = (wchar_t *) g_try_malloc ((if_name_len + 1) * sizeof(wchar_t)); + if (wchar_name_or_ip) + mbstowcs (wchar_name_or_ip, name_or_ip, if_name_len + 1); + /* NOTE: Even if malloc fails here, some comparisons can still be done later... so no exit here! */ + } + + /* + * Step 4: Allocate memory and get adapter addresses. + * Buffer allocation loop recommended by MS, since size can be dynamic + * https://docs.microsoft.com/en-us/windows/desktop/api/iphlpapi/nf-iphlpapi-getadaptersaddresses + */ + #define MAX_ALLOC_ITERATIONS 3 + do + { + malloc_iterations++; + addr_buf = (PIP_ADAPTER_ADDRESSES) g_try_realloc (addr_buf, bufsize); + if (addr_buf) + ret = GetAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, addr_buf, &bufsize); + } + while (addr_buf && + ret == ERROR_BUFFER_OVERFLOW && + malloc_iterations < MAX_ALLOC_ITERATIONS); + #undef MAX_ALLOC_ITERATIONS + + if (addr_buf == 0 || ret != NO_ERROR) + { + g_free (addr_buf); + g_free (wchar_name_or_ip); + return INADDR_NONE; + } + + /* Step 5: Loop through adapters and check match for index or name */ + for (eth_adapter = addr_buf; eth_adapter != NULL; eth_adapter = eth_adapter->Next) + { + /* Check if match for interface index/name: */ + gboolean any_match = (if_index > 0) && (eth_adapter->IfIndex == if_index); + + /* Check if match for friendly name - but only if NO if_index! */ + if (!any_match && if_index == 0 && eth_adapter->FriendlyName && + eth_adapter->FriendlyName[0] != 0 && wchar_name_or_ip != NULL) + any_match = (_wcsicmp (eth_adapter->FriendlyName, wchar_name_or_ip) == 0); + + /* Check if match for adapter low level name - but only if NO if_index: */ + if (!any_match && if_index == 0 && eth_adapter->AdapterName && + eth_adapter->AdapterName[0] != 0) + any_match = (stricmp (eth_adapter->AdapterName, name_or_ip) == 0); + + if (any_match) + { + /* We have match for this adapter, lets get its local unicast IP address! */ + PIP_ADAPTER_UNICAST_ADDRESS uni_addr; + for (uni_addr = eth_adapter->FirstUnicastAddress; + uni_addr != NULL; uni_addr = uni_addr->Next) + { + if (uni_addr->Address.lpSockaddr->sa_family == AF_INET) + { + ip_result = ((PSOCKADDR_IN) uni_addr->Address.lpSockaddr)->sin_addr.S_un.S_addr; + break; /* finished, exit unicast addr loop */ + } + } + } + } + + g_free (addr_buf); + g_free (wchar_name_or_ip); + + return ip_result; +} +#endif + +static gboolean +g_socket_multicast_group_operation (GSocket *socket, + GInetAddress *group, + gboolean source_specific, + const gchar *iface, + gboolean join_group, + GError **error) +{ + const guint8 *native_addr; + gint optname, result; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + g_return_val_if_fail (socket->priv->type == G_SOCKET_TYPE_DATAGRAM, FALSE); + g_return_val_if_fail (G_IS_INET_ADDRESS (group), FALSE); + + if (!check_socket (socket, error)) + return FALSE; + + native_addr = g_inet_address_to_bytes (group); + if (g_inet_address_get_family (group) == G_SOCKET_FAMILY_IPV4) + { +#ifdef HAVE_IP_MREQN + struct ip_mreqn mc_req; +#else + struct ip_mreq mc_req; +#endif + + memset (&mc_req, 0, sizeof (mc_req)); + memcpy (&mc_req.imr_multiaddr, native_addr, sizeof (struct in_addr)); + +#ifdef HAVE_IP_MREQN + if (iface) + mc_req.imr_ifindex = if_nametoindex (iface); + else + mc_req.imr_ifindex = 0; /* Pick any. */ +#elif defined(G_OS_WIN32) + if (iface) + mc_req.imr_interface.s_addr = g_socket_w32_get_adapter_ipv4_addr (iface); + else + mc_req.imr_interface.s_addr = g_htonl (INADDR_ANY); +#else + mc_req.imr_interface.s_addr = g_htonl (INADDR_ANY); +#endif + + if (source_specific) + { +#ifdef IP_ADD_SOURCE_MEMBERSHIP + optname = join_group ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP; +#else + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + join_group ? + _("Error joining multicast group: %s") : + _("Error leaving multicast group: %s"), + _("No support for source-specific multicast")); + return FALSE; +#endif + } + else + optname = join_group ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; + result = setsockopt (socket->priv->fd, IPPROTO_IP, optname, + &mc_req, sizeof (mc_req)); + } + else if (g_inet_address_get_family (group) == G_SOCKET_FAMILY_IPV6) + { + struct ipv6_mreq mc_req_ipv6; + + memset (&mc_req_ipv6, 0, sizeof (mc_req_ipv6)); + memcpy (&mc_req_ipv6.ipv6mr_multiaddr, native_addr, sizeof (struct in6_addr)); +#ifdef HAVE_IF_NAMETOINDEX + if (iface) + mc_req_ipv6.ipv6mr_interface = if_nametoindex (iface); + else +#endif + mc_req_ipv6.ipv6mr_interface = 0; + + optname = join_group ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP; + result = setsockopt (socket->priv->fd, IPPROTO_IPV6, optname, + &mc_req_ipv6, sizeof (mc_req_ipv6)); + } + else + g_return_val_if_reached (FALSE); + + if (result < 0) + { + int errsv = get_socket_errno (); + + g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), + join_group ? + _("Error joining multicast group: %s") : + _("Error leaving multicast group: %s"), + socket_strerror (errsv)); + return FALSE; + } + + return TRUE; +} + +/** + * g_socket_join_multicast_group: + * @socket: a #GSocket. + * @group: a #GInetAddress specifying the group address to join. + * @iface: (nullable): Name of the interface to use, or %NULL + * @source_specific: %TRUE if source-specific multicast should be used + * @error: #GError for error reporting, or %NULL to ignore. + * + * Registers @socket to receive multicast messages sent to @group. + * @socket must be a %G_SOCKET_TYPE_DATAGRAM socket, and must have + * been bound to an appropriate interface and port with + * g_socket_bind(). + * + * If @iface is %NULL, the system will automatically pick an interface + * to bind to based on @group. + * + * If @source_specific is %TRUE, source-specific multicast as defined + * in RFC 4604 is used. Note that on older platforms this may fail + * with a %G_IO_ERROR_NOT_SUPPORTED error. + * + * To bind to a given source-specific multicast address, use + * g_socket_join_multicast_group_ssm() instead. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.32 + */ +gboolean +g_socket_join_multicast_group (GSocket *socket, + GInetAddress *group, + gboolean source_specific, + const gchar *iface, + GError **error) +{ + return g_socket_multicast_group_operation (socket, group, source_specific, iface, TRUE, error); +} + +/** + * g_socket_leave_multicast_group: + * @socket: a #GSocket. + * @group: a #GInetAddress specifying the group address to leave. + * @iface: (nullable): Interface used + * @source_specific: %TRUE if source-specific multicast was used + * @error: #GError for error reporting, or %NULL to ignore. + * + * Removes @socket from the multicast group defined by @group, @iface, + * and @source_specific (which must all have the same values they had + * when you joined the group). + * + * @socket remains bound to its address and port, and can still receive + * unicast messages after calling this. + * + * To unbind to a given source-specific multicast address, use + * g_socket_leave_multicast_group_ssm() instead. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.32 + */ +gboolean +g_socket_leave_multicast_group (GSocket *socket, + GInetAddress *group, + gboolean source_specific, + const gchar *iface, + GError **error) +{ + return g_socket_multicast_group_operation (socket, group, source_specific, iface, FALSE, error); +} + +static gboolean +g_socket_multicast_group_operation_ssm (GSocket *socket, + GInetAddress *group, + GInetAddress *source_specific, + const gchar *iface, + gboolean join_group, + GError **error) +{ + gint result; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + g_return_val_if_fail (socket->priv->type == G_SOCKET_TYPE_DATAGRAM, FALSE); + g_return_val_if_fail (G_IS_INET_ADDRESS (group), FALSE); + g_return_val_if_fail (iface == NULL || *iface != '\0', FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!source_specific) + { + return g_socket_multicast_group_operation (socket, group, FALSE, iface, + join_group, error); + } + + if (!check_socket (socket, error)) + return FALSE; + + switch (g_inet_address_get_family (group)) + { + case G_SOCKET_FAMILY_INVALID: + case G_SOCKET_FAMILY_UNIX: + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + join_group ? + _("Error joining multicast group: %s") : + _("Error leaving multicast group: %s"), + _("Unsupported socket family")); + return FALSE; + } + break; + + case G_SOCKET_FAMILY_IPV4: + { +#ifdef IP_ADD_SOURCE_MEMBERSHIP + +#ifdef BROKEN_IP_MREQ_SOURCE_STRUCT +#define S_ADDR_FIELD(src) src.imr_interface +#else +#define S_ADDR_FIELD(src) src.imr_interface.s_addr +#endif + + gint optname; + struct ip_mreq_source mc_req_src; + + if (g_inet_address_get_family (source_specific) != + G_SOCKET_FAMILY_IPV4) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + join_group ? + _("Error joining multicast group: %s") : + _("Error leaving multicast group: %s"), + _("source-specific not an IPv4 address")); + return FALSE; + } + + memset (&mc_req_src, 0, sizeof (mc_req_src)); + + /* By default use the default IPv4 multicast interface. */ + S_ADDR_FIELD(mc_req_src) = g_htonl (INADDR_ANY); + + if (iface) + { +#if defined(G_OS_WIN32) + S_ADDR_FIELD(mc_req_src) = g_socket_w32_get_adapter_ipv4_addr (iface); +#elif defined (HAVE_SIOCGIFADDR) + int ret; + struct ifreq ifr; + struct sockaddr_in *iface_addr; + size_t if_name_len = strlen (iface); + + memset (&ifr, 0, sizeof (ifr)); + + if (if_name_len >= sizeof (ifr.ifr_name)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FILENAME_TOO_LONG, + _("Interface name too long")); + return FALSE; + } + + memcpy (ifr.ifr_name, iface, if_name_len); + + /* Get the IPv4 address of the given network interface name. */ + ret = ioctl (socket->priv->fd, SIOCGIFADDR, &ifr); + if (ret < 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Interface not found: %s"), g_strerror (errsv)); + return FALSE; + } + + iface_addr = (struct sockaddr_in *) &ifr.ifr_addr; + S_ADDR_FIELD(mc_req_src) = iface_addr->sin_addr.s_addr; +#endif /* defined(G_OS_WIN32) && defined (HAVE_IF_NAMETOINDEX) */ + } + memcpy (&mc_req_src.imr_multiaddr, g_inet_address_to_bytes (group), + g_inet_address_get_native_size (group)); + memcpy (&mc_req_src.imr_sourceaddr, + g_inet_address_to_bytes (source_specific), + g_inet_address_get_native_size (source_specific)); + + optname = + join_group ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP; + result = setsockopt (socket->priv->fd, IPPROTO_IP, optname, + &mc_req_src, sizeof (mc_req_src)); + +#undef S_ADDR_FIELD + +#else + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + join_group ? + _("Error joining multicast group: %s") : + _("Error leaving multicast group: %s"), + _("No support for IPv4 source-specific multicast")); + return FALSE; +#endif /* IP_ADD_SOURCE_MEMBERSHIP */ + } + break; + + case G_SOCKET_FAMILY_IPV6: + { +#ifdef MCAST_JOIN_SOURCE_GROUP + gboolean res; + gint optname; + struct group_source_req mc_req_src; + GSocketAddress *saddr_group, *saddr_source_specific; + guint iface_index = 0; + +#if defined (HAVE_IF_NAMETOINDEX) + if (iface) + { + iface_index = if_nametoindex (iface); + if (iface_index == 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Interface not found: %s"), g_strerror (errsv)); + return FALSE; + } + } +#endif /* defined (HAVE_IF_NAMETOINDEX) */ + mc_req_src.gsr_interface = iface_index; + + saddr_group = g_inet_socket_address_new (group, 0); + res = g_socket_address_to_native (saddr_group, &mc_req_src.gsr_group, + sizeof (mc_req_src.gsr_group), + error); + g_object_unref (saddr_group); + if (!res) + return FALSE; + + saddr_source_specific = g_inet_socket_address_new (source_specific, 0); + res = g_socket_address_to_native (saddr_source_specific, + &mc_req_src.gsr_source, + sizeof (mc_req_src.gsr_source), + error); + g_object_unref (saddr_source_specific); + + if (!res) + return FALSE; + + optname = + join_group ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP; + result = setsockopt (socket->priv->fd, IPPROTO_IPV6, optname, + &mc_req_src, sizeof (mc_req_src)); +#else + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + join_group ? + _("Error joining multicast group: %s") : + _("Error leaving multicast group: %s"), + _("No support for IPv6 source-specific multicast")); + return FALSE; +#endif /* MCAST_JOIN_SOURCE_GROUP */ + } + break; + + default: + g_return_val_if_reached (FALSE); + } + + if (result < 0) + { + int errsv = get_socket_errno (); + + g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), + join_group ? + _("Error joining multicast group: %s") : + _("Error leaving multicast group: %s"), + socket_strerror (errsv)); + return FALSE; + } + + return TRUE; +} + +/** + * g_socket_join_multicast_group_ssm: + * @socket: a #GSocket. + * @group: a #GInetAddress specifying the group address to join. + * @source_specific: (nullable): a #GInetAddress specifying the + * source-specific multicast address or %NULL to ignore. + * @iface: (nullable): Name of the interface to use, or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Registers @socket to receive multicast messages sent to @group. + * @socket must be a %G_SOCKET_TYPE_DATAGRAM socket, and must have + * been bound to an appropriate interface and port with + * g_socket_bind(). + * + * If @iface is %NULL, the system will automatically pick an interface + * to bind to based on @group. + * + * If @source_specific is not %NULL, use source-specific multicast as + * defined in RFC 4604. Note that on older platforms this may fail + * with a %G_IO_ERROR_NOT_SUPPORTED error. + * + * Note that this function can be called multiple times for the same + * @group with different @source_specific in order to receive multicast + * packets from more than one source. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.56 + */ +gboolean +g_socket_join_multicast_group_ssm (GSocket *socket, + GInetAddress *group, + GInetAddress *source_specific, + const gchar *iface, + GError **error) +{ + return g_socket_multicast_group_operation_ssm (socket, group, + source_specific, iface, TRUE, error); +} + +/** + * g_socket_leave_multicast_group_ssm: + * @socket: a #GSocket. + * @group: a #GInetAddress specifying the group address to leave. + * @source_specific: (nullable): a #GInetAddress specifying the + * source-specific multicast address or %NULL to ignore. + * @iface: (nullable): Name of the interface to use, or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Removes @socket from the multicast group defined by @group, @iface, + * and @source_specific (which must all have the same values they had + * when you joined the group). + * + * @socket remains bound to its address and port, and can still receive + * unicast messages after calling this. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.56 + */ +gboolean +g_socket_leave_multicast_group_ssm (GSocket *socket, + GInetAddress *group, + GInetAddress *source_specific, + const gchar *iface, + GError **error) +{ + return g_socket_multicast_group_operation_ssm (socket, group, + source_specific, iface, FALSE, error); +} + +/** + * g_socket_speaks_ipv4: + * @socket: a #GSocket + * + * Checks if a socket is capable of speaking IPv4. + * + * IPv4 sockets are capable of speaking IPv4. On some operating systems + * and under some combinations of circumstances IPv6 sockets are also + * capable of speaking IPv4. See RFC 3493 section 3.7 for more + * information. + * + * No other types of sockets are currently considered as being capable + * of speaking IPv4. + * + * Returns: %TRUE if this socket can be used with IPv4. + * + * Since: 2.22 + **/ +gboolean +g_socket_speaks_ipv4 (GSocket *socket) +{ + switch (socket->priv->family) + { + case G_SOCKET_FAMILY_IPV4: + return TRUE; + + case G_SOCKET_FAMILY_IPV6: +#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY) + { + gint v6_only; + + if (!g_socket_get_option (socket, + IPPROTO_IPV6, IPV6_V6ONLY, + &v6_only, NULL)) + return FALSE; + + return !v6_only; + } +#else + return FALSE; +#endif + + default: + return FALSE; + } +} + +/** + * g_socket_accept: + * @socket: a #GSocket. + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Accept incoming connections on a connection-based socket. This removes + * the first outstanding connection request from the listening socket and + * creates a #GSocket object for it. + * + * The @socket must be bound to a local address with g_socket_bind() and + * must be listening for incoming connections (g_socket_listen()). + * + * If there are no outstanding connections then the operation will block + * or return %G_IO_ERROR_WOULD_BLOCK if non-blocking I/O is enabled. + * To be notified of an incoming connection, wait for the %G_IO_IN condition. + * + * Returns: (transfer full): a new #GSocket, or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GSocket * +g_socket_accept (GSocket *socket, + GCancellable *cancellable, + GError **error) +{ + GSocket *new_socket; + gint ret; + + g_return_val_if_fail (G_IS_SOCKET (socket), NULL); + + if (!check_socket (socket, error)) + return NULL; + + if (!check_timeout (socket, error)) + return NULL; + + while (TRUE) + { + if ((ret = accept (socket->priv->fd, NULL, 0)) < 0) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + +#ifdef WSAEWOULDBLOCK + if (errsv == WSAEWOULDBLOCK) +#else + if (errsv == EWOULDBLOCK || + errsv == EAGAIN) +#endif + { + win32_unset_event_mask (socket, FD_ACCEPT); + + if (socket->priv->blocking) + { + if (!g_socket_condition_wait (socket, + G_IO_IN, cancellable, error)) + return NULL; + + continue; + } + } + + socket_set_error_lazy (error, errsv, _("Error accepting connection: %s")); + return NULL; + } + break; + } + + win32_unset_event_mask (socket, FD_ACCEPT); + +#ifdef G_OS_WIN32 + { + /* The socket inherits the accepting sockets event mask and even object, + we need to remove that */ + WSAEventSelect (ret, NULL, 0); + } +#else + { + int flags; + + /* We always want to set close-on-exec to protect users. If you + need to so some weird inheritance to exec you can re-enable this + using lower level hacks with g_socket_get_fd(). */ + flags = fcntl (ret, F_GETFD, 0); + if (flags != -1 && + (flags & FD_CLOEXEC) == 0) + { + flags |= FD_CLOEXEC; + fcntl (ret, F_SETFD, flags); + } + } +#endif + + new_socket = g_socket_new_from_fd (ret, error); + if (new_socket == NULL) + { +#ifdef G_OS_WIN32 + closesocket (ret); +#else + close (ret); +#endif + } + else + new_socket->priv->protocol = socket->priv->protocol; + + return new_socket; +} + +/** + * g_socket_connect: + * @socket: a #GSocket. + * @address: a #GSocketAddress specifying the remote address. + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Connect the socket to the specified remote address. + * + * For connection oriented socket this generally means we attempt to make + * a connection to the @address. For a connection-less socket it sets + * the default address for g_socket_send() and discards all incoming datagrams + * from other sources. + * + * Generally connection oriented sockets can only connect once, but + * connection-less sockets can connect multiple times to change the + * default address. + * + * If the connect call needs to do network I/O it will block, unless + * non-blocking I/O is enabled. Then %G_IO_ERROR_PENDING is returned + * and the user can be notified of the connection finishing by waiting + * for the G_IO_OUT condition. The result of the connection must then be + * checked with g_socket_check_connect_result(). + * + * Returns: %TRUE if connected, %FALSE on error. + * + * Since: 2.22 + */ +gboolean +g_socket_connect (GSocket *socket, + GSocketAddress *address, + GCancellable *cancellable, + GError **error) +{ + union { + struct sockaddr_storage storage; + struct sockaddr sa; + } buffer; + + g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE); + + if (!check_socket (socket, error)) + return FALSE; + + if (!g_socket_address_to_native (address, &buffer.storage, sizeof buffer, error)) + return FALSE; + + if (socket->priv->remote_address) + g_object_unref (socket->priv->remote_address); + socket->priv->remote_address = g_object_ref (address); + + while (1) + { + if (connect (socket->priv->fd, &buffer.sa, + g_socket_address_get_native_size (address)) < 0) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + +#ifndef G_OS_WIN32 + if (errsv == EINPROGRESS) +#else + if (errsv == WSAEWOULDBLOCK) +#endif + { + win32_unset_event_mask (socket, FD_CONNECT); + + if (socket->priv->blocking) + { + if (g_socket_condition_wait (socket, G_IO_OUT, cancellable, error)) + { + if (g_socket_check_connect_result (socket, error)) + break; + } + } + else + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING, + _("Connection in progress")); + socket->priv->connect_pending = TRUE; + } + } + else + g_set_error_literal (error, G_IO_ERROR, + socket_io_error_from_errno (errsv), + socket_strerror (errsv)); + + return FALSE; + } + break; + } + + win32_unset_event_mask (socket, FD_CONNECT); + + socket->priv->connected_read = TRUE; + socket->priv->connected_write = TRUE; + + return TRUE; +} + +/** + * g_socket_check_connect_result: + * @socket: a #GSocket + * @error: #GError for error reporting, or %NULL to ignore. + * + * Checks and resets the pending connect error for the socket. + * This is used to check for errors when g_socket_connect() is + * used in non-blocking mode. + * + * Returns: %TRUE if no error, %FALSE otherwise, setting @error to the error + * + * Since: 2.22 + */ +gboolean +g_socket_check_connect_result (GSocket *socket, + GError **error) +{ + int value; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + if (!check_socket (socket, error)) + return FALSE; + + if (!check_timeout (socket, error)) + return FALSE; + + if (!g_socket_get_option (socket, SOL_SOCKET, SO_ERROR, &value, error)) + { + g_prefix_error (error, _("Unable to get pending error: ")); + return FALSE; + } + + if (value != 0) + { + g_set_error_literal (error, G_IO_ERROR, socket_io_error_from_errno (value), + socket_strerror (value)); + if (socket->priv->remote_address) + { + g_object_unref (socket->priv->remote_address); + socket->priv->remote_address = NULL; + } + return FALSE; + } + + socket->priv->connected_read = TRUE; + socket->priv->connected_write = TRUE; + + return TRUE; +} + +/** + * g_socket_get_available_bytes: + * @socket: a #GSocket + * + * Get the amount of data pending in the OS input buffer, without blocking. + * + * If @socket is a UDP or SCTP socket, this will return the size of + * just the next packet, even if additional packets are buffered after + * that one. + * + * Note that on Windows, this function is rather inefficient in the + * UDP case, and so if you know any plausible upper bound on the size + * of the incoming packet, it is better to just do a + * g_socket_receive() with a buffer of that size, rather than calling + * g_socket_get_available_bytes() first and then doing a receive of + * exactly the right size. + * + * Returns: the number of bytes that can be read from the socket + * without blocking or truncating, or -1 on error. + * + * Since: 2.32 + */ +gssize +g_socket_get_available_bytes (GSocket *socket) +{ +#ifndef SO_NREAD + const gint bufsize = 64 * 1024; + static guchar *buf = NULL; +#endif +#ifdef G_OS_WIN32 + u_long avail; +#else + gint avail; +#endif + + g_return_val_if_fail (G_IS_SOCKET (socket), -1); + + if (!check_socket (socket, NULL)) + return -1; + +#ifdef SO_NREAD + if (!g_socket_get_option (socket, SOL_SOCKET, SO_NREAD, &avail, NULL)) + return -1; +#else + if (socket->priv->type == G_SOCKET_TYPE_DATAGRAM) + { + if (G_UNLIKELY (g_once_init_enter (&buf))) + g_once_init_leave (&buf, g_malloc (bufsize)); + + /* On datagram sockets, FIONREAD ioctl is not reliable because many + * systems add internal header size to the reported size, making it + * unusable for this function. */ + avail = recv (socket->priv->fd, buf, bufsize, MSG_PEEK); + if ((gint) avail == -1) + { + int errsv = get_socket_errno (); +#ifdef G_OS_WIN32 + if (errsv == WSAEWOULDBLOCK) +#else + if (errsv == EWOULDBLOCK || errsv == EAGAIN) +#endif + avail = 0; + } + } + else + { +#ifdef G_OS_WIN32 + if (ioctlsocket (socket->priv->fd, FIONREAD, &avail) < 0) +#else + if (ioctl (socket->priv->fd, FIONREAD, &avail) < 0) +#endif + avail = -1; + } +#endif + + return avail; +} + +/* Block on a timed wait for @condition until (@start_time + @timeout). + * Return %G_IO_ERROR_TIMED_OUT if the timeout is reached; otherwise %TRUE. + */ +static gboolean +block_on_timeout (GSocket *socket, + GIOCondition condition, + gint64 timeout_us, + gint64 start_time, + GCancellable *cancellable, + GError **error) +{ + gint64 wait_timeout = -1; + + g_return_val_if_fail (timeout_us != 0, TRUE); + + /* check if we've timed out or how much time to wait at most */ + if (timeout_us >= 0) + { + gint64 elapsed = g_get_monotonic_time () - start_time; + + if (elapsed >= timeout_us) + { + g_set_error_literal (error, + G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Socket I/O timed out")); + return FALSE; + } + + wait_timeout = timeout_us - elapsed; + } + + return g_socket_condition_timed_wait (socket, condition, wait_timeout, + cancellable, error); +} + +static gssize +g_socket_receive_with_timeout (GSocket *socket, + guint8 *buffer, + gsize size, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + gssize ret; + gint64 start_time; + + g_return_val_if_fail (G_IS_SOCKET (socket) && buffer != NULL, -1); + + start_time = g_get_monotonic_time (); + + if (!check_socket (socket, error)) + return -1; + + if (!check_timeout (socket, error)) + return -1; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + while (1) + { + if ((ret = recv (socket->priv->fd, buffer, size, 0)) < 0) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + +#ifdef WSAEWOULDBLOCK + if (errsv == WSAEWOULDBLOCK) +#else + if (errsv == EWOULDBLOCK || + errsv == EAGAIN) +#endif + { + win32_unset_event_mask (socket, FD_READ); + + if (timeout_us != 0) + { + if (!block_on_timeout (socket, G_IO_IN, timeout_us, start_time, + cancellable, error)) + return -1; + + continue; + } + } + + win32_unset_event_mask (socket, FD_READ); + + socket_set_error_lazy (error, errsv, _("Error receiving data: %s")); + return -1; + } + + win32_unset_event_mask (socket, FD_READ); + + break; + } + + return ret; +} + +/** + * g_socket_receive: + * @socket: a #GSocket + * @buffer: (array length=size) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least @size bytes long). + * @size: the number of bytes you want to read from the socket + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Receive data (up to @size bytes) from a socket. This is mainly used by + * connection-oriented sockets; it is identical to g_socket_receive_from() + * with @address set to %NULL. + * + * For %G_SOCKET_TYPE_DATAGRAM and %G_SOCKET_TYPE_SEQPACKET sockets, + * g_socket_receive() will always read either 0 or 1 complete messages from + * the socket. If the received message is too large to fit in @buffer, then + * the data beyond @size bytes will be discarded, without any explicit + * indication that this has occurred. + * + * For %G_SOCKET_TYPE_STREAM sockets, g_socket_receive() can return any + * number of bytes, up to @size. If more than @size bytes have been + * received, the additional data will be returned in future calls to + * g_socket_receive(). + * + * If the socket is in blocking mode the call will block until there + * is some data to receive, the connection is closed, or there is an + * error. If there is no data available and the socket is in + * non-blocking mode, a %G_IO_ERROR_WOULD_BLOCK error will be + * returned. To be notified when data is available, wait for the + * %G_IO_IN condition. + * + * On error -1 is returned and @error is set accordingly. + * + * Returns: Number of bytes read, or 0 if the connection was closed by + * the peer, or -1 on error + * + * Since: 2.22 + */ +gssize +g_socket_receive (GSocket *socket, + gchar *buffer, + gsize size, + GCancellable *cancellable, + GError **error) +{ + return g_socket_receive_with_timeout (socket, (guint8 *) buffer, size, + socket->priv->blocking ? -1 : 0, + cancellable, error); +} + +/** + * g_socket_receive_with_blocking: + * @socket: a #GSocket + * @buffer: (array length=size) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least @size bytes long). + * @size: the number of bytes you want to read from the socket + * @blocking: whether to do blocking or non-blocking I/O + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * This behaves exactly the same as g_socket_receive(), except that + * the choice of blocking or non-blocking behavior is determined by + * the @blocking argument rather than by @socket's properties. + * + * Returns: Number of bytes read, or 0 if the connection was closed by + * the peer, or -1 on error + * + * Since: 2.26 + */ +gssize +g_socket_receive_with_blocking (GSocket *socket, + gchar *buffer, + gsize size, + gboolean blocking, + GCancellable *cancellable, + GError **error) +{ + return g_socket_receive_with_timeout (socket, (guint8 *) buffer, size, + blocking ? -1 : 0, cancellable, error); +} + +/** + * g_socket_receive_from: + * @socket: a #GSocket + * @address: (out) (optional): a pointer to a #GSocketAddress + * pointer, or %NULL + * @buffer: (array length=size) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least @size bytes long). + * @size: the number of bytes you want to read from the socket + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Receive data (up to @size bytes) from a socket. + * + * If @address is non-%NULL then @address will be set equal to the + * source address of the received packet. + * @address is owned by the caller. + * + * See g_socket_receive() for additional information. + * + * Returns: Number of bytes read, or 0 if the connection was closed by + * the peer, or -1 on error + * + * Since: 2.22 + */ +gssize +g_socket_receive_from (GSocket *socket, + GSocketAddress **address, + gchar *buffer, + gsize size, + GCancellable *cancellable, + GError **error) +{ + GInputVector v; + + v.buffer = buffer; + v.size = size; + + return g_socket_receive_message (socket, + address, + &v, 1, + NULL, 0, NULL, + cancellable, + error); +} + +/* See the comment about SIGPIPE above. */ +#ifdef MSG_NOSIGNAL +#define G_SOCKET_DEFAULT_SEND_FLAGS MSG_NOSIGNAL +#else +#define G_SOCKET_DEFAULT_SEND_FLAGS 0 +#endif + +static gssize +g_socket_send_with_timeout (GSocket *socket, + const guint8 *buffer, + gsize size, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + gssize ret; + gint64 start_time; + + g_return_val_if_fail (G_IS_SOCKET (socket) && buffer != NULL, -1); + + start_time = g_get_monotonic_time (); + + if (!check_socket (socket, error)) + return -1; + + if (!check_timeout (socket, error)) + return -1; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + while (1) + { + if ((ret = send (socket->priv->fd, (const char *)buffer, size, G_SOCKET_DEFAULT_SEND_FLAGS)) < 0) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + +#ifdef WSAEWOULDBLOCK + if (errsv == WSAEWOULDBLOCK) +#else + if (errsv == EWOULDBLOCK || + errsv == EAGAIN) +#endif + { + win32_unset_event_mask (socket, FD_WRITE); + + if (timeout_us != 0) + { + if (!block_on_timeout (socket, G_IO_OUT, timeout_us, start_time, + cancellable, error)) + return -1; + + continue; + } + } + + socket_set_error_lazy (error, errsv, _("Error sending data: %s")); + return -1; + } + break; + } + + return ret; +} + +/** + * g_socket_send: + * @socket: a #GSocket + * @buffer: (array length=size) (element-type guint8): the buffer + * containing the data to send. + * @size: the number of bytes to send + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Tries to send @size bytes from @buffer on the socket. This is + * mainly used by connection-oriented sockets; it is identical to + * g_socket_send_to() with @address set to %NULL. + * + * If the socket is in blocking mode the call will block until there is + * space for the data in the socket queue. If there is no space available + * and the socket is in non-blocking mode a %G_IO_ERROR_WOULD_BLOCK error + * will be returned. To be notified when space is available, wait for the + * %G_IO_OUT condition. Note though that you may still receive + * %G_IO_ERROR_WOULD_BLOCK from g_socket_send() even if you were previously + * notified of a %G_IO_OUT condition. (On Windows in particular, this is + * very common due to the way the underlying APIs work.) + * + * On error -1 is returned and @error is set accordingly. + * + * Returns: Number of bytes written (which may be less than @size), or -1 + * on error + * + * Since: 2.22 + */ +gssize +g_socket_send (GSocket *socket, + const gchar *buffer, + gsize size, + GCancellable *cancellable, + GError **error) +{ + return g_socket_send_with_blocking (socket, buffer, size, + socket->priv->blocking, + cancellable, error); +} + +/** + * g_socket_send_with_blocking: + * @socket: a #GSocket + * @buffer: (array length=size) (element-type guint8): the buffer + * containing the data to send. + * @size: the number of bytes to send + * @blocking: whether to do blocking or non-blocking I/O + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * This behaves exactly the same as g_socket_send(), except that + * the choice of blocking or non-blocking behavior is determined by + * the @blocking argument rather than by @socket's properties. + * + * Returns: Number of bytes written (which may be less than @size), or -1 + * on error + * + * Since: 2.26 + */ +gssize +g_socket_send_with_blocking (GSocket *socket, + const gchar *buffer, + gsize size, + gboolean blocking, + GCancellable *cancellable, + GError **error) +{ + return g_socket_send_with_timeout (socket, (const guint8 *) buffer, size, + blocking ? -1 : 0, cancellable, error); +} + +/** + * g_socket_send_to: + * @socket: a #GSocket + * @address: (nullable): a #GSocketAddress, or %NULL + * @buffer: (array length=size) (element-type guint8): the buffer + * containing the data to send. + * @size: the number of bytes to send + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Tries to send @size bytes from @buffer to @address. If @address is + * %NULL then the message is sent to the default receiver (set by + * g_socket_connect()). + * + * See g_socket_send() for additional information. + * + * Returns: Number of bytes written (which may be less than @size), or -1 + * on error + * + * Since: 2.22 + */ +gssize +g_socket_send_to (GSocket *socket, + GSocketAddress *address, + const gchar *buffer, + gsize size, + GCancellable *cancellable, + GError **error) +{ + GOutputVector v; + + v.buffer = buffer; + v.size = size; + + return g_socket_send_message (socket, + address, + &v, 1, + NULL, 0, + 0, + cancellable, + error); +} + +/** + * g_socket_shutdown: + * @socket: a #GSocket + * @shutdown_read: whether to shut down the read side + * @shutdown_write: whether to shut down the write side + * @error: #GError for error reporting, or %NULL to ignore. + * + * Shut down part or all of a full-duplex connection. + * + * If @shutdown_read is %TRUE then the receiving side of the connection + * is shut down, and further reading is disallowed. + * + * If @shutdown_write is %TRUE then the sending side of the connection + * is shut down, and further writing is disallowed. + * + * It is allowed for both @shutdown_read and @shutdown_write to be %TRUE. + * + * One example where it is useful to shut down only one side of a connection is + * graceful disconnect for TCP connections where you close the sending side, + * then wait for the other side to close the connection, thus ensuring that the + * other side saw all sent data. + * + * Returns: %TRUE on success, %FALSE on error + * + * Since: 2.22 + */ +gboolean +g_socket_shutdown (GSocket *socket, + gboolean shutdown_read, + gboolean shutdown_write, + GError **error) +{ + int how; + + g_return_val_if_fail (G_IS_SOCKET (socket), TRUE); + + if (!check_socket (socket, error)) + return FALSE; + + /* Do nothing? */ + if (!shutdown_read && !shutdown_write) + return TRUE; + +#ifndef G_OS_WIN32 + if (shutdown_read && shutdown_write) + how = SHUT_RDWR; + else if (shutdown_read) + how = SHUT_RD; + else + how = SHUT_WR; +#else + if (shutdown_read && shutdown_write) + how = SD_BOTH; + else if (shutdown_read) + how = SD_RECEIVE; + else + how = SD_SEND; +#endif + + if (shutdown (socket->priv->fd, how) != 0) + { + int errsv = get_socket_errno (); + g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), + _("Unable to shutdown socket: %s"), socket_strerror (errsv)); + return FALSE; + } + + if (shutdown_read) + socket->priv->connected_read = FALSE; + if (shutdown_write) + socket->priv->connected_write = FALSE; + + return TRUE; +} + +/** + * g_socket_close: + * @socket: a #GSocket + * @error: #GError for error reporting, or %NULL to ignore. + * + * Closes the socket, shutting down any active connection. + * + * Closing a socket does not wait for all outstanding I/O operations + * to finish, so the caller should not rely on them to be guaranteed + * to complete even if the close returns with no error. + * + * Once the socket is closed, all other operations will return + * %G_IO_ERROR_CLOSED. Closing a socket multiple times will not + * return an error. + * + * Sockets will be automatically closed when the last reference + * is dropped, but you might want to call this function to make sure + * resources are released as early as possible. + * + * Beware that due to the way that TCP works, it is possible for + * recently-sent data to be lost if either you close a socket while the + * %G_IO_IN condition is set, or else if the remote connection tries to + * send something to you after you close the socket but before it has + * finished reading all of the data you sent. There is no easy generic + * way to avoid this problem; the easiest fix is to design the network + * protocol such that the client will never send data "out of turn". + * Another solution is for the server to half-close the connection by + * calling g_socket_shutdown() with only the @shutdown_write flag set, + * and then wait for the client to notice this and close its side of the + * connection, after which the server can safely call g_socket_close(). + * (This is what #GTcpConnection does if you call + * g_tcp_connection_set_graceful_disconnect(). But of course, this + * only works if the client will close its connection after the server + * does.) + * + * Returns: %TRUE on success, %FALSE on error + * + * Since: 2.22 + */ +gboolean +g_socket_close (GSocket *socket, + GError **error) +{ + int res; + + g_return_val_if_fail (G_IS_SOCKET (socket), TRUE); + + if (socket->priv->closed) + return TRUE; /* Multiple close not an error */ + + if (!check_socket (socket, error)) + return FALSE; + + while (1) + { +#ifdef G_OS_WIN32 + res = closesocket (socket->priv->fd); +#else + res = close (socket->priv->fd); +#endif + if (res == -1) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + + g_set_error (error, G_IO_ERROR, + socket_io_error_from_errno (errsv), + _("Error closing socket: %s"), + socket_strerror (errsv)); + return FALSE; + } + break; + } + + socket->priv->fd = -1; + socket->priv->connected_read = FALSE; + socket->priv->connected_write = FALSE; + socket->priv->closed = TRUE; + if (socket->priv->remote_address) + { + g_object_unref (socket->priv->remote_address); + socket->priv->remote_address = NULL; + } + + return TRUE; +} + +/** + * g_socket_is_closed: + * @socket: a #GSocket + * + * Checks whether a socket is closed. + * + * Returns: %TRUE if socket is closed, %FALSE otherwise + * + * Since: 2.22 + */ +gboolean +g_socket_is_closed (GSocket *socket) +{ + return socket->priv->closed; +} + +/* Broken source, used on errors */ +static gboolean +broken_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + return TRUE; +} + +static GSourceFuncs broken_funcs = +{ + NULL, + NULL, + broken_dispatch, + NULL, + NULL, + NULL, +}; + +#ifdef G_OS_WIN32 +static gint +network_events_for_condition (GIOCondition condition) +{ + int event_mask = 0; + + if (condition & G_IO_IN) + event_mask |= (FD_READ | FD_ACCEPT); + if (condition & G_IO_OUT) + event_mask |= (FD_WRITE | FD_CONNECT); + event_mask |= FD_CLOSE; + + return event_mask; +} + +static void +ensure_event (GSocket *socket) +{ + if (socket->priv->event == WSA_INVALID_EVENT) + socket->priv->event = WSACreateEvent(); +} + +static void +update_select_events (GSocket *socket) +{ + int event_mask; + GIOCondition *ptr; + GList *l; + WSAEVENT event; + + if (socket->priv->closed) + return; + + ensure_event (socket); + + event_mask = 0; + for (l = socket->priv->requested_conditions; l != NULL; l = l->next) + { + ptr = l->data; + event_mask |= network_events_for_condition (*ptr); + } + + if (event_mask != socket->priv->selected_events) + { + /* If no events selected, disable event so we can unset + nonblocking mode */ + + if (event_mask == 0) + event = NULL; + else + event = socket->priv->event; + + if (WSAEventSelect (socket->priv->fd, event, event_mask) == 0) + socket->priv->selected_events = event_mask; + } +} + +static void +add_condition_watch (GSocket *socket, + GIOCondition *condition) +{ + g_mutex_lock (&socket->priv->win32_source_lock); + g_assert (g_list_find (socket->priv->requested_conditions, condition) == NULL); + + socket->priv->requested_conditions = + g_list_prepend (socket->priv->requested_conditions, condition); + + update_select_events (socket); + g_mutex_unlock (&socket->priv->win32_source_lock); +} + +static void +remove_condition_watch (GSocket *socket, + GIOCondition *condition) +{ + g_mutex_lock (&socket->priv->win32_source_lock); + g_assert (g_list_find (socket->priv->requested_conditions, condition) != NULL); + + socket->priv->requested_conditions = + g_list_remove (socket->priv->requested_conditions, condition); + + update_select_events (socket); + g_mutex_unlock (&socket->priv->win32_source_lock); +} + +static GIOCondition +update_condition_unlocked (GSocket *socket) +{ + WSANETWORKEVENTS events; + GIOCondition condition; + + if (!socket->priv->closed && + WSAEnumNetworkEvents (socket->priv->fd, + socket->priv->event, + &events) == 0) + { + socket->priv->current_events |= events.lNetworkEvents; + if (events.lNetworkEvents & FD_WRITE && + events.iErrorCode[FD_WRITE_BIT] != 0) + socket->priv->current_errors |= FD_WRITE; + if (events.lNetworkEvents & FD_CONNECT && + events.iErrorCode[FD_CONNECT_BIT] != 0) + socket->priv->current_errors |= FD_CONNECT; + } + + condition = 0; + if (socket->priv->current_events & (FD_READ | FD_ACCEPT)) + condition |= G_IO_IN; + + if (socket->priv->current_events & FD_CLOSE) + { + int r, errsv, buffer; + + r = recv (socket->priv->fd, &buffer, sizeof (buffer), MSG_PEEK); + if (r < 0) + errsv = get_socket_errno (); + + if (r > 0 || + (r < 0 && errsv == WSAENOTCONN)) + condition |= G_IO_IN; + else if (r == 0 || + (r < 0 && (errsv == WSAESHUTDOWN || errsv == WSAECONNRESET || + errsv == WSAECONNABORTED || errsv == WSAENETRESET))) + condition |= G_IO_HUP; + else + condition |= G_IO_ERR; + } + + if (socket->priv->closed) + condition |= G_IO_HUP; + + /* Never report both G_IO_OUT and HUP, these are + mutually exclusive (can't write to a closed socket) */ + if ((condition & G_IO_HUP) == 0 && + socket->priv->current_events & FD_WRITE) + { + if (socket->priv->current_errors & FD_WRITE) + condition |= G_IO_ERR; + else + condition |= G_IO_OUT; + } + else + { + if (socket->priv->current_events & FD_CONNECT) + { + if (socket->priv->current_errors & FD_CONNECT) + condition |= (G_IO_HUP | G_IO_ERR); + else + condition |= G_IO_OUT; + } + } + + return condition; +} + +static GIOCondition +update_condition (GSocket *socket) +{ + GIOCondition res; + g_mutex_lock (&socket->priv->win32_source_lock); + res = update_condition_unlocked (socket); + g_mutex_unlock (&socket->priv->win32_source_lock); + return res; +} +#endif + +typedef struct { + GSource source; +#ifdef G_OS_WIN32 + GPollFD pollfd; +#else + gpointer fd_tag; +#endif + GSocket *socket; + GIOCondition condition; +} GSocketSource; + +static gboolean +socket_source_prepare (GSource *source, + gint *timeout) +{ + GSocketSource *socket_source = (GSocketSource *)source; + + *timeout = -1; + +#ifdef G_OS_WIN32 + if ((socket_source->pollfd.revents & G_IO_NVAL) != 0) + return TRUE; + + if (g_socket_is_closed (socket_source->socket)) + { + g_source_remove_poll (source, &socket_source->pollfd); + socket_source->pollfd.revents = G_IO_NVAL; + return TRUE; + } + + return (update_condition (socket_source->socket) & socket_source->condition) != 0; +#else + return g_socket_is_closed (socket_source->socket) && socket_source->fd_tag != NULL; +#endif +} + +#ifdef G_OS_WIN32 +static gboolean +socket_source_check_win32 (GSource *source) +{ + int timeout; + + return socket_source_prepare (source, &timeout); +} +#endif + +static gboolean +socket_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GSocketSourceFunc func = (GSocketSourceFunc)callback; + GSocketSource *socket_source = (GSocketSource *)source; + GSocket *socket = socket_source->socket; + gint64 timeout; + guint events; + gboolean ret; + +#ifdef G_OS_WIN32 + if ((socket_source->pollfd.revents & G_IO_NVAL) != 0) + events = G_IO_NVAL; + else + events = update_condition (socket_source->socket); +#else + if (g_socket_is_closed (socket_source->socket)) + { + if (socket_source->fd_tag) + g_source_remove_unix_fd (source, socket_source->fd_tag); + socket_source->fd_tag = NULL; + events = G_IO_NVAL; + } + else + { + events = g_source_query_unix_fd (source, socket_source->fd_tag); + } +#endif + + timeout = g_source_get_ready_time (source); + if (timeout >= 0 && timeout < g_source_get_time (source) && + !g_socket_is_closed (socket_source->socket)) + { + socket->priv->timed_out = TRUE; + events |= (G_IO_IN | G_IO_OUT); + } + + ret = (*func) (socket, events & socket_source->condition, user_data); + + if (socket->priv->timeout && !g_socket_is_closed (socket_source->socket)) + g_source_set_ready_time (source, g_get_monotonic_time () + socket->priv->timeout * 1000000); + else + g_source_set_ready_time (source, -1); + + return ret; +} + +static void +socket_source_finalize (GSource *source) +{ + GSocketSource *socket_source = (GSocketSource *)source; + GSocket *socket; + + socket = socket_source->socket; + +#ifdef G_OS_WIN32 + remove_condition_watch (socket, &socket_source->condition); +#endif + + g_object_unref (socket); +} + +static gboolean +socket_source_closure_callback (GSocket *socket, + GIOCondition condition, + gpointer data) +{ + GClosure *closure = data; + + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_value_init (¶ms[0], G_TYPE_SOCKET); + g_value_set_object (¶ms[0], socket); + g_value_init (¶ms[1], G_TYPE_IO_CONDITION); + g_value_set_flags (¶ms[1], condition); + + g_closure_invoke (closure, &result_value, 2, params, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + g_value_unset (¶ms[0]); + g_value_unset (¶ms[1]); + + return result; +} + +static GSourceFuncs socket_source_funcs = +{ + socket_source_prepare, +#ifdef G_OS_WIN32 + socket_source_check_win32, +#else + NULL, +#endif + socket_source_dispatch, + socket_source_finalize, + (GSourceFunc)socket_source_closure_callback, + NULL, +}; + +static GSource * +socket_source_new (GSocket *socket, + GIOCondition condition, + GCancellable *cancellable) +{ + GSource *source; + GSocketSource *socket_source; + +#ifdef G_OS_WIN32 + ensure_event (socket); + + if (socket->priv->event == WSA_INVALID_EVENT) + { + g_warning ("Failed to create WSAEvent"); + return g_source_new (&broken_funcs, sizeof (GSource)); + } +#endif + + if (!check_socket (socket, NULL)) + { + g_warning ("Socket check failed"); + return g_source_new (&broken_funcs, sizeof (GSource)); + } + + condition |= G_IO_HUP | G_IO_ERR | G_IO_NVAL; + + source = g_source_new (&socket_source_funcs, sizeof (GSocketSource)); + g_source_set_static_name (source, "GSocket"); + socket_source = (GSocketSource *)source; + + socket_source->socket = g_object_ref (socket); + socket_source->condition = condition; + + if (cancellable) + { + GSource *cancellable_source; + + cancellable_source = g_cancellable_source_new (cancellable); + g_source_add_child_source (source, cancellable_source); + g_source_set_dummy_callback (cancellable_source); + g_source_unref (cancellable_source); + } + +#ifdef G_OS_WIN32 + add_condition_watch (socket, &socket_source->condition); + socket_source->pollfd.fd = (gintptr) socket->priv->event; + socket_source->pollfd.events = condition; + socket_source->pollfd.revents = 0; + g_source_add_poll (source, &socket_source->pollfd); +#else + socket_source->fd_tag = g_source_add_unix_fd (source, socket->priv->fd, condition); +#endif + + if (socket->priv->timeout) + g_source_set_ready_time (source, g_get_monotonic_time () + socket->priv->timeout * 1000000); + else + g_source_set_ready_time (source, -1); + + return source; +} + +/** + * g_socket_create_source: (skip) + * @socket: a #GSocket + * @condition: a #GIOCondition mask to monitor + * @cancellable: (nullable): a %GCancellable or %NULL + * + * Creates a #GSource that can be attached to a %GMainContext to monitor + * for the availability of the specified @condition on the socket. The #GSource + * keeps a reference to the @socket. + * + * The callback on the source is of the #GSocketSourceFunc type. + * + * It is meaningless to specify %G_IO_ERR or %G_IO_HUP in @condition; + * these conditions will always be reported output if they are true. + * + * @cancellable if not %NULL can be used to cancel the source, which will + * cause the source to trigger, reporting the current condition (which + * is likely 0 unless cancellation happened at the same time as a + * condition change). You can check for this in the callback using + * g_cancellable_is_cancelled(). + * + * If @socket has a timeout set, and it is reached before @condition + * occurs, the source will then trigger anyway, reporting %G_IO_IN or + * %G_IO_OUT depending on @condition. However, @socket will have been + * marked as having had a timeout, and so the next #GSocket I/O method + * you call will then fail with a %G_IO_ERROR_TIMED_OUT. + * + * Returns: (transfer full): a newly allocated %GSource, free with g_source_unref(). + * + * Since: 2.22 + */ +GSource * +g_socket_create_source (GSocket *socket, + GIOCondition condition, + GCancellable *cancellable) +{ + g_return_val_if_fail (G_IS_SOCKET (socket) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL); + + return socket_source_new (socket, condition, cancellable); +} + +/** + * g_socket_condition_check: + * @socket: a #GSocket + * @condition: a #GIOCondition mask to check + * + * Checks on the readiness of @socket to perform operations. + * The operations specified in @condition are checked for and masked + * against the currently-satisfied conditions on @socket. The result + * is returned. + * + * Note that on Windows, it is possible for an operation to return + * %G_IO_ERROR_WOULD_BLOCK even immediately after + * g_socket_condition_check() has claimed that the socket is ready for + * writing. Rather than calling g_socket_condition_check() and then + * writing to the socket if it succeeds, it is generally better to + * simply try writing to the socket right away, and try again later if + * the initial attempt returns %G_IO_ERROR_WOULD_BLOCK. + * + * It is meaningless to specify %G_IO_ERR or %G_IO_HUP in condition; + * these conditions will always be set in the output if they are true. + * + * This call never blocks. + * + * Returns: the @GIOCondition mask of the current state + * + * Since: 2.22 + */ +GIOCondition +g_socket_condition_check (GSocket *socket, + GIOCondition condition) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), 0); + + if (!check_socket (socket, NULL)) + return 0; + +#ifdef G_OS_WIN32 + { + GIOCondition current_condition; + + condition |= G_IO_ERR | G_IO_HUP; + + add_condition_watch (socket, &condition); + current_condition = update_condition (socket); + remove_condition_watch (socket, &condition); + return condition & current_condition; + } +#else + { + GPollFD poll_fd; + gint result; + poll_fd.fd = socket->priv->fd; + poll_fd.events = condition; + poll_fd.revents = 0; + + do + result = g_poll (&poll_fd, 1, 0); + while (result == -1 && get_socket_errno () == EINTR); + + return poll_fd.revents; + } +#endif +} + +/** + * g_socket_condition_wait: + * @socket: a #GSocket + * @condition: a #GIOCondition mask to wait for + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a #GError pointer, or %NULL + * + * Waits for @condition to become true on @socket. When the condition + * is met, %TRUE is returned. + * + * If @cancellable is cancelled before the condition is met, or if the + * socket has a timeout set and it is reached before the condition is + * met, then %FALSE is returned and @error, if non-%NULL, is set to + * the appropriate value (%G_IO_ERROR_CANCELLED or + * %G_IO_ERROR_TIMED_OUT). + * + * See also g_socket_condition_timed_wait(). + * + * Returns: %TRUE if the condition was met, %FALSE otherwise + * + * Since: 2.22 + */ +gboolean +g_socket_condition_wait (GSocket *socket, + GIOCondition condition, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + return g_socket_condition_timed_wait (socket, condition, -1, + cancellable, error); +} + +/** + * g_socket_condition_timed_wait: + * @socket: a #GSocket + * @condition: a #GIOCondition mask to wait for + * @timeout_us: the maximum time (in microseconds) to wait, or -1 + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a #GError pointer, or %NULL + * + * Waits for up to @timeout_us microseconds for @condition to become true + * on @socket. If the condition is met, %TRUE is returned. + * + * If @cancellable is cancelled before the condition is met, or if + * @timeout_us (or the socket's #GSocket:timeout) is reached before the + * condition is met, then %FALSE is returned and @error, if non-%NULL, + * is set to the appropriate value (%G_IO_ERROR_CANCELLED or + * %G_IO_ERROR_TIMED_OUT). + * + * If you don't want a timeout, use g_socket_condition_wait(). + * (Alternatively, you can pass -1 for @timeout_us.) + * + * Note that although @timeout_us is in microseconds for consistency with + * other GLib APIs, this function actually only has millisecond + * resolution, and the behavior is undefined if @timeout_us is not an + * exact number of milliseconds. + * + * Returns: %TRUE if the condition was met, %FALSE otherwise + * + * Since: 2.32 + */ +gboolean +g_socket_condition_timed_wait (GSocket *socket, + GIOCondition condition, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + gint64 start_time; + gint64 timeout_ms; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + if (!check_socket (socket, error)) + return FALSE; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + if (socket->priv->timeout && + (timeout_us < 0 || socket->priv->timeout < timeout_us / G_USEC_PER_SEC)) + timeout_ms = (gint64) socket->priv->timeout * 1000; + else if (timeout_us != -1) + timeout_ms = timeout_us / 1000; + else + timeout_ms = -1; + + start_time = g_get_monotonic_time (); + +#ifdef G_OS_WIN32 + { + GIOCondition current_condition; + WSAEVENT events[2]; + DWORD res; + GPollFD cancel_fd; + int num_events; + + /* Always check these */ + condition |= G_IO_ERR | G_IO_HUP; + + add_condition_watch (socket, &condition); + + num_events = 0; + events[num_events++] = socket->priv->event; + + if (g_cancellable_make_pollfd (cancellable, &cancel_fd)) + events[num_events++] = (WSAEVENT)cancel_fd.fd; + + if (timeout_ms == -1) + timeout_ms = WSA_INFINITE; + + g_mutex_lock (&socket->priv->win32_source_lock); + current_condition = update_condition_unlocked (socket); + while ((condition & current_condition) == 0) + { + if (!socket->priv->waiting) + { + socket->priv->waiting = TRUE; + socket->priv->waiting_result = 0; + g_mutex_unlock (&socket->priv->win32_source_lock); + + res = WSAWaitForMultipleEvents (num_events, events, FALSE, timeout_ms, FALSE); + + g_mutex_lock (&socket->priv->win32_source_lock); + socket->priv->waiting = FALSE; + socket->priv->waiting_result = res; + g_cond_broadcast (&socket->priv->win32_source_cond); + } + else + { + if (timeout_ms != WSA_INFINITE) + { + if (!g_cond_wait_until (&socket->priv->win32_source_cond, &socket->priv->win32_source_lock, timeout_ms)) + { + res = WSA_WAIT_TIMEOUT; + break; + } + else + { + res = socket->priv->waiting_result; + } + } + else + { + g_cond_wait (&socket->priv->win32_source_cond, &socket->priv->win32_source_lock); + res = socket->priv->waiting_result; + } + } + + if (res == WSA_WAIT_FAILED) + { + int errsv = get_socket_errno (); + + g_set_error (error, G_IO_ERROR, + socket_io_error_from_errno (errsv), + _("Waiting for socket condition: %s"), + socket_strerror (errsv)); + break; + } + else if (res == WSA_WAIT_TIMEOUT) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Socket I/O timed out")); + break; + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + break; + + current_condition = update_condition_unlocked (socket); + + if (timeout_ms != WSA_INFINITE) + { + timeout_ms -= (g_get_monotonic_time () - start_time) * 1000; + if (timeout_ms < 0) + timeout_ms = 0; + } + } + g_mutex_unlock (&socket->priv->win32_source_lock); + remove_condition_watch (socket, &condition); + if (num_events > 1) + g_cancellable_release_fd (cancellable); + + return (condition & current_condition) != 0; + } +#else + { + GPollFD poll_fd[2]; + gint result; + gint num; + + poll_fd[0].fd = socket->priv->fd; + poll_fd[0].events = condition; + num = 1; + + if (g_cancellable_make_pollfd (cancellable, &poll_fd[1])) + num++; + + while (TRUE) + { + int errsv; + result = g_poll (poll_fd, num, timeout_ms); + errsv = errno; + if (result != -1 || errsv != EINTR) + break; + + if (timeout_ms != -1) + { + timeout_ms -= (g_get_monotonic_time () - start_time) / 1000; + if (timeout_ms < 0) + timeout_ms = 0; + } + } + + if (num > 1) + g_cancellable_release_fd (cancellable); + + if (result == 0) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Socket I/O timed out")); + return FALSE; + } + + return !g_cancellable_set_error_if_cancelled (cancellable, error); + } + #endif +} + +#ifndef G_OS_WIN32 + +#ifdef HAVE_QNX +/* QNX has this weird upper limit, or at least used to back in the 6.x days. + * This was discovered empirically and doesn't appear to be mentioned in any + * of the official documentation. */ +# define G_SOCKET_CONTROL_BUFFER_SIZE_BYTES 2016 +#else +# define G_SOCKET_CONTROL_BUFFER_SIZE_BYTES 2048 +#endif + +/* Unfortunately these have to be macros rather than inline functions due to + * using alloca(). */ +#define output_message_to_msghdr(message, prev_message, msg, prev_msg, error) \ +G_STMT_START { \ + const GOutputMessage *_message = (message); \ + const GOutputMessage *_prev_message = (prev_message); \ + struct msghdr *_msg = (msg); \ + const struct msghdr *_prev_msg = (prev_msg); \ + GError **_error = (error); \ + \ + _msg->msg_flags = 0; \ + \ + /* name */ \ + if (_prev_message != NULL && _prev_message->address == _message->address) \ + { \ + _msg->msg_name = _prev_msg->msg_name; \ + _msg->msg_namelen = _prev_msg->msg_namelen; \ + } \ + else if (_message->address != NULL) \ + { \ + _msg->msg_namelen = g_socket_address_get_native_size (_message->address); \ + _msg->msg_name = g_alloca (_msg->msg_namelen); \ + if (!g_socket_address_to_native (_message->address, _msg->msg_name, \ + _msg->msg_namelen, _error)) \ + break; \ + } \ + else \ + { \ + _msg->msg_name = NULL; \ + _msg->msg_namelen = 0; \ + } \ + \ + /* iov */ \ + { \ + /* this entire expression will be evaluated at compile time */ \ + if (sizeof *_msg->msg_iov == sizeof *_message->vectors && \ + sizeof _msg->msg_iov->iov_base == sizeof _message->vectors->buffer && \ + G_STRUCT_OFFSET (struct iovec, iov_base) == \ + G_STRUCT_OFFSET (GOutputVector, buffer) && \ + sizeof _msg->msg_iov->iov_len == sizeof _message->vectors->size && \ + G_STRUCT_OFFSET (struct iovec, iov_len) == \ + G_STRUCT_OFFSET (GOutputVector, size)) \ + /* ABI is compatible */ \ + { \ + _msg->msg_iov = (struct iovec *) _message->vectors; \ + _msg->msg_iovlen = _message->num_vectors; \ + } \ + else \ + /* ABI is incompatible */ \ + { \ + guint i; \ + \ + _msg->msg_iov = g_newa (struct iovec, _message->num_vectors); \ + for (i = 0; i < _message->num_vectors; i++) \ + { \ + _msg->msg_iov[i].iov_base = (void *) _message->vectors[i].buffer; \ + _msg->msg_iov[i].iov_len = _message->vectors[i].size; \ + } \ + _msg->msg_iovlen = _message->num_vectors; \ + } \ + } \ + \ + /* control */ \ + { \ + struct cmsghdr *cmsg; \ + guint i; \ + \ + _msg->msg_controllen = 0; \ + for (i = 0; i < _message->num_control_messages; i++) \ + _msg->msg_controllen += CMSG_SPACE (g_socket_control_message_get_size (_message->control_messages[i])); \ + \ + if (_msg->msg_controllen == 0) \ + _msg->msg_control = NULL; \ + else \ + { \ + _msg->msg_control = g_alloca0 (_msg->msg_controllen); \ + } \ + \ + cmsg = CMSG_FIRSTHDR (_msg); \ + for (i = 0; i < _message->num_control_messages; i++) \ + { \ + cmsg->cmsg_level = g_socket_control_message_get_level (_message->control_messages[i]); \ + cmsg->cmsg_type = g_socket_control_message_get_msg_type (_message->control_messages[i]); \ + cmsg->cmsg_len = CMSG_LEN (g_socket_control_message_get_size (_message->control_messages[i])); \ + g_socket_control_message_serialize (_message->control_messages[i], \ + CMSG_DATA (cmsg)); \ + cmsg = CMSG_NXTHDR (_msg, cmsg); \ + } \ + g_assert (cmsg == NULL); \ + } \ +} G_STMT_END + +#define input_message_to_msghdr(message, msg) \ +G_STMT_START { \ + const GInputMessage *_message = (message); \ + struct msghdr *_msg = (msg); \ + \ + /* name */ \ + if (_message->address) \ + { \ + _msg->msg_namelen = sizeof (struct sockaddr_storage); \ + _msg->msg_name = g_alloca (_msg->msg_namelen); \ + } \ + else \ + { \ + _msg->msg_name = NULL; \ + _msg->msg_namelen = 0; \ + } \ + \ + /* iov */ \ + /* this entire expression will be evaluated at compile time */ \ + if (sizeof *_msg->msg_iov == sizeof *_message->vectors && \ + sizeof _msg->msg_iov->iov_base == sizeof _message->vectors->buffer && \ + G_STRUCT_OFFSET (struct iovec, iov_base) == \ + G_STRUCT_OFFSET (GInputVector, buffer) && \ + sizeof _msg->msg_iov->iov_len == sizeof _message->vectors->size && \ + G_STRUCT_OFFSET (struct iovec, iov_len) == \ + G_STRUCT_OFFSET (GInputVector, size)) \ + /* ABI is compatible */ \ + { \ + _msg->msg_iov = (struct iovec *) _message->vectors; \ + _msg->msg_iovlen = _message->num_vectors; \ + } \ + else \ + /* ABI is incompatible */ \ + { \ + guint i; \ + \ + _msg->msg_iov = g_newa (struct iovec, _message->num_vectors); \ + for (i = 0; i < _message->num_vectors; i++) \ + { \ + _msg->msg_iov[i].iov_base = _message->vectors[i].buffer; \ + _msg->msg_iov[i].iov_len = _message->vectors[i].size; \ + } \ + _msg->msg_iovlen = _message->num_vectors; \ + } \ + \ + /* control */ \ + if (_message->control_messages == NULL) \ + { \ + _msg->msg_controllen = 0; \ + _msg->msg_control = NULL; \ + } \ + else \ + { \ + _msg->msg_controllen = G_SOCKET_CONTROL_BUFFER_SIZE_BYTES; \ + _msg->msg_control = g_alloca (_msg->msg_controllen); \ + } \ + \ + /* flags */ \ + _msg->msg_flags = _message->flags; \ +} G_STMT_END + +static void +input_message_from_msghdr (const struct msghdr *msg, + GInputMessage *message, + GSocket *socket) +{ + /* decode address */ + if (message->address != NULL) + { + *message->address = cache_recv_address (socket, msg->msg_name, + msg->msg_namelen); + } + + /* decode control messages */ + { + GPtrArray *my_messages = NULL; + struct cmsghdr *cmsg; + + if (msg->msg_controllen >= sizeof (struct cmsghdr)) + { + g_assert (message->control_messages != NULL); + for (cmsg = CMSG_FIRSTHDR (msg); + cmsg != NULL; + cmsg = CMSG_NXTHDR ((struct msghdr *) msg, cmsg)) + { + GSocketControlMessage *control_message; + + control_message = g_socket_control_message_deserialize (cmsg->cmsg_level, + cmsg->cmsg_type, + cmsg->cmsg_len - ((char *)CMSG_DATA (cmsg) - (char *)cmsg), + CMSG_DATA (cmsg)); + if (control_message == NULL) + /* We've already spewed about the problem in the + deserialization code, so just continue */ + continue; + + if (my_messages == NULL) + my_messages = g_ptr_array_new (); + g_ptr_array_add (my_messages, control_message); + } + } + + if (message->num_control_messages) + *message->num_control_messages = my_messages != NULL ? my_messages->len : 0; + + if (message->control_messages) + { + if (my_messages == NULL) + { + *message->control_messages = NULL; + } + else + { + g_ptr_array_add (my_messages, NULL); + *message->control_messages = (GSocketControlMessage **) g_ptr_array_free (my_messages, FALSE); + } + } + else + { + g_assert (my_messages == NULL); + } + } + + /* capture the flags */ + message->flags = msg->msg_flags; +} +#endif + +/** + * g_socket_send_message: + * @socket: a #GSocket + * @address: (nullable): a #GSocketAddress, or %NULL + * @vectors: (array length=num_vectors): an array of #GOutputVector structs + * @num_vectors: the number of elements in @vectors, or -1 + * @messages: (array length=num_messages) (nullable): a pointer to an + * array of #GSocketControlMessages, or %NULL. + * @num_messages: number of elements in @messages, or -1. + * @flags: an int containing #GSocketMsgFlags flags, which may additionally + * contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html) + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Send data to @address on @socket. For sending multiple messages see + * g_socket_send_messages(); for easier use, see + * g_socket_send() and g_socket_send_to(). + * + * If @address is %NULL then the message is sent to the default receiver + * (set by g_socket_connect()). + * + * @vectors must point to an array of #GOutputVector structs and + * @num_vectors must be the length of this array. (If @num_vectors is -1, + * then @vectors is assumed to be terminated by a #GOutputVector with a + * %NULL buffer pointer.) The #GOutputVector structs describe the buffers + * that the sent data will be gathered from. Using multiple + * #GOutputVectors is more memory-efficient than manually copying + * data from multiple sources into a single buffer, and more + * network-efficient than making multiple calls to g_socket_send(). + * + * @messages, if non-%NULL, is taken to point to an array of @num_messages + * #GSocketControlMessage instances. These correspond to the control + * messages to be sent on the socket. + * If @num_messages is -1 then @messages is treated as a %NULL-terminated + * array. + * + * @flags modify how the message is sent. The commonly available arguments + * for this are available in the #GSocketMsgFlags enum, but the + * values there are the same as the system values, and the flags + * are passed in as-is, so you can pass in system-specific flags too. + * + * If the socket is in blocking mode the call will block until there is + * space for the data in the socket queue. If there is no space available + * and the socket is in non-blocking mode a %G_IO_ERROR_WOULD_BLOCK error + * will be returned. To be notified when space is available, wait for the + * %G_IO_OUT condition. Note though that you may still receive + * %G_IO_ERROR_WOULD_BLOCK from g_socket_send() even if you were previously + * notified of a %G_IO_OUT condition. (On Windows in particular, this is + * very common due to the way the underlying APIs work.) + * + * The sum of the sizes of each #GOutputVector in vectors must not be + * greater than %G_MAXSSIZE. If the message can be larger than this, + * then it is mandatory to use the g_socket_send_message_with_timeout() + * function. + * + * On error -1 is returned and @error is set accordingly. + * + * Returns: Number of bytes written (which may be less than @size), or -1 + * on error + * + * Since: 2.22 + */ +gssize +g_socket_send_message (GSocket *socket, + GSocketAddress *address, + GOutputVector *vectors, + gint num_vectors, + GSocketControlMessage **messages, + gint num_messages, + gint flags, + GCancellable *cancellable, + GError **error) +{ + GPollableReturn res; + gsize bytes_written = 0; + gsize vectors_size = 0; + + if (num_vectors != -1) + { + for (gint i = 0; i < num_vectors; i++) + { + /* No wrap-around for vectors_size */ + if (vectors_size > vectors_size + vectors[i].size) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Unable to send message: %s"), + _("Message vectors too large")); + return -1; + } + + vectors_size += vectors[i].size; + } + } + else + { + for (gsize i = 0; vectors[i].buffer != NULL; i++) + { + /* No wrap-around for vectors_size */ + if (vectors_size > vectors_size + vectors[i].size) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Unable to send message: %s"), + _("Message vectors too large")); + return -1; + } + + vectors_size += vectors[i].size; + } + } + + /* Check if vector's buffers are too big for gssize */ + if (vectors_size > G_MAXSSIZE) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Unable to send message: %s"), + _("Message vectors too large")); + return -1; + } + + res = g_socket_send_message_with_timeout (socket, address, + vectors, num_vectors, + messages, num_messages, flags, + socket->priv->blocking ? -1 : 0, + &bytes_written, + cancellable, error); + + g_assert (res != G_POLLABLE_RETURN_OK || bytes_written <= G_MAXSSIZE); + + if (res == G_POLLABLE_RETURN_WOULD_BLOCK) + { +#ifndef G_OS_WIN32 + socket_set_error_lazy (error, EWOULDBLOCK, _("Error sending message: %s")); +#else + socket_set_error_lazy (error, WSAEWOULDBLOCK, _("Error sending message: %s")); +#endif + } + + return res == G_POLLABLE_RETURN_OK ? (gssize) bytes_written : -1; +} + +/** + * g_socket_send_message_with_timeout: + * @socket: a #GSocket + * @address: (nullable): a #GSocketAddress, or %NULL + * @vectors: (array length=num_vectors): an array of #GOutputVector structs + * @num_vectors: the number of elements in @vectors, or -1 + * @messages: (array length=num_messages) (nullable): a pointer to an + * array of #GSocketControlMessages, or %NULL. + * @num_messages: number of elements in @messages, or -1. + * @flags: an int containing #GSocketMsgFlags flags, which may additionally + * contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html) + * @timeout_us: the maximum time (in microseconds) to wait, or -1 + * @bytes_written: (out) (optional): location to store the number of bytes that were written to the socket + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * This behaves exactly the same as g_socket_send_message(), except that + * the choice of timeout behavior is determined by the @timeout_us argument + * rather than by @socket's properties. + * + * On error %G_POLLABLE_RETURN_FAILED is returned and @error is set accordingly, or + * if the socket is currently not writable %G_POLLABLE_RETURN_WOULD_BLOCK is + * returned. @bytes_written will contain 0 in both cases. + * + * Returns: %G_POLLABLE_RETURN_OK if all data was successfully written, + * %G_POLLABLE_RETURN_WOULD_BLOCK if the socket is currently not writable, or + * %G_POLLABLE_RETURN_FAILED if an error happened and @error is set. + * + * Since: 2.60 + */ +GPollableReturn +g_socket_send_message_with_timeout (GSocket *socket, + GSocketAddress *address, + const GOutputVector *vectors, + gint num_vectors, + GSocketControlMessage **messages, + gint num_messages, + gint flags, + gint64 timeout_us, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + GOutputVector one_vector; + char zero; + gint64 start_time; + + if (bytes_written) + *bytes_written = 0; + + g_return_val_if_fail (G_IS_SOCKET (socket), G_POLLABLE_RETURN_FAILED); + g_return_val_if_fail (address == NULL || G_IS_SOCKET_ADDRESS (address), G_POLLABLE_RETURN_FAILED); + g_return_val_if_fail (num_vectors == 0 || vectors != NULL, G_POLLABLE_RETURN_FAILED); + g_return_val_if_fail (num_messages == 0 || messages != NULL, G_POLLABLE_RETURN_FAILED); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_POLLABLE_RETURN_FAILED); + g_return_val_if_fail (error == NULL || *error == NULL, G_POLLABLE_RETURN_FAILED); + + start_time = g_get_monotonic_time (); + + if (!check_socket (socket, error)) + return G_POLLABLE_RETURN_FAILED; + + if (!check_timeout (socket, error)) + return G_POLLABLE_RETURN_FAILED; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return G_POLLABLE_RETURN_FAILED; + + if (num_vectors == -1) + { + for (num_vectors = 0; + vectors[num_vectors].buffer != NULL; + num_vectors++) + ; + } + + if (num_messages == -1) + { + for (num_messages = 0; + messages != NULL && messages[num_messages] != NULL; + num_messages++) + ; + } + + if (num_vectors == 0) + { + zero = '\0'; + + one_vector.buffer = &zero; + one_vector.size = 1; + num_vectors = 1; + vectors = &one_vector; + } + +#ifndef G_OS_WIN32 + { + GOutputMessage output_message; + struct msghdr msg; + gssize result; + GError *child_error = NULL; + + output_message.address = address; + output_message.vectors = (GOutputVector *) vectors; + output_message.num_vectors = num_vectors; + output_message.bytes_sent = 0; + output_message.control_messages = messages; + output_message.num_control_messages = num_messages; + + output_message_to_msghdr (&output_message, NULL, &msg, NULL, &child_error); + + if (child_error != NULL) + { + g_propagate_error (error, child_error); + return G_POLLABLE_RETURN_FAILED; + } + + while (1) + { + result = sendmsg (socket->priv->fd, &msg, flags | G_SOCKET_DEFAULT_SEND_FLAGS); + if (result < 0) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + + if (errsv == EWOULDBLOCK || errsv == EAGAIN) + { + if (timeout_us != 0) + { + if (!block_on_timeout (socket, G_IO_OUT, timeout_us, start_time, + cancellable, error)) + return G_POLLABLE_RETURN_FAILED; + + continue; + } + + return G_POLLABLE_RETURN_WOULD_BLOCK; + } + + socket_set_error_lazy (error, errsv, _("Error sending message: %s")); + return G_POLLABLE_RETURN_FAILED; + } + break; + } + + if (bytes_written) + *bytes_written = result; + + return G_POLLABLE_RETURN_OK; + } +#else + { + struct sockaddr_storage addr; + guint addrlen; + DWORD bytes_sent; + int result; + WSABUF *bufs; + gint i; + + /* Win32 doesn't support control messages. + Actually this is possible for raw and datagram sockets + via WSASendMessage on Vista or later, but that doesn't + seem very useful */ + if (num_messages != 0) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("GSocketControlMessage not supported on Windows")); + return G_POLLABLE_RETURN_FAILED; + } + + /* iov */ + bufs = g_newa (WSABUF, num_vectors); + for (i = 0; i < num_vectors; i++) + { + bufs[i].buf = (char *)vectors[i].buffer; + bufs[i].len = (gulong)vectors[i].size; + } + + /* name */ + addrlen = 0; /* Avoid warning */ + if (address) + { + addrlen = g_socket_address_get_native_size (address); + if (!g_socket_address_to_native (address, &addr, sizeof addr, error)) + return G_POLLABLE_RETURN_FAILED; + } + + while (1) + { + if (address) + result = WSASendTo (socket->priv->fd, + bufs, num_vectors, + &bytes_sent, flags, + (const struct sockaddr *)&addr, addrlen, + NULL, NULL); + else + result = WSASend (socket->priv->fd, + bufs, num_vectors, + &bytes_sent, flags, + NULL, NULL); + + if (result != 0) + { + int errsv = get_socket_errno (); + + if (errsv == WSAEINTR) + continue; + + if (errsv == WSAEWOULDBLOCK) + { + win32_unset_event_mask (socket, FD_WRITE); + + if (timeout_us != 0) + { + if (!block_on_timeout (socket, G_IO_OUT, timeout_us, + start_time, cancellable, error)) + return G_POLLABLE_RETURN_FAILED; + + continue; + } + + return G_POLLABLE_RETURN_WOULD_BLOCK; + } + + socket_set_error_lazy (error, errsv, _("Error sending message: %s")); + return G_POLLABLE_RETURN_FAILED; + } + break; + } + + if (bytes_written) + *bytes_written = bytes_sent; + return G_POLLABLE_RETURN_OK; + } +#endif +} + +/** + * g_socket_send_messages: + * @socket: a #GSocket + * @messages: (array length=num_messages): an array of #GOutputMessage structs + * @num_messages: the number of elements in @messages + * @flags: an int containing #GSocketMsgFlags flags, which may additionally + * contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html) + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Send multiple data messages from @socket in one go. This is the most + * complicated and fully-featured version of this call. For easier use, see + * g_socket_send(), g_socket_send_to(), and g_socket_send_message(). + * + * @messages must point to an array of #GOutputMessage structs and + * @num_messages must be the length of this array. Each #GOutputMessage + * contains an address to send the data to, and a pointer to an array of + * #GOutputVector structs to describe the buffers that the data to be sent + * for each message will be gathered from. Using multiple #GOutputVectors is + * more memory-efficient than manually copying data from multiple sources + * into a single buffer, and more network-efficient than making multiple + * calls to g_socket_send(). Sending multiple messages in one go avoids the + * overhead of making a lot of syscalls in scenarios where a lot of data + * packets need to be sent (e.g. high-bandwidth video streaming over RTP/UDP), + * or where the same data needs to be sent to multiple recipients. + * + * @flags modify how the message is sent. The commonly available arguments + * for this are available in the #GSocketMsgFlags enum, but the + * values there are the same as the system values, and the flags + * are passed in as-is, so you can pass in system-specific flags too. + * + * If the socket is in blocking mode the call will block until there is + * space for all the data in the socket queue. If there is no space available + * and the socket is in non-blocking mode a %G_IO_ERROR_WOULD_BLOCK error + * will be returned if no data was written at all, otherwise the number of + * messages sent will be returned. To be notified when space is available, + * wait for the %G_IO_OUT condition. Note though that you may still receive + * %G_IO_ERROR_WOULD_BLOCK from g_socket_send() even if you were previously + * notified of a %G_IO_OUT condition. (On Windows in particular, this is + * very common due to the way the underlying APIs work.) + * + * On error -1 is returned and @error is set accordingly. An error will only + * be returned if zero messages could be sent; otherwise the number of messages + * successfully sent before the error will be returned. + * + * Returns: number of messages sent, or -1 on error. Note that the number of + * messages sent may be smaller than @num_messages if the socket is + * non-blocking or if @num_messages was larger than UIO_MAXIOV (1024), + * in which case the caller may re-try to send the remaining messages. + * + * Since: 2.44 + */ +gint +g_socket_send_messages (GSocket *socket, + GOutputMessage *messages, + guint num_messages, + gint flags, + GCancellable *cancellable, + GError **error) +{ + return g_socket_send_messages_with_timeout (socket, messages, num_messages, + flags, + socket->priv->blocking ? -1 : 0, + cancellable, error); +} + +static gint +g_socket_send_messages_with_timeout (GSocket *socket, + GOutputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + gint64 start_time; + + g_return_val_if_fail (G_IS_SOCKET (socket), -1); + g_return_val_if_fail (num_messages == 0 || messages != NULL, -1); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + start_time = g_get_monotonic_time (); + + if (!check_socket (socket, error)) + return -1; + + if (!check_timeout (socket, error)) + return -1; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (num_messages == 0) + return 0; + +#if !defined (G_OS_WIN32) && defined (HAVE_SENDMMSG) + { + struct mmsghdr *msgvec; + guint i, num_sent; + + /* Clamp the number of vectors if more given than we can write in one go. + * The caller has to handle short writes anyway. + */ + if (num_messages > G_IOV_MAX) + num_messages = G_IOV_MAX; + + msgvec = g_newa (struct mmsghdr, num_messages); + + for (i = 0; i < num_messages; ++i) + { + GOutputMessage *msg = &messages[i]; + struct msghdr *msg_hdr = &msgvec[i].msg_hdr; + GError *child_error = NULL; + + msgvec[i].msg_len = 0; + + output_message_to_msghdr (msg, (i > 0) ? &messages[i - 1] : NULL, + msg_hdr, (i > 0) ? &msgvec[i - 1].msg_hdr : NULL, + &child_error); + + if (child_error != NULL) + { + g_propagate_error (error, child_error); + return -1; + } + } + + for (num_sent = 0; num_sent < num_messages;) + { + gint ret; + + ret = sendmmsg (socket->priv->fd, msgvec + num_sent, num_messages - num_sent, + flags | G_SOCKET_DEFAULT_SEND_FLAGS); + + if (ret < 0) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + + if (timeout_us != 0 && + (errsv == EWOULDBLOCK || + errsv == EAGAIN)) + { + if (!block_on_timeout (socket, G_IO_OUT, timeout_us, start_time, + cancellable, error)) + { + if (num_sent > 0) + { + g_clear_error (error); + break; + } + + return -1; + } + + continue; + } + + /* If any messages were successfully sent, do not error. */ + if (num_sent > 0) + break; + + socket_set_error_lazy (error, errsv, _("Error sending message: %s")); + + return -1; + } + + num_sent += ret; + } + + for (i = 0; i < num_sent; ++i) + messages[i].bytes_sent = msgvec[i].msg_len; + + return num_sent; + } +#else + { + gssize result; + guint i; + gint64 wait_timeout; + + wait_timeout = timeout_us; + + for (i = 0; i < num_messages; ++i) + { + GOutputMessage *msg = &messages[i]; + GError *msg_error = NULL; + GPollableReturn pollable_result; + gsize bytes_written = 0; + + pollable_result = g_socket_send_message_with_timeout (socket, msg->address, + msg->vectors, + msg->num_vectors, + msg->control_messages, + msg->num_control_messages, + flags, wait_timeout, + &bytes_written, + cancellable, &msg_error); + + if (pollable_result == G_POLLABLE_RETURN_WOULD_BLOCK) + { +#ifndef G_OS_WIN32 + socket_set_error_lazy (&msg_error, EWOULDBLOCK, _("Error sending message: %s")); +#else + socket_set_error_lazy (&msg_error, WSAEWOULDBLOCK, _("Error sending message: %s")); +#endif + } + + if (G_MAXSSIZE > bytes_written && + pollable_result == G_POLLABLE_RETURN_OK) + result = (gssize) bytes_written; + else + result = -1; + + /* check if we've timed out or how much time to wait at most */ + if (timeout_us > 0) + { + gint64 elapsed = g_get_monotonic_time () - start_time; + wait_timeout = MAX (timeout_us - elapsed, 1); + } + + if (result < 0) + { + /* if we couldn't send all messages, just return how many we did + * manage to send, provided we managed to send at least one */ + if (i > 0) + { + g_error_free (msg_error); + return i; + } + else + { + g_propagate_error (error, msg_error); + return -1; + } + } + + msg->bytes_sent = result; + } + + return i; + } +#endif +} + +static GSocketAddress * +cache_recv_address (GSocket *socket, struct sockaddr *native, size_t native_len) +{ + GSocketAddress *saddr; + gint i; + guint64 oldest_time = G_MAXUINT64; + gint oldest_index = 0; + + if (native_len == 0) + return NULL; + + saddr = NULL; + for (i = 0; i < RECV_ADDR_CACHE_SIZE; i++) + { + GSocketAddress *tmp = socket->priv->recv_addr_cache[i].addr; + gpointer tmp_native = socket->priv->recv_addr_cache[i].native; + gsize tmp_native_len = socket->priv->recv_addr_cache[i].native_len; + + if (!tmp) + continue; + + if (tmp_native_len != native_len) + continue; + + if (memcmp (tmp_native, native, native_len) == 0) + { + saddr = g_object_ref (tmp); + socket->priv->recv_addr_cache[i].last_used = g_get_monotonic_time (); + return saddr; + } + + if (socket->priv->recv_addr_cache[i].last_used < oldest_time) + { + oldest_time = socket->priv->recv_addr_cache[i].last_used; + oldest_index = i; + } + } + + saddr = g_socket_address_new_from_native (native, native_len); + + if (socket->priv->recv_addr_cache[oldest_index].addr) + { + g_object_unref (socket->priv->recv_addr_cache[oldest_index].addr); + g_free (socket->priv->recv_addr_cache[oldest_index].native); + } + + socket->priv->recv_addr_cache[oldest_index].native = g_memdup2 (native, native_len); + socket->priv->recv_addr_cache[oldest_index].native_len = native_len; + socket->priv->recv_addr_cache[oldest_index].addr = g_object_ref (saddr); + socket->priv->recv_addr_cache[oldest_index].last_used = g_get_monotonic_time (); + + return saddr; +} + +static gssize +g_socket_receive_message_with_timeout (GSocket *socket, + GSocketAddress **address, + GInputVector *vectors, + gint num_vectors, + GSocketControlMessage ***messages, + gint *num_messages, + gint *flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + GInputVector one_vector; + char one_byte; + gint64 start_time; + + g_return_val_if_fail (G_IS_SOCKET (socket), -1); + + start_time = g_get_monotonic_time (); + + if (!check_socket (socket, error)) + return -1; + + if (!check_timeout (socket, error)) + return -1; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (num_vectors == -1) + { + for (num_vectors = 0; + vectors[num_vectors].buffer != NULL; + num_vectors++) + ; + } + + if (num_vectors == 0) + { + one_vector.buffer = &one_byte; + one_vector.size = 1; + num_vectors = 1; + vectors = &one_vector; + } + +#ifndef G_OS_WIN32 + { + GInputMessage input_message; + struct msghdr msg; + gssize result; + + input_message.address = address; + input_message.vectors = vectors; + input_message.num_vectors = num_vectors; + input_message.bytes_received = 0; + input_message.flags = (flags != NULL) ? *flags : 0; + input_message.control_messages = messages; + input_message.num_control_messages = (guint *) num_messages; + + /* We always set the close-on-exec flag so we don't leak file + * descriptors into child processes. Note that gunixfdmessage.c + * will later call fcntl (fd, FD_CLOEXEC), but that isn't atomic. + */ +#ifdef MSG_CMSG_CLOEXEC + input_message.flags |= MSG_CMSG_CLOEXEC; +#endif + + input_message_to_msghdr (&input_message, &msg); + + /* do it */ + while (1) + { + result = recvmsg (socket->priv->fd, &msg, msg.msg_flags); +#ifdef MSG_CMSG_CLOEXEC + if (result < 0 && get_socket_errno () == EINVAL) + { + /* We must be running on an old kernel. Call without the flag. */ + msg.msg_flags &= ~(MSG_CMSG_CLOEXEC); + result = recvmsg (socket->priv->fd, &msg, msg.msg_flags); + } +#endif + + if (result < 0) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + + if (timeout_us != 0 && + (errsv == EWOULDBLOCK || + errsv == EAGAIN)) + { + if (!block_on_timeout (socket, G_IO_IN, timeout_us, start_time, + cancellable, error)) + return -1; + + continue; + } + + socket_set_error_lazy (error, errsv, _("Error receiving message: %s")); + return -1; + } + break; + } + + input_message_from_msghdr (&msg, &input_message, socket); + + if (flags != NULL) + *flags = input_message.flags; + + return result; + } +#else + { + struct sockaddr_storage addr; + int addrlen; + DWORD bytes_received; + DWORD win_flags; + int result; + WSABUF *bufs; + gint i; + + /* iov */ + bufs = g_newa (WSABUF, num_vectors); + for (i = 0; i < num_vectors; i++) + { + bufs[i].buf = (char *)vectors[i].buffer; + bufs[i].len = (gulong)vectors[i].size; + } + + /* flags */ + if (flags != NULL) + win_flags = *flags; + else + win_flags = 0; + + /* do it */ + while (1) + { + /* addrlen has to be of type int because that’s how WSARecvFrom() is defined */ + G_STATIC_ASSERT (sizeof addr <= G_MAXINT); + + addrlen = sizeof addr; + if (address) + result = WSARecvFrom (socket->priv->fd, + bufs, num_vectors, + &bytes_received, &win_flags, + (struct sockaddr *)&addr, &addrlen, + NULL, NULL); + else + result = WSARecv (socket->priv->fd, + bufs, num_vectors, + &bytes_received, &win_flags, + NULL, NULL); + if (result != 0) + { + int errsv = get_socket_errno (); + + if (errsv == WSAEINTR) + continue; + + win32_unset_event_mask (socket, FD_READ); + + if (errsv == WSAEWOULDBLOCK) + { + if (timeout_us != 0) + { + if (!block_on_timeout (socket, G_IO_IN, timeout_us, + start_time, cancellable, error)) + return -1; + + continue; + } + } + + socket_set_error_lazy (error, errsv, _("Error receiving message: %s")); + return -1; + } + win32_unset_event_mask (socket, FD_READ); + break; + } + + /* decode address */ + if (address != NULL) + { + *address = cache_recv_address (socket, (struct sockaddr *)&addr, addrlen); + } + + /* capture the flags */ + if (flags != NULL) + *flags = win_flags; + + if (messages != NULL) + *messages = NULL; + if (num_messages != NULL) + *num_messages = 0; + + return bytes_received; + } +#endif +} + +/** + * g_socket_receive_messages: + * @socket: a #GSocket + * @messages: (array length=num_messages): an array of #GInputMessage structs + * @num_messages: the number of elements in @messages + * @flags: an int containing #GSocketMsgFlags flags for the overall operation, + * which may additionally contain + * [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html) + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore + * + * Receive multiple data messages from @socket in one go. This is the most + * complicated and fully-featured version of this call. For easier use, see + * g_socket_receive(), g_socket_receive_from(), and g_socket_receive_message(). + * + * @messages must point to an array of #GInputMessage structs and + * @num_messages must be the length of this array. Each #GInputMessage + * contains a pointer to an array of #GInputVector structs describing the + * buffers that the data received in each message will be written to. Using + * multiple #GInputVectors is more memory-efficient than manually copying data + * out of a single buffer to multiple sources, and more system-call-efficient + * than making multiple calls to g_socket_receive(), such as in scenarios where + * a lot of data packets need to be received (e.g. high-bandwidth video + * streaming over RTP/UDP). + * + * @flags modify how all messages are received. The commonly available + * arguments for this are available in the #GSocketMsgFlags enum, but the + * values there are the same as the system values, and the flags + * are passed in as-is, so you can pass in system-specific flags too. These + * flags affect the overall receive operation. Flags affecting individual + * messages are returned in #GInputMessage.flags. + * + * The other members of #GInputMessage are treated as described in its + * documentation. + * + * If #GSocket:blocking is %TRUE the call will block until @num_messages have + * been received, or the end of the stream is reached. + * + * If #GSocket:blocking is %FALSE the call will return up to @num_messages + * without blocking, or %G_IO_ERROR_WOULD_BLOCK if no messages are queued in the + * operating system to be received. + * + * In blocking mode, if #GSocket:timeout is positive and is reached before any + * messages are received, %G_IO_ERROR_TIMED_OUT is returned, otherwise up to + * @num_messages are returned. (Note: This is effectively the + * behaviour of `MSG_WAITFORONE` with recvmmsg().) + * + * To be notified when messages are available, wait for the + * %G_IO_IN condition. Note though that you may still receive + * %G_IO_ERROR_WOULD_BLOCK from g_socket_receive_messages() even if you were + * previously notified of a %G_IO_IN condition. + * + * If the remote peer closes the connection, any messages queued in the + * operating system will be returned, and subsequent calls to + * g_socket_receive_messages() will return 0 (with no error set). + * + * On error -1 is returned and @error is set accordingly. An error will only + * be returned if zero messages could be received; otherwise the number of + * messages successfully received before the error will be returned. + * + * Returns: number of messages received, or -1 on error. Note that the number + * of messages received may be smaller than @num_messages if in non-blocking + * mode, if the peer closed the connection, or if @num_messages + * was larger than `UIO_MAXIOV` (1024), in which case the caller may re-try + * to receive the remaining messages. + * + * Since: 2.48 + */ +gint +g_socket_receive_messages (GSocket *socket, + GInputMessage *messages, + guint num_messages, + gint flags, + GCancellable *cancellable, + GError **error) +{ + if (!check_socket (socket, error) || + !check_timeout (socket, error)) + return -1; + + return g_socket_receive_messages_with_timeout (socket, messages, num_messages, + flags, + socket->priv->blocking ? -1 : 0, + cancellable, error); +} + +static gint +g_socket_receive_messages_with_timeout (GSocket *socket, + GInputMessage *messages, + guint num_messages, + gint flags, + gint64 timeout_us, + GCancellable *cancellable, + GError **error) +{ + gint64 start_time; + + g_return_val_if_fail (G_IS_SOCKET (socket), -1); + g_return_val_if_fail (num_messages == 0 || messages != NULL, -1); + g_return_val_if_fail (cancellable == NULL || + G_IS_CANCELLABLE (cancellable), -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + start_time = g_get_monotonic_time (); + + if (!check_socket (socket, error)) + return -1; + + if (!check_timeout (socket, error)) + return -1; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (num_messages == 0) + return 0; + +#if !defined (G_OS_WIN32) && defined (HAVE_RECVMMSG) + { + struct mmsghdr *msgvec; + guint i, num_received; + + /* Clamp the number of vectors if more given than we can write in one go. + * The caller has to handle short writes anyway. + */ + if (num_messages > G_IOV_MAX) + num_messages = G_IOV_MAX; + + msgvec = g_newa (struct mmsghdr, num_messages); + + for (i = 0; i < num_messages; ++i) + { + GInputMessage *msg = &messages[i]; + struct msghdr *msg_hdr = &msgvec[i].msg_hdr; + + input_message_to_msghdr (msg, msg_hdr); + msgvec[i].msg_len = 0; + } + + /* We always set the close-on-exec flag so we don't leak file + * descriptors into child processes. Note that gunixfdmessage.c + * will later call fcntl (fd, FD_CLOEXEC), but that isn't atomic. + */ +#ifdef MSG_CMSG_CLOEXEC + flags |= MSG_CMSG_CLOEXEC; +#endif + + for (num_received = 0; num_received < num_messages;) + { + gint ret; + + /* We operate in non-blocking mode and handle the timeout ourselves. */ + ret = recvmmsg (socket->priv->fd, + msgvec + num_received, + num_messages - num_received, + flags | G_SOCKET_DEFAULT_SEND_FLAGS, NULL); +#ifdef MSG_CMSG_CLOEXEC + if (ret < 0 && get_socket_errno () == EINVAL) + { + /* We must be running on an old kernel. Call without the flag. */ + flags &= ~(MSG_CMSG_CLOEXEC); + ret = recvmmsg (socket->priv->fd, + msgvec + num_received, + num_messages - num_received, + flags | G_SOCKET_DEFAULT_SEND_FLAGS, NULL); + } +#endif + + if (ret < 0) + { + int errsv = get_socket_errno (); + + if (errsv == EINTR) + continue; + + if (timeout_us != 0 && + (errsv == EWOULDBLOCK || + errsv == EAGAIN)) + { + if (!block_on_timeout (socket, G_IO_IN, timeout_us, start_time, + cancellable, error)) + { + if (num_received > 0) + { + g_clear_error (error); + break; + } + + return -1; + } + + continue; + } + + /* If any messages were successfully received, do not error. */ + if (num_received > 0) + break; + + socket_set_error_lazy (error, errsv, + _("Error receiving message: %s")); + + return -1; + } + else if (ret == 0) + { + /* EOS. */ + break; + } + + num_received += ret; + } + + for (i = 0; i < num_received; ++i) + { + input_message_from_msghdr (&msgvec[i].msg_hdr, &messages[i], socket); + messages[i].bytes_received = msgvec[i].msg_len; + } + + return num_received; + } +#else + { + guint i; + gint64 wait_timeout; + + wait_timeout = timeout_us; + + for (i = 0; i < num_messages; i++) + { + GInputMessage *msg = &messages[i]; + gssize len; + GError *msg_error = NULL; + + msg->flags = flags; /* in-out parameter */ + + len = g_socket_receive_message_with_timeout (socket, + msg->address, + msg->vectors, + msg->num_vectors, + msg->control_messages, + (gint *) msg->num_control_messages, + &msg->flags, + wait_timeout, + cancellable, + &msg_error); + + /* check if we've timed out or how much time to wait at most */ + if (timeout_us > 0) + { + gint64 elapsed = g_get_monotonic_time () - start_time; + wait_timeout = MAX (timeout_us - elapsed, 1); + } + + if (len >= 0) + msg->bytes_received = len; + + if (i != 0 && + (g_error_matches (msg_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) || + g_error_matches (msg_error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT))) + { + g_clear_error (&msg_error); + break; + } + + if (msg_error != NULL) + { + g_propagate_error (error, msg_error); + return -1; + } + + if (len == 0) + break; + } + + return i; + } +#endif +} + +/** + * g_socket_receive_message: + * @socket: a #GSocket + * @address: (out) (optional): a pointer to a #GSocketAddress + * pointer, or %NULL + * @vectors: (array length=num_vectors): an array of #GInputVector structs + * @num_vectors: the number of elements in @vectors, or -1 + * @messages: (array length=num_messages) (out) (optional) (nullable): a pointer + * which may be filled with an array of #GSocketControlMessages, or %NULL + * @num_messages: (out): a pointer which will be filled with the number of + * elements in @messages, or %NULL + * @flags: (inout): a pointer to an int containing #GSocketMsgFlags flags, + * which may additionally contain + * [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html) + * @cancellable: a %GCancellable or %NULL + * @error: a #GError pointer, or %NULL + * + * Receive data from a socket. For receiving multiple messages, see + * g_socket_receive_messages(); for easier use, see + * g_socket_receive() and g_socket_receive_from(). + * + * If @address is non-%NULL then @address will be set equal to the + * source address of the received packet. + * @address is owned by the caller. + * + * @vector must point to an array of #GInputVector structs and + * @num_vectors must be the length of this array. These structs + * describe the buffers that received data will be scattered into. + * If @num_vectors is -1, then @vectors is assumed to be terminated + * by a #GInputVector with a %NULL buffer pointer. + * + * As a special case, if @num_vectors is 0 (in which case, @vectors + * may of course be %NULL), then a single byte is received and + * discarded. This is to facilitate the common practice of sending a + * single '\0' byte for the purposes of transferring ancillary data. + * + * @messages, if non-%NULL, will be set to point to a newly-allocated + * array of #GSocketControlMessage instances or %NULL if no such + * messages was received. These correspond to the control messages + * received from the kernel, one #GSocketControlMessage per message + * from the kernel. This array is %NULL-terminated and must be freed + * by the caller using g_free() after calling g_object_unref() on each + * element. If @messages is %NULL, any control messages received will + * be discarded. + * + * @num_messages, if non-%NULL, will be set to the number of control + * messages received. + * + * If both @messages and @num_messages are non-%NULL, then + * @num_messages gives the number of #GSocketControlMessage instances + * in @messages (ie: not including the %NULL terminator). + * + * @flags is an in/out parameter. The commonly available arguments + * for this are available in the #GSocketMsgFlags enum, but the + * values there are the same as the system values, and the flags + * are passed in as-is, so you can pass in system-specific flags too + * (and g_socket_receive_message() may pass system-specific flags out). + * Flags passed in to the parameter affect the receive operation; flags returned + * out of it are relevant to the specific returned message. + * + * As with g_socket_receive(), data may be discarded if @socket is + * %G_SOCKET_TYPE_DATAGRAM or %G_SOCKET_TYPE_SEQPACKET and you do not + * provide enough buffer space to read a complete message. You can pass + * %G_SOCKET_MSG_PEEK in @flags to peek at the current message without + * removing it from the receive queue, but there is no portable way to find + * out the length of the message other than by reading it into a + * sufficiently-large buffer. + * + * If the socket is in blocking mode the call will block until there + * is some data to receive, the connection is closed, or there is an + * error. If there is no data available and the socket is in + * non-blocking mode, a %G_IO_ERROR_WOULD_BLOCK error will be + * returned. To be notified when data is available, wait for the + * %G_IO_IN condition. + * + * On error -1 is returned and @error is set accordingly. + * + * Returns: Number of bytes read, or 0 if the connection was closed by + * the peer, or -1 on error + * + * Since: 2.22 + */ +gssize +g_socket_receive_message (GSocket *socket, + GSocketAddress **address, + GInputVector *vectors, + gint num_vectors, + GSocketControlMessage ***messages, + gint *num_messages, + gint *flags, + GCancellable *cancellable, + GError **error) +{ + return g_socket_receive_message_with_timeout (socket, address, vectors, + num_vectors, messages, + num_messages, flags, + socket->priv->blocking ? -1 : 0, + cancellable, error); +} + +/** + * g_socket_get_credentials: + * @socket: a #GSocket. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Returns the credentials of the foreign process connected to this + * socket, if any (e.g. it is only supported for %G_SOCKET_FAMILY_UNIX + * sockets). + * + * If this operation isn't supported on the OS, the method fails with + * the %G_IO_ERROR_NOT_SUPPORTED error. On Linux this is implemented + * by reading the %SO_PEERCRED option on the underlying socket. + * + * This method can be expected to be available on the following platforms: + * + * - Linux since GLib 2.26 + * - OpenBSD since GLib 2.30 + * - Solaris, Illumos and OpenSolaris since GLib 2.40 + * - NetBSD since GLib 2.42 + * - macOS, tvOS, iOS since GLib 2.66 + * + * Other ways to obtain credentials from a foreign peer includes the + * #GUnixCredentialsMessage type and + * g_unix_connection_send_credentials() / + * g_unix_connection_receive_credentials() functions. + * + * Returns: (transfer full): %NULL if @error is set, otherwise a #GCredentials object + * that must be freed with g_object_unref(). + * + * Since: 2.26 + */ +GCredentials * +g_socket_get_credentials (GSocket *socket, + GError **error) +{ + GCredentials *ret; + + g_return_val_if_fail (G_IS_SOCKET (socket), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (!check_socket (socket, error)) + return NULL; + + ret = NULL; + +#if G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED + +#ifdef SO_PEERCRED + { + guint8 native_creds_buf[G_CREDENTIALS_NATIVE_SIZE]; + socklen_t optlen = sizeof (native_creds_buf); + + if (getsockopt (socket->priv->fd, + SOL_SOCKET, + SO_PEERCRED, + native_creds_buf, + &optlen) == 0) + { + ret = g_credentials_new (); + g_credentials_set_native (ret, + G_CREDENTIALS_NATIVE_TYPE, + native_creds_buf); + } + } +#elif G_CREDENTIALS_USE_APPLE_XUCRED + { + struct xucred cred; + socklen_t optlen = sizeof (cred); + + if (getsockopt (socket->priv->fd, + SOL_LOCAL, + LOCAL_PEERCRED, + &cred, + &optlen) == 0 + && optlen != 0) + { + if (cred.cr_version == XUCRED_VERSION) + { + pid_t pid; + socklen_t optlen = sizeof (pid); + + ret = g_credentials_new (); + g_credentials_set_native (ret, + G_CREDENTIALS_NATIVE_TYPE, + &cred); + +#ifdef LOCAL_PEERPID + if (getsockopt (socket->priv->fd, + SOL_LOCAL, + LOCAL_PEERPID, + &pid, + &optlen) == 0) + _g_credentials_set_local_peerid (ret, pid); +#endif + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + /* No point in translating this! */ + "struct xucred cr_version %u != %u", + cred.cr_version, XUCRED_VERSION); + /* Reuse a translatable string we already have */ + g_prefix_error (error, + _("Unable to read socket credentials: %s"), + ""); + + return NULL; + } + } + else if (optlen == 0 || errno == EINVAL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Unable to read socket credentials: %s"), + "unsupported socket type"); + return NULL; + } + } +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + { + struct unpcbid cred; + socklen_t optlen = sizeof (cred); + + if (getsockopt (socket->priv->fd, + 0, + LOCAL_PEEREID, + &cred, + &optlen) == 0) + { + ret = g_credentials_new (); + g_credentials_set_native (ret, + G_CREDENTIALS_NATIVE_TYPE, + &cred); + } + } +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + { + ucred_t *ucred = NULL; + + if (getpeerucred (socket->priv->fd, &ucred) == 0) + { + ret = g_credentials_new (); + g_credentials_set_native (ret, + G_CREDENTIALS_TYPE_SOLARIS_UCRED, + ucred); + ucred_free (ucred); + } + } +#elif G_CREDENTIALS_USE_WIN32_PID + { + DWORD peerid, drc; + + if (WSAIoctl (socket->priv->fd, SIO_AF_UNIX_GETPEERPID, + NULL, 0U, + &peerid, sizeof(peerid), + /* Windows bug: always 0 https://github.com/microsoft/WSL/issues/4676 */ + &drc, + NULL, NULL) == 0) + { + ret = g_credentials_new (); + g_credentials_set_native (ret, + G_CREDENTIALS_TYPE_WIN32_PID, + &peerid); + } + } +#else + #error "G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED is set but this is no code for this platform" +#endif + + if (!ret) + { + int errsv = get_socket_errno (); + + g_set_error (error, + G_IO_ERROR, + socket_io_error_from_errno (errsv), + _("Unable to read socket credentials: %s"), + socket_strerror (errsv)); + } + +#else + + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("g_socket_get_credentials not implemented for this OS")); +#endif + + return ret; +} + +/** + * g_socket_get_option: + * @socket: a #GSocket + * @level: the "API level" of the option (eg, `SOL_SOCKET`) + * @optname: the "name" of the option (eg, `SO_BROADCAST`) + * @value: (out): return location for the option value + * @error: #GError for error reporting, or %NULL to ignore. + * + * Gets the value of an integer-valued option on @socket, as with + * getsockopt(). (If you need to fetch a non-integer-valued option, + * you will need to call getsockopt() directly.) + * + * The [][gio-gnetworking.h] + * header pulls in system headers that will define most of the + * standard/portable socket options. For unusual socket protocols or + * platform-dependent options, you may need to include additional + * headers. + * + * Note that even for socket options that are a single byte in size, + * @value is still a pointer to a #gint variable, not a #guchar; + * g_socket_get_option() will handle the conversion internally. + * + * Returns: success or failure. On failure, @error will be set, and + * the system error value (`errno` or WSAGetLastError()) will still + * be set to the result of the getsockopt() call. + * + * Since: 2.36 + */ +gboolean +g_socket_get_option (GSocket *socket, + gint level, + gint optname, + gint *value, + GError **error) +{ + guint size; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + /* g_socket_get_option() is called during socket init, so skip the init checks + * in check_socket() */ + if (socket->priv->inited && !check_socket (socket, error)) + return FALSE; + + *value = 0; + size = sizeof (gint); + if (getsockopt (socket->priv->fd, level, optname, value, &size) != 0) + { + int errsv = get_socket_errno (); + + g_set_error_literal (error, + G_IO_ERROR, + socket_io_error_from_errno (errsv), + socket_strerror (errsv)); +#ifndef G_OS_WIN32 + /* Reset errno in case the caller wants to look at it */ + errno = errsv; +#endif + return FALSE; + } + +#if G_BYTE_ORDER == G_BIG_ENDIAN + /* If the returned value is smaller than an int then we need to + * slide it over into the low-order bytes of *value. + */ + if (size != sizeof (gint)) + *value = *value >> (8 * (sizeof (gint) - size)); +#endif + + return TRUE; +} + +/** + * g_socket_set_option: + * @socket: a #GSocket + * @level: the "API level" of the option (eg, `SOL_SOCKET`) + * @optname: the "name" of the option (eg, `SO_BROADCAST`) + * @value: the value to set the option to + * @error: #GError for error reporting, or %NULL to ignore. + * + * Sets the value of an integer-valued option on @socket, as with + * setsockopt(). (If you need to set a non-integer-valued option, + * you will need to call setsockopt() directly.) + * + * The [][gio-gnetworking.h] + * header pulls in system headers that will define most of the + * standard/portable socket options. For unusual socket protocols or + * platform-dependent options, you may need to include additional + * headers. + * + * Returns: success or failure. On failure, @error will be set, and + * the system error value (`errno` or WSAGetLastError()) will still + * be set to the result of the setsockopt() call. + * + * Since: 2.36 + */ +gboolean +g_socket_set_option (GSocket *socket, + gint level, + gint optname, + gint value, + GError **error) +{ + gint errsv; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + /* g_socket_set_option() is called during socket init, so skip the init checks + * in check_socket() */ + if (socket->priv->inited && !check_socket (socket, error)) + return FALSE; + + if (setsockopt (socket->priv->fd, level, optname, &value, sizeof (gint)) == 0) + return TRUE; + +#if !defined (__linux__) && !defined (G_OS_WIN32) + /* Linux and Windows let you set a single-byte value from an int, + * but most other platforms don't. + */ + if (errno == EINVAL && value >= SCHAR_MIN && value <= CHAR_MAX) + { +#if G_BYTE_ORDER == G_BIG_ENDIAN + value = value << (8 * (sizeof (gint) - 1)); +#endif + if (setsockopt (socket->priv->fd, level, optname, &value, 1) == 0) + return TRUE; + } +#endif + + errsv = get_socket_errno (); + + g_set_error_literal (error, + G_IO_ERROR, + socket_io_error_from_errno (errsv), + socket_strerror (errsv)); +#ifndef G_OS_WIN32 + errno = errsv; +#endif + return FALSE; +} diff --git a/gio/gsocket.h b/gio/gsocket.h new file mode 100644 index 0000000..9741135 --- /dev/null +++ b/gio/gsocket.h @@ -0,0 +1,328 @@ +/* + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + */ + +#ifndef __G_SOCKET_H__ +#define __G_SOCKET_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET (g_socket_get_type ()) +#define G_SOCKET(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SOCKET, GSocket)) +#define G_SOCKET_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SOCKET, GSocketClass)) +#define G_IS_SOCKET(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SOCKET)) +#define G_IS_SOCKET_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SOCKET)) +#define G_SOCKET_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SOCKET, GSocketClass)) + +typedef struct _GSocketPrivate GSocketPrivate; +typedef struct _GSocketClass GSocketClass; + +struct _GSocketClass +{ + GObjectClass parent_class; + + /*< private >*/ + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); + void (*_g_reserved7) (void); + void (*_g_reserved8) (void); + void (*_g_reserved9) (void); + void (*_g_reserved10) (void); +}; + +struct _GSocket +{ + GObject parent_instance; + GSocketPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GSocket * g_socket_new (GSocketFamily family, + GSocketType type, + GSocketProtocol protocol, + GError **error); +GLIB_AVAILABLE_IN_ALL +GSocket * g_socket_new_from_fd (gint fd, + GError **error); +GLIB_AVAILABLE_IN_ALL +int g_socket_get_fd (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +GSocketFamily g_socket_get_family (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +GSocketType g_socket_get_socket_type (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +GSocketProtocol g_socket_get_protocol (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +GSocketAddress * g_socket_get_local_address (GSocket *socket, + GError **error); +GLIB_AVAILABLE_IN_ALL +GSocketAddress * g_socket_get_remote_address (GSocket *socket, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_socket_set_blocking (GSocket *socket, + gboolean blocking); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_get_blocking (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +void g_socket_set_keepalive (GSocket *socket, + gboolean keepalive); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_get_keepalive (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +gint g_socket_get_listen_backlog (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +void g_socket_set_listen_backlog (GSocket *socket, + gint backlog); +GLIB_AVAILABLE_IN_ALL +guint g_socket_get_timeout (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +void g_socket_set_timeout (GSocket *socket, + guint timeout); + +GLIB_AVAILABLE_IN_2_32 +guint g_socket_get_ttl (GSocket *socket); +GLIB_AVAILABLE_IN_2_32 +void g_socket_set_ttl (GSocket *socket, + guint ttl); + +GLIB_AVAILABLE_IN_2_32 +gboolean g_socket_get_broadcast (GSocket *socket); +GLIB_AVAILABLE_IN_2_32 +void g_socket_set_broadcast (GSocket *socket, + gboolean broadcast); + +GLIB_AVAILABLE_IN_2_32 +gboolean g_socket_get_multicast_loopback (GSocket *socket); +GLIB_AVAILABLE_IN_2_32 +void g_socket_set_multicast_loopback (GSocket *socket, + gboolean loopback); +GLIB_AVAILABLE_IN_2_32 +guint g_socket_get_multicast_ttl (GSocket *socket); +GLIB_AVAILABLE_IN_2_32 +void g_socket_set_multicast_ttl (GSocket *socket, + guint ttl); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_is_connected (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_bind (GSocket *socket, + GSocketAddress *address, + gboolean allow_reuse, + GError **error); +GLIB_AVAILABLE_IN_2_32 +gboolean g_socket_join_multicast_group (GSocket *socket, + GInetAddress *group, + gboolean source_specific, + const gchar *iface, + GError **error); +GLIB_AVAILABLE_IN_2_32 +gboolean g_socket_leave_multicast_group (GSocket *socket, + GInetAddress *group, + gboolean source_specific, + const gchar *iface, + GError **error); +GLIB_AVAILABLE_IN_2_56 +gboolean g_socket_join_multicast_group_ssm (GSocket *socket, + GInetAddress *group, + GInetAddress *source_specific, + const gchar *iface, + GError **error); +GLIB_AVAILABLE_IN_2_56 +gboolean g_socket_leave_multicast_group_ssm (GSocket *socket, + GInetAddress *group, + GInetAddress *source_specific, + const gchar *iface, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_connect (GSocket *socket, + GSocketAddress *address, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_check_connect_result (GSocket *socket, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gssize g_socket_get_available_bytes (GSocket *socket); + +GLIB_AVAILABLE_IN_ALL +GIOCondition g_socket_condition_check (GSocket *socket, + GIOCondition condition); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_condition_wait (GSocket *socket, + GIOCondition condition, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_32 +gboolean g_socket_condition_timed_wait (GSocket *socket, + GIOCondition condition, + gint64 timeout_us, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GSocket * g_socket_accept (GSocket *socket, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_listen (GSocket *socket, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_socket_receive (GSocket *socket, + gchar *buffer, + gsize size, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_socket_receive_from (GSocket *socket, + GSocketAddress **address, + gchar *buffer, + gsize size, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_socket_send (GSocket *socket, + const gchar *buffer, + gsize size, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_socket_send_to (GSocket *socket, + GSocketAddress *address, + const gchar *buffer, + gsize size, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_socket_receive_message (GSocket *socket, + GSocketAddress **address, + GInputVector *vectors, + gint num_vectors, + GSocketControlMessage ***messages, + gint *num_messages, + gint *flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_socket_send_message (GSocket *socket, + GSocketAddress *address, + GOutputVector *vectors, + gint num_vectors, + GSocketControlMessage **messages, + gint num_messages, + gint flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_48 +gint g_socket_receive_messages (GSocket *socket, + GInputMessage *messages, + guint num_messages, + gint flags, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_44 +gint g_socket_send_messages (GSocket *socket, + GOutputMessage *messages, + guint num_messages, + gint flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_close (GSocket *socket, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_shutdown (GSocket *socket, + gboolean shutdown_read, + gboolean shutdown_write, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_is_closed (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +GSource * g_socket_create_source (GSocket *socket, + GIOCondition condition, + GCancellable *cancellable); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_speaks_ipv4 (GSocket *socket); +GLIB_AVAILABLE_IN_ALL +GCredentials *g_socket_get_credentials (GSocket *socket, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gssize g_socket_receive_with_blocking (GSocket *socket, + gchar *buffer, + gsize size, + gboolean blocking, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gssize g_socket_send_with_blocking (GSocket *socket, + const gchar *buffer, + gsize size, + gboolean blocking, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_60 +GPollableReturn g_socket_send_message_with_timeout (GSocket *socket, + GSocketAddress *address, + const GOutputVector *vectors, + gint num_vectors, + GSocketControlMessage **messages, + gint num_messages, + gint flags, + gint64 timeout_us, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_36 +gboolean g_socket_get_option (GSocket *socket, + gint level, + gint optname, + gint *value, + GError **error); +GLIB_AVAILABLE_IN_2_36 +gboolean g_socket_set_option (GSocket *socket, + gint level, + gint optname, + gint value, + GError **error); + +G_END_DECLS + +#endif /* __G_SOCKET_H__ */ diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c new file mode 100644 index 0000000..41dbe66 --- /dev/null +++ b/gio/gsocketaddress.c @@ -0,0 +1,418 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#include +#include +#include + +#include "gsocketaddress.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "gnativesocketaddress.h" +#include "gnetworkingprivate.h" +#include "gproxyaddress.h" +#include "gproxyaddressenumerator.h" +#include "gsocketaddressenumerator.h" +#include "gsocketconnectable.h" +#include "glibintl.h" +#include "gioenumtypes.h" + +#include "gunixsocketaddress.h" + +#ifdef G_OS_WIN32 +#include "giowin32-afunix.h" +#endif + + +/** + * SECTION:gsocketaddress + * @short_description: Abstract base class representing endpoints + * for socket communication + * @include: gio/gio.h + * + * #GSocketAddress is the equivalent of struct sockaddr in the BSD + * sockets API. This is an abstract class; use #GInetSocketAddress + * for internet sockets, or #GUnixSocketAddress for UNIX domain sockets. + */ + +/** + * GSocketAddress: + * + * A socket endpoint address, corresponding to struct sockaddr + * or one of its subtypes. + */ + +enum +{ + PROP_NONE, + PROP_FAMILY +}; + +static void g_socket_address_connectable_iface_init (GSocketConnectableIface *iface); +static GSocketAddressEnumerator *g_socket_address_connectable_enumerate (GSocketConnectable *connectable); +static GSocketAddressEnumerator *g_socket_address_connectable_proxy_enumerate (GSocketConnectable *connectable); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GSocketAddress, g_socket_address, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE, + g_socket_address_connectable_iface_init)) + +/** + * g_socket_address_get_family: + * @address: a #GSocketAddress + * + * Gets the socket family type of @address. + * + * Returns: the socket family type of @address + * + * Since: 2.22 + */ +GSocketFamily +g_socket_address_get_family (GSocketAddress *address) +{ + g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), 0); + + return G_SOCKET_ADDRESS_GET_CLASS (address)->get_family (address); +} + +static void +g_socket_address_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GSocketAddress *address = G_SOCKET_ADDRESS (object); + + switch (prop_id) + { + case PROP_FAMILY: + g_value_set_enum (value, g_socket_address_get_family (address)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_address_class_init (GSocketAddressClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = g_socket_address_get_property; + + g_object_class_install_property (gobject_class, PROP_FAMILY, + g_param_spec_enum ("family", + P_("Address family"), + P_("The family of the socket address"), + G_TYPE_SOCKET_FAMILY, + G_SOCKET_FAMILY_INVALID, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_socket_address_connectable_iface_init (GSocketConnectableIface *connectable_iface) +{ + connectable_iface->enumerate = g_socket_address_connectable_enumerate; + connectable_iface->proxy_enumerate = g_socket_address_connectable_proxy_enumerate; + /* to_string() is implemented by subclasses */ +} + +static void +g_socket_address_init (GSocketAddress *address) +{ + +} + +/** + * g_socket_address_get_native_size: + * @address: a #GSocketAddress + * + * Gets the size of @address's native struct sockaddr. + * You can use this to allocate memory to pass to + * g_socket_address_to_native(). + * + * Returns: the size of the native struct sockaddr that + * @address represents + * + * Since: 2.22 + */ +gssize +g_socket_address_get_native_size (GSocketAddress *address) +{ + g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), -1); + + return G_SOCKET_ADDRESS_GET_CLASS (address)->get_native_size (address); +} + +/** + * g_socket_address_to_native: + * @address: a #GSocketAddress + * @dest: a pointer to a memory location that will contain the native + * struct sockaddr + * @destlen: the size of @dest. Must be at least as large as + * g_socket_address_get_native_size() + * @error: #GError for error reporting, or %NULL to ignore + * + * Converts a #GSocketAddress to a native struct sockaddr, which can + * be passed to low-level functions like connect() or bind(). + * + * If not enough space is available, a %G_IO_ERROR_NO_SPACE error + * is returned. If the address type is not known on the system + * then a %G_IO_ERROR_NOT_SUPPORTED error is returned. + * + * Returns: %TRUE if @dest was filled in, %FALSE on error + * + * Since: 2.22 + */ +gboolean +g_socket_address_to_native (GSocketAddress *address, + gpointer dest, + gsize destlen, + GError **error) +{ + g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE); + + return G_SOCKET_ADDRESS_GET_CLASS (address)->to_native (address, dest, destlen, error); +} + +/** + * g_socket_address_new_from_native: + * @native: (not nullable): a pointer to a struct sockaddr + * @len: the size of the memory location pointed to by @native + * + * Creates a #GSocketAddress subclass corresponding to the native + * struct sockaddr @native. + * + * Returns: a new #GSocketAddress if @native could successfully + * be converted, otherwise %NULL + * + * Since: 2.22 + */ +GSocketAddress * +g_socket_address_new_from_native (gpointer native, + gsize len) +{ + gshort family; + + if (len < sizeof (gshort)) + return NULL; + + family = ((struct sockaddr *) native)->sa_family; + + if (family == AF_UNSPEC) + return NULL; + + if (family == AF_INET) + { + struct sockaddr_in *addr = (struct sockaddr_in *) native; + GInetAddress *iaddr; + GSocketAddress *sockaddr; + + if (len < sizeof (*addr)) + return NULL; + + iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin_addr), AF_INET); + sockaddr = g_inet_socket_address_new (iaddr, g_ntohs (addr->sin_port)); + g_object_unref (iaddr); + return sockaddr; + } + + if (family == AF_INET6) + { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) native; + GInetAddress *iaddr; + GSocketAddress *sockaddr; + + if (len < sizeof (*addr)) + return NULL; + + if (IN6_IS_ADDR_V4MAPPED (&(addr->sin6_addr))) + { + struct sockaddr_in sin_addr; + + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = addr->sin6_port; + memcpy (&(sin_addr.sin_addr.s_addr), addr->sin6_addr.s6_addr + 12, 4); + iaddr = g_inet_address_new_from_bytes ((guint8 *) &(sin_addr.sin_addr), AF_INET); + } + else + { + iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin6_addr), AF_INET6); + } + + sockaddr = g_object_new (G_TYPE_INET_SOCKET_ADDRESS, + "address", iaddr, + "port", g_ntohs (addr->sin6_port), + "flowinfo", addr->sin6_flowinfo, + "scope_id", addr->sin6_scope_id, + NULL); + g_object_unref (iaddr); + return sockaddr; + } + + if (family == AF_UNIX) + { + struct sockaddr_un *addr = (struct sockaddr_un *) native; + gint path_len = len - G_STRUCT_OFFSET (struct sockaddr_un, sun_path); + + if (path_len == 0) + { + return g_unix_socket_address_new_with_type ("", 0, + G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + } + else if (addr->sun_path[0] == 0) + { + if (!g_unix_socket_address_abstract_names_supported ()) + { + return g_unix_socket_address_new_with_type ("", 0, + G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + } + else if (len < sizeof (*addr)) + { + return g_unix_socket_address_new_with_type (addr->sun_path + 1, + path_len - 1, + G_UNIX_SOCKET_ADDRESS_ABSTRACT); + } + else + { + return g_unix_socket_address_new_with_type (addr->sun_path + 1, + path_len - 1, + G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED); + } + } + else + return g_unix_socket_address_new (addr->sun_path); + } + + return g_native_socket_address_new (native, len); +} + + +#define G_TYPE_SOCKET_ADDRESS_ADDRESS_ENUMERATOR (_g_socket_address_address_enumerator_get_type ()) +#define G_SOCKET_ADDRESS_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SOCKET_ADDRESS_ADDRESS_ENUMERATOR, GSocketAddressAddressEnumerator)) + +typedef struct { + GSocketAddressEnumerator parent_instance; + + GSocketAddress *sockaddr; +} GSocketAddressAddressEnumerator; + +typedef struct { + GSocketAddressEnumeratorClass parent_class; + +} GSocketAddressAddressEnumeratorClass; + +static GType _g_socket_address_address_enumerator_get_type (void); +G_DEFINE_TYPE (GSocketAddressAddressEnumerator, _g_socket_address_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR) + +static void +g_socket_address_address_enumerator_finalize (GObject *object) +{ + GSocketAddressAddressEnumerator *sockaddr_enum = + G_SOCKET_ADDRESS_ADDRESS_ENUMERATOR (object); + + if (sockaddr_enum->sockaddr) + g_object_unref (sockaddr_enum->sockaddr); + + G_OBJECT_CLASS (_g_socket_address_address_enumerator_parent_class)->finalize (object); +} + +static GSocketAddress * +g_socket_address_address_enumerator_next (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GSocketAddressAddressEnumerator *sockaddr_enum = + G_SOCKET_ADDRESS_ADDRESS_ENUMERATOR (enumerator); + + if (sockaddr_enum->sockaddr) + { + GSocketAddress *ret = sockaddr_enum->sockaddr; + + sockaddr_enum->sockaddr = NULL; + return ret; + } + else + return NULL; +} + +static void +_g_socket_address_address_enumerator_init (GSocketAddressAddressEnumerator *enumerator) +{ +} + +static void +_g_socket_address_address_enumerator_class_init (GSocketAddressAddressEnumeratorClass *sockaddrenum_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (sockaddrenum_class); + GSocketAddressEnumeratorClass *enumerator_class = + G_SOCKET_ADDRESS_ENUMERATOR_CLASS (sockaddrenum_class); + + enumerator_class->next = g_socket_address_address_enumerator_next; + object_class->finalize = g_socket_address_address_enumerator_finalize; +} + +static GSocketAddressEnumerator * +g_socket_address_connectable_enumerate (GSocketConnectable *connectable) +{ + GSocketAddressAddressEnumerator *sockaddr_enum; + + sockaddr_enum = g_object_new (G_TYPE_SOCKET_ADDRESS_ADDRESS_ENUMERATOR, NULL); + sockaddr_enum->sockaddr = g_object_ref (G_SOCKET_ADDRESS (connectable)); + + return (GSocketAddressEnumerator *)sockaddr_enum; +} + +static GSocketAddressEnumerator * +g_socket_address_connectable_proxy_enumerate (GSocketConnectable *connectable) +{ + GSocketAddressEnumerator *addr_enum = NULL; + + g_assert (connectable != NULL); + + if (G_IS_INET_SOCKET_ADDRESS (connectable) && + !G_IS_PROXY_ADDRESS (connectable)) + { + GInetAddress *addr; + guint port; + gchar *uri; + gchar *ip; + + g_object_get (connectable, "address", &addr, "port", &port, NULL); + + ip = g_inet_address_to_string (addr); + uri = g_uri_join (G_URI_FLAGS_NONE, "none", NULL, ip, port, "", NULL, NULL); + + addr_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, + "connectable", connectable, + "uri", uri, + NULL); + + g_object_unref (addr); + g_free (ip); + g_free (uri); + } + else + { + addr_enum = g_socket_address_connectable_enumerate (connectable); + } + + return addr_enum; +} diff --git a/gio/gsocketaddress.h b/gio/gsocketaddress.h new file mode 100644 index 0000000..ca2dbda --- /dev/null +++ b/gio/gsocketaddress.h @@ -0,0 +1,82 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#ifndef __G_SOCKET_ADDRESS_H__ +#define __G_SOCKET_ADDRESS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_ADDRESS (g_socket_address_get_type ()) +#define G_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOCKET_ADDRESS, GSocketAddress)) +#define G_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SOCKET_ADDRESS, GSocketAddressClass)) +#define G_IS_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SOCKET_ADDRESS)) +#define G_IS_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SOCKET_ADDRESS)) +#define G_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SOCKET_ADDRESS, GSocketAddressClass)) + +typedef struct _GSocketAddressClass GSocketAddressClass; + +struct _GSocketAddress +{ + GObject parent_instance; +}; + +struct _GSocketAddressClass +{ + GObjectClass parent_class; + + GSocketFamily (*get_family) (GSocketAddress *address); + + gssize (*get_native_size) (GSocketAddress *address); + + gboolean (*to_native) (GSocketAddress *address, + gpointer dest, + gsize destlen, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_address_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketFamily g_socket_address_get_family (GSocketAddress *address); + +GLIB_AVAILABLE_IN_ALL +GSocketAddress * g_socket_address_new_from_native (gpointer native, + gsize len); + +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_address_to_native (GSocketAddress *address, + gpointer dest, + gsize destlen, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gssize g_socket_address_get_native_size (GSocketAddress *address); + +G_END_DECLS + +#endif /* __G_SOCKET_ADDRESS_H__ */ diff --git a/gio/gsocketaddressenumerator.c b/gio/gsocketaddressenumerator.c new file mode 100644 index 0000000..458c794 --- /dev/null +++ b/gio/gsocketaddressenumerator.c @@ -0,0 +1,198 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "gsocketaddressenumerator.h" +#include "glibintl.h" + +#include "gtask.h" + +/** + * SECTION:gsocketaddressenumerator + * @short_description: Enumerator for socket addresses + * @include: gio/gio.h + * + * #GSocketAddressEnumerator is an enumerator type for #GSocketAddress + * instances. It is returned by enumeration functions such as + * g_socket_connectable_enumerate(), which returns a #GSocketAddressEnumerator + * to list each #GSocketAddress which could be used to connect to that + * #GSocketConnectable. + * + * Enumeration is typically a blocking operation, so the asynchronous methods + * g_socket_address_enumerator_next_async() and + * g_socket_address_enumerator_next_finish() should be used where possible. + * + * Each #GSocketAddressEnumerator can only be enumerated once. Once + * g_socket_address_enumerator_next() has returned %NULL, further + * enumeration with that #GSocketAddressEnumerator is not possible, and it can + * be unreffed. + */ + +G_DEFINE_ABSTRACT_TYPE (GSocketAddressEnumerator, g_socket_address_enumerator, G_TYPE_OBJECT) + +static void g_socket_address_enumerator_real_next_async (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GSocketAddress *g_socket_address_enumerator_real_next_finish (GSocketAddressEnumerator *enumerator, + GAsyncResult *result, + GError **error); + +static void +g_socket_address_enumerator_init (GSocketAddressEnumerator *enumerator) +{ +} + +static void +g_socket_address_enumerator_class_init (GSocketAddressEnumeratorClass *enumerator_class) +{ + enumerator_class->next_async = g_socket_address_enumerator_real_next_async; + enumerator_class->next_finish = g_socket_address_enumerator_real_next_finish; +} + +/** + * g_socket_address_enumerator_next: + * @enumerator: a #GSocketAddressEnumerator + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: a #GError. + * + * Retrieves the next #GSocketAddress from @enumerator. Note that this + * may block for some amount of time. (Eg, a #GNetworkAddress may need + * to do a DNS lookup before it can return an address.) Use + * g_socket_address_enumerator_next_async() if you need to avoid + * blocking. + * + * If @enumerator is expected to yield addresses, but for some reason + * is unable to (eg, because of a DNS error), then the first call to + * g_socket_address_enumerator_next() will return an appropriate error + * in *@error. However, if the first call to + * g_socket_address_enumerator_next() succeeds, then any further + * internal errors (other than @cancellable being triggered) will be + * ignored. + * + * Returns: (transfer full) (nullable): a #GSocketAddress (owned by the caller), or %NULL on + * error (in which case *@error will be set) or if there are no + * more addresses. + */ +GSocketAddress * +g_socket_address_enumerator_next (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GError **error) +{ + GSocketAddressEnumeratorClass *klass; + + g_return_val_if_fail (G_IS_SOCKET_ADDRESS_ENUMERATOR (enumerator), NULL); + + klass = G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS (enumerator); + + return (* klass->next) (enumerator, cancellable, error); +} + +/* Default implementation just calls the synchronous method; this can + * be used if the implementation already knows all of its addresses, + * and so the synchronous method will never block. + */ +static void +g_socket_address_enumerator_real_next_async (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + GSocketAddress *address; + GError *error = NULL; + + task = g_task_new (enumerator, NULL, callback, user_data); + g_task_set_source_tag (task, g_socket_address_enumerator_real_next_async); + + address = g_socket_address_enumerator_next (enumerator, cancellable, &error); + if (error) + g_task_return_error (task, error); + else + g_task_return_pointer (task, address, g_object_unref); + + g_object_unref (task); +} + +/** + * g_socket_address_enumerator_next_async: + * @enumerator: a #GSocketAddressEnumerator + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the request + * is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously retrieves the next #GSocketAddress from @enumerator + * and then calls @callback, which must call + * g_socket_address_enumerator_next_finish() to get the result. + * + * It is an error to call this multiple times before the previous callback has finished. + */ +void +g_socket_address_enumerator_next_async (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSocketAddressEnumeratorClass *klass; + + g_return_if_fail (G_IS_SOCKET_ADDRESS_ENUMERATOR (enumerator)); + + klass = G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS (enumerator); + + (* klass->next_async) (enumerator, cancellable, callback, user_data); +} + +static GSocketAddress * +g_socket_address_enumerator_real_next_finish (GSocketAddressEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +/** + * g_socket_address_enumerator_next_finish: + * @enumerator: a #GSocketAddressEnumerator + * @result: a #GAsyncResult + * @error: a #GError + * + * Retrieves the result of a completed call to + * g_socket_address_enumerator_next_async(). See + * g_socket_address_enumerator_next() for more information about + * error handling. + * + * Returns: (transfer full) (nullable): a #GSocketAddress (owned by the caller), or %NULL on + * error (in which case *@error will be set) or if there are no + * more addresses. + */ +GSocketAddress * +g_socket_address_enumerator_next_finish (GSocketAddressEnumerator *enumerator, + GAsyncResult *result, + GError **error) +{ + GSocketAddressEnumeratorClass *klass; + + g_return_val_if_fail (G_IS_SOCKET_ADDRESS_ENUMERATOR (enumerator), NULL); + + klass = G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS (enumerator); + + return (* klass->next_finish) (enumerator, result, error); +} diff --git a/gio/gsocketaddressenumerator.h b/gio/gsocketaddressenumerator.h new file mode 100644 index 0000000..2a180fd --- /dev/null +++ b/gio/gsocketaddressenumerator.h @@ -0,0 +1,101 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_SOCKET_ADDRESS_ENUMERATOR_H__ +#define __G_SOCKET_ADDRESS_ENUMERATOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_ADDRESS_ENUMERATOR (g_socket_address_enumerator_get_type ()) +#define G_SOCKET_ADDRESS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOCKET_ADDRESS_ENUMERATOR, GSocketAddressEnumerator)) +#define G_SOCKET_ADDRESS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SOCKET_ADDRESS_ENUMERATOR, GSocketAddressEnumeratorClass)) +#define G_IS_SOCKET_ADDRESS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SOCKET_ADDRESS_ENUMERATOR)) +#define G_IS_SOCKET_ADDRESS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SOCKET_ADDRESS_ENUMERATOR)) +#define G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SOCKET_ADDRESS_ENUMERATOR, GSocketAddressEnumeratorClass)) + +/** + * GSocketAddressEnumerator: + * + * Enumerator type for objects that contain or generate + * #GSocketAddress instances. + */ +typedef struct _GSocketAddressEnumeratorClass GSocketAddressEnumeratorClass; + +struct _GSocketAddressEnumerator +{ + /*< private >*/ + GObject parent_instance; +}; + +/** + * GSocketAddressEnumeratorClass: + * @next: Virtual method for g_socket_address_enumerator_next(). + * @next_async: Virtual method for g_socket_address_enumerator_next_async(). + * @next_finish: Virtual method for g_socket_address_enumerator_next_finish(). + * + * Class structure for #GSocketAddressEnumerator. + */ +struct _GSocketAddressEnumeratorClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + /* Virtual Table */ + + GSocketAddress * (* next) (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GError **error); + + void (* next_async) (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GSocketAddress * (* next_finish) (GSocketAddressEnumerator *enumerator, + GAsyncResult *result, + GError **error); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_address_enumerator_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_socket_address_enumerator_next (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_socket_address_enumerator_next_async (GSocketAddressEnumerator *enumerator, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_socket_address_enumerator_next_finish (GSocketAddressEnumerator *enumerator, + GAsyncResult *result, + GError **error); + +G_END_DECLS + + +#endif /* __G_SOCKET_ADDRESS_ENUMERATOR_H__ */ diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c new file mode 100644 index 0000000..8bcbdfa --- /dev/null +++ b/gio/gsocketclient.c @@ -0,0 +1,2396 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008, 2009 codethink + * Copyright © 2009 Red Hat, Inc + * Copyright © 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Alexander Larsson + */ + +#include "config.h" +#include "gsocketclient.h" + +#ifndef G_OS_WIN32 +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "glibintl.h" +#include "gmarshal-internal.h" + +/* As recommended by RFC 8305 this is the time it waits + * on a connection before starting another concurrent attempt. + */ +#define HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS 250 + +/** + * SECTION:gsocketclient + * @short_description: Helper for connecting to a network service + * @include: gio/gio.h + * @see_also: #GSocketConnection, #GSocketListener + * + * #GSocketClient is a lightweight high-level utility class for connecting to + * a network host using a connection oriented socket type. + * + * You create a #GSocketClient object, set any options you want, and then + * call a sync or async connect operation, which returns a #GSocketConnection + * subclass on success. + * + * The type of the #GSocketConnection object returned depends on the type of + * the underlying socket that is in use. For instance, for a TCP/IP connection + * it will be a #GTcpConnection. + * + * As #GSocketClient is a lightweight object, you don't need to cache it. You + * can just create a new one any time you need one. + * + * Since: 2.22 + */ + + +enum +{ + EVENT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum +{ + PROP_NONE, + PROP_FAMILY, + PROP_TYPE, + PROP_PROTOCOL, + PROP_LOCAL_ADDRESS, + PROP_TIMEOUT, + PROP_ENABLE_PROXY, + PROP_TLS, + PROP_TLS_VALIDATION_FLAGS, + PROP_PROXY_RESOLVER +}; + +struct _GSocketClientPrivate +{ + GSocketFamily family; + GSocketType type; + GSocketProtocol protocol; + GSocketAddress *local_address; + guint timeout; + gboolean enable_proxy; + GHashTable *app_proxies; + gboolean tls; + GTlsCertificateFlags tls_validation_flags; + GProxyResolver *proxy_resolver; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GSocketClient, g_socket_client, G_TYPE_OBJECT) + +static GSocket * +create_socket (GSocketClient *client, + GSocketAddress *dest_address, + GError **error) +{ + GSocketFamily family; + GSocket *socket; + + family = client->priv->family; + if (family == G_SOCKET_FAMILY_INVALID && + client->priv->local_address != NULL) + family = g_socket_address_get_family (client->priv->local_address); + if (family == G_SOCKET_FAMILY_INVALID) + family = g_socket_address_get_family (dest_address); + + socket = g_socket_new (family, + client->priv->type, + client->priv->protocol, + error); + if (socket == NULL) + return NULL; + + if (client->priv->local_address) + { +#ifdef IP_BIND_ADDRESS_NO_PORT + g_socket_set_option (socket, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, 1, NULL); +#endif + + if (!g_socket_bind (socket, + client->priv->local_address, + FALSE, + error)) + { + g_object_unref (socket); + return NULL; + } + } + + if (client->priv->timeout) + g_socket_set_timeout (socket, client->priv->timeout); + + return socket; +} + +static gboolean +can_use_proxy (GSocketClient *client) +{ + GSocketClientPrivate *priv = client->priv; + + return priv->enable_proxy + && priv->type == G_SOCKET_TYPE_STREAM; +} + +static void +clarify_connect_error (GError *error, + GSocketConnectable *connectable, + GSocketAddress *address) +{ + const char *name; + char *tmp_name = NULL; + + if (G_IS_PROXY_ADDRESS (address)) + { + name = tmp_name = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address))); + + g_prefix_error (&error, _("Could not connect to proxy server %s: "), name); + } + else + { + if (G_IS_NETWORK_ADDRESS (connectable)) + name = g_network_address_get_hostname (G_NETWORK_ADDRESS (connectable)); + else if (G_IS_NETWORK_SERVICE (connectable)) + name = g_network_service_get_domain (G_NETWORK_SERVICE (connectable)); + else if (G_IS_INET_SOCKET_ADDRESS (connectable)) + name = tmp_name = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (connectable))); + else + name = NULL; + + if (name) + g_prefix_error (&error, _("Could not connect to %s: "), name); + else + g_prefix_error (&error, _("Could not connect: ")); + } + + g_free (tmp_name); +} + +static void +g_socket_client_init (GSocketClient *client) +{ + client->priv = g_socket_client_get_instance_private (client); + client->priv->type = G_SOCKET_TYPE_STREAM; + client->priv->app_proxies = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + NULL); +} + +/** + * g_socket_client_new: + * + * Creates a new #GSocketClient with the default options. + * + * Returns: a #GSocketClient. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GSocketClient * +g_socket_client_new (void) +{ + return g_object_new (G_TYPE_SOCKET_CLIENT, NULL); +} + +static void +g_socket_client_finalize (GObject *object) +{ + GSocketClient *client = G_SOCKET_CLIENT (object); + + g_clear_object (&client->priv->local_address); + g_clear_object (&client->priv->proxy_resolver); + + G_OBJECT_CLASS (g_socket_client_parent_class)->finalize (object); + + g_hash_table_unref (client->priv->app_proxies); +} + +static void +g_socket_client_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSocketClient *client = G_SOCKET_CLIENT (object); + + switch (prop_id) + { + case PROP_FAMILY: + g_value_set_enum (value, client->priv->family); + break; + + case PROP_TYPE: + g_value_set_enum (value, client->priv->type); + break; + + case PROP_PROTOCOL: + g_value_set_enum (value, client->priv->protocol); + break; + + case PROP_LOCAL_ADDRESS: + g_value_set_object (value, client->priv->local_address); + break; + + case PROP_TIMEOUT: + g_value_set_uint (value, client->priv->timeout); + break; + + case PROP_ENABLE_PROXY: + g_value_set_boolean (value, client->priv->enable_proxy); + break; + + case PROP_TLS: + g_value_set_boolean (value, g_socket_client_get_tls (client)); + break; + + case PROP_TLS_VALIDATION_FLAGS: +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_value_set_flags (value, g_socket_client_get_tls_validation_flags (client)); +G_GNUC_END_IGNORE_DEPRECATIONS + break; + + case PROP_PROXY_RESOLVER: + g_value_set_object (value, g_socket_client_get_proxy_resolver (client)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_client_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSocketClient *client = G_SOCKET_CLIENT (object); + + switch (prop_id) + { + case PROP_FAMILY: + g_socket_client_set_family (client, g_value_get_enum (value)); + break; + + case PROP_TYPE: + g_socket_client_set_socket_type (client, g_value_get_enum (value)); + break; + + case PROP_PROTOCOL: + g_socket_client_set_protocol (client, g_value_get_enum (value)); + break; + + case PROP_LOCAL_ADDRESS: + g_socket_client_set_local_address (client, g_value_get_object (value)); + break; + + case PROP_TIMEOUT: + g_socket_client_set_timeout (client, g_value_get_uint (value)); + break; + + case PROP_ENABLE_PROXY: + g_socket_client_set_enable_proxy (client, g_value_get_boolean (value)); + break; + + case PROP_TLS: + g_socket_client_set_tls (client, g_value_get_boolean (value)); + break; + + case PROP_TLS_VALIDATION_FLAGS: +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_socket_client_set_tls_validation_flags (client, g_value_get_flags (value)); +G_GNUC_END_IGNORE_DEPRECATIONS + break; + + case PROP_PROXY_RESOLVER: + g_socket_client_set_proxy_resolver (client, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +/** + * g_socket_client_get_family: + * @client: a #GSocketClient. + * + * Gets the socket family of the socket client. + * + * See g_socket_client_set_family() for details. + * + * Returns: a #GSocketFamily + * + * Since: 2.22 + */ +GSocketFamily +g_socket_client_get_family (GSocketClient *client) +{ + return client->priv->family; +} + +/** + * g_socket_client_set_family: + * @client: a #GSocketClient. + * @family: a #GSocketFamily + * + * Sets the socket family of the socket client. + * If this is set to something other than %G_SOCKET_FAMILY_INVALID + * then the sockets created by this object will be of the specified + * family. + * + * This might be useful for instance if you want to force the local + * connection to be an ipv4 socket, even though the address might + * be an ipv6 mapped to ipv4 address. + * + * Since: 2.22 + */ +void +g_socket_client_set_family (GSocketClient *client, + GSocketFamily family) +{ + if (client->priv->family == family) + return; + + client->priv->family = family; + g_object_notify (G_OBJECT (client), "family"); +} + +/** + * g_socket_client_get_socket_type: + * @client: a #GSocketClient. + * + * Gets the socket type of the socket client. + * + * See g_socket_client_set_socket_type() for details. + * + * Returns: a #GSocketFamily + * + * Since: 2.22 + */ +GSocketType +g_socket_client_get_socket_type (GSocketClient *client) +{ + return client->priv->type; +} + +/** + * g_socket_client_set_socket_type: + * @client: a #GSocketClient. + * @type: a #GSocketType + * + * Sets the socket type of the socket client. + * The sockets created by this object will be of the specified + * type. + * + * It doesn't make sense to specify a type of %G_SOCKET_TYPE_DATAGRAM, + * as GSocketClient is used for connection oriented services. + * + * Since: 2.22 + */ +void +g_socket_client_set_socket_type (GSocketClient *client, + GSocketType type) +{ + if (client->priv->type == type) + return; + + client->priv->type = type; + g_object_notify (G_OBJECT (client), "type"); +} + +/** + * g_socket_client_get_protocol: + * @client: a #GSocketClient + * + * Gets the protocol name type of the socket client. + * + * See g_socket_client_set_protocol() for details. + * + * Returns: a #GSocketProtocol + * + * Since: 2.22 + */ +GSocketProtocol +g_socket_client_get_protocol (GSocketClient *client) +{ + return client->priv->protocol; +} + +/** + * g_socket_client_set_protocol: + * @client: a #GSocketClient. + * @protocol: a #GSocketProtocol + * + * Sets the protocol of the socket client. + * The sockets created by this object will use of the specified + * protocol. + * + * If @protocol is %G_SOCKET_PROTOCOL_DEFAULT that means to use the default + * protocol for the socket family and type. + * + * Since: 2.22 + */ +void +g_socket_client_set_protocol (GSocketClient *client, + GSocketProtocol protocol) +{ + if (client->priv->protocol == protocol) + return; + + client->priv->protocol = protocol; + g_object_notify (G_OBJECT (client), "protocol"); +} + +/** + * g_socket_client_get_local_address: + * @client: a #GSocketClient. + * + * Gets the local address of the socket client. + * + * See g_socket_client_set_local_address() for details. + * + * Returns: (nullable) (transfer none): a #GSocketAddress or %NULL. Do not free. + * + * Since: 2.22 + */ +GSocketAddress * +g_socket_client_get_local_address (GSocketClient *client) +{ + return client->priv->local_address; +} + +/** + * g_socket_client_set_local_address: + * @client: a #GSocketClient. + * @address: (nullable): a #GSocketAddress, or %NULL + * + * Sets the local address of the socket client. + * The sockets created by this object will bound to the + * specified address (if not %NULL) before connecting. + * + * This is useful if you want to ensure that the local + * side of the connection is on a specific port, or on + * a specific interface. + * + * Since: 2.22 + */ +void +g_socket_client_set_local_address (GSocketClient *client, + GSocketAddress *address) +{ + if (address) + g_object_ref (address); + + if (client->priv->local_address) + { + g_object_unref (client->priv->local_address); + } + client->priv->local_address = address; + g_object_notify (G_OBJECT (client), "local-address"); +} + +/** + * g_socket_client_get_timeout: + * @client: a #GSocketClient + * + * Gets the I/O timeout time for sockets created by @client. + * + * See g_socket_client_set_timeout() for details. + * + * Returns: the timeout in seconds + * + * Since: 2.26 + */ +guint +g_socket_client_get_timeout (GSocketClient *client) +{ + return client->priv->timeout; +} + + +/** + * g_socket_client_set_timeout: + * @client: a #GSocketClient. + * @timeout: the timeout + * + * Sets the I/O timeout for sockets created by @client. @timeout is a + * time in seconds, or 0 for no timeout (the default). + * + * The timeout value affects the initial connection attempt as well, + * so setting this may cause calls to g_socket_client_connect(), etc, + * to fail with %G_IO_ERROR_TIMED_OUT. + * + * Since: 2.26 + */ +void +g_socket_client_set_timeout (GSocketClient *client, + guint timeout) +{ + if (client->priv->timeout == timeout) + return; + + client->priv->timeout = timeout; + g_object_notify (G_OBJECT (client), "timeout"); +} + +/** + * g_socket_client_get_enable_proxy: + * @client: a #GSocketClient. + * + * Gets the proxy enable state; see g_socket_client_set_enable_proxy() + * + * Returns: whether proxying is enabled + * + * Since: 2.26 + */ +gboolean +g_socket_client_get_enable_proxy (GSocketClient *client) +{ + return client->priv->enable_proxy; +} + +/** + * g_socket_client_set_enable_proxy: + * @client: a #GSocketClient. + * @enable: whether to enable proxies + * + * Sets whether or not @client attempts to make connections via a + * proxy server. When enabled (the default), #GSocketClient will use a + * #GProxyResolver to determine if a proxy protocol such as SOCKS is + * needed, and automatically do the necessary proxy negotiation. + * + * See also g_socket_client_set_proxy_resolver(). + * + * Since: 2.26 + */ +void +g_socket_client_set_enable_proxy (GSocketClient *client, + gboolean enable) +{ + enable = !!enable; + if (client->priv->enable_proxy == enable) + return; + + client->priv->enable_proxy = enable; + g_object_notify (G_OBJECT (client), "enable-proxy"); +} + +/** + * g_socket_client_get_tls: + * @client: a #GSocketClient. + * + * Gets whether @client creates TLS connections. See + * g_socket_client_set_tls() for details. + * + * Returns: whether @client uses TLS + * + * Since: 2.28 + */ +gboolean +g_socket_client_get_tls (GSocketClient *client) +{ + return client->priv->tls; +} + +/** + * g_socket_client_set_tls: + * @client: a #GSocketClient. + * @tls: whether to use TLS + * + * Sets whether @client creates TLS (aka SSL) connections. If @tls is + * %TRUE, @client will wrap its connections in a #GTlsClientConnection + * and perform a TLS handshake when connecting. + * + * Note that since #GSocketClient must return a #GSocketConnection, + * but #GTlsClientConnection is not a #GSocketConnection, this + * actually wraps the resulting #GTlsClientConnection in a + * #GTcpWrapperConnection when returning it. You can use + * g_tcp_wrapper_connection_get_base_io_stream() on the return value + * to extract the #GTlsClientConnection. + * + * If you need to modify the behavior of the TLS handshake (eg, by + * setting a client-side certificate to use, or connecting to the + * #GTlsConnection::accept-certificate signal), you can connect to + * @client's #GSocketClient::event signal and wait for it to be + * emitted with %G_SOCKET_CLIENT_TLS_HANDSHAKING, which will give you + * a chance to see the #GTlsClientConnection before the handshake + * starts. + * + * Since: 2.28 + */ +void +g_socket_client_set_tls (GSocketClient *client, + gboolean tls) +{ + tls = !!tls; + if (tls == client->priv->tls) + return; + + client->priv->tls = tls; + g_object_notify (G_OBJECT (client), "tls"); +} + +/** + * g_socket_client_get_tls_validation_flags: + * @client: a #GSocketClient. + * + * Gets the TLS validation flags used creating TLS connections via + * @client. + * + * This function does not work as originally designed and is impossible + * to use correctly. See #GSocketClient:tls-validation-flags for more + * information. + * + * Returns: the TLS validation flags + * + * Since: 2.28 + * + * Deprecated: 2.72: Do not attempt to ignore validation errors. + */ +GTlsCertificateFlags +g_socket_client_get_tls_validation_flags (GSocketClient *client) +{ + return client->priv->tls_validation_flags; +} + +/** + * g_socket_client_set_tls_validation_flags: + * @client: a #GSocketClient. + * @flags: the validation flags + * + * Sets the TLS validation flags used when creating TLS connections + * via @client. The default value is %G_TLS_CERTIFICATE_VALIDATE_ALL. + * + * This function does not work as originally designed and is impossible + * to use correctly. See #GSocketClient:tls-validation-flags for more + * information. + * + * Since: 2.28 + * + * Deprecated: 2.72: Do not attempt to ignore validation errors. + */ +void +g_socket_client_set_tls_validation_flags (GSocketClient *client, + GTlsCertificateFlags flags) +{ + if (client->priv->tls_validation_flags != flags) + { + client->priv->tls_validation_flags = flags; + g_object_notify (G_OBJECT (client), "tls-validation-flags"); + } +} + +/** + * g_socket_client_get_proxy_resolver: + * @client: a #GSocketClient. + * + * Gets the #GProxyResolver being used by @client. Normally, this will + * be the resolver returned by g_proxy_resolver_get_default(), but you + * can override it with g_socket_client_set_proxy_resolver(). + * + * Returns: (transfer none): The #GProxyResolver being used by + * @client. + * + * Since: 2.36 + */ +GProxyResolver * +g_socket_client_get_proxy_resolver (GSocketClient *client) +{ + if (client->priv->proxy_resolver) + return client->priv->proxy_resolver; + else + return g_proxy_resolver_get_default (); +} + +/** + * g_socket_client_set_proxy_resolver: + * @client: a #GSocketClient. + * @proxy_resolver: (nullable): a #GProxyResolver, or %NULL for the + * default. + * + * Overrides the #GProxyResolver used by @client. You can call this if + * you want to use specific proxies, rather than using the system + * default proxy settings. + * + * Note that whether or not the proxy resolver is actually used + * depends on the setting of #GSocketClient:enable-proxy, which is not + * changed by this function (but which is %TRUE by default) + * + * Since: 2.36 + */ +void +g_socket_client_set_proxy_resolver (GSocketClient *client, + GProxyResolver *proxy_resolver) +{ + /* We have to be careful to avoid calling + * g_proxy_resolver_get_default() until we're sure we need it, + * because trying to load the default proxy resolver module will + * break some test programs that aren't expecting it (eg, + * tests/gsettings). + */ + + if (client->priv->proxy_resolver) + g_object_unref (client->priv->proxy_resolver); + + client->priv->proxy_resolver = proxy_resolver; + + if (client->priv->proxy_resolver) + g_object_ref (client->priv->proxy_resolver); +} + +static void +g_socket_client_class_init (GSocketClientClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->finalize = g_socket_client_finalize; + gobject_class->set_property = g_socket_client_set_property; + gobject_class->get_property = g_socket_client_get_property; + + /** + * GSocketClient::event: + * @client: the #GSocketClient + * @event: the event that is occurring + * @connectable: the #GSocketConnectable that @event is occurring on + * @connection: (nullable): the current representation of the connection + * + * Emitted when @client's activity on @connectable changes state. + * Among other things, this can be used to provide progress + * information about a network connection in the UI. The meanings of + * the different @event values are as follows: + * + * - %G_SOCKET_CLIENT_RESOLVING: @client is about to look up @connectable + * in DNS. @connection will be %NULL. + * + * - %G_SOCKET_CLIENT_RESOLVED: @client has successfully resolved + * @connectable in DNS. @connection will be %NULL. + * + * - %G_SOCKET_CLIENT_CONNECTING: @client is about to make a connection + * to a remote host; either a proxy server or the destination server + * itself. @connection is the #GSocketConnection, which is not yet + * connected. Since GLib 2.40, you can access the remote + * address via g_socket_connection_get_remote_address(). + * + * - %G_SOCKET_CLIENT_CONNECTED: @client has successfully connected + * to a remote host. @connection is the connected #GSocketConnection. + * + * - %G_SOCKET_CLIENT_PROXY_NEGOTIATING: @client is about to negotiate + * with a proxy to get it to connect to @connectable. @connection is + * the #GSocketConnection to the proxy server. + * + * - %G_SOCKET_CLIENT_PROXY_NEGOTIATED: @client has negotiated a + * connection to @connectable through a proxy server. @connection is + * the stream returned from g_proxy_connect(), which may or may not + * be a #GSocketConnection. + * + * - %G_SOCKET_CLIENT_TLS_HANDSHAKING: @client is about to begin a TLS + * handshake. @connection is a #GTlsClientConnection. + * + * - %G_SOCKET_CLIENT_TLS_HANDSHAKED: @client has successfully completed + * the TLS handshake. @connection is a #GTlsClientConnection. + * + * - %G_SOCKET_CLIENT_COMPLETE: @client has either successfully connected + * to @connectable (in which case @connection is the #GSocketConnection + * that it will be returning to the caller) or has failed (in which + * case @connection is %NULL and the client is about to return an error). + * + * Each event except %G_SOCKET_CLIENT_COMPLETE may be emitted + * multiple times (or not at all) for a given connectable (in + * particular, if @client ends up attempting to connect to more than + * one address). However, if @client emits the #GSocketClient::event + * signal at all for a given connectable, then it will always emit + * it with %G_SOCKET_CLIENT_COMPLETE when it is done. + * + * Note that there may be additional #GSocketClientEvent values in + * the future; unrecognized @event values should be ignored. + * + * Since: 2.32 + */ + signals[EVENT] = + g_signal_new (I_("event"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GSocketClientClass, event), + NULL, NULL, + _g_cclosure_marshal_VOID__ENUM_OBJECT_OBJECT, + G_TYPE_NONE, 3, + G_TYPE_SOCKET_CLIENT_EVENT, + G_TYPE_SOCKET_CONNECTABLE, + G_TYPE_IO_STREAM); + g_signal_set_va_marshaller (signals[EVENT], + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_VOID__ENUM_OBJECT_OBJECTv); + + g_object_class_install_property (gobject_class, PROP_FAMILY, + g_param_spec_enum ("family", + P_("Socket family"), + P_("The sockets address family to use for socket construction"), + G_TYPE_SOCKET_FAMILY, + G_SOCKET_FAMILY_INVALID, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_TYPE, + g_param_spec_enum ("type", + P_("Socket type"), + P_("The sockets type to use for socket construction"), + G_TYPE_SOCKET_TYPE, + G_SOCKET_TYPE_STREAM, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_PROTOCOL, + g_param_spec_enum ("protocol", + P_("Socket protocol"), + P_("The protocol to use for socket construction, or 0 for default"), + G_TYPE_SOCKET_PROTOCOL, + G_SOCKET_PROTOCOL_DEFAULT, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS, + g_param_spec_object ("local-address", + P_("Local address"), + P_("The local address constructed sockets will be bound to"), + G_TYPE_SOCKET_ADDRESS, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_TIMEOUT, + g_param_spec_uint ("timeout", + P_("Socket timeout"), + P_("The I/O timeout for sockets, or 0 for none"), + 0, G_MAXUINT, 0, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_ENABLE_PROXY, + g_param_spec_boolean ("enable-proxy", + P_("Enable proxy"), + P_("Enable proxy support"), + TRUE, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_TLS, + g_param_spec_boolean ("tls", + P_("TLS"), + P_("Whether to create TLS connections"), + FALSE, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * GSocketClient:tls-validation-flags: + * + * The TLS validation flags used when creating TLS connections. The + * default value is %G_TLS_CERTIFICATE_VALIDATE_ALL. + * + * GLib guarantees that if certificate verification fails, at least one + * flag will be set, but it does not guarantee that all possible flags + * will be set. Accordingly, you may not safely decide to ignore any + * particular type of error. For example, it would be incorrect to mask + * %G_TLS_CERTIFICATE_EXPIRED if you want to allow expired certificates, + * because this could potentially be the only error flag set even if + * other problems exist with the certificate. Therefore, there is no + * safe way to use this property. This is not a horrible problem, + * though, because you should not be attempting to ignore validation + * errors anyway. If you really must ignore TLS certificate errors, + * connect to the #GSocketClient::event signal, wait for it to be + * emitted with %G_SOCKET_CLIENT_TLS_HANDSHAKING, and use that to + * connect to #GTlsConnection::accept-certificate. + * + * Deprecated: 2.72: Do not attempt to ignore validation errors. + */ + g_object_class_install_property (gobject_class, PROP_TLS_VALIDATION_FLAGS, + g_param_spec_flags ("tls-validation-flags", + P_("TLS validation flags"), + P_("TLS validation flags to use"), + G_TYPE_TLS_CERTIFICATE_FLAGS, + G_TLS_CERTIFICATE_VALIDATE_ALL, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_DEPRECATED)); + + /** + * GSocketClient:proxy-resolver: + * + * The proxy resolver to use + * + * Since: 2.36 + */ + g_object_class_install_property (gobject_class, PROP_PROXY_RESOLVER, + g_param_spec_object ("proxy-resolver", + P_("Proxy resolver"), + P_("The proxy resolver to use"), + G_TYPE_PROXY_RESOLVER, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_socket_client_emit_event (GSocketClient *client, + GSocketClientEvent event, + GSocketConnectable *connectable, + GIOStream *connection) +{ + g_signal_emit (client, signals[EVENT], 0, + event, connectable, connection); +} + +/* Originally, GSocketClient returned whatever error occured last. Turns + * out this doesn't work well in practice. Consider the following case: + * DNS returns an IPv4 and IPv6 address. First we'll connect() to the + * IPv4 address, and say that succeeds, but TLS is enabled and the TLS + * handshake fails. Then we try the IPv6 address and receive ENETUNREACH + * because IPv6 isn't supported. We wind up returning NETWORK_UNREACHABLE + * even though the address can be pinged and a TLS error would be more + * appropriate. So instead, we now try to return the error corresponding + * to the latest attempted GSocketClientEvent in the connection process. + * TLS errors take precedence over proxy errors, which take precedence + * over connect() errors, which take precedence over DNS errors. + * + * Note that the example above considers a sync codepath, but this is an + * issue for the async codepath too, where events and errors may occur + * in confusing orders. + */ +typedef struct +{ + GError *tmp_error; + GError *best_error; + GSocketClientEvent best_error_event; +} SocketClientErrorInfo; + +static SocketClientErrorInfo * +socket_client_error_info_new (void) +{ + return g_new0 (SocketClientErrorInfo, 1); +} + +static void +socket_client_error_info_free (SocketClientErrorInfo *info) +{ + g_assert (info->tmp_error == NULL); + g_clear_error (&info->best_error); + g_free (info); +} + +static void +consider_tmp_error (SocketClientErrorInfo *info, + GSocketClientEvent event) +{ + if (info->tmp_error == NULL) + return; + + /* If we ever add more GSocketClientEvents in the future, then we'll + * no longer be able to use >= for this comparison, because future + * events will compare greater than G_SOCKET_CLIENT_COMPLETE. Until + * then, this is convenient. Note G_SOCKET_CLIENT_RESOLVING is 0 so we + * need to use >= here or those errors would never be set. That means + * if we get two errors on the same GSocketClientEvent, we wind up + * preferring the last one, which is fine. + */ + g_assert (event <= G_SOCKET_CLIENT_COMPLETE); + if (event >= info->best_error_event) + { + g_clear_error (&info->best_error); + info->best_error = info->tmp_error; + info->tmp_error = NULL; + info->best_error_event = event; + } + else + { + g_clear_error (&info->tmp_error); + } +} + +/** + * g_socket_client_connect: + * @client: a #GSocketClient. + * @connectable: a #GSocketConnectable specifying the remote address. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Tries to resolve the @connectable and make a network connection to it. + * + * Upon a successful connection, a new #GSocketConnection is constructed + * and returned. The caller owns this new object and must drop their + * reference to it when finished with it. + * + * The type of the #GSocketConnection object returned depends on the type of + * the underlying socket that is used. For instance, for a TCP/IP connection + * it will be a #GTcpConnection. + * + * The socket created will be the same family as the address that the + * @connectable resolves to, unless family is set with g_socket_client_set_family() + * or indirectly via g_socket_client_set_local_address(). The socket type + * defaults to %G_SOCKET_TYPE_STREAM but can be set with + * g_socket_client_set_socket_type(). + * + * If a local address is specified with g_socket_client_set_local_address() the + * socket will be bound to this address before connecting. + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.22 + */ +GSocketConnection * +g_socket_client_connect (GSocketClient *client, + GSocketConnectable *connectable, + GCancellable *cancellable, + GError **error) +{ + GIOStream *connection = NULL; + GSocketAddressEnumerator *enumerator = NULL; + SocketClientErrorInfo *error_info; + gboolean ever_resolved = FALSE; + + error_info = socket_client_error_info_new (); + + if (can_use_proxy (client)) + { + enumerator = g_socket_connectable_proxy_enumerate (connectable); + if (client->priv->proxy_resolver && + G_IS_PROXY_ADDRESS_ENUMERATOR (enumerator)) + { + g_object_set (G_OBJECT (enumerator), + "proxy-resolver", client->priv->proxy_resolver, + NULL); + } + } + else + enumerator = g_socket_connectable_enumerate (connectable); + + while (connection == NULL) + { + GSocketAddress *address = NULL; + gboolean application_proxy = FALSE; + GSocket *socket; + gboolean using_proxy; + + if (g_cancellable_is_cancelled (cancellable)) + { + g_clear_error (&error_info->best_error); + g_cancellable_set_error_if_cancelled (cancellable, &error_info->best_error); + break; + } + + if (!ever_resolved) + { + g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVING, + connectable, NULL); + } + address = g_socket_address_enumerator_next (enumerator, cancellable, + &error_info->tmp_error); + consider_tmp_error (error_info, G_SOCKET_CLIENT_RESOLVING); + if (!ever_resolved) + { + g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVED, + connectable, NULL); + ever_resolved = TRUE; + } + + if (address == NULL) + { + /* Enumeration is finished. */ + g_assert (&error_info->best_error != NULL); + break; + } + + using_proxy = (G_IS_PROXY_ADDRESS (address) && + client->priv->enable_proxy); + + socket = create_socket (client, address, &error_info->tmp_error); + consider_tmp_error (error_info, G_SOCKET_CLIENT_CONNECTING); + if (socket == NULL) + { + g_object_unref (address); + continue; + } + + connection = (GIOStream *)g_socket_connection_factory_create_connection (socket); + g_socket_connection_set_cached_remote_address ((GSocketConnection*)connection, address); + g_socket_client_emit_event (client, G_SOCKET_CLIENT_CONNECTING, connectable, connection); + + if (g_socket_connection_connect (G_SOCKET_CONNECTION (connection), + address, cancellable, &error_info->tmp_error)) + { + g_socket_connection_set_cached_remote_address ((GSocketConnection*)connection, NULL); + g_socket_client_emit_event (client, G_SOCKET_CLIENT_CONNECTED, connectable, connection); + } + else + { + clarify_connect_error (error_info->tmp_error, connectable, address); + consider_tmp_error (error_info, G_SOCKET_CLIENT_CONNECTING); + g_object_unref (connection); + connection = NULL; + } + + if (connection && using_proxy) + { + GProxyAddress *proxy_addr = G_PROXY_ADDRESS (address); + const gchar *protocol; + GProxy *proxy; + + protocol = g_proxy_address_get_protocol (proxy_addr); + + /* The connection should not be anything else then TCP Connection, + * but let's put a safety guard in case + */ + if (!G_IS_TCP_CONNECTION (connection)) + { + g_critical ("Trying to proxy over non-TCP connection, this is " + "most likely a bug in GLib IO library."); + + g_set_error_literal (&error_info->tmp_error, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Proxying over a non-TCP connection is not supported.")); + consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING); + + g_object_unref (connection); + connection = NULL; + } + else if (g_hash_table_contains (client->priv->app_proxies, protocol)) + { + application_proxy = TRUE; + } + else if ((proxy = g_proxy_get_default_for_protocol (protocol))) + { + GIOStream *proxy_connection; + + g_socket_client_emit_event (client, G_SOCKET_CLIENT_PROXY_NEGOTIATING, connectable, connection); + proxy_connection = g_proxy_connect (proxy, + connection, + proxy_addr, + cancellable, + &error_info->tmp_error); + consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING); + + g_object_unref (connection); + connection = proxy_connection; + g_object_unref (proxy); + + if (connection) + g_socket_client_emit_event (client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, connectable, connection); + } + else + { + g_set_error (&error_info->tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Proxy protocol “%s†is not supported."), + protocol); + consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING); + g_object_unref (connection); + connection = NULL; + } + } + + if (!application_proxy && connection && client->priv->tls) + { + GIOStream *tlsconn; + + tlsconn = g_tls_client_connection_new (connection, connectable, &error_info->tmp_error); + g_object_unref (connection); + connection = tlsconn; + + if (tlsconn) + { +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn), + client->priv->tls_validation_flags); +G_GNUC_END_IGNORE_DEPRECATIONS + g_socket_client_emit_event (client, G_SOCKET_CLIENT_TLS_HANDSHAKING, connectable, connection); + if (g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn), + cancellable, &error_info->tmp_error)) + { + g_socket_client_emit_event (client, G_SOCKET_CLIENT_TLS_HANDSHAKED, connectable, connection); + } + else + { + consider_tmp_error (error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING); + g_object_unref (tlsconn); + connection = NULL; + } + } + else + { + consider_tmp_error (error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING); + } + } + + if (connection && !G_IS_SOCKET_CONNECTION (connection)) + { + GSocketConnection *wrapper_connection; + + wrapper_connection = g_tcp_wrapper_connection_new (connection, socket); + g_object_unref (connection); + connection = (GIOStream *)wrapper_connection; + } + + g_object_unref (socket); + g_object_unref (address); + } + g_object_unref (enumerator); + + if (!connection) + g_propagate_error (error, g_steal_pointer (&error_info->best_error)); + socket_client_error_info_free (error_info); + + g_socket_client_emit_event (client, G_SOCKET_CLIENT_COMPLETE, connectable, connection); + return G_SOCKET_CONNECTION (connection); +} + +/** + * g_socket_client_connect_to_host: + * @client: a #GSocketClient + * @host_and_port: the name and optionally port of the host to connect to + * @default_port: the default port to connect to + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a pointer to a #GError, or %NULL + * + * This is a helper function for g_socket_client_connect(). + * + * Attempts to create a TCP connection to the named host. + * + * @host_and_port may be in any of a number of recognized formats; an IPv6 + * address, an IPv4 address, or a domain name (in which case a DNS + * lookup is performed). Quoting with [] is supported for all address + * types. A port override may be specified in the usual way with a + * colon. Ports may be given as decimal numbers or symbolic names (in + * which case an /etc/services lookup is performed). + * + * If no port override is given in @host_and_port then @default_port will be + * used as the port number to connect to. + * + * In general, @host_and_port is expected to be provided by the user (allowing + * them to give the hostname, and a port override if necessary) and + * @default_port is expected to be provided by the application. + * + * In the case that an IP address is given, a single connection + * attempt is made. In the case that a name is given, multiple + * connection attempts may be made, in turn and according to the + * number of address records in DNS, until a connection succeeds. + * + * Upon a successful connection, a new #GSocketConnection is constructed + * and returned. The caller owns this new object and must drop their + * reference to it when finished with it. + * + * In the event of any failure (DNS error, service not found, no hosts + * connectable) %NULL is returned and @error (if non-%NULL) is set + * accordingly. + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.22 + */ +GSocketConnection * +g_socket_client_connect_to_host (GSocketClient *client, + const gchar *host_and_port, + guint16 default_port, + GCancellable *cancellable, + GError **error) +{ + GSocketConnectable *connectable; + GSocketConnection *connection; + + connectable = g_network_address_parse (host_and_port, default_port, error); + if (connectable == NULL) + return NULL; + + connection = g_socket_client_connect (client, connectable, + cancellable, error); + g_object_unref (connectable); + + return connection; +} + +/** + * g_socket_client_connect_to_service: + * @client: a #GSocketConnection + * @domain: a domain name + * @service: the name of the service to connect to + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a pointer to a #GError, or %NULL + * + * Attempts to create a TCP connection to a service. + * + * This call looks up the SRV record for @service at @domain for the + * "tcp" protocol. It then attempts to connect, in turn, to each of + * the hosts providing the service until either a connection succeeds + * or there are no hosts remaining. + * + * Upon a successful connection, a new #GSocketConnection is constructed + * and returned. The caller owns this new object and must drop their + * reference to it when finished with it. + * + * In the event of any failure (DNS error, service not found, no hosts + * connectable) %NULL is returned and @error (if non-%NULL) is set + * accordingly. + * + * Returns: (transfer full): a #GSocketConnection if successful, or %NULL on error + */ +GSocketConnection * +g_socket_client_connect_to_service (GSocketClient *client, + const gchar *domain, + const gchar *service, + GCancellable *cancellable, + GError **error) +{ + GSocketConnectable *connectable; + GSocketConnection *connection; + + connectable = g_network_service_new (service, "tcp", domain); + connection = g_socket_client_connect (client, connectable, + cancellable, error); + g_object_unref (connectable); + + return connection; +} + +/** + * g_socket_client_connect_to_uri: + * @client: a #GSocketClient + * @uri: A network URI + * @default_port: the default port to connect to + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a pointer to a #GError, or %NULL + * + * This is a helper function for g_socket_client_connect(). + * + * Attempts to create a TCP connection with a network URI. + * + * @uri may be any valid URI containing an "authority" (hostname/port) + * component. If a port is not specified in the URI, @default_port + * will be used. TLS will be negotiated if #GSocketClient:tls is %TRUE. + * (#GSocketClient does not know to automatically assume TLS for + * certain URI schemes.) + * + * Using this rather than g_socket_client_connect() or + * g_socket_client_connect_to_host() allows #GSocketClient to + * determine when to use application-specific proxy protocols. + * + * Upon a successful connection, a new #GSocketConnection is constructed + * and returned. The caller owns this new object and must drop their + * reference to it when finished with it. + * + * In the event of any failure (DNS error, service not found, no hosts + * connectable) %NULL is returned and @error (if non-%NULL) is set + * accordingly. + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.26 + */ +GSocketConnection * +g_socket_client_connect_to_uri (GSocketClient *client, + const gchar *uri, + guint16 default_port, + GCancellable *cancellable, + GError **error) +{ + GSocketConnectable *connectable; + GSocketConnection *connection; + + connectable = g_network_address_parse_uri (uri, default_port, error); + if (connectable == NULL) + return NULL; + + connection = g_socket_client_connect (client, connectable, + cancellable, error); + g_object_unref (connectable); + + return connection; +} + +typedef struct +{ + GTask *task; /* unowned */ + GSocketClient *client; + + GSocketConnectable *connectable; + GSocketAddressEnumerator *enumerator; + GCancellable *enumeration_cancellable; + GCancellable *enumeration_parent_cancellable; /* (nullable) (owned) */ + gulong enumeration_cancelled_id; + + GSList *connection_attempts; + GSList *successful_connections; + SocketClientErrorInfo *error_info; + + gboolean enumerated_at_least_once; + gboolean enumeration_completed; + gboolean connection_in_progress; + gboolean completed; +} GSocketClientAsyncConnectData; + +static void connection_attempt_unref (gpointer attempt); + +static void +g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data) +{ + data->task = NULL; + g_clear_object (&data->connectable); + g_clear_object (&data->enumerator); + + g_cancellable_disconnect (data->enumeration_parent_cancellable, data->enumeration_cancelled_id); + g_clear_object (&data->enumeration_parent_cancellable); + data->enumeration_cancelled_id = 0; + g_clear_object (&data->enumeration_cancellable); + + g_slist_free_full (data->connection_attempts, connection_attempt_unref); + g_slist_free_full (data->successful_connections, connection_attempt_unref); + + g_clear_pointer (&data->error_info, socket_client_error_info_free); + + g_slice_free (GSocketClientAsyncConnectData, data); +} + +typedef struct +{ + GSocketAddress *address; + GSocket *socket; + GIOStream *connection; + GProxyAddress *proxy_addr; + GSocketClientAsyncConnectData *data; /* unowned */ + GSource *timeout_source; + GCancellable *cancellable; + GCancellable *task_cancellable; /* (owned); this is equal to g_task_get_cancellable (ConnectionAttempt.data->task), but with a longer lifetime */ + gulong cancelled_id; + grefcount ref; +} ConnectionAttempt; + +static ConnectionAttempt * +connection_attempt_new (void) +{ + ConnectionAttempt *attempt = g_new0 (ConnectionAttempt, 1); + g_ref_count_init (&attempt->ref); + return attempt; +} + +static ConnectionAttempt * +connection_attempt_ref (ConnectionAttempt *attempt) +{ + g_ref_count_inc (&attempt->ref); + return attempt; +} + +static void +connection_attempt_unref (gpointer pointer) +{ + ConnectionAttempt *attempt = pointer; + if (g_ref_count_dec (&attempt->ref)) + { + g_clear_object (&attempt->address); + g_clear_object (&attempt->socket); + g_clear_object (&attempt->connection); + g_cancellable_disconnect (attempt->task_cancellable, attempt->cancelled_id); + g_clear_object (&attempt->task_cancellable); + attempt->cancelled_id = 0; + g_clear_object (&attempt->cancellable); + g_clear_object (&attempt->proxy_addr); + if (attempt->timeout_source) + { + g_source_destroy (attempt->timeout_source); + g_source_unref (attempt->timeout_source); + } + g_free (attempt); + } +} + +static void +connection_attempt_remove (ConnectionAttempt *attempt) +{ + attempt->data->connection_attempts = g_slist_remove (attempt->data->connection_attempts, attempt); + connection_attempt_unref (attempt); +} + +static void +cancel_all_attempts (GSocketClientAsyncConnectData *data) +{ + GSList *l; + + for (l = data->connection_attempts; l; l = g_slist_next (l)) + { + ConnectionAttempt *attempt_entry = l->data; + g_cancellable_cancel (attempt_entry->cancellable); + connection_attempt_unref (attempt_entry); + } + g_slist_free (data->connection_attempts); + data->connection_attempts = NULL; + + g_slist_free_full (data->successful_connections, connection_attempt_unref); + data->successful_connections = NULL; + + g_cancellable_cancel (data->enumeration_cancellable); +} + +static void +g_socket_client_async_connect_complete (ConnectionAttempt *attempt) +{ + GSocketClientAsyncConnectData *data = attempt->data; + GError *error = NULL; + g_assert (attempt->connection); + g_assert (!data->completed); + + if (!G_IS_SOCKET_CONNECTION (attempt->connection)) + { + GSocketConnection *wrapper_connection; + + wrapper_connection = g_tcp_wrapper_connection_new (attempt->connection, attempt->socket); + g_object_unref (attempt->connection); + attempt->connection = (GIOStream *)wrapper_connection; + } + + data->completed = TRUE; + cancel_all_attempts (data); + + if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable (data->task), &error)) + { + g_debug ("GSocketClient: Connection cancelled!"); + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); + g_task_return_error (data->task, g_steal_pointer (&error)); + } + else + { + g_debug ("GSocketClient: Connection successful!"); + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, attempt->connection); + g_task_return_pointer (data->task, g_steal_pointer (&attempt->connection), g_object_unref); + } + + connection_attempt_unref (attempt); + g_object_unref (data->task); +} + + +static void +g_socket_client_enumerator_callback (GObject *object, + GAsyncResult *result, + gpointer user_data); + +static void +enumerator_next_async (GSocketClientAsyncConnectData *data, + gboolean add_task_ref) +{ + /* Each enumeration takes a ref. This arg just avoids repeated unrefs when + an enumeration starts another enumeration */ + if (add_task_ref) + g_object_ref (data->task); + + if (!data->enumerated_at_least_once) + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVING, data->connectable, NULL); + g_debug ("GSocketClient: Starting new address enumeration"); + g_socket_address_enumerator_next_async (data->enumerator, + data->enumeration_cancellable, + g_socket_client_enumerator_callback, + data); +} + +static void try_next_connection_or_finish (GSocketClientAsyncConnectData *, gboolean); + +static void +g_socket_client_tls_handshake_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ConnectionAttempt *attempt = user_data; + GSocketClientAsyncConnectData *data = attempt->data; + + if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (object), + result, + &data->error_info->tmp_error)) + { + g_object_unref (attempt->connection); + attempt->connection = G_IO_STREAM (object); + + g_debug ("GSocketClient: TLS handshake succeeded"); + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_TLS_HANDSHAKED, data->connectable, attempt->connection); + g_socket_client_async_connect_complete (attempt); + } + else + { + g_object_unref (object); + connection_attempt_unref (attempt); + + g_debug ("GSocketClient: TLS handshake failed: %s", data->error_info->tmp_error->message); + consider_tmp_error (data->error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING); + try_next_connection_or_finish (data, TRUE); + } +} + +static void +g_socket_client_tls_handshake (ConnectionAttempt *attempt) +{ + GSocketClientAsyncConnectData *data = attempt->data; + GIOStream *tlsconn; + + if (!data->client->priv->tls) + { + g_socket_client_async_connect_complete (attempt); + return; + } + + g_debug ("GSocketClient: Starting TLS handshake"); + tlsconn = g_tls_client_connection_new (attempt->connection, + data->connectable, + &data->error_info->tmp_error); + if (tlsconn) + { +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn), + data->client->priv->tls_validation_flags); +G_GNUC_END_IGNORE_DEPRECATIONS + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_TLS_HANDSHAKING, data->connectable, G_IO_STREAM (tlsconn)); + g_tls_connection_handshake_async (G_TLS_CONNECTION (tlsconn), + G_PRIORITY_DEFAULT, + g_task_get_cancellable (data->task), + g_socket_client_tls_handshake_callback, + attempt); + } + else + { + connection_attempt_unref (attempt); + + consider_tmp_error (data->error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING); + try_next_connection_or_finish (data, TRUE); + } +} + +static void +g_socket_client_proxy_connect_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ConnectionAttempt *attempt = user_data; + GSocketClientAsyncConnectData *data = attempt->data; + + g_object_unref (attempt->connection); + attempt->connection = g_proxy_connect_finish (G_PROXY (object), + result, + &data->error_info->tmp_error); + if (attempt->connection) + { + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, attempt->connection); + g_socket_client_tls_handshake (attempt); + } + else + { + connection_attempt_unref (attempt); + + consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING); + try_next_connection_or_finish (data, TRUE); + } +} + +static void +complete_connection_with_error (GSocketClientAsyncConnectData *data, + GError *error) +{ + g_debug ("GSocketClient: Connection failed: %s", error->message); + g_assert (!data->completed); + + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); + data->completed = TRUE; + cancel_all_attempts (data); + g_task_return_error (data->task, error); +} + +static gboolean +task_completed_or_cancelled (GSocketClientAsyncConnectData *data) +{ + GTask *task = data->task; + GCancellable *cancellable = g_task_get_cancellable (task); + GError *error = NULL; + + if (data->completed) + return TRUE; + else if (g_cancellable_set_error_if_cancelled (cancellable, &error)) + { + complete_connection_with_error (data, g_steal_pointer (&error)); + return TRUE; + } + else + return FALSE; +} + +static gboolean +try_next_successful_connection (GSocketClientAsyncConnectData *data) +{ + ConnectionAttempt *attempt; + const gchar *protocol; + GProxy *proxy; + + if (data->connection_in_progress) + return FALSE; + + g_assert (data->successful_connections != NULL); + attempt = data->successful_connections->data; + g_assert (attempt != NULL); + data->successful_connections = g_slist_remove (data->successful_connections, attempt); + data->connection_in_progress = TRUE; + + g_debug ("GSocketClient: Starting application layer connection"); + + if (!attempt->proxy_addr) + { + g_socket_client_tls_handshake (g_steal_pointer (&attempt)); + return TRUE; + } + + protocol = g_proxy_address_get_protocol (attempt->proxy_addr); + + /* The connection should not be anything other than TCP, + * but let's put a safety guard in case + */ + if (!G_IS_TCP_CONNECTION (attempt->connection)) + { + g_critical ("Trying to proxy over non-TCP connection, this is " + "most likely a bug in GLib IO library."); + + g_set_error_literal (&data->error_info->tmp_error, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Proxying over a non-TCP connection is not supported.")); + consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING); + } + else if (g_hash_table_contains (data->client->priv->app_proxies, protocol)) + { + /* Simply complete the connection, we don't want to do TLS handshake + * as the application proxy handling may need proxy handshake first */ + g_socket_client_async_connect_complete (g_steal_pointer (&attempt)); + return TRUE; + } + else if ((proxy = g_proxy_get_default_for_protocol (protocol))) + { + GIOStream *connection = attempt->connection; + GProxyAddress *proxy_addr = attempt->proxy_addr; + + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATING, data->connectable, attempt->connection); + g_debug ("GSocketClient: Starting proxy connection"); + g_proxy_connect_async (proxy, + connection, + proxy_addr, + g_task_get_cancellable (data->task), + g_socket_client_proxy_connect_callback, + g_steal_pointer (&attempt)); + g_object_unref (proxy); + return TRUE; + } + else + { + g_set_error (&data->error_info->tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Proxy protocol “%s†is not supported."), + protocol); + consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING); + } + + data->connection_in_progress = FALSE; + g_clear_pointer (&attempt, connection_attempt_unref); + return FALSE; /* All non-return paths are failures */ +} + +static void +try_next_connection_or_finish (GSocketClientAsyncConnectData *data, + gboolean end_current_connection) +{ + if (end_current_connection) + data->connection_in_progress = FALSE; + + if (data->connection_in_progress) + return; + + /* Keep trying successful connections until one works, each iteration pops one */ + while (data->successful_connections) + { + if (try_next_successful_connection (data)) + return; + } + + if (!data->enumeration_completed) + { + enumerator_next_async (data, FALSE); + return; + } + + complete_connection_with_error (data, g_steal_pointer (&data->error_info->best_error)); +} + +static void +g_socket_client_connected_callback (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + ConnectionAttempt *attempt = user_data; + GSocketClientAsyncConnectData *data = attempt->data; + + if (task_completed_or_cancelled (data) || g_cancellable_is_cancelled (attempt->cancellable)) + { + g_object_unref (data->task); + connection_attempt_unref (attempt); + return; + } + + if (attempt->timeout_source) + { + g_source_destroy (attempt->timeout_source); + g_clear_pointer (&attempt->timeout_source, g_source_unref); + } + + if (!g_socket_connection_connect_finish (G_SOCKET_CONNECTION (source), + result, &data->error_info->tmp_error)) + { + if (!g_cancellable_is_cancelled (attempt->cancellable)) + { + g_debug ("GSocketClient: Connection attempt failed: %s", data->error_info->tmp_error->message); + clarify_connect_error (data->error_info->tmp_error, data->connectable, attempt->address); + consider_tmp_error (data->error_info, G_SOCKET_CLIENT_CONNECTING); + connection_attempt_remove (attempt); + connection_attempt_unref (attempt); + try_next_connection_or_finish (data, FALSE); + } + else /* Silently ignore cancelled attempts */ + { + g_clear_error (&data->error_info->tmp_error); + g_object_unref (data->task); + connection_attempt_unref (attempt); + } + + return; + } + + g_socket_connection_set_cached_remote_address ((GSocketConnection*)attempt->connection, NULL); + g_debug ("GSocketClient: TCP connection successful"); + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, data->connectable, attempt->connection); + + /* wrong, but backward compatible */ + g_socket_set_blocking (attempt->socket, TRUE); + + /* This ends the parallel "happy eyeballs" portion of connecting. + Now that we have a successful tcp connection we will attempt to connect + at the TLS/Proxy layer. If those layers fail we will move on to the next + connection. + */ + connection_attempt_remove (attempt); + data->successful_connections = g_slist_append (data->successful_connections, g_steal_pointer (&attempt)); + try_next_connection_or_finish (data, FALSE); +} + +static gboolean +on_connection_attempt_timeout (gpointer data) +{ + ConnectionAttempt *attempt = data; + + if (!attempt->data->enumeration_completed) + { + g_debug ("GSocketClient: Timeout reached, trying another enumeration"); + enumerator_next_async (attempt->data, TRUE); + } + + g_clear_pointer (&attempt->timeout_source, g_source_unref); + return G_SOURCE_REMOVE; +} + +static void +on_connection_cancelled (GCancellable *cancellable, + gpointer data) +{ + GCancellable *linked_cancellable = G_CANCELLABLE (data); + + g_cancellable_cancel (linked_cancellable); +} + +static void +g_socket_client_enumerator_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSocketClientAsyncConnectData *data = user_data; + GSocketAddress *address = NULL; + GSocket *socket; + ConnectionAttempt *attempt; + + if (task_completed_or_cancelled (data)) + { + g_object_unref (data->task); + return; + } + + address = g_socket_address_enumerator_next_finish (data->enumerator, + result, &data->error_info->tmp_error); + if (address == NULL) + { + if (G_UNLIKELY (data->enumeration_completed)) + return; + + data->enumeration_completed = TRUE; + g_debug ("GSocketClient: Address enumeration completed (out of addresses)"); + + /* As per API docs: We only care about error if it's the first call, + after that the enumerator is done. + + Note that we don't care about cancellation errors because + task_completed_or_cancelled() above should handle that. + + If this fails and nothing is in progress then we will complete task here. + */ + if ((data->enumerated_at_least_once && !data->connection_attempts && !data->connection_in_progress) || + !data->enumerated_at_least_once) + { + g_debug ("GSocketClient: Address enumeration failed: %s", + data->error_info->tmp_error ? data->error_info->tmp_error->message : NULL); + consider_tmp_error (data->error_info, G_SOCKET_CLIENT_RESOLVING); + g_assert (data->error_info->best_error); + complete_connection_with_error (data, g_steal_pointer (&data->error_info->best_error)); + } + + /* Enumeration should never trigger again, drop our ref */ + g_object_unref (data->task); + return; + } + + g_debug ("GSocketClient: Address enumeration succeeded"); + if (!data->enumerated_at_least_once) + { + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVED, + data->connectable, NULL); + data->enumerated_at_least_once = TRUE; + } + + socket = create_socket (data->client, address, &data->error_info->tmp_error); + if (socket == NULL) + { + g_object_unref (address); + consider_tmp_error (data->error_info, G_SOCKET_CLIENT_CONNECTING); + enumerator_next_async (data, FALSE); + return; + } + + attempt = connection_attempt_new (); + attempt->data = data; + attempt->socket = socket; + attempt->address = address; + attempt->cancellable = g_cancellable_new (); + attempt->connection = (GIOStream *)g_socket_connection_factory_create_connection (socket); + attempt->timeout_source = g_timeout_source_new (HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS); + + if (G_IS_PROXY_ADDRESS (address) && data->client->priv->enable_proxy) + attempt->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address)); + + g_source_set_callback (attempt->timeout_source, on_connection_attempt_timeout, attempt, NULL); + g_source_attach (attempt->timeout_source, g_task_get_context (data->task)); + data->connection_attempts = g_slist_append (data->connection_attempts, attempt); + + if (g_task_get_cancellable (data->task)) + { + attempt->task_cancellable = g_object_ref (g_task_get_cancellable (data->task)); + attempt->cancelled_id = + g_cancellable_connect (attempt->task_cancellable, G_CALLBACK (on_connection_cancelled), + g_object_ref (attempt->cancellable), g_object_unref); + } + + g_socket_connection_set_cached_remote_address ((GSocketConnection *)attempt->connection, address); + g_debug ("GSocketClient: Starting TCP connection attempt"); + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTING, data->connectable, attempt->connection); + g_socket_connection_connect_async (G_SOCKET_CONNECTION (attempt->connection), + address, + attempt->cancellable, + g_socket_client_connected_callback, connection_attempt_ref (attempt)); +} + +/** + * g_socket_client_connect_async: + * @client: a #GSocketClient + * @connectable: a #GSocketConnectable specifying the remote address. + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback + * + * This is the asynchronous version of g_socket_client_connect(). + * + * You may wish to prefer the asynchronous version even in synchronous + * command line programs because, since 2.60, it implements + * [RFC 8305](https://tools.ietf.org/html/rfc8305) "Happy Eyeballs" + * recommendations to work around long connection timeouts in networks + * where IPv6 is broken by performing an IPv4 connection simultaneously + * without waiting for IPv6 to time out, which is not supported by the + * synchronous call. (This is not an API guarantee, and may change in + * the future.) + * + * When the operation is finished @callback will be + * called. You can then call g_socket_client_connect_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_socket_client_connect_async (GSocketClient *client, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSocketClientAsyncConnectData *data; + + g_return_if_fail (G_IS_SOCKET_CLIENT (client)); + + data = g_slice_new0 (GSocketClientAsyncConnectData); + data->client = client; + data->connectable = g_object_ref (connectable); + data->error_info = socket_client_error_info_new (); + + if (can_use_proxy (client)) + { + data->enumerator = g_socket_connectable_proxy_enumerate (connectable); + if (client->priv->proxy_resolver && + G_IS_PROXY_ADDRESS_ENUMERATOR (data->enumerator)) + { + g_object_set (G_OBJECT (data->enumerator), + "proxy-resolver", client->priv->proxy_resolver, + NULL); + } + } + else + data->enumerator = g_socket_connectable_enumerate (connectable); + + /* This function tries to match the behavior of g_socket_client_connect () + which is simple enough but much of it is done in parallel to be as responsive + as possible as per Happy Eyeballs (RFC 8305). This complicates flow quite a + bit but we can describe it in 3 sections: + + Firstly we have address enumeration (DNS): + - This may be triggered multiple times by enumerator_next_async(). + - It also has its own cancellable (data->enumeration_cancellable). + - Enumeration is done lazily because GNetworkAddressAddressEnumerator + also does work in parallel and may lazily add new addresses. + - If the first enumeration errors then the task errors. Otherwise all enumerations + will potentially be used (until task or enumeration is cancelled). + + Then we start attempting connections (TCP): + - Each connection is independent and kept in a ConnectionAttempt object. + - They each hold a ref on the main task and have their own cancellable. + - Multiple attempts may happen in parallel as per Happy Eyeballs. + - Upon failure or timeouts more connection attempts are made. + - If no connections succeed the task errors. + - Upon success they are kept in a list of successful connections. + + Lastly we connect at the application layer (TLS, Proxies): + - These are done in serial. + - The reasoning here is that Happy Eyeballs is about making bad connections responsive + at the IP/TCP layers. Issues at the application layer are generally not due to + connectivity issues but rather misconfiguration. + - Upon failure it will try the next TCP connection until it runs out and + the task errors. + - Upon success it cancels everything remaining (enumeration and connections) + and returns the connection. + */ + + data->task = g_task_new (client, cancellable, callback, user_data); + g_task_set_check_cancellable (data->task, FALSE); /* We handle this manually */ + g_task_set_source_tag (data->task, g_socket_client_connect_async); + g_task_set_task_data (data->task, data, (GDestroyNotify)g_socket_client_async_connect_data_free); + + data->enumeration_cancellable = g_cancellable_new (); + if (cancellable) + { + data->enumeration_parent_cancellable = g_object_ref (cancellable); + data->enumeration_cancelled_id = + g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled), + g_object_ref (data->enumeration_cancellable), g_object_unref); + } + + enumerator_next_async (data, FALSE); +} + +/** + * g_socket_client_connect_to_host_async: + * @client: a #GSocketClient + * @host_and_port: the name and optionally the port of the host to connect to + * @default_port: the default port to connect to + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback + * + * This is the asynchronous version of g_socket_client_connect_to_host(). + * + * When the operation is finished @callback will be + * called. You can then call g_socket_client_connect_to_host_finish() to get + * the result of the operation. + * + * Since: 2.22 + */ +void +g_socket_client_connect_to_host_async (GSocketClient *client, + const gchar *host_and_port, + guint16 default_port, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSocketConnectable *connectable; + GError *error; + + error = NULL; + connectable = g_network_address_parse (host_and_port, default_port, + &error); + if (connectable == NULL) + { + g_task_report_error (client, callback, user_data, + g_socket_client_connect_to_host_async, + error); + } + else + { + g_socket_client_connect_async (client, + connectable, cancellable, + callback, user_data); + g_object_unref (connectable); + } +} + +/** + * g_socket_client_connect_to_service_async: + * @client: a #GSocketClient + * @domain: a domain name + * @service: the name of the service to connect to + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback + * + * This is the asynchronous version of + * g_socket_client_connect_to_service(). + * + * Since: 2.22 + */ +void +g_socket_client_connect_to_service_async (GSocketClient *client, + const gchar *domain, + const gchar *service, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSocketConnectable *connectable; + + connectable = g_network_service_new (service, "tcp", domain); + g_socket_client_connect_async (client, + connectable, cancellable, + callback, user_data); + g_object_unref (connectable); +} + +/** + * g_socket_client_connect_to_uri_async: + * @client: a #GSocketClient + * @uri: a network uri + * @default_port: the default port to connect to + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback + * + * This is the asynchronous version of g_socket_client_connect_to_uri(). + * + * When the operation is finished @callback will be + * called. You can then call g_socket_client_connect_to_uri_finish() to get + * the result of the operation. + * + * Since: 2.26 + */ +void +g_socket_client_connect_to_uri_async (GSocketClient *client, + const gchar *uri, + guint16 default_port, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSocketConnectable *connectable; + GError *error; + + error = NULL; + connectable = g_network_address_parse_uri (uri, default_port, &error); + if (connectable == NULL) + { + g_task_report_error (client, callback, user_data, + g_socket_client_connect_to_uri_async, + error); + } + else + { + g_debug("g_socket_client_connect_to_uri_async"); + g_socket_client_connect_async (client, + connectable, cancellable, + callback, user_data); + g_object_unref (connectable); + } +} + + +/** + * g_socket_client_connect_finish: + * @client: a #GSocketClient. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an async connect operation. See g_socket_client_connect_async() + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.22 + */ +GSocketConnection * +g_socket_client_connect_finish (GSocketClient *client, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, client), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +/** + * g_socket_client_connect_to_host_finish: + * @client: a #GSocketClient. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an async connect operation. See g_socket_client_connect_to_host_async() + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.22 + */ +GSocketConnection * +g_socket_client_connect_to_host_finish (GSocketClient *client, + GAsyncResult *result, + GError **error) +{ + return g_socket_client_connect_finish (client, result, error); +} + +/** + * g_socket_client_connect_to_service_finish: + * @client: a #GSocketClient. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an async connect operation. See g_socket_client_connect_to_service_async() + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.22 + */ +GSocketConnection * +g_socket_client_connect_to_service_finish (GSocketClient *client, + GAsyncResult *result, + GError **error) +{ + return g_socket_client_connect_finish (client, result, error); +} + +/** + * g_socket_client_connect_to_uri_finish: + * @client: a #GSocketClient. + * @result: a #GAsyncResult. + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an async connect operation. See g_socket_client_connect_to_uri_async() + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.26 + */ +GSocketConnection * +g_socket_client_connect_to_uri_finish (GSocketClient *client, + GAsyncResult *result, + GError **error) +{ + return g_socket_client_connect_finish (client, result, error); +} + +/** + * g_socket_client_add_application_proxy: + * @client: a #GSocketClient + * @protocol: The proxy protocol + * + * Enable proxy protocols to be handled by the application. When the + * indicated proxy protocol is returned by the #GProxyResolver, + * #GSocketClient will consider this protocol as supported but will + * not try to find a #GProxy instance to handle handshaking. The + * application must check for this case by calling + * g_socket_connection_get_remote_address() on the returned + * #GSocketConnection, and seeing if it's a #GProxyAddress of the + * appropriate type, to determine whether or not it needs to handle + * the proxy handshaking itself. + * + * This should be used for proxy protocols that are dialects of + * another protocol such as HTTP proxy. It also allows cohabitation of + * proxy protocols that are reused between protocols. A good example + * is HTTP. It can be used to proxy HTTP, FTP and Gopher and can also + * be use as generic socket proxy through the HTTP CONNECT method. + * + * When the proxy is detected as being an application proxy, TLS handshake + * will be skipped. This is required to let the application do the proxy + * specific handshake. + */ +void +g_socket_client_add_application_proxy (GSocketClient *client, + const gchar *protocol) +{ + g_hash_table_add (client->priv->app_proxies, g_strdup (protocol)); +} diff --git a/gio/gsocketclient.h b/gio/gsocketclient.h new file mode 100644 index 0000000..8f86ce8 --- /dev/null +++ b/gio/gsocketclient.h @@ -0,0 +1,197 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008, 2009 Codethink Limited + * Copyright © 2009 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Alexander Larsson + */ + +#ifndef __G_SOCKET_CLIENT_H__ +#define __G_SOCKET_CLIENT_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_CLIENT (g_socket_client_get_type ()) +#define G_SOCKET_CLIENT(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SOCKET_CLIENT, GSocketClient)) +#define G_SOCKET_CLIENT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SOCKET_CLIENT, GSocketClientClass)) +#define G_IS_SOCKET_CLIENT(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SOCKET_CLIENT)) +#define G_IS_SOCKET_CLIENT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SOCKET_CLIENT)) +#define G_SOCKET_CLIENT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SOCKET_CLIENT, GSocketClientClass)) + +typedef struct _GSocketClientPrivate GSocketClientPrivate; +typedef struct _GSocketClientClass GSocketClientClass; + +struct _GSocketClientClass +{ + GObjectClass parent_class; + + void (* event) (GSocketClient *client, + GSocketClientEvent event, + GSocketConnectable *connectable, + GIOStream *connection); + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); +}; + +struct _GSocketClient +{ + GObject parent_instance; + GSocketClientPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_client_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketClient *g_socket_client_new (void); + +GLIB_AVAILABLE_IN_ALL +GSocketFamily g_socket_client_get_family (GSocketClient *client); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_set_family (GSocketClient *client, + GSocketFamily family); +GLIB_AVAILABLE_IN_ALL +GSocketType g_socket_client_get_socket_type (GSocketClient *client); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_set_socket_type (GSocketClient *client, + GSocketType type); +GLIB_AVAILABLE_IN_ALL +GSocketProtocol g_socket_client_get_protocol (GSocketClient *client); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_set_protocol (GSocketClient *client, + GSocketProtocol protocol); +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_socket_client_get_local_address (GSocketClient *client); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_set_local_address (GSocketClient *client, + GSocketAddress *address); +GLIB_AVAILABLE_IN_ALL +guint g_socket_client_get_timeout (GSocketClient *client); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_set_timeout (GSocketClient *client, + guint timeout); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_client_get_enable_proxy (GSocketClient *client); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_set_enable_proxy (GSocketClient *client, + gboolean enable); + +GLIB_AVAILABLE_IN_2_28 +gboolean g_socket_client_get_tls (GSocketClient *client); +GLIB_AVAILABLE_IN_2_28 +void g_socket_client_set_tls (GSocketClient *client, + gboolean tls); +GLIB_DEPRECATED_IN_2_72 +GTlsCertificateFlags g_socket_client_get_tls_validation_flags (GSocketClient *client); +GLIB_DEPRECATED_IN_2_72 +void g_socket_client_set_tls_validation_flags (GSocketClient *client, + GTlsCertificateFlags flags); +GLIB_AVAILABLE_IN_2_36 +GProxyResolver *g_socket_client_get_proxy_resolver (GSocketClient *client); +GLIB_AVAILABLE_IN_2_36 +void g_socket_client_set_proxy_resolver (GSocketClient *client, + GProxyResolver *proxy_resolver); + +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_client_connect (GSocketClient *client, + GSocketConnectable *connectable, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_client_connect_to_host (GSocketClient *client, + const gchar *host_and_port, + guint16 default_port, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_client_connect_to_service (GSocketClient *client, + const gchar *domain, + const gchar *service, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_26 +GSocketConnection * g_socket_client_connect_to_uri (GSocketClient *client, + const gchar *uri, + guint16 default_port, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_connect_async (GSocketClient *client, + GSocketConnectable *connectable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_client_connect_finish (GSocketClient *client, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_connect_to_host_async (GSocketClient *client, + const gchar *host_and_port, + guint16 default_port, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_client_connect_to_host_finish (GSocketClient *client, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_socket_client_connect_to_service_async (GSocketClient *client, + const gchar *domain, + const gchar *service, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_client_connect_to_service_finish (GSocketClient *client, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_connect_to_uri_async (GSocketClient *client, + const gchar *uri, + guint16 default_port, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_client_connect_to_uri_finish (GSocketClient *client, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_socket_client_add_application_proxy (GSocketClient *client, + const gchar *protocol); + +G_END_DECLS + +#endif /* __G_SOCKET_CLIENT_H___ */ diff --git a/gio/gsocketconnectable.c b/gio/gsocketconnectable.c new file mode 100644 index 0000000..e999e65 --- /dev/null +++ b/gio/gsocketconnectable.c @@ -0,0 +1,179 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "gsocketconnectable.h" +#include "glibintl.h" + + +/** + * SECTION:gsocketconnectable + * @short_description: Interface for potential socket endpoints + * @include: gio/gio.h + * + * Objects that describe one or more potential socket endpoints + * implement #GSocketConnectable. Callers can then use + * g_socket_connectable_enumerate() to get a #GSocketAddressEnumerator + * to try out each socket address in turn until one succeeds, as shown + * in the sample code below. + * + * |[ + * MyConnectionType * + * connect_to_host (const char *hostname, + * guint16 port, + * GCancellable *cancellable, + * GError **error) + * { + * MyConnection *conn = NULL; + * GSocketConnectable *addr; + * GSocketAddressEnumerator *enumerator; + * GSocketAddress *sockaddr; + * GError *conn_error = NULL; + * + * addr = g_network_address_new (hostname, port); + * enumerator = g_socket_connectable_enumerate (addr); + * g_object_unref (addr); + * + * // Try each sockaddr until we succeed. Record the first connection error, + * // but not any further ones (since they'll probably be basically the same + * // as the first). + * while (!conn && (sockaddr = g_socket_address_enumerator_next (enumerator, cancellable, error)) + * { + * conn = connect_to_sockaddr (sockaddr, conn_error ? NULL : &conn_error); + * g_object_unref (sockaddr); + * } + * g_object_unref (enumerator); + * + * if (conn) + * { + * if (conn_error) + * { + * // We couldn't connect to the first address, but we succeeded + * // in connecting to a later address. + * g_error_free (conn_error); + * } + * return conn; + * } + * else if (error) + * { + * /// Either initial lookup failed, or else the caller cancelled us. + * if (conn_error) + * g_error_free (conn_error); + * return NULL; + * } + * else + * { + * g_error_propagate (error, conn_error); + * return NULL; + * } + * } + * ]| + */ + + +typedef GSocketConnectableIface GSocketConnectableInterface; +G_DEFINE_INTERFACE (GSocketConnectable, g_socket_connectable, G_TYPE_OBJECT) + +static void +g_socket_connectable_default_init (GSocketConnectableInterface *iface) +{ +} + +/** + * g_socket_connectable_enumerate: + * @connectable: a #GSocketConnectable + * + * Creates a #GSocketAddressEnumerator for @connectable. + * + * Returns: (transfer full): a new #GSocketAddressEnumerator. + * + * Since: 2.22 + */ +GSocketAddressEnumerator * +g_socket_connectable_enumerate (GSocketConnectable *connectable) +{ + GSocketConnectableIface *iface; + + g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (connectable), NULL); + + iface = G_SOCKET_CONNECTABLE_GET_IFACE (connectable); + + return (* iface->enumerate) (connectable); +} + +/** + * g_socket_connectable_proxy_enumerate: + * @connectable: a #GSocketConnectable + * + * Creates a #GSocketAddressEnumerator for @connectable that will + * return a #GProxyAddress for each of its addresses that you must connect + * to via a proxy. + * + * If @connectable does not implement + * g_socket_connectable_proxy_enumerate(), this will fall back to + * calling g_socket_connectable_enumerate(). + * + * Returns: (transfer full): a new #GSocketAddressEnumerator. + * + * Since: 2.26 + */ +GSocketAddressEnumerator * +g_socket_connectable_proxy_enumerate (GSocketConnectable *connectable) +{ + GSocketConnectableIface *iface; + + g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (connectable), NULL); + + iface = G_SOCKET_CONNECTABLE_GET_IFACE (connectable); + + if (iface->proxy_enumerate) + return (* iface->proxy_enumerate) (connectable); + else + return (* iface->enumerate) (connectable); +} + +/** + * g_socket_connectable_to_string: + * @connectable: a #GSocketConnectable + * + * Format a #GSocketConnectable as a string. This is a human-readable format for + * use in debugging output, and is not a stable serialization format. It is not + * suitable for use in user interfaces as it exposes too much information for a + * user. + * + * If the #GSocketConnectable implementation does not support string formatting, + * the implementation’s type name will be returned as a fallback. + * + * Returns: (transfer full): the formatted string + * + * Since: 2.48 + */ +gchar * +g_socket_connectable_to_string (GSocketConnectable *connectable) +{ + GSocketConnectableIface *iface; + + g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (connectable), NULL); + + iface = G_SOCKET_CONNECTABLE_GET_IFACE (connectable); + + if (iface->to_string != NULL) + return iface->to_string (connectable); + else + return g_strdup (G_OBJECT_TYPE_NAME (connectable)); +} diff --git a/gio/gsocketconnectable.h b/gio/gsocketconnectable.h new file mode 100644 index 0000000..da88214 --- /dev/null +++ b/gio/gsocketconnectable.h @@ -0,0 +1,81 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_SOCKET_CONNECTABLE_H__ +#define __G_SOCKET_CONNECTABLE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_CONNECTABLE (g_socket_connectable_get_type ()) +#define G_SOCKET_CONNECTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SOCKET_CONNECTABLE, GSocketConnectable)) +#define G_IS_SOCKET_CONNECTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SOCKET_CONNECTABLE)) +#define G_SOCKET_CONNECTABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_SOCKET_CONNECTABLE, GSocketConnectableIface)) + +/** + * GSocketConnectable: + * + * Interface for objects that contain or generate a #GSocketAddress. + */ +typedef struct _GSocketConnectableIface GSocketConnectableIface; + +/** + * GSocketConnectableIface: + * @g_iface: The parent interface. + * @enumerate: Creates a #GSocketAddressEnumerator + * @proxy_enumerate: Creates a #GProxyAddressEnumerator + * @to_string: Format the connectable’s address as a string for debugging. + * Implementing this is optional. (Since: 2.48) + * + * Provides an interface for returning a #GSocketAddressEnumerator + * and #GProxyAddressEnumerator + */ +struct _GSocketConnectableIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + GSocketAddressEnumerator * (* enumerate) (GSocketConnectable *connectable); + + GSocketAddressEnumerator * (* proxy_enumerate) (GSocketConnectable *connectable); + + gchar * (* to_string) (GSocketConnectable *connectable); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_connectable_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketAddressEnumerator *g_socket_connectable_enumerate (GSocketConnectable *connectable); + +GLIB_AVAILABLE_IN_ALL +GSocketAddressEnumerator *g_socket_connectable_proxy_enumerate (GSocketConnectable *connectable); + +GLIB_AVAILABLE_IN_2_48 +gchar *g_socket_connectable_to_string (GSocketConnectable *connectable); + +G_END_DECLS + + +#endif /* __G_SOCKET_CONNECTABLE_H__ */ diff --git a/gio/gsocketconnection.c b/gio/gsocketconnection.c new file mode 100644 index 0000000..64fe975 --- /dev/null +++ b/gio/gsocketconnection.c @@ -0,0 +1,687 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * © 2008 codethink + * Copyright © 2009 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + * Alexander Larsson + */ + +#include "config.h" + +#include "gsocketconnection.h" + +#include "gsocketoutputstream.h" +#include "gsocketinputstream.h" +#include "gioprivate.h" +#include +#include +#include "gunixconnection.h" +#include "gtcpconnection.h" +#include "glibintl.h" + + +/** + * SECTION:gsocketconnection + * @short_description: A socket connection + * @include: gio/gio.h + * @see_also: #GIOStream, #GSocketClient, #GSocketListener + * + * #GSocketConnection is a #GIOStream for a connected socket. They + * can be created either by #GSocketClient when connecting to a host, + * or by #GSocketListener when accepting a new client. + * + * The type of the #GSocketConnection object returned from these calls + * depends on the type of the underlying socket that is in use. For + * instance, for a TCP/IP connection it will be a #GTcpConnection. + * + * Choosing what type of object to construct is done with the socket + * connection factory, and it is possible for 3rd parties to register + * custom socket connection types for specific combination of socket + * family/type/protocol using g_socket_connection_factory_register_type(). + * + * To close a #GSocketConnection, use g_io_stream_close(). Closing both + * substreams of the #GIOStream separately will not close the underlying + * #GSocket. + * + * Since: 2.22 + */ + +enum +{ + PROP_NONE, + PROP_SOCKET, +}; + +struct _GSocketConnectionPrivate +{ + GSocket *socket; + GInputStream *input_stream; + GOutputStream *output_stream; + + GSocketAddress *cached_remote_address; + + gboolean in_dispose; +}; + +static gboolean g_socket_connection_close (GIOStream *stream, + GCancellable *cancellable, + GError **error); +static void g_socket_connection_close_async (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static gboolean g_socket_connection_close_finish (GIOStream *stream, + GAsyncResult *result, + GError **error); + +G_DEFINE_TYPE_WITH_PRIVATE (GSocketConnection, g_socket_connection, G_TYPE_IO_STREAM) + +static GInputStream * +g_socket_connection_get_input_stream (GIOStream *io_stream) +{ + GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream); + + if (connection->priv->input_stream == NULL) + connection->priv->input_stream = (GInputStream *) + _g_socket_input_stream_new (connection->priv->socket); + + return connection->priv->input_stream; +} + +static GOutputStream * +g_socket_connection_get_output_stream (GIOStream *io_stream) +{ + GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream); + + if (connection->priv->output_stream == NULL) + connection->priv->output_stream = (GOutputStream *) + _g_socket_output_stream_new (connection->priv->socket); + + return connection->priv->output_stream; +} + +/** + * g_socket_connection_is_connected: + * @connection: a #GSocketConnection + * + * Checks if @connection is connected. This is equivalent to calling + * g_socket_is_connected() on @connection's underlying #GSocket. + * + * Returns: whether @connection is connected + * + * Since: 2.32 + */ +gboolean +g_socket_connection_is_connected (GSocketConnection *connection) +{ + return g_socket_is_connected (connection->priv->socket); +} + +/** + * g_socket_connection_connect: + * @connection: a #GSocketConnection + * @address: a #GSocketAddress specifying the remote address. + * @cancellable: (nullable): a %GCancellable or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Connect @connection to the specified remote address. + * + * Returns: %TRUE if the connection succeeded, %FALSE on error + * + * Since: 2.32 + */ +gboolean +g_socket_connection_connect (GSocketConnection *connection, + GSocketAddress *address, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE); + g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE); + + return g_socket_connect (connection->priv->socket, address, + cancellable, error); +} + +static gboolean g_socket_connection_connect_callback (GSocket *socket, + GIOCondition condition, + gpointer user_data); + +/** + * g_socket_connection_connect_async: + * @connection: a #GSocketConnection + * @address: a #GSocketAddress specifying the remote address. + * @cancellable: (nullable): a %GCancellable or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback + * + * Asynchronously connect @connection to the specified remote address. + * + * This clears the #GSocket:blocking flag on @connection's underlying + * socket if it is currently set. + * + * Use g_socket_connection_connect_finish() to retrieve the result. + * + * Since: 2.32 + */ +void +g_socket_connection_connect_async (GSocketConnection *connection, + GSocketAddress *address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + GError *tmp_error = NULL; + + g_return_if_fail (G_IS_SOCKET_CONNECTION (connection)); + g_return_if_fail (G_IS_SOCKET_ADDRESS (address)); + + task = g_task_new (connection, cancellable, callback, user_data); + g_task_set_source_tag (task, g_socket_connection_connect_async); + + g_socket_set_blocking (connection->priv->socket, FALSE); + + if (g_socket_connect (connection->priv->socket, address, + cancellable, &tmp_error)) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + } + else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING)) + { + GSource *source; + + g_error_free (tmp_error); + source = g_socket_create_source (connection->priv->socket, + G_IO_OUT, cancellable); + g_task_attach_source (task, source, + (GSourceFunc) g_socket_connection_connect_callback); + g_source_unref (source); + } + else + { + g_task_return_error (task, tmp_error); + g_object_unref (task); + } +} + +static gboolean +g_socket_connection_connect_callback (GSocket *socket, + GIOCondition condition, + gpointer user_data) +{ + GTask *task = user_data; + GSocketConnection *connection = g_task_get_source_object (task); + GError *error = NULL; + + if (g_socket_check_connect_result (connection->priv->socket, &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); + + g_object_unref (task); + return FALSE; +} + +/** + * g_socket_connection_connect_finish: + * @connection: a #GSocketConnection + * @result: the #GAsyncResult + * @error: #GError for error reporting, or %NULL to ignore. + * + * Gets the result of a g_socket_connection_connect_async() call. + * + * Returns: %TRUE if the connection succeeded, %FALSE on error + * + * Since: 2.32 + */ +gboolean +g_socket_connection_connect_finish (GSocketConnection *connection, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE); + g_return_val_if_fail (g_task_is_valid (result, connection), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +/** + * g_socket_connection_get_socket: + * @connection: a #GSocketConnection + * + * Gets the underlying #GSocket object of the connection. + * This can be useful if you want to do something unusual on it + * not supported by the #GSocketConnection APIs. + * + * Returns: (transfer none): a #GSocket or %NULL on error. + * + * Since: 2.22 + */ +GSocket * +g_socket_connection_get_socket (GSocketConnection *connection) +{ + g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), NULL); + + return connection->priv->socket; +} + +/** + * g_socket_connection_get_local_address: + * @connection: a #GSocketConnection + * @error: #GError for error reporting, or %NULL to ignore. + * + * Try to get the local address of a socket connection. + * + * Returns: (transfer full): a #GSocketAddress or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GSocketAddress * +g_socket_connection_get_local_address (GSocketConnection *connection, + GError **error) +{ + return g_socket_get_local_address (connection->priv->socket, error); +} + +/** + * g_socket_connection_get_remote_address: + * @connection: a #GSocketConnection + * @error: #GError for error reporting, or %NULL to ignore. + * + * Try to get the remote address of a socket connection. + * + * Since GLib 2.40, when used with g_socket_client_connect() or + * g_socket_client_connect_async(), during emission of + * %G_SOCKET_CLIENT_CONNECTING, this function will return the remote + * address that will be used for the connection. This allows + * applications to print e.g. "Connecting to example.com + * (10.42.77.3)...". + * + * Returns: (transfer full): a #GSocketAddress or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.22 + */ +GSocketAddress * +g_socket_connection_get_remote_address (GSocketConnection *connection, + GError **error) +{ + if (!g_socket_is_connected (connection->priv->socket)) + { + return connection->priv->cached_remote_address ? + g_object_ref (connection->priv->cached_remote_address) : NULL; + } + return g_socket_get_remote_address (connection->priv->socket, error); +} + +/* Private API allowing applications to retrieve the resolved address + * now, before we start connecting. + * + * https://bugzilla.gnome.org/show_bug.cgi?id=712547 + */ +void +g_socket_connection_set_cached_remote_address (GSocketConnection *connection, + GSocketAddress *address) +{ + g_clear_object (&connection->priv->cached_remote_address); + connection->priv->cached_remote_address = address ? g_object_ref (address) : NULL; +} + +static void +g_socket_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSocketConnection *connection = G_SOCKET_CONNECTION (object); + + switch (prop_id) + { + case PROP_SOCKET: + g_value_set_object (value, connection->priv->socket); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSocketConnection *connection = G_SOCKET_CONNECTION (object); + + switch (prop_id) + { + case PROP_SOCKET: + connection->priv->socket = G_SOCKET (g_value_dup_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_connection_constructed (GObject *object) +{ +#ifndef G_DISABLE_ASSERT + GSocketConnection *connection = G_SOCKET_CONNECTION (object); +#endif + + g_assert (connection->priv->socket != NULL); +} + +static void +g_socket_connection_dispose (GObject *object) +{ + GSocketConnection *connection = G_SOCKET_CONNECTION (object); + + connection->priv->in_dispose = TRUE; + + g_clear_object (&connection->priv->cached_remote_address); + + G_OBJECT_CLASS (g_socket_connection_parent_class) + ->dispose (object); + + connection->priv->in_dispose = FALSE; +} + +static void +g_socket_connection_finalize (GObject *object) +{ + GSocketConnection *connection = G_SOCKET_CONNECTION (object); + + if (connection->priv->input_stream) + g_object_unref (connection->priv->input_stream); + + if (connection->priv->output_stream) + g_object_unref (connection->priv->output_stream); + + g_object_unref (connection->priv->socket); + + G_OBJECT_CLASS (g_socket_connection_parent_class) + ->finalize (object); +} + +static void +g_socket_connection_class_init (GSocketConnectionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass); + + gobject_class->set_property = g_socket_connection_set_property; + gobject_class->get_property = g_socket_connection_get_property; + gobject_class->constructed = g_socket_connection_constructed; + gobject_class->finalize = g_socket_connection_finalize; + gobject_class->dispose = g_socket_connection_dispose; + + stream_class->get_input_stream = g_socket_connection_get_input_stream; + stream_class->get_output_stream = g_socket_connection_get_output_stream; + stream_class->close_fn = g_socket_connection_close; + stream_class->close_async = g_socket_connection_close_async; + stream_class->close_finish = g_socket_connection_close_finish; + + g_object_class_install_property (gobject_class, + PROP_SOCKET, + g_param_spec_object ("socket", + P_("Socket"), + P_("The underlying GSocket"), + G_TYPE_SOCKET, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_socket_connection_init (GSocketConnection *connection) +{ + connection->priv = g_socket_connection_get_instance_private (connection); +} + +static gboolean +g_socket_connection_close (GIOStream *stream, + GCancellable *cancellable, + GError **error) +{ + GSocketConnection *connection = G_SOCKET_CONNECTION (stream); + + if (connection->priv->output_stream) + g_output_stream_close (connection->priv->output_stream, + cancellable, NULL); + if (connection->priv->input_stream) + g_input_stream_close (connection->priv->input_stream, + cancellable, NULL); + + /* Don't close the underlying socket if this is being called + * as part of dispose(); when destroying the GSocketConnection, + * we only want to close the socket if we're holding the last + * reference on it, and in that case it will close itself when + * we unref it in finalize(). + */ + if (connection->priv->in_dispose) + return TRUE; + + return g_socket_close (connection->priv->socket, error); +} + + +static void +g_socket_connection_close_async (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + GIOStreamClass *class; + GError *error; + + class = G_IO_STREAM_GET_CLASS (stream); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_socket_connection_close_async); + + /* socket close is not blocked, just do it! */ + error = NULL; + if (class->close_fn && + !class->close_fn (stream, cancellable, &error)) + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); + + g_object_unref (task); +} + +static gboolean +g_socket_connection_close_finish (GIOStream *stream, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} + +typedef struct { + GSocketFamily socket_family; + GSocketType socket_type; + int protocol; + GType implementation; +} ConnectionFactory; + +static guint +connection_factory_hash (gconstpointer key) +{ + const ConnectionFactory *factory = key; + guint h; + + h = factory->socket_family ^ (factory->socket_type << 4) ^ (factory->protocol << 8); + /* This is likely to be small, so spread over whole + hash space to get some distribution */ + h = h ^ (h << 8) ^ (h << 16) ^ (h << 24); + + return h; +} + +static gboolean +connection_factory_equal (gconstpointer _a, + gconstpointer _b) +{ + const ConnectionFactory *a = _a; + const ConnectionFactory *b = _b; + + if (a->socket_family != b->socket_family) + return FALSE; + + if (a->socket_type != b->socket_type) + return FALSE; + + if (a->protocol != b->protocol) + return FALSE; + + return TRUE; +} + +static GHashTable *connection_factories = NULL; +G_LOCK_DEFINE_STATIC(connection_factories); + +/** + * g_socket_connection_factory_register_type: + * @g_type: a #GType, inheriting from %G_TYPE_SOCKET_CONNECTION + * @family: a #GSocketFamily + * @type: a #GSocketType + * @protocol: a protocol id + * + * Looks up the #GType to be used when creating socket connections on + * sockets with the specified @family, @type and @protocol. + * + * If no type is registered, the #GSocketConnection base type is returned. + * + * Since: 2.22 + */ +void +g_socket_connection_factory_register_type (GType g_type, + GSocketFamily family, + GSocketType type, + gint protocol) +{ + ConnectionFactory *factory; + + g_return_if_fail (g_type_is_a (g_type, G_TYPE_SOCKET_CONNECTION)); + + G_LOCK (connection_factories); + + if (connection_factories == NULL) + connection_factories = g_hash_table_new_full (connection_factory_hash, + connection_factory_equal, + (GDestroyNotify)g_free, + NULL); + + factory = g_new0 (ConnectionFactory, 1); + factory->socket_family = family; + factory->socket_type = type; + factory->protocol = protocol; + factory->implementation = g_type; + + g_hash_table_insert (connection_factories, + factory, factory); + + G_UNLOCK (connection_factories); +} + +static void +init_builtin_types (void) +{ + g_type_ensure (G_TYPE_UNIX_CONNECTION); + g_type_ensure (G_TYPE_TCP_CONNECTION); +} + +/** + * g_socket_connection_factory_lookup_type: + * @family: a #GSocketFamily + * @type: a #GSocketType + * @protocol_id: a protocol id + * + * Looks up the #GType to be used when creating socket connections on + * sockets with the specified @family, @type and @protocol_id. + * + * If no type is registered, the #GSocketConnection base type is returned. + * + * Returns: a #GType + * + * Since: 2.22 + */ +GType +g_socket_connection_factory_lookup_type (GSocketFamily family, + GSocketType type, + gint protocol_id) +{ + ConnectionFactory *factory, key; + GType g_type; + + init_builtin_types (); + + G_LOCK (connection_factories); + + g_type = G_TYPE_SOCKET_CONNECTION; + + if (connection_factories) + { + key.socket_family = family; + key.socket_type = type; + key.protocol = protocol_id; + + factory = g_hash_table_lookup (connection_factories, &key); + if (factory) + g_type = factory->implementation; + } + + G_UNLOCK (connection_factories); + + return g_type; +} + +/** + * g_socket_connection_factory_create_connection: + * @socket: a #GSocket + * + * Creates a #GSocketConnection subclass of the right type for + * @socket. + * + * Returns: (transfer full): a #GSocketConnection + * + * Since: 2.22 + */ +GSocketConnection * +g_socket_connection_factory_create_connection (GSocket *socket) +{ + GType type; + + type = g_socket_connection_factory_lookup_type (g_socket_get_family (socket), + g_socket_get_socket_type (socket), + g_socket_get_protocol (socket)); + return g_object_new (type, "socket", socket, NULL); +} diff --git a/gio/gsocketconnection.h b/gio/gsocketconnection.h new file mode 100644 index 0000000..bc7a076 --- /dev/null +++ b/gio/gsocketconnection.h @@ -0,0 +1,115 @@ +/* GIO - GLib Input, Output and Streaming Library + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + * Alexander Larsson + */ + +#ifndef __G_SOCKET_CONNECTION_H__ +#define __G_SOCKET_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_CONNECTION (g_socket_connection_get_type ()) +#define G_SOCKET_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SOCKET_CONNECTION, GSocketConnection)) +#define G_SOCKET_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SOCKET_CONNECTION, GSocketConnectionClass)) +#define G_IS_SOCKET_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SOCKET_CONNECTION)) +#define G_IS_SOCKET_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SOCKET_CONNECTION)) +#define G_SOCKET_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SOCKET_CONNECTION, GSocketConnectionClass)) + +typedef struct _GSocketConnectionPrivate GSocketConnectionPrivate; +typedef struct _GSocketConnectionClass GSocketConnectionClass; + +struct _GSocketConnectionClass +{ + GIOStreamClass parent_class; + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); +}; + +struct _GSocketConnection +{ + GIOStream parent_instance; + GSocketConnectionPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_connection_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_32 +gboolean g_socket_connection_is_connected (GSocketConnection *connection); +GLIB_AVAILABLE_IN_2_32 +gboolean g_socket_connection_connect (GSocketConnection *connection, + GSocketAddress *address, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_32 +void g_socket_connection_connect_async (GSocketConnection *connection, + GSocketAddress *address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_32 +gboolean g_socket_connection_connect_finish (GSocketConnection *connection, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GSocket *g_socket_connection_get_socket (GSocketConnection *connection); +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_socket_connection_get_local_address (GSocketConnection *connection, + GError **error); +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_socket_connection_get_remote_address (GSocketConnection *connection, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_socket_connection_factory_register_type (GType g_type, + GSocketFamily family, + GSocketType type, + gint protocol); +GLIB_AVAILABLE_IN_ALL +GType g_socket_connection_factory_lookup_type (GSocketFamily family, + GSocketType type, + gint protocol_id); +GLIB_AVAILABLE_IN_ALL +GSocketConnection *g_socket_connection_factory_create_connection (GSocket *socket); + +G_END_DECLS + +#endif /* __G_SOCKET_CONNECTION_H__ */ diff --git a/gio/gsocketcontrolmessage.c b/gio/gsocketcontrolmessage.c new file mode 100644 index 0000000..198ddec --- /dev/null +++ b/gio/gsocketcontrolmessage.c @@ -0,0 +1,214 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Ryan Lortie + */ + +/** + * SECTION:gsocketcontrolmessage + * @title: GSocketControlMessage + * @short_description: A GSocket control message + * @include: gio/gio.h + * @see_also: #GSocket. + * + * A #GSocketControlMessage is a special-purpose utility message that + * can be sent to or received from a #GSocket. These types of + * messages are often called "ancillary data". + * + * The message can represent some sort of special instruction to or + * information from the socket or can represent a special kind of + * transfer to the peer (for example, sending a file descriptor over + * a UNIX socket). + * + * These messages are sent with g_socket_send_message() and received + * with g_socket_receive_message(). + * + * To extend the set of control message that can be sent, subclass this + * class and override the get_size, get_level, get_type and serialize + * methods. + * + * To extend the set of control messages that can be received, subclass + * this class and implement the deserialize method. Also, make sure your + * class is registered with the GType typesystem before calling + * g_socket_receive_message() to read such a message. + * + * Since: 2.22 + */ + +#include "config.h" +#include "gsocketcontrolmessage.h" +#include "gnetworkingprivate.h" +#include "glibintl.h" + +#ifndef G_OS_WIN32 +#include "gunixcredentialsmessage.h" +#include "gunixfdmessage.h" +#endif + + +G_DEFINE_ABSTRACT_TYPE (GSocketControlMessage, g_socket_control_message, G_TYPE_OBJECT) + +/** + * g_socket_control_message_get_size: + * @message: a #GSocketControlMessage + * + * Returns the space required for the control message, not including + * headers or alignment. + * + * Returns: The number of bytes required. + * + * Since: 2.22 + */ +gsize +g_socket_control_message_get_size (GSocketControlMessage *message) +{ + g_return_val_if_fail (G_IS_SOCKET_CONTROL_MESSAGE (message), 0); + + return G_SOCKET_CONTROL_MESSAGE_GET_CLASS (message)->get_size (message); +} + +/** + * g_socket_control_message_get_level: + * @message: a #GSocketControlMessage + * + * Returns the "level" (i.e. the originating protocol) of the control message. + * This is often SOL_SOCKET. + * + * Returns: an integer describing the level + * + * Since: 2.22 + */ +int +g_socket_control_message_get_level (GSocketControlMessage *message) +{ + g_return_val_if_fail (G_IS_SOCKET_CONTROL_MESSAGE (message), 0); + + return G_SOCKET_CONTROL_MESSAGE_GET_CLASS (message)->get_level (message); +} + +/** + * g_socket_control_message_get_msg_type: + * @message: a #GSocketControlMessage + * + * Returns the protocol specific type of the control message. + * For instance, for UNIX fd passing this would be SCM_RIGHTS. + * + * Returns: an integer describing the type of control message + * + * Since: 2.22 + */ +int +g_socket_control_message_get_msg_type (GSocketControlMessage *message) +{ + g_return_val_if_fail (G_IS_SOCKET_CONTROL_MESSAGE (message), 0); + + return G_SOCKET_CONTROL_MESSAGE_GET_CLASS (message)->get_type (message); +} + +/** + * g_socket_control_message_serialize: + * @message: a #GSocketControlMessage + * @data: (not nullable): A buffer to write data to + * + * Converts the data in the message to bytes placed in the + * message. + * + * @data is guaranteed to have enough space to fit the size + * returned by g_socket_control_message_get_size() on this + * object. + * + * Since: 2.22 + */ +void +g_socket_control_message_serialize (GSocketControlMessage *message, + gpointer data) +{ + g_return_if_fail (G_IS_SOCKET_CONTROL_MESSAGE (message)); + + G_SOCKET_CONTROL_MESSAGE_GET_CLASS (message)->serialize (message, data); +} + + +static void +g_socket_control_message_init (GSocketControlMessage *message) +{ +} + +static void +g_socket_control_message_class_init (GSocketControlMessageClass *class) +{ +} + +/** + * g_socket_control_message_deserialize: + * @level: a socket level + * @type: a socket control message type for the given @level + * @size: the size of the data in bytes + * @data: (array length=size) (element-type guint8): pointer to the message data + * + * Tries to deserialize a socket control message of a given + * @level and @type. This will ask all known (to GType) subclasses + * of #GSocketControlMessage if they can understand this kind + * of message and if so deserialize it into a #GSocketControlMessage. + * + * If there is no implementation for this kind of control message, %NULL + * will be returned. + * + * Returns: (transfer full): the deserialized message or %NULL + * + * Since: 2.22 + */ +GSocketControlMessage * +g_socket_control_message_deserialize (int level, + int type, + gsize size, + gpointer data) +{ + GSocketControlMessage *message; + GType *message_types; + guint n_message_types; + guint i; + + /* Ensure we know about the built in types */ +#ifndef G_OS_WIN32 + g_type_ensure (G_TYPE_UNIX_CREDENTIALS_MESSAGE); + g_type_ensure (G_TYPE_UNIX_FD_MESSAGE); +#endif + + message_types = g_type_children (G_TYPE_SOCKET_CONTROL_MESSAGE, &n_message_types); + + message = NULL; + for (i = 0; i < n_message_types; i++) + { + GSocketControlMessageClass *class; + + class = g_type_class_ref (message_types[i]); + message = class->deserialize (level, type, size, data); + g_type_class_unref (class); + + if (message != NULL) + break; + } + + g_free (message_types); + + /* It's not a bug if we can't deserialize the control message - for + * example, the control message may be be discarded if it is deemed + * empty, see e.g. + * + * https://gitlab.gnome.org/GNOME/glib/commit/ec91ed00f14c70cca9749347b8ebc19d72d9885b + * + * Therefore, it's not appropriate to print a warning about not + * being able to deserialize the message. + */ + + return message; +} diff --git a/gio/gsocketcontrolmessage.h b/gio/gsocketcontrolmessage.h new file mode 100644 index 0000000..a4a5d01 --- /dev/null +++ b/gio/gsocketcontrolmessage.h @@ -0,0 +1,111 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_SOCKET_CONTROL_MESSAGE_H__ +#define __G_SOCKET_CONTROL_MESSAGE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_CONTROL_MESSAGE (g_socket_control_message_get_type ()) +#define G_SOCKET_CONTROL_MESSAGE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SOCKET_CONTROL_MESSAGE, \ + GSocketControlMessage)) +#define G_SOCKET_CONTROL_MESSAGE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SOCKET_CONTROL_MESSAGE, \ + GSocketControlMessageClass)) +#define G_IS_SOCKET_CONTROL_MESSAGE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SOCKET_CONTROL_MESSAGE)) +#define G_IS_SOCKET_CONTROL_MESSAGE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SOCKET_CONTROL_MESSAGE)) +#define G_SOCKET_CONTROL_MESSAGE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SOCKET_CONTROL_MESSAGE, \ + GSocketControlMessageClass)) + +typedef struct _GSocketControlMessagePrivate GSocketControlMessagePrivate; +typedef struct _GSocketControlMessageClass GSocketControlMessageClass; + +/** + * GSocketControlMessageClass: + * @get_size: gets the size of the message. + * @get_level: gets the protocol of the message. + * @get_type: gets the protocol specific type of the message. + * @serialize: Writes out the message data. + * @deserialize: Tries to deserialize a message. + * + * Class structure for #GSocketControlMessage. + **/ + +struct _GSocketControlMessageClass +{ + GObjectClass parent_class; + + gsize (* get_size) (GSocketControlMessage *message); + int (* get_level) (GSocketControlMessage *message); + int (* get_type) (GSocketControlMessage *message); + void (* serialize) (GSocketControlMessage *message, + gpointer data); + GSocketControlMessage *(* deserialize) (int level, + int type, + gsize size, + gpointer data); + + /*< private >*/ + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +struct _GSocketControlMessage +{ + GObject parent_instance; + GSocketControlMessagePrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_control_message_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gsize g_socket_control_message_get_size (GSocketControlMessage *message); +GLIB_AVAILABLE_IN_ALL +int g_socket_control_message_get_level (GSocketControlMessage *message); +GLIB_AVAILABLE_IN_ALL +int g_socket_control_message_get_msg_type (GSocketControlMessage *message); +GLIB_AVAILABLE_IN_ALL +void g_socket_control_message_serialize (GSocketControlMessage *message, + gpointer data); +GLIB_AVAILABLE_IN_ALL +GSocketControlMessage *g_socket_control_message_deserialize (int level, + int type, + gsize size, + gpointer data); + + +G_END_DECLS + +#endif /* __G_SOCKET_CONTROL_MESSAGE_H__ */ diff --git a/gio/gsocketinputstream.c b/gio/gsocketinputstream.c new file mode 100644 index 0000000..b6d5c62 --- /dev/null +++ b/gio/gsocketinputstream.c @@ -0,0 +1,225 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * © 2009 codethink + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + */ + +#include "config.h" +#include "gsocketinputstream.h" +#include "glibintl.h" + +#include "gcancellable.h" +#include "gpollableinputstream.h" +#include "gioerror.h" +#include "gfiledescriptorbased.h" + +struct _GSocketInputStreamPrivate +{ + GSocket *socket; + + /* pending operation metadata */ + gpointer buffer; + gsize count; +}; + +static void g_socket_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface); +#ifdef G_OS_UNIX +static void g_socket_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface); +#endif + +#define g_socket_input_stream_get_type _g_socket_input_stream_get_type + +#ifdef G_OS_UNIX +G_DEFINE_TYPE_WITH_CODE (GSocketInputStream, g_socket_input_stream, G_TYPE_INPUT_STREAM, + G_ADD_PRIVATE (GSocketInputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, g_socket_input_stream_pollable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, g_socket_input_stream_file_descriptor_based_iface_init) + ) +#else +G_DEFINE_TYPE_WITH_CODE (GSocketInputStream, g_socket_input_stream, G_TYPE_INPUT_STREAM, + G_ADD_PRIVATE (GSocketInputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, g_socket_input_stream_pollable_iface_init) + ) +#endif + +enum +{ + PROP_0, + PROP_SOCKET +}; + +static void +g_socket_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSocketInputStream *stream = G_SOCKET_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_SOCKET: + g_value_set_object (value, stream->priv->socket); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSocketInputStream *stream = G_SOCKET_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_SOCKET: + stream->priv->socket = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_input_stream_finalize (GObject *object) +{ + GSocketInputStream *stream = G_SOCKET_INPUT_STREAM (object); + + if (stream->priv->socket) + g_object_unref (stream->priv->socket); + + G_OBJECT_CLASS (g_socket_input_stream_parent_class)->finalize (object); +} + +static gssize +g_socket_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (stream); + + return g_socket_receive_with_blocking (input_stream->priv->socket, + buffer, count, TRUE, + cancellable, error); +} + +static gboolean +g_socket_input_stream_pollable_is_readable (GPollableInputStream *pollable) +{ + GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (pollable); + + return g_socket_condition_check (input_stream->priv->socket, G_IO_IN); +} + +static GSource * +g_socket_input_stream_pollable_create_source (GPollableInputStream *pollable, + GCancellable *cancellable) +{ + GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (pollable); + GSource *socket_source, *pollable_source; + + pollable_source = g_pollable_source_new (G_OBJECT (input_stream)); + socket_source = g_socket_create_source (input_stream->priv->socket, + G_IO_IN, cancellable); + g_source_set_dummy_callback (socket_source); + g_source_add_child_source (pollable_source, socket_source); + g_source_unref (socket_source); + + return pollable_source; +} + +static gssize +g_socket_input_stream_pollable_read_nonblocking (GPollableInputStream *pollable, + void *buffer, + gsize size, + GError **error) +{ + GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (pollable); + + return g_socket_receive_with_blocking (input_stream->priv->socket, + buffer, size, FALSE, + NULL, error); +} + +#ifdef G_OS_UNIX +static int +g_socket_input_stream_get_fd (GFileDescriptorBased *fd_based) +{ + GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (fd_based); + + return g_socket_get_fd (input_stream->priv->socket); +} +#endif + +static void +g_socket_input_stream_class_init (GSocketInputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GInputStreamClass *ginputstream_class = G_INPUT_STREAM_CLASS (klass); + + gobject_class->finalize = g_socket_input_stream_finalize; + gobject_class->get_property = g_socket_input_stream_get_property; + gobject_class->set_property = g_socket_input_stream_set_property; + + ginputstream_class->read_fn = g_socket_input_stream_read; + + g_object_class_install_property (gobject_class, PROP_SOCKET, + g_param_spec_object ("socket", + P_("socket"), + P_("The socket that this stream wraps"), + G_TYPE_SOCKET, G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +#ifdef G_OS_UNIX +static void +g_socket_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface) +{ + iface->get_fd = g_socket_input_stream_get_fd; +} +#endif + +static void +g_socket_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface) +{ + iface->is_readable = g_socket_input_stream_pollable_is_readable; + iface->create_source = g_socket_input_stream_pollable_create_source; + iface->read_nonblocking = g_socket_input_stream_pollable_read_nonblocking; +} + +static void +g_socket_input_stream_init (GSocketInputStream *stream) +{ + stream->priv = g_socket_input_stream_get_instance_private (stream); +} + +GSocketInputStream * +_g_socket_input_stream_new (GSocket *socket) +{ + return g_object_new (G_TYPE_SOCKET_INPUT_STREAM, "socket", socket, NULL); +} diff --git a/gio/gsocketinputstream.h b/gio/gsocketinputstream.h new file mode 100644 index 0000000..f415f1b --- /dev/null +++ b/gio/gsocketinputstream.h @@ -0,0 +1,58 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + */ + +#ifndef __G_SOCKET_INPUT_STREAM_H__ +#define __G_SOCKET_INPUT_STREAM_H__ + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_INPUT_STREAM (_g_socket_input_stream_get_type ()) +#define G_SOCKET_INPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SOCKET_INPUT_STREAM, GSocketInputStream)) +#define G_SOCKET_INPUT_STREAM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SOCKET_INPUT_STREAM, GSocketInputStreamClass)) +#define G_IS_SOCKET_INPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SOCKET_INPUT_STREAM)) +#define G_IS_SOCKET_INPUT_STREAM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SOCKET_INPUT_STREAM)) +#define G_SOCKET_INPUT_STREAM_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SOCKET_INPUT_STREAM, GSocketInputStreamClass)) + +typedef struct _GSocketInputStreamPrivate GSocketInputStreamPrivate; +typedef struct _GSocketInputStreamClass GSocketInputStreamClass; +typedef struct _GSocketInputStream GSocketInputStream; + +struct _GSocketInputStreamClass +{ + GInputStreamClass parent_class; +}; + +struct _GSocketInputStream +{ + GInputStream parent_instance; + GSocketInputStreamPrivate *priv; +}; + +GType _g_socket_input_stream_get_type (void) G_GNUC_CONST; +GSocketInputStream * _g_socket_input_stream_new (GSocket *socket); + +G_END_DECLS + +#endif /* __G_SOCKET_INPUT_STREAM_H___ */ diff --git a/gio/gsocketlistener.c b/gio/gsocketlistener.c new file mode 100644 index 0000000..9baa609 --- /dev/null +++ b/gio/gsocketlistener.c @@ -0,0 +1,1281 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * Copyright © 2009 codethink + * Copyright © 2009 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + * Alexander Larsson + */ + +#include "config.h" +#include "gsocketlistener.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "glibintl.h" +#include "gmarshal-internal.h" + + +/** + * SECTION:gsocketlistener + * @title: GSocketListener + * @short_description: Helper for accepting network client connections + * @include: gio/gio.h + * @see_also: #GThreadedSocketService, #GSocketService. + * + * A #GSocketListener is an object that keeps track of a set + * of server sockets and helps you accept sockets from any of the + * socket, either sync or async. + * + * Add addresses and ports to listen on using g_socket_listener_add_address() + * and g_socket_listener_add_inet_port(). These will be listened on until + * g_socket_listener_close() is called. Dropping your final reference to the + * #GSocketListener will not cause g_socket_listener_close() to be called + * implicitly, as some references to the #GSocketListener may be held + * internally. + * + * If you want to implement a network server, also look at #GSocketService + * and #GThreadedSocketService which are subclasses of #GSocketListener + * that make this even easier. + * + * Since: 2.22 + */ + +enum +{ + PROP_0, + PROP_LISTEN_BACKLOG +}; + +enum +{ + EVENT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static GQuark source_quark = 0; + +struct _GSocketListenerPrivate +{ + GPtrArray *sockets; + GMainContext *main_context; + int listen_backlog; + guint closed : 1; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GSocketListener, g_socket_listener, G_TYPE_OBJECT) + +static void +g_socket_listener_finalize (GObject *object) +{ + GSocketListener *listener = G_SOCKET_LISTENER (object); + + if (listener->priv->main_context) + g_main_context_unref (listener->priv->main_context); + + /* Do not explicitly close the sockets. Instead, let them close themselves if + * their final reference is dropped, but keep them open if a reference is + * held externally to the GSocketListener (which is possible if + * g_socket_listener_add_socket() was used). + */ + g_ptr_array_free (listener->priv->sockets, TRUE); + + G_OBJECT_CLASS (g_socket_listener_parent_class) + ->finalize (object); +} + +static void +g_socket_listener_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSocketListener *listener = G_SOCKET_LISTENER (object); + + switch (prop_id) + { + case PROP_LISTEN_BACKLOG: + g_value_set_int (value, listener->priv->listen_backlog); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_listener_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSocketListener *listener = G_SOCKET_LISTENER (object); + + switch (prop_id) + { + case PROP_LISTEN_BACKLOG: + g_socket_listener_set_backlog (listener, g_value_get_int (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_listener_class_init (GSocketListenerClass *klass) +{ + GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_socket_listener_finalize; + gobject_class->set_property = g_socket_listener_set_property; + gobject_class->get_property = g_socket_listener_get_property; + g_object_class_install_property (gobject_class, PROP_LISTEN_BACKLOG, + g_param_spec_int ("listen-backlog", + P_("Listen backlog"), + P_("outstanding connections in the listen queue"), + 0, + 2000, + 10, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GSocketListener::event: + * @listener: the #GSocketListener + * @event: the event that is occurring + * @socket: the #GSocket the event is occurring on + * + * Emitted when @listener's activity on @socket changes state. + * Note that when @listener is used to listen on both IPv4 and + * IPv6, a separate set of signals will be emitted for each, and + * the order they happen in is undefined. + * + * Since: 2.46 + */ + signals[EVENT] = + g_signal_new (I_("event"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GSocketListenerClass, event), + NULL, NULL, + _g_cclosure_marshal_VOID__ENUM_OBJECT, + G_TYPE_NONE, 2, + G_TYPE_SOCKET_LISTENER_EVENT, + G_TYPE_SOCKET); + g_signal_set_va_marshaller (signals[EVENT], + G_TYPE_FROM_CLASS (gobject_class), + _g_cclosure_marshal_VOID__ENUM_OBJECTv); + + source_quark = g_quark_from_static_string ("g-socket-listener-source"); +} + +static void +g_socket_listener_init (GSocketListener *listener) +{ + listener->priv = g_socket_listener_get_instance_private (listener); + listener->priv->sockets = + g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + listener->priv->listen_backlog = 10; +} + +/** + * g_socket_listener_new: + * + * Creates a new #GSocketListener with no sockets to listen for. + * New listeners can be added with e.g. g_socket_listener_add_address() + * or g_socket_listener_add_inet_port(). + * + * Returns: a new #GSocketListener. + * + * Since: 2.22 + */ +GSocketListener * +g_socket_listener_new (void) +{ + return g_object_new (G_TYPE_SOCKET_LISTENER, NULL); +} + +static gboolean +check_listener (GSocketListener *listener, + GError **error) +{ + if (listener->priv->closed) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Listener is already closed")); + return FALSE; + } + + return TRUE; +} + +/** + * g_socket_listener_add_socket: + * @listener: a #GSocketListener + * @socket: a listening #GSocket + * @source_object: (nullable): Optional #GObject identifying this source + * @error: #GError for error reporting, or %NULL to ignore. + * + * Adds @socket to the set of sockets that we try to accept + * new clients from. The socket must be bound to a local + * address and listened to. + * + * @source_object will be passed out in the various calls + * to accept to identify this particular source, which is + * useful if you're listening on multiple addresses and do + * different things depending on what address is connected to. + * + * The @socket will not be automatically closed when the @listener is finalized + * unless the listener held the final reference to the socket. Before GLib 2.42, + * the @socket was automatically closed on finalization of the @listener, even + * if references to it were held elsewhere. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.22 + */ +gboolean +g_socket_listener_add_socket (GSocketListener *listener, + GSocket *socket, + GObject *source_object, + GError **error) +{ + if (!check_listener (listener, error)) + return FALSE; + + /* TODO: Check that socket it is bound & not closed? */ + + if (g_socket_is_closed (socket)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Added socket is closed")); + return FALSE; + } + + g_object_ref (socket); + g_ptr_array_add (listener->priv->sockets, socket); + + if (source_object) + g_object_set_qdata_full (G_OBJECT (socket), source_quark, + g_object_ref (source_object), g_object_unref); + + + if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed) + G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener); + + return TRUE; +} + +/** + * g_socket_listener_add_address: + * @listener: a #GSocketListener + * @address: a #GSocketAddress + * @type: a #GSocketType + * @protocol: a #GSocketProtocol + * @source_object: (nullable): Optional #GObject identifying this source + * @effective_address: (out) (optional): location to store the address that was bound to, or %NULL. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a socket of type @type and protocol @protocol, binds + * it to @address and adds it to the set of sockets we're accepting + * sockets from. + * + * Note that adding an IPv6 address, depending on the platform, + * may or may not result in a listener that also accepts IPv4 + * connections. For more deterministic behavior, see + * g_socket_listener_add_inet_port(). + * + * @source_object will be passed out in the various calls + * to accept to identify this particular source, which is + * useful if you're listening on multiple addresses and do + * different things depending on what address is connected to. + * + * If successful and @effective_address is non-%NULL then it will + * be set to the address that the binding actually occurred at. This + * is helpful for determining the port number that was used for when + * requesting a binding to port 0 (ie: "any port"). This address, if + * requested, belongs to the caller and must be freed. + * + * Call g_socket_listener_close() to stop listening on @address; this will not + * be done automatically when you drop your final reference to @listener, as + * references may be held internally. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.22 + */ +gboolean +g_socket_listener_add_address (GSocketListener *listener, + GSocketAddress *address, + GSocketType type, + GSocketProtocol protocol, + GObject *source_object, + GSocketAddress **effective_address, + GError **error) +{ + GSocketAddress *local_address; + GSocketFamily family; + GSocket *socket; + + if (!check_listener (listener, error)) + return FALSE; + + family = g_socket_address_get_family (address); + socket = g_socket_new (family, type, protocol, error); + if (socket == NULL) + return FALSE; + + g_socket_set_listen_backlog (socket, listener->priv->listen_backlog); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BINDING, socket); + + if (!g_socket_bind (socket, address, TRUE, error)) + { + g_object_unref (socket); + return FALSE; + } + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BOUND, socket); + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENING, socket); + + if (!g_socket_listen (socket, error)) + { + g_object_unref (socket); + return FALSE; + } + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENED, socket); + + local_address = NULL; + if (effective_address) + { + local_address = g_socket_get_local_address (socket, error); + if (local_address == NULL) + { + g_object_unref (socket); + return FALSE; + } + } + + if (!g_socket_listener_add_socket (listener, socket, + source_object, + error)) + { + if (local_address) + g_object_unref (local_address); + g_object_unref (socket); + return FALSE; + } + + if (effective_address) + *effective_address = local_address; + + g_object_unref (socket); /* add_socket refs this */ + + return TRUE; +} + +/** + * g_socket_listener_add_inet_port: + * @listener: a #GSocketListener + * @port: an IP port number (non-zero) + * @source_object: (nullable): Optional #GObject identifying this source + * @error: #GError for error reporting, or %NULL to ignore. + * + * Helper function for g_socket_listener_add_address() that + * creates a TCP/IP socket listening on IPv4 and IPv6 (if + * supported) on the specified port on all interfaces. + * + * @source_object will be passed out in the various calls + * to accept to identify this particular source, which is + * useful if you're listening on multiple addresses and do + * different things depending on what address is connected to. + * + * Call g_socket_listener_close() to stop listening on @port; this will not + * be done automatically when you drop your final reference to @listener, as + * references may be held internally. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 2.22 + */ +gboolean +g_socket_listener_add_inet_port (GSocketListener *listener, + guint16 port, + GObject *source_object, + GError **error) +{ + gboolean need_ipv4_socket = TRUE; + GSocket *socket4 = NULL; + GSocket *socket6; + + g_return_val_if_fail (listener != NULL, FALSE); + g_return_val_if_fail (port != 0, FALSE); + + if (!check_listener (listener, error)) + return FALSE; + + /* first try to create an IPv6 socket */ + socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + NULL); + + if (socket6 != NULL) + /* IPv6 is supported on this platform, so if we fail now it is + * a result of being unable to bind to our port. Don't fail + * silently as a result of this! + */ + { + GInetAddress *inet_address; + GSocketAddress *address; + + inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6); + address = g_inet_socket_address_new (inet_address, port); + g_object_unref (inet_address); + + g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BINDING, socket6); + + if (!g_socket_bind (socket6, address, TRUE, error)) + { + g_object_unref (address); + g_object_unref (socket6); + return FALSE; + } + + g_object_unref (address); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BOUND, socket6); + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENING, socket6); + + if (!g_socket_listen (socket6, error)) + { + g_object_unref (socket6); + return FALSE; + } + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENED, socket6); + + if (source_object) + g_object_set_qdata_full (G_OBJECT (socket6), source_quark, + g_object_ref (source_object), + g_object_unref); + + /* If this socket already speaks IPv4 then we are done. */ + if (g_socket_speaks_ipv4 (socket6)) + need_ipv4_socket = FALSE; + } + + if (need_ipv4_socket) + /* We are here for exactly one of the following reasons: + * + * - our platform doesn't support IPv6 + * - we successfully created an IPv6 socket but it's V6ONLY + * + * In either case, we need to go ahead and create an IPv4 socket + * and fail the call if we can't bind to it. + */ + { + socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + error); + + if (socket4 != NULL) + /* IPv4 is supported on this platform, so if we fail now it is + * a result of being unable to bind to our port. Don't fail + * silently as a result of this! + */ + { + GInetAddress *inet_address; + GSocketAddress *address; + + inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + address = g_inet_socket_address_new (inet_address, port); + g_object_unref (inet_address); + + g_socket_set_listen_backlog (socket4, + listener->priv->listen_backlog); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BINDING, socket4); + + if (!g_socket_bind (socket4, address, TRUE, error)) + { + g_object_unref (address); + g_object_unref (socket4); + if (socket6 != NULL) + g_object_unref (socket6); + + return FALSE; + } + + g_object_unref (address); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BOUND, socket4); + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENING, socket4); + + if (!g_socket_listen (socket4, error)) + { + g_object_unref (socket4); + if (socket6 != NULL) + g_object_unref (socket6); + + return FALSE; + } + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENED, socket4); + + if (source_object) + g_object_set_qdata_full (G_OBJECT (socket4), source_quark, + g_object_ref (source_object), + g_object_unref); + } + else + /* Ok. So IPv4 is not supported on this platform. If we + * succeeded at creating an IPv6 socket then that's OK, but + * otherwise we need to tell the user we failed. + */ + { + if (socket6 != NULL) + g_clear_error (error); + else + return FALSE; + } + } + + g_assert (socket6 != NULL || socket4 != NULL); + + if (socket6 != NULL) + g_ptr_array_add (listener->priv->sockets, socket6); + + if (socket4 != NULL) + g_ptr_array_add (listener->priv->sockets, socket4); + + if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed) + G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener); + + return TRUE; +} + +static GList * +add_sources (GSocketListener *listener, + GSocketSourceFunc callback, + gpointer callback_data, + GCancellable *cancellable, + GMainContext *context) +{ + GSocket *socket; + GSource *source; + GList *sources; + guint i; + + sources = NULL; + for (i = 0; i < listener->priv->sockets->len; i++) + { + socket = listener->priv->sockets->pdata[i]; + + source = g_socket_create_source (socket, G_IO_IN, cancellable); + g_source_set_callback (source, + (GSourceFunc) callback, + callback_data, NULL); + g_source_attach (source, context); + + sources = g_list_prepend (sources, source); + } + + return sources; +} + +static void +free_sources (GList *sources) +{ + GSource *source; + while (sources != NULL) + { + source = sources->data; + sources = g_list_delete_link (sources, sources); + g_source_destroy (source); + g_source_unref (source); + } +} + +struct AcceptData { + GMainLoop *loop; + GSocket *socket; +}; + +static gboolean +accept_callback (GSocket *socket, + GIOCondition condition, + gpointer user_data) +{ + struct AcceptData *data = user_data; + + data->socket = socket; + g_main_loop_quit (data->loop); + + return TRUE; +} + +/** + * g_socket_listener_accept_socket: + * @listener: a #GSocketListener + * @source_object: (out) (transfer none) (optional) (nullable): location where #GObject pointer will be stored, or %NULL. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Blocks waiting for a client to connect to any of the sockets added + * to the listener. Returns the #GSocket that was accepted. + * + * If you want to accept the high-level #GSocketConnection, not a #GSocket, + * which is often the case, then you should use g_socket_listener_accept() + * instead. + * + * If @source_object is not %NULL it will be filled out with the source + * object specified when the corresponding socket or address was added + * to the listener. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (transfer full): a #GSocket on success, %NULL on error. + * + * Since: 2.22 + */ +GSocket * +g_socket_listener_accept_socket (GSocketListener *listener, + GObject **source_object, + GCancellable *cancellable, + GError **error) +{ + GSocket *accept_socket, *socket; + + g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL); + + if (!check_listener (listener, error)) + return NULL; + + if (listener->priv->sockets->len == 1) + { + accept_socket = listener->priv->sockets->pdata[0]; + if (!g_socket_condition_wait (accept_socket, G_IO_IN, + cancellable, error)) + return NULL; + } + else + { + GList *sources; + struct AcceptData data; + GMainLoop *loop; + + if (listener->priv->main_context == NULL) + listener->priv->main_context = g_main_context_new (); + + loop = g_main_loop_new (listener->priv->main_context, FALSE); + data.loop = loop; + sources = add_sources (listener, + accept_callback, + &data, + cancellable, + listener->priv->main_context); + g_main_loop_run (loop); + accept_socket = data.socket; + free_sources (sources); + g_main_loop_unref (loop); + } + + if (!(socket = g_socket_accept (accept_socket, cancellable, error))) + return NULL; + + if (source_object) + *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark); + + return socket; +} + +/** + * g_socket_listener_accept: + * @listener: a #GSocketListener + * @source_object: (out) (transfer none) (optional) (nullable): location where #GObject pointer will be stored, or %NULL + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Blocks waiting for a client to connect to any of the sockets added + * to the listener. Returns a #GSocketConnection for the socket that was + * accepted. + * + * If @source_object is not %NULL it will be filled out with the source + * object specified when the corresponding socket or address was added + * to the listener. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.22 + */ +GSocketConnection * +g_socket_listener_accept (GSocketListener *listener, + GObject **source_object, + GCancellable *cancellable, + GError **error) +{ + GSocketConnection *connection; + GSocket *socket; + + socket = g_socket_listener_accept_socket (listener, + source_object, + cancellable, + error); + if (socket == NULL) + return NULL; + + connection = g_socket_connection_factory_create_connection (socket); + g_object_unref (socket); + + return connection; +} + +typedef struct +{ + GList *sources; /* (element-type GSource) */ + gboolean returned_yet; +} AcceptSocketAsyncData; + +static void +accept_socket_async_data_free (AcceptSocketAsyncData *data) +{ + free_sources (data->sources); + g_free (data); +} + +static gboolean +accept_ready (GSocket *accept_socket, + GIOCondition condition, + gpointer user_data) +{ + GTask *task = user_data; + GError *error = NULL; + GSocket *socket; + GObject *source_object; + AcceptSocketAsyncData *data = g_task_get_task_data (task); + + /* Don’t call g_task_return_*() multiple times if we have multiple incoming + * connections in the same #GMainContext iteration. */ + if (data->returned_yet) + return G_SOURCE_REMOVE; + + socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error); + if (socket) + { + source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark); + if (source_object) + g_object_set_qdata_full (G_OBJECT (task), + source_quark, + g_object_ref (source_object), g_object_unref); + g_task_return_pointer (task, socket, g_object_unref); + } + else + { + g_task_return_error (task, error); + } + + data->returned_yet = TRUE; + g_object_unref (task); + + return G_SOURCE_REMOVE; +} + +/** + * g_socket_listener_accept_socket_async: + * @listener: a #GSocketListener + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback + * + * This is the asynchronous version of g_socket_listener_accept_socket(). + * + * When the operation is finished @callback will be + * called. You can then call g_socket_listener_accept_socket_finish() + * to get the result of the operation. + * + * Since: 2.22 + */ +void +g_socket_listener_accept_socket_async (GSocketListener *listener, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + GError *error = NULL; + AcceptSocketAsyncData *data = NULL; + + task = g_task_new (listener, cancellable, callback, user_data); + g_task_set_source_tag (task, g_socket_listener_accept_socket_async); + + if (!check_listener (listener, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + data = g_new0 (AcceptSocketAsyncData, 1); + data->returned_yet = FALSE; + data->sources = add_sources (listener, + accept_ready, + task, + cancellable, + g_main_context_get_thread_default ()); + g_task_set_task_data (task, g_steal_pointer (&data), + (GDestroyNotify) accept_socket_async_data_free); +} + +/** + * g_socket_listener_accept_socket_finish: + * @listener: a #GSocketListener + * @result: a #GAsyncResult. + * @source_object: (out) (transfer none) (optional) (nullable): Optional #GObject identifying this source + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an async accept operation. See g_socket_listener_accept_socket_async() + * + * Returns: (transfer full): a #GSocket on success, %NULL on error. + * + * Since: 2.22 + */ +GSocket * +g_socket_listener_accept_socket_finish (GSocketListener *listener, + GAsyncResult *result, + GObject **source_object, + GError **error) +{ + g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL); + g_return_val_if_fail (g_task_is_valid (result, listener), NULL); + + if (source_object) + *source_object = g_object_get_qdata (G_OBJECT (result), source_quark); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +/** + * g_socket_listener_accept_async: + * @listener: a #GSocketListener + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data for the callback + * + * This is the asynchronous version of g_socket_listener_accept(). + * + * When the operation is finished @callback will be + * called. You can then call g_socket_listener_accept_finish() + * to get the result of the operation. + * + * Since: 2.22 + */ +void +g_socket_listener_accept_async (GSocketListener *listener, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_socket_listener_accept_socket_async (listener, + cancellable, + callback, + user_data); +} + +/** + * g_socket_listener_accept_finish: + * @listener: a #GSocketListener + * @result: a #GAsyncResult. + * @source_object: (out) (transfer none) (optional) (nullable): Optional #GObject identifying this source + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Finishes an async accept operation. See g_socket_listener_accept_async() + * + * Returns: (transfer full): a #GSocketConnection on success, %NULL on error. + * + * Since: 2.22 + */ +GSocketConnection * +g_socket_listener_accept_finish (GSocketListener *listener, + GAsyncResult *result, + GObject **source_object, + GError **error) +{ + GSocket *socket; + GSocketConnection *connection; + + socket = g_socket_listener_accept_socket_finish (listener, + result, + source_object, + error); + if (socket == NULL) + return NULL; + + connection = g_socket_connection_factory_create_connection (socket); + g_object_unref (socket); + return connection; +} + +/** + * g_socket_listener_set_backlog: + * @listener: a #GSocketListener + * @listen_backlog: an integer + * + * Sets the listen backlog on the sockets in the listener. This must be called + * before adding any sockets, addresses or ports to the #GSocketListener (for + * example, by calling g_socket_listener_add_inet_port()) to be effective. + * + * See g_socket_set_listen_backlog() for details + * + * Since: 2.22 + */ +void +g_socket_listener_set_backlog (GSocketListener *listener, + int listen_backlog) +{ + GSocket *socket; + guint i; + + if (listener->priv->closed) + return; + + listener->priv->listen_backlog = listen_backlog; + + for (i = 0; i < listener->priv->sockets->len; i++) + { + socket = listener->priv->sockets->pdata[i]; + g_socket_set_listen_backlog (socket, listen_backlog); + } +} + +/** + * g_socket_listener_close: + * @listener: a #GSocketListener + * + * Closes all the sockets in the listener. + * + * Since: 2.22 + */ +void +g_socket_listener_close (GSocketListener *listener) +{ + GSocket *socket; + guint i; + + g_return_if_fail (G_IS_SOCKET_LISTENER (listener)); + + if (listener->priv->closed) + return; + + for (i = 0; i < listener->priv->sockets->len; i++) + { + socket = listener->priv->sockets->pdata[i]; + g_socket_close (socket, NULL); + } + listener->priv->closed = TRUE; +} + +/** + * g_socket_listener_add_any_inet_port: + * @listener: a #GSocketListener + * @source_object: (nullable): Optional #GObject identifying this source + * @error: a #GError location to store the error occurring, or %NULL to + * ignore. + * + * Listens for TCP connections on any available port number for both + * IPv6 and IPv4 (if each is available). + * + * This is useful if you need to have a socket for incoming connections + * but don't care about the specific port number. + * + * @source_object will be passed out in the various calls + * to accept to identify this particular source, which is + * useful if you're listening on multiple addresses and do + * different things depending on what address is connected to. + * + * Returns: the port number, or 0 in case of failure. + * + * Since: 2.24 + **/ +guint16 +g_socket_listener_add_any_inet_port (GSocketListener *listener, + GObject *source_object, + GError **error) +{ + GSList *sockets_to_close = NULL; + guint16 candidate_port = 0; + GSocket *socket6 = NULL; + GSocket *socket4 = NULL; + gint attempts = 37; + + /* + * multi-step process: + * - first, create an IPv6 socket. + * - if that fails, create an IPv4 socket and bind it to port 0 and + * that's it. no retries if that fails (why would it?). + * - if our IPv6 socket also speaks IPv4 then we are done. + * - if not, then we need to create a IPv4 socket with the same port + * number. this might fail, of course. so we try this a bunch of + * times -- leaving the old IPv6 sockets open so that we get a + * different port number to try each time. + * - if all that fails then just give up. + */ + + while (attempts--) + { + GInetAddress *inet_address; + GSocketAddress *address; + gboolean result; + + g_assert (socket6 == NULL); + socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + NULL); + + if (socket6 != NULL) + { + inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6); + address = g_inet_socket_address_new (inet_address, 0); + g_object_unref (inet_address); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BINDING, socket6); + + result = g_socket_bind (socket6, address, TRUE, error); + g_object_unref (address); + + if (!result || + !(address = g_socket_get_local_address (socket6, error))) + { + g_object_unref (socket6); + socket6 = NULL; + break; + } + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BOUND, socket6); + + g_assert (G_IS_INET_SOCKET_ADDRESS (address)); + candidate_port = + g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); + g_assert (candidate_port != 0); + g_object_unref (address); + + if (g_socket_speaks_ipv4 (socket6)) + break; + } + + g_assert (socket4 == NULL); + socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + socket6 ? NULL : error); + + if (socket4 == NULL) + /* IPv4 not supported. + * if IPv6 is supported then candidate_port will be non-zero + * (and the error parameter above will have been NULL) + * if IPv6 is unsupported then candidate_port will be zero + * (and error will have been set by the above call) + */ + break; + + inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + address = g_inet_socket_address_new (inet_address, candidate_port); + g_object_unref (inet_address); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BINDING, socket4); + + /* a note on the 'error' clause below: + * + * if candidate_port is 0 then we report the error right away + * since it is strange that this binding would fail at all. + * otherwise, we ignore the error message (ie: NULL). + * + * the exception to this rule is the last time through the loop + * (ie: attempts == 0) in which case we want to set the error + * because failure here means that the entire call will fail and + * we need something to show to the user. + * + * an english summary of the situation: "if we gave a candidate + * port number AND we have more attempts to try, then ignore the + * error for now". + */ + result = g_socket_bind (socket4, address, TRUE, + (candidate_port && attempts) ? NULL : error); + g_object_unref (address); + + if (candidate_port) + { + g_assert (socket6 != NULL); + + if (result) + /* got our candidate port successfully */ + { + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BOUND, socket4); + break; + } + else + /* we failed to bind to the specified port. try again. */ + { + g_object_unref (socket4); + socket4 = NULL; + + /* keep this open so we get a different port number */ + sockets_to_close = g_slist_prepend (sockets_to_close, + socket6); + candidate_port = 0; + socket6 = NULL; + } + } + else + /* we didn't tell it a port. this means two things. + * - if we failed, then something really bad happened. + * - if we succeeded, then we need to find out the port number. + */ + { + g_assert (socket6 == NULL); + + if (!result || + !(address = g_socket_get_local_address (socket4, error))) + { + g_object_unref (socket4); + socket4 = NULL; + break; + } + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_BOUND, socket4); + + g_assert (G_IS_INET_SOCKET_ADDRESS (address)); + candidate_port = + g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); + g_assert (candidate_port != 0); + g_object_unref (address); + break; + } + } + + /* should only be non-zero if we have a socket */ + g_assert ((candidate_port != 0) == (socket4 || socket6)); + + while (sockets_to_close) + { + g_object_unref (sockets_to_close->data); + sockets_to_close = g_slist_delete_link (sockets_to_close, + sockets_to_close); + } + + /* now we actually listen() the sockets and add them to the listener */ + if (socket6 != NULL) + { + g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENING, socket6); + + if (!g_socket_listen (socket6, error)) + { + g_object_unref (socket6); + if (socket4) + g_object_unref (socket4); + + return 0; + } + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENED, socket6); + + if (source_object) + g_object_set_qdata_full (G_OBJECT (socket6), source_quark, + g_object_ref (source_object), + g_object_unref); + + g_ptr_array_add (listener->priv->sockets, socket6); + } + + if (socket4 != NULL) + { + g_socket_set_listen_backlog (socket4, listener->priv->listen_backlog); + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENING, socket4); + + if (!g_socket_listen (socket4, error)) + { + g_object_unref (socket4); + if (socket6) + g_object_unref (socket6); + + return 0; + } + + g_signal_emit (listener, signals[EVENT], 0, + G_SOCKET_LISTENER_LISTENED, socket4); + + if (source_object) + g_object_set_qdata_full (G_OBJECT (socket4), source_quark, + g_object_ref (source_object), + g_object_unref); + + g_ptr_array_add (listener->priv->sockets, socket4); + } + + if ((socket4 != NULL || socket6 != NULL) && + G_SOCKET_LISTENER_GET_CLASS (listener)->changed) + G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener); + + return candidate_port; +} diff --git a/gio/gsocketlistener.h b/gio/gsocketlistener.h new file mode 100644 index 0000000..e5185c2 --- /dev/null +++ b/gio/gsocketlistener.h @@ -0,0 +1,155 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * Copyright © 2009 Codethink Limited + * Copyright © 2009 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + * Alexander Larsson + */ + +#ifndef __G_SOCKET_LISTENER_H__ +#define __G_SOCKET_LISTENER_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_LISTENER (g_socket_listener_get_type ()) +#define G_SOCKET_LISTENER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SOCKET_LISTENER, GSocketListener)) +#define G_SOCKET_LISTENER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SOCKET_LISTENER, GSocketListenerClass)) +#define G_IS_SOCKET_LISTENER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SOCKET_LISTENER)) +#define G_IS_SOCKET_LISTENER_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SOCKET_LISTENER)) +#define G_SOCKET_LISTENER_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SOCKET_LISTENER, GSocketListenerClass)) + +typedef struct _GSocketListenerPrivate GSocketListenerPrivate; +typedef struct _GSocketListenerClass GSocketListenerClass; + +/** + * GSocketListenerClass: + * @changed: virtual method called when the set of socket listened to changes + * + * Class structure for #GSocketListener. + **/ +struct _GSocketListenerClass +{ + GObjectClass parent_class; + + void (* changed) (GSocketListener *listener); + + void (* event) (GSocketListener *listener, + GSocketListenerEvent event, + GSocket *socket); + + /* Padding for future expansion */ + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); +}; + +struct _GSocketListener +{ + GObject parent_instance; + GSocketListenerPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_listener_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketListener * g_socket_listener_new (void); + +GLIB_AVAILABLE_IN_ALL +void g_socket_listener_set_backlog (GSocketListener *listener, + int listen_backlog); + +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_listener_add_socket (GSocketListener *listener, + GSocket *socket, + GObject *source_object, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_listener_add_address (GSocketListener *listener, + GSocketAddress *address, + GSocketType type, + GSocketProtocol protocol, + GObject *source_object, + GSocketAddress **effective_address, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_listener_add_inet_port (GSocketListener *listener, + guint16 port, + GObject *source_object, + GError **error); +GLIB_AVAILABLE_IN_ALL +guint16 g_socket_listener_add_any_inet_port (GSocketListener *listener, + GObject *source_object, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GSocket * g_socket_listener_accept_socket (GSocketListener *listener, + GObject **source_object, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_socket_listener_accept_socket_async (GSocketListener *listener, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GSocket * g_socket_listener_accept_socket_finish (GSocketListener *listener, + GAsyncResult *result, + GObject **source_object, + GError **error); + + +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_listener_accept (GSocketListener *listener, + GObject **source_object, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_socket_listener_accept_async (GSocketListener *listener, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GSocketConnection * g_socket_listener_accept_finish (GSocketListener *listener, + GAsyncResult *result, + GObject **source_object, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_socket_listener_close (GSocketListener *listener); + +G_END_DECLS + +#endif /* __G_SOCKET_LISTENER_H__ */ diff --git a/gio/gsocketoutputstream.c b/gio/gsocketoutputstream.c new file mode 100644 index 0000000..482ee39 --- /dev/null +++ b/gio/gsocketoutputstream.c @@ -0,0 +1,282 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * © 2009 codethink + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + */ + +#include "config.h" +#include "goutputstream.h" +#include "gsocketoutputstream.h" +#include "gsocket.h" +#include "glibintl.h" + +#include "gcancellable.h" +#include "gpollableinputstream.h" +#include "gpollableoutputstream.h" +#include "gioerror.h" +#include "glibintl.h" +#include "gfiledescriptorbased.h" +#include "gioprivate.h" + +struct _GSocketOutputStreamPrivate +{ + GSocket *socket; + + /* pending operation metadata */ + gconstpointer buffer; + gsize count; +}; + +static void g_socket_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface); +#ifdef G_OS_UNIX +static void g_socket_output_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface); +#endif + +#define g_socket_output_stream_get_type _g_socket_output_stream_get_type + +#ifdef G_OS_UNIX +G_DEFINE_TYPE_WITH_CODE (GSocketOutputStream, g_socket_output_stream, G_TYPE_OUTPUT_STREAM, + G_ADD_PRIVATE (GSocketOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, g_socket_output_stream_pollable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, g_socket_output_stream_file_descriptor_based_iface_init) + ) +#else +G_DEFINE_TYPE_WITH_CODE (GSocketOutputStream, g_socket_output_stream, G_TYPE_OUTPUT_STREAM, + G_ADD_PRIVATE (GSocketOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, g_socket_output_stream_pollable_iface_init) + ) +#endif + +enum +{ + PROP_0, + PROP_SOCKET +}; + +static void +g_socket_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSocketOutputStream *stream = G_SOCKET_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_SOCKET: + g_value_set_object (value, stream->priv->socket); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSocketOutputStream *stream = G_SOCKET_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_SOCKET: + stream->priv->socket = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_socket_output_stream_finalize (GObject *object) +{ + GSocketOutputStream *stream = G_SOCKET_OUTPUT_STREAM (object); + + if (stream->priv->socket) + g_object_unref (stream->priv->socket); + + G_OBJECT_CLASS (g_socket_output_stream_parent_class)->finalize (object); +} + +static gssize +g_socket_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (stream); + + return g_socket_send_with_blocking (output_stream->priv->socket, + buffer, count, TRUE, + cancellable, error); +} + +static gboolean +g_socket_output_stream_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (stream); + GPollableReturn res; + + /* Clamp the number of vectors if more given than we can write in one go. + * The caller has to handle short writes anyway. + */ + if (n_vectors > G_IOV_MAX) + n_vectors = G_IOV_MAX; + + res = g_socket_send_message_with_timeout (output_stream->priv->socket, NULL, + vectors, n_vectors, + NULL, 0, G_SOCKET_MSG_NONE, + -1, bytes_written, + cancellable, error); + + /* we have a non-zero timeout so this can't happen */ + g_assert (res != G_POLLABLE_RETURN_WOULD_BLOCK); + + return res == G_POLLABLE_RETURN_OK; +} + +static gboolean +g_socket_output_stream_pollable_is_writable (GPollableOutputStream *pollable) +{ + GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (pollable); + + return g_socket_condition_check (output_stream->priv->socket, G_IO_OUT); +} + +static gssize +g_socket_output_stream_pollable_write_nonblocking (GPollableOutputStream *pollable, + const void *buffer, + gsize size, + GError **error) +{ + GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (pollable); + + return g_socket_send_with_blocking (output_stream->priv->socket, + buffer, size, FALSE, + NULL, error); +} + +static GPollableReturn +g_socket_output_stream_pollable_writev_nonblocking (GPollableOutputStream *pollable, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GError **error) +{ + GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (pollable); + + /* Clamp the number of vectors if more given than we can write in one go. + * The caller has to handle short writes anyway. + */ + if (n_vectors > G_IOV_MAX) + n_vectors = G_IOV_MAX; + + return g_socket_send_message_with_timeout (output_stream->priv->socket, + NULL, vectors, n_vectors, + NULL, 0, G_SOCKET_MSG_NONE, 0, + bytes_written, NULL, error); +} + +static GSource * +g_socket_output_stream_pollable_create_source (GPollableOutputStream *pollable, + GCancellable *cancellable) +{ + GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (pollable); + GSource *socket_source, *pollable_source; + + pollable_source = g_pollable_source_new (G_OBJECT (output_stream)); + socket_source = g_socket_create_source (output_stream->priv->socket, + G_IO_OUT, cancellable); + g_source_set_dummy_callback (socket_source); + g_source_add_child_source (pollable_source, socket_source); + g_source_unref (socket_source); + + return pollable_source; +} + +#ifdef G_OS_UNIX +static int +g_socket_output_stream_get_fd (GFileDescriptorBased *fd_based) +{ + GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (fd_based); + + return g_socket_get_fd (output_stream->priv->socket); +} +#endif + +static void +g_socket_output_stream_class_init (GSocketOutputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GOutputStreamClass *goutputstream_class = G_OUTPUT_STREAM_CLASS (klass); + + gobject_class->finalize = g_socket_output_stream_finalize; + gobject_class->get_property = g_socket_output_stream_get_property; + gobject_class->set_property = g_socket_output_stream_set_property; + + goutputstream_class->write_fn = g_socket_output_stream_write; + goutputstream_class->writev_fn = g_socket_output_stream_writev; + + g_object_class_install_property (gobject_class, PROP_SOCKET, + g_param_spec_object ("socket", + P_("socket"), + P_("The socket that this stream wraps"), + G_TYPE_SOCKET, G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +#ifdef G_OS_UNIX +static void +g_socket_output_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface) +{ + iface->get_fd = g_socket_output_stream_get_fd; +} +#endif + +static void +g_socket_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface) +{ + iface->is_writable = g_socket_output_stream_pollable_is_writable; + iface->create_source = g_socket_output_stream_pollable_create_source; + iface->write_nonblocking = g_socket_output_stream_pollable_write_nonblocking; + iface->writev_nonblocking = g_socket_output_stream_pollable_writev_nonblocking; +} + +static void +g_socket_output_stream_init (GSocketOutputStream *stream) +{ + stream->priv = g_socket_output_stream_get_instance_private (stream); +} + +GSocketOutputStream * +_g_socket_output_stream_new (GSocket *socket) +{ + return g_object_new (G_TYPE_SOCKET_OUTPUT_STREAM, "socket", socket, NULL); +} diff --git a/gio/gsocketoutputstream.h b/gio/gsocketoutputstream.h new file mode 100644 index 0000000..0cbaa63 --- /dev/null +++ b/gio/gsocketoutputstream.h @@ -0,0 +1,58 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + * Ryan Lortie + */ + +#ifndef __G_SOCKET_OUTPUT_STREAM_H__ +#define __G_SOCKET_OUTPUT_STREAM_H__ + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_OUTPUT_STREAM (_g_socket_output_stream_get_type ()) +#define G_SOCKET_OUTPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SOCKET_OUTPUT_STREAM, GSocketOutputStream)) +#define G_SOCKET_OUTPUT_STREAM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SOCKET_OUTPUT_STREAM, GSocketOutputStreamClass)) +#define G_IS_SOCKET_OUTPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SOCKET_OUTPUT_STREAM)) +#define G_IS_SOCKET_OUTPUT_STREAM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SOCKET_OUTPUT_STREAM)) +#define G_SOCKET_OUTPUT_STREAM_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SOCKET_OUTPUT_STREAM, GSocketOutputStreamClass)) + +typedef struct _GSocketOutputStreamPrivate GSocketOutputStreamPrivate; +typedef struct _GSocketOutputStreamClass GSocketOutputStreamClass; +typedef struct _GSocketOutputStream GSocketOutputStream; + +struct _GSocketOutputStreamClass +{ + GOutputStreamClass parent_class; +}; + +struct _GSocketOutputStream +{ + GOutputStream parent_instance; + GSocketOutputStreamPrivate *priv; +}; + +GType _g_socket_output_stream_get_type (void) G_GNUC_CONST; +GSocketOutputStream * _g_socket_output_stream_new (GSocket *socket); + +G_END_DECLS + +#endif /* __G_SOCKET_OUTPUT_STREAM_H__ */ diff --git a/gio/gsocketservice.c b/gio/gsocketservice.c new file mode 100644 index 0000000..176c122 --- /dev/null +++ b/gio/gsocketservice.c @@ -0,0 +1,427 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * Copyright © 2009 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Alexander Larsson + */ + +/** + * SECTION:gsocketservice + * @title: GSocketService + * @short_description: Make it easy to implement a network service + * @include: gio/gio.h + * @see_also: #GThreadedSocketService, #GSocketListener. + * + * A #GSocketService is an object that represents a service that + * is provided to the network or over local sockets. When a new + * connection is made to the service the #GSocketService::incoming + * signal is emitted. + * + * A #GSocketService is a subclass of #GSocketListener and you need + * to add the addresses you want to accept connections on with the + * #GSocketListener APIs. + * + * There are two options for implementing a network service based on + * #GSocketService. The first is to create the service using + * g_socket_service_new() and to connect to the #GSocketService::incoming + * signal. The second is to subclass #GSocketService and override the + * default signal handler implementation. + * + * In either case, the handler must immediately return, or else it + * will block additional incoming connections from being serviced. + * If you are interested in writing connection handlers that contain + * blocking code then see #GThreadedSocketService. + * + * The socket service runs on the main loop of the + * [thread-default context][g-main-context-push-thread-default-context] + * of the thread it is created in, and is not + * threadsafe in general. However, the calls to start and stop the + * service are thread-safe so these can be used from threads that + * handle incoming clients. + * + * Since: 2.22 + */ + +#include "config.h" +#include "gsocketservice.h" + +#include +#include "gsocketlistener.h" +#include "gsocketconnection.h" +#include "glibintl.h" +#include "gmarshal-internal.h" + +struct _GSocketServicePrivate +{ + GCancellable *cancellable; + guint active : 1; + guint outstanding_accept : 1; +}; + +static guint g_socket_service_incoming_signal; + +G_LOCK_DEFINE_STATIC(active); + +G_DEFINE_TYPE_WITH_PRIVATE (GSocketService, g_socket_service, G_TYPE_SOCKET_LISTENER) + +enum +{ + PROP_0, + PROP_ACTIVE +}; + +static void g_socket_service_ready (GObject *object, + GAsyncResult *result, + gpointer user_data); + +static gboolean +g_socket_service_real_incoming (GSocketService *service, + GSocketConnection *connection, + GObject *source_object) +{ + return FALSE; +} + +static void +g_socket_service_init (GSocketService *service) +{ + service->priv = g_socket_service_get_instance_private (service); + service->priv->cancellable = g_cancellable_new (); + service->priv->active = TRUE; +} + +static void +g_socket_service_finalize (GObject *object) +{ + GSocketService *service = G_SOCKET_SERVICE (object); + + g_object_unref (service->priv->cancellable); + + G_OBJECT_CLASS (g_socket_service_parent_class) + ->finalize (object); +} + +static void +do_accept (GSocketService *service) +{ + g_socket_listener_accept_async (G_SOCKET_LISTENER (service), + service->priv->cancellable, + g_socket_service_ready, NULL); + service->priv->outstanding_accept = TRUE; +} + +static gboolean +get_active (GSocketService *service) +{ + gboolean active; + + G_LOCK (active); + active = service->priv->active; + G_UNLOCK (active); + + return active; +} + +static void +set_active (GSocketService *service, gboolean active) +{ + gboolean notify = FALSE; + + active = !!active; + + G_LOCK (active); + + if (active != service->priv->active) + { + service->priv->active = active; + notify = TRUE; + + if (active) + { + if (service->priv->outstanding_accept) + g_cancellable_cancel (service->priv->cancellable); + else + do_accept (service); + } + else + { + if (service->priv->outstanding_accept) + g_cancellable_cancel (service->priv->cancellable); + } + } + + G_UNLOCK (active); + + if (notify) + g_object_notify (G_OBJECT (service), "active"); +} + +static void +g_socket_service_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSocketService *service = G_SOCKET_SERVICE (object); + + switch (prop_id) + { + case PROP_ACTIVE: + g_value_set_boolean (value, get_active (service)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_socket_service_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSocketService *service = G_SOCKET_SERVICE (object); + + switch (prop_id) + { + case PROP_ACTIVE: + set_active (service, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_socket_service_changed (GSocketListener *listener) +{ + GSocketService *service = G_SOCKET_SERVICE (listener); + + G_LOCK (active); + + if (service->priv->active) + { + if (service->priv->outstanding_accept) + g_cancellable_cancel (service->priv->cancellable); + else + do_accept (service); + } + + G_UNLOCK (active); +} + +/** + * g_socket_service_is_active: + * @service: a #GSocketService + * + * Check whether the service is active or not. An active + * service will accept new clients that connect, while + * a non-active service will let connecting clients queue + * up until the service is started. + * + * Returns: %TRUE if the service is active, %FALSE otherwise + * + * Since: 2.22 + */ +gboolean +g_socket_service_is_active (GSocketService *service) +{ + g_return_val_if_fail (G_IS_SOCKET_SERVICE (service), FALSE); + + return get_active (service); +} + +/** + * g_socket_service_start: + * @service: a #GSocketService + * + * Restarts the service, i.e. start accepting connections + * from the added sockets when the mainloop runs. This only needs + * to be called after the service has been stopped from + * g_socket_service_stop(). + * + * This call is thread-safe, so it may be called from a thread + * handling an incoming client request. + * + * Since: 2.22 + */ +void +g_socket_service_start (GSocketService *service) +{ + g_return_if_fail (G_IS_SOCKET_SERVICE (service)); + + set_active (service, TRUE); +} + +/** + * g_socket_service_stop: + * @service: a #GSocketService + * + * Stops the service, i.e. stops accepting connections + * from the added sockets when the mainloop runs. + * + * This call is thread-safe, so it may be called from a thread + * handling an incoming client request. + * + * Note that this only stops accepting new connections; it does not + * close the listening sockets, and you can call + * g_socket_service_start() again later to begin listening again. To + * close the listening sockets, call g_socket_listener_close(). (This + * will happen automatically when the #GSocketService is finalized.) + * + * This must be called before calling g_socket_listener_close() as + * the socket service will start accepting connections immediately + * when a new socket is added. + * + * Since: 2.22 + */ +void +g_socket_service_stop (GSocketService *service) +{ + g_return_if_fail (G_IS_SOCKET_SERVICE (service)); + + set_active (service, FALSE); +} + +static gboolean +g_socket_service_incoming (GSocketService *service, + GSocketConnection *connection, + GObject *source_object) +{ + gboolean result; + + g_signal_emit (service, g_socket_service_incoming_signal, + 0, connection, source_object, &result); + return result; +} + +static void +g_socket_service_class_init (GSocketServiceClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + GSocketListenerClass *listener_class = G_SOCKET_LISTENER_CLASS (class); + + gobject_class->finalize = g_socket_service_finalize; + gobject_class->set_property = g_socket_service_set_property; + gobject_class->get_property = g_socket_service_get_property; + listener_class->changed = g_socket_service_changed; + class->incoming = g_socket_service_real_incoming; + + /** + * GSocketService::incoming: + * @service: the #GSocketService + * @connection: a new #GSocketConnection object + * @source_object: (nullable): the source_object passed to + * g_socket_listener_add_address() + * + * The ::incoming signal is emitted when a new incoming connection + * to @service needs to be handled. The handler must initiate the + * handling of @connection, but may not block; in essence, + * asynchronous operations must be used. + * + * @connection will be unreffed once the signal handler returns, + * so you need to ref it yourself if you are planning to use it. + * + * Returns: %TRUE to stop other handlers from being called + * + * Since: 2.22 + */ + g_socket_service_incoming_signal = + g_signal_new (I_("incoming"), G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GSocketServiceClass, incoming), + g_signal_accumulator_true_handled, NULL, + _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECT, + G_TYPE_BOOLEAN, + 2, G_TYPE_SOCKET_CONNECTION, G_TYPE_OBJECT); + g_signal_set_va_marshaller (g_socket_service_incoming_signal, + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECTv); + + /** + * GSocketService:active: + * + * Whether the service is currently accepting connections. + * + * Since: 2.46 + */ + g_object_class_install_property (gobject_class, PROP_ACTIVE, + g_param_spec_boolean ("active", + P_("Active"), + P_("Whether the service is currently accepting connections"), + TRUE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +g_socket_service_ready (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSocketListener *listener = G_SOCKET_LISTENER (object); + GSocketService *service = G_SOCKET_SERVICE (object); + GSocketConnection *connection; + GObject *source_object; + GError *error = NULL; + + connection = g_socket_listener_accept_finish (listener, result, &source_object, &error); + if (error) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("fail: %s", error->message); + g_error_free (error); + } + else + { + g_socket_service_incoming (service, connection, source_object); + g_object_unref (connection); + } + + G_LOCK (active); + + g_cancellable_reset (service->priv->cancellable); + + /* requeue */ + service->priv->outstanding_accept = FALSE; + if (service->priv->active) + do_accept (service); + + G_UNLOCK (active); +} + +/** + * g_socket_service_new: + * + * Creates a new #GSocketService with no sockets to listen for. + * New listeners can be added with e.g. g_socket_listener_add_address() + * or g_socket_listener_add_inet_port(). + * + * New services are created active, there is no need to call + * g_socket_service_start(), unless g_socket_service_stop() has been + * called before. + * + * Returns: a new #GSocketService. + * + * Since: 2.22 + */ +GSocketService * +g_socket_service_new (void) +{ + return g_object_new (G_TYPE_SOCKET_SERVICE, NULL); +} diff --git a/gio/gsocketservice.h b/gio/gsocketservice.h new file mode 100644 index 0000000..4dc1e8f --- /dev/null +++ b/gio/gsocketservice.h @@ -0,0 +1,93 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * Copyright © 2009 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Alexander Larsson + */ + +#ifndef __G_SOCKET_SERVICE_H__ +#define __G_SOCKET_SERVICE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKET_SERVICE (g_socket_service_get_type ()) +#define G_SOCKET_SERVICE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_SOCKET_SERVICE, GSocketService)) +#define G_SOCKET_SERVICE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_SOCKET_SERVICE, GSocketServiceClass)) +#define G_IS_SOCKET_SERVICE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_SOCKET_SERVICE)) +#define G_IS_SOCKET_SERVICE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_SOCKET_SERVICE)) +#define G_SOCKET_SERVICE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_SOCKET_SERVICE, GSocketServiceClass)) + +typedef struct _GSocketServicePrivate GSocketServicePrivate; +typedef struct _GSocketServiceClass GSocketServiceClass; + +/** + * GSocketServiceClass: + * @incoming: signal emitted when new connections are accepted + * + * Class structure for #GSocketService. + */ +struct _GSocketServiceClass +{ + GSocketListenerClass parent_class; + + gboolean (* incoming) (GSocketService *service, + GSocketConnection *connection, + GObject *source_object); + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); +}; + +struct _GSocketService +{ + GSocketListener parent_instance; + GSocketServicePrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_socket_service_get_type (void); + +GLIB_AVAILABLE_IN_ALL +GSocketService *g_socket_service_new (void); +GLIB_AVAILABLE_IN_ALL +void g_socket_service_start (GSocketService *service); +GLIB_AVAILABLE_IN_ALL +void g_socket_service_stop (GSocketService *service); +GLIB_AVAILABLE_IN_ALL +gboolean g_socket_service_is_active (GSocketService *service); + + +G_END_DECLS + +#endif /* __G_SOCKET_SERVICE_H__ */ diff --git a/gio/gsocks4aproxy.c b/gio/gsocks4aproxy.c new file mode 100644 index 0000000..988ddaf --- /dev/null +++ b/gio/gsocks4aproxy.c @@ -0,0 +1,458 @@ + /* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#include "config.h" + +#include "gsocks4aproxy.h" + +#include + +#include "giomodule.h" +#include "giomodule-priv.h" +#include "giostream.h" +#include "ginetaddress.h" +#include "ginputstream.h" +#include "glibintl.h" +#include "goutputstream.h" +#include "gproxy.h" +#include "gproxyaddress.h" +#include "gtask.h" + +#define SOCKS4_VERSION 4 + +#define SOCKS4_CMD_CONNECT 1 +#define SOCKS4_CMD_BIND 2 + +#define SOCKS4_MAX_LEN 255 + +#define SOCKS4_REP_VERSION 0 +#define SOCKS4_REP_GRANTED 90 +#define SOCKS4_REP_REJECTED 91 +#define SOCKS4_REP_NO_IDENT 92 +#define SOCKS4_REP_BAD_IDENT 93 + +static void g_socks4a_proxy_iface_init (GProxyInterface *proxy_iface); + +#define g_socks4a_proxy_get_type _g_socks4a_proxy_get_type +G_DEFINE_TYPE_WITH_CODE (GSocks4aProxy, g_socks4a_proxy, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY, + g_socks4a_proxy_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME, + g_define_type_id, + "socks4a", + 0)) + +static void +g_socks4a_proxy_finalize (GObject *object) +{ + /* must chain up */ + G_OBJECT_CLASS (g_socks4a_proxy_parent_class)->finalize (object); +} + +static void +g_socks4a_proxy_init (GSocks4aProxy *proxy) +{ + proxy->supports_hostname = TRUE; +} + +/* |-> SOCKSv4a only + * +----+----+----+----+----+----+----+----+----+----+....+----+------+....+------+ + * | VN | CD | DSTPORT | DSTIP | USERID |NULL| HOST | | NULL | + * +----+----+----+----+----+----+----+----+----+----+....+----+------+....+------+ + * 1 1 2 4 variable 1 variable + */ +#define SOCKS4_CONN_MSG_LEN (9 + SOCKS4_MAX_LEN * 2) +static gint +set_connect_msg (guint8 *msg, + const gchar *hostname, + guint16 port, + const char *username, + GError **error) +{ + GInetAddress *addr; + guint len = 0; + gsize addr_len; + gboolean is_ip; + const gchar *ip; + + msg[len++] = SOCKS4_VERSION; + msg[len++] = SOCKS4_CMD_CONNECT; + + { + guint16 hp = g_htons (port); + memcpy (msg + len, &hp, 2); + len += 2; + } + + is_ip = g_hostname_is_ip_address (hostname); + + if (is_ip) + ip = hostname; + else + ip = "0.0.0.1"; + + addr = g_inet_address_new_from_string (ip); + addr_len = g_inet_address_get_native_size (addr); + + if (addr_len != 4) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("SOCKSv4 does not support IPv6 address “%sâ€"), + ip); + g_object_unref (addr); + return -1; + } + + memcpy (msg + len, g_inet_address_to_bytes (addr), addr_len); + len += addr_len; + + g_object_unref (addr); + + if (username) + { + gsize user_len = strlen (username); + + if (user_len > SOCKS4_MAX_LEN) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("Username is too long for SOCKSv4 protocol")); + return -1; + } + + memcpy (msg + len, username, user_len); + len += user_len; + } + + msg[len++] = '\0'; + + if (!is_ip) + { + gsize host_len = strlen (hostname); + + if (host_len > SOCKS4_MAX_LEN) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("Hostname “%s†is too long for SOCKSv4 protocol"), + hostname); + return -1; + } + + memcpy (msg + len, hostname, host_len); + len += host_len; + msg[len++] = '\0'; + } + + return len; +} + +/* + * +----+----+----+----+----+----+----+----+ + * | VN | CD | DSTPORT | DSTIP | + * +----+----+----+----+----+----+----+----+ + * 1 1 2 4 + */ +#define SOCKS4_CONN_REP_LEN 8 +static gboolean +parse_connect_reply (const guint8 *data, GError **error) +{ + if (data[0] != SOCKS4_REP_VERSION) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("The server is not a SOCKSv4 proxy server.")); + return FALSE; + } + + if (data[1] != SOCKS4_REP_GRANTED) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("Connection through SOCKSv4 server was rejected")); + return FALSE; + } + + return TRUE; +} + +static GIOStream * +g_socks4a_proxy_connect (GProxy *proxy, + GIOStream *io_stream, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GError **error) +{ + GInputStream *in; + GOutputStream *out; + const gchar *hostname; + guint16 port; + const gchar *username; + + hostname = g_proxy_address_get_destination_hostname (proxy_address); + port = g_proxy_address_get_destination_port (proxy_address); + username = g_proxy_address_get_username (proxy_address); + + in = g_io_stream_get_input_stream (io_stream); + out = g_io_stream_get_output_stream (io_stream); + + /* Send SOCKS4 connection request */ + { + guint8 msg[SOCKS4_CONN_MSG_LEN]; + gint len; + + len = set_connect_msg (msg, hostname, port, username, error); + + if (len < 0) + goto error; + + if (!g_output_stream_write_all (out, msg, len, NULL, + cancellable, error)) + goto error; + } + + /* Read SOCKS4 response */ + { + guint8 data[SOCKS4_CONN_REP_LEN]; + + if (!g_input_stream_read_all (in, data, SOCKS4_CONN_REP_LEN, NULL, + cancellable, error)) + goto error; + + if (!parse_connect_reply (data, error)) + goto error; + } + + return g_object_ref (io_stream); + +error: + return NULL; +} + + +typedef struct +{ + GIOStream *io_stream; + + /* For connecting */ + guint8 *buffer; + gssize length; + gssize offset; + +} ConnectAsyncData; + +static void connect_msg_write_cb (GObject *source, + GAsyncResult *result, + gpointer user_data); +static void connect_reply_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data); + +static void +free_connect_data (ConnectAsyncData *data) +{ + g_object_unref (data->io_stream); + g_slice_free (ConnectAsyncData, data); +} + +static void +do_read (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data) +{ + GInputStream *in; + in = g_io_stream_get_input_stream (data->io_stream); + g_input_stream_read_async (in, + data->buffer + data->offset, + data->length - data->offset, + g_task_get_priority (task), + g_task_get_cancellable (task), + callback, task); +} + +static void +do_write (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data) +{ + GOutputStream *out; + out = g_io_stream_get_output_stream (data->io_stream); + g_output_stream_write_async (out, + data->buffer + data->offset, + data->length - data->offset, + g_task_get_priority (task), + g_task_get_cancellable (task), + callback, task); +} + + + +static void +g_socks4a_proxy_connect_async (GProxy *proxy, + GIOStream *io_stream, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GError *error = NULL; + GTask *task; + ConnectAsyncData *data; + const gchar *hostname; + guint16 port; + const gchar *username; + + data = g_slice_new0 (ConnectAsyncData); + data->io_stream = g_object_ref (io_stream); + + task = g_task_new (proxy, cancellable, callback, user_data); + g_task_set_source_tag (task, g_socks4a_proxy_connect_async); + g_task_set_task_data (task, data, (GDestroyNotify) free_connect_data); + + hostname = g_proxy_address_get_destination_hostname (proxy_address); + port = g_proxy_address_get_destination_port (proxy_address); + username = g_proxy_address_get_username (proxy_address); + + data->buffer = g_malloc0 (SOCKS4_CONN_MSG_LEN); + data->length = set_connect_msg (data->buffer, + hostname, port, username, + &error); + data->offset = 0; + + if (data->length < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + } + else + { + do_write (connect_msg_write_cb, task, data); + } +} + +static void +connect_msg_write_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize written; + + written = g_output_stream_write_finish (G_OUTPUT_STREAM (source), + result, &error); + + if (written < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + data->offset += written; + + if (data->offset == data->length) + { + g_free (data->buffer); + + data->buffer = g_malloc0 (SOCKS4_CONN_REP_LEN); + data->length = SOCKS4_CONN_REP_LEN; + data->offset = 0; + + do_read (connect_reply_read_cb, task, data); + } + else + { + do_write (connect_msg_write_cb, task, data); + } +} + +static void +connect_reply_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize read; + + read = g_input_stream_read_finish (G_INPUT_STREAM (source), + result, &error); + + if (read < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + data->offset += read; + + if (data->offset == data->length) + { + if (!parse_connect_reply (data->buffer, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + else + { + g_task_return_pointer (task, g_object_ref (data->io_stream), g_object_unref); + g_object_unref (task); + return; + } + } + else + { + do_read (connect_reply_read_cb, task, data); + } +} + +static GIOStream *g_socks4a_proxy_connect_finish (GProxy *proxy, + GAsyncResult *result, + GError **error); + +static GIOStream * +g_socks4a_proxy_connect_finish (GProxy *proxy, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (result), error); +} + +static gboolean +g_socks4a_proxy_supports_hostname (GProxy *proxy) +{ + return G_SOCKS4A_PROXY (proxy)->supports_hostname; +} + +static void +g_socks4a_proxy_class_init (GSocks4aProxyClass *class) +{ + GObjectClass *object_class; + + object_class = (GObjectClass *) class; + object_class->finalize = g_socks4a_proxy_finalize; +} + +static void +g_socks4a_proxy_iface_init (GProxyInterface *proxy_iface) +{ + proxy_iface->connect = g_socks4a_proxy_connect; + proxy_iface->connect_async = g_socks4a_proxy_connect_async; + proxy_iface->connect_finish = g_socks4a_proxy_connect_finish; + proxy_iface->supports_hostname = g_socks4a_proxy_supports_hostname; +} diff --git a/gio/gsocks4aproxy.h b/gio/gsocks4aproxy.h new file mode 100644 index 0000000..d326621 --- /dev/null +++ b/gio/gsocks4aproxy.h @@ -0,0 +1,53 @@ + /* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#ifndef __G_SOCKS4A_PROXY_H__ +#define __G_SOCKS4A_PROXY_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKS4A_PROXY (_g_socks4a_proxy_get_type ()) +#define G_SOCKS4A_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOCKS4A_PROXY, GSocks4aProxy)) +#define G_SOCKS4A_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SOCKS4A_PROXY, GSocks4aProxyClass)) +#define G_IS_SOCKS4A_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SOCKS4A_PROXY)) +#define G_IS_SOCKS4A_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SOCKS4A_PROXY)) +#define G_SOCKS4A_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SOCKS4A_PROXY, GSocks4aProxyClass)) + +typedef struct _GSocks4aProxy GSocks4aProxy; +typedef struct _GSocks4aProxyClass GSocks4aProxyClass; + +struct _GSocks4aProxy +{ + GObject parent; + gboolean supports_hostname; +}; + +struct _GSocks4aProxyClass +{ + GObjectClass parent_class; +}; + +GType _g_socks4a_proxy_get_type (void); + +G_END_DECLS + +#endif /* __SOCKS5_PROXY_H__ */ diff --git a/gio/gsocks4proxy.c b/gio/gsocks4proxy.c new file mode 100644 index 0000000..ad176ff --- /dev/null +++ b/gio/gsocks4proxy.c @@ -0,0 +1,69 @@ + /* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#include "config.h" + +#include "gsocks4proxy.h" + +#include "giomodule.h" +#include "giomodule-priv.h" +#include "gproxy.h" +#include "gsocks4aproxy.h" + +struct _GSocks4Proxy +{ + GSocks4aProxy parent; +}; + +struct _GSocks4ProxyClass +{ + GSocks4aProxyClass parent_class; +}; + +#define g_socks4_proxy_get_type _g_socks4_proxy_get_type +G_DEFINE_TYPE_WITH_CODE (GSocks4Proxy, g_socks4_proxy, G_TYPE_SOCKS4A_PROXY, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME, + g_define_type_id, + "socks4", + 0)) + +static void +g_socks4_proxy_finalize (GObject *object) +{ + /* must chain up */ + G_OBJECT_CLASS (g_socks4_proxy_parent_class)->finalize (object); +} + +static void +g_socks4_proxy_init (GSocks4Proxy *proxy) +{ + G_SOCKS4A_PROXY (proxy)->supports_hostname = FALSE; +} + + +static void +g_socks4_proxy_class_init (GSocks4ProxyClass *class) +{ + GObjectClass *object_class; + + object_class = (GObjectClass *) class; + object_class->finalize = g_socks4_proxy_finalize; +} diff --git a/gio/gsocks4proxy.h b/gio/gsocks4proxy.h new file mode 100644 index 0000000..59cc99e --- /dev/null +++ b/gio/gsocks4proxy.h @@ -0,0 +1,42 @@ + /* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#ifndef __G_SOCKS4_PROXY_H__ +#define __G_SOCKS4_PROXY_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKS4_PROXY (_g_socks4_proxy_get_type ()) +#define G_SOCKS4_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOCKS4_PROXY, GSocks4Proxy)) +#define G_SOCKS4_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SOCKS4_PROXY, GSocks4ProxyClass)) +#define G_IS_SOCKS4_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SOCKS4_PROXY)) +#define G_IS_SOCKS4_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SOCKS4_PROXY)) +#define G_SOCKS4_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SOCKS4_PROXY, GSocks4ProxyClass)) + +typedef struct _GSocks4Proxy GSocks4Proxy; +typedef struct _GSocks4ProxyClass GSocks4ProxyClass; + +GType _g_socks4_proxy_get_type (void); + +G_END_DECLS + +#endif /* __SOCKS5_PROXY_H__ */ diff --git a/gio/gsocks5proxy.c b/gio/gsocks5proxy.c new file mode 100644 index 0000000..948ac8b --- /dev/null +++ b/gio/gsocks5proxy.c @@ -0,0 +1,1109 @@ + /* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008, 2010 Collabora, Ltd. + * Copyright (C) 2008 Nokia Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Youness Alaoui + */ + +#include "config.h" + +#include "gsocks5proxy.h" + +#include + +#include "giomodule.h" +#include "giomodule-priv.h" +#include "giostream.h" +#include "ginetaddress.h" +#include "ginputstream.h" +#include "glibintl.h" +#include "goutputstream.h" +#include "gproxy.h" +#include "gproxyaddress.h" +#include "gtask.h" + +#define SOCKS5_VERSION 0x05 + +#define SOCKS5_CMD_CONNECT 0x01 +#define SOCKS5_CMD_BIND 0x02 +#define SOCKS5_CMD_UDP_ASSOCIATE 0x03 + +#define SOCKS5_ATYP_IPV4 0x01 +#define SOCKS5_ATYP_DOMAINNAME 0x03 +#define SOCKS5_ATYP_IPV6 0x04 + +#define SOCKS5_AUTH_VERSION 0x01 + +#define SOCKS5_AUTH_NONE 0x00 +#define SOCKS5_AUTH_GSSAPI 0x01 +#define SOCKS5_AUTH_USR_PASS 0x02 +#define SOCKS5_AUTH_NO_ACCEPT 0xff + +#define SOCKS5_MAX_LEN 255 +#define SOCKS5_RESERVED 0x00 + +#define SOCKS5_REP_SUCCEEDED 0x00 +#define SOCKS5_REP_SRV_FAILURE 0x01 +#define SOCKS5_REP_NOT_ALLOWED 0x02 +#define SOCKS5_REP_NET_UNREACH 0x03 +#define SOCKS5_REP_HOST_UNREACH 0x04 +#define SOCKS5_REP_REFUSED 0x05 +#define SOCKS5_REP_TTL_EXPIRED 0x06 +#define SOCKS5_REP_CMD_NOT_SUP 0x07 +#define SOCKS5_REP_ATYPE_NOT_SUP 0x08 + + +struct _GSocks5Proxy +{ + GObject parent; +}; + +struct _GSocks5ProxyClass +{ + GObjectClass parent_class; +}; + +static void g_socks5_proxy_iface_init (GProxyInterface *proxy_iface); + +#define g_socks5_proxy_get_type _g_socks5_proxy_get_type +G_DEFINE_TYPE_WITH_CODE (GSocks5Proxy, g_socks5_proxy, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY, + g_socks5_proxy_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME, + g_define_type_id, + "socks5", + 0)) + +static void +g_socks5_proxy_finalize (GObject *object) +{ + /* must chain up */ + G_OBJECT_CLASS (g_socks5_proxy_parent_class)->finalize (object); +} + +static void +g_socks5_proxy_init (GSocks5Proxy *proxy) +{ +} + +/* + * +----+----------+----------+ + * |VER | NMETHODS | METHODS | + * +----+----------+----------+ + * | 1 | 1 | 1 to 255 | + * +----+----------+----------+ + */ +#define SOCKS5_NEGO_MSG_LEN 4 +static gint +set_nego_msg (guint8 *msg, gboolean has_auth) +{ + gint len = 3; + + msg[0] = SOCKS5_VERSION; + msg[1] = 0x01; /* number of methods supported */ + msg[2] = SOCKS5_AUTH_NONE; + + /* add support for authentication method */ + if (has_auth) + { + msg[1] = 0x02; /* number of methods supported */ + msg[3] = SOCKS5_AUTH_USR_PASS; + len++; + } + + return len; +} + + +/* + * +----+--------+ + * |VER | METHOD | + * +----+--------+ + * | 1 | 1 | + * +----+--------+ + */ +#define SOCKS5_NEGO_REP_LEN 2 +static gboolean +parse_nego_reply (const guint8 *data, + gboolean has_auth, + gboolean *must_auth, + GError **error) +{ + if (data[0] != SOCKS5_VERSION) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("The server is not a SOCKSv5 proxy server.")); + return FALSE; + } + + switch (data[1]) + { + case SOCKS5_AUTH_NONE: + *must_auth = FALSE; + break; + + case SOCKS5_AUTH_USR_PASS: + if (!has_auth) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NEED_AUTH, + _("The SOCKSv5 proxy requires authentication.")); + return FALSE; + } + *must_auth = TRUE; + break; + + case SOCKS5_AUTH_NO_ACCEPT: + if (!has_auth) + { + /* The server has said it accepts none of our authentication methods, + * but given the slightly odd implementation of set_nego_msg(), we + * actually only gave it the choice of %SOCKS5_AUTH_NONE, since the + * caller specified no username or password. + * Return %G_IO_ERROR_PROXY_NEED_AUTH so the caller knows that if + * they specify a username and password and try again, authentication + * might succeed (since we’ll send %SOCKS5_AUTH_USR_PASS next time). */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NEED_AUTH, + _("The SOCKSv5 proxy requires authentication.")); + return FALSE; + } + G_GNUC_FALLTHROUGH; + case SOCKS5_AUTH_GSSAPI: + default: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED, + _("The SOCKSv5 proxy requires an authentication " + "method that is not supported by GLib.")); + return FALSE; + break; + } + + return TRUE; +} + +#define SOCKS5_AUTH_MSG_LEN 515 +static gint +set_auth_msg (guint8 *msg, + const gchar *username, + const gchar *password, + GError **error) +{ + gint len = 0; + gint ulen = 0; /* username length */ + gint plen = 0; /* Password length */ + + if (username) + ulen = strlen (username); + + if (password) + plen = strlen (password); + + if (ulen > SOCKS5_MAX_LEN || plen > SOCKS5_MAX_LEN) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("Username or password is too long for SOCKSv5 " + "protocol.")); + return -1; + } + + msg[len++] = SOCKS5_AUTH_VERSION; + msg[len++] = ulen; + + if (ulen > 0) + memcpy (msg + len, username, ulen); + + len += ulen; + msg[len++] = plen; + + if (plen > 0) + memcpy (msg + len, password, plen); + + len += plen; + + return len; +} + + +static gboolean +check_auth_status (const guint8 *data, GError **error) +{ + if (data[0] != SOCKS5_AUTH_VERSION + || data[1] != SOCKS5_REP_SUCCEEDED) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED, + _("SOCKSv5 authentication failed due to wrong " + "username or password.")); + return FALSE; + } + return TRUE; +} + +/* + * +----+-----+-------+------+----------+----------+ + * |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | + * +----+-----+-------+------+----------+----------+ + * | 1 | 1 | X'00' | 1 | Variable | 2 | + * +----+-----+-------+------+----------+----------+ + * DST.ADDR is a string with first byte being the size. So DST.ADDR may not be + * longer then 256 bytes. + */ +#define SOCKS5_CONN_MSG_LEN 262 +static gint +set_connect_msg (guint8 *msg, + const gchar *hostname, + guint16 port, + GError **error) +{ + guint len = 0; + + msg[len++] = SOCKS5_VERSION; + msg[len++] = SOCKS5_CMD_CONNECT; + msg[len++] = SOCKS5_RESERVED; + + if (g_hostname_is_ip_address (hostname)) + { + GInetAddress *addr = g_inet_address_new_from_string (hostname); + gsize addr_len = g_inet_address_get_native_size (addr); + + /* We are cheating for simplicity, here's the logic: + * 1 = IPV4 = 4 bytes / 4 + * 4 = IPV6 = 16 bytes / 4 */ + msg[len++] = addr_len / 4; + memcpy (msg + len, g_inet_address_to_bytes (addr), addr_len); + len += addr_len; + + g_object_unref (addr); + } + else + { + gsize host_len = strlen (hostname); + + if (host_len > SOCKS5_MAX_LEN) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("Hostname “%s†is too long for SOCKSv5 protocol"), + hostname); + return -1; + } + + msg[len++] = SOCKS5_ATYP_DOMAINNAME; + msg[len++] = (guint8) host_len; + memcpy (msg + len, hostname, host_len); + len += host_len; + } + + { + guint16 hp = g_htons (port); + memcpy (msg + len, &hp, 2); + len += 2; + } + + return len; +} + +/* + * +----+-----+-------+------+----------+----------+ + * |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | + * +----+-----+-------+------+----------+----------+ + * | 1 | 1 | X'00' | 1 | Variable | 2 | + * +----+-----+-------+------+----------+----------+ + * This reply need to be read by small part to determine size. Buffer + * size is determined in function of the biggest part to read. + * + * The parser only requires 4 bytes. + */ +#define SOCKS5_CONN_REP_LEN 257 +static gboolean +parse_connect_reply (const guint8 *data, gint *atype, GError **error) +{ + if (data[0] != SOCKS5_VERSION) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("The server is not a SOCKSv5 proxy server.")); + return FALSE; + } + + switch (data[1]) + { + case SOCKS5_REP_SUCCEEDED: + if (data[2] != SOCKS5_RESERVED) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("The server is not a SOCKSv5 proxy server.")); + return FALSE; + } + + switch (data[3]) + { + case SOCKS5_ATYP_IPV4: + case SOCKS5_ATYP_IPV6: + case SOCKS5_ATYP_DOMAINNAME: + *atype = data[3]; + break; + + default: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("The SOCKSv5 proxy server uses unknown address type.")); + return FALSE; + } + break; + + case SOCKS5_REP_SRV_FAILURE: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("Internal SOCKSv5 proxy server error.")); + return FALSE; + break; + + case SOCKS5_REP_NOT_ALLOWED: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NOT_ALLOWED, + _("SOCKSv5 connection not allowed by ruleset.")); + return FALSE; + break; + + case SOCKS5_REP_TTL_EXPIRED: + case SOCKS5_REP_HOST_UNREACH: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, + _("Host unreachable through SOCKSv5 server.")); + return FALSE; + break; + + case SOCKS5_REP_NET_UNREACH: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE, + _("Network unreachable through SOCKSv5 proxy.")); + return FALSE; + break; + + case SOCKS5_REP_REFUSED: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED, + _("Connection refused through SOCKSv5 proxy.")); + return FALSE; + break; + + case SOCKS5_REP_CMD_NOT_SUP: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("SOCKSv5 proxy does not support “connect†command.")); + return FALSE; + break; + + case SOCKS5_REP_ATYPE_NOT_SUP: + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("SOCKSv5 proxy does not support provided address type.")); + return FALSE; + break; + + default: /* Unknown error */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED, + _("Unknown SOCKSv5 proxy error.")); + return FALSE; + break; + } + + return TRUE; +} + +static GIOStream * +g_socks5_proxy_connect (GProxy *proxy, + GIOStream *io_stream, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GError **error) +{ + gboolean has_auth; + GInputStream *in; + GOutputStream *out; + const gchar *hostname; + guint16 port; + const gchar *username; + const gchar *password; + + hostname = g_proxy_address_get_destination_hostname (proxy_address); + port = g_proxy_address_get_destination_port (proxy_address); + username = g_proxy_address_get_username (proxy_address); + password = g_proxy_address_get_password (proxy_address); + + has_auth = username || password; + + in = g_io_stream_get_input_stream (io_stream); + out = g_io_stream_get_output_stream (io_stream); + + /* Send SOCKS5 handshake */ + { + guint8 msg[SOCKS5_NEGO_MSG_LEN]; + gint len; + + len = set_nego_msg (msg, has_auth); + + if (!g_output_stream_write_all (out, msg, len, NULL, + cancellable, error)) + goto error; + } + + /* Receive SOCKS5 response and reply with authentication if required */ + { + guint8 data[SOCKS5_NEGO_REP_LEN]; + gboolean must_auth = FALSE; + + if (!g_input_stream_read_all (in, data, sizeof (data), NULL, + cancellable, error)) + goto error; + + if (!parse_nego_reply (data, has_auth, &must_auth, error)) + goto error; + + if (must_auth) + { + guint8 msg[SOCKS5_AUTH_MSG_LEN]; + gint len; + + len = set_auth_msg (msg, username, password, error); + + if (len < 0) + goto error; + + if (!g_output_stream_write_all (out, msg, len, NULL, + cancellable, error)) + goto error; + + if (!g_input_stream_read_all (in, data, sizeof (data), NULL, + cancellable, error)) + goto error; + + if (!check_auth_status (data, error)) + goto error; + } + } + + /* Send SOCKS5 connection request */ + { + guint8 msg[SOCKS5_CONN_MSG_LEN]; + gint len; + + len = set_connect_msg (msg, hostname, port, error); + + if (len < 0) + goto error; + + if (!g_output_stream_write_all (out, msg, len, NULL, + cancellable, error)) + goto error; + } + + /* Read SOCKS5 response */ + { + guint8 data[SOCKS5_CONN_REP_LEN]; + gint atype; + + if (!g_input_stream_read_all (in, data, 4 /* VER, REP, RSV, ATYP */, NULL, + cancellable, error)) + goto error; + + if (!parse_connect_reply (data, &atype, error)) + goto error; + + switch (atype) + { + case SOCKS5_ATYP_IPV4: + if (!g_input_stream_read_all (in, data, + 4 /* IPv4 length */ + 2 /* port */, + NULL, cancellable, error)) + goto error; + break; + + case SOCKS5_ATYP_IPV6: + if (!g_input_stream_read_all (in, data, + 16 /* IPv6 length */ + 2 /* port */, + NULL, cancellable, error)) + goto error; + break; + + case SOCKS5_ATYP_DOMAINNAME: + if (!g_input_stream_read_all (in, data, 1 /* domain name length */, + NULL, cancellable, error)) + goto error; + if (!g_input_stream_read_all (in, data, + data[0] /* domain name length */ + 2 /* port */, + NULL, cancellable, error)) + goto error; + break; + } + } + + return g_object_ref (io_stream); + +error: + return NULL; +} + + +typedef struct +{ + GIOStream *io_stream; + gchar *hostname; + guint16 port; + gchar *username; + gchar *password; + guint8 *buffer; + gssize length; + gssize offset; +} ConnectAsyncData; + +static void nego_msg_write_cb (GObject *source, + GAsyncResult *res, + gpointer user_data); +static void nego_reply_read_cb (GObject *source, + GAsyncResult *res, + gpointer user_data); +static void auth_msg_write_cb (GObject *source, + GAsyncResult *res, + gpointer user_data); +static void auth_reply_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data); +static void send_connect_msg (GTask *task); +static void connect_msg_write_cb (GObject *source, + GAsyncResult *result, + gpointer user_data); +static void connect_reply_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data); +static void connect_addr_len_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data); +static void connect_addr_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data); + +static void +free_connect_data (ConnectAsyncData *data) +{ + g_object_unref (data->io_stream); + + g_free (data->hostname); + g_free (data->username); + g_free (data->password); + g_free (data->buffer); + + g_slice_free (ConnectAsyncData, data); +} + +static void +do_read (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data) +{ + GInputStream *in; + in = g_io_stream_get_input_stream (data->io_stream); + g_input_stream_read_async (in, + data->buffer + data->offset, + data->length - data->offset, + g_task_get_priority (task), + g_task_get_cancellable (task), + callback, task); +} + +static void +do_write (GAsyncReadyCallback callback, GTask *task, ConnectAsyncData *data) +{ + GOutputStream *out; + out = g_io_stream_get_output_stream (data->io_stream); + g_output_stream_write_async (out, + data->buffer + data->offset, + data->length - data->offset, + g_task_get_priority (task), + g_task_get_cancellable (task), + callback, task); +} + +static void +g_socks5_proxy_connect_async (GProxy *proxy, + GIOStream *io_stream, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + ConnectAsyncData *data; + + data = g_slice_new0 (ConnectAsyncData); + data->io_stream = g_object_ref (io_stream); + + task = g_task_new (proxy, cancellable, callback, user_data); + g_task_set_source_tag (task, g_socks5_proxy_connect_async); + g_task_set_task_data (task, data, (GDestroyNotify) free_connect_data); + + g_object_get (G_OBJECT (proxy_address), + "destination-hostname", &data->hostname, + "destination-port", &data->port, + "username", &data->username, + "password", &data->password, + NULL); + + data->buffer = g_malloc0 (SOCKS5_NEGO_MSG_LEN); + data->length = set_nego_msg (data->buffer, + data->username || data->password); + data->offset = 0; + + do_write (nego_msg_write_cb, task, data); +} + + +static void +nego_msg_write_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize written; + + written = g_output_stream_write_finish (G_OUTPUT_STREAM (source), + res, &error); + + if (written < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + data->offset += written; + + if (data->offset == data->length) + { + g_free (data->buffer); + + data->buffer = g_malloc0 (SOCKS5_NEGO_REP_LEN); + data->length = SOCKS5_NEGO_REP_LEN; + data->offset = 0; + + do_read (nego_reply_read_cb, task, data); + } + else + { + do_write (nego_msg_write_cb, task, data); + } +} + +static void +nego_reply_read_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize read; + + read = g_input_stream_read_finish (G_INPUT_STREAM (source), + res, &error); + + if (read < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (read == 0) + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); + g_object_unref (task); + return; + } + + data->offset += read; + + if (data->offset == data->length) + { + GError *error = NULL; + gboolean must_auth = FALSE; + gboolean has_auth = data->username || data->password; + + if (!parse_nego_reply (data->buffer, has_auth, &must_auth, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (must_auth) + { + g_free (data->buffer); + + data->buffer = g_malloc0 (SOCKS5_AUTH_MSG_LEN); + data->length = set_auth_msg (data->buffer, + data->username, + data->password, + &error); + data->offset = 0; + + if (data->length < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + do_write (auth_msg_write_cb, task, data); + } + else + { + send_connect_msg (task); + } + } + else + { + do_read (nego_reply_read_cb, task, data); + } +} + +static void +auth_msg_write_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize written; + + written = g_output_stream_write_finish (G_OUTPUT_STREAM (source), + result, &error); + + if (written < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + data->offset += written; + + if (data->offset == data->length) + { + g_free (data->buffer); + + data->buffer = g_malloc0 (SOCKS5_NEGO_REP_LEN); + data->length = SOCKS5_NEGO_REP_LEN; + data->offset = 0; + + do_read (auth_reply_read_cb, task, data); + } + else + { + do_write (auth_msg_write_cb, task, data); + } +} + +static void +auth_reply_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize read; + + read = g_input_stream_read_finish (G_INPUT_STREAM (source), + result, &error); + + if (read < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (read == 0) + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); + g_object_unref (task); + return; + } + + data->offset += read; + + if (data->offset == data->length) + { + if (!check_auth_status (data->buffer, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + send_connect_msg (task); + } + else + { + do_read (auth_reply_read_cb, task, data); + } +} + +static void +send_connect_msg (GTask *task) +{ + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + + g_free (data->buffer); + + data->buffer = g_malloc0 (SOCKS5_CONN_MSG_LEN); + data->length = set_connect_msg (data->buffer, + data->hostname, + data->port, + &error); + data->offset = 0; + + if (data->length < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + do_write (connect_msg_write_cb, task, data); +} + +static void +connect_msg_write_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize written; + + written = g_output_stream_write_finish (G_OUTPUT_STREAM (source), + result, &error); + + if (written < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + data->offset += written; + + if (data->offset == data->length) + { + g_free (data->buffer); + + data->buffer = g_malloc0 (SOCKS5_CONN_REP_LEN); + data->length = 4; + data->offset = 0; + + do_read (connect_reply_read_cb, task, data); + } + else + { + do_write (connect_msg_write_cb, task, data); + } +} + +static void +connect_reply_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize read; + + read = g_input_stream_read_finish (G_INPUT_STREAM (source), + result, &error); + + if (read < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (read == 0) + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); + g_object_unref (task); + return; + } + + data->offset += read; + + if (data->offset == data->length) + { + gint atype; + + if (!parse_connect_reply (data->buffer, &atype, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + switch (atype) + { + case SOCKS5_ATYP_IPV4: + data->length = 6; + data->offset = 0; + do_read (connect_addr_read_cb, task, data); + break; + + case SOCKS5_ATYP_IPV6: + data->length = 18; + data->offset = 0; + do_read (connect_addr_read_cb, task, data); + break; + + case SOCKS5_ATYP_DOMAINNAME: + data->length = 1; + data->offset = 0; + do_read (connect_addr_len_read_cb, task, data); + break; + } + } + else + { + do_read (connect_reply_read_cb, task, data); + } +} + +static void +connect_addr_len_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize read; + + read = g_input_stream_read_finish (G_INPUT_STREAM (source), + result, &error); + + if (read < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (read == 0) + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); + g_object_unref (task); + return; + } + + data->length = data->buffer[0] + 2; + data->offset = 0; + + do_read (connect_addr_read_cb, task, data); +} + +static void +connect_addr_read_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + ConnectAsyncData *data = g_task_get_task_data (task); + GError *error = NULL; + gssize read; + + read = g_input_stream_read_finish (G_INPUT_STREAM (source), + result, &error); + + if (read < 0) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (read == 0) + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_CONNECTION_CLOSED, + "Connection to SOCKSv5 proxy server lost"); + g_object_unref (task); + return; + } + + data->offset += read; + + if (data->offset == data->length) + { + g_task_return_pointer (task, g_object_ref (data->io_stream), g_object_unref); + g_object_unref (task); + return; + } + else + { + do_read (connect_reply_read_cb, task, data); + } +} + +static GIOStream * +g_socks5_proxy_connect_finish (GProxy *proxy, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (result), error); +} + +static gboolean +g_socks5_proxy_supports_hostname (GProxy *proxy) +{ + return TRUE; +} + +static void +g_socks5_proxy_class_init (GSocks5ProxyClass *class) +{ + GObjectClass *object_class; + + object_class = (GObjectClass *) class; + object_class->finalize = g_socks5_proxy_finalize; +} + +static void +g_socks5_proxy_iface_init (GProxyInterface *proxy_iface) +{ + proxy_iface->connect = g_socks5_proxy_connect; + proxy_iface->connect_async = g_socks5_proxy_connect_async; + proxy_iface->connect_finish = g_socks5_proxy_connect_finish; + proxy_iface->supports_hostname = g_socks5_proxy_supports_hostname; +} diff --git a/gio/gsocks5proxy.h b/gio/gsocks5proxy.h new file mode 100644 index 0000000..1d294ae --- /dev/null +++ b/gio/gsocks5proxy.h @@ -0,0 +1,46 @@ + /* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008, 2010 Collabora, Ltd. + * Copyright (C) 2008 Nokia Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Youness Alaoui + */ + +#ifndef __G_SOCKS5_PROXY_H__ +#define __G_SOCKS5_PROXY_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SOCKS5_PROXY (_g_socks5_proxy_get_type ()) +#define G_SOCKS5_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOCKS5_PROXY, GSocks5Proxy)) +#define G_SOCKS5_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SOCKS5_PROXY, GSocks5ProxyClass)) +#define G_IS_SOCKS5_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SOCKS5_PROXY)) +#define G_IS_SOCKS5_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SOCKS5_PROXY)) +#define G_SOCKS5_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SOCKS5_PROXY, GSocks5ProxyClass)) + +typedef struct _GSocks5Proxy GSocks5Proxy; +typedef struct _GSocks5ProxyClass GSocks5ProxyClass; + +GType _g_socks5_proxy_get_type (void); + +G_END_DECLS + +#endif /* __SOCKS5_PROXY_H__ */ diff --git a/gio/gsrvtarget.c b/gio/gsrvtarget.c new file mode 100644 index 0000000..6b4068b --- /dev/null +++ b/gio/gsrvtarget.c @@ -0,0 +1,312 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include +#include "glibintl.h" + +#include "gsrvtarget.h" + +#include +#include + + +/** + * SECTION:gsrvtarget + * @short_description: DNS SRV record target + * @include: gio/gio.h + * + * SRV (service) records are used by some network protocols to provide + * service-specific aliasing and load-balancing. For example, XMPP + * (Jabber) uses SRV records to locate the XMPP server for a domain; + * rather than connecting directly to "example.com" or assuming a + * specific server hostname like "xmpp.example.com", an XMPP client + * would look up the "xmpp-client" SRV record for "example.com", and + * then connect to whatever host was pointed to by that record. + * + * You can use g_resolver_lookup_service() or + * g_resolver_lookup_service_async() to find the #GSrvTargets + * for a given service. However, if you are simply planning to connect + * to the remote service, you can use #GNetworkService's + * #GSocketConnectable interface and not need to worry about + * #GSrvTarget at all. + */ + +struct _GSrvTarget { + gchar *hostname; + guint16 port; + + guint16 priority; + guint16 weight; +}; + +/** + * GSrvTarget: + * + * A single target host/port that a network service is running on. + */ + +G_DEFINE_BOXED_TYPE (GSrvTarget, g_srv_target, + g_srv_target_copy, g_srv_target_free) + +/** + * g_srv_target_new: + * @hostname: the host that the service is running on + * @port: the port that the service is running on + * @priority: the target's priority + * @weight: the target's weight + * + * Creates a new #GSrvTarget with the given parameters. + * + * You should not need to use this; normally #GSrvTargets are + * created by #GResolver. + * + * Returns: a new #GSrvTarget. + * + * Since: 2.22 + */ +GSrvTarget * +g_srv_target_new (const gchar *hostname, + guint16 port, + guint16 priority, + guint16 weight) +{ + GSrvTarget *target = g_slice_new0 (GSrvTarget); + + target->hostname = g_strdup (hostname); + target->port = port; + target->priority = priority; + target->weight = weight; + + return target; +} + +/** + * g_srv_target_copy: + * @target: a #GSrvTarget + * + * Copies @target + * + * Returns: a copy of @target + * + * Since: 2.22 + */ +GSrvTarget * +g_srv_target_copy (GSrvTarget *target) +{ + return g_srv_target_new (target->hostname, target->port, + target->priority, target->weight); +} + +/** + * g_srv_target_free: + * @target: a #GSrvTarget + * + * Frees @target + * + * Since: 2.22 + */ +void +g_srv_target_free (GSrvTarget *target) +{ + g_free (target->hostname); + g_slice_free (GSrvTarget, target); +} + +/** + * g_srv_target_get_hostname: + * @target: a #GSrvTarget + * + * Gets @target's hostname (in ASCII form; if you are going to present + * this to the user, you should use g_hostname_is_ascii_encoded() to + * check if it contains encoded Unicode segments, and use + * g_hostname_to_unicode() to convert it if it does.) + * + * Returns: @target's hostname + * + * Since: 2.22 + */ +const gchar * +g_srv_target_get_hostname (GSrvTarget *target) +{ + return target->hostname; +} + +/** + * g_srv_target_get_port: + * @target: a #GSrvTarget + * + * Gets @target's port + * + * Returns: @target's port + * + * Since: 2.22 + */ +guint16 +g_srv_target_get_port (GSrvTarget *target) +{ + return target->port; +} + +/** + * g_srv_target_get_priority: + * @target: a #GSrvTarget + * + * Gets @target's priority. You should not need to look at this; + * #GResolver already sorts the targets according to the algorithm in + * RFC 2782. + * + * Returns: @target's priority + * + * Since: 2.22 + */ +guint16 +g_srv_target_get_priority (GSrvTarget *target) +{ + return target->priority; +} + +/** + * g_srv_target_get_weight: + * @target: a #GSrvTarget + * + * Gets @target's weight. You should not need to look at this; + * #GResolver already sorts the targets according to the algorithm in + * RFC 2782. + * + * Returns: @target's weight + * + * Since: 2.22 + */ +guint16 +g_srv_target_get_weight (GSrvTarget *target) +{ + return target->weight; +} + +static gint +compare_target (gconstpointer a, gconstpointer b) +{ + GSrvTarget *ta = (GSrvTarget *)a; + GSrvTarget *tb = (GSrvTarget *)b; + + if (ta->priority == tb->priority) + { + /* Arrange targets of the same priority "in any order, except + * that all those with weight 0 are placed at the beginning of + * the list" + */ + return ta->weight - tb->weight; + } + else + return ta->priority - tb->priority; +} + +/** + * g_srv_target_list_sort: (skip) + * @targets: a #GList of #GSrvTarget + * + * Sorts @targets in place according to the algorithm in RFC 2782. + * + * Returns: (transfer full): the head of the sorted list. + * + * Since: 2.22 + */ +GList * +g_srv_target_list_sort (GList *targets) +{ + gint sum, num, val, priority, weight; + GList *t, *out, *tail; + GSrvTarget *target; + + if (!targets) + return NULL; + + if (!targets->next) + { + target = targets->data; + if (!strcmp (target->hostname, ".")) + { + /* 'A Target of "." means that the service is decidedly not + * available at this domain.' + */ + g_srv_target_free (target); + g_list_free (targets); + return NULL; + } + } + + /* Sort input list by priority, and put the 0-weight targets first + * in each priority group. Initialize output list to %NULL. + */ + targets = g_list_sort (targets, compare_target); + out = tail = NULL; + + /* For each group of targets with the same priority, remove them + * from @targets and append them to @out in a valid order. + */ + while (targets) + { + priority = ((GSrvTarget *)targets->data)->priority; + + /* Count the number of targets at this priority level, and + * compute the sum of their weights. + */ + sum = num = 0; + for (t = targets; t; t = t->next) + { + target = (GSrvTarget *)t->data; + if (target->priority != priority) + break; + sum += target->weight; + num++; + } + + /* While there are still targets at this priority level... */ + while (num) + { + /* Randomly select from the targets at this priority level, + * giving precedence to the ones with higher weight, + * according to the rules from RFC 2782. + */ + val = g_random_int_range (0, sum + 1); + for (t = targets; ; t = t->next) + { + weight = ((GSrvTarget *)t->data)->weight; + if (weight >= val) + break; + val -= weight; + } + + targets = g_list_remove_link (targets, t); + + if (!out) + out = t; + else + tail->next = t; + tail = t; + + sum -= weight; + num--; + } + } + + return out; +} diff --git a/gio/gsrvtarget.h b/gio/gsrvtarget.h new file mode 100644 index 0000000..4956915 --- /dev/null +++ b/gio/gsrvtarget.h @@ -0,0 +1,58 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_SRV_TARGET_H__ +#define __G_SRV_TARGET_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +GType g_srv_target_get_type (void) G_GNUC_CONST; +#define G_TYPE_SRV_TARGET (g_srv_target_get_type ()) + +GLIB_AVAILABLE_IN_ALL +GSrvTarget *g_srv_target_new (const gchar *hostname, + guint16 port, + guint16 priority, + guint16 weight); +GLIB_AVAILABLE_IN_ALL +GSrvTarget *g_srv_target_copy (GSrvTarget *target); +GLIB_AVAILABLE_IN_ALL +void g_srv_target_free (GSrvTarget *target); + +GLIB_AVAILABLE_IN_ALL +const gchar *g_srv_target_get_hostname (GSrvTarget *target); +GLIB_AVAILABLE_IN_ALL +guint16 g_srv_target_get_port (GSrvTarget *target); +GLIB_AVAILABLE_IN_ALL +guint16 g_srv_target_get_priority (GSrvTarget *target); +GLIB_AVAILABLE_IN_ALL +guint16 g_srv_target_get_weight (GSrvTarget *target); + +GLIB_AVAILABLE_IN_ALL +GList *g_srv_target_list_sort (GList *targets); + +G_END_DECLS + +#endif /* __G_SRV_TARGET_H__ */ diff --git a/gio/gsubprocess.c b/gio/gsubprocess.c new file mode 100644 index 0000000..523c80b --- /dev/null +++ b/gio/gsubprocess.c @@ -0,0 +1,1805 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2012, 2013 Red Hat, Inc. + * Copyright © 2012, 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Colin Walters + * Ryan Lortie + */ + +/** + * SECTION:gsubprocess + * @title: GSubprocess + * @short_description: Child processes + * @include: gio/gio.h + * @see_also: #GSubprocessLauncher + * + * #GSubprocess allows the creation of and interaction with child + * processes. + * + * Processes can be communicated with using standard GIO-style APIs (ie: + * #GInputStream, #GOutputStream). There are GIO-style APIs to wait for + * process termination (ie: cancellable and with an asynchronous + * variant). + * + * There is an API to force a process to terminate, as well as a + * race-free API for sending UNIX signals to a subprocess. + * + * One major advantage that GIO brings over the core GLib library is + * comprehensive API for asynchronous I/O, such + * g_output_stream_splice_async(). This makes GSubprocess + * significantly more powerful and flexible than equivalent APIs in + * some other languages such as the `subprocess.py` + * included with Python. For example, using #GSubprocess one could + * create two child processes, reading standard output from the first, + * processing it, and writing to the input stream of the second, all + * without blocking the main loop. + * + * A powerful g_subprocess_communicate() API is provided similar to the + * `communicate()` method of `subprocess.py`. This enables very easy + * interaction with a subprocess that has been opened with pipes. + * + * #GSubprocess defaults to tight control over the file descriptors open + * in the child process, avoiding dangling-fd issues that are caused by + * a simple fork()/exec(). The only open file descriptors in the + * spawned process are ones that were explicitly specified by the + * #GSubprocess API (unless %G_SUBPROCESS_FLAGS_INHERIT_FDS was + * specified). + * + * #GSubprocess will quickly reap all child processes as they exit, + * avoiding "zombie processes" remaining around for long periods of + * time. g_subprocess_wait() can be used to wait for this to happen, + * but it will happen even without the call being explicitly made. + * + * As a matter of principle, #GSubprocess has no API that accepts + * shell-style space-separated strings. It will, however, match the + * typical shell behaviour of searching the PATH for executables that do + * not contain a directory separator in their name. By default, the `PATH` + * of the current process is used. You can specify + * %G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP to use the `PATH` of the + * launcher environment instead. + * + * #GSubprocess attempts to have a very simple API for most uses (ie: + * spawning a subprocess with arguments and support for most typical + * kinds of input and output redirection). See g_subprocess_new(). The + * #GSubprocessLauncher API is provided for more complicated cases + * (advanced types of redirection, environment variable manipulation, + * change of working directory, child setup functions, etc). + * + * A typical use of #GSubprocess will involve calling + * g_subprocess_new(), followed by g_subprocess_wait_async() or + * g_subprocess_wait(). After the process exits, the status can be + * checked using functions such as g_subprocess_get_if_exited() (which + * are similar to the familiar WIFEXITED-style POSIX macros). + * + * Since: 2.40 + **/ + +#include "config.h" + +#include "gsubprocess.h" +#include "gsubprocesslauncher-private.h" +#include "gasyncresult.h" +#include "giostream.h" +#include "gmemoryinputstream.h" +#include "glibintl.h" +#include "glib-private.h" + +#include +#ifdef G_OS_UNIX +#include +#include +#include +#include +#include +#include +#endif +#ifdef G_OS_WIN32 +#include +#include +#include "giowin32-priv.h" +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#else +#define HAVE_O_CLOEXEC 1 +#endif + +#define COMMUNICATE_READ_SIZE 4096 + +/* A GSubprocess can have two possible states: running and not. + * + * These two states are reflected by the value of 'pid'. If it is + * non-zero then the process is running, with that pid. + * + * When a GSubprocess is first created with g_object_new() it is not + * running. When it is finalized, it is also not running. + * + * During initable_init(), if the g_spawn() is successful then we + * immediately register a child watch and take an extra ref on the + * subprocess. That reference doesn't drop until the child has quit, + * which is why finalize can only happen in the non-running state. In + * the event that the g_spawn() failed we will still be finalizing a + * non-running GSubprocess (before returning from g_subprocess_new()) + * with NULL. + * + * We make extensive use of the glib worker thread to guarantee + * race-free operation. As with all child watches, glib calls waitpid() + * in the worker thread. It reports the child exiting to us via the + * worker thread (which means that we can do synchronous waits without + * running a separate loop). We also send signals to the child process + * via the worker thread so that we don't race with waitpid() and + * accidentally send a signal to an already-reaped child. + */ +static void initable_iface_init (GInitableIface *initable_iface); + +typedef GObjectClass GSubprocessClass; + +struct _GSubprocess +{ + GObject parent; + + /* only used during construction */ + GSubprocessLauncher *launcher; + GSubprocessFlags flags; + gchar **argv; + + /* state tracking variables */ + gchar identifier[24]; + int status; + GPid pid; + + /* list of GTask */ + GMutex pending_waits_lock; + GSList *pending_waits; + + /* These are the streams created if a pipe is requested via flags. */ + GOutputStream *stdin_pipe; + GInputStream *stdout_pipe; + GInputStream *stderr_pipe; +}; + +G_DEFINE_TYPE_WITH_CODE (GSubprocess, g_subprocess, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)) + +enum +{ + PROP_0, + PROP_FLAGS, + PROP_ARGV, + N_PROPS +}; + +static GInputStream * +platform_input_stream_from_spawn_fd (gint fd) +{ + if (fd < 0) + return NULL; + +#ifdef G_OS_UNIX + return g_unix_input_stream_new (fd, TRUE); +#else + return g_win32_input_stream_new_from_fd (fd, TRUE); +#endif +} + +static GOutputStream * +platform_output_stream_from_spawn_fd (gint fd) +{ + if (fd < 0) + return NULL; + +#ifdef G_OS_UNIX + return g_unix_output_stream_new (fd, TRUE); +#else + return g_win32_output_stream_new_from_fd (fd, TRUE); +#endif +} + +#ifdef G_OS_UNIX +static gint +unix_open_file (const char *filename, + gint mode, + GError **error) +{ + gint my_fd; + + my_fd = g_open (filename, mode | O_BINARY | O_CLOEXEC, 0666); + + /* If we return -1 we should also set the error */ + if (my_fd < 0) + { + gint saved_errno = errno; + char *display_name; + + display_name = g_filename_display_name (filename); + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), + _("Error opening file “%sâ€: %s"), display_name, + g_strerror (saved_errno)); + g_free (display_name); + /* fall through... */ + } +#ifndef HAVE_O_CLOEXEC + else + fcntl (my_fd, F_SETFD, FD_CLOEXEC); +#endif + + return my_fd; +} +#endif + +static void +g_subprocess_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSubprocess *self = G_SUBPROCESS (object); + + switch (prop_id) + { + case PROP_FLAGS: + self->flags = g_value_get_flags (value); + break; + + case PROP_ARGV: + self->argv = g_value_dup_boxed (value); + break; + + default: + g_assert_not_reached (); + } +} + +static gboolean +g_subprocess_exited (GPid pid, + gint status, + gpointer user_data) +{ + GSubprocess *self = user_data; + GSList *tasks; + + g_assert (self->pid == pid); + + g_mutex_lock (&self->pending_waits_lock); + self->status = status; + tasks = self->pending_waits; + self->pending_waits = NULL; + self->pid = 0; + g_mutex_unlock (&self->pending_waits_lock); + + /* Signal anyone in g_subprocess_wait_async() to wake up now */ + while (tasks) + { + g_task_return_boolean (tasks->data, TRUE); + g_object_unref (tasks->data); + tasks = g_slist_delete_link (tasks, tasks); + } + + g_spawn_close_pid (pid); + + return FALSE; +} + +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GSubprocess *self = G_SUBPROCESS (initable); + gint *pipe_ptrs[3] = { NULL, NULL, NULL }; + gint pipe_fds[3] = { -1, -1, -1 }; + gint close_fds[3] = { -1, -1, -1 }; +#ifdef G_OS_UNIX + gint stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; +#endif + GSpawnFlags spawn_flags = 0; + gboolean success = FALSE; + gint i; + + /* this is a programmer error */ + if (!self->argv || !self->argv[0] || !self->argv[0][0]) + return FALSE; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + /* We must setup the three fds that will end up in the child as stdin, + * stdout and stderr. + * + * First, stdin. + */ + if (self->flags & G_SUBPROCESS_FLAGS_STDIN_INHERIT) + spawn_flags |= G_SPAWN_CHILD_INHERITS_STDIN; + else if (self->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE) + pipe_ptrs[0] = &pipe_fds[0]; +#ifdef G_OS_UNIX + else if (self->launcher) + { + if (self->launcher->stdin_fd != -1) + stdin_fd = self->launcher->stdin_fd; + else if (self->launcher->stdin_path != NULL) + { + stdin_fd = close_fds[0] = unix_open_file (self->launcher->stdin_path, O_RDONLY, error); + if (stdin_fd == -1) + goto out; + } + } +#endif + + /* Next, stdout. */ + if (self->flags & G_SUBPROCESS_FLAGS_STDOUT_SILENCE) + spawn_flags |= G_SPAWN_STDOUT_TO_DEV_NULL; + else if (self->flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE) + pipe_ptrs[1] = &pipe_fds[1]; +#ifdef G_OS_UNIX + else if (self->launcher) + { + if (self->launcher->stdout_fd != -1) + stdout_fd = self->launcher->stdout_fd; + else if (self->launcher->stdout_path != NULL) + { + stdout_fd = close_fds[1] = unix_open_file (self->launcher->stdout_path, O_CREAT | O_WRONLY, error); + if (stdout_fd == -1) + goto out; + } + } +#endif + + /* Finally, stderr. */ + if (self->flags & G_SUBPROCESS_FLAGS_STDERR_SILENCE) + spawn_flags |= G_SPAWN_STDERR_TO_DEV_NULL; + else if (self->flags & G_SUBPROCESS_FLAGS_STDERR_PIPE) + pipe_ptrs[2] = &pipe_fds[2]; +#ifdef G_OS_UNIX + else if (self->flags & G_SUBPROCESS_FLAGS_STDERR_MERGE) + /* This will work because stderr gets set up after stdout. */ + stderr_fd = 1; + else if (self->launcher) + { + if (self->launcher->stderr_fd != -1) + stderr_fd = self->launcher->stderr_fd; + else if (self->launcher->stderr_path != NULL) + { + stderr_fd = close_fds[2] = unix_open_file (self->launcher->stderr_path, O_CREAT | O_WRONLY, error); + if (stderr_fd == -1) + goto out; + } + } +#endif + + /* argv0 has no '/' in it? We better do a PATH lookup. */ + if (strchr (self->argv[0], G_DIR_SEPARATOR) == NULL) + { + if (self->launcher && self->launcher->flags & G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP) + spawn_flags |= G_SPAWN_SEARCH_PATH_FROM_ENVP; + else + spawn_flags |= G_SPAWN_SEARCH_PATH; + } + + if (self->flags & G_SUBPROCESS_FLAGS_INHERIT_FDS) + spawn_flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN; + + spawn_flags |= G_SPAWN_DO_NOT_REAP_CHILD; + spawn_flags |= G_SPAWN_CLOEXEC_PIPES; + + success = g_spawn_async_with_pipes_and_fds (self->launcher ? self->launcher->cwd : NULL, + (const gchar * const *) self->argv, + (const gchar * const *) (self->launcher ? self->launcher->envp : NULL), + spawn_flags, +#ifdef G_OS_UNIX + self->launcher ? self->launcher->child_setup_func : NULL, + self->launcher ? self->launcher->child_setup_user_data : NULL, + stdin_fd, stdout_fd, stderr_fd, + self->launcher ? (const gint *) self->launcher->source_fds->data : NULL, + self->launcher ? (const gint *) self->launcher->target_fds->data : NULL, + self->launcher ? self->launcher->source_fds->len : 0, +#else + NULL, NULL, + -1, -1, -1, + NULL, NULL, 0, +#endif + &self->pid, + pipe_ptrs[0], pipe_ptrs[1], pipe_ptrs[2], + error); + g_assert (success == (self->pid != 0)); + + { + guint64 identifier; + gint s G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + +#ifdef G_OS_WIN32 + identifier = (guint64) GetProcessId (self->pid); +#else + identifier = (guint64) self->pid; +#endif + + s = g_snprintf (self->identifier, sizeof self->identifier, "%"G_GUINT64_FORMAT, identifier); + g_assert (0 < s && (gsize) s < sizeof self->identifier); + } + + /* Start attempting to reap the child immediately */ + if (success) + { + GMainContext *worker_context; + GSource *source; + + worker_context = GLIB_PRIVATE_CALL (g_get_worker_context) (); + source = g_child_watch_source_new (self->pid); + g_source_set_callback (source, (GSourceFunc) g_subprocess_exited, g_object_ref (self), g_object_unref); + g_source_attach (source, worker_context); + g_source_unref (source); + } + +#ifdef G_OS_UNIX +out: +#endif + /* we don't need this past init... */ + self->launcher = NULL; + + for (i = 0; i < 3; i++) + if (close_fds[i] != -1) + close (close_fds[i]); + + self->stdin_pipe = platform_output_stream_from_spawn_fd (pipe_fds[0]); + self->stdout_pipe = platform_input_stream_from_spawn_fd (pipe_fds[1]); + self->stderr_pipe = platform_input_stream_from_spawn_fd (pipe_fds[2]); + + return success; +} + +static void +g_subprocess_finalize (GObject *object) +{ + GSubprocess *self = G_SUBPROCESS (object); + + g_assert (self->pending_waits == NULL); + g_assert (self->pid == 0); + + g_clear_object (&self->stdin_pipe); + g_clear_object (&self->stdout_pipe); + g_clear_object (&self->stderr_pipe); + g_strfreev (self->argv); + + g_mutex_clear (&self->pending_waits_lock); + + G_OBJECT_CLASS (g_subprocess_parent_class)->finalize (object); +} + +static void +g_subprocess_init (GSubprocess *self) +{ + g_mutex_init (&self->pending_waits_lock); +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = initable_init; +} + +static void +g_subprocess_class_init (GSubprocessClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->finalize = g_subprocess_finalize; + gobject_class->set_property = g_subprocess_set_property; + + g_object_class_install_property (gobject_class, PROP_FLAGS, + g_param_spec_flags ("flags", P_("Flags"), P_("Subprocess flags"), + G_TYPE_SUBPROCESS_FLAGS, 0, G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_ARGV, + g_param_spec_boxed ("argv", P_("Arguments"), P_("Argument vector"), + G_TYPE_STRV, G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); +} + +/** + * g_subprocess_new: (skip) + * @flags: flags that define the behaviour of the subprocess + * @error: (nullable): return location for an error, or %NULL + * @argv0: first commandline argument to pass to the subprocess + * @...: more commandline arguments, followed by %NULL + * + * Create a new process with the given flags and varargs argument + * list. By default, matching the g_spawn_async() defaults, the + * child's stdin will be set to the system null device, and + * stdout/stderr will be inherited from the parent. You can use + * @flags to control this behavior. + * + * The argument list must be terminated with %NULL. + * + * Returns: A newly created #GSubprocess, or %NULL on error (and @error + * will be set) + * + * Since: 2.40 + */ +GSubprocess * +g_subprocess_new (GSubprocessFlags flags, + GError **error, + const gchar *argv0, + ...) +{ + GSubprocess *result; + GPtrArray *args; + const gchar *arg; + va_list ap; + + g_return_val_if_fail (argv0 != NULL && argv0[0] != '\0', NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + args = g_ptr_array_new (); + + va_start (ap, argv0); + g_ptr_array_add (args, (gchar *) argv0); + while ((arg = va_arg (ap, const gchar *))) + g_ptr_array_add (args, (gchar *) arg); + g_ptr_array_add (args, NULL); + va_end (ap); + + result = g_subprocess_newv ((const gchar * const *) args->pdata, flags, error); + + g_ptr_array_free (args, TRUE); + + return result; +} + +/** + * g_subprocess_newv: (rename-to g_subprocess_new) + * @argv: (array zero-terminated=1) (element-type filename): commandline arguments for the subprocess + * @flags: flags that define the behaviour of the subprocess + * @error: (nullable): return location for an error, or %NULL + * + * Create a new process with the given flags and argument list. + * + * The argument list is expected to be %NULL-terminated. + * + * Returns: A newly created #GSubprocess, or %NULL on error (and @error + * will be set) + * + * Since: 2.40 + */ +GSubprocess * +g_subprocess_newv (const gchar * const *argv, + GSubprocessFlags flags, + GError **error) +{ + g_return_val_if_fail (argv != NULL && argv[0] != NULL && argv[0][0] != '\0', NULL); + + return g_initable_new (G_TYPE_SUBPROCESS, NULL, error, + "argv", argv, + "flags", flags, + NULL); +} + +/** + * g_subprocess_get_identifier: + * @subprocess: a #GSubprocess + * + * On UNIX, returns the process ID as a decimal string. + * On Windows, returns the result of GetProcessId() also as a string. + * If the subprocess has terminated, this will return %NULL. + * + * Returns: (nullable): the subprocess identifier, or %NULL if the subprocess + * has terminated + * Since: 2.40 + */ +const gchar * +g_subprocess_get_identifier (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), NULL); + + if (subprocess->pid) + return subprocess->identifier; + else + return NULL; +} + +/** + * g_subprocess_get_stdin_pipe: + * @subprocess: a #GSubprocess + * + * Gets the #GOutputStream that you can write to in order to give data + * to the stdin of @subprocess. + * + * The process must have been created with %G_SUBPROCESS_FLAGS_STDIN_PIPE and + * not %G_SUBPROCESS_FLAGS_STDIN_INHERIT, otherwise %NULL will be returned. + * + * Returns: (nullable) (transfer none): the stdout pipe + * + * Since: 2.40 + **/ +GOutputStream * +g_subprocess_get_stdin_pipe (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), NULL); + + return subprocess->stdin_pipe; +} + +/** + * g_subprocess_get_stdout_pipe: + * @subprocess: a #GSubprocess + * + * Gets the #GInputStream from which to read the stdout output of + * @subprocess. + * + * The process must have been created with %G_SUBPROCESS_FLAGS_STDOUT_PIPE, + * otherwise %NULL will be returned. + * + * Returns: (nullable) (transfer none): the stdout pipe + * + * Since: 2.40 + **/ +GInputStream * +g_subprocess_get_stdout_pipe (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), NULL); + + return subprocess->stdout_pipe; +} + +/** + * g_subprocess_get_stderr_pipe: + * @subprocess: a #GSubprocess + * + * Gets the #GInputStream from which to read the stderr output of + * @subprocess. + * + * The process must have been created with %G_SUBPROCESS_FLAGS_STDERR_PIPE, + * otherwise %NULL will be returned. + * + * Returns: (nullable) (transfer none): the stderr pipe + * + * Since: 2.40 + **/ +GInputStream * +g_subprocess_get_stderr_pipe (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), NULL); + + return subprocess->stderr_pipe; +} + +/* Remove the first list element containing @data, and return %TRUE. If no + * such element is found, return %FALSE. */ +static gboolean +slist_remove_if_present (GSList **list, + gconstpointer data) +{ + GSList *l, *prev; + + for (l = *list, prev = NULL; l != NULL; prev = l, l = prev->next) + { + if (l->data == data) + { + if (prev != NULL) + prev->next = l->next; + else + *list = l->next; + + g_slist_free_1 (l); + + return TRUE; + } + } + + return FALSE; +} + +static void +g_subprocess_wait_cancelled (GCancellable *cancellable, + gpointer user_data) +{ + GTask *task = user_data; + GSubprocess *self; + gboolean task_was_pending; + + self = g_task_get_source_object (task); + + g_mutex_lock (&self->pending_waits_lock); + task_was_pending = slist_remove_if_present (&self->pending_waits, task); + g_mutex_unlock (&self->pending_waits_lock); + + if (task_was_pending) + { + g_task_return_boolean (task, FALSE); + g_object_unref (task); /* ref from pending_waits */ + } +} + +/** + * g_subprocess_wait_async: + * @subprocess: a #GSubprocess + * @cancellable: a #GCancellable, or %NULL + * @callback: a #GAsyncReadyCallback to call when the operation is complete + * @user_data: user_data for @callback + * + * Wait for the subprocess to terminate. + * + * This is the asynchronous version of g_subprocess_wait(). + * + * Since: 2.40 + */ +void +g_subprocess_wait_async (GSubprocess *subprocess, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (subprocess, cancellable, callback, user_data); + g_task_set_source_tag (task, g_subprocess_wait_async); + + g_mutex_lock (&subprocess->pending_waits_lock); + if (subprocess->pid) + { + /* Only bother with cancellable if we're putting it in the list. + * If not, it's going to dispatch immediately anyway and we will + * see the cancellation in the _finish(). + */ + if (cancellable) + g_signal_connect_object (cancellable, "cancelled", G_CALLBACK (g_subprocess_wait_cancelled), task, 0); + + subprocess->pending_waits = g_slist_prepend (subprocess->pending_waits, task); + task = NULL; + } + g_mutex_unlock (&subprocess->pending_waits_lock); + + /* If we still have task then it's because did_exit is already TRUE */ + if (task != NULL) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + } +} + +/** + * g_subprocess_wait_finish: + * @subprocess: a #GSubprocess + * @result: the #GAsyncResult passed to your #GAsyncReadyCallback + * @error: a pointer to a %NULL #GError, or %NULL + * + * Collects the result of a previous call to + * g_subprocess_wait_async(). + * + * Returns: %TRUE if successful, or %FALSE with @error set + * + * Since: 2.40 + */ +gboolean +g_subprocess_wait_finish (GSubprocess *subprocess, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} + +/* Some generic helpers for emulating synchronous operations using async + * operations. + */ +static void +g_subprocess_sync_setup (void) +{ + g_main_context_push_thread_default (g_main_context_new ()); +} + +static void +g_subprocess_sync_done (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GAsyncResult **result_ptr = user_data; + + *result_ptr = g_object_ref (result); +} + +static void +g_subprocess_sync_complete (GAsyncResult **result) +{ + GMainContext *context = g_main_context_get_thread_default (); + + while (!*result) + g_main_context_iteration (context, TRUE); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); +} + +/** + * g_subprocess_wait: + * @subprocess: a #GSubprocess + * @cancellable: a #GCancellable + * @error: a #GError + * + * Synchronously wait for the subprocess to terminate. + * + * After the process terminates you can query its exit status with + * functions such as g_subprocess_get_if_exited() and + * g_subprocess_get_exit_status(). + * + * This function does not fail in the case of the subprocess having + * abnormal termination. See g_subprocess_wait_check() for that. + * + * Cancelling @cancellable doesn't kill the subprocess. Call + * g_subprocess_force_exit() if it is desirable. + * + * Returns: %TRUE on success, %FALSE if @cancellable was cancelled + * + * Since: 2.40 + */ +gboolean +g_subprocess_wait (GSubprocess *subprocess, + GCancellable *cancellable, + GError **error) +{ + GAsyncResult *result = NULL; + gboolean success; + + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + + /* Synchronous waits are actually the 'more difficult' case because we + * need to deal with the possibility of cancellation. That more or + * less implies that we need a main context (to dispatch either of the + * possible reasons for the operation ending). + * + * So we make one and then do this async... + */ + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + /* We can shortcut in the case that the process already quit (but only + * after we checked the cancellable). + */ + if (subprocess->pid == 0) + return TRUE; + + /* Otherwise, we need to do this the long way... */ + g_subprocess_sync_setup (); + g_subprocess_wait_async (subprocess, cancellable, g_subprocess_sync_done, &result); + g_subprocess_sync_complete (&result); + success = g_subprocess_wait_finish (subprocess, result, error); + g_object_unref (result); + + return success; +} + +/** + * g_subprocess_wait_check: + * @subprocess: a #GSubprocess + * @cancellable: a #GCancellable + * @error: a #GError + * + * Combines g_subprocess_wait() with g_spawn_check_wait_status(). + * + * Returns: %TRUE on success, %FALSE if process exited abnormally, or + * @cancellable was cancelled + * + * Since: 2.40 + */ +gboolean +g_subprocess_wait_check (GSubprocess *subprocess, + GCancellable *cancellable, + GError **error) +{ + return g_subprocess_wait (subprocess, cancellable, error) && + g_spawn_check_wait_status (subprocess->status, error); +} + +/** + * g_subprocess_wait_check_async: + * @subprocess: a #GSubprocess + * @cancellable: a #GCancellable, or %NULL + * @callback: a #GAsyncReadyCallback to call when the operation is complete + * @user_data: user_data for @callback + * + * Combines g_subprocess_wait_async() with g_spawn_check_wait_status(). + * + * This is the asynchronous version of g_subprocess_wait_check(). + * + * Since: 2.40 + */ +void +g_subprocess_wait_check_async (GSubprocess *subprocess, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_subprocess_wait_async (subprocess, cancellable, callback, user_data); +} + +/** + * g_subprocess_wait_check_finish: + * @subprocess: a #GSubprocess + * @result: the #GAsyncResult passed to your #GAsyncReadyCallback + * @error: a pointer to a %NULL #GError, or %NULL + * + * Collects the result of a previous call to + * g_subprocess_wait_check_async(). + * + * Returns: %TRUE if successful, or %FALSE with @error set + * + * Since: 2.40 + */ +gboolean +g_subprocess_wait_check_finish (GSubprocess *subprocess, + GAsyncResult *result, + GError **error) +{ + return g_subprocess_wait_finish (subprocess, result, error) && + g_spawn_check_wait_status (subprocess->status, error); +} + +#ifdef G_OS_UNIX +typedef struct +{ + GSubprocess *subprocess; + gint signalnum; +} SignalRecord; + +static gboolean +g_subprocess_actually_send_signal (gpointer user_data) +{ + SignalRecord *signal_record = user_data; + + /* The pid is set to zero from the worker thread as well, so we don't + * need to take a lock in order to prevent it from changing under us. + */ + if (signal_record->subprocess->pid) + kill (signal_record->subprocess->pid, signal_record->signalnum); + + g_object_unref (signal_record->subprocess); + + g_slice_free (SignalRecord, signal_record); + + return FALSE; +} + +static void +g_subprocess_dispatch_signal (GSubprocess *subprocess, + gint signalnum) +{ + SignalRecord signal_record = { g_object_ref (subprocess), signalnum }; + + g_return_if_fail (G_IS_SUBPROCESS (subprocess)); + + /* This MUST be a lower priority than the priority that the child + * watch source uses in initable_init(). + * + * Reaping processes, reporting the results back to GSubprocess and + * sending signals is all done in the glib worker thread. We cannot + * have a kill() done after the reap and before the report without + * risking killing a process that's no longer there so the kill() + * needs to have the lower priority. + * + * G_PRIORITY_HIGH_IDLE is lower priority than G_PRIORITY_DEFAULT. + */ + g_main_context_invoke_full (GLIB_PRIVATE_CALL (g_get_worker_context) (), + G_PRIORITY_HIGH_IDLE, + g_subprocess_actually_send_signal, + g_slice_dup (SignalRecord, &signal_record), + NULL); +} + +/** + * g_subprocess_send_signal: + * @subprocess: a #GSubprocess + * @signal_num: the signal number to send + * + * Sends the UNIX signal @signal_num to the subprocess, if it is still + * running. + * + * This API is race-free. If the subprocess has terminated, it will not + * be signalled. + * + * This API is not available on Windows. + * + * Since: 2.40 + **/ +void +g_subprocess_send_signal (GSubprocess *subprocess, + gint signal_num) +{ + g_return_if_fail (G_IS_SUBPROCESS (subprocess)); + + g_subprocess_dispatch_signal (subprocess, signal_num); +} +#endif + +/** + * g_subprocess_force_exit: + * @subprocess: a #GSubprocess + * + * Use an operating-system specific method to attempt an immediate, + * forceful termination of the process. There is no mechanism to + * determine whether or not the request itself was successful; + * however, you can use g_subprocess_wait() to monitor the status of + * the process after calling this function. + * + * On Unix, this function sends %SIGKILL. + * + * Since: 2.40 + **/ +void +g_subprocess_force_exit (GSubprocess *subprocess) +{ + g_return_if_fail (G_IS_SUBPROCESS (subprocess)); + +#ifdef G_OS_UNIX + g_subprocess_dispatch_signal (subprocess, SIGKILL); +#else + TerminateProcess (subprocess->pid, 1); +#endif +} + +/** + * g_subprocess_get_status: + * @subprocess: a #GSubprocess + * + * Gets the raw status code of the process, as from waitpid(). + * + * This value has no particular meaning, but it can be used with the + * macros defined by the system headers such as WIFEXITED. It can also + * be used with g_spawn_check_wait_status(). + * + * It is more likely that you want to use g_subprocess_get_if_exited() + * followed by g_subprocess_get_exit_status(). + * + * It is an error to call this function before g_subprocess_wait() has + * returned. + * + * Returns: the (meaningless) waitpid() exit status from the kernel + * + * Since: 2.40 + **/ +gint +g_subprocess_get_status (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + g_return_val_if_fail (subprocess->pid == 0, FALSE); + + return subprocess->status; +} + +/** + * g_subprocess_get_successful: + * @subprocess: a #GSubprocess + * + * Checks if the process was "successful". A process is considered + * successful if it exited cleanly with an exit status of 0, either by + * way of the exit() system call or return from main(). + * + * It is an error to call this function before g_subprocess_wait() has + * returned. + * + * Returns: %TRUE if the process exited cleanly with a exit status of 0 + * + * Since: 2.40 + **/ +gboolean +g_subprocess_get_successful (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + g_return_val_if_fail (subprocess->pid == 0, FALSE); + +#ifdef G_OS_UNIX + return WIFEXITED (subprocess->status) && WEXITSTATUS (subprocess->status) == 0; +#else + return subprocess->status == 0; +#endif +} + +/** + * g_subprocess_get_if_exited: + * @subprocess: a #GSubprocess + * + * Check if the given subprocess exited normally (ie: by way of exit() + * or return from main()). + * + * This is equivalent to the system WIFEXITED macro. + * + * It is an error to call this function before g_subprocess_wait() has + * returned. + * + * Returns: %TRUE if the case of a normal exit + * + * Since: 2.40 + **/ +gboolean +g_subprocess_get_if_exited (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + g_return_val_if_fail (subprocess->pid == 0, FALSE); + +#ifdef G_OS_UNIX + return WIFEXITED (subprocess->status); +#else + return TRUE; +#endif +} + +/** + * g_subprocess_get_exit_status: + * @subprocess: a #GSubprocess + * + * Check the exit status of the subprocess, given that it exited + * normally. This is the value passed to the exit() system call or the + * return value from main. + * + * This is equivalent to the system WEXITSTATUS macro. + * + * It is an error to call this function before g_subprocess_wait() and + * unless g_subprocess_get_if_exited() returned %TRUE. + * + * Returns: the exit status + * + * Since: 2.40 + **/ +gint +g_subprocess_get_exit_status (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), 1); + g_return_val_if_fail (subprocess->pid == 0, 1); + +#ifdef G_OS_UNIX + g_return_val_if_fail (WIFEXITED (subprocess->status), 1); + + return WEXITSTATUS (subprocess->status); +#else + return subprocess->status; +#endif +} + +/** + * g_subprocess_get_if_signaled: + * @subprocess: a #GSubprocess + * + * Check if the given subprocess terminated in response to a signal. + * + * This is equivalent to the system WIFSIGNALED macro. + * + * It is an error to call this function before g_subprocess_wait() has + * returned. + * + * Returns: %TRUE if the case of termination due to a signal + * + * Since: 2.40 + **/ +gboolean +g_subprocess_get_if_signaled (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + g_return_val_if_fail (subprocess->pid == 0, FALSE); + +#ifdef G_OS_UNIX + return WIFSIGNALED (subprocess->status); +#else + return FALSE; +#endif +} + +/** + * g_subprocess_get_term_sig: + * @subprocess: a #GSubprocess + * + * Get the signal number that caused the subprocess to terminate, given + * that it terminated due to a signal. + * + * This is equivalent to the system WTERMSIG macro. + * + * It is an error to call this function before g_subprocess_wait() and + * unless g_subprocess_get_if_signaled() returned %TRUE. + * + * Returns: the signal causing termination + * + * Since: 2.40 + **/ +gint +g_subprocess_get_term_sig (GSubprocess *subprocess) +{ + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), 0); + g_return_val_if_fail (subprocess->pid == 0, 0); + +#ifdef G_OS_UNIX + g_return_val_if_fail (WIFSIGNALED (subprocess->status), 0); + + return WTERMSIG (subprocess->status); +#else + g_critical ("g_subprocess_get_term_sig() called on Windows, where " + "g_subprocess_get_if_signaled() always returns FALSE..."); + return 0; +#endif +} + +/*< private >*/ +void +g_subprocess_set_launcher (GSubprocess *subprocess, + GSubprocessLauncher *launcher) +{ + subprocess->launcher = launcher; +} + + +/* g_subprocess_communicate implementation below: + * + * This is a tough problem. We have to watch 5 things at the same time: + * + * - writing to stdin made progress + * - reading from stdout made progress + * - reading from stderr made progress + * - process terminated + * - cancellable being cancelled by caller + * + * We use a GMainContext for all of these (either as async function + * calls or as a GSource (in the case of the cancellable). That way at + * least we don't have to worry about threading. + * + * For the sync case we use the usual trick of creating a private main + * context and iterating it until completion. + * + * It's very possible that the process will dump a lot of data to stdout + * just before it quits, so we can easily have data to read from stdout + * and see the process has terminated at the same time. We want to make + * sure that we read all of the data from the pipes first, though, so we + * do IO operations at a higher priority than the wait operation (which + * is at G_IO_PRIORITY_DEFAULT). Even in the case that we have to do + * multiple reads to get this data, the pipe() will always be polling + * as ready and with the async result for the read at a higher priority, + * the main context will not dispatch the completion for the wait(). + * + * We keep our own private GCancellable. In the event that any of the + * above suffers from an error condition (including the user cancelling + * their cancellable) we immediately dispatch the GTask with the error + * result and fire our cancellable to cleanup any pending operations. + * In the case that the error is that the user's cancellable was fired, + * it's vaguely wasteful to report an error because GTask will handle + * this automatically, so we just return FALSE. + * + * We let each pending sub-operation take a ref on the GTask of the + * communicate operation. We have to be careful that we don't report + * the task completion more than once, though, so we keep a flag for + * that. + */ +typedef struct +{ + const gchar *stdin_data; + gsize stdin_length; + gsize stdin_offset; + + gboolean add_nul; + + GInputStream *stdin_buf; + GMemoryOutputStream *stdout_buf; + GMemoryOutputStream *stderr_buf; + + GCancellable *cancellable; + GSource *cancellable_source; + + guint outstanding_ops; + gboolean reported_error; +} CommunicateState; + +static void +g_subprocess_communicate_made_progress (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + CommunicateState *state; + GSubprocess *subprocess; + GError *error = NULL; + gpointer source; + GTask *task; + + g_assert (source_object != NULL); + + task = user_data; + subprocess = g_task_get_source_object (task); + state = g_task_get_task_data (task); + source = source_object; + + state->outstanding_ops--; + + if (source == subprocess->stdin_pipe || + source == state->stdout_buf || + source == state->stderr_buf) + { + if (g_output_stream_splice_finish ((GOutputStream*) source, result, &error) == -1) + goto out; + + if (source == state->stdout_buf || + source == state->stderr_buf) + { + /* This is a memory stream, so it can't be cancelled or return + * an error really. + */ + if (state->add_nul) + { + gsize bytes_written; + if (!g_output_stream_write_all (source, "\0", 1, &bytes_written, + NULL, &error)) + goto out; + } + if (!g_output_stream_close (source, NULL, &error)) + goto out; + } + } + else if (source == subprocess) + { + (void) g_subprocess_wait_finish (subprocess, result, &error); + } + else + g_assert_not_reached (); + + out: + if (error) + { + /* Only report the first error we see. + * + * We might be seeing an error as a result of the cancellation + * done when the process quits. + */ + if (!state->reported_error) + { + state->reported_error = TRUE; + g_cancellable_cancel (state->cancellable); + g_task_return_error (task, error); + } + else + g_error_free (error); + } + else if (state->outstanding_ops == 0) + { + g_task_return_boolean (task, TRUE); + } + + /* And drop the original ref */ + g_object_unref (task); +} + +static gboolean +g_subprocess_communicate_cancelled (GCancellable *cancellable, + gpointer user_data) +{ + CommunicateState *state = user_data; + + g_cancellable_cancel (state->cancellable); + + return FALSE; +} + +static void +g_subprocess_communicate_state_free (gpointer data) +{ + CommunicateState *state = data; + + g_clear_object (&state->cancellable); + g_clear_object (&state->stdin_buf); + g_clear_object (&state->stdout_buf); + g_clear_object (&state->stderr_buf); + + if (state->cancellable_source) + { + g_source_destroy (state->cancellable_source); + g_source_unref (state->cancellable_source); + } + + g_slice_free (CommunicateState, state); +} + +static CommunicateState * +g_subprocess_communicate_internal (GSubprocess *subprocess, + gboolean add_nul, + GBytes *stdin_buf, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + CommunicateState *state; + GTask *task; + + task = g_task_new (subprocess, cancellable, callback, user_data); + g_task_set_source_tag (task, g_subprocess_communicate_internal); + + state = g_slice_new0 (CommunicateState); + g_task_set_task_data (task, state, g_subprocess_communicate_state_free); + + state->cancellable = g_cancellable_new (); + state->add_nul = add_nul; + + if (cancellable) + { + state->cancellable_source = g_cancellable_source_new (cancellable); + /* No ref held here, but we unref the source from state's free function */ + g_source_set_callback (state->cancellable_source, + G_SOURCE_FUNC (g_subprocess_communicate_cancelled), + state, NULL); + g_source_attach (state->cancellable_source, g_main_context_get_thread_default ()); + } + + if (subprocess->stdin_pipe) + { + g_assert (stdin_buf != NULL); + +#ifdef G_OS_UNIX + /* We're doing async writes to the pipe, and the async write mechanism assumes + * that streams polling as writable do SOME progress (possibly partial) and then + * stop, but never block. + * + * However, for blocking pipes, unix will return writable if there is *any* space left + * but still block until the full buffer size is available before returning from write. + * So, to avoid async blocking on the main loop we make this non-blocking here. + * + * It should be safe to change the fd because we're the only user at this point as + * per the g_subprocess_communicate() docs, and all the code called by this function + * properly handles non-blocking fds. + */ + g_unix_set_fd_nonblocking (g_unix_output_stream_get_fd (G_UNIX_OUTPUT_STREAM (subprocess->stdin_pipe)), TRUE, NULL); +#endif + + state->stdin_buf = g_memory_input_stream_new_from_bytes (stdin_buf); + g_output_stream_splice_async (subprocess->stdin_pipe, (GInputStream*)state->stdin_buf, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + G_PRIORITY_DEFAULT, state->cancellable, + g_subprocess_communicate_made_progress, g_object_ref (task)); + state->outstanding_ops++; + } + + if (subprocess->stdout_pipe) + { + state->stdout_buf = (GMemoryOutputStream*)g_memory_output_stream_new_resizable (); + g_output_stream_splice_async ((GOutputStream*)state->stdout_buf, subprocess->stdout_pipe, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, + G_PRIORITY_DEFAULT, state->cancellable, + g_subprocess_communicate_made_progress, g_object_ref (task)); + state->outstanding_ops++; + } + + if (subprocess->stderr_pipe) + { + state->stderr_buf = (GMemoryOutputStream*)g_memory_output_stream_new_resizable (); + g_output_stream_splice_async ((GOutputStream*)state->stderr_buf, subprocess->stderr_pipe, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, + G_PRIORITY_DEFAULT, state->cancellable, + g_subprocess_communicate_made_progress, g_object_ref (task)); + state->outstanding_ops++; + } + + g_subprocess_wait_async (subprocess, state->cancellable, + g_subprocess_communicate_made_progress, g_object_ref (task)); + state->outstanding_ops++; + + g_object_unref (task); + return state; +} + +/** + * g_subprocess_communicate: + * @subprocess: a #GSubprocess + * @stdin_buf: (nullable): data to send to the stdin of the subprocess, or %NULL + * @cancellable: a #GCancellable + * @stdout_buf: (out) (nullable) (optional) (transfer full): data read from the subprocess stdout + * @stderr_buf: (out) (nullable) (optional) (transfer full): data read from the subprocess stderr + * @error: a pointer to a %NULL #GError pointer, or %NULL + * + * Communicate with the subprocess until it terminates, and all input + * and output has been completed. + * + * If @stdin_buf is given, the subprocess must have been created with + * %G_SUBPROCESS_FLAGS_STDIN_PIPE. The given data is fed to the + * stdin of the subprocess and the pipe is closed (ie: EOF). + * + * At the same time (as not to cause blocking when dealing with large + * amounts of data), if %G_SUBPROCESS_FLAGS_STDOUT_PIPE or + * %G_SUBPROCESS_FLAGS_STDERR_PIPE were used, reads from those + * streams. The data that was read is returned in @stdout and/or + * the @stderr. + * + * If the subprocess was created with %G_SUBPROCESS_FLAGS_STDOUT_PIPE, + * @stdout_buf will contain the data read from stdout. Otherwise, for + * subprocesses not created with %G_SUBPROCESS_FLAGS_STDOUT_PIPE, + * @stdout_buf will be set to %NULL. Similar provisions apply to + * @stderr_buf and %G_SUBPROCESS_FLAGS_STDERR_PIPE. + * + * As usual, any output variable may be given as %NULL to ignore it. + * + * If you desire the stdout and stderr data to be interleaved, create + * the subprocess with %G_SUBPROCESS_FLAGS_STDOUT_PIPE and + * %G_SUBPROCESS_FLAGS_STDERR_MERGE. The merged result will be returned + * in @stdout_buf and @stderr_buf will be set to %NULL. + * + * In case of any error (including cancellation), %FALSE will be + * returned with @error set. Some or all of the stdin data may have + * been written. Any stdout or stderr data that has been read will be + * discarded. None of the out variables (aside from @error) will have + * been set to anything in particular and should not be inspected. + * + * In the case that %TRUE is returned, the subprocess has exited and the + * exit status inspection APIs (eg: g_subprocess_get_if_exited(), + * g_subprocess_get_exit_status()) may be used. + * + * You should not attempt to use any of the subprocess pipes after + * starting this function, since they may be left in strange states, + * even if the operation was cancelled. You should especially not + * attempt to interact with the pipes while the operation is in progress + * (either from another thread or if using the asynchronous version). + * + * Returns: %TRUE if successful + * + * Since: 2.40 + **/ +gboolean +g_subprocess_communicate (GSubprocess *subprocess, + GBytes *stdin_buf, + GCancellable *cancellable, + GBytes **stdout_buf, + GBytes **stderr_buf, + GError **error) +{ + GAsyncResult *result = NULL; + gboolean success; + + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + g_return_val_if_fail (stdin_buf == NULL || (subprocess->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + g_subprocess_sync_setup (); + g_subprocess_communicate_internal (subprocess, FALSE, stdin_buf, cancellable, + g_subprocess_sync_done, &result); + g_subprocess_sync_complete (&result); + success = g_subprocess_communicate_finish (subprocess, result, stdout_buf, stderr_buf, error); + g_object_unref (result); + + return success; +} + +/** + * g_subprocess_communicate_async: + * @subprocess: Self + * @stdin_buf: (nullable): Input data, or %NULL + * @cancellable: (nullable): Cancellable + * @callback: Callback + * @user_data: User data + * + * Asynchronous version of g_subprocess_communicate(). Complete + * invocation with g_subprocess_communicate_finish(). + */ +void +g_subprocess_communicate_async (GSubprocess *subprocess, + GBytes *stdin_buf, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_SUBPROCESS (subprocess)); + g_return_if_fail (stdin_buf == NULL || (subprocess->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + g_subprocess_communicate_internal (subprocess, FALSE, stdin_buf, cancellable, callback, user_data); +} + +/** + * g_subprocess_communicate_finish: + * @subprocess: Self + * @result: Result + * @stdout_buf: (out) (nullable) (optional) (transfer full): Return location for stdout data + * @stderr_buf: (out) (nullable) (optional) (transfer full): Return location for stderr data + * @error: Error + * + * Complete an invocation of g_subprocess_communicate_async(). + */ +gboolean +g_subprocess_communicate_finish (GSubprocess *subprocess, + GAsyncResult *result, + GBytes **stdout_buf, + GBytes **stderr_buf, + GError **error) +{ + gboolean success; + CommunicateState *state; + + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + g_return_val_if_fail (g_task_is_valid (result, subprocess), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + g_object_ref (result); + + state = g_task_get_task_data ((GTask*)result); + success = g_task_propagate_boolean ((GTask*)result, error); + + if (success) + { + if (stdout_buf) + *stdout_buf = (state->stdout_buf != NULL) ? g_memory_output_stream_steal_as_bytes (state->stdout_buf) : NULL; + if (stderr_buf) + *stderr_buf = (state->stderr_buf != NULL) ? g_memory_output_stream_steal_as_bytes (state->stderr_buf) : NULL; + } + + g_object_unref (result); + return success; +} + +/** + * g_subprocess_communicate_utf8: + * @subprocess: a #GSubprocess + * @stdin_buf: (nullable): data to send to the stdin of the subprocess, or %NULL + * @cancellable: a #GCancellable + * @stdout_buf: (out) (nullable) (optional) (transfer full): data read from the subprocess stdout + * @stderr_buf: (out) (nullable) (optional) (transfer full): data read from the subprocess stderr + * @error: a pointer to a %NULL #GError pointer, or %NULL + * + * Like g_subprocess_communicate(), but validates the output of the + * process as UTF-8, and returns it as a regular NUL terminated string. + * + * On error, @stdout_buf and @stderr_buf will be set to undefined values and + * should not be used. + */ +gboolean +g_subprocess_communicate_utf8 (GSubprocess *subprocess, + const char *stdin_buf, + GCancellable *cancellable, + char **stdout_buf, + char **stderr_buf, + GError **error) +{ + GAsyncResult *result = NULL; + gboolean success; + GBytes *stdin_bytes; + size_t stdin_buf_len = 0; + + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + g_return_val_if_fail (stdin_buf == NULL || (subprocess->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (stdin_buf != NULL) + stdin_buf_len = strlen (stdin_buf); + stdin_bytes = g_bytes_new (stdin_buf, stdin_buf_len); + + g_subprocess_sync_setup (); + g_subprocess_communicate_internal (subprocess, TRUE, stdin_bytes, cancellable, + g_subprocess_sync_done, &result); + g_subprocess_sync_complete (&result); + success = g_subprocess_communicate_utf8_finish (subprocess, result, stdout_buf, stderr_buf, error); + g_object_unref (result); + + g_bytes_unref (stdin_bytes); + return success; +} + +/** + * g_subprocess_communicate_utf8_async: + * @subprocess: Self + * @stdin_buf: (nullable): Input data, or %NULL + * @cancellable: Cancellable + * @callback: Callback + * @user_data: User data + * + * Asynchronous version of g_subprocess_communicate_utf8(). Complete + * invocation with g_subprocess_communicate_utf8_finish(). + */ +void +g_subprocess_communicate_utf8_async (GSubprocess *subprocess, + const char *stdin_buf, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GBytes *stdin_bytes; + size_t stdin_buf_len = 0; + + g_return_if_fail (G_IS_SUBPROCESS (subprocess)); + g_return_if_fail (stdin_buf == NULL || (subprocess->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + if (stdin_buf != NULL) + stdin_buf_len = strlen (stdin_buf); + stdin_bytes = g_bytes_new (stdin_buf, stdin_buf_len); + + g_subprocess_communicate_internal (subprocess, TRUE, stdin_bytes, cancellable, callback, user_data); + + g_bytes_unref (stdin_bytes); +} + +static gboolean +communicate_result_validate_utf8 (const char *stream_name, + char **return_location, + GMemoryOutputStream *buffer, + GError **error) +{ + if (return_location == NULL) + return TRUE; + + if (buffer) + { + const char *end; + *return_location = g_memory_output_stream_steal_data (buffer); + if (!g_utf8_validate (*return_location, -1, &end)) + { + g_free (*return_location); + *return_location = NULL; + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid UTF-8 in child %s at offset %lu", + stream_name, + (unsigned long) (end - *return_location)); + return FALSE; + } + } + else + *return_location = NULL; + + return TRUE; +} + +/** + * g_subprocess_communicate_utf8_finish: + * @subprocess: Self + * @result: Result + * @stdout_buf: (out) (nullable) (optional) (transfer full): Return location for stdout data + * @stderr_buf: (out) (nullable) (optional) (transfer full): Return location for stderr data + * @error: Error + * + * Complete an invocation of g_subprocess_communicate_utf8_async(). + */ +gboolean +g_subprocess_communicate_utf8_finish (GSubprocess *subprocess, + GAsyncResult *result, + char **stdout_buf, + char **stderr_buf, + GError **error) +{ + gboolean ret = FALSE; + CommunicateState *state; + gchar *local_stdout_buf = NULL, *local_stderr_buf = NULL; + + g_return_val_if_fail (G_IS_SUBPROCESS (subprocess), FALSE); + g_return_val_if_fail (g_task_is_valid (result, subprocess), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + g_object_ref (result); + + state = g_task_get_task_data ((GTask*)result); + if (!g_task_propagate_boolean ((GTask*)result, error)) + goto out; + + /* TODO - validate UTF-8 while streaming, rather than all at once. + */ + if (!communicate_result_validate_utf8 ("stdout", &local_stdout_buf, + state->stdout_buf, + error)) + goto out; + if (!communicate_result_validate_utf8 ("stderr", &local_stderr_buf, + state->stderr_buf, + error)) + goto out; + + ret = TRUE; + out: + g_object_unref (result); + + if (ret && stdout_buf != NULL) + *stdout_buf = g_steal_pointer (&local_stdout_buf); + if (ret && stderr_buf != NULL) + *stderr_buf = g_steal_pointer (&local_stderr_buf); + + g_free (local_stderr_buf); + g_free (local_stdout_buf); + + return ret; +} diff --git a/gio/gsubprocess.h b/gio/gsubprocess.h new file mode 100644 index 0000000..68bb26a --- /dev/null +++ b/gio/gsubprocess.h @@ -0,0 +1,167 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2012 Colin Walters + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Colin Walters + */ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_SUBPROCESS_H__ +#define __G_SUBPROCESS_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SUBPROCESS (g_subprocess_get_type ()) +#define G_SUBPROCESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SUBPROCESS, GSubprocess)) +#define G_IS_SUBPROCESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SUBPROCESS)) + +GLIB_AVAILABLE_IN_2_40 +GType g_subprocess_get_type (void) G_GNUC_CONST; + +/**** Core API ****/ + +GLIB_AVAILABLE_IN_2_40 +GSubprocess * g_subprocess_new (GSubprocessFlags flags, + GError **error, + const gchar *argv0, + ...) G_GNUC_NULL_TERMINATED; +GLIB_AVAILABLE_IN_2_40 +GSubprocess * g_subprocess_newv (const gchar * const *argv, + GSubprocessFlags flags, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +GOutputStream * g_subprocess_get_stdin_pipe (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +GInputStream * g_subprocess_get_stdout_pipe (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +GInputStream * g_subprocess_get_stderr_pipe (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +const gchar * g_subprocess_get_identifier (GSubprocess *subprocess); + +#ifdef G_OS_UNIX +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_send_signal (GSubprocess *subprocess, + gint signal_num); +#endif + +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_force_exit (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_wait (GSubprocess *subprocess, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_wait_async (GSubprocess *subprocess, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_wait_finish (GSubprocess *subprocess, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_wait_check (GSubprocess *subprocess, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_wait_check_async (GSubprocess *subprocess, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_wait_check_finish (GSubprocess *subprocess, + GAsyncResult *result, + GError **error); + + +GLIB_AVAILABLE_IN_2_40 +gint g_subprocess_get_status (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_get_successful (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_get_if_exited (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +gint g_subprocess_get_exit_status (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_get_if_signaled (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +gint g_subprocess_get_term_sig (GSubprocess *subprocess); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_communicate (GSubprocess *subprocess, + GBytes *stdin_buf, + GCancellable *cancellable, + GBytes **stdout_buf, + GBytes **stderr_buf, + GError **error); +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_communicate_async (GSubprocess *subprocess, + GBytes *stdin_buf, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_communicate_finish (GSubprocess *subprocess, + GAsyncResult *result, + GBytes **stdout_buf, + GBytes **stderr_buf, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_communicate_utf8 (GSubprocess *subprocess, + const char *stdin_buf, + GCancellable *cancellable, + char **stdout_buf, + char **stderr_buf, + GError **error); +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_communicate_utf8_async (GSubprocess *subprocess, + const char *stdin_buf, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_40 +gboolean g_subprocess_communicate_utf8_finish (GSubprocess *subprocess, + GAsyncResult *result, + char **stdout_buf, + char **stderr_buf, + GError **error); + +G_END_DECLS + +#endif /* __G_SUBPROCESS_H__ */ diff --git a/gio/gsubprocesslauncher-private.h b/gio/gsubprocesslauncher-private.h new file mode 100644 index 0000000..8bd1b28 --- /dev/null +++ b/gio/gsubprocesslauncher-private.h @@ -0,0 +1,59 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2012 Colin Walters + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_SUBPROCESS_CONTEXT_PRIVATE_H__ +#define __G_SUBPROCESS_CONTEXT_PRIVATE_H__ + +#include "gsubprocesslauncher.h" + +G_BEGIN_DECLS + +struct _GSubprocessLauncher +{ + GObject parent; + + GSubprocessFlags flags; + char **envp; + char *cwd; + +#ifdef G_OS_UNIX + gint stdin_fd; + gchar *stdin_path; + + gint stdout_fd; + gchar *stdout_path; + + gint stderr_fd; + gchar *stderr_path; + + GArray *source_fds; /* GSubprocessLauncher has ownership of the FD elements */ + GArray *target_fds; /* always the same length as source_fds; elements are just integers and not FDs in this process */ + gboolean closed_fd; + + GSpawnChildSetupFunc child_setup_func; + gpointer child_setup_user_data; + GDestroyNotify child_setup_destroy_notify; +#endif +}; + +void g_subprocess_set_launcher (GSubprocess *subprocess, + GSubprocessLauncher *launcher); + +G_END_DECLS + +#endif diff --git a/gio/gsubprocesslauncher.c b/gio/gsubprocesslauncher.c new file mode 100644 index 0000000..a1c65e9 --- /dev/null +++ b/gio/gsubprocesslauncher.c @@ -0,0 +1,802 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2012 Red Hat, Inc. + * Copyright © 2012-2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Colin Walters + * Ryan Lortie + */ + +/** + * SECTION:gsubprocesslauncher + * @title: GSubprocess Launcher + * @short_description: Environment options for launching a child process + * @include: gio/gio.h + * + * This class contains a set of options for launching child processes, + * such as where its standard input and output will be directed, the + * argument list, the environment, and more. + * + * While the #GSubprocess class has high level functions covering + * popular cases, use of this class allows access to more advanced + * options. It can also be used to launch multiple subprocesses with + * a similar configuration. + * + * Since: 2.40 + */ + +#define ALL_STDIN_FLAGS (G_SUBPROCESS_FLAGS_STDIN_PIPE | \ + G_SUBPROCESS_FLAGS_STDIN_INHERIT) +#define ALL_STDOUT_FLAGS (G_SUBPROCESS_FLAGS_STDOUT_PIPE | \ + G_SUBPROCESS_FLAGS_STDOUT_SILENCE) +#define ALL_STDERR_FLAGS (G_SUBPROCESS_FLAGS_STDERR_PIPE | \ + G_SUBPROCESS_FLAGS_STDERR_SILENCE | \ + G_SUBPROCESS_FLAGS_STDERR_MERGE) + +#include "config.h" + +#include "gsubprocesslauncher-private.h" +#include "gioenumtypes.h" +#include "gsubprocess.h" +#include "ginitable.h" +#include "gioerror.h" + +#ifdef G_OS_UNIX +#include +#include +#endif + +typedef GObjectClass GSubprocessLauncherClass; + +G_DEFINE_TYPE (GSubprocessLauncher, g_subprocess_launcher, G_TYPE_OBJECT) + +static gboolean +verify_disposition (const gchar *stream_name, + GSubprocessFlags filtered_flags, + gint fd, + const gchar *filename) +{ + guint n_bits; + + if (!filtered_flags) + n_bits = 0; + else if (((filtered_flags - 1) & filtered_flags) == 0) + n_bits = 1; + else + n_bits = 2; /* ...or more */ + + if (n_bits + (fd >= 0) + (filename != NULL) > 1) + { + GString *err; + + err = g_string_new (NULL); + if (n_bits) + { + GFlagsClass *class; + guint i; + + class = g_type_class_peek (G_TYPE_SUBPROCESS_FLAGS); + + for (i = 0; i < class->n_values; i++) + { + const GFlagsValue *value = &class->values[i]; + + if (filtered_flags & value->value) + g_string_append_printf (err, " %s", value->value_name); + } + + g_type_class_unref (class); + } + + if (fd >= 0) + g_string_append_printf (err, " g_subprocess_launcher_take_%s_fd()", stream_name); + + if (filename) + g_string_append_printf (err, " g_subprocess_launcher_set_%s_file_path()", stream_name); + + g_critical ("You may specify at most one disposition for the %s stream, but you specified:%s.", + stream_name, err->str); + g_string_free (err, TRUE); + + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_flags (GSubprocessFlags flags) +{ + return verify_disposition ("stdin", flags & ALL_STDIN_FLAGS, -1, NULL) && + verify_disposition ("stdout", flags & ALL_STDOUT_FLAGS, -1, NULL) && + verify_disposition ("stderr", flags & ALL_STDERR_FLAGS, -1, NULL); +} + +static void +g_subprocess_launcher_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + GSubprocessLauncher *launcher = G_SUBPROCESS_LAUNCHER (object); + + g_assert (prop_id == 1); + + if (verify_flags (g_value_get_flags (value))) + launcher->flags = g_value_get_flags (value); +} + +static void +g_subprocess_launcher_dispose (GObject *object) +{ + GSubprocessLauncher *self = G_SUBPROCESS_LAUNCHER (object); + +#ifdef G_OS_UNIX + g_clear_pointer (&self->stdin_path, g_free); + g_clear_pointer (&self->stdout_path, g_free); + g_clear_pointer (&self->stderr_path, g_free); + + g_subprocess_launcher_close (self); + + if (self->child_setup_destroy_notify) + (* self->child_setup_destroy_notify) (self->child_setup_user_data); + self->child_setup_destroy_notify = NULL; + self->child_setup_user_data = NULL; +#endif + + g_clear_pointer (&self->envp, g_strfreev); + g_clear_pointer (&self->cwd, g_free); + + G_OBJECT_CLASS (g_subprocess_launcher_parent_class)->dispose (object); +} + +static void +g_subprocess_launcher_init (GSubprocessLauncher *self) +{ + self->envp = g_get_environ (); + +#ifdef G_OS_UNIX + self->stdin_fd = -1; + self->stdout_fd = -1; + self->stderr_fd = -1; + self->source_fds = g_array_new (FALSE, 0, sizeof (int)); + self->target_fds = g_array_new (FALSE, 0, sizeof (int)); +#endif +} + +static void +g_subprocess_launcher_class_init (GSubprocessLauncherClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->set_property = g_subprocess_launcher_set_property; + gobject_class->dispose = g_subprocess_launcher_dispose; + + g_object_class_install_property (gobject_class, 1, + g_param_spec_flags ("flags", "Flags", "GSubprocessFlags for launched processes", + G_TYPE_SUBPROCESS_FLAGS, 0, G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY)); +} + +/** + * g_subprocess_launcher_new: + * @flags: #GSubprocessFlags + * + * Creates a new #GSubprocessLauncher. + * + * The launcher is created with the default options. A copy of the + * environment of the calling process is made at the time of this call + * and will be used as the environment that the process is launched in. + * + * Since: 2.40 + **/ +GSubprocessLauncher * +g_subprocess_launcher_new (GSubprocessFlags flags) +{ + if (!verify_flags (flags)) + return NULL; + + return g_object_new (G_TYPE_SUBPROCESS_LAUNCHER, + "flags", flags, + NULL); +} + +/** + * g_subprocess_launcher_set_environ: + * @self: a #GSubprocessLauncher + * @env: (array zero-terminated=1) (element-type filename) (transfer none): + * the replacement environment + * + * Replace the entire environment of processes launched from this + * launcher with the given 'environ' variable. + * + * Typically you will build this variable by using g_listenv() to copy + * the process 'environ' and using the functions g_environ_setenv(), + * g_environ_unsetenv(), etc. + * + * As an alternative, you can use g_subprocess_launcher_setenv(), + * g_subprocess_launcher_unsetenv(), etc. + * + * Pass an empty array to set an empty environment. Pass %NULL to inherit the + * parent process’ environment. As of GLib 2.54, the parent process’ environment + * will be copied when g_subprocess_launcher_set_environ() is called. + * Previously, it was copied when the subprocess was executed. This means the + * copied environment may now be modified (using g_subprocess_launcher_setenv(), + * etc.) before launching the subprocess. + * + * On UNIX, all strings in this array can be arbitrary byte strings. + * On Windows, they should be in UTF-8. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_set_environ (GSubprocessLauncher *self, + gchar **env) +{ + g_strfreev (self->envp); + self->envp = g_strdupv (env); + + if (self->envp == NULL) + self->envp = g_get_environ (); +} + +/** + * g_subprocess_launcher_setenv: + * @self: a #GSubprocessLauncher + * @variable: (type filename): the environment variable to set, + * must not contain '=' + * @value: (type filename): the new value for the variable + * @overwrite: whether to change the variable if it already exists + * + * Sets the environment variable @variable in the environment of + * processes launched from this launcher. + * + * On UNIX, both the variable's name and value can be arbitrary byte + * strings, except that the variable's name cannot contain '='. + * On Windows, they should be in UTF-8. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_setenv (GSubprocessLauncher *self, + const gchar *variable, + const gchar *value, + gboolean overwrite) +{ + self->envp = g_environ_setenv (self->envp, variable, value, overwrite); +} + +/** + * g_subprocess_launcher_unsetenv: + * @self: a #GSubprocessLauncher + * @variable: (type filename): the environment variable to unset, + * must not contain '=' + * + * Removes the environment variable @variable from the environment of + * processes launched from this launcher. + * + * On UNIX, the variable's name can be an arbitrary byte string not + * containing '='. On Windows, it should be in UTF-8. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_unsetenv (GSubprocessLauncher *self, + const gchar *variable) +{ + self->envp = g_environ_unsetenv (self->envp, variable); +} + +/** + * g_subprocess_launcher_getenv: + * @self: a #GSubprocessLauncher + * @variable: (type filename): the environment variable to get + * + * Returns the value of the environment variable @variable in the + * environment of processes launched from this launcher. + * + * On UNIX, the returned string can be an arbitrary byte string. + * On Windows, it will be UTF-8. + * + * Returns: (nullable) (type filename): the value of the environment variable, + * %NULL if unset + * + * Since: 2.40 + **/ +const gchar * +g_subprocess_launcher_getenv (GSubprocessLauncher *self, + const gchar *variable) +{ + return g_environ_getenv (self->envp, variable); +} + +/** + * g_subprocess_launcher_set_cwd: + * @self: a #GSubprocessLauncher + * @cwd: (type filename): the cwd for launched processes + * + * Sets the current working directory that processes will be launched + * with. + * + * By default processes are launched with the current working directory + * of the launching process at the time of launch. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_set_cwd (GSubprocessLauncher *self, + const gchar *cwd) +{ + g_free (self->cwd); + self->cwd = g_strdup (cwd); +} + +/** + * g_subprocess_launcher_set_flags: + * @self: a #GSubprocessLauncher + * @flags: #GSubprocessFlags + * + * Sets the flags on the launcher. + * + * The default flags are %G_SUBPROCESS_FLAGS_NONE. + * + * You may not set flags that specify conflicting options for how to + * handle a particular stdio stream (eg: specifying both + * %G_SUBPROCESS_FLAGS_STDIN_PIPE and + * %G_SUBPROCESS_FLAGS_STDIN_INHERIT). + * + * You may also not set a flag that conflicts with a previous call to a + * function like g_subprocess_launcher_set_stdin_file_path() or + * g_subprocess_launcher_take_stdout_fd(). + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_set_flags (GSubprocessLauncher *self, + GSubprocessFlags flags) +{ + const gchar *stdin_path = NULL, *stdout_path = NULL, *stderr_path = NULL; + gint stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; + +#ifdef G_OS_UNIX + stdin_fd = self->stdin_fd; + stdout_fd = self->stdout_fd; + stderr_fd = self->stderr_fd; + stdin_path = self->stdin_path; + stdout_path = self->stdout_path; + stderr_path = self->stderr_path; +#endif + + if (verify_disposition ("stdin", flags & ALL_STDIN_FLAGS, stdin_fd, stdin_path) && + verify_disposition ("stdout", flags & ALL_STDOUT_FLAGS, stdout_fd, stdout_path) && + verify_disposition ("stderr", flags & ALL_STDERR_FLAGS, stderr_fd, stderr_path)) + self->flags = flags; +} + +#ifdef G_OS_UNIX +static void +assign_fd (gint *fd_ptr, gint fd) +{ + gint flags; + + if (*fd_ptr != -1) + close (*fd_ptr); + + *fd_ptr = fd; + + if (fd != -1) + { + /* best effort */ + flags = fcntl (fd, F_GETFD); + if (~flags & FD_CLOEXEC) + fcntl (fd, F_SETFD, flags | FD_CLOEXEC); + } +} + +/** + * g_subprocess_launcher_set_stdin_file_path: + * @self: a #GSubprocessLauncher + * @path: (type filename) (nullable: a filename or %NULL + * + * Sets the file path to use as the stdin for spawned processes. + * + * If @path is %NULL then any previously given path is unset. + * + * The file must exist or spawning the process will fail. + * + * You may not set a stdin file path if a stdin fd is already set or if + * the launcher flags contain any flags directing stdin elsewhere. + * + * This feature is only available on UNIX. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_set_stdin_file_path (GSubprocessLauncher *self, + const gchar *path) +{ + if (verify_disposition ("stdin", self->flags & ALL_STDIN_FLAGS, self->stdin_fd, path)) + { + g_free (self->stdin_path); + self->stdin_path = g_strdup (path); + } +} + +/** + * g_subprocess_launcher_take_stdin_fd: + * @self: a #GSubprocessLauncher + * @fd: a file descriptor, or -1 + * + * Sets the file descriptor to use as the stdin for spawned processes. + * + * If @fd is -1 then any previously given fd is unset. + * + * Note that if your intention is to have the stdin of the calling + * process inherited by the child then %G_SUBPROCESS_FLAGS_STDIN_INHERIT + * is a better way to go about doing that. + * + * The passed @fd is noted but will not be touched in the current + * process. It is therefore necessary that it be kept open by the + * caller until the subprocess is spawned. The file descriptor will + * also not be explicitly closed on the child side, so it must be marked + * O_CLOEXEC if that's what you want. + * + * You may not set a stdin fd if a stdin file path is already set or if + * the launcher flags contain any flags directing stdin elsewhere. + * + * This feature is only available on UNIX. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_take_stdin_fd (GSubprocessLauncher *self, + gint fd) +{ + if (verify_disposition ("stdin", self->flags & ALL_STDIN_FLAGS, fd, self->stdin_path)) + assign_fd (&self->stdin_fd, fd); +} + +/** + * g_subprocess_launcher_set_stdout_file_path: + * @self: a #GSubprocessLauncher + * @path: (type filename) (nullable): a filename or %NULL + * + * Sets the file path to use as the stdout for spawned processes. + * + * If @path is %NULL then any previously given path is unset. + * + * The file will be created or truncated when the process is spawned, as + * would be the case if using '>' at the shell. + * + * You may not set a stdout file path if a stdout fd is already set or + * if the launcher flags contain any flags directing stdout elsewhere. + * + * This feature is only available on UNIX. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_set_stdout_file_path (GSubprocessLauncher *self, + const gchar *path) +{ + if (verify_disposition ("stdout", self->flags & ALL_STDOUT_FLAGS, self->stdout_fd, path)) + { + g_free (self->stdout_path); + self->stdout_path = g_strdup (path); + } +} + +/** + * g_subprocess_launcher_take_stdout_fd: + * @self: a #GSubprocessLauncher + * @fd: a file descriptor, or -1 + * + * Sets the file descriptor to use as the stdout for spawned processes. + * + * If @fd is -1 then any previously given fd is unset. + * + * Note that the default behaviour is to pass stdout through to the + * stdout of the parent process. + * + * The passed @fd is noted but will not be touched in the current + * process. It is therefore necessary that it be kept open by the + * caller until the subprocess is spawned. The file descriptor will + * also not be explicitly closed on the child side, so it must be marked + * O_CLOEXEC if that's what you want. + * + * You may not set a stdout fd if a stdout file path is already set or + * if the launcher flags contain any flags directing stdout elsewhere. + * + * This feature is only available on UNIX. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_take_stdout_fd (GSubprocessLauncher *self, + gint fd) +{ + if (verify_disposition ("stdout", self->flags & ALL_STDOUT_FLAGS, fd, self->stdout_path)) + assign_fd (&self->stdout_fd, fd); +} + +/** + * g_subprocess_launcher_set_stderr_file_path: + * @self: a #GSubprocessLauncher + * @path: (type filename) (nullable): a filename or %NULL + * + * Sets the file path to use as the stderr for spawned processes. + * + * If @path is %NULL then any previously given path is unset. + * + * The file will be created or truncated when the process is spawned, as + * would be the case if using '2>' at the shell. + * + * If you want to send both stdout and stderr to the same file then use + * %G_SUBPROCESS_FLAGS_STDERR_MERGE. + * + * You may not set a stderr file path if a stderr fd is already set or + * if the launcher flags contain any flags directing stderr elsewhere. + * + * This feature is only available on UNIX. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_set_stderr_file_path (GSubprocessLauncher *self, + const gchar *path) +{ + if (verify_disposition ("stderr", self->flags & ALL_STDERR_FLAGS, self->stderr_fd, path)) + { + g_free (self->stderr_path); + self->stderr_path = g_strdup (path); + } +} + +/** + * g_subprocess_launcher_take_stderr_fd: + * @self: a #GSubprocessLauncher + * @fd: a file descriptor, or -1 + * + * Sets the file descriptor to use as the stderr for spawned processes. + * + * If @fd is -1 then any previously given fd is unset. + * + * Note that the default behaviour is to pass stderr through to the + * stderr of the parent process. + * + * The passed @fd belongs to the #GSubprocessLauncher. It will be + * automatically closed when the launcher is finalized. The file + * descriptor will also be closed on the child side when executing the + * spawned process. + * + * You may not set a stderr fd if a stderr file path is already set or + * if the launcher flags contain any flags directing stderr elsewhere. + * + * This feature is only available on UNIX. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher *self, + gint fd) +{ + if (verify_disposition ("stderr", self->flags & ALL_STDERR_FLAGS, fd, self->stderr_path)) + assign_fd (&self->stderr_fd, fd); +} + +/** + * g_subprocess_launcher_take_fd: + * @self: a #GSubprocessLauncher + * @source_fd: File descriptor in parent process + * @target_fd: Target descriptor for child process + * + * Transfer an arbitrary file descriptor from parent process to the + * child. This function takes ownership of the @source_fd; it will be closed + * in the parent when @self is freed. + * + * By default, all file descriptors from the parent will be closed. + * This function allows you to create (for example) a custom `pipe()` or + * `socketpair()` before launching the process, and choose the target + * descriptor in the child. + * + * An example use case is GNUPG, which has a command line argument + * `--passphrase-fd` providing a file descriptor number where it expects + * the passphrase to be written. + */ +void +g_subprocess_launcher_take_fd (GSubprocessLauncher *self, + gint source_fd, + gint target_fd) +{ + if (self->source_fds != NULL && self->target_fds != NULL) + { + g_array_append_val (self->source_fds, source_fd); + g_array_append_val (self->target_fds, target_fd); + } +} + +/** + * g_subprocess_launcher_close: + * @self: a #GSubprocessLauncher + * + * Closes all the file descriptors previously passed to the object with + * g_subprocess_launcher_take_fd(), g_subprocess_launcher_take_stderr_fd(), etc. + * + * After calling this method, any subsequent calls to g_subprocess_launcher_spawn() or g_subprocess_launcher_spawnv() will + * return %G_IO_ERROR_CLOSED. This method is idempotent if + * called more than once. + * + * This function is called automatically when the #GSubprocessLauncher + * is disposed, but is provided separately so that garbage collected + * language bindings can call it earlier to guarantee when FDs are closed. + * + * Since: 2.68 + */ +void +g_subprocess_launcher_close (GSubprocessLauncher *self) +{ + guint i; + + g_return_if_fail (G_IS_SUBPROCESS_LAUNCHER (self)); + + if (self->stdin_fd != -1) + close (self->stdin_fd); + self->stdin_fd = -1; + + if (self->stdout_fd != -1) + close (self->stdout_fd); + self->stdout_fd = -1; + + if (self->stderr_fd != -1) + close (self->stderr_fd); + self->stderr_fd = -1; + + if (self->source_fds) + { + g_assert (self->target_fds != NULL); + g_assert (self->source_fds->len == self->target_fds->len); + + /* Note: Don’t close the target_fds, as they’re only valid FDs in the + * child process. This code never executes in the child process. */ + for (i = 0; i < self->source_fds->len; i++) + (void) close (g_array_index (self->source_fds, int, i)); + + g_clear_pointer (&self->source_fds, g_array_unref); + g_clear_pointer (&self->target_fds, g_array_unref); + } + + self->closed_fd = TRUE; +} + +/** + * g_subprocess_launcher_set_child_setup: (skip) + * @self: a #GSubprocessLauncher + * @child_setup: a #GSpawnChildSetupFunc to use as the child setup function + * @user_data: user data for @child_setup + * @destroy_notify: a #GDestroyNotify for @user_data + * + * Sets up a child setup function. + * + * The child setup function will be called after fork() but before + * exec() on the child's side. + * + * @destroy_notify will not be automatically called on the child's side + * of the fork(). It will only be called when the last reference on the + * #GSubprocessLauncher is dropped or when a new child setup function is + * given. + * + * %NULL can be given as @child_setup to disable the functionality. + * + * Child setup functions are only available on UNIX. + * + * Since: 2.40 + **/ +void +g_subprocess_launcher_set_child_setup (GSubprocessLauncher *self, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GDestroyNotify destroy_notify) +{ + if (self->child_setup_destroy_notify) + (* self->child_setup_destroy_notify) (self->child_setup_user_data); + + self->child_setup_func = child_setup; + self->child_setup_user_data = user_data; + self->child_setup_destroy_notify = destroy_notify; +} +#endif + +/** + * g_subprocess_launcher_spawn: + * @self: a #GSubprocessLauncher + * @error: Error + * @argv0: Command line arguments + * @...: Continued arguments, %NULL terminated + * + * Creates a #GSubprocess given a provided varargs list of arguments. + * + * Since: 2.40 + * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set) + **/ +GSubprocess * +g_subprocess_launcher_spawn (GSubprocessLauncher *launcher, + GError **error, + const gchar *argv0, + ...) +{ + GSubprocess *result; + GPtrArray *args; + const gchar *arg; + va_list ap; + + g_return_val_if_fail (argv0 != NULL && argv0[0] != '\0', NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + args = g_ptr_array_new (); + + va_start (ap, argv0); + g_ptr_array_add (args, (gchar *) argv0); + while ((arg = va_arg (ap, const gchar *))) + g_ptr_array_add (args, (gchar *) arg); + + g_ptr_array_add (args, NULL); + va_end (ap); + + result = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + + g_ptr_array_free (args, TRUE); + + return result; + +} + +/** + * g_subprocess_launcher_spawnv: + * @self: a #GSubprocessLauncher + * @argv: (array zero-terminated=1) (element-type filename): Command line arguments + * @error: Error + * + * Creates a #GSubprocess given a provided array of arguments. + * + * Since: 2.40 + * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set) + **/ +GSubprocess * +g_subprocess_launcher_spawnv (GSubprocessLauncher *launcher, + const gchar * const *argv, + GError **error) +{ + GSubprocess *subprocess; + + g_return_val_if_fail (argv != NULL && argv[0] != NULL && argv[0][0] != '\0', NULL); + +#ifdef G_OS_UNIX + if (launcher->closed_fd) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_CLOSED, + "Can't spawn a new child because a passed file descriptor has been closed."); + return NULL; + } +#endif + + subprocess = g_object_new (G_TYPE_SUBPROCESS, + "argv", argv, + "flags", launcher->flags, + NULL); + g_subprocess_set_launcher (subprocess, launcher); + + if (!g_initable_init (G_INITABLE (subprocess), NULL, error)) + { + g_object_unref (subprocess); + return NULL; + } + + return subprocess; +} diff --git a/gio/gsubprocesslauncher.h b/gio/gsubprocesslauncher.h new file mode 100644 index 0000000..0654c2b --- /dev/null +++ b/gio/gsubprocesslauncher.h @@ -0,0 +1,119 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2012,2013 Colin Walters + * Copyright © 2012,2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Ryan Lortie + * Author: Colin Walters + */ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_SUBPROCESS_LAUNCHER_H__ +#define __G_SUBPROCESS_LAUNCHER_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_SUBPROCESS_LAUNCHER (g_subprocess_launcher_get_type ()) +#define G_SUBPROCESS_LAUNCHER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SUBPROCESS_LAUNCHER, GSubprocessLauncher)) +#define G_IS_SUBPROCESS_LAUNCHER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SUBPROCESS_LAUNCHER)) + +GLIB_AVAILABLE_IN_2_40 +GType g_subprocess_launcher_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_40 +GSubprocessLauncher * g_subprocess_launcher_new (GSubprocessFlags flags); + +GLIB_AVAILABLE_IN_2_40 +GSubprocess * g_subprocess_launcher_spawn (GSubprocessLauncher *self, + GError **error, + const gchar *argv0, + ...) G_GNUC_NULL_TERMINATED; + +GLIB_AVAILABLE_IN_2_40 +GSubprocess * g_subprocess_launcher_spawnv (GSubprocessLauncher *self, + const gchar * const *argv, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_set_environ (GSubprocessLauncher *self, + gchar **env); + +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_setenv (GSubprocessLauncher *self, + const gchar *variable, + const gchar *value, + gboolean overwrite); + +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_unsetenv (GSubprocessLauncher *self, + const gchar *variable); + +GLIB_AVAILABLE_IN_2_40 +const gchar * g_subprocess_launcher_getenv (GSubprocessLauncher *self, + const gchar *variable); + +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_set_cwd (GSubprocessLauncher *self, + const gchar *cwd); +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_set_flags (GSubprocessLauncher *self, + GSubprocessFlags flags); + +/* Extended I/O control, only available on UNIX */ +#ifdef G_OS_UNIX +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_set_stdin_file_path (GSubprocessLauncher *self, + const gchar *path); +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_take_stdin_fd (GSubprocessLauncher *self, + gint fd); +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_set_stdout_file_path (GSubprocessLauncher *self, + const gchar *path); +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_take_stdout_fd (GSubprocessLauncher *self, + gint fd); +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_set_stderr_file_path (GSubprocessLauncher *self, + const gchar *path); +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher *self, + gint fd); + +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_take_fd (GSubprocessLauncher *self, + gint source_fd, + gint target_fd); + +GLIB_AVAILABLE_IN_2_68 +void g_subprocess_launcher_close (GSubprocessLauncher *self); + +/* Child setup, only available on UNIX */ +GLIB_AVAILABLE_IN_2_40 +void g_subprocess_launcher_set_child_setup (GSubprocessLauncher *self, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GDestroyNotify destroy_notify); +#endif + +G_END_DECLS + +#endif /* __G_SUBPROCESS_H__ */ diff --git a/gio/gtask.c b/gio/gtask.c new file mode 100644 index 0000000..365f200 --- /dev/null +++ b/gio/gtask.c @@ -0,0 +1,2285 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "gio_trace.h" + +#include "gtask.h" + +#include "gasyncresult.h" +#include "gcancellable.h" +#include "glib-private.h" +#include "gtrace-private.h" + +#include "glibintl.h" + +#include + +/** + * SECTION:gtask + * @short_description: Cancellable synchronous or asynchronous task + * and result + * @include: gio/gio.h + * @see_also: #GAsyncResult + * + * A #GTask represents and manages a cancellable "task". + * + * ## Asynchronous operations + * + * The most common usage of #GTask is as a #GAsyncResult, to + * manage data during an asynchronous operation. You call + * g_task_new() in the "start" method, followed by + * g_task_set_task_data() and the like if you need to keep some + * additional data associated with the task, and then pass the + * task object around through your asynchronous operation. + * Eventually, you will call a method such as + * g_task_return_pointer() or g_task_return_error(), which will + * save the value you give it and then invoke the task's callback + * function in the + * [thread-default main context][g-main-context-push-thread-default] + * where it was created (waiting until the next iteration of the main + * loop first, if necessary). The caller will pass the #GTask back to + * the operation's finish function (as a #GAsyncResult), and you can + * use g_task_propagate_pointer() or the like to extract the + * return value. + * + * Using #GTask requires the thread-default #GMainContext from when the + * #GTask was constructed to be running at least until the task has completed + * and its data has been freed. + * + * Here is an example for using GTask as a GAsyncResult: + * |[ + * typedef struct { + * CakeFrostingType frosting; + * char *message; + * } DecorationData; + * + * static void + * decoration_data_free (DecorationData *decoration) + * { + * g_free (decoration->message); + * g_slice_free (DecorationData, decoration); + * } + * + * static void + * baked_cb (Cake *cake, + * gpointer user_data) + * { + * GTask *task = user_data; + * DecorationData *decoration = g_task_get_task_data (task); + * GError *error = NULL; + * + * if (cake == NULL) + * { + * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR, + * "Go to the supermarket"); + * g_object_unref (task); + * return; + * } + * + * if (!cake_decorate (cake, decoration->frosting, decoration->message, &error)) + * { + * g_object_unref (cake); + * // g_task_return_error() takes ownership of error + * g_task_return_error (task, error); + * g_object_unref (task); + * return; + * } + * + * g_task_return_pointer (task, cake, g_object_unref); + * g_object_unref (task); + * } + * + * void + * baker_bake_cake_async (Baker *self, + * guint radius, + * CakeFlavor flavor, + * CakeFrostingType frosting, + * const char *message, + * GCancellable *cancellable, + * GAsyncReadyCallback callback, + * gpointer user_data) + * { + * GTask *task; + * DecorationData *decoration; + * Cake *cake; + * + * task = g_task_new (self, cancellable, callback, user_data); + * if (radius < 3) + * { + * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_TOO_SMALL, + * "%ucm radius cakes are silly", + * radius); + * g_object_unref (task); + * return; + * } + * + * cake = _baker_get_cached_cake (self, radius, flavor, frosting, message); + * if (cake != NULL) + * { + * // _baker_get_cached_cake() returns a reffed cake + * g_task_return_pointer (task, cake, g_object_unref); + * g_object_unref (task); + * return; + * } + * + * decoration = g_slice_new (DecorationData); + * decoration->frosting = frosting; + * decoration->message = g_strdup (message); + * g_task_set_task_data (task, decoration, (GDestroyNotify) decoration_data_free); + * + * _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task); + * } + * + * Cake * + * baker_bake_cake_finish (Baker *self, + * GAsyncResult *result, + * GError **error) + * { + * g_return_val_if_fail (g_task_is_valid (result, self), NULL); + * + * return g_task_propagate_pointer (G_TASK (result), error); + * } + * ]| + * + * ## Chained asynchronous operations + * + * #GTask also tries to simplify asynchronous operations that + * internally chain together several smaller asynchronous + * operations. g_task_get_cancellable(), g_task_get_context(), + * and g_task_get_priority() allow you to get back the task's + * #GCancellable, #GMainContext, and [I/O priority][io-priority] + * when starting a new subtask, so you don't have to keep track + * of them yourself. g_task_attach_source() simplifies the case + * of waiting for a source to fire (automatically using the correct + * #GMainContext and priority). + * + * Here is an example for chained asynchronous operations: + * |[ + * typedef struct { + * Cake *cake; + * CakeFrostingType frosting; + * char *message; + * } BakingData; + * + * static void + * decoration_data_free (BakingData *bd) + * { + * if (bd->cake) + * g_object_unref (bd->cake); + * g_free (bd->message); + * g_slice_free (BakingData, bd); + * } + * + * static void + * decorated_cb (Cake *cake, + * GAsyncResult *result, + * gpointer user_data) + * { + * GTask *task = user_data; + * GError *error = NULL; + * + * if (!cake_decorate_finish (cake, result, &error)) + * { + * g_object_unref (cake); + * g_task_return_error (task, error); + * g_object_unref (task); + * return; + * } + * + * // baking_data_free() will drop its ref on the cake, so we have to + * // take another here to give to the caller. + * g_task_return_pointer (task, g_object_ref (cake), g_object_unref); + * g_object_unref (task); + * } + * + * static gboolean + * decorator_ready (gpointer user_data) + * { + * GTask *task = user_data; + * BakingData *bd = g_task_get_task_data (task); + * + * cake_decorate_async (bd->cake, bd->frosting, bd->message, + * g_task_get_cancellable (task), + * decorated_cb, task); + * + * return G_SOURCE_REMOVE; + * } + * + * static void + * baked_cb (Cake *cake, + * gpointer user_data) + * { + * GTask *task = user_data; + * BakingData *bd = g_task_get_task_data (task); + * GError *error = NULL; + * + * if (cake == NULL) + * { + * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR, + * "Go to the supermarket"); + * g_object_unref (task); + * return; + * } + * + * bd->cake = cake; + * + * // Bail out now if the user has already cancelled + * if (g_task_return_error_if_cancelled (task)) + * { + * g_object_unref (task); + * return; + * } + * + * if (cake_decorator_available (cake)) + * decorator_ready (task); + * else + * { + * GSource *source; + * + * source = cake_decorator_wait_source_new (cake); + * // Attach @source to @task's GMainContext and have it call + * // decorator_ready() when it is ready. + * g_task_attach_source (task, source, decorator_ready); + * g_source_unref (source); + * } + * } + * + * void + * baker_bake_cake_async (Baker *self, + * guint radius, + * CakeFlavor flavor, + * CakeFrostingType frosting, + * const char *message, + * gint priority, + * GCancellable *cancellable, + * GAsyncReadyCallback callback, + * gpointer user_data) + * { + * GTask *task; + * BakingData *bd; + * + * task = g_task_new (self, cancellable, callback, user_data); + * g_task_set_priority (task, priority); + * + * bd = g_slice_new0 (BakingData); + * bd->frosting = frosting; + * bd->message = g_strdup (message); + * g_task_set_task_data (task, bd, (GDestroyNotify) baking_data_free); + * + * _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task); + * } + * + * Cake * + * baker_bake_cake_finish (Baker *self, + * GAsyncResult *result, + * GError **error) + * { + * g_return_val_if_fail (g_task_is_valid (result, self), NULL); + * + * return g_task_propagate_pointer (G_TASK (result), error); + * } + * ]| + * + * ## Asynchronous operations from synchronous ones + * + * You can use g_task_run_in_thread() to turn a synchronous + * operation into an asynchronous one, by running it in a thread. + * When it completes, the result will be dispatched to the + * [thread-default main context][g-main-context-push-thread-default] + * where the #GTask was created. + * + * Running a task in a thread: + * |[ + * typedef struct { + * guint radius; + * CakeFlavor flavor; + * CakeFrostingType frosting; + * char *message; + * } CakeData; + * + * static void + * cake_data_free (CakeData *cake_data) + * { + * g_free (cake_data->message); + * g_slice_free (CakeData, cake_data); + * } + * + * static void + * bake_cake_thread (GTask *task, + * gpointer source_object, + * gpointer task_data, + * GCancellable *cancellable) + * { + * Baker *self = source_object; + * CakeData *cake_data = task_data; + * Cake *cake; + * GError *error = NULL; + * + * cake = bake_cake (baker, cake_data->radius, cake_data->flavor, + * cake_data->frosting, cake_data->message, + * cancellable, &error); + * if (cake) + * g_task_return_pointer (task, cake, g_object_unref); + * else + * g_task_return_error (task, error); + * } + * + * void + * baker_bake_cake_async (Baker *self, + * guint radius, + * CakeFlavor flavor, + * CakeFrostingType frosting, + * const char *message, + * GCancellable *cancellable, + * GAsyncReadyCallback callback, + * gpointer user_data) + * { + * CakeData *cake_data; + * GTask *task; + * + * cake_data = g_slice_new (CakeData); + * cake_data->radius = radius; + * cake_data->flavor = flavor; + * cake_data->frosting = frosting; + * cake_data->message = g_strdup (message); + * task = g_task_new (self, cancellable, callback, user_data); + * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); + * g_task_run_in_thread (task, bake_cake_thread); + * g_object_unref (task); + * } + * + * Cake * + * baker_bake_cake_finish (Baker *self, + * GAsyncResult *result, + * GError **error) + * { + * g_return_val_if_fail (g_task_is_valid (result, self), NULL); + * + * return g_task_propagate_pointer (G_TASK (result), error); + * } + * ]| + * + * ## Adding cancellability to uncancellable tasks + * + * Finally, g_task_run_in_thread() and g_task_run_in_thread_sync() + * can be used to turn an uncancellable operation into a + * cancellable one. If you call g_task_set_return_on_cancel(), + * passing %TRUE, then if the task's #GCancellable is cancelled, + * it will return control back to the caller immediately, while + * allowing the task thread to continue running in the background + * (and simply discarding its result when it finally does finish). + * Provided that the task thread is careful about how it uses + * locks and other externally-visible resources, this allows you + * to make "GLib-friendly" asynchronous and cancellable + * synchronous variants of blocking APIs. + * + * Cancelling a task: + * |[ + * static void + * bake_cake_thread (GTask *task, + * gpointer source_object, + * gpointer task_data, + * GCancellable *cancellable) + * { + * Baker *self = source_object; + * CakeData *cake_data = task_data; + * Cake *cake; + * GError *error = NULL; + * + * cake = bake_cake (baker, cake_data->radius, cake_data->flavor, + * cake_data->frosting, cake_data->message, + * &error); + * if (error) + * { + * g_task_return_error (task, error); + * return; + * } + * + * // If the task has already been cancelled, then we don't want to add + * // the cake to the cake cache. Likewise, we don't want to have the + * // task get cancelled in the middle of updating the cache. + * // g_task_set_return_on_cancel() will return %TRUE here if it managed + * // to disable return-on-cancel, or %FALSE if the task was cancelled + * // before it could. + * if (g_task_set_return_on_cancel (task, FALSE)) + * { + * // If the caller cancels at this point, their + * // GAsyncReadyCallback won't be invoked until we return, + * // so we don't have to worry that this code will run at + * // the same time as that code does. But if there were + * // other functions that might look at the cake cache, + * // then we'd probably need a GMutex here as well. + * baker_add_cake_to_cache (baker, cake); + * g_task_return_pointer (task, cake, g_object_unref); + * } + * } + * + * void + * baker_bake_cake_async (Baker *self, + * guint radius, + * CakeFlavor flavor, + * CakeFrostingType frosting, + * const char *message, + * GCancellable *cancellable, + * GAsyncReadyCallback callback, + * gpointer user_data) + * { + * CakeData *cake_data; + * GTask *task; + * + * cake_data = g_slice_new (CakeData); + * + * ... + * + * task = g_task_new (self, cancellable, callback, user_data); + * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); + * g_task_set_return_on_cancel (task, TRUE); + * g_task_run_in_thread (task, bake_cake_thread); + * } + * + * Cake * + * baker_bake_cake_sync (Baker *self, + * guint radius, + * CakeFlavor flavor, + * CakeFrostingType frosting, + * const char *message, + * GCancellable *cancellable, + * GError **error) + * { + * CakeData *cake_data; + * GTask *task; + * Cake *cake; + * + * cake_data = g_slice_new (CakeData); + * + * ... + * + * task = g_task_new (self, cancellable, NULL, NULL); + * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); + * g_task_set_return_on_cancel (task, TRUE); + * g_task_run_in_thread_sync (task, bake_cake_thread); + * + * cake = g_task_propagate_pointer (task, error); + * g_object_unref (task); + * return cake; + * } + * ]| + * + * ## Porting from GSimpleAsyncResult + * + * #GTask's API attempts to be simpler than #GSimpleAsyncResult's + * in several ways: + * - You can save task-specific data with g_task_set_task_data(), and + * retrieve it later with g_task_get_task_data(). This replaces the + * abuse of g_simple_async_result_set_op_res_gpointer() for the same + * purpose with #GSimpleAsyncResult. + * - In addition to the task data, #GTask also keeps track of the + * [priority][io-priority], #GCancellable, and + * #GMainContext associated with the task, so tasks that consist of + * a chain of simpler asynchronous operations will have easy access + * to those values when starting each sub-task. + * - g_task_return_error_if_cancelled() provides simplified + * handling for cancellation. In addition, cancellation + * overrides any other #GTask return value by default, like + * #GSimpleAsyncResult does when + * g_simple_async_result_set_check_cancellable() is called. + * (You can use g_task_set_check_cancellable() to turn off that + * behavior.) On the other hand, g_task_run_in_thread() + * guarantees that it will always run your + * `task_func`, even if the task's #GCancellable + * is already cancelled before the task gets a chance to run; + * you can start your `task_func` with a + * g_task_return_error_if_cancelled() check if you need the + * old behavior. + * - The "return" methods (eg, g_task_return_pointer()) + * automatically cause the task to be "completed" as well, and + * there is no need to worry about the "complete" vs "complete + * in idle" distinction. (#GTask automatically figures out + * whether the task's callback can be invoked directly, or + * if it needs to be sent to another #GMainContext, or delayed + * until the next iteration of the current #GMainContext.) + * - The "finish" functions for #GTask based operations are generally + * much simpler than #GSimpleAsyncResult ones, normally consisting + * of only a single call to g_task_propagate_pointer() or the like. + * Since g_task_propagate_pointer() "steals" the return value from + * the #GTask, it is not necessary to juggle pointers around to + * prevent it from being freed twice. + * - With #GSimpleAsyncResult, it was common to call + * g_simple_async_result_propagate_error() from the + * `_finish()` wrapper function, and have + * virtual method implementations only deal with successful + * returns. This behavior is deprecated, because it makes it + * difficult for a subclass to chain to a parent class's async + * methods. Instead, the wrapper function should just be a + * simple wrapper, and the virtual method should call an + * appropriate `g_task_propagate_` function. + * Note that wrapper methods can now use + * g_async_result_legacy_propagate_error() to do old-style + * #GSimpleAsyncResult error-returning behavior, and + * g_async_result_is_tagged() to check if a result is tagged as + * having come from the `_async()` wrapper + * function (for "short-circuit" results, such as when passing + * 0 to g_input_stream_read_async()). + */ + +/** + * GTask: + * + * The opaque object representing a synchronous or asynchronous task + * and its result. + */ + +struct _GTask { + GObject parent_instance; + + gpointer source_object; + gpointer source_tag; + gchar *name; /* (owned); may only be modified before the #GTask is threaded */ + + gpointer task_data; + GDestroyNotify task_data_destroy; + + GMainContext *context; + gint64 creation_time; + gint priority; + GCancellable *cancellable; + + GAsyncReadyCallback callback; + gpointer callback_data; + + GTaskThreadFunc task_func; + GMutex lock; + GCond cond; + + /* This can’t be in the bit field because we access it from TRACE(). */ + gboolean thread_cancelled; + + /* Protected by the lock when task is threaded: */ + gboolean thread_complete : 1; + gboolean return_on_cancel : 1; + gboolean : 0; + + /* Unprotected, but written to when task runs in thread: */ + gboolean completed : 1; + gboolean had_error : 1; + gboolean result_set : 1; + gboolean ever_returned : 1; + gboolean : 0; + + /* Read-only once task runs in thread: */ + gboolean check_cancellable : 1; + gboolean synchronous : 1; + gboolean blocking_other_task : 1; + + GError *error; + union { + gpointer pointer; + gssize size; + gboolean boolean; + } result; + GDestroyNotify result_destroy; +}; + +#define G_TASK_IS_THREADED(task) ((task)->task_func != NULL) + +struct _GTaskClass +{ + GObjectClass parent_class; +}; + +typedef enum +{ + PROP_COMPLETED = 1, +} GTaskProperty; + +static void g_task_async_result_iface_init (GAsyncResultIface *iface); +static void g_task_thread_pool_init (void); + +G_DEFINE_TYPE_WITH_CODE (GTask, g_task, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, + g_task_async_result_iface_init); + g_task_thread_pool_init ();) + +static GThreadPool *task_pool; +static GMutex task_pool_mutex; +static GPrivate task_private = G_PRIVATE_INIT (NULL); +static GSource *task_pool_manager; +static guint64 task_wait_time; +static gint tasks_running; + +static guint task_pool_max_counter; +static guint tasks_running_counter; + +/* When the task pool fills up and blocks, and the program keeps + * queueing more tasks, we will slowly add more threads to the pool + * (in case the existing tasks are trying to queue subtasks of their + * own) until tasks start completing again. These "overflow" threads + * will only run one task apiece, and then exit, so the pool will + * eventually get back down to its base size. + * + * The base and multiplier below gives us 10 extra threads after about + * a second of blocking, 30 after 5 seconds, 100 after a minute, and + * 200 after 20 minutes. + * + * We specify maximum pool size of 330 to increase the waiting time up + * to around 30 minutes. + */ +#define G_TASK_POOL_SIZE 10 +#define G_TASK_WAIT_TIME_BASE 100000 +#define G_TASK_WAIT_TIME_MULTIPLIER 1.03 +#define G_TASK_WAIT_TIME_MAX_POOL_SIZE 330 + +static void +g_task_init (GTask *task) +{ + task->check_cancellable = TRUE; +} + +static void +g_task_finalize (GObject *object) +{ + GTask *task = G_TASK (object); + + g_clear_object (&task->source_object); + g_clear_object (&task->cancellable); + g_free (task->name); + + if (task->context) + g_main_context_unref (task->context); + + if (task->task_data_destroy) + task->task_data_destroy (task->task_data); + + if (task->result_destroy && task->result.pointer) + task->result_destroy (task->result.pointer); + + if (task->error) + g_error_free (task->error); + + if (G_TASK_IS_THREADED (task)) + { + g_mutex_clear (&task->lock); + g_cond_clear (&task->cond); + } + + G_OBJECT_CLASS (g_task_parent_class)->finalize (object); +} + +/** + * g_task_new: + * @source_object: (nullable) (type GObject): the #GObject that owns + * this task, or %NULL. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback. + * @callback_data: (closure): user data passed to @callback. + * + * Creates a #GTask acting on @source_object, which will eventually be + * used to invoke @callback in the current + * [thread-default main context][g-main-context-push-thread-default]. + * + * Call this in the "start" method of your asynchronous method, and + * pass the #GTask around throughout the asynchronous operation. You + * can use g_task_set_task_data() to attach task-specific data to the + * object, which you can retrieve later via g_task_get_task_data(). + * + * By default, if @cancellable is cancelled, then the return value of + * the task will always be %G_IO_ERROR_CANCELLED, even if the task had + * already completed before the cancellation. This allows for + * simplified handling in cases where cancellation may imply that + * other objects that the task depends on have been destroyed. If you + * do not want this behavior, you can use + * g_task_set_check_cancellable() to change it. + * + * Returns: a #GTask. + * + * Since: 2.36 + */ +GTask * +g_task_new (gpointer source_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer callback_data) +{ + GTask *task; + GSource *source; + + task = g_object_new (G_TYPE_TASK, NULL); + task->source_object = source_object ? g_object_ref (source_object) : NULL; + task->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + task->callback = callback; + task->callback_data = callback_data; + task->context = g_main_context_ref_thread_default (); + + source = g_main_current_source (); + if (source) + task->creation_time = g_source_get_time (source); + + TRACE (GIO_TASK_NEW (task, source_object, cancellable, + callback, callback_data)); + + return task; +} + +/** + * g_task_report_error: + * @source_object: (nullable) (type GObject): the #GObject that owns + * this task, or %NULL. + * @callback: (scope async): a #GAsyncReadyCallback. + * @callback_data: (closure): user data passed to @callback. + * @source_tag: an opaque pointer indicating the source of this task + * @error: (transfer full): error to report + * + * Creates a #GTask and then immediately calls g_task_return_error() + * on it. Use this in the wrapper function of an asynchronous method + * when you want to avoid even calling the virtual method. You can + * then use g_async_result_is_tagged() in the finish method wrapper to + * check if the result there is tagged as having been created by the + * wrapper method, and deal with it appropriately if so. + * + * See also g_task_report_new_error(). + * + * Since: 2.36 + */ +void +g_task_report_error (gpointer source_object, + GAsyncReadyCallback callback, + gpointer callback_data, + gpointer source_tag, + GError *error) +{ + GTask *task; + + task = g_task_new (source_object, NULL, callback, callback_data); + g_task_set_source_tag (task, source_tag); + g_task_set_name (task, G_STRFUNC); + g_task_return_error (task, error); + g_object_unref (task); +} + +/** + * g_task_report_new_error: + * @source_object: (nullable) (type GObject): the #GObject that owns + * this task, or %NULL. + * @callback: (scope async): a #GAsyncReadyCallback. + * @callback_data: (closure): user data passed to @callback. + * @source_tag: an opaque pointer indicating the source of this task + * @domain: a #GQuark. + * @code: an error code. + * @format: a string with format characters. + * @...: a list of values to insert into @format. + * + * Creates a #GTask and then immediately calls + * g_task_return_new_error() on it. Use this in the wrapper function + * of an asynchronous method when you want to avoid even calling the + * virtual method. You can then use g_async_result_is_tagged() in the + * finish method wrapper to check if the result there is tagged as + * having been created by the wrapper method, and deal with it + * appropriately if so. + * + * See also g_task_report_error(). + * + * Since: 2.36 + */ +void +g_task_report_new_error (gpointer source_object, + GAsyncReadyCallback callback, + gpointer callback_data, + gpointer source_tag, + GQuark domain, + gint code, + const char *format, + ...) +{ + GError *error; + va_list ap; + + va_start (ap, format); + error = g_error_new_valist (domain, code, format, ap); + va_end (ap); + + g_task_report_error (source_object, callback, callback_data, + source_tag, error); +} + +/** + * g_task_set_task_data: + * @task: the #GTask + * @task_data: (nullable): task-specific data + * @task_data_destroy: (nullable): #GDestroyNotify for @task_data + * + * Sets @task's task data (freeing the existing task data, if any). + * + * Since: 2.36 + */ +void +g_task_set_task_data (GTask *task, + gpointer task_data, + GDestroyNotify task_data_destroy) +{ + g_return_if_fail (G_IS_TASK (task)); + + if (task->task_data_destroy) + task->task_data_destroy (task->task_data); + + task->task_data = task_data; + task->task_data_destroy = task_data_destroy; + + TRACE (GIO_TASK_SET_TASK_DATA (task, task_data, task_data_destroy)); +} + +/** + * g_task_set_priority: + * @task: the #GTask + * @priority: the [priority][io-priority] of the request + * + * Sets @task's priority. If you do not call this, it will default to + * %G_PRIORITY_DEFAULT. + * + * This will affect the priority of #GSources created with + * g_task_attach_source() and the scheduling of tasks run in threads, + * and can also be explicitly retrieved later via + * g_task_get_priority(). + * + * Since: 2.36 + */ +void +g_task_set_priority (GTask *task, + gint priority) +{ + g_return_if_fail (G_IS_TASK (task)); + + task->priority = priority; + + TRACE (GIO_TASK_SET_PRIORITY (task, priority)); +} + +/** + * g_task_set_check_cancellable: + * @task: the #GTask + * @check_cancellable: whether #GTask will check the state of + * its #GCancellable for you. + * + * Sets or clears @task's check-cancellable flag. If this is %TRUE + * (the default), then g_task_propagate_pointer(), etc, and + * g_task_had_error() will check the task's #GCancellable first, and + * if it has been cancelled, then they will consider the task to have + * returned an "Operation was cancelled" error + * (%G_IO_ERROR_CANCELLED), regardless of any other error or return + * value the task may have had. + * + * If @check_cancellable is %FALSE, then the #GTask will not check the + * cancellable itself, and it is up to @task's owner to do this (eg, + * via g_task_return_error_if_cancelled()). + * + * If you are using g_task_set_return_on_cancel() as well, then + * you must leave check-cancellable set %TRUE. + * + * Since: 2.36 + */ +void +g_task_set_check_cancellable (GTask *task, + gboolean check_cancellable) +{ + g_return_if_fail (G_IS_TASK (task)); + g_return_if_fail (check_cancellable || !task->return_on_cancel); + + task->check_cancellable = check_cancellable; +} + +static void g_task_thread_complete (GTask *task); + +/** + * g_task_set_return_on_cancel: + * @task: the #GTask + * @return_on_cancel: whether the task returns automatically when + * it is cancelled. + * + * Sets or clears @task's return-on-cancel flag. This is only + * meaningful for tasks run via g_task_run_in_thread() or + * g_task_run_in_thread_sync(). + * + * If @return_on_cancel is %TRUE, then cancelling @task's + * #GCancellable will immediately cause it to return, as though the + * task's #GTaskThreadFunc had called + * g_task_return_error_if_cancelled() and then returned. + * + * This allows you to create a cancellable wrapper around an + * uninterruptible function. The #GTaskThreadFunc just needs to be + * careful that it does not modify any externally-visible state after + * it has been cancelled. To do that, the thread should call + * g_task_set_return_on_cancel() again to (atomically) set + * return-on-cancel %FALSE before making externally-visible changes; + * if the task gets cancelled before the return-on-cancel flag could + * be changed, g_task_set_return_on_cancel() will indicate this by + * returning %FALSE. + * + * You can disable and re-enable this flag multiple times if you wish. + * If the task's #GCancellable is cancelled while return-on-cancel is + * %FALSE, then calling g_task_set_return_on_cancel() to set it %TRUE + * again will cause the task to be cancelled at that point. + * + * If the task's #GCancellable is already cancelled before you call + * g_task_run_in_thread()/g_task_run_in_thread_sync(), then the + * #GTaskThreadFunc will still be run (for consistency), but the task + * will also be completed right away. + * + * Returns: %TRUE if @task's return-on-cancel flag was changed to + * match @return_on_cancel. %FALSE if @task has already been + * cancelled. + * + * Since: 2.36 + */ +gboolean +g_task_set_return_on_cancel (GTask *task, + gboolean return_on_cancel) +{ + g_return_val_if_fail (G_IS_TASK (task), FALSE); + g_return_val_if_fail (task->check_cancellable || !return_on_cancel, FALSE); + + if (!G_TASK_IS_THREADED (task)) + { + task->return_on_cancel = return_on_cancel; + return TRUE; + } + + g_mutex_lock (&task->lock); + if (task->thread_cancelled) + { + if (return_on_cancel && !task->return_on_cancel) + { + g_mutex_unlock (&task->lock); + g_task_thread_complete (task); + } + else + g_mutex_unlock (&task->lock); + return FALSE; + } + task->return_on_cancel = return_on_cancel; + g_mutex_unlock (&task->lock); + + return TRUE; +} + +/** + * g_task_set_source_tag: + * @task: the #GTask + * @source_tag: an opaque pointer indicating the source of this task + * + * Sets @task's source tag. + * + * You can use this to tag a task return + * value with a particular pointer (usually a pointer to the function + * doing the tagging) and then later check it using + * g_task_get_source_tag() (or g_async_result_is_tagged()) in the + * task's "finish" function, to figure out if the response came from a + * particular place. + * + * A macro wrapper around this function will automatically set the + * task’s name to the string form of @source_tag if it’s not already + * set, for convenience. + * + * Since: 2.36 + */ +void +(g_task_set_source_tag) (GTask *task, + gpointer source_tag) +{ + g_return_if_fail (G_IS_TASK (task)); + + task->source_tag = source_tag; + + TRACE (GIO_TASK_SET_SOURCE_TAG (task, source_tag)); +} + +/** + * g_task_set_name: + * @task: a #GTask + * @name: (nullable): a human readable name for the task, or %NULL to unset it + * + * Sets @task’s name, used in debugging and profiling. The name defaults to + * %NULL. + * + * The task name should describe in a human readable way what the task does. + * For example, ‘Open file’ or ‘Connect to network host’. It is used to set the + * name of the #GSource used for idle completion of the task. + * + * This function may only be called before the @task is first used in a thread + * other than the one it was constructed in. It is called automatically by + * g_task_set_source_tag() if not called already. + * + * Since: 2.60 + */ +void +g_task_set_name (GTask *task, + const gchar *name) +{ + gchar *new_name; + + g_return_if_fail (G_IS_TASK (task)); + + new_name = g_strdup (name); + g_free (task->name); + task->name = g_steal_pointer (&new_name); +} + +/** + * g_task_get_source_object: + * @task: a #GTask + * + * Gets the source object from @task. Like + * g_async_result_get_source_object(), but does not ref the object. + * + * Returns: (transfer none) (nullable) (type GObject): @task's source object, or %NULL + * + * Since: 2.36 + */ +gpointer +g_task_get_source_object (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), NULL); + + return task->source_object; +} + +static GObject * +g_task_ref_source_object (GAsyncResult *res) +{ + GTask *task = G_TASK (res); + + if (task->source_object) + return g_object_ref (task->source_object); + else + return NULL; +} + +/** + * g_task_get_task_data: + * @task: a #GTask + * + * Gets @task's `task_data`. + * + * Returns: (transfer none): @task's `task_data`. + * + * Since: 2.36 + */ +gpointer +g_task_get_task_data (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), NULL); + + return task->task_data; +} + +/** + * g_task_get_priority: + * @task: a #GTask + * + * Gets @task's priority + * + * Returns: @task's priority + * + * Since: 2.36 + */ +gint +g_task_get_priority (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), G_PRIORITY_DEFAULT); + + return task->priority; +} + +/** + * g_task_get_context: + * @task: a #GTask + * + * Gets the #GMainContext that @task will return its result in (that + * is, the context that was the + * [thread-default main context][g-main-context-push-thread-default] + * at the point when @task was created). + * + * This will always return a non-%NULL value, even if the task's + * context is the default #GMainContext. + * + * Returns: (transfer none): @task's #GMainContext + * + * Since: 2.36 + */ +GMainContext * +g_task_get_context (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), NULL); + + return task->context; +} + +/** + * g_task_get_cancellable: + * @task: a #GTask + * + * Gets @task's #GCancellable + * + * Returns: (transfer none): @task's #GCancellable + * + * Since: 2.36 + */ +GCancellable * +g_task_get_cancellable (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), NULL); + + return task->cancellable; +} + +/** + * g_task_get_check_cancellable: + * @task: the #GTask + * + * Gets @task's check-cancellable flag. See + * g_task_set_check_cancellable() for more details. + * + * Since: 2.36 + */ +gboolean +g_task_get_check_cancellable (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), FALSE); + + /* Convert from a bit field to a boolean. */ + return task->check_cancellable ? TRUE : FALSE; +} + +/** + * g_task_get_return_on_cancel: + * @task: the #GTask + * + * Gets @task's return-on-cancel flag. See + * g_task_set_return_on_cancel() for more details. + * + * Since: 2.36 + */ +gboolean +g_task_get_return_on_cancel (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), FALSE); + + /* Convert from a bit field to a boolean. */ + return task->return_on_cancel ? TRUE : FALSE; +} + +/** + * g_task_get_source_tag: + * @task: a #GTask + * + * Gets @task's source tag. See g_task_set_source_tag(). + * + * Returns: (transfer none): @task's source tag + * + * Since: 2.36 + */ +gpointer +g_task_get_source_tag (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), NULL); + + return task->source_tag; +} + +/** + * g_task_get_name: + * @task: a #GTask + * + * Gets @task’s name. See g_task_set_name(). + * + * Returns: (nullable) (transfer none): @task’s name, or %NULL + * Since: 2.60 + */ +const gchar * +g_task_get_name (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), NULL); + + return task->name; +} + +static void +g_task_return_now (GTask *task) +{ + TRACE (GIO_TASK_BEFORE_RETURN (task, task->source_object, task->callback, + task->callback_data)); + + g_main_context_push_thread_default (task->context); + + if (task->callback != NULL) + { + task->callback (task->source_object, + G_ASYNC_RESULT (task), + task->callback_data); + } + + task->completed = TRUE; + g_object_notify (G_OBJECT (task), "completed"); + + g_main_context_pop_thread_default (task->context); +} + +static gboolean +complete_in_idle_cb (gpointer task) +{ + g_task_return_now (task); + g_object_unref (task); + return FALSE; +} + +typedef enum { + G_TASK_RETURN_SUCCESS, + G_TASK_RETURN_ERROR, + G_TASK_RETURN_FROM_THREAD +} GTaskReturnType; + +static void +g_task_return (GTask *task, + GTaskReturnType type) +{ + GSource *source; + + if (type != G_TASK_RETURN_FROM_THREAD) + task->ever_returned = TRUE; + + if (type == G_TASK_RETURN_SUCCESS) + task->result_set = TRUE; + + if (task->synchronous) + return; + + /* Normally we want to invoke the task's callback when its return + * value is set. But if the task is running in a thread, then we + * want to wait until after the task_func returns, to simplify + * locking/refcounting/etc. + */ + if (G_TASK_IS_THREADED (task) && type != G_TASK_RETURN_FROM_THREAD) + return; + + g_object_ref (task); + + /* See if we can complete the task immediately. First, we have to be + * running inside the task's thread/GMainContext. + */ + source = g_main_current_source (); + if (source && g_source_get_context (source) == task->context) + { + /* Second, we can only complete immediately if this is not the + * same iteration of the main loop that the task was created in. + */ + if (g_source_get_time (source) > task->creation_time) + { + /* Finally, if the task has been cancelled, we shouldn't + * return synchronously from inside the + * GCancellable::cancelled handler. It's easier to run + * another iteration of the main loop than tracking how the + * cancellation was handled. + */ + if (!g_cancellable_is_cancelled (task->cancellable)) + { + g_task_return_now (task); + g_object_unref (task); + return; + } + } + } + + /* Otherwise, complete in the next iteration */ + source = g_idle_source_new (); + + /* Note: in case the task name is NULL we set it as a const string instead + * of going through the concat path which is more expensive and may show in the + * profiler if g_task_return is called very often + */ + if (task->name == NULL) + g_source_set_static_name (source, "[gio] (unnamed) complete_in_idle_cb"); + else + { + gchar *source_name; + + source_name = g_strconcat ("[gio] ", task->name, " complete_in_idle_cb", NULL); + g_source_set_name (source, source_name); + g_free (source_name); + } + + g_task_attach_source (task, source, complete_in_idle_cb); + g_source_unref (source); +} + + +/** + * GTaskThreadFunc: + * @task: the #GTask + * @source_object: (type GObject): @task's source object + * @task_data: @task's task data + * @cancellable: @task's #GCancellable, or %NULL + * + * The prototype for a task function to be run in a thread via + * g_task_run_in_thread() or g_task_run_in_thread_sync(). + * + * If the return-on-cancel flag is set on @task, and @cancellable gets + * cancelled, then the #GTask will be completed immediately (as though + * g_task_return_error_if_cancelled() had been called), without + * waiting for the task function to complete. However, the task + * function will continue running in its thread in the background. The + * function therefore needs to be careful about how it uses + * externally-visible state in this case. See + * g_task_set_return_on_cancel() for more details. + * + * Other than in that case, @task will be completed when the + * #GTaskThreadFunc returns, not when it calls a + * `g_task_return_` function. + * + * Since: 2.36 + */ + +static void task_thread_cancelled (GCancellable *cancellable, + gpointer user_data); + +static void +g_task_thread_complete (GTask *task) +{ + g_mutex_lock (&task->lock); + if (task->thread_complete) + { + /* The task belatedly completed after having been cancelled + * (or was cancelled in the midst of being completed). + */ + g_mutex_unlock (&task->lock); + return; + } + + TRACE (GIO_TASK_AFTER_RUN_IN_THREAD (task, task->thread_cancelled)); + + task->thread_complete = TRUE; + g_mutex_unlock (&task->lock); + + if (task->cancellable) + g_signal_handlers_disconnect_by_func (task->cancellable, task_thread_cancelled, task); + + if (task->synchronous) + g_cond_signal (&task->cond); + else + g_task_return (task, G_TASK_RETURN_FROM_THREAD); +} + +static gboolean +task_pool_manager_timeout (gpointer user_data) +{ + g_mutex_lock (&task_pool_mutex); + g_thread_pool_set_max_threads (task_pool, tasks_running + 1, NULL); + g_trace_set_int64_counter (task_pool_max_counter, tasks_running + 1); + g_source_set_ready_time (task_pool_manager, -1); + g_mutex_unlock (&task_pool_mutex); + + return TRUE; +} + +static void +g_task_thread_setup (void) +{ + g_private_set (&task_private, GUINT_TO_POINTER (TRUE)); + g_mutex_lock (&task_pool_mutex); + tasks_running++; + + g_trace_set_int64_counter (tasks_running_counter, tasks_running); + + if (tasks_running == G_TASK_POOL_SIZE) + task_wait_time = G_TASK_WAIT_TIME_BASE; + else if (tasks_running > G_TASK_POOL_SIZE && tasks_running < G_TASK_WAIT_TIME_MAX_POOL_SIZE) + task_wait_time *= G_TASK_WAIT_TIME_MULTIPLIER; + + if (tasks_running >= G_TASK_POOL_SIZE) + g_source_set_ready_time (task_pool_manager, g_get_monotonic_time () + task_wait_time); + + g_mutex_unlock (&task_pool_mutex); +} + +static void +g_task_thread_cleanup (void) +{ + gint tasks_pending; + + g_mutex_lock (&task_pool_mutex); + tasks_pending = g_thread_pool_unprocessed (task_pool); + + if (tasks_running > G_TASK_POOL_SIZE) + { + g_thread_pool_set_max_threads (task_pool, tasks_running - 1, NULL); + g_trace_set_int64_counter (task_pool_max_counter, tasks_running - 1); + } + else if (tasks_running + tasks_pending < G_TASK_POOL_SIZE) + g_source_set_ready_time (task_pool_manager, -1); + + if (tasks_running > G_TASK_POOL_SIZE && tasks_running < G_TASK_WAIT_TIME_MAX_POOL_SIZE) + task_wait_time /= G_TASK_WAIT_TIME_MULTIPLIER; + + tasks_running--; + + g_trace_set_int64_counter (tasks_running_counter, tasks_running); + + g_mutex_unlock (&task_pool_mutex); + g_private_set (&task_private, GUINT_TO_POINTER (FALSE)); +} + +static void +g_task_thread_pool_thread (gpointer thread_data, + gpointer pool_data) +{ + GTask *task = thread_data; + + g_task_thread_setup (); + + task->task_func (task, task->source_object, task->task_data, + task->cancellable); + g_task_thread_complete (task); + g_object_unref (task); + + g_task_thread_cleanup (); +} + +static void +task_thread_cancelled (GCancellable *cancellable, + gpointer user_data) +{ + GTask *task = user_data; + + /* Move this task to the front of the queue - no need for + * a complete resorting of the queue. + */ + g_thread_pool_move_to_front (task_pool, task); + + g_mutex_lock (&task->lock); + task->thread_cancelled = TRUE; + + if (!task->return_on_cancel) + { + g_mutex_unlock (&task->lock); + return; + } + + /* We don't actually set task->error; g_task_return_error() doesn't + * use a lock, and g_task_propagate_error() will call + * g_cancellable_set_error_if_cancelled() anyway. + */ + g_mutex_unlock (&task->lock); + g_task_thread_complete (task); +} + +static void +task_thread_cancelled_disconnect_notify (gpointer task, + GClosure *closure) +{ + g_object_unref (task); +} + +static void +g_task_start_task_thread (GTask *task, + GTaskThreadFunc task_func) +{ + g_mutex_init (&task->lock); + g_cond_init (&task->cond); + + g_mutex_lock (&task->lock); + + TRACE (GIO_TASK_BEFORE_RUN_IN_THREAD (task, task_func)); + + task->task_func = task_func; + + if (task->cancellable) + { + if (task->return_on_cancel && + g_cancellable_set_error_if_cancelled (task->cancellable, + &task->error)) + { + task->thread_cancelled = task->thread_complete = TRUE; + TRACE (GIO_TASK_AFTER_RUN_IN_THREAD (task, task->thread_cancelled)); + g_thread_pool_push (task_pool, g_object_ref (task), NULL); + return; + } + + /* This introduces a reference count loop between the GTask and + * GCancellable, but is necessary to avoid a race on finalising the GTask + * between task_thread_cancelled() (in one thread) and + * g_task_thread_complete() (in another). + * + * Accordingly, the signal handler *must* be removed once the task has + * completed. + */ + g_signal_connect_data (task->cancellable, "cancelled", + G_CALLBACK (task_thread_cancelled), + g_object_ref (task), + task_thread_cancelled_disconnect_notify, 0); + } + + if (g_private_get (&task_private)) + task->blocking_other_task = TRUE; + g_thread_pool_push (task_pool, g_object_ref (task), NULL); +} + +/** + * g_task_run_in_thread: + * @task: a #GTask + * @task_func: (scope async): a #GTaskThreadFunc + * + * Runs @task_func in another thread. When @task_func returns, @task's + * #GAsyncReadyCallback will be invoked in @task's #GMainContext. + * + * This takes a ref on @task until the task completes. + * + * See #GTaskThreadFunc for more details about how @task_func is handled. + * + * Although GLib currently rate-limits the tasks queued via + * g_task_run_in_thread(), you should not assume that it will always + * do this. If you have a very large number of tasks to run (several tens of + * tasks), but don't want them to all run at once, you should only queue a + * limited number of them (around ten) at a time. + * + * Since: 2.36 + */ +void +g_task_run_in_thread (GTask *task, + GTaskThreadFunc task_func) +{ + g_return_if_fail (G_IS_TASK (task)); + + g_object_ref (task); + g_task_start_task_thread (task, task_func); + + /* The task may already be cancelled, or g_thread_pool_push() may + * have failed. + */ + if (task->thread_complete) + { + g_mutex_unlock (&task->lock); + g_task_return (task, G_TASK_RETURN_FROM_THREAD); + } + else + g_mutex_unlock (&task->lock); + + g_object_unref (task); +} + +/** + * g_task_run_in_thread_sync: + * @task: a #GTask + * @task_func: (scope async): a #GTaskThreadFunc + * + * Runs @task_func in another thread, and waits for it to return or be + * cancelled. You can use g_task_propagate_pointer(), etc, afterward + * to get the result of @task_func. + * + * See #GTaskThreadFunc for more details about how @task_func is handled. + * + * Normally this is used with tasks created with a %NULL + * `callback`, but note that even if the task does + * have a callback, it will not be invoked when @task_func returns. + * #GTask:completed will be set to %TRUE just before this function returns. + * + * Although GLib currently rate-limits the tasks queued via + * g_task_run_in_thread_sync(), you should not assume that it will + * always do this. If you have a very large number of tasks to run, + * but don't want them to all run at once, you should only queue a + * limited number of them at a time. + * + * Since: 2.36 + */ +void +g_task_run_in_thread_sync (GTask *task, + GTaskThreadFunc task_func) +{ + g_return_if_fail (G_IS_TASK (task)); + + g_object_ref (task); + + task->synchronous = TRUE; + g_task_start_task_thread (task, task_func); + + while (!task->thread_complete) + g_cond_wait (&task->cond, &task->lock); + + g_mutex_unlock (&task->lock); + + TRACE (GIO_TASK_BEFORE_RETURN (task, task->source_object, + NULL /* callback */, + NULL /* callback data */)); + + /* Notify of completion in this thread. */ + task->completed = TRUE; + g_object_notify (G_OBJECT (task), "completed"); + + g_object_unref (task); +} + +/** + * g_task_attach_source: + * @task: a #GTask + * @source: the source to attach + * @callback: the callback to invoke when @source triggers + * + * A utility function for dealing with async operations where you need + * to wait for a #GSource to trigger. Attaches @source to @task's + * #GMainContext with @task's [priority][io-priority], and sets @source's + * callback to @callback, with @task as the callback's `user_data`. + * + * It will set the @source’s name to the task’s name (as set with + * g_task_set_name()), if one has been set. + * + * This takes a reference on @task until @source is destroyed. + * + * Since: 2.36 + */ +void +g_task_attach_source (GTask *task, + GSource *source, + GSourceFunc callback) +{ + g_return_if_fail (G_IS_TASK (task)); + + g_source_set_callback (source, callback, + g_object_ref (task), g_object_unref); + g_source_set_priority (source, task->priority); + if (task->name != NULL) + g_source_set_name (source, task->name); + + g_source_attach (source, task->context); +} + + +static gboolean +g_task_propagate_error (GTask *task, + GError **error) +{ + gboolean error_set; + + if (task->check_cancellable && + g_cancellable_set_error_if_cancelled (task->cancellable, error)) + error_set = TRUE; + else if (task->error) + { + g_propagate_error (error, task->error); + task->error = NULL; + task->had_error = TRUE; + error_set = TRUE; + } + else + error_set = FALSE; + + TRACE (GIO_TASK_PROPAGATE (task, error_set)); + + return error_set; +} + +/** + * g_task_return_pointer: + * @task: a #GTask + * @result: (nullable) (transfer full): the pointer result of a task + * function + * @result_destroy: (nullable): a #GDestroyNotify function. + * + * Sets @task's result to @result and completes the task. If @result + * is not %NULL, then @result_destroy will be used to free @result if + * the caller does not take ownership of it with + * g_task_propagate_pointer(). + * + * "Completes the task" means that for an ordinary asynchronous task + * it will either invoke the task's callback, or else queue that + * callback to be invoked in the proper #GMainContext, or in the next + * iteration of the current #GMainContext. For a task run via + * g_task_run_in_thread() or g_task_run_in_thread_sync(), calling this + * method will save @result to be returned to the caller later, but + * the task will not actually be completed until the #GTaskThreadFunc + * exits. + * + * Note that since the task may be completed before returning from + * g_task_return_pointer(), you cannot assume that @result is still + * valid after calling this, unless you are still holding another + * reference on it. + * + * Since: 2.36 + */ +void +g_task_return_pointer (GTask *task, + gpointer result, + GDestroyNotify result_destroy) +{ + g_return_if_fail (G_IS_TASK (task)); + g_return_if_fail (!task->ever_returned); + + task->result.pointer = result; + task->result_destroy = result_destroy; + + g_task_return (task, G_TASK_RETURN_SUCCESS); +} + +/** + * g_task_propagate_pointer: + * @task: a #GTask + * @error: return location for a #GError + * + * Gets the result of @task as a pointer, and transfers ownership + * of that value to the caller. + * + * If the task resulted in an error, or was cancelled, then this will + * instead return %NULL and set @error. + * + * Since this method transfers ownership of the return value (or + * error) to the caller, you may only call it once. + * + * Returns: (transfer full): the task result, or %NULL on error + * + * Since: 2.36 + */ +gpointer +g_task_propagate_pointer (GTask *task, + GError **error) +{ + g_return_val_if_fail (G_IS_TASK (task), NULL); + + if (g_task_propagate_error (task, error)) + return NULL; + + g_return_val_if_fail (task->result_set, NULL); + + task->result_destroy = NULL; + task->result_set = FALSE; + return task->result.pointer; +} + +/** + * g_task_return_int: + * @task: a #GTask. + * @result: the integer (#gssize) result of a task function. + * + * Sets @task's result to @result and completes the task (see + * g_task_return_pointer() for more discussion of exactly what this + * means). + * + * Since: 2.36 + */ +void +g_task_return_int (GTask *task, + gssize result) +{ + g_return_if_fail (G_IS_TASK (task)); + g_return_if_fail (!task->ever_returned); + + task->result.size = result; + + g_task_return (task, G_TASK_RETURN_SUCCESS); +} + +/** + * g_task_propagate_int: + * @task: a #GTask. + * @error: return location for a #GError + * + * Gets the result of @task as an integer (#gssize). + * + * If the task resulted in an error, or was cancelled, then this will + * instead return -1 and set @error. + * + * Since this method transfers ownership of the return value (or + * error) to the caller, you may only call it once. + * + * Returns: the task result, or -1 on error + * + * Since: 2.36 + */ +gssize +g_task_propagate_int (GTask *task, + GError **error) +{ + g_return_val_if_fail (G_IS_TASK (task), -1); + + if (g_task_propagate_error (task, error)) + return -1; + + g_return_val_if_fail (task->result_set, -1); + + task->result_set = FALSE; + return task->result.size; +} + +/** + * g_task_return_boolean: + * @task: a #GTask. + * @result: the #gboolean result of a task function. + * + * Sets @task's result to @result and completes the task (see + * g_task_return_pointer() for more discussion of exactly what this + * means). + * + * Since: 2.36 + */ +void +g_task_return_boolean (GTask *task, + gboolean result) +{ + g_return_if_fail (G_IS_TASK (task)); + g_return_if_fail (!task->ever_returned); + + task->result.boolean = result; + + g_task_return (task, G_TASK_RETURN_SUCCESS); +} + +/** + * g_task_propagate_boolean: + * @task: a #GTask. + * @error: return location for a #GError + * + * Gets the result of @task as a #gboolean. + * + * If the task resulted in an error, or was cancelled, then this will + * instead return %FALSE and set @error. + * + * Since this method transfers ownership of the return value (or + * error) to the caller, you may only call it once. + * + * Returns: the task result, or %FALSE on error + * + * Since: 2.36 + */ +gboolean +g_task_propagate_boolean (GTask *task, + GError **error) +{ + g_return_val_if_fail (G_IS_TASK (task), FALSE); + + if (g_task_propagate_error (task, error)) + return FALSE; + + g_return_val_if_fail (task->result_set, FALSE); + + task->result_set = FALSE; + return task->result.boolean; +} + +/** + * g_task_return_error: + * @task: a #GTask. + * @error: (transfer full): the #GError result of a task function. + * + * Sets @task's result to @error (which @task assumes ownership of) + * and completes the task (see g_task_return_pointer() for more + * discussion of exactly what this means). + * + * Note that since the task takes ownership of @error, and since the + * task may be completed before returning from g_task_return_error(), + * you cannot assume that @error is still valid after calling this. + * Call g_error_copy() on the error if you need to keep a local copy + * as well. + * + * See also g_task_return_new_error(). + * + * Since: 2.36 + */ +void +g_task_return_error (GTask *task, + GError *error) +{ + g_return_if_fail (G_IS_TASK (task)); + g_return_if_fail (!task->ever_returned); + g_return_if_fail (error != NULL); + + task->error = error; + + g_task_return (task, G_TASK_RETURN_ERROR); +} + +/** + * g_task_return_new_error: + * @task: a #GTask. + * @domain: a #GQuark. + * @code: an error code. + * @format: a string with format characters. + * @...: a list of values to insert into @format. + * + * Sets @task's result to a new #GError created from @domain, @code, + * @format, and the remaining arguments, and completes the task (see + * g_task_return_pointer() for more discussion of exactly what this + * means). + * + * See also g_task_return_error(). + * + * Since: 2.36 + */ +void +g_task_return_new_error (GTask *task, + GQuark domain, + gint code, + const char *format, + ...) +{ + GError *error; + va_list args; + + va_start (args, format); + error = g_error_new_valist (domain, code, format, args); + va_end (args); + + g_task_return_error (task, error); +} + +/** + * g_task_return_error_if_cancelled: + * @task: a #GTask + * + * Checks if @task's #GCancellable has been cancelled, and if so, sets + * @task's error accordingly and completes the task (see + * g_task_return_pointer() for more discussion of exactly what this + * means). + * + * Returns: %TRUE if @task has been cancelled, %FALSE if not + * + * Since: 2.36 + */ +gboolean +g_task_return_error_if_cancelled (GTask *task) +{ + GError *error = NULL; + + g_return_val_if_fail (G_IS_TASK (task), FALSE); + g_return_val_if_fail (!task->ever_returned, FALSE); + + if (g_cancellable_set_error_if_cancelled (task->cancellable, &error)) + { + /* We explicitly set task->error so this works even when + * check-cancellable is not set. + */ + g_clear_error (&task->error); + task->error = error; + + g_task_return (task, G_TASK_RETURN_ERROR); + return TRUE; + } + else + return FALSE; +} + +/** + * g_task_had_error: + * @task: a #GTask. + * + * Tests if @task resulted in an error. + * + * Returns: %TRUE if the task resulted in an error, %FALSE otherwise. + * + * Since: 2.36 + */ +gboolean +g_task_had_error (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), FALSE); + + if (task->error != NULL || task->had_error) + return TRUE; + + if (task->check_cancellable && g_cancellable_is_cancelled (task->cancellable)) + return TRUE; + + return FALSE; +} + +static void +value_free (gpointer value) +{ + g_value_unset (value); + g_free (value); +} + +/** + * g_task_return_value: + * @task: a #GTask + * @result: (nullable) (transfer none): the #GValue result of + * a task function + * + * Sets @task's result to @result (by copying it) and completes the task. + * + * If @result is %NULL then a #GValue of type %G_TYPE_POINTER + * with a value of %NULL will be used for the result. + * + * This is a very generic low-level method intended primarily for use + * by language bindings; for C code, g_task_return_pointer() and the + * like will normally be much easier to use. + * + * Since: 2.64 + */ +void +g_task_return_value (GTask *task, + GValue *result) +{ + GValue *value; + + g_return_if_fail (G_IS_TASK (task)); + g_return_if_fail (!task->ever_returned); + + value = g_new0 (GValue, 1); + + if (result == NULL) + { + g_value_init (value, G_TYPE_POINTER); + g_value_set_pointer (value, NULL); + } + else + { + g_value_init (value, G_VALUE_TYPE (result)); + g_value_copy (result, value); + } + + g_task_return_pointer (task, value, value_free); +} + +/** + * g_task_propagate_value: + * @task: a #GTask + * @value: (out caller-allocates): return location for the #GValue + * @error: return location for a #GError + * + * Gets the result of @task as a #GValue, and transfers ownership of + * that value to the caller. As with g_task_return_value(), this is + * a generic low-level method; g_task_propagate_pointer() and the like + * will usually be more useful for C code. + * + * If the task resulted in an error, or was cancelled, then this will + * instead set @error and return %FALSE. + * + * Since this method transfers ownership of the return value (or + * error) to the caller, you may only call it once. + * + * Returns: %TRUE if @task succeeded, %FALSE on error. + * + * Since: 2.64 + */ +gboolean +g_task_propagate_value (GTask *task, + GValue *value, + GError **error) +{ + g_return_val_if_fail (G_IS_TASK (task), FALSE); + g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (g_task_propagate_error (task, error)) + return FALSE; + + g_return_val_if_fail (task->result_set, FALSE); + g_return_val_if_fail (task->result_destroy == value_free, FALSE); + + memcpy (value, task->result.pointer, sizeof (GValue)); + g_free (task->result.pointer); + + task->result_destroy = NULL; + task->result_set = FALSE; + + return TRUE; +} + +/** + * g_task_get_completed: + * @task: a #GTask. + * + * Gets the value of #GTask:completed. This changes from %FALSE to %TRUE after + * the task’s callback is invoked, and will return %FALSE if called from inside + * the callback. + * + * Returns: %TRUE if the task has completed, %FALSE otherwise. + * + * Since: 2.44 + */ +gboolean +g_task_get_completed (GTask *task) +{ + g_return_val_if_fail (G_IS_TASK (task), FALSE); + + /* Convert from a bit field to a boolean. */ + return task->completed ? TRUE : FALSE; +} + +/** + * g_task_is_valid: + * @result: (type Gio.AsyncResult): A #GAsyncResult + * @source_object: (nullable) (type GObject): the source object + * expected to be associated with the task + * + * Checks that @result is a #GTask, and that @source_object is its + * source object (or that @source_object is %NULL and @result has no + * source object). This can be used in g_return_if_fail() checks. + * + * Returns: %TRUE if @result and @source_object are valid, %FALSE + * if not + * + * Since: 2.36 + */ +gboolean +g_task_is_valid (gpointer result, + gpointer source_object) +{ + if (!G_IS_TASK (result)) + return FALSE; + + return G_TASK (result)->source_object == source_object; +} + +static gint +g_task_compare_priority (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + const GTask *ta = a; + const GTask *tb = b; + gboolean a_cancelled, b_cancelled; + + /* Tasks that are causing other tasks to block have higher + * priority. + */ + if (ta->blocking_other_task && !tb->blocking_other_task) + return -1; + else if (tb->blocking_other_task && !ta->blocking_other_task) + return 1; + + /* Let already-cancelled tasks finish right away */ + a_cancelled = (ta->check_cancellable && + g_cancellable_is_cancelled (ta->cancellable)); + b_cancelled = (tb->check_cancellable && + g_cancellable_is_cancelled (tb->cancellable)); + if (a_cancelled && !b_cancelled) + return -1; + else if (b_cancelled && !a_cancelled) + return 1; + + /* Lower priority == run sooner == negative return value */ + return ta->priority - tb->priority; +} + +static gboolean +trivial_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + return callback (user_data); +} + +GSourceFuncs trivial_source_funcs = { + NULL, /* prepare */ + NULL, /* check */ + trivial_source_dispatch, + NULL, /* finalize */ + NULL, /* closure */ + NULL /* marshal */ +}; + +static void +g_task_thread_pool_init (void) +{ + task_pool = g_thread_pool_new (g_task_thread_pool_thread, NULL, + G_TASK_POOL_SIZE, FALSE, NULL); + g_assert (task_pool != NULL); + + g_thread_pool_set_sort_function (task_pool, g_task_compare_priority, NULL); + + task_pool_manager = g_source_new (&trivial_source_funcs, sizeof (GSource)); + g_source_set_static_name (task_pool_manager, "GTask thread pool manager"); + g_source_set_callback (task_pool_manager, task_pool_manager_timeout, NULL, NULL); + g_source_set_ready_time (task_pool_manager, -1); + g_source_attach (task_pool_manager, + GLIB_PRIVATE_CALL (g_get_worker_context ())); + g_source_unref (task_pool_manager); +} + +static void +g_task_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTask *task = G_TASK (object); + + switch ((GTaskProperty) prop_id) + { + case PROP_COMPLETED: + g_value_set_boolean (value, g_task_get_completed (task)); + break; + } +} + +static void +g_task_class_init (GTaskClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = g_task_get_property; + gobject_class->finalize = g_task_finalize; + + /** + * GTask:completed: + * + * Whether the task has completed, meaning its callback (if set) has been + * invoked. This can only happen after g_task_return_pointer(), + * g_task_return_error() or one of the other return functions have been called + * on the task. + * + * This property is guaranteed to change from %FALSE to %TRUE exactly once. + * + * The #GObject::notify signal for this change is emitted in the same main + * context as the task’s callback, immediately after that callback is invoked. + * + * Since: 2.44 + */ + g_object_class_install_property (gobject_class, PROP_COMPLETED, + g_param_spec_boolean ("completed", + P_("Task completed"), + P_("Whether the task has completed yet"), + FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + if (G_UNLIKELY (task_pool_max_counter == 0)) + { + /* We use two counters to track characteristics of the GTask thread pool. + * task pool max size - the value of g_thread_pool_set_max_threads() + * tasks running - the number of running threads + */ + task_pool_max_counter = g_trace_define_int64_counter ("GIO", "task pool max size", "Maximum number of threads allowed in the GTask thread pool; see g_thread_pool_set_max_threads()"); + tasks_running_counter = g_trace_define_int64_counter ("GIO", "tasks running", "Number of currently running tasks in the GTask thread pool"); + } +} + +static gpointer +g_task_get_user_data (GAsyncResult *res) +{ + return G_TASK (res)->callback_data; +} + +static gboolean +g_task_is_tagged (GAsyncResult *res, + gpointer source_tag) +{ + return G_TASK (res)->source_tag == source_tag; +} + +static void +g_task_async_result_iface_init (GAsyncResultIface *iface) +{ + iface->get_user_data = g_task_get_user_data; + iface->get_source_object = g_task_ref_source_object; + iface->is_tagged = g_task_is_tagged; +} diff --git a/gio/gtask.h b/gio/gtask.h new file mode 100644 index 0000000..bc6454a --- /dev/null +++ b/gio/gtask.h @@ -0,0 +1,182 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_TASK_H__ +#define __G_TASK_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TASK (g_task_get_type ()) +#define G_TASK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TASK, GTask)) +#define G_TASK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TASK, GTaskClass)) +#define G_IS_TASK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TASK)) +#define G_IS_TASK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TASK)) +#define G_TASK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TASK, GTaskClass)) + +typedef struct _GTaskClass GTaskClass; + +GLIB_AVAILABLE_IN_2_36 +GType g_task_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_36 +GTask *g_task_new (gpointer source_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer callback_data); + +GLIB_AVAILABLE_IN_2_36 +void g_task_report_error (gpointer source_object, + GAsyncReadyCallback callback, + gpointer callback_data, + gpointer source_tag, + GError *error); +GLIB_AVAILABLE_IN_2_36 +void g_task_report_new_error (gpointer source_object, + GAsyncReadyCallback callback, + gpointer callback_data, + gpointer source_tag, + GQuark domain, + gint code, + const char *format, + ...) G_GNUC_PRINTF(7, 8); + +GLIB_AVAILABLE_IN_2_36 +void g_task_set_task_data (GTask *task, + gpointer task_data, + GDestroyNotify task_data_destroy); +GLIB_AVAILABLE_IN_2_36 +void g_task_set_priority (GTask *task, + gint priority); +GLIB_AVAILABLE_IN_2_36 +void g_task_set_check_cancellable (GTask *task, + gboolean check_cancellable); +GLIB_AVAILABLE_IN_2_36 +void g_task_set_source_tag (GTask *task, + gpointer source_tag); +GLIB_AVAILABLE_IN_2_60 +void g_task_set_name (GTask *task, + const gchar *name); + +/* Macro wrapper to set the task name when setting the source tag. */ +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_60 +#define g_task_set_source_tag(task, tag) G_STMT_START { \ + GTask *_task = (task); \ + (g_task_set_source_tag) (_task, tag); \ + if (g_task_get_name (_task) == NULL) \ + g_task_set_name (_task, G_STRINGIFY (tag)); \ +} G_STMT_END +#endif + +GLIB_AVAILABLE_IN_2_36 +gpointer g_task_get_source_object (GTask *task); +GLIB_AVAILABLE_IN_2_36 +gpointer g_task_get_task_data (GTask *task); +GLIB_AVAILABLE_IN_2_36 +gint g_task_get_priority (GTask *task); +GLIB_AVAILABLE_IN_2_36 +GMainContext *g_task_get_context (GTask *task); +GLIB_AVAILABLE_IN_2_36 +GCancellable *g_task_get_cancellable (GTask *task); +GLIB_AVAILABLE_IN_2_36 +gboolean g_task_get_check_cancellable (GTask *task); +GLIB_AVAILABLE_IN_2_36 +gpointer g_task_get_source_tag (GTask *task); +GLIB_AVAILABLE_IN_2_60 +const gchar *g_task_get_name (GTask *task); + +GLIB_AVAILABLE_IN_2_36 +gboolean g_task_is_valid (gpointer result, + gpointer source_object); + + +typedef void (*GTaskThreadFunc) (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable); +GLIB_AVAILABLE_IN_2_36 +void g_task_run_in_thread (GTask *task, + GTaskThreadFunc task_func); +GLIB_AVAILABLE_IN_2_36 +void g_task_run_in_thread_sync (GTask *task, + GTaskThreadFunc task_func); +GLIB_AVAILABLE_IN_2_36 +gboolean g_task_set_return_on_cancel (GTask *task, + gboolean return_on_cancel); +GLIB_AVAILABLE_IN_2_36 +gboolean g_task_get_return_on_cancel (GTask *task); + +GLIB_AVAILABLE_IN_2_36 +void g_task_attach_source (GTask *task, + GSource *source, + GSourceFunc callback); + + +GLIB_AVAILABLE_IN_2_36 +void g_task_return_pointer (GTask *task, + gpointer result, + GDestroyNotify result_destroy); +GLIB_AVAILABLE_IN_2_36 +void g_task_return_boolean (GTask *task, + gboolean result); +GLIB_AVAILABLE_IN_2_36 +void g_task_return_int (GTask *task, + gssize result); + +GLIB_AVAILABLE_IN_2_36 +void g_task_return_error (GTask *task, + GError *error); +GLIB_AVAILABLE_IN_2_36 +void g_task_return_new_error (GTask *task, + GQuark domain, + gint code, + const char *format, + ...) G_GNUC_PRINTF (4, 5); +GLIB_AVAILABLE_IN_2_64 +void g_task_return_value (GTask *task, + GValue *result); + +GLIB_AVAILABLE_IN_2_36 +gboolean g_task_return_error_if_cancelled (GTask *task); + +GLIB_AVAILABLE_IN_2_36 +gpointer g_task_propagate_pointer (GTask *task, + GError **error); +GLIB_AVAILABLE_IN_2_36 +gboolean g_task_propagate_boolean (GTask *task, + GError **error); +GLIB_AVAILABLE_IN_2_36 +gssize g_task_propagate_int (GTask *task, + GError **error); +GLIB_AVAILABLE_IN_2_64 +gboolean g_task_propagate_value (GTask *task, + GValue *value, + GError **error); +GLIB_AVAILABLE_IN_2_36 +gboolean g_task_had_error (GTask *task); +GLIB_AVAILABLE_IN_2_44 +gboolean g_task_get_completed (GTask *task); + +G_END_DECLS + +#endif /* __G_TASK_H__ */ diff --git a/gio/gtcpconnection.c b/gio/gtcpconnection.c new file mode 100644 index 0000000..68ed1e1 --- /dev/null +++ b/gio/gtcpconnection.c @@ -0,0 +1,332 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008, 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +/** + * SECTION:gtcpconnection + * @title: GTcpConnection + * @short_description: A TCP GSocketConnection + * @include: gio/gio.h + * @see_also: #GSocketConnection. + * + * This is the subclass of #GSocketConnection that is created + * for TCP/IP sockets. + * + * Since: 2.22 + */ + +#include "config.h" +#include "gtcpconnection.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "giostream.h" +#include "glibintl.h" + +struct _GTcpConnectionPrivate +{ + guint graceful_disconnect : 1; +}; + +G_DEFINE_TYPE_WITH_CODE (GTcpConnection, g_tcp_connection, + G_TYPE_SOCKET_CONNECTION, + G_ADD_PRIVATE (GTcpConnection) + g_socket_connection_factory_register_type (g_define_type_id, + G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT); + g_socket_connection_factory_register_type (g_define_type_id, + G_SOCKET_FAMILY_IPV6, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT); + g_socket_connection_factory_register_type (g_define_type_id, + G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP); + g_socket_connection_factory_register_type (g_define_type_id, + G_SOCKET_FAMILY_IPV6, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP); + ); + +static gboolean g_tcp_connection_close (GIOStream *stream, + GCancellable *cancellable, + GError **error); +static void g_tcp_connection_close_async (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + +enum +{ + PROP_0, + PROP_GRACEFUL_DISCONNECT +}; + +static void +g_tcp_connection_init (GTcpConnection *connection) +{ + connection->priv = g_tcp_connection_get_instance_private (connection); + connection->priv->graceful_disconnect = FALSE; +} + +static void +g_tcp_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTcpConnection *connection = G_TCP_CONNECTION (object); + + switch (prop_id) + { + case PROP_GRACEFUL_DISCONNECT: + g_value_set_boolean (value, connection->priv->graceful_disconnect); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_tcp_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTcpConnection *connection = G_TCP_CONNECTION (object); + + switch (prop_id) + { + case PROP_GRACEFUL_DISCONNECT: + g_tcp_connection_set_graceful_disconnect (connection, + g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_tcp_connection_class_init (GTcpConnectionClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + GIOStreamClass *stream_class = G_IO_STREAM_CLASS (class); + + gobject_class->set_property = g_tcp_connection_set_property; + gobject_class->get_property = g_tcp_connection_get_property; + + stream_class->close_fn = g_tcp_connection_close; + stream_class->close_async = g_tcp_connection_close_async; + + g_object_class_install_property (gobject_class, PROP_GRACEFUL_DISCONNECT, + g_param_spec_boolean ("graceful-disconnect", + P_("Graceful Disconnect"), + P_("Whether or not close does a graceful disconnect"), + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + +} + +static gboolean +g_tcp_connection_close (GIOStream *stream, + GCancellable *cancellable, + GError **error) +{ + GTcpConnection *connection = G_TCP_CONNECTION (stream); + GSocket *socket; + char buffer[1024]; + gssize ret; + gboolean had_error; + + socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream)); + had_error = FALSE; + + if (connection->priv->graceful_disconnect && + !g_cancellable_is_cancelled (cancellable) /* Cancelled -> close fast */) + { + if (!g_socket_shutdown (socket, FALSE, TRUE, error)) + { + error = NULL; /* Ignore further errors */ + had_error = TRUE; + } + else + { + while (TRUE) + { + ret = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer), + TRUE, cancellable, error); + if (ret < 0) + { + had_error = TRUE; + error = NULL; + break; + } + if (ret == 0) + break; + } + } + } + + return G_IO_STREAM_CLASS (g_tcp_connection_parent_class) + ->close_fn (stream, cancellable, error) && !had_error; +} + +/* consumes @error */ +static void +async_close_finish (GTask *task, + GError *error) +{ + GIOStreamClass *parent = G_IO_STREAM_CLASS (g_tcp_connection_parent_class); + GIOStream *stream = g_task_get_source_object (task); + GCancellable *cancellable = g_task_get_cancellable (task); + + /* Close underlying stream, ignoring further errors if we already + * have one. + */ + if (error) + parent->close_fn (stream, cancellable, NULL); + else + parent->close_fn (stream, cancellable, &error); + + if (error) + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); +} + + +static gboolean +close_read_ready (GSocket *socket, + GIOCondition condition, + GTask *task) +{ + GError *error = NULL; + char buffer[1024]; + gssize ret; + + ret = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer), + FALSE, g_task_get_cancellable (task), + &error); + if (ret < 0) + { + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) + { + g_error_free (error); + return TRUE; + } + else + { + async_close_finish (task, error); + g_object_unref (task); + return FALSE; + } + } + + if (ret == 0) + { + async_close_finish (task, NULL); + return FALSE; + } + + return TRUE; +} + + +static void +g_tcp_connection_close_async (GIOStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTcpConnection *connection = G_TCP_CONNECTION (stream); + GSocket *socket; + GSource *source; + GError *error; + GTask *task; + + if (connection->priv->graceful_disconnect && + !g_cancellable_is_cancelled (cancellable) /* Cancelled -> close fast */) + { + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, g_tcp_connection_close_async); + g_task_set_priority (task, io_priority); + + socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream)); + + error = NULL; + if (!g_socket_shutdown (socket, FALSE, TRUE, &error)) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + source = g_socket_create_source (socket, G_IO_IN, cancellable); + g_task_attach_source (task, source, (GSourceFunc) close_read_ready); + g_source_unref (source); + + return; + } + + G_IO_STREAM_CLASS (g_tcp_connection_parent_class) + ->close_async (stream, io_priority, cancellable, callback, user_data); +} + +/** + * g_tcp_connection_set_graceful_disconnect: + * @connection: a #GTcpConnection + * @graceful_disconnect: Whether to do graceful disconnects or not + * + * This enables graceful disconnects on close. A graceful disconnect + * means that we signal the receiving end that the connection is terminated + * and wait for it to close the connection before closing the connection. + * + * A graceful disconnect means that we can be sure that we successfully sent + * all the outstanding data to the other end, or get an error reported. + * However, it also means we have to wait for all the data to reach the + * other side and for it to acknowledge this by closing the socket, which may + * take a while. For this reason it is disabled by default. + * + * Since: 2.22 + */ +void +g_tcp_connection_set_graceful_disconnect (GTcpConnection *connection, + gboolean graceful_disconnect) +{ + graceful_disconnect = !!graceful_disconnect; + if (graceful_disconnect != connection->priv->graceful_disconnect) + { + connection->priv->graceful_disconnect = graceful_disconnect; + g_object_notify (G_OBJECT (connection), "graceful-disconnect"); + } +} + +/** + * g_tcp_connection_get_graceful_disconnect: + * @connection: a #GTcpConnection + * + * Checks if graceful disconnects are used. See + * g_tcp_connection_set_graceful_disconnect(). + * + * Returns: %TRUE if graceful disconnect is used on close, %FALSE otherwise + * + * Since: 2.22 + */ +gboolean +g_tcp_connection_get_graceful_disconnect (GTcpConnection *connection) +{ + return connection->priv->graceful_disconnect; +} diff --git a/gio/gtcpconnection.h b/gio/gtcpconnection.h new file mode 100644 index 0000000..39645f9 --- /dev/null +++ b/gio/gtcpconnection.h @@ -0,0 +1,69 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2008, 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_TCP_CONNECTION_H__ +#define __G_TCP_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TCP_CONNECTION (g_tcp_connection_get_type ()) +#define G_TCP_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_TCP_CONNECTION, GTcpConnection)) +#define G_TCP_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_TCP_CONNECTION, GTcpConnectionClass)) +#define G_IS_TCP_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_TCP_CONNECTION)) +#define G_IS_TCP_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_TCP_CONNECTION)) +#define G_TCP_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_TCP_CONNECTION, GTcpConnectionClass)) + +typedef struct _GTcpConnectionPrivate GTcpConnectionPrivate; +typedef struct _GTcpConnectionClass GTcpConnectionClass; + +struct _GTcpConnectionClass +{ + GSocketConnectionClass parent_class; +}; + +struct _GTcpConnection +{ + GSocketConnection parent_instance; + GTcpConnectionPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tcp_connection_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +void g_tcp_connection_set_graceful_disconnect (GTcpConnection *connection, + gboolean graceful_disconnect); +GLIB_AVAILABLE_IN_ALL +gboolean g_tcp_connection_get_graceful_disconnect (GTcpConnection *connection); + +G_END_DECLS + +#endif /* __G_TCP_CONNECTION_H__ */ diff --git a/gio/gtcpwrapperconnection.c b/gio/gtcpwrapperconnection.c new file mode 100644 index 0000000..7c3bf69 --- /dev/null +++ b/gio/gtcpwrapperconnection.c @@ -0,0 +1,201 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Nicolas Dufresne + */ + +/** + * SECTION:gtcpwrapperconnection + * @title: GTcpWrapperConnection + * @short_description: Wrapper for non-GSocketConnection-based, + * GSocket-based GIOStreams + * @include: gio/gio.h + * @see_also: #GSocketConnection. + * + * A #GTcpWrapperConnection can be used to wrap a #GIOStream that is + * based on a #GSocket, but which is not actually a + * #GSocketConnection. This is used by #GSocketClient so that it can + * always return a #GSocketConnection, even when the connection it has + * actually created is not directly a #GSocketConnection. + * + * Since: 2.28 + */ + +/** + * GTcpWrapperConnection: + * + * #GTcpWrapperConnection is an opaque data structure and can only be accessed + * using the following functions. + **/ + +#include "config.h" + +#include "gtcpwrapperconnection.h" + +#include "gtcpconnection.h" +#include "glibintl.h" + +struct _GTcpWrapperConnectionPrivate +{ + GIOStream *base_io_stream; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GTcpWrapperConnection, g_tcp_wrapper_connection, G_TYPE_TCP_CONNECTION) + +enum +{ + PROP_NONE, + PROP_BASE_IO_STREAM +}; + +static GInputStream * +g_tcp_wrapper_connection_get_input_stream (GIOStream *io_stream) +{ + GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (io_stream); + + return g_io_stream_get_input_stream (connection->priv->base_io_stream); +} + +static GOutputStream * +g_tcp_wrapper_connection_get_output_stream (GIOStream *io_stream) +{ + GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (io_stream); + + return g_io_stream_get_output_stream (connection->priv->base_io_stream); +} + +static void +g_tcp_wrapper_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (object); + + switch (prop_id) + { + case PROP_BASE_IO_STREAM: + g_value_set_object (value, connection->priv->base_io_stream); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_tcp_wrapper_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (object); + + switch (prop_id) + { + case PROP_BASE_IO_STREAM: + connection->priv->base_io_stream = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_tcp_wrapper_connection_finalize (GObject *object) +{ + GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (object); + + if (connection->priv->base_io_stream) + g_object_unref (connection->priv->base_io_stream); + + G_OBJECT_CLASS (g_tcp_wrapper_connection_parent_class)->finalize (object); +} + +static void +g_tcp_wrapper_connection_class_init (GTcpWrapperConnectionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass); + + gobject_class->set_property = g_tcp_wrapper_connection_set_property; + gobject_class->get_property = g_tcp_wrapper_connection_get_property; + gobject_class->finalize = g_tcp_wrapper_connection_finalize; + + stream_class->get_input_stream = g_tcp_wrapper_connection_get_input_stream; + stream_class->get_output_stream = g_tcp_wrapper_connection_get_output_stream; + + g_object_class_install_property (gobject_class, + PROP_BASE_IO_STREAM, + g_param_spec_object ("base-io-stream", + P_("Base IO Stream"), + P_("The wrapped GIOStream"), + G_TYPE_IO_STREAM, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_tcp_wrapper_connection_init (GTcpWrapperConnection *connection) +{ + connection->priv = g_tcp_wrapper_connection_get_instance_private (connection); +} + +/** + * g_tcp_wrapper_connection_new: + * @base_io_stream: the #GIOStream to wrap + * @socket: the #GSocket associated with @base_io_stream + * + * Wraps @base_io_stream and @socket together as a #GSocketConnection. + * + * Returns: the new #GSocketConnection. + * + * Since: 2.28 + */ +GSocketConnection * +g_tcp_wrapper_connection_new (GIOStream *base_io_stream, + GSocket *socket) +{ + g_return_val_if_fail (G_IS_IO_STREAM (base_io_stream), NULL); + g_return_val_if_fail (G_IS_SOCKET (socket), NULL); + g_return_val_if_fail (g_socket_get_family (socket) == G_SOCKET_FAMILY_IPV4 || + g_socket_get_family (socket) == G_SOCKET_FAMILY_IPV6, NULL); + g_return_val_if_fail (g_socket_get_socket_type (socket) == G_SOCKET_TYPE_STREAM, NULL); + + return g_object_new (G_TYPE_TCP_WRAPPER_CONNECTION, + "base-io-stream", base_io_stream, + "socket", socket, + NULL); +} + +/** + * g_tcp_wrapper_connection_get_base_io_stream: + * @conn: a #GTcpWrapperConnection + * + * Gets @conn's base #GIOStream + * + * Returns: (transfer none): @conn's base #GIOStream + */ +GIOStream * +g_tcp_wrapper_connection_get_base_io_stream (GTcpWrapperConnection *conn) +{ + g_return_val_if_fail (G_IS_TCP_WRAPPER_CONNECTION (conn), NULL); + + return conn->priv->base_io_stream; +} diff --git a/gio/gtcpwrapperconnection.h b/gio/gtcpwrapperconnection.h new file mode 100644 index 0000000..a32acad --- /dev/null +++ b/gio/gtcpwrapperconnection.h @@ -0,0 +1,69 @@ +/* GIO - GLib Input, Output and Streaming Library + * Copyright © 2010 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Nicolas Dufresne + * + */ + +#ifndef __G_TCP_WRAPPER_CONNECTION_H__ +#define __G_TCP_WRAPPER_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TCP_WRAPPER_CONNECTION (g_tcp_wrapper_connection_get_type ()) +#define G_TCP_WRAPPER_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_TCP_WRAPPER_CONNECTION, GTcpWrapperConnection)) +#define G_TCP_WRAPPER_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_TCP_WRAPPER_CONNECTION, GTcpWrapperConnectionClass)) +#define G_IS_TCP_WRAPPER_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_TCP_WRAPPER_CONNECTION)) +#define G_IS_TCP_WRAPPER_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_TCP_WRAPPER_CONNECTION)) +#define G_TCP_WRAPPER_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_TCP_WRAPPER_CONNECTION, GTcpWrapperConnectionClass)) + +typedef struct _GTcpWrapperConnectionPrivate GTcpWrapperConnectionPrivate; +typedef struct _GTcpWrapperConnectionClass GTcpWrapperConnectionClass; + +struct _GTcpWrapperConnectionClass +{ + GTcpConnectionClass parent_class; +}; + +struct _GTcpWrapperConnection +{ + GTcpConnection parent_instance; + GTcpWrapperConnectionPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tcp_wrapper_connection_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketConnection *g_tcp_wrapper_connection_new (GIOStream *base_io_stream, + GSocket *socket); +GLIB_AVAILABLE_IN_ALL +GIOStream *g_tcp_wrapper_connection_get_base_io_stream (GTcpWrapperConnection *conn); + +G_END_DECLS + +#endif /* __G_TCP_WRAPPER_CONNECTION_H__ */ diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c new file mode 100644 index 0000000..992d29c --- /dev/null +++ b/gio/gtestdbus.c @@ -0,0 +1,894 @@ +/* GIO testing utilities + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * Copyright (C) 2012 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: David Zeuthen + * Xavier Claessens + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include +#include +#include +#endif + +#include + +#include "gdbusconnection.h" +#include "gdbusprivate.h" +#include "gfile.h" +#include "gioenumtypes.h" +#include "gtestdbus.h" + +#include "glibintl.h" + +#ifdef G_OS_UNIX +#include "glib-unix.h" +#endif + +/* -------------------------------------------------------------------------- */ +/* Utility: Wait until object has a single ref */ + +typedef struct +{ + GMainLoop *loop; + gboolean timed_out; +} WeakNotifyData; + +static gboolean +on_weak_notify_timeout (gpointer user_data) +{ + WeakNotifyData *data = user_data; + data->timed_out = TRUE; + g_main_loop_quit (data->loop); + return FALSE; +} + +static gboolean +unref_on_idle (gpointer object) +{ + g_object_unref (object); + return FALSE; +} + +static gboolean +_g_object_unref_and_wait_weak_notify (gpointer object) +{ + WeakNotifyData data; + guint timeout_id; + + data.loop = g_main_loop_new (NULL, FALSE); + data.timed_out = FALSE; + + g_object_weak_ref (object, (GWeakNotify) g_main_loop_quit, data.loop); + + /* Drop the strong ref held by the caller in an idle callback. This is to + * make sure the mainloop is already running when weak notify happens (when + * all other strong ref holders have dropped theirs). */ + g_idle_add (unref_on_idle, object); + + /* Make sure we don't block forever */ + timeout_id = g_timeout_add (30 * 1000, on_weak_notify_timeout, &data); + + g_main_loop_run (data.loop); + + if (data.timed_out) + { + g_warning ("Weak notify timeout, object ref_count=%d", + G_OBJECT (object)->ref_count); + } + else + { + g_source_remove (timeout_id); + } + + g_main_loop_unref (data.loop); + return data.timed_out; +} + +/* -------------------------------------------------------------------------- */ +/* Utilities to cleanup the mess in the case unit test process crash */ + +#ifdef G_OS_WIN32 + +/* This could be interesting to expose in public API */ +static void +_g_test_watcher_add_pid (GPid pid) +{ + static gsize started = 0; + HANDLE job; + + if (g_once_init_enter (&started)) + { + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + + job = CreateJobObjectW (NULL, NULL); + memset (&info, 0, sizeof (info)); + info.BasicLimitInformation.LimitFlags = 0x2000 /* JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE */; + + if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &info, sizeof (info))) + g_warning ("Can't enable JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: %s", g_win32_error_message (GetLastError())); + + g_once_init_leave (&started,(gsize)job); + } + + job = (HANDLE)started; + + if (!AssignProcessToJobObject(job, pid)) + g_warning ("Can't assign process to job: %s", g_win32_error_message (GetLastError())); +} + +static void +_g_test_watcher_remove_pid (GPid pid) +{ + /* No need to unassign the process from the job object as the process + will be killed anyway */ +} + +#else + +#define ADD_PID_FORMAT "add pid %d\n" +#define REMOVE_PID_FORMAT "remove pid %d\n" + +static void +watch_parent (gint fd) +{ + GIOChannel *channel; + GPollFD fds[1]; + GArray *pids_to_kill; + + channel = g_io_channel_unix_new (fd); + + fds[0].fd = fd; + fds[0].events = G_IO_HUP | G_IO_IN; + fds[0].revents = 0; + + pids_to_kill = g_array_new (FALSE, FALSE, sizeof (guint)); + + do + { + gint num_events; + gchar *command = NULL; + guint pid; + guint n; + GError *error = NULL; + + num_events = g_poll (fds, 1, -1); + if (num_events == 0) + continue; + + if (fds[0].revents & G_IO_HUP) + { + /* Parent quit, cleanup the mess and exit */ + for (n = 0; n < pids_to_kill->len; n++) + { + pid = g_array_index (pids_to_kill, guint, n); + g_printerr ("cleaning up pid %d\n", pid); + kill (pid, SIGTERM); + } + + g_array_unref (pids_to_kill); + g_io_channel_shutdown (channel, FALSE, &error); + g_assert_no_error (error); + g_io_channel_unref (channel); + + exit (0); + } + + /* Read the command from the input */ + g_io_channel_read_line (channel, &command, NULL, NULL, &error); + g_assert_no_error (error); + + /* Check for known commands */ + if (sscanf (command, ADD_PID_FORMAT, &pid) == 1) + { + g_array_append_val (pids_to_kill, pid); + } + else if (sscanf (command, REMOVE_PID_FORMAT, &pid) == 1) + { + for (n = 0; n < pids_to_kill->len; n++) + { + if (g_array_index (pids_to_kill, guint, n) == pid) + { + g_array_remove_index (pids_to_kill, n); + pid = 0; + break; + } + } + if (pid != 0) + { + g_warning ("unknown pid %d to remove", pid); + } + } + else + { + g_warning ("unknown command from parent '%s'", command); + } + + g_free (command); + } + while (TRUE); +} + +static GIOChannel * +watcher_init (void) +{ + static gsize started = 0; + static GIOChannel *channel = NULL; + int errsv; + + if (g_once_init_enter (&started)) + { + gint pipe_fds[2]; + + /* fork a child to clean up when we are killed */ + if (pipe (pipe_fds) != 0) + { + errsv = errno; + g_warning ("pipe() failed: %s", g_strerror (errsv)); + g_assert_not_reached (); + } + + /* flush streams to avoid buffers being duplicated in the child and + * flushed by both the child and parent later + * + * FIXME: This is a workaround for the fact that watch_parent() uses + * non-async-signal-safe API. See + * https://gitlab.gnome.org/GNOME/glib/-/issues/2322#note_1034330 + */ + fflush (stdout); + fflush (stderr); + + switch (fork ()) + { + case -1: + errsv = errno; + g_warning ("fork() failed: %s", g_strerror (errsv)); + g_assert_not_reached (); + break; + + case 0: + /* child */ + close (pipe_fds[1]); + watch_parent (pipe_fds[0]); + break; + + default: + /* parent */ + close (pipe_fds[0]); + channel = g_io_channel_unix_new (pipe_fds[1]); + } + + g_once_init_leave (&started, 1); + } + + return channel; +} + +static void +watcher_send_command (const gchar *command) +{ + GIOChannel *channel; + GError *error = NULL; + GIOStatus status; + + channel = watcher_init (); + + do + status = g_io_channel_write_chars (channel, command, -1, NULL, &error); + while (status == G_IO_STATUS_AGAIN); + g_assert_no_error (error); + + g_io_channel_flush (channel, &error); + g_assert_no_error (error); +} + +/* This could be interesting to expose in public API */ +static void +_g_test_watcher_add_pid (GPid pid) +{ + gchar *command; + + command = g_strdup_printf (ADD_PID_FORMAT, (guint) pid); + watcher_send_command (command); + g_free (command); +} + +static void +_g_test_watcher_remove_pid (GPid pid) +{ + gchar *command; + + command = g_strdup_printf (REMOVE_PID_FORMAT, (guint) pid); + watcher_send_command (command); + g_free (command); +} + +#endif + +/* -------------------------------------------------------------------------- */ +/* GTestDBus object implementation */ + +/** + * SECTION:gtestdbus + * @short_description: D-Bus testing helper + * @include: gio/gio.h + * + * A helper class for testing code which uses D-Bus without touching the user's + * session bus. + * + * Note that #GTestDBus modifies the user’s environment, calling setenv(). + * This is not thread-safe, so all #GTestDBus calls should be completed before + * threads are spawned, or should have appropriate locking to ensure no access + * conflicts to environment variables shared between #GTestDBus and other + * threads. + * + * ## Creating unit tests using GTestDBus + * + * Testing of D-Bus services can be tricky because normally we only ever run + * D-Bus services over an existing instance of the D-Bus daemon thus we + * usually don't activate D-Bus services that are not yet installed into the + * target system. The #GTestDBus object makes this easier for us by taking care + * of the lower level tasks such as running a private D-Bus daemon and looking + * up uninstalled services in customizable locations, typically in your source + * code tree. + * + * The first thing you will need is a separate service description file for the + * D-Bus daemon. Typically a `services` subdirectory of your `tests` directory + * is a good place to put this file. + * + * The service file should list your service along with an absolute path to the + * uninstalled service executable in your source tree. Using autotools we would + * achieve this by adding a file such as `my-server.service.in` in the services + * directory and have it processed by configure. + * |[ + * [D-BUS Service] + * Name=org.gtk.GDBus.Examples.ObjectManager + * Exec=@abs_top_builddir@/gio/tests/gdbus-example-objectmanager-server + * ]| + * You will also need to indicate this service directory in your test + * fixtures, so you will need to pass the path while compiling your + * test cases. Typically this is done with autotools with an added + * preprocessor flag specified to compile your tests such as: + * |[ + * -DTEST_SERVICES=\""$(abs_top_builddir)/tests/services"\" + * ]| + * Once you have a service definition file which is local to your source tree, + * you can proceed to set up a GTest fixture using the #GTestDBus scaffolding. + * + * An example of a test fixture for D-Bus services can be found + * here: + * [gdbus-test-fixture.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-test-fixture.c) + * + * Note that these examples only deal with isolating the D-Bus aspect of your + * service. To successfully run isolated unit tests on your service you may need + * some additional modifications to your test case fixture. For example; if your + * service uses GSettings and installs a schema then it is important that your test service + * not load the schema in the ordinary installed location (chances are that your service + * and schema files are not yet installed, or worse; there is an older version of the + * schema file sitting in the install location). + * + * Most of the time we can work around these obstacles using the + * environment. Since the environment is inherited by the D-Bus daemon + * created by #GTestDBus and then in turn inherited by any services the + * D-Bus daemon activates, using the setup routine for your fixture is + * a practical place to help sandbox your runtime environment. For the + * rather typical GSettings case we can work around this by setting + * `GSETTINGS_SCHEMA_DIR` to the in tree directory holding your schemas + * in the above fixture_setup() routine. + * + * The GSettings schemas need to be locally pre-compiled for this to work. This can be achieved + * by compiling the schemas locally as a step before running test cases, an autotools setup might + * do the following in the directory holding schemas: + * |[ + * all-am: + * $(GLIB_COMPILE_SCHEMAS) . + * + * CLEANFILES += gschemas.compiled + * ]| + */ + +typedef struct _GTestDBusClass GTestDBusClass; +typedef struct _GTestDBusPrivate GTestDBusPrivate; + +/** + * GTestDBus: + * + * The #GTestDBus structure contains only private data and + * should only be accessed using the provided API. + * + * Since: 2.34 + */ +struct _GTestDBus { + GObject parent; + + GTestDBusPrivate *priv; +}; + +struct _GTestDBusClass { + GObjectClass parent_class; +}; + +struct _GTestDBusPrivate +{ + GTestDBusFlags flags; + GPtrArray *service_dirs; + GPid bus_pid; + gchar *bus_address; + gboolean up; +}; + +enum +{ + PROP_0, + PROP_FLAGS, +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GTestDBus, g_test_dbus, G_TYPE_OBJECT) + +static void +g_test_dbus_init (GTestDBus *self) +{ + self->priv = g_test_dbus_get_instance_private (self); + self->priv->service_dirs = g_ptr_array_new_with_free_func (g_free); +} + +static void +g_test_dbus_dispose (GObject *object) +{ + GTestDBus *self = (GTestDBus *) object; + + if (self->priv->up) + g_test_dbus_down (self); + + G_OBJECT_CLASS (g_test_dbus_parent_class)->dispose (object); +} + +static void +g_test_dbus_finalize (GObject *object) +{ + GTestDBus *self = (GTestDBus *) object; + + g_ptr_array_unref (self->priv->service_dirs); + g_free (self->priv->bus_address); + + G_OBJECT_CLASS (g_test_dbus_parent_class)->finalize (object); +} + +static void +g_test_dbus_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GTestDBus *self = (GTestDBus *) object; + + switch (property_id) + { + case PROP_FLAGS: + g_value_set_flags (value, g_test_dbus_get_flags (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +g_test_dbus_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GTestDBus *self = (GTestDBus *) object; + + switch (property_id) + { + case PROP_FLAGS: + self->priv->flags = g_value_get_flags (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +g_test_dbus_class_init (GTestDBusClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = g_test_dbus_dispose; + object_class->finalize = g_test_dbus_finalize; + object_class->get_property = g_test_dbus_get_property; + object_class->set_property = g_test_dbus_set_property; + + /** + * GTestDBus:flags: + * + * #GTestDBusFlags specifying the behaviour of the D-Bus session. + * + * Since: 2.34 + */ + g_object_class_install_property (object_class, PROP_FLAGS, + g_param_spec_flags ("flags", + P_("D-Bus session flags"), + P_("Flags specifying the behaviour of the D-Bus session"), + G_TYPE_TEST_DBUS_FLAGS, G_TEST_DBUS_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + +} + +static gchar * +write_config_file (GTestDBus *self) +{ + GString *contents; + gint fd; + guint i; + GError *error = NULL; + gchar *path = NULL; + + fd = g_file_open_tmp ("g-test-dbus-XXXXXX", &path, &error); + g_assert_no_error (error); + + contents = g_string_new (NULL); + g_string_append (contents, + "\n" + " session\n" +#ifdef G_OS_WIN32 + " nonce-tcp:\n" +#else + " unix:tmpdir=/tmp\n" +#endif + ); + + for (i = 0; i < self->priv->service_dirs->len; i++) + { + const gchar *dir_path = g_ptr_array_index (self->priv->service_dirs, i); + + g_string_append_printf (contents, + " %s\n", dir_path); + } + + g_string_append (contents, + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"); + + close (fd); + g_file_set_contents_full (path, contents->str, contents->len, + G_FILE_SET_CONTENTS_NONE, + 0600, &error); + g_assert_no_error (error); + + g_string_free (contents, TRUE); + + return path; +} + +static gboolean +make_pipe (gint pipe_fds[2], + GError **error) +{ +#if defined(G_OS_UNIX) + return g_unix_open_pipe (pipe_fds, FD_CLOEXEC, error); +#elif defined(G_OS_WIN32) + if (_pipe (pipe_fds, 4096, _O_BINARY) < 0) + { + int errsv = errno; + + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Failed to create pipe for communicating with child process (%s)"), + g_strerror (errsv)); + return FALSE; + } + return TRUE; +#else + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Pipes are not supported in this platform")); + return FALSE; +#endif +} + +static void +start_daemon (GTestDBus *self) +{ + const gchar *argv[] = {"dbus-daemon", "--print-address", "--config-file=foo", NULL}; + gint pipe_fds[2] = {-1, -1}; + gchar *config_path; + gchar *config_arg; + gchar *print_address; + GIOChannel *channel; + gsize termpos; + GError *error = NULL; + + if (g_getenv ("G_TEST_DBUS_DAEMON") != NULL) + argv[0] = (gchar *)g_getenv ("G_TEST_DBUS_DAEMON"); + + make_pipe (pipe_fds, &error); + g_assert_no_error (error); + + print_address = g_strdup_printf ("--print-address=%d", pipe_fds[1]); + argv[1] = print_address; + g_assert_no_error (error); + + /* Write config file and set its path in argv */ + config_path = write_config_file (self); + config_arg = g_strdup_printf ("--config-file=%s", config_path); + argv[2] = config_arg; + + /* Spawn dbus-daemon */ + g_spawn_async_with_pipes_and_fds (NULL, + argv, + NULL, + /* We Need this to get the pid returned on win32 */ + G_SPAWN_DO_NOT_REAP_CHILD | + G_SPAWN_SEARCH_PATH | + /* dbus-daemon will not abuse our descriptors, and + * passing this means we can use posix_spawn() for speed */ + G_SPAWN_LEAVE_DESCRIPTORS_OPEN, + NULL, NULL, + -1, -1, -1, + &pipe_fds[1], &pipe_fds[1], 1, + &self->priv->bus_pid, + NULL, NULL, NULL, + &error); + g_assert_no_error (error); + + _g_test_watcher_add_pid (self->priv->bus_pid); + + /* Read bus address from pipe */ + channel = g_io_channel_unix_new (pipe_fds[0]); + pipe_fds[0] = -1; + g_io_channel_set_close_on_unref (channel, TRUE); + g_io_channel_read_line (channel, &self->priv->bus_address, NULL, + &termpos, &error); + g_assert_no_error (error); + self->priv->bus_address[termpos] = '\0'; + close (pipe_fds[1]); + pipe_fds[1] = -1; + + /* start dbus-monitor */ + if (g_getenv ("G_DBUS_MONITOR") != NULL) + { + gchar *command; + + command = g_strdup_printf ("dbus-monitor --address %s", + self->priv->bus_address); + g_spawn_command_line_async (command, NULL); + g_free (command); + + g_usleep (500 * 1000); + } + + /* Cleanup */ + g_io_channel_shutdown (channel, FALSE, &error); + g_assert_no_error (error); + g_io_channel_unref (channel); + + /* Don't use g_file_delete since it calls into gvfs */ + if (g_unlink (config_path) != 0) + g_assert_not_reached (); + + g_free (print_address); + g_free (config_path); + g_free (config_arg); +} + +static void +stop_daemon (GTestDBus *self) +{ +#ifdef G_OS_WIN32 + if (!TerminateProcess (self->priv->bus_pid, 0)) + g_warning ("Can't terminate process: %s", g_win32_error_message (GetLastError())); +#else + kill (self->priv->bus_pid, SIGTERM); +#endif + _g_test_watcher_remove_pid (self->priv->bus_pid); + g_spawn_close_pid (self->priv->bus_pid); + self->priv->bus_pid = 0; + + g_free (self->priv->bus_address); + self->priv->bus_address = NULL; +} + +/** + * g_test_dbus_new: + * @flags: a #GTestDBusFlags + * + * Create a new #GTestDBus object. + * + * Returns: (transfer full): a new #GTestDBus. + */ +GTestDBus * +g_test_dbus_new (GTestDBusFlags flags) +{ + return g_object_new (G_TYPE_TEST_DBUS, + "flags", flags, + NULL); +} + +/** + * g_test_dbus_get_flags: + * @self: a #GTestDBus + * + * Get the flags of the #GTestDBus object. + * + * Returns: the value of #GTestDBus:flags property + */ +GTestDBusFlags +g_test_dbus_get_flags (GTestDBus *self) +{ + g_return_val_if_fail (G_IS_TEST_DBUS (self), G_TEST_DBUS_NONE); + + return self->priv->flags; +} + +/** + * g_test_dbus_get_bus_address: + * @self: a #GTestDBus + * + * Get the address on which dbus-daemon is running. If g_test_dbus_up() has not + * been called yet, %NULL is returned. This can be used with + * g_dbus_connection_new_for_address(). + * + * Returns: (nullable): the address of the bus, or %NULL. + */ +const gchar * +g_test_dbus_get_bus_address (GTestDBus *self) +{ + g_return_val_if_fail (G_IS_TEST_DBUS (self), NULL); + + return self->priv->bus_address; +} + +/** + * g_test_dbus_add_service_dir: + * @self: a #GTestDBus + * @path: path to a directory containing .service files + * + * Add a path where dbus-daemon will look up .service files. This can't be + * called after g_test_dbus_up(). + */ +void +g_test_dbus_add_service_dir (GTestDBus *self, + const gchar *path) +{ + g_return_if_fail (G_IS_TEST_DBUS (self)); + g_return_if_fail (self->priv->bus_address == NULL); + + g_ptr_array_add (self->priv->service_dirs, g_strdup (path)); +} + +/** + * g_test_dbus_up: + * @self: a #GTestDBus + * + * Start a dbus-daemon instance and set DBUS_SESSION_BUS_ADDRESS. After this + * call, it is safe for unit tests to start sending messages on the session bus. + * + * If this function is called from setup callback of g_test_add(), + * g_test_dbus_down() must be called in its teardown callback. + * + * If this function is called from unit test's main(), then g_test_dbus_down() + * must be called after g_test_run(). + */ +void +g_test_dbus_up (GTestDBus *self) +{ + g_return_if_fail (G_IS_TEST_DBUS (self)); + g_return_if_fail (self->priv->bus_address == NULL); + g_return_if_fail (!self->priv->up); + + start_daemon (self); + + g_test_dbus_unset (); + g_setenv ("DBUS_SESSION_BUS_ADDRESS", self->priv->bus_address, TRUE); + self->priv->up = TRUE; +} + + +/** + * g_test_dbus_stop: + * @self: a #GTestDBus + * + * Stop the session bus started by g_test_dbus_up(). + * + * Unlike g_test_dbus_down(), this won't verify the #GDBusConnection + * singleton returned by g_bus_get() or g_bus_get_sync() is destroyed. Unit + * tests wanting to verify behaviour after the session bus has been stopped + * can use this function but should still call g_test_dbus_down() when done. + */ +void +g_test_dbus_stop (GTestDBus *self) +{ + g_return_if_fail (G_IS_TEST_DBUS (self)); + g_return_if_fail (self->priv->bus_address != NULL); + + stop_daemon (self); +} + +/** + * g_test_dbus_down: + * @self: a #GTestDBus + * + * Stop the session bus started by g_test_dbus_up(). + * + * This will wait for the singleton returned by g_bus_get() or g_bus_get_sync() + * to be destroyed. This is done to ensure that the next unit test won't get a + * leaked singleton from this test. + */ +void +g_test_dbus_down (GTestDBus *self) +{ + GDBusConnection *connection; + + g_return_if_fail (G_IS_TEST_DBUS (self)); + g_return_if_fail (self->priv->up); + + connection = _g_bus_get_singleton_if_exists (G_BUS_TYPE_SESSION); + if (connection != NULL) + g_dbus_connection_set_exit_on_close (connection, FALSE); + + if (self->priv->bus_address != NULL) + stop_daemon (self); + + if (connection != NULL) + _g_object_unref_and_wait_weak_notify (connection); + + g_test_dbus_unset (); + _g_bus_forget_singleton (G_BUS_TYPE_SESSION); + self->priv->up = FALSE; +} + +/** + * g_test_dbus_unset: + * + * Unset DISPLAY and DBUS_SESSION_BUS_ADDRESS env variables to ensure the test + * won't use user's session bus. + * + * This is useful for unit tests that want to verify behaviour when no session + * bus is running. It is not necessary to call this if unit test already calls + * g_test_dbus_up() before acquiring the session bus. + */ +void +g_test_dbus_unset (void) +{ + g_unsetenv ("DISPLAY"); + g_unsetenv ("DBUS_SESSION_BUS_ADDRESS"); + g_unsetenv ("DBUS_STARTER_ADDRESS"); + g_unsetenv ("DBUS_STARTER_BUS_TYPE"); + /* avoid using XDG_RUNTIME_DIR/bus */ + g_unsetenv ("XDG_RUNTIME_DIR"); +} diff --git a/gio/gtestdbus.h b/gio/gtestdbus.h new file mode 100644 index 0000000..9467f59 --- /dev/null +++ b/gio/gtestdbus.h @@ -0,0 +1,72 @@ +/* GIO testing utilities + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * Copyright (C) 2012 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: David Zeuthen + * Xavier Claessens + */ + +#ifndef __G_TEST_DBUS_H__ +#define __G_TEST_DBUS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TEST_DBUS \ + (g_test_dbus_get_type ()) +#define G_TEST_DBUS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_TEST_DBUS, \ + GTestDBus)) +#define G_IS_TEST_DBUS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_TEST_DBUS)) + +GLIB_AVAILABLE_IN_2_34 +GType g_test_dbus_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_34 +GTestDBus * g_test_dbus_new (GTestDBusFlags flags); + +GLIB_AVAILABLE_IN_2_34 +GTestDBusFlags g_test_dbus_get_flags (GTestDBus *self); + +GLIB_AVAILABLE_IN_2_34 +const gchar * g_test_dbus_get_bus_address (GTestDBus *self); + +GLIB_AVAILABLE_IN_2_34 +void g_test_dbus_add_service_dir (GTestDBus *self, + const gchar *path); + +GLIB_AVAILABLE_IN_2_34 +void g_test_dbus_up (GTestDBus *self); + +GLIB_AVAILABLE_IN_2_34 +void g_test_dbus_stop (GTestDBus *self); + +GLIB_AVAILABLE_IN_2_34 +void g_test_dbus_down (GTestDBus *self); + +GLIB_AVAILABLE_IN_2_34 +void g_test_dbus_unset (void); + +G_END_DECLS + +#endif /* __G_TEST_DBUS_H__ */ diff --git a/gio/gthemedicon.c b/gio/gthemedicon.c new file mode 100644 index 0000000..35970de --- /dev/null +++ b/gio/gthemedicon.c @@ -0,0 +1,628 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "gthemedicon.h" +#include "gicon.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gthemedicon + * @short_description: Icon theming support + * @include: gio/gio.h + * @see_also: #GIcon, #GLoadableIcon + * + * #GThemedIcon is an implementation of #GIcon that supports icon themes. + * #GThemedIcon contains a list of all of the icons present in an icon + * theme, so that icons can be looked up quickly. #GThemedIcon does + * not provide actual pixmaps for icons, just the icon names. + * Ideally something like gtk_icon_theme_choose_icon() should be used to + * resolve the list of names so that fallback icons work nicely with + * themes that inherit other themes. + **/ + +static void g_themed_icon_icon_iface_init (GIconIface *iface); + +struct _GThemedIcon +{ + GObject parent_instance; + + char **init_names; + char **names; + gboolean use_default_fallbacks; +}; + +struct _GThemedIconClass +{ + GObjectClass parent_class; +}; + +enum +{ + PROP_0, + PROP_NAME, + PROP_NAMES, + PROP_USE_DEFAULT_FALLBACKS +}; + +static void g_themed_icon_update_names (GThemedIcon *themed); + +G_DEFINE_TYPE_WITH_CODE (GThemedIcon, g_themed_icon, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ICON, + g_themed_icon_icon_iface_init)) + +static void +g_themed_icon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GThemedIcon *icon = G_THEMED_ICON (object); + + switch (prop_id) + { + case PROP_NAMES: + g_value_set_boxed (value, icon->init_names); + break; + + case PROP_USE_DEFAULT_FALLBACKS: + g_value_set_boolean (value, icon->use_default_fallbacks); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_themed_icon_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GThemedIcon *icon = G_THEMED_ICON (object); + gchar **names; + const gchar *name; + + switch (prop_id) + { + case PROP_NAME: + name = g_value_get_string (value); + + if (!name) + break; + + if (icon->init_names) + g_strfreev (icon->init_names); + + icon->init_names = g_new (char *, 2); + icon->init_names[0] = g_strdup (name); + icon->init_names[1] = NULL; + break; + + case PROP_NAMES: + names = g_value_dup_boxed (value); + + if (!names) + break; + + if (icon->init_names) + g_strfreev (icon->init_names); + + icon->init_names = names; + break; + + case PROP_USE_DEFAULT_FALLBACKS: + icon->use_default_fallbacks = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_themed_icon_constructed (GObject *object) +{ + g_themed_icon_update_names (G_THEMED_ICON (object)); +} + +static void +g_themed_icon_finalize (GObject *object) +{ + GThemedIcon *themed; + + themed = G_THEMED_ICON (object); + + g_strfreev (themed->init_names); + g_strfreev (themed->names); + + G_OBJECT_CLASS (g_themed_icon_parent_class)->finalize (object); +} + +static void +g_themed_icon_class_init (GThemedIconClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_themed_icon_finalize; + gobject_class->constructed = g_themed_icon_constructed; + gobject_class->set_property = g_themed_icon_set_property; + gobject_class->get_property = g_themed_icon_get_property; + + /** + * GThemedIcon:name: + * + * The icon name. + */ + g_object_class_install_property (gobject_class, PROP_NAME, + g_param_spec_string ("name", + P_("name"), + P_("The name of the icon"), + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); + + /** + * GThemedIcon:names: + * + * A %NULL-terminated array of icon names. + */ + g_object_class_install_property (gobject_class, PROP_NAMES, + g_param_spec_boxed ("names", + P_("names"), + P_("An array containing the icon names"), + G_TYPE_STRV, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); + + /** + * GThemedIcon:use-default-fallbacks: + * + * Whether to use the default fallbacks found by shortening the icon name + * at '-' characters. If the "names" array has more than one element, + * ignores any past the first. + * + * For example, if the icon name was "gnome-dev-cdrom-audio", the array + * would become + * |[ + * { + * "gnome-dev-cdrom-audio", + * "gnome-dev-cdrom", + * "gnome-dev", + * "gnome", + * NULL + * }; + * ]| + */ + g_object_class_install_property (gobject_class, PROP_USE_DEFAULT_FALLBACKS, + g_param_spec_boolean ("use-default-fallbacks", + P_("use default fallbacks"), + P_("Whether to use default fallbacks found by shortening the name at “-†characters. Ignores names after the first if multiple names are given."), + FALSE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); +} + +static void +g_themed_icon_init (GThemedIcon *themed) +{ + themed->init_names = NULL; + themed->names = NULL; +} + +/** + * g_themed_icon_update_names: + * @themed: a #GThemedIcon. + * + * Update the actual icon name list, based on the requested names (from + * construction, or later added with g_themed_icon_prepend_name() and + * g_themed_icon_append_name()). + * The order of the list matters, indicating priority: + * - The first requested icon is first in priority. + * - If "use-default-fallbacks" is #TRUE, then it is followed by all its + * fallbacks (starting from top to lower context levels). + * - Then next requested icons, and optionally their fallbacks, follow. + * - Finally all the style variants (symbolic or regular, opposite to whatever + * is the requested style) follow in the same order. + * + * An icon is not added twice in the list if it was previously added. + * + * For instance, if requested names are: + * [ "some-icon-symbolic", "some-other-icon" ] + * and use-default-fallbacks is TRUE, the final name list shall be: + * [ "some-icon-symbolic", "some-symbolic", "some-other-icon", + * "some-other", "some", "some-icon", "some-other-icon-symbolic", + * "some-other-symbolic" ] + * + * Returns: (transfer full) (type GThemedIcon): a new #GThemedIcon + **/ +static void +g_themed_icon_update_names (GThemedIcon *themed) +{ + GList *names = NULL; + GList *variants = NULL; + GList *iter; + guint i; + + g_return_if_fail (themed->init_names != NULL && themed->init_names[0] != NULL); + + for (i = 0; themed->init_names[i]; i++) + { + gchar *name; + gboolean is_symbolic; + + is_symbolic = g_str_has_suffix (themed->init_names[i], "-symbolic"); + if (is_symbolic) + name = g_strndup (themed->init_names[i], strlen (themed->init_names[i]) - 9); + else + name = g_strdup (themed->init_names[i]); + + if (g_list_find_custom (names, name, (GCompareFunc) g_strcmp0)) + { + g_free (name); + continue; + } + + if (is_symbolic) + names = g_list_prepend (names, g_strdup (themed->init_names[i])); + else + names = g_list_prepend (names, name); + + if (themed->use_default_fallbacks) + { + char *dashp; + char *last; + + last = name; + + while ((dashp = strrchr (last, '-')) != NULL) + { + gchar *tmp = last; + gchar *fallback; + + last = g_strndup (last, dashp - last); + if (is_symbolic) + { + g_free (tmp); + fallback = g_strdup_printf ("%s-symbolic", last); + } + else + fallback = last; + if (g_list_find_custom (names, fallback, (GCompareFunc) g_strcmp0)) + { + g_free (fallback); + break; + } + names = g_list_prepend (names, fallback); + } + if (is_symbolic) + g_free (last); + } + else if (is_symbolic) + g_free (name); + } + for (iter = names; iter; iter = iter->next) + { + gchar *name = (gchar *) iter->data; + gchar *variant; + gboolean is_symbolic; + + is_symbolic = g_str_has_suffix (name, "-symbolic"); + if (is_symbolic) + variant = g_strndup (name, strlen (name) - 9); + else + variant = g_strdup_printf ("%s-symbolic", name); + if (g_list_find_custom (names, variant, (GCompareFunc) g_strcmp0) || + g_list_find_custom (variants, variant, (GCompareFunc) g_strcmp0)) + { + g_free (variant); + continue; + } + + variants = g_list_prepend (variants, variant); + } + names = g_list_reverse (names); + + g_strfreev (themed->names); + themed->names = g_new (char *, g_list_length (names) + g_list_length (variants) + 1); + + for (iter = names, i = 0; iter; iter = iter->next, i++) + themed->names[i] = iter->data; + for (iter = variants; iter; iter = iter->next, i++) + themed->names[i] = iter->data; + themed->names[i] = NULL; + + g_list_free (names); + g_list_free (variants); + + g_object_notify (G_OBJECT (themed), "names"); +} + +/** + * g_themed_icon_new: + * @iconname: a string containing an icon name. + * + * Creates a new themed icon for @iconname. + * + * Returns: (transfer full) (type GThemedIcon): a new #GThemedIcon. + **/ +GIcon * +g_themed_icon_new (const char *iconname) +{ + g_return_val_if_fail (iconname != NULL, NULL); + + return G_ICON (g_object_new (G_TYPE_THEMED_ICON, "name", iconname, NULL)); +} + +/** + * g_themed_icon_new_from_names: + * @iconnames: (array length=len): an array of strings containing icon names. + * @len: the length of the @iconnames array, or -1 if @iconnames is + * %NULL-terminated + * + * Creates a new themed icon for @iconnames. + * + * Returns: (transfer full) (type GThemedIcon): a new #GThemedIcon + **/ +GIcon * +g_themed_icon_new_from_names (char **iconnames, + int len) +{ + GIcon *icon; + + g_return_val_if_fail (iconnames != NULL, NULL); + + if (len >= 0) + { + char **names; + int i; + + names = g_new (char *, len + 1); + + for (i = 0; i < len; i++) + names[i] = iconnames[i]; + + names[i] = NULL; + + icon = G_ICON (g_object_new (G_TYPE_THEMED_ICON, "names", names, NULL)); + + g_free (names); + } + else + icon = G_ICON (g_object_new (G_TYPE_THEMED_ICON, "names", iconnames, NULL)); + + return icon; +} + +/** + * g_themed_icon_new_with_default_fallbacks: + * @iconname: a string containing an icon name + * + * Creates a new themed icon for @iconname, and all the names + * that can be created by shortening @iconname at '-' characters. + * + * In the following example, @icon1 and @icon2 are equivalent: + * |[ + * const char *names[] = { + * "gnome-dev-cdrom-audio", + * "gnome-dev-cdrom", + * "gnome-dev", + * "gnome" + * }; + * + * icon1 = g_themed_icon_new_from_names (names, 4); + * icon2 = g_themed_icon_new_with_default_fallbacks ("gnome-dev-cdrom-audio"); + * ]| + * + * Returns: (transfer full) (type GThemedIcon): a new #GThemedIcon. + */ +GIcon * +g_themed_icon_new_with_default_fallbacks (const char *iconname) +{ + g_return_val_if_fail (iconname != NULL, NULL); + + return G_ICON (g_object_new (G_TYPE_THEMED_ICON, "name", iconname, "use-default-fallbacks", TRUE, NULL)); +} + + +/** + * g_themed_icon_get_names: + * @icon: a #GThemedIcon. + * + * Gets the names of icons from within @icon. + * + * Returns: (transfer none): a list of icon names. + */ +const char * const * +g_themed_icon_get_names (GThemedIcon *icon) +{ + g_return_val_if_fail (G_IS_THEMED_ICON (icon), NULL); + return (const char * const *)icon->names; +} + +/** + * g_themed_icon_append_name: + * @icon: a #GThemedIcon + * @iconname: name of icon to append to list of icons from within @icon. + * + * Append a name to the list of icons from within @icon. + * + * Note that doing so invalidates the hash computed by prior calls + * to g_icon_hash(). + */ +void +g_themed_icon_append_name (GThemedIcon *icon, + const char *iconname) +{ + guint num_names; + + g_return_if_fail (G_IS_THEMED_ICON (icon)); + g_return_if_fail (iconname != NULL); + + num_names = g_strv_length (icon->init_names); + icon->init_names = g_realloc (icon->init_names, sizeof (char*) * (num_names + 2)); + icon->init_names[num_names] = g_strdup (iconname); + icon->init_names[num_names + 1] = NULL; + + g_themed_icon_update_names (icon); +} + +/** + * g_themed_icon_prepend_name: + * @icon: a #GThemedIcon + * @iconname: name of icon to prepend to list of icons from within @icon. + * + * Prepend a name to the list of icons from within @icon. + * + * Note that doing so invalidates the hash computed by prior calls + * to g_icon_hash(). + * + * Since: 2.18 + */ +void +g_themed_icon_prepend_name (GThemedIcon *icon, + const char *iconname) +{ + guint num_names; + gchar **names; + gint i; + + g_return_if_fail (G_IS_THEMED_ICON (icon)); + g_return_if_fail (iconname != NULL); + + num_names = g_strv_length (icon->init_names); + names = g_new (char*, num_names + 2); + for (i = 0; icon->init_names[i]; i++) + names[i + 1] = icon->init_names[i]; + names[0] = g_strdup (iconname); + names[num_names + 1] = NULL; + + g_free (icon->init_names); + icon->init_names = names; + + g_themed_icon_update_names (icon); +} + +static guint +g_themed_icon_hash (GIcon *icon) +{ + GThemedIcon *themed = G_THEMED_ICON (icon); + guint hash; + int i; + + hash = 0; + + for (i = 0; themed->names[i] != NULL; i++) + hash ^= g_str_hash (themed->names[i]); + + return hash; +} + +static gboolean +g_themed_icon_equal (GIcon *icon1, + GIcon *icon2) +{ + GThemedIcon *themed1 = G_THEMED_ICON (icon1); + GThemedIcon *themed2 = G_THEMED_ICON (icon2); + int i; + + for (i = 0; themed1->names[i] != NULL && themed2->names[i] != NULL; i++) + { + if (!g_str_equal (themed1->names[i], themed2->names[i])) + return FALSE; + } + + return themed1->names[i] == NULL && themed2->names[i] == NULL; +} + + +static gboolean +g_themed_icon_to_tokens (GIcon *icon, + GPtrArray *tokens, + gint *out_version) +{ + GThemedIcon *themed_icon = G_THEMED_ICON (icon); + int n; + + g_return_val_if_fail (out_version != NULL, FALSE); + + *out_version = 0; + + for (n = 0; themed_icon->names[n] != NULL; n++) + g_ptr_array_add (tokens, + g_strdup (themed_icon->names[n])); + + return TRUE; +} + +static GIcon * +g_themed_icon_from_tokens (gchar **tokens, + gint num_tokens, + gint version, + GError **error) +{ + GIcon *icon; + gchar **names; + int n; + + icon = NULL; + + if (version != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Can’t handle version %d of GThemedIcon encoding"), + version); + goto out; + } + + names = g_new0 (gchar *, num_tokens + 1); + for (n = 0; n < num_tokens; n++) + names[n] = tokens[n]; + names[n] = NULL; + + icon = g_themed_icon_new_from_names (names, num_tokens); + g_free (names); + + out: + return icon; +} + +static GVariant * +g_themed_icon_serialize (GIcon *icon) +{ + GThemedIcon *themed_icon = G_THEMED_ICON (icon); + + return g_variant_new ("(sv)", "themed", g_variant_new ("^as", themed_icon->names)); +} + +static void +g_themed_icon_icon_iface_init (GIconIface *iface) +{ + iface->hash = g_themed_icon_hash; + iface->equal = g_themed_icon_equal; + iface->to_tokens = g_themed_icon_to_tokens; + iface->from_tokens = g_themed_icon_from_tokens; + iface->serialize = g_themed_icon_serialize; +} diff --git a/gio/gthemedicon.h b/gio/gthemedicon.h new file mode 100644 index 0000000..3a145b5 --- /dev/null +++ b/gio/gthemedicon.h @@ -0,0 +1,68 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_THEMED_ICON_H__ +#define __G_THEMED_ICON_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_THEMED_ICON (g_themed_icon_get_type ()) +#define G_THEMED_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_THEMED_ICON, GThemedIcon)) +#define G_THEMED_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_THEMED_ICON, GThemedIconClass)) +#define G_IS_THEMED_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_THEMED_ICON)) +#define G_IS_THEMED_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_THEMED_ICON)) +#define G_THEMED_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_THEMED_ICON, GThemedIconClass)) + +/** + * GThemedIcon: + * + * An implementation of #GIcon for themed icons. + **/ +typedef struct _GThemedIconClass GThemedIconClass; + +GLIB_AVAILABLE_IN_ALL +GType g_themed_icon_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GIcon *g_themed_icon_new (const char *iconname); +GLIB_AVAILABLE_IN_ALL +GIcon *g_themed_icon_new_with_default_fallbacks (const char *iconname); +GLIB_AVAILABLE_IN_ALL +GIcon *g_themed_icon_new_from_names (char **iconnames, + int len); +GLIB_AVAILABLE_IN_ALL +void g_themed_icon_prepend_name (GThemedIcon *icon, + const char *iconname); +GLIB_AVAILABLE_IN_ALL +void g_themed_icon_append_name (GThemedIcon *icon, + const char *iconname); + +GLIB_AVAILABLE_IN_ALL +const gchar* const * g_themed_icon_get_names (GThemedIcon *icon); + +G_END_DECLS + +#endif /* __G_THEMED_ICON_H__ */ diff --git a/gio/gthreadedresolver.c b/gio/gthreadedresolver.c new file mode 100644 index 0000000..aeeb40e --- /dev/null +++ b/gio/gthreadedresolver.c @@ -0,0 +1,1254 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include +#include "glibintl.h" + +#include +#include + +#include "gthreadedresolver.h" +#include "gnetworkingprivate.h" + +#include "gcancellable.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "gtask.h" +#include "gsocketaddress.h" +#include "gsrvtarget.h" + + +G_DEFINE_TYPE (GThreadedResolver, g_threaded_resolver, G_TYPE_RESOLVER) + +static void +g_threaded_resolver_init (GThreadedResolver *gtr) +{ +} + +static GResolverError +g_resolver_error_from_addrinfo_error (gint err) +{ + switch (err) + { + case EAI_FAIL: +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif + case EAI_NONAME: + return G_RESOLVER_ERROR_NOT_FOUND; + + case EAI_AGAIN: + return G_RESOLVER_ERROR_TEMPORARY_FAILURE; + + default: + return G_RESOLVER_ERROR_INTERNAL; + } +} + +typedef struct { + char *hostname; + int address_family; +} LookupData; + +static LookupData * +lookup_data_new (const char *hostname, + int address_family) +{ + LookupData *data = g_new (LookupData, 1); + data->hostname = g_strdup (hostname); + data->address_family = address_family; + return data; +} + +static void +lookup_data_free (LookupData *data) +{ + g_free (data->hostname); + g_free (data); +} + +static void +do_lookup_by_name (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + LookupData *lookup_data = task_data; + const char *hostname = lookup_data->hostname; + struct addrinfo *res = NULL; + GList *addresses; + gint retval; + struct addrinfo addrinfo_hints = { 0 }; + +#ifdef AI_ADDRCONFIG + addrinfo_hints.ai_flags = AI_ADDRCONFIG; +#endif + /* socktype and protocol don't actually matter, they just get copied into the + * returned addrinfo structures (and then we ignore them). But if + * we leave them unset, we'll get back duplicate answers. + */ + addrinfo_hints.ai_socktype = SOCK_STREAM; + addrinfo_hints.ai_protocol = IPPROTO_TCP; + + addrinfo_hints.ai_family = lookup_data->address_family; + retval = getaddrinfo (hostname, NULL, &addrinfo_hints, &res); + + if (retval == 0) + { + struct addrinfo *ai; + GSocketAddress *sockaddr; + GInetAddress *addr; + + addresses = NULL; + for (ai = res; ai; ai = ai->ai_next) + { + sockaddr = g_socket_address_new_from_native (ai->ai_addr, ai->ai_addrlen); + if (!sockaddr) + continue; + if (!G_IS_INET_SOCKET_ADDRESS (sockaddr)) + { + g_clear_object (&sockaddr); + continue; + } + + addr = g_object_ref (g_inet_socket_address_get_address ((GInetSocketAddress *)sockaddr)); + addresses = g_list_prepend (addresses, addr); + g_object_unref (sockaddr); + } + + if (addresses != NULL) + { + addresses = g_list_reverse (addresses); + g_task_return_pointer (task, addresses, + (GDestroyNotify)g_resolver_free_addresses); + } + else + { + /* All addresses failed to be converted to GSocketAddresses. */ + g_task_return_new_error (task, + G_RESOLVER_ERROR, + G_RESOLVER_ERROR_NOT_FOUND, + _("Error resolving “%sâ€: %s"), + hostname, + _("No valid addresses were found")); + } + } + else + { +#ifdef G_OS_WIN32 + gchar *error_message = g_win32_error_message (WSAGetLastError ()); +#else + gchar *error_message = g_locale_to_utf8 (gai_strerror (retval), -1, NULL, NULL, NULL); + if (error_message == NULL) + error_message = g_strdup ("[Invalid UTF-8]"); +#endif + + g_task_return_new_error (task, + G_RESOLVER_ERROR, + g_resolver_error_from_addrinfo_error (retval), + _("Error resolving “%sâ€: %s"), + hostname, error_message); + g_free (error_message); + } + + if (res) + freeaddrinfo (res); +} + +static GList * +lookup_by_name (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GError **error) +{ + GTask *task; + GList *addresses; + LookupData *data; + + data = lookup_data_new (hostname, AF_UNSPEC); + task = g_task_new (resolver, cancellable, NULL, NULL); + g_task_set_source_tag (task, lookup_by_name); + g_task_set_name (task, "[gio] resolver lookup"); + g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free); + g_task_set_return_on_cancel (task, TRUE); + g_task_run_in_thread_sync (task, do_lookup_by_name); + addresses = g_task_propagate_pointer (task, error); + g_object_unref (task); + + return addresses; +} + +static int +flags_to_family (GResolverNameLookupFlags flags) +{ + int address_family = AF_UNSPEC; + + if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY) + address_family = AF_INET; + + if (flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY) + { + address_family = AF_INET6; + /* You can only filter by one family at a time */ + g_return_val_if_fail (!(flags & G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY), address_family); + } + + return address_family; +} + +static GList * +lookup_by_name_with_flags (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GError **error) +{ + GTask *task; + GList *addresses; + LookupData *data; + + data = lookup_data_new (hostname, flags_to_family (flags)); + task = g_task_new (resolver, cancellable, NULL, NULL); + g_task_set_source_tag (task, lookup_by_name_with_flags); + g_task_set_name (task, "[gio] resolver lookup"); + g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free); + g_task_set_return_on_cancel (task, TRUE); + g_task_run_in_thread_sync (task, do_lookup_by_name); + addresses = g_task_propagate_pointer (task, error); + g_object_unref (task); + + return addresses; +} + +static void +lookup_by_name_with_flags_async (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + LookupData *data; + + data = lookup_data_new (hostname, flags_to_family (flags)); + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, lookup_by_name_with_flags_async); + g_task_set_name (task, "[gio] resolver lookup"); + g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free); + g_task_set_return_on_cancel (task, TRUE); + g_task_run_in_thread (task, do_lookup_by_name); + g_object_unref (task); +} + +static void +lookup_by_name_async (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + lookup_by_name_with_flags_async (resolver, + hostname, + G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, + cancellable, + callback, + user_data); +} + +static GList * +lookup_by_name_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, resolver), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static GList * +lookup_by_name_with_flags_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, resolver), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +do_lookup_by_address (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GInetAddress *address = task_data; + struct sockaddr_storage sockaddr; + gsize sockaddr_size; + GSocketAddress *gsockaddr; + gchar name[NI_MAXHOST]; + gint retval; + + gsockaddr = g_inet_socket_address_new (address, 0); + g_socket_address_to_native (gsockaddr, (struct sockaddr *)&sockaddr, + sizeof (sockaddr), NULL); + sockaddr_size = g_socket_address_get_native_size (gsockaddr); + g_object_unref (gsockaddr); + + retval = getnameinfo ((struct sockaddr *)&sockaddr, sockaddr_size, + name, sizeof (name), NULL, 0, NI_NAMEREQD); + if (retval == 0) + g_task_return_pointer (task, g_strdup (name), g_free); + else + { + gchar *phys; + +#ifdef G_OS_WIN32 + gchar *error_message = g_win32_error_message (WSAGetLastError ()); +#else + gchar *error_message = g_locale_to_utf8 (gai_strerror (retval), -1, NULL, NULL, NULL); + if (error_message == NULL) + error_message = g_strdup ("[Invalid UTF-8]"); +#endif + + phys = g_inet_address_to_string (address); + g_task_return_new_error (task, + G_RESOLVER_ERROR, + g_resolver_error_from_addrinfo_error (retval), + _("Error reverse-resolving “%sâ€: %s"), + phys ? phys : "(unknown)", + error_message); + g_free (phys); + g_free (error_message); + } +} + +static gchar * +lookup_by_address (GResolver *resolver, + GInetAddress *address, + GCancellable *cancellable, + GError **error) +{ + GTask *task; + gchar *name; + + task = g_task_new (resolver, cancellable, NULL, NULL); + g_task_set_source_tag (task, lookup_by_address); + g_task_set_name (task, "[gio] resolver lookup"); + g_task_set_task_data (task, g_object_ref (address), g_object_unref); + g_task_set_return_on_cancel (task, TRUE); + g_task_run_in_thread_sync (task, do_lookup_by_address); + name = g_task_propagate_pointer (task, error); + g_object_unref (task); + + return name; +} + +static void +lookup_by_address_async (GResolver *resolver, + GInetAddress *address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, lookup_by_address_async); + g_task_set_name (task, "[gio] resolver lookup"); + g_task_set_task_data (task, g_object_ref (address), g_object_unref); + g_task_set_return_on_cancel (task, TRUE); + g_task_run_in_thread (task, do_lookup_by_address); + g_object_unref (task); +} + +static gchar * +lookup_by_address_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, resolver), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + + +#if defined(G_OS_UNIX) + +#if defined __BIONIC__ && !defined BIND_4_COMPAT +/* Copy from bionic/libc/private/arpa_nameser_compat.h + * and bionic/libc/private/arpa_nameser.h */ +typedef struct { + unsigned id :16; /* query identification number */ +#if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /* response flag */ + unsigned opcode: 4; /* purpose of message */ + unsigned aa: 1; /* authoritative answer */ + unsigned tc: 1; /* truncated message */ + unsigned rd: 1; /* recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /* recursion available */ + unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ad: 1; /* authentic data from named */ + unsigned cd: 1; /* checking disabled by resolver */ + unsigned rcode :4; /* response code */ +#endif +#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /* recursion desired */ + unsigned tc :1; /* truncated message */ + unsigned aa :1; /* authoritative answer */ + unsigned opcode :4; /* purpose of message */ + unsigned qr :1; /* response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /* response code */ + unsigned cd: 1; /* checking disabled by resolver */ + unsigned ad: 1; /* authentic data from named */ + unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /* recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /* number of question entries */ + unsigned ancount :16; /* number of answer entries */ + unsigned nscount :16; /* number of authority entries */ + unsigned arcount :16; /* number of resource entries */ +} HEADER; + +#define NS_INT32SZ 4 /* #/bytes of data in a uint32_t */ +#define NS_INT16SZ 2 /* #/bytes of data in a uint16_t */ + +#define NS_GET16(s, cp) do { \ + const u_char *t_cp = (const u_char *)(cp); \ + (s) = ((uint16_t)t_cp[0] << 8) \ + | ((uint16_t)t_cp[1]) \ + ; \ + (cp) += NS_INT16SZ; \ +} while (/*CONSTCOND*/0) + +#define NS_GET32(l, cp) do { \ + const u_char *t_cp = (const u_char *)(cp); \ + (l) = ((uint32_t)t_cp[0] << 24) \ + | ((uint32_t)t_cp[1] << 16) \ + | ((uint32_t)t_cp[2] << 8) \ + | ((uint32_t)t_cp[3]) \ + ; \ + (cp) += NS_INT32SZ; \ +} while (/*CONSTCOND*/0) + +#define GETSHORT NS_GET16 +#define GETLONG NS_GET32 + +#define C_IN 1 + +/* From bionic/libc/private/resolv_private.h */ +int dn_expand(const u_char *, const u_char *, const u_char *, char *, int); +#define dn_skipname __dn_skipname +int dn_skipname(const u_char *, const u_char *); + +/* From bionic/libc/private/arpa_nameser_compat.h */ +#define T_MX ns_t_mx +#define T_TXT ns_t_txt +#define T_SOA ns_t_soa +#define T_NS ns_t_ns + +/* From bionic/libc/private/arpa_nameser.h */ +typedef enum __ns_type { + ns_t_invalid = 0, /* Cookie. */ + ns_t_a = 1, /* Host address. */ + ns_t_ns = 2, /* Authoritative server. */ + ns_t_md = 3, /* Mail destination. */ + ns_t_mf = 4, /* Mail forwarder. */ + ns_t_cname = 5, /* Canonical name. */ + ns_t_soa = 6, /* Start of authority zone. */ + ns_t_mb = 7, /* Mailbox domain name. */ + ns_t_mg = 8, /* Mail group member. */ + ns_t_mr = 9, /* Mail rename name. */ + ns_t_null = 10, /* Null resource record. */ + ns_t_wks = 11, /* Well known service. */ + ns_t_ptr = 12, /* Domain name pointer. */ + ns_t_hinfo = 13, /* Host information. */ + ns_t_minfo = 14, /* Mailbox information. */ + ns_t_mx = 15, /* Mail routing information. */ + ns_t_txt = 16, /* Text strings. */ + ns_t_rp = 17, /* Responsible person. */ + ns_t_afsdb = 18, /* AFS cell database. */ + ns_t_x25 = 19, /* X_25 calling address. */ + ns_t_isdn = 20, /* ISDN calling address. */ + ns_t_rt = 21, /* Router. */ + ns_t_nsap = 22, /* NSAP address. */ + ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */ + ns_t_sig = 24, /* Security signature. */ + ns_t_key = 25, /* Security key. */ + ns_t_px = 26, /* X.400 mail mapping. */ + ns_t_gpos = 27, /* Geographical position (withdrawn). */ + ns_t_aaaa = 28, /* Ip6 Address. */ + ns_t_loc = 29, /* Location Information. */ + ns_t_nxt = 30, /* Next domain (security). */ + ns_t_eid = 31, /* Endpoint identifier. */ + ns_t_nimloc = 32, /* Nimrod Locator. */ + ns_t_srv = 33, /* Server Selection. */ + ns_t_atma = 34, /* ATM Address */ + ns_t_naptr = 35, /* Naming Authority PoinTeR */ + ns_t_kx = 36, /* Key Exchange */ + ns_t_cert = 37, /* Certification record */ + ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */ + ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ + ns_t_sink = 40, /* Kitchen sink (experimental) */ + ns_t_opt = 41, /* EDNS0 option (meta-RR) */ + ns_t_apl = 42, /* Address prefix list (RFC 3123) */ + ns_t_tkey = 249, /* Transaction key */ + ns_t_tsig = 250, /* Transaction signature. */ + ns_t_ixfr = 251, /* Incremental zone transfer. */ + ns_t_axfr = 252, /* Transfer zone of authority. */ + ns_t_mailb = 253, /* Transfer mailbox records. */ + ns_t_maila = 254, /* Transfer mail agent records. */ + ns_t_any = 255, /* Wildcard match. */ + ns_t_zxfr = 256, /* BIND-specific, nonstandard. */ + ns_t_max = 65536 +} ns_type; + +#endif /* __BIONIC__ */ + +/* Wrapper around dn_expand() which does associated length checks and returns + * errors as #GError. */ +static gboolean +expand_name (const gchar *rrname, + const guint8 *answer, + const guint8 *end, + const guint8 **p, + gchar *namebuf, + gsize namebuf_len, + GError **error) +{ + int expand_result; + + expand_result = dn_expand (answer, end, *p, namebuf, namebuf_len); + if (expand_result < 0 || end - *p < expand_result) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ */ + _("Error parsing DNS %s record: malformed DNS packet"), rrname); + return FALSE; + } + + *p += expand_result; + + return TRUE; +} + +static GVariant * +parse_res_srv (const guint8 *answer, + const guint8 *end, + const guint8 **p, + GError **error) +{ + gchar namebuf[1024]; + guint16 priority, weight, port; + + if (end - *p < 6) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ */ + _("Error parsing DNS %s record: malformed DNS packet"), "SRV"); + return NULL; + } + + GETSHORT (priority, *p); + GETSHORT (weight, *p); + GETSHORT (port, *p); + + if (!expand_name ("SRV", answer, end, p, namebuf, sizeof (namebuf), error)) + return NULL; + + return g_variant_new ("(qqqs)", + priority, + weight, + port, + namebuf); +} + +static GVariant * +parse_res_soa (const guint8 *answer, + const guint8 *end, + const guint8 **p, + GError **error) +{ + gchar mnamebuf[1024]; + gchar rnamebuf[1024]; + guint32 serial, refresh, retry, expire, ttl; + + if (!expand_name ("SOA", answer, end, p, mnamebuf, sizeof (mnamebuf), error)) + return NULL; + + if (!expand_name ("SOA", answer, end, p, rnamebuf, sizeof (rnamebuf), error)) + return NULL; + + if (end - *p < 20) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ */ + _("Error parsing DNS %s record: malformed DNS packet"), "SOA"); + return NULL; + } + + GETLONG (serial, *p); + GETLONG (refresh, *p); + GETLONG (retry, *p); + GETLONG (expire, *p); + GETLONG (ttl, *p); + + return g_variant_new ("(ssuuuuu)", + mnamebuf, + rnamebuf, + serial, + refresh, + retry, + expire, + ttl); +} + +static GVariant * +parse_res_ns (const guint8 *answer, + const guint8 *end, + const guint8 **p, + GError **error) +{ + gchar namebuf[1024]; + + if (!expand_name ("NS", answer, end, p, namebuf, sizeof (namebuf), error)) + return NULL; + + return g_variant_new ("(s)", namebuf); +} + +static GVariant * +parse_res_mx (const guint8 *answer, + const guint8 *end, + const guint8 **p, + GError **error) +{ + gchar namebuf[1024]; + guint16 preference; + + if (end - *p < 2) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ */ + _("Error parsing DNS %s record: malformed DNS packet"), "MX"); + return NULL; + } + + GETSHORT (preference, *p); + + if (!expand_name ("MX", answer, end, p, namebuf, sizeof (namebuf), error)) + return NULL; + + return g_variant_new ("(qs)", + preference, + namebuf); +} + +static GVariant * +parse_res_txt (const guint8 *answer, + const guint8 *end, + const guint8 **p, + GError **error) +{ + GVariant *record; + GPtrArray *array; + const guint8 *at = *p; + gsize len; + + if (end - *p == 0) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ */ + _("Error parsing DNS %s record: malformed DNS packet"), "TXT"); + return NULL; + } + + array = g_ptr_array_new_with_free_func (g_free); + while (at < end) + { + len = *(at++); + if (len > (gsize) (end - at)) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ */ + _("Error parsing DNS %s record: malformed DNS packet"), "TXT"); + g_ptr_array_free (array, TRUE); + return NULL; + } + + g_ptr_array_add (array, g_strndup ((gchar *)at, len)); + at += len; + } + + *p = at; + record = g_variant_new ("(@as)", + g_variant_new_strv ((const gchar **)array->pdata, array->len)); + g_ptr_array_free (array, TRUE); + return record; +} + +gint +g_resolver_record_type_to_rrtype (GResolverRecordType type) +{ + switch (type) + { + case G_RESOLVER_RECORD_SRV: + return T_SRV; + case G_RESOLVER_RECORD_TXT: + return T_TXT; + case G_RESOLVER_RECORD_SOA: + return T_SOA; + case G_RESOLVER_RECORD_NS: + return T_NS; + case G_RESOLVER_RECORD_MX: + return T_MX; + } + g_return_val_if_reached (-1); +} + +GList * +g_resolver_records_from_res_query (const gchar *rrname, + gint rrtype, + const guint8 *answer, + gssize len, + gint herr, + GError **error) +{ + uint16_t count; + gchar namebuf[1024]; + const guint8 *end, *p; + guint16 type, qclass, rdlength; + const HEADER *header; + GList *records; + GVariant *record; + gsize len_unsigned; + GError *parsing_error = NULL; + + if (len <= 0) + { + if (len == 0 || herr == HOST_NOT_FOUND || herr == NO_DATA) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + _("No DNS record of the requested type for “%sâ€"), rrname); + } + else if (herr == TRY_AGAIN) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_TEMPORARY_FAILURE, + _("Temporarily unable to resolve “%sâ€"), rrname); + } + else + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + _("Error resolving “%sâ€"), rrname); + } + + return NULL; + } + + /* We know len ≥ 0 now. */ + len_unsigned = (gsize) len; + + if (len_unsigned < sizeof (HEADER)) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the first placeholder is a domain name, the + * second is an error message */ + _("Error resolving “%sâ€: %s"), rrname, _("Malformed DNS packet")); + return NULL; + } + + records = NULL; + + header = (HEADER *)answer; + p = answer + sizeof (HEADER); + end = answer + len_unsigned; + + /* Skip query */ + count = ntohs (header->qdcount); + while (count-- && p < end) + { + int expand_result; + + expand_result = dn_expand (answer, end, p, namebuf, sizeof (namebuf)); + if (expand_result < 0 || end - p < expand_result + 4) + { + /* Not possible to recover parsing as the length of the rest of the + * record is unknown or is too short. */ + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the first placeholder is a domain name, the + * second is an error message */ + _("Error resolving “%sâ€: %s"), rrname, _("Malformed DNS packet")); + return NULL; + } + + p += expand_result; + p += 4; /* skip TYPE and CLASS */ + + /* To silence gcc warnings */ + namebuf[0] = namebuf[1]; + } + + /* Read answers */ + count = ntohs (header->ancount); + while (count-- && p < end) + { + int expand_result; + + expand_result = dn_expand (answer, end, p, namebuf, sizeof (namebuf)); + if (expand_result < 0 || end - p < expand_result + 10) + { + /* Not possible to recover parsing as the length of the rest of the + * record is unknown or is too short. */ + g_set_error (&parsing_error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the first placeholder is a domain name, the + * second is an error message */ + _("Error resolving “%sâ€: %s"), rrname, _("Malformed DNS packet")); + break; + } + + p += expand_result; + GETSHORT (type, p); + GETSHORT (qclass, p); + p += 4; /* ignore the ttl (type=long) value */ + GETSHORT (rdlength, p); + + if (end - p < rdlength) + { + g_set_error (&parsing_error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + /* Translators: the first placeholder is a domain name, the + * second is an error message */ + _("Error resolving “%sâ€: %s"), rrname, _("Malformed DNS packet")); + break; + } + + if (type != rrtype || qclass != C_IN) + { + p += rdlength; + continue; + } + + switch (rrtype) + { + case T_SRV: + record = parse_res_srv (answer, p + rdlength, &p, &parsing_error); + break; + case T_MX: + record = parse_res_mx (answer, p + rdlength, &p, &parsing_error); + break; + case T_SOA: + record = parse_res_soa (answer, p + rdlength, &p, &parsing_error); + break; + case T_NS: + record = parse_res_ns (answer, p + rdlength, &p, &parsing_error); + break; + case T_TXT: + record = parse_res_txt (answer, p + rdlength, &p, &parsing_error); + break; + default: + g_debug ("Unrecognised DNS record type %u", rrtype); + record = NULL; + break; + } + + if (record != NULL) + records = g_list_prepend (records, record); + + if (parsing_error != NULL) + break; + } + + if (parsing_error != NULL) + { + g_propagate_prefixed_error (error, parsing_error, _("Failed to parse DNS response for “%sâ€: "), rrname); + g_list_free_full (records, (GDestroyNotify)g_variant_unref); + return NULL; + } + else if (records == NULL) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + _("No DNS record of the requested type for “%sâ€"), rrname); + + return NULL; + } + else + return records; +} + +#elif defined(G_OS_WIN32) + +static GVariant * +parse_dns_srv (DNS_RECORD *rec) +{ + return g_variant_new ("(qqqs)", + (guint16)rec->Data.SRV.wPriority, + (guint16)rec->Data.SRV.wWeight, + (guint16)rec->Data.SRV.wPort, + rec->Data.SRV.pNameTarget); +} + +static GVariant * +parse_dns_soa (DNS_RECORD *rec) +{ + return g_variant_new ("(ssuuuuu)", + rec->Data.SOA.pNamePrimaryServer, + rec->Data.SOA.pNameAdministrator, + (guint32)rec->Data.SOA.dwSerialNo, + (guint32)rec->Data.SOA.dwRefresh, + (guint32)rec->Data.SOA.dwRetry, + (guint32)rec->Data.SOA.dwExpire, + (guint32)rec->Data.SOA.dwDefaultTtl); +} + +static GVariant * +parse_dns_ns (DNS_RECORD *rec) +{ + return g_variant_new ("(s)", rec->Data.NS.pNameHost); +} + +static GVariant * +parse_dns_mx (DNS_RECORD *rec) +{ + return g_variant_new ("(qs)", + (guint16)rec->Data.MX.wPreference, + rec->Data.MX.pNameExchange); +} + +static GVariant * +parse_dns_txt (DNS_RECORD *rec) +{ + GVariant *record; + GPtrArray *array; + DWORD i; + + array = g_ptr_array_new (); + for (i = 0; i < rec->Data.TXT.dwStringCount; i++) + g_ptr_array_add (array, rec->Data.TXT.pStringArray[i]); + record = g_variant_new ("(@as)", + g_variant_new_strv ((const gchar **)array->pdata, array->len)); + g_ptr_array_free (array, TRUE); + return record; +} + +static WORD +g_resolver_record_type_to_dnstype (GResolverRecordType type) +{ + switch (type) + { + case G_RESOLVER_RECORD_SRV: + return DNS_TYPE_SRV; + case G_RESOLVER_RECORD_TXT: + return DNS_TYPE_TEXT; + case G_RESOLVER_RECORD_SOA: + return DNS_TYPE_SOA; + case G_RESOLVER_RECORD_NS: + return DNS_TYPE_NS; + case G_RESOLVER_RECORD_MX: + return DNS_TYPE_MX; + } + g_return_val_if_reached (-1); +} + +static GList * +g_resolver_records_from_DnsQuery (const gchar *rrname, + WORD dnstype, + DNS_STATUS status, + DNS_RECORD *results, + GError **error) +{ + DNS_RECORD *rec; + gpointer record; + GList *records; + + if (status != ERROR_SUCCESS) + { + if (status == DNS_ERROR_RCODE_NAME_ERROR) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + _("No DNS record of the requested type for “%sâ€"), rrname); + } + else if (status == DNS_ERROR_RCODE_SERVER_FAILURE) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_TEMPORARY_FAILURE, + _("Temporarily unable to resolve “%sâ€"), rrname); + } + else + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + _("Error resolving “%sâ€"), rrname); + } + + return NULL; + } + + records = NULL; + for (rec = results; rec; rec = rec->pNext) + { + if (rec->wType != dnstype) + continue; + switch (dnstype) + { + case DNS_TYPE_SRV: + record = parse_dns_srv (rec); + break; + case DNS_TYPE_SOA: + record = parse_dns_soa (rec); + break; + case DNS_TYPE_NS: + record = parse_dns_ns (rec); + break; + case DNS_TYPE_MX: + record = parse_dns_mx (rec); + break; + case DNS_TYPE_TEXT: + record = parse_dns_txt (rec); + break; + default: + g_warn_if_reached (); + record = NULL; + break; + } + if (record != NULL) + records = g_list_prepend (records, g_variant_ref_sink (record)); + } + + if (records == NULL) + { + g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + _("No DNS record of the requested type for “%sâ€"), rrname); + + return NULL; + } + else + return records; +} + +#endif + +typedef struct { + char *rrname; + GResolverRecordType record_type; +} LookupRecordsData; + +static void +free_lookup_records_data (LookupRecordsData *lrd) +{ + g_free (lrd->rrname); + g_slice_free (LookupRecordsData, lrd); +} + +static void +free_records (GList *records) +{ + g_list_free_full (records, (GDestroyNotify) g_variant_unref); +} + +#if defined(G_OS_UNIX) +#ifdef __BIONIC__ +#ifndef C_IN +#define C_IN 1 +#endif +int res_query(const char *, int, int, u_char *, int); +#endif +#endif + +static void +do_lookup_records (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + LookupRecordsData *lrd = task_data; + GList *records; + GError *error = NULL; + +#if defined(G_OS_UNIX) + gint len = 512; + gint herr; + GByteArray *answer; + gint rrtype; + +#ifdef HAVE_RES_NQUERY + /* Load the resolver state. This is done once per worker thread, and the + * #GResolver::reload signal is ignored (since we always reload). This could + * be improved by having an explicit worker thread pool, with each thread + * containing some state which is initialised at thread creation time and + * updated in response to #GResolver::reload. + * + * What we have currently is not particularly worse than using res_query() in + * worker threads, since it would transparently call res_init() for each new + * worker thread. (Although the workers would get reused by the + * #GThreadPool.) + * + * FreeBSD requires the state to be zero-filled before calling res_ninit(). */ + struct __res_state res = { 0, }; + if (res_ninit (&res) != 0) + { + g_task_return_new_error (task, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL, + _("Error resolving “%sâ€"), lrd->rrname); + return; + } +#endif + + rrtype = g_resolver_record_type_to_rrtype (lrd->record_type); + answer = g_byte_array_new (); + for (;;) + { + g_byte_array_set_size (answer, len * 2); +#if defined(HAVE_RES_NQUERY) + len = res_nquery (&res, lrd->rrname, C_IN, rrtype, answer->data, answer->len); +#else + len = res_query (lrd->rrname, C_IN, rrtype, answer->data, answer->len); +#endif + + /* If answer fit in the buffer then we're done */ + if (len < 0 || len < (gint)answer->len) + break; + + /* + * On overflow some res_query's return the length needed, others + * return the full length entered. This code works in either case. + */ + } + + herr = h_errno; + records = g_resolver_records_from_res_query (lrd->rrname, rrtype, answer->data, len, herr, &error); + g_byte_array_free (answer, TRUE); + +#ifdef HAVE_RES_NQUERY + +#if defined(HAVE_RES_NDESTROY) + res_ndestroy (&res); +#elif defined(HAVE_RES_NCLOSE) + res_nclose (&res); +#elif defined(HAVE_RES_NINIT) +#error "Your platform has res_ninit() but not res_nclose() or res_ndestroy(). Please file a bug at https://gitlab.gnome.org/GNOME/glib/issues/new" +#endif + +#endif /* HAVE_RES_NQUERY */ + +#else + + DNS_STATUS status; + DNS_RECORD *results = NULL; + WORD dnstype; + + dnstype = g_resolver_record_type_to_dnstype (lrd->record_type); + status = DnsQuery_A (lrd->rrname, dnstype, DNS_QUERY_STANDARD, NULL, &results, NULL); + records = g_resolver_records_from_DnsQuery (lrd->rrname, dnstype, status, results, &error); + if (results != NULL) + DnsRecordListFree (results, DnsFreeRecordList); + +#endif + + if (records) + g_task_return_pointer (task, records, (GDestroyNotify) free_records); + else + g_task_return_error (task, error); +} + +static GList * +lookup_records (GResolver *resolver, + const gchar *rrname, + GResolverRecordType record_type, + GCancellable *cancellable, + GError **error) +{ + GTask *task; + GList *records; + LookupRecordsData *lrd; + + task = g_task_new (resolver, cancellable, NULL, NULL); + g_task_set_source_tag (task, lookup_records); + g_task_set_name (task, "[gio] resolver lookup records"); + + lrd = g_slice_new (LookupRecordsData); + lrd->rrname = g_strdup (rrname); + lrd->record_type = record_type; + g_task_set_task_data (task, lrd, (GDestroyNotify) free_lookup_records_data); + + g_task_set_return_on_cancel (task, TRUE); + g_task_run_in_thread_sync (task, do_lookup_records); + records = g_task_propagate_pointer (task, error); + g_object_unref (task); + + return records; +} + +static void +lookup_records_async (GResolver *resolver, + const char *rrname, + GResolverRecordType record_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + LookupRecordsData *lrd; + + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, lookup_records_async); + g_task_set_name (task, "[gio] resolver lookup records"); + + lrd = g_slice_new (LookupRecordsData); + lrd->rrname = g_strdup (rrname); + lrd->record_type = record_type; + g_task_set_task_data (task, lrd, (GDestroyNotify) free_lookup_records_data); + + g_task_set_return_on_cancel (task, TRUE); + g_task_run_in_thread (task, do_lookup_records); + g_object_unref (task); +} + +static GList * +lookup_records_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, resolver), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + + +static void +g_threaded_resolver_class_init (GThreadedResolverClass *threaded_class) +{ + GResolverClass *resolver_class = G_RESOLVER_CLASS (threaded_class); + + resolver_class->lookup_by_name = lookup_by_name; + resolver_class->lookup_by_name_async = lookup_by_name_async; + resolver_class->lookup_by_name_finish = lookup_by_name_finish; + resolver_class->lookup_by_name_with_flags = lookup_by_name_with_flags; + resolver_class->lookup_by_name_with_flags_async = lookup_by_name_with_flags_async; + resolver_class->lookup_by_name_with_flags_finish = lookup_by_name_with_flags_finish; + resolver_class->lookup_by_address = lookup_by_address; + resolver_class->lookup_by_address_async = lookup_by_address_async; + resolver_class->lookup_by_address_finish = lookup_by_address_finish; + resolver_class->lookup_records = lookup_records; + resolver_class->lookup_records_async = lookup_records_async; + resolver_class->lookup_records_finish = lookup_records_finish; +} diff --git a/gio/gthreadedresolver.h b/gio/gthreadedresolver.h new file mode 100644 index 0000000..8d2ca19 --- /dev/null +++ b/gio/gthreadedresolver.h @@ -0,0 +1,60 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_THREADED_RESOLVER_H__ +#define __G_THREADED_RESOLVER_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_THREADED_RESOLVER (g_threaded_resolver_get_type ()) +#define G_THREADED_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_THREADED_RESOLVER, GThreadedResolver)) +#define G_THREADED_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_THREADED_RESOLVER, GThreadedResolverClass)) +#define G_IS_THREADED_RESOLVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_THREADED_RESOLVER)) +#define G_IS_THREADED_RESOLVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_THREADED_RESOLVER)) +#define G_THREADED_RESOLVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_THREADED_RESOLVER, GThreadedResolverClass)) + +typedef struct { + GResolver parent_instance; +} GThreadedResolver; + +typedef struct { + GResolverClass parent_class; + +} GThreadedResolverClass; + +GLIB_AVAILABLE_IN_ALL +GType g_threaded_resolver_get_type (void) G_GNUC_CONST; + +/* Used for a private test API */ +#ifdef G_OS_UNIX +GLIB_AVAILABLE_IN_ALL +GList *g_resolver_records_from_res_query (const gchar *rrname, + gint rrtype, + const guint8 *answer, + gssize len, + gint herr, + GError **error); +GLIB_AVAILABLE_IN_ALL +gint g_resolver_record_type_to_rrtype (GResolverRecordType type); +#endif + +G_END_DECLS + +#endif /* __G_RESOLVER_H__ */ diff --git a/gio/gthreadedsocketservice.c b/gio/gthreadedsocketservice.c new file mode 100644 index 0000000..6416e3a --- /dev/null +++ b/gio/gthreadedsocketservice.c @@ -0,0 +1,277 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * Copyright © 2009 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Alexander Larsson + */ + +/** + * SECTION:gthreadedsocketservice + * @title: GThreadedSocketService + * @short_description: A threaded GSocketService + * @include: gio/gio.h + * @see_also: #GSocketService. + * + * A #GThreadedSocketService is a simple subclass of #GSocketService + * that handles incoming connections by creating a worker thread and + * dispatching the connection to it by emitting the + * #GThreadedSocketService::run signal in the new thread. + * + * The signal handler may perform blocking IO and need not return + * until the connection is closed. + * + * The service is implemented using a thread pool, so there is a + * limited amount of threads available to serve incoming requests. + * The service automatically stops the #GSocketService from accepting + * new connections when all threads are busy. + * + * As with #GSocketService, you may connect to #GThreadedSocketService::run, + * or subclass and override the default handler. + */ + +#include "config.h" +#include "gsocketconnection.h" +#include "gthreadedsocketservice.h" +#include "glibintl.h" +#include "gmarshal-internal.h" + +struct _GThreadedSocketServicePrivate +{ + GThreadPool *thread_pool; + int max_threads; + gint job_count; +}; + +static guint g_threaded_socket_service_run_signal; + +G_DEFINE_TYPE_WITH_PRIVATE (GThreadedSocketService, + g_threaded_socket_service, + G_TYPE_SOCKET_SERVICE) + +typedef enum +{ + PROP_MAX_THREADS = 1, +} GThreadedSocketServiceProperty; + +G_LOCK_DEFINE_STATIC(job_count); + +typedef struct +{ + GThreadedSocketService *service; /* (owned) */ + GSocketConnection *connection; /* (owned) */ + GObject *source_object; /* (owned) (nullable) */ +} GThreadedSocketServiceData; + +static void +g_threaded_socket_service_data_free (GThreadedSocketServiceData *data) +{ + g_clear_object (&data->service); + g_clear_object (&data->connection); + g_clear_object (&data->source_object); + g_slice_free (GThreadedSocketServiceData, data); +} + +static void +g_threaded_socket_service_func (gpointer job_data, + gpointer user_data) +{ + GThreadedSocketServiceData *data = job_data; + gboolean result; + + g_signal_emit (data->service, g_threaded_socket_service_run_signal, + 0, data->connection, data->source_object, &result); + + G_LOCK (job_count); + if (data->service->priv->job_count-- == data->service->priv->max_threads) + g_socket_service_start (G_SOCKET_SERVICE (data->service)); + G_UNLOCK (job_count); + + g_threaded_socket_service_data_free (data); +} + +static gboolean +g_threaded_socket_service_incoming (GSocketService *service, + GSocketConnection *connection, + GObject *source_object) +{ + GThreadedSocketService *threaded; + GThreadedSocketServiceData *data; + GError *local_error = NULL; + + threaded = G_THREADED_SOCKET_SERVICE (service); + + data = g_slice_new0 (GThreadedSocketServiceData); + data->service = g_object_ref (threaded); + data->connection = g_object_ref (connection); + data->source_object = (source_object != NULL) ? g_object_ref (source_object) : NULL; + + G_LOCK (job_count); + if (++threaded->priv->job_count == threaded->priv->max_threads) + g_socket_service_stop (service); + G_UNLOCK (job_count); + + if (!g_thread_pool_push (threaded->priv->thread_pool, data, &local_error)) + { + g_warning ("Error handling incoming socket: %s", local_error->message); + g_threaded_socket_service_data_free (data); + } + + g_clear_error (&local_error); + + return FALSE; +} + +static void +g_threaded_socket_service_init (GThreadedSocketService *service) +{ + service->priv = g_threaded_socket_service_get_instance_private (service); + service->priv->max_threads = 10; +} + +static void +g_threaded_socket_service_constructed (GObject *object) +{ + GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); + + service->priv->thread_pool = + g_thread_pool_new (g_threaded_socket_service_func, + NULL, + service->priv->max_threads, + FALSE, + NULL); +} + + +static void +g_threaded_socket_service_finalize (GObject *object) +{ + GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); + + /* All jobs in the pool hold a reference to this #GThreadedSocketService, so + * this should only be called once the pool is empty: */ + g_thread_pool_free (service->priv->thread_pool, FALSE, FALSE); + + G_OBJECT_CLASS (g_threaded_socket_service_parent_class) + ->finalize (object); +} + +static void +g_threaded_socket_service_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); + + switch ((GThreadedSocketServiceProperty) prop_id) + { + case PROP_MAX_THREADS: + g_value_set_int (value, service->priv->max_threads); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_threaded_socket_service_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); + + switch ((GThreadedSocketServiceProperty) prop_id) + { + case PROP_MAX_THREADS: + service->priv->max_threads = g_value_get_int (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + + +static void +g_threaded_socket_service_class_init (GThreadedSocketServiceClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + GSocketServiceClass *ss_class = &class->parent_class; + + gobject_class->constructed = g_threaded_socket_service_constructed; + gobject_class->finalize = g_threaded_socket_service_finalize; + gobject_class->set_property = g_threaded_socket_service_set_property; + gobject_class->get_property = g_threaded_socket_service_get_property; + + ss_class->incoming = g_threaded_socket_service_incoming; + + /** + * GThreadedSocketService::run: + * @service: the #GThreadedSocketService. + * @connection: a new #GSocketConnection object. + * @source_object: (nullable): the source_object passed to g_socket_listener_add_address(). + * + * The ::run signal is emitted in a worker thread in response to an + * incoming connection. This thread is dedicated to handling + * @connection and may perform blocking IO. The signal handler need + * not return until the connection is closed. + * + * Returns: %TRUE to stop further signal handlers from being called + */ + g_threaded_socket_service_run_signal = + g_signal_new (I_("run"), G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GThreadedSocketServiceClass, run), + g_signal_accumulator_true_handled, NULL, + _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECT, + G_TYPE_BOOLEAN, + 2, G_TYPE_SOCKET_CONNECTION, G_TYPE_OBJECT); + g_signal_set_va_marshaller (g_threaded_socket_service_run_signal, + G_TYPE_FROM_CLASS (class), + _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECTv); + + g_object_class_install_property (gobject_class, PROP_MAX_THREADS, + g_param_spec_int ("max-threads", + P_("Max threads"), + P_("The max number of threads handling clients for this service"), + -1, + G_MAXINT, + 10, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +/** + * g_threaded_socket_service_new: + * @max_threads: the maximal number of threads to execute concurrently + * handling incoming clients, -1 means no limit + * + * Creates a new #GThreadedSocketService with no listeners. Listeners + * must be added with one of the #GSocketListener "add" methods. + * + * Returns: a new #GSocketService. + * + * Since: 2.22 + */ +GSocketService * +g_threaded_socket_service_new (int max_threads) +{ + return g_object_new (G_TYPE_THREADED_SOCKET_SERVICE, + "max-threads", max_threads, + NULL); +} diff --git a/gio/gthreadedsocketservice.h b/gio/gthreadedsocketservice.h new file mode 100644 index 0000000..fa3204f --- /dev/null +++ b/gio/gthreadedsocketservice.h @@ -0,0 +1,81 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * Copyright © 2009 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + * Alexander Larsson + */ + +#ifndef __G_THREADED_SOCKET_SERVICE_H__ +#define __G_THREADED_SOCKET_SERVICE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_THREADED_SOCKET_SERVICE (g_threaded_socket_service_get_type ()) +#define G_THREADED_SOCKET_SERVICE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_THREADED_SOCKET_SERVICE, \ + GThreadedSocketService)) +#define G_THREADED_SOCKET_SERVICE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_THREADED_SOCKET_SERVICE, \ + GThreadedSocketServiceClass)) +#define G_IS_THREADED_SOCKET_SERVICE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_THREADED_SOCKET_SERVICE)) +#define G_IS_THREADED_SOCKET_SERVICE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_THREADED_SOCKET_SERVICE)) +#define G_THREADED_SOCKET_SERVICE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_THREADED_SOCKET_SERVICE, \ + GThreadedSocketServiceClass)) + +typedef struct _GThreadedSocketServicePrivate GThreadedSocketServicePrivate; +typedef struct _GThreadedSocketServiceClass GThreadedSocketServiceClass; + +struct _GThreadedSocketServiceClass +{ + GSocketServiceClass parent_class; + + gboolean (* run) (GThreadedSocketService *service, + GSocketConnection *connection, + GObject *source_object); + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +struct _GThreadedSocketService +{ + GSocketService parent_instance; + GThreadedSocketServicePrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_threaded_socket_service_get_type (void); +GLIB_AVAILABLE_IN_ALL +GSocketService * g_threaded_socket_service_new (int max_threads); + +G_END_DECLS + +#endif /* __G_THREADED_SOCKET_SERVICE_H__ */ diff --git a/gio/gtlsbackend.c b/gio/gtlsbackend.c new file mode 100644 index 0000000..25569aa --- /dev/null +++ b/gio/gtlsbackend.c @@ -0,0 +1,348 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" + +#include "gtlsbackend.h" +#include "gtlsdatabase.h" +#include "gdummytlsbackend.h" +#include "gioenumtypes.h" +#include "giomodule-priv.h" + +/** + * SECTION:gtls + * @title: TLS Overview + * @short_description: TLS (aka SSL) support for GSocketConnection + * @include: gio/gio.h + * + * #GTlsConnection and related classes provide TLS (Transport Layer + * Security, previously known as SSL, Secure Sockets Layer) support for + * gio-based network streams. + * + * #GDtlsConnection and related classes provide DTLS (Datagram TLS) support for + * GIO-based network sockets, using the #GDatagramBased interface. The TLS and + * DTLS APIs are almost identical, except TLS is stream-based and DTLS is + * datagram-based. They share certificate and backend infrastructure. + * + * In the simplest case, for a client TLS connection, you can just set the + * #GSocketClient:tls flag on a #GSocketClient, and then any + * connections created by that client will have TLS negotiated + * automatically, using appropriate default settings, and rejecting + * any invalid or self-signed certificates (unless you change that + * default by setting the #GSocketClient:tls-validation-flags + * property). The returned object will be a #GTcpWrapperConnection, + * which wraps the underlying #GTlsClientConnection. + * + * For greater control, you can create your own #GTlsClientConnection, + * wrapping a #GSocketConnection (or an arbitrary #GIOStream with + * pollable input and output streams) and then connect to its signals, + * such as #GTlsConnection::accept-certificate, before starting the + * handshake. + * + * Server-side TLS is similar, using #GTlsServerConnection. At the + * moment, there is no support for automatically wrapping server-side + * connections in the way #GSocketClient does for client-side + * connections. + */ + +/** + * SECTION:gtlsbackend + * @title: GTlsBackend + * @short_description: TLS backend implementation + * @include: gio/gio.h + * + * TLS (Transport Layer Security, aka SSL) and DTLS backend. + * + * Since: 2.28 + */ + +/** + * GTlsBackend: + * + * TLS (Transport Layer Security, aka SSL) and DTLS backend. This is an + * internal type used to coordinate the different classes implemented + * by a TLS backend. + * + * Since: 2.28 + */ + +G_DEFINE_INTERFACE (GTlsBackend, g_tls_backend, G_TYPE_OBJECT) + +static GTlsDatabase *default_database; +G_LOCK_DEFINE_STATIC (default_database_lock); + +static void +g_tls_backend_default_init (GTlsBackendInterface *iface) +{ +} + +static GTlsBackend *tls_backend_default_singleton = NULL; /* (owned) (atomic) */ + +/** + * g_tls_backend_get_default: + * + * Gets the default #GTlsBackend for the system. + * + * Returns: (not nullable) (transfer none): a #GTlsBackend, which will be a + * dummy object if no TLS backend is available + * + * Since: 2.28 + */ +GTlsBackend * +g_tls_backend_get_default (void) +{ + if (g_once_init_enter (&tls_backend_default_singleton)) + { + GTlsBackend *singleton; + + singleton = _g_io_module_get_default (G_TLS_BACKEND_EXTENSION_POINT_NAME, + "GIO_USE_TLS", + NULL); + + g_once_init_leave (&tls_backend_default_singleton, singleton); + } + + return tls_backend_default_singleton; +} + +/** + * g_tls_backend_supports_tls: + * @backend: the #GTlsBackend + * + * Checks if TLS is supported; if this returns %FALSE for the default + * #GTlsBackend, it means no "real" TLS backend is available. + * + * Returns: whether or not TLS is supported + * + * Since: 2.28 + */ +gboolean +g_tls_backend_supports_tls (GTlsBackend *backend) +{ + if (G_TLS_BACKEND_GET_INTERFACE (backend)->supports_tls) + return G_TLS_BACKEND_GET_INTERFACE (backend)->supports_tls (backend); + else if (G_IS_DUMMY_TLS_BACKEND (backend)) + return FALSE; + else + return TRUE; +} + +/** + * g_tls_backend_supports_dtls: + * @backend: the #GTlsBackend + * + * Checks if DTLS is supported. DTLS support may not be available even if TLS + * support is available, and vice-versa. + * + * Returns: whether DTLS is supported + * + * Since: 2.48 + */ +gboolean +g_tls_backend_supports_dtls (GTlsBackend *backend) +{ + if (G_TLS_BACKEND_GET_INTERFACE (backend)->supports_dtls) + return G_TLS_BACKEND_GET_INTERFACE (backend)->supports_dtls (backend); + + return FALSE; +} + +/** + * g_tls_backend_get_default_database: + * @backend: the #GTlsBackend + * + * Gets the default #GTlsDatabase used to verify TLS connections. + * + * Returns: (transfer full): the default database, which should be + * unreffed when done. + * + * Since: 2.30 + */ +GTlsDatabase * +g_tls_backend_get_default_database (GTlsBackend *backend) +{ + GTlsDatabase *db; + + g_return_val_if_fail (G_IS_TLS_BACKEND (backend), NULL); + + /* This method was added later, so accept the (remote) possibility it can be NULL */ + if (!G_TLS_BACKEND_GET_INTERFACE (backend)->get_default_database) + return NULL; + + G_LOCK (default_database_lock); + + if (!default_database) + default_database = G_TLS_BACKEND_GET_INTERFACE (backend)->get_default_database (backend); + db = default_database ? g_object_ref (default_database) : NULL; + G_UNLOCK (default_database_lock); + + return db; +} + +/** + * g_tls_backend_set_default_database: + * @backend: the #GTlsBackend + * @database: (nullable): the #GTlsDatabase + * + * Set the default #GTlsDatabase used to verify TLS connections + * + * Any subsequent call to g_tls_backend_get_default_database() will return + * the database set in this call. Existing databases and connections are not + * modified. + * + * Setting a %NULL default database will reset to using the system default + * database as if g_tls_backend_set_default_database() had never been called. + * + * Since: 2.60 + */ +void +g_tls_backend_set_default_database (GTlsBackend *backend, + GTlsDatabase *database) +{ + g_return_if_fail (G_IS_TLS_BACKEND (backend)); + g_return_if_fail (database == NULL || G_IS_TLS_DATABASE (database)); + + G_LOCK (default_database_lock); + g_set_object (&default_database, database); + G_UNLOCK (default_database_lock); +} + +/** + * g_tls_backend_get_certificate_type: + * @backend: the #GTlsBackend + * + * Gets the #GType of @backend's #GTlsCertificate implementation. + * + * Returns: the #GType of @backend's #GTlsCertificate + * implementation. + * + * Since: 2.28 + */ +GType +g_tls_backend_get_certificate_type (GTlsBackend *backend) +{ + return G_TLS_BACKEND_GET_INTERFACE (backend)->get_certificate_type (); +} + +/** + * g_tls_backend_get_client_connection_type: + * @backend: the #GTlsBackend + * + * Gets the #GType of @backend's #GTlsClientConnection implementation. + * + * Returns: the #GType of @backend's #GTlsClientConnection + * implementation. + * + * Since: 2.28 + */ +GType +g_tls_backend_get_client_connection_type (GTlsBackend *backend) +{ + return G_TLS_BACKEND_GET_INTERFACE (backend)->get_client_connection_type (); +} + +/** + * g_tls_backend_get_server_connection_type: + * @backend: the #GTlsBackend + * + * Gets the #GType of @backend's #GTlsServerConnection implementation. + * + * Returns: the #GType of @backend's #GTlsServerConnection + * implementation. + * + * Since: 2.28 + */ +GType +g_tls_backend_get_server_connection_type (GTlsBackend *backend) +{ + return G_TLS_BACKEND_GET_INTERFACE (backend)->get_server_connection_type (); +} + +/** + * g_tls_backend_get_dtls_client_connection_type: + * @backend: the #GTlsBackend + * + * Gets the #GType of @backend’s #GDtlsClientConnection implementation. + * + * Returns: the #GType of @backend’s #GDtlsClientConnection + * implementation, or %G_TYPE_INVALID if this backend doesn’t support DTLS. + * + * Since: 2.48 + */ +GType +g_tls_backend_get_dtls_client_connection_type (GTlsBackend *backend) +{ + GTlsBackendInterface *iface; + + g_return_val_if_fail (G_IS_TLS_BACKEND (backend), G_TYPE_INVALID); + + iface = G_TLS_BACKEND_GET_INTERFACE (backend); + if (iface->get_dtls_client_connection_type == NULL) + return G_TYPE_INVALID; + + return iface->get_dtls_client_connection_type (); +} + +/** + * g_tls_backend_get_dtls_server_connection_type: + * @backend: the #GTlsBackend + * + * Gets the #GType of @backend’s #GDtlsServerConnection implementation. + * + * Returns: the #GType of @backend’s #GDtlsServerConnection + * implementation, or %G_TYPE_INVALID if this backend doesn’t support DTLS. + * + * Since: 2.48 + */ +GType +g_tls_backend_get_dtls_server_connection_type (GTlsBackend *backend) +{ + GTlsBackendInterface *iface; + + g_return_val_if_fail (G_IS_TLS_BACKEND (backend), G_TYPE_INVALID); + + iface = G_TLS_BACKEND_GET_INTERFACE (backend); + if (iface->get_dtls_server_connection_type == NULL) + return G_TYPE_INVALID; + + return iface->get_dtls_server_connection_type (); +} + +/** + * g_tls_backend_get_file_database_type: + * @backend: the #GTlsBackend + * + * Gets the #GType of @backend's #GTlsFileDatabase implementation. + * + * Returns: the #GType of backend's #GTlsFileDatabase implementation. + * + * Since: 2.30 + */ +GType +g_tls_backend_get_file_database_type (GTlsBackend *backend) +{ + g_return_val_if_fail (G_IS_TLS_BACKEND (backend), 0); + + /* This method was added later, so accept the (remote) possibility it can be NULL */ + if (!G_TLS_BACKEND_GET_INTERFACE (backend)->get_file_database_type) + return 0; + + return G_TLS_BACKEND_GET_INTERFACE (backend)->get_file_database_type (); +} diff --git a/gio/gtlsbackend.h b/gio/gtlsbackend.h new file mode 100644 index 0000000..f19ab7e --- /dev/null +++ b/gio/gtlsbackend.h @@ -0,0 +1,113 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * Copyright © 2015 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_TLS_BACKEND_H__ +#define __G_TLS_BACKEND_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_TLS_BACKEND_EXTENSION_POINT_NAME: + * + * Extension point for TLS functionality via #GTlsBackend. + * See [Extending GIO][extending-gio]. + */ +#define G_TLS_BACKEND_EXTENSION_POINT_NAME "gio-tls-backend" + +#define G_TYPE_TLS_BACKEND (g_tls_backend_get_type ()) +#define G_TLS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_TLS_BACKEND, GTlsBackend)) +#define G_IS_TLS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_TLS_BACKEND)) +#define G_TLS_BACKEND_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_TLS_BACKEND, GTlsBackendInterface)) + +typedef struct _GTlsBackend GTlsBackend; +typedef struct _GTlsBackendInterface GTlsBackendInterface; + +/** + * GTlsBackendInterface: + * @g_iface: The parent interface. + * @supports_tls: returns whether the backend supports TLS. + * @supports_dtls: returns whether the backend supports DTLS + * @get_default_database: returns a default #GTlsDatabase instance. + * @get_certificate_type: returns the #GTlsCertificate implementation type + * @get_client_connection_type: returns the #GTlsClientConnection implementation type + * @get_server_connection_type: returns the #GTlsServerConnection implementation type + * @get_file_database_type: returns the #GTlsFileDatabase implementation type. + * @get_dtls_client_connection_type: returns the #GDtlsClientConnection implementation type + * @get_dtls_server_connection_type: returns the #GDtlsServerConnection implementation type + * + * Provides an interface for describing TLS-related types. + * + * Since: 2.28 + */ +struct _GTlsBackendInterface +{ + GTypeInterface g_iface; + + /* methods */ + gboolean ( *supports_tls) (GTlsBackend *backend); + GType ( *get_certificate_type) (void); + GType ( *get_client_connection_type) (void); + GType ( *get_server_connection_type) (void); + GType ( *get_file_database_type) (void); + GTlsDatabase * ( *get_default_database) (GTlsBackend *backend); + gboolean ( *supports_dtls) (GTlsBackend *backend); + GType ( *get_dtls_client_connection_type) (void); + GType ( *get_dtls_server_connection_type) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_backend_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GTlsBackend * g_tls_backend_get_default (void); + +GLIB_AVAILABLE_IN_ALL +GTlsDatabase * g_tls_backend_get_default_database (GTlsBackend *backend); +GLIB_AVAILABLE_IN_2_60 +void g_tls_backend_set_default_database (GTlsBackend *backend, + GTlsDatabase *database); + +GLIB_AVAILABLE_IN_ALL +gboolean g_tls_backend_supports_tls (GTlsBackend *backend); +GLIB_AVAILABLE_IN_2_48 +gboolean g_tls_backend_supports_dtls (GTlsBackend *backend); + +GLIB_AVAILABLE_IN_ALL +GType g_tls_backend_get_certificate_type (GTlsBackend *backend); +GLIB_AVAILABLE_IN_ALL +GType g_tls_backend_get_client_connection_type (GTlsBackend *backend); +GLIB_AVAILABLE_IN_ALL +GType g_tls_backend_get_server_connection_type (GTlsBackend *backend); +GLIB_AVAILABLE_IN_ALL +GType g_tls_backend_get_file_database_type (GTlsBackend *backend); + +GLIB_AVAILABLE_IN_2_48 +GType g_tls_backend_get_dtls_client_connection_type (GTlsBackend *backend); +GLIB_AVAILABLE_IN_2_48 +GType g_tls_backend_get_dtls_server_connection_type (GTlsBackend *backend); + +G_END_DECLS + +#endif /* __G_TLS_BACKEND_H__ */ diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c new file mode 100644 index 0000000..9751170 --- /dev/null +++ b/gio/gtlscertificate.c @@ -0,0 +1,1330 @@ +/* GIO - GLib Input, Output and Certificateing Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gtlscertificate.h" + +#include +#include "ginitable.h" +#include "gtlsbackend.h" +#include "gtlsconnection.h" +#include "glibintl.h" + +/** + * SECTION:gtlscertificate + * @title: GTlsCertificate + * @short_description: TLS certificate + * @include: gio/gio.h + * @see_also: #GTlsConnection + * + * A certificate used for TLS authentication and encryption. + * This can represent either a certificate only (eg, the certificate + * received by a client from a server), or the combination of + * a certificate and a private key (which is needed when acting as a + * #GTlsServerConnection). + * + * Since: 2.28 + */ + +/** + * GTlsCertificate: + * + * Abstract base class for TLS certificate types. + * + * Since: 2.28 + */ + +struct _GTlsCertificatePrivate { + gboolean pkcs12_properties_not_overridden; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GTlsCertificate, g_tls_certificate, G_TYPE_OBJECT) + +enum +{ + PROP_0, + + PROP_CERTIFICATE, + PROP_CERTIFICATE_PEM, + PROP_PRIVATE_KEY, + PROP_PRIVATE_KEY_PEM, + PROP_ISSUER, + PROP_PKCS11_URI, + PROP_PRIVATE_KEY_PKCS11_URI, + PROP_NOT_VALID_BEFORE, + PROP_NOT_VALID_AFTER, + PROP_SUBJECT_NAME, + PROP_ISSUER_NAME, + PROP_DNS_NAMES, + PROP_IP_ADDRESSES, + PROP_PKCS12_DATA, + PROP_PASSWORD, +}; + +static void +g_tls_certificate_init (GTlsCertificate *cert) +{ +} + +static void +g_tls_certificate_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + /* Subclasses must override these properties but this allows older backends to not fatally error */ + case PROP_PRIVATE_KEY: + case PROP_PRIVATE_KEY_PEM: + case PROP_PKCS11_URI: + case PROP_PRIVATE_KEY_PKCS11_URI: + g_value_set_static_string (value, NULL); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_tls_certificate_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTlsCertificate *cert = (GTlsCertificate*)object; + GTlsCertificatePrivate *priv = g_tls_certificate_get_instance_private (cert); + + switch (prop_id) + { + case PROP_PKCS11_URI: + case PROP_PRIVATE_KEY_PKCS11_URI: + /* Subclasses must override these properties but this allows older backends to not fatally error. */ + break; + case PROP_PKCS12_DATA: + case PROP_PASSWORD: + /* We don't error on setting these properties however we track that they were not overridden. */ + priv->pkcs12_properties_not_overridden = TRUE; + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_tls_certificate_class_init (GTlsCertificateClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->set_property = g_tls_certificate_set_property; + gobject_class->get_property = g_tls_certificate_get_property; + + /** + * GTlsCertificate:pkcs12-data: (nullable) + * + * The PKCS #12 formatted data used to construct the object. + * + * See also: g_tls_certificate_new_from_pkcs12() + * + * Since: 2.72 + */ + g_object_class_install_property (gobject_class, PROP_PKCS12_DATA, + g_param_spec_boxed ("pkcs12-data", + P_("PKCS #12 data"), + P_("The PKCS #12 data used for construction"), + G_TYPE_BYTE_ARRAY, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsCertificate:password: (nullable) + * + * An optional password used when constructed with GTlsCertificate:pkcs12-data. + * + * Since: 2.72 + */ + g_object_class_install_property (gobject_class, PROP_PASSWORD, + g_param_spec_string ("password", + P_("Password"), + P_("Password used when constructing from bytes"), + NULL, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsCertificate:certificate: + * + * The DER (binary) encoded representation of the certificate. + * This property and the #GTlsCertificate:certificate-pem property + * represent the same data, just in different forms. + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_CERTIFICATE, + g_param_spec_boxed ("certificate", + P_("Certificate"), + P_("The DER representation of the certificate"), + G_TYPE_BYTE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsCertificate:certificate-pem: + * + * The PEM (ASCII) encoded representation of the certificate. + * This property and the #GTlsCertificate:certificate + * property represent the same data, just in different forms. + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_CERTIFICATE_PEM, + g_param_spec_string ("certificate-pem", + P_("Certificate (PEM)"), + P_("The PEM representation of the certificate"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsCertificate:private-key: (nullable) + * + * The DER (binary) encoded representation of the certificate's + * private key, in either [PKCS \#1 format](https://datatracker.ietf.org/doc/html/rfc8017) + * or unencrypted [PKCS \#8 format.](https://datatracker.ietf.org/doc/html/rfc5208) + * PKCS \#8 format is supported since 2.32; earlier releases only + * support PKCS \#1. You can use the `openssl rsa` tool to convert + * PKCS \#8 keys to PKCS \#1. + * + * This property (or the #GTlsCertificate:private-key-pem property) + * can be set when constructing a key (for example, from a file). + * Since GLib 2.70, it is now also readable; however, be aware that if + * the private key is backed by a PKCS \#11 URI – for example, if it + * is stored on a smartcard – then this property will be %NULL. If so, + * the private key must be referenced via its PKCS \#11 URI, + * #GTlsCertificate:private-key-pkcs11-uri. You must check both + * properties to see if the certificate really has a private key. + * When this property is read, the output format will be unencrypted + * PKCS \#8. + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY, + g_param_spec_boxed ("private-key", + P_("Private key"), + P_("The DER representation of the certificate’s private key"), + G_TYPE_BYTE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsCertificate:private-key-pem: (nullable) + * + * The PEM (ASCII) encoded representation of the certificate's + * private key in either [PKCS \#1 format](https://datatracker.ietf.org/doc/html/rfc8017) + * ("`BEGIN RSA PRIVATE KEY`") or unencrypted + * [PKCS \#8 format](https://datatracker.ietf.org/doc/html/rfc5208) + * ("`BEGIN PRIVATE KEY`"). PKCS \#8 format is supported since 2.32; + * earlier releases only support PKCS \#1. You can use the `openssl rsa` + * tool to convert PKCS \#8 keys to PKCS \#1. + * + * This property (or the #GTlsCertificate:private-key property) + * can be set when constructing a key (for example, from a file). + * Since GLib 2.70, it is now also readable; however, be aware that if + * the private key is backed by a PKCS \#11 URI - for example, if it + * is stored on a smartcard - then this property will be %NULL. If so, + * the private key must be referenced via its PKCS \#11 URI, + * #GTlsCertificate:private-key-pkcs11-uri. You must check both + * properties to see if the certificate really has a private key. + * When this property is read, the output format will be unencrypted + * PKCS \#8. + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PEM, + g_param_spec_string ("private-key-pem", + P_("Private key (PEM)"), + P_("The PEM representation of the certificate’s private key"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsCertificate:issuer: + * + * A #GTlsCertificate representing the entity that issued this + * certificate. If %NULL, this means that the certificate is either + * self-signed, or else the certificate of the issuer is not + * available. + * + * Beware the issuer certificate may not be the same as the + * certificate that would actually be used to construct a valid + * certification path during certificate verification. + * [RFC 4158](https://datatracker.ietf.org/doc/html/rfc4158) explains + * why an issuer certificate cannot be naively assumed to be part of the + * the certification path (though GLib's TLS backends may not follow the + * path building strategies outlined in this RFC). Due to the complexity + * of certification path building, GLib does not provide any way to know + * which certification path will actually be used. Accordingly, this + * property cannot be used to make security-related decisions. Only + * GLib itself should make security decisions about TLS certificates. + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_ISSUER, + g_param_spec_object ("issuer", + P_("Issuer"), + P_("The certificate for the issuing entity"), + G_TYPE_TLS_CERTIFICATE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsCertificate:pkcs11-uri: (nullable) + * + * A URI referencing the [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html) + * objects containing an X.509 certificate and optionally a private key. + * + * If %NULL, the certificate is either not backed by PKCS \#11 or the + * #GTlsBackend does not support PKCS \#11. + * + * Since: 2.68 + */ + g_object_class_install_property (gobject_class, PROP_PKCS11_URI, + g_param_spec_string ("pkcs11-uri", + P_("PKCS #11 URI"), + P_("The PKCS #11 URI"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsCertificate:private-key-pkcs11-uri: (nullable) + * + * A URI referencing a [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html) + * object containing a private key. + * + * Since: 2.68 + */ + g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PKCS11_URI, + g_param_spec_string ("private-key-pkcs11-uri", + P_("PKCS #11 URI"), + P_("The PKCS #11 URI for a private key"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsCertificate:not-valid-before: (nullable) + * + * The time at which this cert is considered to be valid, + * %NULL if unavailable. + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_NOT_VALID_BEFORE, + g_param_spec_boxed ("not-valid-before", + P_("Not Valid Before"), + P_("Cert should not be considered valid before this time."), + G_TYPE_DATE_TIME, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsCertificate:not-valid-after: (nullable) + * + * The time at which this cert is no longer valid, + * %NULL if unavailable. + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_NOT_VALID_AFTER, + g_param_spec_boxed ("not-valid-after", + P_("Not Valid after"), + P_("Cert should not be considered valid after this time."), + G_TYPE_DATE_TIME, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsCertificate:subject-name: (nullable) + * + * The subject from the cert, + * %NULL if unavailable. + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_SUBJECT_NAME, + g_param_spec_string ("subject-name", + P_("Subject Name"), + P_("The subject name from the certificate."), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsCertificate:issuer-name: (nullable) + * + * The issuer from the certificate, + * %NULL if unavailable. + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_ISSUER_NAME, + g_param_spec_string ("issuer-name", + P_("Issuer Name"), + P_("The issuer from the certificate."), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsCertificate:dns-names: (nullable) (element-type GBytes) (transfer container) + * + * The DNS names from the certificate's Subject Alternative Names (SANs), + * %NULL if unavailable. + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_DNS_NAMES, + g_param_spec_boxed ("dns-names", + P_("DNS Names"), + P_("DNS Names listed on the cert."), + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsCertificate:ip-addresses: (nullable) (element-type GInetAddress) (transfer container) + * + * The IP addresses from the certificate's Subject Alternative Names (SANs), + * %NULL if unavailable. + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_IP_ADDRESSES, + g_param_spec_boxed ("ip-addresses", + P_("IP Addresses"), + P_("IP Addresses listed on the cert."), + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +static GTlsCertificate * +g_tls_certificate_new_internal (const gchar *certificate_pem, + const gchar *private_key_pem, + GTlsCertificate *issuer, + GError **error) +{ + GObject *cert; + GTlsBackend *backend; + + backend = g_tls_backend_get_default (); + + cert = g_initable_new (g_tls_backend_get_certificate_type (backend), + NULL, error, + "certificate-pem", certificate_pem, + "private-key-pem", private_key_pem, + "issuer", issuer, + NULL); + + return G_TLS_CERTIFICATE (cert); +} + +#define PEM_CERTIFICATE_HEADER "-----BEGIN CERTIFICATE-----" +#define PEM_CERTIFICATE_FOOTER "-----END CERTIFICATE-----" +#define PEM_PRIVKEY_HEADER_BEGIN "-----BEGIN " +#define PEM_PRIVKEY_HEADER_END "PRIVATE KEY-----" +#define PEM_PRIVKEY_FOOTER_BEGIN "-----END " +#define PEM_PRIVKEY_FOOTER_END "PRIVATE KEY-----" +#define PEM_PKCS8_ENCRYPTED_HEADER "-----BEGIN ENCRYPTED PRIVATE KEY-----" + +static gchar * +parse_private_key (const gchar *data, + gsize data_len, + gboolean required, + GError **error) +{ + const gchar *header_start = NULL, *header_end, *footer_start = NULL, *footer_end; + const gchar *data_end = data + data_len; + + header_end = g_strstr_len (data, data_len, PEM_PRIVKEY_HEADER_END); + if (header_end) + header_start = g_strrstr_len (data, header_end - data, PEM_PRIVKEY_HEADER_BEGIN); + + if (!header_start) + { + if (required) + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE, + _("No PEM-encoded private key found")); + + return NULL; + } + + header_end += strlen (PEM_PRIVKEY_HEADER_END); + + if (strncmp (header_start, PEM_PKCS8_ENCRYPTED_HEADER, header_end - header_start) == 0) + { + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE, + _("Cannot decrypt PEM-encoded private key")); + return NULL; + } + + footer_end = g_strstr_len (header_end, data_len - (header_end - data), PEM_PRIVKEY_FOOTER_END); + if (footer_end) + footer_start = g_strrstr_len (header_end, footer_end - header_end, PEM_PRIVKEY_FOOTER_BEGIN); + + if (!footer_start) + { + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE, + _("Could not parse PEM-encoded private key")); + return NULL; + } + + footer_end += strlen (PEM_PRIVKEY_FOOTER_END); + + while ((footer_end < data_end) && (*footer_end == '\r' || *footer_end == '\n')) + footer_end++; + + return g_strndup (header_start, footer_end - header_start); +} + + +static gchar * +parse_next_pem_certificate (const gchar **data, + const gchar *data_end, + gboolean required, + GError **error) +{ + const gchar *start, *end; + + start = g_strstr_len (*data, data_end - *data, PEM_CERTIFICATE_HEADER); + if (!start) + { + if (required) + { + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE, + _("No PEM-encoded certificate found")); + } + return NULL; + } + + end = g_strstr_len (start, data_end - start, PEM_CERTIFICATE_FOOTER); + if (!end) + { + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE, + _("Could not parse PEM-encoded certificate")); + return NULL; + } + end += strlen (PEM_CERTIFICATE_FOOTER); + while ((end < data_end) && (*end == '\r' || *end == '\n')) + end++; + + *data = end; + + return g_strndup (start, end - start); +} + +static GSList * +parse_and_create_certificate_list (const gchar *data, + gsize data_len, + GError **error) +{ + GSList *first_pem_list = NULL, *pem_list = NULL; + gchar *first_pem; + const gchar *p, *end; + + p = data; + end = p + data_len; + + /* Make sure we can load, at least, one certificate. */ + first_pem = parse_next_pem_certificate (&p, end, TRUE, error); + if (!first_pem) + return NULL; + + /* Create a list with a single element. If we load more certificates + * below, we will concatenate the two lists at the end. */ + first_pem_list = g_slist_prepend (first_pem_list, first_pem); + + /* If we read one certificate successfully, let's see if we can read + * some more. If not, we will simply return a list with the first one. + */ + while (p < end && p && *p) + { + gchar *cert_pem; + GError *error = NULL; + + cert_pem = parse_next_pem_certificate (&p, end, FALSE, &error); + if (error) + { + g_slist_free_full (pem_list, g_free); + g_error_free (error); + return first_pem_list; + } + else if (!cert_pem) + { + break; + } + + pem_list = g_slist_prepend (pem_list, cert_pem); + } + + pem_list = g_slist_concat (pem_list, first_pem_list); + + return pem_list; +} + +static GTlsCertificate * +create_certificate_chain_from_list (GSList *pem_list, + const gchar *key_pem) +{ + GTlsCertificate *cert = NULL, *issuer = NULL, *root = NULL; + GTlsCertificateFlags flags; + GSList *pem; + + pem = pem_list; + while (pem) + { + const gchar *key = NULL; + + /* Private key belongs only to the first certificate. */ + if (!pem->next) + key = key_pem; + + /* We assume that the whole file is a certificate chain, so we use + * each certificate as the issuer of the next one (list is in + * reverse order). + */ + issuer = cert; + cert = g_tls_certificate_new_internal (pem->data, key, issuer, NULL); + if (issuer) + g_object_unref (issuer); + + if (!cert) + return NULL; + + /* root will point to the last certificate in the file. */ + if (!root) + root = g_object_ref (cert); + + pem = g_slist_next (pem); + } + + /* Verify that the certificates form a chain. (We don't care at this + * point if there are other problems with it.) + */ + flags = g_tls_certificate_verify (cert, NULL, root); + if (flags & G_TLS_CERTIFICATE_UNKNOWN_CA) + { + /* It wasn't a chain, it's just a bunch of unrelated certs. */ + g_clear_object (&cert); + } + + g_clear_object (&root); + + return cert; +} + +static GTlsCertificate * +parse_and_create_certificate (const gchar *data, + gsize data_len, + const gchar *key_pem, + GError **error) + +{ + GSList *pem_list; + GTlsCertificate *cert; + + pem_list = parse_and_create_certificate_list (data, data_len, error); + if (!pem_list) + return NULL; + + /* We don't pass the error here because, if it fails, we still want to + * load and return the first certificate. + */ + cert = create_certificate_chain_from_list (pem_list, key_pem); + if (!cert) + { + GSList *last = NULL; + + /* Get the first certificate (which is the last one as the list is + * in reverse order). + */ + last = g_slist_last (pem_list); + + cert = g_tls_certificate_new_internal (last->data, key_pem, NULL, error); + } + + g_slist_free_full (pem_list, g_free); + + return cert; +} + +/** + * g_tls_certificate_new_from_pem: + * @data: PEM-encoded certificate data + * @length: the length of @data, or -1 if it's 0-terminated. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a #GTlsCertificate from the PEM-encoded data in @data. If + * @data includes both a certificate and a private key, then the + * returned certificate will include the private key data as well. (See + * the #GTlsCertificate:private-key-pem property for information about + * supported formats.) + * + * The returned certificate will be the first certificate found in + * @data. As of GLib 2.44, if @data contains more certificates it will + * try to load a certificate chain. All certificates will be verified in + * the order found (top-level certificate should be the last one in the + * file) and the #GTlsCertificate:issuer property of each certificate + * will be set accordingly if the verification succeeds. If any + * certificate in the chain cannot be verified, the first certificate in + * the file will still be returned. + * + * Returns: the new certificate, or %NULL if @data is invalid + * + * Since: 2.28 + */ +GTlsCertificate * +g_tls_certificate_new_from_pem (const gchar *data, + gssize length, + GError **error) +{ + GError *child_error = NULL; + gchar *key_pem; + GTlsCertificate *cert; + + g_return_val_if_fail (data != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (length == -1) + length = strlen (data); + + key_pem = parse_private_key (data, length, FALSE, &child_error); + if (child_error != NULL) + { + g_propagate_error (error, child_error); + return NULL; + } + + cert = parse_and_create_certificate (data, length, key_pem, error); + g_free (key_pem); + + return cert; +} + +/** + * g_tls_certificate_new_from_pkcs12: + * @data: (array length=length): DER-encoded PKCS #12 format certificate data + * @length: the length of @data + * @password: (nullable): optional password for encrypted certificate data + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a #GTlsCertificate from the data in @data. It must contain + * a certificate and matching private key. + * + * If extra certificates are included they will be verified as a chain + * and the #GTlsCertificate:issuer property will be set. + * All other data will be ignored. + * + * You can pass as single password for all of the data which will be + * used both for the PKCS #12 container as well as encrypted + * private keys. If decryption fails it will error with + * %G_TLS_ERROR_BAD_CERTIFICATE_PASSWORD. + * + * This constructor requires support in the current #GTlsBackend. + * If support is missing it will error with + * %G_IO_ERROR_NOT_SUPPORTED. + * + * Other parsing failures will error with %G_TLS_ERROR_BAD_CERTIFICATE. + * + * Returns: the new certificate, or %NULL if @data is invalid + * + * Since: 2.72 + */ +GTlsCertificate * +g_tls_certificate_new_from_pkcs12 (const guint8 *data, + gsize length, + const gchar *password, + GError **error) +{ + GObject *cert; + GTlsBackend *backend; + GByteArray *bytes; + + g_return_val_if_fail (data != NULL || length == 0, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + backend = g_tls_backend_get_default (); + + bytes = g_byte_array_new (); + g_byte_array_append (bytes, data, length); + + cert = g_initable_new (g_tls_backend_get_certificate_type (backend), + NULL, error, + "pkcs12-data", bytes, + "password", password, + NULL); + + g_byte_array_unref (bytes); + + if (cert) + { + GTlsCertificatePrivate *priv = g_tls_certificate_get_instance_private (G_TLS_CERTIFICATE (cert)); + + if (priv->pkcs12_properties_not_overridden) + { + g_clear_object (&cert); + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("The current TLS backend does not support PKCS #12")); + return NULL; + } + } + + return G_TLS_CERTIFICATE (cert); +} + +/** + * g_tls_certificate_new_from_file_with_password: + * @file: (type filename): file containing a certificate to import + * @password: (not nullable): password for PKCS #12 files + * @error: #GError for error reporting, or %NULL to ignore + * + * Creates a #GTlsCertificate from the data in @file. + * + * If @file cannot be read or parsed, the function will return %NULL and + * set @error. + * + * Any unknown file types will error with %G_IO_ERROR_NOT_SUPPORTED. + * Currently only `.p12` and `.pfx` files are supported. + * See g_tls_certificate_new_from_pkcs12() for more details. + * + * Returns: the new certificate, or %NULL on error + * + * Since: 2.72 + */ +GTlsCertificate * +g_tls_certificate_new_from_file_with_password (const gchar *file, + const gchar *password, + GError **error) +{ + GTlsCertificate *cert; + gchar *contents; + gsize length; + + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (password != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (!g_str_has_suffix (file, ".p12") && !g_str_has_suffix (file, ".pfx")) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "The file type of \"%s\" is unknown. Only .p12 and .pfx files are supported currently.", file); + return NULL; + } + + if (!g_file_get_contents (file, &contents, &length, error)) + return NULL; + + cert = g_tls_certificate_new_from_pkcs12 ((guint8 *)contents, length, password, error); + + g_free (contents); + return cert; +} + +/** + * g_tls_certificate_new_from_file: + * @file: (type filename): file containing a certificate to import + * @error: #GError for error reporting, or %NULL to ignore + * + * Creates a #GTlsCertificate from the data in @file. + * + * As of 2.72, if the filename ends in `.p12` or `.pfx` the data is loaded by + * g_tls_certificate_new_from_pkcs12() otherwise it is loaded by + * g_tls_certificate_new_from_pem(). See those functions for + * exact details. + * + * If @file cannot be read or parsed, the function will return %NULL and + * set @error. + * + * Returns: the new certificate, or %NULL on error + * + * Since: 2.28 + */ +GTlsCertificate * +g_tls_certificate_new_from_file (const gchar *file, + GError **error) +{ + GTlsCertificate *cert; + gchar *contents; + gsize length; + + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (!g_file_get_contents (file, &contents, &length, error)) + return NULL; + + if (g_str_has_suffix (file, ".p12") || g_str_has_suffix (file, ".pfx")) + cert = g_tls_certificate_new_from_pkcs12 ((guint8 *)contents, length, NULL, error); + else + cert = g_tls_certificate_new_from_pem (contents, length, error); + + g_free (contents); + return cert; +} + +/** + * g_tls_certificate_new_from_files: + * @cert_file: (type filename): file containing one or more PEM-encoded + * certificates to import + * @key_file: (type filename): file containing a PEM-encoded private key + * to import + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a #GTlsCertificate from the PEM-encoded data in @cert_file + * and @key_file. The returned certificate will be the first certificate + * found in @cert_file. As of GLib 2.44, if @cert_file contains more + * certificates it will try to load a certificate chain. All + * certificates will be verified in the order found (top-level + * certificate should be the last one in the file) and the + * #GTlsCertificate:issuer property of each certificate will be set + * accordingly if the verification succeeds. If any certificate in the + * chain cannot be verified, the first certificate in the file will + * still be returned. + * + * If either file cannot be read or parsed, the function will return + * %NULL and set @error. Otherwise, this behaves like + * g_tls_certificate_new_from_pem(). + * + * Returns: the new certificate, or %NULL on error + * + * Since: 2.28 + */ +GTlsCertificate * +g_tls_certificate_new_from_files (const gchar *cert_file, + const gchar *key_file, + GError **error) +{ + GTlsCertificate *cert; + gchar *cert_data, *key_data; + gsize cert_len, key_len; + gchar *key_pem; + + if (!g_file_get_contents (key_file, &key_data, &key_len, error)) + return NULL; + + key_pem = parse_private_key (key_data, key_len, TRUE, error); + g_free (key_data); + if (!key_pem) + return NULL; + + if (!g_file_get_contents (cert_file, &cert_data, &cert_len, error)) + { + g_free (key_pem); + return NULL; + } + + cert = parse_and_create_certificate (cert_data, cert_len, key_pem, error); + g_free (cert_data); + g_free (key_pem); + return cert; +} + +/** + * g_tls_certificate_new_from_pkcs11_uris: + * @pkcs11_uri: A PKCS \#11 URI + * @private_key_pkcs11_uri: (nullable): A PKCS \#11 URI + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a #GTlsCertificate from a + * [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html) URI. + * + * An example @pkcs11_uri would be `pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01` + * + * Where the token’s layout is: + * + * |[ + * Object 0: + * URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=private%20key;type=private + * Type: Private key (RSA-2048) + * ID: 01 + * + * Object 1: + * URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=Certificate%20for%20Authentication;type=cert + * Type: X.509 Certificate (RSA-2048) + * ID: 01 + * ]| + * + * In this case the certificate and private key would both be detected and used as expected. + * @pkcs_uri may also just reference an X.509 certificate object and then optionally + * @private_key_pkcs11_uri allows using a private key exposed under a different URI. + * + * Note that the private key is not accessed until usage and may fail or require a PIN later. + * + * Returns: (transfer full): the new certificate, or %NULL on error + * + * Since: 2.68 + */ +GTlsCertificate * +g_tls_certificate_new_from_pkcs11_uris (const gchar *pkcs11_uri, + const gchar *private_key_pkcs11_uri, + GError **error) +{ + GObject *cert; + GTlsBackend *backend; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (pkcs11_uri, NULL); + + backend = g_tls_backend_get_default (); + + cert = g_initable_new (g_tls_backend_get_certificate_type (backend), + NULL, error, + "pkcs11-uri", pkcs11_uri, + "private-key-pkcs11-uri", private_key_pkcs11_uri, + NULL); + + if (cert != NULL) + { + gchar *objects_uri; + + /* Old implementations might not override this property */ + g_object_get (cert, "pkcs11-uri", &objects_uri, NULL); + if (objects_uri == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("This GTlsBackend does not support creating PKCS #11 certificates")); + g_object_unref (cert); + return NULL; + } + g_free (objects_uri); + } + + return G_TLS_CERTIFICATE (cert); +} + +/** + * g_tls_certificate_list_new_from_file: + * @file: (type filename): file containing PEM-encoded certificates to import + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates one or more #GTlsCertificates from the PEM-encoded + * data in @file. If @file cannot be read or parsed, the function will + * return %NULL and set @error. If @file does not contain any + * PEM-encoded certificates, this will return an empty list and not + * set @error. + * + * Returns: (element-type Gio.TlsCertificate) (transfer full): a + * #GList containing #GTlsCertificate objects. You must free the list + * and its contents when you are done with it. + * + * Since: 2.28 + */ +GList * +g_tls_certificate_list_new_from_file (const gchar *file, + GError **error) +{ + GQueue queue = G_QUEUE_INIT; + gchar *contents, *end; + const gchar *p; + gsize length; + + if (!g_file_get_contents (file, &contents, &length, error)) + return NULL; + + end = contents + length; + p = contents; + while (p && *p) + { + gchar *cert_pem; + GTlsCertificate *cert = NULL; + GError *parse_error = NULL; + + cert_pem = parse_next_pem_certificate (&p, end, FALSE, &parse_error); + if (cert_pem) + { + cert = g_tls_certificate_new_internal (cert_pem, NULL, NULL, &parse_error); + g_free (cert_pem); + } + if (!cert) + { + if (parse_error) + { + g_propagate_error (error, parse_error); + g_list_free_full (queue.head, g_object_unref); + queue.head = NULL; + } + break; + } + g_queue_push_tail (&queue, cert); + } + + g_free (contents); + return queue.head; +} + + +/** + * g_tls_certificate_get_issuer: + * @cert: a #GTlsCertificate + * + * Gets the #GTlsCertificate representing @cert's issuer, if known + * + * Returns: (nullable) (transfer none): The certificate of @cert's issuer, + * or %NULL if @cert is self-signed or signed with an unknown + * certificate. + * + * Since: 2.28 + */ +GTlsCertificate * +g_tls_certificate_get_issuer (GTlsCertificate *cert) +{ + GTlsCertificate *issuer; + + g_object_get (G_OBJECT (cert), "issuer", &issuer, NULL); + if (issuer) + g_object_unref (issuer); + + return issuer; +} + +/** + * g_tls_certificate_verify: + * @cert: a #GTlsCertificate + * @identity: (nullable): the expected peer identity + * @trusted_ca: (nullable): the certificate of a trusted authority + * + * This verifies @cert and returns a set of #GTlsCertificateFlags + * indicating any problems found with it. This can be used to verify a + * certificate outside the context of making a connection, or to + * check a certificate against a CA that is not part of the system + * CA database. + * + * If @identity is not %NULL, @cert's name(s) will be compared against + * it, and %G_TLS_CERTIFICATE_BAD_IDENTITY will be set in the return + * value if it does not match. If @identity is %NULL, that bit will + * never be set in the return value. + * + * If @trusted_ca is not %NULL, then @cert (or one of the certificates + * in its chain) must be signed by it, or else + * %G_TLS_CERTIFICATE_UNKNOWN_CA will be set in the return value. If + * @trusted_ca is %NULL, that bit will never be set in the return + * value. + * + * GLib guarantees that if certificate verification fails, at least one + * error will be set in the return value, but it does not guarantee + * that all possible errors will be set. Accordingly, you may not safely + * decide to ignore any particular type of error. For example, it would + * be incorrect to mask %G_TLS_CERTIFICATE_EXPIRED if you want to allow + * expired certificates, because this could potentially be the only + * error flag set even if other problems exist with the certificate. + * + * Because TLS session context is not used, #GTlsCertificate may not + * perform as many checks on the certificates as #GTlsConnection would. + * For example, certificate constraints may not be honored, and + * revocation checks may not be performed. The best way to verify TLS + * certificates used by a TLS connection is to let #GTlsConnection + * handle the verification. + * + * Returns: the appropriate #GTlsCertificateFlags + * + * Since: 2.28 + */ +GTlsCertificateFlags +g_tls_certificate_verify (GTlsCertificate *cert, + GSocketConnectable *identity, + GTlsCertificate *trusted_ca) +{ + return G_TLS_CERTIFICATE_GET_CLASS (cert)->verify (cert, identity, trusted_ca); +} + +/** + * g_tls_certificate_is_same: + * @cert_one: first certificate to compare + * @cert_two: second certificate to compare + * + * Check if two #GTlsCertificate objects represent the same certificate. + * The raw DER byte data of the two certificates are checked for equality. + * This has the effect that two certificates may compare equal even if + * their #GTlsCertificate:issuer, #GTlsCertificate:private-key, or + * #GTlsCertificate:private-key-pem properties differ. + * + * Returns: whether the same or not + * + * Since: 2.34 + */ +gboolean +g_tls_certificate_is_same (GTlsCertificate *cert_one, + GTlsCertificate *cert_two) +{ + GByteArray *b1, *b2; + gboolean equal; + + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert_one), FALSE); + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert_two), FALSE); + + g_object_get (cert_one, "certificate", &b1, NULL); + g_object_get (cert_two, "certificate", &b2, NULL); + + equal = (b1->len == b2->len && + memcmp (b1->data, b2->data, b1->len) == 0); + + g_byte_array_unref (b1); + g_byte_array_unref (b2); + + return equal; +} + + +/** + * g_tls_certificate_get_not_valid_before: + * @cert: a #GTlsCertificate + * + * Returns the time at which the certificate became or will become valid. + * + * Returns: (nullable) (transfer full): The not-valid-before date, or %NULL if it's not available. + * + * Since: 2.70 + */ +GDateTime * +g_tls_certificate_get_not_valid_before (GTlsCertificate *cert) +{ + GDateTime *not_valid_before = NULL; + + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL); + + g_object_get (G_OBJECT (cert), "not-valid-before", ¬_valid_before, NULL); + + return g_steal_pointer (¬_valid_before); +} + +/** + * g_tls_certificate_get_not_valid_after: + * @cert: a #GTlsCertificate + * + * Returns the time at which the certificate became or will become invalid. + * + * Returns: (nullable) (transfer full): The not-valid-after date, or %NULL if it's not available. + * + * Since: 2.70 + */ +GDateTime * +g_tls_certificate_get_not_valid_after (GTlsCertificate *cert) +{ + GDateTime *not_valid_after = NULL; + + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL); + + g_object_get (G_OBJECT (cert), "not-valid-after", ¬_valid_after, NULL); + + return g_steal_pointer (¬_valid_after); +} + +/** + * g_tls_certificate_get_subject_name: + * @cert: a #GTlsCertificate + * + * Returns the subject name from the certificate. + * + * Returns: (nullable) (transfer full): The subject name, or %NULL if it's not available. + * + * Since: 2.70 + */ +gchar * +g_tls_certificate_get_subject_name (GTlsCertificate *cert) +{ + gchar *subject_name = NULL; + + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL); + + g_object_get (G_OBJECT (cert), "subject-name", &subject_name, NULL); + + return g_steal_pointer (&subject_name); +} + +/** + * g_tls_certificate_get_issuer_name: + * @cert: a #GTlsCertificate + * + * Returns the issuer name from the certificate. + * + * Returns: (nullable) (transfer full): The issuer name, or %NULL if it's not available. + * + * Since: 2.70 + */ +gchar * +g_tls_certificate_get_issuer_name (GTlsCertificate *cert) +{ + gchar *issuer_name = NULL; + + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL); + + g_object_get (G_OBJECT (cert), "issuer-name", &issuer_name, NULL); + + return g_steal_pointer (&issuer_name); +} + +/** + * g_tls_certificate_get_dns_names: + * @cert: a #GTlsCertificate + * + * Gets the value of #GTlsCertificate:dns-names. + * + * Returns: (nullable) (element-type GBytes) (transfer container): A #GPtrArray of + * #GBytes elements, or %NULL if it's not available. + * + * Since: 2.70 + */ +GPtrArray * +g_tls_certificate_get_dns_names (GTlsCertificate *cert) +{ + GPtrArray *dns_names = NULL; + + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL); + + g_object_get (G_OBJECT (cert), "dns-names", &dns_names, NULL); + + return g_steal_pointer (&dns_names); +} + +/** + * g_tls_certificate_get_ip_addresses: + * @cert: a #GTlsCertificate + * + * Gets the value of #GTlsCertificate:ip-addresses. + * + * Returns: (nullable) (element-type GInetAddress) (transfer container): A #GPtrArray + * of #GInetAddress elements, or %NULL if it's not available. + * + * Since: 2.70 + */ +GPtrArray * +g_tls_certificate_get_ip_addresses (GTlsCertificate *cert) +{ + GPtrArray *ip_addresses = NULL; + + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL); + + g_object_get (G_OBJECT (cert), "ip-addresses", &ip_addresses, NULL); + + return g_steal_pointer (&ip_addresses); +} diff --git a/gio/gtlscertificate.h b/gio/gtlscertificate.h new file mode 100644 index 0000000..52e678b --- /dev/null +++ b/gio/gtlscertificate.h @@ -0,0 +1,123 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_TLS_CERTIFICATE_H__ +#define __G_TLS_CERTIFICATE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TLS_CERTIFICATE (g_tls_certificate_get_type ()) +#define G_TLS_CERTIFICATE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_CERTIFICATE, GTlsCertificate)) +#define G_TLS_CERTIFICATE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_TLS_CERTIFICATE, GTlsCertificateClass)) +#define G_IS_TLS_CERTIFICATE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_CERTIFICATE)) +#define G_IS_TLS_CERTIFICATE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_TLS_CERTIFICATE)) +#define G_TLS_CERTIFICATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), G_TYPE_TLS_CERTIFICATE, GTlsCertificateClass)) + +typedef struct _GTlsCertificateClass GTlsCertificateClass; +typedef struct _GTlsCertificatePrivate GTlsCertificatePrivate; + +struct _GTlsCertificate { + GObject parent_instance; + + GTlsCertificatePrivate *priv; +}; + +struct _GTlsCertificateClass +{ + GObjectClass parent_class; + + GTlsCertificateFlags (* verify) (GTlsCertificate *cert, + GSocketConnectable *identity, + GTlsCertificate *trusted_ca); + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_certificate_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GTlsCertificate *g_tls_certificate_new_from_pem (const gchar *data, + gssize length, + GError **error); +GLIB_AVAILABLE_IN_2_72 +GTlsCertificate *g_tls_certificate_new_from_pkcs12 (const guint8 *data, + gsize length, + const gchar *password, + GError **error); +GLIB_AVAILABLE_IN_2_72 +GTlsCertificate *g_tls_certificate_new_from_file_with_password (const gchar *file, + const gchar *password, + GError **error); +GLIB_AVAILABLE_IN_ALL +GTlsCertificate *g_tls_certificate_new_from_file (const gchar *file, + GError **error); +GLIB_AVAILABLE_IN_ALL +GTlsCertificate *g_tls_certificate_new_from_files (const gchar *cert_file, + const gchar *key_file, + GError **error); +GLIB_AVAILABLE_IN_2_68 +GTlsCertificate *g_tls_certificate_new_from_pkcs11_uris (const gchar *pkcs11_uri, + const gchar *private_key_pkcs11_uri, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GList *g_tls_certificate_list_new_from_file (const gchar *file, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GTlsCertificate *g_tls_certificate_get_issuer (GTlsCertificate *cert); + +GLIB_AVAILABLE_IN_ALL +GTlsCertificateFlags g_tls_certificate_verify (GTlsCertificate *cert, + GSocketConnectable *identity, + GTlsCertificate *trusted_ca); + +GLIB_AVAILABLE_IN_2_34 +gboolean g_tls_certificate_is_same (GTlsCertificate *cert_one, + GTlsCertificate *cert_two); + +GLIB_AVAILABLE_IN_2_70 +GDateTime *g_tls_certificate_get_not_valid_before (GTlsCertificate *cert); + +GLIB_AVAILABLE_IN_2_70 +GDateTime *g_tls_certificate_get_not_valid_after (GTlsCertificate *cert); + +GLIB_AVAILABLE_IN_2_70 +gchar *g_tls_certificate_get_subject_name (GTlsCertificate *cert); + +GLIB_AVAILABLE_IN_2_70 +gchar *g_tls_certificate_get_issuer_name (GTlsCertificate *cert); + +GLIB_AVAILABLE_IN_2_70 +GPtrArray *g_tls_certificate_get_dns_names (GTlsCertificate *cert); + +GLIB_AVAILABLE_IN_2_70 +GPtrArray *g_tls_certificate_get_ip_addresses (GTlsCertificate *cert); + +G_END_DECLS + +#endif /* __G_TLS_CERTIFICATE_H__ */ diff --git a/gio/gtlsclientconnection.c b/gio/gtlsclientconnection.c new file mode 100644 index 0000000..63dd6be --- /dev/null +++ b/gio/gtlsclientconnection.c @@ -0,0 +1,422 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" + +#include "gtlsclientconnection.h" +#include "ginitable.h" +#include "gioenumtypes.h" +#include "gsocket.h" +#include "gsocketconnectable.h" +#include "gtlsbackend.h" +#include "gtlscertificate.h" +#include "glibintl.h" + +/** + * SECTION:gtlsclientconnection + * @short_description: TLS client-side connection + * @include: gio/gio.h + * + * #GTlsClientConnection is the client-side subclass of + * #GTlsConnection, representing a client-side TLS connection. + */ + +/** + * GTlsClientConnection: + * + * Abstract base class for the backend-specific client connection + * type. + * + * Since: 2.28 + */ + +G_DEFINE_INTERFACE (GTlsClientConnection, g_tls_client_connection, G_TYPE_TLS_CONNECTION) + +static void +g_tls_client_connection_default_init (GTlsClientConnectionInterface *iface) +{ + /** + * GTlsClientConnection:validation-flags: + * + * What steps to perform when validating a certificate received from + * a server. Server certificates that fail to validate in any of the + * ways indicated here will be rejected unless the application + * overrides the default via #GTlsConnection::accept-certificate. + * + * GLib guarantees that if certificate verification fails, at least one + * flag will be set, but it does not guarantee that all possible flags + * will be set. Accordingly, you may not safely decide to ignore any + * particular type of error. For example, it would be incorrect to mask + * %G_TLS_CERTIFICATE_EXPIRED if you want to allow expired certificates, + * because this could potentially be the only error flag set even if + * other problems exist with the certificate. Therefore, there is no + * safe way to use this property. This is not a horrible problem, + * though, because you should not be attempting to ignore validation + * errors anyway. If you really must ignore TLS certificate errors, + * connect to #GTlsConnection::accept-certificate. + * + * Since: 2.28 + * + * Deprecated: 2.72: Do not attempt to ignore validation errors. + */ + g_object_interface_install_property (iface, + g_param_spec_flags ("validation-flags", + P_("Validation flags"), + P_("What certificate validation to perform"), + G_TYPE_TLS_CERTIFICATE_FLAGS, + G_TLS_CERTIFICATE_VALIDATE_ALL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS | + G_PARAM_DEPRECATED)); + + /** + * GTlsClientConnection:server-identity: + * + * A #GSocketConnectable describing the identity of the server that + * is expected on the other end of the connection. + * + * If the %G_TLS_CERTIFICATE_BAD_IDENTITY flag is set in + * #GTlsClientConnection:validation-flags, this object will be used + * to determine the expected identify of the remote end of the + * connection; if #GTlsClientConnection:server-identity is not set, + * or does not match the identity presented by the server, then the + * %G_TLS_CERTIFICATE_BAD_IDENTITY validation will fail. + * + * In addition to its use in verifying the server certificate, + * this is also used to give a hint to the server about what + * certificate we expect, which is useful for servers that serve + * virtual hosts. + * + * Since: 2.28 + */ + g_object_interface_install_property (iface, + g_param_spec_object ("server-identity", + P_("Server identity"), + P_("GSocketConnectable identifying the server"), + G_TYPE_SOCKET_CONNECTABLE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsClientConnection:use-ssl3: + * + * SSL 3.0 is no longer supported. See + * g_tls_client_connection_set_use_ssl3() for details. + * + * Since: 2.28 + * + * Deprecated: 2.56: SSL 3.0 is insecure. + */ + g_object_interface_install_property (iface, + g_param_spec_boolean ("use-ssl3", + P_("Use fallback"), + P_("Use fallback version of SSL/TLS rather than most recent version"), + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS | + G_PARAM_DEPRECATED)); + + /** + * GTlsClientConnection:accepted-cas: (type GLib.List) (element-type GLib.ByteArray) + * + * A list of the distinguished names of the Certificate Authorities + * that the server will accept client certificates signed by. If the + * server requests a client certificate during the handshake, then + * this property will be set after the handshake completes. + * + * Each item in the list is a #GByteArray which contains the complete + * subject DN of the certificate authority. + * + * Since: 2.28 + */ + g_object_interface_install_property (iface, + g_param_spec_pointer ("accepted-cas", + P_("Accepted CAs"), + P_("Distinguished names of the CAs the server accepts certificates from"), + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_tls_client_connection_new: + * @base_io_stream: the #GIOStream to wrap + * @server_identity: (nullable): the expected identity of the server + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a new #GTlsClientConnection wrapping @base_io_stream (which + * must have pollable input and output streams) which is assumed to + * communicate with the server identified by @server_identity. + * + * See the documentation for #GTlsConnection:base-io-stream for restrictions + * on when application code can run operations on the @base_io_stream after + * this function has returned. + * + * Returns: (transfer full) (type GTlsClientConnection): the new + * #GTlsClientConnection, or %NULL on error + * + * Since: 2.28 + */ +GIOStream * +g_tls_client_connection_new (GIOStream *base_io_stream, + GSocketConnectable *server_identity, + GError **error) +{ + GObject *conn; + GTlsBackend *backend; + + backend = g_tls_backend_get_default (); + conn = g_initable_new (g_tls_backend_get_client_connection_type (backend), + NULL, error, + "base-io-stream", base_io_stream, + "server-identity", server_identity, + NULL); + return G_IO_STREAM (conn); +} + +/** + * g_tls_client_connection_get_validation_flags: + * @conn: the #GTlsClientConnection + * + * Gets @conn's validation flags + * + * This function does not work as originally designed and is impossible + * to use correctly. See #GTlsClientConnection:validation-flags for more + * information. + * + * Returns: the validation flags + * + * Since: 2.28 + * + * Deprecated: 2.72: Do not attempt to ignore validation errors. + */ +GTlsCertificateFlags +g_tls_client_connection_get_validation_flags (GTlsClientConnection *conn) +{ + GTlsCertificateFlags flags = 0; + + g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), 0); + + g_object_get (G_OBJECT (conn), "validation-flags", &flags, NULL); + return flags; +} + +/** + * g_tls_client_connection_set_validation_flags: + * @conn: the #GTlsClientConnection + * @flags: the #GTlsCertificateFlags to use + * + * Sets @conn's validation flags, to override the default set of + * checks performed when validating a server certificate. By default, + * %G_TLS_CERTIFICATE_VALIDATE_ALL is used. + * + * This function does not work as originally designed and is impossible + * to use correctly. See #GTlsClientConnection:validation-flags for more + * information. + * + * Since: 2.28 + * + * Deprecated: 2.72: Do not attempt to ignore validation errors. + */ +void +g_tls_client_connection_set_validation_flags (GTlsClientConnection *conn, + GTlsCertificateFlags flags) +{ + g_return_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), "validation-flags", flags, NULL); +} + +/** + * g_tls_client_connection_get_server_identity: + * @conn: the #GTlsClientConnection + * + * Gets @conn's expected server identity + * + * Returns: (nullable) (transfer none): a #GSocketConnectable describing the + * expected server identity, or %NULL if the expected identity is not + * known. + * + * Since: 2.28 + */ +GSocketConnectable * +g_tls_client_connection_get_server_identity (GTlsClientConnection *conn) +{ + GSocketConnectable *identity = NULL; + + g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), 0); + + g_object_get (G_OBJECT (conn), "server-identity", &identity, NULL); + if (identity) + g_object_unref (identity); + return identity; +} + +/** + * g_tls_client_connection_set_server_identity: + * @conn: the #GTlsClientConnection + * @identity: a #GSocketConnectable describing the expected server identity + * + * Sets @conn's expected server identity, which is used both to tell + * servers on virtual hosts which certificate to present, and also + * to let @conn know what name to look for in the certificate when + * performing %G_TLS_CERTIFICATE_BAD_IDENTITY validation, if enabled. + * + * Since: 2.28 + */ +void +g_tls_client_connection_set_server_identity (GTlsClientConnection *conn, + GSocketConnectable *identity) +{ + g_return_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), "server-identity", identity, NULL); +} + +/** + * g_tls_client_connection_get_use_ssl3: + * @conn: the #GTlsClientConnection + * + * SSL 3.0 is no longer supported. See + * g_tls_client_connection_set_use_ssl3() for details. + * + * Returns: %FALSE + * + * Since: 2.28 + * + * Deprecated: 2.56: SSL 3.0 is insecure. + */ +gboolean +g_tls_client_connection_get_use_ssl3 (GTlsClientConnection *conn) +{ + gboolean use_ssl3 = FALSE; + + g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), 0); + + g_object_get (G_OBJECT (conn), "use-ssl3", &use_ssl3, NULL); + return FALSE; +} + +/** + * g_tls_client_connection_set_use_ssl3: + * @conn: the #GTlsClientConnection + * @use_ssl3: a #gboolean, ignored + * + * Since GLib 2.42.1, SSL 3.0 is no longer supported. + * + * From GLib 2.42.1 through GLib 2.62, this function could be used to + * force use of TLS 1.0, the lowest-supported TLS protocol version at + * the time. In the past, this was needed to connect to broken TLS + * servers that exhibited protocol version intolerance. Such servers + * are no longer common, and using TLS 1.0 is no longer considered + * acceptable. + * + * Since GLib 2.64, this function does nothing. + * + * Since: 2.28 + * + * Deprecated: 2.56: SSL 3.0 is insecure. + */ +void +g_tls_client_connection_set_use_ssl3 (GTlsClientConnection *conn, + gboolean use_ssl3) +{ + g_return_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), "use-ssl3", FALSE, NULL); +} + +/** + * g_tls_client_connection_get_accepted_cas: + * @conn: the #GTlsClientConnection + * + * Gets the list of distinguished names of the Certificate Authorities + * that the server will accept certificates from. This will be set + * during the TLS handshake if the server requests a certificate. + * Otherwise, it will be %NULL. + * + * Each item in the list is a #GByteArray which contains the complete + * subject DN of the certificate authority. + * + * Returns: (element-type GByteArray) (transfer full): the list of + * CA DNs. You should unref each element with g_byte_array_unref() and then + * the free the list with g_list_free(). + * + * Since: 2.28 + */ +GList * +g_tls_client_connection_get_accepted_cas (GTlsClientConnection *conn) +{ + GList *accepted_cas = NULL; + + g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), "accepted-cas", &accepted_cas, NULL); + return accepted_cas; +} + +/** + * g_tls_client_connection_copy_session_state: + * @conn: a #GTlsClientConnection + * @source: a #GTlsClientConnection + * + * Possibly copies session state from one connection to another, for use + * in TLS session resumption. This is not normally needed, but may be + * used when the same session needs to be used between different + * endpoints, as is required by some protocols, such as FTP over TLS. + * @source should have already completed a handshake and, since TLS 1.3, + * it should have been used to read data at least once. @conn should not + * have completed a handshake. + * + * It is not possible to know whether a call to this function will + * actually do anything. Because session resumption is normally used + * only for performance benefit, the TLS backend might not implement + * this function. Even if implemented, it may not actually succeed in + * allowing @conn to resume @source's TLS session, because the server + * may not have sent a session resumption token to @source, or it may + * refuse to accept the token from @conn. There is no way to know + * whether a call to this function is actually successful. + * + * Using this function is not required to benefit from session + * resumption. If the TLS backend supports session resumption, the + * session will be resumed automatically if it is possible to do so + * without weakening the privacy guarantees normally provided by TLS, + * without need to call this function. For example, with TLS 1.3, + * a session ticket will be automatically copied from any + * #GTlsClientConnection that has previously received session tickets + * from the server, provided a ticket is available that has not + * previously been used for session resumption, since session ticket + * reuse would be a privacy weakness. Using this function causes the + * ticket to be copied without regard for privacy considerations. + * + * Since: 2.46 + */ +void +g_tls_client_connection_copy_session_state (GTlsClientConnection *conn, + GTlsClientConnection *source) +{ + g_return_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn)); + g_return_if_fail (G_IS_TLS_CLIENT_CONNECTION (source)); + g_return_if_fail (G_TLS_CLIENT_CONNECTION_GET_INTERFACE (conn)->copy_session_state != NULL); + + G_TLS_CLIENT_CONNECTION_GET_INTERFACE (conn)->copy_session_state (conn, + source); +} diff --git a/gio/gtlsclientconnection.h b/gio/gtlsclientconnection.h new file mode 100644 index 0000000..f592fa8 --- /dev/null +++ b/gio/gtlsclientconnection.h @@ -0,0 +1,86 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_TLS_CLIENT_CONNECTION_H__ +#define __G_TLS_CLIENT_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TLS_CLIENT_CONNECTION (g_tls_client_connection_get_type ()) +#define G_TLS_CLIENT_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_CLIENT_CONNECTION, GTlsClientConnection)) +#define G_IS_TLS_CLIENT_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_CLIENT_CONNECTION)) +#define G_TLS_CLIENT_CONNECTION_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_TLS_CLIENT_CONNECTION, GTlsClientConnectionInterface)) + +typedef struct _GTlsClientConnectionInterface GTlsClientConnectionInterface; + +/** + * GTlsClientConnectionInterface: + * @g_iface: The parent interface. + * @copy_session_state: Copies session state from one #GTlsClientConnection to another. + * + * vtable for a #GTlsClientConnection implementation. + * + * Since: 2.26 + */ +struct _GTlsClientConnectionInterface +{ + GTypeInterface g_iface; + + void ( *copy_session_state ) (GTlsClientConnection *conn, + GTlsClientConnection *source); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_client_connection_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GIOStream * g_tls_client_connection_new (GIOStream *base_io_stream, + GSocketConnectable *server_identity, + GError **error); + +GLIB_DEPRECATED_IN_2_72 +GTlsCertificateFlags g_tls_client_connection_get_validation_flags (GTlsClientConnection *conn); +GLIB_DEPRECATED_IN_2_72 +void g_tls_client_connection_set_validation_flags (GTlsClientConnection *conn, + GTlsCertificateFlags flags); +GLIB_AVAILABLE_IN_ALL +GSocketConnectable *g_tls_client_connection_get_server_identity (GTlsClientConnection *conn); +GLIB_AVAILABLE_IN_ALL +void g_tls_client_connection_set_server_identity (GTlsClientConnection *conn, + GSocketConnectable *identity); +GLIB_DEPRECATED_IN_2_56 +gboolean g_tls_client_connection_get_use_ssl3 (GTlsClientConnection *conn); +GLIB_DEPRECATED_IN_2_56 +void g_tls_client_connection_set_use_ssl3 (GTlsClientConnection *conn, + gboolean use_ssl3); +GLIB_AVAILABLE_IN_ALL +GList * g_tls_client_connection_get_accepted_cas (GTlsClientConnection *conn); + +GLIB_AVAILABLE_IN_2_46 +void g_tls_client_connection_copy_session_state (GTlsClientConnection *conn, + GTlsClientConnection *source); + +G_END_DECLS + +#endif /* __G_TLS_CLIENT_CONNECTION_H__ */ diff --git a/gio/gtlsconnection.c b/gio/gtlsconnection.c new file mode 100644 index 0000000..f930eba --- /dev/null +++ b/gio/gtlsconnection.c @@ -0,0 +1,1163 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" + +#include "gtlsconnection.h" +#include "gcancellable.h" +#include "gioenumtypes.h" +#include "gsocket.h" +#include "gtlsbackend.h" +#include "gtlscertificate.h" +#include "gtlsclientconnection.h" +#include "gtlsdatabase.h" +#include "gtlsinteraction.h" +#include "glibintl.h" +#include "gmarshal-internal.h" + +/** + * SECTION:gtlsconnection + * @short_description: TLS connection type + * @include: gio/gio.h + * + * #GTlsConnection is the base TLS connection class type, which wraps + * a #GIOStream and provides TLS encryption on top of it. Its + * subclasses, #GTlsClientConnection and #GTlsServerConnection, + * implement client-side and server-side TLS, respectively. + * + * For DTLS (Datagram TLS) support, see #GDtlsConnection. + * + * Since: 2.28 + */ + +/** + * GTlsConnection: + * + * Abstract base class for the backend-specific #GTlsClientConnection + * and #GTlsServerConnection types. + * + * Since: 2.28 + */ + +G_DEFINE_ABSTRACT_TYPE (GTlsConnection, g_tls_connection, G_TYPE_IO_STREAM) + +static void g_tls_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void g_tls_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +enum { + ACCEPT_CERTIFICATE, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_BASE_IO_STREAM, + PROP_REQUIRE_CLOSE_NOTIFY, + PROP_REHANDSHAKE_MODE, + PROP_USE_SYSTEM_CERTDB, + PROP_DATABASE, + PROP_INTERACTION, + PROP_CERTIFICATE, + PROP_PEER_CERTIFICATE, + PROP_PEER_CERTIFICATE_ERRORS, + PROP_ADVERTISED_PROTOCOLS, + PROP_NEGOTIATED_PROTOCOL, + PROP_PROTOCOL_VERSION, + PROP_CIPHERSUITE_NAME, +}; + +static void +g_tls_connection_class_init (GTlsConnectionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = g_tls_connection_get_property; + gobject_class->set_property = g_tls_connection_set_property; + + /** + * GTlsConnection:base-io-stream: + * + * The #GIOStream that the connection wraps. The connection holds a reference + * to this stream, and may run operations on the stream from other threads + * throughout its lifetime. Consequently, after the #GIOStream has been + * constructed, application code may only run its own operations on this + * stream when no #GIOStream operations are running. + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_BASE_IO_STREAM, + g_param_spec_object ("base-io-stream", + P_("Base IOStream"), + P_("The GIOStream that the connection wraps"), + G_TYPE_IO_STREAM, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:use-system-certdb: + * + * Whether or not the system certificate database will be used to + * verify peer certificates. See + * g_tls_connection_set_use_system_certdb(). + * + * Deprecated: 2.30: Use GTlsConnection:database instead + */ + g_object_class_install_property (gobject_class, PROP_USE_SYSTEM_CERTDB, + g_param_spec_boolean ("use-system-certdb", + P_("Use system certificate database"), + P_("Whether to verify peer certificates against the system certificate database"), + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS | + G_PARAM_DEPRECATED)); + /** + * GTlsConnection:database: (nullable) + * + * The certificate database to use when verifying this TLS connection. + * If no certificate database is set, then the default database will be + * used. See g_tls_backend_get_default_database(). + * + * When using a non-default database, #GTlsConnection must fall back to using + * the #GTlsDatabase to perform certificate verification using + * g_tls_database_verify_chain(), which means certificate verification will + * not be able to make use of TLS session context. This may be less secure. + * For example, if you create your own #GTlsDatabase that just wraps the + * default #GTlsDatabase, you might expect that you have not changed anything, + * but this is not true because you may have altered the behavior of + * #GTlsConnection by causing it to use g_tls_database_verify_chain(). See the + * documentation of g_tls_database_verify_chain() for more details on specific + * security checks that may not be performed. Accordingly, setting a + * non-default database is discouraged except for specialty applications with + * unusual security requirements. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, PROP_DATABASE, + g_param_spec_object ("database", + P_("Database"), + P_("Certificate database to use for looking up or verifying certificates"), + G_TYPE_TLS_DATABASE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:interaction: (nullable) + * + * A #GTlsInteraction object to be used when the connection or certificate + * database need to interact with the user. This will be used to prompt the + * user for passwords where necessary. + * + * Since: 2.30 + */ + g_object_class_install_property (gobject_class, PROP_INTERACTION, + g_param_spec_object ("interaction", + P_("Interaction"), + P_("Optional object for user interaction"), + G_TYPE_TLS_INTERACTION, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:require-close-notify: + * + * Whether or not proper TLS close notification is required. + * See g_tls_connection_set_require_close_notify(). + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_REQUIRE_CLOSE_NOTIFY, + g_param_spec_boolean ("require-close-notify", + P_("Require close notify"), + P_("Whether to require proper TLS close notification"), + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:rehandshake-mode: + * + * The rehandshaking mode. See + * g_tls_connection_set_rehandshake_mode(). + * + * Since: 2.28 + * + * Deprecated: 2.60: The rehandshake mode is ignored. + */ + g_object_class_install_property (gobject_class, PROP_REHANDSHAKE_MODE, + g_param_spec_enum ("rehandshake-mode", + P_("Rehandshake mode"), + P_("When to allow rehandshaking"), + G_TYPE_TLS_REHANDSHAKE_MODE, + G_TLS_REHANDSHAKE_SAFELY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS | + G_PARAM_DEPRECATED)); + /** + * GTlsConnection:certificate: + * + * The connection's certificate; see + * g_tls_connection_set_certificate(). + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_CERTIFICATE, + g_param_spec_object ("certificate", + P_("Certificate"), + P_("The connection’s certificate"), + G_TYPE_TLS_CERTIFICATE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:peer-certificate: (nullable) + * + * The connection's peer's certificate, after the TLS handshake has + * completed or failed. Note in particular that this is not yet set + * during the emission of #GTlsConnection::accept-certificate. + * + * (You can watch for a #GObject::notify signal on this property to + * detect when a handshake has occurred.) + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_PEER_CERTIFICATE, + g_param_spec_object ("peer-certificate", + P_("Peer Certificate"), + P_("The connection’s peer’s certificate"), + G_TYPE_TLS_CERTIFICATE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:peer-certificate-errors: + * + * The errors noticed while verifying + * #GTlsConnection:peer-certificate. Normally this should be 0, but + * it may not be if #GTlsClientConnection:validation-flags is not + * %G_TLS_CERTIFICATE_VALIDATE_ALL, or if + * #GTlsConnection::accept-certificate overrode the default + * behavior. + * + * GLib guarantees that if certificate verification fails, at least + * one error will be set, but it does not guarantee that all possible + * errors will be set. Accordingly, you may not safely decide to + * ignore any particular type of error. For example, it would be + * incorrect to mask %G_TLS_CERTIFICATE_EXPIRED if you want to allow + * expired certificates, because this could potentially be the only + * error flag set even if other problems exist with the certificate. + * + * Since: 2.28 + */ + g_object_class_install_property (gobject_class, PROP_PEER_CERTIFICATE_ERRORS, + g_param_spec_flags ("peer-certificate-errors", + P_("Peer Certificate Errors"), + P_("Errors found with the peer’s certificate"), + G_TYPE_TLS_CERTIFICATE_FLAGS, + 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:advertised-protocols: (nullable) + * + * The list of application-layer protocols that the connection + * advertises that it is willing to speak. See + * g_tls_connection_set_advertised_protocols(). + * + * Since: 2.60 + */ + g_object_class_install_property (gobject_class, PROP_ADVERTISED_PROTOCOLS, + g_param_spec_boxed ("advertised-protocols", + P_("Advertised Protocols"), + P_("Application-layer protocols available on this connection"), + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:negotiated-protocol: + * + * The application-layer protocol negotiated during the TLS + * handshake. See g_tls_connection_get_negotiated_protocol(). + * + * Since: 2.60 + */ + g_object_class_install_property (gobject_class, PROP_NEGOTIATED_PROTOCOL, + g_param_spec_string ("negotiated-protocol", + P_("Negotiated Protocol"), + P_("Application-layer protocol negotiated for this connection"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsConnection:protocol-version: + * + * The TLS protocol version in use. See g_tls_connection_get_protocol_version(). + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_PROTOCOL_VERSION, + g_param_spec_enum ("protocol-version", + P_("Protocol Version"), + P_("TLS protocol version negotiated for this connection"), + G_TYPE_TLS_PROTOCOL_VERSION, + G_TLS_PROTOCOL_VERSION_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsConnection:ciphersuite-name: (nullable) + * + * The name of the TLS ciphersuite in use. See g_tls_connection_get_ciphersuite_name(). + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_CIPHERSUITE_NAME, + g_param_spec_string ("ciphersuite-name", + P_("Ciphersuite Name"), + P_("Name of ciphersuite negotiated for this connection"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsConnection::accept-certificate: + * @conn: a #GTlsConnection + * @peer_cert: the peer's #GTlsCertificate + * @errors: the problems with @peer_cert. + * + * Emitted during the TLS handshake after the peer certificate has + * been received. You can examine @peer_cert's certification path by + * calling g_tls_certificate_get_issuer() on it. + * + * For a client-side connection, @peer_cert is the server's + * certificate, and the signal will only be emitted if the + * certificate was not acceptable according to @conn's + * #GTlsClientConnection:validation_flags. If you would like the + * certificate to be accepted despite @errors, return %TRUE from the + * signal handler. Otherwise, if no handler accepts the certificate, + * the handshake will fail with %G_TLS_ERROR_BAD_CERTIFICATE. + * + * GLib guarantees that if certificate verification fails, this signal + * will be emitted with at least one error will be set in @errors, but + * it does not guarantee that all possible errors will be set. + * Accordingly, you may not safely decide to ignore any particular + * type of error. For example, it would be incorrect to ignore + * %G_TLS_CERTIFICATE_EXPIRED if you want to allow expired + * certificates, because this could potentially be the only error flag + * set even if other problems exist with the certificate. + * + * For a server-side connection, @peer_cert is the certificate + * presented by the client, if this was requested via the server's + * #GTlsServerConnection:authentication_mode. On the server side, + * the signal is always emitted when the client presents a + * certificate, and the certificate will only be accepted if a + * handler returns %TRUE. + * + * Note that if this signal is emitted as part of asynchronous I/O + * in the main thread, then you should not attempt to interact with + * the user before returning from the signal handler. If you want to + * let the user decide whether or not to accept the certificate, you + * would have to return %FALSE from the signal handler on the first + * attempt, and then after the connection attempt returns a + * %G_TLS_ERROR_BAD_CERTIFICATE, you can interact with the user, and + * if the user decides to accept the certificate, remember that fact, + * create a new connection, and return %TRUE from the signal handler + * the next time. + * + * If you are doing I/O in another thread, you do not + * need to worry about this, and can simply block in the signal + * handler until the UI thread returns an answer. + * + * Returns: %TRUE to accept @peer_cert (which will also + * immediately end the signal emission). %FALSE to allow the signal + * emission to continue, which will cause the handshake to fail if + * no one else overrides it. + * + * Since: 2.28 + */ + signals[ACCEPT_CERTIFICATE] = + g_signal_new (I_("accept-certificate"), + G_TYPE_TLS_CONNECTION, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GTlsConnectionClass, accept_certificate), + g_signal_accumulator_true_handled, NULL, + _g_cclosure_marshal_BOOLEAN__OBJECT_FLAGS, + G_TYPE_BOOLEAN, 2, + G_TYPE_TLS_CERTIFICATE, + G_TYPE_TLS_CERTIFICATE_FLAGS); + g_signal_set_va_marshaller (signals[ACCEPT_CERTIFICATE], + G_TYPE_FROM_CLASS (klass), + _g_cclosure_marshal_BOOLEAN__OBJECT_FLAGSv); +} + +static void +g_tls_connection_init (GTlsConnection *conn) +{ +} + +static void +g_tls_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +} + +static void +g_tls_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +} + +/** + * g_tls_connection_set_use_system_certdb: + * @conn: a #GTlsConnection + * @use_system_certdb: whether to use the system certificate database + * + * Sets whether @conn uses the system certificate database to verify + * peer certificates. This is %TRUE by default. If set to %FALSE, then + * peer certificate validation will always set the + * %G_TLS_CERTIFICATE_UNKNOWN_CA error (meaning + * #GTlsConnection::accept-certificate will always be emitted on + * client-side connections, unless that bit is not set in + * #GTlsClientConnection:validation-flags). + * + * Deprecated: 2.30: Use g_tls_connection_set_database() instead + */ +void +g_tls_connection_set_use_system_certdb (GTlsConnection *conn, + gboolean use_system_certdb) +{ + g_return_if_fail (G_IS_TLS_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), + "use-system-certdb", use_system_certdb, + NULL); +} + +/** + * g_tls_connection_get_use_system_certdb: + * @conn: a #GTlsConnection + * + * Gets whether @conn uses the system certificate database to verify + * peer certificates. See g_tls_connection_set_use_system_certdb(). + * + * Returns: whether @conn uses the system certificate database + * + * Deprecated: 2.30: Use g_tls_connection_get_database() instead + */ +gboolean +g_tls_connection_get_use_system_certdb (GTlsConnection *conn) +{ + gboolean use_system_certdb; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), TRUE); + + g_object_get (G_OBJECT (conn), + "use-system-certdb", &use_system_certdb, + NULL); + return use_system_certdb; +} + +/** + * g_tls_connection_set_database: + * @conn: a #GTlsConnection + * @database: (nullable): a #GTlsDatabase + * + * Sets the certificate database that is used to verify peer certificates. + * This is set to the default database by default. See + * g_tls_backend_get_default_database(). If set to %NULL, then + * peer certificate validation will always set the + * %G_TLS_CERTIFICATE_UNKNOWN_CA error (meaning + * #GTlsConnection::accept-certificate will always be emitted on + * client-side connections, unless that bit is not set in + * #GTlsClientConnection:validation-flags). + * + * There are nonintuitive security implications when using a non-default + * database. See #GTlsConnection:database for details. + * + * Since: 2.30 + */ +void +g_tls_connection_set_database (GTlsConnection *conn, + GTlsDatabase *database) +{ + g_return_if_fail (G_IS_TLS_CONNECTION (conn)); + g_return_if_fail (database == NULL || G_IS_TLS_DATABASE (database)); + + g_object_set (G_OBJECT (conn), + "database", database, + NULL); +} + +/** + * g_tls_connection_get_database: + * @conn: a #GTlsConnection + * + * Gets the certificate database that @conn uses to verify + * peer certificates. See g_tls_connection_set_database(). + * + * Returns: (transfer none) (nullable): the certificate database that @conn uses or %NULL + * + * Since: 2.30 + */ +GTlsDatabase* +g_tls_connection_get_database (GTlsConnection *conn) +{ + GTlsDatabase *database = NULL; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), + "database", &database, + NULL); + if (database) + g_object_unref (database); + return database; +} + +/** + * g_tls_connection_set_certificate: + * @conn: a #GTlsConnection + * @certificate: the certificate to use for @conn + * + * This sets the certificate that @conn will present to its peer + * during the TLS handshake. For a #GTlsServerConnection, it is + * mandatory to set this, and that will normally be done at construct + * time. + * + * For a #GTlsClientConnection, this is optional. If a handshake fails + * with %G_TLS_ERROR_CERTIFICATE_REQUIRED, that means that the server + * requires a certificate, and if you try connecting again, you should + * call this method first. You can call + * g_tls_client_connection_get_accepted_cas() on the failed connection + * to get a list of Certificate Authorities that the server will + * accept certificates from. + * + * (It is also possible that a server will allow the connection with + * or without a certificate; in that case, if you don't provide a + * certificate, you can tell that the server requested one by the fact + * that g_tls_client_connection_get_accepted_cas() will return + * non-%NULL.) + * + * Since: 2.28 + */ +void +g_tls_connection_set_certificate (GTlsConnection *conn, + GTlsCertificate *certificate) +{ + g_return_if_fail (G_IS_TLS_CONNECTION (conn)); + g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate)); + + g_object_set (G_OBJECT (conn), "certificate", certificate, NULL); +} + +/** + * g_tls_connection_get_certificate: + * @conn: a #GTlsConnection + * + * Gets @conn's certificate, as set by + * g_tls_connection_set_certificate(). + * + * Returns: (transfer none) (nullable): @conn's certificate, or %NULL + * + * Since: 2.28 + */ +GTlsCertificate * +g_tls_connection_get_certificate (GTlsConnection *conn) +{ + GTlsCertificate *certificate; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), "certificate", &certificate, NULL); + if (certificate) + g_object_unref (certificate); + + return certificate; +} + +/** + * g_tls_connection_set_interaction: + * @conn: a connection + * @interaction: (nullable): an interaction object, or %NULL + * + * Set the object that will be used to interact with the user. It will be used + * for things like prompting the user for passwords. + * + * The @interaction argument will normally be a derived subclass of + * #GTlsInteraction. %NULL can also be provided if no user interaction + * should occur for this connection. + * + * Since: 2.30 + */ +void +g_tls_connection_set_interaction (GTlsConnection *conn, + GTlsInteraction *interaction) +{ + g_return_if_fail (G_IS_TLS_CONNECTION (conn)); + g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); + + g_object_set (G_OBJECT (conn), "interaction", interaction, NULL); +} + +/** + * g_tls_connection_get_interaction: + * @conn: a connection + * + * Get the object that will be used to interact with the user. It will be used + * for things like prompting the user for passwords. If %NULL is returned, then + * no user interaction will occur for this connection. + * + * Returns: (transfer none) (nullable): The interaction object. + * + * Since: 2.30 + */ +GTlsInteraction * +g_tls_connection_get_interaction (GTlsConnection *conn) +{ + GTlsInteraction *interaction = NULL; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), "interaction", &interaction, NULL); + if (interaction) + g_object_unref (interaction); + + return interaction; +} + +/** + * g_tls_connection_get_peer_certificate: + * @conn: a #GTlsConnection + * + * Gets @conn's peer's certificate after the handshake has completed + * or failed. (It is not set during the emission of + * #GTlsConnection::accept-certificate.) + * + * Returns: (transfer none) (nullable): @conn's peer's certificate, or %NULL + * + * Since: 2.28 + */ +GTlsCertificate * +g_tls_connection_get_peer_certificate (GTlsConnection *conn) +{ + GTlsCertificate *peer_certificate; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), "peer-certificate", &peer_certificate, NULL); + if (peer_certificate) + g_object_unref (peer_certificate); + + return peer_certificate; +} + +/** + * g_tls_connection_get_peer_certificate_errors: + * @conn: a #GTlsConnection + * + * Gets the errors associated with validating @conn's peer's + * certificate, after the handshake has completed or failed. (It is + * not set during the emission of #GTlsConnection::accept-certificate.) + * + * See #GTlsConnection:peer-certificate-errors for more information. + * + * Returns: @conn's peer's certificate errors + * + * Since: 2.28 + */ +GTlsCertificateFlags +g_tls_connection_get_peer_certificate_errors (GTlsConnection *conn) +{ + GTlsCertificateFlags errors; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), 0); + + g_object_get (G_OBJECT (conn), "peer-certificate-errors", &errors, NULL); + return errors; +} + +/** + * g_tls_connection_set_require_close_notify: + * @conn: a #GTlsConnection + * @require_close_notify: whether or not to require close notification + * + * Sets whether or not @conn expects a proper TLS close notification + * before the connection is closed. If this is %TRUE (the default), + * then @conn will expect to receive a TLS close notification from its + * peer before the connection is closed, and will return a + * %G_TLS_ERROR_EOF error if the connection is closed without proper + * notification (since this may indicate a network error, or + * man-in-the-middle attack). + * + * In some protocols, the application will know whether or not the + * connection was closed cleanly based on application-level data + * (because the application-level data includes a length field, or is + * somehow self-delimiting); in this case, the close notify is + * redundant and sometimes omitted. (TLS 1.1 explicitly allows this; + * in TLS 1.0 it is technically an error, but often done anyway.) You + * can use g_tls_connection_set_require_close_notify() to tell @conn + * to allow an "unannounced" connection close, in which case the close + * will show up as a 0-length read, as in a non-TLS + * #GSocketConnection, and it is up to the application to check that + * the data has been fully received. + * + * Note that this only affects the behavior when the peer closes the + * connection; when the application calls g_io_stream_close() itself + * on @conn, this will send a close notification regardless of the + * setting of this property. If you explicitly want to do an unclean + * close, you can close @conn's #GTlsConnection:base-io-stream rather + * than closing @conn itself, but note that this may only be done when no other + * operations are pending on @conn or the base I/O stream. + * + * Since: 2.28 + */ +void +g_tls_connection_set_require_close_notify (GTlsConnection *conn, + gboolean require_close_notify) +{ + g_return_if_fail (G_IS_TLS_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), + "require-close-notify", require_close_notify, + NULL); +} + +/** + * g_tls_connection_get_require_close_notify: + * @conn: a #GTlsConnection + * + * Tests whether or not @conn expects a proper TLS close notification + * when the connection is closed. See + * g_tls_connection_set_require_close_notify() for details. + * + * Returns: %TRUE if @conn requires a proper TLS close + * notification. + * + * Since: 2.28 + */ +gboolean +g_tls_connection_get_require_close_notify (GTlsConnection *conn) +{ + gboolean require_close_notify; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), TRUE); + + g_object_get (G_OBJECT (conn), + "require-close-notify", &require_close_notify, + NULL); + return require_close_notify; +} + +/** + * g_tls_connection_set_rehandshake_mode: + * @conn: a #GTlsConnection + * @mode: the rehandshaking mode + * + * Since GLib 2.64, changing the rehandshake mode is no longer supported + * and will have no effect. With TLS 1.3, rehandshaking has been removed from + * the TLS protocol, replaced by separate post-handshake authentication and + * rekey operations. + * + * Since: 2.28 + * + * Deprecated: 2.60. Changing the rehandshake mode is no longer + * required for compatibility. Also, rehandshaking has been removed + * from the TLS protocol in TLS 1.3. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +void +g_tls_connection_set_rehandshake_mode (GTlsConnection *conn, + GTlsRehandshakeMode mode) +{ + g_return_if_fail (G_IS_TLS_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), + "rehandshake-mode", G_TLS_REHANDSHAKE_SAFELY, + NULL); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_tls_connection_get_rehandshake_mode: + * @conn: a #GTlsConnection + * + * Gets @conn rehandshaking mode. See + * g_tls_connection_set_rehandshake_mode() for details. + * + * Returns: %G_TLS_REHANDSHAKE_SAFELY + * + * Since: 2.28 + * + * Deprecated: 2.60. Changing the rehandshake mode is no longer + * required for compatibility. Also, rehandshaking has been removed + * from the TLS protocol in TLS 1.3. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GTlsRehandshakeMode +g_tls_connection_get_rehandshake_mode (GTlsConnection *conn) +{ + GTlsRehandshakeMode mode; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), G_TLS_REHANDSHAKE_SAFELY); + + /* Continue to call g_object_get(), even though the return value is + * ignored, so that behavior doesn’t change for derived classes. + */ + g_object_get (G_OBJECT (conn), + "rehandshake-mode", &mode, + NULL); + return G_TLS_REHANDSHAKE_SAFELY; +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_tls_connection_set_advertised_protocols: + * @conn: a #GTlsConnection + * @protocols: (array zero-terminated=1) (nullable): a %NULL-terminated + * array of ALPN protocol names (eg, "http/1.1", "h2"), or %NULL + * + * Sets the list of application-layer protocols to advertise that the + * caller is willing to speak on this connection. The + * Application-Layer Protocol Negotiation (ALPN) extension will be + * used to negotiate a compatible protocol with the peer; use + * g_tls_connection_get_negotiated_protocol() to find the negotiated + * protocol after the handshake. Specifying %NULL for the the value + * of @protocols will disable ALPN negotiation. + * + * See [IANA TLS ALPN Protocol IDs](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids) + * for a list of registered protocol IDs. + * + * Since: 2.60 + */ +void +g_tls_connection_set_advertised_protocols (GTlsConnection *conn, + const gchar * const *protocols) +{ + g_return_if_fail (G_IS_TLS_CONNECTION (conn)); + + g_object_set (G_OBJECT (conn), + "advertised-protocols", protocols, + NULL); +} + +/** + * g_tls_connection_get_negotiated_protocol: + * @conn: a #GTlsConnection + * + * Gets the name of the application-layer protocol negotiated during + * the handshake. + * + * If the peer did not use the ALPN extension, or did not advertise a + * protocol that matched one of @conn's protocols, or the TLS backend + * does not support ALPN, then this will be %NULL. See + * g_tls_connection_set_advertised_protocols(). + * + * Returns: (nullable): the negotiated protocol, or %NULL + * + * Since: 2.60 + */ +const gchar * +g_tls_connection_get_negotiated_protocol (GTlsConnection *conn) +{ + GTlsConnectionClass *class; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL); + + class = G_TLS_CONNECTION_GET_CLASS (conn); + if (class->get_negotiated_protocol == NULL) + return NULL; + + return class->get_negotiated_protocol (conn); +} + +/** + * g_tls_channel_binding_error_quark: + * + * Gets the TLS channel binding error quark. + * + * Returns: a #GQuark. + * + * Since: 2.66 + */ +G_DEFINE_QUARK (g-tls-channel-binding-error-quark, g_tls_channel_binding_error) + +/** + * g_tls_connection_get_channel_binding_data: + * @conn: a #GTlsConnection + * @type: #GTlsChannelBindingType type of data to fetch + * @data: (out callee-allocates)(optional)(transfer none): #GByteArray is + * filled with the binding data, or %NULL + * @error: a #GError pointer, or %NULL + * + * Query the TLS backend for TLS channel binding data of @type for @conn. + * + * This call retrieves TLS channel binding data as specified in RFC + * [5056](https://tools.ietf.org/html/rfc5056), RFC + * [5929](https://tools.ietf.org/html/rfc5929), and related RFCs. The + * binding data is returned in @data. The @data is resized by the callee + * using #GByteArray buffer management and will be freed when the @data + * is destroyed by g_byte_array_unref(). If @data is %NULL, it will only + * check whether TLS backend is able to fetch the data (e.g. whether @type + * is supported by the TLS backend). It does not guarantee that the data + * will be available though. That could happen if TLS connection does not + * support @type or the binding data is not available yet due to additional + * negotiation or input required. + * + * Returns: %TRUE on success, %FALSE otherwise + * + * Since: 2.66 + */ +gboolean +g_tls_connection_get_channel_binding_data (GTlsConnection *conn, + GTlsChannelBindingType type, + GByteArray *data, + GError **error) +{ + GTlsConnectionClass *class; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + class = G_TLS_CONNECTION_GET_CLASS (conn); + if (class->get_binding_data == NULL) + { + g_set_error_literal (error, G_TLS_CHANNEL_BINDING_ERROR, + G_TLS_CHANNEL_BINDING_ERROR_NOT_IMPLEMENTED, + _("TLS backend does not implement TLS binding retrieval")); + return FALSE; + } + + return class->get_binding_data (conn, type, data, error); +} + +/** + * g_tls_connection_handshake: + * @conn: a #GTlsConnection + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: a #GError, or %NULL + * + * Attempts a TLS handshake on @conn. + * + * On the client side, it is never necessary to call this method; + * although the connection needs to perform a handshake after + * connecting (or after sending a "STARTTLS"-type command), + * #GTlsConnection will handle this for you automatically when you try + * to send or receive data on the connection. You can call + * g_tls_connection_handshake() manually if you want to know whether + * the initial handshake succeeded or failed (as opposed to just + * immediately trying to use @conn to read or write, in which case, + * if it fails, it may not be possible to tell if it failed before or + * after completing the handshake), but beware that servers may reject + * client authentication after the handshake has completed, so a + * successful handshake does not indicate the connection will be usable. + * + * Likewise, on the server side, although a handshake is necessary at + * the beginning of the communication, you do not need to call this + * function explicitly unless you want clearer error reporting. + * + * Previously, calling g_tls_connection_handshake() after the initial + * handshake would trigger a rehandshake; however, this usage was + * deprecated in GLib 2.60 because rehandshaking was removed from the + * TLS protocol in TLS 1.3. Since GLib 2.64, calling this function after + * the initial handshake will no longer do anything. + * + * When using a #GTlsConnection created by #GSocketClient, the + * #GSocketClient performs the initial handshake, so calling this + * function manually is not recommended. + * + * #GTlsConnection::accept_certificate may be emitted during the + * handshake. + * + * Returns: success or failure + * + * Since: 2.28 + */ +gboolean +g_tls_connection_handshake (GTlsConnection *conn, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), FALSE); + + return G_TLS_CONNECTION_GET_CLASS (conn)->handshake (conn, cancellable, error); +} + +/** + * g_tls_connection_handshake_async: + * @conn: a #GTlsConnection + * @io_priority: the [I/O priority][io-priority] of the request + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: callback to call when the handshake is complete + * @user_data: the data to pass to the callback function + * + * Asynchronously performs a TLS handshake on @conn. See + * g_tls_connection_handshake() for more information. + * + * Since: 2.28 + */ +void +g_tls_connection_handshake_async (GTlsConnection *conn, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_TLS_CONNECTION (conn)); + + G_TLS_CONNECTION_GET_CLASS (conn)->handshake_async (conn, io_priority, + cancellable, + callback, user_data); +} + +/** + * g_tls_connection_handshake_finish: + * @conn: a #GTlsConnection + * @result: a #GAsyncResult. + * @error: a #GError pointer, or %NULL + * + * Finish an asynchronous TLS handshake operation. See + * g_tls_connection_handshake() for more information. + * + * Returns: %TRUE on success, %FALSE on failure, in which + * case @error will be set. + * + * Since: 2.28 + */ +gboolean +g_tls_connection_handshake_finish (GTlsConnection *conn, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), FALSE); + + return G_TLS_CONNECTION_GET_CLASS (conn)->handshake_finish (conn, result, error); +} + +/** + * g_tls_connection_get_protocol_version: + * @conn: a #GTlsConnection + * + * Returns the current TLS protocol version, which may be + * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the connection has not handshaked, or + * has been closed, or if the TLS backend has implemented a protocol version + * that is not a recognized #GTlsProtocolVersion. + * + * Returns: The current TLS protocol version + * + * Since: 2.70 + */ +GTlsProtocolVersion +g_tls_connection_get_protocol_version (GTlsConnection *conn) +{ + GTlsProtocolVersion protocol_version; + GEnumClass *enum_class; + GEnumValue *enum_value; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), G_TLS_PROTOCOL_VERSION_UNKNOWN); + + g_object_get (G_OBJECT (conn), + "protocol-version", &protocol_version, + NULL); + + /* Convert unknown values to G_TLS_PROTOCOL_VERSION_UNKNOWN. */ + enum_class = g_type_class_peek_static (G_TYPE_TLS_PROTOCOL_VERSION); + enum_value = g_enum_get_value (enum_class, protocol_version); + return enum_value ? protocol_version : G_TLS_PROTOCOL_VERSION_UNKNOWN; +} + +/** + * g_tls_connection_get_ciphersuite_name: + * @conn: a #GTlsConnection + * + * Returns the name of the current TLS ciphersuite, or %NULL if the + * connection has not handshaked or has been closed. Beware that the TLS + * backend may use any of multiple different naming conventions, because + * OpenSSL and GnuTLS have their own ciphersuite naming conventions that + * are different from each other and different from the standard, IANA- + * registered ciphersuite names. The ciphersuite name is intended to be + * displayed to the user for informative purposes only, and parsing it + * is not recommended. + * + * Returns: (nullable): The name of the current TLS ciphersuite, or %NULL + * + * Since: 2.70 + */ +gchar * +g_tls_connection_get_ciphersuite_name (GTlsConnection *conn) +{ + gchar *ciphersuite_name; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), + "ciphersuite-name", &ciphersuite_name, + NULL); + + return g_steal_pointer (&ciphersuite_name); +} + +/** + * g_tls_error_quark: + * + * Gets the TLS error quark. + * + * Returns: a #GQuark. + * + * Since: 2.28 + */ +G_DEFINE_QUARK (g-tls-error-quark, g_tls_error) + +/** + * g_tls_connection_emit_accept_certificate: + * @conn: a #GTlsConnection + * @peer_cert: the peer's #GTlsCertificate + * @errors: the problems with @peer_cert + * + * Used by #GTlsConnection implementations to emit the + * #GTlsConnection::accept-certificate signal. + * + * Returns: %TRUE if one of the signal handlers has returned + * %TRUE to accept @peer_cert + * + * Since: 2.28 + */ +gboolean +g_tls_connection_emit_accept_certificate (GTlsConnection *conn, + GTlsCertificate *peer_cert, + GTlsCertificateFlags errors) +{ + gboolean accept = FALSE; + + g_signal_emit (conn, signals[ACCEPT_CERTIFICATE], 0, + peer_cert, errors, &accept); + return accept; +} diff --git a/gio/gtlsconnection.h b/gio/gtlsconnection.h new file mode 100644 index 0000000..526eb60 --- /dev/null +++ b/gio/gtlsconnection.h @@ -0,0 +1,212 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_TLS_CONNECTION_H__ +#define __G_TLS_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TLS_CONNECTION (g_tls_connection_get_type ()) +#define G_TLS_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_CONNECTION, GTlsConnection)) +#define G_TLS_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_TLS_CONNECTION, GTlsConnectionClass)) +#define G_IS_TLS_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_CONNECTION)) +#define G_IS_TLS_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_TLS_CONNECTION)) +#define G_TLS_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), G_TYPE_TLS_CONNECTION, GTlsConnectionClass)) + +typedef struct _GTlsConnectionClass GTlsConnectionClass; +typedef struct _GTlsConnectionPrivate GTlsConnectionPrivate; + +struct _GTlsConnection { + GIOStream parent_instance; + + GTlsConnectionPrivate *priv; +}; + +/** + * GTlsConnectionClass: + * @parent_class: The parent class. + * @accept_certificate: Check whether to accept a certificate. + * @handshake: Perform a handshake operation. + * @handshake_async: Start an asynchronous handshake operation. + * @handshake_finish: Finish an asynchronous handshake operation. + * @get_binding_data: Retrieve TLS channel binding data (Since: 2.66) + * @get_negotiated_protocol: Get ALPN-negotiated protocol (Since: 2.70) + * + * The class structure for the #GTlsConnection type. + * + * Since: 2.28 + */ +struct _GTlsConnectionClass +{ + GIOStreamClass parent_class; + + /* signals */ + gboolean ( *accept_certificate) (GTlsConnection *connection, + GTlsCertificate *peer_cert, + GTlsCertificateFlags errors); + + /* methods */ + gboolean ( *handshake ) (GTlsConnection *conn, + GCancellable *cancellable, + GError **error); + + void ( *handshake_async ) (GTlsConnection *conn, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean ( *handshake_finish ) (GTlsConnection *conn, + GAsyncResult *result, + GError **error); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + gboolean ( *get_binding_data) (GTlsConnection *conn, + GTlsChannelBindingType type, + GByteArray *data, + GError **error); +G_GNUC_END_IGNORE_DEPRECATIONS + + const gchar *(*get_negotiated_protocol) (GTlsConnection *conn); + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[6]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_connection_get_type (void) G_GNUC_CONST; + +GLIB_DEPRECATED +void g_tls_connection_set_use_system_certdb (GTlsConnection *conn, + gboolean use_system_certdb); +GLIB_DEPRECATED +gboolean g_tls_connection_get_use_system_certdb (GTlsConnection *conn); + +GLIB_AVAILABLE_IN_ALL +void g_tls_connection_set_database (GTlsConnection *conn, + GTlsDatabase *database); +GLIB_AVAILABLE_IN_ALL +GTlsDatabase * g_tls_connection_get_database (GTlsConnection *conn); + +GLIB_AVAILABLE_IN_ALL +void g_tls_connection_set_certificate (GTlsConnection *conn, + GTlsCertificate *certificate); +GLIB_AVAILABLE_IN_ALL +GTlsCertificate *g_tls_connection_get_certificate (GTlsConnection *conn); + +GLIB_AVAILABLE_IN_ALL +void g_tls_connection_set_interaction (GTlsConnection *conn, + GTlsInteraction *interaction); +GLIB_AVAILABLE_IN_ALL +GTlsInteraction * g_tls_connection_get_interaction (GTlsConnection *conn); + +GLIB_AVAILABLE_IN_ALL +GTlsCertificate *g_tls_connection_get_peer_certificate (GTlsConnection *conn); +GLIB_AVAILABLE_IN_ALL +GTlsCertificateFlags g_tls_connection_get_peer_certificate_errors (GTlsConnection *conn); + +GLIB_AVAILABLE_IN_ALL +void g_tls_connection_set_require_close_notify (GTlsConnection *conn, + gboolean require_close_notify); +GLIB_AVAILABLE_IN_ALL +gboolean g_tls_connection_get_require_close_notify (GTlsConnection *conn); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_DEPRECATED_IN_2_60 +void g_tls_connection_set_rehandshake_mode (GTlsConnection *conn, + GTlsRehandshakeMode mode); +GLIB_DEPRECATED_IN_2_60 +GTlsRehandshakeMode g_tls_connection_get_rehandshake_mode (GTlsConnection *conn); +G_GNUC_END_IGNORE_DEPRECATIONS + +GLIB_AVAILABLE_IN_2_60 +void g_tls_connection_set_advertised_protocols (GTlsConnection *conn, + const gchar * const *protocols); + +GLIB_AVAILABLE_IN_2_60 +const gchar * g_tls_connection_get_negotiated_protocol (GTlsConnection *conn); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_AVAILABLE_IN_2_66 +gboolean g_tls_connection_get_channel_binding_data (GTlsConnection *conn, + GTlsChannelBindingType type, + GByteArray *data, + GError **error); +G_GNUC_END_IGNORE_DEPRECATIONS + +GLIB_AVAILABLE_IN_ALL +gboolean g_tls_connection_handshake (GTlsConnection *conn, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_tls_connection_handshake_async (GTlsConnection *conn, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_tls_connection_handshake_finish (GTlsConnection *conn, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_70 +GTlsProtocolVersion g_tls_connection_get_protocol_version (GTlsConnection *conn); + +GLIB_AVAILABLE_IN_2_70 +gchar * g_tls_connection_get_ciphersuite_name (GTlsConnection *conn); + +/** + * G_TLS_ERROR: + * + * Error domain for TLS. Errors in this domain will be from the + * #GTlsError enumeration. See #GError for more information on error + * domains. + */ +#define G_TLS_ERROR (g_tls_error_quark ()) +GLIB_AVAILABLE_IN_ALL +GQuark g_tls_error_quark (void); + +/** + * G_TLS_CHANNEL_BINDING_ERROR: + * + * Error domain for TLS channel binding. Errors in this domain will be from the + * #GTlsChannelBindingError enumeration. See #GError for more information on error + * domains. + * + * Since: 2.66 + */ +#define G_TLS_CHANNEL_BINDING_ERROR (g_tls_channel_binding_error_quark ()) +GLIB_AVAILABLE_IN_2_66 +GQuark g_tls_channel_binding_error_quark (void); + +/*< protected >*/ +GLIB_AVAILABLE_IN_ALL +gboolean g_tls_connection_emit_accept_certificate (GTlsConnection *conn, + GTlsCertificate *peer_cert, + GTlsCertificateFlags errors); + +G_END_DECLS + +#endif /* __G_TLS_CONNECTION_H__ */ diff --git a/gio/gtlsdatabase.c b/gio/gtlsdatabase.c new file mode 100644 index 0000000..7027b12 --- /dev/null +++ b/gio/gtlsdatabase.c @@ -0,0 +1,1034 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#include "config.h" + +#include "gtlsdatabase.h" + +#include "gasyncresult.h" +#include "gcancellable.h" +#include "glibintl.h" +#include "gsocketconnectable.h" +#include "gtask.h" +#include "gtlscertificate.h" +#include "gtlsinteraction.h" + +/** + * SECTION:gtlsdatabase + * @short_description: TLS database type + * @include: gio/gio.h + * + * #GTlsDatabase is used to look up certificates and other information + * from a certificate or key store. It is an abstract base class which + * TLS library specific subtypes override. + * + * A #GTlsDatabase may be accessed from multiple threads by the TLS backend. + * All implementations are required to be fully thread-safe. + * + * Most common client applications will not directly interact with + * #GTlsDatabase. It is used internally by #GTlsConnection. + * + * Since: 2.30 + */ + +/** + * GTlsDatabase: + * + * Abstract base class for the backend-specific database types. + * + * Since: 2.30 + */ + +/** + * GTlsDatabaseClass: + * @verify_chain: Virtual method implementing + * g_tls_database_verify_chain(). + * @verify_chain_async: Virtual method implementing + * g_tls_database_verify_chain_async(). + * @verify_chain_finish: Virtual method implementing + * g_tls_database_verify_chain_finish(). + * @create_certificate_handle: Virtual method implementing + * g_tls_database_create_certificate_handle(). + * @lookup_certificate_for_handle: Virtual method implementing + * g_tls_database_lookup_certificate_for_handle(). + * @lookup_certificate_for_handle_async: Virtual method implementing + * g_tls_database_lookup_certificate_for_handle_async(). + * @lookup_certificate_for_handle_finish: Virtual method implementing + * g_tls_database_lookup_certificate_for_handle_finish(). + * @lookup_certificate_issuer: Virtual method implementing + * g_tls_database_lookup_certificate_issuer(). + * @lookup_certificate_issuer_async: Virtual method implementing + * g_tls_database_lookup_certificate_issuer_async(). + * @lookup_certificate_issuer_finish: Virtual method implementing + * g_tls_database_lookup_certificate_issuer_finish(). + * @lookup_certificates_issued_by: Virtual method implementing + * g_tls_database_lookup_certificates_issued_by(). + * @lookup_certificates_issued_by_async: Virtual method implementing + * g_tls_database_lookup_certificates_issued_by_async(). + * @lookup_certificates_issued_by_finish: Virtual method implementing + * g_tls_database_lookup_certificates_issued_by_finish(). + * + * The class for #GTlsDatabase. Derived classes should implement the various + * virtual methods. _async and _finish methods have a default + * implementation that runs the corresponding sync method in a thread. + * + * Since: 2.30 + */ + +G_DEFINE_ABSTRACT_TYPE (GTlsDatabase, g_tls_database, G_TYPE_OBJECT) + +enum { + UNLOCK_REQUIRED, + + LAST_SIGNAL +}; + +/** + * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER: + * + * The purpose used to verify the server certificate in a TLS connection. This + * is the most common purpose in use. Used by TLS clients. + */ + +/** + * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT: + * + * The purpose used to verify the client certificate in a TLS connection. + * Used by TLS servers. + */ + +static void +g_tls_database_init (GTlsDatabase *cert) +{ + +} + +typedef struct _AsyncVerifyChain { + GTlsCertificate *chain; + gchar *purpose; + GSocketConnectable *identity; + GTlsInteraction *interaction; + GTlsDatabaseVerifyFlags flags; +} AsyncVerifyChain; + +static void +async_verify_chain_free (gpointer data) +{ + AsyncVerifyChain *args = data; + g_clear_object (&args->chain); + g_free (args->purpose); + g_clear_object (&args->identity); + g_clear_object (&args->interaction); + g_slice_free (AsyncVerifyChain, args); +} + +static void +async_verify_chain_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + AsyncVerifyChain *args = task_data; + GTlsCertificateFlags verify_result; + GError *error = NULL; + + verify_result = g_tls_database_verify_chain (G_TLS_DATABASE (object), + args->chain, + args->purpose, + args->identity, + args->interaction, + args->flags, + cancellable, + &error); + if (error) + g_task_return_error (task, error); + else + g_task_return_int (task, (gssize)verify_result); +} + +static void +g_tls_database_real_verify_chain_async (GTlsDatabase *self, + GTlsCertificate *chain, + const gchar *purpose, + GSocketConnectable *identity, + GTlsInteraction *interaction, + GTlsDatabaseVerifyFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + AsyncVerifyChain *args; + + args = g_slice_new0 (AsyncVerifyChain); + args->chain = g_object_ref (chain); + args->purpose = g_strdup (purpose); + args->identity = identity ? g_object_ref (identity) : NULL; + args->interaction = interaction ? g_object_ref (interaction) : NULL; + args->flags = flags; + + task = g_task_new (self, cancellable, callback, user_data); + g_task_set_source_tag (task, g_tls_database_real_verify_chain_async); + g_task_set_name (task, "[gio] verify TLS chain"); + g_task_set_task_data (task, args, async_verify_chain_free); + g_task_run_in_thread (task, async_verify_chain_thread); + g_object_unref (task); +} + +static GTlsCertificateFlags +g_tls_database_real_verify_chain_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error) +{ + GTlsCertificateFlags ret; + + g_return_val_if_fail (g_task_is_valid (result, self), G_TLS_CERTIFICATE_GENERIC_ERROR); + + ret = (GTlsCertificateFlags)g_task_propagate_int (G_TASK (result), error); + if (ret == (GTlsCertificateFlags)-1) + return G_TLS_CERTIFICATE_GENERIC_ERROR; + else + return ret; +} + +typedef struct { + gchar *handle; + GTlsInteraction *interaction; + GTlsDatabaseLookupFlags flags; +} AsyncLookupCertificateForHandle; + +static void +async_lookup_certificate_for_handle_free (gpointer data) +{ + AsyncLookupCertificateForHandle *args = data; + + g_free (args->handle); + g_clear_object (&args->interaction); + g_slice_free (AsyncLookupCertificateForHandle, args); +} + +static void +async_lookup_certificate_for_handle_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + AsyncLookupCertificateForHandle *args = task_data; + GTlsCertificate *result; + GError *error = NULL; + + result = g_tls_database_lookup_certificate_for_handle (G_TLS_DATABASE (object), + args->handle, + args->interaction, + args->flags, + cancellable, + &error); + if (result) + g_task_return_pointer (task, result, g_object_unref); + else + g_task_return_error (task, error); +} + +static void +g_tls_database_real_lookup_certificate_for_handle_async (GTlsDatabase *self, + const gchar *handle, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + AsyncLookupCertificateForHandle *args; + + args = g_slice_new0 (AsyncLookupCertificateForHandle); + args->handle = g_strdup (handle); + args->interaction = interaction ? g_object_ref (interaction) : NULL; + + task = g_task_new (self, cancellable, callback, user_data); + g_task_set_source_tag (task, + g_tls_database_real_lookup_certificate_for_handle_async); + g_task_set_name (task, "[gio] lookup TLS certificate"); + g_task_set_task_data (task, args, async_lookup_certificate_for_handle_free); + g_task_run_in_thread (task, async_lookup_certificate_for_handle_thread); + g_object_unref (task); +} + +static GTlsCertificate* +g_tls_database_real_lookup_certificate_for_handle_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, self), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + + +typedef struct { + GTlsCertificate *certificate; + GTlsInteraction *interaction; + GTlsDatabaseLookupFlags flags; +} AsyncLookupCertificateIssuer; + +static void +async_lookup_certificate_issuer_free (gpointer data) +{ + AsyncLookupCertificateIssuer *args = data; + + g_clear_object (&args->certificate); + g_clear_object (&args->interaction); + g_slice_free (AsyncLookupCertificateIssuer, args); +} + +static void +async_lookup_certificate_issuer_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + AsyncLookupCertificateIssuer *args = task_data; + GTlsCertificate *issuer; + GError *error = NULL; + + issuer = g_tls_database_lookup_certificate_issuer (G_TLS_DATABASE (object), + args->certificate, + args->interaction, + args->flags, + cancellable, + &error); + if (issuer) + g_task_return_pointer (task, issuer, g_object_unref); + else + g_task_return_error (task, error); +} + +static void +g_tls_database_real_lookup_certificate_issuer_async (GTlsDatabase *self, + GTlsCertificate *certificate, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + AsyncLookupCertificateIssuer *args; + + args = g_slice_new0 (AsyncLookupCertificateIssuer); + args->certificate = g_object_ref (certificate); + args->flags = flags; + args->interaction = interaction ? g_object_ref (interaction) : NULL; + + task = g_task_new (self, cancellable, callback, user_data); + g_task_set_source_tag (task, + g_tls_database_real_lookup_certificate_issuer_async); + g_task_set_name (task, "[gio] lookup certificate issuer"); + g_task_set_task_data (task, args, async_lookup_certificate_issuer_free); + g_task_run_in_thread (task, async_lookup_certificate_issuer_thread); + g_object_unref (task); +} + +static GTlsCertificate * +g_tls_database_real_lookup_certificate_issuer_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, self), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +typedef struct { + GByteArray *issuer; + GTlsInteraction *interaction; + GTlsDatabaseLookupFlags flags; +} AsyncLookupCertificatesIssuedBy; + +static void +async_lookup_certificates_issued_by_free (gpointer data) +{ + AsyncLookupCertificatesIssuedBy *args = data; + + g_byte_array_unref (args->issuer); + g_clear_object (&args->interaction); + g_slice_free (AsyncLookupCertificatesIssuedBy, args); +} + +static void +async_lookup_certificates_free_certificates (gpointer data) +{ + GList *list = data; + + g_list_free_full (list, g_object_unref); +} + +static void +async_lookup_certificates_issued_by_thread (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + AsyncLookupCertificatesIssuedBy *args = task_data; + GList *results; + GError *error = NULL; + + results = g_tls_database_lookup_certificates_issued_by (G_TLS_DATABASE (object), + args->issuer, + args->interaction, + args->flags, + cancellable, + &error); + if (results) + g_task_return_pointer (task, results, async_lookup_certificates_free_certificates); + else + g_task_return_error (task, error); +} + +static void +g_tls_database_real_lookup_certificates_issued_by_async (GTlsDatabase *self, + GByteArray *issuer, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + AsyncLookupCertificatesIssuedBy *args; + + args = g_slice_new0 (AsyncLookupCertificatesIssuedBy); + args->issuer = g_byte_array_ref (issuer); + args->flags = flags; + args->interaction = interaction ? g_object_ref (interaction) : NULL; + + task = g_task_new (self, cancellable, callback, user_data); + g_task_set_source_tag (task, + g_tls_database_real_lookup_certificates_issued_by_async); + g_task_set_name (task, "[gio] lookup certificates issued by"); + g_task_set_task_data (task, args, async_lookup_certificates_issued_by_free); + g_task_run_in_thread (task, async_lookup_certificates_issued_by_thread); + g_object_unref (task); +} + +static GList * +g_tls_database_real_lookup_certificates_issued_by_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, self), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +g_tls_database_class_init (GTlsDatabaseClass *klass) +{ + klass->verify_chain_async = g_tls_database_real_verify_chain_async; + klass->verify_chain_finish = g_tls_database_real_verify_chain_finish; + klass->lookup_certificate_for_handle_async = g_tls_database_real_lookup_certificate_for_handle_async; + klass->lookup_certificate_for_handle_finish = g_tls_database_real_lookup_certificate_for_handle_finish; + klass->lookup_certificate_issuer_async = g_tls_database_real_lookup_certificate_issuer_async; + klass->lookup_certificate_issuer_finish = g_tls_database_real_lookup_certificate_issuer_finish; + klass->lookup_certificates_issued_by_async = g_tls_database_real_lookup_certificates_issued_by_async; + klass->lookup_certificates_issued_by_finish = g_tls_database_real_lookup_certificates_issued_by_finish; +} + +/** + * g_tls_database_verify_chain: + * @self: a #GTlsDatabase + * @chain: a #GTlsCertificate chain + * @purpose: the purpose that this certificate chain will be used for. + * @identity: (nullable): the expected peer identity + * @interaction: (nullable): used to interact with the user if necessary + * @flags: additional verify flags + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: (nullable): a #GError, or %NULL + * + * Determines the validity of a certificate chain, outside the context + * of a TLS session. + * + * @chain is a chain of #GTlsCertificate objects each pointing to the next + * certificate in the chain by its #GTlsCertificate:issuer property. + * + * @purpose describes the purpose (or usage) for which the certificate + * is being used. Typically @purpose will be set to %G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER + * which means that the certificate is being used to authenticate a server + * (and we are acting as the client). + * + * The @identity is used to ensure the server certificate is valid for + * the expected peer identity. If the identity does not match the + * certificate, %G_TLS_CERTIFICATE_BAD_IDENTITY will be set in the + * return value. If @identity is %NULL, that bit will never be set in + * the return value. The peer identity may also be used to check for + * pinned certificates (trust exceptions) in the database. These may + * override the normal verification process on a host-by-host basis. + * + * Currently there are no @flags, and %G_TLS_DATABASE_VERIFY_NONE should be + * used. + * + * If @chain is found to be valid, then the return value will be 0. If + * @chain is found to be invalid, then the return value will indicate at + * least one problem found. If the function is unable to determine + * whether @chain is valid (for example, because @cancellable is + * triggered before it completes) then the return value will be + * %G_TLS_CERTIFICATE_GENERIC_ERROR and @error will be set accordingly. + * @error is not set when @chain is successfully analyzed but found to + * be invalid. + * + * GLib guarantees that if certificate verification fails, at least one + * error will be set in the return value, but it does not guarantee + * that all possible errors will be set. Accordingly, you may not safely + * decide to ignore any particular type of error. For example, it would + * be incorrect to mask %G_TLS_CERTIFICATE_EXPIRED if you want to allow + * expired certificates, because this could potentially be the only + * error flag set even if other problems exist with the certificate. + * + * Prior to GLib 2.48, GLib's default TLS backend modified @chain to + * represent the certification path built by #GTlsDatabase during + * certificate verification by adjusting the #GTlsCertificate:issuer + * property of each certificate in @chain. Since GLib 2.48, this no + * longer occurs, so you cannot rely on #GTlsCertificate:issuer to + * represent the actual certification path used during certificate + * verification. + * + * Because TLS session context is not used, #GTlsDatabase may not + * perform as many checks on the certificates as #GTlsConnection would. + * For example, certificate constraints may not be honored, and + * revocation checks may not be performed. The best way to verify TLS + * certificates used by a TLS connection is to let #GTlsConnection + * handle the verification. + * + * The TLS backend may attempt to look up and add missing certificates + * to the chain. This may involve HTTP requests to download missing + * certificates. + * + * This function can block. Use g_tls_database_verify_chain_async() to + * perform the verification operation asynchronously. + * + * Returns: the appropriate #GTlsCertificateFlags which represents the + * result of verification. + * + * Since: 2.30 + */ +GTlsCertificateFlags +g_tls_database_verify_chain (GTlsDatabase *self, + GTlsCertificate *chain, + const gchar *purpose, + GSocketConnectable *identity, + GTlsInteraction *interaction, + GTlsDatabaseVerifyFlags flags, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR); + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (chain), + G_TLS_CERTIFICATE_GENERIC_ERROR); + g_return_val_if_fail (purpose, G_TLS_CERTIFICATE_GENERIC_ERROR); + g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), + G_TLS_CERTIFICATE_GENERIC_ERROR); + g_return_val_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity), + G_TLS_CERTIFICATE_GENERIC_ERROR); + g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR); + + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain, + G_TLS_CERTIFICATE_GENERIC_ERROR); + + return G_TLS_DATABASE_GET_CLASS (self)->verify_chain (self, + chain, + purpose, + identity, + interaction, + flags, + cancellable, + error); +} + +/** + * g_tls_database_verify_chain_async: + * @self: a #GTlsDatabase + * @chain: a #GTlsCertificate chain + * @purpose: the purpose that this certificate chain will be used for. + * @identity: (nullable): the expected peer identity + * @interaction: (nullable): used to interact with the user if necessary + * @flags: additional verify flags + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: callback to call when the operation completes + * @user_data: the data to pass to the callback function + * + * Asynchronously determines the validity of a certificate chain after + * looking up and adding any missing certificates to the chain. See + * g_tls_database_verify_chain() for more information. + * + * Since: 2.30 + */ +void +g_tls_database_verify_chain_async (GTlsDatabase *self, + GTlsCertificate *chain, + const gchar *purpose, + GSocketConnectable *identity, + GTlsInteraction *interaction, + GTlsDatabaseVerifyFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_TLS_DATABASE (self)); + g_return_if_fail (G_IS_TLS_CERTIFICATE (chain)); + g_return_if_fail (purpose != NULL); + g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_return_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity)); + g_return_if_fail (callback != NULL); + + g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async); + G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async (self, + chain, + purpose, + identity, + interaction, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_tls_database_verify_chain_finish: + * @self: a #GTlsDatabase + * @result: a #GAsyncResult. + * @error: a #GError pointer, or %NULL + * + * Finish an asynchronous verify chain operation. See + * g_tls_database_verify_chain() for more information. + * + * If @chain is found to be valid, then the return value will be 0. If + * @chain is found to be invalid, then the return value will indicate + * the problems found. If the function is unable to determine whether + * @chain is valid or not (eg, because @cancellable is triggered + * before it completes) then the return value will be + * %G_TLS_CERTIFICATE_GENERIC_ERROR and @error will be set + * accordingly. @error is not set when @chain is successfully analyzed + * but found to be invalid. + * + * Returns: the appropriate #GTlsCertificateFlags which represents the + * result of verification. + * + * Since: 2.30 + */ +GTlsCertificateFlags +g_tls_database_verify_chain_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_CERTIFICATE_GENERIC_ERROR); + g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR); + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish, + G_TLS_CERTIFICATE_GENERIC_ERROR); + return G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish (self, + result, + error); +} + +/** + * g_tls_database_create_certificate_handle: + * @self: a #GTlsDatabase + * @certificate: certificate for which to create a handle. + * + * Create a handle string for the certificate. The database will only be able + * to create a handle for certificates that originate from the database. In + * cases where the database cannot create a handle for a certificate, %NULL + * will be returned. + * + * This handle should be stable across various instances of the application, + * and between applications. If a certificate is modified in the database, + * then it is not guaranteed that this handle will continue to point to it. + * + * Returns: (nullable): a newly allocated string containing the + * handle. + * + * Since: 2.30 + */ +gchar* +g_tls_database_create_certificate_handle (GTlsDatabase *self, + GTlsCertificate *certificate) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL); + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle, NULL); + return G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle (self, + certificate); +} + +/** + * g_tls_database_lookup_certificate_for_handle: + * @self: a #GTlsDatabase + * @handle: a certificate handle + * @interaction: (nullable): used to interact with the user if necessary + * @flags: Flags which affect the lookup. + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: (nullable): a #GError, or %NULL + * + * Look up a certificate by its handle. + * + * The handle should have been created by calling + * g_tls_database_create_certificate_handle() on a #GTlsDatabase object of + * the same TLS backend. The handle is designed to remain valid across + * instantiations of the database. + * + * If the handle is no longer valid, or does not point to a certificate in + * this database, then %NULL will be returned. + * + * This function can block, use g_tls_database_lookup_certificate_for_handle_async() to perform + * the lookup operation asynchronously. + * + * Returns: (transfer full) (nullable): a newly allocated + * #GTlsCertificate, or %NULL. Use g_object_unref() to release the certificate. + * + * Since: 2.30 + */ +GTlsCertificate* +g_tls_database_lookup_certificate_for_handle (GTlsDatabase *self, + const gchar *handle, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); + g_return_val_if_fail (handle != NULL, NULL); + g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle, NULL); + return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle (self, + handle, + interaction, + flags, + cancellable, + error); +} + + +/** + * g_tls_database_lookup_certificate_for_handle_async: + * @self: a #GTlsDatabase + * @handle: a certificate handle + * @interaction: (nullable): used to interact with the user if necessary + * @flags: Flags which affect the lookup. + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: callback to call when the operation completes + * @user_data: the data to pass to the callback function + * + * Asynchronously look up a certificate by its handle in the database. See + * g_tls_database_lookup_certificate_for_handle() for more information. + * + * Since: 2.30 + */ +void +g_tls_database_lookup_certificate_for_handle_async (GTlsDatabase *self, + const gchar *handle, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_TLS_DATABASE (self)); + g_return_if_fail (handle != NULL); + g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async); + G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async (self, + handle, + interaction, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_tls_database_lookup_certificate_for_handle_finish: + * @self: a #GTlsDatabase + * @result: a #GAsyncResult. + * @error: a #GError pointer, or %NULL + * + * Finish an asynchronous lookup of a certificate by its handle. See + * g_tls_database_lookup_certificate_for_handle() for more information. + * + * If the handle is no longer valid, or does not point to a certificate in + * this database, then %NULL will be returned. + * + * Returns: (transfer full): a newly allocated #GTlsCertificate object. + * Use g_object_unref() to release the certificate. + * + * Since: 2.30 + */ +GTlsCertificate* +g_tls_database_lookup_certificate_for_handle_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish, NULL); + return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish (self, + result, + error); +} + +/** + * g_tls_database_lookup_certificate_issuer: + * @self: a #GTlsDatabase + * @certificate: a #GTlsCertificate + * @interaction: (nullable): used to interact with the user if necessary + * @flags: flags which affect the lookup operation + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: (nullable): a #GError, or %NULL + * + * Look up the issuer of @certificate in the database. The + * #GTlsCertificate:issuer property of @certificate is not modified, and + * the two certificates are not hooked into a chain. + * + * This function can block. Use g_tls_database_lookup_certificate_issuer_async() + * to perform the lookup operation asynchronously. + * + * Beware this function cannot be used to build certification paths. The + * issuer certificate returned by this function may not be the same as + * the certificate that would actually be used to construct a valid + * certification path during certificate verification. + * [RFC 4158](https://datatracker.ietf.org/doc/html/rfc4158) explains + * why an issuer certificate cannot be naively assumed to be part of the + * the certification path (though GLib's TLS backends may not follow the + * path building strategies outlined in this RFC). Due to the complexity + * of certification path building, GLib does not provide any way to know + * which certification path will actually be used when verifying a TLS + * certificate. Accordingly, this function cannot be used to make + * security-related decisions. Only GLib itself should make security + * decisions about TLS certificates. + * + * Returns: (transfer full): a newly allocated issuer #GTlsCertificate, + * or %NULL. Use g_object_unref() to release the certificate. + * + * Since: 2.30 + */ +GTlsCertificate* +g_tls_database_lookup_certificate_issuer (GTlsDatabase *self, + GTlsCertificate *certificate, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); + g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL); + g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer, NULL); + return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer (self, + certificate, + interaction, + flags, + cancellable, + error); +} + +/** + * g_tls_database_lookup_certificate_issuer_async: + * @self: a #GTlsDatabase + * @certificate: a #GTlsCertificate + * @interaction: (nullable): used to interact with the user if necessary + * @flags: flags which affect the lookup operation + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: callback to call when the operation completes + * @user_data: the data to pass to the callback function + * + * Asynchronously look up the issuer of @certificate in the database. See + * g_tls_database_lookup_certificate_issuer() for more information. + * + * Since: 2.30 + */ +void +g_tls_database_lookup_certificate_issuer_async (GTlsDatabase *self, + GTlsCertificate *certificate, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_TLS_DATABASE (self)); + g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate)); + g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_return_if_fail (callback != NULL); + g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async); + G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async (self, + certificate, + interaction, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_tls_database_lookup_certificate_issuer_finish: + * @self: a #GTlsDatabase + * @result: a #GAsyncResult. + * @error: a #GError pointer, or %NULL + * + * Finish an asynchronous lookup issuer operation. See + * g_tls_database_lookup_certificate_issuer() for more information. + * + * Returns: (transfer full): a newly allocated issuer #GTlsCertificate, + * or %NULL. Use g_object_unref() to release the certificate. + * + * Since: 2.30 + */ +GTlsCertificate* +g_tls_database_lookup_certificate_issuer_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish, NULL); + return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish (self, + result, + error); +} + +/** + * g_tls_database_lookup_certificates_issued_by: + * @self: a #GTlsDatabase + * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN. + * @interaction: (nullable): used to interact with the user if necessary + * @flags: Flags which affect the lookup operation. + * @cancellable: (nullable): a #GCancellable, or %NULL + * @error: (nullable): a #GError, or %NULL + * + * Look up certificates issued by this issuer in the database. + * + * This function can block, use g_tls_database_lookup_certificates_issued_by_async() to perform + * the lookup operation asynchronously. + * + * Returns: (transfer full) (element-type GTlsCertificate): a newly allocated list of #GTlsCertificate + * objects. Use g_object_unref() on each certificate, and g_list_free() on the release the list. + * + * Since: 2.30 + */ +GList* +g_tls_database_lookup_certificates_issued_by (GTlsDatabase *self, + GByteArray *issuer_raw_dn, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); + g_return_val_if_fail (issuer_raw_dn, NULL); + g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by, NULL); + return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by (self, + issuer_raw_dn, + interaction, + flags, + cancellable, + error); +} + +/** + * g_tls_database_lookup_certificates_issued_by_async: + * @self: a #GTlsDatabase + * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN. + * @interaction: (nullable): used to interact with the user if necessary + * @flags: Flags which affect the lookup operation. + * @cancellable: (nullable): a #GCancellable, or %NULL + * @callback: callback to call when the operation completes + * @user_data: the data to pass to the callback function + * + * Asynchronously look up certificates issued by this issuer in the database. See + * g_tls_database_lookup_certificates_issued_by() for more information. + * + * The database may choose to hold a reference to the issuer byte array for the duration + * of of this asynchronous operation. The byte array should not be modified during + * this time. + * + * Since: 2.30 + */ +void +g_tls_database_lookup_certificates_issued_by_async (GTlsDatabase *self, + GByteArray *issuer_raw_dn, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (G_IS_TLS_DATABASE (self)); + g_return_if_fail (issuer_raw_dn != NULL); + g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_return_if_fail (callback != NULL); + g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async); + G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async (self, + issuer_raw_dn, + interaction, + flags, + cancellable, + callback, + user_data); +} + +/** + * g_tls_database_lookup_certificates_issued_by_finish: + * @self: a #GTlsDatabase + * @result: a #GAsyncResult. + * @error: a #GError pointer, or %NULL + * + * Finish an asynchronous lookup of certificates. See + * g_tls_database_lookup_certificates_issued_by() for more information. + * + * Returns: (transfer full) (element-type GTlsCertificate): a newly allocated list of #GTlsCertificate + * objects. Use g_object_unref() on each certificate, and g_list_free() on the release the list. + * + * Since: 2.30 + */ +GList* +g_tls_database_lookup_certificates_issued_by_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish, NULL); + return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish (self, + result, + error); +} diff --git a/gio/gtlsdatabase.h b/gio/gtlsdatabase.h new file mode 100644 index 0000000..5dafd7b --- /dev/null +++ b/gio/gtlsdatabase.h @@ -0,0 +1,247 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#ifndef __G_TLS_DATABASE_H__ +#define __G_TLS_DATABASE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER "1.3.6.1.5.5.7.3.1" +#define G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT "1.3.6.1.5.5.7.3.2" + +#define G_TYPE_TLS_DATABASE (g_tls_database_get_type ()) +#define G_TLS_DATABASE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_DATABASE, GTlsDatabase)) +#define G_TLS_DATABASE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_TLS_DATABASE, GTlsDatabaseClass)) +#define G_IS_TLS_DATABASE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_DATABASE)) +#define G_IS_TLS_DATABASE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_TLS_DATABASE)) +#define G_TLS_DATABASE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), G_TYPE_TLS_DATABASE, GTlsDatabaseClass)) + +typedef struct _GTlsDatabaseClass GTlsDatabaseClass; +typedef struct _GTlsDatabasePrivate GTlsDatabasePrivate; + +struct _GTlsDatabase +{ + GObject parent_instance; + + GTlsDatabasePrivate *priv; +}; + +struct _GTlsDatabaseClass +{ + GObjectClass parent_class; + + /* virtual methods */ + + GTlsCertificateFlags (*verify_chain) (GTlsDatabase *self, + GTlsCertificate *chain, + const gchar *purpose, + GSocketConnectable *identity, + GTlsInteraction *interaction, + GTlsDatabaseVerifyFlags flags, + GCancellable *cancellable, + GError **error); + + void (*verify_chain_async) (GTlsDatabase *self, + GTlsCertificate *chain, + const gchar *purpose, + GSocketConnectable *identity, + GTlsInteraction *interaction, + GTlsDatabaseVerifyFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + GTlsCertificateFlags (*verify_chain_finish) (GTlsDatabase *self, + GAsyncResult *result, + GError **error); + + gchar* (*create_certificate_handle) (GTlsDatabase *self, + GTlsCertificate *certificate); + + GTlsCertificate* (*lookup_certificate_for_handle) (GTlsDatabase *self, + const gchar *handle, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error); + + void (*lookup_certificate_for_handle_async) (GTlsDatabase *self, + const gchar *handle, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + GTlsCertificate* (*lookup_certificate_for_handle_finish) (GTlsDatabase *self, + GAsyncResult *result, + GError **error); + + GTlsCertificate* (*lookup_certificate_issuer) (GTlsDatabase *self, + GTlsCertificate *certificate, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error); + + void (*lookup_certificate_issuer_async) (GTlsDatabase *self, + GTlsCertificate *certificate, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + GTlsCertificate* (*lookup_certificate_issuer_finish) (GTlsDatabase *self, + GAsyncResult *result, + GError **error); + + GList* (*lookup_certificates_issued_by) (GTlsDatabase *self, + GByteArray *issuer_raw_dn, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error); + + void (*lookup_certificates_issued_by_async) (GTlsDatabase *self, + GByteArray *issuer_raw_dn, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + GList* (*lookup_certificates_issued_by_finish) (GTlsDatabase *self, + GAsyncResult *result, + GError **error); + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[16]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_database_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GTlsCertificateFlags g_tls_database_verify_chain (GTlsDatabase *self, + GTlsCertificate *chain, + const gchar *purpose, + GSocketConnectable *identity, + GTlsInteraction *interaction, + GTlsDatabaseVerifyFlags flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_tls_database_verify_chain_async (GTlsDatabase *self, + GTlsCertificate *chain, + const gchar *purpose, + GSocketConnectable *identity, + GTlsInteraction *interaction, + GTlsDatabaseVerifyFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GTlsCertificateFlags g_tls_database_verify_chain_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gchar* g_tls_database_create_certificate_handle (GTlsDatabase *self, + GTlsCertificate *certificate); + +GLIB_AVAILABLE_IN_ALL +GTlsCertificate* g_tls_database_lookup_certificate_for_handle (GTlsDatabase *self, + const gchar *handle, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_tls_database_lookup_certificate_for_handle_async (GTlsDatabase *self, + const gchar *handle, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GTlsCertificate* g_tls_database_lookup_certificate_for_handle_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GTlsCertificate* g_tls_database_lookup_certificate_issuer (GTlsDatabase *self, + GTlsCertificate *certificate, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_tls_database_lookup_certificate_issuer_async (GTlsDatabase *self, + GTlsCertificate *certificate, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GTlsCertificate* g_tls_database_lookup_certificate_issuer_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GList* g_tls_database_lookup_certificates_issued_by (GTlsDatabase *self, + GByteArray *issuer_raw_dn, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_tls_database_lookup_certificates_issued_by_async (GTlsDatabase *self, + GByteArray *issuer_raw_dn, + GTlsInteraction *interaction, + GTlsDatabaseLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GList* g_tls_database_lookup_certificates_issued_by_finish (GTlsDatabase *self, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __G_TLS_DATABASE_H__ */ diff --git a/gio/gtlsfiledatabase.c b/gio/gtlsfiledatabase.c new file mode 100644 index 0000000..75c0133 --- /dev/null +++ b/gio/gtlsfiledatabase.c @@ -0,0 +1,103 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Collabora, Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#include "config.h" + +#include "gtlsfiledatabase.h" + +#include "ginitable.h" +#include "gtlsbackend.h" +#include "gtlsdatabase.h" +#include "glibintl.h" + +/** + * SECTION:gtlsfiledatabase + * @short_description: TLS file based database type + * @include: gio/gio.h + * + * #GTlsFileDatabase is implemented by #GTlsDatabase objects which load + * their certificate information from a file. It is an interface which + * TLS library specific subtypes implement. + * + * Since: 2.30 + */ + +/** + * GTlsFileDatabase: + * + * Implemented by a #GTlsDatabase which allows you to load certificates + * from a file. + * + * Since: 2.30 + */ +G_DEFINE_INTERFACE (GTlsFileDatabase, g_tls_file_database, G_TYPE_TLS_DATABASE) + +static void +g_tls_file_database_default_init (GTlsFileDatabaseInterface *iface) +{ + /** + * GTlsFileDatabase:anchors: + * + * The path to a file containing PEM encoded certificate authority + * root anchors. The certificates in this file will be treated as + * root authorities for the purpose of verifying other certificates + * via the g_tls_database_verify_chain() operation. + * + * Since: 2.30 + */ + g_object_interface_install_property (iface, + g_param_spec_string ("anchors", + P_("Anchors"), + P_("The certificate authority anchor file"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_tls_file_database_new: + * @anchors: (type filename): filename of anchor certificate authorities. + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a new #GTlsFileDatabase which uses anchor certificate authorities + * in @anchors to verify certificate chains. + * + * The certificates in @anchors must be PEM encoded. + * + * Returns: (transfer full) (type GTlsFileDatabase): the new + * #GTlsFileDatabase, or %NULL on error + * + * Since: 2.30 + */ +GTlsDatabase* +g_tls_file_database_new (const gchar *anchors, + GError **error) +{ + GObject *database; + GTlsBackend *backend; + + backend = g_tls_backend_get_default (); + database = g_initable_new (g_tls_backend_get_file_database_type (backend), + NULL, error, + "anchors", anchors, + NULL); + return G_TLS_DATABASE (database); +} diff --git a/gio/gtlsfiledatabase.h b/gio/gtlsfiledatabase.h new file mode 100644 index 0000000..1ee4631 --- /dev/null +++ b/gio/gtlsfiledatabase.h @@ -0,0 +1,58 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Author: Stef Walter + */ + +#ifndef __G_TLS_FILE_DATABASE_H__ +#define __G_TLS_FILE_DATABASE_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TLS_FILE_DATABASE (g_tls_file_database_get_type ()) +#define G_TLS_FILE_DATABASE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_FILE_DATABASE, GTlsFileDatabase)) +#define G_IS_TLS_FILE_DATABASE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_FILE_DATABASE)) +#define G_TLS_FILE_DATABASE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_TLS_FILE_DATABASE, GTlsFileDatabaseInterface)) + +typedef struct _GTlsFileDatabaseInterface GTlsFileDatabaseInterface; + +/** + * GTlsFileDatabaseInterface: + * @g_iface: The parent interface. + * + * Provides an interface for #GTlsFileDatabase implementations. + * + */ +struct _GTlsFileDatabaseInterface +{ + GTypeInterface g_iface; + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[8]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_file_database_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GTlsDatabase* g_tls_file_database_new (const gchar *anchors, + GError **error); + +G_END_DECLS + +#endif /* __G_TLS_FILE_DATABASE_H___ */ diff --git a/gio/gtlsinteraction.c b/gio/gtlsinteraction.c new file mode 100644 index 0000000..dfb54f6 --- /dev/null +++ b/gio/gtlsinteraction.c @@ -0,0 +1,846 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#include "config.h" + +#include + +#include "gtlscertificate.h" +#include "gtlsconnection.h" +#include "gtlsinteraction.h" +#include "gtlspassword.h" +#include "gasyncresult.h" +#include "gcancellable.h" +#include "gtask.h" +#include "gioenumtypes.h" +#include "glibintl.h" + + +/** + * SECTION:gtlsinteraction + * @short_description: Interaction with the user during TLS operations. + * @include: gio/gio.h + * + * #GTlsInteraction provides a mechanism for the TLS connection and database + * code to interact with the user. It can be used to ask the user for passwords. + * + * To use a #GTlsInteraction with a TLS connection use + * g_tls_connection_set_interaction(). + * + * Callers should instantiate a derived class that implements the various + * interaction methods to show the required dialogs. + * + * Callers should use the 'invoke' functions like + * g_tls_interaction_invoke_ask_password() to run interaction methods. These + * functions make sure that the interaction is invoked in the main loop + * and not in the current thread, if the current thread is not running the + * main loop. + * + * Derived classes can choose to implement whichever interactions methods they'd + * like to support by overriding those virtual methods in their class + * initialization function. Any interactions not implemented will return + * %G_TLS_INTERACTION_UNHANDLED. If a derived class implements an async method, + * it must also implement the corresponding finish method. + */ + +/** + * GTlsInteraction: + * + * An object representing interaction that the TLS connection and database + * might have with the user. + * + * Since: 2.30 + */ + +/** + * GTlsInteractionClass: + * @ask_password: ask for a password synchronously. If the implementation + * returns %G_TLS_INTERACTION_HANDLED, then the password argument should + * have been filled in by using g_tls_password_set_value() or a similar + * function. + * @ask_password_async: ask for a password asynchronously. + * @ask_password_finish: complete operation to ask for a password asynchronously. + * If the implementation returns %G_TLS_INTERACTION_HANDLED, then the + * password argument of the async method should have been filled in by using + * g_tls_password_set_value() or a similar function. + * @request_certificate: ask for a certificate synchronously. If the + * implementation returns %G_TLS_INTERACTION_HANDLED, then the connection + * argument should have been filled in by using + * g_tls_connection_set_certificate(). + * @request_certificate_async: ask for a certificate asynchronously. + * @request_certificate_finish: complete operation to ask for a certificate + * asynchronously. If the implementation returns %G_TLS_INTERACTION_HANDLED, + * then the connection argument of the async method should have been + * filled in by using g_tls_connection_set_certificate(). + * + * The class for #GTlsInteraction. Derived classes implement the various + * virtual interaction methods to handle TLS interactions. + * + * Derived classes can choose to implement whichever interactions methods they'd + * like to support by overriding those virtual methods in their class + * initialization function. If a derived class implements an async method, + * it must also implement the corresponding finish method. + * + * The synchronous interaction methods should implement to display modal dialogs, + * and the asynchronous methods to display modeless dialogs. + * + * If the user cancels an interaction, then the result should be + * %G_TLS_INTERACTION_FAILED and the error should be set with a domain of + * %G_IO_ERROR and code of %G_IO_ERROR_CANCELLED. + * + * Since: 2.30 + */ + +struct _GTlsInteractionPrivate { + GMainContext *context; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GTlsInteraction, g_tls_interaction, G_TYPE_OBJECT) + +typedef struct { + GMutex mutex; + + /* Input arguments */ + GTlsInteraction *interaction; + GObject *argument; + GCancellable *cancellable; + + /* Used when we're invoking async interactions */ + GAsyncReadyCallback callback; + gpointer user_data; + + /* Used when we expect results */ + GTlsInteractionResult result; + GError *error; + gboolean complete; + GCond cond; +} InvokeClosure; + +static void +invoke_closure_free (gpointer data) +{ + InvokeClosure *closure = data; + g_assert (closure); + g_object_unref (closure->interaction); + g_clear_object (&closure->argument); + g_clear_object (&closure->cancellable); + g_cond_clear (&closure->cond); + g_mutex_clear (&closure->mutex); + g_clear_error (&closure->error); + + /* Insurance that we've actually used these before freeing */ + g_assert (closure->callback == NULL); + g_assert (closure->user_data == NULL); + + g_free (closure); +} + +static InvokeClosure * +invoke_closure_new (GTlsInteraction *interaction, + GObject *argument, + GCancellable *cancellable) +{ + InvokeClosure *closure = g_new0 (InvokeClosure, 1); + closure->interaction = g_object_ref (interaction); + closure->argument = argument ? g_object_ref (argument) : NULL; + closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + g_mutex_init (&closure->mutex); + g_cond_init (&closure->cond); + closure->result = G_TLS_INTERACTION_UNHANDLED; + return closure; +} + +static GTlsInteractionResult +invoke_closure_wait_and_free (InvokeClosure *closure, + GError **error) +{ + GTlsInteractionResult result; + + g_mutex_lock (&closure->mutex); + + while (!closure->complete) + g_cond_wait (&closure->cond, &closure->mutex); + + g_mutex_unlock (&closure->mutex); + + if (closure->error) + { + g_propagate_error (error, closure->error); + closure->error = NULL; + } + result = closure->result; + + invoke_closure_free (closure); + return result; +} + +static GTlsInteractionResult +invoke_closure_complete_and_free (GTlsInteraction *interaction, + InvokeClosure *closure, + GError **error) +{ + GTlsInteractionResult result; + gboolean complete; + + /* + * Handle the case where we've been called from within the main context + * or in the case where the main context is not running. This approximates + * the behavior of a modal dialog. + */ + if (g_main_context_acquire (interaction->priv->context)) + { + for (;;) + { + g_mutex_lock (&closure->mutex); + complete = closure->complete; + g_mutex_unlock (&closure->mutex); + if (complete) + break; + g_main_context_iteration (interaction->priv->context, TRUE); + } + + g_main_context_release (interaction->priv->context); + + if (closure->error) + { + g_propagate_error (error, closure->error); + closure->error = NULL; + } + + result = closure->result; + invoke_closure_free (closure); + } + + /* + * Handle the case where we're in a different thread than the main + * context and a main loop is running. + */ + else + { + result = invoke_closure_wait_and_free (closure, error); + } + + return result; +} + +static void +g_tls_interaction_init (GTlsInteraction *interaction) +{ + interaction->priv = g_tls_interaction_get_instance_private (interaction); + interaction->priv->context = g_main_context_ref_thread_default (); +} + +static void +g_tls_interaction_finalize (GObject *object) +{ + GTlsInteraction *interaction = G_TLS_INTERACTION (object); + + g_main_context_unref (interaction->priv->context); + + G_OBJECT_CLASS (g_tls_interaction_parent_class)->finalize (object); +} + +static void +g_tls_interaction_class_init (GTlsInteractionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_tls_interaction_finalize; +} + +static gboolean +on_invoke_ask_password_sync (gpointer user_data) +{ + InvokeClosure *closure = user_data; + GTlsInteractionClass *klass; + + g_mutex_lock (&closure->mutex); + + klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction); + g_assert (klass->ask_password); + + closure->result = klass->ask_password (closure->interaction, + G_TLS_PASSWORD (closure->argument), + closure->cancellable, + &closure->error); + + closure->complete = TRUE; + g_cond_signal (&closure->cond); + g_mutex_unlock (&closure->mutex); + + return FALSE; /* don't call again */ +} + +static void +on_ask_password_complete (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + InvokeClosure *closure = user_data; + GTlsInteractionClass *klass; + + g_mutex_lock (&closure->mutex); + + klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction); + g_assert (klass->ask_password_finish); + + closure->result = klass->ask_password_finish (closure->interaction, + result, + &closure->error); + + closure->complete = TRUE; + g_cond_signal (&closure->cond); + g_mutex_unlock (&closure->mutex); +} + +static gboolean +on_invoke_ask_password_async_as_sync (gpointer user_data) +{ + InvokeClosure *closure = user_data; + GTlsInteractionClass *klass; + + g_mutex_lock (&closure->mutex); + + klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction); + g_assert (klass->ask_password_async); + + klass->ask_password_async (closure->interaction, + G_TLS_PASSWORD (closure->argument), + closure->cancellable, + on_ask_password_complete, + closure); + + /* Note that we've used these */ + closure->callback = NULL; + closure->user_data = NULL; + + g_mutex_unlock (&closure->mutex); + + return FALSE; /* don't call again */ +} + +/** + * g_tls_interaction_invoke_ask_password: + * @interaction: a #GTlsInteraction object + * @password: a #GTlsPassword object + * @cancellable: an optional #GCancellable cancellation object + * @error: an optional location to place an error on failure + * + * Invoke the interaction to ask the user for a password. It invokes this + * interaction in the main loop, specifically the #GMainContext returned by + * g_main_context_get_thread_default() when the interaction is created. This + * is called by called by #GTlsConnection or #GTlsDatabase to ask the user + * for a password. + * + * Derived subclasses usually implement a password prompt, although they may + * also choose to provide a password from elsewhere. The @password value will + * be filled in and then @callback will be called. Alternatively the user may + * abort this password request, which will usually abort the TLS connection. + * + * The implementation can either be a synchronous (eg: modal dialog) or an + * asynchronous one (eg: modeless dialog). This function will take care of + * calling which ever one correctly. + * + * If the interaction is cancelled by the cancellation object, or by the + * user then %G_TLS_INTERACTION_FAILED will be returned with an error that + * contains a %G_IO_ERROR_CANCELLED error code. Certain implementations may + * not support immediate cancellation. + * + * Returns: The status of the ask password interaction. + * + * Since: 2.30 + */ +GTlsInteractionResult +g_tls_interaction_invoke_ask_password (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GError **error) +{ + GTlsInteractionResult result; + InvokeClosure *closure; + GTlsInteractionClass *klass; + + g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_TLS_INTERACTION_UNHANDLED); + + klass = G_TLS_INTERACTION_GET_CLASS (interaction); + + if (klass->ask_password) + { + closure = invoke_closure_new (interaction, G_OBJECT (password), cancellable); + g_main_context_invoke (interaction->priv->context, + on_invoke_ask_password_sync, closure); + result = invoke_closure_wait_and_free (closure, error); + } + else if (klass->ask_password_async) + { + g_return_val_if_fail (klass->ask_password_finish, G_TLS_INTERACTION_UNHANDLED); + + closure = invoke_closure_new (interaction, G_OBJECT (password), cancellable); + g_main_context_invoke (interaction->priv->context, + on_invoke_ask_password_async_as_sync, closure); + + result = invoke_closure_complete_and_free (interaction, closure, error); + } + else + { + result = G_TLS_INTERACTION_UNHANDLED; + } + + return result; +} + +/** + * g_tls_interaction_ask_password: + * @interaction: a #GTlsInteraction object + * @password: a #GTlsPassword object + * @cancellable: an optional #GCancellable cancellation object + * @error: an optional location to place an error on failure + * + * Run synchronous interaction to ask the user for a password. In general, + * g_tls_interaction_invoke_ask_password() should be used instead of this + * function. + * + * Derived subclasses usually implement a password prompt, although they may + * also choose to provide a password from elsewhere. The @password value will + * be filled in and then @callback will be called. Alternatively the user may + * abort this password request, which will usually abort the TLS connection. + * + * If the interaction is cancelled by the cancellation object, or by the + * user then %G_TLS_INTERACTION_FAILED will be returned with an error that + * contains a %G_IO_ERROR_CANCELLED error code. Certain implementations may + * not support immediate cancellation. + * + * Returns: The status of the ask password interaction. + * + * Since: 2.30 + */ +GTlsInteractionResult +g_tls_interaction_ask_password (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GError **error) +{ + GTlsInteractionClass *klass; + + g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_TLS_INTERACTION_UNHANDLED); + + klass = G_TLS_INTERACTION_GET_CLASS (interaction); + if (klass->ask_password) + return (klass->ask_password) (interaction, password, cancellable, error); + else + return G_TLS_INTERACTION_UNHANDLED; +} + +/** + * g_tls_interaction_ask_password_async: + * @interaction: a #GTlsInteraction object + * @password: a #GTlsPassword object + * @cancellable: an optional #GCancellable cancellation object + * @callback: (nullable): will be called when the interaction completes + * @user_data: (nullable): data to pass to the @callback + * + * Run asynchronous interaction to ask the user for a password. In general, + * g_tls_interaction_invoke_ask_password() should be used instead of this + * function. + * + * Derived subclasses usually implement a password prompt, although they may + * also choose to provide a password from elsewhere. The @password value will + * be filled in and then @callback will be called. Alternatively the user may + * abort this password request, which will usually abort the TLS connection. + * + * If the interaction is cancelled by the cancellation object, or by the + * user then %G_TLS_INTERACTION_FAILED will be returned with an error that + * contains a %G_IO_ERROR_CANCELLED error code. Certain implementations may + * not support immediate cancellation. + * + * Certain implementations may not support immediate cancellation. + * + * Since: 2.30 + */ +void +g_tls_interaction_ask_password_async (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTlsInteractionClass *klass; + GTask *task; + + g_return_if_fail (G_IS_TLS_INTERACTION (interaction)); + g_return_if_fail (G_IS_TLS_PASSWORD (password)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + klass = G_TLS_INTERACTION_GET_CLASS (interaction); + if (klass->ask_password_async) + { + g_return_if_fail (klass->ask_password_finish); + (klass->ask_password_async) (interaction, password, cancellable, + callback, user_data); + } + else + { + task = g_task_new (interaction, cancellable, callback, user_data); + g_task_set_source_tag (task, g_tls_interaction_ask_password_async); + g_task_return_int (task, G_TLS_INTERACTION_UNHANDLED); + g_object_unref (task); + } +} + +/** + * g_tls_interaction_ask_password_finish: + * @interaction: a #GTlsInteraction object + * @result: the result passed to the callback + * @error: an optional location to place an error on failure + * + * Complete an ask password user interaction request. This should be once + * the g_tls_interaction_ask_password_async() completion callback is called. + * + * If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsPassword passed + * to g_tls_interaction_ask_password() will have its password filled in. + * + * If the interaction is cancelled by the cancellation object, or by the + * user then %G_TLS_INTERACTION_FAILED will be returned with an error that + * contains a %G_IO_ERROR_CANCELLED error code. + * + * Returns: The status of the ask password interaction. + * + * Since: 2.30 + */ +GTlsInteractionResult +g_tls_interaction_ask_password_finish (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error) +{ + GTlsInteractionClass *klass; + + g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_INTERACTION_UNHANDLED); + + klass = G_TLS_INTERACTION_GET_CLASS (interaction); + if (klass->ask_password_finish) + { + g_return_val_if_fail (klass->ask_password_async != NULL, G_TLS_INTERACTION_UNHANDLED); + + return (klass->ask_password_finish) (interaction, result, error); + } + else + { + g_return_val_if_fail (g_async_result_is_tagged (result, g_tls_interaction_ask_password_async), G_TLS_INTERACTION_UNHANDLED); + + return g_task_propagate_int (G_TASK (result), error); + } +} + +static gboolean +on_invoke_request_certificate_sync (gpointer user_data) +{ + InvokeClosure *closure = user_data; + GTlsInteractionClass *klass; + + g_mutex_lock (&closure->mutex); + + klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction); + g_assert (klass->request_certificate != NULL); + + closure->result = klass->request_certificate (closure->interaction, + G_TLS_CONNECTION (closure->argument), + 0, + closure->cancellable, + &closure->error); + + closure->complete = TRUE; + g_cond_signal (&closure->cond); + g_mutex_unlock (&closure->mutex); + + return FALSE; /* don't call again */ +} + +static void +on_request_certificate_complete (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + InvokeClosure *closure = user_data; + GTlsInteractionClass *klass; + + g_mutex_lock (&closure->mutex); + + klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction); + g_assert (klass->request_certificate_finish != NULL); + + closure->result = klass->request_certificate_finish (closure->interaction, + result, &closure->error); + + closure->complete = TRUE; + g_cond_signal (&closure->cond); + g_mutex_unlock (&closure->mutex); +} + +static gboolean +on_invoke_request_certificate_async_as_sync (gpointer user_data) +{ + InvokeClosure *closure = user_data; + GTlsInteractionClass *klass; + + g_mutex_lock (&closure->mutex); + + klass = G_TLS_INTERACTION_GET_CLASS (closure->interaction); + g_assert (klass->request_certificate_async); + + klass->request_certificate_async (closure->interaction, + G_TLS_CONNECTION (closure->argument), 0, + closure->cancellable, + on_request_certificate_complete, + closure); + + /* Note that we've used these */ + closure->callback = NULL; + closure->user_data = NULL; + + g_mutex_unlock (&closure->mutex); + + return FALSE; /* don't call again */ +} + +/** + * g_tls_interaction_invoke_request_certificate: + * @interaction: a #GTlsInteraction object + * @connection: a #GTlsConnection object + * @flags: flags providing more information about the request + * @cancellable: an optional #GCancellable cancellation object + * @error: an optional location to place an error on failure + * + * Invoke the interaction to ask the user to choose a certificate to + * use with the connection. It invokes this interaction in the main + * loop, specifically the #GMainContext returned by + * g_main_context_get_thread_default() when the interaction is + * created. This is called by called by #GTlsConnection when the peer + * requests a certificate during the handshake. + * + * Derived subclasses usually implement a certificate selector, + * although they may also choose to provide a certificate from + * elsewhere. Alternatively the user may abort this certificate + * request, which may or may not abort the TLS connection. + * + * The implementation can either be a synchronous (eg: modal dialog) or an + * asynchronous one (eg: modeless dialog). This function will take care of + * calling which ever one correctly. + * + * If the interaction is cancelled by the cancellation object, or by the + * user then %G_TLS_INTERACTION_FAILED will be returned with an error that + * contains a %G_IO_ERROR_CANCELLED error code. Certain implementations may + * not support immediate cancellation. + * + * Returns: The status of the certificate request interaction. + * + * Since: 2.40 + */ +GTlsInteractionResult +g_tls_interaction_invoke_request_certificate (GTlsInteraction *interaction, + GTlsConnection *connection, + GTlsCertificateRequestFlags flags, + GCancellable *cancellable, + GError **error) +{ + GTlsInteractionResult result; + InvokeClosure *closure; + GTlsInteractionClass *klass; + + g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (G_IS_TLS_CONNECTION (connection), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_TLS_INTERACTION_UNHANDLED); + + klass = G_TLS_INTERACTION_GET_CLASS (interaction); + + if (klass->request_certificate) + { + closure = invoke_closure_new (interaction, G_OBJECT (connection), cancellable); + g_main_context_invoke (interaction->priv->context, + on_invoke_request_certificate_sync, closure); + result = invoke_closure_wait_and_free (closure, error); + } + else if (klass->request_certificate_async) + { + g_return_val_if_fail (klass->request_certificate_finish, G_TLS_INTERACTION_UNHANDLED); + + closure = invoke_closure_new (interaction, G_OBJECT (connection), cancellable); + g_main_context_invoke (interaction->priv->context, + on_invoke_request_certificate_async_as_sync, closure); + + result = invoke_closure_complete_and_free (interaction, closure, error); + } + else + { + result = G_TLS_INTERACTION_UNHANDLED; + } + + return result; +} + +/** + * g_tls_interaction_request_certificate: + * @interaction: a #GTlsInteraction object + * @connection: a #GTlsConnection object + * @flags: flags providing more information about the request + * @cancellable: an optional #GCancellable cancellation object + * @error: an optional location to place an error on failure + * + * Run synchronous interaction to ask the user to choose a certificate to use + * with the connection. In general, g_tls_interaction_invoke_request_certificate() + * should be used instead of this function. + * + * Derived subclasses usually implement a certificate selector, although they may + * also choose to provide a certificate from elsewhere. Alternatively the user may + * abort this certificate request, which will usually abort the TLS connection. + * + * If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsConnection + * passed to g_tls_interaction_request_certificate() will have had its + * #GTlsConnection:certificate filled in. + * + * If the interaction is cancelled by the cancellation object, or by the + * user then %G_TLS_INTERACTION_FAILED will be returned with an error that + * contains a %G_IO_ERROR_CANCELLED error code. Certain implementations may + * not support immediate cancellation. + * + * Returns: The status of the request certificate interaction. + * + * Since: 2.40 + */ +GTlsInteractionResult +g_tls_interaction_request_certificate (GTlsInteraction *interaction, + GTlsConnection *connection, + GTlsCertificateRequestFlags flags, + GCancellable *cancellable, + GError **error) +{ + GTlsInteractionClass *klass; + + g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (G_IS_TLS_CONNECTION (connection), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_TLS_INTERACTION_UNHANDLED); + + klass = G_TLS_INTERACTION_GET_CLASS (interaction); + if (klass->request_certificate) + return (klass->request_certificate) (interaction, connection, flags, cancellable, error); + else + return G_TLS_INTERACTION_UNHANDLED; +} + +/** + * g_tls_interaction_request_certificate_async: + * @interaction: a #GTlsInteraction object + * @connection: a #GTlsConnection object + * @flags: flags providing more information about the request + * @cancellable: an optional #GCancellable cancellation object + * @callback: (nullable): will be called when the interaction completes + * @user_data: (nullable): data to pass to the @callback + * + * Run asynchronous interaction to ask the user for a certificate to use with + * the connection. In general, g_tls_interaction_invoke_request_certificate() should + * be used instead of this function. + * + * Derived subclasses usually implement a certificate selector, although they may + * also choose to provide a certificate from elsewhere. @callback will be called + * when the operation completes. Alternatively the user may abort this certificate + * request, which will usually abort the TLS connection. + * + * Since: 2.40 + */ +void +g_tls_interaction_request_certificate_async (GTlsInteraction *interaction, + GTlsConnection *connection, + GTlsCertificateRequestFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTlsInteractionClass *klass; + GTask *task; + + g_return_if_fail (G_IS_TLS_INTERACTION (interaction)); + g_return_if_fail (G_IS_TLS_CONNECTION (connection)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + klass = G_TLS_INTERACTION_GET_CLASS (interaction); + if (klass->request_certificate_async) + { + g_return_if_fail (klass->request_certificate_finish); + (klass->request_certificate_async) (interaction, connection, flags, + cancellable, callback, user_data); + } + else + { + task = g_task_new (interaction, cancellable, callback, user_data); + g_task_set_source_tag (task, g_tls_interaction_request_certificate_async); + g_task_return_int (task, G_TLS_INTERACTION_UNHANDLED); + g_object_unref (task); + } +} + +/** + * g_tls_interaction_request_certificate_finish: + * @interaction: a #GTlsInteraction object + * @result: the result passed to the callback + * @error: an optional location to place an error on failure + * + * Complete a request certificate user interaction request. This should be once + * the g_tls_interaction_request_certificate_async() completion callback is called. + * + * If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsConnection + * passed to g_tls_interaction_request_certificate_async() will have had its + * #GTlsConnection:certificate filled in. + * + * If the interaction is cancelled by the cancellation object, or by the + * user then %G_TLS_INTERACTION_FAILED will be returned with an error that + * contains a %G_IO_ERROR_CANCELLED error code. + * + * Returns: The status of the request certificate interaction. + * + * Since: 2.40 + */ +GTlsInteractionResult +g_tls_interaction_request_certificate_finish (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error) +{ + GTlsInteractionClass *klass; + + g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_INTERACTION_UNHANDLED); + + klass = G_TLS_INTERACTION_GET_CLASS (interaction); + if (klass->request_certificate_finish) + { + g_return_val_if_fail (klass->request_certificate_async != NULL, G_TLS_INTERACTION_UNHANDLED); + + return (klass->request_certificate_finish) (interaction, result, error); + } + else + { + g_return_val_if_fail (g_async_result_is_tagged (result, g_tls_interaction_request_certificate_async), G_TLS_INTERACTION_UNHANDLED); + + return g_task_propagate_int (G_TASK (result), error); + } +} diff --git a/gio/gtlsinteraction.h b/gio/gtlsinteraction.h new file mode 100644 index 0000000..03552fb --- /dev/null +++ b/gio/gtlsinteraction.h @@ -0,0 +1,148 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#ifndef __G_TLS_INTERACTION_H__ +#define __G_TLS_INTERACTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TLS_INTERACTION (g_tls_interaction_get_type ()) +#define G_TLS_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_INTERACTION, GTlsInteraction)) +#define G_TLS_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_INTERACTION, GTlsInteractionClass)) +#define G_IS_TLS_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_INTERACTION)) +#define G_IS_TLS_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_INTERACTION)) +#define G_TLS_INTERACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_INTERACTION, GTlsInteractionClass)) + +typedef struct _GTlsInteractionClass GTlsInteractionClass; +typedef struct _GTlsInteractionPrivate GTlsInteractionPrivate; + +struct _GTlsInteraction +{ + /*< private >*/ + GObject parent_instance; + GTlsInteractionPrivate *priv; +}; + +struct _GTlsInteractionClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + GTlsInteractionResult (* ask_password) (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GError **error); + + void (* ask_password_async) (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + GTlsInteractionResult (* ask_password_finish) (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error); + + GTlsInteractionResult (* request_certificate) (GTlsInteraction *interaction, + GTlsConnection *connection, + GTlsCertificateRequestFlags flags, + GCancellable *cancellable, + GError **error); + + void (* request_certificate_async) (GTlsInteraction *interaction, + GTlsConnection *connection, + GTlsCertificateRequestFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + + GTlsInteractionResult (* request_certificate_finish) (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error); + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[21]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_interaction_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GTlsInteractionResult g_tls_interaction_invoke_ask_password (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +GTlsInteractionResult g_tls_interaction_ask_password (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_tls_interaction_ask_password_async (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GTlsInteractionResult g_tls_interaction_ask_password_finish (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +GTlsInteractionResult g_tls_interaction_invoke_request_certificate (GTlsInteraction *interaction, + GTlsConnection *connection, + GTlsCertificateRequestFlags flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +GTlsInteractionResult g_tls_interaction_request_certificate (GTlsInteraction *interaction, + GTlsConnection *connection, + GTlsCertificateRequestFlags flags, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_2_40 +void g_tls_interaction_request_certificate_async (GTlsInteraction *interaction, + GTlsConnection *connection, + GTlsCertificateRequestFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_40 +GTlsInteractionResult g_tls_interaction_request_certificate_finish (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __G_TLS_INTERACTION_H__ */ diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c new file mode 100644 index 0000000..f705bcb --- /dev/null +++ b/gio/gtlspassword.c @@ -0,0 +1,456 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#include "config.h" +#include "glib.h" +#include "glibintl.h" + +#include "gioenumtypes.h" +#include "gtlspassword.h" + +#include + +/** + * SECTION:gtlspassword + * @title: GTlsPassword + * @short_description: TLS Passwords for prompting + * @include: gio/gio.h + * + * Holds a password used in TLS. + */ + +/** + * GTlsPassword: + * + * An abstract interface representing a password used in TLS. Often used in + * user interaction such as unlocking a key storage token. + * + * Since: 2.30 + */ + +enum +{ + PROP_0, + PROP_FLAGS, + PROP_DESCRIPTION, + PROP_WARNING +}; + +struct _GTlsPasswordPrivate +{ + guchar *value; + gsize length; + GDestroyNotify destroy; + GTlsPasswordFlags flags; + gchar *description; + gchar *warning; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GTlsPassword, g_tls_password, G_TYPE_OBJECT) + +static void +g_tls_password_init (GTlsPassword *password) +{ + password->priv = g_tls_password_get_instance_private (password); +} + +static const guchar * +g_tls_password_real_get_value (GTlsPassword *password, + gsize *length) +{ + if (length) + *length = password->priv->length; + return password->priv->value; +} + +static void +g_tls_password_real_set_value (GTlsPassword *password, + guchar *value, + gssize length, + GDestroyNotify destroy) +{ + if (password->priv->destroy) + (password->priv->destroy) (password->priv->value); + password->priv->destroy = NULL; + password->priv->value = NULL; + password->priv->length = 0; + + if (length < 0) + length = strlen ((gchar*) value); + + password->priv->value = value; + password->priv->length = length; + password->priv->destroy = destroy; +} + +static const gchar* +g_tls_password_real_get_default_warning (GTlsPassword *password) +{ + GTlsPasswordFlags flags; + + flags = g_tls_password_get_flags (password); + + if (flags & G_TLS_PASSWORD_FINAL_TRY) + return _("This is the last chance to enter the password correctly before your access is locked out."); + if (flags & G_TLS_PASSWORD_MANY_TRIES) + /* Translators: This is not the 'This is the last chance' string. It is + * displayed when more than one attempt is allowed. */ + return _("Several passwords entered have been incorrect, and your access will be locked out after further failures."); + if (flags & G_TLS_PASSWORD_RETRY) + return _("The password entered is incorrect."); + + return NULL; +} + +static void +g_tls_password_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTlsPassword *password = G_TLS_PASSWORD (object); + + switch (prop_id) + { + case PROP_FLAGS: + g_value_set_flags (value, g_tls_password_get_flags (password)); + break; + case PROP_WARNING: + g_value_set_string (value, g_tls_password_get_warning (password)); + break; + case PROP_DESCRIPTION: + g_value_set_string (value, g_tls_password_get_description (password)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_tls_password_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTlsPassword *password = G_TLS_PASSWORD (object); + + switch (prop_id) + { + case PROP_FLAGS: + g_tls_password_set_flags (password, g_value_get_flags (value)); + break; + case PROP_WARNING: + g_tls_password_set_warning (password, g_value_get_string (value)); + break; + case PROP_DESCRIPTION: + g_tls_password_set_description (password, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_tls_password_finalize (GObject *object) +{ + GTlsPassword *password = G_TLS_PASSWORD (object); + + g_tls_password_real_set_value (password, NULL, 0, NULL); + g_free (password->priv->warning); + g_free (password->priv->description); + + G_OBJECT_CLASS (g_tls_password_parent_class)->finalize (object); +} + +static void +g_tls_password_class_init (GTlsPasswordClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + klass->get_value = g_tls_password_real_get_value; + klass->set_value = g_tls_password_real_set_value; + klass->get_default_warning = g_tls_password_real_get_default_warning; + + gobject_class->get_property = g_tls_password_get_property; + gobject_class->set_property = g_tls_password_set_property; + gobject_class->finalize = g_tls_password_finalize; + + g_object_class_install_property (gobject_class, PROP_FLAGS, + g_param_spec_flags ("flags", + P_("Flags"), + P_("Flags about the password"), + G_TYPE_TLS_PASSWORD_FLAGS, + G_TLS_PASSWORD_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_DESCRIPTION, + g_param_spec_string ("description", + P_("Description"), + P_("Description of what the password is for"), + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_WARNING, + g_param_spec_string ("warning", + P_("Warning"), + P_("Warning about the password"), + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + +} + +/** + * g_tls_password_new: + * @flags: the password flags + * @description: description of what the password is for + * + * Create a new #GTlsPassword object. + * + * Returns: (transfer full): The newly allocated password object + */ +GTlsPassword * +g_tls_password_new (GTlsPasswordFlags flags, + const gchar *description) +{ + return g_object_new (G_TYPE_TLS_PASSWORD, + "flags", flags, + "description", description, + NULL); +} + +/** + * g_tls_password_get_value: (virtual get_value) + * @password: a #GTlsPassword object + * @length: (optional): location to place the length of the password. + * + * Get the password value. If @length is not %NULL then it will be + * filled in with the length of the password value. (Note that the + * password value is not nul-terminated, so you can only pass %NULL + * for @length in contexts where you know the password will have a + * certain fixed length.) + * + * Returns: (array length=length): The password value (owned by the password object). + * + * Since: 2.30 + */ +const guchar * +g_tls_password_get_value (GTlsPassword *password, + gsize *length) +{ + g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL); + return G_TLS_PASSWORD_GET_CLASS (password)->get_value (password, length); +} + +/** + * g_tls_password_set_value: + * @password: a #GTlsPassword object + * @value: (array length=length): the new password value + * @length: the length of the password, or -1 + * + * Set the value for this password. The @value will be copied by the password + * object. + * + * Specify the @length, for a non-nul-terminated password. Pass -1 as + * @length if using a nul-terminated password, and @length will be + * calculated automatically. (Note that the terminating nul is not + * considered part of the password in this case.) + * + * Since: 2.30 + */ +void +g_tls_password_set_value (GTlsPassword *password, + const guchar *value, + gssize length) +{ + g_return_if_fail (G_IS_TLS_PASSWORD (password)); + + if (length < 0) + { + /* FIXME: g_tls_password_set_value_full() doesn’t support unsigned gsize */ + gsize length_unsigned = strlen ((gchar *) value); + g_return_if_fail (length_unsigned <= G_MAXSSIZE); + length = (gssize) length_unsigned; + } + + g_tls_password_set_value_full (password, g_memdup2 (value, (gsize) length), length, g_free); +} + +/** + * g_tls_password_set_value_full: + * @password: a #GTlsPassword object + * @value: (array length=length): the value for the password + * @length: the length of the password, or -1 + * @destroy: (nullable): a function to use to free the password. + * + * Provide the value for this password. + * + * The @value will be owned by the password object, and later freed using + * the @destroy function callback. + * + * Specify the @length, for a non-nul-terminated password. Pass -1 as + * @length if using a nul-terminated password, and @length will be + * calculated automatically. (Note that the terminating nul is not + * considered part of the password in this case.) + * + * Virtual: set_value + * Since: 2.30 + */ +void +g_tls_password_set_value_full (GTlsPassword *password, + guchar *value, + gssize length, + GDestroyNotify destroy) +{ + g_return_if_fail (G_IS_TLS_PASSWORD (password)); + G_TLS_PASSWORD_GET_CLASS (password)->set_value (password, value, + length, destroy); +} + +/** + * g_tls_password_get_flags: + * @password: a #GTlsPassword object + * + * Get flags about the password. + * + * Returns: The flags about the password. + * + * Since: 2.30 + */ +GTlsPasswordFlags +g_tls_password_get_flags (GTlsPassword *password) +{ + g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_PASSWORD_NONE); + return password->priv->flags; +} + +/** + * g_tls_password_set_flags: + * @password: a #GTlsPassword object + * @flags: The flags about the password + * + * Set flags about the password. + * + * Since: 2.30 + */ +void +g_tls_password_set_flags (GTlsPassword *password, + GTlsPasswordFlags flags) +{ + g_return_if_fail (G_IS_TLS_PASSWORD (password)); + + password->priv->flags = flags; + + g_object_notify (G_OBJECT (password), "flags"); +} + +/** + * g_tls_password_get_description: + * @password: a #GTlsPassword object + * + * Get a description string about what the password will be used for. + * + * Returns: The description of the password. + * + * Since: 2.30 + */ +const gchar* +g_tls_password_get_description (GTlsPassword *password) +{ + g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL); + return password->priv->description; +} + +/** + * g_tls_password_set_description: + * @password: a #GTlsPassword object + * @description: The description of the password + * + * Set a description string about what the password will be used for. + * + * Since: 2.30 + */ +void +g_tls_password_set_description (GTlsPassword *password, + const gchar *description) +{ + gchar *copy; + + g_return_if_fail (G_IS_TLS_PASSWORD (password)); + + copy = g_strdup (description); + g_free (password->priv->description); + password->priv->description = copy; + + g_object_notify (G_OBJECT (password), "description"); +} + +/** + * g_tls_password_get_warning: + * @password: a #GTlsPassword object + * + * Get a user readable translated warning. Usually this warning is a + * representation of the password flags returned from + * g_tls_password_get_flags(). + * + * Returns: The warning. + * + * Since: 2.30 + */ +const gchar * +g_tls_password_get_warning (GTlsPassword *password) +{ + g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL); + + if (password->priv->warning == NULL) + return G_TLS_PASSWORD_GET_CLASS (password)->get_default_warning (password); + + return password->priv->warning; +} + +/** + * g_tls_password_set_warning: + * @password: a #GTlsPassword object + * @warning: The user readable warning + * + * Set a user readable translated warning. Usually this warning is a + * representation of the password flags returned from + * g_tls_password_get_flags(). + * + * Since: 2.30 + */ +void +g_tls_password_set_warning (GTlsPassword *password, + const gchar *warning) +{ + gchar *copy; + + g_return_if_fail (G_IS_TLS_PASSWORD (password)); + + copy = g_strdup (warning); + g_free (password->priv->warning); + password->priv->warning = copy; + + g_object_notify (G_OBJECT (password), "warning"); +} diff --git a/gio/gtlspassword.h b/gio/gtlspassword.h new file mode 100644 index 0000000..befe706 --- /dev/null +++ b/gio/gtlspassword.h @@ -0,0 +1,119 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#ifndef __G_TLS_PASSWORD_H__ +#define __G_TLS_PASSWORD_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TLS_PASSWORD (g_tls_password_get_type ()) +#define G_TLS_PASSWORD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_PASSWORD, GTlsPassword)) +#define G_TLS_PASSWORD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_PASSWORD, GTlsPasswordClass)) +#define G_IS_TLS_PASSWORD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_PASSWORD)) +#define G_IS_TLS_PASSWORD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_PASSWORD)) +#define G_TLS_PASSWORD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_PASSWORD, GTlsPasswordClass)) + +typedef struct _GTlsPasswordClass GTlsPasswordClass; +typedef struct _GTlsPasswordPrivate GTlsPasswordPrivate; + +struct _GTlsPassword +{ + GObject parent_instance; + + GTlsPasswordPrivate *priv; +}; + +/** + * GTlsPasswordClass: + * @get_value: virtual method for g_tls_password_get_value() + * @set_value: virtual method for g_tls_password_set_value() + * @get_default_warning: virtual method for g_tls_password_get_warning() if no + * value has been set using g_tls_password_set_warning() + * + * Class structure for #GTlsPassword. + */ +struct _GTlsPasswordClass +{ + GObjectClass parent_class; + + /* methods */ + + const guchar * ( *get_value) (GTlsPassword *password, + gsize *length); + + void ( *set_value) (GTlsPassword *password, + guchar *value, + gssize length, + GDestroyNotify destroy); + + const gchar* ( *get_default_warning) (GTlsPassword *password); + + /*< private >*/ + /* Padding for future expansion */ + gpointer padding[4]; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_password_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GTlsPassword * g_tls_password_new (GTlsPasswordFlags flags, + const gchar *description); + +GLIB_AVAILABLE_IN_ALL +const guchar * g_tls_password_get_value (GTlsPassword *password, + gsize *length); +GLIB_AVAILABLE_IN_ALL +void g_tls_password_set_value (GTlsPassword *password, + const guchar *value, + gssize length); +GLIB_AVAILABLE_IN_ALL +void g_tls_password_set_value_full (GTlsPassword *password, + guchar *value, + gssize length, + GDestroyNotify destroy); + +GLIB_AVAILABLE_IN_ALL +GTlsPasswordFlags g_tls_password_get_flags (GTlsPassword *password); +GLIB_AVAILABLE_IN_ALL +void g_tls_password_set_flags (GTlsPassword *password, + GTlsPasswordFlags flags); + +GLIB_AVAILABLE_IN_ALL +const gchar* g_tls_password_get_description (GTlsPassword *password); +GLIB_AVAILABLE_IN_ALL +void g_tls_password_set_description (GTlsPassword *password, + const gchar *description); + +GLIB_AVAILABLE_IN_ALL +const gchar * g_tls_password_get_warning (GTlsPassword *password); +GLIB_AVAILABLE_IN_ALL +void g_tls_password_set_warning (GTlsPassword *password, + const gchar *warning); + +G_END_DECLS + +#endif /* __G_TLS_PASSWORD_H__ */ diff --git a/gio/gtlsserverconnection.c b/gio/gtlsserverconnection.c new file mode 100644 index 0000000..dde9a83 --- /dev/null +++ b/gio/gtlsserverconnection.c @@ -0,0 +1,98 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2010 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include "glib.h" + +#include "gtlsserverconnection.h" +#include "ginitable.h" +#include "gioenumtypes.h" +#include "gsocket.h" +#include "gtlsbackend.h" +#include "gtlscertificate.h" +#include "glibintl.h" + +/** + * SECTION:gtlsserverconnection + * @short_description: TLS server-side connection + * @include: gio/gio.h + * + * #GTlsServerConnection is the server-side subclass of #GTlsConnection, + * representing a server-side TLS connection. + * + * Since: 2.28 + */ + +G_DEFINE_INTERFACE (GTlsServerConnection, g_tls_server_connection, G_TYPE_TLS_CONNECTION) + +static void +g_tls_server_connection_default_init (GTlsServerConnectionInterface *iface) +{ + /** + * GTlsServerConnection:authentication-mode: + * + * The #GTlsAuthenticationMode for the server. This can be changed + * before calling g_tls_connection_handshake() if you want to + * rehandshake with a different mode from the initial handshake. + * + * Since: 2.28 + */ + g_object_interface_install_property (iface, + g_param_spec_enum ("authentication-mode", + P_("Authentication Mode"), + P_("The client authentication mode"), + G_TYPE_TLS_AUTHENTICATION_MODE, + G_TLS_AUTHENTICATION_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_tls_server_connection_new: + * @base_io_stream: the #GIOStream to wrap + * @certificate: (nullable): the default server certificate, or %NULL + * @error: #GError for error reporting, or %NULL to ignore. + * + * Creates a new #GTlsServerConnection wrapping @base_io_stream (which + * must have pollable input and output streams). + * + * See the documentation for #GTlsConnection:base-io-stream for restrictions + * on when application code can run operations on the @base_io_stream after + * this function has returned. + * + * Returns: (transfer full) (type GTlsServerConnection): the new + * #GTlsServerConnection, or %NULL on error + * + * Since: 2.28 + */ +GIOStream * +g_tls_server_connection_new (GIOStream *base_io_stream, + GTlsCertificate *certificate, + GError **error) +{ + GObject *conn; + GTlsBackend *backend; + + backend = g_tls_backend_get_default (); + conn = g_initable_new (g_tls_backend_get_server_connection_type (backend), + NULL, error, + "base-io-stream", base_io_stream, + "certificate", certificate, + NULL); + return G_IO_STREAM (conn); +} diff --git a/gio/gtlsserverconnection.h b/gio/gtlsserverconnection.h new file mode 100644 index 0000000..6926e7d --- /dev/null +++ b/gio/gtlsserverconnection.h @@ -0,0 +1,69 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_TLS_SERVER_CONNECTION_H__ +#define __G_TLS_SERVER_CONNECTION_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TLS_SERVER_CONNECTION (g_tls_server_connection_get_type ()) +#define G_TLS_SERVER_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_SERVER_CONNECTION, GTlsServerConnection)) +#define G_IS_TLS_SERVER_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_SERVER_CONNECTION)) +#define G_TLS_SERVER_CONNECTION_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_TLS_SERVER_CONNECTION, GTlsServerConnectionInterface)) + +/** + * GTlsServerConnection: + * + * TLS server-side connection. This is the server-side implementation + * of a #GTlsConnection. + * + * Since: 2.28 + */ +typedef struct _GTlsServerConnectionInterface GTlsServerConnectionInterface; + +/** + * GTlsServerConnectionInterface: + * @g_iface: The parent interface. + * + * vtable for a #GTlsServerConnection implementation. + * + * Since: 2.26 + */ +struct _GTlsServerConnectionInterface +{ + GTypeInterface g_iface; + +}; + +GLIB_AVAILABLE_IN_ALL +GType g_tls_server_connection_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GIOStream * g_tls_server_connection_new (GIOStream *base_io_stream, + GTlsCertificate *certificate, + GError **error); + +G_END_DECLS + +#endif /* __G_TLS_SERVER_CONNECTION_H__ */ diff --git a/gio/gtrashportal.c b/gio/gtrashportal.c new file mode 100644 index 0000000..2f73960 --- /dev/null +++ b/gio/gtrashportal.c @@ -0,0 +1,138 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2018, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "gtrashportal.h" +#include "xdp-dbus.h" +#include "gstdio.h" + +#ifdef G_OS_UNIX +#include "gunixfdlist.h" +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#else +#define HAVE_O_CLOEXEC 1 +#endif + +#ifndef O_PATH +#define O_PATH 0 +#endif + +static GXdpTrash * +ensure_trash_portal (void) +{ + static GXdpTrash *trash = NULL; + + if (g_once_init_enter (&trash)) + { + GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + GXdpTrash *proxy = NULL; + + if (connection != NULL) + { + proxy = gxdp_trash_proxy_new_sync (connection, 0, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + NULL, NULL); + g_object_unref (connection); + } + + g_once_init_leave (&trash, proxy); + } + + return trash; +} + +gboolean +g_trash_portal_trash_file (GFile *file, + GError **error) +{ + char *path = NULL; + GUnixFDList *fd_list = NULL; + int fd, fd_in, errsv; + gboolean ret = FALSE; + guint portal_result = 0; + GXdpTrash *proxy; + + proxy = ensure_trash_portal (); + if (proxy == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, + "Trash portal is not available"); + goto out; + } + + path = g_file_get_path (file); + + fd = g_open (path, O_RDWR | O_CLOEXEC | O_NOFOLLOW); + if (fd == -1 && errno == EISDIR) + /* If it is a directory, fall back to O_PATH. + * Remove O_NOFOLLOW since + * a) we know it is a directory, not a symlink, and + * b) the portal reject this combination + */ + fd = g_open (path, O_PATH | O_CLOEXEC | O_RDONLY); + + errsv = errno; + + if (fd == -1) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + "Failed to open %s", path); + goto out; + } + +#ifndef HAVE_O_CLOEXEC + fcntl (fd, F_SETFD, FD_CLOEXEC); +#endif + + fd_list = g_unix_fd_list_new (); + fd_in = g_unix_fd_list_append (fd_list, fd, error); + g_close (fd, NULL); + + if (fd_in == -1) + goto out; + + ret = gxdp_trash_call_trash_file_sync (proxy, + g_variant_new_handle (fd_in), + fd_list, + &portal_result, + NULL, + NULL, + error); + + if (ret && portal_result != 1) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Trash portal failed on %s", path); + ret = FALSE; + } + + out: + g_clear_object (&fd_list); + g_free (path); + + return ret; +} diff --git a/gio/gtrashportal.h b/gio/gtrashportal.h new file mode 100644 index 0000000..a53de8a --- /dev/null +++ b/gio/gtrashportal.h @@ -0,0 +1,31 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_TRASH_PORTAL_H__ + +#include +#include + +G_BEGIN_DECLS + +gboolean g_trash_portal_trash_file (GFile *file, + GError **error); + +G_END_DECLS + +#endif diff --git a/gio/gunionvolumemonitor.c b/gio/gunionvolumemonitor.c new file mode 100644 index 0000000..c017303 --- /dev/null +++ b/gio/gunionvolumemonitor.c @@ -0,0 +1,635 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#include "config.h" + +#include + +#include +#include "gunionvolumemonitor.h" +#include "gmountprivate.h" +#include "giomodule-priv.h" +#ifdef G_OS_UNIX +#include "gunixvolumemonitor.h" +#endif +#include "gnativevolumemonitor.h" + +#include "glibintl.h" + + +struct _GUnionVolumeMonitor { + GVolumeMonitor parent; + + GList *monitors; +}; + +static void g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor, + GVolumeMonitor *child_monitor); + + +#define g_union_volume_monitor_get_type _g_union_volume_monitor_get_type +G_DEFINE_TYPE (GUnionVolumeMonitor, g_union_volume_monitor, G_TYPE_VOLUME_MONITOR) + +static GRecMutex the_volume_monitor_mutex; + +static GUnionVolumeMonitor *the_volume_monitor = NULL; + +static void +g_union_volume_monitor_finalize (GObject *object) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + + monitor = G_UNION_VOLUME_MONITOR (object); + + while (monitor->monitors != NULL) + { + child_monitor = monitor->monitors->data; + g_union_volume_monitor_remove_monitor (monitor, + child_monitor); + g_object_unref (child_monitor); + } + + G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->finalize (object); +} + +static void +g_union_volume_monitor_dispose (GObject *object) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (object); + + g_rec_mutex_lock (&the_volume_monitor_mutex); + the_volume_monitor = NULL; + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + g_object_run_dispose (G_OBJECT (child_monitor)); + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->dispose (object); +} + +static GList * +get_mounts (GVolumeMonitor *volume_monitor) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GList *res; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (volume_monitor); + + res = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + + res = g_list_concat (res, g_volume_monitor_get_mounts (child_monitor)); + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return res; +} + +static GList * +get_volumes (GVolumeMonitor *volume_monitor) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GList *res; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (volume_monitor); + + res = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + + res = g_list_concat (res, g_volume_monitor_get_volumes (child_monitor)); + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return res; +} + +static GList * +get_connected_drives (GVolumeMonitor *volume_monitor) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GList *res; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (volume_monitor); + + res = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + + res = g_list_concat (res, g_volume_monitor_get_connected_drives (child_monitor)); + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return res; +} + +static GVolume * +get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GVolume *volume; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (volume_monitor); + + volume = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + + volume = g_volume_monitor_get_volume_for_uuid (child_monitor, uuid); + if (volume != NULL) + break; + + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return volume; +} + +static GMount * +get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + GUnionVolumeMonitor *monitor; + GVolumeMonitor *child_monitor; + GMount *mount; + GList *l; + + monitor = G_UNION_VOLUME_MONITOR (volume_monitor); + + mount = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + + mount = g_volume_monitor_get_mount_for_uuid (child_monitor, uuid); + if (mount != NULL) + break; + + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return mount; +} + +static void +g_union_volume_monitor_class_init (GUnionVolumeMonitorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass); + + gobject_class->finalize = g_union_volume_monitor_finalize; + gobject_class->dispose = g_union_volume_monitor_dispose; + + monitor_class->get_connected_drives = get_connected_drives; + monitor_class->get_volumes = get_volumes; + monitor_class->get_mounts = get_mounts; + monitor_class->get_volume_for_uuid = get_volume_for_uuid; + monitor_class->get_mount_for_uuid = get_mount_for_uuid; +} + +static void +child_volume_added (GVolumeMonitor *child_monitor, + GVolume *child_volume, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "volume-added", + child_volume); +} + +static void +child_volume_removed (GVolumeMonitor *child_monitor, + GVolume *child_volume, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "volume-removed", + child_volume); +} + +static void +child_volume_changed (GVolumeMonitor *child_monitor, + GVolume *child_volume, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "volume-changed", + child_volume); +} + +static void +child_mount_added (GVolumeMonitor *child_monitor, + GMount *child_mount, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "mount-added", + child_mount); +} + +static void +child_mount_removed (GVolumeMonitor *child_monitor, + GMount *child_mount, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "mount-removed", + child_mount); +} + +static void +child_mount_pre_unmount (GVolumeMonitor *child_monitor, + GMount *child_mount, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "mount-pre-unmount", + child_mount); +} + + +static void +child_mount_changed (GVolumeMonitor *child_monitor, + GMount *child_mount, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "mount-changed", + child_mount); +} + +static void +child_drive_connected (GVolumeMonitor *child_monitor, + GDrive *child_drive, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "drive-connected", + child_drive); +} + +static void +child_drive_disconnected (GVolumeMonitor *child_monitor, + GDrive *child_drive, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "drive-disconnected", + child_drive); +} + +static void +child_drive_changed (GVolumeMonitor *child_monitor, + GDrive *child_drive, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "drive-changed", + child_drive); +} + +static void +child_drive_eject_button (GVolumeMonitor *child_monitor, + GDrive *child_drive, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "drive-eject-button", + child_drive); +} + +static void +child_drive_stop_button (GVolumeMonitor *child_monitor, + GDrive *child_drive, + GUnionVolumeMonitor *union_monitor) +{ + g_signal_emit_by_name (union_monitor, + "drive-stop-button", + child_drive); +} + +static void +g_union_volume_monitor_add_monitor (GUnionVolumeMonitor *union_monitor, + GVolumeMonitor *volume_monitor) +{ + if (g_list_find (union_monitor->monitors, volume_monitor)) + return; + + union_monitor->monitors = + g_list_prepend (union_monitor->monitors, + g_object_ref (volume_monitor)); + + g_signal_connect (volume_monitor, "volume-added", (GCallback)child_volume_added, union_monitor); + g_signal_connect (volume_monitor, "volume-removed", (GCallback)child_volume_removed, union_monitor); + g_signal_connect (volume_monitor, "volume-changed", (GCallback)child_volume_changed, union_monitor); + g_signal_connect (volume_monitor, "mount-added", (GCallback)child_mount_added, union_monitor); + g_signal_connect (volume_monitor, "mount-removed", (GCallback)child_mount_removed, union_monitor); + g_signal_connect (volume_monitor, "mount-pre-unmount", (GCallback)child_mount_pre_unmount, union_monitor); + g_signal_connect (volume_monitor, "mount-changed", (GCallback)child_mount_changed, union_monitor); + g_signal_connect (volume_monitor, "drive-connected", (GCallback)child_drive_connected, union_monitor); + g_signal_connect (volume_monitor, "drive-disconnected", (GCallback)child_drive_disconnected, union_monitor); + g_signal_connect (volume_monitor, "drive-changed", (GCallback)child_drive_changed, union_monitor); + g_signal_connect (volume_monitor, "drive-eject-button", (GCallback)child_drive_eject_button, union_monitor); + g_signal_connect (volume_monitor, "drive-stop-button", (GCallback)child_drive_stop_button, union_monitor); +} + +static void +g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor, + GVolumeMonitor *child_monitor) +{ + GList *l; + + l = g_list_find (union_monitor->monitors, child_monitor); + if (l == NULL) + return; + + union_monitor->monitors = g_list_delete_link (union_monitor->monitors, l); + + g_signal_handlers_disconnect_by_func (child_monitor, child_volume_added, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_volume_removed, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_volume_changed, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_mount_added, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_mount_removed, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_mount_pre_unmount, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_mount_changed, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_drive_connected, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_drive_disconnected, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_drive_changed, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_drive_eject_button, union_monitor); + g_signal_handlers_disconnect_by_func (child_monitor, child_drive_stop_button, union_monitor); +} + +static GType +get_default_native_class (gpointer data) +{ + return _g_io_module_get_default_type (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME, + "GIO_USE_VOLUME_MONITOR", + G_STRUCT_OFFSET (GVolumeMonitorClass, is_supported)); +} + +/* We return the class, with a ref taken. + * This way we avoid unloading the class/module + * between selecting the type and creating the + * instance on the first call. + */ +static GNativeVolumeMonitorClass * +get_native_class (void) +{ + static GOnce once_init = G_ONCE_INIT; + GTypeClass *type_class; + + type_class = NULL; + g_once (&once_init, (GThreadFunc)get_default_native_class, &type_class); + + if (type_class == NULL && once_init.retval != GUINT_TO_POINTER(G_TYPE_INVALID)) + type_class = g_type_class_ref ((GType)once_init.retval); + + return (GNativeVolumeMonitorClass *)type_class; +} + +static void +g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor) +{ +} + +static void +populate_union_monitor (GUnionVolumeMonitor *union_monitor) +{ + GVolumeMonitor *monitor; + GNativeVolumeMonitorClass *native_class; + GVolumeMonitorClass *klass; + GIOExtensionPoint *ep; + GIOExtension *extension; + GList *l; + + native_class = get_native_class (); + + if (native_class != NULL) + { + monitor = g_object_new (G_TYPE_FROM_CLASS (native_class), NULL); + g_union_volume_monitor_add_monitor (union_monitor, monitor); + g_object_unref (monitor); + g_type_class_unref (native_class); + } + + ep = g_io_extension_point_lookup (G_VOLUME_MONITOR_EXTENSION_POINT_NAME); + for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next) + { + extension = l->data; + + klass = G_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension)); + if (klass->is_supported == NULL || klass->is_supported()) + { + monitor = g_object_new (g_io_extension_get_type (extension), NULL); + g_union_volume_monitor_add_monitor (union_monitor, monitor); + g_object_unref (monitor); + } + g_type_class_unref (klass); + } +} + +static GUnionVolumeMonitor * +g_union_volume_monitor_new (void) +{ + GUnionVolumeMonitor *monitor; + + monitor = g_object_new (G_TYPE_UNION_VOLUME_MONITOR, NULL); + + return monitor; +} + +/** + * g_volume_monitor_get: + * + * Gets the volume monitor used by gio. + * + * Returns: (transfer full): a reference to the #GVolumeMonitor used by gio. Call + * g_object_unref() when done with it. + **/ +GVolumeMonitor * +g_volume_monitor_get (void) +{ + GVolumeMonitor *vm; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + if (the_volume_monitor) + vm = G_VOLUME_MONITOR (g_object_ref (the_volume_monitor)); + else + { + the_volume_monitor = g_union_volume_monitor_new (); + populate_union_monitor (the_volume_monitor); + vm = G_VOLUME_MONITOR (the_volume_monitor); + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return vm; +} + +GMount * +_g_mount_get_for_mount_path (const gchar *mount_path, + GCancellable *cancellable) +{ + GNativeVolumeMonitorClass *klass; + GMount *mount; + + klass = get_native_class (); + if (klass == NULL) + return NULL; + + mount = NULL; + + if (klass->get_mount_for_mount_path) + mount = klass->get_mount_for_mount_path (mount_path, cancellable); + + /* TODO: How do we know this succeeded? Keep in mind that the native + * volume monitor may fail (e.g. not being able to connect to + * udisks). Is the get_mount_for_mount_path() method allowed to + * return NULL? Seems like it is ... probably the method needs + * to take a boolean and write if it succeeds or not.. Messy. + * Very messy. + */ + + g_type_class_unref (klass); + + return mount; +} + +/** + * g_volume_monitor_adopt_orphan_mount: + * @mount: a #GMount object to find a parent for + * + * This function should be called by any #GVolumeMonitor + * implementation when a new #GMount object is created that is not + * associated with a #GVolume object. It must be called just before + * emitting the @mount_added signal. + * + * If the return value is not %NULL, the caller must associate the + * returned #GVolume object with the #GMount. This involves returning + * it in its g_mount_get_volume() implementation. The caller must + * also listen for the "removed" signal on the returned object + * and give up its reference when handling that signal + * + * Similarly, if implementing g_volume_monitor_adopt_orphan_mount(), + * the implementor must take a reference to @mount and return it in + * its g_volume_get_mount() implemented. Also, the implementor must + * listen for the "unmounted" signal on @mount and give up its + * reference upon handling that signal. + * + * There are two main use cases for this function. + * + * One is when implementing a user space file system driver that reads + * blocks of a block device that is already represented by the native + * volume monitor (for example a CD Audio file system driver). Such + * a driver will generate its own #GMount object that needs to be + * associated with the #GVolume object that represents the volume. + * + * The other is for implementing a #GVolumeMonitor whose sole purpose + * is to return #GVolume objects representing entries in the users + * "favorite servers" list or similar. + * + * Returns: (transfer full): the #GVolume object that is the parent for @mount or %NULL + * if no wants to adopt the #GMount. + * + * Deprecated: 2.20: Instead of using this function, #GVolumeMonitor + * implementations should instead create shadow mounts with the URI of + * the mount they intend to adopt. See the proxy volume monitor in + * gvfs for an example of this. Also see g_mount_is_shadowed(), + * g_mount_shadow() and g_mount_unshadow() functions. + */ +GVolume * +g_volume_monitor_adopt_orphan_mount (GMount *mount) +{ + GVolumeMonitor *child_monitor; + GVolumeMonitorClass *child_monitor_class; + GVolume *volume; + GList *l; + + g_return_val_if_fail (mount != NULL, NULL); + + if (the_volume_monitor == NULL) + return NULL; + + volume = NULL; + + g_rec_mutex_lock (&the_volume_monitor_mutex); + + for (l = the_volume_monitor->monitors; l != NULL; l = l->next) + { + child_monitor = l->data; + child_monitor_class = G_VOLUME_MONITOR_GET_CLASS (child_monitor); + + if (child_monitor_class->adopt_orphan_mount != NULL) + { + volume = child_monitor_class->adopt_orphan_mount (mount, child_monitor); + if (volume != NULL) + break; + } + } + + g_rec_mutex_unlock (&the_volume_monitor_mutex); + + return volume; +} diff --git a/gio/gunionvolumemonitor.h b/gio/gunionvolumemonitor.h new file mode 100644 index 0000000..5e4c544 --- /dev/null +++ b/gio/gunionvolumemonitor.h @@ -0,0 +1,47 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#ifndef __G_UNION_VOLUME_MONITOR_H__ +#define __G_UNION_VOLUME_MONITOR_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNION_VOLUME_MONITOR (_g_union_volume_monitor_get_type ()) +#define G_UNION_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNION_VOLUME_MONITOR, GUnionVolumeMonitor)) +#define G_UNION_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNION_VOLUME_MONITOR, GUnionVolumeMonitorClass)) +#define G_IS_UNION_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNION_VOLUME_MONITOR)) +#define G_IS_UNION_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNION_VOLUME_MONITOR)) + +typedef struct _GUnionVolumeMonitor GUnionVolumeMonitor; +typedef struct _GUnionVolumeMonitorClass GUnionVolumeMonitorClass; + +struct _GUnionVolumeMonitorClass +{ + GVolumeMonitorClass parent_class; +}; + +GType _g_union_volume_monitor_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __G_UNION_VOLUME_MONITOR_H__ */ diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c new file mode 100644 index 0000000..e89aba6 --- /dev/null +++ b/gio/gunixconnection.c @@ -0,0 +1,735 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Ryan Lortie + */ + +#include "config.h" + +#include "gunixconnection.h" +#include "gnetworking.h" +#include "gsocket.h" +#include "gsocketcontrolmessage.h" +#include "gunixcredentialsmessage.h" +#include "gunixfdmessage.h" +#include "glibintl.h" + +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +/** + * SECTION:gunixconnection + * @title: GUnixConnection + * @short_description: A UNIX domain GSocketConnection + * @include: gio/gunixconnection.h + * @see_also: #GSocketConnection. + * + * This is the subclass of #GSocketConnection that is created + * for UNIX domain sockets. + * + * It contains functions to do some of the UNIX socket specific + * functionality like passing file descriptors. + * + * Since GLib 2.72, #GUnixConnection is available on all platforms. It requires + * underlying system support (such as Windows 10 with `AF_UNIX`) at run time. + * + * Before GLib 2.72, `` belonged to the UNIX-specific GIO + * interfaces, thus you had to use the `gio-unix-2.0.pc` pkg-config file when + * using it. This is no longer necessary since GLib 2.72. + * + * Since: 2.22 + */ + +/** + * GUnixConnection: + * + * #GUnixConnection is an opaque data structure and can only be accessed + * using the following functions. + **/ + +G_DEFINE_TYPE_WITH_CODE (GUnixConnection, g_unix_connection, + G_TYPE_SOCKET_CONNECTION, + g_socket_connection_factory_register_type (g_define_type_id, + G_SOCKET_FAMILY_UNIX, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT); + ); + +/** + * g_unix_connection_send_fd: + * @connection: a #GUnixConnection + * @fd: a file descriptor + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @error: (nullable): #GError for error reporting, or %NULL to ignore. + * + * Passes a file descriptor to the receiving side of the + * connection. The receiving end has to call g_unix_connection_receive_fd() + * to accept the file descriptor. + * + * As well as sending the fd this also writes a single byte to the + * stream, as this is required for fd passing to work on some + * implementations. + * + * Returns: a %TRUE on success, %NULL on error. + * + * Since: 2.22 + */ +gboolean +g_unix_connection_send_fd (GUnixConnection *connection, + gint fd, + GCancellable *cancellable, + GError **error) +{ +#ifdef G_OS_UNIX + GSocketControlMessage *scm; + GSocket *socket; + + g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE); + g_return_val_if_fail (fd >= 0, FALSE); + + scm = g_unix_fd_message_new (); + + if (!g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (scm), fd, error)) + { + g_object_unref (scm); + return FALSE; + } + + g_object_get (connection, "socket", &socket, NULL); + if (g_socket_send_message (socket, NULL, NULL, 0, &scm, 1, 0, cancellable, error) != 1) + /* XXX could it 'fail' with zero? */ + { + g_object_unref (socket); + g_object_unref (scm); + + return FALSE; + } + + g_object_unref (socket); + g_object_unref (scm); + + return TRUE; +#else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Sending FD is not supported")); + return FALSE; +#endif +} + +/** + * g_unix_connection_receive_fd: + * @connection: a #GUnixConnection + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @error: (nullable): #GError for error reporting, or %NULL to ignore + * + * Receives a file descriptor from the sending end of the connection. + * The sending end has to call g_unix_connection_send_fd() for this + * to work. + * + * As well as reading the fd this also reads a single byte from the + * stream, as this is required for fd passing to work on some + * implementations. + * + * Returns: a file descriptor on success, -1 on error. + * + * Since: 2.22 + **/ +gint +g_unix_connection_receive_fd (GUnixConnection *connection, + GCancellable *cancellable, + GError **error) +{ +#ifdef G_OS_UNIX + GSocketControlMessage **scms; + gint *fds, nfd, fd, nscm; + GUnixFDMessage *fdmsg; + GSocket *socket; + + g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), -1); + + g_object_get (connection, "socket", &socket, NULL); + if (g_socket_receive_message (socket, NULL, NULL, 0, + &scms, &nscm, NULL, cancellable, error) != 1) + /* XXX it _could_ 'fail' with zero. */ + { + g_object_unref (socket); + + return -1; + } + + g_object_unref (socket); + + if (nscm != 1) + { + gint i; + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + ngettext("Expecting 1 control message, got %d", + "Expecting 1 control message, got %d", + nscm), + nscm); + + for (i = 0; i < nscm; i++) + g_object_unref (scms[i]); + + g_free (scms); + + return -1; + } + + if (!G_IS_UNIX_FD_MESSAGE (scms[0])) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Unexpected type of ancillary data")); + g_object_unref (scms[0]); + g_free (scms); + + return -1; + } + + fdmsg = G_UNIX_FD_MESSAGE (scms[0]); + g_free (scms); + + fds = g_unix_fd_message_steal_fds (fdmsg, &nfd); + g_object_unref (fdmsg); + + if (nfd != 1) + { + gint i; + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + ngettext("Expecting one fd, but got %d\n", + "Expecting one fd, but got %d\n", + nfd), + nfd); + + for (i = 0; i < nfd; i++) + close (fds[i]); + + g_free (fds); + + return -1; + } + + fd = *fds; + g_free (fds); + + if (fd < 0) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Received invalid fd")); + fd = -1; + } + + return fd; +#else + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Receiving FD is not supported")); + return -1; +#endif +} + +static void +g_unix_connection_init (GUnixConnection *connection) +{ +} + +static void +g_unix_connection_class_init (GUnixConnectionClass *class) +{ +} + +/* TODO: Other stuff we might want to add are: +void g_unix_connection_send_fd_async (GUnixConnection *connection, + gint fd, + gboolean close, + gint io_priority, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean g_unix_connection_send_fd_finish (GUnixConnection *connection, + GError **error); + +gboolean g_unix_connection_send_fds (GUnixConnection *connection, + gint *fds, + gint nfds, + GError **error); +void g_unix_connection_send_fds_async (GUnixConnection *connection, + gint *fds, + gint nfds, + gint io_priority, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean g_unix_connection_send_fds_finish (GUnixConnection *connection, + GError **error); + +void g_unix_connection_receive_fd_async (GUnixConnection *connection, + gint io_priority, + GAsyncReadyCallback callback, + gpointer user_data); +gint g_unix_connection_receive_fd_finish (GUnixConnection *connection, + GError **error); + + +gboolean g_unix_connection_send_fake_credentials (GUnixConnection *connection, + guint64 pid, + guint64 uid, + guint64 gid, + GError **error); +void g_unix_connection_send_fake_credentials_async (GUnixConnection *connection, + guint64 pid, + guint64 uid, + guint64 gid, + gint io_priority, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean g_unix_connection_send_fake_credentials_finish (GUnixConnection *connection, + GError **error); + +gboolean g_unix_connection_create_pair (GUnixConnection **one, + GUnixConnection **two, + GError **error); +*/ + + +/** + * g_unix_connection_send_credentials: + * @connection: A #GUnixConnection. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Passes the credentials of the current user the receiving side + * of the connection. The receiving end has to call + * g_unix_connection_receive_credentials() (or similar) to accept the + * credentials. + * + * As well as sending the credentials this also writes a single NUL + * byte to the stream, as this is required for credentials passing to + * work on some implementations. + * + * This method can be expected to be available on the following platforms: + * + * - Linux since GLib 2.26 + * - FreeBSD since GLib 2.26 + * - GNU/kFreeBSD since GLib 2.36 + * - Solaris, Illumos and OpenSolaris since GLib 2.40 + * - GNU/Hurd since GLib 2.40 + * + * Other ways to exchange credentials with a foreign peer includes the + * #GUnixCredentialsMessage type and g_socket_get_credentials() function. + * + * Returns: %TRUE on success, %FALSE if @error is set. + * + * Since: 2.26 + */ +gboolean +g_unix_connection_send_credentials (GUnixConnection *connection, + GCancellable *cancellable, + GError **error) +{ + GCredentials *credentials; + GSocketControlMessage *scm; + GSocket *socket; + gboolean ret; + GOutputVector vector; + guchar nul_byte[1] = {'\0'}; + gint num_messages; + + g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + ret = FALSE; + + credentials = g_credentials_new (); + + vector.buffer = &nul_byte; + vector.size = 1; + + if (g_unix_credentials_message_is_supported ()) + { + scm = g_unix_credentials_message_new_with_credentials (credentials); + num_messages = 1; + } + else + { + scm = NULL; + num_messages = 0; + } + + g_object_get (connection, "socket", &socket, NULL); + if (g_socket_send_message (socket, + NULL, /* address */ + &vector, + 1, + &scm, + num_messages, + G_SOCKET_MSG_NONE, + cancellable, + error) != 1) + { + g_prefix_error (error, _("Error sending credentials: ")); + goto out; + } + + ret = TRUE; + + out: + g_object_unref (socket); + if (scm != NULL) + g_object_unref (scm); + g_object_unref (credentials); + return ret; +} + +static void +send_credentials_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + + if (g_unix_connection_send_credentials (G_UNIX_CONNECTION (source_object), + cancellable, + &error)) + g_task_return_boolean (task, TRUE); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +/** + * g_unix_connection_send_credentials_async: + * @connection: A #GUnixConnection. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously send credentials. + * + * For more details, see g_unix_connection_send_credentials() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. You can then call + * g_unix_connection_send_credentials_finish() to get the result of the operation. + * + * Since: 2.32 + **/ +void +g_unix_connection_send_credentials_async (GUnixConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (connection, cancellable, callback, user_data); + g_task_set_source_tag (task, g_unix_connection_send_credentials_async); + g_task_run_in_thread (task, send_credentials_async_thread); +} + +/** + * g_unix_connection_send_credentials_finish: + * @connection: A #GUnixConnection. + * @result: a #GAsyncResult. + * @error: a #GError, or %NULL + * + * Finishes an asynchronous send credentials operation started with + * g_unix_connection_send_credentials_async(). + * + * Returns: %TRUE if the operation was successful, otherwise %FALSE. + * + * Since: 2.32 + **/ +gboolean +g_unix_connection_send_credentials_finish (GUnixConnection *connection, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, connection), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +/** + * g_unix_connection_receive_credentials: + * @connection: A #GUnixConnection. + * @cancellable: (nullable): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Receives credentials from the sending end of the connection. The + * sending end has to call g_unix_connection_send_credentials() (or + * similar) for this to work. + * + * As well as reading the credentials this also reads (and discards) a + * single byte from the stream, as this is required for credentials + * passing to work on some implementations. + * + * This method can be expected to be available on the following platforms: + * + * - Linux since GLib 2.26 + * - FreeBSD since GLib 2.26 + * - GNU/kFreeBSD since GLib 2.36 + * - Solaris, Illumos and OpenSolaris since GLib 2.40 + * - GNU/Hurd since GLib 2.40 + * + * Other ways to exchange credentials with a foreign peer includes the + * #GUnixCredentialsMessage type and g_socket_get_credentials() function. + * + * Returns: (transfer full): Received credentials on success (free with + * g_object_unref()), %NULL if @error is set. + * + * Since: 2.26 + */ +GCredentials * +g_unix_connection_receive_credentials (GUnixConnection *connection, + GCancellable *cancellable, + GError **error) +{ + GCredentials *ret; + GSocketControlMessage **scms; + gint nscm; + GSocket *socket; + gint n; + gssize num_bytes_read; +#ifdef __linux__ + gboolean turn_off_so_passcreds; +#endif + + g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + ret = NULL; + scms = NULL; + + g_object_get (connection, "socket", &socket, NULL); + + /* On Linux, we need to turn on SO_PASSCRED if it isn't enabled + * already. We also need to turn it off when we're done. See + * #617483 for more discussion. + */ +#ifdef __linux__ + { + gint opt_val; + + turn_off_so_passcreds = FALSE; + opt_val = 0; + if (!g_socket_get_option (socket, + SOL_SOCKET, + SO_PASSCRED, + &opt_val, + NULL)) + { + int errsv = errno; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error checking if SO_PASSCRED is enabled for socket: %s"), + g_strerror (errsv)); + goto out; + } + if (opt_val == 0) + { + if (!g_socket_set_option (socket, + SOL_SOCKET, + SO_PASSCRED, + TRUE, + NULL)) + { + int errsv = errno; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error enabling SO_PASSCRED: %s"), + g_strerror (errsv)); + goto out; + } + turn_off_so_passcreds = TRUE; + } + } +#endif + + g_type_ensure (G_TYPE_UNIX_CREDENTIALS_MESSAGE); + num_bytes_read = g_socket_receive_message (socket, + NULL, /* GSocketAddress **address */ + NULL, + 0, + &scms, + &nscm, + NULL, + cancellable, + error); + if (num_bytes_read != 1) + { + /* Handle situation where g_socket_receive_message() returns + * 0 bytes and not setting @error + */ + if (num_bytes_read == 0 && error != NULL && *error == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Expecting to read a single byte for receiving credentials but read zero bytes")); + } + goto out; + } + + if (g_unix_credentials_message_is_supported () && + /* Fall back on get_credentials if the other side didn't send the credentials */ + nscm > 0) + { + if (nscm != 1) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + ngettext("Expecting 1 control message, got %d", + "Expecting 1 control message, got %d", + nscm), + nscm); + goto out; + } + + if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0])) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unexpected type of ancillary data")); + goto out; + } + + ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0])); + g_object_ref (ret); + } + else + { + if (nscm != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Not expecting control message, but got %d"), + nscm); + goto out; + } + else + { + ret = g_socket_get_credentials (socket, error); + } + } + + out: + +#ifdef __linux__ + if (turn_off_so_passcreds) + { + if (!g_socket_set_option (socket, + SOL_SOCKET, + SO_PASSCRED, + FALSE, + NULL)) + { + int errsv = errno; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error while disabling SO_PASSCRED: %s"), + g_strerror (errsv)); + goto out; + } + } +#endif + + if (scms != NULL) + { + for (n = 0; n < nscm; n++) + g_object_unref (scms[n]); + g_free (scms); + } + g_object_unref (socket); + return ret; +} + +static void +receive_credentials_async_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GCredentials *creds; + GError *error = NULL; + + creds = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (source_object), + cancellable, + &error); + if (creds) + g_task_return_pointer (task, creds, g_object_unref); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +/** + * g_unix_connection_receive_credentials_async: + * @connection: A #GUnixConnection. + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously receive credentials. + * + * For more details, see g_unix_connection_receive_credentials() which is + * the synchronous version of this call. + * + * When the operation is finished, @callback will be called. You can then call + * g_unix_connection_receive_credentials_finish() to get the result of the operation. + * + * Since: 2.32 + **/ +void +g_unix_connection_receive_credentials_async (GUnixConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (connection, cancellable, callback, user_data); + g_task_set_source_tag (task, g_unix_connection_receive_credentials_async); + g_task_run_in_thread (task, receive_credentials_async_thread); +} + +/** + * g_unix_connection_receive_credentials_finish: + * @connection: A #GUnixConnection. + * @result: a #GAsyncResult. + * @error: a #GError, or %NULL + * + * Finishes an asynchronous receive credentials operation started with + * g_unix_connection_receive_credentials_async(). + * + * Returns: (transfer full): a #GCredentials, or %NULL on error. + * Free the returned object with g_object_unref(). + * + * Since: 2.32 + **/ +GCredentials * +g_unix_connection_receive_credentials_finish (GUnixConnection *connection, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, connection), NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} diff --git a/gio/gunixconnection.h b/gio/gunixconnection.h new file mode 100644 index 0000000..620c72b --- /dev/null +++ b/gio/gunixconnection.h @@ -0,0 +1,100 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_UNIX_CONNECTION_H__ +#define __G_UNIX_CONNECTION_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_CONNECTION (g_unix_connection_get_type ()) +#define G_UNIX_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_UNIX_CONNECTION, GUnixConnection)) +#define G_UNIX_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_UNIX_CONNECTION, GUnixConnectionClass)) +#define G_IS_UNIX_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_UNIX_CONNECTION)) +#define G_IS_UNIX_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_UNIX_CONNECTION)) +#define G_UNIX_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_UNIX_CONNECTION, GUnixConnectionClass)) + +typedef struct _GUnixConnection GUnixConnection; +typedef struct _GUnixConnectionPrivate GUnixConnectionPrivate; +typedef struct _GUnixConnectionClass GUnixConnectionClass; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixConnection, g_object_unref) + +struct _GUnixConnectionClass +{ + GSocketConnectionClass parent_class; +}; + +struct _GUnixConnection +{ + GSocketConnection parent_instance; + GUnixConnectionPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_unix_connection_get_type (void); + +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_connection_send_fd (GUnixConnection *connection, + gint fd, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_ALL +gint g_unix_connection_receive_fd (GUnixConnection *connection, + GCancellable *cancellable, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_connection_send_credentials (GUnixConnection *connection, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_32 +void g_unix_connection_send_credentials_async (GUnixConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_2_32 +gboolean g_unix_connection_send_credentials_finish (GUnixConnection *connection, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_32 +GCredentials *g_unix_connection_receive_credentials (GUnixConnection *connection, + GCancellable *cancellable, + GError **error); +GLIB_AVAILABLE_IN_2_32 +void g_unix_connection_receive_credentials_async (GUnixConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GCredentials *g_unix_connection_receive_credentials_finish (GUnixConnection *connection, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __G_UNIX_CONNECTION_H__ */ diff --git a/gio/gunixcredentialsmessage.c b/gio/gunixcredentialsmessage.c new file mode 100644 index 0000000..e8ac5a7 --- /dev/null +++ b/gio/gunixcredentialsmessage.c @@ -0,0 +1,355 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: David Zeuthen + */ + +/** + * SECTION:gunixcredentialsmessage + * @title: GUnixCredentialsMessage + * @short_description: A GSocketControlMessage containing credentials + * @include: gio/gunixcredentialsmessage.h + * @see_also: #GUnixConnection, #GSocketControlMessage + * + * This #GSocketControlMessage contains a #GCredentials instance. It + * may be sent using g_socket_send_message() and received using + * g_socket_receive_message() over UNIX sockets (ie: sockets in the + * %G_SOCKET_FAMILY_UNIX family). + * + * For an easier way to send and receive credentials over + * stream-oriented UNIX sockets, see + * g_unix_connection_send_credentials() and + * g_unix_connection_receive_credentials(). To receive credentials of + * a foreign process connected to a socket, use + * g_socket_get_credentials(). + * + * Since GLib 2.72, #GUnixCredentialMessage is available on all platforms. It + * requires underlying system support (such as Windows 10 with `AF_UNIX`) at run + * time. + * + * Before GLib 2.72, `` belonged to the UNIX-specific + * GIO interfaces, thus you had to use the `gio-unix-2.0.pc` pkg-config file + * when using it. This is no longer necessary since GLib 2.72. + */ + +#include "config.h" + +/* ---------------------------------------------------------------------------------------------------- */ + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "gunixcredentialsmessage.h" +#include "gcredentials.h" +#include "gcredentialsprivate.h" +#include "gnetworking.h" + +#include "glibintl.h" + +struct _GUnixCredentialsMessagePrivate +{ + GCredentials *credentials; +}; + +enum +{ + PROP_0, + PROP_CREDENTIALS +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GUnixCredentialsMessage, g_unix_credentials_message, G_TYPE_SOCKET_CONTROL_MESSAGE) + +static gsize +g_unix_credentials_message_get_size (GSocketControlMessage *message) +{ +#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED + return G_CREDENTIALS_NATIVE_SIZE; +#else + return 0; +#endif +} + +static int +g_unix_credentials_message_get_level (GSocketControlMessage *message) +{ +#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED + return SOL_SOCKET; +#else + return 0; +#endif +} + +static int +g_unix_credentials_message_get_msg_type (GSocketControlMessage *message) +{ +#if G_CREDENTIALS_USE_LINUX_UCRED + return SCM_CREDENTIALS; +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + return SCM_CREDS; +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + return SCM_CREDS; +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + return SCM_UCRED; +#elif G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED + #error "G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED is set but there is no msg_type defined for this platform" +#else + /* includes G_CREDENTIALS_USE_APPLE_XUCRED */ + return 0; +#endif +} + +static GSocketControlMessage * +g_unix_credentials_message_deserialize (gint level, + gint type, + gsize size, + gpointer data) +{ +#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED + GSocketControlMessage *message; + GCredentials *credentials; + + if (level != SOL_SOCKET || type != g_unix_credentials_message_get_msg_type (NULL)) + return NULL; + + if (size != G_CREDENTIALS_NATIVE_SIZE) + { + g_warning ("Expected a credentials struct of %" G_GSIZE_FORMAT " bytes but " + "got %" G_GSIZE_FORMAT " bytes of data", + G_CREDENTIALS_NATIVE_SIZE, size); + return NULL; + } + + credentials = g_credentials_new (); + g_credentials_set_native (credentials, G_CREDENTIALS_NATIVE_TYPE, data); + + if (g_credentials_get_unix_user (credentials, NULL) == (uid_t) -1) + { + /* This happens on Linux if the remote side didn't pass the credentials */ + g_object_unref (credentials); + return NULL; + } + + message = g_unix_credentials_message_new_with_credentials (credentials); + g_object_unref (credentials); + + return message; + +#else /* !G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED */ + + return NULL; +#endif +} + +static void +g_unix_credentials_message_serialize (GSocketControlMessage *_message, + gpointer data) +{ +#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED + GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (_message); + + memcpy (data, + g_credentials_get_native (message->priv->credentials, + G_CREDENTIALS_NATIVE_TYPE), + G_CREDENTIALS_NATIVE_SIZE); +#endif +} + +static void +g_unix_credentials_message_finalize (GObject *object) +{ + GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (object); + + if (message->priv->credentials != NULL) + g_object_unref (message->priv->credentials); + + G_OBJECT_CLASS (g_unix_credentials_message_parent_class)->finalize (object); +} + +static void +g_unix_credentials_message_init (GUnixCredentialsMessage *message) +{ + message->priv = g_unix_credentials_message_get_instance_private (message); +} + +static void +g_unix_credentials_message_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (object); + + switch (prop_id) + { + case PROP_CREDENTIALS: + g_value_set_object (value, message->priv->credentials); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_unix_credentials_message_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (object); + + switch (prop_id) + { + case PROP_CREDENTIALS: + message->priv->credentials = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_unix_credentials_message_constructed (GObject *object) +{ + GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (object); + + if (message->priv->credentials == NULL) + message->priv->credentials = g_credentials_new (); + + if (G_OBJECT_CLASS (g_unix_credentials_message_parent_class)->constructed != NULL) + G_OBJECT_CLASS (g_unix_credentials_message_parent_class)->constructed (object); +} + +static void +g_unix_credentials_message_class_init (GUnixCredentialsMessageClass *class) +{ + GSocketControlMessageClass *scm_class; + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (class); + gobject_class->get_property = g_unix_credentials_message_get_property; + gobject_class->set_property = g_unix_credentials_message_set_property; + gobject_class->finalize = g_unix_credentials_message_finalize; + gobject_class->constructed = g_unix_credentials_message_constructed; + + scm_class = G_SOCKET_CONTROL_MESSAGE_CLASS (class); + scm_class->get_size = g_unix_credentials_message_get_size; + scm_class->get_level = g_unix_credentials_message_get_level; + scm_class->get_type = g_unix_credentials_message_get_msg_type; + scm_class->serialize = g_unix_credentials_message_serialize; + scm_class->deserialize = g_unix_credentials_message_deserialize; + + /** + * GUnixCredentialsMessage:credentials: + * + * The credentials stored in the message. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_CREDENTIALS, + g_param_spec_object ("credentials", + P_("Credentials"), + P_("The credentials stored in the message"), + G_TYPE_CREDENTIALS, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK)); + +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_unix_credentials_message_is_supported: + * + * Checks if passing #GCredentials on a #GSocket is supported on this platform. + * + * Returns: %TRUE if supported, %FALSE otherwise + * + * Since: 2.26 + */ +gboolean +g_unix_credentials_message_is_supported (void) +{ +#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED + return TRUE; +#else + return FALSE; +#endif +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_unix_credentials_message_new: + * + * Creates a new #GUnixCredentialsMessage with credentials matching the current processes. + * + * Returns: a new #GUnixCredentialsMessage + * + * Since: 2.26 + */ +GSocketControlMessage * +g_unix_credentials_message_new (void) +{ + g_return_val_if_fail (g_unix_credentials_message_is_supported (), NULL); + return g_object_new (G_TYPE_UNIX_CREDENTIALS_MESSAGE, + NULL); +} + +/** + * g_unix_credentials_message_new_with_credentials: + * @credentials: A #GCredentials object. + * + * Creates a new #GUnixCredentialsMessage holding @credentials. + * + * Returns: a new #GUnixCredentialsMessage + * + * Since: 2.26 + */ +GSocketControlMessage * +g_unix_credentials_message_new_with_credentials (GCredentials *credentials) +{ + g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); + g_return_val_if_fail (g_unix_credentials_message_is_supported (), NULL); + return g_object_new (G_TYPE_UNIX_CREDENTIALS_MESSAGE, + "credentials", credentials, + NULL); +} + +/** + * g_unix_credentials_message_get_credentials: + * @message: A #GUnixCredentialsMessage. + * + * Gets the credentials stored in @message. + * + * Returns: (transfer none): A #GCredentials instance. Do not free, it is owned by @message. + * + * Since: 2.26 + */ +GCredentials * +g_unix_credentials_message_get_credentials (GUnixCredentialsMessage *message) +{ + g_return_val_if_fail (G_IS_UNIX_CREDENTIALS_MESSAGE (message), NULL); + return message->priv->credentials; +} diff --git a/gio/gunixcredentialsmessage.h b/gio/gunixcredentialsmessage.h new file mode 100644 index 0000000..2f3ad75 --- /dev/null +++ b/gio/gunixcredentialsmessage.h @@ -0,0 +1,87 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: David Zeuthen + */ + +#ifndef __G_UNIX_CREDENTIALS_MESSAGE_H__ +#define __G_UNIX_CREDENTIALS_MESSAGE_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_CREDENTIALS_MESSAGE (g_unix_credentials_message_get_type ()) +#define G_UNIX_CREDENTIALS_MESSAGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_CREDENTIALS_MESSAGE, GUnixCredentialsMessage)) +#define G_UNIX_CREDENTIALS_MESSAGE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), G_TYPE_UNIX_CREDENTIALS_MESSAGE, GUnixCredentialsMessageClass)) +#define G_IS_UNIX_CREDENTIALS_MESSAGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_CREDENTIALS_MESSAGE)) +#define G_IS_UNIX_CREDENTIALS_MESSAGE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), G_TYPE_UNIX_CREDENTIALS_MESSAGE)) +#define G_UNIX_CREDENTIALS_MESSAGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_UNIX_CREDENTIALS_MESSAGE, GUnixCredentialsMessageClass)) + +typedef struct _GUnixCredentialsMessagePrivate GUnixCredentialsMessagePrivate; +typedef struct _GUnixCredentialsMessageClass GUnixCredentialsMessageClass; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixCredentialsMessage, g_object_unref) + +/** + * GUnixCredentialsMessageClass: + * + * Class structure for #GUnixCredentialsMessage. + * + * Since: 2.26 + */ +struct _GUnixCredentialsMessageClass +{ + GSocketControlMessageClass parent_class; + + /*< private >*/ + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); +}; + +/** + * GUnixCredentialsMessage: + * + * The #GUnixCredentialsMessage structure contains only private data + * and should only be accessed using the provided API. + * + * Since: 2.26 + */ +struct _GUnixCredentialsMessage +{ + GSocketControlMessage parent_instance; + GUnixCredentialsMessagePrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_unix_credentials_message_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GSocketControlMessage *g_unix_credentials_message_new (void); +GLIB_AVAILABLE_IN_ALL +GSocketControlMessage *g_unix_credentials_message_new_with_credentials (GCredentials *credentials); +GLIB_AVAILABLE_IN_ALL +GCredentials *g_unix_credentials_message_get_credentials (GUnixCredentialsMessage *message); + +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_credentials_message_is_supported (void); + +G_END_DECLS + +#endif /* __G_UNIX_CREDENTIALS_MESSAGE_H__ */ diff --git a/gio/gunixfdlist.c b/gio/gunixfdlist.c new file mode 100644 index 0000000..e8c4ac5 --- /dev/null +++ b/gio/gunixfdlist.c @@ -0,0 +1,400 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Ryan Lortie + */ + +/** + * SECTION:gunixfdlist + * @title: GUnixFDList + * @short_description: An object containing a set of UNIX file descriptors + * @include: gio/gunixfdlist.h + * @see_also: #GUnixFDMessage + * + * A #GUnixFDList contains a list of file descriptors. It owns the file + * descriptors that it contains, closing them when finalized. + * + * It may be wrapped in a #GUnixFDMessage and sent over a #GSocket in + * the %G_SOCKET_FAMILY_UNIX family by using g_socket_send_message() + * and received using g_socket_receive_message(). + * + * Note that `` belongs to the UNIX-specific GIO + * interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config + * file when using it. + */ + +/** + * GUnixFDList: + * + * #GUnixFDList is an opaque data structure and can only be accessed + * using the following functions. + **/ + +#include "config.h" + +#include +#include +#include +#include + +#include "gunixfdlist.h" +#include "gnetworking.h" +#include "gioerror.h" + +struct _GUnixFDListPrivate +{ + gint *fds; + gint nfd; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GUnixFDList, g_unix_fd_list, G_TYPE_OBJECT) + +static void +g_unix_fd_list_init (GUnixFDList *list) +{ + list->priv = g_unix_fd_list_get_instance_private (list); +} + +static void +g_unix_fd_list_finalize (GObject *object) +{ + GUnixFDList *list = G_UNIX_FD_LIST (object); + gint i; + + for (i = 0; i < list->priv->nfd; i++) + close (list->priv->fds[i]); + g_free (list->priv->fds); + + G_OBJECT_CLASS (g_unix_fd_list_parent_class) + ->finalize (object); +} + +static void +g_unix_fd_list_class_init (GUnixFDListClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = g_unix_fd_list_finalize; +} + +static int +dup_close_on_exec_fd (gint fd, + GError **error) +{ + gint new_fd; + gint s; + +#ifdef F_DUPFD_CLOEXEC + do + new_fd = fcntl (fd, F_DUPFD_CLOEXEC, 0l); + while (new_fd < 0 && (errno == EINTR)); + + if (new_fd >= 0) + return new_fd; + + /* if that didn't work (new libc/old kernel?), try it the other way. */ +#endif + + do + new_fd = dup (fd); + while (new_fd < 0 && (errno == EINTR)); + + if (new_fd < 0) + { + int saved_errno = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (saved_errno), + "dup: %s", g_strerror (saved_errno)); + + return -1; + } + + do + { + s = fcntl (new_fd, F_GETFD); + + if (s >= 0) + s = fcntl (new_fd, F_SETFD, (long) (s | FD_CLOEXEC)); + } + while (s < 0 && (errno == EINTR)); + + if (s < 0) + { + int saved_errno = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (saved_errno), + "fcntl: %s", g_strerror (saved_errno)); + close (new_fd); + + return -1; + } + + return new_fd; +} + +/** + * g_unix_fd_list_new: + * + * Creates a new #GUnixFDList containing no file descriptors. + * + * Returns: a new #GUnixFDList + * + * Since: 2.24 + **/ +GUnixFDList * +g_unix_fd_list_new (void) +{ + return g_object_new (G_TYPE_UNIX_FD_LIST, NULL); +} + +/** + * g_unix_fd_list_new_from_array: + * @fds: (array length=n_fds): the initial list of file descriptors + * @n_fds: the length of #fds, or -1 + * + * Creates a new #GUnixFDList containing the file descriptors given in + * @fds. The file descriptors become the property of the new list and + * may no longer be used by the caller. The array itself is owned by + * the caller. + * + * Each file descriptor in the array should be set to close-on-exec. + * + * If @n_fds is -1 then @fds must be terminated with -1. + * + * Returns: a new #GUnixFDList + * + * Since: 2.24 + **/ +GUnixFDList * +g_unix_fd_list_new_from_array (const gint *fds, + gint n_fds) +{ + GUnixFDList *list; + + g_return_val_if_fail (fds != NULL || n_fds == 0, NULL); + + if (n_fds == -1) + for (n_fds = 0; fds[n_fds] != -1; n_fds++); + + list = g_object_new (G_TYPE_UNIX_FD_LIST, NULL); + list->priv->fds = g_new (gint, n_fds + 1); + list->priv->nfd = n_fds; + + if (n_fds > 0) + memcpy (list->priv->fds, fds, sizeof (gint) * n_fds); + list->priv->fds[n_fds] = -1; + + return list; +} + +/** + * g_unix_fd_list_steal_fds: + * @list: a #GUnixFDList + * @length: (out) (optional): pointer to the length of the returned + * array, or %NULL + * + * Returns the array of file descriptors that is contained in this + * object. + * + * After this call, the descriptors are no longer contained in + * @list. Further calls will return an empty list (unless more + * descriptors have been added). + * + * The return result of this function must be freed with g_free(). + * The caller is also responsible for closing all of the file + * descriptors. The file descriptors in the array are set to + * close-on-exec. + * + * If @length is non-%NULL then it is set to the number of file + * descriptors in the returned array. The returned array is also + * terminated with -1. + * + * This function never returns %NULL. In case there are no file + * descriptors contained in @list, an empty array is returned. + * + * Returns: (array length=length) (transfer full): an array of file + * descriptors + * + * Since: 2.24 + */ +gint * +g_unix_fd_list_steal_fds (GUnixFDList *list, + gint *length) +{ + gint *result; + + g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), NULL); + + /* will be true for fresh object or if we were just called */ + if (list->priv->fds == NULL) + { + list->priv->fds = g_new (gint, 1); + list->priv->fds[0] = -1; + list->priv->nfd = 0; + } + + if (length) + *length = list->priv->nfd; + result = list->priv->fds; + + list->priv->fds = NULL; + list->priv->nfd = 0; + + return result; +} + +/** + * g_unix_fd_list_peek_fds: + * @list: a #GUnixFDList + * @length: (out) (optional): pointer to the length of the returned + * array, or %NULL + * + * Returns the array of file descriptors that is contained in this + * object. + * + * After this call, the descriptors remain the property of @list. The + * caller must not close them and must not free the array. The array is + * valid only until @list is changed in any way. + * + * If @length is non-%NULL then it is set to the number of file + * descriptors in the returned array. The returned array is also + * terminated with -1. + * + * This function never returns %NULL. In case there are no file + * descriptors contained in @list, an empty array is returned. + * + * Returns: (array length=length) (transfer none): an array of file + * descriptors + * + * Since: 2.24 + */ +const gint * +g_unix_fd_list_peek_fds (GUnixFDList *list, + gint *length) +{ + g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), NULL); + + /* will be true for fresh object or if steal() was just called */ + if (list->priv->fds == NULL) + { + list->priv->fds = g_new (gint, 1); + list->priv->fds[0] = -1; + list->priv->nfd = 0; + } + + if (length) + *length = list->priv->nfd; + + return list->priv->fds; +} + +/** + * g_unix_fd_list_append: + * @list: a #GUnixFDList + * @fd: a valid open file descriptor + * @error: a #GError pointer + * + * Adds a file descriptor to @list. + * + * The file descriptor is duplicated using dup(). You keep your copy + * of the descriptor and the copy contained in @list will be closed + * when @list is finalized. + * + * A possible cause of failure is exceeding the per-process or + * system-wide file descriptor limit. + * + * The index of the file descriptor in the list is returned. If you use + * this index with g_unix_fd_list_get() then you will receive back a + * duplicated copy of the same file descriptor. + * + * Returns: the index of the appended fd in case of success, else -1 + * (and @error is set) + * + * Since: 2.24 + */ +gint +g_unix_fd_list_append (GUnixFDList *list, + gint fd, + GError **error) +{ + gint new_fd; + + g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), -1); + g_return_val_if_fail (fd >= 0, -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + if ((new_fd = dup_close_on_exec_fd (fd, error)) < 0) + return -1; + + list->priv->fds = g_realloc (list->priv->fds, + sizeof (gint) * + (list->priv->nfd + 2)); + list->priv->fds[list->priv->nfd++] = new_fd; + list->priv->fds[list->priv->nfd] = -1; + + return list->priv->nfd - 1; +} + +/** + * g_unix_fd_list_get: + * @list: a #GUnixFDList + * @index_: the index into the list + * @error: a #GError pointer + * + * Gets a file descriptor out of @list. + * + * @index_ specifies the index of the file descriptor to get. It is a + * programmer error for @index_ to be out of range; see + * g_unix_fd_list_get_length(). + * + * The file descriptor is duplicated using dup() and set as + * close-on-exec before being returned. You must call close() on it + * when you are done. + * + * A possible cause of failure is exceeding the per-process or + * system-wide file descriptor limit. + * + * Returns: the file descriptor, or -1 in case of error + * + * Since: 2.24 + **/ +gint +g_unix_fd_list_get (GUnixFDList *list, + gint index_, + GError **error) +{ + g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), -1); + g_return_val_if_fail (index_ < list->priv->nfd, -1); + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + return dup_close_on_exec_fd (list->priv->fds[index_], error); +} + +/** + * g_unix_fd_list_get_length: + * @list: a #GUnixFDList + * + * Gets the length of @list (ie: the number of file descriptors + * contained within). + * + * Returns: the length of @list + * + * Since: 2.24 + **/ +gint +g_unix_fd_list_get_length (GUnixFDList *list) +{ + g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), 0); + + return list->priv->nfd; +} diff --git a/gio/gunixfdlist.h b/gio/gunixfdlist.h new file mode 100644 index 0000000..9d3204a --- /dev/null +++ b/gio/gunixfdlist.h @@ -0,0 +1,95 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_UNIX_FD_LIST_H__ +#define __G_UNIX_FD_LIST_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_FD_LIST (g_unix_fd_list_get_type ()) +#define G_UNIX_FD_LIST(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_UNIX_FD_LIST, GUnixFDList)) +#define G_UNIX_FD_LIST_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_UNIX_FD_LIST, GUnixFDListClass)) +#define G_IS_UNIX_FD_LIST(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_UNIX_FD_LIST)) +#define G_IS_UNIX_FD_LIST_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_UNIX_FD_LIST)) +#define G_UNIX_FD_LIST_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_UNIX_FD_LIST, GUnixFDListClass)) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixFDList, g_object_unref) + +typedef struct _GUnixFDListPrivate GUnixFDListPrivate; +typedef struct _GUnixFDListClass GUnixFDListClass; + +struct _GUnixFDListClass +{ + GObjectClass parent_class; + + /*< private >*/ + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +struct _GUnixFDList +{ + GObject parent_instance; + GUnixFDListPrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_unix_fd_list_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GUnixFDList * g_unix_fd_list_new (void); +GLIB_AVAILABLE_IN_ALL +GUnixFDList * g_unix_fd_list_new_from_array (const gint *fds, + gint n_fds); + +GLIB_AVAILABLE_IN_ALL +gint g_unix_fd_list_append (GUnixFDList *list, + gint fd, + GError **error); + +GLIB_AVAILABLE_IN_ALL +gint g_unix_fd_list_get_length (GUnixFDList *list); + +GLIB_AVAILABLE_IN_ALL +gint g_unix_fd_list_get (GUnixFDList *list, + gint index_, + GError **error); + +GLIB_AVAILABLE_IN_ALL +const gint * g_unix_fd_list_peek_fds (GUnixFDList *list, + gint *length); + +GLIB_AVAILABLE_IN_ALL +gint * g_unix_fd_list_steal_fds (GUnixFDList *list, + gint *length); + +G_END_DECLS + +#endif /* __G_UNIX_FD_LIST_H__ */ diff --git a/gio/gunixfdmessage.c b/gio/gunixfdmessage.c new file mode 100644 index 0000000..3324651 --- /dev/null +++ b/gio/gunixfdmessage.c @@ -0,0 +1,331 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Authors: Ryan Lortie + */ + +/** + * SECTION:gunixfdmessage + * @title: GUnixFDMessage + * @short_description: A GSocketControlMessage containing a GUnixFDList + * @include: gio/gunixfdmessage.h + * @see_also: #GUnixConnection, #GUnixFDList, #GSocketControlMessage + * + * This #GSocketControlMessage contains a #GUnixFDList. + * It may be sent using g_socket_send_message() and received using + * g_socket_receive_message() over UNIX sockets (ie: sockets in the + * %G_SOCKET_FAMILY_UNIX family). The file descriptors are copied + * between processes by the kernel. + * + * For an easier way to send and receive file descriptors over + * stream-oriented UNIX sockets, see g_unix_connection_send_fd() and + * g_unix_connection_receive_fd(). + * + * Note that `` belongs to the UNIX-specific GIO + * interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config + * file when using it. + */ + +/** + * GUnixFDMessage: + * + * #GUnixFDMessage is an opaque data structure and can only be accessed + * using the following functions. + **/ + +#include "config.h" + +#include +#include +#include +#include + +#include "gunixfdmessage.h" +#include "gunixfdlist.h" +#include "gnetworking.h" +#include "gioerror.h" + +struct _GUnixFDMessagePrivate +{ + GUnixFDList *list; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GUnixFDMessage, g_unix_fd_message, G_TYPE_SOCKET_CONTROL_MESSAGE) + +static gsize +g_unix_fd_message_get_size (GSocketControlMessage *message) +{ + GUnixFDMessage *fd_message = G_UNIX_FD_MESSAGE (message); + + return g_unix_fd_list_get_length (fd_message->priv->list) * sizeof (gint); +} + +static int +g_unix_fd_message_get_level (GSocketControlMessage *message) +{ + return SOL_SOCKET; +} + +static int +g_unix_fd_message_get_msg_type (GSocketControlMessage *message) +{ + return SCM_RIGHTS; +} + +static GSocketControlMessage * +g_unix_fd_message_deserialize (int level, + int type, + gsize size, + gpointer data) +{ + GSocketControlMessage *message; + GUnixFDList *list; + gint n, s, i; + gint *fds; + + if (level != SOL_SOCKET || + type != SCM_RIGHTS) + return NULL; + + if (size % 4 > 0) + { + g_warning ("Kernel returned non-integral number of fds"); + return NULL; + } + + fds = data; + n = size / sizeof (gint); + + /* Note we probably handled this in gsocket.c already if we're on + * Linux and have MSG_CMSG_CLOEXEC, but this code remains as a fallback + * in case the kernel is too old for MSG_CMSG_CLOEXEC. + */ + for (i = 0; i < n; i++) + { + int errsv; + + do + { + s = fcntl (fds[i], F_SETFD, FD_CLOEXEC); + errsv = errno; + } + while (s < 0 && errsv == EINTR); + + if (s < 0) + { + g_warning ("Error setting close-on-exec flag on incoming fd: %s", + g_strerror (errsv)); + return NULL; + } + } + + list = g_unix_fd_list_new_from_array (fds, n); + message = g_unix_fd_message_new_with_fd_list (list); + g_object_unref (list); + + return message; +} + +static void +g_unix_fd_message_serialize (GSocketControlMessage *message, + gpointer data) +{ + GUnixFDMessage *fd_message = G_UNIX_FD_MESSAGE (message); + const gint *fds; + gint n_fds; + + fds = g_unix_fd_list_peek_fds (fd_message->priv->list, &n_fds); + memcpy (data, fds, sizeof (gint) * n_fds); +} + +static void +g_unix_fd_message_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + GUnixFDMessage *message = G_UNIX_FD_MESSAGE (object); + + g_assert (message->priv->list == NULL); + g_assert_cmpint (prop_id, ==, 1); + + message->priv->list = g_value_dup_object (value); + + if (message->priv->list == NULL) + message->priv->list = g_unix_fd_list_new (); +} + +/** + * g_unix_fd_message_get_fd_list: + * @message: a #GUnixFDMessage + * + * Gets the #GUnixFDList contained in @message. This function does not + * return a reference to the caller, but the returned list is valid for + * the lifetime of @message. + * + * Returns: (transfer none): the #GUnixFDList from @message + * + * Since: 2.24 + **/ +GUnixFDList * +g_unix_fd_message_get_fd_list (GUnixFDMessage *message) +{ + return message->priv->list; +} + +static void +g_unix_fd_message_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GUnixFDMessage *message = G_UNIX_FD_MESSAGE (object); + + g_assert_cmpint (prop_id, ==, 1); + + g_value_set_object (value, g_unix_fd_message_get_fd_list (message)); +} + +static void +g_unix_fd_message_init (GUnixFDMessage *message) +{ + message->priv = g_unix_fd_message_get_instance_private (message); +} + +static void +g_unix_fd_message_finalize (GObject *object) +{ + GUnixFDMessage *message = G_UNIX_FD_MESSAGE (object); + + g_object_unref (message->priv->list); + + G_OBJECT_CLASS (g_unix_fd_message_parent_class) + ->finalize (object); +} + +static void +g_unix_fd_message_class_init (GUnixFDMessageClass *class) +{ + GSocketControlMessageClass *scm_class = G_SOCKET_CONTROL_MESSAGE_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (class); + + scm_class->get_size = g_unix_fd_message_get_size; + scm_class->get_level = g_unix_fd_message_get_level; + scm_class->get_type = g_unix_fd_message_get_msg_type; + scm_class->serialize = g_unix_fd_message_serialize; + scm_class->deserialize = g_unix_fd_message_deserialize; + object_class->finalize = g_unix_fd_message_finalize; + object_class->set_property = g_unix_fd_message_set_property; + object_class->get_property = g_unix_fd_message_get_property; + + g_object_class_install_property (object_class, 1, + g_param_spec_object ("fd-list", "file descriptor list", + "The GUnixFDList object to send with the message", + G_TYPE_UNIX_FD_LIST, G_PARAM_STATIC_STRINGS | + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + +/** + * g_unix_fd_message_new: + * + * Creates a new #GUnixFDMessage containing an empty file descriptor + * list. + * + * Returns: a new #GUnixFDMessage + * + * Since: 2.22 + **/ +GSocketControlMessage * +g_unix_fd_message_new (void) +{ + return g_object_new (G_TYPE_UNIX_FD_MESSAGE, NULL); +} + +/** + * g_unix_fd_message_new_with_fd_list: + * @fd_list: a #GUnixFDList + * + * Creates a new #GUnixFDMessage containing @list. + * + * Returns: a new #GUnixFDMessage + * + * Since: 2.24 + **/ +GSocketControlMessage * +g_unix_fd_message_new_with_fd_list (GUnixFDList *fd_list) +{ + return g_object_new (G_TYPE_UNIX_FD_MESSAGE, + "fd-list", fd_list, + NULL); +} + +/** + * g_unix_fd_message_steal_fds: + * @message: a #GUnixFDMessage + * @length: (out) (optional): pointer to the length of the returned + * array, or %NULL + * + * Returns the array of file descriptors that is contained in this + * object. + * + * After this call, the descriptors are no longer contained in + * @message. Further calls will return an empty list (unless more + * descriptors have been added). + * + * The return result of this function must be freed with g_free(). + * The caller is also responsible for closing all of the file + * descriptors. + * + * If @length is non-%NULL then it is set to the number of file + * descriptors in the returned array. The returned array is also + * terminated with -1. + * + * This function never returns %NULL. In case there are no file + * descriptors contained in @message, an empty array is returned. + * + * Returns: (array length=length) (transfer full): an array of file + * descriptors + * + * Since: 2.22 + **/ +gint * +g_unix_fd_message_steal_fds (GUnixFDMessage *message, + gint *length) +{ + g_return_val_if_fail (G_UNIX_FD_MESSAGE (message), NULL); + + return g_unix_fd_list_steal_fds (message->priv->list, length); +} + +/** + * g_unix_fd_message_append_fd: + * @message: a #GUnixFDMessage + * @fd: a valid open file descriptor + * @error: a #GError pointer + * + * Adds a file descriptor to @message. + * + * The file descriptor is duplicated using dup(). You keep your copy + * of the descriptor and the copy contained in @message will be closed + * when @message is finalized. + * + * A possible cause of failure is exceeding the per-process or + * system-wide file descriptor limit. + * + * Returns: %TRUE in case of success, else %FALSE (and @error is set) + * + * Since: 2.22 + **/ +gboolean +g_unix_fd_message_append_fd (GUnixFDMessage *message, + gint fd, + GError **error) +{ + g_return_val_if_fail (G_UNIX_FD_MESSAGE (message), FALSE); + + return g_unix_fd_list_append (message->priv->list, fd, error) >= 0; +} diff --git a/gio/gunixfdmessage.h b/gio/gunixfdmessage.h new file mode 100644 index 0000000..c766e2a --- /dev/null +++ b/gio/gunixfdmessage.h @@ -0,0 +1,84 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#ifndef __G_UNIX_FD_MESSAGE_H__ +#define __G_UNIX_FD_MESSAGE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_FD_MESSAGE (g_unix_fd_message_get_type ()) +#define G_UNIX_FD_MESSAGE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_UNIX_FD_MESSAGE, GUnixFDMessage)) +#define G_UNIX_FD_MESSAGE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + G_TYPE_UNIX_FD_MESSAGE, GUnixFDMessageClass)) +#define G_IS_UNIX_FD_MESSAGE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ + G_TYPE_UNIX_FD_MESSAGE)) +#define G_IS_UNIX_FD_MESSAGE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + G_TYPE_UNIX_FD_MESSAGE)) +#define G_UNIX_FD_MESSAGE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \ + G_TYPE_UNIX_FD_MESSAGE, GUnixFDMessageClass)) + +typedef struct _GUnixFDMessagePrivate GUnixFDMessagePrivate; +typedef struct _GUnixFDMessageClass GUnixFDMessageClass; +typedef struct _GUnixFDMessage GUnixFDMessage; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixFDMessage, g_object_unref) + +struct _GUnixFDMessageClass +{ + GSocketControlMessageClass parent_class; + + /*< private >*/ + + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); +}; + +struct _GUnixFDMessage +{ + GSocketControlMessage parent_instance; + GUnixFDMessagePrivate *priv; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_unix_fd_message_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GSocketControlMessage * g_unix_fd_message_new_with_fd_list (GUnixFDList *fd_list); +GLIB_AVAILABLE_IN_ALL +GSocketControlMessage * g_unix_fd_message_new (void); + +GLIB_AVAILABLE_IN_ALL +GUnixFDList * g_unix_fd_message_get_fd_list (GUnixFDMessage *message); + +GLIB_AVAILABLE_IN_ALL +gint * g_unix_fd_message_steal_fds (GUnixFDMessage *message, + gint *length); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_fd_message_append_fd (GUnixFDMessage *message, + gint fd, + GError **error); + +G_END_DECLS + +#endif /* __G_UNIX_FD_MESSAGE_H__ */ diff --git a/gio/gunixinputstream.c b/gio/gunixinputstream.c new file mode 100644 index 0000000..8c2ce62 --- /dev/null +++ b/gio/gunixinputstream.c @@ -0,0 +1,487 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include "gioerror.h" +#include "gunixinputstream.h" +#include "gcancellable.h" +#include "gasynchelper.h" +#include "gfiledescriptorbased.h" +#include "glibintl.h" +#include "giounix-private.h" + + +/** + * SECTION:gunixinputstream + * @short_description: Streaming input operations for UNIX file descriptors + * @include: gio/gunixinputstream.h + * @see_also: #GInputStream + * + * #GUnixInputStream implements #GInputStream for reading from a UNIX + * file descriptor, including asynchronous operations. (If the file + * descriptor refers to a socket or pipe, this will use poll() to do + * asynchronous I/O. If it refers to a regular file, it will fall back + * to doing asynchronous I/O in another thread.) + * + * Note that `` belongs to the UNIX-specific GIO + * interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config + * file when using it. + */ + +enum { + PROP_0, + PROP_FD, + PROP_CLOSE_FD +}; + +struct _GUnixInputStreamPrivate { + int fd; + guint close_fd : 1; + guint can_poll : 1; +}; + +static void g_unix_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface); +static void g_unix_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GUnixInputStream, g_unix_input_stream, G_TYPE_INPUT_STREAM, + G_ADD_PRIVATE (GUnixInputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, + g_unix_input_stream_pollable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, + g_unix_input_stream_file_descriptor_based_iface_init) + ) + +static void g_unix_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_unix_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static gssize g_unix_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_unix_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error); +static void g_unix_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data); +static gssize g_unix_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); + +static gboolean g_unix_input_stream_pollable_can_poll (GPollableInputStream *stream); +static gboolean g_unix_input_stream_pollable_is_readable (GPollableInputStream *stream); +static GSource *g_unix_input_stream_pollable_create_source (GPollableInputStream *stream, + GCancellable *cancellable); + +static void +g_unix_input_stream_class_init (GUnixInputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass); + + gobject_class->get_property = g_unix_input_stream_get_property; + gobject_class->set_property = g_unix_input_stream_set_property; + + stream_class->read_fn = g_unix_input_stream_read; + stream_class->close_fn = g_unix_input_stream_close; + if (0) + { + /* TODO: Implement instead of using fallbacks */ + stream_class->skip_async = g_unix_input_stream_skip_async; + stream_class->skip_finish = g_unix_input_stream_skip_finish; + } + + /** + * GUnixInputStream:fd: + * + * The file descriptor that the stream reads from. + * + * Since: 2.20 + */ + g_object_class_install_property (gobject_class, + PROP_FD, + g_param_spec_int ("fd", + P_("File descriptor"), + P_("The file descriptor to read from"), + G_MININT, G_MAXINT, -1, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + /** + * GUnixInputStream:close-fd: + * + * Whether to close the file descriptor when the stream is closed. + * + * Since: 2.20 + */ + g_object_class_install_property (gobject_class, + PROP_CLOSE_FD, + g_param_spec_boolean ("close-fd", + P_("Close file descriptor"), + P_("Whether to close the file descriptor when the stream is closed"), + TRUE, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); +} + +static void +g_unix_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface) +{ + iface->can_poll = g_unix_input_stream_pollable_can_poll; + iface->is_readable = g_unix_input_stream_pollable_is_readable; + iface->create_source = g_unix_input_stream_pollable_create_source; +} + +static void +g_unix_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface) +{ + iface->get_fd = (int (*) (GFileDescriptorBased *))g_unix_input_stream_get_fd; +} + +static void +g_unix_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GUnixInputStream *unix_stream; + + unix_stream = G_UNIX_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_FD: + unix_stream->priv->fd = g_value_get_int (value); + unix_stream->priv->can_poll = _g_fd_is_pollable (unix_stream->priv->fd); + break; + case PROP_CLOSE_FD: + unix_stream->priv->close_fd = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_unix_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GUnixInputStream *unix_stream; + + unix_stream = G_UNIX_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_FD: + g_value_set_int (value, unix_stream->priv->fd); + break; + case PROP_CLOSE_FD: + g_value_set_boolean (value, unix_stream->priv->close_fd); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_unix_input_stream_init (GUnixInputStream *unix_stream) +{ + unix_stream->priv = g_unix_input_stream_get_instance_private (unix_stream); + unix_stream->priv->fd = -1; + unix_stream->priv->close_fd = TRUE; +} + +/** + * g_unix_input_stream_new: + * @fd: a UNIX file descriptor + * @close_fd: %TRUE to close the file descriptor when done + * + * Creates a new #GUnixInputStream for the given @fd. + * + * If @close_fd is %TRUE, the file descriptor will be closed + * when the stream is closed. + * + * Returns: a new #GUnixInputStream + **/ +GInputStream * +g_unix_input_stream_new (gint fd, + gboolean close_fd) +{ + GUnixInputStream *stream; + + g_return_val_if_fail (fd != -1, NULL); + + stream = g_object_new (G_TYPE_UNIX_INPUT_STREAM, + "fd", fd, + "close-fd", close_fd, + NULL); + + return G_INPUT_STREAM (stream); +} + +/** + * g_unix_input_stream_set_close_fd: + * @stream: a #GUnixInputStream + * @close_fd: %TRUE to close the file descriptor when done + * + * Sets whether the file descriptor of @stream shall be closed + * when the stream is closed. + * + * Since: 2.20 + */ +void +g_unix_input_stream_set_close_fd (GUnixInputStream *stream, + gboolean close_fd) +{ + g_return_if_fail (G_IS_UNIX_INPUT_STREAM (stream)); + + close_fd = close_fd != FALSE; + if (stream->priv->close_fd != close_fd) + { + stream->priv->close_fd = close_fd; + g_object_notify (G_OBJECT (stream), "close-fd"); + } +} + +/** + * g_unix_input_stream_get_close_fd: + * @stream: a #GUnixInputStream + * + * Returns whether the file descriptor of @stream will be + * closed when the stream is closed. + * + * Returns: %TRUE if the file descriptor is closed when done + * + * Since: 2.20 + */ +gboolean +g_unix_input_stream_get_close_fd (GUnixInputStream *stream) +{ + g_return_val_if_fail (G_IS_UNIX_INPUT_STREAM (stream), FALSE); + + return stream->priv->close_fd; +} + +/** + * g_unix_input_stream_get_fd: + * @stream: a #GUnixInputStream + * + * Return the UNIX file descriptor that the stream reads from. + * + * Returns: The file descriptor of @stream + * + * Since: 2.20 + */ +gint +g_unix_input_stream_get_fd (GUnixInputStream *stream) +{ + g_return_val_if_fail (G_IS_UNIX_INPUT_STREAM (stream), -1); + + return stream->priv->fd; +} + +static gssize +g_unix_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GUnixInputStream *unix_stream; + gssize res = -1; + GPollFD poll_fds[2]; + int nfds; + int poll_ret; + + unix_stream = G_UNIX_INPUT_STREAM (stream); + + poll_fds[0].fd = unix_stream->priv->fd; + poll_fds[0].events = G_IO_IN; + if (unix_stream->priv->can_poll && + g_cancellable_make_pollfd (cancellable, &poll_fds[1])) + nfds = 2; + else + nfds = 1; + + while (1) + { + int errsv; + + poll_fds[0].revents = poll_fds[1].revents = 0; + do + { + poll_ret = g_poll (poll_fds, nfds, -1); + errsv = errno; + } + while (poll_ret == -1 && errsv == EINTR); + + if (poll_ret == -1) + { + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error reading from file descriptor: %s"), + g_strerror (errsv)); + break; + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + break; + + if (!poll_fds[0].revents) + continue; + + res = read (unix_stream->priv->fd, buffer, count); + if (res == -1) + { + int errsv = errno; + + if (errsv == EINTR || errsv == EAGAIN) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error reading from file descriptor: %s"), + g_strerror (errsv)); + } + + break; + } + + if (nfds == 2) + g_cancellable_release_fd (cancellable); + return res; +} + +static gboolean +g_unix_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GUnixInputStream *unix_stream; + int res; + + unix_stream = G_UNIX_INPUT_STREAM (stream); + + if (!unix_stream->priv->close_fd) + return TRUE; + + /* This might block during the close. Doesn't seem to be a way to avoid it though. */ + res = close (unix_stream->priv->fd); + if (res == -1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error closing file descriptor: %s"), + g_strerror (errsv)); + } + + return res != -1; +} + +static void +g_unix_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer data) +{ + g_warn_if_reached (); + /* TODO: Not implemented */ +} + +static gssize +g_unix_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_warn_if_reached (); + return 0; + /* TODO: Not implemented */ +} + +static gboolean +g_unix_input_stream_pollable_can_poll (GPollableInputStream *stream) +{ + return G_UNIX_INPUT_STREAM (stream)->priv->can_poll; +} + +static gboolean +g_unix_input_stream_pollable_is_readable (GPollableInputStream *stream) +{ + GUnixInputStream *unix_stream = G_UNIX_INPUT_STREAM (stream); + GPollFD poll_fd; + gint result; + + poll_fd.fd = unix_stream->priv->fd; + poll_fd.events = G_IO_IN; + poll_fd.revents = 0; + + do + result = g_poll (&poll_fd, 1, 0); + while (result == -1 && errno == EINTR); + + return poll_fd.revents != 0; +} + +static GSource * +g_unix_input_stream_pollable_create_source (GPollableInputStream *stream, + GCancellable *cancellable) +{ + GUnixInputStream *unix_stream = G_UNIX_INPUT_STREAM (stream); + GSource *inner_source, *cancellable_source, *pollable_source; + + pollable_source = g_pollable_source_new (G_OBJECT (stream)); + + inner_source = g_unix_fd_source_new (unix_stream->priv->fd, G_IO_IN); + g_source_set_dummy_callback (inner_source); + g_source_add_child_source (pollable_source, inner_source); + g_source_unref (inner_source); + + if (cancellable) + { + cancellable_source = g_cancellable_source_new (cancellable); + g_source_set_dummy_callback (cancellable_source); + g_source_add_child_source (pollable_source, cancellable_source); + g_source_unref (cancellable_source); + } + + return pollable_source; +} diff --git a/gio/gunixinputstream.h b/gio/gunixinputstream.h new file mode 100644 index 0000000..1fba553 --- /dev/null +++ b/gio/gunixinputstream.h @@ -0,0 +1,83 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_UNIX_INPUT_STREAM_H__ +#define __G_UNIX_INPUT_STREAM_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_INPUT_STREAM (g_unix_input_stream_get_type ()) +#define G_UNIX_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_INPUT_STREAM, GUnixInputStream)) +#define G_UNIX_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_INPUT_STREAM, GUnixInputStreamClass)) +#define G_IS_UNIX_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_INPUT_STREAM)) +#define G_IS_UNIX_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_INPUT_STREAM)) +#define G_UNIX_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_UNIX_INPUT_STREAM, GUnixInputStreamClass)) + +/** + * GUnixInputStream: + * + * Implements #GInputStream for reading from selectable unix file descriptors + **/ +typedef struct _GUnixInputStream GUnixInputStream; +typedef struct _GUnixInputStreamClass GUnixInputStreamClass; +typedef struct _GUnixInputStreamPrivate GUnixInputStreamPrivate; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixInputStream, g_object_unref) + +struct _GUnixInputStream +{ + GInputStream parent_instance; + + /*< private >*/ + GUnixInputStreamPrivate *priv; +}; + +struct _GUnixInputStreamClass +{ + GInputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_unix_input_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GInputStream * g_unix_input_stream_new (gint fd, + gboolean close_fd); +GLIB_AVAILABLE_IN_ALL +void g_unix_input_stream_set_close_fd (GUnixInputStream *stream, + gboolean close_fd); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_input_stream_get_close_fd (GUnixInputStream *stream); +GLIB_AVAILABLE_IN_ALL +gint g_unix_input_stream_get_fd (GUnixInputStream *stream); + +G_END_DECLS + +#endif /* __G_UNIX_INPUT_STREAM_H__ */ diff --git a/gio/gunixmount.c b/gio/gunixmount.c new file mode 100644 index 0000000..acfebff --- /dev/null +++ b/gio/gunixmount.c @@ -0,0 +1,395 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#include "config.h" + +#include +#include +#include + +#include +#include "gsubprocess.h" +#include "gioenums.h" +#include "gunixvolumemonitor.h" +#include "gunixmount.h" +#include "gunixmounts.h" +#include "gunixvolume.h" +#include "gmountprivate.h" +#include "gmount.h" +#include "gfile.h" +#include "gvolumemonitor.h" +#include "gthemedicon.h" +#include "gioerror.h" +#include "glibintl.h" +/* for BUFSIZ */ +#include + + +struct _GUnixMount { + GObject parent; + + GVolumeMonitor *volume_monitor; + + GUnixVolume *volume; /* owned by volume monitor */ + + char *name; + GIcon *icon; + GIcon *symbolic_icon; + char *device_path; + char *mount_path; + + gboolean can_eject; +}; + +static void g_unix_mount_mount_iface_init (GMountIface *iface); + +#define g_unix_mount_get_type _g_unix_mount_get_type +G_DEFINE_TYPE_WITH_CODE (GUnixMount, g_unix_mount, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT, + g_unix_mount_mount_iface_init)) + + +static void +g_unix_mount_finalize (GObject *object) +{ + GUnixMount *mount; + + mount = G_UNIX_MOUNT (object); + + if (mount->volume_monitor != NULL) + g_object_unref (mount->volume_monitor); + + if (mount->volume) + _g_unix_volume_unset_mount (mount->volume, mount); + + /* TODO: g_warn_if_fail (volume->volume == NULL); */ + g_object_unref (mount->icon); + g_object_unref (mount->symbolic_icon); + g_free (mount->name); + g_free (mount->device_path); + g_free (mount->mount_path); + + G_OBJECT_CLASS (g_unix_mount_parent_class)->finalize (object); +} + +static void +g_unix_mount_class_init (GUnixMountClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_unix_mount_finalize; +} + +static void +g_unix_mount_init (GUnixMount *unix_mount) +{ +} + +GUnixMount * +_g_unix_mount_new (GVolumeMonitor *volume_monitor, + GUnixMountEntry *mount_entry, + GUnixVolume *volume) +{ + GUnixMount *mount; + + /* No volume for mount: Ignore internal things */ + if (volume == NULL && !g_unix_mount_guess_should_display (mount_entry)) + return NULL; + + mount = g_object_new (G_TYPE_UNIX_MOUNT, NULL); + mount->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL; + mount->device_path = g_strdup (g_unix_mount_get_device_path (mount_entry)); + mount->mount_path = g_strdup (g_unix_mount_get_mount_path (mount_entry)); + mount->can_eject = g_unix_mount_guess_can_eject (mount_entry); + + mount->name = g_unix_mount_guess_name (mount_entry); + mount->icon = g_unix_mount_guess_icon (mount_entry); + mount->symbolic_icon = g_unix_mount_guess_symbolic_icon (mount_entry); + + /* need to do this last */ + mount->volume = volume; + if (volume != NULL) + _g_unix_volume_set_mount (volume, mount); + + return mount; +} + +void +_g_unix_mount_unmounted (GUnixMount *mount) +{ + if (mount->volume != NULL) + { + _g_unix_volume_unset_mount (mount->volume, mount); + mount->volume = NULL; + g_signal_emit_by_name (mount, "changed"); + /* there's really no need to emit mount_changed on the volume monitor + * as we're going to be deleted.. */ + } +} + +void +_g_unix_mount_unset_volume (GUnixMount *mount, + GUnixVolume *volume) +{ + if (mount->volume == volume) + { + mount->volume = NULL; + /* TODO: Emit changed in idle to avoid locking issues */ + g_signal_emit_by_name (mount, "changed"); + if (mount->volume_monitor != NULL) + g_signal_emit_by_name (mount->volume_monitor, "mount-changed", mount); + } +} + +static GFile * +g_unix_mount_get_root (GMount *mount) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + + return g_file_new_for_path (unix_mount->mount_path); +} + +static GIcon * +g_unix_mount_get_icon (GMount *mount) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + + return g_object_ref (unix_mount->icon); +} + +static GIcon * +g_unix_mount_get_symbolic_icon (GMount *mount) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + + return g_object_ref (unix_mount->symbolic_icon); +} + +static char * +g_unix_mount_get_uuid (GMount *mount) +{ + return NULL; +} + +static char * +g_unix_mount_get_name (GMount *mount) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + + return g_strdup (unix_mount->name); +} + +gboolean +_g_unix_mount_has_mount_path (GUnixMount *mount, + const char *mount_path) +{ + return strcmp (mount->mount_path, mount_path) == 0; +} + +static GDrive * +g_unix_mount_get_drive (GMount *mount) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + + if (unix_mount->volume != NULL) + return g_volume_get_drive (G_VOLUME (unix_mount->volume)); + + return NULL; +} + +static GVolume * +g_unix_mount_get_volume (GMount *mount) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + + if (unix_mount->volume) + return G_VOLUME (g_object_ref (unix_mount->volume)); + + return NULL; +} + +static gboolean +g_unix_mount_can_unmount (GMount *mount) +{ + return TRUE; +} + +static gboolean +g_unix_mount_can_eject (GMount *mount) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + return unix_mount->can_eject; +} + +static void +eject_unmount_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSubprocess *subprocess = G_SUBPROCESS (source); + GTask *task = user_data; + GError *error = NULL; + gchar *stderr_str; + + if (!g_subprocess_communicate_utf8_finish (subprocess, result, NULL, &stderr_str, &error)) + { + g_task_return_error (task, error); + g_error_free (error); + } + else /* successful communication */ + { + if (!g_subprocess_get_successful (subprocess)) + /* ...but bad exit code */ + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", stderr_str); + else + /* ...and successful exit code */ + g_task_return_boolean (task, TRUE); + + g_free (stderr_str); + } + + g_object_unref (task); +} + +static gboolean +eject_unmount_do_cb (gpointer user_data) +{ + GTask *task = user_data; + GError *error = NULL; + GSubprocess *subprocess; + const gchar **argv; + + argv = g_task_get_task_data (task); + + if (g_task_return_error_if_cancelled (task)) + { + g_object_unref (task); + return G_SOURCE_REMOVE; + } + + subprocess = g_subprocess_newv (argv, G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_PIPE, &error); + g_assert_no_error (error); + + g_subprocess_communicate_utf8_async (subprocess, NULL, + g_task_get_cancellable (task), + eject_unmount_done, task); + + return G_SOURCE_REMOVE; +} + +static void +eject_unmount_do (GMount *mount, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + char **argv, + const gchar *task_name) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + GTask *task; + GSource *timeout; + + task = g_task_new (mount, cancellable, callback, user_data); + g_task_set_source_tag (task, eject_unmount_do); + g_task_set_name (task, task_name); + g_task_set_task_data (task, g_strdupv (argv), (GDestroyNotify) g_strfreev); + + if (unix_mount->volume_monitor != NULL) + g_signal_emit_by_name (unix_mount->volume_monitor, "mount-pre-unmount", mount); + + g_signal_emit_by_name (mount, "pre-unmount", 0); + + timeout = g_timeout_source_new (500); + g_task_attach_source (task, timeout, (GSourceFunc) eject_unmount_do_cb); + g_source_unref (timeout); +} + +static void +g_unix_mount_unmount (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + char *argv[] = {"umount", NULL, NULL}; + + if (unix_mount->mount_path != NULL) + argv[1] = unix_mount->mount_path; + else + argv[1] = unix_mount->device_path; + + eject_unmount_do (mount, cancellable, callback, user_data, argv, "[gio] unmount mount"); +} + +static gboolean +g_unix_mount_unmount_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +g_unix_mount_eject (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GUnixMount *unix_mount = G_UNIX_MOUNT (mount); + char *argv[] = {"eject", NULL, NULL}; + + if (unix_mount->mount_path != NULL) + argv[1] = unix_mount->mount_path; + else + argv[1] = unix_mount->device_path; + + eject_unmount_do (mount, cancellable, callback, user_data, argv, "[gio] eject mount"); +} + +static gboolean +g_unix_mount_eject_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +g_unix_mount_mount_iface_init (GMountIface *iface) +{ + iface->get_root = g_unix_mount_get_root; + iface->get_name = g_unix_mount_get_name; + iface->get_icon = g_unix_mount_get_icon; + iface->get_symbolic_icon = g_unix_mount_get_symbolic_icon; + iface->get_uuid = g_unix_mount_get_uuid; + iface->get_drive = g_unix_mount_get_drive; + iface->get_volume = g_unix_mount_get_volume; + iface->can_unmount = g_unix_mount_can_unmount; + iface->can_eject = g_unix_mount_can_eject; + iface->unmount = g_unix_mount_unmount; + iface->unmount_finish = g_unix_mount_unmount_finish; + iface->eject = g_unix_mount_eject; + iface->eject_finish = g_unix_mount_eject_finish; +} diff --git a/gio/gunixmount.h b/gio/gunixmount.h new file mode 100644 index 0000000..9faaf64 --- /dev/null +++ b/gio/gunixmount.h @@ -0,0 +1,58 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#ifndef __G_UNIX_MOUNT_H__ +#define __G_UNIX_MOUNT_H__ + +#include + +#include "gunixmounts.h" + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_MOUNT (_g_unix_mount_get_type ()) +#define G_UNIX_MOUNT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_MOUNT, GUnixMount)) +#define G_UNIX_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_MOUNT, GUnixMountClass)) +#define G_IS_UNIX_MOUNT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_MOUNT)) +#define G_IS_UNIX_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_MOUNT)) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixMount, g_object_unref) + +typedef struct _GUnixMountClass GUnixMountClass; + +struct _GUnixMountClass +{ + GObjectClass parent_class; +}; + +GType _g_unix_mount_get_type (void) G_GNUC_CONST; + +GUnixMount * _g_unix_mount_new (GVolumeMonitor *volume_monitor, + GUnixMountEntry *mount_entry, + GUnixVolume *volume); +gboolean _g_unix_mount_has_mount_path (GUnixMount *mount, + const char *mount_path); +void _g_unix_mount_unset_volume (GUnixMount *mount, + GUnixVolume *volume); +void _g_unix_mount_unmounted (GUnixMount *mount); + +G_END_DECLS + +#endif /* __G_UNIX_MOUNT_H__ */ diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c new file mode 100644 index 0000000..26963d6 --- /dev/null +++ b/gio/gunixmounts.c @@ -0,0 +1,3222 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +/* Prologue {{{1 */ + +#include "config.h" + +#include +#include +#include +#ifndef HAVE_SYSCTLBYNAME +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#endif +#ifdef HAVE_POLL +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_SYS_STATFS_H +#include +#endif +#if HAVE_SYS_STATVFS_H +#include +#endif +#if HAVE_SYS_VFS_H +#include +#elif HAVE_SYS_MOUNT_H +#if HAVE_SYS_PARAM_H +#include +#endif +#include +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#include "gunixmounts.h" +#include "gfile.h" +#include "gfilemonitor.h" +#include "glibintl.h" +#include "glocalfile.h" +#include "gthemedicon.h" +#include "gcontextspecificgroup.h" + + +#ifdef HAVE_MNTENT_H +static const char *_resolve_dev_root (void); +#endif + +/** + * SECTION:gunixmounts + * @include: gio/gunixmounts.h + * @short_description: UNIX mounts + * + * Routines for managing mounted UNIX mount points and paths. + * + * Note that `` belongs to the UNIX-specific GIO + * interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config + * file when using it. + */ + +/** + * GUnixMountType: + * @G_UNIX_MOUNT_TYPE_UNKNOWN: Unknown UNIX mount type. + * @G_UNIX_MOUNT_TYPE_FLOPPY: Floppy disk UNIX mount type. + * @G_UNIX_MOUNT_TYPE_CDROM: CDROM UNIX mount type. + * @G_UNIX_MOUNT_TYPE_NFS: Network File System (NFS) UNIX mount type. + * @G_UNIX_MOUNT_TYPE_ZIP: ZIP UNIX mount type. + * @G_UNIX_MOUNT_TYPE_JAZ: JAZZ UNIX mount type. + * @G_UNIX_MOUNT_TYPE_MEMSTICK: Memory Stick UNIX mount type. + * @G_UNIX_MOUNT_TYPE_CF: Compact Flash UNIX mount type. + * @G_UNIX_MOUNT_TYPE_SM: Smart Media UNIX mount type. + * @G_UNIX_MOUNT_TYPE_SDMMC: SD/MMC UNIX mount type. + * @G_UNIX_MOUNT_TYPE_IPOD: iPod UNIX mount type. + * @G_UNIX_MOUNT_TYPE_CAMERA: Digital camera UNIX mount type. + * @G_UNIX_MOUNT_TYPE_HD: Hard drive UNIX mount type. + * + * Types of UNIX mounts. + **/ +typedef enum { + G_UNIX_MOUNT_TYPE_UNKNOWN, + G_UNIX_MOUNT_TYPE_FLOPPY, + G_UNIX_MOUNT_TYPE_CDROM, + G_UNIX_MOUNT_TYPE_NFS, + G_UNIX_MOUNT_TYPE_ZIP, + G_UNIX_MOUNT_TYPE_JAZ, + G_UNIX_MOUNT_TYPE_MEMSTICK, + G_UNIX_MOUNT_TYPE_CF, + G_UNIX_MOUNT_TYPE_SM, + G_UNIX_MOUNT_TYPE_SDMMC, + G_UNIX_MOUNT_TYPE_IPOD, + G_UNIX_MOUNT_TYPE_CAMERA, + G_UNIX_MOUNT_TYPE_HD +} GUnixMountType; + +struct _GUnixMountEntry { + char *mount_path; + char *device_path; + char *root_path; + char *filesystem_type; + char *options; + gboolean is_read_only; + gboolean is_system_internal; +}; + +G_DEFINE_BOXED_TYPE (GUnixMountEntry, g_unix_mount_entry, + g_unix_mount_copy, g_unix_mount_free) + +struct _GUnixMountPoint { + char *mount_path; + char *device_path; + char *filesystem_type; + char *options; + gboolean is_read_only; + gboolean is_user_mountable; + gboolean is_loopback; +}; + +G_DEFINE_BOXED_TYPE (GUnixMountPoint, g_unix_mount_point, + g_unix_mount_point_copy, g_unix_mount_point_free) + +static GList *_g_get_unix_mounts (void); +static GList *_g_get_unix_mount_points (void); +static gboolean proc_mounts_watch_is_running (void); + +G_LOCK_DEFINE_STATIC (proc_mounts_source); + +/* Protected by proc_mounts_source lock */ +static guint64 mount_poller_time = 0; +static GSource *proc_mounts_watch_source; + +#ifdef HAVE_SYS_MNTTAB_H +#define MNTOPT_RO "ro" +#endif + +#ifdef HAVE_MNTENT_H +#include +#ifdef HAVE_LIBMOUNT +#include +#endif +#elif defined (HAVE_SYS_MNTTAB_H) +#include +#if defined(__sun) && !defined(mnt_opts) +#define mnt_opts mnt_mntopts +#endif +#endif + +#ifdef HAVE_SYS_VFSTAB_H +#include +#endif + +#if defined(HAVE_SYS_MNTCTL_H) && defined(HAVE_SYS_VMOUNT_H) && defined(HAVE_SYS_VFS_H) +#include +#include +#include +#include +#endif + +#if (defined(HAVE_GETVFSSTAT) || defined(HAVE_GETFSSTAT)) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H) +#include +#include +#include +#include +#ifdef HAVE_SYS_SYSCTL_H +#include +#endif +#endif + +#ifndef HAVE_SETMNTENT +#define setmntent(f,m) fopen(f,m) +#endif +#ifndef HAVE_ENDMNTENT +#define endmntent(f) fclose(f) +#endif + +static gboolean +is_in (const char *value, const char *set[]) +{ + int i; + for (i = 0; set[i] != NULL; i++) + { + if (strcmp (set[i], value) == 0) + return TRUE; + } + return FALSE; +} + +/** + * g_unix_is_mount_path_system_internal: + * @mount_path: (type filename): a mount path, e.g. `/media/disk` or `/usr` + * + * Determines if @mount_path is considered an implementation of the + * OS. This is primarily used for hiding mountable and mounted volumes + * that only are used in the OS and has little to no relevance to the + * casual user. + * + * Returns: %TRUE if @mount_path is considered an implementation detail + * of the OS. + **/ +gboolean +g_unix_is_mount_path_system_internal (const char *mount_path) +{ + const char *ignore_mountpoints[] = { + /* Includes all FHS 2.3 toplevel dirs and other specialized + * directories that we want to hide from the user. + */ + "/", /* we already have "Filesystem root" in Nautilus */ + "/bin", + "/boot", + "/compat/linux/proc", + "/compat/linux/sys", + "/dev", + "/etc", + "/home", + "/lib", + "/lib64", + "/libexec", + "/live/cow", + "/live/image", + "/media", + "/mnt", + "/opt", + "/rescue", + "/root", + "/sbin", + "/srv", + "/tmp", + "/usr", + "/usr/X11R6", + "/usr/local", + "/usr/obj", + "/usr/ports", + "/usr/src", + "/usr/xobj", + "/var", + "/var/crash", + "/var/local", + "/var/log", + "/var/log/audit", /* https://bugzilla.redhat.com/show_bug.cgi?id=333041 */ + "/var/mail", + "/var/run", + "/var/tmp", /* https://bugzilla.redhat.com/show_bug.cgi?id=335241 */ + "/proc", + "/sbin", + "/net", + "/sys", + NULL + }; + + if (is_in (mount_path, ignore_mountpoints)) + return TRUE; + + if (g_str_has_prefix (mount_path, "/dev/") || + g_str_has_prefix (mount_path, "/proc/") || + g_str_has_prefix (mount_path, "/sys/")) + return TRUE; + + if (g_str_has_suffix (mount_path, "/.gvfs")) + return TRUE; + + return FALSE; +} + +/** + * g_unix_is_system_fs_type: + * @fs_type: a file system type, e.g. `procfs` or `tmpfs` + * + * Determines if @fs_type is considered a type of file system which is only + * used in implementation of the OS. This is primarily used for hiding + * mounted volumes that are intended as APIs for programs to read, and system + * administrators at a shell; rather than something that should, for example, + * appear in a GUI. For example, the Linux `/proc` filesystem. + * + * The list of file system types considered ‘system’ ones may change over time. + * + * Returns: %TRUE if @fs_type is considered an implementation detail of the OS. + * Since: 2.56 + */ +gboolean +g_unix_is_system_fs_type (const char *fs_type) +{ + const char *ignore_fs[] = { + "adfs", + "afs", + "auto", + "autofs", + "autofs4", + "cgroup", + "configfs", + "cxfs", + "debugfs", + "devfs", + "devpts", + "devtmpfs", + "ecryptfs", + "fdescfs", + "fusectl", + "gfs", + "gfs2", + "gpfs", + "hugetlbfs", + "kernfs", + "linprocfs", + "linsysfs", + "lustre", + "lustre_lite", + "mfs", + "mqueue", + "ncpfs", + "nfsd", + "nullfs", + "ocfs2", + "overlay", + "proc", + "procfs", + "pstore", + "ptyfs", + "rootfs", + "rpc_pipefs", + "securityfs", + "selinuxfs", + "sysfs", + "tmpfs", + "usbfs", + NULL + }; + + g_return_val_if_fail (fs_type != NULL && *fs_type != '\0', FALSE); + + return is_in (fs_type, ignore_fs); +} + +/** + * g_unix_is_system_device_path: + * @device_path: a device path, e.g. `/dev/loop0` or `nfsd` + * + * Determines if @device_path is considered a block device path which is only + * used in implementation of the OS. This is primarily used for hiding + * mounted volumes that are intended as APIs for programs to read, and system + * administrators at a shell; rather than something that should, for example, + * appear in a GUI. For example, the Linux `/proc` filesystem. + * + * The list of device paths considered ‘system’ ones may change over time. + * + * Returns: %TRUE if @device_path is considered an implementation detail of + * the OS. + * Since: 2.56 + */ +gboolean +g_unix_is_system_device_path (const char *device_path) +{ + const char *ignore_devices[] = { + "none", + "sunrpc", + "devpts", + "nfsd", + "/dev/loop", + "/dev/vn", + NULL + }; + + g_return_val_if_fail (device_path != NULL && *device_path != '\0', FALSE); + + return is_in (device_path, ignore_devices); +} + +static gboolean +guess_system_internal (const char *mountpoint, + const char *fs, + const char *device, + const char *root) +{ + if (g_unix_is_system_fs_type (fs)) + return TRUE; + + if (g_unix_is_system_device_path (device)) + return TRUE; + + if (g_unix_is_mount_path_system_internal (mountpoint)) + return TRUE; + + /* It is not possible to reliably detect mounts which were created by bind + * operation. mntent-based _g_get_unix_mounts() implementation blindly skips + * mounts with a device path that is repeated (e.g. mounts created by bind + * operation, btrfs subvolumes). This usually chooses the most important + * mounts (i.e. which points to the root of filesystem), but it doesn't work + * in all cases and also it is not ideal that those mounts are completely + * ignored (e.g. x-gvfs-show doesn't work for them, trash backend can't handle + * files on btrfs subvolumes). libmount-based _g_get_unix_mounts() + * implementation provides a root path. So there is no need to completely + * ignore those mounts, because e.g. our volume monitors can use the root path + * to not mengle those mounts with the "regular" mounts (i.e. which points to + * the root). But because those mounts usually just duplicate other mounts and + * are completely ignored with mntend-based implementation, let's mark them as + * system internal. Given the different approaches it doesn't mean that all + * mounts which were ignored will be system internal now, but this should work + * in most cases. For more info, see g_unix_mount_get_root_path() annotation, + * comment in mntent-based _g_get_unix_mounts() implementation and the + * https://gitlab.gnome.org/GNOME/glib/issues/1271 issue. + */ + if (root != NULL && g_strcmp0 (root, "/") != 0) + return TRUE; + + return FALSE; +} + +/* GUnixMounts (ie: mtab) implementations {{{1 */ + +static GUnixMountEntry * +create_unix_mount_entry (const char *device_path, + const char *mount_path, + const char *root_path, + const char *filesystem_type, + const char *options, + gboolean is_read_only) +{ + GUnixMountEntry *mount_entry = NULL; + + mount_entry = g_new0 (GUnixMountEntry, 1); + mount_entry->device_path = g_strdup (device_path); + mount_entry->mount_path = g_strdup (mount_path); + mount_entry->root_path = g_strdup (root_path); + mount_entry->filesystem_type = g_strdup (filesystem_type); + mount_entry->options = g_strdup (options); + mount_entry->is_read_only = is_read_only; + + mount_entry->is_system_internal = + guess_system_internal (mount_entry->mount_path, + mount_entry->filesystem_type, + mount_entry->device_path, + mount_entry->root_path); + + return mount_entry; +} + +static GUnixMountPoint * +create_unix_mount_point (const char *device_path, + const char *mount_path, + const char *filesystem_type, + const char *options, + gboolean is_read_only, + gboolean is_user_mountable, + gboolean is_loopback) +{ + GUnixMountPoint *mount_point = NULL; + + mount_point = g_new0 (GUnixMountPoint, 1); + mount_point->device_path = g_strdup (device_path); + mount_point->mount_path = g_strdup (mount_path); + mount_point->filesystem_type = g_strdup (filesystem_type); + mount_point->options = g_strdup (options); + mount_point->is_read_only = is_read_only; + mount_point->is_user_mountable = is_user_mountable; + mount_point->is_loopback = is_loopback; + + return mount_point; +} + +/* mntent.h (Linux, GNU, NSS) {{{2 */ +#ifdef HAVE_MNTENT_H + +#ifdef HAVE_LIBMOUNT + +/* For documentation on /proc/self/mountinfo see + * http://www.kernel.org/doc/Documentation/filesystems/proc.txt + */ +#define PROC_MOUNTINFO_PATH "/proc/self/mountinfo" + +static GList * +_g_get_unix_mounts (void) +{ + struct libmnt_table *table = NULL; + struct libmnt_iter* iter = NULL; + struct libmnt_fs *fs = NULL; + GUnixMountEntry *mount_entry = NULL; + GList *return_list = NULL; + + table = mnt_new_table (); + if (mnt_table_parse_mtab (table, NULL) < 0) + goto out; + + iter = mnt_new_iter (MNT_ITER_FORWARD); + while (mnt_table_next_fs (table, iter, &fs) == 0) + { + const char *device_path = NULL; + char *mount_options = NULL; + unsigned long mount_flags = 0; + gboolean is_read_only = FALSE; + + device_path = mnt_fs_get_source (fs); + if (g_strcmp0 (device_path, "/dev/root") == 0) + device_path = _resolve_dev_root (); + + mount_options = mnt_fs_strdup_options (fs); + if (mount_options) + { + mnt_optstr_get_flags (mount_options, &mount_flags, mnt_get_builtin_optmap (MNT_LINUX_MAP)); + g_free (mount_options); + } + is_read_only = (mount_flags & MS_RDONLY) ? TRUE : FALSE; + + mount_entry = create_unix_mount_entry (device_path, + mnt_fs_get_target (fs), + mnt_fs_get_root (fs), + mnt_fs_get_fstype (fs), + mnt_fs_get_options (fs), + is_read_only); + + return_list = g_list_prepend (return_list, mount_entry); + } + mnt_free_iter (iter); + + out: + mnt_free_table (table); + + return g_list_reverse (return_list); +} + +#else + +static const char * +get_mtab_read_file (void) +{ +#ifdef _PATH_MOUNTED +# ifdef __linux__ + return "/proc/mounts"; +# else + return _PATH_MOUNTED; +# endif +#else + return "/etc/mtab"; +#endif +} + +#ifndef HAVE_GETMNTENT_R +G_LOCK_DEFINE_STATIC(getmntent); +#endif + +static GList * +_g_get_unix_mounts (void) +{ +#ifdef HAVE_GETMNTENT_R + struct mntent ent; + char buf[1024]; +#endif + struct mntent *mntent; + FILE *file; + const char *read_file; + GUnixMountEntry *mount_entry; + GHashTable *mounts_hash; + GList *return_list; + + read_file = get_mtab_read_file (); + + file = setmntent (read_file, "r"); + if (file == NULL) + return NULL; + + return_list = NULL; + + mounts_hash = g_hash_table_new (g_str_hash, g_str_equal); + +#ifdef HAVE_GETMNTENT_R + while ((mntent = getmntent_r (file, &ent, buf, sizeof (buf))) != NULL) +#else + G_LOCK (getmntent); + while ((mntent = getmntent (file)) != NULL) +#endif + { + const char *device_path = NULL; + gboolean is_read_only = FALSE; + + /* ignore any mnt_fsname that is repeated and begins with a '/' + * + * We do this to avoid being fooled by --bind mounts, since + * these have the same device as the location they bind to. + * It's not an ideal solution to the problem, but it's likely that + * the most important mountpoint is first and the --bind ones after + * that aren't as important. So it should work. + * + * The '/' is to handle procfs, tmpfs and other no device mounts. + */ + if (mntent->mnt_fsname != NULL && + mntent->mnt_fsname[0] == '/' && + g_hash_table_lookup (mounts_hash, mntent->mnt_fsname)) + continue; + + if (g_strcmp0 (mntent->mnt_fsname, "/dev/root") == 0) + device_path = _resolve_dev_root (); + else + device_path = mntent->mnt_fsname; + +#if defined (HAVE_HASMNTOPT) + if (hasmntopt (mntent, MNTOPT_RO) != NULL) + is_read_only = TRUE; +#endif + + mount_entry = create_unix_mount_entry (device_path, + mntent->mnt_dir, + NULL, + mntent->mnt_type, + mntent->mnt_opts, + is_read_only); + + g_hash_table_insert (mounts_hash, + mount_entry->device_path, + mount_entry->device_path); + + return_list = g_list_prepend (return_list, mount_entry); + } + g_hash_table_destroy (mounts_hash); + + endmntent (file); + +#ifndef HAVE_GETMNTENT_R + G_UNLOCK (getmntent); +#endif + + return g_list_reverse (return_list); +} + +#endif /* HAVE_LIBMOUNT */ + +static const char * +get_mtab_monitor_file (void) +{ + static const char *mountinfo_path = NULL; +#ifdef HAVE_LIBMOUNT + struct stat buf; +#endif + + if (mountinfo_path != NULL) + return mountinfo_path; + +#ifdef HAVE_LIBMOUNT + /* The mtab file is still used by some distros, so it has to be monitored in + * order to avoid races between g_unix_mounts_get and "mounts-changed" signal: + * https://bugzilla.gnome.org/show_bug.cgi?id=782814 + */ + if (mnt_has_regular_mtab (&mountinfo_path, NULL)) + { + return mountinfo_path; + } + + if (stat (PROC_MOUNTINFO_PATH, &buf) == 0) + { + mountinfo_path = PROC_MOUNTINFO_PATH; + return mountinfo_path; + } +#endif + +#ifdef _PATH_MOUNTED +# ifdef __linux__ + mountinfo_path = "/proc/mounts"; +# else + mountinfo_path = _PATH_MOUNTED; +# endif +#else + mountinfo_path = "/etc/mtab"; +#endif + + return mountinfo_path; +} + +/* mnttab.h {{{2 */ +#elif defined (HAVE_SYS_MNTTAB_H) + +G_LOCK_DEFINE_STATIC(getmntent); + +static const char * +get_mtab_read_file (void) +{ +#ifdef _PATH_MOUNTED + return _PATH_MOUNTED; +#else + return "/etc/mnttab"; +#endif +} + +static const char * +get_mtab_monitor_file (void) +{ + return get_mtab_read_file (); +} + +static GList * +_g_get_unix_mounts (void) +{ + struct mnttab mntent; + FILE *file; + const char *read_file; + GUnixMountEntry *mount_entry; + GList *return_list; + + read_file = get_mtab_read_file (); + + file = setmntent (read_file, "r"); + if (file == NULL) + return NULL; + + return_list = NULL; + + G_LOCK (getmntent); + while (! getmntent (file, &mntent)) + { + gboolean is_read_only = FALSE; + +#if defined (HAVE_HASMNTOPT) + if (hasmntopt (&mntent, MNTOPT_RO) != NULL) + is_read_only = TRUE; +#endif + + mount_entry = create_unix_mount_entry (mntent.mnt_special, + mntent.mnt_mountp, + NULL, + mntent.mnt_fstype, + mntent.mnt_opts, + is_read_only); + + return_list = g_list_prepend (return_list, mount_entry); + } + + endmntent (file); + + G_UNLOCK (getmntent); + + return g_list_reverse (return_list); +} + +/* mntctl.h (AIX) {{{2 */ +#elif defined(HAVE_SYS_MNTCTL_H) && defined(HAVE_SYS_VMOUNT_H) && defined(HAVE_SYS_VFS_H) + +static const char * +get_mtab_monitor_file (void) +{ + return NULL; +} + +static GList * +_g_get_unix_mounts (void) +{ + struct vfs_ent *fs_info; + struct vmount *vmount_info; + int vmount_number; + unsigned int vmount_size; + int current; + GList *return_list; + + if (mntctl (MCTL_QUERY, sizeof (vmount_size), &vmount_size) != 0) + { + g_warning ("Unable to know the number of mounted volumes"); + + return NULL; + } + + vmount_info = (struct vmount*)g_malloc (vmount_size); + + vmount_number = mntctl (MCTL_QUERY, vmount_size, vmount_info); + + if (vmount_info->vmt_revision != VMT_REVISION) + g_warning ("Bad vmount structure revision number, want %d, got %d", VMT_REVISION, vmount_info->vmt_revision); + + if (vmount_number < 0) + { + g_warning ("Unable to recover mounted volumes information"); + + g_free (vmount_info); + return NULL; + } + + return_list = NULL; + while (vmount_number > 0) + { + gboolean is_read_only = FALSE; + + fs_info = getvfsbytype (vmount_info->vmt_gfstype); + + /* is_removable = (vmount_info->vmt_flags & MNT_REMOVABLE) ? 1 : 0; */ + is_read_only = (vmount_info->vmt_flags & MNT_READONLY) ? 1 : 0; + + mount_entry = create_unix_mount_entry (vmt2dataptr (vmount_info, VMT_OBJECT), + vmt2dataptr (vmount_info, VMT_STUB), + NULL, + fs_info == NULL ? "unknown" : fs_info->vfsent_name, + NULL, + is_read_only); + + return_list = g_list_prepend (return_list, mount_entry); + + vmount_info = (struct vmount *)( (char*)vmount_info + + vmount_info->vmt_length); + vmount_number--; + } + + g_free (vmount_info); + + return g_list_reverse (return_list); +} + +/* sys/mount.h {{{2 */ +#elif (defined(HAVE_GETVFSSTAT) || defined(HAVE_GETFSSTAT)) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H) + +static const char * +get_mtab_monitor_file (void) +{ + return NULL; +} + +static GList * +_g_get_unix_mounts (void) +{ +#if defined(USE_STATVFS) + struct statvfs *mntent = NULL; +#elif defined(USE_STATFS) + struct statfs *mntent = NULL; +#else + #error statfs juggling failed +#endif + size_t bufsize; + int num_mounts, i; + GUnixMountEntry *mount_entry; + GList *return_list; + + /* Pass NOWAIT to avoid blocking trying to update NFS mounts. */ +#if defined(USE_STATVFS) && defined(HAVE_GETVFSSTAT) + num_mounts = getvfsstat (NULL, 0, ST_NOWAIT); +#elif defined(USE_STATFS) && defined(HAVE_GETFSSTAT) + num_mounts = getfsstat (NULL, 0, MNT_NOWAIT); +#endif + if (num_mounts == -1) + return NULL; + + bufsize = num_mounts * sizeof (*mntent); + mntent = g_malloc (bufsize); +#if defined(USE_STATVFS) && defined(HAVE_GETVFSSTAT) + num_mounts = getvfsstat (mntent, bufsize, ST_NOWAIT); +#elif defined(USE_STATFS) && defined(HAVE_GETFSSTAT) + num_mounts = getfsstat (mntent, bufsize, MNT_NOWAIT); +#endif + if (num_mounts == -1) + return NULL; + + return_list = NULL; + + for (i = 0; i < num_mounts; i++) + { + gboolean is_read_only = FALSE; + +#if defined(USE_STATVFS) + if (mntent[i].f_flag & ST_RDONLY) +#elif defined(USE_STATFS) + if (mntent[i].f_flags & MNT_RDONLY) +#else + #error statfs juggling failed +#endif + is_read_only = TRUE; + + mount_entry = create_unix_mount_entry (mntent[i].f_mntfromname, + mntent[i].f_mntonname, + NULL, + mntent[i].f_fstypename, + NULL, + is_read_only); + + return_list = g_list_prepend (return_list, mount_entry); + } + + g_free (mntent); + + return g_list_reverse (return_list); +} + +/* Interix {{{2 */ +#elif defined(__INTERIX) + +static const char * +get_mtab_monitor_file (void) +{ + return NULL; +} + +static GList * +_g_get_unix_mounts (void) +{ + DIR *dirp; + GList* return_list = NULL; + char filename[9 + NAME_MAX]; + + dirp = opendir ("/dev/fs"); + if (!dirp) + { + g_warning ("unable to read /dev/fs!"); + return NULL; + } + + while (1) + { + struct statvfs statbuf; + struct dirent entry; + struct dirent* result; + + if (readdir_r (dirp, &entry, &result) || result == NULL) + break; + + strcpy (filename, "/dev/fs/"); + strcat (filename, entry.d_name); + + if (statvfs (filename, &statbuf) == 0) + { + GUnixMountEntry* mount_entry = g_new0(GUnixMountEntry, 1); + + mount_entry->mount_path = g_strdup (statbuf.f_mntonname); + mount_entry->device_path = g_strdup (statbuf.f_mntfromname); + mount_entry->filesystem_type = g_strdup (statbuf.f_fstypename); + + if (statbuf.f_flag & ST_RDONLY) + mount_entry->is_read_only = TRUE; + + return_list = g_list_prepend(return_list, mount_entry); + } + } + + return_list = g_list_reverse (return_list); + + closedir (dirp); + + return return_list; +} + +/* QNX {{{2 */ +#elif defined (HAVE_QNX) + +static char * +get_mtab_monitor_file (void) +{ + /* TODO: Not implemented */ + return NULL; +} + +static GList * +_g_get_unix_mounts (void) +{ + /* TODO: Not implemented */ + return NULL; +} + +/* Common code {{{2 */ +#else +#error No _g_get_unix_mounts() implementation for system +#endif + +/* GUnixMountPoints (ie: fstab) implementations {{{1 */ + +/* _g_get_unix_mount_points(): + * read the fstab. + * don't return swap and ignore mounts. + */ + +static char * +get_fstab_file (void) +{ +#ifdef HAVE_LIBMOUNT + return (char *) mnt_get_fstab_path (); +#else +#if defined(HAVE_SYS_MNTCTL_H) && defined(HAVE_SYS_VMOUNT_H) && defined(HAVE_SYS_VFS_H) + /* AIX */ + return "/etc/filesystems"; +#elif defined(_PATH_MNTTAB) + return _PATH_MNTTAB; +#elif defined(VFSTAB) + return VFSTAB; +#else + return "/etc/fstab"; +#endif +#endif +} + +/* mntent.h (Linux, GNU, NSS) {{{2 */ +#ifdef HAVE_MNTENT_H + +#ifdef HAVE_LIBMOUNT + +static GList * +_g_get_unix_mount_points (void) +{ + struct libmnt_table *table = NULL; + struct libmnt_iter* iter = NULL; + struct libmnt_fs *fs = NULL; + GUnixMountPoint *mount_point = NULL; + GList *return_list = NULL; + + table = mnt_new_table (); + if (mnt_table_parse_fstab (table, NULL) < 0) + goto out; + + iter = mnt_new_iter (MNT_ITER_FORWARD); + while (mnt_table_next_fs (table, iter, &fs) == 0) + { + const char *device_path = NULL; + const char *mount_path = NULL; + const char *mount_fstype = NULL; + char *mount_options = NULL; + gboolean is_read_only = FALSE; + gboolean is_user_mountable = FALSE; + gboolean is_loopback = FALSE; + + mount_path = mnt_fs_get_target (fs); + if ((strcmp (mount_path, "ignore") == 0) || + (strcmp (mount_path, "swap") == 0) || + (strcmp (mount_path, "none") == 0)) + continue; + + mount_fstype = mnt_fs_get_fstype (fs); + mount_options = mnt_fs_strdup_options (fs); + if (mount_options) + { + unsigned long mount_flags = 0; + unsigned long userspace_flags = 0; + + mnt_optstr_get_flags (mount_options, &mount_flags, mnt_get_builtin_optmap (MNT_LINUX_MAP)); + mnt_optstr_get_flags (mount_options, &userspace_flags, mnt_get_builtin_optmap (MNT_USERSPACE_MAP)); + + /* We ignore bind fstab entries, as we ignore bind mounts anyway */ + if (mount_flags & MS_BIND) + { + g_free (mount_options); + continue; + } + + is_read_only = (mount_flags & MS_RDONLY) != 0; + is_loopback = (userspace_flags & MNT_MS_LOOP) != 0; + + if ((mount_fstype != NULL && g_strcmp0 ("supermount", mount_fstype) == 0) || + ((userspace_flags & MNT_MS_USER) && + (g_strstr_len (mount_options, -1, "user_xattr") == NULL)) || + (userspace_flags & MNT_MS_USERS) || + (userspace_flags & MNT_MS_OWNER)) + { + is_user_mountable = TRUE; + } + } + + device_path = mnt_fs_get_source (fs); + if (g_strcmp0 (device_path, "/dev/root") == 0) + device_path = _resolve_dev_root (); + + mount_point = create_unix_mount_point (device_path, + mount_path, + mount_fstype, + mount_options, + is_read_only, + is_user_mountable, + is_loopback); + if (mount_options) + g_free (mount_options); + + return_list = g_list_prepend (return_list, mount_point); + } + mnt_free_iter (iter); + + out: + mnt_free_table (table); + + return g_list_reverse (return_list); +} + +#else + +static GList * +_g_get_unix_mount_points (void) +{ +#ifdef HAVE_GETMNTENT_R + struct mntent ent; + char buf[1024]; +#endif + struct mntent *mntent; + FILE *file; + char *read_file; + GUnixMountPoint *mount_point; + GList *return_list; + + read_file = get_fstab_file (); + + file = setmntent (read_file, "r"); + if (file == NULL) + return NULL; + + return_list = NULL; + +#ifdef HAVE_GETMNTENT_R + while ((mntent = getmntent_r (file, &ent, buf, sizeof (buf))) != NULL) +#else + G_LOCK (getmntent); + while ((mntent = getmntent (file)) != NULL) +#endif + { + const char *device_path = NULL; + gboolean is_read_only = FALSE; + gboolean is_user_mountable = FALSE; + gboolean is_loopback = FALSE; + + if ((strcmp (mntent->mnt_dir, "ignore") == 0) || + (strcmp (mntent->mnt_dir, "swap") == 0) || + (strcmp (mntent->mnt_dir, "none") == 0)) + continue; + +#ifdef HAVE_HASMNTOPT + /* We ignore bind fstab entries, as we ignore bind mounts anyway */ + if (hasmntopt (mntent, "bind")) + continue; +#endif + + if (strcmp (mntent->mnt_fsname, "/dev/root") == 0) + device_path = _resolve_dev_root (); + else + device_path = mntent->mnt_fsname; + +#ifdef HAVE_HASMNTOPT + if (hasmntopt (mntent, MNTOPT_RO) != NULL) + is_read_only = TRUE; + + if (hasmntopt (mntent, "loop") != NULL) + is_loopback = TRUE; + +#endif + + if ((mntent->mnt_type != NULL && strcmp ("supermount", mntent->mnt_type) == 0) +#ifdef HAVE_HASMNTOPT + || (hasmntopt (mntent, "user") != NULL + && hasmntopt (mntent, "user") != hasmntopt (mntent, "user_xattr")) + || hasmntopt (mntent, "users") != NULL + || hasmntopt (mntent, "owner") != NULL +#endif + ) + is_user_mountable = TRUE; + + mount_point = create_unix_mount_point (device_path, + mntent->mnt_dir, + mntent->mnt_type, + mntent->mnt_opts, + is_read_only, + is_user_mountable, + is_loopback); + + return_list = g_list_prepend (return_list, mount_point); + } + + endmntent (file); + +#ifndef HAVE_GETMNTENT_R + G_UNLOCK (getmntent); +#endif + + return g_list_reverse (return_list); +} + +#endif /* HAVE_LIBMOUNT */ + +/* mnttab.h {{{2 */ +#elif defined (HAVE_SYS_MNTTAB_H) + +static GList * +_g_get_unix_mount_points (void) +{ + struct mnttab mntent; + FILE *file; + char *read_file; + GUnixMountPoint *mount_point; + GList *return_list; + + read_file = get_fstab_file (); + + file = setmntent (read_file, "r"); + if (file == NULL) + return NULL; + + return_list = NULL; + + G_LOCK (getmntent); + while (! getmntent (file, &mntent)) + { + gboolean is_read_only = FALSE; + gboolean is_user_mountable = FALSE; + gboolean is_loopback = FALSE; + + if ((strcmp (mntent.mnt_mountp, "ignore") == 0) || + (strcmp (mntent.mnt_mountp, "swap") == 0) || + (strcmp (mntent.mnt_mountp, "none") == 0)) + continue; + +#ifdef HAVE_HASMNTOPT + if (hasmntopt (&mntent, MNTOPT_RO) != NULL) + is_read_only = TRUE; + + if (hasmntopt (&mntent, "lofs") != NULL) + is_loopback = TRUE; +#endif + + if ((mntent.mnt_fstype != NULL) +#ifdef HAVE_HASMNTOPT + || (hasmntopt (&mntent, "user") != NULL + && hasmntopt (&mntent, "user") != hasmntopt (&mntent, "user_xattr")) + || hasmntopt (&mntent, "users") != NULL + || hasmntopt (&mntent, "owner") != NULL +#endif + ) + is_user_mountable = TRUE; + + mount_point = create_unix_mount_point (mntent.mnt_special, + mntent.mnt_mountp, + mntent.mnt_fstype, + mntent.mnt_mntopts, + is_read_only, + is_user_mountable, + is_loopback); + + return_list = g_list_prepend (return_list, mount_point); + } + + endmntent (file); + G_UNLOCK (getmntent); + + return g_list_reverse (return_list); +} + +/* mntctl.h (AIX) {{{2 */ +#elif defined(HAVE_SYS_MNTCTL_H) && defined(HAVE_SYS_VMOUNT_H) && defined(HAVE_SYS_VFS_H) + +/* functions to parse /etc/filesystems on aix */ + +/* read character, ignoring comments (begin with '*', end with '\n' */ +static int +aix_fs_getc (FILE *fd) +{ + int c; + + while ((c = getc (fd)) == '*') + { + while (((c = getc (fd)) != '\n') && (c != EOF)) + ; + } +} + +/* eat all continuous spaces in a file */ +static int +aix_fs_ignorespace (FILE *fd) +{ + int c; + + while ((c = aix_fs_getc (fd)) != EOF) + { + if (!g_ascii_isspace (c)) + { + ungetc (c,fd); + return c; + } + } + + return EOF; +} + +/* read one word from file */ +static int +aix_fs_getword (FILE *fd, + char *word) +{ + int c; + + aix_fs_ignorespace (fd); + + while (((c = aix_fs_getc (fd)) != EOF) && !g_ascii_isspace (c)) + { + if (c == '"') + { + while (((c = aix_fs_getc (fd)) != EOF) && (c != '"')) + *word++ = c; + else + *word++ = c; + } + } + *word = 0; + + return c; +} + +typedef struct { + char mnt_mount[PATH_MAX]; + char mnt_special[PATH_MAX]; + char mnt_fstype[16]; + char mnt_options[128]; +} AixMountTableEntry; + +/* read mount points properties */ +static int +aix_fs_get (FILE *fd, + AixMountTableEntry *prop) +{ + static char word[PATH_MAX] = { 0 }; + char value[PATH_MAX]; + + /* read stanza */ + if (word[0] == 0) + { + if (aix_fs_getword (fd, word) == EOF) + return EOF; + } + + word[strlen(word) - 1] = 0; + strcpy (prop->mnt_mount, word); + + /* read attributes and value */ + + while (aix_fs_getword (fd, word) != EOF) + { + /* test if is attribute or new stanza */ + if (word[strlen(word) - 1] == ':') + return 0; + + /* read "=" */ + aix_fs_getword (fd, value); + + /* read value */ + aix_fs_getword (fd, value); + + if (strcmp (word, "dev") == 0) + strcpy (prop->mnt_special, value); + else if (strcmp (word, "vfs") == 0) + strcpy (prop->mnt_fstype, value); + else if (strcmp (word, "options") == 0) + strcpy(prop->mnt_options, value); + } + + return 0; +} + +static GList * +_g_get_unix_mount_points (void) +{ + struct mntent *mntent; + FILE *file; + char *read_file; + GUnixMountPoint *mount_point; + AixMountTableEntry mntent; + GList *return_list; + + read_file = get_fstab_file (); + + file = setmntent (read_file, "r"); + if (file == NULL) + return NULL; + + return_list = NULL; + + while (!aix_fs_get (file, &mntent)) + { + if (strcmp ("cdrfs", mntent.mnt_fstype) == 0) + { + mount_point = create_unix_mount_point (mntent.mnt_special, + mntent.mnt_mount, + mntent.mnt_fstype, + mntent.mnt_options, + TRUE, + TRUE, + FALSE); + + return_list = g_list_prepend (return_list, mount_point); + } + } + + endmntent (file); + + return g_list_reverse (return_list); +} + +#elif (defined(HAVE_GETVFSSTAT) || defined(HAVE_GETFSSTAT)) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H) + +static GList * +_g_get_unix_mount_points (void) +{ + struct fstab *fstab = NULL; + GUnixMountPoint *mount_point; + GList *return_list = NULL; + G_LOCK_DEFINE_STATIC (fsent); +#ifdef HAVE_SYS_SYSCTL_H + int usermnt = 0; + struct stat sb; +#endif + +#ifdef HAVE_SYS_SYSCTL_H +#if defined(HAVE_SYSCTLBYNAME) + { + size_t len = sizeof(usermnt); + + sysctlbyname ("vfs.usermount", &usermnt, &len, NULL, 0); + } +#elif defined(CTL_VFS) && defined(VFS_USERMOUNT) + { + int mib[2]; + size_t len = sizeof(usermnt); + + mib[0] = CTL_VFS; + mib[1] = VFS_USERMOUNT; + sysctl (mib, 2, &usermnt, &len, NULL, 0); + } +#elif defined(CTL_KERN) && defined(KERN_USERMOUNT) + { + int mib[2]; + size_t len = sizeof(usermnt); + + mib[0] = CTL_KERN; + mib[1] = KERN_USERMOUNT; + sysctl (mib, 2, &usermnt, &len, NULL, 0); + } +#endif +#endif + + G_LOCK (fsent); + if (!setfsent ()) + { + G_UNLOCK (fsent); + return NULL; + } + + while ((fstab = getfsent ()) != NULL) + { + gboolean is_read_only = FALSE; + gboolean is_user_mountable = FALSE; + + if (strcmp (fstab->fs_vfstype, "swap") == 0) + continue; + + if (strcmp (fstab->fs_type, "ro") == 0) + is_read_only = TRUE; + +#ifdef HAVE_SYS_SYSCTL_H + if (usermnt != 0) + { + uid_t uid = getuid (); + if (stat (fstab->fs_file, &sb) == 0) + { + if (uid == 0 || sb.st_uid == uid) + is_user_mountable = TRUE; + } + } +#endif + + mount_point = create_unix_mount_point (fstab->fs_spec, + fstab->fs_file, + fstab->fs_vfstype, + fstab->fs_mntops, + is_read_only, + is_user_mountable, + FALSE); + + return_list = g_list_prepend (return_list, mount_point); + } + + endfsent (); + G_UNLOCK (fsent); + + return g_list_reverse (return_list); +} +/* Interix {{{2 */ +#elif defined(__INTERIX) +static GList * +_g_get_unix_mount_points (void) +{ + return _g_get_unix_mounts (); +} + +/* QNX {{{2 */ +#elif defined (HAVE_QNX) +static GList * +_g_get_unix_mount_points (void) +{ + return _g_get_unix_mounts (); +} + +/* Common code {{{2 */ +#else +#error No g_get_mount_table() implementation for system +#endif + +static guint64 +get_mounts_timestamp (void) +{ + const char *monitor_file; + struct stat buf; + guint64 timestamp = 0; + + G_LOCK (proc_mounts_source); + + monitor_file = get_mtab_monitor_file (); + /* Don't return mtime for /proc/ files */ + if (monitor_file && !g_str_has_prefix (monitor_file, "/proc/")) + { + if (stat (monitor_file, &buf) == 0) + timestamp = buf.st_mtime; + } + else if (proc_mounts_watch_is_running ()) + { + /* it's being monitored by poll, so return mount_poller_time */ + timestamp = mount_poller_time; + } + else + { + /* Case of /proc/ file not being monitored - Be on the safe side and + * send a new timestamp to force g_unix_mounts_changed_since() to + * return TRUE so any application caches depending on it (like eg. + * the one in GIO) get invalidated and don't hold possibly outdated + * data - see Bug 787731 */ + timestamp = g_get_monotonic_time (); + } + + G_UNLOCK (proc_mounts_source); + + return timestamp; +} + +static guint64 +get_mount_points_timestamp (void) +{ + const char *monitor_file; + struct stat buf; + + monitor_file = get_fstab_file (); + if (monitor_file) + { + if (stat (monitor_file, &buf) == 0) + return (guint64)buf.st_mtime; + } + return 0; +} + +/** + * g_unix_mounts_get: + * @time_read: (out) (optional): guint64 to contain a timestamp, or %NULL + * + * Gets a #GList of #GUnixMountEntry containing the unix mounts. + * If @time_read is set, it will be filled with the mount + * timestamp, allowing for checking if the mounts have changed + * with g_unix_mounts_changed_since(). + * + * Returns: (element-type GUnixMountEntry) (transfer full): + * a #GList of the UNIX mounts. + **/ +GList * +g_unix_mounts_get (guint64 *time_read) +{ + if (time_read) + *time_read = get_mounts_timestamp (); + + return _g_get_unix_mounts (); +} + +/** + * g_unix_mount_at: + * @mount_path: (type filename): path for a possible unix mount. + * @time_read: (out) (optional): guint64 to contain a timestamp. + * + * Gets a #GUnixMountEntry for a given mount path. If @time_read + * is set, it will be filled with a unix timestamp for checking + * if the mounts have changed since with g_unix_mounts_changed_since(). + * + * If more mounts have the same mount path, the last matching mount + * is returned. + * + * This will return %NULL if there is no mount point at @mount_path. + * + * Returns: (transfer full) (nullable): a #GUnixMountEntry. + **/ +GUnixMountEntry * +g_unix_mount_at (const char *mount_path, + guint64 *time_read) +{ + GList *mounts, *l; + GUnixMountEntry *mount_entry, *found; + + mounts = g_unix_mounts_get (time_read); + + found = NULL; + for (l = mounts; l != NULL; l = l->next) + { + mount_entry = l->data; + + if (strcmp (mount_path, mount_entry->mount_path) == 0) + { + if (found != NULL) + g_unix_mount_free (found); + + found = mount_entry; + } + else + g_unix_mount_free (mount_entry); + } + g_list_free (mounts); + + return found; +} + +/** + * g_unix_mount_for: + * @file_path: (type filename): file path on some unix mount. + * @time_read: (out) (optional): guint64 to contain a timestamp. + * + * Gets a #GUnixMountEntry for a given file path. If @time_read + * is set, it will be filled with a unix timestamp for checking + * if the mounts have changed since with g_unix_mounts_changed_since(). + * + * If more mounts have the same mount path, the last matching mount + * is returned. + * + * This will return %NULL if looking up the mount entry fails, if + * @file_path doesn’t exist or there is an I/O error. + * + * Returns: (transfer full) (nullable): a #GUnixMountEntry. + * + * Since: 2.52 + **/ +GUnixMountEntry * +g_unix_mount_for (const char *file_path, + guint64 *time_read) +{ + GUnixMountEntry *entry; + + g_return_val_if_fail (file_path != NULL, NULL); + + entry = g_unix_mount_at (file_path, time_read); + if (entry == NULL) + { + char *topdir; + + topdir = _g_local_file_find_topdir_for (file_path); + if (topdir != NULL) + { + entry = g_unix_mount_at (topdir, time_read); + g_free (topdir); + } + } + + return entry; +} + +static gpointer +copy_mount_point_cb (gconstpointer src, + gpointer data) +{ + GUnixMountPoint *src_mount_point = (GUnixMountPoint *) src; + return g_unix_mount_point_copy (src_mount_point); +} + +/** + * g_unix_mount_points_get: + * @time_read: (out) (optional): guint64 to contain a timestamp. + * + * Gets a #GList of #GUnixMountPoint containing the unix mount points. + * If @time_read is set, it will be filled with the mount timestamp, + * allowing for checking if the mounts have changed with + * g_unix_mount_points_changed_since(). + * + * Returns: (element-type GUnixMountPoint) (transfer full): + * a #GList of the UNIX mountpoints. + **/ +GList * +g_unix_mount_points_get (guint64 *time_read) +{ + static GList *mnt_pts_last = NULL; + static guint64 time_read_last = 0; + GList *mnt_pts = NULL; + guint64 time_read_now; + G_LOCK_DEFINE_STATIC (unix_mount_points); + + G_LOCK (unix_mount_points); + + time_read_now = get_mount_points_timestamp (); + if (time_read_now != time_read_last || mnt_pts_last == NULL) + { + time_read_last = time_read_now; + g_list_free_full (mnt_pts_last, (GDestroyNotify) g_unix_mount_point_free); + mnt_pts_last = _g_get_unix_mount_points (); + } + mnt_pts = g_list_copy_deep (mnt_pts_last, copy_mount_point_cb, NULL); + + G_UNLOCK (unix_mount_points); + + if (time_read) + *time_read = time_read_now; + + return mnt_pts; +} + +/** + * g_unix_mount_point_at: + * @mount_path: (type filename): path for a possible unix mount point. + * @time_read: (out) (optional): guint64 to contain a timestamp. + * + * Gets a #GUnixMountPoint for a given mount path. If @time_read is set, it + * will be filled with a unix timestamp for checking if the mount points have + * changed since with g_unix_mount_points_changed_since(). + * + * If more mount points have the same mount path, the last matching mount point + * is returned. + * + * Returns: (transfer full) (nullable): a #GUnixMountPoint, or %NULL if no match + * is found. + * + * Since: 2.66 + **/ +GUnixMountPoint * +g_unix_mount_point_at (const char *mount_path, + guint64 *time_read) +{ + GList *mount_points, *l; + GUnixMountPoint *mount_point, *found; + + mount_points = g_unix_mount_points_get (time_read); + + found = NULL; + for (l = mount_points; l != NULL; l = l->next) + { + mount_point = l->data; + + if (strcmp (mount_path, mount_point->mount_path) == 0) + { + if (found != NULL) + g_unix_mount_point_free (found); + + found = mount_point; + } + else + g_unix_mount_point_free (mount_point); + } + g_list_free (mount_points); + + return found; +} + +/** + * g_unix_mounts_changed_since: + * @time: guint64 to contain a timestamp. + * + * Checks if the unix mounts have changed since a given unix time. + * + * Returns: %TRUE if the mounts have changed since @time. + **/ +gboolean +g_unix_mounts_changed_since (guint64 time) +{ + return get_mounts_timestamp () != time; +} + +/** + * g_unix_mount_points_changed_since: + * @time: guint64 to contain a timestamp. + * + * Checks if the unix mount points have changed since a given unix time. + * + * Returns: %TRUE if the mount points have changed since @time. + **/ +gboolean +g_unix_mount_points_changed_since (guint64 time) +{ + return get_mount_points_timestamp () != time; +} + +/* GUnixMountMonitor {{{1 */ + +enum { + MOUNTS_CHANGED, + MOUNTPOINTS_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +struct _GUnixMountMonitor { + GObject parent; + + GMainContext *context; +}; + +struct _GUnixMountMonitorClass { + GObjectClass parent_class; +}; + + +G_DEFINE_TYPE (GUnixMountMonitor, g_unix_mount_monitor, G_TYPE_OBJECT) + +static GContextSpecificGroup mount_monitor_group; +static GFileMonitor *fstab_monitor; +static GFileMonitor *mtab_monitor; +static GList *mount_poller_mounts; +static guint mtab_file_changed_id; + +/* Called with proc_mounts_source lock held. */ +static gboolean +proc_mounts_watch_is_running (void) +{ + return proc_mounts_watch_source != NULL && + !g_source_is_destroyed (proc_mounts_watch_source); +} + +static void +fstab_file_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + if (event_type != G_FILE_MONITOR_EVENT_CHANGED && + event_type != G_FILE_MONITOR_EVENT_CREATED && + event_type != G_FILE_MONITOR_EVENT_DELETED) + return; + + g_context_specific_group_emit (&mount_monitor_group, signals[MOUNTPOINTS_CHANGED]); +} + +static gboolean +mtab_file_changed_cb (gpointer user_data) +{ + mtab_file_changed_id = 0; + g_context_specific_group_emit (&mount_monitor_group, signals[MOUNTS_CHANGED]); + + return G_SOURCE_REMOVE; +} + +static void +mtab_file_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + GMainContext *context; + GSource *source; + + if (event_type != G_FILE_MONITOR_EVENT_CHANGED && + event_type != G_FILE_MONITOR_EVENT_CREATED && + event_type != G_FILE_MONITOR_EVENT_DELETED) + return; + + /* Skip accumulated events from file monitor which we are not able to handle + * in a real time instead of emitting mounts_changed signal several times. + * This should behave equally to GIOChannel based monitoring. See Bug 792235. + */ + if (mtab_file_changed_id > 0) + return; + + context = g_main_context_get_thread_default (); + if (!context) + context = g_main_context_default (); + + source = g_idle_source_new (); + g_source_set_priority (source, G_PRIORITY_DEFAULT); + g_source_set_callback (source, mtab_file_changed_cb, NULL, NULL); + g_source_set_static_name (source, "[gio] mtab_file_changed_cb"); + g_source_attach (source, context); + g_source_unref (source); +} + +static gboolean +proc_mounts_changed (GIOChannel *channel, + GIOCondition cond, + gpointer user_data) +{ + if (cond & G_IO_ERR) + { + G_LOCK (proc_mounts_source); + mount_poller_time = (guint64) g_get_monotonic_time (); + G_UNLOCK (proc_mounts_source); + + g_context_specific_group_emit (&mount_monitor_group, signals[MOUNTS_CHANGED]); + } + + return TRUE; +} + +static gboolean +mount_change_poller (gpointer user_data) +{ + GList *current_mounts, *new_it, *old_it; + gboolean has_changed = FALSE; + + current_mounts = _g_get_unix_mounts (); + + for ( new_it = current_mounts, old_it = mount_poller_mounts; + new_it != NULL && old_it != NULL; + new_it = g_list_next (new_it), old_it = g_list_next (old_it) ) + { + if (g_unix_mount_compare (new_it->data, old_it->data) != 0) + { + has_changed = TRUE; + break; + } + } + if (!(new_it == NULL && old_it == NULL)) + has_changed = TRUE; + + g_list_free_full (mount_poller_mounts, (GDestroyNotify) g_unix_mount_free); + + mount_poller_mounts = current_mounts; + + if (has_changed) + { + G_LOCK (proc_mounts_source); + mount_poller_time = (guint64) g_get_monotonic_time (); + G_UNLOCK (proc_mounts_source); + + g_context_specific_group_emit (&mount_monitor_group, signals[MOUNTPOINTS_CHANGED]); + } + + return TRUE; +} + + +static void +mount_monitor_stop (void) +{ + if (fstab_monitor) + { + g_file_monitor_cancel (fstab_monitor); + g_object_unref (fstab_monitor); + } + + G_LOCK (proc_mounts_source); + if (proc_mounts_watch_source != NULL) + { + g_source_destroy (proc_mounts_watch_source); + proc_mounts_watch_source = NULL; + } + G_UNLOCK (proc_mounts_source); + + if (mtab_monitor) + { + g_file_monitor_cancel (mtab_monitor); + g_object_unref (mtab_monitor); + } + + if (mtab_file_changed_id) + { + g_source_remove (mtab_file_changed_id); + mtab_file_changed_id = 0; + } + + g_list_free_full (mount_poller_mounts, (GDestroyNotify) g_unix_mount_free); +} + +static void +mount_monitor_start (void) +{ + GFile *file; + + if (get_fstab_file () != NULL) + { + file = g_file_new_for_path (get_fstab_file ()); + fstab_monitor = g_file_monitor_file (file, 0, NULL, NULL); + g_object_unref (file); + + g_signal_connect (fstab_monitor, "changed", (GCallback)fstab_file_changed, NULL); + } + + if (get_mtab_monitor_file () != NULL) + { + const gchar *mtab_path; + + mtab_path = get_mtab_monitor_file (); + /* Monitoring files in /proc/ is special - can't just use GFileMonitor. + * See 'man proc' for more details. + */ + if (g_str_has_prefix (mtab_path, "/proc/")) + { + GIOChannel *proc_mounts_channel; + GError *error = NULL; + proc_mounts_channel = g_io_channel_new_file (mtab_path, "r", &error); + if (proc_mounts_channel == NULL) + { + g_warning ("Error creating IO channel for %s: %s (%s, %d)", mtab_path, + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + } + else + { + G_LOCK (proc_mounts_source); + + proc_mounts_watch_source = g_io_create_watch (proc_mounts_channel, G_IO_ERR); + mount_poller_time = (guint64) g_get_monotonic_time (); + g_source_set_callback (proc_mounts_watch_source, + (GSourceFunc) proc_mounts_changed, + NULL, NULL); + g_source_attach (proc_mounts_watch_source, + g_main_context_get_thread_default ()); + g_source_unref (proc_mounts_watch_source); + g_io_channel_unref (proc_mounts_channel); + + G_UNLOCK (proc_mounts_source); + } + } + else + { + file = g_file_new_for_path (mtab_path); + mtab_monitor = g_file_monitor_file (file, 0, NULL, NULL); + g_object_unref (file); + g_signal_connect (mtab_monitor, "changed", (GCallback)mtab_file_changed, NULL); + } + } + else + { + G_LOCK (proc_mounts_source); + + proc_mounts_watch_source = g_timeout_source_new_seconds (3); + mount_poller_mounts = _g_get_unix_mounts (); + mount_poller_time = (guint64)g_get_monotonic_time (); + g_source_set_callback (proc_mounts_watch_source, + mount_change_poller, + NULL, NULL); + g_source_attach (proc_mounts_watch_source, + g_main_context_get_thread_default ()); + g_source_unref (proc_mounts_watch_source); + + G_UNLOCK (proc_mounts_source); + } +} + +static void +g_unix_mount_monitor_finalize (GObject *object) +{ + GUnixMountMonitor *monitor; + + monitor = G_UNIX_MOUNT_MONITOR (object); + + g_context_specific_group_remove (&mount_monitor_group, monitor->context, monitor, mount_monitor_stop); + + G_OBJECT_CLASS (g_unix_mount_monitor_parent_class)->finalize (object); +} + +static void +g_unix_mount_monitor_class_init (GUnixMountMonitorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_unix_mount_monitor_finalize; + + /** + * GUnixMountMonitor::mounts-changed: + * @monitor: the object on which the signal is emitted + * + * Emitted when the unix mounts have changed. + */ + signals[MOUNTS_CHANGED] = + g_signal_new (I_("mounts-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + /** + * GUnixMountMonitor::mountpoints-changed: + * @monitor: the object on which the signal is emitted + * + * Emitted when the unix mount points have changed. + */ + signals[MOUNTPOINTS_CHANGED] = + g_signal_new (I_("mountpoints-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, 0); +} + +static void +g_unix_mount_monitor_init (GUnixMountMonitor *monitor) +{ +} + +/** + * g_unix_mount_monitor_set_rate_limit: + * @mount_monitor: a #GUnixMountMonitor + * @limit_msec: a integer with the limit in milliseconds to + * poll for changes. + * + * This function does nothing. + * + * Before 2.44, this was a partially-effective way of controlling the + * rate at which events would be reported under some uncommon + * circumstances. Since @mount_monitor is a singleton, it also meant + * that calling this function would have side effects for other users of + * the monitor. + * + * Since: 2.18 + * + * Deprecated:2.44:This function does nothing. Don't call it. + */ +void +g_unix_mount_monitor_set_rate_limit (GUnixMountMonitor *mount_monitor, + gint limit_msec) +{ +} + +/** + * g_unix_mount_monitor_get: + * + * Gets the #GUnixMountMonitor for the current thread-default main + * context. + * + * The mount monitor can be used to monitor for changes to the list of + * mounted filesystems as well as the list of mount points (ie: fstab + * entries). + * + * You must only call g_object_unref() on the return value from under + * the same main context as you called this function. + * + * Returns: (transfer full): the #GUnixMountMonitor. + * + * Since: 2.44 + **/ +GUnixMountMonitor * +g_unix_mount_monitor_get (void) +{ + return g_context_specific_group_get (&mount_monitor_group, + G_TYPE_UNIX_MOUNT_MONITOR, + G_STRUCT_OFFSET(GUnixMountMonitor, context), + mount_monitor_start); +} + +/** + * g_unix_mount_monitor_new: + * + * Deprecated alias for g_unix_mount_monitor_get(). + * + * This function was never a true constructor, which is why it was + * renamed. + * + * Returns: a #GUnixMountMonitor. + * + * Deprecated:2.44:Use g_unix_mount_monitor_get() instead. + */ +GUnixMountMonitor * +g_unix_mount_monitor_new (void) +{ + return g_unix_mount_monitor_get (); +} + +/* GUnixMount {{{1 */ +/** + * g_unix_mount_free: + * @mount_entry: a #GUnixMountEntry. + * + * Frees a unix mount. + */ +void +g_unix_mount_free (GUnixMountEntry *mount_entry) +{ + g_return_if_fail (mount_entry != NULL); + + g_free (mount_entry->mount_path); + g_free (mount_entry->device_path); + g_free (mount_entry->root_path); + g_free (mount_entry->filesystem_type); + g_free (mount_entry->options); + g_free (mount_entry); +} + +/** + * g_unix_mount_copy: + * @mount_entry: a #GUnixMountEntry. + * + * Makes a copy of @mount_entry. + * + * Returns: (transfer full): a new #GUnixMountEntry + * + * Since: 2.54 + */ +GUnixMountEntry * +g_unix_mount_copy (GUnixMountEntry *mount_entry) +{ + GUnixMountEntry *copy; + + g_return_val_if_fail (mount_entry != NULL, NULL); + + copy = g_new0 (GUnixMountEntry, 1); + copy->mount_path = g_strdup (mount_entry->mount_path); + copy->device_path = g_strdup (mount_entry->device_path); + copy->root_path = g_strdup (mount_entry->root_path); + copy->filesystem_type = g_strdup (mount_entry->filesystem_type); + copy->options = g_strdup (mount_entry->options); + copy->is_read_only = mount_entry->is_read_only; + copy->is_system_internal = mount_entry->is_system_internal; + + return copy; +} + +/** + * g_unix_mount_point_free: + * @mount_point: unix mount point to free. + * + * Frees a unix mount point. + */ +void +g_unix_mount_point_free (GUnixMountPoint *mount_point) +{ + g_return_if_fail (mount_point != NULL); + + g_free (mount_point->mount_path); + g_free (mount_point->device_path); + g_free (mount_point->filesystem_type); + g_free (mount_point->options); + g_free (mount_point); +} + +/** + * g_unix_mount_point_copy: + * @mount_point: a #GUnixMountPoint. + * + * Makes a copy of @mount_point. + * + * Returns: (transfer full): a new #GUnixMountPoint + * + * Since: 2.54 + */ +GUnixMountPoint* +g_unix_mount_point_copy (GUnixMountPoint *mount_point) +{ + GUnixMountPoint *copy; + + g_return_val_if_fail (mount_point != NULL, NULL); + + copy = g_new0 (GUnixMountPoint, 1); + copy->mount_path = g_strdup (mount_point->mount_path); + copy->device_path = g_strdup (mount_point->device_path); + copy->filesystem_type = g_strdup (mount_point->filesystem_type); + copy->options = g_strdup (mount_point->options); + copy->is_read_only = mount_point->is_read_only; + copy->is_user_mountable = mount_point->is_user_mountable; + copy->is_loopback = mount_point->is_loopback; + + return copy; +} + +/** + * g_unix_mount_compare: + * @mount1: first #GUnixMountEntry to compare. + * @mount2: second #GUnixMountEntry to compare. + * + * Compares two unix mounts. + * + * Returns: 1, 0 or -1 if @mount1 is greater than, equal to, + * or less than @mount2, respectively. + */ +gint +g_unix_mount_compare (GUnixMountEntry *mount1, + GUnixMountEntry *mount2) +{ + int res; + + g_return_val_if_fail (mount1 != NULL && mount2 != NULL, 0); + + res = g_strcmp0 (mount1->mount_path, mount2->mount_path); + if (res != 0) + return res; + + res = g_strcmp0 (mount1->device_path, mount2->device_path); + if (res != 0) + return res; + + res = g_strcmp0 (mount1->root_path, mount2->root_path); + if (res != 0) + return res; + + res = g_strcmp0 (mount1->filesystem_type, mount2->filesystem_type); + if (res != 0) + return res; + + res = g_strcmp0 (mount1->options, mount2->options); + if (res != 0) + return res; + + res = mount1->is_read_only - mount2->is_read_only; + if (res != 0) + return res; + + return 0; +} + +/** + * g_unix_mount_get_mount_path: + * @mount_entry: input #GUnixMountEntry to get the mount path for. + * + * Gets the mount path for a unix mount. + * + * Returns: (type filename): the mount path for @mount_entry. + */ +const gchar * +g_unix_mount_get_mount_path (GUnixMountEntry *mount_entry) +{ + g_return_val_if_fail (mount_entry != NULL, NULL); + + return mount_entry->mount_path; +} + +/** + * g_unix_mount_get_device_path: + * @mount_entry: a #GUnixMount. + * + * Gets the device path for a unix mount. + * + * Returns: (type filename): a string containing the device path. + */ +const gchar * +g_unix_mount_get_device_path (GUnixMountEntry *mount_entry) +{ + g_return_val_if_fail (mount_entry != NULL, NULL); + + return mount_entry->device_path; +} + +/** + * g_unix_mount_get_root_path: + * @mount_entry: a #GUnixMountEntry. + * + * Gets the root of the mount within the filesystem. This is useful e.g. for + * mounts created by bind operation, or btrfs subvolumes. + * + * For example, the root path is equal to "/" for mount created by + * "mount /dev/sda1 /mnt/foo" and "/bar" for + * "mount --bind /mnt/foo/bar /mnt/bar". + * + * Returns: (nullable): a string containing the root, or %NULL if not supported. + * + * Since: 2.60 + */ +const gchar * +g_unix_mount_get_root_path (GUnixMountEntry *mount_entry) +{ + g_return_val_if_fail (mount_entry != NULL, NULL); + + return mount_entry->root_path; +} + +/** + * g_unix_mount_get_fs_type: + * @mount_entry: a #GUnixMount. + * + * Gets the filesystem type for the unix mount. + * + * Returns: a string containing the file system type. + */ +const gchar * +g_unix_mount_get_fs_type (GUnixMountEntry *mount_entry) +{ + g_return_val_if_fail (mount_entry != NULL, NULL); + + return mount_entry->filesystem_type; +} + +/** + * g_unix_mount_get_options: + * @mount_entry: a #GUnixMountEntry. + * + * Gets a comma-separated list of mount options for the unix mount. For example, + * `rw,relatime,seclabel,data=ordered`. + * + * This is similar to g_unix_mount_point_get_options(), but it takes + * a #GUnixMountEntry as an argument. + * + * Returns: (nullable): a string containing the options, or %NULL if not + * available. + * + * Since: 2.58 + */ +const gchar * +g_unix_mount_get_options (GUnixMountEntry *mount_entry) +{ + g_return_val_if_fail (mount_entry != NULL, NULL); + + return mount_entry->options; +} + +/** + * g_unix_mount_is_readonly: + * @mount_entry: a #GUnixMount. + * + * Checks if a unix mount is mounted read only. + * + * Returns: %TRUE if @mount_entry is read only. + */ +gboolean +g_unix_mount_is_readonly (GUnixMountEntry *mount_entry) +{ + g_return_val_if_fail (mount_entry != NULL, FALSE); + + return mount_entry->is_read_only; +} + +/** + * g_unix_mount_is_system_internal: + * @mount_entry: a #GUnixMount. + * + * Checks if a Unix mount is a system mount. This is the Boolean OR of + * g_unix_is_system_fs_type(), g_unix_is_system_device_path() and + * g_unix_is_mount_path_system_internal() on @mount_entry’s properties. + * + * The definition of what a ‘system’ mount entry is may change over time as new + * file system types and device paths are ignored. + * + * Returns: %TRUE if the unix mount is for a system path. + */ +gboolean +g_unix_mount_is_system_internal (GUnixMountEntry *mount_entry) +{ + g_return_val_if_fail (mount_entry != NULL, FALSE); + + return mount_entry->is_system_internal; +} + +/* GUnixMountPoint {{{1 */ +/** + * g_unix_mount_point_compare: + * @mount1: a #GUnixMount. + * @mount2: a #GUnixMount. + * + * Compares two unix mount points. + * + * Returns: 1, 0 or -1 if @mount1 is greater than, equal to, + * or less than @mount2, respectively. + */ +gint +g_unix_mount_point_compare (GUnixMountPoint *mount1, + GUnixMountPoint *mount2) +{ + int res; + + g_return_val_if_fail (mount1 != NULL && mount2 != NULL, 0); + + res = g_strcmp0 (mount1->mount_path, mount2->mount_path); + if (res != 0) + return res; + + res = g_strcmp0 (mount1->device_path, mount2->device_path); + if (res != 0) + return res; + + res = g_strcmp0 (mount1->filesystem_type, mount2->filesystem_type); + if (res != 0) + return res; + + res = g_strcmp0 (mount1->options, mount2->options); + if (res != 0) + return res; + + res = mount1->is_read_only - mount2->is_read_only; + if (res != 0) + return res; + + res = mount1->is_user_mountable - mount2->is_user_mountable; + if (res != 0) + return res; + + res = mount1->is_loopback - mount2->is_loopback; + if (res != 0) + return res; + + return 0; +} + +/** + * g_unix_mount_point_get_mount_path: + * @mount_point: a #GUnixMountPoint. + * + * Gets the mount path for a unix mount point. + * + * Returns: (type filename): a string containing the mount path. + */ +const gchar * +g_unix_mount_point_get_mount_path (GUnixMountPoint *mount_point) +{ + g_return_val_if_fail (mount_point != NULL, NULL); + + return mount_point->mount_path; +} + +/** + * g_unix_mount_point_get_device_path: + * @mount_point: a #GUnixMountPoint. + * + * Gets the device path for a unix mount point. + * + * Returns: (type filename): a string containing the device path. + */ +const gchar * +g_unix_mount_point_get_device_path (GUnixMountPoint *mount_point) +{ + g_return_val_if_fail (mount_point != NULL, NULL); + + return mount_point->device_path; +} + +/** + * g_unix_mount_point_get_fs_type: + * @mount_point: a #GUnixMountPoint. + * + * Gets the file system type for the mount point. + * + * Returns: a string containing the file system type. + */ +const gchar * +g_unix_mount_point_get_fs_type (GUnixMountPoint *mount_point) +{ + g_return_val_if_fail (mount_point != NULL, NULL); + + return mount_point->filesystem_type; +} + +/** + * g_unix_mount_point_get_options: + * @mount_point: a #GUnixMountPoint. + * + * Gets the options for the mount point. + * + * Returns: (nullable): a string containing the options. + * + * Since: 2.32 + */ +const gchar * +g_unix_mount_point_get_options (GUnixMountPoint *mount_point) +{ + g_return_val_if_fail (mount_point != NULL, NULL); + + return mount_point->options; +} + +/** + * g_unix_mount_point_is_readonly: + * @mount_point: a #GUnixMountPoint. + * + * Checks if a unix mount point is read only. + * + * Returns: %TRUE if a mount point is read only. + */ +gboolean +g_unix_mount_point_is_readonly (GUnixMountPoint *mount_point) +{ + g_return_val_if_fail (mount_point != NULL, FALSE); + + return mount_point->is_read_only; +} + +/** + * g_unix_mount_point_is_user_mountable: + * @mount_point: a #GUnixMountPoint. + * + * Checks if a unix mount point is mountable by the user. + * + * Returns: %TRUE if the mount point is user mountable. + */ +gboolean +g_unix_mount_point_is_user_mountable (GUnixMountPoint *mount_point) +{ + g_return_val_if_fail (mount_point != NULL, FALSE); + + return mount_point->is_user_mountable; +} + +/** + * g_unix_mount_point_is_loopback: + * @mount_point: a #GUnixMountPoint. + * + * Checks if a unix mount point is a loopback device. + * + * Returns: %TRUE if the mount point is a loopback. %FALSE otherwise. + */ +gboolean +g_unix_mount_point_is_loopback (GUnixMountPoint *mount_point) +{ + g_return_val_if_fail (mount_point != NULL, FALSE); + + return mount_point->is_loopback; +} + +static GUnixMountType +guess_mount_type (const char *mount_path, + const char *device_path, + const char *filesystem_type) +{ + GUnixMountType type; + char *basename; + + type = G_UNIX_MOUNT_TYPE_UNKNOWN; + + if ((strcmp (filesystem_type, "udf") == 0) || + (strcmp (filesystem_type, "iso9660") == 0) || + (strcmp (filesystem_type, "cd9660") == 0)) + type = G_UNIX_MOUNT_TYPE_CDROM; + else if ((strcmp (filesystem_type, "nfs") == 0) || + (strcmp (filesystem_type, "nfs4") == 0)) + type = G_UNIX_MOUNT_TYPE_NFS; + else if (g_str_has_prefix (device_path, "/vol/dev/diskette/") || + g_str_has_prefix (device_path, "/dev/fd") || + g_str_has_prefix (device_path, "/dev/floppy")) + type = G_UNIX_MOUNT_TYPE_FLOPPY; + else if (g_str_has_prefix (device_path, "/dev/cdrom") || + g_str_has_prefix (device_path, "/dev/acd") || + g_str_has_prefix (device_path, "/dev/cd")) + type = G_UNIX_MOUNT_TYPE_CDROM; + else if (g_str_has_prefix (device_path, "/vol/")) + { + const char *name = mount_path + strlen ("/"); + + if (g_str_has_prefix (name, "cdrom")) + type = G_UNIX_MOUNT_TYPE_CDROM; + else if (g_str_has_prefix (name, "floppy") || + g_str_has_prefix (device_path, "/vol/dev/diskette/")) + type = G_UNIX_MOUNT_TYPE_FLOPPY; + else if (g_str_has_prefix (name, "rmdisk")) + type = G_UNIX_MOUNT_TYPE_ZIP; + else if (g_str_has_prefix (name, "jaz")) + type = G_UNIX_MOUNT_TYPE_JAZ; + else if (g_str_has_prefix (name, "memstick")) + type = G_UNIX_MOUNT_TYPE_MEMSTICK; + } + else + { + basename = g_path_get_basename (mount_path); + + if (g_str_has_prefix (basename, "cdr") || + g_str_has_prefix (basename, "cdwriter") || + g_str_has_prefix (basename, "burn") || + g_str_has_prefix (basename, "dvdr")) + type = G_UNIX_MOUNT_TYPE_CDROM; + else if (g_str_has_prefix (basename, "floppy")) + type = G_UNIX_MOUNT_TYPE_FLOPPY; + else if (g_str_has_prefix (basename, "zip")) + type = G_UNIX_MOUNT_TYPE_ZIP; + else if (g_str_has_prefix (basename, "jaz")) + type = G_UNIX_MOUNT_TYPE_JAZ; + else if (g_str_has_prefix (basename, "camera")) + type = G_UNIX_MOUNT_TYPE_CAMERA; + else if (g_str_has_prefix (basename, "memstick") || + g_str_has_prefix (basename, "memory_stick") || + g_str_has_prefix (basename, "ram")) + type = G_UNIX_MOUNT_TYPE_MEMSTICK; + else if (g_str_has_prefix (basename, "compact_flash")) + type = G_UNIX_MOUNT_TYPE_CF; + else if (g_str_has_prefix (basename, "smart_media")) + type = G_UNIX_MOUNT_TYPE_SM; + else if (g_str_has_prefix (basename, "sd_mmc")) + type = G_UNIX_MOUNT_TYPE_SDMMC; + else if (g_str_has_prefix (basename, "ipod")) + type = G_UNIX_MOUNT_TYPE_IPOD; + + g_free (basename); + } + + if (type == G_UNIX_MOUNT_TYPE_UNKNOWN) + type = G_UNIX_MOUNT_TYPE_HD; + + return type; +} + +/** + * g_unix_mount_guess_type: + * @mount_entry: a #GUnixMount. + * + * Guesses the type of a unix mount. If the mount type cannot be + * determined, returns %G_UNIX_MOUNT_TYPE_UNKNOWN. + * + * Returns: a #GUnixMountType. + */ +static GUnixMountType +g_unix_mount_guess_type (GUnixMountEntry *mount_entry) +{ + g_return_val_if_fail (mount_entry != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN); + g_return_val_if_fail (mount_entry->mount_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN); + g_return_val_if_fail (mount_entry->device_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN); + g_return_val_if_fail (mount_entry->filesystem_type != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN); + + return guess_mount_type (mount_entry->mount_path, + mount_entry->device_path, + mount_entry->filesystem_type); +} + +/** + * g_unix_mount_point_guess_type: + * @mount_point: a #GUnixMountPoint. + * + * Guesses the type of a unix mount point. + * If the mount type cannot be determined, + * returns %G_UNIX_MOUNT_TYPE_UNKNOWN. + * + * Returns: a #GUnixMountType. + */ +static GUnixMountType +g_unix_mount_point_guess_type (GUnixMountPoint *mount_point) +{ + g_return_val_if_fail (mount_point != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN); + g_return_val_if_fail (mount_point->mount_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN); + g_return_val_if_fail (mount_point->device_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN); + g_return_val_if_fail (mount_point->filesystem_type != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN); + + return guess_mount_type (mount_point->mount_path, + mount_point->device_path, + mount_point->filesystem_type); +} + +static const char * +type_to_icon (GUnixMountType type, gboolean is_mount_point, gboolean use_symbolic) +{ + const char *icon_name; + + switch (type) + { + case G_UNIX_MOUNT_TYPE_HD: + if (is_mount_point) + icon_name = use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media"; + else + icon_name = use_symbolic ? "drive-harddisk-symbolic" : "drive-harddisk"; + break; + case G_UNIX_MOUNT_TYPE_FLOPPY: + case G_UNIX_MOUNT_TYPE_ZIP: + case G_UNIX_MOUNT_TYPE_JAZ: + if (is_mount_point) + icon_name = use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media"; + else + icon_name = use_symbolic ? "media-removable-symbolic" : "media-floppy"; + break; + case G_UNIX_MOUNT_TYPE_CDROM: + if (is_mount_point) + icon_name = use_symbolic ? "drive-optical-symbolic" : "drive-optical"; + else + icon_name = use_symbolic ? "media-optical-symbolic" : "media-optical"; + break; + case G_UNIX_MOUNT_TYPE_NFS: + icon_name = use_symbolic ? "folder-remote-symbolic" : "folder-remote"; + break; + case G_UNIX_MOUNT_TYPE_MEMSTICK: + if (is_mount_point) + icon_name = use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media"; + else + icon_name = use_symbolic ? "media-removable-symbolic" : "media-flash"; + break; + case G_UNIX_MOUNT_TYPE_CAMERA: + if (is_mount_point) + icon_name = use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media"; + else + icon_name = use_symbolic ? "camera-photo-symbolic" : "camera-photo"; + break; + case G_UNIX_MOUNT_TYPE_IPOD: + if (is_mount_point) + icon_name = use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media"; + else + icon_name = use_symbolic ? "multimedia-player-symbolic" : "multimedia-player"; + break; + case G_UNIX_MOUNT_TYPE_UNKNOWN: + default: + if (is_mount_point) + icon_name = use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media"; + else + icon_name = use_symbolic ? "drive-harddisk-symbolic" : "drive-harddisk"; + break; + } + + return icon_name; +} + +/** + * g_unix_mount_guess_name: + * @mount_entry: a #GUnixMountEntry + * + * Guesses the name of a Unix mount. + * The result is a translated string. + * + * Returns: A newly allocated string that must + * be freed with g_free() + */ +gchar * +g_unix_mount_guess_name (GUnixMountEntry *mount_entry) +{ + char *name; + + if (strcmp (mount_entry->mount_path, "/") == 0) + name = g_strdup (_("Filesystem root")); + else + name = g_filename_display_basename (mount_entry->mount_path); + + return name; +} + +/** + * g_unix_mount_guess_icon: + * @mount_entry: a #GUnixMountEntry + * + * Guesses the icon of a Unix mount. + * + * Returns: (transfer full): a #GIcon + */ +GIcon * +g_unix_mount_guess_icon (GUnixMountEntry *mount_entry) +{ + return g_themed_icon_new_with_default_fallbacks (type_to_icon (g_unix_mount_guess_type (mount_entry), FALSE, FALSE)); +} + +/** + * g_unix_mount_guess_symbolic_icon: + * @mount_entry: a #GUnixMountEntry + * + * Guesses the symbolic icon of a Unix mount. + * + * Returns: (transfer full): a #GIcon + * + * Since: 2.34 + */ +GIcon * +g_unix_mount_guess_symbolic_icon (GUnixMountEntry *mount_entry) +{ + return g_themed_icon_new_with_default_fallbacks (type_to_icon (g_unix_mount_guess_type (mount_entry), FALSE, TRUE)); +} + +/** + * g_unix_mount_point_guess_name: + * @mount_point: a #GUnixMountPoint + * + * Guesses the name of a Unix mount point. + * The result is a translated string. + * + * Returns: A newly allocated string that must + * be freed with g_free() + */ +gchar * +g_unix_mount_point_guess_name (GUnixMountPoint *mount_point) +{ + char *name; + + if (strcmp (mount_point->mount_path, "/") == 0) + name = g_strdup (_("Filesystem root")); + else + name = g_filename_display_basename (mount_point->mount_path); + + return name; +} + +/** + * g_unix_mount_point_guess_icon: + * @mount_point: a #GUnixMountPoint + * + * Guesses the icon of a Unix mount point. + * + * Returns: (transfer full): a #GIcon + */ +GIcon * +g_unix_mount_point_guess_icon (GUnixMountPoint *mount_point) +{ + return g_themed_icon_new_with_default_fallbacks (type_to_icon (g_unix_mount_point_guess_type (mount_point), TRUE, FALSE)); +} + +/** + * g_unix_mount_point_guess_symbolic_icon: + * @mount_point: a #GUnixMountPoint + * + * Guesses the symbolic icon of a Unix mount point. + * + * Returns: (transfer full): a #GIcon + * + * Since: 2.34 + */ +GIcon * +g_unix_mount_point_guess_symbolic_icon (GUnixMountPoint *mount_point) +{ + return g_themed_icon_new_with_default_fallbacks (type_to_icon (g_unix_mount_point_guess_type (mount_point), TRUE, TRUE)); +} + +/** + * g_unix_mount_guess_can_eject: + * @mount_entry: a #GUnixMountEntry + * + * Guesses whether a Unix mount can be ejected. + * + * Returns: %TRUE if @mount_entry is deemed to be ejectable. + */ +gboolean +g_unix_mount_guess_can_eject (GUnixMountEntry *mount_entry) +{ + GUnixMountType guessed_type; + + guessed_type = g_unix_mount_guess_type (mount_entry); + if (guessed_type == G_UNIX_MOUNT_TYPE_IPOD || + guessed_type == G_UNIX_MOUNT_TYPE_CDROM) + return TRUE; + + return FALSE; +} + +/** + * g_unix_mount_guess_should_display: + * @mount_entry: a #GUnixMountEntry + * + * Guesses whether a Unix mount should be displayed in the UI. + * + * Returns: %TRUE if @mount_entry is deemed to be displayable. + */ +gboolean +g_unix_mount_guess_should_display (GUnixMountEntry *mount_entry) +{ + const char *mount_path; + const gchar *user_name; + gsize user_name_len; + + /* Never display internal mountpoints */ + if (g_unix_mount_is_system_internal (mount_entry)) + return FALSE; + + /* Only display things in /media (which are generally user mountable) + and home dir (fuse stuff) and /run/media/$USER */ + mount_path = mount_entry->mount_path; + if (mount_path != NULL) + { + const gboolean running_as_root = (getuid () == 0); + gboolean is_in_runtime_dir = FALSE; + + /* Hide mounts within a dot path, suppose it was a purpose to hide this mount */ + if (g_strstr_len (mount_path, -1, "/.") != NULL) + return FALSE; + + /* Check /run/media/$USER/. If running as root, display any mounts below + * /run/media/. */ + if (running_as_root) + { + if (strncmp (mount_path, "/run/media/", strlen ("/run/media/")) == 0) + is_in_runtime_dir = TRUE; + } + else + { + user_name = g_get_user_name (); + user_name_len = strlen (user_name); + if (strncmp (mount_path, "/run/media/", strlen ("/run/media/")) == 0 && + strncmp (mount_path + strlen ("/run/media/"), user_name, user_name_len) == 0 && + mount_path[strlen ("/run/media/") + user_name_len] == '/') + is_in_runtime_dir = TRUE; + } + + if (is_in_runtime_dir || g_str_has_prefix (mount_path, "/media/")) + { + char *path; + /* Avoid displaying mounts that are not accessible to the user. + * + * See http://bugzilla.gnome.org/show_bug.cgi?id=526320 for why we + * want to avoid g_access() for mount points which can potentially + * block or fail stat()'ing, such as network mounts. + */ + path = g_path_get_dirname (mount_path); + if (g_str_has_prefix (path, "/media/")) + { + if (g_access (path, R_OK|X_OK) != 0) + { + g_free (path); + return FALSE; + } + } + g_free (path); + + if (mount_entry->device_path && mount_entry->device_path[0] == '/') + { + struct stat st; + if (g_stat (mount_entry->device_path, &st) == 0 && + S_ISBLK(st.st_mode) && + g_access (mount_path, R_OK|X_OK) != 0) + return FALSE; + } + return TRUE; + } + + if (g_str_has_prefix (mount_path, g_get_home_dir ()) && + mount_path[strlen (g_get_home_dir())] == G_DIR_SEPARATOR) + return TRUE; + } + + return FALSE; +} + +/** + * g_unix_mount_point_guess_can_eject: + * @mount_point: a #GUnixMountPoint + * + * Guesses whether a Unix mount point can be ejected. + * + * Returns: %TRUE if @mount_point is deemed to be ejectable. + */ +gboolean +g_unix_mount_point_guess_can_eject (GUnixMountPoint *mount_point) +{ + GUnixMountType guessed_type; + + guessed_type = g_unix_mount_point_guess_type (mount_point); + if (guessed_type == G_UNIX_MOUNT_TYPE_IPOD || + guessed_type == G_UNIX_MOUNT_TYPE_CDROM) + return TRUE; + + return FALSE; +} + +/* Utility functions {{{1 */ + +#ifdef HAVE_MNTENT_H +/* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */ +static void +_canonicalize_filename (gchar *filename) +{ + gchar *p, *q; + gboolean last_was_slash = FALSE; + + p = filename; + q = filename; + + while (*p) + { + if (*p == G_DIR_SEPARATOR) + { + if (!last_was_slash) + *q++ = G_DIR_SEPARATOR; + + last_was_slash = TRUE; + } + else + { + if (last_was_slash && *p == '.') + { + if (*(p + 1) == G_DIR_SEPARATOR || + *(p + 1) == '\0') + { + if (*(p + 1) == '\0') + break; + + p += 1; + } + else if (*(p + 1) == '.' && + (*(p + 2) == G_DIR_SEPARATOR || + *(p + 2) == '\0')) + { + if (q > filename + 1) + { + q--; + while (q > filename + 1 && + *(q - 1) != G_DIR_SEPARATOR) + q--; + } + + if (*(p + 2) == '\0') + break; + + p += 2; + } + else + { + *q++ = *p; + last_was_slash = FALSE; + } + } + else + { + *q++ = *p; + last_was_slash = FALSE; + } + } + + p++; + } + + if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR) + q--; + + *q = '\0'; +} + +static char * +_resolve_symlink (const char *file) +{ + GError *error; + char *dir; + char *link; + char *f; + char *f1; + + f = g_strdup (file); + + while (g_file_test (f, G_FILE_TEST_IS_SYMLINK)) + { + link = g_file_read_link (f, &error); + if (link == NULL) + { + g_error_free (error); + g_free (f); + f = NULL; + goto out; + } + + dir = g_path_get_dirname (f); + f1 = g_strdup_printf ("%s/%s", dir, link); + g_free (dir); + g_free (link); + g_free (f); + f = f1; + } + + out: + if (f != NULL) + _canonicalize_filename (f); + return f; +} + +static const char * +_resolve_dev_root (void) +{ + static gboolean have_real_dev_root = FALSE; + static char real_dev_root[256]; + struct stat statbuf; + + /* see if it's cached already */ + if (have_real_dev_root) + goto found; + + /* otherwise we're going to find it right away.. */ + have_real_dev_root = TRUE; + + if (stat ("/dev/root", &statbuf) == 0) + { + if (! S_ISLNK (statbuf.st_mode)) + { + dev_t root_dev = statbuf.st_dev; + FILE *f; + + /* see if device with similar major:minor as /dev/root is mention + * in /etc/mtab (it usually is) + */ + f = fopen ("/etc/mtab", "r"); + if (f != NULL) + { + struct mntent *entp; +#ifdef HAVE_GETMNTENT_R + struct mntent ent; + char buf[1024]; + while ((entp = getmntent_r (f, &ent, buf, sizeof (buf))) != NULL) + { +#else + G_LOCK (getmntent); + while ((entp = getmntent (f)) != NULL) + { +#endif + if (stat (entp->mnt_fsname, &statbuf) == 0 && + statbuf.st_dev == root_dev) + { + strncpy (real_dev_root, entp->mnt_fsname, sizeof (real_dev_root) - 1); + real_dev_root[sizeof (real_dev_root) - 1] = '\0'; + fclose (f); + goto found; + } + } + + endmntent (f); + +#ifndef HAVE_GETMNTENT_R + G_UNLOCK (getmntent); +#endif + } + + /* no, that didn't work.. next we could scan /dev ... but I digress.. */ + + } + else + { + char *resolved; + resolved = _resolve_symlink ("/dev/root"); + if (resolved != NULL) + { + strncpy (real_dev_root, resolved, sizeof (real_dev_root) - 1); + real_dev_root[sizeof (real_dev_root) - 1] = '\0'; + g_free (resolved); + goto found; + } + } + } + + /* bah sucks.. */ + strcpy (real_dev_root, "/dev/root"); + +found: + return real_dev_root; +} +#endif + +/* Epilogue {{{1 */ +/* vim:set foldmethod=marker: */ diff --git a/gio/gunixmounts.h b/gio/gunixmounts.h new file mode 100644 index 0000000..2553e1c --- /dev/null +++ b/gio/gunixmounts.h @@ -0,0 +1,170 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_UNIX_MOUNTS_H__ +#define __G_UNIX_MOUNTS_H__ + +#include + +G_BEGIN_DECLS + +/** + * GUnixMountEntry: + * + * Defines a Unix mount entry (e.g. /media/cdrom). + * This corresponds roughly to a mtab entry. + **/ +typedef struct _GUnixMountEntry GUnixMountEntry; + +#define G_TYPE_UNIX_MOUNT_ENTRY (g_unix_mount_entry_get_type ()) +GLIB_AVAILABLE_IN_2_54 +GType g_unix_mount_entry_get_type (void) G_GNUC_CONST; + +/** + * GUnixMountPoint: + * + * Defines a Unix mount point (e.g. /dev). + * This corresponds roughly to a fstab entry. + **/ +typedef struct _GUnixMountPoint GUnixMountPoint; + +#define G_TYPE_UNIX_MOUNT_POINT (g_unix_mount_point_get_type ()) +GLIB_AVAILABLE_IN_2_54 +GType g_unix_mount_point_get_type (void) G_GNUC_CONST; + +/** + * GUnixMountMonitor: + * + * Watches #GUnixMounts for changes. + **/ +typedef struct _GUnixMountMonitor GUnixMountMonitor; +typedef struct _GUnixMountMonitorClass GUnixMountMonitorClass; + +#define G_TYPE_UNIX_MOUNT_MONITOR (g_unix_mount_monitor_get_type ()) +#define G_UNIX_MOUNT_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_MOUNT_MONITOR, GUnixMountMonitor)) +#define G_UNIX_MOUNT_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_MOUNT_MONITOR, GUnixMountMonitorClass)) +#define G_IS_UNIX_MOUNT_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_MOUNT_MONITOR)) +#define G_IS_UNIX_MOUNT_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_MOUNT_MONITOR)) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixMountMonitor, g_object_unref) + +GLIB_AVAILABLE_IN_ALL +void g_unix_mount_free (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_2_54 +GUnixMountEntry *g_unix_mount_copy (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +void g_unix_mount_point_free (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_2_54 +GUnixMountPoint *g_unix_mount_point_copy (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +gint g_unix_mount_compare (GUnixMountEntry *mount1, + GUnixMountEntry *mount2); +GLIB_AVAILABLE_IN_ALL +const char * g_unix_mount_get_mount_path (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +const char * g_unix_mount_get_device_path (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_2_60 +const char * g_unix_mount_get_root_path (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +const char * g_unix_mount_get_fs_type (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_2_58 +const char * g_unix_mount_get_options (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_is_readonly (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_is_system_internal (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_guess_can_eject (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_guess_should_display (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +char * g_unix_mount_guess_name (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +GIcon * g_unix_mount_guess_icon (GUnixMountEntry *mount_entry); +GLIB_AVAILABLE_IN_ALL +GIcon * g_unix_mount_guess_symbolic_icon (GUnixMountEntry *mount_entry); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixMountEntry, g_unix_mount_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixMountPoint, g_unix_mount_point_free) + +GLIB_AVAILABLE_IN_ALL +gint g_unix_mount_point_compare (GUnixMountPoint *mount1, + GUnixMountPoint *mount2); +GLIB_AVAILABLE_IN_ALL +const char * g_unix_mount_point_get_mount_path (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +const char * g_unix_mount_point_get_device_path (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +const char * g_unix_mount_point_get_fs_type (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_2_32 +const char * g_unix_mount_point_get_options (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_point_is_readonly (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_point_is_user_mountable (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_point_is_loopback (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_point_guess_can_eject (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +char * g_unix_mount_point_guess_name (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +GIcon * g_unix_mount_point_guess_icon (GUnixMountPoint *mount_point); +GLIB_AVAILABLE_IN_ALL +GIcon * g_unix_mount_point_guess_symbolic_icon (GUnixMountPoint *mount_point); + + +GLIB_AVAILABLE_IN_ALL +GList * g_unix_mount_points_get (guint64 *time_read); +GLIB_AVAILABLE_IN_2_66 +GUnixMountPoint *g_unix_mount_point_at (const char *mount_path, + guint64 *time_read); +GLIB_AVAILABLE_IN_ALL +GList * g_unix_mounts_get (guint64 *time_read); +GLIB_AVAILABLE_IN_ALL +GUnixMountEntry *g_unix_mount_at (const char *mount_path, + guint64 *time_read); +GLIB_AVAILABLE_IN_2_52 +GUnixMountEntry *g_unix_mount_for (const char *file_path, + guint64 *time_read); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mounts_changed_since (guint64 time); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_mount_points_changed_since (guint64 time); + +GLIB_AVAILABLE_IN_ALL +GType g_unix_mount_monitor_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_44 +GUnixMountMonitor *g_unix_mount_monitor_get (void); +GLIB_DEPRECATED_IN_2_44_FOR(g_unix_mount_monitor_get) +GUnixMountMonitor *g_unix_mount_monitor_new (void); +GLIB_DEPRECATED_IN_2_44 +void g_unix_mount_monitor_set_rate_limit (GUnixMountMonitor *mount_monitor, + int limit_msec); + +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_is_mount_path_system_internal (const char *mount_path); +GLIB_AVAILABLE_IN_2_56 +gboolean g_unix_is_system_fs_type (const char *fs_type); +GLIB_AVAILABLE_IN_2_56 +gboolean g_unix_is_system_device_path (const char *device_path); + +G_END_DECLS + +#endif /* __G_UNIX_MOUNTS_H__ */ diff --git a/gio/gunixoutputstream.c b/gio/gunixoutputstream.c new file mode 100644 index 0000000..f4843a8 --- /dev/null +++ b/gio/gunixoutputstream.c @@ -0,0 +1,641 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include "gioerror.h" +#include "gunixoutputstream.h" +#include "gcancellable.h" +#include "gasynchelper.h" +#include "gfiledescriptorbased.h" +#include "glibintl.h" +#include "gioprivate.h" +#include "giounix-private.h" + + +/** + * SECTION:gunixoutputstream + * @short_description: Streaming output operations for UNIX file descriptors + * @include: gio/gunixoutputstream.h + * @see_also: #GOutputStream + * + * #GUnixOutputStream implements #GOutputStream for writing to a UNIX + * file descriptor, including asynchronous operations. (If the file + * descriptor refers to a socket or pipe, this will use poll() to do + * asynchronous I/O. If it refers to a regular file, it will fall back + * to doing asynchronous I/O in another thread.) + * + * Note that `` belongs to the UNIX-specific GIO + * interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config file + * when using it. + */ + +enum { + PROP_0, + PROP_FD, + PROP_CLOSE_FD +}; + +struct _GUnixOutputStreamPrivate { + int fd; + guint close_fd : 1; + guint can_poll : 1; +}; + +static void g_unix_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface); +static void g_unix_output_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GUnixOutputStream, g_unix_output_stream, G_TYPE_OUTPUT_STREAM, + G_ADD_PRIVATE (GUnixOutputStream) + G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, + g_unix_output_stream_pollable_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, + g_unix_output_stream_file_descriptor_based_iface_init) + ) + +static void g_unix_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void g_unix_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static gssize g_unix_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); +static gboolean g_unix_output_stream_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error); +static gboolean g_unix_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error); + +static gboolean g_unix_output_stream_pollable_can_poll (GPollableOutputStream *stream); +static gboolean g_unix_output_stream_pollable_is_writable (GPollableOutputStream *stream); +static GSource *g_unix_output_stream_pollable_create_source (GPollableOutputStream *stream, + GCancellable *cancellable); +static GPollableReturn g_unix_output_stream_pollable_writev_nonblocking (GPollableOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GError **error); + +static void +g_unix_output_stream_class_init (GUnixOutputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass); + + gobject_class->get_property = g_unix_output_stream_get_property; + gobject_class->set_property = g_unix_output_stream_set_property; + + stream_class->write_fn = g_unix_output_stream_write; + stream_class->writev_fn = g_unix_output_stream_writev; + stream_class->close_fn = g_unix_output_stream_close; + + /** + * GUnixOutputStream:fd: + * + * The file descriptor that the stream writes to. + * + * Since: 2.20 + */ + g_object_class_install_property (gobject_class, + PROP_FD, + g_param_spec_int ("fd", + P_("File descriptor"), + P_("The file descriptor to write to"), + G_MININT, G_MAXINT, -1, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + /** + * GUnixOutputStream:close-fd: + * + * Whether to close the file descriptor when the stream is closed. + * + * Since: 2.20 + */ + g_object_class_install_property (gobject_class, + PROP_CLOSE_FD, + g_param_spec_boolean ("close-fd", + P_("Close file descriptor"), + P_("Whether to close the file descriptor when the stream is closed"), + TRUE, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); +} + +static void +g_unix_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface) +{ + iface->can_poll = g_unix_output_stream_pollable_can_poll; + iface->is_writable = g_unix_output_stream_pollable_is_writable; + iface->create_source = g_unix_output_stream_pollable_create_source; + iface->writev_nonblocking = g_unix_output_stream_pollable_writev_nonblocking; +} + +static void +g_unix_output_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface) +{ + iface->get_fd = (int (*) (GFileDescriptorBased *))g_unix_output_stream_get_fd; +} + +static void +g_unix_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GUnixOutputStream *unix_stream; + + unix_stream = G_UNIX_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_FD: + unix_stream->priv->fd = g_value_get_int (value); + unix_stream->priv->can_poll = _g_fd_is_pollable (unix_stream->priv->fd); + break; + case PROP_CLOSE_FD: + unix_stream->priv->close_fd = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_unix_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GUnixOutputStream *unix_stream; + + unix_stream = G_UNIX_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_FD: + g_value_set_int (value, unix_stream->priv->fd); + break; + case PROP_CLOSE_FD: + g_value_set_boolean (value, unix_stream->priv->close_fd); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_unix_output_stream_init (GUnixOutputStream *unix_stream) +{ + unix_stream->priv = g_unix_output_stream_get_instance_private (unix_stream); + unix_stream->priv->fd = -1; + unix_stream->priv->close_fd = TRUE; +} + +/** + * g_unix_output_stream_new: + * @fd: a UNIX file descriptor + * @close_fd: %TRUE to close the file descriptor when done + * + * Creates a new #GUnixOutputStream for the given @fd. + * + * If @close_fd, is %TRUE, the file descriptor will be closed when + * the output stream is destroyed. + * + * Returns: a new #GOutputStream + **/ +GOutputStream * +g_unix_output_stream_new (gint fd, + gboolean close_fd) +{ + GUnixOutputStream *stream; + + g_return_val_if_fail (fd != -1, NULL); + + stream = g_object_new (G_TYPE_UNIX_OUTPUT_STREAM, + "fd", fd, + "close-fd", close_fd, + NULL); + + return G_OUTPUT_STREAM (stream); +} + +/** + * g_unix_output_stream_set_close_fd: + * @stream: a #GUnixOutputStream + * @close_fd: %TRUE to close the file descriptor when done + * + * Sets whether the file descriptor of @stream shall be closed + * when the stream is closed. + * + * Since: 2.20 + */ +void +g_unix_output_stream_set_close_fd (GUnixOutputStream *stream, + gboolean close_fd) +{ + g_return_if_fail (G_IS_UNIX_OUTPUT_STREAM (stream)); + + close_fd = close_fd != FALSE; + if (stream->priv->close_fd != close_fd) + { + stream->priv->close_fd = close_fd; + g_object_notify (G_OBJECT (stream), "close-fd"); + } +} + +/** + * g_unix_output_stream_get_close_fd: + * @stream: a #GUnixOutputStream + * + * Returns whether the file descriptor of @stream will be + * closed when the stream is closed. + * + * Returns: %TRUE if the file descriptor is closed when done + * + * Since: 2.20 + */ +gboolean +g_unix_output_stream_get_close_fd (GUnixOutputStream *stream) +{ + g_return_val_if_fail (G_IS_UNIX_OUTPUT_STREAM (stream), FALSE); + + return stream->priv->close_fd; +} + +/** + * g_unix_output_stream_get_fd: + * @stream: a #GUnixOutputStream + * + * Return the UNIX file descriptor that the stream writes to. + * + * Returns: The file descriptor of @stream + * + * Since: 2.20 + */ +gint +g_unix_output_stream_get_fd (GUnixOutputStream *stream) +{ + g_return_val_if_fail (G_IS_UNIX_OUTPUT_STREAM (stream), -1); + + return stream->priv->fd; +} + +static gssize +g_unix_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GUnixOutputStream *unix_stream; + gssize res = -1; + GPollFD poll_fds[2]; + int nfds = 0; + int poll_ret; + + unix_stream = G_UNIX_OUTPUT_STREAM (stream); + + poll_fds[0].fd = unix_stream->priv->fd; + poll_fds[0].events = G_IO_OUT; + nfds++; + + if (unix_stream->priv->can_poll && + g_cancellable_make_pollfd (cancellable, &poll_fds[1])) + nfds++; + + while (1) + { + int errsv; + + poll_fds[0].revents = poll_fds[1].revents = 0; + do + { + poll_ret = g_poll (poll_fds, nfds, -1); + errsv = errno; + } + while (poll_ret == -1 && errsv == EINTR); + + if (poll_ret == -1) + { + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file descriptor: %s"), + g_strerror (errsv)); + break; + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + break; + + if (!poll_fds[0].revents) + continue; + + res = write (unix_stream->priv->fd, buffer, count); + errsv = errno; + if (res == -1) + { + if (errsv == EINTR || errsv == EAGAIN) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file descriptor: %s"), + g_strerror (errsv)); + } + + break; + } + + if (nfds == 2) + g_cancellable_release_fd (cancellable); + return res; +} + +/* Macro to check if struct iovec and GOutputVector have the same ABI */ +#define G_OUTPUT_VECTOR_IS_IOVEC (sizeof (struct iovec) == sizeof (GOutputVector) && \ + G_SIZEOF_MEMBER (struct iovec, iov_base) == G_SIZEOF_MEMBER (GOutputVector, buffer) && \ + G_STRUCT_OFFSET (struct iovec, iov_base) == G_STRUCT_OFFSET (GOutputVector, buffer) && \ + G_SIZEOF_MEMBER (struct iovec, iov_len) == G_SIZEOF_MEMBER (GOutputVector, size) && \ + G_STRUCT_OFFSET (struct iovec, iov_len) == G_STRUCT_OFFSET (GOutputVector, size)) + +static gboolean +g_unix_output_stream_writev (GOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GCancellable *cancellable, + GError **error) +{ + GUnixOutputStream *unix_stream; + gssize res = -1; + GPollFD poll_fds[2]; + int nfds = 0; + int poll_ret; + struct iovec *iov; + + if (bytes_written) + *bytes_written = 0; + + /* Clamp the number of vectors if more given than we can write in one go. + * The caller has to handle short writes anyway. + */ + if (n_vectors > G_IOV_MAX) + n_vectors = G_IOV_MAX; + + unix_stream = G_UNIX_OUTPUT_STREAM (stream); + + if (G_OUTPUT_VECTOR_IS_IOVEC) + { + /* ABI is compatible */ + iov = (struct iovec *) vectors; + } + else + { + gsize i; + + /* ABI is incompatible */ + iov = g_newa (struct iovec, n_vectors); + for (i = 0; i < n_vectors; i++) + { + iov[i].iov_base = (void *)vectors[i].buffer; + iov[i].iov_len = vectors[i].size; + } + } + + poll_fds[0].fd = unix_stream->priv->fd; + poll_fds[0].events = G_IO_OUT; + nfds++; + + if (unix_stream->priv->can_poll && + g_cancellable_make_pollfd (cancellable, &poll_fds[1])) + nfds++; + + while (1) + { + int errsv; + + poll_fds[0].revents = poll_fds[1].revents = 0; + do + { + poll_ret = g_poll (poll_fds, nfds, -1); + errsv = errno; + } + while (poll_ret == -1 && errsv == EINTR); + + if (poll_ret == -1) + { + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file descriptor: %s"), + g_strerror (errsv)); + break; + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + break; + + if (!poll_fds[0].revents) + continue; + + res = writev (unix_stream->priv->fd, iov, n_vectors); + errsv = errno; + if (res == -1) + { + if (errsv == EINTR || errsv == EAGAIN) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file descriptor: %s"), + g_strerror (errsv)); + } + + if (bytes_written) + *bytes_written = res; + + break; + } + + if (nfds == 2) + g_cancellable_release_fd (cancellable); + return res != -1; +} + +static gboolean +g_unix_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GUnixOutputStream *unix_stream; + int res; + + unix_stream = G_UNIX_OUTPUT_STREAM (stream); + + if (!unix_stream->priv->close_fd) + return TRUE; + + /* This might block during the close. Doesn't seem to be a way to avoid it though. */ + res = close (unix_stream->priv->fd); + if (res == -1) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error closing file descriptor: %s"), + g_strerror (errsv)); + } + + return res != -1; +} + +static gboolean +g_unix_output_stream_pollable_can_poll (GPollableOutputStream *stream) +{ + return G_UNIX_OUTPUT_STREAM (stream)->priv->can_poll; +} + +static gboolean +g_unix_output_stream_pollable_is_writable (GPollableOutputStream *stream) +{ + GUnixOutputStream *unix_stream = G_UNIX_OUTPUT_STREAM (stream); + GPollFD poll_fd; + gint result; + + poll_fd.fd = unix_stream->priv->fd; + poll_fd.events = G_IO_OUT; + poll_fd.revents = 0; + + do + result = g_poll (&poll_fd, 1, 0); + while (result == -1 && errno == EINTR); + + return poll_fd.revents != 0; +} + +static GSource * +g_unix_output_stream_pollable_create_source (GPollableOutputStream *stream, + GCancellable *cancellable) +{ + GUnixOutputStream *unix_stream = G_UNIX_OUTPUT_STREAM (stream); + GSource *inner_source, *cancellable_source, *pollable_source; + + pollable_source = g_pollable_source_new (G_OBJECT (stream)); + + inner_source = g_unix_fd_source_new (unix_stream->priv->fd, G_IO_OUT); + g_source_set_dummy_callback (inner_source); + g_source_add_child_source (pollable_source, inner_source); + g_source_unref (inner_source); + + if (cancellable) + { + cancellable_source = g_cancellable_source_new (cancellable); + g_source_set_dummy_callback (cancellable_source); + g_source_add_child_source (pollable_source, cancellable_source); + g_source_unref (cancellable_source); + } + + return pollable_source; +} + +static GPollableReturn +g_unix_output_stream_pollable_writev_nonblocking (GPollableOutputStream *stream, + const GOutputVector *vectors, + gsize n_vectors, + gsize *bytes_written, + GError **error) +{ + GUnixOutputStream *unix_stream = G_UNIX_OUTPUT_STREAM (stream); + struct iovec *iov; + gssize res = -1; + + if (!g_pollable_output_stream_is_writable (stream)) + { + *bytes_written = 0; + return G_POLLABLE_RETURN_WOULD_BLOCK; + } + + /* Clamp the number of vectors if more given than we can write in one go. + * The caller has to handle short writes anyway. + */ + if (n_vectors > G_IOV_MAX) + n_vectors = G_IOV_MAX; + + if (G_OUTPUT_VECTOR_IS_IOVEC) + { + /* ABI is compatible */ + iov = (struct iovec *) vectors; + } + else + { + gsize i; + + /* ABI is incompatible */ + iov = g_newa (struct iovec, n_vectors); + for (i = 0; i < n_vectors; i++) + { + iov[i].iov_base = (void *)vectors[i].buffer; + iov[i].iov_len = vectors[i].size; + } + } + + while (1) + { + int errsv; + + res = writev (unix_stream->priv->fd, iov, n_vectors); + errsv = errno; + if (res == -1) + { + if (errsv == EINTR) + continue; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error writing to file descriptor: %s"), + g_strerror (errsv)); + } + + if (bytes_written) + *bytes_written = res; + + break; + } + + return res != -1 ? G_POLLABLE_RETURN_OK : G_POLLABLE_RETURN_FAILED; +} diff --git a/gio/gunixoutputstream.h b/gio/gunixoutputstream.h new file mode 100644 index 0000000..2d1d768 --- /dev/null +++ b/gio/gunixoutputstream.h @@ -0,0 +1,82 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_UNIX_OUTPUT_STREAM_H__ +#define __G_UNIX_OUTPUT_STREAM_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_OUTPUT_STREAM (g_unix_output_stream_get_type ()) +#define G_UNIX_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_OUTPUT_STREAM, GUnixOutputStream)) +#define G_UNIX_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_OUTPUT_STREAM, GUnixOutputStreamClass)) +#define G_IS_UNIX_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_OUTPUT_STREAM)) +#define G_IS_UNIX_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_OUTPUT_STREAM)) +#define G_UNIX_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_UNIX_OUTPUT_STREAM, GUnixOutputStreamClass)) + +/** + * GUnixOutputStream: + * + * Implements #GOutputStream for outputting to selectable unix file descriptors + **/ +typedef struct _GUnixOutputStream GUnixOutputStream; +typedef struct _GUnixOutputStreamClass GUnixOutputStreamClass; +typedef struct _GUnixOutputStreamPrivate GUnixOutputStreamPrivate; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixOutputStream, g_object_unref) + +struct _GUnixOutputStream +{ + GOutputStream parent_instance; + + /*< private >*/ + GUnixOutputStreamPrivate *priv; +}; + +struct _GUnixOutputStreamClass +{ + GOutputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_unix_output_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GOutputStream * g_unix_output_stream_new (gint fd, + gboolean close_fd); +GLIB_AVAILABLE_IN_ALL +void g_unix_output_stream_set_close_fd (GUnixOutputStream *stream, + gboolean close_fd); +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_output_stream_get_close_fd (GUnixOutputStream *stream); +GLIB_AVAILABLE_IN_ALL +gint g_unix_output_stream_get_fd (GUnixOutputStream *stream); +G_END_DECLS + +#endif /* __G_UNIX_OUTPUT_STREAM_H__ */ diff --git a/gio/gunixsocketaddress.c b/gio/gunixsocketaddress.c new file mode 100644 index 0000000..f80e8cc --- /dev/null +++ b/gio/gunixsocketaddress.c @@ -0,0 +1,576 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#include +#include +#include + +#include "gunixsocketaddress.h" +#include "gsocketconnectable.h" +#include "glibintl.h" +#include "gnetworking.h" + +#ifdef G_OS_WIN32 +#include "giowin32-afunix.h" +#endif + +/** + * SECTION:gunixsocketaddress + * @short_description: UNIX GSocketAddress + * @include: gio/gunixsocketaddress.h + * + * Support for UNIX-domain (also known as local) sockets. + * + * UNIX domain sockets are generally visible in the filesystem. + * However, some systems support abstract socket names which are not + * visible in the filesystem and not affected by the filesystem + * permissions, visibility, etc. Currently this is only supported + * under Linux. If you attempt to use abstract sockets on other + * systems, function calls may return %G_IO_ERROR_NOT_SUPPORTED + * errors. You can use g_unix_socket_address_abstract_names_supported() + * to see if abstract names are supported. + * + * Since GLib 2.72, #GUnixSocketAddress is available on all platforms. It + * requires underlying system support (such as Windows 10 with `AF_UNIX`) at + * run time. + * + * Before GLib 2.72, `` belonged to the UNIX-specific + * GIO interfaces, thus you had to use the `gio-unix-2.0.pc` pkg-config file + * when using it. This is no longer necessary since GLib 2.72. + */ + +/** + * GUnixSocketAddress: + * + * A UNIX-domain (local) socket address, corresponding to a + * struct sockaddr_un. + */ + +enum +{ + PROP_0, + PROP_PATH, + PROP_PATH_AS_ARRAY, + PROP_ABSTRACT, + PROP_ADDRESS_TYPE +}; + +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX G_SIZEOF_MEMBER (struct sockaddr_un, sun_path) +#endif + +struct _GUnixSocketAddressPrivate +{ + char path[UNIX_PATH_MAX]; /* Not including the initial zero in abstract case, so + we can guarantee zero termination of abstract + pathnames in the get_path() API */ + gsize path_len; /* Not including any terminating zeros */ + GUnixSocketAddressType address_type; +}; + +static void g_unix_socket_address_connectable_iface_init (GSocketConnectableIface *iface); +static gchar *g_unix_socket_address_connectable_to_string (GSocketConnectable *connectable); + +G_DEFINE_TYPE_WITH_CODE (GUnixSocketAddress, g_unix_socket_address, G_TYPE_SOCKET_ADDRESS, + G_ADD_PRIVATE (GUnixSocketAddress) + G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE, + g_unix_socket_address_connectable_iface_init)) + +static void +g_unix_socket_address_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GUnixSocketAddress *address = G_UNIX_SOCKET_ADDRESS (object); + const char *str; + GByteArray *array; + gsize len; + + switch (prop_id) + { + case PROP_PATH: + str = g_value_get_string (value); + if (str) + { + g_strlcpy (address->priv->path, str, + sizeof (address->priv->path)); + address->priv->path_len = strlen (address->priv->path); + } + break; + + case PROP_PATH_AS_ARRAY: + array = g_value_get_boxed (value); + + if (array) + { + /* Clip to fit in UNIX_PATH_MAX with zero termination or first byte */ + len = MIN (array->len, UNIX_PATH_MAX-1); + + if (len != 0) + memcpy (address->priv->path, array->data, len); + + address->priv->path[len] = 0; /* Ensure null-terminated */ + address->priv->path_len = len; + } + break; + + case PROP_ABSTRACT: + /* Only set it if it's not the default... */ + if (g_value_get_boolean (value)) + address->priv->address_type = G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED; + break; + + case PROP_ADDRESS_TYPE: + /* Only set it if it's not the default... */ + if (g_value_get_enum (value) != G_UNIX_SOCKET_ADDRESS_PATH) + address->priv->address_type = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_unix_socket_address_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GUnixSocketAddress *address = G_UNIX_SOCKET_ADDRESS (object); + GByteArray *array; + + switch (prop_id) + { + case PROP_PATH: + g_value_set_string (value, address->priv->path); + break; + + case PROP_PATH_AS_ARRAY: + array = g_byte_array_sized_new (address->priv->path_len); + g_byte_array_append (array, (guint8 *)address->priv->path, address->priv->path_len); + g_value_take_boxed (value, array); + break; + + case PROP_ABSTRACT: + g_value_set_boolean (value, (address->priv->address_type == G_UNIX_SOCKET_ADDRESS_ABSTRACT || + address->priv->address_type == G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED)); + + break; + + case PROP_ADDRESS_TYPE: + g_value_set_enum (value, address->priv->address_type); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static GSocketFamily +g_unix_socket_address_get_family (GSocketAddress *address) +{ + g_assert (PF_UNIX == G_SOCKET_FAMILY_UNIX); + + return G_SOCKET_FAMILY_UNIX; +} + +static gssize +g_unix_socket_address_get_native_size (GSocketAddress *address) +{ + GUnixSocketAddress *addr = G_UNIX_SOCKET_ADDRESS (address); + + switch (addr->priv->address_type) + { + case G_UNIX_SOCKET_ADDRESS_ANONYMOUS: + return G_STRUCT_OFFSET(struct sockaddr_un, sun_path); + case G_UNIX_SOCKET_ADDRESS_ABSTRACT: + return G_STRUCT_OFFSET(struct sockaddr_un, sun_path) + addr->priv->path_len + 1; + default: + return sizeof (struct sockaddr_un); + } +} + +static gboolean +g_unix_socket_address_to_native (GSocketAddress *address, + gpointer dest, + gsize destlen, + GError **error) +{ + GUnixSocketAddress *addr = G_UNIX_SOCKET_ADDRESS (address); + struct sockaddr_un *sock; + gssize socklen; + + socklen = g_unix_socket_address_get_native_size (address); + g_assert (socklen >= 0); + if (destlen < (gsize) socklen) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, + _("Not enough space for socket address")); + return FALSE; + } + + sock = (struct sockaddr_un *) dest; + memset (sock, 0, socklen); + sock->sun_family = AF_UNIX; + + switch (addr->priv->address_type) + { + case G_UNIX_SOCKET_ADDRESS_INVALID: + case G_UNIX_SOCKET_ADDRESS_ANONYMOUS: + break; + + case G_UNIX_SOCKET_ADDRESS_PATH: + strcpy (sock->sun_path, addr->priv->path); + break; + + case G_UNIX_SOCKET_ADDRESS_ABSTRACT: + case G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED: + if (!g_unix_socket_address_abstract_names_supported ()) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Abstract UNIX domain socket addresses not supported on this system")); + return FALSE; + } + + sock->sun_path[0] = 0; + memcpy (sock->sun_path+1, addr->priv->path, addr->priv->path_len); + break; + } + + return TRUE; +} + +static void +g_unix_socket_address_class_init (GUnixSocketAddressClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass); + + gobject_class->set_property = g_unix_socket_address_set_property; + gobject_class->get_property = g_unix_socket_address_get_property; + + gsocketaddress_class->get_family = g_unix_socket_address_get_family; + gsocketaddress_class->to_native = g_unix_socket_address_to_native; + gsocketaddress_class->get_native_size = g_unix_socket_address_get_native_size; + + g_object_class_install_property (gobject_class, + PROP_PATH, + g_param_spec_string ("path", + P_("Path"), + P_("UNIX socket path"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PATH_AS_ARRAY, + g_param_spec_boxed ("path-as-array", + P_("Path array"), + P_("UNIX socket path, as byte array"), + G_TYPE_BYTE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + /** + * GUnixSocketAddress:abstract: + * + * Whether or not this is an abstract address + * + * Deprecated: Use #GUnixSocketAddress:address-type, which + * distinguishes between zero-padded and non-zero-padded + * abstract addresses. + */ + g_object_class_install_property (gobject_class, PROP_ABSTRACT, + g_param_spec_boolean ("abstract", + P_("Abstract"), + P_("Whether or not this is an abstract address"), + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_ADDRESS_TYPE, + g_param_spec_enum ("address-type", + P_("Address type"), + P_("The type of UNIX socket address"), + G_TYPE_UNIX_SOCKET_ADDRESS_TYPE, + G_UNIX_SOCKET_ADDRESS_PATH, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_unix_socket_address_connectable_iface_init (GSocketConnectableIface *iface) +{ + GSocketConnectableIface *parent_iface = g_type_interface_peek_parent (iface); + + iface->enumerate = parent_iface->enumerate; + iface->proxy_enumerate = parent_iface->proxy_enumerate; + iface->to_string = g_unix_socket_address_connectable_to_string; +} + +static gchar * +g_unix_socket_address_connectable_to_string (GSocketConnectable *connectable) +{ + GUnixSocketAddress *ua; + GString *out; + const gchar *path; + gsize path_len, i; + + ua = G_UNIX_SOCKET_ADDRESS (connectable); + + /* Anonymous sockets have no path. */ + if (ua->priv->address_type == G_UNIX_SOCKET_ADDRESS_ANONYMOUS) + return g_strdup ("anonymous"); + + path = g_unix_socket_address_get_path (ua); + path_len = g_unix_socket_address_get_path_len (ua); + out = g_string_sized_new (path_len); + + /* Return the #GUnixSocketAddress:path, but with all non-printable characters + * (including nul bytes) escaped to hex. */ + for (i = 0; i < path_len; i++) + { + guint8 c = path[i]; + + if (g_ascii_isprint (path[i])) + g_string_append_c (out, c); + else + g_string_append_printf (out, "\\x%02x", (guint) c); + } + + return g_string_free (out, FALSE); +} + +static void +g_unix_socket_address_init (GUnixSocketAddress *address) +{ + address->priv = g_unix_socket_address_get_instance_private (address); + + memset (address->priv->path, 0, sizeof (address->priv->path)); + address->priv->path_len = -1; + address->priv->address_type = G_UNIX_SOCKET_ADDRESS_PATH; +} + +/** + * g_unix_socket_address_new: + * @path: the socket path + * + * Creates a new #GUnixSocketAddress for @path. + * + * To create abstract socket addresses, on systems that support that, + * use g_unix_socket_address_new_abstract(). + * + * Returns: a new #GUnixSocketAddress + * + * Since: 2.22 + */ +GSocketAddress * +g_unix_socket_address_new (const gchar *path) +{ + return g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, + "path", path, + "abstract", FALSE, + NULL); +} + +/** + * g_unix_socket_address_new_abstract: + * @path: (array length=path_len) (element-type gchar): the abstract name + * @path_len: the length of @path, or -1 + * + * Creates a new %G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED + * #GUnixSocketAddress for @path. + * + * Returns: a new #GUnixSocketAddress + * + * Deprecated: Use g_unix_socket_address_new_with_type(). + */ +GSocketAddress * +g_unix_socket_address_new_abstract (const gchar *path, + gint path_len) +{ + return g_unix_socket_address_new_with_type (path, path_len, + G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED); +} + +/** + * g_unix_socket_address_new_with_type: + * @path: (array length=path_len) (element-type gchar): the name + * @path_len: the length of @path, or -1 + * @type: a #GUnixSocketAddressType + * + * Creates a new #GUnixSocketAddress of type @type with name @path. + * + * If @type is %G_UNIX_SOCKET_ADDRESS_PATH, this is equivalent to + * calling g_unix_socket_address_new(). + * + * If @type is %G_UNIX_SOCKET_ADDRESS_ANONYMOUS, @path and @path_len will be + * ignored. + * + * If @path_type is %G_UNIX_SOCKET_ADDRESS_ABSTRACT, then @path_len + * bytes of @path will be copied to the socket's path, and only those + * bytes will be considered part of the name. (If @path_len is -1, + * then @path is assumed to be NUL-terminated.) For example, if @path + * was "test", then calling g_socket_address_get_native_size() on the + * returned socket would return 7 (2 bytes of overhead, 1 byte for the + * abstract-socket indicator byte, and 4 bytes for the name "test"). + * + * If @path_type is %G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED, then + * @path_len bytes of @path will be copied to the socket's path, the + * rest of the path will be padded with 0 bytes, and the entire + * zero-padded buffer will be considered the name. (As above, if + * @path_len is -1, then @path is assumed to be NUL-terminated.) In + * this case, g_socket_address_get_native_size() will always return + * the full size of a `struct sockaddr_un`, although + * g_unix_socket_address_get_path_len() will still return just the + * length of @path. + * + * %G_UNIX_SOCKET_ADDRESS_ABSTRACT is preferred over + * %G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED for new programs. Of course, + * when connecting to a server created by another process, you must + * use the appropriate type corresponding to how that process created + * its listening socket. + * + * Returns: a new #GUnixSocketAddress + * + * Since: 2.26 + */ +GSocketAddress * +g_unix_socket_address_new_with_type (const gchar *path, + gint path_len, + GUnixSocketAddressType type) +{ + GSocketAddress *address; + GByteArray *array; + + if (type == G_UNIX_SOCKET_ADDRESS_ANONYMOUS) + path_len = 0; + else if (path_len == -1) + path_len = strlen (path); + + array = g_byte_array_sized_new (path_len); + + g_byte_array_append (array, (guint8 *)path, path_len); + + address = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, + "path-as-array", array, + "address-type", type, + NULL); + + g_byte_array_unref (array); + + return address; +} + +/** + * g_unix_socket_address_get_path: + * @address: a #GInetSocketAddress + * + * Gets @address's path, or for abstract sockets the "name". + * + * Guaranteed to be zero-terminated, but an abstract socket + * may contain embedded zeros, and thus you should use + * g_unix_socket_address_get_path_len() to get the true length + * of this string. + * + * Returns: the path for @address + * + * Since: 2.22 + */ +const char * +g_unix_socket_address_get_path (GUnixSocketAddress *address) +{ + return address->priv->path; +} + +/** + * g_unix_socket_address_get_path_len: + * @address: a #GInetSocketAddress + * + * Gets the length of @address's path. + * + * For details, see g_unix_socket_address_get_path(). + * + * Returns: the length of the path + * + * Since: 2.22 + */ +gsize +g_unix_socket_address_get_path_len (GUnixSocketAddress *address) +{ + return address->priv->path_len; +} + +/** + * g_unix_socket_address_get_address_type: + * @address: a #GInetSocketAddress + * + * Gets @address's type. + * + * Returns: a #GUnixSocketAddressType + * + * Since: 2.26 + */ +GUnixSocketAddressType +g_unix_socket_address_get_address_type (GUnixSocketAddress *address) +{ + return address->priv->address_type; +} + +/** + * g_unix_socket_address_get_is_abstract: + * @address: a #GInetSocketAddress + * + * Tests if @address is abstract. + * + * Returns: %TRUE if the address is abstract, %FALSE otherwise + * + * Since: 2.22 + * + * Deprecated: Use g_unix_socket_address_get_address_type() + */ +gboolean +g_unix_socket_address_get_is_abstract (GUnixSocketAddress *address) +{ + return (address->priv->address_type == G_UNIX_SOCKET_ADDRESS_ABSTRACT || + address->priv->address_type == G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED); +} + +/** + * g_unix_socket_address_abstract_names_supported: + * + * Checks if abstract UNIX domain socket names are supported. + * + * Returns: %TRUE if supported, %FALSE otherwise + * + * Since: 2.22 + */ +gboolean +g_unix_socket_address_abstract_names_supported (void) +{ +#ifdef __linux__ + return TRUE; +#else + return FALSE; +#endif +} diff --git a/gio/gunixsocketaddress.h b/gio/gunixsocketaddress.h new file mode 100644 index 0000000..1c1df14 --- /dev/null +++ b/gio/gunixsocketaddress.h @@ -0,0 +1,81 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#ifndef __G_UNIX_SOCKET_ADDRESS_H__ +#define __G_UNIX_SOCKET_ADDRESS_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_SOCKET_ADDRESS (g_unix_socket_address_get_type ()) +#define G_UNIX_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_SOCKET_ADDRESS, GUnixSocketAddress)) +#define G_UNIX_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_SOCKET_ADDRESS, GUnixSocketAddressClass)) +#define G_IS_UNIX_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_SOCKET_ADDRESS)) +#define G_IS_UNIX_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_SOCKET_ADDRESS)) +#define G_UNIX_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_UNIX_SOCKET_ADDRESS, GUnixSocketAddressClass)) + +typedef struct _GUnixSocketAddress GUnixSocketAddress; +typedef struct _GUnixSocketAddressClass GUnixSocketAddressClass; +typedef struct _GUnixSocketAddressPrivate GUnixSocketAddressPrivate; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixSocketAddress, g_object_unref) + +struct _GUnixSocketAddress +{ + GSocketAddress parent_instance; + + /*< private >*/ + GUnixSocketAddressPrivate *priv; +}; + +struct _GUnixSocketAddressClass +{ + GSocketAddressClass parent_class; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_unix_socket_address_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_unix_socket_address_new (const gchar *path); +GLIB_DEPRECATED_FOR(g_unix_socket_address_new_with_type) +GSocketAddress *g_unix_socket_address_new_abstract (const gchar *path, + gint path_len); +GLIB_AVAILABLE_IN_ALL +GSocketAddress *g_unix_socket_address_new_with_type (const gchar *path, + gint path_len, + GUnixSocketAddressType type); +GLIB_AVAILABLE_IN_ALL +const char * g_unix_socket_address_get_path (GUnixSocketAddress *address); +GLIB_AVAILABLE_IN_ALL +gsize g_unix_socket_address_get_path_len (GUnixSocketAddress *address); +GLIB_AVAILABLE_IN_ALL +GUnixSocketAddressType g_unix_socket_address_get_address_type (GUnixSocketAddress *address); +GLIB_DEPRECATED +gboolean g_unix_socket_address_get_is_abstract (GUnixSocketAddress *address); + +GLIB_AVAILABLE_IN_ALL +gboolean g_unix_socket_address_abstract_names_supported (void); + +G_END_DECLS + +#endif /* __G_UNIX_SOCKET_ADDRESS_H__ */ diff --git a/gio/gunixvolume.c b/gio/gunixvolume.c new file mode 100644 index 0000000..60ae628 --- /dev/null +++ b/gio/gunixvolume.c @@ -0,0 +1,439 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#include "config.h" + +#include +#include +#include + +#include +#include "gunixvolume.h" +#include "gunixmount.h" +#include "gunixmounts.h" +#include "gthemedicon.h" +#include "gvolume.h" +#include "gvolumemonitor.h" +#include "gtask.h" +#include "gioerror.h" +#include "glibintl.h" +/* for BUFSIZ */ +#include + + +struct _GUnixVolume { + GObject parent; + + GVolumeMonitor *volume_monitor; + GUnixMount *mount; /* owned by volume monitor */ + + char *device_path; + char *mount_path; + gboolean can_eject; + + char *identifier; + char *identifier_type; + + char *name; + GIcon *icon; + GIcon *symbolic_icon; +}; + +static void g_unix_volume_volume_iface_init (GVolumeIface *iface); + +#define g_unix_volume_get_type _g_unix_volume_get_type +G_DEFINE_TYPE_WITH_CODE (GUnixVolume, g_unix_volume, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME, + g_unix_volume_volume_iface_init)) + +static void +g_unix_volume_finalize (GObject *object) +{ + GUnixVolume *volume; + + volume = G_UNIX_VOLUME (object); + + if (volume->volume_monitor != NULL) + g_object_unref (volume->volume_monitor); + + if (volume->mount) + _g_unix_mount_unset_volume (volume->mount, volume); + + g_object_unref (volume->icon); + g_object_unref (volume->symbolic_icon); + g_free (volume->name); + g_free (volume->mount_path); + g_free (volume->device_path); + g_free (volume->identifier); + g_free (volume->identifier_type); + + G_OBJECT_CLASS (g_unix_volume_parent_class)->finalize (object); +} + +static void +g_unix_volume_class_init (GUnixVolumeClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_unix_volume_finalize; +} + +static void +g_unix_volume_init (GUnixVolume *unix_volume) +{ +} + +GUnixVolume * +_g_unix_volume_new (GVolumeMonitor *volume_monitor, + GUnixMountPoint *mountpoint) +{ + GUnixVolume *volume; + + if (!(g_unix_mount_point_is_user_mountable (mountpoint) || + g_str_has_prefix (g_unix_mount_point_get_device_path (mountpoint), "/vol/")) || + g_unix_mount_point_is_loopback (mountpoint)) + return NULL; + + volume = g_object_new (G_TYPE_UNIX_VOLUME, NULL); + volume->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL; + volume->mount_path = g_strdup (g_unix_mount_point_get_mount_path (mountpoint)); + volume->device_path = g_strdup (g_unix_mount_point_get_device_path (mountpoint)); + volume->can_eject = g_unix_mount_point_guess_can_eject (mountpoint); + + volume->name = g_unix_mount_point_guess_name (mountpoint); + volume->icon = g_unix_mount_point_guess_icon (mountpoint); + volume->symbolic_icon = g_unix_mount_point_guess_symbolic_icon (mountpoint); + + + if (strcmp (g_unix_mount_point_get_fs_type (mountpoint), "nfs") == 0) + { + volume->identifier_type = g_strdup (G_VOLUME_IDENTIFIER_KIND_NFS_MOUNT); + volume->identifier = g_strdup (volume->device_path); + } + else if (g_str_has_prefix (volume->device_path, "LABEL=")) + { + volume->identifier_type = g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL); + volume->identifier = g_strdup (volume->device_path + 6); + } + else if (g_str_has_prefix (volume->device_path, "UUID=")) + { + volume->identifier_type = g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID); + volume->identifier = g_strdup (volume->device_path + 5); + } + else if (g_path_is_absolute (volume->device_path)) + { + volume->identifier_type = g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); + volume->identifier = g_strdup (volume->device_path); + } + + return volume; +} + +void +_g_unix_volume_disconnected (GUnixVolume *volume) +{ + if (volume->mount) + { + _g_unix_mount_unset_volume (volume->mount, volume); + volume->mount = NULL; + } +} + +void +_g_unix_volume_set_mount (GUnixVolume *volume, + GUnixMount *mount) +{ + if (volume->mount == mount) + return; + + if (volume->mount) + _g_unix_mount_unset_volume (volume->mount, volume); + + volume->mount = mount; + + /* TODO: Emit changed in idle to avoid locking issues */ + g_signal_emit_by_name (volume, "changed"); + if (volume->volume_monitor != NULL) + g_signal_emit_by_name (volume->volume_monitor, "volume-changed", volume); +} + +void +_g_unix_volume_unset_mount (GUnixVolume *volume, + GUnixMount *mount) +{ + if (volume->mount == mount) + { + volume->mount = NULL; + /* TODO: Emit changed in idle to avoid locking issues */ + g_signal_emit_by_name (volume, "changed"); + if (volume->volume_monitor != NULL) + g_signal_emit_by_name (volume->volume_monitor, "volume-changed", volume); + } +} + +static GIcon * +g_unix_volume_get_icon (GVolume *volume) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + return g_object_ref (unix_volume->icon); +} + +static GIcon * +g_unix_volume_get_symbolic_icon (GVolume *volume) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + return g_object_ref (unix_volume->symbolic_icon); +} + +static char * +g_unix_volume_get_name (GVolume *volume) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + return g_strdup (unix_volume->name); +} + +static char * +g_unix_volume_get_uuid (GVolume *volume) +{ + return NULL; +} + +static gboolean +g_unix_volume_can_mount (GVolume *volume) +{ + return TRUE; +} + +static gboolean +g_unix_volume_can_eject (GVolume *volume) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + return unix_volume->can_eject; +} + +static gboolean +g_unix_volume_should_automount (GVolume *volume) +{ + /* We automount all local volumes because we don't even + * make the internal stuff visible + */ + return TRUE; +} + +static GDrive * +g_unix_volume_get_drive (GVolume *volume) +{ + return NULL; +} + +static GMount * +g_unix_volume_get_mount (GVolume *volume) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + + if (unix_volume->mount != NULL) + return g_object_ref (G_MOUNT (unix_volume->mount)); + + return NULL; +} + + +gboolean +_g_unix_volume_has_mount_path (GUnixVolume *volume, + const char *mount_path) +{ + return strcmp (volume->mount_path, mount_path) == 0; +} + +static void +eject_mount_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSubprocess *subprocess = G_SUBPROCESS (source); + GTask *task = user_data; + GError *error = NULL; + gchar *stderr_str; + GUnixVolume *unix_volume; + + if (!g_subprocess_communicate_utf8_finish (subprocess, result, NULL, &stderr_str, &error)) + { + g_task_return_error (task, error); + g_error_free (error); + } + else /* successful communication */ + { + if (!g_subprocess_get_successful (subprocess)) + /* ...but bad exit code */ + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", stderr_str); + else + { + /* ...and successful exit code */ + unix_volume = G_UNIX_VOLUME (g_task_get_source_object (task)); + _g_unix_volume_monitor_update (G_UNIX_VOLUME_MONITOR (unix_volume->volume_monitor)); + g_task_return_boolean (task, TRUE); + } + + g_free (stderr_str); + } + + g_object_unref (task); +} + +static void +eject_mount_do (GVolume *volume, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + const gchar * const *argv, + const gchar *task_name) +{ + GSubprocess *subprocess; + GError *error = NULL; + GTask *task; + + task = g_task_new (volume, cancellable, callback, user_data); + g_task_set_source_tag (task, eject_mount_do); + g_task_set_name (task, task_name); + + if (g_task_return_error_if_cancelled (task)) + { + g_object_unref (task); + return; + } + + subprocess = g_subprocess_newv (argv, G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_PIPE, &error); + g_assert_no_error (error); + + g_subprocess_communicate_utf8_async (subprocess, NULL, + g_task_get_cancellable (task), + eject_mount_done, task); +} + +static void +g_unix_volume_mount (GVolume *volume, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + const gchar *argv[] = { "mount", NULL, NULL }; + + if (unix_volume->mount_path != NULL) + argv[1] = unix_volume->mount_path; + else + argv[1] = unix_volume->device_path; + + eject_mount_do (volume, cancellable, callback, user_data, argv, "[gio] mount volume"); +} + +static gboolean +g_unix_volume_mount_finish (GVolume *volume, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, volume), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +g_unix_volume_eject (GVolume *volume, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + const gchar *argv[] = { "eject", NULL, NULL }; + + argv[1] = unix_volume->device_path; + + eject_mount_do (volume, cancellable, callback, user_data, argv, "[gio] eject volume"); +} + +static gboolean +g_unix_volume_eject_finish (GVolume *volume, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, volume), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static gchar * +g_unix_volume_get_identifier (GVolume *volume, + const gchar *kind) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + + if (unix_volume->identifier_type != NULL && + strcmp (kind, unix_volume->identifier_type) == 0) + return g_strdup (unix_volume->identifier); + + return NULL; +} + +static gchar ** +g_unix_volume_enumerate_identifiers (GVolume *volume) +{ + GUnixVolume *unix_volume = G_UNIX_VOLUME (volume); + gchar **res; + + if (unix_volume->identifier_type) + { + res = g_new (gchar *, 2); + res[0] = g_strdup (unix_volume->identifier_type); + res[1] = NULL; + } + else + { + res = g_new (gchar *, 1); + res[0] = NULL; + } + + return res; +} + +static void +g_unix_volume_volume_iface_init (GVolumeIface *iface) +{ + iface->get_name = g_unix_volume_get_name; + iface->get_icon = g_unix_volume_get_icon; + iface->get_symbolic_icon = g_unix_volume_get_symbolic_icon; + iface->get_uuid = g_unix_volume_get_uuid; + iface->get_drive = g_unix_volume_get_drive; + iface->get_mount = g_unix_volume_get_mount; + iface->can_mount = g_unix_volume_can_mount; + iface->can_eject = g_unix_volume_can_eject; + iface->should_automount = g_unix_volume_should_automount; + iface->mount_fn = g_unix_volume_mount; + iface->mount_finish = g_unix_volume_mount_finish; + iface->eject = g_unix_volume_eject; + iface->eject_finish = g_unix_volume_eject_finish; + iface->get_identifier = g_unix_volume_get_identifier; + iface->enumerate_identifiers = g_unix_volume_enumerate_identifiers; +} diff --git a/gio/gunixvolume.h b/gio/gunixvolume.h new file mode 100644 index 0000000..e7b4615 --- /dev/null +++ b/gio/gunixvolume.h @@ -0,0 +1,59 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#ifndef __G_UNIX_VOLUME_H__ +#define __G_UNIX_VOLUME_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_VOLUME (_g_unix_volume_get_type ()) +#define G_UNIX_VOLUME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_VOLUME, GUnixVolume)) +#define G_UNIX_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_VOLUME, GUnixVolumeClass)) +#define G_IS_UNIX_VOLUME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_VOLUME)) +#define G_IS_UNIX_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_VOLUME)) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixVolume, g_object_unref) + +typedef struct _GUnixVolumeClass GUnixVolumeClass; + +struct _GUnixVolumeClass +{ + GObjectClass parent_class; +}; + +GType _g_unix_volume_get_type (void) G_GNUC_CONST; + +GUnixVolume * _g_unix_volume_new (GVolumeMonitor *volume_monitor, + GUnixMountPoint *mountpoint); +gboolean _g_unix_volume_has_mount_path (GUnixVolume *volume, + const char *mount_path); +void _g_unix_volume_set_mount (GUnixVolume *volume, + GUnixMount *mount); +void _g_unix_volume_unset_mount (GUnixVolume *volume, + GUnixMount *mount); +void _g_unix_volume_disconnected (GUnixVolume *volume); + +G_END_DECLS + +#endif /* __G_UNIX_VOLUME_H__ */ diff --git a/gio/gunixvolumemonitor.c b/gio/gunixvolumemonitor.c new file mode 100644 index 0000000..4b99423 --- /dev/null +++ b/gio/gunixvolumemonitor.c @@ -0,0 +1,419 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#include "config.h" + +#include + +#include +#include "gunixvolumemonitor.h" +#include "gunixmounts.h" +#include "gunixmount.h" +#include "gunixvolume.h" +#include "gmount.h" +#include "gmountprivate.h" +#include "giomodule.h" +#include "glibintl.h" + + +struct _GUnixVolumeMonitor { + GNativeVolumeMonitor parent; + + GUnixMountMonitor *mount_monitor; + + GList *last_mountpoints; + GList *last_mounts; + + GList *volumes; + GList *mounts; +}; + +static void mountpoints_changed (GUnixMountMonitor *mount_monitor, + gpointer user_data); +static void mounts_changed (GUnixMountMonitor *mount_monitor, + gpointer user_data); +static void update_volumes (GUnixVolumeMonitor *monitor); +static void update_mounts (GUnixVolumeMonitor *monitor); + +#define g_unix_volume_monitor_get_type _g_unix_volume_monitor_get_type +G_DEFINE_TYPE_WITH_CODE (GUnixVolumeMonitor, g_unix_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR, + g_io_extension_point_implement (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "unix", + 0)); + +static void +g_unix_volume_monitor_finalize (GObject *object) +{ + GUnixVolumeMonitor *monitor; + + monitor = G_UNIX_VOLUME_MONITOR (object); + + g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mountpoints_changed, monitor); + g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mounts_changed, monitor); + + g_object_unref (monitor->mount_monitor); + + g_list_free_full (monitor->last_mountpoints, (GDestroyNotify) g_unix_mount_point_free); + g_list_free_full (monitor->last_mounts, (GDestroyNotify) g_unix_mount_free); + + g_list_free_full (monitor->volumes, g_object_unref); + g_list_free_full (monitor->mounts, g_object_unref); + + G_OBJECT_CLASS (g_unix_volume_monitor_parent_class)->finalize (object); +} + +static void +g_unix_volume_monitor_dispose (GObject *object) +{ + GUnixVolumeMonitor *monitor; + + monitor = G_UNIX_VOLUME_MONITOR (object); + + g_list_free_full (monitor->volumes, g_object_unref); + monitor->volumes = NULL; + + g_list_free_full (monitor->mounts, g_object_unref); + monitor->mounts = NULL; + + G_OBJECT_CLASS (g_unix_volume_monitor_parent_class)->dispose (object); +} + +static GList * +get_mounts (GVolumeMonitor *volume_monitor) +{ + GUnixVolumeMonitor *monitor; + + monitor = G_UNIX_VOLUME_MONITOR (volume_monitor); + + return g_list_copy_deep (monitor->mounts, (GCopyFunc) g_object_ref, NULL); +} + +static GList * +get_volumes (GVolumeMonitor *volume_monitor) +{ + GUnixVolumeMonitor *monitor; + + monitor = G_UNIX_VOLUME_MONITOR (volume_monitor); + + return g_list_copy_deep (monitor->volumes, (GCopyFunc) g_object_ref, NULL); +} + +static GList * +get_connected_drives (GVolumeMonitor *volume_monitor) +{ + return NULL; +} + +static GVolume * +get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + return NULL; +} + +static GMount * +get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + return NULL; +} + +static gboolean +is_supported (void) +{ + return TRUE; +} + +static GMount * +get_mount_for_mount_path (const char *mount_path, + GCancellable *cancellable) +{ + GUnixMountEntry *mount_entry; + GUnixMount *mount; + + mount_entry = g_unix_mount_at (mount_path, NULL); + + if (!mount_entry) + return NULL; + + /* TODO: Set mountable volume? */ + mount = _g_unix_mount_new (NULL, mount_entry, NULL); + + g_unix_mount_free (mount_entry); + + return G_MOUNT (mount); +} + +static void +g_unix_volume_monitor_class_init (GUnixVolumeMonitorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass); + GNativeVolumeMonitorClass *native_class = G_NATIVE_VOLUME_MONITOR_CLASS (klass); + + gobject_class->finalize = g_unix_volume_monitor_finalize; + gobject_class->dispose = g_unix_volume_monitor_dispose; + + monitor_class->get_mounts = get_mounts; + monitor_class->get_volumes = get_volumes; + monitor_class->get_connected_drives = get_connected_drives; + monitor_class->get_volume_for_uuid = get_volume_for_uuid; + monitor_class->get_mount_for_uuid = get_mount_for_uuid; + monitor_class->is_supported = is_supported; + + native_class->get_mount_for_mount_path = get_mount_for_mount_path; +} + +void +_g_unix_volume_monitor_update (GUnixVolumeMonitor *unix_monitor) +{ + /* Update both to make sure volumes are created before mounts */ + update_volumes (unix_monitor); + update_mounts (unix_monitor); +} + +static void +mountpoints_changed (GUnixMountMonitor *mount_monitor, + gpointer user_data) +{ + GUnixVolumeMonitor *unix_monitor = user_data; + + _g_unix_volume_monitor_update (unix_monitor); +} + +static void +mounts_changed (GUnixMountMonitor *mount_monitor, + gpointer user_data) +{ + GUnixVolumeMonitor *unix_monitor = user_data; + + _g_unix_volume_monitor_update (unix_monitor); +} + +static void +g_unix_volume_monitor_init (GUnixVolumeMonitor *unix_monitor) +{ + + unix_monitor->mount_monitor = g_unix_mount_monitor_get (); + + g_signal_connect (unix_monitor->mount_monitor, + "mounts-changed", G_CALLBACK (mounts_changed), + unix_monitor); + + g_signal_connect (unix_monitor->mount_monitor, + "mountpoints-changed", G_CALLBACK (mountpoints_changed), + unix_monitor); + + _g_unix_volume_monitor_update (unix_monitor); +} + +GVolumeMonitor * +_g_unix_volume_monitor_new (void) +{ + GUnixVolumeMonitor *monitor; + + monitor = g_object_new (G_TYPE_UNIX_VOLUME_MONITOR, NULL); + + return G_VOLUME_MONITOR (monitor); +} + +static void +diff_sorted_lists (GList *list1, + GList *list2, + GCompareFunc compare, + GList **added, + GList **removed) +{ + int order; + + *added = *removed = NULL; + + while (list1 != NULL && + list2 != NULL) + { + order = (*compare) (list1->data, list2->data); + if (order < 0) + { + *removed = g_list_prepend (*removed, list1->data); + list1 = list1->next; + } + else if (order > 0) + { + *added = g_list_prepend (*added, list2->data); + list2 = list2->next; + } + else + { /* same item */ + list1 = list1->next; + list2 = list2->next; + } + } + + while (list1 != NULL) + { + *removed = g_list_prepend (*removed, list1->data); + list1 = list1->next; + } + while (list2 != NULL) + { + *added = g_list_prepend (*added, list2->data); + list2 = list2->next; + } +} + +GUnixVolume * +_g_unix_volume_monitor_lookup_volume_for_mount_path (GUnixVolumeMonitor *monitor, + const char *mount_path) +{ + GList *l; + + for (l = monitor->volumes; l != NULL; l = l->next) + { + GUnixVolume *volume = l->data; + + if (_g_unix_volume_has_mount_path (volume, mount_path)) + return volume; + } + + return NULL; +} + +static GUnixMount * +find_mount_by_mountpath (GUnixVolumeMonitor *monitor, + const char *mount_path) +{ + GList *l; + + for (l = monitor->mounts; l != NULL; l = l->next) + { + GUnixMount *mount = l->data; + + if (_g_unix_mount_has_mount_path (mount, mount_path)) + return mount; + } + + return NULL; +} + +static void +update_volumes (GUnixVolumeMonitor *monitor) +{ + GList *new_mountpoints; + GList *removed, *added; + GList *l; + GUnixVolume *volume; + + new_mountpoints = g_unix_mount_points_get (NULL); + + new_mountpoints = g_list_sort (new_mountpoints, (GCompareFunc) g_unix_mount_point_compare); + + diff_sorted_lists (monitor->last_mountpoints, + new_mountpoints, (GCompareFunc) g_unix_mount_point_compare, + &added, &removed); + + for (l = removed; l != NULL; l = l->next) + { + GUnixMountPoint *mountpoint = l->data; + + volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, + g_unix_mount_point_get_mount_path (mountpoint)); + if (volume) + { + _g_unix_volume_disconnected (volume); + monitor->volumes = g_list_remove (monitor->volumes, volume); + g_signal_emit_by_name (monitor, "volume-removed", volume); + g_signal_emit_by_name (volume, "removed"); + g_object_unref (volume); + } + } + + for (l = added; l != NULL; l = l->next) + { + GUnixMountPoint *mountpoint = l->data; + + volume = _g_unix_volume_new (G_VOLUME_MONITOR (monitor), mountpoint); + if (volume) + { + monitor->volumes = g_list_prepend (monitor->volumes, volume); + g_signal_emit_by_name (monitor, "volume-added", volume); + } + } + + g_list_free (added); + g_list_free (removed); + g_list_free_full (monitor->last_mountpoints, (GDestroyNotify) g_unix_mount_point_free); + monitor->last_mountpoints = new_mountpoints; +} + +static void +update_mounts (GUnixVolumeMonitor *monitor) +{ + GList *new_mounts; + GList *removed, *added; + GList *l; + GUnixMount *mount; + GUnixVolume *volume; + const char *mount_path; + + new_mounts = g_unix_mounts_get (NULL); + + new_mounts = g_list_sort (new_mounts, (GCompareFunc) g_unix_mount_compare); + + diff_sorted_lists (monitor->last_mounts, + new_mounts, (GCompareFunc) g_unix_mount_compare, + &added, &removed); + + for (l = removed; l != NULL; l = l->next) + { + GUnixMountEntry *mount_entry = l->data; + + mount = find_mount_by_mountpath (monitor, g_unix_mount_get_mount_path (mount_entry)); + if (mount) + { + _g_unix_mount_unmounted (mount); + monitor->mounts = g_list_remove (monitor->mounts, mount); + g_signal_emit_by_name (monitor, "mount-removed", mount); + g_signal_emit_by_name (mount, "unmounted"); + g_object_unref (mount); + } + } + + for (l = added; l != NULL; l = l->next) + { + GUnixMountEntry *mount_entry = l->data; + + mount_path = g_unix_mount_get_mount_path (mount_entry); + + volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, mount_path); + mount = _g_unix_mount_new (G_VOLUME_MONITOR (monitor), mount_entry, volume); + if (mount) + { + monitor->mounts = g_list_prepend (monitor->mounts, mount); + g_signal_emit_by_name (monitor, "mount-added", mount); + } + } + + g_list_free (added); + g_list_free (removed); + g_list_free_full (monitor->last_mounts, (GDestroyNotify) g_unix_mount_free); + monitor->last_mounts = new_mounts; +} diff --git a/gio/gunixvolumemonitor.h b/gio/gunixvolumemonitor.h new file mode 100644 index 0000000..14e07fb --- /dev/null +++ b/gio/gunixvolumemonitor.h @@ -0,0 +1,62 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#ifndef __G_UNIX_VOLUME_MONITOR_H__ +#define __G_UNIX_VOLUME_MONITOR_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_UNIX_VOLUME_MONITOR (_g_unix_volume_monitor_get_type ()) +#define G_UNIX_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_VOLUME_MONITOR, GUnixVolumeMonitor)) +#define G_UNIX_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_VOLUME_MONITOR, GUnixVolumeMonitorClass)) +#define G_IS_UNIX_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_VOLUME_MONITOR)) +#define G_IS_UNIX_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_VOLUME_MONITOR)) + +typedef struct _GUnixVolumeMonitor GUnixVolumeMonitor; +typedef struct _GUnixVolumeMonitorClass GUnixVolumeMonitorClass; + +/* Forward definitions */ + +/** + * GUnixMount: + * + * Implementation of the #GMount interface for Unix systems. + */ +typedef struct _GUnixMount GUnixMount; +typedef struct _GUnixVolume GUnixVolume; + +struct _GUnixVolumeMonitorClass +{ + GNativeVolumeMonitorClass parent_class; +}; + +GType _g_unix_volume_monitor_get_type (void) G_GNUC_CONST; + +GVolumeMonitor * _g_unix_volume_monitor_new (void); +GUnixVolume * _g_unix_volume_monitor_lookup_volume_for_mount_path (GUnixVolumeMonitor *monitor, + const char *mount_path); +void _g_unix_volume_monitor_update (GUnixVolumeMonitor *monitor); + +G_END_DECLS + +#endif /* __G_UNIX_VOLUME_MONITOR_H__ */ diff --git a/gio/gvdb/gvdb-builder.c b/gio/gvdb/gvdb-builder.c new file mode 100644 index 0000000..64d8201 --- /dev/null +++ b/gio/gvdb/gvdb-builder.c @@ -0,0 +1,636 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "gvdb-builder.h" +#include "gvdb-format.h" + +#include +#include +#if !defined(G_OS_WIN32) || !defined(_MSC_VER) +#include +#endif +#include + + +struct _GvdbItem +{ + gchar *key; + guint32 hash_value; + guint32_le assigned_index; + GvdbItem *parent; + GvdbItem *sibling; + GvdbItem *next; + + /* one of: + * this: + */ + GVariant *value; + + /* this: */ + GHashTable *table; + + /* or this: */ + GvdbItem *child; +}; + +static void +gvdb_item_free (gpointer data) +{ + GvdbItem *item = data; + + g_free (item->key); + + if (item->value) + g_variant_unref (item->value); + + if (item->table) + g_hash_table_unref (item->table); + + g_slice_free (GvdbItem, item); +} + +GHashTable * +gvdb_hash_table_new (GHashTable *parent, + const gchar *name_in_parent) +{ + GHashTable *table; + + table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, gvdb_item_free); + + if (parent) + { + GvdbItem *item; + + item = gvdb_hash_table_insert (parent, name_in_parent); + gvdb_item_set_hash_table (item, table); + } + + return table; +} + +static guint32 +djb_hash (const gchar *key) +{ + guint32 hash_value = 5381; + + while (*key) + hash_value = hash_value * 33 + *(signed char *)key++; + + return hash_value; +} + +GvdbItem * +gvdb_hash_table_insert (GHashTable *table, + const gchar *key) +{ + GvdbItem *item; + + item = g_slice_new0 (GvdbItem); + item->key = g_strdup (key); + item->hash_value = djb_hash (key); + + g_hash_table_insert (table, g_strdup (key), item); + + return item; +} + +void +gvdb_hash_table_insert_string (GHashTable *table, + const gchar *key, + const gchar *value) +{ + GvdbItem *item; + + item = gvdb_hash_table_insert (table, key); + gvdb_item_set_value (item, g_variant_new_string (value)); +} + +void +gvdb_item_set_value (GvdbItem *item, + GVariant *value) +{ + g_return_if_fail (!item->value && !item->table && !item->child); + + item->value = g_variant_ref_sink (value); +} + +void +gvdb_item_set_hash_table (GvdbItem *item, + GHashTable *table) +{ + g_return_if_fail (!item->value && !item->table && !item->child); + + item->table = g_hash_table_ref (table); +} + +void +gvdb_item_set_parent (GvdbItem *item, + GvdbItem *parent) +{ + GvdbItem **node; + + g_return_if_fail (g_str_has_prefix (item->key, parent->key)); + g_return_if_fail (!parent->value && !parent->table); + g_return_if_fail (!item->parent && !item->sibling); + + for (node = &parent->child; *node; node = &(*node)->sibling) + if (strcmp ((*node)->key, item->key) > 0) + break; + + item->parent = parent; + item->sibling = *node; + *node = item; +} + +typedef struct +{ + GvdbItem **buckets; + gint n_buckets; +} HashTable; + +static HashTable * +hash_table_new (gint n_buckets) +{ + HashTable *table; + + table = g_slice_new (HashTable); + table->buckets = g_new0 (GvdbItem *, n_buckets); + table->n_buckets = n_buckets; + + return table; +} + +static void +hash_table_free (HashTable *table) +{ + g_free (table->buckets); + + g_slice_free (HashTable, table); +} + +static void +hash_table_insert (gpointer key, + gpointer value, + gpointer data) +{ + guint32 hash_value, bucket; + HashTable *table = data; + GvdbItem *item = value; + + hash_value = djb_hash (key); + bucket = hash_value % table->n_buckets; + item->next = table->buckets[bucket]; + table->buckets[bucket] = item; +} + +static guint32_le +item_to_index (GvdbItem *item) +{ + if (item != NULL) + return item->assigned_index; + + return guint32_to_le ((guint32) -1); +} + +typedef struct +{ + GQueue *chunks; + guint64 offset; + gboolean byteswap; +} FileBuilder; + +typedef struct +{ + gsize offset; + gsize size; + gpointer data; +} FileChunk; + +static gpointer +file_builder_allocate (FileBuilder *fb, + guint alignment, + gsize size, + struct gvdb_pointer *pointer) +{ + FileChunk *chunk; + + if (size == 0) + return NULL; + + fb->offset += (guint64) (-fb->offset) & (alignment - 1); + chunk = g_slice_new (FileChunk); + chunk->offset = fb->offset; + chunk->size = size; + chunk->data = g_malloc (size); + + pointer->start = guint32_to_le (fb->offset); + fb->offset += size; + pointer->end = guint32_to_le (fb->offset); + + g_queue_push_tail (fb->chunks, chunk); + + return chunk->data; +} + +static void +file_builder_add_value (FileBuilder *fb, + GVariant *value, + struct gvdb_pointer *pointer) +{ + GVariant *variant, *normal; + gpointer data; + gsize size; + + if (fb->byteswap) + { + value = g_variant_byteswap (value); + variant = g_variant_new_variant (value); + g_variant_unref (value); + } + else + variant = g_variant_new_variant (value); + + normal = g_variant_get_normal_form (variant); + g_variant_unref (variant); + + size = g_variant_get_size (normal); + data = file_builder_allocate (fb, 8, size, pointer); + g_variant_store (normal, data); + g_variant_unref (normal); +} + +static void +file_builder_add_string (FileBuilder *fb, + const gchar *string, + guint32_le *start, + guint16_le *size) +{ + FileChunk *chunk; + gsize length; + + length = strlen (string); + + chunk = g_slice_new (FileChunk); + chunk->offset = fb->offset; + chunk->size = length; + chunk->data = g_malloc (length); + if (length != 0) + memcpy (chunk->data, string, length); + + *start = guint32_to_le (fb->offset); + *size = guint16_to_le (length); + fb->offset += length; + + g_queue_push_tail (fb->chunks, chunk); +} + +static void +file_builder_allocate_for_hash (FileBuilder *fb, + gsize n_buckets, + gsize n_items, + guint bloom_shift, + gsize n_bloom_words, + guint32_le **bloom_filter, + guint32_le **hash_buckets, + struct gvdb_hash_item **hash_items, + struct gvdb_pointer *pointer) +{ + guint32_le bloom_hdr, table_hdr; + guchar *data; + gsize size; + + g_assert (n_bloom_words < (1u << 27)); + + bloom_hdr = guint32_to_le (bloom_shift << 27 | n_bloom_words); + table_hdr = guint32_to_le (n_buckets); + + size = sizeof bloom_hdr + sizeof table_hdr + + n_bloom_words * sizeof (guint32_le) + + n_buckets * sizeof (guint32_le) + + n_items * sizeof (struct gvdb_hash_item); + + data = file_builder_allocate (fb, 4, size, pointer); + +#define chunk(s) (size -= (s), data += (s), data - (s)) + memcpy (chunk (sizeof bloom_hdr), &bloom_hdr, sizeof bloom_hdr); + memcpy (chunk (sizeof table_hdr), &table_hdr, sizeof table_hdr); + *bloom_filter = (guint32_le *) chunk (n_bloom_words * sizeof (guint32_le)); + *hash_buckets = (guint32_le *) chunk (n_buckets * sizeof (guint32_le)); + *hash_items = (struct gvdb_hash_item *) chunk (n_items * + sizeof (struct gvdb_hash_item)); + g_assert (size == 0); +#undef chunk + + memset (*bloom_filter, 0, n_bloom_words * sizeof (guint32_le)); + memset (*hash_buckets, 0, n_buckets * sizeof (guint32_le)); + memset (*hash_items, 0, n_items * sizeof (struct gvdb_hash_item)); + + /* NOTE - the code to actually fill in the bloom filter here is missing. + * Patches welcome! + * + * http://en.wikipedia.org/wiki/Bloom_filter + * http://0pointer.de/blog/projects/bloom.html + */ +} + +static void +file_builder_add_hash (FileBuilder *fb, + GHashTable *table, + struct gvdb_pointer *pointer) +{ + guint32_le *buckets, *bloom_filter; + struct gvdb_hash_item *items; + HashTable *mytable; + GvdbItem *item; + guint32 index; + gint bucket; + + mytable = hash_table_new (g_hash_table_size (table)); + g_hash_table_foreach (table, hash_table_insert, mytable); + index = 0; + + for (bucket = 0; bucket < mytable->n_buckets; bucket++) + for (item = mytable->buckets[bucket]; item; item = item->next) + item->assigned_index = guint32_to_le (index++); + + file_builder_allocate_for_hash (fb, mytable->n_buckets, index, 5, 0, + &bloom_filter, &buckets, &items, pointer); + + index = 0; + for (bucket = 0; bucket < mytable->n_buckets; bucket++) + { + buckets[bucket] = guint32_to_le (index); + + for (item = mytable->buckets[bucket]; item; item = item->next) + { + struct gvdb_hash_item *entry = items++; + const gchar *basename; + + g_assert (index == guint32_from_le (item->assigned_index)); + entry->hash_value = guint32_to_le (item->hash_value); + entry->parent = item_to_index (item->parent); + entry->unused = 0; + + if (item->parent != NULL) + basename = item->key + strlen (item->parent->key); + else + basename = item->key; + + file_builder_add_string (fb, basename, + &entry->key_start, + &entry->key_size); + + if (item->value != NULL) + { + g_assert (item->child == NULL && item->table == NULL); + + file_builder_add_value (fb, item->value, &entry->value.pointer); + entry->type = 'v'; + } + + if (item->child != NULL) + { + guint32 children = 0, i = 0; + guint32_le *offsets; + GvdbItem *child; + + g_assert (item->table == NULL); + + for (child = item->child; child; child = child->sibling) + children++; + + offsets = file_builder_allocate (fb, 4, 4 * children, + &entry->value.pointer); + entry->type = 'L'; + + for (child = item->child; child; child = child->sibling) + offsets[i++] = child->assigned_index; + + g_assert (children == i); + } + + if (item->table != NULL) + { + entry->type = 'H'; + file_builder_add_hash (fb, item->table, &entry->value.pointer); + } + + index++; + } + } + + hash_table_free (mytable); +} + +static FileBuilder * +file_builder_new (gboolean byteswap) +{ + FileBuilder *builder; + + builder = g_slice_new (FileBuilder); + builder->chunks = g_queue_new (); + builder->offset = sizeof (struct gvdb_header); + builder->byteswap = byteswap; + + return builder; +} + +static void +file_builder_free (FileBuilder *fb) +{ + g_queue_free (fb->chunks); + g_slice_free (FileBuilder, fb); +} + +static GString * +file_builder_serialise (FileBuilder *fb, + struct gvdb_pointer root) +{ + struct gvdb_header header = { { 0, 0 }, { 0 }, { 0 }, { { 0 }, { 0 } } }; + GString *result; + + memset (&header, 0, sizeof (header)); + + if (fb->byteswap) + { + header.signature[0] = GVDB_SWAPPED_SIGNATURE0; + header.signature[1] = GVDB_SWAPPED_SIGNATURE1; + } + else + { + header.signature[0] = GVDB_SIGNATURE0; + header.signature[1] = GVDB_SIGNATURE1; + } + + result = g_string_new (NULL); + + header.root = root; + g_string_append_len (result, (gpointer) &header, sizeof header); + + while (!g_queue_is_empty (fb->chunks)) + { + FileChunk *chunk = g_queue_pop_head (fb->chunks); + + if (result->len != chunk->offset) + { + gchar zero[8] = { 0, }; + + g_assert (chunk->offset > result->len); + g_assert (chunk->offset - result->len < 8); + + g_string_append_len (result, zero, chunk->offset - result->len); + g_assert (result->len == chunk->offset); + } + + g_string_append_len (result, chunk->data, chunk->size); + g_free (chunk->data); + + g_slice_free (FileChunk, chunk); + } + + return result; +} + +gboolean +gvdb_table_write_contents (GHashTable *table, + const gchar *filename, + gboolean byteswap, + GError **error) +{ + struct gvdb_pointer root; + gboolean status; + FileBuilder *fb; + GString *str; + + g_return_val_if_fail (table != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + fb = file_builder_new (byteswap); + file_builder_add_hash (fb, table, &root); + str = file_builder_serialise (fb, root); + file_builder_free (fb); + + status = g_file_set_contents (filename, str->str, str->len, error); + g_string_free (str, TRUE); + + return status; +} + +typedef struct { + GBytes *contents; /* (owned) */ + GFile *file; /* (owned) */ +} WriteContentsData; + +static WriteContentsData * +write_contents_data_new (GBytes *contents, + GFile *file) +{ + WriteContentsData *data; + + data = g_slice_new (WriteContentsData); + data->contents = g_bytes_ref (contents); + data->file = g_object_ref (file); + + return data; +} + +static void +write_contents_data_free (WriteContentsData *data) +{ + g_bytes_unref (data->contents); + g_object_unref (data->file); + g_slice_free (WriteContentsData, data); +} + +static void +replace_contents_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = user_data; + WriteContentsData *data = g_task_get_task_data (task); + GError *error = NULL; + + g_return_if_fail (g_task_get_source_tag (task) == gvdb_table_write_contents_async); + + if (!g_file_replace_contents_finish (data->file, result, NULL, &error)) + g_task_return_error (task, g_steal_pointer (&error)); + else + g_task_return_boolean (task, TRUE); + + g_object_unref (task); +} + +void +gvdb_table_write_contents_async (GHashTable *table, + const gchar *filename, + gboolean byteswap, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + struct gvdb_pointer root; + FileBuilder *fb; + WriteContentsData *data; + GString *str; + GBytes *bytes; + GFile *file; + GTask *task; + + g_return_if_fail (table != NULL); + g_return_if_fail (filename != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + fb = file_builder_new (byteswap); + file_builder_add_hash (fb, table, &root); + str = file_builder_serialise (fb, root); + bytes = g_string_free_to_bytes (str); + file_builder_free (fb); + + file = g_file_new_for_path (filename); + data = write_contents_data_new (bytes, file); + + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_task_data (task, data, (GDestroyNotify)write_contents_data_free); + g_task_set_source_tag (task, gvdb_table_write_contents_async); + + g_file_replace_contents_async (file, + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + NULL, FALSE, + G_FILE_CREATE_PRIVATE, + cancellable, replace_contents_cb, g_steal_pointer (&task)); + + g_bytes_unref (bytes); + g_object_unref (file); +} + +gboolean +gvdb_table_write_contents_finish (GHashTable *table, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (table != NULL, FALSE); + g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} diff --git a/gio/gvdb/gvdb-builder.h b/gio/gvdb/gvdb-builder.h new file mode 100644 index 0000000..30757d0 --- /dev/null +++ b/gio/gvdb/gvdb-builder.h @@ -0,0 +1,66 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __gvdb_builder_h__ +#define __gvdb_builder_h__ + +#include + +typedef struct _GvdbItem GvdbItem; + +G_GNUC_INTERNAL +GHashTable * gvdb_hash_table_new (GHashTable *parent, + const gchar *key); + +G_GNUC_INTERNAL +GvdbItem * gvdb_hash_table_insert (GHashTable *table, + const gchar *key); +G_GNUC_INTERNAL +void gvdb_hash_table_insert_string (GHashTable *table, + const gchar *key, + const gchar *value); + +G_GNUC_INTERNAL +void gvdb_item_set_value (GvdbItem *item, + GVariant *value); +G_GNUC_INTERNAL +void gvdb_item_set_hash_table (GvdbItem *item, + GHashTable *table); +G_GNUC_INTERNAL +void gvdb_item_set_parent (GvdbItem *item, + GvdbItem *parent); + +G_GNUC_INTERNAL +gboolean gvdb_table_write_contents (GHashTable *table, + const gchar *filename, + gboolean byteswap, + GError **error); +G_GNUC_INTERNAL +void gvdb_table_write_contents_async (GHashTable *table, + const gchar *filename, + gboolean byteswap, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +G_GNUC_INTERNAL +gboolean gvdb_table_write_contents_finish (GHashTable *table, + GAsyncResult *result, + GError **error); + +#endif /* __gvdb_builder_h__ */ diff --git a/gio/gvdb/gvdb-format.h b/gio/gvdb/gvdb-format.h new file mode 100644 index 0000000..ed6adab --- /dev/null +++ b/gio/gvdb/gvdb-format.h @@ -0,0 +1,85 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __gvdb_format_h__ +#define __gvdb_format_h__ + +#include + +typedef struct { guint16 value; } guint16_le; +typedef struct { guint32 value; } guint32_le; + +struct gvdb_pointer { + guint32_le start; + guint32_le end; +}; + +struct gvdb_hash_header { + guint32_le n_bloom_words; + guint32_le n_buckets; +}; + +struct gvdb_hash_item { + guint32_le hash_value; + guint32_le parent; + + guint32_le key_start; + guint16_le key_size; + gchar type; + gchar unused; + + union + { + struct gvdb_pointer pointer; + gchar direct[8]; + } value; +}; + +struct gvdb_header { + guint32 signature[2]; + guint32_le version; + guint32_le options; + + struct gvdb_pointer root; +}; + +static inline guint32_le guint32_to_le (guint32 value) { + guint32_le result = { GUINT32_TO_LE (value) }; + return result; +} + +static inline guint32 guint32_from_le (guint32_le value) { + return GUINT32_FROM_LE (value.value); +} + +static inline guint16_le guint16_to_le (guint16 value) { + guint16_le result = { GUINT16_TO_LE (value) }; + return result; +} + +static inline guint16 guint16_from_le (guint16_le value) { + return GUINT16_FROM_LE (value.value); +} + +#define GVDB_SIGNATURE0 1918981703 +#define GVDB_SIGNATURE1 1953390953 +#define GVDB_SWAPPED_SIGNATURE0 GUINT32_SWAP_LE_BE (GVDB_SIGNATURE0) +#define GVDB_SWAPPED_SIGNATURE1 GUINT32_SWAP_LE_BE (GVDB_SIGNATURE1) + +#endif /* __gvdb_format_h__ */ diff --git a/gio/gvdb/gvdb-reader.c b/gio/gvdb/gvdb-reader.c new file mode 100644 index 0000000..820ce4c --- /dev/null +++ b/gio/gvdb/gvdb-reader.c @@ -0,0 +1,736 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "gvdb-reader.h" +#include "gvdb-format.h" + +#include + +struct _GvdbTable { + GBytes *bytes; + + const gchar *data; + gsize size; + + gboolean byteswapped; + gboolean trusted; + + const guint32_le *bloom_words; + guint32 n_bloom_words; + guint bloom_shift; + + const guint32_le *hash_buckets; + guint32 n_buckets; + + struct gvdb_hash_item *hash_items; + guint32 n_hash_items; +}; + +static const gchar * +gvdb_table_item_get_key (GvdbTable *file, + const struct gvdb_hash_item *item, + gsize *size) +{ + guint32 start, end; + + start = guint32_from_le (item->key_start); + *size = guint16_from_le (item->key_size); + end = start + *size; + + if G_UNLIKELY (start > end || end > file->size) + return NULL; + + return file->data + start; +} + +static gconstpointer +gvdb_table_dereference (GvdbTable *file, + const struct gvdb_pointer *pointer, + gint alignment, + gsize *size) +{ + guint32 start, end; + + start = guint32_from_le (pointer->start); + end = guint32_from_le (pointer->end); + + if G_UNLIKELY (start > end || end > file->size || start & (alignment - 1)) + return NULL; + + *size = end - start; + + return file->data + start; +} + +static void +gvdb_table_setup_root (GvdbTable *file, + const struct gvdb_pointer *pointer) +{ + const struct gvdb_hash_header *header; + guint32 n_bloom_words; + guint32 n_buckets; + gsize size; + + header = gvdb_table_dereference (file, pointer, 4, &size); + + if G_UNLIKELY (header == NULL || size < sizeof *header) + return; + + size -= sizeof *header; + + n_bloom_words = guint32_from_le (header->n_bloom_words); + n_buckets = guint32_from_le (header->n_buckets); + n_bloom_words &= (1u << 27) - 1; + + if G_UNLIKELY (n_bloom_words * sizeof (guint32_le) > size) + return; + + file->bloom_words = (gpointer) (header + 1); + size -= n_bloom_words * sizeof (guint32_le); + file->n_bloom_words = n_bloom_words; + + if G_UNLIKELY (n_buckets > G_MAXUINT / sizeof (guint32_le) || + n_buckets * sizeof (guint32_le) > size) + return; + + file->hash_buckets = file->bloom_words + file->n_bloom_words; + size -= n_buckets * sizeof (guint32_le); + file->n_buckets = n_buckets; + + if G_UNLIKELY (size % sizeof (struct gvdb_hash_item)) + return; + + file->hash_items = (gpointer) (file->hash_buckets + n_buckets); + file->n_hash_items = size / sizeof (struct gvdb_hash_item); +} + +/** + * gvdb_table_new_from_bytes: + * @bytes: the #GBytes with the data + * @trusted: if the contents of @bytes are trusted + * @error: %NULL, or a pointer to a %NULL #GError + * + * Creates a new #GvdbTable from the contents of @bytes. + * + * This call can fail if the header contained in @bytes is invalid or if @bytes + * is empty; if so, %G_FILE_ERROR_INVAL will be returned. + * + * You should call gvdb_table_free() on the return result when you no + * longer require it. + * + * Returns: a new #GvdbTable + **/ +GvdbTable * +gvdb_table_new_from_bytes (GBytes *bytes, + gboolean trusted, + GError **error) +{ + const struct gvdb_header *header; + GvdbTable *file; + + file = g_slice_new0 (GvdbTable); + file->bytes = g_bytes_ref (bytes); + file->data = g_bytes_get_data (bytes, &file->size); + file->trusted = trusted; + + if (file->size < sizeof (struct gvdb_header)) + goto invalid; + + header = (gpointer) file->data; + + if (header->signature[0] == GVDB_SIGNATURE0 && + header->signature[1] == GVDB_SIGNATURE1 && + guint32_from_le (header->version) == 0) + file->byteswapped = FALSE; + + else if (header->signature[0] == GVDB_SWAPPED_SIGNATURE0 && + header->signature[1] == GVDB_SWAPPED_SIGNATURE1 && + guint32_from_le (header->version) == 0) + file->byteswapped = TRUE; + + else + goto invalid; + + gvdb_table_setup_root (file, &header->root); + + return file; + +invalid: + g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "invalid gvdb header"); + + g_bytes_unref (file->bytes); + + g_slice_free (GvdbTable, file); + + return NULL; +} + +/** + * gvdb_table_new: + * @filename: a filename + * @trusted: if the contents of @bytes are trusted + * @error: %NULL, or a pointer to a %NULL #GError + * + * Creates a new #GvdbTable using the #GMappedFile for @filename as the + * #GBytes. + * + * This function will fail if the file cannot be opened. + * In that case, the #GError that is returned will be an error from + * g_mapped_file_new(). + * + * An empty or corrupt file will result in %G_FILE_ERROR_INVAL. + * + * Returns: a new #GvdbTable + **/ +GvdbTable * +gvdb_table_new (const gchar *filename, + gboolean trusted, + GError **error) +{ + GMappedFile *mapped; + GvdbTable *table; + GBytes *bytes; + + mapped = g_mapped_file_new (filename, FALSE, error); + if (!mapped) + return NULL; + + bytes = g_mapped_file_get_bytes (mapped); + table = gvdb_table_new_from_bytes (bytes, trusted, error); + g_mapped_file_unref (mapped); + g_bytes_unref (bytes); + + g_prefix_error (error, "%s: ", filename); + + return table; +} + +static gboolean +gvdb_table_bloom_filter (GvdbTable *file, + guint32 hash_value) +{ + guint32 word, mask; + + if (file->n_bloom_words == 0) + return TRUE; + + word = (hash_value / 32) % file->n_bloom_words; + mask = 1 << (hash_value & 31); + mask |= 1 << ((hash_value >> file->bloom_shift) & 31); + + return (guint32_from_le (file->bloom_words[word]) & mask) == mask; +} + +static gboolean +gvdb_table_check_name (GvdbTable *file, + struct gvdb_hash_item *item, + const gchar *key, + guint key_length) +{ + const gchar *this_key; + gsize this_size; + guint32 parent; + + this_key = gvdb_table_item_get_key (file, item, &this_size); + + if G_UNLIKELY (this_key == NULL || this_size > key_length) + return FALSE; + + key_length -= this_size; + + if G_UNLIKELY (memcmp (this_key, key + key_length, this_size) != 0) + return FALSE; + + parent = guint32_from_le (item->parent); + if (key_length == 0 && parent == 0xffffffffu) + return TRUE; + + if G_LIKELY (parent < file->n_hash_items && this_size > 0) + return gvdb_table_check_name (file, + &file->hash_items[parent], + key, key_length); + + return FALSE; +} + +static const struct gvdb_hash_item * +gvdb_table_lookup (GvdbTable *file, + const gchar *key, + gchar type) +{ + guint32 hash_value = 5381; + guint key_length; + guint32 bucket; + guint32 lastno; + guint32 itemno; + + if G_UNLIKELY (file->n_buckets == 0 || file->n_hash_items == 0) + return NULL; + + for (key_length = 0; key[key_length]; key_length++) + hash_value = (hash_value * 33) + ((signed char *) key)[key_length]; + + if (!gvdb_table_bloom_filter (file, hash_value)) + return NULL; + + bucket = hash_value % file->n_buckets; + itemno = guint32_from_le (file->hash_buckets[bucket]); + + if (bucket == file->n_buckets - 1 || + (lastno = guint32_from_le(file->hash_buckets[bucket + 1])) > file->n_hash_items) + lastno = file->n_hash_items; + + while G_LIKELY (itemno < lastno) + { + struct gvdb_hash_item *item = &file->hash_items[itemno]; + + if (hash_value == guint32_from_le (item->hash_value)) + if G_LIKELY (gvdb_table_check_name (file, item, key, key_length)) + if G_LIKELY (item->type == type) + return item; + + itemno++; + } + + return NULL; +} + +static gboolean +gvdb_table_list_from_item (GvdbTable *table, + const struct gvdb_hash_item *item, + const guint32_le **list, + guint *length) +{ + gsize size; + + *list = gvdb_table_dereference (table, &item->value.pointer, 4, &size); + + if G_LIKELY (*list == NULL || size % 4) + return FALSE; + + *length = size / 4; + + return TRUE; +} + +/** + * gvdb_table_get_names: + * @table: a #GvdbTable + * @length: (out) (optional): the number of items returned, or %NULL + * + * Gets a list of all names contained in @table. + * + * No call to gvdb_table_get_table(), gvdb_table_list() or + * gvdb_table_get_value() will succeed unless it is for one of the + * names returned by this function. + * + * Note that some names that are returned may still fail for all of the + * above calls in the case of the corrupted file. Note also that the + * returned strings may not be utf8. + * + * Returns: (array length=length): a %NULL-terminated list of strings, of length @length + **/ +gchar ** +gvdb_table_get_names (GvdbTable *table, + gsize *length) +{ + gchar **names; + guint n_names; + guint filled; + guint total; + guint i; + + /* We generally proceed by iterating over the list of items in the + * hash table (in order of appearance) recording them into an array. + * + * Each item has a parent item (except root items). The parent item + * forms part of the name of the item. We could go fetching the + * parent item chain at the point that we encounter each item but then + * we would need to implement some sort of recursion along with checks + * for self-referential items. + * + * Instead, we do a number of passes. Each pass will build up one + * level of names (starting from the root). We continue to do passes + * until no more items are left. The first pass will only add root + * items and each further pass will only add items whose direct parent + * is an item added in the immediately previous pass. It's also + * possible that items get filled if they follow their parent within a + * particular pass. + * + * At most we will have a number of passes equal to the depth of the + * tree. Self-referential items will never be filled in (since their + * parent will have never been filled in). We continue until we have + * a pass that fills in no additional items. + * + * This takes an O(n) algorithm and turns it into O(n*m) where m is + * the depth of the tree, but typically the tree won't be very + * deep and the constant factor of this algorithm is lower (and the + * complexity of coding it, as well). + */ + + n_names = table->n_hash_items; + names = g_new0 (gchar *, n_names + 1); + + /* 'names' starts out all-NULL. On each pass we record the number + * of items changed from NULL to non-NULL in 'filled' so we know if we + * should repeat the loop. 'total' counts the total number of items + * filled. If 'total' ends up equal to 'n_names' then we know that + * 'names' has been completely filled. + */ + + total = 0; + do + { + /* Loop until we have filled no more entries */ + filled = 0; + + for (i = 0; i < n_names; i++) + { + const struct gvdb_hash_item *item = &table->hash_items[i]; + const gchar *name; + gsize name_length; + guint32 parent; + + /* already got it on a previous pass */ + if (names[i] != NULL) + continue; + + parent = guint32_from_le (item->parent); + + if (parent == 0xffffffffu) + { + /* it's a root item */ + name = gvdb_table_item_get_key (table, item, &name_length); + + if (name != NULL) + { + names[i] = g_strndup (name, name_length); + filled++; + } + } + + else if (parent < n_names && names[parent] != NULL) + { + /* It's a non-root item whose parent was filled in already. + * + * Calculate the name of this item by combining it with + * its parent name. + */ + name = gvdb_table_item_get_key (table, item, &name_length); + + if (name != NULL) + { + const gchar *parent_name = names[parent]; + gsize parent_length; + gchar *fullname; + + parent_length = strlen (parent_name); + fullname = g_malloc (parent_length + name_length + 1); + memcpy (fullname, parent_name, parent_length); + memcpy (fullname + parent_length, name, name_length); + fullname[parent_length + name_length] = '\0'; + names[i] = fullname; + filled++; + } + } + } + + total += filled; + } + while (filled && total < n_names); + + /* If the table was corrupted then 'names' may have holes in it. + * Collapse those. + */ + if G_UNLIKELY (total != n_names) + { + GPtrArray *fixed_names; + + fixed_names = g_ptr_array_sized_new (n_names + 1 /* NULL terminator */); + for (i = 0; i < n_names; i++) + if (names[i] != NULL) + g_ptr_array_add (fixed_names, names[i]); + + g_free (names); + n_names = fixed_names->len; + g_ptr_array_add (fixed_names, NULL); + names = (gchar **) g_ptr_array_free (fixed_names, FALSE); + } + + if (length) + { + G_STATIC_ASSERT (sizeof (*length) >= sizeof (n_names)); + *length = n_names; + } + + return names; +} + +/** + * gvdb_table_list: + * @file: a #GvdbTable + * @key: a string + * + * List all of the keys that appear below @key. The nesting of keys + * within the hash file is defined by the program that created the hash + * file. One thing is constant: each item in the returned array can be + * concatenated to @key to obtain the full name of that key. + * + * It is not possible to tell from this function if a given key is + * itself a path, a value, or another hash table; you are expected to + * know this for yourself. + * + * You should call g_strfreev() on the return result when you no longer + * require it. + * + * Returns: a %NULL-terminated string array + **/ +gchar ** +gvdb_table_list (GvdbTable *file, + const gchar *key) +{ + const struct gvdb_hash_item *item; + const guint32_le *list; + gchar **strv; + guint length; + guint i; + + if ((item = gvdb_table_lookup (file, key, 'L')) == NULL) + return NULL; + + if (!gvdb_table_list_from_item (file, item, &list, &length)) + return NULL; + + strv = g_new (gchar *, length + 1); + for (i = 0; i < length; i++) + { + guint32 itemno = guint32_from_le (list[i]); + + if (itemno < file->n_hash_items) + { + const struct gvdb_hash_item *item; + const gchar *string; + gsize strsize; + + item = file->hash_items + itemno; + + string = gvdb_table_item_get_key (file, item, &strsize); + + if (string != NULL) + strv[i] = g_strndup (string, strsize); + else + strv[i] = g_malloc0 (1); + } + else + strv[i] = g_malloc0 (1); + } + + strv[i] = NULL; + + return strv; +} + +/** + * gvdb_table_has_value: + * @file: a #GvdbTable + * @key: a string + * + * Checks for a value named @key in @file. + * + * Note: this function does not consider non-value nodes (other hash + * tables, for example). + * + * Returns: %TRUE if @key is in the table + **/ +gboolean +gvdb_table_has_value (GvdbTable *file, + const gchar *key) +{ + static const struct gvdb_hash_item *item; + gsize size; + + item = gvdb_table_lookup (file, key, 'v'); + + if (item == NULL) + return FALSE; + + return gvdb_table_dereference (file, &item->value.pointer, 8, &size) != NULL; +} + +static GVariant * +gvdb_table_value_from_item (GvdbTable *table, + const struct gvdb_hash_item *item) +{ + GVariant *variant, *value; + gconstpointer data; + GBytes *bytes; + gsize size; + + data = gvdb_table_dereference (table, &item->value.pointer, 8, &size); + + if G_UNLIKELY (data == NULL) + return NULL; + + bytes = g_bytes_new_from_bytes (table->bytes, ((gchar *) data) - table->data, size); + variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, bytes, table->trusted); + value = g_variant_get_variant (variant); + g_variant_unref (variant); + g_bytes_unref (bytes); + + return value; +} + +/** + * gvdb_table_get_value: + * @file: a #GvdbTable + * @key: a string + * + * Looks up a value named @key in @file. + * + * If the value is not found then %NULL is returned. Otherwise, a new + * #GVariant instance is returned. The #GVariant does not depend on the + * continued existence of @file. + * + * You should call g_variant_unref() on the return result when you no + * longer require it. + * + * Returns: a #GVariant, or %NULL + **/ +GVariant * +gvdb_table_get_value (GvdbTable *file, + const gchar *key) +{ + const struct gvdb_hash_item *item; + GVariant *value; + + if ((item = gvdb_table_lookup (file, key, 'v')) == NULL) + return NULL; + + value = gvdb_table_value_from_item (file, item); + + if (value && file->byteswapped) + { + GVariant *tmp; + + tmp = g_variant_byteswap (value); + g_variant_unref (value); + value = tmp; + } + + return value; +} + +/** + * gvdb_table_get_raw_value: + * @table: a #GvdbTable + * @key: a string + * + * Looks up a value named @key in @file. + * + * This call is equivalent to gvdb_table_get_value() except that it + * never byteswaps the value. + * + * Returns: a #GVariant, or %NULL + **/ +GVariant * +gvdb_table_get_raw_value (GvdbTable *table, + const gchar *key) +{ + const struct gvdb_hash_item *item; + + if ((item = gvdb_table_lookup (table, key, 'v')) == NULL) + return NULL; + + return gvdb_table_value_from_item (table, item); +} + +/** + * gvdb_table_get_table: + * @file: a #GvdbTable + * @key: a string + * + * Looks up the hash table named @key in @file. + * + * The toplevel hash table in a #GvdbTable can contain reference to + * child hash tables (and those can contain further references...). + * + * If @key is not found in @file then %NULL is returned. Otherwise, a + * new #GvdbTable is returned, referring to the child hashtable as + * contained in the file. This newly-created #GvdbTable does not depend + * on the continued existence of @file. + * + * You should call gvdb_table_free() on the return result when you no + * longer require it. + * + * Returns: a new #GvdbTable, or %NULL + **/ +GvdbTable * +gvdb_table_get_table (GvdbTable *file, + const gchar *key) +{ + const struct gvdb_hash_item *item; + GvdbTable *new; + + item = gvdb_table_lookup (file, key, 'H'); + + if (item == NULL) + return NULL; + + new = g_slice_new0 (GvdbTable); + new->bytes = g_bytes_ref (file->bytes); + new->byteswapped = file->byteswapped; + new->trusted = file->trusted; + new->data = file->data; + new->size = file->size; + + gvdb_table_setup_root (new, &item->value.pointer); + + return new; +} + +/** + * gvdb_table_free: + * @file: a #GvdbTable + * + * Frees @file. + **/ +void +gvdb_table_free (GvdbTable *file) +{ + g_bytes_unref (file->bytes); + g_slice_free (GvdbTable, file); +} + +/** + * gvdb_table_is_valid: + * @table: a #GvdbTable + * + * Checks if the table is still valid. + * + * An on-disk GVDB can be marked as invalid. This happens when the file + * has been replaced. The appropriate action is typically to reopen the + * file. + * + * Returns: %TRUE if @table is still valid + **/ +gboolean +gvdb_table_is_valid (GvdbTable *table) +{ + return !!*table->data; +} diff --git a/gio/gvdb/gvdb-reader.h b/gio/gvdb/gvdb-reader.h new file mode 100644 index 0000000..79a97d3 --- /dev/null +++ b/gio/gvdb/gvdb-reader.h @@ -0,0 +1,78 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __gvdb_reader_h__ +#define __gvdb_reader_h__ + +#include + +/* We cannot enable the weak attribute unconditionally here because both + * gvdb/gvdb-reader.c and tests/dconf-mock-gvdb.c include this file. The + * intention of using weak symbols here is to allow the latter to override + * functions defined in the former, so functions in tests/dconf-mock-gvdb.c + * must have strong bindings. */ +#ifdef GVDB_USE_WEAK_SYMBOLS +# ifdef __GNUC__ +# define GVDB_GNUC_WEAK __attribute__((weak)) +# else +# define GVDB_GNUC_WEAK +# endif +#else +# define GVDB_GNUC_WEAK +#endif + +typedef struct _GvdbTable GvdbTable; + +G_BEGIN_DECLS + +G_GNUC_INTERNAL GVDB_GNUC_WEAK +GvdbTable * gvdb_table_new_from_bytes (GBytes *bytes, + gboolean trusted, + GError **error); +G_GNUC_INTERNAL GVDB_GNUC_WEAK +GvdbTable * gvdb_table_new (const gchar *filename, + gboolean trusted, + GError **error); +G_GNUC_INTERNAL GVDB_GNUC_WEAK +void gvdb_table_free (GvdbTable *table); +G_GNUC_INTERNAL GVDB_GNUC_WEAK +gchar ** gvdb_table_get_names (GvdbTable *table, + gsize *length); +G_GNUC_INTERNAL GVDB_GNUC_WEAK +gchar ** gvdb_table_list (GvdbTable *table, + const gchar *key); +G_GNUC_INTERNAL GVDB_GNUC_WEAK +GvdbTable * gvdb_table_get_table (GvdbTable *table, + const gchar *key); +G_GNUC_INTERNAL GVDB_GNUC_WEAK +GVariant * gvdb_table_get_raw_value (GvdbTable *table, + const gchar *key); +G_GNUC_INTERNAL GVDB_GNUC_WEAK +GVariant * gvdb_table_get_value (GvdbTable *table, + const gchar *key); + +G_GNUC_INTERNAL GVDB_GNUC_WEAK +gboolean gvdb_table_has_value (GvdbTable *table, + const gchar *key); +G_GNUC_INTERNAL GVDB_GNUC_WEAK +gboolean gvdb_table_is_valid (GvdbTable *table); + +G_END_DECLS + +#endif /* __gvdb_reader_h__ */ diff --git a/gio/gvdb/gvdb.doap b/gio/gvdb/gvdb.doap new file mode 100644 index 0000000..8c5f3e8 --- /dev/null +++ b/gio/gvdb/gvdb.doap @@ -0,0 +1,57 @@ + + + + + gvdb + GVariant Database file + + A simple database file format that stores a mapping from strings to + GVariant values in a way that is extremely efficient for lookups. + + The database is written once and can not be modified. + + Included here is reader code and a first-pass implementation of a + writer (that does not currently produce particularly optimised + output). + + It is intended that this code be used by copy-pasting into your + project or by making use of git-merge(1). + + + + + Matthias Clasen + + matthiasc + + + + + + Allison Ryan Lortie + + desrt + + + + + + Philip Withnall + + + pwithnall + + + + + + Emmanuele Bassi + + ebassi + + + + diff --git a/gio/gvfs.c b/gio/gvfs.c new file mode 100644 index 0000000..6e2dcf0 --- /dev/null +++ b/gio/gvfs.c @@ -0,0 +1,511 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" +#include +#include "gvfs.h" +#include "glib-private.h" +#include "glocalvfs.h" +#include "gresourcefile.h" +#include "giomodule-priv.h" +#include "glibintl.h" + + +/** + * SECTION:gvfs + * @short_description: Virtual File System + * @include: gio/gio.h + * + * Entry point for using GIO functionality. + * + */ + +static GRWLock additional_schemes_lock; + +typedef struct _GVfsPrivate { + GHashTable *additional_schemes; + char const **supported_schemes; +} GVfsPrivate; + +typedef struct { + GVfsFileLookupFunc uri_func; + gpointer uri_data; + GDestroyNotify uri_destroy; + + GVfsFileLookupFunc parse_name_func; + gpointer parse_name_data; + GDestroyNotify parse_name_destroy; +} GVfsURISchemeData; + +G_DEFINE_TYPE_WITH_PRIVATE (GVfs, g_vfs, G_TYPE_OBJECT) + +static void +g_vfs_dispose (GObject *object) +{ + GVfs *vfs = G_VFS (object); + GVfsPrivate *priv = g_vfs_get_instance_private (vfs); + + g_clear_pointer (&priv->additional_schemes, g_hash_table_destroy); + g_clear_pointer (&priv->supported_schemes, g_free); + + G_OBJECT_CLASS (g_vfs_parent_class)->dispose (object); +} + +static void +g_vfs_class_init (GVfsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->dispose = g_vfs_dispose; +} + +static GFile * +resource_parse_name (GVfs *vfs, + const char *parse_name, + gpointer user_data) +{ + if (g_str_has_prefix (parse_name, "resource:")) + return _g_resource_file_new (parse_name); + + return NULL; +} + +static GFile * +resource_get_file_for_uri (GVfs *vfs, + const char *uri, + gpointer user_data) +{ + return _g_resource_file_new (uri); +} + +static void +g_vfs_uri_lookup_func_closure_free (gpointer data) +{ + GVfsURISchemeData *closure = data; + + if (closure->uri_destroy) + closure->uri_destroy (closure->uri_data); + if (closure->parse_name_destroy) + closure->parse_name_destroy (closure->parse_name_data); + + g_free (closure); +} + +static void +g_vfs_init (GVfs *vfs) +{ + GVfsPrivate *priv = g_vfs_get_instance_private (vfs); + priv->additional_schemes = + g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_vfs_uri_lookup_func_closure_free); + + g_vfs_register_uri_scheme (vfs, "resource", + resource_get_file_for_uri, NULL, NULL, + resource_parse_name, NULL, NULL); +} + +/** + * g_vfs_is_active: + * @vfs: a #GVfs. + * + * Checks if the VFS is active. + * + * Returns: %TRUE if construction of the @vfs was successful + * and it is now active. + */ +gboolean +g_vfs_is_active (GVfs *vfs) +{ + GVfsClass *class; + + g_return_val_if_fail (G_IS_VFS (vfs), FALSE); + + class = G_VFS_GET_CLASS (vfs); + + return (* class->is_active) (vfs); +} + + +/** + * g_vfs_get_file_for_path: + * @vfs: a #GVfs. + * @path: a string containing a VFS path. + * + * Gets a #GFile for @path. + * + * Returns: (transfer full): a #GFile. + * Free the returned object with g_object_unref(). + */ +GFile * +g_vfs_get_file_for_path (GVfs *vfs, + const char *path) +{ + GVfsClass *class; + + g_return_val_if_fail (G_IS_VFS (vfs), NULL); + g_return_val_if_fail (path != NULL, NULL); + + class = G_VFS_GET_CLASS (vfs); + + return (* class->get_file_for_path) (vfs, path); +} + +static GFile * +parse_name_internal (GVfs *vfs, + const char *parse_name) +{ + GVfsPrivate *priv = g_vfs_get_instance_private (vfs); + GHashTableIter iter; + GVfsURISchemeData *closure; + GFile *ret = NULL; + + g_rw_lock_reader_lock (&additional_schemes_lock); + g_hash_table_iter_init (&iter, priv->additional_schemes); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &closure)) + { + ret = closure->parse_name_func (vfs, parse_name, + closure->parse_name_data); + + if (ret) + break; + } + + g_rw_lock_reader_unlock (&additional_schemes_lock); + + return ret; +} + +static GFile * +get_file_for_uri_internal (GVfs *vfs, + const char *uri) +{ + GVfsPrivate *priv = g_vfs_get_instance_private (vfs); + GFile *ret = NULL; + char *scheme; + GVfsURISchemeData *closure; + + scheme = g_uri_parse_scheme (uri); + if (scheme == NULL) + return NULL; + + g_rw_lock_reader_lock (&additional_schemes_lock); + closure = g_hash_table_lookup (priv->additional_schemes, scheme); + + if (closure) + ret = closure->uri_func (vfs, uri, closure->uri_data); + + g_rw_lock_reader_unlock (&additional_schemes_lock); + + g_free (scheme); + return ret; +} + +/** + * g_vfs_get_file_for_uri: + * @vfs: a#GVfs. + * @uri: a string containing a URI + * + * Gets a #GFile for @uri. + * + * This operation never fails, but the returned object + * might not support any I/O operation if the URI + * is malformed or if the URI scheme is not supported. + * + * Returns: (transfer full): a #GFile. + * Free the returned object with g_object_unref(). + */ +GFile * +g_vfs_get_file_for_uri (GVfs *vfs, + const char *uri) +{ + GVfsClass *class; + GFile *ret = NULL; + + g_return_val_if_fail (G_IS_VFS (vfs), NULL); + g_return_val_if_fail (uri != NULL, NULL); + + class = G_VFS_GET_CLASS (vfs); + + ret = get_file_for_uri_internal (vfs, uri); + if (!ret) + ret = (* class->get_file_for_uri) (vfs, uri); + + g_assert (ret != NULL); + + return g_steal_pointer (&ret); +} + +/** + * g_vfs_get_supported_uri_schemes: + * @vfs: a #GVfs. + * + * Gets a list of URI schemes supported by @vfs. + * + * Returns: (transfer none): a %NULL-terminated array of strings. + * The returned array belongs to GIO and must + * not be freed or modified. + */ +const gchar * const * +g_vfs_get_supported_uri_schemes (GVfs *vfs) +{ + GVfsPrivate *priv; + + g_return_val_if_fail (G_IS_VFS (vfs), NULL); + + priv = g_vfs_get_instance_private (vfs); + + if (!priv->supported_schemes) + { + GVfsClass *class; + const char * const *default_schemes; + const char *additional_scheme; + GPtrArray *supported_schemes; + GHashTableIter iter; + + class = G_VFS_GET_CLASS (vfs); + + default_schemes = (* class->get_supported_uri_schemes) (vfs); + supported_schemes = g_ptr_array_new (); + + for (; default_schemes && *default_schemes; default_schemes++) + g_ptr_array_add (supported_schemes, (gpointer) *default_schemes); + + g_rw_lock_reader_lock (&additional_schemes_lock); + g_hash_table_iter_init (&iter, priv->additional_schemes); + + while (g_hash_table_iter_next + (&iter, (gpointer *) &additional_scheme, NULL)) + g_ptr_array_add (supported_schemes, (gpointer) additional_scheme); + + g_rw_lock_reader_unlock (&additional_schemes_lock); + + g_ptr_array_add (supported_schemes, NULL); + + g_free (priv->supported_schemes); + priv->supported_schemes = + (char const **) g_ptr_array_free (supported_schemes, FALSE); + } + + return priv->supported_schemes; +} + +/** + * g_vfs_parse_name: + * @vfs: a #GVfs. + * @parse_name: a string to be parsed by the VFS module. + * + * This operation never fails, but the returned object might + * not support any I/O operations if the @parse_name cannot + * be parsed by the #GVfs module. + * + * Returns: (transfer full): a #GFile for the given @parse_name. + * Free the returned object with g_object_unref(). + */ +GFile * +g_vfs_parse_name (GVfs *vfs, + const char *parse_name) +{ + GVfsClass *class; + GFile *ret; + + g_return_val_if_fail (G_IS_VFS (vfs), NULL); + g_return_val_if_fail (parse_name != NULL, NULL); + + class = G_VFS_GET_CLASS (vfs); + + ret = parse_name_internal (vfs, parse_name); + if (ret) + return ret; + + return (* class->parse_name) (vfs, parse_name); +} + +static GVfs *vfs_default_singleton = NULL; /* (owned) (atomic) */ + +/** + * g_vfs_get_default: + * + * Gets the default #GVfs for the system. + * + * Returns: (not nullable) (transfer none): a #GVfs, which will be the local + * file system #GVfs if no other implementation is available. + */ +GVfs * +g_vfs_get_default (void) +{ + if (GLIB_PRIVATE_CALL (g_check_setuid) ()) + return g_vfs_get_local (); + + if (g_once_init_enter (&vfs_default_singleton)) + { + GVfs *singleton; + + singleton = _g_io_module_get_default (G_VFS_EXTENSION_POINT_NAME, + "GIO_USE_VFS", + (GIOModuleVerifyFunc) g_vfs_is_active); + + g_once_init_leave (&vfs_default_singleton, singleton); + } + + return vfs_default_singleton; +} + +/** + * g_vfs_get_local: + * + * Gets the local #GVfs for the system. + * + * Returns: (transfer none): a #GVfs. + */ +GVfs * +g_vfs_get_local (void) +{ + static gsize vfs = 0; + + if (g_once_init_enter (&vfs)) + g_once_init_leave (&vfs, (gsize)_g_local_vfs_new ()); + + return G_VFS (vfs); +} + +/** + * g_vfs_register_uri_scheme: + * @vfs: a #GVfs + * @scheme: an URI scheme, e.g. "http" + * @uri_func: (scope notified) (nullable): a #GVfsFileLookupFunc + * @uri_data: (nullable): custom data passed to be passed to @uri_func, or %NULL + * @uri_destroy: (nullable): function to be called when unregistering the + * URI scheme, or when @vfs is disposed, to free the resources used + * by the URI lookup function + * @parse_name_func: (scope notified) (nullable): a #GVfsFileLookupFunc + * @parse_name_data: (nullable): custom data passed to be passed to + * @parse_name_func, or %NULL + * @parse_name_destroy: (nullable): function to be called when unregistering the + * URI scheme, or when @vfs is disposed, to free the resources used + * by the parse name lookup function + * + * Registers @uri_func and @parse_name_func as the #GFile URI and parse name + * lookup functions for URIs with a scheme matching @scheme. + * Note that @scheme is registered only within the running application, as + * opposed to desktop-wide as it happens with GVfs backends. + * + * When a #GFile is requested with an URI containing @scheme (e.g. through + * g_file_new_for_uri()), @uri_func will be called to allow a custom + * constructor. The implementation of @uri_func should not be blocking, and + * must not call g_vfs_register_uri_scheme() or g_vfs_unregister_uri_scheme(). + * + * When g_file_parse_name() is called with a parse name obtained from such file, + * @parse_name_func will be called to allow the #GFile to be created again. In + * that case, it's responsibility of @parse_name_func to make sure the parse + * name matches what the custom #GFile implementation returned when + * g_file_get_parse_name() was previously called. The implementation of + * @parse_name_func should not be blocking, and must not call + * g_vfs_register_uri_scheme() or g_vfs_unregister_uri_scheme(). + * + * It's an error to call this function twice with the same scheme. To unregister + * a custom URI scheme, use g_vfs_unregister_uri_scheme(). + * + * Returns: %TRUE if @scheme was successfully registered, or %FALSE if a handler + * for @scheme already exists. + * + * Since: 2.50 + */ +gboolean +g_vfs_register_uri_scheme (GVfs *vfs, + const char *scheme, + GVfsFileLookupFunc uri_func, + gpointer uri_data, + GDestroyNotify uri_destroy, + GVfsFileLookupFunc parse_name_func, + gpointer parse_name_data, + GDestroyNotify parse_name_destroy) +{ + GVfsPrivate *priv; + GVfsURISchemeData *closure; + + g_return_val_if_fail (G_IS_VFS (vfs), FALSE); + g_return_val_if_fail (scheme != NULL, FALSE); + + priv = g_vfs_get_instance_private (vfs); + + g_rw_lock_reader_lock (&additional_schemes_lock); + closure = g_hash_table_lookup (priv->additional_schemes, scheme); + g_rw_lock_reader_unlock (&additional_schemes_lock); + + if (closure != NULL) + return FALSE; + + closure = g_new0 (GVfsURISchemeData, 1); + closure->uri_func = uri_func; + closure->uri_data = uri_data; + closure->uri_destroy = uri_destroy; + closure->parse_name_func = parse_name_func; + closure->parse_name_data = parse_name_data; + closure->parse_name_destroy = parse_name_destroy; + + g_rw_lock_writer_lock (&additional_schemes_lock); + g_hash_table_insert (priv->additional_schemes, g_strdup (scheme), closure); + g_rw_lock_writer_unlock (&additional_schemes_lock); + + /* Invalidate supported schemes */ + g_clear_pointer (&priv->supported_schemes, g_free); + + return TRUE; +} + +/** + * g_vfs_unregister_uri_scheme: + * @vfs: a #GVfs + * @scheme: an URI scheme, e.g. "http" + * + * Unregisters the URI handler for @scheme previously registered with + * g_vfs_register_uri_scheme(). + * + * Returns: %TRUE if @scheme was successfully unregistered, or %FALSE if a + * handler for @scheme does not exist. + * + * Since: 2.50 + */ +gboolean +g_vfs_unregister_uri_scheme (GVfs *vfs, + const char *scheme) +{ + GVfsPrivate *priv; + gboolean res; + + g_return_val_if_fail (G_IS_VFS (vfs), FALSE); + g_return_val_if_fail (scheme != NULL, FALSE); + + priv = g_vfs_get_instance_private (vfs); + + g_rw_lock_writer_lock (&additional_schemes_lock); + res = g_hash_table_remove (priv->additional_schemes, scheme); + g_rw_lock_writer_unlock (&additional_schemes_lock); + + if (res) + { + /* Invalidate supported schemes */ + g_clear_pointer (&priv->supported_schemes, g_free); + + return TRUE; + } + + return FALSE; +} diff --git a/gio/gvfs.h b/gio/gvfs.h new file mode 100644 index 0000000..72fe2dd --- /dev/null +++ b/gio/gvfs.h @@ -0,0 +1,168 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_VFS_H__ +#define __G_VFS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_VFS (g_vfs_get_type ()) +#define G_VFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_VFS, GVfs)) +#define G_VFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_VFS, GVfsClass)) +#define G_VFS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VFS, GVfsClass)) +#define G_IS_VFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_VFS)) +#define G_IS_VFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS)) + +/** + * GVfsFileLookupFunc: + * @vfs: a #GVfs + * @identifier: the identifier to look up a #GFile for. This can either + * be an URI or a parse name as returned by g_file_get_parse_name() + * @user_data: user data passed to the function + * + * This function type is used by g_vfs_register_uri_scheme() to make it + * possible for a client to associate an URI scheme to a different #GFile + * implementation. + * + * The client should return a reference to the new file that has been + * created for @uri, or %NULL to continue with the default implementation. + * + * Returns: (transfer full): a #GFile for @identifier. + * + * Since: 2.50 + */ +typedef GFile * (* GVfsFileLookupFunc) (GVfs *vfs, + const char *identifier, + gpointer user_data); + +/** + * G_VFS_EXTENSION_POINT_NAME: + * + * Extension point for #GVfs functionality. + * See [Extending GIO][extending-gio]. + */ +#define G_VFS_EXTENSION_POINT_NAME "gio-vfs" + +/** + * GVfs: + * + * Virtual File System object. + **/ +typedef struct _GVfsClass GVfsClass; + +struct _GVfs +{ + GObject parent_instance; +}; + +struct _GVfsClass +{ + GObjectClass parent_class; + + /* Virtual Table */ + + gboolean (* is_active) (GVfs *vfs); + GFile * (* get_file_for_path) (GVfs *vfs, + const char *path); + GFile * (* get_file_for_uri) (GVfs *vfs, + const char *uri); + const gchar * const * (* get_supported_uri_schemes) (GVfs *vfs); + GFile * (* parse_name) (GVfs *vfs, + const char *parse_name); + + /*< private >*/ + void (* local_file_add_info) (GVfs *vfs, + const char *filename, + guint64 device, + GFileAttributeMatcher *attribute_matcher, + GFileInfo *info, + GCancellable *cancellable, + gpointer *extra_data, + GDestroyNotify *free_extra_data); + void (* add_writable_namespaces) (GVfs *vfs, + GFileAttributeInfoList *list); + gboolean (* local_file_set_attributes) (GVfs *vfs, + const char *filename, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + void (* local_file_removed) (GVfs *vfs, + const char *filename); + void (* local_file_moved) (GVfs *vfs, + const char *source, + const char *dest); + GIcon * (* deserialize_icon) (GVfs *vfs, + GVariant *value); + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_vfs_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +gboolean g_vfs_is_active (GVfs *vfs); +GLIB_AVAILABLE_IN_ALL +GFile * g_vfs_get_file_for_path (GVfs *vfs, + const char *path); +GLIB_AVAILABLE_IN_ALL +GFile * g_vfs_get_file_for_uri (GVfs *vfs, + const char *uri); +GLIB_AVAILABLE_IN_ALL +const gchar* const * g_vfs_get_supported_uri_schemes (GVfs *vfs); + +GLIB_AVAILABLE_IN_ALL +GFile * g_vfs_parse_name (GVfs *vfs, + const char *parse_name); + +GLIB_AVAILABLE_IN_ALL +GVfs * g_vfs_get_default (void); +GLIB_AVAILABLE_IN_ALL +GVfs * g_vfs_get_local (void); + +GLIB_AVAILABLE_IN_2_50 +gboolean g_vfs_register_uri_scheme (GVfs *vfs, + const char *scheme, + GVfsFileLookupFunc uri_func, + gpointer uri_data, + GDestroyNotify uri_destroy, + GVfsFileLookupFunc parse_name_func, + gpointer parse_name_data, + GDestroyNotify parse_name_destroy); +GLIB_AVAILABLE_IN_2_50 +gboolean g_vfs_unregister_uri_scheme (GVfs *vfs, + const char *scheme); + + +G_END_DECLS + +#endif /* __G_VFS_H__ */ diff --git a/gio/gvolume.c b/gio/gvolume.c new file mode 100644 index 0000000..cb6d34f --- /dev/null +++ b/gio/gvolume.c @@ -0,0 +1,687 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#include "config.h" +#include "gmount.h" +#include "gvolume.h" +#include "gthemedicon.h" +#include "gasyncresult.h" +#include "gtask.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gvolume + * @short_description: Volume management + * @include: gio/gio.h + * + * The #GVolume interface represents user-visible objects that can be + * mounted. Note, when porting from GnomeVFS, #GVolume is the moral + * equivalent of #GnomeVFSDrive. + * + * Mounting a #GVolume instance is an asynchronous operation. For more + * information about asynchronous operations, see #GAsyncResult and + * #GTask. To mount a #GVolume, first call g_volume_mount() with (at + * least) the #GVolume instance, optionally a #GMountOperation object + * and a #GAsyncReadyCallback. + * + * Typically, one will only want to pass %NULL for the + * #GMountOperation if automounting all volumes when a desktop session + * starts since it's not desirable to put up a lot of dialogs asking + * for credentials. + * + * The callback will be fired when the operation has resolved (either + * with success or failure), and a #GAsyncResult instance will be + * passed to the callback. That callback should then call + * g_volume_mount_finish() with the #GVolume instance and the + * #GAsyncResult data to see if the operation was completed + * successfully. If an @error is present when g_volume_mount_finish() + * is called, then it will be filled with any error information. + * + * ## Volume Identifiers # {#volume-identifier} + * + * It is sometimes necessary to directly access the underlying + * operating system object behind a volume (e.g. for passing a volume + * to an application via the commandline). For this purpose, GIO + * allows to obtain an 'identifier' for the volume. There can be + * different kinds of identifiers, such as Hal UDIs, filesystem labels, + * traditional Unix devices (e.g. `/dev/sda2`), UUIDs. GIO uses predefined + * strings as names for the different kinds of identifiers: + * %G_VOLUME_IDENTIFIER_KIND_UUID, %G_VOLUME_IDENTIFIER_KIND_LABEL, etc. + * Use g_volume_get_identifier() to obtain an identifier for a volume. + * + * + * Note that %G_VOLUME_IDENTIFIER_KIND_HAL_UDI will only be available + * when the gvfs hal volume monitor is in use. Other volume monitors + * will generally be able to provide the %G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE + * identifier, which can be used to obtain a hal device by means of + * libhal_manager_find_device_string_match(). + */ + +typedef GVolumeIface GVolumeInterface; +G_DEFINE_INTERFACE(GVolume, g_volume, G_TYPE_OBJECT) + +static void +g_volume_default_init (GVolumeInterface *iface) +{ + /** + * GVolume::changed: + * + * Emitted when the volume has been changed. + */ + g_signal_new (I_("changed"), + G_TYPE_VOLUME, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeIface, changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + /** + * GVolume::removed: + * + * This signal is emitted when the #GVolume have been removed. If + * the recipient is holding references to the object they should + * release them so the object can be finalized. + */ + g_signal_new (I_("removed"), + G_TYPE_VOLUME, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeIface, removed), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); +} + +/** + * g_volume_get_name: + * @volume: a #GVolume + * + * Gets the name of @volume. + * + * Returns: the name for the given @volume. The returned string should + * be freed with g_free() when no longer needed. + */ +char * +g_volume_get_name (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + + iface = G_VOLUME_GET_IFACE (volume); + + return (* iface->get_name) (volume); +} + +/** + * g_volume_get_icon: + * @volume: a #GVolume + * + * Gets the icon for @volume. + * + * Returns: (transfer full): a #GIcon. + * The returned object should be unreffed with g_object_unref() + * when no longer needed. + */ +GIcon * +g_volume_get_icon (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + + iface = G_VOLUME_GET_IFACE (volume); + + return (* iface->get_icon) (volume); +} + +/** + * g_volume_get_symbolic_icon: + * @volume: a #GVolume + * + * Gets the symbolic icon for @volume. + * + * Returns: (transfer full): a #GIcon. + * The returned object should be unreffed with g_object_unref() + * when no longer needed. + * + * Since: 2.34 + */ +GIcon * +g_volume_get_symbolic_icon (GVolume *volume) +{ + GVolumeIface *iface; + GIcon *ret; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->get_symbolic_icon != NULL) + ret = iface->get_symbolic_icon (volume); + else + ret = g_themed_icon_new_with_default_fallbacks ("folder-remote-symbolic"); + + return ret; + +} + +/** + * g_volume_get_uuid: + * @volume: a #GVolume + * + * Gets the UUID for the @volume. The reference is typically based on + * the file system UUID for the volume in question and should be + * considered an opaque string. Returns %NULL if there is no UUID + * available. + * + * Returns: (nullable) (transfer full): the UUID for @volume or %NULL if no UUID + * can be computed. + * The returned string should be freed with g_free() + * when no longer needed. + */ +char * +g_volume_get_uuid (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + + iface = G_VOLUME_GET_IFACE (volume); + + return (* iface->get_uuid) (volume); +} + +/** + * g_volume_get_drive: + * @volume: a #GVolume + * + * Gets the drive for the @volume. + * + * Returns: (transfer full) (nullable): a #GDrive or %NULL if @volume is not + * associated with a drive. The returned object should be unreffed + * with g_object_unref() when no longer needed. + */ +GDrive * +g_volume_get_drive (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + + iface = G_VOLUME_GET_IFACE (volume); + + return (* iface->get_drive) (volume); +} + +/** + * g_volume_get_mount: + * @volume: a #GVolume + * + * Gets the mount for the @volume. + * + * Returns: (transfer full) (nullable): a #GMount or %NULL if @volume isn't mounted. + * The returned object should be unreffed with g_object_unref() + * when no longer needed. + */ +GMount * +g_volume_get_mount (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + + iface = G_VOLUME_GET_IFACE (volume); + + return (* iface->get_mount) (volume); +} + + +/** + * g_volume_can_mount: + * @volume: a #GVolume + * + * Checks if a volume can be mounted. + * + * Returns: %TRUE if the @volume can be mounted. %FALSE otherwise + */ +gboolean +g_volume_can_mount (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->can_mount == NULL) + return FALSE; + + return (* iface->can_mount) (volume); +} + +/** + * g_volume_can_eject: + * @volume: a #GVolume + * + * Checks if a volume can be ejected. + * + * Returns: %TRUE if the @volume can be ejected. %FALSE otherwise + */ +gboolean +g_volume_can_eject (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->can_eject == NULL) + return FALSE; + + return (* iface->can_eject) (volume); +} + +/** + * g_volume_should_automount: + * @volume: a #GVolume + * + * Returns whether the volume should be automatically mounted. + * + * Returns: %TRUE if the volume should be automatically mounted + */ +gboolean +g_volume_should_automount (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->should_automount == NULL) + return FALSE; + + return (* iface->should_automount) (volume); +} + + +/** + * g_volume_mount: + * @volume: a #GVolume + * @flags: flags affecting the operation + * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid user interaction + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL + * @user_data: user data that gets passed to @callback + * + * Mounts a volume. This is an asynchronous operation, and is + * finished by calling g_volume_mount_finish() with the @volume + * and #GAsyncResult returned in the @callback. + * + * Virtual: mount_fn + */ +void +g_volume_mount (GVolume *volume, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVolumeIface *iface; + + g_return_if_fail (G_IS_VOLUME (volume)); + + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->mount_fn == NULL) + { + g_task_report_new_error (volume, callback, user_data, + g_volume_mount, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("volume doesn’t implement mount")); + return; + } + + (* iface->mount_fn) (volume, flags, mount_operation, cancellable, callback, user_data); +} + +/** + * g_volume_mount_finish: + * @volume: a #GVolume + * @result: a #GAsyncResult + * @error: a #GError location to store an error, or %NULL to ignore + * + * Finishes mounting a volume. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * If the mount operation succeeded, g_volume_get_mount() on @volume + * is guaranteed to return the mount right after calling this + * function; there's no need to listen for the 'mount-added' signal on + * #GVolumeMonitor. + * + * Returns: %TRUE, %FALSE if operation failed + */ +gboolean +g_volume_mount_finish (GVolume *volume, + GAsyncResult *result, + GError **error) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_volume_mount)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_VOLUME_GET_IFACE (volume); + return (* iface->mount_finish) (volume, result, error); +} + +/** + * g_volume_eject: + * @volume: a #GVolume + * @flags: flags affecting the unmount if required for eject + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL + * @user_data: user data that gets passed to @callback + * + * Ejects a volume. This is an asynchronous operation, and is + * finished by calling g_volume_eject_finish() with the @volume + * and #GAsyncResult returned in the @callback. + * + * Deprecated: 2.22: Use g_volume_eject_with_operation() instead. + */ +void +g_volume_eject (GVolume *volume, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVolumeIface *iface; + + g_return_if_fail (G_IS_VOLUME (volume)); + + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->eject == NULL) + { + g_task_report_new_error (volume, callback, user_data, + g_volume_eject_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("volume doesn’t implement eject")); + return; + } + + (* iface->eject) (volume, flags, cancellable, callback, user_data); +} + +/** + * g_volume_eject_finish: + * @volume: pointer to a #GVolume + * @result: a #GAsyncResult + * @error: a #GError location to store an error, or %NULL to ignore + * + * Finishes ejecting a volume. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * Returns: %TRUE, %FALSE if operation failed + * + * Deprecated: 2.22: Use g_volume_eject_with_operation_finish() instead. + **/ +gboolean +g_volume_eject_finish (GVolume *volume, + GAsyncResult *result, + GError **error) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + if (g_async_result_is_tagged (result, g_volume_eject_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_VOLUME_GET_IFACE (volume); + return (* iface->eject_finish) (volume, result, error); +} + +/** + * g_volume_eject_with_operation: + * @volume: a #GVolume + * @flags: flags affecting the unmount if required for eject + * @mount_operation: (nullable): a #GMountOperation or %NULL to + * avoid user interaction + * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore + * @callback: (nullable): a #GAsyncReadyCallback, or %NULL + * @user_data: user data passed to @callback + * + * Ejects a volume. This is an asynchronous operation, and is + * finished by calling g_volume_eject_with_operation_finish() with the @volume + * and #GAsyncResult data returned in the @callback. + * + * Since: 2.22 + **/ +void +g_volume_eject_with_operation (GVolume *volume, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVolumeIface *iface; + + g_return_if_fail (G_IS_VOLUME (volume)); + + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->eject == NULL && iface->eject_with_operation == NULL) + { + g_task_report_new_error (volume, callback, user_data, + g_volume_eject_with_operation, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + /* Translators: This is an error + * message for volume objects that + * don't implement any of eject or eject_with_operation. */ + _("volume doesn’t implement eject or eject_with_operation")); + return; + } + + if (iface->eject_with_operation != NULL) + (* iface->eject_with_operation) (volume, flags, mount_operation, cancellable, callback, user_data); + else + (* iface->eject) (volume, flags, cancellable, callback, user_data); +} + +/** + * g_volume_eject_with_operation_finish: + * @volume: a #GVolume + * @result: a #GAsyncResult + * @error: a #GError location to store the error occurring, or %NULL + * + * Finishes ejecting a volume. If any errors occurred during the operation, + * @error will be set to contain the errors and %FALSE will be returned. + * + * Returns: %TRUE if the volume was successfully ejected. %FALSE otherwise + * + * Since: 2.22 + **/ +gboolean +g_volume_eject_with_operation_finish (GVolume *volume, + GAsyncResult *result, + GError **error) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); + + if (g_async_result_legacy_propagate_error (result, error)) + return FALSE; + else if (g_async_result_is_tagged (result, g_volume_eject_with_operation)) + return g_task_propagate_boolean (G_TASK (result), error); + + iface = G_VOLUME_GET_IFACE (volume); + if (iface->eject_with_operation_finish != NULL) + return (* iface->eject_with_operation_finish) (volume, result, error); + else + return (* iface->eject_finish) (volume, result, error); +} + +/** + * g_volume_get_identifier: + * @volume: a #GVolume + * @kind: the kind of identifier to return + * + * Gets the identifier of the given kind for @volume. + * See the [introduction][volume-identifier] for more + * information about volume identifiers. + * + * Returns: (nullable) (transfer full): a newly allocated string containing the + * requested identifier, or %NULL if the #GVolume + * doesn't have this kind of identifier + */ +char * +g_volume_get_identifier (GVolume *volume, + const char *kind) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + g_return_val_if_fail (kind != NULL, NULL); + + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->get_identifier == NULL) + return NULL; + + return (* iface->get_identifier) (volume, kind); +} + +/** + * g_volume_enumerate_identifiers: + * @volume: a #GVolume + * + * Gets the kinds of [identifiers][volume-identifier] that @volume has. + * Use g_volume_get_identifier() to obtain the identifiers themselves. + * + * Returns: (array zero-terminated=1) (transfer full): a %NULL-terminated array + * of strings containing kinds of identifiers. Use g_strfreev() to free. + */ +char ** +g_volume_enumerate_identifiers (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->enumerate_identifiers == NULL) + return NULL; + + return (* iface->enumerate_identifiers) (volume); +} + +/** + * g_volume_get_activation_root: + * @volume: a #GVolume + * + * Gets the activation root for a #GVolume if it is known ahead of + * mount time. Returns %NULL otherwise. If not %NULL and if @volume + * is mounted, then the result of g_mount_get_root() on the + * #GMount object obtained from g_volume_get_mount() will always + * either be equal or a prefix of what this function returns. In + * other words, in code + * + * |[ + * GMount *mount; + * GFile *mount_root + * GFile *volume_activation_root; + * + * mount = g_volume_get_mount (volume); // mounted, so never NULL + * mount_root = g_mount_get_root (mount); + * volume_activation_root = g_volume_get_activation_root (volume); // assume not NULL + * ]| + * then the expression + * |[ + * (g_file_has_prefix (volume_activation_root, mount_root) || + * g_file_equal (volume_activation_root, mount_root)) + * ]| + * will always be %TRUE. + * + * Activation roots are typically used in #GVolumeMonitor + * implementations to find the underlying mount to shadow, see + * g_mount_is_shadowed() for more details. + * + * Returns: (nullable) (transfer full): the activation root of @volume + * or %NULL. Use g_object_unref() to free. + * + * Since: 2.18 + */ +GFile * +g_volume_get_activation_root (GVolume *volume) +{ + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + iface = G_VOLUME_GET_IFACE (volume); + + if (iface->get_activation_root == NULL) + return NULL; + + return (* iface->get_activation_root) (volume); +} + +/** + * g_volume_get_sort_key: + * @volume: a #GVolume + * + * Gets the sort key for @volume, if any. + * + * Returns: (nullable): Sorting key for @volume or %NULL if no such key is available + * + * Since: 2.32 + */ +const gchar * +g_volume_get_sort_key (GVolume *volume) +{ + const gchar *ret = NULL; + GVolumeIface *iface; + + g_return_val_if_fail (G_IS_VOLUME (volume), NULL); + + iface = G_VOLUME_GET_IFACE (volume); + if (iface->get_sort_key != NULL) + ret = iface->get_sort_key (volume); + + return ret; +} diff --git a/gio/gvolume.h b/gio/gvolume.h new file mode 100644 index 0000000..e153b7c --- /dev/null +++ b/gio/gvolume.h @@ -0,0 +1,253 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#ifndef __G_VOLUME_H__ +#define __G_VOLUME_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_VOLUME_IDENTIFIER_KIND_HAL_UDI: + * + * The string used to obtain a Hal UDI with g_volume_get_identifier(). + * + * Deprecated: 2.58: Do not use, HAL is deprecated. + */ +#define G_VOLUME_IDENTIFIER_KIND_HAL_UDI "hal-udi" GLIB_DEPRECATED_MACRO_IN_2_58 + +/** + * G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE: + * + * The string used to obtain a Unix device path with g_volume_get_identifier(). + */ +#define G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE "unix-device" + +/** + * G_VOLUME_IDENTIFIER_KIND_LABEL: + * + * The string used to obtain a filesystem label with g_volume_get_identifier(). + */ +#define G_VOLUME_IDENTIFIER_KIND_LABEL "label" + +/** + * G_VOLUME_IDENTIFIER_KIND_UUID: + * + * The string used to obtain a UUID with g_volume_get_identifier(). + */ +#define G_VOLUME_IDENTIFIER_KIND_UUID "uuid" + +/** + * G_VOLUME_IDENTIFIER_KIND_NFS_MOUNT: + * + * The string used to obtain a NFS mount with g_volume_get_identifier(). + */ +#define G_VOLUME_IDENTIFIER_KIND_NFS_MOUNT "nfs-mount" + +/** + * G_VOLUME_IDENTIFIER_KIND_CLASS: + * + * The string used to obtain the volume class with g_volume_get_identifier(). + * + * Known volume classes include `device`, `network`, and `loop`. Other + * classes may be added in the future. + * + * This is intended to be used by applications to classify #GVolume + * instances into different sections - for example a file manager or + * file chooser can use this information to show `network` volumes under + * a "Network" heading and `device` volumes under a "Devices" heading. + */ +#define G_VOLUME_IDENTIFIER_KIND_CLASS "class" + + +#define G_TYPE_VOLUME (g_volume_get_type ()) +#define G_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_VOLUME, GVolume)) +#define G_IS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_VOLUME)) +#define G_VOLUME_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_VOLUME, GVolumeIface)) + +/** + * GVolumeIface: + * @g_iface: The parent interface. + * @changed: Changed signal that is emitted when the volume's state has changed. + * @removed: The removed signal that is emitted when the #GVolume have been removed. If the recipient is holding references to the object they should release them so the object can be finalized. + * @get_name: Gets a string containing the name of the #GVolume. + * @get_icon: Gets a #GIcon for the #GVolume. + * @get_uuid: Gets the UUID for the #GVolume. The reference is typically based on the file system UUID for the mount in question and should be considered an opaque string. Returns %NULL if there is no UUID available. + * @get_drive: Gets a #GDrive the volume is located on. Returns %NULL if the #GVolume is not associated with a #GDrive. + * @get_mount: Gets a #GMount representing the mounted volume. Returns %NULL if the #GVolume is not mounted. + * @can_mount: Returns %TRUE if the #GVolume can be mounted. + * @can_eject: Checks if a #GVolume can be ejected. + * @mount_fn: Mounts a given #GVolume. + * #GVolume implementations must emit the #GMountOperation::aborted + * signal before completing a mount operation that is aborted while + * awaiting input from the user through a #GMountOperation instance. + * @mount_finish: Finishes a mount operation. + * @eject: Ejects a given #GVolume. + * @eject_finish: Finishes an eject operation. + * @get_identifier: Returns the [identifier][volume-identifier] of the given kind, or %NULL if + * the #GVolume doesn't have one. + * @enumerate_identifiers: Returns an array strings listing the kinds + * of [identifiers][volume-identifier] which the #GVolume has. + * @should_automount: Returns %TRUE if the #GVolume should be automatically mounted. + * @get_activation_root: Returns the activation root for the #GVolume if it is known in advance or %NULL if + * it is not known. + * @eject_with_operation: Starts ejecting a #GVolume using a #GMountOperation. Since 2.22. + * @eject_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22. + * @get_sort_key: Gets a key used for sorting #GVolume instance or %NULL if no such key exists. Since 2.32. + * @get_symbolic_icon: Gets a symbolic #GIcon for the #GVolume. Since 2.34. + * + * Interface for implementing operations for mountable volumes. + **/ +typedef struct _GVolumeIface GVolumeIface; + +struct _GVolumeIface +{ + GTypeInterface g_iface; + + /* signals */ + + void (* changed) (GVolume *volume); + void (* removed) (GVolume *volume); + + /* Virtual Table */ + + char * (* get_name) (GVolume *volume); + GIcon * (* get_icon) (GVolume *volume); + char * (* get_uuid) (GVolume *volume); + GDrive * (* get_drive) (GVolume *volume); + GMount * (* get_mount) (GVolume *volume); + gboolean (* can_mount) (GVolume *volume); + gboolean (* can_eject) (GVolume *volume); + void (* mount_fn) (GVolume *volume, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* mount_finish) (GVolume *volume, + GAsyncResult *result, + GError **error); + void (* eject) (GVolume *volume, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* eject_finish) (GVolume *volume, + GAsyncResult *result, + GError **error); + + char * (* get_identifier) (GVolume *volume, + const char *kind); + char ** (* enumerate_identifiers) (GVolume *volume); + + gboolean (* should_automount) (GVolume *volume); + + GFile * (* get_activation_root) (GVolume *volume); + + void (* eject_with_operation) (GVolume *volume, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* eject_with_operation_finish) (GVolume *volume, + GAsyncResult *result, + GError **error); + + const gchar * (* get_sort_key) (GVolume *volume); + GIcon * (* get_symbolic_icon) (GVolume *volume); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_volume_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +char * g_volume_get_name (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +GIcon * g_volume_get_icon (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +GIcon * g_volume_get_symbolic_icon (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +char * g_volume_get_uuid (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +GDrive * g_volume_get_drive (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +GMount * g_volume_get_mount (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +gboolean g_volume_can_mount (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +gboolean g_volume_can_eject (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +gboolean g_volume_should_automount (GVolume *volume); +GLIB_AVAILABLE_IN_ALL +void g_volume_mount (GVolume *volume, + GMountMountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_volume_mount_finish (GVolume *volume, + GAsyncResult *result, + GError **error); +GLIB_DEPRECATED_FOR(g_volume_eject_with_operation) +void g_volume_eject (GVolume *volume, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GLIB_DEPRECATED_FOR(g_volume_eject_with_operation_finish) +gboolean g_volume_eject_finish (GVolume *volume, + GAsyncResult *result, + GError **error); +GLIB_AVAILABLE_IN_ALL +char * g_volume_get_identifier (GVolume *volume, + const char *kind); +GLIB_AVAILABLE_IN_ALL +char ** g_volume_enumerate_identifiers (GVolume *volume); + +GLIB_AVAILABLE_IN_ALL +GFile * g_volume_get_activation_root (GVolume *volume); + +GLIB_AVAILABLE_IN_ALL +void g_volume_eject_with_operation (GVolume *volume, + GMountUnmountFlags flags, + GMountOperation *mount_operation, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gboolean g_volume_eject_with_operation_finish (GVolume *volume, + GAsyncResult *result, + GError **error); + +GLIB_AVAILABLE_IN_2_32 +const gchar *g_volume_get_sort_key (GVolume *volume); + +G_END_DECLS + +#endif /* __G_VOLUME_H__ */ diff --git a/gio/gvolumemonitor.c b/gio/gvolumemonitor.c new file mode 100644 index 0000000..056999f --- /dev/null +++ b/gio/gvolumemonitor.c @@ -0,0 +1,395 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#include "config.h" +#include "gvolumemonitor.h" +#include "gvolume.h" +#include "gmount.h" +#include "gdrive.h" +#include "glibintl.h" + + +/** + * SECTION:gvolumemonitor + * @short_description: Volume Monitor + * @include: gio/gio.h + * @see_also: #GFileMonitor + * + * #GVolumeMonitor is for listing the user interesting devices and volumes + * on the computer. In other words, what a file selector or file manager + * would show in a sidebar. + * + * #GVolumeMonitor is not + * [thread-default-context aware][g-main-context-push-thread-default], + * and so should not be used other than from the main thread, with no + * thread-default-context active. + * + * In order to receive updates about volumes and mounts monitored through GVFS, + * a main loop must be running. + **/ + +G_DEFINE_TYPE (GVolumeMonitor, g_volume_monitor, G_TYPE_OBJECT) + +enum { + VOLUME_ADDED, + VOLUME_REMOVED, + VOLUME_CHANGED, + MOUNT_ADDED, + MOUNT_REMOVED, + MOUNT_PRE_UNMOUNT, + MOUNT_CHANGED, + DRIVE_CONNECTED, + DRIVE_DISCONNECTED, + DRIVE_CHANGED, + DRIVE_EJECT_BUTTON, + DRIVE_STOP_BUTTON, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + + +static void +g_volume_monitor_finalize (GObject *object) +{ + G_OBJECT_CLASS (g_volume_monitor_parent_class)->finalize (object); +} + +static void +g_volume_monitor_class_init (GVolumeMonitorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_volume_monitor_finalize; + + /** + * GVolumeMonitor::volume-added: + * @volume_monitor: The volume monitor emitting the signal. + * @volume: a #GVolume that was added. + * + * Emitted when a mountable volume is added to the system. + **/ + signals[VOLUME_ADDED] = g_signal_new (I_("volume-added"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, volume_added), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_VOLUME); + + /** + * GVolumeMonitor::volume-removed: + * @volume_monitor: The volume monitor emitting the signal. + * @volume: a #GVolume that was removed. + * + * Emitted when a mountable volume is removed from the system. + **/ + signals[VOLUME_REMOVED] = g_signal_new (I_("volume-removed"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, volume_removed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_VOLUME); + + /** + * GVolumeMonitor::volume-changed: + * @volume_monitor: The volume monitor emitting the signal. + * @volume: a #GVolume that changed. + * + * Emitted when mountable volume is changed. + **/ + signals[VOLUME_CHANGED] = g_signal_new (I_("volume-changed"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, volume_changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_VOLUME); + + /** + * GVolumeMonitor::mount-added: + * @volume_monitor: The volume monitor emitting the signal. + * @mount: a #GMount that was added. + * + * Emitted when a mount is added. + **/ + signals[MOUNT_ADDED] = g_signal_new (I_("mount-added"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, mount_added), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_MOUNT); + + /** + * GVolumeMonitor::mount-removed: + * @volume_monitor: The volume monitor emitting the signal. + * @mount: a #GMount that was removed. + * + * Emitted when a mount is removed. + **/ + signals[MOUNT_REMOVED] = g_signal_new (I_("mount-removed"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, mount_removed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_MOUNT); + + /** + * GVolumeMonitor::mount-pre-unmount: + * @volume_monitor: The volume monitor emitting the signal. + * @mount: a #GMount that is being unmounted. + * + * May be emitted when a mount is about to be removed. + * + * This signal depends on the backend and is only emitted if + * GIO was used to unmount. + **/ + signals[MOUNT_PRE_UNMOUNT] = g_signal_new (I_("mount-pre-unmount"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, mount_pre_unmount), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_MOUNT); + + /** + * GVolumeMonitor::mount-changed: + * @volume_monitor: The volume monitor emitting the signal. + * @mount: a #GMount that changed. + * + * Emitted when a mount changes. + **/ + signals[MOUNT_CHANGED] = g_signal_new (I_("mount-changed"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, mount_changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_MOUNT); + + /** + * GVolumeMonitor::drive-connected: + * @volume_monitor: The volume monitor emitting the signal. + * @drive: a #GDrive that was connected. + * + * Emitted when a drive is connected to the system. + **/ + signals[DRIVE_CONNECTED] = g_signal_new (I_("drive-connected"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, drive_connected), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_DRIVE); + + /** + * GVolumeMonitor::drive-disconnected: + * @volume_monitor: The volume monitor emitting the signal. + * @drive: a #GDrive that was disconnected. + * + * Emitted when a drive is disconnected from the system. + **/ + signals[DRIVE_DISCONNECTED] = g_signal_new (I_("drive-disconnected"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, drive_disconnected), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_DRIVE); + + /** + * GVolumeMonitor::drive-changed: + * @volume_monitor: The volume monitor emitting the signal. + * @drive: the drive that changed + * + * Emitted when a drive changes. + **/ + signals[DRIVE_CHANGED] = g_signal_new (I_("drive-changed"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, drive_changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_DRIVE); + + /** + * GVolumeMonitor::drive-eject-button: + * @volume_monitor: The volume monitor emitting the signal. + * @drive: the drive where the eject button was pressed + * + * Emitted when the eject button is pressed on @drive. + * + * Since: 2.18 + **/ + signals[DRIVE_EJECT_BUTTON] = g_signal_new (I_("drive-eject-button"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, drive_eject_button), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_DRIVE); + + /** + * GVolumeMonitor::drive-stop-button: + * @volume_monitor: The volume monitor emitting the signal. + * @drive: the drive where the stop button was pressed + * + * Emitted when the stop button is pressed on @drive. + * + * Since: 2.22 + **/ + signals[DRIVE_STOP_BUTTON] = g_signal_new (I_("drive-stop-button"), + G_TYPE_VOLUME_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GVolumeMonitorClass, drive_stop_button), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_DRIVE); + +} + +static void +g_volume_monitor_init (GVolumeMonitor *monitor) +{ +} + + +/** + * g_volume_monitor_get_connected_drives: + * @volume_monitor: a #GVolumeMonitor. + * + * Gets a list of drives connected to the system. + * + * The returned list should be freed with g_list_free(), after + * its elements have been unreffed with g_object_unref(). + * + * Returns: (element-type GDrive) (transfer full): a #GList of connected #GDrive objects. + **/ +GList * +g_volume_monitor_get_connected_drives (GVolumeMonitor *volume_monitor) +{ + GVolumeMonitorClass *class; + + g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL); + + class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor); + + return class->get_connected_drives (volume_monitor); +} + +/** + * g_volume_monitor_get_volumes: + * @volume_monitor: a #GVolumeMonitor. + * + * Gets a list of the volumes on the system. + * + * The returned list should be freed with g_list_free(), after + * its elements have been unreffed with g_object_unref(). + * + * Returns: (element-type GVolume) (transfer full): a #GList of #GVolume objects. + **/ +GList * +g_volume_monitor_get_volumes (GVolumeMonitor *volume_monitor) +{ + GVolumeMonitorClass *class; + + g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL); + + class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor); + + return class->get_volumes (volume_monitor); +} + +/** + * g_volume_monitor_get_mounts: + * @volume_monitor: a #GVolumeMonitor. + * + * Gets a list of the mounts on the system. + * + * The returned list should be freed with g_list_free(), after + * its elements have been unreffed with g_object_unref(). + * + * Returns: (element-type GMount) (transfer full): a #GList of #GMount objects. + **/ +GList * +g_volume_monitor_get_mounts (GVolumeMonitor *volume_monitor) +{ + GVolumeMonitorClass *class; + + g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL); + + class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor); + + return class->get_mounts (volume_monitor); +} + +/** + * g_volume_monitor_get_volume_for_uuid: + * @volume_monitor: a #GVolumeMonitor. + * @uuid: the UUID to look for + * + * Finds a #GVolume object by its UUID (see g_volume_get_uuid()) + * + * Returns: (nullable) (transfer full): a #GVolume or %NULL if no such volume is available. + * Free the returned object with g_object_unref(). + **/ +GVolume * +g_volume_monitor_get_volume_for_uuid (GVolumeMonitor *volume_monitor, + const char *uuid) +{ + GVolumeMonitorClass *class; + + g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL); + g_return_val_if_fail (uuid != NULL, NULL); + + class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor); + + return class->get_volume_for_uuid (volume_monitor, uuid); +} + +/** + * g_volume_monitor_get_mount_for_uuid: + * @volume_monitor: a #GVolumeMonitor. + * @uuid: the UUID to look for + * + * Finds a #GMount object by its UUID (see g_mount_get_uuid()) + * + * Returns: (nullable) (transfer full): a #GMount or %NULL if no such mount is available. + * Free the returned object with g_object_unref(). + **/ +GMount * +g_volume_monitor_get_mount_for_uuid (GVolumeMonitor *volume_monitor, + const char *uuid) +{ + GVolumeMonitorClass *class; + + g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL); + g_return_val_if_fail (uuid != NULL, NULL); + + class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor); + + return class->get_mount_for_uuid (volume_monitor, uuid); +} diff --git a/gio/gvolumemonitor.h b/gio/gvolumemonitor.h new file mode 100644 index 0000000..899942f --- /dev/null +++ b/gio/gvolumemonitor.h @@ -0,0 +1,154 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + */ + +#ifndef __G_VOLUME_MONITOR_H__ +#define __G_VOLUME_MONITOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_VOLUME_MONITOR (g_volume_monitor_get_type ()) +#define G_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_VOLUME_MONITOR, GVolumeMonitor)) +#define G_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_VOLUME_MONITOR, GVolumeMonitorClass)) +#define G_VOLUME_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VOLUME_MONITOR, GVolumeMonitorClass)) +#define G_IS_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_VOLUME_MONITOR)) +#define G_IS_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VOLUME_MONITOR)) + +/** + * G_VOLUME_MONITOR_EXTENSION_POINT_NAME: + * + * Extension point for volume monitor functionality. + * See [Extending GIO][extending-gio]. + */ +#define G_VOLUME_MONITOR_EXTENSION_POINT_NAME "gio-volume-monitor" + +/** + * GVolumeMonitor: + * + * A Volume Monitor that watches for volume events. + **/ +typedef struct _GVolumeMonitorClass GVolumeMonitorClass; + +struct _GVolumeMonitor +{ + GObject parent_instance; + + /*< private >*/ + gpointer priv; +}; + +struct _GVolumeMonitorClass +{ + GObjectClass parent_class; + + /*< public >*/ + /* signals */ + void (* volume_added) (GVolumeMonitor *volume_monitor, + GVolume *volume); + void (* volume_removed) (GVolumeMonitor *volume_monitor, + GVolume *volume); + void (* volume_changed) (GVolumeMonitor *volume_monitor, + GVolume *volume); + + void (* mount_added) (GVolumeMonitor *volume_monitor, + GMount *mount); + void (* mount_removed) (GVolumeMonitor *volume_monitor, + GMount *mount); + void (* mount_pre_unmount) (GVolumeMonitor *volume_monitor, + GMount *mount); + void (* mount_changed) (GVolumeMonitor *volume_monitor, + GMount *mount); + + void (* drive_connected) (GVolumeMonitor *volume_monitor, + GDrive *drive); + void (* drive_disconnected) (GVolumeMonitor *volume_monitor, + GDrive *drive); + void (* drive_changed) (GVolumeMonitor *volume_monitor, + GDrive *drive); + + /* Vtable */ + + gboolean (* is_supported) (void); + + GList * (* get_connected_drives) (GVolumeMonitor *volume_monitor); + GList * (* get_volumes) (GVolumeMonitor *volume_monitor); + GList * (* get_mounts) (GVolumeMonitor *volume_monitor); + + GVolume * (* get_volume_for_uuid) (GVolumeMonitor *volume_monitor, + const char *uuid); + + GMount * (* get_mount_for_uuid) (GVolumeMonitor *volume_monitor, + const char *uuid); + + + /* These arguments are unfortunately backwards by mistake (bug #520169). Deprecated in 2.20. */ + GVolume * (* adopt_orphan_mount) (GMount *mount, + GVolumeMonitor *volume_monitor); + + /* signal added in 2.17 */ + void (* drive_eject_button) (GVolumeMonitor *volume_monitor, + GDrive *drive); + + /* signal added in 2.21 */ + void (* drive_stop_button) (GVolumeMonitor *volume_monitor, + GDrive *drive); + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); + void (*_g_reserved6) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_volume_monitor_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GVolumeMonitor *g_volume_monitor_get (void); +GLIB_AVAILABLE_IN_ALL +GList * g_volume_monitor_get_connected_drives (GVolumeMonitor *volume_monitor); +GLIB_AVAILABLE_IN_ALL +GList * g_volume_monitor_get_volumes (GVolumeMonitor *volume_monitor); +GLIB_AVAILABLE_IN_ALL +GList * g_volume_monitor_get_mounts (GVolumeMonitor *volume_monitor); +GLIB_AVAILABLE_IN_ALL +GVolume * g_volume_monitor_get_volume_for_uuid (GVolumeMonitor *volume_monitor, + const char *uuid); +GLIB_AVAILABLE_IN_ALL +GMount * g_volume_monitor_get_mount_for_uuid (GVolumeMonitor *volume_monitor, + const char *uuid); + +GLIB_DEPRECATED +GVolume * g_volume_monitor_adopt_orphan_mount (GMount *mount); + +G_END_DECLS + +#endif /* __G_VOLUME_MONITOR_H__ */ diff --git a/gio/gwin32api-application-activation-manager.h b/gio/gwin32api-application-activation-manager.h new file mode 100755 index 0000000..cf44b93 --- /dev/null +++ b/gio/gwin32api-application-activation-manager.h @@ -0,0 +1,126 @@ +#if NTDDI_VERSION < NTDDI_WIN8 +/* The following code is copied verbatim from MinGW-w64 shobjidl.h */ +/* + * IApplicationActivationManager interface + */ +typedef enum ACTIVATEOPTIONS { + AO_NONE = 0x0, + AO_DESIGNMODE = 0x1, + AO_NOERRORUI = 0x2, + AO_NOSPLASHSCREEN = 0x4 +} ACTIVATEOPTIONS; + +DEFINE_ENUM_FLAG_OPERATORS(ACTIVATEOPTIONS) + +#ifndef __IApplicationActivationManager_INTERFACE_DEFINED__ +#define __IApplicationActivationManager_INTERFACE_DEFINED__ + +DEFINE_GUID(IID_IApplicationActivationManager, 0x2e941141, 0x7f97, 0x4756, 0xba,0x1d, 0x9d,0xec,0xde,0x89,0x4a,0x3d); +#if defined(__cplusplus) && !defined(CINTERFACE) +MIDL_INTERFACE("2e941141-7f97-4756-ba1d-9decde894a3d") +IApplicationActivationManager : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE ActivateApplication( + LPCWSTR appUserModelId, + LPCWSTR arguments, + ACTIVATEOPTIONS options, + DWORD *processId) = 0; + + virtual HRESULT STDMETHODCALLTYPE ActivateForFile( + LPCWSTR appUserModelId, + IShellItemArray *itemArray, + LPCWSTR verb, + DWORD *processId) = 0; + + virtual HRESULT STDMETHODCALLTYPE ActivateForProtocol( + LPCWSTR appUserModelId, + IShellItemArray *itemArray, + DWORD *processId) = 0; + +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(IApplicationActivationManager, 0x2e941141, 0x7f97, 0x4756, 0xba,0x1d, 0x9d,0xec,0xde,0x89,0x4a,0x3d) +#endif +#else +typedef struct IApplicationActivationManagerVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IApplicationActivationManager *This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IApplicationActivationManager *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IApplicationActivationManager *This); + + /*** IApplicationActivationManager methods ***/ + HRESULT (STDMETHODCALLTYPE *ActivateApplication)( + IApplicationActivationManager *This, + LPCWSTR appUserModelId, + LPCWSTR arguments, + ACTIVATEOPTIONS options, + DWORD *processId); + + HRESULT (STDMETHODCALLTYPE *ActivateForFile)( + IApplicationActivationManager *This, + LPCWSTR appUserModelId, + IShellItemArray *itemArray, + LPCWSTR verb, + DWORD *processId); + + HRESULT (STDMETHODCALLTYPE *ActivateForProtocol)( + IApplicationActivationManager *This, + LPCWSTR appUserModelId, + IShellItemArray *itemArray, + DWORD *processId); + + END_INTERFACE +} IApplicationActivationManagerVtbl; + +interface IApplicationActivationManager { + CONST_VTBL IApplicationActivationManagerVtbl* lpVtbl; +}; + +#ifdef COBJMACROS +#ifndef WIDL_C_INLINE_WRAPPERS +/*** IUnknown methods ***/ +#define IApplicationActivationManager_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject) +#define IApplicationActivationManager_AddRef(This) (This)->lpVtbl->AddRef(This) +#define IApplicationActivationManager_Release(This) (This)->lpVtbl->Release(This) +/*** IApplicationActivationManager methods ***/ +#define IApplicationActivationManager_ActivateApplication(This,appUserModelId,arguments,options,processId) (This)->lpVtbl->ActivateApplication(This,appUserModelId,arguments,options,processId) +#define IApplicationActivationManager_ActivateForFile(This,appUserModelId,itemArray,verb,processId) (This)->lpVtbl->ActivateForFile(This,appUserModelId,itemArray,verb,processId) +#define IApplicationActivationManager_ActivateForProtocol(This,appUserModelId,itemArray,processId) (This)->lpVtbl->ActivateForProtocol(This,appUserModelId,itemArray,processId) +#else +/*** IUnknown methods ***/ +static FORCEINLINE HRESULT IApplicationActivationManager_QueryInterface(IApplicationActivationManager* This,REFIID riid,void **ppvObject) { + return This->lpVtbl->QueryInterface(This,riid,ppvObject); +} +static FORCEINLINE ULONG IApplicationActivationManager_AddRef(IApplicationActivationManager* This) { + return This->lpVtbl->AddRef(This); +} +static FORCEINLINE ULONG IApplicationActivationManager_Release(IApplicationActivationManager* This) { + return This->lpVtbl->Release(This); +} +/*** IApplicationActivationManager methods ***/ +static FORCEINLINE HRESULT IApplicationActivationManager_ActivateApplication(IApplicationActivationManager* This,LPCWSTR appUserModelId,LPCWSTR arguments,ACTIVATEOPTIONS options,DWORD *processId) { + return This->lpVtbl->ActivateApplication(This,appUserModelId,arguments,options,processId); +} +static FORCEINLINE HRESULT IApplicationActivationManager_ActivateForFile(IApplicationActivationManager* This,LPCWSTR appUserModelId,IShellItemArray *itemArray,LPCWSTR verb,DWORD *processId) { + return This->lpVtbl->ActivateForFile(This,appUserModelId,itemArray,verb,processId); +} +static FORCEINLINE HRESULT IApplicationActivationManager_ActivateForProtocol(IApplicationActivationManager* This,LPCWSTR appUserModelId,IShellItemArray *itemArray,DWORD *processId) { + return This->lpVtbl->ActivateForProtocol(This,appUserModelId,itemArray,processId); +} +#endif +#endif + +#endif + + +#endif /* __IApplicationActivationManager_INTERFACE_DEFINED__ */ +#endif /* NTDDI_VERSION < NTDDI_WIN8 */ \ No newline at end of file diff --git a/gio/gwin32api-iterator.h b/gio/gwin32api-iterator.h new file mode 100755 index 0000000..d4df8a7 --- /dev/null +++ b/gio/gwin32api-iterator.h @@ -0,0 +1,125 @@ +typedef interface IIterator IIterator; +typedef interface IIterable IIterable; + +/* IIterator */ +typedef struct IIteratorVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IIterator *This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IIterator *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IIterator *This); + + /*** IInspectable methods ***/ + HRESULT (STDMETHODCALLTYPE *GetIids)( + IIterator *This, + UINT32 *count, + IID **ids); + + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)( + IIterator *This, + HSTRING *className); + + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)( + IIterator *This, + TrustLevel *trustLevel); + + /*** IIterator methods ***/ + HRESULT (STDMETHODCALLTYPE *get_Current)( + IIterator *This, + IUnknown **current); + + HRESULT (STDMETHODCALLTYPE *get_HasCurrent)( + IIterator *This, + CHAR *hasCurrent); + + HRESULT (STDMETHODCALLTYPE *MoveNext)( + IIterator *This, + CHAR *hasCurrent); + + HRESULT (STDMETHODCALLTYPE *GetMany)( + IIterator *This, + UINT capacity, + void *value, + UINT *actual); + + END_INTERFACE +} IIteratorVtbl; + +interface IIterator { + CONST_VTBL IIteratorVtbl* lpVtbl; +}; + +/*** IUnknown methods ***/ +#define IIterator_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject) +#define IIterator_AddRef(This) (This)->lpVtbl->AddRef(This) +#define IIterator_Release(This) (This)->lpVtbl->Release(This) +/*** IInspectable methods ***/ +#define IIterator_GetIids(This,count,ids) (This)->lpVtbl->GetIids(This,count,ids) +#define IIterator_GetRuntimeClassName(This,name) (This)->lpVtbl->GetRuntimeClassName(This,name) +#define IIterator_GetTrustLevel(This,level) (This)->lpVtbl->GetTrustLevel(This,level) +/*** IIterator methods ***/ +#define IIterator_get_Current(This,current) (This)->lpVtbl->get_Current(This,current) +#define IIterator_get_HasCurrent(This,hasCurrent) (This)->lpVtbl->get_HasCurrent(This,hasCurrent) +#define IIterator_MoveNext(This,hasCurrent) (This)->lpVtbl->MoveNext(This,hasCurrent) +#define IIterator_GetMany(This,capacity,value,actual) (This)->lpVtbl->GetMany(This,capacity,value,actual) + +/* IIterable */ +typedef struct IIterableVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IIterable *This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IIterable *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IIterable *This); + + /*** IInspectable methods ***/ + HRESULT (STDMETHODCALLTYPE *GetIids)( + IIterable *This, + UINT32 *count, + IID **ids); + + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)( + IIterable *This, + HSTRING *className); + + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)( + IIterable *This, + TrustLevel *trustLevel); + + /*** IIterable methods ***/ + HRESULT (STDMETHODCALLTYPE *First)( + IIterable *This, + IIterator **first); + + END_INTERFACE +} IIterableVtbl; + +interface IIterable { + CONST_VTBL IIterableVtbl* lpVtbl; +}; + +/*** IUnknown methods ***/ +#define IIterable_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject) +#define IIterable_AddRef(This) (This)->lpVtbl->AddRef(This) +#define IIterable_Release(This) (This)->lpVtbl->Release(This) +/*** IInspectable methods ***/ +#define IIterable_GetIids(This,count,ids) (This)->lpVtbl->GetIids(This,count,ids) +#define IIterable_GetRuntimeClassName(This,name) (This)->lpVtbl->GetRuntimeClassName(This,name) +#define IIterable_GetTrustLevel(This,level) (This)->lpVtbl->GetTrustLevel(This,level) +/*** IIterable methods ***/ +#define IIterable_First(This,retval) (This)->lpVtbl->First(This,retval) diff --git a/gio/gwin32api-misc.h b/gio/gwin32api-misc.h new file mode 100755 index 0000000..2b45d9a --- /dev/null +++ b/gio/gwin32api-misc.h @@ -0,0 +1 @@ +typedef interface IProcessorArchitecture IProcessorArchitecture; diff --git a/gio/gwin32api-package.h b/gio/gwin32api-package.h new file mode 100755 index 0000000..9842a86 --- /dev/null +++ b/gio/gwin32api-package.h @@ -0,0 +1,264 @@ +typedef interface IPackageManager IPackageManager; +typedef interface IPackage IPackage; +typedef interface IPackageId IPackageId; +typedef interface IPackageVersion IPackageVersion; + +DEFINE_GUID(IID_IPackageManager, 0x9A7D4B65, 0x5E8F, 0x4FC7, 0xA2, 0xE5, 0x7F, 0x69, 0x25, 0xCB, 0x8B, 0x53); +DEFINE_GUID(IID_IPackage, 0x163C792F, 0xBD75, 0x413C, 0xBF, 0x23, 0xB1, 0xFE, 0x7B, 0x95, 0xD8, 0x25); + +/* IPackageManager */ +typedef struct IPackageManagerVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IPackageManager *This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IPackageManager *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IPackageManager *This); + + /*** IInspectable methods ***/ + HRESULT (STDMETHODCALLTYPE *GetIids)( + IPackageManager *This, + UINT32 *count, + IID **ids); + + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)( + IPackageManager *This, + HSTRING *className); + + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)( + IPackageManager *This, + TrustLevel *trustLevel); + + /*** IPackageManager methods ***/ + HRESULT (STDMETHODCALLTYPE *stub_AddPackageAsync)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_UpdatePackageAsync)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_RemovePackageAsync)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_StagePackageAsync)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_RegisterPackageAsync)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *FindPackages)( + IPackageManager *This, + IIterable **retval); + + HRESULT (STDMETHODCALLTYPE *FindPackagesByUserSecurityId)( + IPackageManager *This, + HSTRING userSecurityId, + IIterable **retval); + + HRESULT (STDMETHODCALLTYPE *stub_FindPackagesByNamePublisher)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_FindPackagesByUserSecurityIdNamePublisher)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_FindUsers)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_SetPackageState)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_FindPackageByPackageFullName)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_CleanupPackageForUserAsync)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_FindPackagesByPackageFamilyName)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_FindPackagesByUserSecurityIdPackageFamilyName)( + IPackageManager *This); + + HRESULT (STDMETHODCALLTYPE *stub_FindPackageByUserSecurityIdPackageFullName)( + IPackageManager *This); + + END_INTERFACE +} IPackageManagerVtbl; + +interface IPackageManager { + CONST_VTBL IPackageManagerVtbl* lpVtbl; +}; + +/*** IUnknown methods ***/ +#define IPackageManager_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject) +#define IPackageManager_AddRef(This) (This)->lpVtbl->AddRef(This) +#define IPackageManager_Release(This) (This)->lpVtbl->Release(This) +/*** IInspectable methods ***/ +#define IPackageManager_GetIids(This,count,ids) (This)->lpVtbl->GetIids(This,count,ids) +#define IPackageManager_GetRuntimeClassName(This,name) (This)->lpVtbl->GetRuntimeClassName(This,name) +#define IPackageManager_GetTrustLevel(This,level) (This)->lpVtbl->GetTrustLevel(This,level) +/*** IPackageManager methods ***/ +#define IPackageManager_FindPackages(This,retval) (This)->lpVtbl->FindPackages(This,retval) +#define IPackageManager_FindPackagesByUserSecurityId(This,userSecurityId,retval) (This)->lpVtbl->FindPackagesByUserSecurityId(This,userSecurityId,retval) + +/* IPackageId */ +typedef struct IPackageIdVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IPackageId *This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IPackageId *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IPackageId *This); + + /*** IInspectable methods ***/ + HRESULT (STDMETHODCALLTYPE *GetIids)( + IPackageId *This, + UINT32 *count, + IID **ids); + + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)( + IPackageId *This, + HSTRING *className); + + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)( + IPackageId *This, + TrustLevel *trustLevel); + + /*** IPackageId methods ***/ + HRESULT (STDMETHODCALLTYPE *get_Name)( + IPackageId *This, + HSTRING *value); + + HRESULT (STDMETHODCALLTYPE *get_Version)( + IPackageId *This, + IPackageVersion *value); + + HRESULT (STDMETHODCALLTYPE *get_Architecture)( + IPackageId *This, + IProcessorArchitecture *value); + + HRESULT (STDMETHODCALLTYPE *get_ResourceId)( + IPackageId *This, + HSTRING *value); + + HRESULT (STDMETHODCALLTYPE *get_Publisher)( + IPackageId *This, + HSTRING *value); + + HRESULT (STDMETHODCALLTYPE *get_PublisherId)( + IPackageId *This, + HSTRING *value); + + HRESULT (STDMETHODCALLTYPE *get_FullName)( + IPackageId *This, + HSTRING *value); + + HRESULT (STDMETHODCALLTYPE *get_FamilyName)( + IPackageId *This, + HSTRING *value); + + END_INTERFACE +} IPackageIdVtbl; + +interface IPackageId { + CONST_VTBL IPackageIdVtbl* lpVtbl; +}; + +/*** IUnknown methods ***/ +#define IPackageId_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject) +#define IPackageId_AddRef(This) (This)->lpVtbl->AddRef(This) +#define IPackageId_Release(This) (This)->lpVtbl->Release(This) +/*** IInspectable methods ***/ +#define IPackageId_GetIids(This,count,ids) (This)->lpVtbl->GetIids(This,count,ids) +#define IPackageId_GetRuntimeClassName(This,name) (This)->lpVtbl->GetRuntimeClassName(This,name) +#define IPackageId_GetTrustLevel(This,level) (This)->lpVtbl->GetTrustLevel(This,level) +/*** IPackageId methods ***/ +#define IPackageId_get_Name(This,value) (This)->lpVtbl->get_Name(This,value) +#define IPackageId_get_Version(This,value) (This)->lpVtbl->get_Version(This,value) +#define IPackageId_get_Architecture(This,value) (This)->lpVtbl->get_Architecture(This,value) +#define IPackageId_get_ResourceId(This,value) (This)->lpVtbl->get_ResourceId(This,value) +#define IPackageId_get_Publisher(This,value) (This)->lpVtbl->get_Publisher(This,value) +#define IPackageId_get_PublisherId(This,value) (This)->lpVtbl->get_PublisherId(This,value) +#define IPackageId_get_FullName(This,value) (This)->lpVtbl->get_FullName(This,value) +#define IPackageId_get_FamilyName(This,value) (This)->lpVtbl->get_FamilyName(This,value) + +/* IPackage */ +typedef struct IPackageVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IPackage *This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IPackage *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IPackage *This); + + /*** IInspectable methods ***/ + HRESULT (STDMETHODCALLTYPE *GetIids)( + IPackage *This, + UINT32 *count, + IID **ids); + + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)( + IPackage *This, + HSTRING *className); + + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)( + IPackage *This, + TrustLevel *trustLevel); + + /*** IPackage methods ***/ + HRESULT (STDMETHODCALLTYPE *get_Id)( + IPackage *This, + IPackageId **value); + + HRESULT (STDMETHODCALLTYPE *get_InstalledLocation)( + IPackage *This, + IUnknown **value); + + HRESULT (STDMETHODCALLTYPE *get_IsFramework)( + IPackage *This, + CHAR *value); + + HRESULT (STDMETHODCALLTYPE *get_Dependencies)( + IPackage *This, + void **value); + + END_INTERFACE +} IPackageVtbl; + +interface IPackage { + CONST_VTBL IPackageVtbl* lpVtbl; +}; + +/*** IUnknown methods ***/ +#define IPackage_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject) +#define IPackage_AddRef(This) (This)->lpVtbl->AddRef(This) +#define IPackage_Release(This) (This)->lpVtbl->Release(This) +/*** IInspectable methods ***/ +#define IPackage_GetIids(This,count,ids) (This)->lpVtbl->GetIids(This,count,ids) +#define IPackage_GetRuntimeClassName(This,name) (This)->lpVtbl->GetRuntimeClassName(This,name) +#define IPackage_GetTrustLevel(This,level) (This)->lpVtbl->GetTrustLevel(This,level) +/*** IPackage methods ***/ +#define IPackage_get_Id(This,value) (This)->lpVtbl->get_Id(This,value) +#define IPackage_get_InstalledLocation(This,value) (This)->lpVtbl->get_InstalledLocation(This,value) +#define IPackage_get_IsFramework(This,value) (This)->lpVtbl->get_IsFramework(This,value) +#define IPackage_get_Dependencies(This,value) (This)->lpVtbl->get_Dependencies(This,value) diff --git a/gio/gwin32api-storage.h b/gio/gwin32api-storage.h new file mode 100755 index 0000000..716a0a7 --- /dev/null +++ b/gio/gwin32api-storage.h @@ -0,0 +1,339 @@ +struct DateTime; + +typedef struct DateTime { + UINT64 UniversalTime; +} DateTime; + +/* The following is copied verbatim from MinGW-w64 windows.storage.h */ +enum StorageItemTypes; +enum FileAttributes; +enum NameCollisionOption; +enum StorageDeleteOption; + +typedef enum NameCollisionoption { + NameCollisionoption_GenerateUniqueName = 0, + NameCollisionoption_ReplaceExisting = 1, + NameCollisionoption_FailIfExists = 2 +} NameCollisionOption; + +typedef enum FileAttributes { + FileAttributes_Normal = 0, + FileAttributes_ReadOnly = 1, + FileAttributes_Directory = 2, + FileAttributes_Archive = 3, + FileAttributes_Temporary = 4 +} FileAttributes; + +typedef enum StorageItemTypes { + StorageItemTypes_None = 0, + StorageItemTypes_File = 1, + StorageItemTypes_Folder = 2 +} StorageItemTypes; + +typedef enum StorageDeleteOption { + StorageDeleteOption_Default = 0, + StorageDeleteOption_PermanentDelete = 1 +} StorageDeleteOption; + +#ifndef __IStorageItem_FWD_DEFINED__ +#define __IStorageItem_FWD_DEFINED__ +typedef interface IStorageItem IStorageItem; +#endif + +/* + * IStorageItem interface + */ +#ifndef __IStorageItem_INTERFACE_DEFINED__ +#define __IStorageItem_INTERFACE_DEFINED__ + +DEFINE_GUID(IID_IStorageItem, 0x4207a996, 0xca2f, 0x42f7, 0xbd,0xe8, 0x8b,0x10,0x45,0x7a,0x7f,0x30); +#if defined(__cplusplus) && !defined(CINTERFACE) +MIDL_INTERFACE("4207a996-ca2f-42f7-bde8-8b10457a7f30") +IStorageItem : public IInspectable +{ + virtual HRESULT STDMETHODCALLTYPE RenameAsyncOverloadDefaultOptions( + HSTRING desiredName, + IInspectable **action) = 0; + + virtual HRESULT STDMETHODCALLTYPE RenameAsync( + HSTRING desiredName, + NameCollisionOption option, + IInspectable **action) = 0; + + virtual HRESULT STDMETHODCALLTYPE DeleteAsyncOverloadDefaultOptions( + IInspectable **action) = 0; + + virtual HRESULT STDMETHODCALLTYPE DeleteAsync( + StorageDeleteOption option, + IInspectable **action) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBasicPropertiesAsync( + IInspectable **action) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_Name( + HSTRING *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_Path( + HSTRING *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_Attributes( + FileAttributes *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_DateCreated( + DateTime *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsOfType( + StorageItemTypes itemType, + boolean *value) = 0; + +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(IStorageItem, 0x4207a996, 0xca2f, 0x42f7, 0xbd,0xe8, 0x8b,0x10,0x45,0x7a,0x7f,0x30) +#endif +#else +typedef struct IStorageItemVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IStorageItem* This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IStorageItem* This); + + ULONG (STDMETHODCALLTYPE *Release)( + IStorageItem* This); + + /*** IInspectable methods ***/ + HRESULT (STDMETHODCALLTYPE *GetIids)( + IStorageItem* This, + ULONG *iidCount, + IID **iids); + + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)( + IStorageItem* This, + HSTRING *className); + + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)( + IStorageItem* This, + TrustLevel *trustLevel); + + /*** IStorageItem methods ***/ + HRESULT (STDMETHODCALLTYPE *RenameAsyncOverloadDefaultOptions)( + IStorageItem* This, + HSTRING desiredName, + IInspectable **action); + + HRESULT (STDMETHODCALLTYPE *RenameAsync)( + IStorageItem* This, + HSTRING desiredName, + NameCollisionOption option, + IInspectable **action); + + HRESULT (STDMETHODCALLTYPE *DeleteAsyncOverloadDefaultOptions)( + IStorageItem* This, + IInspectable **action); + + HRESULT (STDMETHODCALLTYPE *DeleteAsync)( + IStorageItem* This, + StorageDeleteOption option, + IInspectable **action); + + HRESULT (STDMETHODCALLTYPE *GetBasicPropertiesAsync)( + IStorageItem* This, + IInspectable **action); + + HRESULT (STDMETHODCALLTYPE *get_Name)( + IStorageItem* This, + HSTRING *value); + + HRESULT (STDMETHODCALLTYPE *get_Path)( + IStorageItem* This, + HSTRING *value); + + HRESULT (STDMETHODCALLTYPE *get_Attributes)( + IStorageItem* This, + FileAttributes *value); + + HRESULT (STDMETHODCALLTYPE *get_DateCreated)( + IStorageItem* This, + DateTime *value); + + HRESULT (STDMETHODCALLTYPE *IsOfType)( + IStorageItem* This, + StorageItemTypes itemType, + boolean *value); + + END_INTERFACE +} IStorageItemVtbl; +interface IStorageItem { + CONST_VTBL IStorageItemVtbl* lpVtbl; +}; + +#ifdef COBJMACROS +#ifndef WIDL_C_INLINE_WRAPPERS +/*** IUnknown methods ***/ +#define IStorageItem_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject) +#define IStorageItem_AddRef(This) (This)->lpVtbl->AddRef(This) +#define IStorageItem_Release(This) (This)->lpVtbl->Release(This) +/*** IInspectable methods ***/ +#define IStorageItem_GetIids(This,iidCount,iids) (This)->lpVtbl->GetIids(This,iidCount,iids) +#define IStorageItem_GetRuntimeClassName(This,className) (This)->lpVtbl->GetRuntimeClassName(This,className) +#define IStorageItem_GetTrustLevel(This,trustLevel) (This)->lpVtbl->GetTrustLevel(This,trustLevel) +/*** IStorageItem methods ***/ +#define IStorageItem_RenameAsyncOverloadDefaultOptions(This,desiredName,action) (This)->lpVtbl->RenameAsyncOverloadDefaultOptions(This,desiredName,action) +#define IStorageItem_RenameAsync(This,desiredName,option,action) (This)->lpVtbl->RenameAsync(This,desiredName,option,action) +#define IStorageItem_DeleteAsyncOverloadDefaultOptions(This,action) (This)->lpVtbl->DeleteAsyncOverloadDefaultOptions(This,action) +#define IStorageItem_DeleteAsync(This,option,action) (This)->lpVtbl->DeleteAsync(This,option,action) +#define IStorageItem_GetBasicPropertiesAsync(This,action) (This)->lpVtbl->GetBasicPropertiesAsync(This,action) +#define IStorageItem_get_Name(This,value) (This)->lpVtbl->get_Name(This,value) +#define IStorageItem_get_Path(This,value) (This)->lpVtbl->get_Path(This,value) +#define IStorageItem_get_Attributes(This,value) (This)->lpVtbl->get_Attributes(This,value) +#define IStorageItem_get_DateCreated(This,value) (This)->lpVtbl->get_DateCreated(This,value) +#define IStorageItem_IsOfType(This,itemType,value) (This)->lpVtbl->IsOfType(This,itemType,value) +#else +/*** IUnknown methods ***/ +static FORCEINLINE HRESULT IStorageItem_QueryInterface(IStorageItem* This,REFIID riid,void **ppvObject) { + return This->lpVtbl->QueryInterface(This,riid,ppvObject); +} +static FORCEINLINE ULONG IStorageItem_AddRef(IStorageItem* This) { + return This->lpVtbl->AddRef(This); +} +static FORCEINLINE ULONG IStorageItem_Release(IStorageItem* This) { + return This->lpVtbl->Release(This); +} +/*** IInspectable methods ***/ +static FORCEINLINE HRESULT IStorageItem_GetIids(IStorageItem* This,ULONG *iidCount,IID **iids) { + return This->lpVtbl->GetIids(This,iidCount,iids); +} +static FORCEINLINE HRESULT IStorageItem_GetRuntimeClassName(IStorageItem* This,HSTRING *className) { + return This->lpVtbl->GetRuntimeClassName(This,className); +} +static FORCEINLINE HRESULT IStorageItem_GetTrustLevel(IStorageItem* This,TrustLevel *trustLevel) { + return This->lpVtbl->GetTrustLevel(This,trustLevel); +} +/*** IStorageItem methods ***/ +static FORCEINLINE HRESULT IStorageItem_RenameAsyncOverloadDefaultOptions(IStorageItem* This,HSTRING desiredName,IInspectable **action) { + return This->lpVtbl->RenameAsyncOverloadDefaultOptions(This,desiredName,action); +} +static FORCEINLINE HRESULT IStorageItem_RenameAsync(IStorageItem* This,HSTRING desiredName,NameCollisionOption option,IInspectable **action) { + return This->lpVtbl->RenameAsync(This,desiredName,option,action); +} +static FORCEINLINE HRESULT IStorageItem_DeleteAsyncOverloadDefaultOptions(IStorageItem* This,IInspectable **action) { + return This->lpVtbl->DeleteAsyncOverloadDefaultOptions(This,action); +} +static FORCEINLINE HRESULT IStorageItem_DeleteAsync(IStorageItem* This,StorageDeleteOption option,IInspectable **action) { + return This->lpVtbl->DeleteAsync(This,option,action); +} +static FORCEINLINE HRESULT IStorageItem_GetBasicPropertiesAsync(IStorageItem* This,IInspectable **action) { + return This->lpVtbl->GetBasicPropertiesAsync(This,action); +} +static FORCEINLINE HRESULT IStorageItem_get_Name(IStorageItem* This,HSTRING *value) { + return This->lpVtbl->get_Name(This,value); +} +static FORCEINLINE HRESULT IStorageItem_get_Path(IStorageItem* This,HSTRING *value) { + return This->lpVtbl->get_Path(This,value); +} +static FORCEINLINE HRESULT IStorageItem_get_Attributes(IStorageItem* This,FileAttributes *value) { + return This->lpVtbl->get_Attributes(This,value); +} +static FORCEINLINE HRESULT IStorageItem_get_DateCreated(IStorageItem* This,DateTime *value) { + return This->lpVtbl->get_DateCreated(This,value); +} +static FORCEINLINE HRESULT IStorageItem_IsOfType(IStorageItem* This,StorageItemTypes itemType,boolean *value) { + return This->lpVtbl->IsOfType(This,itemType,value); +} +#endif +#endif + +#endif + +HRESULT STDMETHODCALLTYPE IStorageItem_RenameAsyncOverloadDefaultOptions_Proxy( + IStorageItem* This, + HSTRING desiredName, + IInspectable **action); +void __RPC_STUB IStorageItem_RenameAsyncOverloadDefaultOptions_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_RenameAsync_Proxy( + IStorageItem* This, + HSTRING desiredName, + NameCollisionOption option, + IInspectable **action); +void __RPC_STUB IStorageItem_RenameAsync_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_DeleteAsyncOverloadDefaultOptions_Proxy( + IStorageItem* This, + IInspectable **action); +void __RPC_STUB IStorageItem_DeleteAsyncOverloadDefaultOptions_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_DeleteAsync_Proxy( + IStorageItem* This, + StorageDeleteOption option, + IInspectable **action); +void __RPC_STUB IStorageItem_DeleteAsync_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_GetBasicPropertiesAsync_Proxy( + IStorageItem* This, + IInspectable **action); +void __RPC_STUB IStorageItem_GetBasicPropertiesAsync_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_get_Name_Proxy( + IStorageItem* This, + HSTRING *value); +void __RPC_STUB IStorageItem_get_Name_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_get_Path_Proxy( + IStorageItem* This, + HSTRING *value); +void __RPC_STUB IStorageItem_get_Path_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_get_Attributes_Proxy( + IStorageItem* This, + FileAttributes *value); +void __RPC_STUB IStorageItem_get_Attributes_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_get_DateCreated_Proxy( + IStorageItem* This, + DateTime *value); +void __RPC_STUB IStorageItem_get_DateCreated_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); +HRESULT STDMETHODCALLTYPE IStorageItem_IsOfType_Proxy( + IStorageItem* This, + StorageItemTypes itemType, + boolean *value); +void __RPC_STUB IStorageItem_IsOfType_Stub( + IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, + PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase); + +#endif /* __IStorageItem_INTERFACE_DEFINED__ */ diff --git a/gio/gwin32appinfo.c b/gio/gwin32appinfo.c new file mode 100644 index 0000000..26ca6ef --- /dev/null +++ b/gio/gwin32appinfo.c @@ -0,0 +1,5476 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2014 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Alexander Larsson + * РуÑлан Ижбулатов + */ + +#include "config.h" + +#define COBJMACROS + +#include + +#include "gcontenttype.h" +#include "gwin32appinfo.h" +#include "gappinfo.h" +#include "gioerror.h" +#include "gfile.h" +#include +#include "glibintl.h" +#include +#include +/* Contains the definitions from shlobj.h that are + * guarded as Windows8-or-newer and are unavailable + * to GLib, being only Windows7-or-newer. + */ +#include "gwin32api-application-activation-manager.h" + +#include +/* For SHLoadIndirectString() */ +#include + +#include +#include "giowin32-priv.h" +#include "glib-private.h" + +/* We need to watch 8 places: + * 0) HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations + * (anything below that key) + * On change: re-enumerate subkeys, read their values. + * 1) HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts + * (anything below that key) + * On change: re-enumerate subkeys + * 2) HKEY_CURRENT_USER\\Software\\Clients (anything below that key) + * On change: re-read the whole hierarchy of handlers + * 3) HKEY_LOCAL_MACHINE\\Software\\Clients (anything below that key) + * On change: re-read the whole hierarchy of handlers + * 4) HKEY_LOCAL_MACHINE\\Software\\RegisteredApplications (values of that key) + * On change: re-read the value list of registered applications + * 5) HKEY_CURRENT_USER\\Software\\RegisteredApplications (values of that key) + * On change: re-read the value list of registered applications + * 6) HKEY_CLASSES_ROOT\\Applications (anything below that key) + * On change: re-read the whole hierarchy of apps + * 7) HKEY_CLASSES_ROOT (only its subkeys) + * On change: re-enumerate subkeys, try to filter out wrong names. + * + * + * About verbs. A registry key (the name of that key is known as ProgID) + * can contain a "shell" subkey, which can then contain a number of verb + * subkeys (the most common being the "open" verb), and each of these + * contains a "command" subkey, which has a default string value that + * is the command to be run. + * Most ProgIDs are in HKEY_CLASSES_ROOT, but some are nested deeper in + * the registry (such as HKEY_CURRENT_USER\\Software\\). + * + * Verb selection works like this (according to https://docs.microsoft.com/en-us/windows/win32/shell/context ): + * 1) If "open" verb is available, that verb is used. + * 2) If the Shell subkey has a default string value, and if a verb subkey + * with that name exists, that verb is used. + * 3) The first subkey found in the list of verb subkeys is used. + * 4) The "openwith" verb is used + * + * Testing suggests that Windows never reaches the point 4 in any realistic + * circumstances. If a "command" subkey is missing for a verb, or if it has + * an empty string as its default value, the app launch fails + * (the "openwith" verb is not used, even if it's present). + * If the command is present, but is not valid (runs nonexisting executable, + * for example), then other verbs are not checked. + * It seems that when the documentation said "openwith verb", it meant + * that Windows invokes the default "Open with..." dialog (it does not + * look at the "openwith" verb subkey, even if it's there). + * If a verb subkey that is supposed to be used is present, but it lacks + * a command subkey, an error message is shown and nothing else happens. + */ + +#define _verb_idx(array,index) ((GWin32AppInfoShellVerb *) g_ptr_array_index (array, index)) + +#define _lookup_by_verb(array, verb, dst, itemtype) do { \ + gsize _index; \ + itemtype *_v; \ + for (_index = 0; array && _index < array->len; _index++) \ + { \ + _v = (itemtype *) g_ptr_array_index (array, _index); \ + if (_wcsicmp (_v->verb_name, (verb)) == 0) \ + { \ + *(dst) = _v; \ + break; \ + } \ + } \ + if (array == NULL || _index >= array->len) \ + *(dst) = NULL; \ +} while (0) + +#define _verb_lookup(array, verb, dst) _lookup_by_verb (array, verb, dst, GWin32AppInfoShellVerb) + +/* Because with subcommands a verb would have + * a name like "foo\\bar", but the key its command + * should be looked for is "shell\\foo\\shell\\bar\\command" + */ +typedef struct _reg_verb { + gunichar2 *name; + gunichar2 *shellpath; +} reg_verb; + +typedef struct _GWin32AppInfoURLSchema GWin32AppInfoURLSchema; +typedef struct _GWin32AppInfoFileExtension GWin32AppInfoFileExtension; +typedef struct _GWin32AppInfoShellVerb GWin32AppInfoShellVerb; +typedef struct _GWin32AppInfoHandler GWin32AppInfoHandler; +typedef struct _GWin32AppInfoApplication GWin32AppInfoApplication; + +typedef struct _GWin32AppInfoURLSchemaClass GWin32AppInfoURLSchemaClass; +typedef struct _GWin32AppInfoFileExtensionClass GWin32AppInfoFileExtensionClass; +typedef struct _GWin32AppInfoShellVerbClass GWin32AppInfoShellVerbClass; +typedef struct _GWin32AppInfoHandlerClass GWin32AppInfoHandlerClass; +typedef struct _GWin32AppInfoApplicationClass GWin32AppInfoApplicationClass; + +struct _GWin32AppInfoURLSchemaClass +{ + GObjectClass parent_class; +}; + +struct _GWin32AppInfoFileExtensionClass +{ + GObjectClass parent_class; +}; + +struct _GWin32AppInfoHandlerClass +{ + GObjectClass parent_class; +}; + +struct _GWin32AppInfoApplicationClass +{ + GObjectClass parent_class; +}; + +struct _GWin32AppInfoShellVerbClass +{ + GObjectClass parent_class; +}; + +struct _GWin32AppInfoURLSchema { + GObject parent_instance; + + /* url schema (stuff before ':') */ + gunichar2 *schema; + + /* url schema (stuff before ':'), in UTF-8 */ + gchar *schema_u8; + + /* url schema (stuff before ':'), in UTF-8, folded */ + gchar *schema_u8_folded; + + /* Handler currently selected for this schema. Can be NULL. */ + GWin32AppInfoHandler *chosen_handler; + + /* Maps folded handler IDs -> to GWin32AppInfoHandlers for this schema. + * Includes the chosen handler, if any. + */ + GHashTable *handlers; +}; + +struct _GWin32AppInfoHandler { + GObject parent_instance; + + /* Usually a class name in HKCR */ + gunichar2 *handler_id; + + /* Registry object obtained by opening @handler_id. + * Can be used to watch this handler. + * May be %NULL (for fake handlers that we made up). + */ + GWin32RegistryKey *key; + + /* @handler_id, in UTF-8, folded */ + gchar *handler_id_folded; + + /* Icon of the application for this handler */ + GIcon *icon; + + /* Verbs that this handler supports */ + GPtrArray *verbs; /* of GWin32AppInfoShellVerb */ + + /* AppUserModelID for a UWP application. When this is not NULL, + * this handler launches a UWP application. + * UWP applications are launched using a COM interface and have no commandlines, + * and the verbs will reflect that too. + */ + gunichar2 *uwp_aumid; +}; + +struct _GWin32AppInfoShellVerb { + GObject parent_instance; + + /* The verb that is used to invoke this handler. */ + gunichar2 *verb_name; + + /* User-friendly (localized) verb name. */ + gchar *verb_displayname; + + /* %TRUE if this verb is for a UWP app. + * It means that @command, @executable and @dll_function are %NULL. + */ + gboolean is_uwp; + + /* shell/verb/command */ + gunichar2 *command; + + /* Same as @command, but in UTF-8 */ + gchar *command_utf8; + + /* Executable of the program (UTF-8) */ + gchar *executable; + + /* Executable of the program (for matching, in folded form; UTF-8) */ + gchar *executable_folded; + + /* Pointer to a location within @executable */ + gchar *executable_basename; + + /* If not NULL, then @executable and its derived fields contain the name + * of a DLL file (without the name of the function that rundll32.exe should + * invoke), and this field contains the name of the function to be invoked. + * The application is then invoked as 'rundll32.exe "dll_path",dll_function other_arguments...'. + */ + gchar *dll_function; + + /* The application that is linked to this verb. */ + GWin32AppInfoApplication *app; +}; + +struct _GWin32AppInfoFileExtension { + GObject parent_instance; + + /* File extension (with leading '.') */ + gunichar2 *extension; + + /* File extension (with leading '.'), in UTF-8 */ + gchar *extension_u8; + + /* handler currently selected for this extension. Can be NULL. */ + GWin32AppInfoHandler *chosen_handler; + + /* Maps folded handler IDs -> to GWin32AppInfoHandlers for this extension. + * Includes the chosen handler, if any. + */ + GHashTable *handlers; +}; + +struct _GWin32AppInfoApplication { + GObject parent_instance; + + /* Canonical name (used for key names). + * For applications tracked by id this is the root registry + * key path for the application. + * For applications tracked by executable name this is the + * basename of the executable. + * For UWP apps this is the AppUserModelID. + * For fake applications this is the full filename of the + * executable (as far as it can be inferred from a command line, + * meaning that it can also be a basename, if that's + * all that a commandline happen to give us). + */ + gunichar2 *canonical_name; + + /* @canonical_name, in UTF-8 */ + gchar *canonical_name_u8; + + /* @canonical_name, in UTF-8, folded */ + gchar *canonical_name_folded; + + /* Human-readable name in English. Can be NULL */ + gunichar2 *pretty_name; + + /* Human-readable name in English, UTF-8. Can be NULL */ + gchar *pretty_name_u8; + + /* Human-readable name in user's language. Can be NULL */ + gunichar2 *localized_pretty_name; + + /* Human-readable name in user's language, UTF-8. Can be NULL */ + gchar *localized_pretty_name_u8; + + /* Description, could be in user's language. Can be NULL */ + gunichar2 *description; + + /* Description, could be in user's language, UTF-8. Can be NULL */ + gchar *description_u8; + + /* Verbs that this application supports */ + GPtrArray *verbs; /* of GWin32AppInfoShellVerb */ + + /* Explicitly supported URLs, hashmap from map-owned gchar ptr (schema, + * UTF-8, folded) -> to a GWin32AppInfoHandler + * Schema can be used as a key in the urls hashmap. + */ + GHashTable *supported_urls; + + /* Explicitly supported extensions, hashmap from map-owned gchar ptr + * (.extension, UTF-8, folded) -> to a GWin32AppInfoHandler + * Extension can be used as a key in the extensions hashmap. + */ + GHashTable *supported_exts; + + /* Icon of the application (remember, handler can have its own icon too) */ + GIcon *icon; + + /* Set to TRUE to prevent this app from appearing in lists of apps for + * opening files. This will not prevent it from appearing in lists of apps + * just for running, or lists of apps for opening exts/urls for which this + * app reports explicit support. + */ + gboolean no_open_with; + + /* Set to TRUE for applications from HKEY_CURRENT_USER. + * Give them priority over applications from HKEY_LOCAL_MACHINE, when all + * other things are equal. + */ + gboolean user_specific; + + /* Set to TRUE for applications that are machine-wide defaults (i.e. default + * browser) */ + gboolean default_app; + + /* Set to TRUE for UWP applications */ + gboolean is_uwp; +}; + +#define G_TYPE_WIN32_APPINFO_URL_SCHEMA (g_win32_appinfo_url_schema_get_type ()) +#define G_WIN32_APPINFO_URL_SCHEMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_WIN32_APPINFO_URL_SCHEMA, GWin32AppInfoURLSchema)) + +#define G_TYPE_WIN32_APPINFO_FILE_EXTENSION (g_win32_appinfo_file_extension_get_type ()) +#define G_WIN32_APPINFO_FILE_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_WIN32_APPINFO_FILE_EXTENSION, GWin32AppInfoFileExtension)) + +#define G_TYPE_WIN32_APPINFO_HANDLER (g_win32_appinfo_handler_get_type ()) +#define G_WIN32_APPINFO_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_WIN32_APPINFO_HANDLER, GWin32AppInfoHandler)) + +#define G_TYPE_WIN32_APPINFO_APPLICATION (g_win32_appinfo_application_get_type ()) +#define G_WIN32_APPINFO_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_WIN32_APPINFO_APPLICATION, GWin32AppInfoApplication)) + +#define G_TYPE_WIN32_APPINFO_SHELL_VERB (g_win32_appinfo_shell_verb_get_type ()) +#define G_WIN32_APPINFO_SHELL_VERB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_WIN32_APPINFO_SHELL_VERB, GWin32AppInfoShellVerb)) + +GType g_win32_appinfo_url_schema_get_type (void) G_GNUC_CONST; +GType g_win32_appinfo_file_extension_get_type (void) G_GNUC_CONST; +GType g_win32_appinfo_shell_verb_get_type (void) G_GNUC_CONST; +GType g_win32_appinfo_handler_get_type (void) G_GNUC_CONST; +GType g_win32_appinfo_application_get_type (void) G_GNUC_CONST; + +G_DEFINE_TYPE (GWin32AppInfoURLSchema, g_win32_appinfo_url_schema, G_TYPE_OBJECT) +G_DEFINE_TYPE (GWin32AppInfoFileExtension, g_win32_appinfo_file_extension, G_TYPE_OBJECT) +G_DEFINE_TYPE (GWin32AppInfoShellVerb, g_win32_appinfo_shell_verb, G_TYPE_OBJECT) +G_DEFINE_TYPE (GWin32AppInfoHandler, g_win32_appinfo_handler, G_TYPE_OBJECT) +G_DEFINE_TYPE (GWin32AppInfoApplication, g_win32_appinfo_application, G_TYPE_OBJECT) + +static void +g_win32_appinfo_url_schema_dispose (GObject *object) +{ + GWin32AppInfoURLSchema *url = G_WIN32_APPINFO_URL_SCHEMA (object); + + g_clear_pointer (&url->schema, g_free); + g_clear_pointer (&url->schema_u8, g_free); + g_clear_pointer (&url->schema_u8_folded, g_free); + g_clear_object (&url->chosen_handler); + g_clear_pointer (&url->handlers, g_hash_table_destroy); + G_OBJECT_CLASS (g_win32_appinfo_url_schema_parent_class)->dispose (object); +} + + +static void +g_win32_appinfo_handler_dispose (GObject *object) +{ + GWin32AppInfoHandler *handler = G_WIN32_APPINFO_HANDLER (object); + + g_clear_pointer (&handler->handler_id, g_free); + g_clear_pointer (&handler->handler_id_folded, g_free); + g_clear_object (&handler->key); + g_clear_object (&handler->icon); + g_clear_pointer (&handler->verbs, g_ptr_array_unref); + g_clear_pointer (&handler->uwp_aumid, g_free); + G_OBJECT_CLASS (g_win32_appinfo_handler_parent_class)->dispose (object); +} + +static void +g_win32_appinfo_file_extension_dispose (GObject *object) +{ + GWin32AppInfoFileExtension *ext = G_WIN32_APPINFO_FILE_EXTENSION (object); + + g_clear_pointer (&ext->extension, g_free); + g_clear_pointer (&ext->extension_u8, g_free); + g_clear_object (&ext->chosen_handler); + g_clear_pointer (&ext->handlers, g_hash_table_destroy); + G_OBJECT_CLASS (g_win32_appinfo_file_extension_parent_class)->dispose (object); +} + +static void +g_win32_appinfo_shell_verb_dispose (GObject *object) +{ + GWin32AppInfoShellVerb *shverb = G_WIN32_APPINFO_SHELL_VERB (object); + + g_clear_pointer (&shverb->verb_name, g_free); + g_clear_pointer (&shverb->verb_displayname, g_free); + g_clear_pointer (&shverb->command, g_free); + g_clear_pointer (&shverb->command_utf8, g_free); + g_clear_pointer (&shverb->executable_folded, g_free); + g_clear_pointer (&shverb->executable, g_free); + g_clear_pointer (&shverb->dll_function, g_free); + g_clear_object (&shverb->app); + G_OBJECT_CLASS (g_win32_appinfo_shell_verb_parent_class)->dispose (object); +} + +static void +g_win32_appinfo_application_dispose (GObject *object) +{ + GWin32AppInfoApplication *app = G_WIN32_APPINFO_APPLICATION (object); + + g_clear_pointer (&app->canonical_name_u8, g_free); + g_clear_pointer (&app->canonical_name_folded, g_free); + g_clear_pointer (&app->canonical_name, g_free); + g_clear_pointer (&app->pretty_name, g_free); + g_clear_pointer (&app->localized_pretty_name, g_free); + g_clear_pointer (&app->description, g_free); + g_clear_pointer (&app->pretty_name_u8, g_free); + g_clear_pointer (&app->localized_pretty_name_u8, g_free); + g_clear_pointer (&app->description_u8, g_free); + g_clear_pointer (&app->supported_urls, g_hash_table_destroy); + g_clear_pointer (&app->supported_exts, g_hash_table_destroy); + g_clear_object (&app->icon); + g_clear_pointer (&app->verbs, g_ptr_array_unref); + G_OBJECT_CLASS (g_win32_appinfo_application_parent_class)->dispose (object); +} + +static const gchar * +g_win32_appinfo_application_get_some_name (GWin32AppInfoApplication *app) +{ + if (app->localized_pretty_name_u8) + return app->localized_pretty_name_u8; + + if (app->pretty_name_u8) + return app->pretty_name_u8; + + return app->canonical_name_u8; +} + +static void +g_win32_appinfo_url_schema_class_init (GWin32AppInfoURLSchemaClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_win32_appinfo_url_schema_dispose; +} + +static void +g_win32_appinfo_file_extension_class_init (GWin32AppInfoFileExtensionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_win32_appinfo_file_extension_dispose; +} + +static void +g_win32_appinfo_shell_verb_class_init (GWin32AppInfoShellVerbClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_win32_appinfo_shell_verb_dispose; +} + +static void +g_win32_appinfo_handler_class_init (GWin32AppInfoHandlerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_win32_appinfo_handler_dispose; +} + +static void +g_win32_appinfo_application_class_init (GWin32AppInfoApplicationClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_win32_appinfo_application_dispose; +} + +static void +g_win32_appinfo_url_schema_init (GWin32AppInfoURLSchema *self) +{ + self->handlers = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); +} + +static void +g_win32_appinfo_shell_verb_init (GWin32AppInfoShellVerb *self) +{ +} + +static void +g_win32_appinfo_file_extension_init (GWin32AppInfoFileExtension *self) +{ + self->handlers = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); +} + +static void +g_win32_appinfo_handler_init (GWin32AppInfoHandler *self) +{ + self->verbs = g_ptr_array_new_with_free_func (g_object_unref); +} + +static void +g_win32_appinfo_application_init (GWin32AppInfoApplication *self) +{ + self->supported_urls = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + self->supported_exts = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + self->verbs = g_ptr_array_new_with_free_func (g_object_unref); +} + +/* The AppInfo threadpool that does asynchronous AppInfo tree rebuilds */ +static GThreadPool *gio_win32_appinfo_threadpool; + +/* This mutex is held by a thread that reads or writes the AppInfo tree. + * (tree object references can be obtained and later read without + * holding this mutex, since objects are practically immutable). + */ +static GMutex gio_win32_appinfo_mutex; + +/* Any thread wanting to access AppInfo can wait on this condition */ +static GCond gio_win32_appinfo_cond; + +/* Increased to indicate that AppInfo tree does needs to be rebuilt. + * AppInfo thread checks this to see if it needs to + * do a tree re-build. If the value changes during a rebuild, + * another rebuild is triggered after that. + * Other threads check this to see if they need + * to wait for a tree re-build to finish. + */ +static gint gio_win32_appinfo_update_counter = 0; + +/* Map of owned ".ext" (with '.', UTF-8, folded) + * to GWin32AppInfoFileExtension ptr + */ +static GHashTable *extensions = NULL; + +/* Map of owned "schema" (without ':', UTF-8, folded) + * to GWin32AppInfoURLSchema ptr + */ +static GHashTable *urls = NULL; + +/* Map of owned "appID" (UTF-8, folded) to + * a GWin32AppInfoApplication + */ +static GHashTable *apps_by_id = NULL; + +/* Map of owned "app.exe" (UTF-8, folded) to + * a GWin32AppInfoApplication. + * This map and its values are separate from apps_by_id. The fact that an app + * with known ID has the same executable [base]name as an app in this map does + * not mean that they are the same application. + */ +static GHashTable *apps_by_exe = NULL; + +/* Map of owned "path:\to\app.exe" (UTF-8, folded) to + * a GWin32AppInfoApplication. + * The app objects in this map are fake - they are linked to + * handlers that do not have any apps associated with them. + */ +static GHashTable *fake_apps = NULL; + +/* Map of owned "handler id" (UTF-8, folded) + * to a GWin32AppInfoHandler + */ +static GHashTable *handlers = NULL; + +/* Temporary (only exists while the registry is being scanned) table + * that maps GWin32RegistryKey objects (keeps a ref) to owned AUMId wchar strings. + */ +static GHashTable *uwp_handler_table = NULL; + +/* Watch this whole subtree */ +static GWin32RegistryKey *url_associations_key; + +/* Watch this whole subtree */ +static GWin32RegistryKey *file_exts_key; + +/* Watch this whole subtree */ +static GWin32RegistryKey *user_clients_key; + +/* Watch this whole subtree */ +static GWin32RegistryKey *system_clients_key; + +/* Watch this key */ +static GWin32RegistryKey *user_registered_apps_key; + +/* Watch this key */ +static GWin32RegistryKey *system_registered_apps_key; + +/* Watch this whole subtree */ +static GWin32RegistryKey *applications_key; + +/* Watch this key */ +static GWin32RegistryKey *classes_root_key; + +#define URL_ASSOCIATIONS L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\" +#define USER_CHOICE L"\\UserChoice" +#define OPEN_WITH_PROGIDS L"\\OpenWithProgids" +#define FILE_EXTS L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" +#define HKCR L"HKEY_CLASSES_ROOT\\" +#define HKCU L"HKEY_CURRENT_USER\\" +#define HKLM L"HKEY_LOCAL_MACHINE\\" +#define REG_PATH_MAX 256 +#define REG_PATH_MAX_SIZE (REG_PATH_MAX * sizeof (gunichar2)) + +/* for g_wcsdup(), + * _g_win32_extract_executable(), + * _g_win32_fixup_broken_microsoft_rundll_commandline() + */ +#include "giowin32-private.c" + +/* for g_win32_package_parser_enum_packages() */ +#include "gwin32packageparser.h" + +static void +read_handler_icon (GWin32RegistryKey *key, + GIcon **icon_out) +{ + GWin32RegistryKey *icon_key; + GWin32RegistryValueType default_type; + gchar *default_value; + + g_assert (icon_out); + + *icon_out = NULL; + + icon_key = g_win32_registry_key_get_child_w (key, L"DefaultIcon", NULL); + + if (icon_key == NULL) + return; + + if (g_win32_registry_key_get_value (icon_key, + NULL, + TRUE, + "", + &default_type, + (gpointer *) &default_value, + NULL, + NULL)) + { + /* TODO: For UWP handlers this string is usually in @{...} form, + * see grab_registry_string() below. Right now this + * string is read as-is and the icon would silently fail to load. + * Also, right now handler icon is not used anywhere + * (only app icon is used). + */ + if (default_type == G_WIN32_REGISTRY_VALUE_STR && + default_value[0] != '\0') + *icon_out = g_themed_icon_new (default_value); + + g_clear_pointer (&default_value, g_free); + } + + g_object_unref (icon_key); +} + +static void +reg_verb_free (gpointer p) +{ + if (p == NULL) + return; + + g_free (((reg_verb *) p)->name); + g_free (((reg_verb *) p)->shellpath); + g_free (p); +} + +#define is_open(x) ( \ + ((x)[0] == L'o' || (x)[0] == L'O') && \ + ((x)[1] == L'p' || (x)[1] == L'P') && \ + ((x)[2] == L'e' || (x)[2] == L'E') && \ + ((x)[3] == L'n' || (x)[3] == L'N') && \ + ((x)[4] == L'\0') \ +) + +/* default verb (if any) comes first, + * then "open", then the rest of the verbs + * are sorted alphabetically + */ +static gint +compare_verbs (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + const reg_verb *ca = (const reg_verb *) a; + const reg_verb *cb = (const reg_verb *) b; + const gunichar2 *def = (const gunichar2 *) user_data; + gboolean is_open_ca; + gboolean is_open_cb; + + if (def != NULL) + { + if (_wcsicmp (ca->name, def) == 0) + return -1; + else if (_wcsicmp (cb->name, def) == 0) + return 1; + } + + is_open_ca = is_open (ca->name); + is_open_cb = is_open (cb->name); + + if (is_open_ca && !is_open_cb) + return -1; + else if (is_open_ca && !is_open_cb) + return 1; + + return _wcsicmp (ca->name, cb->name); +} + +static gboolean build_registry_path (gunichar2 *output, gsize output_size, ...) G_GNUC_NULL_TERMINATED; +static gboolean build_registry_pathv (gunichar2 *output, gsize output_size, va_list components); + +static GWin32RegistryKey *_g_win32_registry_key_build_and_new_w (GError **error, ...) G_GNUC_NULL_TERMINATED; + +/* Called by process_verbs_commands. + * @verb is a verb name + * @command_line is the commandline of that verb + * @command_line_utf8 is the UTF-8 version of @command_line + * @verb_displayname is the prettier display name of the verb (might be NULL) + * @verb_is_preferred is TRUE if the verb is the preferred one + * @invent_new_verb_name is TRUE when the verb should be added + * even if a verb with such + * name already exists (in which case + * a new name is invented), unless + * the existing verb runs exactly the same + * commandline. + */ +typedef void (*verb_command_func) (gpointer handler_data1, + gpointer handler_data2, + const gunichar2 *verb, + const gunichar2 *command_line, + const gchar *command_line_utf8, + const gchar *verb_displayname, + gboolean verb_is_preferred, + gboolean invent_new_verb_name); + +static gunichar2 * decide_which_id_to_use (const gunichar2 *program_id, + GWin32RegistryKey **return_key, + gchar **return_handler_id_u8, + gchar **return_handler_id_u8_folded, + gunichar2 **return_uwp_aumid); + +static GWin32AppInfoURLSchema * get_schema_object (const gunichar2 *schema, + const gchar *schema_u8, + const gchar *schema_u8_folded); + +static GWin32AppInfoHandler * get_handler_object (const gchar *handler_id_u8_folded, + GWin32RegistryKey *handler_key, + const gunichar2 *handler_id, + const gunichar2 *uwp_aumid); + +static GWin32AppInfoFileExtension *get_ext_object (const gunichar2 *ext, + const gchar *ext_u8, + const gchar *ext_u8_folded); + + +static void process_verbs_commands (GList *verbs, + const reg_verb *preferred_verb, + const gunichar2 *path_to_progid, + const gunichar2 *progid, + gboolean autoprefer_first_verb, + verb_command_func handler, + gpointer handler_data1, + gpointer handler_data2); + +static void handler_add_verb (gpointer handler_data1, + gpointer handler_data2, + const gunichar2 *verb, + const gunichar2 *command_line, + const gchar *command_line_utf8, + const gchar *verb_displayname, + gboolean verb_is_preferred, + gboolean invent_new_verb_name); + +static void process_uwp_verbs (GList *verbs, + const reg_verb *preferred_verb, + const gunichar2 *path_to_progid, + const gunichar2 *progid, + gboolean autoprefer_first_verb, + GWin32AppInfoHandler *handler_rec, + GWin32AppInfoApplication *app); + +static void uwp_handler_add_verb (GWin32AppInfoHandler *handler_rec, + GWin32AppInfoApplication *app, + const gunichar2 *verb, + const gchar *verb_displayname, + gboolean verb_is_preferred); + +/* output_size is in *bytes*, not gunichar2s! */ +static gboolean +build_registry_path (gunichar2 *output, gsize output_size, ...) +{ + va_list ap; + gboolean result; + + va_start (ap, output_size); + + result = build_registry_pathv (output, output_size, ap); + + va_end (ap); + + return result; +} + +/* output_size is in *bytes*, not gunichar2s! */ +static gboolean +build_registry_pathv (gunichar2 *output, gsize output_size, va_list components) +{ + va_list lentest; + gunichar2 *p; + gunichar2 *component; + gsize length; + + if (output == NULL) + return FALSE; + + G_VA_COPY (lentest, components); + + for (length = 0, component = va_arg (lentest, gunichar2 *); + component != NULL; + component = va_arg (lentest, gunichar2 *)) + { + length += wcslen (component); + } + + va_end (lentest); + + if ((length >= REG_PATH_MAX_SIZE) || + (length * sizeof (gunichar2) >= output_size)) + return FALSE; + + output[0] = L'\0'; + + for (p = output, component = va_arg (components, gunichar2 *); + component != NULL; + component = va_arg (components, gunichar2 *)) + { + length = wcslen (component); + wcscat (p, component); + p += length; + } + + return TRUE; +} + + +static GWin32RegistryKey * +_g_win32_registry_key_build_and_new_w (GError **error, ...) +{ + va_list ap; + gunichar2 key_path[REG_PATH_MAX_SIZE + 1]; + GWin32RegistryKey *key; + + va_start (ap, error); + + key = NULL; + + if (build_registry_pathv (key_path, sizeof (key_path), ap)) + key = g_win32_registry_key_new_w (key_path, error); + + va_end (ap); + + return key; +} + +/* Gets the list of shell verbs (a GList of reg_verb, put into @verbs) + * from the @program_id_key. + * If one of the verbs should be preferred, + * a pointer to this verb (in the GList) will be + * put into @preferred_verb. + * Does not automatically assume that the first verb + * is preferred (when no other preferences exist). + * @verbname_prefix is prefixed to the name of the verb + * (this is used for subcommands) and is initially an + * empty string. + * @verbshell_prefix is the subkey of @program_id_key + * that contains the verbs. It is "Shell" initially, + * but grows with recursive invocations (for subcommands). + * @is_uwp points to a boolean, which + * indicates whether the function is being called for a UWP app. + * It might be switched from %TRUE to %FALSE on return, + * if the application turns out to not to be UWP on closer inspection. + * If the application is already known not to be UWP before the + * call, this pointer can be %NULL instead. + * Returns TRUE on success, FALSE on failure. + */ +static gboolean +get_verbs (GWin32RegistryKey *program_id_key, + const reg_verb **preferred_verb, + GList **verbs, + const gunichar2 *verbname_prefix, + const gunichar2 *verbshell_prefix, + gboolean *is_uwp) +{ + GWin32RegistrySubkeyIter iter; + GWin32RegistryKey *key; + GWin32RegistryValueType val_type; + gunichar2 *default_verb; + gsize verbshell_prefix_len; + gsize verbname_prefix_len; + GList *i; + + g_assert (program_id_key && verbs && preferred_verb); + + *verbs = NULL; + *preferred_verb = NULL; + + key = g_win32_registry_key_get_child_w (program_id_key, + verbshell_prefix, + NULL); + + if (key == NULL) + return FALSE; + + if (!g_win32_registry_subkey_iter_init (&iter, key, NULL)) + { + g_object_unref (key); + + return FALSE; + } + + verbshell_prefix_len = g_utf16_len (verbshell_prefix); + verbname_prefix_len = g_utf16_len (verbname_prefix); + + while (g_win32_registry_subkey_iter_next (&iter, TRUE, NULL)) + { + const gunichar2 *name; + gsize name_len; + GWin32RegistryKey *subkey; + gboolean has_subcommands; + const reg_verb *tmp; + GWin32RegistryValueType subc_type; + reg_verb *rverb; + const gunichar2 *shell = L"Shell"; + const gsize shell_len = g_utf16_len (shell); + + if (!g_win32_registry_subkey_iter_get_name_w (&iter, &name, &name_len, NULL)) + continue; + + subkey = g_win32_registry_key_get_child_w (key, + name, + NULL); + + /* We may not have the required access rights to open the child key */ + if (subkey == NULL) + continue; + + /* The key we're looking at is "/Shell/", + * where "Shell" is verbshell_prefix. + * If it has a value named 'Subcommands' (doesn't matter what its data is), + * it means that this key has its own Shell subkey, the subkeys + * of which are shell commands (i.e. /Shell//Shell/). + * To handle that, create new, extended nameprefix and shellprefix, + * and call the function recursively. + * name prefix "" -> "\\" + * shell prefix "Shell" -> "Shell\\\\Shell" + * The root, program_id_key, remains the same in all invocations. + * Essentially, we're flattening the command tree into a list. + */ + has_subcommands = FALSE; + if ((is_uwp == NULL || !(*is_uwp)) && /* Assume UWP apps don't have subcommands */ + g_win32_registry_key_get_value_w (subkey, + NULL, + TRUE, + L"Subcommands", + &subc_type, + NULL, + NULL, + NULL) && + subc_type == G_WIN32_REGISTRY_VALUE_STR) + { + gboolean dummy = FALSE; + gunichar2 *new_nameprefix = g_new (gunichar2, verbname_prefix_len + name_len + 1 + 1); + gunichar2 *new_shellprefix = g_new (gunichar2, verbshell_prefix_len + 1 + name_len + 1 + shell_len + 1); + memcpy (&new_shellprefix[0], verbshell_prefix, verbshell_prefix_len * sizeof (gunichar2)); + new_shellprefix[verbshell_prefix_len] = L'\\'; + memcpy (&new_shellprefix[verbshell_prefix_len + 1], name, name_len * sizeof (gunichar2)); + new_shellprefix[verbshell_prefix_len + 1 + name_len] = L'\\'; + memcpy (&new_shellprefix[verbshell_prefix_len + 1 + name_len + 1], shell, shell_len * sizeof (gunichar2)); + new_shellprefix[verbshell_prefix_len + 1 + name_len + 1 + shell_len] = 0; + + memcpy (&new_nameprefix[0], verbname_prefix, verbname_prefix_len * sizeof (gunichar2)); + memcpy (&new_nameprefix[verbname_prefix_len], name, (name_len) * sizeof (gunichar2)); + new_nameprefix[verbname_prefix_len + name_len] = L'\\'; + new_nameprefix[verbname_prefix_len + name_len + 1] = 0; + has_subcommands = get_verbs (program_id_key, &tmp, verbs, new_nameprefix, new_shellprefix, &dummy); + g_free (new_shellprefix); + g_free (new_nameprefix); + } + + /* Presence of subcommands means that this key itself is not a command-key */ + if (has_subcommands) + { + g_clear_object (&subkey); + continue; + } + + if (is_uwp != NULL && *is_uwp && + !g_win32_registry_key_get_value_w (subkey, + NULL, + TRUE, + L"ActivatableClassId", + &subc_type, + NULL, + NULL, + NULL)) + { + /* We expected a UWP app, but it lacks ActivatableClassId + * on a verb, which means that it does not behave like + * a UWP app should (msedge being an example - it's UWP, + * but has its own launchable exe file and a simple ID), + * so we have to treat it like a normal app. + */ + *is_uwp = FALSE; + } + + g_clear_object (&subkey); + + /* We don't look at the command sub-key and its value (the actual command line) here. + * We save the registry path instead, and use it later in process_verbs_commands(). + * The name of the verb is also saved. + * verbname_prefix is prefixed to the verb name (it's either an empty string + * or already ends with a '\\', so no extra separators needed). + * verbshell_prefix is prefixed to the verb key path (this one needs a separator, + * because it never has one - all verbshell prefixes end with "Shell", not "Shell\\") + */ + rverb = g_new0 (reg_verb, 1); + rverb->name = g_new (gunichar2, verbname_prefix_len + name_len + 1); + memcpy (&rverb->name[0], verbname_prefix, verbname_prefix_len * sizeof (gunichar2)); + memcpy (&rverb->name[verbname_prefix_len], name, name_len * sizeof (gunichar2)); + rverb->name[verbname_prefix_len + name_len] = 0; + rverb->shellpath = g_new (gunichar2, verbshell_prefix_len + 1 + name_len + 1); + memcpy (&rverb->shellpath[0], verbshell_prefix, verbshell_prefix_len * sizeof (gunichar2)); + memcpy (&rverb->shellpath[verbshell_prefix_len], L"\\", sizeof (gunichar2)); + memcpy (&rverb->shellpath[verbshell_prefix_len + 1], name, name_len * sizeof (gunichar2)); + rverb->shellpath[verbshell_prefix_len + 1 + name_len] = 0; + *verbs = g_list_append (*verbs, rverb); + } + + g_win32_registry_subkey_iter_clear (&iter); + + if (*verbs == NULL) + { + g_object_unref (key); + + return FALSE; + } + + default_verb = NULL; + + if (g_win32_registry_key_get_value_w (key, + NULL, + TRUE, + L"", + &val_type, + (void **) &default_verb, + NULL, + NULL) && + (val_type != G_WIN32_REGISTRY_VALUE_STR || + g_utf16_len (default_verb) <= 0)) + g_clear_pointer (&default_verb, g_free); + + g_object_unref (key); + + /* Only sort at the top level */ + if (verbname_prefix[0] == 0) + { + *verbs = g_list_sort_with_data (*verbs, compare_verbs, default_verb); + + for (i = *verbs; default_verb && *preferred_verb == NULL && i; i = i->next) + if (_wcsicmp (default_verb, ((const reg_verb *) i->data)->name) == 0) + *preferred_verb = (const reg_verb *) i->data; + } + + g_clear_pointer (&default_verb, g_free); + + return TRUE; +} + +/* Grabs a URL association (from HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\ + * or from an application with Capabilities, or just a schema subkey in HKCR). + * @program_id is a ProgID of the handler for the URL. + * @schema is the schema for the URL. + * @schema_u8 and @schema_u8_folded are UTF-8 and folded UTF-8 + * respectively. + * @app is the app to which the URL handler belongs (can be NULL). + * @is_user_choice is TRUE if this association is clearly preferred + */ +static void +get_url_association (const gunichar2 *program_id, + const gunichar2 *schema, + const gchar *schema_u8, + const gchar *schema_u8_folded, + GWin32AppInfoApplication *app, + gboolean is_user_choice) +{ + GWin32AppInfoURLSchema *schema_rec; + GWin32AppInfoHandler *handler_rec; + gunichar2 *handler_id; + GList *verbs; + const reg_verb *preferred_verb; + gchar *handler_id_u8; + gchar *handler_id_u8_folded; + gunichar2 *uwp_aumid; + gboolean is_uwp; + GWin32RegistryKey *handler_key; + + if ((handler_id = decide_which_id_to_use (program_id, + &handler_key, + &handler_id_u8, + &handler_id_u8_folded, + &uwp_aumid)) == NULL) + return; + + is_uwp = uwp_aumid != NULL; + + if (!get_verbs (handler_key, &preferred_verb, &verbs, L"", L"Shell", &is_uwp)) + { + g_clear_pointer (&handler_id, g_free); + g_clear_pointer (&handler_id_u8, g_free); + g_clear_pointer (&handler_id_u8_folded, g_free); + g_clear_object (&handler_key); + g_clear_pointer (&uwp_aumid, g_free); + + return; + } + + if (!is_uwp && uwp_aumid != NULL) + g_clear_pointer (&uwp_aumid, g_free); + + schema_rec = get_schema_object (schema, + schema_u8, + schema_u8_folded); + + handler_rec = get_handler_object (handler_id_u8_folded, + handler_key, + handler_id, + uwp_aumid); + + if (is_user_choice || schema_rec->chosen_handler == NULL) + g_set_object (&schema_rec->chosen_handler, handler_rec); + + g_hash_table_insert (schema_rec->handlers, + g_strdup (handler_id_u8_folded), + g_object_ref (handler_rec)); + + g_clear_object (&handler_key); + + if (app) + g_hash_table_insert (app->supported_urls, + g_strdup (schema_rec->schema_u8_folded), + g_object_ref (handler_rec)); + + if (uwp_aumid == NULL) + process_verbs_commands (g_steal_pointer (&verbs), + preferred_verb, + HKCR, + handler_id, + TRUE, + handler_add_verb, + handler_rec, + app); + else + process_uwp_verbs (g_steal_pointer (&verbs), + preferred_verb, + HKCR, + handler_id, + TRUE, + handler_rec, + app); + + + g_clear_pointer (&handler_id_u8, g_free); + g_clear_pointer (&handler_id_u8_folded, g_free); + g_clear_pointer (&handler_id, g_free); + g_clear_pointer (&uwp_aumid, g_free); +} + +/* Grabs a file extension association (from HKCR\.ext or similar). + * @program_id is a ProgID of the handler for the extension. + * @file_extension is the extension (with the leading '.') + * @app is the app to which the extension handler belongs (can be NULL). + * @is_user_choice is TRUE if this is clearly the preferred association + */ +static void +get_file_ext (const gunichar2 *program_id, + const gunichar2 *file_extension, + GWin32AppInfoApplication *app, + gboolean is_user_choice) +{ + GWin32AppInfoHandler *handler_rec; + gunichar2 *handler_id; + const reg_verb *preferred_verb; + GList *verbs; + gchar *handler_id_u8; + gchar *handler_id_u8_folded; + gunichar2 *uwp_aumid; + gboolean is_uwp; + GWin32RegistryKey *handler_key; + GWin32AppInfoFileExtension *file_extn; + gchar *file_extension_u8; + gchar *file_extension_u8_folded; + + if ((handler_id = decide_which_id_to_use (program_id, + &handler_key, + &handler_id_u8, + &handler_id_u8_folded, + &uwp_aumid)) == NULL) + return; + + if (!g_utf16_to_utf8_and_fold (file_extension, + -1, + &file_extension_u8, + &file_extension_u8_folded)) + { + g_clear_pointer (&handler_id, g_free); + g_clear_pointer (&handler_id_u8, g_free); + g_clear_pointer (&handler_id_u8_folded, g_free); + g_clear_pointer (&uwp_aumid, g_free); + g_clear_object (&handler_key); + + return; + } + + is_uwp = uwp_aumid != NULL; + + if (!get_verbs (handler_key, &preferred_verb, &verbs, L"", L"Shell", &is_uwp)) + { + g_clear_pointer (&handler_id, g_free); + g_clear_pointer (&handler_id_u8, g_free); + g_clear_pointer (&handler_id_u8_folded, g_free); + g_clear_object (&handler_key); + g_clear_pointer (&file_extension_u8, g_free); + g_clear_pointer (&file_extension_u8_folded, g_free); + g_clear_pointer (&uwp_aumid, g_free); + + return; + } + + if (!is_uwp && uwp_aumid != NULL) + g_clear_pointer (&uwp_aumid, g_free); + + file_extn = get_ext_object (file_extension, file_extension_u8, file_extension_u8_folded); + + handler_rec = get_handler_object (handler_id_u8_folded, + handler_key, + handler_id, + uwp_aumid); + + if (is_user_choice || file_extn->chosen_handler == NULL) + g_set_object (&file_extn->chosen_handler, handler_rec); + + g_hash_table_insert (file_extn->handlers, + g_strdup (handler_id_u8_folded), + g_object_ref (handler_rec)); + + if (app) + g_hash_table_insert (app->supported_exts, + g_strdup (file_extension_u8_folded), + g_object_ref (handler_rec)); + + g_clear_pointer (&file_extension_u8, g_free); + g_clear_pointer (&file_extension_u8_folded, g_free); + g_clear_object (&handler_key); + + if (uwp_aumid == NULL) + process_verbs_commands (g_steal_pointer (&verbs), + preferred_verb, + HKCR, + handler_id, + TRUE, + handler_add_verb, + handler_rec, + app); + else + process_uwp_verbs (g_steal_pointer (&verbs), + preferred_verb, + HKCR, + handler_id, + TRUE, + handler_rec, + app); + + g_clear_pointer (&handler_id, g_free); + g_clear_pointer (&handler_id_u8, g_free); + g_clear_pointer (&handler_id_u8_folded, g_free); + g_clear_pointer (&uwp_aumid, g_free); +} + +/* Returns either a @program_id or the string from + * the default value of the program_id key (which is a name + * of a proxy class), or NULL. + * Does not check that proxy represents a valid + * record, just checks that it exists. + * Can return the class key (HKCR/program_id or HKCR/proxy_id). + * Can convert returned value to UTF-8 and fold it. + */ +static gunichar2 * +decide_which_id_to_use (const gunichar2 *program_id, + GWin32RegistryKey **return_key, + gchar **return_handler_id_u8, + gchar **return_handler_id_u8_folded, + gunichar2 **return_uwp_aumid) +{ + GWin32RegistryKey *key; + GWin32RegistryKey *uwp_key; + GWin32RegistryValueType val_type; + gunichar2 *proxy_id; + gunichar2 *return_id; + gunichar2 *uwp_aumid; + gboolean got_value; + gchar *handler_id_u8; + gchar *handler_id_u8_folded; + g_assert (program_id); + + if (return_key) + *return_key = NULL; + + if (return_uwp_aumid) + *return_uwp_aumid = NULL; + + key = g_win32_registry_key_get_child_w (classes_root_key, program_id, NULL); + + if (key == NULL) + return NULL; + + /* Check for UWP first */ + uwp_aumid = NULL; + uwp_key = g_win32_registry_key_get_child_w (key, L"Application", NULL); + + if (uwp_key != NULL) + { + got_value = g_win32_registry_key_get_value_w (uwp_key, + NULL, + TRUE, + L"AppUserModelID", + &val_type, + (void **) &uwp_aumid, + NULL, + NULL); + if (got_value && val_type != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&uwp_aumid, g_free); + + /* Other values in the Application key contain useful information + * (description, name, icon), but it's inconvenient to read + * it here (we don't have an app object *yet*). Store the key + * in a table instead, and look at it later. + */ + if (uwp_aumid == NULL) + g_debug ("ProgramID %S looks like a UWP application, but isn't", + program_id); + else + g_hash_table_insert (uwp_handler_table, g_object_ref (uwp_key), g_wcsdup (uwp_aumid, -1)); + + g_object_unref (uwp_key); + } + + /* Then check for proxy */ + proxy_id = NULL; + + if (uwp_aumid == NULL) + { + got_value = g_win32_registry_key_get_value_w (key, + NULL, + TRUE, + L"", + &val_type, + (void **) &proxy_id, + NULL, + NULL); + if (got_value && val_type != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&proxy_id, g_free); + } + + return_id = NULL; + + if (proxy_id) + { + GWin32RegistryKey *proxy_key; + proxy_key = g_win32_registry_key_get_child_w (classes_root_key, proxy_id, NULL); + + if (proxy_key) + { + if (return_key) + *return_key = g_steal_pointer (&proxy_key); + g_clear_object (&proxy_key); + + return_id = g_steal_pointer (&proxy_id); + } + + g_clear_pointer (&proxy_id, g_free); + } + + if ((return_handler_id_u8 || + return_handler_id_u8_folded) && + !g_utf16_to_utf8_and_fold (return_id == NULL ? program_id : return_id, + -1, + &handler_id_u8, + &handler_id_u8_folded)) + { + g_clear_object (&key); + if (return_key) + g_clear_object (return_key); + g_clear_pointer (&return_id, g_free); + + return NULL; + } + + if (return_handler_id_u8) + *return_handler_id_u8 = g_steal_pointer (&handler_id_u8); + g_clear_pointer (&handler_id_u8, g_free); + if (return_handler_id_u8_folded) + *return_handler_id_u8_folded = g_steal_pointer (&handler_id_u8_folded); + g_clear_pointer (&handler_id_u8_folded, g_free); + if (return_uwp_aumid) + *return_uwp_aumid = g_steal_pointer (&uwp_aumid); + g_clear_pointer (&uwp_aumid, g_free); + + if (return_id == NULL && return_key) + *return_key = g_steal_pointer (&key); + g_clear_object (&key); + + if (return_id == NULL) + return g_wcsdup (program_id, -1); + + return return_id; +} + +/* Grabs the command for each verb from @verbs, + * and invokes @handler for it. Consumes @verbs. + * @path_to_progid and @progid are concatenated to + * produce a path to the key where Shell/verb/command + * subkeys are looked up. + * @preferred_verb, if not NULL, will be used to inform + * the @handler that a verb is preferred. + * @autoprefer_first_verb will automatically make the first + * verb to be preferred, if @preferred_verb is NULL. + * @handler_data1 and @handler_data2 are passed to @handler as-is. + */ +static void +process_verbs_commands (GList *verbs, + const reg_verb *preferred_verb, + const gunichar2 *path_to_progid, + const gunichar2 *progid, + gboolean autoprefer_first_verb, + verb_command_func handler, + gpointer handler_data1, + gpointer handler_data2) +{ + GList *i; + gboolean got_value; + + g_assert (handler != NULL); + g_assert (verbs != NULL); + g_assert (progid != NULL); + + for (i = verbs; i; i = i->next) + { + const reg_verb *verb = (const reg_verb *) i->data; + GWin32RegistryKey *key; + GWin32RegistryKey *verb_key; + gunichar2 *command_value; + gchar *command_value_utf8; + GWin32RegistryValueType val_type; + gunichar2 *verb_displayname; + gchar *verb_displayname_u8; + + key = _g_win32_registry_key_build_and_new_w (NULL, path_to_progid, progid, + L"\\", verb->shellpath, L"\\command", NULL); + + if (key == NULL) + { + g_debug ("%S%S\\shell\\%S does not have a \"command\" subkey", + path_to_progid, progid, verb->shellpath); + continue; + } + + command_value = NULL; + got_value = g_win32_registry_key_get_value_w (key, + NULL, + TRUE, + L"", + &val_type, + (void **) &command_value, + NULL, + NULL); + g_clear_object (&key); + + if (!got_value || + val_type != G_WIN32_REGISTRY_VALUE_STR || + (command_value_utf8 = g_utf16_to_utf8 (command_value, + -1, + NULL, + NULL, + NULL)) == NULL) + { + g_clear_pointer (&command_value, g_free); + continue; + } + + verb_displayname = NULL; + verb_displayname_u8 = NULL; + verb_key = _g_win32_registry_key_build_and_new_w (NULL, path_to_progid, progid, + L"\\", verb->shellpath, NULL); + + if (verb_key) + { + gsize verb_displayname_len; + + got_value = g_win32_registry_key_get_value_w (verb_key, + g_win32_registry_get_os_dirs_w (), + TRUE, + L"MUIVerb", + &val_type, + (void **) &verb_displayname, + &verb_displayname_len, + NULL); + + if (got_value && + val_type == G_WIN32_REGISTRY_VALUE_STR && + verb_displayname_len > sizeof (gunichar2)) + verb_displayname_u8 = g_utf16_to_utf8 (verb_displayname, -1, NULL, NULL, NULL); + + g_clear_pointer (&verb_displayname, g_free); + + if (verb_displayname_u8 == NULL) + { + got_value = g_win32_registry_key_get_value_w (verb_key, + NULL, + TRUE, + L"", + &val_type, + (void **) &verb_displayname, + &verb_displayname_len, + NULL); + + if (got_value && + val_type == G_WIN32_REGISTRY_VALUE_STR && + verb_displayname_len > sizeof (gunichar2)) + verb_displayname_u8 = g_utf16_to_utf8 (verb_displayname, -1, NULL, NULL, NULL); + } + + g_clear_pointer (&verb_displayname, g_free); + g_clear_object (&verb_key); + } + + handler (handler_data1, handler_data2, verb->name, command_value, command_value_utf8, + verb_displayname_u8, + (preferred_verb && _wcsicmp (verb->name, preferred_verb->name) == 0) || + (!preferred_verb && autoprefer_first_verb && i == verbs), + FALSE); + + g_clear_pointer (&command_value, g_free); + g_clear_pointer (&command_value_utf8, g_free); + g_clear_pointer (&verb_displayname_u8, g_free); + } + + g_list_free_full (verbs, reg_verb_free); +} + +static void +process_uwp_verbs (GList *verbs, + const reg_verb *preferred_verb, + const gunichar2 *path_to_progid, + const gunichar2 *progid, + gboolean autoprefer_first_verb, + GWin32AppInfoHandler *handler_rec, + GWin32AppInfoApplication *app) +{ + GList *i; + + g_assert (verbs != NULL); + + for (i = verbs; i; i = i->next) + { + const reg_verb *verb = (const reg_verb *) i->data; + GWin32RegistryKey *key; + gboolean got_value; + GWin32RegistryValueType val_type; + gunichar2 *acid; + gsize acid_len; + + key = _g_win32_registry_key_build_and_new_w (NULL, path_to_progid, progid, + L"\\", verb->shellpath, NULL); + + if (key == NULL) + { + g_debug ("%S%S\\%S does not exist", + path_to_progid, progid, verb->shellpath); + continue; + } + + acid = NULL; + got_value = g_win32_registry_key_get_value_w (key, + g_win32_registry_get_os_dirs_w (), + TRUE, + L"ActivatableClassId", + &val_type, + (void **) &acid, + &acid_len, + NULL); + + if (got_value && + val_type == G_WIN32_REGISTRY_VALUE_STR && + acid_len > sizeof (gunichar2)) + { + /* TODO: default value of a shell subkey, if not empty, + * migh contain something like @{Some.Identifier_1234.456.678.789_some_words?ms-resource://Arbitrary.Path/Pointing/Somewhere} + * and it might be possible to turn it into a nice displayname. + */ + uwp_handler_add_verb (handler_rec, + app, + verb->name, + NULL, + (preferred_verb && _wcsicmp (verb->name, preferred_verb->name) == 0) || + (!preferred_verb && autoprefer_first_verb && i == verbs)); + } + else + { + g_debug ("%S%S\\%S does not have an ActivatableClassId string value", + path_to_progid, progid, verb->shellpath); + } + + g_clear_pointer (&acid, g_free); + g_clear_object (&key); + } + + g_list_free_full (verbs, reg_verb_free); +} + +/* Looks up a schema object identified by + * @schema_u8_folded in the urls hash table. + * If such object doesn't exist, + * creates it and puts it into the urls hash table. + * Returns the object. + */ +static GWin32AppInfoURLSchema * +get_schema_object (const gunichar2 *schema, + const gchar *schema_u8, + const gchar *schema_u8_folded) +{ + GWin32AppInfoURLSchema *schema_rec; + + schema_rec = g_hash_table_lookup (urls, schema_u8_folded); + + if (schema_rec != NULL) + return schema_rec; + + schema_rec = g_object_new (G_TYPE_WIN32_APPINFO_URL_SCHEMA, NULL); + schema_rec->schema = g_wcsdup (schema, -1); + schema_rec->schema_u8 = g_strdup (schema_u8); + schema_rec->schema_u8_folded = g_strdup (schema_u8_folded); + g_hash_table_insert (urls, g_strdup (schema_rec->schema_u8_folded), schema_rec); + + return schema_rec; +} + +/* Looks up a handler object identified by + * @handler_id_u8_folded in the handlers hash table. + * If such object doesn't exist, + * creates it and puts it into the handlers hash table. + * Returns the object. + */ +static GWin32AppInfoHandler * +get_handler_object (const gchar *handler_id_u8_folded, + GWin32RegistryKey *handler_key, + const gunichar2 *handler_id, + const gunichar2 *uwp_aumid) +{ + GWin32AppInfoHandler *handler_rec; + + handler_rec = g_hash_table_lookup (handlers, handler_id_u8_folded); + + if (handler_rec != NULL) + return handler_rec; + + handler_rec = g_object_new (G_TYPE_WIN32_APPINFO_HANDLER, NULL); + if (handler_key) + handler_rec->key = g_object_ref (handler_key); + handler_rec->handler_id = g_wcsdup (handler_id, -1); + handler_rec->handler_id_folded = g_strdup (handler_id_u8_folded); + if (uwp_aumid) + handler_rec->uwp_aumid = g_wcsdup (uwp_aumid, -1); + if (handler_key) + read_handler_icon (handler_key, &handler_rec->icon); + g_hash_table_insert (handlers, g_strdup (handler_id_u8_folded), handler_rec); + + return handler_rec; +} + +static void +handler_add_verb (gpointer handler_data1, + gpointer handler_data2, + const gunichar2 *verb, + const gunichar2 *command_line, + const gchar *command_line_utf8, + const gchar *verb_displayname, + gboolean verb_is_preferred, + gboolean invent_new_verb_name) +{ + GWin32AppInfoHandler *handler_rec = (GWin32AppInfoHandler *) handler_data1; + GWin32AppInfoApplication *app_rec = (GWin32AppInfoApplication *) handler_data2; + GWin32AppInfoShellVerb *shverb; + + _verb_lookup (handler_rec->verbs, verb, &shverb); + + if (shverb != NULL) + return; + + shverb = g_object_new (G_TYPE_WIN32_APPINFO_SHELL_VERB, NULL); + shverb->verb_name = g_wcsdup (verb, -1); + shverb->verb_displayname = g_strdup (verb_displayname); + shverb->command = g_wcsdup (command_line, -1); + shverb->command_utf8 = g_strdup (command_line_utf8); + shverb->is_uwp = FALSE; /* This function is for non-UWP verbs only */ + if (app_rec) + shverb->app = g_object_ref (app_rec); + + _g_win32_extract_executable (shverb->command, + &shverb->executable, + &shverb->executable_basename, + &shverb->executable_folded, + NULL, + &shverb->dll_function); + + if (shverb->dll_function != NULL) + _g_win32_fixup_broken_microsoft_rundll_commandline (shverb->command); + + if (!verb_is_preferred) + g_ptr_array_add (handler_rec->verbs, shverb); + else + g_ptr_array_insert (handler_rec->verbs, 0, shverb); +} + +/* Tries to generate a new name for a verb that looks + * like "verb (%x)", where %x is an integer in range of [0;255). + * On success puts new verb (and new verb displayname) into + * @new_verb and @new_displayname and return TRUE. + * On failure puts NULL into both and returns FALSE. + */ +static gboolean +generate_new_verb_name (GPtrArray *verbs, + const gunichar2 *verb, + const gchar *verb_displayname, + gunichar2 **new_verb, + gchar **new_displayname) +{ + gsize counter; + GWin32AppInfoShellVerb *shverb; + gsize orig_len = g_utf16_len (verb); + gsize new_verb_name_len = orig_len + strlen (" ()") + 2 + 1; + gunichar2 *new_verb_name = g_new (gunichar2, new_verb_name_len); + + *new_verb = NULL; + *new_displayname = NULL; + + memcpy (new_verb_name, verb, orig_len * sizeof (gunichar2)); + for (counter = 0; counter < 255; counter++) + { + _snwprintf (&new_verb_name[orig_len], new_verb_name_len, L" (%zx)", counter); + _verb_lookup (verbs, new_verb_name, &shverb); + + if (shverb == NULL) + { + *new_verb = new_verb_name; + if (verb_displayname != NULL) + *new_displayname = g_strdup_printf ("%s (%zx)", verb_displayname, counter); + + return TRUE; + } + } + + return FALSE; +} + +static void +app_add_verb (gpointer handler_data1, + gpointer handler_data2, + const gunichar2 *verb, + const gunichar2 *command_line, + const gchar *command_line_utf8, + const gchar *verb_displayname, + gboolean verb_is_preferred, + gboolean invent_new_verb_name) +{ + gunichar2 *new_verb = NULL; + gchar *new_displayname = NULL; + GWin32AppInfoApplication *app_rec = (GWin32AppInfoApplication *) handler_data2; + GWin32AppInfoShellVerb *shverb; + + _verb_lookup (app_rec->verbs, verb, &shverb); + + /* Special logic for fake apps - do our best to + * collate all possible verbs in the app, + * including the verbs that have the same name but + * different commandlines, in which case a new + * verb name has to be invented. + */ + if (shverb != NULL) + { + gsize vi; + + if (!invent_new_verb_name) + return; + + for (vi = 0; vi < app_rec->verbs->len; vi++) + { + GWin32AppInfoShellVerb *app_verb; + + app_verb = _verb_idx (app_rec->verbs, vi); + + if (_wcsicmp (command_line, app_verb->command) == 0) + break; + } + + if (vi < app_rec->verbs->len || + !generate_new_verb_name (app_rec->verbs, + verb, + verb_displayname, + &new_verb, + &new_displayname)) + return; + } + + shverb = g_object_new (G_TYPE_WIN32_APPINFO_SHELL_VERB, NULL); + if (new_verb == NULL) + shverb->verb_name = g_wcsdup (verb, -1); + else + shverb->verb_name = g_steal_pointer (&new_verb); + if (new_displayname == NULL) + shverb->verb_displayname = g_strdup (verb_displayname); + else + shverb->verb_displayname = g_steal_pointer (&new_displayname); + + shverb->command = g_wcsdup (command_line, -1); + shverb->command_utf8 = g_strdup (command_line_utf8); + shverb->app = g_object_ref (app_rec); + + _g_win32_extract_executable (shverb->command, + &shverb->executable, + &shverb->executable_basename, + &shverb->executable_folded, + NULL, + &shverb->dll_function); + + if (shverb->dll_function != NULL) + _g_win32_fixup_broken_microsoft_rundll_commandline (shverb->command); + + if (!verb_is_preferred) + g_ptr_array_add (app_rec->verbs, shverb); + else + g_ptr_array_insert (app_rec->verbs, 0, shverb); +} + +static void +uwp_app_add_verb (GWin32AppInfoApplication *app_rec, + const gunichar2 *verb, + const gchar *verb_displayname) +{ + GWin32AppInfoShellVerb *shverb; + + _verb_lookup (app_rec->verbs, verb, &shverb); + + if (shverb != NULL) + return; + + shverb = g_object_new (G_TYPE_WIN32_APPINFO_SHELL_VERB, NULL); + shverb->verb_name = g_wcsdup (verb, -1); + shverb->app = g_object_ref (app_rec); + shverb->verb_displayname = g_strdup (verb_displayname); + + shverb->is_uwp = TRUE; + + /* Strictly speaking, this is unnecessary, but + * let's make it clear that UWP verbs have no + * commands and executables. + */ + shverb->command = NULL; + shverb->command_utf8 = NULL; + shverb->executable = NULL; + shverb->executable_basename = NULL; + shverb->executable_folded = NULL; + shverb->dll_function = NULL; + + g_ptr_array_add (app_rec->verbs, shverb); +} + +static void +uwp_handler_add_verb (GWin32AppInfoHandler *handler_rec, + GWin32AppInfoApplication *app, + const gunichar2 *verb, + const gchar *verb_displayname, + gboolean verb_is_preferred) +{ + GWin32AppInfoShellVerb *shverb; + + _verb_lookup (handler_rec->verbs, verb, &shverb); + + if (shverb != NULL) + return; + + shverb = g_object_new (G_TYPE_WIN32_APPINFO_SHELL_VERB, NULL); + shverb->verb_name = g_wcsdup (verb, -1); + shverb->verb_displayname = g_strdup (verb_displayname); + + shverb->is_uwp = TRUE; + + if (app) + shverb->app = g_object_ref (app); + + shverb->command = NULL; + shverb->command_utf8 = NULL; + shverb->executable = NULL; + shverb->executable_basename = NULL; + shverb->executable_folded = NULL; + shverb->dll_function = NULL; + + if (!verb_is_preferred) + g_ptr_array_add (handler_rec->verbs, shverb); + else + g_ptr_array_insert (handler_rec->verbs, 0, shverb); +} + +/* Looks up a file extension object identified by + * @ext_u8_folded in the extensions hash table. + * If such object doesn't exist, + * creates it and puts it into the extensions hash table. + * Returns the object. + */ +static GWin32AppInfoFileExtension * +get_ext_object (const gunichar2 *ext, + const gchar *ext_u8, + const gchar *ext_u8_folded) +{ + GWin32AppInfoFileExtension *file_extn; + + if (g_hash_table_lookup_extended (extensions, + ext_u8_folded, + NULL, + (void **) &file_extn)) + return file_extn; + + file_extn = g_object_new (G_TYPE_WIN32_APPINFO_FILE_EXTENSION, NULL); + file_extn->extension = g_wcsdup (ext, -1); + file_extn->extension_u8 = g_strdup (ext_u8); + g_hash_table_insert (extensions, g_strdup (ext_u8_folded), file_extn); + + return file_extn; +} + +/* Iterates over HKCU\\Software\\Clients or HKLM\\Software\\Clients, + * (depending on @user_registry being TRUE or FALSE), + * collecting applications listed there. + * Puts the path to the client key for each client into @priority_capable_apps + * (only for clients with file or URL associations). + */ +static void +collect_capable_apps_from_clients (GPtrArray *capable_apps, + GPtrArray *priority_capable_apps, + gboolean user_registry) +{ + GWin32RegistryKey *clients; + GWin32RegistrySubkeyIter clients_iter; + + const gunichar2 *client_type_name; + gsize client_type_name_len; + + + if (user_registry) + clients = + g_win32_registry_key_new_w (L"HKEY_CURRENT_USER\\Software\\Clients", + NULL); + else + clients = + g_win32_registry_key_new_w (L"HKEY_LOCAL_MACHINE\\Software\\Clients", + NULL); + + if (clients == NULL) + return; + + if (!g_win32_registry_subkey_iter_init (&clients_iter, clients, NULL)) + { + g_object_unref (clients); + return; + } + + while (g_win32_registry_subkey_iter_next (&clients_iter, TRUE, NULL)) + { + GWin32RegistrySubkeyIter subkey_iter; + GWin32RegistryKey *system_client_type; + GWin32RegistryValueType default_type; + gunichar2 *default_value = NULL; + const gunichar2 *client_name; + gsize client_name_len; + + if (!g_win32_registry_subkey_iter_get_name_w (&clients_iter, + &client_type_name, + &client_type_name_len, + NULL)) + continue; + + system_client_type = g_win32_registry_key_get_child_w (clients, + client_type_name, + NULL); + + if (system_client_type == NULL) + continue; + + if (g_win32_registry_key_get_value_w (system_client_type, + NULL, + TRUE, + L"", + &default_type, + (gpointer *) &default_value, + NULL, + NULL)) + { + if (default_type != G_WIN32_REGISTRY_VALUE_STR || + default_value[0] == L'\0') + g_clear_pointer (&default_value, g_free); + } + + if (!g_win32_registry_subkey_iter_init (&subkey_iter, + system_client_type, + NULL)) + { + g_clear_pointer (&default_value, g_free); + g_object_unref (system_client_type); + continue; + } + + while (g_win32_registry_subkey_iter_next (&subkey_iter, TRUE, NULL)) + { + GWin32RegistryKey *system_client; + GWin32RegistryKey *system_client_assoc; + gboolean add; + gunichar2 *keyname; + + if (!g_win32_registry_subkey_iter_get_name_w (&subkey_iter, + &client_name, + &client_name_len, + NULL)) + continue; + + system_client = g_win32_registry_key_get_child_w (system_client_type, + client_name, + NULL); + + if (system_client == NULL) + continue; + + add = FALSE; + + system_client_assoc = g_win32_registry_key_get_child_w (system_client, + L"Capabilities\\FileAssociations", + NULL); + + if (system_client_assoc != NULL) + { + add = TRUE; + g_object_unref (system_client_assoc); + } + else + { + system_client_assoc = g_win32_registry_key_get_child_w (system_client, + L"Capabilities\\UrlAssociations", + NULL); + + if (system_client_assoc != NULL) + { + add = TRUE; + g_object_unref (system_client_assoc); + } + } + + if (add) + { + keyname = g_wcsdup (g_win32_registry_key_get_path_w (system_client), -1); + + if (default_value && wcscmp (default_value, client_name) == 0) + g_ptr_array_add (priority_capable_apps, keyname); + else + g_ptr_array_add (capable_apps, keyname); + } + + g_object_unref (system_client); + } + + g_win32_registry_subkey_iter_clear (&subkey_iter); + g_clear_pointer (&default_value, g_free); + g_object_unref (system_client_type); + } + + g_win32_registry_subkey_iter_clear (&clients_iter); + g_object_unref (clients); +} + +/* Iterates over HKCU\\Software\\RegisteredApplications or HKLM\\Software\\RegisteredApplications, + * (depending on @user_registry being TRUE or FALSE), + * collecting applications listed there. + * Puts the path to the app key for each app into @capable_apps. + */ +static void +collect_capable_apps_from_registered_apps (GPtrArray *capable_apps, + gboolean user_registry) +{ + GWin32RegistryValueIter iter; + const gunichar2 *reg_path; + + gunichar2 *value_data; + gsize value_data_size; + GWin32RegistryValueType value_type; + GWin32RegistryKey *registered_apps; + + if (user_registry) + reg_path = L"HKEY_CURRENT_USER\\Software\\RegisteredApplications"; + else + reg_path = L"HKEY_LOCAL_MACHINE\\Software\\RegisteredApplications"; + + registered_apps = + g_win32_registry_key_new_w (reg_path, NULL); + + if (!registered_apps) + return; + + if (!g_win32_registry_value_iter_init (&iter, registered_apps, NULL)) + { + g_object_unref (registered_apps); + + return; + } + + while (g_win32_registry_value_iter_next (&iter, TRUE, NULL)) + { + gunichar2 possible_location[REG_PATH_MAX_SIZE + 1]; + GWin32RegistryKey *location; + gunichar2 *p; + + if ((!g_win32_registry_value_iter_get_value_type (&iter, + &value_type, + NULL)) || + (value_type != G_WIN32_REGISTRY_VALUE_STR) || + (!g_win32_registry_value_iter_get_data_w (&iter, TRUE, + (void **) &value_data, + &value_data_size, + NULL)) || + (value_data_size < sizeof (gunichar2)) || + (value_data[0] == L'\0')) + continue; + + if (!build_registry_path (possible_location, sizeof (possible_location), + user_registry ? HKCU : HKLM, value_data, NULL)) + continue; + + location = g_win32_registry_key_new_w (possible_location, NULL); + + if (location == NULL) + continue; + + p = wcsrchr (possible_location, L'\\'); + + if (p) + { + *p = L'\0'; + g_ptr_array_add (capable_apps, g_wcsdup (possible_location, -1)); + } + + g_object_unref (location); + } + + g_win32_registry_value_iter_clear (&iter); + g_object_unref (registered_apps); +} + +/* Looks up an app object identified by + * @canonical_name_folded in the @app_hashmap. + * If such object doesn't exist, + * creates it and puts it into the @app_hashmap. + * Returns the object. + */ +static GWin32AppInfoApplication * +get_app_object (GHashTable *app_hashmap, + const gunichar2 *canonical_name, + const gchar *canonical_name_u8, + const gchar *canonical_name_folded, + gboolean user_specific, + gboolean default_app, + gboolean is_uwp) +{ + GWin32AppInfoApplication *app; + + app = g_hash_table_lookup (app_hashmap, canonical_name_folded); + + if (app != NULL) + return app; + + app = g_object_new (G_TYPE_WIN32_APPINFO_APPLICATION, NULL); + app->canonical_name = g_wcsdup (canonical_name, -1); + app->canonical_name_u8 = g_strdup (canonical_name_u8); + app->canonical_name_folded = g_strdup (canonical_name_folded); + app->no_open_with = FALSE; + app->user_specific = user_specific; + app->default_app = default_app; + app->is_uwp = is_uwp; + g_hash_table_insert (app_hashmap, + g_strdup (canonical_name_folded), + app); + + return app; +} + +/* Grabs an application that has Capabilities. + * @app_key_path is the path to the application key + * (which must have a "Capabilities" subkey). + * @default_app is TRUE if the app has priority + */ +static void +read_capable_app (const gunichar2 *app_key_path, + gboolean user_specific, + gboolean default_app) +{ + GWin32AppInfoApplication *app; + gchar *canonical_name_u8 = NULL; + gchar *canonical_name_folded = NULL; + gchar *app_key_path_u8 = NULL; + gchar *app_key_path_u8_folded = NULL; + GWin32RegistryKey *appkey = NULL; + gunichar2 *fallback_friendly_name; + GWin32RegistryValueType vtype; + gboolean success; + gunichar2 *friendly_name; + gunichar2 *description; + gunichar2 *narrow_application_name; + gunichar2 *icon_source; + GWin32RegistryKey *capabilities; + GWin32RegistryKey *default_icon_key; + GWin32RegistryKey *associations; + const reg_verb *preferred_verb; + GList *verbs = NULL; + gboolean verbs_in_root_key = TRUE; + + appkey = NULL; + capabilities = NULL; + + if (!g_utf16_to_utf8_and_fold (app_key_path, + -1, + &canonical_name_u8, + &canonical_name_folded) || + !g_utf16_to_utf8_and_fold (app_key_path, + -1, + &app_key_path_u8, + &app_key_path_u8_folded) || + (appkey = g_win32_registry_key_new_w (app_key_path, NULL)) == NULL || + (capabilities = g_win32_registry_key_get_child_w (appkey, L"Capabilities", NULL)) == NULL || + !(get_verbs (appkey, &preferred_verb, &verbs, L"", L"Shell", NULL) || + (verbs_in_root_key = FALSE) || + get_verbs (capabilities, &preferred_verb, &verbs, L"", L"Shell", NULL))) + { + g_clear_pointer (&canonical_name_u8, g_free); + g_clear_pointer (&canonical_name_folded, g_free); + g_clear_object (&appkey); + g_clear_object (&capabilities); + g_clear_pointer (&app_key_path_u8, g_free); + g_clear_pointer (&app_key_path_u8_folded, g_free); + + return; + } + + app = get_app_object (apps_by_id, + app_key_path, + canonical_name_u8, + canonical_name_folded, + user_specific, + default_app, + FALSE); + + process_verbs_commands (g_steal_pointer (&verbs), + preferred_verb, + L"", /* [ab]use the fact that two strings are simply concatenated */ + verbs_in_root_key ? app_key_path : g_win32_registry_key_get_path_w (capabilities), + FALSE, + app_add_verb, + app, + app); + + fallback_friendly_name = NULL; + success = g_win32_registry_key_get_value_w (appkey, + NULL, + TRUE, + L"", + &vtype, + (void **) &fallback_friendly_name, + NULL, + NULL); + + if (success && vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&fallback_friendly_name, g_free); + + if (fallback_friendly_name && + app->pretty_name == NULL) + { + app->pretty_name = g_wcsdup (fallback_friendly_name, -1); + g_clear_pointer (&app->pretty_name_u8, g_free); + app->pretty_name_u8 = g_utf16_to_utf8 (fallback_friendly_name, + -1, + NULL, + NULL, + NULL); + } + + friendly_name = NULL; + success = g_win32_registry_key_get_value_w (capabilities, + g_win32_registry_get_os_dirs_w (), + TRUE, + L"LocalizedString", + &vtype, + (void **) &friendly_name, + NULL, + NULL); + + if (success && + vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&friendly_name, g_free); + + if (friendly_name && + app->localized_pretty_name == NULL) + { + app->localized_pretty_name = g_wcsdup (friendly_name, -1); + g_clear_pointer (&app->localized_pretty_name_u8, g_free); + app->localized_pretty_name_u8 = g_utf16_to_utf8 (friendly_name, + -1, + NULL, + NULL, + NULL); + } + + description = NULL; + success = g_win32_registry_key_get_value_w (capabilities, + g_win32_registry_get_os_dirs_w (), + TRUE, + L"ApplicationDescription", + &vtype, + (void **) &description, + NULL, + NULL); + + if (success && vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&description, g_free); + + if (description && app->description == NULL) + { + app->description = g_wcsdup (description, -1); + g_clear_pointer (&app->description_u8, g_free); + app->description_u8 = g_utf16_to_utf8 (description, -1, NULL, NULL, NULL); + } + + default_icon_key = g_win32_registry_key_get_child_w (appkey, + L"DefaultIcon", + NULL); + + icon_source = NULL; + + if (default_icon_key != NULL) + { + success = g_win32_registry_key_get_value_w (default_icon_key, + NULL, + TRUE, + L"", + &vtype, + (void **) &icon_source, + NULL, + NULL); + + if (success && + vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&icon_source, g_free); + + g_object_unref (default_icon_key); + } + + if (icon_source == NULL) + { + success = g_win32_registry_key_get_value_w (capabilities, + NULL, + TRUE, + L"ApplicationIcon", + &vtype, + (void **) &icon_source, + NULL, + NULL); + + if (success && + vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&icon_source, g_free); + } + + if (icon_source && + app->icon == NULL) + { + gchar *name = g_utf16_to_utf8 (icon_source, -1, NULL, NULL, NULL); + app->icon = g_themed_icon_new (name); + g_free (name); + } + + narrow_application_name = NULL; + success = g_win32_registry_key_get_value_w (capabilities, + g_win32_registry_get_os_dirs_w (), + TRUE, + L"ApplicationName", + &vtype, + (void **) &narrow_application_name, + NULL, + NULL); + + if (success && vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&narrow_application_name, g_free); + + if (narrow_application_name && + app->localized_pretty_name == NULL) + { + app->localized_pretty_name = g_wcsdup (narrow_application_name, -1); + g_clear_pointer (&app->localized_pretty_name_u8, g_free); + app->localized_pretty_name_u8 = g_utf16_to_utf8 (narrow_application_name, + -1, + NULL, + NULL, + NULL); + } + + associations = g_win32_registry_key_get_child_w (capabilities, + L"FileAssociations", + NULL); + + if (associations != NULL) + { + GWin32RegistryValueIter iter; + + if (g_win32_registry_value_iter_init (&iter, associations, NULL)) + { + gunichar2 *file_extension; + gunichar2 *extension_handler; + gsize file_extension_len; + gsize extension_handler_size; + GWin32RegistryValueType value_type; + + while (g_win32_registry_value_iter_next (&iter, TRUE, NULL)) + { + if ((!g_win32_registry_value_iter_get_value_type (&iter, + &value_type, + NULL)) || + (value_type != G_WIN32_REGISTRY_VALUE_STR) || + (!g_win32_registry_value_iter_get_name_w (&iter, + &file_extension, + &file_extension_len, + NULL)) || + (file_extension_len <= 0) || + (file_extension[0] != L'.') || + (!g_win32_registry_value_iter_get_data_w (&iter, TRUE, + (void **) &extension_handler, + &extension_handler_size, + NULL)) || + (extension_handler_size < sizeof (gunichar2)) || + (extension_handler[0] == L'\0')) + continue; + + get_file_ext (extension_handler, file_extension, app, FALSE); + } + + g_win32_registry_value_iter_clear (&iter); + } + + g_object_unref (associations); + } + + associations = g_win32_registry_key_get_child_w (capabilities, L"URLAssociations", NULL); + + if (associations != NULL) + { + GWin32RegistryValueIter iter; + + if (g_win32_registry_value_iter_init (&iter, associations, NULL)) + { + gunichar2 *url_schema; + gunichar2 *schema_handler; + gsize url_schema_len; + gsize schema_handler_size; + GWin32RegistryValueType value_type; + + while (g_win32_registry_value_iter_next (&iter, TRUE, NULL)) + { + gchar *schema_u8; + gchar *schema_u8_folded; + + if ((!g_win32_registry_value_iter_get_value_type (&iter, + &value_type, + NULL)) || + ((value_type != G_WIN32_REGISTRY_VALUE_STR) && + (value_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR)) || + (!g_win32_registry_value_iter_get_name_w (&iter, + &url_schema, + &url_schema_len, + NULL)) || + (url_schema_len <= 0) || + (url_schema[0] == L'\0') || + (!g_win32_registry_value_iter_get_data_w (&iter, TRUE, + (void **) &schema_handler, + &schema_handler_size, + NULL)) || + (schema_handler_size < sizeof (gunichar2)) || + (schema_handler[0] == L'\0')) + continue; + + + + if (g_utf16_to_utf8_and_fold (url_schema, + url_schema_len, + &schema_u8, + &schema_u8_folded)) + get_url_association (schema_handler, url_schema, schema_u8, schema_u8_folded, app, FALSE); + + g_clear_pointer (&schema_u8, g_free); + g_clear_pointer (&schema_u8_folded, g_free); + } + + g_win32_registry_value_iter_clear (&iter); + } + + g_object_unref (associations); + } + + g_clear_pointer (&fallback_friendly_name, g_free); + g_clear_pointer (&description, g_free); + g_clear_pointer (&icon_source, g_free); + g_clear_pointer (&narrow_application_name, g_free); + + g_object_unref (appkey); + g_object_unref (capabilities); + g_clear_pointer (&app_key_path_u8, g_free); + g_clear_pointer (&app_key_path_u8_folded, g_free); + g_clear_pointer (&canonical_name_u8, g_free); + g_clear_pointer (&canonical_name_folded, g_free); +} + +/* Iterates over subkeys in HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\ + * and calls get_url_association() for each one that has a user-chosen handler. + */ +static void +read_urls (GWin32RegistryKey *url_associations) +{ + GWin32RegistrySubkeyIter url_iter; + + if (url_associations == NULL) + return; + + if (!g_win32_registry_subkey_iter_init (&url_iter, url_associations, NULL)) + return; + + while (g_win32_registry_subkey_iter_next (&url_iter, TRUE, NULL)) + { + gchar *schema_u8 = NULL; + gchar *schema_u8_folded = NULL; + const gunichar2 *url_schema = NULL; + gunichar2 *program_id = NULL; + GWin32RegistryKey *user_choice = NULL; + gsize url_schema_len; + GWin32RegistryValueType val_type; + + if (g_win32_registry_subkey_iter_get_name_w (&url_iter, + &url_schema, + &url_schema_len, + NULL) && + g_utf16_to_utf8_and_fold (url_schema, + url_schema_len, + &schema_u8, + &schema_u8_folded) && + (user_choice = _g_win32_registry_key_build_and_new_w (NULL, URL_ASSOCIATIONS, + url_schema, USER_CHOICE, + NULL)) != NULL && + g_win32_registry_key_get_value_w (user_choice, + NULL, + TRUE, + L"Progid", + &val_type, + (void **) &program_id, + NULL, + NULL) && + val_type == G_WIN32_REGISTRY_VALUE_STR) + get_url_association (program_id, url_schema, schema_u8, schema_u8_folded, NULL, TRUE); + + g_clear_pointer (&program_id, g_free); + g_clear_pointer (&user_choice, g_object_unref); + g_clear_pointer (&schema_u8, g_free); + g_clear_pointer (&schema_u8_folded, g_free); + } + + g_win32_registry_subkey_iter_clear (&url_iter); +} + +/* Reads an application that is only registered by the basename of its + * executable (and doesn't have Capabilities subkey). + * @incapable_app is the registry key for the app. + * @app_exe_basename is the basename of its executable. + */ +static void +read_incapable_app (GWin32RegistryKey *incapable_app, + const gunichar2 *app_exe_basename, + const gchar *app_exe_basename_u8, + const gchar *app_exe_basename_u8_folded) +{ + GWin32RegistryValueIter sup_iter; + GWin32AppInfoApplication *app; + GList *verbs; + const reg_verb *preferred_verb; + gunichar2 *friendly_app_name; + gboolean success; + GWin32RegistryValueType vtype; + gboolean no_open_with; + GWin32RegistryKey *default_icon_key; + gunichar2 *icon_source; + GIcon *icon = NULL; + GWin32RegistryKey *supported_key; + + if (!get_verbs (incapable_app, &preferred_verb, &verbs, L"", L"Shell", NULL)) + return; + + app = get_app_object (apps_by_exe, + app_exe_basename, + app_exe_basename_u8, + app_exe_basename_u8_folded, + FALSE, + FALSE, + FALSE); + + process_verbs_commands (g_steal_pointer (&verbs), + preferred_verb, + L"HKEY_CLASSES_ROOT\\Applications\\", + app_exe_basename, + TRUE, + app_add_verb, + app, + app); + + friendly_app_name = NULL; + success = g_win32_registry_key_get_value_w (incapable_app, + g_win32_registry_get_os_dirs_w (), + TRUE, + L"FriendlyAppName", + &vtype, + (void **) &friendly_app_name, + NULL, + NULL); + + if (success && vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&friendly_app_name, g_free); + + no_open_with = g_win32_registry_key_get_value_w (incapable_app, + NULL, + TRUE, + L"NoOpenWith", + &vtype, + NULL, + NULL, + NULL); + + default_icon_key = + g_win32_registry_key_get_child_w (incapable_app, + L"DefaultIcon", + NULL); + + icon_source = NULL; + + if (default_icon_key != NULL) + { + success = + g_win32_registry_key_get_value_w (default_icon_key, + NULL, + TRUE, + L"", + &vtype, + (void **) &icon_source, + NULL, + NULL); + + if (success && vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&icon_source, g_free); + + g_object_unref (default_icon_key); + } + + if (icon_source) + { + gchar *name = g_utf16_to_utf8 (icon_source, -1, NULL, NULL, NULL); + if (name != NULL) + icon = g_themed_icon_new (name); + g_free (name); + } + + app->no_open_with = no_open_with; + + if (friendly_app_name && + app->localized_pretty_name == NULL) + { + app->localized_pretty_name = g_wcsdup (friendly_app_name, -1); + g_clear_pointer (&app->localized_pretty_name_u8, g_free); + app->localized_pretty_name_u8 = + g_utf16_to_utf8 (friendly_app_name, -1, NULL, NULL, NULL); + } + + if (icon && app->icon == NULL) + app->icon = g_object_ref (icon); + + supported_key = + g_win32_registry_key_get_child_w (incapable_app, + L"SupportedTypes", + NULL); + + if (supported_key && + g_win32_registry_value_iter_init (&sup_iter, supported_key, NULL)) + { + gunichar2 *ext_name; + gsize ext_name_len; + + while (g_win32_registry_value_iter_next (&sup_iter, TRUE, NULL)) + { + if ((!g_win32_registry_value_iter_get_name_w (&sup_iter, + &ext_name, + &ext_name_len, + NULL)) || + (ext_name_len <= 0) || + (ext_name[0] != L'.')) + continue; + + get_file_ext (ext_name, ext_name, app, FALSE); + } + + g_win32_registry_value_iter_clear (&sup_iter); + } + + g_clear_object (&supported_key); + g_free (friendly_app_name); + g_free (icon_source); + + g_clear_object (&icon); +} + +/* Iterates over subkeys of HKEY_CLASSES_ROOT\\Applications + * and calls read_incapable_app() for each one. + */ +static void +read_exeapps (void) +{ + GWin32RegistryKey *applications_key; + GWin32RegistrySubkeyIter app_iter; + + applications_key = + g_win32_registry_key_new_w (L"HKEY_CLASSES_ROOT\\Applications", NULL); + + if (applications_key == NULL) + return; + + if (!g_win32_registry_subkey_iter_init (&app_iter, applications_key, NULL)) + { + g_object_unref (applications_key); + return; + } + + while (g_win32_registry_subkey_iter_next (&app_iter, TRUE, NULL)) + { + const gunichar2 *app_exe_basename; + gsize app_exe_basename_len; + GWin32RegistryKey *incapable_app; + gchar *app_exe_basename_u8; + gchar *app_exe_basename_u8_folded; + + if (!g_win32_registry_subkey_iter_get_name_w (&app_iter, + &app_exe_basename, + &app_exe_basename_len, + NULL) || + !g_utf16_to_utf8_and_fold (app_exe_basename, + app_exe_basename_len, + &app_exe_basename_u8, + &app_exe_basename_u8_folded)) + continue; + + incapable_app = + g_win32_registry_key_get_child_w (applications_key, + app_exe_basename, + NULL); + + if (incapable_app != NULL) + read_incapable_app (incapable_app, + app_exe_basename, + app_exe_basename_u8, + app_exe_basename_u8_folded); + + g_clear_object (&incapable_app); + g_clear_pointer (&app_exe_basename_u8, g_free); + g_clear_pointer (&app_exe_basename_u8_folded, g_free); + } + + g_win32_registry_subkey_iter_clear (&app_iter); + g_object_unref (applications_key); +} + +/* Iterates over subkeys of HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\ + * and calls get_file_ext() for each associated handler + * (starting with user-chosen handler, if any) + */ +static void +read_exts (GWin32RegistryKey *file_exts) +{ + GWin32RegistrySubkeyIter ext_iter; + const gunichar2 *file_extension; + gsize file_extension_len; + + if (file_exts == NULL) + return; + + if (!g_win32_registry_subkey_iter_init (&ext_iter, file_exts, NULL)) + return; + + while (g_win32_registry_subkey_iter_next (&ext_iter, TRUE, NULL)) + { + GWin32RegistryKey *open_with_progids; + gunichar2 *program_id; + GWin32RegistryValueIter iter; + gunichar2 *value_name; + gsize value_name_len; + GWin32RegistryValueType value_type; + GWin32RegistryKey *user_choice; + + if (!g_win32_registry_subkey_iter_get_name_w (&ext_iter, + &file_extension, + &file_extension_len, + NULL)) + continue; + + program_id = NULL; + user_choice = _g_win32_registry_key_build_and_new_w (NULL, FILE_EXTS, file_extension, + USER_CHOICE, NULL); + if (user_choice && + g_win32_registry_key_get_value_w (user_choice, + NULL, + TRUE, + L"Progid", + &value_type, + (void **) &program_id, + NULL, + NULL) && + value_type == G_WIN32_REGISTRY_VALUE_STR) + { + /* Note: program_id could be "ProgramID" or "Applications\\program.exe". + * The code still works, but handler_id might have a backslash + * in it - that might trip us up later on. + * Even though in that case this is logically an "application" + * registry entry, we don't treat it in any special way. + * We do scan that registry branch anyway, just not here. + */ + get_file_ext (program_id, file_extension, NULL, TRUE); + } + + g_clear_object (&user_choice); + g_clear_pointer (&program_id, g_free); + + open_with_progids = _g_win32_registry_key_build_and_new_w (NULL, FILE_EXTS, + file_extension, + OPEN_WITH_PROGIDS, + NULL); + + if (open_with_progids == NULL) + continue; + + if (!g_win32_registry_value_iter_init (&iter, open_with_progids, NULL)) + { + g_clear_object (&open_with_progids); + continue; + } + + while (g_win32_registry_value_iter_next (&iter, TRUE, NULL)) + { + if (!g_win32_registry_value_iter_get_name_w (&iter, &value_name, + &value_name_len, + NULL) || + (value_name_len == 0)) + continue; + + get_file_ext (value_name, file_extension, NULL, FALSE); + } + + g_win32_registry_value_iter_clear (&iter); + g_clear_object (&open_with_progids); + } + + g_win32_registry_subkey_iter_clear (&ext_iter); +} + +/* Iterates over subkeys in HKCR, calls + * get_file_ext() for any subkey that starts with ".", + * or get_url_association() for any subkey that could + * be a URL schema and has a "URL Protocol" value. + */ +static void +read_classes (GWin32RegistryKey *classes_root) +{ + GWin32RegistrySubkeyIter class_iter; + const gunichar2 *class_name; + gsize class_name_len; + + if (classes_root == NULL) + return; + + if (!g_win32_registry_subkey_iter_init (&class_iter, classes_root, NULL)) + return; + + while (g_win32_registry_subkey_iter_next (&class_iter, TRUE, NULL)) + { + if ((!g_win32_registry_subkey_iter_get_name_w (&class_iter, + &class_name, + &class_name_len, + NULL)) || + (class_name_len <= 1)) + continue; + + if (class_name[0] == L'.') + { + GWin32RegistryKey *class_key; + GWin32RegistryValueIter iter; + GWin32RegistryKey *open_with_progids; + gunichar2 *value_name; + gsize value_name_len; + + /* Read the data from the HKCR\\.ext (usually proxied + * to another HKCR subkey) + */ + get_file_ext (class_name, class_name, NULL, FALSE); + + class_key = g_win32_registry_key_get_child_w (classes_root, class_name, NULL); + + if (class_key == NULL) + continue; + + open_with_progids = g_win32_registry_key_get_child_w (class_key, L"OpenWithProgids", NULL); + g_clear_object (&class_key); + + if (open_with_progids == NULL) + continue; + + if (!g_win32_registry_value_iter_init (&iter, open_with_progids, NULL)) + { + g_clear_object (&open_with_progids); + continue; + } + + /* Read the data for other handlers for this extension */ + while (g_win32_registry_value_iter_next (&iter, TRUE, NULL)) + { + if (!g_win32_registry_value_iter_get_name_w (&iter, &value_name, + &value_name_len, + NULL) || + (value_name_len == 0)) + continue; + + get_file_ext (value_name, class_name, NULL, FALSE); + } + + g_win32_registry_value_iter_clear (&iter); + g_clear_object (&open_with_progids); + } + else + { + gsize i; + GWin32RegistryKey *class_key; + gboolean success; + GWin32RegistryValueType vtype; + gchar *schema_u8; + gchar *schema_u8_folded; + + for (i = 0; i < class_name_len; i++) + if (!iswalpha (class_name[i])) + break; + + if (i != class_name_len) + continue; + + class_key = g_win32_registry_key_get_child_w (classes_root, class_name, NULL); + + if (class_key == NULL) + continue; + + success = g_win32_registry_key_get_value_w (class_key, + NULL, + TRUE, + L"URL Protocol", + &vtype, + NULL, + NULL, + NULL); + g_clear_object (&class_key); + + if (!success || + vtype != G_WIN32_REGISTRY_VALUE_STR) + continue; + + if (!g_utf16_to_utf8_and_fold (class_name, -1, &schema_u8, &schema_u8_folded)) + continue; + + get_url_association (class_name, class_name, schema_u8, schema_u8_folded, NULL, FALSE); + + g_clear_pointer (&schema_u8, g_free); + g_clear_pointer (&schema_u8_folded, g_free); + } + } + + g_win32_registry_subkey_iter_clear (&class_iter); +} + +/* Iterates over all handlers and over all apps, + * and links handler verbs to apps if a handler + * runs the same executable as one of the app verbs. + */ +static void +link_handlers_to_unregistered_apps (void) +{ + GHashTableIter iter; + GHashTableIter app_iter; + GWin32AppInfoHandler *handler; + gchar *handler_id_fld; + GWin32AppInfoApplication *app; + gchar *canonical_name_fld; + gchar *appexe_fld_basename; + + g_hash_table_iter_init (&iter, handlers); + while (g_hash_table_iter_next (&iter, + (gpointer *) &handler_id_fld, + (gpointer *) &handler)) + { + gsize vi; + + if (handler->uwp_aumid != NULL) + continue; + + for (vi = 0; vi < handler->verbs->len; vi++) + { + GWin32AppInfoShellVerb *handler_verb; + const gchar *handler_exe_basename; + enum + { + SH_UNKNOWN, + GOT_SH_INFO, + ERROR_GETTING_SH_INFO, + } have_stat_handler = SH_UNKNOWN; + GWin32PrivateStat handler_verb_exec_info; + + handler_verb = _verb_idx (handler->verbs, vi); + + if (handler_verb->app != NULL) + continue; + + handler_exe_basename = g_utf8_find_basename (handler_verb->executable_folded, -1); + g_hash_table_iter_init (&app_iter, apps_by_id); + + while (g_hash_table_iter_next (&app_iter, + (gpointer *) &canonical_name_fld, + (gpointer *) &app)) + { + GWin32AppInfoShellVerb *app_verb; + gsize ai; + + if (app->is_uwp) + continue; + + for (ai = 0; ai < app->verbs->len; ai++) + { + GWin32PrivateStat app_verb_exec_info; + const gchar *app_exe_basename; + app_verb = _verb_idx (app->verbs, ai); + + app_exe_basename = g_utf8_find_basename (app_verb->executable_folded, -1); + + /* First check that the executable paths are identical */ + if (g_strcmp0 (app_verb->executable_folded, handler_verb->executable_folded) != 0) + { + /* If not, check the basenames. If they are different, don't bother + * with further checks. + */ + if (g_strcmp0 (app_exe_basename, handler_exe_basename) != 0) + continue; + + /* Get filesystem IDs for both files. + * For the handler that is attempted only once. + */ + if (have_stat_handler == SH_UNKNOWN) + { + if (GLIB_PRIVATE_CALL (g_win32_stat_utf8) (handler_verb->executable_folded, + &handler_verb_exec_info) == 0) + have_stat_handler = GOT_SH_INFO; + else + have_stat_handler = ERROR_GETTING_SH_INFO; + } + + if (have_stat_handler != GOT_SH_INFO || + (GLIB_PRIVATE_CALL (g_win32_stat_utf8) (app_verb->executable_folded, + &app_verb_exec_info) != 0) || + app_verb_exec_info.file_index != handler_verb_exec_info.file_index) + continue; + } + + handler_verb->app = g_object_ref (app); + break; + } + } + + if (handler_verb->app != NULL) + continue; + + g_hash_table_iter_init (&app_iter, apps_by_exe); + + while (g_hash_table_iter_next (&app_iter, + (gpointer *) &appexe_fld_basename, + (gpointer *) &app)) + { + if (app->is_uwp) + continue; + + /* Use basename because apps_by_exe only has basenames */ + if (g_strcmp0 (handler_exe_basename, appexe_fld_basename) != 0) + continue; + + handler_verb->app = g_object_ref (app); + break; + } + } + } +} + +/* Finds all .ext and schema: handler verbs that have no app linked to them, + * creates a "fake app" object and links these verbs to these + * objects. Objects are identified by the full path to + * the executable being run, thus multiple different invocations + * get grouped in a more-or-less natural way. + * The iteration goes separately over .ext and schema: handlers + * (instead of the global handlers hashmap) to allow us to + * put the handlers into supported_urls or supported_exts as + * needed (handler objects themselves have no knowledge of extensions + * and/or URLs they are associated with). + */ +static void +link_handlers_to_fake_apps (void) +{ + GHashTableIter iter; + GHashTableIter handler_iter; + gchar *extension_utf8_folded; + GWin32AppInfoFileExtension *file_extn; + gchar *handler_id_fld; + GWin32AppInfoHandler *handler; + gchar *url_utf8_folded; + GWin32AppInfoURLSchema *schema; + + g_hash_table_iter_init (&iter, extensions); + while (g_hash_table_iter_next (&iter, + (gpointer *) &extension_utf8_folded, + (gpointer *) &file_extn)) + { + g_hash_table_iter_init (&handler_iter, file_extn->handlers); + while (g_hash_table_iter_next (&handler_iter, + (gpointer *) &handler_id_fld, + (gpointer *) &handler)) + { + gsize vi; + + if (handler->uwp_aumid != NULL) + continue; + + for (vi = 0; vi < handler->verbs->len; vi++) + { + GWin32AppInfoShellVerb *handler_verb; + GWin32AppInfoApplication *app; + gunichar2 *exename_utf16; + handler_verb = _verb_idx (handler->verbs, vi); + + if (handler_verb->app != NULL) + continue; + + exename_utf16 = g_utf8_to_utf16 (handler_verb->executable, -1, NULL, NULL, NULL); + if (exename_utf16 == NULL) + continue; + + app = get_app_object (fake_apps, + exename_utf16, + handler_verb->executable, + handler_verb->executable_folded, + FALSE, + FALSE, + FALSE); + g_clear_pointer (&exename_utf16, g_free); + handler_verb->app = g_object_ref (app); + + app_add_verb (app, + app, + handler_verb->verb_name, + handler_verb->command, + handler_verb->command_utf8, + handler_verb->verb_displayname, + TRUE, + TRUE); + g_hash_table_insert (app->supported_exts, + g_strdup (extension_utf8_folded), + g_object_ref (handler)); + } + } + } + + g_hash_table_iter_init (&iter, urls); + while (g_hash_table_iter_next (&iter, + (gpointer *) &url_utf8_folded, + (gpointer *) &schema)) + { + g_hash_table_iter_init (&handler_iter, schema->handlers); + while (g_hash_table_iter_next (&handler_iter, + (gpointer *) &handler_id_fld, + (gpointer *) &handler)) + { + gsize vi; + + if (handler->uwp_aumid != NULL) + continue; + + for (vi = 0; vi < handler->verbs->len; vi++) + { + GWin32AppInfoShellVerb *handler_verb; + GWin32AppInfoApplication *app; + gchar *command_utf8_folded; + handler_verb = _verb_idx (handler->verbs, vi); + + if (handler_verb->app != NULL) + continue; + + command_utf8_folded = g_utf8_casefold (handler_verb->command_utf8, -1); + app = get_app_object (fake_apps, + handler_verb->command, + handler_verb->command_utf8, + command_utf8_folded, + FALSE, + FALSE, + FALSE); + g_clear_pointer (&command_utf8_folded, g_free); + handler_verb->app = g_object_ref (app); + + app_add_verb (app, + app, + handler_verb->verb_name, + handler_verb->command, + handler_verb->command_utf8, + handler_verb->verb_displayname, + TRUE, + TRUE); + g_hash_table_insert (app->supported_urls, + g_strdup (url_utf8_folded), + g_object_ref (handler)); + } + } + } +} + +static GWin32AppInfoHandler * +find_uwp_handler_for_ext (GWin32AppInfoFileExtension *file_extn, + const gunichar2 *app_user_model_id) +{ + GHashTableIter handler_iter; + gchar *handler_id_fld; + GWin32AppInfoHandler *handler; + + g_hash_table_iter_init (&handler_iter, file_extn->handlers); + while (g_hash_table_iter_next (&handler_iter, + (gpointer *) &handler_id_fld, + (gpointer *) &handler)) + { + if (handler->uwp_aumid == NULL) + continue; + + if (_wcsicmp (handler->uwp_aumid, app_user_model_id) == 0) + return handler; + } + + return NULL; +} + +static GWin32AppInfoHandler * +find_uwp_handler_for_schema (GWin32AppInfoURLSchema *schema, + const gunichar2 *app_user_model_id) +{ + GHashTableIter handler_iter; + gchar *handler_id_fld; + GWin32AppInfoHandler *handler; + + g_hash_table_iter_init (&handler_iter, schema->handlers); + while (g_hash_table_iter_next (&handler_iter, + (gpointer *) &handler_id_fld, + (gpointer *) &handler)) + { + if (handler->uwp_aumid == NULL) + continue; + + if (_wcsicmp (handler->uwp_aumid, app_user_model_id) == 0) + return handler; + } + + return NULL; +} + +static gboolean +uwp_package_cb (gpointer user_data, + const gunichar2 *full_package_name, + const gunichar2 *package_name, + const gunichar2 *app_user_model_id, + gboolean show_in_applist, + GPtrArray *supported_extgroups, + GPtrArray *supported_protocols) +{ + guint i, i_verb, i_ext; + gint extensions_considered; + GWin32AppInfoApplication *app; + gchar *app_user_model_id_u8; + gchar *app_user_model_id_u8_folded; + GHashTableIter iter; + GWin32AppInfoHandler *ext; + GWin32AppInfoHandler *url; + + if (!g_utf16_to_utf8_and_fold (app_user_model_id, + -1, + &app_user_model_id_u8, + &app_user_model_id_u8_folded)) + return TRUE; + + app = get_app_object (apps_by_id, + app_user_model_id, + app_user_model_id_u8, + app_user_model_id_u8_folded, + TRUE, + FALSE, + TRUE); + + extensions_considered = 0; + + for (i = 0; i < supported_extgroups->len; i++) + { + GWin32PackageExtGroup *grp = (GWin32PackageExtGroup *) g_ptr_array_index (supported_extgroups, i); + + extensions_considered += grp->extensions->len; + + for (i_ext = 0; i_ext < grp->extensions->len; i_ext++) + { + wchar_t *ext = (wchar_t *) g_ptr_array_index (grp->extensions, i_ext); + gchar *ext_u8; + gchar *ext_u8_folded; + GWin32AppInfoFileExtension *file_extn; + GWin32AppInfoHandler *handler_rec; + + if (!g_utf16_to_utf8_and_fold (ext, + -1, + &ext_u8, + &ext_u8_folded)) + continue; + + file_extn = get_ext_object (ext, ext_u8, ext_u8_folded); + g_free (ext_u8); + handler_rec = find_uwp_handler_for_ext (file_extn, app_user_model_id); + + if (handler_rec == NULL) + { + /* Use AppUserModelId as the ID of the new fake handler */ + handler_rec = get_handler_object (app_user_model_id_u8_folded, + NULL, + app_user_model_id, + app_user_model_id); + g_hash_table_insert (file_extn->handlers, + g_strdup (app_user_model_id_u8_folded), + g_object_ref (handler_rec)); + } + + if (file_extn->chosen_handler == NULL) + g_set_object (&file_extn->chosen_handler, handler_rec); + + /* This is somewhat wasteful, but for 100% correct handling + * we need to remember which extensions (handlers) support + * which verbs, and each handler gets its own copy of the + * verb object, since our design is handler-centric, + * not verb-centric. The app also gets a list of verbs, + * but without handlers it would have no idea which + * verbs can be used with which extensions. + */ + for (i_verb = 0; i_verb < grp->verbs->len; i_verb++) + { + wchar_t *verb = NULL; + + verb = (wchar_t *) g_ptr_array_index (grp->verbs, i_verb); + /* *_add_verb() functions are no-ops when a verb already exists, + * so we're free to call them as many times as we want. + */ + uwp_handler_add_verb (handler_rec, + app, + verb, + NULL, + FALSE); + } + + g_hash_table_insert (app->supported_exts, + g_steal_pointer (&ext_u8_folded), + g_object_ref (handler_rec)); + } + } + + g_hash_table_iter_init (&iter, app->supported_exts); + + /* Pile up all handler verbs into the app too, + * for cases when we don't have a ref to a handler. + */ + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &ext)) + { + guint i_hverb; + + if (!ext) + continue; + + for (i_hverb = 0; i_hverb < ext->verbs->len; i_hverb++) + { + GWin32AppInfoShellVerb *handler_verb; + + handler_verb = _verb_idx (ext->verbs, i_hverb); + uwp_app_add_verb (app, handler_verb->verb_name, handler_verb->verb_displayname); + if (handler_verb->app == NULL && handler_verb->is_uwp) + handler_verb->app = g_object_ref (app); + } + } + + if (app->verbs->len == 0 && extensions_considered > 0) + g_debug ("Unexpectedly, UWP app `%S' (AUMId `%s') supports %d extensions but has no verbs", + full_package_name, app_user_model_id_u8, extensions_considered); + + for (i = 0; i < supported_protocols->len; i++) + { + wchar_t *proto = (wchar_t *) g_ptr_array_index (supported_protocols, i); + gchar *proto_u8; + gchar *proto_u8_folded; + GWin32AppInfoURLSchema *schema_rec; + GWin32AppInfoHandler *handler_rec; + + if (!g_utf16_to_utf8_and_fold (proto, + -1, + &proto_u8, + &proto_u8_folded)) + continue; + + schema_rec = get_schema_object (proto, + proto_u8, + proto_u8_folded); + + g_free (proto_u8); + + handler_rec = find_uwp_handler_for_schema (schema_rec, app_user_model_id); + + if (handler_rec == NULL) + { + /* Use AppUserModelId as the ID of the new fake handler */ + handler_rec = get_handler_object (app_user_model_id_u8_folded, + NULL, + app_user_model_id, + app_user_model_id); + + g_hash_table_insert (schema_rec->handlers, + g_strdup (app_user_model_id_u8_folded), + g_object_ref (handler_rec)); + } + + if (schema_rec->chosen_handler == NULL) + g_set_object (&schema_rec->chosen_handler, handler_rec); + + /* Technically, UWP apps don't use verbs for URIs, + * but we only store an app field in verbs, + * so each UWP URI handler has to have one. + * Let's call it "open". + */ + uwp_handler_add_verb (handler_rec, + app, + L"open", + NULL, + TRUE); + + g_hash_table_insert (app->supported_urls, + g_steal_pointer (&proto_u8_folded), + g_object_ref (handler_rec)); + } + + g_hash_table_iter_init (&iter, app->supported_urls); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &url)) + { + guint i_hverb; + + if (!url) + continue; + + for (i_hverb = 0; i_hverb < url->verbs->len; i_hverb++) + { + GWin32AppInfoShellVerb *handler_verb; + + handler_verb = _verb_idx (url->verbs, i_hverb); + uwp_app_add_verb (app, handler_verb->verb_name, handler_verb->verb_displayname); + if (handler_verb->app == NULL && handler_verb->is_uwp) + handler_verb->app = g_object_ref (app); + } + } + + g_free (app_user_model_id_u8); + g_free (app_user_model_id_u8_folded); + + return TRUE; +} + +/* Calls SHLoadIndirectString() in a loop to resolve + * a string in @{...} format (also supports other indirect + * strings, but we aren't using it for those). + * Consumes the input, but may return it unmodified + * (not an indirect string). May return %NULL (the string + * is indirect, but the OS failed to load it). + */ +static gunichar2 * +resolve_string (gunichar2 *at_string) +{ + HRESULT hr; + gunichar2 *result = NULL; + gsize result_size; + /* This value is arbitrary */ + const gsize reasonable_size_limit = 8192; + + if (at_string == NULL || at_string[0] != L'@') + return at_string; + + /* In case of a no-op @at_string will be copied into the output, + * buffer so allocate at least that much. + */ + result_size = wcslen (at_string) + 1; + + while (TRUE) + { + result = g_renew (gunichar2, result, result_size); + /* Since there's no built-in way to detect too small buffer size, + * we do so by putting a sentinel at the end of the buffer. + * If it's 0 (result is always 0-terminated, even if the buffer + * is too small), then try larger buffer. + */ + result[result_size - 1] = 0xff; + /* This string accepts size in characters, not bytes. */ + hr = SHLoadIndirectString (at_string, result, result_size, NULL); + if (!SUCCEEDED (hr)) + { + g_free (result); + g_free (at_string); + return NULL; + } + else if (result[result_size - 1] != 0 || + result_size >= reasonable_size_limit) + { + /* Now that the length is known, allocate the exact amount */ + gunichar2 *copy = g_wcsdup (result, -1); + g_free (result); + g_free (at_string); + return copy; + } + + result_size *= 2; + } + + g_assert_not_reached (); + + return at_string; +} + +static void +grab_registry_string (GWin32RegistryKey *handler_appkey, + const gunichar2 *value_name, + gunichar2 **destination, + gchar **destination_u8) +{ + gunichar2 *value; + gsize value_size; + GWin32RegistryValueType vtype; + const gunichar2 *ms_resource_prefix = L"ms-resource:"; + gsize ms_resource_prefix_len = wcslen (ms_resource_prefix); + + /* Right now this function is not used without destination, + * enforce this. destination_u8 is optional. + */ + g_assert (destination != NULL); + + if (*destination != NULL) + return; + + value = NULL; + if (g_win32_registry_key_get_value_w (handler_appkey, + NULL, + TRUE, + value_name, + &vtype, + (void **) &value, + &value_size, + NULL) && + vtype != G_WIN32_REGISTRY_VALUE_STR) + g_clear_pointer (&value, g_free); + + /* There's no way for us to resolve "ms-resource:..." strings */ + if (value != NULL && + value_size >= ms_resource_prefix_len && + memcmp (value, + ms_resource_prefix, + ms_resource_prefix_len * sizeof (gunichar2)) == 0) + g_clear_pointer (&value, g_free); + + if (value == NULL) + return; + + *destination = resolve_string (g_steal_pointer (&value)); + + if (*destination == NULL) + return; + + if (destination_u8) + *destination_u8 = g_utf16_to_utf8 (*destination, -1, NULL, NULL, NULL); +} + +static void +read_uwp_handler_info (void) +{ + GHashTableIter iter; + GWin32RegistryKey *handler_appkey; + gunichar2 *aumid; + + g_hash_table_iter_init (&iter, uwp_handler_table); + + while (g_hash_table_iter_next (&iter, (gpointer *) &handler_appkey, (gpointer *) &aumid)) + { + gchar *aumid_u8_folded; + GWin32AppInfoApplication *app; + + if (!g_utf16_to_utf8_and_fold (aumid, + -1, + NULL, + &aumid_u8_folded)) + continue; + + app = g_hash_table_lookup (apps_by_id, aumid_u8_folded); + g_clear_pointer (&aumid_u8_folded, g_free); + + if (app == NULL) + continue; + + grab_registry_string (handler_appkey, L"ApplicationDescription", &app->description, &app->description_u8); + grab_registry_string (handler_appkey, L"ApplicationName", &app->localized_pretty_name, &app->localized_pretty_name_u8); + /* TODO: ApplicationIcon value (usually also @{...}) resolves into + * an image (PNG only?) with implicit multiple variants (scale, size, etc). + */ + } +} + +static void +update_registry_data (void) +{ + guint i; + GPtrArray *capable_apps_keys; + GPtrArray *user_capable_apps_keys; + GPtrArray *priority_capable_apps_keys; + GWin32RegistryKey *url_associations; + GWin32RegistryKey *file_exts; + GWin32RegistryKey *classes_root; + DWORD collect_start, collect_end, alloc_end, capable_end, url_end, ext_end, exeapp_end, classes_end, uwp_end, postproc_end; + GError *error = NULL; + + url_associations = + g_win32_registry_key_new_w (L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations", + NULL); + file_exts = + g_win32_registry_key_new_w (L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts", + NULL); + classes_root = g_win32_registry_key_new_w (L"HKEY_CLASSES_ROOT", NULL); + + capable_apps_keys = g_ptr_array_new_with_free_func (g_free); + user_capable_apps_keys = g_ptr_array_new_with_free_func (g_free); + priority_capable_apps_keys = g_ptr_array_new_with_free_func (g_free); + + g_clear_pointer (&apps_by_id, g_hash_table_destroy); + g_clear_pointer (&apps_by_exe, g_hash_table_destroy); + g_clear_pointer (&fake_apps, g_hash_table_destroy); + g_clear_pointer (&urls, g_hash_table_destroy); + g_clear_pointer (&extensions, g_hash_table_destroy); + g_clear_pointer (&handlers, g_hash_table_destroy); + + collect_start = GetTickCount (); + collect_capable_apps_from_clients (capable_apps_keys, + priority_capable_apps_keys, + FALSE); + collect_capable_apps_from_clients (user_capable_apps_keys, + priority_capable_apps_keys, + TRUE); + collect_capable_apps_from_registered_apps (user_capable_apps_keys, + TRUE); + collect_capable_apps_from_registered_apps (capable_apps_keys, + FALSE); + collect_end = GetTickCount (); + + apps_by_id = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + apps_by_exe = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + fake_apps = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + urls = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + extensions = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + handlers = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + uwp_handler_table = + g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, g_free); + alloc_end = GetTickCount (); + + for (i = 0; i < priority_capable_apps_keys->len; i++) + read_capable_app (g_ptr_array_index (priority_capable_apps_keys, i), + TRUE, + TRUE); + for (i = 0; i < user_capable_apps_keys->len; i++) + read_capable_app (g_ptr_array_index (user_capable_apps_keys, i), + TRUE, + FALSE); + for (i = 0; i < capable_apps_keys->len; i++) + read_capable_app (g_ptr_array_index (capable_apps_keys, i), + FALSE, + FALSE); + capable_end = GetTickCount (); + + read_urls (url_associations); + url_end = GetTickCount (); + read_exts (file_exts); + ext_end = GetTickCount (); + read_exeapps (); + exeapp_end = GetTickCount (); + read_classes (classes_root); + classes_end = GetTickCount (); + + if (!g_win32_package_parser_enum_packages (uwp_package_cb, NULL, &error)) + { + g_debug ("Unable to get UWP apps: %s", error->message); + g_clear_error (&error); + } + + read_uwp_handler_info (); + + uwp_end = GetTickCount (); + link_handlers_to_unregistered_apps (); + link_handlers_to_fake_apps (); + postproc_end = GetTickCount (); + + g_debug ("Collecting capable appnames: %lums\n" + "Allocating hashtables:...... %lums\n" + "Reading capable apps: %lums\n" + "Reading URL associations:... %lums\n" + "Reading extension assocs: %lums\n" + "Reading exe-only apps:...... %lums\n" + "Reading classes: %lums\n" + "Reading UWP apps: %lums\n" + "Postprocessing:..............%lums\n" + "TOTAL: %lums", + collect_end - collect_start, + alloc_end - collect_end, + capable_end - alloc_end, + url_end - capable_end, + ext_end - url_end, + exeapp_end - ext_end, + classes_end - exeapp_end, + uwp_end - classes_end, + postproc_end - uwp_end, + postproc_end - collect_start); + + g_clear_object (&classes_root); + g_clear_object (&url_associations); + g_clear_object (&file_exts); + g_ptr_array_free (capable_apps_keys, TRUE); + g_ptr_array_free (user_capable_apps_keys, TRUE); + g_ptr_array_free (priority_capable_apps_keys, TRUE); + g_hash_table_unref (uwp_handler_table); + + return; +} + +static void +watch_keys (void); + +/* This function is called when any of our registry watchers detect + * changes in the registry. + */ +static void +keys_updated (GWin32RegistryKey *key, + gpointer user_data) +{ + watch_keys (); + /* Indicate the tree as not up-to-date, push a new job for the AppInfo thread */ + g_atomic_int_inc (&gio_win32_appinfo_update_counter); + /* We don't use the data pointer, but it must be non-NULL */ + g_thread_pool_push (gio_win32_appinfo_threadpool, (gpointer) keys_updated, NULL); +} + +static void +watch_keys (void) +{ + if (url_associations_key) + g_win32_registry_key_watch (url_associations_key, + TRUE, + G_WIN32_REGISTRY_WATCH_NAME | + G_WIN32_REGISTRY_WATCH_ATTRIBUTES | + G_WIN32_REGISTRY_WATCH_VALUES, + keys_updated, + NULL, + NULL); + + if (file_exts_key) + g_win32_registry_key_watch (file_exts_key, + TRUE, + G_WIN32_REGISTRY_WATCH_NAME | + G_WIN32_REGISTRY_WATCH_ATTRIBUTES | + G_WIN32_REGISTRY_WATCH_VALUES, + keys_updated, + NULL, + NULL); + + if (user_clients_key) + g_win32_registry_key_watch (user_clients_key, + TRUE, + G_WIN32_REGISTRY_WATCH_NAME | + G_WIN32_REGISTRY_WATCH_ATTRIBUTES | + G_WIN32_REGISTRY_WATCH_VALUES, + keys_updated, + NULL, + NULL); + + if (system_clients_key) + g_win32_registry_key_watch (system_clients_key, + TRUE, + G_WIN32_REGISTRY_WATCH_NAME | + G_WIN32_REGISTRY_WATCH_ATTRIBUTES | + G_WIN32_REGISTRY_WATCH_VALUES, + keys_updated, + NULL, + NULL); + + if (applications_key) + g_win32_registry_key_watch (applications_key, + TRUE, + G_WIN32_REGISTRY_WATCH_NAME | + G_WIN32_REGISTRY_WATCH_ATTRIBUTES | + G_WIN32_REGISTRY_WATCH_VALUES, + keys_updated, + NULL, + NULL); + + if (user_registered_apps_key) + g_win32_registry_key_watch (user_registered_apps_key, + TRUE, + G_WIN32_REGISTRY_WATCH_NAME | + G_WIN32_REGISTRY_WATCH_ATTRIBUTES | + G_WIN32_REGISTRY_WATCH_VALUES, + keys_updated, + NULL, + NULL); + + if (system_registered_apps_key) + g_win32_registry_key_watch (system_registered_apps_key, + TRUE, + G_WIN32_REGISTRY_WATCH_NAME | + G_WIN32_REGISTRY_WATCH_ATTRIBUTES | + G_WIN32_REGISTRY_WATCH_VALUES, + keys_updated, + NULL, + NULL); + + if (classes_root_key) + g_win32_registry_key_watch (classes_root_key, + FALSE, + G_WIN32_REGISTRY_WATCH_NAME | + G_WIN32_REGISTRY_WATCH_ATTRIBUTES | + G_WIN32_REGISTRY_WATCH_VALUES, + keys_updated, + NULL, + NULL); +} + +/* This is the main function of the AppInfo thread */ +static void +gio_win32_appinfo_thread_func (gpointer data, + gpointer user_data) +{ + gint saved_counter; + g_mutex_lock (&gio_win32_appinfo_mutex); + saved_counter = g_atomic_int_get (&gio_win32_appinfo_update_counter); + + if (saved_counter > 0) + update_registry_data (); + /* If the counter didn't change while we were working, then set it to zero. + * Otherwise we need to rebuild the tree again, so keep it greater than zero. + * Numeric value doesn't matter - even if we're asked to rebuild N times, + * we just need to rebuild once, and as long as there were no new rebuild + * requests while we were working, we're done. + */ + if (g_atomic_int_compare_and_exchange (&gio_win32_appinfo_update_counter, + saved_counter, + 0)) + g_cond_broadcast (&gio_win32_appinfo_cond); + + g_mutex_unlock (&gio_win32_appinfo_mutex); +} + +/* Initializes Windows AppInfo. Creates the registry watchers, + * the AppInfo thread, and initiates an update of the AppInfo tree. + * Called with do_wait = `FALSE` at startup to prevent it from + * blocking until the tree is updated. All subsequent calls + * from everywhere else are made with do_wait = `TRUE`, blocking + * until the tree is re-built (if needed). + */ +void +gio_win32_appinfo_init (gboolean do_wait) +{ + static gsize initialized; + + if (g_once_init_enter (&initialized)) + { + HMODULE gio_dll_extra; + + url_associations_key = + g_win32_registry_key_new_w (L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations", + NULL); + file_exts_key = + g_win32_registry_key_new_w (L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts", + NULL); + user_clients_key = + g_win32_registry_key_new_w (L"HKEY_CURRENT_USER\\Software\\Clients", + NULL); + system_clients_key = + g_win32_registry_key_new_w (L"HKEY_LOCAL_MACHINE\\Software\\Clients", + NULL); + applications_key = + g_win32_registry_key_new_w (L"HKEY_CLASSES_ROOT\\Applications", + NULL); + user_registered_apps_key = + g_win32_registry_key_new_w (L"HKEY_CURRENT_USER\\Software\\RegisteredApplications", + NULL); + system_registered_apps_key = + g_win32_registry_key_new_w (L"HKEY_LOCAL_MACHINE\\Software\\RegisteredApplications", + NULL); + classes_root_key = + g_win32_registry_key_new_w (L"HKEY_CLASSES_ROOT", + NULL); + + watch_keys (); + + /* We don't really require an exclusive pool, but the implementation + * details might cause the g_thread_pool_push() call below to block + * if the pool is not exclusive (specifically - for POSIX threads backend + * lacking thread scheduler settings). + */ + gio_win32_appinfo_threadpool = g_thread_pool_new (gio_win32_appinfo_thread_func, + NULL, + 1, + TRUE, + NULL); + g_mutex_init (&gio_win32_appinfo_mutex); + g_cond_init (&gio_win32_appinfo_cond); + g_atomic_int_set (&gio_win32_appinfo_update_counter, 1); + /* Trigger initial tree build. Fake data pointer. */ + g_thread_pool_push (gio_win32_appinfo_threadpool, (gpointer) keys_updated, NULL); + /* Increment the DLL refcount */ + GetModuleHandleExA (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, + (const char *) gio_win32_appinfo_init, + &gio_dll_extra); + /* gio DLL cannot be unloaded now */ + + g_once_init_leave (&initialized, TRUE); + } + + if (!do_wait) + return; + + /* Previously, we checked each of the watched keys here. + * Now we just look at the update counter, because each key + * has a change callback keys_updated, which increments this counter. + */ + if (g_atomic_int_get (&gio_win32_appinfo_update_counter) > 0) + { + g_mutex_lock (&gio_win32_appinfo_mutex); + while (g_atomic_int_get (&gio_win32_appinfo_update_counter) > 0) + g_cond_wait (&gio_win32_appinfo_cond, &gio_win32_appinfo_mutex); + g_mutex_unlock (&gio_win32_appinfo_mutex); + } +} + + +static void g_win32_app_info_iface_init (GAppInfoIface *iface); + +struct _GWin32AppInfo +{ + GObject parent_instance; + + /**/ + gchar **supported_types; + + GWin32AppInfoApplication *app; + + GWin32AppInfoHandler *handler; + + guint startup_notify : 1; +}; + +G_DEFINE_TYPE_WITH_CODE (GWin32AppInfo, g_win32_app_info, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_APP_INFO, + g_win32_app_info_iface_init)) + + +static void +g_win32_app_info_finalize (GObject *object) +{ + GWin32AppInfo *info; + + info = G_WIN32_APP_INFO (object); + + g_clear_pointer (&info->supported_types, g_strfreev); + g_clear_object (&info->app); + g_clear_object (&info->handler); + + G_OBJECT_CLASS (g_win32_app_info_parent_class)->finalize (object); +} + +static void +g_win32_app_info_class_init (GWin32AppInfoClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_win32_app_info_finalize; +} + +static void +g_win32_app_info_init (GWin32AppInfo *local) +{ +} + +static GAppInfo * +g_win32_app_info_new_from_app (GWin32AppInfoApplication *app, + GWin32AppInfoHandler *handler) +{ + GWin32AppInfo *new_info; + GHashTableIter iter; + gpointer ext; + int i; + + new_info = g_object_new (G_TYPE_WIN32_APP_INFO, NULL); + + new_info->app = g_object_ref (app); + + gio_win32_appinfo_init (TRUE); + g_mutex_lock (&gio_win32_appinfo_mutex); + + i = 0; + g_hash_table_iter_init (&iter, new_info->app->supported_exts); + + while (g_hash_table_iter_next (&iter, &ext, NULL)) + { + if (ext) + i += 1; + } + + new_info->supported_types = g_new (gchar *, i + 1); + + i = 0; + g_hash_table_iter_init (&iter, new_info->app->supported_exts); + + while (g_hash_table_iter_next (&iter, &ext, NULL)) + { + if (!ext) + continue; + + new_info->supported_types[i] = g_strdup ((gchar *) ext); + i += 1; + } + + g_mutex_unlock (&gio_win32_appinfo_mutex); + + new_info->supported_types[i] = NULL; + + new_info->handler = handler ? g_object_ref (handler) : NULL; + + return G_APP_INFO (new_info); +} + + +static GAppInfo * +g_win32_app_info_dup (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + GWin32AppInfo *new_info; + + new_info = g_object_new (G_TYPE_WIN32_APP_INFO, NULL); + + if (info->app) + new_info->app = g_object_ref (info->app); + + if (info->handler) + new_info->handler = g_object_ref (info->handler); + + new_info->startup_notify = info->startup_notify; + + if (info->supported_types) + { + int i; + + for (i = 0; info->supported_types[i]; i++) + break; + + new_info->supported_types = g_new (gchar *, i + 1); + + for (i = 0; info->supported_types[i]; i++) + new_info->supported_types[i] = g_strdup (info->supported_types[i]); + + new_info->supported_types[i] = NULL; + } + + return G_APP_INFO (new_info); +} + +static gboolean +g_win32_app_info_equal (GAppInfo *appinfo1, + GAppInfo *appinfo2) +{ + GWin32AppInfoShellVerb *shverb1 = NULL; + GWin32AppInfoShellVerb *shverb2 = NULL; + GWin32AppInfo *info1 = G_WIN32_APP_INFO (appinfo1); + GWin32AppInfo *info2 = G_WIN32_APP_INFO (appinfo2); + GWin32AppInfoApplication *app1 = info1->app; + GWin32AppInfoApplication *app2 = info2->app; + + if (app1 == NULL || + app2 == NULL) + return info1 == info2; + + if (app1->canonical_name_folded != NULL && + app2->canonical_name_folded != NULL) + return (g_strcmp0 (app1->canonical_name_folded, + app2->canonical_name_folded)) == 0; + + if (app1->verbs->len > 0 && + app2->verbs->len > 0) + { + shverb1 = _verb_idx (app1->verbs, 0); + shverb2 = _verb_idx (app2->verbs, 0); + if (shverb1->executable_folded != NULL && + shverb2->executable_folded != NULL) + return (g_strcmp0 (shverb1->executable_folded, + shverb2->executable_folded)) == 0; + } + + return app1 == app2; +} + +static const char * +g_win32_app_info_get_id (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + GWin32AppInfoShellVerb *shverb; + + if (info->app == NULL) + return NULL; + + if (info->app->canonical_name_u8) + return info->app->canonical_name_u8; + + if (info->app->verbs->len > 0 && + (shverb = _verb_idx (info->app->verbs, 0))->executable_basename != NULL) + return shverb->executable_basename; + + return NULL; +} + +static const char * +g_win32_app_info_get_name (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app && info->app->pretty_name_u8) + return info->app->pretty_name_u8; + else if (info->app && info->app->canonical_name_u8) + return info->app->canonical_name_u8; + else + return P_("Unnamed"); +} + +static const char * +g_win32_app_info_get_display_name (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app) + { + if (info->app->localized_pretty_name_u8) + return info->app->localized_pretty_name_u8; + else if (info->app->pretty_name_u8) + return info->app->pretty_name_u8; + } + + return g_win32_app_info_get_name (appinfo); +} + +static const char * +g_win32_app_info_get_description (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app == NULL) + return NULL; + + return info->app->description_u8; +} + +static const char * +g_win32_app_info_get_executable (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app == NULL) + return NULL; + + if (info->app->verbs->len > 0 && !info->app->is_uwp) + return _verb_idx (info->app->verbs, 0)->executable; + + return NULL; +} + +static const char * +g_win32_app_info_get_commandline (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app == NULL) + return NULL; + + if (info->app->verbs->len > 0 && !info->app->is_uwp) + return _verb_idx (info->app->verbs, 0)->command_utf8; + + return NULL; +} + +static GIcon * +g_win32_app_info_get_icon (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app == NULL) + return NULL; + + return info->app->icon; +} + +typedef struct _file_or_uri { + gchar *uri; + gchar *file; +} file_or_uri; + +static char * +expand_macro_single (char macro, file_or_uri *obj) +{ + char *result = NULL; + + switch (macro) + { + case '*': + case '0': + case '1': + case 'l': + case 'd': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* TODO: handle 'l' and 'd' differently (longname and desktop name) */ + if (obj->uri) + result = g_strdup (obj->uri); + else if (obj->file) + result = g_strdup (obj->file); + break; + case 'u': + case 'U': + if (obj->uri) + result = g_shell_quote (obj->uri); + break; + case 'f': + case 'F': + if (obj->file) + result = g_shell_quote (obj->file); + break; + } + + return result; +} + +static gboolean +expand_macro (char macro, + GString *exec, + GWin32AppInfo *info, + GList **stat_obj_list, + GList **obj_list) +{ + GList *objs = *obj_list; + char *expanded; + gboolean result = FALSE; + + g_return_val_if_fail (exec != NULL, FALSE); + +/* +Legend: (from http://msdn.microsoft.com/en-us/library/windows/desktop/cc144101%28v=vs.85%29.aspx) +%* - replace with all parameters +%~ - replace with all parameters starting with and following the second parameter +%0 or %1 the first file parameter. For example "C:\\Users\\Eric\\Destop\\New Text Document.txt". Generally this should be in quotes and the applications command line parsing should accept quotes to disambiguate files with spaces in the name and different command line parameters (this is a security best practice and I believe mentioned in MSDN). +% (where N is 2 - 9), replace with the nth parameter +%s - show command +%h - hotkey value +%i - IDList stored in a shared memory handle is passed here. +%l - long file name form of the first parameter. Note win32 applications will be passed the long file name, win16 applications get the short file name. Specifying %L is preferred as it avoids the need to probe for the application type. +%d - desktop absolute parsing name of the first parameter (for items that don't have file system paths) +%v - for verbs that are none implies all, if there is no parameter passed this is the working directory +%w - the working directory +*/ + + switch (macro) + { + case '*': + case '~': + if (*stat_obj_list) + { + gint i; + GList *o; + + for (o = *stat_obj_list, i = 0; + macro == '~' && o && i < 2; + o = o->next, i++); + + for (; o; o = o->next) + { + expanded = expand_macro_single (macro, o->data); + + if (expanded) + { + if (o != *stat_obj_list) + g_string_append (exec, " "); + + g_string_append (exec, expanded); + g_free (expanded); + } + } + + objs = NULL; + result = TRUE; + } + break; + case '0': + case '1': + case 'l': + case 'd': + if (*stat_obj_list) + { + GList *o; + + o = *stat_obj_list; + + if (o) + { + expanded = expand_macro_single (macro, o->data); + + if (expanded) + { + if (o != *stat_obj_list) + g_string_append (exec, " "); + + g_string_append (exec, expanded); + g_free (expanded); + } + } + + if (objs) + objs = objs->next; + + result = TRUE; + } + break; + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (*stat_obj_list) + { + gint i; + GList *o; + gint n; + + switch (macro) + { + case '2': + n = 2; + break; + case '3': + n = 3; + break; + case '4': + n = 4; + break; + case '5': + n = 5; + break; + case '6': + n = 6; + break; + case '7': + n = 7; + break; + case '8': + n = 8; + break; + case '9': + n = 9; + break; + } + + for (o = *stat_obj_list, i = 0; o && i < n; o = o->next, i++); + + if (o) + { + expanded = expand_macro_single (macro, o->data); + + if (expanded) + { + if (o != *stat_obj_list) + g_string_append (exec, " "); + + g_string_append (exec, expanded); + g_free (expanded); + } + } + result = TRUE; + + if (objs) + objs = NULL; + } + break; + case 's': + break; + case 'h': + break; + case 'i': + break; + case 'v': + break; + case 'w': + expanded = g_get_current_dir (); + g_string_append (exec, expanded); + g_free (expanded); + break; + case 'u': + case 'f': + if (objs) + { + expanded = expand_macro_single (macro, objs->data); + + if (expanded) + { + g_string_append (exec, expanded); + g_free (expanded); + } + objs = objs->next; + result = TRUE; + } + + break; + + case 'U': + case 'F': + while (objs) + { + expanded = expand_macro_single (macro, objs->data); + + if (expanded) + { + g_string_append (exec, expanded); + g_free (expanded); + } + + objs = objs->next; + result = TRUE; + + if (objs != NULL && expanded) + g_string_append_c (exec, ' '); + } + + break; + + case 'c': + if (info->app && info->app->localized_pretty_name_u8) + { + expanded = g_shell_quote (info->app->localized_pretty_name_u8); + g_string_append (exec, expanded); + g_free (expanded); + } + break; + + case 'm': /* deprecated */ + case 'n': /* deprecated */ + case 'N': /* deprecated */ + /*case 'd': *//* deprecated */ + case 'D': /* deprecated */ + break; + + case '%': + g_string_append_c (exec, '%'); + break; + } + + *obj_list = objs; + + return result; +} + +static gboolean +expand_application_parameters (GWin32AppInfo *info, + const gchar *exec_line, + GList **objs, + int *argc, + char ***argv, + GError **error) +{ + GList *obj_list = *objs; + GList **stat_obj_list = objs; + const char *p = exec_line; + GString *expanded_exec; + gboolean res; + gchar *a_char; + + expanded_exec = g_string_new (NULL); + res = FALSE; + + while (*p) + { + if (p[0] == '%' && p[1] != '\0') + { + if (expand_macro (p[1], + expanded_exec, + info, stat_obj_list, + objs)) + res = TRUE; + + p++; + } + else + g_string_append_c (expanded_exec, *p); + + p++; + } + + /* No file substitutions */ + if (obj_list == *objs && obj_list != NULL && !res) + { + /* If there is no macro default to %f. This is also what KDE does */ + g_string_append_c (expanded_exec, ' '); + expand_macro ('f', expanded_exec, info, stat_obj_list, objs); + } + + /* Replace '\\' with '/', because g_shell_parse_argv considers them + * to be escape sequences. + */ + for (a_char = expanded_exec->str; + a_char <= &expanded_exec->str[expanded_exec->len]; + a_char++) + { + if (*a_char == '\\') + *a_char = '/'; + } + + res = g_shell_parse_argv (expanded_exec->str, argc, argv, error); + g_string_free (expanded_exec, TRUE); + return res; +} + + +static gchar * +get_appath_for_exe (const gchar *exe_basename) +{ + GWin32RegistryKey *apppath_key = NULL; + GWin32RegistryValueType val_type; + gchar *appath = NULL; + gboolean got_value; + gchar *key_path = g_strdup_printf ("HKEY_LOCAL_MACHINE\\" + "SOFTWARE\\" + "Microsoft\\" + "Windows\\" + "CurrentVersion\\" + "App Paths\\" + "%s", exe_basename); + + apppath_key = g_win32_registry_key_new (key_path, NULL); + g_clear_pointer (&key_path, g_free); + + if (apppath_key == NULL) + return NULL; + + got_value = g_win32_registry_key_get_value (apppath_key, + NULL, + TRUE, + "Path", + &val_type, + (void **) &appath, + NULL, + NULL); + + g_object_unref (apppath_key); + + if (got_value && + val_type == G_WIN32_REGISTRY_VALUE_STR) + return appath; + + g_clear_pointer (&appath, g_free); + + return appath; +} + + +static gboolean +g_win32_app_info_launch_uwp_internal (GWin32AppInfo *info, + gboolean for_files, + IShellItemArray *items, + GWin32AppInfoShellVerb *shverb, + GError **error) +{ + DWORD pid; + IApplicationActivationManager* paam = NULL; + gboolean result = TRUE; + HRESULT hr; + + hr = CoCreateInstance (&CLSID_ApplicationActivationManager, NULL, CLSCTX_INPROC_SERVER, &IID_IApplicationActivationManager, (void **) &paam); + if (FAILED (hr)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to create ApplicationActivationManager: 0x%lx", hr); + return FALSE; + } + + if (items == NULL) + hr = IApplicationActivationManager_ActivateApplication (paam, (const wchar_t *) info->app->canonical_name, NULL, AO_NONE, &pid); + else if (for_files) + hr = IApplicationActivationManager_ActivateForFile (paam, (const wchar_t *) info->app->canonical_name, items, shverb->verb_name, &pid); + else + hr = IApplicationActivationManager_ActivateForProtocol (paam, (const wchar_t *) info->app->canonical_name, items, &pid); + + if (FAILED (hr)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "The app %s failed to launch: 0x%lx", + g_win32_appinfo_application_get_some_name (info->app), hr); + result = FALSE; + } + + IApplicationActivationManager_Release (paam); + + return result; +} + + +static gboolean +g_win32_app_info_launch_internal (GWin32AppInfo *info, + GList *objs, /* non-UWP only */ + gboolean for_files, /* UWP only */ + IShellItemArray *items, /* UWP only */ + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GError **error) +{ + gboolean completed = FALSE; + char **argv, **envp; + int argc; + const gchar *command; + gchar *apppath; + GWin32AppInfoShellVerb *shverb; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (info->app != NULL, FALSE); + + argv = NULL; + shverb = NULL; + + if (!info->app->is_uwp && + info->handler != NULL && + info->handler->verbs->len > 0) + shverb = _verb_idx (info->handler->verbs, 0); + else if (info->app->verbs->len > 0) + shverb = _verb_idx (info->app->verbs, 0); + + if (shverb == NULL) + { + if (info->app->is_uwp || info->handler == NULL) + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + P_("The app ‘%s’ in the application object has no verbs"), + g_win32_appinfo_application_get_some_name (info->app)); + else if (info->handler->verbs->len == 0) + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + P_("The app ‘%s’ and the handler ‘%s’ in the application object have no verbs"), + g_win32_appinfo_application_get_some_name (info->app), + info->handler->handler_id_folded); + + return FALSE; + } + + if (info->app->is_uwp) + return g_win32_app_info_launch_uwp_internal (info, + for_files, + items, + shverb, + error); + + if (launch_context) + envp = g_app_launch_context_get_environment (launch_context); + else + envp = g_get_environ (); + + g_assert (shverb->command_utf8 != NULL); + command = shverb->command_utf8; + apppath = get_appath_for_exe (shverb->executable_basename); + + if (apppath) + { + gchar **p; + gsize p_index; + + for (p = envp, p_index = 0; p[0]; p++, p_index++) + if ((p[0][0] == 'p' || p[0][0] == 'P') && + (p[0][1] == 'a' || p[0][1] == 'A') && + (p[0][2] == 't' || p[0][2] == 'T') && + (p[0][3] == 'h' || p[0][3] == 'H') && + (p[0][4] == '=')) + break; + + if (p[0] == NULL) + { + gchar **new_envp; + new_envp = g_new (char *, g_strv_length (envp) + 2); + new_envp[0] = g_strdup_printf ("PATH=%s", apppath); + + for (p_index = 0; p_index <= g_strv_length (envp); p_index++) + new_envp[1 + p_index] = envp[p_index]; + + g_free (envp); + envp = new_envp; + } + else + { + gchar *p_path; + + p_path = &p[0][5]; + + if (p_path[0] != '\0') + envp[p_index] = g_strdup_printf ("PATH=%s%c%s", + apppath, + G_SEARCHPATH_SEPARATOR, + p_path); + else + envp[p_index] = g_strdup_printf ("PATH=%s", apppath); + + g_free (&p_path[-5]); + } + } + + do + { + GPid pid; + + if (!expand_application_parameters (info, + command, + &objs, + &argc, + &argv, + error)) + goto out; + + if (!g_spawn_async (NULL, + argv, + envp, + spawn_flags, + NULL, + NULL, + &pid, + error)) + goto out; + + if (launch_context != NULL) + { + GVariantBuilder builder; + GVariant *platform_data; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + /* pid handles are never bigger than 2^24 as per + * https://docs.microsoft.com/en-us/windows/win32/sysinfo/kernel-objects, + * so truncating to `int32` is valid. + * The gsize cast is to silence a compiler warning + * about conversion from pointer to integer of + * different size. */ + g_variant_builder_add (&builder, "{sv}", "pid", g_variant_new_int32 ((gsize) pid)); + + platform_data = g_variant_ref_sink (g_variant_builder_end (&builder)); + g_signal_emit_by_name (launch_context, "launched", info, platform_data); + g_variant_unref (platform_data); + } + + g_strfreev (argv); + argv = NULL; + } + while (objs != NULL); + + completed = TRUE; + + out: + g_strfreev (argv); + g_strfreev (envp); + + return completed; +} + +static void +free_file_or_uri (gpointer ptr) +{ + file_or_uri *obj = ptr; + g_free (obj->file); + g_free (obj->uri); + g_free (obj); +} + + +static gboolean +g_win32_app_supports_uris (GWin32AppInfoApplication *app) +{ + gssize num_of_uris_supported; + + if (app == NULL) + return FALSE; + + num_of_uris_supported = (gssize) g_hash_table_size (app->supported_urls); + + if (g_hash_table_lookup (app->supported_urls, "file")) + num_of_uris_supported -= 1; + + return num_of_uris_supported > 0; +} + + +static gboolean +g_win32_app_info_supports_uris (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app == NULL) + return FALSE; + + return g_win32_app_supports_uris (info->app); +} + + +static gboolean +g_win32_app_info_supports_files (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app == NULL) + return FALSE; + + return g_hash_table_size (info->app->supported_exts) > 0; +} + + +static IShellItemArray * +make_item_array (gboolean for_files, + GList *files_or_uris, + GError **error) +{ + ITEMIDLIST **item_ids; + IShellItemArray *items; + GList *p; + gsize count; + gsize i; + HRESULT hr; + + count = g_list_length (files_or_uris); + + items = NULL; + item_ids = g_new (ITEMIDLIST*, count); + + for (i = 0, p = files_or_uris; p != NULL; p = p->next, i++) + { + wchar_t *file_or_uri_utf16; + + if (!for_files) + file_or_uri_utf16 = g_utf8_to_utf16 ((gchar *) p->data, -1, NULL, NULL, error); + else + file_or_uri_utf16 = g_utf8_to_utf16 (g_file_peek_path (G_FILE (p->data)), -1, NULL, NULL, error); + + if (file_or_uri_utf16 == NULL) + break; + + if (for_files) + { + wchar_t *c; + gsize len; + gsize len_tail; + + len = wcslen (file_or_uri_utf16); + /* Filenames *MUST* use single backslashes, else the call + * will fail. First convert all slashes to backslashes, + * then remove duplicates. + */ + for (c = file_or_uri_utf16; for_files && *c != 0; c++) + { + if (*c == L'/') + *c = L'\\'; + } + for (len_tail = 0, c = &file_or_uri_utf16[len - 1]; + for_files && c > file_or_uri_utf16; + c--, len_tail++) + { + if (c[0] != L'\\' || c[-1] != L'\\') + continue; + + memmove (&c[-1], &c[0], len_tail * sizeof (wchar_t)); + } + } + + hr = SHParseDisplayName (file_or_uri_utf16, NULL, &item_ids[i], 0, NULL); + g_free (file_or_uri_utf16); + + if (FAILED (hr)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "File or URI `%S' cannot be parsed by SHParseDisplayName: 0x%lx", file_or_uri_utf16, hr); + break; + } + } + + if (i == count) + { + hr = SHCreateShellItemArrayFromIDLists (count, (const ITEMIDLIST **) item_ids, &items); + if (FAILED (hr)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "SHCreateShellItemArrayFromIDLists() failed: 0x%lx", hr); + items = NULL; + } + } + + count = i; + + for (i = 0; i < count; i++) + CoTaskMemFree (item_ids[i]); + + g_free (item_ids); + + return items; +} + + +static gboolean +g_win32_app_info_launch_uris (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GError **error) +{ + gboolean res = FALSE; + gboolean do_files; + GList *objs; + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app != NULL && info->app->is_uwp) + { + IShellItemArray *items = NULL; + + if (uris) + { + items = make_item_array (FALSE, uris, error); + if (items == NULL) + return res; + } + + res = g_win32_app_info_launch_internal (info, NULL, FALSE, items, launch_context, 0, error); + + if (items != NULL) + IShellItemArray_Release (items); + + return res; + } + + do_files = g_win32_app_info_supports_files (appinfo); + + objs = NULL; + while (uris) + { + file_or_uri *obj; + obj = g_new0 (file_or_uri, 1); + + if (do_files) + { + GFile *file; + gchar *path; + + file = g_file_new_for_uri (uris->data); + path = g_file_get_path (file); + obj->file = path; + g_object_unref (file); + } + + obj->uri = g_strdup (uris->data); + + objs = g_list_prepend (objs, obj); + uris = uris->next; + } + + objs = g_list_reverse (objs); + + res = g_win32_app_info_launch_internal (info, + objs, + FALSE, + NULL, + launch_context, + G_SPAWN_SEARCH_PATH, + error); + + g_list_free_full (objs, free_file_or_uri); + + return res; +} + +static gboolean +g_win32_app_info_should_show (GAppInfo *appinfo) +{ + /* FIXME: This is a placeholder implementation to avoid crashes + * for now. It can be made more specific to @appinfo in future. */ + + return TRUE; +} + +static gboolean +g_win32_app_info_launch (GAppInfo *appinfo, + GList *files, + GAppLaunchContext *launch_context, + GError **error) +{ + gboolean res = FALSE; + gboolean do_uris; + GList *objs; + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + if (info->app != NULL && info->app->is_uwp) + { + IShellItemArray *items = NULL; + + if (files) + { + items = make_item_array (TRUE, files, error); + if (items == NULL) + return res; + } + + res = g_win32_app_info_launch_internal (info, NULL, TRUE, items, launch_context, 0, error); + + if (items != NULL) + IShellItemArray_Release (items); + + return res; + } + + do_uris = g_win32_app_info_supports_uris (appinfo); + + objs = NULL; + while (files) + { + file_or_uri *obj; + obj = g_new0 (file_or_uri, 1); + obj->file = g_file_get_path (G_FILE (files->data)); + + if (do_uris) + obj->uri = g_file_get_uri (G_FILE (files->data)); + + objs = g_list_prepend (objs, obj); + files = files->next; + } + + objs = g_list_reverse (objs); + + res = g_win32_app_info_launch_internal (info, + objs, + TRUE, + NULL, + launch_context, + G_SPAWN_SEARCH_PATH, + error); + + g_list_free_full (objs, free_file_or_uri); + + return res; +} + +static const char ** +g_win32_app_info_get_supported_types (GAppInfo *appinfo) +{ + GWin32AppInfo *info = G_WIN32_APP_INFO (appinfo); + + return (const char**) info->supported_types; +} + +GAppInfo * +g_app_info_create_from_commandline (const char *commandline, + const char *application_name, + GAppInfoCreateFlags flags, + GError **error) +{ + GWin32AppInfo *info; + GWin32AppInfoApplication *app; + gunichar2 *app_command; + + g_return_val_if_fail (commandline, NULL); + + app_command = g_utf8_to_utf16 (commandline, -1, NULL, NULL, NULL); + + if (app_command == NULL) + return NULL; + + info = g_object_new (G_TYPE_WIN32_APP_INFO, NULL); + app = g_object_new (G_TYPE_WIN32_APPINFO_APPLICATION, NULL); + + app->no_open_with = FALSE; + app->user_specific = FALSE; + app->default_app = FALSE; + + if (application_name) + { + app->canonical_name = g_utf8_to_utf16 (application_name, + -1, + NULL, + NULL, + NULL); + app->canonical_name_u8 = g_strdup (application_name); + app->canonical_name_folded = g_utf8_casefold (application_name, -1); + } + + app_add_verb (app, + app, + L"open", + app_command, + commandline, + "open", + TRUE, + FALSE); + + g_clear_pointer (&app_command, g_free); + info->app = app; + info->handler = NULL; + + return G_APP_INFO (info); +} + +/* GAppInfo interface init */ + +static void +g_win32_app_info_iface_init (GAppInfoIface *iface) +{ + iface->dup = g_win32_app_info_dup; + iface->equal = g_win32_app_info_equal; + iface->get_id = g_win32_app_info_get_id; + iface->get_name = g_win32_app_info_get_name; + iface->get_description = g_win32_app_info_get_description; + iface->get_executable = g_win32_app_info_get_executable; + iface->get_icon = g_win32_app_info_get_icon; + iface->launch = g_win32_app_info_launch; + iface->supports_uris = g_win32_app_info_supports_uris; + iface->supports_files = g_win32_app_info_supports_files; + iface->launch_uris = g_win32_app_info_launch_uris; + iface->should_show = g_win32_app_info_should_show; +/* iface->set_as_default_for_type = g_win32_app_info_set_as_default_for_type;*/ +/* iface->set_as_default_for_extension = g_win32_app_info_set_as_default_for_extension;*/ +/* iface->add_supports_type = g_win32_app_info_add_supports_type;*/ +/* iface->can_remove_supports_type = g_win32_app_info_can_remove_supports_type;*/ +/* iface->remove_supports_type = g_win32_app_info_remove_supports_type;*/ +/* iface->can_delete = g_win32_app_info_can_delete;*/ +/* iface->do_delete = g_win32_app_info_delete;*/ + iface->get_commandline = g_win32_app_info_get_commandline; + iface->get_display_name = g_win32_app_info_get_display_name; +/* iface->set_as_last_used_for_type = g_win32_app_info_set_as_last_used_for_type;*/ + iface->get_supported_types = g_win32_app_info_get_supported_types; +} + +GAppInfo * +g_app_info_get_default_for_uri_scheme (const char *uri_scheme) +{ + GWin32AppInfoURLSchema *scheme = NULL; + char *scheme_down; + GAppInfo *result; + GWin32AppInfoShellVerb *shverb; + + scheme_down = g_utf8_casefold (uri_scheme, -1); + + if (!scheme_down) + return NULL; + + if (strcmp (scheme_down, "file") == 0) + { + g_free (scheme_down); + + return NULL; + } + + gio_win32_appinfo_init (TRUE); + g_mutex_lock (&gio_win32_appinfo_mutex); + + g_set_object (&scheme, g_hash_table_lookup (urls, scheme_down)); + g_free (scheme_down); + + g_mutex_unlock (&gio_win32_appinfo_mutex); + + result = NULL; + + if (scheme != NULL && + scheme->chosen_handler != NULL && + scheme->chosen_handler->verbs->len > 0 && + (shverb = _verb_idx (scheme->chosen_handler->verbs, 0))->app != NULL) + result = g_win32_app_info_new_from_app (shverb->app, + scheme->chosen_handler); + + g_clear_object (&scheme); + + return result; +} + +GAppInfo * +g_app_info_get_default_for_type (const char *content_type, + gboolean must_support_uris) +{ + GWin32AppInfoFileExtension *ext = NULL; + char *ext_down; + GAppInfo *result; + GWin32AppInfoShellVerb *shverb; + + ext_down = g_utf8_casefold (content_type, -1); + + if (!ext_down) + return NULL; + + gio_win32_appinfo_init (TRUE); + g_mutex_lock (&gio_win32_appinfo_mutex); + + /* Assuming that "content_type" is a file extension, not a MIME type */ + g_set_object (&ext, g_hash_table_lookup (extensions, ext_down)); + g_free (ext_down); + + g_mutex_unlock (&gio_win32_appinfo_mutex); + + if (ext == NULL) + return NULL; + + result = NULL; + + if (ext->chosen_handler != NULL && + ext->chosen_handler->verbs->len > 0 && + (shverb = _verb_idx (ext->chosen_handler->verbs, 0))->app != NULL && + (!must_support_uris || + g_win32_app_supports_uris (shverb->app))) + result = g_win32_app_info_new_from_app (shverb->app, + ext->chosen_handler); + else + { + GHashTableIter iter; + GWin32AppInfoHandler *handler; + + g_hash_table_iter_init (&iter, ext->handlers); + + while (result == NULL && + g_hash_table_iter_next (&iter, NULL, (gpointer *) &handler)) + { + if (handler->verbs->len == 0) + continue; + + shverb = _verb_idx (handler->verbs, 0); + + if (shverb->app && + (!must_support_uris || + g_win32_app_supports_uris (shverb->app))) + result = g_win32_app_info_new_from_app (shverb->app, handler); + } + } + + g_clear_object (&ext); + + return result; +} + +GList * +g_app_info_get_all (void) +{ + GHashTableIter iter; + gpointer value; + GList *infos; + GList *apps; + GList *apps_i; + + gio_win32_appinfo_init (TRUE); + g_mutex_lock (&gio_win32_appinfo_mutex); + + apps = NULL; + g_hash_table_iter_init (&iter, apps_by_id); + while (g_hash_table_iter_next (&iter, NULL, &value)) + apps = g_list_prepend (apps, g_object_ref (G_OBJECT (value))); + + g_mutex_unlock (&gio_win32_appinfo_mutex); + + infos = NULL; + for (apps_i = apps; apps_i; apps_i = apps_i->next) + infos = g_list_prepend (infos, + g_win32_app_info_new_from_app (apps_i->data, NULL)); + + g_list_free_full (apps, g_object_unref); + + return infos; +} + +GList * +g_app_info_get_all_for_type (const char *content_type) +{ + GWin32AppInfoFileExtension *ext = NULL; + char *ext_down; + GWin32AppInfoHandler *handler; + GHashTableIter iter; + GHashTable *apps = NULL; + GList *result; + GWin32AppInfoShellVerb *shverb; + + ext_down = g_utf8_casefold (content_type, -1); + + if (!ext_down) + return NULL; + + gio_win32_appinfo_init (TRUE); + g_mutex_lock (&gio_win32_appinfo_mutex); + + /* Assuming that "content_type" is a file extension, not a MIME type */ + g_set_object (&ext, g_hash_table_lookup (extensions, ext_down)); + g_free (ext_down); + + g_mutex_unlock (&gio_win32_appinfo_mutex); + + if (ext == NULL) + return NULL; + + result = NULL; + /* Used as a set to ensure uniqueness */ + apps = g_hash_table_new (g_direct_hash, g_direct_equal); + + if (ext->chosen_handler != NULL && + ext->chosen_handler->verbs->len > 0 && + (shverb = _verb_idx (ext->chosen_handler->verbs, 0))->app != NULL) + { + g_hash_table_add (apps, shverb->app); + result = g_list_prepend (result, + g_win32_app_info_new_from_app (shverb->app, + ext->chosen_handler)); + } + + g_hash_table_iter_init (&iter, ext->handlers); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &handler)) + { + gsize vi; + + for (vi = 0; vi < handler->verbs->len; vi++) + { + shverb = _verb_idx (handler->verbs, vi); + + if (shverb->app == NULL || + g_hash_table_contains (apps, shverb->app)) + continue; + + g_hash_table_add (apps, shverb->app); + result = g_list_prepend (result, + g_win32_app_info_new_from_app (shverb->app, + handler)); + } + } + + g_clear_object (&ext); + result = g_list_reverse (result); + g_hash_table_unref (apps); + + return result; +} + +GList * +g_app_info_get_fallback_for_type (const gchar *content_type) +{ + /* TODO: fix this once gcontenttype support is improved */ + return g_app_info_get_all_for_type (content_type); +} + +GList * +g_app_info_get_recommended_for_type (const gchar *content_type) +{ + /* TODO: fix this once gcontenttype support is improved */ + return g_app_info_get_all_for_type (content_type); +} + +void +g_app_info_reset_type_associations (const char *content_type) +{ + /* nothing to do */ +} diff --git a/gio/gwin32appinfo.h b/gio/gwin32appinfo.h new file mode 100644 index 0000000..5d463ca --- /dev/null +++ b/gio/gwin32appinfo.h @@ -0,0 +1,52 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2014 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Alexander Larsson + * РуÑлан Ижбулатов + */ + +#ifndef __G_WIN32_APP_INFO_H__ +#define __G_WIN32_APP_INFO_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_WIN32_APP_INFO (g_win32_app_info_get_type ()) +#define G_WIN32_APP_INFO(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_APP_INFO, GWin32AppInfo)) +#define G_WIN32_APP_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_APP_INFO, GWin32AppInfoClass)) +#define G_IS_WIN32_APP_INFO(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_APP_INFO)) +#define G_IS_WIN32_APP_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_APP_INFO)) +#define G_WIN32_APP_INFO_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WIN32_APP_INFO, GWin32AppInfoClass)) + +typedef struct _GWin32AppInfo GWin32AppInfo; +typedef struct _GWin32AppInfoClass GWin32AppInfoClass; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GWin32AppInfo, g_object_unref) + +struct _GWin32AppInfoClass +{ + GObjectClass parent_class; +}; + +GType g_win32_app_info_get_type (void) G_GNUC_CONST; + +G_END_DECLS + + +#endif /* __G_WIN32_APP_INFO_H__ */ diff --git a/gio/gwin32file-sync-stream.c b/gio/gwin32file-sync-stream.c new file mode 100755 index 0000000..bc3b606 --- /dev/null +++ b/gio/gwin32file-sync-stream.c @@ -0,0 +1,508 @@ +/* gwin32file-sync-stream.c - a simple IStream implementation + * + * Copyright 2020 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +/* A COM object that implements an IStream backed by a file HANDLE. + * Works just like `SHCreateStreamOnFileEx()`, but does not + * support locking, and doesn't force us to link to libshlwapi. + * Only supports synchronous access. + */ +#include "config.h" +#define COBJMACROS +#define INITGUID +#include + +#include "gwin32file-sync-stream.h" + +static HRESULT STDMETHODCALLTYPE _file_sync_stream_query_interface (IStream *self_ptr, + REFIID ref_interface_guid, + LPVOID *output_object_ptr); +static ULONG STDMETHODCALLTYPE _file_sync_stream_release (IStream *self_ptr); +static ULONG STDMETHODCALLTYPE _file_sync_stream_add_ref (IStream *self_ptr); + +static HRESULT STDMETHODCALLTYPE _file_sync_stream_read (IStream *self_ptr, + void *output_data, + ULONG bytes_to_read, + ULONG *output_bytes_read); + +static HRESULT STDMETHODCALLTYPE _file_sync_stream_write (IStream *self_ptr, + const void *data, + ULONG bytes_to_write, + ULONG *output_bytes_written); + + +static HRESULT STDMETHODCALLTYPE _file_sync_stream_clone (IStream *self_ptr, + IStream **output_clone_ptr); +static HRESULT STDMETHODCALLTYPE _file_sync_stream_commit (IStream *self_ptr, + DWORD commit_flags); +static HRESULT STDMETHODCALLTYPE _file_sync_stream_copy_to (IStream *self_ptr, + IStream *output_stream, + ULARGE_INTEGER bytes_to_copy, + ULARGE_INTEGER *output_bytes_read, + ULARGE_INTEGER *output_bytes_written); +static HRESULT STDMETHODCALLTYPE _file_sync_stream_lock_region (IStream *self_ptr, + ULARGE_INTEGER lock_offset, + ULARGE_INTEGER lock_bytes, + DWORD lock_type); +static HRESULT STDMETHODCALLTYPE _file_sync_stream_revert (IStream *self_ptr); +static HRESULT STDMETHODCALLTYPE _file_sync_stream_seek (IStream *self_ptr, + LARGE_INTEGER move_distance, + DWORD origin, + ULARGE_INTEGER *output_new_position); +static HRESULT STDMETHODCALLTYPE _file_sync_stream_set_size (IStream *self_ptr, + ULARGE_INTEGER new_size); +static HRESULT STDMETHODCALLTYPE _file_sync_stream_stat (IStream *self_ptr, + STATSTG *output_stat, + DWORD flags); +static HRESULT STDMETHODCALLTYPE _file_sync_stream_unlock_region (IStream *self_ptr, + ULARGE_INTEGER lock_offset, + ULARGE_INTEGER lock_bytes, + DWORD lock_type); + +static void _file_sync_stream_free (GWin32FileSyncStream *self); + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_query_interface (IStream *self_ptr, + REFIID ref_interface_guid, + LPVOID *output_object_ptr) +{ + *output_object_ptr = NULL; + + if (IsEqualGUID (ref_interface_guid, &IID_IUnknown)) + { + IUnknown_AddRef ((IUnknown *) self_ptr); + *output_object_ptr = self_ptr; + return S_OK; + } + else if (IsEqualGUID (ref_interface_guid, &IID_IStream)) + { + IStream_AddRef (self_ptr); + *output_object_ptr = self_ptr; + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE +_file_sync_stream_add_ref (IStream *self_ptr) +{ + GWin32FileSyncStream *self = (GWin32FileSyncStream *) self_ptr; + + return ++self->ref_count; +} + +static ULONG STDMETHODCALLTYPE +_file_sync_stream_release (IStream *self_ptr) +{ + GWin32FileSyncStream *self = (GWin32FileSyncStream *) self_ptr; + + int ref_count = --self->ref_count; + + if (ref_count == 0) + _file_sync_stream_free (self); + + return ref_count; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_read (IStream *self_ptr, + void *output_data, + ULONG bytes_to_read, + ULONG *output_bytes_read) +{ + GWin32FileSyncStream *self = (GWin32FileSyncStream *) self_ptr; + DWORD bytes_read; + + if (!ReadFile (self->file_handle, output_data, bytes_to_read, &bytes_read, NULL)) + { + DWORD error = GetLastError (); + return __HRESULT_FROM_WIN32 (error); + } + + if (output_bytes_read) + *output_bytes_read = bytes_read; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_write (IStream *self_ptr, + const void *data, + ULONG bytes_to_write, + ULONG *output_bytes_written) +{ + GWin32FileSyncStream *self = (GWin32FileSyncStream *) self_ptr; + DWORD bytes_written; + + if (!WriteFile (self->file_handle, data, bytes_to_write, &bytes_written, NULL)) + { + DWORD error = GetLastError (); + return __HRESULT_FROM_WIN32 (error); + } + + if (output_bytes_written) + *output_bytes_written = bytes_written; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_seek (IStream *self_ptr, + LARGE_INTEGER move_distance, + DWORD origin, + ULARGE_INTEGER *output_new_position) +{ + GWin32FileSyncStream *self = (GWin32FileSyncStream *) self_ptr; + LARGE_INTEGER new_position; + DWORD move_method; + + switch (origin) + { + case STREAM_SEEK_SET: + move_method = FILE_BEGIN; + break; + case STREAM_SEEK_CUR: + move_method = FILE_CURRENT; + break; + case STREAM_SEEK_END: + move_method = FILE_END; + break; + default: + return E_INVALIDARG; + } + + if (!SetFilePointerEx (self->file_handle, move_distance, &new_position, move_method)) + { + DWORD error = GetLastError (); + return __HRESULT_FROM_WIN32 (error); + } + + (*output_new_position).QuadPart = new_position.QuadPart; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_set_size (IStream *self_ptr, + ULARGE_INTEGER new_size) +{ + GWin32FileSyncStream *self = (GWin32FileSyncStream *) self_ptr; + FILE_END_OF_FILE_INFO info; + + info.EndOfFile.QuadPart = new_size.QuadPart; + + if (SetFileInformationByHandle (self->file_handle, FileEndOfFileInfo, &info, sizeof (info))) + { + DWORD error = GetLastError (); + return __HRESULT_FROM_WIN32 (error); + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_copy_to (IStream *self_ptr, + IStream *output_stream, + ULARGE_INTEGER bytes_to_copy, + ULARGE_INTEGER *output_bytes_read, + ULARGE_INTEGER *output_bytes_written) +{ + ULARGE_INTEGER counter; + ULARGE_INTEGER written_counter; + ULARGE_INTEGER read_counter; + + counter.QuadPart = bytes_to_copy.QuadPart; + written_counter.QuadPart = 0; + read_counter.QuadPart = 0; + + while (counter.QuadPart > 0) + { + HRESULT hr; + ULONG bytes_read; + ULONG bytes_written; + ULONG bytes_index; +#define _INTERNAL_BUFSIZE 1024 + BYTE buffer[_INTERNAL_BUFSIZE]; +#undef _INTERNAL_BUFSIZE + ULONG buffer_size = sizeof (buffer); + ULONG to_read = buffer_size; + + if (counter.QuadPart < buffer_size) + to_read = (ULONG) counter.QuadPart; + + /* Because MS SDK has a function IStream_Read() with 3 arguments */ + hr = self_ptr->lpVtbl->Read (self_ptr, buffer, to_read, &bytes_read); + if (!SUCCEEDED (hr)) + return hr; + + read_counter.QuadPart += bytes_read; + + if (bytes_read == 0) + break; + + bytes_index = 0; + + while (bytes_index < bytes_read) + { + /* Because MS SDK has a function IStream_Write() with 3 arguments */ + hr = output_stream->lpVtbl->Write (output_stream, &buffer[bytes_index], bytes_read - bytes_index, &bytes_written); + if (!SUCCEEDED (hr)) + return hr; + + if (bytes_written == 0) + return __HRESULT_FROM_WIN32 (ERROR_WRITE_FAULT); + + bytes_index += bytes_written; + written_counter.QuadPart += bytes_written; + } + } + + if (output_bytes_read) + output_bytes_read->QuadPart = read_counter.QuadPart; + if (output_bytes_written) + output_bytes_written->QuadPart = written_counter.QuadPart; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_commit (IStream *self_ptr, + DWORD commit_flags) +{ + GWin32FileSyncStream *self = (GWin32FileSyncStream *) self_ptr; + + if (!FlushFileBuffers (self->file_handle)) + { + DWORD error = GetLastError (); + return __HRESULT_FROM_WIN32 (error); + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_revert (IStream *self_ptr) +{ + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_lock_region (IStream *self_ptr, + ULARGE_INTEGER lock_offset, + ULARGE_INTEGER lock_bytes, + DWORD lock_type) +{ + return STG_E_INVALIDFUNCTION; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_unlock_region (IStream *self_ptr, + ULARGE_INTEGER lock_offset, + ULARGE_INTEGER lock_bytes, + DWORD lock_type) +{ + return STG_E_INVALIDFUNCTION; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_stat (IStream *self_ptr, + STATSTG *output_stat, + DWORD flags) +{ + GWin32FileSyncStream *self = (GWin32FileSyncStream *) self_ptr; + BOOL get_name = FALSE; + FILE_BASIC_INFO bi; + FILE_STANDARD_INFO si; + + if (output_stat == NULL) + return STG_E_INVALIDPOINTER; + + switch (flags) + { + case STATFLAG_DEFAULT: + get_name = TRUE; + break; + case STATFLAG_NONAME: + get_name = FALSE; + break; + default: + return STG_E_INVALIDFLAG; + } + + if (!GetFileInformationByHandleEx (self->file_handle, FileBasicInfo, &bi, sizeof (bi)) || + !GetFileInformationByHandleEx (self->file_handle, FileStandardInfo, &si, sizeof (si))) + { + DWORD error = GetLastError (); + return __HRESULT_FROM_WIN32 (error); + } + + output_stat->type = STGTY_STREAM; + output_stat->mtime.dwLowDateTime = bi.LastWriteTime.LowPart; + output_stat->mtime.dwHighDateTime = bi.LastWriteTime.HighPart; + output_stat->ctime.dwLowDateTime = bi.CreationTime.LowPart; + output_stat->ctime.dwHighDateTime = bi.CreationTime.HighPart; + output_stat->atime.dwLowDateTime = bi.LastAccessTime.LowPart; + output_stat->atime.dwHighDateTime = bi.LastAccessTime.HighPart; + output_stat->grfLocksSupported = 0; + memset (&output_stat->clsid, 0, sizeof (CLSID)); + output_stat->grfStateBits = 0; + output_stat->reserved = 0; + output_stat->cbSize.QuadPart = si.EndOfFile.QuadPart; + output_stat->grfMode = self->stgm_mode; + + if (get_name) + { + DWORD tries; + wchar_t *buffer; + + /* Nothing in the documentation guarantees that the name + * won't change between two invocations (one - to get the + * buffer size, the other - to fill the buffer). + * Re-try up to 5 times in case the required buffer size + * doesn't match. + */ + for (tries = 5; tries > 0; tries--) + { + DWORD buffer_size; + DWORD buffer_size2; + DWORD error; + + buffer_size = GetFinalPathNameByHandleW (self->file_handle, NULL, 0, 0); + + if (buffer_size == 0) + { + DWORD error = GetLastError (); + return __HRESULT_FROM_WIN32 (error); + } + + buffer = CoTaskMemAlloc (buffer_size); + buffer[buffer_size - 1] = 0; + buffer_size2 = GetFinalPathNameByHandleW (self->file_handle, buffer, buffer_size, 0); + + if (buffer_size2 < buffer_size) + break; + + error = GetLastError (); + CoTaskMemFree (buffer); + if (buffer_size2 == 0) + return __HRESULT_FROM_WIN32 (error); + } + + if (tries == 0) + return __HRESULT_FROM_WIN32 (ERROR_BAD_LENGTH); + + output_stat->pwcsName = buffer; + } + else + output_stat->pwcsName = NULL; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +_file_sync_stream_clone (IStream *self_ptr, + IStream **output_clone_ptr) +{ + return E_NOTIMPL; +} + +static IStreamVtbl _file_sync_stream_vtbl = { + _file_sync_stream_query_interface, + _file_sync_stream_add_ref, + _file_sync_stream_release, + _file_sync_stream_read, + _file_sync_stream_write, + _file_sync_stream_seek, + _file_sync_stream_set_size, + _file_sync_stream_copy_to, + _file_sync_stream_commit, + _file_sync_stream_revert, + _file_sync_stream_lock_region, + _file_sync_stream_unlock_region, + _file_sync_stream_stat, + _file_sync_stream_clone, +}; + +static void +_file_sync_stream_free (GWin32FileSyncStream *self) +{ + if (self->owns_handle) + CloseHandle (self->file_handle); + + g_free (self); +} + +/** + * g_win32_file_sync_stream_new: + * @handle: a Win32 HANDLE for a file. + * @owns_handle: %TRUE if newly-created stream owns the handle + * (and closes it when destroyed) + * @stgm_mode: a combination of [STGM constants](https://docs.microsoft.com/en-us/windows/win32/stg/stgm-constants) + * that specify the mode with which the stream + * is opened. + * @output_hresult: (out) (optional): a HRESULT from the internal COM calls. + * Will be `S_OK` on success. + * + * Creates an IStream object backed by a HANDLE. + * + * @stgm_mode should match the mode of the @handle, otherwise the stream might + * attempt to perform operations that the @handle does not allow. The implementation + * itself ignores these flags completely, they are only used to report + * the mode of the stream to third parties. + * + * The stream only does synchronous access and will never return `E_PENDING` on I/O. + * + * The returned stream object should be treated just like any other + * COM object, and released via `IUnknown_Release()`. + * its elements have been unreffed with g_object_unref(). + * + * Returns: (nullable) (transfer full): a new IStream object on success, %NULL on failure. + **/ +IStream * +g_win32_file_sync_stream_new (HANDLE file_handle, + gboolean owns_handle, + DWORD stgm_mode, + HRESULT *output_hresult) +{ + GWin32FileSyncStream *new_stream; + IStream *result; + HRESULT hr; + + new_stream = g_new0 (GWin32FileSyncStream, 1); + new_stream->self.lpVtbl = &_file_sync_stream_vtbl; + + hr = IUnknown_QueryInterface ((IUnknown *) new_stream, &IID_IStream, (void **) &result); + if (!SUCCEEDED (hr)) + { + g_free (new_stream); + + if (output_hresult) + *output_hresult = hr; + + return NULL; + } + + new_stream->stgm_mode = stgm_mode; + new_stream->file_handle = file_handle; + new_stream->owns_handle = owns_handle; + + if (output_hresult) + *output_hresult = S_OK; + + return result; +} diff --git a/gio/gwin32file-sync-stream.h b/gio/gwin32file-sync-stream.h new file mode 100755 index 0000000..8e7f5fd --- /dev/null +++ b/gio/gwin32file-sync-stream.h @@ -0,0 +1,44 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2020 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ +#ifndef __G_WIN32_FILE_SYNC_STREAM_H__ +#define __G_WIN32_FILE_SYNC_STREAM_H__ + +#include + +#ifdef G_PLATFORM_WIN32 + +typedef struct _GWin32FileSyncStream GWin32FileSyncStream; + +struct _GWin32FileSyncStream +{ + IStream self; + ULONG ref_count; + HANDLE file_handle; + gboolean owns_handle; + DWORD stgm_mode; +}; + +IStream *g_win32_file_sync_stream_new (HANDLE file_handle, + gboolean owns_handle, + DWORD stgm_mode, + HRESULT *output_hresult); + +#endif /* G_PLATFORM_WIN32 */ + +#endif /* __G_WIN32_FILE_SYNC_STREAM_H__ */ \ No newline at end of file diff --git a/gio/gwin32inputstream.c b/gio/gwin32inputstream.c new file mode 100644 index 0000000..5649af1 --- /dev/null +++ b/gio/gwin32inputstream.c @@ -0,0 +1,400 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#include "config.h" + +#include + +#include + +#include +#include "gioerror.h" +#include "gwin32inputstream.h" +#include "giowin32-priv.h" +#include "gcancellable.h" +#include "gasynchelper.h" +#include "glibintl.h" + +/** + * SECTION:gwin32inputstream + * @short_description: Streaming input operations for Windows file handles + * @include: gio/gwin32inputstream.h + * @see_also: #GInputStream + * + * #GWin32InputStream implements #GInputStream for reading from a + * Windows file handle. + * + * Note that `` belongs to the Windows-specific GIO + * interfaces, thus you have to use the `gio-windows-2.0.pc` pkg-config file + * when using it. + */ + +struct _GWin32InputStreamPrivate { + HANDLE handle; + gboolean close_handle; + gint fd; +}; + +enum { + PROP_0, + PROP_HANDLE, + PROP_CLOSE_HANDLE, + LAST_PROP +}; + +static GParamSpec *props[LAST_PROP]; + +G_DEFINE_TYPE_WITH_PRIVATE (GWin32InputStream, g_win32_input_stream, G_TYPE_INPUT_STREAM) + +static void +g_win32_input_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GWin32InputStream *win32_stream; + + win32_stream = G_WIN32_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_HANDLE: + win32_stream->priv->handle = g_value_get_pointer (value); + break; + case PROP_CLOSE_HANDLE: + win32_stream->priv->close_handle = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_win32_input_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GWin32InputStream *win32_stream; + + win32_stream = G_WIN32_INPUT_STREAM (object); + + switch (prop_id) + { + case PROP_HANDLE: + g_value_set_pointer (value, win32_stream->priv->handle); + break; + case PROP_CLOSE_HANDLE: + g_value_set_boolean (value, win32_stream->priv->close_handle); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static gssize +g_win32_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GWin32InputStream *win32_stream; + BOOL res; + DWORD nbytes, nread; + OVERLAPPED overlap = { 0, }; + gssize retval = -1; + + win32_stream = G_WIN32_INPUT_STREAM (stream); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (count > G_MAXINT) + nbytes = G_MAXINT; + else + nbytes = count; + + overlap.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + g_return_val_if_fail (overlap.hEvent != NULL, -1); + + res = ReadFile (win32_stream->priv->handle, buffer, nbytes, &nread, &overlap); + if (res) + retval = nread; + else + { + int errsv = GetLastError (); + + if (errsv == ERROR_IO_PENDING && + _g_win32_overlap_wait_result (win32_stream->priv->handle, + &overlap, &nread, cancellable)) + { + retval = nread; + goto end; + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto end; + + errsv = GetLastError (); + if (errsv == ERROR_MORE_DATA) + { + /* If a named pipe is being read in message mode and the + * next message is longer than the nNumberOfBytesToRead + * parameter specifies, ReadFile returns FALSE and + * GetLastError returns ERROR_MORE_DATA */ + retval = nread; + goto end; + } + else if (errsv == ERROR_HANDLE_EOF || + errsv == ERROR_BROKEN_PIPE) + { + /* TODO: the other end of a pipe may call the WriteFile + * function with nNumberOfBytesToWrite set to zero. In this + * case, it's not possible for the caller to know if it's + * broken pipe or a read of 0. Perhaps we should add a + * is_broken flag for this win32 case.. */ + retval = 0; + } + else + { + gchar *emsg; + + emsg = g_win32_error_message (errsv); + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (errsv), + _("Error reading from handle: %s"), + emsg); + g_free (emsg); + } + } + +end: + CloseHandle (overlap.hEvent); + return retval; +} + +static gboolean +g_win32_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GWin32InputStream *win32_stream; + BOOL res; + + win32_stream = G_WIN32_INPUT_STREAM (stream); + + if (!win32_stream->priv->close_handle) + return TRUE; + + if (win32_stream->priv->fd != -1) + { + if (close (win32_stream->priv->fd) < 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error closing file descriptor: %s"), + g_strerror (errsv)); + return FALSE; + } + } + else + { + res = CloseHandle (win32_stream->priv->handle); + if (!res) + { + int errsv = GetLastError (); + gchar *emsg = g_win32_error_message (errsv); + + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (errsv), + _("Error closing handle: %s"), + emsg); + g_free (emsg); + return FALSE; + } + } + + return TRUE; +} + +static void +g_win32_input_stream_class_init (GWin32InputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass); + + gobject_class->get_property = g_win32_input_stream_get_property; + gobject_class->set_property = g_win32_input_stream_set_property; + + stream_class->read_fn = g_win32_input_stream_read; + stream_class->close_fn = g_win32_input_stream_close; + + /** + * GWin32InputStream:handle: + * + * The handle that the stream reads from. + * + * Since: 2.26 + */ + props[PROP_HANDLE] = + g_param_spec_pointer ("handle", + P_("File handle"), + P_("The file handle to read from"), + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + /** + * GWin32InputStream:close-handle: + * + * Whether to close the file handle when the stream is closed. + * + * Since: 2.26 + */ + props[PROP_CLOSE_HANDLE] = + g_param_spec_boolean ("close-handle", + P_("Close file handle"), + P_("Whether to close the file handle when the stream is closed"), + TRUE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, LAST_PROP, props); +} + +static void +g_win32_input_stream_init (GWin32InputStream *win32_stream) +{ + win32_stream->priv = g_win32_input_stream_get_instance_private (win32_stream); + win32_stream->priv->handle = NULL; + win32_stream->priv->close_handle = TRUE; + win32_stream->priv->fd = -1; +} + +/** + * g_win32_input_stream_new: + * @handle: a Win32 file handle + * @close_handle: %TRUE to close the handle when done + * + * Creates a new #GWin32InputStream for the given @handle. + * + * If @close_handle is %TRUE, the handle will be closed + * when the stream is closed. + * + * Note that "handle" here means a Win32 HANDLE, not a "file descriptor" + * as used in the Windows C libraries. + * + * Returns: a new #GWin32InputStream + **/ +GInputStream * +g_win32_input_stream_new (void *handle, + gboolean close_handle) +{ + GWin32InputStream *stream; + + g_return_val_if_fail (handle != NULL, NULL); + + stream = g_object_new (G_TYPE_WIN32_INPUT_STREAM, + "handle", handle, + "close-handle", close_handle, + NULL); + + return G_INPUT_STREAM (stream); +} + +/** + * g_win32_input_stream_set_close_handle: + * @stream: a #GWin32InputStream + * @close_handle: %TRUE to close the handle when done + * + * Sets whether the handle of @stream shall be closed + * when the stream is closed. + * + * Since: 2.26 + */ +void +g_win32_input_stream_set_close_handle (GWin32InputStream *stream, + gboolean close_handle) +{ + g_return_if_fail (G_IS_WIN32_INPUT_STREAM (stream)); + + close_handle = close_handle != FALSE; + if (stream->priv->close_handle != close_handle) + { + stream->priv->close_handle = close_handle; + g_object_notify (G_OBJECT (stream), "close-handle"); + } +} + +/** + * g_win32_input_stream_get_close_handle: + * @stream: a #GWin32InputStream + * + * Returns whether the handle of @stream will be + * closed when the stream is closed. + * + * Returns: %TRUE if the handle is closed when done + * + * Since: 2.26 + */ +gboolean +g_win32_input_stream_get_close_handle (GWin32InputStream *stream) +{ + g_return_val_if_fail (G_IS_WIN32_INPUT_STREAM (stream), FALSE); + + return stream->priv->close_handle; +} + +/** + * g_win32_input_stream_get_handle: + * @stream: a #GWin32InputStream + * + * Return the Windows file handle that the stream reads from. + * + * Returns: The file handle of @stream + * + * Since: 2.26 + */ +void * +g_win32_input_stream_get_handle (GWin32InputStream *stream) +{ + g_return_val_if_fail (G_IS_WIN32_INPUT_STREAM (stream), NULL); + + return stream->priv->handle; +} + +GInputStream * +g_win32_input_stream_new_from_fd (gint fd, + gboolean close_fd) +{ + GWin32InputStream *win32_stream; + + win32_stream = G_WIN32_INPUT_STREAM (g_win32_input_stream_new ((HANDLE) _get_osfhandle (fd), close_fd)); + win32_stream->priv->fd = fd; + + return (GInputStream*)win32_stream; +} diff --git a/gio/gwin32inputstream.h b/gio/gwin32inputstream.h new file mode 100644 index 0000000..c6d8d9a --- /dev/null +++ b/gio/gwin32inputstream.h @@ -0,0 +1,84 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#ifndef __G_WIN32_INPUT_STREAM_H__ +#define __G_WIN32_INPUT_STREAM_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_WIN32_INPUT_STREAM (g_win32_input_stream_get_type ()) +#define G_WIN32_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_INPUT_STREAM, GWin32InputStream)) +#define G_WIN32_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_INPUT_STREAM, GWin32InputStreamClass)) +#define G_IS_WIN32_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_INPUT_STREAM)) +#define G_IS_WIN32_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_INPUT_STREAM)) +#define G_WIN32_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WIN32_INPUT_STREAM, GWin32InputStreamClass)) + +/** + * GWin32InputStream: + * + * Implements #GInputStream for reading from selectable Windows file handles + **/ +typedef struct _GWin32InputStream GWin32InputStream; +typedef struct _GWin32InputStreamClass GWin32InputStreamClass; +typedef struct _GWin32InputStreamPrivate GWin32InputStreamPrivate; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GWin32InputStream, g_object_unref) + +struct _GWin32InputStream +{ + GInputStream parent_instance; + + /*< private >*/ + GWin32InputStreamPrivate *priv; +}; + +struct _GWin32InputStreamClass +{ + GInputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_win32_input_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GInputStream * g_win32_input_stream_new (void *handle, + gboolean close_handle); +GLIB_AVAILABLE_IN_ALL +void g_win32_input_stream_set_close_handle (GWin32InputStream *stream, + gboolean close_handle); +GLIB_AVAILABLE_IN_ALL +gboolean g_win32_input_stream_get_close_handle (GWin32InputStream *stream); +GLIB_AVAILABLE_IN_ALL +void *g_win32_input_stream_get_handle (GWin32InputStream *stream); + +G_END_DECLS + +#endif /* __G_WIN32_INPUT_STREAM_H__ */ diff --git a/gio/gwin32mount.c b/gio/gwin32mount.c new file mode 100644 index 0000000..f5be8ad --- /dev/null +++ b/gio/gwin32mount.c @@ -0,0 +1,539 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Hans Breuer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + * Hans Breuer + */ + +#include "config.h" + +#include +#define WIN32_MEAN_AND_LEAN +#define COBJMACROS +#include +#include +#include + +/* At the moment of writing IExtractIconW interface in Mingw-w64 + * is missing IUnknown members in its vtable. Use our own + * fixed declaration for now. + */ +#undef INTERFACE +#define INTERFACE IMyExtractIconW +DECLARE_INTERFACE_(IMyExtractIconW,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + /*** IMyExtractIconW methods ***/ + STDMETHOD(GetIconLocation)(THIS_ UINT uFlags, LPWSTR pszIconFile, UINT cchMax, int *piIndex, PUINT pwFlags) PURE; + STDMETHOD(Extract)(THIS_ LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) +/*** IUnknown methods ***/ +#define IMyExtractIconW_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IMyExtractIconW_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IMyExtractIconW_Release(p) (p)->lpVtbl->Release(p) +/*** IMyExtractIconW methods ***/ +#define IMyExtractIconW_GetIconLocation(p,a,b,c,d,e) (p)->lpVtbl->GetIconLocation(p,a,b,c,d,e) +#define IMyExtractIconW_Extract(p,a,b,c,d,e) (p)->lpVtbl->Extract(p,a,b,c,d,e) +#else +/*** IUnknown methods ***/ +#define IMyExtractIconW_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IMyExtractIconW_AddRef(p) (p)->AddRef() +#define IMyExtractIconW_Release(p) (p)->Release() +/*** IMyExtractIconW methods ***/ +#define IMyExtractIconW_GetIconLocation(p,a,b,c,d,e) (p)->GetIconLocation(p,a,b,c,d,e) +#define IMyExtractIconW_Extract(p,a,b,c,d,e) (p)->Extract(p,a,b,c,d,e) +#endif + + +#include +#include "gwin32volumemonitor.h" +#include "gwin32mount.h" +#include "gmount.h" +#include "gfile.h" +#include "gmountprivate.h" +#include "gvolumemonitor.h" +#include "gthemedicon.h" +#include "glibintl.h" + + +struct _GWin32Mount { + GObject parent; + + GVolumeMonitor *volume_monitor; + + GWin32Volume *volume; /* owned by volume monitor */ + int drive_type; + + /* why does all this stuff need to be duplicated? It is in volume already! */ + char *name; + GIcon *icon; + GIcon *symbolic_icon; + char *mount_path; + + gboolean can_eject; +}; + +static void g_win32_mount_mount_iface_init (GMountIface *iface); + +#define g_win32_mount_get_type _g_win32_mount_get_type +G_DEFINE_TYPE_WITH_CODE (GWin32Mount, g_win32_mount, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT, + g_win32_mount_mount_iface_init)) + + +static void +g_win32_mount_finalize (GObject *object) +{ + GWin32Mount *mount; + + mount = G_WIN32_MOUNT (object); + + if (mount->volume_monitor != NULL) + g_object_unref (mount->volume_monitor); +#if 0 + if (mount->volume) + _g_win32_volume_unset_mount (mount->volume, mount); +#endif + /* TODO: g_warn_if_fail (volume->volume == NULL); */ + + if (mount->icon != NULL) + g_object_unref (mount->icon); + if (mount->symbolic_icon != NULL) + g_object_unref (mount->symbolic_icon); + + g_free (mount->name); + g_free (mount->mount_path); + + if (G_OBJECT_CLASS (g_win32_mount_parent_class)->finalize) + (*G_OBJECT_CLASS (g_win32_mount_parent_class)->finalize) (object); +} + +static void +g_win32_mount_class_init (GWin32MountClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_win32_mount_finalize; +} + +static void +g_win32_mount_init (GWin32Mount *win32_mount) +{ +} + +/* wdrive doesn't need to end with a path separator. + wdrive must use backslashes as path separators, not slashes. + IShellFolder::ParseDisplayName() takes non-const string as input, + so wdrive can't be a const string. + Returns the name on success (free with g_free), + NULL otherwise. + */ +static gchar * +get_mount_display_name (gunichar2 *wdrive) +{ + IShellFolder *desktop; + PIDLIST_RELATIVE volume; + STRRET volume_name; + gchar *result = NULL; + + /* Get the desktop folder object reference */ + if (!SUCCEEDED (SHGetDesktopFolder (&desktop))) + return result; + + if (SUCCEEDED (IShellFolder_ParseDisplayName (desktop, NULL, NULL, wdrive, NULL, &volume, NULL))) + { + volume_name.uType = STRRET_WSTR; + + if (SUCCEEDED (IShellFolder_GetDisplayNameOf (desktop, volume, SHGDN_FORADDRESSBAR, &volume_name))) + { + wchar_t *volume_name_wchar; + + if (SUCCEEDED (StrRetToStrW (&volume_name, volume, &volume_name_wchar))) + { + result = g_utf16_to_utf8 (volume_name_wchar, -1, NULL, NULL, NULL); + CoTaskMemFree (volume_name_wchar); + } + } + CoTaskMemFree (volume); + } + + IShellFolder_Release (desktop); + + return result; +} + +static gchar * +_win32_get_displayname (const char *drive) +{ + gunichar2 *wdrive = g_utf8_to_utf16 (drive, -1, NULL, NULL, NULL); + gchar *name = get_mount_display_name (wdrive); + + g_free (wdrive); + return name ? name : g_strdup (drive); +} + +/* + * _g_win32_mount_new: + * @volume_monitor: a #GVolumeMonitor. + * @path: a win32 path. + * @volume: usually NULL + * + * Returns: a #GWin32Mount for the given win32 path. + **/ +GWin32Mount * +_g_win32_mount_new (GVolumeMonitor *volume_monitor, + const char *path, + GWin32Volume *volume) +{ + GWin32Mount *mount; + const gchar *drive = path; //fixme + WCHAR *drive_utf16; + + drive_utf16 = g_utf8_to_utf16 (drive, -1, NULL, NULL, NULL); + +#if 0 + /* No volume for mount: Ignore internal things */ + if (volume == NULL && !g_win32_mount_guess_should_display (mount_entry)) + return NULL; +#endif + + mount = g_object_new (G_TYPE_WIN32_MOUNT, NULL); + mount->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL; + mount->mount_path = g_strdup (path); + mount->drive_type = GetDriveTypeW (drive_utf16); + mount->can_eject = FALSE; /* TODO */ + mount->name = _win32_get_displayname (drive); + + /* need to do this last */ + mount->volume = volume; +#if 0 + if (volume != NULL) + _g_win32_volume_set_mount (volume, mount); +#endif + + g_free (drive_utf16); + + return mount; +} + +void +_g_win32_mount_unmounted (GWin32Mount *mount) +{ + if (mount->volume != NULL) + { +#if 0 + _g_win32_volume_unset_mount (mount->volume, mount); +#endif + mount->volume = NULL; + g_signal_emit_by_name (mount, "changed"); + /* there's really no need to emit mount_changed on the volume monitor + * as we're going to be deleted.. */ + } +} + +void +_g_win32_mount_unset_volume (GWin32Mount *mount, + GWin32Volume *volume) +{ + if (mount->volume == volume) + { + mount->volume = NULL; + /* TODO: Emit changed in idle to avoid locking issues */ + g_signal_emit_by_name (mount, "changed"); + if (mount->volume_monitor != NULL) + g_signal_emit_by_name (mount->volume_monitor, "mount-changed", mount); + } +} + +static GFile * +g_win32_mount_get_root (GMount *mount) +{ + GWin32Mount *win32_mount = G_WIN32_MOUNT (mount); + + return g_file_new_for_path (win32_mount->mount_path); +} + +static const char * +_win32_drive_type_to_icon (int type, gboolean use_symbolic) +{ + switch (type) + { + case DRIVE_REMOVABLE : return use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media"; + case DRIVE_FIXED : return use_symbolic ? "drive-harddisk-symbolic" : "drive-harddisk"; + case DRIVE_REMOTE : return use_symbolic ? "folder-remote-symbolic" : "folder-remote"; + case DRIVE_CDROM : return use_symbolic ? "drive-optical-symbolic" : "drive-optical"; + default : return use_symbolic ? "folder-symbolic" : "folder"; + } +} + +/* mount_path doesn't need to end with a path separator. + mount_path must use backslashes as path separators, not slashes. + IShellFolder::ParseDisplayName() takes non-const string as input, + so mount_path can't be a const string. + result_name and result_index must not be NULL. + Returns TRUE when result_name is set (free with g_free), + FALSE otherwise. + */ +static gboolean +get_icon_name_index (wchar_t *mount_path, + wchar_t **result_name, + int *result_index) +{ + IShellFolder *desktop; + PIDLIST_RELATIVE volume; + IShellFolder *volume_parent; + PCUITEMID_CHILD volume_relative; + IMyExtractIconW *eicon; + int icon_index; + UINT icon_flags; + wchar_t *name_buffer; + gsize name_buffer_size; + gsize arbitrary_reasonable_limit = 5000; + gboolean result = FALSE; + + *result_name = NULL; + + /* Get the desktop folder object reference */ + if (!SUCCEEDED (SHGetDesktopFolder (&desktop))) + return FALSE; + + /* Construct the volume IDList relative to desktop */ + if (SUCCEEDED (IShellFolder_ParseDisplayName (desktop, NULL, NULL, mount_path, NULL, &volume, NULL))) + { + /* Get the parent of the volume (transfer-full) and the IDList relative to parent (transfer-none) */ + if (SUCCEEDED (SHBindToParent (volume, &IID_IShellFolder, (void **) &volume_parent, &volume_relative))) + { + /* Get a reference to IExtractIcon object for the volume */ + if (SUCCEEDED (IShellFolder_GetUIObjectOf (volume_parent, NULL, 1, (LPCITEMIDLIST *) &volume_relative, &IID_IExtractIconW, NULL, (void **) &eicon))) + { + gboolean keep_going = TRUE; + name_buffer = NULL; + name_buffer_size = MAX_PATH / 2; + while (keep_going) + { + name_buffer_size *= 2; + name_buffer = g_renew (wchar_t, name_buffer, name_buffer_size); + name_buffer[name_buffer_size - 1] = 0x1; /* sentinel */ + keep_going = FALSE; + + /* Try to get the icon location */ + if (SUCCEEDED (IMyExtractIconW_GetIconLocation (eicon, GIL_FORSHELL, name_buffer, name_buffer_size, &icon_index, &icon_flags))) + { + if (name_buffer[name_buffer_size - 1] != 0x1) + { + if (name_buffer_size < arbitrary_reasonable_limit) + { + /* Buffer was too small, keep going */ + keep_going = TRUE; + continue; + } + /* Else stop trying */ + } + /* name_buffer might not contain a name */ + else if ((icon_flags & GIL_NOTFILENAME) != GIL_NOTFILENAME) + { + *result_name = g_steal_pointer (&name_buffer); + *result_index = icon_index; + result = TRUE; + } + } + } + + g_free (name_buffer); + IMyExtractIconW_Release (eicon); + } + IShellFolder_Release (volume_parent); + } + CoTaskMemFree (volume); + } + + IShellFolder_Release (desktop); + + return result; +} + +static GIcon * +g_win32_mount_get_icon (GMount *mount) +{ + GWin32Mount *win32_mount = G_WIN32_MOUNT (mount); + + g_return_val_if_fail (win32_mount->mount_path != NULL, NULL); + + /* lazy creation */ + if (!win32_mount->icon) + { + wchar_t *icon_path; + int icon_index; + wchar_t *p; + wchar_t *wfn = g_utf8_to_utf16 (win32_mount->mount_path, -1, NULL, NULL, NULL); + + for (p = wfn; p != NULL && *p != 0; p++) + if (*p == L'/') + *p = L'\\'; + + if (get_icon_name_index (wfn, &icon_path, &icon_index)) + { + gchar *id = g_strdup_printf ("%S,%i", icon_path, icon_index); + g_free (icon_path); + win32_mount->icon = g_themed_icon_new (id); + g_free (id); + } + else + { + win32_mount->icon = g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount->drive_type, FALSE)); + } + } + + return g_object_ref (win32_mount->icon); +} + +static GIcon * +g_win32_mount_get_symbolic_icon (GMount *mount) +{ + GWin32Mount *win32_mount = G_WIN32_MOUNT (mount); + + g_return_val_if_fail (win32_mount->mount_path != NULL, NULL); + + /* lazy creation */ + if (!win32_mount->symbolic_icon) + { + win32_mount->symbolic_icon = g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount->drive_type, TRUE)); + } + + return g_object_ref (win32_mount->symbolic_icon); +} + +static char * +g_win32_mount_get_uuid (GMount *mount) +{ + return NULL; +} + +static char * +g_win32_mount_get_name (GMount *mount) +{ + GWin32Mount *win32_mount = G_WIN32_MOUNT (mount); + + return g_strdup (win32_mount->name); +} + +static GDrive * +g_win32_mount_get_drive (GMount *mount) +{ + GWin32Mount *win32_mount = G_WIN32_MOUNT (mount); + + if (win32_mount->volume != NULL) + return g_volume_get_drive (G_VOLUME (win32_mount->volume)); + + return NULL; +} + +static GVolume * +g_win32_mount_get_volume (GMount *mount) +{ + GWin32Mount *win32_mount = G_WIN32_MOUNT (mount); + + if (win32_mount->volume) + return G_VOLUME (g_object_ref (win32_mount->volume)); + + return NULL; +} + +static gboolean +g_win32_mount_can_unmount (GMount *mount) +{ + return FALSE; +} + +static gboolean +g_win32_mount_can_eject (GMount *mount) +{ + GWin32Mount *win32_mount = G_WIN32_MOUNT (mount); + return win32_mount->can_eject; +} + + +typedef struct { + GWin32Mount *win32_mount; + GAsyncReadyCallback callback; + gpointer user_data; + GCancellable *cancellable; + int error_fd; + GIOChannel *error_channel; + guint error_channel_source_id; + GString *error_string; +} UnmountEjectOp; + +static void +g_win32_mount_unmount (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ +} + +static gboolean +g_win32_mount_unmount_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + return FALSE; +} + +static void +g_win32_mount_eject (GMount *mount, + GMountUnmountFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ +} + +static gboolean +g_win32_mount_eject_finish (GMount *mount, + GAsyncResult *result, + GError **error) +{ + return FALSE; +} + +static void +g_win32_mount_mount_iface_init (GMountIface *iface) +{ + iface->get_root = g_win32_mount_get_root; + iface->get_name = g_win32_mount_get_name; + iface->get_icon = g_win32_mount_get_icon; + iface->get_symbolic_icon = g_win32_mount_get_symbolic_icon; + iface->get_uuid = g_win32_mount_get_uuid; + iface->get_drive = g_win32_mount_get_drive; + iface->get_volume = g_win32_mount_get_volume; + iface->can_unmount = g_win32_mount_can_unmount; + iface->can_eject = g_win32_mount_can_eject; + iface->unmount = g_win32_mount_unmount; + iface->unmount_finish = g_win32_mount_unmount_finish; + iface->eject = g_win32_mount_eject; + iface->eject_finish = g_win32_mount_eject_finish; +} diff --git a/gio/gwin32mount.h b/gio/gwin32mount.h new file mode 100644 index 0000000..4eef3ef --- /dev/null +++ b/gio/gwin32mount.h @@ -0,0 +1,56 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Hans Breuer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + * Hans Breuer + */ + +#ifndef __G_WIN32_MOUNT_H__ +#define __G_WIN32_MOUNT_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_WIN32_MOUNT (_g_win32_mount_get_type ()) +#define G_WIN32_MOUNT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_MOUNT, GWin32Mount)) +#define G_WIN32_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_MOUNT, GWin32MountClass)) +#define G_IS_WIN32_MOUNT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_MOUNT)) +#define G_IS_WIN32_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_MOUNT)) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GWin32Mount, g_object_unref) + +typedef struct _GWin32MountClass GWin32MountClass; + +struct _GWin32MountClass +{ + GObjectClass parent_class; +}; + +GType _g_win32_mount_get_type (void) G_GNUC_CONST; + +GWin32Mount * _g_win32_mount_new (GVolumeMonitor *volume_monitor, + const char *path, + GWin32Volume *volume); +void _g_win32_mount_unset_volume (GWin32Mount *mount, + GWin32Volume *volume); +void _g_win32_mount_unmounted (GWin32Mount *mount); + +G_END_DECLS + +#endif /* __G_WIN32_MOUNT_H__ */ diff --git a/gio/gwin32networkmonitor.c b/gio/gwin32networkmonitor.c new file mode 100644 index 0000000..fd9b676 --- /dev/null +++ b/gio/gwin32networkmonitor.c @@ -0,0 +1,339 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2014-2018 Jan-Michael Brummer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include +#include + +#include "gwin32networkmonitor.h" +#include "ginetaddress.h" +#include "ginetaddressmask.h" +#include "ginitable.h" +#include "giomodule-priv.h" +#include "glibintl.h" +#include "glib/gstdio.h" +#include "gnetworkingprivate.h" +#include "gsocket.h" +#include "gnetworkmonitor.h" +#include "gioerror.h" + +static GInitableIface *initable_parent_iface; +static void g_win32_network_monitor_iface_init (GNetworkMonitorInterface *iface); +static void g_win32_network_monitor_initable_iface_init (GInitableIface *iface); + +struct _GWin32NetworkMonitorPrivate +{ + gboolean initialized; + GError *init_error; + GMainContext *main_context; + GSource *route_change_source; + HANDLE handle; +}; + +#define g_win32_network_monitor_get_type _g_win32_network_monitor_get_type +G_DEFINE_TYPE_WITH_CODE (GWin32NetworkMonitor, g_win32_network_monitor, G_TYPE_NETWORK_MONITOR_BASE, + G_ADD_PRIVATE (GWin32NetworkMonitor) + G_IMPLEMENT_INTERFACE (G_TYPE_NETWORK_MONITOR, + g_win32_network_monitor_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_win32_network_monitor_initable_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NETWORK_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "win32", + 20)) + +static void +g_win32_network_monitor_init (GWin32NetworkMonitor *win) +{ + win->priv = g_win32_network_monitor_get_instance_private (win); +} + +static gboolean +win_network_monitor_get_ip_info (IP_ADDRESS_PREFIX prefix, + GSocketFamily *family, + const guint8 **dest, + gsize *len) +{ + switch (prefix.Prefix.si_family) + { + case AF_UNSPEC: + /* Fall-through: AF_UNSPEC deliveres both IPV4 and IPV6 infos, let`s stick with IPV4 here */ + case AF_INET: + *family = G_SOCKET_FAMILY_IPV4; + *dest = (guint8 *) &prefix.Prefix.Ipv4.sin_addr; + *len = prefix.PrefixLength; + break; + case AF_INET6: + *family = G_SOCKET_FAMILY_IPV6; + *dest = (guint8 *) &prefix.Prefix.Ipv6.sin6_addr; + *len = prefix.PrefixLength; + break; + default: + return FALSE; + } + + return TRUE; +} + +static GInetAddressMask * +get_network_mask (GSocketFamily family, + const guint8 *dest, + gsize len) +{ + GInetAddressMask *network; + GInetAddress *dest_addr; + + if (dest != NULL) + dest_addr = g_inet_address_new_from_bytes (dest, family); + else + dest_addr = g_inet_address_new_any (family); + + network = g_inet_address_mask_new (dest_addr, len, NULL); + g_object_unref (dest_addr); + + return network; +} + +static gboolean +win_network_monitor_process_table (GWin32NetworkMonitor *win, + GError **error) +{ + DWORD ret = 0; + GPtrArray *networks; + gsize i; + MIB_IPFORWARD_TABLE2 *routes = NULL; + MIB_IPFORWARD_ROW2 *route; + + ret = GetIpForwardTable2 (AF_UNSPEC, &routes); + if (ret != ERROR_SUCCESS) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "GetIpForwardTable2 () failed: %ld", ret); + + return FALSE; + } + + networks = g_ptr_array_new_full (routes->NumEntries, g_object_unref); + for (i = 0; i < routes->NumEntries; i++) + { + GInetAddressMask *network; + const guint8 *dest; + gsize len; + GSocketFamily family; + + route = routes->Table + i; + + if (!win_network_monitor_get_ip_info (route->DestinationPrefix, &family, &dest, &len)) + continue; + + network = get_network_mask (family, dest, len); + if (network == NULL) + continue; + + g_ptr_array_add (networks, network); + } + + g_network_monitor_base_set_networks (G_NETWORK_MONITOR_BASE (win), + (GInetAddressMask **) networks->pdata, + networks->len); + + return TRUE; +} + +static void +add_network (GWin32NetworkMonitor *win, + GSocketFamily family, + const guint8 *dest, + gsize dest_len) +{ + GInetAddressMask *network; + + network = get_network_mask (family, dest, dest_len); + if (network != NULL) + { + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (win), network); + g_object_unref (network); + } +} + +static void +remove_network (GWin32NetworkMonitor *win, + GSocketFamily family, + const guint8 *dest, + gsize dest_len) +{ + GInetAddressMask *network; + + network = get_network_mask (family, dest, dest_len); + if (network != NULL) + { + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (win), network); + g_object_unref (network); + } +} + +typedef struct { + PMIB_IPFORWARD_ROW2 route; + MIB_NOTIFICATION_TYPE type; + GWin32NetworkMonitor *win; +} RouteData; + +static gboolean +win_network_monitor_invoke_route_changed (gpointer user_data) +{ + GSocketFamily family; + RouteData *route_data = user_data; + const guint8 *dest; + gsize len; + + switch (route_data->type) + { + case MibDeleteInstance: + if (!win_network_monitor_get_ip_info (route_data->route->DestinationPrefix, &family, &dest, &len)) + break; + + remove_network (route_data->win, family, dest, len); + break; + case MibAddInstance: + if (!win_network_monitor_get_ip_info (route_data->route->DestinationPrefix, &family, &dest, &len)) + break; + + add_network (route_data->win, family, dest, len); + break; + case MibInitialNotification: + default: + break; + } + + return G_SOURCE_REMOVE; +} + +static VOID WINAPI +win_network_monitor_route_changed_cb (PVOID context, + PMIB_IPFORWARD_ROW2 route, + MIB_NOTIFICATION_TYPE type) +{ + GWin32NetworkMonitor *win = context; + RouteData *route_data; + + route_data = g_new0 (RouteData, 1); + route_data->route = route; + route_data->type = type; + route_data->win = win; + + win->priv->route_change_source = g_idle_source_new (); + g_source_set_priority (win->priv->route_change_source, G_PRIORITY_DEFAULT); + g_source_set_callback (win->priv->route_change_source, + win_network_monitor_invoke_route_changed, + route_data, + g_free); + + g_source_attach (win->priv->route_change_source, win->priv->main_context); +} + +static gboolean +g_win32_network_monitor_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GWin32NetworkMonitor *win = G_WIN32_NETWORK_MONITOR (initable); + NTSTATUS status; + gboolean read; + + if (!win->priv->initialized) + { + win->priv->main_context = g_main_context_ref_thread_default (); + + /* Read current IP routing table. */ + read = win_network_monitor_process_table (win, &win->priv->init_error); + if (read) + { + /* Register for IPv4 and IPv6 route updates. */ + status = NotifyRouteChange2 (AF_UNSPEC, (PIPFORWARD_CHANGE_CALLBACK) win_network_monitor_route_changed_cb, win, FALSE, &win->priv->handle); + if (status != NO_ERROR) + g_set_error (&win->priv->init_error, G_IO_ERROR, G_IO_ERROR_FAILED, + "NotifyRouteChange2() error: %ld", status); + } + + win->priv->initialized = TRUE; + } + + /* Forward the results. */ + if (win->priv->init_error != NULL) + { + g_propagate_error (error, g_error_copy (win->priv->init_error)); + return FALSE; + } + + return initable_parent_iface->init (initable, cancellable, error); +} + +static void +g_win32_network_monitor_finalize (GObject *object) +{ + GWin32NetworkMonitor *win = G_WIN32_NETWORK_MONITOR (object); + + /* Cancel notification event */ + if (win->priv->handle) + CancelMibChangeNotify2 (win->priv->handle); + + g_clear_error (&win->priv->init_error); + + if (win->priv->route_change_source != NULL) + { + g_source_destroy (win->priv->route_change_source); + g_source_unref (win->priv->route_change_source); + } + + g_main_context_unref (win->priv->main_context); + + G_OBJECT_CLASS (g_win32_network_monitor_parent_class)->finalize (object); +} + +static void +g_win32_network_monitor_class_init (GWin32NetworkMonitorClass *win_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (win_class); + + gobject_class->finalize = g_win32_network_monitor_finalize; +} + +static void +g_win32_network_monitor_iface_init (GNetworkMonitorInterface *monitor_iface) +{ +} + +static void +g_win32_network_monitor_initable_iface_init (GInitableIface *iface) +{ + initable_parent_iface = g_type_interface_peek_parent (iface); + + iface->init = g_win32_network_monitor_initable_init; +} diff --git a/gio/gwin32networkmonitor.h b/gio/gwin32networkmonitor.h new file mode 100644 index 0000000..49408cf --- /dev/null +++ b/gio/gwin32networkmonitor.h @@ -0,0 +1,53 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2014-2018 Jan-Michael Brummer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_WIN32_NETWORK_MONITOR_H__ +#define __G_WIN32_NETWORK_MONITOR_H__ + +#include "gnetworkmonitorbase.h" + +G_BEGIN_DECLS + +#define G_TYPE_WIN32_NETWORK_MONITOR (_g_win32_network_monitor_get_type ()) +#define G_WIN32_NETWORK_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_NETWORK_MONITOR, GWin32NetworkMonitor)) +#define G_WIN32_NETWORK_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_NETWORK_MONITOR, GWin32NetworkMonitorClass)) +#define G_IS_WIN32_NETWORK_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_NETWORK_MONITOR)) +#define G_IS_WIN32_NETWORK_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_NETWORK_MONITOR)) +#define G_WIN32_NETWORK_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WIN32_NETWORK_MONITOR, GWin32NetworkMonitorClass)) + +typedef struct _GWin32NetworkMonitor GWin32NetworkMonitor; +typedef struct _GWin32NetworkMonitorClass GWin32NetworkMonitorClass; +typedef struct _GWin32NetworkMonitorPrivate GWin32NetworkMonitorPrivate; + +struct _GWin32NetworkMonitor { + GNetworkMonitorBase parent_instance; + + GWin32NetworkMonitorPrivate *priv; +}; + +struct _GWin32NetworkMonitorClass { + GNetworkMonitorBaseClass parent_class; +}; + +GType _g_win32_network_monitor_get_type (void); + +G_END_DECLS + +#endif /* __G_WIN32_NETWORK_MONITOR_H__ */ diff --git a/gio/gwin32notificationbackend.c b/gio/gwin32notificationbackend.c new file mode 100644 index 0000000..602f3f3 --- /dev/null +++ b/gio/gwin32notificationbackend.c @@ -0,0 +1,96 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2018 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + * + * Authors: + * - Philip Withnall + */ + +#include "config.h" + +#include "gnotificationbackend.h" + +#include "giomodule-priv.h" +#include "gnotification-private.h" + +#define G_TYPE_WIN32_NOTIFICATION_BACKEND (g_win32_notification_backend_get_type ()) +#define G_WIN32_NOTIFICATION_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_NOTIFICATION_BACKEND, GWin32NotificationBackend)) + +typedef struct _GWin32NotificationBackend GWin32NotificationBackend; +typedef GNotificationBackendClass GWin32NotificationBackendClass; + +struct _GWin32NotificationBackend +{ + GNotificationBackend parent; +}; + +GType g_win32_notification_backend_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (GWin32NotificationBackend, g_win32_notification_backend, G_TYPE_NOTIFICATION_BACKEND, + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, "win32", 0)) + +static gboolean +g_win32_notification_backend_is_supported (void) +{ + /* This is the only backend supported on Windows, and always needs to be + * present to avoid no backend being selected. */ + return TRUE; +} + +static void +g_win32_notification_backend_send_notification (GNotificationBackend *backend, + const gchar *id, + GNotification *notification) +{ + static gsize warned = 0; + + /* FIXME: See https://bugzilla.gnome.org/show_bug.cgi?id=776583. This backend + * exists purely to stop crashes when applications use g_notification*() + * on Windows, by providing a dummy backend implementation. (The alternative + * was to modify all of the backend call sites in g_notification*(), which + * seemed less scalable.) */ + if (g_once_init_enter (&warned)) + { + g_warning ("Notifications are not yet supported on Windows."); + g_once_init_leave (&warned, 1); + } +} + +static void +g_win32_notification_backend_withdraw_notification (GNotificationBackend *backend, + const gchar *id) +{ + /* FIXME: Nothing needs doing here until send_notification() is implemented. */ +} + +static void +g_win32_notification_backend_init (GWin32NotificationBackend *backend) +{ +} + +static void +g_win32_notification_backend_class_init (GWin32NotificationBackendClass *class) +{ + GNotificationBackendClass *backend_class = G_NOTIFICATION_BACKEND_CLASS (class); + + backend_class->is_supported = g_win32_notification_backend_is_supported; + backend_class->send_notification = g_win32_notification_backend_send_notification; + backend_class->withdraw_notification = g_win32_notification_backend_withdraw_notification; +} diff --git a/gio/gwin32outputstream.c b/gio/gwin32outputstream.c new file mode 100644 index 0000000..b5f70c9 --- /dev/null +++ b/gio/gwin32outputstream.c @@ -0,0 +1,386 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#include "config.h" + +#include + +#include + +#include +#include +#include "gioerror.h" +#include "gwin32outputstream.h" +#include "giowin32-priv.h" +#include "gcancellable.h" +#include "gasynchelper.h" +#include "glibintl.h" + +/** + * SECTION:gwin32outputstream + * @short_description: Streaming output operations for Windows file handles + * @include: gio/gwin32outputstream.h + * @see_also: #GOutputStream + * + * #GWin32OutputStream implements #GOutputStream for writing to a + * Windows file handle. + * + * Note that `` belongs to the Windows-specific GIO + * interfaces, thus you have to use the `gio-windows-2.0.pc` pkg-config file + * when using it. + */ + +struct _GWin32OutputStreamPrivate { + HANDLE handle; + gboolean close_handle; + gint fd; +}; + +enum { + PROP_0, + PROP_HANDLE, + PROP_CLOSE_HANDLE, + LAST_PROP +}; + +static GParamSpec *props[LAST_PROP]; + +G_DEFINE_TYPE_WITH_PRIVATE (GWin32OutputStream, g_win32_output_stream, G_TYPE_OUTPUT_STREAM) + +static void +g_win32_output_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GWin32OutputStream *win32_stream; + + win32_stream = G_WIN32_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_HANDLE: + win32_stream->priv->handle = g_value_get_pointer (value); + break; + case PROP_CLOSE_HANDLE: + win32_stream->priv->close_handle = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_win32_output_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GWin32OutputStream *win32_stream; + + win32_stream = G_WIN32_OUTPUT_STREAM (object); + + switch (prop_id) + { + case PROP_HANDLE: + g_value_set_pointer (value, win32_stream->priv->handle); + break; + case PROP_CLOSE_HANDLE: + g_value_set_boolean (value, win32_stream->priv->close_handle); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static gssize +g_win32_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GWin32OutputStream *win32_stream; + BOOL res; + DWORD nbytes, nwritten; + OVERLAPPED overlap = { 0, }; + gssize retval = -1; + + win32_stream = G_WIN32_OUTPUT_STREAM (stream); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return -1; + + if (count > G_MAXINT) + nbytes = G_MAXINT; + else + nbytes = count; + + overlap.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + g_return_val_if_fail (overlap.hEvent != NULL, -1); + + res = WriteFile (win32_stream->priv->handle, buffer, nbytes, &nwritten, &overlap); + if (res) + retval = nwritten; + else + { + int errsv = GetLastError (); + + if (errsv == ERROR_IO_PENDING && + _g_win32_overlap_wait_result (win32_stream->priv->handle, + &overlap, &nwritten, cancellable)) + { + retval = nwritten; + goto end; + } + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + goto end; + + errsv = GetLastError (); + if (errsv == ERROR_HANDLE_EOF || + errsv == ERROR_BROKEN_PIPE) + { + retval = 0; + } + else + { + gchar *emsg; + + emsg = g_win32_error_message (errsv); + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (errsv), + _("Error writing to handle: %s"), + emsg); + g_free (emsg); + } + } + +end: + CloseHandle (overlap.hEvent); + return retval; +} + +static gboolean +g_win32_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GWin32OutputStream *win32_stream; + BOOL res; + + win32_stream = G_WIN32_OUTPUT_STREAM (stream); + + if (!win32_stream->priv->close_handle) + return TRUE; + + if (win32_stream->priv->fd != -1) + { + if (close (win32_stream->priv->fd) < 0) + { + int errsv = errno; + + g_set_error (error, G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Error closing file descriptor: %s"), + g_strerror (errsv)); + return FALSE; + } + } + else + { + res = CloseHandle (win32_stream->priv->handle); + if (!res) + { + int errsv = GetLastError (); + gchar *emsg = g_win32_error_message (errsv); + + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (errsv), + _("Error closing handle: %s"), + emsg); + g_free (emsg); + return FALSE; + } + } + + return TRUE; +} + +static void +g_win32_output_stream_class_init (GWin32OutputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass); + + gobject_class->get_property = g_win32_output_stream_get_property; + gobject_class->set_property = g_win32_output_stream_set_property; + + stream_class->write_fn = g_win32_output_stream_write; + stream_class->close_fn = g_win32_output_stream_close; + + /** + * GWin32OutputStream:handle: + * + * The file handle that the stream writes to. + * + * Since: 2.26 + */ + props[PROP_HANDLE] = + g_param_spec_pointer ("handle", + P_("File handle"), + P_("The file handle to write to"), + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + /** + * GWin32OutputStream:close-handle: + * + * Whether to close the file handle when the stream is closed. + * + * Since: 2.26 + */ + props[PROP_CLOSE_HANDLE] = + g_param_spec_boolean ("close-handle", + P_("Close file handle"), + P_("Whether to close the file handle when the stream is closed"), + TRUE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, LAST_PROP, props); +} + +static void +g_win32_output_stream_init (GWin32OutputStream *win32_stream) +{ + win32_stream->priv = g_win32_output_stream_get_instance_private (win32_stream); + win32_stream->priv->handle = NULL; + win32_stream->priv->close_handle = TRUE; + win32_stream->priv->fd = -1; +} + +/** + * g_win32_output_stream_new: + * @handle: a Win32 file handle + * @close_handle: %TRUE to close the handle when done + * + * Creates a new #GWin32OutputStream for the given @handle. + * + * If @close_handle, is %TRUE, the handle will be closed when the + * output stream is destroyed. + * + * Returns: a new #GOutputStream + * + * Since: 2.26 +**/ +GOutputStream * +g_win32_output_stream_new (void *handle, + gboolean close_handle) +{ + GWin32OutputStream *stream; + + g_return_val_if_fail (handle != NULL, NULL); + + stream = g_object_new (G_TYPE_WIN32_OUTPUT_STREAM, + "handle", handle, + "close-handle", close_handle, + NULL); + + return G_OUTPUT_STREAM (stream); +} + +/** + * g_win32_output_stream_set_close_handle: + * @stream: a #GWin32OutputStream + * @close_handle: %TRUE to close the handle when done + * + * Sets whether the handle of @stream shall be closed when the stream + * is closed. + * + * Since: 2.26 + */ +void +g_win32_output_stream_set_close_handle (GWin32OutputStream *stream, + gboolean close_handle) +{ + g_return_if_fail (G_IS_WIN32_OUTPUT_STREAM (stream)); + + close_handle = close_handle != FALSE; + if (stream->priv->close_handle != close_handle) + { + stream->priv->close_handle = close_handle; + g_object_notify (G_OBJECT (stream), "close-handle"); + } +} + +/** + * g_win32_output_stream_get_close_handle: + * @stream: a #GWin32OutputStream + * + * Returns whether the handle of @stream will be closed when the + * stream is closed. + * + * Returns: %TRUE if the handle is closed when done + * + * Since: 2.26 + */ +gboolean +g_win32_output_stream_get_close_handle (GWin32OutputStream *stream) +{ + g_return_val_if_fail (G_IS_WIN32_OUTPUT_STREAM (stream), FALSE); + + return stream->priv->close_handle; +} + +/** + * g_win32_output_stream_get_handle: + * @stream: a #GWin32OutputStream + * + * Return the Windows handle that the stream writes to. + * + * Returns: The handle descriptor of @stream + * + * Since: 2.26 + */ +void * +g_win32_output_stream_get_handle (GWin32OutputStream *stream) +{ + g_return_val_if_fail (G_IS_WIN32_OUTPUT_STREAM (stream), NULL); + + return stream->priv->handle; +} + +GOutputStream * +g_win32_output_stream_new_from_fd (gint fd, + gboolean close_fd) +{ + GWin32OutputStream *win32_stream; + + win32_stream = G_WIN32_OUTPUT_STREAM (g_win32_output_stream_new ((HANDLE) _get_osfhandle (fd), close_fd)); + win32_stream->priv->fd = fd; + + return (GOutputStream*)win32_stream; +} diff --git a/gio/gwin32outputstream.h b/gio/gwin32outputstream.h new file mode 100644 index 0000000..9045da8 --- /dev/null +++ b/gio/gwin32outputstream.h @@ -0,0 +1,83 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#ifndef __G_WIN32_OUTPUT_STREAM_H__ +#define __G_WIN32_OUTPUT_STREAM_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_WIN32_OUTPUT_STREAM (g_win32_output_stream_get_type ()) +#define G_WIN32_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_OUTPUT_STREAM, GWin32OutputStream)) +#define G_WIN32_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_OUTPUT_STREAM, GWin32OutputStreamClass)) +#define G_IS_WIN32_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_OUTPUT_STREAM)) +#define G_IS_WIN32_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_OUTPUT_STREAM)) +#define G_WIN32_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WIN32_OUTPUT_STREAM, GWin32OutputStreamClass)) + +/** + * GWin32OutputStream: + * + * Implements #GOutputStream for outputting to Windows file handles + **/ +typedef struct _GWin32OutputStream GWin32OutputStream; +typedef struct _GWin32OutputStreamClass GWin32OutputStreamClass; +typedef struct _GWin32OutputStreamPrivate GWin32OutputStreamPrivate; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GWin32OutputStream, g_object_unref) + +struct _GWin32OutputStream +{ + GOutputStream parent_instance; + + /*< private >*/ + GWin32OutputStreamPrivate *priv; +}; + +struct _GWin32OutputStreamClass +{ + GOutputStreamClass parent_class; + + /*< private >*/ + /* Padding for future expansion */ + void (*_g_reserved1) (void); + void (*_g_reserved2) (void); + void (*_g_reserved3) (void); + void (*_g_reserved4) (void); + void (*_g_reserved5) (void); +}; + +GLIB_AVAILABLE_IN_ALL +GType g_win32_output_stream_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GOutputStream * g_win32_output_stream_new (void *handle, + gboolean close_handle); +GLIB_AVAILABLE_IN_ALL +void g_win32_output_stream_set_close_handle (GWin32OutputStream *stream, + gboolean close_handle); +GLIB_AVAILABLE_IN_ALL +gboolean g_win32_output_stream_get_close_handle (GWin32OutputStream *stream); +GLIB_AVAILABLE_IN_ALL +void *g_win32_output_stream_get_handle (GWin32OutputStream *stream); +G_END_DECLS + +#endif /* __G_WIN32_OUTPUT_STREAM_H__ */ diff --git a/gio/gwin32packageparser.c b/gio/gwin32packageparser.c new file mode 100755 index 0000000..58b9994 --- /dev/null +++ b/gio/gwin32packageparser.c @@ -0,0 +1,818 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2020 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ + +/* Queries the system (Windows 8 or newer) for the list + * of UWP packages, parses their manifests and invokes + * a user-provided callback with the needed application + * info. + */ + +#include "config.h" + +#define COBJMACROS +#define INITGUID +#include +#include +#include +#include +#include + +#include "gwin32api-storage.h" +#include "gwin32api-misc.h" +#include "gwin32api-iterator.h" +#include "gwin32api-package.h" + +#include + +#include + +#include "gwin32file-sync-stream.h" +#include "gwin32packageparser.h" + +#ifdef G_WINAPI_ONLY_APP +#define LoadedRoActivateInstance RoActivateInstance +#define LoadedWindowsCreateStringReference WindowsCreateStringReference +#define LoadedWindowsDeleteString WindowsDeleteString +#define sax_WindowsGetStringRawBuffer WindowsGetStringRawBuffer +#define LoadedWindowsGetStringRawBuffer WindowsGetStringRawBuffer +#define sax_CreateXmlReader CreateXmlReader +#else +typedef HRESULT (WINAPI *RoActivateInstance_func)(HSTRING activatableClassId, IInspectable **instance); +typedef HRESULT (WINAPI *WindowsCreateStringReference_func)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING *string); +typedef HRESULT (WINAPI *WindowsDeleteString_func)(HSTRING string); +typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_func)(HSTRING string, UINT32 *length); +typedef HRESULT (STDAPICALLTYPE *CreateXmlReader_func)(REFIID riid, void **ppvObject, IMalloc *pMalloc); +#define sax_WindowsGetStringRawBuffer sax->WindowsGetStringRawBuffer +#define sax_CreateXmlReader sax->CreateXmlReader +#endif + +static gsize +g_utf16_len (const gunichar2 *str) +{ + gsize result; + + for (result = 0; str[0] != 0; str++, result++) + ; + + return result; +} + +static gunichar2 * +g_wcsdup (const gunichar2 *str, gssize str_len) +{ + gsize str_len_unsigned; + gsize str_size; + + g_return_val_if_fail (str != NULL, NULL); + + if (str_len < 0) + str_len_unsigned = g_utf16_len (str); + else + str_len_unsigned = (gsize) str_len; + + g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1); + str_size = (str_len_unsigned + 1) * sizeof (gunichar2); + + return g_memdup2 (str, str_size); +} + +static BOOL +WIN32_FROM_HRESULT (HRESULT hresult, + DWORD *win32_error_code) +{ + if ((hresult & (HRESULT) 0xFFFF0000) == MAKE_HRESULT (SEVERITY_ERROR, FACILITY_WIN32, 0) || + hresult == S_OK) + { + *win32_error_code = HRESULT_CODE (hresult); + return TRUE; + } + + return FALSE; +} + +static GIOErrorEnum +gio_error_from_hresult (HRESULT hresult) +{ + DWORD error; + + if (WIN32_FROM_HRESULT (hresult, &error)) + return g_io_error_from_errno (error); + + return G_IO_ERROR_FAILED; +} + +static void +free_extgroup (GWin32PackageExtGroup *g) +{ + g_ptr_array_unref (g->verbs); + g_ptr_array_unref (g->extensions); + g_free (g); +} + +struct _xml_sax_state +{ +#ifndef G_WINAPI_ONLY_APP + WindowsGetStringRawBuffer_func WindowsGetStringRawBuffer; + CreateXmlReader_func CreateXmlReader; +#endif + + GWin32PackageParserCallback callback; + gpointer user_data; + + const wchar_t *manifest_filename; + gsize package_index; + const wchar_t *wcs_full_name; + const wchar_t *wcs_name; + HSTRING package_family; + + gboolean applist; + gboolean exit_early; + + UINT64 in_package; + UINT64 in_applications; + UINT64 in_application; + UINT64 in_extensions; + UINT64 in_extension_protocol; + UINT64 in_extension_fta; + UINT64 in_fta_group; + UINT64 in_sfp; + UINT64 in_filetype; + UINT64 in_sv; + GPtrArray *supported_extensions; + GPtrArray *supported_protocols; + GPtrArray *supported_verbs; + GPtrArray *supported_extgroups; + wchar_t *application_usermodelid; +}; + +static gboolean parse_manifest_file (struct _xml_sax_state *sax); +static gboolean xml_parser_iteration (struct _xml_sax_state *sax, + IXmlReader *xml_reader); +static gboolean xml_parser_get_current_state (struct _xml_sax_state *sax, + IXmlReader *xml_reader, + const wchar_t **local_name, + const wchar_t **prefix, + const wchar_t **value); + +gboolean +g_win32_package_parser_enum_packages (GWin32PackageParserCallback callback, + gpointer user_data, + GError **error) +{ + gboolean result = TRUE; + HRESULT hr; + HSTRING packagemanager_name = NULL; + HSTRING_HEADER packageanager_name_header; + const wchar_t *packman_id = L"Windows.Management.Deployment.PackageManager"; + IInspectable *ii_pm = NULL; + IPackageManager *pm = NULL; + IIterable *packages_iterable = NULL; + IIterator *packages_iterator = NULL; + CHAR has_current; + gsize package_index; + const wchar_t *bslash_appmanifest = L"\\AppxManifest.xml"; + struct _xml_sax_state sax_stack; + struct _xml_sax_state *sax = &sax_stack; + +#ifndef G_WINAPI_ONLY_APP + HMODULE xmllite = NULL; + HMODULE combase = NULL; + HMODULE winrt = NULL; + RoActivateInstance_func LoadedRoActivateInstance; + WindowsCreateStringReference_func LoadedWindowsCreateStringReference; + WindowsDeleteString_func LoadedWindowsDeleteString; + WindowsGetStringRawBuffer_func LoadedWindowsGetStringRawBuffer; + CreateXmlReader_func LoadedCreateXmlReader; + + winrt = LoadLibraryW (L"api-ms-win-core-winrt-l1-1-0.dll"); + if (winrt == NULL) + { + result = FALSE; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to load api-ms-win-core-winrt-l1-1-0.dll"); + goto cleanup; + } + + combase = LoadLibraryW (L"combase.dll"); + if (combase == NULL) + { + result = FALSE; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to load combase.dll"); + goto cleanup; + } + + xmllite = LoadLibraryW (L"xmllite.dll"); + if (xmllite == NULL) + { + result = FALSE; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to load xmllite.dll"); + goto cleanup; + } + + LoadedCreateXmlReader = (CreateXmlReader_func) GetProcAddress (xmllite, "CreateXmlReader"); + if (LoadedCreateXmlReader == NULL) + { + result = FALSE; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "CreateXmlReader entry point is not found in xmllite.dll"); + goto cleanup; + } + + LoadedRoActivateInstance = (RoActivateInstance_func) GetProcAddress (winrt, "RoActivateInstance"); + if (LoadedRoActivateInstance == NULL) + { + result = FALSE; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "RoActivateInstance entry point is not found in api-ms-win-core-winrt-l1-1-0.dll"); + goto cleanup; + } + + LoadedWindowsCreateStringReference = (WindowsCreateStringReference_func) GetProcAddress (combase, "WindowsCreateStringReference"); + if (LoadedWindowsCreateStringReference == NULL) + { + result = FALSE; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "WindowsCreateStringReference entry point is not found in combase.dll"); + goto cleanup; + } + + LoadedWindowsDeleteString = (WindowsDeleteString_func) GetProcAddress (combase, "WindowsDeleteString"); + if (LoadedWindowsDeleteString == NULL) + { + result = FALSE; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "WindowsDeleteString entry point is not found in combase.dll"); + goto cleanup; + } + + LoadedWindowsGetStringRawBuffer = (WindowsGetStringRawBuffer_func) GetProcAddress (combase, "WindowsGetStringRawBuffer"); + if (LoadedWindowsGetStringRawBuffer == NULL) + { + result = FALSE; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "WindowsGetStringRawBuffer entry point is not found in combase.dll"); + goto cleanup; + } +#endif + + /* This essentially locks current GLib thread into apartment COM model. */ + hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED); + /* Can return S_FALSE if COM is already initialized, + * which is not an error, and we still need to uninitialize after that. + */ + if (hr != S_OK && hr != S_FALSE) + { + result = FALSE; + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, + "CoInitializeEx(COINIT_APARTMENTTHREADED) failed with code 0x%lx", hr); + goto cleanup; + } + +#define canned_com_error_handler(function_name_literal, where_to_go) \ + do \ + { \ + if (FAILED (hr)) \ + { \ + result = FALSE; \ + g_set_error (error, G_IO_ERROR, gio_error_from_hresult (hr), \ + function_name_literal " failed with code 0x%lx", hr); \ + goto where_to_go; \ + } \ + } while (0) + + hr = LoadedWindowsCreateStringReference (packman_id, wcslen (packman_id), &packageanager_name_header, &packagemanager_name); + canned_com_error_handler ("WindowsCreateStringReference()", cleanup); + + hr = LoadedRoActivateInstance (packagemanager_name, &ii_pm); + canned_com_error_handler ("RoActivateInstance()", cleanup); + + hr = IInspectable_QueryInterface (ii_pm, &IID_IPackageManager, (void**) &pm); + canned_com_error_handler ("IInspectable_QueryInterface()", cleanup); + + hr = IPackageManager_FindPackagesByUserSecurityId (pm, 0, &packages_iterable); + canned_com_error_handler ("IPackageManager_FindPackagesByUserSecurityId()", cleanup); + + hr = IIterable_First (packages_iterable, &packages_iterator); + canned_com_error_handler ("IIterable_First()", cleanup); + + hr = IIterator_get_HasCurrent (packages_iterator, &has_current); + canned_com_error_handler ("IIterator_get_HasCurrent()", cleanup); + + for (package_index = 0; SUCCEEDED (hr) && has_current; package_index++) + { + IUnknown *item = NULL; + IPackage *ipackage = NULL; + IPackageId *ipackageid = NULL; + IUnknown *package_install_location = NULL; + IStorageItem *storage_item = NULL; + HSTRING path = NULL; + HSTRING name = NULL; + HSTRING full_name = NULL; + HSTRING package_family = NULL; + size_t manifest_filename_size; + const wchar_t *wcs_path; + const wchar_t *wcs_full_name; + const wchar_t *wcs_name; + wchar_t *manifest_filename = NULL; + +#define canned_com_error_handler_pkg(function_name_literal, where_to_go) \ + do \ + { \ + if (FAILED (hr)) \ + { \ + result = FALSE; \ + g_set_error (error, G_IO_ERROR, gio_error_from_hresult (hr), \ + function_name_literal " for package #%zu failed with code 0x%lx", package_index, hr); \ + goto where_to_go; \ + } \ + } while (0) + + hr = IIterator_get_Current (packages_iterator, &item); + canned_com_error_handler_pkg ("IIterator_get_Current()", package_cleanup); + + hr = IUnknown_QueryInterface (item, &IID_IPackage, (void **) &ipackage); + canned_com_error_handler_pkg ("IUnknown_QueryInterface(IID_IPackage)", package_cleanup); + + hr = IPackage_get_Id (ipackage, &ipackageid); + canned_com_error_handler_pkg ("IPackage_get_Id()", package_cleanup); + + hr = IPackageId_get_FullName (ipackageid, &full_name); + canned_com_error_handler_pkg ("IPackageId_get_FullName()", package_cleanup); + + hr = IPackageId_get_Name (ipackageid, &name); + canned_com_error_handler_pkg ("IPackageId_get_Name()", package_cleanup); + + wcs_full_name = LoadedWindowsGetStringRawBuffer (full_name, NULL); + wcs_name = LoadedWindowsGetStringRawBuffer (name, NULL); + +#define canned_com_error_handler_pkg_named(function_name_literal, where_to_go) \ + do \ + { \ + if (FAILED (hr)) \ + { \ + result = FALSE; \ + g_set_error (error, G_IO_ERROR, gio_error_from_hresult (hr), \ + function_name_literal " for package #%zu (`%S') failed with code 0x%lx", package_index, wcs_full_name, hr); \ + goto where_to_go; \ + } \ + } while (0) + + hr = IPackage_get_InstalledLocation (ipackage, &package_install_location); + canned_com_error_handler_pkg_named ("IPackage_get_InstalledLocation()", package_cleanup); + + hr = IUnknown_QueryInterface (package_install_location, &IID_IStorageItem, (void **) &storage_item); + canned_com_error_handler_pkg_named ("IUnknown_QueryInterface(IID_IStorageItem)", package_cleanup); + + hr = IPackageId_get_FamilyName (ipackageid, &package_family); + canned_com_error_handler_pkg_named ("IPackageId_get_FamilyName()", package_cleanup); + + hr = IStorageItem_get_Path (storage_item, &path); + canned_com_error_handler_pkg_named ("IStorageItem_get_Path()", package_cleanup); + + wcs_path = LoadedWindowsGetStringRawBuffer (path, NULL); + manifest_filename_size = wcslen (wcs_path) + wcslen (bslash_appmanifest); + manifest_filename = g_new (wchar_t, manifest_filename_size + 1); + memcpy (manifest_filename, wcs_path, wcslen (wcs_path) * sizeof (wchar_t)); + memcpy (&manifest_filename[wcslen (wcs_path)], bslash_appmanifest, (wcslen (bslash_appmanifest) + 1) * sizeof (wchar_t)); + + memset (sax, 0, sizeof (*sax)); + sax->callback = callback; + sax->user_data = user_data; + sax->manifest_filename = manifest_filename; + sax->package_index = package_index; + sax->wcs_full_name = wcs_full_name; + sax->wcs_name = wcs_name; + sax->package_family = package_family; + sax->applist = TRUE; + sax->exit_early = FALSE; +#ifndef G_WINAPI_ONLY_APP + sax->CreateXmlReader = LoadedCreateXmlReader; + sax->WindowsGetStringRawBuffer = LoadedWindowsGetStringRawBuffer; +#endif + /* Result isn't checked. If we fail to parse the manifest, + * just try the next package, no need to bail out. + */ + parse_manifest_file (sax); + + hr = IIterator_MoveNext (packages_iterator, &has_current); + canned_com_error_handler_pkg_named ("IIterator_MoveNext()", package_cleanup); + +#undef canned_com_error_handler_pkg_named +#undef canned_com_error_handler_pkg +#undef canned_com_error_handler + + package_cleanup: + g_clear_pointer (&manifest_filename, g_free); + + if (path) + LoadedWindowsDeleteString (path); + if (storage_item) + (void) IStorageItem_Release (storage_item); + if (package_install_location) + (void) IUnknown_Release (package_install_location); + if (ipackage) + (void) IPackage_Release (ipackage); + if (item) + (void) IUnknown_Release (item); + + if (package_family) + LoadedWindowsDeleteString (package_family); + if (name) + LoadedWindowsDeleteString (name); + if (full_name) + LoadedWindowsDeleteString (full_name); + + if (ipackageid) + (void) IPackageId_Release (ipackageid); + if (sax->exit_early) + break; + } + + cleanup: + if (packages_iterator) + (void) IIterator_Release (packages_iterator); + if (packages_iterable) + (void) IIterable_Release (packages_iterable); + if (pm) + (void) IPackageManager_Release (pm); + if (ii_pm) + (void) IInspectable_Release (ii_pm); + + CoUninitialize (); + +#ifndef G_WINAPI_ONLY_APP + if (xmllite) + (void) FreeLibrary (xmllite); + if (combase) + (void) FreeLibrary (combase); + if (winrt) + (void) FreeLibrary (winrt); +#endif + + return result; +} + +static gboolean +parse_manifest_file (struct _xml_sax_state *sax) +{ + HRESULT hr; + HANDLE file_handle = INVALID_HANDLE_VALUE; + IStream *file_stream = NULL; + gboolean result; + IXmlReader *xml_reader; + + file_handle = CreateFileW (sax->manifest_filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file_handle == INVALID_HANDLE_VALUE) + { + g_warning ("Failed to open application manifest `%S' for package #%zu (`%S'): error code 0x%lx", + sax->manifest_filename, sax->package_index, sax->wcs_full_name, GetLastError ()); + return FALSE; + } + + file_stream = g_win32_file_sync_stream_new (file_handle, TRUE, STGM_READ | STGM_SHARE_DENY_WRITE, &hr); + if (file_stream == NULL) + { + g_warning ("Failed to create an IStream for application manifest `%S' for package #%zu (`%S'): HRESULT 0x%lx", + sax->manifest_filename, sax->package_index, sax->wcs_full_name, hr); + CloseHandle (file_handle); + return FALSE; + } + + /* file_stream owns it now */ + file_handle = NULL; + + hr = sax_CreateXmlReader (&IID_IXmlReader, (void **) &xml_reader, NULL); + /* Slightly incorrect - xml reader is not created for any particular file, + * in theory we could re-use the same xml reader instance for all files. + */ + if (FAILED (hr)) + { + g_warning ("CreateXmlReader() for application manifest `%S' for package #%zu (`%S') failed with HRESULT 0x%lx", + sax->manifest_filename, sax->package_index, sax->wcs_full_name, hr); + (void) IStream_Release (file_stream); + return FALSE; + } + + hr = IXmlReader_SetInput (xml_reader, (IUnknown *) file_stream); + if (FAILED (hr)) + { + g_warning ("IXmlReader_SetInput() for application manifest `%S' for package #%zu (`%S') failed with HRESULT 0x%lx", + sax->manifest_filename, sax->package_index, sax->wcs_full_name, hr); + (void) IXmlReader_Release (xml_reader); + (void) IStream_Release (file_stream); + return FALSE; + } + + sax->supported_extensions = g_ptr_array_new_full (0, (GDestroyNotify) g_free); + sax->supported_protocols = g_ptr_array_new_full (0, (GDestroyNotify) g_free); + sax->supported_verbs = g_ptr_array_new_full (0, (GDestroyNotify) g_free); + sax->supported_extgroups = g_ptr_array_new_full (0, (GDestroyNotify) free_extgroup); + + result = TRUE; + + while (!sax->exit_early && result && !IXmlReader_IsEOF (xml_reader)) + result = xml_parser_iteration (sax, xml_reader); + + g_clear_pointer (&sax->application_usermodelid, g_free); + g_clear_pointer (&sax->supported_extensions, g_ptr_array_unref); + g_clear_pointer (&sax->supported_verbs, g_ptr_array_unref); + g_clear_pointer (&sax->supported_extgroups, g_ptr_array_unref); + g_clear_pointer (&sax->supported_protocols, g_ptr_array_unref); + + (void) IXmlReader_Release (xml_reader); + (void) IStream_Release (file_stream); + + return result; +} + +static gboolean +xml_parser_get_current_state (struct _xml_sax_state *sax, + IXmlReader *xml_reader, + const wchar_t **local_name, + const wchar_t **prefix, + const wchar_t **value) +{ + HRESULT hr; + UINT xml_line_number; + UINT xml_line_position; + + hr = IXmlReader_GetLineNumber (xml_reader, &xml_line_number); + if (FAILED (hr)) + { + g_warning ("IXmlReader_GetLineNumber() for application manifest `%S' for package #%zu (`%S') failed with HRESULT 0x%lx", + sax->manifest_filename, sax->package_index, sax->wcs_full_name, hr); + return FALSE; + } + + hr = IXmlReader_GetLinePosition (xml_reader, &xml_line_position); + if (FAILED (hr)) + { + g_warning ("IXmlReader_GetLinePosition() for application manifest `%S' for package #%zu (`%S') failed with HRESULT 0x%lx", + sax->manifest_filename, sax->package_index, sax->wcs_full_name, hr); + return FALSE; + } + + hr = IXmlReader_GetLocalName (xml_reader, local_name, NULL); + if (FAILED (hr)) + { + g_warning ("IXmlReader_GetLocalName() for application manifest `%S':%u (column %u) for package #%zu (`%S') failed with HRESULT 0x%lx", + sax->manifest_filename, xml_line_number, xml_line_position, sax->package_index, sax->wcs_full_name, hr); + return FALSE; + } + + hr = IXmlReader_GetPrefix (xml_reader, prefix, NULL); + if (FAILED (hr)) + { + g_warning ("IXmlReader_GetPrefix() for application manifest `%S':%u (column %u) for package #%zu (`%S') failed with HRESULT 0x%lx", + sax->manifest_filename, xml_line_number, xml_line_position, sax->package_index, sax->wcs_full_name, hr); + return FALSE; + } + + hr = IXmlReader_GetValue (xml_reader, value, NULL); + if (FAILED (hr)) + { + g_warning ("IXmlReader_GetValue() for application manifest `%S':%u (column %u) for package #%zu (`%S') failed with HRESULT 0x%lx", + sax->manifest_filename, xml_line_number, xml_line_position, sax->package_index, sax->wcs_full_name, hr); + return FALSE; + } + + return TRUE; +} + +static gboolean +xml_parser_iteration (struct _xml_sax_state *sax, + IXmlReader *xml_reader) +{ + HRESULT hr; + XmlNodeType xml_node_type; + const wchar_t *local_name; + const wchar_t *prefix; + const wchar_t *value; + BOOL is_visual_elements = FALSE; + BOOL is_extension = FALSE; + BOOL is_protocol = FALSE; + BOOL is_empty; + BOOL is_application = FALSE; + BOOL is_verb = FALSE; + + hr = IXmlReader_Read (xml_reader, &xml_node_type); + if (FAILED (hr)) + { + g_warning ("IXmlReader_Read() for application manifest `%S' for package #%zu (`%S') failed with HRESULT 0x%lx", + sax->manifest_filename, sax->package_index, sax->wcs_full_name, hr); + return FALSE; + } + + if (!xml_parser_get_current_state (sax, xml_reader, &local_name, &prefix, &value)) + return FALSE; + + switch (xml_node_type) + { + case XmlNodeType_Element: + is_empty = IXmlReader_IsEmptyElement (xml_reader); + g_assert (local_name != NULL); + + if (!is_empty && + _wcsicmp (local_name, L"Package") == 0 && + prefix[0] == 0) + sax->in_package += 1; + else if (!is_empty && + sax->in_package == 1 && + _wcsicmp (local_name, L"Applications") == 0 && + prefix[0] == 0) + sax->in_applications += 1; + else if (!is_empty && + sax->in_applications == 1 && + _wcsicmp (local_name, L"Application") == 0 && + prefix[0] == 0) + { + sax->in_application += 1; + is_application = TRUE; + sax->applist = TRUE; + g_clear_pointer (&sax->application_usermodelid, g_free); + } + else if (sax->in_application == 1 && + _wcsicmp (local_name, L"VisualElements") == 0 && + (_wcsicmp (prefix, L"uap") == 0 || _wcsicmp (prefix, L"uap3") == 0)) + is_visual_elements = TRUE; + else if (!is_empty && + sax->in_application == 1 && + _wcsicmp (local_name, L"Extensions") == 0 && + prefix[0] == 0) + sax->in_extensions += 1; + else if (!is_empty && + sax->in_application == 1 && + _wcsicmp (local_name, L"Extension") == 0 && + _wcsicmp (prefix, L"uap") == 0) + is_extension = TRUE; + else if (sax->in_extension_protocol == 1 && + _wcsicmp (local_name, L"Protocol") == 0 && + _wcsicmp (prefix, L"uap") == 0) + is_protocol = TRUE; + else if (!is_empty && + sax->in_extension_fta == 1 && + _wcsicmp (local_name, L"FileTypeAssociation") == 0 && + _wcsicmp (prefix, L"uap") == 0) + sax->in_fta_group += 1; + else if (!is_empty && + sax->in_fta_group == 1 && + _wcsicmp (local_name, L"SupportedFileTypes") == 0 && + _wcsicmp (prefix, L"uap") == 0) + sax->in_sfp += 1; + else if (!is_empty && + sax->in_fta_group == 1 && + _wcsicmp (local_name, L"SupportedVerbs") == 0 && + _wcsicmp (prefix, L"uap2") == 0) + sax->in_sv += 1; + else if (!is_empty && + sax->in_sfp == 1 && + _wcsicmp (local_name, L"FileType") == 0 && + _wcsicmp (prefix, L"uap") == 0) + sax->in_filetype += 1; + else if (!is_empty && + sax->in_sv == 1 && + _wcsicmp (local_name, L"Verb") == 0 && + _wcsicmp (prefix, L"uap3") == 0) + is_verb = TRUE; + + hr = IXmlReader_MoveToFirstAttribute (xml_reader); + while (hr == S_OK) + { + if (!xml_parser_get_current_state (sax, xml_reader, &local_name, &prefix, &value)) + return FALSE; + + g_assert (local_name != NULL); + g_assert (value != NULL); + g_assert (prefix != NULL); + + if (is_application && + sax->application_usermodelid == NULL && + _wcsicmp (local_name, L"Id") == 0) + { + size_t id_len = 0; + size_t value_len = wcslen (value); + const wchar_t *wcs_package_family; + size_t wcs_package_family_len; + + wcs_package_family = sax_WindowsGetStringRawBuffer (sax->package_family, NULL); + wcs_package_family_len = wcslen (wcs_package_family); + id_len += wcs_package_family_len + 1 + value_len; + sax->application_usermodelid = g_new (wchar_t, id_len + 1); + /* AppUserModelId = ! */ + memcpy (&sax->application_usermodelid[0], wcs_package_family, wcs_package_family_len * sizeof (wchar_t)); + memcpy (&sax->application_usermodelid[wcs_package_family_len], L"!", sizeof (wchar_t)); + memcpy (&sax->application_usermodelid[wcs_package_family_len + 1], value, (value_len + 1) * sizeof (wchar_t)); + } + else if (is_visual_elements && + _wcsicmp (local_name, L"AppListEntry") == 0 && + _wcsicmp (value, L"none") == 0) + sax->applist = FALSE; + else if (is_extension && + _wcsicmp (local_name, L"Category") == 0 && + _wcsicmp (value, L"windows.protocol") == 0) + sax->in_extension_protocol += 1; + else if (is_extension && + _wcsicmp (local_name, L"Category") == 0 && + _wcsicmp (value, L"windows.fileTypeAssociation") == 0) + sax->in_extension_fta += 1; + else if (is_protocol && + _wcsicmp (local_name, L"Name") == 0) + g_ptr_array_add (sax->supported_protocols, g_wcsdup (value, -1)); + else if (is_verb && + _wcsicmp (local_name, L"Id") == 0) + g_ptr_array_add (sax->supported_verbs, g_wcsdup (value, -1)); + + hr = IXmlReader_MoveToNextAttribute (xml_reader); + } + break; + case XmlNodeType_Text: + g_assert (value != NULL); + + if (sax->in_filetype && value[0] != 0) + g_ptr_array_add (sax->supported_extensions, g_wcsdup (value, -1)); + break; + case XmlNodeType_EndElement: + g_assert (local_name != NULL); + + if (_wcsicmp (local_name, L"Package") == 0 && + prefix[0] == 0) + sax->in_package -= 1; + else if (sax->in_package == 1 && + _wcsicmp (local_name, L"Applications") == 0 && + prefix[0] == 0) + sax->in_applications -= 1; + else if (sax->in_application == 1 && + _wcsicmp (local_name, L"Extensions") == 0 && + prefix[0] == 0) + sax->in_extensions -= 1; + else if (sax->in_extension_protocol == 1 && + _wcsicmp (local_name, L"Extension") == 0 && + _wcsicmp (prefix, L"uap") == 0) + sax->in_extension_protocol -= 1; + else if (sax->in_extension_fta == 1 && + _wcsicmp (local_name, L"Extension") == 0 && + _wcsicmp (prefix, L"uap") == 0) + sax->in_extension_fta -= 1; + else if (sax->in_fta_group == 1 && + _wcsicmp (local_name, L"SupportedFileTypes") == 0 && + _wcsicmp (prefix, L"uap") == 0) + sax->in_sfp -= 1; + else if (sax->in_sfp == 1 && + _wcsicmp (local_name, L"FileType") == 0 && + _wcsicmp (prefix, L"uap") == 0) + sax->in_filetype -= 1; + else if (sax->in_fta_group == 1 && + _wcsicmp (local_name, L"SupportedVerbs") == 0 && + _wcsicmp (prefix, L"uap2") == 0) + sax->in_sv -= 1; + else if (sax->in_applications == 1 && + _wcsicmp (local_name, L"Application") == 0 && + prefix[0] == 0) + { + if (sax->application_usermodelid != NULL) + sax->exit_early = !sax->callback (sax->user_data, sax->wcs_full_name, sax->wcs_name, + sax->application_usermodelid, sax->applist, + sax->supported_extgroups, sax->supported_protocols); + g_clear_pointer (&sax->supported_extgroups, g_ptr_array_unref); + g_clear_pointer (&sax->supported_protocols, g_ptr_array_unref); + sax->supported_protocols = g_ptr_array_new_full (0, (GDestroyNotify) g_free); + sax->supported_extgroups = g_ptr_array_new_full (0, (GDestroyNotify) free_extgroup); + sax->in_application -= 1; + } + else if (sax->in_extension_fta == 1 && + _wcsicmp (local_name, L"FileTypeAssociation") == 0 && + _wcsicmp (prefix, L"uap") == 0) + { + GWin32PackageExtGroup *new_group = g_new0 (GWin32PackageExtGroup, 1); + new_group->extensions = g_steal_pointer (&sax->supported_extensions); + sax->supported_extensions = g_ptr_array_new_full (0, (GDestroyNotify) g_free); + new_group->verbs = g_steal_pointer (&sax->supported_verbs); + sax->supported_verbs = g_ptr_array_new_full (0, (GDestroyNotify) g_free); + g_ptr_array_add (sax->supported_extgroups, new_group); + sax->in_fta_group -= 1; + } + break; + default: + break; + } + + return TRUE; +} diff --git a/gio/gwin32packageparser.h b/gio/gwin32packageparser.h new file mode 100755 index 0000000..f55e30c --- /dev/null +++ b/gio/gwin32packageparser.h @@ -0,0 +1,48 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2020 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ +#ifndef __G_WIN32_PACKAGE_PARSER_H__ +#define __G_WIN32_PACKAGE_PARSER_H__ + +#include + +#ifdef G_PLATFORM_WIN32 + +typedef struct _GWin32PackageExtGroup GWin32PackageExtGroup; + +struct _GWin32PackageExtGroup +{ + GPtrArray *verbs; + GPtrArray *extensions; +}; + +typedef gboolean (*GWin32PackageParserCallback)(gpointer user_data, + const gunichar2 *full_package_name, + const gunichar2 *package_name, + const gunichar2 *app_user_model_id, + gboolean show_in_applist, + GPtrArray *supported_extgroups, + GPtrArray *supported_protocols); + +gboolean g_win32_package_parser_enum_packages (GWin32PackageParserCallback callback, + gpointer user_data, + GError **error); + +#endif /* G_PLATFORM_WIN32 */ + +#endif /* __G_WIN32_PACKAGE_PARSER_H__ */ \ No newline at end of file diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c new file mode 100644 index 0000000..5e2b006 --- /dev/null +++ b/gio/gwin32registrykey.c @@ -0,0 +1,2728 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2014 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ + +#include "config.h" +#include "ginitable.h" +#include "gwin32registrykey.h" +#include +#ifdef _MSC_VER +#pragma warning ( disable:4005 ) +#endif +#include +#include +#include + +#ifndef _WDMDDK_ +typedef enum _KEY_INFORMATION_CLASS { + KeyBasicInformation, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation, + KeyCachedInformation, + KeyFlagsInformation, + KeyVirtualizationInformation, + KeyHandleTagsInformation, + MaxKeyInfoClass +} KEY_INFORMATION_CLASS; + +typedef struct _KEY_BASIC_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG NameLength; + WCHAR Name[1]; +} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION; +#endif + +#if !defined (__OBJECT_ATTRIBUTES_DEFINED) && defined (__MINGW32_) +#define __OBJECT_ATTRIBUTES_DEFINED + typedef struct _OBJECT_ATTRIBUTES { + ULONG Length; +#ifdef _WIN64 + ULONG pad1; +#endif + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; +#ifdef _WIN64 + ULONG pad2; +#endif + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; + } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; +#endif + +#ifndef HKEY_CURRENT_USER_LOCAL_SETTINGS +#define HKEY_CURRENT_USER_LOCAL_SETTINGS ((HKEY) (ULONG_PTR)((LONG)0x80000007)) +#endif + +#if !defined (__UNICODE_STRING_DEFINED) && defined (__MINGW32_) +#define __UNICODE_STRING_DEFINED +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING, *PUNICODE_STRING; +#endif +typedef const UNICODE_STRING* PCUNICODE_STRING; + +typedef NTSTATUS +(NTAPI * NtQueryKeyFunc)(HANDLE key_handle, + KEY_INFORMATION_CLASS key_info_class, + PVOID key_info_buffer, + ULONG key_info_buffer_size, + PULONG result_size); + +typedef NTSTATUS +(NTAPI * NtNotifyChangeMultipleKeysFunc)(HANDLE key_handle, + ULONG subkey_count, + POBJECT_ATTRIBUTES subkeys, + HANDLE event, + PIO_APC_ROUTINE apc_routine, + PVOID apc_closure, + PIO_STATUS_BLOCK status_block, + ULONG filter, + BOOLEAN watch_tree, + PVOID buffer, + ULONG buffer_size, + BOOLEAN async); + +static NtQueryKeyFunc nt_query_key = NULL; +static NtNotifyChangeMultipleKeysFunc nt_notify_change_multiple_keys = NULL; + +#define G_WIN32_KEY_UNWATCHED 0 +#define G_WIN32_KEY_WATCHED 1 +#define G_WIN32_KEY_UNCHANGED 0 +#define G_WIN32_KEY_CHANGED 1 +#define G_WIN32_KEY_UNKNOWN -1 + +enum +{ + PROP_0, + PROP_PATH, + PROP_PATH_UTF16, + PROP_MAX, +}; + +typedef enum +{ + G_WIN32_REGISTRY_UPDATED_NOTHING = 0, + G_WIN32_REGISTRY_UPDATED_PATH = 1, +} GWin32RegistryKeyUpdateFlag; + +static gsize +g_utf16_len (const gunichar2 *str) +{ + gsize result; + + for (result = 0; str[0] != 0; str++, result++) + ; + + return result; +} + +static gunichar2 * +g_wcsdup (const gunichar2 *str, gssize str_len) +{ + gsize str_len_unsigned; + gsize str_size; + + g_return_val_if_fail (str != NULL, NULL); + + if (str_len < 0) + str_len_unsigned = g_utf16_len (str); + else + str_len_unsigned = (gsize) str_len; + + g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1); + str_size = (str_len_unsigned + 1) * sizeof (gunichar2); + + return g_memdup2 (str, str_size); +} + +/** + * g_win32_registry_subkey_iter_copy: + * @iter: an iterator + * + * Creates a dynamically-allocated copy of an iterator. Dynamically-allocated + * state of the iterator is duplicated too. + * + * Returns: (transfer full): a copy of the @iter, + * free with g_win32_registry_subkey_iter_free () + * + * Since: 2.46 + **/ +GWin32RegistrySubkeyIter * +g_win32_registry_subkey_iter_copy (const GWin32RegistrySubkeyIter *iter) +{ + GWin32RegistrySubkeyIter *new_iter; + + g_return_val_if_fail (iter != NULL, NULL); + + new_iter = g_new0 (GWin32RegistrySubkeyIter, 1); + + new_iter->key = g_object_ref (iter->key); + new_iter->counter = iter->counter; + new_iter->subkey_count = iter->subkey_count; + new_iter->subkey_name = g_wcsdup (iter->subkey_name, iter->subkey_name_size); + new_iter->subkey_name_size = iter->subkey_name_size; + + if (iter->subkey_name_u8) + new_iter->subkey_name_u8 = iter->subkey_name_u8; + else + new_iter->subkey_name_u8 = NULL; + + return new_iter; +} + +/** + * g_win32_registry_subkey_iter_free: + * @iter: a dynamically-allocated iterator + * + * Free an iterator allocated on the heap. For iterators that are allocated + * on the stack use g_win32_registry_subkey_iter_clear () instead. + * + * Since: 2.46 + **/ +void +g_win32_registry_subkey_iter_free (GWin32RegistrySubkeyIter *iter) +{ + g_return_if_fail (iter != NULL); + + g_object_unref (iter->key); + g_free (iter->subkey_name); + g_free (iter->subkey_name_u8); + g_free (iter); +} + +/** + * g_win32_registry_subkey_iter_assign: + * @iter: a #GWin32RegistrySubkeyIter + * @other: another #GWin32RegistrySubkeyIter + * + * Assigns the value of @other to @iter. This function + * is not useful in applications, because iterators can be assigned + * with `GWin32RegistrySubkeyIter i = j;`. The + * function is used by language bindings. + * + * Since: 2.46 + **/ +void +g_win32_registry_subkey_iter_assign (GWin32RegistrySubkeyIter *iter, + const GWin32RegistrySubkeyIter *other) +{ + g_return_if_fail (iter != NULL); + g_return_if_fail (other != NULL); + + *iter = *other; +} + + +G_DEFINE_BOXED_TYPE (GWin32RegistrySubkeyIter, g_win32_registry_subkey_iter, + g_win32_registry_subkey_iter_copy, + g_win32_registry_subkey_iter_free) + +/** + * g_win32_registry_value_iter_copy: + * @iter: an iterator + * + * Creates a dynamically-allocated copy of an iterator. Dynamically-allocated + * state of the iterator is duplicated too. + * + * Returns: (transfer full): a copy of the @iter, + * free with g_win32_registry_value_iter_free (). + * + * Since: 2.46 + **/ +GWin32RegistryValueIter * +g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter) +{ + GWin32RegistryValueIter *new_iter; + + g_return_val_if_fail (iter != NULL, NULL); + + new_iter = g_new0 (GWin32RegistryValueIter, 1); + + new_iter->key = g_object_ref (iter->key); + new_iter->counter = iter->counter; + new_iter->value_count = iter->value_count; + new_iter->value_name = g_wcsdup (iter->value_name, iter->value_name_size); + new_iter->value_name_size = iter->value_name_size; + + if (iter->value_data != NULL) + new_iter->value_data = g_memdup2 (iter->value_data, iter->value_data_size); + + new_iter->value_data_size = iter->value_data_size; + + if (iter->value_name_u8 != NULL) + new_iter->value_name_u8 = g_strdup (iter->value_name_u8); + + new_iter->value_name_u8_len = iter->value_name_u8_len; + + if (iter->value_data_u8 != NULL) + new_iter->value_data_u8 = g_strdup (iter->value_data_u8); + + new_iter->value_data_u8_size = iter->value_data_u8_size; + + if (iter->value_data_expanded != NULL) + new_iter->value_data_expanded = g_wcsdup ((gunichar2 *) iter->value_data_expanded, + iter->value_data_expanded_charsize * sizeof (gunichar2)); + + new_iter->value_data_expanded_charsize = iter->value_data_expanded_charsize; + + if (iter->value_data_expanded_u8 != NULL) + new_iter->value_data_expanded_u8 = g_memdup2 (iter->value_data_expanded_u8, + iter->value_data_expanded_charsize); + + new_iter->value_data_expanded_u8_size = iter->value_data_expanded_charsize; + + return new_iter; +} + +/** + * g_win32_registry_value_iter_free: + * @iter: a dynamically-allocated iterator + * + * Free an iterator allocated on the heap. For iterators that are allocated + * on the stack use g_win32_registry_value_iter_clear () instead. + * + * Since: 2.46 + **/ +void +g_win32_registry_value_iter_free (GWin32RegistryValueIter *iter) +{ + g_return_if_fail (iter != NULL); + + g_object_unref (iter->key); + g_free (iter->value_name); + g_free (iter->value_data); + g_free (iter->value_data_expanded); + g_free (iter->value_name_u8); + g_free (iter->value_data_u8); + g_free (iter->value_data_expanded_u8); + g_free (iter); +} + +/** + * g_win32_registry_value_iter_assign: + * @iter: a #GWin32RegistryValueIter + * @other: another #GWin32RegistryValueIter + * + * Assigns the value of @other to @iter. This function + * is not useful in applications, because iterators can be assigned + * with `GWin32RegistryValueIter i = j;`. The + * function is used by language bindings. + * + * Since: 2.46 + **/ +void +g_win32_registry_value_iter_assign (GWin32RegistryValueIter *iter, + const GWin32RegistryValueIter *other) +{ + g_return_if_fail (iter != NULL); + g_return_if_fail (other != NULL); + + *iter = *other; +} + +G_DEFINE_BOXED_TYPE (GWin32RegistryValueIter, g_win32_registry_value_iter, + g_win32_registry_value_iter_copy, + g_win32_registry_value_iter_free) + +/** + * SECTION:gwin32registrykey + * @title: GWin32RegistryKey + * @short_description: W32 registry access helper + * @include: gio/win32/gwin32registrykey.h + * + * #GWin32RegistryKey represents a single Windows Registry key. + * + * #GWin32RegistryKey is used by a number of helper functions that read + * Windows Registry. All keys are opened with read-only access, and at + * the moment there is no API for writing into registry keys or creating + * new ones. + * + * #GWin32RegistryKey implements the #GInitable interface, so if it is manually + * constructed by e.g. g_object_new() you must call g_initable_init() and check + * the results before using the object. This is done automatically + * in g_win32_registry_key_new() and g_win32_registry_key_get_child(), so these + * functions can return %NULL. + * + * To increase efficiency, a UTF-16 variant is available for all functions + * that deal with key or value names in the registry. Use these to perform + * deep registry queries or other operations that require querying a name + * of a key or a value and then opening it (or querying its data). The use + * of UTF-16 functions avoids the overhead of converting names to UTF-8 and + * back. + * + * All functions operate in current user's context (it is not possible to + * access registry tree of a different user). + * + * Key paths must use '\\' as a separator, '/' is not supported. Key names + * must not include '\\', because it's used as a separator. Value names + * can include '\\'. + * + * Key and value names are not case sensitive. + * + * Full key name (excluding the pre-defined ancestor's name) can't exceed + * 255 UTF-16 characters, give or take. Value name can't exceed 16383 UTF-16 + * characters. Tree depth is limited to 512 levels. + **/ + +struct _GWin32RegistryKeyPrivate { + /* Ancestor of this key. May not be the immediate parent, because + * RegOpenKeyEx() allows grand*-children to be opened transitively. + * May be NULL. + */ + GWin32RegistryKey *ancestor; + + /* Handle to the key */ + HKEY handle; + + /* Full absolute path of the key, in UTF-16. Always allocated. + * Can become out of sync if the key is renamed from while we have it + * open, check watch_indicator to see if anything changed. + */ + gunichar2 *absolute_path_w; + + /* Full absolute path of the key, in UTF-8. Allocated when needed by + * converting the UTF-16 value from absolute_path_w. */ + gchar *absolute_path; + + /* TRUE if this object represents one of the pre-defined keys + * (and thus must not be closed). + */ + gboolean predefined; + + /* Set to G_WIN32_KEY_UNWATCHED if the key is not being watched. + * Set to G_WIN32_KEY_WATCHED when the key is put on watch notification. + */ + gint watch_indicator; + + /* Set to G_WIN32_KEY_UNKNOWN while the key is not being watched. + * Set to G_WIN32_KEY_UNCHANGED once the key is put under watch. + * Set to G_WIN32_KEY_CHANGED by the watch notification APC on key change. + */ + gint change_indicator; + + /* Unset after the key is changed, individual bits are set when their + * respective key parameters are updated from the registry. + * This prevents GLib from re-querying things like key name each time + * one is requested by the client while key is in G_WIN32_KEY_CHANGED state. + */ + GWin32RegistryKeyUpdateFlag update_flags; + + GWin32RegistryKeyWatchCallbackFunc callback; + + gpointer user_data; +}; + +static void g_win32_registry_key_initable_iface_init (GInitableIface *iface); +static gboolean g_win32_registry_key_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error); + +G_DEFINE_TYPE_WITH_CODE (GWin32RegistryKey, g_win32_registry_key, G_TYPE_OBJECT, + G_ADD_PRIVATE (GWin32RegistryKey) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_win32_registry_key_initable_iface_init)); + +static void +g_win32_registry_key_dispose (GObject *object) +{ + GWin32RegistryKey *key; + GWin32RegistryKeyPrivate *priv; + + key = G_WIN32_REGISTRY_KEY (object); + priv = key->priv; + + g_clear_object (&priv->ancestor); + g_clear_pointer (&priv->absolute_path_w, g_free); + g_clear_pointer (&priv->absolute_path, g_free); + + if (!priv->predefined && priv->handle != INVALID_HANDLE_VALUE) + { + RegCloseKey (priv->handle); + priv->handle = INVALID_HANDLE_VALUE; + } + + G_OBJECT_CLASS (g_win32_registry_key_parent_class)->dispose (object); +} + +/** + * g_win32_registry_key_new: + * @path: absolute full name of a key to open (in UTF-8) + * @error: (nullable): a pointer to a %NULL #GError, or %NULL + * + * Creates an object that represents a registry key specified by @path. + * @path must start with one of the following pre-defined names: + * - HKEY_CLASSES_ROOT + * - HKEY_CURRENT_CONFIG + * - HKEY_CURRENT_USER + * - HKEY_CURRENT_USER_LOCAL_SETTINGS + * - HKEY_LOCAL_MACHINE + * - HKEY_PERFORMANCE_DATA + * - HKEY_PERFORMANCE_NLSTEXT + * - HKEY_PERFORMANCE_TEXT + * - HKEY_USERS + * @path must not end with '\\'. + * + * Returns: (nullable) (transfer full): a #GWin32RegistryKey or %NULL if can't + * be opened. Free with g_object_unref(). + */ +GWin32RegistryKey * +g_win32_registry_key_new (const gchar *path, + GError **error) +{ + g_return_val_if_fail (path != NULL, NULL); + + return g_initable_new (G_TYPE_WIN32_REGISTRY_KEY, + NULL, + error, + "path", + path, + NULL); +} + +/** + * g_win32_registry_key_new_w: + * @path: (in) (transfer none): absolute full name of a key to open (in UTF-16) + * @error: (inout) (optional) (nullable): a pointer to a %NULL #GError, or %NULL + * + * Creates an object that represents a registry key specified by @path. + * @path must start with one of the following pre-defined names: + * - HKEY_CLASSES_ROOT + * - HKEY_CURRENT_CONFIG + * - HKEY_CURRENT_USER + * - HKEY_CURRENT_USER_LOCAL_SETTINGS + * - HKEY_LOCAL_MACHINE + * - HKEY_PERFORMANCE_DATA + * - HKEY_PERFORMANCE_NLSTEXT + * - HKEY_PERFORMANCE_TEXT + * - HKEY_USERS + * @path must not end with L'\\'. + * + * Returns: (nullable) (transfer full): a #GWin32RegistryKey or %NULL if can't + * be opened. Free with g_object_unref(). + */ +GWin32RegistryKey * +g_win32_registry_key_new_w (const gunichar2 *path, + GError **error) +{ + GObject *result; + + g_return_val_if_fail (path != NULL, NULL); + + result = g_initable_new (G_TYPE_WIN32_REGISTRY_KEY, + NULL, + error, + "path-utf16", + g_wcsdup (path, -1), + NULL); + + return result ? G_WIN32_REGISTRY_KEY (result) : NULL; +} + +static void +g_win32_registry_key_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_win32_registry_key_initable_init; +} + +static gboolean +g_win32_registry_key_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + GWin32RegistryKey *key; + GWin32RegistryKeyPrivate *priv; + gunichar2 *path; + gunichar2 *first_chunk_end; + gsize first_chunk_len; + gunichar2 *second_chunk_begin; + gunichar2 *first_chunk; + HKEY ancestor; + HKEY key_handle; + LONG opened; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (initable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + key = G_WIN32_REGISTRY_KEY (initable); + priv = key->priv; + + if (priv->absolute_path_w == NULL) + { + priv->absolute_path_w = g_utf8_to_utf16 (priv->absolute_path, + -1, + NULL, + NULL, + error); + + if (priv->absolute_path_w == NULL) + return FALSE; + } + + path = priv->absolute_path_w; + + first_chunk_end = wcschr (path, L'\\'); + + if (first_chunk_end == NULL) + first_chunk_end = &path[wcslen (path)]; + + first_chunk_len = first_chunk_end - path; + first_chunk = g_wcsdup (path, -1); + first_chunk[first_chunk_len] = L'\0'; + if (wcscmp (first_chunk, L"HKEY_CLASSES_ROOT") == 0) + ancestor = HKEY_CLASSES_ROOT; + else if (wcscmp (first_chunk, L"HKEY_LOCAL_MACHINE") == 0) + ancestor = HKEY_LOCAL_MACHINE; + else if (wcscmp (first_chunk, L"HKEY_CURRENT_USER") == 0) + ancestor = HKEY_CURRENT_USER; + else if (wcscmp (first_chunk, L"HKEY_CURRENT_CONFIG") == 0) + ancestor = HKEY_CURRENT_CONFIG; + else if (wcscmp (first_chunk, L"HKEY_CURRENT_USER_LOCAL_SETTINGS") == 0) + ancestor = HKEY_CURRENT_USER_LOCAL_SETTINGS; + else if (wcscmp (first_chunk, L"HKEY_USERS") == 0) + ancestor = HKEY_USERS; + else if (wcscmp (first_chunk, L"HKEY_PERFORMANCE_DATA") == 0) + ancestor = HKEY_PERFORMANCE_DATA; + else if (wcscmp (first_chunk, L"HKEY_PERFORMANCE_NLSTEXT") == 0) + ancestor = HKEY_PERFORMANCE_NLSTEXT; + else if (wcscmp (first_chunk, L"HKEY_PERFORMANCE_TEXT") == 0) + ancestor = HKEY_PERFORMANCE_TEXT; + else + { + g_critical ("Root key '%S' is not a pre-defined key", first_chunk); + g_free (first_chunk); + return FALSE; + } + + g_free (first_chunk); + + second_chunk_begin = first_chunk_end; + + while (second_chunk_begin[0] != L'\0' && second_chunk_begin[0] == L'\\') + second_chunk_begin++; + + if (second_chunk_begin != first_chunk_end && second_chunk_begin[0] == L'\0') + { + g_critical ("Key name '%S' ends with '\\'", path); + return FALSE; + } + + opened = RegOpenKeyExW (ancestor, second_chunk_begin, 0, KEY_READ, &key_handle); + + if (opened != ERROR_SUCCESS) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (opened), + "Failed to open registry key '%S'", path); + return FALSE; + } + + priv->ancestor = NULL; + priv->handle = key_handle; + priv->predefined = (second_chunk_begin[0] == L'\0'); + + return TRUE; +} + +/** + * g_win32_registry_key_get_child: + * @key: (in) (transfer none): a parent #GWin32RegistryKey + * @subkey: (in) (transfer none): name of a child key to open (in UTF-8), relative to @key + * @error: (inout) (optional) (nullable): a pointer to a %NULL #GError, or %NULL + * + * Opens a @subkey of the @key. + * + * Returns: (nullable): a #GWin32RegistryKey or %NULL if can't be opened. Free + * with g_object_unref(). + */ +GWin32RegistryKey * +g_win32_registry_key_get_child (GWin32RegistryKey *key, + const gchar *subkey, + GError **error) +{ + gunichar2 *subkey_w; + GWin32RegistryKey *result = NULL; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), NULL); + g_return_val_if_fail (subkey != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + subkey_w = g_utf8_to_utf16 (subkey, -1, NULL, NULL, error); + + if (subkey_w != NULL) + { + result = g_win32_registry_key_get_child_w (key, subkey_w, error); + g_free (subkey_w); + } + + return result; +} + +/** + * g_win32_registry_key_get_child_w: + * @key: (in) (transfer none): a parent #GWin32RegistryKey + * @subkey: (in) (transfer none): name of a child key to open (in UTF-8), relative to @key + * @error: (inout) (optional) (nullable): a pointer to a %NULL #GError, or %NULL + * + * Opens a @subkey of the @key. + * + * Returns: (nullable): a #GWin32RegistryKey or %NULL if can't be opened. Free + * with g_object_unref(). + */ +GWin32RegistryKey * +g_win32_registry_key_get_child_w (GWin32RegistryKey *key, + const gunichar2 *subkey, + GError **error) +{ + HKEY key_handle; + LONG opened; + const gunichar2 *end_of_subkey; + gsize subkey_len; + GWin32RegistryKey *result; + const gunichar2 *key_path; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), NULL); + g_return_val_if_fail (subkey != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (subkey[0] == L'\\') + { + g_critical ("Subkey name '%S' starts with '\\'", subkey); + return NULL; + } + + subkey_len = wcslen (subkey); + end_of_subkey = &subkey[subkey_len]; + + if (subkey_len == 0) + end_of_subkey = subkey; + + if (end_of_subkey[0] == L'\\') + { + g_critical ("Subkey name '%S' ends with '\\'", subkey); + return NULL; + } + + key_path = g_win32_registry_key_get_path_w (key); + opened = RegOpenKeyExW (key->priv->handle, subkey, 0, KEY_READ, &key_handle); + + if (opened != ERROR_SUCCESS) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (opened), + "Failed to open registry subkey '%S' of key '%S'", + subkey, key_path); + return NULL; + } + + result = g_object_new (G_TYPE_WIN32_REGISTRY_KEY, NULL); + + result->priv->handle = key_handle; + result->priv->absolute_path_w = + g_malloc ((wcslen (key_path) + 2 + subkey_len) * sizeof (gunichar2)); + result->priv->absolute_path_w[0] = L'\0'; + wcscat (&result->priv->absolute_path_w[0], key_path); + wcscat (&result->priv->absolute_path_w[wcslen (key_path)], L"\\"); + wcscat (&result->priv->absolute_path_w[wcslen (key_path) + 1], subkey); + result->priv->predefined = (subkey[0] == L'\0' && key->priv->predefined); + + if (subkey[0] != L'\0') + result->priv->ancestor = g_object_ref (key); + else + result->priv->ancestor = NULL; + + result->priv->change_indicator = G_WIN32_KEY_UNKNOWN; + + return result; +} + +/** + * g_win32_registry_subkey_iter_init: + * @iter: (in) (transfer none): a pointer to a #GWin32RegistrySubkeyIter + * @key: (in) (transfer none): a #GWin32RegistryKey to iterate over + * @error: (inout) (optional) (nullable): a pointer to %NULL #GError, or %NULL + * + * Initialises (without allocating) a #GWin32RegistrySubkeyIter. @iter may be + * completely uninitialised prior to this call; its old value is + * ignored. + * + * The iterator remains valid for as long as @key exists. + * Clean up its internal buffers with a call to + * g_win32_registry_subkey_iter_clear() when done. + * + * Returns: %TRUE if iterator was initialized successfully, %FALSE on error. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_subkey_iter_init (GWin32RegistrySubkeyIter *iter, + GWin32RegistryKey *key, + GError **error) +{ + LONG status; + DWORD subkey_count; + DWORD max_subkey_len; + + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + status = RegQueryInfoKeyW (key->priv->handle, + NULL, NULL, NULL, + &subkey_count, &max_subkey_len, + NULL, NULL, NULL, NULL, NULL, NULL); + + if (status != ERROR_SUCCESS) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status), + "Failed to query info for registry key '%S'", + g_win32_registry_key_get_path_w (key)); + return FALSE; + } + + iter->key = g_object_ref (key); + iter->counter = -1; + iter->subkey_count = subkey_count; + iter->subkey_name_size = sizeof (gunichar2) * (max_subkey_len + 1); + iter->subkey_name = g_malloc (iter->subkey_name_size); + iter->subkey_name_u8 = NULL; + + return TRUE; +} + +/** + * g_win32_registry_subkey_iter_clear: + * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter + * + * Frees internal buffers of a #GWin32RegistrySubkeyIter. + * + * Since: 2.46 + **/ +void +g_win32_registry_subkey_iter_clear (GWin32RegistrySubkeyIter *iter) +{ + g_return_if_fail (iter != NULL); + + g_free (iter->subkey_name); + g_free (iter->subkey_name_u8); + g_clear_object (&iter->key); +} + +/** + * g_win32_registry_subkey_iter_n_subkeys: + * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter + * + * Queries the number of subkeys items in the key that we are + * iterating over. This is the total number of subkeys -- not the number + * of items remaining. + * + * This information is accurate at the point of iterator initialization, + * and may go out of sync with reality even while subkeys are enumerated. + * + * Returns: the number of subkeys in the key + * + * Since: 2.46 + **/ +gsize +g_win32_registry_subkey_iter_n_subkeys (GWin32RegistrySubkeyIter *iter) +{ + g_return_val_if_fail (iter != NULL, 0); + + return iter->subkey_count; +} + +/** + * g_win32_registry_subkey_iter_next: + * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter + * @skip_errors: (in): %TRUE if iterator should silently ignore errors (such as + * the actual number of subkeys being less than expected) and + * proceed forward + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Moves iterator to the next subkey. + * Enumeration errors can be ignored if @skip_errors is %TRUE + * + * Here is an example for iterating with g_win32_registry_subkey_iter_next(): + * |[ + * // recursively iterate a key + * void + * iterate_key_recursive (GWin32RegistryKey *key) + * { + * GWin32RegistrySubkeyIter iter; + * gchar *name; + * GWin32RegistryKey *child; + * + * if (!g_win32_registry_subkey_iter_init (&iter, key, NULL)) + * return; + * + * while (g_win32_registry_subkey_iter_next (&iter, TRUE, NULL)) + * { + * if (!g_win32_registry_subkey_iter_get_name (&iter, &name, NULL, NULL)) + * continue; + * + * g_print ("subkey '%s'\n", name); + * child = g_win32_registry_key_get_child (key, name, NULL); + * + * if (child) + * iterate_key_recursive (child); + * } + * + * g_win32_registry_subkey_iter_clear (&iter); + * } + * ]| + * + * Returns: %TRUE if next subkey info was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_subkey_iter_next (GWin32RegistrySubkeyIter *iter, + gboolean skip_errors, + GError **error) +{ + LONG status; + DWORD subkey_len; + + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->subkey_count) + { + g_critical ("g_win32_registry_subkey_iter_get_next_w: must not be called again " + "after FALSE has already been returned."); + return FALSE; + } + + while (TRUE) + { + iter->counter += 1; + + if (iter->counter >= iter->subkey_count) + return FALSE; + + /* Including 0-terminator */ + subkey_len = iter->subkey_name_size; + status = RegEnumKeyExW (iter->key->priv->handle, + iter->counter, + iter->subkey_name, + &subkey_len, + NULL, NULL, NULL, NULL); + + if (status == ERROR_SUCCESS) + { + iter->subkey_name_len = subkey_len; + + return TRUE; + } + + if (!skip_errors) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status), + "Failed to enumerate subkey #%d for key '%S'", + iter->counter, g_win32_registry_key_get_path_w (iter->key)); + iter->subkey_count = 0; + + return FALSE; + } + } +} + +/** + * g_win32_registry_subkey_iter_get_name_w: + * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter + * @subkey_name: (out callee-allocates) (transfer none): Pointer to a location + * to store the name of a subkey (in UTF-16). + * @subkey_name_len: (out) (optional) (transfer none): Pointer to a location + * to store the length of @subkey_name, in gunichar2s, excluding + * NUL-terminator. + * %NULL if length is not needed. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Same as g_win32_registry_subkey_iter_get_next(), but outputs UTF-16-encoded + * data, without converting it to UTF-8 first. + * + * Returns: %TRUE if the name was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_subkey_iter_get_name_w (GWin32RegistrySubkeyIter *iter, + const gunichar2 **subkey_name, + gsize *subkey_name_len, + GError **error) +{ + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (subkey_name != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->subkey_count) + { + g_critical ("g_win32_registry_subkey_iter_get_name_w: must not be called " + "after FALSE has already been returned by " + "g_win32_registry_subkey_iter_next."); + return FALSE; + } + + *subkey_name = iter->subkey_name; + + if (subkey_name_len) + *subkey_name_len = iter->subkey_name_len; + + return TRUE; +} + +/** + * g_win32_registry_subkey_iter_get_name: + * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter + * @subkey_name: (out callee-allocates) (transfer none): Pointer to a location + * to store the name of a subkey (in UTF-8). Free with g_free(). + * @subkey_name_len: (out) (optional): Pointer to a location to store the + * length of @subkey_name, in gchars, excluding NUL-terminator. + * %NULL if length is not needed. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Gets the name of the subkey at the @iter potision. + * + * Returns: %TRUE if the name was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_subkey_iter_get_name (GWin32RegistrySubkeyIter *iter, + const gchar **subkey_name, + gsize *subkey_name_len, + GError **error) +{ + glong subkey_name_len_glong; + + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (subkey_name != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->subkey_count) + { + g_critical ("g_win32_registry_subkey_iter_get_name_w: must not be called " + "after FALSE has already been returned by " + "g_win32_registry_subkey_iter_next."); + return FALSE; + } + + g_clear_pointer (&iter->subkey_name_u8, g_free); + iter->subkey_name_u8 = g_utf16_to_utf8 (iter->subkey_name, + iter->subkey_name_len, + NULL, + &subkey_name_len_glong, + error); + + if (iter->subkey_name_u8 == NULL) + return FALSE; + + *subkey_name = iter->subkey_name_u8; + + if (subkey_name_len) + *subkey_name_len = subkey_name_len_glong; + + return TRUE; +} + +/** + * g_win32_registry_value_iter_init: + * @iter: (in) (transfer none): a pointer to a #GWin32RegistryValueIter + * @key: (in) (transfer none): a #GWin32RegistryKey to iterate over + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Initialises (without allocating) a #GWin32RegistryValueIter. @iter may be + * completely uninitialised prior to this call; its old value is + * ignored. + * + * The iterator remains valid for as long as @key exists. + * Clean up its internal buffers with a call to + * g_win32_registry_value_iter_clear() when done. + * + * Returns: %TRUE if iterator was initialized successfully, %FALSE on error. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_value_iter_init (GWin32RegistryValueIter *iter, + GWin32RegistryKey *key, + GError **error) +{ + LONG status; + DWORD value_count; + DWORD max_value_len; + DWORD max_data_len; + + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + status = RegQueryInfoKeyW (key->priv->handle, + NULL, NULL, NULL, NULL, NULL, NULL, + &value_count, &max_value_len, + &max_data_len, NULL, NULL); + + if (status != ERROR_SUCCESS) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status), + "Failed to query info for registry key '%S'", + g_win32_registry_key_get_path_w (key)); + return FALSE; + } + + iter->key = g_object_ref (key); + iter->counter = -1; + iter->value_count = value_count; + iter->value_name_size = sizeof (gunichar2) * (max_value_len + 1); + iter->value_name = g_malloc (iter->value_name_size); + /* FIXME: max_value_data_len is said to have no size limit in newer W32 + * versions (and its size limit in older ones is 1MB!). Consider limiting it + * with a hard-coded value, or by allowing the user to choose a limit. + */ + /* Two extra gunichar2s is for cases when a string was stored in the + * Registry without a 0-terminator (for multiline strings - 00-terminator), + * and we need to terminate it ourselves. + */ + iter->value_data_size = max_data_len + sizeof (gunichar2) * 2; + iter->value_data = g_malloc (iter->value_data_size); + iter->value_name_u8 = NULL; + iter->value_data_u8 = NULL; + iter->value_data_expanded = NULL; + iter->value_data_expanded_charsize = 0; + iter->value_data_expanded_u8 = NULL; + iter->value_data_expanded_u8_size = 0; + return TRUE; +} + +/** + * g_win32_registry_value_iter_clear: + * @iter: (in) (transfer none): a #GWin32RegistryValueIter + * + * Frees internal buffers of a #GWin32RegistryValueIter. + * + * Since: 2.46 + **/ +void +g_win32_registry_value_iter_clear (GWin32RegistryValueIter *iter) +{ + g_return_if_fail (iter != NULL); + + g_free (iter->value_name); + g_free (iter->value_data); + g_free (iter->value_name_u8); + g_free (iter->value_data_u8); + g_free (iter->value_data_expanded); + g_free (iter->value_data_expanded_u8); + g_clear_object (&iter->key); +} + +/** + * g_win32_registry_value_iter_n_values: + * @iter: (in) (transfer none): a #GWin32RegistryValueIter + * + * Queries the number of values items in the key that we are + * iterating over. This is the total number of values -- not the number + * of items remaining. + * + * This information is accurate at the point of iterator initialization, + * and may go out of sync with reality even while values are enumerated. + * + * Returns: the number of values in the key + * + * Since: 2.46 + **/ +gsize +g_win32_registry_value_iter_n_values (GWin32RegistryValueIter *iter) +{ + g_return_val_if_fail (iter != NULL, 0); + + return iter->value_count; +} + +static GWin32RegistryValueType +_g_win32_registry_type_w_to_g (DWORD value_type) +{ + switch (value_type) + { + case REG_BINARY: + return G_WIN32_REGISTRY_VALUE_BINARY; + case REG_DWORD: + return G_WIN32_REGISTRY_VALUE_UINT32; +#if G_BYTE_ORDER == G_BIG_ENDIAN + case REG_DWORD_LITTLE_ENDIAN: + return G_WIN32_REGISTRY_VALUE_UINT32LE; +#else + case REG_DWORD_BIG_ENDIAN: + return G_WIN32_REGISTRY_VALUE_UINT32BE; +#endif + case REG_EXPAND_SZ: + return G_WIN32_REGISTRY_VALUE_EXPAND_STR; + case REG_LINK: + return G_WIN32_REGISTRY_VALUE_LINK; + case REG_MULTI_SZ: + return G_WIN32_REGISTRY_VALUE_MULTI_STR; + case REG_NONE: + return G_WIN32_REGISTRY_VALUE_NONE; + case REG_QWORD: + return G_WIN32_REGISTRY_VALUE_UINT64; +#if G_BYTE_ORDER == G_BIG_ENDIAN + case REG_QWORD_LITTLE_ENDIAN: + return G_WIN32_REGISTRY_VALUE_UINT64LE; +#endif + case REG_SZ: + return G_WIN32_REGISTRY_VALUE_STR; + default: + return G_WIN32_REGISTRY_VALUE_NONE; + } +} + +static gsize +ensure_nul_termination (GWin32RegistryValueType value_type, + guint8 *value_data, + gsize value_data_size) +{ + gsize new_size = value_data_size; + + if (value_type == G_WIN32_REGISTRY_VALUE_EXPAND_STR || + value_type == G_WIN32_REGISTRY_VALUE_LINK || + value_type == G_WIN32_REGISTRY_VALUE_STR) + { + if ((value_data_size < 2) || + (value_data[value_data_size - 1] != 0) || + (value_data[value_data_size - 2] != 0)) + { + value_data[value_data_size] = 0; + value_data[value_data_size + 1] = 0; + new_size += 2; + } + } + else if (value_type == G_WIN32_REGISTRY_VALUE_MULTI_STR) + { + if ((value_data_size < 4) || + (value_data[value_data_size - 1] != 0) || + (value_data[value_data_size - 2] != 0) || + (value_data[value_data_size - 3] != 0) || + (value_data[value_data_size - 4] != 0)) + { + value_data[value_data_size] = 0; + value_data[value_data_size + 1] = 0; + value_data[value_data_size + 2] = 0; + value_data[value_data_size + 3] = 0; + new_size += 4; + } + } + + return new_size; +} + +/** + * g_win32_registry_value_iter_next: + * @iter: (in) (transfer none): a #GWin32RegistryValueIter + * @skip_errors: (in): %TRUE if iterator should silently ignore errors (such as + * the actual number of values being less than expected) and + * proceed forward + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Advances iterator to the next value in the key. If no more values remain then + * FALSE is returned. + * Enumeration errors can be ignored if @skip_errors is %TRUE + * + * Here is an example for iterating with g_win32_registry_value_iter_next(): + * |[ + * // iterate values of a key + * void + * iterate_values_recursive (GWin32RegistryKey *key) + * { + * GWin32RegistryValueIter iter; + * gchar *name; + * GWin32RegistryValueType val_type; + * gchar *val_data; + * + * if (!g_win32_registry_value_iter_init (&iter, key, NULL)) + * return; + * + * while (g_win32_registry_value_iter_next (&iter, TRUE, NULL)) + * { + * if ((!g_win32_registry_value_iter_get_value_type (&iter, &value)) || + * ((val_type != G_WIN32_REGISTRY_VALUE_STR) && + * (val_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR))) + * continue; + * + * if (g_win32_registry_value_iter_get_value (&iter, TRUE, &name, NULL, + * &val_data, NULL, NULL)) + * g_print ("value '%s' = '%s'\n", name, val_data); + * } + * + * g_win32_registry_value_iter_clear (&iter); + * } + * ]| + * + * Returns: %TRUE if next value info was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_value_iter_next (GWin32RegistryValueIter *iter, + gboolean skip_errors, + GError **error) +{ + LONG status; + DWORD value_name_len_w; + DWORD value_data_size_w; + DWORD value_type_w; + GWin32RegistryValueType value_type_g; + + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->value_count) + { + g_critical ("g_win32_registry_value_iter_next: must not be called " + "again after FALSE has already been returned."); + return FALSE; + } + + while (TRUE) + { + iter->counter += 1; + + if (iter->counter >= iter->value_count) + return FALSE; + + g_clear_pointer (&iter->value_name_u8, g_free); + g_clear_pointer (&iter->value_data_u8, g_free); + g_clear_pointer (&iter->value_data_expanded_u8, g_free); + /* Including 0-terminator */ + value_name_len_w = iter->value_name_size / sizeof (gunichar2); + value_data_size_w = iter->value_data_size; + status = RegEnumValueW (iter->key->priv->handle, + iter->counter, + iter->value_name, + &value_name_len_w, + NULL, + &value_type_w, + (LPBYTE) iter->value_data, + &value_data_size_w); + + if (status != ERROR_SUCCESS && !skip_errors) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status), + "Failed to enumerate value #%d for key '%S'", + iter->counter, g_win32_registry_key_get_path_w (iter->key)); + iter->value_count = 0; + + return FALSE; + } + else if (status != ERROR_SUCCESS && skip_errors) + continue; + + value_type_g = _g_win32_registry_type_w_to_g (value_type_w); + value_data_size_w = ensure_nul_termination (value_type_g, + iter->value_data, + value_data_size_w); + iter->value_type = value_type_g; + iter->value_expanded_type = value_type_g; + iter->value_actual_data_size = value_data_size_w; + iter->value_name_len = value_name_len_w; + + return TRUE; + } +} + +/** + * g_win32_registry_value_iter_get_value_type: + * @iter: (in) (transfer none): a #GWin32RegistryValueIter + * @value_type: (out): Pointer to a location to store the type of + * the value. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Stores the type of the value currently being iterated over in @value_type. + * + * Returns: %TRUE if value type was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_value_iter_get_value_type (GWin32RegistryValueIter *iter, + GWin32RegistryValueType *value_type, + GError **error) +{ + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (value_type != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->value_count) + { + g_critical ("g_win32_registry_value_iter_get_type: must not be called " + "again after NULL has already been returned."); + return FALSE; + } + + *value_type = iter->value_type; + + return TRUE; +} + +/** + * g_win32_registry_value_iter_get_name_w: + * @iter: (in) (transfer none): a #GWin32RegistryValueIter + * @value_name: (out callee-allocates) (transfer none): Pointer to a location + * to store the name of a value (in UTF-16). + * @value_name_len: (out) (optional): Pointer to a location to store the length + * of @value_name, in gunichar2s, excluding NUL-terminator. + * %NULL if length is not needed. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Stores the name of the value currently being iterated over in @value_name, + * and its length - in @value_name (if not %NULL). + * + * Returns: %TRUE if value name was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_value_iter_get_name_w (GWin32RegistryValueIter *iter, + gunichar2 **value_name, + gsize *value_name_len, + GError **error) +{ + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (value_name != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->value_count) + { + g_critical ("g_win32_registry_value_iter_get_name_w: must not be called " + "again after NULL has already been returned."); + return FALSE; + } + + *value_name = iter->value_name; + + if (value_name_len) + *value_name_len = iter->value_name_len; + + return TRUE; +} + +/** + * g_win32_registry_value_iter_get_name: + * @iter: (in) (transfer none): a #GWin32RegistryValueIter + * @value_name: (out callee-allocates) (transfer none): Pointer to a location + * to store the name of a value (in UTF-8). + * @value_name_len: (out) (optional): Pointer to a location to store the length + * of @value_name, in gchars, excluding NUL-terminator. + * %NULL if length is not needed. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Stores the name of the value currently being iterated over in @value_name, + * and its length - in @value_name_len (if not %NULL). + * + * Returns: %TRUE if value name was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_value_iter_get_name (GWin32RegistryValueIter *iter, + gchar **value_name, + gsize *value_name_len, + GError **error) +{ + glong value_name_len_glong; + + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (value_name != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->value_count) + { + g_critical ("g_win32_registry_value_iter_get_name: must not be called " + "again after NULL has already been returned."); + return FALSE; + } + + if (iter->value_name_u8 == NULL) + { + iter->value_name_u8 = g_utf16_to_utf8 (iter->value_name, iter->value_name_len, NULL, + &value_name_len_glong, error); + + if (iter->value_name_u8 == NULL) + return FALSE; + } + + *value_name = iter->value_name_u8; + + if (value_name_len) + *value_name_len = iter->value_name_u8_len; + + return TRUE; +} + +static gboolean +expand_value (gunichar2 *value, + const gunichar2 *value_name, + gpointer *expanded_value, + gsize *expanded_charsize, + GError **error) +{ + DWORD value_data_expanded_charsize_w; + + value_data_expanded_charsize_w = + ExpandEnvironmentStringsW (value, + (gunichar2 *) *expanded_value, + *expanded_charsize); + + if (value_data_expanded_charsize_w > *expanded_charsize) + { + *expanded_value = g_realloc (*expanded_value, + value_data_expanded_charsize_w * sizeof (gunichar2)); + *expanded_charsize = value_data_expanded_charsize_w; + value_data_expanded_charsize_w = + ExpandEnvironmentStringsW (value, + (gunichar2 *) *expanded_value, + *expanded_charsize); + } + + if (value_data_expanded_charsize_w == 0) + { + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (GetLastError ()), + "Failed to expand data '%S' of value %S", + value, value_name); + return FALSE; + } + + return TRUE; +} + +/** + * g_win32_registry_value_iter_get_data_w: + * @iter: (in) (transfer none): a #GWin32RegistryValueIter + * @auto_expand: (in): %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR to + * G_WIN32_REGISTRY_VALUE_STR + * @value_data: (out callee-allocates) (optional) (transfer none): Pointer to a + * location to store the data of the value (in UTF-16, if it's a string) + * @value_data_size: (out) (optional): Pointer to a location to store the size + * of @value_data, in bytes (including any NUL-terminators, if it's a string). + * %NULL if length is not needed. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Stores the data of the value currently being iterated over in @value_data, + * and its length - in @value_data_len (if not %NULL). + * + * Returns: %TRUE if value data was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_value_iter_get_data_w (GWin32RegistryValueIter *iter, + gboolean auto_expand, + gpointer *value_data, + gsize *value_data_size, + GError **error) +{ + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (value_data != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->value_count) + { + g_critical ("g_win32_registry_value_iter_get_data_w: must not be called " + "again after FALSE has already been returned."); + return FALSE; + } + + if (!auto_expand || (iter->value_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR)) + { + *value_data = iter->value_data; + + if (value_data_size) + *value_data_size = iter->value_actual_data_size; + + return TRUE; + } + + if (iter->value_type == iter->value_expanded_type) + { + if (!expand_value ((gunichar2 *) iter->value_data, + iter->value_name, + (gpointer *) &iter->value_data_expanded, + &iter->value_data_expanded_charsize, + error)) + return FALSE; + + iter->value_expanded_type = G_WIN32_REGISTRY_VALUE_STR; + } + + *value_data = iter->value_data_expanded; + + if (value_data_size) + *value_data_size = iter->value_data_expanded_charsize * sizeof (gunichar2); + + return TRUE; +} + +/** + * g_win32_registry_value_iter_get_data: + * @iter: (in) (transfer none): a #GWin32RegistryValueIter + * @auto_expand: (in): %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR to + * G_WIN32_REGISTRY_VALUE_STR + * @value_data: (out callee-allocates) (optional) (transfer none): Pointer to a + * location to store the data of the value (in UTF-8, if it's a string) + * @value_data_size: (out) (optional): Pointer to a location to store the length + * of @value_data, in bytes (including any NUL-terminators, if it's a string). + * %NULL if length is not needed + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Stores the data of the value currently being iterated over in @value_data, + * and its length - in @value_data_len (if not %NULL). + * + * Returns: %TRUE if value data was retrieved, %FALSE otherwise. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_value_iter_get_data (GWin32RegistryValueIter *iter, + gboolean auto_expand, + gpointer *value_data, + gsize *value_data_size, + GError **error) +{ + gsize value_data_len_gsize; + gpointer tmp; + gsize tmp_size; + + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (value_data != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if G_UNLIKELY (iter->counter >= iter->value_count) + { + g_critical ("g_win32_registry_value_iter_get_data: must not be called " + "again after FALSE has already been returned."); + return FALSE; + } + + if (iter->value_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR && + iter->value_type != G_WIN32_REGISTRY_VALUE_LINK && + iter->value_type != G_WIN32_REGISTRY_VALUE_STR && + iter->value_type != G_WIN32_REGISTRY_VALUE_MULTI_STR) + { + *value_data = iter->value_data; + + if (value_data_size != NULL) + *value_data_size = iter->value_actual_data_size; + + return TRUE; + } + + if (!auto_expand || (iter->value_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR)) + { + if (iter->value_data_u8 == NULL) + { + iter->value_data_u8 = g_convert ((const gchar *) iter->value_data, + iter->value_actual_data_size - sizeof (gunichar2) /* excl. 0 */, + "UTF8", "UTF16", NULL, + &value_data_len_gsize, + error); + + if (iter->value_data_u8 == NULL) + return FALSE; + + iter->value_data_u8_size = value_data_len_gsize + 1; /* incl. 0 */ + } + + *value_data = iter->value_data_u8; + + if (value_data_size != NULL) + *value_data_size = iter->value_data_u8_size; + + return TRUE; + } + + if (iter->value_data_expanded_u8 == NULL) + { + if (!g_win32_registry_value_iter_get_data_w (iter, + TRUE, + &tmp, + &tmp_size, + error)) + return FALSE; + + iter->value_data_expanded_u8 = g_convert ((const gchar *) iter->value_data_expanded, + iter->value_data_expanded_charsize * sizeof (gunichar2) - sizeof (gunichar2) /* excl. 0 */, + "UTF8", "UTF16", NULL, + &value_data_len_gsize, + error); + + if (iter->value_data_expanded_u8 == NULL) + return FALSE; + + iter->value_data_u8_size = value_data_len_gsize + 1; /* incl. 0 */ + } + + *value_data = iter->value_data_expanded_u8; + + if (value_data_size != NULL) + *value_data_size = iter->value_data_expanded_u8_size; + + return TRUE; +} + +static void +_g_win32_registry_key_reread_kernel (GWin32RegistryKey *key, + GWin32RegistryKeyPrivate *buf) +{ + NTSTATUS status; + KEY_BASIC_INFORMATION *basic_info; + ULONG basic_info_size; + ULONG datasize; + + basic_info_size = 256 * sizeof (gunichar2) + sizeof (KEY_BASIC_INFORMATION); + basic_info = g_malloc (basic_info_size + sizeof (gunichar2)); + status = nt_query_key (key->priv->handle, + KeyBasicInformation, + basic_info, + basic_info_size, + &datasize); + + if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL) + { + g_free (basic_info); + basic_info_size = datasize; + /* +1 for 0-terminator */ + basic_info = g_malloc (basic_info_size + sizeof (gunichar2)); + status = nt_query_key (key->priv->handle, + KeyBasicInformation, + basic_info, + basic_info_size, + &datasize); + } + + if (status != STATUS_SUCCESS) + { + g_free (basic_info); + return; + } + + /* Ensure 0-termination */ + ((char *) basic_info)[datasize] = 0; + ((char *) basic_info)[datasize + 1] = 0; + + buf->absolute_path_w = g_wcsdup (&basic_info->Name[0], + basic_info->NameLength + sizeof (gunichar2)); + g_free (basic_info); +} + +static void +_g_win32_registry_key_reread_user (GWin32RegistryKey *key, + GWin32RegistryKeyPrivate *buf) +{ + /* Use RegQueryInfoKey(). It's just like NtQueryKey(), but can't query + * key name. + * Since right now we only need the name, this function is a noop. + */ +} + +static void +_g_win32_registry_key_reread (GWin32RegistryKey *key, + GWin32RegistryKeyPrivate *buf) +{ + if (g_once_init_enter (&nt_query_key)) + { + NtQueryKeyFunc func; + HMODULE ntdll = GetModuleHandleW (L"ntdll.dll"); + + if (ntdll != NULL) + func = (NtQueryKeyFunc) GetProcAddress (ntdll, "NtQueryKey"); + else + func = NULL; + + g_once_init_leave (&nt_query_key, func); + } + + /* Assume that predefined keys never get renamed. Also, their handles probably + * won't be accepted by NtQueryKey(), i suspect. + */ + if (nt_query_key != NULL && !key->priv->predefined) + _g_win32_registry_key_reread_kernel (key, buf); + else + _g_win32_registry_key_reread_user (key, buf); +} + +static gboolean +_g_win32_registry_key_update_path (GWin32RegistryKey *key) +{ + GWin32RegistryKeyPrivate tmp; + gboolean changed; + gint change_indicator; + + change_indicator = g_atomic_int_get (&key->priv->change_indicator); + + if (change_indicator == G_WIN32_KEY_UNCHANGED) + return FALSE; + + tmp.absolute_path_w = NULL; + _g_win32_registry_key_reread (key, &tmp); + changed = FALSE; + + if (wcscmp (key->priv->absolute_path_w, tmp.absolute_path_w) == 0) + g_free (tmp.absolute_path_w); + else + { + g_free (key->priv->absolute_path_w); + key->priv->absolute_path_w = tmp.absolute_path_w; + changed = TRUE; + } + + return changed; +} + +/** + * g_win32_registry_key_get_path: + * @key: (in) (transfer none): a #GWin32RegistryKey + * + * Get full path to the key + * + * Returns: (transfer none): a full path to the key (in UTF-8), + * or %NULL if it can't be converted to UTF-8. + * + * Since: 2.46 + **/ +const gchar * +g_win32_registry_key_get_path (GWin32RegistryKey *key) +{ + gint change_indicator; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), NULL); + + change_indicator = g_atomic_int_get (&key->priv->change_indicator); + + if (change_indicator == G_WIN32_KEY_CHANGED && + !(key->priv->update_flags & G_WIN32_REGISTRY_UPDATED_PATH)) + { + _g_win32_registry_key_update_path (key); + key->priv->update_flags |= G_WIN32_REGISTRY_UPDATED_PATH; + } + + if (key->priv->absolute_path == NULL) + { + g_free (key->priv->absolute_path); + key->priv->absolute_path = + g_utf16_to_utf8 (key->priv->absolute_path_w, -1, + NULL, NULL, NULL); + } + + return key->priv->absolute_path; +} + +/** + * g_win32_registry_key_get_path_w: + * @key: (in) (transfer none): a #GWin32RegistryKey + * + * Get full path to the key + * + * Returns: (transfer none): a full path to the key (in UTF-16) + * + * Since: 2.46 + **/ +const gunichar2 * +g_win32_registry_key_get_path_w (GWin32RegistryKey *key) +{ + gint change_indicator; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), NULL); + + change_indicator = g_atomic_int_get (&key->priv->change_indicator); + + if (change_indicator == G_WIN32_KEY_CHANGED) + _g_win32_registry_key_update_path (key); + + return key->priv->absolute_path_w; +} + +/** + * g_win32_registry_get_os_dirs_w: + * + * Returns a list of directories for DLL lookups. + * Can be used with g_win32_registry_key_get_value_w(). + * + * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of UTF-16 strings. + * + * Since: 2.66 + */ +const gunichar2 * const * +g_win32_registry_get_os_dirs_w (void) +{ + static gunichar2 **mui_os_dirs = NULL; + + if (g_once_init_enter (&mui_os_dirs)) + { + gunichar2 **new_mui_os_dirs; + gunichar2 *system32 = NULL; + gunichar2 *syswow64 = NULL; + UINT buffer_size; + gsize array_index = 0; + + buffer_size = GetSystemWow64DirectoryW (NULL, 0); + + if (buffer_size > 0) + { + UINT copied; + syswow64 = g_malloc (buffer_size * sizeof (gunichar2)); + copied = GetSystemWow64DirectoryW (syswow64, buffer_size); + if (copied <= 0) + g_clear_pointer (&syswow64, g_free); + } + + buffer_size = GetSystemDirectoryW (NULL, 0); + + if (buffer_size > 0) + { + UINT copied; + system32 = g_malloc (buffer_size * sizeof (gunichar2)); + copied = GetSystemDirectoryW (system32, buffer_size); + if (copied <= 0) + g_clear_pointer (&system32, g_free); + } + + new_mui_os_dirs = g_new0 (gunichar2 *, 3); + + if (system32 != NULL) + new_mui_os_dirs[array_index++] = system32; + + if (syswow64 != NULL) + new_mui_os_dirs[array_index++] = syswow64; + + new_mui_os_dirs[array_index++] = NULL; + + g_once_init_leave (&mui_os_dirs, new_mui_os_dirs); + } + + return (const gunichar2 * const *) mui_os_dirs; +} + +/** + * g_win32_registry_get_os_dirs: + * + * Returns a list of directories for DLL lookups. + * Can be used with g_win32_registry_key_get_value(). + * + * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of UTF-8 strings. + * + * Since: 2.66 + */ +const gchar * const * +g_win32_registry_get_os_dirs (void) +{ + static gchar **mui_os_dirs = NULL; + + if (g_once_init_enter (&mui_os_dirs)) + { + gchar **new_mui_os_dirs; + gsize array_index; + gsize new_array_index; + const gunichar2 * const *mui_os_dirs_utf16 = g_win32_registry_get_os_dirs_w (); + + for (array_index = 0; mui_os_dirs_utf16[array_index] != NULL; array_index++) + ; + + new_mui_os_dirs = g_new0 (gchar *, array_index + 1); + + for (array_index = 0, new_array_index = 0; + mui_os_dirs_utf16[array_index] != NULL; + array_index++) + { + new_mui_os_dirs[new_array_index] = g_utf16_to_utf8 (mui_os_dirs_utf16[array_index], + -1, NULL, NULL, NULL); + if (new_mui_os_dirs[new_array_index] != NULL) + new_array_index += 1; + else + g_critical ("Failed to convert to a system directory #%zu to UTF-8", array_index); + } + + g_once_init_leave (&mui_os_dirs, new_mui_os_dirs); + } + + return (const gchar * const *) mui_os_dirs; +} + +/** + * g_win32_registry_key_get_value: + * @key: (in) (transfer none): a #GWin32RegistryKey + * @mui_dll_dirs: (in) (transfer none) (array zero-terminated=1) (optional): a %NULL-terminated + * array of directory names where the OS + * should look for a DLL indicated in a MUI string, if the + * DLL path in the string is not absolute + * @auto_expand: (in) %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR + * to G_WIN32_REGISTRY_VALUE_STR. + * @value_name: (in) (transfer none): name of the value to get (in UTF-8). + * Empty string means the '(Default)' value. + * @value_type: (out) (optional): type of the value retrieved. + * @value_data: (out callee-allocates) (optional): contents of the value. + * @value_data_size: (out) (optional): size of the buffer pointed + * by @value_data. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Get data from a value of a key. String data is guaranteed to be + * appropriately terminated and will be in UTF-8. + * + * When not %NULL, @mui_dll_dirs indicates that `RegLoadMUIStringW()` API + * should be used instead of the usual `RegQueryValueExW()`. This implies + * that the value being queried is of type `REG_SZ` or `REG_EXPAND_SZ` (if it is not, the function + * falls back to `RegQueryValueExW()`), and that this string must undergo special processing + * (see [`SHLoadIndirectString()` documentation](https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring) for an explanation on what + * kinds of strings are processed) to get the result. + * + * If no specific MUI DLL directories need to be used, pass + * the return value of g_win32_registry_get_os_dirs() as @mui_dll_dirs + * (as an bonus, the value from g_win32_registry_get_os_dirs() + * does not add any extra UTF8->UTF16 conversion overhead). + * + * @auto_expand works with @mui_dll_dirs, but only affects the processed + * string, making it somewhat useless. The unprocessed string is always expanded + * internally, if its type is `REG_EXPAND_SZ` - there is no need to enable + * @auto_expand for this to work. + * + * The API for this function changed in GLib 2.66 to add the @mui_dll_dirs argument. + * + * Returns: %TRUE on success, %FALSE on failure. + * + * Since: 2.66 + **/ +gboolean +g_win32_registry_key_get_value (GWin32RegistryKey *key, + const gchar * const *mui_dll_dirs, + gboolean auto_expand, + const gchar *value_name, + GWin32RegistryValueType *value_type, + gpointer *value_data, + gsize *value_data_size, + GError **error) +{ + GWin32RegistryValueType value_type_g; + gpointer value_data_w; + gsize value_data_w_size; + gunichar2 *value_name_w; + gchar *value_data_u8; + gsize value_data_u8_len; + gboolean result; + gsize mui_dll_dirs_count; + gunichar2 **mui_dll_dirs_utf16; + const gchar * const *mui_os_dirs; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE); + g_return_val_if_fail (value_name != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* No sense calling this function with all of these set to NULL */ + g_return_val_if_fail (value_type != NULL || + value_data != NULL || + value_data_size != NULL, FALSE); + + value_name_w = g_utf8_to_utf16 (value_name, -1, NULL, NULL, error); + + if (value_name_w == NULL) + return FALSE; + + mui_dll_dirs_utf16 = NULL; + mui_os_dirs = g_win32_registry_get_os_dirs (); + + if (mui_dll_dirs != NULL && + mui_dll_dirs != mui_os_dirs) + { + gsize i; + + mui_dll_dirs_count = g_strv_length ((gchar **) mui_dll_dirs); + mui_dll_dirs_utf16 = g_new0 (gunichar2 *, mui_dll_dirs_count + 1); + + for (i = 0; mui_dll_dirs[i] != NULL; i++) + { + mui_dll_dirs_utf16[i] = g_utf8_to_utf16 (mui_dll_dirs[i], -1, NULL, NULL, error); + + if (mui_dll_dirs_utf16[i] == NULL) + break; + } + + if (mui_dll_dirs[i] != NULL) + { + g_prefix_error (error, + "A mui_dll_dirs string #%zu `%s' failed to convert: ", + i, mui_dll_dirs[i]); + + for (i = 0; i < mui_dll_dirs_count; i++) + g_free (mui_dll_dirs_utf16[i]); + + g_free (mui_dll_dirs_utf16); + g_free (value_name_w); + + return FALSE; + } + } + else if (mui_dll_dirs != NULL && + mui_dll_dirs == mui_os_dirs) + { + mui_dll_dirs_utf16 = (gunichar2 **) g_win32_registry_get_os_dirs_w (); + } + + result = g_win32_registry_key_get_value_w (key, + (const gunichar2 * const *) mui_dll_dirs_utf16, + auto_expand, + value_name_w, + &value_type_g, + &value_data_w, + &value_data_w_size, + error); + + g_free (value_name_w); + if (mui_dll_dirs_utf16 != NULL && + mui_dll_dirs != mui_os_dirs) + { + gsize array_index; + for (array_index = 0; mui_dll_dirs_utf16[array_index] != NULL; array_index++) + g_free (mui_dll_dirs_utf16[array_index]); + g_free (mui_dll_dirs_utf16); + } + + if (!result) + return FALSE; + + if (value_type_g == G_WIN32_REGISTRY_VALUE_EXPAND_STR || + value_type_g == G_WIN32_REGISTRY_VALUE_LINK || + value_type_g == G_WIN32_REGISTRY_VALUE_STR || + value_type_g == G_WIN32_REGISTRY_VALUE_MULTI_STR) + { + value_data_u8 = g_convert ((const gchar *) value_data_w, + value_data_w_size - sizeof (gunichar2) /* excl. 0 */, + "UTF8", + "UTF16", + NULL, + &value_data_u8_len, + error); + g_free (value_data_w); + + if (value_data_u8 == NULL) + return FALSE; + + if (value_data) + *value_data = value_data_u8; + else + g_free (value_data_u8); + + if (value_data_size) + *value_data_size = value_data_u8_len + 1; + } + else + { + if (value_data) + *value_data = value_data_w; + else + g_free (value_data_w); + + if (value_data_size) + *value_data_size = value_data_w_size; + } + + if (value_type) + *value_type = value_type_g; + + return TRUE; +} + +/* A wrapper that calls either RegQueryValueExW() or + * RegLoadMUIStringW() depending on the value of the + * last argument. + * Apart from the extra argument, the function behaves + * just like RegQueryValueExW(), with a few caveats. + */ +static LSTATUS +MuiRegQueryValueExW (HKEY hKey, + LPCWSTR lpValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData, + const gunichar2 * const *mui_dll_dirs) +{ + gsize dir_index; + LSTATUS result = ERROR_PATH_NOT_FOUND; + DWORD bufsize; + DWORD data_size; + PVOID old_value; + + if (mui_dll_dirs == NULL) + return RegQueryValueExW (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); + + bufsize = 0; + + if (lpcbData != NULL) + bufsize = *lpcbData; + + if (mui_dll_dirs[0] != NULL) + { + /* Optimization: check that the value actually exists, + * before we start trying different mui dll dirs + */ + result = RegQueryValueExW (hKey, lpValueName, NULL, NULL, NULL, 0); + + if (result == ERROR_FILE_NOT_FOUND) + return result; + } + + Wow64DisableWow64FsRedirection (&old_value); + + /* Try with NULL dir first */ + result = RegLoadMUIStringW (hKey, + lpValueName, + (wchar_t *) lpData, + bufsize, + &data_size, + 0, + NULL); + + /* Not a MUI value, load normally */ + if (result == ERROR_INVALID_DATA) + { + Wow64RevertWow64FsRedirection (old_value); + + return RegQueryValueExW (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); + } + + for (dir_index = 0; + result == ERROR_FILE_NOT_FOUND && + mui_dll_dirs[dir_index] != NULL; + dir_index++) + result = RegLoadMUIStringW (hKey, + lpValueName, + (wchar_t *) lpData, + bufsize, + &data_size, + 0, + mui_dll_dirs[dir_index]); + + Wow64RevertWow64FsRedirection (old_value); + + if (lpcbData != NULL && + result == ERROR_MORE_DATA) + *lpcbData = data_size; + + if (lpType != NULL && + result != ERROR_INVALID_DATA && + result != ERROR_FILE_NOT_FOUND) + *lpType = REG_SZ; + + return result; +} + +/** + * g_win32_registry_key_get_value_w: + * @key: (in) (transfer none): a #GWin32RegistryKey + * @mui_dll_dirs: (in) (transfer none) (array zero-terminated=1) (optional): a %NULL-terminated + * array of directory names where the OS + * should look for a DLL indicated in a MUI string, if the + * DLL path in the string is not absolute + * @auto_expand: (in) %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR + * to G_WIN32_REGISTRY_VALUE_STR. + * @value_name: (in) (transfer none): name of the value to get (in UTF-16). + * Empty string means the '(Default)' value. + * @value_type: (out) (optional): type of the value retrieved. + * @value_data: (out callee-allocates) (optional): contents of the value. + * @value_data_size: (out) (optional): size of the buffer pointed + * by @value_data. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Get data from a value of a key. String data is guaranteed to be + * appropriately terminated and will be in UTF-16. + * + * When calling with value_data == NULL (to get data size without getting + * the data itself) remember that returned size corresponds to possibly + * unterminated string data (if value is some kind of string), because + * termination cannot be checked and fixed unless the data is retrieved + * too. + * + * When not %NULL, @mui_dll_dirs indicates that `RegLoadMUIStringW()` API + * should be used instead of the usual `RegQueryValueExW()`. This implies + * that the value being queried is of type `REG_SZ` or `REG_EXPAND_SZ` (if it is not, the function + * falls back to `RegQueryValueExW()`), and that this string must undergo special processing + * (see [`SHLoadIndirectString()` documentation](https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring) for an explanation on what + * kinds of strings are processed) to get the result. + * + * If no specific MUI DLL directories need to be used, pass + * the return value of g_win32_registry_get_os_dirs_w() as @mui_dll_dirs. + * + * @auto_expand works with @mui_dll_dirs, but only affects the processed + * string, making it somewhat useless. The unprocessed string is always expanded + * internally, if its type is `REG_EXPAND_SZ` - there is no need to enable + * @auto_expand for this to work. + * + * The API for this function changed in GLib 2.66 to add the @mui_dll_dirs argument. + * + * Returns: %TRUE on success, %FALSE on failure. + * + * Since: 2.66 + **/ +gboolean +g_win32_registry_key_get_value_w (GWin32RegistryKey *key, + const gunichar2 * const *mui_dll_dirs, + gboolean auto_expand, + const gunichar2 *value_name, + GWin32RegistryValueType *value_type, + gpointer *value_data, + gsize *value_data_size, + GError **error) +{ + LONG status; + DWORD value_type_w; + DWORD value_type_w2; + char *req_value_data; + GWin32RegistryValueType value_type_g; + GWin32RegistryValueType value_type_g2; + DWORD req_value_data_size; + DWORD req_value_data_size2; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE); + g_return_val_if_fail (value_name != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* No sense calling this functions with all of these set to NULL */ + g_return_val_if_fail (value_type != NULL || + value_data != NULL || + value_data_size != NULL, FALSE); + + req_value_data_size = 0; + status = MuiRegQueryValueExW (key->priv->handle, + value_name, + NULL, + &value_type_w, + NULL, + &req_value_data_size, + mui_dll_dirs); + + if (status != ERROR_MORE_DATA && status != ERROR_SUCCESS) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status), + "Failed to query value '%S' for key '%S'", + value_name, g_win32_registry_key_get_path_w (key)); + + return FALSE; + } + + value_type_g = _g_win32_registry_type_w_to_g (value_type_w); + + if (value_data == NULL && + (!auto_expand || value_type_g != G_WIN32_REGISTRY_VALUE_EXPAND_STR)) + { + if (value_type) + *value_type = value_type_g; + + if (value_data_size) + *value_data_size = req_value_data_size; + + return TRUE; + } + + req_value_data = g_malloc (req_value_data_size + sizeof (gunichar2) * 2); + req_value_data_size2 = req_value_data_size; + status = MuiRegQueryValueExW (key->priv->handle, + value_name, + NULL, + &value_type_w2, + (gpointer) req_value_data, + &req_value_data_size2, + mui_dll_dirs); + + if (status != ERROR_SUCCESS) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status), + "Failed to query value '%S' of size %lu for key '%S'", + value_name, + req_value_data_size, + g_win32_registry_key_get_path_w (key)); + g_free (req_value_data); + return FALSE; + } + + value_type_g2 = _g_win32_registry_type_w_to_g (value_type_w2); + + if (value_type_w != value_type_w2) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Type of value '%S' of key '%S' changed from %u to %u" + " between calls", + value_name, + g_win32_registry_key_get_path_w (key), + value_type_g, value_type_g2); + g_free (req_value_data); + return FALSE; + } + + req_value_data_size = ensure_nul_termination (value_type_g, + (guint8 *) req_value_data, + req_value_data_size2); + + if (value_type_g == G_WIN32_REGISTRY_VALUE_EXPAND_STR && auto_expand) + { + gsize value_data_expanded_charsize_w = 0; + gunichar2 *value_data_expanded = NULL; + + if (!expand_value ((gunichar2 *) req_value_data, + value_name, + (gpointer *) &value_data_expanded, + &value_data_expanded_charsize_w, + error)) + return FALSE; + + g_free (req_value_data); + + if (value_type) + *value_type = G_WIN32_REGISTRY_VALUE_STR; + + if (value_data) + *value_data = value_data_expanded; + else + g_free (value_data_expanded); + + if (value_data_size) + *value_data_size = value_data_expanded_charsize_w * sizeof (gunichar2); + + return TRUE; + } + + if (value_type) + *value_type = value_type_g; + + if (value_data_size) + *value_data_size = req_value_data_size; + + if (value_data) + *value_data = req_value_data; + else + g_free (req_value_data); + + return TRUE; +} + +static VOID NTAPI +key_changed (PVOID closure, + PIO_STATUS_BLOCK status_block, + ULONG reserved) +{ + GWin32RegistryKey *key = G_WIN32_REGISTRY_KEY (closure); + gpointer user_data; + GWin32RegistryKeyWatchCallbackFunc callback; + + callback = g_steal_pointer (&key->priv->callback); + user_data = g_steal_pointer (&key->priv->user_data); + + g_free (status_block); + g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_CHANGED); + g_atomic_int_set (&key->priv->watch_indicator, G_WIN32_KEY_UNWATCHED); + key->priv->update_flags = G_WIN32_REGISTRY_UPDATED_NOTHING; + + if (callback) + callback (key, user_data); + + g_object_unref (key); +} + +/** + * g_win32_registry_key_watch: + * @key: (in) (transfer none): a #GWin32RegistryKey + * @watch_children: (in) %TRUE also watch the children of the @key, %FALSE + * to watch the key only. + * @watch_flags: (in): specifies the types of changes to watch for. + * @callback: (in) (nullable): a function to invoke when a change occurs. + * @user_data: (in) (nullable): a pointer to pass to @callback on invocation. + * @error: (nullable): a pointer to %NULL #GError, or %NULL + * + * Puts @key under a watch. + * + * When the key changes, an APC will be queued in the current thread. The APC + * will run when the current thread enters alertable state (GLib main loop + * should do that; if you are not using it, see MSDN documentation for W32API + * calls that put thread into alertable state). When it runs, it will + * atomically switch an indicator in the @key. If a callback was specified, + * it is invoked at that point. Subsequent calls to + * g_win32_registry_key_has_changed() will return %TRUE, and the callback (if + * it was specified) will not be invoked anymore. + * Calling g_win32_registry_key_erase_change_indicator() will reset the indicator, + * and g_win32_registry_key_has_changed() will start returning %FALSE. + * To resume the watch, call g_win32_registry_key_watch_for_changes() again. + * + * Calling g_win32_registry_key_watch_for_changes() for a key that is already + * being watched is allowed and affects nothing. + * + * The fact that the key is being watched will be used internally to update + * key path (if it changes). + * + * Returns: %TRUE on success, %FALSE on failure. + * + * Since: 2.46 + **/ +gboolean +g_win32_registry_key_watch (GWin32RegistryKey *key, + gboolean watch_children, + GWin32RegistryKeyWatcherFlags watch_flags, + GWin32RegistryKeyWatchCallbackFunc callback, + gpointer user_data, + GError **error) +{ + ULONG filter; + gboolean started_to_watch; + NTSTATUS status; + PIO_STATUS_BLOCK status_block; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE); + + filter = ((watch_flags & G_WIN32_REGISTRY_WATCH_NAME) ? REG_NOTIFY_CHANGE_NAME : 0) | + ((watch_flags & G_WIN32_REGISTRY_WATCH_ATTRIBUTES) ? REG_NOTIFY_CHANGE_ATTRIBUTES : 0) | + ((watch_flags & G_WIN32_REGISTRY_WATCH_VALUES) ? REG_NOTIFY_CHANGE_LAST_SET : 0) | + ((watch_flags & G_WIN32_REGISTRY_WATCH_SECURITY) ? REG_NOTIFY_CHANGE_SECURITY : 0); + + if (filter == 0) + { + g_critical ("No supported flags specified in watch_flags (%x)", (guint) watch_flags); + return FALSE; + } + + if (g_once_init_enter (&nt_notify_change_multiple_keys)) + { + NtNotifyChangeMultipleKeysFunc func; + HMODULE ntdll = GetModuleHandleW (L"ntdll.dll"); + + if (ntdll != NULL) + func = (NtNotifyChangeMultipleKeysFunc) GetProcAddress (ntdll, "NtNotifyChangeMultipleKeys"); + else + func = NULL; + + g_once_init_leave (&nt_notify_change_multiple_keys, func); + } + + if (nt_notify_change_multiple_keys== NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Couldn't get NtNotifyChangeMultipleKeys() from ntdll"); + return FALSE; + } + + started_to_watch = + g_atomic_int_compare_and_exchange (&key->priv->watch_indicator, + G_WIN32_KEY_UNWATCHED, + G_WIN32_KEY_WATCHED); + + if (!started_to_watch) + return TRUE; + + key->priv->callback = callback; + key->priv->user_data = user_data; + + g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_UNCHANGED); + + /* Keep it alive until APC is called */ + g_object_ref (key); + + status_block = g_malloc (sizeof (IO_STATUS_BLOCK)); + + status = nt_notify_change_multiple_keys (key->priv->handle, + 0, + NULL, + NULL, + key_changed, + (PVOID) key, + status_block, + filter, + watch_children, + NULL, + 0, + TRUE); + + if (status == STATUS_PENDING || status == STATUS_SUCCESS) + return TRUE; + + g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_UNKNOWN); + g_atomic_int_set (&key->priv->watch_indicator, G_WIN32_KEY_UNWATCHED); + g_object_unref (key); + g_free (status_block); + + return FALSE; +} + +/** + * g_win32_registry_key_erase_change_indicator: + * @key: (in) (transfer none): a #GWin32RegistryKey + * + * Erases change indicator of the @key. + * + * Subsequent calls to g_win32_registry_key_has_changed() will return %FALSE + * until the key is put on watch again by calling + * g_win32_registry_key_watch() again. + * + * Since: 2.46 + */ +void +g_win32_registry_key_erase_change_indicator (GWin32RegistryKey *key) +{ + g_return_if_fail (G_IS_WIN32_REGISTRY_KEY (key)); + + g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_UNKNOWN); +} + +/** + * g_win32_registry_key_has_changed: + * @key: (in) (transfer none): a #GWin32RegistryKey + * + * Check the @key's status indicator. + * + * Returns: %TRUE if the @key was put under watch at some point and has changed + * since then, %FALSE if it either wasn't changed or wasn't watched at all. + * + * Since: 2.46 + */ +gboolean +g_win32_registry_key_has_changed (GWin32RegistryKey *key) +{ + gint changed; + + g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE); + + changed = g_atomic_int_get (&key->priv->change_indicator); + + return (changed == G_WIN32_KEY_CHANGED ? TRUE : FALSE); +} + +static void +g_win32_registry_key_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GWin32RegistryKey *key = G_WIN32_REGISTRY_KEY (object); + + switch (prop_id) + { + case PROP_PATH: + g_value_set_string (value, g_win32_registry_key_get_path (key)); + break; + + case PROP_PATH_UTF16: + g_value_set_pointer (value, (gpointer) g_win32_registry_key_get_path_w (key)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_win32_registry_key_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GWin32RegistryKey *key = G_WIN32_REGISTRY_KEY (object); + GWin32RegistryKeyPrivate *priv = key->priv; + const gchar *path; + gunichar2 *path_w; + + switch (prop_id) + { + case PROP_PATH: + path = g_value_get_string (value); + + if (path == NULL) + break; + + path_w = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL); + + if (path_w == NULL) + break; + + /* Construct only */ + g_assert (priv->absolute_path_w == NULL); + g_assert (priv->absolute_path == NULL); + priv->absolute_path_w = path_w; + priv->absolute_path = g_value_dup_string (value); + break; + + case PROP_PATH_UTF16: + path_w = (gunichar2 *) g_value_get_pointer (value); + + if (path_w == NULL) + break; + + /* Construct only */ + g_assert (priv->absolute_path_w == NULL); + priv->absolute_path_w = g_wcsdup (path_w, -1); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_win32_registry_key_class_init (GWin32RegistryKeyClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = g_win32_registry_key_dispose; + gobject_class->set_property = g_win32_registry_key_set_property; + gobject_class->get_property = g_win32_registry_key_get_property; + + /** + * GWin32RegistryKey:path: + * + * A path to the key in the registry, in UTF-8. + * + * Since: 2.46 + */ + g_object_class_install_property (gobject_class, + PROP_PATH, + g_param_spec_string ("path", + "Path", + "Path to the key in the registry", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GWin32RegistryKey:path-utf16: + * + * A path to the key in the registry, in UTF-16. + * + * Since: 2.46 + */ + g_object_class_install_property (gobject_class, + PROP_PATH_UTF16, + g_param_spec_pointer ("path-utf16", + "Path (UTF-16)", + "Path to the key in the registry, in UTF-16", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_win32_registry_key_init (GWin32RegistryKey *key) +{ + key->priv = g_win32_registry_key_get_instance_private (key); + key->priv->change_indicator = G_WIN32_KEY_UNKNOWN; +} diff --git a/gio/gwin32registrykey.h b/gio/gwin32registrykey.h new file mode 100644 index 0000000..f92a10c --- /dev/null +++ b/gio/gwin32registrykey.h @@ -0,0 +1,291 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2014 РуÑлан Ижбулатов + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + */ +#ifndef __G_WIN32_REGISTRY_KEY_H__ +#define __G_WIN32_REGISTRY_KEY_H__ + +#include + +#ifdef G_PLATFORM_WIN32 + +G_BEGIN_DECLS + +#define G_TYPE_WIN32_REGISTRY_KEY (g_win32_registry_key_get_type ()) +#define G_WIN32_REGISTRY_KEY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_REGISTRY_KEY, GWin32RegistryKey)) +#define G_WIN32_REGISTRY_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_WIN32_REGISTRY_KEY, GWin32RegistryKeyClass)) +#define G_IS_WIN32_REGISTRY_KEY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_REGISTRY_KEY)) +#define G_IS_WIN32_REGISTRY_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_WIN32_REGISTRY_KEY)) +#define G_WIN32_REGISTRY_KEY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WIN32_REGISTRY_KEY, GWin32RegistryKeyClass)) + +typedef enum { + G_WIN32_REGISTRY_VALUE_NONE = 0, + G_WIN32_REGISTRY_VALUE_BINARY = 1, + G_WIN32_REGISTRY_VALUE_UINT32LE = 2, + G_WIN32_REGISTRY_VALUE_UINT32BE = 3, +#if G_BYTE_ORDER == G_BIG_ENDIAN + G_WIN32_REGISTRY_VALUE_UINT32 = G_WIN32_REGISTRY_VALUE_UINT32BE, +#else + G_WIN32_REGISTRY_VALUE_UINT32 = G_WIN32_REGISTRY_VALUE_UINT32LE, +#endif + G_WIN32_REGISTRY_VALUE_EXPAND_STR = 4, + G_WIN32_REGISTRY_VALUE_LINK = 5, + G_WIN32_REGISTRY_VALUE_MULTI_STR = 6, + G_WIN32_REGISTRY_VALUE_UINT64LE = 7, +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + G_WIN32_REGISTRY_VALUE_UINT64 = G_WIN32_REGISTRY_VALUE_UINT64LE, +#endif + G_WIN32_REGISTRY_VALUE_STR = 8 +} GWin32RegistryValueType; + +typedef enum { + G_WIN32_REGISTRY_WATCH_NAME = 1 << 0, + G_WIN32_REGISTRY_WATCH_ATTRIBUTES = 1 << 1, + G_WIN32_REGISTRY_WATCH_VALUES = 1 << 2, + G_WIN32_REGISTRY_WATCH_SECURITY = 1 << 3, +} GWin32RegistryKeyWatcherFlags; + +typedef struct _GWin32RegistryKey GWin32RegistryKey; +typedef struct _GWin32RegistryKeyClass GWin32RegistryKeyClass; +typedef struct _GWin32RegistryKeyPrivate GWin32RegistryKeyPrivate; +typedef struct _GWin32RegistrySubkeyIter GWin32RegistrySubkeyIter; +typedef struct _GWin32RegistryValueIter GWin32RegistryValueIter; + +struct _GWin32RegistryKey { + GObject parent_instance; + + /*< private >*/ + GWin32RegistryKeyPrivate *priv; +}; + +struct _GWin32RegistryKeyClass { + GObjectClass parent_class; +}; + +/** + * GWin32RegistryKeyWatchCallbackFunc: + * @key: A #GWin32RegistryKey that was watched. + * @user_data: The @user_data #gpointer passed to g_win32_registry_key_watch(). + * + * The type of the callback passed to g_win32_registry_key_watch(). + * + * The callback is invoked after a change matching the watch flags and arguments + * occurs. If the children of the key were watched also, there is no way to know + * which one of them triggered the callback. + * + * Since: 2.42 + */ +typedef void (*GWin32RegistryKeyWatchCallbackFunc) (GWin32RegistryKey *key, + gpointer user_data); + +#define G_TYPE_WIN32_REGISTRY_SUBKEY_ITER (g_win32_registry_subkey_iter_get_type ()) + +struct _GWin32RegistrySubkeyIter { + /*< private >*/ + GWin32RegistryKey *key; + gint counter; + gint subkey_count; + + gunichar2 *subkey_name; + gsize subkey_name_size; + gsize subkey_name_len; + + gchar *subkey_name_u8; +}; + +#define G_TYPE_WIN32_REGISTRY_VALUE_ITER (g_win32_registry_value_iter_get_type ()) + +struct _GWin32RegistryValueIter { + /*< private >*/ + GWin32RegistryKey *key; + gint counter; + gint value_count; + + gunichar2 *value_name; + gsize value_name_size; + gsize value_name_len; + GWin32RegistryValueType value_type; + guint8 *value_data; + gsize value_data_size; + gsize value_actual_data_size; + GWin32RegistryValueType value_expanded_type; + gunichar2 *value_data_expanded; + gsize value_data_expanded_charsize; + + gchar *value_name_u8; + gsize value_name_u8_len; + gchar *value_data_u8; + gsize value_data_u8_size; + gchar *value_data_expanded_u8; + gsize value_data_expanded_u8_size; +}; + +GLIB_AVAILABLE_IN_2_46 +GWin32RegistrySubkeyIter *g_win32_registry_subkey_iter_copy (const GWin32RegistrySubkeyIter *iter); +GLIB_AVAILABLE_IN_2_46 +void g_win32_registry_subkey_iter_free (GWin32RegistrySubkeyIter *iter); +GLIB_AVAILABLE_IN_2_46 +void g_win32_registry_subkey_iter_assign (GWin32RegistrySubkeyIter *iter, + const GWin32RegistrySubkeyIter *other); +GLIB_AVAILABLE_IN_2_46 +GType g_win32_registry_subkey_iter_get_type (void) G_GNUC_CONST; + + +GLIB_AVAILABLE_IN_2_46 +GWin32RegistryValueIter *g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter); +GLIB_AVAILABLE_IN_2_46 +void g_win32_registry_value_iter_free (GWin32RegistryValueIter *iter); +GLIB_AVAILABLE_IN_2_46 +void g_win32_registry_value_iter_assign (GWin32RegistryValueIter *iter, + const GWin32RegistryValueIter *other); +GLIB_AVAILABLE_IN_2_46 +GType g_win32_registry_value_iter_get_type (void) G_GNUC_CONST; + + +GLIB_AVAILABLE_IN_2_46 +GType g_win32_registry_key_get_type (void); + +GLIB_AVAILABLE_IN_2_46 +GWin32RegistryKey *g_win32_registry_key_new (const gchar *path, + GError **error); + +GLIB_AVAILABLE_IN_2_46 +GWin32RegistryKey *g_win32_registry_key_new_w (const gunichar2 *path, + GError **error); + +GLIB_AVAILABLE_IN_2_46 +GWin32RegistryKey *g_win32_registry_key_get_child (GWin32RegistryKey *key, + const gchar *subkey, + GError **error); + +GLIB_AVAILABLE_IN_2_46 +GWin32RegistryKey *g_win32_registry_key_get_child_w (GWin32RegistryKey *key, + const gunichar2 *subkey, + GError **error); + +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_subkey_iter_init (GWin32RegistrySubkeyIter *iter, + GWin32RegistryKey *key, + GError **error); +GLIB_AVAILABLE_IN_2_46 +void g_win32_registry_subkey_iter_clear (GWin32RegistrySubkeyIter *iter); +GLIB_AVAILABLE_IN_2_46 +gsize g_win32_registry_subkey_iter_n_subkeys (GWin32RegistrySubkeyIter *iter); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_subkey_iter_next (GWin32RegistrySubkeyIter *iter, + gboolean skip_errors, + GError **error); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_subkey_iter_get_name (GWin32RegistrySubkeyIter *iter, + const gchar **subkey_name, + gsize *subkey_name_len, + GError **error); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_subkey_iter_get_name_w (GWin32RegistrySubkeyIter *iter, + const gunichar2 **subkey_name, + gsize *subkey_name_len, + GError **error); + +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_value_iter_init (GWin32RegistryValueIter *iter, + GWin32RegistryKey *key, + GError **error); +GLIB_AVAILABLE_IN_2_46 +void g_win32_registry_value_iter_clear (GWin32RegistryValueIter *iter); +GLIB_AVAILABLE_IN_2_46 +gsize g_win32_registry_value_iter_n_values (GWin32RegistryValueIter *iter); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_value_iter_next (GWin32RegistryValueIter *iter, + gboolean skip_errors, + GError **error); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_value_iter_get_value_type (GWin32RegistryValueIter *iter, + GWin32RegistryValueType *value_type, + GError **error); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_value_iter_get_name (GWin32RegistryValueIter *iter, + gchar **value_name, + gsize *value_name_len, + GError **error); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_value_iter_get_name_w (GWin32RegistryValueIter *iter, + gunichar2 **value_name, + gsize *value_name_len, + GError **error); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_value_iter_get_data (GWin32RegistryValueIter *iter, + gboolean auto_expand, + gpointer *value_data, + gsize *value_data_size, + GError **error); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_value_iter_get_data_w (GWin32RegistryValueIter *iter, + gboolean auto_expand, + gpointer *value_data, + gsize *value_data_size, + GError **error); + +GLIB_AVAILABLE_IN_2_66 +gboolean g_win32_registry_key_get_value (GWin32RegistryKey *key, + const gchar * const *mui_dll_dirs, + gboolean auto_expand, + const gchar *value_name, + GWin32RegistryValueType *value_type, + gpointer *value_data, + gsize *value_data_size, + GError **error); + +GLIB_AVAILABLE_IN_2_66 +gboolean g_win32_registry_key_get_value_w (GWin32RegistryKey *key, + const gunichar2 * const *mui_dll_dirs, + gboolean auto_expand, + const gunichar2 *value_name, + GWin32RegistryValueType *value_type, + gpointer *value_data, + gsize *value_data_size, + GError **error); + +GLIB_AVAILABLE_IN_2_46 +const gchar *g_win32_registry_key_get_path (GWin32RegistryKey *key); + +GLIB_AVAILABLE_IN_2_46 +const gunichar2 *g_win32_registry_key_get_path_w (GWin32RegistryKey *key); + +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_key_watch (GWin32RegistryKey *key, + gboolean watch_children, + GWin32RegistryKeyWatcherFlags watch_flags, + GWin32RegistryKeyWatchCallbackFunc callback, + gpointer user_data, + GError **error); +GLIB_AVAILABLE_IN_2_46 +gboolean g_win32_registry_key_has_changed (GWin32RegistryKey *key); + +GLIB_AVAILABLE_IN_2_46 +void g_win32_registry_key_erase_change_indicator (GWin32RegistryKey *key); + +GLIB_AVAILABLE_IN_2_66 +const gunichar2 * const *g_win32_registry_get_os_dirs_w (void); + +GLIB_AVAILABLE_IN_2_66 +const gchar * const *g_win32_registry_get_os_dirs (void); + +G_END_DECLS + +#endif /* G_PLATFORM_WIN32 */ + +#endif /* __G_WIN32_REGISTRY_KEY_H__ */ diff --git a/gio/gwin32sid.c b/gio/gwin32sid.c new file mode 100644 index 0000000..6112cf1 --- /dev/null +++ b/gio/gwin32sid.c @@ -0,0 +1,234 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2018 РуÑлан Ижбулатов + * Copyright (C) 2022 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: РуÑлан Ижбулатов + */ + +#include "config.h" + +#include "gwin32sid.h" +#include "gioerror.h" + +#include + +/** + * _g_win32_sid_replace: (skip) + * @dest: A pointer to a SID storage + * @src: Existing SID + * @error: return location for a #GError, or %NULL + * + * Creates a copy of the @src SID and puts that into @dest, after freeing + * existing SID in @dest (if any). + * + * The @src SID must be valid (use IsValidSid() to ensure that). + * + * Returns: TRUE on success, FALSE otherwise + */ +static gboolean +_g_win32_sid_replace (SID **dest, + SID *src, + GError **error) +{ + DWORD sid_len; + SID *new_sid; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (src != NULL, FALSE); + g_return_val_if_fail (dest && *dest == NULL, FALSE); + + sid_len = GetLengthSid (src); + new_sid = g_malloc (sid_len); + + if (!CopySid (sid_len, new_sid, src)) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to copy SID"); + + g_free (new_sid); + return FALSE; + } + else + { + g_free (*dest); + *dest = g_steal_pointer (&new_sid); + + return TRUE; + } +} + +/** + * _g_win32_token_get_sid: (skip) + * @token: A handle of an access token + * @error: return location for a #GError, or %NULL + * + * Gets user SID of the @token and returns a copy of that SID. + * + * Returns: A newly-allocated SID, or NULL in case of an error. + * Free the returned SID with g_free(). + */ +static SID * +_g_win32_token_get_sid (HANDLE token, + GError **error) +{ + TOKEN_USER *token_user = NULL; + DWORD n; + PSID psid; + SID *result = NULL; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (!GetTokenInformation (token, TokenUser, NULL, 0, &n) + && GetLastError () != ERROR_INSUFFICIENT_BUFFER) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to GetTokenInformation"); + + return NULL; + } + + token_user = g_alloca (n); + + if (!GetTokenInformation (token, TokenUser, token_user, n, &n)) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to GetTokenInformation"); + + return NULL; + } + + psid = token_user->User.Sid; + + if (!IsValidSid (psid)) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Invalid SID token"); + + return NULL; + } + + _g_win32_sid_replace (&result, psid, error); + + return result; +} + +/** + * _g_win32_process_get_access_token_sid: (skip) + * @process_id: Identifier of a process to get an access token of + * (use 0 to get a token of the current process) + * @error: return location for a #GError, or %NULL + * + * Opens the process identified by @process_id and opens its token, + * then retrieves SID of the token user and returns a copy of that SID. + * + * Returns: A newly-allocated SID, or NULL in case of an error. + * Free the returned SID with g_free(). + */ +SID * +_g_win32_process_get_access_token_sid (DWORD process_id, + GError **error) +{ + HANDLE process_handle; + HANDLE process_token; + SID *result = NULL; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (process_id == 0) + process_handle = GetCurrentProcess (); + else + process_handle = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id); + + if (process_handle == NULL) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "%s failed", process_id == 0 ? "GetCurrentProcess" : "OpenProcess"); + + return NULL; + } + + if (!OpenProcessToken (process_handle, TOKEN_QUERY, &process_token)) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "OpenProcessToken failed"); + + CloseHandle (process_handle); + return NULL; + } + + result = _g_win32_token_get_sid (process_token, error); + + CloseHandle (process_token); + CloseHandle (process_handle); + + return result; +} + +/** + * _g_win32_sid_to_string: (skip) + * @sid: a SID. + * @error: return location for a #GError, or %NULL + * + * Convert a SID to its string form. + * + * Returns: A newly-allocated string, or NULL in case of an error. + */ +gchar * +_g_win32_sid_to_string (SID *sid, GError **error) +{ + gchar *tmp, *ret; + + g_return_val_if_fail (sid != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + if (!ConvertSidToStringSidA (sid, &tmp)) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (GetLastError ()), + "Failed to ConvertSidToString"); + + return NULL; + } + + ret = g_strdup (tmp); + LocalFree (tmp); + return ret; +} + +/** + * _g_win32_current_process_sid_string: (skip) + * @error: return location for a #GError, or %NULL + * + * Get the current process SID, as a string. + * + * Returns: A newly-allocated string, or NULL in case of an error. + */ +gchar * +_g_win32_current_process_sid_string (GError **error) +{ + SID *sid; + gchar *ret; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + sid = _g_win32_process_get_access_token_sid (0, error); + if (!sid) + return NULL; + + ret = _g_win32_sid_to_string (sid, error); + g_free (sid); + return ret; +} diff --git a/gio/gwin32sid.h b/gio/gwin32sid.h new file mode 100644 index 0000000..84c0377 --- /dev/null +++ b/gio/gwin32sid.h @@ -0,0 +1,40 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2018 РуÑлан Ижбулатов + * Copyright (C) 2022 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: РуÑлан Ижбулатов + */ + +#ifndef __G_WIN32_SID_H__ +#define __G_WIN32_SID_H__ + +#include +#include + +G_BEGIN_DECLS + +SID * _g_win32_process_get_access_token_sid (DWORD process_id, + GError **error); + +gchar * _g_win32_sid_to_string (SID *sid, + GError **error); + +gchar * _g_win32_current_process_sid_string (GError **error); + +G_END_DECLS + +#endif /* __G_WIN32_SID_H__ */ diff --git a/gio/gwin32volumemonitor.c b/gio/gwin32volumemonitor.c new file mode 100644 index 0000000..c6657a3 --- /dev/null +++ b/gio/gwin32volumemonitor.c @@ -0,0 +1,255 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Hans Breuer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + * Hans Breuer + */ + +#include "config.h" + +#include + +#include +#include "glibintl.h" + +#include "gwin32volumemonitor.h" +#include "gwin32mount.h" +#include "gmount.h" +#include "giomodule.h" + +#include + +struct _GWin32VolumeMonitor { + GNativeVolumeMonitor parent; +}; + +#define g_win32_volume_monitor_get_type _g_win32_volume_monitor_get_type +G_DEFINE_TYPE_WITH_CODE (GWin32VolumeMonitor, g_win32_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR, + g_io_extension_point_implement (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "win32", + 0)); + +/** + * get_viewable_logical_drives: + * + * Returns the list of logical and viewable drives as defined by + * GetLogicalDrives() and the registry keys + * Software\Microsoft\Windows\CurrentVersion\Policies\Explorer under + * HKLM or HKCU. If neither key exists the result of + * GetLogicalDrives() is returned. + * + * Returns: bitmask with same meaning as returned by GetLogicalDrives() + */ +static guint32 +get_viewable_logical_drives (void) +{ + guint viewable_drives = GetLogicalDrives (); + HKEY key; + + DWORD var_type = REG_DWORD; //the value's a REG_DWORD type + DWORD no_drives_size = 4; + DWORD no_drives; + gboolean hklm_present = FALSE; + + if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows\\" + L"CurrentVersion\\Policies\\Explorer", + 0, KEY_READ, &key) == ERROR_SUCCESS) + { + if (RegQueryValueExW (key, L"NoDrives", NULL, &var_type, + (LPBYTE) &no_drives, &no_drives_size) == ERROR_SUCCESS) + { + /* We need the bits that are set in viewable_drives, and + * unset in no_drives. + */ + viewable_drives = viewable_drives & ~no_drives; + hklm_present = TRUE; + } + RegCloseKey (key); + } + + /* If the key is present in HKLM then the one in HKCU should be ignored */ + if (!hklm_present) + { + if (RegOpenKeyExW (HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\" + L"CurrentVersion\\Policies\\Explorer", + 0, KEY_READ, &key) == ERROR_SUCCESS) + { + if (RegQueryValueExW (key, L"NoDrives", NULL, &var_type, + (LPBYTE) &no_drives, &no_drives_size) == ERROR_SUCCESS) + { + viewable_drives = viewable_drives & ~no_drives; + } + RegCloseKey (key); + } + } + + return viewable_drives; +} + +/* deliver accessible (aka 'mounted') volumes */ +static GList * +get_mounts (GVolumeMonitor *volume_monitor) +{ + DWORD drives; + gchar drive[4] = "A:\\"; + GQueue queue = G_QUEUE_INIT; + + drives = get_viewable_logical_drives (); + + if (!drives) + g_warning ("get_viewable_logical_drives failed."); + + while (drives && drive[0] <= 'Z') + { + if (drives & 1) + g_queue_push_tail (&queue, _g_win32_mount_new (volume_monitor, drive, NULL)); + + drives >>= 1; + drive[0]++; + } + + return g_steal_pointer (&queue.head); +} + +/* actually 'mounting' volumes is out of GIOs business on win32, so no volumes are delivered either */ +static GList * +get_volumes (GVolumeMonitor *volume_monitor) +{ + return NULL; +} + +/* real hardware */ +static GList * +get_connected_drives (GVolumeMonitor *volume_monitor) +{ + GList *list = NULL; + +#if 0 + HANDLE find_handle; + BOOL found; + wchar_t wc_name[MAX_PATH+1]; + + find_handle = FindFirstVolumeW (wc_name, MAX_PATH); + found = (find_handle != INVALID_HANDLE_VALUE); + while (found) + { + /* I don't know what this code is supposed to do; clearly it now + * does nothing, the returned GList is always NULL. But what was + * this code supposed to be a start of? The volume names that + * the FindFirstVolume/FindNextVolume loop iterates over returns + * device names like + * + * \Device\HarddiskVolume1 + * \Device\HarddiskVolume2 + * \Device\CdRom0 + * + * No DOS devices there, so I don't see the point with the + * QueryDosDevice call below. Probably this code is confusing volumes + * with something else that does contain the mapping from DOS devices + * to volumes. + */ + wchar_t wc_dev_name[MAX_PATH+1]; + guint trailing = wcslen (wc_name) - 1; + + /* remove trailing backslash and leading \\?\\ */ + wc_name[trailing] = L'\0'; + if (QueryDosDeviceW (&wc_name[4], wc_dev_name, MAX_PATH)) + { + gchar *name = g_utf16_to_utf8 (wc_dev_name, -1, NULL, NULL, NULL); + g_print ("%s\n", name); + g_free (name); + } + + found = FindNextVolumeW (find_handle, wc_name, MAX_PATH); + } + if (find_handle != INVALID_HANDLE_VALUE) + FindVolumeClose (find_handle); +#endif + + return list; +} + +static GVolume * +get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + return NULL; +} + +static GMount * +get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + return NULL; +} + +static gboolean +is_supported (void) +{ + return TRUE; +} + +static GMount * +get_mount_for_mount_path (const char *mount_path, + GCancellable *cancellable) +{ + GWin32Mount *mount; + + /* TODO: Set mountable volume? */ + mount = _g_win32_mount_new (NULL, mount_path, NULL); + + return G_MOUNT (mount); +} + +static void +g_win32_volume_monitor_class_init (GWin32VolumeMonitorClass *klass) +{ + GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass); + GNativeVolumeMonitorClass *native_class = G_NATIVE_VOLUME_MONITOR_CLASS (klass); + + monitor_class->get_mounts = get_mounts; + monitor_class->get_volumes = get_volumes; + monitor_class->get_connected_drives = get_connected_drives; + monitor_class->get_volume_for_uuid = get_volume_for_uuid; + monitor_class->get_mount_for_uuid = get_mount_for_uuid; + monitor_class->is_supported = is_supported; + + native_class->get_mount_for_mount_path = get_mount_for_mount_path; +} + +static void +g_win32_volume_monitor_init (GWin32VolumeMonitor *win32_monitor) +{ + /* maybe we should setup a callback window to listen for WM_DEVICECHANGE ? */ +#if 0 + unix_monitor->mount_monitor = g_win32_mount_monitor_new (); + + g_signal_connect (win32_monitor->mount_monitor, + "mounts-changed", G_CALLBACK (mounts_changed), + win32_monitor); + + g_signal_connect (win32_monitor->mount_monitor, + "mountpoints-changed", G_CALLBACK (mountpoints_changed), + win32_monitor); + + update_volumes (win32_monitor); + update_mounts (win32_monitor); +#endif +} diff --git a/gio/gwin32volumemonitor.h b/gio/gwin32volumemonitor.h new file mode 100644 index 0000000..8c036dd --- /dev/null +++ b/gio/gwin32volumemonitor.h @@ -0,0 +1,63 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Hans Breuer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * David Zeuthen + * Hans Breuer + */ + +#ifndef __G_WIN32_VOLUME_MONITOR_H__ +#define __G_WIN32_VOLUME_MONITOR_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_WIN32_VOLUME_MONITOR (_g_win32_volume_monitor_get_type ()) +#define G_WIN32_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WIN32_VOLUME_MONITOR, GWin32VolumeMonitor)) +#define G_WIN32_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WIN32_VOLUME_MONITOR, GWin32VolumeMonitorClass)) +#define G_IS_WIN32_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WIN32_VOLUME_MONITOR)) +#define G_IS_WIN32_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WIN32_VOLUME_MONITOR)) + +typedef struct _GWin32VolumeMonitor GWin32VolumeMonitor; +typedef struct _GWin32VolumeMonitorClass GWin32VolumeMonitorClass; + +/* Forward definitions */ + +/** + * GWin32Mount: + * + * Implementation of the #GMount interface for Win32 systems. + */ +typedef struct _GWin32Mount GWin32Mount; +typedef struct _GWin32Volume GWin32Volume; + +struct _GWin32VolumeMonitorClass +{ + GNativeVolumeMonitorClass parent_class; +}; + +GType _g_win32_volume_monitor_get_type (void) G_GNUC_CONST; + +GVolumeMonitor * _g_win32_volume_monitor_new (void); +GWin32Volume * _g_win32_volume_monitor_lookup_volume_for_mount_path (GWin32VolumeMonitor *monitor, + const char *mount_path); + +G_END_DECLS + +#endif /* __G_WIN32_VOLUME_MONITOR_H__ */ diff --git a/gio/gzlibcompressor.c b/gio/gzlibcompressor.c new file mode 100644 index 0000000..6d4ef50 --- /dev/null +++ b/gio/gzlibcompressor.c @@ -0,0 +1,436 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gzlibcompressor.h" + +#include +#include +#include + +#include "gfileinfo.h" +#include "gioerror.h" +#include "gioenums.h" +#include "gioenumtypes.h" +#include "glibintl.h" + + +enum { + PROP_0, + PROP_FORMAT, + PROP_LEVEL, + PROP_FILE_INFO +}; + +/** + * SECTION:gzlibcompressor + * @short_description: Zlib compressor + * @include: gio/gio.h + * + * #GZlibCompressor is an implementation of #GConverter that + * compresses data using zlib. + */ + +static void g_zlib_compressor_iface_init (GConverterIface *iface); + +/** + * GZlibCompressor: + * + * Zlib decompression + */ +struct _GZlibCompressor +{ + GObject parent_instance; + + GZlibCompressorFormat format; + int level; + z_stream zstream; + gz_header gzheader; + GFileInfo *file_info; +}; + +static void +g_zlib_compressor_set_gzheader (GZlibCompressor *compressor) +{ + /* On win32, these functions were not exported before 1.2.4 */ +#if !defined (G_OS_WIN32) || ZLIB_VERNUM >= 0x1240 + const gchar *filename; + + if (compressor->format != G_ZLIB_COMPRESSOR_FORMAT_GZIP || + compressor->file_info == NULL) + return; + + memset (&compressor->gzheader, 0, sizeof (gz_header)); + compressor->gzheader.os = 0x03; /* Unix */ + + filename = g_file_info_get_name (compressor->file_info); + compressor->gzheader.name = (Bytef *) filename; + compressor->gzheader.name_max = filename ? strlen (filename) + 1 : 0; + + compressor->gzheader.time = + (uLong) g_file_info_get_attribute_uint64 (compressor->file_info, + G_FILE_ATTRIBUTE_TIME_MODIFIED); + + if (deflateSetHeader (&compressor->zstream, &compressor->gzheader) != Z_OK) + g_warning ("unexpected zlib error: %s", compressor->zstream.msg); +#endif /* !G_OS_WIN32 || ZLIB >= 1.2.4 */ +} + +G_DEFINE_TYPE_WITH_CODE (GZlibCompressor, g_zlib_compressor, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, + g_zlib_compressor_iface_init)) + +static void +g_zlib_compressor_finalize (GObject *object) +{ + GZlibCompressor *compressor; + + compressor = G_ZLIB_COMPRESSOR (object); + + deflateEnd (&compressor->zstream); + + if (compressor->file_info) + g_object_unref (compressor->file_info); + + G_OBJECT_CLASS (g_zlib_compressor_parent_class)->finalize (object); +} + + +static void +g_zlib_compressor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GZlibCompressor *compressor; + + compressor = G_ZLIB_COMPRESSOR (object); + + switch (prop_id) + { + case PROP_FORMAT: + compressor->format = g_value_get_enum (value); + break; + + case PROP_LEVEL: + compressor->level = g_value_get_int (value); + break; + + case PROP_FILE_INFO: + g_zlib_compressor_set_file_info (compressor, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_zlib_compressor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GZlibCompressor *compressor; + + compressor = G_ZLIB_COMPRESSOR (object); + + switch (prop_id) + { + case PROP_FORMAT: + g_value_set_enum (value, compressor->format); + break; + + case PROP_LEVEL: + g_value_set_int (value, compressor->level); + break; + + case PROP_FILE_INFO: + g_value_set_object (value, compressor->file_info); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_zlib_compressor_init (GZlibCompressor *compressor) +{ +} + +static void +g_zlib_compressor_constructed (GObject *object) +{ + GZlibCompressor *compressor; + int res; + + compressor = G_ZLIB_COMPRESSOR (object); + + if (compressor->format == G_ZLIB_COMPRESSOR_FORMAT_GZIP) + { + /* + 16 for gzip */ + res = deflateInit2 (&compressor->zstream, + compressor->level, Z_DEFLATED, + MAX_WBITS + 16, 8, + Z_DEFAULT_STRATEGY); + } + else if (compressor->format == G_ZLIB_COMPRESSOR_FORMAT_RAW) + { + /* negative wbits for raw */ + res = deflateInit2 (&compressor->zstream, + compressor->level, Z_DEFLATED, + -MAX_WBITS, 8, + Z_DEFAULT_STRATEGY); + } + else /* ZLIB */ + res = deflateInit (&compressor->zstream, compressor->level); + + if (res == Z_MEM_ERROR ) + g_error ("GZlibCompressor: Not enough memory for zlib use"); + + if (res != Z_OK) + g_warning ("unexpected zlib error: %s", compressor->zstream.msg); + + g_zlib_compressor_set_gzheader (compressor); +} + +static void +g_zlib_compressor_class_init (GZlibCompressorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_zlib_compressor_finalize; + gobject_class->constructed = g_zlib_compressor_constructed; + gobject_class->get_property = g_zlib_compressor_get_property; + gobject_class->set_property = g_zlib_compressor_set_property; + + g_object_class_install_property (gobject_class, + PROP_FORMAT, + g_param_spec_enum ("format", + P_("compression format"), + P_("The format of the compressed data"), + G_TYPE_ZLIB_COMPRESSOR_FORMAT, + G_ZLIB_COMPRESSOR_FORMAT_ZLIB, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_LEVEL, + g_param_spec_int ("level", + P_("compression level"), + P_("The level of compression from 0 (no compression) to 9 (most compression), -1 for the default level"), + -1, 9, + -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GZlibCompressor:file-info: + * + * If set to a non-%NULL #GFileInfo object, and #GZlibCompressor:format is + * %G_ZLIB_COMPRESSOR_FORMAT_GZIP, the compressor will write the file name + * and modification time from the file info to the GZIP header. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_FILE_INFO, + g_param_spec_object ("file-info", + P_("file info"), + P_("File info"), + G_TYPE_FILE_INFO, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_zlib_compressor_new: + * @format: The format to use for the compressed data + * @level: compression level (0-9), -1 for default + * + * Creates a new #GZlibCompressor. + * + * Returns: a new #GZlibCompressor + * + * Since: 2.24 + **/ +GZlibCompressor * +g_zlib_compressor_new (GZlibCompressorFormat format, + int level) +{ + GZlibCompressor *compressor; + + compressor = g_object_new (G_TYPE_ZLIB_COMPRESSOR, + "format", format, + "level", level, + NULL); + + return compressor; +} + +/** + * g_zlib_compressor_get_file_info: + * @compressor: a #GZlibCompressor + * + * Returns the #GZlibCompressor:file-info property. + * + * Returns: (nullable) (transfer none): a #GFileInfo, or %NULL + * + * Since: 2.26 + */ +GFileInfo * +g_zlib_compressor_get_file_info (GZlibCompressor *compressor) +{ + g_return_val_if_fail (G_IS_ZLIB_COMPRESSOR (compressor), NULL); + + return compressor->file_info; +} + +/** + * g_zlib_compressor_set_file_info: + * @compressor: a #GZlibCompressor + * @file_info: (nullable): a #GFileInfo + * + * Sets @file_info in @compressor. If non-%NULL, and @compressor's + * #GZlibCompressor:format property is %G_ZLIB_COMPRESSOR_FORMAT_GZIP, + * it will be used to set the file name and modification time in + * the GZIP header of the compressed data. + * + * Note: it is an error to call this function while a compression is in + * progress; it may only be called immediately after creation of @compressor, + * or after resetting it with g_converter_reset(). + * + * Since: 2.26 + */ +void +g_zlib_compressor_set_file_info (GZlibCompressor *compressor, + GFileInfo *file_info) +{ + g_return_if_fail (G_IS_ZLIB_COMPRESSOR (compressor)); + + if (file_info == compressor->file_info) + return; + + if (compressor->file_info) + g_object_unref (compressor->file_info); + if (file_info) + g_object_ref (file_info); + compressor->file_info = file_info; + g_object_notify (G_OBJECT (compressor), "file-info"); + + g_zlib_compressor_set_gzheader (compressor); +} + +static void +g_zlib_compressor_reset (GConverter *converter) +{ + GZlibCompressor *compressor = G_ZLIB_COMPRESSOR (converter); + int res; + + res = deflateReset (&compressor->zstream); + if (res != Z_OK) + g_warning ("unexpected zlib error: %s", compressor->zstream.msg); + + /* deflateReset reset the header too, so re-set it */ + g_zlib_compressor_set_gzheader (compressor); +} + +static GConverterResult +g_zlib_compressor_convert (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + GZlibCompressor *compressor; + int res; + int flush; + + compressor = G_ZLIB_COMPRESSOR (converter); + + compressor->zstream.next_in = (void *)inbuf; + compressor->zstream.avail_in = inbuf_size; + + compressor->zstream.next_out = outbuf; + compressor->zstream.avail_out = outbuf_size; + + flush = Z_NO_FLUSH; + if (flags & G_CONVERTER_INPUT_AT_END) + flush = Z_FINISH; + else if (flags & G_CONVERTER_FLUSH) + flush = Z_SYNC_FLUSH; + + res = deflate (&compressor->zstream, flush); + + if (res == Z_MEM_ERROR) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Not enough memory")); + return G_CONVERTER_ERROR; + } + + if (res == Z_STREAM_ERROR) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Internal error: %s"), compressor->zstream.msg); + return G_CONVERTER_ERROR; + } + + if (res == Z_BUF_ERROR) + { + if (flags & G_CONVERTER_FLUSH) + return G_CONVERTER_FLUSHED; + + /* We do have output space, so this should only happen if we + have no input but need some */ + + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, + _("Need more input")); + return G_CONVERTER_ERROR; + } + + if (res == Z_OK || res == Z_STREAM_END) + { + *bytes_read = inbuf_size - compressor->zstream.avail_in; + *bytes_written = outbuf_size - compressor->zstream.avail_out; + + if (res == Z_STREAM_END) + return G_CONVERTER_FINISHED; + return G_CONVERTER_CONVERTED; + } + + g_assert_not_reached (); +} + +static void +g_zlib_compressor_iface_init (GConverterIface *iface) +{ + iface->convert = g_zlib_compressor_convert; + iface->reset = g_zlib_compressor_reset; +} diff --git a/gio/gzlibcompressor.h b/gio/gzlibcompressor.h new file mode 100644 index 0000000..f89b30f --- /dev/null +++ b/gio/gzlibcompressor.h @@ -0,0 +1,62 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_ZLIB_COMPRESSOR_H__ +#define __G_ZLIB_COMPRESSOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_ZLIB_COMPRESSOR (g_zlib_compressor_get_type ()) +#define G_ZLIB_COMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_ZLIB_COMPRESSOR, GZlibCompressor)) +#define G_ZLIB_COMPRESSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_ZLIB_COMPRESSOR, GZlibCompressorClass)) +#define G_IS_ZLIB_COMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_ZLIB_COMPRESSOR)) +#define G_IS_ZLIB_COMPRESSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_ZLIB_COMPRESSOR)) +#define G_ZLIB_COMPRESSOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_ZLIB_COMPRESSOR, GZlibCompressorClass)) + +typedef struct _GZlibCompressorClass GZlibCompressorClass; + +struct _GZlibCompressorClass +{ + GObjectClass parent_class; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_zlib_compressor_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GZlibCompressor *g_zlib_compressor_new (GZlibCompressorFormat format, + int level); + +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_zlib_compressor_get_file_info (GZlibCompressor *compressor); +GLIB_AVAILABLE_IN_ALL +void g_zlib_compressor_set_file_info (GZlibCompressor *compressor, + GFileInfo *file_info); + +G_END_DECLS + +#endif /* __G_ZLIB_COMPRESSOR_H__ */ diff --git a/gio/gzlibdecompressor.c b/gio/gzlibdecompressor.c new file mode 100644 index 0000000..8e54812 --- /dev/null +++ b/gio/gzlibdecompressor.c @@ -0,0 +1,413 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gzlibdecompressor.h" + +#include +#include +#include + +#include "gfileinfo.h" +#include "gioerror.h" +#include "gioenums.h" +#include "gioenumtypes.h" +#include "glibintl.h" + + +enum { + PROP_0, + PROP_FORMAT, + PROP_FILE_INFO +}; + +/** + * SECTION:gzlibdecompressor + * @short_description: Zlib decompressor + * @include: gio/gio.h + * + * #GZlibDecompressor is an implementation of #GConverter that + * decompresses data compressed with zlib. + */ + +static void g_zlib_decompressor_iface_init (GConverterIface *iface); + +typedef struct { + gz_header gzheader; + char filename[257]; + GFileInfo *file_info; +} HeaderData; + +/** + * GZlibDecompressor: + * + * Zlib decompression + */ +struct _GZlibDecompressor +{ + GObject parent_instance; + + GZlibCompressorFormat format; + z_stream zstream; + HeaderData *header_data; +}; + +static void +g_zlib_decompressor_set_gzheader (GZlibDecompressor *decompressor) +{ + /* On win32, these functions were not exported before 1.2.4 */ +#if !defined (G_OS_WIN32) || ZLIB_VERNUM >= 0x1240 + if (decompressor->format != G_ZLIB_COMPRESSOR_FORMAT_GZIP) + return; + + if (decompressor->header_data != NULL) + { + if (decompressor->header_data->file_info) + g_object_unref (decompressor->header_data->file_info); + + memset (decompressor->header_data, 0, sizeof (HeaderData)); + } + else + { + decompressor->header_data = g_new0 (HeaderData, 1); + } + + decompressor->header_data->gzheader.name = (Bytef*) &decompressor->header_data->filename; + /* We keep one byte to guarantee the string is 0-terminated */ + decompressor->header_data->gzheader.name_max = 256; + + if (inflateGetHeader (&decompressor->zstream, &decompressor->header_data->gzheader) != Z_OK) + g_warning ("unexpected zlib error: %s", decompressor->zstream.msg); +#endif /* !G_OS_WIN32 || ZLIB >= 1.2.4 */ +} + +G_DEFINE_TYPE_WITH_CODE (GZlibDecompressor, g_zlib_decompressor, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, + g_zlib_decompressor_iface_init)) + +static void +g_zlib_decompressor_finalize (GObject *object) +{ + GZlibDecompressor *decompressor; + + decompressor = G_ZLIB_DECOMPRESSOR (object); + + inflateEnd (&decompressor->zstream); + + if (decompressor->header_data != NULL) + { + if (decompressor->header_data->file_info) + g_object_unref (decompressor->header_data->file_info); + g_free (decompressor->header_data); + } + + G_OBJECT_CLASS (g_zlib_decompressor_parent_class)->finalize (object); +} + + +static void +g_zlib_decompressor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GZlibDecompressor *decompressor; + + decompressor = G_ZLIB_DECOMPRESSOR (object); + + switch (prop_id) + { + case PROP_FORMAT: + decompressor->format = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + +} + +static void +g_zlib_decompressor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GZlibDecompressor *decompressor; + + decompressor = G_ZLIB_DECOMPRESSOR (object); + + switch (prop_id) + { + case PROP_FORMAT: + g_value_set_enum (value, decompressor->format); + break; + + case PROP_FILE_INFO: + if (decompressor->header_data) + g_value_set_object (value, decompressor->header_data->file_info); + else + g_value_set_object (value, NULL); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_zlib_decompressor_init (GZlibDecompressor *decompressor) +{ +} + +static void +g_zlib_decompressor_constructed (GObject *object) +{ + GZlibDecompressor *decompressor; + int res; + + decompressor = G_ZLIB_DECOMPRESSOR (object); + + if (decompressor->format == G_ZLIB_COMPRESSOR_FORMAT_GZIP) + { + /* + 16 for gzip */ + res = inflateInit2 (&decompressor->zstream, MAX_WBITS + 16); + } + else if (decompressor->format == G_ZLIB_COMPRESSOR_FORMAT_RAW) + { + /* Negative for raw */ + res = inflateInit2 (&decompressor->zstream, -MAX_WBITS); + } + else /* ZLIB */ + res = inflateInit (&decompressor->zstream); + + if (res == Z_MEM_ERROR ) + g_error ("GZlibDecompressor: Not enough memory for zlib use"); + + if (res != Z_OK) + g_warning ("unexpected zlib error: %s", decompressor->zstream.msg); + + g_zlib_decompressor_set_gzheader (decompressor); +} + +static void +g_zlib_decompressor_class_init (GZlibDecompressorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_zlib_decompressor_finalize; + gobject_class->constructed = g_zlib_decompressor_constructed; + gobject_class->get_property = g_zlib_decompressor_get_property; + gobject_class->set_property = g_zlib_decompressor_set_property; + + g_object_class_install_property (gobject_class, + PROP_FORMAT, + g_param_spec_enum ("format", + P_("compression format"), + P_("The format of the compressed data"), + G_TYPE_ZLIB_COMPRESSOR_FORMAT, + G_ZLIB_COMPRESSOR_FORMAT_ZLIB, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * GZlibDecompressor:file-info: + * + * A #GFileInfo containing the information found in the GZIP header + * of the data stream processed, or %NULL if the header was not yet + * fully processed, is not present at all, or the compressor's + * #GZlibDecompressor:format property is not %G_ZLIB_COMPRESSOR_FORMAT_GZIP. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_FILE_INFO, + g_param_spec_object ("file-info", + P_("file info"), + P_("File info"), + G_TYPE_FILE_INFO, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * g_zlib_decompressor_new: + * @format: The format to use for the compressed data + * + * Creates a new #GZlibDecompressor. + * + * Returns: a new #GZlibDecompressor + * + * Since: 2.24 + **/ +GZlibDecompressor * +g_zlib_decompressor_new (GZlibCompressorFormat format) +{ + GZlibDecompressor *decompressor; + + decompressor = g_object_new (G_TYPE_ZLIB_DECOMPRESSOR, + "format", format, + NULL); + + return decompressor; +} + +/** + * g_zlib_decompressor_get_file_info: + * @decompressor: a #GZlibDecompressor + * + * Retrieves the #GFileInfo constructed from the GZIP header data + * of compressed data processed by @compressor, or %NULL if @decompressor's + * #GZlibDecompressor:format property is not %G_ZLIB_COMPRESSOR_FORMAT_GZIP, + * or the header data was not fully processed yet, or it not present in the + * data stream at all. + * + * Returns: (nullable) (transfer none): a #GFileInfo, or %NULL + * + * Since: 2.26 + */ +GFileInfo * +g_zlib_decompressor_get_file_info (GZlibDecompressor *decompressor) +{ + g_return_val_if_fail (G_IS_ZLIB_DECOMPRESSOR (decompressor), NULL); + + if (decompressor->header_data) + return decompressor->header_data->file_info; + + return NULL; +} + +static void +g_zlib_decompressor_reset (GConverter *converter) +{ + GZlibDecompressor *decompressor = G_ZLIB_DECOMPRESSOR (converter); + int res; + + res = inflateReset (&decompressor->zstream); + if (res != Z_OK) + g_warning ("unexpected zlib error: %s", decompressor->zstream.msg); + + g_zlib_decompressor_set_gzheader (decompressor); +} + +static GConverterResult +g_zlib_decompressor_convert (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + GZlibDecompressor *decompressor; + int res; + + decompressor = G_ZLIB_DECOMPRESSOR (converter); + + decompressor->zstream.next_in = (void *)inbuf; + decompressor->zstream.avail_in = inbuf_size; + + decompressor->zstream.next_out = outbuf; + decompressor->zstream.avail_out = outbuf_size; + + res = inflate (&decompressor->zstream, Z_NO_FLUSH); + + if (res == Z_DATA_ERROR || res == Z_NEED_DICT) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + _("Invalid compressed data")); + return G_CONVERTER_ERROR; + } + + if (res == Z_MEM_ERROR) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Not enough memory")); + return G_CONVERTER_ERROR; + } + + if (res == Z_STREAM_ERROR) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Internal error: %s"), decompressor->zstream.msg); + return G_CONVERTER_ERROR; + } + + if (res == Z_BUF_ERROR) + { + if (flags & G_CONVERTER_FLUSH) + return G_CONVERTER_FLUSHED; + + /* Z_FINISH not set, so this means no progress could be made */ + /* We do have output space, so this should only happen if we + have no input but need some */ + + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, + _("Need more input")); + return G_CONVERTER_ERROR; + } + + g_assert (res == Z_OK || res == Z_STREAM_END); + + *bytes_read = inbuf_size - decompressor->zstream.avail_in; + *bytes_written = outbuf_size - decompressor->zstream.avail_out; + +#if !defined (G_OS_WIN32) || ZLIB_VERNUM >= 0x1240 + if (decompressor->header_data != NULL && + decompressor->header_data->gzheader.done == 1) + { + HeaderData *data = decompressor->header_data; + + /* So we don't notify again */ + data->gzheader.done = 2; + + data->file_info = g_file_info_new (); + g_file_info_set_attribute_uint64 (data->file_info, + G_FILE_ATTRIBUTE_TIME_MODIFIED, + data->gzheader.time); + g_file_info_set_attribute_uint32 (data->file_info, + G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, + 0); + + if (data->filename[0] != '\0') + g_file_info_set_attribute_byte_string (data->file_info, + G_FILE_ATTRIBUTE_STANDARD_NAME, + data->filename); + + g_object_notify (G_OBJECT (decompressor), "file-info"); + } +#endif /* !G_OS_WIN32 || ZLIB >= 1.2.4 */ + + if (res == Z_STREAM_END) + return G_CONVERTER_FINISHED; + return G_CONVERTER_CONVERTED; +} + +static void +g_zlib_decompressor_iface_init (GConverterIface *iface) +{ + iface->convert = g_zlib_decompressor_convert; + iface->reset = g_zlib_decompressor_reset; +} diff --git a/gio/gzlibdecompressor.h b/gio/gzlibdecompressor.h new file mode 100644 index 0000000..373ac67 --- /dev/null +++ b/gio/gzlibdecompressor.h @@ -0,0 +1,58 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __G_ZLIB_DECOMPRESSOR_H__ +#define __G_ZLIB_DECOMPRESSOR_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_ZLIB_DECOMPRESSOR (g_zlib_decompressor_get_type ()) +#define G_ZLIB_DECOMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_ZLIB_DECOMPRESSOR, GZlibDecompressor)) +#define G_ZLIB_DECOMPRESSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_ZLIB_DECOMPRESSOR, GZlibDecompressorClass)) +#define G_IS_ZLIB_DECOMPRESSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_ZLIB_DECOMPRESSOR)) +#define G_IS_ZLIB_DECOMPRESSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_ZLIB_DECOMPRESSOR)) +#define G_ZLIB_DECOMPRESSOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_ZLIB_DECOMPRESSOR, GZlibDecompressorClass)) + +typedef struct _GZlibDecompressorClass GZlibDecompressorClass; + +struct _GZlibDecompressorClass +{ + GObjectClass parent_class; +}; + +GLIB_AVAILABLE_IN_ALL +GType g_zlib_decompressor_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GZlibDecompressor *g_zlib_decompressor_new (GZlibCompressorFormat format); + +GLIB_AVAILABLE_IN_ALL +GFileInfo *g_zlib_decompressor_get_file_info (GZlibDecompressor *decompressor); + +G_END_DECLS + +#endif /* __G_ZLIB_DECOMPRESSOR_H__ */ diff --git a/gio/inotify/ginotifyfilemonitor.c b/gio/inotify/ginotifyfilemonitor.c new file mode 100644 index 0000000..b2364cc --- /dev/null +++ b/gio/inotify/ginotifyfilemonitor.c @@ -0,0 +1,114 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2007 Sebastian Dröge. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Alexander Larsson + * John McCutchan + * Sebastian Dröge + * Ryan Lortie + */ + +#include "config.h" + +#include "ginotifyfilemonitor.h" +#include + +#define USE_INOTIFY 1 +#include "inotify-helper.h" + +struct _GInotifyFileMonitor +{ + GLocalFileMonitor parent_instance; + + inotify_sub *sub; +}; + +G_DEFINE_TYPE_WITH_CODE (GInotifyFileMonitor, g_inotify_file_monitor, G_TYPE_LOCAL_FILE_MONITOR, + g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, "inotify", 20)) + +static gboolean +g_inotify_file_monitor_is_supported (void) +{ + return _ih_startup (); +} + +static void +g_inotify_file_monitor_start (GLocalFileMonitor *local_monitor, + const gchar *dirname, + const gchar *basename, + const gchar *filename, + GFileMonitorSource *source) +{ + GInotifyFileMonitor *inotify_monitor = G_INOTIFY_FILE_MONITOR (local_monitor); + gboolean success G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + /* should already have been called, from is_supported() */ + success = _ih_startup (); + g_assert (success); + + inotify_monitor->sub = _ih_sub_new (dirname, basename, filename, source); + _ih_sub_add (inotify_monitor->sub); +} + +static gboolean +g_inotify_file_monitor_cancel (GFileMonitor *monitor) +{ + GInotifyFileMonitor *inotify_monitor = G_INOTIFY_FILE_MONITOR (monitor); + + if (inotify_monitor->sub) + { + _ih_sub_cancel (inotify_monitor->sub); + _ih_sub_free (inotify_monitor->sub); + inotify_monitor->sub = NULL; + } + + return TRUE; +} + +static void +g_inotify_file_monitor_finalize (GObject *object) +{ +#ifndef G_DISABLE_ASSERT + GInotifyFileMonitor *inotify_monitor = G_INOTIFY_FILE_MONITOR (object); +#endif + + /* must surely have been cancelled already */ + g_assert (!inotify_monitor->sub); + + G_OBJECT_CLASS (g_inotify_file_monitor_parent_class)->finalize (object); +} + +static void +g_inotify_file_monitor_init (GInotifyFileMonitor* monitor) +{ +} + +static void +g_inotify_file_monitor_class_init (GInotifyFileMonitorClass* klass) +{ + GObjectClass* gobject_class = G_OBJECT_CLASS (klass); + GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass); + GLocalFileMonitorClass *local_file_monitor_class = G_LOCAL_FILE_MONITOR_CLASS (klass); + + local_file_monitor_class->is_supported = g_inotify_file_monitor_is_supported; + local_file_monitor_class->start = g_inotify_file_monitor_start; + local_file_monitor_class->mount_notify = TRUE; + file_monitor_class->cancel = g_inotify_file_monitor_cancel; + + gobject_class->finalize = g_inotify_file_monitor_finalize; +} diff --git a/gio/inotify/ginotifyfilemonitor.h b/gio/inotify/ginotifyfilemonitor.h new file mode 100644 index 0000000..2b40ff2 --- /dev/null +++ b/gio/inotify/ginotifyfilemonitor.h @@ -0,0 +1,52 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2007 Sebastian Dröge. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Alexander Larsson + * John McCutchan + * Sebastian Dröge + */ + +#ifndef __G_INOTIFY_FILE_MONITOR_H__ +#define __G_INOTIFY_FILE_MONITOR_H__ + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_INOTIFY_FILE_MONITOR (g_inotify_file_monitor_get_type ()) +#define G_INOTIFY_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_INOTIFY_FILE_MONITOR, GInotifyFileMonitor)) +#define G_INOTIFY_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_INOTIFY_FILE_MONITOR, GInotifyFileMonitorClass)) +#define G_IS_INOTIFY_FILE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_INOTIFY_FILE_MONITOR)) +#define G_IS_INOTIFY_FILE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_INOTIFY_FILE_MONITOR)) + +typedef struct _GInotifyFileMonitor GInotifyFileMonitor; +typedef struct _GInotifyFileMonitorClass GInotifyFileMonitorClass; + +struct _GInotifyFileMonitorClass { + GLocalFileMonitorClass parent_class; +}; + +GType g_inotify_file_monitor_get_type (void); + +G_END_DECLS + +#endif /* __G_INOTIFY_FILE_MONITOR_H__ */ diff --git a/gio/inotify/inotify-helper.c b/gio/inotify/inotify-helper.c new file mode 100644 index 0000000..c2b98b1 --- /dev/null +++ b/gio/inotify/inotify-helper.c @@ -0,0 +1,290 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */ + +/* inotify-helper.c - GVFS Monitor based on inotify. + + Copyright (C) 2007 John McCutchan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Authors: + John McCutchan +*/ + +#include "config.h" +#include +#include +#include +#include +#include +/* Just include the local header to stop all the pain */ +#include +#include +#include +#include "inotify-helper.h" +#include "inotify-missing.h" +#include "inotify-path.h" + +static gboolean ih_debug_enabled = FALSE; +#define IH_W if (ih_debug_enabled) g_warning + +static gboolean ih_event_callback (ik_event_t *event, + inotify_sub *sub, + gboolean file_event); +static void ih_not_missing_callback (inotify_sub *sub); + +/* We share this lock with inotify-kernel.c and inotify-missing.c + * + * inotify-kernel.c takes the lock when it reads events from + * the kernel and when it processes those events + * + * inotify-missing.c takes the lock when it is scanning the missing + * list. + * + * We take the lock in all public functions + */ +G_LOCK_DEFINE (inotify_lock); + +static GFileMonitorEvent ih_mask_to_EventFlags (guint32 mask); + +/** + * _ih_startup: + * + * Initializes the inotify backend. This must be called before + * any other functions in this module. + * + * Returns: #TRUE if initialization succeeded, #FALSE otherwise + */ +gboolean +_ih_startup (void) +{ + static gboolean initialized = FALSE; + static gboolean result = FALSE; + + G_LOCK (inotify_lock); + + if (initialized == TRUE) + { + G_UNLOCK (inotify_lock); + return result; + } + + result = _ip_startup (ih_event_callback); + if (!result) + { + G_UNLOCK (inotify_lock); + return FALSE; + } + _im_startup (ih_not_missing_callback); + + IH_W ("started gvfs inotify backend\n"); + + initialized = TRUE; + + G_UNLOCK (inotify_lock); + + return TRUE; +} + +/* + * Adds a subscription to be monitored. + */ +gboolean +_ih_sub_add (inotify_sub *sub) +{ + G_LOCK (inotify_lock); + + if (!_ip_start_watching (sub)) + _im_add (sub); + + G_UNLOCK (inotify_lock); + + return TRUE; +} + +/* + * Cancels a subscription which was being monitored. + */ +gboolean +_ih_sub_cancel (inotify_sub *sub) +{ + G_LOCK (inotify_lock); + + if (!sub->cancelled) + { + IH_W ("cancelling %s\n", sub->dirname); + sub->cancelled = TRUE; + _im_rm (sub); + _ip_stop_watching (sub); + } + + G_UNLOCK (inotify_lock); + + return TRUE; +} + +static char * +_ih_fullpath_from_event (ik_event_t *event, + const char *dirname, + const char *filename) +{ + char *fullpath; + + if (filename) + fullpath = g_strdup_printf ("%s/%s", dirname, filename); + else if (event->name) + fullpath = g_strdup_printf ("%s/%s", dirname, event->name); + else + fullpath = g_strdup_printf ("%s/", dirname); + + return fullpath; +} + +static gboolean +ih_event_callback (ik_event_t *event, + inotify_sub *sub, + gboolean file_event) +{ + gboolean interesting; + GFileMonitorEvent event_flags; + + event_flags = ih_mask_to_EventFlags (event->mask); + + if (event->mask & IN_MOVE) + { + /* We either have a rename (in the same directory) or a move + * (between different directories). + */ + if (event->pair && event->pair->wd == event->wd) + { + /* this is a rename */ + interesting = g_file_monitor_source_handle_event (sub->user_data, G_FILE_MONITOR_EVENT_RENAMED, + event->name, event->pair->name, NULL, event->timestamp); + } + else + { + GFile *other; + + if (event->pair) + { + const char *parent_dir; + gchar *fullpath; + + parent_dir = _ip_get_path_for_wd (event->pair->wd); + fullpath = _ih_fullpath_from_event (event->pair, parent_dir, NULL); + other = g_file_new_for_path (fullpath); + g_free (fullpath); + } + else + other = NULL; + + /* This is either an incoming or outgoing move. Since we checked the + * event->mask above, it should have converted to a #GFileMonitorEvent + * properly. If not, the assumption we have made about event->mask + * only ever having a single bit set (apart from IN_ISDIR) is false. + * The kernel documentation is lacking here. */ + g_assert ((int) event_flags != -1); + interesting = g_file_monitor_source_handle_event (sub->user_data, event_flags, + event->name, NULL, other, event->timestamp); + + if (other) + g_object_unref (other); + } + } + else if ((int) event_flags != -1) + /* unpaired event -- no 'other' field */ + interesting = g_file_monitor_source_handle_event (sub->user_data, event_flags, + event->name, NULL, NULL, event->timestamp); + else + interesting = FALSE; + + if (event->mask & IN_CREATE) + { + const gchar *parent_dir; + gchar *fullname; + struct stat buf; + gint s; + + /* The kernel reports IN_CREATE for two types of events: + * + * - creat(), in which case IN_CLOSE_WRITE will come soon; or + * - link(), mkdir(), mknod(), etc., in which case it won't + * + * We can attempt to detect the second case and send the + * CHANGES_DONE immediately so that the user isn't left waiting. + * + * The detection for link() is not 100% reliable since the link + * count could be 1 if the original link was deleted or if + * O_TMPFILE was being used, but in that case the virtual + * CHANGES_DONE will be emitted to close the loop. + */ + + parent_dir = _ip_get_path_for_wd (event->wd); + fullname = _ih_fullpath_from_event (event, parent_dir, NULL); + s = stat (fullname, &buf); + g_free (fullname); + + /* if it doesn't look like the result of creat()... */ + if (s != 0 || !S_ISREG (buf.st_mode) || buf.st_nlink != 1) + g_file_monitor_source_handle_event (sub->user_data, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, + event->name, NULL, NULL, event->timestamp); + } + + return interesting; +} + +static void +ih_not_missing_callback (inotify_sub *sub) +{ + gint now = g_get_monotonic_time (); + + g_file_monitor_source_handle_event (sub->user_data, G_FILE_MONITOR_EVENT_CREATED, + sub->filename, NULL, NULL, now); + g_file_monitor_source_handle_event (sub->user_data, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, + sub->filename, NULL, NULL, now); +} + +/* Transforms a inotify event to a GVFS event. */ +static GFileMonitorEvent +ih_mask_to_EventFlags (guint32 mask) +{ + mask &= ~IN_ISDIR; + switch (mask) + { + case IN_MODIFY: + return G_FILE_MONITOR_EVENT_CHANGED; + case IN_CLOSE_WRITE: + return G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT; + case IN_ATTRIB: + return G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED; + case IN_MOVE_SELF: + case IN_DELETE: + case IN_DELETE_SELF: + return G_FILE_MONITOR_EVENT_DELETED; + case IN_CREATE: + return G_FILE_MONITOR_EVENT_CREATED; + case IN_MOVED_FROM: + return G_FILE_MONITOR_EVENT_MOVED_OUT; + case IN_MOVED_TO: + return G_FILE_MONITOR_EVENT_MOVED_IN; + case IN_UNMOUNT: + return G_FILE_MONITOR_EVENT_UNMOUNTED; + case IN_Q_OVERFLOW: + case IN_OPEN: + case IN_CLOSE_NOWRITE: + case IN_ACCESS: + case IN_IGNORED: + default: + return -1; + } +} diff --git a/gio/inotify/inotify-helper.h b/gio/inotify/inotify-helper.h new file mode 100644 index 0000000..340f33d --- /dev/null +++ b/gio/inotify/inotify-helper.h @@ -0,0 +1,31 @@ +/* inotify-helper.h - GVFS Directory Monitor using inotify + + Copyright (C) 2007 John McCutchan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Author: John McCutchan +*/ + + +#ifndef __INOTIFY_HELPER_H +#define __INOTIFY_HELPER_H + +#include "inotify-sub.h" + +gboolean _ih_startup (void); +gboolean _ih_sub_add (inotify_sub *sub); +gboolean _ih_sub_cancel (inotify_sub *sub); + +#endif /* __INOTIFY_HELPER_H */ diff --git a/gio/inotify/inotify-kernel.c b/gio/inotify/inotify-kernel.c new file mode 100644 index 0000000..92d61fc --- /dev/null +++ b/gio/inotify/inotify-kernel.c @@ -0,0 +1,458 @@ +/* + Copyright (C) 2005 John McCutchan + Copyright © 2015 Canonical Limited + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Authors: + Ryan Lortie + John McCutchan +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include "inotify-kernel.h" +#include +#ifdef HAVE_SYS_FILIO_H +#include +#endif +#include + +#include "glib-private.h" + +/* From inotify(7) */ +#define MAX_EVENT_SIZE (sizeof(struct inotify_event) + NAME_MAX + 1) + +/* Amount of time to sleep on receipt of uninteresting events */ +#define BOREDOM_SLEEP_TIME (100 * G_TIME_SPAN_MILLISECOND) + +/* Define limits on the maximum amount of time and maximum amount of + * interceding events between FROM/TO that can be merged. + */ +#define MOVE_PAIR_DELAY (10 * G_TIME_SPAN_MILLISECOND) +#define MOVE_PAIR_DISTANCE (100) + +/* We use the lock from inotify-helper.c + * + * We only have to take it on our read callback. + * + * The rest of locking is taken care of in inotify-helper.c + */ +G_LOCK_EXTERN (inotify_lock); + +static ik_event_t * +ik_event_new (struct inotify_event *kevent, + gint64 now) +{ + ik_event_t *event = g_new0 (ik_event_t, 1); + + event->wd = kevent->wd; + event->mask = kevent->mask; + event->cookie = kevent->cookie; + event->len = kevent->len; + event->timestamp = now; + if (event->len) + event->name = g_strdup (kevent->name); + else + event->name = NULL; + + return event; +} + +void +_ik_event_free (ik_event_t *event) +{ + if (event->pair) + { + event->pair->pair = NULL; + _ik_event_free (event->pair); + } + + g_free (event->name); + g_free (event); +} + +typedef struct +{ + GSource source; + + GQueue queue; + gpointer fd_tag; + gint fd; + + GHashTable *unmatched_moves; + gboolean is_bored; +} InotifyKernelSource; + +static InotifyKernelSource *inotify_source; + +static gint64 +ik_source_get_dispatch_time (InotifyKernelSource *iks) +{ + ik_event_t *head; + + head = g_queue_peek_head (&iks->queue); + + /* nothing in the queue: not ready */ + if (!head) + return -1; + + /* if it's not an unpaired move, it is ready now */ + if (~head->mask & IN_MOVED_FROM || head->pair) + return 0; + + /* if the queue is too long then it's ready now */ + if (iks->queue.length > MOVE_PAIR_DISTANCE) + return 0; + + /* otherwise, it's ready after the delay */ + return head->timestamp + MOVE_PAIR_DELAY; +} + +static gboolean +ik_source_can_dispatch_now (InotifyKernelSource *iks, + gint64 now) +{ + gint64 dispatch_time; + + dispatch_time = ik_source_get_dispatch_time (iks); + + return 0 <= dispatch_time && dispatch_time <= now; +} + +static gsize +ik_source_read_some_events (InotifyKernelSource *iks, + gchar *buffer, + gsize buffer_len) +{ + gssize result; + int errsv; + +again: + result = read (iks->fd, buffer, buffer_len); + errsv = errno; + + if (result < 0) + { + if (errsv == EINTR) + goto again; + + if (errsv == EAGAIN) + return 0; + + g_error ("inotify read(): %s", g_strerror (errsv)); + } + else if (result == 0) + g_error ("inotify unexpectedly hit eof"); + + return result; +} + +static gchar * +ik_source_read_all_the_events (InotifyKernelSource *iks, + gchar *buffer, + gsize buffer_len, + gsize *length_out) +{ + gsize n_read; + + n_read = ik_source_read_some_events (iks, buffer, buffer_len); + + /* Check if we might have gotten another event if we had passed in a + * bigger buffer... + */ + if (n_read + MAX_EVENT_SIZE > buffer_len) + { + gchar *new_buffer; + guint n_readable; + gint result; + int errsv; + + /* figure out how many more bytes there are to read */ + result = ioctl (iks->fd, FIONREAD, &n_readable); + errsv = errno; + if (result != 0) + g_error ("inotify ioctl(FIONREAD): %s", g_strerror (errsv)); + + if (n_readable != 0) + { + /* there is in fact more data. allocate a new buffer, copy + * the existing data, and then append the remaining. + */ + new_buffer = g_malloc (n_read + n_readable); + memcpy (new_buffer, buffer, n_read); + n_read += ik_source_read_some_events (iks, new_buffer + n_read, n_readable); + + buffer = new_buffer; + + /* There may be new events in the buffer that were added after + * the FIONREAD was performed, but we can't risk getting into + * a loop. We'll get them next time. + */ + } + } + + *length_out = n_read; + + return buffer; +} + +static gboolean +ik_source_dispatch (GSource *source, + GSourceFunc func, + gpointer user_data) +{ + InotifyKernelSource *iks = (InotifyKernelSource *) source; + gboolean (*user_callback) (ik_event_t *event) = (void *) func; + gboolean interesting = FALSE; + gint64 now; + + now = g_source_get_time (source); + + if (iks->is_bored || g_source_query_unix_fd (source, iks->fd_tag)) + { + gchar stack_buffer[4096]; + gsize buffer_len; + gchar *buffer; + gsize offset; + + /* We want to read all of the available events. + * + * We need to do it in a finite number of steps so that we don't + * get caught in a loop of read() with another process + * continuously adding events each time we drain them. + * + * In the normal case we will have only a few events in the queue, + * so start out by reading into a small stack-allocated buffer. + * Even though we're on a fresh stack frame, there is no need to + * pointlessly blow up with the size of the worker thread stack + * with a huge buffer here. + * + * If the result is large enough to cause us to suspect that + * another event may be pending then we allocate a buffer on the + * heap that can hold all of the events and read (once!) into that + * buffer. + */ + buffer = ik_source_read_all_the_events (iks, stack_buffer, sizeof stack_buffer, &buffer_len); + + offset = 0; + + while (offset < buffer_len) + { + struct inotify_event *kevent = (struct inotify_event *) (buffer + offset); + ik_event_t *event; + + event = ik_event_new (kevent, now); + + offset += sizeof (struct inotify_event) + event->len; + + if (event->mask & IN_MOVED_TO) + { + ik_event_t *pair; + + pair = g_hash_table_lookup (iks->unmatched_moves, GUINT_TO_POINTER (event->cookie)); + if (pair != NULL) + { + g_assert (!pair->pair); + + g_hash_table_remove (iks->unmatched_moves, GUINT_TO_POINTER (event->cookie)); + event->is_second_in_pair = TRUE; + event->pair = pair; + pair->pair = event; + continue; + } + + interesting = TRUE; + } + + else if (event->mask & IN_MOVED_FROM) + { + gboolean new; + + new = g_hash_table_insert (iks->unmatched_moves, GUINT_TO_POINTER (event->cookie), event); + if G_UNLIKELY (!new) + g_warning ("inotify: got IN_MOVED_FROM event with already-pending cookie %#x", event->cookie); + + interesting = TRUE; + } + + g_queue_push_tail (&iks->queue, event); + } + + if (buffer_len == 0) + { + /* We can end up reading nothing if we arrived here due to a + * boredom timer but the stream of events stopped meanwhile. + * + * In that case, we need to switch back to polling the file + * descriptor in the usual way. + */ + g_assert (iks->is_bored); + interesting = TRUE; + } + + if (buffer != stack_buffer) + g_free (buffer); + } + + while (ik_source_can_dispatch_now (iks, now)) + { + ik_event_t *event; + + /* callback will free the event */ + event = g_queue_pop_head (&iks->queue); + + if (event->mask & IN_MOVED_FROM && !event->pair) + g_hash_table_remove (iks->unmatched_moves, GUINT_TO_POINTER (event->cookie)); + + G_LOCK (inotify_lock); + + interesting |= (* user_callback) (event); + + G_UNLOCK (inotify_lock); + } + + /* The queue gets blocked iff we have unmatched moves */ + g_assert ((iks->queue.length > 0) == (g_hash_table_size (iks->unmatched_moves) > 0)); + + /* Here's where we decide what will wake us up next. + * + * If the last event was interesting then we will wake up on the fd or + * when the timeout is reached on an unpaired move (if any). + * + * If the last event was uninteresting then we will wake up after the + * shorter of the boredom sleep or any timeout for an unpaired move. + */ + if (interesting) + { + if (iks->is_bored) + { + g_source_modify_unix_fd (source, iks->fd_tag, G_IO_IN); + iks->is_bored = FALSE; + } + + g_source_set_ready_time (source, ik_source_get_dispatch_time (iks)); + } + else + { + guint64 dispatch_time = ik_source_get_dispatch_time (iks); + guint64 boredom_time = now + BOREDOM_SLEEP_TIME; + + if (!iks->is_bored) + { + g_source_modify_unix_fd (source, iks->fd_tag, 0); + iks->is_bored = TRUE; + } + + g_source_set_ready_time (source, MIN (dispatch_time, boredom_time)); + } + + return TRUE; +} + +static InotifyKernelSource * +ik_source_new (gboolean (* callback) (ik_event_t *event)) +{ + static GSourceFuncs source_funcs = { + NULL, NULL, + ik_source_dispatch, + NULL, NULL, NULL + }; + InotifyKernelSource *iks; + GSource *source; + + source = g_source_new (&source_funcs, sizeof (InotifyKernelSource)); + iks = (InotifyKernelSource *) source; + + g_source_set_static_name (source, "inotify kernel source"); + + iks->unmatched_moves = g_hash_table_new (NULL, NULL); + iks->fd = inotify_init1 (IN_CLOEXEC); + + if (iks->fd < 0) + iks->fd = inotify_init (); + + if (iks->fd >= 0) + { + GError *error = NULL; + + g_unix_set_fd_nonblocking (iks->fd, TRUE, &error); + g_assert_no_error (error); + + iks->fd_tag = g_source_add_unix_fd (source, iks->fd, G_IO_IN); + } + + g_source_set_callback (source, (GSourceFunc) callback, NULL, NULL); + + g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ()); + + return iks; +} + +gboolean +_ik_startup (gboolean (*cb)(ik_event_t *event)) +{ + if (g_once_init_enter (&inotify_source)) + g_once_init_leave (&inotify_source, ik_source_new (cb)); + + return inotify_source->fd >= 0; +} + +gint32 +_ik_watch (const char *path, + guint32 mask, + int *err) +{ + gint32 wd = -1; + + g_assert (path != NULL); + g_assert (inotify_source && inotify_source->fd >= 0); + + wd = inotify_add_watch (inotify_source->fd, path, mask); + + if (wd < 0) + { + int e = errno; + /* FIXME: debug msg failed to add watch */ + if (err) + *err = e; + return wd; + } + + g_assert (wd >= 0); + return wd; +} + +int +_ik_ignore (const char *path, + gint32 wd) +{ + g_assert (wd >= 0); + g_assert (inotify_source && inotify_source->fd >= 0); + + if (inotify_rm_watch (inotify_source->fd, wd) < 0) + { + /* int e = errno; */ + /* failed to rm watch */ + return -1; + } + + return 0; +} diff --git a/gio/inotify/inotify-kernel.h b/gio/inotify/inotify-kernel.h new file mode 100644 index 0000000..c11cd7c --- /dev/null +++ b/gio/inotify/inotify-kernel.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2005 John McCutchan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Authors:. + John McCutchan +*/ + +#ifndef __INOTIFY_KERNEL_H +#define __INOTIFY_KERNEL_H + +typedef struct ik_event_s { + gint32 wd; + guint32 mask; + guint32 original_mask; + guint32 cookie; + guint32 len; + char * name; + /* TRUE if this event is the last element of a pair + * (e.g., MOVE_TO in a pair of MOVE_FROM, MOVE_TO events) */ + gboolean is_second_in_pair; + /* if event1 and event2 are two paired events + * (e.g., MOVE_FROM and MOVE_TO events related to the same file move), + * then event1->pair == event2 and event2->pair == NULL. + * It will result also in event1->pair->is_second_in_pair == TRUE */ + struct ik_event_s *pair; + gint64 timestamp; /* monotonic time that this was created */ +} ik_event_t; + +gboolean _ik_startup (gboolean (*cb) (ik_event_t *event)); + +ik_event_t *_ik_event_new_dummy (const char *name, + gint32 wd, + guint32 mask); +void _ik_event_free (ik_event_t *event); + +gint32 _ik_watch (const char *path, + guint32 mask, + int *err); +int _ik_ignore (const char *path, + gint32 wd); + + +/* The miss count will probably be enflated */ +void _ik_move_stats (guint32 *matches, + guint32 *misses); +const char *_ik_mask_to_string (guint32 mask); + + +#endif diff --git a/gio/inotify/inotify-missing.c b/gio/inotify/inotify-missing.c new file mode 100644 index 0000000..b71b2d3 --- /dev/null +++ b/gio/inotify/inotify-missing.c @@ -0,0 +1,156 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */ + +/* inotify-missing.c - GVFS Monitor based on inotify. + + Copyright (C) 2005 John McCutchan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Authors: + John McCutchan +*/ + +#include "config.h" +#include +#include "inotify-missing.h" +#include "inotify-path.h" +#include "glib-private.h" + +#define SCAN_MISSING_TIME 4 /* 1/4 Hz */ + +static gboolean im_debug_enabled = FALSE; +#define IM_W if (im_debug_enabled) g_warning + +/* We put inotify_sub's that are missing on this list */ +static GList *missing_sub_list = NULL; +static gboolean im_scan_missing (gpointer user_data); +static gboolean scan_missing_running = FALSE; +static void (*missing_cb)(inotify_sub *sub) = NULL; + +G_LOCK_EXTERN (inotify_lock); + +/* inotify_lock must be held before calling */ +void +_im_startup (void (*callback)(inotify_sub *sub)) +{ + static gboolean initialized = FALSE; + + if (!initialized) + { + missing_cb = callback; + initialized = TRUE; + } +} + +/* inotify_lock must be held before calling */ +void +_im_add (inotify_sub *sub) +{ + if (g_list_find (missing_sub_list, sub)) + { + IM_W ("asked to add %s to missing list but it's already on the list!\n", sub->dirname); + return; + } + + IM_W ("adding %s to missing list\n", sub->dirname); + missing_sub_list = g_list_prepend (missing_sub_list, sub); + + /* If the timeout is turned off, we turn it back on */ + if (!scan_missing_running) + { + GSource *source; + + scan_missing_running = TRUE; + source = g_timeout_source_new_seconds (SCAN_MISSING_TIME); + g_source_set_callback (source, im_scan_missing, NULL, NULL); + g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ()); + g_source_unref (source); + } +} + +/* inotify_lock must be held before calling */ +void +_im_rm (inotify_sub *sub) +{ + GList *link; + + link = g_list_find (missing_sub_list, sub); + + if (!link) + { + IM_W ("asked to remove %s from missing list but it isn't on the list!\n", sub->dirname); + return; + } + + IM_W ("removing %s from missing list\n", sub->dirname); + + missing_sub_list = g_list_remove_link (missing_sub_list, link); + g_list_free_1 (link); +} + +/* Scans the list of missing subscriptions checking if they + * are available yet. + */ +static gboolean +im_scan_missing (gpointer user_data) +{ + GList *nolonger_missing = NULL; + GList *l; + + G_LOCK (inotify_lock); + + IM_W ("scanning missing list with %d items\n", g_list_length (missing_sub_list)); + for (l = missing_sub_list; l; l = l->next) + { + inotify_sub *sub = l->data; + gboolean not_m = FALSE; + + IM_W ("checking %p\n", sub); + g_assert (sub); + g_assert (sub->dirname); + not_m = _ip_start_watching (sub); + + if (not_m) + { + missing_cb (sub); + IM_W ("removed %s from missing list\n", sub->dirname); + /* We have to build a list of list nodes to remove from the + * missing_sub_list. We do the removal outside of this loop. + */ + nolonger_missing = g_list_prepend (nolonger_missing, l); + } + } + + for (l = nolonger_missing; l ; l = l->next) + { + GList *llink = l->data; + missing_sub_list = g_list_remove_link (missing_sub_list, llink); + g_list_free_1 (llink); + } + + g_list_free (nolonger_missing); + + /* If the missing list is now empty, we disable the timeout */ + if (missing_sub_list == NULL) + { + scan_missing_running = FALSE; + G_UNLOCK (inotify_lock); + return FALSE; + } + else + { + G_UNLOCK (inotify_lock); + return TRUE; + } +} diff --git a/gio/inotify/inotify-missing.h b/gio/inotify/inotify-missing.h new file mode 100644 index 0000000..f0ccdce --- /dev/null +++ b/gio/inotify/inotify-missing.h @@ -0,0 +1,33 @@ +/* inotify-helper.h - GNOME VFS Monitor using inotify + + Copyright (C) 2006 John McCutchan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Author: John McCutchan +*/ + + +#ifndef __INOTIFY_MISSING_H +#define __INOTIFY_MISSING_H + +#include "inotify-sub.h" + +void _im_startup (void (*missing_cb)(inotify_sub *sub)); +void _im_add (inotify_sub *sub); +void _im_rm (inotify_sub *sub); +void _im_diag_dump (GIOChannel *ioc); + + +#endif /* __INOTIFY_MISSING_H */ diff --git a/gio/inotify/inotify-path.c b/gio/inotify/inotify-path.c new file mode 100644 index 0000000..e1129cd --- /dev/null +++ b/gio/inotify/inotify-path.c @@ -0,0 +1,595 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */ + +/* inotify-path.c - GVFS Monitor based on inotify. + + Copyright (C) 2006 John McCutchan + Copyright (C) 2009 Codethink Limited + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Authors: + John McCutchan + Ryan Lortie +*/ + +#include "config.h" + +/* Don't put conflicting kernel types in the global namespace: */ +#define __KERNEL_STRICT_NAMES + +#include +#include +#include +#include "inotify-kernel.h" +#include "inotify-path.h" +#include "inotify-missing.h" + +#define IP_INOTIFY_DIR_MASK (IN_MODIFY|IN_ATTRIB|IN_MOVED_FROM|IN_MOVED_TO|IN_DELETE|IN_CREATE|IN_DELETE_SELF|IN_UNMOUNT|IN_MOVE_SELF|IN_CLOSE_WRITE) + +#define IP_INOTIFY_FILE_MASK (IN_MODIFY|IN_ATTRIB|IN_CLOSE_WRITE) + +/* Older libcs don't have this */ +#ifndef IN_ONLYDIR +#define IN_ONLYDIR 0 +#endif + +typedef struct ip_watched_file_s { + gchar *filename; + gchar *path; + gint32 wd; + + GList *subs; +} ip_watched_file_t; + +typedef struct ip_watched_dir_s { + char *path; + /* TODO: We need to maintain a tree of watched directories + * so that we can deliver move/delete events to sub folders. + * Or the application could do it... + */ + struct ip_watched_dir_s* parent; + GList* children; + + /* basename -> ip_watched_file_t + * Maps basename to a ip_watched_file_t if the file is currently + * being directly watched for changes (ie: 'hardlinks' mode). + */ + GHashTable *files_hash; + + /* Inotify state */ + gint32 wd; + + /* List of inotify subscriptions */ + GList *subs; +} ip_watched_dir_t; + +static gboolean ip_debug_enabled = FALSE; +#define IP_W if (ip_debug_enabled) g_warning + +/* path -> ip_watched_dir */ +static GHashTable * path_dir_hash = NULL; +/* inotify_sub * -> ip_watched_dir * + * + * Each subscription is attached to a watched directory or it is on + * the missing list + */ +static GHashTable * sub_dir_hash = NULL; +/* This hash holds GLists of ip_watched_dir_t *'s + * We need to hold a list because symbolic links can share + * the same wd + */ +static GHashTable * wd_dir_hash = NULL; +/* This hash holds GLists of ip_watched_file_t *'s + * We need to hold a list because links can share + * the same wd + */ +static GHashTable * wd_file_hash = NULL; + +static ip_watched_dir_t *ip_watched_dir_new (const char *path, + int wd); +static void ip_watched_dir_free (ip_watched_dir_t *dir); +static gboolean ip_event_callback (ik_event_t *event); + + +static gboolean (*event_callback)(ik_event_t *event, inotify_sub *sub, gboolean file_event); + +gboolean +_ip_startup (gboolean (*cb)(ik_event_t *event, inotify_sub *sub, gboolean file_event)) +{ + static gboolean initialized = FALSE; + static gboolean result = FALSE; + + if (initialized == TRUE) + return result; + + event_callback = cb; + result = _ik_startup (ip_event_callback); + + if (!result) + return FALSE; + + path_dir_hash = g_hash_table_new (g_str_hash, g_str_equal); + sub_dir_hash = g_hash_table_new (g_direct_hash, g_direct_equal); + wd_dir_hash = g_hash_table_new (g_direct_hash, g_direct_equal); + wd_file_hash = g_hash_table_new (g_direct_hash, g_direct_equal); + + initialized = TRUE; + return TRUE; +} + +static void +ip_map_path_dir (const char *path, + ip_watched_dir_t *dir) +{ + g_assert (path && dir); + g_hash_table_insert (path_dir_hash, dir->path, dir); +} + +static void +ip_map_sub_dir (inotify_sub *sub, + ip_watched_dir_t *dir) +{ + /* Associate subscription and directory */ + g_assert (dir && sub); + g_hash_table_insert (sub_dir_hash, sub, dir); + dir->subs = g_list_prepend (dir->subs, sub); +} + +static void +ip_map_wd_dir (gint32 wd, + ip_watched_dir_t *dir) +{ + GList *dir_list; + + g_assert (wd >= 0 && dir); + dir_list = g_hash_table_lookup (wd_dir_hash, GINT_TO_POINTER (wd)); + dir_list = g_list_prepend (dir_list, dir); + g_hash_table_replace (wd_dir_hash, GINT_TO_POINTER (dir->wd), dir_list); +} + +static void +ip_map_wd_file (gint32 wd, + ip_watched_file_t *file) +{ + GList *file_list; + + g_assert (wd >= 0 && file); + file_list = g_hash_table_lookup (wd_file_hash, GINT_TO_POINTER (wd)); + file_list = g_list_prepend (file_list, file); + g_hash_table_replace (wd_file_hash, GINT_TO_POINTER (wd), file_list); +} + +static void +ip_unmap_wd_file (gint32 wd, + ip_watched_file_t *file) +{ + GList *file_list = g_hash_table_lookup (wd_file_hash, GINT_TO_POINTER (wd)); + + if (!file_list) + return; + + g_assert (wd >= 0 && file); + file_list = g_list_remove (file_list, file); + if (file_list == NULL) + g_hash_table_remove (wd_file_hash, GINT_TO_POINTER (wd)); + else + g_hash_table_replace (wd_file_hash, GINT_TO_POINTER (wd), file_list); +} + + +static ip_watched_file_t * +ip_watched_file_new (const gchar *dirname, + const gchar *filename) +{ + ip_watched_file_t *file; + + file = g_new0 (ip_watched_file_t, 1); + file->path = g_strjoin ("/", dirname, filename, NULL); + file->filename = g_strdup (filename); + file->wd = -1; + + return file; +} + +static void +ip_watched_file_free (ip_watched_file_t *file) +{ + g_assert (file->subs == NULL); + g_free (file->filename); + g_free (file->path); + g_free (file); +} + +static void +ip_watched_file_add_sub (ip_watched_file_t *file, + inotify_sub *sub) +{ + file->subs = g_list_prepend (file->subs, sub); +} + +static void +ip_watched_file_start (ip_watched_file_t *file) +{ + if (file->wd < 0) + { + gint err; + + file->wd = _ik_watch (file->path, + IP_INOTIFY_FILE_MASK, + &err); + + if (file->wd >= 0) + ip_map_wd_file (file->wd, file); + } +} + +static void +ip_watched_file_stop (ip_watched_file_t *file) +{ + if (file->wd >= 0) + { + _ik_ignore (file->path, file->wd); + ip_unmap_wd_file (file->wd, file); + file->wd = -1; + } +} + +gboolean +_ip_start_watching (inotify_sub *sub) +{ + gint32 wd; + int err; + ip_watched_dir_t *dir; + + g_assert (sub); + g_assert (!sub->cancelled); + g_assert (sub->dirname); + + IP_W ("Starting to watch %s\n", sub->dirname); + dir = g_hash_table_lookup (path_dir_hash, sub->dirname); + + if (dir == NULL) + { + IP_W ("Trying to add inotify watch "); + wd = _ik_watch (sub->dirname, IP_INOTIFY_DIR_MASK|IN_ONLYDIR, &err); + if (wd < 0) + { + IP_W ("Failed\n"); + return FALSE; + } + else + { + /* Create new watched directory and associate it with the + * wd hash and path hash + */ + IP_W ("Success\n"); + dir = ip_watched_dir_new (sub->dirname, wd); + ip_map_wd_dir (wd, dir); + ip_map_path_dir (sub->dirname, dir); + } + } + else + IP_W ("Already watching\n"); + + if (sub->hardlinks) + { + ip_watched_file_t *file; + + file = g_hash_table_lookup (dir->files_hash, sub->filename); + + if (file == NULL) + { + file = ip_watched_file_new (sub->dirname, sub->filename); + g_hash_table_insert (dir->files_hash, file->filename, file); + } + + ip_watched_file_add_sub (file, sub); + ip_watched_file_start (file); + } + + ip_map_sub_dir (sub, dir); + + return TRUE; +} + +static void +ip_unmap_path_dir (const char *path, + ip_watched_dir_t *dir) +{ + g_assert (path && dir); + g_hash_table_remove (path_dir_hash, dir->path); +} + +static void +ip_unmap_wd_dir (gint32 wd, + ip_watched_dir_t *dir) +{ + GList *dir_list = g_hash_table_lookup (wd_dir_hash, GINT_TO_POINTER (wd)); + + if (!dir_list) + return; + + g_assert (wd >= 0 && dir); + dir_list = g_list_remove (dir_list, dir); + if (dir_list == NULL) + g_hash_table_remove (wd_dir_hash, GINT_TO_POINTER (dir->wd)); + else + g_hash_table_replace (wd_dir_hash, GINT_TO_POINTER (dir->wd), dir_list); +} + +static void +ip_unmap_wd (gint32 wd) +{ + GList *dir_list = g_hash_table_lookup (wd_dir_hash, GINT_TO_POINTER (wd)); + if (!dir_list) + return; + g_assert (wd >= 0); + g_hash_table_remove (wd_dir_hash, GINT_TO_POINTER (wd)); + g_list_free (dir_list); +} + +static void +ip_unmap_sub_dir (inotify_sub *sub, + ip_watched_dir_t *dir) +{ + g_assert (sub && dir); + g_hash_table_remove (sub_dir_hash, sub); + dir->subs = g_list_remove (dir->subs, sub); + + if (sub->hardlinks) + { + ip_watched_file_t *file; + + file = g_hash_table_lookup (dir->files_hash, sub->filename); + file->subs = g_list_remove (file->subs, sub); + + if (file->subs == NULL) + { + g_hash_table_remove (dir->files_hash, sub->filename); + ip_watched_file_stop (file); + ip_watched_file_free (file); + } + } + } + +static void +ip_unmap_all_subs (ip_watched_dir_t *dir) +{ + while (dir->subs != NULL) + ip_unmap_sub_dir (dir->subs->data, dir); +} + +gboolean +_ip_stop_watching (inotify_sub *sub) +{ + ip_watched_dir_t *dir = NULL; + + dir = g_hash_table_lookup (sub_dir_hash, sub); + if (!dir) + return TRUE; + + ip_unmap_sub_dir (sub, dir); + + /* No one is subscribing to this directory any more */ + if (dir->subs == NULL) + { + _ik_ignore (dir->path, dir->wd); + ip_unmap_wd_dir (dir->wd, dir); + ip_unmap_path_dir (dir->path, dir); + ip_watched_dir_free (dir); + } + + return TRUE; +} + + +static ip_watched_dir_t * +ip_watched_dir_new (const char *path, + gint32 wd) +{ + ip_watched_dir_t *dir = g_new0 (ip_watched_dir_t, 1); + + dir->path = g_strdup (path); + dir->files_hash = g_hash_table_new (g_str_hash, g_str_equal); + dir->wd = wd; + + return dir; +} + +static void +ip_watched_dir_free (ip_watched_dir_t *dir) +{ + g_assert_cmpint (g_hash_table_size (dir->files_hash), ==, 0); + g_assert (dir->subs == NULL); + g_free (dir->path); + g_hash_table_unref (dir->files_hash); + g_free (dir); +} + +static void +ip_wd_delete (gpointer data, + gpointer user_data) +{ + ip_watched_dir_t *dir = data; + GList *l = NULL; + + for (l = dir->subs; l; l = l->next) + { + inotify_sub *sub = l->data; + /* Add subscription to missing list */ + _im_add (sub); + } + ip_unmap_all_subs (dir); + /* Unassociate the path and the directory */ + ip_unmap_path_dir (dir->path, dir); + ip_watched_dir_free (dir); +} + +static gboolean +ip_event_dispatch (GList *dir_list, + GList *file_list, + ik_event_t *event) +{ + gboolean interesting = FALSE; + + GList *l; + + if (!event) + return FALSE; + + for (l = dir_list; l; l = l->next) + { + GList *subl; + ip_watched_dir_t *dir = l->data; + + for (subl = dir->subs; subl; subl = subl->next) + { + inotify_sub *sub = subl->data; + + /* If the subscription and the event + * contain a filename and they don't + * match, we don't deliver this event. + */ + if (sub->filename && + event->name && + strcmp (sub->filename, event->name) && + (!event->pair || !event->pair->name || strcmp (sub->filename, event->pair->name))) + continue; + + /* If the subscription has a filename + * but this event doesn't, we don't + * deliver this event. + */ + if (sub->filename && !event->name) + continue; + + /* If we're also watching the file directly + * don't report events that will also be + * reported on the file itself. + */ + if (sub->hardlinks) + { + event->mask &= ~IP_INOTIFY_FILE_MASK; + if (!event->mask) + continue; + } + + /* FIXME: We might need to synthesize + * DELETE/UNMOUNT events when + * the filename doesn't match + */ + + interesting |= event_callback (event, sub, FALSE); + + if (sub->hardlinks) + { + ip_watched_file_t *file; + + file = g_hash_table_lookup (dir->files_hash, sub->filename); + + if (file != NULL) + { + if (event->mask & (IN_MOVED_FROM | IN_DELETE)) + ip_watched_file_stop (file); + + if (event->mask & (IN_MOVED_TO | IN_CREATE)) + ip_watched_file_start (file); + } + } + } + } + + for (l = file_list; l; l = l->next) + { + ip_watched_file_t *file = l->data; + GList *subl; + + for (subl = file->subs; subl; subl = subl->next) + { + inotify_sub *sub = subl->data; + + interesting |= event_callback (event, sub, TRUE); + } + } + + return interesting; +} + +static gboolean +ip_event_callback (ik_event_t *event) +{ + gboolean interesting = FALSE; + GList* dir_list = NULL; + GList *file_list = NULL; + + /* We can ignore the IGNORED events. Likewise, if the event queue overflowed, + * there is not much we can do to recover. */ + if (event->mask & (IN_IGNORED | IN_Q_OVERFLOW)) + { + _ik_event_free (event); + return TRUE; + } + + dir_list = g_hash_table_lookup (wd_dir_hash, GINT_TO_POINTER (event->wd)); + file_list = g_hash_table_lookup (wd_file_hash, GINT_TO_POINTER (event->wd)); + + if (event->mask & IP_INOTIFY_DIR_MASK) + interesting |= ip_event_dispatch (dir_list, file_list, event); + + /* Only deliver paired events if the wds are separate */ + if (event->pair && event->pair->wd != event->wd) + { + dir_list = g_hash_table_lookup (wd_dir_hash, GINT_TO_POINTER (event->pair->wd)); + file_list = g_hash_table_lookup (wd_file_hash, GINT_TO_POINTER (event->pair->wd)); + + if (event->pair->mask & IP_INOTIFY_DIR_MASK) + interesting |= ip_event_dispatch (dir_list, file_list, event->pair); + } + + /* We have to manage the missing list + * when we get an event that means the + * file has been deleted/moved/unmounted. + */ + if (event->mask & IN_DELETE_SELF || + event->mask & IN_MOVE_SELF || + event->mask & IN_UNMOUNT) + { + /* Add all subscriptions to missing list */ + g_list_foreach (dir_list, ip_wd_delete, NULL); + /* Unmap all directories attached to this wd */ + ip_unmap_wd (event->wd); + } + + _ik_event_free (event); + + return interesting; +} + +const char * +_ip_get_path_for_wd (gint32 wd) +{ + GList *dir_list; + ip_watched_dir_t *dir; + + g_assert (wd >= 0); + dir_list = g_hash_table_lookup (wd_dir_hash, GINT_TO_POINTER (wd)); + if (dir_list) + { + dir = dir_list->data; + if (dir) + return dir->path; + } + + return NULL; +} diff --git a/gio/inotify/inotify-path.h b/gio/inotify/inotify-path.h new file mode 100644 index 0000000..26f6dfd --- /dev/null +++ b/gio/inotify/inotify-path.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2005 John McCutchan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Authors:. + John McCutchan +*/ + +#ifndef __INOTIFY_PATH_H +#define __INOTIFY_PATH_H + +#include "inotify-kernel.h" +#include "inotify-sub.h" + +gboolean _ip_startup (gboolean (*event_cb)(ik_event_t *event, inotify_sub *sub, gboolean file_event)); +gboolean _ip_start_watching (inotify_sub *sub); +gboolean _ip_stop_watching (inotify_sub *sub); +const char * _ip_get_path_for_wd (gint32 wd); +#endif diff --git a/gio/inotify/inotify-sub.c b/gio/inotify/inotify-sub.c new file mode 100644 index 0000000..b161557 --- /dev/null +++ b/gio/inotify/inotify-sub.c @@ -0,0 +1,81 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */ + +/* inotify-sub.c - GVFS Monitor based on inotify. + + Copyright (C) 2006 John McCutchan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Authors: + John McCutchan +*/ + +#include "config.h" +#include +#include + +#include "inotify-sub.h" + +static gboolean is_debug_enabled = FALSE; +#define IS_W if (is_debug_enabled) g_warning + +static gchar* +dup_dirname (const gchar *dirname) +{ + gchar *d_dirname = g_strdup (dirname); + size_t len = strlen (d_dirname); + + if (d_dirname[len - 1] == '/') + d_dirname[len - 1] = '\0'; + + return d_dirname; +} + +inotify_sub* +_ih_sub_new (const gchar *dirname, + const gchar *basename, + const gchar *filename, + gpointer user_data) +{ + inotify_sub *sub = NULL; + + sub = g_new0 (inotify_sub, 1); + + if (filename) + { + sub->dirname = g_path_get_dirname (filename); + sub->filename = g_path_get_basename (filename); + sub->hardlinks = TRUE; + } + else + { + sub->dirname = dup_dirname (dirname); + sub->filename = g_strdup (basename); + sub->hardlinks = FALSE; + } + + sub->user_data = user_data; + + IS_W ("new subscription for %s being setup\n", sub->dirname); + + return sub; +} + +void +_ih_sub_free (inotify_sub *sub) +{ + g_free (sub->dirname); + g_free (sub->filename); + g_free (sub); +} diff --git a/gio/inotify/inotify-sub.h b/gio/inotify/inotify-sub.h new file mode 100644 index 0000000..fcde4f4 --- /dev/null +++ b/gio/inotify/inotify-sub.h @@ -0,0 +1,41 @@ +/* inotify-sub.h - GVFS Directory Monitor using inotify + + Copyright (C) 2006 John McCutchan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see . + + Author: John McCutchan +*/ + + +#ifndef __INOTIFY_SUB_H +#define __INOTIFY_SUB_H + +typedef struct +{ + gchar* dirname; + gchar* filename; + gboolean cancelled; + gpointer user_data; + gboolean pair_moves; + gboolean hardlinks; +} inotify_sub; + +inotify_sub *_ih_sub_new (const gchar *dirname, + const gchar *basename, + const gchar *filename, + gpointer user_data); +void _ih_sub_free (inotify_sub *sub); + +#endif /* __INOTIFY_SUB_H */ diff --git a/gio/inotify/meson.build b/gio/inotify/meson.build new file mode 100644 index 0000000..9b0c7ab --- /dev/null +++ b/gio/inotify/meson.build @@ -0,0 +1,15 @@ +inotify_sources = [ + 'inotify-kernel.c', + 'inotify-sub.c', + 'inotify-path.c', + 'inotify-missing.c', + 'inotify-helper.c', + 'ginotifyfilemonitor.c', +] + +inotify_lib = static_library('inotify', + sources : inotify_sources, + include_directories : [configinc, glibinc, gmoduleinc], + dependencies : [gioenumtypes_dep, libglib_dep, libgobject_dep], + pic : true, + c_args : gio_c_args) diff --git a/gio/kqueue/dep-list.c b/gio/kqueue/dep-list.c new file mode 100644 index 0000000..0a46aa8 --- /dev/null +++ b/gio/kqueue/dep-list.c @@ -0,0 +1,536 @@ +/******************************************************************************* + Copyright (c) 2011, 2012 Dmitry Matveev + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*******************************************************************************/ + +#include + +#include /* calloc */ +#include /* printf */ +#include /* opendir, readdir, closedir */ +#include /* strcmp */ +#include + +#include "dep-list.h" + +static gboolean kdl_debug_enabled = FALSE; +#define perror_msg if (kdl_debug_enabled) g_warning + + +/** + * Print a list to stdout. + * + * @param[in] dl A pointer to a list. + **/ +void +dl_print (const dep_list *dl) +{ + while (dl != NULL) { + printf ("%lld:%s ", (long long int) dl->inode, dl->path); + dl = dl->next; + } + printf ("\n"); +} + +/** + * Create a new list item. + * + * Create a new list item and initialize its fields. + * + * @param[in] path A name of a file (the string is not copied!). + * @param[in] inode A file's inode number. + * @return A pointer to a new item or NULL in the case of error. + **/ +dep_list* dl_create (char *path, ino_t inode) +{ + dep_list *dl = calloc (1, sizeof (dep_list)); + if (dl == NULL) { + perror_msg ("Failed to create a new dep-list item"); + return NULL; + } + + dl->path = path; + dl->inode = inode; + return dl; +} + +/** + * Create a shallow copy of a list. + * + * A shallow copy is a copy of a structure, but not the copy of the + * contents. All data pointers ('path' in our case) of a list and its + * shallow copy will point to the same memory. + * + * @param[in] dl A pointer to list to make a copy. May be NULL. + * @return A shallow copy of the list. + **/ +dep_list* +dl_shallow_copy (const dep_list *dl) +{ + dep_list *head; + dep_list *cp; + const dep_list *it; + + if (dl == NULL) { + return NULL; + } + + head = calloc (1, sizeof (dep_list)); + if (head == NULL) { + perror_msg ("Failed to allocate head during shallow copy"); + return NULL; + } + + cp = head; + it = dl; + + while (it != NULL) { + cp->path = it->path; + cp->inode = it->inode; + if (it->next) { + cp->next = calloc (1, sizeof (dep_list)); + if (cp->next == NULL) { + perror_msg ("Failed to allocate a new element during shallow copy"); + dl_shallow_free (head); + return NULL; + } + cp = cp->next; + } + it = it->next; + } + + return head; +} + +/** + * Free the memory allocated for shallow copy. + * + * This function will free the memory used by a list structure, but + * the list data will remain in the heap. + * + * @param[in] dl A pointer to a list. May be NULL. + **/ +void +dl_shallow_free (dep_list *dl) +{ + while (dl != NULL) { + dep_list *ptr = dl; + dl = dl->next; + free (ptr); + } +} + +/** + * Free the memory allocated for a list. + * + * This function will free all the memory used by a list: both + * list structure and the list data. + * + * @param[in] dl A pointer to a list. May be NULL. + **/ +void +dl_free (dep_list *dl) +{ + while (dl != NULL) { + dep_list *ptr = dl; + dl = dl->next; + + free (ptr->path); + free (ptr); + } +} + +/** + * Create a directory listing and return it as a list. + * + * @param[in] path A path to a directory. + * @return A pointer to a list. May return NULL, check errno in this case. + **/ +dep_list* +dl_listing (const char *path) +{ + dep_list *head = NULL; + dep_list *prev = NULL; + DIR *dir; + + assert (path != NULL); + + dir = opendir (path); + if (dir != NULL) { + struct dirent *ent; + + while ((ent = readdir (dir)) != NULL) { + dep_list *iter; + + if (!strcmp (ent->d_name, ".") || !strcmp (ent->d_name, "..")) { + continue; + } + + if (head == NULL) { + head = calloc (1, sizeof (dep_list)); + if (head == NULL) { + perror_msg ("Failed to allocate head during listing"); + goto error; + } + } + + iter = (prev == NULL) ? head : calloc (1, sizeof (dep_list)); + if (iter == NULL) { + perror_msg ("Failed to allocate a new element during listing"); + goto error; + } + + iter->path = strdup (ent->d_name); + if (iter->path == NULL) { + perror_msg ("Failed to copy a string during listing"); + goto error; + } + + iter->inode = ent->d_ino; + iter->next = NULL; + if (prev) { + prev->next = iter; + } + prev = iter; + } + + closedir (dir); + } + return head; + +error: + if (dir != NULL) { + closedir (dir); + } + dl_free (head); + return NULL; +} + +/** + * Perform a diff on lists. + * + * This function performs something like a set intersection. The same items + * will be removed from the both lists. Items are comapred by a filename. + * + * @param[in,out] before A pointer to a pointer to a list. Will contain items + * which were not found in the 'after' list. + * @param[in,out] after A pointer to a pointer to a list. Will contain items + * which were not found in the 'before' list. + **/ +void +dl_diff (dep_list **before, dep_list **after) +{ + dep_list *before_iter; + dep_list *before_prev; + + assert (before != NULL); + assert (after != NULL); + + if (*before == NULL || *after == NULL) { + return; + } + + before_iter = *before; + before_prev = NULL; + + while (before_iter != NULL) { + dep_list *after_iter = *after; + dep_list *after_prev = NULL; + dep_list *oldptr; + + int matched = 0; + while (after_iter != NULL) { + if (strcmp (before_iter->path, after_iter->path) == 0) { + matched = 1; + /* removing the entry from the both lists */ + if (before_prev) { + before_prev->next = before_iter->next; + } else { + *before = before_iter->next; + } + + if (after_prev) { + after_prev->next = after_iter->next; + } else { + *after = after_iter->next; + } + free (after_iter); + break; + } + after_prev = after_iter; + after_iter = after_iter->next; + } + + oldptr = before_iter; + before_iter = before_iter->next; + if (matched == 0) { + before_prev = oldptr; + } else { + free (oldptr); + } + } +} + + +/** + * Traverses two lists. Compares items with a supplied expression + * and performs the passed code on a match. Removes the matched entries + * from the both lists. + **/ +#define EXCLUDE_SIMILAR(removed_list, added_list, match_expr, matched_code) \ +G_STMT_START { \ + dep_list *removed_list##_iter; \ + dep_list *removed_list##_prev; \ + int productive = 0; \ + \ + assert (removed_list != NULL); \ + assert (added_list != NULL); \ + \ + removed_list##_iter = *removed_list; \ + removed_list##_prev = NULL; \ + \ + while (removed_list##_iter != NULL) { \ + dep_list *added_list##_iter = *added_list; \ + dep_list *added_list##_prev = NULL; \ + dep_list *oldptr; \ + \ + int matched = 0; \ + while (added_list##_iter != NULL) { \ + if (match_expr) { \ + matched = 1; \ + ++productive; \ + matched_code; \ + \ + if (removed_list##_prev) { \ + removed_list##_prev->next = removed_list##_iter->next; \ + } else { \ + *removed_list = removed_list##_iter->next; \ + } \ + if (added_list##_prev) { \ + added_list##_prev->next = added_list##_iter->next; \ + } else { \ + *added_list = added_list##_iter->next; \ + } \ + free (added_list##_iter); \ + break; \ + } \ + added_list##_iter = added_list##_iter->next; \ + } \ + oldptr = removed_list##_iter; \ + removed_list##_iter = removed_list##_iter->next; \ + if (matched == 0) { \ + removed_list##_prev = oldptr; \ + } else { \ + free (oldptr); \ + } \ + } \ + return (productive > 0); \ +} G_STMT_END + + +#define cb_invoke(cbs, name, udata, ...) \ + do { \ + if (cbs->name) { \ + (cbs->name) (udata, ## __VA_ARGS__); \ + } \ + } while (0) + +/** + * Detect and notify about moves in the watched directory. + * + * A move is what happens when you rename a file in a directory, and + * a new name is unique, i.e. you didn't overwrite any existing files + * with this one. + * + * @param[in,out] removed A list of the removed files in the directory. + * @param[in,out] added A list of the added files of the directory. + * @param[in] cbs A pointer to #traverse_cbs, a user-defined set of + * traverse callbacks. + * @param[in] udata A pointer to the user-defined data. + * @return 0 if no files were renamed, >0 otherwise. +**/ +static int +dl_detect_moves (dep_list **removed, + dep_list **added, + const traverse_cbs *cbs, + void *udata) +{ + assert (cbs != NULL); + + EXCLUDE_SIMILAR + (removed, added, + (removed_iter->inode == added_iter->inode), + { + cb_invoke (cbs, moved, udata, + removed_iter->path, removed_iter->inode, + added_iter->path, added_iter->inode); + }); +} + +/** + * Detect and notify about replacements in the watched directory. + * + * Consider you are watching a directory foo with the following files + * insinde: + * + * foo/bar + * foo/baz + * + * A replacement in a watched directory is what happens when you invoke + * + * mv /foo/bar /foo/bar + * + * i.e. when you replace a file in a watched directory with another file + * from the same directory. + * + * @param[in,out] removed A list of the removed files in the directory. + * @param[in,out] current A list with the current contents of the directory. + * @param[in] cbs A pointer to #traverse_cbs, a user-defined set of + * traverse callbacks. + * @param[in] udata A pointer to the user-defined data. + * @return 0 if no files were renamed, >0 otherwise. + **/ +static int +dl_detect_replacements (dep_list **removed, + dep_list **current, + const traverse_cbs *cbs, + void *udata) +{ + assert (cbs != NULL); + + EXCLUDE_SIMILAR + (removed, current, + (removed_iter->inode == current_iter->inode), + { + cb_invoke (cbs, replaced, udata, + removed_iter->path, removed_iter->inode, + current_iter->path, current_iter->inode); + }); +} + +/** + * Detect and notify about overwrites in the watched directory. + * + * Consider you are watching a directory foo with a file inside: + * + * foo/bar + * + * And you also have a directory tmp with a file 1: + * + * tmp/1 + * + * You do not watching directory tmp. + * + * An overwrite in a watched directory is what happens when you invoke + * + * mv /tmp/1 /foo/bar + * + * i.e. when you overwrite a file in a watched directory with another file + * from the another directory. + * + * @param[in,out] previous A list with the previous contents of the directory. + * @param[in,out] current A list with the current contents of the directory. + * @param[in] cbs A pointer to #traverse_cbs, a user-defined set of + * traverse callbacks. + * @param[in] udata A pointer to the user-defined data. + * @return 0 if no files were renamed, >0 otherwise. + **/ +static int +dl_detect_overwrites (dep_list **previous, + dep_list **current, + const traverse_cbs *cbs, + void *udata) +{ + assert (cbs != NULL); + + EXCLUDE_SIMILAR + (previous, current, + (strcmp (previous_iter->path, current_iter->path) == 0 + && previous_iter->inode != current_iter->inode), + { + cb_invoke (cbs, overwritten, udata, current_iter->path, current_iter->inode); + }); +} + + +/** + * Traverse a list and invoke a callback for each item. + * + * @param[in] list A #dep_list. + * @param[in] cb A #single_entry_cb callback function. + * @param[in] udata A pointer to the user-defined data. + **/ +static void +dl_emit_single_cb_on (dep_list *list, + single_entry_cb cb, + void *udata) +{ + while (cb && list != NULL) { + (cb) (udata, list->path, list->inode); + list = list->next; + } +} + + +/** + * Recognize all the changes in the directory, invoke the appropriate callbacks. + * + * This is the core function of directory diffing submodule. + * + * @param[in] before The previous contents of the directory. + * @param[in] after The current contents of the directory. + * @param[in] cbs A pointer to user callbacks (#traverse_callbacks). + * @param[in] udata A pointer to user data. + **/ +void +dl_calculate (dep_list *before, + dep_list *after, + const traverse_cbs *cbs, + void *udata) +{ + int need_update = 0; + dep_list *was = dl_shallow_copy (before); + dep_list *pre = dl_shallow_copy (before); + dep_list *now = dl_shallow_copy (after); + dep_list *lst = dl_shallow_copy (after); + + assert (cbs != NULL); + + dl_diff (&was, &now); + + need_update += dl_detect_moves (&was, &now, cbs, udata); + need_update += dl_detect_replacements (&was, &lst, cbs, udata); + dl_detect_overwrites (&pre, &lst, cbs, udata); + + if (need_update) { + cb_invoke (cbs, names_updated, udata); + } + + dl_emit_single_cb_on (was, cbs->removed, udata); + dl_emit_single_cb_on (now, cbs->added, udata); + + cb_invoke (cbs, many_added, udata, now); + cb_invoke (cbs, many_removed, udata, was); + + dl_shallow_free (lst); + dl_shallow_free (now); + dl_shallow_free (pre); + dl_shallow_free (was); +} diff --git a/gio/kqueue/dep-list.h b/gio/kqueue/dep-list.h new file mode 100644 index 0000000..b12802d --- /dev/null +++ b/gio/kqueue/dep-list.h @@ -0,0 +1,69 @@ +/******************************************************************************* + Copyright (c) 2011, 2012 Dmitry Matveev + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*******************************************************************************/ + +#ifndef __DEP_LIST_H__ +#define __DEP_LIST_H__ + +#include /* ino_t */ + +typedef struct dep_list { + struct dep_list *next; + + char *path; + ino_t inode; +} dep_list; + +typedef void (* no_entry_cb) (void *udata); +typedef void (* single_entry_cb) (void *udata, const char *path, ino_t inode); +typedef void (* dual_entry_cb) (void *udata, + const char *from_path, ino_t from_inode, + const char *to_path, ino_t to_inode); +typedef void (* list_cb) (void *udata, const dep_list *list); + + +typedef struct traverse_cbs { + single_entry_cb added; + single_entry_cb removed; + dual_entry_cb replaced; + single_entry_cb overwritten; + dual_entry_cb moved; + list_cb many_added; + list_cb many_removed; + no_entry_cb names_updated; +} traverse_cbs; + +dep_list* dl_create (char *path, ino_t inode); +void dl_print (const dep_list *dl); +dep_list* dl_shallow_copy (const dep_list *dl); +void dl_shallow_free (dep_list *dl); +void dl_free (dep_list *dl); +dep_list* dl_listing (const char *path); +void dl_diff (dep_list **before, dep_list **after); + +void +dl_calculate (dep_list *before, + dep_list *after, + const traverse_cbs *cbs, + void *udata); + + +#endif /* __DEP_LIST_H__ */ diff --git a/gio/kqueue/gkqueuefilemonitor.c b/gio/kqueue/gkqueuefilemonitor.c new file mode 100644 index 0000000..f69f98e --- /dev/null +++ b/gio/kqueue/gkqueuefilemonitor.c @@ -0,0 +1,617 @@ +/******************************************************************************* + Copyright (c) 2011, 2012 Dmitry Matveev + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*******************************************************************************/ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "glib-private.h" + +#include "kqueue-helper.h" +#include "dep-list.h" + +G_LOCK_DEFINE_STATIC (kq_lock); +static GSource *kq_source; +static int kq_queue = -1; + +#define G_TYPE_KQUEUE_FILE_MONITOR (g_kqueue_file_monitor_get_type ()) +#define G_KQUEUE_FILE_MONITOR(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ + G_TYPE_KQUEUE_FILE_MONITOR, GKqueueFileMonitor)) + +/* C11 allows type redefinition, but GLib is configured to use C89, which causes + * clang to show warnings when we use a C11 feature. Since the C89 requirement + * is mostly used to support MSVC, we simply ignore the warning here because + * this file is never going to be useful on Windows. */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wtypedef-redefinition" +#endif + +typedef GLocalFileMonitorClass GKqueueFileMonitorClass; + +/* When the file we are monitoring is a directory, sub_dir is subscribed to the + * directory itself and sub_file is NULL. + * + * When the file we are monitoring is a regular file, sub_dir is subscribed to + * the directory containing the file and sub_file is subscribed to the file + * being monitored. We have to monitor both because it is possible that the + * file chosen for monitoring doesn't exist when the file monitor is started. + * We monitor on its parent in order to get notification when it is created. + * + * To distinguish between a directory monitor and a regular file monitor, check + * whether sub_file is NULL. */ +struct _GKqueueFileMonitor +{ + GLocalFileMonitor parent_instance; + + kqueue_sub *sub_dir; + kqueue_sub *sub_file; +#ifndef O_EVTONLY + GFileMonitor *fallback; + GFile *fbfile; +#endif +}; + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +GType g_kqueue_file_monitor_get_type (void); +G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL_FILE_MONITOR, + g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, + "kqueue", + 20)) + +#ifndef O_EVTONLY +#define O_KQFLAG O_RDONLY +#else +#define O_KQFLAG O_EVTONLY +#endif + +static inline unsigned int +note_all (void) +{ + unsigned int notes = NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE; +#ifdef NOTE_TRUNCATE + notes |= NOTE_TRUNCATE; +#endif +#ifdef NOTE_CLOSE_WRITE + notes |= NOTE_CLOSE_WRITE; +#endif + return notes; +} + +static gboolean g_kqueue_file_monitor_cancel (GFileMonitor* monitor); +static gboolean g_kqueue_file_monitor_is_supported (void); + +static kqueue_sub *_kqsub_new (gchar *, gchar *, GKqueueFileMonitor *, GFileMonitorSource *); +static void _kqsub_free (kqueue_sub *); +static void _kqsub_cancel (kqueue_sub *); + + +#ifndef O_EVTONLY +static void +_fallback_callback (GFileMonitor *unused, + GFile *first, + GFile *second, + GFileMonitorEvent event, + gpointer udata) +{ + GKqueueFileMonitor *kq_mon = G_KQUEUE_FILE_MONITOR (udata); + + g_file_monitor_emit_event (G_FILE_MONITOR (kq_mon), first, second, event); +} + +/* + * _ke_is_excluded: + * @full_path - a path to file to check. + * + * Returns: TRUE if the file should be excluded from the kqueue-powered + * monitoring, FALSE otherwise. + **/ +static gboolean +_ke_is_excluded (const char *full_path) +{ + GFile *f = NULL; + GMount *mount = NULL; + + f = g_file_new_for_path (full_path); + + if (f != NULL) { + mount = g_file_find_enclosing_mount (f, NULL, NULL); + g_object_unref (f); + } + + if (mount != NULL && (g_str_has_prefix (full_path, "/media/") || g_str_has_prefix (full_path, "/run/media/"))) + { + g_warning ("Excluding %s from kernel notification, falling back to poll", full_path); + if (mount) + g_object_unref (mount); + return TRUE; + } + + return FALSE; +} +#endif /* !O_EVTONLY */ + +static void +g_kqueue_file_monitor_finalize (GObject *object) +{ + GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (object); + + if (kqueue_monitor->sub_dir) + { + _kqsub_cancel (kqueue_monitor->sub_dir); + _kqsub_free (kqueue_monitor->sub_dir); + kqueue_monitor->sub_dir = NULL; + } + + if (kqueue_monitor->sub_file) + { + _kqsub_cancel (kqueue_monitor->sub_file); + _kqsub_free (kqueue_monitor->sub_file); + kqueue_monitor->sub_file = NULL; + } + +#ifndef O_EVTONLY + if (kqueue_monitor->fallback) + g_object_unref (kqueue_monitor->fallback); + + if (kqueue_monitor->fbfile) + g_object_unref (kqueue_monitor->fbfile); +#endif + + if (G_OBJECT_CLASS (g_kqueue_file_monitor_parent_class)->finalize) + (*G_OBJECT_CLASS (g_kqueue_file_monitor_parent_class)->finalize) (object); +} + +static void +g_kqueue_file_monitor_start (GLocalFileMonitor *local_monitor, + const gchar *dirname, + const gchar *basename, + const gchar *filename, + GFileMonitorSource *source) +{ + GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (local_monitor); + kqueue_sub *sub_dir = NULL, *sub_file = NULL; + gchar *path_dir, *path_file, *file_basename; + + /* There are three possible cases here: + * + * 1. Directory: dirname != NULL, basename == NULL, filename == NULL + * 2. Regular file: dirname != NULL, basename != NULL, filename == NULL + * 3. Hard links: dirname == NULL, basename == NULL, filename != NULL + * + * Note that we don't distinguish between case 2 and 3. Kqueue monitors + * files based on file descriptors, so we always receive events come from + * hard links. + */ + if (filename != NULL) + { + path_dir = g_path_get_dirname (filename); + path_file = g_strdup (filename); + file_basename = g_path_get_basename (filename); + } + else + { + path_dir = g_strdup (dirname); + if (basename != NULL) + { + path_file = g_build_filename (dirname, basename, NULL); + file_basename = g_strdup (basename); + } + else + { + path_file = NULL; + file_basename = NULL; + } + } + +#ifndef O_EVTONLY + if (_ke_is_excluded (path_dir)) + { + GFile *file; + if (path_file != NULL) + file = g_file_new_for_path (path_file); + else + file = g_file_new_for_path (path_dir); + g_free (path_dir); + g_free (path_file); + g_free (file_basename); + kqueue_monitor->fbfile = file; + kqueue_monitor->fallback = _g_poll_file_monitor_new (file); + g_signal_connect (kqueue_monitor->fallback, "changed", + G_CALLBACK (_fallback_callback), kqueue_monitor); + return; + } +#endif + + /* For a directory monitor, create a subscription object anyway. + * It will be used for directory diff calculation routines. + * Wait, directory diff in a GKqueueFileMonitor? + * Yes, it is. When a file monitor is started on a non-existent + * file, GIO uses a GKqueueFileMonitor object for that. If a directory + * will be created under that path, GKqueueFileMonitor will have to + * handle the directory notifications. */ + sub_dir = _kqsub_new (g_steal_pointer (&path_dir), NULL, + kqueue_monitor, source); + if (!_kqsub_start_watching (sub_dir)) + _km_add_missing (sub_dir); + + /* Unlike GInotifyFileMonitor, which always uses a directory monitor + * regardless of the type of the file being monitored, kqueue doesn't + * give us events generated by files under it when we are monitoring + * a directory. We have to monitor the file itself to know changes which + * was made to the file itself. */ + if (path_file != NULL) + { + sub_file = _kqsub_new (g_steal_pointer (&path_file), + g_steal_pointer (&file_basename), + kqueue_monitor, source); + if (!_kqsub_start_watching (sub_file)) + _km_add_missing (sub_file); + } + + kqueue_monitor->sub_dir = sub_dir; + kqueue_monitor->sub_file = sub_file; + g_clear_pointer (&path_dir, g_free); + g_clear_pointer (&path_file, g_free); + g_clear_pointer (&file_basename, g_free); +} + +static void +g_kqueue_file_monitor_class_init (GKqueueFileMonitorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass); + GLocalFileMonitorClass *local_file_monitor_class = G_LOCAL_FILE_MONITOR_CLASS (klass); + + gobject_class->finalize = g_kqueue_file_monitor_finalize; + file_monitor_class->cancel = g_kqueue_file_monitor_cancel; + + local_file_monitor_class->is_supported = g_kqueue_file_monitor_is_supported; + local_file_monitor_class->start = g_kqueue_file_monitor_start; + local_file_monitor_class->mount_notify = TRUE; /* TODO: ??? */ +} + +static void +g_kqueue_file_monitor_init (GKqueueFileMonitor *monitor) +{ +} + +static gboolean +g_kqueue_file_monitor_callback (gint fd, GIOCondition condition, gpointer user_data) +{ + gint64 now = g_source_get_time (kq_source); + kqueue_sub *sub; + GFileMonitorSource *source; + struct kevent ev; + struct timespec ts; + + memset (&ts, 0, sizeof(ts)); + + /* We must hold the global lock before accessing any kqueue_sub because it is + * possible for other threads to call g_kqueue_file_monitor_cancel, which may + * free the kqueue_sub struct we are accessing. */ + G_LOCK (kq_lock); + + while (kevent(fd, NULL, 0, &ev, 1, &ts) > 0) + { + if (ev.filter != EVFILT_VNODE || ev.udata == NULL) + continue; + + sub = ev.udata; + source = sub->source; + + /* When we are monitoring a regular file which already exists, ignore + * events generated by its parent directory. This has to be the first + * check to prevent the following code to emit useless events */ + if (sub->is_dir && sub->mon->sub_file != NULL && sub->mon->sub_file->fd != -1) + continue; + + if (ev.flags & EV_ERROR) + ev.fflags = NOTE_REVOKE; + + if (sub->is_dir && ev.fflags & (NOTE_WRITE | NOTE_EXTEND)) + { + /* If we are monitoring on a non-existent regular file, trigger the + * rescan of missing files immediately so we don't have to wait for + * 4 seconds for discovering missing files. We pass the sub_file + * corresponding to the GKqueueFileMonitor to 'check_this_sub_only' + * argument to prevent _km_scan_missing from emitting 'CREATED' + * events because _kh_dir_diff will do it for us. */ + if (sub->mon->sub_file != NULL && sub->mon->sub_file->fd == -1) + _km_scan_missing (sub->mon->sub_file); + + /* If we are monitoring a regular file, don't emit 'DELETED' events + * from the directory monitor because it will be emitted from the + * file itself when a NOTE_DELETE is reported on sub_file. */ + _kh_dir_diff (sub, sub->mon->sub_file == NULL); + +#ifdef NOTE_TRUNCATE + ev.fflags &= ~(NOTE_WRITE | NOTE_EXTEND | NOTE_TRUNCATE); +#else + ev.fflags &= ~(NOTE_WRITE | NOTE_EXTEND); +#endif + } + + /* Here starts the long section of mapping kqueue events to + * GFileMonitorEvent. Since kqueue can return multiple events in a + * single kevent struct, we must use 'if' instead of 'else if'. */ + if (ev.fflags & NOTE_DELETE) + { + struct stat st; + if (fstat (sub->fd, &st) < 0) + st.st_nlink = 0; + + g_file_monitor_source_handle_event (source, + G_FILE_MONITOR_EVENT_DELETED, + sub->basename, NULL, NULL, now); + + /* If the last reference to the file was removed, delete the + * subscription from kqueue and add it to the missing list. + * If you are monitoring a file which has hard link count higher + * than 1, it is possible for the same file to emit 'DELETED' + * events multiple times. */ + if (st.st_nlink == 0) + { + _kqsub_cancel (sub); + _km_add_missing (sub); + } + } + if (ev.fflags & NOTE_REVOKE) + { + g_file_monitor_source_handle_event (source, + G_FILE_MONITOR_EVENT_UNMOUNTED, + sub->basename, NULL, NULL, now); + _kqsub_cancel (sub); + _km_add_missing (sub); + } + if (ev.fflags & NOTE_ATTRIB) + { + g_file_monitor_source_handle_event (source, + G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED, + sub->basename, NULL, NULL, now); + } +#ifdef NOTE_TRUNCATE + if (ev.fflags & (NOTE_WRITE | NOTE_EXTEND | NOTE_TRUNCATE)) +#else + if (ev.fflags & (NOTE_WRITE | NOTE_EXTEND)) +#endif + { + g_file_monitor_source_handle_event (source, + G_FILE_MONITOR_EVENT_CHANGED, + sub->basename, NULL, NULL, now); + } + if (ev.fflags & NOTE_RENAME) + { + /* Since there’s apparently no way to get the new name of the + * file out of kqueue(), all we can do is say that this one has + * been deleted. */ + g_file_monitor_source_handle_event (source, + G_FILE_MONITOR_EVENT_DELETED, + sub->basename, NULL, NULL, now); + } +#ifdef NOTE_CLOSE_WRITE + if (ev.fflags & NOTE_CLOSE_WRITE) + { + g_file_monitor_source_handle_event (source, + G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, + sub->basename, NULL, NULL, now); + } +#endif + + /* Handle the case when a file is created again shortly after it was + * deleted. It has to be the last check because 'DELETED' must happen + * before 'CREATED'. */ + if (ev.fflags & (NOTE_DELETE | NOTE_REVOKE)) + _km_scan_missing (NULL); + } + + G_UNLOCK (kq_lock); + + return TRUE; +} + +static gboolean +g_kqueue_file_monitor_is_supported (void) +{ + int errsv; + + G_LOCK (kq_lock); + + if (kq_queue == -1) + { + kq_queue = kqueue (); + errsv = errno; + + if (kq_queue == -1) + { + g_warning ("Unable to create a kqueue: %s", g_strerror (errsv)); + G_UNLOCK (kq_lock); + return FALSE; + } + + kq_source = g_unix_fd_source_new (kq_queue, G_IO_IN); + g_source_set_callback (kq_source, (GSourceFunc) g_kqueue_file_monitor_callback, NULL, NULL); + g_source_attach (kq_source, GLIB_PRIVATE_CALL (g_get_worker_context) ()); + } + + G_UNLOCK (kq_lock); + + return TRUE; +} + +static gboolean +g_kqueue_file_monitor_cancel (GFileMonitor *monitor) +{ + GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (monitor); + + /* We must hold the global lock before calling _kqsub_cancel. However, we + * cannot call G_LOCK in _kqsub_cancel because it is also used by + * g_kqueue_file_monitor_callback, which already holds the lock itself. */ + G_LOCK (kq_lock); + + if (kqueue_monitor->sub_dir) + { + _kqsub_cancel (kqueue_monitor->sub_dir); + _kqsub_free (kqueue_monitor->sub_dir); + kqueue_monitor->sub_dir = NULL; + } + if (kqueue_monitor->sub_file) + { + _kqsub_cancel (kqueue_monitor->sub_file); + _kqsub_free (kqueue_monitor->sub_file); + kqueue_monitor->sub_file = NULL; + } + + G_UNLOCK (kq_lock); + +#ifndef O_EVTONLY + if (kqueue_monitor->fallback) + { + g_signal_handlers_disconnect_by_func (kqueue_monitor->fallback, _fallback_callback, kqueue_monitor); + g_file_monitor_cancel (kqueue_monitor->fallback); + } +#endif + + if (G_FILE_MONITOR_CLASS (g_kqueue_file_monitor_parent_class)->cancel) + (*G_FILE_MONITOR_CLASS (g_kqueue_file_monitor_parent_class)->cancel) (monitor); + + return TRUE; +} + +static kqueue_sub * +_kqsub_new (gchar *filename, gchar *basename, GKqueueFileMonitor *mon, GFileMonitorSource *source) +{ + kqueue_sub *sub; + + sub = g_slice_new (kqueue_sub); + sub->filename = filename; + sub->basename = basename; + sub->mon = mon; + g_source_ref ((GSource *) source); + sub->source = source; + sub->fd = -1; + sub->deps = NULL; + sub->is_dir = 0; + + return sub; +} + +static void +_kqsub_free (kqueue_sub *sub) +{ + g_assert (sub->deps == NULL); + g_assert (sub->fd == -1); + + g_source_unref ((GSource *) sub->source); + g_free (sub->filename); + g_free (sub->basename); + g_slice_free (kqueue_sub, sub); +} + +static void +_kqsub_cancel (kqueue_sub *sub) +{ + /* WARNING: Before calling this function, you must hold a lock on kq_lock + * or you will cause use-after-free in g_kqueue_file_monitor_callback. */ + + struct kevent ev; + + /* Remove the event and close the file descriptor to automatically + * delete pending events. */ + if (sub->fd != -1) + { + EV_SET (&ev, sub->fd, EVFILT_VNODE, EV_DELETE, note_all (), 0, sub); + if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1) + { + g_warning ("Unable to remove event for %s: %s", sub->filename, g_strerror (errno)); + } + close (sub->fd); + sub->fd = -1; + } + + _km_remove (sub); + + if (sub->deps) + { + dl_free (sub->deps); + sub->deps = NULL; + } +} + +gboolean +_kqsub_start_watching (kqueue_sub *sub) +{ + struct stat st; + struct kevent ev; + + sub->fd = open (sub->filename, O_KQFLAG); + if (sub->fd == -1) + return FALSE; + + if (fstat (sub->fd, &st) == -1) + { + g_warning ("fstat failed for %s: %s", sub->filename, g_strerror (errno)); + close (sub->fd); + sub->fd = -1; + return FALSE; + } + + sub->is_dir = (st.st_mode & S_IFDIR) ? 1 : 0; + if (sub->is_dir) + { + if (sub->deps) + dl_free (sub->deps); + + sub->deps = dl_listing (sub->filename); + } + + EV_SET (&ev, sub->fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, note_all (), 0, sub); + if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1) + { + g_warning ("Unable to add event for %s: %s", sub->filename, g_strerror (errno)); + close (sub->fd); + sub->fd = -1; + return FALSE; + } + + return TRUE; +} diff --git a/gio/kqueue/kqueue-helper.c b/gio/kqueue/kqueue-helper.c new file mode 100644 index 0000000..b3e42a2 --- /dev/null +++ b/gio/kqueue/kqueue-helper.c @@ -0,0 +1,196 @@ +/******************************************************************************* + Copyright (c) 2011, 2012 Dmitry Matveev + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*******************************************************************************/ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kqueue-helper.h" + +typedef struct { + kqueue_sub *sub; + GFileMonitorSource *source; + gboolean handle_deleted; +} handle_ctx; + +/** + * handle_created: + * @udata: a pointer to user data (#handle_context). + * @path: file name of a new file. + * @inode: inode number of a new file. + * + * A callback function for the directory diff calculation routine, + * produces G_FILE_MONITOR_EVENT_CREATED event for a created file. + **/ +static void +handle_created (void *udata, const char *path, ino_t inode) +{ + handle_ctx *ctx = NULL; + gint64 now; + gchar *fullname; + struct stat st; + + (void) inode; + ctx = (handle_ctx *) udata; + g_assert (udata != NULL); + g_assert (ctx->sub != NULL); + g_assert (ctx->source != NULL); + + now = g_get_monotonic_time (); + g_file_monitor_source_handle_event (ctx->source, G_FILE_MONITOR_EVENT_CREATED, path, + NULL, NULL, now); + + /* Copied from ih_event_callback to report 'CHANGES_DONE_HINT' earlier. */ + fullname = g_build_filename (ctx->sub->filename, path, NULL); + if (stat (fullname, &st) != 0 || !S_ISREG (st.st_mode) || st.st_nlink != 1) + g_file_monitor_source_handle_event (ctx->source, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, path, + NULL, NULL, now); + g_free (fullname); +} + +/** + * handle_deleted: + * @udata: a pointer to user data (#handle_context). + * @path: file name of the removed file. + * @inode: inode number of the removed file. + * + * A callback function for the directory diff calculation routine, + * produces G_FILE_MONITOR_EVENT_DELETED event for a deleted file. + **/ +static void +handle_deleted (void *udata, const char *path, ino_t inode) +{ + handle_ctx *ctx = NULL; + + (void) inode; + ctx = (handle_ctx *) udata; + g_assert (udata != NULL); + g_assert (ctx->sub != NULL); + g_assert (ctx->source != NULL); + + if (!ctx->handle_deleted) + return; + + g_file_monitor_source_handle_event (ctx->source, G_FILE_MONITOR_EVENT_DELETED, path, + NULL, NULL, g_get_monotonic_time ()); +} + +/** + * handle_moved: + * @udata: a pointer to user data (#handle_context). + * @from_path: file name of the source file. + * @from_inode: inode number of the source file. + * @to_path: file name of the replaced file. + * @to_inode: inode number of the replaced file. + * + * A callback function for the directory diff calculation routine, + * produces G_FILE_MONITOR_EVENT_RENAMED event on a move. + **/ +static void +handle_moved (void *udata, + const char *from_path, + ino_t from_inode, + const char *to_path, + ino_t to_inode) +{ + handle_ctx *ctx = NULL; + + (void) from_inode; + (void) to_inode; + + ctx = (handle_ctx *) udata; + g_assert (udata != NULL); + g_assert (ctx->sub != NULL); + g_assert (ctx->source != NULL); + + g_file_monitor_source_handle_event (ctx->source, G_FILE_MONITOR_EVENT_RENAMED, + from_path, to_path, NULL, g_get_monotonic_time ()); +} + +/** + * handle_overwritten: + * @data: a pointer to user data (#handle_context). + * @path: file name of the overwritten file. + * @node: inode number of the overwritten file. + * + * A callback function for the directory diff calculation routine, + * produces G_FILE_MONITOR_EVENT_DELETED/CREATED event pair when + * an overwrite occurs in the directory (see dep-list for details). + **/ +static void +handle_overwritten (void *udata, const char *path, ino_t inode) +{ + handle_ctx *ctx = NULL; + + (void) inode; + ctx = (handle_ctx *) udata; + g_assert (udata != NULL); + g_assert (ctx->sub != NULL); + g_assert (ctx->source != NULL); + + g_file_monitor_source_handle_event (ctx->source, G_FILE_MONITOR_EVENT_DELETED, + path, NULL, NULL, g_get_monotonic_time ()); + + g_file_monitor_source_handle_event (ctx->source, G_FILE_MONITOR_EVENT_CREATED, + path, NULL, NULL, g_get_monotonic_time ()); +} + +static const traverse_cbs cbs = { + handle_created, + handle_deleted, + handle_moved, + handle_overwritten, + handle_moved, + NULL, /* many added */ + NULL, /* many removed */ + NULL, /* names updated */ +}; + + +void +_kh_dir_diff (kqueue_sub *sub, gboolean handle_deleted) +{ + dep_list *was; + handle_ctx ctx; + + memset (&ctx, 0, sizeof (handle_ctx)); + ctx.sub = sub; + ctx.source = sub->source; + ctx.handle_deleted = handle_deleted; + + was = sub->deps; + sub->deps = dl_listing (sub->filename); + + dl_calculate (was, sub->deps, &cbs, &ctx); + + dl_free (was); +} diff --git a/gio/kqueue/kqueue-helper.h b/gio/kqueue/kqueue-helper.h new file mode 100644 index 0000000..418b38c --- /dev/null +++ b/gio/kqueue/kqueue-helper.h @@ -0,0 +1,60 @@ +/******************************************************************************* + Copyright (c) 2011, 2012 Dmitry Matveev + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*******************************************************************************/ + +#ifndef __KQUEUE_HELPER_H +#define __KQUEUE_HELPER_H + +#include +#include + +#include "dep-list.h" + +typedef struct _GKqueueFileMonitor GKqueueFileMonitor; + +/** + * kqueue_sub: + * @mon: a pointer to the GKqueueFileMonitor which holds this subscription + * @filename: a name of the file to monitor + * @fd: the associated file descriptor (used by kqueue) + * + * Represents a subscription on a file or directory. To check whether a + * subscription is active, check the fd field. If fd is not -1, it is an + * active subscription which can emit events from kqueue. + */ +typedef struct +{ + GKqueueFileMonitor *mon; + GFileMonitorSource *source; + gchar* filename; + gchar* basename; + int fd; + dep_list* deps; + int is_dir; +} kqueue_sub; + +gboolean _kqsub_start_watching (kqueue_sub *sub); +void _kh_dir_diff (kqueue_sub *sub, gboolean handle_deleted); +void _km_add_missing (kqueue_sub *sub); +gboolean _km_scan_missing (kqueue_sub *check_this_sub_only); +void _km_remove (kqueue_sub *sub); + +#endif /* __KQUEUE_HELPER_H */ diff --git a/gio/kqueue/kqueue-missing.c b/gio/kqueue/kqueue-missing.c new file mode 100644 index 0000000..d1ffdf4 --- /dev/null +++ b/gio/kqueue/kqueue-missing.c @@ -0,0 +1,179 @@ +/******************************************************************************* + Copyright (c) 2011, 2012 Dmitry Matveev + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*******************************************************************************/ + +#include +#include "glib-private.h" + +#include "kqueue-helper.h" + + +#define SCAN_MISSING_TIME 4 /* 1/4 Hz */ + +static gboolean km_debug_enabled = FALSE; +#define KM_W if (km_debug_enabled) g_warning + +static GSList *missing_subs_list = NULL; +G_LOCK_DEFINE_STATIC (missing_lock); + +static gboolean scan_missing_running = FALSE; /* must be accessed under @missing_lock */ + + +static gboolean +_km_scan_missing_cb (gpointer user_data) +{ + return _km_scan_missing (NULL); +} + +/** + * _km_add_missing: + * @sub: a #kqueue_sub + * + * Adds a subscription to the missing files list. + **/ +void +_km_add_missing (kqueue_sub *sub) +{ + G_LOCK (missing_lock); + if (g_slist_find (missing_subs_list, sub)) + { + KM_W ("asked to add %s to missing list but it's already on the list!\n", sub->filename); + G_UNLOCK (missing_lock); + return; + } + + KM_W ("adding %s to missing list\n", sub->filename); + missing_subs_list = g_slist_prepend (missing_subs_list, sub); + + if (!scan_missing_running) + { + GSource *source; + scan_missing_running = TRUE; + source = g_timeout_source_new_seconds (SCAN_MISSING_TIME); + g_source_set_callback (source, _km_scan_missing_cb, NULL, NULL); + g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ()); + g_source_unref (source); + } + + G_UNLOCK (missing_lock); +} + +/** + * _kh_file_appeared_cb: + * @sub: a #kqueue_sub + * + * A callback function for kqueue-missing subsystem. + * + * Signals that a missing file has finally appeared in the filesystem. + * Emits %G_FILE_MONITOR_EVENT_CREATED. + **/ +static void +_kh_file_appeared_cb (kqueue_sub *sub) +{ + gint64 now = g_get_monotonic_time (); + + g_assert (sub != NULL); + g_assert (sub->filename); + + if (!g_file_test (sub->filename, G_FILE_TEST_EXISTS)) + return; + + g_file_monitor_source_handle_event (sub->source, G_FILE_MONITOR_EVENT_CREATED, + sub->basename, NULL, NULL, now); + g_file_monitor_source_handle_event (sub->source, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, + sub->basename, NULL, NULL, now); +} + +/** + * _km_scan_missing: + * @user_data: unused + * + * The core missing files watching routine. + * + * Traverses through a list of missing files, tries to start watching each with + * kqueue, removes the appropriate entry and invokes a user callback if the file + * has appeared. + * + * Returns: %FALSE if no missing files left, %TRUE otherwise. + **/ +gboolean +_km_scan_missing (kqueue_sub *check_this_sub_only) +{ + GSList *head; + GSList *not_missing = NULL; + gboolean retval = FALSE; + + G_LOCK (missing_lock); + + if (missing_subs_list) + KM_W ("we have a job"); + + for (head = missing_subs_list; head; head = head->next) + { + kqueue_sub *sub = (kqueue_sub *) head->data; + g_assert (sub != NULL); + g_assert (sub->filename != NULL); + + if (check_this_sub_only != NULL && sub != check_this_sub_only) + continue; + + if (_kqsub_start_watching (sub)) + { + KM_W ("file %s now exists, starting watching", sub->filename); + if (check_this_sub_only == NULL) + _kh_file_appeared_cb (sub); + not_missing = g_slist_prepend (not_missing, head); + } + } + + for (head = not_missing; head; head = head->next) + { + GSList *link = (GSList *) head->data; + missing_subs_list = g_slist_remove_link (missing_subs_list, link); + } + g_slist_free (not_missing); + + if (missing_subs_list == NULL) + { + scan_missing_running = FALSE; + retval = FALSE; + } + else + retval = TRUE; + + G_UNLOCK (missing_lock); + return retval; +} + + +/** + * _km_remove: + * @sub: a #kqueue_sub + * + * Removes a subscription from a list of missing files. + **/ +void +_km_remove (kqueue_sub *sub) +{ + G_LOCK (missing_lock); + missing_subs_list = g_slist_remove (missing_subs_list, sub); + G_UNLOCK (missing_lock); +} diff --git a/gio/kqueue/meson.build b/gio/kqueue/meson.build new file mode 100644 index 0000000..d389b06 --- /dev/null +++ b/gio/kqueue/meson.build @@ -0,0 +1,13 @@ +kqueue_sources = [ + 'gkqueuefilemonitor.c', + 'kqueue-helper.c', + 'kqueue-missing.c', + 'dep-list.c', +] + +kqueue_lib = static_library('kqueue', + sources : kqueue_sources, + include_directories : [configinc, glibinc, gmoduleinc], + dependencies : [gioenumtypes_dep], + pic : true, + c_args : gio_c_args) diff --git a/gio/meson.build b/gio/meson.build new file mode 100644 index 0000000..9019104 --- /dev/null +++ b/gio/meson.build @@ -0,0 +1,1050 @@ +gio_c_args = [ + '-DG_LOG_DOMAIN="GLib-GIO"', + '-DGIO_COMPILATION', + '-DGIO_MODULE_DIR="@0@"'.format(glib_giomodulesdir), + '-DLOCALSTATEDIR="@0@"'.format(glib_localstatedir), +] + +gio_c_args += glib_hidden_visibility_args + +# FIXME: Install empty glib_giomodulesdir + +gnetworking_h_conf = configuration_data() + +gnetworking_h_nameser_compat_include = '' + +if host_system not in ['windows', 'android'] + # Don't check for C_IN on Android since it does not define it in public + # headers, we define it ourselves wherever necessary + if not cc.compiles('''#include + #include + int qclass = C_IN;''', + name : 'C_IN in public headers (no arpa/nameser_compat.h needed)') + if cc.compiles('''#include + #include + #include + int qclass = C_IN;''', + name : 'arpa/nameser_compat.h needed for C_IN') + gnetworking_h_nameser_compat_include = '#include ' + else + error('Could not find required includes for ARPA C_IN') + endif + endif +endif + +network_libs = [ ] +network_args = [ ] +if host_system != 'windows' + # res_query() + res_query_test = '''#include + int main (int argc, char ** argv) { + return res_query("test", 0, 0, (void *)0, 0); + }''' + res_query_test_full = '''#include + #include + #include + ''' + res_query_test + if not cc.links(res_query_test_full, name : 'res_query()') + if cc.links(res_query_test_full, args : '-lresolv', name : 'res_query() in -lresolv') + network_libs += [ cc.find_library('resolv') ] + network_args += [ '-lresolv' ] + elif cc.links(res_query_test, args : '-lbind', name : 'res_query() in -lbind') + network_libs += [ cc.find_library('bind') ] + network_args += [ '-lbind' ] + elif cc.links(res_query_test, args : '-lsocket', name : 'res_query() in -lsocket') + network_libs += [ cc.find_library('socket') ] + network_args += [ '-lsocket' ] + else + error('Could not find res_query()') + endif + endif + + # socket() + socket_test = '''#include + #include + int main (int argc, char ** argv) { + return socket(1, 2, 3); + }''' + if not cc.links(socket_test, name : 'socket()') + if cc.links(socket_test, args : '-lsocket', name : 'socket() in -lsocket') + network_libs += [ cc.find_library('socket') ] + network_args += [ '-lsocket' ] + else + error('Could not find socket()') + endif + endif + + # dn_comp() + if cc.links('''#include + int main (int argc, char ** argv) { + return dn_comp(NULL, NULL, 0, NULL, NULL) == -1; + } ''', args : network_args, name : 'dn_comp()') + glib_conf.set('HAVE_DN_COMP', 1) + endif + + # res_nclose() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + res_nclose(&res); + return 0; + }''', args : network_args, name : 'res_nclose()') + glib_conf.set('HAVE_RES_NCLOSE', 1) + endif + + # res_ndestroy() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + res_ndestroy(&res); + return 0; + }''', args : network_args, name : 'res_ndestroy()') + glib_conf.set('HAVE_RES_NDESTROY', 1) + endif + + # res_ninit() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + return res_ninit(&res); + }''', args : network_args, name : 'res_ninit()') + glib_conf.set('HAVE_RES_NINIT', 1) + endif + + # res_nquery() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + return res_nquery(&res, "test", 0, 0, (void *)0, 0); + }''', args : network_args, name : 'res_nquery()') + glib_conf.set('HAVE_RES_NQUERY', 1) + endif + + if cc.has_type('struct ip_mreqn', prefix : '#include ') + glib_conf.set('HAVE_IP_MREQN', 1) + endif + + if cc.compiles('''#include + #include + int main (int argc, char ** argv) { + struct ifreq ifr; + ioctl(0, SIOCGIFADDR, &ifr); + return 0; + }''', + name : 'ioctl with request SIOCGIFADDR') + glib_conf.set('HAVE_SIOCGIFADDR', '/**/') + endif + +endif + +if host_system == 'android' + # struct ip_mreq_source definition is broken on Android NDK <= r16 + # See https://bugzilla.gnome.org/show_bug.cgi?id=740791 + if not cc.compiles('''#include + int main(int argc, char ** argv) { + struct ip_mreq_source mc_req_src; + mc_req_src.imr_interface.s_addr = 0; + return 0; + }''', + name : 'ip_mreq_source.imr_interface has s_addr member') + glib_conf.set('BROKEN_IP_MREQ_SOURCE_STRUCT', 1) + endif +endif + +gnetworking_h_conf.set('NAMESER_COMPAT_INCLUDE', gnetworking_h_nameser_compat_include) + +gnetworking_h = configure_file(input : 'gnetworking.h.in', + output : 'gnetworking.h', + install_dir : join_paths(get_option('includedir'), 'glib-2.0/gio'), + configuration : gnetworking_h_conf) + +gdbus_headers = files( + 'gdbusauthobserver.h', + 'gcredentials.h', + 'gdbusutils.h', + 'gdbuserror.h', + 'gdbusaddress.h', + 'gdbusconnection.h', + 'gdbusmessage.h', + 'gdbusnameowning.h', + 'gdbusnamewatching.h', + 'gdbusproxy.h', + 'gdbusintrospection.h', + 'gdbusmethodinvocation.h', + 'gdbusserver.h', + 'gdbusinterface.h', + 'gdbusinterfaceskeleton.h', + 'gdbusobject.h', + 'gdbusobjectskeleton.h', + 'gdbusobjectproxy.h', + 'gdbusobjectmanager.h', + 'gdbusobjectmanagerclient.h', + 'gdbusobjectmanagerserver.h', + 'gtestdbus.h', +) + +gdbus_sources = files( + 'gdbusutils.c', + 'gdbusaddress.c', + 'gdbusauthobserver.c', + 'gdbusauth.c', + 'gdbusauthmechanism.c', + 'gdbusauthmechanismanon.c', + 'gdbusauthmechanismexternal.c', + 'gdbusauthmechanismsha1.c', + 'gdbuserror.c', + 'gdbusconnection.c', + 'gdbusmessage.c', + 'gdbusnameowning.c', + 'gdbusnamewatching.c', + 'gdbusproxy.c', + 'gdbusprivate.c', + 'gdbusintrospection.c', + 'gdbusmethodinvocation.c', + 'gdbusserver.c', + 'gdbusinterface.c', + 'gdbusinterfaceskeleton.c', + 'gdbusobject.c', + 'gdbusobjectskeleton.c', + 'gdbusobjectproxy.c', + 'gdbusobjectmanager.c', + 'gdbusobjectmanagerclient.c', + 'gdbusobjectmanagerserver.c', + 'gtestdbus.c', +) + +# Generate gdbus-codegen +subdir('gdbus-2.0/codegen') + +# Generate xdp-dbus.{c,h} +xdp_dbus_generated = custom_target('xdp-dbus', + input : ['org.freedesktop.portal.Documents.xml', + 'org.freedesktop.portal.OpenURI.xml', + 'org.freedesktop.portal.ProxyResolver.xml', + 'org.freedesktop.portal.Trash.xml'], + output : ['xdp-dbus.h', 'xdp-dbus.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.freedesktop.portal.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'xdp-dbus', + '--c-namespace', 'GXdp', + '@INPUT@']) + +# Generate gdbus-generated.{c,h} +gdbus_daemon_generated = custom_target('gdbus-daemon-generated', + input : ['dbus-daemon.xml'], + output : ['gdbus-daemon-generated.h', 'gdbus-daemon-generated.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'gdbus-daemon-generated', + '--c-namespace', '_G', '@INPUT@']) + +settings_headers = files( + 'gsettingsbackend.h', + 'gsettingsschema.h', + 'gsettings.h', +) + +settings_sources = files( + 'gvdb/gvdb-reader.c', + 'gdelayedsettingsbackend.c', + 'gkeyfilesettingsbackend.c', + 'gmemorysettingsbackend.c', + 'gnullsettingsbackend.c', + 'gsettingsbackend.c', + 'gsettingsschema.c', + 'gsettings-mapping.c', + 'gsettings.c', +) + +if host_system == 'windows' + settings_sources += files('gregistrysettingsbackend.c') +endif + +application_headers = files( + 'gapplication.h', + 'gapplicationcommandline.h', + + 'gactiongroup.h', + 'gactionmap.h', + 'gsimpleactiongroup.h', + 'gremoteactiongroup.h', + 'gactiongroupexporter.h', + 'gdbusactiongroup.h', + 'gaction.h', + 'gpropertyaction.h', + 'gsimpleaction.h', + + 'gmenumodel.h', + 'gmenu.h', + 'gmenuexporter.h', + 'gdbusmenumodel.h', + 'gnotification.h', +) + +application_sources = files( + 'gapplication.c', + 'gapplicationcommandline.c', + 'gapplicationimpl-dbus.c', + + 'gactiongroup.c', + 'gactionmap.c', + 'gsimpleactiongroup.c', + 'gremoteactiongroup.c', + 'gactiongroupexporter.c', + 'gdbusactiongroup.c', + 'gaction.c', + 'gpropertyaction.c', + 'gsimpleaction.c', + + 'gmenumodel.c', + 'gmenu.c', + 'gmenuexporter.c', + 'gdbusmenumodel.c', + 'gnotification.c', + 'gnotificationbackend.c', +) + +local_sources = files( + 'ghttpproxy.c', + 'glocalfile.c', + 'glocalfileenumerator.c', + 'glocalfileinfo.c', + 'glocalfileinputstream.c', + 'glocalfilemonitor.c', + 'glocalfileoutputstream.c', + 'glocalfileiostream.c', + 'glocalvfs.c', + 'gsocks4proxy.c', + 'gsocks4aproxy.c', + 'gsocks5proxy.c', + 'thumbnail-verify.c', +) + +platform_deps = [] +internal_deps = [] +appinfo_sources = [] +contenttype_sources = [] +portal_sources = [] +unix_sources = [] +win32_sources = [] + +# This is also used by tests/gdbus-daemon, so use files() to include the path +gdbus_daemon_sources = [ + files('gdbusdaemon.c'), + gdbus_daemon_generated, +] + +if host_system != 'windows' + unix_sources = files( + 'gfiledescriptorbased.c', + 'giounix-private.c', + 'gunixfdlist.c', + 'gunixfdmessage.c', + 'gunixmount.c', + 'gunixmounts.c', + 'gunixvolume.c', + 'gunixvolumemonitor.c', + 'gunixinputstream.c', + 'gunixoutputstream.c', + 'gfdonotificationbackend.c', + 'ggtknotificationbackend.c', + ) + + portal_sources = [files( + 'gdocumentportal.c', + 'gopenuriportal.c', + 'gmemorymonitorportal.c', + 'gnetworkmonitorportal.c', + 'gpowerprofilemonitorportal.c', + 'gproxyresolverportal.c', + 'gtrashportal.c', + 'gportalsupport.c', + 'gportalnotificationbackend.c'), + xdp_dbus_generated + ] + + gio_unix_include_headers = files( + 'gfiledescriptorbased.h', + 'gunixmounts.h', + 'gunixfdlist.h', + 'gunixfdmessage.h', + 'gunixinputstream.h', + 'gunixoutputstream.h', + ) + + if glib_have_cocoa + settings_sources += files('gnextstepsettingsbackend.m') + contenttype_sources += files('gosxcontenttype.m') + appinfo_sources += files('gosxappinfo.m') + framework_dep = dependency('appleframeworks', modules : ['Foundation', 'CoreFoundation', 'AppKit']) + platform_deps += [framework_dep] + if glib_have_os_x_9_or_later + unix_sources += files('gcocoanotificationbackend.m') + endif + application_headers += files('gosxappinfo.h') + else + contenttype_sources += files('gcontenttype.c') + appinfo_sources += files('gdesktopappinfo.c') + gio_unix_include_headers += files('gdesktopappinfo.h') + endif + + subdir('xdgmime') + internal_deps += [xdgmime_lib] + + install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio') + + if glib_conf.has('HAVE_NETLINK') + unix_sources += files( + 'gnetworkmonitornetlink.c', + 'gnetworkmonitornm.c', + ) + endif +else + appinfo_sources += files('gwin32appinfo.c') + contenttype_sources += files('gcontenttype-win32.c') + platform_deps += [cc.find_library('shlwapi'), + cc.find_library('dnsapi'), + iphlpapi_dep, + winsock2] + platform_deps += uwp_gio_deps + + win32_sources += files( + 'gmemorymonitorwin32.c', + 'gwin32registrykey.c', + 'gwin32mount.c', + 'gwin32volumemonitor.c', + 'gwin32inputstream.c', + 'gwin32outputstream.c', + 'gwin32file-sync-stream.c', + 'gwin32packageparser.c', + 'gwin32networkmonitor.c', + 'gwin32networkmonitor.h', + 'gwin32notificationbackend.c', + 'gwin32sid.c', + 'gwin32sid.h', + ) + + gio_win_rc = configure_file( + input: 'gio.rc.in', + output: 'gio.rc', + configuration: glibconfig_conf, + ) + gio_win_res = windows.compile_resources(gio_win_rc) + win32_sources += [gio_win_res] + + gio_win32_include_headers = files( + 'gwin32inputstream.h', + 'gwin32outputstream.h', + ) + install_headers(gio_win32_include_headers, subdir : 'gio-win32-2.0/gio') +endif + +gio_sources = files( + 'gappinfo.c', + 'gasynchelper.c', + 'gasyncinitable.c', + 'gasyncresult.c', + 'gbufferedinputstream.c', + 'gbufferedoutputstream.c', + 'gbytesicon.c', + 'gcancellable.c', + 'gcharsetconverter.c', + 'gcontextspecificgroup.c', + 'gconverter.c', + 'gconverterinputstream.c', + 'gconverteroutputstream.c', + 'gcredentials.c', + 'gdatagrambased.c', + 'gdatainputstream.c', + 'gdataoutputstream.c', + 'gdebugcontroller.c', + 'gdebugcontrollerdbus.c', + 'gdrive.c', + 'gdummyfile.c', + 'gdummyproxyresolver.c', + 'gdummytlsbackend.c', + 'gemblem.c', + 'gemblemedicon.c', + 'gfile.c', + 'gfileattribute.c', + 'gfileenumerator.c', + 'gfileicon.c', + 'gfileinfo.c', + 'gfileinputstream.c', + 'gfilemonitor.c', + 'gfilenamecompleter.c', + 'gfileoutputstream.c', + 'gfileiostream.c', + 'gfilterinputstream.c', + 'gfilteroutputstream.c', + 'gicon.c', + 'ginetaddress.c', + 'ginetaddressmask.c', + 'ginetsocketaddress.c', + 'ginitable.c', + 'ginputstream.c', + 'gioerror.c', + 'giomodule.c', + 'giomodule-priv.c', + 'gioscheduler.c', + 'giostream.c', + 'gloadableicon.c', + 'gmarshal-internal.c', + 'gmount.c', + 'gmemorymonitor.c', + 'gmemorymonitordbus.c', + 'gmemoryinputstream.c', + 'gmemoryoutputstream.c', + 'gmountoperation.c', + 'gnativesocketaddress.c', + 'gnativevolumemonitor.c', + 'gnetworkaddress.c', + 'gnetworking.c', + 'gnetworkmonitor.c', + 'gnetworkmonitorbase.c', + 'gnetworkservice.c', + 'goutputstream.c', + 'gpermission.c', + 'gpollableinputstream.c', + 'gpollableoutputstream.c', + 'gpollableutils.c', + 'gpollfilemonitor.c', + 'gpowerprofilemonitor.c', + 'gpowerprofilemonitordbus.c', + 'gproxy.c', + 'gproxyaddress.c', + 'gproxyaddressenumerator.c', + 'gproxyresolver.c', + 'gresolver.c', + 'gresource.c', + 'gresourcefile.c', + 'gseekable.c', + 'gsimpleasyncresult.c', + 'gsimpleiostream.c', + 'gsimplepermission.c', + 'gsimpleproxyresolver.c', + 'gsocket.c', + 'gsocketaddress.c', + 'gsocketaddressenumerator.c', + 'gsocketclient.c', + 'gsocketconnectable.c', + 'gsocketconnection.c', + 'gsocketcontrolmessage.c', + 'gsocketinputstream.c', + 'gsocketlistener.c', + 'gsocketoutputstream.c', + 'gsocketservice.c', + 'gsrvtarget.c', + 'gsubprocesslauncher.c', + 'gsubprocess.c', + 'gtask.c', + 'gtcpconnection.c', + 'gtcpwrapperconnection.c', + 'gthemedicon.c', + 'gthreadedsocketservice.c', + 'gthreadedresolver.c', + 'gthreadedresolver.h', + 'gtlsbackend.c', + 'gtlscertificate.c', + 'gtlsclientconnection.c', + 'gtlsconnection.c', + 'gtlsdatabase.c', + 'gtlsfiledatabase.c', + 'gtlsinteraction.c', + 'gtlspassword.c', + 'gtlsserverconnection.c', + 'gdtlsconnection.c', + 'gdtlsclientconnection.c', + 'gdtlsserverconnection.c', + 'gunionvolumemonitor.c', + 'gunixconnection.c', + 'gunixcredentialsmessage.c', + 'gunixsocketaddress.c', + 'gvfs.c', + 'gvolume.c', + 'gvolumemonitor.c', + 'gzlibcompressor.c', + 'gzlibdecompressor.c', + 'glistmodel.c', + 'gliststore.c', + '../glib/gtrace.c', +) + +gio_sources += appinfo_sources +gio_sources += contenttype_sources +gio_sources += gdbus_daemon_sources +gio_sources += unix_sources +gio_sources += win32_sources +gio_sources += application_sources +gio_sources += settings_sources +gio_sources += gdbus_sources +gio_sources += portal_sources +gio_sources += local_sources + +MISSING_STUFF = ''' +# This is read by gobject-introspection/misc/ and gtk-doc +gio-public-headers.txt: Makefile + '$(AM_V_GEN) echo $(gioinclude_HEADERS) $(giowin32include_HEADERS) $(giounixinclude_HEADERS) > $@.tmp && mv $@.tmp $@ + +gio.def: libgio-2.0.la + '$(AM_V_GEN) dumpbin.exe -exports .libs/libgio-2.0-0.dll | awk 'BEGIN { print "EXPORTS" } / +[[:digit:]]+ +[[:xdigit:]]+ +[[:xdigit:]]+/{ print $$4 }' > gio.def.tmp && mv gio.def.tmp gio.def + +gio-2.0.lib: libgio-2.0.la gio.def + '$(AM_V_GEN) lib.exe -machine:@LIB_EXE_MACHINE_FLAG@ -name:libgio-2.0-$(LT_CURRENT_MINUS_AGE).dll -def:$(builddir)/gio.def -out:$@ +''' + +gio_headers = files( + 'gappinfo.h', + 'gasyncinitable.h', + 'gasyncresult.h', + 'gbufferedinputstream.h', + 'gbufferedoutputstream.h', + 'gbytesicon.h', + 'gcancellable.h', + 'gcontenttype.h', + 'gcharsetconverter.h', + 'gconverter.h', + 'gconverterinputstream.h', + 'gconverteroutputstream.h', + 'gdatagrambased.h', + 'gdatainputstream.h', + 'gdataoutputstream.h', + 'gdebugcontroller.h', + 'gdebugcontrollerdbus.h', + 'gdrive.h', + 'gemblem.h', + 'gemblemedicon.h', + 'gfile.h', + 'gfileattribute.h', + 'gfileenumerator.h', + 'gfileicon.h', + 'gfileinfo.h', + 'gfileinputstream.h', + 'gfilemonitor.h', + 'gfilenamecompleter.h', + 'gfileoutputstream.h', + 'gfileiostream.h', + 'gfilterinputstream.h', + 'gfilteroutputstream.h', + 'gicon.h', + 'ginetaddress.h', + 'ginetaddressmask.h', + 'ginetsocketaddress.h', + 'ginitable.h', + 'ginputstream.h', + 'gio.h', + 'gio-autocleanups.h', + 'gioenums.h', + 'gioerror.h', + 'giomodule.h', + 'gioscheduler.h', + 'giostream.h', + 'giotypes.h', + 'gloadableicon.h', + 'gmount.h', + 'gmemoryinputstream.h', + 'gmemorymonitor.h', + 'gmemoryoutputstream.h', + 'gmountoperation.h', + 'gnativesocketaddress.h', + 'gnativevolumemonitor.h', + 'gnetworkaddress.h', + 'gnetworkmonitor.h', + 'gnetworkservice.h', + 'goutputstream.h', + 'gpermission.h', + 'gpollableinputstream.h', + 'gpollableoutputstream.h', + 'gpollableutils.h', + 'gpowerprofilemonitor.h', + 'gproxy.h', + 'gproxyaddress.h', + 'gproxyaddressenumerator.h', + 'gproxyresolver.h', + 'gresolver.h', + 'gresource.h', + 'gseekable.h', + 'gsimpleasyncresult.h', + 'gsimpleiostream.h', + 'gsimplepermission.h', + 'gsimpleproxyresolver.h', + 'gsocket.h', + 'gsocketaddress.h', + 'gsocketaddressenumerator.h', + 'gsocketclient.h', + 'gsocketconnectable.h', + 'gsocketconnection.h', + 'gsocketcontrolmessage.h', + 'gsocketlistener.h', + 'gsocketservice.h', + 'gsrvtarget.h', + 'gsubprocess.h', + 'gsubprocesslauncher.h', + 'gtask.h', + 'gtcpconnection.h', + 'gtcpwrapperconnection.h', + 'gthemedicon.h', + 'gthreadedsocketservice.h', + 'gtlsbackend.h', + 'gtlscertificate.h', + 'gtlsclientconnection.h', + 'gtlsconnection.h', + 'gtlsdatabase.h', + 'gtlsfiledatabase.h', + 'gtlsinteraction.h', + 'gtlspassword.h', + 'gtlsserverconnection.h', + 'gdtlsconnection.h', + 'gdtlsclientconnection.h', + 'gdtlsserverconnection.h', + 'gunixconnection.h', + 'gunixcredentialsmessage.h', + 'gunixsocketaddress.h', + 'gvfs.h', + 'gvolume.h', + 'gvolumemonitor.h', + 'gzlibcompressor.h', + 'gzlibdecompressor.h', + 'glistmodel.h', + 'gliststore.h', +) + +gio_headers += application_headers +gio_headers += settings_headers +gio_headers += gdbus_headers +install_headers(gio_headers, subdir : 'glib-2.0/gio/') + +# We can't use gnome.mkenums() because the GNOME module looks for glib-mkenums +# in PATH, which means you can't bootstrap glib with its own glib-mkenums. +gioenumtypes_h = custom_target('gioenumtypes_h', + output : 'gioenumtypes.h', + capture : true, + input : gio_headers, + install : true, + install_dir : join_paths(get_option('includedir'), 'glib-2.0/gio'), + command : [python, glib_mkenums, + '--template', files('gioenumtypes.h.template'), + '@INPUT@', gnetworking_h]) + +gioenumtypes_c = custom_target('gioenumtypes_c', + output : 'gioenumtypes.c', + capture : true, + input : gio_headers, + depends : [gioenumtypes_h], + command : [python, glib_mkenums, + '--template', files('gioenumtypes.c.template'), + '@INPUT@', gnetworking_h]) + +gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h, glib_enumtypes_h]) + +# inotify +if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1 + subdir('inotify') + internal_deps += [ inotify_lib ] +endif + +# kevent +if have_func_kqueue and have_func_kevent + subdir('kqueue') + internal_deps += [ kqueue_lib ] +endif + +if host_system == 'windows' + subdir('win32') + internal_deps += [ giowin32_lib ] +endif + +if have_bash + bash_comp_inst_dir = '' + if bash_comp_dep.found() + bash_comp_dir_override = bash_comp_dep.version().version_compare('>= 2.10') ? ['datadir', get_option('datadir')] : ['prefix', get_option('prefix')] + bash_comp_inst_dir = bash_comp_dep.get_pkgconfig_variable('completionsdir', define_variable: bash_comp_dir_override) + endif + + if bash_comp_inst_dir == '' + message('Found bash-completion but the .pc file did not set \'completionsdir\', fallback to a predefined path') + bash_comp_inst_dir = join_paths(get_option('datadir'), 'bash-completion/completions') + endif + + install_data([ + 'completion/gapplication', + 'completion/gdbus', + 'completion/gio', + 'completion/gsettings', + 'completion/gresource' + ], + install_dir: bash_comp_inst_dir) +endif + +if enable_dtrace + gio_dtrace_obj = dtrace_obj_gen.process('gio_probes.d') + gio_dtrace_hdr = dtrace_hdr_gen.process('gio_probes.d') +else + gio_dtrace_obj = [] + gio_dtrace_hdr = [] +endif + +libgio = library('gio-2.0', + gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources, + gio_dtrace_hdr, gio_dtrace_obj, + version : library_version, + soversion : soversion, + darwin_versions : darwin_versions, + install : true, + include_directories : [configinc, gioinc], + # '$(gio_win32_res_ldflag)', + link_with: internal_deps, + dependencies : [libz_dep, libdl_dep, libmount_dep, libglib_dep, + libgobject_dep, libgmodule_dep, selinux_dep, xattr_dep, + platform_deps, network_libs, libsysprof_capture_dep], + c_args : gio_c_args, + objc_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : [noseh_link_args, glib_link_flags], +) + +if get_option('gio_module_dir') != '' + pkgconfig_giomodulesdir = join_paths('${prefix}', get_option('gio_module_dir')) +else + pkgconfig_giomodulesdir = join_paths('${libdir}', 'gio', 'modules') +endif + +schemas_subdir = join_paths('glib-2.0', 'schemas') + +libgio_dep = declare_dependency(link_with : libgio, + dependencies : [libgmodule_dep, libgobject_dep, gioenumtypes_dep], + include_directories : [gioinc]) + +# Work around variables kwarg requiring Meson 0.56 +if meson.version().version_compare('>=0.56.0') + libgio_dep = declare_dependency(dependencies: libgio_dep, + variables: [ + 'schemasdir=' + join_paths(glib_datadir, schemas_subdir), + 'giomoduledir=' + glib_giomodulesdir, + ] + ) +endif + +pkg.generate(libgio, + requires : ['glib-2.0', 'gobject-2.0'], + variables : ['datadir=' + join_paths('${prefix}', get_option('datadir')), + 'schemasdir=' + join_paths('${datadir}', schemas_subdir), + 'bindir=' + join_paths('${prefix}', get_option('bindir')), + 'giomoduledir=' + pkgconfig_giomodulesdir, + 'gio=' + join_paths('${bindir}', 'gio'), + 'gio_querymodules=' + join_paths('${bindir}', 'gio-querymodules'), + 'glib_compile_schemas=' + join_paths('${bindir}', 'glib-compile-schemas'), + 'glib_compile_resources=' + join_paths('${bindir}', 'glib-compile-resources'), + 'gdbus=' + join_paths('${bindir}', 'gdbus'), + 'gdbus_codegen=' + join_paths('${bindir}', 'gdbus-codegen'), + 'gresource=' + join_paths('${bindir}', 'gresource'), + 'gsettings=' + join_paths('${bindir}', 'gsettings')], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-2.0', + name : 'GIO', + description : 'glib I/O library', +) + +if meson.version().version_compare('>=0.54.0') + meson.override_dependency('gio-2.0', libgio_dep) +endif + + +if host_system == 'windows' + pkg.generate(requires : ['gobject-2.0', 'gmodule-no-export-2.0', 'gio-2.0'], + subdirs : ['gio-win32-2.0'], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-windows-2.0', + name : 'GIO Windows specific APIs', + description : 'Windows specific headers for glib I/O library', + ) + if meson.version().version_compare('>=0.54.0') + meson.override_dependency('gio-windows-2.0', libgio_dep) + endif +else + pkg.generate(requires : ['gobject-2.0', 'gio-2.0'], + subdirs : ['gio-unix-2.0'], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-unix-2.0', + name : 'GIO unix specific APIs', + description : 'unix specific headers for glib I/O library', + ) + if meson.version().version_compare('>=0.54.0') + meson.override_dependency('gio-unix-2.0', libgio_dep) + endif +endif + +if host_system == 'windows' + # Hack till https://github.com/mesonbuild/meson/issues/2324 is fixed + libgiounix_dep = dependency('', required : false) + libgiowin32_dep = libgio_dep +else + libgiowin32_dep = dependency('', required : false) + libgiounix_dep = libgio_dep +endif + +# Dependencies used by executables below +have_libelf = false +libelf = dependency('libelf', version : '>= 0.8.12', required : get_option ('libelf')) +if libelf.found() + have_libelf = true +else + # This fallback is necessary on *BSD. elfutils isn't the only libelf + # implementation, and *BSD usually includes their own libelf as a system + # library which doesn't have a corresponding .pc file. + libelf = cc.find_library('elf', required : get_option ('libelf')) + have_libelf = libelf.found() + have_libelf = have_libelf and cc.has_function('elf_begin', dependencies : libelf) + have_libelf = have_libelf and cc.has_function('elf_getshdrstrndx', dependencies : libelf) + have_libelf = have_libelf and cc.has_function('elf_getshdrnum', dependencies : libelf) + have_libelf = have_libelf and cc.has_header('libelf.h') +endif + +if have_libelf + glib_conf.set('HAVE_LIBELF', 1) +else + libelf = [] +endif + +gconstructor_as_data_h = custom_target('gconstructor_as_data.h', + input : ['data-to-c.py', files('../glib/gconstructor.h')], + output : ['gconstructor_as_data.h'], + command : [python, '@INPUT0@', '@INPUT1@', 'gconstructor_code', '@OUTPUT@']) + +# Several installed executables +gio_tool_sources = [ + 'gio-tool.c', + 'gio-tool.h', + 'gio-tool-cat.c', + 'gio-tool-copy.c', + 'gio-tool-info.c', + 'gio-tool-launch.c', + 'gio-tool-list.c', + 'gio-tool-mime.c', + 'gio-tool-mkdir.c', + 'gio-tool-monitor.c', + 'gio-tool-mount.c', + 'gio-tool-move.c', + 'gio-tool-open.c', + 'gio-tool-rename.c', + 'gio-tool-remove.c', + 'gio-tool-save.c', + 'gio-tool-set.c', + 'gio-tool-trash.c', + 'gio-tool-tree.c', +] + +executable('gio', gio_tool_sources, + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +executable('gresource', 'gresource-tool.c', + install : true, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libelf, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +gio_querymodules = executable('gio-querymodules', 'gio-querymodules.c', 'giomodule-priv.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +glib_compile_schemas = executable('glib-compile-schemas', + ['gvdb/gvdb-builder.c', 'glib-compile-schemas.c'], + install : true, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +glib_compile_resources = executable('glib-compile-resources', + [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-resources.c'], + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +# Cannot override those programs in cross compilation case because they are +# native executables that cannot be run on the build machine. +# See https://gitlab.gnome.org/GNOME/glib/issues/1859. +if not meson.is_cross_build() + meson.override_find_program('glib-compile-schemas', glib_compile_schemas) + meson.override_find_program('glib-compile-resources', glib_compile_resources) + meson.override_find_program('gio-querymodules', gio_querymodules) +endif + +executable('gsettings', 'gsettings-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) +install_data('gschema.dtd', + install_dir : join_paths(get_option('datadir'), schemas_subdir)) + +install_data(['gschema.loc', 'gschema.its'], + install_dir : join_paths(get_option('datadir'), 'gettext/its')) + +executable('gdbus', 'gdbus-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +if host_system != 'windows' and not glib_have_cocoa + executable('gapplication', 'gapplication-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) +endif + +if enable_systemtap + gio_stp = configure_file(input : 'gio.stp.in', + output : '@0@.stp'.format(libgio.full_path().split('/').get(-1)), + configuration : stp_cdata, + install_dir : tapset_install_dir, + ) +endif + +subdir('fam') +if build_tests + subdir('tests') +endif + +# The following is an example for building internal marshallers that are used +# by GIO. We cannot guarantee glib-genmarshal availability while building GLib +# so they are pre-generated and placed into gmarshal-internal.[ch]. +# +# gmarshal_internal = gnome.genmarshal('gmarshal-internal', +# sources: 'gmarshal-internal.list', +# prefix: '_g_cclosure_marshal', +# valist_marshallers: true, +# internal: true, +# ) diff --git a/gio/org.freedesktop.portal.Documents.xml b/gio/org.freedesktop.portal.Documents.xml new file mode 100644 index 0000000..7867931 --- /dev/null +++ b/gio/org.freedesktop.portal.Documents.xml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gio/org.freedesktop.portal.OpenURI.xml b/gio/org.freedesktop.portal.OpenURI.xml new file mode 100644 index 0000000..5ed054c --- /dev/null +++ b/gio/org.freedesktop.portal.OpenURI.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gio/org.freedesktop.portal.ProxyResolver.xml b/gio/org.freedesktop.portal.ProxyResolver.xml new file mode 100644 index 0000000..4b39fc0 --- /dev/null +++ b/gio/org.freedesktop.portal.ProxyResolver.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + diff --git a/gio/org.freedesktop.portal.Trash.xml b/gio/org.freedesktop.portal.Trash.xml new file mode 100644 index 0000000..6142f3d --- /dev/null +++ b/gio/org.freedesktop.portal.Trash.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + diff --git a/gio/strinfo.c b/gio/strinfo.c new file mode 100644 index 0000000..f5e92a4 --- /dev/null +++ b/gio/strinfo.c @@ -0,0 +1,348 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include +#include + +/* + * The string info map is an efficient data structure designed to be + * used with a small set of items. It is used by GSettings schemas for + * three purposes: + * + * 1) Implement with a list of valid strings + * + * 2) Implement by mapping one string to another + * + * 3) Implement enumerated types by mapping strings to integer values + * (and back). + * + * The map is made out of an array of uint32s. Each entry in the array + * is an integer value, followed by a specially formatted string value: + * + * The string starts with the byte 0xff or 0xfe, followed by the + * content of the string, followed by a nul byte, followed by + * additional nul bytes for padding, followed by a 0xff byte. + * + * Padding is added so that the entire formatted string takes up a + * multiple of 4 bytes, and not less than 8 bytes. The requirement + * for a string to take up 8 bytes is so that the scanner doesn't lose + * synch and mistake a string for an integer value. + * + * The first byte of the formatted string depends on if the integer is + * an enum value (0xff) or an alias (0xfe). If it is an alias then the + * number refers to the word offset within the info map at which the + * integer corresponding to the "target" value is stored. + * + * For example, consider the case of the string info map representing an + * enumerated type of 'foo' (value 1) and 'bar' (value 2) and 'baz' + * (alias for 'bar'). Note that string info maps are always little + * endian. + * + * x01 x00 x00 x00 xff 'f' 'o' 'o' x00 x00 x00 xff x02 x00 x00 x00 + * xff 'b' 'a' 'r' x00 x00 x00 xff x03 x00 x00 x00 xfe 'b' 'a' 'z' + * x00 x00 x00 xff + * + * + * The operations that someone may want to perform with the map: + * + * - look up if a string is valid (and not an alias) + * - look up the integer value for a enum 'nick' + * - look up the integer value for the target of an alias + * - look up an alias and convert it to its target string + * - look up the enum nick for a given value + * + * In order to look up if a string is valid, it is padded on either side + * (as described) and scanned for in the array. For example, you might + * look for "foo": + * + * xff 'f' 'o' 'o' x00 x00 x00 xff + * + * In order to look up the integer value for a nick, the string is padded + * on either side and scanned for in the array, as above. Instead of + * merely succeeding, we look at the integer value to the left of the + * match. This is the enum value. + * + * In order to look up an alias and convert it to its target enum value, + * the string is padded on either side (as described, with 0xfe) and + * scanned for. For example, you might look for "baz": + * + * xfe 'b' 'a' 'z' x00 x00 x00 xff + * + * The integer immediately preceding the match then contains the offset + * of the integer value of the target. In our example, that's '3'. + * This index is dereferenced to find the enum value of '2'. + * + * To convert the alias to its target string, 5 bytes just need to be + * added past the start of the integer value to find the start of the + * string. + * + * To look up the enum nick for a given value, the value is searched for + * in the array. To ensure that the value isn't matching the inside of a + * string, we must check that it is either the first item in the array or + * immediately preceded by the byte 0xff. It must also be immediately + * followed by the byte 0xff. + * + * Because strings always take up a minimum of 2 words, because 0xff or + * 0xfe never appear inside of a utf-8 string and because no two integer + * values ever appear in sequence, the only way we can have the + * sequence: + * + * xff __ __ __ __ xff (or 0xfe) + * + * is in the event of an integer nested between two strings. + * + * For implementation simplicity/efficiency, strings may not be more + * than 65 characters in length (ie: 17 32bit words after padding). + * + * In the event that we are doing (ie: not an enum type) then + * the value of each choice is set to zero and ignored. + */ + +#define STRINFO_MAX_WORDS 17 +G_GNUC_UNUSED static guint +strinfo_string_to_words (const gchar *string, + guint32 *words, + gboolean alias) +{ + guint n_words; + gsize size; + + size = strlen (string); + + n_words = MAX (2, (size + 6) >> 2); + + if (n_words > STRINFO_MAX_WORDS) + return FALSE; + + words[0] = GUINT32_TO_LE (alias ? 0xfe : 0xff); + words[n_words - 1] = GUINT32_TO_BE (0xff); + memcpy (((gchar *) words) + 1, string, size + 1); + + return n_words; +} + +G_GNUC_UNUSED static gint +strinfo_scan (const guint32 *strinfo, + guint length, + const guint32 *words, + guint n_words) +{ + guint i = 0; + + if (length < n_words) + return -1; + + while (i <= length - n_words) + { + guint j = 0; + + for (j = 0; j < n_words; j++) + if (strinfo[i + j] != words[j]) + break; + + if (j == n_words) + return i; /* match */ + + /* skip at least one word, continue */ + i += j ? j : 1; + } + + return -1; +} + +G_GNUC_UNUSED static gint +strinfo_find_string (const guint32 *strinfo, + guint length, + const gchar *string, + gboolean alias) +{ + guint32 words[STRINFO_MAX_WORDS]; + guint n_words; + + if (length == 0) + return -1; + + n_words = strinfo_string_to_words (string, words, alias); + + return strinfo_scan (strinfo + 1, length - 1, words, n_words); +} + +G_GNUC_UNUSED static gint +strinfo_find_integer (const guint32 *strinfo, + guint length, + guint32 value) +{ + guint i; + + for (i = 0; i < length; i++) + if (strinfo[i] == GUINT32_TO_LE (value)) + { + const guchar *charinfo = (const guchar *) &strinfo[i]; + + /* make sure it has 0xff on either side */ + if ((i == 0 || charinfo[-1] == 0xff) && charinfo[4] == 0xff) + return i; + } + + return -1; +} + +G_GNUC_UNUSED static gboolean +strinfo_is_string_valid (const guint32 *strinfo, + guint length, + const gchar *string) +{ + return strinfo_find_string (strinfo, length, string, FALSE) != -1; +} + +G_GNUC_UNUSED static gboolean +strinfo_enum_from_string (const guint32 *strinfo, + guint length, + const gchar *string, + guint *result) +{ + gint index; + + index = strinfo_find_string (strinfo, length, string, FALSE); + + if (index < 0) + return FALSE; + + *result = GUINT32_FROM_LE (strinfo[index]); + return TRUE; +} + +G_GNUC_UNUSED static const gchar * +strinfo_string_from_enum (const guint32 *strinfo, + guint length, + guint value) +{ + gint index; + + index = strinfo_find_integer (strinfo, length, value); + + if (index < 0) + return NULL; + + return 1 + (const gchar *) &strinfo[index + 1]; +} + +G_GNUC_UNUSED static const gchar * +strinfo_string_from_alias (const guint32 *strinfo, + guint length, + const gchar *alias) +{ + gint index; + + index = strinfo_find_string (strinfo, length, alias, TRUE); + + if (index < 0) + return NULL; + + return 1 + (const gchar *) &strinfo[GUINT32_TO_LE (strinfo[index]) + 1]; +} + +G_GNUC_UNUSED static GVariant * +strinfo_enumerate (const guint32 *strinfo, + guint length) +{ + GVariantBuilder builder; + const gchar *ptr, *end; + + ptr = (gpointer) strinfo; + end = ptr + 4 * length; + + ptr += 4; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY); + + while (ptr < end) + { + /* don't include aliases */ + if (*ptr == '\xff') + g_variant_builder_add (&builder, "s", ptr + 1); + + /* find the end of this string */ + ptr = memchr (ptr, '\xff', end - ptr); + g_assert (ptr != NULL); + + /* skip over the int to the next string */ + ptr += 5; + } + + return g_variant_builder_end (&builder); +} + +G_GNUC_UNUSED static void +strinfo_builder_append_item (GString *builder, + const gchar *string, + guint value) +{ + guint32 words[STRINFO_MAX_WORDS]; + guint n_words; + + value = GUINT32_TO_LE (value); + + n_words = strinfo_string_to_words (string, words, FALSE); + g_string_append_len (builder, (void *) &value, sizeof value); + g_string_append_len (builder, (void *) words, 4 * n_words); +} + +G_GNUC_UNUSED static gboolean +strinfo_builder_append_alias (GString *builder, + const gchar *alias, + const gchar *target) +{ + guint32 words[STRINFO_MAX_WORDS]; + guint n_words; + guint value; + gint index; + + index = strinfo_find_string ((const guint32 *) builder->str, + builder->len / 4, target, FALSE); + + if (index == -1) + return FALSE; + + value = GUINT32_TO_LE (index); + + n_words = strinfo_string_to_words (alias, words, TRUE); + g_string_append_len (builder, (void *) &value, sizeof value); + g_string_append_len (builder, (void *) words, 4 * n_words); + + return TRUE; +} + +G_GNUC_UNUSED static gboolean +strinfo_builder_contains (GString *builder, + const gchar *string) +{ + return strinfo_find_string ((const guint32 *) builder->str, + builder->len / 4, string, FALSE) != -1 || + strinfo_find_string ((const guint32 *) builder->str, + builder->len / 4, string, TRUE) != -1; +} + +G_GNUC_UNUSED static gboolean +strinfo_builder_contains_value (GString *builder, + guint value) +{ + return strinfo_string_from_enum ((const guint32 *) builder->str, + builder->len / 4, value) != NULL; +} diff --git a/gio/tests/.gitignore b/gio/tests/.gitignore new file mode 100644 index 0000000..e6c9124 --- /dev/null +++ b/gio/tests/.gitignore @@ -0,0 +1,146 @@ +actions +appinfo +appinfo-test +appmonitor +apps +async-close-output-stream +async-splice-output-stream +autoptr +basic-application +buffered-input-stream +buffered-output-stream +cancellable +connectable +contenttype +contexts +converter-stream +credentials +data-input-stream +data-output-stream +dbus-appinfo +dbus-launch +de/ +defaultvalue +desktop-app-info +echo-server +file +fileattributematcher +filter-cat +filter-streams +gapplication +gapplication-example-actions +gapplication-example-cmdline +gapplication-example-cmdline2 +gapplication-example-cmdline3 +gapplication-example-dbushooks +gapplication-example-menu +gapplication-example-open +gdbus-addresses +gdbus-auth +gdbus-bz627724 +gdbus-close-pending +gdbus-connection +gdbus-connection-flush +gdbus-connection-flush-helper +gdbus-connection-loss +gdbus-connection-slow +gdbus-daemon +gdbus-error +gdbus-example-export +gdbus-example-objectmanager-client +gdbus-example-objectmanager-server +gdbus-example-own-name +gdbus-example-peer +gdbus-example-proxy-subclass +gdbus-example-server +gdbus-example-subtree +gdbus-example-unix-fd-client +gdbus-example-watch-name +gdbus-example-watch-proxy +gdbus-exit-on-close +gdbus-export +gdbus-introspection +gdbus-message +gdbus-names +gdbus-non-socket +gdbus-overflow +gdbus-peer +gdbus-peer-object-manager +gdbus-proxy +gdbus-proxy-threads +gdbus-proxy-well-known-name +gdbus-serialization +gdbus-test-codegen +gdbus-test-codegen-generated* +gdbus-test-codegen-old +gdbus-test-fixture +gdbus-testserver +gdbus-threading +gdbus-address-get-session +glistmodel +gio-du +giomodule +giotypefuncs.inc +gnotification +gsubprocess +gsubprocess-testprog +g-file +g-file-info +g-icon +gmenumodel +gschemas.compiled +gsettings +gsettings.store +httpd +icons +inet-address +io-stream +live-g-file +memory-input-stream +memory-output-stream +mimeapps +monitor +network-address +network-monitor +org.gtk.test.enums.xml +org.gtk.test.gschema.xml +permission +pollable +plugin_resources.c +proxy +proxy-test +readwrite +resolver +resources +send-data +services/org.gtk.GDBus.Examples.ObjectManager.service +simple-async-result +simple-proxy +sleepy-stream +stream-rw_all +socket +socket-address +socket-client +socket-listener +socket-service +socket-server +srvtarget +task +test-generated.txt +test.gresource +test.mo +test_resources.c +test_resources2.c +test_resources2.h +testfilemonitor +thumbnail-verification +tls-certificate +tls-database +tls-interaction +unix-fd +unix-streams +vfs +volumemonitor +xgen-gio +xgen-giosrc.c +gresource-big-test.txt diff --git a/gio/tests/111_digit_test.gresource.xml b/gio/tests/111_digit_test.gresource.xml new file mode 100644 index 0000000..00efcc3 --- /dev/null +++ b/gio/tests/111_digit_test.gresource.xml @@ -0,0 +1,6 @@ + + + + test1.txt + + diff --git a/gio/tests/actions.c b/gio/tests/actions.c new file mode 100644 index 0000000..a41e989 --- /dev/null +++ b/gio/tests/actions.c @@ -0,0 +1,1249 @@ +#include +#include +#include + +#include "gdbus-sessionbus.h" + +typedef struct +{ + GVariant *params; + gboolean did_run; +} Activation; + +static void +activate (GAction *action, + GVariant *parameter, + gpointer user_data) +{ + Activation *activation = user_data; + + if (parameter) + activation->params = g_variant_ref (parameter); + else + activation->params = NULL; + activation->did_run = TRUE; +} + +static void +test_basic (void) +{ + Activation a = { 0, }; + GSimpleAction *action; + gchar *name; + GVariantType *parameter_type; + gboolean enabled; + GVariantType *state_type; + GVariant *state; + + action = g_simple_action_new ("foo", NULL); + g_assert_true (g_action_get_enabled (G_ACTION (action))); + g_assert_null (g_action_get_parameter_type (G_ACTION (action))); + g_assert_null (g_action_get_state_type (G_ACTION (action))); + g_assert_null (g_action_get_state_hint (G_ACTION (action))); + g_assert_null (g_action_get_state (G_ACTION (action))); + g_object_get (action, + "name", &name, + "parameter-type", ¶meter_type, + "enabled", &enabled, + "state-type", &state_type, + "state", &state, + NULL); + g_assert_cmpstr (name, ==, "foo"); + g_assert_null (parameter_type); + g_assert_true (enabled); + g_assert_null (state_type); + g_assert_null (state); + g_free (name); + + g_signal_connect (action, "activate", G_CALLBACK (activate), &a); + g_assert_false (a.did_run); + g_action_activate (G_ACTION (action), NULL); + g_assert_true (a.did_run); + a.did_run = FALSE; + + g_simple_action_set_enabled (action, FALSE); + g_action_activate (G_ACTION (action), NULL); + g_assert_false (a.did_run); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*g_variant_is_of_type*failed*"); + g_action_activate (G_ACTION (action), g_variant_new_string ("xxx")); + g_test_assert_expected_messages (); + } + + g_object_unref (action); + g_assert_false (a.did_run); + + action = g_simple_action_new ("foo", G_VARIANT_TYPE_STRING); + g_assert_true (g_action_get_enabled (G_ACTION (action))); + g_assert_true (g_variant_type_equal (g_action_get_parameter_type (G_ACTION (action)), G_VARIANT_TYPE_STRING)); + g_assert_null (g_action_get_state_type (G_ACTION (action))); + g_assert_null (g_action_get_state_hint (G_ACTION (action))); + g_assert_null (g_action_get_state (G_ACTION (action))); + + g_signal_connect (action, "activate", G_CALLBACK (activate), &a); + g_assert_false (a.did_run); + g_action_activate (G_ACTION (action), g_variant_new_string ("Hello world")); + g_assert_true (a.did_run); + g_assert_cmpstr (g_variant_get_string (a.params, NULL), ==, "Hello world"); + g_variant_unref (a.params); + a.did_run = FALSE; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*failed*"); + g_action_activate (G_ACTION (action), NULL); + g_test_assert_expected_messages (); + } + + g_object_unref (action); + g_assert_false (a.did_run); +} + +static void +test_name (void) +{ + g_assert_false (g_action_name_is_valid ("")); + g_assert_false (g_action_name_is_valid ("(")); + g_assert_false (g_action_name_is_valid ("%abc")); + g_assert_false (g_action_name_is_valid ("$x1")); + g_assert_true (g_action_name_is_valid ("abc.def")); + g_assert_true (g_action_name_is_valid ("ABC-DEF")); +} + +static gboolean +strv_strv_cmp (const gchar * const *a, + const gchar * const *b) +{ + guint n; + + for (n = 0; a[n] != NULL; n++) + { + if (!g_strv_contains (b, a[n])) + return FALSE; + } + + for (n = 0; b[n] != NULL; n++) + { + if (!g_strv_contains (a, b[n])) + return FALSE; + } + + return TRUE; +} + +static gboolean +strv_set_equal (const gchar * const *strv, ...) +{ + guint count; + va_list list; + const gchar *str; + gboolean res; + + res = TRUE; + count = 0; + va_start (list, strv); + while (1) + { + str = va_arg (list, const gchar *); + if (str == NULL) + break; + if (!g_strv_contains (strv, str)) + { + res = FALSE; + break; + } + count++; + } + va_end (list); + + if (res) + res = g_strv_length ((gchar**)strv) == count; + + return res; +} + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +static void +test_simple_group (void) +{ + GSimpleActionGroup *group; + Activation a = { 0, }; + GSimpleAction *simple; + GAction *action; + gchar **actions; + GVariant *state; + + simple = g_simple_action_new ("foo", NULL); + g_signal_connect (simple, "activate", G_CALLBACK (activate), &a); + g_assert_false (a.did_run); + g_action_activate (G_ACTION (simple), NULL); + g_assert_true (a.did_run); + a.did_run = FALSE; + + group = g_simple_action_group_new (); + g_simple_action_group_insert (group, G_ACTION (simple)); + g_object_unref (simple); + + g_assert_false (a.did_run); + g_action_group_activate_action (G_ACTION_GROUP (group), "foo", NULL); + g_assert_true (a.did_run); + + simple = g_simple_action_new_stateful ("bar", G_VARIANT_TYPE_STRING, g_variant_new_string ("hihi")); + g_simple_action_group_insert (group, G_ACTION (simple)); + g_object_unref (simple); + + g_assert_true (g_action_group_has_action (G_ACTION_GROUP (group), "foo")); + g_assert_true (g_action_group_has_action (G_ACTION_GROUP (group), "bar")); + g_assert_false (g_action_group_has_action (G_ACTION_GROUP (group), "baz")); + actions = g_action_group_list_actions (G_ACTION_GROUP (group)); + g_assert_cmpint (g_strv_length (actions), ==, 2); + g_assert_true (strv_set_equal ((const gchar * const *) actions, "foo", "bar", NULL)); + g_strfreev (actions); + g_assert_true (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "foo")); + g_assert_true (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar")); + g_assert_null (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "foo")); + g_assert_true (g_variant_type_equal (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING)); + g_assert_null (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "foo")); + g_assert_true (g_variant_type_equal (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING)); + g_assert_null (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "foo")); + g_assert_null (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "bar")); + g_assert_null (g_action_group_get_action_state (G_ACTION_GROUP (group), "foo")); + state = g_action_group_get_action_state (G_ACTION_GROUP (group), "bar"); + g_assert_true (g_variant_type_equal (g_variant_get_type (state), G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi"); + g_variant_unref (state); + + g_action_group_change_action_state (G_ACTION_GROUP (group), "bar", g_variant_new_string ("boo")); + state = g_action_group_get_action_state (G_ACTION_GROUP (group), "bar"); + g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "boo"); + g_variant_unref (state); + + action = g_simple_action_group_lookup (group, "bar"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); + g_assert_false (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar")); + + g_simple_action_group_remove (group, "bar"); + action = g_simple_action_group_lookup (group, "foo"); + g_assert_cmpstr (g_action_get_name (action), ==, "foo"); + action = g_simple_action_group_lookup (group, "bar"); + g_assert_null (action); + + simple = g_simple_action_new ("foo", NULL); + g_simple_action_group_insert (group, G_ACTION (simple)); + g_object_unref (simple); + + a.did_run = FALSE; + g_object_unref (group); + g_assert_false (a.did_run); +} + +G_GNUC_END_IGNORE_DEPRECATIONS + +static void +test_stateful (void) +{ + GSimpleAction *action; + GVariant *state; + + action = g_simple_action_new_stateful ("foo", NULL, g_variant_new_string ("hihi")); + g_assert_true (g_action_get_enabled (G_ACTION (action))); + g_assert_null (g_action_get_parameter_type (G_ACTION (action))); + g_assert_null (g_action_get_state_hint (G_ACTION (action))); + g_assert_true (g_variant_type_equal (g_action_get_state_type (G_ACTION (action)), + G_VARIANT_TYPE_STRING)); + state = g_action_get_state (G_ACTION (action)); + g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi"); + g_variant_unref (state); + + if (g_test_undefined ()) + { + GVariant *new_state = g_variant_ref_sink (g_variant_new_int32 (123)); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*g_variant_is_of_type*failed*"); + g_simple_action_set_state (action, new_state); + g_test_assert_expected_messages (); + g_variant_unref (new_state); + } + + g_simple_action_set_state (action, g_variant_new_string ("hello")); + state = g_action_get_state (G_ACTION (action)); + g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hello"); + g_variant_unref (state); + + g_object_unref (action); + + action = g_simple_action_new ("foo", NULL); + + if (g_test_undefined ()) + { + GVariant *new_state = g_variant_ref_sink (g_variant_new_int32 (123)); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*failed*"); + g_simple_action_set_state (action, new_state); + g_test_assert_expected_messages (); + g_variant_unref (new_state); + } + + g_object_unref (action); +} + +static void +test_default_activate (void) +{ + GSimpleAction *action; + GVariant *state; + + /* Test changing state via activation with parameter */ + action = g_simple_action_new_stateful ("foo", G_VARIANT_TYPE_STRING, g_variant_new_string ("hihi")); + g_action_activate (G_ACTION (action), g_variant_new_string ("bye")); + state = g_action_get_state (G_ACTION (action)); + g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "bye"); + g_variant_unref (state); + g_object_unref (action); + + /* Test toggling a boolean action via activation with no parameter */ + action = g_simple_action_new_stateful ("foo", NULL, g_variant_new_boolean (FALSE)); + g_action_activate (G_ACTION (action), NULL); + state = g_action_get_state (G_ACTION (action)); + g_assert_true (g_variant_get_boolean (state)); + g_variant_unref (state); + /* and back again */ + g_action_activate (G_ACTION (action), NULL); + state = g_action_get_state (G_ACTION (action)); + g_assert_false (g_variant_get_boolean (state)); + g_variant_unref (state); + g_object_unref (action); +} + +static gboolean foo_activated = FALSE; +static gboolean bar_activated = FALSE; + +static void +activate_foo (GSimpleAction *simple, + GVariant *parameter, + gpointer user_data) +{ + g_assert_true (user_data == GINT_TO_POINTER (123)); + g_assert_null (parameter); + foo_activated = TRUE; +} + +static void +activate_bar (GSimpleAction *simple, + GVariant *parameter, + gpointer user_data) +{ + g_assert_true (user_data == GINT_TO_POINTER (123)); + g_assert_cmpstr (g_variant_get_string (parameter, NULL), ==, "param"); + bar_activated = TRUE; +} + +static void +change_volume_state (GSimpleAction *action, + GVariant *value, + gpointer user_data) +{ + gint requested; + + requested = g_variant_get_int32 (value); + + /* Volume only goes from 0 to 10 */ + if (0 <= requested && requested <= 10) + g_simple_action_set_state (action, value); +} + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +static void +test_entries (void) +{ + const GActionEntry entries[] = { + { "foo", activate_foo, NULL, NULL, NULL, { 0 } }, + { "bar", activate_bar, "s", NULL, NULL, { 0 } }, + { "toggle", NULL, NULL, "false", NULL, { 0 } }, + { "volume", NULL, NULL, "0", change_volume_state, { 0 } }, + }; + GSimpleActionGroup *actions; + GVariant *state; + + actions = g_simple_action_group_new (); + g_simple_action_group_add_entries (actions, entries, + G_N_ELEMENTS (entries), + GINT_TO_POINTER (123)); + + g_assert_false (foo_activated); + g_action_group_activate_action (G_ACTION_GROUP (actions), "foo", NULL); + g_assert_true (foo_activated); + foo_activated = FALSE; + + g_assert_false (bar_activated); + g_action_group_activate_action (G_ACTION_GROUP (actions), "bar", + g_variant_new_string ("param")); + g_assert_true (bar_activated); + g_assert_false (foo_activated); + + if (g_test_undefined ()) + { + const GActionEntry bad_type = { + "bad-type", NULL, "ss", NULL, NULL, { 0 } + }; + const GActionEntry bad_state = { + "bad-state", NULL, NULL, "flse", NULL, { 0 } + }; + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*not a valid GVariant type string*"); + g_simple_action_group_add_entries (actions, &bad_type, 1, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*could not parse*"); + g_simple_action_group_add_entries (actions, &bad_state, 1, NULL); + g_test_assert_expected_messages (); + } + + state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume"); + g_assert_cmpint (g_variant_get_int32 (state), ==, 0); + g_variant_unref (state); + + /* should change */ + g_action_group_change_action_state (G_ACTION_GROUP (actions), "volume", + g_variant_new_int32 (7)); + state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume"); + g_assert_cmpint (g_variant_get_int32 (state), ==, 7); + g_variant_unref (state); + + /* should not change */ + g_action_group_change_action_state (G_ACTION_GROUP (actions), "volume", + g_variant_new_int32 (11)); + state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume"); + g_assert_cmpint (g_variant_get_int32 (state), ==, 7); + g_variant_unref (state); + + g_object_unref (actions); +} + +G_GNUC_END_IGNORE_DEPRECATIONS + +static void +test_parse_detailed (void) +{ + struct { + const gchar *detailed; + const gchar *expected_name; + const gchar *expected_target; + const gchar *expected_error; + const gchar *detailed_roundtrip; + } testcases[] = { + { "abc", "abc", NULL, NULL, "abc" }, + { " abc", NULL, NULL, "invalid format", NULL }, + { " abc", NULL, NULL, "invalid format", NULL }, + { "abc:", NULL, NULL, "invalid format", NULL }, + { ":abc", NULL, NULL, "invalid format", NULL }, + { "abc(", NULL, NULL, "invalid format", NULL }, + { "abc)", NULL, NULL, "invalid format", NULL }, + { "(abc", NULL, NULL, "invalid format", NULL }, + { ")abc", NULL, NULL, "invalid format", NULL }, + { "abc::xyz", "abc", "'xyz'", NULL, "abc::xyz" }, + { "abc('xyz')", "abc", "'xyz'", NULL, "abc::xyz" }, + { "abc(42)", "abc", "42", NULL, "abc(42)" }, + { "abc(int32 42)", "abc", "42", NULL, "abc(42)" }, + { "abc(@i 42)", "abc", "42", NULL, "abc(42)" }, + { "abc (42)", NULL, NULL, "invalid format", NULL }, + { "abc(42abc)", NULL, NULL, "invalid character in number", NULL }, + { "abc(42, 4)", "abc", "(42, 4)", "expected end of input", NULL }, + { "abc(42,)", "abc", "(42,)", "expected end of input", NULL } + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (testcases); i++) + { + GError *error = NULL; + GVariant *target; + gboolean success; + gchar *name; + + success = g_action_parse_detailed_name (testcases[i].detailed, &name, &target, &error); + g_assert_true (success == (error == NULL)); + if (success && testcases[i].expected_error) + g_error ("Unexpected success on '%s'. Expected error containing '%s'", + testcases[i].detailed, testcases[i].expected_error); + + if (!success && !testcases[i].expected_error) + g_error ("Unexpected failure on '%s': %s", testcases[i].detailed, error->message); + + if (!success) + { + if (!strstr (error->message, testcases[i].expected_error)) + g_error ("Failure message '%s' for string '%s' did not contained expected substring '%s'", + error->message, testcases[i].detailed, testcases[i].expected_error); + + g_error_free (error); + continue; + } + + g_assert_cmpstr (name, ==, testcases[i].expected_name); + g_assert_true ((target == NULL) == (testcases[i].expected_target == NULL)); + + if (success) + { + gchar *detailed; + + detailed = g_action_print_detailed_name (name, target); + g_assert_cmpstr (detailed, ==, testcases[i].detailed_roundtrip); + g_free (detailed); + } + + if (target) + { + GVariant *expected; + + expected = g_variant_parse (NULL, testcases[i].expected_target, NULL, NULL, NULL); + g_assert_true (expected); + + g_assert_cmpvariant (expected, target); + g_variant_unref (expected); + g_variant_unref (target); + } + + g_free (name); + } +} + +GHashTable *activation_counts; + +static void +count_activation (const gchar *action) +{ + gint count; + + if (activation_counts == NULL) + activation_counts = g_hash_table_new (g_str_hash, g_str_equal); + count = GPOINTER_TO_INT (g_hash_table_lookup (activation_counts, action)); + count++; + g_hash_table_insert (activation_counts, (gpointer)action, GINT_TO_POINTER (count)); + + g_main_context_wakeup (NULL); +} + +static gint +activation_count (const gchar *action) +{ + if (activation_counts == NULL) + return 0; + + return GPOINTER_TO_INT (g_hash_table_lookup (activation_counts, action)); +} + +static void +activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + count_activation (g_action_get_name (G_ACTION (action))); +} + +static void +activate_toggle (GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + GVariant *old_state, *new_state; + + count_activation (g_action_get_name (G_ACTION (action))); + + old_state = g_action_get_state (G_ACTION (action)); + new_state = g_variant_new_boolean (!g_variant_get_boolean (old_state)); + g_simple_action_set_state (action, new_state); + g_variant_unref (old_state); +} + +static void +activate_radio (GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + GVariant *new_state; + + count_activation (g_action_get_name (G_ACTION (action))); + + new_state = g_variant_new_string (g_variant_get_string (parameter, NULL)); + g_simple_action_set_state (action, new_state); +} + +static gboolean +compare_action_groups (GActionGroup *a, GActionGroup *b) +{ + gchar **alist; + gchar **blist; + gint i; + gboolean equal; + gboolean ares, bres; + gboolean aenabled, benabled; + const GVariantType *aparameter_type, *bparameter_type; + const GVariantType *astate_type, *bstate_type; + GVariant *astate_hint, *bstate_hint; + GVariant *astate, *bstate; + + alist = g_action_group_list_actions (a); + blist = g_action_group_list_actions (b); + equal = strv_strv_cmp ((const gchar * const *) alist, (const gchar * const *) blist); + + for (i = 0; equal && alist[i]; i++) + { + ares = g_action_group_query_action (a, alist[i], &aenabled, &aparameter_type, &astate_type, &astate_hint, &astate); + bres = g_action_group_query_action (b, alist[i], &benabled, &bparameter_type, &bstate_type, &bstate_hint, &bstate); + + if (ares && bres) + { + equal = equal && (aenabled == benabled); + equal = equal && ((!aparameter_type && !bparameter_type) || g_variant_type_equal (aparameter_type, bparameter_type)); + equal = equal && ((!astate_type && !bstate_type) || g_variant_type_equal (astate_type, bstate_type)); + equal = equal && ((!astate_hint && !bstate_hint) || g_variant_equal (astate_hint, bstate_hint)); + equal = equal && ((!astate && !bstate) || g_variant_equal (astate, bstate)); + + if (astate_hint) + g_variant_unref (astate_hint); + if (bstate_hint) + g_variant_unref (bstate_hint); + if (astate) + g_variant_unref (astate); + if (bstate) + g_variant_unref (bstate); + } + else + equal = FALSE; + } + + g_strfreev (alist); + g_strfreev (blist); + + return equal; +} + +static gboolean +stop_loop (gpointer data) +{ + GMainLoop *loop = data; + + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static GActionEntry exported_entries[] = { + { "undo", activate_action, NULL, NULL, NULL, { 0 } }, + { "redo", activate_action, NULL, NULL, NULL, { 0 } }, + { "cut", activate_action, NULL, NULL, NULL, { 0 } }, + { "copy", activate_action, NULL, NULL, NULL, { 0 } }, + { "paste", activate_action, NULL, NULL, NULL, { 0 } }, + { "bold", activate_toggle, NULL, "true", NULL, { 0 } }, + { "lang", activate_radio, "s", "'latin'", NULL, { 0 } }, +}; + +static void +list_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GDBusConnection *bus = G_DBUS_CONNECTION (source); + GMainLoop *loop = user_data; + GError *error = NULL; + GVariant *v; + gchar **actions; + + v = g_dbus_connection_call_finish (bus, res, &error); + g_assert_nonnull (v); + g_variant_get (v, "(^a&s)", &actions); + g_assert_cmpint (g_strv_length (actions), ==, G_N_ELEMENTS (exported_entries)); + g_free (actions); + g_variant_unref (v); + g_main_loop_quit (loop); +} + +static gboolean +call_list (gpointer user_data) +{ + GDBusConnection *bus; + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + g_dbus_connection_call (bus, + g_dbus_connection_get_unique_name (bus), + "/", + "org.gtk.Actions", + "List", + NULL, + NULL, + 0, + G_MAXINT, + NULL, + list_cb, + user_data); + g_object_unref (bus); + + return G_SOURCE_REMOVE; +} + +static void +describe_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GDBusConnection *bus = G_DBUS_CONNECTION (source); + GMainLoop *loop = user_data; + GError *error = NULL; + GVariant *v; + gboolean enabled; + gchar *param; + GVariantIter *iter; + + v = g_dbus_connection_call_finish (bus, res, &error); + g_assert_nonnull (v); + /* FIXME: there's an extra level of tuplelization in here */ + g_variant_get (v, "((bgav))", &enabled, ¶m, &iter); + g_assert_true (enabled); + g_assert_cmpstr (param, ==, ""); + g_assert_cmpint (g_variant_iter_n_children (iter), ==, 0); + g_free (param); + g_variant_iter_free (iter); + g_variant_unref (v); + + g_main_loop_quit (loop); +} + +static gboolean +call_describe (gpointer user_data) +{ + GDBusConnection *bus; + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + g_dbus_connection_call (bus, + g_dbus_connection_get_unique_name (bus), + "/", + "org.gtk.Actions", + "Describe", + g_variant_new ("(s)", "copy"), + NULL, + 0, + G_MAXINT, + NULL, + describe_cb, + user_data); + g_object_unref (bus); + + return G_SOURCE_REMOVE; +} + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +static void +action_added_removed_cb (GActionGroup *action_group, + char *action_name, + gpointer user_data) +{ + guint *counter = user_data; + + *counter = *counter + 1; + g_main_context_wakeup (NULL); +} + +static void +action_enabled_changed_cb (GActionGroup *action_group, + char *action_name, + gboolean enabled, + gpointer user_data) +{ + guint *counter = user_data; + + *counter = *counter + 1; + g_main_context_wakeup (NULL); +} + +static void +action_state_changed_cb (GActionGroup *action_group, + char *action_name, + GVariant *value, + gpointer user_data) +{ + guint *counter = user_data; + + *counter = *counter + 1; + g_main_context_wakeup (NULL); +} + +static void +test_dbus_export (void) +{ + GDBusConnection *bus; + GSimpleActionGroup *group; + GDBusActionGroup *proxy; + GSimpleAction *action; + GMainLoop *loop; + GError *error = NULL; + GVariant *v; + guint id; + gchar **actions; + guint n_actions_added = 0, n_actions_enabled_changed = 0, n_actions_removed = 0, n_actions_state_changed = 0; + gulong added_signal_id, enabled_changed_signal_id, removed_signal_id, state_changed_signal_id; + + loop = g_main_loop_new (NULL, FALSE); + + session_bus_up (); + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + group = g_simple_action_group_new (); + g_simple_action_group_add_entries (group, + exported_entries, + G_N_ELEMENTS (exported_entries), + NULL); + + id = g_dbus_connection_export_action_group (bus, "/", G_ACTION_GROUP (group), &error); + g_assert_no_error (error); + + proxy = g_dbus_action_group_get (bus, g_dbus_connection_get_unique_name (bus), "/"); + added_signal_id = g_signal_connect (proxy, "action-added", G_CALLBACK (action_added_removed_cb), &n_actions_added); + enabled_changed_signal_id = g_signal_connect (proxy, "action-enabled-changed", G_CALLBACK (action_enabled_changed_cb), &n_actions_enabled_changed); + removed_signal_id = g_signal_connect (proxy, "action-removed", G_CALLBACK (action_added_removed_cb), &n_actions_removed); + state_changed_signal_id = g_signal_connect (proxy, "action-state-changed", G_CALLBACK (action_state_changed_cb), &n_actions_state_changed); + + actions = g_action_group_list_actions (G_ACTION_GROUP (proxy)); + g_assert_cmpint (g_strv_length (actions), ==, 0); + g_strfreev (actions); + + /* Actions are queried from the bus asynchronously after the first + * list_actions() call. Wait for the expected signals then check again. */ + while (n_actions_added < G_N_ELEMENTS (exported_entries)) + g_main_context_iteration (NULL, TRUE); + + actions = g_action_group_list_actions (G_ACTION_GROUP (proxy)); + g_assert_cmpint (g_strv_length (actions), ==, G_N_ELEMENTS (exported_entries)); + g_strfreev (actions); + + /* check that calling "List" works too */ + g_idle_add (call_list, loop); + g_main_loop_run (loop); + + /* check that calling "Describe" works */ + g_idle_add (call_describe, loop); + g_main_loop_run (loop); + + /* test that the initial transfer works */ + g_assert_true (G_IS_DBUS_ACTION_GROUP (proxy)); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + + /* test that various changes get propagated from group to proxy */ + n_actions_added = 0; + action = g_simple_action_new_stateful ("italic", NULL, g_variant_new_boolean (FALSE)); + g_simple_action_group_insert (group, G_ACTION (action)); + g_object_unref (action); + + while (n_actions_added == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + + action = G_SIMPLE_ACTION (g_simple_action_group_lookup (group, "cut")); + g_simple_action_set_enabled (action, FALSE); + + while (n_actions_enabled_changed == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + + action = G_SIMPLE_ACTION (g_simple_action_group_lookup (group, "bold")); + g_simple_action_set_state (action, g_variant_new_boolean (FALSE)); + + while (n_actions_state_changed == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + + g_simple_action_group_remove (group, "italic"); + + while (n_actions_removed == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + + /* test that activations and state changes propagate the other way */ + n_actions_state_changed = 0; + g_assert_cmpint (activation_count ("copy"), ==, 0); + g_action_group_activate_action (G_ACTION_GROUP (proxy), "copy", NULL); + + while (activation_count ("copy") == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpint (activation_count ("copy"), ==, 1); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + + n_actions_state_changed = 0; + g_assert_cmpint (activation_count ("bold"), ==, 0); + g_action_group_activate_action (G_ACTION_GROUP (proxy), "bold", NULL); + + while (n_actions_state_changed == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpint (activation_count ("bold"), ==, 1); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + v = g_action_group_get_action_state (G_ACTION_GROUP (group), "bold"); + g_assert_true (g_variant_get_boolean (v)); + g_variant_unref (v); + + n_actions_state_changed = 0; + g_action_group_change_action_state (G_ACTION_GROUP (proxy), "bold", g_variant_new_boolean (FALSE)); + + while (n_actions_state_changed == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpint (activation_count ("bold"), ==, 1); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + v = g_action_group_get_action_state (G_ACTION_GROUP (group), "bold"); + g_assert_false (g_variant_get_boolean (v)); + g_variant_unref (v); + + g_dbus_connection_unexport_action_group (bus, id); + + g_signal_handler_disconnect (proxy, added_signal_id); + g_signal_handler_disconnect (proxy, enabled_changed_signal_id); + g_signal_handler_disconnect (proxy, removed_signal_id); + g_signal_handler_disconnect (proxy, state_changed_signal_id); + g_object_unref (proxy); + g_object_unref (group); + g_main_loop_unref (loop); + g_object_unref (bus); + + session_bus_down (); +} + +static gpointer +do_export (gpointer data) +{ + GActionGroup *group = data; + GMainContext *ctx; + gint i; + GError *error = NULL; + guint id; + GDBusConnection *bus; + GAction *action; + gchar *path; + + ctx = g_main_context_new (); + + g_main_context_push_thread_default (ctx); + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + path = g_strdup_printf("/%p", data); + + for (i = 0; i < 10000; i++) + { + id = g_dbus_connection_export_action_group (bus, path, G_ACTION_GROUP (group), &error); + g_assert_no_error (error); + + action = g_simple_action_group_lookup (G_SIMPLE_ACTION_GROUP (group), "a"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), + !g_action_get_enabled (action)); + + g_dbus_connection_unexport_action_group (bus, id); + + while (g_main_context_iteration (ctx, FALSE)); + } + + g_free (path); + g_object_unref (bus); + + g_main_context_pop_thread_default (ctx); + + g_main_context_unref (ctx); + + return NULL; +} + +static void +test_dbus_threaded (void) +{ + GSimpleActionGroup *group[10]; + GThread *export[10]; + static GActionEntry entries[] = { + { "a", activate_action, NULL, NULL, NULL, { 0 } }, + { "b", activate_action, NULL, NULL, NULL, { 0 } }, + }; + gint i; + + session_bus_up (); + + for (i = 0; i < 10; i++) + { + group[i] = g_simple_action_group_new (); + g_simple_action_group_add_entries (group[i], entries, G_N_ELEMENTS (entries), NULL); + export[i] = g_thread_new ("export", do_export, group[i]); + } + + for (i = 0; i < 10; i++) + g_thread_join (export[i]); + + for (i = 0; i < 10; i++) + g_object_unref (group[i]); + + session_bus_down (); +} + +G_GNUC_END_IGNORE_DEPRECATIONS + +static void +test_bug679509 (void) +{ + GDBusConnection *bus; + GDBusActionGroup *proxy; + GMainLoop *loop; + + loop = g_main_loop_new (NULL, FALSE); + + session_bus_up (); + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + proxy = g_dbus_action_group_get (bus, g_dbus_connection_get_unique_name (bus), "/"); + g_strfreev (g_action_group_list_actions (G_ACTION_GROUP (proxy))); + g_object_unref (proxy); + + g_timeout_add (100, stop_loop, loop); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + g_object_unref (bus); + + session_bus_down (); +} + +static gchar *state_change_log; + +static void +state_changed (GActionGroup *group, + const gchar *action_name, + GVariant *value, + gpointer user_data) +{ + GString *string; + + g_assert_false (state_change_log); + + string = g_string_new (action_name); + g_string_append_c (string, ':'); + g_variant_print_string (value, string, TRUE); + state_change_log = g_string_free (string, FALSE); +} + +static void +verify_changed (const gchar *log_entry) +{ + g_assert_cmpstr (state_change_log, ==, log_entry); + g_clear_pointer (&state_change_log, g_free); +} + +static void +ensure_state (GSimpleActionGroup *group, + const gchar *action_name, + const gchar *expected) +{ + GVariant *value; + gchar *printed; + + value = g_action_group_get_action_state (G_ACTION_GROUP (group), action_name); + printed = g_variant_print (value, TRUE); + g_variant_unref (value); + + g_assert_cmpstr (printed, ==, expected); + g_free (printed); +} + +static void +test_property_actions (void) +{ + GSimpleActionGroup *group; + GPropertyAction *action; + GSocketClient *client; + GApplication *app; + gchar *name; + GVariantType *ptype, *stype; + gboolean enabled; + GVariant *state; + + group = g_simple_action_group_new (); + g_signal_connect (group, "action-state-changed", G_CALLBACK (state_changed), NULL); + + client = g_socket_client_new (); + app = g_application_new ("org.gtk.test", 0); + + /* string... */ + action = g_property_action_new ("app-id", app, "application-id"); + g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); + g_object_unref (action); + + /* uint... */ + action = g_property_action_new ("keepalive", app, "inactivity-timeout"); + g_object_get (action, "name", &name, "parameter-type", &ptype, "enabled", &enabled, "state-type", &stype, "state", &state, NULL); + g_assert_cmpstr (name, ==, "keepalive"); + g_assert_true (enabled); + g_free (name); + g_variant_type_free (ptype); + g_variant_type_free (stype); + g_variant_unref (state); + + g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); + g_object_unref (action); + + /* bool... */ + action = g_property_action_new ("tls", client, "tls"); + g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); + g_object_unref (action); + + /* inverted */ + action = g_object_new (G_TYPE_PROPERTY_ACTION, + "name", "disable-proxy", + "object", client, + "property-name", "enable-proxy", + "invert-boolean", TRUE, + NULL); + g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); + g_object_unref (action); + + /* enum... */ + action = g_property_action_new ("type", client, "type"); + g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); + g_object_unref (action); + + /* the objects should be held alive by the actions... */ + g_object_unref (client); + g_object_unref (app); + + ensure_state (group, "app-id", "'org.gtk.test'"); + ensure_state (group, "keepalive", "uint32 0"); + ensure_state (group, "tls", "false"); + ensure_state (group, "disable-proxy", "false"); + ensure_state (group, "type", "'stream'"); + + verify_changed (NULL); + + /* some string tests... */ + g_action_group_change_action_state (G_ACTION_GROUP (group), "app-id", g_variant_new ("s", "org.gtk.test2")); + verify_changed ("app-id:'org.gtk.test2'"); + g_assert_cmpstr (g_application_get_application_id (app), ==, "org.gtk.test2"); + ensure_state (group, "app-id", "'org.gtk.test2'"); + + g_action_group_activate_action (G_ACTION_GROUP (group), "app-id", g_variant_new ("s", "org.gtk.test3")); + verify_changed ("app-id:'org.gtk.test3'"); + g_assert_cmpstr (g_application_get_application_id (app), ==, "org.gtk.test3"); + ensure_state (group, "app-id", "'org.gtk.test3'"); + + g_application_set_application_id (app, "org.gtk.test"); + verify_changed ("app-id:'org.gtk.test'"); + ensure_state (group, "app-id", "'org.gtk.test'"); + + /* uint tests */ + g_action_group_change_action_state (G_ACTION_GROUP (group), "keepalive", g_variant_new ("u", 1234)); + verify_changed ("keepalive:uint32 1234"); + g_assert_cmpuint (g_application_get_inactivity_timeout (app), ==, 1234); + ensure_state (group, "keepalive", "uint32 1234"); + + g_action_group_activate_action (G_ACTION_GROUP (group), "keepalive", g_variant_new ("u", 5678)); + verify_changed ("keepalive:uint32 5678"); + g_assert_cmpuint (g_application_get_inactivity_timeout (app), ==, 5678); + ensure_state (group, "keepalive", "uint32 5678"); + + g_application_set_inactivity_timeout (app, 0); + verify_changed ("keepalive:uint32 0"); + ensure_state (group, "keepalive", "uint32 0"); + + /* bool tests */ + g_action_group_change_action_state (G_ACTION_GROUP (group), "tls", g_variant_new ("b", TRUE)); + verify_changed ("tls:true"); + g_assert_true (g_socket_client_get_tls (client)); + ensure_state (group, "tls", "true"); + + g_action_group_change_action_state (G_ACTION_GROUP (group), "disable-proxy", g_variant_new ("b", TRUE)); + verify_changed ("disable-proxy:true"); + ensure_state (group, "disable-proxy", "true"); + g_assert_false (g_socket_client_get_enable_proxy (client)); + + /* test toggle true->false */ + g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL); + verify_changed ("tls:false"); + g_assert_false (g_socket_client_get_tls (client)); + ensure_state (group, "tls", "false"); + + /* and now back false->true */ + g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL); + verify_changed ("tls:true"); + g_assert_true (g_socket_client_get_tls (client)); + ensure_state (group, "tls", "true"); + + g_socket_client_set_tls (client, FALSE); + verify_changed ("tls:false"); + ensure_state (group, "tls", "false"); + + /* now do the same for the inverted action */ + g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL); + verify_changed ("disable-proxy:false"); + g_assert_true (g_socket_client_get_enable_proxy (client)); + ensure_state (group, "disable-proxy", "false"); + + g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL); + verify_changed ("disable-proxy:true"); + g_assert_false (g_socket_client_get_enable_proxy (client)); + ensure_state (group, "disable-proxy", "true"); + + g_socket_client_set_enable_proxy (client, TRUE); + verify_changed ("disable-proxy:false"); + ensure_state (group, "disable-proxy", "false"); + + /* enum tests */ + g_action_group_change_action_state (G_ACTION_GROUP (group), "type", g_variant_new ("s", "datagram")); + verify_changed ("type:'datagram'"); + g_assert_cmpint (g_socket_client_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM); + ensure_state (group, "type", "'datagram'"); + + g_action_group_activate_action (G_ACTION_GROUP (group), "type", g_variant_new ("s", "stream")); + verify_changed ("type:'stream'"); + g_assert_cmpint (g_socket_client_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM); + ensure_state (group, "type", "'stream'"); + + g_socket_client_set_socket_type (client, G_SOCKET_TYPE_SEQPACKET); + verify_changed ("type:'seqpacket'"); + ensure_state (group, "type", "'seqpacket'"); + + /* Check some error cases... */ + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*non-existent*"); + action = g_property_action_new ("foo", app, "xyz"); + g_test_assert_expected_messages (); + g_object_unref (action); + + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*writable*"); + action = g_property_action_new ("foo", app, "is-registered"); + g_test_assert_expected_messages (); + g_object_unref (action); + + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*type 'GSocketAddress'*"); + action = g_property_action_new ("foo", client, "local-address"); + g_test_assert_expected_messages (); + g_object_unref (action); + + g_object_unref (group); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/actions/basic", test_basic); + g_test_add_func ("/actions/name", test_name); + g_test_add_func ("/actions/simplegroup", test_simple_group); + g_test_add_func ("/actions/stateful", test_stateful); + g_test_add_func ("/actions/default-activate", test_default_activate); + g_test_add_func ("/actions/entries", test_entries); + g_test_add_func ("/actions/parse-detailed", test_parse_detailed); + g_test_add_func ("/actions/dbus/export", test_dbus_export); + g_test_add_func ("/actions/dbus/threaded", test_dbus_threaded); + g_test_add_func ("/actions/dbus/bug679509", test_bug679509); + g_test_add_func ("/actions/property", test_property_actions); + + return g_test_run (); +} diff --git a/gio/tests/appinfo-test-actions.desktop b/gio/tests/appinfo-test-actions.desktop new file mode 100644 index 0000000..86e3bcf --- /dev/null +++ b/gio/tests/appinfo-test-actions.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +Type=Application +Actions=frob;tweak;twiddle;broken; +Exec=true + +[Desktop Action frob] +Name=Frobnicate +Exec=touch frob + +[Desktop Action tweak] +Name=Tweak +Exec=touch tweak + +[Desktop Action twiddle] +Name=Twiddle +Exec=touch twiddle diff --git a/gio/tests/appinfo-test-gnome.desktop.in b/gio/tests/appinfo-test-gnome.desktop.in new file mode 100644 index 0000000..e32d545 --- /dev/null +++ b/gio/tests/appinfo-test-gnome.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Application +Name=appinfo-test +Exec=@installed_tests_dir@/appinfo-test --option +OnlyShowIn=GNOME;KDE; +NotShowIn=ROX; diff --git a/gio/tests/appinfo-test-notgnome.desktop.in b/gio/tests/appinfo-test-notgnome.desktop.in new file mode 100644 index 0000000..5858182 --- /dev/null +++ b/gio/tests/appinfo-test-notgnome.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Application +Name=appinfo-test +Exec=@installed_tests_dir@/appinfo-test --option +OnlyShowIn=KDE; +NotShowIn=GNOME; diff --git a/gio/tests/appinfo-test-static.desktop b/gio/tests/appinfo-test-static.desktop new file mode 100644 index 0000000..f8a09f6 --- /dev/null +++ b/gio/tests/appinfo-test-static.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] +Type=Application +GenericName=generic-appinfo-test +Name=appinfo-test +Name[de]=appinfo-test-de +X-GNOME-FullName=example +X-GNOME-FullName[de]=Beispiel +Comment=GAppInfo example +Comment[de]=GAppInfo Beispiel +Exec=true --option %U %i --name %c --filename %k %m %% +Icon=testicon.svg +Terminal=true +StartupNotify=true +StartupWMClass=appinfo-class +MimeType=image/png;image/jpeg; +Keywords=keyword1;test keyword; +Categories=GNOME;GTK; +X-JunkFood=Burger +X-JunkFood[de]=Bratwurst \ No newline at end of file diff --git a/gio/tests/appinfo-test.c b/gio/tests/appinfo-test.c new file mode 100644 index 0000000..1b64a8f --- /dev/null +++ b/gio/tests/appinfo-test.c @@ -0,0 +1,28 @@ +#include +#include + +int +main (int argc, char *argv[]) +{ + const gchar *envvar; + + g_test_init (&argc, &argv, NULL); + + envvar = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE"); + if (envvar != NULL) + { + gchar *expected; + gint pid_from_env; + + expected = g_test_build_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL); + g_assert_cmpstr (envvar, ==, expected); + g_free (expected); + + envvar = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE_PID"); + g_assert (envvar != NULL); + pid_from_env = atoi (envvar); + g_assert_cmpint (pid_from_env, ==, getpid ()); + } + + return 0; +} diff --git a/gio/tests/appinfo-test.desktop.in b/gio/tests/appinfo-test.desktop.in new file mode 100644 index 0000000..1f6ff71 --- /dev/null +++ b/gio/tests/appinfo-test.desktop.in @@ -0,0 +1,19 @@ +[Desktop Entry] +Type=Application +GenericName=generic-appinfo-test +Name=appinfo-test +Name[de]=appinfo-test-de +X-GNOME-FullName=example +X-GNOME-FullName[de]=Beispiel +Comment=GAppInfo example +Comment[de]=GAppInfo Beispiel +Exec=@installed_tests_dir@/appinfo-test --option %U %i --name %c --filename %k %m %% +Icon=testicon.svg +Terminal=false +StartupNotify=true +StartupWMClass=appinfo-class +MimeType=image/png;image/jpeg; +Keywords=keyword1;test keyword; +Categories=GNOME;GTK; +X-JunkFood=Burger +X-JunkFood[de]=Bratwurst diff --git a/gio/tests/appinfo-test2.desktop.in b/gio/tests/appinfo-test2.desktop.in new file mode 100644 index 0000000..70780f8 --- /dev/null +++ b/gio/tests/appinfo-test2.desktop.in @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Name=appinfo-test +Name[de]=appinfo-test-de +X-GNOME-FullName=example +X-GNOME-FullName[de]=Beispiel +Comment=GAppInfo example +Comment[de]=GAppInfo Beispiel +Exec=@installed_tests_dir@/appinfo-test --option +TryExec=does-not-exist +Icon=testicon diff --git a/gio/tests/appinfo.c b/gio/tests/appinfo.c new file mode 100644 index 0000000..bd76729 --- /dev/null +++ b/gio/tests/appinfo.c @@ -0,0 +1,601 @@ + +#include +#include + +#include +#include +#include + +static void +test_launch_for_app_info (GAppInfo *appinfo) +{ + GError *error = NULL; + gboolean success; + GFile *file; + GList *l; + const gchar *path; + gchar *uri; + + if (g_getenv ("DISPLAY") == NULL || g_getenv ("DISPLAY")[0] == '\0') + { + g_test_skip ("No DISPLAY set"); + return; + } + + success = g_app_info_launch (appinfo, NULL, NULL, &error); + g_assert_no_error (error); + g_assert_true (success); + + success = g_app_info_launch_uris (appinfo, NULL, NULL, &error); + g_assert_no_error (error); + g_assert_true (success); + + path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL); + file = g_file_new_for_path (path); + l = NULL; + l = g_list_append (l, file); + + success = g_app_info_launch (appinfo, l, NULL, &error); + g_assert_no_error (error); + g_assert_true (success); + g_list_free (l); + g_object_unref (file); + + l = NULL; + uri = g_strconcat ("file://", g_test_get_dir (G_TEST_BUILT), "/appinfo-test.desktop", NULL); + l = g_list_append (l, uri); + l = g_list_append (l, "file:///etc/group#adm"); + + success = g_app_info_launch_uris (appinfo, l, NULL, &error); + g_assert_no_error (error); + g_assert_true (success); + + g_list_free (l); + g_free (uri); +} + +static void +test_launch (void) +{ + GAppInfo *appinfo; + const gchar *path; + + path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL); + appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path); + + if (appinfo == NULL) + { + g_test_skip ("appinfo-test binary not installed"); + return; + } + + test_launch_for_app_info (appinfo); + g_object_unref (appinfo); +} + +static void +test_launch_no_app_id (void) +{ + const gchar desktop_file_base_contents[] = + "[Desktop Entry]\n" + "Type=Application\n" + "GenericName=generic-appinfo-test\n" + "Name=appinfo-test\n" + "Name[de]=appinfo-test-de\n" + "X-GNOME-FullName=example\n" + "X-GNOME-FullName[de]=Beispiel\n" + "Comment=GAppInfo example\n" + "Comment[de]=GAppInfo Beispiel\n" + "Icon=testicon.svg\n" + "Terminal=false\n" + "StartupNotify=true\n" + "StartupWMClass=appinfo-class\n" + "MimeType=image/png;image/jpeg;\n" + "Keywords=keyword1;test keyword;\n" + "Categories=GNOME;GTK;\n"; + + gchar *exec_line_variants[2]; + gsize i; + + exec_line_variants[0] = g_strdup_printf ( + "Exec=%s/appinfo-test --option %%U %%i --name %%c --filename %%k %%m %%%%", + g_test_get_dir (G_TEST_BUILT)); + exec_line_variants[1] = g_strdup_printf ( + "Exec=%s/appinfo-test --option %%u %%i --name %%c --filename %%k %%m %%%%", + g_test_get_dir (G_TEST_BUILT)); + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=791337"); + + for (i = 0; i < G_N_ELEMENTS (exec_line_variants); i++) + { + gchar *desktop_file_contents; + GKeyFile *fake_desktop_file; + GAppInfo *appinfo; + gboolean loaded; + + g_test_message ("Exec line variant #%" G_GSIZE_FORMAT, i); + + desktop_file_contents = g_strdup_printf ("%s\n%s", + desktop_file_base_contents, + exec_line_variants[i]); + + /* We load a desktop file from memory to force the app not + * to have an app ID, which would check different codepaths. + */ + fake_desktop_file = g_key_file_new (); + loaded = g_key_file_load_from_data (fake_desktop_file, desktop_file_contents, -1, G_KEY_FILE_NONE, NULL); + g_assert_true (loaded); + + appinfo = (GAppInfo*)g_desktop_app_info_new_from_keyfile (fake_desktop_file); + g_assert_nonnull (appinfo); + + test_launch_for_app_info (appinfo); + + g_free (desktop_file_contents); + g_object_unref (appinfo); + g_key_file_unref (fake_desktop_file); + } + + g_free (exec_line_variants[1]); + g_free (exec_line_variants[0]); +} + +static void +test_locale (const char *locale) +{ + GAppInfo *appinfo; + gchar *orig = NULL; + const gchar *path; + + orig = g_strdup (setlocale (LC_ALL, NULL)); + g_setenv ("LANGUAGE", locale, TRUE); + setlocale (LC_ALL, ""); + + path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL); + appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path); + + if (g_strcmp0 (locale, "C") == 0) + { + g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test"); + g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo example"); + g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "example"); + } + else if (g_str_has_prefix (locale, "en")) + { + g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test"); + g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo example"); + g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "example"); + } + else if (g_str_has_prefix (locale, "de")) + { + g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test-de"); + g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo Beispiel"); + g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "Beispiel"); + } + + g_object_unref (appinfo); + + g_setenv ("LANGUAGE", orig, TRUE); + setlocale (LC_ALL, ""); + g_free (orig); +} + +static void +test_text (void) +{ + test_locale ("C"); + test_locale ("en_US"); + test_locale ("de"); + test_locale ("de_DE.UTF-8"); +} + +static void +test_basic (void) +{ + GAppInfo *appinfo; + GAppInfo *appinfo2; + GIcon *icon, *icon2; + const gchar *path; + + path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL); + appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path); + g_assert_nonnull (appinfo); + + g_assert_cmpstr (g_app_info_get_id (appinfo), ==, "appinfo-test-static.desktop"); + g_assert_nonnull (strstr (g_app_info_get_executable (appinfo), "true")); + + icon = g_app_info_get_icon (appinfo); + g_assert_true (G_IS_THEMED_ICON (icon)); + icon2 = g_themed_icon_new ("testicon"); + g_assert_true (g_icon_equal (icon, icon2)); + g_object_unref (icon2); + + appinfo2 = g_app_info_dup (appinfo); + g_assert_cmpstr (g_app_info_get_id (appinfo), ==, g_app_info_get_id (appinfo2)); + g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2)); + + g_object_unref (appinfo); + g_object_unref (appinfo2); +} + +static void +test_show_in (void) +{ + GAppInfo *appinfo; + const gchar *path; + + path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL); + appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path); + + if (appinfo == NULL) + { + g_test_skip ("appinfo-test binary not installed"); + return; + } + + g_assert_true (g_app_info_should_show (appinfo)); + g_object_unref (appinfo); + + path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-gnome.desktop", NULL); + appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path); + g_assert_true (g_app_info_should_show (appinfo)); + g_object_unref (appinfo); + + path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-notgnome.desktop", NULL); + appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path); + g_assert_false (g_app_info_should_show (appinfo)); + g_object_unref (appinfo); +} + +static void +test_commandline (void) +{ + GAppInfo *appinfo; + GError *error; + gchar *cmdline; + gchar *cmdline_out; + + cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL); + cmdline_out = g_strconcat (cmdline, " %u", NULL); + + error = NULL; + appinfo = g_app_info_create_from_commandline (cmdline, + "cmdline-app-test", + G_APP_INFO_CREATE_SUPPORTS_URIS, + &error); + g_assert_no_error (error); + g_assert_nonnull (appinfo); + g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "cmdline-app-test"); + g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, cmdline_out); + g_assert_true (g_app_info_supports_uris (appinfo)); + g_assert_false (g_app_info_supports_files (appinfo)); + + g_object_unref (appinfo); + + g_free (cmdline_out); + cmdline_out = g_strconcat (cmdline, " %f", NULL); + + error = NULL; + appinfo = g_app_info_create_from_commandline (cmdline, + "cmdline-app-test", + G_APP_INFO_CREATE_NONE, + &error); + g_assert_no_error (error); + g_assert_nonnull (appinfo); + g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "cmdline-app-test"); + g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, cmdline_out); + g_assert_false (g_app_info_supports_uris (appinfo)); + g_assert_true (g_app_info_supports_files (appinfo)); + + g_object_unref (appinfo); + + g_free (cmdline); + g_free (cmdline_out); +} + +static void +test_launch_context (void) +{ + GAppLaunchContext *context; + GAppInfo *appinfo; + gchar *str; + gchar *cmdline; + + cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL); + + context = g_app_launch_context_new (); + appinfo = g_app_info_create_from_commandline (cmdline, + "cmdline-app-test", + G_APP_INFO_CREATE_SUPPORTS_URIS, + NULL); + + str = g_app_launch_context_get_display (context, appinfo, NULL); + g_assert_null (str); + + str = g_app_launch_context_get_startup_notify_id (context, appinfo, NULL); + g_assert_null (str); + + g_object_unref (appinfo); + g_object_unref (context); + + g_free (cmdline); +} + +static gboolean launched_reached; + +static void +launched (GAppLaunchContext *context, + GAppInfo *info, + GVariant *platform_data, + gpointer user_data) +{ + gint pid; + + pid = 0; + g_assert_true (g_variant_lookup (platform_data, "pid", "i", &pid)); + g_assert_cmpint (pid, !=, 0); + + launched_reached = TRUE; +} + +static void +launch_failed (GAppLaunchContext *context, + const gchar *startup_notify_id) +{ + g_assert_not_reached (); +} + +static void +test_launch_context_signals (void) +{ + GAppLaunchContext *context; + GAppInfo *appinfo; + GError *error = NULL; + gboolean success; + gchar *cmdline; + + cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL); + + context = g_app_launch_context_new (); + g_signal_connect (context, "launched", G_CALLBACK (launched), NULL); + g_signal_connect (context, "launch_failed", G_CALLBACK (launch_failed), NULL); + appinfo = g_app_info_create_from_commandline (cmdline, + "cmdline-app-test", + G_APP_INFO_CREATE_SUPPORTS_URIS, + NULL); + + success = g_app_info_launch (appinfo, NULL, context, &error); + g_assert_no_error (error); + g_assert_true (success); + + g_assert_true (launched_reached); + + g_object_unref (appinfo); + g_object_unref (context); + + g_free (cmdline); +} + +static void +test_tryexec (void) +{ + GAppInfo *appinfo; + const gchar *path; + + path = g_test_get_filename (G_TEST_BUILT, "appinfo-test2.desktop", NULL); + appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path); + + g_assert_null (appinfo); +} + +/* Test that we can set an appinfo as default for a mime type or + * file extension, and also add and remove handled mime types. + */ +static void +test_associations (void) +{ + GAppInfo *appinfo; + GAppInfo *appinfo2; + GError *error = NULL; + gboolean result; + GList *list; + gchar *cmdline; + + cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL); + appinfo = g_app_info_create_from_commandline (cmdline, + "cmdline-app-test", + G_APP_INFO_CREATE_SUPPORTS_URIS, + NULL); + g_free (cmdline); + + result = g_app_info_set_as_default_for_type (appinfo, "application/x-glib-test", &error); + g_assert_no_error (error); + g_assert_true (result); + + appinfo2 = g_app_info_get_default_for_type ("application/x-glib-test", FALSE); + + g_assert_nonnull (appinfo2); + g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2)); + + g_object_unref (appinfo2); + + result = g_app_info_set_as_default_for_extension (appinfo, "gio-tests", &error); + g_assert_no_error (error); + g_assert_true (result); + + appinfo2 = g_app_info_get_default_for_type ("application/x-extension-gio-tests", FALSE); + + g_assert_nonnull (appinfo2); + g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2)); + + g_object_unref (appinfo2); + + result = g_app_info_add_supports_type (appinfo, "application/x-gio-test", &error); + g_assert_no_error (error); + g_assert_true (result); + + list = g_app_info_get_all_for_type ("application/x-gio-test"); + g_assert_cmpint (g_list_length (list), ==, 1); + appinfo2 = list->data; + g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2)); + g_object_unref (appinfo2); + g_list_free (list); + + g_assert_true (g_app_info_can_remove_supports_type (appinfo)); + result = g_app_info_remove_supports_type (appinfo, "application/x-gio-test", &error); + g_assert_no_error (error); + g_assert_true (result); + + g_assert_true (g_app_info_can_delete (appinfo)); + g_assert_true (g_app_info_delete (appinfo)); + g_object_unref (appinfo); +} + +static void +test_environment (void) +{ + GAppLaunchContext *ctx; + gchar **env; + const gchar *path; + + g_unsetenv ("FOO"); + g_unsetenv ("BLA"); + path = g_getenv ("PATH"); + + ctx = g_app_launch_context_new (); + + env = g_app_launch_context_get_environment (ctx); + + g_assert_null (g_environ_getenv (env, "FOO")); + g_assert_null (g_environ_getenv (env, "BLA")); + g_assert_cmpstr (g_environ_getenv (env, "PATH"), ==, path); + + g_strfreev (env); + + g_app_launch_context_setenv (ctx, "FOO", "bar"); + g_app_launch_context_setenv (ctx, "BLA", "bla"); + + env = g_app_launch_context_get_environment (ctx); + + g_assert_cmpstr (g_environ_getenv (env, "FOO"), ==, "bar"); + g_assert_cmpstr (g_environ_getenv (env, "BLA"), ==, "bla"); + g_assert_cmpstr (g_environ_getenv (env, "PATH"), ==, path); + + g_strfreev (env); + + g_app_launch_context_setenv (ctx, "FOO", "baz"); + g_app_launch_context_unsetenv (ctx, "BLA"); + + env = g_app_launch_context_get_environment (ctx); + + g_assert_cmpstr (g_environ_getenv (env, "FOO"), ==, "baz"); + g_assert_null (g_environ_getenv (env, "BLA")); + + g_strfreev (env); + + g_object_unref (ctx); +} + +static void +test_startup_wm_class (void) +{ + GDesktopAppInfo *appinfo; + const char *wm_class; + const gchar *path; + + path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL); + appinfo = g_desktop_app_info_new_from_filename (path); + wm_class = g_desktop_app_info_get_startup_wm_class (appinfo); + + g_assert_cmpstr (wm_class, ==, "appinfo-class"); + + g_object_unref (appinfo); +} + +static void +test_supported_types (void) +{ + GAppInfo *appinfo; + const char * const *content_types; + const gchar *path; + + path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL); + appinfo = G_APP_INFO (g_desktop_app_info_new_from_filename (path)); + content_types = g_app_info_get_supported_types (appinfo); + + g_assert_cmpint (g_strv_length ((char**)content_types), ==, 2); + g_assert_cmpstr (content_types[0], ==, "image/png"); + + g_object_unref (appinfo); +} + +static void +test_from_keyfile (void) +{ + GDesktopAppInfo *info; + GKeyFile *kf; + GError *error = NULL; + const gchar *categories; + gchar **categories_list; + gsize categories_count; + gchar **keywords; + const gchar *file; + const gchar *name; + const gchar *path; + + path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL); + kf = g_key_file_new (); + g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + info = g_desktop_app_info_new_from_keyfile (kf); + g_key_file_unref (kf); + g_assert_nonnull (info); + + g_object_get (info, "filename", &file, NULL); + g_assert_null (file); + + file = g_desktop_app_info_get_filename (info); + g_assert_null (file); + categories = g_desktop_app_info_get_categories (info); + g_assert_cmpstr (categories, ==, "GNOME;GTK;"); + categories_list = g_desktop_app_info_get_string_list (info, "Categories", &categories_count); + g_assert_cmpint (categories_count, ==, 2); + g_assert_cmpint (g_strv_length (categories_list), ==, 2); + g_assert_cmpstr (categories_list[0], ==, "GNOME"); + g_assert_cmpstr (categories_list[1], ==, "GTK"); + keywords = (gchar **)g_desktop_app_info_get_keywords (info); + g_assert_cmpint (g_strv_length (keywords), ==, 2); + g_assert_cmpstr (keywords[0], ==, "keyword1"); + g_assert_cmpstr (keywords[1], ==, "test keyword"); + name = g_desktop_app_info_get_generic_name (info); + g_assert_cmpstr (name, ==, "generic-appinfo-test"); + g_assert_false (g_desktop_app_info_get_nodisplay (info)); + + g_strfreev (categories_list); + g_object_unref (info); +} + +int +main (int argc, char *argv[]) +{ + g_setenv ("XDG_CURRENT_DESKTOP", "GNOME", TRUE); + + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add_func ("/appinfo/basic", test_basic); + g_test_add_func ("/appinfo/text", test_text); + g_test_add_func ("/appinfo/launch", test_launch); + g_test_add_func ("/appinfo/launch/no-appid", test_launch_no_app_id); + g_test_add_func ("/appinfo/show-in", test_show_in); + g_test_add_func ("/appinfo/commandline", test_commandline); + g_test_add_func ("/appinfo/launch-context", test_launch_context); + g_test_add_func ("/appinfo/launch-context-signals", test_launch_context_signals); + g_test_add_func ("/appinfo/tryexec", test_tryexec); + g_test_add_func ("/appinfo/associations", test_associations); + g_test_add_func ("/appinfo/environment", test_environment); + g_test_add_func ("/appinfo/startup-wm-class", test_startup_wm_class); + g_test_add_func ("/appinfo/supported-types", test_supported_types); + g_test_add_func ("/appinfo/from-keyfile", test_from_keyfile); + + return g_test_run (); +} diff --git a/gio/tests/appmonitor.c b/gio/tests/appmonitor.c new file mode 100644 index 0000000..9db8c4d --- /dev/null +++ b/gio/tests/appmonitor.c @@ -0,0 +1,130 @@ +#include +#include + +typedef struct +{ + gchar *applications_dir; +} Fixture; + +static void +setup (Fixture *fixture, + gconstpointer user_data) +{ + fixture->applications_dir = g_build_filename (g_get_user_data_dir (), "applications", NULL); + g_assert_no_errno (g_mkdir_with_parents (fixture->applications_dir, 0755)); + + g_test_message ("Using data directory: %s", g_get_user_data_dir ()); +} + +static void +teardown (Fixture *fixture, + gconstpointer user_data) +{ + g_assert_no_errno (g_rmdir (fixture->applications_dir)); + g_clear_pointer (&fixture->applications_dir, g_free); +} + +static gboolean +create_app (gpointer data) +{ + const gchar *path = data; + GError *error = NULL; + const gchar *contents = + "[Desktop Entry]\n" + "Name=Application\n" + "Version=1.0\n" + "Type=Application\n" + "Exec=true\n"; + + g_file_set_contents (path, contents, -1, &error); + g_assert_no_error (error); + + return G_SOURCE_REMOVE; +} + +static void +delete_app (gpointer data) +{ + const gchar *path = data; + + g_remove (path); +} + +static gboolean changed_fired; + +static void +changed_cb (GAppInfoMonitor *monitor, GMainLoop *loop) +{ + changed_fired = TRUE; + g_main_loop_quit (loop); +} + +static gboolean +quit_loop (gpointer data) +{ + GMainLoop *loop = data; + + if (g_main_loop_is_running (loop)) + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static void +test_app_monitor (Fixture *fixture, + gconstpointer user_data) +{ + gchar *app_path; + GAppInfoMonitor *monitor; + GMainLoop *loop; + +#ifdef G_OS_WIN32 + g_test_skip (".desktop monitor on win32"); + return; +#endif + + app_path = g_build_filename (fixture->applications_dir, "app.desktop", NULL); + + /* FIXME: this shouldn't be required */ + g_list_free_full (g_app_info_get_all (), g_object_unref); + + monitor = g_app_info_monitor_get (); + loop = g_main_loop_new (NULL, FALSE); + + g_signal_connect (monitor, "changed", G_CALLBACK (changed_cb), loop); + + g_idle_add (create_app, app_path); + g_timeout_add_seconds (3, quit_loop, loop); + + g_main_loop_run (loop); + g_assert (changed_fired); + changed_fired = FALSE; + + /* FIXME: this shouldn't be required */ + g_list_free_full (g_app_info_get_all (), g_object_unref); + + g_timeout_add_seconds (3, quit_loop, loop); + + delete_app (app_path); + + g_main_loop_run (loop); + + g_assert (changed_fired); + + g_main_loop_unref (loop); + g_remove (app_path); + + g_object_unref (monitor); + + g_free (app_path); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add ("/monitor/app", Fixture, NULL, setup, test_app_monitor, teardown); + + return g_test_run (); +} diff --git a/gio/tests/apps.c b/gio/tests/apps.c new file mode 100644 index 0000000..191edd4 --- /dev/null +++ b/gio/tests/apps.c @@ -0,0 +1,147 @@ +#include +#include +#include +#include + +static void +print (const gchar *str) +{ + g_print ("%s\n", str ? str : "nil"); +} + +static void +print_app_list (GList *list) +{ + while (list) + { + GAppInfo *info = list->data; + print (g_app_info_get_id (info)); + list = g_list_delete_link (list, list); + g_object_unref (info); + } +} + +static void +quit (gpointer user_data) +{ + g_print ("appinfo database changed.\n"); + exit (0); +} + +int +main (int argc, char **argv) +{ + setlocale (LC_ALL, ""); + + if (argv[1] == NULL) + ; + else if (g_str_equal (argv[1], "list")) + { + GList *all, *i; + + all = g_app_info_get_all (); + for (i = all; i; i = i->next) + g_print ("%s%s", g_app_info_get_id (i->data), i->next ? " " : "\n"); + g_list_free_full (all, g_object_unref); + } + else if (g_str_equal (argv[1], "search")) + { + gchar ***results; + gint i, j; + + results = g_desktop_app_info_search (argv[2]); + for (i = 0; results[i]; i++) + { + for (j = 0; results[i][j]; j++) + g_print ("%s%s", j ? " " : "", results[i][j]); + g_print ("\n"); + g_strfreev (results[i]); + } + g_free (results); + } + else if (g_str_equal (argv[1], "implementations")) + { + GList *results; + + results = g_desktop_app_info_get_implementations (argv[2]); + print_app_list (results); + } + else if (g_str_equal (argv[1], "show-info")) + { + GAppInfo *info; + + info = (GAppInfo *) g_desktop_app_info_new (argv[2]); + if (info) + { + print (g_app_info_get_id (info)); + print (g_app_info_get_name (info)); + print (g_app_info_get_display_name (info)); + print (g_app_info_get_description (info)); + g_object_unref (info); + } + } + else if (g_str_equal (argv[1], "default-for-type")) + { + GAppInfo *info; + + info = g_app_info_get_default_for_type (argv[2], FALSE); + + if (info) + { + print (g_app_info_get_id (info)); + g_object_unref (info); + } + } + else if (g_str_equal (argv[1], "recommended-for-type")) + { + GList *list; + + list = g_app_info_get_recommended_for_type (argv[2]); + print_app_list (list); + } + else if (g_str_equal (argv[1], "all-for-type")) + { + GList *list; + + list = g_app_info_get_all_for_type (argv[2]); + print_app_list (list); + } + + else if (g_str_equal (argv[1], "fallback-for-type")) + { + GList *list; + + list = g_app_info_get_fallback_for_type (argv[2]); + print_app_list (list); + } + + else if (g_str_equal (argv[1], "should-show")) + { + GAppInfo *info; + + info = (GAppInfo *) g_desktop_app_info_new (argv[2]); + if (info) + { + g_print ("%s\n", g_app_info_should_show (info) ? "true" : "false"); + g_object_unref (info); + } + } + + else if (g_str_equal (argv[1], "monitor")) + { + GAppInfoMonitor *monitor; + GAppInfo *info; + + monitor = g_app_info_monitor_get (); + + info = (GAppInfo *) g_desktop_app_info_new ("this-desktop-file-does-not-exist"); + g_assert (!info); + + g_signal_connect (monitor, "changed", G_CALLBACK (quit), NULL); + + while (1) + g_main_context_iteration (NULL, TRUE); + } + + return 0; +} diff --git a/gio/tests/async-close-output-stream.c b/gio/tests/async-close-output-stream.c new file mode 100644 index 0000000..a14c413 --- /dev/null +++ b/gio/tests/async-close-output-stream.c @@ -0,0 +1,276 @@ +/* GLib testing framework examples and tests + * Authors: Jesse van den Kieboom + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +#define DATA_TO_WRITE "Hello world\n" + +typedef struct +{ + GOutputStream *conv_stream; + GOutputStream *data_stream; + gchar *expected_output; + gsize expected_size; + GMainLoop *main_loop; +} SetupData; + +static void +create_streams (SetupData *data) +{ + GConverter *converter; + + converter = G_CONVERTER (g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1)); + + data->data_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + data->conv_stream = g_converter_output_stream_new (data->data_stream, + converter); + + g_object_unref (converter); +} + +static void +destroy_streams (SetupData *data) +{ + g_object_unref (data->data_stream); + g_object_unref (data->conv_stream); +} + +static void +write_data_to_stream (SetupData *data) +{ + gsize bytes_written; + GError *error = NULL; + + /* just write the data synchronously */ + g_output_stream_write_all (data->conv_stream, + DATA_TO_WRITE, + sizeof (DATA_TO_WRITE), + &bytes_written, + NULL, + &error); + + g_assert_no_error (error); + g_assert_cmpint (sizeof (DATA_TO_WRITE), ==, bytes_written); +} + +static void +setup_data (SetupData *data, + gconstpointer user_data) +{ + data->main_loop = g_main_loop_new (NULL, FALSE); + create_streams (data); +} + +static void +teardown_data (SetupData *data, + gconstpointer user_data) +{ + /* cleanup */ + g_main_loop_unref (data->main_loop); + + destroy_streams (data); + + g_free (data->expected_output); +} + +static void +compare_output (SetupData *data) +{ + gsize size; + gpointer written; + + written = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->data_stream)); + size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream)); + + g_assert_cmpmem (written, size, data->expected_output, data->expected_size); +} + +static void +async_close_ready (GOutputStream *stream, + GAsyncResult *result, + SetupData *data) +{ + GError *error = NULL; + + /* finish the close */ + g_output_stream_close_finish (stream, result, &error); + + g_assert_no_error (error); + + /* compare the output with the desired output */ + compare_output (data); + + g_main_loop_quit (data->main_loop); +} + +static void +prepare_data (SetupData *data, + gboolean manual_flush) +{ + GError *error = NULL; + gpointer written; + + write_data_to_stream (data); + + if (manual_flush) + { + g_output_stream_flush (data->conv_stream, NULL, &error); + g_assert_no_error (error); + } + + g_output_stream_close (data->conv_stream, NULL, &error); + + g_assert_no_error (error); + + written = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->data_stream)); + + data->expected_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream)); + + g_assert_cmpuint (data->expected_size, >, 0); + + data->expected_output = g_memdup2 (written, data->expected_size); + + /* then recreate the streams and prepare them for the asynchronous close */ + destroy_streams (data); + create_streams (data); + + write_data_to_stream (data); +} + +static void +test_without_flush (SetupData *data, + gconstpointer user_data) +{ + prepare_data (data, FALSE); + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937"); + + /* just close asynchronously */ + g_output_stream_close_async (data->conv_stream, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback)async_close_ready, + data); + + g_main_loop_run (data->main_loop); +} + +static void +test_with_flush (SetupData *data, gconstpointer user_data) +{ + GError *error = NULL; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937"); + + prepare_data (data, TRUE); + + g_output_stream_flush (data->conv_stream, NULL, &error); + + g_assert_no_error (error); + + /* then close asynchronously */ + g_output_stream_close_async (data->conv_stream, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback)async_close_ready, + data); + + g_main_loop_run (data->main_loop); +} + +static void +async_flush_ready (GOutputStream *stream, + GAsyncResult *result, + SetupData *data) +{ + GError *error = NULL; + + g_output_stream_flush_finish (stream, result, &error); + + g_assert_no_error (error); + + /* then close async after the flush */ + g_output_stream_close_async (data->conv_stream, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback)async_close_ready, + data); +} + +static void +test_with_async_flush (SetupData *data, + gconstpointer user_data) +{ + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937"); + + prepare_data (data, TRUE); + + /* first flush async */ + g_output_stream_flush_async (data->conv_stream, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback)async_flush_ready, + data); + + g_main_loop_run (data->main_loop); +} + +int +main (int argc, + char *argv[]) +{ + SetupData *data; + + g_test_init (&argc, &argv, NULL); + + data = g_slice_new (SetupData); + + /* test closing asynchronously without flushing manually */ + g_test_add ("/close-async/without-flush", + SetupData, + data, + setup_data, + test_without_flush, + teardown_data); + + /* test closing asynchronously with a synchronous manually flush */ + g_test_add ("/close-async/with-flush", + SetupData, + data, + setup_data, + test_with_flush, + teardown_data); + + /* test closing asynchronously with an asynchronous manually flush */ + g_test_add ("/close-async/with-async-flush", + SetupData, + data, + setup_data, + test_with_async_flush, + teardown_data); + + g_slice_free (SetupData, data); + + return g_test_run(); +} diff --git a/gio/tests/async-splice-output-stream.c b/gio/tests/async-splice-output-stream.c new file mode 100644 index 0000000..3ac03ae --- /dev/null +++ b/gio/tests/async-splice-output-stream.c @@ -0,0 +1,231 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2010-2012 Collabora Ltd. + * Authors: Xavier Claessens + * Mike Ruprecht + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include +#include + +typedef enum +{ + TEST_THREADED_NONE = 0, + TEST_THREADED_ISTREAM = 1, + TEST_THREADED_OSTREAM = 2, + TEST_CANCEL = 4, + TEST_THREADED_BOTH = TEST_THREADED_ISTREAM | TEST_THREADED_OSTREAM, +} TestThreadedFlags; + +typedef struct +{ + GMainLoop *main_loop; + const gchar *data; + GInputStream *istream; + GOutputStream *ostream; + TestThreadedFlags flags; + gchar *input_path; + gchar *output_path; +} TestCopyChunksData; + +static void +test_copy_chunks_splice_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + TestCopyChunksData *data = user_data; + gchar *received_data; + GError *error = NULL; + gssize bytes_spliced; + + bytes_spliced = g_output_stream_splice_finish (G_OUTPUT_STREAM (source), + res, &error); + + if (data->flags & TEST_CANCEL) + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_error_free (error); + g_main_loop_quit (data->main_loop); + return; + } + + g_assert_no_error (error); + g_assert_cmpint (bytes_spliced, ==, strlen (data->data)); + + if (data->flags & TEST_THREADED_OSTREAM) + { + gsize length = 0; + + g_file_get_contents (data->output_path, &received_data, + &length, &error); + g_assert_no_error (error); + g_assert_cmpstr (received_data, ==, data->data); + g_free (received_data); + } + else + { + received_data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->ostream)); + g_assert_cmpstr (received_data, ==, data->data); + } + + g_assert (g_input_stream_is_closed (data->istream)); + g_assert (g_output_stream_is_closed (data->ostream)); + + if (data->flags & TEST_THREADED_ISTREAM) + { + g_unlink (data->input_path); + g_free (data->input_path); + } + + if (data->flags & TEST_THREADED_OSTREAM) + { + g_unlink (data->output_path); + g_free (data->output_path); + } + + g_main_loop_quit (data->main_loop); +} + +static void +test_copy_chunks_start (TestThreadedFlags flags) +{ + TestCopyChunksData data; + GError *error = NULL; + GCancellable *cancellable = NULL; + + data.main_loop = g_main_loop_new (NULL, FALSE); + data.data = "abcdefghijklmnopqrstuvwxyz"; + data.flags = flags; + + if (data.flags & TEST_CANCEL) + { + cancellable = g_cancellable_new (); + g_cancellable_cancel (cancellable); + } + + if (data.flags & TEST_THREADED_ISTREAM) + { + GFile *file; + GFileIOStream *stream; + + file = g_file_new_tmp ("test-inputXXXXXX", &stream, &error); + g_assert_no_error (error); + g_object_unref (stream); + data.input_path = g_file_get_path (file); + g_file_set_contents (data.input_path, + data.data, strlen (data.data), + &error); + g_assert_no_error (error); + data.istream = G_INPUT_STREAM (g_file_read (file, NULL, &error)); + g_assert_no_error (error); + g_object_unref (file); + } + else + { + data.istream = g_memory_input_stream_new_from_data (data.data, -1, NULL); + } + + if (data.flags & TEST_THREADED_OSTREAM) + { + GFile *file; + GFileIOStream *stream; + + file = g_file_new_tmp ("test-outputXXXXXX", &stream, &error); + g_assert_no_error (error); + g_object_unref (stream); + data.output_path = g_file_get_path (file); + data.ostream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, + G_FILE_CREATE_NONE, + NULL, &error)); + g_assert_no_error (error); + g_object_unref (file); + } + else + { + data.ostream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + } + + g_output_stream_splice_async (data.ostream, data.istream, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + G_PRIORITY_DEFAULT, cancellable, + test_copy_chunks_splice_cb, &data); + + /* We do not hold a ref in data struct, this is to make sure the operation + * keeps the iostream objects alive until it finishes + */ + g_object_unref (data.istream); + g_object_unref (data.ostream); + g_clear_object (&cancellable); + + g_main_loop_run (data.main_loop); + g_main_loop_unref (data.main_loop); +} + +static void +test_copy_chunks (void) +{ + test_copy_chunks_start (TEST_THREADED_NONE); +} + +static void +test_copy_chunks_threaded_input (void) +{ + test_copy_chunks_start (TEST_THREADED_ISTREAM); +} + +static void +test_copy_chunks_threaded_output (void) +{ + test_copy_chunks_start (TEST_THREADED_OSTREAM); +} + +static void +test_copy_chunks_threaded (void) +{ + test_copy_chunks_start (TEST_THREADED_BOTH); +} + +static void +test_cancelled (void) +{ + test_copy_chunks_start (TEST_THREADED_NONE | TEST_CANCEL); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/async-splice/copy-chunks", test_copy_chunks); + g_test_add_func ("/async-splice/copy-chunks-threaded-input", + test_copy_chunks_threaded_input); + g_test_add_func ("/async-splice/copy-chunks-threaded-output", + test_copy_chunks_threaded_output); + g_test_add_func ("/async-splice/copy-chunks-threaded", + test_copy_chunks_threaded); + g_test_add_func ("/async-splice/cancelled", + test_cancelled); + + return g_test_run(); +} diff --git a/gio/tests/autoptr.c b/gio/tests/autoptr.c new file mode 100644 index 0000000..55a1c91 --- /dev/null +++ b/gio/tests/autoptr.c @@ -0,0 +1,23 @@ +#include + +static void +test_autoptr (void) +{ + g_autoptr(GFile) p = g_file_new_for_path ("/blah"); + g_autoptr(GInetAddress) a = g_inet_address_new_from_string ("127.0.0.1"); + g_autofree gchar *path = g_file_get_path (p); + g_autofree gchar *istr = g_inet_address_to_string (a); + + g_assert_cmpstr (path, ==, G_DIR_SEPARATOR_S "blah"); + g_assert_cmpstr (istr, ==, "127.0.0.1"); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/autoptr/autoptr", test_autoptr); + + return g_test_run (); +} diff --git a/gio/tests/basic-application.c b/gio/tests/basic-application.c new file mode 100644 index 0000000..362b2fd --- /dev/null +++ b/gio/tests/basic-application.c @@ -0,0 +1,274 @@ +#include +#include + +static void +new_activated (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + GApplication *app = user_data; + + g_application_activate (app); +} + +static void +quit_activated (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + GApplication *app = user_data; + + g_application_quit (app); +} + +static void +action1_activated (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + g_print ("activate action1\n"); +} + +static void +action2_activated (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + GVariant *state; + + state = g_action_get_state (G_ACTION (action)); + g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state))); + g_print ("activate action2 %d\n", !g_variant_get_boolean (state)); + g_variant_unref (state); +} + +static void +change_action2 (GSimpleAction *action, + GVariant *state, + gpointer user_data) +{ + g_print ("change action2 %d\n", g_variant_get_boolean (state)); +} + +static void +startup (GApplication *app) +{ + static GActionEntry actions[] = { + { "new", new_activated, NULL, NULL, NULL, { 0 } }, + { "quit", quit_activated, NULL, NULL, NULL, { 0 } }, + { "action1", action1_activated, NULL, NULL, NULL, { 0 } }, + { "action2", action2_activated, "b", "false", change_action2, { 0 } } + }; + + g_action_map_add_action_entries (G_ACTION_MAP (app), + actions, G_N_ELEMENTS (actions), + app); +} + +static void +activate (GApplication *application) +{ + g_application_hold (application); + g_print ("activated\n"); + g_application_release (application); +} + +static void +open (GApplication *application, + GFile **files, + gint n_files, + const gchar *hint) +{ + gint i; + + g_application_hold (application); + + g_print ("open"); + for (i = 0; i < n_files; i++) + { + gchar *uri = g_file_get_uri (files[i]); + g_print (" %s", uri); + g_free (uri); + } + g_print ("\n"); + + g_application_release (application); +} + +static int +command_line (GApplication *application, + GApplicationCommandLine *cmdline) +{ + gchar **argv; + gint argc; + gint i; + + g_application_hold (application); + argv = g_application_command_line_get_arguments (cmdline, &argc); + + if (argc > 1) + { + if (g_strcmp0 (argv[1], "echo") == 0) + { + g_print ("cmdline"); + for (i = 0; i < argc; i++) + g_print (" %s", argv[i]); + g_print ("\n"); + } + else if (g_strcmp0 (argv[1], "env") == 0) + { + const gchar * const *env; + + env = g_application_command_line_get_environ (cmdline); + g_print ("environment"); + for (i = 0; env[i]; i++) + if (g_str_has_prefix (env[i], "TEST=")) + g_print (" %s", env[i]); + g_print ("\n"); + } + else if (g_strcmp0 (argv[1], "getenv") == 0) + { + g_print ("getenv TEST=%s\n", g_application_command_line_getenv (cmdline, "TEST")); + } + else if (g_strcmp0 (argv[1], "print") == 0) + { + g_application_command_line_print (cmdline, "print %s\n", argv[2]); + } + else if (g_strcmp0 (argv[1], "printerr") == 0) + { + g_application_command_line_printerr (cmdline, "printerr %s\n", argv[2]); + } + else if (g_strcmp0 (argv[1], "file") == 0) + { + GFile *file; + + file = g_application_command_line_create_file_for_arg (cmdline, argv[2]); + g_print ("file %s\n", g_file_get_path (file)); + g_object_unref (file); + } + else if (g_strcmp0 (argv[1], "properties") == 0) + { + gboolean remote; + GVariant *data; + + g_object_get (cmdline, + "is-remote", &remote, + NULL); + + data = g_application_command_line_get_platform_data (cmdline); + g_assert (remote); + g_assert (g_variant_is_of_type (data, G_VARIANT_TYPE ("a{sv}"))); + g_variant_unref (data); + g_print ("properties ok\n"); + } + else if (g_strcmp0 (argv[1], "cwd") == 0) + { + g_print ("cwd %s\n", g_application_command_line_get_cwd (cmdline)); + } + else if (g_strcmp0 (argv[1], "busy") == 0) + { + g_application_mark_busy (g_application_get_default ()); + g_print ("busy\n"); + } + else if (g_strcmp0 (argv[1], "idle") == 0) + { + g_application_unmark_busy (g_application_get_default ()); + g_print ("idle\n"); + } + else if (g_strcmp0 (argv[1], "stdin") == 0) + { + GInputStream *stream; + + stream = g_application_command_line_get_stdin (cmdline); + + g_assert (stream == NULL || G_IS_INPUT_STREAM (stream)); + g_object_unref (stream); + + g_print ("stdin ok\n"); + } + else + g_print ("unexpected command: %s\n", argv[1]); + } + else + g_print ("got ./cmd %d\n", g_application_command_line_get_is_remote (cmdline)); + + g_strfreev (argv); + g_application_release (application); + + return 0; +} + +static gboolean +action_cb (gpointer data) +{ + gchar **argv = data; + GApplication *app; + gchar **actions; + gint i; + + if (g_strcmp0 (argv[1], "./actions") == 0) + { + app = g_application_get_default (); + + if (g_strcmp0 (argv[2], "list") == 0) + { + g_print ("actions"); + actions = g_action_group_list_actions (G_ACTION_GROUP (app)); + for (i = 0; actions[i]; i++) + g_print (" %s", actions[i]); + g_print ("\n"); + g_strfreev (actions); + } + else if (g_strcmp0 (argv[2], "activate") == 0) + { + g_action_group_activate_action (G_ACTION_GROUP (app), + "action1", NULL); + } + else if (g_strcmp0 (argv[2], "set-state") == 0) + { + g_action_group_change_action_state (G_ACTION_GROUP (app), + "action2", + g_variant_new_boolean (TRUE)); + } + g_application_release (app); + } + + return G_SOURCE_REMOVE; +} + +int +main (int argc, char **argv) +{ + GApplication *app; + int status; + + app = g_application_new ("org.gtk.TestApplication", + G_APPLICATION_SEND_ENVIRONMENT | + (g_strcmp0 (argv[1], "./cmd") == 0 + ? G_APPLICATION_HANDLES_COMMAND_LINE + : G_APPLICATION_HANDLES_OPEN)); + g_signal_connect (app, "startup", G_CALLBACK (startup), NULL); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (open), NULL); + g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL); +#ifdef STANDALONE + g_application_set_inactivity_timeout (app, 10000); +#else + g_application_set_inactivity_timeout (app, 1000); +#endif + + if (g_strcmp0 (argv[1], "./actions") == 0) + { + g_application_set_inactivity_timeout (app, 0); + g_application_hold (app); + g_idle_add (action_cb, argv); + } + + status = g_application_run (app, argc - 1, argv + 1); + + g_object_unref (app); + + g_print ("exit status: %d\n", status); + + return 0; +} diff --git a/gio/tests/buffered-input-stream.c b/gio/tests/buffered-input-stream.c new file mode 100644 index 0000000..ee084b3 --- /dev/null +++ b/gio/tests/buffered-input-stream.c @@ -0,0 +1,552 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc. + * Authors: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +static void +test_peek (void) +{ + GInputStream *base; + GInputStream *in; + gssize npeek; + char *buffer; + + base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL); + in = g_buffered_input_stream_new_sized (base, 64); + + g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), 5, NULL, NULL); + g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 5); + g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), -1, NULL, NULL); + g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, strlen ("abcdefjhijk")); + + buffer = g_new0 (char, 64); + npeek = g_buffered_input_stream_peek (G_BUFFERED_INPUT_STREAM (in), buffer, 2, 3); + g_assert_cmpint (npeek, ==, 3); + g_assert_cmpstr ("cde", ==, buffer); + g_free (buffer); + + buffer = g_new0 (char, 64); + npeek = g_buffered_input_stream_peek (G_BUFFERED_INPUT_STREAM (in), buffer, 9, 5); + g_assert_cmpint (npeek, ==, 2); + g_assert_cmpstr ("jk", ==, buffer); + g_free (buffer); + + buffer = g_new0 (char, 64); + npeek = g_buffered_input_stream_peek (G_BUFFERED_INPUT_STREAM (in), buffer, 75, 3); + g_assert_cmpint (npeek, ==, 0); + g_free (buffer); + + g_object_unref (in); + g_object_unref (base); +} + +static void +test_peek_buffer (void) +{ + GInputStream *base; + GInputStream *in; + gssize nfill; + gsize bufsize; + char *buffer; + + base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL); + in = g_buffered_input_stream_new (base); + + nfill = g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), strlen ("abcdefghijk"), NULL, NULL); + buffer = (char *) g_buffered_input_stream_peek_buffer (G_BUFFERED_INPUT_STREAM (in), &bufsize); + g_assert_cmpint (nfill, ==, bufsize); + g_assert (0 == strncmp ("abcdefghijk", buffer, bufsize)); + + g_object_unref (in); + g_object_unref (base); +} + +static void +test_set_buffer_size (void) +{ + GInputStream *base; + GInputStream *in; + guint bufsize_prop; + gsize size, bufsize; + + base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL); + in = g_buffered_input_stream_new (base); + size = g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (in)); + g_assert_cmpint (size, ==, 4096); + + g_buffered_input_stream_set_buffer_size (G_BUFFERED_INPUT_STREAM (in), 64); + size = g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (in)); + g_assert_cmpint (size, ==, 64); + + /* size cannot shrink below current content len */ + g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), strlen ("abcdefghijk"), NULL, NULL); + g_buffered_input_stream_peek_buffer (G_BUFFERED_INPUT_STREAM (in), &bufsize); + g_buffered_input_stream_set_buffer_size (G_BUFFERED_INPUT_STREAM (in), 2); + size = g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (in)); + g_assert_cmpint (size, ==, bufsize); + g_object_get (in, "buffer-size", &bufsize_prop, NULL); + g_assert_cmpint (bufsize_prop, ==, bufsize); + + g_object_unref (in); + + in = g_buffered_input_stream_new_sized (base, 64); + size = g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (in)); + g_assert_cmpint (size, ==, 64); + + g_object_unref (in); + g_object_unref (base); +} + +static void +test_read_byte (void) +{ + GInputStream *base; + GInputStream *in; + GError *error; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=562393"); + + base = g_memory_input_stream_new_from_data ("abcdefgh", -1, NULL); + in = g_buffered_input_stream_new (base); + + error = NULL; + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'a'); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'b'); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'c'); + g_assert_no_error (error); + + g_assert_cmpint (g_input_stream_skip (in, 3, NULL, &error), ==, 3); + g_assert_no_error (error); + + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'g'); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'h'); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, -1); + g_assert_no_error (error); + + g_assert (g_input_stream_close (in, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); + g_error_free (error); + + g_object_unref (in); + g_object_unref (base); +} + +static void +test_read (void) +{ + GInputStream *base; + GInputStream *in; + gchar buffer[20]; + GError *error; + + base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, NULL); + in = g_buffered_input_stream_new_sized (base, 8); + + g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 0); + + error = NULL; + g_assert_cmpint (g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), 8, NULL, &error), ==, 8); + g_assert_no_error (error); + + g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 8); + + memset (buffer, 0, 20); + g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 16); + g_assert_cmpstr (buffer, ==, "abcdefghijklmnop"); + g_assert_no_error (error); + + g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 0); + + memset (buffer, 0, 20); + g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 16); + g_assert_cmpstr (buffer, ==, "qrstuvwxyzABCDEF"); + g_assert_no_error (error); + + memset (buffer, 0, 20); + g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 16); + g_assert_cmpstr (buffer, ==, "GHIJKLMNOPQRSTUV"); + g_assert_no_error (error); + + memset (buffer, 0, 20); + g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 4); + g_assert_cmpstr (buffer, ==, "WXYZ"); + g_assert_no_error (error); + + memset (buffer, 0, 20); + g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 0); + g_assert_no_error (error); + + g_object_unref (in); + g_object_unref (base); +} + +static void +return_result_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GAsyncResult **ret = user_data; + + *ret = g_object_ref (result); +} + +static void +test_read_async (void) +{ + GInputStream *base; + GInputStream *in; + gchar buffer[20]; + GError *error; + GAsyncResult *result; + + base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, NULL); + in = g_buffered_input_stream_new_sized (base, 8); + + g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 0); + + error = NULL; + result = NULL; + g_buffered_input_stream_fill_async (G_BUFFERED_INPUT_STREAM (in), 8, + G_PRIORITY_DEFAULT, NULL, + return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_buffered_input_stream_fill_finish (G_BUFFERED_INPUT_STREAM (in), result, &error), ==, 8); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 8); + + memset (buffer, 0, 20); + g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 16); + g_assert_cmpstr (buffer, ==, "abcdefghijklmnop"); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 0); + + memset (buffer, 0, 20); + g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 16); + g_assert_cmpstr (buffer, ==, "qrstuvwxyzABCDEF"); + g_assert_no_error (error); + g_clear_object (&result); + + memset (buffer, 0, 20); + g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 16); + g_assert_cmpstr (buffer, ==, "GHIJKLMNOPQRSTUV"); + g_assert_no_error (error); + g_clear_object (&result); + + memset (buffer, 0, 20); + g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 4); + g_assert_cmpstr (buffer, ==, "WXYZ"); + g_assert_no_error (error); + g_clear_object (&result); + + memset (buffer, 0, 20); + g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 0); + g_assert_no_error (error); + g_clear_object (&result); + + g_object_unref (in); + g_object_unref (base); +} + +static void +test_skip (void) +{ + GInputStream *base; + GInputStream *in; + GError *error; + + base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL); + in = g_buffered_input_stream_new_sized (base, 5); + + error = NULL; + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'a'); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'b'); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'c'); + g_assert_no_error (error); + + g_assert_cmpint (g_input_stream_skip (in, 7, NULL, &error), ==, 7); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'k'); + g_assert_no_error (error); + + g_assert_cmpint (g_input_stream_skip (in, 10, NULL, &error), ==, 10); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'v'); + g_assert_no_error (error); + + g_assert_cmpint (g_input_stream_skip (in, 20, NULL, &error), ==, 20); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'Q'); + g_assert_no_error (error); + + g_assert_cmpint (g_input_stream_skip (in, 10, NULL, &error), ==, 8); + g_assert_no_error (error); + g_assert_cmpint (g_input_stream_skip (in, 10, NULL, &error), ==, 0); + g_assert_no_error (error); + + g_object_unref (in); + g_object_unref (base); +} + +static void +test_skip_async (void) +{ + GInputStream *base; + GInputStream *in; + GError *error; + GAsyncResult *result; + + base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL); + in = g_buffered_input_stream_new_sized (base, 5); + + error = NULL; + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'a'); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'b'); + g_assert_no_error (error); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'c'); + g_assert_no_error (error); + + result = NULL; + g_input_stream_skip_async (in, 7, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 7); + g_assert_no_error (error); + g_clear_object (&result); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'k'); + g_assert_no_error (error); + + g_input_stream_skip_async (in, 10, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 10); + g_assert_no_error (error); + g_clear_object (&result); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'v'); + g_assert_no_error (error); + + g_input_stream_skip_async (in, 20, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 20); + g_assert_no_error (error); + g_clear_object (&result); + g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'Q'); + g_assert_no_error (error); + + g_input_stream_skip_async (in, 10, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 8); + g_clear_object (&result); + g_assert_no_error (error); + + g_input_stream_skip_async (in, 10, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + while (!result) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 0); + g_clear_object (&result); + g_assert_no_error (error); + + g_object_unref (in); + g_object_unref (base); +} + +static void +test_close (void) +{ + GInputStream *base; + GInputStream *in; + GError *error; + + base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL); + in = g_buffered_input_stream_new (base); + + g_assert (g_filter_input_stream_get_close_base_stream (G_FILTER_INPUT_STREAM (in))); + + error = NULL; + g_assert (g_input_stream_close (in, NULL, &error)); + g_assert_no_error (error); + g_assert (g_input_stream_is_closed (base)); + + g_object_unref (in); + g_object_unref (base); + + base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL); + in = g_buffered_input_stream_new (base); + + g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (in), FALSE); + + error = NULL; + g_assert (g_input_stream_close (in, NULL, &error)); + g_assert_no_error (error); + g_assert (!g_input_stream_is_closed (base)); + + g_object_unref (in); + g_object_unref (base); +} + +static void +test_seek (void) +{ + GInputStream *base; + GInputStream *in; + GError *error; + gint byte; + gboolean ret; + + base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL); + in = g_buffered_input_stream_new_sized (base, 4); + error = NULL; + + /* Seek by read */ + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 0); + byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (byte, ==, 'a'); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 1); + + /* Seek forward (in buffer) */ + ret = g_seekable_seek (G_SEEKABLE (in), 1, G_SEEK_CUR, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 2); + byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (byte, ==, 'c'); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 3); + + /* Seek backward (in buffer) */ + ret = g_seekable_seek (G_SEEKABLE (in), -2, G_SEEK_CUR, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 1); + byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (byte, ==, 'b'); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 2); + + /* Seek forward (outside buffer) */ + ret = g_seekable_seek (G_SEEKABLE (in), 6, G_SEEK_CUR, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 8); + byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (byte, ==, 'i'); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 9); + + /* Seek backward (outside buffer) */ + ret = g_seekable_seek (G_SEEKABLE (in), -6, G_SEEK_CUR, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 3); + byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (byte, ==, 'd'); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 4); + + /* Seek from beginning */ + ret = g_seekable_seek (G_SEEKABLE (in), 8, G_SEEK_SET, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 8); + byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (byte, ==, 'i'); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 9); + + /* Seek from end */ + ret = g_seekable_seek (G_SEEKABLE (in), -1, G_SEEK_END, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 50); + byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (byte, ==, 'Z'); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 51); + + /* Cleanup */ + g_object_unref (in); + g_object_unref (base); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/buffered-input-stream/peek", test_peek); + g_test_add_func ("/buffered-input-stream/peek-buffer", test_peek_buffer); + g_test_add_func ("/buffered-input-stream/set-buffer-size", test_set_buffer_size); + g_test_add_func ("/buffered-input-stream/read-byte", test_read_byte); + g_test_add_func ("/buffered-input-stream/read", test_read); + g_test_add_func ("/buffered-input-stream/read-async", test_read_async); + g_test_add_func ("/buffered-input-stream/skip", test_skip); + g_test_add_func ("/buffered-input-stream/skip-async", test_skip_async); + g_test_add_func ("/buffered-input-stream/seek", test_seek); + g_test_add_func ("/filter-input-stream/close", test_close); + + return g_test_run(); +} diff --git a/gio/tests/buffered-output-stream.c b/gio/tests/buffered-output-stream.c new file mode 100644 index 0000000..fc740b7 --- /dev/null +++ b/gio/tests/buffered-output-stream.c @@ -0,0 +1,329 @@ +#include + +static void +test_write (void) +{ + GOutputStream *base; + GOutputStream *out; + GError *error; + const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz"; + + base = g_memory_output_stream_new (g_malloc0 (20), 20, NULL, g_free); + out = g_buffered_output_stream_new (base); + + g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 4096); + g_assert (!g_buffered_output_stream_get_auto_grow (G_BUFFERED_OUTPUT_STREAM (out))); + g_object_set (out, "auto-grow", TRUE, NULL); + g_assert (g_buffered_output_stream_get_auto_grow (G_BUFFERED_OUTPUT_STREAM (out))); + g_object_set (out, "auto-grow", FALSE, NULL); + + g_buffered_output_stream_set_buffer_size (G_BUFFERED_OUTPUT_STREAM (out), 16); + g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 16); + + error = NULL; + g_assert_cmpint (g_output_stream_write (out, buffer, 10, NULL, &error), ==, 10); + g_assert_no_error (error); + + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0); + + g_assert_cmpint (g_output_stream_write (out, buffer + 10, 10, NULL, &error), ==, 6); + g_assert_no_error (error); + + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0); + g_assert (g_output_stream_flush (out, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 16); + + g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnop"); + + g_object_unref (out); + g_object_unref (base); +} + +static void +test_grow (void) +{ + GOutputStream *base; + GOutputStream *out; + GError *error; + const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz"; + gint size; + gboolean grow; + + base = g_memory_output_stream_new (g_malloc0 (30), 30, g_realloc, g_free); + out = g_buffered_output_stream_new_sized (base, 16); + + g_buffered_output_stream_set_auto_grow (G_BUFFERED_OUTPUT_STREAM (out), TRUE); + + g_object_get (out, "buffer-size", &size, "auto-grow", &grow, NULL); + g_assert_cmpint (size, ==, 16); + g_assert (grow); + + g_assert (g_seekable_can_seek (G_SEEKABLE (out))); + + error = NULL; + g_assert_cmpint (g_output_stream_write (out, buffer, 10, NULL, &error), ==, 10); + g_assert_no_error (error); + + g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 16); + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0); + + g_assert_cmpint (g_output_stream_write (out, buffer + 10, 10, NULL, &error), ==, 10); + g_assert_no_error (error); + + g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), >=, 20); + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0); + + g_assert (g_output_stream_flush (out, NULL, &error)); + g_assert_no_error (error); + + g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnopqrst"); + + g_object_unref (out); + g_object_unref (base); +} + +static void +test_close (void) +{ + GOutputStream *base; + GOutputStream *out; + GError *error; + + base = g_memory_output_stream_new (g_malloc0 (30), 30, g_realloc, g_free); + out = g_buffered_output_stream_new (base); + + g_assert (g_filter_output_stream_get_close_base_stream (G_FILTER_OUTPUT_STREAM (out))); + + error = NULL; + g_assert (g_output_stream_close (out, NULL, &error)); + g_assert_no_error (error); + g_assert (g_output_stream_is_closed (base)); + + g_object_unref (out); + g_object_unref (base); + + base = g_memory_output_stream_new (g_malloc0 (30), 30, g_realloc, g_free); + out = g_buffered_output_stream_new (base); + + g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (out), FALSE); + + error = NULL; + g_assert (g_output_stream_close (out, NULL, &error)); + g_assert_no_error (error); + g_assert (!g_output_stream_is_closed (base)); + + g_object_unref (out); + g_object_unref (base); +} + +static void +test_seek (void) +{ + GMemoryOutputStream *base; + GOutputStream *out; + GSeekable *seekable; + GError *error; + gsize bytes_written; + gboolean ret; + const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz"; + + base = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (g_malloc0 (30), 30, NULL, g_free)); + out = g_buffered_output_stream_new_sized (G_OUTPUT_STREAM (base), 8); + seekable = G_SEEKABLE (out); + error = NULL; + + /* Write data */ + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 0); + ret = g_output_stream_write_all (out, buffer, 4, &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (bytes_written, ==, 4); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4); + g_assert_cmpint (g_memory_output_stream_get_data_size (base), ==, 0); + + /* Forward relative seek */ + ret = g_seekable_seek (seekable, 2, G_SEEK_CUR, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); + g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); + g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); + ret = g_output_stream_write_all (out, buffer, 2, &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (bytes_written, ==, 2); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8); + + /* Backward relative seek */ + ret = g_seekable_seek (seekable, -4, G_SEEK_CUR, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); + g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); + g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]); + ret = g_output_stream_write_all (out, buffer, 2, &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (bytes_written, ==, 2); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6); + + /* From start */ + ret = g_seekable_seek (seekable, 2, G_SEEK_SET, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 2); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); + g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); + g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]); + ret = g_output_stream_write_all (out, buffer, 2, &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (bytes_written, ==, 2); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4); + + /* From end */ + ret = g_seekable_seek (seekable, 6 - 30, G_SEEK_END, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]); + ret = g_output_stream_write_all (out, buffer + 2, 2, &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (bytes_written, ==, 2); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8); + + /* Check flush */ + ret = g_output_stream_flush (out, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); + g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]); + g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]); + g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]); + g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]); + + g_object_unref (out); + g_object_unref (base); +} + +static void +test_truncate(void) +{ + GMemoryOutputStream *base_stream; + GOutputStream *stream; + GSeekable *seekable; + GError *error; + gsize bytes_written; + guchar *stream_data; + gsize len; + gboolean res; + + len = 8; + + /* Create objects */ + stream_data = g_malloc0 (len); + base_stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (stream_data, len, g_realloc, g_free)); + stream = g_buffered_output_stream_new_sized (G_OUTPUT_STREAM (base_stream), 8); + seekable = G_SEEKABLE (stream); + + g_assert (g_seekable_can_truncate (seekable)); + + /* Write */ + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 0); + + error = NULL; + res = g_output_stream_write_all (stream, "ab", 2, &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert (res); + res = g_output_stream_write_all (stream, "cd", 2, &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert (res); + + res = g_output_stream_flush (stream, NULL, &error); + g_assert_no_error (error); + g_assert (res); + + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4); + stream_data = g_memory_output_stream_get_data (base_stream); + g_assert_cmpint (stream_data[0], ==, 'a'); + g_assert_cmpint (stream_data[1], ==, 'b'); + g_assert_cmpint (stream_data[2], ==, 'c'); + g_assert_cmpint (stream_data[3], ==, 'd'); + + /* Truncate at position */ + res = g_seekable_truncate (seekable, 4, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 4); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4); + stream_data = g_memory_output_stream_get_data (base_stream); + g_assert_cmpint (stream_data[0], ==, 'a'); + g_assert_cmpint (stream_data[1], ==, 'b'); + g_assert_cmpint (stream_data[2], ==, 'c'); + g_assert_cmpint (stream_data[3], ==, 'd'); + + /* Truncate beyond position */ + res = g_seekable_truncate (seekable, 6, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 6); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 6); + stream_data = g_memory_output_stream_get_data (base_stream); + g_assert_cmpint (stream_data[0], ==, 'a'); + g_assert_cmpint (stream_data[1], ==, 'b'); + g_assert_cmpint (stream_data[2], ==, 'c'); + g_assert_cmpint (stream_data[3], ==, 'd'); + + /* Truncate before position */ + res = g_seekable_truncate (seekable, 2, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 2); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 2); + stream_data = g_memory_output_stream_get_data (base_stream); + g_assert_cmpint (stream_data[0], ==, 'a'); + g_assert_cmpint (stream_data[1], ==, 'b'); + + g_object_unref (stream); + g_object_unref (base_stream); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/buffered-output-stream/write", test_write); + g_test_add_func ("/buffered-output-stream/grow", test_grow); + g_test_add_func ("/buffered-output-stream/seek", test_seek); + g_test_add_func ("/buffered-output-stream/truncate", test_truncate); + g_test_add_func ("/filter-output-stream/close", test_close); + + return g_test_run (); +} diff --git a/gio/tests/cancellable.c b/gio/tests/cancellable.c new file mode 100644 index 0000000..1eb7529 --- /dev/null +++ b/gio/tests/cancellable.c @@ -0,0 +1,349 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#include + +#include + +#include "glib/glib-private.h" + +/* How long to wait in ms for each iteration */ +#define WAIT_ITERATION (10) + +static gint num_async_operations = 0; + +typedef struct +{ + guint iterations_requested; /* construct-only */ + guint iterations_done; /* (atomic) */ +} MockOperationData; + +static void +mock_operation_free (gpointer user_data) +{ + MockOperationData *data = user_data; + g_free (data); +} + +static void +mock_operation_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + MockOperationData *data = task_data; + guint i; + + for (i = 0; i < data->iterations_requested; i++) + { + if (g_cancellable_is_cancelled (cancellable)) + break; + if (g_test_verbose ()) + g_test_message ("THRD: %u iteration %u", data->iterations_requested, i); + g_usleep (WAIT_ITERATION * 1000); + } + + if (g_test_verbose ()) + g_test_message ("THRD: %u stopped at %u", data->iterations_requested, i); + g_atomic_int_add (&data->iterations_done, i); + + g_task_return_boolean (task, TRUE); +} + +static gboolean +mock_operation_timeout (gpointer user_data) +{ + GTask *task; + MockOperationData *data; + gboolean done = FALSE; + guint iterations_done; + + task = G_TASK (user_data); + data = g_task_get_task_data (task); + iterations_done = g_atomic_int_get (&data->iterations_done); + + if (iterations_done >= data->iterations_requested) + done = TRUE; + + if (g_cancellable_is_cancelled (g_task_get_cancellable (task))) + done = TRUE; + + if (done) + { + if (g_test_verbose ()) + g_test_message ("LOOP: %u stopped at %u", + data->iterations_requested, iterations_done); + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; + } + else + { + g_atomic_int_inc (&data->iterations_done); + if (g_test_verbose ()) + g_test_message ("LOOP: %u iteration %u", + data->iterations_requested, iterations_done + 1); + return G_SOURCE_CONTINUE; + } +} + +static void +mock_operation_async (guint wait_iterations, + gboolean run_in_thread, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + MockOperationData *data; + + task = g_task_new (NULL, cancellable, callback, user_data); + data = g_new0 (MockOperationData, 1); + data->iterations_requested = wait_iterations; + g_task_set_task_data (task, data, mock_operation_free); + + if (run_in_thread) + { + g_task_run_in_thread (task, mock_operation_thread); + if (g_test_verbose ()) + g_test_message ("THRD: %d started", wait_iterations); + } + else + { + g_timeout_add_full (G_PRIORITY_DEFAULT, WAIT_ITERATION, mock_operation_timeout, + g_object_ref (task), g_object_unref); + if (g_test_verbose ()) + g_test_message ("LOOP: %d started", wait_iterations); + } + + g_object_unref (task); +} + +static guint +mock_operation_finish (GAsyncResult *result, + GError **error) +{ + MockOperationData *data; + GTask *task; + + g_assert_true (g_task_is_valid (result, NULL)); + + /* This test expects the return value to be iterations_done even + * when an error is set. + */ + task = G_TASK (result); + data = g_task_get_task_data (task); + + g_task_propagate_boolean (task, error); + return g_atomic_int_get (&data->iterations_done); +} + +static void +on_mock_operation_ready (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + guint iterations_requested; + guint iterations_done; + GError *error = NULL; + + iterations_requested = GPOINTER_TO_UINT (user_data); + iterations_done = mock_operation_finish (result, &error); + + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_error_free (error); + + g_assert_cmpint (iterations_requested, >, iterations_done); + num_async_operations--; + g_main_context_wakeup (NULL); +} + +static void +test_cancel_multiple_concurrent (void) +{ + GCancellable *cancellable; + guint i, iterations; + + if (!g_test_thorough ()) + { + g_test_skip ("Not running timing heavy test"); + return; + } + + cancellable = g_cancellable_new (); + + for (i = 0; i < 45; i++) + { + iterations = i + 10; + mock_operation_async (iterations, g_random_boolean (), cancellable, + on_mock_operation_ready, GUINT_TO_POINTER (iterations)); + num_async_operations++; + } + + /* Wait for the threads to start up */ + while (num_async_operations != 45) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (num_async_operations, ==, 45);\ + + if (g_test_verbose ()) + g_test_message ("CANCEL: %d operations", num_async_operations); + g_cancellable_cancel (cancellable); + g_assert_true (g_cancellable_is_cancelled (cancellable)); + + /* Wait for all operations to be cancelled */ + while (num_async_operations != 0) + g_main_context_iteration (NULL, TRUE); + g_assert_cmpint (num_async_operations, ==, 0); + + g_object_unref (cancellable); +} + +static void +test_cancel_null (void) +{ + g_cancellable_cancel (NULL); +} + +typedef struct +{ + GCond cond; + GMutex mutex; + gboolean thread_ready; + GAsyncQueue *cancellable_source_queue; /* (owned) (element-type GCancellableSource) */ +} ThreadedDisposeData; + +static gboolean +cancelled_cb (GCancellable *cancellable, + gpointer user_data) +{ + /* Nothing needs to be done here. */ + return G_SOURCE_CONTINUE; +} + +static gpointer +threaded_dispose_thread_cb (gpointer user_data) +{ + ThreadedDisposeData *data = user_data; + GSource *cancellable_source; + + g_mutex_lock (&data->mutex); + data->thread_ready = TRUE; + g_cond_broadcast (&data->cond); + g_mutex_unlock (&data->mutex); + + while ((cancellable_source = g_async_queue_pop (data->cancellable_source_queue)) != (gpointer) 1) + { + /* Race with cancellation of the cancellable. */ + g_source_unref (cancellable_source); + } + + return NULL; +} + +static void +test_cancellable_source_threaded_dispose (void) +{ +#ifdef _GLIB_ADDRESS_SANITIZER + g_test_incomplete ("FIXME: Leaks lots of GCancellableSource objects, see glib#2309"); + (void) cancelled_cb; + (void) threaded_dispose_thread_cb; +#else + ThreadedDisposeData data; + GThread *thread = NULL; + guint i; + GPtrArray *cancellables_pending_unref = g_ptr_array_new_with_free_func (g_object_unref); + + g_test_summary ("Test a thread race between disposing of a GCancellableSource " + "(in one thread) and cancelling the GCancellable it refers " + "to (in another thread)"); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1841"); + + /* Create a new thread and wait until it’s ready to execute. Each iteration of + * the test will pass it a new #GCancellableSource. */ + g_cond_init (&data.cond); + g_mutex_init (&data.mutex); + data.cancellable_source_queue = g_async_queue_new_full ((GDestroyNotify) g_source_unref); + data.thread_ready = FALSE; + + g_mutex_lock (&data.mutex); + thread = g_thread_new ("/cancellable-source/threaded-dispose", + threaded_dispose_thread_cb, &data); + + while (!data.thread_ready) + g_cond_wait (&data.cond, &data.mutex); + g_mutex_unlock (&data.mutex); + + for (i = 0; i < 100000; i++) + { + GCancellable *cancellable = NULL; + GSource *cancellable_source = NULL; + + /* Create a cancellable and a cancellable source for it. For this test, + * there’s no need to attach the source to a #GMainContext. */ + cancellable = g_cancellable_new (); + cancellable_source = g_cancellable_source_new (cancellable); + g_source_set_callback (cancellable_source, G_SOURCE_FUNC (cancelled_cb), NULL, NULL); + + /* Send it to the thread and wait until it’s ready to execute before + * cancelling our cancellable. */ + g_async_queue_push (data.cancellable_source_queue, g_steal_pointer (&cancellable_source)); + + /* Race with disposal of the cancellable source. */ + g_cancellable_cancel (cancellable); + + /* This thread can’t drop its reference to the #GCancellable here, as it + * might not be the final reference (depending on how the race is + * resolved: #GCancellableSource holds a strong ref on the #GCancellable), + * and at this point we can’t guarantee to support disposing of a + * #GCancellable in a different thread from where it’s created, especially + * when signal handlers are connected to it. + * + * So this is a workaround for a disposal-in-another-thread bug for + * #GCancellable, but there’s no hope of debugging and resolving it with + * this test setup, and the bug is orthogonal to what’s being tested here + * (a race between #GCancellable and #GCancellableSource). */ + g_ptr_array_add (cancellables_pending_unref, g_steal_pointer (&cancellable)); + } + + /* Indicate that the test has finished. Can’t use %NULL as #GAsyncQueue + * doesn’t allow that.*/ + g_async_queue_push (data.cancellable_source_queue, (gpointer) 1); + + g_thread_join (g_steal_pointer (&thread)); + + g_assert (g_async_queue_length (data.cancellable_source_queue) == 0); + g_async_queue_unref (data.cancellable_source_queue); + g_mutex_clear (&data.mutex); + g_cond_clear (&data.cond); + + g_ptr_array_unref (cancellables_pending_unref); +#endif +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/cancellable/multiple-concurrent", test_cancel_multiple_concurrent); + g_test_add_func ("/cancellable/null", test_cancel_null); + g_test_add_func ("/cancellable-source/threaded-dispose", test_cancellable_source_threaded_dispose); + + return g_test_run (); +} diff --git a/gio/tests/cert-tests/cert-crlf.pem b/gio/tests/cert-tests/cert-crlf.pem new file mode 100644 index 0000000..c54f448 --- /dev/null +++ b/gio/tests/cert-tests/cert-crlf.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC +Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM +DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w +LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu +Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT +AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK +DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu +MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh +LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U +DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR +ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt +0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw +BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR +q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS ++5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ== +-----END CERTIFICATE----- diff --git a/gio/tests/cert-tests/cert-key.pem b/gio/tests/cert-tests/cert-key.pem new file mode 100644 index 0000000..5babba3 --- /dev/null +++ b/gio/tests/cert-tests/cert-key.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC +Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM +DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w +LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu +Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT +AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK +DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu +MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh +LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U +DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR +ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt +0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw +BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR +q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS ++5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7 +P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb +dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB +AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R +gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR +Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR +pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G ++3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3 +Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V +oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9 +J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe +aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7 +HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t +-----END RSA PRIVATE KEY----- diff --git a/gio/tests/cert-tests/cert-list.pem b/gio/tests/cert-tests/cert-list.pem new file mode 100644 index 0000000..ffab3f4 --- /dev/null +++ b/gio/tests/cert-tests/cert-list.pem @@ -0,0 +1,68 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC +Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM +DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w +LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu +Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT +AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK +DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu +MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh +LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U +DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR +ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt +0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw +BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR +q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS ++5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICtTCCAh4CCQCVO34vew4kvTANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC +Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM +DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w +LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu +Y29tMB4XDTExMDcyNTE4NTI1M1oXDTEyMDcyNDE4NTI1M1owgZ4xCzAJBgNVBAYT +AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK +DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu +MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh +LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U +DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR +ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt +0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAiaJ6bO5NJ +pyS8p//UVQM/T+exyZxznULwqCuVKv7uwss2QiKiQGJPfVc0iy650cTegtoc4ki5 +Zfg/Cllxj2KAmbkWGlzVw7IvuBouruxdojm+0y60DzWr1rQUkL6VX/VBZXL51VPp +zCdTCzI3v4ztFStbUyC99xx1hdHOSleLOQ== +-----END CERTIFICATE----- +>>>> Garbage to be ignore <<<< +-----BEGIN CERTIFICATE----- +MIICtTCCAh4CCQD9ny7saeYnDDANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC +Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM +DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w +LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu +Y29tMB4XDTExMDcyNTE4NTMwMVoXDTEyMDcyNDE4NTMwMVowgZ4xCzAJBgNVBAYT +AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK +DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu +MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh +LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U +DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR +ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt +0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAGBjOlcmD6 +E6GlY2rvjCf0BpW0t4zKL/wvA5tBmuOWYg93psHgIdSNgkmfbA1kvD6kXehQlt1F +5yZJP91/VND5LHvXf5TcAmr/KeQAPYvqfiGYXuvHDLA9y9OOyTBMURLYfWuo9HZt +xeI14sZ9udXwtUhgcvXrBFzlRfkbojuMZw== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7 +P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb +dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB +AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R +gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR +Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR +pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G ++3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3 +Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V +oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9 +J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe +aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7 +HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t +-----END RSA PRIVATE KEY----- +>>>> Garbage to be ignore <<<< diff --git a/gio/tests/cert-tests/cert1.pem b/gio/tests/cert-tests/cert1.pem new file mode 100644 index 0000000..b21bb8b --- /dev/null +++ b/gio/tests/cert-tests/cert1.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC +Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM +DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w +LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu +Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT +AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK +DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu +MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh +LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U +DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR +ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt +0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw +BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR +q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS ++5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ== +-----END CERTIFICATE----- diff --git a/gio/tests/cert-tests/cert2.pem b/gio/tests/cert-tests/cert2.pem new file mode 100644 index 0000000..ba1df45 --- /dev/null +++ b/gio/tests/cert-tests/cert2.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAh4CCQCVO34vew4kvTANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC +Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM +DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w +LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu +Y29tMB4XDTExMDcyNTE4NTI1M1oXDTEyMDcyNDE4NTI1M1owgZ4xCzAJBgNVBAYT +AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK +DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu +MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh +LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U +DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR +ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt +0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAiaJ6bO5NJ +pyS8p//UVQM/T+exyZxznULwqCuVKv7uwss2QiKiQGJPfVc0iy650cTegtoc4ki5 +Zfg/Cllxj2KAmbkWGlzVw7IvuBouruxdojm+0y60DzWr1rQUkL6VX/VBZXL51VPp +zCdTCzI3v4ztFStbUyC99xx1hdHOSleLOQ== +-----END CERTIFICATE----- diff --git a/gio/tests/cert-tests/cert3.pem b/gio/tests/cert-tests/cert3.pem new file mode 100644 index 0000000..57d6e6b --- /dev/null +++ b/gio/tests/cert-tests/cert3.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAh4CCQD9ny7saeYnDDANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC +Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM +DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w +LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu +Y29tMB4XDTExMDcyNTE4NTMwMVoXDTEyMDcyNDE4NTMwMVowgZ4xCzAJBgNVBAYT +AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK +DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu +MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh +LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U +DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR +ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt +0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAGBjOlcmD6 +E6GlY2rvjCf0BpW0t4zKL/wvA5tBmuOWYg93psHgIdSNgkmfbA1kvD6kXehQlt1F +5yZJP91/VND5LHvXf5TcAmr/KeQAPYvqfiGYXuvHDLA9y9OOyTBMURLYfWuo9HZt +xeI14sZ9udXwtUhgcvXrBFzlRfkbojuMZw== +-----END CERTIFICATE----- diff --git a/gio/tests/cert-tests/key-cert-password-123.p12 b/gio/tests/cert-tests/key-cert-password-123.p12 new file mode 100644 index 0000000000000000000000000000000000000000..4da265fd65ca9d9aed35323968578c177f01af65 GIT binary patch literal 1717 zcmXqLV%x~X$ZXKWR?fz$)#lOmotKfFaX}MX21^rLia`@wfeKvYi-Yjdo~5^vmoC42=;Oj}Ta8@X;JXpezB|6&u*Pm@!tW^u{{1rfHuvdE4>Jo> zot0-DqgHY=?^vMp=+k$*snww$|9%d6Q#0|`s_Mr5^$JDbo;)ZPO|$LZQluPH@K(d< zH@o^N0nUfk=NoJNXC-e@QRY1?royZlVDpGtd{fkaJ-IDY$zq<7DxyIzly53uUykuQbw42Fiv&@7H zk>tDGlN0y2K0IeK<6DTIbKsq2r(SKpHv5oEX8ZCJKChMhm!|mzPXAGu<>dGEquR_D z)uP{`UDyBd*kai5to>`F{j(Y)$LT(MSQq}dn0fQYwT9DCwwwGzg)HW_W-Yvv*rn4i z_iAbZr_%$!x-VCn%L9ISWUXW=nPPmY)UodQ;?)@rU#$HCr?4Hp8c}sVbN8eAIZ|87 zcPv%n_&d!^`|2$5H}#|D344wkRy+b1vsRo; z>Q8I_5*gnXwMoudomuACzO7%EF_e9u^1sF6j{Y1)0 z3!0c-u{1F~GiYLZWYENPkBu9at+*JO7Bn#}GiYL3gp%8sLAmX<>(||UW#0av+{V(x z)bKGpTm4JNr#H*RWy-`o_ZVh8FFt?aue7YHw!oBk8UHncKmB=`Z+=e8VY|uQ)>!5F z#%E*o*?Y1~>wZs-ne+1h<&wS(0iElt{z3O9Ei`!%Cw;2*|M}PLY136sM#(7ubnHFP zm}I_bYmaX1bltz18egu2?8u$4-6@)BxsJqprMYXbK0KG2<;>5|FfXqBYvtA)=A{@egI8vC-W$D@5=!o>CnEl`zH0dTROV7PdK0I@vXt0yHnodebf2C)SXFi}Ch1nh#s?LPMN@yeb{5W<{_Ed~tb6y3)|{vOLdm?&7ZqG_TH<8kc%Jn!_Ml?<1@7CFi1$g^Rp!) zrqN{cQ`Z{PnbjA68H*mMwAOvSy>R|pz5|oh@-|L!zoR}=sZr{~lAG^WGNiLy6u<4t zY;4TdrXs)`HtCT#>*keg-Mfr$_|Ms&HglGp#=*L*o\n" + "#ifdef G_OS_UNIX\n" + "# include \n" + "#endif", + "standard_typedefs_and_helpers": "typedef struct\n" + "{\n" + " GDBusArgInfo parent_struct;\n" + " gboolean use_gvariant;\n" + "} _ExtendedGDBusArgInfo;\n" + "\n" + "typedef struct\n" + "{\n" + " GDBusMethodInfo parent_struct;\n" + " const gchar *signal_name;\n" + " gboolean pass_fdlist;\n" + "} _ExtendedGDBusMethodInfo;\n" + "\n" + "typedef struct\n" + "{\n" + " GDBusSignalInfo parent_struct;\n" + " const gchar *signal_name;\n" + "} _ExtendedGDBusSignalInfo;\n" + "\n" + "typedef struct\n" + "{\n" + " GDBusPropertyInfo parent_struct;\n" + " const gchar *hyphen_name;\n" + " guint use_gvariant : 1;\n" + " guint emits_changed_signal : 1;\n" + "} _ExtendedGDBusPropertyInfo;\n" + "\n" + "typedef struct\n" + "{\n" + " GDBusInterfaceInfo parent_struct;\n" + " const gchar *hyphen_name;\n" + "} _ExtendedGDBusInterfaceInfo;\n" + "\n" + "typedef struct\n" + "{\n" + " const _ExtendedGDBusPropertyInfo *info;\n" + " guint prop_id;\n" + " GValue orig_value; /* the value before the change */\n" + "} ChangedProperty;\n" + "\n" + "static void\n" + "_changed_property_free (ChangedProperty *data)\n" + "{\n" + " g_value_unset (&data->orig_value);\n" + " g_free (data);\n" + "}\n" + "\n" + "static gboolean\n" + "_g_strv_equal0 (gchar **a, gchar **b)\n" + "{\n" + " gboolean ret = FALSE;\n" + " guint n;\n" + " if (a == NULL && b == NULL)\n" + " {\n" + " ret = TRUE;\n" + " goto out;\n" + " }\n" + " if (a == NULL || b == NULL)\n" + " goto out;\n" + " if (g_strv_length (a) != g_strv_length (b))\n" + " goto out;\n" + " for (n = 0; a[n] != NULL; n++)\n" + " if (g_strcmp0 (a[n], b[n]) != 0)\n" + " goto out;\n" + " ret = TRUE;\n" + "out:\n" + " return ret;\n" + "}\n" + "\n" + "static gboolean\n" + "_g_variant_equal0 (GVariant *a, GVariant *b)\n" + "{\n" + " gboolean ret = FALSE;\n" + " if (a == NULL && b == NULL)\n" + " {\n" + " ret = TRUE;\n" + " goto out;\n" + " }\n" + " if (a == NULL || b == NULL)\n" + " goto out;\n" + " ret = g_variant_equal (a, b);\n" + "out:\n" + " return ret;\n" + "}\n" + "\n" + "G_GNUC_UNUSED static gboolean\n" + "_g_value_equal (const GValue *a, const GValue *b)\n" + "{\n" + " gboolean ret = FALSE;\n" + " g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n" + " switch (G_VALUE_TYPE (a))\n" + " {\n" + " case G_TYPE_BOOLEAN:\n" + " ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n" + " break;\n" + " case G_TYPE_UCHAR:\n" + " ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n" + " break;\n" + " case G_TYPE_INT:\n" + " ret = (g_value_get_int (a) == g_value_get_int (b));\n" + " break;\n" + " case G_TYPE_UINT:\n" + " ret = (g_value_get_uint (a) == g_value_get_uint (b));\n" + " break;\n" + " case G_TYPE_INT64:\n" + " ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n" + " break;\n" + " case G_TYPE_UINT64:\n" + " ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n" + " break;\n" + " case G_TYPE_DOUBLE:\n" + " {\n" + " /* Avoid -Wfloat-equal warnings by doing a direct bit compare */\n" + " gdouble da = g_value_get_double (a);\n" + " gdouble db = g_value_get_double (b);\n" + " ret = memcmp (&da, &db, sizeof (gdouble)) == 0;\n" + " }\n" + " break;\n" + " case G_TYPE_STRING:\n" + " ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n" + " break;\n" + " case G_TYPE_VARIANT:\n" + " ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n" + " break;\n" + " default:\n" + " if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n" + " ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n" + " else\n" + ' g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n' + " break;\n" + " }\n" + " return ret;\n" + "}", + } + + result = Result(info, out, err, subs) + + print("Output:", result.out) + return result + + def runCodegenWithInterface(self, interface_contents, *args): + with tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, suffix=".xml", delete=False + ) as interface_file: + # Write out the interface. + interface_file.write(interface_contents.encode("utf-8")) + print(interface_file.name + ":", interface_contents) + interface_file.flush() + + return self.runCodegen(interface_file.name, *args) + + def test_help(self): + """Test the --help argument.""" + result = self.runCodegen("--help") + self.assertIn("usage: gdbus-codegen", result.out) + + def test_no_args(self): + """Test running with no arguments at all.""" + with self.assertRaises(subprocess.CalledProcessError): + self.runCodegen() + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_empty_interface_header(self): + """Test generating a header with an empty interface file.""" + result = self.runCodegenWithInterface("", "--output", "/dev/stdout", "--header") + self.assertEqual("", result.err) + self.assertEqual( + """{standard_top_comment} + +#ifndef __STDOUT__ +#define __STDOUT__ + +#include + +G_BEGIN_DECLS + + +G_END_DECLS + +#endif /* __STDOUT__ */""".format( + **result.subs + ), + result.out.strip(), + ) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_empty_interface_body(self): + """Test generating a body with an empty interface file.""" + result = self.runCodegenWithInterface("", "--output", "/dev/stdout", "--body") + self.assertEqual("", result.err) + self.assertEqual( + """{standard_top_comment} + +{standard_config_h_include} + +#include "stdout.h" + +{standard_header_includes} + +{standard_typedefs_and_helpers}""".format( + **result.subs + ), + result.out.strip(), + ) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_reproducible(self): + """Test builds are reproducible regardless of file ordering.""" + xml_contents1 = """ + + + + + + + + + + """ + + xml_contents2 = """ + + + + + + """ + + with tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, suffix="1.xml", delete=False + ) as xml_file1, tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, suffix="2.xml", delete=False + ) as xml_file2: + # Write out the interfaces. + xml_file1.write(xml_contents1.encode("utf-8")) + xml_file2.write(xml_contents2.encode("utf-8")) + + xml_file1.flush() + xml_file2.flush() + + # Repeat this for headers and bodies. + for header_or_body in ["--header", "--body"]: + # Run gdbus-codegen with the interfaces in one order, and then + # again in another order. + result1 = self.runCodegen( + xml_file1.name, + xml_file2.name, + "--output", + "/dev/stdout", + header_or_body, + ) + self.assertEqual("", result1.err) + + result2 = self.runCodegen( + xml_file2.name, + xml_file1.name, + "--output", + "/dev/stdout", + header_or_body, + ) + self.assertEqual("", result2.err) + + # The output should be the same. + self.assertEqual(result1.out, result2.out) + + def test_generate_docbook(self): + """Test the basic functionality of the docbook generator.""" + xml_contents = """ + + + + + + """ + res = self.runCodegenWithInterface( + xml_contents, + "--generate-docbook", + "test", + ) + self.assertEqual("", res.err) + self.assertEqual("", res.out) + with open("test-org.project.Bar.Frobnicator.xml", "r") as f: + xml_data = f.readlines() + self.assertTrue(len(xml_data) != 0) + + def test_generate_rst(self): + """Test the basic functionality of the rst generator.""" + xml_contents = """ + + + + + + """ + res = self.runCodegenWithInterface( + xml_contents, + "--generate-rst", + "test", + ) + self.assertEqual("", res.err) + self.assertEqual("", res.out) + with open("test-org.project.Bar.Frobnicator.rst", "r") as f: + rst = f.readlines() + self.assertTrue(len(rst) != 0) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_min_required_invalid(self): + """Test running with an invalid --glib-min-required.""" + with self.assertRaises(subprocess.CalledProcessError): + self.runCodegenWithInterface( + "", + "--output", + "/dev/stdout", + "--body", + "--glib-min-required", + "hello mum", + ) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_min_required_too_low(self): + """Test running with a --glib-min-required which is too low (and hence + probably a typo).""" + with self.assertRaises(subprocess.CalledProcessError): + self.runCodegenWithInterface( + "", "--output", "/dev/stdout", "--body", "--glib-min-required", "2.6" + ) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_min_required_major_only(self): + """Test running with a --glib-min-required which contains only a major version.""" + result = self.runCodegenWithInterface( + "", + "--output", + "/dev/stdout", + "--header", + "--glib-min-required", + "3", + "--glib-max-allowed", + "3.2", + ) + self.assertEqual("", result.err) + self.assertNotEqual("", result.out.strip()) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_min_required_with_micro(self): + """Test running with a --glib-min-required which contains a micro version.""" + result = self.runCodegenWithInterface( + "", "--output", "/dev/stdout", "--header", "--glib-min-required", "2.46.2" + ) + self.assertEqual("", result.err) + self.assertNotEqual("", result.out.strip()) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_max_allowed_too_low(self): + """Test running with a --glib-max-allowed which is too low (and hence + probably a typo).""" + with self.assertRaises(subprocess.CalledProcessError): + self.runCodegenWithInterface( + "", "--output", "/dev/stdout", "--body", "--glib-max-allowed", "2.6" + ) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_max_allowed_major_only(self): + """Test running with a --glib-max-allowed which contains only a major version.""" + result = self.runCodegenWithInterface( + "", "--output", "/dev/stdout", "--header", "--glib-max-allowed", "3" + ) + self.assertEqual("", result.err) + self.assertNotEqual("", result.out.strip()) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_max_allowed_with_micro(self): + """Test running with a --glib-max-allowed which contains a micro version.""" + result = self.runCodegenWithInterface( + "", "--output", "/dev/stdout", "--header", "--glib-max-allowed", "2.46.2" + ) + self.assertEqual("", result.err) + self.assertNotEqual("", result.out.strip()) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_max_allowed_unstable(self): + """Test running with a --glib-max-allowed which is unstable. It should + be rounded up to the next stable version number, and hence should not + end up less than --glib-min-required.""" + result = self.runCodegenWithInterface( + "", + "--output", + "/dev/stdout", + "--header", + "--glib-max-allowed", + "2.63", + "--glib-min-required", + "2.64", + ) + self.assertEqual("", result.err) + self.assertNotEqual("", result.out.strip()) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_glib_max_allowed_less_than_min_required(self): + """Test running with a --glib-max-allowed which is less than + --glib-min-required.""" + with self.assertRaises(subprocess.CalledProcessError): + self.runCodegenWithInterface( + "", + "--output", + "/dev/stdout", + "--body", + "--glib-max-allowed", + "2.62", + "--glib-min-required", + "2.64", + ) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_unix_fd_types_and_annotations(self): + """Test an interface with `h` arguments, no annotation, and GLib < 2.64. + + See issue #1726. + """ + interface_xml = """ + + + + + + + + + + + + + + + + + + """ + + # Try without specifying --glib-min-required. + result = self.runCodegenWithInterface( + interface_xml, "--output", "/dev/stdout", "--header" + ) + self.assertEqual("", result.err) + self.assertEqual(result.out.strip().count("GUnixFDList"), 6) + + # Specify an old --glib-min-required. + result = self.runCodegenWithInterface( + interface_xml, + "--output", + "/dev/stdout", + "--header", + "--glib-min-required", + "2.32", + ) + self.assertEqual("", result.err) + self.assertEqual(result.out.strip().count("GUnixFDList"), 6) + + # Specify a --glib-min-required ≥ 2.64. There should be more + # mentions of `GUnixFDList` now, since the annotation is not needed to + # trigger its use. + result = self.runCodegenWithInterface( + interface_xml, + "--output", + "/dev/stdout", + "--header", + "--glib-min-required", + "2.64", + ) + self.assertEqual("", result.err) + self.assertEqual(result.out.strip().count("GUnixFDList"), 18) + + @unittest.skipIf(on_win32(), "requires /dev/stdout") + def test_call_flags_and_timeout_method_args(self): + """Test that generated method call functions have @call_flags and + @timeout_msec args if and only if GLib >= 2.64. + """ + interface_xml = """ + + + + + """ + + # Try without specifying --glib-min-required. + result = self.runCodegenWithInterface( + interface_xml, "--output", "/dev/stdout", "--header" + ) + self.assertEqual("", result.err) + self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 0) + self.assertEqual(result.out.strip().count("gint timeout_msec,"), 0) + + # Specify an old --glib-min-required. + result = self.runCodegenWithInterface( + interface_xml, + "--output", + "/dev/stdout", + "--header", + "--glib-min-required", + "2.32", + ) + self.assertEqual("", result.err) + self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 0) + self.assertEqual(result.out.strip().count("gint timeout_msec,"), 0) + + # Specify a --glib-min-required ≥ 2.64. The two arguments should be + # present for both the async and sync method call functions. + result = self.runCodegenWithInterface( + interface_xml, + "--output", + "/dev/stdout", + "--header", + "--glib-min-required", + "2.64", + ) + self.assertEqual("", result.err) + self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 2) + self.assertEqual(result.out.strip().count("gint timeout_msec,"), 2) + + def test_generate_valid_docbook(self): + """Test the basic functionality of the docbook generator.""" + xml_contents = """ + + + + + + + + + + """ + res = self.runCodegenWithInterface( + xml_contents, + "--generate-docbook", + "test", + ) + self.assertEqual("", res.err) + self.assertEqual("", res.out) + with open("test-org.project.Bar.Frobnicator.xml", "r") as f: + self.assertTrue(ET.parse(f) is not None) + + +if __name__ == "__main__": + unittest.main(testRunner=taptestrunner.TAPTestRunner()) diff --git a/gio/tests/contenttype.c b/gio/tests/contenttype.c new file mode 100644 index 0000000..6cfd366 --- /dev/null +++ b/gio/tests/contenttype.c @@ -0,0 +1,449 @@ +#include +#include + +#define g_assert_content_type_equals(s1, s2) \ + do { \ + const char *__s1 = (s1), *__s2 = (s2); \ + if (g_content_type_equals (__s1, __s2)) ; \ + else \ + g_assertion_message_cmpstr (G_LOG_DOMAIN, \ + __FILE__, __LINE__, \ + G_STRFUNC, \ + #s1 " == " #s2, \ + __s1, " == ", __s2); \ + } while (0) + +static void +test_guess (void) +{ + gchar *res; + gchar *expected; + gchar *existing_directory; + gboolean uncertain; + guchar data[] = + "[Desktop Entry]\n" + "Type=Application\n" + "Name=appinfo-test\n" + "Exec=./appinfo-test --option\n"; + +#ifdef G_OS_WIN32 + existing_directory = (gchar *) g_getenv ("SYSTEMROOT"); + + if (existing_directory) + existing_directory = g_strdup_printf ("%s" G_DIR_SEPARATOR_S, existing_directory); +#else + existing_directory = g_strdup ("/etc/"); +#endif + + res = g_content_type_guess (existing_directory, NULL, 0, &uncertain); + g_free (existing_directory); + expected = g_content_type_from_mime_type ("inode/directory"); + g_assert_content_type_equals (expected, res); + g_assert_true (uncertain); + g_free (res); + g_free (expected); + + res = g_content_type_guess ("foo.txt", NULL, 0, &uncertain); + expected = g_content_type_from_mime_type ("text/plain"); + g_assert_content_type_equals (expected, res); + g_free (res); + g_free (expected); + + res = g_content_type_guess ("foo.txt", data, sizeof (data) - 1, &uncertain); + expected = g_content_type_from_mime_type ("text/plain"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); + + /* Sadly win32 & OSX just don't have as large and robust of a mime type database as Linux */ +#ifndef G_OS_WIN32 +#ifndef __APPLE__ + res = g_content_type_guess ("foo", data, sizeof (data) - 1, &uncertain); + expected = g_content_type_from_mime_type ("text/plain"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); + + res = g_content_type_guess ("foo.desktop", data, sizeof (data) - 1, &uncertain); + expected = g_content_type_from_mime_type ("application/x-desktop"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); + + res = g_content_type_guess (NULL, data, sizeof (data) - 1, &uncertain); + expected = g_content_type_from_mime_type ("application/x-desktop"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); + + /* this is potentially ambiguous: it does not match the PO template format, + * but looks like text so it can't be Powerpoint */ + res = g_content_type_guess ("test.pot", (guchar *)"ABC abc", 7, &uncertain); + expected = g_content_type_from_mime_type ("text/x-gettext-translation-template"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); + + res = g_content_type_guess ("test.pot", (guchar *)"msgid \"", 7, &uncertain); + expected = g_content_type_from_mime_type ("text/x-gettext-translation-template"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); + + res = g_content_type_guess ("test.pot", (guchar *)"\xCF\xD0\xE0\x11", 4, &uncertain); + expected = g_content_type_from_mime_type ("application/vnd.ms-powerpoint"); + g_assert_content_type_equals (expected, res); + /* we cannot reliably detect binary powerpoint files as long as there is no + * defined MIME magic, so do not check uncertain here + */ + g_free (res); + g_free (expected); + + res = g_content_type_guess ("test.otf", (guchar *)"OTTO", 4, &uncertain); + expected = g_content_type_from_mime_type ("application/x-font-otf"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); +#endif /* __APPLE__ */ + + res = g_content_type_guess (NULL, (guchar *)"%!PS-Adobe-2.0 EPSF-1.2", 23, &uncertain); + expected = g_content_type_from_mime_type ("image/x-eps"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); + + /* The data below would be detected as a valid content type, but shouldn’t be read at all. */ + res = g_content_type_guess (NULL, (guchar *)"%!PS-Adobe-2.0 EPSF-1.2", 0, &uncertain); + expected = g_content_type_from_mime_type ("application/x-zerosize"); + g_assert_content_type_equals (expected, res); + g_assert_false (uncertain); + g_free (res); + g_free (expected); +#endif /* G_OS_WIN32 */ +} + +static void +test_unknown (void) +{ + gchar *unknown; + gchar *str; + + unknown = g_content_type_from_mime_type ("application/octet-stream"); + g_assert_true (g_content_type_is_unknown (unknown)); + str = g_content_type_get_mime_type (unknown); + g_assert_cmpstr (str, ==, "application/octet-stream"); + g_free (str); + g_free (unknown); +} + +static void +test_subtype (void) +{ + gchar *plain; + gchar *xml; + + plain = g_content_type_from_mime_type ("text/plain"); + xml = g_content_type_from_mime_type ("application/xml"); + + g_assert_true (g_content_type_is_a (xml, plain)); + g_assert_true (g_content_type_is_mime_type (xml, "text/plain")); + + g_free (plain); + g_free (xml); +} + +static gint +find_mime (gconstpointer a, gconstpointer b) +{ + if (g_content_type_equals (a, b)) + return 0; + return 1; +} + +static void +test_list (void) +{ + GList *types; + gchar *plain; + gchar *xml; + +#ifdef __APPLE__ + g_test_skip ("The OSX backend does not implement g_content_types_get_registered()"); + return; +#endif + + plain = g_content_type_from_mime_type ("text/plain"); + xml = g_content_type_from_mime_type ("application/xml"); + + types = g_content_types_get_registered (); + + g_assert_cmpuint (g_list_length (types), >, 1); + + /* just check that some types are in the list */ + g_assert_nonnull (g_list_find_custom (types, plain, find_mime)); + g_assert_nonnull (g_list_find_custom (types, xml, find_mime)); + + g_list_free_full (types, g_free); + + g_free (plain); + g_free (xml); +} + +static void +test_executable (void) +{ + gchar *type; + +#ifdef G_OS_WIN32 + type = g_content_type_from_mime_type ("application/vnd.microsoft.portable-executable"); + /* FIXME: the MIME is not in the default `MIME\Database\Content Type` registry. + * g_assert_true (g_content_type_can_be_executable (type)); + */ + g_free (type); +#else + type = g_content_type_from_mime_type ("application/x-executable"); + g_assert_true (g_content_type_can_be_executable (type)); + g_free (type); + + type = g_content_type_from_mime_type ("text/plain"); + g_assert_true (g_content_type_can_be_executable (type)); + g_free (type); +#endif + type = g_content_type_from_mime_type ("image/png"); + g_assert_false (g_content_type_can_be_executable (type)); + g_free (type); +} + +static void +test_description (void) +{ + gchar *type; + gchar *desc; + + type = g_content_type_from_mime_type ("text/plain"); + desc = g_content_type_get_description (type); + g_assert_nonnull (desc); + + g_free (desc); + g_free (type); +} + +static void +test_icon (void) +{ + gchar *type; + GIcon *icon; + + type = g_content_type_from_mime_type ("text/plain"); + icon = g_content_type_get_icon (type); + g_assert_true (G_IS_ICON (icon)); + if (G_IS_THEMED_ICON (icon)) + { + const gchar *const *names; + + names = g_themed_icon_get_names (G_THEMED_ICON (icon)); +#ifdef __APPLE__ + g_assert_true (g_strv_contains (names, "text-*")); +#else +#ifndef G_OS_WIN32 + g_assert_true (g_strv_contains (names, "text-plain")); +#endif + g_assert_true (g_strv_contains (names, "text-x-generic")); +#endif + } + g_object_unref (icon); + g_free (type); + + type = g_content_type_from_mime_type ("application/rtf"); + icon = g_content_type_get_icon (type); + g_assert_true (G_IS_ICON (icon)); + if (G_IS_THEMED_ICON (icon)) + { + const gchar *const *names; + + names = g_themed_icon_get_names (G_THEMED_ICON (icon)); +#ifdef G_OS_WIN32 + g_assert_true (g_strv_contains (names, "text-x-generic")); +#else + g_assert_true (g_strv_contains (names, "application-rtf")); +#ifndef __APPLE__ + g_assert_true (g_strv_contains (names, "x-office-document")); +#endif +#endif + } + g_object_unref (icon); + g_free (type); +} + +static void +test_symbolic_icon (void) +{ +#ifndef G_OS_WIN32 + gchar *type; + GIcon *icon; + + type = g_content_type_from_mime_type ("text/plain"); + icon = g_content_type_get_symbolic_icon (type); + g_assert_true (G_IS_ICON (icon)); + if (G_IS_THEMED_ICON (icon)) + { + const gchar *const *names; + + names = g_themed_icon_get_names (G_THEMED_ICON (icon)); +#ifdef __APPLE__ + g_assert_true (g_strv_contains (names, "text-*-symbolic")); + g_assert_true (g_strv_contains (names, "text-*")); +#else + g_assert_true (g_strv_contains (names, "text-plain-symbolic")); + g_assert_true (g_strv_contains (names, "text-x-generic-symbolic")); + g_assert_true (g_strv_contains (names, "text-plain")); + g_assert_true (g_strv_contains (names, "text-x-generic")); +#endif + } + g_object_unref (icon); + g_free (type); + + type = g_content_type_from_mime_type ("application/rtf"); + icon = g_content_type_get_symbolic_icon (type); + g_assert_true (G_IS_ICON (icon)); + if (G_IS_THEMED_ICON (icon)) + { + const gchar *const *names; + + names = g_themed_icon_get_names (G_THEMED_ICON (icon)); + g_assert_true (g_strv_contains (names, "application-rtf-symbolic")); + g_assert_true (g_strv_contains (names, "application-rtf")); +#ifndef __APPLE__ + g_assert_true (g_strv_contains (names, "x-office-document-symbolic")); + g_assert_true (g_strv_contains (names, "x-office-document")); +#endif + } + g_object_unref (icon); + g_free (type); +#endif +} + +static void +test_tree (void) +{ + const gchar *tests[] = { + "x-content/image-dcf", + "x-content/unix-software", + "x-content/win32-software" + }; + const gchar *path; + GFile *file; + gchar **types; + gsize i; + +#if defined(__APPLE__) || defined(G_OS_WIN32) + g_test_skip ("The OSX & Windows backends do not implement g_content_type_guess_for_tree()"); + return; +#endif + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + path = g_test_get_filename (G_TEST_DIST, tests[i], NULL); + file = g_file_new_for_path (path); + types = g_content_type_guess_for_tree (file); + g_assert_content_type_equals (types[0], tests[i]); + g_strfreev (types); + g_object_unref (file); + } +} + +static void +test_type_is_a_special_case (void) +{ + gboolean res; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=782311"); + + /* Everything but the inode type is application/octet-stream */ + res = g_content_type_is_a ("inode/directory", "application/octet-stream"); + g_assert_false (res); +#if !defined(__APPLE__) && !defined(G_OS_WIN32) + res = g_content_type_is_a ("anything", "application/octet-stream"); + g_assert_true (res); +#endif +} + +static void +test_guess_svg_from_data (void) +{ + const gchar svgfilecontent[] = "\n\ + \n\ +\n"; + + gboolean uncertain = TRUE; + gchar *res = g_content_type_guess (NULL, (guchar *)svgfilecontent, + sizeof (svgfilecontent) - 1, &uncertain); +#ifdef __APPLE__ + g_assert_cmpstr (res, ==, "public.svg-image"); +#elif defined(G_OS_WIN32) + g_test_skip ("svg type detection from content is not implemented on WIN32"); +#else + g_assert_cmpstr (res, ==, "image/svg+xml"); +#endif + g_assert_false (uncertain); + g_free (res); +} + +static void +test_mime_from_content (void) +{ +#ifdef __APPLE__ + gchar *mime_type; + mime_type = g_content_type_get_mime_type ("com.microsoft.bmp"); + g_assert_cmpstr (mime_type, ==, "image/bmp"); + g_free (mime_type); + mime_type = g_content_type_get_mime_type ("com.compuserve.gif"); + g_assert_cmpstr (mime_type, ==, "image/gif"); + g_free (mime_type); + mime_type = g_content_type_get_mime_type ("public.png"); + g_assert_cmpstr (mime_type, ==, "image/png"); + g_free (mime_type); + mime_type = g_content_type_get_mime_type ("public.text"); + g_assert_cmpstr (mime_type, ==, "text/*"); + g_free (mime_type); + mime_type = g_content_type_get_mime_type ("public.svg-image"); + g_assert_cmpstr (mime_type, ==, "image/svg+xml"); + g_free (mime_type); +#elif defined(G_OS_WIN32) + g_test_skip ("mime from content type test not implemented on WIN32"); +#else + g_test_skip ("mime from content type test not implemented on UNIX"); +#endif +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/contenttype/guess", test_guess); + g_test_add_func ("/contenttype/guess_svg_from_data", test_guess_svg_from_data); + g_test_add_func ("/contenttype/mime_from_content", test_mime_from_content); + g_test_add_func ("/contenttype/unknown", test_unknown); + g_test_add_func ("/contenttype/subtype", test_subtype); + g_test_add_func ("/contenttype/list", test_list); + g_test_add_func ("/contenttype/executable", test_executable); + g_test_add_func ("/contenttype/description", test_description); + g_test_add_func ("/contenttype/icon", test_icon); + g_test_add_func ("/contenttype/symbolic-icon", test_symbolic_icon); + g_test_add_func ("/contenttype/tree", test_tree); + g_test_add_func ("/contenttype/test_type_is_a_special_case", + test_type_is_a_special_case); + + return g_test_run (); +} diff --git a/gio/tests/contexts.c b/gio/tests/contexts.c new file mode 100644 index 0000000..3b64c76 --- /dev/null +++ b/gio/tests/contexts.c @@ -0,0 +1,441 @@ +#include "gcontextspecificgroup.c" +#include +#include +#include + +#define N_THREADS 10 + +static gchar *test_file; + +char *test_file_buffer; +gsize test_file_size; +static char async_read_buffer[8192]; + +static void +read_data (GObject *source, GAsyncResult *result, gpointer loop) +{ + GInputStream *in = G_INPUT_STREAM (source); + GError *error = NULL; + gssize nread; + + nread = g_input_stream_read_finish (in, result, &error); + g_assert_no_error (error); + + g_assert_cmpint (nread, >, 0); + g_assert_cmpint (nread, <=, MIN(sizeof (async_read_buffer), test_file_size)); + g_assert (memcmp (async_read_buffer, test_file_buffer, nread) == 0); + + g_main_loop_quit (loop); +} + +static void +opened_for_read (GObject *source, GAsyncResult *result, gpointer loop) +{ + GFile *file = G_FILE (source); + GFileInputStream *in; + GError *error = NULL; + + in = g_file_read_finish (file, result, &error); + g_assert_no_error (error); + + memset (async_read_buffer, 0, sizeof (async_read_buffer)); + g_input_stream_read_async (G_INPUT_STREAM (in), + async_read_buffer, sizeof (async_read_buffer), + G_PRIORITY_DEFAULT, NULL, + read_data, loop); + + g_object_unref (in); +} + +/* Test 1: Async I/O started in a thread with a thread-default context + * will stick to that thread, and will complete even if the default + * main loop is blocked. (NB: the last part would not be true if we + * were testing GFileMonitor!) + */ + +static gboolean idle_start_test1_thread (gpointer loop); +static gpointer test1_thread (gpointer user_data); + +static gboolean test1_done; +static GCond test1_cond; +static GMutex test1_mutex; + +static void +test_thread_independence (void) +{ + GMainLoop *loop; + + loop = g_main_loop_new (NULL, FALSE); + g_idle_add (idle_start_test1_thread, loop); + g_main_loop_run (loop); + g_main_loop_unref (loop); +} + +static gboolean +idle_start_test1_thread (gpointer loop) +{ + gint64 time; + GThread *thread; + gboolean io_completed; + + g_mutex_lock (&test1_mutex); + thread = g_thread_new ("test1", test1_thread, NULL); + + time = g_get_monotonic_time () + 2 * G_TIME_SPAN_SECOND; + while (!test1_done) + { + io_completed = g_cond_wait_until (&test1_cond, &test1_mutex, time); + g_assert (io_completed); + } + g_thread_join (thread); + + g_mutex_unlock (&test1_mutex); + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; +} + +static gpointer +test1_thread (gpointer user_data) +{ + GMainContext *context; + GMainLoop *loop; + GFile *file; + + /* Wait for main thread to be waiting on test1_cond */ + g_mutex_lock (&test1_mutex); + + context = g_main_context_new (); + g_assert (g_main_context_get_thread_default () == NULL); + g_main_context_push_thread_default (context); + g_assert (g_main_context_get_thread_default () == context); + + file = g_file_new_for_path (test_file); + g_assert (g_file_supports_thread_contexts (file)); + + loop = g_main_loop_new (context, FALSE); + g_file_read_async (file, G_PRIORITY_DEFAULT, NULL, + opened_for_read, loop); + g_object_unref (file); + g_main_loop_run (loop); + g_main_loop_unref (loop); + + test1_done = TRUE; + g_cond_signal (&test1_cond); + g_mutex_unlock (&test1_mutex); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); + + return NULL; +} + +/* Test 2: If we push a thread-default context in the main thread, we + * can run async ops in that context without running the default + * context. + */ + +static gboolean test2_fail (gpointer user_data); + +static void +test_context_independence (void) +{ + GMainContext *context; + GMainLoop *loop; + GFile *file; + guint default_timeout; + GSource *thread_default_timeout; + + context = g_main_context_new (); + g_assert (g_main_context_get_thread_default () == NULL); + g_main_context_push_thread_default (context); + g_assert (g_main_context_get_thread_default () == context); + + file = g_file_new_for_path (test_file); + g_assert (g_file_supports_thread_contexts (file)); + + /* Add a timeout to the main loop, to fail immediately if it gets run */ + default_timeout = g_timeout_add_full (G_PRIORITY_HIGH, 0, + test2_fail, NULL, NULL); + /* Add a timeout to the alternate loop, to fail if the I/O *doesn't* run */ + thread_default_timeout = g_timeout_source_new_seconds (2); + g_source_set_callback (thread_default_timeout, test2_fail, NULL, NULL); + g_source_attach (thread_default_timeout, context); + + loop = g_main_loop_new (context, FALSE); + g_file_read_async (file, G_PRIORITY_DEFAULT, NULL, + opened_for_read, loop); + g_object_unref (file); + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_source_remove (default_timeout); + g_source_destroy (thread_default_timeout); + g_source_unref (thread_default_timeout); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); +} + +static gboolean +test2_fail (gpointer user_data) +{ + g_assert_not_reached (); + return FALSE; +} + + +typedef struct +{ + GObject parent_instance; + + GMainContext *context; +} PerThreadThing; + +typedef GObjectClass PerThreadThingClass; + +static GType per_thread_thing_get_type (void); + +G_DEFINE_TYPE (PerThreadThing, per_thread_thing, G_TYPE_OBJECT) + +static GContextSpecificGroup group; +static gpointer instances[N_THREADS]; +static gint is_running; +static gint current_value; +static gint observed_values[N_THREADS]; + +static void +start_func (void) +{ + g_assert (!is_running); + g_atomic_int_set (&is_running, TRUE); +} + +static void +stop_func (void) +{ + g_assert (is_running); + g_atomic_int_set (&is_running, FALSE); +} + +static void +per_thread_thing_finalize (GObject *object) +{ + PerThreadThing *thing = (PerThreadThing *) object; + + g_context_specific_group_remove (&group, thing->context, thing, stop_func); + + G_OBJECT_CLASS (per_thread_thing_parent_class)->finalize (object); +} + +static void +per_thread_thing_init (PerThreadThing *thing) +{ +} + +static void +per_thread_thing_class_init (PerThreadThingClass *class) +{ + class->finalize = per_thread_thing_finalize; + + g_signal_new ("changed", per_thread_thing_get_type (), G_SIGNAL_RUN_FIRST, 0, + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); +} + +static gpointer +per_thread_thing_get (void) +{ + return g_context_specific_group_get (&group, per_thread_thing_get_type (), + G_STRUCT_OFFSET (PerThreadThing, context), + start_func); +} + +static gpointer +test_identity_thread (gpointer user_data) +{ + guint thread_nr = GPOINTER_TO_UINT (user_data); + GMainContext *my_context; + guint i, j; + + my_context = g_main_context_new (); + g_main_context_push_thread_default (my_context); + + g_assert (!instances[thread_nr]); + instances[thread_nr] = per_thread_thing_get (); + g_assert (g_atomic_int_get (&is_running)); + + for (i = 0; i < 100; i++) + { + gpointer instance = per_thread_thing_get (); + + for (j = 0; j < N_THREADS; j++) + g_assert ((instance == instances[j]) == (thread_nr == j)); + + g_assert (g_atomic_int_get (&is_running)); + + g_thread_yield (); + + g_assert (g_atomic_int_get (&is_running)); + } + + for (i = 0; i < 100; i++) + { + g_object_unref (instances[thread_nr]); + + for (j = 0; j < N_THREADS; j++) + g_assert ((instances[thread_nr] == instances[j]) == (thread_nr == j)); + + g_assert (g_atomic_int_get (&is_running)); + + g_thread_yield (); + } + + /* drop the last ref */ + g_object_unref (instances[thread_nr]); + instances[thread_nr] = NULL; + + g_main_context_pop_thread_default (my_context); + g_main_context_unref (my_context); + + /* at least one thread should see this cleared on exit */ + return GUINT_TO_POINTER (!group.requested_state); +} + +static void +test_context_specific_identity (void) +{ + GThread *threads[N_THREADS]; + gboolean exited = FALSE; + guint i; + + g_assert (!g_atomic_int_get (&is_running)); + for (i = 0; i < N_THREADS; i++) + threads[i] = g_thread_new ("test", test_identity_thread, GUINT_TO_POINTER (i)); + for (i = 0; i < N_THREADS; i++) + exited |= GPOINTER_TO_UINT (g_thread_join (threads[i])); + g_assert (exited); + g_assert (!group.requested_state); +} + +static void +changed_emitted (PerThreadThing *thing, + gpointer user_data) +{ + gint *observed_value = user_data; + + g_atomic_int_set (observed_value, g_atomic_int_get (¤t_value)); +} + +static gpointer +test_emit_thread (gpointer user_data) +{ + gint *observed_value = user_data; + GMainContext *my_context; + gpointer instance; + + my_context = g_main_context_new (); + g_main_context_push_thread_default (my_context); + + instance = per_thread_thing_get (); + g_assert (g_atomic_int_get (&is_running)); + + g_signal_connect (instance, "changed", G_CALLBACK (changed_emitted), observed_value); + + /* observe after connection */ + g_atomic_int_set (observed_value, g_atomic_int_get (¤t_value)); + + while (g_atomic_int_get (¤t_value) != -1) + g_main_context_iteration (my_context, TRUE); + + g_object_unref (instance); + + g_main_context_pop_thread_default (my_context); + g_main_context_unref (my_context); + + /* at least one thread should see this cleared on exit */ + return GUINT_TO_POINTER (!group.requested_state); +} + +static void +test_context_specific_emit (void) +{ + GThread *threads[N_THREADS]; + gboolean exited = FALSE; + gsize i; + gint k, n; + + for (i = 0; i < N_THREADS; i++) + threads[i] = g_thread_new ("test", test_emit_thread, &observed_values[i]); + + /* make changes and ensure that they are observed */ + for (n = 0; n < 1000; n++) + { + gint64 expiry; + + /* don't burn CPU forever */ + expiry = g_get_monotonic_time () + 10 * G_TIME_SPAN_SECOND; + + g_atomic_int_set (¤t_value, n); + + /* wake them to notice */ + for (k = 0; k < g_test_rand_int_range (1, 5); k++) + g_context_specific_group_emit (&group, g_signal_lookup ("changed", per_thread_thing_get_type ())); + + for (i = 0; i < N_THREADS; i++) + while (g_atomic_int_get (&observed_values[i]) != n) + { + g_thread_yield (); + + if (g_get_monotonic_time () > expiry) + g_error ("timed out"); + } + } + + /* tell them to quit */ + g_atomic_int_set (¤t_value, -1); + g_context_specific_group_emit (&group, g_signal_lookup ("notify", G_TYPE_OBJECT)); + + for (i = 0; i < N_THREADS; i++) + exited |= GPOINTER_TO_UINT (g_thread_join (threads[i])); + g_assert (exited); + g_assert (!group.requested_state); +} + +static void +test_context_specific_emit_and_unref (void) +{ + gpointer obj; + + obj = per_thread_thing_get (); + g_context_specific_group_emit (&group, g_signal_lookup ("changed", per_thread_thing_get_type ())); + g_object_unref (obj); + + while (g_main_context_iteration (NULL, 0)) + ; +} + +int +main (int argc, char **argv) +{ + GError *error = NULL; + int ret; + + g_test_init (&argc, &argv, NULL); + + test_file = g_test_build_filename (G_TEST_DIST, "contexts.c", NULL); + g_file_get_contents (test_file, &test_file_buffer, + &test_file_size, &error); + g_assert_no_error (error); + + g_test_add_func ("/gio/contexts/thread-independence", test_thread_independence); + g_test_add_func ("/gio/contexts/context-independence", test_context_independence); + g_test_add_func ("/gio/contexts/context-specific/identity", test_context_specific_identity); + g_test_add_func ("/gio/contexts/context-specific/emit", test_context_specific_emit); + g_test_add_func ("/gio/contexts/context-specific/emit-and-unref", test_context_specific_emit_and_unref); + + ret = g_test_run(); + + g_free (test_file_buffer); + g_free (test_file); + + return ret; +} diff --git a/gio/tests/converter-stream.c b/gio/tests/converter-stream.c new file mode 100644 index 0000000..31399a7 --- /dev/null +++ b/gio/tests/converter-stream.c @@ -0,0 +1,1235 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2009 Red Hat, Inc. + * Authors: Alexander Larsson + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +#define G_TYPE_EXPANDER_CONVERTER (g_expander_converter_get_type ()) +#define G_EXPANDER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_EXPANDER_CONVERTER, GExpanderConverter)) +#define G_EXPANDER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_EXPANDER_CONVERTER, GExpanderConverterClass)) +#define G_IS_EXPANDER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_EXPANDER_CONVERTER)) +#define G_IS_EXPANDER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_EXPANDER_CONVERTER)) +#define G_EXPANDER_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_EXPANDER_CONVERTER, GExpanderConverterClass)) + +typedef struct _GExpanderConverter GExpanderConverter; +typedef struct _GExpanderConverterClass GExpanderConverterClass; + +struct _GExpanderConverterClass +{ + GObjectClass parent_class; +}; + +GType g_expander_converter_get_type (void) G_GNUC_CONST; +GConverter *g_expander_converter_new (void); + + + +static void g_expander_converter_iface_init (GConverterIface *iface); + +struct _GExpanderConverter +{ + GObject parent_instance; +}; + +G_DEFINE_TYPE_WITH_CODE (GExpanderConverter, g_expander_converter, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, + g_expander_converter_iface_init)) + +static void +g_expander_converter_class_init (GExpanderConverterClass *klass) +{ +} + +static void +g_expander_converter_init (GExpanderConverter *local) +{ +} + +GConverter * +g_expander_converter_new (void) +{ + GConverter *conv; + + conv = g_object_new (G_TYPE_EXPANDER_CONVERTER, NULL); + + return conv; +} + +static void +g_expander_converter_reset (GConverter *converter) +{ +} + +static GConverterResult +g_expander_converter_convert (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const guint8 *in, *in_end; + guint8 v, *out; + gsize i; + gsize block_size; + + in = inbuf; + out = outbuf; + in_end = in + inbuf_size; + + while (in < in_end) + { + v = *in; + + if (v == 0) + block_size = 10; + else + block_size = v * 1000; + + if (outbuf_size < block_size) + { + if (*bytes_read > 0) + return G_CONVERTER_CONVERTED; + + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_NO_SPACE, + "No space in dest"); + return G_CONVERTER_ERROR; + } + + in++; + *bytes_read += 1; + *bytes_written += block_size; + outbuf_size -= block_size; + for (i = 0; i < block_size; i++) + *out++ = v; + } + + if (in == in_end && (flags & G_CONVERTER_INPUT_AT_END)) + return G_CONVERTER_FINISHED; + return G_CONVERTER_CONVERTED; +} + +static void +g_expander_converter_iface_init (GConverterIface *iface) +{ + iface->convert = g_expander_converter_convert; + iface->reset = g_expander_converter_reset; +} + +#define G_TYPE_COMPRESSOR_CONVERTER (g_compressor_converter_get_type ()) +#define G_COMPRESSOR_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverter)) +#define G_COMPRESSOR_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverterClass)) +#define G_IS_COMPRESSOR_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_COMPRESSOR_CONVERTER)) +#define G_IS_COMPRESSOR_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_COMPRESSOR_CONVERTER)) +#define G_COMPRESSOR_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverterClass)) + +typedef struct _GCompressorConverter GCompressorConverter; +typedef struct _GCompressorConverterClass GCompressorConverterClass; + +struct _GCompressorConverterClass +{ + GObjectClass parent_class; +}; + +GType g_compressor_converter_get_type (void) G_GNUC_CONST; +GConverter *g_compressor_converter_new (void); + + + +static void g_compressor_converter_iface_init (GConverterIface *iface); + +struct _GCompressorConverter +{ + GObject parent_instance; +}; + +G_DEFINE_TYPE_WITH_CODE (GCompressorConverter, g_compressor_converter, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, + g_compressor_converter_iface_init)) + +static void +g_compressor_converter_class_init (GCompressorConverterClass *klass) +{ +} + +static void +g_compressor_converter_init (GCompressorConverter *local) +{ +} + +GConverter * +g_compressor_converter_new (void) +{ + GConverter *conv; + + conv = g_object_new (G_TYPE_COMPRESSOR_CONVERTER, NULL); + + return conv; +} + +static void +g_compressor_converter_reset (GConverter *converter) +{ +} + +static GConverterResult +g_compressor_converter_convert (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const guint8 *in, *in_end; + guint8 v, *out; + gsize i; + gsize block_size; + + in = inbuf; + out = outbuf; + in_end = in + inbuf_size; + + while (in < in_end) + { + v = *in; + + if (v == 0) + { + block_size = 0; + while (in+block_size < in_end && *(in+block_size) == 0) + block_size ++; + } + else + block_size = v * 1000; + + /* Not enough data */ + if ((gsize) (in_end - in) < block_size) + { + if (*bytes_read > 0) + break; + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_PARTIAL_INPUT, + "Need more data"); + return G_CONVERTER_ERROR; + } + + for (i = 0; i < block_size; i++) + { + if (*(in + i) != v) + { + if (*bytes_read > 0) + break; + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "invalid data"); + return G_CONVERTER_ERROR; + } + } + + if (v == 0 && (gsize) (in_end - in) == block_size && (flags & G_CONVERTER_INPUT_AT_END) == 0) + { + if (*bytes_read > 0) + break; + g_set_error_literal (error, G_IO_ERROR, + G_IO_ERROR_PARTIAL_INPUT, + "Need more data"); + return G_CONVERTER_ERROR; + } + + in += block_size; + *out++ = v; + *bytes_read += block_size; + *bytes_written += 1; + } + + if (in == in_end && (flags & G_CONVERTER_INPUT_AT_END)) + return G_CONVERTER_FINISHED; + return G_CONVERTER_CONVERTED; +} + +static void +g_compressor_converter_iface_init (GConverterIface *iface) +{ + iface->convert = g_compressor_converter_convert; + iface->reset = g_compressor_converter_reset; +} + +guint8 unexpanded_data[] = { 0,1,3,4,5,6,7,3,12,0,0}; + +static void +test_expander (void) +{ + guint8 *converted1, *converted2, *ptr; + gsize n_read, n_written; + gsize total_read; + gssize res; + GConverterResult cres; + GInputStream *mem, *cstream; + GOutputStream *mem_out, *cstream_out; + GConverter *expander; + GConverter *converter; + GError *error; + gsize i; + + expander = g_expander_converter_new (); + + converted1 = g_malloc (100*1000); /* Large enough */ + converted2 = g_malloc (100*1000); /* Large enough */ + + cres = g_converter_convert (expander, + unexpanded_data, sizeof(unexpanded_data), + converted1, 100*1000, + G_CONVERTER_INPUT_AT_END, + &n_read, &n_written, NULL); + + g_assert_cmpint (cres, ==, G_CONVERTER_FINISHED); + g_assert_cmpuint (n_read, ==, 11); + g_assert_cmpuint (n_written, ==, 41030); + + g_converter_reset (expander); + + mem = g_memory_input_stream_new_from_data (unexpanded_data, + sizeof (unexpanded_data), + NULL); + cstream = g_converter_input_stream_new (mem, expander); + g_assert_true (g_converter_input_stream_get_converter (G_CONVERTER_INPUT_STREAM (cstream)) == expander); + g_object_get (cstream, "converter", &converter, NULL); + g_assert_true (converter == expander); + g_object_unref (converter); + g_object_unref (mem); + + total_read = 0; + ptr = converted2; + while (TRUE) + { + error = NULL; + res = g_input_stream_read (cstream, + ptr, 1, + NULL, &error); + g_assert_cmpint (res, !=, -1); + if (res == 0) + break; + ptr += res; + total_read += res; + } + + g_assert_cmpmem (converted1, n_written, converted2, total_read); + + g_converter_reset (expander); + + mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + cstream_out = g_converter_output_stream_new (mem_out, expander); + g_assert_true (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (cstream_out)) == expander); + g_object_get (cstream_out, "converter", &converter, NULL); + g_assert_true (converter == expander); + g_object_unref (converter); + g_object_unref (mem_out); + + for (i = 0; i < sizeof(unexpanded_data); i++) + { + error = NULL; + res = g_output_stream_write (cstream_out, + unexpanded_data + i, 1, + NULL, &error); + g_assert_cmpint (res, !=, -1); + if (res == 0) + { + g_assert_cmpuint (i, ==, sizeof(unexpanded_data) -1); + break; + } + g_assert_cmpint (res, ==, 1); + } + + g_output_stream_close (cstream_out, NULL, NULL); + + g_assert_cmpmem (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)), + g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)), + converted1, n_written); + + g_free (converted1); + g_free (converted2); + g_object_unref (cstream); + g_object_unref (cstream_out); + g_object_unref (expander); +} + +static void +test_compressor (void) +{ + guint8 *converted, *expanded, *ptr; + gsize n_read, expanded_size; + gsize total_read; + gssize res; + GConverterResult cres; + GInputStream *mem, *cstream; + GOutputStream *mem_out, *cstream_out; + GConverter *expander, *compressor; + GError *error; + gsize i; + + expander = g_expander_converter_new (); + expanded = g_malloc (100*1000); /* Large enough */ + cres = g_converter_convert (expander, + unexpanded_data, sizeof(unexpanded_data), + expanded, 100*1000, + G_CONVERTER_INPUT_AT_END, + &n_read, &expanded_size, NULL); + g_assert_cmpint (cres, ==, G_CONVERTER_FINISHED); + g_assert_cmpuint (n_read, ==, 11); + g_assert_cmpuint (expanded_size, ==, 41030); + + compressor = g_compressor_converter_new (); + + converted = g_malloc (100*1000); /* Large enough */ + + mem = g_memory_input_stream_new_from_data (expanded, + expanded_size, + NULL); + cstream = g_converter_input_stream_new (mem, compressor); + g_object_unref (mem); + + total_read = 0; + ptr = converted; + while (TRUE) + { + error = NULL; + res = g_input_stream_read (cstream, + ptr, 1, + NULL, &error); + g_assert_cmpint (res, !=, -1); + if (res == 0) + break; + ptr += res; + total_read += res; + } + + /* "n_read - 1" because last 2 zeros are combined */ + g_assert_cmpmem (unexpanded_data, n_read - 1, converted, total_read); + + g_object_unref (cstream); + + g_converter_reset (compressor); + + mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + cstream_out = g_converter_output_stream_new (mem_out, compressor); + g_object_unref (mem_out); + + for (i = 0; i < expanded_size; i++) + { + error = NULL; + res = g_output_stream_write (cstream_out, + expanded + i, 1, + NULL, &error); + g_assert_cmpint (res, !=, -1); + if (res == 0) + { + g_assert_cmpuint (i, ==, expanded_size -1); + break; + } + g_assert_cmpint (res, ==, 1); + } + + g_output_stream_close (cstream_out, NULL, NULL); + + /* "n_read - 1" because last 2 zeros are combined */ + g_assert_cmpmem (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)), + g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)), + unexpanded_data, + n_read - 1); + + g_object_unref (cstream_out); + + g_converter_reset (compressor); + + memset (expanded, 5, 5*1000*2); + + mem = g_memory_input_stream_new_from_data (expanded, + 5*1000, + NULL); + cstream = g_converter_input_stream_new (mem, compressor); + g_object_unref (mem); + + total_read = 0; + ptr = converted; + while (TRUE) + { + error = NULL; + res = g_input_stream_read (cstream, + ptr, 1, + NULL, &error); + g_assert_cmpint (res, !=, -1); + if (res == 0) + break; + ptr += res; + total_read += res; + } + + g_assert_cmpuint (total_read, ==, 1); + g_assert_cmpuint (*converted, ==, 5); + + g_object_unref (cstream); + + mem = g_memory_input_stream_new_from_data (expanded, + 5*1000 * 2, + NULL); + cstream = g_converter_input_stream_new (mem, compressor); + g_object_unref (mem); + + total_read = 0; + ptr = converted; + while (TRUE) + { + error = NULL; + res = g_input_stream_read (cstream, + ptr, 1, + NULL, &error); + g_assert_cmpint (res, !=, -1); + if (res == 0) + break; + ptr += res; + total_read += res; + } + + g_assert_cmpuint (total_read, ==, 2); + g_assert_cmpuint (converted[0], ==, 5); + g_assert_cmpuint (converted[1], ==, 5); + + g_object_unref (cstream); + + g_converter_reset (compressor); + + mem = g_memory_input_stream_new_from_data (expanded, + 5*1000 * 2 - 1, + NULL); + cstream = g_converter_input_stream_new (mem, compressor); + g_object_unref (mem); + + total_read = 0; + ptr = converted; + while (TRUE) + { + error = NULL; + res = g_input_stream_read (cstream, + ptr, 1, + NULL, &error); + if (res == -1) + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT); + g_error_free (error); + break; + } + + g_assert_cmpint (res, !=, 0); + ptr += res; + total_read += res; + } + + g_assert_cmpuint (total_read, ==, 1); + g_assert_cmpuint (converted[0], ==, 5); + + g_object_unref (cstream); + + g_free (expanded); + g_free (converted); + g_object_unref (expander); + g_object_unref (compressor); +} + +#define LEFTOVER_SHORT_READ_SIZE 512 + +#define G_TYPE_LEFTOVER_CONVERTER (g_leftover_converter_get_type ()) +#define G_LEFTOVER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverter)) +#define G_LEFTOVER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverterClass)) +#define G_IS_LEFTOVER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LEFTOVER_CONVERTER)) +#define G_IS_LEFTOVER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LEFTOVER_CONVERTER)) +#define G_LEFTOVER_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverterClass)) + +typedef struct _GLeftoverConverter GLeftoverConverter; +typedef struct _GLeftoverConverterClass GLeftoverConverterClass; + +struct _GLeftoverConverterClass +{ + GObjectClass parent_class; +}; + +GType g_leftover_converter_get_type (void) G_GNUC_CONST; +GConverter *g_leftover_converter_new (void); + + + +static void g_leftover_converter_iface_init (GConverterIface *iface); + +struct _GLeftoverConverter +{ + GObject parent_instance; +}; + +G_DEFINE_TYPE_WITH_CODE (GLeftoverConverter, g_leftover_converter, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, + g_leftover_converter_iface_init)) + +static void +g_leftover_converter_class_init (GLeftoverConverterClass *klass) +{ +} + +static void +g_leftover_converter_init (GLeftoverConverter *local) +{ +} + +GConverter * +g_leftover_converter_new (void) +{ + GConverter *conv; + + conv = g_object_new (G_TYPE_LEFTOVER_CONVERTER, NULL); + + return conv; +} + +static void +g_leftover_converter_reset (GConverter *converter) +{ +} + +static GConverterResult +g_leftover_converter_convert (GConverter *converter, + const void *inbuf, + gsize inbuf_size, + void *outbuf, + gsize outbuf_size, + GConverterFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + if (outbuf_size == LEFTOVER_SHORT_READ_SIZE) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_PARTIAL_INPUT, + "partial input"); + return G_CONVERTER_ERROR; + } + + if (inbuf_size < 100) + *bytes_read = *bytes_written = MIN (inbuf_size, outbuf_size); + else + *bytes_read = *bytes_written = MIN (inbuf_size - 10, outbuf_size); + memcpy (outbuf, inbuf, *bytes_written); + + if (*bytes_read == inbuf_size && (flags & G_CONVERTER_INPUT_AT_END)) + return G_CONVERTER_FINISHED; + return G_CONVERTER_CONVERTED; +} + +static void +g_leftover_converter_iface_init (GConverterIface *iface) +{ + iface->convert = g_leftover_converter_convert; + iface->reset = g_leftover_converter_reset; +} + +#define LEFTOVER_BUFSIZE 8192 +#define INTERNAL_BUFSIZE 4096 + +static void +test_converter_leftover (void) +{ + gchar *orig, *converted; + gsize total_read; + gssize res; + goffset offset; + GInputStream *mem, *cstream; + GConverter *converter; + GError *error; + int i; + + converter = g_leftover_converter_new (); + + orig = g_malloc (LEFTOVER_BUFSIZE); + converted = g_malloc (LEFTOVER_BUFSIZE); + for (i = 0; i < LEFTOVER_BUFSIZE; i++) + orig[i] = i % 64 + 32; + + mem = g_memory_input_stream_new_from_data (orig, LEFTOVER_BUFSIZE, NULL); + cstream = g_converter_input_stream_new (mem, G_CONVERTER (converter)); + g_object_unref (mem); + + total_read = 0; + + error = NULL; + res = g_input_stream_read (cstream, + converted, LEFTOVER_SHORT_READ_SIZE, + NULL, &error); + g_assert_cmpint (res, ==, LEFTOVER_SHORT_READ_SIZE); + total_read += res; + + offset = g_seekable_tell (G_SEEKABLE (mem)); + g_assert_cmpint (offset, >, LEFTOVER_SHORT_READ_SIZE); + g_assert_cmpint (offset, <, LEFTOVER_BUFSIZE); + + /* At this point, @cstream has both a non-empty input_buffer + * and a non-empty converted_buffer, which is the case + * we want to test. + */ + + while (TRUE) + { + error = NULL; + res = g_input_stream_read (cstream, + converted + total_read, + LEFTOVER_BUFSIZE - total_read, + NULL, &error); + g_assert_cmpint (res, >=, 0); + if (res == 0) + break; + total_read += res; + } + + g_assert_cmpmem (orig, LEFTOVER_BUFSIZE, converted, total_read); + + g_object_unref (cstream); + g_free (orig); + g_free (converted); + g_object_unref (converter); +} + +#define DATA_LENGTH 1000000 + +typedef struct { + const gchar *path; + GZlibCompressorFormat format; + gint level; +} CompressorTest; + +static void +test_roundtrip (gconstpointer data) +{ + const CompressorTest *test = data; + GError *error = NULL; + guint32 *data0, *data1; + gsize data1_size; + gint i; + GInputStream *istream0, *istream1, *cistream1; + GOutputStream *ostream1, *ostream2, *costream1; + GConverter *compressor, *decompressor; + GZlibCompressorFormat fmt; + gint lvl; + GFileInfo *info; + GFileInfo *info2; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=619945"); + + data0 = g_malloc (DATA_LENGTH * sizeof (guint32)); + for (i = 0; i < DATA_LENGTH; i++) + data0[i] = g_random_int (); + + istream0 = g_memory_input_stream_new_from_data (data0, + DATA_LENGTH * sizeof (guint32), NULL); + + ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + compressor = G_CONVERTER (g_zlib_compressor_new (test->format, test->level)); + info = g_file_info_new (); + g_file_info_set_name (info, "foo"); + g_object_set (compressor, "file-info", info, NULL); + info2 = g_zlib_compressor_get_file_info (G_ZLIB_COMPRESSOR (compressor)); + g_assert_true (info == info2); + g_object_unref (info); + costream1 = g_converter_output_stream_new (ostream1, compressor); + g_assert_true (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (costream1)) == compressor); + + g_output_stream_splice (costream1, istream0, 0, NULL, &error); + g_assert_no_error (error); + + g_object_unref (costream1); + + g_converter_reset (compressor); + g_object_get (compressor, "format", &fmt, "level", &lvl, NULL); + g_assert_cmpint (fmt, ==, test->format); + g_assert_cmpint (lvl, ==, test->level); + g_object_unref (compressor); + data1 = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream1)); + data1_size = g_memory_output_stream_get_data_size ( + G_MEMORY_OUTPUT_STREAM (ostream1)); + g_object_unref (ostream1); + g_object_unref (istream0); + + istream1 = g_memory_input_stream_new_from_data (data1, data1_size, g_free); + decompressor = G_CONVERTER (g_zlib_decompressor_new (test->format)); + cistream1 = g_converter_input_stream_new (istream1, decompressor); + + ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + + g_output_stream_splice (ostream2, cistream1, 0, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpmem (data0, DATA_LENGTH * sizeof (guint32), + g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (ostream2)), + g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream2))); + g_object_unref (istream1); + g_converter_reset (decompressor); + g_object_get (decompressor, "format", &fmt, NULL); + g_assert_cmpint (fmt, ==, test->format); + g_object_unref (decompressor); + g_object_unref (cistream1); + g_object_unref (ostream2); + g_free (data0); +} + +typedef struct { + const gchar *path; + const gchar *charset_in; + const gchar *text_in; + const gchar *charset_out; + const gchar *text_out; + gint n_fallbacks; +} CharsetTest; + +static void +test_charset (gconstpointer data) +{ + const CharsetTest *test = data; + GInputStream *in, *in2; + GConverter *conv; + gchar *buffer; + gsize count; + gsize bytes_read; + GError *error; + gboolean fallback; + + conv = (GConverter *)g_charset_converter_new (test->charset_out, test->charset_in, NULL); + g_object_get (conv, "use-fallback", &fallback, NULL); + g_assert_false (fallback); + + in = g_memory_input_stream_new_from_data (test->text_in, -1, NULL); + in2 = g_converter_input_stream_new (in, conv); + + count = 2 * strlen (test->text_out); + buffer = g_malloc0 (count); + error = NULL; + g_input_stream_read_all (in2, buffer, count, &bytes_read, NULL, &error); + if (test->n_fallbacks == 0) + { + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, strlen (test->text_out)); + g_assert_cmpstr (buffer, ==, test->text_out); + } + else + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA); + g_error_free (error); + } + + g_free (buffer); + g_object_unref (in2); + g_object_unref (in); + + if (test->n_fallbacks == 0) + { + g_object_unref (conv); + return; + } + + g_converter_reset (conv); + + g_assert_false (g_charset_converter_get_use_fallback (G_CHARSET_CONVERTER (conv))); + g_charset_converter_set_use_fallback (G_CHARSET_CONVERTER (conv), TRUE); + + in = g_memory_input_stream_new_from_data (test->text_in, -1, NULL); + in2 = g_converter_input_stream_new (in, conv); + + count = 2 * strlen (test->text_out); + buffer = g_malloc0 (count); + error = NULL; + g_input_stream_read_all (in2, buffer, count, &bytes_read, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (buffer, ==, test->text_out); + g_assert_cmpint (bytes_read, ==, strlen (test->text_out)); + g_assert_cmpint (test->n_fallbacks, ==, g_charset_converter_get_num_fallbacks (G_CHARSET_CONVERTER (conv))); + + g_free (buffer); + g_object_unref (in2); + g_object_unref (in); + + g_object_unref (conv); +} + + +static void +client_connected (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSocketClient *client = G_SOCKET_CLIENT (source); + GSocketConnection **conn = user_data; + GError *error = NULL; + + *conn = g_socket_client_connect_finish (client, result, &error); + g_assert_no_error (error); +} + +static void +server_connected (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSocketListener *listener = G_SOCKET_LISTENER (source); + GSocketConnection **conn = user_data; + GError *error = NULL; + + *conn = g_socket_listener_accept_finish (listener, result, NULL, &error); + g_assert_no_error (error); +} + +static void +make_socketpair (GIOStream **left, + GIOStream **right) +{ + GInetAddress *iaddr; + GSocketAddress *saddr, *effective_address; + GSocketListener *listener; + GSocketClient *client; + GError *error = NULL; + GSocketConnection *client_conn = NULL, *server_conn = NULL; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + listener = g_socket_listener_new (); + g_socket_listener_add_address (listener, saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &effective_address, + &error); + g_assert_no_error (error); + g_object_unref (saddr); + + client = g_socket_client_new (); + + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (effective_address), + NULL, client_connected, &client_conn); + g_socket_listener_accept_async (listener, NULL, + server_connected, &server_conn); + + while (!client_conn || !server_conn) + g_main_context_iteration (NULL, TRUE); + + g_object_unref (client); + g_object_unref (listener); + g_object_unref (effective_address); + + *left = G_IO_STREAM (client_conn); + *right = G_IO_STREAM (server_conn); +} + +static void +test_converter_pollable (void) +{ + GIOStream *left, *right; + guint8 *converted, *inptr; + guint8 *expanded, *outptr, *expanded_end; + gsize n_read, expanded_size; + gsize total_read; + gssize res; + gboolean is_readable; + GConverterResult cres; + GInputStream *cstream; + GPollableInputStream *pollable_in; + GOutputStream *socket_out, *mem_out, *cstream_out; + GPollableOutputStream *pollable_out; + GConverter *expander, *compressor; + GError *error; + gsize i; + + expander = g_expander_converter_new (); + expanded = g_malloc (100*1000); /* Large enough */ + cres = g_converter_convert (expander, + unexpanded_data, sizeof(unexpanded_data), + expanded, 100*1000, + G_CONVERTER_INPUT_AT_END, + &n_read, &expanded_size, NULL); + g_assert_cmpint (cres, ==, G_CONVERTER_FINISHED); + g_assert_cmpuint (n_read, ==, 11); + g_assert_cmpuint (expanded_size, ==, 41030); + expanded_end = expanded + expanded_size; + + make_socketpair (&left, &right); + + compressor = g_compressor_converter_new (); + + converted = g_malloc (100*1000); /* Large enough */ + + cstream = g_converter_input_stream_new (g_io_stream_get_input_stream (left), + compressor); + pollable_in = G_POLLABLE_INPUT_STREAM (cstream); + g_assert_true (g_pollable_input_stream_can_poll (pollable_in)); + + socket_out = g_io_stream_get_output_stream (right); + + total_read = 0; + outptr = expanded; + inptr = converted; + while (TRUE) + { + error = NULL; + + if (outptr < expanded_end) + { + res = g_output_stream_write (socket_out, + outptr, + MIN (1000, (expanded_end - outptr)), + NULL, &error); + g_assert_cmpint (res, >, 0); + outptr += res; + } + else if (socket_out) + { + g_output_stream_close (socket_out, NULL, NULL); + g_object_unref (right); + socket_out = NULL; + } + + /* Wait a few ticks to check for the pipe to propagate the + * write. We can’t wait on a GSource as that might affect the stream under + * test, so just poll. */ + while (!g_pollable_input_stream_is_readable (pollable_in)) + g_usleep (80L); + + is_readable = g_pollable_input_stream_is_readable (pollable_in); + res = g_pollable_input_stream_read_nonblocking (pollable_in, + inptr, 1, + NULL, &error); + + /* is_readable can be a false positive, but not a false negative */ + if (!is_readable) + g_assert_cmpint (res, ==, -1); + + /* After closing the write end, we can't get WOULD_BLOCK any more */ + if (!socket_out) + { + g_assert_no_error (error); + g_assert_cmpint (res, !=, -1); + } + + if (res == -1) + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_error_free (error); + + continue; + } + + if (res == 0) + break; + inptr += res; + total_read += res; + } + + /* "n_read - 1" because last 2 zeros are combined */ + g_assert_cmpmem (unexpanded_data, n_read - 1, converted, total_read); + + g_object_unref (cstream); + g_object_unref (left); + + g_converter_reset (compressor); + + /* This doesn't actually test the behavior on + * G_IO_ERROR_WOULD_BLOCK; to do that we'd need to implement a + * custom GOutputStream that we could control blocking on. + */ + + mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + cstream_out = g_converter_output_stream_new (mem_out, compressor); + g_object_unref (mem_out); + pollable_out = G_POLLABLE_OUTPUT_STREAM (cstream_out); + g_assert_true (g_pollable_output_stream_can_poll (pollable_out)); + g_assert_true (g_pollable_output_stream_is_writable (pollable_out)); + + for (i = 0; i < expanded_size; i++) + { + error = NULL; + res = g_pollable_output_stream_write_nonblocking (pollable_out, + expanded + i, 1, + NULL, &error); + g_assert_cmpint (res, !=, -1); + if (res == 0) + { + g_assert_cmpuint (i, ==, expanded_size -1); + break; + } + g_assert_cmpint (res, ==, 1); + } + + g_output_stream_close (cstream_out, NULL, NULL); + + /* "n_read - 1" because last 2 zeros are combined */ + g_assert_cmpmem (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)), + g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)), + unexpanded_data, + n_read - 1); + + g_object_unref (cstream_out); + + g_free (expanded); + g_free (converted); + g_object_unref (expander); + g_object_unref (compressor); +} + +static void +test_truncation (gconstpointer data) +{ + const CompressorTest *test = data; + GError *error = NULL; + guint32 *data0, *data1; + gsize data1_size; + gint i; + GInputStream *istream0, *istream1, *cistream1; + GOutputStream *ostream1, *ostream2, *costream1; + GConverter *compressor, *decompressor; + + data0 = g_malloc (DATA_LENGTH * sizeof (guint32)); + for (i = 0; i < DATA_LENGTH; i++) + data0[i] = g_random_int (); + + istream0 = g_memory_input_stream_new_from_data (data0, + DATA_LENGTH * sizeof (guint32), NULL); + + ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + compressor = G_CONVERTER (g_zlib_compressor_new (test->format, -1)); + costream1 = g_converter_output_stream_new (ostream1, compressor); + g_assert_true (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (costream1)) == compressor); + + g_output_stream_splice (costream1, istream0, 0, NULL, &error); + g_assert_no_error (error); + + g_object_unref (costream1); + g_object_unref (compressor); + + data1 = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream1)); + data1_size = g_memory_output_stream_get_data_size ( + G_MEMORY_OUTPUT_STREAM (ostream1)); + g_object_unref (ostream1); + g_object_unref (istream0); + + /* truncate */ + data1_size /= 2; + + istream1 = g_memory_input_stream_new_from_data (data1, data1_size, g_free); + decompressor = G_CONVERTER (g_zlib_decompressor_new (test->format)); + cistream1 = g_converter_input_stream_new (istream1, decompressor); + + ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + + g_output_stream_splice (ostream2, cistream1, 0, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT); + g_error_free (error); + + g_object_unref (istream1); + g_object_unref (decompressor); + g_object_unref (cistream1); + g_object_unref (ostream2); + g_free (data0); +} + +static void +test_converter_basics (void) +{ + GConverter *converter; + GError *error = NULL; + gchar *to; + gchar *from; + + converter = (GConverter *)g_charset_converter_new ("utf-8", "latin1", &error); + g_assert_no_error (error); + g_object_get (converter, + "to-charset", &to, + "from-charset", &from, + NULL); + + g_assert_cmpstr (to, ==, "utf-8"); + g_assert_cmpstr (from, ==, "latin1"); + + g_free (to); + g_free (from); + g_object_unref (converter); +} + +int +main (int argc, + char *argv[]) +{ + CompressorTest compressor_tests[] = { + { "/converter-output-stream/roundtrip/zlib-0", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 }, + { "/converter-output-stream/roundtrip/zlib-9", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9 }, + { "/converter-output-stream/roundtrip/gzip-0", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 }, + { "/converter-output-stream/roundtrip/gzip-9", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 9 }, + { "/converter-output-stream/roundtrip/raw-0", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 }, + { "/converter-output-stream/roundtrip/raw-9", G_ZLIB_COMPRESSOR_FORMAT_RAW, 9 }, + }; + CompressorTest truncation_tests[] = { + { "/converter-input-stream/truncation/zlib", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 }, + { "/converter-input-stream/truncation/gzip", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 }, + { "/converter-input-stream/truncation/raw", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 }, + }; + CharsetTest charset_tests[] = { + { "/converter-input-stream/charset/utf8->latin1", "UTF-8", "\303\205rr Sant\303\251", "ISO-8859-1", "\305rr Sant\351", 0 }, + { "/converter-input-stream/charset/latin1->utf8", "ISO-8859-1", "\305rr Sant\351", "UTF-8", "\303\205rr Sant\303\251", 0 }, + { "/converter-input-stream/charset/fallbacks", "UTF-8", "Some characters just don't fit into latin1: Ï€×", "ISO-8859-1", "Some characters just don't fit into latin1: \\CF\\80\\D7\\90", 4 }, + }; + + gsize i; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/converter/basics", test_converter_basics); + g_test_add_func ("/converter-input-stream/expander", test_expander); + g_test_add_func ("/converter-input-stream/compressor", test_compressor); + + for (i = 0; i < G_N_ELEMENTS (compressor_tests); i++) + g_test_add_data_func (compressor_tests[i].path, &compressor_tests[i], test_roundtrip); + + for (i = 0; i < G_N_ELEMENTS (truncation_tests); i++) + g_test_add_data_func (truncation_tests[i].path, &truncation_tests[i], test_truncation); + + for (i = 0; i < G_N_ELEMENTS (charset_tests); i++) + g_test_add_data_func (charset_tests[i].path, &charset_tests[i], test_charset); + + g_test_add_func ("/converter-stream/pollable", test_converter_pollable); + g_test_add_func ("/converter-stream/leftover", test_converter_leftover); + + return g_test_run(); +} diff --git a/gio/tests/credentials.c b/gio/tests/credentials.c new file mode 100644 index 0000000..070019f --- /dev/null +++ b/gio/tests/credentials.c @@ -0,0 +1,213 @@ +/* GLib testing framework examples and tests + * + * Copyright © 2012 Collabora Ltd. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "config.h" + +#include +#include + +#ifdef G_OS_WIN32 + +static void +test_basic (void) +{ + GCredentials *creds = g_credentials_new (); + gchar *stringified; + DWORD *pid; + + stringified = g_credentials_to_string (creds); + g_test_message ("%s", stringified); + g_free (stringified); + + pid = g_credentials_get_native (creds, + G_CREDENTIALS_TYPE_WIN32_PID); + g_assert_cmpuint (*pid, ==, GetCurrentProcessId ()); + + g_object_unref (creds); +} + +#else + +static void +test_basic (void) +{ + GCredentials *creds = g_credentials_new (); + GCredentials *other = g_credentials_new (); + gpointer bad_native_creds; +#if G_CREDENTIALS_SUPPORTED + GError *error = NULL; + gboolean set; + pid_t not_me; + gchar *stringified; +#endif + + /* You can always get a credentials object, but it might not work. */ + g_assert (creds != NULL); + g_assert (other != NULL); + +#if G_CREDENTIALS_SUPPORTED + g_assert (g_credentials_is_same_user (creds, other, &error)); + g_assert_no_error (error); + + if (geteuid () == 0) + not_me = 65534; /* traditionally 'nobody' */ + else + not_me = 0; + + g_assert_cmpuint (g_credentials_get_unix_user (creds, &error), ==, + geteuid ()); + g_assert_no_error (error); + +#if G_CREDENTIALS_HAS_PID + g_assert_cmpint (g_credentials_get_unix_pid (creds, &error), ==, + getpid ()); + g_assert_no_error (error); +#else + g_assert_cmpint (g_credentials_get_unix_pid (creds, &error), ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); +#endif + + set = g_credentials_set_unix_user (other, not_me, &error); +#if G_CREDENTIALS_SPOOFING_SUPPORTED + g_assert_no_error (error); + g_assert (set); + + g_assert_cmpuint (g_credentials_get_unix_user (other, &error), ==, not_me); + g_assert (!g_credentials_is_same_user (creds, other, &error)); + g_assert_no_error (error); +#else + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED); + g_assert (!set); + g_clear_error (&error); + + g_assert_cmpuint (g_credentials_get_unix_user (other, &error), ==, geteuid ()); + g_assert (g_credentials_is_same_user (creds, other, &error)); + g_assert_no_error (error); +#endif + + stringified = g_credentials_to_string (creds); + g_test_message ("%s", stringified); + g_free (stringified); + + stringified = g_credentials_to_string (other); + g_test_message ("%s", stringified); + g_free (stringified); + +#if G_CREDENTIALS_USE_LINUX_UCRED + { + struct ucred *native = g_credentials_get_native (creds, + G_CREDENTIALS_TYPE_LINUX_UCRED); + + g_assert_cmpuint (native->uid, ==, geteuid ()); + g_assert_cmpuint (native->pid, ==, getpid ()); + } +#elif G_CREDENTIALS_USE_APPLE_XUCRED + { + struct xucred *native = g_credentials_get_native (creds, + G_CREDENTIALS_TYPE_APPLE_XUCRED); + + g_assert_cmpuint (native->cr_version, ==, XUCRED_VERSION); + g_assert_cmpuint (native->cr_uid, ==, geteuid ()); + } +#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED + { + struct cmsgcred *native = g_credentials_get_native (creds, + G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED); + + g_assert_cmpuint (native->cmcred_euid, ==, geteuid ()); + g_assert_cmpuint (native->cmcred_pid, ==, getpid ()); + } +#elif G_CREDENTIALS_USE_NETBSD_UNPCBID + { + struct unpcbid *native = g_credentials_get_native (creds, + G_CREDENTIALS_TYPE_NETBSD_UNPCBID); + + g_assert_cmpuint (native->unp_euid, ==, geteuid ()); + g_assert_cmpuint (native->unp_pid, ==, getpid ()); + } +#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED + { + struct sockpeercred *native = g_credentials_get_native (creds, + G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED); + + g_assert_cmpuint (native->uid, ==, geteuid ()); + g_assert_cmpuint (native->pid, ==, getpid ()); + } +#elif G_CREDENTIALS_USE_SOLARIS_UCRED + { + ucred_t *native = g_credentials_get_native (creds, + G_CREDENTIALS_TYPE_SOLARIS_UCRED); + + g_assert_cmpuint (ucred_geteuid (native), ==, geteuid ()); + g_assert_cmpuint (ucred_getpid (native), ==, getpid ()); + } +#else +#error "G_CREDENTIALS_SUPPORTED is set but there is no test for this platform" +#endif + + +#if G_CREDENTIALS_USE_LINUX_UCRED + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*g_credentials_get_native: Trying to get*" + "G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED " + "but only G_CREDENTIALS_TYPE_LINUX_UCRED*" + "supported*"); + bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED); + g_test_assert_expected_messages (); + g_assert_null (bad_native_creds); +#else + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*g_credentials_get_native: Trying to get*" + "G_CREDENTIALS_TYPE_LINUX_UCRED " + "but only G_CREDENTIALS_TYPE_*supported*"); + bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_LINUX_UCRED); + g_test_assert_expected_messages (); + g_assert_null (bad_native_creds); +#endif + +#else /* ! G_CREDENTIALS_SUPPORTED */ + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*g_credentials_get_native: Trying to get " + "credentials *but*no support*"); + bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_LINUX_UCRED); + g_test_assert_expected_messages (); + g_assert_null (bad_native_creds); +#endif + + g_object_unref (creds); + g_object_unref (other); +} + +#endif /* !G_OS_WIN32 */ + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/credentials/basic", test_basic); + + return g_test_run(); +} diff --git a/gio/tests/cxx.cpp b/gio/tests/cxx.cpp new file mode 100644 index 0000000..1f28d0b --- /dev/null +++ b/gio/tests/cxx.cpp @@ -0,0 +1,26 @@ +/* Copyright (C) 2001 Sebastian Wilhelmi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +/* A trivial C++ program to be compiled in C++ mode, which + * smoketests that the GIO headers are valid C++ headers. */ + +#include + +int +main () +{ + return 0; +} diff --git a/gio/tests/data-input-stream.c b/gio/tests/data-input-stream.c new file mode 100644 index 0000000..0d59cac --- /dev/null +++ b/gio/tests/data-input-stream.c @@ -0,0 +1,507 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc. + * Authors: Tomas Bzatek + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +#define MAX_LINES 0xFFF +#define MAX_BYTES 0x10000 + +static void +test_basic (void) +{ + GInputStream *stream; + GInputStream *base_stream; + gint val; + + base_stream = g_memory_input_stream_new (); + stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream)); + + g_object_get (stream, "byte-order", &val, NULL); + g_assert_cmpint (val, ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + g_object_set (stream, "byte-order", G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN, NULL); + g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); + + g_object_get (stream, "newline-type", &val, NULL); + g_assert_cmpint (val, ==, G_DATA_STREAM_NEWLINE_TYPE_LF); + g_object_set (stream, "newline-type", G_DATA_STREAM_NEWLINE_TYPE_CR_LF, NULL); + g_assert_cmpint (g_data_input_stream_get_newline_type (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); + + g_object_unref (stream); + g_object_unref (base_stream); +} + +static void +test_seek_to_start (GInputStream *stream) +{ + GError *error = NULL; + gboolean res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error); + g_assert_cmpint (res, ==, TRUE); + g_assert_no_error (error); +} + +static void +test_read_lines (GDataStreamNewlineType newline_type) +{ + GInputStream *stream; + GInputStream *base_stream; + GError *error = NULL; + char *data; + int line; + const char* lines[MAX_LINES]; + const char* endl[4] = {"\n", "\r", "\r\n", "\n"}; + + /* prepare data */ + int i; + for (i = 0; i < MAX_LINES; i++) + lines[i] = "some_text"; + + base_stream = g_memory_input_stream_new (); + g_assert (base_stream != NULL); + stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream)); + g_assert(stream != NULL); + + /* Byte order testing */ + g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); + g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); + + /* Line ends testing */ + g_data_input_stream_set_newline_type (G_DATA_INPUT_STREAM (stream), newline_type); + g_assert_cmpint (g_data_input_stream_get_newline_type (G_DATA_INPUT_STREAM (stream)), ==, newline_type); + + + /* Add sample data */ + for (i = 0; i < MAX_LINES; i++) + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), + g_strconcat (lines[i], endl[newline_type], NULL), -1, g_free); + + /* Seek to the start */ + test_seek_to_start (base_stream); + + /* Test read line */ + error = NULL; + data = (char*)1; + line = 0; + while (data) + { + gsize length = -1; + data = g_data_input_stream_read_line (G_DATA_INPUT_STREAM (stream), &length, NULL, &error); + if (data) + { + g_assert_cmpstr (data, ==, lines[line]); + g_free (data); + g_assert_no_error (error); + line++; + } + if (error) + g_error_free (error); + } + g_assert_cmpint (line, ==, MAX_LINES); + + + g_object_unref (base_stream); + g_object_unref (stream); +} + +static void +test_read_lines_LF (void) +{ + test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_LF); +} + +static void +test_read_lines_CR (void) +{ + test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR); +} + +static void +test_read_lines_CR_LF (void) +{ + test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR_LF); +} + +static void +test_read_lines_any (void) +{ + test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_ANY); +} + +static void +test_read_lines_LF_valid_utf8 (void) +{ + GInputStream *stream; + GInputStream *base_stream; + GError *error = NULL; + char *line; + guint n_lines = 0; + + base_stream = g_memory_input_stream_new (); + stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream)); + + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), + "foo\nthis is valid UTF-8 ☺!\nbar\n", -1, NULL); + + /* Test read line */ + error = NULL; + while (TRUE) + { + gsize length = -1; + line = g_data_input_stream_read_line_utf8 (G_DATA_INPUT_STREAM (stream), &length, NULL, &error); + g_assert_no_error (error); + if (line == NULL) + break; + n_lines++; + g_free (line); + } + g_assert_cmpint (n_lines, ==, 3); + + g_object_unref (base_stream); + g_object_unref (stream); +} + +static void +test_read_lines_LF_invalid_utf8 (void) +{ + GInputStream *stream; + GInputStream *base_stream; + GError *error = NULL; + char *line; + guint n_lines = 0; + + base_stream = g_memory_input_stream_new (); + stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream)); + + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), + "foo\nthis is not valid UTF-8 \xE5 =(\nbar\n", -1, NULL); + + /* Test read line */ + error = NULL; + while (TRUE) + { + gsize length = -1; + line = g_data_input_stream_read_line_utf8 (G_DATA_INPUT_STREAM (stream), &length, NULL, &error); + if (n_lines == 0) + g_assert_no_error (error); + else + { + g_assert (error != NULL); + g_clear_error (&error); + g_free (line); + break; + } + n_lines++; + g_free (line); + } + g_assert_cmpint (n_lines, ==, 1); + + g_object_unref (base_stream); + g_object_unref (stream); +} + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +static void +test_read_until (void) +{ + GInputStream *stream; + GInputStream *base_stream; + GError *error = NULL; + char *data; + int line; + int i; + +#define REPEATS 10 /* number of rounds */ +#define DATA_STRING " part1 # part2 $ part3 % part4 ^" +#define DATA_PART_LEN 7 /* number of characters between separators */ +#define DATA_SEP "#$%^" +#define DATA_SEP_LEN 4 + const int DATA_PARTS_NUM = DATA_SEP_LEN * REPEATS; + + base_stream = g_memory_input_stream_new (); + stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream)); + + for (i = 0; i < REPEATS; i++) + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), DATA_STRING, -1, NULL); + + /* Test stop characters */ + error = NULL; + data = (char*)1; + line = 0; + while (data) + { + gsize length = -1; + data = g_data_input_stream_read_until (G_DATA_INPUT_STREAM (stream), DATA_SEP, &length, NULL, &error); + if (data) + { + g_assert_cmpint (strlen (data), ==, DATA_PART_LEN); + g_free (data); + g_assert_no_error (error); + line++; + } + } + g_assert_no_error (error); + g_assert_cmpint (line, ==, DATA_PARTS_NUM); + + g_object_unref (base_stream); + g_object_unref (stream); +} + +G_GNUC_END_IGNORE_DEPRECATIONS + +static void +test_read_upto (void) +{ + GInputStream *stream; + GInputStream *base_stream; + GError *error = NULL; + char *data; + int line; + int i; + guchar stop_char; + +#undef REPEATS +#undef DATA_STRING +#undef DATA_PART_LEN +#undef DATA_SEP +#undef DATA_SEP_LEN +#define REPEATS 10 /* number of rounds */ +#define DATA_STRING " part1 # part2 $ part3 \0 part4 ^" +#define DATA_PART_LEN 7 /* number of characters between separators */ +#define DATA_SEP "#$\0^" +#define DATA_SEP_LEN 4 + const int DATA_PARTS_NUM = DATA_SEP_LEN * REPEATS; + + base_stream = g_memory_input_stream_new (); + stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream)); + + for (i = 0; i < REPEATS; i++) + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), DATA_STRING, 32, NULL); + + /* Test stop characters */ + error = NULL; + data = (char*)1; + line = 0; + while (data) + { + gsize length = -1; + data = g_data_input_stream_read_upto (G_DATA_INPUT_STREAM (stream), DATA_SEP, DATA_SEP_LEN, &length, NULL, &error); + if (data) + { + g_assert_cmpint (strlen (data), ==, DATA_PART_LEN); + g_assert_no_error (error); + line++; + + stop_char = g_data_input_stream_read_byte (G_DATA_INPUT_STREAM (stream), NULL, &error); + g_assert (memchr (DATA_SEP, stop_char, DATA_SEP_LEN) != NULL); + g_assert_no_error (error); + } + g_free (data); + } + g_assert_no_error (error); + g_assert_cmpint (line, ==, DATA_PARTS_NUM); + + g_object_unref (base_stream); + g_object_unref (stream); +} +enum TestDataType { + TEST_DATA_BYTE = 0, + TEST_DATA_INT16, + TEST_DATA_UINT16, + TEST_DATA_INT32, + TEST_DATA_UINT32, + TEST_DATA_INT64, + TEST_DATA_UINT64 +}; + +/* The order is reversed to avoid -Wduplicated-branches. */ +#define TEST_DATA_RETYPE_BUFF(a, t, v) \ + (a == TEST_DATA_UINT64 ? (t) *(guint64*)v : \ + (a == TEST_DATA_INT64 ? (t) *(gint64*)v : \ + (a == TEST_DATA_UINT32 ? (t) *(guint32*)v : \ + (a == TEST_DATA_INT32 ? (t) *(gint32*)v : \ + (a == TEST_DATA_UINT16 ? (t) *(guint16*)v : \ + (a == TEST_DATA_INT16 ? (t) *(gint16*)v : \ + (t) *(guchar*)v )))))) + + +static void +test_data_array (GInputStream *stream, GInputStream *base_stream, + gpointer buffer, int len, + enum TestDataType data_type, GDataStreamByteOrder byte_order) +{ + GError *error = NULL; + int pos = 0; + int data_size = 1; + gint64 data; + GDataStreamByteOrder native; + gboolean swap; + + /* Seek to start */ + test_seek_to_start (base_stream); + + /* Set correct data size */ + switch (data_type) + { + case TEST_DATA_BYTE: + data_size = 1; + break; + case TEST_DATA_INT16: + case TEST_DATA_UINT16: + data_size = 2; + break; + case TEST_DATA_INT32: + case TEST_DATA_UINT32: + data_size = 4; + break; + case TEST_DATA_INT64: + case TEST_DATA_UINT64: + data_size = 8; + break; + default: + g_assert_not_reached (); + break; + } + + /* Set flag to swap bytes if needed */ + native = (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN : G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN; + swap = (byte_order != G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN) && (byte_order != native); + + data = 1; + while (data != 0) + { + switch (data_type) + { + case TEST_DATA_BYTE: + data = g_data_input_stream_read_byte (G_DATA_INPUT_STREAM (stream), NULL, &error); + break; + case TEST_DATA_INT16: + data = g_data_input_stream_read_int16 (G_DATA_INPUT_STREAM (stream), NULL, &error); + if (swap) + data = (gint16)GUINT16_SWAP_LE_BE((gint16)data); + break; + case TEST_DATA_UINT16: + data = g_data_input_stream_read_uint16 (G_DATA_INPUT_STREAM (stream), NULL, &error); + if (swap) + data = (guint16)GUINT16_SWAP_LE_BE((guint16)data); + break; + case TEST_DATA_INT32: + data = g_data_input_stream_read_int32 (G_DATA_INPUT_STREAM (stream), NULL, &error); + if (swap) + data = (gint32)GUINT32_SWAP_LE_BE((gint32)data); + break; + case TEST_DATA_UINT32: + data = g_data_input_stream_read_uint32 (G_DATA_INPUT_STREAM (stream), NULL, &error); + if (swap) + data = (guint32)GUINT32_SWAP_LE_BE((guint32)data); + break; + case TEST_DATA_INT64: + data = g_data_input_stream_read_int64 (G_DATA_INPUT_STREAM (stream), NULL, &error); + if (swap) + data = (gint64)GUINT64_SWAP_LE_BE((gint64)data); + break; + case TEST_DATA_UINT64: + data = g_data_input_stream_read_uint64 (G_DATA_INPUT_STREAM (stream), NULL, &error); + if (swap) + data = (guint64)GUINT64_SWAP_LE_BE((guint64)data); + break; + default: + g_assert_not_reached (); + break; + } + if (!error) + g_assert_cmpint (data, ==, TEST_DATA_RETYPE_BUFF(data_type, gint64, ((guchar*)buffer + pos))); + + pos += data_size; + } + if (pos < len + 1) + g_assert_no_error (error); + if (error) + g_error_free (error); + g_assert_cmpint (pos - data_size, ==, len); +} + +static void +test_read_int (void) +{ + GInputStream *stream; + GInputStream *base_stream; + GRand *randomizer; + int i; + gpointer buffer; + + randomizer = g_rand_new (); + buffer = g_malloc0 (MAX_BYTES); + + /* Fill in some random data */ + for (i = 0; i < MAX_BYTES; i++) + { + guchar x = 0; + while (! x) + x = (guchar)g_rand_int (randomizer); + *(guchar*)((guchar*)buffer + sizeof(guchar) * i) = x; + } + + base_stream = g_memory_input_stream_new (); + stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream)); + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), buffer, MAX_BYTES, NULL); + + + for (i = 0; i < 3; i++) + { + int j; + g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), i); + + for (j = 0; j <= TEST_DATA_UINT64; j++) + test_data_array (stream, base_stream, buffer, MAX_BYTES, j, i); + } + + g_object_unref (base_stream); + g_object_unref (stream); + g_rand_free (randomizer); + g_free (buffer); +} + + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/data-input-stream/basic", test_basic); + g_test_add_func ("/data-input-stream/read-lines-LF", test_read_lines_LF); + g_test_add_func ("/data-input-stream/read-lines-LF-valid-utf8", test_read_lines_LF_valid_utf8); + g_test_add_func ("/data-input-stream/read-lines-LF-invalid-utf8", test_read_lines_LF_invalid_utf8); + g_test_add_func ("/data-input-stream/read-lines-CR", test_read_lines_CR); + g_test_add_func ("/data-input-stream/read-lines-CR-LF", test_read_lines_CR_LF); + g_test_add_func ("/data-input-stream/read-lines-any", test_read_lines_any); + g_test_add_func ("/data-input-stream/read-until", test_read_until); + g_test_add_func ("/data-input-stream/read-upto", test_read_upto); + g_test_add_func ("/data-input-stream/read-int", test_read_int); + + return g_test_run(); +} diff --git a/gio/tests/data-output-stream.c b/gio/tests/data-output-stream.c new file mode 100644 index 0000000..0872edf --- /dev/null +++ b/gio/tests/data-output-stream.c @@ -0,0 +1,514 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc. + * Authors: Tomas Bzatek + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +#define MAX_LINES 0xFFF +#define MAX_LINES_BUFF 0xFFFFFF +#define MAX_BYTES_BINARY 0x100 + +static void +test_basic (void) +{ + GOutputStream *stream; + GOutputStream *base_stream; + gpointer data; + gint val; + + data = g_malloc0 (MAX_LINES_BUFF); + + /* initialize objects */ + base_stream = g_memory_output_stream_new (data, MAX_LINES_BUFF, NULL, NULL); + stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream)); + + g_object_get (stream, "byte-order", &val, NULL); + g_assert_cmpint (val, ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + g_object_set (stream, "byte-order", G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN, NULL); + g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); + + g_object_unref (stream); + g_object_unref (base_stream); + g_free (data); +} + +static void +test_read_lines (GDataStreamNewlineType newline_type) +{ + GOutputStream *stream; + GOutputStream *base_stream; + GError *error = NULL; + gpointer data; + char *lines; + int size; + int i; + +#define TEST_STRING "some_text" + + const char* endl[4] = {"\n", "\r", "\r\n", "\n"}; + + + data = g_malloc0 (MAX_LINES_BUFF); + lines = g_malloc0 ((strlen (TEST_STRING) + strlen (endl[newline_type])) * MAX_LINES + 1); + + /* initialize objects */ + base_stream = g_memory_output_stream_new (data, MAX_LINES_BUFF, NULL, NULL); + stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream)); + + + /* fill data */ + for (i = 0; i < MAX_LINES; i++) + { + gboolean res; + char *s = g_strconcat (TEST_STRING, endl[newline_type], NULL); + res = g_data_output_stream_put_string (G_DATA_OUTPUT_STREAM (stream), s, NULL, &error); + g_stpcpy ((char*)(lines + i*strlen(s)), s); + g_assert_no_error (error); + g_assert (res == TRUE); + g_free (s); + } + + /* Byte order testing */ + g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); + g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); + + /* compare data */ + size = strlen (data); + g_assert_cmpint (size, <, MAX_LINES_BUFF); + g_assert_cmpstr ((char*)data, ==, lines); + + g_object_unref (base_stream); + g_object_unref (stream); + g_free (data); + g_free (lines); +} + +static void +test_read_lines_LF (void) +{ + test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_LF); +} + +static void +test_read_lines_CR (void) +{ + test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR); +} + +static void +test_read_lines_CR_LF (void) +{ + test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR_LF); +} + +enum TestDataType { + TEST_DATA_BYTE = 0, + TEST_DATA_INT16, + TEST_DATA_UINT16, + TEST_DATA_INT32, + TEST_DATA_UINT32, + TEST_DATA_INT64, + TEST_DATA_UINT64 +}; + +static void +test_data_array (guchar *buffer, gsize len, + enum TestDataType data_type, GDataStreamByteOrder byte_order) +{ + GOutputStream *stream; + GOutputStream *base_stream; + guchar *stream_data; + + GError *error = NULL; + guint pos; + GDataStreamByteOrder native; + gboolean swap; + gboolean res; + + /* create objects */ + stream_data = g_malloc0 (len); + base_stream = g_memory_output_stream_new (stream_data, len, NULL, NULL); + stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream)); + g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), byte_order); + + /* Set flag to swap bytes if needed */ + native = (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN : G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN; + swap = (byte_order != G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN) && (byte_order != native); + + /* set len to length of buffer cast to actual type */ + switch (data_type) + { + case TEST_DATA_BYTE: + break; + case TEST_DATA_INT16: + case TEST_DATA_UINT16: + g_assert_cmpint (len % 2, ==, 0); + G_GNUC_FALLTHROUGH; + case TEST_DATA_INT32: + case TEST_DATA_UINT32: + g_assert_cmpint (len % 4, ==, 0); + G_GNUC_FALLTHROUGH; + case TEST_DATA_INT64: + case TEST_DATA_UINT64: + g_assert_cmpint (len % 8, ==, 0); + len /= 8; + break; + default: + g_assert_not_reached (); + break; + } + + /* Write data to the file */ + for (pos = 0; pos < len; pos++) + { + switch (data_type) + { + case TEST_DATA_BYTE: + res = g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (stream), buffer[pos], NULL, &error); + break; + case TEST_DATA_INT16: + res = g_data_output_stream_put_int16 (G_DATA_OUTPUT_STREAM (stream), ((gint16 *) buffer)[pos], NULL, &error); + break; + case TEST_DATA_UINT16: + res = g_data_output_stream_put_uint16 (G_DATA_OUTPUT_STREAM (stream), ((guint16 *) buffer)[pos], NULL, &error); + break; + case TEST_DATA_INT32: + res = g_data_output_stream_put_int32 (G_DATA_OUTPUT_STREAM (stream), ((gint32 *) buffer)[pos], NULL, &error); + break; + case TEST_DATA_UINT32: + res = g_data_output_stream_put_uint32 (G_DATA_OUTPUT_STREAM (stream), ((guint32 *) buffer)[pos], NULL, &error); + break; + case TEST_DATA_INT64: + res = g_data_output_stream_put_int64 (G_DATA_OUTPUT_STREAM (stream), ((gint64 *) buffer)[pos], NULL, &error); + break; + case TEST_DATA_UINT64: + res = g_data_output_stream_put_uint64 (G_DATA_OUTPUT_STREAM (stream), ((guint64 *) buffer)[pos], NULL, &error); + break; + default: + g_assert_not_reached (); + break; + } + g_assert_no_error (error); + g_assert_cmpint (res, ==, TRUE); + } + + /* Compare data back */ + for (pos = 0; pos < len; pos++) + { + switch (data_type) + { + case TEST_DATA_BYTE: + /* swapping unnecessary */ + g_assert_cmpint (buffer[pos], ==, stream_data[pos]); + break; + case TEST_DATA_UINT16: + if (swap) + g_assert_cmpint (GUINT16_SWAP_LE_BE (((guint16 *) buffer)[pos]), ==, ((guint16 *) stream_data)[pos]); + else + g_assert_cmpint (((guint16 *) buffer)[pos], ==, ((guint16 *) stream_data)[pos]); + break; + case TEST_DATA_INT16: + if (swap) + g_assert_cmpint ((gint16) GUINT16_SWAP_LE_BE (((gint16 *) buffer)[pos]), ==, ((gint16 *) stream_data)[pos]); + else + g_assert_cmpint (((gint16 *) buffer)[pos], ==, ((gint16 *) stream_data)[pos]); + break; + case TEST_DATA_UINT32: + if (swap) + g_assert_cmpint (GUINT32_SWAP_LE_BE (((guint32 *) buffer)[pos]), ==, ((guint32 *) stream_data)[pos]); + else + g_assert_cmpint (((guint32 *) buffer)[pos], ==, ((guint32 *) stream_data)[pos]); + break; + case TEST_DATA_INT32: + if (swap) + g_assert_cmpint ((gint32) GUINT32_SWAP_LE_BE (((gint32 *) buffer)[pos]), ==, ((gint32 *) stream_data)[pos]); + else + g_assert_cmpint (((gint32 *) buffer)[pos], ==, ((gint32 *) stream_data)[pos]); + break; + case TEST_DATA_UINT64: + if (swap) + g_assert_cmpint (GUINT64_SWAP_LE_BE (((guint64 *) buffer)[pos]), ==, ((guint64 *) stream_data)[pos]); + else + g_assert_cmpint (((guint64 *) buffer)[pos], ==, ((guint64 *) stream_data)[pos]); + break; + case TEST_DATA_INT64: + if (swap) + g_assert_cmpint ((gint64) GUINT64_SWAP_LE_BE (((gint64 *) buffer)[pos]), ==, ((gint64 *) stream_data)[pos]); + else + g_assert_cmpint (((gint64 *) buffer)[pos], ==, ((gint64 *) stream_data)[pos]); + break; + default: + g_assert_not_reached (); + break; + } + } + + g_object_unref (base_stream); + g_object_unref (stream); + g_free (stream_data); +} + +static void +test_read_int (void) +{ + GRand *randomizer; + gpointer buffer; + int i; + + randomizer = g_rand_new (); + buffer = g_malloc0(MAX_BYTES_BINARY); + + /* Fill in some random data */ + for (i = 0; i < MAX_BYTES_BINARY; i++) + { + guchar x = 0; + while (! x) x = (guchar)g_rand_int (randomizer); + *(guchar*)((guchar*)buffer + sizeof (guchar) * i) = x; + } + + for (i = 0; i < 3; i++) + { + int j; + for (j = 0; j <= TEST_DATA_UINT64; j++) + test_data_array (buffer, MAX_BYTES_BINARY, j, i); + } + + g_rand_free (randomizer); + g_free (buffer); +} + +static void +test_seek (void) +{ + GDataOutputStream *stream; + GMemoryOutputStream *base_stream; + GSeekable *seekable; + GError *error; + guchar *stream_data; + gsize len; + gboolean res; + + len = 8; + + /* create objects */ + stream_data = g_malloc0 (len); + base_stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (stream_data, len, NULL, NULL)); + stream = g_data_output_stream_new (G_OUTPUT_STREAM (base_stream)); + g_data_output_stream_set_byte_order (stream, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + seekable = G_SEEKABLE (stream); + g_assert (!g_seekable_can_truncate (seekable)); + error = NULL; + + /* Write */ + g_assert_cmpint (g_seekable_tell (seekable), ==, 0); + res = g_data_output_stream_put_uint16 (stream, 0x0123, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_data_output_stream_put_uint16 (stream, 0x4567, NULL, NULL); + g_assert_cmpint (g_seekable_tell (seekable), ==, 4); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + g_assert_cmpint (stream_data[2], ==, 0x45); + g_assert_cmpint (stream_data[3], ==, 0x67); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4); + + /* Forward relative seek */ + res = g_seekable_seek (seekable, 2, G_SEEK_CUR, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_seekable_tell (seekable), ==, 6); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4); + res = g_data_output_stream_put_uint16 (stream, 0x89AB, NULL, &error); + g_assert (res); + g_assert_cmpint (g_seekable_tell (seekable), ==, 8); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + g_assert_cmpint (stream_data[2], ==, 0x45); + g_assert_cmpint (stream_data[3], ==, 0x67); + g_assert_cmpint (stream_data[4], ==, 0x00); + g_assert_cmpint (stream_data[5], ==, 0x00); + g_assert_cmpint (stream_data[6], ==, 0x89); + g_assert_cmpint (stream_data[7], ==, 0xAB); + + /* Backward relative seek */ + res = g_seekable_seek (seekable, -3, G_SEEK_CUR, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_seekable_tell (seekable), ==, 5); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8); + res = g_data_output_stream_put_uint16 (stream, 0xCDEF, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_seekable_tell (seekable), ==, 7); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + g_assert_cmpint (stream_data[2], ==, 0x45); + g_assert_cmpint (stream_data[3], ==, 0x67); + g_assert_cmpint (stream_data[4], ==, 0x00); + g_assert_cmpint (stream_data[5], ==, 0xCD); + g_assert_cmpint (stream_data[6], ==, 0xEF); + g_assert_cmpint (stream_data[7], ==, 0xAB); + + /* From start */ + res = g_seekable_seek (seekable, 4, G_SEEK_SET, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_seekable_tell (seekable), ==, 4); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8); + res = g_data_output_stream_put_uint16 (stream, 0xFEDC, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_seekable_tell (seekable), ==, 6); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + g_assert_cmpint (stream_data[2], ==, 0x45); + g_assert_cmpint (stream_data[3], ==, 0x67); + g_assert_cmpint (stream_data[4], ==, 0xFE); + g_assert_cmpint (stream_data[5], ==, 0xDC); + g_assert_cmpint (stream_data[6], ==, 0xEF); + g_assert_cmpint (stream_data[7], ==, 0xAB); + + /* From end */ + res = g_seekable_seek (seekable, -4, G_SEEK_END, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_seekable_tell (seekable), ==, 4); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8); + res = g_data_output_stream_put_uint16 (stream, 0xBA87, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_seekable_tell (seekable), ==, 6); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + g_assert_cmpint (stream_data[2], ==, 0x45); + g_assert_cmpint (stream_data[3], ==, 0x67); + g_assert_cmpint (stream_data[4], ==, 0xBA); + g_assert_cmpint (stream_data[5], ==, 0x87); + g_assert_cmpint (stream_data[6], ==, 0xEF); + g_assert_cmpint (stream_data[7], ==, 0xAB); + + g_object_unref (stream); + g_object_unref (base_stream); + g_free (stream_data); +} + +static void +test_truncate (void) +{ + GDataOutputStream *stream; + GMemoryOutputStream *base_stream; + GSeekable *seekable; + GError *error; + guchar *stream_data; + gsize len; + gboolean res; + + len = 8; + + /* Create objects */ + stream_data = g_malloc0 (len); + base_stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (stream_data, len, g_realloc, g_free)); + stream = g_data_output_stream_new (G_OUTPUT_STREAM (base_stream)); + g_data_output_stream_set_byte_order (stream, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + seekable = G_SEEKABLE (stream); + error = NULL; + g_assert (g_seekable_can_truncate (seekable)); + + /* Write */ + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 0); + res = g_data_output_stream_put_uint16 (stream, 0x0123, NULL, &error); + g_assert_no_error (error); + g_assert (res); + res = g_data_output_stream_put_uint16 (stream, 0x4567, NULL, NULL); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4); + stream_data = g_memory_output_stream_get_data (base_stream); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + g_assert_cmpint (stream_data[2], ==, 0x45); + g_assert_cmpint (stream_data[3], ==, 0x67); + + /* Truncate at position */ + res = g_seekable_truncate (seekable, 4, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 4); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4); + stream_data = g_memory_output_stream_get_data (base_stream); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + g_assert_cmpint (stream_data[2], ==, 0x45); + g_assert_cmpint (stream_data[3], ==, 0x67); + + /* Truncate beyond position */ + res = g_seekable_truncate (seekable, 6, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 6); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 6); + stream_data = g_memory_output_stream_get_data (base_stream); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + g_assert_cmpint (stream_data[2], ==, 0x45); + g_assert_cmpint (stream_data[3], ==, 0x67); + + /* Truncate before position */ + res = g_seekable_truncate (seekable, 2, NULL, &error); + g_assert_no_error (error); + g_assert (res); + g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 2); + g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 2); + stream_data = g_memory_output_stream_get_data (base_stream); + g_assert_cmpint (stream_data[0], ==, 0x01); + g_assert_cmpint (stream_data[1], ==, 0x23); + + g_object_unref (stream); + g_object_unref (base_stream); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/data-output-stream/basic", test_basic); + g_test_add_func ("/data-output-stream/write-lines-LF", test_read_lines_LF); + g_test_add_func ("/data-output-stream/write-lines-CR", test_read_lines_CR); + g_test_add_func ("/data-output-stream/write-lines-CR-LF", test_read_lines_CR_LF); + g_test_add_func ("/data-output-stream/write-int", test_read_int); + g_test_add_func ("/data-output-stream/seek", test_seek); + g_test_add_func ("/data-output-stream/truncate", test_truncate); + + return g_test_run(); +} diff --git a/gio/tests/dbus-appinfo.c b/gio/tests/dbus-appinfo.c new file mode 100644 index 0000000..f24e3a8 --- /dev/null +++ b/gio/tests/dbus-appinfo.c @@ -0,0 +1,449 @@ +/* + * Copyright © 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include +#include + +#include "gdbus-sessionbus.h" + +static GDesktopAppInfo *appinfo; +static int current_state; +static gboolean saw_startup_id; +static gboolean requested_startup_id; + + +static GType test_app_launch_context_get_type (void); +typedef GAppLaunchContext TestAppLaunchContext; +typedef GAppLaunchContextClass TestAppLaunchContextClass; +G_DEFINE_TYPE (TestAppLaunchContext, test_app_launch_context, G_TYPE_APP_LAUNCH_CONTEXT) + +static gchar * +test_app_launch_context_get_startup_notify_id (GAppLaunchContext *context, + GAppInfo *info, + GList *uris) +{ + requested_startup_id = TRUE; + return g_strdup ("expected startup id"); +} + +static void +test_app_launch_context_init (TestAppLaunchContext *ctx) +{ +} + +static void +test_app_launch_context_class_init (GAppLaunchContextClass *class) +{ + class->get_startup_notify_id = test_app_launch_context_get_startup_notify_id; +} + +static GType test_application_get_type (void); +typedef GApplication TestApplication; +typedef GApplicationClass TestApplicationClass; +G_DEFINE_TYPE (TestApplication, test_application, G_TYPE_APPLICATION) + +static void +saw_action (const gchar *action) +{ + /* This is the main driver of the test. It's a bit of a state + * machine. + * + * Each time some event arrives on the app, it calls here to report + * which event it was. The initial activation of the app is what + * starts everything in motion (starting from state 0). At each + * state, we assert that we receive the expected event, send the next + * event, then update the current_state variable so we do the correct + * thing next time. + */ + + switch (current_state) + { + case 0: g_assert_cmpstr (action, ==, "activate"); + + /* Let's try another activation... */ + g_app_info_launch (G_APP_INFO (appinfo), NULL, NULL, NULL); + current_state = 1; return; case 1: g_assert_cmpstr (action, ==, "activate"); + + + /* Now let's try opening some files... */ + { + GList *files; + + files = g_list_prepend (NULL, g_file_new_for_uri ("file:///a/b")); + files = g_list_append (files, g_file_new_for_uri ("file:///c/d")); + g_app_info_launch (G_APP_INFO (appinfo), files, NULL, NULL); + g_list_free_full (files, g_object_unref); + } + current_state = 2; return; case 2: g_assert_cmpstr (action, ==, "open"); + + /* Now action activations... */ + g_desktop_app_info_launch_action (appinfo, "frob", NULL); + current_state = 3; return; case 3: g_assert_cmpstr (action, ==, "frob"); + + g_desktop_app_info_launch_action (appinfo, "tweak", NULL); + current_state = 4; return; case 4: g_assert_cmpstr (action, ==, "tweak"); + + g_desktop_app_info_launch_action (appinfo, "twiddle", NULL); + current_state = 5; return; case 5: g_assert_cmpstr (action, ==, "twiddle"); + + /* Now launch the app with startup notification */ + { + GAppLaunchContext *ctx; + + g_assert (saw_startup_id == FALSE); + ctx = g_object_new (test_app_launch_context_get_type (), NULL); + g_app_info_launch (G_APP_INFO (appinfo), NULL, ctx, NULL); + g_assert (requested_startup_id); + requested_startup_id = FALSE; + g_object_unref (ctx); + } + current_state = 6; return; case 6: g_assert_cmpstr (action, ==, "activate"); g_assert (saw_startup_id); + saw_startup_id = FALSE; + + /* Now do the same for an action */ + { + GAppLaunchContext *ctx; + + g_assert (saw_startup_id == FALSE); + ctx = g_object_new (test_app_launch_context_get_type (), NULL); + g_desktop_app_info_launch_action (appinfo, "frob", ctx); + g_assert (requested_startup_id); + requested_startup_id = FALSE; + g_object_unref (ctx); + } + current_state = 7; return; case 7: g_assert_cmpstr (action, ==, "frob"); g_assert (saw_startup_id); + saw_startup_id = FALSE; + + /* Now quit... */ + g_desktop_app_info_launch_action (appinfo, "quit", NULL); + current_state = 8; return; case 8: g_assert_not_reached (); + } +} + +static void +test_application_frob (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + g_assert (parameter == NULL); + saw_action ("frob"); +} + +static void +test_application_tweak (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + g_assert (parameter == NULL); + saw_action ("tweak"); +} + +static void +test_application_twiddle (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + g_assert (parameter == NULL); + saw_action ("twiddle"); +} + +static void +test_application_quit (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + GApplication *application = user_data; + + g_application_quit (application); +} + +static const GActionEntry app_actions[] = { + { "frob", test_application_frob, NULL, NULL, NULL, { 0 } }, + { "tweak", test_application_tweak, NULL, NULL, NULL, { 0 } }, + { "twiddle", test_application_twiddle, NULL, NULL, NULL, { 0 } }, + { "quit", test_application_quit, NULL, NULL, NULL, { 0 } } +}; + +static void +test_application_activate (GApplication *application) +{ + /* Unbalanced, but that's OK because we will quit() */ + g_application_hold (application); + + saw_action ("activate"); +} + +static void +test_application_open (GApplication *application, + GFile **files, + gint n_files, + const gchar *hint) +{ + GFile *f; + + g_assert_cmpstr (hint, ==, ""); + + g_assert_cmpint (n_files, ==, 2); + f = g_file_new_for_uri ("file:///a/b"); + g_assert (g_file_equal (files[0], f)); + g_object_unref (f); + f = g_file_new_for_uri ("file:///c/d"); + g_assert (g_file_equal (files[1], f)); + g_object_unref (f); + + saw_action ("open"); +} + +static void +test_application_startup (GApplication *application) +{ + G_APPLICATION_CLASS (test_application_parent_class) + ->startup (application); + + g_action_map_add_action_entries (G_ACTION_MAP (application), app_actions, G_N_ELEMENTS (app_actions), application); +} + +static void +test_application_before_emit (GApplication *application, + GVariant *platform_data) +{ + const gchar *startup_id; + + g_assert (!saw_startup_id); + + if (!g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_id)) + return; + + g_assert_cmpstr (startup_id, ==, "expected startup id"); + saw_startup_id = TRUE; +} + +static void +test_application_init (TestApplication *app) +{ +} + +static void +test_application_class_init (GApplicationClass *class) +{ + class->before_emit = test_application_before_emit; + class->startup = test_application_startup; + class->activate = test_application_activate; + class->open = test_application_open; +} + +static void +test_dbus_appinfo (void) +{ + const gchar *argv[] = { "myapp", NULL }; + TestApplication *app; + int status; + gchar *desktop_file = NULL; + + desktop_file = g_test_build_filename (G_TEST_DIST, + "org.gtk.test.dbusappinfo.desktop", + NULL); + appinfo = g_desktop_app_info_new_from_filename (desktop_file); + g_assert (appinfo != NULL); + g_free (desktop_file); + + app = g_object_new (test_application_get_type (), + "application-id", "org.gtk.test.dbusappinfo", + "flags", G_APPLICATION_HANDLES_OPEN, + NULL); + status = g_application_run (app, 1, (gchar **) argv); + + g_assert_cmpint (status, ==, 0); + g_assert_cmpint (current_state, ==, 8); + + g_object_unref (appinfo); + g_object_unref (app); +} + +static void +on_flatpak_launch_uris_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GApplication *app = user_data; + GError *error = NULL; + + g_app_info_launch_uris_finish (G_APP_INFO (object), result, &error); + g_assert_no_error (error); + + g_application_release (app); +} + +static void +on_flatpak_activate (GApplication *app, + gpointer user_data) +{ + GDesktopAppInfo *flatpak_appinfo = user_data; + char *uri; + GList *uris; + + /* The app will be released in on_flatpak_launch_uris_finish */ + g_application_hold (app); + + uri = g_filename_to_uri (g_desktop_app_info_get_filename (flatpak_appinfo), NULL, NULL); + g_assert_nonnull (uri); + uris = g_list_prepend (NULL, uri); + g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, NULL, + NULL, on_flatpak_launch_uris_finish, app); + g_list_free (uris); + g_free (uri); +} + +static void +on_flatpak_open (GApplication *app, + GFile **files, + gint n_files, + const char *hint) +{ + GFile *f; + + g_assert_cmpint (n_files, ==, 1); + g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0])); + + /* The file has been exported via the document portal */ + f = g_file_new_for_uri ("file:///document-portal/document-id/org.gtk.test.dbusappinfo.flatpak.desktop"); + g_assert_true (g_file_equal (files[0], f)); + g_object_unref (f); +} + +static void +test_flatpak_doc_export (void) +{ + const gchar *argv[] = { "myapp", NULL }; + gchar *desktop_file = NULL; + GDesktopAppInfo *flatpak_appinfo; + GApplication *app; + int status; + + g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal."); + + desktop_file = g_test_build_filename (G_TEST_DIST, + "org.gtk.test.dbusappinfo.flatpak.desktop", + NULL); + flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file); + g_assert_nonnull (flatpak_appinfo); + g_free (desktop_file); + + app = g_application_new ("org.gtk.test.dbusappinfo.flatpak", + G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate), + flatpak_appinfo); + g_signal_connect (app, "open", G_CALLBACK (on_flatpak_open), NULL); + + status = g_application_run (app, 1, (gchar **) argv); + g_assert_cmpint (status, ==, 0); + + g_object_unref (app); + g_object_unref (flatpak_appinfo); +} + +static void +on_flatpak_launch_invalid_uri_finish (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GApplication *app = user_data; + GError *error = NULL; + + g_app_info_launch_uris_finish (G_APP_INFO (object), result, &error); + g_assert_no_error (error); + + g_application_release (app); +} + +static void +on_flatpak_activate_invalid_uri (GApplication *app, + gpointer user_data) +{ + GDesktopAppInfo *flatpak_appinfo = user_data; + GList *uris; + + /* The app will be released in on_flatpak_launch_uris_finish */ + g_application_hold (app); + + uris = g_list_prepend (NULL, "file:///hopefully/an/invalid/path.desktop"); + g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, NULL, + NULL, on_flatpak_launch_invalid_uri_finish, app); + g_list_free (uris); +} + +static void +on_flatpak_open_invalid_uri (GApplication *app, + GFile **files, + gint n_files, + const char *hint) +{ + GFile *f; + + g_assert_cmpint (n_files, ==, 1); + g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0])); + + /* The file has been exported via the document portal */ + f = g_file_new_for_uri ("file:///hopefully/an/invalid/path.desktop"); + g_assert_true (g_file_equal (files[0], f)); + g_object_unref (f); +} + +static void +test_flatpak_missing_doc_export (void) +{ + const gchar *argv[] = { "myapp", NULL }; + gchar *desktop_file = NULL; + GDesktopAppInfo *flatpak_appinfo; + GApplication *app; + int status; + + g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal."); + + desktop_file = g_test_build_filename (G_TEST_DIST, + "org.gtk.test.dbusappinfo.flatpak.desktop", + NULL); + flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file); + g_assert_nonnull (flatpak_appinfo); + + app = g_application_new ("org.gtk.test.dbusappinfo.flatpak", + G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate_invalid_uri), + flatpak_appinfo); + g_signal_connect (app, "open", G_CALLBACK (on_flatpak_open_invalid_uri), NULL); + + status = g_application_run (app, 1, (gchar **) argv); + g_assert_cmpint (status, ==, 0); + + g_object_unref (app); + g_object_unref (flatpak_appinfo); + g_free (desktop_file); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/appinfo/dbusappinfo", test_dbus_appinfo); + g_test_add_func ("/appinfo/flatpak-doc-export", test_flatpak_doc_export); + g_test_add_func ("/appinfo/flatpak-missing-doc-export", test_flatpak_missing_doc_export); + + return session_bus_run (); +} diff --git a/gio/tests/dbus-launch.c b/gio/tests/dbus-launch.c new file mode 100644 index 0000000..ef57219 --- /dev/null +++ b/gio/tests/dbus-launch.c @@ -0,0 +1,78 @@ +/* + * Mock version of dbus-launch, for gdbus-address-get-session test + * + * Copyright © 2015 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +#ifndef G_OS_UNIX +#error This is a Unix-specific test helper +#endif + +#include +#include +#include +#include + +#define ME "GDBus mock version of dbus-launch" + +static void +write_all (const void *ptr, + size_t len) +{ + const char *p = ptr; + + while (len > 0) + { + gssize done = write (STDOUT_FILENO, p, len); + int errsv = errno; + + if (done == 0) + { + g_error ("%s: write: EOF", ME); + } + else if (done < 0) + { + if (errsv == EINTR) + continue; + + g_error ("%s: write: %s", ME, g_strerror (errsv)); + } + else + { + if (len < (size_t) done) + g_error ("%s: wrote too many bytes?", ME); + + len -= done; + p += done; + } + } +} + +int +main (int argc, + char *argv[]) +{ + pid_t pid = 0x2323; + long window_id = 0x42424242; + const char *addr = "hello:this=address-is-from-the,mock=dbus-launch"; + + write_all (addr, strlen (addr) + 1); + write_all (&pid, sizeof (pid)); + write_all (&window_id, sizeof (window_id)); + return 0; +} diff --git a/gio/tests/de.po b/gio/tests/de.po new file mode 100644 index 0000000..eed161c --- /dev/null +++ b/gio/tests/de.po @@ -0,0 +1,17 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: \n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +msgid "\"Unnamed\"" +msgstr "\"Unbenannt\"" + +msgctxt "keyboard label" +msgid "\"BackSpace\"" +msgstr "\"Löschen\"" diff --git a/gio/tests/de/LC_MESSAGES/meson.build b/gio/tests/de/LC_MESSAGES/meson.build new file mode 100644 index 0000000..2aab3b6 --- /dev/null +++ b/gio/tests/de/LC_MESSAGES/meson.build @@ -0,0 +1,8 @@ +# Doing this in a subdir, so we get it in the right build de/LC_MESSAGES subdir +# at least in cases where the build directory layout is mirrored. +test_mo = custom_target('test.mo', + input : ['../../de.po'], + output : ['test.mo'], + command : [msgfmt, '-o', '@OUTPUT@', '@INPUT@']) + +test_mo_dir = meson.current_build_dir() diff --git a/gio/tests/debugcontroller.c b/gio/tests/debugcontroller.c new file mode 100644 index 0000000..c20acd6 --- /dev/null +++ b/gio/tests/debugcontroller.c @@ -0,0 +1,396 @@ +/* GLib testing framework examples and tests + * + * Copyright © 2022 Endless OS Foundation, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * Author: Philip Withnall + */ + +#include +#include + + +static void +test_dbus_basic (void) +{ + GTestDBus *bus; + GDBusConnection *connection = NULL, *connection2 = NULL; + GDebugControllerDBus *controller = NULL; + gboolean old_value; + gboolean debug_enabled; + GError *local_error = NULL; + + g_test_summary ("Smoketest for construction and setting of a #GDebugControllerDBus."); + + /* Set up a test session bus and connection. */ + bus = g_test_dbus_new (G_TEST_DBUS_NONE); + g_test_dbus_up (bus); + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error); + g_assert_no_error (local_error); + + /* Create a controller for this process. */ + controller = g_debug_controller_dbus_new (connection, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (controller); + g_assert_true (G_IS_DEBUG_CONTROLLER_DBUS (controller)); + + /* Try enabling and disabling debug output from within the process. */ + old_value = g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)); + + g_debug_controller_set_debug_enabled (G_DEBUG_CONTROLLER (controller), TRUE); + g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller))); + + g_debug_controller_set_debug_enabled (G_DEBUG_CONTROLLER (controller), FALSE); + g_assert_false (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller))); + + /* Reset the debug state and check using g_object_get(), to exercise that. */ + g_debug_controller_set_debug_enabled (G_DEBUG_CONTROLLER (controller), old_value); + + g_object_get (G_OBJECT (controller), + "debug-enabled", &debug_enabled, + "connection", &connection2, + NULL); + g_assert_true (debug_enabled == old_value); + g_assert_true (connection2 == connection); + g_clear_object (&connection2); + + g_debug_controller_dbus_stop (controller); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_finalize_object (controller); + g_clear_object (&connection); + + g_test_dbus_down (bus); + g_clear_object (&bus); +} + +static void +test_dbus_duplicate (void) +{ + GTestDBus *bus; + GDBusConnection *connection = NULL; + GDebugControllerDBus *controller1 = NULL, *controller2 = NULL; + GError *local_error = NULL; + + g_test_summary ("Test that creating a second #GDebugControllerDBus on the same D-Bus connection fails."); + + /* Set up a test session bus and connection. */ + bus = g_test_dbus_new (G_TEST_DBUS_NONE); + g_test_dbus_up (bus); + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error); + g_assert_no_error (local_error); + + /* Create a controller for this process. */ + controller1 = g_debug_controller_dbus_new (connection, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (controller1); + + /* And try creating a second one. */ + controller2 = g_debug_controller_dbus_new (connection, NULL, &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS); + g_assert_null (controller2); + g_clear_error (&local_error); + + g_debug_controller_dbus_stop (controller1); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_finalize_object (controller1); + g_clear_object (&connection); + + g_test_dbus_down (bus); + g_clear_object (&bus); +} + +static void +async_result_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GAsyncResult **result_out = user_data; + + g_assert_null (*result_out); + *result_out = g_object_ref (result); + + g_main_context_wakeup (g_main_context_get_thread_default ()); +} + +static gboolean +authorize_false_cb (GDebugControllerDBus *debug_controller, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + return FALSE; +} + +static gboolean +authorize_true_cb (GDebugControllerDBus *debug_controller, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + return TRUE; +} + +static void +notify_debug_enabled_cb (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + guint *notify_count_out = user_data; + + *notify_count_out = *notify_count_out + 1; +} + +static void +properties_changed_cb (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + guint *properties_changed_count_out = user_data; + + *properties_changed_count_out = *properties_changed_count_out + 1; + g_main_context_wakeup (g_main_context_get_thread_default ()); +} + +static void +test_dbus_properties (void) +{ + GTestDBus *bus; + GDBusConnection *controller_connection = NULL; + GDBusConnection *remote_connection = NULL; + GDebugControllerDBus *controller = NULL; + gboolean old_value; + GAsyncResult *result = NULL; + GVariant *reply = NULL; + GVariant *debug_enabled_variant = NULL; + gboolean debug_enabled; + GError *local_error = NULL; + gulong handler_id; + gulong notify_id; + guint notify_count = 0; + guint properties_changed_id; + guint properties_changed_count = 0; + + g_test_summary ("Test getting and setting properties on a #GDebugControllerDBus."); + + /* Set up a test session bus and connection. Set up a separate second + * connection to simulate a remote peer. */ + bus = g_test_dbus_new (G_TEST_DBUS_NONE); + g_test_dbus_up (bus); + + controller_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error); + g_assert_no_error (local_error); + + remote_connection = g_dbus_connection_new_for_address_sync (g_test_dbus_get_bus_address (bus), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, + NULL, + NULL, + &local_error); + g_assert_no_error (local_error); + + /* Create a controller for this process. */ + controller = g_debug_controller_dbus_new (controller_connection, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (controller); + g_assert_true (G_IS_DEBUG_CONTROLLER_DBUS (controller)); + + old_value = g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)); + notify_id = g_signal_connect (controller, "notify::debug-enabled", G_CALLBACK (notify_debug_enabled_cb), ¬ify_count); + + properties_changed_id = g_dbus_connection_signal_subscribe (remote_connection, + g_dbus_connection_get_unique_name (controller_connection), + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + "/org/gtk/Debugging", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + properties_changed_cb, + &properties_changed_count, + NULL); + + /* Get the debug status remotely. */ + g_dbus_connection_call (remote_connection, + g_dbus_connection_get_unique_name (controller_connection), + "/org/gtk/Debugging", + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new ("(ss)", "org.gtk.Debugging", "DebugEnabled"), + G_VARIANT_TYPE ("(v)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + async_result_cb, + &result); + g_assert_no_error (local_error); + + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + + reply = g_dbus_connection_call_finish (remote_connection, result, &local_error); + g_assert_no_error (local_error); + g_clear_object (&result); + + g_variant_get (reply, "(v)", &debug_enabled_variant); + debug_enabled = g_variant_get_boolean (debug_enabled_variant); + g_assert_true (debug_enabled == old_value); + g_assert_cmpuint (notify_count, ==, 0); + g_assert_cmpuint (properties_changed_count, ==, 0); + + g_clear_pointer (&debug_enabled_variant, g_variant_unref); + g_clear_pointer (&reply, g_variant_unref); + + /* Set the debug status remotely. The first attempt should fail due to no + * authorisation handler being connected. The second should fail due to the + * now-connected handler returning %FALSE. The third attempt should + * succeed. */ + g_dbus_connection_call (remote_connection, + g_dbus_connection_get_unique_name (controller_connection), + "/org/gtk/Debugging", + "org.gtk.Debugging", + "SetDebugEnabled", + g_variant_new ("(b)", !old_value), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + async_result_cb, + &result); + + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + + reply = g_dbus_connection_call_finish (remote_connection, result, &local_error); + g_assert_error (local_error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED); + g_clear_object (&result); + g_clear_error (&local_error); + + g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)) == old_value); + g_assert_cmpuint (notify_count, ==, 0); + g_assert_cmpuint (properties_changed_count, ==, 0); + + g_clear_pointer (&debug_enabled_variant, g_variant_unref); + g_clear_pointer (&reply, g_variant_unref); + + /* Attach an authorisation handler and try again. */ + handler_id = g_signal_connect (controller, "authorize", G_CALLBACK (authorize_false_cb), NULL); + + g_dbus_connection_call (remote_connection, + g_dbus_connection_get_unique_name (controller_connection), + "/org/gtk/Debugging", + "org.gtk.Debugging", + "SetDebugEnabled", + g_variant_new ("(b)", !old_value), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + async_result_cb, + &result); + + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + + reply = g_dbus_connection_call_finish (remote_connection, result, &local_error); + g_assert_error (local_error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED); + g_clear_object (&result); + g_clear_error (&local_error); + + g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)) == old_value); + g_assert_cmpuint (notify_count, ==, 0); + g_assert_cmpuint (properties_changed_count, ==, 0); + + g_clear_pointer (&debug_enabled_variant, g_variant_unref); + g_clear_pointer (&reply, g_variant_unref); + + g_signal_handler_disconnect (controller, handler_id); + handler_id = 0; + + /* Attach another signal handler which will grant access, and try again. */ + handler_id = g_signal_connect (controller, "authorize", G_CALLBACK (authorize_true_cb), NULL); + + g_dbus_connection_call (remote_connection, + g_dbus_connection_get_unique_name (controller_connection), + "/org/gtk/Debugging", + "org.gtk.Debugging", + "SetDebugEnabled", + g_variant_new ("(b)", !old_value), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + async_result_cb, + &result); + + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + + reply = g_dbus_connection_call_finish (remote_connection, result, &local_error); + g_assert_no_error (local_error); + g_clear_object (&result); + + g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)) == !old_value); + g_assert_cmpuint (notify_count, ==, 1); + g_assert_cmpuint (properties_changed_count, ==, 1); + + g_clear_pointer (&debug_enabled_variant, g_variant_unref); + g_clear_pointer (&reply, g_variant_unref); + + g_signal_handler_disconnect (controller, handler_id); + handler_id = 0; + + /* Set the debug status locally. */ + g_debug_controller_set_debug_enabled (G_DEBUG_CONTROLLER (controller), old_value); + g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)) == old_value); + g_assert_cmpuint (notify_count, ==, 2); + + while (properties_changed_count != 2) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (properties_changed_count, ==, 2); + + g_signal_handler_disconnect (controller, notify_id); + notify_id = 0; + + g_dbus_connection_signal_unsubscribe (remote_connection, properties_changed_id); + properties_changed_id = 0; + + g_debug_controller_dbus_stop (controller); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_finalize_object (controller); + g_clear_object (&controller_connection); + g_clear_object (&remote_connection); + + g_test_dbus_down (bus); + g_clear_object (&bus); +} + +int +main (int argc, + char *argv[]) +{ + setlocale (LC_ALL, ""); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/debug-controller/dbus/basic", test_dbus_basic); + g_test_add_func ("/debug-controller/dbus/duplicate", test_dbus_duplicate); + g_test_add_func ("/debug-controller/dbus/properties", test_dbus_properties); + + return g_test_run (); +} diff --git a/gio/tests/defaultvalue.c b/gio/tests/defaultvalue.c new file mode 100644 index 0000000..de0e9b1 --- /dev/null +++ b/gio/tests/defaultvalue.c @@ -0,0 +1,228 @@ +/* GIO default value tests + * Copyright (C) 2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include + +static void +check_property (const char *output, + GParamSpec *pspec, + GValue *value) +{ + GValue default_value = G_VALUE_INIT; + char *v, *dv, *msg; + + if (g_param_value_defaults (pspec, value)) + return; + + g_param_value_set_default (pspec, &default_value); + + v = g_strdup_value_contents (value); + dv = g_strdup_value_contents (&default_value); + + msg = g_strdup_printf ("%s %s.%s: %s != %s\n", + output, + g_type_name (pspec->owner_type), + pspec->name, + dv, v); + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); + g_free (msg); + + g_free (v); + g_free (dv); + g_value_unset (&default_value); +} + +static void +test_type (gconstpointer data) +{ + GObjectClass *klass; + GObject *instance; + GParamSpec **pspecs; + guint n_pspecs, i; + GType type; + + type = * (GType *) data; + + if (g_type_is_a (type, G_TYPE_APP_INFO_MONITOR)) + { + g_test_skip ("singleton"); + return; + } + + if (g_type_is_a (type, G_TYPE_BINDING) || + g_type_is_a (type, G_TYPE_BUFFERED_INPUT_STREAM) || + g_type_is_a (type, G_TYPE_BUFFERED_OUTPUT_STREAM) || + g_type_is_a (type, G_TYPE_CHARSET_CONVERTER) || + g_type_is_a (type, G_TYPE_DBUS_ACTION_GROUP) || + g_type_is_a (type, G_TYPE_DBUS_CONNECTION) || + g_type_is_a (type, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT) || + g_type_is_a (type, G_TYPE_DBUS_OBJECT_MANAGER_SERVER) || + g_type_is_a (type, G_TYPE_DBUS_PROXY) || + g_type_is_a (type, G_TYPE_DBUS_SERVER) || + g_type_is_a (type, G_TYPE_FILTER_OUTPUT_STREAM) || + g_type_is_a (type, G_TYPE_FILTER_INPUT_STREAM) || + g_type_is_a (type, G_TYPE_INET_ADDRESS) || + g_type_is_a (type, G_TYPE_INET_SOCKET_ADDRESS) || + g_type_is_a (type, G_TYPE_PROPERTY_ACTION) || + g_type_is_a (type, G_TYPE_SETTINGS) || + g_type_is_a (type, G_TYPE_SOCKET_CONNECTION) || + g_type_is_a (type, G_TYPE_SIMPLE_IO_STREAM) || + g_type_is_a (type, G_TYPE_THEMED_ICON) || + FALSE) + { + g_test_skip ("mandatory construct params"); + return; + } + + if (g_type_is_a (type, G_TYPE_DBUS_MENU_MODEL) || + g_type_is_a (type, G_TYPE_DBUS_METHOD_INVOCATION)) + { + g_test_skip ("crash in finalize"); + return; + } + + if (g_type_is_a (type, G_TYPE_FILE_ENUMERATOR) || + g_type_is_a (type, G_TYPE_FILE_IO_STREAM)) + { + g_test_skip ("should be abstract"); + return; + } + + klass = g_type_class_ref (type); + instance = g_object_new (type, NULL); + + if (G_IS_INITABLE (instance) && + !g_initable_init (G_INITABLE (instance), NULL, NULL)) + { + g_test_skip ("initialization failed"); + g_object_unref (instance); + g_type_class_unref (klass); + return; + } + + if (g_type_is_a (type, G_TYPE_INITIALLY_UNOWNED)) + g_object_ref_sink (instance); + + pspecs = g_object_class_list_properties (klass, &n_pspecs); + for (i = 0; i < n_pspecs; ++i) + { + GParamSpec *pspec = pspecs[i]; + GValue value = G_VALUE_INIT; + + if (pspec->owner_type != type) + continue; + + if ((pspec->flags & G_PARAM_READABLE) == 0) + continue; + + if (g_type_is_a (type, G_TYPE_APPLICATION) && + (strcmp (pspec->name, "is-remote") == 0)) + { + g_test_message ("skipping GApplication:is-remote"); + continue; + } + + if (g_type_is_a (type, G_TYPE_PROXY_ADDRESS_ENUMERATOR) && + (strcmp (pspec->name, "proxy-resolver") == 0)) + { + g_test_message ("skipping GProxyAddressEnumerator:proxy-resolver"); + continue; + } + + if (g_type_is_a (type, G_TYPE_SOCKET_CLIENT) && + (strcmp (pspec->name, "proxy-resolver") == 0)) + { + g_test_message ("skipping GSocketClient:proxy-resolver"); + continue; + } + + if (g_test_verbose ()) + g_printerr ("Property %s.%s\n", g_type_name (pspec->owner_type), pspec->name); + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + g_object_get_property (instance, pspec->name, &value); + check_property ("Property", pspec, &value); + g_value_unset (&value); + } + g_free (pspecs); + g_object_unref (instance); + g_type_class_unref (klass); +} + +static GType *all_registered_types; + +static const GType * +list_all_types (void) +{ + if (!all_registered_types) + { + GType *tp; + all_registered_types = g_new0 (GType, 1000); + tp = all_registered_types; +#include "giotypefuncs.inc" + *tp = 0; + } + + return all_registered_types; +} + +int +main (int argc, char **argv) +{ + const GType *otypes; + guint i; + GTestDBus *bus; + gint result; + + g_setenv ("GIO_USE_VFS", "local", TRUE); + g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); + + g_test_init (&argc, &argv, NULL); + + /* Create one test bus for all tests, as we have a lot of very small + * and quick tests. + */ + bus = g_test_dbus_new (G_TEST_DBUS_NONE); + g_test_dbus_up (bus); + + otypes = list_all_types (); + for (i = 0; otypes[i]; i++) + { + gchar *testname; + + if (!G_TYPE_IS_CLASSED (otypes[i])) + continue; + + if (G_TYPE_IS_ABSTRACT (otypes[i])) + continue; + + if (!g_type_is_a (otypes[i], G_TYPE_OBJECT)) + continue; + + testname = g_strdup_printf ("/Default Values/%s", + g_type_name (otypes[i])); + g_test_add_data_func (testname, &otypes[i], test_type); + g_free (testname); + } + + result = g_test_run (); + + g_test_dbus_down (bus); + g_object_unref (bus); + + return result; +} diff --git a/gio/tests/desktop-app-info.c b/gio/tests/desktop-app-info.c new file mode 100644 index 0000000..4a5de60 --- /dev/null +++ b/gio/tests/desktop-app-info.c @@ -0,0 +1,836 @@ +/* + * Copyright (C) 2008 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +static GAppInfo * +create_app_info (const char *name) +{ + GError *error; + GAppInfo *info; + + error = NULL; + info = g_app_info_create_from_commandline ("true blah", + name, + G_APP_INFO_CREATE_NONE, + &error); + g_assert_no_error (error); + + /* this is necessary to ensure that the info is saved */ + g_app_info_set_as_default_for_type (info, "application/x-blah", &error); + g_assert_no_error (error); + g_app_info_remove_supports_type (info, "application/x-blah", &error); + g_assert_no_error (error); + g_app_info_reset_type_associations ("application/x-blah"); + + return info; +} + +static void +test_delete (void) +{ + GAppInfo *info; + + const char *id; + char *filename; + gboolean res; + + info = create_app_info ("Blah"); + + id = g_app_info_get_id (info); + g_assert_nonnull (id); + + filename = g_build_filename (g_get_user_data_dir (), "applications", id, NULL); + + res = g_file_test (filename, G_FILE_TEST_EXISTS); + g_assert_true (res); + + res = g_app_info_can_delete (info); + g_assert_true (res); + + res = g_app_info_delete (info); + g_assert_true (res); + + res = g_file_test (filename, G_FILE_TEST_EXISTS); + g_assert_false (res); + + g_object_unref (info); + + if (g_file_test ("/usr/share/applications/gedit.desktop", G_FILE_TEST_EXISTS)) + { + info = (GAppInfo*)g_desktop_app_info_new_from_filename ("/usr/share/applications/gedit.desktop"); + g_assert_nonnull (info); + + res = g_app_info_can_delete (info); + g_assert_false (res); + + res = g_app_info_delete (info); + g_assert_false (res); + } + + g_free (filename); +} + +static void +test_default (void) +{ + GAppInfo *info, *info1, *info2, *info3; + GList *list; + GError *error = NULL; + + info1 = create_app_info ("Blah1"); + info2 = create_app_info ("Blah2"); + info3 = create_app_info ("Blah3"); + + g_app_info_set_as_default_for_type (info1, "application/x-test", &error); + g_assert_no_error (error); + + g_app_info_set_as_default_for_type (info2, "application/x-test", &error); + g_assert_no_error (error); + + info = g_app_info_get_default_for_type ("application/x-test", FALSE); + g_assert_nonnull (info); + g_assert_cmpstr (g_app_info_get_id (info), ==, g_app_info_get_id (info2)); + g_object_unref (info); + + /* now try adding something, but not setting as default */ + g_app_info_add_supports_type (info3, "application/x-test", &error); + g_assert_no_error (error); + + /* check that info2 is still default */ + info = g_app_info_get_default_for_type ("application/x-test", FALSE); + g_assert_nonnull (info); + g_assert_cmpstr (g_app_info_get_id (info), ==, g_app_info_get_id (info2)); + g_object_unref (info); + + /* now remove info1 again */ + g_app_info_remove_supports_type (info1, "application/x-test", &error); + g_assert_no_error (error); + + /* and make sure info2 is still default */ + info = g_app_info_get_default_for_type ("application/x-test", FALSE); + g_assert_nonnull (info); + g_assert_cmpstr (g_app_info_get_id (info), ==, g_app_info_get_id (info2)); + g_object_unref (info); + + /* now clean it all up */ + g_app_info_reset_type_associations ("application/x-test"); + + list = g_app_info_get_all_for_type ("application/x-test"); + g_assert_null (list); + + g_app_info_delete (info1); + g_app_info_delete (info2); + g_app_info_delete (info3); + + g_object_unref (info1); + g_object_unref (info2); + g_object_unref (info3); +} + +static void +test_fallback (void) +{ + GAppInfo *info1, *info2, *app = NULL; + GList *apps, *recomm, *fallback, *list, *l, *m; + GError *error = NULL; + gint old_length; + + info1 = create_app_info ("Test1"); + info2 = create_app_info ("Test2"); + + g_assert_true (g_content_type_is_a ("text/x-python", "text/plain")); + + apps = g_app_info_get_all_for_type ("text/x-python"); + old_length = g_list_length (apps); + g_list_free_full (apps, g_object_unref); + + g_app_info_add_supports_type (info1, "text/x-python", &error); + g_assert_no_error (error); + + g_app_info_add_supports_type (info2, "text/plain", &error); + g_assert_no_error (error); + + /* check that both apps are registered */ + apps = g_app_info_get_all_for_type ("text/x-python"); + g_assert_cmpint (g_list_length (apps), ==, old_length + 2); + + /* check that Test1 is among the recommended apps */ + recomm = g_app_info_get_recommended_for_type ("text/x-python"); + g_assert_nonnull (recomm); + for (l = recomm; l; l = l->next) + { + app = l->data; + if (g_app_info_equal (info1, app)) + break; + } + g_assert_nonnull (app); + g_assert_true (g_app_info_equal (info1, app)); + + /* and that Test2 is among the fallback apps */ + fallback = g_app_info_get_fallback_for_type ("text/x-python"); + g_assert_nonnull (fallback); + for (l = fallback; l; l = l->next) + { + app = l->data; + if (g_app_info_equal (info2, app)) + break; + } + g_assert_cmpstr (g_app_info_get_name (app), ==, "Test2"); + + /* check that recomm + fallback = all applications */ + list = g_list_concat (g_list_copy (recomm), g_list_copy (fallback)); + g_assert_cmpuint (g_list_length (list), ==, g_list_length (apps)); + + for (l = list, m = apps; l != NULL && m != NULL; l = l->next, m = m->next) + { + g_assert_true (g_app_info_equal (l->data, m->data)); + } + + g_list_free (list); + + g_list_free_full (apps, g_object_unref); + g_list_free_full (recomm, g_object_unref); + g_list_free_full (fallback, g_object_unref); + + g_app_info_reset_type_associations ("text/x-python"); + g_app_info_reset_type_associations ("text/plain"); + + g_app_info_delete (info1); + g_app_info_delete (info2); + + g_object_unref (info1); + g_object_unref (info2); +} + +static void +test_last_used (void) +{ + GList *applications; + GAppInfo *info1, *info2, *default_app; + GError *error = NULL; + + info1 = create_app_info ("Test1"); + info2 = create_app_info ("Test2"); + + g_app_info_set_as_default_for_type (info1, "application/x-test", &error); + g_assert_no_error (error); + + g_app_info_add_supports_type (info2, "application/x-test", &error); + g_assert_no_error (error); + + applications = g_app_info_get_recommended_for_type ("application/x-test"); + g_assert_cmpuint (g_list_length (applications), ==, 2); + + /* the first should be the default app now */ + g_assert_true (g_app_info_equal (g_list_nth_data (applications, 0), info1)); + g_assert_true (g_app_info_equal (g_list_nth_data (applications, 1), info2)); + + g_list_free_full (applications, g_object_unref); + + g_app_info_set_as_last_used_for_type (info2, "application/x-test", &error); + g_assert_no_error (error); + + applications = g_app_info_get_recommended_for_type ("application/x-test"); + g_assert_cmpuint (g_list_length (applications), ==, 2); + + default_app = g_app_info_get_default_for_type ("application/x-test", FALSE); + g_assert_true (g_app_info_equal (default_app, info1)); + + /* the first should be the other app now */ + g_assert_true (g_app_info_equal (g_list_nth_data (applications, 0), info2)); + g_assert_true (g_app_info_equal (g_list_nth_data (applications, 1), info1)); + + g_list_free_full (applications, g_object_unref); + + g_app_info_reset_type_associations ("application/x-test"); + + g_app_info_delete (info1); + g_app_info_delete (info2); + + g_object_unref (info1); + g_object_unref (info2); + g_object_unref (default_app); +} + +static void +test_extra_getters (void) +{ + GDesktopAppInfo *appinfo; + const gchar *lang; + gchar *s; + gboolean b; + + lang = setlocale (LC_ALL, NULL); + g_setenv ("LANGUAGE", "de_DE.UTF8", TRUE); + setlocale (LC_ALL, ""); + + appinfo = g_desktop_app_info_new_from_filename (g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL)); + g_assert_nonnull (appinfo); + + g_assert_true (g_desktop_app_info_has_key (appinfo, "Terminal")); + g_assert_false (g_desktop_app_info_has_key (appinfo, "Bratwurst")); + + s = g_desktop_app_info_get_string (appinfo, "StartupWMClass"); + g_assert_cmpstr (s, ==, "appinfo-class"); + g_free (s); + + s = g_desktop_app_info_get_locale_string (appinfo, "X-JunkFood"); + g_assert_cmpstr (s, ==, "Bratwurst"); + g_free (s); + + g_setenv ("LANGUAGE", "sv_SE.UTF8", TRUE); + setlocale (LC_ALL, ""); + + s = g_desktop_app_info_get_locale_string (appinfo, "X-JunkFood"); + g_assert_cmpstr (s, ==, "Burger"); /* fallback */ + g_free (s); + + b = g_desktop_app_info_get_boolean (appinfo, "Terminal"); + g_assert_true (b); + + g_object_unref (appinfo); + + g_setenv ("LANGUAGE", lang, TRUE); + setlocale (LC_ALL, ""); +} + +static void +wait_for_file (const gchar *want_this, + const gchar *but_not_this, + const gchar *or_this) +{ + guint retries = 600; + + /* I hate time-based conditions in tests, but this will wait up to one + * whole minute for "touch file" to finish running. I think it should + * be OK. + * + * 600 * 100ms = 60 seconds. + */ + while (access (want_this, F_OK) != 0) + { + g_usleep (100000); /* 100ms */ + g_assert_cmpuint (retries, >, 0); + retries--; + } + + g_assert_cmpuint (access (but_not_this, F_OK), !=, 0); + g_assert_cmpuint (access (or_this, F_OK), !=, 0); + + unlink (want_this); + unlink (but_not_this); + unlink (or_this); +} + +static void +test_actions (void) +{ + const char *expected[] = { "frob", "tweak", "twiddle", "broken", NULL }; + const gchar * const *actions; + GDesktopAppInfo *appinfo; + gchar *name; + + appinfo = g_desktop_app_info_new_from_filename (g_test_get_filename (G_TEST_DIST, "appinfo-test-actions.desktop", NULL)); + g_assert_nonnull (appinfo); + + actions = g_desktop_app_info_list_actions (appinfo); + g_assert_cmpstrv (actions, expected); + + name = g_desktop_app_info_get_action_name (appinfo, "frob"); + g_assert_cmpstr (name, ==, "Frobnicate"); + g_free (name); + + name = g_desktop_app_info_get_action_name (appinfo, "tweak"); + g_assert_cmpstr (name, ==, "Tweak"); + g_free (name); + + name = g_desktop_app_info_get_action_name (appinfo, "twiddle"); + g_assert_cmpstr (name, ==, "Twiddle"); + g_free (name); + + name = g_desktop_app_info_get_action_name (appinfo, "broken"); + g_assert_nonnull (name); + g_assert_true (g_utf8_validate (name, -1, NULL)); + g_free (name); + + unlink ("frob"); unlink ("tweak"); unlink ("twiddle"); + + g_desktop_app_info_launch_action (appinfo, "frob", NULL); + wait_for_file ("frob", "tweak", "twiddle"); + + g_desktop_app_info_launch_action (appinfo, "tweak", NULL); + wait_for_file ("tweak", "frob", "twiddle"); + + g_desktop_app_info_launch_action (appinfo, "twiddle", NULL); + wait_for_file ("twiddle", "frob", "tweak"); + + g_object_unref (appinfo); +} + +static gchar * +run_apps (const gchar *command, + const gchar *arg, + gboolean with_usr, + gboolean with_home, + const gchar *locale_name, + const gchar *language, + const gchar *xdg_current_desktop) +{ + gboolean success; + gchar **envp; + gchar **argv; + gint status; + gchar *out; + gchar *argv_str = NULL; + + argv = g_new (gchar *, 4); + argv[0] = g_test_build_filename (G_TEST_BUILT, "apps", NULL); + argv[1] = g_strdup (command); + argv[2] = g_strdup (arg); + argv[3] = NULL; + + envp = g_get_environ (); + + if (with_usr) + { + gchar *tmp = g_test_build_filename (G_TEST_DIST, "desktop-files", "usr", NULL); + envp = g_environ_setenv (envp, "XDG_DATA_DIRS", tmp, TRUE); + g_free (tmp); + } + else + envp = g_environ_setenv (envp, "XDG_DATA_DIRS", "/does-not-exist", TRUE); + + if (with_home) + { + gchar *tmp = g_test_build_filename (G_TEST_DIST, "desktop-files", "home", NULL); + envp = g_environ_setenv (envp, "XDG_DATA_HOME", tmp, TRUE); + g_free (tmp); + } + else + envp = g_environ_setenv (envp, "XDG_DATA_HOME", "/does-not-exist", TRUE); + + if (locale_name) + envp = g_environ_setenv (envp, "LC_ALL", locale_name, TRUE); + else + envp = g_environ_setenv (envp, "LC_ALL", "C", TRUE); + + if (language) + envp = g_environ_setenv (envp, "LANGUAGE", language, TRUE); + else + envp = g_environ_unsetenv (envp, "LANGUAGE"); + + if (xdg_current_desktop) + envp = g_environ_setenv (envp, "XDG_CURRENT_DESKTOP", xdg_current_desktop, TRUE); + else + envp = g_environ_unsetenv (envp, "XDG_CURRENT_DESKTOP"); + + envp = g_environ_setenv (envp, "G_MESSAGES_DEBUG", "", TRUE); + + success = g_spawn_sync (NULL, argv, envp, 0, NULL, NULL, &out, NULL, &status, NULL); + g_assert_true (success); + g_assert_cmpuint (status, ==, 0); + + argv_str = g_strjoinv (" ", argv); + g_test_message ("%s: `%s` returned: %s", G_STRFUNC, argv_str, out); + g_free (argv_str); + + g_strfreev (envp); + g_strfreev (argv); + + return out; +} + +static void +assert_strings_equivalent (const gchar *expected, + const gchar *result) +{ + gchar **expected_words; + gchar **result_words; + gint i, j; + + expected_words = g_strsplit (expected, " ", 0); + result_words = g_strsplit_set (result, " \n", 0); + + for (i = 0; expected_words[i]; i++) + { + for (j = 0; result_words[j]; j++) + if (g_str_equal (expected_words[i], result_words[j])) + goto got_it; + + g_test_fail_printf ("Unable to find expected string '%s' in result '%s'", expected_words[i], result); + +got_it: + continue; + } + + g_assert_cmpint (g_strv_length (expected_words), ==, g_strv_length (result_words)); + g_strfreev (expected_words); + g_strfreev (result_words); +} + +static void +assert_list (const gchar *expected, + gboolean with_usr, + gboolean with_home, + const gchar *locale_name, + const gchar *language) +{ + gchar *result; + + result = run_apps ("list", NULL, with_usr, with_home, locale_name, language, NULL); + g_strchomp (result); + assert_strings_equivalent (expected, result); + g_free (result); +} + +static void +assert_info (const gchar *desktop_id, + const gchar *expected, + gboolean with_usr, + gboolean with_home, + const gchar *locale_name, + const gchar *language) +{ + gchar *result; + + result = run_apps ("show-info", desktop_id, with_usr, with_home, locale_name, language, NULL); + g_assert_cmpstr (result, ==, expected); + g_free (result); +} + +static void +assert_search (const gchar *search_string, + const gchar *expected, + gboolean with_usr, + gboolean with_home, + const gchar *locale_name, + const gchar *language) +{ + gchar **expected_lines; + gchar **result_lines; + gchar *result; + gint i; + + expected_lines = g_strsplit (expected, "\n", -1); + result = run_apps ("search", search_string, with_usr, with_home, locale_name, language, NULL); + result_lines = g_strsplit (result, "\n", -1); + g_assert_cmpint (g_strv_length (expected_lines), ==, g_strv_length (result_lines)); + for (i = 0; expected_lines[i]; i++) + assert_strings_equivalent (expected_lines[i], result_lines[i]); + g_strfreev (expected_lines); + g_strfreev (result_lines); + g_free (result); +} + +static void +assert_implementations (const gchar *interface, + const gchar *expected, + gboolean with_usr, + gboolean with_home) +{ + gchar *result; + + result = run_apps ("implementations", interface, with_usr, with_home, NULL, NULL, NULL); + g_strchomp (result); + assert_strings_equivalent (expected, result); + g_free (result); +} + +#define ALL_USR_APPS "evince-previewer.desktop nautilus-classic.desktop gnome-font-viewer.desktop " \ + "baobab.desktop yelp.desktop eog.desktop cheese.desktop org.gnome.clocks.desktop " \ + "gnome-contacts.desktop kde4-kate.desktop gcr-prompter.desktop totem.desktop " \ + "gnome-terminal.desktop nautilus-autorun-software.desktop gcr-viewer.desktop " \ + "nautilus-connect-server.desktop kde4-dolphin.desktop gnome-music.desktop " \ + "kde4-konqbrowser.desktop gucharmap.desktop kde4-okular.desktop nautilus.desktop " \ + "gedit.desktop evince.desktop file-roller.desktop dconf-editor.desktop glade.desktop " \ + "invalid-desktop.desktop" +#define HOME_APPS "epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb.desktop" +#define ALL_HOME_APPS HOME_APPS " eog.desktop" + +static void +test_search (void) +{ + assert_list ("", FALSE, FALSE, NULL, NULL); + assert_list (ALL_USR_APPS, TRUE, FALSE, NULL, NULL); + assert_list (ALL_HOME_APPS, FALSE, TRUE, NULL, NULL); + assert_list (ALL_USR_APPS " " HOME_APPS, TRUE, TRUE, NULL, NULL); + + /* The user has "installed" their own version of eog.desktop which + * calls it "Eye of GNOME". Do some testing based on that. + * + * We should always find "Pictures" keyword no matter where we look. + */ + assert_search ("Picture", "eog.desktop\n", TRUE, TRUE, NULL, NULL); + assert_search ("Picture", "eog.desktop\n", TRUE, FALSE, NULL, NULL); + assert_search ("Picture", "eog.desktop\n", FALSE, TRUE, NULL, NULL); + assert_search ("Picture", "", FALSE, FALSE, NULL, NULL); + + /* We should only find it called "eye of gnome" when using the user's + * directory. + */ + assert_search ("eye gnome", "", TRUE, FALSE, NULL, NULL); + assert_search ("eye gnome", "eog.desktop\n", FALSE, TRUE, NULL, NULL); + assert_search ("eye gnome", "eog.desktop\n", TRUE, TRUE, NULL, NULL); + + /* We should only find it called "image viewer" when _not_ using the + * user's directory. + */ + assert_search ("image viewer", "eog.desktop\n", TRUE, FALSE, NULL, NULL); + assert_search ("image viewer", "", FALSE, TRUE, NULL, NULL); + assert_search ("image viewer", "", TRUE, TRUE, NULL, NULL); + + /* There're "flatpak" apps (clocks) installed as well - they should *not* + * match the prefix command ("/bin/sh") in the Exec= line though. + */ + assert_search ("sh", "gnome-terminal.desktop\n", TRUE, FALSE, NULL, NULL); + + /* "frobnicator.desktop" is ignored by get_all() because the binary is + * missing, but search should still find it (to avoid either stale results + * from the cache or expensive stat() calls for each potential result) + */ + assert_search ("frobni", "frobnicator.desktop\n", TRUE, FALSE, NULL, NULL); + + /* Obvious multi-word search */ + assert_search ("gno hel", "yelp.desktop\n", TRUE, TRUE, NULL, NULL); + + /* Repeated search terms should do nothing... */ + assert_search ("files file fil fi f", "nautilus.desktop\n" + "gedit.desktop\n", TRUE, TRUE, NULL, NULL); + + /* "con" will match "connect" and "contacts" on name but dconf only on + * the "config" keyword + */ + assert_search ("con", "nautilus-connect-server.desktop gnome-contacts.desktop\n" + "dconf-editor.desktop\n", TRUE, TRUE, NULL, NULL); + + /* "gnome" will match "eye of gnome" from the user's directory, plus + * matching "GNOME Clocks" X-GNOME-FullName. It's only a comment on + * yelp and gnome-contacts, though. + */ + assert_search ("gnome", "eog.desktop\n" + "org.gnome.clocks.desktop\n" + "yelp.desktop gnome-contacts.desktop\n", TRUE, TRUE, NULL, NULL); + + /* eog has exec name 'false' in usr only */ + assert_search ("false", "eog.desktop\n", TRUE, FALSE, NULL, NULL); + assert_search ("false", "", FALSE, TRUE, NULL, NULL); + assert_search ("false", "", TRUE, TRUE, NULL, NULL); + assert_search ("false", "", FALSE, FALSE, NULL, NULL); + + /* make sure we only search the first component */ + assert_search ("nonsearchable", "", TRUE, FALSE, NULL, NULL); + + /* "gnome con" will match only gnome contacts; via the name for + * "contacts" and the comment for "gnome" + */ + assert_search ("gnome con", "gnome-contacts.desktop\n", TRUE, TRUE, NULL, NULL); + + /* make sure we get the correct kde4- prefix on the application IDs + * from subdirectories + */ + assert_search ("konq", "kde4-konqbrowser.desktop\n", TRUE, TRUE, NULL, NULL); + assert_search ("kate", "kde4-kate.desktop\n", TRUE, TRUE, NULL, NULL); + + /* make sure we can look up apps by name properly */ + assert_info ("kde4-kate.desktop", + "kde4-kate.desktop\n" + "Kate\n" + "Kate\n" + "nil\n", TRUE, TRUE, NULL, NULL); + + assert_info ("nautilus.desktop", + "nautilus.desktop\n" + "Files\n" + "Files\n" + "Access and organize files\n", TRUE, TRUE, NULL, NULL); + + /* make sure localised searching works properly */ + assert_search ("foliumi", "nautilus.desktop\n" + "kde4-konqbrowser.desktop\n" + "eog.desktop\n", TRUE, FALSE, "en_US.UTF-8", "eo"); + /* the user's eog.desktop has no translations... */ + assert_search ("foliumi", "nautilus.desktop\n" + "kde4-konqbrowser.desktop\n", TRUE, TRUE, "en_US.UTF-8", "eo"); +} + +static void +test_implements (void) +{ + /* Make sure we can find our search providers... */ + assert_implementations ("org.gnome.Shell.SearchProvider2", + "gnome-music.desktop gnome-contacts.desktop eog.desktop", + TRUE, FALSE); + + /* And our image acquisition possibilities... */ + assert_implementations ("org.freedesktop.ImageProvider", + "cheese.desktop", + TRUE, FALSE); + + /* Make sure the user's eog is properly masking the system one */ + assert_implementations ("org.gnome.Shell.SearchProvider2", + "gnome-music.desktop gnome-contacts.desktop", + TRUE, TRUE); + + /* Make sure we get nothing if we have nothing */ + assert_implementations ("org.gnome.Shell.SearchProvider2", "", FALSE, FALSE); +} + +static void +assert_shown (const gchar *desktop_id, + gboolean expected, + const gchar *xdg_current_desktop) +{ + gchar *result; + + result = run_apps ("should-show", desktop_id, TRUE, TRUE, NULL, NULL, xdg_current_desktop); + g_assert_cmpstr (result, ==, expected ? "true\n" : "false\n"); + g_free (result); +} + +static void +test_show_in (void) +{ + assert_shown ("gcr-prompter.desktop", FALSE, NULL); + assert_shown ("gcr-prompter.desktop", FALSE, "GNOME"); + assert_shown ("gcr-prompter.desktop", FALSE, "KDE"); + assert_shown ("gcr-prompter.desktop", FALSE, "GNOME:GNOME-Classic"); + assert_shown ("gcr-prompter.desktop", TRUE, "GNOME-Classic:GNOME"); + assert_shown ("gcr-prompter.desktop", TRUE, "GNOME-Classic"); + assert_shown ("gcr-prompter.desktop", TRUE, "GNOME-Classic:KDE"); + assert_shown ("gcr-prompter.desktop", TRUE, "KDE:GNOME-Classic"); + assert_shown ("invalid-desktop.desktop", TRUE, "GNOME"); + assert_shown ("invalid-desktop.desktop", FALSE, "../invalid/desktop"); + assert_shown ("invalid-desktop.desktop", FALSE, "../invalid/desktop:../invalid/desktop"); +} + +static void +on_launch_started (GAppLaunchContext *context, GAppInfo *info, GVariant *platform_data, gpointer data) +{ + gboolean *invoked = data; + + g_assert_true (G_IS_APP_LAUNCH_CONTEXT (context)); + g_assert_true (G_IS_APP_INFO (info)); + /* Our default context doesn't fill in any platform data */ + g_assert_null (platform_data); + + g_assert_false (*invoked); + *invoked = TRUE; +} + +/* Test g_desktop_app_info_launch_uris_as_manager() and + * g_desktop_app_info_launch_uris_as_manager_with_fds() + */ +static void +test_launch_as_manager (void) +{ + GDesktopAppInfo *appinfo; + GError *error = NULL; + gboolean retval; + const gchar *path; + gboolean invoked = FALSE; + GAppLaunchContext *context; + + if (g_getenv ("DISPLAY") == NULL || g_getenv ("DISPLAY")[0] == '\0') + { + g_test_skip ("No DISPLAY. Skipping test."); + return; + } + + path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL); + appinfo = g_desktop_app_info_new_from_filename (path); + + if (appinfo == NULL) + { + g_test_skip ("appinfo-test binary not installed"); + return; + } + + context = g_app_launch_context_new (); + g_signal_connect (context, "launch-started", + G_CALLBACK (on_launch_started), + &invoked); + retval = g_desktop_app_info_launch_uris_as_manager (appinfo, NULL, context, 0, + NULL, NULL, + NULL, NULL, + &error); + g_assert_no_error (error); + g_assert_true (retval); + g_assert_true (invoked); + + invoked = FALSE; + retval = g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo, + NULL, context, 0, + NULL, NULL, + NULL, NULL, + -1, -1, -1, + &error); + g_assert_no_error (error); + g_assert_true (retval); + g_assert_true (invoked); + + g_object_unref (appinfo); + g_assert_finalize_object (context); +} + +/* Test if Desktop-File Id is correctly formed */ +static void +test_id (void) +{ + gchar *result; + + result = run_apps ("default-for-type", "application/vnd.kde.okular-archive", + TRUE, FALSE, NULL, NULL, NULL); + g_assert_cmpstr (result, ==, "kde4-okular.desktop\n"); + g_free (result); +} + +int +main (int argc, + char *argv[]) +{ + /* While we use %G_TEST_OPTION_ISOLATE_DIRS to create temporary directories + * for each of the tests, we want to use the system MIME registry, assuming + * that it exists and correctly has shared-mime-info installed. */ + g_content_type_set_mime_dirs (NULL); + + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add_func ("/desktop-app-info/delete", test_delete); + g_test_add_func ("/desktop-app-info/default", test_default); + g_test_add_func ("/desktop-app-info/fallback", test_fallback); + g_test_add_func ("/desktop-app-info/lastused", test_last_used); + g_test_add_func ("/desktop-app-info/extra-getters", test_extra_getters); + g_test_add_func ("/desktop-app-info/actions", test_actions); + g_test_add_func ("/desktop-app-info/search", test_search); + g_test_add_func ("/desktop-app-info/implements", test_implements); + g_test_add_func ("/desktop-app-info/show-in", test_show_in); + g_test_add_func ("/desktop-app-info/launch-as-manager", test_launch_as_manager); + g_test_add_func ("/desktop-app-info/id", test_id); + + return g_test_run (); +} diff --git a/gio/tests/desktop-files/home/applications/eog.desktop b/gio/tests/desktop-files/home/applications/eog.desktop new file mode 100644 index 0000000..f15bdc8 --- /dev/null +++ b/gio/tests/desktop-files/home/applications/eog.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Eye of GNOME +Exec=true %U +Icon=eog +StartupNotify=true +Terminal=false +Type=Application +Categories=GNOME;GTK;Graphics;2DGraphics;RasterGraphics;Viewer; +MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/x-bmp;image/x-gray;image/x-icb;image/x-ico;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-xbitmap;image/x-xpixmap;image/x-pcx;image/svg+xml;image/svg+xml-compressed;image/vnd.wap.wbmp; +# Extra keywords that can be used to search for eog in GNOME Shell and Unity +Keywords=Picture;Slideshow;Graphics; diff --git a/gio/tests/desktop-files/home/applications/epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb.desktop b/gio/tests/desktop-files/home/applications/epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb.desktop new file mode 100644 index 0000000..83976e0 --- /dev/null +++ b/gio/tests/desktop-files/home/applications/epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=Weather for Toronto Island +Exec=true +StartupNotify=true +Terminal=false +Type=Application +StartupWMClass=epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb diff --git a/gio/tests/desktop-files/usr/applications/baobab.desktop b/gio/tests/desktop-files/usr/applications/baobab.desktop new file mode 100644 index 0000000..198e047 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/baobab.desktop @@ -0,0 +1,39 @@ +[Desktop Entry] +Name=Disk Usage Analyzer +Name[bn]=ডিসà§à¦• বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° বিশà§à¦²à§‡à¦·à¦£ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ +Name[bn_IN]=ডিসà§à¦• বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° বিশà§à¦²à§‡à¦·à¦£ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ +Name[ca]=Analitzador de l'ús dels discs +Name[ca@valencia]=Analitzador de l'ús dels discs +Name[en@shaw]=ð‘›ð‘¦ð‘•ð‘’ ð‘¿ð‘•ð‘¦ð‘¡ ð‘¨ð‘¯ð‘©ð‘¤ð‘²ð‘Ÿð‘» +Name[en_GB]=Disk Usage Analyser +Name[eo]=Diskuzada analizilo +Name[pt]=Analisador de Utilização do Disco +Name[pt_BR]=Analisador de uso de disco +Comment=Check folder sizes and available disk space +Comment[bn]=ফোলà§à¦¡à¦¾à¦°à§‡à¦° মাপ ও ডিসà§à¦•ে বিদà§à¦¯à¦®à¦¾à¦¨ সà§à¦¥à¦¾à¦¨ পরীকà§à¦·à¦¾ করা হবে +Comment[bn_IN]=ফোলà§à¦¡à¦¾à¦°à§‡à¦° মাপ ও ডিসà§à¦•ে উপলবà§à¦§ সà§à¦¥à¦¾à¦¨ পরীকà§à¦·à¦¾ করা হবে +Comment[ca]=Comprova la mida de les carpetes i l'espai disponible al disc +Comment[ca@valencia]=Comprova la mida de les carpetes i l'espai disponible al disc +Comment[en@shaw]=ð‘—ð‘§ð‘’ ð‘“ð‘´ð‘¤ð‘›ð‘¼ ð‘•ð‘²ð‘Ÿð‘©ð‘Ÿ 𑯠ð‘©ð‘ð‘±ð‘¤ð‘©ð‘šð‘©ð‘¤ ð‘›ð‘¦ð‘•ð‘’ ð‘•ð‘ð‘±ð‘• +Comment[en_GB]=Check folder sizes and available disk space +Comment[eo]=Kontroli dosierujajn grandojn kaj disponeblan diskmemoron +Comment[pt]=Verificar o tamanho das pastas e o espaço disponível em disco +Comment[pt_BR]=Verifique o tamanho de pastas e o espaço disponível em disco +Keywords=storage;space;cleanup; +Keywords[ca]=emmagatzemament;espai;neteja; +Keywords[ca@valencia]=emmagatzemament;espai;neteja; +Keywords[eo]=spaco;diskospaco;purigi;senrubigi; +Keywords[pt]=armazenamento;espaço;limpar; +Keywords[pt_BR]=armazenamento;espaço;limpeza; +Exec=true +Icon=baobab +Terminal=false +Type=Application +StartupNotify=true +MimeType=inode/directory; +Categories=GTK;GNOME;System;Filesystem; +NotShowIn=KDE; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-utils +X-GNOME-Bugzilla-Component=baobab +X-GNOME-Bugzilla-Version=3.10 diff --git a/gio/tests/desktop-files/usr/applications/cheese.desktop b/gio/tests/desktop-files/usr/applications/cheese.desktop new file mode 100644 index 0000000..650c500 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/cheese.desktop @@ -0,0 +1,47 @@ +[Desktop Entry] +Name=Cheese +Name[bn]=Cheese +Name[bn_IN]=Cheese +Name[ca]=Cheese +Name[ca@valencia]=Cheese +Name[en@shaw]=·ð‘—ð‘°ð‘Ÿ +Name[en_GB]=Cheese +Name[eo]=Rideto +Name[pt]=Cheese +Name[pt_BR]=Cheese +X-GNOME-FullName=Cheese Webcam Booth +X-GNOME-FullName[bn]=Cheese ওয়েবকà§à¦¯à¦¾à¦® বà§à¦¥ +X-GNOME-FullName[bn_IN]=Cheese-র ওয়েবকà§à¦¯à¦¾à¦® বà§à¦¥ +X-GNOME-FullName[ca]=Cabina de fotografia del Cheese +X-GNOME-FullName[ca@valencia]=Cabina de fotografia del Cheese +X-GNOME-FullName[en@shaw]=·ð‘—ð‘°ð‘Ÿ ð‘¢ð‘§ð‘šð‘’ð‘¨ð‘¥ ð‘šð‘µð‘” +X-GNOME-FullName[en_GB]=Cheese Webcam Booth +X-GNOME-FullName[eo]=Rideto-Retkamerao-Budo +X-GNOME-FullName[pt]=Cabine Fotográfica Cheese +X-GNOME-FullName[pt_BR]=Cabine de webcam do Cheese +Comment=Take photos and videos with your webcam, with fun graphical effects +Comment[bn]=ওয়েবকà§à¦¯à¦¾à¦®à§‡à¦° সাহাযà§à¦¯à§‡ মজাদার গà§à¦°à¦¾à¦«à¦¿à¦•à§à¦¸à§‡à¦° আবহসহ ফটো তà§à¦²à§à¦¨ ও ভিডিও তৈরি করà§à¦¨ +Comment[bn_IN]=ওয়েবকà§à¦¯à¦¾à¦®à§‡à¦° সাহাযà§à¦¯à§‡ মজাদার গà§à¦°à§à¦¯à¦¾à¦«à¦¿à¦•à§à¦¸ সহ ফটো তà§à¦²à§à¦¨ ও ভিডিও তৈরি করà§à¦¨ +Comment[ca]=Feu fotos i vídeos amb la càmera web, amb efectes gràfics divertits +Comment[ca@valencia]=Feu fotos i vídeos amb la càmera web, amb efectes gràfics divertits +Comment[en@shaw]=ð‘‘ð‘±ð‘’ ð‘“ð‘´ð‘‘ð‘´ð‘Ÿ 𑯠ð‘ð‘¦ð‘›ð‘°ð‘´ð‘Ÿ ð‘¢ð‘¦ð‘ž ð‘¿ð‘¼ ð‘¢ð‘§ð‘šð‘’ð‘¨ð‘¥, ð‘¢ð‘¦ð‘ž ð‘“ð‘³ð‘¯ ð‘œð‘®ð‘¨ð‘“ð‘¦ð‘’ð‘©ð‘¤ ð‘¦ð‘“ð‘§ð‘’ð‘‘ð‘• +Comment[en_GB]=Take photos and videos with your webcam, with fun graphical effects +Comment[eo]=Fari fotaĵojn kaj videojn per via retkamerao, kun gajaj grafikaj efektoj +Comment[pt]=Tire fotografias e grave vídeos com a sua webcam, com engraçados efeitos gráficos +Comment[pt_BR]=Tire fotos e vídeos com sua webcam, com efeitos gráficos divertidos +Keywords=photo;video;webcam; +Keywords[ca]=foto;vídeo;càmera web; +Keywords[ca@valencia]=foto;vídeo;càmera web; +Keywords[pt]=foto;vídeo;webcam; +Keywords[pt_BR]=foto;fotos;vídeo;vídeos;webcam; +Exec=true +Terminal=false +Type=Application +StartupNotify=true +Icon=cheese +Categories=GNOME;AudioVideo;Video;Recorder; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=cheese +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.11.1 +Implements=org.freedesktop.ImageProvider diff --git a/gio/tests/desktop-files/usr/applications/dconf-editor.desktop b/gio/tests/desktop-files/usr/applications/dconf-editor.desktop new file mode 100644 index 0000000..6d6b66d --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/dconf-editor.desktop @@ -0,0 +1,33 @@ +[Desktop Entry] +Name=dconf Editor +Name[bn_IN]=dconf সমà§à¦ªà¦¾à¦¦à¦• +Name[ca]=Editor del dconf +Name[ca@valencia]=Editor del dconf +Name[en_GB]=dconf Editor +Name[eo]=dconf Redaktilo +Name[pt]=Editor dconf +Name[pt_BR]=Editor do dconf +Comment=Directly edit your entire configuration database +Comment[bn_IN]=আপনার সমà§à¦ªà§‚রà§à¦£ কনফিগারেশন ডাটাবেস সরাসরি সমà§à¦ªà¦¾à¦¦à¦¨ করà§à¦¨ +Comment[ca]=Editeu directament la base de dades de configuració +Comment[ca@valencia]=Editeu directament la base de dades de configuració +Comment[en_GB]=Directly edit your entire configuration database +Comment[eo]=Rekte redakti vian totan agordan datumbazon +Comment[pt]=Edite diretamente toda a sua base de dados de configuração +Comment[pt_BR]=Edite diretamente seu banco de dados de configuração por inteiro +Keywords=settings;configuration; +Keywords[ca]=paràmetres;configuració; +Keywords[ca@valencia]=paràmetres;configuració; +Keywords[eo]=agordoj; +Keywords[pt]=definições;configuração; +Keywords[pt_BR]=ajustes;configuração;configurações; +Exec=true +Terminal=false +Type=Application +Icon=dconf-editor +StartupNotify=true +Categories=GNOME;GTK;System; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=dconf +X-GNOME-Bugzilla-Component=editor +X-GNOME-Bugzilla-Version=0.18.0 diff --git a/gio/tests/desktop-files/usr/applications/eog.desktop b/gio/tests/desktop-files/usr/applications/eog.desktop new file mode 100644 index 0000000..8dc3911 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/eog.desktop @@ -0,0 +1,44 @@ +[Desktop Entry] +Name=Image Viewer +Name[bn]=ছবি পà§à¦°à¦¦à¦°à§à¦¶à¦• +Name[bn_IN]=ছবি পà§à¦°à¦¦à¦°à§à¦¶à¦• +Name[ca]=Visualitzador d'imatges +Name[ca@valencia]=Visualitzador d'imatges +Name[en@shaw]=ð‘¦ð‘¥ð‘¦ð‘¡ ð‘ð‘¿ð‘¼ +Name[en_CA]=Image Viewer +Name[en_GB]=Image Viewer +Name[eo]=Bildomontrilo +Name[pt]=Visualizador de Imagens +Name[pt_BR]=Visualizador de imagens +Comment=Browse and rotate images +Comment[bn]=ছবি বà§à¦°à¦¾à¦‰à¦œ করà§à¦¨ à¦à¦¬à¦‚ চকà§à¦°à¦¾à¦•ারে ঘোরান +Comment[bn_IN]=ছবি বà§à¦°à¦¾à¦‰à¦œ করà§à¦¨ ও ঘà§à¦°à¦¿à§Ÿà§‡ নিন +Comment[ca]=Navegueu per imatges i gireu-les +Comment[ca@valencia]=Navegueu per imatges i gireu-les +Comment[en@shaw]=ð‘šð‘®ð‘¬ð‘Ÿ 𑯠ð‘®ð‘´ð‘‘ð‘±ð‘‘ ð‘¦ð‘¥ð‘¦ð‘¡ð‘©ð‘Ÿ +Comment[en_CA]=Browse and rotate images +Comment[en_GB]=Browse and rotate images +Comment[eo]=Foliumi kaj turni bildojn +Comment[pt]=Navegue e rode imagens +Comment[pt_BR]=Navegue e gire imagens +Exec=false --nonsearchable %U +Icon=eog +StartupNotify=true +Terminal=false +Type=Application +Categories=GNOME;GTK;Graphics;2DGraphics;RasterGraphics;Viewer; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=EOG +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.1 +X-GNOME-DocPath=eog/eog.xml +MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/x-bmp;image/x-gray;image/x-icb;image/x-ico;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-xbitmap;image/x-xpixmap;image/x-pcx;image/svg+xml;image/svg+xml-compressed;image/vnd.wap.wbmp; +# Extra keywords that can be used to search for eog in GNOME Shell and Unity +Keywords=Picture;Slideshow;Graphics; +Keywords[ca]=Fotografia;Diapositives;Gràfics; +Keywords[ca@valencia]=Fotografia;Diapositives;Gràfics; +Keywords[en_GB]=Picture;Slideshow;Graphics; +Keywords[eo]=Bildo;Lumbildprezentado;Grafiko; +Keywords[pt]=Imagem;Apresentação;Gráficos; +Keywords[pt_BR]=Fotos;Apresentação de slides;Gráficos; +Implements=org.gnome.Shell.SearchProvider2 diff --git a/gio/tests/desktop-files/usr/applications/evince-previewer.desktop b/gio/tests/desktop-files/usr/applications/evince-previewer.desktop new file mode 100644 index 0000000..c6a2e84 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/evince-previewer.desktop @@ -0,0 +1,28 @@ +[Desktop Entry] +Name=Print Preview +Name[ca]=Previsualitza la impressió +Name[ca@valencia]=Previsualitza la impressió +Name[en_GB]=Print Preview +Name[eo]=Aspekto de la presotaĵo +Name[pt]=Antevisão de Impressão +Name[pt_BR]=Visualizar de impressão +Comment=Preview before printing +Comment[ca]=Previsualitza abans d'imprimir +Comment[ca@valencia]=Previsualitza abans d'imprimir +Comment[en_GB]=Preview before printing +Comment[eo]=Aspekti antaÅ­ presi +Comment[pt]=Antever antes de imprimir +Comment[pt_BR]=Visualize antes de imprimir +Exec=true %U +StartupNotify=true +Terminal=false +Type=Application +Icon=document-print-preview +NoDisplay=true +X-GNOME-DocPath= +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=evince +X-GNOME-Bugzilla-Component=BugBuddyBugs +X-GNOME-Bugzilla-Version=3.10.0 +Categories=GNOME;GTK;Office;Viewer;Graphics;2DGraphics;VectorGraphics; +MimeType=application/pdf;application/x-bzpdf;application/x-gzpdf;application/x-xzpdf;image/tiff;application/x-cbr;application/x-cbz;application/x-cb7;application/x-cbt;application/oxps;application/vnd.ms-xpsdocument; diff --git a/gio/tests/desktop-files/usr/applications/evince.desktop b/gio/tests/desktop-files/usr/applications/evince.desktop new file mode 100644 index 0000000..45711db --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/evince.desktop @@ -0,0 +1,42 @@ +[Desktop Entry] +Name=Document Viewer +Name[bn]=নথি পà§à¦°à¦¦à¦°à§à¦¶à¦• +Name[bn_IN]=ডকà§à¦®à§‡à¦¨à§à¦Ÿ পà§à¦°à¦¦à¦°à§à¦¶à¦¨ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ +Name[ca]=Visualitzador de documents +Name[ca@valencia]=Visualitzador de documents +Name[en@shaw]=ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘ð‘¿ð‘¼ +Name[en_CA]=Document Viewer +Name[en_GB]=Document Viewer +Name[eo]=Dokumentmontrilo +Name[pt]=Visualizador de Documento +Name[pt_BR]=Visualizador de documentos +Comment=View multi-page documents +Comment[bn]=বহà§à¦ªà§ƒà¦·à§à¦ à¦¾ সমà§à¦¬à¦²à¦¿à¦¤ নথি পà§à¦°à¦¦à¦°à§à¦¶à¦¨ +Comment[bn_IN]=à¦à¦•াধিক পৃষà§à¦ à¦¾à¦¬à¦¿à¦¶à¦¿à¦·à§à¦Ÿ ডকà§à¦®à§‡à¦¨à§à¦Ÿ দেখà§à¦¨ +Comment[ca]=Visualitzeu documents multipàgina +Comment[ca@valencia]=Visualitzeu documents multipàgina +Comment[en@shaw]=ð‘ð‘¿ ð‘¥ð‘©ð‘¤ð‘‘ð‘°-ð‘ð‘±ð‘¡ ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ð‘• +Comment[en_CA]=View multi-page documents +Comment[en_GB]=View multi-page documents +Comment[eo]=Montri mult-paÄajn dokumentojn +Comment[pt]=Visualizar documentos multipáginas +Comment[pt_BR]=Visualize documentos de múltiplas páginas +Keywords=pdf;ps;postscript;dvi;xps;djvu;tiff;document;presentation; +Keywords[ca]=pdf;ps;postscript;dvi;xps;djvu;tiff;document;presentació; +Keywords[ca@valencia]=pdf;ps;postscript;dvi;xps;djvu;tiff;document;presentació; +Keywords[en_GB]=pdf;ps;postscript;dvi;xps;djvu;tiff;document;presentation; +Keywords[eo]=pdf;ps;postscript;dvi;xps;djvu;tiff;dokumento;prezentaĵo; +Keywords[pt]=pdf;ps;postscript;dvi;xps;djvu;tiff;documento;apresentação; +Keywords[pt_BR]=pdf;ps;postscript;dvi;xps;djvu;tiff;documento;apresentação; +Exec=true %U +StartupNotify=true +Terminal=false +Type=Application +Icon=evince +X-GNOME-DocPath= +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=evince +X-GNOME-Bugzilla-Component=BugBuddyBugs +X-GNOME-Bugzilla-Version=3.10.0 +Categories=GNOME;GTK;Office;Viewer;Graphics;2DGraphics;VectorGraphics; +MimeType=application/pdf;application/x-bzpdf;application/x-gzpdf;application/x-xzpdf;image/tiff;application/x-cbr;application/x-cbz;application/x-cb7;application/x-cbt;application/oxps;application/vnd.ms-xpsdocument; diff --git a/gio/tests/desktop-files/usr/applications/file-roller.desktop b/gio/tests/desktop-files/usr/applications/file-roller.desktop new file mode 100644 index 0000000..72e28a1 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/file-roller.desktop @@ -0,0 +1,43 @@ +[Desktop Entry] +Name=Archive Manager +Name[bn]=আরà§à¦•াইভ মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦° +Name[bn_IN]=আরà§à¦•াইভ পরিচালন বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ +Name[ca]=Gestor d'arxius +Name[ca@valencia]=Gestor d'arxius +Name[en@shaw]=ð‘¸ð‘’ð‘²ð‘ ð‘¥ð‘¨ð‘¯ð‘©ð‘¡ð‘¼ +Name[en_CA]=Archive Manager +Name[en_GB]=Archive Manager +Name[eo]=Arkivo-administrilo +Name[pt]=Gestor de Arquivos +Name[pt_BR]=Gerenciador de pacotes +Comment=Create and modify an archive +Comment[bn]=নতà§à¦¨ আরà§à¦•াইভ তৈরি ও পরিবরà§à¦§à¦¨ করা হবে +Comment[bn_IN]=আরà§à¦•াইভ নিরà§à¦®à¦¾à¦£ ও পরিবরà§à¦¤à¦¨ করà§à¦¨ +Comment[ca]=Crea i modifica un arxiu +Comment[ca@valencia]=Crea i modifica un arxiu +Comment[en@shaw]=ð‘’ð‘®ð‘¦ð‘±ð‘‘ 𑯠ð‘¥ð‘ªð‘›ð‘¦ð‘“𑲠ð‘©ð‘¯ ð‘¸ð‘’ð‘²ð‘ +Comment[en_CA]=Create and modify an archive +Comment[en_GB]=Create and modify an archive +Comment[eo]=Krei kaj modifi arkivon +Comment[pt]=Criar e alterar um arquivo +Comment[pt_BR]=Crie e modifique um pacote +Keywords=zip;tar;extract;unpack; +Keywords[ca]=zip;tar;extreure;desampaquetar; +Keywords[ca@valencia]=zip;tar;extraure;desampaquetar; +Keywords[eo]=zip;tar;eltiri;malkompaktigi;malpaki;elpaki; +Keywords[pt]=zip;tar;extrair;desempacotar; +Keywords[pt_BR]=zip;tar;extrair;descompactar; +Exec=true %U +StartupNotify=true +Terminal=false +Type=Application +Icon=file-roller +Categories=GTK;GNOME;Utility;Archiving;Compression; +NotShowIn=KDE; +MimeType=application/x-7z-compressed;application/x-7z-compressed-tar;application/x-ace;application/x-alz;application/x-ar;application/x-arj;application/x-bzip;application/x-bzip-compressed-tar;application/x-bzip1;application/x-bzip1-compressed-tar;application/x-cabinet;application/x-cbr;application/x-cbz;application/x-cd-image;application/x-compress;application/x-compressed-tar;application/x-cpio;application/x-deb;application/x-ear;application/x-ms-dos-executable;application/x-gtar;application/x-gzip;application/x-gzpostscript;application/x-java-archive;application/x-lha;application/x-lhz;application/x-lrzip;application/x-lrzip-compressed-tar;application/x-lzip;application/x-lzip-compressed-tar;application/x-lzma;application/x-lzma-compressed-tar;application/x-lzop;application/x-lzop-compressed-tar;application/x-ms-wim;application/x-rar;application/x-rar-compressed;application/x-rpm;application/x-rzip;application/x-rzip-compressed-tar;application/x-tar;application/x-tarz;application/x-stuffit;application/x-war;application/x-xz;application/x-xz-compressed-tar;application/x-zip;application/x-zip-compressed;application/x-zoo;application/zip;application/x-archive;application/vnd.ms-cab-compressed; +X-GNOME-DocPath=file-roller/file-roller.xml +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=file-roller +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.0 +X-GNOME-UsesNotifications=true diff --git a/gio/tests/desktop-files/usr/applications/frobnicator.desktop b/gio/tests/desktop-files/usr/applications/frobnicator.desktop new file mode 100644 index 0000000..0a8dbfa --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/frobnicator.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Frobnicator +Comment=Frobnicate your life! +Exec=/does-not-exist +Icon=frobnicator +StartupNotify=true +Terminal=false +Type=Application +Categories=GNOME;GTK;Utilities diff --git a/gio/tests/desktop-files/usr/applications/gcr-prompter.desktop b/gio/tests/desktop-files/usr/applications/gcr-prompter.desktop new file mode 100644 index 0000000..15273b0 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/gcr-prompter.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] +Name=Access Prompt +Name[ca]=Petició d'accés +Name[ca@valencia]=Petició d'accés +Name[en_GB]=Access Prompt +Name[pt]=Pedido de Acesso +Name[pt_BR]=Prompt de acesso +Comment=Unlock access to passwords and other secrets +Comment[ca]=Desbloca l'accés a les contrasenyes i altres secrets +Comment[ca@valencia]=Desbloca l'accés a les contrasenyes i altres secrets +Comment[en_GB]=Unlock access to passwords and other secrets +Comment[pt]=Destrancar acesso a senhas e outros segredos +Comment[pt_BR]=Destravar acesso a senhas e outros segredos +Icon=security-medium +Exec=true +Terminal=false +Type=Application +OnlyShowIn=GNOME-Classic +NotShowIn=GNOME diff --git a/gio/tests/desktop-files/usr/applications/gcr-viewer.desktop b/gio/tests/desktop-files/usr/applications/gcr-viewer.desktop new file mode 100644 index 0000000..64a8e52 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/gcr-viewer.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=View file +MimeType=application/pkcs12;application/pkcs12+pem;application/pkcs7-mime;application/pkcs7-mime+pem;application/pkcs8;application/pkcs8+pem;application/pkix-cert;application/pkix-cert+pem;application/pkix-crl;application/pkix-crl+pem;application/x-pem-file;application/x-pem-key;application/x-pkcs12;application/x-pkcs7-certificates;application/x-x509-ca-cert;application/x-x509-user-cert;application/pkcs10;application/pkcs10+pem;application/x-spkac;application/x-spkac+base64; +Exec=true +Type=Application +Terminal=false +NoDisplay=true +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-keyring +X-GNOME-Bugzilla-Component=gcr diff --git a/gio/tests/desktop-files/usr/applications/gedit.desktop b/gio/tests/desktop-files/usr/applications/gedit.desktop new file mode 100644 index 0000000..faf89ae --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/gedit.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Name=gedit +Name[bn]=জিà¦à¦¡à¦¿à¦Ÿ +Name[bn_IN]=gedit +Name[ca]=gedit +Name[ca@valencia]=gedit +Name[en@shaw]=·ð‘œð‘§ð‘›ð‘¦ð‘‘ +Name[en_CA]=gedit +Name[en_GB]=gedit +Name[eo]=Gedit +Name[pt]=gedit +Name[pt_BR]=gedit +GenericName=Text Editor +GenericName[bn]=টেকà§à¦¸à¦Ÿ সমà§à¦ªà¦¾à¦¦à¦• +GenericName[bn_IN]=টেকà§à¦¸à¦Ÿ à¦à¦¡à¦¿à¦Ÿà¦¾à¦° +GenericName[ca]=Editor de text +GenericName[ca@valencia]=Editor de text +GenericName[en@shaw]=ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘§ð‘›ð‘¦ð‘‘𑼠+GenericName[en_CA]=Text Editor +GenericName[en_GB]=Text Editor +GenericName[eo]=Tekstredaktilo +GenericName[pt]=Editor de Texto +GenericName[pt_BR]=Editor de texto +Comment=Edit text files +Comment[bn]=টেকà§à¦¸à¦Ÿ ফাইল সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করà§à¦¨ +Comment[bn_IN]=টেকà§à¦¸à¦Ÿ ফাইল সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ +Comment[ca]=Editeu fitxers de text +Comment[ca@valencia]=Editeu fitxers de text +Comment[en@shaw]=ð‘§ð‘›ð‘¦ð‘‘ ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘“ð‘²ð‘¤ð‘Ÿ +Comment[en_CA]=Edit text files +Comment[en_GB]=Edit text files +Comment[eo]=Redakti tekstdosierojn +Comment[pt]=Editar ficheiros de texto +Comment[pt_BR]=Edite arquivos de texto +Exec=true +Terminal=false +Type=Application +StartupNotify=true +MimeType=text/plain; +Icon=accessories-text-editor +Categories=GNOME;GTK;Utility;TextEditor; +X-GNOME-DocPath=gedit/gedit.xml +X-GNOME-FullName=gedit Text Editor +X-GNOME-FullName[bn]=জিà¦à¦¡à¦¿à¦Ÿ টেকà§à¦¸à¦Ÿ সমà§à¦ªà¦¾à¦¦à¦• +X-GNOME-FullName[bn_IN]=gedit টেকà§à¦¸à¦Ÿ à¦à¦¡à¦¿à¦Ÿà¦¾à¦° +X-GNOME-FullName[ca]=Editor de text gedit +X-GNOME-FullName[ca@valencia]=Editor de text gedit +X-GNOME-FullName[en@shaw]=·ð‘œð‘§ð‘›ð‘¦ð‘‘ ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘§ð‘›ð‘¦ð‘‘𑼠+X-GNOME-FullName[en_GB]=gedit Text Editor +X-GNOME-FullName[eo]=Gedit tekstredaktilo +X-GNOME-FullName[pt]=Editor de Texto gedit +X-GNOME-FullName[pt_BR]=Editor de texto gedit +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gedit +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.0 +X-GNOME-Bugzilla-ExtraInfoScript=true +Actions=Window;Document; +Keywords=Text;Editor; +Keywords[ca]=Text;Editor; +Keywords[ca@valencia]=Text;Editor; +Keywords[pt]=Texto;Editor; +Keywords[pt_BR]=Texto;Editor; + +[Desktop Action Window] +Name=Open a New Window +Name[bn_IN]=à¦à¦•টি নতà§à¦¨ উইনà§à¦¡à§‹ খà§à¦²à§à¦¨ +Name[ca]=Obre una finestra nova +Name[ca@valencia]=Obri una finestra nova +Name[en_GB]=Open a New Window +Name[pt]=Abrir uma Nova Janela +Name[pt_BR]=Abrir uma nova janela +Exec=true + +[Desktop Action Document] +Name=Open a New Document +Name[bn_IN]=নতà§à¦¨ ডকà§à¦®à§‡à¦¨à§à¦Ÿ খà§à¦²à§à¦¨ +Name[ca]=Obre un document nou +Name[ca@valencia]=Obri un document nou +Name[en_GB]=Open a New Document +Name[pt]=Abrir um Novo Documento +Name[pt_BR]=Abrir um novo documento +Exec=true diff --git a/gio/tests/desktop-files/usr/applications/glade.desktop b/gio/tests/desktop-files/usr/applications/glade.desktop new file mode 100644 index 0000000..dcede22 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/glade.desktop @@ -0,0 +1,56 @@ +[Desktop Entry] +Name=Glade +Name[bn]=Glade +Name[bn_IN]=Glade +Name[ca]=Glade +Name[ca@valencia]=Glade +Name[en@shaw]=·ð‘œð‘¤ð‘±ð‘› +Name[en_CA]=Glade +Name[en_GB]=Glade +Name[eo]=Glado +Name[pt]=Glade +Name[pt_BR]=Glade +GenericName=Interface Designer +GenericName[ca]=Dissenyador d'interfícies +GenericName[ca@valencia]=Dissenyador d'interfícies +GenericName[en@shaw]=ð‘¦ð‘¯ð‘‘ð‘¼ð‘“ð‘±ð‘• ð‘›ð‘©ð‘Ÿð‘²ð‘¯ð‘¼ +GenericName[en_GB]=Interface Designer +GenericName[eo]=Interfaco-dizajnilo +GenericName[pt]=Desenhador de Interfaces +GenericName[pt_BR]=Construtor de interface +X-GNOME-FullName=Glade Interface Designer +X-GNOME-FullName[ca]=Dissenyador d'interfícies Glade +X-GNOME-FullName[ca@valencia]=Dissenyador d'interfícies Glade +X-GNOME-FullName[en@shaw]=·ð‘œð‘¤ð‘±ð‘› ð‘¦ð‘¯ð‘‘ð‘¼ð‘“ð‘±ð‘• ð‘›ð‘©ð‘Ÿð‘²ð‘¯ð‘¼ +X-GNOME-FullName[en_CA]=Glade Interface Designer +X-GNOME-FullName[en_GB]=Glade Interface Designer +X-GNOME-FullName[eo]=Uzantointerfaca dizajnilo Glado +X-GNOME-FullName[pt]=Designer de Interfaces Glade +X-GNOME-FullName[pt_BR]=Construtor de interfaces Glade +Comment=Create or open user interface designs for GTK+ applications +Comment[ca]=Creeu o obriu dissenys d'interfície d'usuari per a aplicacions GTK+ +Comment[ca@valencia]=Creeu o obriu dissenys d'interfície d'usuari per a aplicacions GTK+ +Comment[en@shaw]=ð‘’ð‘®ð‘¦ð‘±ð‘‘ 𑹠ð‘´ð‘ð‘©ð‘¯ ð‘¿ð‘Ÿð‘¼ ð‘¦ð‘¯ð‘‘ð‘¼ð‘“ð‘±ð‘• ð‘›ð‘©ð‘Ÿð‘²ð‘¯ð‘Ÿ ð‘“𑹠GTK+ ð‘©ð‘ð‘¤ð‘¦ð‘’ð‘±ð‘•ð‘©ð‘¯ð‘Ÿ +Comment[en_CA]=Create or open user interface designs for GTK+ applications +Comment[en_GB]=Create or open user interface designs for GTK+ applications +Comment[eo]=Krei aÅ­ malfermi uzantointerfacan dizajnon por aplikaĵoj de GTK+ +Comment[pt]=Criar ou abrir um desenho de interface de utilizador para aplicações GTK+ +Comment[pt_BR]=Crie ou abra projetos de interface com o usuário para aplicativos GTK+ +Keywords=GUI designer;user interface;ui builder; +Keywords[ca]=dissenyador d'interfícies d'usuari gràfiques;interfície d'usuari;constructor d'interfícies d'usuari; +Keywords[ca@valencia]=dissenyador d'interfícies d'usuari gràfiques;interfície d'usuari;constructor d'interfícies d'usuari; +Keywords[en_GB]=GUI designer;user interface;ui builder; +Keywords[pt]=criador IU;interface utilizador;interface gráfico; +Keywords[pt_BR]=Construtor de interface gráfica;Construtor de GUI;interface de usuário;construtor de interface;construtor de ui; +Exec=true +Terminal=false +StartupNotify=true +Type=Application +Icon=glade +Categories=GNOME;GTK;Development;GUIDesigner; +MimeType=application/x-glade; +X-GNOME-DocPath=glade/glade.xml +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=glade +X-GNOME-Bugzilla-Version=3.16.0 +X-GNOME-Bugzilla-Component=general diff --git a/gio/tests/desktop-files/usr/applications/gnome-contacts.desktop b/gio/tests/desktop-files/usr/applications/gnome-contacts.desktop new file mode 100644 index 0000000..388b26f --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/gnome-contacts.desktop @@ -0,0 +1,26 @@ +[Desktop Entry] +Name=Contacts +Name[bn_IN]=পরিচিতি-সমূহ +Name[ca]=Contactes +Name[ca@valencia]=Contactes +Name[en_CA]=Contacts +Name[en_GB]=Contacts +Name[eo]=Kontaktaro +Name[pt]=Contactos +Name[pt_BR]=Contatos +Comment=A contacts manager for GNOME +Keywords=friends;address book; +Keywords[bn_IN]=বনà§à¦§à§; ঠিকানা বই; +Keywords[ca]=amics;llibreta d'adreces; +Keywords[ca@valencia]=amics;llibreta d'adreces; +Keywords[eo]=amikoj;adreslibro; +Keywords[pt]=amigos;livro de endereços; +Keywords[pt_BR]=amigos;catálogo de endereços; +Icon=x-office-address-book +Exec=true +Terminal=false +Type=Application +StartupNotify=true +Categories=GNOME;GTK;Utility; +OnlyShowIn=GNOME;Unity; +Implements=org.gnome.Shell.SearchProvider2 diff --git a/gio/tests/desktop-files/usr/applications/gnome-font-viewer.desktop b/gio/tests/desktop-files/usr/applications/gnome-font-viewer.desktop new file mode 100644 index 0000000..a3f7e45 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/gnome-font-viewer.desktop @@ -0,0 +1,33 @@ +[Desktop Entry] +Name=Font Viewer +Name[bn_IN]=ফনà§à¦Ÿ পà§à¦°à¦¦à¦°à§à¦¶à¦¨ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ +Name[ca]=Visualitzador de tipus de lletra +Name[ca@valencia]=Visualitzador de tipus de lletra +Name[en_GB]=Font Viewer +Name[eo]=Tipar-rigardilo +Name[pt]=Visualizador de Fontes +Name[pt_BR]=Visualizador de fontes +Comment=View fonts on your system +Comment[bn_IN]=সিসà§à¦Ÿà§‡à¦®à§‡à¦° মধà§à¦¯à§‡ উপসà§à¦¥à¦¿à¦¤ ফনà§à¦Ÿ দেখà§à¦¨ +Comment[ca]=Visualitza tots els tipus de lletra del sistema +Comment[ca@valencia]=Visualitza tots els tipus de lletra del sistema +Comment[en_GB]=View fonts on your system +Comment[pt]=Visualize as fontes no seu sistema +Comment[pt_BR]=Ver fontes no seu sistema +Keywords=fonts;fontface; +Keywords[ca]=tipus de lletra;tipografia; +Keywords[ca@valencia]=tipus de lletra;tipografia; +Keywords[pt]=fontes;tipos de fonte; +Keywords[pt_BR]=fontes;tipo de fonte;tipo da fonte; +Icon=preferences-desktop-font +Exec=true %u +Terminal=false +Type=Application +StartupNotify=true +Categories=GTK;GNOME;Utility; +MimeType=application/x-font-ttf;application/x-font-pcf;application/x-font-type1;application/x-font-otf; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-font-viewer +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-OtherBinaries=gnome-thumbnail-font +X-GNOME-Bugzilla-Version=3.10.0 diff --git a/gio/tests/desktop-files/usr/applications/gnome-music.desktop b/gio/tests/desktop-files/usr/applications/gnome-music.desktop new file mode 100644 index 0000000..e4262cd --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/gnome-music.desktop @@ -0,0 +1,23 @@ +[Desktop Entry] +Name=Music +Name[ca]=Música +Name[en_GB]=Music +Name[pt]=Música +Name[pt_BR]=Músicas +GenericName=Music Player +GenericName[ca]=Reproductor de música +GenericName[en_GB]=Music Player +GenericName[pt]=Reprodutor de Música +GenericName[pt_BR]=Reprodutor de músicas +Comment=Play and organize your music collection +Comment[ca]=Reproduïu i organitzeu la col·lecció de música +Comment[en_GB]=Play and organise your music collection +Comment[pt]=Reproduz e organiza a sua coleção de media +Comment[pt_BR]=Reproduza e organize sua coleção de músicas +Icon=gnome-music +Exec=true +Terminal=false +Type=Application +Categories=GNOME;GTK;AudioVideo;Player;Audio; +StartupNotify=true +Implements=org.gnome.Shell.SearchProvider2 diff --git a/gio/tests/desktop-files/usr/applications/gnome-terminal.desktop b/gio/tests/desktop-files/usr/applications/gnome-terminal.desktop new file mode 100644 index 0000000..5f0ad8b --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/gnome-terminal.desktop @@ -0,0 +1,39 @@ +[Desktop Entry] +Name=Terminal +Name[bn]=টারà§à¦®à¦¿à¦¨à¦¾à¦² +Name[bn_IN]=টারà§à¦®à¦¿à¦¨à§à¦¯à¦¾à¦² +Name[ca]=Terminal +Name[ca@valencia]=Terminal +Name[en@shaw]=ð‘‘ð‘»ð‘¥ð‘¦ð‘¯ð‘©ð‘¤ +Name[en_CA]=Terminal +Name[en_GB]=Terminal +Name[eo]=Terminalo +Name[pt]=Consola +Name[pt_BR]=Terminal +Comment=Use the command line +Comment[bn]=কমানà§à¦¡ লাইন বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ +Comment[bn_IN]=কমানà§à¦¡ লাইন বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ +Comment[ca]=Obriu la línia d'ordres +Comment[ca@valencia]=Obriu la línia d'ordes +Comment[en@shaw]=ð‘¿ð‘• 𑞠ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘› ð‘¤ð‘²ð‘¯ +Comment[en_CA]=Use the command line +Comment[en_GB]=Use the command line +Comment[eo]=Uzi la komandolinion +Comment[pt]=Utilizar a linha de comando +Comment[pt_BR]=Use a linha de comando +Keywords=shell;prompt;command;commandline; +Keywords[ca]=intèrpret d'ordres;indicador;ordre;línia d'ordres; +Keywords[ca@valencia]=intèrpret d'ordes;indicador;orde;línia d'ordes; +Keywords[en_GB]=shell;prompt;command;commandline; +Keywords[pt]=consola;linha;comando;terminal; +Keywords[pt_BR]=shell;prompt;comando;comandos;linha de comando; +Exec=true +Icon=utilities-terminal +Type=Application +X-GNOME-DocPath=gnome-terminal/index.html +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-terminal +X-GNOME-Bugzilla-Component=BugBuddyBugs +X-GNOME-Bugzilla-Version=3.10.1 +Categories=GNOME;GTK;System;TerminalEmulator; +StartupNotify=true diff --git a/gio/tests/desktop-files/usr/applications/gucharmap.desktop b/gio/tests/desktop-files/usr/applications/gucharmap.desktop new file mode 100644 index 0000000..912e9b3 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/gucharmap.desktop @@ -0,0 +1,38 @@ +[Desktop Entry] +Name=Character Map +Name[bn]=অকà§à¦·à¦°à§‡à¦° মà§à¦¯à¦¾à¦ª +Name[bn_IN]=অকà§à¦·à¦°à§‡à¦° মà§à¦¯à¦¾à¦ª +Name[ca]=Mapa de caràcters +Name[ca@valencia]=Mapa de caràcters +Name[en@shaw]=ð‘’ð‘¸ð‘©ð‘’ð‘‘𑼠ð‘¥ð‘¨ð‘ +Name[en_CA]=Character Map +Name[en_GB]=Character Map +Name[eo]=Signotabelo +Name[pt]=Mapa de Carateres +Name[pt_BR]=Mapa de caracteres +Comment=Insert special characters into documents +Comment[bn]=ডকà§à¦®à§‡à¦¨à§à¦Ÿà§‡ বিশেষ অকà§à¦·à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ +Comment[bn_IN]=নথিপতà§à¦°à§‡à¦° মধà§à¦¯à§‡ বিশেষ অকà§à¦·à¦° সনà§à¦¨à¦¿à¦¬à§‡à¦¶ করà§à¦¨ +Comment[ca]=Inseriu caràcters especials en els documents +Comment[ca@valencia]=Inseriu caràcters especials en els documents +Comment[en@shaw]=ð‘¦ð‘¯ð‘•ð‘»ð‘‘ ð‘•ð‘ð‘§ð‘–ð‘©ð‘¤ ð‘’ð‘¸ð‘©ð‘’ð‘‘ð‘¼ð‘Ÿ ð‘¦ð‘¯ð‘‘ð‘« ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ð‘• +Comment[en_CA]=Insert special characters into documents +Comment[en_GB]=Insert special characters into documents +Comment[eo]=Enmeti specialajn signojn en dokumentojn +Comment[pt]=Inserir carateres especiais em documentos +Comment[pt_BR]=Insira caracteres especiais nos documentos +Keywords=font;unicode; +Keywords[ca]=tipus de lletra;unicode; +Keywords[ca@valencia]=tipus de lletra;unicode; +Keywords[pt]=fonte;unicode; +Keywords[pt_BR]=fonte;unicode; +Exec=true +Icon=accessories-character-map +Terminal=false +Type=Application +Categories=GNOME;GTK;Utility; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gucharmap +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.0 +StartupNotify=true diff --git a/gio/tests/desktop-files/usr/applications/invalid-desktop.desktop b/gio/tests/desktop-files/usr/applications/invalid-desktop.desktop new file mode 100644 index 0000000..dffaa24 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/invalid-desktop.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Type=Application +Name=appinfo-test +OnlyShowIn=../invalid/desktop;GNOME +NotShowIn=ROX; diff --git a/gio/tests/desktop-files/usr/applications/kde4/dolphin.desktop b/gio/tests/desktop-files/usr/applications/kde4/dolphin.desktop new file mode 100644 index 0000000..3e2aa0d --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/kde4/dolphin.desktop @@ -0,0 +1,27 @@ +[Desktop Entry] +Name=Dolphin +Name[bn]=ডলফিন +Name[bn_IN]=Dolphin +Name[ca]=Dolphin +Name[ca@valencia]=Dolphin +Name[en_GB]=Dolphin +Name[eo]=Dolphin +Name[pt]=Dolphin +Name[pt_BR]=Dolphin +Exec=true %i -caption %c %u +Icon=system-file-manager +Type=Application +X-DocPath=dolphin/index.html +Categories=Qt;KDE;System;FileTools;FileManager; +GenericName=File Manager +GenericName[bn]=ফাইল মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦° +GenericName[bn_IN]=ফাইল পরিচালন বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ +GenericName[ca]=Gestor de fitxers +GenericName[ca@valencia]=Gestor de fitxers +GenericName[en_GB]=File Manager +GenericName[eo]=Dosieradministrilo +GenericName[pt]=Gestor de Ficheiros +GenericName[pt_BR]=Gerenciador de arquivos +Terminal=false +MimeType=inode/directory; +InitialPreference=10 diff --git a/gio/tests/desktop-files/usr/applications/kde4/kate.desktop b/gio/tests/desktop-files/usr/applications/kde4/kate.desktop new file mode 100644 index 0000000..147e6a9 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/kde4/kate.desktop @@ -0,0 +1,26 @@ +[Desktop Entry] +GenericName=Advanced Text Editor +GenericName[ca]=Editor de text avançat +GenericName[ca@valencia]=Editor de text avançat +GenericName[en_GB]=Advanced Text Editor +GenericName[pt]=Editor de Texto Avançado +GenericName[pt_BR]=Editor de textos avançado +Name=Kate +Name[ca]=Kate +Name[ca@valencia]=Kate +Name[en_GB]=Kate +Name[eo]=Kate +Name[pt]=Kate +Name[pt_BR]=Kate +MimeType=text/plain; +Exec=true -b %U +X-KDE-StartupNotify=true +X-KDE-HasTempFileOption=true +Icon=kate +X-DocPath=kate/index.html +Type=Application +Terminal=false +InitialPreference=9 +X-DBUS-StartupType=Multi +X-DBUS-ServiceName=org.kde.kate +Categories=Qt;KDE;Utility;TextEditor; diff --git a/gio/tests/desktop-files/usr/applications/kde4/konqbrowser.desktop b/gio/tests/desktop-files/usr/applications/kde4/konqbrowser.desktop new file mode 100644 index 0000000..2760fc0 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/kde4/konqbrowser.desktop @@ -0,0 +1,26 @@ +[Desktop Entry] +Type=Application +Exec=true openProfile webbrowsing +Icon=konqueror +X-DocPath=konqueror/index.html +MimeType=x-scheme-handler/http; + +Name=Konqueror +Name[bn]=কনকরার +Name[bn_IN]=Konqueror +Name[ca]=Konqueror +Name[ca@valencia]=Konqueror +Name[en_GB]=Konqueror +Name[eo]=Konkeranto +Name[pt]=Konqueror +Name[pt_BR]=Konqueror +GenericName=Web Browser +GenericName[bn]=ওয়েব বà§à¦°à¦¾à¦‰à¦œà¦¾à¦° +GenericName[bn_IN]=ওয়েব বà§à¦°à¦¾à¦‰à¦œà¦¾à¦° +GenericName[ca]=Navegador web +GenericName[ca@valencia]=Navegador web +GenericName[en_GB]=Web Browser +GenericName[eo]=TTT-foliumilo +GenericName[pt]=Navegador Web +GenericName[pt_BR]=Navegador Web +Categories=Qt;KDE;Network;WebBrowser; diff --git a/gio/tests/desktop-files/usr/applications/kde4/okular.desktop b/gio/tests/desktop-files/usr/applications/kde4/okular.desktop new file mode 100644 index 0000000..1af4c34 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/kde4/okular.desktop @@ -0,0 +1,23 @@ +[Desktop Entry] +Terminal=false +Name=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +GenericName=Document Viewer +GenericName[ca]=Visualitzador de documents +GenericName[ca@valencia]=Visualitzador de documents +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +Exec=true %U %i -caption %c +Icon=okular +Type=Application +X-DocPath=okular/index.html +InitialPreference=7 +Categories=Qt;KDE;Graphics;VectorGraphics;Viewer; +MimeType=application/vnd.kde.okular-archive; diff --git a/gio/tests/desktop-files/usr/applications/mimeinfo.cache b/gio/tests/desktop-files/usr/applications/mimeinfo.cache new file mode 100644 index 0000000..e0a943d --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/mimeinfo.cache @@ -0,0 +1,246 @@ +[MIME Cache] +application/mxf=totem.desktop; +application/ogg=totem.desktop; +application/oxps=evince.desktop;evince-previewer.desktop; +application/pdf=evince.desktop;evince-previewer.desktop; +application/pkcs10=gcr-viewer.desktop; +application/pkcs10+pem=gcr-viewer.desktop; +application/pkcs12=gcr-viewer.desktop; +application/pkcs12+pem=gcr-viewer.desktop; +application/pkcs7-mime=gcr-viewer.desktop; +application/pkcs7-mime+pem=gcr-viewer.desktop; +application/pkcs8=gcr-viewer.desktop; +application/pkcs8+pem=gcr-viewer.desktop; +application/pkix-cert=gcr-viewer.desktop; +application/pkix-cert+pem=gcr-viewer.desktop; +application/pkix-crl=gcr-viewer.desktop; +application/pkix-crl+pem=gcr-viewer.desktop; +application/ram=totem.desktop; +application/sdp=totem.desktop; +application/smil=totem.desktop; +application/smil+xml=totem.desktop; +application/vnd.apple.mpegurl=totem.desktop; +application/vnd.kde.okular-archive=kde4-okular.desktop; +application/vnd.ms-cab-compressed=file-roller.desktop; +application/vnd.ms-wpl=totem.desktop; +application/vnd.ms-xpsdocument=evince.desktop;evince-previewer.desktop; +application/vnd.rn-realmedia=totem.desktop; +application/x-7z-compressed=file-roller.desktop; +application/x-7z-compressed-tar=file-roller.desktop; +application/x-ace=file-roller.desktop; +application/x-alz=file-roller.desktop; +application/x-ar=file-roller.desktop; +application/x-archive=file-roller.desktop; +application/x-arj=file-roller.desktop; +application/x-bzip=file-roller.desktop; +application/x-bzip-compressed-tar=file-roller.desktop; +application/x-bzip1=file-roller.desktop; +application/x-bzip1-compressed-tar=file-roller.desktop; +application/x-bzpdf=evince.desktop;evince-previewer.desktop; +application/x-cabinet=file-roller.desktop; +application/x-cb7=evince.desktop;evince-previewer.desktop; +application/x-cbr=evince.desktop;evince-previewer.desktop;file-roller.desktop; +application/x-cbt=evince.desktop;evince-previewer.desktop; +application/x-cbz=evince.desktop;evince-previewer.desktop;file-roller.desktop; +application/x-cd-image=file-roller.desktop; +application/x-compress=file-roller.desktop; +application/x-compressed-tar=file-roller.desktop; +application/x-cpio=file-roller.desktop; +application/x-deb=file-roller.desktop; +application/x-ear=file-roller.desktop; +application/x-extension-m4a=totem.desktop; +application/x-extension-mp4=totem.desktop; +application/x-flac=totem.desktop; +application/x-flash-video=totem.desktop; +application/x-font-otf=gnome-font-viewer.desktop; +application/x-font-pcf=gnome-font-viewer.desktop; +application/x-font-ttf=gnome-font-viewer.desktop; +application/x-font-type1=gnome-font-viewer.desktop; +application/x-glade=glade.desktop; +application/x-gnome-saved-search=nautilus.desktop; +application/x-gtar=file-roller.desktop; +application/x-gzip=file-roller.desktop; +application/x-gzpdf=evince.desktop;evince-previewer.desktop; +application/x-gzpostscript=file-roller.desktop; +application/x-java-archive=file-roller.desktop; +application/x-lha=file-roller.desktop; +application/x-lhz=file-roller.desktop; +application/x-lrzip=file-roller.desktop; +application/x-lrzip-compressed-tar=file-roller.desktop; +application/x-lzip=file-roller.desktop; +application/x-lzip-compressed-tar=file-roller.desktop; +application/x-lzma=file-roller.desktop; +application/x-lzma-compressed-tar=file-roller.desktop; +application/x-lzop=file-roller.desktop; +application/x-lzop-compressed-tar=file-roller.desktop; +application/x-matroska=totem.desktop; +application/x-ms-dos-executable=file-roller.desktop; +application/x-ms-wim=file-roller.desktop; +application/x-netshow-channel=totem.desktop; +application/x-ogg=totem.desktop; +application/x-pem-file=gcr-viewer.desktop; +application/x-pem-key=gcr-viewer.desktop; +application/x-pkcs12=gcr-viewer.desktop; +application/x-pkcs7-certificates=gcr-viewer.desktop; +application/x-quicktime-media-link=totem.desktop; +application/x-quicktimeplayer=totem.desktop; +application/x-rar=file-roller.desktop; +application/x-rar-compressed=file-roller.desktop; +application/x-rpm=file-roller.desktop; +application/x-rzip=file-roller.desktop; +application/x-rzip-compressed-tar=file-roller.desktop; +application/x-shorten=totem.desktop; +application/x-smil=totem.desktop; +application/x-spkac=gcr-viewer.desktop; +application/x-spkac+base64=gcr-viewer.desktop; +application/x-stuffit=file-roller.desktop; +application/x-tar=file-roller.desktop; +application/x-tarz=file-roller.desktop; +application/x-war=file-roller.desktop; +application/x-x509-ca-cert=gcr-viewer.desktop; +application/x-x509-user-cert=gcr-viewer.desktop; +application/x-xz=file-roller.desktop; +application/x-xz-compressed-tar=file-roller.desktop; +application/x-xzpdf=evince.desktop;evince-previewer.desktop; +application/x-zip=file-roller.desktop; +application/x-zip-compressed=file-roller.desktop; +application/x-zoo=file-roller.desktop; +application/xspf+xml=totem.desktop; +application/zip=file-roller.desktop; +audio/3gpp=totem.desktop; +audio/AMR=totem.desktop; +audio/AMR-WB=totem.desktop; +audio/ac3=totem.desktop; +audio/basic=totem.desktop; +audio/flac=totem.desktop; +audio/midi=totem.desktop; +audio/mp2=totem.desktop; +audio/mp4=totem.desktop; +audio/mpeg=totem.desktop; +audio/mpegurl=totem.desktop; +audio/ogg=totem.desktop; +audio/prs.sid=totem.desktop; +audio/vnd.rn-realaudio=totem.desktop; +audio/x-aiff=totem.desktop; +audio/x-ape=totem.desktop; +audio/x-flac=totem.desktop; +audio/x-gsm=totem.desktop; +audio/x-it=totem.desktop; +audio/x-m4a=totem.desktop; +audio/x-matroska=totem.desktop; +audio/x-mod=totem.desktop; +audio/x-mp3=totem.desktop; +audio/x-mpeg=totem.desktop; +audio/x-mpegurl=totem.desktop; +audio/x-ms-asf=totem.desktop; +audio/x-ms-asx=totem.desktop; +audio/x-ms-wax=totem.desktop; +audio/x-ms-wma=totem.desktop; +audio/x-musepack=totem.desktop; +audio/x-pn-aiff=totem.desktop; +audio/x-pn-au=totem.desktop; +audio/x-pn-realaudio=totem.desktop; +audio/x-pn-realaudio-plugin=totem.desktop; +audio/x-pn-wav=totem.desktop; +audio/x-pn-windows-acm=totem.desktop; +audio/x-real-audio=totem.desktop; +audio/x-realaudio=totem.desktop; +audio/x-s3m=totem.desktop; +audio/x-sbc=totem.desktop; +audio/x-scpls=totem.desktop; +audio/x-speex=totem.desktop; +audio/x-stm=totem.desktop; +audio/x-tta=totem.desktop; +audio/x-vorbis=totem.desktop; +audio/x-vorbis+ogg=totem.desktop; +audio/x-wav=totem.desktop; +audio/x-wavpack=totem.desktop; +audio/x-xm=totem.desktop; +image/bmp=eog.desktop; +image/gif=eog.desktop; +image/jpeg=eog.desktop; +image/jpg=eog.desktop; +image/pjpeg=eog.desktop; +image/png=eog.desktop; +image/svg+xml=eog.desktop; +image/svg+xml-compressed=eog.desktop; +image/tiff=eog.desktop;evince.desktop;evince-previewer.desktop; +image/vnd.rn-realpix=totem.desktop; +image/vnd.wap.wbmp=eog.desktop; +image/x-bmp=eog.desktop; +image/x-gray=eog.desktop; +image/x-icb=eog.desktop; +image/x-ico=eog.desktop; +image/x-pcx=eog.desktop; +image/x-pict=totem.desktop; +image/x-png=eog.desktop; +image/x-portable-anymap=eog.desktop; +image/x-portable-bitmap=eog.desktop; +image/x-portable-graymap=eog.desktop; +image/x-portable-pixmap=eog.desktop; +image/x-xbitmap=eog.desktop; +image/x-xpixmap=eog.desktop; +inode/directory=kde4-dolphin.desktop;baobab.desktop;nautilus.desktop; +misc/ultravox=totem.desktop; +text/google-video-pointer=totem.desktop; +text/plain=kde4-kate.desktop;gedit.desktop; +text/x-google-video-pointer=totem.desktop; +video/3gp=totem.desktop; +video/3gpp=totem.desktop; +video/divx=totem.desktop; +video/dv=totem.desktop; +video/fli=totem.desktop; +video/flv=totem.desktop; +video/mp2t=totem.desktop; +video/mp4=totem.desktop; +video/mp4v-es=totem.desktop; +video/mpeg=totem.desktop; +video/msvideo=totem.desktop; +video/ogg=totem.desktop; +video/quicktime=totem.desktop; +video/vivo=totem.desktop; +video/vnd.divx=totem.desktop; +video/vnd.mpegurl=totem.desktop; +video/vnd.rn-realvideo=totem.desktop; +video/vnd.vivo=totem.desktop; +video/webm=totem.desktop; +video/x-anim=totem.desktop; +video/x-avi=totem.desktop; +video/x-flc=totem.desktop; +video/x-fli=totem.desktop; +video/x-flic=totem.desktop; +video/x-flv=totem.desktop; +video/x-m4v=totem.desktop; +video/x-matroska=totem.desktop; +video/x-mpeg=totem.desktop; +video/x-mpeg2=totem.desktop; +video/x-ms-asf=totem.desktop; +video/x-ms-asx=totem.desktop; +video/x-ms-wm=totem.desktop; +video/x-ms-wmv=totem.desktop; +video/x-ms-wmx=totem.desktop; +video/x-ms-wvx=totem.desktop; +video/x-msvideo=totem.desktop; +video/x-nsv=totem.desktop; +video/x-ogm+ogg=totem.desktop; +video/x-theora+ogg=totem.desktop; +video/x-totem-stream=totem.desktop; +x-content/unix-software=nautilus-autorun-software.desktop; +x-content/video-dvd=totem.desktop; +x-content/video-svcd=totem.desktop; +x-content/video-vcd=totem.desktop; +x-scheme-handler/ghelp=yelp.desktop; +x-scheme-handler/help=yelp.desktop; +x-scheme-handler/http=kde4-konqbrowser.desktop; +x-scheme-handler/icy=totem.desktop; +x-scheme-handler/icyx=totem.desktop; +x-scheme-handler/info=yelp.desktop; +x-scheme-handler/man=yelp.desktop; +x-scheme-handler/mms=totem.desktop; +x-scheme-handler/mmsh=totem.desktop; +x-scheme-handler/net=totem.desktop; +x-scheme-handler/pnm=totem.desktop; +x-scheme-handler/rtmp=totem.desktop; +x-scheme-handler/rtp=totem.desktop; +x-scheme-handler/rtsp=totem.desktop; +x-scheme-handler/uvox=totem.desktop; diff --git a/gio/tests/desktop-files/usr/applications/nautilus-autorun-software.desktop b/gio/tests/desktop-files/usr/applications/nautilus-autorun-software.desktop new file mode 100644 index 0000000..3fc154e --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/nautilus-autorun-software.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] +Name=Run Software +Name[ca]=Executa programari +Name[ca@valencia]=Executa programari +Name[en_GB]=Run Software +Name[eo]=Lanĉi programaron +Name[pt]=Executar Aplicação +Name[pt_BR]=Executar software +Exec=true %u +Icon=application-x-executable +NoDisplay=true +Terminal=false +StartupNotify=true +Type=Application +MimeType=x-content/unix-software; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=nautilus +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.0 diff --git a/gio/tests/desktop-files/usr/applications/nautilus-classic.desktop b/gio/tests/desktop-files/usr/applications/nautilus-classic.desktop new file mode 100644 index 0000000..98612d5 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/nautilus-classic.desktop @@ -0,0 +1,15 @@ +[Desktop Entry] +Type=Application +Name=Desktop Icons +Comment=Classic session desktop file for desktop icons +Exec=true --no-default-window --force-desktop +OnlyShowIn=GNOME; +NoDisplay=true +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=nautilus +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.0 +X-GNOME-Autostart-Phase=Desktop +X-GNOME-Autostart-Notify=true +X-GNOME-AutoRestart=true +X-GNOME-Provides=filemanager diff --git a/gio/tests/desktop-files/usr/applications/nautilus-connect-server.desktop b/gio/tests/desktop-files/usr/applications/nautilus-connect-server.desktop new file mode 100644 index 0000000..6258fcf --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/nautilus-connect-server.desktop @@ -0,0 +1,22 @@ +[Desktop Entry] +Name=Connect to Server +Name[bn]=সারà§à¦­à¦¾à¦°à§‡à¦° সাথে সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করা হবে +Name[bn_IN]=সারà§à¦­à¦¾à¦°à§‡à¦° সাথে সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করা হবে +Name[ca]=Connecta't al servidor +Name[ca@valencia]=Connecta't al servidor +Name[en@shaw]=ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘‘ ð‘‘ ð‘•ð‘»ð‘𑼠+Name[en_CA]=Connect to Server +Name[en_GB]=Connect to Server +Name[eo]=Konekti al servilo +Name[pt]=Ligar-se a Servidores +Name[pt_BR]=Conectar ao servidor +Exec=true +Icon=applications-internet +NoDisplay=true +Terminal=false +StartupNotify=true +Type=Application +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=nautilus +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.0 diff --git a/gio/tests/desktop-files/usr/applications/nautilus.desktop b/gio/tests/desktop-files/usr/applications/nautilus.desktop new file mode 100644 index 0000000..de65da0 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/nautilus.desktop @@ -0,0 +1,39 @@ +[Desktop Entry] +Name=Files +Name[bn]=ফাইল +Name[ca]=Fitxers +Name[ca@valencia]=Fitxers +Name[en_CA]=Files +Name[en_GB]=Files +Name[eo]=Dosieroj +Name[pt]=Ficheiros +Name[pt_BR]=Arquivos +Comment=Access and organize files +Comment[bn]=ফাইলে বà§à¦¯à¦¬à¦¾à¦¹à¦° à¦à¦¬à¦‚ সাজানো +Comment[ca]=Organitzeu i accediu a fitxers +Comment[ca@valencia]=Organitzeu i accediu a fitxers +Comment[en_CA]=Access and organize files +Comment[en_GB]=Access and organise files +Comment[eo]=Atingi kaj organizi dosierojn +Comment[pt]=Aceder e organizar ficheiros +Comment[pt_BR]=Acesse e organize arquivos +Keywords=folder;manager;explore;disk;filesystem; +Keywords[ca]=carpeta;gestor;explora;disc;sistema de fitxers; +Keywords[ca@valencia]=carpeta;gestor;explora;disc;sistema de fitxers; +Keywords[en_GB]=folder;manager;explore;disk;filesystem; +Keywords[eo]=dosierujo;administrilo;foliumi;esplori;disko;dosiersistemo; +Keywords[pt]=pasta;gestor;explorar;disco;sistema;ficheiros; +Keywords[pt_BR]=pasta;gerenciador;explorar;disco;sistema de arquivos; +Exec=true --new-window %U +Icon=system-file-manager +Terminal=false +Type=Application +StartupNotify=true +OnlyShowIn=GNOME;Unity; +Categories=GNOME;GTK;Utility;Core;FileManager; +MimeType=inode/directory;application/x-gnome-saved-search; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=nautilus +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.0 +X-GNOME-UsesNotifications=true diff --git a/gio/tests/desktop-files/usr/applications/org.gnome.clocks.desktop b/gio/tests/desktop-files/usr/applications/org.gnome.clocks.desktop new file mode 100644 index 0000000..92a6b35 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/org.gnome.clocks.desktop @@ -0,0 +1,404 @@ +[Desktop Entry] +Name[af]=Horlosies +Name[an]=Reloches +Name[ar]=الساعات +Name[as]=ঘড়ী +Name[be]=Гадзіннікі +Name[bg]=ЧаÑовници +Name[bn_IN]=ঘড়ি +Name[bs]=Satovi +Name[ca]=Rellotges +Name[ca@valencia]=Rellotges +Name[cs]=Hodiny +Name[da]=Ure +Name[de]=Uhren +Name[el]=Ρολόγια +Name[en_GB]=Clocks +Name[eo]=HorloÄoj +Name[es]=Relojes +Name[et]=Kell +Name[eu]=Ordulariak +Name[fa]=ساعت‌ها +Name[fi]=Kellot +Name[fr]=Horloges +Name[fur]=Orlois +Name[ga]=Cloig +Name[gd]=Uaireadairean +Name[gl]=Reloxos +Name[gu]=ઘડિયાળ +Name[he]=×©×¢×•× ×™× +Name[hi]=घड़ी +Name[hr]=Satovi +Name[hu]=Órák +Name[id]=Jam +Name[is]=Klukkur +Name[it]=Orologi +Name[ja]=時計 +Name[kk]=Сағаттар +Name[ko]=시계 +Name[kn]=ಗಡಿಯಾರಗಳೠ+Name[lt]=Laikrodžiai +Name[lv]=Pulksteņi +Name[ml]=à´•àµà´²àµ‹à´•àµà´•àµà´•ൾ +Name[mr]=घडà¥à¤¯à¤¾à¤³à¥€ +Name[nb]=Klokker +Name[ne]=घडिहरू +Name[nl]=Klok +Name[oc]=Relòtges +Name[or]=ଘଣà­à¬Ÿà¬¾à¬—à­à¬¡à¬¼à¬¿à¬• +Name[pa]=ਘੜੀ +Name[pl]=Zegar +Name[pt]=Relógios +Name[pt_BR]=Relógios +Name[ro]=Ceasuri +Name[ru]=ЧаÑÑ‹ +Name[sk]=Hodiny +Name[sl]=Ure +Name[sr]=Сатови +Name[sr@latin]=Satovi +Name[sv]=Klockor +Name[ta]=கடிகாரஙà¯à®•ள௠+Name[te]=గడియారాలౠ+Name[tg]=Соатҳо +Name[th]=นาฬิà¸à¸² +Name[tr]=Saatler +Name[uk]=Годинники +Name[vi]=Äồng hồ +Name[zh_CN]=æ—¶é’Ÿ +Name[zh_HK]=æ™‚é˜ +Name[zh_TW]=æ™‚é˜ +Name[ug]=سائەتلەر +Name=Clocks +GenericName[af]=Horlosies +GenericName[an]=Reloches +GenericName[ar]=الساعات +GenericName[as]=ঘড়ী +GenericName[be]=Гадзіннікі +GenericName[bg]=ЧаÑовници +GenericName[bn_IN]=ঘড়ি +GenericName[bs]=Satovi +GenericName[ca]=Rellotges +GenericName[ca@valencia]=Rellotges +GenericName[cs]=Hodiny +GenericName[da]=Ure +GenericName[de]=Uhren +GenericName[el]=Ρολόγια +GenericName[en_GB]=Clocks +GenericName[eo]=HorloÄoj +GenericName[es]=Relojes +GenericName[et]=Kell +GenericName[eu]=Ordulariak +GenericName[fa]=ساعت‌ها +GenericName[fi]=Kellot +GenericName[fr]=Horloges +GenericName[fur]=Orlois +GenericName[ga]=Cloig +GenericName[gd]=Uaireadairean +GenericName[gl]=Reloxos +GenericName[gu]=ઘડિયાળ +GenericName[he]=×©×¢×•× ×™× +GenericName[hi]=घड़ी +GenericName[hr]=Satovi +GenericName[hu]=Órák +GenericName[id]=Jam +GenericName[is]=Klukkur +GenericName[it]=Orologi +GenericName[ja]=時計 +GenericName[kk]=Сағаттар +GenericName[ko]=시계 +GenericName[kn]=ಗಡಿಯಾರಗಳೠ+GenericName[lt]=Laikrodžiai +GenericName[lv]=Pulksteņi +GenericName[ml]=à´•àµà´²àµ‹à´•àµà´•àµà´•ൾ +GenericName[mr]=घडà¥à¤¯à¤¾à¤³à¥€ +GenericName[nb]=Klokker +GenericName[ne]=घडिहरू +GenericName[nl]=Klok +GenericName[oc]=Relòtges +GenericName[or]=ଘଣà­à¬Ÿà¬¾à¬—à­à¬¡à¬¼à¬¿à¬• +GenericName[pa]=ਘੜੀ +GenericName[pl]=Zegar +GenericName[pt]=Relógios +GenericName[pt_BR]=Relógios +GenericName[ro]=Ceasuri +GenericName[ru]=ЧаÑÑ‹ +GenericName[sk]=Hodiny +GenericName[sl]=Ure +GenericName[sr]=Сатови +GenericName[sr@latin]=Satovi +GenericName[sv]=Klockor +GenericName[ta]=கடிகாரஙà¯à®•ள௠+GenericName[te]=గడియారాలౠ+GenericName[tg]=Соатҳо +GenericName[th]=นาฬิà¸à¸² +GenericName[tr]=Saatler +GenericName[uk]=Годинники +GenericName[vi]=Äồng hồ +GenericName[zh_CN]=æ—¶é’Ÿ +GenericName[zh_HK]=æ™‚é˜ +GenericName[zh_TW]=æ™‚é˜ +GenericName[ug]=سائەتلەر +GenericName=Clocks +X-GNOME-FullName[af]=GNOME Horlosies +X-GNOME-FullName[an]=Reloches d'o GNOME +X-GNOME-FullName[ar]=ساعات جنوم +X-GNOME-FullName[as]=GNOME ঘড়ী +X-GNOME-FullName[be]=Гадзіннікі GNOME +X-GNOME-FullName[bg]=ЧаÑовници +X-GNOME-FullName[bn_IN]=GNOME ঘড়ি +X-GNOME-FullName[bs]=GNOME satovi +X-GNOME-FullName[ca]=Rellotges del GNOME +X-GNOME-FullName[ca@valencia]=Rellotges del GNOME +X-GNOME-FullName[cs]=Hodiny GNOME +X-GNOME-FullName[da]=GNOME Ure +X-GNOME-FullName[de]=GNOME-Uhren +X-GNOME-FullName[el]=Ρολόγια GNOME +X-GNOME-FullName[en_GB]=GNOME Clocks +X-GNOME-FullName[eo]=GNOME-horloÄoj +X-GNOME-FullName[es]=Relojes de GNOME +X-GNOME-FullName[et]=GNOME kell +X-GNOME-FullName[eu]=GNOMEren ordulariak +X-GNOME-FullName[fa]=ساعت‌های گنوم +X-GNOME-FullName[fi]=Gnomen kellot +X-GNOME-FullName[fr]=Horloges de GNOME +X-GNOME-FullName[fur]=Orlois par GNOME +X-GNOME-FullName[ga]=Cloig GNOME +X-GNOME-FullName[gd]=Uaireadairean GNOME +X-GNOME-FullName[gl]=Reloxos de GNOME +X-GNOME-FullName[gu]=GNOME ઘડિયાળ +X-GNOME-FullName[he]=×©×¢×•× ×™× ×ž×‘×™×ª GNOME +X-GNOME-FullName[hi]=गनोम घड़ी +X-GNOME-FullName[hr]=GNOME satovi +X-GNOME-FullName[hu]=GNOME órák +X-GNOME-FullName[id]=Jam GNOME +X-GNOME-FullName[is]=GNOME Klukkur +X-GNOME-FullName[it]=Orologi per GNOME +X-GNOME-FullName[ja]=GNOME Clocks +X-GNOME-FullName[kk]=GNOME Ñағаттары +X-GNOME-FullName[ko]=그놈 시계 +X-GNOME-FullName[kn]=GNOME ಕà³à²²à²¾à²•à³à²¸à³ +X-GNOME-FullName[lt]=GNOME laikrodžiai +X-GNOME-FullName[lv]=GNOME pulksteņi +X-GNOME-FullName[ml]=à´—àµà´¨àµ‹à´‚ à´•àµà´²àµ‹à´•àµà´•àµà´•ൾ +X-GNOME-FullName[mr]=GNOME घडà¥à¤¯à¤¾à¤³à¥€ +X-GNOME-FullName[nb]=GNOME klokker +X-GNOME-FullName[ne]=जिनोम घडी +X-GNOME-FullName[nl]=Gnome Klok +X-GNOME-FullName[oc]=Relòtges GNOME +X-GNOME-FullName[or]=GNOME ଘଣà­à¬Ÿà¬¾à¬—à­à¬¡à¬¼à¬¿à¬• +X-GNOME-FullName[pa]=ਗਨੋਮ ਘੜੀ +X-GNOME-FullName[pl]=Zegar GNOME +X-GNOME-FullName[pt]=Relógios GNOME +X-GNOME-FullName[pt_BR]=Relógios do GNOME +X-GNOME-FullName[ro]=Ceasuri GNOME +X-GNOME-FullName[ru]=ЧаÑÑ‹ GNOME +X-GNOME-FullName[sk]=Hodiny prostredia GNOME +X-GNOME-FullName[sl]=Gnomeove ure +X-GNOME-FullName[sr]=Гномови Ñатови +X-GNOME-FullName[sr@latin]=Gnomovi satovi +X-GNOME-FullName[sv]=GNOME Klockor +X-GNOME-FullName[ta]=கà¯à®©à¯‹à®®à¯ கடிகாரஙà¯à®•ள௠+X-GNOME-FullName[te]=à°—à±à°¨à±‹à°®à± గడియారాలౠ+X-GNOME-FullName[tg]=Соатҳои GNOME +X-GNOME-FullName[th]=นาฬิà¸à¸² GNOME +X-GNOME-FullName[tr]=GNOME Saatleri +X-GNOME-FullName[vi]=Äồng hồ GNOME +X-GNOME-FullName[zh_CN]=GNOME æ—¶é’Ÿ +X-GNOME-FullName[zh_HK]=GNOME Clocks +X-GNOME-FullName[zh_TW]=GNOME æ™‚é˜ +X-GNOME-FullName[ug]=گىنوم سائەتلىرى +X-GNOME-FullName=GNOME Clocks +Comment[af]=Horlosies vir wêreldtyd, plus wekkers, stophorlosie en 'n tydteller +Comment[an]=Reloches d'horas mundials, amás d'alarmas, cronometro y un temporizador +Comment[ar]=ساعات لتوقيتات العالم، مع منبه ÙˆÙ…ÙØ¤Ù‚ّت وساعة إيقاÙ. +Comment[as]=বিশà§à¦¬à§° সময়সমূহৰ বাবে ঘড়ী, লগতে à¦à¦²à¦¾à§°à§à¦®, সà§à¦Ÿà¦ªà§±à¦¾à¦š আৰৠà¦à¦Ÿà¦¾ টাইমাৰ +Comment[be]=Гадзіннікі Ð´Ð»Ñ Ð°Ð´ÑÐ¾Ñ‡Ð²Ð°Ð½Ð½Ñ Ñ‡Ð°Ñу Ñž розных кутках Ñвету, з будзільнікам, таймерам Ñ– Ñекундамерам +Comment[bg]=ЧаÑовници за различни градове, аларми, хронометър и отброÑване +Comment[bn_IN]=বিশà§à¦¬à¦˜à¦¡à¦¼à¦¿, পà§à¦²à¦¾à¦¸ অà§à¦¯à¦¾à¦²à¦¾à¦°à§à¦®, সà§à¦Ÿà¦ªà¦“য়াচ à¦à¦¬à¦‚ টাইমারের জনà§à¦¯ ঘড়ি +Comment[bs]=Satovi za svjetsko vrijeme, plus alarmi, Å¡toperica i tajmer +Comment[ca]=Rellotges de tot el món, a més d'alarmes, de cronòmetres i de temporitzadors +Comment[ca@valencia]=Rellotges de tot el món, a més d'alarmes, de cronòmetres i de temporitzadors +Comment[cs]=Hodiny s Äasy ve svÄ›tÄ›, budíkem, stopkami a odpoÄtem +Comment[da]=Verdensur plus alarmer, stopur og et minutur +Comment[de]=Uhren für die Weltzeit mit Alarm, Stoppuhr und einem Timer +Comment[el]=Ρολόγια για παγκόσμιες ÏŽÏες, για ειδοποιήσεις, με χÏονόμετÏο και αντίστÏοφη μέτÏηση +Comment[en_GB]=Clocks for world times, plus alarms, stopwatch and a timer +Comment[eo]=HorloÄoj por mondaj horoj, plus alarmoj, kronometro kaj minutatoro +Comment[es]=Relojes de horas mundiales, además de alarmas, cronómetro y un temporizador +Comment[et]=Kell maailmaajaga, alarmide, stopperi ja taimeriga +Comment[eu]=Ordulariak munduko orduetarako, gehi alarmak, kronometroa eta tenporizadorea +Comment[fa]=ساعت‌هایی برای زمان‌ها در دنیا، با اضاÙه‌ی زنگ هشدار، کرنومتر Ùˆ زمان‌سنج +Comment[fi]=Kellot eri puolille maailmaa, hälytykset, sekuntikello ja ajastin +Comment[fr]=Des horloges pour connaître l’heure dans le monde, régler des alarmes, chronométrer ou lancer un décompte +Comment[fur]=Orlois par i fûs oraris tal mont, sveis, cronometri e un timer +Comment[gd]=Uaireadairean airson àm an t-saoghail le caismeachdan, stad-uaireadair ’s tìmear +Comment[gl]=Reloxos para todo o mundo, ademais de alarmas, cronómetro e un temporizador +Comment[gu]=વિશà«àª°à«àªµàª¨à«‹ સમય, વતà«àª¤àª¾ àªàª²àª¾àª°à«àª®, સà«àªŸà«‹àªªàªµà«‰àªš અને ટાઇમર માટે ઘડિયાળો +Comment[he]=×©×¢×•× ×™× ×œ×–×ž× ×™× ×©×•× ×™× ×‘×¨×—×‘×™ ×”×¢×•×œ× ×œ×¨×‘×•×ª התרעות, שעון עצר וקוצב זמן +Comment[hi]=विशà¥à¤µ समय, के साथ साथ अलारà¥à¤®, सà¥à¤Ÿà¥‰à¤ªà¤µà¥‰à¤š और à¤à¤• टाइमर के लिठघड़ियां +Comment[hr]=Satovi sa svjetskim vremenima, ukljuÄujući alarme, Å¡topericu i odbrojavanje vremena +Comment[hu]=VilágidÅ‘, figyelmeztetés, stopper és idÅ‘zítÅ‘ +Comment[id]=Jam untuk waktu dunia, alarm, stopwatch dan penghitung waktu +Comment[is]=Klukkur á ýmsum stöðum, vekjaraklukkur, skeiðklukka og niðurteljari. +Comment[it]=Orologi per i fusi orari nel mondo, sveglie, cronometro e un timer +Comment[ja]=世界時計ã€ã‚¢ãƒ©ãƒ¼ãƒ ã€ã‚¹ãƒˆãƒƒãƒ—ウォッãƒã€ãŠã‚ˆã³ã‚¿ã‚¤ãƒžãƒ¼æ©Ÿèƒ½ã‚’ã‚‚ã¤æ™‚計アプリケーション +Comment[kk]=Дүниежүзілік уақыттары үшін Ñағаттар, құрамында тағы оÑтқыш, Ñекундтар өлшегіші және таймері бар +Comment[ko]=세계 시계, 알림, 초시계, 타ì´ë¨¸ ê¸°ëŠ¥ì´ ìžˆëŠ” 시계 +Comment[kn]=ಪà³à²°à²ªà²‚ಚದ ಸಮಯಕà³à²•ಾಗಿನ, ಜೊತೆಗೆ ಅಲಾರಂಗಳಿಗಾಗಿನ, ಸà³à²Ÿà²¾à²ªà³â€Œà²µà²¾à²šà³â€Œà²—ಾಗಿನ ಮತà³à²¤à³ ಟೈಮರಿಗಾಗಿನ ಗಡಿಯಾರಗಳೠ+Comment[lt]=Pasaulio laikų laikrodžiai, taip pat žadintuvai, chronometras ir laikmatis +Comment[lv]=Pulksteņi pasaules laikiem, kÄ arÄ« modinÄtÄjs, hronometrs un taimeris +Comment[ml]=ലോകതàµà´¤àµ†à´µà´¿à´Ÿàµ†à´¯àµà´®àµà´³àµà´³ സമയം കാണിയàµà´•àµà´•àµà´¨àµà´¨ à´•àµà´²àµ‹à´•àµà´•àµà´•ൾ, അലാറങàµà´™àµ¾, à´¸àµà´±àµà´±àµ‹à´ªàµà´ªàµâ€Œà´µà´¾à´šàµà´šàµ, ടൈമരàµâ€ à´Žà´¨àµà´¨à´¿à´µà´¯àµà´‚ +Comment[mr]=जागतिक वेळ, तसेच गजर, सà¥à¤Ÿà¥‰à¤ªà¤µà¥‰à¤š व टाइमरकरीता घडà¥à¤¯à¤¾à¤³à¥€ +Comment[nb]=Klokker med verdenstid, alarm, stoppeklokke og nedtelling +Comment[nl]=Wereldklok, wekker, stopwatch en timer +Comment[oc]=De relòtges per conéisser l'ora dins lo mond, reglar d'alarmas, cronometrar o aviar un descompte +Comment[or]=ବିଶà­à­± ସମୟ ପାଇଠଘଣà­à¬Ÿà¬¾à¬—à­à¬¡à¬¼à¬¿à¬•, à¬à¬¹à¬¾ ସହିତ ଆଲାରà­à¬®, ଷà­à¬Ÿà¬ªà­±à¬¾à¬š à¬à¬¬à¬‚ ସମୟ ମାପକ +Comment[pa]=ਸੰਸਾਰ ਸਮਾਂ, ਅਲਾਰਮ, ਸਟਾਪਵਾਚ ਅਤੇ ਟਾਈਮਰ ਦੇ ਨਾਲ ਘੜੀਆਂ +Comment[pl]=Zegar Å›wiatowy, budzik, stoper i minutnik +Comment[pt]=Relógios com as horas do mundo, alarmes, cronómetros e um temporizador +Comment[pt_BR]=Relógios para horários mundiais além de alarmes, cronômetro e um temporizador +Comment[ro]=Ora în lume, alarme, cronometru È™i temporizator +Comment[ru]=ЧаÑÑ‹ мирового времени, а также будильник, Ñекундомер и таймер +Comment[sk]=Hodiny svetového Äasu, budík, stopky a ÄasovaÄ +Comment[sl]=Ure za prikazovanje svetovnega Äasa, alarmi, Å¡toparica in Äasomer +Comment[sr]=Сатови за ÑветÑка времена, будилници, штоперица и одбројавач +Comment[sr@latin]=Satovi za svetska vremena, budilnici, Å¡toperica i odbrojavaÄ +Comment[sv]=Klockor för världstider, alarm, stoppur och en timer +Comment[ta]=உலக நேரமà¯, எசà¯à®šà®°à®¿à®•à¯à®•ை மணிகளà¯, நிறà¯à®¤à¯à®¤ கடிகாரமà¯, நேர அளவி கொணà¯à®Ÿ கடிகாரஙà¯à®•ள௠+Comment[te]=à°ªà±à°°à°ªà°‚à°š సమయాలకà±,అలారాలకà±, à°¸à±à°Ÿà°¾à°ªà±â€à°µà°¾à°šà± ఇంకా సమయకానికి ఉపయోగపడే గడియారాలౠ+Comment[tg]=Соат барои вақти ҷаҳон, аз ҷумла иÑтифодаи ҳушдорҳо, ÑониÑшумор ва вақтÑанҷ +Comment[th]=นาฬิà¸à¸²à¸ªà¸³à¸«à¸£à¸±à¸šà¹€à¸§à¸¥à¸²à¸—ั่วโลà¸, พร้อมด้วยนาฬิà¸à¸²à¸›à¸¥à¸¸à¸, นาฬิà¸à¸²à¸ˆà¸±à¸šà¹€à¸§à¸¥à¸² à¹à¸¥à¸°à¸™à¸²à¸¬à¸´à¸à¸²à¸™à¸±à¸šà¸–อยหลัง +Comment[tr]=Dünya saatleri, alarmlar, kronometre ve zaman ölçer +Comment[vi]=Äồng hồ thế giá»›i, kèm báo thức và Ä‘o giá» +Comment[zh_CN]=æ—¶é’Ÿå¯ç”¨æ¥æŸ¥çœ‹ä¸–界时间,外加闹钟ã€ç§’表和定时器功能 +Comment[zh_HK]=包å«ä¸–界時刻的時é˜ï¼ŒåŠ ä¸Šé¬§é˜ã€ç¢¼è¡¨å’Œè¨ˆæ™‚器 +Comment[zh_TW]=包å«ä¸–界時刻的時é˜ï¼ŒåŠ ä¸Šé¬§é˜ã€ç¢¼è¡¨å’Œè¨ˆæ™‚器 +Comment[ug]=دۇنيا ۋاقىتلىرى، قوڭغۇراقلىق سائەت، ۋاقىت ئۆلچىگۈچ +Comment=Clocks for world times, plus alarms, stopwatch and a timer +Keywords[af]=time;timer;alarm;world clock;stopwatch;time zone;tyd;tydteller;wekker;wêreldtyd;stophorlosie;tydsone;tydhou; +Keywords[an]=Hora;Temporizador;Alarma;Hora mundial;Cronometro;Zona horaria; +Keywords[ar]=وقت;موقت;منبه;ساعة عالمية;ساعة إيقاÙ;منطقة زمنية; +Keywords[as]=time;timer;alarm;world clock;stopwatch;time zone; +Keywords[be]=чаÑ;таймер;гадзіннік;будзільнік;ÑуÑветны гадзіннік;Ñекундамер;чаÑавы поÑÑ; +Keywords[bg]=време;обратно;отброÑване;напомнÑне;аларма;чаÑовник;Ñекундомер;поÑÑ;хронометър;time;timer;alarm;world clock;stopwatch;time zone; +Keywords[bn_IN]=সময়;টাইমার;অà§à¦¯à¦¾à¦²à¦¾à¦°à§à¦®;বিশà§à¦¬à¦˜à¦¡à¦¼à¦¿;সà§à¦Ÿà¦ªà¦“য়াচ;সময় জোন; +Keywords[bs]=vrijeme;tajmer;alarm;svjetski sat;Å¡toperica;vremenska zona; +Keywords[ca]=temps;temporitzador;alarma;rellotge global;cronòmetre;zona horària; +Keywords[ca@valencia]=temps;temporitzador;alarma;rellotge global;cronòmetre;zona horària; +Keywords[cs]=Äas;ÄasovaÄ;minutka;odpoÄet;budík;buzení;svÄ›tový Äas;stopky;Äasové pásmo; +Keywords[da]=tid;timer;minutur;alarm;vækkeur;verdensur;stopur;ur;tidszone;klokken; +Keywords[de]=Zeit;Uhrzeit;Alarm;Weltuhr;Stoppuhr;Zeitzone; +Keywords[el]=χÏόνος;χÏονόμετÏο;ξυπνητήÏι;παγκόσμιο Ïολόι;χÏονόμετÏο;ÏŽÏα ζώνης;time;timer;alarm;world clock;stopwatch;time zone; +Keywords[en_GB]=time;timer;alarm;world clock;stopwatch;time zone; +Keywords[eo]=horo;minutatoro;alarmo;monda horloÄo;kronometro;horzono; +Keywords[es]=Hora;Temporizador;Alarma;Hora mundial;Cronómetro;Zona horaria; +Keywords[et]=aeg;kell;kuupäev;taimer;alarm;äratus;maailmakell;stopper;ajavöönd;ajatsoon; +Keywords[eu]=ordua;tenporizadorea;alarma;munduko ordulariak;kronometroa;ordu-zona; +Keywords[fa]=time;timer;alarm;world clock;stopwatch;time zone;زمان;زمانسنج;زنگ;ساعت جهانی;منطقه زمانی; +Keywords[fi]=time;timer;alarm;world clock;stopwatch;time zone;aika;ajastin;hälytys;maailmankello;aikavyöhyke; +Keywords[fr]=heure;minuterie;décompte;alarme;horloge mondiale;chronomètre;fuseau horaire; +Keywords[fur]=ore;orari;timp;orloi;cronometri;fûs orari;svee;alarme; +Keywords[gd]=time;timer;alarm;world clock;stopwatch;time zone;àm;ùine;tìmear;uaireadair an t-saoghail;uaireadair;saoghal;cleoc;gleoc;stad-uaireadair;roinn-tìde; +Keywords[gl]=tempo;temporizador;alarma;reloxo mundial;reloxo de parada;fuso horario; +Keywords[gu]=સમય;ટાઇમર;àªàª²àª¾àª°à«àª®;વિશà«àª°à«àªµ ઘડિયાળો;સà«àªŸà«‹àªªàªµà«‰àªš;ટાઇમàªà«‹àª¨; +Keywords[he]=זמן;שעה;טיימר;קוצב זמן;שעון עולמי;שעון עצר;סטופר;×זור זמן;שעון; +Keywords[hi]=समय; टाइमर;अलारà¥à¤®;दà¥à¤¨à¤¿à¤¯à¤¾ घड़ी; सà¥à¤Ÿà¥‰à¤ªà¤µà¥‰à¤š; समय कà¥à¤·à¥‡à¤¤à¥à¤°; +Keywords[hr]=vrijeme;odbrojavanje;alarm;svjetski sat;Å¡toperica;vremenska zona; +Keywords[hu]=idÅ‘;idÅ‘zítÅ‘;riasztás;világóra;stopper;idÅ‘zóna; +Keywords[id]=time;timer;alarm;world clock;stopwatch;time zone;jam;waktu; +Keywords[is]=tími;heimsklukka;vekjari;skeiðklukka;niðurteljari;tímabelti; +Keywords[it]=ora;orario;tempo;orologio;cronometro;fuso orario;sveglia;allarme; +Keywords[ja]=time;timer;alarm;world clock;stopwatch;time zone;時間;時刻;タイム;タイマー;アラーム;世界時計;時計;ストップウォッãƒ;ストップウオッãƒ;タイムゾーン; +Keywords[kk]=time;timer;alarm;world clock;stopwatch;time zone;уақыт;таймер;оÑтқыш;дүниежүзі Ñағаты;Ñекундтар өлшегіші;уақыт белдеуі; +Keywords[ko]=time;시간;timer;타ì´ë¨¸;alarm;알림;world clock;세계 시계;stopwatch;스톱워치;time zone;시간대; +Keywords[kn]=ಸಮಯ;ಟೈಮರà³;ಅಲಾರಂ;ಪà³à²°à²ªà²‚ಚದ ಗಡಿಯಾರ;ಸà³à²Ÿà²¾à²ªà³â€Œà²µà²¾à²šà³;ಕಾಲ ವಲಯ; +Keywords[lt]=laikas;laikmatis;žadintuvas;pasaulio laikrodis;chronometras;laiko juosta; +Keywords[lv]=laiks;taimeris;modinÄtÄjs;pasaules pulkstenis;hronometrs;laika zona;signÄls; +Keywords[ml]=time;timer;alarm;world clock;stopwatch;time zone; +Keywords[mr]=वेळ;टाइमर;गजर;जागतिक घडà¥à¤¯à¤¾à¤³;सà¥à¤Ÿà¥‰à¤ªà¤µà¥‰à¤š;वेळ कà¥à¤·à¥‡à¤¤à¥à¤°; +Keywords[nb]=tid;nedtelling;alarm;verdensklokke;stoppeklokke;tidssone; +Keywords[nl]=time;timer;alarm;world clock;stopwatch;time zone;klok;tijd;wekker;wereldtijd;wereldklok;tijdzone; +Keywords[oc]=ora;minutariá;descompte;alarma;relòtge mondiala;cronomètre;fus orari; +Keywords[or]=ସମୟ;ସମୟ ମାପକ;ଆଲାରà­à¬®;ବିଶà­à­± ସମୟ;ଷà­à¬Ÿà¬ª ୱାଚ;ସମୟ ମଣà­à¬¡à¬³; +Keywords[pa]=ਸਮਾਂ;ਟਾਈਮ;ਟਾਈਮਰ;ਅਲਾਰਮ;ਸੰਸਾਰ ਘੜੀ;ਸਟਾਪਵਾਚ;ਸਮਾਂ ਖੇਤਰ;ਟਾਈਮ ਜ਼ੋਨ;ਖੇਤਰ;ਵੇਲਾ;ਦà©à¨¨à¨¿à¨†à¨‚;ਕਲਾਕ;ਵਕਤ; +Keywords[pl]=czas;minutnik;timer;budzik;alarm;zegar Å›wiatowy;stoper;strefa czasowa; +Keywords[pt]=horas;temporizador;alarme;relógio mundial;cronómetro;fuso horário; +Keywords[pt_BR]=hora;temporizador;alarme;relógio mundial;cronômetro;fuso horário; +Keywords[ro]=timp;temporizator;fus orar;cronometru;alarmă;time;timer;alarm;world clock;stopwatch;time zone; +Keywords[ru]=времÑ;таймер;будильник;мировое времÑ;чаÑовой поÑÑ; +Keywords[sk]=Äas;ÄasovaÄ;budík;svetový Äas;stopky;Äasová zóna; +Keywords[sl]=Äas;Äasomer;alarm;svetovne ure;Å¡toparica;Äasovni pas; +Keywords[sr]=време;одбројавач;аларм;будилник;ÑветÑки Ñат;штоперица;временÑка зона; +Keywords[sr@latin]=vreme;odbrojavaÄ;alarm;budilnik;svetski sat;Å¡toperica;vremenska zona; +Keywords[sv]=tid;timer;alarm:världsklocka;världsur;stoppur;tidszon; +Keywords[ta]=நேரமà¯;நேர அளவி;எசà¯à®šà®°à®¿à®ªà¯à®ªà®¾à®©à¯;உலக கடிகாரமà¯;நிறà¯à®¤à¯à®¤à®•௠கடிகாரமà¯;காலபà¯à®ªà®•à¯à®¤à®¿; +Keywords[te]=సమయం;సమయకం;అలారం;à°ªà±à°°à°ªà°‚à°š గడియారం;à°¸à±à°Ÿà°¾à°ªà±â€Œà°µà°¾à°šà±;సమయకà±à°·à±‡à°¤à±à°°à°‚; +Keywords[tg]=вақт;вақтÑанҷ;ҳушдор;Ñоати ҷаҳон;ÑониÑшумор;минтақаи вақт; +Keywords[th]=เวลา;นาฬิà¸à¸²à¸™à¸±à¸šà¸–อยหลัง;นาฬิà¸à¸²à¸›à¸¥à¸¸à¸;นาฬิà¸à¸²à¸—ั่วโลà¸;นาฬิà¸à¸²à¸ˆà¸±à¸šà¹€à¸§à¸¥à¸²;เขตเวลา; +Keywords[tr]=saat;zaman;geri sayım;alarm;dünya saatleri;kronometre;saat dilimi; +Keywords[vi]=time;thá»i;gian;thoi;timer;hẹn;giá»;hen;gio;alarm;world clock;đồng;hồ;dong;ho;stopwatch;time zone;múi;mui;bấm; +Keywords[zh_CN]=time;timer;alarm;world clock;stopwatch;time zone;é’Ÿ;表;定时;计时;æ—¶é—´;时区; +Keywords[zh_HK]=time;timer;alarm;world clock;stopwatch;time zone;時間;計時器;鬧é˜;鬧鈴;世界時é˜;碼表;時å€; +Keywords[zh_TW]=time;timer;alarm;world clock;stopwatch;time zone;時間;倒數;計時器;鬧é˜;鬧鈴;世界時é˜;碼表;時å€; +Keywords[ug]=time;timer;alarm;world clock;stopwatch;time zone;ۋاقىت;ئۆلچىگۈچ;قوڭغۇراق;دۇنيا سائىتى;ۋاقىت رايونى; +Keywords=time;timer;alarm;world clock;stopwatch;time zone; +# GDesktopAppInfo requires that the command exists, so use /bin/sh +# rather than /usr/bin/flatpak, since that's guaranteed to exist on +# all test systems (in particular CI machines). +Exec=/bin/sh run --branch=stable --arch=x86_64 --command=gnome-clocks org.gnome.clocks +Icon=org.gnome.clocks +Terminal=false +Type=Application +Categories=GNOME;GTK;Utility;Clock; +StartupNotify=true +DBusActivatable=true +X-GNOME-UsesNotifications=true +X-Geoclue-Reason[af]=Laat wêreldhorlosies toe om vir jou tydsone vertoon te word. +X-Geoclue-Reason[ar]=يتيح عرض الساعات العالمية ÙÙŠ منطقة الزمنية الحالية. +X-Geoclue-Reason[be]=ДазвалÑе паказваць ÑуÑÐ²ÐµÑ‚Ð½Ñ‹Ñ Ð³Ð°Ð´Ð·Ñ–Ð½Ð½Ñ–ÐºÑ– Ð´Ð»Ñ Ð²Ð°ÑˆÐ°Ð³Ð° чаÑавога поÑÑа. +X-Geoclue-Reason[ca]=Permet que els rellotges del món es mostrin a la vostra zona horària. +X-Geoclue-Reason[ca@valencia]=Permet que els rellotges del món es mostren a la vostra zona horària. +X-Geoclue-Reason[cs]=Umožňuje zobrazit svÄ›tové Äasy pro vaÅ¡e Äasová pásma. +X-Geoclue-Reason[da]=Lader verdensure blive vist for din tidszone. +X-Geoclue-Reason[de]=Ermöglicht die Anzeige von Weltuhren für Ihre Zeitzone. +X-Geoclue-Reason[el]=ΕπιτÏέπει την εμφάνιση των παγκόσμιων Ïολογιών για την ζώνη ÏŽÏας σας. +X-Geoclue-Reason[en_GB]=Allows world clocks to be displayed for your time zone. +X-Geoclue-Reason[es]=Permite a los relojes del mundo mostrarse para su zona horaria. +X-Geoclue-Reason[eu]=Munduko ordulariak zure ordu-zonan bistaratzea baimentzen du. +X-Geoclue-Reason[fa]=اجازه می‌دهد تا ساعت‌های جهانی برای منطقه زمانی شما نمایش داده شود. +X-Geoclue-Reason[fi]=Mahdollistaa maailmankellojen esityksen aikavyöhykkeellesi. +X-Geoclue-Reason[fr]=Permet d’afficher des horloges mondiales selon votre fuseau horaire. +X-Geoclue-Reason[fur]=Al permet di mostrâ orlois di dut il mont pal tô fûs orari. +X-Geoclue-Reason[gd]=Leigidh seo leat uaireadairean an t-saoghail a shealltainn airson na roinn-tìde agad. +X-Geoclue-Reason[gl]=Permítelle mostrar reloxos do mundio para o seu fuso horario. +X-Geoclue-Reason[he]=מ×פשר הצגת ×©×¢×•× ×™× ×ž×¡×‘×™×‘ ×œ×¢×•×œ× ×¢×‘×•×¨ ×זור הזמן שלך. +X-Geoclue-Reason[hr]=DopuÅ¡ta svjetskim satovima prikaz u vaÅ¡oj vremenskoj zoni. +X-Geoclue-Reason[hu]=Világórák megjelenítése az idÅ‘zónájához. +X-Geoclue-Reason[id]=Mengijinkan jam dunia ditampilkan untuk zona waktu Anda. +X-Geoclue-Reason[is]=Gerir kleift að birta klukku fyrir staðinn þar sem þú ert. +X-Geoclue-Reason[it]=Consente di visualizzare orologi per il proprio fuso orario. +X-Geoclue-Reason[ja]=タイムゾーンã«å¯¾å¿œã—ãŸä¸–界時計を表示ã—ã¾ã™ã€‚ +X-Geoclue-Reason[kk]=Сіздің уақыт белдеуіңіз үшін дүниежүзілік Ñағаттарды көрÑетуді мүмкін етеді. +X-Geoclue-Reason[ko]=현재 ì‹œê°„ëŒ€ì— í•´ë‹¹í•˜ëŠ” 세계 시계 표시 허용. +X-Geoclue-Reason[lt]=Leidžia rodyti pasaulio laikrodžius jÅ«sų laiko zonai. +X-Geoclue-Reason[lv]=Ä»auj parÄdÄ«t pasaules pulksteņus jÅ«su laika joslai. +X-Geoclue-Reason[ml]=താങàµà´•à´³àµà´Ÿàµ† സമയമേഖലയàµà´•àµà´•à´¨àµà´¸à´°à´¿à´šàµà´šàµ ലോകതàµà´¤àµ† മറàµà´±àµ à´¸àµà´¥à´²à´™àµà´™à´³à´¿à´²àµ† à´•àµà´²àµ‹à´•àµà´•àµà´•ൾ à´ªàµà´°à´¦àµ¼à´¶à´¿à´ªàµà´ªà´¿à´•àµà´•ാൻ à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨àµ. +X-Geoclue-Reason[nb]=Tillat visning av verdensklokker for din tidssone. +X-Geoclue-Reason[nl]=Uw tijdzone kan worden weergegeven in de wereldklok. +X-Geoclue-Reason[pa]=ਤà©à¨¹à¨¾à¨¡à©‡ ਸਮਾਂ ਖੇਤਰ ਲਈ ਸੰਸਾਰ ਘੜੀਆਂ ਵਿਖਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿਉ। +X-Geoclue-Reason[pl]=Umożliwia wyÅ›wietlanie zegara dla strefy czasowej użytkownika. +X-Geoclue-Reason[pt]=Permite que o relógio mundial apresente o seu fuso horário. +X-Geoclue-Reason[pt_BR]=Permite que relógios mundiais sejam exibidos para o seu fuso horário. +X-Geoclue-Reason[ru]=ПозволÑет отображать мировые чаÑÑ‹ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ чаÑового поÑÑа. +X-Geoclue-Reason[sk]=Umožňuje zobrazenie svetových hodín pre vaÅ¡u Äasovú zónu. +X-Geoclue-Reason[sl]=Dovoli prikaz svetovnih Äasov za trenutno Äasovno obmoÄje. +X-Geoclue-Reason[sr]=ДопуÑтите да ÑветÑки Ñатови буду приказани за вашу временÑку зону. +X-Geoclue-Reason[sr@latin]=Dopustite da svetski satovi budu prikazani za vaÅ¡u vremensku zonu. +X-Geoclue-Reason[sv]=LÃ¥ter världsklockor visas för din tidszon. +X-Geoclue-Reason[th]=เพื่อให้สามารถà¹à¸ªà¸”งนาฬิà¸à¸²à¸—ั่วโลà¸à¸ªà¸³à¸«à¸£à¸±à¸šà¹€à¸‚ตเวลาของคุณ +X-Geoclue-Reason[tr]=Saat diliminiz için dünya saatlerinin gösterilmesine olanak tanır. +X-Geoclue-Reason[vi]=Cho phép các đồng hồ thế giá»›i hiển thị cho múi giá» cá»§a bạn. +X-Geoclue-Reason[zh_CN]=å…许为您的时区显示世界时钟 +X-Geoclue-Reason[zh_TW]=å…許為您的時å€é¡¯ç¤ºä¸–界時é˜ã€‚ +X-Geoclue-Reason=Allows world clocks to be displayed for your time zone. +X-Flatpak=org.gnome.clocks diff --git a/gio/tests/desktop-files/usr/applications/totem.desktop b/gio/tests/desktop-files/usr/applications/totem.desktop new file mode 100644 index 0000000..44f6170 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/totem.desktop @@ -0,0 +1,36 @@ +[Desktop Entry] +Name=Videos +Name[bn]=ভিডিও +Name[bn_IN]=ভিডিও +Name[ca]=Vídeos +Name[ca@valencia]=Vídeos +Name[en@shaw]=ð‘ð‘¦ð‘›ð‘°ð‘´ð‘Ÿ +Name[en_GB]=Videos +Name[pt]=Vídeos +Name[pt_BR]=Vídeos +Comment=Play movies +Comment[ca]=Reprodueix pel·lícules +Comment[ca@valencia]=Reprodueix pel·lícules +Comment[en_GB]=Play movies +Comment[pt]=Reproduzir filmes +Comment[pt_BR]=Reproduzir filmes +Keywords=Video;Movie;Film;Clip;Series;Player;DVD;TV;Disc; +Keywords[ca]=Vídeo;Pel·lícula;Film;Clip;Sèries;Reproductor;DVD;TV;Disc; +Keywords[ca@valencia]=Vídeo;Pel·lícula;Film;Clip;Sèries;Reproductor;DVD;TV;Disc; +Keywords[en_GB]=Video;Movie;Film;Clip;Series;Player;DVD;TV;Disc; +Keywords[pt]=Vídeo;Filme;Clip;Séries;Reprodutor;DVD;TV;Disc; +Keywords[pt_BR]=Vídeo;Filme;Clipe;Série;Reprodutor;DVD;TV;Disco; +Exec=true %U +Icon=totem +Terminal=false +Type=Application +Categories=GTK;GNOME;AudioVideo;Player;Video; +X-GNOME-DocPath=totem/totem.xml +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=totem +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.1 +X-GNOME-Bugzilla-OtherBinaries=totem-video-thumbnailer;totem-audio-preview; +X-GNOME-Bugzilla-ExtraInfoScript=true +StartupNotify=true +MimeType=application/mxf;application/ogg;application/ram;application/sdp;application/smil;application/smil+xml;application/vnd.apple.mpegurl;application/vnd.ms-wpl;application/vnd.rn-realmedia;application/x-extension-m4a;application/x-extension-mp4;application/x-flac;application/x-flash-video;application/x-matroska;application/x-netshow-channel;application/x-ogg;application/x-quicktime-media-link;application/x-quicktimeplayer;application/x-shorten;application/x-smil;application/xspf+xml;audio/3gpp;audio/ac3;audio/AMR;audio/AMR-WB;audio/basic;audio/flac;audio/midi;audio/mp2;audio/mp4;audio/mpeg;audio/mpegurl;audio/ogg;audio/prs.sid;audio/vnd.rn-realaudio;audio/x-aiff;audio/x-ape;audio/x-flac;audio/x-gsm;audio/x-it;audio/x-m4a;audio/x-matroska;audio/x-mod;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-asf;audio/x-ms-asx;audio/x-ms-wax;audio/x-ms-wma;audio/x-musepack;audio/x-pn-aiff;audio/x-pn-au;audio/x-pn-realaudio;audio/x-pn-realaudio-plugin;audio/x-pn-wav;audio/x-pn-windows-acm;audio/x-realaudio;audio/x-real-audio;audio/x-s3m;audio/x-sbc;audio/x-scpls;audio/x-speex;audio/x-stm;audio/x-tta;audio/x-wav;audio/x-wavpack;audio/x-vorbis;audio/x-vorbis+ogg;audio/x-xm;image/vnd.rn-realpix;image/x-pict;misc/ultravox;text/google-video-pointer;text/x-google-video-pointer;video/3gp;video/3gpp;video/dv;video/divx;video/fli;video/flv;video/mp2t;video/mp4;video/mp4v-es;video/mpeg;video/msvideo;video/ogg;video/quicktime;video/vivo;video/vnd.divx;video/vnd.mpegurl;video/vnd.rn-realvideo;video/vnd.vivo;video/webm;video/x-anim;video/x-avi;video/x-flc;video/x-fli;video/x-flic;video/x-flv;video/x-m4v;video/x-matroska;video/x-mpeg;video/x-mpeg2;video/x-ms-asf;video/x-ms-asx;video/x-msvideo;video/x-ms-wm;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvx;video/x-nsv;video/x-ogm+ogg;video/x-theora+ogg;video/x-totem-stream;x-content/video-dvd;x-content/video-vcd;x-content/video-svcd;x-scheme-handler/pnm;x-scheme-handler/mms;x-scheme-handler/net;x-scheme-handler/rtp;x-scheme-handler/rtmp;x-scheme-handler/rtsp;x-scheme-handler/mmsh;x-scheme-handler/uvox;x-scheme-handler/icy;x-scheme-handler/icyx; diff --git a/gio/tests/desktop-files/usr/applications/yelp.desktop b/gio/tests/desktop-files/usr/applications/yelp.desktop new file mode 100644 index 0000000..3c58575 --- /dev/null +++ b/gio/tests/desktop-files/usr/applications/yelp.desktop @@ -0,0 +1,39 @@ +[Desktop Entry] +Name=Help +Name[bn]=সহায়তা +Name[bn_IN]=সাহাযà§à¦¯ +Name[ca]=Ajuda +Name[ca@valencia]=Ajuda +Name[en_CA]=Help +Name[en_GB]=Help +Name[eo]=Helpo +Name[pt]=Ajuda +Name[pt_BR]=Ajuda +Comment=Get help with GNOME +Comment[bn]=GNOME থেকে সহায়তা নিন +Comment[bn_IN]=GNOME থেকে সহায়তা পà§à¦°à¦¾à¦ªà§à¦¤ করà§à¦¨ +Comment[ca]=Obtingueu ajuda per al GNOME +Comment[ca@valencia]=Obtingueu ajuda per al GNOME +Comment[en_CA]=Get help with GNOME +Comment[en_GB]=Get help with GNOME +Comment[eo]=Ricevi helpon pri GNOME +Comment[pt]=Obtenha ajuda com o GNOME +Comment[pt_BR]=Obtenha ajuda sobre o GNOME +Keywords=documentation;information;manual; +Keywords[ca]=documentació;informació;manual; +Keywords[ca@valencia]=documentació;informació;manual; +Keywords[eo]=dokumentado;informo;manlibro;gvidilo; +Keywords[pt]=documentação;informação;manual; +Keywords[pt_BR]=documentação;informação;informações;manual; +OnlyShowIn=GNOME;Unity; +Exec=true %u +Icon=help-browser +StartupNotify=true +Terminal=false +Type=Application +Categories=GNOME;GTK;Core;Documentation;Utility; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=Yelp +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-Version=3.10.0 +MimeType=x-scheme-handler/ghelp;x-scheme-handler/help;x-scheme-handler/info;x-scheme-handler/man; diff --git a/gio/tests/echo-server.c b/gio/tests/echo-server.c new file mode 100644 index 0000000..83d1d32 --- /dev/null +++ b/gio/tests/echo-server.c @@ -0,0 +1,70 @@ +#include +#include + +#define MESSAGE "Welcome to the echo service!\n" + +int port = 7777; +static GOptionEntry cmd_entries[] = { + {"port", 'p', 0, G_OPTION_ARG_INT, &port, + "Local port to bind to", NULL}, + G_OPTION_ENTRY_NULL +}; + + +static gboolean +handler (GThreadedSocketService *service, + GSocketConnection *connection, + GSocketListener *listener, + gpointer user_data) +{ + GOutputStream *out; + GInputStream *in; + char buffer[1024]; + gssize size; + + out = g_io_stream_get_output_stream (G_IO_STREAM (connection)); + in = g_io_stream_get_input_stream (G_IO_STREAM (connection)); + + g_output_stream_write_all (out, MESSAGE, strlen (MESSAGE), + NULL, NULL, NULL); + + while (0 < (size = g_input_stream_read (in, buffer, + sizeof buffer, NULL, NULL))) + g_output_stream_write (out, buffer, size, NULL, NULL); + + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + GSocketService *service; + GOptionContext *context; + GError *error = NULL; + + context = g_option_context_new (" - Test GSocket server stuff"); + g_option_context_add_main_entries (context, cmd_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + service = g_threaded_socket_service_new (10); + + if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service), + port, + NULL, + &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + g_print ("Echo service listening on port %d\n", port); + + g_signal_connect (service, "run", G_CALLBACK (handler), NULL); + + g_main_loop_run (g_main_loop_new (NULL, FALSE)); + g_assert_not_reached (); +} diff --git a/gio/tests/empty.txt b/gio/tests/empty.txt new file mode 100644 index 0000000..e69de29 diff --git a/gio/tests/enums.xml.template b/gio/tests/enums.xml.template new file mode 100644 index 0000000..67d07b5 --- /dev/null +++ b/gio/tests/enums.xml.template @@ -0,0 +1,18 @@ +/*** BEGIN comment ***/ + +/*** END comment ***/ +/*** BEGIN file-header ***/ + +/*** END file-header ***/ +/*** BEGIN value-header ***/ + <@type@ id='org.gtk.test.@EnumName@'> +/*** END value-header ***/ +/*** BEGIN value-production ***/ + +/*** END value-production ***/ +/*** BEGIN value-tail ***/ + +/*** END value-tail ***/ +/*** BEGIN file-tail ***/ + +/*** END file-tail ***/ diff --git a/gio/tests/fake-document-portal.c b/gio/tests/fake-document-portal.c new file mode 100644 index 0000000..c9bb795 --- /dev/null +++ b/gio/tests/fake-document-portal.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2019 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: James Henstridge + */ + +/* A stub implementation of xdg-document-portal covering enough to + * support g_document_portal_add_documents */ + +#include +#include +#include + +#include "fake-document-portal-generated.h" + +static gboolean +on_handle_get_mount_point (FakeDocuments *object, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + fake_documents_complete_get_mount_point (object, + invocation, + "/document-portal"); + return TRUE; +} + +static gboolean +on_handle_add_full (FakeDocuments *object, + GDBusMethodInvocation *invocation, + GUnixFDList *o_path_fds, + guint flags, + const gchar *app_id, + const gchar * const *permissions, + gpointer user_data) +{ + const gchar **doc_ids = NULL; + GVariant *extra_out = NULL; + gsize length, i; + + if (o_path_fds != NULL) + length = g_unix_fd_list_get_length (o_path_fds); + else + length = 0; + + doc_ids = g_new0 (const gchar *, length + 1 /* NULL terminator */); + for (i = 0; i < length; i++) + { + doc_ids[i] = "document-id"; + } + extra_out = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0); + + fake_documents_complete_add_full (object, + invocation, + NULL, + doc_ids, + extra_out); + + g_free (doc_ids); + + return TRUE; +} + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + FakeDocuments *interface; + GError *error = NULL; + + g_test_message ("Acquired a message bus connection"); + + interface = fake_documents_skeleton_new (); + g_signal_connect (interface, + "handle-get-mount-point", + G_CALLBACK (on_handle_get_mount_point), + NULL); + g_signal_connect (interface, + "handle-add-full", + G_CALLBACK (on_handle_add_full), + NULL); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interface), + connection, + "/org/freedesktop/portal/documents", + &error); + g_assert_no_error (error); +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_test_message ("Acquired the name %s", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_test_message ("Lost the name %s", name); +} + + +gint +main (gint argc, gchar *argv[]) +{ + GMainLoop *loop; + guint id; + + loop = g_main_loop_new (NULL, FALSE); + + id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.freedesktop.portal.Documents", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + G_BUS_NAME_OWNER_FLAGS_REPLACE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + loop, + NULL); + + g_main_loop_run (loop); + + g_bus_unown_name (id); + g_main_loop_unref (loop); + + return 0; +} diff --git a/gio/tests/fake-service-name.c b/gio/tests/fake-service-name.c new file mode 100644 index 0000000..c3a6118 --- /dev/null +++ b/gio/tests/fake-service-name.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2021 Frederic Martinsons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Frederic Martinsons + */ + +/* A dummy service which just own a dbus name and implement a method to quit*/ + +#include +#include + +static GDBusNodeInfo *introspection_data = NULL; +static GMainLoop *loop = NULL; +static const gchar introspection_xml[] = + "" + " " + " " + " " + ""; + +static void +incoming_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + if (g_strcmp0 (method_name, "Quit") == 0) + { + g_dbus_method_invocation_return_value (invocation, NULL); + g_main_loop_quit (loop); + } +} + +static const GDBusInterfaceVTable interface_vtable = { + incoming_method_call, + NULL, + NULL, + { 0 } +}; + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + guint registration_id; + GError *error = NULL; + g_test_message ("Acquired a message bus connection"); + + registration_id = g_dbus_connection_register_object (connection, + "/org/gtk/GDBus/FakeService", + introspection_data->interfaces[0], + &interface_vtable, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_test_message ("Acquired the name %s", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_test_message ("Lost the name %s", name); +} + +gint +main (gint argc, gchar *argv[]) +{ + guint id; + + loop = g_main_loop_new (NULL, FALSE); + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + g_assert (introspection_data != NULL); + + id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gtk.GDBus.FakeService", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + G_BUS_NAME_OWNER_FLAGS_REPLACE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + loop, + NULL); + + g_main_loop_run (loop); + + g_bus_unown_name (id); + g_main_loop_unref (loop); + g_dbus_node_info_unref (introspection_data); + + return 0; +} diff --git a/gio/tests/file.c b/gio/tests/file.c new file mode 100644 index 0000000..a849e83 --- /dev/null +++ b/gio/tests/file.c @@ -0,0 +1,3160 @@ +#include +#include +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#endif + +static void +test_basic_for_file (GFile *file, + const gchar *suffix) +{ + gchar *s; + + s = g_file_get_basename (file); + g_assert_cmpstr (s, ==, "testfile"); + g_free (s); + + s = g_file_get_uri (file); + g_assert_true (g_str_has_prefix (s, "file://")); + g_assert_true (g_str_has_suffix (s, suffix)); + g_free (s); + + g_assert_true (g_file_has_uri_scheme (file, "file")); + s = g_file_get_uri_scheme (file); + g_assert_cmpstr (s, ==, "file"); + g_free (s); +} + +static void +test_basic (void) +{ + GFile *file; + + file = g_file_new_for_path ("./some/directory/testfile"); + test_basic_for_file (file, "/some/directory/testfile"); + g_object_unref (file); +} + +static void +test_build_filename (void) +{ + GFile *file; + + file = g_file_new_build_filename (".", "some", "directory", "testfile", NULL); + test_basic_for_file (file, "/some/directory/testfile"); + g_object_unref (file); + + file = g_file_new_build_filename ("testfile", NULL); + test_basic_for_file (file, "/testfile"); + g_object_unref (file); +} + +static void +test_parent (void) +{ + GFile *file; + GFile *file2; + GFile *parent; + GFile *root; + + file = g_file_new_for_path ("./some/directory/testfile"); + file2 = g_file_new_for_path ("./some/directory"); + root = g_file_new_for_path ("/"); + + g_assert_true (g_file_has_parent (file, file2)); + + parent = g_file_get_parent (file); + g_assert_true (g_file_equal (parent, file2)); + g_object_unref (parent); + + g_assert_null (g_file_get_parent (root)); + + g_object_unref (file); + g_object_unref (file2); + g_object_unref (root); +} + +static void +test_child (void) +{ + GFile *file; + GFile *child; + GFile *child2; + + file = g_file_new_for_path ("./some/directory"); + child = g_file_get_child (file, "child"); + g_assert_true (g_file_has_parent (child, file)); + + child2 = g_file_get_child_for_display_name (file, "child2", NULL); + g_assert_true (g_file_has_parent (child2, file)); + + g_object_unref (child); + g_object_unref (child2); + g_object_unref (file); +} + +static void +test_empty_path (void) +{ + GFile *file = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2328"); + g_test_summary ("Check that creating a file with an empty path results in errors"); + + /* Creating the file must always succeed. */ + file = g_file_new_for_path (""); + g_assert_nonnull (file); + + /* But then querying its path should indicate it’s invalid. */ + g_assert_null (g_file_get_path (file)); + g_assert_null (g_file_get_basename (file)); + g_assert_null (g_file_get_parent (file)); + + g_object_unref (file); +} + +static void +test_type (void) +{ + GFile *datapath_f; + GFile *file; + GFileType type; + GError *error = NULL; + + datapath_f = g_file_new_for_path (g_test_get_dir (G_TEST_DIST)); + + file = g_file_get_child (datapath_f, "g-icon.c"); + type = g_file_query_file_type (file, 0, NULL); + g_assert_cmpint (type, ==, G_FILE_TYPE_REGULAR); + g_object_unref (file); + + file = g_file_get_child (datapath_f, "cert-tests"); + type = g_file_query_file_type (file, 0, NULL); + g_assert_cmpint (type, ==, G_FILE_TYPE_DIRECTORY); + + g_file_read (file, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY); + g_error_free (error); + g_object_unref (file); + + g_object_unref (datapath_f); +} + +static void +test_parse_name (void) +{ + GFile *file; + gchar *name; + + file = g_file_new_for_uri ("file://somewhere"); + name = g_file_get_parse_name (file); + g_assert_cmpstr (name, ==, "file://somewhere"); + g_object_unref (file); + g_free (name); + + file = g_file_parse_name ("~foo"); + name = g_file_get_parse_name (file); + g_assert_nonnull (name); + g_object_unref (file); + g_free (name); +} + +typedef struct +{ + GMainContext *context; + GFile *file; + GFileMonitor *monitor; + GOutputStream *ostream; + GInputStream *istream; + gint buffersize; + gint monitor_created; + gint monitor_deleted; + gint monitor_changed; + gchar *monitor_path; + gsize pos; + const gchar *data; + gchar *buffer; + guint timeout; + gboolean file_deleted; + gboolean timed_out; +} CreateDeleteData; + +static void +monitor_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + CreateDeleteData *data = user_data; + gchar *path; + const gchar *peeked_path; + + path = g_file_get_path (file); + peeked_path = g_file_peek_path (file); + g_assert_cmpstr (data->monitor_path, ==, path); + g_assert_cmpstr (path, ==, peeked_path); + g_free (path); + + if (event_type == G_FILE_MONITOR_EVENT_CREATED) + data->monitor_created++; + if (event_type == G_FILE_MONITOR_EVENT_DELETED) + data->monitor_deleted++; + if (event_type == G_FILE_MONITOR_EVENT_CHANGED) + data->monitor_changed++; + + g_main_context_wakeup (data->context); +} + +static void +iclosed_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CreateDeleteData *data = user_data; + GError *error; + gboolean ret; + + error = NULL; + ret = g_input_stream_close_finish (data->istream, res, &error); + g_assert_no_error (error); + g_assert_true (ret); + + g_assert_true (g_input_stream_is_closed (data->istream)); + + ret = g_file_delete (data->file, NULL, &error); + g_assert_true (ret); + g_assert_no_error (error); + + data->file_deleted = TRUE; + g_main_context_wakeup (data->context); +} + +static void +read_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CreateDeleteData *data = user_data; + GError *error; + gssize size; + + error = NULL; + size = g_input_stream_read_finish (data->istream, res, &error); + g_assert_no_error (error); + + data->pos += size; + if (data->pos < strlen (data->data)) + { + g_input_stream_read_async (data->istream, + data->buffer + data->pos, + strlen (data->data) - data->pos, + 0, + NULL, + read_cb, + data); + } + else + { + g_assert_cmpstr (data->buffer, ==, data->data); + g_assert_false (g_input_stream_is_closed (data->istream)); + g_input_stream_close_async (data->istream, 0, NULL, iclosed_cb, data); + } +} + +static void +ipending_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CreateDeleteData *data = user_data; + GError *error; + + error = NULL; + g_input_stream_read_finish (data->istream, res, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING); + g_error_free (error); +} + +static void +skipped_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CreateDeleteData *data = user_data; + GError *error; + gssize size; + + error = NULL; + size = g_input_stream_skip_finish (data->istream, res, &error); + g_assert_no_error (error); + g_assert_cmpint (size, ==, data->pos); + + g_input_stream_read_async (data->istream, + data->buffer + data->pos, + strlen (data->data) - data->pos, + 0, + NULL, + read_cb, + data); + /* check that we get a pending error */ + g_input_stream_read_async (data->istream, + data->buffer + data->pos, + strlen (data->data) - data->pos, + 0, + NULL, + ipending_cb, + data); +} + +static void +opened_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GFileInputStream *base; + CreateDeleteData *data = user_data; + GError *error; + + error = NULL; + base = g_file_read_finish (data->file, res, &error); + g_assert_no_error (error); + + if (data->buffersize == 0) + data->istream = G_INPUT_STREAM (g_object_ref (base)); + else + data->istream = g_buffered_input_stream_new_sized (G_INPUT_STREAM (base), data->buffersize); + g_object_unref (base); + + data->buffer = g_new0 (gchar, strlen (data->data) + 1); + + /* copy initial segment directly, then skip */ + memcpy (data->buffer, data->data, 10); + data->pos = 10; + + g_input_stream_skip_async (data->istream, + 10, + 0, + NULL, + skipped_cb, + data); +} + +static void +oclosed_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CreateDeleteData *data = user_data; + GError *error; + gboolean ret; + + error = NULL; + ret = g_output_stream_close_finish (data->ostream, res, &error); + g_assert_no_error (error); + g_assert_true (ret); + g_assert_true (g_output_stream_is_closed (data->ostream)); + + g_file_read_async (data->file, 0, NULL, opened_cb, data); +} + +static void +written_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CreateDeleteData *data = user_data; + gssize size; + GError *error; + + error = NULL; + size = g_output_stream_write_finish (data->ostream, res, &error); + g_assert_no_error (error); + + data->pos += size; + if (data->pos < strlen (data->data)) + { + g_output_stream_write_async (data->ostream, + data->data + data->pos, + strlen (data->data) - data->pos, + 0, + NULL, + written_cb, + data); + } + else + { + g_assert_false (g_output_stream_is_closed (data->ostream)); + g_output_stream_close_async (data->ostream, 0, NULL, oclosed_cb, data); + } +} + +static void +opending_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CreateDeleteData *data = user_data; + GError *error; + + error = NULL; + g_output_stream_write_finish (data->ostream, res, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING); + g_error_free (error); +} + +static void +created_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GFileOutputStream *base; + CreateDeleteData *data = user_data; + GError *error; + + error = NULL; + base = g_file_create_finish (G_FILE (source), res, &error); + g_assert_no_error (error); + g_assert_true (g_file_query_exists (data->file, NULL)); + + if (data->buffersize == 0) + data->ostream = G_OUTPUT_STREAM (g_object_ref (base)); + else + data->ostream = g_buffered_output_stream_new_sized (G_OUTPUT_STREAM (base), data->buffersize); + g_object_unref (base); + + g_output_stream_write_async (data->ostream, + data->data, + strlen (data->data), + 0, + NULL, + written_cb, + data); + /* check that we get a pending error */ + g_output_stream_write_async (data->ostream, + data->data, + strlen (data->data), + 0, + NULL, + opending_cb, + data); +} + +static gboolean +stop_timeout (gpointer user_data) +{ + CreateDeleteData *data = user_data; + + data->timed_out = TRUE; + g_main_context_wakeup (data->context); + + return G_SOURCE_REMOVE; +} + +/* + * This test does a fully async create-write-read-delete. + * Callbackistan. + */ +static void +test_create_delete (gconstpointer d) +{ + GError *error; + CreateDeleteData *data; + GFileIOStream *iostream; + + data = g_new0 (CreateDeleteData, 1); + + data->buffersize = GPOINTER_TO_INT (d); + data->data = "abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789"; + data->pos = 0; + + data->file = g_file_new_tmp ("g_file_create_delete_XXXXXX", + &iostream, NULL); + g_assert_nonnull (data->file); + g_object_unref (iostream); + + data->monitor_path = g_file_get_path (data->file); + remove (data->monitor_path); + + g_assert_false (g_file_query_exists (data->file, NULL)); + + error = NULL; + data->monitor = g_file_monitor_file (data->file, 0, NULL, &error); + g_assert_no_error (error); + + /* This test doesn't work with GPollFileMonitor, because it assumes + * that the monitor will notice a create immediately followed by a + * delete, rather than coalescing them into nothing. + */ + /* This test also doesn't work with GKqueueFileMonitor because of + * the same reason. Kqueue is able to return a kevent when a file is + * created or deleted in a directory. However, the kernel doesn't tell + * the program file names, so GKqueueFileMonitor has to calculate the + * difference itself. This is usually too slow for rapid file creation + * and deletion tests. + */ + if (strcmp (G_OBJECT_TYPE_NAME (data->monitor), "GPollFileMonitor") == 0 || + strcmp (G_OBJECT_TYPE_NAME (data->monitor), "GKqueueFileMonitor") == 0) + { + g_test_skip ("skipping test for this GFileMonitor implementation"); + goto skip; + } + + g_file_monitor_set_rate_limit (data->monitor, 100); + + g_signal_connect (data->monitor, "changed", G_CALLBACK (monitor_changed), data); + + /* Use the global default main context */ + data->context = NULL; + data->timeout = g_timeout_add_seconds (10, stop_timeout, data); + + g_file_create_async (data->file, 0, 0, NULL, created_cb, data); + + while (!data->timed_out && + (data->monitor_created == 0 || + data->monitor_deleted == 0 || + data->monitor_changed == 0 || + !data->file_deleted)) + g_main_context_iteration (data->context, TRUE); + + g_source_remove (data->timeout); + + g_assert_false (data->timed_out); + g_assert_true (data->file_deleted); + g_assert_cmpint (data->monitor_created, ==, 1); + g_assert_cmpint (data->monitor_deleted, ==, 1); + g_assert_cmpint (data->monitor_changed, >, 0); + + g_assert_false (g_file_monitor_is_cancelled (data->monitor)); + g_file_monitor_cancel (data->monitor); + g_assert_true (g_file_monitor_is_cancelled (data->monitor)); + + g_clear_pointer (&data->context, g_main_context_unref); + g_object_unref (data->ostream); + g_object_unref (data->istream); + + skip: + g_object_unref (data->monitor); + g_object_unref (data->file); + g_free (data->monitor_path); + g_free (data->buffer); + g_free (data); +} + +static const gchar *original_data = + "/**\n" + " * g_file_replace_contents_async:\n" + "**/\n"; + +static const gchar *replace_data = + "/**\n" + " * g_file_replace_contents_async:\n" + " * @file: input #GFile.\n" + " * @contents: string of contents to replace the file with.\n" + " * @length: the length of @contents in bytes.\n" + " * @etag: (nullable): a new entity tag for the @file, or %NULL\n" + " * @make_backup: %TRUE if a backup should be created.\n" + " * @flags: a set of #GFileCreateFlags.\n" + " * @cancellable: optional #GCancellable object, %NULL to ignore.\n" + " * @callback: a #GAsyncReadyCallback to call when the request is satisfied\n" + " * @user_data: the data to pass to callback function\n" + " * \n" + " * Starts an asynchronous replacement of @file with the given \n" + " * @contents of @length bytes. @etag will replace the document's\n" + " * current entity tag.\n" + " * \n" + " * When this operation has completed, @callback will be called with\n" + " * @user_user data, and the operation can be finalized with \n" + " * g_file_replace_contents_finish().\n" + " * \n" + " * If @cancellable is not %NULL, then the operation can be cancelled by\n" + " * triggering the cancellable object from another thread. If the operation\n" + " * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. \n" + " * \n" + " * If @make_backup is %TRUE, this function will attempt to \n" + " * make a backup of @file.\n" + " **/\n"; + +typedef struct +{ + GFile *file; + const gchar *data; + GMainLoop *loop; + gboolean again; +} ReplaceLoadData; + +static void replaced_cb (GObject *source, + GAsyncResult *res, + gpointer user_data); + +static void +loaded_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + ReplaceLoadData *data = user_data; + gboolean ret; + GError *error; + gchar *contents; + gsize length; + + error = NULL; + ret = g_file_load_contents_finish (data->file, res, &contents, &length, NULL, &error); + g_assert_true (ret); + g_assert_no_error (error); + g_assert_cmpint (length, ==, strlen (data->data)); + g_assert_cmpstr (contents, ==, data->data); + + g_free (contents); + + if (data->again) + { + data->again = FALSE; + data->data = "pi pa po"; + + g_file_replace_contents_async (data->file, + data->data, + strlen (data->data), + NULL, + FALSE, + 0, + NULL, + replaced_cb, + data); + } + else + { + error = NULL; + ret = g_file_delete (data->file, NULL, &error); + g_assert_no_error (error); + g_assert_true (ret); + g_assert_false (g_file_query_exists (data->file, NULL)); + + g_main_loop_quit (data->loop); + } +} + +static void +replaced_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + ReplaceLoadData *data = user_data; + GError *error; + + error = NULL; + g_file_replace_contents_finish (data->file, res, NULL, &error); + g_assert_no_error (error); + + g_file_load_contents_async (data->file, NULL, loaded_cb, data); +} + +static void +test_replace_load (void) +{ + ReplaceLoadData *data; + const gchar *path; + GFileIOStream *iostream; + + data = g_new0 (ReplaceLoadData, 1); + data->again = TRUE; + data->data = replace_data; + + data->file = g_file_new_tmp ("g_file_replace_load_XXXXXX", + &iostream, NULL); + g_assert_nonnull (data->file); + g_object_unref (iostream); + + path = g_file_peek_path (data->file); + remove (path); + + g_assert_false (g_file_query_exists (data->file, NULL)); + + data->loop = g_main_loop_new (NULL, FALSE); + + g_file_replace_contents_async (data->file, + data->data, + strlen (data->data), + NULL, + FALSE, + 0, + NULL, + replaced_cb, + data); + + g_main_loop_run (data->loop); + + g_main_loop_unref (data->loop); + g_object_unref (data->file); + g_free (data); +} + +static void +test_replace_cancel (void) +{ + GFile *tmpdir, *file; + GFileOutputStream *ostream; + GFileEnumerator *fenum; + GFileInfo *info; + GCancellable *cancellable; + gchar *path; + gchar *contents; + gsize nwrote, length; + guint count; + GError *error = NULL; + + g_test_bug ("https://bugzilla.gnome.org/629301"); + + path = g_dir_make_tmp ("g_file_replace_cancel_XXXXXX", &error); + g_assert_no_error (error); + tmpdir = g_file_new_for_path (path); + g_free (path); + + file = g_file_get_child (tmpdir, "file"); + g_file_replace_contents (file, + original_data, + strlen (original_data), + NULL, FALSE, 0, NULL, + NULL, &error); + g_assert_no_error (error); + + ostream = g_file_replace (file, NULL, TRUE, 0, NULL, &error); + g_assert_no_error (error); + + g_output_stream_write_all (G_OUTPUT_STREAM (ostream), + replace_data, strlen (replace_data), + &nwrote, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, strlen (replace_data)); + + /* At this point there should be two files; the original and the + * temporary. + */ + fenum = g_file_enumerate_children (tmpdir, NULL, 0, NULL, &error); + g_assert_no_error (error); + + info = g_file_enumerator_next_file (fenum, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (info); + g_object_unref (info); + info = g_file_enumerator_next_file (fenum, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (info); + g_object_unref (info); + + g_file_enumerator_close (fenum, NULL, &error); + g_assert_no_error (error); + g_object_unref (fenum); + + /* Also test the g_file_enumerator_iterate() API */ + fenum = g_file_enumerate_children (tmpdir, NULL, 0, NULL, &error); + g_assert_no_error (error); + count = 0; + + while (TRUE) + { + gboolean ret = g_file_enumerator_iterate (fenum, &info, NULL, NULL, &error); + g_assert_true (ret); + g_assert_no_error (error); + if (!info) + break; + count++; + } + g_assert_cmpint (count, ==, 2); + + g_file_enumerator_close (fenum, NULL, &error); + g_assert_no_error (error); + g_object_unref (fenum); + + /* Now test just getting child from the g_file_enumerator_iterate() API */ + fenum = g_file_enumerate_children (tmpdir, "standard::name", 0, NULL, &error); + g_assert_no_error (error); + count = 0; + + while (TRUE) + { + GFile *child; + gboolean ret = g_file_enumerator_iterate (fenum, NULL, &child, NULL, &error); + + g_assert_true (ret); + g_assert_no_error (error); + + if (!child) + break; + + g_assert_true (G_IS_FILE (child)); + count++; + } + g_assert_cmpint (count, ==, 2); + + g_file_enumerator_close (fenum, NULL, &error); + g_assert_no_error (error); + g_object_unref (fenum); + + /* Make sure the temporary gets deleted even if we cancel. */ + cancellable = g_cancellable_new (); + g_cancellable_cancel (cancellable); + g_output_stream_close (G_OUTPUT_STREAM (ostream), cancellable, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + + g_object_unref (cancellable); + g_object_unref (ostream); + + /* Make sure that file contents wasn't actually replaced. */ + g_file_load_contents (file, + NULL, + &contents, + &length, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (contents, ==, original_data); + g_free (contents); + + g_file_delete (file, NULL, &error); + g_assert_no_error (error); + g_object_unref (file); + + /* This will only succeed if the temp file was deleted. */ + g_file_delete (tmpdir, NULL, &error); + g_assert_no_error (error); + g_object_unref (tmpdir); +} + +static void +test_replace_symlink (void) +{ +#ifdef G_OS_UNIX + gchar *tmpdir_path = NULL; + GFile *tmpdir = NULL, *source_file = NULL, *target_file = NULL; + GFileOutputStream *stream = NULL; + const gchar *new_contents = "this is a test message which should be written to source and not target"; + gsize n_written; + GFileEnumerator *enumerator = NULL; + GFileInfo *info = NULL; + gchar *contents = NULL; + gsize length = 0; + GError *local_error = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2325"); + g_test_summary ("Test that G_FILE_CREATE_REPLACE_DESTINATION doesn’t follow symlinks"); + + /* Create a fresh, empty working directory. */ + tmpdir_path = g_dir_make_tmp ("g_file_replace_symlink_XXXXXX", &local_error); + g_assert_no_error (local_error); + tmpdir = g_file_new_for_path (tmpdir_path); + + g_test_message ("Using temporary directory %s", tmpdir_path); + g_free (tmpdir_path); + + /* Create symlink `source` which points to `target`. */ + source_file = g_file_get_child (tmpdir, "source"); + target_file = g_file_get_child (tmpdir, "target"); + g_file_make_symbolic_link (source_file, "target", NULL, &local_error); + g_assert_no_error (local_error); + + /* Ensure that `target` doesn’t exist */ + g_assert_false (g_file_query_exists (target_file, NULL)); + + /* Replace the `source` symlink with a regular file using + * %G_FILE_CREATE_REPLACE_DESTINATION, which should replace it *without* + * following the symlink */ + stream = g_file_replace (source_file, NULL, FALSE /* no backup */, + G_FILE_CREATE_REPLACE_DESTINATION, NULL, &local_error); + g_assert_no_error (local_error); + + g_output_stream_write_all (G_OUTPUT_STREAM (stream), new_contents, strlen (new_contents), + &n_written, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_cmpint (n_written, ==, strlen (new_contents)); + + g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, &local_error); + g_assert_no_error (local_error); + + g_clear_object (&stream); + + /* At this point, there should still only be one file: `source`. It should + * now be a regular file. `target` should not exist. */ + enumerator = g_file_enumerate_children (tmpdir, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error); + g_assert_no_error (local_error); + + info = g_file_enumerator_next_file (enumerator, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (info); + + g_assert_cmpstr (g_file_info_get_name (info), ==, "source"); + g_assert_cmpint (g_file_info_get_file_type (info), ==, G_FILE_TYPE_REGULAR); + + g_clear_object (&info); + + info = g_file_enumerator_next_file (enumerator, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_null (info); + + g_file_enumerator_close (enumerator, NULL, &local_error); + g_assert_no_error (local_error); + g_clear_object (&enumerator); + + /* Double-check that `target` doesn’t exist */ + g_assert_false (g_file_query_exists (target_file, NULL)); + + /* Check the content of `source`. */ + g_file_load_contents (source_file, + NULL, + &contents, + &length, + NULL, + &local_error); + g_assert_no_error (local_error); + g_assert_cmpstr (contents, ==, new_contents); + g_assert_cmpuint (length, ==, strlen (new_contents)); + g_free (contents); + + /* Tidy up. */ + g_file_delete (source_file, NULL, &local_error); + g_assert_no_error (local_error); + + g_file_delete (tmpdir, NULL, &local_error); + g_assert_no_error (local_error); + + g_clear_object (&target_file); + g_clear_object (&source_file); + g_clear_object (&tmpdir); +#else /* if !G_OS_UNIX */ + g_test_skip ("Symlink replacement tests can only be run on Unix") +#endif +} + +static void +test_replace_symlink_using_etag (void) +{ +#ifdef G_OS_UNIX + gchar *tmpdir_path = NULL; + GFile *tmpdir = NULL, *source_file = NULL, *target_file = NULL; + GFileOutputStream *stream = NULL; + const gchar *old_contents = "this is a test message which should be written to target and then overwritten"; + gchar *old_etag = NULL; + const gchar *new_contents = "this is an updated message"; + gsize n_written; + gchar *contents = NULL; + gsize length = 0; + GFileInfo *info = NULL; + GError *local_error = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2417"); + g_test_summary ("Test that ETag checks work when replacing a file through a symlink"); + + /* Create a fresh, empty working directory. */ + tmpdir_path = g_dir_make_tmp ("g_file_replace_symlink_using_etag_XXXXXX", &local_error); + g_assert_no_error (local_error); + tmpdir = g_file_new_for_path (tmpdir_path); + + g_test_message ("Using temporary directory %s", tmpdir_path); + g_free (tmpdir_path); + + /* Create symlink `source` which points to `target`. */ + source_file = g_file_get_child (tmpdir, "source"); + target_file = g_file_get_child (tmpdir, "target"); + g_file_make_symbolic_link (source_file, "target", NULL, &local_error); + g_assert_no_error (local_error); + + /* Sleep for at least 1s to ensure the mtimes of `source` and `target` differ, + * as that’s what _g_local_file_info_create_etag() uses to create the ETag, + * and one failure mode we’re testing for is that the ETags of `source` and + * `target` are conflated. */ + sleep (1); + + /* Create `target` with some arbitrary content. */ + stream = g_file_create (target_file, G_FILE_CREATE_NONE, NULL, &local_error); + g_assert_no_error (local_error); + g_output_stream_write_all (G_OUTPUT_STREAM (stream), old_contents, strlen (old_contents), + &n_written, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_cmpint (n_written, ==, strlen (old_contents)); + + g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, &local_error); + g_assert_no_error (local_error); + + old_etag = g_file_output_stream_get_etag (stream); + g_assert_nonnull (old_etag); + g_assert_cmpstr (old_etag, !=, ""); + + g_clear_object (&stream); + + /* Sleep again to ensure the ETag changes again. */ + sleep (1); + + /* Write out a new copy of the `target`, checking its ETag first. This should + * replace `target` by following the symlink. */ + stream = g_file_replace (source_file, old_etag, FALSE /* no backup */, + G_FILE_CREATE_NONE, NULL, &local_error); + g_assert_no_error (local_error); + + g_output_stream_write_all (G_OUTPUT_STREAM (stream), new_contents, strlen (new_contents), + &n_written, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_cmpint (n_written, ==, strlen (new_contents)); + + g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, &local_error); + g_assert_no_error (local_error); + + g_clear_object (&stream); + + /* At this point, there should be a regular file, `target`, containing + * @new_contents; and a symlink `source` which points to `target`. */ + g_assert_cmpint (g_file_query_file_type (source_file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL), ==, G_FILE_TYPE_SYMBOLIC_LINK); + g_assert_cmpint (g_file_query_file_type (target_file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL), ==, G_FILE_TYPE_REGULAR); + + /* Check the content of `target`. */ + g_file_load_contents (target_file, + NULL, + &contents, + &length, + NULL, + &local_error); + g_assert_no_error (local_error); + g_assert_cmpstr (contents, ==, new_contents); + g_assert_cmpuint (length, ==, strlen (new_contents)); + g_free (contents); + + /* And check its ETag value has changed. */ + info = g_file_query_info (target_file, G_FILE_ATTRIBUTE_ETAG_VALUE, + G_FILE_QUERY_INFO_NONE, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_cmpstr (g_file_info_get_etag (info), !=, old_etag); + + g_clear_object (&info); + g_free (old_etag); + + /* Tidy up. */ + g_file_delete (target_file, NULL, &local_error); + g_assert_no_error (local_error); + + g_file_delete (source_file, NULL, &local_error); + g_assert_no_error (local_error); + + g_file_delete (tmpdir, NULL, &local_error); + g_assert_no_error (local_error); + + g_clear_object (&target_file); + g_clear_object (&source_file); + g_clear_object (&tmpdir); +#else /* if !G_OS_UNIX */ + g_test_skip ("Symlink replacement tests can only be run on Unix") +#endif +} + +/* FIXME: These tests have only been checked on Linux. Most of them are probably + * applicable on Windows, too, but that has not been tested yet. + * See https://gitlab.gnome.org/GNOME/glib/-/issues/2325 */ +#ifdef __linux__ + +/* Different kinds of file which create_test_file() can create. */ +typedef enum +{ + FILE_TEST_SETUP_TYPE_NONEXISTENT, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, + FILE_TEST_SETUP_TYPE_DIRECTORY, + FILE_TEST_SETUP_TYPE_SOCKET, + FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING, + FILE_TEST_SETUP_TYPE_SYMLINK_VALID, +} FileTestSetupType; + +/* Create file `tmpdir/basename`, of type @setup_type, and chmod it to + * @setup_mode. Return the #GFile representing it. Abort on any errors. */ +static GFile * +create_test_file (GFile *tmpdir, + const gchar *basename, + FileTestSetupType setup_type, + guint setup_mode) +{ + GFile *test_file = g_file_get_child (tmpdir, basename); + gchar *target_basename = g_strdup_printf ("%s-target", basename); /* for symlinks */ + GFile *target_file = g_file_get_child (tmpdir, target_basename); + GError *local_error = NULL; + + switch (setup_type) + { + case FILE_TEST_SETUP_TYPE_NONEXISTENT: + /* Nothing to do here. */ + g_assert (setup_mode == 0); + break; + case FILE_TEST_SETUP_TYPE_REGULAR_EMPTY: + case FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY: + { + gchar *contents = NULL; + + if (setup_type == FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY) + contents = g_strdup_printf ("this is some test content in %s", basename); + else + contents = g_strdup (""); + + g_file_set_contents (g_file_peek_path (test_file), contents, -1, &local_error); + g_assert_no_error (local_error); + + g_file_set_attribute_uint32 (test_file, G_FILE_ATTRIBUTE_UNIX_MODE, + setup_mode, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, &local_error); + g_assert_no_error (local_error); + + g_free (contents); + break; + } + case FILE_TEST_SETUP_TYPE_DIRECTORY: + g_assert (setup_mode == 0); + + g_file_make_directory (test_file, NULL, &local_error); + g_assert_no_error (local_error); + break; + case FILE_TEST_SETUP_TYPE_SOCKET: + g_assert_no_errno (mknod (g_file_peek_path (test_file), S_IFSOCK | setup_mode, 0)); + break; + case FILE_TEST_SETUP_TYPE_SYMLINK_VALID: + g_file_set_contents (g_file_peek_path (target_file), "target file", -1, &local_error); + g_assert_no_error (local_error); + G_GNUC_FALLTHROUGH; + case FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING: + /* Permissions on a symlink are not used by the kernel, so are only + * applicable if the symlink is valid (and are applied to the target) */ + g_assert (setup_type != FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING || setup_mode == 0); + + g_file_make_symbolic_link (test_file, target_basename, NULL, &local_error); + g_assert_no_error (local_error); + + if (setup_type == FILE_TEST_SETUP_TYPE_SYMLINK_VALID) + { + g_file_set_attribute_uint32 (test_file, G_FILE_ATTRIBUTE_UNIX_MODE, + setup_mode, G_FILE_QUERY_INFO_NONE, + NULL, &local_error); + g_assert_no_error (local_error); + } + + if (setup_type == FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING) + { + /* Ensure that the target doesn’t exist */ + g_assert_false (g_file_query_exists (target_file, NULL)); + } + break; + default: + g_assert_not_reached (); + } + + g_clear_object (&target_file); + g_free (target_basename); + + return g_steal_pointer (&test_file); +} + +/* Check that @test_file is of the @expected_type, has the @expected_mode, and + * (if it’s a regular file) has the @expected_contents or (if it’s a symlink) + * has the symlink target given by @expected_contents. + * + * @test_file must point to the file `tmpdir/basename`. + * + * Aborts on any errors or mismatches against the expectations. + */ +static void +check_test_file (GFile *test_file, + GFile *tmpdir, + const gchar *basename, + FileTestSetupType expected_type, + guint expected_mode, + const gchar *expected_contents) +{ + gchar *target_basename = g_strdup_printf ("%s-target", basename); /* for symlinks */ + GFile *target_file = g_file_get_child (tmpdir, target_basename); + GFileType test_file_type = g_file_query_file_type (test_file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL); + GFileInfo *info = NULL; + GError *local_error = NULL; + + switch (expected_type) + { + case FILE_TEST_SETUP_TYPE_NONEXISTENT: + g_assert (expected_mode == 0); + g_assert (expected_contents == NULL); + + g_assert_false (g_file_query_exists (test_file, NULL)); + g_assert_cmpint (test_file_type, ==, G_FILE_TYPE_UNKNOWN); + break; + case FILE_TEST_SETUP_TYPE_REGULAR_EMPTY: + case FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY: + g_assert (expected_type != FILE_TEST_SETUP_TYPE_REGULAR_EMPTY || expected_contents == NULL); + g_assert (expected_type != FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY || expected_contents != NULL); + + g_assert_cmpint (test_file_type, ==, G_FILE_TYPE_REGULAR); + + info = g_file_query_info (test_file, + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error); + g_assert_no_error (local_error); + + if (expected_type == FILE_TEST_SETUP_TYPE_REGULAR_EMPTY) + g_assert_cmpint (g_file_info_get_size (info), ==, 0); + else + g_assert_cmpint (g_file_info_get_size (info), >, 0); + + if (expected_contents != NULL) + { + gchar *contents = NULL; + gsize length = 0; + + g_file_get_contents (g_file_peek_path (test_file), &contents, &length, &local_error); + g_assert_no_error (local_error); + + g_assert_cmpstr (contents, ==, expected_contents); + g_free (contents); + } + + g_assert_cmpuint (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE) & 0777, ==, expected_mode); + + break; + case FILE_TEST_SETUP_TYPE_DIRECTORY: + g_assert (expected_mode == 0); + g_assert (expected_contents == NULL); + + g_assert_cmpint (test_file_type, ==, G_FILE_TYPE_DIRECTORY); + break; + case FILE_TEST_SETUP_TYPE_SOCKET: + g_assert (expected_contents == NULL); + + g_assert_cmpint (test_file_type, ==, G_FILE_TYPE_SPECIAL); + + info = g_file_query_info (test_file, + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error); + g_assert_no_error (local_error); + + g_assert_cmpuint (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE) & 0777, ==, expected_mode); + break; + case FILE_TEST_SETUP_TYPE_SYMLINK_VALID: + case FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING: + { + GFile *symlink_target_file = NULL; + + /* Permissions on a symlink are not used by the kernel, so are only + * applicable if the symlink is valid (and are applied to the target) */ + g_assert (expected_type != FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING || expected_mode == 0); + g_assert (expected_contents != NULL); + + g_assert_cmpint (test_file_type, ==, G_FILE_TYPE_SYMBOLIC_LINK); + + info = g_file_query_info (test_file, + G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error); + g_assert_no_error (local_error); + + g_assert_cmpstr (g_file_info_get_symlink_target (info), ==, expected_contents); + + symlink_target_file = g_file_get_child (tmpdir, g_file_info_get_symlink_target (info)); + if (expected_type == FILE_TEST_SETUP_TYPE_SYMLINK_VALID) + g_assert_true (g_file_query_exists (symlink_target_file, NULL)); + else + g_assert_false (g_file_query_exists (symlink_target_file, NULL)); + + if (expected_type == FILE_TEST_SETUP_TYPE_SYMLINK_VALID) + { + GFileInfo *target_info = NULL; + + /* Need to re-query the info so we follow symlinks */ + target_info = g_file_query_info (test_file, + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_QUERY_INFO_NONE, NULL, &local_error); + g_assert_no_error (local_error); + + g_assert_cmpuint (g_file_info_get_attribute_uint32 (target_info, G_FILE_ATTRIBUTE_UNIX_MODE) & 0777, ==, expected_mode); + + g_clear_object (&target_info); + } + + g_clear_object (&symlink_target_file); + break; + } + default: + g_assert_not_reached (); + } + + g_clear_object (&info); + g_clear_object (&target_file); + g_free (target_basename); +} + +#endif /* __linux__ */ + +/* A big test for g_file_replace() and g_file_replace_readwrite(). The + * @test_data is a boolean: %TRUE to test g_file_replace_readwrite(), %FALSE to + * test g_file_replace(). The test setup and checks are identical for both + * functions; in the case of testing g_file_replace_readwrite(), only the output + * stream side of the returned #GIOStream is tested. i.e. We test the write + * behaviour of both functions is identical. + * + * This is intended to test all static behaviour of the function: for each test + * scenario, a temporary directory is set up with a source file (and maybe some + * other files) in a set configuration, g_file_replace{,_readwrite}() is called, + * and the final state of the directory is checked. + * + * This test does not check dynamic behaviour or race conditions. For example, + * it does not test what happens if the source file is deleted from another + * process half-way through a call to g_file_replace(). + */ +static void +test_replace (gconstpointer test_data) +{ +#ifdef __linux__ + gboolean read_write = GPOINTER_TO_UINT (test_data); + const gchar *new_contents = "this is a new test message which should be written to source"; + const gchar *original_source_contents = "this is some test content in source"; + const gchar *original_backup_contents = "this is some test content in source~"; + mode_t current_umask = umask (0); + guint32 default_public_mode = 0666 & ~current_umask; + guint32 default_private_mode = 0600; + + const struct + { + /* Arguments to pass to g_file_replace(). */ + gboolean replace_make_backup; + GFileCreateFlags replace_flags; + const gchar *replace_etag; /* (nullable) */ + + /* File system setup. */ + FileTestSetupType setup_source_type; + guint setup_source_mode; + FileTestSetupType setup_backup_type; + guint setup_backup_mode; + + /* Expected results. */ + gboolean expected_success; + GQuark expected_error_domain; + gint expected_error_code; + + /* Expected final file system state. */ + guint expected_n_files; + FileTestSetupType expected_source_type; + guint expected_source_mode; + const gchar *expected_source_contents; /* content for a regular file, or target for a symlink; NULL otherwise */ + FileTestSetupType expected_backup_type; + guint expected_backup_mode; + const gchar *expected_backup_contents; /* content for a regular file, or target for a symlink; NULL otherwise */ + } + tests[] = + { + /* replace_make_backup == FALSE, replace_flags == NONE, replace_etag == NULL, + * all the different values of setup_source_type, mostly with a backup + * file created to check it’s not modified */ + { + FALSE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 1, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + { + FALSE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_DIRECTORY, 0, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, + 2, FILE_TEST_SETUP_TYPE_DIRECTORY, 0, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE, + 2, FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING, 0, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 3, FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, "source-target", + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 3, FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, "source-target", + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + + /* replace_etag set to an invalid value, with setup_source_type as a + * regular non-empty file; replacement should fail */ + { + FALSE, G_FILE_CREATE_NONE, "incorrect etag", + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_WRONG_ETAG, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + + /* replace_make_backup == TRUE, replace_flags == NONE, replace_etag == NULL, + * all the different values of setup_source_type, with a backup + * file created to check it’s either replaced or the operation fails */ + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 1, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, default_public_mode, NULL, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_DIRECTORY, 0, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, + 2, FILE_TEST_SETUP_TYPE_DIRECTORY, 0, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE, + 2, FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING, 0, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + /* The final situation here is a bit odd; the backup file is a bit + * pointless as the original source file was a dangling symlink. + * Theoretically the backup file should be that symlink, pointing to + * `source-target`, and hence no longer dangling, as that file has now + * been created as the new source content, since REPLACE_DESTINATION was + * not specified. However, the code instead creates an empty regular + * file as the backup. FIXME: This seems acceptable for now, but not + * entirely ideal and would be good to fix at some point. */ + 3, FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, "source-target", + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, 0777 & ~current_umask, NULL, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + /* FIXME: The permissions for the backup file are just the default umask, + * but should probably be the same as the permissions for the source + * file (`default_public_mode`). This probably arises from the fact that + * symlinks don’t have permissions. */ + 3, FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, "source-target", + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, 0777 & ~current_umask, "target file", + }, + + /* replace_make_backup == TRUE, replace_flags == NONE, replace_etag == NULL, + * setup_source_type is a regular file, with a backup file of every type + * created to check it’s either replaced or the operation fails */ + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_DIRECTORY, 0, + FALSE, G_IO_ERROR, G_IO_ERROR_CANT_CREATE_BACKUP, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + FILE_TEST_SETUP_TYPE_DIRECTORY, 0, NULL, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING, 0, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, + TRUE, 0, 0, + /* the third file is `source~-target`, the original target of the old + * backup symlink */ + 3, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + + /* replace_make_backup == FALSE, replace_flags == REPLACE_DESTINATION, + * replace_etag == NULL, all the different values of setup_source_type, + * mostly with a backup file created to check it’s not modified */ + { + FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 1, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + { + FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_DIRECTORY, 0, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, + 2, FILE_TEST_SETUP_TYPE_DIRECTORY, 0, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE, + 2, FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING, 0, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + /* the third file is `source-target`, the original target of the old + * source file */ + 3, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + + /* replace_flags == REPLACE_DESTINATION, replace_etag set to an invalid + * value, with setup_source_type as a regular non-empty file; replacement + * should fail */ + { + FALSE, G_FILE_CREATE_REPLACE_DESTINATION, "incorrect etag", + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_WRONG_ETAG, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + + /* replace_make_backup == TRUE, replace_flags == REPLACE_DESTINATION, + * replace_etag == NULL, all the different values of setup_source_type, + * with a backup file created to check it’s either replaced or the + * operation fails */ + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 1, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, default_public_mode, NULL, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_DIRECTORY, 0, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, + 2, FILE_TEST_SETUP_TYPE_DIRECTORY, 0, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FALSE, G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE, + 2, FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_backup_contents, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING, 0, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING, 0, "source-target", + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + /* the third file is `source-target`, the original target of the old + * source file */ + 3, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, "source-target", + }, + + /* replace_make_backup == TRUE, replace_flags == REPLACE_DESTINATION, + * replace_etag == NULL, setup_source_type is a regular file, with a + * backup file of every type created to check it’s either replaced or the + * operation fails */ + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_DIRECTORY, 0, + FALSE, G_IO_ERROR, G_IO_ERROR_CANT_CREATE_BACKUP, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + FILE_TEST_SETUP_TYPE_DIRECTORY, 0, NULL, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_SOCKET, default_public_mode, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_SYMLINK_DANGLING, 0, + TRUE, 0, 0, + 2, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + { + TRUE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_SYMLINK_VALID, default_public_mode, + TRUE, 0, 0, + /* the third file is `source~-target`, the original target of the old + * backup symlink */ + 3, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, original_source_contents, + }, + + /* several different setups with replace_flags == PRIVATE */ + { + FALSE, G_FILE_CREATE_PRIVATE, NULL, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 1, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_private_mode, new_contents, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + { + FALSE, G_FILE_CREATE_PRIVATE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + /* the file isn’t being replaced, so it should keep its existing permissions */ + 1, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, new_contents, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + { + FALSE, G_FILE_CREATE_PRIVATE | G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 1, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_private_mode, new_contents, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + { + FALSE, G_FILE_CREATE_PRIVATE | G_FILE_CREATE_REPLACE_DESTINATION, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_public_mode, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + TRUE, 0, 0, + 1, FILE_TEST_SETUP_TYPE_REGULAR_NONEMPTY, default_private_mode, new_contents, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + + /* make the initial source file unreadable, so the replace operation + * should fail */ + { + FALSE, G_FILE_CREATE_NONE, NULL, + FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, 0 /* most restrictive permissions */, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, + FALSE, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, + 1, FILE_TEST_SETUP_TYPE_REGULAR_EMPTY, 0, NULL, + FILE_TEST_SETUP_TYPE_NONEXISTENT, 0, NULL, + }, + }; + gsize i; + + g_test_summary ("Test various situations for g_file_replace()"); + + /* Reset the umask after querying it above. There’s no way to query it without + * changing it. */ + umask (current_umask); + g_test_message ("Current umask: %u", current_umask); + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + gchar *tmpdir_path = NULL; + GFile *tmpdir = NULL, *source_file = NULL, *backup_file = NULL; + GFileOutputStream *output_stream = NULL; + GFileIOStream *io_stream = NULL; + GFileEnumerator *enumerator = NULL; + GFileInfo *info = NULL; + guint n_files; + GError *local_error = NULL; + + /* Create a fresh, empty working directory. */ + tmpdir_path = g_dir_make_tmp ("g_file_replace_XXXXXX", &local_error); + g_assert_no_error (local_error); + tmpdir = g_file_new_for_path (tmpdir_path); + + g_test_message ("Test %" G_GSIZE_FORMAT ", using temporary directory %s", i, tmpdir_path); + g_free (tmpdir_path); + + /* Set up the test directory. */ + source_file = create_test_file (tmpdir, "source", tests[i].setup_source_type, tests[i].setup_source_mode); + backup_file = create_test_file (tmpdir, "source~", tests[i].setup_backup_type, tests[i].setup_backup_mode); + + /* Replace the source file. Check the error state only after finishing + * writing, as the replace operation is split across g_file_replace() and + * g_output_stream_close(). */ + if (read_write) + io_stream = g_file_replace_readwrite (source_file, + tests[i].replace_etag, + tests[i].replace_make_backup, + tests[i].replace_flags, + NULL, + &local_error); + else + output_stream = g_file_replace (source_file, + tests[i].replace_etag, + tests[i].replace_make_backup, + tests[i].replace_flags, + NULL, + &local_error); + + if (tests[i].expected_success) + { + g_assert_no_error (local_error); + if (read_write) + g_assert_nonnull (io_stream); + else + g_assert_nonnull (output_stream); + } + + /* Write new content to it. */ + if (io_stream != NULL) + { + GOutputStream *io_output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); + gsize n_written; + + g_output_stream_write_all (G_OUTPUT_STREAM (io_output_stream), new_contents, strlen (new_contents), + &n_written, NULL, &local_error); + + if (tests[i].expected_success) + { + g_assert_no_error (local_error); + g_assert_cmpint (n_written, ==, strlen (new_contents)); + } + + g_io_stream_close (G_IO_STREAM (io_stream), NULL, (local_error == NULL) ? &local_error : NULL); + + if (tests[i].expected_success) + g_assert_no_error (local_error); + } + else if (output_stream != NULL) + { + gsize n_written; + + g_output_stream_write_all (G_OUTPUT_STREAM (output_stream), new_contents, strlen (new_contents), + &n_written, NULL, &local_error); + + if (tests[i].expected_success) + { + g_assert_no_error (local_error); + g_assert_cmpint (n_written, ==, strlen (new_contents)); + } + + g_output_stream_close (G_OUTPUT_STREAM (output_stream), NULL, (local_error == NULL) ? &local_error : NULL); + + if (tests[i].expected_success) + g_assert_no_error (local_error); + } + + if (tests[i].expected_success) + g_assert_no_error (local_error); + else + g_assert_error (local_error, tests[i].expected_error_domain, tests[i].expected_error_code); + + g_clear_error (&local_error); + g_clear_object (&io_stream); + g_clear_object (&output_stream); + + /* Verify the final state of the directory. */ + enumerator = g_file_enumerate_children (tmpdir, + G_FILE_ATTRIBUTE_STANDARD_NAME, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error); + g_assert_no_error (local_error); + + n_files = 0; + do + { + g_file_enumerator_iterate (enumerator, &info, NULL, NULL, &local_error); + g_assert_no_error (local_error); + + if (info != NULL) + n_files++; + } + while (info != NULL); + + g_clear_object (&enumerator); + + g_assert_cmpuint (n_files, ==, tests[i].expected_n_files); + + check_test_file (source_file, tmpdir, "source", tests[i].expected_source_type, tests[i].expected_source_mode, tests[i].expected_source_contents); + check_test_file (backup_file, tmpdir, "source~", tests[i].expected_backup_type, tests[i].expected_backup_mode, tests[i].expected_backup_contents); + + /* Tidy up. Ignore failure apart from when deleting the directory, which + * should be empty. */ + g_file_delete (source_file, NULL, NULL); + g_file_delete (backup_file, NULL, NULL); + + /* Other files which are occasionally generated by the tests. */ + { + GFile *backup_target_file = g_file_get_child (tmpdir, "source~-target"); + g_file_delete (backup_target_file, NULL, NULL); + g_clear_object (&backup_target_file); + } + { + GFile *backup_target_file = g_file_get_child (tmpdir, "source-target"); + g_file_delete (backup_target_file, NULL, NULL); + g_clear_object (&backup_target_file); + } + + g_file_delete (tmpdir, NULL, &local_error); + g_assert_no_error (local_error); + + g_clear_object (&backup_file); + g_clear_object (&source_file); + g_clear_object (&tmpdir); + } +#else /* if !__linux__ */ + g_test_skip ("File replacement tests can only be run on Linux"); +#endif +} + +static void +on_file_deleted (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *local_error = NULL; + GMainLoop *loop = user_data; + + (void) g_file_delete_finish ((GFile*)object, result, &local_error); + g_assert_no_error (local_error); + + g_main_loop_quit (loop); +} + +static void +test_async_delete (void) +{ + GFile *file; + GFileIOStream *iostream; + GError *local_error = NULL; + GError **error = &local_error; + GMainLoop *loop; + + file = g_file_new_tmp ("g_file_delete_XXXXXX", + &iostream, error); + g_assert_no_error (local_error); + g_object_unref (iostream); + + g_assert_true (g_file_query_exists (file, NULL)); + + loop = g_main_loop_new (NULL, TRUE); + + g_file_delete_async (file, G_PRIORITY_DEFAULT, NULL, on_file_deleted, loop); + + g_main_loop_run (loop); + + g_assert_false (g_file_query_exists (file, NULL)); + + g_main_loop_unref (loop); + g_object_unref (file); +} + +static void +test_copy_preserve_mode (void) +{ +#ifdef G_OS_UNIX + mode_t current_umask = umask (0); + const struct + { + guint32 source_mode; + guint32 expected_destination_mode; + gboolean create_destination_before_copy; + GFileCopyFlags copy_flags; + } + vectors[] = + { + /* Overwriting the destination file should copy the permissions from the + * source file, even if %G_FILE_COPY_ALL_METADATA is set: */ + { 0600, 0600, TRUE, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA }, + { 0600, 0600, TRUE, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS }, + /* The same behaviour should hold if the destination file is not being + * overwritten because it doesn’t already exist: */ + { 0600, 0600, FALSE, G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA }, + { 0600, 0600, FALSE, G_FILE_COPY_NOFOLLOW_SYMLINKS }, + /* Anything with %G_FILE_COPY_TARGET_DEFAULT_PERMS should use the current + * umask for the destination file: */ + { 0600, 0666 & ~current_umask, TRUE, G_FILE_COPY_TARGET_DEFAULT_PERMS | G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA }, + { 0600, 0666 & ~current_umask, TRUE, G_FILE_COPY_TARGET_DEFAULT_PERMS | G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS }, + { 0600, 0666 & ~current_umask, FALSE, G_FILE_COPY_TARGET_DEFAULT_PERMS | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA }, + { 0600, 0666 & ~current_umask, FALSE, G_FILE_COPY_TARGET_DEFAULT_PERMS | G_FILE_COPY_NOFOLLOW_SYMLINKS }, + }; + gsize i; + + /* Reset the umask after querying it above. There’s no way to query it without + * changing it. */ + umask (current_umask); + g_test_message ("Current umask: %u", current_umask); + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + GFile *tmpfile; + GFile *dest_tmpfile; + GFileInfo *dest_info; + GFileIOStream *iostream; + GError *local_error = NULL; + guint32 romode = vectors[i].source_mode; + guint32 dest_mode; + + g_test_message ("Vector %" G_GSIZE_FORMAT, i); + + tmpfile = g_file_new_tmp ("tmp-copy-preserve-modeXXXXXX", + &iostream, &local_error); + g_assert_no_error (local_error); + g_io_stream_close ((GIOStream*)iostream, NULL, &local_error); + g_assert_no_error (local_error); + g_clear_object (&iostream); + + g_file_set_attribute (tmpfile, G_FILE_ATTRIBUTE_UNIX_MODE, G_FILE_ATTRIBUTE_TYPE_UINT32, + &romode, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, &local_error); + g_assert_no_error (local_error); + + dest_tmpfile = g_file_new_tmp ("tmp-copy-preserve-modeXXXXXX", + &iostream, &local_error); + g_assert_no_error (local_error); + g_io_stream_close ((GIOStream*)iostream, NULL, &local_error); + g_assert_no_error (local_error); + g_clear_object (&iostream); + + if (!vectors[i].create_destination_before_copy) + { + g_file_delete (dest_tmpfile, NULL, &local_error); + g_assert_no_error (local_error); + } + + g_file_copy (tmpfile, dest_tmpfile, vectors[i].copy_flags, + NULL, NULL, NULL, &local_error); + g_assert_no_error (local_error); + + dest_info = g_file_query_info (dest_tmpfile, G_FILE_ATTRIBUTE_UNIX_MODE, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, &local_error); + g_assert_no_error (local_error); + + dest_mode = g_file_info_get_attribute_uint32 (dest_info, G_FILE_ATTRIBUTE_UNIX_MODE); + + g_assert_cmpint (dest_mode & ~S_IFMT, ==, vectors[i].expected_destination_mode); + g_assert_cmpint (dest_mode & S_IFMT, ==, S_IFREG); + + (void) g_file_delete (tmpfile, NULL, NULL); + (void) g_file_delete (dest_tmpfile, NULL, NULL); + + g_clear_object (&tmpfile); + g_clear_object (&dest_tmpfile); + g_clear_object (&dest_info); + } +#else /* if !G_OS_UNIX */ + g_test_skip ("File permissions tests can only be run on Unix") +#endif +} + +static gchar * +splice_to_string (GInputStream *stream, + GError **error) +{ + GMemoryOutputStream *buffer = NULL; + char *ret = NULL; + + buffer = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + if (g_output_stream_splice ((GOutputStream*)buffer, stream, 0, NULL, error) < 0) + goto out; + + if (!g_output_stream_write ((GOutputStream*)buffer, "\0", 1, NULL, error)) + goto out; + + if (!g_output_stream_close ((GOutputStream*)buffer, NULL, error)) + goto out; + + ret = g_memory_output_stream_steal_data (buffer); + out: + g_clear_object (&buffer); + return ret; +} + +static gboolean +get_size_from_du (const gchar *path, guint64 *size) +{ + GSubprocess *du; + gboolean ok; + gchar *result; + gchar *endptr; + GError *error = NULL; + gchar *du_path = NULL; + + /* If we can’t find du, don’t try and run the test. */ + du_path = g_find_program_in_path ("du"); + if (du_path == NULL) + return FALSE; + g_free (du_path); + + du = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE, + &error, + "du", "--bytes", "-s", path, NULL); + g_assert_no_error (error); + + result = splice_to_string (g_subprocess_get_stdout_pipe (du), &error); + g_assert_no_error (error); + + *size = g_ascii_strtoll (result, &endptr, 10); + + g_subprocess_wait (du, NULL, &error); + g_assert_no_error (error); + + ok = g_subprocess_get_successful (du); + + g_object_unref (du); + g_free (result); + + return ok; +} + +static void +test_measure (void) +{ + GFile *file; + guint64 size; + guint64 num_bytes; + guint64 num_dirs; + guint64 num_files; + GError *error = NULL; + gboolean ok; + gchar *path; + + path = g_test_build_filename (G_TEST_DIST, "desktop-files", NULL); + file = g_file_new_for_path (path); + + if (!get_size_from_du (path, &size)) + { + g_test_message ("du not found or fail to run, skipping byte measurement"); + size = 0; + } + + ok = g_file_measure_disk_usage (file, + G_FILE_MEASURE_APPARENT_SIZE, + NULL, + NULL, + NULL, + &num_bytes, + &num_dirs, + &num_files, + &error); + g_assert_true (ok); + g_assert_no_error (error); + + if (size > 0) + g_assert_cmpuint (num_bytes, ==, size); + g_assert_cmpuint (num_dirs, ==, 6); + g_assert_cmpuint (num_files, ==, 32); + + g_object_unref (file); + g_free (path); +} + +typedef struct { + guint64 expected_bytes; + guint64 expected_dirs; + guint64 expected_files; + gint progress_count; + guint64 progress_bytes; + guint64 progress_dirs; + guint64 progress_files; +} MeasureData; + +static void +measure_progress (gboolean reporting, + guint64 current_size, + guint64 num_dirs, + guint64 num_files, + gpointer user_data) +{ + MeasureData *data = user_data; + + data->progress_count += 1; + + g_assert_cmpuint (current_size, >=, data->progress_bytes); + g_assert_cmpuint (num_dirs, >=, data->progress_dirs); + g_assert_cmpuint (num_files, >=, data->progress_files); + + data->progress_bytes = current_size; + data->progress_dirs = num_dirs; + data->progress_files = num_files; +} + +static void +measure_done (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + MeasureData *data = user_data; + guint64 num_bytes, num_dirs, num_files; + GError *error = NULL; + gboolean ok; + + ok = g_file_measure_disk_usage_finish (G_FILE (source), res, &num_bytes, &num_dirs, &num_files, &error); + g_assert_true (ok); + g_assert_no_error (error); + + if (data->expected_bytes > 0) + g_assert_cmpuint (data->expected_bytes, ==, num_bytes); + g_assert_cmpuint (data->expected_dirs, ==, num_dirs); + g_assert_cmpuint (data->expected_files, ==, num_files); + + g_assert_cmpuint (data->progress_count, >, 0); + g_assert_cmpuint (num_bytes, >=, data->progress_bytes); + g_assert_cmpuint (num_dirs, >=, data->progress_dirs); + g_assert_cmpuint (num_files, >=, data->progress_files); + + g_free (data); + g_object_unref (source); +} + +static void +test_measure_async (void) +{ + gchar *path; + GFile *file; + MeasureData *data; + + data = g_new (MeasureData, 1); + + data->progress_count = 0; + data->progress_bytes = 0; + data->progress_files = 0; + data->progress_dirs = 0; + + path = g_test_build_filename (G_TEST_DIST, "desktop-files", NULL); + file = g_file_new_for_path (path); + + if (!get_size_from_du (path, &data->expected_bytes)) + { + g_test_message ("du not found or fail to run, skipping byte measurement"); + data->expected_bytes = 0; + } + + g_free (path); + + data->expected_dirs = 6; + data->expected_files = 32; + + g_file_measure_disk_usage_async (file, + G_FILE_MEASURE_APPARENT_SIZE, + 0, NULL, + measure_progress, data, + measure_done, data); +} + +static void +test_load_bytes (void) +{ + gchar filename[] = "g_file_load_bytes_XXXXXX"; + GError *error = NULL; + GBytes *bytes; + GFile *file; + int len; + int fd; + int ret; + + fd = g_mkstemp (filename); + g_assert_cmpint (fd, !=, -1); + len = strlen ("test_load_bytes"); + ret = write (fd, "test_load_bytes", len); + g_assert_cmpint (ret, ==, len); + close (fd); + + file = g_file_new_for_path (filename); + bytes = g_file_load_bytes (file, NULL, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (bytes); + g_assert_cmpint (len, ==, g_bytes_get_size (bytes)); + g_assert_cmpstr ("test_load_bytes", ==, (gchar *)g_bytes_get_data (bytes, NULL)); + + g_file_delete (file, NULL, NULL); + + g_bytes_unref (bytes); + g_object_unref (file); +} + +typedef struct +{ + GMainLoop *main_loop; + GFile *file; + GBytes *bytes; +} LoadBytesAsyncData; + +static void +test_load_bytes_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GFile *file = G_FILE (object); + LoadBytesAsyncData *data = user_data; + GError *error = NULL; + + data->bytes = g_file_load_bytes_finish (file, result, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (data->bytes); + + g_main_loop_quit (data->main_loop); +} + +static void +test_load_bytes_async (void) +{ + LoadBytesAsyncData data = { 0 }; + gchar filename[] = "g_file_load_bytes_XXXXXX"; + int len; + int fd; + int ret; + + fd = g_mkstemp (filename); + g_assert_cmpint (fd, !=, -1); + len = strlen ("test_load_bytes_async"); + ret = write (fd, "test_load_bytes_async", len); + g_assert_cmpint (ret, ==, len); + close (fd); + + data.main_loop = g_main_loop_new (NULL, FALSE); + data.file = g_file_new_for_path (filename); + + g_file_load_bytes_async (data.file, NULL, test_load_bytes_cb, &data); + g_main_loop_run (data.main_loop); + + g_assert_cmpint (len, ==, g_bytes_get_size (data.bytes)); + g_assert_cmpstr ("test_load_bytes_async", ==, (gchar *)g_bytes_get_data (data.bytes, NULL)); + + g_file_delete (data.file, NULL, NULL); + g_object_unref (data.file); + g_bytes_unref (data.bytes); + g_main_loop_unref (data.main_loop); +} + +static void +test_writev_helper (GOutputVector *vectors, + gsize n_vectors, + gboolean use_bytes_written, + const guint8 *expected_contents, + gsize expected_length) +{ + GFile *file; + GFileIOStream *iostream = NULL; + GOutputStream *ostream; + GError *error = NULL; + gsize bytes_written = 0; + gboolean res; + guint8 *contents; + gsize length; + + file = g_file_new_tmp ("g_file_writev_XXXXXX", + &iostream, NULL); + g_assert_nonnull (file); + g_assert_nonnull (iostream); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + + res = g_output_stream_writev_all (ostream, vectors, n_vectors, use_bytes_written ? &bytes_written : NULL, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + if (use_bytes_written) + g_assert_cmpuint (bytes_written, ==, expected_length); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_assert_cmpmem (contents, length, expected_contents, expected_length); + + g_free (contents); + + g_file_delete (file, NULL, NULL); + g_object_unref (file); +} + +/* Test that writev() on local file output streams works on a non-empty vector */ +static void +test_writev (void) +{ + GOutputVector vectors[3]; + const guint8 buffer[] = {1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 1, 2, 3}; + + vectors[0].buffer = buffer; + vectors[0].size = 5; + + vectors[1].buffer = buffer + 5; + vectors[1].size = 12; + + vectors[2].buffer = buffer + 5 + 12; + vectors[2].size = 3; + + test_writev_helper (vectors, G_N_ELEMENTS (vectors), TRUE, buffer, sizeof buffer); +} + +/* Test that writev() on local file output streams works on a non-empty vector without returning bytes_written */ +static void +test_writev_no_bytes_written (void) +{ + GOutputVector vectors[3]; + const guint8 buffer[] = {1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 1, 2, 3}; + + vectors[0].buffer = buffer; + vectors[0].size = 5; + + vectors[1].buffer = buffer + 5; + vectors[1].size = 12; + + vectors[2].buffer = buffer + 5 + 12; + vectors[2].size = 3; + + test_writev_helper (vectors, G_N_ELEMENTS (vectors), FALSE, buffer, sizeof buffer); +} + +/* Test that writev() on local file output streams works on 0 vectors */ +static void +test_writev_no_vectors (void) +{ + test_writev_helper (NULL, 0, TRUE, NULL, 0); +} + +/* Test that writev() on local file output streams works on empty vectors */ +static void +test_writev_empty_vectors (void) +{ + GOutputVector vectors[3]; + + vectors[0].buffer = NULL; + vectors[0].size = 0; + vectors[1].buffer = NULL; + vectors[1].size = 0; + vectors[2].buffer = NULL; + vectors[2].size = 0; + + test_writev_helper (vectors, G_N_ELEMENTS (vectors), TRUE, NULL, 0); +} + +/* Test that writev() fails if the sum of sizes in the vector is too big */ +static void +test_writev_too_big_vectors (void) +{ + GFile *file; + GFileIOStream *iostream = NULL; + GOutputStream *ostream; + GError *error = NULL; + gsize bytes_written = 0; + gboolean res; + guint8 *contents; + gsize length; + GOutputVector vectors[3]; + + vectors[0].buffer = (void*) 1; + vectors[0].size = G_MAXSIZE / 2; + + vectors[1].buffer = (void*) 1; + vectors[1].size = G_MAXSIZE / 2; + + vectors[2].buffer = (void*) 1; + vectors[2].size = G_MAXSIZE / 2; + + file = g_file_new_tmp ("g_file_writev_XXXXXX", + &iostream, NULL); + g_assert_nonnull (file); + g_assert_nonnull (iostream); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + + res = g_output_stream_writev_all (ostream, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpuint (bytes_written, ==, 0); + g_assert_false (res); + g_clear_error (&error); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_assert_cmpmem (contents, length, NULL, 0); + + g_free (contents); + + g_file_delete (file, NULL, NULL); + g_object_unref (file); +} + +typedef struct +{ + gsize bytes_written; + GOutputVector *vectors; + gsize n_vectors; + GError *error; + gboolean done; +} WritevAsyncData; + +static void +test_writev_async_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GOutputStream *ostream = G_OUTPUT_STREAM (object); + WritevAsyncData *data = user_data; + GError *error = NULL; + gsize bytes_written; + gboolean res; + + res = g_output_stream_writev_finish (ostream, result, &bytes_written, &error); + g_assert_true (res); + g_assert_no_error (error); + data->bytes_written += bytes_written; + + /* skip vectors that have been written in full */ + while (data->n_vectors > 0 && bytes_written >= data->vectors[0].size) + { + bytes_written -= data->vectors[0].size; + ++data->vectors; + --data->n_vectors; + } + /* skip partially written vector data */ + if (bytes_written > 0 && data->n_vectors > 0) + { + data->vectors[0].size -= bytes_written; + data->vectors[0].buffer = ((guint8 *) data->vectors[0].buffer) + bytes_written; + } + + if (data->n_vectors > 0) + g_output_stream_writev_async (ostream, data->vectors, data->n_vectors, 0, NULL, test_writev_async_cb, &data); +} + +/* Test that writev_async() on local file output streams works on a non-empty vector */ +static void +test_writev_async (void) +{ + WritevAsyncData data = { 0 }; + GFile *file; + GFileIOStream *iostream = NULL; + GOutputVector vectors[3]; + const guint8 buffer[] = {1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 1, 2, 3}; + GOutputStream *ostream; + GError *error = NULL; + gboolean res; + guint8 *contents; + gsize length; + + vectors[0].buffer = buffer; + vectors[0].size = 5; + + vectors[1].buffer = buffer + 5; + vectors[1].size = 12; + + vectors[2].buffer = buffer + 5 + 12; + vectors[2].size = 3; + + file = g_file_new_tmp ("g_file_writev_XXXXXX", + &iostream, NULL); + g_assert_nonnull (file); + g_assert_nonnull (iostream); + + data.vectors = vectors; + data.n_vectors = G_N_ELEMENTS (vectors); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + + g_output_stream_writev_async (ostream, data.vectors, data.n_vectors, 0, NULL, test_writev_async_cb, &data); + + while (data.n_vectors > 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (data.bytes_written, ==, sizeof buffer); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_assert_cmpmem (contents, length, buffer, sizeof buffer); + + g_free (contents); + + g_file_delete (file, NULL, NULL); + g_object_unref (file); +} + +static void +test_writev_all_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GOutputStream *ostream = G_OUTPUT_STREAM (object); + WritevAsyncData *data = user_data; + + g_output_stream_writev_all_finish (ostream, result, &data->bytes_written, &data->error); + data->done = TRUE; +} + +/* Test that writev_async_all() on local file output streams works on a non-empty vector */ +static void +test_writev_async_all (void) +{ + WritevAsyncData data = { 0 }; + GFile *file; + GFileIOStream *iostream = NULL; + GOutputStream *ostream; + GOutputVector vectors[3]; + const guint8 buffer[] = {1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 1, 2, 3}; + GError *error = NULL; + gboolean res; + guint8 *contents; + gsize length; + + vectors[0].buffer = buffer; + vectors[0].size = 5; + + vectors[1].buffer = buffer + 5; + vectors[1].size = 12; + + vectors[2].buffer = buffer + 5 + 12; + vectors[2].size = 3; + + file = g_file_new_tmp ("g_file_writev_XXXXXX", + &iostream, NULL); + g_assert_nonnull (file); + g_assert_nonnull (iostream); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + + g_output_stream_writev_all_async (ostream, vectors, G_N_ELEMENTS (vectors), 0, NULL, test_writev_all_cb, &data); + + while (!data.done) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (data.bytes_written, ==, sizeof buffer); + g_assert_no_error (data.error); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_assert_cmpmem (contents, length, buffer, sizeof buffer); + + g_free (contents); + + g_file_delete (file, NULL, NULL); + g_object_unref (file); +} + +/* Test that writev_async_all() on local file output streams handles cancellation correctly */ +static void +test_writev_async_all_cancellation (void) +{ + WritevAsyncData data = { 0 }; + GFile *file; + GFileIOStream *iostream = NULL; + GOutputVector vectors[3]; + const guint8 buffer[] = {1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 1, 2, 3}; + GOutputStream *ostream; + GError *error = NULL; + gboolean res; + guint8 *contents; + gsize length; + GCancellable *cancellable; + + vectors[0].buffer = buffer; + vectors[0].size = 5; + + vectors[1].buffer = buffer + 5; + vectors[1].size = 12; + + vectors[2].buffer = buffer + 5 + 12; + vectors[2].size = 3; + + file = g_file_new_tmp ("g_file_writev_XXXXXX", + &iostream, NULL); + g_assert_nonnull (file); + g_assert_nonnull (iostream); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + + cancellable = g_cancellable_new (); + g_cancellable_cancel (cancellable); + + g_output_stream_writev_all_async (ostream, vectors, G_N_ELEMENTS (vectors), 0, cancellable, test_writev_all_cb, &data); + + while (!data.done) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (data.bytes_written, ==, 0); + g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&data.error); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (length, ==, 0); + + g_free (contents); + + g_file_delete (file, NULL, NULL); + g_object_unref (file); + g_object_unref (cancellable); +} + +/* Test that writev_async_all() with empty vectors is handled correctly */ +static void +test_writev_async_all_empty_vectors (void) +{ + WritevAsyncData data = { 0 }; + GFile *file; + GFileIOStream *iostream = NULL; + GOutputVector vectors[3]; + GOutputStream *ostream; + GError *error = NULL; + gboolean res; + guint8 *contents; + gsize length; + + vectors[0].buffer = NULL; + vectors[0].size = 0; + + vectors[1].buffer = NULL; + vectors[1].size = 0; + + vectors[2].buffer = NULL; + vectors[2].size = 0; + + file = g_file_new_tmp ("g_file_writev_XXXXXX", + &iostream, NULL); + g_assert_nonnull (file); + g_assert_nonnull (iostream); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + + g_output_stream_writev_all_async (ostream, vectors, G_N_ELEMENTS (vectors), 0, NULL, test_writev_all_cb, &data); + + while (!data.done) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (data.bytes_written, ==, 0); + g_assert_no_error (data.error); + g_clear_error (&data.error); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (length, ==, 0); + + g_free (contents); + + g_file_delete (file, NULL, NULL); + g_object_unref (file); +} + +/* Test that writev_async_all() with no vectors is handled correctly */ +static void +test_writev_async_all_no_vectors (void) +{ + WritevAsyncData data = { 0 }; + GFile *file; + GFileIOStream *iostream = NULL; + GOutputStream *ostream; + GError *error = NULL; + gboolean res; + guint8 *contents; + gsize length; + + file = g_file_new_tmp ("g_file_writev_XXXXXX", + &iostream, NULL); + g_assert_nonnull (file); + g_assert_nonnull (iostream); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + + g_output_stream_writev_all_async (ostream, NULL, 0, 0, NULL, test_writev_all_cb, &data); + + while (!data.done) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (data.bytes_written, ==, 0); + g_assert_no_error (data.error); + g_clear_error (&data.error); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (length, ==, 0); + + g_free (contents); + + g_file_delete (file, NULL, NULL); + g_object_unref (file); +} + +/* Test that writev_async_all() with too big vectors is handled correctly */ +static void +test_writev_async_all_too_big_vectors (void) +{ + WritevAsyncData data = { 0 }; + GFile *file; + GFileIOStream *iostream = NULL; + GOutputVector vectors[3]; + GOutputStream *ostream; + GError *error = NULL; + gboolean res; + guint8 *contents; + gsize length; + + vectors[0].buffer = (void*) 1; + vectors[0].size = G_MAXSIZE / 2; + + vectors[1].buffer = (void*) 1; + vectors[1].size = G_MAXSIZE / 2; + + vectors[2].buffer = (void*) 1; + vectors[2].size = G_MAXSIZE / 2; + + file = g_file_new_tmp ("g_file_writev_XXXXXX", + &iostream, NULL); + g_assert_nonnull (file); + g_assert_nonnull (iostream); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + + g_output_stream_writev_all_async (ostream, vectors, G_N_ELEMENTS (vectors), 0, NULL, test_writev_all_cb, &data); + + while (!data.done) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (data.bytes_written, ==, 0); + g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_clear_error (&data.error); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (length, ==, 0); + + g_free (contents); + + g_file_delete (file, NULL, NULL); + g_object_unref (file); +} + +static void +test_build_attribute_list_for_copy (void) +{ + GFile *tmpfile; + GFileIOStream *iostream; + GError *error = NULL; + const GFileCopyFlags test_flags[] = + { + G_FILE_COPY_NONE, + G_FILE_COPY_TARGET_DEFAULT_PERMS, + G_FILE_COPY_ALL_METADATA, + G_FILE_COPY_ALL_METADATA | G_FILE_COPY_TARGET_DEFAULT_PERMS, + }; + gsize i; + char *attrs; + gchar *attrs_with_commas; + + tmpfile = g_file_new_tmp ("tmp-build-attribute-list-for-copyXXXXXX", + &iostream, &error); + g_assert_no_error (error); + g_io_stream_close ((GIOStream*)iostream, NULL, &error); + g_assert_no_error (error); + g_clear_object (&iostream); + + for (i = 0; i < G_N_ELEMENTS (test_flags); i++) + { + GFileCopyFlags flags = test_flags[i]; + + attrs = g_file_build_attribute_list_for_copy (tmpfile, flags, NULL, &error); + g_test_message ("Attributes for copy: %s", attrs); + g_assert_no_error (error); + g_assert_nonnull (attrs); + attrs_with_commas = g_strconcat (",", attrs, ",", NULL); + g_free (attrs); + + /* See g_local_file_class_init for reference. */ + if (flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) + g_assert_null (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_UNIX_MODE ",")); + else + g_assert_nonnull (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_UNIX_MODE ",")); +#ifdef G_OS_UNIX + if (flags & G_FILE_COPY_ALL_METADATA) + { + g_assert_nonnull (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_UNIX_UID ",")); + g_assert_nonnull (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_UNIX_GID ",")); + } + else + { + g_assert_null (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_UNIX_UID ",")); + g_assert_null (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_UNIX_GID ",")); + } +#endif +#ifdef HAVE_UTIMES + g_assert_nonnull (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_TIME_MODIFIED ",")); + g_assert_nonnull (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC ",")); + if (flags & G_FILE_COPY_ALL_METADATA) + { + g_assert_nonnull (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_TIME_ACCESS ",")); + g_assert_nonnull (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_TIME_ACCESS_USEC ",")); + } + else + { + g_assert_null (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_TIME_ACCESS ",")); + g_assert_null (g_strstr_len (attrs_with_commas, -1, "," G_FILE_ATTRIBUTE_TIME_ACCESS_USEC ",")); + } +#endif + g_free (attrs_with_commas); + } + + (void) g_file_delete (tmpfile, NULL, NULL); + g_clear_object (&tmpfile); +} + +typedef struct +{ + GError *error; + gboolean done; + gboolean res; +} MoveAsyncData; + +static void +test_move_async_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GFile *file = G_FILE (object); + MoveAsyncData *data = user_data; + GError *error = NULL; + + data->res = g_file_move_finish (file, result, &error); + data->error = error; + data->done = TRUE; +} + +typedef struct +{ + goffset total_num_bytes; +} MoveAsyncProgressData; + +static void +test_move_async_progress_cb (goffset current_num_bytes, + goffset total_num_bytes, + gpointer user_data) +{ + MoveAsyncProgressData *data = user_data; + data->total_num_bytes = total_num_bytes; +} + +/* Test that move_async() moves the file correctly */ +static void +test_move_async (void) +{ + MoveAsyncData data = { 0 }; + MoveAsyncProgressData progress_data = { 0 }; + GFile *source; + GFileIOStream *iostream; + GOutputStream *ostream; + GFile *destination; + gchar *destination_path; + GError *error = NULL; + gboolean res; + const guint8 buffer[] = {1, 2, 3, 4, 5}; + + source = g_file_new_tmp ("g_file_move_XXXXXX", &iostream, NULL); + + destination_path = g_build_path (G_DIR_SEPARATOR_S, g_get_tmp_dir (), "g_file_move_target", NULL); + destination = g_file_new_for_path (destination_path); + + g_assert_nonnull (source); + g_assert_nonnull (iostream); + + res = g_file_query_exists (source, NULL); + g_assert_true (res); + res = g_file_query_exists (destination, NULL); + g_assert_false (res); + + // Write a known amount of bytes to the file, so we can test the progress callback against it + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + g_output_stream_write (ostream, buffer, sizeof (buffer), NULL, &error); + g_assert_no_error (error); + + g_file_move_async (source, + destination, + G_FILE_COPY_NONE, + 0, + NULL, + test_move_async_progress_cb, + &progress_data, + test_move_async_cb, + &data); + + while (!data.done) + g_main_context_iteration (NULL, TRUE); + + g_assert_no_error (data.error); + g_assert_true (data.res); + g_assert_cmpuint (progress_data.total_num_bytes, ==, sizeof (buffer)); + + res = g_file_query_exists (source, NULL); + g_assert_false (res); + res = g_file_query_exists (destination, NULL); + g_assert_true (res); + + res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_object_unref (iostream); + + res = g_file_delete (destination, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_object_unref (source); + g_object_unref (destination); + + g_free (destination_path); +} + +int +main (int argc, char *argv[]) +{ + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/file/basic", test_basic); + g_test_add_func ("/file/build-filename", test_build_filename); + g_test_add_func ("/file/parent", test_parent); + g_test_add_func ("/file/child", test_child); + g_test_add_func ("/file/empty-path", test_empty_path); + g_test_add_func ("/file/type", test_type); + g_test_add_func ("/file/parse-name", test_parse_name); + g_test_add_data_func ("/file/async-create-delete/0", GINT_TO_POINTER (0), test_create_delete); + g_test_add_data_func ("/file/async-create-delete/1", GINT_TO_POINTER (1), test_create_delete); + g_test_add_data_func ("/file/async-create-delete/10", GINT_TO_POINTER (10), test_create_delete); + g_test_add_data_func ("/file/async-create-delete/25", GINT_TO_POINTER (25), test_create_delete); + g_test_add_data_func ("/file/async-create-delete/4096", GINT_TO_POINTER (4096), test_create_delete); + g_test_add_func ("/file/replace-load", test_replace_load); + g_test_add_func ("/file/replace-cancel", test_replace_cancel); + g_test_add_func ("/file/replace-symlink", test_replace_symlink); + g_test_add_func ("/file/replace-symlink/using-etag", test_replace_symlink_using_etag); + g_test_add_data_func ("/file/replace/write-only", GUINT_TO_POINTER (FALSE), test_replace); + g_test_add_data_func ("/file/replace/read-write", GUINT_TO_POINTER (TRUE), test_replace); + g_test_add_func ("/file/async-delete", test_async_delete); + g_test_add_func ("/file/copy-preserve-mode", test_copy_preserve_mode); + g_test_add_func ("/file/measure", test_measure); + g_test_add_func ("/file/measure-async", test_measure_async); + g_test_add_func ("/file/load-bytes", test_load_bytes); + g_test_add_func ("/file/load-bytes-async", test_load_bytes_async); + g_test_add_func ("/file/writev", test_writev); + g_test_add_func ("/file/writev/no-bytes-written", test_writev_no_bytes_written); + g_test_add_func ("/file/writev/no-vectors", test_writev_no_vectors); + g_test_add_func ("/file/writev/empty-vectors", test_writev_empty_vectors); + g_test_add_func ("/file/writev/too-big-vectors", test_writev_too_big_vectors); + g_test_add_func ("/file/writev/async", test_writev_async); + g_test_add_func ("/file/writev/async_all", test_writev_async_all); + g_test_add_func ("/file/writev/async_all-empty-vectors", test_writev_async_all_empty_vectors); + g_test_add_func ("/file/writev/async_all-no-vectors", test_writev_async_all_no_vectors); + g_test_add_func ("/file/writev/async_all-to-big-vectors", test_writev_async_all_too_big_vectors); + g_test_add_func ("/file/writev/async_all-cancellation", test_writev_async_all_cancellation); + g_test_add_func ("/file/build-attribute-list-for-copy", test_build_attribute_list_for_copy); + g_test_add_func ("/file/move_async", test_move_async); + + return g_test_run (); +} diff --git a/gio/tests/fileattributematcher.c b/gio/tests/fileattributematcher.c new file mode 100644 index 0000000..553d57b --- /dev/null +++ b/gio/tests/fileattributematcher.c @@ -0,0 +1,162 @@ +#include + +static void +test_exact (void) +{ + const char *exact_matches[] = { + "*", + "a::*", + "a::*,b::*", + "a::a,a::b", + "a::a,a::b,b::*" + }; + + GFileAttributeMatcher *matcher; + char *s; + guint i; + + for (i = 0; i < G_N_ELEMENTS (exact_matches); i++) + { + matcher = g_file_attribute_matcher_new (exact_matches[i]); + s = g_file_attribute_matcher_to_string (matcher); + g_assert_cmpstr (exact_matches[i], ==, s); + g_free (s); + g_file_attribute_matcher_unref (matcher); + } +} + +static void +test_equality (void) +{ + struct { + const char *expected; + const char *actual; + } equals[] = { + /* star makes everything else go away */ + { "*", "*,*" }, + { "*", "*,a::*" }, + { "*", "*,a::b" }, + { "*", "a::*,*" }, + { "*", "a::b,*" }, + { "*", "a::b,*,a::*" }, + /* a::* makes a:: go away */ + { "a::*", "a::*,a::*" }, + { "a::*", "a::*,a::b" }, + { "a::*", "a::b,a::*" }, + { "a::*", "a::b,a::*,a::c" }, + /* a::b does not allow duplicates */ + { "a::b", "a::b,a::b" }, + { "a::b,a::c", "a::b,a::c,a::b" }, + /* stuff gets ordered in registration order */ + { "a::b,a::c", "a::c,a::b" }, + { "a::*,b::*", "b::*,a::*" }, + }; + + GFileAttributeMatcher *matcher; + char *s; + guint i; + + for (i = 0; i < G_N_ELEMENTS (equals); i++) + { + matcher = g_file_attribute_matcher_new (equals[i].actual); + s = g_file_attribute_matcher_to_string (matcher); + g_assert_cmpstr (equals[i].expected, ==, s); + g_free (s); + g_file_attribute_matcher_unref (matcher); + } +} + +static void +test_subtract (void) +{ + struct { + const char *attributes; + const char *subtract; + const char *result; + } subtractions[] = { + /* * subtracts everything */ + { "*", "*", NULL }, + { "a::*", "*", NULL }, + { "a::b", "*", NULL }, + { "a::b,a::c", "*", NULL }, + { "a::*,b::*", "*", NULL }, + { "a::*,b::c", "*", NULL }, + { "a::b,b::*", "*", NULL }, + { "a::b,b::c", "*", NULL }, + { "a::b,a::c,b::*", "*", NULL }, + { "a::b,a::c,b::c", "*", NULL }, + /* a::* subtracts all a's */ + { "*", "a::*", "*" }, + { "a::*", "a::*", NULL }, + { "a::b", "a::*", NULL }, + { "a::b,a::c", "a::*", NULL }, + { "a::*,b::*", "a::*", "b::*" }, + { "a::*,b::c", "a::*", "b::c" }, + { "a::b,b::*", "a::*", "b::*" }, + { "a::b,b::c", "a::*", "b::c" }, + { "a::b,a::c,b::*", "a::*", "b::*" }, + { "a::b,a::c,b::c", "a::*", "b::c" }, + /* a::b subtracts exactly that */ + { "*", "a::b", "*" }, + { "a::*", "a::b", "a::*" }, + { "a::b", "a::b", NULL }, + { "a::b,a::c", "a::b", "a::c" }, + { "a::*,b::*", "a::b", "a::*,b::*" }, + { "a::*,b::c", "a::b", "a::*,b::c" }, + { "a::b,b::*", "a::b", "b::*" }, + { "a::b,b::c", "a::b", "b::c" }, + { "a::b,a::c,b::*", "a::b", "a::c,b::*" }, + { "a::b,a::c,b::c", "a::b", "a::c,b::c" }, + /* a::b,b::* subtracts both of those */ + { "*", "a::b,b::*", "*" }, + { "a::*", "a::b,b::*", "a::*" }, + { "a::b", "a::b,b::*", NULL }, + { "a::b,a::c", "a::b,b::*", "a::c" }, + { "a::*,b::*", "a::b,b::*", "a::*" }, + { "a::*,b::c", "a::b,b::*", "a::*" }, + { "a::b,b::*", "a::b,b::*", NULL }, + { "a::b,b::c", "a::b,b::*", NULL }, + { "a::b,a::c,b::*", "a::b,b::*", "a::c" }, + { "a::b,a::c,b::c", "a::b,b::*", "a::c" }, + /* a::b,b::c should work, too */ + { "*", "a::b,b::c", "*" }, + { "a::*", "a::b,b::c", "a::*" }, + { "a::b", "a::b,b::c", NULL }, + { "a::b,a::c", "a::b,b::c", "a::c" }, + { "a::*,b::*", "a::b,b::c", "a::*,b::*" }, + { "a::*,b::c", "a::b,b::c", "a::*" }, + { "a::b,b::*", "a::b,b::c", "b::*" }, + { "a::b,b::c", "a::b,b::c", NULL }, + { "a::b,a::c,b::*", "a::b,b::c", "a::c,b::*" }, + { "a::b,a::c,b::c", "a::b,b::c", "a::c" }, + }; + + GFileAttributeMatcher *matcher, *subtract, *result; + char *s; + guint i; + + for (i = 0; i < G_N_ELEMENTS (subtractions); i++) + { + matcher = g_file_attribute_matcher_new (subtractions[i].attributes); + subtract = g_file_attribute_matcher_new (subtractions[i].subtract); + result = g_file_attribute_matcher_subtract (matcher, subtract); + s = g_file_attribute_matcher_to_string (result); + g_assert_cmpstr (subtractions[i].result, ==, s); + g_free (s); + g_file_attribute_matcher_unref (matcher); + g_file_attribute_matcher_unref (subtract); + g_file_attribute_matcher_unref (result); + } +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/fileattributematcher/exact", test_exact); + g_test_add_func ("/fileattributematcher/equality", test_equality); + g_test_add_func ("/fileattributematcher/subtract", test_subtract); + + return g_test_run (); +} diff --git a/gio/tests/filter-cat.c b/gio/tests/filter-cat.c new file mode 100644 index 0000000..0bc7137 --- /dev/null +++ b/gio/tests/filter-cat.c @@ -0,0 +1,269 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#include + +#include +#include +#include + +#include +#include + +#ifdef G_OS_UNIX +#include +#endif + +#ifdef G_OS_WIN32 +#include +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#endif + +static gchar **locations = NULL; +static char *from_charset = NULL; +static char *to_charset = NULL; +static gboolean decompress = FALSE; +static gboolean compress = FALSE; +static gboolean gzip = FALSE; +static gboolean fallback = FALSE; + +static GOptionEntry entries[] = { + {"decompress", 0, 0, G_OPTION_ARG_NONE, &decompress, "decompress", NULL}, + {"compress", 0, 0, G_OPTION_ARG_NONE, &compress, "compress", NULL}, + {"gzip", 0, 0, G_OPTION_ARG_NONE, &gzip, "use gzip format", NULL}, + {"from-charset", 0, 0, G_OPTION_ARG_STRING, &from_charset, "from charset", NULL}, + {"to-charset", 0, 0, G_OPTION_ARG_STRING, &to_charset, "to charset", NULL}, + {"fallback", 0, 0, G_OPTION_ARG_NONE, &fallback, "use fallback", NULL}, + {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &locations, "locations", NULL}, + G_OPTION_ENTRY_NULL +}; + +static void +decompressor_file_info_notify_cb (GZlibDecompressor *decompressor, + GParamSpec *pspec, + gpointer data) +{ + GFileInfo *file_info; + const gchar *filename; + + file_info = g_zlib_decompressor_get_file_info (decompressor); + if (file_info == NULL) + return; + + filename = g_file_info_get_name (file_info); + if (filename) + g_printerr ("Decompressor filename: %s\n", filename); +} + +static void +cat (GFile * file) +{ + GInputStream *in; + char buffer[1024 * 8 + 1]; + char *p; + gssize res; + gboolean close_res; + GError *error; + GConverter *conv; + GCharsetConverter *cconv = NULL; + + error = NULL; + in = (GInputStream *) g_file_read (file, NULL, &error); + if (in == NULL) + { + /* Translators: the first %s is the program name, the second one */ + /* is the URI of the file, the third is the error message. */ + g_printerr ("%s: %s: error opening file: %s\n", + g_get_prgname (), g_file_get_uri (file), error->message); + g_error_free (error); + return; + } + + if (decompress) + { + GInputStream *old; + conv = (GConverter *)g_zlib_decompressor_new (gzip?G_ZLIB_COMPRESSOR_FORMAT_GZIP:G_ZLIB_COMPRESSOR_FORMAT_ZLIB); + old = in; + in = (GInputStream *) g_converter_input_stream_new (in, conv); + g_signal_connect (conv, "notify::file-info", G_CALLBACK (decompressor_file_info_notify_cb), NULL); + g_object_unref (conv); + g_object_unref (old); + } + + if (from_charset && to_charset) + { + cconv = g_charset_converter_new (to_charset, from_charset, &error); + conv = (GConverter *)cconv; + if (conv) + { + GInputStream *old; + + g_charset_converter_set_use_fallback (cconv, fallback); + + old = in; + in = (GInputStream *) g_converter_input_stream_new (in, conv); + g_object_unref (conv); + g_object_unref (old); + } + else + { + g_printerr ("%s: Can't convert between charsets: %s\n", + g_get_prgname (), error->message); + } + } + + if (compress) + { + GInputStream *old; + GFileInfo *in_file_info; + + in_file_info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_TIME_MODIFIED, + G_FILE_QUERY_INFO_NONE, + NULL, + &error); + if (in_file_info == NULL) + { + g_printerr ("%s: %s: error reading file info: %s\n", + g_get_prgname (), g_file_get_uri (file), error->message); + g_error_free (error); + return; + } + + conv = (GConverter *)g_zlib_compressor_new(gzip?G_ZLIB_COMPRESSOR_FORMAT_GZIP:G_ZLIB_COMPRESSOR_FORMAT_ZLIB, -1); + g_zlib_compressor_set_file_info (G_ZLIB_COMPRESSOR (conv), in_file_info); + old = in; + in = (GInputStream *) g_converter_input_stream_new (in, conv); + g_object_unref (conv); + g_object_unref (old); + g_object_unref (in_file_info); + } + + while (1) + { + res = + g_input_stream_read (in, buffer, sizeof (buffer) - 1, NULL, &error); + if (res > 0) + { + gssize written; + + p = buffer; + while (res > 0) + { + written = write (STDOUT_FILENO, p, res); + + if (written == -1 && errno != EINTR) + { + /* Translators: the first %s is the program name, the */ + /* second one is the URI of the file. */ + g_printerr ("%s: %s, error writing to stdout", + g_get_prgname (), g_file_get_uri (file)); + goto out; + } + res -= written; + p += written; + } + } + else if (res < 0) + { + g_printerr ("%s: %s: error reading: %s\n", + g_get_prgname (), g_file_get_uri (file), + error->message); + g_error_free (error); + error = NULL; + break; + } + else if (res == 0) + break; + } + + out: + + close_res = g_input_stream_close (in, NULL, &error); + if (!close_res) + { + g_printerr ("%s: %s:error closing: %s\n", + g_get_prgname (), g_file_get_uri (file), error->message); + g_error_free (error); + } + + if (cconv != NULL && fallback) + { + guint num = g_charset_converter_get_num_fallbacks (cconv); + if (num > 0) + g_printerr ("Number of fallback errors: %u\n", num); + } +} + +int +main (int argc, char *argv[]) +{ + GError *error = NULL; + GOptionContext *context = NULL; + GFile *file; + int i; + + context = + g_option_context_new ("LOCATION... - concatenate LOCATIONS " + "to standard output."); + + g_option_context_set_summary (context, "filter files"); + + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + g_option_context_parse (context, &argc, &argv, &error); + + g_option_context_free (context); + + if (error != NULL) + { + g_printerr ("Error parsing commandline options: %s\n", error->message); + g_printerr ("\n"); + g_printerr ("Try \"%s --help\" for more information.", + g_get_prgname ()); + g_printerr ("\n"); + g_error_free(error); + return 1; + } + + if (!locations) + { + g_printerr ("%s: missing locations", g_get_prgname ()); + g_printerr ("\n"); + g_printerr ("Try \"%s --help\" for more information.", + g_get_prgname ()); + g_printerr ("\n"); + return 1; + } + + i = 0; + + do + { + file = g_file_new_for_commandline_arg (locations[i]); + cat (file); + g_object_unref (file); + } + while (locations[++i] != NULL); + + return 0; +} diff --git a/gio/tests/filter-streams.c b/gio/tests/filter-streams.c new file mode 100644 index 0000000..1f94dc2 --- /dev/null +++ b/gio/tests/filter-streams.c @@ -0,0 +1,391 @@ +/* + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Author: Ryan Lortie + */ + +#include +#include +#include + +/* GFilterInputStream and GFilterOutputStream are abstract, so define + * minimal subclasses for testing. (This used to use + * GBufferedInputStream and GBufferedOutputStream, but those have + * their own test program, and they override some methods, meaning the + * core filter stream functionality wasn't getting fully tested.) + */ + +GType test_filter_input_stream_get_type (void); +GType test_filter_output_stream_get_type (void); + +#define TEST_TYPE_FILTER_INPUT_STREAM (test_filter_input_stream_get_type ()) +#define TEST_FILTER_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_FILTER_INPUT_STREAM, TestFilterInputStream)) +#define TEST_TYPE_FILTER_OUTPUT_STREAM (test_filter_output_stream_get_type ()) +#define TEST_FILTER_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_FILTER_OUTPUT_STREAM, TestFilterOutputStream)) + +typedef GFilterInputStream TestFilterInputStream; +typedef GFilterInputStreamClass TestFilterInputStreamClass; +typedef GFilterOutputStream TestFilterOutputStream; +typedef GFilterOutputStreamClass TestFilterOutputStreamClass; + +G_DEFINE_TYPE (TestFilterInputStream, test_filter_input_stream, G_TYPE_FILTER_INPUT_STREAM) +G_DEFINE_TYPE (TestFilterOutputStream, test_filter_output_stream, G_TYPE_FILTER_OUTPUT_STREAM) + +static void +test_filter_input_stream_init (TestFilterInputStream *stream) +{ +} + +static void +test_filter_input_stream_class_init (TestFilterInputStreamClass *klass) +{ +} + +static void +test_filter_output_stream_init (TestFilterOutputStream *stream) +{ +} + +static void +test_filter_output_stream_class_init (TestFilterOutputStreamClass *klass) +{ +} + +/* Now the tests */ + +static void +test_input_filter (void) +{ + GInputStream *base, *f1, *f2, *s; + gboolean close_base; + gchar buf[1024]; + GError *error = NULL; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=568394"); + base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL); + f1 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM, + "base-stream", base, + "close-base-stream", FALSE, + NULL); + f2 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM, + "base-stream", base, + NULL); + + g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base); + g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base); + + g_assert (!g_input_stream_is_closed (base)); + g_assert (!g_input_stream_is_closed (f1)); + g_assert (!g_input_stream_is_closed (f2)); + + g_object_get (f1, + "close-base-stream", &close_base, + "base-stream", &s, + NULL); + g_assert (!close_base); + g_assert (s == base); + g_object_unref (s); + + g_object_unref (f1); + + g_assert (!g_input_stream_is_closed (base)); + g_assert (!g_input_stream_is_closed (f2)); + + g_input_stream_skip (f2, 3, NULL, &error); + g_assert_no_error (error); + + memset (buf, 0, 1024); + g_input_stream_read_all (f2, buf, 1024, NULL, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (buf, ==, "defghijk"); + + g_object_unref (f2); + + g_assert (g_input_stream_is_closed (base)); + + g_object_unref (base); +} + +static void +test_output_filter (void) +{ + GOutputStream *base, *f1, *f2; + + base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + f1 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM, + "base-stream", base, + "close-base-stream", FALSE, + NULL); + f2 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM, + "base-stream", base, + NULL); + + g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base); + g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base); + + g_assert (!g_output_stream_is_closed (base)); + g_assert (!g_output_stream_is_closed (f1)); + g_assert (!g_output_stream_is_closed (f2)); + + g_object_unref (f1); + + g_assert (!g_output_stream_is_closed (base)); + g_assert (!g_output_stream_is_closed (f2)); + + g_object_unref (f2); + + g_assert (g_output_stream_is_closed (base)); + + g_object_unref (base); +} + +gpointer expected_obj; +gpointer expected_data; +gboolean callback_happened; +GMainLoop *loop; + +static void +return_result_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GAsyncResult **ret = user_data; + + *ret = g_object_ref (result); + g_main_loop_quit (loop); +} + +static void +in_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + g_assert (object == expected_obj); + g_assert (user_data == expected_data); + g_assert (callback_happened == FALSE); + + g_input_stream_close_finish (expected_obj, result, &error); + g_assert (error == NULL); + + callback_happened = TRUE; + g_main_loop_quit (loop); +} + +static void +test_input_async (void) +{ + GInputStream *base, *f1, *f2; + char buf[20]; + GAsyncResult *result = NULL; + GError *error = NULL; + + loop = g_main_loop_new (NULL, FALSE); + + base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyz", -1, NULL); + f1 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM, + "base-stream", base, + "close-base-stream", FALSE, + NULL); + f2 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM, + "base-stream", base, + NULL); + + g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base); + g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base); + + + memset (buf, 0, sizeof (buf)); + g_input_stream_read_async (f1, buf, 10, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + g_main_loop_run (loop); + g_assert_cmpint (g_input_stream_read_finish (f1, result, &error), ==, 10); + g_assert_cmpstr (buf, ==, "abcdefghij"); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 10); + + g_input_stream_skip_async (f2, 10, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + g_main_loop_run (loop); + g_assert_cmpint (g_input_stream_skip_finish (f2, result, &error), ==, 10); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 20); + + memset (buf, 0, sizeof (buf)); + g_input_stream_read_async (f1, buf, 10, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + g_main_loop_run (loop); + g_assert_cmpint (g_input_stream_read_finish (f1, result, &error), ==, 6); + g_assert_cmpstr (buf, ==, "uvwxyz"); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 26); + + + g_assert (!g_input_stream_is_closed (base)); + g_assert (!g_input_stream_is_closed (f1)); + g_assert (!g_input_stream_is_closed (f2)); + + expected_obj = f1; + expected_data = g_malloc (20); + callback_happened = FALSE; + g_input_stream_close_async (f1, 0, NULL, in_cb, expected_data); + + g_assert (callback_happened == FALSE); + g_main_loop_run (loop); + g_assert (callback_happened == TRUE); + + g_assert (!g_input_stream_is_closed (base)); + g_assert (!g_input_stream_is_closed (f2)); + g_free (expected_data); + g_object_unref (f1); + g_assert (!g_input_stream_is_closed (base)); + g_assert (!g_input_stream_is_closed (f2)); + + expected_obj = f2; + expected_data = g_malloc (20); + callback_happened = FALSE; + g_input_stream_close_async (f2, 0, NULL, in_cb, expected_data); + + g_assert (callback_happened == FALSE); + g_main_loop_run (loop); + g_assert (callback_happened == TRUE); + + g_assert (g_input_stream_is_closed (base)); + g_assert (g_input_stream_is_closed (f2)); + g_free (expected_data); + g_object_unref (f2); + + g_assert (g_input_stream_is_closed (base)); + g_object_unref (base); + g_main_loop_unref (loop); +} + +static void +out_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + g_assert (object == expected_obj); + g_assert (user_data == expected_data); + g_assert (callback_happened == FALSE); + + g_output_stream_close_finish (expected_obj, result, &error); + g_assert (error == NULL); + + callback_happened = TRUE; + g_main_loop_quit (loop); +} + +static void +test_output_async (void) +{ + GOutputStream *base, *f1, *f2; + GAsyncResult *result = NULL; + GError *error = NULL; + + loop = g_main_loop_new (NULL, FALSE); + + base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + f1 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM, + "base-stream", base, + "close-base-stream", FALSE, + NULL); + f2 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM, + "base-stream", base, + NULL); + + g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base); + g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base); + + + g_output_stream_write_async (f1, "abcdefghijklm", 13, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + g_main_loop_run (loop); + g_assert_cmpint (g_output_stream_write_finish (f1, result, &error), ==, 13); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 13); + + g_output_stream_write_async (f2, "nopqrstuvwxyz", 13, G_PRIORITY_DEFAULT, + NULL, return_result_cb, &result); + g_main_loop_run (loop); + g_assert_cmpint (g_output_stream_write_finish (f2, result, &error), ==, 13); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 26); + + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 26); + g_output_stream_write (base, "\0", 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnopqrstuvwxyz"); + + + g_assert (!g_output_stream_is_closed (base)); + g_assert (!g_output_stream_is_closed (f1)); + g_assert (!g_output_stream_is_closed (f2)); + + expected_obj = f1; + expected_data = g_malloc (20); + callback_happened = FALSE; + g_output_stream_close_async (f1, 0, NULL, out_cb, expected_data); + + g_assert (callback_happened == FALSE); + g_main_loop_run (loop); + g_assert (callback_happened == TRUE); + + g_assert (!g_output_stream_is_closed (base)); + g_assert (!g_output_stream_is_closed (f2)); + g_free (expected_data); + g_object_unref (f1); + g_assert (!g_output_stream_is_closed (base)); + g_assert (!g_output_stream_is_closed (f2)); + + expected_obj = f2; + expected_data = g_malloc (20); + callback_happened = FALSE; + g_output_stream_close_async (f2, 0, NULL, out_cb, expected_data); + + g_assert (callback_happened == FALSE); + g_main_loop_run (loop); + g_assert (callback_happened == TRUE); + + g_assert (g_output_stream_is_closed (base)); + g_assert (g_output_stream_is_closed (f2)); + g_free (expected_data); + g_object_unref (f2); + + g_assert (g_output_stream_is_closed (base)); + g_object_unref (base); + g_main_loop_unref (loop); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/filter-stream/input", test_input_filter); + g_test_add_func ("/filter-stream/output", test_output_filter); + g_test_add_func ("/filter-stream/async-input", test_input_async); + g_test_add_func ("/filter-stream/async-output", test_output_async); + + return g_test_run(); +} diff --git a/gio/tests/g-file-info-filesystem-readonly.c b/gio/tests/g-file-info-filesystem-readonly.c new file mode 100644 index 0000000..ddf99da --- /dev/null +++ b/gio/tests/g-file-info-filesystem-readonly.c @@ -0,0 +1,273 @@ +/* Testcase for bug in GIO function g_file_query_filesystem_info() + * Author: Nelson Benítez León + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include +#include + +static gboolean +run (GError **error, + const gchar *argv0, + ...) +{ + GPtrArray *args; + const gchar *arg; + va_list ap; + GSubprocess *subprocess; + gchar *command_line = NULL; + gboolean success; + + args = g_ptr_array_new (); + + va_start (ap, argv0); + g_ptr_array_add (args, (gchar *) argv0); + while ((arg = va_arg (ap, const gchar *))) + g_ptr_array_add (args, (gchar *) arg); + g_ptr_array_add (args, NULL); + va_end (ap); + + command_line = g_strjoinv (" ", (gchar **) args->pdata); + g_test_message ("Running command `%s`", command_line); + g_free (command_line); + + subprocess = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error); + g_ptr_array_free (args, TRUE); + + if (subprocess == NULL) + return FALSE; + + success = g_subprocess_wait_check (subprocess, NULL, error); + g_object_unref (subprocess); + + return success; +} + +static void +assert_remove (const gchar *file) +{ + if (g_remove (file) != 0) + g_error ("failed to remove %s: %s", file, g_strerror (errno)); +} + +static gboolean +fuse_module_loaded (void) +{ + char *contents = NULL; + gboolean ret; + + if (!g_file_get_contents ("/proc/modules", &contents, NULL, NULL) || + contents == NULL) + { + g_free (contents); + return FALSE; + } + + ret = (strstr (contents, "\nfuse ") != NULL); + g_free (contents); + return ret; +} + +static void +test_filesystem_readonly (gconstpointer with_mount_monitor) +{ + GFileInfo *file_info; + GFile *mounted_file; + GUnixMountMonitor *mount_monitor = NULL; + gchar *bindfs, *fusermount; + gchar *curdir, *dir_to_mount, *dir_mountpoint; + gchar *file_in_mount, *file_in_mountpoint; + GError *error = NULL; + + /* installed by package 'bindfs' in Fedora */ + bindfs = g_find_program_in_path ("bindfs"); + + /* installed by package 'fuse' in Fedora */ + fusermount = g_find_program_in_path ("fusermount"); + + if (bindfs == NULL || fusermount == NULL) + { + /* We need these because "mount --bind" requires root privileges */ + g_test_skip ("'bindfs' and 'fusermount' commands are needed to run this test"); + g_free (fusermount); + g_free (bindfs); + return; + } + + /* If the fuse module is loaded but there's no /dev/fuse, then we're + * we're probably in a rootless container and won't be able to + * use bindfs to run our tests */ + if (fuse_module_loaded () && + !g_file_test ("/dev/fuse", G_FILE_TEST_EXISTS)) + { + g_test_skip ("fuse support is needed to run this test (rootless container?)"); + g_free (fusermount); + g_free (bindfs); + return; + } + + curdir = g_get_current_dir (); + dir_to_mount = g_strdup_printf ("%s/dir_bindfs_to_mount", curdir); + file_in_mount = g_strdup_printf ("%s/example.txt", dir_to_mount); + dir_mountpoint = g_strdup_printf ("%s/dir_bindfs_mountpoint", curdir); + + g_mkdir (dir_to_mount, 0777); + g_mkdir (dir_mountpoint, 0777); + if (! g_file_set_contents (file_in_mount, "Example", -1, NULL)) + { + g_test_skip ("Failed to create file needed to proceed further with the test"); + + g_free (dir_mountpoint); + g_free (file_in_mount); + g_free (dir_to_mount); + g_free (curdir); + g_free (fusermount); + g_free (bindfs); + return; + } + + if (with_mount_monitor) + mount_monitor = g_unix_mount_monitor_get (); + + /* Use bindfs, which does not need root privileges, to mount the contents of one dir + * into another dir (and do the mount as readonly as per passed '-o ro' option) */ + if (!run (&error, bindfs, "-n", "-o", "ro", dir_to_mount, dir_mountpoint, NULL)) + { + gchar *skip_message = g_strdup_printf ("Failed to run bindfs to set up test: %s", error->message); + g_test_skip (skip_message); + + g_free (skip_message); + g_clear_error (&error); + + g_clear_object (&mount_monitor); + g_free (dir_mountpoint); + g_free (file_in_mount); + g_free (dir_to_mount); + g_free (curdir); + g_free (fusermount); + g_free (bindfs); + + return; + } + + /* Let's check now, that the file is in indeed in a readonly filesystem */ + file_in_mountpoint = g_strdup_printf ("%s/example.txt", dir_mountpoint); + mounted_file = g_file_new_for_path (file_in_mountpoint); + + if (with_mount_monitor) + { + /* Let UnixMountMonitor process its 'mounts-changed' + * signal triggered by mount operation above */ + while (g_main_context_iteration (NULL, FALSE)); + } + + file_info = g_file_query_filesystem_info (mounted_file, + G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (file_info); + if (! g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY)) + { + g_test_skip ("Failed to create readonly file needed to proceed further with the test"); + + g_clear_object (&file_info); + g_clear_object (&mounted_file); + g_free (file_in_mountpoint); + g_clear_object (&mount_monitor); + g_free (dir_mountpoint); + g_free (file_in_mount); + g_free (dir_to_mount); + g_free (curdir); + g_free (fusermount); + g_free (bindfs); + + return; + } + + /* Now we unmount, and mount again but this time rw (not readonly) */ + run (&error, fusermount, "-z", "-u", dir_mountpoint, NULL); + g_assert_no_error (error); + run (&error, bindfs, "-n", dir_to_mount, dir_mountpoint, NULL); + g_assert_no_error (error); + + if (with_mount_monitor) + { + /* Let UnixMountMonitor process its 'mounts-changed' signal + * triggered by mount/umount operations above */ + while (g_main_context_iteration (NULL, FALSE)); + } + + /* Now let's test if GIO will report the new filesystem state */ + g_clear_object (&file_info); + g_clear_object (&mounted_file); + mounted_file = g_file_new_for_path (file_in_mountpoint); + file_info = g_file_query_filesystem_info (mounted_file, + G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (file_info); + + g_assert_false (g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY)); + + /* Clean up */ + g_clear_object (&mount_monitor); + g_clear_object (&file_info); + g_clear_object (&mounted_file); + run (&error, fusermount, "-z", "-u", dir_mountpoint, NULL); + g_assert_no_error (error); + + assert_remove (file_in_mount); + assert_remove (dir_to_mount); + assert_remove (dir_mountpoint); + + g_free (bindfs); + g_free (fusermount); + g_free (curdir); + g_free (dir_to_mount); + g_free (dir_mountpoint); + g_free (file_in_mount); + g_free (file_in_mountpoint); +} + +int +main (int argc, char *argv[]) +{ + /* To avoid unnecessary D-Bus calls, see http://goo.gl/ir56j2 */ + g_setenv ("GIO_USE_VFS", "local", FALSE); + + g_test_init (&argc, &argv, NULL); + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=787731"); + + g_test_add_data_func ("/g-file-info-filesystem-readonly/test-fs-ro", + GINT_TO_POINTER (FALSE), test_filesystem_readonly); + + /* This second test is using a running GUnixMountMonitor, so the calls to: + * g_unix_mount_get(&time_read) - To fill the time_read parameter + * g_unix_mounts_changed_since() + * + * made from inside g_file_query_filesystem_info() will use the mount_poller_time + * from the monitoring of /proc/self/mountinfo , while in the previous test new + * created timestamps are returned from those g_unix_mount* functions. */ + g_test_add_data_func ("/g-file-info-filesystem-readonly/test-fs-ro-with-mount-monitor", + GINT_TO_POINTER (TRUE), test_filesystem_readonly); + + return g_test_run (); +} diff --git a/gio/tests/g-file-info.c b/gio/tests/g-file-info.c new file mode 100644 index 0000000..59411c3 --- /dev/null +++ b/gio/tests/g-file-info.c @@ -0,0 +1,908 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc. + * Authors: Tomas Bzatek + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "config.h" + +#include +#include +#include +#include +#ifdef G_OS_WIN32 +#include +#include +#include +#include +#include /* for _get_osfhandle */ +#endif + +#define TEST_NAME "Prilis zlutoucky kun" +#define TEST_DISPLAY_NAME "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88" +#define TEST_SIZE 0xFFFFFFF0 + +static void +test_assigned_values (GFileInfo *info) +{ + const char *name, *display_name, *mistake; + guint64 size; + GFileType type; + + /* Test for attributes presence */ + g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME)); + g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)); + g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)); + g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME)); + + /* Retrieve data back and compare */ + + name = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME); + display_name = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME); + mistake = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME); + size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE); + type = g_file_info_get_file_type (info); + + g_assert_cmpstr (name, ==, TEST_NAME); + g_assert_cmpstr (display_name, ==, TEST_DISPLAY_NAME); + g_assert_null (mistake); + g_assert_cmpint (size, ==, TEST_SIZE); + g_assert_cmpstr (name, ==, g_file_info_get_name (info)); + g_assert_cmpstr (display_name, ==, g_file_info_get_display_name (info)); + g_assert_cmpint (size, ==, g_file_info_get_size (info) ); + g_assert_cmpint (type, ==, G_FILE_TYPE_DIRECTORY); +} + + + +static void +test_g_file_info (void) +{ + GFileInfo *info; + GFileInfo *info_dup; + GFileInfo *info_copy; + char **attr_list; + GFileAttributeMatcher *matcher; + + info = g_file_info_new (); + + /* Test for empty instance */ + attr_list = g_file_info_list_attributes (info, NULL); + g_assert_nonnull (attr_list); + g_assert_null (*attr_list); + g_strfreev (attr_list); + + g_file_info_set_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME, TEST_NAME); + g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, TEST_DISPLAY_NAME); + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE, TEST_SIZE); + g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY); + + /* The attr list should not be empty now */ + attr_list = g_file_info_list_attributes (info, NULL); + g_assert_nonnull (attr_list); + g_assert_nonnull (*attr_list); + g_strfreev (attr_list); + + test_assigned_values (info); + + /* Test dups */ + info_dup = g_file_info_dup (info); + g_assert_nonnull (info_dup); + test_assigned_values (info_dup); + + info_copy = g_file_info_new (); + g_file_info_copy_into (info_dup, info_copy); + g_assert_nonnull (info_copy); + test_assigned_values (info_copy); + + /* Test remove attribute */ + g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER)); + g_file_info_set_attribute_int32 (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER, 10); + g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER)); + + g_assert_cmpint (g_file_info_get_attribute_type (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), ==, G_FILE_ATTRIBUTE_TYPE_INT32); + g_assert_cmpint (g_file_info_get_attribute_status (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), !=, G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + + g_file_info_remove_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER); + g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER)); + g_assert_cmpint (g_file_info_get_attribute_type (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), ==, G_FILE_ATTRIBUTE_TYPE_INVALID); + + matcher = g_file_attribute_matcher_new (G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME); + + g_assert_true (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_NAME)); + g_assert_false (g_file_attribute_matcher_matches_only (matcher, G_FILE_ATTRIBUTE_STANDARD_NAME)); + g_assert_false (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_SIZE)); + + g_file_info_set_attribute_mask (info, matcher); + g_file_attribute_matcher_unref (matcher); + + g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)); + g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME)); + + g_object_unref (info); + g_object_unref (info_dup); + g_object_unref (info_copy); +} + +static void +test_g_file_info_modification_time (void) +{ + GFile *file = NULL; + GFileIOStream *io_stream = NULL; + GFileInfo *info = NULL; + GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL; + GTimeSpan ts; + GError *error = NULL; + + g_test_summary ("Test that getting the modification time of a file works."); + + file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error); + g_assert_no_error (error); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_TIME_MODIFIED, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + g_assert_no_error (error); + + /* Check the modification time is retrievable. */ + dt = g_file_info_get_modification_date_time (info); + g_assert_nonnull (dt); + + /* Try again with microsecond precision. */ + g_clear_object (&info); + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + g_assert_no_error (error); + + dt_usecs = g_file_info_get_modification_date_time (info); + g_assert_nonnull (dt_usecs); + + ts = g_date_time_difference (dt_usecs, dt); + g_assert_cmpint (ts, >=, 0); + g_assert_cmpint (ts, <, G_USEC_PER_SEC); + + /* Try round-tripping the modification time. */ + dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50); + g_file_info_set_modification_date_time (info, dt_new); + + dt_new_usecs = g_file_info_get_modification_date_time (info); + ts = g_date_time_difference (dt_new_usecs, dt_new); + g_assert_cmpint (ts, ==, 0); + + /* Clean up. */ + g_clear_object (&io_stream); + g_file_delete (file, NULL, NULL); + g_clear_object (&file); + + g_clear_object (&info); + g_date_time_unref (dt); + g_date_time_unref (dt_usecs); + g_date_time_unref (dt_new); + g_date_time_unref (dt_new_usecs); +} + +static void +test_g_file_info_access_time (void) +{ + GFile *file = NULL; + GFileIOStream *io_stream = NULL; + GFileInfo *info = NULL; + GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL, + *dt_before_epoch = NULL, *dt_before_epoch_returned = NULL; + GTimeSpan ts; + GError *error = NULL; + + g_test_summary ("Test that getting the access time of a file works."); + + file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error); + g_assert_no_error (error); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_TIME_ACCESS, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + g_assert_no_error (error); + + /* Check the access time is retrievable. */ + dt = g_file_info_get_access_date_time (info); + g_assert_nonnull (dt); + + /* Try again with microsecond precision. */ + g_clear_object (&info); + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_ACCESS_USEC, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + g_assert_no_error (error); + + dt_usecs = g_file_info_get_access_date_time (info); + g_assert_nonnull (dt_usecs); + + ts = g_date_time_difference (dt_usecs, dt); + g_assert_cmpint (ts, >, 0); + g_assert_cmpint (ts, <, G_USEC_PER_SEC); + + /* Try round-tripping the access time. */ + dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50); + g_file_info_set_access_date_time (info, dt_new); + + dt_new_usecs = g_file_info_get_access_date_time (info); + ts = g_date_time_difference (dt_new_usecs, dt_new); + g_assert_cmpint (ts, ==, 0); + + // try with a negative timestamp + dt_before_epoch = g_date_time_new_from_unix_utc (-10000); + g_file_info_set_access_date_time (info, dt_before_epoch); + dt_before_epoch_returned = g_file_info_get_access_date_time (info); + ts = g_date_time_difference (dt_before_epoch, dt_before_epoch_returned); + g_assert_cmpint (ts, ==, 0); + + /* Clean up. */ + g_clear_object (&io_stream); + g_file_delete (file, NULL, NULL); + g_clear_object (&file); + + g_clear_object (&info); + g_date_time_unref (dt); + g_date_time_unref (dt_usecs); + g_date_time_unref (dt_new); + g_date_time_unref (dt_new_usecs); + g_date_time_unref (dt_before_epoch); + g_date_time_unref (dt_before_epoch_returned); +} + +static void +test_g_file_info_creation_time (void) +{ + GFile *file = NULL; + GFileIOStream *io_stream = NULL; + GFileInfo *info = NULL; + GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL, + *dt_before_epoch = NULL, *dt_before_epoch_returned = NULL; + GTimeSpan ts; + GError *error = NULL; + + g_test_summary ("Test that getting the creation time of a file works."); + + file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error); + g_assert_no_error (error); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_TIME_CREATED, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + g_assert_no_error (error); + + /* Check the creation time is retrievable. */ + dt = g_file_info_get_creation_date_time (info); + if (!dt) + { + g_test_skip ("Skipping testing creation time as it’s not supported by the kernel"); + g_file_delete (file, NULL, NULL); + g_clear_object (&file); + g_clear_object (&info); + return; + } + + /* Try again with microsecond precision. */ + g_clear_object (&info); + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_TIME_CREATED "," G_FILE_ATTRIBUTE_TIME_CREATED_USEC, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + g_assert_no_error (error); + + dt_usecs = g_file_info_get_creation_date_time (info); + g_assert_nonnull (dt_usecs); + + ts = g_date_time_difference (dt_usecs, dt); + g_assert_cmpint (ts, >, 0); + g_assert_cmpint (ts, <, G_USEC_PER_SEC); + + /* Try round-tripping the creation time. */ + dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50); + g_file_info_set_creation_date_time (info, dt_new); + + dt_new_usecs = g_file_info_get_creation_date_time (info); + ts = g_date_time_difference (dt_new_usecs, dt_new); + g_assert_cmpint (ts, ==, 0); + + // try with a negative timestamp + dt_before_epoch = g_date_time_new_from_unix_utc (-10000); + g_file_info_set_creation_date_time (info, dt_before_epoch); + dt_before_epoch_returned = g_file_info_get_creation_date_time (info); + ts = g_date_time_difference (dt_before_epoch, dt_before_epoch_returned); + g_assert_cmpint (ts, ==, 0); + + /* Clean up. */ + g_clear_object (&io_stream); + g_file_delete (file, NULL, NULL); + g_clear_object (&file); + + g_clear_object (&info); + g_date_time_unref (dt); + g_date_time_unref (dt_usecs); + g_date_time_unref (dt_new); + g_date_time_unref (dt_new_usecs); + g_date_time_unref (dt_before_epoch); + g_date_time_unref (dt_before_epoch_returned); +} + +#ifdef G_OS_WIN32 +static void +test_internal_enhanced_stdio (void) +{ + char *p0, *p1, *ps; + gboolean try_sparse; + gchar *tmp_dir_root; + wchar_t *tmp_dir_root_w; + gchar *c; + DWORD fsflags; + FILE *f; + SYSTEMTIME st; + FILETIME ft; + HANDLE h; + GStatBuf statbuf_p0, statbuf_p1, statbuf_ps; + GFile *gf_p0, *gf_p1, *gf_ps; + GFileInfo *fi_p0, *fi_p1, *fi_ps; + guint64 size_p0, alsize_p0, size_ps, alsize_ps; + const gchar *id_p0; + const gchar *id_p1; + guint64 time_p0; + gchar *tmp_dir; + wchar_t *programdata_dir_w; + wchar_t *users_dir_w; + static const GUID folder_id_programdata = + { 0x62AB5D82, 0xFDC1, 0x4DC3, { 0xA9, 0xDD, 0x07, 0x0D, 0x1D, 0x49, 0x5D, 0x97 } }; + static const GUID folder_id_users = + { 0x0762D272, 0xC50A, 0x4BB0, { 0xA3, 0x82, 0x69, 0x7D, 0xCD, 0x72, 0x9B, 0x80 } }; + GDateTime *dt = NULL, *dt2 = NULL; + GTimeSpan ts; + /* Just before SYSTEMTIME limit (Jan 1 30827) */ + const gint64 one_sec_before_systemtime_limit = 910670515199; + gboolean retval; + GError *local_error = NULL; + + + programdata_dir_w = NULL; + SHGetKnownFolderPath (&folder_id_programdata, 0, NULL, &programdata_dir_w); + + users_dir_w = NULL; + SHGetKnownFolderPath (&folder_id_users, 0, NULL, &users_dir_w); + + if (programdata_dir_w != NULL && users_dir_w != NULL) + { + gchar *programdata; + gchar *users_dir; + gchar *allusers; + gchar *commondata; + GFile *gf_programdata, *gf_allusers, *gf_commondata; + GFileInfo *fi_programdata, *fi_allusers, *fi_allusers_target, *fi_commondata, *fi_commondata_target; + GFileType ft_allusers; + GFileType ft_allusers_target; + GFileType ft_programdata; + GFileType ft_commondata; + gboolean allusers_is_symlink; + gboolean commondata_is_symlink; + gboolean commondata_is_mount_point; + guint32 allusers_reparse_tag; + guint32 commondata_reparse_tag; + const gchar *id_allusers; + const gchar *id_allusers_target; + const gchar *id_commondata_target; + const gchar *id_programdata; + const gchar *allusers_target; + const gchar *commondata_target; + + /* C:/ProgramData */ + programdata = g_utf16_to_utf8 (programdata_dir_w, -1, NULL, NULL, NULL); + g_assert_nonnull (programdata); + /* C:/Users */ + users_dir = g_utf16_to_utf8 (users_dir_w, -1, NULL, NULL, NULL); + g_assert_nonnull (users_dir); + /* "C:/Users/All Users" is a known directory symlink + * for "C:/ProgramData". + */ + allusers = g_build_filename (users_dir, "All Users", NULL); + + /* "C:/Users/All Users/Application Data" is a known + * junction for "C:/ProgramData" + */ + commondata = g_build_filename (allusers, "Application Data", NULL); + + /* We don't test g_stat() and g_lstat() on these directories, + * because it is pointless - there's no way to tell that these + * functions behave correctly in this case + * (st_ino is useless, so we can't tell apart g_stat() and g_lstat() + * results; st_mode is also useless as it does not support S_ISLNK; + * and these directories have no interesting properties other + * than [not] being symlinks). + */ + gf_programdata = g_file_new_for_path (programdata); + gf_allusers = g_file_new_for_path (allusers); + gf_commondata = g_file_new_for_path (commondata); + + fi_programdata = g_file_query_info (gf_programdata, + G_FILE_ATTRIBUTE_ID_FILE "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + fi_allusers_target = g_file_query_info (gf_allusers, + G_FILE_ATTRIBUTE_ID_FILE "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + fi_allusers = g_file_query_info (gf_allusers, + G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," + G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," + G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG "," + G_FILE_ATTRIBUTE_ID_FILE "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, NULL); + + fi_commondata = g_file_query_info (gf_commondata, + G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," + G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," + G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT "," + G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG "," + G_FILE_ATTRIBUTE_ID_FILE "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, NULL); + + fi_commondata_target = g_file_query_info (gf_commondata, + G_FILE_ATTRIBUTE_ID_FILE "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + g_assert_true (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE)); + g_assert_true (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_STANDARD_TYPE)); + + g_assert_true (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE)); + g_assert_true (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_STANDARD_TYPE)); + g_assert_true (g_file_info_has_attribute (fi_commondata_target, G_FILE_ATTRIBUTE_ID_FILE)); + g_assert_true (g_file_info_has_attribute (fi_commondata_target, G_FILE_ATTRIBUTE_STANDARD_TYPE)); + + g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE)); + g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_TYPE)); + g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK)); + g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG)); + g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET)); + + g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_ID_FILE)); + g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_TYPE)); + g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK)); + g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT)); + g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG)); + g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET)); + + ft_allusers = g_file_info_get_file_type (fi_allusers); + ft_allusers_target = g_file_info_get_file_type (fi_allusers_target); + ft_programdata = g_file_info_get_file_type (fi_programdata); + ft_commondata = g_file_info_get_file_type (fi_commondata); + + g_assert_cmpint (ft_allusers, ==, G_FILE_TYPE_DIRECTORY); + g_assert_cmpint (ft_allusers_target, ==, G_FILE_TYPE_DIRECTORY); + g_assert_cmpint (ft_programdata, ==, G_FILE_TYPE_DIRECTORY); + g_assert_cmpint (ft_commondata, ==, G_FILE_TYPE_DIRECTORY); + + allusers_is_symlink = g_file_info_get_attribute_boolean (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK); + allusers_reparse_tag = g_file_info_get_attribute_uint32 (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG); + commondata_is_symlink = g_file_info_get_attribute_boolean (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK); + commondata_is_mount_point = g_file_info_get_attribute_boolean (fi_commondata, G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT); + commondata_reparse_tag = g_file_info_get_attribute_uint32 (fi_commondata, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG); + + g_assert_true (allusers_is_symlink); + g_assert_cmpuint (allusers_reparse_tag, ==, IO_REPARSE_TAG_SYMLINK); + g_assert_true (commondata_is_symlink); + g_assert_true (commondata_is_mount_point); + g_assert_cmpuint (commondata_reparse_tag, ==, IO_REPARSE_TAG_MOUNT_POINT); + + id_allusers = g_file_info_get_attribute_string (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE); + id_allusers_target = g_file_info_get_attribute_string (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE); + id_commondata_target = g_file_info_get_attribute_string (fi_commondata_target, G_FILE_ATTRIBUTE_ID_FILE); + id_programdata = g_file_info_get_attribute_string (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE); + + g_assert_cmpstr (id_allusers_target, ==, id_programdata); + g_assert_cmpstr (id_commondata_target, ==, id_programdata); + g_assert_cmpstr (id_allusers, !=, id_programdata); + + allusers_target = g_file_info_get_symlink_target (fi_allusers); + + g_assert_true (g_str_has_suffix (allusers_target, "ProgramData")); + + commondata_target = g_file_info_get_symlink_target (fi_commondata); + + g_assert_true (g_str_has_suffix (commondata_target, "ProgramData")); + + g_object_unref (fi_allusers); + g_object_unref (fi_allusers_target); + g_object_unref (fi_commondata); + g_object_unref (fi_commondata_target); + g_object_unref (fi_programdata); + g_object_unref (gf_allusers); + g_object_unref (gf_commondata); + g_object_unref (gf_programdata); + + g_free (allusers); + g_free (commondata); + g_free (users_dir); + g_free (programdata); + } + + if (programdata_dir_w) + CoTaskMemFree (programdata_dir_w); + + if (users_dir_w) + CoTaskMemFree (users_dir_w); + + tmp_dir = g_dir_make_tmp ("glib_stdio_testXXXXXX", NULL); + g_assert_nonnull (tmp_dir); + + /* Technically, this isn't necessary - we already assume NTFS, because of + * symlink support, and NTFS also supports sparse files. Still, given + * the amount of unusual I/O APIs called in this test, checking for + * sparse file support of the filesystem where temp directory is + * doesn't seem to be out of place. + */ + try_sparse = FALSE; + tmp_dir_root = g_strdup (tmp_dir); + /* We need "C:\\" or "C:/", with a trailing [back]slash */ + for (c = tmp_dir_root; c && c[0] && c[1]; c++) + if (c[0] == ':') + { + c[2] = '\0'; + break; + } + tmp_dir_root_w = g_utf8_to_utf16 (tmp_dir_root, -1, NULL, NULL, NULL); + g_assert_nonnull (tmp_dir_root_w); + g_free (tmp_dir_root); + g_assert_true (GetVolumeInformationW (tmp_dir_root_w, NULL, 0, NULL, NULL, &fsflags, NULL, 0)); + g_free (tmp_dir_root_w); + try_sparse = (fsflags & FILE_SUPPORTS_SPARSE_FILES) == FILE_SUPPORTS_SPARSE_FILES; + + p0 = g_build_filename (tmp_dir, "zool", NULL); + p1 = g_build_filename (tmp_dir, "looz", NULL); + ps = g_build_filename (tmp_dir, "sparse", NULL); + + if (try_sparse) + { + FILE_SET_SPARSE_BUFFER ssb; + FILE_ZERO_DATA_INFORMATION zdi; + + g_remove (ps); + + f = g_fopen (ps, "wb"); + g_assert_nonnull (f); + + h = (HANDLE) _get_osfhandle (fileno (f)); + g_assert_cmpuint ((guintptr) h, !=, (guintptr) INVALID_HANDLE_VALUE); + + ssb.SetSparse = TRUE; + g_assert_true (DeviceIoControl (h, + FSCTL_SET_SPARSE, + &ssb, sizeof (ssb), + NULL, 0, NULL, NULL)); + + /* Make it a sparse file that starts with 4GBs of zeros */ + zdi.FileOffset.QuadPart = 0; + zdi.BeyondFinalZero.QuadPart = 0xFFFFFFFFULL + 1; + g_assert_true (DeviceIoControl (h, + FSCTL_SET_ZERO_DATA, + &zdi, sizeof (zdi), + NULL, 0, NULL, NULL)); + + /* Let's not keep this seemingly 4GB monster around + * longer than we absolutely need to. Do all operations + * without assertions, then remove the file immediately. + */ + _fseeki64 (f, 0xFFFFFFFFULL, SEEK_SET); + fprintf (f, "Hello 4GB World!"); + fflush (f); + fclose (f); + + memset (&statbuf_ps, 0, sizeof (statbuf_ps)); + + g_stat (ps, &statbuf_ps); + + gf_ps = g_file_new_for_path (ps); + + fi_ps = g_file_query_info (gf_ps, + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + g_remove (ps); + + g_assert_true (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE)); + g_assert_true (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE)); + + size_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE); + alsize_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE); + + /* allocated size should small (usually - size of the FS cluster, + * let's assume it's less than 1 gigabyte), + * size should be more than 4 gigabytes, + * st_size should not exceed its 0xFFFFFFFF 32-bit limit, + * and should be nonzero (this also detects a failed g_stat() earlier). + */ + g_assert_cmpuint (alsize_ps, <, 0x40000000); + g_assert_cmpuint (size_ps, >, G_GUINT64_CONSTANT (0xFFFFFFFF)); + g_assert_cmpuint (statbuf_ps.st_size, >, 0); +#if defined(_WIN64) + g_assert_cmpuint (statbuf_ps.st_size, ==, G_GUINT64_CONSTANT (0x10000000f)); +#else + g_assert_cmpuint (statbuf_ps.st_size, <=, 0xFFFFFFFF); +#endif + + g_object_unref (fi_ps); + g_object_unref (gf_ps); + } + + /* Wa-a-ay past 02/07/2106 @ 6:28am (UTC), + * which is the date corresponding to 0xFFFFFFFF + 1. + * This is easier to check than Y2038 (0x80000000 + 1), + * since there's no need to worry about signedness this way. + */ + st.wYear = 2106; + st.wMonth = 2; + st.wDay = 9; + st.wHour = 0; + st.wMinute = 0; + st.wSecond = 0; + st.wMilliseconds = 0; + + g_assert_true (SystemTimeToFileTime (&st, &ft)); + + f = g_fopen (p0, "w"); + g_assert_nonnull (f); + + h = (HANDLE) _get_osfhandle (fileno (f)); + g_assert_cmpuint ((guintptr) h, !=, (guintptr) INVALID_HANDLE_VALUE); + + fprintf (f, "1"); + fflush (f); + + g_assert_true (SetFileTime (h, &ft, &ft, &ft)); + + fclose (f); + + f = g_fopen (p1, "w"); + g_assert_nonnull (f); + + fclose (f); + + memset (&statbuf_p0, 0, sizeof (statbuf_p0)); + memset (&statbuf_p1, 0, sizeof (statbuf_p1)); + + g_assert_cmpint (g_stat (p0, &statbuf_p0), ==, 0); + g_assert_cmpint (g_stat (p1, &statbuf_p1), ==, 0); + + gf_p0 = g_file_new_for_path (p0); + gf_p1 = g_file_new_for_path (p1); + + fi_p0 = g_file_query_info (gf_p0, + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE "," + G_FILE_ATTRIBUTE_ID_FILE "," + G_FILE_ATTRIBUTE_TIME_MODIFIED "," + G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + fi_p1 = g_file_query_info (gf_p1, + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE "," + G_FILE_ATTRIBUTE_ID_FILE "," + G_FILE_ATTRIBUTE_TIME_MODIFIED "," + G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE)); + g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE)); + g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_ID_FILE)); + g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED)); + g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC)); + + g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_SIZE)); + g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE)); + g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_ID_FILE)); + g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED)); + g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC)); + + size_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE); + alsize_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE); + + /* size should be 1, allocated size should be something else + * (could be 0 or the size of the FS cluster, but never 1). + */ + g_assert_cmpuint (size_p0, ==, statbuf_p0.st_size); + g_assert_cmpuint (size_p0, ==, 1); + g_assert_cmpuint (alsize_p0, !=, size_p0); + + id_p0 = g_file_info_get_attribute_string (fi_p0, G_FILE_ATTRIBUTE_ID_FILE); + id_p1 = g_file_info_get_attribute_string (fi_p1, G_FILE_ATTRIBUTE_ID_FILE); + + /* st_ino from W32 stat() is useless for file identification. + * It will be either 0, or it will be the same for both files. + */ + g_assert_cmpint (statbuf_p0.st_ino, ==, statbuf_p1.st_ino); + g_assert_cmpstr (id_p0, !=, id_p1); + + time_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED); + + /* Check that GFileInfo doesn't suffer from Y2106 problem. + * Don't check stat(), as its contents may vary depending on + * the host platform architecture + * (time fields are 32-bit on 32-bit Windows, + * and 64-bit on 64-bit Windows, usually), + * so it *can* pass this test in some cases. + */ + g_assert_cmpuint (time_p0, >, G_GUINT64_CONSTANT (0xFFFFFFFF)); + + dt = g_file_info_get_modification_date_time (fi_p0); + g_assert_nonnull (dt); + dt2 = g_date_time_add (dt, G_USEC_PER_SEC / 100 * 200); + g_object_unref (fi_p0); + fi_p0 = g_file_info_new (); + g_file_info_set_modification_date_time (fi_p0, dt2); + + g_assert_true (g_file_set_attributes_from_info (gf_p0, + fi_p0, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL)); + g_date_time_unref (dt2); + g_object_unref (fi_p0); + fi_p0 = g_file_query_info (gf_p0, + G_FILE_ATTRIBUTE_TIME_MODIFIED "," + G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + dt2 = g_file_info_get_modification_date_time (fi_p0); + ts = g_date_time_difference (dt2, dt); + g_assert_cmpint (ts, >, 0); + g_assert_cmpint (ts, <, G_USEC_PER_SEC / 100 * 300); + + g_date_time_unref (dt); + g_date_time_unref (dt2); + + g_file_info_set_attribute_uint64 (fi_p0, + G_FILE_ATTRIBUTE_TIME_MODIFIED, + one_sec_before_systemtime_limit); + g_file_info_set_attribute_uint32 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, 0); + g_assert_true (g_file_set_attributes_from_info (gf_p0, + fi_p0, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL)); + + g_file_info_set_attribute_uint64 (fi_p0, + G_FILE_ATTRIBUTE_TIME_MODIFIED, + one_sec_before_systemtime_limit + G_USEC_PER_SEC * 2); + g_file_info_set_attribute_uint32 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, 0); + retval = g_file_set_attributes_from_info (gf_p0, + fi_p0, + G_FILE_QUERY_INFO_NONE, + NULL, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA); + g_assert_false (retval); + g_clear_error (&local_error); + + g_object_unref (fi_p0); + g_object_unref (fi_p1); + g_object_unref (gf_p0); + g_object_unref (gf_p1); + g_remove (p0); + g_remove (p1); + g_free (p0); + g_free (p1); + g_rmdir (tmp_dir); +} +#endif + +static void +test_xattrs (void) +{ + GFile *file = NULL; + GFileIOStream *stream = NULL; + GFileInfo *file_info0 = NULL, *file_info1 = NULL; + GError *local_error = NULL; + + g_test_summary ("Test setting and getting escaped xattrs"); + + /* Create a temporary file; no need to write anything to it. */ + file = g_file_new_tmp ("g-file-info-test-xattrs-XXXXXX", &stream, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (file); + + g_io_stream_close (G_IO_STREAM (stream), NULL, NULL); + g_object_unref (stream); + + /* Check the existing xattrs. */ + file_info0 = g_file_query_info (file, "xattr::*", G_FILE_QUERY_INFO_NONE, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (file_info0); + + /* Set some new xattrs, with escaping and some embedded nuls. */ + g_file_info_set_attribute_string (file_info0, "xattr::escaped", "hello\\x82\\x80\\xbd"); + g_file_info_set_attribute_string (file_info0, "xattr::string", "hi there"); + g_file_info_set_attribute_string (file_info0, "xattr::embedded-nul", "hi\\x00there"); + + g_file_set_attributes_from_info (file, file_info0, G_FILE_QUERY_INFO_NONE, NULL, &local_error); + + g_object_unref (file_info0); + + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + g_test_skip ("xattrs not supported on this file system"); + g_clear_error (&local_error); + } + else + { + g_assert_no_error (local_error); + + /* Check they were set properly. */ + file_info1 = g_file_query_info (file, "xattr::*", G_FILE_QUERY_INFO_NONE, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (file_info1); + + g_assert_true (g_file_info_has_namespace (file_info1, "xattr")); + + g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::escaped"), ==, "hello\\x82\\x80\\xbd"); + g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::string"), ==, "hi there"); + g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::embedded-nul"), ==, "hi\\x00there"); + + g_object_unref (file_info1); + } + + /* Tidy up. */ + g_file_delete (file, NULL, NULL); + + g_object_unref (file); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/g-file-info/test_g_file_info", test_g_file_info); + g_test_add_func ("/g-file-info/test_g_file_info/modification-time", test_g_file_info_modification_time); + g_test_add_func ("/g-file-info/test_g_file_info/access-time", test_g_file_info_access_time); + g_test_add_func ("/g-file-info/test_g_file_info/creation-time", test_g_file_info_creation_time); +#ifdef G_OS_WIN32 + g_test_add_func ("/g-file-info/internal-enhanced-stdio", test_internal_enhanced_stdio); +#endif + g_test_add_func ("/g-file-info/xattrs", test_xattrs); + + return g_test_run(); +} diff --git a/gio/tests/g-file.c b/gio/tests/g-file.c new file mode 100644 index 0000000..8669e3a --- /dev/null +++ b/gio/tests/g-file.c @@ -0,0 +1,537 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc. + * Authors: Tomas Bzatek + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +struct TestPathsWithOper { + const char *path1; + gboolean equal; + gboolean use_uri; + const char *path2; + const char *path3; +}; + + + +/* TODO: + * - test on Windows + * + **/ + +static void +test_g_file_new_null (void) +{ + const char *paths[] = {"/", + "/tmp///", + "/non-existent-file", + "/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", + NULL + }; + const char *uris[] = {"file:///", + "file:///tmp///", + "non-existent-uri:///some-dir/", + "file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", + NULL + }; + + GFile *file = NULL; + + int i = 0; + while (paths[i]) + { + file = g_file_new_for_path (paths[i++]); + g_assert (file != NULL); + g_object_unref (file); + } + + i = 0; + while (uris[i]) + { + file = g_file_new_for_uri (uris[i++]); + g_assert (file != NULL); + g_object_unref(file); + } +} + + + +static gboolean +compare_two_files (const gboolean use_uri, const char *path1, const char *path2) +{ + GFile *file1 = NULL; + GFile *file2 = NULL; + gboolean equal; + + if (use_uri) + { + file1 = g_file_new_for_uri (path1); + file2 = g_file_new_for_uri (path2); + } + else + { + file1 = g_file_new_for_path (path1); + file2 = g_file_new_for_path (path2); + } + + g_assert (file1 != NULL); + g_assert (file2 != NULL); + + equal = g_file_equal (file1, file2); + + g_object_unref (file1); + g_object_unref (file2); + + return equal; +} + +static void +test_g_file_new_for_path (void) +{ + const struct TestPathsWithOper cmp_paths[] = + { + {"/", TRUE, 0, "/./", NULL }, + {"//", TRUE, 0, "//", NULL }, + {"//", TRUE, 0, "//./", NULL }, + {"/", TRUE, 0, "/.//", NULL }, + {"/", TRUE, 0, "/././", NULL }, + {"/tmp", TRUE, 0, "/tmp/d/../", NULL }, + {"/", TRUE, 0, "/somedir/../", NULL }, + {"/", FALSE, 0, "/somedir/.../", NULL }, + {"//tmp/dir1", TRUE, 0, "//tmp/dir1", NULL }, + {"/tmp/dir1", TRUE, 0, "///tmp/dir1", NULL }, + {"/tmp/dir1", TRUE, 0, "////tmp/dir1", NULL }, + {"/tmp/dir1", TRUE, 0, "/tmp/./dir1", NULL }, + {"/tmp/dir1", TRUE, 0, "/tmp//dir1", NULL }, + {"/tmp/dir1", TRUE, 0, "/tmp///dir1///", NULL }, + {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", TRUE, 0, "/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/", NULL } + }; + + guint i; + for (i = 0; i < G_N_ELEMENTS (cmp_paths); i++) + { + gboolean equal = compare_two_files (FALSE, cmp_paths[i].path1, cmp_paths[i].path2); + g_assert_cmpint (equal, ==, cmp_paths[i].equal); + } +} + + + +static void +test_g_file_new_for_uri (void) +{ + const struct TestPathsWithOper cmp_uris[] = { + {"file:///", TRUE, 0, "file:///./", NULL }, + {"file:////", TRUE, 0, "file:////", NULL }, + {"file:////", TRUE, 0, "file:////./", NULL }, + {"file:///", TRUE, 0, "file:///.//", NULL }, + {"file:///", TRUE, 0, "file:///././", NULL }, + {"file:///tmp", TRUE, 0, "file:///tmp/d/../", NULL }, + {"file:///", TRUE, 0, "file:///somedir/../", NULL }, + {"file:///", FALSE, 0, "file:///somedir/.../", NULL }, + {"file:////tmp/dir1", TRUE, 0, "file:////tmp/dir1", NULL }, + {"file:///tmp/dir1", TRUE, 0, "file:///tmp/./dir1", NULL }, + {"file:///tmp/dir1", TRUE, 0, "file:///tmp//dir1", NULL }, + {"file:///tmp/dir1", TRUE, 0, "file:///tmp///dir1///", NULL }, + {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", TRUE, 0, "file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", NULL } + }; + + guint i; + for (i = 0; i < G_N_ELEMENTS (cmp_uris); i++) + { + gboolean equal = compare_two_files (TRUE, cmp_uris[i].path1, cmp_uris[i].path2); + g_assert_cmpint (equal, ==, cmp_uris[i].equal); + } +} + + + +static gboolean +dup_equals (const gboolean use_uri, const char *path) +{ + GFile *file1 = NULL; + GFile *file2 = NULL; + gboolean equal; + + if (use_uri) + file1 = g_file_new_for_uri (path); + else + file1 = g_file_new_for_path (path); + + g_assert (file1 != NULL); + + file2 = g_file_dup (file1); + + g_assert (file2 != NULL); + + equal = g_file_equal (file1, file2); + + g_object_unref (file1); + g_object_unref (file2); + + return equal; +} + +static void +test_g_file_dup (void) +{ + const struct TestPathsWithOper dup_paths[] = + { + {"/", 0, FALSE, "", NULL }, + {"file:///", 0, TRUE, "", NULL }, + {"totalnonsense", 0, FALSE, "", NULL }, + {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, "", NULL }, + {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", 0, TRUE, "", NULL }, + }; + + guint i; + for (i = 0; i < G_N_ELEMENTS (dup_paths); i++) + { + gboolean equal = dup_equals (dup_paths[i].use_uri, dup_paths[i].path1); + g_assert (equal == TRUE); + } +} + + + +static gboolean +parse_check_utf8 (const gboolean use_uri, const char *path, const char *result_parse_name) +{ + GFile *file1 = NULL; + GFile *file2 = NULL; + char *parsed_name; + gboolean is_utf8_valid; + gboolean equal; + + if (use_uri) + file1 = g_file_new_for_uri (path); + else + file1 = g_file_new_for_path (path); + + g_assert (file1 != NULL); + + parsed_name = g_file_get_parse_name (file1); + + g_assert (parsed_name != NULL); + + /* UTF-8 validation */ + is_utf8_valid = g_utf8_validate (parsed_name, -1, NULL); + g_assert (is_utf8_valid == TRUE); + + if (result_parse_name) + g_assert_cmpstr (parsed_name, ==, result_parse_name); + + file2 = g_file_parse_name (parsed_name); + + g_assert (file2 != NULL); + + equal = g_file_equal (file1, file2); + + g_object_unref (file1); + g_object_unref (file2); + + g_free (parsed_name); + + return equal; +} + +static void +test_g_file_get_parse_name_utf8 (void) +{ + const struct TestPathsWithOper strings[] = + { + {G_DIR_SEPARATOR_S, 0, FALSE, G_DIR_SEPARATOR_S, NULL }, + {"file:///", 0, TRUE, G_DIR_SEPARATOR_S, NULL }, + {"totalnonsense", 0, FALSE, NULL, NULL }, + {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, NULL, NULL /* Depends on local file encoding */}, + {"file:///invalid%08/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, TRUE, "file:///invalid%08/UTF-8%20p\xc5\x99\xc3\xadli\xc5\xa1%20\xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd%20k\xc5\xaf\xc5\x88", NULL }, + }; + + guint i; + for (i = 0; i < G_N_ELEMENTS (strings); i++) + { + gboolean equal = parse_check_utf8 (strings[i].use_uri, strings[i].path1, strings[i].path2); + g_assert (equal == TRUE); + } +} + +static char * +resolve_arg (const gboolean is_uri_only, const char *arg) +{ + GFile *file1 = NULL; + char *uri = NULL; + char *path = NULL; + char *s = NULL; + + file1 = g_file_new_for_commandline_arg (arg); + g_assert (file1 != NULL); + + /* Test if we get URI string */ + uri = g_file_get_uri (file1); + g_assert_cmpstr (uri, !=, NULL); + g_printerr ("%s\n",uri); + + /* Test if we get correct value of the local path */ + path = g_file_get_path (file1); + if (is_uri_only) + g_assert_cmpstr (path, ==, NULL); + else + g_assert (g_path_is_absolute (path) == TRUE); + + /* Get the URI scheme and compare it with expected one */ + s = g_file_get_uri_scheme (file1); + + g_object_unref (file1); + g_free (uri); + g_free (path); + + return s; +} + +static void +test_g_file_new_for_commandline_arg (void) +{ + /* TestPathsWithOper.use_uri represents IsURIOnly here */ + const struct TestPathsWithOper arg_data[] = + { + {"./", 0, FALSE, "file", NULL }, + {"../", 0, FALSE, "file", NULL }, + {"/tmp", 0, FALSE, "file", NULL }, + {"//UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, "file", NULL }, + {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, FALSE, "file", NULL }, +#if 0 + {"http://www.gtk.org/", 0, TRUE, "http", NULL }, + {"ftp://user:pass@ftp.gimp.org/", 0, TRUE, "ftp", NULL }, +#endif + }; + GFile *file; + char *resolved; + char *cwd; + guint i; + + for (i = 0; i < G_N_ELEMENTS (arg_data); i++) + { + char *s = resolve_arg (arg_data[i].use_uri, arg_data[i].path1); + g_assert_cmpstr (s, ==, arg_data[i].path2); + g_free (s); + } + + /* Manual test for getting correct cwd */ + file = g_file_new_for_commandline_arg ("./"); + resolved = g_file_get_path (file); + cwd = g_get_current_dir (); + g_assert_cmpstr (resolved, ==, cwd); + g_object_unref (file); + g_free (resolved); + g_free (cwd); +} + +static char* +get_relative_path (const gboolean use_uri, const gboolean should_have_prefix, const char *dir1, const char *dir2) +{ + GFile *file1 = NULL; + GFile *file2 = NULL; + GFile *file3 = NULL; + gboolean has_prefix = FALSE; + char *relative_path = NULL; + + if (use_uri) + { + file1 = g_file_new_for_uri (dir1); + file2 = g_file_new_for_uri (dir2); + } + else + { + file1 = g_file_new_for_path (dir1); + file2 = g_file_new_for_path (dir2); + } + + g_assert (file1 != NULL); + g_assert (file2 != NULL); + + has_prefix = g_file_has_prefix (file2, file1); + g_printerr ("%s %s\n", dir1, dir2); + g_assert (has_prefix == should_have_prefix); + + relative_path = g_file_get_relative_path (file1, file2); + if (should_have_prefix) + { + g_assert (relative_path != NULL); + + file3 = g_file_resolve_relative_path (file1, relative_path); + g_assert (g_file_equal (file2, file3) == TRUE); + } + + if (file1) + g_object_unref (file1); + if (file2) + g_object_unref (file2); + if (file3) + g_object_unref (file3); + + return relative_path; +} + +static void +test_g_file_has_prefix (void) +{ + /* TestPathsWithOper.equal represents here if the dir belongs to the directory structure */ + const struct TestPathsWithOper dirs[] = + { + /* path1 equal uri path2 path3 */ + {"/dir1", TRUE, FALSE, "/dir1/dir2/dir3/", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"/dir1/", TRUE, FALSE, "/dir1/dir2/dir3/", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"/dir1", TRUE, FALSE, "/dir1/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"/dir1/", TRUE, FALSE, "/dir1/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"/tmp/", FALSE, FALSE, "/something/", NULL}, + {"/dir1/dir2", FALSE, FALSE, "/dir1/", NULL}, + {"//dir1/new", TRUE, FALSE, "//dir1/new/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"/dir/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", TRUE, FALSE, "/dir/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/dir2", "dir2"}, + {"file:///dir1", TRUE, TRUE, "file:///dir1/dir2/dir3/", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"file:///dir1/", TRUE, TRUE, "file:///dir1/dir2/dir3/", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"file:///dir1", TRUE, TRUE, "file:///dir1/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"file:///dir1/", TRUE, TRUE, "file:///dir1/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"file:///tmp/", FALSE, TRUE, "file:///something/", NULL}, + {"file:///dir1/dir2", FALSE, TRUE, "file:///dir1/", NULL}, + {"file:////dir1/new", TRUE, TRUE, "file:////dir1/new/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"}, + {"file:///dir/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", TRUE, TRUE, "file:///dir/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/dir2", "dir2"}, +#if 0 + {"dav://www.gtk.org/plan/", TRUE, TRUE, "dav://www.gtk.org/plan/meetings/20071218.txt", "meetings/20071218.txt"}, + {"dav://www.gtk.org/plan/meetings", TRUE, TRUE, "dav://www.gtk.org/plan/meetings/20071218.txt", "20071218.txt"}, +#endif + }; + + guint i; + for (i = 0; i < G_N_ELEMENTS (dirs); i++) + { + char *s = get_relative_path (dirs[i].use_uri, dirs[i].equal, dirs[i].path1, dirs[i].path2); + if (dirs[i].equal) + g_assert_cmpstr (s, ==, dirs[i].path3); + g_free (s); + } +} + +static void +roundtrip_parent_child (const gboolean use_uri, const gboolean under_root_descending, + const char *path, const char *dir_holder) +{ + GFile *files[6] = {NULL}; + guint i; + + if (use_uri) + { + files[0] = g_file_new_for_uri (path); + files[1] = g_file_new_for_uri (path); + } + else + { + files[0] = g_file_new_for_path (path); + files[1] = g_file_new_for_path (path); + } + + g_assert (files[0] != NULL); + g_assert (files[1] != NULL); + + files[2] = g_file_get_child (files[1], dir_holder); + g_assert (files[2] != NULL); + + files[3] = g_file_get_parent (files[2]); + g_assert (files[3] != NULL); + g_assert (g_file_equal (files[3], files[0]) == TRUE); + + files[4] = g_file_get_parent (files[3]); + /* Don't go lower beyond the root */ + if (under_root_descending) + g_assert (files[4] == NULL); + else + { + g_assert (files[4] != NULL); + + files[5] = g_file_get_child (files[4], dir_holder); + g_assert (files[5] != NULL); + g_assert (g_file_equal (files[5], files[0]) == TRUE); + } + + for (i = 0; i < G_N_ELEMENTS (files); i++) + { + if (files[i]) + g_object_unref (files[i]); + } +} + +static void +test_g_file_get_parent_child (void) +{ + const struct TestPathsWithOper paths[] = + { + /* path root_desc uri dir_holder */ + {"/dir1/dir", FALSE, FALSE, "dir", NULL }, + {"/dir", FALSE, FALSE, "dir", NULL }, + {"/", TRUE, FALSE, "dir", NULL }, + {"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/", FALSE, FALSE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", NULL }, + {"file:///dir1/dir", FALSE, TRUE, "dir", NULL }, + {"file:///dir", FALSE, TRUE, "dir", NULL }, + {"file:///", TRUE, TRUE, "dir", NULL }, + {"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", FALSE, TRUE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", NULL }, + {"dav://www.gtk.org/plan/meetings", FALSE, TRUE, "meetings", NULL }, + }; + + guint i; + for (i = 0; i < G_N_ELEMENTS (paths); i++) + roundtrip_parent_child (paths[i].use_uri, paths[i].equal, paths[i].path1, paths[i].path2); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + + /* Testing whether g_file_new_for_path() or g_file_new_for_uri() always returns non-NULL result */ + g_test_add_func ("/g-file/test_g_file_new_null", test_g_file_new_null); + + /* Testing whether the g_file_new_for_path() correctly canonicalizes strings and two files equals (g_file_equal()) */ + g_test_add_func ("/g-file/test_g_file_new_for_path", test_g_file_new_for_path); + + /* Testing whether the g_file_new_for_uri() correctly canonicalizes strings and two files equals (g_file_equal()) */ + g_test_add_func ("/g-file/test_g_file_new_for_uri", test_g_file_new_for_uri); + + /* Testing g_file_dup() equals original file via g_file_equal() */ + g_test_add_func ("/g-file/test_g_file_dup", test_g_file_dup); + + /* Testing g_file_get_parse_name() to return correct UTF-8 string */ + g_test_add_func ("/g-file/test_g_file_get_parse_name_utf8", test_g_file_get_parse_name_utf8); + + /* Testing g_file_new_for_commandline_arg() for correct relavive path resolution and correct path/URI guess */ + g_test_add_func ("/g-file/test_g_file_new_for_commandline_arg", test_g_file_new_for_commandline_arg); + + /* Testing g_file_has_prefix(), g_file_get_relative_path() and g_file_resolve_relative_path() to return and process correct relative paths */ + g_test_add_func ("/g-file/test_g_file_has_prefix", test_g_file_has_prefix); + + /* Testing g_file_get_parent() and g_file_get_child() */ + g_test_add_func ("/g-file/test_g_file_get_parent_child", test_g_file_get_parent_child); + + return g_test_run(); +} diff --git a/gio/tests/g-icon.c b/gio/tests/g-icon.c new file mode 100644 index 0000000..13985d6 --- /dev/null +++ b/gio/tests/g-icon.c @@ -0,0 +1,622 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Authors: David Zeuthen + */ + +#include +#include +#include +#include + +static void +test_g_icon_to_string (void) +{ + GIcon *icon; + GIcon *icon2; + GIcon *icon3; + GIcon *icon4; + GIcon *icon5; + GEmblem *emblem1; + GEmblem *emblem2; + const char *uri; + GFile *location; + char *data; + GError *error; + gint origin; + GIcon *i; + GFile *file; + + error = NULL; + + /* check that GFileIcon and GThemedIcon serialize to the encoding specified */ + + uri = "file:///some/native/path/to/an/icon.png"; + location = g_file_new_for_uri (uri); + icon = g_file_icon_new (location); + + g_object_get (icon, "file", &file, NULL); + g_assert (file == location); + g_object_unref (file); + + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, G_DIR_SEPARATOR_S "some" G_DIR_SEPARATOR_S "native" G_DIR_SEPARATOR_S "path" G_DIR_SEPARATOR_S "to" G_DIR_SEPARATOR_S "an" G_DIR_SEPARATOR_S "icon.png"); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (location); + + uri = "file:///some/native/path/to/an/icon with spaces.png"; + location = g_file_new_for_uri (uri); + icon = g_file_icon_new (location); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, G_DIR_SEPARATOR_S "some" G_DIR_SEPARATOR_S "native" G_DIR_SEPARATOR_S "path" G_DIR_SEPARATOR_S "to" G_DIR_SEPARATOR_S "an" G_DIR_SEPARATOR_S "icon with spaces.png"); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (location); + + uri = "sftp:///some/non-native/path/to/an/icon.png"; + location = g_file_new_for_uri (uri); + icon = g_file_icon_new (location); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, "sftp:///some/non-native/path/to/an/icon.png"); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (location); + +#if 0 + uri = "sftp:///some/non-native/path/to/an/icon with spaces.png"; + location = g_file_new_for_uri (uri); + icon = g_file_icon_new (location); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, "sftp:///some/non-native/path/to/an/icon%20with%20spaces.png"); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (location); +#endif + + icon = g_themed_icon_new_with_default_fallbacks ("some-icon-symbolic"); + g_themed_icon_append_name (G_THEMED_ICON (icon), "some-other-icon"); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, ". GThemedIcon " + "some-icon-symbolic some-symbolic some-other-icon some-other some " + "some-icon some-other-icon-symbolic some-other-symbolic"); + g_free (data); + g_object_unref (icon); + + icon = g_themed_icon_new ("network-server"); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, "network-server"); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + + icon = g_themed_icon_new_with_default_fallbacks ("network-server"); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, ". GThemedIcon network-server network network-server-symbolic network-symbolic"); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + + /* Check that we can serialize from well-known specified formats */ + icon = g_icon_new_for_string ("network-server%", &error); + g_assert_no_error (error); + icon2 = g_themed_icon_new ("network-server%"); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (icon); + g_object_unref (icon2); + + icon = g_icon_new_for_string ("/path/to/somewhere.png", &error); + g_assert_no_error (error); + location = g_file_new_for_commandline_arg ("/path/to/somewhere.png"); + icon2 = g_file_icon_new (location); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (location); + + icon = g_icon_new_for_string ("/path/to/somewhere with whitespace.png", &error); + g_assert_no_error (error); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, G_DIR_SEPARATOR_S "path" G_DIR_SEPARATOR_S "to" G_DIR_SEPARATOR_S "somewhere with whitespace.png"); + g_free (data); + location = g_file_new_for_commandline_arg ("/path/to/somewhere with whitespace.png"); + icon2 = g_file_icon_new (location); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (location); + g_object_unref (icon2); + location = g_file_new_for_commandline_arg ("/path/to/somewhere%20with%20whitespace.png"); + icon2 = g_file_icon_new (location); + g_assert (!g_icon_equal (icon, icon2)); + g_object_unref (location); + g_object_unref (icon2); + g_object_unref (icon); + + icon = g_icon_new_for_string ("sftp:///path/to/somewhere.png", &error); + g_assert_no_error (error); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, "sftp:///path/to/somewhere.png"); + g_free (data); + location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere.png"); + icon2 = g_file_icon_new (location); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (location); + +#if 0 + icon = g_icon_new_for_string ("sftp:///path/to/somewhere with whitespace.png", &error); + g_assert_no_error (error); + data = g_icon_to_string (icon); + g_assert_cmpstr (data, ==, "sftp:///path/to/somewhere%20with%20whitespace.png"); + g_free (data); + location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere with whitespace.png"); + icon2 = g_file_icon_new (location); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (location); + g_object_unref (icon2); + location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere%20with%20whitespace.png"); + icon2 = g_file_icon_new (location); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (location); + g_object_unref (icon2); + g_object_unref (icon); +#endif + + /* Check that GThemedIcon serialization works */ + + icon = g_themed_icon_new ("network-server"); + g_themed_icon_append_name (G_THEMED_ICON (icon), "computer"); + data = g_icon_to_string (icon); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + + icon = g_themed_icon_new ("icon name with whitespace"); + g_themed_icon_append_name (G_THEMED_ICON (icon), "computer"); + data = g_icon_to_string (icon); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + + icon = g_themed_icon_new_with_default_fallbacks ("network-server-xyz"); + g_themed_icon_append_name (G_THEMED_ICON (icon), "computer"); + data = g_icon_to_string (icon); + icon2 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon, icon2)); + g_free (data); + g_object_unref (icon); + g_object_unref (icon2); + + /* Check that GEmblemedIcon serialization works */ + + icon = g_themed_icon_new ("face-smirk"); + icon2 = g_themed_icon_new ("emblem-important"); + g_themed_icon_append_name (G_THEMED_ICON (icon2), "emblem-shared"); + location = g_file_new_for_uri ("file:///some/path/somewhere.png"); + icon3 = g_file_icon_new (location); + g_object_unref (location); + emblem1 = g_emblem_new_with_origin (icon2, G_EMBLEM_ORIGIN_DEVICE); + emblem2 = g_emblem_new_with_origin (icon3, G_EMBLEM_ORIGIN_LIVEMETADATA); + icon4 = g_emblemed_icon_new (icon, emblem1); + g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (icon4), emblem2); + data = g_icon_to_string (icon4); + icon5 = g_icon_new_for_string (data, &error); + g_assert_no_error (error); + g_assert (g_icon_equal (icon4, icon5)); + + g_object_get (emblem1, "origin", &origin, "icon", &i, NULL); + g_assert (origin == G_EMBLEM_ORIGIN_DEVICE); + g_assert (i == icon2); + g_object_unref (i); + + g_object_unref (emblem1); + g_object_unref (emblem2); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (icon3); + g_object_unref (icon4); + g_object_unref (icon5); + g_free (data); +} + +static void +test_g_icon_serialize (void) +{ + GIcon *icon; + GIcon *icon2; + GIcon *icon3; + GIcon *icon4; + GIcon *icon5; + GEmblem *emblem1; + GEmblem *emblem2; + GFile *location; + GVariant *data; + gint origin; + GIcon *i; + + /* Check that we can deserialize from well-known specified formats */ + data = g_variant_new_string ("network-server%"); + icon = g_icon_deserialize (g_variant_ref_sink (data)); + g_variant_unref (data); + icon2 = g_themed_icon_new ("network-server%"); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (icon); + g_object_unref (icon2); + + data = g_variant_new_string ("/path/to/somewhere.png"); + icon = g_icon_deserialize (g_variant_ref_sink (data)); + g_variant_unref (data); + location = g_file_new_for_commandline_arg ("/path/to/somewhere.png"); + icon2 = g_file_icon_new (location); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (location); + + data = g_variant_new_string ("/path/to/somewhere with whitespace.png"); + icon = g_icon_deserialize (g_variant_ref_sink (data)); + g_variant_unref (data); + location = g_file_new_for_commandline_arg ("/path/to/somewhere with whitespace.png"); + icon2 = g_file_icon_new (location); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (location); + g_object_unref (icon2); + location = g_file_new_for_commandline_arg ("/path/to/somewhere%20with%20whitespace.png"); + icon2 = g_file_icon_new (location); + g_assert (!g_icon_equal (icon, icon2)); + g_object_unref (location); + g_object_unref (icon2); + g_object_unref (icon); + + data = g_variant_new_string ("sftp:///path/to/somewhere.png"); + icon = g_icon_deserialize (g_variant_ref_sink (data)); + g_variant_unref (data); + location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere.png"); + icon2 = g_file_icon_new (location); + g_assert (g_icon_equal (icon, icon2)); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (location); + + /* Check that GThemedIcon serialization works */ + + icon = g_themed_icon_new ("network-server"); + g_themed_icon_append_name (G_THEMED_ICON (icon), "computer"); + data = g_icon_serialize (icon); + icon2 = g_icon_deserialize (data); + g_assert (g_icon_equal (icon, icon2)); + g_variant_unref (data); + g_object_unref (icon); + g_object_unref (icon2); + + icon = g_themed_icon_new ("icon name with whitespace"); + g_themed_icon_append_name (G_THEMED_ICON (icon), "computer"); + data = g_icon_serialize (icon); + icon2 = g_icon_deserialize (data); + g_assert (g_icon_equal (icon, icon2)); + g_variant_unref (data); + g_object_unref (icon); + g_object_unref (icon2); + + icon = g_themed_icon_new_with_default_fallbacks ("network-server-xyz"); + g_themed_icon_append_name (G_THEMED_ICON (icon), "computer"); + data = g_icon_serialize (icon); + icon2 = g_icon_deserialize (data); + g_assert (g_icon_equal (icon, icon2)); + g_variant_unref (data); + g_object_unref (icon); + g_object_unref (icon2); + + /* Check that GEmblemedIcon serialization works */ + + icon = g_themed_icon_new ("face-smirk"); + icon2 = g_themed_icon_new ("emblem-important"); + g_themed_icon_append_name (G_THEMED_ICON (icon2), "emblem-shared"); + location = g_file_new_for_uri ("file:///some/path/somewhere.png"); + icon3 = g_file_icon_new (location); + g_object_unref (location); + emblem1 = g_emblem_new_with_origin (icon2, G_EMBLEM_ORIGIN_DEVICE); + emblem2 = g_emblem_new_with_origin (icon3, G_EMBLEM_ORIGIN_LIVEMETADATA); + icon4 = g_emblemed_icon_new (icon, emblem1); + g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (icon4), emblem2); + data = g_icon_serialize (icon4); + icon5 = g_icon_deserialize (data); + g_assert (g_icon_equal (icon4, icon5)); + + g_object_get (emblem1, "origin", &origin, "icon", &i, NULL); + g_assert (origin == G_EMBLEM_ORIGIN_DEVICE); + g_assert (i == icon2); + g_object_unref (i); + + g_object_unref (emblem1); + g_object_unref (emblem2); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (icon3); + g_object_unref (icon4); + g_object_unref (icon5); + g_variant_unref (data); +} + +static void +test_themed_icon (void) +{ + GIcon *icon1, *icon2, *icon3, *icon4; + const gchar *const *names; + const gchar *names2[] = { "first-symbolic", "testicon", "last", NULL }; + gchar *str; + gboolean fallbacks; + GVariant *variant; + + icon1 = g_themed_icon_new ("testicon"); + + g_object_get (icon1, "use-default-fallbacks", &fallbacks, NULL); + g_assert (!fallbacks); + + names = g_themed_icon_get_names (G_THEMED_ICON (icon1)); + g_assert_cmpint (g_strv_length ((gchar **)names), ==, 2); + g_assert_cmpstr (names[0], ==, "testicon"); + g_assert_cmpstr (names[1], ==, "testicon-symbolic"); + + g_themed_icon_prepend_name (G_THEMED_ICON (icon1), "first-symbolic"); + g_themed_icon_append_name (G_THEMED_ICON (icon1), "last"); + names = g_themed_icon_get_names (G_THEMED_ICON (icon1)); + g_assert_cmpint (g_strv_length ((gchar **)names), ==, 6); + g_assert_cmpstr (names[0], ==, "first-symbolic"); + g_assert_cmpstr (names[1], ==, "testicon"); + g_assert_cmpstr (names[2], ==, "last"); + g_assert_cmpstr (names[3], ==, "first"); + g_assert_cmpstr (names[4], ==, "testicon-symbolic"); + g_assert_cmpstr (names[5], ==, "last-symbolic"); + g_assert_cmpuint (g_icon_hash (icon1), ==, 1812785139); + + icon2 = g_themed_icon_new_from_names ((gchar**)names2, -1); + g_assert (g_icon_equal (icon1, icon2)); + + str = g_icon_to_string (icon2); + icon3 = g_icon_new_for_string (str, NULL); + g_assert (g_icon_equal (icon2, icon3)); + g_free (str); + + variant = g_icon_serialize (icon3); + icon4 = g_icon_deserialize (variant); + g_assert (g_icon_equal (icon3, icon4)); + g_assert (g_icon_hash (icon3) == g_icon_hash (icon4)); + g_variant_unref (variant); + + g_object_unref (icon1); + g_object_unref (icon2); + g_object_unref (icon3); + g_object_unref (icon4); +} + +static void +test_emblemed_icon (void) +{ + GIcon *icon; + GIcon *icon1, *icon2, *icon3, *icon4, *icon5; + GEmblem *emblem, *emblem1, *emblem2; + GList *emblems; + GVariant *variant; + + icon1 = g_themed_icon_new ("testicon"); + icon2 = g_themed_icon_new ("testemblem"); + emblem1 = g_emblem_new (icon2); + emblem2 = g_emblem_new_with_origin (icon2, G_EMBLEM_ORIGIN_TAG); + + icon3 = g_emblemed_icon_new (icon1, emblem1); + emblems = g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon3)); + g_assert_cmpint (g_list_length (emblems), ==, 1); + g_assert (g_emblemed_icon_get_icon (G_EMBLEMED_ICON (icon3)) == icon1); + + icon4 = g_emblemed_icon_new (icon1, emblem1); + g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (icon4), emblem2); + emblems = g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon4)); + g_assert_cmpint (g_list_length (emblems), ==, 2); + + g_assert (!g_icon_equal (icon3, icon4)); + + variant = g_icon_serialize (icon4); + icon5 = g_icon_deserialize (variant); + g_assert (g_icon_equal (icon4, icon5)); + g_assert (g_icon_hash (icon4) == g_icon_hash (icon5)); + g_variant_unref (variant); + + emblem = emblems->data; + g_assert (g_emblem_get_icon (emblem) == icon2); + g_assert (g_emblem_get_origin (emblem) == G_EMBLEM_ORIGIN_UNKNOWN); + + emblem = emblems->next->data; + g_assert (g_emblem_get_icon (emblem) == icon2); + g_assert (g_emblem_get_origin (emblem) == G_EMBLEM_ORIGIN_TAG); + + g_emblemed_icon_clear_emblems (G_EMBLEMED_ICON (icon4)); + g_assert (g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon4)) == NULL); + + g_assert (g_icon_hash (icon4) != g_icon_hash (icon2)); + g_object_get (icon4, "gicon", &icon, NULL); + g_assert (icon == icon1); + g_object_unref (icon); + + g_object_unref (icon1); + g_object_unref (icon2); + g_object_unref (icon3); + g_object_unref (icon4); + g_object_unref (icon5); + + g_object_unref (emblem1); + g_object_unref (emblem2); +} + +static void +load_cb (GObject *source_object, + GAsyncResult *res, + gpointer data) +{ + GLoadableIcon *icon = G_LOADABLE_ICON (source_object); + GMainLoop *loop = data; + GError *error = NULL; + GInputStream *stream; + + stream = g_loadable_icon_load_finish (icon, res, NULL, &error); + g_assert_no_error (error); + g_assert (G_IS_INPUT_STREAM (stream)); + g_object_unref (stream); + g_main_loop_quit (loop); +} + +static void +loadable_icon_tests (GLoadableIcon *icon) +{ + GError *error = NULL; + GInputStream *stream; + GMainLoop *loop; + + stream = g_loadable_icon_load (icon, 20, NULL, NULL, &error); + g_assert_no_error (error); + g_assert (G_IS_INPUT_STREAM (stream)); + g_object_unref (stream); + + loop = g_main_loop_new (NULL, FALSE); + g_loadable_icon_load_async (icon, 20, NULL, load_cb, loop); + g_main_loop_run (loop); + g_main_loop_unref (loop); +} + +static void +test_file_icon (void) +{ + GFile *file; + GIcon *icon; + GIcon *icon2; + GIcon *icon3; + GIcon *icon4; + gchar *str; + GVariant *variant; + + file = g_file_new_for_path (g_test_get_filename (G_TEST_DIST, "g-icon.c", NULL)); + icon = g_file_icon_new (file); + g_object_unref (file); + + loadable_icon_tests (G_LOADABLE_ICON (icon)); + + str = g_icon_to_string (icon); + icon2 = g_icon_new_for_string (str, NULL); + g_assert (g_icon_equal (icon, icon2)); + g_free (str); + + file = g_file_new_for_path ("/\1\2\3/\244"); + icon4 = g_file_icon_new (file); + + variant = g_icon_serialize (icon4); + icon3 = g_icon_deserialize (variant); + g_assert (g_icon_equal (icon4, icon3)); + g_assert (g_icon_hash (icon4) == g_icon_hash (icon3)); + g_variant_unref (variant); + + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (icon3); + g_object_unref (icon4); + g_object_unref (file); +} + +static void +test_bytes_icon (void) +{ + GBytes *bytes; + GBytes *bytes2; + GIcon *icon; + GIcon *icon2; + GIcon *icon3; + GVariant *variant; + const gchar *data = "1234567890987654321"; + + bytes = g_bytes_new_static (data, strlen (data)); + icon = g_bytes_icon_new (bytes); + icon2 = g_bytes_icon_new (bytes); + + g_assert (g_bytes_icon_get_bytes (G_BYTES_ICON (icon)) == bytes); + g_assert (g_icon_equal (icon, icon2)); + g_assert (g_icon_hash (icon) == g_icon_hash (icon2)); + + g_object_get (icon, "bytes", &bytes2, NULL); + g_assert (bytes == bytes2); + g_bytes_unref (bytes2); + + variant = g_icon_serialize (icon); + icon3 = g_icon_deserialize (variant); + g_assert (g_icon_equal (icon, icon3)); + g_assert (g_icon_hash (icon) == g_icon_hash (icon3)); + + loadable_icon_tests (G_LOADABLE_ICON (icon)); + + g_variant_unref (variant); + g_object_unref (icon); + g_object_unref (icon2); + g_object_unref (icon3); + g_bytes_unref (bytes); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/icons/to-string", test_g_icon_to_string); + g_test_add_func ("/icons/serialize", test_g_icon_serialize); + g_test_add_func ("/icons/themed", test_themed_icon); + g_test_add_func ("/icons/emblemed", test_emblemed_icon); + g_test_add_func ("/icons/file", test_file_icon); + g_test_add_func ("/icons/bytes", test_bytes_icon); + + return g_test_run(); +} diff --git a/gio/tests/gapplication-example-actions.c b/gio/tests/gapplication-example-actions.c new file mode 100644 index 0000000..7aaa41e --- /dev/null +++ b/gio/tests/gapplication-example-actions.c @@ -0,0 +1,122 @@ +#include +#include +#include + +static void +activate (GApplication *application) +{ + g_application_hold (application); + g_print ("activated\n"); + g_application_release (application); +} + +static void +activate_action (GAction *action, + GVariant *parameter, + gpointer data) +{ + GApplication *application = G_APPLICATION (data); + + g_application_hold (application); + g_print ("action %s activated\n", g_action_get_name (action)); + g_application_release (application); +} + +static void +activate_toggle_action (GSimpleAction *action, + GVariant *parameter, + gpointer data) +{ + GApplication *application = G_APPLICATION (data); + GVariant *state; + gboolean b; + + g_print ("action %s activated\n", g_action_get_name (G_ACTION (action))); + + g_application_hold (application); + state = g_action_get_state (G_ACTION (action)); + b = g_variant_get_boolean (state); + g_variant_unref (state); + g_simple_action_set_state (action, g_variant_new_boolean (!b)); + g_print ("state change %d -> %d\n", b, !b); + g_application_release (application); +} + +static void +add_actions (GApplication *app) +{ + GSimpleAction *action; + + action = g_simple_action_new ("simple-action", NULL); + g_signal_connect (action, "activate", G_CALLBACK (activate_action), app); + g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (action)); + g_object_unref (action); + + action = g_simple_action_new_stateful ("toggle-action", NULL, + g_variant_new_boolean (FALSE)); + g_signal_connect (action, "activate", G_CALLBACK (activate_toggle_action), app); + g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (action)); + g_object_unref (action); +} + +static void +describe_and_activate_action (GActionGroup *group, + const gchar *name) +{ + const GVariantType *param_type; + GVariant *state; + gboolean enabled; + gchar *tmp; + + param_type = g_action_group_get_action_parameter_type (group, name); + state = g_action_group_get_action_state (group, name); + enabled = g_action_group_get_action_enabled (group, name); + + g_print ("action name: %s\n", name); + tmp = param_type ? g_variant_type_dup_string (param_type) : NULL; + g_print ("parameter type: %s\n", tmp ? tmp : ""); + g_free (tmp); + g_print ("state type: %s\n", + state ? g_variant_get_type_string (state) : ""); + tmp = state ? g_variant_print (state, FALSE) : NULL; + g_print ("state: %s\n", tmp ? tmp : ""); + g_free (tmp); + g_print ("enabled: %s\n", enabled ? "true" : "false"); + + if (state != NULL) + g_variant_unref (state); + + g_action_group_activate_action (group, name, NULL); +} + +int +main (int argc, char **argv) +{ + GApplication *app; + int status; + + app = g_application_new ("org.gtk.TestApplication", 0); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + g_application_set_inactivity_timeout (app, 10000); + + add_actions (app); + + if (argc > 1 && strcmp (argv[1], "--simple-action") == 0) + { + g_application_register (app, NULL, NULL); + describe_and_activate_action (G_ACTION_GROUP (app), "simple-action"); + exit (0); + } + else if (argc > 1 && strcmp (argv[1], "--toggle-action") == 0) + { + g_application_register (app, NULL, NULL); + describe_and_activate_action (G_ACTION_GROUP (app), "toggle-action"); + exit (0); + } + + status = g_application_run (app, argc, argv); + + g_object_unref (app); + + return status; +} diff --git a/gio/tests/gapplication-example-cmdline.c b/gio/tests/gapplication-example-cmdline.c new file mode 100644 index 0000000..99380cd --- /dev/null +++ b/gio/tests/gapplication-example-cmdline.c @@ -0,0 +1,43 @@ +#include +#include +#include + +static int +command_line (GApplication *application, + GApplicationCommandLine *cmdline) +{ + gchar **argv; + gint argc; + gint i; + + argv = g_application_command_line_get_arguments (cmdline, &argc); + + g_application_command_line_print (cmdline, + "This text is written back\n" + "to stdout of the caller\n"); + + for (i = 0; i < argc; i++) + g_print ("argument %d: %s\n", i, argv[i]); + + g_strfreev (argv); + + return 0; +} + +int +main (int argc, char **argv) +{ + GApplication *app; + int status; + + app = g_application_new ("org.gtk.TestApplication", + G_APPLICATION_HANDLES_COMMAND_LINE); + g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL); + g_application_set_inactivity_timeout (app, 10000); + + status = g_application_run (app, argc, argv); + + g_object_unref (app); + + return status; +} diff --git a/gio/tests/gapplication-example-cmdline2.c b/gio/tests/gapplication-example-cmdline2.c new file mode 100644 index 0000000..dc25e95 --- /dev/null +++ b/gio/tests/gapplication-example-cmdline2.c @@ -0,0 +1,106 @@ +#include +#include +#include + +static int +command_line (GApplication *application, + GApplicationCommandLine *cmdline) +{ + gchar **argv; + gint argc; + gint i; + + argv = g_application_command_line_get_arguments (cmdline, &argc); + + for (i = 0; i < argc; i++) + g_print ("handling argument %s remotely\n", argv[i]); + + g_strfreev (argv); + + return 0; +} + +static gboolean +test_local_cmdline (GApplication *application, + gchar ***arguments, + gint *exit_status) +{ + gint i, j; + gchar **argv; + + argv = *arguments; + + i = 1; + while (argv[i]) + { + if (g_str_has_prefix (argv[i], "--local-")) + { + g_print ("handling argument %s locally\n", argv[i]); + g_free (argv[i]); + for (j = i; argv[j]; j++) + argv[j] = argv[j + 1]; + } + else + { + g_print ("not handling argument %s locally\n", argv[i]); + i++; + } + } + + *exit_status = 0; + + return FALSE; +} + +typedef GApplication TestApplication; +typedef GApplicationClass TestApplicationClass; + +static GType test_application_get_type (void); +G_DEFINE_TYPE (TestApplication, test_application, G_TYPE_APPLICATION) + +static void +test_application_finalize (GObject *object) +{ + G_OBJECT_CLASS (test_application_parent_class)->finalize (object); +} + +static void +test_application_init (TestApplication *app) +{ +} + +static void +test_application_class_init (TestApplicationClass *class) +{ + G_OBJECT_CLASS (class)->finalize = test_application_finalize; + G_APPLICATION_CLASS (class)->local_command_line = test_local_cmdline; +} + +static GApplication * +test_application_new (const gchar *application_id, + GApplicationFlags flags) +{ + g_return_val_if_fail (g_application_id_is_valid (application_id), NULL); + + return g_object_new (test_application_get_type (), + "application-id", application_id, + "flags", flags, + NULL); +} + +int +main (int argc, char **argv) +{ + GApplication *app; + int status; + + app = test_application_new ("org.gtk.TestApplication", 0); + g_application_set_inactivity_timeout (app, 10000); + g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL); + + status = g_application_run (app, argc, argv); + + g_object_unref (app); + + return status; +} diff --git a/gio/tests/gapplication-example-cmdline3.c b/gio/tests/gapplication-example-cmdline3.c new file mode 100644 index 0000000..eecdc65 --- /dev/null +++ b/gio/tests/gapplication-example-cmdline3.c @@ -0,0 +1,106 @@ +#include +#include +#include + +static gboolean +my_cmdline_handler (gpointer data) +{ + GApplicationCommandLine *cmdline = data; + gchar **args; + gchar **argv; + gint argc; + gint arg1; + gboolean arg2; + gboolean help; + GOptionContext *context; + GOptionEntry entries[] = { + { "arg1", 0, 0, G_OPTION_ARG_INT, &arg1, NULL, NULL }, + { "arg2", 0, 0, G_OPTION_ARG_NONE, &arg2, NULL, NULL }, + { "help", '?', 0, G_OPTION_ARG_NONE, &help, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + GError *error; + gint i; + + args = g_application_command_line_get_arguments (cmdline, &argc); + + /* We have to make an extra copy of the array, since g_option_context_parse() + * assumes that it can remove strings from the array without freeing them. + */ + argv = g_new (gchar*, argc + 1); + for (i = 0; i <= argc; i++) + argv[i] = args[i]; + + context = g_option_context_new (NULL); + g_option_context_set_help_enabled (context, FALSE); + g_option_context_add_main_entries (context, entries, NULL); + + arg1 = 0; + arg2 = FALSE; + help = FALSE; + error = NULL; + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_application_command_line_printerr (cmdline, "%s\n", error->message); + g_error_free (error); + g_application_command_line_set_exit_status (cmdline, 1); + } + else if (help) + { + gchar *text; + text = g_option_context_get_help (context, FALSE, NULL); + g_application_command_line_print (cmdline, "%s", text); + g_free (text); + } + else + { + g_application_command_line_print (cmdline, "arg1 is %d and arg2 is %s\n", + arg1, arg2 ? "TRUE" : "FALSE"); + g_application_command_line_set_exit_status (cmdline, 0); + } + + g_free (argv); + g_strfreev (args); + + g_option_context_free (context); + + /* we are done handling this commandline */ + g_object_unref (cmdline); + + return G_SOURCE_REMOVE; +} + +static int +command_line (GApplication *application, + GApplicationCommandLine *cmdline) +{ + /* keep the application running until we are done with this commandline */ + g_application_hold (application); + + g_object_set_data_full (G_OBJECT (cmdline), + "application", application, + (GDestroyNotify)g_application_release); + + g_object_ref (cmdline); + g_idle_add (my_cmdline_handler, cmdline); + + return 0; +} + +int +main (int argc, char **argv) +{ + GApplication *app; + int status; + + app = g_application_new ("org.gtk.TestApplication", + G_APPLICATION_HANDLES_COMMAND_LINE); + g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL); + g_application_set_inactivity_timeout (app, 10000); + + status = g_application_run (app, argc, argv); + + g_object_unref (app); + + return status; +} diff --git a/gio/tests/gapplication-example-cmdline4.c b/gio/tests/gapplication-example-cmdline4.c new file mode 100644 index 0000000..ece2ee5 --- /dev/null +++ b/gio/tests/gapplication-example-cmdline4.c @@ -0,0 +1,85 @@ +#include +#include +#include + + +static gint +handle_local_options (GApplication *application, + GVariantDict *options, + gpointer user_data) +{ + guint32 count; + + /* Deal (locally) with version option */ + if (g_variant_dict_lookup (options, "version", "b", &count)) + { + g_print ("This is example-cmdline4, version 1.2.3\n"); + return EXIT_SUCCESS; + } + + return -1; + +} + +static gint +command_line (GApplication *application, + GApplicationCommandLine *cmdline, + gpointer user_data) +{ + guint32 count; + + GVariantDict *options = g_application_command_line_get_options_dict (cmdline); + + /* Deal with arg option */ + if (g_variant_dict_lookup (options, "flag", "b", &count)) + { + g_application_command_line_print (cmdline, "flag is set\n"); + } + + return EXIT_SUCCESS; +} + + +int +main (int argc, char **argv) +{ + GApplication *app; + int status; + + GOptionEntry entries[] = { + /* A version flag option, to be handled locally */ + { "version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "Show the application version", NULL }, + + /* A dummy flag option, to be handled in primary */ + { "flag", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "A flag argument", NULL }, + + G_OPTION_ENTRY_NULL + }; + + app = g_application_new ("org.gtk.TestApplication", + G_APPLICATION_HANDLES_COMMAND_LINE); + + g_application_add_main_option_entries (app, entries); + + g_application_set_option_context_parameter_string (app, "- a simple command line example"); + g_application_set_option_context_summary (app, + "Summary:\n" + "This is a simple command line --help example."); + g_application_set_option_context_description (app, + "Description:\n" + "This example illustrates the use of " + "g_application command line --help functionalities " + "(parameter string, summary, description). " + "It does nothing at all except displaying information " + "when invoked with --help argument...\n"); + + g_signal_connect (app, "handle-local-options", G_CALLBACK (handle_local_options), NULL); + g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL); + + /* This application does absolutely nothing, except if a command line is given */ + status = g_application_run (app, argc, argv); + + g_object_unref (app); + + return status; +} diff --git a/gio/tests/gapplication-example-dbushooks.c b/gio/tests/gapplication-example-dbushooks.c new file mode 100644 index 0000000..e93cf08 --- /dev/null +++ b/gio/tests/gapplication-example-dbushooks.c @@ -0,0 +1,97 @@ +#include +#include +#include + +static void +activate (GApplication *application) +{ + g_print ("activated\n"); + + /* Note: when doing a longer-lasting action here that returns + * to the mainloop, you should use g_application_hold() and + * g_application_release() to keep the application alive until + * the action is completed. + */ +} + +typedef GApplication TestApplication; +typedef GApplicationClass TestApplicationClass; + +static GType test_application_get_type (void); +G_DEFINE_TYPE (TestApplication, test_application, G_TYPE_APPLICATION) + +static gboolean +test_application_dbus_register (GApplication *application, + GDBusConnection *connection, + const gchar *object_path, + GError **error) +{ + /* We must chain up to the parent class */ + if (!G_APPLICATION_CLASS (test_application_parent_class)->dbus_register (application, + connection, + object_path, + error)) + return FALSE; + + /* Now we can do our own stuff here. For example, we could export some D-Bus objects */ + return TRUE; +} + +static void +test_application_dbus_unregister (GApplication *application, + GDBusConnection *connection, + const gchar *object_path) +{ + /* Do our own stuff here, e.g. unexport any D-Bus objects we exported in the dbus_register + * hook above. Be sure to check that we actually did export them, since the hook + * above might have returned early due to the parent class' hook returning FALSE! + */ + + /* Lastly, we must chain up to the parent class */ + G_APPLICATION_CLASS (test_application_parent_class)->dbus_unregister (application, + connection, + object_path); +} + +static void +test_application_init (TestApplication *app) +{ +} + +static void +test_application_class_init (TestApplicationClass *class) +{ + GApplicationClass *g_application_class = G_APPLICATION_CLASS (class); + + g_application_class->dbus_register = test_application_dbus_register; + g_application_class->dbus_unregister = test_application_dbus_unregister; +} + +static GApplication * +test_application_new (const gchar *application_id, + GApplicationFlags flags) +{ + g_return_val_if_fail (g_application_id_is_valid (application_id), NULL); + + return g_object_new (test_application_get_type (), + "application-id", application_id, + "flags", flags, + NULL); +} + +int +main (int argc, char **argv) +{ + GApplication *app; + int status; + + app = test_application_new ("org.gtk.TestApplication", 0); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + g_application_set_inactivity_timeout (app, 10000); + + status = g_application_run (app, argc, argv); + + g_object_unref (app); + + return status; +} diff --git a/gio/tests/gapplication-example-open.c b/gio/tests/gapplication-example-open.c new file mode 100644 index 0000000..6dcf53c --- /dev/null +++ b/gio/tests/gapplication-example-open.c @@ -0,0 +1,56 @@ +#include +#include +#include + +static void +activate (GApplication *application) +{ + g_print ("activated\n"); + + /* Note: when doing a longer-lasting action here that returns + * to the mainloop, you should use g_application_hold() and + * g_application_release() to keep the application alive until + * the action is completed. + */ +} + +static void +open (GApplication *application, + GFile **files, + gint n_files, + const gchar *hint) +{ + gint i; + + for (i = 0; i < n_files; i++) + { + gchar *uri = g_file_get_uri (files[i]); + g_print ("open %s\n", uri); + g_free (uri); + } + + /* Note: when doing a longer-lasting action here that returns + * to the mainloop, you should use g_application_hold() and + * g_application_release() to keep the application alive until + * the action is completed. + */ +} + +int +main (int argc, char **argv) +{ + GApplication *app; + int status; + + app = g_application_new ("org.gtk.TestApplication", + G_APPLICATION_HANDLES_OPEN); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + g_signal_connect (app, "open", G_CALLBACK (open), NULL); + g_application_set_inactivity_timeout (app, 10000); + + status = g_application_run (app, argc, argv); + + g_object_unref (app); + + return status; +} diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c new file mode 100644 index 0000000..6f1a27e --- /dev/null +++ b/gio/tests/gapplication.c @@ -0,0 +1,1230 @@ +#include +#include +#include +#include + +#include "gdbus-tests.h" +#include "gdbus-sessionbus.h" + +#if 0 +/* These tests are racy -- there is no guarantee about the order of data + * arriving over D-Bus. + * + * They're also a bit ridiculous -- GApplication was never meant to be + * abused in this way... + * + * We need new tests. + */ +static gint outstanding_watches; +static GMainLoop *main_loop; + +typedef struct +{ + gchar *expected_stdout; + gint stdout_pipe; + gchar *expected_stderr; + gint stderr_pipe; +} ChildData; + +static void +check_data (gint fd, const gchar *expected) +{ + gssize len, actual; + gchar *buffer; + + len = strlen (expected); + buffer = g_alloca (len + 100); + actual = read (fd, buffer, len + 100); + + g_assert_cmpint (actual, >=, 0); + + if (actual != len || + memcmp (buffer, expected, len) != 0) + { + buffer[MIN(len + 100, actual)] = '\0'; + + g_error ("\nExpected\n-----\n%s-----\nGot (%s)\n-----\n%s-----\n", + expected, + (actual > len) ? "truncated" : "full", buffer); + } +} + +static void +child_quit (GPid pid, + gint status, + gpointer data) +{ + ChildData *child = data; + + g_assert_cmpint (status, ==, 0); + + if (--outstanding_watches == 0) + g_main_loop_quit (main_loop); + + check_data (child->stdout_pipe, child->expected_stdout); + close (child->stdout_pipe); + g_free (child->expected_stdout); + + if (child->expected_stderr) + { + check_data (child->stderr_pipe, child->expected_stderr); + close (child->stderr_pipe); + g_free (child->expected_stderr); + } + + g_slice_free (ChildData, child); +} + +static void +spawn (const gchar *expected_stdout, + const gchar *expected_stderr, + const gchar *first_arg, + ...) +{ + GError *error = NULL; + const gchar *arg; + GPtrArray *array; + ChildData *data; + gchar **args; + va_list ap; + GPid pid; + GPollFD fd; + gchar **env; + + va_start (ap, first_arg); + array = g_ptr_array_new (); + g_ptr_array_add (array, g_test_build_filename (G_TEST_BUILT, "basic-application", NULL)); + for (arg = first_arg; arg; arg = va_arg (ap, const gchar *)) + g_ptr_array_add (array, g_strdup (arg)); + g_ptr_array_add (array, NULL); + args = (gchar **) g_ptr_array_free (array, FALSE); + va_end (ap); + + env = g_environ_setenv (g_get_environ (), "TEST", "1", TRUE); + + data = g_slice_new (ChildData); + data->expected_stdout = g_strdup (expected_stdout); + data->expected_stderr = g_strdup (expected_stderr); + + g_spawn_async_with_pipes (NULL, args, env, + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, &pid, NULL, + &data->stdout_pipe, + expected_stderr ? &data->stderr_pipe : NULL, + &error); + g_assert_no_error (error); + + g_strfreev (env); + + g_child_watch_add (pid, child_quit, data); + outstanding_watches++; + + /* we block until the children write to stdout to make sure + * they have started, as they need to be executed in order; + * see https://bugzilla.gnome.org/show_bug.cgi?id=664627 + */ + fd.fd = data->stdout_pipe; + fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR; + g_poll (&fd, 1, -1); +} + +static void +basic (void) +{ + GDBusConnection *c; + + g_assert (outstanding_watches == 0); + + session_bus_up (); + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + main_loop = g_main_loop_new (NULL, 0); + + /* spawn the main instance */ + spawn ("activated\n" + "open file:///a file:///b\n" + "exit status: 0\n", NULL, + "./app", NULL); + + /* send it some files */ + spawn ("exit status: 0\n", NULL, + "./app", "/a", "/b", NULL); + + g_main_loop_run (main_loop); + + g_object_unref (c); + session_bus_down (); + + g_main_loop_unref (main_loop); +} + +static void +test_remote_command_line (void) +{ + GDBusConnection *c; + GFile *file; + gchar *replies; + gchar *cwd; + + g_assert (outstanding_watches == 0); + + session_bus_up (); + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + main_loop = g_main_loop_new (NULL, 0); + + file = g_file_new_for_commandline_arg ("foo"); + cwd = g_get_current_dir (); + + replies = g_strconcat ("got ./cmd 0\n", + "got ./cmd 1\n", + "cmdline ./cmd echo --abc -d\n", + "environment TEST=1\n", + "getenv TEST=1\n", + "file ", g_file_get_path (file), "\n", + "properties ok\n", + "cwd ", cwd, "\n", + "busy\n", + "idle\n", + "stdin ok\n", + "exit status: 0\n", + NULL); + g_object_unref (file); + + /* spawn the main instance */ + spawn (replies, NULL, + "./cmd", NULL); + + g_free (replies); + + /* send it a few commandlines */ + spawn ("exit status: 0\n", NULL, + "./cmd", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "echo", "--abc", "-d", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "env", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "getenv", NULL); + + spawn ("print test\n" + "exit status: 0\n", NULL, + "./cmd", "print", "test", NULL); + + spawn ("exit status: 0\n", "printerr test\n", + "./cmd", "printerr", "test", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "file", "foo", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "properties", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "cwd", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "busy", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "idle", NULL); + + spawn ("exit status: 0\n", NULL, + "./cmd", "stdin", NULL); + + g_main_loop_run (main_loop); + + g_object_unref (c); + session_bus_down (); + + g_main_loop_unref (main_loop); +} + +static void +test_remote_actions (void) +{ + GDBusConnection *c; + + g_assert (outstanding_watches == 0); + + session_bus_up (); + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + main_loop = g_main_loop_new (NULL, 0); + + /* spawn the main instance */ + spawn ("got ./cmd 0\n" + "activate action1\n" + "change action2 1\n" + "exit status: 0\n", NULL, + "./cmd", NULL); + + spawn ("actions quit new action1 action2\n" + "exit status: 0\n", NULL, + "./actions", "list", NULL); + + spawn ("exit status: 0\n", NULL, + "./actions", "activate", NULL); + + spawn ("exit status: 0\n", NULL, + "./actions", "set-state", NULL); + + g_main_loop_run (main_loop); + + g_object_unref (c); + session_bus_down (); + + g_main_loop_unref (main_loop); +} +#endif + +#if 0 +/* Now that we register non-unique apps on the bus we need to fix the + * following test not to assume that it's safe to create multiple instances + * of the same app in one process. + * + * See https://bugzilla.gnome.org/show_bug.cgi?id=647986 for the patch that + * introduced this problem. + */ + +static GApplication *recently_activated; +static GMainLoop *loop; + +static void +nonunique_activate (GApplication *application) +{ + recently_activated = application; + + if (loop != NULL) + g_main_loop_quit (loop); +} + +static GApplication * +make_app (gboolean non_unique) +{ + GApplication *app; + gboolean ok; + + app = g_application_new ("org.gtk.Test-Application", + non_unique ? G_APPLICATION_NON_UNIQUE : 0); + g_signal_connect (app, "activate", G_CALLBACK (nonunique_activate), NULL); + ok = g_application_register (app, NULL, NULL); + if (!ok) + { + g_object_unref (app); + return NULL; + } + + g_application_activate (app); + + return app; +} + +static void +test_nonunique (void) +{ + GApplication *first, *second, *third, *fourth; + + session_bus_up (); + + first = make_app (TRUE); + /* non-remote because it is non-unique */ + g_assert (!g_application_get_is_remote (first)); + g_assert (recently_activated == first); + recently_activated = NULL; + + second = make_app (FALSE); + /* non-remote because it is first */ + g_assert (!g_application_get_is_remote (second)); + g_assert (recently_activated == second); + recently_activated = NULL; + + third = make_app (TRUE); + /* non-remote because it is non-unique */ + g_assert (!g_application_get_is_remote (third)); + g_assert (recently_activated == third); + recently_activated = NULL; + + fourth = make_app (FALSE); + /* should have failed to register due to being + * unable to register the object paths + */ + g_assert (fourth == NULL); + g_assert (recently_activated == NULL); + + g_object_unref (first); + g_object_unref (second); + g_object_unref (third); + + session_bus_down (); +} +#endif + +static void +properties (void) +{ + GDBusConnection *c; + GObject *app; + gchar *id; + GApplicationFlags flags; + gboolean registered; + guint timeout; + gboolean remote; + gboolean ret; + GError *error = NULL; + + session_bus_up (); + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + app = g_object_new (G_TYPE_APPLICATION, + "application-id", "org.gtk.TestApplication", + NULL); + + g_object_get (app, + "application-id", &id, + "flags", &flags, + "is-registered", ®istered, + "inactivity-timeout", &timeout, + NULL); + + g_assert_cmpstr (id, ==, "org.gtk.TestApplication"); + g_assert_cmpint (flags, ==, G_APPLICATION_FLAGS_NONE); + g_assert (!registered); + g_assert_cmpint (timeout, ==, 0); + + ret = g_application_register (G_APPLICATION (app), NULL, &error); + g_assert (ret); + g_assert_no_error (error); + + g_object_get (app, + "is-registered", ®istered, + "is-remote", &remote, + NULL); + + g_assert (registered); + g_assert (!remote); + + g_object_set (app, + "inactivity-timeout", 1000, + NULL); + + g_application_quit (G_APPLICATION (app)); + + g_object_unref (c); + g_object_unref (app); + g_free (id); + + session_bus_down (); +} + +static void +appid (void) +{ + gchar *id; + + g_assert_false (g_application_id_is_valid ("")); + g_assert_false (g_application_id_is_valid (".")); + g_assert_false (g_application_id_is_valid ("a")); + g_assert_false (g_application_id_is_valid ("abc")); + g_assert_false (g_application_id_is_valid (".abc")); + g_assert_false (g_application_id_is_valid ("abc.")); + g_assert_false (g_application_id_is_valid ("a..b")); + g_assert_false (g_application_id_is_valid ("a/b")); + g_assert_false (g_application_id_is_valid ("a\nb")); + g_assert_false (g_application_id_is_valid ("a\nb")); + g_assert_false (g_application_id_is_valid ("emoji_picker")); + g_assert_false (g_application_id_is_valid ("emoji-picker")); + g_assert_false (g_application_id_is_valid ("emojipicker")); + g_assert_false (g_application_id_is_valid ("my.Terminal.0123")); + id = g_new0 (gchar, 261); + memset (id, 'a', 260); + id[1] = '.'; + id[260] = 0; + g_assert_false (g_application_id_is_valid (id)); + g_free (id); + + g_assert_true (g_application_id_is_valid ("a.b")); + g_assert_true (g_application_id_is_valid ("A.B")); + g_assert_true (g_application_id_is_valid ("A-.B")); + g_assert_true (g_application_id_is_valid ("a_b.c-d")); + g_assert_true (g_application_id_is_valid ("_a.b")); + g_assert_true (g_application_id_is_valid ("-a.b")); + g_assert_true (g_application_id_is_valid ("org.gnome.SessionManager")); + g_assert_true (g_application_id_is_valid ("my.Terminal._0123")); + g_assert_true (g_application_id_is_valid ("com.example.MyApp")); + g_assert_true (g_application_id_is_valid ("com.example.internal_apps.Calculator")); + g_assert_true (g_application_id_is_valid ("org._7_zip.Archiver")); +} + +static gboolean nodbus_activated; + +static gboolean +release_app (gpointer user_data) +{ + g_application_release (user_data); + return G_SOURCE_REMOVE; +} + +static void +nodbus_activate (GApplication *app) +{ + nodbus_activated = TRUE; + g_application_hold (app); + + g_assert (g_application_get_dbus_connection (app) == NULL); + g_assert (g_application_get_dbus_object_path (app) == NULL); + + g_idle_add (release_app, app); +} + +static void +test_nodbus (void) +{ + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, NULL }; + GApplication *app; + + app = g_application_new ("org.gtk.Unimportant", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (nodbus_activate), NULL); + g_application_run (app, 1, argv); + g_object_unref (app); + + g_assert (nodbus_activated); + g_free (binpath); +} + +static gboolean noappid_activated; + +static void +noappid_activate (GApplication *app) +{ + noappid_activated = TRUE; + g_application_hold (app); + + g_assert (g_application_get_flags (app) & G_APPLICATION_NON_UNIQUE); + + g_idle_add (release_app, app); +} + +/* test that no appid -> non-unique */ +static void +test_noappid (void) +{ + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, NULL }; + GApplication *app; + + app = g_application_new (NULL, G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (noappid_activate), NULL); + g_application_run (app, 1, argv); + g_object_unref (app); + + g_assert (noappid_activated); + g_free (binpath); +} + +static gboolean activated; +static gboolean quitted; + +static gboolean +quit_app (gpointer user_data) +{ + quitted = TRUE; + g_application_quit (user_data); + return G_SOURCE_REMOVE; +} + +static void +quit_activate (GApplication *app) +{ + activated = TRUE; + g_application_hold (app); + + g_assert (g_application_get_dbus_connection (app) != NULL); + g_assert (g_application_get_dbus_object_path (app) != NULL); + + g_idle_add (quit_app, app); +} + +static void +test_quit (void) +{ + GDBusConnection *c; + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, NULL }; + GApplication *app; + + session_bus_up (); + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + app = g_application_new ("org.gtk.Unimportant", + G_APPLICATION_FLAGS_NONE); + activated = FALSE; + quitted = FALSE; + g_signal_connect (app, "activate", G_CALLBACK (quit_activate), NULL); + g_application_run (app, 1, argv); + g_object_unref (app); + g_object_unref (c); + + g_assert (activated); + g_assert (quitted); + + session_bus_down (); + g_free (binpath); +} + +typedef struct +{ + gboolean shutdown; + GParamSpec *notify_spec; /* (owned) (nullable) */ +} RegisteredData; + +static void +on_registered_shutdown (GApplication *app, + gpointer user_data) +{ + RegisteredData *registered_data = user_data; + + registered_data->shutdown = TRUE; +} + +static void +on_registered_notify (GApplication *app, + GParamSpec *spec, + gpointer user_data) +{ + RegisteredData *registered_data = user_data; + registered_data->notify_spec = g_param_spec_ref (spec); + + if (g_application_get_is_registered (app)) + g_assert_false (registered_data->shutdown); + else + g_assert_true (registered_data->shutdown); +} + +static void +test_registered (void) +{ + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, NULL }; + RegisteredData registered_data = { FALSE, NULL }; + GApplication *app; + + app = g_application_new (NULL, G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (noappid_activate), NULL); + g_signal_connect (app, "shutdown", G_CALLBACK (on_registered_shutdown), ®istered_data); + g_signal_connect (app, "notify::is-registered", G_CALLBACK (on_registered_notify), ®istered_data); + + g_assert_null (registered_data.notify_spec); + + g_assert_true (g_application_register (app, NULL, NULL)); + g_assert_true (g_application_get_is_registered (app)); + + g_assert_nonnull (registered_data.notify_spec); + g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered"); + g_clear_pointer (®istered_data.notify_spec, g_param_spec_unref); + + g_assert_false (registered_data.shutdown); + + g_application_run (app, 1, argv); + + g_assert_true (registered_data.shutdown); + g_assert_false (g_application_get_is_registered (app)); + g_assert_nonnull (registered_data.notify_spec); + g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered"); + g_clear_pointer (®istered_data.notify_spec, g_param_spec_unref); + + /* Register it again */ + registered_data.shutdown = FALSE; + g_assert_true (g_application_register (app, NULL, NULL)); + g_assert_true (g_application_get_is_registered (app)); + g_assert_nonnull (registered_data.notify_spec); + g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered"); + g_clear_pointer (®istered_data.notify_spec, g_param_spec_unref); + g_assert_false (registered_data.shutdown); + + g_object_unref (app); + + g_free (binpath); +} + +static void +on_activate (GApplication *app) +{ + gchar **actions; + GAction *action; + GVariant *state; + + g_assert (!g_application_get_is_remote (app)); + + actions = g_action_group_list_actions (G_ACTION_GROUP (app)); + g_assert (g_strv_length (actions) == 0); + g_strfreev (actions); + + action = (GAction*)g_simple_action_new_stateful ("test", G_VARIANT_TYPE_BOOLEAN, g_variant_new_boolean (FALSE)); + g_action_map_add_action (G_ACTION_MAP (app), action); + + actions = g_action_group_list_actions (G_ACTION_GROUP (app)); + g_assert (g_strv_length (actions) == 1); + g_strfreev (actions); + + g_action_group_change_action_state (G_ACTION_GROUP (app), "test", g_variant_new_boolean (TRUE)); + state = g_action_group_get_action_state (G_ACTION_GROUP (app), "test"); + g_assert (g_variant_get_boolean (state) == TRUE); + + action = g_action_map_lookup_action (G_ACTION_MAP (app), "test"); + g_assert (action != NULL); + + g_action_map_remove_action (G_ACTION_MAP (app), "test"); + + actions = g_action_group_list_actions (G_ACTION_GROUP (app)); + g_assert (g_strv_length (actions) == 0); + g_strfreev (actions); +} + +static void +test_local_actions (void) +{ + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, NULL }; + GApplication *app; + + app = g_application_new ("org.gtk.Unimportant", + G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL); + g_application_run (app, 1, argv); + g_object_unref (app); + g_free (binpath); +} + +typedef GApplication TestLocCmdApp; +typedef GApplicationClass TestLocCmdAppClass; + +static GType test_loc_cmd_app_get_type (void); +G_DEFINE_TYPE (TestLocCmdApp, test_loc_cmd_app, G_TYPE_APPLICATION) + +static void +test_loc_cmd_app_init (TestLocCmdApp *app) +{ +} + +static void +test_loc_cmd_app_startup (GApplication *app) +{ + g_assert_not_reached (); +} + +static void +test_loc_cmd_app_shutdown (GApplication *app) +{ + g_assert_not_reached (); +} + +static gboolean +test_loc_cmd_app_local_command_line (GApplication *application, + gchar ***arguments, + gint *exit_status) +{ + return TRUE; +} + +static void +test_loc_cmd_app_class_init (TestLocCmdAppClass *klass) +{ + G_APPLICATION_CLASS (klass)->startup = test_loc_cmd_app_startup; + G_APPLICATION_CLASS (klass)->shutdown = test_loc_cmd_app_shutdown; + G_APPLICATION_CLASS (klass)->local_command_line = test_loc_cmd_app_local_command_line; +} + +static void +test_local_command_line (void) +{ + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, "-invalid", NULL }; + GApplication *app; + + app = g_object_new (test_loc_cmd_app_get_type (), + "application-id", "org.gtk.Unimportant", + "flags", G_APPLICATION_FLAGS_NONE, + NULL); + g_application_run (app, 1, argv); + g_object_unref (app); + g_free (binpath); +} + +static void +test_resource_path (void) +{ + GApplication *app; + + app = g_application_new ("x.y.z", 0); + g_assert_cmpstr (g_application_get_resource_base_path (app), ==, "/x/y/z"); + + /* this should not change anything */ + g_application_set_application_id (app, "a.b.c"); + g_assert_cmpstr (g_application_get_resource_base_path (app), ==, "/x/y/z"); + + /* but this should... */ + g_application_set_resource_base_path (app, "/x"); + g_assert_cmpstr (g_application_get_resource_base_path (app), ==, "/x"); + + /* ... and this */ + g_application_set_resource_base_path (app, NULL); + g_assert_cmpstr (g_application_get_resource_base_path (app), ==, NULL); + + g_object_unref (app); + + /* Make sure that overriding at construction time works properly */ + app = g_object_new (G_TYPE_APPLICATION, "application-id", "x.y.z", "resource-base-path", "/a", NULL); + g_assert_cmpstr (g_application_get_resource_base_path (app), ==, "/a"); + g_object_unref (app); + + /* ... particularly if we override to NULL */ + app = g_object_new (G_TYPE_APPLICATION, "application-id", "x.y.z", "resource-base-path", NULL, NULL); + g_assert_cmpstr (g_application_get_resource_base_path (app), ==, NULL); + g_object_unref (app); +} + +static gint +test_help_command_line (GApplication *app, + GApplicationCommandLine *command_line, + gpointer user_data) +{ + gboolean *called = user_data; + + *called = TRUE; + + return 0; +} + +/* Test whether --help is handled when HANDLES_COMMND_LINE is set and + * options have been added. + */ +static void +test_help (void) +{ + if (g_test_subprocess ()) + { + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, "--help", NULL }; + GApplication *app; + gboolean called = FALSE; + int status; + + app = g_application_new ("org.gtk.TestApplication", G_APPLICATION_HANDLES_COMMAND_LINE); + g_application_add_main_option (app, "foo", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, "", ""); + g_signal_connect (app, "command-line", G_CALLBACK (test_help_command_line), &called); + + status = g_application_run (app, G_N_ELEMENTS (argv) -1, argv); + g_assert (called == TRUE); + g_assert_cmpint (status, ==, 0); + + g_object_unref (app); + g_free (binpath); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Application options*"); +} + +static void +test_busy (void) +{ + GApplication *app; + + /* use GSimpleAction to bind to the busy state, because it's easy to + * create and has an easily modifiable boolean property */ + GSimpleAction *action1; + GSimpleAction *action2; + + session_bus_up (); + + app = g_application_new ("org.gtk.TestApplication", G_APPLICATION_NON_UNIQUE); + g_assert (g_application_register (app, NULL, NULL)); + + g_assert (!g_application_get_is_busy (app)); + g_application_mark_busy (app); + g_assert (g_application_get_is_busy (app)); + g_application_unmark_busy (app); + g_assert (!g_application_get_is_busy (app)); + + action1 = g_simple_action_new ("action", NULL); + g_application_bind_busy_property (app, action1, "enabled"); + g_assert (g_application_get_is_busy (app)); + + g_simple_action_set_enabled (action1, FALSE); + g_assert (!g_application_get_is_busy (app)); + + g_application_mark_busy (app); + g_assert (g_application_get_is_busy (app)); + + action2 = g_simple_action_new ("action", NULL); + g_application_bind_busy_property (app, action2, "enabled"); + g_assert (g_application_get_is_busy (app)); + + g_application_unmark_busy (app); + g_assert (g_application_get_is_busy (app)); + + g_object_unref (action2); + g_assert (!g_application_get_is_busy (app)); + + g_simple_action_set_enabled (action1, TRUE); + g_assert (g_application_get_is_busy (app)); + + g_application_mark_busy (app); + g_assert (g_application_get_is_busy (app)); + + g_application_unbind_busy_property (app, action1, "enabled"); + g_assert (g_application_get_is_busy (app)); + + g_application_unmark_busy (app); + g_assert (!g_application_get_is_busy (app)); + + g_object_unref (action1); + g_object_unref (app); + + session_bus_down (); +} + +/* + * Test that handle-local-options works as expected + */ + +static gint +test_local_options (GApplication *app, + GVariantDict *options, + gpointer data) +{ + gboolean *called = data; + + *called = TRUE; + + if (g_variant_dict_contains (options, "success")) + return 0; + else if (g_variant_dict_contains (options, "failure")) + return 1; + else + return -1; +} + +static gint +second_handler (GApplication *app, + GVariantDict *options, + gpointer data) +{ + gboolean *called = data; + + *called = TRUE; + + return 2; +} + +static void +test_handle_local_options_success (void) +{ + if (g_test_subprocess ()) + { + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, "--success", NULL }; + GApplication *app; + gboolean called = FALSE; + gboolean called2 = FALSE; + int status; + + app = g_application_new ("org.gtk.TestApplication", 0); + g_application_add_main_option (app, "success", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, "", ""); + g_application_add_main_option (app, "failure", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, "", ""); + g_signal_connect (app, "handle-local-options", G_CALLBACK (test_local_options), &called); + g_signal_connect (app, "handle-local-options", G_CALLBACK (second_handler), &called2); + + status = g_application_run (app, G_N_ELEMENTS (argv) -1, argv); + g_assert (called); + g_assert (!called2); + g_assert_cmpint (status, ==, 0); + + g_object_unref (app); + g_free (binpath); + return; + } + + g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR); + g_test_trap_assert_passed (); +} + +static void +test_handle_local_options_failure (void) +{ + if (g_test_subprocess ()) + { + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, "--failure", NULL }; + GApplication *app; + gboolean called = FALSE; + gboolean called2 = FALSE; + int status; + + app = g_application_new ("org.gtk.TestApplication", 0); + g_application_add_main_option (app, "success", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, "", ""); + g_application_add_main_option (app, "failure", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, "", ""); + g_signal_connect (app, "handle-local-options", G_CALLBACK (test_local_options), &called); + g_signal_connect (app, "handle-local-options", G_CALLBACK (second_handler), &called2); + + status = g_application_run (app, G_N_ELEMENTS (argv) -1, argv); + g_assert (called); + g_assert (!called2); + g_assert_cmpint (status, ==, 1); + + g_object_unref (app); + g_free (binpath); + return; + } + + g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR); + g_test_trap_assert_passed (); +} + +static void +test_handle_local_options_passthrough (void) +{ + if (g_test_subprocess ()) + { + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, NULL }; + GApplication *app; + gboolean called = FALSE; + gboolean called2 = FALSE; + int status; + + app = g_application_new ("org.gtk.TestApplication", 0); + g_application_add_main_option (app, "success", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, "", ""); + g_application_add_main_option (app, "failure", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, "", ""); + g_signal_connect (app, "handle-local-options", G_CALLBACK (test_local_options), &called); + g_signal_connect (app, "handle-local-options", G_CALLBACK (second_handler), &called2); + + status = g_application_run (app, G_N_ELEMENTS (argv) -1, argv); + g_assert (called); + g_assert (called2); + g_assert_cmpint (status, ==, 2); + + g_object_unref (app); + g_free (binpath); + return; + } + + g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR); + g_test_trap_assert_passed (); +} + +static void +test_api (void) +{ + GApplication *app; + GSimpleAction *action; + + app = g_application_new ("org.gtk.TestApplication", 0); + + /* add an action without a name */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*assertion*failed*"); + action = g_simple_action_new (NULL, NULL); + g_assert (action == NULL); + g_test_assert_expected_messages (); + + /* also, gapplication shouldn't accept actions without names */ + action = g_object_new (G_TYPE_SIMPLE_ACTION, NULL); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*action has no name*"); + g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (action)); + g_test_assert_expected_messages (); + + g_object_unref (action); + g_object_unref (app); +} + +/* Check that G_APPLICATION_ALLOW_REPLACEMENT works. To do so, we launch + * a GApplication in this process that allows replacement, and then + * launch a subprocess with --gapplication-replace. We have to do our + * own async version of g_test_trap_subprocess() here since we need + * the main process to keep spinning its mainloop. + */ + +static gboolean +name_was_lost (GApplication *app, + gboolean *called) +{ + *called = TRUE; + g_application_quit (app); + return TRUE; +} + +static void +startup_in_subprocess (GApplication *app, + gboolean *called) +{ + *called = TRUE; +} + +typedef struct +{ + gboolean allow_replacement; + GSubprocess *subprocess; +} TestReplaceData; + +static void +startup_cb (GApplication *app, + TestReplaceData *data) +{ + const char *argv[] = { NULL, "--verbose", "--quiet", "-p", NULL, "--GTestSubprocess", NULL }; + GSubprocessLauncher *launcher; + GError *local_error = NULL; + + g_application_hold (app); + + argv[0] = g_get_prgname (); + + if (data->allow_replacement) + argv[4] = "/gapplication/replace"; + else + argv[4] = "/gapplication/no-replace"; + + /* Now that we are the primary instance, launch our replacement. + * We inherit the environment to share the test session bus. + */ + g_test_message ("launching subprocess"); + + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); + g_subprocess_launcher_set_environ (launcher, NULL); + data->subprocess = g_subprocess_launcher_spawnv (launcher, argv, &local_error); + g_assert_no_error (local_error); + g_object_unref (launcher); + + if (!data->allow_replacement) + { + /* make sure we exit after a bit, if the subprocess is not replacing us */ + g_application_set_inactivity_timeout (app, 500); + g_application_release (app); + } +} + +static void +activate (gpointer data) +{ + /* GApplication complains if we don't connect to ::activate */ +} + +static gboolean +quit_already (gpointer data) +{ + GApplication *app = data; + + g_application_quit (app); + + return G_SOURCE_REMOVE; +} + +static void +test_replace (gconstpointer data) +{ + gboolean allow = GPOINTER_TO_INT (data); + + if (g_test_subprocess ()) + { + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + char *argv[] = { binpath, "--gapplication-replace", NULL }; + GApplication *app; + gboolean startup = FALSE; + + app = g_application_new ("org.gtk.TestApplication.Replace", G_APPLICATION_ALLOW_REPLACEMENT); + g_signal_connect (app, "startup", G_CALLBACK (startup_in_subprocess), &startup); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + + g_application_run (app, G_N_ELEMENTS (argv) - 1, argv); + + if (allow) + g_assert_true (startup); + else + g_assert_false (startup); + + g_object_unref (app); + g_free (binpath); + } + else + { + char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); + gchar *argv[] = { binpath, NULL }; + GApplication *app; + gboolean name_lost = FALSE; + TestReplaceData data; + GTestDBus *bus; + + data.allow_replacement = allow; + data.subprocess = NULL; + + bus = g_test_dbus_new (0); + g_test_dbus_up (bus); + + app = g_application_new ("org.gtk.TestApplication.Replace", allow ? G_APPLICATION_ALLOW_REPLACEMENT : G_APPLICATION_FLAGS_NONE); + g_application_set_inactivity_timeout (app, 500); + g_signal_connect (app, "name-lost", G_CALLBACK (name_was_lost), &name_lost); + g_signal_connect (app, "startup", G_CALLBACK (startup_cb), &data); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + + if (!allow) + g_timeout_add_seconds (1, quit_already, app); + + g_application_run (app, G_N_ELEMENTS (argv) - 1, argv); + + g_assert_nonnull (data.subprocess); + if (allow) + g_assert_true (name_lost); + else + g_assert_false (name_lost); + + g_object_unref (app); + g_free (binpath); + + g_subprocess_wait (data.subprocess, NULL, NULL); + g_clear_object (&data.subprocess); + + g_test_dbus_down (bus); + g_object_unref (bus); + } +} + +int +main (int argc, char **argv) +{ + g_setenv ("LC_ALL", "C", TRUE); + + g_test_init (&argc, &argv, NULL); + + if (!g_test_subprocess ()) + g_test_dbus_unset (); + + g_test_add_func ("/gapplication/no-dbus", test_nodbus); +/* g_test_add_func ("/gapplication/basic", basic); */ + g_test_add_func ("/gapplication/no-appid", test_noappid); +/* g_test_add_func ("/gapplication/non-unique", test_nonunique); */ + g_test_add_func ("/gapplication/properties", properties); + g_test_add_func ("/gapplication/app-id", appid); + g_test_add_func ("/gapplication/quit", test_quit); + g_test_add_func ("/gapplication/registered", test_registered); + g_test_add_func ("/gapplication/local-actions", test_local_actions); +/* g_test_add_func ("/gapplication/remote-actions", test_remote_actions); */ + g_test_add_func ("/gapplication/local-command-line", test_local_command_line); +/* g_test_add_func ("/gapplication/remote-command-line", test_remote_command_line); */ + g_test_add_func ("/gapplication/resource-path", test_resource_path); + g_test_add_func ("/gapplication/test-help", test_help); + g_test_add_func ("/gapplication/test-busy", test_busy); + g_test_add_func ("/gapplication/test-handle-local-options1", test_handle_local_options_success); + g_test_add_func ("/gapplication/test-handle-local-options2", test_handle_local_options_failure); + g_test_add_func ("/gapplication/test-handle-local-options3", test_handle_local_options_passthrough); + g_test_add_func ("/gapplication/api", test_api); + g_test_add_data_func ("/gapplication/replace", GINT_TO_POINTER (TRUE), test_replace); + g_test_add_data_func ("/gapplication/no-replace", GINT_TO_POINTER (FALSE), test_replace); + + return g_test_run (); +} diff --git a/gio/tests/gdbus-address-get-session.c b/gio/tests/gdbus-address-get-session.c new file mode 100644 index 0000000..72de2c7 --- /dev/null +++ b/gio/tests/gdbus-address-get-session.c @@ -0,0 +1,227 @@ +/* GLib testing framework examples and tests + * + * Copyright © 2015 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +/* This test does NOT depend on any dbus binaries preinstalled on test host. + * On Unix it uses mock environment (test_xdg_runtime) + * or mock dbus-launch binary (test_x11_autolaunch). + * On Windows it relies on the fact that libgio provides + * internal session dbus-server on win32. + */ + +#include + +#include +#include +#include + +static void +print_address (void) +{ + GError *error = NULL; + gchar *addr; + + addr = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, + &error); + + g_assert_no_error (error); + g_assert_nonnull (addr); + g_print ("%s\n", addr); + g_free (addr); +} + +#ifdef G_OS_UNIX + +static GSocket *mock_bus = NULL; +static gchar *mock_bus_path = NULL; +/* this is deliberately something that needs escaping */ +static gchar tmpdir[] = "/tmp/gdbus,unix,test.XXXXXX"; + +static void +set_up_mock_xdg_runtime_dir (void) +{ + GError *error = NULL; + GSocketAddress *addr; + + mock_bus = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, + &error); + g_assert_no_error (error); + g_assert_true (G_IS_SOCKET (mock_bus)); + + /* alters tmpdir in-place */ + if (g_mkdtemp_full (tmpdir, 0700) == NULL) + { + int errsv = errno; + g_error ("g_mkdtemp_full: %s", g_strerror (errsv)); + } + + mock_bus_path = g_strconcat (tmpdir, "/bus", NULL); + addr = g_unix_socket_address_new (mock_bus_path); + g_socket_bind (mock_bus, addr, FALSE, &error); + g_assert_no_error (error); + g_object_unref (addr); + + g_setenv ("XDG_RUNTIME_DIR", tmpdir, TRUE); +} + +static void +tear_down_mock_xdg_runtime_dir (void) +{ + GError *error = NULL; + + g_socket_close (mock_bus, &error); + g_assert_no_error (error); + + if (g_unlink (mock_bus_path) < 0) + { + int errsv = errno; + g_error ("g_unlink(\"%s\"): %s", mock_bus_path, g_strerror (errsv)); + } + + if (g_rmdir (tmpdir) < 0) + { + int errsv = errno; + g_error ("g_rmdir(\"%s\"): %s", tmpdir, g_strerror (errsv)); + } + + g_clear_object (&mock_bus); + g_clear_pointer (&mock_bus_path, g_free); +} + +static gchar *path = NULL; + +static void +set_up_mock_dbus_launch (void) +{ + path = g_strconcat (g_test_get_dir (G_TEST_BUILT), ":", + g_getenv ("PATH"), NULL); + g_setenv ("PATH", path, TRUE); + + /* libdbus won't even try X11 autolaunch if DISPLAY is unset; GDBus + * does the same in Debian derivatives (proposed upstream in + * GNOME#723506) */ + g_setenv ("DISPLAY", "an unrealistic mock X11 display", TRUE); +} + +static void +tear_down_mock_dbus_launch (void) +{ + g_clear_pointer (&path, g_free); +} + +static void +test_x11_autolaunch (void) +{ + if (g_test_subprocess ()) + { + g_unsetenv ("DISPLAY"); + g_unsetenv ("DBUS_SESSION_BUS_ADDRESS"); + g_unsetenv ("XDG_RUNTIME_DIR"); + g_unsetenv ("G_MESSAGES_DEBUG"); + set_up_mock_dbus_launch (); + + print_address (); + + tear_down_mock_dbus_launch (); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_stderr_unmatched ("?*"); + g_test_trap_assert_stdout ("hello:this=address-is-from-the,mock=dbus-launch\n"); + g_test_trap_assert_passed (); +} + +static void +test_xdg_runtime (void) +{ + if (g_test_subprocess ()) + { + g_unsetenv ("DISPLAY"); + g_unsetenv ("DBUS_SESSION_BUS_ADDRESS"); + set_up_mock_xdg_runtime_dir (); + set_up_mock_dbus_launch (); + + print_address (); + + tear_down_mock_dbus_launch (); + tear_down_mock_xdg_runtime_dir (); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_stderr_unmatched ("?*"); + g_test_trap_assert_stdout ("unix:path=/tmp/gdbus%2Cunix%2Ctest.*/bus\n"); + g_test_trap_assert_passed (); +} + +#endif + +#ifdef G_OS_WIN32 +static void +check_and_cleanup_autolaunched_win32_bus (void) +{ + /* win32 autostarted bus runs infinitely if no client ever connected. + * However it exits in several seconds if the last client disconnects. + * _This_ test only checks successful launching and connectivity, + * and don't bother on bus termination behavior (being it a bug or not). + * So connect+disconnect here is not only connectivity test, + * but also the workaround the bus process infinite run. + */ + GError *err = NULL; + GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &err); + g_assert_no_error (err); + g_object_unref (bus); +} + +static void +test_win32_autolaunch (void) +{ + if (g_test_subprocess ()) + { + print_address (); + + check_and_cleanup_autolaunched_win32_bus (); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + /* stderr is not checked: coverage prints warnings there */ + g_test_trap_assert_stdout ("nonce-tcp:host=localhost,port=*,noncefile=*\\gdbus-nonce-file-*\n"); + g_test_trap_assert_passed (); +} +#endif + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + +#ifdef G_OS_UNIX + g_test_add_func ("/gdbus/x11-autolaunch", test_x11_autolaunch); + g_test_add_func ("/gdbus/xdg-runtime", test_xdg_runtime); +#endif + +#ifdef G_OS_WIN32 + g_test_add_func ("/gdbus/win32-autolaunch", test_win32_autolaunch); +#endif + + return g_test_run (); +} diff --git a/gio/tests/gdbus-addresses.c b/gio/tests/gdbus-addresses.c new file mode 100644 index 0000000..dbff79c --- /dev/null +++ b/gio/tests/gdbus-addresses.c @@ -0,0 +1,223 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include + +#ifdef G_OS_UNIX +#include +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_empty_address (void) +{ + GError *error; + error = NULL; + g_dbus_address_get_stream_sync ("", + NULL, + NULL, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_error_free (error); +} + +/* Test that g_dbus_is_supported_address() returns FALSE for an unparsable + * address. */ +static void +test_unsupported_address (void) +{ + GError *error = NULL; + + g_assert_false (g_dbus_is_supported_address (";", &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_clear_error (&error); +} + +static void +assert_is_supported_address (const gchar *address) +{ + GError *error = NULL; + + g_assert_true (g_dbus_is_address (address)); + + g_assert_true (g_dbus_is_supported_address (address, NULL)); + g_assert_true (g_dbus_is_supported_address (address, &error)); + g_assert_no_error (error); +} + +static void +assert_not_supported_address (const gchar *address) +{ + GError *error = NULL; + + g_assert_true (g_dbus_is_address (address)); + + g_assert_false (g_dbus_is_supported_address (address, NULL)); + g_assert_false (g_dbus_is_supported_address (address, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_clear_error (&error); +} + +/* Test that g_dbus_is_address() returns FALSE for various differently invalid + * input strings. */ +static void +test_address_parsing (void) +{ + assert_not_supported_address ("some-imaginary-transport:foo=bar"); + g_assert_true (g_dbus_is_address ("some-imaginary-transport:foo=bar")); + + assert_not_supported_address ("some-imaginary-transport:foo=bar;unix:path=/this/is/valid"); + + g_assert_false (g_dbus_is_address ("")); + g_assert_false (g_dbus_is_address (";")); + g_assert_false (g_dbus_is_address (":")); + g_assert_false (g_dbus_is_address ("=:;")); + g_assert_false (g_dbus_is_address (":=;:=")); + g_assert_false (g_dbus_is_address ("transport-name:=")); + g_assert_false (g_dbus_is_address ("transport-name:=bar")); + + g_assert_false (g_dbus_is_address ("transport-name:foo")); + g_assert_false (g_dbus_is_address ("transport-name:foo=%00")); + g_assert_false (g_dbus_is_address ("transport-name:%00=bar")); + + assert_not_supported_address ("magic-tractor:"); +} + +static void +test_unix_address (void) +{ +#ifndef G_OS_UNIX + g_test_skip ("unix transport is not supported on non-Unix platforms"); +#else + assert_is_supported_address ("unix:path=/tmp/dbus-test"); + assert_is_supported_address ("unix:path=/tmp/dbus-test,guid=0"); + assert_is_supported_address ("unix:abstract=/tmp/dbus-another-test"); + assert_is_supported_address ("unix:abstract=/tmp/dbus-another-test,guid=1000"); + assert_not_supported_address ("unix:foo=bar"); + g_assert_false (g_dbus_is_address ("unix:path=/foo;abstract=/bar")); + assert_is_supported_address ("unix:path=/tmp/concrete;unix:abstract=/tmp/abstract"); + assert_is_supported_address ("unix:tmpdir=/tmp"); + assert_is_supported_address ("unix:dir=/tmp"); + assert_not_supported_address ("unix:tmpdir=/tmp,path=/tmp"); + assert_not_supported_address ("unix:tmpdir=/tmp,abstract=/tmp/foo"); + assert_not_supported_address ("unix:tmpdir=/tmp,dir=/tmp"); + assert_not_supported_address ("unix:path=/tmp,abstract=/tmp/foo"); + assert_not_supported_address ("unix:path=/tmp,dir=/tmp"); + assert_not_supported_address ("unix:abstract=/tmp/foo,dir=/tmp"); + assert_not_supported_address ("unix:"); +#endif +} + +static void +test_nonce_tcp_address (void) +{ + assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar"); + assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,guid=0"); + assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=ipv6"); + assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=ipv4"); + assert_is_supported_address ("nonce-tcp:host=localhost"); + assert_is_supported_address ("nonce-tcp:host=localhost,guid=1000"); + + assert_not_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=blah"); + assert_not_supported_address ("nonce-tcp:host=localhost,port=420000,noncefile=/foo/bar,family=ipv4"); + assert_not_supported_address ("nonce-tcp:host=,port=x42,noncefile=/foo/bar,family=ipv4"); + assert_not_supported_address ("nonce-tcp:host=,port=42x,noncefile=/foo/bar,family=ipv4"); + assert_not_supported_address ("nonce-tcp:host=,port=420000,noncefile=/foo/bar,family=ipv4"); + assert_not_supported_address ("nonce-tcp:meaningless-key=blah"); + assert_not_supported_address ("nonce-tcp:host=localhost,port=-1"); + assert_not_supported_address ("nonce-tcp:host=localhost,port=420000"); + assert_not_supported_address ("nonce-tcp:host=localhost,port=42x"); + assert_not_supported_address ("nonce-tcp:host=localhost,port="); + assert_not_supported_address ("nonce-tcp:host=localhost,port=42,noncefile="); +} + +static void +test_tcp_address (void) +{ + assert_is_supported_address ("tcp:host=localhost"); + assert_is_supported_address ("tcp:host=localhost,guid=1000"); + assert_not_supported_address ("tcp:host=localhost,noncefile=/tmp/foo"); + assert_is_supported_address ("tcp:host=localhost,port=42"); + assert_is_supported_address ("tcp:host=localhost,port=42,guid=1000"); + assert_not_supported_address ("tcp:host=localhost,port=-1"); + assert_not_supported_address ("tcp:host=localhost,port=420000"); + assert_not_supported_address ("tcp:host=localhost,port=42x"); + assert_not_supported_address ("tcp:host=localhost,port="); + assert_is_supported_address ("tcp:host=localhost,port=42,family=ipv4"); + assert_is_supported_address ("tcp:host=localhost,port=42,family=ipv6"); + assert_not_supported_address ("tcp:host=localhost,port=42,family=sopranos"); +} + +static void +test_autolaunch_address (void) +{ + assert_is_supported_address ("autolaunch:"); +} + +static void +test_mixed_address (void) +{ + assert_is_supported_address ("unix:path=/tmp/dbus1;unix:path=/tmp/dbus2"); + assert_is_supported_address ("tcp:host=localhost,port=42;autolaunch:"); + assert_not_supported_address ("tcp:host=localhost,port=42;tcp:family=bla"); +} + +static const struct { const char *before; const char *after; } escaping[] = { + { "foo", "foo" }, + { "/.\\-_", "/.\\-_" }, + { "<=>", "%3C%3D%3E" }, + { "/foo~1", "/foo%7E1" }, + { "\xe2\x98\xad\xff", "%E2%98%AD%FF" }, + { NULL, NULL } +}; + +static void +test_escape_address (void) +{ + gsize i; + + for (i = 0; escaping[i].before != NULL; i++) + { + gchar *s = g_dbus_address_escape_value (escaping[i].before); + + g_assert_cmpstr (s, ==, escaping[i].after); + g_free (s); + } +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gdbus/empty-address", test_empty_address); + g_test_add_func ("/gdbus/unsupported-address", test_unsupported_address); + g_test_add_func ("/gdbus/address-parsing", test_address_parsing); + g_test_add_func ("/gdbus/unix-address", test_unix_address); + g_test_add_func ("/gdbus/nonce-tcp-address", test_nonce_tcp_address); + g_test_add_func ("/gdbus/tcp-address", test_tcp_address); + g_test_add_func ("/gdbus/autolaunch-address", test_autolaunch_address); + g_test_add_func ("/gdbus/mixed-address", test_mixed_address); + g_test_add_func ("/gdbus/escape-address", test_escape_address); + + return g_test_run(); +} diff --git a/gio/tests/gdbus-auth.c b/gio/tests/gdbus-auth.c new file mode 100644 index 0000000..eabfdd3 --- /dev/null +++ b/gio/tests/gdbus-auth.c @@ -0,0 +1,314 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include + +#include +#include + +#include "gdbus-tests.h" + +#ifdef G_OS_UNIX +#include +#include +#include +#include +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +server_on_allow_mechanism (GDBusAuthObserver *observer, + const gchar *mechanism, + gpointer user_data) +{ + const gchar *allowed_mechanism = user_data; + if (allowed_mechanism == NULL || g_strcmp0 (mechanism, allowed_mechanism) == 0) + return TRUE; + else + return FALSE; +} + +/* pass NULL to allow any mechanism */ +static GDBusServer * +server_new_for_mechanism (const gchar *allowed_mechanism) +{ + gchar *addr; + gchar *guid; + GDBusServer *server; + GDBusAuthObserver *auth_observer; + GError *error; + GDBusServerFlags flags; + + guid = g_dbus_generate_guid (); + +#ifdef G_OS_UNIX + if (g_unix_socket_address_abstract_names_supported ()) + { + addr = g_strdup ("unix:tmpdir=/tmp/gdbus-test-"); + } + else + { + gchar *tmpdir; + tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); + addr = g_strdup_printf ("unix:tmpdir=%s", tmpdir); + g_free (tmpdir); + } +#else + addr = g_strdup ("nonce-tcp:"); +#endif + + auth_observer = g_dbus_auth_observer_new (); + + flags = G_DBUS_SERVER_FLAGS_NONE; + if (g_strcmp0 (allowed_mechanism, "ANONYMOUS") == 0) + flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; + + error = NULL; + server = g_dbus_server_new_sync (addr, + flags, + guid, + auth_observer, + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert (server != NULL); + + g_signal_connect (auth_observer, + "allow-mechanism", + G_CALLBACK (server_on_allow_mechanism), + (gpointer) allowed_mechanism); + + g_free (addr); + g_free (guid); + g_object_unref (auth_observer); + + return server; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +test_auth_on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + GMainLoop *loop = user_data; + g_main_loop_quit (loop); + return FALSE; +} + +static gboolean +test_auth_on_timeout (gpointer user_data) +{ + g_error ("Timeout waiting for client"); + g_assert_not_reached (); + return G_SOURCE_REMOVE; +} + + +typedef struct +{ + const gchar *address; + const gchar *allowed_client_mechanism; + const gchar *allowed_server_mechanism; +} TestAuthData; + +static gpointer +test_auth_client_thread_func (gpointer user_data) +{ + TestAuthData *data = user_data; + GDBusConnection *c = NULL; + GError *error = NULL; + GDBusAuthObserver *auth_observer = NULL; + + auth_observer = g_dbus_auth_observer_new (); + + g_signal_connect (auth_observer, + "allow-mechanism", + G_CALLBACK (server_on_allow_mechanism), + (gpointer) data->allowed_client_mechanism); + + c = g_dbus_connection_new_for_address_sync (data->address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + auth_observer, + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_assert (c != NULL); + g_clear_object (&c); + g_clear_object (&auth_observer); + return NULL; +} + +static void +test_auth_mechanism (const gchar *allowed_client_mechanism, + const gchar *allowed_server_mechanism) +{ + GDBusServer *server; + GMainLoop *loop; + GThread *client_thread; + TestAuthData data; + guint timeout_id; + + server = server_new_for_mechanism (allowed_server_mechanism); + + loop = g_main_loop_new (NULL, FALSE); + + g_signal_connect (server, + "new-connection", + G_CALLBACK (test_auth_on_new_connection), + loop); + + timeout_id = g_timeout_add_seconds (5, test_auth_on_timeout, NULL); + + data.allowed_client_mechanism = allowed_client_mechanism; + data.allowed_server_mechanism = allowed_server_mechanism; + data.address = g_dbus_server_get_client_address (server); + + /* run the D-Bus client in a thread */ + client_thread = g_thread_new ("gdbus-client-thread", + test_auth_client_thread_func, + &data); + + g_dbus_server_start (server); + + g_main_loop_run (loop); + + g_dbus_server_stop (server); + + g_thread_join (client_thread); + g_source_remove (timeout_id); + + while (g_main_context_iteration (NULL, FALSE)); + g_main_loop_unref (loop); + + g_object_unref (server); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +auth_client_external (void) +{ + test_auth_mechanism ("EXTERNAL", NULL); +} + +static void +auth_client_dbus_cookie_sha1 (void) +{ + test_auth_mechanism ("DBUS_COOKIE_SHA1", NULL); +} + +static void +auth_server_anonymous (void) +{ + test_auth_mechanism (NULL, "ANONYMOUS"); +} + +static void +auth_server_external (void) +{ + test_auth_mechanism (NULL, "EXTERNAL"); +} + +static void +auth_server_dbus_cookie_sha1 (void) +{ + test_auth_mechanism (NULL, "DBUS_COOKIE_SHA1"); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar *temp_dbus_keyrings_dir = NULL; + +static void +temp_dbus_keyrings_setup (void) +{ + GError *error = NULL; + + g_assert (temp_dbus_keyrings_dir == NULL); + temp_dbus_keyrings_dir = g_dir_make_tmp ("gdbus-test-dbus-keyrings-XXXXXX", &error); + g_assert_no_error (error); + g_assert (temp_dbus_keyrings_dir != NULL); + g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR", temp_dbus_keyrings_dir, TRUE); + g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION", "1", TRUE); +} + +static void +temp_dbus_keyrings_teardown (void) +{ + GDir *dir; + GError *error = NULL; + const gchar *name; + + g_assert (temp_dbus_keyrings_dir != NULL); + + dir = g_dir_open (temp_dbus_keyrings_dir, 0, &error); + g_assert_no_error (error); + g_assert (dir != NULL); + while ((name = g_dir_read_name (dir)) != NULL) + { + gchar *path = g_build_filename (temp_dbus_keyrings_dir, name, NULL); + g_assert (unlink (path) == 0); + g_free (path); + } + g_dir_close (dir); + g_assert (rmdir (temp_dbus_keyrings_dir) == 0); + + g_free (temp_dbus_keyrings_dir); + temp_dbus_keyrings_dir = NULL; + g_unsetenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR"); + g_unsetenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION"); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + setlocale (LC_ALL, "C"); + + temp_dbus_keyrings_setup (); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gdbus/auth/client/EXTERNAL", auth_client_external); + g_test_add_func ("/gdbus/auth/client/DBUS_COOKIE_SHA1", auth_client_dbus_cookie_sha1); + g_test_add_func ("/gdbus/auth/server/ANONYMOUS", auth_server_anonymous); + g_test_add_func ("/gdbus/auth/server/EXTERNAL", auth_server_external); + g_test_add_func ("/gdbus/auth/server/DBUS_COOKIE_SHA1", auth_server_dbus_cookie_sha1); + + /* TODO: we currently don't have tests for + * + * - DBUS_COOKIE_SHA1 timeouts (and clock changes etc) + * - interoperability with libdbus-1 implementations of authentication methods (both client and server) + */ + + ret = g_test_run(); + + temp_dbus_keyrings_teardown (); + + return ret; +} diff --git a/gio/tests/gdbus-bz627724.c b/gio/tests/gdbus-bz627724.c new file mode 100644 index 0000000..c668192 --- /dev/null +++ b/gio/tests/gdbus-bz627724.c @@ -0,0 +1,87 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +static GDBusConnection *the_connection = NULL; + +#define MY_TYPE_OBJECT (my_object_get_type ()) +#define MY_OBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MY_TYPE_OBJECT, MyObject)) +#define MY_IS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MY_TYPE_OBJECT)) + +typedef struct { + GObject parent_instance; +} MyObject; + +typedef struct { + GObjectClass parent_class; +} MyObjectClass; + +GType my_object_get_type (void) G_GNUC_CONST; + +G_DEFINE_TYPE (MyObject, my_object, G_TYPE_OBJECT) + +static void +my_object_init (MyObject *object) +{ +} + +static void +my_object_class_init (MyObjectClass *klass) +{ + GError *error; + error = NULL; + the_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, + NULL, /* GCancellable* */ + &error); + g_assert_no_error (error); + g_assert (G_IS_DBUS_CONNECTION (the_connection)); +} + +static void +test_bz627724 (void) +{ + MyObject *object; + + session_bus_up (); + g_assert (the_connection == NULL); + object = g_object_new (MY_TYPE_OBJECT, NULL); + g_assert (the_connection != NULL); + g_object_unref (the_connection); + g_object_unref (object); + session_bus_down (); +} + + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_dbus_unset (); + + g_test_add_func ("/gdbus/bz627724", test_bz627724); + return g_test_run(); +} diff --git a/gio/tests/gdbus-close-pending.c b/gio/tests/gdbus-close-pending.c new file mode 100644 index 0000000..bd8fda5 --- /dev/null +++ b/gio/tests/gdbus-close-pending.c @@ -0,0 +1,394 @@ +/* GDBus regression test - close a stream when a message remains to be written + * + * Copyright © 2006-2010 Red Hat, Inc. + * Copyright © 2011 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Simon McVittie + */ + +#include + +#include +#include + +#include + +#ifdef G_OS_UNIX +# include + +# include +# include +# include +# include +#else +# error This test is currently Unix-specific due to use of g_unix_open_pipe() +#endif + +#include "gdbus-tests.h" + +#define CLOSE_TIME_MS 1 +#define N_REPEATS_SLOW 5000 +#define N_REPEATS 100 + +/* ---------- MyIOStream ------------------------------------------------- */ + +#define MY_TYPE_IO_STREAM (my_io_stream_get_type ()) +#define MY_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MY_TYPE_IO_STREAM, MyIOStream)) +#define MY_IS_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MY_TYPE_IO_STREAM)) + +typedef struct +{ + GIOStream parent_instance; + GInputStream *input_stream; + GOutputStream *output_stream; +} MyIOStream; + +typedef struct +{ + GIOStreamClass parent_class; +} MyIOStreamClass; + +static GType my_io_stream_get_type (void) G_GNUC_CONST; + +G_DEFINE_TYPE (MyIOStream, my_io_stream, G_TYPE_IO_STREAM) + +static void +my_io_stream_finalize (GObject *object) +{ + MyIOStream *stream = MY_IO_STREAM (object); + g_object_unref (stream->input_stream); + g_object_unref (stream->output_stream); + G_OBJECT_CLASS (my_io_stream_parent_class)->finalize (object); +} + +static void +my_io_stream_init (MyIOStream *stream) +{ +} + +static GInputStream * +my_io_stream_get_input_stream (GIOStream *_stream) +{ + MyIOStream *stream = MY_IO_STREAM (_stream); + return stream->input_stream; +} + +static GOutputStream * +my_io_stream_get_output_stream (GIOStream *_stream) +{ + MyIOStream *stream = MY_IO_STREAM (_stream); + return stream->output_stream; +} + +static void +my_io_stream_class_init (MyIOStreamClass *klass) +{ + GObjectClass *gobject_class; + GIOStreamClass *giostream_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = my_io_stream_finalize; + + giostream_class = G_IO_STREAM_CLASS (klass); + giostream_class->get_input_stream = my_io_stream_get_input_stream; + giostream_class->get_output_stream = my_io_stream_get_output_stream; +} + +static GIOStream * +my_io_stream_new (GInputStream *input_stream, + GOutputStream *output_stream) +{ + MyIOStream *stream; + g_return_val_if_fail (G_IS_INPUT_STREAM (input_stream), NULL); + g_return_val_if_fail (G_IS_OUTPUT_STREAM (output_stream), NULL); + stream = MY_IO_STREAM (g_object_new (MY_TYPE_IO_STREAM, NULL)); + stream->input_stream = g_object_ref (input_stream); + stream->output_stream = g_object_ref (output_stream); + return G_IO_STREAM (stream); +} + +/* ---------- MySlowCloseOutputStream ------------------------------------ */ + +typedef struct +{ + GFilterOutputStream parent_instance; +} MySlowCloseOutputStream; + +typedef struct +{ + GFilterOutputStreamClass parent_class; +} MySlowCloseOutputStreamClass; + +#define MY_TYPE_SLOW_CLOSE_OUTPUT_STREAM \ + (my_slow_close_output_stream_get_type ()) +#define MY_OUTPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), MY_TYPE_SLOW_CLOSE_OUTPUT_STREAM, \ + MySlowCloseOutputStream)) +#define MY_IS_SLOW_CLOSE_OUTPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), MY_TYPE_SLOW_CLOSE_OUTPUT_STREAM)) + +static GType my_slow_close_output_stream_get_type (void) G_GNUC_CONST; + +G_DEFINE_TYPE (MySlowCloseOutputStream, my_slow_close_output_stream, + G_TYPE_FILTER_OUTPUT_STREAM) + +static void +my_slow_close_output_stream_init (MySlowCloseOutputStream *stream) +{ +} + +static gboolean +my_slow_close_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + g_usleep (CLOSE_TIME_MS * 1000); + return G_OUTPUT_STREAM_CLASS (my_slow_close_output_stream_parent_class)-> + close_fn (stream, cancellable, error); +} + +typedef struct { + GOutputStream *stream; + gint io_priority; + GCancellable *cancellable; + GAsyncReadyCallback callback; + gpointer user_data; +} DelayedClose; + +static void +delayed_close_free (gpointer data) +{ + DelayedClose *df = data; + + g_object_unref (df->stream); + if (df->cancellable) + g_object_unref (df->cancellable); + g_free (df); +} + +static gboolean +delayed_close_cb (gpointer data) +{ + DelayedClose *df = data; + + G_OUTPUT_STREAM_CLASS (my_slow_close_output_stream_parent_class)-> + close_async (df->stream, df->io_priority, df->cancellable, df->callback, + df->user_data); + + return G_SOURCE_REMOVE; +} + +static void +my_slow_close_output_stream_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSource *later; + DelayedClose *df; + + df = g_new0 (DelayedClose, 1); + df->stream = g_object_ref (stream); + df->io_priority = io_priority; + df->cancellable = (cancellable != NULL ? g_object_ref (cancellable) : NULL); + df->callback = callback; + df->user_data = user_data; + + later = g_timeout_source_new (CLOSE_TIME_MS); + g_source_set_callback (later, delayed_close_cb, df, delayed_close_free); + g_source_attach (later, g_main_context_get_thread_default ()); +} + +static gboolean +my_slow_close_output_stream_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + return G_OUTPUT_STREAM_CLASS (my_slow_close_output_stream_parent_class)-> + close_finish (stream, result, error); +} + +static void +my_slow_close_output_stream_class_init (MySlowCloseOutputStreamClass *klass) +{ + GOutputStreamClass *ostream_class; + + ostream_class = G_OUTPUT_STREAM_CLASS (klass); + ostream_class->close_fn = my_slow_close_output_stream_close; + ostream_class->close_async = my_slow_close_output_stream_close_async; + ostream_class->close_finish = my_slow_close_output_stream_close_finish; +} + +static GIOStream * +my_io_stream_new_for_fds (gint fd_in, gint fd_out) +{ + GIOStream *stream; + GInputStream *input_stream; + GOutputStream *real_output_stream; + GOutputStream *output_stream; + + input_stream = g_unix_input_stream_new (fd_in, TRUE); + real_output_stream = g_unix_output_stream_new (fd_out, TRUE); + output_stream = g_object_new (MY_TYPE_SLOW_CLOSE_OUTPUT_STREAM, + "base-stream", real_output_stream, + NULL); + stream = my_io_stream_new (input_stream, output_stream); + g_object_unref (input_stream); + g_object_unref (output_stream); + g_object_unref (real_output_stream); + return stream; +} + +/* ---------- Tests ------------------------------------------------------ */ + +typedef struct { + gint server_to_client[2]; + gint client_to_server[2]; + GIOStream *server_iostream; + GDBusConnection *server_conn; + GIOStream *iostream; + GDBusConnection *connection; + gchar *guid; + GError *error; +} Fixture; + +static void +setup (Fixture *f, + gconstpointer context) +{ + f->guid = g_dbus_generate_guid (); +} + +static void +teardown (Fixture *f, + gconstpointer context) +{ + g_clear_object (&f->server_iostream); + g_clear_object (&f->server_conn); + g_clear_object (&f->iostream); + g_clear_object (&f->connection); + g_clear_error (&f->error); + g_free (f->guid); +} + +static void +on_new_conn (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GDBusConnection **connection = user_data; + GError *error = NULL; + + *connection = g_dbus_connection_new_for_address_finish (res, &error); + g_assert_no_error (error); +} + +static void +test_once (Fixture *f, + gconstpointer context) +{ + GDBusMessage *message; + gboolean pipe_res; + + pipe_res = g_unix_open_pipe (f->server_to_client, FD_CLOEXEC, &f->error); + g_assert (pipe_res); + pipe_res = g_unix_open_pipe (f->client_to_server, FD_CLOEXEC, &f->error); + g_assert (pipe_res); + + f->server_iostream = my_io_stream_new_for_fds (f->client_to_server[0], + f->server_to_client[1]); + f->iostream = my_io_stream_new_for_fds (f->server_to_client[0], + f->client_to_server[1]); + + g_dbus_connection_new (f->server_iostream, + f->guid, + (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS), + NULL /* auth observer */, + NULL /* cancellable */, + on_new_conn, &f->server_conn); + + g_dbus_connection_new (f->iostream, + NULL, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL /* auth observer */, + NULL /* cancellable */, + on_new_conn, &f->connection); + + while (f->server_conn == NULL || f->connection == NULL) + g_main_context_iteration (NULL, TRUE); + + /* + * queue a message - it'll sometimes be sent while the close is pending, + * triggering the bug + */ + message = g_dbus_message_new_signal ("/", "com.example.Foo", "Bar"); + g_dbus_connection_send_message (f->connection, message, 0, NULL, &f->error); + g_assert_no_error (f->error); + g_object_unref (message); + + /* close the connection (deliberately or via last-unref) */ + if (g_strcmp0 (context, "unref") == 0) + { + g_clear_object (&f->connection); + } + else + { + g_dbus_connection_close_sync (f->connection, NULL, &f->error); + g_assert_no_error (f->error); + } + + /* either way, wait for the connection to close */ + while (!g_dbus_connection_is_closed (f->server_conn)) + g_main_context_iteration (NULL, TRUE); + + /* clean up before the next run */ + g_clear_object (&f->iostream); + g_clear_object (&f->server_iostream); + g_clear_object (&f->connection); + g_clear_object (&f->server_conn); + g_clear_error (&f->error); +} + +static void +test_many_times (Fixture *f, + gconstpointer context) +{ + guint i, n_repeats; + + if (g_test_slow ()) + n_repeats = N_REPEATS_SLOW; + else + n_repeats = N_REPEATS; + + for (i = 0; i < n_repeats; i++) + test_once (f, context); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add ("/gdbus/close-pending", Fixture, "close", + setup, test_many_times, teardown); + g_test_add ("/gdbus/unref-pending", Fixture, "unref", + setup, test_many_times, teardown); + + return g_test_run(); +} diff --git a/gio/tests/gdbus-connection-flush-helper.c b/gio/tests/gdbus-connection-flush-helper.c new file mode 100644 index 0000000..172f3e8 --- /dev/null +++ b/gio/tests/gdbus-connection-flush-helper.c @@ -0,0 +1,56 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include + +int +main (int argc, + char *argv[]) +{ + GDBusConnection *c; + GError *error; + gboolean ret; + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, + NULL, /* GCancellable* */ + &error); + g_assert_no_error (error); + + error = NULL; + g_dbus_connection_emit_signal (c, + NULL, /* const gchar *destination_bus_name */ + "/org/gtk/GDBus/FlushObject", + "org.gtk.GDBus.FlushInterface", + "SomeSignal", + NULL, /* GVariant *parameters */ + &error); + g_assert_no_error (error); + + error = NULL; + ret = g_dbus_connection_flush_sync (c, + NULL, /* GCancellable* */ + &error); + g_assert_no_error (error); + g_assert (ret); + + /* and now exit immediately! */ + return 0; +} diff --git a/gio/tests/gdbus-connection-flush.c b/gio/tests/gdbus-connection-flush.c new file mode 100644 index 0000000..c164765 --- /dev/null +++ b/gio/tests/gdbus-connection-flush.c @@ -0,0 +1,381 @@ +/* Test case for GNOME #662395 + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * Copyright (C) 2011 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Simon McVittie + */ + +#include + +#include +#include + +#include + +#include "test-io-stream.h" +#include "test-pipe-unix.h" + +#define MY_TYPE_OUTPUT_STREAM \ + (my_output_stream_get_type ()) +#define MY_OUTPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), \ + MY_TYPE_OUTPUT_STREAM, \ + MyOutputStream)) +#define MY_IS_OUTPUT_STREAM(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), MY_TYPE_OUTPUT_STREAM)) + +G_LOCK_DEFINE_STATIC (write); + +typedef struct { + GFilterOutputStream parent; + + gint started; /* (atomic) */ + gint finished; /* (atomic) */ + gint flushed; /* (atomic) */ + + GOutputStream *real_output; +} MyOutputStream; + +typedef struct { + GFilterOutputStreamClass parent; +} MyOutputStreamClass; + +static GType my_output_stream_get_type (void) G_GNUC_CONST; + +G_DEFINE_TYPE (MyOutputStream, my_output_stream, G_TYPE_FILTER_OUTPUT_STREAM) + +/* Called from GDBusWorker thread */ +static gssize +my_output_stream_write (GOutputStream *os, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + MyOutputStream *self = MY_OUTPUT_STREAM (os); + GFilterOutputStream *filter = G_FILTER_OUTPUT_STREAM (os); + GOutputStream *real = g_filter_output_stream_get_base_stream (filter); + gssize ret; + + g_atomic_int_add (&self->started, count); + /* Other threads can make writing block forever by taking this lock */ + G_LOCK (write); + ret = g_output_stream_write (real, buffer, count, cancellable, error); + G_UNLOCK (write); + g_atomic_int_add (&self->finished, count); + return ret; +} + +/* Called from GDBusWorker thread */ +static gboolean +my_output_stream_flush (GOutputStream *os, + GCancellable *cancellable, + GError **error) +{ + MyOutputStream *self = MY_OUTPUT_STREAM (os); + GFilterOutputStream *filter = G_FILTER_OUTPUT_STREAM (os); + GOutputStream *real = g_filter_output_stream_get_base_stream (filter); + gint started, finished; + gboolean ret; + + /* These should be equal because you're not allowed to flush with a + * write pending, and GOutputStream enforces that for its subclasses + */ + started = g_atomic_int_get (&self->started); + finished = g_atomic_int_get (&self->finished); + g_assert_cmpint (started, ==, finished); + + ret = g_output_stream_flush (real, cancellable, error); + + /* As above, this shouldn't have changed during the flush */ + finished = g_atomic_int_get (&self->finished); + g_assert_cmpint (started, ==, finished); + + /* Checkpoint reached */ + g_atomic_int_set (&self->flushed, finished); + return ret; +} + +/* Called from any thread; thread-safe */ +static gint +my_output_stream_get_bytes_started (GOutputStream *os) +{ + MyOutputStream *self = MY_OUTPUT_STREAM (os); + + return g_atomic_int_get (&self->started); +} + +/* Called from any thread; thread-safe */ +static gint +my_output_stream_get_bytes_finished (GOutputStream *os) +{ + MyOutputStream *self = MY_OUTPUT_STREAM (os); + + return g_atomic_int_get (&self->finished); +} + +/* Called from any thread; thread-safe */ +static gint +my_output_stream_get_bytes_flushed (GOutputStream *os) +{ + MyOutputStream *self = MY_OUTPUT_STREAM (os); + + return g_atomic_int_get (&self->flushed); +} + +static void +my_output_stream_init (MyOutputStream *self) +{ +} + +static void +my_output_stream_class_init (MyOutputStreamClass *cls) +{ + GOutputStreamClass *ostream_class = (GOutputStreamClass *) cls; + + ostream_class->write_fn = my_output_stream_write; + ostream_class->flush = my_output_stream_flush; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + GError *error; + gchar *guid; + gboolean flushed; + + GIOStream *client_stream; + GInputStream *client_istream; + GOutputStream *client_ostream; + GOutputStream *client_real_ostream; + GDBusConnection *client_conn; + + GIOStream *server_stream; + GInputStream *server_istream; + GOutputStream *server_ostream; + GDBusConnection *server_conn; +} Fixture; + +static void +setup_client_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + Fixture *f = user_data; + + f->client_conn = g_dbus_connection_new_finish (res, &f->error); + g_assert_no_error (f->error); + g_assert_true (G_IS_DBUS_CONNECTION (f->client_conn)); + g_assert_true (f->client_conn == G_DBUS_CONNECTION (source)); +} + +static void +setup_server_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + Fixture *f = user_data; + + f->server_conn = g_dbus_connection_new_finish (res, &f->error); + g_assert_no_error (f->error); + g_assert_true (G_IS_DBUS_CONNECTION (f->server_conn)); + g_assert_true (f->server_conn == G_DBUS_CONNECTION (source)); +} + +static void +setup (Fixture *f, + gconstpointer test_data G_GNUC_UNUSED) +{ + gboolean ok; + + f->guid = g_dbus_generate_guid (); + + ok = test_pipe (&f->server_istream, &f->client_real_ostream, &f->error); + g_assert_no_error (f->error); + g_assert_true (G_IS_OUTPUT_STREAM (f->client_real_ostream)); + g_assert_true (G_IS_INPUT_STREAM (f->server_istream)); + g_assert_true (ok); + + f->client_ostream = g_object_new (MY_TYPE_OUTPUT_STREAM, + "base-stream", f->client_real_ostream, + "close-base-stream", TRUE, + NULL); + g_assert_true (G_IS_OUTPUT_STREAM (f->client_ostream)); + + ok = test_pipe (&f->client_istream, &f->server_ostream, &f->error); + g_assert_no_error (f->error); + g_assert_true (G_IS_OUTPUT_STREAM (f->server_ostream)); + g_assert_true (G_IS_INPUT_STREAM (f->client_istream)); + g_assert_true (ok); + + f->client_stream = test_io_stream_new (f->client_istream, f->client_ostream); + f->server_stream = test_io_stream_new (f->server_istream, f->server_ostream); + + g_dbus_connection_new (f->client_stream, NULL, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, NULL, setup_client_cb, f); + g_dbus_connection_new (f->server_stream, f->guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + NULL, NULL, setup_server_cb, f); + + while (f->client_conn == NULL || f->server_conn == NULL) + g_main_context_iteration (NULL, TRUE); +} + +static void +flush_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + Fixture *f = user_data; + gboolean ok; + + g_assert_true (G_IS_DBUS_CONNECTION (source)); + g_assert_true (G_IS_DBUS_CONNECTION (f->client_conn)); + g_assert_cmpuint ((guintptr) f->client_conn, ==, (guintptr) G_DBUS_CONNECTION (source)); + + ok = g_dbus_connection_flush_finish (f->client_conn, res, &f->error); + g_assert_no_error (f->error); + g_assert_true (ok); + + f->flushed = TRUE; +} + +static void +test_flush_busy (Fixture *f, + gconstpointer test_data G_GNUC_UNUSED) +{ + gint initial, started; + gboolean ok; + + initial = my_output_stream_get_bytes_started (f->client_ostream); + /* make sure the actual write will block */ + G_LOCK (write); + + ok = g_dbus_connection_emit_signal (f->client_conn, NULL, "/", + "com.example.Foo", "SomeSignal", NULL, + &f->error); + g_assert_no_error (f->error); + g_assert_true (ok); + + /* wait for at least part of the message to have started writing - + * the write will block indefinitely in the worker thread + */ + do { + started = my_output_stream_get_bytes_started (f->client_ostream); + g_thread_yield (); + } while (initial >= started); + + /* we haven't flushed anything */ + g_assert_cmpint (my_output_stream_get_bytes_flushed (f->client_ostream), + <=, initial); + + /* start to flush: it can't happen til the write finishes */ + g_dbus_connection_flush (f->client_conn, NULL, flush_cb, f); + + /* we still haven't actually flushed anything */ + g_assert_cmpint (my_output_stream_get_bytes_flushed (f->client_ostream), + <=, initial); + + /* let the write finish */ + G_UNLOCK (write); + + /* wait for the flush to happen */ + while (!f->flushed) + g_main_context_iteration (NULL, TRUE); + + /* now we have flushed at least what we'd written - but before fixing + * GNOME#662395 this assertion would fail + */ + g_assert_cmpint (my_output_stream_get_bytes_flushed (f->client_ostream), + >=, started); +} + +static void +test_flush_idle (Fixture *f, + gconstpointer test_data G_GNUC_UNUSED) +{ + gint initial, finished; + gboolean ok; + + initial = my_output_stream_get_bytes_finished (f->client_ostream); + + ok = g_dbus_connection_emit_signal (f->client_conn, NULL, "/", + "com.example.Foo", "SomeSignal", NULL, + &f->error); + g_assert_no_error (f->error); + g_assert_true (ok); + + /* wait for at least part of the message to have been written */ + do { + finished = my_output_stream_get_bytes_finished (f->client_ostream); + g_thread_yield (); + } while (initial >= finished); + + /* we haven't flushed anything */ + g_assert_cmpint (my_output_stream_get_bytes_flushed (f->client_ostream), + <=, initial); + + /* flush with fully-written, but unflushed, messages */ + ok = g_dbus_connection_flush_sync (f->client_conn, NULL, &f->error); + + /* now we have flushed at least what we'd written - but before fixing + * GNOME#662395 this assertion would fail + */ + g_assert_cmpint (my_output_stream_get_bytes_flushed (f->client_ostream), + >=, finished); +} + +static void +teardown (Fixture *f, + gconstpointer test_data G_GNUC_UNUSED) +{ + g_clear_error (&f->error); + + g_clear_object (&f->client_stream); + g_clear_object (&f->client_istream); + g_clear_object (&f->client_ostream); + g_clear_object (&f->client_real_ostream); + g_clear_object (&f->client_conn); + + g_clear_object (&f->server_stream); + g_clear_object (&f->server_istream); + g_clear_object (&f->server_ostream); + g_clear_object (&f->server_conn); + + g_free (f->guid); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add ("/gdbus/connection/flush/busy", Fixture, NULL, + setup, test_flush_busy, teardown); + g_test_add ("/gdbus/connection/flush/idle", Fixture, NULL, + setup, test_flush_idle, teardown); + + ret = g_test_run(); + + return ret; +} diff --git a/gio/tests/gdbus-connection-loss.c b/gio/tests/gdbus-connection-loss.c new file mode 100644 index 0000000..cc88cb0 --- /dev/null +++ b/gio/tests/gdbus-connection-loss.c @@ -0,0 +1,146 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a global connection */ +static GDBusConnection *c = NULL; + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ +/* Check that pending calls fail with G_IO_ERROR_CLOSED if the connection is closed */ +/* See https://bugzilla.gnome.org/show_bug.cgi?id=660637 */ +/* ---------------------------------------------------------------------------------------------------- */ + +static void +sleep_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GError **error = user_data; + GVariant *result; + + result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, error); + g_assert (result == NULL); + g_main_loop_quit (loop); +} + +static gboolean +on_timeout (gpointer user_data) +{ + /* tear down bus */ + session_bus_stop (); + return G_SOURCE_REMOVE; +} + +static void +test_connection_loss (void) +{ + GDBusProxy *proxy; + GError *error; + + error = NULL; + proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + error = NULL; + g_dbus_proxy_call (proxy, + "Sleep", + g_variant_new ("(i)", 100 * 1000 /* msec */), + G_DBUS_CALL_FLAGS_NONE, + 10 * 1000 /* msec */, + NULL, /* GCancellable */ + sleep_cb, + &error); + + /* Make sure we don't exit when the bus goes away */ + g_dbus_connection_set_exit_on_close (c, FALSE); + + /* Nuke the connection to the bus */ + g_timeout_add (100 /* ms */, on_timeout, NULL); + + g_main_loop_run (loop); + + /* If we didn't act on connection-loss we'd be getting G_IO_ERROR_TIMEOUT + * generated locally. So if we get G_IO_ERROR_CLOSED it means that we + * are acting correctly on connection loss. + */ + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); + g_assert (!g_dbus_error_is_remote_error (error)); + g_clear_error (&error); + + g_object_unref (proxy); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + GError *error; + gint ret; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + session_bus_up (); + + /* this is safe; testserver will exit once the bus goes away */ + path = g_test_build_filename (G_TEST_BUILT, "gdbus-testserver", NULL); + g_assert (g_spawn_command_line_async (path, NULL)); + g_free (path); + + /* Create the connection in the main thread */ + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (c != NULL); + + ensure_gdbus_testserver_up (c, NULL); + + g_test_add_func ("/gdbus/connection-loss", test_connection_loss); + + ret = g_test_run(); + + g_object_unref (c); + + session_bus_down (); + + g_main_loop_unref (loop); + + return ret; +} diff --git a/gio/tests/gdbus-connection-slow.c b/gio/tests/gdbus-connection-slow.c new file mode 100644 index 0000000..3339e70 --- /dev/null +++ b/gio/tests/gdbus-connection-slow.c @@ -0,0 +1,239 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include + +#include "gdbus-tests.h" + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_connection_flush_signal_handler (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + g_main_loop_quit (loop); +} + +static gboolean +test_connection_flush_on_timeout (gpointer user_data) +{ + guint iteration = GPOINTER_TO_UINT (user_data); + g_printerr ("Timeout waiting 1000 msec on iteration %d\n", iteration); + g_assert_not_reached (); + return G_SOURCE_REMOVE; +} + +static void +test_connection_flush (void) +{ + GDBusConnection *connection; + GError *error; + guint n; + guint signal_handler_id; + const gchar *flush_helper; + + session_bus_up (); + + error = NULL; + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (connection != NULL); + + signal_handler_id = g_dbus_connection_signal_subscribe (connection, + NULL, /* sender */ + "org.gtk.GDBus.FlushInterface", + "SomeSignal", + "/org/gtk/GDBus/FlushObject", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + test_connection_flush_signal_handler, + NULL, + NULL); + g_assert_cmpint (signal_handler_id, !=, 0); + + flush_helper = g_test_get_filename (G_TEST_BUILT, "gdbus-connection-flush-helper", NULL); + for (n = 0; n < 50; n++) + { + gboolean ret; + gint wait_status; + guint timeout_mainloop_id; + gchar *flush_helper_stdout = NULL; + gchar *flush_helper_stderr = NULL; + + error = NULL; + ret = g_spawn_command_line_sync (flush_helper, + &flush_helper_stdout, + &flush_helper_stderr, + &wait_status, + &error) && + g_spawn_check_wait_status (wait_status, &error); + if (!ret) + g_test_message ("Child process ‘%s’ failed. stdout:\n%s\nstderr:\n%s", + flush_helper, flush_helper_stdout, flush_helper_stderr); + + g_free (flush_helper_stdout); + g_free (flush_helper_stderr); + + g_assert_no_error (error); + g_assert_true (ret); + + timeout_mainloop_id = g_timeout_add (1000, test_connection_flush_on_timeout, GUINT_TO_POINTER (n)); + g_main_loop_run (loop); + g_source_remove (timeout_mainloop_id); + } + + g_dbus_connection_signal_unsubscribe (connection, signal_handler_id); + g_object_unref (connection); + + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Message size > 20MiB ... should be enough to make sure the message + * is fragmented when shoved across any transport + */ +#define LARGE_MESSAGE_STRING_LENGTH (20*1024*1024) +/* the test will fail if the service name has not appeared after this amount of seconds */ +#define LARGE_MESSAGE_TIMEOUT_SECONDS 10 + +static gboolean +large_message_timeout_cb (gpointer data) +{ + (void)data; + + g_error ("Error: timeout waiting for dbus name to appear"); + + return G_SOURCE_REMOVE; +} + +static void +large_message_on_name_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + GError *error; + gchar *request; + const gchar *reply; + GVariant *result; + guint n; + + g_assert (g_source_remove (GPOINTER_TO_UINT (user_data))); + + request = g_new (gchar, LARGE_MESSAGE_STRING_LENGTH + 1); + for (n = 0; n < LARGE_MESSAGE_STRING_LENGTH; n++) + request[n] = '0' + (n%10); + request[n] = '\0'; + + error = NULL; + result = g_dbus_connection_call_sync (connection, + "com.example.TestService", /* bus name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + "HelloWorld", /* method name */ + g_variant_new ("(s)", request), /* parameters */ + G_VARIANT_TYPE ("(s)"), /* return type */ + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_variant_get (result, "(&s)", &reply); + g_assert_cmpint (strlen (reply), >, LARGE_MESSAGE_STRING_LENGTH); + g_assert (g_str_has_prefix (reply, "You greeted me with '01234567890123456789012")); + g_assert (g_str_has_suffix (reply, "6789'. Thanks!")); + g_variant_unref (result); + + g_free (request); + + g_main_loop_quit (loop); +} + +static void +large_message_on_name_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ +} + +static void +test_connection_large_message (void) +{ + guint watcher_id; + guint timeout_id; + + session_bus_up (); + + /* this is safe; testserver will exit once the bus goes away */ + g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + + timeout_id = g_timeout_add_seconds (LARGE_MESSAGE_TIMEOUT_SECONDS, + large_message_timeout_cb, + NULL); + + watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, + "com.example.TestService", + G_BUS_NAME_WATCHER_FLAGS_NONE, + large_message_on_name_appeared, + large_message_on_name_vanished, + GUINT_TO_POINTER (timeout_id), /* user_data */ + NULL); /* GDestroyNotify */ + g_main_loop_run (loop); + g_bus_unwatch_name (watcher_id); + + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, NULL); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_dbus_unset (); + + g_test_add_func ("/gdbus/connection/flush", test_connection_flush); + g_test_add_func ("/gdbus/connection/large_message", test_connection_large_message); + + ret = g_test_run(); + g_main_loop_unref (loop); + return ret; +} diff --git a/gio/tests/gdbus-connection.c b/gio/tests/gdbus-connection.c new file mode 100644 index 0000000..396b1a4 --- /dev/null +++ b/gio/tests/gdbus-connection.c @@ -0,0 +1,1296 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include + +#include "gdbus-tests.h" + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +#if 0 +G_GNUC_UNUSED static void +_log (const gchar *format, ...) +{ + GTimeVal now; + time_t now_time; + struct tm *now_tm; + gchar time_buf[128]; + gchar *str; + va_list var_args; + + va_start (var_args, format); + str = g_strdup_vprintf (format, var_args); + va_end (var_args); + + g_get_current_time (&now); + now_time = (time_t) now.tv_sec; + now_tm = localtime (&now_time); + strftime (time_buf, sizeof time_buf, "%H:%M:%S", now_tm); + + g_printerr ("%s.%06d: %s\n", + time_buf, (gint) now.tv_usec / 1000, + str); + g_free (str); +} +#else +#define _log(...) +#endif + +static gboolean +test_connection_quit_mainloop (gpointer user_data) +{ + gboolean *quit_mainloop_fired = user_data; /* (atomic) */ + _log ("quit_mainloop_fired"); + g_atomic_int_set (quit_mainloop_fired, TRUE); + g_main_loop_quit (loop); + return G_SOURCE_CONTINUE; +} + +/* ---------------------------------------------------------------------------------------------------- */ +/* Connection life-cycle testing */ +/* ---------------------------------------------------------------------------------------------------- */ + +static const GDBusInterfaceInfo boo_interface_info = +{ + -1, + "org.example.Boo", + (GDBusMethodInfo **) NULL, + (GDBusSignalInfo **) NULL, + (GDBusPropertyInfo **) NULL, + NULL, +}; + +static const GDBusInterfaceVTable boo_vtable = +{ + NULL, /* _method_call */ + NULL, /* _get_property */ + NULL, /* _set_property */ + { 0 } +}; + +/* Runs in a worker thread. */ +static GDBusMessage * +some_filter_func (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data) +{ + return message; +} + +static void +on_name_owner_changed (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ +} + +static void +a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop (gpointer user_data) +{ + gboolean *val = user_data; /* (atomic) */ + g_atomic_int_set (val, TRUE); + _log ("destroynotify fired for %p", val); + g_main_loop_quit (loop); +} + +static void +test_connection_bus_failure (void) +{ + GDBusConnection *c; + GError *error = NULL; + + /* + * Check for correct behavior when no bus is present + * + */ + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_nonnull (error); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_assert_null (c); + g_error_free (error); +} + +static void +test_connection_life_cycle (void) +{ + gboolean ret; + GDBusConnection *c; + GDBusConnection *c2; + GError *error; + gboolean on_signal_registration_freed_called; /* (atomic) */ + gboolean on_filter_freed_called; /* (atomic) */ + gboolean on_register_object_freed_called; /* (atomic) */ + gboolean quit_mainloop_fired; /* (atomic) */ + guint quit_mainloop_id; + guint registration_id; + + error = NULL; + + /* + * Check for correct behavior when a bus is present + */ + session_bus_up (); + /* case 1 */ + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c); + g_assert_false (g_dbus_connection_is_closed (c)); + + /* + * Check that singleton handling work + */ + error = NULL; + c2 = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c2); + g_assert_true (c == c2); + g_object_unref (c2); + + /* + * Check that private connections work + */ + c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c2); + g_assert_true (c != c2); + g_object_unref (c2); + + c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c2); + g_assert_false (g_dbus_connection_is_closed (c2)); + ret = g_dbus_connection_close_sync (c2, NULL, &error); + g_assert_no_error (error); + g_assert_true (ret); + _g_assert_signal_received (c2, "closed"); + g_assert_true (g_dbus_connection_is_closed (c2)); + ret = g_dbus_connection_close_sync (c2, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); + g_error_free (error); + g_assert_false (ret); + g_object_unref (c2); + + /* + * Check that the finalization code works + * + * (and that the GDestroyNotify for filters and objects and signal + * registrations are run as expected) + */ + error = NULL; + c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c2); + /* signal registration */ + g_atomic_int_set (&on_signal_registration_freed_called, FALSE); + g_dbus_connection_signal_subscribe (c2, + "org.freedesktop.DBus", /* bus name */ + "org.freedesktop.DBus", /* interface */ + "NameOwnerChanged", /* member */ + "/org/freesktop/DBus", /* path */ + NULL, /* arg0 */ + G_DBUS_SIGNAL_FLAGS_NONE, + on_name_owner_changed, + (gpointer) &on_signal_registration_freed_called, + a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop); + /* filter func */ + g_atomic_int_set (&on_filter_freed_called, FALSE); + g_dbus_connection_add_filter (c2, + some_filter_func, + (gpointer) &on_filter_freed_called, + a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop); + /* object registration */ + g_atomic_int_set (&on_register_object_freed_called, FALSE); + error = NULL; + registration_id = g_dbus_connection_register_object (c2, + "/foo", + (GDBusInterfaceInfo *) &boo_interface_info, + &boo_vtable, + (gpointer) &on_register_object_freed_called, + a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop, + &error); + g_assert_no_error (error); + g_assert_cmpuint (registration_id, >, 0); + /* ok, finalize the connection and check that all the GDestroyNotify functions are invoked as expected */ + g_object_unref (c2); + g_atomic_int_set (&quit_mainloop_fired, FALSE); + quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, (gpointer) &quit_mainloop_fired); + _log ("destroynotifies for\n" + " register_object %p\n" + " filter %p\n" + " signal %p", + &on_register_object_freed_called, + &on_filter_freed_called, + &on_signal_registration_freed_called); + while (TRUE) + { + if (g_atomic_int_get (&on_signal_registration_freed_called) && + g_atomic_int_get (&on_filter_freed_called) && + g_atomic_int_get (&on_register_object_freed_called)) + break; + if (g_atomic_int_get (&quit_mainloop_fired)) + break; + _log ("entering loop"); + g_main_loop_run (loop); + _log ("exiting loop"); + } + g_source_remove (quit_mainloop_id); + g_assert_true (g_atomic_int_get (&on_signal_registration_freed_called)); + g_assert_true (g_atomic_int_get (&on_filter_freed_called)); + g_assert_true (g_atomic_int_get (&on_register_object_freed_called)); + g_assert_false (g_atomic_int_get (&quit_mainloop_fired)); + + /* + * Check for correct behavior when the bus goes away + * + */ + g_assert_false (g_dbus_connection_is_closed (c)); + g_dbus_connection_set_exit_on_close (c, FALSE); + session_bus_stop (); + _g_assert_signal_received (c, "closed"); + g_assert_true (g_dbus_connection_is_closed (c)); + g_object_unref (c); + + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that sending and receiving messages work as expected */ +/* ---------------------------------------------------------------------------------------------------- */ + +static void +msg_cb_expect_error_disconnected (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GError *error; + GVariant *result; + + /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */ + g_dbus_connection_get_last_serial (connection); + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_error_free (error); + g_assert_null (result); + + g_main_loop_quit (loop); +} + +static void +msg_cb_expect_error_unknown_method (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GError *error; + GVariant *result; + + /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */ + g_dbus_connection_get_last_serial (connection); + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_assert_true (g_dbus_error_is_remote_error (error)); + g_error_free (error); + g_assert_null (result); + + g_main_loop_quit (loop); +} + +static void +msg_cb_expect_success (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GError *error; + GVariant *result; + + /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */ + g_dbus_connection_get_last_serial (connection); + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_variant_unref (result); + + g_main_loop_quit (loop); +} + +static void +msg_cb_expect_error_cancelled (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GError *error; + GVariant *result; + + /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */ + g_dbus_connection_get_last_serial (connection); + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_error_free (error); + g_assert_null (result); + + g_main_loop_quit (loop); +} + +static void +msg_cb_expect_error_cancelled_2 (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + GError *error; + GVariant *result; + + /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */ + g_dbus_connection_get_last_serial (connection); + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_error_free (error); + g_assert_null (result); + + g_main_loop_quit (loop); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_connection_send (void) +{ + GDBusConnection *c; + GCancellable *ca; + + session_bus_up (); + + /* First, get an unopened connection */ + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert_nonnull (c); + g_assert_false (g_dbus_connection_is_closed (c)); + + /* + * Check that we never actually send a message if the GCancellable + * is already cancelled - i.e. we should get G_IO_ERROR_CANCELLED + * when the actual connection is not up. + */ + ca = g_cancellable_new (); + g_cancellable_cancel (ca); + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + ca, + (GAsyncReadyCallback) msg_cb_expect_error_cancelled, + NULL); + g_main_loop_run (loop); + g_object_unref (ca); + + /* + * Check that we get a reply to the GetId() method call. + */ + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) msg_cb_expect_success, + NULL); + g_main_loop_run (loop); + + /* + * Check that we get an error reply to the NonExistantMethod() method call. + */ + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "NonExistantMethod", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) msg_cb_expect_error_unknown_method, + NULL); + g_main_loop_run (loop); + + /* + * Check that cancellation works when the message is already in flight. + */ + ca = g_cancellable_new (); + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + ca, + (GAsyncReadyCallback) msg_cb_expect_error_cancelled_2, + NULL); + g_cancellable_cancel (ca); + g_main_loop_run (loop); + g_object_unref (ca); + + /* + * Check that we get an error when sending to a connection that is disconnected. + */ + g_dbus_connection_set_exit_on_close (c, FALSE); + session_bus_stop (); + _g_assert_signal_received (c, "closed"); + g_assert_true (g_dbus_connection_is_closed (c)); + + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) msg_cb_expect_error_disconnected, + NULL); + g_main_loop_run (loop); + + g_object_unref (c); + + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ +/* Connection signal tests */ +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_connection_signal_handler (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + gint *counter = user_data; + *counter += 1; + + /*g_debug ("in test_connection_signal_handler (sender=%s path=%s interface=%s member=%s)", + sender_name, + object_path, + interface_name, + signal_name);*/ + + g_main_loop_quit (loop); +} + +static void +test_connection_signals (void) +{ + GDBusConnection *c1; + GDBusConnection *c2; + GDBusConnection *c3; + guint s1; + guint s1b; + guint s2; + guint s3; + gint count_s1; + gint count_s1b; + gint count_s2; + gint count_name_owner_changed; + GError *error; + gboolean ret; + GVariant *result; + gboolean quit_mainloop_fired; + guint quit_mainloop_id; + + error = NULL; + + /* + * Bring up first separate connections + */ + session_bus_up (); + /* if running with dbus-monitor, it claims the name :1.0 - so if we don't run with the monitor + * emulate this + */ + if (g_getenv ("G_DBUS_MONITOR") == NULL) + { + c1 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert_nonnull (c1); + g_assert_false (g_dbus_connection_is_closed (c1)); + g_object_unref (c1); + } + c1 = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert_nonnull (c1); + g_assert_false (g_dbus_connection_is_closed (c1)); + g_assert_cmpstr (g_dbus_connection_get_unique_name (c1), ==, ":1.1"); + + /* + * Install two signal handlers for the first connection + * + * - Listen to the signal "Foo" from :1.2 (e.g. c2) + * - Listen to the signal "Foo" from anyone (e.g. both c2 and c3) + * + * and then count how many times this signal handler was invoked. + */ + s1 = g_dbus_connection_signal_subscribe (c1, + ":1.2", + "org.gtk.GDBus.ExampleInterface", + "Foo", + "/org/gtk/GDBus/ExampleInterface", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + test_connection_signal_handler, + &count_s1, + NULL); + s2 = g_dbus_connection_signal_subscribe (c1, + NULL, /* match any sender */ + "org.gtk.GDBus.ExampleInterface", + "Foo", + "/org/gtk/GDBus/ExampleInterface", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + test_connection_signal_handler, + &count_s2, + NULL); + s3 = g_dbus_connection_signal_subscribe (c1, + "org.freedesktop.DBus", /* sender */ + "org.freedesktop.DBus", /* interface */ + "NameOwnerChanged", /* member */ + "/org/freedesktop/DBus", /* path */ + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + test_connection_signal_handler, + &count_name_owner_changed, + NULL); + /* Note that s1b is *just like* s1 - this is to catch a bug where N + * subscriptions of the same rule causes N calls to each of the N + * subscriptions instead of just 1 call to each of the N subscriptions. + */ + s1b = g_dbus_connection_signal_subscribe (c1, + ":1.2", + "org.gtk.GDBus.ExampleInterface", + "Foo", + "/org/gtk/GDBus/ExampleInterface", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + test_connection_signal_handler, + &count_s1b, + NULL); + g_assert_cmpuint (s1, !=, 0); + g_assert_cmpuint (s1b, !=, 0); + g_assert_cmpuint (s2, !=, 0); + g_assert_cmpuint (s3, !=, 0); + + count_s1 = 0; + count_s1b = 0; + count_s2 = 0; + count_name_owner_changed = 0; + + /* + * Make c2 emit "Foo" - we should catch it twice + * + * Note that there is no way to be sure that the signal subscriptions + * on c1 are effective yet - for all we know, the AddMatch() messages + * could sit waiting in a buffer somewhere between this process and + * the message bus. And emitting signals on c2 (a completely other + * socket!) will not necessarily change this. + * + * To ensure this is not the case, do a synchronous call on c1. + */ + result = g_dbus_connection_call_sync (c1, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, /* parameters */ + NULL, /* return type */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_variant_unref (result); + + /* + * Bring up two other connections + */ + c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert_nonnull (c2); + g_assert_false (g_dbus_connection_is_closed (c2)); + g_assert_cmpstr (g_dbus_connection_get_unique_name (c2), ==, ":1.2"); + c3 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert_nonnull (c3); + g_assert_false (g_dbus_connection_is_closed (c3)); + g_assert_cmpstr (g_dbus_connection_get_unique_name (c3), ==, ":1.3"); + + /* now, emit the signal on c2 */ + ret = g_dbus_connection_emit_signal (c2, + NULL, /* destination bus name */ + "/org/gtk/GDBus/ExampleInterface", + "org.gtk.GDBus.ExampleInterface", + "Foo", + NULL, + &error); + g_assert_no_error (error); + g_assert_true (ret); + while (!(count_s1 >= 1 && count_s2 >= 1)) + g_main_loop_run (loop); + g_assert_cmpint (count_s1, ==, 1); + g_assert_cmpint (count_s2, ==, 1); + + /* + * Make c3 emit "Foo" - we should catch it only once + */ + ret = g_dbus_connection_emit_signal (c3, + NULL, /* destination bus name */ + "/org/gtk/GDBus/ExampleInterface", + "org.gtk.GDBus.ExampleInterface", + "Foo", + NULL, + &error); + g_assert_no_error (error); + g_assert_true (ret); + while (!(count_s1 == 1 && count_s2 == 2)) + g_main_loop_run (loop); + g_assert_cmpint (count_s1, ==, 1); + g_assert_cmpint (count_s2, ==, 2); + + /* + * Also to check the total amount of NameOwnerChanged signals - use a 5 second ceiling + * to avoid spinning forever + */ + quit_mainloop_fired = FALSE; + quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, &quit_mainloop_fired); + while (count_name_owner_changed < 2 && !quit_mainloop_fired) + g_main_loop_run (loop); + g_source_remove (quit_mainloop_id); + g_assert_cmpint (count_s1, ==, 1); + g_assert_cmpint (count_s2, ==, 2); + g_assert_cmpint (count_name_owner_changed, ==, 2); + + g_dbus_connection_signal_unsubscribe (c1, s1); + g_dbus_connection_signal_unsubscribe (c1, s2); + g_dbus_connection_signal_unsubscribe (c1, s3); + g_dbus_connection_signal_unsubscribe (c1, s1b); + + g_object_unref (c1); + g_object_unref (c2); + g_object_unref (c3); + + session_bus_down (); +} + +static void +test_match_rule (GDBusConnection *connection, + GDBusSignalFlags flags, + gchar *arg0_rule, + gchar *arg0, + gboolean should_match) +{ + guint subscription_ids[2]; + gint emissions = 0; + gint matches = 0; + GError *error = NULL; + + subscription_ids[0] = g_dbus_connection_signal_subscribe (connection, + NULL, "org.gtk.ExampleInterface", "Foo", "/", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + test_connection_signal_handler, + &emissions, NULL); + subscription_ids[1] = g_dbus_connection_signal_subscribe (connection, + NULL, "org.gtk.ExampleInterface", "Foo", "/", + arg0_rule, + flags, + test_connection_signal_handler, + &matches, NULL); + g_assert_cmpint (subscription_ids[0], !=, 0); + g_assert_cmpint (subscription_ids[1], !=, 0); + + g_dbus_connection_emit_signal (connection, + NULL, "/", "org.gtk.ExampleInterface", + "Foo", g_variant_new ("(s)", arg0), + &error); + g_assert_no_error (error); + + /* synchronously ping a non-existent method to make sure the signals are dispatched */ + g_dbus_connection_call_sync (connection, "org.gtk.ExampleInterface", "/", "org.gtk.ExampleInterface", + "Bar", g_variant_new ("()"), G_VARIANT_TYPE_UNIT, G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL); + + while (g_main_context_iteration (NULL, FALSE)) + ; + + g_assert_cmpint (emissions, ==, 1); + g_assert_cmpint (matches, ==, should_match ? 1 : 0); + + g_dbus_connection_signal_unsubscribe (connection, subscription_ids[0]); + g_dbus_connection_signal_unsubscribe (connection, subscription_ids[1]); +} + +static void +test_connection_signal_match_rules (void) +{ + GDBusConnection *con; + + session_bus_up (); + con = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_NONE, "foo", "foo", TRUE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_NONE, "foo", "bar", FALSE); + + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "", FALSE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org", FALSE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk", TRUE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk.Example", TRUE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk+", FALSE); + + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/", "/", TRUE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/", "", FALSE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk/Example", TRUE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/", "/org/gtk/Example", TRUE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk/", TRUE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk", FALSE); + test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk+", "/org/gtk", FALSE); + + g_object_unref (con); + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Accessed both from the test code and the filter function (in a worker thread) + * so all accesses must be atomic. */ +typedef struct +{ + GAsyncQueue *incoming_queue; /* (element-type GDBusMessage) */ + guint num_outgoing; /* (atomic) */ +} FilterData; + +/* Runs in a worker thread. */ +static GDBusMessage * +filter_func (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data) +{ + FilterData *data = user_data; + + if (incoming) + g_async_queue_push (data->incoming_queue, g_object_ref (message)); + else + g_atomic_int_inc (&data->num_outgoing); + + return message; +} + +static void +wait_for_filtered_reply (GAsyncQueue *incoming_queue, + guint32 expected_serial) +{ + GDBusMessage *popped_message = NULL; + + while ((popped_message = g_async_queue_pop (incoming_queue)) != NULL) + { + guint32 reply_serial = g_dbus_message_get_reply_serial (popped_message); + g_object_unref (popped_message); + if (reply_serial == expected_serial) + return; + } + + g_assert_not_reached (); +} + +typedef struct +{ + gboolean alter_incoming; + gboolean alter_outgoing; +} FilterEffects; + +/* Runs in a worker thread. */ +static GDBusMessage * +other_filter_func (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data) +{ + const FilterEffects *effects = user_data; + GDBusMessage *ret; + gboolean alter; + + if (incoming) + alter = effects->alter_incoming; + else + alter = effects->alter_outgoing; + + if (alter) + { + GDBusMessage *copy; + GVariant *body; + gchar *s; + gchar *s2; + + copy = g_dbus_message_copy (message, NULL); + g_object_unref (message); + + body = g_dbus_message_get_body (copy); + g_variant_get (body, "(s)", &s); + s2 = g_strdup_printf ("MOD: %s", s); + g_dbus_message_set_body (copy, g_variant_new ("(s)", s2)); + g_free (s2); + g_free (s); + + ret = copy; + } + else + { + ret = message; + } + + return ret; +} + +static void +test_connection_filter_name_owner_changed_signal_handler (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + const gchar *name; + const gchar *old_owner; + const gchar *new_owner; + + g_variant_get (parameters, + "(&s&s&s)", + &name, + &old_owner, + &new_owner); + + if (g_strcmp0 (name, "com.example.TestService") == 0 && strlen (new_owner) > 0) + { + g_main_loop_quit (loop); + } +} + +static gboolean +test_connection_filter_on_timeout (gpointer user_data) +{ + g_printerr ("Timeout waiting 30 sec on service\n"); + g_assert_not_reached (); + return G_SOURCE_REMOVE; +} + +static void +test_connection_filter (void) +{ + GDBusConnection *c; + FilterData data = { NULL, 0 }; + GDBusMessage *m; + GDBusMessage *m2; + GDBusMessage *r; + GError *error; + guint filter_id; + guint timeout_mainloop_id; + guint signal_handler_id; + FilterEffects effects; + GVariant *result; + const gchar *s; + guint32 serial_temp; + + session_bus_up (); + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c); + + data.incoming_queue = g_async_queue_new_full (g_object_unref); + data.num_outgoing = 0; + filter_id = g_dbus_connection_add_filter (c, + filter_func, + &data, + NULL); + + m = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */ + "/org/freedesktop/DBus", /* path */ + "org.freedesktop.DBus", /* interface */ + "GetNameOwner"); + g_dbus_message_set_body (m, g_variant_new ("(s)", "org.freedesktop.DBus")); + error = NULL; + g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error); + g_assert_no_error (error); + + wait_for_filtered_reply (data.incoming_queue, serial_temp); + + m2 = g_dbus_message_copy (m, &error); + g_assert_no_error (error); + g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error); + g_object_unref (m2); + g_assert_no_error (error); + + wait_for_filtered_reply (data.incoming_queue, serial_temp); + + m2 = g_dbus_message_copy (m, &error); + g_assert_no_error (error); + g_dbus_message_set_serial (m2, serial_temp); + /* lock the message to test PRESERVE_SERIAL flag. */ + g_dbus_message_lock (m2); + g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, &serial_temp, &error); + g_object_unref (m2); + g_assert_no_error (error); + + wait_for_filtered_reply (data.incoming_queue, serial_temp); + + m2 = g_dbus_message_copy (m, &error); + g_assert_no_error (error); + r = g_dbus_connection_send_message_with_reply_sync (c, + m2, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + &serial_temp, + NULL, /* GCancellable */ + &error); + g_object_unref (m2); + g_assert_no_error (error); + g_assert_nonnull (r); + g_object_unref (r); + + wait_for_filtered_reply (data.incoming_queue, serial_temp); + g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0); + + g_dbus_connection_remove_filter (c, filter_id); + + m2 = g_dbus_message_copy (m, &error); + g_assert_no_error (error); + r = g_dbus_connection_send_message_with_reply_sync (c, + m2, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + &serial_temp, + NULL, /* GCancellable */ + &error); + g_object_unref (m2); + g_assert_no_error (error); + g_assert_nonnull (r); + g_object_unref (r); + g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0); + g_assert_cmpint (g_atomic_int_get (&data.num_outgoing), ==, 4); + + /* wait for service to be available */ + signal_handler_id = g_dbus_connection_signal_subscribe (c, + "org.freedesktop.DBus", /* sender */ + "org.freedesktop.DBus", + "NameOwnerChanged", + "/org/freedesktop/DBus", + NULL, /* arg0 */ + G_DBUS_SIGNAL_FLAGS_NONE, + test_connection_filter_name_owner_changed_signal_handler, + NULL, + NULL); + g_assert_cmpint (signal_handler_id, !=, 0); + + /* this is safe; testserver will exit once the bus goes away */ + g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + + timeout_mainloop_id = g_timeout_add (30000, test_connection_filter_on_timeout, NULL); + g_main_loop_run (loop); + g_source_remove (timeout_mainloop_id); + g_dbus_connection_signal_unsubscribe (c, signal_handler_id); + + /* now test some combinations... */ + filter_id = g_dbus_connection_add_filter (c, + other_filter_func, + &effects, + NULL); + /* -- */ + effects.alter_incoming = FALSE; + effects.alter_outgoing = FALSE; + error = NULL; + result = g_dbus_connection_call_sync (c, + "com.example.TestService", /* bus name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + "HelloWorld", /* method name */ + g_variant_new ("(s)", "Cat"), /* parameters */ + G_VARIANT_TYPE ("(s)"), /* return type */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_variant_get (result, "(&s)", &s); + g_assert_cmpstr (s, ==, "You greeted me with 'Cat'. Thanks!"); + g_variant_unref (result); + /* -- */ + effects.alter_incoming = TRUE; + effects.alter_outgoing = TRUE; + error = NULL; + result = g_dbus_connection_call_sync (c, + "com.example.TestService", /* bus name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + "HelloWorld", /* method name */ + g_variant_new ("(s)", "Cat"), /* parameters */ + G_VARIANT_TYPE ("(s)"), /* return type */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_variant_get (result, "(&s)", &s); + g_assert_cmpstr (s, ==, "MOD: You greeted me with 'MOD: Cat'. Thanks!"); + g_variant_unref (result); + + + g_dbus_connection_remove_filter (c, filter_id); + + g_object_unref (c); + g_object_unref (m); + g_async_queue_unref (data.incoming_queue); + + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#define NUM_THREADS 50 + +static void +send_bogus_message (GDBusConnection *c, guint32 *out_serial) +{ + GDBusMessage *m; + GError *error; + + m = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */ + "/org/freedesktop/DBus", /* path */ + "org.freedesktop.DBus", /* interface */ + "GetNameOwner"); + g_dbus_message_set_body (m, g_variant_new ("(s)", "org.freedesktop.DBus")); + error = NULL; + g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, out_serial, &error); + g_assert_no_error (error); + g_object_unref (m); +} + +#define SLEEP_USEC (100 * 1000) + +static gpointer +serials_thread_func (GDBusConnection *c) +{ + guint32 message_serial; + guint i; + + /* No calls on this thread yet */ + g_assert_cmpint (g_dbus_connection_get_last_serial(c), ==, 0); + + /* Send a bogus message and store its serial */ + message_serial = 0; + send_bogus_message (c, &message_serial); + + /* Give it some time to actually send the message out. 10 seconds + * should be plenty, even on slow machines. */ + for (i = 0; i < 10 * G_USEC_PER_SEC / SLEEP_USEC; i++) + { + if (g_dbus_connection_get_last_serial(c) != 0) + break; + + g_usleep (SLEEP_USEC); + } + + g_assert_cmpint (g_dbus_connection_get_last_serial(c), !=, 0); + g_assert_cmpint (g_dbus_connection_get_last_serial(c), ==, message_serial); + + return NULL; +} + +static void +test_connection_serials (void) +{ + GDBusConnection *c; + GError *error; + GThread *pool[NUM_THREADS]; + int i; + + session_bus_up (); + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c); + + /* Status after initialization */ + g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 1); + + /* Send a bogus message */ + send_bogus_message (c, NULL); + g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 2); + + /* Start the threads */ + for (i = 0; i < NUM_THREADS; i++) + pool[i] = g_thread_new (NULL, (GThreadFunc) serials_thread_func, c); + + /* Wait until threads are finished */ + for (i = 0; i < NUM_THREADS; i++) + g_thread_join (pool[i]); + + /* No calls in between on this thread, should be the last value */ + g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 2); + + send_bogus_message (c, NULL); + + /* All above calls + calls in threads */ + g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 3 + NUM_THREADS); + + g_object_unref (c); + + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_connection_basic (void) +{ + GDBusConnection *connection; + GError *error; + GDBusCapabilityFlags flags; + GDBusConnectionFlags connection_flags; + gchar *guid; + gchar *name; + gboolean closed; + gboolean exit_on_close; + GIOStream *stream; + GCredentials *credentials; + + session_bus_up (); + + error = NULL; + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (connection); + + flags = g_dbus_connection_get_capabilities (connection); + g_assert_true (flags == G_DBUS_CAPABILITY_FLAGS_NONE || + flags == G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); + + connection_flags = g_dbus_connection_get_flags (connection); + g_assert_cmpint (connection_flags, ==, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION); + + credentials = g_dbus_connection_get_peer_credentials (connection); + g_assert_null (credentials); + + g_object_get (connection, + "stream", &stream, + "guid", &guid, + "unique-name", &name, + "closed", &closed, + "exit-on-close", &exit_on_close, + "capabilities", &flags, + NULL); + + g_assert_true (G_IS_IO_STREAM (stream)); + g_assert_true (g_dbus_is_guid (guid)); + g_assert_true (g_dbus_is_unique_name (name)); + g_assert_false (closed); + g_assert_true (exit_on_close); + g_assert_true (flags == G_DBUS_CAPABILITY_FLAGS_NONE || + flags == G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); + g_object_unref (stream); + g_free (name); + g_free (guid); + + g_object_unref (connection); + + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + int ret; + + g_test_init (&argc, &argv, NULL); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_dbus_unset (); + + /* gdbus cleanup is pretty racy due to worker threads, so always do this test first */ + g_test_add_func ("/gdbus/connection/bus-failure", test_connection_bus_failure); + + g_test_add_func ("/gdbus/connection/basic", test_connection_basic); + g_test_add_func ("/gdbus/connection/life-cycle", test_connection_life_cycle); + g_test_add_func ("/gdbus/connection/send", test_connection_send); + g_test_add_func ("/gdbus/connection/signals", test_connection_signals); + g_test_add_func ("/gdbus/connection/signal-match-rules", test_connection_signal_match_rules); + g_test_add_func ("/gdbus/connection/filter", test_connection_filter); + g_test_add_func ("/gdbus/connection/serials", test_connection_serials); + ret = g_test_run(); + + g_main_loop_unref (loop); + return ret; +} diff --git a/gio/tests/gdbus-daemon.c b/gio/tests/gdbus-daemon.c new file mode 100644 index 0000000..6c2b81c --- /dev/null +++ b/gio/tests/gdbus-daemon.c @@ -0,0 +1,70 @@ +#include "config.h" + +#include "gdbusdaemon.h" +#include + +int +main (int argc, char *argv[]) +{ + GDBusDaemon *daemon; + GMainLoop *loop; + const char *address = NULL; + const char *config_file = NULL; + GError *error = NULL; + gboolean print_address = FALSE; + gboolean print_env = FALSE; + GOptionContext *context; + GOptionEntry entries[] = { + { "address", 0, 0, G_OPTION_ARG_STRING, &address, N_("Address to listen on"), NULL }, + { "config-file", 0, 0, G_OPTION_ARG_STRING, &config_file, N_("Ignored, for compat with GTestDbus"), NULL }, + { "print-address", 0, 0, G_OPTION_ARG_NONE, &print_address, N_("Print address"), NULL }, + { "print-env", 0, 0, G_OPTION_ARG_NONE, &print_env, N_("Print address in shell mode"), NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (""); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_set_summary (context, + N_("Run a dbus service")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + error = NULL; + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s\n", error->message); + return 1; + } + + g_option_context_free (context); + + if (argc != 1) + { + g_printerr (_("Wrong args\n")); + return 1; + } + + + loop = g_main_loop_new (NULL, FALSE); + + if (argc >= 2) + address = argv[1]; + + daemon = _g_dbus_daemon_new (address, NULL, &error); + if (daemon == NULL) + { + g_printerr ("Can't init bus: %s\n", error->message); + return 1; + } + + if (print_env) + g_print ("export DBUS_SESSION_BUS_ADDRESS=\"%s\"\n", _g_dbus_daemon_get_address (daemon)); + + if (print_address) + g_print ("%s\n", _g_dbus_daemon_get_address (daemon)); + + g_main_loop_run (loop); + + g_main_loop_unref (loop); + + return 0; +} diff --git a/gio/tests/gdbus-error.c b/gio/tests/gdbus-error.c new file mode 100644 index 0000000..96ed422 --- /dev/null +++ b/gio/tests/gdbus-error.c @@ -0,0 +1,269 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that registered errors are properly mapped */ +/* ---------------------------------------------------------------------------------------------------- */ + +static void +check_registered_error (const gchar *given_dbus_error_name, + GQuark error_domain, + gint error_code) +{ + GError *error; + gchar *dbus_error_name; + + error = g_dbus_error_new_for_dbus_error (given_dbus_error_name, "test message"); + g_assert_error (error, error_domain, error_code); + g_assert (g_dbus_error_is_remote_error (error)); + g_assert (g_dbus_error_strip_remote_error (error)); + g_assert_cmpstr (error->message, ==, "test message"); + dbus_error_name = g_dbus_error_get_remote_error (error); + g_assert_cmpstr (dbus_error_name, ==, given_dbus_error_name); + g_free (dbus_error_name); + g_error_free (error); +} + +static void +test_registered_errors (void) +{ + /* Here we check that we are able to map to GError and back for registered + * errors. + * + * For example, if "org.freedesktop.DBus.Error.AddressInUse" is + * associated with (G_DBUS_ERROR, G_DBUS_ERROR_DBUS_FAILED), check + * that + * + * - Creating a GError for e.g. "org.freedesktop.DBus.Error.AddressInUse" + * has (error_domain, code) == (G_DBUS_ERROR, G_DBUS_ERROR_DBUS_FAILED) + * + * - That it is possible to recover e.g. "org.freedesktop.DBus.Error.AddressInUse" + * as the D-Bus error name when dealing with an error with (error_domain, code) == + * (G_DBUS_ERROR, G_DBUS_ERROR_DBUS_FAILED) + * + * We just check a couple of well-known errors. + */ + check_registered_error ("org.freedesktop.DBus.Error.Failed", + G_DBUS_ERROR, + G_DBUS_ERROR_FAILED); + check_registered_error ("org.freedesktop.DBus.Error.AddressInUse", + G_DBUS_ERROR, + G_DBUS_ERROR_ADDRESS_IN_USE); + check_registered_error ("org.freedesktop.DBus.Error.UnknownMethod", + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD); + check_registered_error ("org.freedesktop.DBus.Error.UnknownObject", + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_OBJECT); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +check_unregistered_error (const gchar *given_dbus_error_name) +{ + GError *error; + gchar *dbus_error_name; + + error = g_dbus_error_new_for_dbus_error (given_dbus_error_name, "test message"); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR); + g_assert (g_dbus_error_is_remote_error (error)); + dbus_error_name = g_dbus_error_get_remote_error (error); + g_assert_cmpstr (dbus_error_name, ==, given_dbus_error_name); + g_free (dbus_error_name); + + /* strip the message */ + g_assert (g_dbus_error_strip_remote_error (error)); + g_assert_cmpstr (error->message, ==, "test message"); + + /* check that we can no longer recover the D-Bus error name */ + g_assert (g_dbus_error_get_remote_error (error) == NULL); + + g_error_free (error); + +} + +static void +test_unregistered_errors (void) +{ + /* Here we check that we are able to map to GError and back for unregistered + * errors. + * + * For example, if "com.example.Error.Failed" is not registered, then check + * + * - Creating a GError for e.g. "com.example.Error.Failed" has (error_domain, code) == + * (G_IO_ERROR, G_IO_ERROR_DBUS_ERROR) + * + * - That it is possible to recover e.g. "com.example.Error.Failed" from that + * GError. + * + * We just check a couple of random errors. + */ + + check_unregistered_error ("com.example.Error.Failed"); + check_unregistered_error ("foobar.buh"); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +check_transparent_gerror (GQuark error_domain, + gint error_code) +{ + GError *error; + gchar *given_dbus_error_name; + gchar *dbus_error_name; + + error = g_error_new (error_domain, error_code, "test message"); + given_dbus_error_name = g_dbus_error_encode_gerror (error); + g_assert (g_str_has_prefix (given_dbus_error_name, "org.gtk.GDBus.UnmappedGError.Quark")); + g_error_free (error); + + error = g_dbus_error_new_for_dbus_error (given_dbus_error_name, "test message"); + g_assert_error (error, error_domain, error_code); + g_assert (g_dbus_error_is_remote_error (error)); + dbus_error_name = g_dbus_error_get_remote_error (error); + g_assert_cmpstr (dbus_error_name, ==, given_dbus_error_name); + g_free (dbus_error_name); + g_free (given_dbus_error_name); + + /* strip the message */ + g_assert (g_dbus_error_strip_remote_error (error)); + g_assert_cmpstr (error->message, ==, "test message"); + + /* check that we can no longer recover the D-Bus error name */ + g_assert (g_dbus_error_get_remote_error (error) == NULL); + + g_error_free (error); +} + +static void +test_transparent_gerror (void) +{ + /* Here we check that we are able to transparent pass unregistered GError's + * over the wire. + * + * For example, if G_IO_ERROR_FAILED is not registered, then check + * + * - g_dbus_error_encode_gerror() returns something of the form + * org.gtk.GDBus.UnmappedGError.Quark_HEXENCODED_QUARK_NAME_.Code_ERROR_CODE + * + * - mapping back the D-Bus error name gives us G_IO_ERROR_FAILED + * + * - That it is possible to recover the D-Bus error name from the + * GError. + * + * We just check a couple of random errors. + */ + + check_transparent_gerror (G_IO_ERROR, G_IO_ERROR_FAILED); + check_transparent_gerror (G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); +} + +typedef enum +{ + TEST_ERROR_FAILED, + TEST_ERROR_BLA +} TestError; + +GDBusErrorEntry test_error_entries[] = +{ + { TEST_ERROR_FAILED, "org.gtk.test.Error.Failed" }, + { TEST_ERROR_BLA, "org.gtk.test.Error.Bla" } +}; + +static void +test_register_error (void) +{ + gsize test_error_quark = 0; + gboolean res; + gchar *msg; + GError *error; + + g_dbus_error_register_error_domain ("test-error-quark", + &test_error_quark, + test_error_entries, + G_N_ELEMENTS (test_error_entries)); + g_assert_cmpint (test_error_quark, !=, 0); + + error = g_dbus_error_new_for_dbus_error ("org.gtk.test.Error.Failed", "Failed"); + g_assert_error (error, test_error_quark, TEST_ERROR_FAILED); + res = g_dbus_error_is_remote_error (error); + msg = g_dbus_error_get_remote_error (error); + g_assert (res); + g_assert_cmpstr (msg, ==, "org.gtk.test.Error.Failed"); + res = g_dbus_error_strip_remote_error (error); + g_assert (res); + g_assert_cmpstr (error->message, ==, "Failed"); + g_clear_error (&error); + g_free (msg); + + g_dbus_error_set_dbus_error (&error, "org.gtk.test.Error.Failed", "Failed again", "Prefix %d", 1); + res = g_dbus_error_is_remote_error (error); + msg = g_dbus_error_get_remote_error (error); + g_assert (res); + g_assert_cmpstr (msg, ==, "org.gtk.test.Error.Failed"); + res = g_dbus_error_strip_remote_error (error); + g_assert (res); + g_assert_cmpstr (error->message, ==, "Prefix 1: Failed again"); + g_clear_error (&error); + g_free (msg); + + error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_EMPTY, "Not Empty"); + res = g_dbus_error_is_remote_error (error); + msg = g_dbus_error_get_remote_error (error); + g_assert (!res); + g_assert_cmpstr (msg, ==, NULL); + res = g_dbus_error_strip_remote_error (error); + g_assert (!res); + g_assert_cmpstr (error->message, ==, "Not Empty"); + g_clear_error (&error); + + error = g_error_new_literal (test_error_quark, TEST_ERROR_BLA, "Bla"); + msg = g_dbus_error_encode_gerror (error); + g_assert_cmpstr (msg, ==, "org.gtk.test.Error.Bla"); + g_free (msg); + g_clear_error (&error); + + res = g_dbus_error_unregister_error (test_error_quark, + TEST_ERROR_BLA, "org.gtk.test.Error.Bla"); + g_assert (res); +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gdbus/registered-errors", test_registered_errors); + g_test_add_func ("/gdbus/unregistered-errors", test_unregistered_errors); + g_test_add_func ("/gdbus/transparent-gerror", test_transparent_gerror); + g_test_add_func ("/gdbus/register-error", test_register_error); + + return g_test_run(); +} diff --git a/gio/tests/gdbus-example-export.c b/gio/tests/gdbus-example-export.c new file mode 100644 index 0000000..1823050 --- /dev/null +++ b/gio/tests/gdbus-example-export.c @@ -0,0 +1,335 @@ +#include +#include + +/* ---------------------------------------------------------------------------------------------------- */ + +/* The object we want to export */ +typedef struct _MyObjectClass MyObjectClass; +typedef struct _MyObject MyObject; + +struct _MyObjectClass +{ + GObjectClass parent_class; +}; + +struct _MyObject +{ + GObject parent_instance; + + gint count; + gchar *name; +}; + +enum +{ + PROP_0, + PROP_COUNT, + PROP_NAME +}; + +static GType my_object_get_type (void); +G_DEFINE_TYPE (MyObject, my_object, G_TYPE_OBJECT) + +static void +my_object_finalize (GObject *object) +{ + MyObject *myobj = (MyObject*)object; + + g_free (myobj->name); + + G_OBJECT_CLASS (my_object_parent_class)->finalize (object); +} + +static void +my_object_init (MyObject *object) +{ + object->count = 0; + object->name = NULL; +} + +static void +my_object_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MyObject *myobj = (MyObject*)object; + + switch (prop_id) + { + case PROP_COUNT: + g_value_set_int (value, myobj->count); + break; + + case PROP_NAME: + g_value_set_string (value, myobj->name); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +my_object_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MyObject *myobj = (MyObject*)object; + + switch (prop_id) + { + case PROP_COUNT: + myobj->count = g_value_get_int (value); + break; + + case PROP_NAME: + g_free (myobj->name); + myobj->name = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +my_object_class_init (MyObjectClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->finalize = my_object_finalize; + gobject_class->set_property = my_object_set_property; + gobject_class->get_property = my_object_get_property; + + g_object_class_install_property (gobject_class, + PROP_COUNT, + g_param_spec_int ("count", + "Count", + "Count", + 0, 99999, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "Name", + NULL, + G_PARAM_READWRITE)); +} + +/* A method that we want to export */ +static void +my_object_change_count (MyObject *myobj, + gint change) +{ + myobj->count = 2 * myobj->count + change; + + g_object_notify (G_OBJECT (myobj), "count"); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusNodeInfo *introspection_data = NULL; + +/* Introspection data for the service we are exporting */ +static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + ""; + + +static void +handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + MyObject *myobj = user_data; + + if (g_strcmp0 (method_name, "ChangeCount") == 0) + { + gint change; + g_variant_get (parameters, "(i)", &change); + + my_object_change_count (myobj, change); + + g_dbus_method_invocation_return_value (invocation, NULL); + } +} + +static GVariant * +handle_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + GVariant *ret; + MyObject *myobj = user_data; + + ret = NULL; + if (g_strcmp0 (property_name, "Count") == 0) + { + ret = g_variant_new_int32 (myobj->count); + } + else if (g_strcmp0 (property_name, "Name") == 0) + { + ret = g_variant_new_string (myobj->name ? myobj->name : ""); + } + + return ret; +} + +static gboolean +handle_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data) +{ + MyObject *myobj = user_data; + + if (g_strcmp0 (property_name, "Count") == 0) + { + g_object_set (myobj, "count", g_variant_get_int32 (value), NULL); + } + else if (g_strcmp0 (property_name, "Name") == 0) + { + g_object_set (myobj, "name", g_variant_get_string (value, NULL), NULL); + } + + return TRUE; +} + + +/* for now */ +static const GDBusInterfaceVTable interface_vtable = +{ + handle_method_call, + handle_get_property, + handle_set_property, + { 0 } +}; + +static void +send_property_change (GObject *obj, + GParamSpec *pspec, + GDBusConnection *connection) +{ + GVariantBuilder *builder; + GVariantBuilder *invalidated_builder; + MyObject *myobj = (MyObject *)obj; + + builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); + + if (g_strcmp0 (pspec->name, "count") == 0) + g_variant_builder_add (builder, + "{sv}", + "Count", g_variant_new_int32 (myobj->count)); + else if (g_strcmp0 (pspec->name, "name") == 0) + g_variant_builder_add (builder, + "{sv}", + "Name", g_variant_new_string (myobj->name ? myobj->name : "")); + + g_dbus_connection_emit_signal (connection, + NULL, + "/org/myorg/MyObject", + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(sa{sv}as)", + "org.myorg.MyObject", + builder, + invalidated_builder), + NULL); +} + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + MyObject *myobj = user_data; + guint registration_id; + + g_signal_connect (myobj, "notify", + G_CALLBACK (send_property_change), connection); + registration_id = g_dbus_connection_register_object (connection, + "/org/myorg/MyObject", + introspection_data->interfaces[0], + &interface_vtable, + myobj, + NULL, /* user_data_free_func */ + NULL); /* GError** */ + g_assert (registration_id > 0); +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + exit (1); +} + +int +main (int argc, char *argv[]) +{ + guint owner_id; + GMainLoop *loop; + MyObject *myobj; + + /* We are lazy here - we don't want to manually provide + * the introspection data structures - so we just build + * them from XML. + */ + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + g_assert (introspection_data != NULL); + + myobj = g_object_new (my_object_get_type (), NULL); + + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.myorg.MyObject", + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + myobj, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_bus_unown_name (owner_id); + + g_dbus_node_info_unref (introspection_data); + + g_object_unref (myobj); + + return 0; +} diff --git a/gio/tests/gdbus-example-objectmanager-client.c b/gio/tests/gdbus-example-objectmanager-client.c new file mode 100644 index 0000000..af69c02 --- /dev/null +++ b/gio/tests/gdbus-example-objectmanager-client.c @@ -0,0 +1,168 @@ + +#include "gdbus-object-manager-example/objectmanager-gen.h" + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +print_objects (GDBusObjectManager *manager) +{ + GList *objects; + GList *l; + + g_print ("Object manager at %s\n", g_dbus_object_manager_get_object_path (manager)); + objects = g_dbus_object_manager_get_objects (manager); + for (l = objects; l != NULL; l = l->next) + { + ExampleObject *object = EXAMPLE_OBJECT (l->data); + GList *interfaces; + GList *ll; + g_print (" - Object at %s\n", g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); + + interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object)); + for (ll = interfaces; ll != NULL; ll = ll->next) + { + GDBusInterface *interface = G_DBUS_INTERFACE (ll->data); + g_print (" - Interface %s\n", g_dbus_interface_get_info (interface)->name); + + /* Note that @interface is really a GDBusProxy instance - and additionally also + * an ExampleAnimal or ExampleCat instance - either of these can be used to + * invoke methods on the remote object. For example, the generated function + * + * void example_animal_call_poke_sync (ExampleAnimal *proxy, + * gboolean make_sad, + * gboolean make_happy, + * GCancellable *cancellable, + * GError **error); + * + * can be used to call the Poke() D-Bus method on the .Animal interface. + * Additionally, the generated function + * + * const gchar *example_animal_get_mood (ExampleAnimal *object); + * + * can be used to get the value of the :Mood property. + */ + } + g_list_free_full (interfaces, g_object_unref); + } + g_list_free_full (objects, g_object_unref); +} + +static void +on_object_added (GDBusObjectManager *manager, + GDBusObject *object, + gpointer user_data) +{ + gchar *owner; + owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (manager)); + g_print ("Added object at %s (owner %s)\n", g_dbus_object_get_object_path (object), owner); + g_free (owner); +} + +static void +on_object_removed (GDBusObjectManager *manager, + GDBusObject *object, + gpointer user_data) +{ + gchar *owner; + owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (manager)); + g_print ("Removed object at %s (owner %s)\n", g_dbus_object_get_object_path (object), owner); + g_free (owner); +} + +static void +on_notify_name_owner (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (object); + gchar *name_owner; + + name_owner = g_dbus_object_manager_client_get_name_owner (manager); + g_print ("name-owner: %s\n", name_owner); + g_free (name_owner); +} + +static void +on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager, + GDBusObjectProxy *object_proxy, + GDBusProxy *interface_proxy, + GVariant *changed_properties, + const gchar *const *invalidated_properties, + gpointer user_data) +{ + GVariantIter iter; + const gchar *key; + GVariant *value; + gchar *s; + + g_print ("Properties Changed on %s:\n", g_dbus_object_get_object_path (G_DBUS_OBJECT (object_proxy))); + g_variant_iter_init (&iter, changed_properties); + while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) + { + s = g_variant_print (value, TRUE); + g_print (" %s -> %s\n", key, s); + g_variant_unref (value); + g_free (s); + } +} + +gint +main (gint argc, gchar *argv[]) +{ + GDBusObjectManager *manager; + GMainLoop *loop; + GError *error; + gchar *name_owner; + + manager = NULL; + loop = NULL; + + loop = g_main_loop_new (NULL, FALSE); + + error = NULL; + manager = example_object_manager_client_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + "org.gtk.GDBus.Examples.ObjectManager", + "/example/Animals", + NULL, /* GCancellable */ + &error); + if (manager == NULL) + { + g_printerr ("Error getting object manager client: %s", error->message); + g_error_free (error); + goto out; + } + + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (manager)); + g_print ("name-owner: %s\n", name_owner); + g_free (name_owner); + + print_objects (manager); + + g_signal_connect (manager, + "notify::name-owner", + G_CALLBACK (on_notify_name_owner), + NULL); + g_signal_connect (manager, + "object-added", + G_CALLBACK (on_object_added), + NULL); + g_signal_connect (manager, + "object-removed", + G_CALLBACK (on_object_removed), + NULL); + g_signal_connect (manager, + "interface-proxy-properties-changed", + G_CALLBACK (on_interface_proxy_properties_changed), + NULL); + + g_main_loop_run (loop); + + out: + if (manager != NULL) + g_object_unref (manager); + if (loop != NULL) + g_main_loop_unref (loop); + + return 0; +} diff --git a/gio/tests/gdbus-example-objectmanager-server.c b/gio/tests/gdbus-example-objectmanager-server.c new file mode 100644 index 0000000..dcedba2 --- /dev/null +++ b/gio/tests/gdbus-example-objectmanager-server.c @@ -0,0 +1,160 @@ + +#include "gdbus-object-manager-example/objectmanager-gen.h" + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusObjectManagerServer *manager = NULL; + +static gboolean +on_animal_poke (ExampleAnimal *animal, + GDBusMethodInvocation *invocation, + gboolean make_sad, + gboolean make_happy, + gpointer user_data) +{ + if ((make_sad && make_happy) || (!make_sad && !make_happy)) + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.Examples.ObjectManager.Error.Failed", + "Exactly one of make_sad or make_happy must be TRUE"); + goto out; + } + + if (make_sad) + { + if (g_strcmp0 (example_animal_get_mood (animal), "Sad") == 0) + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.Examples.ObjectManager.Error.SadAnimalIsSad", + "Sad animal is already sad"); + goto out; + } + + example_animal_set_mood (animal, "Sad"); + example_animal_complete_poke (animal, invocation); + goto out; + } + + if (make_happy) + { + if (g_strcmp0 (example_animal_get_mood (animal), "Happy") == 0) + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.Examples.ObjectManager.Error.HappyAnimalIsHappy", + "Happy animal is already happy"); + goto out; + } + + example_animal_set_mood (animal, "Happy"); + example_animal_complete_poke (animal, invocation); + goto out; + } + + g_assert_not_reached (); + + out: + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + ExampleObjectSkeleton *object; + guint n; + + g_print ("Acquired a message bus connection\n"); + + /* Create a new org.freedesktop.DBus.ObjectManager rooted at /example/Animals */ + manager = g_dbus_object_manager_server_new ("/example/Animals"); + + for (n = 0; n < 10; n++) + { + gchar *s; + ExampleAnimal *animal; + + /* Create a new D-Bus object at the path /example/Animals/N where N is 000..009 */ + s = g_strdup_printf ("/example/Animals/%03d", n); + object = example_object_skeleton_new (s); + g_free (s); + + /* Make the newly created object export the interface + * org.gtk.GDBus.Example.ObjectManager.Animal (note + * that @object takes its own reference to @animal). + */ + animal = example_animal_skeleton_new (); + example_animal_set_mood (animal, "Happy"); + example_object_skeleton_set_animal (object, animal); + g_object_unref (animal); + + /* Cats are odd animals - so some of our objects implement the + * org.gtk.GDBus.Example.ObjectManager.Cat interface in addition + * to the .Animal interface + */ + if (n % 2 == 1) + { + ExampleCat *cat; + cat = example_cat_skeleton_new (); + example_object_skeleton_set_cat (object, cat); + g_object_unref (cat); + } + + /* Handle Poke() D-Bus method invocations on the .Animal interface */ + g_signal_connect (animal, + "handle-poke", + G_CALLBACK (on_animal_poke), + NULL); /* user_data */ + + /* Export the object (@manager takes its own reference to @object) */ + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object)); + g_object_unref (object); + } + + /* Export all objects */ + g_dbus_object_manager_server_set_connection (manager, connection); +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_print ("Acquired the name %s\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_print ("Lost the name %s\n", name); +} + + +gint +main (gint argc, gchar *argv[]) +{ + GMainLoop *loop; + guint id; + + loop = g_main_loop_new (NULL, FALSE); + + id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gtk.GDBus.Examples.ObjectManager", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + G_BUS_NAME_OWNER_FLAGS_REPLACE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + loop, + NULL); + + g_main_loop_run (loop); + + g_bus_unown_name (id); + g_main_loop_unref (loop); + + return 0; +} diff --git a/gio/tests/gdbus-example-own-name.c b/gio/tests/gdbus-example-own-name.c new file mode 100644 index 0000000..6c83f12 --- /dev/null +++ b/gio/tests/gdbus-example-own-name.c @@ -0,0 +1,84 @@ +#include + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + /* This is where we'd export some objects on the bus */ +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_print ("Acquired the name %s on the session bus\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_print ("Lost the name %s on the session bus\n", name); +} + +int +main (int argc, char *argv[]) +{ + guint owner_id; + GMainLoop *loop; + GBusNameOwnerFlags flags; + gboolean opt_replace; + gboolean opt_allow_replacement; + gchar *opt_name; + GOptionContext *opt_context; + GError *error; + GOptionEntry opt_entries[] = + { + { "replace", 'r', 0, G_OPTION_ARG_NONE, &opt_replace, "Replace existing name if possible", NULL }, + { "allow-replacement", 'a', 0, G_OPTION_ARG_NONE, &opt_allow_replacement, "Allow replacement", NULL }, + { "name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, "Name to acquire", NULL }, + G_OPTION_ENTRY_NULL + }; + + error = NULL; + opt_name = NULL; + opt_replace = FALSE; + opt_allow_replacement = FALSE; + opt_context = g_option_context_new ("g_bus_own_name() example"); + g_option_context_add_main_entries (opt_context, opt_entries, NULL); + if (!g_option_context_parse (opt_context, &argc, &argv, &error)) + { + g_printerr ("Error parsing options: %s", error->message); + return 1; + } + if (opt_name == NULL) + { + g_printerr ("Incorrect usage, try --help.\n"); + return 1; + } + + flags = G_BUS_NAME_OWNER_FLAGS_NONE; + if (opt_replace) + flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; + if (opt_allow_replacement) + flags |= G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; + + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + opt_name, + flags, + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_bus_unown_name (owner_id); + + return 0; +} diff --git a/gio/tests/gdbus-example-peer.c b/gio/tests/gdbus-example-peer.c new file mode 100755 index 0000000..f57d368 --- /dev/null +++ b/gio/tests/gdbus-example-peer.c @@ -0,0 +1,394 @@ +/* + +Usage examples (modulo addresses / credentials). + +UNIX domain socket transport: + + Server: + $ ./gdbus-example-peer --server --address unix:abstract=myaddr + Server is listening at: unix:abstract=myaddr + Client connected. + Peer credentials: GCredentials:unix-user=500,unix-group=500,unix-process=13378 + Negotiated capabilities: unix-fd-passing=1 + Client said: Hey, it's 1273093080 already! + + Client: + $ ./gdbus-example-peer --address unix:abstract=myaddr + Connected. + Negotiated capabilities: unix-fd-passing=1 + Server said: You said 'Hey, it's 1273093080 already!'. KTHXBYE! + +Nonce-secured TCP transport on the same host: + + Server: + $ ./gdbus-example-peer --server --address nonce-tcp: + Server is listening at: nonce-tcp:host=localhost,port=43077,noncefile=/tmp/gdbus-nonce-file-X1ZNCV + Client connected. + Peer credentials: (no credentials received) + Negotiated capabilities: unix-fd-passing=0 + Client said: Hey, it's 1273093206 already! + + Client: + $ ./gdbus-example-peer -address nonce-tcp:host=localhost,port=43077,noncefile=/tmp/gdbus-nonce-file-X1ZNCV + Connected. + Negotiated capabilities: unix-fd-passing=0 + Server said: You said 'Hey, it's 1273093206 already!'. KTHXBYE! + +TCP transport on two different hosts with a shared home directory: + + Server: + host1 $ ./gdbus-example-peer --server --address tcp:host=0.0.0.0 + Server is listening at: tcp:host=0.0.0.0,port=46314 + Client connected. + Peer credentials: (no credentials received) + Negotiated capabilities: unix-fd-passing=0 + Client said: Hey, it's 1273093337 already! + + Client: + host2 $ ./gdbus-example-peer -a tcp:host=host1,port=46314 + Connected. + Negotiated capabilities: unix-fd-passing=0 + Server said: You said 'Hey, it's 1273093337 already!'. KTHXBYE! + +TCP transport on two different hosts without authentication: + + Server: + host1 $ ./gdbus-example-peer --server --address tcp:host=0.0.0.0 --allow-anonymous + Server is listening at: tcp:host=0.0.0.0,port=59556 + Client connected. + Peer credentials: (no credentials received) + Negotiated capabilities: unix-fd-passing=0 + Client said: Hey, it's 1273093652 already! + + Client: + host2 $ ./gdbus-example-peer -a tcp:host=host1,port=59556 + Connected. + Negotiated capabilities: unix-fd-passing=0 + Server said: You said 'Hey, it's 1273093652 already!'. KTHXBYE! + + */ + +#include +#include + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusNodeInfo *introspection_data = NULL; + +/* Introspection data for the service we are exporting */ +static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " + " " + ""; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + if (g_strcmp0 (method_name, "HelloWorld") == 0) + { + const gchar *greeting; + gchar *response; + + g_variant_get (parameters, "(&s)", &greeting); + response = g_strdup_printf ("You said '%s'. KTHXBYE!", greeting); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", response)); + g_free (response); + g_print ("Client said: %s\n", greeting); + } +} + +static const GDBusInterfaceVTable interface_vtable = +{ + handle_method_call, + NULL, + NULL, + { 0 } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +connection_closed (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *Error, + gpointer user_data) +{ + g_print ("Client disconnected.\n"); + g_object_unref (connection); +} + +static gboolean +on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + guint registration_id; + GCredentials *credentials; + gchar *s; + + credentials = g_dbus_connection_get_peer_credentials (connection); + if (credentials == NULL) + s = g_strdup ("(no credentials received)"); + else + s = g_credentials_to_string (credentials); + + + g_print ("Client connected.\n" + "Peer credentials: %s\n" + "Negotiated capabilities: unix-fd-passing=%d\n", + s, + g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); + + g_object_ref (connection); + g_signal_connect (connection, "closed", G_CALLBACK (connection_closed), NULL); + registration_id = g_dbus_connection_register_object (connection, + "/org/gtk/GDBus/TestObject", + introspection_data->interfaces[0], + &interface_vtable, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + NULL); /* GError** */ + g_assert (registration_id > 0); + + return TRUE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +allow_mechanism_cb (GDBusAuthObserver *observer, + const gchar *mechanism, + G_GNUC_UNUSED gpointer user_data) +{ + /* + * In a production GDBusServer that only needs to work on modern Unix + * platforms, consider requiring EXTERNAL (credentials-passing), + * which is the recommended authentication mechanism for AF_UNIX + * sockets: + * + * if (g_strcmp0 (mechanism, "EXTERNAL") == 0) + * return TRUE; + * + * return FALSE; + * + * For this example we accept everything. + */ + + g_print ("Considering whether to accept %s authentication...\n", mechanism); + return TRUE; +} + +static gboolean +authorize_authenticated_peer_cb (GDBusAuthObserver *observer, + G_GNUC_UNUSED GIOStream *stream, + GCredentials *credentials, + G_GNUC_UNUSED gpointer user_data) +{ + gboolean authorized = FALSE; + + g_print ("Considering whether to authorize authenticated peer...\n"); + + if (credentials != NULL) + { + GCredentials *own_credentials; + gchar *credentials_string = NULL; + + credentials_string = g_credentials_to_string (credentials); + g_print ("Peer's credentials: %s\n", credentials_string); + g_free (credentials_string); + + own_credentials = g_credentials_new (); + + credentials_string = g_credentials_to_string (own_credentials); + g_print ("Server's credentials: %s\n", credentials_string); + g_free (credentials_string); + + if (g_credentials_is_same_user (credentials, own_credentials, NULL)) + authorized = TRUE; + + g_object_unref (own_credentials); + } + + if (!authorized) + { + /* In most servers you'd want to reject this, but for this example + * we allow it. */ + g_print ("A server would often not want to authorize this identity\n"); + g_print ("Authorizing it anyway for demonstration purposes\n"); + authorized = TRUE; + } + + return authorized; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, char *argv[]) +{ + gint ret; + gboolean opt_server; + gchar *opt_address; + GOptionContext *opt_context; + gboolean opt_allow_anonymous; + GError *error; + GOptionEntry opt_entries[] = + { + { "server", 's', 0, G_OPTION_ARG_NONE, &opt_server, "Start a server instead of a client", NULL }, + { "address", 'a', 0, G_OPTION_ARG_STRING, &opt_address, "D-Bus address to use", NULL }, + { "allow-anonymous", 'n', 0, G_OPTION_ARG_NONE, &opt_allow_anonymous, "Allow anonymous authentication", NULL }, + G_OPTION_ENTRY_NULL + }; + + ret = 1; + + opt_address = NULL; + opt_server = FALSE; + opt_allow_anonymous = FALSE; + + opt_context = g_option_context_new ("peer-to-peer example"); + error = NULL; + g_option_context_add_main_entries (opt_context, opt_entries, NULL); + if (!g_option_context_parse (opt_context, &argc, &argv, &error)) + { + g_printerr ("Error parsing options: %s\n", error->message); + g_error_free (error); + goto out; + } + if (opt_address == NULL) + { + g_printerr ("Incorrect usage, try --help.\n"); + goto out; + } + if (!opt_server && opt_allow_anonymous) + { + g_printerr ("The --allow-anonymous option only makes sense when used with --server.\n"); + goto out; + } + + /* We are lazy here - we don't want to manually provide + * the introspection data structures - so we just build + * them from XML. + */ + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + g_assert (introspection_data != NULL); + + if (opt_server) + { + GDBusAuthObserver *observer; + GDBusServer *server; + gchar *guid; + GMainLoop *loop; + GDBusServerFlags server_flags; + + guid = g_dbus_generate_guid (); + + server_flags = G_DBUS_SERVER_FLAGS_NONE; + if (opt_allow_anonymous) + server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; + + observer = g_dbus_auth_observer_new (); + g_signal_connect (observer, "allow-mechanism", G_CALLBACK (allow_mechanism_cb), NULL); + g_signal_connect (observer, "authorize-authenticated-peer", G_CALLBACK (authorize_authenticated_peer_cb), NULL); + + error = NULL; + server = g_dbus_server_new_sync (opt_address, + server_flags, + guid, + observer, + NULL, /* GCancellable */ + &error); + g_dbus_server_start (server); + + g_object_unref (observer); + g_free (guid); + + if (server == NULL) + { + g_printerr ("Error creating server at address %s: %s\n", opt_address, error->message); + g_error_free (error); + goto out; + } + g_print ("Server is listening at: %s\n", g_dbus_server_get_client_address (server)); + g_signal_connect (server, + "new-connection", + G_CALLBACK (on_new_connection), + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_object_unref (server); + g_main_loop_unref (loop); + } + else + { + GDBusConnection *connection; + const gchar *greeting_response; + GVariant *value; + gchar *greeting; + + error = NULL; + connection = g_dbus_connection_new_for_address_sync (opt_address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* GCancellable */ + &error); + if (connection == NULL) + { + g_printerr ("Error connecting to D-Bus address %s: %s\n", opt_address, error->message); + g_error_free (error); + goto out; + } + + g_print ("Connected.\n" + "Negotiated capabilities: unix-fd-passing=%d\n", + g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); + + greeting = g_strdup_printf ("Hey, it's %" G_GINT64_FORMAT " already!", + g_get_real_time () / G_USEC_PER_SEC); + value = g_dbus_connection_call_sync (connection, + NULL, /* bus_name */ + "/org/gtk/GDBus/TestObject", + "org.gtk.GDBus.TestPeerInterface", + "HelloWorld", + g_variant_new ("(s)", greeting), + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (value == NULL) + { + g_printerr ("Error invoking HelloWorld(): %s\n", error->message); + g_error_free (error); + goto out; + } + g_variant_get (value, "(&s)", &greeting_response); + g_print ("Server said: %s\n", greeting_response); + g_variant_unref (value); + + g_object_unref (connection); + } + g_dbus_node_info_unref (introspection_data); + + ret = 0; + + out: + return ret; +} diff --git a/gio/tests/gdbus-example-proxy-subclass.c b/gio/tests/gdbus-example-proxy-subclass.c new file mode 100644 index 0000000..ef2ed20 --- /dev/null +++ b/gio/tests/gdbus-example-proxy-subclass.c @@ -0,0 +1,358 @@ + +#include + +/* ---------------------------------------------------------------------------------------------------- */ +/* The D-Bus interface definition we want to create a GDBusProxy-derived type for: */ +/* ---------------------------------------------------------------------------------------------------- */ + +static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +/* ---------------------------------------------------------------------------------------------------- */ +/* Definition of the AccountsUser type */ +/* ---------------------------------------------------------------------------------------------------- */ + +#define ACCOUNTS_TYPE_USER (accounts_user_get_type ()) +#define ACCOUNTS_USER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ACCOUNTS_TYPE_USER, AccountsUser)) +#define ACCOUNTS_USER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), ACCOUNTS_TYPE_USER, AccountsUserClass)) +#define ACCOUNTS_USER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ACCOUNTS_TYPE_USER, AccountsUserClass)) +#define ACCOUNTS_IS_USER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ACCOUNTS_TYPE_USER)) +#define ACCOUNTS_IS_USER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), ACCOUNTS_TYPE_USER)) + +typedef struct _AccountsUser AccountsUser; +typedef struct _AccountsUserClass AccountsUserClass; +typedef struct _AccountsUserPrivate AccountsUserPrivate; + +struct _AccountsUser +{ + /*< private >*/ + GDBusProxy parent_instance; + AccountsUserPrivate *priv; +}; + +struct _AccountsUserClass +{ + /*< private >*/ + GDBusProxyClass parent_class; + void (*changed) (AccountsUser *user); +}; + +GType accounts_user_get_type (void) G_GNUC_CONST; + +const gchar *accounts_user_get_user_name (AccountsUser *user); +const gchar *accounts_user_get_real_name (AccountsUser *user); +gboolean accounts_user_get_automatic_login (AccountsUser *user); + +void accounts_user_frobnicate (AccountsUser *user, + const gchar *flux, + gint baz, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gchar *accounts_user_frobnicate_finish (AccountsUser *user, + GAsyncResult *res, + GError **error); +gchar *accounts_user_frobnicate_sync (AccountsUser *user, + const gchar *flux, + gint baz, + GCancellable *cancellable, + GError **error); + +/* ---------------------------------------------------------------------------------------------------- */ +/* Implementation of the AccountsUser type */ +/* ---------------------------------------------------------------------------------------------------- */ + +/* A more efficient approach than parsing XML is to use const static + * GDBusInterfaceInfo, GDBusMethodInfo, ... structures + */ +static GDBusInterfaceInfo * +accounts_user_get_interface_info (void) +{ + static gsize has_info = 0; + static GDBusInterfaceInfo *info = NULL; + if (g_once_init_enter (&has_info)) + { + GDBusNodeInfo *introspection_data; + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + info = introspection_data->interfaces[0]; + g_once_init_leave (&has_info, 1); + } + return info; +} + +enum +{ + PROP_0, + PROP_USER_NAME, + PROP_REAL_NAME, + PROP_AUTOMATIC_LOGIN, +}; + +enum +{ + CHANGED_SIGNAL, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +G_DEFINE_TYPE (AccountsUser, accounts_user, G_TYPE_DBUS_PROXY) + +static void +accounts_user_finalize (GObject *object) +{ + G_GNUC_UNUSED AccountsUser *user = ACCOUNTS_USER (object); + + if (G_OBJECT_CLASS (accounts_user_parent_class)->finalize != NULL) + G_OBJECT_CLASS (accounts_user_parent_class)->finalize (object); +} + +static void +accounts_user_init (AccountsUser *user) +{ + /* Sets the expected interface */ + g_dbus_proxy_set_interface_info (G_DBUS_PROXY (user), accounts_user_get_interface_info ()); +} + +static void +accounts_user_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + AccountsUser *user = ACCOUNTS_USER (object); + + switch (prop_id) + { + case PROP_USER_NAME: + g_value_set_string (value, accounts_user_get_user_name (user)); + break; + + case PROP_REAL_NAME: + g_value_set_string (value, accounts_user_get_real_name (user)); + break; + + case PROP_AUTOMATIC_LOGIN: + g_value_set_boolean (value, accounts_user_get_automatic_login (user)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +const gchar * +accounts_user_get_user_name (AccountsUser *user) +{ + GVariant *value; + const gchar *ret; + g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL); + value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "UserName"); + ret = g_variant_get_string (value, NULL); + g_variant_unref (value); + return ret; +} + +const gchar * +accounts_user_get_real_name (AccountsUser *user) +{ + GVariant *value; + const gchar *ret; + g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL); + value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "RealName"); + ret = g_variant_get_string (value, NULL); + g_variant_unref (value); + return ret; +} + +gboolean +accounts_user_get_automatic_login (AccountsUser *user) +{ + GVariant *value; + gboolean ret; + g_return_val_if_fail (ACCOUNTS_IS_USER (user), FALSE); + value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "AutomaticLogin"); + ret = g_variant_get_boolean (value); + g_variant_unref (value); + return ret; +} + +static void +accounts_user_g_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters) +{ + AccountsUser *user = ACCOUNTS_USER (proxy); + if (g_strcmp0 (signal_name, "Changed") == 0) + g_signal_emit (user, signals[CHANGED_SIGNAL], 0); +} + +static void +accounts_user_g_properties_changed (GDBusProxy *proxy, + GVariant *changed_properties, + const gchar* const *invalidated_properties) +{ + AccountsUser *user = ACCOUNTS_USER (proxy); + GVariantIter *iter; + const gchar *key; + + if (changed_properties != NULL) + { + g_variant_get (changed_properties, "a{sv}", &iter); + while (g_variant_iter_next (iter, "{&sv}", &key, NULL)) + { + if (g_strcmp0 (key, "AutomaticLogin") == 0) + g_object_notify (G_OBJECT (user), "automatic-login"); + else if (g_strcmp0 (key, "RealName") == 0) + g_object_notify (G_OBJECT (user), "real-name"); + else if (g_strcmp0 (key, "UserName") == 0) + g_object_notify (G_OBJECT (user), "user-name"); + } + g_variant_iter_free (iter); + } +} + +static void +accounts_user_class_init (AccountsUserClass *klass) +{ + GObjectClass *gobject_class; + GDBusProxyClass *proxy_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->get_property = accounts_user_get_property; + gobject_class->finalize = accounts_user_finalize; + + proxy_class = G_DBUS_PROXY_CLASS (klass); + proxy_class->g_signal = accounts_user_g_signal; + proxy_class->g_properties_changed = accounts_user_g_properties_changed; + + g_object_class_install_property (gobject_class, + PROP_USER_NAME, + g_param_spec_string ("user-name", + "User Name", + "The user name of the user", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_REAL_NAME, + g_param_spec_string ("real-name", + "Real Name", + "The real name of the user", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_AUTOMATIC_LOGIN, + g_param_spec_boolean ("automatic-login", + "Automatic Login", + "Whether the user is automatically logged in", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + signals[CHANGED_SIGNAL] = g_signal_new ("changed", + ACCOUNTS_TYPE_USER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (AccountsUserClass, changed), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +gchar * +accounts_user_frobnicate_sync (AccountsUser *user, + const gchar *flux, + gint baz, + GCancellable *cancellable, + GError **error) +{ + gchar *ret; + GVariant *value; + + g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL); + + ret = NULL; + + value = g_dbus_proxy_call_sync (G_DBUS_PROXY (user), + "Frobnicate", + g_variant_new ("(si)", + flux, + baz), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + if (value != NULL) + { + g_variant_get (value, "(s)", &ret); + g_variant_unref (value); + } + return ret; +} + +void +accounts_user_frobnicate (AccountsUser *user, + const gchar *flux, + gint baz, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (ACCOUNTS_IS_USER (user)); + g_dbus_proxy_call (G_DBUS_PROXY (user), + "Frobnicate", + g_variant_new ("(si)", + flux, + baz), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + callback, + user_data); +} + + +gchar * +accounts_user_frobnicate_finish (AccountsUser *user, + GAsyncResult *res, + GError **error) +{ + gchar *ret; + GVariant *value; + + ret = NULL; + value = g_dbus_proxy_call_finish (G_DBUS_PROXY (user), res, error); + if (value != NULL) + { + g_variant_get (value, "(s)", &ret); + g_variant_unref (value); + } + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +gint +main (gint argc, gchar *argv[]) +{ + return 0; +} diff --git a/gio/tests/gdbus-example-server.c b/gio/tests/gdbus-example-server.c new file mode 100644 index 0000000..b19f650 --- /dev/null +++ b/gio/tests/gdbus-example-server.c @@ -0,0 +1,391 @@ +#include +#include + +#ifdef G_OS_UNIX +#include +/* For STDOUT_FILENO */ +#include +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusNodeInfo *introspection_data = NULL; + +/* Introspection data for the service we are exporting */ +static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + if (g_strcmp0 (method_name, "HelloWorld") == 0) + { + const gchar *greeting; + + g_variant_get (parameters, "(&s)", &greeting); + + if (g_strcmp0 (greeting, "Return Unregistered") == 0) + { + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_FAILED_HANDLED, + "As requested, here's a GError not registered (G_IO_ERROR_FAILED_HANDLED)"); + } + else if (g_strcmp0 (greeting, "Return Registered") == 0) + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_MATCH_RULE_NOT_FOUND, + "As requested, here's a GError that is registered (G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)"); + } + else if (g_strcmp0 (greeting, "Return Raw") == 0) + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.SomeErrorName", + "As requested, here's a raw D-Bus error"); + } + else + { + gchar *response; + response = g_strdup_printf ("You greeted me with '%s'. Thanks!", greeting); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", response)); + g_free (response); + } + } + else if (g_strcmp0 (method_name, "EmitSignal") == 0) + { + GError *local_error; + gdouble speed_in_mph; + gchar *speed_as_string; + + g_variant_get (parameters, "(d)", &speed_in_mph); + speed_as_string = g_strdup_printf ("%g mph!", speed_in_mph); + + local_error = NULL; + g_dbus_connection_emit_signal (connection, + NULL, + object_path, + interface_name, + "VelocityChanged", + g_variant_new ("(ds)", + speed_in_mph, + speed_as_string), + &local_error); + g_assert_no_error (local_error); + g_free (speed_as_string); + + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_strcmp0 (method_name, "GimmeStdout") == 0) + { +#ifdef G_OS_UNIX + if (g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) + { + GDBusMessage *reply; + GUnixFDList *fd_list; + GError *error; + + fd_list = g_unix_fd_list_new (); + error = NULL; + g_unix_fd_list_append (fd_list, STDOUT_FILENO, &error); + g_assert_no_error (error); + + reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_dbus_message_set_unix_fd_list (reply, fd_list); + + error = NULL; + g_dbus_connection_send_message (connection, + reply, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + NULL, /* out_serial */ + &error); + g_assert_no_error (error); + + g_object_unref (invocation); + g_object_unref (fd_list); + g_object_unref (reply); + } + else + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.Failed", + "Your message bus daemon does not support file descriptor passing (need D-Bus >= 1.3.0)"); + } +#else + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.NotOnUnix", + "Your OS does not support file descriptor passing"); +#endif + } +} + +static gchar *_global_title = NULL; + +static gboolean swap_a_and_b = FALSE; + +static GVariant * +handle_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + GVariant *ret; + + ret = NULL; + if (g_strcmp0 (property_name, "FluxCapicitorName") == 0) + { + ret = g_variant_new_string ("DeLorean"); + } + else if (g_strcmp0 (property_name, "Title") == 0) + { + if (_global_title == NULL) + _global_title = g_strdup ("Back To C!"); + ret = g_variant_new_string (_global_title); + } + else if (g_strcmp0 (property_name, "ReadingAlwaysThrowsError") == 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Hello %s. I thought I said reading this property " + "always results in an error. kthxbye", + sender); + } + else if (g_strcmp0 (property_name, "WritingAlwaysThrowsError") == 0) + { + ret = g_variant_new_string ("There's no home like home"); + } + else if (g_strcmp0 (property_name, "Foo") == 0) + { + ret = g_variant_new_string (swap_a_and_b ? "Tock" : "Tick"); + } + else if (g_strcmp0 (property_name, "Bar") == 0) + { + ret = g_variant_new_string (swap_a_and_b ? "Tick" : "Tock"); + } + + return ret; +} + +static gboolean +handle_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data) +{ + if (g_strcmp0 (property_name, "Title") == 0) + { + if (g_strcmp0 (_global_title, g_variant_get_string (value, NULL)) != 0) + { + GVariantBuilder *builder; + GError *local_error; + + g_free (_global_title); + _global_title = g_variant_dup_string (value, NULL); + + local_error = NULL; + builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (builder, + "{sv}", + "Title", + g_variant_new_string (_global_title)); + g_dbus_connection_emit_signal (connection, + NULL, + object_path, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(sa{sv}as)", + interface_name, + builder, + NULL), + &local_error); + g_assert_no_error (local_error); + } + } + else if (g_strcmp0 (property_name, "ReadingAlwaysThrowsError") == 0) + { + /* do nothing - they can't read it after all! */ + } + else if (g_strcmp0 (property_name, "WritingAlwaysThrowsError") == 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Hello AGAIN %s. I thought I said writing this property " + "always results in an error. kthxbye", + sender); + } + + return *error == NULL; +} + + +/* for now */ +static const GDBusInterfaceVTable interface_vtable = +{ + handle_method_call, + handle_get_property, + handle_set_property, + { 0 } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +on_timeout_cb (gpointer user_data) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (user_data); + GVariantBuilder *builder; + GVariantBuilder *invalidated_builder; + GError *error; + + swap_a_and_b = !swap_a_and_b; + + error = NULL; + builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); + g_variant_builder_add (builder, + "{sv}", + "Foo", + g_variant_new_string (swap_a_and_b ? "Tock" : "Tick")); + g_variant_builder_add (builder, + "{sv}", + "Bar", + g_variant_new_string (swap_a_and_b ? "Tick" : "Tock")); + g_dbus_connection_emit_signal (connection, + NULL, + "/org/gtk/GDBus/TestObject", + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(sa{sv}as)", + "org.gtk.GDBus.TestInterface", + builder, + invalidated_builder), + &error); + g_assert_no_error (error); + + + return G_SOURCE_CONTINUE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + guint registration_id; + + registration_id = g_dbus_connection_register_object (connection, + "/org/gtk/GDBus/TestObject", + introspection_data->interfaces[0], + &interface_vtable, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + NULL); /* GError** */ + g_assert (registration_id > 0); + + /* swap value of properties Foo and Bar every two seconds */ + g_timeout_add_seconds (2, + on_timeout_cb, + connection); +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + exit (1); +} + +int +main (int argc, char *argv[]) +{ + guint owner_id; + GMainLoop *loop; + + /* We are lazy here - we don't want to manually provide + * the introspection data structures - so we just build + * them from XML. + */ + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + g_assert (introspection_data != NULL); + + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gtk.GDBus.TestServer", + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_bus_unown_name (owner_id); + + g_dbus_node_info_unref (introspection_data); + + return 0; +} diff --git a/gio/tests/gdbus-example-subtree.c b/gio/tests/gdbus-example-subtree.c new file mode 100644 index 0000000..3254a27 --- /dev/null +++ b/gio/tests/gdbus-example-subtree.c @@ -0,0 +1,402 @@ +#include +#include +#include + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusNodeInfo *introspection_data = NULL; +static GDBusInterfaceInfo *manager_interface_info = NULL; +static GDBusInterfaceInfo *block_interface_info = NULL; +static GDBusInterfaceInfo *partition_interface_info = NULL; + +/* Introspection data for the service we are exporting */ +static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +manager_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + const gchar *greeting; + gchar *response; + + g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Manager"); + g_assert_cmpstr (method_name, ==, "Hello"); + + g_variant_get (parameters, "(&s)", &greeting); + + response = g_strdup_printf ("Method %s.%s with user_data '%s' on object path %s called with arg '%s'", + interface_name, + method_name, + (const gchar *) user_data, + object_path, + greeting); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", response)); + g_free (response); +} + +const GDBusInterfaceVTable manager_vtable = +{ + manager_method_call, + NULL, /* get_property */ + NULL, /* set_property */ + { 0 } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +block_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Block"); + + if (g_strcmp0 (method_name, "Hello") == 0) + { + const gchar *greeting; + gchar *response; + + g_variant_get (parameters, "(&s)", &greeting); + + response = g_strdup_printf ("Method %s.%s with user_data '%s' on object path %s called with arg '%s'", + interface_name, + method_name, + (const gchar *) user_data, + object_path, + greeting); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", response)); + g_free (response); + } + else if (g_strcmp0 (method_name, "DoStuff") == 0) + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.TestSubtree.Error.Failed", + "This method intentionally always fails"); + } + else + { + g_assert_not_reached (); + } +} + +static GVariant * +block_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + GVariant *ret; + const gchar *node; + gint major; + gint minor; + + node = strrchr (object_path, '/') + 1; + if (g_str_has_prefix (node, "sda")) + major = 8; + else + major = 9; + if (strlen (node) == 4) + minor = node[3] - '0'; + else + minor = 0; + + ret = NULL; + if (g_strcmp0 (property_name, "Major") == 0) + { + ret = g_variant_new_int32 (major); + } + else if (g_strcmp0 (property_name, "Minor") == 0) + { + ret = g_variant_new_int32 (minor); + } + else if (g_strcmp0 (property_name, "Notes") == 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Hello %s. I thought I said reading this property " + "always results in an error. kthxbye", + sender); + } + else + { + g_assert_not_reached (); + } + + return ret; +} + +static gboolean +block_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data) +{ + /* TODO */ + g_assert_not_reached (); +} + +const GDBusInterfaceVTable block_vtable = +{ + block_method_call, + block_get_property, + block_set_property, + { 0 } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +partition_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + const gchar *greeting; + gchar *response; + + g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Partition"); + g_assert_cmpstr (method_name, ==, "Hello"); + + g_variant_get (parameters, "(&s)", &greeting); + + response = g_strdup_printf ("Method %s.%s with user_data '%s' on object path %s called with arg '%s'", + interface_name, + method_name, + (const gchar *) user_data, + object_path, + greeting); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", response)); + g_free (response); +} + +const GDBusInterfaceVTable partition_vtable = +{ + partition_method_call, + NULL, + NULL, + { 0 } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar ** +subtree_enumerate (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + gpointer user_data) +{ + gchar **nodes; + GPtrArray *p; + + p = g_ptr_array_new (); + g_ptr_array_add (p, g_strdup ("sda")); + g_ptr_array_add (p, g_strdup ("sda1")); + g_ptr_array_add (p, g_strdup ("sda2")); + g_ptr_array_add (p, g_strdup ("sda3")); + g_ptr_array_add (p, g_strdup ("sdb")); + g_ptr_array_add (p, g_strdup ("sdb1")); + g_ptr_array_add (p, g_strdup ("sdc")); + g_ptr_array_add (p, g_strdup ("sdc1")); + g_ptr_array_add (p, NULL); + nodes = (gchar **) g_ptr_array_free (p, FALSE); + + return nodes; +} + +static GDBusInterfaceInfo ** +subtree_introspect (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *node, + gpointer user_data) +{ + GPtrArray *p; + + p = g_ptr_array_new (); + if (node == NULL) + { + g_ptr_array_add (p, g_dbus_interface_info_ref (manager_interface_info)); + } + else + { + g_ptr_array_add (p, g_dbus_interface_info_ref (block_interface_info)); + if (strlen (node) == 4) + g_ptr_array_add (p, + g_dbus_interface_info_ref (partition_interface_info)); + } + + g_ptr_array_add (p, NULL); + + return (GDBusInterfaceInfo **) g_ptr_array_free (p, FALSE); +} + +static const GDBusInterfaceVTable * +subtree_dispatch (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *node, + gpointer *out_user_data, + gpointer user_data) +{ + const GDBusInterfaceVTable *vtable_to_return; + gpointer user_data_to_return; + + if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Manager") == 0) + { + user_data_to_return = "The Root"; + vtable_to_return = &manager_vtable; + } + else + { + if (strlen (node) == 4) + user_data_to_return = "A partition"; + else + user_data_to_return = "A block device"; + + if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Block") == 0) + vtable_to_return = &block_vtable; + else if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Partition") == 0) + vtable_to_return = &partition_vtable; + else + g_assert_not_reached (); + } + + *out_user_data = user_data_to_return; + + return vtable_to_return; +} + +const GDBusSubtreeVTable subtree_vtable = +{ + subtree_enumerate, + subtree_introspect, + subtree_dispatch, + { 0 } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + guint registration_id; + + registration_id = g_dbus_connection_register_subtree (connection, + "/org/gtk/GDBus/TestSubtree/Devices", + &subtree_vtable, + G_DBUS_SUBTREE_FLAGS_NONE, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + NULL); /* GError** */ + g_assert (registration_id > 0); +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + exit (1); +} + +int +main (int argc, char *argv[]) +{ + guint owner_id; + GMainLoop *loop; + + /* We are lazy here - we don't want to manually provide + * the introspection data structures - so we just build + * them from XML. + */ + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + g_assert (introspection_data != NULL); + + manager_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Manager"); + block_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Block"); + partition_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Partition"); + g_assert (manager_interface_info != NULL); + g_assert (block_interface_info != NULL); + g_assert (partition_interface_info != NULL); + + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gtk.GDBus.TestSubtree", + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_bus_unown_name (owner_id); + + g_dbus_node_info_unref (introspection_data); + + return 0; +} diff --git a/gio/tests/gdbus-example-unix-fd-client.c b/gio/tests/gdbus-example-unix-fd-client.c new file mode 100644 index 0000000..c676bcb --- /dev/null +++ b/gio/tests/gdbus-example-unix-fd-client.c @@ -0,0 +1,131 @@ +#include +#include + +#include +#include + +#include + +#include +#include + +/* see gdbus-example-server.c for the server implementation */ +static gint +get_server_stdout (GDBusConnection *connection, + const gchar *name_owner, + GError **error) +{ + GDBusMessage *method_call_message; + GDBusMessage *method_reply_message; + GUnixFDList *fd_list; + gint fd; + + fd = -1; + method_call_message = NULL; + method_reply_message = NULL; + + method_call_message = g_dbus_message_new_method_call (name_owner, + "/org/gtk/GDBus/TestObject", + "org.gtk.GDBus.TestInterface", + "GimmeStdout"); + method_reply_message = g_dbus_connection_send_message_with_reply_sync (connection, + method_call_message, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, /* out_serial */ + NULL, /* cancellable */ + error); + if (method_reply_message == NULL) + goto out; + + if (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_ERROR) + { + g_dbus_message_to_gerror (method_reply_message, error); + goto out; + } + + fd_list = g_dbus_message_get_unix_fd_list (method_reply_message); + fd = g_unix_fd_list_get (fd_list, 0, error); + + out: + g_object_unref (method_call_message); + g_object_unref (method_reply_message); + + return fd; +} + +static void +on_name_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + gint fd; + GError *error; + + error = NULL; + fd = get_server_stdout (connection, name_owner, &error); + if (fd == -1) + { + g_printerr ("Error invoking GimmeStdout(): %s\n", + error->message); + g_error_free (error); + exit (1); + } + else + { + gchar *now_buf = NULL; + gssize len; + gchar *str; + GDateTime *now = g_date_time_new_now_local (); + + g_assert_nonnull (now); + now_buf = g_date_time_format (now, "%Y-%m-%d %H:%M:%S"); + g_date_time_unref (now); + + str = g_strdup_printf ("On %s, gdbus-example-unix-fd-client with pid %d was here!\n", + now_buf, + (gint) getpid ()); + len = strlen (str); + g_warn_if_fail (write (fd, str, len) == len); + close (fd); + + g_print ("Wrote the following on server's stdout:\n%s", str); + + g_free (str); + g_free (now_buf); + exit (0); + } +} + +static void +on_name_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_printerr ("Failed to get name owner for %s\n" + "Is ./gdbus-example-server running?\n", + name); + exit (1); +} + +int +main (int argc, char *argv[]) +{ + guint watcher_id; + GMainLoop *loop; + + watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, + "org.gtk.GDBus.TestServer", + G_BUS_NAME_WATCHER_FLAGS_NONE, + on_name_appeared, + on_name_vanished, + NULL, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_bus_unwatch_name (watcher_id); + return 0; +} diff --git a/gio/tests/gdbus-example-watch-name.c b/gio/tests/gdbus-example-watch-name.c new file mode 100644 index 0000000..27cc3f3 --- /dev/null +++ b/gio/tests/gdbus-example-watch-name.c @@ -0,0 +1,86 @@ +#include + +static gchar *opt_name = NULL; +static gboolean opt_system_bus = FALSE; +static gboolean opt_auto_start = FALSE; + +static GOptionEntry opt_entries[] = +{ + { "name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, "Name to watch", NULL }, + { "system-bus", 's', 0, G_OPTION_ARG_NONE, &opt_system_bus, "Use the system-bus instead of the session-bus", NULL }, + { "auto-start", 'a', 0, G_OPTION_ARG_NONE, &opt_auto_start, "Instruct the bus to launch an owner for the name", NULL}, + G_OPTION_ENTRY_NULL +}; + +static void +on_name_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + g_print ("Name %s on %s is owned by %s\n", + name, + opt_system_bus ? "the system bus" : "the session bus", + name_owner); +} + +static void +on_name_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_print ("Name %s does not exist on %s\n", + name, + opt_system_bus ? "the system bus" : "the session bus"); +} + +int +main (int argc, char *argv[]) +{ + guint watcher_id; + GMainLoop *loop; + GOptionContext *opt_context; + GError *error; + GBusNameWatcherFlags flags; + + error = NULL; + opt_context = g_option_context_new ("g_bus_watch_name() example"); + g_option_context_set_summary (opt_context, + "Example: to watch the power manager on the session bus, use:\n" + "\n" + " ./example-watch-name -n org.gnome.PowerManager"); + g_option_context_add_main_entries (opt_context, opt_entries, NULL); + if (!g_option_context_parse (opt_context, &argc, &argv, &error)) + { + g_printerr ("Error parsing options: %s", error->message); + goto out; + } + if (opt_name == NULL) + { + g_printerr ("Incorrect usage, try --help.\n"); + goto out; + } + + flags = G_BUS_NAME_WATCHER_FLAGS_NONE; + if (opt_auto_start) + flags |= G_BUS_NAME_WATCHER_FLAGS_AUTO_START; + + watcher_id = g_bus_watch_name (opt_system_bus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION, + opt_name, + flags, + on_name_appeared, + on_name_vanished, + NULL, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_bus_unwatch_name (watcher_id); + + out: + g_option_context_free (opt_context); + g_free (opt_name); + + return 0; +} diff --git a/gio/tests/gdbus-example-watch-proxy.c b/gio/tests/gdbus-example-watch-proxy.c new file mode 100644 index 0000000..8cce90c --- /dev/null +++ b/gio/tests/gdbus-example-watch-proxy.c @@ -0,0 +1,230 @@ +#include + +static gchar *opt_name = NULL; +static gchar *opt_object_path = NULL; +static gchar *opt_interface = NULL; +static gboolean opt_system_bus = FALSE; +static gboolean opt_no_auto_start = FALSE; +static gboolean opt_no_properties = FALSE; + +static GOptionEntry opt_entries[] = +{ + { "name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, "Name of the remote object to watch", NULL }, + { "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_object_path, "Object path of the remote object", NULL }, + { "interface", 'i', 0, G_OPTION_ARG_STRING, &opt_interface, "D-Bus interface of remote object", NULL }, + { "system-bus", 's', 0, G_OPTION_ARG_NONE, &opt_system_bus, "Use the system-bus instead of the session-bus", NULL }, + { "no-auto-start", 'a', 0, G_OPTION_ARG_NONE, &opt_no_auto_start, "Don't instruct the bus to launch an owner for the name", NULL}, + { "no-properties", 'p', 0, G_OPTION_ARG_NONE, &opt_no_properties, "Do not load properties", NULL}, + G_OPTION_ENTRY_NULL +}; + +static GMainLoop *loop = NULL; + +static void +print_properties (GDBusProxy *proxy) +{ + gchar **property_names; + guint n; + + g_print (" properties:\n"); + + property_names = g_dbus_proxy_get_cached_property_names (proxy); + for (n = 0; property_names != NULL && property_names[n] != NULL; n++) + { + const gchar *key = property_names[n]; + GVariant *value; + gchar *value_str; + value = g_dbus_proxy_get_cached_property (proxy, key); + value_str = g_variant_print (value, TRUE); + g_print (" %s -> %s\n", key, value_str); + g_variant_unref (value); + g_free (value_str); + } + g_strfreev (property_names); +} + +static void +on_properties_changed (GDBusProxy *proxy, + GVariant *changed_properties, + const gchar* const *invalidated_properties, + gpointer user_data) +{ + /* Note that we are guaranteed that changed_properties and + * invalidated_properties are never NULL + */ + + if (g_variant_n_children (changed_properties) > 0) + { + GVariantIter *iter; + const gchar *key; + GVariant *value; + + g_print (" *** Properties Changed:\n"); + g_variant_get (changed_properties, + "a{sv}", + &iter); + while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) + { + gchar *value_str; + value_str = g_variant_print (value, TRUE); + g_print (" %s -> %s\n", key, value_str); + g_free (value_str); + } + g_variant_iter_free (iter); + } + + if (g_strv_length ((GStrv) invalidated_properties) > 0) + { + guint n; + g_print (" *** Properties Invalidated:\n"); + for (n = 0; invalidated_properties[n] != NULL; n++) + { + const gchar *key = invalidated_properties[n]; + g_print (" %s\n", key); + } + } +} + +static void +on_signal (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + gchar *parameters_str; + + parameters_str = g_variant_print (parameters, TRUE); + g_print (" *** Received Signal: %s: %s\n", + signal_name, + parameters_str); + g_free (parameters_str); +} + +static void +print_proxy (GDBusProxy *proxy) +{ + gchar *name_owner; + + name_owner = g_dbus_proxy_get_name_owner (proxy); + if (name_owner != NULL) + { + g_print ("+++ Proxy object points to remote object owned by %s\n" + " bus: %s\n" + " name: %s\n" + " object path: %s\n" + " interface: %s\n", + name_owner, + opt_system_bus ? "System Bus" : "Session Bus", + opt_name, + opt_object_path, + opt_interface); + print_properties (proxy); + } + else + { + g_print ("--- Proxy object is inert - there is no name owner for the name\n" + " bus: %s\n" + " name: %s\n" + " object path: %s\n" + " interface: %s\n", + opt_system_bus ? "System Bus" : "Session Bus", + opt_name, + opt_object_path, + opt_interface); + } + g_free (name_owner); +} + +static void +on_name_owner_notify (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (object); + print_proxy (proxy); +} + +int +main (int argc, char *argv[]) +{ + GOptionContext *opt_context; + GError *error; + GDBusProxyFlags flags; + GDBusProxy *proxy; + + loop = NULL; + proxy = NULL; + + opt_context = g_option_context_new ("g_bus_watch_proxy() example"); + g_option_context_set_summary (opt_context, + "Example: to watch the object of gdbus-example-server, use:\n" + "\n" + " ./gdbus-example-watch-proxy -n org.gtk.GDBus.TestServer \\\n" + " -o /org/gtk/GDBus/TestObject \\\n" + " -i org.gtk.GDBus.TestInterface"); + g_option_context_add_main_entries (opt_context, opt_entries, NULL); + error = NULL; + if (!g_option_context_parse (opt_context, &argc, &argv, &error)) + { + g_printerr ("Error parsing options: %s\n", error->message); + goto out; + } + if (opt_name == NULL || opt_object_path == NULL || opt_interface == NULL) + { + g_printerr ("Incorrect usage, try --help.\n"); + goto out; + } + + flags = G_DBUS_PROXY_FLAGS_NONE; + if (opt_no_properties) + flags |= G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES; + if (opt_no_auto_start) + flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START; + + loop = g_main_loop_new (NULL, FALSE); + + error = NULL; + proxy = g_dbus_proxy_new_for_bus_sync (opt_system_bus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION, + flags, + NULL, /* GDBusInterfaceInfo */ + opt_name, + opt_object_path, + opt_interface, + NULL, /* GCancellable */ + &error); + if (proxy == NULL) + { + g_printerr ("Error creating proxy: %s\n", error->message); + g_error_free (error); + goto out; + } + + g_signal_connect (proxy, + "g-properties-changed", + G_CALLBACK (on_properties_changed), + NULL); + g_signal_connect (proxy, + "g-signal", + G_CALLBACK (on_signal), + NULL); + g_signal_connect (proxy, + "notify::g-name-owner", + G_CALLBACK (on_name_owner_notify), + NULL); + print_proxy (proxy); + + g_main_loop_run (loop); + + out: + if (proxy != NULL) + g_object_unref (proxy); + if (loop != NULL) + g_main_loop_unref (loop); + g_option_context_free (opt_context); + g_free (opt_name); + g_free (opt_object_path); + g_free (opt_interface); + + return 0; +} diff --git a/gio/tests/gdbus-exit-on-close.c b/gio/tests/gdbus-exit-on-close.c new file mode 100644 index 0000000..1bf0ce7 --- /dev/null +++ b/gio/tests/gdbus-exit-on-close.c @@ -0,0 +1,218 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + const gchar *name; + const gchar *bug; + enum { + EXPLICITLY_FALSE = FALSE, + EXPLICITLY_TRUE = TRUE, + IMPLICITLY_TRUE + } exit_on_close; + enum { + LOCAL, + REMOTE + } who_closes; +} TestData; + +static const TestData cases[] = { + { "default", NULL, IMPLICITLY_TRUE, REMOTE }, + { "true", NULL, EXPLICITLY_TRUE, REMOTE }, + { "false", NULL, EXPLICITLY_FALSE, REMOTE }, + { "we-close", "662100", EXPLICITLY_TRUE, LOCAL }, + { NULL, NULL, 0, 0 } +}; + +static gboolean +quit_later_cb (gpointer data G_GNUC_UNUSED) +{ + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static void +closed_cb (GDBusConnection *c G_GNUC_UNUSED, + gboolean remote_peer_vanished, + GError *error, + gpointer test_data) +{ + const TestData *td = test_data; + + if (error == NULL) + g_debug ("closed (%d, no error)", remote_peer_vanished); + else + g_debug ("closed (%d, %s %d \"%s\")", remote_peer_vanished, + g_quark_to_string (error->domain), error->code, error->message); + + g_assert_cmpint (remote_peer_vanished, ==, (td->who_closes == REMOTE)); + g_assert_cmpint ((error == NULL), ==, (td->who_closes == LOCAL)); + + /* we delay this so that if exit-on-close was going to happen, it will + * win the race + */ + g_timeout_add (50, quit_later_cb, NULL); +} + +static void +close_async_cb (GObject *source G_GNUC_UNUSED, + GAsyncResult *res G_GNUC_UNUSED, + gpointer nil G_GNUC_UNUSED) +{ + GError *error = NULL; + + if (g_dbus_connection_close_finish (G_DBUS_CONNECTION (source), + res, + &error)) + { + g_debug ("closed connection"); + } + else + { + g_warning ("failed to close connection: %s (%s #%d)", + error->message, g_quark_to_string (error->domain), + error->code); + } +} + +static void +test_exit_on_close_subprocess (gconstpointer test_data) +{ + const TestData *td = test_data; + GDBusConnection *c; + + loop = g_main_loop_new (NULL, FALSE); + + session_bus_up (); + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + g_assert (c != NULL); + + /* the default is meant to be TRUE */ + if (td->exit_on_close != IMPLICITLY_TRUE) + g_dbus_connection_set_exit_on_close (c, td->exit_on_close); + + g_assert_cmpint (g_dbus_connection_get_exit_on_close (c), ==, + (td->exit_on_close != EXPLICITLY_FALSE)); + g_assert (!g_dbus_connection_is_closed (c)); + + g_timeout_add (50, quit_later_cb, NULL); + g_main_loop_run (loop); + + g_signal_connect (c, "closed", G_CALLBACK (closed_cb), (gpointer) td); + + if (td->who_closes == LOCAL) + { + GVariant *v; + GError *error = NULL; + + v = g_dbus_connection_call_sync (c, "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ListNames", + NULL, + G_VARIANT_TYPE ("(as)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (v != NULL); + g_variant_unref (v); + + g_dbus_connection_close (c, NULL, close_async_cb, NULL); + } + else + { + session_bus_stop (); + } + + g_main_loop_run (loop); + /* this is only reached when we turn off exit-on-close */ + g_main_loop_unref (loop); + g_object_unref (c); + + session_bus_down (); + + exit (0); +} + +static void +test_exit_on_close (gconstpointer test_data) +{ + const TestData *td = test_data; + GTestSubprocessFlags flags; + char *child_name; + + g_test_dbus_unset (); + + if (g_test_verbose ()) + flags = G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR; + else + flags = 0; + + child_name = g_strdup_printf ("/gdbus/exit-on-close/%s/subprocess", td->name); + g_test_trap_subprocess (child_name, 0, flags); + g_free (child_name); + + if (td->exit_on_close == EXPLICITLY_FALSE || + td->who_closes == LOCAL) + g_test_trap_assert_passed (); + else + g_test_trap_assert_failed(); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint i; + + g_test_init (&argc, &argv, NULL); + + for (i = 0; cases[i].name != NULL; i++) + { + gchar *name; + + name = g_strdup_printf ("/gdbus/exit-on-close/%s", cases[i].name); + g_test_add_data_func (name, &cases[i], test_exit_on_close); + g_free (name); + + name = g_strdup_printf ("/gdbus/exit-on-close/%s/subprocess", cases[i].name); + g_test_add_data_func (name, &cases[i], test_exit_on_close_subprocess); + g_free (name); + } + + return g_test_run(); +} diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c new file mode 100644 index 0000000..f66b1f7 --- /dev/null +++ b/gio/tests/gdbus-export.c @@ -0,0 +1,1987 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +static GDBusConnection *c = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that we can export objects, the hierarchy is correct and the right handlers are invoked */ +/* ---------------------------------------------------------------------------------------------------- */ + +static const GDBusArgInfo foo_method1_in_args = +{ + -1, + "an_input_string", + "s", + NULL +}; +static const GDBusArgInfo * const foo_method1_in_arg_pointers[] = {&foo_method1_in_args, NULL}; + +static const GDBusArgInfo foo_method1_out_args = +{ + -1, + "an_output_string", + "s", + NULL +}; +static const GDBusArgInfo * const foo_method1_out_arg_pointers[] = {&foo_method1_out_args, NULL}; + +static const GDBusMethodInfo foo_method_info_method1 = +{ + -1, + "Method1", + (GDBusArgInfo **) &foo_method1_in_arg_pointers, + (GDBusArgInfo **) &foo_method1_out_arg_pointers, + NULL +}; +static const GDBusMethodInfo foo_method_info_method2 = +{ + -1, + "Method2", + NULL, + NULL, + NULL +}; +static const GDBusMethodInfo * const foo_method_info_pointers[] = {&foo_method_info_method1, &foo_method_info_method2, NULL}; + +static const GDBusSignalInfo foo_signal_info = +{ + -1, + "SignalAlpha", + NULL, + NULL +}; +static const GDBusSignalInfo * const foo_signal_info_pointers[] = {&foo_signal_info, NULL}; + +static const GDBusPropertyInfo foo_property_info[] = +{ + { + -1, + "PropertyUno", + "s", + G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, + NULL + }, + { + -1, + "NotWritable", + "s", + G_DBUS_PROPERTY_INFO_FLAGS_READABLE, + NULL + }, + { + -1, + "NotReadable", + "s", + G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, + NULL + } +}; +static const GDBusPropertyInfo * const foo_property_info_pointers[] = +{ + &foo_property_info[0], + &foo_property_info[1], + &foo_property_info[2], + NULL +}; + +static const GDBusInterfaceInfo foo_interface_info = +{ + -1, + "org.example.Foo", + (GDBusMethodInfo **) &foo_method_info_pointers, + (GDBusSignalInfo **) &foo_signal_info_pointers, + (GDBusPropertyInfo **)&foo_property_info_pointers, + NULL, +}; + +/* Foo2 is just Foo without the properties */ +static const GDBusInterfaceInfo foo2_interface_info = +{ + -1, + "org.example.Foo2", + (GDBusMethodInfo **) &foo_method_info_pointers, + (GDBusSignalInfo **) &foo_signal_info_pointers, + NULL, + NULL +}; + +static void +foo_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + if (g_strcmp0 (method_name, "Method1") == 0) + { + const gchar *input; + gchar *output; + g_variant_get (parameters, "(&s)", &input); + output = g_strdup_printf ("You passed the string '%s'. Jolly good!", input); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", output)); + g_free (output); + } + else + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.example.SomeError", + "How do you like them apples, buddy!"); + } +} + +static GVariant * +foo_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + GVariant *ret; + gchar *s; + s = g_strdup_printf ("Property '%s' Is What It Is!", property_name); + ret = g_variant_new_string (s); + g_free (s); + return ret; +} + +static gboolean +foo_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data) +{ + gchar *s; + s = g_variant_print (value, TRUE); + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_SPAWN_FILE_INVALID, + "Returning some error instead of writing the value '%s' to the property '%s'", + s, property_name); + g_free (s); + return FALSE; +} + +static const GDBusInterfaceVTable foo_vtable = +{ + foo_method_call, + foo_get_property, + foo_set_property, + { 0 }, +}; + +/* -------------------- */ + +static const GDBusMethodInfo bar_method_info[] = +{ + { + -1, + "MethodA", + NULL, + NULL, + NULL + }, + { + -1, + "MethodB", + NULL, + NULL, + NULL + } +}; +static const GDBusMethodInfo * const bar_method_info_pointers[] = {&bar_method_info[0], &bar_method_info[1], NULL}; + +static const GDBusSignalInfo bar_signal_info[] = +{ + { + -1, + "SignalMars", + NULL, + NULL + } +}; +static const GDBusSignalInfo * const bar_signal_info_pointers[] = {&bar_signal_info[0], NULL}; + +static const GDBusPropertyInfo bar_property_info[] = +{ + { + -1, + "PropertyDuo", + "s", + G_DBUS_PROPERTY_INFO_FLAGS_READABLE, + NULL + } +}; +static const GDBusPropertyInfo * const bar_property_info_pointers[] = {&bar_property_info[0], NULL}; + +static const GDBusInterfaceInfo bar_interface_info = +{ + -1, + "org.example.Bar", + (GDBusMethodInfo **) bar_method_info_pointers, + (GDBusSignalInfo **) bar_signal_info_pointers, + (GDBusPropertyInfo **) bar_property_info_pointers, + NULL, +}; + +/* -------------------- */ + +static const GDBusMethodInfo dyna_method_info[] = +{ + { + -1, + "DynaCyber", + NULL, + NULL, + NULL + } +}; +static const GDBusMethodInfo * const dyna_method_info_pointers[] = {&dyna_method_info[0], NULL}; + +static const GDBusInterfaceInfo dyna_interface_info = +{ + -1, + "org.example.Dyna", + (GDBusMethodInfo **) dyna_method_info_pointers, + NULL, /* no signals */ + NULL, /* no properties */ + NULL, +}; + +static void +dyna_cyber (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GPtrArray *data = user_data; + gchar *node_name; + guint n; + + node_name = strrchr (object_path, '/') + 1; + + /* Add new node if it is not already known */ + for (n = 0; n < data->len ; n++) + { + if (g_strcmp0 (g_ptr_array_index (data, n), node_name) == 0) + goto out; + } + g_ptr_array_add (data, g_strdup(node_name)); + + out: + g_dbus_method_invocation_return_value (invocation, NULL); +} + +static const GDBusInterfaceVTable dyna_interface_vtable = +{ + dyna_cyber, + NULL, + NULL, + { 0 } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +introspect_callback (GDBusProxy *proxy, + GAsyncResult *res, + gpointer user_data) +{ + gchar **xml_data = user_data; + GVariant *result; + GError *error; + + error = NULL; + result = g_dbus_proxy_call_finish (proxy, + res, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_variant_get (result, "(s)", xml_data); + g_variant_unref (result); + + g_main_loop_quit (loop); +} + +static gint +compare_strings (gconstpointer a, + gconstpointer b) +{ + const gchar *sa = *(const gchar **) a; + const gchar *sb = *(const gchar **) b; + + /* Array terminator must sort last */ + if (sa == NULL) + return 1; + if (sb == NULL) + return -1; + + return strcmp (sa, sb); +} + +static gchar ** +get_nodes_at (GDBusConnection *c, + const gchar *object_path) +{ + GError *error; + GDBusProxy *proxy; + gchar *xml_data; + GPtrArray *p; + GDBusNodeInfo *node_info; + guint n; + + error = NULL; + proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + g_dbus_connection_get_unique_name (c), + object_path, + "org.freedesktop.DBus.Introspectable", + NULL, + &error); + g_assert_no_error (error); + g_assert (proxy != NULL); + + /* do this async to avoid libdbus-1 deadlocks */ + xml_data = NULL; + g_dbus_proxy_call (proxy, + "Introspect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) introspect_callback, + &xml_data); + g_main_loop_run (loop); + g_assert (xml_data != NULL); + + node_info = g_dbus_node_info_new_for_xml (xml_data, &error); + g_assert_no_error (error); + g_assert (node_info != NULL); + + p = g_ptr_array_new (); + for (n = 0; node_info->nodes != NULL && node_info->nodes[n] != NULL; n++) + { + const GDBusNodeInfo *sub_node_info = node_info->nodes[n]; + g_ptr_array_add (p, g_strdup (sub_node_info->path)); + } + g_ptr_array_add (p, NULL); + + g_object_unref (proxy); + g_free (xml_data); + g_dbus_node_info_unref (node_info); + + /* Nodes are semantically unordered; sort array so tests can rely on order */ + g_ptr_array_sort (p, compare_strings); + + return (gchar **) g_ptr_array_free (p, FALSE); +} + +static gboolean +has_interface (GDBusConnection *c, + const gchar *object_path, + const gchar *interface_name) +{ + GError *error; + GDBusProxy *proxy; + gchar *xml_data; + GDBusNodeInfo *node_info; + gboolean ret; + + error = NULL; + proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + g_dbus_connection_get_unique_name (c), + object_path, + "org.freedesktop.DBus.Introspectable", + NULL, + &error); + g_assert_no_error (error); + g_assert (proxy != NULL); + + /* do this async to avoid libdbus-1 deadlocks */ + xml_data = NULL; + g_dbus_proxy_call (proxy, + "Introspect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) introspect_callback, + &xml_data); + g_main_loop_run (loop); + g_assert (xml_data != NULL); + + node_info = g_dbus_node_info_new_for_xml (xml_data, &error); + g_assert_no_error (error); + g_assert (node_info != NULL); + + ret = (g_dbus_node_info_lookup_interface (node_info, interface_name) != NULL); + + g_object_unref (proxy); + g_free (xml_data); + g_dbus_node_info_unref (node_info); + + return ret; +} + +static guint +count_interfaces (GDBusConnection *c, + const gchar *object_path) +{ + GError *error; + GDBusProxy *proxy; + gchar *xml_data; + GDBusNodeInfo *node_info; + guint ret; + + error = NULL; + proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + g_dbus_connection_get_unique_name (c), + object_path, + "org.freedesktop.DBus.Introspectable", + NULL, + &error); + g_assert_no_error (error); + g_assert (proxy != NULL); + + /* do this async to avoid libdbus-1 deadlocks */ + xml_data = NULL; + g_dbus_proxy_call (proxy, + "Introspect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) introspect_callback, + &xml_data); + g_main_loop_run (loop); + g_assert (xml_data != NULL); + + node_info = g_dbus_node_info_new_for_xml (xml_data, &error); + g_assert_no_error (error); + g_assert (node_info != NULL); + + ret = 0; + while (node_info->interfaces != NULL && node_info->interfaces[ret] != NULL) + ret++; + + g_object_unref (proxy); + g_free (xml_data); + g_dbus_node_info_unref (node_info); + + return ret; +} + +static void +dyna_create_callback (GDBusProxy *proxy, + GAsyncResult *res, + gpointer user_data) +{ + GVariant *result; + GError *error; + + error = NULL; + result = g_dbus_proxy_call_finish (proxy, + res, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_variant_unref (result); + + g_main_loop_quit (loop); +} + +/* Dynamically create @object_name under /foo/dyna */ +static void +dyna_create (GDBusConnection *c, + const gchar *object_name) +{ + GError *error; + GDBusProxy *proxy; + gchar *object_path; + + object_path = g_strconcat ("/foo/dyna/", object_name, NULL); + + error = NULL; + proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + g_dbus_connection_get_unique_name (c), + object_path, + "org.example.Dyna", + NULL, + &error); + g_assert_no_error (error); + g_assert (proxy != NULL); + + /* do this async to avoid libdbus-1 deadlocks */ + g_dbus_proxy_call (proxy, + "DynaCyber", + g_variant_new ("()"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) dyna_create_callback, + NULL); + g_main_loop_run (loop); + + g_assert_no_error (error); + + g_object_unref (proxy); + g_free (object_path); + + return; +} + +typedef struct +{ + guint num_unregistered_calls; + guint num_unregistered_subtree_calls; + guint num_subtree_nodes; +} ObjectRegistrationData; + +static void +on_object_unregistered (gpointer user_data) +{ + ObjectRegistrationData *data = user_data; + + data->num_unregistered_calls++; +} + +static void +on_subtree_unregistered (gpointer user_data) +{ + ObjectRegistrationData *data = user_data; + + data->num_unregistered_subtree_calls++; +} + +/* -------------------- */ + +static gchar ** +subtree_enumerate (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + gpointer user_data) +{ + ObjectRegistrationData *data = user_data; + GPtrArray *p; + gchar **nodes; + guint n; + + p = g_ptr_array_new (); + + for (n = 0; n < data->num_subtree_nodes; n++) + { + g_ptr_array_add (p, g_strdup_printf ("vp%d", n)); + g_ptr_array_add (p, g_strdup_printf ("evp%d", n)); + } + g_ptr_array_add (p, NULL); + + nodes = (gchar **) g_ptr_array_free (p, FALSE); + + return nodes; +} + +/* Only allows certain objects, and aborts on unknowns */ +static GDBusInterfaceInfo ** +subtree_introspect (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *node, + gpointer user_data) +{ + const GDBusInterfaceInfo *interfaces[2] = { + NULL /* filled in below */, NULL + }; + + /* VPs implement the Foo interface, EVPs implement the Bar interface. The root + * does not implement any interfaces + */ + if (node == NULL) + { + return NULL; + } + else if (g_str_has_prefix (node, "vp")) + { + interfaces[0] = &foo_interface_info; + } + else if (g_str_has_prefix (node, "evp")) + { + interfaces[0] = &bar_interface_info; + } + else + { + g_assert_not_reached (); + } + + return g_memdup2 (interfaces, 2 * sizeof (void *)); +} + +static const GDBusInterfaceVTable * +subtree_dispatch (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *node, + gpointer *out_user_data, + gpointer user_data) +{ + if (g_strcmp0 (interface_name, "org.example.Foo") == 0) + return &foo_vtable; + else + return NULL; +} + +static const GDBusSubtreeVTable subtree_vtable = +{ + subtree_enumerate, + subtree_introspect, + subtree_dispatch, + { 0 } +}; + +/* -------------------- */ + +static gchar ** +dynamic_subtree_enumerate (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + gpointer user_data) +{ + GPtrArray *data = user_data; + gchar **nodes = g_new (gchar*, data->len + 1); + guint n; + + for (n = 0; n < data->len; n++) + { + nodes[n] = g_strdup (g_ptr_array_index (data, n)); + } + nodes[data->len] = NULL; + + return nodes; +} + +/* Allow all objects to be introspected */ +static GDBusInterfaceInfo ** +dynamic_subtree_introspect (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *node, + gpointer user_data) +{ + const GDBusInterfaceInfo *interfaces[2] = { &dyna_interface_info, NULL }; + + return g_memdup2 (interfaces, 2 * sizeof (void *)); +} + +static const GDBusInterfaceVTable * +dynamic_subtree_dispatch (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *node, + gpointer *out_user_data, + gpointer user_data) +{ + *out_user_data = user_data; + return &dyna_interface_vtable; +} + +static const GDBusSubtreeVTable dynamic_subtree_vtable = +{ + dynamic_subtree_enumerate, + dynamic_subtree_introspect, + dynamic_subtree_dispatch, + { 0 } +}; + +/* -------------------- */ + +typedef struct +{ + const gchar *object_path; + gboolean check_remote_errors; +} TestDispatchThreadFuncArgs; + +static gpointer +test_dispatch_thread_func (gpointer user_data) +{ + TestDispatchThreadFuncArgs *args = user_data; + const gchar *object_path = args->object_path; + GDBusProxy *foo_proxy; + GVariant *value; + GVariant *inner; + GError *error; + gchar *s; + const gchar *value_str; + + foo_proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + g_dbus_connection_get_unique_name (c), + object_path, + "org.example.Foo", + NULL, + &error); + g_assert (foo_proxy != NULL); + + /* generic interfaces */ + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "org.freedesktop.DBus.Peer.Ping", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (value != NULL); + g_variant_unref (value); + + /* user methods */ + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "Method1", + g_variant_new ("(s)", "winwinwin"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (value != NULL); + g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("(s)"))); + g_variant_get (value, "(&s)", &value_str); + g_assert_cmpstr (value_str, ==, "You passed the string 'winwinwin'. Jolly good!"); + g_variant_unref (value); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "Method2", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR); + g_assert_cmpstr (error->message, ==, "GDBus.Error:org.example.SomeError: How do you like them apples, buddy!"); + g_error_free (error); + g_assert (value == NULL); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "Method2", + g_variant_new ("(s)", "failfailfail"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS); + g_assert_cmpstr (error->message, ==, "GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Type of message, “(s)â€, does not match expected type “()â€"); + g_error_free (error); + g_assert (value == NULL); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "NonExistantMethod", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_assert_cmpstr (error->message, ==, "GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such method “NonExistantMethodâ€"); + g_error_free (error); + g_assert (value == NULL); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "org.example.FooXYZ.NonExistant", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_error_free (error); + g_assert (value == NULL); + + /* user properties */ + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "org.freedesktop.DBus.Properties.Get", + g_variant_new ("(ss)", + "org.example.Foo", + "PropertyUno"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (value != NULL); + g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("(v)"))); + g_variant_get (value, "(v)", &inner); + g_assert (g_variant_is_of_type (inner, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (inner, NULL), ==, "Property 'PropertyUno' Is What It Is!"); + g_variant_unref (value); + g_variant_unref (inner); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "org.freedesktop.DBus.Properties.Get", + g_variant_new ("(ss)", + "org.example.Foo", + "ThisDoesntExist"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert (value == NULL); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS); + g_assert_cmpstr (error->message, ==, "GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: No such property “ThisDoesntExistâ€"); + g_error_free (error); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "org.freedesktop.DBus.Properties.Get", + g_variant_new ("(ss)", + "org.example.Foo", + "NotReadable"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert (value == NULL); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS); + g_assert_cmpstr (error->message, ==, "GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Property “NotReadable†is not readable"); + g_error_free (error); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "org.freedesktop.DBus.Properties.Set", + g_variant_new ("(ssv)", + "org.example.Foo", + "NotReadable", + g_variant_new_string ("But Writable you are!")), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert (value == NULL); + if (args->check_remote_errors) + { + /* _with_closures variant doesn't support customizing error data. */ + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FILE_INVALID); + g_assert_cmpstr (error->message, ==, "GDBus.Error:org.freedesktop.DBus.Error.Spawn.FileInvalid: Returning some error instead of writing the value ''But Writable you are!'' to the property 'NotReadable'"); + } + g_assert (error != NULL && error->domain == G_DBUS_ERROR); + g_error_free (error); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "org.freedesktop.DBus.Properties.Set", + g_variant_new ("(ssv)", + "org.example.Foo", + "NotWritable", + g_variant_new_uint32 (42)), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert (value == NULL); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS); + g_assert_cmpstr (error->message, ==, "GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Property “NotWritable†is not writable"); + g_error_free (error); + + error = NULL; + value = g_dbus_proxy_call_sync (foo_proxy, + "org.freedesktop.DBus.Properties.GetAll", + g_variant_new ("(s)", + "org.example.Foo"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (value != NULL); + g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("(a{sv})"))); + s = g_variant_print (value, TRUE); + g_assert_cmpstr (s, ==, "({'PropertyUno': <\"Property 'PropertyUno' Is What It Is!\">, 'NotWritable': <\"Property 'NotWritable' Is What It Is!\">},)"); + g_free (s); + g_variant_unref (value); + + g_object_unref (foo_proxy); + + g_main_loop_quit (loop); + return NULL; +} + +static void +test_dispatch (const gchar *object_path, + gboolean check_remote_errors) +{ + GThread *thread; + + TestDispatchThreadFuncArgs args = {object_path, check_remote_errors}; + + /* run this in a thread to avoid deadlocks */ + thread = g_thread_new ("test_dispatch", + test_dispatch_thread_func, + (gpointer) &args); + g_main_loop_run (loop); + g_thread_join (thread); +} + +static void +test_object_registration (void) +{ + GError *error; + ObjectRegistrationData data; + GPtrArray *dyna_data; + gchar **nodes; + guint boss_foo_reg_id; + guint boss_bar_reg_id; + guint worker1_foo_reg_id; + guint worker1p1_foo_reg_id; + guint worker2_bar_reg_id; + guint intern1_foo_reg_id; + guint intern2_bar_reg_id; + guint intern2_foo_reg_id; + guint intern3_bar_reg_id; + guint registration_id; + guint subtree_registration_id; + guint non_subtree_object_path_foo_reg_id; + guint non_subtree_object_path_bar_reg_id; + guint dyna_subtree_registration_id; + guint num_successful_registrations; + + data.num_unregistered_calls = 0; + data.num_unregistered_subtree_calls = 0; + data.num_subtree_nodes = 0; + + num_successful_registrations = 0; + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (c != NULL); + + registration_id = g_dbus_connection_register_object (c, + "/foo/boss", + (GDBusInterfaceInfo *) &foo_interface_info, + &foo_vtable, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + boss_foo_reg_id = registration_id; + num_successful_registrations++; + + registration_id = g_dbus_connection_register_object (c, + "/foo/boss", + (GDBusInterfaceInfo *) &bar_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + boss_bar_reg_id = registration_id; + num_successful_registrations++; + + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/worker1", + (GDBusInterfaceInfo *) &foo_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + worker1_foo_reg_id = registration_id; + num_successful_registrations++; + + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/worker1p1", + (GDBusInterfaceInfo *) &foo_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + worker1p1_foo_reg_id = registration_id; + num_successful_registrations++; + + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/worker2", + (GDBusInterfaceInfo *) &bar_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + worker2_bar_reg_id = registration_id; + num_successful_registrations++; + + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/interns/intern1", + (GDBusInterfaceInfo *) &foo_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + intern1_foo_reg_id = registration_id; + num_successful_registrations++; + + /* ... and try again at another path */ + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/interns/intern2", + (GDBusInterfaceInfo *) &bar_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + intern2_bar_reg_id = registration_id; + num_successful_registrations++; + + /* register at the same path/interface - this should fail */ + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/interns/intern2", + (GDBusInterfaceInfo *) &bar_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS); + g_assert (!g_dbus_error_is_remote_error (error)); + g_error_free (error); + error = NULL; + g_assert (registration_id == 0); + + /* register at different interface - shouldn't fail */ + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/interns/intern2", + (GDBusInterfaceInfo *) &foo_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + intern2_foo_reg_id = registration_id; + num_successful_registrations++; + + /* unregister it via the id */ + g_assert (g_dbus_connection_unregister_object (c, registration_id)); + g_main_context_iteration (NULL, FALSE); + g_assert_cmpint (data.num_unregistered_calls, ==, 1); + intern2_foo_reg_id = 0; + + /* register it back */ + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/interns/intern2", + (GDBusInterfaceInfo *) &foo_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + intern2_foo_reg_id = registration_id; + num_successful_registrations++; + + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/interns/intern3", + (GDBusInterfaceInfo *) &bar_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + intern3_bar_reg_id = registration_id; + num_successful_registrations++; + + /* now register a whole subtree at /foo/boss/executives */ + subtree_registration_id = g_dbus_connection_register_subtree (c, + "/foo/boss/executives", + &subtree_vtable, + G_DBUS_SUBTREE_FLAGS_NONE, + &data, + on_subtree_unregistered, + &error); + g_assert_no_error (error); + g_assert (subtree_registration_id > 0); + /* try registering it again.. this should fail */ + registration_id = g_dbus_connection_register_subtree (c, + "/foo/boss/executives", + &subtree_vtable, + G_DBUS_SUBTREE_FLAGS_NONE, + &data, + on_subtree_unregistered, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS); + g_assert (!g_dbus_error_is_remote_error (error)); + g_error_free (error); + error = NULL; + g_assert (registration_id == 0); + + /* unregister it, then register it again */ + g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 0); + g_assert (g_dbus_connection_unregister_subtree (c, subtree_registration_id)); + g_main_context_iteration (NULL, FALSE); + g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 1); + subtree_registration_id = g_dbus_connection_register_subtree (c, + "/foo/boss/executives", + &subtree_vtable, + G_DBUS_SUBTREE_FLAGS_NONE, + &data, + on_subtree_unregistered, + &error); + g_assert_no_error (error); + g_assert (subtree_registration_id > 0); + + /* try to register something under /foo/boss/executives - this should work + * because registered subtrees and registered objects can coexist. + * + * Make the exported object implement *two* interfaces so we can check + * that the right introspection handler is invoked. + */ + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/executives/non_subtree_object", + (GDBusInterfaceInfo *) &bar_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + non_subtree_object_path_bar_reg_id = registration_id; + num_successful_registrations++; + registration_id = g_dbus_connection_register_object (c, + "/foo/boss/executives/non_subtree_object", + (GDBusInterfaceInfo *) &foo_interface_info, + NULL, + &data, + on_object_unregistered, + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + non_subtree_object_path_foo_reg_id = registration_id; + num_successful_registrations++; + + /* now register a dynamic subtree, spawning objects as they are called */ + dyna_data = g_ptr_array_new_with_free_func (g_free); + dyna_subtree_registration_id = g_dbus_connection_register_subtree (c, + "/foo/dyna", + &dynamic_subtree_vtable, + G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES, + dyna_data, + (GDestroyNotify)g_ptr_array_unref, + &error); + g_assert_no_error (error); + g_assert (dyna_subtree_registration_id > 0); + + /* First assert that we have no nodes in the dynamic subtree */ + nodes = get_nodes_at (c, "/foo/dyna"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 0); + g_strfreev (nodes); + g_assert_cmpint (count_interfaces (c, "/foo/dyna"), ==, 4); + + /* Install three nodes in the dynamic subtree via the dyna_data backdoor and + * assert that they show up correctly in the introspection data */ + g_ptr_array_add (dyna_data, g_strdup ("lol")); + g_ptr_array_add (dyna_data, g_strdup ("cat")); + g_ptr_array_add (dyna_data, g_strdup ("cheezburger")); + nodes = get_nodes_at (c, "/foo/dyna"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 3); + g_assert_cmpstr (nodes[0], ==, "cat"); + g_assert_cmpstr (nodes[1], ==, "cheezburger"); + g_assert_cmpstr (nodes[2], ==, "lol"); + g_strfreev (nodes); + g_assert_cmpint (count_interfaces (c, "/foo/dyna/lol"), ==, 4); + g_assert_cmpint (count_interfaces (c, "/foo/dyna/cat"), ==, 4); + g_assert_cmpint (count_interfaces (c, "/foo/dyna/cheezburger"), ==, 4); + + /* Call a non-existing object path and assert that it has been created */ + dyna_create (c, "dynamicallycreated"); + nodes = get_nodes_at (c, "/foo/dyna"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 4); + g_assert_cmpstr (nodes[0], ==, "cat"); + g_assert_cmpstr (nodes[1], ==, "cheezburger"); + g_assert_cmpstr (nodes[2], ==, "dynamicallycreated"); + g_assert_cmpstr (nodes[3], ==, "lol"); + g_strfreev (nodes); + g_assert_cmpint (count_interfaces (c, "/foo/dyna/dynamicallycreated"), ==, 4); + + /* now check that the object hierarchy is properly generated... yes, it's a bit + * perverse that we round-trip to the bus to introspect ourselves ;-) + */ + nodes = get_nodes_at (c, "/"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 1); + g_assert_cmpstr (nodes[0], ==, "foo"); + g_strfreev (nodes); + g_assert_cmpint (count_interfaces (c, "/"), ==, 0); + + nodes = get_nodes_at (c, "/foo"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 2); + g_assert_cmpstr (nodes[0], ==, "boss"); + g_assert_cmpstr (nodes[1], ==, "dyna"); + g_strfreev (nodes); + g_assert_cmpint (count_interfaces (c, "/foo"), ==, 0); + + nodes = get_nodes_at (c, "/foo/boss"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 5); + g_assert (g_strv_contains ((const gchar* const *) nodes, "worker1")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "worker1p1")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "worker2")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "interns")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "executives")); + g_strfreev (nodes); + /* any registered object always implement org.freedesktop.DBus.[Peer,Introspectable,Properties] */ + g_assert_cmpint (count_interfaces (c, "/foo/boss"), ==, 5); + g_assert (has_interface (c, "/foo/boss", foo_interface_info.name)); + g_assert (has_interface (c, "/foo/boss", bar_interface_info.name)); + + /* check subtree nodes - we should have only non_subtree_object in /foo/boss/executives + * because data.num_subtree_nodes is 0 + */ + nodes = get_nodes_at (c, "/foo/boss/executives"); + g_assert (nodes != NULL); + g_assert (g_strv_contains ((const gchar* const *) nodes, "non_subtree_object")); + g_assert_cmpint (g_strv_length (nodes), ==, 1); + g_strfreev (nodes); + g_assert_cmpint (count_interfaces (c, "/foo/boss/executives"), ==, 0); + + /* now change data.num_subtree_nodes and check */ + data.num_subtree_nodes = 2; + nodes = get_nodes_at (c, "/foo/boss/executives"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 5); + g_assert (g_strv_contains ((const gchar* const *) nodes, "non_subtree_object")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "vp0")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "vp1")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "evp0")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "evp1")); + /* check that /foo/boss/executives/non_subtree_object is not handled by the + * subtree handlers - we can do this because objects from subtree handlers + * has exactly one interface and non_subtree_object has two + */ + g_assert_cmpint (count_interfaces (c, "/foo/boss/executives/non_subtree_object"), ==, 5); + g_assert (has_interface (c, "/foo/boss/executives/non_subtree_object", foo_interface_info.name)); + g_assert (has_interface (c, "/foo/boss/executives/non_subtree_object", bar_interface_info.name)); + /* check that the vp and evp objects are handled by the subtree handlers */ + g_assert_cmpint (count_interfaces (c, "/foo/boss/executives/vp0"), ==, 4); + g_assert_cmpint (count_interfaces (c, "/foo/boss/executives/vp1"), ==, 4); + g_assert_cmpint (count_interfaces (c, "/foo/boss/executives/evp0"), ==, 4); + g_assert_cmpint (count_interfaces (c, "/foo/boss/executives/evp1"), ==, 4); + g_assert (has_interface (c, "/foo/boss/executives/vp0", foo_interface_info.name)); + g_assert (has_interface (c, "/foo/boss/executives/vp1", foo_interface_info.name)); + g_assert (has_interface (c, "/foo/boss/executives/evp0", bar_interface_info.name)); + g_assert (has_interface (c, "/foo/boss/executives/evp1", bar_interface_info.name)); + g_strfreev (nodes); + data.num_subtree_nodes = 3; + nodes = get_nodes_at (c, "/foo/boss/executives"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 7); + g_assert (g_strv_contains ((const gchar* const *) nodes, "non_subtree_object")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "vp0")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "vp1")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "vp2")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "evp0")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "evp1")); + g_assert (g_strv_contains ((const gchar* const *) nodes, "evp2")); + g_strfreev (nodes); + + /* This is to check that a bug (rather, class of bugs) in gdbusconnection.c's + * + * g_dbus_connection_list_registered_unlocked() + * + * where /foo/boss/worker1 reported a child '1', is now fixed. + */ + nodes = get_nodes_at (c, "/foo/boss/worker1"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 0); + g_strfreev (nodes); + + /* check that calls are properly dispatched to the functions in foo_vtable for objects + * implementing the org.example.Foo interface + * + * We do this for both a regular registered object (/foo/boss) and also for an object + * registered through the subtree mechanism. + */ + test_dispatch ("/foo/boss", TRUE); + test_dispatch ("/foo/boss/executives/vp0", TRUE); + + /* To prevent from exiting and attaching a D-Bus tool like D-Feet; uncomment: */ +#if 0 + g_debug ("Point D-feet or other tool at: %s", g_test_dbus_get_temporary_address()); + g_main_loop_run (loop); +#endif + + /* check that unregistering the subtree handler works */ + g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 1); + g_assert (g_dbus_connection_unregister_subtree (c, subtree_registration_id)); + g_main_context_iteration (NULL, FALSE); + g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 2); + nodes = get_nodes_at (c, "/foo/boss/executives"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 1); + g_assert (g_strv_contains ((const gchar* const *) nodes, "non_subtree_object")); + g_strfreev (nodes); + + g_assert (g_dbus_connection_unregister_object (c, boss_foo_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, boss_bar_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, worker1_foo_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, worker1p1_foo_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, worker2_bar_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, intern1_foo_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, intern2_bar_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, intern2_foo_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, intern3_bar_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, non_subtree_object_path_bar_reg_id)); + g_assert (g_dbus_connection_unregister_object (c, non_subtree_object_path_foo_reg_id)); + + g_main_context_iteration (NULL, FALSE); + g_assert_cmpint (data.num_unregistered_calls, ==, num_successful_registrations); + + /* check that we no longer export any objects - TODO: it looks like there's a bug in + * libdbus-1 here: libdbus still reports the '/foo' object; so disable the test for now + */ +#if 0 + nodes = get_nodes_at (c, "/"); + g_assert (nodes != NULL); + g_assert_cmpint (g_strv_length (nodes), ==, 0); + g_strfreev (nodes); +#endif + + g_object_unref (c); +} + +static void +test_object_registration_with_closures (void) +{ + GError *error; + guint registration_id; + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (c != NULL); + + registration_id = g_dbus_connection_register_object_with_closures (c, + "/foo/boss", + (GDBusInterfaceInfo *) &foo_interface_info, + g_cclosure_new (G_CALLBACK (foo_method_call), NULL, NULL), + g_cclosure_new (G_CALLBACK (foo_get_property), NULL, NULL), + g_cclosure_new (G_CALLBACK (foo_set_property), NULL, NULL), + &error); + g_assert_no_error (error); + g_assert (registration_id > 0); + + test_dispatch ("/foo/boss", FALSE); + + g_assert (g_dbus_connection_unregister_object (c, registration_id)); + + g_object_unref (c); +} + +static const GDBusInterfaceInfo test_interface_info1 = +{ + -1, + "org.example.Foo", + (GDBusMethodInfo **) NULL, + (GDBusSignalInfo **) NULL, + (GDBusPropertyInfo **) NULL, + NULL, +}; + +static const GDBusInterfaceInfo test_interface_info2 = +{ + -1, + "org.freedesktop.DBus.Properties", + (GDBusMethodInfo **) NULL, + (GDBusSignalInfo **) NULL, + (GDBusPropertyInfo **) NULL, + NULL, +}; + +static void +check_interfaces (GDBusConnection *c, + const gchar *object_path, + const gchar **interfaces) +{ + GError *error; + GDBusProxy *proxy; + gchar *xml_data; + GDBusNodeInfo *node_info; + gint i, j; + + error = NULL; + proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + g_dbus_connection_get_unique_name (c), + object_path, + "org.freedesktop.DBus.Introspectable", + NULL, + &error); + g_assert_no_error (error); + g_assert (proxy != NULL); + + /* do this async to avoid libdbus-1 deadlocks */ + xml_data = NULL; + g_dbus_proxy_call (proxy, + "Introspect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) introspect_callback, + &xml_data); + g_main_loop_run (loop); + g_assert (xml_data != NULL); + + node_info = g_dbus_node_info_new_for_xml (xml_data, &error); + g_assert_no_error (error); + g_assert (node_info != NULL); + + g_assert (node_info->interfaces != NULL); + for (i = 0; node_info->interfaces[i]; i++) ; +#if 0 + if (g_strv_length ((gchar**)interfaces) != i - 1) + { + g_printerr ("expected "); + for (i = 0; interfaces[i]; i++) + g_printerr ("%s ", interfaces[i]); + g_printerr ("\ngot "); + for (i = 0; node_info->interfaces[i]; i++) + g_printerr ("%s ", node_info->interfaces[i]->name); + g_printerr ("\n"); + } +#endif + g_assert_cmpint (g_strv_length ((gchar**)interfaces), ==, i - 1); + + for (i = 0; interfaces[i]; i++) + { + for (j = 0; node_info->interfaces[j]; j++) + { + if (strcmp (interfaces[i], node_info->interfaces[j]->name) == 0) + goto found; + } + + g_assert_not_reached (); + + found: ; + } + + g_object_unref (proxy); + g_free (xml_data); + g_dbus_node_info_unref (node_info); +} + +static void +test_registered_interfaces (void) +{ + GError *error; + guint id1, id2; + const gchar *interfaces[] = { + "org.example.Foo", + "org.freedesktop.DBus.Properties", + "org.freedesktop.DBus.Introspectable", + NULL, + }; + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (c != NULL); + + id1 = g_dbus_connection_register_object (c, + "/test", + (GDBusInterfaceInfo *) &test_interface_info1, + NULL, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert (id1 > 0); + id2 = g_dbus_connection_register_object (c, + "/test", + (GDBusInterfaceInfo *) &test_interface_info2, + NULL, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert (id2 > 0); + + check_interfaces (c, "/test", interfaces); + + g_assert (g_dbus_connection_unregister_object (c, id1)); + g_assert (g_dbus_connection_unregister_object (c, id2)); + g_object_unref (c); +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_async_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + const GDBusPropertyInfo *property; + + /* Strictly speaking, this function should also expect to receive + * method calls not on the org.freedesktop.DBus.Properties interface, + * but we don't do any during this testcase, so assert that. + */ + g_assert_cmpstr (interface_name, ==, "org.freedesktop.DBus.Properties"); + g_assert (g_dbus_method_invocation_get_method_info (invocation) == NULL); + + property = g_dbus_method_invocation_get_property_info (invocation); + + /* We should never be seeing any property calls on the com.example.Bar + * interface because it doesn't export any properties. + * + * In each case below make sure the interface is org.example.Foo. + */ + + /* Do a whole lot of asserts to make sure that invalid calls are still + * getting properly rejected by GDBusConnection and that our + * environment is as we expect it to be. + */ + if (g_str_equal (method_name, "Get")) + { + const gchar *iface_name, *prop_name; + + g_variant_get (parameters, "(&s&s)", &iface_name, &prop_name); + g_assert_cmpstr (iface_name, ==, "org.example.Foo"); + g_assert (property != NULL); + g_assert_cmpstr (prop_name, ==, property->name); + g_assert (property->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(v)", g_variant_new_string (prop_name))); + } + + else if (g_str_equal (method_name, "Set")) + { + const gchar *iface_name, *prop_name; + GVariant *value; + + g_variant_get (parameters, "(&s&sv)", &iface_name, &prop_name, &value); + g_assert_cmpstr (iface_name, ==, "org.example.Foo"); + g_assert (property != NULL); + g_assert_cmpstr (prop_name, ==, property->name); + g_assert (property->flags & G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE); + g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE (property->signature))); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); + g_variant_unref (value); + } + + else if (g_str_equal (method_name, "GetAll")) + { + const gchar *iface_name; + + g_variant_get (parameters, "(&s)", &iface_name); + g_assert_cmpstr (iface_name, ==, "org.example.Foo"); + g_assert (property == NULL); + g_dbus_method_invocation_return_value (invocation, + g_variant_new_parsed ("({ 'PropertyUno': < 'uno' >," + " 'NotWritable': < 'notwrite' > },)")); + } + + else + g_assert_not_reached (); +} + +static gint outstanding_cases; + +static void +ensure_result_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (source); + GVariant *reply; + + reply = g_dbus_connection_call_finish (connection, result, NULL); + + if (user_data == NULL) + { + /* Expected an error */ + g_assert (reply == NULL); + } + else + { + /* Expected a reply of a particular format. */ + gchar *str; + + g_assert (reply != NULL); + str = g_variant_print (reply, TRUE); + g_assert_cmpstr (str, ==, (const gchar *) user_data); + g_free (str); + + g_variant_unref (reply); + } + + g_assert_cmpint (outstanding_cases, >, 0); + outstanding_cases--; +} + +static void +test_async_case (GDBusConnection *connection, + const gchar *expected_reply, + const gchar *method, + const gchar *format_string, + ...) +{ + va_list ap; + + va_start (ap, format_string); + + g_dbus_connection_call (connection, g_dbus_connection_get_unique_name (connection), "/foo", + "org.freedesktop.DBus.Properties", method, g_variant_new_va (format_string, NULL, &ap), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, ensure_result_cb, (gpointer) expected_reply); + + va_end (ap); + + outstanding_cases++; +} + +static void +test_async_properties (void) +{ + GError *error = NULL; + guint registration_id, registration_id2; + static const GDBusInterfaceVTable vtable = { + test_async_method_call, NULL, NULL, { 0 } + }; + + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (c != NULL); + + registration_id = g_dbus_connection_register_object (c, + "/foo", + (GDBusInterfaceInfo *) &foo_interface_info, + &vtable, NULL, NULL, &error); + g_assert_no_error (error); + g_assert (registration_id); + registration_id2 = g_dbus_connection_register_object (c, + "/foo", + (GDBusInterfaceInfo *) &foo2_interface_info, + &vtable, NULL, NULL, &error); + g_assert_no_error (error); + g_assert (registration_id); + + test_async_case (c, NULL, "random", "()"); + + /* Test a variety of error cases */ + test_async_case (c, NULL, "Get", "(si)", "wrong signature", 5); + test_async_case (c, NULL, "Get", "(ss)", "org.example.WrongInterface", "zzz"); + test_async_case (c, NULL, "Get", "(ss)", "org.example.Foo", "NoSuchProperty"); + test_async_case (c, NULL, "Get", "(ss)", "org.example.Foo", "NotReadable"); + + test_async_case (c, NULL, "Set", "(si)", "wrong signature", 5); + test_async_case (c, NULL, "Set", "(ssv)", "org.example.WrongInterface", "zzz", g_variant_new_string ("")); + test_async_case (c, NULL, "Set", "(ssv)", "org.example.Foo", "NoSuchProperty", g_variant_new_string ("")); + test_async_case (c, NULL, "Set", "(ssv)", "org.example.Foo", "NotWritable", g_variant_new_string ("")); + test_async_case (c, NULL, "Set", "(ssv)", "org.example.Foo", "PropertyUno", g_variant_new_object_path ("/wrong")); + + test_async_case (c, NULL, "GetAll", "(si)", "wrong signature", 5); + test_async_case (c, NULL, "GetAll", "(s)", "org.example.WrongInterface"); + + /* Make sure that we get no unexpected async property calls for com.example.Foo2 */ + test_async_case (c, NULL, "Get", "(ss)", "org.example.Foo2", "zzz"); + test_async_case (c, NULL, "Set", "(ssv)", "org.example.Foo2", "zzz", g_variant_new_string ("")); + test_async_case (c, "(@a{sv} {},)", "GetAll", "(s)", "org.example.Foo2"); + + /* Now do the proper things */ + test_async_case (c, "(<'PropertyUno'>,)", "Get", "(ss)", "org.example.Foo", "PropertyUno"); + test_async_case (c, "(<'NotWritable'>,)", "Get", "(ss)", "org.example.Foo", "NotWritable"); + test_async_case (c, "()", "Set", "(ssv)", "org.example.Foo", "PropertyUno", g_variant_new_string ("")); + test_async_case (c, "()", "Set", "(ssv)", "org.example.Foo", "NotReadable", g_variant_new_string ("")); + test_async_case (c, "({'PropertyUno': <'uno'>, 'NotWritable': <'notwrite'>},)", "GetAll", "(s)", "org.example.Foo"); + + while (outstanding_cases) + g_main_context_iteration (NULL, TRUE); + + g_dbus_connection_unregister_object (c, registration_id); + g_dbus_connection_unregister_object (c, registration_id2); + g_object_unref (c); +} + +typedef struct +{ + GDBusConnection *connection; /* (owned) */ + guint registration_id; + guint subtree_registration_id; +} ThreadedUnregistrationData; + +static gpointer +unregister_thread_cb (gpointer user_data) +{ + ThreadedUnregistrationData *data = user_data; + + /* Sleeping here makes the race more likely to be hit, as it balances the + * time taken to set up the thread and unregister, with the time taken to + * make and handle the D-Bus call. This will likely change with future kernel + * versions, but there isn’t a more deterministic synchronisation point that + * I can think of to use instead. */ + usleep (330); + + if (data->registration_id > 0) + g_assert_true (g_dbus_connection_unregister_object (data->connection, data->registration_id)); + + if (data->subtree_registration_id > 0) + g_assert_true (g_dbus_connection_unregister_subtree (data->connection, data->subtree_registration_id)); + + return NULL; +} + +static void +async_result_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GAsyncResult **result_out = user_data; + + *result_out = g_object_ref (result); + g_main_context_wakeup (NULL); +} + +/* Returns %TRUE if this iteration resolved the race with the unregistration + * first, %FALSE if the call handler was invoked first. */ +static gboolean +test_threaded_unregistration_iteration (gboolean subtree) +{ + ThreadedUnregistrationData data = { NULL, 0, 0 }; + ObjectRegistrationData object_registration_data = { 0, 0, 2 }; + GError *local_error = NULL; + GThread *unregister_thread = NULL; + const gchar *object_path; + GVariant *value = NULL; + const gchar *value_str; + GAsyncResult *call_result = NULL; + gboolean unregistration_was_first; + + data.connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (data.connection); + + /* Register an object or a subtree */ + if (!subtree) + { + data.registration_id = g_dbus_connection_register_object (data.connection, + "/foo/boss", + (GDBusInterfaceInfo *) &foo_interface_info, + &foo_vtable, + &object_registration_data, + on_object_unregistered, + &local_error); + g_assert_no_error (local_error); + g_assert_cmpint (data.registration_id, >, 0); + + object_path = "/foo/boss"; + } + else + { + data.subtree_registration_id = g_dbus_connection_register_subtree (data.connection, + "/foo/boss/executives", + &subtree_vtable, + G_DBUS_SUBTREE_FLAGS_NONE, + &object_registration_data, + on_subtree_unregistered, + &local_error); + g_assert_no_error (local_error); + g_assert_cmpint (data.subtree_registration_id, >, 0); + + object_path = "/foo/boss/executives/vp0"; + } + + /* Allow the registrations to go through. */ + g_main_context_iteration (NULL, FALSE); + + /* Spawn a thread to unregister the object/subtree. This will race with + * the call we subsequently make. */ + unregister_thread = g_thread_new ("unregister-object", + unregister_thread_cb, &data); + + /* Call a method on the object (or an object in the subtree). The callback + * will be invoked in this main context. */ + g_dbus_connection_call (data.connection, + g_dbus_connection_get_unique_name (data.connection), + object_path, + "org.example.Foo", + "Method1", + g_variant_new ("(s)", "winwinwin"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + async_result_cb, + &call_result); + + while (call_result == NULL) + g_main_context_iteration (NULL, TRUE); + + value = g_dbus_connection_call_finish (data.connection, call_result, &local_error); + + /* The result of the method could either be an error (that the object doesn’t + * exist) or a valid result, depending on how the thread was scheduled + * relative to the call. */ + unregistration_was_first = (value == NULL); + if (value != NULL) + { + g_assert_no_error (local_error); + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE ("(s)"))); + g_variant_get (value, "(&s)", &value_str); + g_assert_cmpstr (value_str, ==, "You passed the string 'winwinwin'. Jolly good!"); + } + else + { + g_assert_null (value); + g_assert_error (local_error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + } + + g_clear_pointer (&value, g_variant_unref); + g_clear_error (&local_error); + + /* Tidy up. */ + g_thread_join (g_steal_pointer (&unregister_thread)); + + g_clear_object (&call_result); + g_clear_object (&data.connection); + + return unregistration_was_first; +} + +static void +test_threaded_unregistration (gconstpointer test_data) +{ + gboolean subtree = GPOINTER_TO_INT (test_data); + guint i; + guint n_iterations_unregistration_first = 0; + guint n_iterations_call_first = 0; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2400"); + g_test_summary ("Test that object/subtree unregistration from one thread " + "doesn’t cause problems when racing with method callbacks " + "in another thread for that object or subtree"); + + /* Run iterations of the test until it’s likely we’ve hit the race. Limit the + * number of iterations so the test doesn’t run forever if not. The choice of + * 100 is arbitrary. */ + for (i = 0; i < 1000 && (n_iterations_unregistration_first < 100 || n_iterations_call_first < 100); i++) + { + if (test_threaded_unregistration_iteration (subtree)) + n_iterations_unregistration_first++; + else + n_iterations_call_first++; + } + + /* If the condition below is met, we probably failed to reproduce the race. + * Don’t fail the test, though, as we can’t always control whether we hit the + * race, and spurious test failures are annoying. */ + if (n_iterations_unregistration_first < 100 || + n_iterations_call_first < 100) + g_test_skip_printf ("Failed to reproduce race (%u iterations with unregistration first, %u with call first); skipping test", + n_iterations_unregistration_first, n_iterations_call_first); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, NULL); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_add_func ("/gdbus/object-registration", test_object_registration); + g_test_add_func ("/gdbus/object-registration-with-closures", test_object_registration_with_closures); + g_test_add_func ("/gdbus/registered-interfaces", test_registered_interfaces); + g_test_add_func ("/gdbus/async-properties", test_async_properties); + g_test_add_data_func ("/gdbus/threaded-unregistration/object", GINT_TO_POINTER (FALSE), test_threaded_unregistration); + g_test_add_data_func ("/gdbus/threaded-unregistration/subtree", GINT_TO_POINTER (TRUE), test_threaded_unregistration); + + /* TODO: check that we spit out correct introspection data */ + /* TODO: check that registering a whole subtree works */ + + ret = session_bus_run (); + + g_main_loop_unref (loop); + + return ret; +} diff --git a/gio/tests/gdbus-introspection.c b/gio/tests/gdbus-introspection.c new file mode 100644 index 0000000..50c0cc7 --- /dev/null +++ b/gio/tests/gdbus-introspection.c @@ -0,0 +1,324 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test introspection parser */ +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_introspection (GDBusProxy *proxy) +{ + GError *error; + const gchar *xml_data; + GDBusNodeInfo *node_info; + GDBusInterfaceInfo *interface_info; + GDBusMethodInfo *method_info; + GDBusSignalInfo *signal_info; + GVariant *result; + + error = NULL; + + /* + * Invoke Introspect(), then parse the output. + */ + result = g_dbus_proxy_call_sync (proxy, + "org.freedesktop.DBus.Introspectable.Introspect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_variant_get (result, "(&s)", &xml_data); + + node_info = g_dbus_node_info_new_for_xml (xml_data, &error); + g_assert_no_error (error); + g_assert (node_info != NULL); + + /* for now we only check a couple of things. TODO: check more things */ + + interface_info = g_dbus_node_info_lookup_interface (node_info, "com.example.NonExistantInterface"); + g_assert (interface_info == NULL); + + interface_info = g_dbus_node_info_lookup_interface (node_info, "org.freedesktop.DBus.Introspectable"); + g_assert (interface_info != NULL); + method_info = g_dbus_interface_info_lookup_method (interface_info, "NonExistantMethod"); + g_assert (method_info == NULL); + method_info = g_dbus_interface_info_lookup_method (interface_info, "Introspect"); + g_assert (method_info != NULL); + g_assert (method_info->in_args != NULL); + g_assert (method_info->in_args[0] == NULL); + g_assert (method_info->out_args != NULL); + g_assert (method_info->out_args[0] != NULL); + g_assert (method_info->out_args[1] == NULL); + g_assert_cmpstr (method_info->out_args[0]->signature, ==, "s"); + + interface_info = g_dbus_node_info_lookup_interface (node_info, "com.example.Frob"); + g_assert (interface_info != NULL); + signal_info = g_dbus_interface_info_lookup_signal (interface_info, "TestSignal"); + g_assert (signal_info != NULL); + g_assert (signal_info->args != NULL); + g_assert (signal_info->args[0] != NULL); + g_assert_cmpstr (signal_info->args[0]->signature, ==, "s"); + g_assert (signal_info->args[1] != NULL); + g_assert_cmpstr (signal_info->args[1]->signature, ==, "o"); + g_assert (signal_info->args[2] != NULL); + g_assert_cmpstr (signal_info->args[2]->signature, ==, "v"); + g_assert (signal_info->args[3] == NULL); + + g_dbus_node_info_unref (node_info); + g_variant_unref (result); + + g_main_loop_quit (loop); +} + +static void +test_introspection_parser (void) +{ + GDBusProxy *proxy; + GDBusConnection *connection; + GError *error; + + error = NULL; + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, + NULL, + &error); + g_assert_no_error (error); + error = NULL; + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + /* this is safe; testserver will exit once the bus goes away */ + g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + + _g_assert_property_notify (proxy, "g-name-owner"); + + test_introspection (proxy); + + g_object_unref (proxy); + g_object_unref (connection); +} + +/* check that a parse-generate roundtrip produces identical results + */ +static void +test_generate (void) +{ + GDBusNodeInfo *info; + GDBusNodeInfo *info2; + GDBusInterfaceInfo *iinfo; + GDBusMethodInfo *minfo; + GDBusSignalInfo *sinfo; + GDBusArgInfo *arginfo; + GDBusPropertyInfo *pinfo; + GDBusAnnotationInfo *aninfo; + const gchar *data = + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " "; + + GString *string; + GString *string2; + GError *error; + + error = NULL; + info = g_dbus_node_info_new_for_xml (data, &error); + g_assert_no_error (error); + + iinfo = g_dbus_node_info_lookup_interface (info, "com.example.Frob"); + aninfo = iinfo->annotations[0]; + g_assert_cmpstr (aninfo->key, ==, "foo"); + g_assert_cmpstr (aninfo->value, ==, "bar"); + g_assert (iinfo->annotations[1] == NULL); + minfo = g_dbus_interface_info_lookup_method (iinfo, "PairReturn"); + g_assert_cmpstr (g_dbus_annotation_info_lookup (minfo->annotations, "org.freedesktop.DBus.GLib.Async"), ==, ""); + arginfo = minfo->in_args[0]; + g_assert_cmpstr (arginfo->name, ==, "somenumber"); + g_assert_cmpstr (arginfo->signature, ==, "u"); + g_assert (minfo->in_args[1] == NULL); + arginfo = minfo->out_args[0]; + g_assert_cmpstr (arginfo->name, ==, "somestring"); + g_assert_cmpstr (arginfo->signature, ==, "s"); + g_assert (minfo->out_args[1] == NULL); + sinfo = g_dbus_interface_info_lookup_signal (iinfo, "HelloWorld"); + arginfo = sinfo->args[0]; + g_assert_cmpstr (arginfo->name, ==, "greeting"); + g_assert_cmpstr (arginfo->signature, ==, "s"); + g_assert (sinfo->args[1] == NULL); + pinfo = g_dbus_interface_info_lookup_property (iinfo, "y"); + g_assert_cmpstr (pinfo->signature, ==, "y"); + g_assert_cmpint (pinfo->flags, ==, G_DBUS_PROPERTY_INFO_FLAGS_READABLE | + G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE); + + string = g_string_new (""); + g_dbus_node_info_generate_xml (info, 2, string); + + info2 = g_dbus_node_info_new_for_xml (string->str, &error); + string2 = g_string_new (""); + g_dbus_node_info_generate_xml (info2, 2, string2); + + g_assert_cmpstr (string->str, ==, string2->str); + g_string_free (string, TRUE); + g_string_free (string2, TRUE); + + g_dbus_node_info_unref (info); + g_dbus_node_info_unref (info2); +} + +/* test that omitted direction attributes default to 'out' for signals, + * and 'in' for methods. + */ +static void +test_default_direction (void) +{ + GDBusNodeInfo *info; + GDBusInterfaceInfo *iinfo; + GDBusMethodInfo *minfo; + GDBusSignalInfo *sinfo; + GDBusArgInfo *arginfo; + const gchar *data = + " " + " " + " " + " " + " " + " " + " " + " " + " " + " "; + + GError *error; + + error = NULL; + info = g_dbus_node_info_new_for_xml (data, &error); + g_assert_no_error (error); + + iinfo = g_dbus_node_info_lookup_interface (info, "com.example.Frob"); + sinfo = g_dbus_interface_info_lookup_signal (iinfo, "HelloWorld"); + g_assert (sinfo->args != NULL); + arginfo = sinfo->args[0]; + g_assert_cmpstr (arginfo->name, ==, "greeting"); + g_assert (sinfo->args[1] == NULL); + minfo = g_dbus_interface_info_lookup_method (iinfo, "Sleep"); + g_assert (minfo->in_args != NULL); + arginfo = minfo->in_args[0]; + g_assert_cmpstr (arginfo->name, ==, "timeout"); + g_assert (minfo->in_args[1] == NULL); + + g_dbus_node_info_unref (info); +} + +static void +test_extra_data (void) +{ + GDBusNodeInfo *info; + const gchar *data = + " " + " " + " Blah blah" + " " + " " + " " + " See example" + " " + " " + " " + " " + " More docs" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " "; + GError *error; + + error = NULL; + info = g_dbus_node_info_new_for_xml (data, &error); + g_assert_no_error (error); + + g_dbus_node_info_unref (info); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, NULL); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_add_func ("/gdbus/introspection-parser", test_introspection_parser); + g_test_add_func ("/gdbus/introspection-generate", test_generate); + g_test_add_func ("/gdbus/introspection-default-direction", test_default_direction); + g_test_add_func ("/gdbus/introspection-extra-data", test_extra_data); + + ret = session_bus_run (); + + while (g_main_context_iteration (NULL, FALSE)); + g_main_loop_unref (loop); + + return ret; +} diff --git a/gio/tests/gdbus-message.c b/gio/tests/gdbus-message.c new file mode 100644 index 0000000..9323574 --- /dev/null +++ b/gio/tests/gdbus-message.c @@ -0,0 +1,225 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_notify_locked (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + gint *count = user_data; + *count += 1; +} + +static void +message_lock (void) +{ + GDBusMessage *m; + gint count; + + count = 0; + m = g_dbus_message_new (); + g_signal_connect (m, + "notify::locked", + G_CALLBACK (on_notify_locked), + &count); + g_assert (!g_dbus_message_get_locked (m)); + g_dbus_message_lock (m); + g_assert (g_dbus_message_get_locked (m)); + g_assert_cmpint (count, ==, 1); + g_dbus_message_lock (m); + g_assert (g_dbus_message_get_locked (m)); + g_assert_cmpint (count, ==, 1); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*Attempted to modify a locked message*"); + g_dbus_message_set_serial (m, 42); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*Attempted to modify a locked message*"); + g_dbus_message_set_byte_order (m, G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*Attempted to modify a locked message*"); + g_dbus_message_set_message_type (m, G_DBUS_MESSAGE_TYPE_METHOD_CALL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*Attempted to modify a locked message*"); + g_dbus_message_set_flags (m, G_DBUS_MESSAGE_FLAGS_NONE); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*Attempted to modify a locked message*"); + g_dbus_message_set_body (m, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*Attempted to modify a locked message*"); + g_dbus_message_set_header (m, 0, NULL); + g_test_assert_expected_messages (); + + g_object_unref (m); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +message_copy (void) +{ + GDBusMessage *m; + GDBusMessage *copy; + GError *error; + guchar *m_headers; + guchar *copy_headers; + guint n; + + m = g_dbus_message_new_method_call ("org.example.Name", + "/org/example/Object", + "org.example.Interface", + "Method"); + g_dbus_message_set_serial (m, 42); + g_dbus_message_set_byte_order (m, G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN); + + error = NULL; + copy = g_dbus_message_copy (m, &error); + g_assert_no_error (error); + g_assert (G_IS_DBUS_MESSAGE (copy)); + g_assert (m != copy); + g_assert_cmpint (G_OBJECT (m)->ref_count, ==, 1); + g_assert_cmpint (G_OBJECT (copy)->ref_count, ==, 1); + + g_assert_cmpint (g_dbus_message_get_serial (copy), ==, g_dbus_message_get_serial (m)); + g_assert_cmpint (g_dbus_message_get_byte_order (copy), ==, g_dbus_message_get_byte_order (m)); + g_assert_cmpint (g_dbus_message_get_flags (copy), ==, g_dbus_message_get_flags (m)); + g_assert_cmpint (g_dbus_message_get_message_type (copy), ==, g_dbus_message_get_message_type (m)); + m_headers = g_dbus_message_get_header_fields (m); + copy_headers = g_dbus_message_get_header_fields (copy); + g_assert (m_headers != NULL); + g_assert (copy_headers != NULL); + for (n = 0; m_headers[n] != 0; n++) + { + GVariant *m_val; + GVariant *copy_val; + m_val = g_dbus_message_get_header (m, m_headers[n]); + copy_val = g_dbus_message_get_header (m, m_headers[n]); + g_assert (m_val != NULL); + g_assert (copy_val != NULL); + g_assert_cmpvariant (m_val, copy_val); + } + g_assert_cmpint (n, >, 0); /* make sure we actually compared headers etc. */ + g_assert_cmpint (copy_headers[n], ==, 0); + g_free (m_headers); + g_free (copy_headers); + + g_object_unref (copy); + g_object_unref (m); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Test g_dbus_message_bytes_needed() returns correct results for a variety of + * arbitrary binary inputs.*/ +static void +message_bytes_needed (void) +{ + const struct + { + const guint8 blob[16]; + gssize expected_bytes_needed; + } + vectors[] = + { + /* Little endian with header rounding */ + { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */ + 50, 0, 0, 0, /* body length */ + 1, 0, 0, 0, /* message serial */ + 7, 0, 0, 0 /* header length */}, 74 }, + /* Little endian without header rounding */ + { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */ + 50, 0, 0, 0, /* body length */ + 1, 0, 0, 0, /* message serial */ + 8, 0, 0, 0 /* header length */}, 74 }, + /* Big endian with header rounding */ + { { 'B', 0, 0, 1, /* endianness, message type, flags, protocol version */ + 0, 0, 0, 50, /* body length */ + 0, 0, 0, 1, /* message serial */ + 0, 0, 0, 7 /* header length */}, 74 }, + /* Big endian without header rounding */ + { { 'B', 0, 0, 1, /* endianness, message type, flags, protocol version */ + 0, 0, 0, 50, /* body length */ + 0, 0, 0, 1, /* message serial */ + 0, 0, 0, 8 /* header length */}, 74 }, + /* Invalid endianness */ + { { '!', 0, 0, 1, /* endianness, message type, flags, protocol version */ + 0, 0, 0, 50, /* body length */ + 0, 0, 0, 1, /* message serial */ + 0, 0, 0, 8 /* header length */}, -1 }, + /* Oversized */ + { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */ + 0, 0, 0, 0x08, /* body length (128MiB) */ + 1, 0, 0, 0, /* message serial */ + 7, 0, 0, 0 /* header length */}, -1 }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + gssize bytes_needed; + GError *local_error = NULL; + + g_test_message ("Vector: %" G_GSIZE_FORMAT, i); + + bytes_needed = g_dbus_message_bytes_needed ((guchar *) vectors[i].blob, + G_N_ELEMENTS (vectors[i].blob), + &local_error); + + if (vectors[i].expected_bytes_needed < 0) + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + else + g_assert_no_error (local_error); + g_assert_cmpint (bytes_needed, ==, vectors[i].expected_bytes_needed); + + g_clear_error (&local_error); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + setlocale (LC_ALL, "C"); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gdbus/message/lock", message_lock); + g_test_add_func ("/gdbus/message/copy", message_copy); + g_test_add_func ("/gdbus/message/bytes-needed", message_bytes_needed); + + return g_test_run (); +} diff --git a/gio/tests/gdbus-method-invocation.c b/gio/tests/gdbus-method-invocation.c new file mode 100644 index 0000000..45fb677 --- /dev/null +++ b/gio/tests/gdbus-method-invocation.c @@ -0,0 +1,406 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright © 2022 Endless OS Foundation, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include +#include +#include +#include + +#include "gdbus-tests.h" + +static const GDBusArgInfo foo_get_fds_in_args = +{ + -1, + "type", + "s", + NULL +}; +static const GDBusArgInfo * const foo_get_fds_in_arg_pointers[] = {&foo_get_fds_in_args, NULL}; + +static const GDBusArgInfo foo_get_fds_out_args = +{ + -1, + "some_fd", + "h", + NULL +}; +static const GDBusArgInfo * const foo_get_fds_out_arg_pointers[] = {&foo_get_fds_out_args, NULL}; + +static const GDBusMethodInfo foo_method_info_wrong_return_type = +{ + -1, + "WrongReturnType", + NULL, /* in args */ + NULL, /* out args */ + NULL /* annotations */ +}; +static const GDBusMethodInfo foo_method_info_close_before_returning = +{ + -1, + "CloseBeforeReturning", + NULL, /* in args */ + NULL, /* out args */ + NULL /* annotations */ +}; +static const GDBusMethodInfo foo_method_info_get_fds = +{ + -1, + "GetFDs", + (GDBusArgInfo **) foo_get_fds_in_arg_pointers, + (GDBusArgInfo **) foo_get_fds_out_arg_pointers, + NULL /* annotations */ +}; +static const GDBusMethodInfo foo_method_info_return_error = +{ + -1, + "ReturnError", + NULL, /* in args */ + NULL, /* out args */ + NULL /* annotations */ +}; +static const GDBusMethodInfo * const foo_method_info_pointers[] = { + &foo_method_info_wrong_return_type, + &foo_method_info_close_before_returning, + &foo_method_info_get_fds, + &foo_method_info_return_error, + NULL +}; + +static const GDBusPropertyInfo foo_property_info[] = +{ + { + -1, + "InvalidType", + "s", + G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, + NULL + }, + { + -1, + "InvalidTypeNull", + "s", + G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, + NULL + }, + { + -1, + "InvalidValueType", + "s", + G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, + NULL + }, +}; +static const GDBusPropertyInfo * const foo_property_info_pointers[] = +{ + &foo_property_info[0], + &foo_property_info[1], + &foo_property_info[2], + NULL +}; + +static const GDBusInterfaceInfo foo_interface_info = +{ + -1, + "org.example.Foo", + (GDBusMethodInfo **) &foo_method_info_pointers, + NULL, /* signals */ + (GDBusPropertyInfo **) &foo_property_info_pointers, + NULL, /* annotations */ +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_method_invocation_return_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + gboolean no_reply = g_dbus_message_get_flags (g_dbus_method_invocation_get_message (invocation)) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED; + + if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") && + g_str_equal (method_name, "Get")) + { + const gchar *iface_name, *prop_name; + + g_variant_get (parameters, "(&s&s)", &iface_name, &prop_name); + g_assert_cmpstr (iface_name, ==, "org.example.Foo"); + + /* Do different things depending on the property name. */ + if (g_str_equal (prop_name, "InvalidType")) + { + if (!no_reply) + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, + "Type of return value for property 'Get' call should be '(v)' but got '(s)'"); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "this type is invalid")); + } + else if (g_str_equal (prop_name, "InvalidTypeNull")) + { + if (!no_reply) + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, + "Type of return value for property 'Get' call should be '(v)' but got '()'"); + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_str_equal (prop_name, "InvalidValueType")) + { + if (!no_reply) + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, + "Value returned from property 'Get' call for 'InvalidValueType' should be 's' but is 'u'"); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(v)", g_variant_new_uint32 (123))); + } + else + { + g_assert_not_reached (); + } + + g_test_assert_expected_messages (); + } + else if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") && + g_str_equal (method_name, "Set")) + { + const gchar *iface_name, *prop_name; + GVariant *value; + + g_variant_get (parameters, "(&s&sv)", &iface_name, &prop_name, &value); + g_assert_cmpstr (iface_name, ==, "org.example.Foo"); + + if (g_str_equal (prop_name, "InvalidType")) + { + if (!no_reply) + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, + "Type of return value for property 'Set' call should be '()' but got '(s)'"); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be unit")); + } + else + { + g_assert_not_reached (); + } + + g_test_assert_expected_messages (); + g_variant_unref (value); + } + else if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") && + g_str_equal (method_name, "GetAll")) + { + const gchar *iface_name; + + g_variant_get (parameters, "(&s)", &iface_name); + g_assert_cmpstr (iface_name, ==, "org.example.Foo"); + + if (!no_reply) + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, + "Type of return value for property 'GetAll' call should be '(a{sv})' but got '(s)'"); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be a different type")); + } + else if (g_str_equal (interface_name, "org.example.Foo") && + g_str_equal (method_name, "WrongReturnType")) + { + if (!no_reply) + g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, + "Type of return value is incorrect: expected '()', got '(s)'"); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be a different type")); + } + else if (g_str_equal (interface_name, "org.example.Foo") && + g_str_equal (method_name, "CloseBeforeReturning")) + { + g_dbus_connection_close (connection, NULL, NULL, NULL); + + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_str_equal (interface_name, "org.example.Foo") && + g_str_equal (method_name, "GetFDs")) + { + const gchar *action; + GUnixFDList *list = NULL; + GError *local_error = NULL; + + g_variant_get (parameters, "(&s)", &action); + + list = g_unix_fd_list_new (); + g_unix_fd_list_append (list, 1, &local_error); + g_assert_no_error (local_error); + + if (g_str_equal (action, "WrongNumber")) + { + g_unix_fd_list_append (list, 1, &local_error); + g_assert_no_error (local_error); + } + + if (g_str_equal (action, "Valid") || + g_str_equal (action, "WrongNumber")) + g_dbus_method_invocation_return_value_with_unix_fd_list (invocation, g_variant_new ("(h)"), list); + else + g_assert_not_reached (); + + g_object_unref (list); + } + else if (g_str_equal (interface_name, "org.example.Foo") && + g_str_equal (method_name, "ReturnError")) + { + g_dbus_method_invocation_return_dbus_error (invocation, "org.example.Foo", "SomeError"); + } + else + g_assert_not_reached (); +} + +static void +ensure_result_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (source); + GVariant *reply; + guint *n_outstanding_calls = user_data; + + reply = g_dbus_connection_call_finish (connection, result, NULL); + + /* We don’t care what the reply is. */ + g_clear_pointer (&reply, g_variant_unref); + + g_assert_cmpint (*n_outstanding_calls, >, 0); + *n_outstanding_calls = *n_outstanding_calls - 1; +} + +static void +test_method_invocation_return (void) +{ + GDBusConnection *connection = NULL; + GError *local_error = NULL; + guint registration_id; + const GDBusInterfaceVTable vtable = { + test_method_invocation_return_method_call, NULL, NULL, { 0 } + }; + guint n_outstanding_calls = 0; + + g_test_summary ("Test calling g_dbus_method_invocation_return_*() in various ways"); + + /* Connect to the bus. */ + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (connection); + + /* Don’t exit the test when the server closes the connection in + * CloseBeforeReturning(). */ + g_dbus_connection_set_exit_on_close (connection, FALSE); + + /* Register an object which we can call methods on. */ + registration_id = g_dbus_connection_register_object (connection, + "/foo", + (GDBusInterfaceInfo *) &foo_interface_info, + &vtable, NULL, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_cmpint (registration_id, !=, 0); + + /* Test a variety of error cases */ + { + const struct + { + const gchar *interface_name; + const gchar *method_name; + const gchar *parameters_string; + gboolean tests_undefined_behaviour; + } + calls[] = + { + { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidType')", TRUE }, + { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidTypeNull')", TRUE }, + { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidValueType')", TRUE }, + { "org.freedesktop.DBus.Properties", "Set", "('org.example.Foo', 'InvalidType', <'irrelevant'>)", TRUE }, + { "org.freedesktop.DBus.Properties", "GetAll", "('org.example.Foo',)", TRUE }, + { "org.example.Foo", "WrongReturnType", "()", TRUE }, + { "org.example.Foo", "GetFDs", "('Valid',)", FALSE }, + { "org.example.Foo", "GetFDs", "('WrongNumber',)", TRUE }, + { "org.example.Foo", "ReturnError", "()", FALSE }, + { "org.example.Foo", "CloseBeforeReturning", "()", FALSE }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (calls); i++) + { + if (calls[i].tests_undefined_behaviour && !g_test_undefined ()) + { + g_test_message ("Skipping %s.%s", calls[i].interface_name, calls[i].method_name); + continue; + } + else + { + g_test_message ("Calling %s.%s", calls[i].interface_name, calls[i].method_name); + } + + /* Call twice, once expecting a result and once not. Do the call which + * doesn’t expect a result first; message ordering should ensure that + * it’s completed by the time the second call completes, so we don’t + * have to account for it separately. + * + * That’s good, because the only way to get g_dbus_connection_call() + * to set %G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED is to not provide + * a callback function. */ + n_outstanding_calls++; + + g_dbus_connection_call (connection, + g_dbus_connection_get_unique_name (connection), + "/foo", + calls[i].interface_name, + calls[i].method_name, + g_variant_new_parsed (calls[i].parameters_string), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, /* no callback */ + NULL); + + g_dbus_connection_call (connection, + g_dbus_connection_get_unique_name (connection), + "/foo", + calls[i].interface_name, + calls[i].method_name, + g_variant_new_parsed (calls[i].parameters_string), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + ensure_result_cb, + &n_outstanding_calls); + } + } + + /* Wait until all the calls are complete. */ + while (n_outstanding_calls > 0) + g_main_context_iteration (NULL, TRUE); + + g_dbus_connection_unregister_object (connection, registration_id); + g_object_unref (connection); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add_func ("/gdbus/method-invocation/return", test_method_invocation_return); + + return session_bus_run (); +} diff --git a/gio/tests/gdbus-names.c b/gio/tests/gdbus-names.c new file mode 100644 index 0000000..838a4ee --- /dev/null +++ b/gio/tests/gdbus-names.c @@ -0,0 +1,1368 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * Copyright (C) 2021 Frederic Martinsons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + * Author: Frederic Martinsons + */ + +#include +#include + +#include "gdbus-tests.h" + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that g_bus_own_name() works correctly */ +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + gboolean expect_null_connection; + guint num_bus_acquired; + guint num_acquired; + guint num_lost; + guint num_free_func; + GMainContext *main_context; /* (unowned) */ +} OwnNameData; + +static void +own_name_data_free_func (OwnNameData *data) +{ + data->num_free_func++; + g_main_context_wakeup (data->main_context); +} + +static void +bus_acquired_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + OwnNameData *data = user_data; + g_dbus_connection_set_exit_on_close (connection, FALSE); + data->num_bus_acquired += 1; + g_main_context_wakeup (data->main_context); +} + +static void +name_acquired_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + OwnNameData *data = user_data; + data->num_acquired += 1; + g_main_context_wakeup (data->main_context); +} + +static void +name_lost_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + OwnNameData *data = user_data; + if (data->expect_null_connection) + { + g_assert (connection == NULL); + } + else + { + g_assert (connection != NULL); + g_dbus_connection_set_exit_on_close (connection, FALSE); + } + data->num_lost += 1; + g_main_context_wakeup (data->main_context); +} + +static void +test_bus_own_name (void) +{ + guint id; + guint id2; + OwnNameData data; + OwnNameData data2; + const gchar *name; + GDBusConnection *c; + GError *error; + gboolean name_has_owner_reply; + GDBusConnection *c2; + GVariant *result; + GMainContext *main_context = NULL; /* use the global default for now */ + + error = NULL; + name = "org.gtk.GDBus.Name1"; + + /* + * First check that name_lost_handler() is invoked if there is no bus. + * + * Also make sure name_lost_handler() isn't invoked when unowning the name. + */ + data.num_bus_acquired = 0; + data.num_free_func = 0; + data.num_acquired = 0; + data.num_lost = 0; + data.expect_null_connection = TRUE; + data.main_context = main_context; + id = g_bus_own_name (G_BUS_TYPE_SESSION, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired_handler, + name_acquired_handler, + name_lost_handler, + &data, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data.num_bus_acquired, ==, 0); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 0); + + while (data.num_lost < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_bus_acquired, ==, 0); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 1); + g_bus_unown_name (id); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 1); + g_assert_cmpint (data.num_free_func, ==, 1); + + /* + * Bring up a bus, then own a name and check bus_acquired_handler() then name_acquired_handler() is invoked. + */ + session_bus_up (); + data.num_bus_acquired = 0; + data.num_acquired = 0; + data.num_lost = 0; + data.expect_null_connection = FALSE; + id = g_bus_own_name (G_BUS_TYPE_SESSION, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired_handler, + name_acquired_handler, + name_lost_handler, + &data, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data.num_bus_acquired, ==, 0); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 0); + + while (data.num_bus_acquired < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 0); + + while (data.num_acquired < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_lost, ==, 0); + + /* + * Check that the name was actually acquired. + */ + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert (c != NULL); + g_assert (!g_dbus_connection_is_closed (c)); + result = g_dbus_connection_call_sync (c, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "NameHasOwner", /* method name */ + g_variant_new ("(s)", name), + G_VARIANT_TYPE ("(b)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_variant_get (result, "(b)", &name_has_owner_reply); + g_assert (name_has_owner_reply); + g_variant_unref (result); + + /* + * Stop owning the name - this should invoke our free func + */ + g_bus_unown_name (id); + while (data.num_free_func < 2) + g_main_context_iteration (main_context, TRUE); + g_assert_cmpint (data.num_free_func, ==, 2); + + /* + * Check that the name was actually released. + */ + result = g_dbus_connection_call_sync (c, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "NameHasOwner", /* method name */ + g_variant_new ("(s)", name), + G_VARIANT_TYPE ("(b)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_variant_get (result, "(b)", &name_has_owner_reply); + g_assert (!name_has_owner_reply); + g_variant_unref (result); + + /* Now try owning the name and then immediately decide to unown the name */ + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_lost, ==, 0); + g_assert_cmpint (data.num_free_func, ==, 2); + id = g_bus_own_name (G_BUS_TYPE_SESSION, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired_handler, + name_acquired_handler, + name_lost_handler, + &data, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_lost, ==, 0); + g_assert_cmpint (data.num_free_func, ==, 2); + g_bus_unown_name (id); + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_lost, ==, 0); + g_assert_cmpint (data.num_free_func, ==, 2); + + /* the GDestroyNotify is called in idle because the bus is acquired in idle */ + while (data.num_free_func < 3) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_free_func, ==, 3); + + /* + * Own the name again. + */ + data.num_bus_acquired = 0; + data.num_acquired = 0; + data.num_lost = 0; + data.expect_null_connection = FALSE; + id = g_bus_own_name_with_closures (G_BUS_TYPE_SESSION, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + g_cclosure_new (G_CALLBACK (bus_acquired_handler), + &data, + NULL), + g_cclosure_new (G_CALLBACK (name_acquired_handler), + &data, + NULL), + g_cclosure_new (G_CALLBACK (name_lost_handler), + &data, + (GClosureNotify) own_name_data_free_func)); + g_assert_cmpint (data.num_bus_acquired, ==, 0); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 0); + + while (data.num_bus_acquired < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 0); + + while (data.num_acquired < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_lost, ==, 0); + + /* + * Try owning the name with another object on the same connection - this should + * fail because we already own the name. + */ + data2.num_free_func = 0; + data2.num_bus_acquired = 0; + data2.num_acquired = 0; + data2.num_lost = 0; + data2.expect_null_connection = FALSE; + data2.main_context = main_context; + id2 = g_bus_own_name (G_BUS_TYPE_SESSION, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired_handler, + name_acquired_handler, + name_lost_handler, + &data2, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 0); + + while (data2.num_bus_acquired < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 1); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 0); + + while (data2.num_lost < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 1); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 1); + + g_bus_unown_name (id2); + while (data2.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 1); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 1); + g_assert_cmpint (data2.num_free_func, ==, 1); + + /* + * Create a secondary (e.g. private) connection and try owning the name on that + * connection. This should fail both with and without _REPLACE because we + * didn't specify ALLOW_REPLACEMENT. + */ + c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert (c2 != NULL); + g_assert (!g_dbus_connection_is_closed (c2)); + /* first without _REPLACE */ + data2.num_bus_acquired = 0; + data2.num_acquired = 0; + data2.num_lost = 0; + data2.expect_null_connection = FALSE; + data2.num_free_func = 0; + id2 = g_bus_own_name_on_connection (c2, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + name_acquired_handler, + name_lost_handler, + &data2, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 0); + + while (data2.num_lost < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 1); + + g_bus_unown_name (id2); + while (data2.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 1); + g_assert_cmpint (data2.num_free_func, ==, 1); + /* then with _REPLACE */ + data2.num_bus_acquired = 0; + data2.num_acquired = 0; + data2.num_lost = 0; + data2.expect_null_connection = FALSE; + data2.num_free_func = 0; + id2 = g_bus_own_name_on_connection (c2, + name, + G_BUS_NAME_OWNER_FLAGS_REPLACE, + name_acquired_handler, + name_lost_handler, + &data2, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 0); + + while (data2.num_lost < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 1); + + g_bus_unown_name (id2); + while (data2.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 1); + g_assert_cmpint (data2.num_free_func, ==, 1); + + /* + * Stop owning the name and grab it again with _ALLOW_REPLACEMENT. + */ + data.expect_null_connection = FALSE; + g_bus_unown_name (id); + while (data.num_bus_acquired < 1 || data.num_free_func < 4) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_free_func, ==, 4); + /* grab it again */ + data.num_bus_acquired = 0; + data.num_acquired = 0; + data.num_lost = 0; + data.expect_null_connection = FALSE; + id = g_bus_own_name (G_BUS_TYPE_SESSION, + name, + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, + bus_acquired_handler, + name_acquired_handler, + name_lost_handler, + &data, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data.num_bus_acquired, ==, 0); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 0); + + while (data.num_bus_acquired < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 0); + g_assert_cmpint (data.num_lost, ==, 0); + + while (data.num_acquired < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_bus_acquired, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_lost, ==, 0); + + /* + * Now try to grab the name from the secondary connection. + * + */ + /* first without _REPLACE - this won't make us acquire the name */ + data2.num_bus_acquired = 0; + data2.num_acquired = 0; + data2.num_lost = 0; + data2.expect_null_connection = FALSE; + data2.num_free_func = 0; + id2 = g_bus_own_name_on_connection (c2, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + name_acquired_handler, + name_lost_handler, + &data2, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 0); + + while (data2.num_lost < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 1); + + g_bus_unown_name (id2); + while (data2.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 1); + g_assert_cmpint (data2.num_free_func, ==, 1); + /* then with _REPLACE - here we should acquire the name - e.g. owner should lose it + * and owner2 should acquire it */ + data2.num_bus_acquired = 0; + data2.num_acquired = 0; + data2.num_lost = 0; + data2.expect_null_connection = FALSE; + data2.num_free_func = 0; + id2 = g_bus_own_name_on_connection (c2, + name, + G_BUS_NAME_OWNER_FLAGS_REPLACE, + name_acquired_handler, + name_lost_handler, + &data2, + (GDestroyNotify) own_name_data_free_func); + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_lost, ==, 0); + g_assert_cmpint (data2.num_acquired, ==, 0); + g_assert_cmpint (data2.num_lost, ==, 0); + + /* wait for handlers for both owner and owner2 to fire */ + while (data.num_lost == 0 || data2.num_acquired == 0) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_acquired, ==, 1); + g_assert_cmpint (data.num_lost, ==, 1); + g_assert_cmpint (data2.num_acquired, ==, 1); + g_assert_cmpint (data2.num_lost, ==, 0); + g_assert_cmpint (data2.num_bus_acquired, ==, 0); + + /* ok, make owner2 release the name - then wait for owner to automagically reacquire it */ + g_bus_unown_name (id2); + while (data.num_acquired < 2 || data2.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data2.num_free_func, ==, 1); + g_assert_cmpint (data.num_acquired, ==, 2); + g_assert_cmpint (data.num_lost, ==, 1); + + /* + * Finally, nuke the bus and check name_lost_handler() is invoked. + * + */ + data.expect_null_connection = TRUE; + session_bus_stop (); + while (data.num_lost != 2) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_acquired, ==, 2); + g_assert_cmpint (data.num_lost, ==, 2); + + g_bus_unown_name (id); + while (data.num_free_func < 5) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_free_func, ==, 5); + + g_object_unref (c); + g_object_unref (c2); + + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that g_bus_watch_name() works correctly */ +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + gboolean expect_null_connection; + guint num_acquired; + guint num_lost; + guint num_appeared; + guint num_vanished; + guint num_free_func; + GMainContext *main_context; /* (unowned), for the main test thread */ +} WatchNameData; + +typedef struct +{ + WatchNameData data; + GDBusConnection *connection; + GMutex cond_mutex; + GCond cond; + gboolean started; + gboolean name_acquired; + gboolean ended; + gboolean unwatch_early; + GMutex mutex; + guint watch_id; + GMainContext *thread_context; /* (unowned), only accessed from watcher_thread() */ +} WatchNameThreadData; + +static void +watch_name_data_free_func (WatchNameData *data) +{ + data->num_free_func++; + g_main_context_wakeup (data->main_context); +} + +static void +w_bus_acquired_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ +} + +static void +w_name_acquired_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + OwnNameData *data = user_data; + data->num_acquired += 1; + g_main_context_wakeup (data->main_context); +} + +static void +w_name_lost_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + OwnNameData *data = user_data; + data->num_lost += 1; + g_main_context_wakeup (data->main_context); +} + +static void +name_appeared_handler (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + WatchNameData *data = user_data; + + if (data->expect_null_connection) + { + g_assert (connection == NULL); + } + else + { + g_assert (connection != NULL); + g_dbus_connection_set_exit_on_close (connection, FALSE); + } + data->num_appeared += 1; + g_main_context_wakeup (data->main_context); +} + +static void +name_vanished_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + WatchNameData *data = user_data; + + if (data->expect_null_connection) + { + g_assert (connection == NULL); + } + else + { + g_assert (connection != NULL); + g_dbus_connection_set_exit_on_close (connection, FALSE); + } + data->num_vanished += 1; + g_main_context_wakeup (data->main_context); +} + +typedef struct +{ + guint watcher_flags; + gboolean watch_with_closures; + gboolean existing_service; +} WatchNameTest; + +static const WatchNameTest watch_no_closures_no_flags = { + .watcher_flags = G_BUS_NAME_WATCHER_FLAGS_NONE, + .watch_with_closures = FALSE, + .existing_service = FALSE +}; + +static const WatchNameTest watch_no_closures_flags_auto_start = { + .watcher_flags = G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + .watch_with_closures = FALSE, + .existing_service = FALSE +}; + +static const WatchNameTest watch_no_closures_flags_auto_start_service_exist = { + .watcher_flags = G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + .watch_with_closures = FALSE, + .existing_service = TRUE +}; + +static const WatchNameTest watch_closures_no_flags = { + .watcher_flags = G_BUS_NAME_WATCHER_FLAGS_NONE, + .watch_with_closures = TRUE, + .existing_service = FALSE +}; + +static const WatchNameTest watch_closures_flags_auto_start = { + .watcher_flags = G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + .watch_with_closures = TRUE, + .existing_service = FALSE +}; + +static void +stop_service (GDBusConnection *connection, + WatchNameData *data) +{ + GError *error = NULL; + GDBusProxy *proxy = NULL; + GVariant *result = NULL; + GMainContext *main_context = NULL; /* use the global default for now */ + + data->num_vanished = 0; + + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "org.gtk.GDBus.FakeService", + "/org/gtk/GDBus/FakeService", + "org.gtk.GDBus.FakeService", + NULL, + &error); + g_assert_no_error (error); + + result = g_dbus_proxy_call_sync (proxy, + "Quit", + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 100, + NULL, + &error); + g_assert_no_error (error); + g_object_unref (proxy); + if (result) + g_variant_unref (result); + while (data->num_vanished == 0) + g_main_context_iteration (main_context, TRUE); +} + +static void +test_bus_watch_name (gconstpointer d) +{ + WatchNameData data; + OwnNameData own_data; + guint id; + guint owner_id; + GDBusConnection *connection; + const WatchNameTest *watch_name_test; + const gchar *name; + GMainContext *main_context = NULL; /* use the global default for now */ + + watch_name_test = (WatchNameTest *) d; + + if (watch_name_test->existing_service) + { + name = "org.gtk.GDBus.FakeService"; + } + else + { + name = "org.gtk.GDBus.Name1"; + } + + /* + * First check that name_vanished_handler() is invoked if there is no bus. + * + * Also make sure name_vanished_handler() isn't invoked when unwatching the name. + */ + data.num_free_func = 0; + data.num_appeared = 0; + data.num_vanished = 0; + data.expect_null_connection = TRUE; + data.main_context = main_context; + id = g_bus_watch_name (G_BUS_TYPE_SESSION, + name, + watch_name_test->watcher_flags, + name_appeared_handler, + name_vanished_handler, + &data, + (GDestroyNotify) watch_name_data_free_func); + g_assert_cmpint (data.num_appeared, ==, 0); + g_assert_cmpint (data.num_vanished, ==, 0); + + while (data.num_vanished < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_appeared, ==, 0); + g_assert_cmpint (data.num_vanished, ==, 1); + + g_bus_unwatch_name (id); + while (data.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_appeared, ==, 0); + g_assert_cmpint (data.num_vanished, ==, 1); + g_assert_cmpint (data.num_free_func, ==, 1); + data.num_free_func = 0; + + /* + * Now bring up a bus, own a name, and then start watching it. + */ + session_bus_up (); + /* own the name */ + own_data.num_free_func = 0; + own_data.num_acquired = 0; + own_data.num_lost = 0; + data.expect_null_connection = FALSE; + own_data.main_context = main_context; + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + w_bus_acquired_handler, + w_name_acquired_handler, + w_name_lost_handler, + &own_data, + (GDestroyNotify) own_name_data_free_func); + + while (own_data.num_acquired < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (own_data.num_acquired, ==, 1); + g_assert_cmpint (own_data.num_lost, ==, 0); + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert (connection != NULL); + + /* now watch the name */ + data.num_appeared = 0; + data.num_vanished = 0; + if (watch_name_test->watch_with_closures) + { + id = g_bus_watch_name_on_connection_with_closures (connection, + name, + watch_name_test->watcher_flags, + g_cclosure_new (G_CALLBACK (name_appeared_handler), + &data, + NULL), + g_cclosure_new (G_CALLBACK (name_vanished_handler), + &data, + (GClosureNotify) watch_name_data_free_func)); + } + else + { + id = g_bus_watch_name_on_connection (connection, + name, + watch_name_test->watcher_flags, + name_appeared_handler, + name_vanished_handler, + &data, + (GDestroyNotify) watch_name_data_free_func); + } + g_assert_cmpint (data.num_appeared, ==, 0); + g_assert_cmpint (data.num_vanished, ==, 0); + + while (data.num_appeared < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_appeared, ==, 1); + g_assert_cmpint (data.num_vanished, ==, 0); + + /* + * Unwatch the name. + */ + g_bus_unwatch_name (id); + while (data.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_free_func, ==, 1); + + /* unown the name */ + g_bus_unown_name (owner_id); + while (own_data.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (own_data.num_acquired, ==, 1); + g_assert_cmpint (own_data.num_free_func, ==, 1); + own_data.num_free_func = 0; + /* + * Create a watcher and then make a name be owned. + * + * This should trigger name_appeared_handler() ... + */ + /* watch the name */ + data.num_appeared = 0; + data.num_vanished = 0; + data.num_free_func = 0; + if (watch_name_test->watch_with_closures) + { + id = g_bus_watch_name_with_closures (G_BUS_TYPE_SESSION, + name, + watch_name_test->watcher_flags, + g_cclosure_new (G_CALLBACK (name_appeared_handler), + &data, + NULL), + g_cclosure_new (G_CALLBACK (name_vanished_handler), + &data, + (GClosureNotify) watch_name_data_free_func)); + } + else + { + id = g_bus_watch_name (G_BUS_TYPE_SESSION, + name, + watch_name_test->watcher_flags, + name_appeared_handler, + name_vanished_handler, + &data, + (GDestroyNotify) watch_name_data_free_func); + } + + g_assert_cmpint (data.num_appeared, ==, 0); + g_assert_cmpint (data.num_vanished, ==, 0); + + while (data.num_appeared == 0 && data.num_vanished == 0) + g_main_context_iteration (main_context, TRUE); + + if (watch_name_test->existing_service) + { + g_assert_cmpint (data.num_appeared, ==, 1); + g_assert_cmpint (data.num_vanished, ==, 0); + } + else + { + g_assert_cmpint (data.num_appeared, ==, 0); + g_assert_cmpint (data.num_vanished, ==, 1); + } + + if (!watch_name_test->existing_service) + { + /* own the name */ + own_data.num_acquired = 0; + own_data.num_lost = 0; + own_data.expect_null_connection = FALSE; + own_data.main_context = main_context; + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + name, + G_BUS_NAME_OWNER_FLAGS_NONE, + w_bus_acquired_handler, + w_name_acquired_handler, + w_name_lost_handler, + &own_data, + (GDestroyNotify) own_name_data_free_func); + + while (own_data.num_acquired == 0 || data.num_appeared == 0) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (own_data.num_acquired, ==, 1); + g_assert_cmpint (own_data.num_lost, ==, 0); + g_assert_cmpint (data.num_appeared, ==, 1); + g_assert_cmpint (data.num_vanished, ==, 1); + } + + data.expect_null_connection = TRUE; + if (watch_name_test->existing_service) + { + data.expect_null_connection = FALSE; + stop_service (connection, &data); + } + g_object_unref (connection); + /* + * Nuke the bus and check that the name vanishes and is lost. + */ + session_bus_stop (); + if (!watch_name_test->existing_service) + { + while (own_data.num_lost < 1 || data.num_vanished < 2) + g_main_context_iteration (main_context, TRUE); + g_assert_cmpint (own_data.num_lost, ==, 1); + g_assert_cmpint (data.num_vanished, ==, 2); + } + else + { + g_assert_cmpint (own_data.num_lost, ==, 0); + g_assert_cmpint (data.num_vanished, ==, 1); + } + + g_bus_unwatch_name (id); + while (data.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (data.num_free_func, ==, 1); + + if (!watch_name_test->existing_service) + { + g_bus_unown_name (owner_id); + while (own_data.num_free_func < 1) + g_main_context_iteration (main_context, TRUE); + + g_assert_cmpint (own_data.num_free_func, ==, 1); + } + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Called in the same thread as watcher_thread() */ +static void +t_watch_name_data_free_func (WatchNameThreadData *thread_data) +{ + thread_data->data.num_free_func++; + + g_assert_true (g_main_context_is_owner (thread_data->thread_context)); + g_main_context_wakeup (thread_data->thread_context); +} + +/* Called in the same thread as watcher_thread() */ +static void +t_name_appeared_handler (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + WatchNameThreadData *thread_data = user_data; + thread_data->data.num_appeared += 1; + + g_assert_true (g_main_context_is_owner (thread_data->thread_context)); + g_main_context_wakeup (thread_data->thread_context); +} + +/* Called in the same thread as watcher_thread() */ +static void +t_name_vanished_handler (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + WatchNameThreadData *thread_data = user_data; + thread_data->data.num_vanished += 1; + + g_assert_true (g_main_context_is_owner (thread_data->thread_context)); + g_main_context_wakeup (thread_data->thread_context); +} + +/* Called in the thread which constructed the GDBusConnection */ +static void +connection_closed_cb (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + gpointer user_data) +{ + WatchNameThreadData *thread_data = (WatchNameThreadData *) user_data; + if (thread_data->unwatch_early) + { + g_mutex_lock (&thread_data->mutex); + g_bus_unwatch_name (g_atomic_int_get (&thread_data->watch_id)); + g_atomic_int_set (&thread_data->watch_id, 0); + g_cond_signal (&thread_data->cond); + g_mutex_unlock (&thread_data->mutex); + } +} + +static gpointer +watcher_thread (gpointer user_data) +{ + WatchNameThreadData *thread_data = user_data; + GMainContext *thread_context; + + thread_context = g_main_context_new (); + thread_data->thread_context = thread_context; + g_main_context_push_thread_default (thread_context); + + // Notify that the thread has started + g_mutex_lock (&thread_data->cond_mutex); + g_atomic_int_set (&thread_data->started, TRUE); + g_cond_signal (&thread_data->cond); + g_mutex_unlock (&thread_data->cond_mutex); + + // Wait for the main thread to own the name before watching it + g_mutex_lock (&thread_data->cond_mutex); + while (!g_atomic_int_get (&thread_data->name_acquired)) + g_cond_wait (&thread_data->cond, &thread_data->cond_mutex); + g_mutex_unlock (&thread_data->cond_mutex); + + thread_data->data.num_appeared = 0; + thread_data->data.num_vanished = 0; + thread_data->data.num_free_func = 0; + // g_signal_connect_after is important to have default handler be called before our code + g_signal_connect_after (thread_data->connection, "closed", G_CALLBACK (connection_closed_cb), thread_data); + + g_mutex_lock (&thread_data->mutex); + thread_data->watch_id = g_bus_watch_name_on_connection (thread_data->connection, + "org.gtk.GDBus.Name1", + G_BUS_NAME_WATCHER_FLAGS_NONE, + t_name_appeared_handler, + t_name_vanished_handler, + thread_data, + (GDestroyNotify) t_watch_name_data_free_func); + g_mutex_unlock (&thread_data->mutex); + + g_assert_cmpint (thread_data->data.num_appeared, ==, 0); + g_assert_cmpint (thread_data->data.num_vanished, ==, 0); + while (thread_data->data.num_appeared == 0) + g_main_context_iteration (thread_context, TRUE); + g_assert_cmpint (thread_data->data.num_appeared, ==, 1); + g_assert_cmpint (thread_data->data.num_vanished, ==, 0); + thread_data->data.num_appeared = 0; + + /* Close the connection and: + * - check that we had received a vanished event even begin in different thread + * - or check that unwatching the bus when a vanished had been scheduled + * make it correctly unscheduled (unwatch_early condition) + */ + g_dbus_connection_close_sync (thread_data->connection, NULL, NULL); + if (thread_data->unwatch_early) + { + // Wait for the main thread to iterate in order to have close connection handled + g_mutex_lock (&thread_data->mutex); + while (g_atomic_int_get (&thread_data->watch_id) != 0) + g_cond_wait (&thread_data->cond, &thread_data->mutex); + g_mutex_unlock (&thread_data->mutex); + + while (thread_data->data.num_free_func == 0) + g_main_context_iteration (thread_context, TRUE); + g_assert_cmpint (thread_data->data.num_vanished, ==, 0); + g_assert_cmpint (thread_data->data.num_appeared, ==, 0); + g_assert_cmpint (thread_data->data.num_free_func, ==, 1); + } + else + { + while (thread_data->data.num_vanished == 0) + { + /* + * Close of connection is treated in the context of the thread which + * creates the connection. We must run iteration on it (to have the 'closed' + * signal handled) and also run current thread loop to have name_vanished + * callback handled. + */ + g_main_context_iteration (thread_context, TRUE); + } + g_assert_cmpint (thread_data->data.num_vanished, ==, 1); + g_assert_cmpint (thread_data->data.num_appeared, ==, 0); + g_mutex_lock (&thread_data->mutex); + g_bus_unwatch_name (g_atomic_int_get (&thread_data->watch_id)); + g_atomic_int_set (&thread_data->watch_id, 0); + g_mutex_unlock (&thread_data->mutex); + while (thread_data->data.num_free_func == 0) + g_main_context_iteration (thread_context, TRUE); + g_assert_cmpint (thread_data->data.num_free_func, ==, 1); + } + + g_mutex_lock (&thread_data->cond_mutex); + thread_data->ended = TRUE; + g_main_context_wakeup (NULL); + g_cond_signal (&thread_data->cond); + g_mutex_unlock (&thread_data->cond_mutex); + + g_signal_handlers_disconnect_by_func (thread_data->connection, connection_closed_cb, thread_data); + g_object_unref (thread_data->connection); + g_main_context_pop_thread_default (thread_context); + g_main_context_unref (thread_context); + + g_mutex_lock (&thread_data->mutex); + g_assert_cmpint (thread_data->watch_id, ==, 0); + g_mutex_unlock (&thread_data->mutex); + return NULL; +} + +static void +watch_with_different_context (gboolean unwatch_early) +{ + OwnNameData own_data; + WatchNameThreadData thread_data; + GDBusConnection *connection; + GThread *watcher; + guint id; + GMainContext *main_context = NULL; /* use the global default for now */ + + session_bus_up (); + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert (connection != NULL); + + g_mutex_init (&thread_data.mutex); + g_mutex_init (&thread_data.cond_mutex); + g_cond_init (&thread_data.cond); + thread_data.started = FALSE; + thread_data.name_acquired = FALSE; + thread_data.ended = FALSE; + thread_data.connection = g_object_ref (connection); + thread_data.unwatch_early = unwatch_early; + + // Create a thread which will watch a name and wait for it to be ready + g_mutex_lock (&thread_data.cond_mutex); + watcher = g_thread_new ("watcher", watcher_thread, &thread_data); + while (!g_atomic_int_get (&thread_data.started)) + g_cond_wait (&thread_data.cond, &thread_data.cond_mutex); + g_mutex_unlock (&thread_data.cond_mutex); + + own_data.num_acquired = 0; + own_data.num_lost = 0; + own_data.num_free_func = 0; + own_data.expect_null_connection = FALSE; + own_data.main_context = main_context; + // Own the name to avoid direct name vanished in watcher thread + id = g_bus_own_name_on_connection (connection, + "org.gtk.GDBus.Name1", + G_BUS_NAME_OWNER_FLAGS_REPLACE, + w_name_acquired_handler, + w_name_lost_handler, + &own_data, + (GDestroyNotify) own_name_data_free_func); + while (own_data.num_acquired == 0) + g_main_context_iteration (main_context, TRUE); + g_assert_cmpint (own_data.num_acquired, ==, 1); + g_assert_cmpint (own_data.num_lost, ==, 0); + + // Wake the thread for it to begin watch + g_mutex_lock (&thread_data.cond_mutex); + g_atomic_int_set (&thread_data.name_acquired, TRUE); + g_cond_signal (&thread_data.cond); + g_mutex_unlock (&thread_data.cond_mutex); + + // Iterate the loop until thread is waking us up + while (!thread_data.ended) + g_main_context_iteration (main_context, TRUE); + + g_thread_join (watcher); + + g_bus_unown_name (id); + while (own_data.num_free_func == 0) + g_main_context_iteration (main_context, TRUE); + g_assert_cmpint (own_data.num_free_func, ==, 1); + + g_mutex_clear (&thread_data.mutex); + g_mutex_clear (&thread_data.cond_mutex); + g_cond_clear (&thread_data.cond); + + session_bus_stop (); + g_assert_true (g_dbus_connection_is_closed (connection)); + g_object_unref (connection); + session_bus_down (); +} + +static void +test_bus_watch_different_context (void) +{ + watch_with_different_context (FALSE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_bus_unwatch_early (void) +{ + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/604"); + watch_with_different_context (TRUE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_validate_names (void) +{ + guint n; + static const struct + { + gboolean name; + gboolean unique; + gboolean interface; + const gchar *string; + } names[] = { + { 1, 0, 1, "valid.well_known.name"}, + { 1, 0, 0, "valid.well-known.name"}, + { 1, 1, 0, ":valid.unique.name"}, + { 0, 0, 0, "invalid.5well_known.name"}, + { 0, 0, 0, "4invalid.5well_known.name"}, + { 1, 1, 0, ":4valid.5unique.name"}, + { 0, 0, 0, ""}, + { 1, 0, 1, "very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.name1"}, /* 255 */ + { 0, 0, 0, "very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.very.long.name12"}, /* 256 - too long! */ + { 0, 0, 0, ".starts.with.a.dot"}, + { 0, 0, 0, "contains.invalid;.characters"}, + { 0, 0, 0, "contains.inva/lid.characters"}, + { 0, 0, 0, "contains.inva[lid.characters"}, + { 0, 0, 0, "contains.inva]lid.characters"}, + { 0, 0, 0, "contains.inva_æøå_lid.characters"}, + { 1, 1, 0, ":1.1"}, + }; + + for (n = 0; n < G_N_ELEMENTS (names); n++) + { + if (names[n].name) + g_assert (g_dbus_is_name (names[n].string)); + else + g_assert (!g_dbus_is_name (names[n].string)); + + if (names[n].unique) + g_assert (g_dbus_is_unique_name (names[n].string)); + else + g_assert (!g_dbus_is_unique_name (names[n].string)); + + if (names[n].interface) + { + g_assert (g_dbus_is_interface_name (names[n].string)); + g_assert (g_dbus_is_error_name (names[n].string)); + } + else + { + g_assert (!g_dbus_is_interface_name (names[n].string)); + g_assert (!g_dbus_is_error_name (names[n].string)); + } + } +} + +static void +assert_cmp_escaped_object_path (const gchar *s, + const gchar *correct_escaped) +{ + gchar *escaped; + guint8 *unescaped; + + escaped = g_dbus_escape_object_path (s); + g_assert_cmpstr (escaped, ==, correct_escaped); + + g_free (escaped); + escaped = g_dbus_escape_object_path_bytestring ((const guint8 *) s); + g_assert_cmpstr (escaped, ==, correct_escaped); + + unescaped = g_dbus_unescape_object_path (escaped); + g_assert_cmpstr ((const gchar *) unescaped, ==, s); + + g_free (escaped); + g_free (unescaped); +} + +static void +test_escape_object_path (void) +{ + assert_cmp_escaped_object_path ("Foo42", "Foo42"); + assert_cmp_escaped_object_path ("foo.bar.baz", "foo_2ebar_2ebaz"); + assert_cmp_escaped_object_path ("foo_bar_baz", "foo_5fbar_5fbaz"); + assert_cmp_escaped_object_path ("_", "_5f"); + assert_cmp_escaped_object_path ("__", "_5f_5f"); + assert_cmp_escaped_object_path ("", "_"); + assert_cmp_escaped_object_path (":1.42", "_3a1_2e42"); + assert_cmp_escaped_object_path ("a/b", "a_2fb"); + assert_cmp_escaped_object_path (" ", "_20"); + assert_cmp_escaped_object_path ("\n", "_0a"); + + g_assert_null (g_dbus_unescape_object_path ("_ii")); + g_assert_null (g_dbus_unescape_object_path ("döner")); + g_assert_null (g_dbus_unescape_object_path ("_00")); + g_assert_null (g_dbus_unescape_object_path ("_61")); + g_assert_null (g_dbus_unescape_object_path ("_ga")); + g_assert_null (g_dbus_unescape_object_path ("_ag")); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, NULL); + + g_test_dbus_unset (); + + g_test_add_func ("/gdbus/validate-names", test_validate_names); + g_test_add_func ("/gdbus/bus-own-name", test_bus_own_name); + g_test_add_data_func ("/gdbus/bus-watch-name", + &watch_no_closures_no_flags, + test_bus_watch_name); + g_test_add_data_func ("/gdbus/bus-watch-name-auto-start", + &watch_no_closures_flags_auto_start, + test_bus_watch_name); + g_test_add_data_func ("/gdbus/bus-watch-name-auto-start-service-exist", + &watch_no_closures_flags_auto_start_service_exist, + test_bus_watch_name); + g_test_add_data_func ("/gdbus/bus-watch-name-closures", + &watch_closures_no_flags, + test_bus_watch_name); + g_test_add_data_func ("/gdbus/bus-watch-name-closures-auto-start", + &watch_closures_flags_auto_start, + test_bus_watch_name); + g_test_add_func ("/gdbus/bus-watch-different-context", test_bus_watch_different_context); + g_test_add_func ("/gdbus/bus-unwatch-early", test_bus_unwatch_early); + g_test_add_func ("/gdbus/escape-object-path", test_escape_object_path); + ret = g_test_run(); + + return ret; +} diff --git a/gio/tests/gdbus-non-socket.c b/gio/tests/gdbus-non-socket.c new file mode 100644 index 0000000..7ddb55b --- /dev/null +++ b/gio/tests/gdbus-non-socket.c @@ -0,0 +1,303 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include + +#ifdef G_OS_UNIX +#include +#include +#include +#endif + +#include "gdbus-tests.h" + +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ +#ifdef G_OS_UNIX + +#include "test-pipe-unix.h" +#include "test-io-stream.h" + +/* ---------------------------------------------------------------------------------------------------- */ + +static const GDBusArgInfo pokee_method_poke_out_arg0 = { + -1, /* ref_count */ + "result", + "s", + NULL /* annotations */ +}; + +static const GDBusArgInfo *pokee_method_poke_out_args[2] = { + &pokee_method_poke_out_arg0, + NULL, +}; + +static const GDBusArgInfo pokee_method_poke_in_arg0 = { + -1, /* ref_count */ + "value", + "s", + NULL /* annotations */ +}; + +static const GDBusArgInfo *pokee_method_poke_in_args[2] = { + &pokee_method_poke_in_arg0, + NULL, +}; + +static const GDBusMethodInfo pokee_method_poke = { + -1, /* ref_count */ + "Poke", + (GDBusArgInfo**) pokee_method_poke_in_args, + (GDBusArgInfo**) pokee_method_poke_out_args, + NULL /* annotations */ +}; + +static const GDBusMethodInfo *pokee_methods[2] = { + &pokee_method_poke, + NULL +}; + +static const GDBusInterfaceInfo pokee_object_info = { + -1, /* ref_count */ + "org.gtk.GDBus.Pokee", + (GDBusMethodInfo**) pokee_methods, + NULL, /* signals */ + NULL, /* properties */ + NULL /* annotations */ +}; + +static void +pokee_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + const gchar *str; + gchar *ret; + + g_assert_cmpstr (method_name, ==, "Poke"); + + g_variant_get (parameters, "(&s)", &str); + ret = g_strdup_printf ("You poked me with: '%s'", str); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", ret)); + g_free (ret); +} + +static const GDBusInterfaceVTable pokee_vtable = { + pokee_method_call, + NULL, /* get_property */ + NULL, /* set_property */ + { 0 } +}; + +/* Processes: + * + * parent + * \- first child (via fork()) is the pokee + * \- second child (via g_test_trap_fork()) is the poker + * + * The second child only exists to avoid sharing a main context between several + * second-children if we run a test resembling this one multiple times. + * See https://bugzilla.gnome.org/show_bug.cgi?id=658999 for why that's bad. + */ +static void +test_non_socket (void) +{ + GIOStream *streams[2]; + GDBusConnection *connection; + GError *error; + gchar *guid; + pid_t first_child; + GVariant *ret; + const gchar *str; + gboolean ok; + + error = NULL; + + ok = test_bidi_pipe (&streams[0], &streams[1], &error); + g_assert_no_error (error); + g_assert (ok); + g_assert (G_IS_IO_STREAM (streams[0])); + g_assert (G_IS_INPUT_STREAM (g_io_stream_get_input_stream (streams[0]))); + g_assert (G_IS_OUTPUT_STREAM (g_io_stream_get_output_stream (streams[0]))); + g_assert (G_IS_IO_STREAM (streams[1])); + g_assert (G_IS_INPUT_STREAM (g_io_stream_get_input_stream (streams[1]))); + g_assert (G_IS_OUTPUT_STREAM (g_io_stream_get_output_stream (streams[1]))); + + switch ((first_child = fork ())) + { + case -1: + g_assert_not_reached (); + break; + + case 0: + /* first child */ + + /* we shouldn't do this in the parent, because we shouldn't use a + * GMainContext both before and after fork + */ + loop = g_main_loop_new (NULL, FALSE); + + ok = g_io_stream_close (streams[1], NULL, &error); + g_assert_no_error (error); + g_assert (ok); + g_object_unref (streams[1]); + + guid = g_dbus_generate_guid (); + error = NULL; + /* We need to delay message processing to avoid the race + * described in + * + * https://bugzilla.gnome.org/show_bug.cgi?id=627188 + * + * This is because (early) dispatching is done on the IO thread + * (method_call() isn't called until we're in the right thread + * though) so in rare cases the parent sends the message before + * we (the first child) register the object + */ + connection = g_dbus_connection_new_sync (streams[0], + guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | + G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, + NULL, /* GDBusAuthObserver */ + NULL, + &error); + g_free (guid); + g_assert_no_error (error); + g_object_unref (streams[0]); + + /* make sure we exit along with the parent */ + g_dbus_connection_set_exit_on_close (connection, TRUE); + + error = NULL; + g_dbus_connection_register_object (connection, + "/pokee", + (GDBusInterfaceInfo *) &pokee_object_info, + &pokee_vtable, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + &error); + g_assert_no_error (error); + + /* and now start message processing */ + g_dbus_connection_start_message_processing (connection); + + g_main_loop_run (loop); + + g_assert_not_reached (); + break; + + default: + /* parent continues below */ + break; + } + + /* This is #ifdef G_OS_UNIX anyway, so just use g_test_trap_fork() */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + if (!g_test_trap_fork (0, 0)) + { + /* parent */ + g_object_unref (streams[0]); + g_object_unref (streams[1]); + + g_test_trap_assert_passed (); + g_assert_cmpint (kill (first_child, SIGTERM), ==, 0); + return; + } + G_GNUC_END_IGNORE_DEPRECATIONS; + + /* second child */ + + /* we shouldn't do this in the parent, because we shouldn't use a + * GMainContext both before and after fork + */ + loop = g_main_loop_new (NULL, FALSE); + + ok = g_io_stream_close (streams[0], NULL, &error); + g_assert_no_error (error); + g_assert (ok); + g_object_unref (streams[0]); + + connection = g_dbus_connection_new_sync (streams[1], + NULL, /* guid */ + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, + &error); + g_assert_no_error (error); + g_object_unref (streams[1]); + + /* poke the first child */ + error = NULL; + ret = g_dbus_connection_call_sync (connection, + NULL, /* name */ + "/pokee", + "org.gtk.GDBus.Pokee", + "Poke", + g_variant_new ("(s)", "I am the POKER!"), + G_VARIANT_TYPE ("(s)"), /* return type */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_variant_get (ret, "(&s)", &str); + g_assert_cmpstr (str, ==, "You poked me with: 'I am the POKER!'"); + g_variant_unref (ret); + + g_object_unref (connection); + g_main_loop_unref (loop); + exit (0); +} + +#else /* G_OS_UNIX */ + +static void +test_non_socket (void) +{ + /* TODO: test this with e.g. GWin32InputStream/GWin32OutputStream */ +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add_func ("/gdbus/non-socket", test_non_socket); + + ret = g_test_run(); + + return ret; +} diff --git a/gio/tests/gdbus-object-manager-example/gdbus-example-objectmanager.xml b/gio/tests/gdbus-object-manager-example/gdbus-example-objectmanager.xml new file mode 100644 index 0000000..472b257 --- /dev/null +++ b/gio/tests/gdbus-object-manager-example/gdbus-example-objectmanager.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gio/tests/gdbus-object-manager-example/meson.build b/gio/tests/gdbus-object-manager-example/meson.build new file mode 100644 index 0000000..ce0335e --- /dev/null +++ b/gio/tests/gdbus-object-manager-example/meson.build @@ -0,0 +1,49 @@ +# FIXME: set UNINSTALLED_GLIB_{SRC|BUILD}DIR=top_{src|build}dir ? +gdbus_example_objectmanager_xml = files('gdbus-example-objectmanager.xml') +gdbus_example_objectmanager_generated = custom_target('objectmanager-gen', + input : gdbus_example_objectmanager_xml, + output : ['objectmanager-gen.h', + 'objectmanager-gen.c', + 'objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Animal.xml', + 'objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Cat.xml'], + command : [python, gdbus_codegen, + '--interface-prefix', 'org.gtk.GDBus.Example.ObjectManager.', + '--c-namespace', 'Example', + '--c-generate-object-manager', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'objectmanager-gen', + '--generate-docbook', 'objectmanager-gen', + '--symbol-decorator', '_GLIB_EXTERN', + '--symbol-decorator-define', 'HAVE_CONFIG_H', + '@INPUT@']) + +gdbus_example_objectmanager_rst_gen = custom_target('objectmanager-rst-gen', + input: gdbus_example_objectmanager_xml, + output: [ + 'objectmanager-rst-gen-org.gtk.GDBus.Example.ObjectManager.Animal.rst', + 'objectmanager-rst-gen-org.gtk.GDBus.Example.ObjectManager.Cat.rst', + ], + command: [ + python, + gdbus_codegen, + '--interface-prefix', 'org.gtk.GDBus.Example.ObjectManager.', + '--generate-rst', 'objectmanager-rst-gen', + '--output-directory', '@OUTDIR@', + '@INPUT@', + ], +) + +libgdbus_example_objectmanager = library('gdbus-example-objectmanager', + gdbus_example_objectmanager_generated, + c_args : test_c_args, + dependencies : [libglib_dep, libgmodule_dep, libgobject_dep, libgio_dep], + install : installed_tests_enabled, + install_dir : installed_tests_execdir) + +libgdbus_example_objectmanager_dep = declare_dependency( + sources : [ + gdbus_example_objectmanager_generated[0], + gdbus_example_objectmanager_rst_gen[0], + ], + link_with : libgdbus_example_objectmanager, + dependencies : [libgio_dep]) diff --git a/gio/tests/gdbus-overflow.c b/gio/tests/gdbus-overflow.c new file mode 100644 index 0000000..d3e1eb2 --- /dev/null +++ b/gio/tests/gdbus-overflow.c @@ -0,0 +1,250 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include +#include + +/* for open(2) */ +#include +#include +#include +#include + +/* for g_unlink() */ +#include + +#include +#include +#include + +/* used in test_overflow */ +#ifdef G_OS_UNIX +#include +#include +#endif + +#ifdef G_OS_UNIX +static gboolean is_unix = TRUE; +#else +static gboolean is_unix = FALSE; +#endif + +static gchar *tmp_address = NULL; +static gchar *test_guid = NULL; +static GMainLoop *loop = NULL; + +static const gchar *test_interface_introspection_xml = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; +static GDBusInterfaceInfo *test_interface_introspection_data = NULL; + + +#ifdef G_OS_UNIX + +/* Chosen to be big enough to overflow the socket buffer */ +#define OVERFLOW_NUM_SIGNALS 5000 +#define OVERFLOW_TIMEOUT_SEC 10 + +static GDBusMessage * +overflow_filter_func (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data) +{ + gint *counter = user_data; /* (atomic) */ + g_atomic_int_inc (counter); + return message; +} + +static gboolean +overflow_on_500ms_later_func (gpointer user_data) +{ + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; +} + +static void +test_overflow (void) +{ + gint sv[2]; + gint n; + GSocket *socket; + GSocketConnection *socket_connection; + GDBusConnection *producer, *consumer; + GError *error; + GTimer *timer; + gint n_messages_received; /* (atomic) */ + gint n_messages_sent; /* (atomic) */ + + g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0); + + error = NULL; + socket = g_socket_new_from_fd (sv[0], &error); + g_assert_no_error (error); + socket_connection = g_socket_connection_factory_create_connection (socket); + g_assert (socket_connection != NULL); + g_object_unref (socket); + producer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), + NULL, /* guid */ + G_DBUS_CONNECTION_FLAGS_NONE, + NULL, /* GDBusAuthObserver */ + NULL, /* GCancellable */ + + &error); + g_dbus_connection_set_exit_on_close (producer, TRUE); + g_assert_no_error (error); + g_object_unref (socket_connection); + g_atomic_int_set (&n_messages_sent, 0); + g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL); + + /* send enough data that we get an EAGAIN */ + for (n = 0; n < OVERFLOW_NUM_SIGNALS; n++) + { + error = NULL; + g_dbus_connection_emit_signal (producer, + NULL, /* destination */ + "/org/foo/Object", + "org.foo.Interface", + "Member", + g_variant_new ("(s)", "a string"), + &error); + g_assert_no_error (error); + } + + /* sleep for 0.5 sec (to allow the GDBus IO thread to fill up the + * kernel buffers) and verify that n_messages_sent < + * OVERFLOW_NUM_SIGNALS + * + * This is to verify that not all the submitted messages have been + * sent to the underlying transport. + */ + g_timeout_add (500, overflow_on_500ms_later_func, NULL); + g_main_loop_run (loop); + g_assert_cmpint (g_atomic_int_get (&n_messages_sent), <, OVERFLOW_NUM_SIGNALS); + + /* now suck it all out as a client, and add it up */ + socket = g_socket_new_from_fd (sv[1], &error); + g_assert_no_error (error); + socket_connection = g_socket_connection_factory_create_connection (socket); + g_assert (socket_connection != NULL); + g_object_unref (socket); + consumer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), + NULL, /* guid */ + G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, + NULL, /* GDBusAuthObserver */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_object_unref (socket_connection); + g_atomic_int_set (&n_messages_received, 0); + g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL); + g_dbus_connection_start_message_processing (consumer); + + timer = g_timer_new (); + g_timer_start (timer); + + while (g_atomic_int_get (&n_messages_received) < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) + g_main_context_iteration (NULL, FALSE); + + g_assert_cmpint (g_atomic_int_get (&n_messages_sent), ==, OVERFLOW_NUM_SIGNALS); + g_assert_cmpint (g_atomic_int_get (&n_messages_received), ==, OVERFLOW_NUM_SIGNALS); + + g_timer_destroy (timer); + g_object_unref (consumer); + g_object_unref (producer); +} +#else +static void +test_overflow (void) +{ + /* TODO: test this with e.g. GWin32InputStream/GWin32OutputStream */ +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + + +int +main (int argc, + char *argv[]) +{ + gint ret; + GDBusNodeInfo *introspection_data = NULL; + gchar *tmpdir = NULL; + + g_test_init (&argc, &argv, NULL); + + introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL); + g_assert (introspection_data != NULL); + test_interface_introspection_data = introspection_data->interfaces[0]; + + test_guid = g_dbus_generate_guid (); + + if (is_unix) + { + if (g_unix_socket_address_abstract_names_supported ()) + tmp_address = g_strdup ("unix:tmpdir=/tmp/gdbus-test-"); + else + { + tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); + tmp_address = g_strdup_printf ("unix:tmpdir=%s", tmpdir); + } + } + else + tmp_address = g_strdup ("nonce-tcp:"); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_add_func ("/gdbus/overflow", test_overflow); + + ret = g_test_run(); + + g_main_loop_unref (loop); + g_free (test_guid); + g_dbus_node_info_unref (introspection_data); + if (is_unix) + g_free (tmp_address); + if (tmpdir) + { + g_rmdir (tmpdir); + g_free (tmpdir); + } + + return ret; +} diff --git a/gio/tests/gdbus-peer-object-manager.c b/gio/tests/gdbus-peer-object-manager.c new file mode 100644 index 0000000..f101b46 --- /dev/null +++ b/gio/tests/gdbus-peer-object-manager.c @@ -0,0 +1,386 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2012 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#include "config.h" + +#include + +#include + +#include +#include +#include + +typedef struct { + GDBusInterfaceSkeleton parent; + gint number; +} MockInterface; + +typedef struct { + GDBusInterfaceSkeletonClass parent_class; +} MockInterfaceClass; + +static GType mock_interface_get_type (void); +G_DEFINE_TYPE (MockInterface, mock_interface, G_TYPE_DBUS_INTERFACE_SKELETON) + +static void +mock_interface_init (MockInterface *self) +{ + +} + +static GDBusInterfaceInfo * +mock_interface_get_info (GDBusInterfaceSkeleton *skeleton) +{ + static GDBusPropertyInfo path_info = { + -1, + "Path", + "o", + G_DBUS_PROPERTY_INFO_FLAGS_READABLE, + NULL, + }; + + static GDBusPropertyInfo number_info = { + -1, + "Number", + "i", + G_DBUS_PROPERTY_INFO_FLAGS_READABLE, + NULL, + }; + + static GDBusPropertyInfo *property_info[] = { + &path_info, + &number_info, + NULL + }; + + static GDBusInterfaceInfo interface_info = { + -1, + (gchar *) "org.mock.Interface", + NULL, + NULL, + (GDBusPropertyInfo **) &property_info, + NULL + }; + + return &interface_info; +} + +static GVariant * +mock_interface_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + MockInterface *self = user_data; + if (g_str_equal (property_name, "Path")) + return g_variant_new_object_path (object_path); + else if (g_str_equal (property_name, "Number")) + return g_variant_new_int32 (self->number); + else + return NULL; +} + +static GDBusInterfaceVTable * +mock_interface_get_vtable (GDBusInterfaceSkeleton *interface) +{ + static GDBusInterfaceVTable vtable = { + NULL, + mock_interface_get_property, + NULL, + { 0 } + }; + + return &vtable; +} + +static GVariant * +mock_interface_get_properties (GDBusInterfaceSkeleton *interface) +{ + GVariantBuilder builder; + GDBusInterfaceInfo *info; + GDBusInterfaceVTable *vtable; + guint n; + + /* Groan, this is completely generic code and should be in gdbus */ + + info = g_dbus_interface_skeleton_get_info (interface); + vtable = g_dbus_interface_skeleton_get_vtable (interface); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + for (n = 0; info->properties[n] != NULL; n++) + { + if (info->properties[n]->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE) + { + GVariant *value; + g_return_val_if_fail (vtable->get_property != NULL, NULL); + value = (vtable->get_property) (g_dbus_interface_skeleton_get_connection (interface), NULL, + g_dbus_interface_skeleton_get_object_path (interface), + info->name, info->properties[n]->name, + NULL, interface); + if (value != NULL) + { + g_variant_take_ref (value); + g_variant_builder_add (&builder, "{sv}", info->properties[n]->name, value); + g_variant_unref (value); + } + } + } + + return g_variant_builder_end (&builder); +} + +static void +mock_interface_flush (GDBusInterfaceSkeleton *skeleton) +{ + +} + +static void +mock_interface_class_init (MockInterfaceClass *klass) +{ + GDBusInterfaceSkeletonClass *skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass); + skeleton_class->get_info = mock_interface_get_info; + skeleton_class->get_properties = mock_interface_get_properties; + skeleton_class->flush = mock_interface_flush; + skeleton_class->get_vtable = mock_interface_get_vtable; +} +typedef struct { + GDBusConnection *server; + GDBusConnection *client; + GMainLoop *loop; + GAsyncResult *result; +} Test; + +static void +on_server_connection (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + Test *test = user_data; + GError *error = NULL; + + g_assert (test->server == NULL); + test->server = g_dbus_connection_new_finish (result, &error); + g_assert_no_error (error); + g_assert (test->server != NULL); + + if (test->server && test->client) + g_main_loop_quit (test->loop); +} + +static void +on_client_connection (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + Test *test = user_data; + GError *error = NULL; + + g_assert (test->client == NULL); + test->client = g_dbus_connection_new_finish (result, &error); + g_assert_no_error (error); + g_assert (test->client != NULL); + + if (test->server && test->client) + g_main_loop_quit (test->loop); +} + +static void +setup (Test *test, + gconstpointer unused) +{ + GError *error = NULL; + GSocket *socket; + GSocketConnection *stream; + gchar *guid; + int pair[2]; + + test->loop = g_main_loop_new (NULL, FALSE); + + if (socketpair (AF_UNIX, SOCK_STREAM, 0, pair) < 0) + { + int errsv = errno; + g_set_error (&error, G_IO_ERROR, g_io_error_from_errno (errsv), + "%s", g_strerror (errsv)); + g_assert_no_error (error); + } + + /* Build up the server stuff */ + socket = g_socket_new_from_fd (pair[1], &error); + g_assert_no_error (error); + + stream = g_socket_connection_factory_create_connection (socket); + g_assert (stream != NULL); + g_object_unref (socket); + + guid = g_dbus_generate_guid (); + g_dbus_connection_new (G_IO_STREAM (stream), guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS, + NULL, NULL, on_server_connection, test); + g_object_unref (stream); + g_free (guid); + + /* Build up the client stuff */ + socket = g_socket_new_from_fd (pair[0], &error); + g_assert_no_error (error); + + stream = g_socket_connection_factory_create_connection (socket); + g_assert (stream != NULL); + g_object_unref (socket); + + g_dbus_connection_new (G_IO_STREAM (stream), NULL, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS, + NULL, NULL, on_client_connection, test); + + g_main_loop_run (test->loop); + + g_assert (test->server); + g_assert (test->client); + + g_object_unref (stream); +} + +static void +teardown (Test *test, + gconstpointer unused) +{ + g_clear_object (&test->client); + g_clear_object (&test->server); + g_main_loop_unref (test->loop); +} + +static void +on_result (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + Test *test = user_data; + g_assert (test->result == NULL); + test->result = g_object_ref (result); + g_main_loop_quit (test->loop); + +} + +static void +test_object_manager (Test *test, + gconstpointer test_data) +{ + GDBusObjectManager *client; + GDBusObjectManagerServer *server; + MockInterface *mock; + GDBusObjectSkeleton *skeleton; + const gchar *dbus_name; + GError *error = NULL; + GDBusInterface *proxy; + GVariant *prop; + const gchar *object_path = test_data; + gchar *number1_path = NULL, *number2_path = NULL; + + if (g_strcmp0 (object_path, "/") == 0) + { + number1_path = g_strdup ("/number_1"); + number2_path = g_strdup ("/number_2"); + } + else + { + number1_path = g_strdup_printf ("%s/number_1", object_path); + number2_path = g_strdup_printf ("%s/number_2", object_path); + } + + server = g_dbus_object_manager_server_new (object_path); + + mock = g_object_new (mock_interface_get_type (), NULL); + mock->number = 1; + skeleton = g_dbus_object_skeleton_new (number1_path); + g_dbus_object_skeleton_add_interface (skeleton, G_DBUS_INTERFACE_SKELETON (mock)); + g_dbus_object_manager_server_export (server, skeleton); + + mock = g_object_new (mock_interface_get_type (), NULL); + mock->number = 2; + skeleton = g_dbus_object_skeleton_new (number2_path); + g_dbus_object_skeleton_add_interface (skeleton, G_DBUS_INTERFACE_SKELETON (mock)); + g_dbus_object_manager_server_export (server, skeleton); + + g_dbus_object_manager_server_set_connection (server, test->server); + + dbus_name = NULL; + + g_dbus_object_manager_client_new (test->client, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, + dbus_name, object_path, NULL, NULL, NULL, NULL, on_result, test); + + g_main_loop_run (test->loop); + client = g_dbus_object_manager_client_new_finish (test->result, &error); + g_assert_no_error (error); + g_clear_object (&test->result); + + proxy = g_dbus_object_manager_get_interface (client, number1_path, "org.mock.Interface"); + g_assert (proxy != NULL); + prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Path"); + g_assert (prop != NULL); + g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_OBJECT_PATH); + g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, number1_path); + g_variant_unref (prop); + prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Number"); + g_assert (prop != NULL); + g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_INT32); + g_assert_cmpint (g_variant_get_int32 (prop), ==, 1); + g_variant_unref (prop); + g_object_unref (proxy); + + proxy = g_dbus_object_manager_get_interface (client, number2_path, "org.mock.Interface"); + g_assert (proxy != NULL); + prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Path"); + g_assert (prop != NULL); + g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_OBJECT_PATH); + g_assert_cmpstr (g_variant_get_string (prop, NULL), ==, number2_path); + g_variant_unref (prop); + prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Number"); + g_assert (prop != NULL); + g_assert_cmpstr ((gchar *)g_variant_get_type (prop), ==, (gchar *)G_VARIANT_TYPE_INT32); + g_assert_cmpint (g_variant_get_int32 (prop), ==, 2); + g_variant_unref (prop); + g_object_unref (proxy); + + g_object_unref (server); + g_object_unref (client); + + g_free (number2_path); + g_free (number1_path); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add ("/gdbus/peer-object-manager/normal", Test, "/objects", + setup, test_object_manager, teardown); + g_test_add ("/gdbus/peer-object-manager/root", Test, "/", + setup, test_object_manager, teardown); + + return g_test_run(); +} diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c new file mode 100644 index 0000000..2f2caf7 --- /dev/null +++ b/gio/tests/gdbus-peer.c @@ -0,0 +1,2215 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include +#include + +/* for open(2) */ +#include +#include +#include +#include + +/* for g_unlink() */ +#include + +#include +#include +#include +#include + +#ifdef G_OS_UNIX +#include +#include +#endif + +#include "gdbus-tests.h" + +#include "gdbus-object-manager-example/objectmanager-gen.h" + +#ifdef G_OS_UNIX +static gboolean is_unix = TRUE; +#else +static gboolean is_unix = FALSE; +#endif + +static gchar *tmpdir = NULL; +static gchar *tmp_address = NULL; +static gchar *test_guid = NULL; +static GMutex service_loop_lock; +static GCond service_loop_cond; +static GMainLoop *service_loop = NULL; +static GDBusServer *server = NULL; +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that peer-to-peer connections work */ +/* ---------------------------------------------------------------------------------------------------- */ + + +typedef struct +{ + gboolean accept_connection; + gint num_connection_attempts; + GPtrArray *current_connections; + guint num_method_calls; + gboolean signal_received; +} PeerData; + +/* This needs to be enough to usually take more than one write(), + * to reproduce + * . + * 1 MiB ought to be enough. */ +#define BIG_MESSAGE_ARRAY_SIZE (1024 * 1024) + +static const gchar *test_interface_introspection_xml = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; +static GDBusInterfaceInfo *test_interface_introspection_data = NULL; + +static void +test_interface_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + PeerData *data = user_data; + const GDBusMethodInfo *info; + + data->num_method_calls++; + + g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject"); + g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface"); + + info = g_dbus_method_invocation_get_method_info (invocation); + g_assert_cmpstr (info->name, ==, method_name); + + if (g_strcmp0 (method_name, "HelloPeer") == 0) + { + const gchar *greeting; + gchar *response; + + g_variant_get (parameters, "(&s)", &greeting); + + response = g_strdup_printf ("You greeted me with '%s'.", + greeting); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", response)); + g_free (response); + } + else if (g_strcmp0 (method_name, "EmitSignal") == 0) + { + GError *error; + + error = NULL; + g_dbus_connection_emit_signal (connection, + NULL, + "/org/gtk/GDBus/PeerTestObject", + "org.gtk.GDBus.PeerTestInterface", + "PeerSignal", + NULL, + &error); + g_assert_no_error (error); + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_strcmp0 (method_name, "EmitSignalWithNameSet") == 0) + { + GError *error; + gboolean ret; + GDBusMessage *message; + + message = g_dbus_message_new_signal ("/org/gtk/GDBus/PeerTestObject", + "org.gtk.GDBus.PeerTestInterface", + "PeerSignalWithNameSet"); + g_dbus_message_set_sender (message, ":1.42"); + + error = NULL; + ret = g_dbus_connection_send_message (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error); + g_assert_no_error (error); + g_assert (ret); + g_object_unref (message); + + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_strcmp0 (method_name, "OpenFile") == 0 || + g_strcmp0 (method_name, "OpenFileWithBigMessage") == 0) + { +#ifdef G_OS_UNIX + const gchar *path; + GDBusMessage *reply; + GError *error; + gint fd; + GUnixFDList *fd_list; + + g_variant_get (parameters, "(&s)", &path); + + fd_list = g_unix_fd_list_new (); + + error = NULL; + + fd = g_open (path, O_RDONLY, 0); + g_assert (fd != -1); + g_unix_fd_list_append (fd_list, fd, &error); + g_assert_no_error (error); + close (fd); + + reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_dbus_message_set_unix_fd_list (reply, fd_list); + g_object_unref (fd_list); + g_object_unref (invocation); + + if (g_strcmp0 (method_name, "OpenFileWithBigMessage") == 0) + { + char *junk; + + junk = g_new0 (char, BIG_MESSAGE_ARRAY_SIZE); + g_dbus_message_set_body (reply, + g_variant_new ("(h@ay)", + 0, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + junk, + BIG_MESSAGE_ARRAY_SIZE, + 1))); + g_free (junk); + } + + error = NULL; + g_dbus_connection_send_message (connection, + reply, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + NULL, /* out_serial */ + &error); + g_assert_no_error (error); + g_object_unref (reply); +#else + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.NotOnUnix", + "Your OS does not support file descriptor passing"); +#endif + } + else + { + g_assert_not_reached (); + } +} + +static GVariant * +test_interface_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + g_assert_cmpstr (object_path, ==, "/org/gtk/GDBus/PeerTestObject"); + g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.PeerTestInterface"); + g_assert_cmpstr (property_name, ==, "PeerProperty"); + + return g_variant_new_string ("ThePropertyValue"); +} + + +static const GDBusInterfaceVTable test_interface_vtable = +{ + test_interface_method_call, + test_interface_get_property, + NULL, /* set_property */ + { 0 } +}; + +static void +on_proxy_signal_received (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + PeerData *data = user_data; + + data->signal_received = TRUE; + + g_assert (sender_name == NULL); + g_assert_cmpstr (signal_name, ==, "PeerSignal"); + g_main_loop_quit (loop); +} + +static void +on_proxy_signal_received_with_name_set (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + PeerData *data = user_data; + + data->signal_received = TRUE; + + g_assert_cmpstr (sender_name, ==, ":1.42"); + g_assert_cmpstr (signal_name, ==, "PeerSignalWithNameSet"); + g_main_loop_quit (loop); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +setup_test_address (void) +{ + if (is_unix) + { + g_test_message ("Testing with unix:dir address"); + tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); + tmp_address = g_strdup_printf ("unix:dir=%s", tmpdir); + } + else + tmp_address = g_strdup ("nonce-tcp:host=127.0.0.1"); +} + +#ifdef G_OS_UNIX +static void +setup_tmpdir_test_address (void) +{ + g_test_message ("Testing with unix:tmpdir address"); + tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); + tmp_address = g_strdup_printf ("unix:tmpdir=%s", tmpdir); +} + +static void +setup_path_test_address (void) +{ + g_test_message ("Testing with unix:path address"); + tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); + tmp_address = g_strdup_printf ("unix:path=%s/gdbus-peer-socket", tmpdir); +} +#endif + +static void +teardown_test_address (void) +{ + g_free (tmp_address); + if (tmpdir) + { + /* Ensuring the rmdir succeeds also ensures any sockets created on the + * filesystem are also deleted. + */ + g_assert_cmpstr (g_rmdir (tmpdir) == 0 ? "OK" : g_strerror (errno), + ==, "OK"); + g_clear_pointer (&tmpdir, g_free); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +on_authorize_authenticated_peer (GDBusAuthObserver *observer, + GIOStream *stream, + GCredentials *credentials, + gpointer user_data) +{ + PeerData *data = user_data; + gboolean authorized; + + data->num_connection_attempts++; + + authorized = TRUE; + if (!data->accept_connection) + { + authorized = FALSE; + g_main_loop_quit (loop); + } + + return authorized; +} + +/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */ +static gboolean +on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + PeerData *data = user_data; + GError *error = NULL; + guint reg_id; + + //g_printerr ("Client connected.\n" + // "Negotiated capabilities: unix-fd-passing=%d\n", + // g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); + + g_ptr_array_add (data->current_connections, g_object_ref (connection)); + +#if G_CREDENTIALS_SUPPORTED + { + GCredentials *credentials; + + credentials = g_dbus_connection_get_peer_credentials (connection); + + g_assert (credentials != NULL); + g_assert_cmpuint (g_credentials_get_unix_user (credentials, NULL), ==, + getuid ()); +#if G_CREDENTIALS_HAS_PID + g_assert_cmpint (g_credentials_get_unix_pid (credentials, &error), ==, + getpid ()); + g_assert_no_error (error); +#else + g_assert_cmpint (g_credentials_get_unix_pid (credentials, &error), ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); +#endif + } +#endif + + /* export object on the newly established connection */ + reg_id = g_dbus_connection_register_object (connection, + "/org/gtk/GDBus/PeerTestObject", + test_interface_introspection_data, + &test_interface_vtable, + data, + NULL, /* GDestroyNotify for data */ + &error); + g_assert_no_error (error); + g_assert (reg_id > 0); + + g_main_loop_quit (loop); + + return TRUE; +} + +/* We don't tell the main thread about the new GDBusServer until it has + * had a chance to start listening. */ +static gboolean +idle_in_service_loop (gpointer loop) +{ + g_assert (service_loop == NULL); + g_mutex_lock (&service_loop_lock); + service_loop = loop; + g_cond_broadcast (&service_loop_cond); + g_mutex_unlock (&service_loop_lock); + + return G_SOURCE_REMOVE; +} + +static void +run_service_loop (GMainContext *service_context) +{ + GMainLoop *loop; + GSource *source; + + g_assert (service_loop == NULL); + + loop = g_main_loop_new (service_context, FALSE); + source = g_idle_source_new (); + g_source_set_callback (source, idle_in_service_loop, loop, NULL); + g_source_attach (source, service_context); + g_source_unref (source); + g_main_loop_run (loop); +} + +static void +teardown_service_loop (void) +{ + g_mutex_lock (&service_loop_lock); + g_clear_pointer (&service_loop, g_main_loop_unref); + g_mutex_unlock (&service_loop_lock); +} + +static void +await_service_loop (void) +{ + g_mutex_lock (&service_loop_lock); + while (service_loop == NULL) + g_cond_wait (&service_loop_cond, &service_loop_lock); + g_mutex_unlock (&service_loop_lock); +} + +static gpointer +service_thread_func (gpointer user_data) +{ + PeerData *data = user_data; + GMainContext *service_context; + GDBusAuthObserver *observer, *o; + GError *error; + GDBusServerFlags f; + gchar *a, *g; + gboolean b; + + service_context = g_main_context_new (); + g_main_context_push_thread_default (service_context); + + error = NULL; + observer = g_dbus_auth_observer_new (); + server = g_dbus_server_new_sync (tmp_address, + G_DBUS_SERVER_FLAGS_NONE, + test_guid, + observer, + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + + g_signal_connect (server, + "new-connection", + G_CALLBACK (on_new_connection), + data); + g_signal_connect (observer, + "authorize-authenticated-peer", + G_CALLBACK (on_authorize_authenticated_peer), + data); + + g_assert_cmpint (g_dbus_server_get_flags (server), ==, G_DBUS_SERVER_FLAGS_NONE); + g_assert_cmpstr (g_dbus_server_get_guid (server), ==, test_guid); + g_object_get (server, + "flags", &f, + "address", &a, + "guid", &g, + "active", &b, + "authentication-observer", &o, + NULL); + g_assert_cmpint (f, ==, G_DBUS_SERVER_FLAGS_NONE); + g_assert_cmpstr (a, ==, tmp_address); + g_assert_cmpstr (g, ==, test_guid); + g_assert (!b); + g_assert (o == observer); + g_free (a); + g_free (g); + g_object_unref (o); + + g_object_unref (observer); + + g_dbus_server_start (server); + + run_service_loop (service_context); + + g_main_context_pop_thread_default (service_context); + + teardown_service_loop (); + g_main_context_unref (service_context); + + /* test code specifically unrefs the server - see below */ + g_assert (server == NULL); + + return NULL; +} + +#if 0 +static gboolean +on_incoming_connection (GSocketService *service, + GSocketConnection *socket_connection, + GObject *source_object, + gpointer user_data) +{ + PeerData *data = user_data; + + if (data->accept_connection) + { + GError *error; + guint reg_id; + GDBusConnection *connection; + + error = NULL; + connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), + test_guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + + g_ptr_array_add (data->current_connections, connection); + + /* export object on the newly established connection */ + error = NULL; + reg_id = g_dbus_connection_register_object (connection, + "/org/gtk/GDBus/PeerTestObject", + &test_interface_introspection_data, + &test_interface_vtable, + data, + NULL, /* GDestroyNotify for data */ + &error); + g_assert_no_error (error); + g_assert (reg_id > 0); + + } + else + { + /* don't do anything */ + } + + data->num_connection_attempts++; + + g_main_loop_quit (loop); + + /* stops other signal handlers from being invoked */ + return TRUE; +} + +static gpointer +service_thread_func (gpointer data) +{ + GMainContext *service_context; + gchar *socket_path; + GSocketAddress *address; + GError *error; + + service_context = g_main_context_new (); + g_main_context_push_thread_default (service_context); + + socket_path = g_strdup_printf ("/tmp/gdbus-test-pid-%d", getpid ()); + address = g_unix_socket_address_new (socket_path); + + service = g_socket_service_new (); + error = NULL; + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + address, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + NULL, /* source_object */ + NULL, /* effective_address */ + &error); + g_assert_no_error (error); + g_signal_connect (service, + "incoming", + G_CALLBACK (on_incoming_connection), + data); + g_socket_service_start (service); + + run_service_loop (service_context); + + g_main_context_pop_thread_default (service_context); + + teardown_service_loop (); + g_main_context_unref (service_context); + + g_object_unref (address); + g_free (socket_path); + return NULL; +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +#if 0 +static gboolean +check_connection (gpointer user_data) +{ + PeerData *data = user_data; + guint n; + + for (n = 0; n < data->current_connections->len; n++) + { + GDBusConnection *c; + GIOStream *stream; + + c = G_DBUS_CONNECTION (data->current_connections->pdata[n]); + stream = g_dbus_connection_get_stream (c); + + g_debug ("In check_connection for %d: connection %p, stream %p", n, c, stream); + g_debug ("closed = %d", g_io_stream_is_closed (stream)); + + GSocket *socket; + socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream)); + g_debug ("socket_closed = %d", g_socket_is_closed (socket)); + g_debug ("socket_condition_check = %d", g_socket_condition_check (socket, G_IO_IN|G_IO_OUT|G_IO_ERR|G_IO_HUP)); + + gchar buf[128]; + GError *error; + gssize num_read; + error = NULL; + num_read = g_input_stream_read (g_io_stream_get_input_stream (stream), + buf, + 128, + NULL, + &error); + if (num_read < 0) + { + g_debug ("error: %s", error->message); + g_error_free (error); + } + else + { + g_debug ("no error, read %d bytes", (gint) num_read); + } + } + + return G_SOURCE_REMOVE; +} + +static gboolean +on_do_disconnect_in_idle (gpointer data) +{ + GDBusConnection *c = G_DBUS_CONNECTION (data); + g_debug ("GDC %p has ref_count %d", c, G_OBJECT (c)->ref_count); + g_dbus_connection_disconnect (c); + g_object_unref (c); + return G_SOURCE_REMOVE; +} +#endif + +#ifdef G_OS_UNIX +static gchar * +read_all_from_fd (gint fd, gsize *out_len, GError **error) +{ + GString *str; + gchar buf[64]; + gssize num_read; + + str = g_string_new (NULL); + + do + { + int errsv; + + num_read = read (fd, buf, sizeof (buf)); + errsv = errno; + if (num_read == -1) + { + if (errsv == EAGAIN || errsv == EWOULDBLOCK) + continue; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + "Failed reading %d bytes into offset %d: %s", + (gint) sizeof (buf), + (gint) str->len, + g_strerror (errsv)); + goto error; + } + else if (num_read > 0) + { + g_string_append_len (str, buf, num_read); + } + else if (num_read == 0) + { + break; + } + } + while (TRUE); + + if (out_len != NULL) + *out_len = str->len; + return g_string_free (str, FALSE); + + error: + if (out_len != NULL) + *out_len = 0; + g_string_free (str, TRUE); + return NULL; +} +#endif + +static void +do_test_peer (void) +{ + GDBusConnection *c; + GDBusConnection *c2; + GDBusProxy *proxy; + GError *error; + PeerData data; + GVariant *value; + GVariant *result; + const gchar *s; + GThread *service_thread; + gulong signal_handler_id; + gsize i; + + memset (&data, '\0', sizeof (PeerData)); + data.current_connections = g_ptr_array_new_with_free_func (g_object_unref); + + /* first try to connect when there is no server */ + error = NULL; + c = g_dbus_connection_new_for_address_sync (is_unix ? "unix:path=/tmp/gdbus-test-does-not-exist-pid" : + /* NOTE: Even if something is listening on port 12345 the connection + * will fail because the nonce file doesn't exist */ + "nonce-tcp:host=127.0.0.1,port=12345,noncefile=this-does-not-exist-gdbus", + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + _g_assert_error_domain (error, G_IO_ERROR); + g_assert (!g_dbus_error_is_remote_error (error)); + g_clear_error (&error); + g_assert (c == NULL); + + /* bring up a server - we run the server in a different thread to avoid deadlocks */ + service_thread = g_thread_new ("test_peer", + service_thread_func, + &data); + await_service_loop (); + g_assert (server != NULL); + + /* bring up a connection and accept it */ + data.accept_connection = TRUE; + error = NULL; + c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert (c != NULL); + while (data.current_connections->len < 1) + g_main_loop_run (loop); + g_assert_cmpint (data.current_connections->len, ==, 1); + g_assert_cmpint (data.num_connection_attempts, ==, 1); + g_assert (g_dbus_connection_get_unique_name (c) == NULL); + g_assert_cmpstr (g_dbus_connection_get_guid (c), ==, test_guid); + + /* check that we create a proxy, read properties, receive signals and invoke + * the HelloPeer() method. Since the server runs in another thread it's fine + * to use synchronous blocking API here. + */ + error = NULL; + proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + NULL, /* bus_name */ + "/org/gtk/GDBus/PeerTestObject", + "org.gtk.GDBus.PeerTestInterface", + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_assert (proxy != NULL); + error = NULL; + value = g_dbus_proxy_get_cached_property (proxy, "PeerProperty"); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "ThePropertyValue"); + + /* try invoking a method */ + error = NULL; + result = g_dbus_proxy_call_sync (proxy, + "HelloPeer", + g_variant_new ("(s)", "Hey Peer!"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_variant_get (result, "(&s)", &s); + g_assert_cmpstr (s, ==, "You greeted me with 'Hey Peer!'."); + g_variant_unref (result); + g_assert_cmpint (data.num_method_calls, ==, 1); + + /* make the other peer emit a signal - catch it */ + signal_handler_id = g_signal_connect (proxy, + "g-signal", + G_CALLBACK (on_proxy_signal_received), + &data); + g_assert (!data.signal_received); + g_dbus_proxy_call (proxy, + "EmitSignal", + NULL, /* no arguments */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* GCancellable */ + NULL, /* GAsyncReadyCallback - we don't care about the result */ + NULL); /* user_data */ + g_main_loop_run (loop); + g_assert (data.signal_received); + g_assert_cmpint (data.num_method_calls, ==, 2); + g_signal_handler_disconnect (proxy, signal_handler_id); + + /* Also ensure that messages with the sender header-field set gets + * delivered to the proxy - note that this doesn't really make sense + * e.g. names are meaning-less in a peer-to-peer case... but we + * support it because it makes sense in certain bridging + * applications - see e.g. #623815. + */ + signal_handler_id = g_signal_connect (proxy, + "g-signal", + G_CALLBACK (on_proxy_signal_received_with_name_set), + &data); + data.signal_received = FALSE; + g_dbus_proxy_call (proxy, + "EmitSignalWithNameSet", + NULL, /* no arguments */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* GCancellable */ + NULL, /* GAsyncReadyCallback - we don't care about the result */ + NULL); /* user_data */ + g_main_loop_run (loop); + g_assert (data.signal_received); + g_assert_cmpint (data.num_method_calls, ==, 3); + g_signal_handler_disconnect (proxy, signal_handler_id); + + /* + * Check for UNIX fd passing. + * + * The first time through, we use a very simple method call. Note that + * because this does not have a G_VARIANT_TYPE_HANDLE in the message body + * to refer to the fd, it is a GDBus-specific idiom that would not + * interoperate with libdbus or sd-bus + * (see ). + * + * The second time, we call a method that returns a fd attached to a + * large message, to reproduce + * . It also happens + * to follow the more usual pattern for D-Bus messages containing a + * G_VARIANT_TYPE_HANDLE to refer to attached fds. + */ + for (i = 0; i < 2; i++) + { +#ifdef G_OS_UNIX + GDBusMessage *method_call_message; + GDBusMessage *method_reply_message; + GUnixFDList *fd_list; + gint fd; + gchar *buf; + gsize len; + gchar *buf2; + gsize len2; + const char *testfile = g_test_get_filename (G_TEST_DIST, "file.c", NULL); + const char *method = "OpenFile"; + GVariant *body; + + if (i == 1) + method = "OpenFileWithBigMessage"; + + method_call_message = g_dbus_message_new_method_call (NULL, /* name */ + "/org/gtk/GDBus/PeerTestObject", + "org.gtk.GDBus.PeerTestInterface", + method); + g_dbus_message_set_body (method_call_message, g_variant_new ("(s)", testfile)); + error = NULL; + method_reply_message = g_dbus_connection_send_message_with_reply_sync (c, + method_call_message, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, /* out_serial */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_METHOD_RETURN); + + body = g_dbus_message_get_body (method_reply_message); + + if (i == 1) + { + gint32 handle = -1; + GVariant *junk = NULL; + + g_assert_cmpstr (g_variant_get_type_string (body), ==, "(hay)"); + g_variant_get (body, "(h@ay)", &handle, &junk); + g_assert_cmpint (handle, ==, 0); + g_assert_cmpuint (g_variant_n_children (junk), ==, BIG_MESSAGE_ARRAY_SIZE); + g_variant_unref (junk); + } + else + { + g_assert_null (body); + } + + fd_list = g_dbus_message_get_unix_fd_list (method_reply_message); + g_assert (fd_list != NULL); + g_assert_cmpint (g_unix_fd_list_get_length (fd_list), ==, 1); + error = NULL; + fd = g_unix_fd_list_get (fd_list, 0, &error); + g_assert_no_error (error); + g_object_unref (method_call_message); + g_object_unref (method_reply_message); + + error = NULL; + len = 0; + buf = read_all_from_fd (fd, &len, &error); + g_assert_no_error (error); + g_assert (buf != NULL); + close (fd); + + error = NULL; + g_file_get_contents (testfile, + &buf2, + &len2, + &error); + g_assert_no_error (error); + g_assert_cmpmem (buf, len, buf2, len2); + g_free (buf2); + g_free (buf); +#else + /* We do the same number of iterations on non-Unix, so that + * the method call count will match. In this case we use + * OpenFile both times, because the difference between this + * and OpenFileWithBigMessage is only relevant on Unix. */ + error = NULL; + result = g_dbus_proxy_call_sync (proxy, + "OpenFile", + g_variant_new ("(s)", "boo"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* GCancellable */ + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR); + g_assert (result == NULL); + g_error_free (error); +#endif /* G_OS_UNIX */ + } + + /* Check that g_socket_get_credentials() work - (though this really + * should be in socket.c) + */ + { + GSocket *socket; + GCredentials *credentials; + socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (g_dbus_connection_get_stream (c))); + g_assert (G_IS_SOCKET (socket)); + error = NULL; + credentials = g_socket_get_credentials (socket, &error); + +#if G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED + g_assert_no_error (error); + g_assert (G_IS_CREDENTIALS (credentials)); + + g_assert_cmpuint (g_credentials_get_unix_user (credentials, NULL), ==, + getuid ()); +#if G_CREDENTIALS_HAS_PID + g_assert_cmpint (g_credentials_get_unix_pid (credentials, &error), ==, + getpid ()); + g_assert_no_error (error); +#else + g_assert_cmpint (g_credentials_get_unix_pid (credentials, &error), ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); +#endif + g_object_unref (credentials); +#else + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_assert (credentials == NULL); +#endif + } + + + /* bring up a connection - don't accept it - this should fail + */ + data.accept_connection = FALSE; + error = NULL; + c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + _g_assert_error_domain (error, G_IO_ERROR); + g_error_free (error); + g_assert (c2 == NULL); + +#if 0 + /* TODO: THIS TEST DOESN'T WORK YET */ + + /* bring up a connection - accept it.. then disconnect from the client side - check + * that the server side gets the disconnect signal. + */ + error = NULL; + data.accept_connection = TRUE; + c2 = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert (c2 != NULL); + g_assert (!g_dbus_connection_get_is_disconnected (c2)); + while (data.num_connection_attempts < 3) + g_main_loop_run (loop); + g_assert_cmpint (data.current_connections->len, ==, 2); + g_assert_cmpint (data.num_connection_attempts, ==, 3); + g_assert (!g_dbus_connection_get_is_disconnected (G_DBUS_CONNECTION (data.current_connections->pdata[1]))); + g_idle_add (on_do_disconnect_in_idle, c2); + g_debug ("=================================================="); + g_debug ("=================================================="); + g_debug ("=================================================="); + g_debug ("waiting for disconnect on connection %p, stream %p", + data.current_connections->pdata[1], + g_dbus_connection_get_stream (data.current_connections->pdata[1])); + + g_timeout_add (2000, check_connection, &data); + //_g_assert_signal_received (G_DBUS_CONNECTION (data.current_connections->pdata[1]), "closed"); + g_main_loop_run (loop); + g_assert (g_dbus_connection_get_is_disconnected (G_DBUS_CONNECTION (data.current_connections->pdata[1]))); + g_ptr_array_set_size (data.current_connections, 1); /* remove disconnected connection object */ +#endif + + /* unref the server and stop listening for new connections + * + * This won't bring down the established connections - check that c is still connected + * by invoking a method + */ + //g_socket_service_stop (service); + //g_object_unref (service); + g_dbus_server_stop (server); + g_object_unref (server); + server = NULL; + + error = NULL; + result = g_dbus_proxy_call_sync (proxy, + "HelloPeer", + g_variant_new ("(s)", "Hey Again Peer!"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_variant_get (result, "(&s)", &s); + g_assert_cmpstr (s, ==, "You greeted me with 'Hey Again Peer!'."); + g_variant_unref (result); + g_assert_cmpint (data.num_method_calls, ==, 6); + +#if 0 + /* TODO: THIS TEST DOESN'T WORK YET */ + + /* now disconnect from the server side - check that the client side gets the signal */ + g_assert_cmpint (data.current_connections->len, ==, 1); + g_assert (G_DBUS_CONNECTION (data.current_connections->pdata[0]) != c); + g_dbus_connection_disconnect (G_DBUS_CONNECTION (data.current_connections->pdata[0])); + if (!g_dbus_connection_get_is_disconnected (c)) + _g_assert_signal_received (c, "closed"); + g_assert (g_dbus_connection_get_is_disconnected (c)); +#endif + + g_object_unref (c); + g_ptr_array_unref (data.current_connections); + g_object_unref (proxy); + + g_main_loop_quit (service_loop); + g_thread_join (service_thread); +} + +static void +test_peer (void) +{ + test_guid = g_dbus_generate_guid (); + loop = g_main_loop_new (NULL, FALSE); + + /* Run this test multiple times using different address formats to ensure + * they all work. + */ + setup_test_address (); + do_test_peer (); + teardown_test_address (); + +#ifdef G_OS_UNIX + setup_tmpdir_test_address (); + do_test_peer (); + teardown_test_address (); + + setup_path_test_address (); + do_test_peer (); + teardown_test_address (); +#endif + + g_main_loop_unref (loop); + g_free (test_guid); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#define VALID_GUID "0123456789abcdef0123456789abcdef" + +static void +test_peer_invalid_server (void) +{ + GDBusServer *server; + + if (!g_test_undefined ()) + { + g_test_skip ("Not exercising programming errors"); + return; + } + + if (g_test_subprocess ()) + { + /* This assumes we are not going to run out of GDBusServerFlags + * any time soon */ + server = g_dbus_server_new_sync ("tcp:", (GDBusServerFlags) (1 << 30), + VALID_GUID, + NULL, NULL, NULL); + g_assert_null (server); + } + else + { + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_SERVER_FLAGS_ALL*"); + } +} + +static void +test_peer_invalid_conn_stream_sync (void) +{ + GSocket *sock; + GSocketConnection *socket_conn; + GIOStream *iostream; + GDBusConnection *conn; + + if (!g_test_undefined ()) + { + g_test_skip ("Not exercising programming errors"); + return; + } + + sock = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL); + + if (sock == NULL) + { + g_test_skip ("TCP not available?"); + return; + } + + socket_conn = g_socket_connection_factory_create_connection (sock); + g_assert_nonnull (socket_conn); + iostream = G_IO_STREAM (socket_conn); + g_assert_nonnull (iostream); + + if (g_test_subprocess ()) + { + /* This assumes we are not going to run out of GDBusConnectionFlags + * any time soon */ + conn = g_dbus_connection_new_sync (iostream, VALID_GUID, + (GDBusConnectionFlags) (1 << 30), + NULL, NULL, NULL); + g_assert_null (conn); + } + else + { + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*"); + } + + g_clear_object (&sock); + g_clear_object (&socket_conn); +} + +static void +test_peer_invalid_conn_stream_async (void) +{ + GSocket *sock; + GSocketConnection *socket_conn; + GIOStream *iostream; + + if (!g_test_undefined ()) + { + g_test_skip ("Not exercising programming errors"); + return; + } + + sock = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL); + + if (sock == NULL) + { + g_test_skip ("TCP not available?"); + return; + } + + socket_conn = g_socket_connection_factory_create_connection (sock); + g_assert_nonnull (socket_conn); + iostream = G_IO_STREAM (socket_conn); + g_assert_nonnull (iostream); + + if (g_test_subprocess ()) + { + g_dbus_connection_new (iostream, VALID_GUID, + (GDBusConnectionFlags) (1 << 30), + NULL, NULL, NULL, NULL); + } + else + { + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*"); + } + + g_clear_object (&sock); + g_clear_object (&socket_conn); +} + +static void +test_peer_invalid_conn_addr_sync (void) +{ + GDBusConnection *conn; + + if (!g_test_undefined ()) + { + g_test_skip ("Not exercising programming errors"); + return; + } + + if (g_test_subprocess ()) + { + conn = g_dbus_connection_new_for_address_sync ("tcp:", + (GDBusConnectionFlags) (1 << 30), + NULL, NULL, NULL); + g_assert_null (conn); + } + else + { + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*"); + } +} + +static void +test_peer_invalid_conn_addr_async (void) +{ + if (!g_test_undefined ()) + { + g_test_skip ("Not exercising programming errors"); + return; + } + + if (g_test_subprocess ()) + { + g_dbus_connection_new_for_address ("tcp:", + (GDBusConnectionFlags) (1 << 30), + NULL, NULL, NULL, NULL); + } + else + { + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*"); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_peer_signals (void) +{ + GDBusConnection *c; + GDBusProxy *proxy; + GError *error = NULL; + PeerData data; + GThread *service_thread; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1620"); + + test_guid = g_dbus_generate_guid (); + loop = g_main_loop_new (NULL, FALSE); + + setup_test_address (); + memset (&data, '\0', sizeof (PeerData)); + data.current_connections = g_ptr_array_new_with_free_func (g_object_unref); + + /* bring up a server - we run the server in a different thread to avoid deadlocks */ + service_thread = g_thread_new ("test_peer", + service_thread_func, + &data); + await_service_loop (); + g_assert_nonnull (server); + + /* bring up a connection and accept it */ + data.accept_connection = TRUE; + c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert_nonnull (c); + while (data.current_connections->len < 1) + g_main_loop_run (loop); + g_assert_cmpint (data.current_connections->len, ==, 1); + g_assert_cmpint (data.num_connection_attempts, ==, 1); + g_assert_null (g_dbus_connection_get_unique_name (c)); + g_assert_cmpstr (g_dbus_connection_get_guid (c), ==, test_guid); + + /* Check that we can create a proxy with a non-NULL bus name, even though it's + * irrelevant in the non-message-bus case. Since the server runs in another + * thread it's fine to use synchronous blocking API here. + */ + proxy = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + ":1.1", /* bus_name */ + "/org/gtk/GDBus/PeerTestObject", + "org.gtk.GDBus.PeerTestInterface", + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_assert_nonnull (proxy); + + /* unref the server and stop listening for new connections */ + g_dbus_server_stop (server); + g_clear_object (&server); + + g_object_unref (c); + g_ptr_array_unref (data.current_connections); + g_object_unref (proxy); + + g_main_loop_quit (service_loop); + g_thread_join (service_thread); + + teardown_test_address (); + + g_main_loop_unref (loop); + g_free (test_guid); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GDBusServer *server; + GMainContext *context; + GMainLoop *loop; + + GList *connections; +} DmpData; + +static void +dmp_data_free (DmpData *data) +{ + g_main_loop_unref (data->loop); + g_main_context_unref (data->context); + g_object_unref (data->server); + g_list_free_full (data->connections, g_object_unref); + g_free (data); +} + +static void +dmp_on_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + //DmpData *data = user_data; + gint32 first; + gint32 second; + g_variant_get (parameters, + "(ii)", + &first, + &second); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(i)", first + second)); +} + +static const GDBusInterfaceVTable dmp_interface_vtable = +{ + dmp_on_method_call, + NULL, /* get_property */ + NULL, /* set_property */ + { 0 } +}; + + +/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */ +static gboolean +dmp_on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + DmpData *data = user_data; + GDBusNodeInfo *node; + GError *error; + + /* accept the connection */ + data->connections = g_list_prepend (data->connections, g_object_ref (connection)); + + error = NULL; + node = g_dbus_node_info_new_for_xml ("" + " " + " " + " " + " " + " " + " " + " " + "", + &error); + g_assert_no_error (error); + + /* sleep 100ms before exporting an object - this is to test that + * G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING really works + * (GDBusServer uses this feature). + */ + usleep (100 * 1000); + + /* export an object */ + error = NULL; + g_dbus_connection_register_object (connection, + "/dmp/test", + node->interfaces[0], + &dmp_interface_vtable, + data, + NULL, + &error); + g_dbus_node_info_unref (node); + + return TRUE; +} + +static gpointer +dmp_thread_func (gpointer user_data) +{ + DmpData *data = user_data; + GError *error; + gchar *guid; + + data->context = g_main_context_new (); + g_main_context_push_thread_default (data->context); + + error = NULL; + guid = g_dbus_generate_guid (); + data->server = g_dbus_server_new_sync (tmp_address, + G_DBUS_SERVER_FLAGS_NONE, + guid, + NULL, /* GDBusAuthObserver */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_signal_connect (data->server, + "new-connection", + G_CALLBACK (dmp_on_new_connection), + data); + + g_dbus_server_start (data->server); + + data->loop = g_main_loop_new (data->context, FALSE); + g_main_loop_run (data->loop); + + g_dbus_server_stop (data->server); + g_main_context_pop_thread_default (data->context); + + g_free (guid); + return NULL; +} + +static void +delayed_message_processing (void) +{ + GError *error; + DmpData *data; + GThread *service_thread; + guint n; + + test_guid = g_dbus_generate_guid (); + loop = g_main_loop_new (NULL, FALSE); + + setup_test_address (); + + data = g_new0 (DmpData, 1); + + service_thread = g_thread_new ("dmp", + dmp_thread_func, + data); + while (data->server == NULL || !g_dbus_server_is_active (data->server)) + g_thread_yield (); + + for (n = 0; n < 5; n++) + { + GDBusConnection *c; + GVariant *res; + gint32 val; + + error = NULL; + c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (data->server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + error = NULL; + res = g_dbus_connection_call_sync (c, + NULL, /* bus name */ + "/dmp/test", + "org.gtk.GDBus.DmpInterface", + "AddPair", + g_variant_new ("(ii)", 2, n), + G_VARIANT_TYPE ("(i)"), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout_msec */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_variant_get (res, "(i)", &val); + g_assert_cmpint (val, ==, 2 + n); + g_variant_unref (res); + g_object_unref (c); + } + + g_main_loop_quit (data->loop); + g_thread_join (service_thread); + dmp_data_free (data); + teardown_test_address (); + + g_main_loop_unref (loop); + g_free (test_guid); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +nonce_tcp_on_authorize_authenticated_peer (GDBusAuthObserver *observer, + GIOStream *stream, + GCredentials *credentials, + gpointer user_data) +{ + PeerData *data = user_data; + gboolean authorized; + + data->num_connection_attempts++; + + authorized = TRUE; + if (!data->accept_connection) + { + authorized = FALSE; + g_main_loop_quit (loop); + } + + return authorized; +} + +/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */ +static gboolean +nonce_tcp_on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + PeerData *data = user_data; + + g_ptr_array_add (data->current_connections, g_object_ref (connection)); + + g_main_loop_quit (loop); + + return TRUE; +} + +static gpointer +nonce_tcp_service_thread_func (gpointer user_data) +{ + PeerData *data = user_data; + GMainContext *service_context; + GDBusAuthObserver *observer; + GError *error; + + service_context = g_main_context_new (); + g_main_context_push_thread_default (service_context); + + error = NULL; + observer = g_dbus_auth_observer_new (); + server = g_dbus_server_new_sync ("nonce-tcp:host=127.0.0.1", + G_DBUS_SERVER_FLAGS_NONE, + test_guid, + observer, + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + + g_signal_connect (server, + "new-connection", + G_CALLBACK (nonce_tcp_on_new_connection), + data); + g_signal_connect (observer, + "authorize-authenticated-peer", + G_CALLBACK (nonce_tcp_on_authorize_authenticated_peer), + data); + g_object_unref (observer); + + g_dbus_server_start (server); + + run_service_loop (service_context); + + g_main_context_pop_thread_default (service_context); + + teardown_service_loop (); + g_main_context_unref (service_context); + + /* test code specifically unrefs the server - see below */ + g_assert (server == NULL); + + return NULL; +} + +static void +test_nonce_tcp (void) +{ + PeerData data; + GError *error; + GThread *service_thread; + GDBusConnection *c; + gchar *s; + gchar *nonce_file; + gboolean res; + const gchar *address; + + test_guid = g_dbus_generate_guid (); + loop = g_main_loop_new (NULL, FALSE); + + memset (&data, '\0', sizeof (PeerData)); + data.current_connections = g_ptr_array_new_with_free_func (g_object_unref); + + error = NULL; + server = NULL; + service_thread = g_thread_new ("nonce-tcp-service", + nonce_tcp_service_thread_func, + &data); + await_service_loop (); + g_assert (server != NULL); + + /* bring up a connection and accept it */ + data.accept_connection = TRUE; + error = NULL; + c = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert (c != NULL); + while (data.current_connections->len < 1) + g_thread_yield (); + g_assert_cmpint (data.current_connections->len, ==, 1); + g_assert_cmpint (data.num_connection_attempts, ==, 1); + g_assert (g_dbus_connection_get_unique_name (c) == NULL); + g_assert_cmpstr (g_dbus_connection_get_guid (c), ==, test_guid); + g_object_unref (c); + + /* now, try to subvert the nonce file (this assumes noncefile is the last key/value pair) + */ + + address = g_dbus_server_get_client_address (server); + + s = strstr (address, "noncefile="); + g_assert (s != NULL); + s += sizeof "noncefile=" - 1; + nonce_file = g_strdup (s); + + /* First try invalid data in the nonce file - this will actually + * make the client send this and the server will reject it. The way + * it works is that if the nonce doesn't match, the server will + * simply close the connection. So, from the client point of view, + * we can see a variety of errors. + */ + error = NULL; + res = g_file_set_contents (nonce_file, + "0123456789012345", + -1, + &error); + g_assert_no_error (error); + g_assert (res); + c = g_dbus_connection_new_for_address_sync (address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + _g_assert_error_domain (error, G_IO_ERROR); + g_error_free (error); + g_assert (c == NULL); + + /* Then try with a nonce-file of incorrect length - this will make + * the client complain - we won't even try connecting to the server + * for this + */ + error = NULL; + res = g_file_set_contents (nonce_file, + "0123456789012345_", + -1, + &error); + g_assert_no_error (error); + g_assert (res); + c = g_dbus_connection_new_for_address_sync (address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_error_free (error); + g_assert (c == NULL); + + /* Finally try with no nonce-file at all */ + g_assert_cmpint (g_unlink (nonce_file), ==, 0); + error = NULL; + c = g_dbus_connection_new_for_address_sync (address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_error_free (error); + g_assert (c == NULL); + + /* Recreate the nonce-file so we can ensure the server deletes it when stopped. */ + g_assert_cmpint (g_creat (nonce_file, 0600), !=, -1); + + g_dbus_server_stop (server); + g_object_unref (server); + server = NULL; + + g_assert_false (g_file_test (nonce_file, G_FILE_TEST_EXISTS)); + g_free (nonce_file); + + g_main_loop_quit (service_loop); + g_thread_join (service_thread); + + g_ptr_array_unref (data.current_connections); + + g_main_loop_unref (loop); + g_free (test_guid); +} + +static void +test_credentials (void) +{ + GCredentials *c1, *c2; + GError *error; + gchar *desc; + + c1 = g_credentials_new (); + c2 = g_credentials_new (); + + error = NULL; + if (g_credentials_set_unix_user (c2, getuid (), &error)) + g_assert_no_error (error); + + g_clear_error (&error); + g_assert (g_credentials_is_same_user (c1, c2, &error)); + g_assert_no_error (error); + + desc = g_credentials_to_string (c1); + g_assert (desc != NULL); + g_free (desc); + + g_object_unref (c1); + g_object_unref (c2); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +tcp_anonymous_on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + gboolean *seen_connection = user_data; + *seen_connection = TRUE; + return TRUE; +} + +static gpointer +tcp_anonymous_service_thread_func (gpointer user_data) +{ + gboolean *seen_connection = user_data; + GMainContext *service_context; + GError *error; + + service_context = g_main_context_new (); + g_main_context_push_thread_default (service_context); + + error = NULL; + server = g_dbus_server_new_sync ("tcp:host=127.0.0.1", + G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS, + test_guid, + NULL, /* GDBusObserver* */ + NULL, /* GCancellable* */ + &error); + g_assert_no_error (error); + + g_signal_connect (server, + "new-connection", + G_CALLBACK (tcp_anonymous_on_new_connection), + seen_connection); + + g_dbus_server_start (server); + + run_service_loop (service_context); + + g_main_context_pop_thread_default (service_context); + + teardown_service_loop (); + g_main_context_unref (service_context); + + return NULL; +} + +static void +test_tcp_anonymous (void) +{ + gboolean seen_connection; + GThread *service_thread; + GDBusConnection *connection; + GError *error; + + test_guid = g_dbus_generate_guid (); + loop = g_main_loop_new (NULL, FALSE); + + seen_connection = FALSE; + service_thread = g_thread_new ("tcp-anon-service", + tcp_anonymous_service_thread_func, + &seen_connection); + await_service_loop (); + g_assert (server != NULL); + + error = NULL; + connection = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver* */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_assert (connection != NULL); + + while (!seen_connection) + g_thread_yield (); + + g_object_unref (connection); + + g_main_loop_quit (service_loop); + g_dbus_server_stop (server); + g_object_unref (server); + server = NULL; + + g_thread_join (service_thread); + + g_main_loop_unref (loop); + g_free (test_guid); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusServer *codegen_server = NULL; + +static gboolean +codegen_on_animal_poke (ExampleAnimal *animal, + GDBusMethodInvocation *invocation, + gboolean make_sad, + gboolean make_happy, + gpointer user_data) +{ + if ((make_sad && make_happy) || (!make_sad && !make_happy)) + { + g_main_loop_quit (service_loop); + + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.Examples.ObjectManager.Error.Failed", + "Exactly one of make_sad or make_happy must be TRUE"); + goto out; + } + + if (make_sad) + { + if (g_strcmp0 (example_animal_get_mood (animal), "Sad") == 0) + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.Examples.ObjectManager.Error.SadAnimalIsSad", + "Sad animal is already sad"); + goto out; + } + + example_animal_set_mood (animal, "Sad"); + example_animal_complete_poke (animal, invocation); + goto out; + } + + if (make_happy) + { + if (g_strcmp0 (example_animal_get_mood (animal), "Happy") == 0) + { + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.Examples.ObjectManager.Error.HappyAnimalIsHappy", + "Happy animal is already happy"); + goto out; + } + + example_animal_set_mood (animal, "Happy"); + example_animal_complete_poke (animal, invocation); + goto out; + } + + g_assert_not_reached (); + + out: + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +/* Runs in thread we created GDBusServer in (since we didn't pass G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) */ +static gboolean +codegen_on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + ExampleAnimal *animal = user_data; + GError *error = NULL; + + /* g_printerr ("Client connected.\n" */ + /* "Negotiated capabilities: unix-fd-passing=%d\n", */ + /* g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); */ + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (animal), connection, + "/Example/Animals/000", &error); + g_assert_no_error (error); + + return TRUE; +} + +static gpointer +codegen_service_thread_func (gpointer user_data) +{ + GMainContext *service_context; + ExampleAnimal *animal; + GError *error = NULL; + + service_context = g_main_context_new (); + g_main_context_push_thread_default (service_context); + + /* Create the animal in the right thread context */ + animal = example_animal_skeleton_new (); + + /* Handle Poke() D-Bus method invocations on the .Animal interface */ + g_signal_connect (animal, "handle-poke", + G_CALLBACK (codegen_on_animal_poke), + NULL); /* user_data */ + + codegen_server = g_dbus_server_new_sync (tmp_address, + G_DBUS_SERVER_FLAGS_NONE, + test_guid, + NULL, /* observer */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_dbus_server_start (codegen_server); + + g_signal_connect (codegen_server, "new-connection", + G_CALLBACK (codegen_on_new_connection), + animal); + + run_service_loop (service_context); + + g_object_unref (animal); + + g_main_context_pop_thread_default (service_context); + + teardown_service_loop (); + g_main_context_unref (service_context); + + g_dbus_server_stop (codegen_server); + g_object_unref (codegen_server); + codegen_server = NULL; + + return NULL; +} + + +static gboolean +codegen_quit_mainloop_timeout (gpointer data) +{ + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; +} + +static void +codegen_test_peer (void) +{ + GDBusConnection *connection; + ExampleAnimal *animal1, *animal2; + GThread *service_thread; + GError *error = NULL; + GVariant *value; + const gchar *s; + + test_guid = g_dbus_generate_guid (); + loop = g_main_loop_new (NULL, FALSE); + + setup_test_address (); + + /* bring up a server - we run the server in a different thread to avoid deadlocks */ + service_thread = g_thread_new ("codegen_test_peer", + codegen_service_thread_func, + NULL); + await_service_loop (); + g_assert (codegen_server != NULL); + + /* Get an animal 1 ... */ + connection = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (codegen_server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert (connection != NULL); + + animal1 = example_animal_proxy_new_sync (connection, 0, NULL, + "/Example/Animals/000", NULL, &error); + g_assert_no_error (error); + g_assert (animal1 != NULL); + g_object_unref (connection); + + /* Get animal 2 ... */ + connection = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (codegen_server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert (connection != NULL); + + animal2 = example_animal_proxy_new_sync (connection, 0, NULL, + "/Example/Animals/000", NULL, &error); + g_assert_no_error (error); + g_assert (animal2 != NULL); + g_object_unref (connection); + + /* Make animal sad via animal1 */ + example_animal_call_poke_sync (animal1, TRUE, FALSE, NULL, &error); + g_assert_no_error (error); + + /* Poke server and make sure animal is updated */ + value = g_dbus_proxy_call_sync (G_DBUS_PROXY (animal1), + "org.freedesktop.DBus.Peer.Ping", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_assert_no_error (error); + g_assert (value != NULL); + g_variant_unref (value); + + /* Give the proxies a chance to refresh in the default main loop */ + g_timeout_add (100, codegen_quit_mainloop_timeout, NULL); + g_main_loop_run (loop); + + /* Assert animals are sad */ + g_assert_cmpstr (example_animal_get_mood (animal1), ==, "Sad"); + g_assert_cmpstr (example_animal_get_mood (animal2), ==, "Sad"); + + /* Make animal happy via animal2 */ + example_animal_call_poke_sync (animal2, FALSE, TRUE, NULL, &error); + g_assert_no_error (error); + + /* Some random unrelated call, just to get some test coverage */ + value = g_dbus_proxy_call_sync (G_DBUS_PROXY (animal2), + "org.freedesktop.DBus.Peer.GetMachineId", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_assert_no_error (error); + g_variant_get (value, "(&s)", &s); + g_test_message ("Machine ID: %s", s); + /* It's valid for machine-id inside containers to be empty, so we + * need to test for that possibility + */ + g_assert ((s == NULL || *s == '\0') || g_dbus_is_guid (s)); + g_variant_unref (value); + + /* Poke server and make sure animal is updated */ + value = g_dbus_proxy_call_sync (G_DBUS_PROXY (animal2), + "org.freedesktop.DBus.Peer.Ping", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_assert_no_error (error); + g_assert (value != NULL); + g_variant_unref (value); + + /* Give the proxies a chance to refresh in the default main loop */ + g_timeout_add (1000, codegen_quit_mainloop_timeout, NULL); + g_main_loop_run (loop); + + /* Assert animals are happy */ + g_assert_cmpstr (example_animal_get_mood (animal1), ==, "Happy"); + g_assert_cmpstr (example_animal_get_mood (animal2), ==, "Happy"); + + /* This final call making the animal happy and sad will cause + * the server to quit, when the server quits we dont get property + * change notifications anyway because those are done from an idle handler + */ + example_animal_call_poke_sync (animal2, TRUE, TRUE, NULL, &error); + g_clear_error (&error); + + g_object_unref (animal1); + g_object_unref (animal2); + g_thread_join (service_thread); + + teardown_test_address (); + + g_main_loop_unref (loop); + g_free (test_guid); +} + +/* ---------------------------------------------------------------------------------------------------- */ + + +int +main (int argc, + char *argv[]) +{ + gint ret; + GDBusNodeInfo *introspection_data = NULL; + + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL); + g_assert (introspection_data != NULL); + test_interface_introspection_data = introspection_data->interfaces[0]; + + g_test_add_func ("/gdbus/peer-to-peer", test_peer); + g_test_add_func ("/gdbus/peer-to-peer/invalid/server", + test_peer_invalid_server); + g_test_add_func ("/gdbus/peer-to-peer/invalid/conn/stream/async", + test_peer_invalid_conn_stream_async); + g_test_add_func ("/gdbus/peer-to-peer/invalid/conn/stream/sync", + test_peer_invalid_conn_stream_sync); + g_test_add_func ("/gdbus/peer-to-peer/invalid/conn/addr/async", + test_peer_invalid_conn_addr_async); + g_test_add_func ("/gdbus/peer-to-peer/invalid/conn/addr/sync", + test_peer_invalid_conn_addr_sync); + g_test_add_func ("/gdbus/peer-to-peer/signals", test_peer_signals); + g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing); + g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp); + + g_test_add_func ("/gdbus/tcp-anonymous", test_tcp_anonymous); + g_test_add_func ("/gdbus/credentials", test_credentials); + g_test_add_func ("/gdbus/codegen-peer-to-peer", codegen_test_peer); + + ret = g_test_run (); + + g_dbus_node_info_unref (introspection_data); + + return ret; +} diff --git a/gio/tests/gdbus-proxy-threads.c b/gio/tests/gdbus-proxy-threads.c new file mode 100644 index 0000000..690a9cc --- /dev/null +++ b/gio/tests/gdbus-proxy-threads.c @@ -0,0 +1,250 @@ +/* Test case for GNOME #651133 + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * Copyright (C) 2011 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Simon McVittie + */ + +#include + +#include +#include + +#include + +#include "gdbus-tests.h" + +#ifdef HAVE_DBUS1 +# include +#else +# define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" +# define DBUS_PATH_DBUS "/org/freedesktop/DBus" +# define DBUS_SERVICE_DBUS "org.freedesktop.DBus" +# define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 +# define DBUS_RELEASE_NAME_REPLY_RELEASED 1 +#endif + +#define MY_NAME "com.example.Test.Myself" +/* This many threads create and destroy GDBusProxy instances, in addition + * to the main thread processing their NameOwnerChanged signals. + * N_THREADS_MAX is used with "-m slow", N_THREADS otherwise. + */ +#define N_THREADS_MAX 10 +#define N_THREADS 2 +/* This many GDBusProxy instances are created by each thread. */ +#define N_REPEATS 100 +/* The main thread requests/releases a name this many times as rapidly as + * possible, before performing one "slow" cycle that waits for each method + * call result (and therefore, due to D-Bus total ordering, all previous + * method calls) to prevent requests from piling up infinitely. The more calls + * are made rapidly, the better we reproduce bugs. + */ +#define N_RAPID_CYCLES 50 + +static GMainLoop *loop; + +static gpointer +run_proxy_thread (gpointer data) +{ + GDBusConnection *connection = data; + int i; + + g_assert (g_main_context_get_thread_default () == NULL); + + for (i = 0; i < N_REPEATS; i++) + { + GDBusProxy *proxy; + GError *error = NULL; + GVariant *ret; + + if (g_test_verbose ()) + g_printerr ("."); + + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + MY_NAME, + "/com/example/TestObject", + "com.example.Frob", + NULL, + &error); + g_assert_no_error (error); + g_assert (proxy != NULL); + g_dbus_proxy_set_default_timeout (proxy, G_MAXINT); + + ret = g_dbus_proxy_call_sync (proxy, "StupidMethod", NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, + NULL, NULL); + /* + * we expect this to fail - if we have the name at the moment, we called + * an unimplemented method, and if not, there was nothing to call + */ + g_assert (ret == NULL); + + /* + * this races with the NameOwnerChanged signal being emitted in an + * idle + */ + g_object_unref (proxy); + } + + g_main_loop_quit (loop); + return NULL; +} + +static void release_name (GDBusConnection *connection, gboolean wait); + +static void +request_name_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (source); + GError *error = NULL; + GVariant *var; + + var = g_dbus_connection_call_finish (connection, res, &error); + g_assert_no_error (error); + g_assert_cmpuint (g_variant_get_uint32 (g_variant_get_child_value (var, 0)), + ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER); + + release_name (connection, TRUE); +} + +static void +request_name (GDBusConnection *connection, + gboolean wait) +{ + g_dbus_connection_call (connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "RequestName", + g_variant_new ("(su)", MY_NAME, 0), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + wait ? request_name_cb : NULL, + NULL); +} + +static void +release_name_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GDBusConnection *connection = G_DBUS_CONNECTION (source); + GError *error = NULL; + GVariant *var; + int i; + + var = g_dbus_connection_call_finish (connection, res, &error); + g_assert_no_error (error); + g_assert_cmpuint (g_variant_get_uint32 (g_variant_get_child_value (var, 0)), + ==, DBUS_RELEASE_NAME_REPLY_RELEASED); + + /* generate some rapid NameOwnerChanged signals to try to trigger crashes */ + for (i = 0; i < N_RAPID_CYCLES; i++) + { + request_name (connection, FALSE); + release_name (connection, FALSE); + } + + /* wait for dbus-daemon to catch up */ + request_name (connection, TRUE); +} + +static void +release_name (GDBusConnection *connection, + gboolean wait) +{ + g_dbus_connection_call (connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "ReleaseName", + g_variant_new ("(s)", MY_NAME), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + wait ? release_name_cb : NULL, + NULL); +} + +static void +test_proxy (void) +{ + GDBusConnection *connection; + GError *error = NULL; + GThread *proxy_threads[N_THREADS_MAX]; + int i; + int n_threads; + + if (g_test_slow ()) + n_threads = N_THREADS_MAX; + else + n_threads = N_THREADS; + + session_bus_up (); + + loop = g_main_loop_new (NULL, TRUE); + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, + NULL, + &error); + g_assert_no_error (error); + + request_name (connection, TRUE); + + for (i = 0; i < n_threads; i++) + { + proxy_threads[i] = g_thread_new ("run-proxy", + run_proxy_thread, connection); + } + + g_main_loop_run (loop); + + for (i = 0; i < n_threads; i++) + { + g_thread_join (proxy_threads[i]); + } + + g_object_unref (connection); + g_main_loop_unref (loop); + + /* TODO: should call session_bus_down() but that requires waiting + * for all the outstanding method calls to complete... + */ + if (g_test_verbose ()) + g_printerr ("\n"); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_dbus_unset (); + + g_test_add_func ("/gdbus/proxy/vs-threads", test_proxy); + + return g_test_run(); +} diff --git a/gio/tests/gdbus-proxy-unique-name.c b/gio/tests/gdbus-proxy-unique-name.c new file mode 100644 index 0000000..eacb021 --- /dev/null +++ b/gio/tests/gdbus-proxy-unique-name.c @@ -0,0 +1,215 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Cosimo Cecchi + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +proxy_new_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GDBusProxy **ret = user_data; + GError *error; + + error = NULL; + *ret = g_dbus_proxy_new_finish (res, &error); + g_assert_no_error (error); + g_assert_nonnull (ret); + + g_main_loop_quit (loop); +} + +static void +test_proxy_unique_name (void) +{ + GDBusProxy *wp; + GDBusProxy *p; + GDBusProxy *ap; + GDBusConnection *c; + GError *error; + gchar *name_owner; + gchar **property_names; + GVariant *variant; + GVariant *result; + char *unique_name; + + session_bus_up (); + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c); + + /* use a proxy to the well-known name to set things up */ + wp = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo* */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + /* this is safe; testserver will exit once the bus goes away */ + g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + + /* check that we get the notify::g-name-owner signal */ + _g_assert_property_notify (wp, "g-name-owner"); + + /* now get the unique name of testserver's connection */ + unique_name = g_dbus_proxy_get_name_owner (wp); + + /* if we create another a proxy with the service being available, check that + * it has a name owner and properties + */ + error = NULL; + p = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo* */ + unique_name, /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + name_owner = g_dbus_proxy_get_name_owner (p); + property_names = g_dbus_proxy_get_cached_property_names (p); + g_assert_true (g_dbus_is_unique_name (name_owner)); + g_assert_nonnull (property_names); + g_assert_cmpint (g_strv_length (property_names), >, 0); + g_free (name_owner); + g_strfreev (property_names); + + /* also for async: we should have a name owner and cached properties */ + g_dbus_proxy_new (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo* */ + unique_name, /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + NULL, /* GCancellable */ + (GAsyncReadyCallback) proxy_new_cb, + &ap); + g_main_loop_run (loop); + name_owner = g_dbus_proxy_get_name_owner (ap); + property_names = g_dbus_proxy_get_cached_property_names (ap); + g_assert_true (g_dbus_is_unique_name (name_owner)); + g_assert_nonnull (property_names); + g_assert_cmpint (g_strv_length (property_names), >, 0); + g_free (name_owner); + g_strfreev (property_names); + + /* Check property value is the initial value */ + variant = g_dbus_proxy_get_cached_property (p, "y"); + g_assert_nonnull (variant); + g_assert_cmpint (g_variant_get_byte (variant), ==, 1); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (ap, "y"); + g_assert_nonnull (variant); + g_assert_cmpint (g_variant_get_byte (variant), ==, 1); + g_variant_unref (variant); + + /* Check that properties are updated on p */ + result = g_dbus_proxy_call_sync (p, + "FrobSetProperty", + g_variant_new ("(sv)", + "y", + g_variant_new_byte (42)), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + _g_assert_signal_received (p, "g-properties-changed"); + variant = g_dbus_proxy_get_cached_property (p, "y"); + g_assert_nonnull (variant); + g_assert_cmpint (g_variant_get_byte (variant), ==, 42); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (ap, "y"); + g_assert_nonnull (variant); + g_assert_cmpint (g_variant_get_byte (variant), ==, 42); + g_variant_unref (variant); + + /* Nuke the service and check that we get the signal and then don't + * have a name owner nor any cached properties + */ + result = g_dbus_proxy_call_sync (p, + "Quit", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + /* and wait... */ + _g_assert_property_notify (p, "g-name-owner"); + /* now we shouldn't have a name owner nor any cached properties */ + g_assert_cmpstr (g_dbus_proxy_get_name_owner (p), ==, NULL); + g_assert_null (g_dbus_proxy_get_cached_property_names (p)); + g_assert_null (g_dbus_proxy_get_cached_property (p, "y")); + + g_object_unref (p); + g_object_unref (ap); + + g_object_unref (wp); + g_free (unique_name); + + g_object_unref (c); + + /* tear down bus */ + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, NULL); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_dbus_unset (); + + g_test_add_func ("/gdbus/proxy-unique-name", test_proxy_unique_name); + + ret = g_test_run(); + return ret; +} diff --git a/gio/tests/gdbus-proxy-well-known-name.c b/gio/tests/gdbus-proxy-well-known-name.c new file mode 100644 index 0000000..51b537c --- /dev/null +++ b/gio/tests/gdbus-proxy-well-known-name.c @@ -0,0 +1,272 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +proxy_new_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GDBusProxy **ret = user_data; + GError *error; + + error = NULL; + *ret = g_dbus_proxy_new_finish (res, &error); + g_assert_no_error (error); + g_assert (ret != NULL); + + g_main_loop_quit (loop); +} + +static void +test_proxy_well_known_name (void) +{ + GDBusProxy *p; + GDBusProxy *p2; + GDBusProxy *ap; + GDBusProxy *ap2; + GDBusConnection *c; + GError *error; + gchar *name_owner; + gchar **property_names; + GVariant *variant; + GVariant *result; + + session_bus_up (); + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (c != NULL); + + error = NULL; + p = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo* */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + /* we shouldn't have a name owner nor any cached properties */ + g_assert_cmpstr (g_dbus_proxy_get_name_owner (p), ==, NULL); + g_assert (g_dbus_proxy_get_cached_property_names (p) == NULL); + + /* also for async: we shouldn't have a name owner nor any cached properties */ + g_dbus_proxy_new (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo* */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + NULL, /* GCancellable */ + (GAsyncReadyCallback) proxy_new_cb, + &ap); + g_main_loop_run (loop); + g_assert_cmpstr (g_dbus_proxy_get_name_owner (ap), ==, NULL); + g_assert (g_dbus_proxy_get_cached_property_names (ap) == NULL); + + /* this is safe; testserver will exit once the bus goes away */ + g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + + /* check that we get the notify::g-name-owner signal */ + _g_assert_property_notify (p, "g-name-owner"); + + /* Now we should have a name owner as well as properties */ + name_owner = g_dbus_proxy_get_name_owner (p); + property_names = g_dbus_proxy_get_cached_property_names (p); + g_assert (g_dbus_is_unique_name (name_owner)); + g_assert (property_names != NULL && g_strv_length (property_names) > 0); + g_free (name_owner); + g_strfreev (property_names); + + /* if we create another proxy with the service being available, check that + * it has a name owner and properties + */ + error = NULL; + p2 = g_dbus_proxy_new_sync (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo* */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + name_owner = g_dbus_proxy_get_name_owner (p2); + property_names = g_dbus_proxy_get_cached_property_names (p2); + g_assert (g_dbus_is_unique_name (name_owner)); + g_assert (property_names != NULL && g_strv_length (property_names) > 0); + g_free (name_owner); + g_strfreev (property_names); + + /* also for async: we should have a name owner and cached properties */ + g_dbus_proxy_new (c, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo* */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + NULL, /* GCancellable */ + (GAsyncReadyCallback) proxy_new_cb, + &ap2); + g_main_loop_run (loop); + name_owner = g_dbus_proxy_get_name_owner (ap2); + property_names = g_dbus_proxy_get_cached_property_names (ap2); + g_assert (g_dbus_is_unique_name (name_owner)); + g_assert (property_names != NULL && g_strv_length (property_names) > 0); + g_free (name_owner); + g_strfreev (property_names); + + /* Check property value is the initial value */ + variant = g_dbus_proxy_get_cached_property (p, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 1); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (p2, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 1); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (ap, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 1); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (ap2, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 1); + g_variant_unref (variant); + + /* Check that properties are updated on both p and p2 */ + result = g_dbus_proxy_call_sync (p, + "FrobSetProperty", + g_variant_new ("(sv)", + "y", + g_variant_new_byte (42)), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + _g_assert_signal_received (p, "g-properties-changed"); + variant = g_dbus_proxy_get_cached_property (p, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 42); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (p2, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 42); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (ap, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 42); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (ap2, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 42); + g_variant_unref (variant); + + /* Nuke the service and check that we get the signal and then don't + * have a name owner nor any cached properties + */ + result = g_dbus_proxy_call_sync (p, + "Quit", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + /* and wait... */ + _g_assert_property_notify (p, "g-name-owner"); + /* now we shouldn't have a name owner nor any cached properties */ + g_assert_cmpstr (g_dbus_proxy_get_name_owner (p), ==, NULL); + g_assert (g_dbus_proxy_get_cached_property_names (p) == NULL); + g_assert (g_dbus_proxy_get_cached_property (p, "y") == NULL); + + /* now bring back the server and wait for the proxy to be updated.. now + * the 'y' property should be back at 1... + */ + /* this is safe; testserver will exit once the bus goes away */ + g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + + /* check that we get the notify::g-name-owner signal */ + _g_assert_property_notify (p, "g-name-owner"); + /* Now we should have a name owner as well as properties */ + name_owner = g_dbus_proxy_get_name_owner (p); + property_names = g_dbus_proxy_get_cached_property_names (p); + g_assert (g_dbus_is_unique_name (name_owner)); + g_assert (property_names != NULL && g_strv_length (property_names) > 0); + g_free (name_owner); + g_strfreev (property_names); + /* and finally check the 'y' property */ + variant = g_dbus_proxy_get_cached_property (p, "y"); + g_assert (variant != NULL); + g_assert_cmpint (g_variant_get_byte (variant), ==, 1); + g_variant_unref (variant); + + g_object_unref (p2); + g_object_unref (p); + g_object_unref (ap2); + g_object_unref (ap); + + g_object_unref (c); + + /* tear down bus */ + session_bus_down (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, NULL); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_dbus_unset (); + + g_test_add_func ("/gdbus/proxy-well-known-name", test_proxy_well_known_name); + + ret = g_test_run(); + return ret; +} diff --git a/gio/tests/gdbus-proxy.c b/gio/tests/gdbus-proxy.c new file mode 100644 index 0000000..eed75ac --- /dev/null +++ b/gio/tests/gdbus-proxy.c @@ -0,0 +1,1039 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a shared mainloop */ +static GMainLoop *loop = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that the method aspects of GDBusProxy works */ +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_methods (GDBusProxy *proxy) +{ + GVariant *result; + GError *error; + const gchar *str; + gchar *dbus_error_name; + + /* check that we can invoke a method */ + error = NULL; + result = g_dbus_proxy_call_sync (proxy, + "HelloWorld", + g_variant_new ("(s)", "Hey"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "(s)"); + g_variant_get (result, "(&s)", &str); + g_assert_cmpstr (str, ==, "You greeted me with 'Hey'. Thanks!"); + g_variant_unref (result); + + /* Check that we can completely recover the returned error */ + result = g_dbus_proxy_call_sync (proxy, + "HelloWorld", + g_variant_new ("(s)", "Yo"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR); + g_assert_true (g_dbus_error_is_remote_error (error)); + g_assert_true (g_dbus_error_is_remote_error (error)); + g_assert_null (result); + dbus_error_name = g_dbus_error_get_remote_error (error); + g_assert_cmpstr (dbus_error_name, ==, "com.example.TestException"); + g_free (dbus_error_name); + g_assert_true (g_dbus_error_strip_remote_error (error)); + g_assert_cmpstr (error->message, ==, "Yo is not a proper greeting"); + g_clear_error (&error); + + /* Check that we get a timeout if the method handling is taking longer than + * timeout. We use such a long sleep because on slow machines, if the + * sleep isn't much longer than the timeout and we're doing a parallel + * build, there's no guarantee we'll be scheduled in the window between + * the timeout being hit and the sleep finishing. */ + error = NULL; + result = g_dbus_proxy_call_sync (proxy, + "Sleep", + g_variant_new ("(i)", 10000 /* msec */), + G_DBUS_CALL_FLAGS_NONE, + 100 /* msec */, + NULL, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_assert_null (result); + g_clear_error (&error); + + /* Check that proxy-default timeouts work. */ + g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, -1); + + /* the default timeout is 25000 msec so this should work */ + result = g_dbus_proxy_call_sync (proxy, + "Sleep", + g_variant_new ("(i)", 500 /* msec */), + G_DBUS_CALL_FLAGS_NONE, + -1, /* use proxy default (e.g. -1 -> e.g. 25000 msec) */ + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + + /* Now set the proxy-default timeout to 250 msec and try the 10000 msec + * call - this should FAIL. Again, we use such a long sleep because on slow + * machines there's no guarantee we'll be scheduled when we want to be. */ + g_dbus_proxy_set_default_timeout (proxy, 250); + g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, 250); + result = g_dbus_proxy_call_sync (proxy, + "Sleep", + g_variant_new ("(i)", 10000 /* msec */), + G_DBUS_CALL_FLAGS_NONE, + -1, /* use proxy default (e.g. 250 msec) */ + NULL, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_assert_null (result); + g_clear_error (&error); + + /* clean up after ourselves */ + g_dbus_proxy_set_default_timeout (proxy, -1); +} + +static gboolean +strv_equal (gchar **strv, ...) +{ + gsize count; + va_list list; + const gchar *str; + gboolean res; + + res = TRUE; + count = 0; + va_start (list, strv); + while (1) + { + str = va_arg (list, const gchar *); + if (str == NULL) + break; + if (g_strcmp0 (str, strv[count]) != 0) + { + res = FALSE; + break; + } + count++; + } + va_end (list); + + if (res) + res = g_strv_length (strv) == count; + + return res; +} + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that the property aspects of GDBusProxy works */ +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_properties (GDBusProxy *proxy) +{ + GError *error; + GVariant *variant; + GVariant *variant2; + GVariant *result; + gchar **names; + gchar *name_owner; + GDBusProxy *proxy2; + + error = NULL; + + if (g_dbus_proxy_get_flags (proxy) & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) + { + g_assert_null (g_dbus_proxy_get_cached_property_names (proxy)); + return; + } + + /* + * Check that we can list all cached properties. + */ + names = g_dbus_proxy_get_cached_property_names (proxy); + + g_assert_true (strv_equal (names, + "PropertyThatWillBeInvalidated", + "ab", + "ad", + "ai", + "an", + "ao", + "aq", + "as", + "at", + "au", + "ax", + "ay", + "b", + "d", + "foo", + "i", + "n", + "o", + "q", + "s", + "t", + "u", + "x", + "y", + NULL)); + + g_strfreev (names); + + /* + * Check that we can read cached properties. + * + * No need to test all properties - GVariant has already been tested + */ + variant = g_dbus_proxy_get_cached_property (proxy, "y"); + g_assert_nonnull (variant); + g_assert_cmpint (g_variant_get_byte (variant), ==, 1); + g_variant_unref (variant); + variant = g_dbus_proxy_get_cached_property (proxy, "o"); + g_assert_nonnull (variant); + g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "/some/path"); + g_variant_unref (variant); + + /* + * Now ask the service to change a property and check that #GDBusProxy::g-property-changed + * is received. Also check that the cache is updated. + */ + variant2 = g_variant_new_byte (42); + result = g_dbus_proxy_call_sync (proxy, + "FrobSetProperty", + g_variant_new ("(sv)", + "y", + variant2), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + _g_assert_signal_received (proxy, "g-properties-changed"); + variant = g_dbus_proxy_get_cached_property (proxy, "y"); + g_assert_nonnull (variant); + g_assert_cmpint (g_variant_get_byte (variant), ==, 42); + g_variant_unref (variant); + + g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (142)); + variant = g_dbus_proxy_get_cached_property (proxy, "y"); + g_assert_nonnull (variant); + g_assert_cmpint (g_variant_get_byte (variant), ==, 142); + g_variant_unref (variant); + + g_dbus_proxy_set_cached_property (proxy, "y", NULL); + variant = g_dbus_proxy_get_cached_property (proxy, "y"); + g_assert_null (variant); + + /* Check that the invalidation feature of the PropertiesChanged() + * signal works... First, check that we have a cached value of the + * property (from the initial GetAll() call) + */ + variant = g_dbus_proxy_get_cached_property (proxy, "PropertyThatWillBeInvalidated"); + g_assert_nonnull (variant); + g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "InitialValue"); + g_variant_unref (variant); + /* now ask to invalidate the property - this causes a + * + * PropertiesChanaged("com.example.Frob", + * {}, + * ["PropertyThatWillBeInvalidated") + * + * signal to be emitted. This is received before the method reply + * for FrobInvalidateProperty *but* since the proxy was created in + * the same thread as we're doing this synchronous call, we'll get + * the method reply before... + */ + result = g_dbus_proxy_call_sync (proxy, + "FrobInvalidateProperty", + g_variant_new ("(s)", "OMGInvalidated"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + /* ... hence we wait for the g-properties-changed signal to be delivered */ + _g_assert_signal_received (proxy, "g-properties-changed"); + /* ... and now we finally, check that the cached value has been invalidated */ + variant = g_dbus_proxy_get_cached_property (proxy, "PropertyThatWillBeInvalidated"); + g_assert_null (variant); + + /* Now test that G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES works - we need a new proxy for that */ + error = NULL; + proxy2 = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy), + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + NULL, /* GDBusInterfaceInfo */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + name_owner = g_dbus_proxy_get_name_owner (proxy2); + g_assert_nonnull (name_owner); + g_free (name_owner); + + variant = g_dbus_proxy_get_cached_property (proxy2, "PropertyThatWillBeInvalidated"); + g_assert_nonnull (variant); + g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "OMGInvalidated"); /* from previous test */ + g_variant_unref (variant); + + result = g_dbus_proxy_call_sync (proxy2, + "FrobInvalidateProperty", + g_variant_new ("(s)", "OMGInvalidated2"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + + /* this time we should get the ::g-properties-changed _with_ the value */ + _g_assert_signal_received (proxy2, "g-properties-changed"); + + variant = g_dbus_proxy_get_cached_property (proxy2, "PropertyThatWillBeInvalidated"); + g_assert_nonnull (variant); + g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "OMGInvalidated2"); + g_variant_unref (variant); + + g_object_unref (proxy2); +} + +/* ---------------------------------------------------------------------------------------------------- */ +/* Test that the signal aspects of GDBusProxy works */ +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_proxy_signals_on_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GString *s = user_data; + + g_assert_cmpstr (signal_name, ==, "TestSignal"); + g_assert_cmpstr (g_variant_get_type_string (parameters), ==, "(sov)"); + + g_variant_print_string (parameters, s, TRUE); +} + +typedef struct +{ + GMainLoop *internal_loop; + GString *s; +} TestSignalData; + +static void +test_proxy_signals_on_emit_signal_cb (GDBusProxy *proxy, + GAsyncResult *res, + gpointer user_data) +{ + TestSignalData *data = user_data; + GError *error; + GVariant *result; + + error = NULL; + result = g_dbus_proxy_call_finish (proxy, + res, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + + /* check that the signal was received before we got the method result */ + g_assert_cmpuint (strlen (data->s->str), >, 0); + + /* break out of the loop */ + g_main_loop_quit (data->internal_loop); +} + +static void +test_signals (GDBusProxy *proxy) +{ + GError *error; + GString *s; + gulong signal_handler_id; + TestSignalData data; + GVariant *result; + + error = NULL; + + /* + * Ask the service to emit a signal and check that we receive it. + * + * Note that blocking calls don't block in the mainloop so wait for the signal (which + * is dispatched before the method reply) + */ + s = g_string_new (NULL); + signal_handler_id = g_signal_connect (proxy, + "g-signal", + G_CALLBACK (test_proxy_signals_on_signal), + s); + + result = g_dbus_proxy_call_sync (proxy, + "EmitSignal", + g_variant_new ("(so)", + "Accept the next proposition you hear", + "/some/path"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + /* check that we haven't received the signal just yet */ + g_assert_cmpuint (strlen (s->str), ==, 0); + /* and now wait for the signal */ + _g_assert_signal_received (proxy, "g-signal"); + g_assert_cmpstr (s->str, + ==, + "('Accept the next proposition you hear .. in bed!', objectpath '/some/path/in/bed', <'a variant'>)"); + g_signal_handler_disconnect (proxy, signal_handler_id); + g_string_free (s, TRUE); + + /* + * Now do this async to check the signal is received before the method returns. + */ + s = g_string_new (NULL); + data.internal_loop = g_main_loop_new (NULL, FALSE); + data.s = s; + signal_handler_id = g_signal_connect (proxy, + "g-signal", + G_CALLBACK (test_proxy_signals_on_signal), + s); + g_dbus_proxy_call (proxy, + "EmitSignal", + g_variant_new ("(so)", + "You will make a great programmer", + "/some/other/path"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) test_proxy_signals_on_emit_signal_cb, + &data); + g_main_loop_run (data.internal_loop); + g_main_loop_unref (data.internal_loop); + g_assert_cmpstr (s->str, + ==, + "('You will make a great programmer .. in bed!', objectpath '/some/other/path/in/bed', <'a variant'>)"); + g_signal_handler_disconnect (proxy, signal_handler_id); + g_string_free (s, TRUE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_bogus_method_return (GDBusProxy *proxy) +{ + GError *error = NULL; + GVariant *result; + + result = g_dbus_proxy_call_sync (proxy, + "PairReturn", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_error_free (error); + g_assert_null (result); +} + +#if 0 /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999 */ +static void +test_bogus_signal (GDBusProxy *proxy) +{ + GError *error = NULL; + GVariant *result; + GDBusInterfaceInfo *old_iface_info; + + result = g_dbus_proxy_call_sync (proxy, + "EmitSignal2", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + + if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR)) + { + /* and now wait for the signal that will never arrive */ + _g_assert_signal_received (proxy, "g-signal"); + } + g_test_trap_assert_stderr ("*Dropping signal TestSignal2 of type (i) since the type from the expected interface is (u)*"); + g_test_trap_assert_failed(); + + /* Our main branch will also do g_warning() when running the mainloop so + * temporarily remove the expected interface + */ + old_iface_info = g_dbus_proxy_get_interface_info (proxy); + g_dbus_proxy_set_interface_info (proxy, NULL); + _g_assert_signal_received (proxy, "g-signal"); + g_dbus_proxy_set_interface_info (proxy, old_iface_info); +} + +static void +test_bogus_property (GDBusProxy *proxy) +{ + GError *error = NULL; + GVariant *result; + GDBusInterfaceInfo *old_iface_info; + + /* Make the service emit a PropertiesChanged signal for property 'i' of type 'i' - since + * our introspection data has this as type 'u' we should get a warning on stderr. + */ + result = g_dbus_proxy_call_sync (proxy, + "FrobSetProperty", + g_variant_new ("(sv)", + "i", g_variant_new_int32 (42)), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + + if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR)) + { + /* and now wait for the signal that will never arrive */ + _g_assert_signal_received (proxy, "g-properties-changed"); + } + g_test_trap_assert_stderr ("*Received property i with type i does not match expected type u in the expected interface*"); + g_test_trap_assert_failed(); + + /* Our main branch will also do g_warning() when running the mainloop so + * temporarily remove the expected interface + */ + old_iface_info = g_dbus_proxy_get_interface_info (proxy); + g_dbus_proxy_set_interface_info (proxy, NULL); + _g_assert_signal_received (proxy, "g-properties-changed"); + g_dbus_proxy_set_interface_info (proxy, old_iface_info); +} +#endif /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999 */ + +/* ---------------------------------------------------------------------------------------------------- */ + +static const gchar *frob_dbus_interface_xml = + "" + " " + /* PairReturn() is deliberately different from gdbus-testserver's definition */ + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + /* We deliberately only mention a single property here */ + " " + /* The 'i' property is deliberately different from gdbus-testserver's definition */ + " " + /* ::TestSignal2 is deliberately different from gdbus-testserver's definition */ + " " + " " + " " + " " + ""; +static GDBusInterfaceInfo *frob_dbus_interface_info; + +static void +test_expected_interface (GDBusProxy *proxy) +{ + GVariant *value; + GError *error; + + /* This is obviously wrong but expected interface is not set so we don't fail... */ + g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_string ("error_me_out!")); + g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (42)); + g_dbus_proxy_set_cached_property (proxy, "does-not-exist", g_variant_new_string ("something")); + g_dbus_proxy_set_cached_property (proxy, "does-not-exist", NULL); + + /* Now repeat the method tests, with an expected interface set */ + g_dbus_proxy_set_interface_info (proxy, frob_dbus_interface_info); + test_methods (proxy); + test_signals (proxy); + + /* And also where we deliberately set the expected interface definition incorrectly */ + test_bogus_method_return (proxy); + /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999 + test_bogus_signal (proxy); + test_bogus_property (proxy); + */ + + if (g_test_undefined ()) + { + /* Also check that we complain if setting a cached property of the wrong type */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*Trying to set property y of type s but according to the expected interface the type is y*"); + value = g_variant_ref_sink (g_variant_new_string ("error_me_out!")); + g_dbus_proxy_set_cached_property (proxy, "y", value); + g_variant_unref (value); + g_test_assert_expected_messages (); + } + + /* this should work, however (since the type is correct) */ + g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (42)); + + if (g_test_undefined ()) + { + /* Try to get the value of a property where the type we expect is different from + * what we have in our cache (e.g. what the service returned) + */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*Trying to get property i with type i but according to the expected interface the type is u*"); + value = g_dbus_proxy_get_cached_property (proxy, "i"); + g_test_assert_expected_messages (); + } + + /* Even if a property does not exist in expected_interface, looking it + * up, or setting it, should never fail. Because it could be that the + * property has been added to the service but the GDBusInterfaceInfo* + * passed to g_dbus_proxy_set_interface_info() just haven't been updated. + * + * See https://bugzilla.gnome.org/show_bug.cgi?id=660886 + */ + value = g_dbus_proxy_get_cached_property (proxy, "d"); + g_assert_nonnull (value); + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); + g_assert_cmpfloat (g_variant_get_double (value), ==, 7.5); + g_variant_unref (value); + /* update it via the cached property... */ + g_dbus_proxy_set_cached_property (proxy, "d", g_variant_new_double (75.0)); + /* ... and finally check that it has changed */ + value = g_dbus_proxy_get_cached_property (proxy, "d"); + g_assert_nonnull (value); + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); + g_assert_cmpfloat (g_variant_get_double (value), ==, 75.0); + g_variant_unref (value); + /* now update it via the D-Bus interface... */ + error = NULL; + value = g_dbus_proxy_call_sync (proxy, "FrobSetProperty", + g_variant_new ("(sv)", "d", g_variant_new_double (85.0)), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (value); + g_assert_cmpstr (g_variant_get_type_string (value), ==, "()"); + g_variant_unref (value); + /* ...ensure we receive the ::PropertiesChanged signal... */ + _g_assert_signal_received (proxy, "g-properties-changed"); + /* ... and finally check that it has changed */ + value = g_dbus_proxy_get_cached_property (proxy, "d"); + g_assert_nonnull (value); + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); + g_assert_cmpfloat (g_variant_get_double (value), ==, 85.0); + g_variant_unref (value); +} + +static void +test_basic (GDBusProxy *proxy) +{ + GDBusConnection *connection; + GDBusConnection *conn; + GDBusProxyFlags flags; + GDBusInterfaceInfo *info; + gchar *name; + gchar *path; + gchar *interface; + gint timeout; + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + g_assert_true (g_dbus_proxy_get_connection (proxy) == connection); + g_assert_null (g_dbus_proxy_get_interface_info (proxy)); + g_assert_cmpstr (g_dbus_proxy_get_name (proxy), ==, "com.example.TestService"); + g_assert_cmpstr (g_dbus_proxy_get_object_path (proxy), ==, "/com/example/TestObject"); + g_assert_cmpstr (g_dbus_proxy_get_interface_name (proxy), ==, "com.example.Frob"); + g_assert_cmpint (g_dbus_proxy_get_default_timeout (proxy), ==, -1); + + g_object_get (proxy, + "g-connection", &conn, + "g-interface-info", &info, + "g-flags", &flags, + "g-name", &name, + "g-object-path", &path, + "g-interface-name", &interface, + "g-default-timeout", &timeout, + NULL); + + g_assert_true (conn == connection); + g_assert_null (info); + g_assert_cmpint (flags, ==, g_dbus_proxy_get_flags (proxy)); + g_assert_cmpstr (name, ==, "com.example.TestService"); + g_assert_cmpstr (path, ==, "/com/example/TestObject"); + g_assert_cmpstr (interface, ==, "com.example.Frob"); + g_assert_cmpint (timeout, ==, -1); + + g_object_unref (conn); + g_free (name); + g_free (path); + g_free (interface); + + g_object_unref (connection); +} + +static void +name_disappeared_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + gboolean *name_disappeared = user_data; + *name_disappeared = TRUE; + g_main_context_wakeup (NULL); +} + +static void +kill_test_service (GDBusConnection *connection) +{ +#ifdef G_OS_UNIX + guint pid; + GVariant *ret; + GError *error = NULL; + const gchar *name = "com.example.TestService"; + guint watch_id; + gboolean name_disappeared = FALSE; + + ret = g_dbus_connection_call_sync (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixProcessID", + g_variant_new ("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_variant_get (ret, "(u)", &pid); + g_variant_unref (ret); + + /* Watch the name and wait until it’s disappeared. */ + watch_id = g_bus_watch_name_on_connection (connection, name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, name_disappeared_cb, + &name_disappeared, NULL); + kill (pid, SIGTERM); + + while (!name_disappeared) + g_main_context_iteration (NULL, TRUE); + + g_bus_unwatch_name (watch_id); +#else + g_warning ("Can't kill com.example.TestService"); +#endif +} + +static void +test_proxy_with_flags (GDBusProxyFlags flags) +{ + GDBusProxy *proxy; + GDBusConnection *connection; + GError *error; + gchar *owner; + + error = NULL; + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, + NULL, + &error); + g_assert_no_error (error); + error = NULL; + proxy = g_dbus_proxy_new_sync (connection, + flags, + NULL, /* GDBusInterfaceInfo */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + /* this is safe; we explicitly kill the service later on */ + g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + + _g_assert_property_notify (proxy, "g-name-owner"); + + test_basic (proxy); + test_methods (proxy); + test_properties (proxy); + test_signals (proxy); + test_expected_interface (proxy); + + kill_test_service (connection); + + owner = g_dbus_proxy_get_name_owner (proxy); + g_assert_null (owner); + g_free (owner); + + g_object_unref (proxy); + g_object_unref (connection); +} + +static void +test_proxy (void) +{ + test_proxy_with_flags (G_DBUS_PROXY_FLAGS_NONE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +proxy_ready (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GDBusProxy *proxy; + GError *error; + gchar *owner; + + error = NULL; + proxy = g_dbus_proxy_new_for_bus_finish (result, &error); + g_assert_no_error (error); + + owner = g_dbus_proxy_get_name_owner (proxy); + g_assert_null (owner); + g_free (owner); + + /* this is safe; we explicitly kill the service later on */ + g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + + _g_assert_property_notify (proxy, "g-name-owner"); + + test_basic (proxy); + test_methods (proxy); + test_properties (proxy); + test_signals (proxy); + test_expected_interface (proxy); + + kill_test_service (g_dbus_proxy_get_connection (proxy)); + g_object_unref (proxy); + g_main_loop_quit (loop); +} + +static gboolean +fail_test (gpointer user_data) +{ + g_assert_not_reached (); +} + +static void +test_async (void) +{ + guint id; + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface */ + NULL, /* GCancellable */ + proxy_ready, + NULL); + + id = g_timeout_add (10000, fail_test, NULL); + g_main_loop_run (loop); + + g_source_remove (id); +} + +static void +test_no_properties (void) +{ + GDBusProxy *proxy; + GError *error; + + error = NULL; + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, /* GDBusInterfaceInfo */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + test_properties (proxy); + + g_object_unref (proxy); +} + +static void +check_error (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + GVariant *reply; + + reply = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_assert_null (reply); + g_error_free (error); + + g_main_loop_quit (loop); +} + +static void +test_wellknown_noauto (void) +{ + GError *error = NULL; + GDBusProxy *proxy; + guint id; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, "some.name.that.does.not.exist", + "/", "some.interface", NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (proxy); + + g_dbus_proxy_call (proxy, "method", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, check_error, NULL); + id = g_timeout_add (10000, fail_test, NULL); + g_main_loop_run (loop); + g_object_unref (proxy); + g_source_remove (id); +} + +typedef enum { + ADD_MATCH, + REMOVE_MATCH, +} AddOrRemove; + +static void +add_or_remove_match_rule (GDBusConnection *connection, + AddOrRemove add_or_remove, + GVariant *match_rule) +{ + GDBusMessage *message = NULL; + GError *error = NULL; + + message = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */ + "/org/freedesktop/DBus", /* path */ + "org.freedesktop.DBus", /* interface */ + (add_or_remove == ADD_MATCH) ? "AddMatch" : "RemoveMatch"); + g_dbus_message_set_body (message, match_rule); + g_dbus_connection_send_message (connection, + message, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + NULL, + &error); + g_assert_no_error (error); + g_clear_object (&message); +} + +static void +test_proxy_no_match_rule (void) +{ + GDBusConnection *connection = NULL; + GVariant *match_rule = NULL; + + g_test_summary ("Test that G_DBUS_PROXY_FLAGS_NO_MATCH_RULE works"); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1109"); + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + /* Add a custom match rule which matches everything. */ + match_rule = g_variant_ref_sink (g_variant_new ("(s)", "type='signal'")); + add_or_remove_match_rule (connection, ADD_MATCH, match_rule); + + /* Run the tests. */ + test_proxy_with_flags (G_DBUS_PROXY_FLAGS_NO_MATCH_RULE); + + /* Remove the match rule again. */ + add_or_remove_match_rule (connection, REMOVE_MATCH, match_rule); + + g_clear_pointer (&match_rule, g_variant_unref); + g_clear_object (&connection); +} + +int +main (int argc, + char *argv[]) +{ + gint ret; + GDBusNodeInfo *introspection_data = NULL; + + g_test_init (&argc, &argv, NULL); + + introspection_data = g_dbus_node_info_new_for_xml (frob_dbus_interface_xml, NULL); + g_assert_nonnull (introspection_data); + frob_dbus_interface_info = introspection_data->interfaces[0]; + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_add_func ("/gdbus/proxy", test_proxy); + g_test_add_func ("/gdbus/proxy/no-properties", test_no_properties); + g_test_add_func ("/gdbus/proxy/wellknown-noauto", test_wellknown_noauto); + g_test_add_func ("/gdbus/proxy/async", test_async); + g_test_add_func ("/gdbus/proxy/no-match-rule", test_proxy_no_match_rule); + + ret = session_bus_run(); + + g_dbus_node_info_unref (introspection_data); + g_main_loop_unref (loop); + + return ret; +} diff --git a/gio/tests/gdbus-serialization.c b/gio/tests/gdbus-serialization.c new file mode 100644 index 0000000..7cc46a4 --- /dev/null +++ b/gio/tests/gdbus-serialization.c @@ -0,0 +1,1660 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include + +#include +#ifndef _MSC_VER +#include +#endif +#include + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +hexdump (const guchar *str, gsize len) +{ + const guchar *data = (const guchar *) str; + guint n, m; + + for (n = 0; n < len; n += 16) + { + g_printerr ("%04x: ", n); + + for (m = n; m < n + 16; m++) + { + if (m > n && (m%4) == 0) + g_printerr (" "); + if (m < len) + g_printerr ("%02x ", data[m]); + else + g_printerr (" "); + } + + g_printerr (" "); + + for (m = n; m < len && m < n + 16; m++) + g_printerr ("%c", g_ascii_isprint (data[m]) ? data[m] : '.'); + + g_printerr ("\n"); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +append_gv_to_dbus_iter (DBusMessageIter *iter, + GVariant *value, + GError **error) +{ + const GVariantType *type; + + type = g_variant_get_type (value); + if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN)) + { + dbus_bool_t v = g_variant_get_boolean (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE)) + { + guint8 v = g_variant_get_byte (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16)) + { + gint16 v = g_variant_get_int16 (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_INT16, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16)) + { + guint16 v = g_variant_get_uint16 (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT16, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) + { + gint32 v = g_variant_get_int32 (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32)) + { + guint32 v = g_variant_get_uint32 (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64)) + { + gint64 v = g_variant_get_int64 (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64)) + { + guint64 v = g_variant_get_uint64 (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE)) + { + gdouble v = g_variant_get_double (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) + { + const gchar *v = g_variant_get_string (value, NULL); + dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH)) + { + const gchar *v = g_variant_get_string (value, NULL); + dbus_message_iter_append_basic (iter, DBUS_TYPE_OBJECT_PATH, &v); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE)) + { + const gchar *v = g_variant_get_string (value, NULL); + dbus_message_iter_append_basic (iter, DBUS_TYPE_SIGNATURE, &v); + } + else if (g_variant_type_is_variant (type)) + { + DBusMessageIter sub; + GVariant *child; + + child = g_variant_get_child_value (value, 0); + dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, + g_variant_get_type_string (child), + &sub); + if (!append_gv_to_dbus_iter (&sub, child, error)) + { + g_variant_unref (child); + goto fail; + } + dbus_message_iter_close_container (iter, &sub); + g_variant_unref (child); + } + else if (g_variant_type_is_array (type)) + { + DBusMessageIter dbus_iter; + const gchar *type_string; + GVariantIter gv_iter; + GVariant *item; + + type_string = g_variant_get_type_string (value); + type_string++; /* skip the 'a' */ + + dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, + type_string, &dbus_iter); + g_variant_iter_init (&gv_iter, value); + + while ((item = g_variant_iter_next_value (&gv_iter))) + { + if (!append_gv_to_dbus_iter (&dbus_iter, item, error)) + { + goto fail; + } + } + + dbus_message_iter_close_container (iter, &dbus_iter); + } + else if (g_variant_type_is_tuple (type)) + { + DBusMessageIter dbus_iter; + GVariantIter gv_iter; + GVariant *item; + + dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, + NULL, &dbus_iter); + g_variant_iter_init (&gv_iter, value); + + while ((item = g_variant_iter_next_value (&gv_iter))) + { + if (!append_gv_to_dbus_iter (&dbus_iter, item, error)) + goto fail; + } + + dbus_message_iter_close_container (iter, &dbus_iter); + } + else if (g_variant_type_is_dict_entry (type)) + { + DBusMessageIter dbus_iter; + GVariant *key, *val; + + dbus_message_iter_open_container (iter, DBUS_TYPE_DICT_ENTRY, + NULL, &dbus_iter); + key = g_variant_get_child_value (value, 0); + if (!append_gv_to_dbus_iter (&dbus_iter, key, error)) + { + g_variant_unref (key); + goto fail; + } + g_variant_unref (key); + + val = g_variant_get_child_value (value, 1); + if (!append_gv_to_dbus_iter (&dbus_iter, val, error)) + { + g_variant_unref (val); + goto fail; + } + g_variant_unref (val); + + dbus_message_iter_close_container (iter, &dbus_iter); + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Error serializing GVariant with type-string '%s' to a D-Bus message", + g_variant_get_type_string (value)); + goto fail; + } + + return TRUE; + + fail: + return FALSE; +} + +static gboolean +append_gv_to_dbus_message (DBusMessage *message, + GVariant *value, + GError **error) +{ + gboolean ret; + guint n; + + ret = FALSE; + + if (value != NULL) + { + DBusMessageIter iter; + GVariantIter gv_iter; + GVariant *item; + + dbus_message_iter_init_append (message, &iter); + + g_variant_iter_init (&gv_iter, value); + n = 0; + while ((item = g_variant_iter_next_value (&gv_iter))) + { + if (!append_gv_to_dbus_iter (&iter, item, error)) + { + g_prefix_error (error, + "Error encoding in-arg %d: ", + n); + goto out; + } + n++; + } + } + + ret = TRUE; + + out: + return ret; +} + +static void +print_gv_dbus_message (GVariant *value) +{ + DBusMessage *message; + char *blob; + int blob_len; + GError *error; + + message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); + dbus_message_set_serial (message, 0x41); + dbus_message_set_path (message, "/foo/bar"); + dbus_message_set_member (message, "Member"); + + error = NULL; + if (!append_gv_to_dbus_message (message, value, &error)) + { + g_printerr ("Error printing GVariant as DBusMessage: %s", error->message); + g_error_free (error); + goto out; + } + + dbus_message_marshal (message, &blob, &blob_len); + g_printerr ("\n"); + hexdump ((guchar *) blob, blob_len); + out: + dbus_message_unref (message); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +dbus_1_message_append (GString *s, + guint indent, + DBusMessageIter *iter) +{ + gint arg_type; + DBusMessageIter sub; + + g_string_append_printf (s, "%*s", indent, ""); + + arg_type = dbus_message_iter_get_arg_type (iter); + switch (arg_type) + { + case DBUS_TYPE_BOOLEAN: + { + dbus_bool_t value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "bool: %s\n", value ? "true" : "false"); + break; + } + + case DBUS_TYPE_BYTE: + { + guchar value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "byte: 0x%02x\n", (guint) value); + break; + } + + case DBUS_TYPE_INT16: + { + gint16 value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "int16: %" G_GINT16_FORMAT "\n", value); + break; + } + + case DBUS_TYPE_UINT16: + { + guint16 value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "uint16: %" G_GUINT16_FORMAT "\n", value); + break; + } + + case DBUS_TYPE_INT32: + { + gint32 value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "int32: %" G_GINT32_FORMAT "\n", value); + break; + } + + case DBUS_TYPE_UINT32: + { + guint32 value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "uint32: %" G_GUINT32_FORMAT "\n", value); + break; + } + + case DBUS_TYPE_INT64: + { + gint64 value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "int64: %" G_GINT64_FORMAT "\n", value); + break; + } + + case DBUS_TYPE_UINT64: + { + guint64 value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "uint64: %" G_GUINT64_FORMAT "\n", value); + break; + } + + case DBUS_TYPE_DOUBLE: + { + gdouble value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "double: %f\n", value); + break; + } + + case DBUS_TYPE_STRING: + { + const gchar *value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "string: '%s'\n", value); + break; + } + + case DBUS_TYPE_OBJECT_PATH: + { + const gchar *value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "object_path: '%s'\n", value); + break; + } + + case DBUS_TYPE_SIGNATURE: + { + const gchar *value; + dbus_message_iter_get_basic (iter, &value); + g_string_append_printf (s, "signature: '%s'\n", value); + break; + } + +#ifdef DBUS_TYPE_UNIX_FD + case DBUS_TYPE_UNIX_FD: + { + /* unfortunately there's currently no way to get just the + * protocol value, since dbus_message_iter_get_basic() wants + * to be 'helpful' and dup the fd for the user... + */ + g_string_append (s, "unix-fd: (not extracted)\n"); + break; + } +#endif + + case DBUS_TYPE_VARIANT: + g_string_append_printf (s, "variant:\n"); + dbus_message_iter_recurse (iter, &sub); + while (dbus_message_iter_get_arg_type (&sub)) + { + dbus_1_message_append (s, indent + 2, &sub); + dbus_message_iter_next (&sub); + } + break; + + case DBUS_TYPE_ARRAY: + g_string_append_printf (s, "array:\n"); + dbus_message_iter_recurse (iter, &sub); + while (dbus_message_iter_get_arg_type (&sub)) + { + dbus_1_message_append (s, indent + 2, &sub); + dbus_message_iter_next (&sub); + } + break; + + case DBUS_TYPE_STRUCT: + g_string_append_printf (s, "struct:\n"); + dbus_message_iter_recurse (iter, &sub); + while (dbus_message_iter_get_arg_type (&sub)) + { + dbus_1_message_append (s, indent + 2, &sub); + dbus_message_iter_next (&sub); + } + break; + + case DBUS_TYPE_DICT_ENTRY: + g_string_append_printf (s, "dict_entry:\n"); + dbus_message_iter_recurse (iter, &sub); + while (dbus_message_iter_get_arg_type (&sub)) + { + dbus_1_message_append (s, indent + 2, &sub); + dbus_message_iter_next (&sub); + } + break; + + default: + g_printerr ("Error serializing D-Bus message to GVariant. Unsupported arg type '%c' (%d)", + arg_type, + arg_type); + g_assert_not_reached (); + break; + } +} + +static gchar * +dbus_1_message_print (DBusMessage *message) +{ + GString *s; + guint n; + DBusMessageIter iter; + + s = g_string_new (NULL); + n = 0; + dbus_message_iter_init (message, &iter); + while (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) + { + g_string_append_printf (s, "value %d: ", n); + dbus_1_message_append (s, 2, &iter); + dbus_message_iter_next (&iter); + n++; + } + + return g_string_free (s, FALSE); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +get_body_signature (GVariant *value) +{ + const gchar *s; + gsize len; + gchar *ret; + + if (value == NULL) + { + ret = g_strdup (""); + goto out; + } + + s = g_variant_get_type_string (value); + len = strlen (s); + g_assert (len >= 2); + + ret = g_strndup (s + 1, len - 2); + + out: + return ret; +} + +/* If @value is floating, this assumes ownership. */ +static gchar * +get_and_check_serialization (GVariant *value) +{ + guchar *blob; + gsize blob_size; + DBusMessage *dbus_1_message; + GDBusMessage *message; + GDBusMessage *recovered_message; + GError *error; + DBusError dbus_error; + gchar *last_serialization = NULL; + gchar *s = NULL; + guint n; + + message = g_dbus_message_new (); + g_dbus_message_set_body (message, value); + g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL); + g_dbus_message_set_serial (message, 0x41); + s = get_body_signature (value); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, g_variant_new_object_path ("/foo/bar")); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, g_variant_new_string ("Member")); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, g_variant_new_signature (s)); + g_free (s); + + /* First check that the serialization to the D-Bus wire format is correct - do this for both byte orders */ + for (n = 0; n < 2; n++) + { + GDBusMessageByteOrder byte_order; + switch (n) + { + case 0: + byte_order = G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN; + break; + case 1: + byte_order = G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN; + break; + case 2: + g_assert_not_reached (); + break; + } + g_dbus_message_set_byte_order (message, byte_order); + + error = NULL; + blob = g_dbus_message_to_blob (message, + &blob_size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &error); + g_assert_no_error (error); + g_assert (blob != NULL); + + switch (byte_order) + { + case G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN: + g_assert_cmpint (blob[0], ==, 'B'); + break; + case G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN: + g_assert_cmpint (blob[0], ==, 'l'); + break; + } + + dbus_error_init (&dbus_error); + dbus_1_message = dbus_message_demarshal ((char *) blob, blob_size, &dbus_error); + if (dbus_error_is_set (&dbus_error)) + { + g_printerr ("Error calling dbus_message_demarshal() on this blob: %s: %s\n", + dbus_error.name, + dbus_error.message); + hexdump (blob, blob_size); + dbus_error_free (&dbus_error); + + s = g_variant_print (value, TRUE); + g_printerr ("\nThe blob was generated from the following GVariant value:\n%s\n\n", s); + g_free (s); + + g_printerr ("If the blob was encoded using DBusMessageIter, the payload would have been:\n"); + print_gv_dbus_message (value); + + g_assert_not_reached (); + } + + s = dbus_1_message_print (dbus_1_message); + dbus_message_unref (dbus_1_message); + + /* Then serialize back and check that the body is identical */ + + error = NULL; + recovered_message = g_dbus_message_new_from_blob (blob, + blob_size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &error); + g_assert_no_error (error); + g_assert (recovered_message != NULL); + + if (value == NULL) + { + g_assert (g_dbus_message_get_body (recovered_message) == NULL); + } + else + { + g_assert (g_dbus_message_get_body (recovered_message) != NULL); + g_assert_cmpvariant (g_dbus_message_get_body (recovered_message), value); + } + g_object_unref (recovered_message); + g_free (blob); + + if (last_serialization != NULL) + { + g_assert_cmpstr (last_serialization, ==, s); + g_free (last_serialization); + } + + last_serialization = g_steal_pointer (&s); + } + + g_object_unref (message); + + return g_steal_pointer (&last_serialization); +} + +/* If @value is floating, this assumes ownership. */ +static void +check_serialization (GVariant *value, + const gchar *expected_dbus_1_output) +{ + gchar *s = get_and_check_serialization (value); + g_assert_cmpstr (s, ==, expected_dbus_1_output); + g_free (s); +} + +static void +test_message_serialize_basic (void) +{ + check_serialization (NULL, ""); + + check_serialization (g_variant_new ("(sogybnqiuxtd)", + "this is a string", + "/this/is/a/path", + "sad", + 42, + TRUE, + -42, + 60000, + -44, + 100000, + -(G_GUINT64_CONSTANT(2)<<34), + G_GUINT64_CONSTANT(0xffffffffffffffff), + 42.5), + "value 0: string: 'this is a string'\n" + "value 1: object_path: '/this/is/a/path'\n" + "value 2: signature: 'sad'\n" + "value 3: byte: 0x2a\n" + "value 4: bool: true\n" + "value 5: int16: -42\n" + "value 6: uint16: 60000\n" + "value 7: int32: -44\n" + "value 8: uint32: 100000\n" + "value 9: int64: -34359738368\n" + "value 10: uint64: 18446744073709551615\n" + "value 11: double: 42.500000\n"); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_message_serialize_complex (void) +{ + GError *error; + GVariant *value; + guint i; + gchar *serialization = NULL; + + error = NULL; + + value = g_variant_parse (G_VARIANT_TYPE ("(aia{ss})"), + "([1, 2, 3], {'one': 'white', 'two': 'black'})", + NULL, NULL, &error); + g_assert_no_error (error); + g_assert (value != NULL); + check_serialization (value, + "value 0: array:\n" + " int32: 1\n" + " int32: 2\n" + " int32: 3\n" + "value 1: array:\n" + " dict_entry:\n" + " string: 'one'\n" + " string: 'white'\n" + " dict_entry:\n" + " string: 'two'\n" + " string: 'black'\n"); + g_variant_unref (value); + + value = g_variant_parse (G_VARIANT_TYPE ("(sa{sv}as)"), + "('01234567890123456', {}, ['Something'])", + NULL, NULL, &error); + g_assert_no_error (error); + g_assert (value != NULL); + check_serialization (value, + "value 0: string: '01234567890123456'\n" + "value 1: array:\n" + "value 2: array:\n" + " string: 'Something'\n"); + g_variant_unref (value); + + /* https://bugzilla.gnome.org/show_bug.cgi?id=621838 */ + check_serialization (g_variant_new_parsed ("(@aay [], {'cwd': <'/home/davidz/Hacking/glib/gio/tests'>})"), + "value 0: array:\n" + "value 1: array:\n" + " dict_entry:\n" + " string: 'cwd'\n" + " variant:\n" + " string: '/home/davidz/Hacking/glib/gio/tests'\n"); + +#ifdef DBUS_TYPE_UNIX_FD + value = g_variant_parse (G_VARIANT_TYPE ("(hah)"), + "(42, [43, 44])", + NULL, NULL, &error); + g_assert_no_error (error); + g_assert (value != NULL); + /* about (not extracted), see comment in DBUS_TYPE_UNIX_FD case in + * dbus_1_message_append() above. + */ + check_serialization (value, + "value 0: unix-fd: (not extracted)\n" + "value 1: array:\n" + " unix-fd: (not extracted)\n" + " unix-fd: (not extracted)\n"); + g_variant_unref (value); +#endif + + /* Deep nesting of variants (just below the recursion limit). */ + value = g_variant_new_string ("buried"); + for (i = 0; i < 64; i++) + value = g_variant_new_variant (value); + value = g_variant_new_tuple (&value, 1); + + serialization = get_and_check_serialization (value); + g_assert_nonnull (serialization); + g_assert_true (g_str_has_prefix (serialization, + "value 0: variant:\n" + " variant:\n" + " variant:\n")); + g_free (serialization); + + /* Deep nesting of arrays and structs (just below the recursion limit). + * See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-signature */ + value = g_variant_new_string ("hello"); + for (i = 0; i < 32; i++) + value = g_variant_new_tuple (&value, 1); + for (i = 0; i < 32; i++) + value = g_variant_new_array (NULL, &value, 1); + value = g_variant_new_tuple (&value, 1); + + serialization = get_and_check_serialization (value); + g_assert_nonnull (serialization); + g_assert_true (g_str_has_prefix (serialization, + "value 0: array:\n" + " array:\n" + " array:\n")); + g_free (serialization); +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +replace (char *blob, + gsize len, + const char *before, + const char *after) +{ + gsize i; + gsize slen = strlen (before) + 1; + + g_assert_cmpuint (strlen (before), ==, strlen (after)); + g_assert_cmpuint (len, >=, slen); + + for (i = 0; i < (len - slen + 1); i++) + { + if (memcmp (blob + i, before, slen) == 0) + memcpy (blob + i, after, slen); + } +} + +static void +test_message_serialize_invalid (void) +{ + guint n; + + /* Other things we could check (note that GDBus _does_ check for all + * these things - we just don't have test-suit coverage for it) + * + * - array exceeding 64 MiB (2^26 bytes) - unfortunately libdbus-1 checks + * this, e.g. + * + * process 19620: arguments to dbus_message_iter_append_fixed_array() were incorrect, + * assertion "n_elements <= DBUS_MAXIMUM_ARRAY_LENGTH / _dbus_type_get_alignment (element_type)" + * failed in file dbus-message.c line 2344. + * This is normally a bug in some application using the D-Bus library. + * D-Bus not built with -rdynamic so unable to print a backtrace + * Aborted (core dumped) + * + * - message exceeding 128 MiB (2^27 bytes) + * + * - endianness, message type, flags, protocol version + */ + + for (n = 0; n < 3; n++) + { + GDBusMessage *message; + GError *error; + DBusMessage *dbus_message; + char *blob; + int blob_len; + /* these are in pairs with matching length */ + const gchar *valid_utf8_str = "this is valid..."; + const gchar *invalid_utf8_str = "this is invalid\xff"; + const gchar *valid_signature = "a{sv}a{sv}a{sv}aiai"; + const gchar *invalid_signature = "not valid signature"; + const gchar *valid_object_path = "/this/is/a/valid/dbus/object/path"; + const gchar *invalid_object_path = "/this/is/not a valid object path!"; + + dbus_message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); + dbus_message_set_serial (dbus_message, 0x41); + dbus_message_set_path (dbus_message, "/foo/bar"); + dbus_message_set_member (dbus_message, "Member"); + switch (n) + { + case 0: + /* invalid UTF-8 */ + dbus_message_append_args (dbus_message, + DBUS_TYPE_STRING, &valid_utf8_str, + DBUS_TYPE_INVALID); + break; + + case 1: + /* invalid object path */ + dbus_message_append_args (dbus_message, + DBUS_TYPE_OBJECT_PATH, &valid_object_path, + DBUS_TYPE_INVALID); + break; + + case 2: + /* invalid signature */ + dbus_message_append_args (dbus_message, + DBUS_TYPE_SIGNATURE, &valid_signature, + DBUS_TYPE_INVALID); + break; + + default: + g_assert_not_reached (); + break; + } + dbus_message_marshal (dbus_message, &blob, &blob_len); + /* hack up the message to be invalid by replacing each valid string + * with its invalid counterpart */ + replace (blob, blob_len, valid_utf8_str, invalid_utf8_str); + replace (blob, blob_len, valid_object_path, invalid_object_path); + replace (blob, blob_len, valid_signature, invalid_signature); + + error = NULL; + message = g_dbus_message_new_from_blob ((guchar *) blob, + blob_len, + G_DBUS_CAPABILITY_FLAGS_NONE, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_error_free (error); + g_assert (message == NULL); + + dbus_free (blob); + dbus_message_unref (dbus_message); + } + +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_message_serialize_header_checks (void) +{ + GDBusMessage *message; + GDBusMessage *reply; + GError *error = NULL; + guchar *blob; + gsize blob_size; + + /* + * check we can't serialize messages with INVALID type + */ + message = g_dbus_message_new (); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: type is INVALID"); + g_clear_error (&error); + g_assert_null (blob); + g_object_unref (message); + + /* + * check that we can't serialize messages with SIGNATURE set to a non-signature-typed value + */ + message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember"); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, g_variant_new_boolean (FALSE)); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Signature header found but is not of type signature"); + g_assert_null (blob); + + g_clear_error (&error); + g_clear_object (&message); + + /* + * check we can't serialize signal messages with INTERFACE, PATH or MEMBER unset / set to reserved value + */ + message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember"); + /* ----- */ + /* interface NULL => error */ + g_dbus_message_set_interface (message, NULL); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"); + g_clear_error (&error); + g_assert_null (blob); + /* interface reserved value => error */ + g_dbus_message_set_interface (message, "org.freedesktop.DBus.Local"); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local"); + g_clear_error (&error); + g_assert_null (blob); + /* reset interface */ + g_dbus_message_set_interface (message, "The.Interface"); + /* ----- */ + /* path NULL => error */ + g_dbus_message_set_path (message, NULL); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"); + g_clear_error (&error); + g_assert_null (blob); + /* path reserved value => error */ + g_dbus_message_set_path (message, "/org/freedesktop/DBus/Local"); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local"); + g_clear_error (&error); + g_assert_null (blob); + /* reset path */ + g_dbus_message_set_path (message, "/the/path"); + /* ----- */ + /* member NULL => error */ + g_dbus_message_set_member (message, NULL); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: PATH, INTERFACE or MEMBER header field is missing"); + g_clear_error (&error); + g_assert_null (blob); + /* reset member */ + g_dbus_message_set_member (message, "TheMember"); + /* ----- */ + /* done */ + g_object_unref (message); + + /* + * check that we can't serialize method call messages with PATH or MEMBER unset + */ + message = g_dbus_message_new_method_call (NULL, "/the/path", NULL, "TheMember"); + /* ----- */ + /* path NULL => error */ + g_dbus_message_set_path (message, NULL); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_CALL message: PATH or MEMBER header field is missing"); + g_clear_error (&error); + g_assert_null (blob); + /* reset path */ + g_dbus_message_set_path (message, "/the/path"); + /* ----- */ + /* member NULL => error */ + g_dbus_message_set_member (message, NULL); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_CALL message: PATH or MEMBER header field is missing"); + g_clear_error (&error); + g_assert_null (blob); + /* reset member */ + g_dbus_message_set_member (message, "TheMember"); + /* ----- */ + /* done */ + g_object_unref (message); + + /* + * check that we can't serialize method reply messages with REPLY_SERIAL unset + */ + message = g_dbus_message_new_method_call (NULL, "/the/path", NULL, "TheMember"); + g_dbus_message_set_serial (message, 42); + /* method reply */ + reply = g_dbus_message_new_method_reply (message); + g_assert_cmpint (g_dbus_message_get_reply_serial (reply), ==, 42); + g_dbus_message_set_header (reply, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, NULL); + blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: METHOD_RETURN message: REPLY_SERIAL header field is missing"); + g_clear_error (&error); + g_assert_null (blob); + g_object_unref (reply); + /* method error - first nuke ERROR_NAME, then REPLY_SERIAL */ + reply = g_dbus_message_new_method_error (message, "Some.Error.Name", "the message"); + g_assert_cmpint (g_dbus_message_get_reply_serial (reply), ==, 42); + /* nuke ERROR_NAME */ + g_dbus_message_set_error_name (reply, NULL); + blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"); + g_clear_error (&error); + g_assert_null (blob); + /* reset ERROR_NAME */ + g_dbus_message_set_error_name (reply, "Some.Error.Name"); + /* nuke REPLY_SERIAL */ + g_dbus_message_set_header (reply, G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, NULL); + blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing"); + g_clear_error (&error); + g_assert_null (blob); + g_object_unref (reply); + g_object_unref (message); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_message_parse_empty_arrays_of_arrays (void) +{ + GVariant *body; + GError *error = NULL; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=673612"); + /* These three-element array of empty arrays were previously read back as a + * two-element array of empty arrays, due to sometimes erroneously skipping + * four bytes to align for the eight-byte-aligned grandchild types (x and + * dict_entry). + */ + body = g_variant_parse (G_VARIANT_TYPE ("(aaax)"), + "([@aax [], [], []],)", NULL, NULL, &error); + g_assert_no_error (error); + check_serialization (body, + "value 0: array:\n" + " array:\n" + " array:\n" + " array:\n"); + g_variant_unref (body); + + body = g_variant_parse (G_VARIANT_TYPE ("(aaa{uu})"), + "([@aa{uu} [], [], []],)", NULL, NULL, &error); + g_assert_no_error (error); + check_serialization (body, + "value 0: array:\n" + " array:\n" + " array:\n" + " array:\n"); + g_variant_unref (body); + + /* Due to the same bug, g_dbus_message_new_from_blob() would fail for this + * message because it would try to read past the end of the string. Hence, + * sending this to an application would make it fall off the bus. */ + body = g_variant_parse (G_VARIANT_TYPE ("(a(aa{sv}as))"), + "([ ([], [])," + " ([], [])," + " ([], [])],)", NULL, NULL, &error); + g_assert_no_error (error); + check_serialization (body, + "value 0: array:\n" + " struct:\n" + " array:\n" + " array:\n" + " struct:\n" + " array:\n" + " array:\n" + " struct:\n" + " array:\n" + " array:\n"); + g_variant_unref (body); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_message_serialize_double_array (void) +{ + GVariantBuilder builder; + GVariant *body; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=732754"); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("ad")); + g_variant_builder_add (&builder, "d", (gdouble)0.0); + g_variant_builder_add (&builder, "d", (gdouble)8.0); + g_variant_builder_add (&builder, "d", (gdouble)22.0); + g_variant_builder_add (&builder, "d", (gdouble)0.0); + body = g_variant_new ("(@ad)", g_variant_builder_end (&builder)); + check_serialization (body, + "value 0: array:\n" + " double: 0.000000\n" + " double: 8.000000\n" + " double: 22.000000\n" + " double: 0.000000\n"); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Test that an invalid header in a D-Bus message (specifically, with a type + * which doesn’t match what’s expected for the given header) is gracefully + * handled with an error rather than a crash. */ +static void +test_message_parse_non_signature_header (void) +{ + const guint8 data[] = { + 'l', /* little-endian byte order */ + 0x02, /* message type (method return) */ + 0x00, /* message flags (none) */ + 0x01, /* major protocol version */ + 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */ + 0x00, 0x00, 0x00, 0xbc, /* message serial */ + /* a{yv} of header fields: + * (things start to be invalid below here) */ + 0x10, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */ + 0x08, /* array key (SIGNATURE) */ + /* Variant array value: */ + 0x04, /* signature length */ + 'd', 0x00, 0x00, 'F', /* signature (invalid) */ + 0x00, /* nul terminator */ + /* (Variant array value payload missing) */ + /* alignment padding before the next header array element, as structs must + * be 8-aligned: */ + 0x00, + 0x05, /* array key (REPLY_SERIAL, required for method return messages) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'u', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + 0x00, 0x01, 0x02, 0x03, + /* (message body is zero-length) */ + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message); + + g_clear_error (&local_error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Test that an invalid header in a D-Bus message (specifically, containing a + * variant with an empty type signature) is gracefully handled with an error + * rather than a crash. */ +static void +test_message_parse_empty_signature_header (void) +{ + const guint8 data[] = { + 'l', /* little-endian byte order */ + 0x02, /* message type (method return) */ + 0x00, /* message flags (none) */ + 0x01, /* major protocol version */ + 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */ + 0x20, 0x20, 0x20, 0x20, /* message serial */ + /* a{yv} of header fields: + * (things start to be invalid below here) */ + 0x10, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */ + 0x20, /* array key (this is not currently a valid header field) */ + /* Variant array value: */ + 0x00, /* signature length */ + 0x00, /* nul terminator */ + /* (Variant array value payload missing) */ + /* alignment padding before the next header array element, as structs must + * be 8-aligned: */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, /* array key (REPLY_SERIAL, required for method return messages) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'u', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + 0x00, 0x01, 0x02, 0x03, + /* (message body is zero-length) */ + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message); + + g_clear_error (&local_error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Test that an invalid header in a D-Bus message (specifically, containing a + * variant with a type signature containing multiple complete types) is + * gracefully handled with an error rather than a crash. */ +static void +test_message_parse_multiple_signature_header (void) +{ + const guint8 data[] = { + 'l', /* little-endian byte order */ + 0x02, /* message type (method return) */ + 0x00, /* message flags (none) */ + 0x01, /* major protocol version */ + 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */ + 0x20, 0x20, 0x20, 0x20, /* message serial */ + /* a{yv} of header fields: + * (things start to be invalid below here) */ + 0x10, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */ + 0x20, /* array key (this is not currently a valid header field) */ + /* Variant array value: */ + 0x02, /* signature length */ + 'b', 'b', /* two complete types */ + 0x00, /* nul terminator */ + /* (Variant array value payload missing) */ + /* alignment padding before the next header array element, as structs must + * be 8-aligned: */ + 0x00, 0x00, 0x00, + 0x05, /* array key (REPLY_SERIAL, required for method return messages) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'u', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + 0x00, 0x01, 0x02, 0x03, + /* (message body is zero-length) */ + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message); + + g_clear_error (&local_error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Test that an invalid header in a D-Bus message (specifically, containing a + * variant with a valid type signature that is too long to be a valid + * #GVariantType due to exceeding the array nesting limits) is gracefully + * handled with an error rather than a crash. */ +static void +test_message_parse_over_long_signature_header (void) +{ + const guint8 data[] = { + 'l', /* little-endian byte order */ + 0x02, /* message type (method return) */ + 0x00, /* message flags (none) */ + 0x01, /* major protocol version */ + 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */ + 0x20, 0x20, 0x20, 0x20, /* message serial */ + /* a{yv} of header fields: + * (things start to be invalid below here) */ + 0xa0, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */ + 0x08, /* array key (SIGNATURE) */ + /* Variant array value: */ + 0x04, /* signature length */ + 'g', 0x00, 0x20, 0x20, /* one complete type plus some rubbish */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + /* Critically, this contains 128 nested ‘a’s, which exceeds + * %G_VARIANT_MAX_RECURSION_DEPTH. */ + 0xec, + 'a', 'b', 'g', 'd', 'u', 'd', 'd', 'd', 'd', 'd', 'd', 'd', + 'd', 'd', 'd', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'v', + /* first header length is a multiple of 8 so no padding is needed */ + 0x05, /* array key (REPLY_SERIAL, required for method return messages) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'u', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + 0x00, 0x01, 0x02, 0x03, + /* (message body is zero-length) */ + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message); + + g_clear_error (&local_error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Test that an invalid header in a D-Bus message (specifically, containing too + * many levels of nested variant) is gracefully handled with an error rather + * than a crash. */ +static void +test_message_parse_deep_header_nesting (void) +{ + const guint8 data[] = { + 'l', /* little-endian byte order */ + 0x02, /* message type (method return) */ + 0x00, /* message flags (none) */ + 0x01, /* major protocol version */ + 0x00, 0x00, 0x00, 0x00, /* body length (in bytes) */ + 0x20, 0x20, 0x20, 0x20, /* message serial */ + /* a{yv} of header fields: + * (things start to be invalid below here) */ + 0xd0, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */ + 0x20, /* array key (this is not currently a valid header field) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'v', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + /* Critically, this contains 64 nested variants (minus two for the + * ‘arbitrary valid content’ below, but ignoring two for the `a{yv}` + * above), which in total exceeds %G_DBUS_MAX_TYPE_DEPTH. */ + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + /* Some arbitrary valid content inside the innermost variant: */ + 0x01, 'y', 0x00, 0xcc, + /* no padding needed as this header element length is a multiple of 8 */ + 0x05, /* array key (REPLY_SERIAL, required for method return messages) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'u', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + 0x00, 0x01, 0x02, 0x03, + /* (message body is zero-length) */ + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message); + + g_clear_error (&local_error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* Test that an invalid body in a D-Bus message (specifically, containing too + * many levels of nested variant) is gracefully handled with an error rather + * than a crash. The set of bytes here are a modified version of the bytes from + * test_message_parse_deep_header_nesting(). */ +static void +test_message_parse_deep_body_nesting (void) +{ + const guint8 data[] = { + 'l', /* little-endian byte order */ + 0x02, /* message type (method return) */ + 0x00, /* message flags (none) */ + 0x01, /* major protocol version */ + 0xc4, 0x00, 0x00, 0x00, /* body length (in bytes) */ + 0x20, 0x20, 0x20, 0x20, /* message serial */ + /* a{yv} of header fields: */ + 0x10, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */ + 0x08, /* array key (SIGNATURE) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'g', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + 0x01, 'v', 0x00, + /* alignment padding before the next header array element, as structs must + * be 8-aligned: */ + 0x00, + 0x05, /* array key (REPLY_SERIAL, required for method return messages) */ + /* Variant array value: */ + 0x01, /* signature length */ + 'u', /* one complete type */ + 0x00, /* nul terminator */ + /* (Variant array value payload) */ + 0x00, 0x01, 0x02, 0x03, + /* Message body: over 64 levels of nested variant, which is not valid: */ + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, 0x01, 'v', 0x00, + /* Some arbitrary valid content inside the innermost variant: */ + 0x01, 'y', 0x00, 0xcc, + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message); + + g_clear_error (&local_error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_message_parse_truncated (void) +{ + GDBusMessage *message = NULL; + GDBusMessage *message2 = NULL; + GVariantBuilder builder; + guchar *blob = NULL; + gsize size = 0; + GError *error = NULL; + + g_test_summary ("Test that truncated messages are properly rejected."); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2528"); + + message = g_dbus_message_new (); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(asbynqiuxtd)")); + g_variant_builder_open (&builder, G_VARIANT_TYPE ("as")); + g_variant_builder_add (&builder, "s", "fourtytwo"); + g_variant_builder_close (&builder); + g_variant_builder_add (&builder, "b", TRUE); + g_variant_builder_add (&builder, "y", 42); + g_variant_builder_add (&builder, "n", 42); + g_variant_builder_add (&builder, "q", 42); + g_variant_builder_add (&builder, "i", 42); + g_variant_builder_add (&builder, "u", 42); + g_variant_builder_add (&builder, "x", 42); + g_variant_builder_add (&builder, "t", 42); + g_variant_builder_add (&builder, "d", (gdouble) 42); + + g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, + g_variant_new_object_path ("/foo/bar")); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, + g_variant_new_string ("Member")); + g_dbus_message_set_body (message, g_variant_builder_end (&builder)); + + blob = g_dbus_message_to_blob (message, &size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_no_error (error); + + g_clear_object (&message); + + /* Try parsing all possible prefixes of the full @blob. */ + for (gsize i = 0; i < size; i++) + { + message2 = g_dbus_message_new_from_blob (blob, i, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (message2); + g_clear_error (&error); + } + + message2 = g_dbus_message_new_from_blob (blob, size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + g_assert_no_error (error); + g_assert_true (G_IS_DBUS_MESSAGE (message2)); + g_clear_object (&message2); + + g_free (blob); +} + +static void +test_message_parse_empty_structure (void) +{ + const guint8 data[] = + { + 'l', /* little-endian byte order */ + 0x02, /* message type (method return) */ + 0x00, /* message flags (none) */ + 0x01, /* major protocol version */ + 0x08, 0x00, 0x00, 0x00, /* body length (in bytes) */ + 0x00, 0x00, 0x00, 0x00, /* message serial */ + /* a{yv} of header fields */ + 0x20, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */ + 0x01, /* array key (PATH) */ + 0x01, /* signature length */ + 'o', /* type (OBJECT_PATH) */ + 0x00, /* nul terminator */ + 0x05, 0x00, 0x00, 0x00, /* length 5 */ + '/', 'p', 'a', 't', 'h', 0x00, 0x00, 0x00, /* string '/path' and padding */ + 0x03, /* array key (MEMBER) */ + 0x01, /* signature length */ + 's', /* type (STRING) */ + 0x00, /* nul terminator */ + 0x06, 0x00, 0x00, 0x00, /* length 6 */ + 'M', 'e', 'm', 'b', 'e', 'r', 0x00, 0x00, /* string 'Member' and padding */ + 0x08, /* array key (SIGNATURE) */ + 0x01, /* signature length */ + 'g', /* type (SIGNATURE) */ + 0x00, /* nul terminator */ + 0x03, /* length 3 */ + 'a', '(', ')', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* type 'a()' and padding */ + 0x08, 0x00, 0x00, 0x00, /* array length: 4 bytes */ + 0x00, 0x00, 0x00, 0x00, /* padding to 8 bytes */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* array data */ + 0x00 + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + g_test_summary ("Test that empty structures are rejected when parsing."); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2557"); + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (local_error->message, ==, "Empty structures (tuples) are not allowed in D-Bus"); + g_assert_null (message); + + g_clear_error (&local_error); +} + +static void +test_message_serialize_empty_structure (void) +{ + GDBusMessage *message; + GVariantBuilder builder; + gsize size = 0; + GError *local_error = NULL; + + g_test_summary ("Test that empty structures are rejected when serializing."); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2557"); + + message = g_dbus_message_new (); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a())")); + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a()")); + g_variant_builder_add (&builder, "()"); + g_variant_builder_close (&builder); + g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, + g_variant_new_object_path ("/path")); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, + g_variant_new_string ("Member")); + g_dbus_message_set_body (message, g_variant_builder_end (&builder)); + + g_dbus_message_to_blob (message, &size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (local_error->message, ==, "Empty structures (tuples) are not allowed in D-Bus"); + + g_clear_error (&local_error); + g_clear_object (&message); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + g_setenv ("LC_ALL", "C", TRUE); + setlocale (LC_ALL, "C"); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gdbus/message-serialize/basic", + test_message_serialize_basic); + g_test_add_func ("/gdbus/message-serialize/complex", + test_message_serialize_complex); + g_test_add_func ("/gdbus/message-serialize/invalid", + test_message_serialize_invalid); + g_test_add_func ("/gdbus/message-serialize/header-checks", + test_message_serialize_header_checks); + g_test_add_func ("/gdbus/message-serialize/double-array", + test_message_serialize_double_array); + g_test_add_func ("/gdbus/message-serialize/empty-structure", + test_message_serialize_empty_structure); + + g_test_add_func ("/gdbus/message-parse/empty-arrays-of-arrays", + test_message_parse_empty_arrays_of_arrays); + g_test_add_func ("/gdbus/message-parse/non-signature-header", + test_message_parse_non_signature_header); + g_test_add_func ("/gdbus/message-parse/empty-signature-header", + test_message_parse_empty_signature_header); + g_test_add_func ("/gdbus/message-parse/multiple-signature-header", + test_message_parse_multiple_signature_header); + g_test_add_func ("/gdbus/message-parse/over-long-signature-header", + test_message_parse_over_long_signature_header); + g_test_add_func ("/gdbus/message-parse/deep-header-nesting", + test_message_parse_deep_header_nesting); + g_test_add_func ("/gdbus/message-parse/deep-body-nesting", + test_message_parse_deep_body_nesting); + g_test_add_func ("/gdbus/message-parse/truncated", + test_message_parse_truncated); + g_test_add_func ("/gdbus/message-parse/empty-structure", + test_message_parse_empty_structure); + + return g_test_run(); +} diff --git a/gio/tests/gdbus-server-auth.c b/gio/tests/gdbus-server-auth.c new file mode 100644 index 0000000..bd1443e --- /dev/null +++ b/gio/tests/gdbus-server-auth.c @@ -0,0 +1,554 @@ +/* + * Copyright 2019 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include + +#include +#include + +/* For G_CREDENTIALS_*_SUPPORTED */ +#include + +#ifdef HAVE_DBUS1 +#include +#endif + +typedef enum +{ + INTEROP_FLAGS_EXTERNAL = (1 << 0), + INTEROP_FLAGS_ANONYMOUS = (1 << 1), + INTEROP_FLAGS_SHA1 = (1 << 2), + INTEROP_FLAGS_TCP = (1 << 3), + INTEROP_FLAGS_LIBDBUS = (1 << 4), + INTEROP_FLAGS_ABSTRACT = (1 << 5), + INTEROP_FLAGS_REQUIRE_SAME_USER = (1 << 6), + INTEROP_FLAGS_NONE = 0 +} InteropFlags; + +static gboolean +allow_external_cb (G_GNUC_UNUSED GDBusAuthObserver *observer, + const char *mechanism, + G_GNUC_UNUSED gpointer user_data) +{ + if (g_strcmp0 (mechanism, "EXTERNAL") == 0) + { + g_debug ("Accepting EXTERNAL authentication"); + return TRUE; + } + else + { + g_debug ("Rejecting \"%s\" authentication: not EXTERNAL", mechanism); + return FALSE; + } +} + +static gboolean +allow_anonymous_cb (G_GNUC_UNUSED GDBusAuthObserver *observer, + const char *mechanism, + G_GNUC_UNUSED gpointer user_data) +{ + if (g_strcmp0 (mechanism, "ANONYMOUS") == 0) + { + g_debug ("Accepting ANONYMOUS authentication"); + return TRUE; + } + else + { + g_debug ("Rejecting \"%s\" authentication: not ANONYMOUS", mechanism); + return FALSE; + } +} + +static gboolean +allow_sha1_cb (G_GNUC_UNUSED GDBusAuthObserver *observer, + const char *mechanism, + G_GNUC_UNUSED gpointer user_data) +{ + if (g_strcmp0 (mechanism, "DBUS_COOKIE_SHA1") == 0) + { + g_debug ("Accepting DBUS_COOKIE_SHA1 authentication"); + return TRUE; + } + else + { + g_debug ("Rejecting \"%s\" authentication: not DBUS_COOKIE_SHA1", + mechanism); + return FALSE; + } +} + +static gboolean +allow_any_mechanism_cb (G_GNUC_UNUSED GDBusAuthObserver *observer, + const char *mechanism, + G_GNUC_UNUSED gpointer user_data) +{ + g_debug ("Accepting \"%s\" authentication", mechanism); + return TRUE; +} + +static gboolean +authorize_any_authenticated_peer_cb (G_GNUC_UNUSED GDBusAuthObserver *observer, + G_GNUC_UNUSED GIOStream *stream, + GCredentials *credentials, + G_GNUC_UNUSED gpointer user_data) +{ + if (credentials == NULL) + { + g_debug ("Authorizing peer with no credentials"); + } + else + { + gchar *str = g_credentials_to_string (credentials); + + g_debug ("Authorizing peer with credentials: %s", str); + g_free (str); + } + + return TRUE; +} + +static GDBusMessage * +whoami_filter_cb (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + G_GNUC_UNUSED gpointer user_data) +{ + if (!incoming) + return message; + + if (g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL && + g_strcmp0 (g_dbus_message_get_member (message), "WhoAmI") == 0) + { + GDBusMessage *reply = g_dbus_message_new_method_reply (message); + gint64 uid = -1; + gint64 pid = -1; +#ifdef G_OS_UNIX + GCredentials *credentials = g_dbus_connection_get_peer_credentials (connection); + + if (credentials != NULL) + { + uid = (gint64) g_credentials_get_unix_user (credentials, NULL); + pid = (gint64) g_credentials_get_unix_pid (credentials, NULL); + } +#endif + + g_dbus_message_set_body (reply, + g_variant_new ("(xx)", uid, pid)); + g_dbus_connection_send_message (connection, reply, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + NULL, NULL); + g_object_unref (reply); + + /* handled */ + g_object_unref (message); + return NULL; + } + + return message; +} + +static gboolean +new_connection_cb (G_GNUC_UNUSED GDBusServer *server, + GDBusConnection *connection, + G_GNUC_UNUSED gpointer user_data) +{ + GCredentials *credentials = g_dbus_connection_get_peer_credentials (connection); + + if (credentials == NULL) + { + g_debug ("New connection from peer with no credentials"); + } + else + { + gchar *str = g_credentials_to_string (credentials); + + g_debug ("New connection from peer with credentials: %s", str); + g_free (str); + } + + g_object_ref (connection); + g_dbus_connection_add_filter (connection, whoami_filter_cb, NULL, NULL); + return TRUE; +} + +#ifdef HAVE_DBUS1 +typedef struct +{ + DBusError error; + DBusConnection *conn; + DBusMessage *call; + DBusMessage *reply; +} LibdbusCall; + +static void +libdbus_call_task_cb (GTask *task, + G_GNUC_UNUSED gpointer source_object, + gpointer task_data, + G_GNUC_UNUSED GCancellable *cancellable) +{ + LibdbusCall *libdbus_call = task_data; + + libdbus_call->reply = dbus_connection_send_with_reply_and_block (libdbus_call->conn, + libdbus_call->call, + -1, + &libdbus_call->error); +} +#endif /* HAVE_DBUS1 */ + +static void +store_result_cb (G_GNUC_UNUSED GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GAsyncResult **result = user_data; + + g_assert_nonnull (result); + g_assert_null (*result); + *result = g_object_ref (res); +} + +static void +assert_expected_uid_pid (InteropFlags flags, + gint64 uid, + gint64 pid) +{ +#ifdef G_OS_UNIX + if (flags & (INTEROP_FLAGS_ANONYMOUS | INTEROP_FLAGS_SHA1 | INTEROP_FLAGS_TCP)) + { + /* No assertion. There is no guarantee whether credentials will be + * passed even though we didn't send them. Conversely, if + * credentials were not passed, + * g_dbus_connection_get_peer_credentials() always returns the + * credentials of the socket, and not the uid that a + * client might have proved it has by using DBUS_COOKIE_SHA1. */ + } + else /* We should prefer EXTERNAL whenever it is allowed. */ + { +#ifdef __linux__ + /* We know that both GDBus and libdbus support full credentials-passing + * on Linux. */ + g_assert_cmpint (uid, ==, getuid ()); + g_assert_cmpint (pid, ==, getpid ()); +#elif defined(__APPLE__) + /* We know (or at least suspect) that both GDBus and libdbus support + * passing the uid only on macOS. */ + g_assert_cmpint (uid, ==, getuid ()); + /* No pid here */ +#else + g_test_message ("Please open a merge request to add appropriate " + "assertions for your platform"); +#endif + } +#endif /* G_OS_UNIX */ +} + +static void +do_test_server_auth (InteropFlags flags) +{ + GError *error = NULL; + gchar *tmpdir = NULL; + gchar *listenable_address = NULL; + GDBusServer *server = NULL; + GDBusAuthObserver *observer = NULL; + GDBusServerFlags server_flags = G_DBUS_SERVER_FLAGS_RUN_IN_THREAD; + gchar *guid = NULL; + const char *connectable_address; + GDBusConnection *client = NULL; + GAsyncResult *result = NULL; + GVariant *tuple = NULL; + gint64 uid, pid; +#ifdef HAVE_DBUS1 + /* GNOME/glib#1831 seems to involve a race condition, so try a few times + * to see if we can trigger it. */ + gsize i; + gsize n = 20; +#endif + + if (flags & INTEROP_FLAGS_TCP) + { + listenable_address = g_strdup ("tcp:host=127.0.0.1"); + } + else + { +#ifdef G_OS_UNIX + gchar *escaped; + + tmpdir = g_dir_make_tmp ("gdbus-server-auth-XXXXXX", &error); + g_assert_no_error (error); + escaped = g_dbus_address_escape_value (tmpdir); + listenable_address = g_strdup_printf ("unix:%s=%s", + (flags & INTEROP_FLAGS_ABSTRACT) ? "tmpdir" : "dir", + escaped); + g_free (escaped); +#else + g_test_skip ("unix: addresses only work on Unix"); + goto out; +#endif + } + + g_test_message ("Testing GDBus server at %s / libdbus client, with flags: " + "external:%s " + "anonymous:%s " + "sha1:%s " + "abstract:%s " + "tcp:%s", + listenable_address, + (flags & INTEROP_FLAGS_EXTERNAL) ? "true" : "false", + (flags & INTEROP_FLAGS_ANONYMOUS) ? "true" : "false", + (flags & INTEROP_FLAGS_SHA1) ? "true" : "false", + (flags & INTEROP_FLAGS_ABSTRACT) ? "true" : "false", + (flags & INTEROP_FLAGS_TCP) ? "true" : "false"); + +#if !defined(G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED) \ + && !defined(G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED) + if (flags & INTEROP_FLAGS_EXTERNAL) + { + g_test_skip ("EXTERNAL authentication not implemented on this platform"); + goto out; + } +#endif + + if (flags & INTEROP_FLAGS_ANONYMOUS) + server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; + if (flags & INTEROP_FLAGS_REQUIRE_SAME_USER) + server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER; + + observer = g_dbus_auth_observer_new (); + + if (flags & INTEROP_FLAGS_EXTERNAL) + g_signal_connect (observer, "allow-mechanism", + G_CALLBACK (allow_external_cb), NULL); + else if (flags & INTEROP_FLAGS_ANONYMOUS) + g_signal_connect (observer, "allow-mechanism", + G_CALLBACK (allow_anonymous_cb), NULL); + else if (flags & INTEROP_FLAGS_SHA1) + g_signal_connect (observer, "allow-mechanism", + G_CALLBACK (allow_sha1_cb), NULL); + else + g_signal_connect (observer, "allow-mechanism", + G_CALLBACK (allow_any_mechanism_cb), NULL); + + g_signal_connect (observer, "authorize-authenticated-peer", + G_CALLBACK (authorize_any_authenticated_peer_cb), + NULL); + + guid = g_dbus_generate_guid (); + server = g_dbus_server_new_sync (listenable_address, + server_flags, + guid, + observer, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (server); + g_signal_connect (server, "new-connection", G_CALLBACK (new_connection_cb), NULL); + g_dbus_server_start (server); + connectable_address = g_dbus_server_get_client_address (server); + g_test_message ("Connectable address: %s", connectable_address); + + result = NULL; + g_dbus_connection_new_for_address (connectable_address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, NULL, store_result_cb, &result); + + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + + client = g_dbus_connection_new_for_address_finish (result, &error); + g_assert_no_error (error); + g_assert_nonnull (client); + g_clear_object (&result); + + g_dbus_connection_call (client, NULL, "/", "com.example.Test", "WhoAmI", + NULL, G_VARIANT_TYPE ("(xx)"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, store_result_cb, + &result); + + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + + tuple = g_dbus_connection_call_finish (client, result, &error); + g_assert_no_error (error); + g_assert_nonnull (tuple); + g_clear_object (&result); + g_clear_object (&client); + + uid = -2; + pid = -2; + g_variant_get (tuple, "(xx)", &uid, &pid); + + g_debug ("Server says GDBus client is uid %" G_GINT64_FORMAT ", pid %" G_GINT64_FORMAT, + uid, pid); + + assert_expected_uid_pid (flags, uid, pid); + + g_clear_pointer (&tuple, g_variant_unref); + +#ifdef HAVE_DBUS1 + for (i = 0; i < n; i++) + { + LibdbusCall libdbus_call = { DBUS_ERROR_INIT, NULL, NULL, NULL }; + GTask *task; + + /* The test suite uses %G_TEST_OPTION_ISOLATE_DIRS, which sets + * `HOME=/dev/null` and leaves g_get_home_dir() pointing to the per-test + * temp home directory. Unfortunately, libdbus doesn’t allow the home dir + * to be overridden except using the environment, so copy the per-test + * temp home directory back there so that libdbus uses the same + * `$HOME/.dbus-keyrings` path as GLib. This is not thread-safe. */ + g_setenv ("HOME", g_get_home_dir (), TRUE); + + libdbus_call.conn = dbus_connection_open_private (connectable_address, + &libdbus_call.error); + g_assert_cmpstr (libdbus_call.error.name, ==, NULL); + g_assert_nonnull (libdbus_call.conn); + + libdbus_call.call = dbus_message_new_method_call (NULL, "/", + "com.example.Test", + "WhoAmI"); + + if (libdbus_call.call == NULL) + g_error ("Out of memory"); + + result = NULL; + task = g_task_new (NULL, NULL, store_result_cb, &result); + g_task_set_task_data (task, &libdbus_call, NULL); + g_task_run_in_thread (task, libdbus_call_task_cb); + + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + + g_clear_object (&result); + + g_assert_cmpstr (libdbus_call.error.name, ==, NULL); + g_assert_nonnull (libdbus_call.reply); + + uid = -2; + pid = -2; + dbus_message_get_args (libdbus_call.reply, &libdbus_call.error, + DBUS_TYPE_INT64, &uid, + DBUS_TYPE_INT64, &pid, + DBUS_TYPE_INVALID); + g_assert_cmpstr (libdbus_call.error.name, ==, NULL); + + g_debug ("Server says libdbus client %" G_GSIZE_FORMAT " is uid %" G_GINT64_FORMAT ", pid %" G_GINT64_FORMAT, + i, uid, pid); + assert_expected_uid_pid (flags | INTEROP_FLAGS_LIBDBUS, uid, pid); + + dbus_connection_close (libdbus_call.conn); + dbus_connection_unref (libdbus_call.conn); + dbus_message_unref (libdbus_call.call); + dbus_message_unref (libdbus_call.reply); + g_clear_object (&task); + } +#else /* !HAVE_DBUS1 */ + g_test_skip ("Testing interop with libdbus not supported"); +#endif /* !HAVE_DBUS1 */ + + /* No practical effect, just to avoid -Wunused-label under some + * combinations of #ifdefs */ + goto out; + +out: + if (server != NULL) + g_dbus_server_stop (server); + + if (tmpdir != NULL) + g_assert_cmpstr (g_rmdir (tmpdir) == 0 ? "OK" : g_strerror (errno), + ==, "OK"); + + g_clear_object (&server); + g_clear_object (&observer); + g_free (guid); + g_free (listenable_address); + g_free (tmpdir); +} + +static void +test_server_auth (void) +{ + do_test_server_auth (INTEROP_FLAGS_NONE); +} + +static void +test_server_auth_abstract (void) +{ + do_test_server_auth (INTEROP_FLAGS_ABSTRACT); +} + +static void +test_server_auth_tcp (void) +{ + do_test_server_auth (INTEROP_FLAGS_TCP); +} + +static void +test_server_auth_anonymous (void) +{ + do_test_server_auth (INTEROP_FLAGS_ANONYMOUS); +} + +static void +test_server_auth_anonymous_tcp (void) +{ + do_test_server_auth (INTEROP_FLAGS_ANONYMOUS | INTEROP_FLAGS_TCP); +} + +static void +test_server_auth_external (void) +{ + do_test_server_auth (INTEROP_FLAGS_EXTERNAL); +} + +static void +test_server_auth_external_require_same_user (void) +{ + do_test_server_auth (INTEROP_FLAGS_EXTERNAL | INTEROP_FLAGS_REQUIRE_SAME_USER); +} + +static void +test_server_auth_sha1 (void) +{ + do_test_server_auth (INTEROP_FLAGS_SHA1); +} + +static void +test_server_auth_sha1_tcp (void) +{ + do_test_server_auth (INTEROP_FLAGS_SHA1 | INTEROP_FLAGS_TCP); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add_func ("/gdbus/server-auth", test_server_auth); + g_test_add_func ("/gdbus/server-auth/abstract", test_server_auth_abstract); + g_test_add_func ("/gdbus/server-auth/tcp", test_server_auth_tcp); + g_test_add_func ("/gdbus/server-auth/anonymous", test_server_auth_anonymous); + g_test_add_func ("/gdbus/server-auth/anonymous/tcp", test_server_auth_anonymous_tcp); + g_test_add_func ("/gdbus/server-auth/external", test_server_auth_external); + g_test_add_func ("/gdbus/server-auth/external/require-same-user", test_server_auth_external_require_same_user); + g_test_add_func ("/gdbus/server-auth/sha1", test_server_auth_sha1); + g_test_add_func ("/gdbus/server-auth/sha1/tcp", test_server_auth_sha1_tcp); + + return g_test_run(); +} diff --git a/gio/tests/gdbus-sessionbus.c b/gio/tests/gdbus-sessionbus.c new file mode 100644 index 0000000..29f05d4 --- /dev/null +++ b/gio/tests/gdbus-sessionbus.c @@ -0,0 +1,71 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2012 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Xavier Claessens + */ + +#include "gdbus-sessionbus.h" + +static GTestDBus *singleton = NULL; + +void +session_bus_up (void) +{ + gchar *relative, *servicesdir; + g_assert (singleton == NULL); + singleton = g_test_dbus_new (G_TEST_DBUS_NONE); + + /* We ignore deprecations here so that gdbus-test-codegen-old can + * build successfully despite these two functions not being + * available in GLib 2.36 */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + relative = g_test_build_filename (G_TEST_BUILT, "services", NULL); + servicesdir = g_canonicalize_filename (relative, NULL); + G_GNUC_END_IGNORE_DEPRECATIONS + g_free (relative); + + g_test_dbus_add_service_dir (singleton, servicesdir); + g_free (servicesdir); + g_test_dbus_up (singleton); +} + +void +session_bus_stop (void) +{ + g_assert (singleton != NULL); + g_test_dbus_stop (singleton); +} + +void +session_bus_down (void) +{ + g_assert (singleton != NULL); + g_test_dbus_down (singleton); + g_clear_object (&singleton); +} + +gint +session_bus_run (void) +{ + gint ret; + + session_bus_up (); + ret = g_test_run (); + session_bus_down (); + + return ret; +} diff --git a/gio/tests/gdbus-sessionbus.h b/gio/tests/gdbus-sessionbus.h new file mode 100644 index 0000000..c756237 --- /dev/null +++ b/gio/tests/gdbus-sessionbus.h @@ -0,0 +1,35 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2012 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Xavier Claessens + */ + +#ifndef __SESSION_BUS_H__ +#define __SESSION_BUS_H__ + +#include + +G_BEGIN_DECLS + +void session_bus_up (void); +void session_bus_stop (void); +void session_bus_down (void); +gint session_bus_run (void); + +G_END_DECLS + +#endif /* __SESSION_BUS_H__ */ diff --git a/gio/tests/gdbus-test-codegen.c b/gio/tests/gdbus-test-codegen.c new file mode 100644 index 0000000..22628c0 --- /dev/null +++ b/gio/tests/gdbus-test-codegen.c @@ -0,0 +1,2749 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include +#include + +#include "gdbus-tests.h" + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 +#include "gdbus-test-codegen-generated-min-required-2-64.h" +#else +#include "gdbus-test-codegen-generated.h" +#endif + +#include "gdbus-test-codegen-generated-interface-info.h" + +#if GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_68 +# undef G_DBUS_METHOD_INVOCATION_HANDLED +# define G_DBUS_METHOD_INVOCATION_HANDLED TRUE +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +static guint +count_annotations (GDBusAnnotationInfo **annotations) +{ + guint ret; + ret = 0; + while (annotations != NULL && annotations[ret] != NULL) + ret++; + return ret; +} + +/* checks that + * + * - non-internal annotations are written out correctly; and + * - injection via --annotation --key --value works + */ +static void +test_annotations (void) +{ + GDBusInterfaceInfo *iface; + GDBusMethodInfo *method; + GDBusSignalInfo *signal; + GDBusPropertyInfo *property; + + iface = foo_igen_bar_interface_info (); + g_assert (iface != NULL); + + /* see meson.build for where these annotations are injected */ + g_assert_cmpint (count_annotations (iface->annotations), ==, 1); + g_assert_cmpstr (g_dbus_annotation_info_lookup (iface->annotations, "Key1"), ==, "Value1"); + + method = g_dbus_interface_info_lookup_method (iface, "HelloWorld"); + g_assert (method != NULL); + g_assert_cmpint (count_annotations (method->annotations), ==, 2); + g_assert_cmpstr (g_dbus_annotation_info_lookup (method->annotations, "ExistingAnnotation"), ==, "blah"); + g_assert_cmpstr (g_dbus_annotation_info_lookup (method->annotations, "Key3"), ==, "Value3"); + + signal = g_dbus_interface_info_lookup_signal (iface, "TestSignal"); + g_assert (signal != NULL); + g_assert_cmpint (count_annotations (signal->annotations), ==, 1); + g_assert_cmpstr (g_dbus_annotation_info_lookup (signal->annotations, "Key4"), ==, "Value4"); + g_assert_cmpstr (g_dbus_annotation_info_lookup (signal->args[1]->annotations, "Key8"), ==, "Value8"); + + property = g_dbus_interface_info_lookup_property (iface, "ay"); + g_assert (property != NULL); + g_assert_cmpint (count_annotations (property->annotations), ==, 1); + g_assert_cmpstr (g_dbus_annotation_info_lookup (property->annotations, "Key5"), ==, "Value5"); + + method = g_dbus_interface_info_lookup_method (iface, "TestPrimitiveTypes"); + g_assert (method != NULL); + g_assert_cmpstr (g_dbus_annotation_info_lookup (method->in_args[4]->annotations, "Key6"), ==, "Value6"); + g_assert_cmpstr (g_dbus_annotation_info_lookup (method->out_args[5]->annotations, "Key7"), ==, "Value7"); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +on_handle_hello_world (FooiGenBar *object, + GDBusMethodInvocation *invocation, + const gchar *greeting, + gpointer user_data) +{ + gchar *response; + response = g_strdup_printf ("Word! You said '%s'. I'm Skeleton, btw!", greeting); + foo_igen_bar_complete_hello_world (object, invocation, response); + g_free (response); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +on_handle_test_primitive_types (FooiGenBar *object, + GDBusMethodInvocation *invocation, + guchar val_byte, + gboolean val_boolean, + gint16 val_int16, + guint16 val_uint16, + gint val_int32, + guint val_uint32, + gint64 val_int64, + guint64 val_uint64, + gdouble val_double, + const gchar *val_string, + const gchar *val_objpath, + const gchar *val_signature, + const gchar *val_bytestring, + gpointer user_data) +{ + gchar *s1; + gchar *s2; + gchar *s3; + s1 = g_strdup_printf ("Word! You said '%s'. Rock'n'roll!", val_string); + s2 = g_strdup_printf ("/modified%s", val_objpath); + s3 = g_strdup_printf ("assgit%s", val_signature); + foo_igen_bar_complete_test_primitive_types (object, + invocation, + 10 + val_byte, + !val_boolean, + 100 + val_int16, + 1000 + val_uint16, + 10000 + val_int32, + 100000 + val_uint32, + 1000000 + val_int64, + 10000000 + val_uint64, + val_double / G_PI, + s1, + s2, + s3, + "bytestring!\xff"); + g_free (s1); + g_free (s2); + g_free (s3); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +on_handle_test_non_primitive_types (FooiGenBar *object, + GDBusMethodInvocation *invocation, + GVariant *dict_s_to_s, + GVariant *dict_s_to_pairs, + GVariant *a_struct, + const gchar* const *array_of_strings, + const gchar* const *array_of_objpaths, + GVariant *array_of_signatures, + const gchar* const *array_of_bytestrings, + gpointer user_data) +{ + gchar *s; + GString *str; + str = g_string_new (NULL); + s = g_variant_print (dict_s_to_s, TRUE); g_string_append (str, s); g_free (s); + s = g_variant_print (dict_s_to_pairs, TRUE); g_string_append (str, s); g_free (s); + s = g_variant_print (a_struct, TRUE); g_string_append (str, s); g_free (s); + s = g_strjoinv (", ", (gchar **) array_of_strings); + g_string_append_printf (str, "array_of_strings: [%s] ", s); + g_free (s); + s = g_strjoinv (", ", (gchar **) array_of_objpaths); + g_string_append_printf (str, "array_of_objpaths: [%s] ", s); + g_free (s); + s = g_variant_print (array_of_signatures, TRUE); + g_string_append_printf (str, "array_of_signatures: %s ", s); + g_free (s); + s = g_strjoinv (", ", (gchar **) array_of_bytestrings); + g_string_append_printf (str, "array_of_bytestrings: [%s] ", s); + g_free (s); + foo_igen_bar_complete_test_non_primitive_types (object, invocation, + array_of_strings, + array_of_objpaths, + array_of_signatures, + array_of_bytestrings, + str->str); + g_string_free (str, TRUE); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +on_handle_request_signal_emission (FooiGenBar *object, + GDBusMethodInvocation *invocation, + gint which_one, + gpointer user_data) +{ + if (which_one == 0) + { + const gchar *a_strv[] = {"foo", "bar", NULL}; + const gchar *a_bytestring_array[] = {"foo\xff", "bar\xff", NULL}; + GVariant *a_variant = g_variant_new_parsed ("{'first': (42, 42), 'second': (43, 43)}"); + foo_igen_bar_emit_test_signal (object, 43, a_strv, a_bytestring_array, a_variant); /* consumes a_variant */ + foo_igen_bar_complete_request_signal_emission (object, invocation); + } + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +on_handle_request_multi_property_mods (FooiGenBar *object, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1); + foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1); + foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1); + foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1); + g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (object)); + foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1); + foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1); + foo_igen_bar_complete_request_multi_property_mods (object, invocation); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +on_handle_property_cancellation (FooiGenBar *object, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + guint n; + n = foo_igen_bar_get_n (object); + /* This queues up a PropertiesChange event */ + foo_igen_bar_set_n (object, n + 1); + /* this modifies the queued up event */ + foo_igen_bar_set_n (object, n); + /* this flushes all PropertiesChanges event (sends the D-Bus message right + * away, if any - there should not be any) + */ + g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (object)); + /* this makes us return the reply D-Bus method */ + foo_igen_bar_complete_property_cancellation (object, invocation); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +on_handle_force_method (FooiGenBat *object, + GDBusMethodInvocation *invocation, + GVariant *force_in_i, + GVariant *force_in_s, + GVariant *force_in_ay, + GVariant *force_in_struct, + gpointer user_data) +{ + GVariant *ret_i; + GVariant *ret_s; + GVariant *ret_ay; + GVariant *ret_struct; + gint32 val; + gchar *s; + + ret_i = g_variant_new_int32 (g_variant_get_int32 (force_in_i) + 10); + s = g_strdup_printf ("%s_foo", g_variant_get_string (force_in_s, NULL)); + ret_s = g_variant_new_string (s); + g_free (s); + s = g_strdup_printf ("%s_foo\xff", g_variant_get_bytestring (force_in_ay)); + ret_ay = g_variant_new_bytestring (s); + g_free (s); + + g_variant_get (force_in_struct, "(i)", &val); + ret_struct = g_variant_new ("(i)", val + 10); + + g_variant_ref_sink (ret_i); + g_variant_ref_sink (ret_s); + g_variant_ref_sink (ret_ay); + g_variant_ref_sink (ret_struct); + + foo_igen_bat_emit_force_signal (object, + ret_i, + ret_s, + ret_ay, + ret_struct); + + foo_igen_bat_complete_force_method (object, + invocation, + ret_i, + ret_s, + ret_ay, + ret_struct); + + g_variant_unref (ret_i); + g_variant_unref (ret_s); + g_variant_unref (ret_ay); + g_variant_unref (ret_struct); + + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +my_g_authorize_method_handler (GDBusInterfaceSkeleton *interface, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + const gchar *method_name; + gboolean authorized; + + authorized = FALSE; + + method_name = g_dbus_method_invocation_get_method_name (invocation); + if (g_strcmp0 (method_name, "CheckNotAuthorized") == 0) + { + authorized = FALSE; + } + else if (g_strcmp0 (method_name, "CheckAuthorized") == 0) + { + authorized = TRUE; + } + else if (g_strcmp0 (method_name, "CheckNotAuthorizedFromObject") == 0) + { + authorized = TRUE; + } + else + { + g_assert_not_reached (); + } + + if (!authorized) + { + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED, + "not authorized..."); + } + return authorized; +} + +static gboolean +my_object_authorize_method_handler (GDBusObjectSkeleton *object, + GDBusInterfaceSkeleton *interface, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + const gchar *method_name; + gboolean authorized; + + authorized = FALSE; + + method_name = g_dbus_method_invocation_get_method_name (invocation); + if (g_strcmp0 (method_name, "CheckNotAuthorized") == 0) + { + authorized = TRUE; + } + else if (g_strcmp0 (method_name, "CheckAuthorized") == 0) + { + authorized = TRUE; + } + else if (g_strcmp0 (method_name, "CheckNotAuthorizedFromObject") == 0) + { + authorized = FALSE; + } + else + { + g_assert_not_reached (); + } + + if (!authorized) + { + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_PENDING, + "not authorized (from object)..."); + } + return authorized; +} + +static gboolean +on_handle_check_not_authorized (FooiGenAuthorize *object, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + foo_igen_authorize_complete_check_not_authorized (object, invocation); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +on_handle_check_authorized (FooiGenAuthorize *object, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + foo_igen_authorize_complete_check_authorized (object, invocation); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +on_handle_check_not_authorized_from_object (FooiGenAuthorize *object, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + foo_igen_authorize_complete_check_not_authorized_from_object (object, invocation); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +on_handle_get_self (FooiGenMethodThreads *object, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + gchar *s; + s = g_strdup_printf ("%p", (void *)g_thread_self ()); + foo_igen_method_threads_complete_get_self (object, invocation, s); + g_free (s); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GThread *method_handler_thread = NULL; + +static FooiGenBar *exported_bar_object = NULL; +static FooiGenBat *exported_bat_object = NULL; +static FooiGenAuthorize *exported_authorize_object = NULL; +static GDBusObjectSkeleton *authorize_enclosing_object = NULL; +static FooiGenMethodThreads *exported_thread_object_1 = NULL; +static FooiGenMethodThreads *exported_thread_object_2 = NULL; + +static void +unexport_objects (void) +{ + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_bar_object)); + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_bat_object)); + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_authorize_object)); + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1)); + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2)); +} + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GError *error; + + /* Test that we can export an object using the generated + * FooiGenBarSkeleton subclass. Notes: + * + * 1. We handle methods by simply connecting to the appropriate + * GObject signal. + * + * 2. Property storage is taken care of by the class; we can + * use g_object_get()/g_object_set() (and the generated + * C bindings at will) + */ + error = NULL; + exported_bar_object = foo_igen_bar_skeleton_new (); + foo_igen_bar_set_ay (exported_bar_object, "ABCabc"); + foo_igen_bar_set_y (exported_bar_object, 42); + foo_igen_bar_set_d (exported_bar_object, 43.0); + foo_igen_bar_set_finally_normal_name (exported_bar_object, "There aint no place like home"); + foo_igen_bar_set_writeonly_property (exported_bar_object, "Mr. Burns"); + + /* The following works because it's on the Skeleton object - it will + * fail (at run-time) on a Proxy (see on_proxy_appeared() below) + */ + foo_igen_bar_set_readonly_property (exported_bar_object, "blah"); + g_assert_cmpstr (foo_igen_bar_get_writeonly_property (exported_bar_object), ==, "Mr. Burns"); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_bar_object), + connection, + "/bar", + &error); + g_assert_no_error (error); + g_signal_connect (exported_bar_object, + "handle-hello-world", + G_CALLBACK (on_handle_hello_world), + NULL); + g_signal_connect (exported_bar_object, + "handle-test-primitive-types", + G_CALLBACK (on_handle_test_primitive_types), + NULL); + g_signal_connect (exported_bar_object, + "handle-test-non-primitive-types", + G_CALLBACK (on_handle_test_non_primitive_types), + NULL); + g_signal_connect (exported_bar_object, + "handle-request-signal-emission", + G_CALLBACK (on_handle_request_signal_emission), + NULL); + g_signal_connect (exported_bar_object, + "handle-request-multi-property-mods", + G_CALLBACK (on_handle_request_multi_property_mods), + NULL); + g_signal_connect (exported_bar_object, + "handle-property-cancellation", + G_CALLBACK (on_handle_property_cancellation), + NULL); + + exported_bat_object = foo_igen_bat_skeleton_new (); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_bat_object), + connection, + "/bat", + &error); + g_assert_no_error (error); + g_signal_connect (exported_bat_object, + "handle-force-method", + G_CALLBACK (on_handle_force_method), + NULL); + g_object_set (exported_bat_object, + "force-i", g_variant_new_int32 (43), + "force-s", g_variant_new_string ("prop string"), + "force-ay", g_variant_new_bytestring ("prop bytestring\xff"), + "force-struct", g_variant_new ("(i)", 4300), + NULL); + + authorize_enclosing_object = g_dbus_object_skeleton_new ("/authorize"); + g_signal_connect (authorize_enclosing_object, + "authorize-method", + G_CALLBACK (my_object_authorize_method_handler), + NULL); + exported_authorize_object = foo_igen_authorize_skeleton_new (); + g_dbus_object_skeleton_add_interface (authorize_enclosing_object, + G_DBUS_INTERFACE_SKELETON (exported_authorize_object)); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_authorize_object), + connection, + "/authorize", + &error); + g_assert_no_error (error); + g_signal_connect (exported_authorize_object, + "g-authorize-method", + G_CALLBACK (my_g_authorize_method_handler), + NULL); + g_signal_connect (exported_authorize_object, + "handle-check-not-authorized", + G_CALLBACK (on_handle_check_not_authorized), + NULL); + g_signal_connect (exported_authorize_object, + "handle-check-authorized", + G_CALLBACK (on_handle_check_authorized), + NULL); + g_signal_connect (exported_authorize_object, + "handle-check-not-authorized-from-object", + G_CALLBACK (on_handle_check_not_authorized_from_object), + NULL); + + + /* only object 1 has the G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD flag set */ + exported_thread_object_1 = foo_igen_method_threads_skeleton_new (); + g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1), + G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); + + g_assert (!g_dbus_interface_skeleton_has_connection (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1), connection)); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1), + connection, + "/method_threads_1", + &error); + g_assert_no_error (error); + g_signal_connect (exported_thread_object_1, + "handle-get-self", + G_CALLBACK (on_handle_get_self), + NULL); + g_assert_cmpint (g_dbus_interface_skeleton_get_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1)), ==, G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); + + exported_thread_object_2 = foo_igen_method_threads_skeleton_new (); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2), + connection, + "/method_threads_2", + &error); + g_assert_no_error (error); + g_signal_connect (exported_thread_object_2, + "handle-get-self", + G_CALLBACK (on_handle_get_self), + NULL); + + g_assert_cmpint (g_dbus_interface_skeleton_get_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2)), ==, G_DBUS_INTERFACE_SKELETON_FLAGS_NONE); + + method_handler_thread = g_thread_self (); +} + +static gpointer check_proxies_in_thread (gpointer user_data); + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GMainLoop *loop = user_data; + GThread *thread = g_thread_new ("check-proxies", check_proxies_in_thread, loop); + g_thread_unref (thread); +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_assert_not_reached (); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GMainLoop *thread_loop; + gint initial_y; + gint initial_i; + guint num_g_properties_changed; + gboolean received_test_signal; + guint num_notify_u; + guint num_notify_n; +} ClientData; + +static void +on_notify_u (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + ClientData *data = user_data; + g_assert_cmpstr (pspec->name, ==, "u"); + data->num_notify_u += 1; +} + +static void +on_notify_n (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + ClientData *data = user_data; + g_assert_cmpstr (pspec->name, ==, "n"); + data->num_notify_n += 1; +} + +static void +on_g_properties_changed (GDBusProxy *_proxy, + GVariant *changed_properties, + const gchar* const *invalidated_properties, + gpointer user_data) +{ + ClientData *data = user_data; + FooiGenBar *proxy = FOO_IGEN_BAR (_proxy); + + g_assert_cmpint (g_variant_n_children (changed_properties), ==, 2); + + if (data->num_g_properties_changed == 0) + { + g_assert_cmpint (data->initial_y, ==, foo_igen_bar_get_y (proxy) - 2); + g_assert_cmpint (data->initial_i, ==, foo_igen_bar_get_i (proxy) - 2); + } + else if (data->num_g_properties_changed == 1) + { + g_assert_cmpint (data->initial_y, ==, foo_igen_bar_get_y (proxy) - 3); + g_assert_cmpint (data->initial_i, ==, foo_igen_bar_get_i (proxy) - 3); + } + else + g_assert_not_reached (); + + data->num_g_properties_changed++; + + if (data->num_g_properties_changed == 2) + g_main_loop_quit (data->thread_loop); +} + +static void +on_test_signal (FooiGenBar *proxy, + gint val_int32, + const gchar* const *array_of_strings, + const gchar* const *array_of_bytestrings, + GVariant *dict_s_to_pairs, + gpointer user_data) +{ + ClientData *data = user_data; + + g_assert_cmpint (val_int32, ==, 43); + g_assert_cmpstr (array_of_strings[0], ==, "foo"); + g_assert_cmpstr (array_of_strings[1], ==, "bar"); + g_assert (array_of_strings[2] == NULL); + g_assert_cmpstr (array_of_bytestrings[0], ==, "foo\xff"); + g_assert_cmpstr (array_of_bytestrings[1], ==, "bar\xff"); + g_assert (array_of_bytestrings[2] == NULL); + + data->received_test_signal = TRUE; + g_main_loop_quit (data->thread_loop); +} + +static void +on_property_cancellation_cb (FooiGenBar *proxy, + GAsyncResult *res, + gpointer user_data) +{ + ClientData *data = user_data; + gboolean ret; + GError *error = NULL; + + error = NULL; + ret = foo_igen_bar_call_property_cancellation_finish (proxy, res, &error); + g_assert_no_error (error); + g_assert (ret); + + g_main_loop_quit (data->thread_loop); +} + +static void +check_bar_proxy (FooiGenBar *proxy, + GMainLoop *thread_loop) +{ + const gchar *array_of_strings[3] = {"one", "two", NULL}; + const gchar *array_of_strings_2[3] = {"one2", "two2", NULL}; + const gchar *array_of_objpaths[3] = {"/one", "/one/two", NULL}; + GVariant *array_of_signatures = NULL; + const gchar *array_of_bytestrings[3] = {"one\xff", "two\xff", NULL}; + gchar **ret_array_of_strings = NULL; + gchar **ret_array_of_objpaths = NULL; + GVariant *ret_array_of_signatures = NULL; + gchar **ret_array_of_bytestrings = NULL; + guchar ret_val_byte; + gboolean ret_val_boolean; + gint16 ret_val_int16; + guint16 ret_val_uint16; + gint ret_val_int32; + guint ret_val_uint32; + gint64 ret_val_int64; + guint64 ret_val_uint64; + gdouble ret_val_double; + gchar *ret_val_string; + gchar *ret_val_objpath; + gchar *ret_val_signature; + gchar *ret_val_bytestring; + gboolean ret; + GError *error; + ClientData *data; + guchar val_y; + gboolean val_b; + gint val_n; + guint val_q; + gint val_i; + guint val_u; + gint64 val_x; + guint64 val_t; + gdouble val_d; + gchar *val_s; + gchar *val_o; + gchar *val_g; + gchar *val_ay; + gchar **val_as; + gchar **val_ao; + GVariant *val_ag; + gint32 val_unset_i; + gdouble val_unset_d; + gchar *val_unset_s; + gchar *val_unset_o; + gchar *val_unset_g; + gchar *val_unset_ay; + gchar **val_unset_as; + gchar **val_unset_ao; + GVariant *val_unset_ag; + GVariant *val_unset_struct; + gchar *val_finally_normal_name; + GVariant *v; + gchar *s; + const gchar *const *read_as; + const gchar *const *read_as2; + const gchar *const *read_as3; + + data = g_new0 (ClientData, 1); + data->thread_loop = thread_loop; + + v = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "y"); + g_assert (v != NULL); + g_variant_unref (v); + + /* set empty values to non-empty */ + val_unset_i = 42; + val_unset_d = 42.0; + val_unset_s = "42"; + val_unset_o = "42"; + val_unset_g = "42"; + val_unset_ay = NULL; + val_unset_as = NULL; + val_unset_ao = NULL; + val_unset_ag = NULL; + val_unset_struct = NULL; + /* check properties */ + g_object_get (proxy, + "y", &val_y, + "b", &val_b, + "n", &val_n, + "q", &val_q, + "i", &val_i, + "u", &val_u, + "x", &val_x, + "t", &val_t, + "d", &val_d, + "s", &val_s, + "o", &val_o, + "g", &val_g, + "ay", &val_ay, + "as", &val_as, + "ao", &val_ao, + "ag", &val_ag, + "unset_i", &val_unset_i, + "unset_d", &val_unset_d, + "unset_s", &val_unset_s, + "unset_o", &val_unset_o, + "unset_g", &val_unset_g, + "unset_ay", &val_unset_ay, + "unset_as", &val_unset_as, + "unset_ao", &val_unset_ao, + "unset_ag", &val_unset_ag, + "unset_struct", &val_unset_struct, + "finally-normal-name", &val_finally_normal_name, + NULL); + g_assert_cmpint (val_y, ==, 42); + g_assert_cmpstr (val_finally_normal_name, ==, "There aint no place like home"); + g_free (val_s); + g_free (val_o); + g_free (val_g); + g_assert_cmpstr (val_ay, ==, "ABCabc"); + g_free (val_ay); + g_strfreev (val_as); + g_strfreev (val_ao); + g_variant_unref (val_ag); + g_free (val_finally_normal_name); + /* check empty values */ + g_assert_cmpint (val_unset_i, ==, 0); + g_assert_cmpfloat (val_unset_d, ==, 0.0); + g_assert_cmpstr (val_unset_s, ==, ""); + g_assert_cmpstr (val_unset_o, ==, "/"); + g_assert_cmpstr (val_unset_g, ==, ""); + g_free (val_unset_s); + g_free (val_unset_o); + g_free (val_unset_g); + g_assert_cmpstr (val_unset_ay, ==, ""); + g_assert (val_unset_as[0] == NULL); + g_assert (val_unset_ao[0] == NULL); + g_assert (g_variant_is_of_type (val_unset_ag, G_VARIANT_TYPE ("ag"))); + g_assert (g_variant_is_of_type (val_unset_struct, G_VARIANT_TYPE ("(idsogayasaoag)"))); + s = g_variant_print (val_unset_struct, TRUE); + g_assert_cmpstr (s, ==, "(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])"); + g_free (s); + g_free (val_unset_ay); + g_strfreev (val_unset_as); + g_strfreev (val_unset_ao); + g_variant_unref (val_unset_ag); + g_variant_unref (val_unset_struct); + + /* Try setting a property. This causes the generated glue to invoke + * the org.fd.DBus.Properties.Set() method asynchronously. So we + * have to wait for properties-changed... + */ + foo_igen_bar_set_finally_normal_name (proxy, "foo!"); + _g_assert_property_notify (proxy, "finally-normal-name"); + g_assert_cmpstr (foo_igen_bar_get_finally_normal_name (proxy), ==, "foo!"); + + /* Try setting properties that requires memory management. This + * is to exercise the paths that frees the references. + */ + + g_object_set (proxy, + "s", "a string", + "o", "/a/path", + "g", "asig", + "ay", "eg", + "as", array_of_strings, + "ao", array_of_objpaths, + "ag", g_variant_new_parsed ("[@g 'ass', 'git']"), + NULL); + + error = NULL; + ret = foo_igen_bar_call_test_primitive_types_sync (proxy, + 10, + TRUE, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + "a string", + "/a/path", + "asig", + "bytestring\xff", +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + G_DBUS_CALL_FLAGS_NONE, + -1, +#endif + &ret_val_byte, + &ret_val_boolean, + &ret_val_int16, + &ret_val_uint16, + &ret_val_int32, + &ret_val_uint32, + &ret_val_int64, + &ret_val_uint64, + &ret_val_double, + &ret_val_string, + &ret_val_objpath, + &ret_val_signature, + &ret_val_bytestring, + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_assert (ret); + + g_clear_pointer (&ret_val_string, g_free); + g_clear_pointer (&ret_val_objpath, g_free); + g_clear_pointer (&ret_val_signature, g_free); + g_clear_pointer (&ret_val_bytestring, g_free); + + error = NULL; + array_of_signatures = g_variant_ref_sink (g_variant_new_parsed ("[@g 'ass', 'git']")); + ret = foo_igen_bar_call_test_non_primitive_types_sync (proxy, + g_variant_new_parsed ("{'one': 'red'," + " 'two': 'blue'}"), + g_variant_new_parsed ("{'first': (42, 42), " + "'second': (43, 43)}"), + g_variant_new_parsed ("(42, 'foo', 'bar')"), + array_of_strings, + array_of_objpaths, + array_of_signatures, + array_of_bytestrings, +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + G_DBUS_CALL_FLAGS_NONE, + -1, +#endif + &ret_array_of_strings, + &ret_array_of_objpaths, + &ret_array_of_signatures, + &ret_array_of_bytestrings, + &s, + NULL, /* GCancellable */ + &error); + + g_assert_no_error (error); + g_assert (ret); + + g_assert_nonnull (ret_array_of_strings); + g_assert_cmpuint (g_strv_length ((gchar **) ret_array_of_strings), ==, + g_strv_length ((gchar **) array_of_strings)); + g_assert_nonnull (ret_array_of_objpaths); + g_assert_cmpuint (g_strv_length ((gchar **) ret_array_of_objpaths), ==, + g_strv_length ((gchar **) array_of_objpaths)); + g_assert_nonnull (ret_array_of_signatures); + g_assert_cmpvariant (ret_array_of_signatures, array_of_signatures); + g_assert_nonnull (ret_array_of_bytestrings); + g_assert_cmpuint (g_strv_length ((gchar **) ret_array_of_bytestrings), ==, + g_strv_length ((gchar **) array_of_bytestrings)); + + g_clear_pointer (&ret_array_of_strings, g_strfreev); + g_clear_pointer (&ret_array_of_objpaths, g_strfreev); + g_clear_pointer (&ret_array_of_signatures, g_variant_unref); + g_clear_pointer (&ret_array_of_bytestrings, g_strfreev); + g_clear_pointer (&s, g_free); + + /* Check that org.freedesktop.DBus.Error.UnknownMethod is returned on + * unimplemented methods. + */ + error = NULL; +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + ret = foo_igen_bar_call_unimplemented_method_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL /* GCancellable */, &error); +#else + ret = foo_igen_bar_call_unimplemented_method_sync (proxy, NULL /* GCancellable */, &error); +#endif + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_error_free (error); + error = NULL; + g_assert (!ret); + + g_signal_connect (proxy, + "test-signal", + G_CALLBACK (on_test_signal), + data); + error = NULL; +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + ret = foo_igen_bar_call_request_signal_emission_sync (proxy, 0, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); +#else + ret = foo_igen_bar_call_request_signal_emission_sync (proxy, 0, NULL, &error); +#endif + g_assert_no_error (error); + g_assert (ret); + + g_assert (!data->received_test_signal); + g_main_loop_run (thread_loop); + g_assert (data->received_test_signal); + + /* Try setting a property. This causes the generated glue to invoke + * the org.fd.DBus.Properties.Set() method asynchronously. So we + * have to wait for properties-changed... + */ + foo_igen_bar_set_finally_normal_name (proxy, "hey back!"); + _g_assert_property_notify (proxy, "finally-normal-name"); + g_assert_cmpstr (foo_igen_bar_get_finally_normal_name (proxy), ==, "hey back!"); + + /* Check that multiple calls to a strv getter works... and that + * updates on them works as well (See comment for "property vfuncs" + * in gio/gdbus-codegen/codegen.py for details) + */ + read_as = foo_igen_bar_get_as (proxy); + read_as2 = foo_igen_bar_get_as (proxy); + g_assert_cmpint (g_strv_length ((gchar **) read_as), ==, 2); + g_assert_cmpstr (read_as[0], ==, "one"); + g_assert_cmpstr (read_as[1], ==, "two"); + g_assert (read_as == read_as2); /* this is more testing an implementation detail */ + g_object_set (proxy, + "as", array_of_strings_2, + NULL); + _g_assert_property_notify (proxy, "as"); + read_as3 = foo_igen_bar_get_as (proxy); + g_assert_cmpint (g_strv_length ((gchar **) read_as3), ==, 2); + g_assert_cmpstr (read_as3[0], ==, "one2"); + g_assert_cmpstr (read_as3[1], ==, "two2"); + + /* Check that grouping changes in idle works. + * + * See on_handle_request_multi_property_mods(). The server should + * emit exactly two PropertiesChanged signals each containing two + * properties. + * + * On the first reception, y and i should both be increased by + * two. On the second reception, only by one. The signal handler + * checks this. + * + * This also checks that _drain_notify() works. + */ + data->initial_y = foo_igen_bar_get_y (proxy); + data->initial_i = foo_igen_bar_get_i (proxy); + g_signal_connect (proxy, + "g-properties-changed", + G_CALLBACK (on_g_properties_changed), + data); + error = NULL; +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + ret = foo_igen_bar_call_request_multi_property_mods_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); +#else + ret = foo_igen_bar_call_request_multi_property_mods_sync (proxy, NULL, &error); +#endif + g_assert_no_error (error); + g_assert (ret); + g_main_loop_run (thread_loop); + g_assert_cmpint (data->num_g_properties_changed, ==, 2); + g_signal_handlers_disconnect_by_func (proxy, + G_CALLBACK (on_g_properties_changed), + data); + + /* Check that we don't emit PropertiesChanged() if the property + * didn't change... we actually get two notifies.. one for the + * local set (without a value change) and one when receiving + * the PropertiesChanged() signal generated from the remote end. + */ + g_assert_cmpint (data->num_notify_u, ==, 0); + g_signal_connect (proxy, + "notify::u", + G_CALLBACK (on_notify_u), + data); + foo_igen_bar_set_u (proxy, 1042); + g_assert_cmpint (data->num_notify_u, ==, 1); + g_assert_cmpint (foo_igen_bar_get_u (proxy), ==, 0); + _g_assert_property_notify (proxy, "u"); + g_assert_cmpint (foo_igen_bar_get_u (proxy), ==, 1042); + g_assert_cmpint (data->num_notify_u, ==, 2); + + /* Now change u again to the same value.. this will cause a + * local notify:: notify and the usual Properties.Set() call + * + * (Btw, why also the Set() call if the value in the cache is + * the same? Because someone else might have changed it + * in the mean time and we're just waiting to receive the + * PropertiesChanged() signal...) + * + * More tricky - how do we check for the *absence* of the + * notification that u changed? Simple: we change another + * property and wait for that PropertiesChanged() message + * to arrive. + */ + foo_igen_bar_set_u (proxy, 1042); + g_assert_cmpint (data->num_notify_u, ==, 3); + + g_assert_cmpint (data->num_notify_n, ==, 0); + g_signal_connect (proxy, + "notify::n", + G_CALLBACK (on_notify_n), + data); + foo_igen_bar_set_n (proxy, 10042); + g_assert_cmpint (data->num_notify_n, ==, 1); + g_assert_cmpint (foo_igen_bar_get_n (proxy), ==, 0); + _g_assert_property_notify (proxy, "n"); + g_assert_cmpint (foo_igen_bar_get_n (proxy), ==, 10042); + g_assert_cmpint (data->num_notify_n, ==, 2); + /* Checks that u didn't change at all */ + g_assert_cmpint (data->num_notify_u, ==, 3); + + /* Now we check that if the service does + * + * guint n = foo_igen_bar_get_n (foo); + * foo_igen_bar_set_n (foo, n + 1); + * foo_igen_bar_set_n (foo, n); + * + * then no PropertiesChanged() signal is emitted! + */ + error = NULL; + foo_igen_bar_call_property_cancellation (proxy, +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + G_DBUS_CALL_FLAGS_NONE, + -1, +#endif + NULL, /* GCancellable */ + (GAsyncReadyCallback) on_property_cancellation_cb, + data); + g_main_loop_run (thread_loop); + /* Checks that n didn't change at all */ + g_assert_cmpint (data->num_notify_n, ==, 2); + + /* cleanup */ + g_free (data); + g_variant_unref (array_of_signatures); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_force_signal (FooiGenBat *proxy, + GVariant *force_i, + GVariant *force_s, + GVariant *force_ay, + GVariant *force_struct, + gpointer user_data) +{ + gboolean *signal_received = user_data; + gint val; + + g_assert (!(*signal_received)); + + g_assert_cmpint (g_variant_get_int32 (force_i), ==, 42 + 10); + g_assert_cmpstr (g_variant_get_string (force_s, NULL), ==, "a string_foo"); + g_assert_cmpstr (g_variant_get_bytestring (force_ay), ==, "a bytestring\xff_foo\xff"); + g_variant_get (force_struct, "(i)", &val); + g_assert_cmpint (val, ==, 4200 + 10); + + *signal_received = TRUE; +} + +static void +check_bat_proxy (FooiGenBat *proxy, + GMainLoop *thread_loop) +{ + GError *error; + GVariant *ret_i; + GVariant *ret_s; + GVariant *ret_ay; + GVariant *ret_struct; + gint val; + gboolean force_signal_received; + + /* --------------------------------------------------- */ + /* Check type-mapping where we force use of a GVariant */ + /* --------------------------------------------------- */ + + /* check properties */ + g_object_get (proxy, + "force-i", &ret_i, + "force-s", &ret_s, + "force-ay", &ret_ay, + "force-struct", &ret_struct, + NULL); + g_assert_cmpint (g_variant_get_int32 (ret_i), ==, 43); + g_assert_cmpstr (g_variant_get_string (ret_s, NULL), ==, "prop string"); + g_assert_cmpstr (g_variant_get_bytestring (ret_ay), ==, "prop bytestring\xff"); + g_variant_get (ret_struct, "(i)", &val); + g_assert_cmpint (val, ==, 4300); + g_variant_unref (ret_i); + g_variant_unref (ret_s); + g_variant_unref (ret_ay); + g_variant_unref (ret_struct); + + /* check method and signal */ + force_signal_received = FALSE; + g_signal_connect (proxy, + "force-signal", + G_CALLBACK (on_force_signal), + &force_signal_received); + + error = NULL; + foo_igen_bat_call_force_method_sync (proxy, + g_variant_new_int32 (42), + g_variant_new_string ("a string"), + g_variant_new_bytestring ("a bytestring\xff"), + g_variant_new ("(i)", 4200), +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + G_DBUS_CALL_FLAGS_NONE, + -1, +#endif + &ret_i, + &ret_s, + &ret_ay, + &ret_struct, + NULL, /* GCancellable* */ + &error); + g_assert_no_error (error); + g_assert_cmpint (g_variant_get_int32 (ret_i), ==, 42 + 10); + g_assert_cmpstr (g_variant_get_string (ret_s, NULL), ==, "a string_foo"); + g_assert_cmpstr (g_variant_get_bytestring (ret_ay), ==, "a bytestring\xff_foo\xff"); + g_variant_get (ret_struct, "(i)", &val); + g_assert_cmpint (val, ==, 4200 + 10); + g_variant_unref (ret_i); + g_variant_unref (ret_s); + g_variant_unref (ret_ay); + g_variant_unref (ret_struct); + _g_assert_signal_received (proxy, "force-signal"); + g_assert (force_signal_received); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +check_authorize_proxy (FooiGenAuthorize *proxy, + GMainLoop *thread_loop) +{ + GError *error; + gboolean ret; + + /* Check that g-authorize-method works as intended */ + + error = NULL; +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + ret = foo_igen_authorize_call_check_not_authorized_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); +#else + ret = foo_igen_authorize_call_check_not_authorized_sync (proxy, NULL, &error); +#endif + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED); + g_error_free (error); + g_assert (!ret); + + error = NULL; +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + ret = foo_igen_authorize_call_check_authorized_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); +#else + ret = foo_igen_authorize_call_check_authorized_sync (proxy, NULL, &error); +#endif + g_assert_no_error (error); + g_assert (ret); + + error = NULL; +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + ret = foo_igen_authorize_call_check_not_authorized_from_object_sync (proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); +#else + ret = foo_igen_authorize_call_check_not_authorized_from_object_sync (proxy, NULL, &error); +#endif + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING); + g_error_free (error); + g_assert (!ret); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GThread * +get_self_via_proxy (FooiGenMethodThreads *proxy_1) +{ + GError *error; + gchar *self_str; + gboolean ret; + gpointer self; + + error = NULL; +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 + ret = foo_igen_method_threads_call_get_self_sync (proxy_1, G_DBUS_CALL_FLAGS_NONE, -1, &self_str, NULL, &error); +#else + ret = foo_igen_method_threads_call_get_self_sync (proxy_1, &self_str, NULL, &error); +#endif + g_assert_no_error (error); + g_assert (ret); + + g_assert_cmpint (sscanf (self_str, "%p", &self), ==, 1); + + g_free (self_str); + + return self; +} + +static void +check_thread_proxies (FooiGenMethodThreads *proxy_1, + FooiGenMethodThreads *proxy_2, + GMainLoop *thread_loop) +{ + /* proxy_1 is indeed using threads so should never get the handler thread */ + g_assert (get_self_via_proxy (proxy_1) != method_handler_thread); + + /* proxy_2 is not using threads so should get the handler thread */ + g_assert (get_self_via_proxy (proxy_2) == method_handler_thread); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gpointer +check_proxies_in_thread (gpointer user_data) +{ + GMainLoop *loop = user_data; + GMainContext *thread_context; + GMainLoop *thread_loop; + GError *error; + FooiGenBar *bar_proxy; + FooiGenBat *bat_proxy; + FooiGenAuthorize *authorize_proxy; + FooiGenMethodThreads *thread_proxy_1; + FooiGenMethodThreads *thread_proxy_2; + + thread_context = g_main_context_new (); + thread_loop = g_main_loop_new (thread_context, FALSE); + g_main_context_push_thread_default (thread_context); + + /* Check the object */ + error = NULL; + bar_proxy = foo_igen_bar_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gtk.GDBus.BindingsTool.Test", + "/bar", + NULL, /* GCancellable* */ + &error); + check_bar_proxy (bar_proxy, thread_loop); + g_assert_no_error (error); + g_object_unref (bar_proxy); + + error = NULL; + bat_proxy = foo_igen_bat_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gtk.GDBus.BindingsTool.Test", + "/bat", + NULL, /* GCancellable* */ + &error); + check_bat_proxy (bat_proxy, thread_loop); + g_assert_no_error (error); + g_object_unref (bat_proxy); + + error = NULL; + authorize_proxy = foo_igen_authorize_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gtk.GDBus.BindingsTool.Test", + "/authorize", + NULL, /* GCancellable* */ + &error); + check_authorize_proxy (authorize_proxy, thread_loop); + g_assert_no_error (error); + g_object_unref (authorize_proxy); + + error = NULL; + thread_proxy_1 = foo_igen_method_threads_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gtk.GDBus.BindingsTool.Test", + "/method_threads_1", + NULL, /* GCancellable* */ + &error); + g_assert_no_error (error); + thread_proxy_2 = foo_igen_method_threads_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gtk.GDBus.BindingsTool.Test", + "/method_threads_2", + NULL, /* GCancellable* */ + &error); + g_assert_no_error (error); + check_thread_proxies (thread_proxy_1, thread_proxy_2, thread_loop); + g_object_unref (thread_proxy_1); + g_object_unref (thread_proxy_2); + + /* Wait for the proxy signals to all be unsubscribed. */ + while (g_main_context_iteration (thread_context, FALSE)) + { + /* Nothing needs to be done here */ + } + + g_main_loop_unref (thread_loop); + g_main_context_unref (thread_context); + + /* this breaks out of the loop in main() (below) */ + g_main_loop_quit (loop); + return NULL; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + gchar *xml; + GMainLoop *loop; +} IntrospectData; + +static void +introspect_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + IntrospectData *data = user_data; + GVariant *result; + GError *error; + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_variant_get (result, "(s)", &data->xml); + g_variant_unref (result); + + g_main_loop_quit (data->loop); +} + +static GDBusNodeInfo * +introspect (GDBusConnection *connection, + const gchar *name, + const gchar *object_path, + GMainLoop *loop) +{ + GError *error; + GDBusNodeInfo *node_info; + IntrospectData *data; + + data = g_new0 (IntrospectData, 1); + data->xml = NULL; + data->loop = loop; + + /* do this async to avoid deadlocks */ + g_dbus_connection_call (connection, + name, + object_path, + "org.freedesktop.DBus.Introspectable", + "Introspect", + NULL, /* params */ + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) introspect_cb, + data); + g_main_loop_run (loop); + g_assert (data->xml != NULL); + + error = NULL; + node_info = g_dbus_node_info_new_for_xml (data->xml, &error); + g_assert_no_error (error); + g_assert (node_info != NULL); + g_free (data->xml); + g_free (data); + + return node_info; +} + +static guint +count_interfaces (GDBusNodeInfo *info) +{ + guint n; + for (n = 0; info->interfaces != NULL && info->interfaces[n] != NULL; n++) + ; + return n; +} + +static guint +count_nodes (GDBusNodeInfo *info) +{ + guint n; + for (n = 0; info->nodes != NULL && info->nodes[n] != NULL; n++) + ; + return n; +} + +static guint +has_interface (GDBusNodeInfo *info, + const gchar *name) +{ + guint n; + for (n = 0; info->interfaces != NULL && info->interfaces[n] != NULL; n++) + { + if (g_strcmp0 (info->interfaces[n]->name, name) == 0) + return TRUE; + } + return FALSE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + GMainLoop *loop; + GVariant *result; +} OMGetManagedObjectsData; + +static void +om_get_all_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + OMGetManagedObjectsData *data = user_data; + GError *error; + + error = NULL; + data->result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_no_error (error); + g_assert (data->result != NULL); + g_main_loop_quit (data->loop); +} + +static void +om_check_get_all (GDBusConnection *c, + GMainLoop *loop, + const gchar *str) +{ + OMGetManagedObjectsData data; + gchar *s; + + data.loop = loop; + data.result = NULL; + + /* do this async to avoid deadlocks */ + g_dbus_connection_call (c, + g_dbus_connection_get_unique_name (c), + "/managed", + "org.freedesktop.DBus.ObjectManager", + "GetManagedObjects", + NULL, /* params */ + G_VARIANT_TYPE ("(a{oa{sa{sv}}})"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) om_get_all_cb, + &data); + g_main_loop_run (loop); + g_assert (data.result != NULL); + s = g_variant_print (data.result, TRUE); + g_assert_cmpstr (s, ==, str); + g_free (s); + g_variant_unref (data.result); +} + +typedef struct +{ + GMainLoop *loop; + guint state; + + guint num_object_proxy_added_signals; + guint num_object_proxy_removed_signals; + guint num_interface_added_signals; + guint num_interface_removed_signals; +} OMData; + +static gint +my_pstrcmp (const gchar **a, const gchar **b) +{ + return g_strcmp0 (*a, *b); +} + +static void +om_check_interfaces_added (const gchar *signal_name, + GVariant *parameters, + const gchar *object_path, + const gchar *first_interface_name, + ...) +{ + const gchar *path; + GVariant *array; + guint n; + GPtrArray *interfaces; + GPtrArray *interfaces_in_message; + va_list var_args; + const gchar *str; + + interfaces = g_ptr_array_new (); + g_ptr_array_add (interfaces, (gpointer) first_interface_name); + va_start (var_args, first_interface_name); + do + { + str = va_arg (var_args, const gchar *); + if (str == NULL) + break; + g_ptr_array_add (interfaces, (gpointer) str); + } + while (TRUE); + va_end (var_args); + + g_variant_get (parameters, "(&o*)", &path, &array); + g_assert_cmpstr (signal_name, ==, "InterfacesAdded"); + g_assert_cmpstr (path, ==, object_path); + g_assert_cmpint (g_variant_n_children (array), ==, interfaces->len); + interfaces_in_message = g_ptr_array_new (); + for (n = 0; n < interfaces->len; n++) + { + const gchar *iface_name; + g_variant_get_child (array, n, "{&sa{sv}}", &iface_name, NULL); + g_ptr_array_add (interfaces_in_message, (gpointer) iface_name); + } + g_assert_cmpint (interfaces_in_message->len, ==, interfaces->len); + g_ptr_array_sort (interfaces, (GCompareFunc) my_pstrcmp); + g_ptr_array_sort (interfaces_in_message, (GCompareFunc) my_pstrcmp); + for (n = 0; n < interfaces->len; n++) + g_assert_cmpstr (interfaces->pdata[n], ==, interfaces_in_message->pdata[n]); + g_ptr_array_unref (interfaces_in_message); + g_ptr_array_unref (interfaces); + g_variant_unref (array); +} + +static void +om_check_interfaces_removed (const gchar *signal_name, + GVariant *parameters, + const gchar *object_path, + const gchar *first_interface_name, + ...) +{ + const gchar *path; + GVariant *array; + guint n; + GPtrArray *interfaces; + GPtrArray *interfaces_in_message; + va_list var_args; + const gchar *str; + + interfaces = g_ptr_array_new (); + g_ptr_array_add (interfaces, (gpointer) first_interface_name); + va_start (var_args, first_interface_name); + do + { + str = va_arg (var_args, const gchar *); + if (str == NULL) + break; + g_ptr_array_add (interfaces, (gpointer) str); + } + while (TRUE); + va_end (var_args); + + g_variant_get (parameters, "(&o*)", &path, &array); + g_assert_cmpstr (signal_name, ==, "InterfacesRemoved"); + g_assert_cmpstr (path, ==, object_path); + g_assert_cmpint (g_variant_n_children (array), ==, interfaces->len); + interfaces_in_message = g_ptr_array_new (); + for (n = 0; n < interfaces->len; n++) + { + const gchar *iface_name; + g_variant_get_child (array, n, "&s", &iface_name, NULL); + g_ptr_array_add (interfaces_in_message, (gpointer) iface_name); + } + g_assert_cmpint (interfaces_in_message->len, ==, interfaces->len); + g_ptr_array_sort (interfaces, (GCompareFunc) my_pstrcmp); + g_ptr_array_sort (interfaces_in_message, (GCompareFunc) my_pstrcmp); + for (n = 0; n < interfaces->len; n++) + g_assert_cmpstr (interfaces->pdata[n], ==, interfaces_in_message->pdata[n]); + g_ptr_array_unref (interfaces_in_message); + g_ptr_array_unref (interfaces); + g_variant_unref (array); +} + +static void +om_on_signal (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + OMData *om_data = user_data; + + //g_debug ("foo: %s", g_variant_print (parameters, TRUE)); + + switch (om_data->state) + { + default: + case 0: + g_printerr ("failing and om_data->state=%d on signal %s, params=%s\n", + om_data->state, + signal_name, + g_variant_print (parameters, TRUE)); + g_assert_not_reached (); + break; + + case 1: + om_check_interfaces_added (signal_name, parameters, "/managed/first", + "org.project.Bar", NULL); + om_data->state = 2; + g_main_loop_quit (om_data->loop); + break; + + case 3: + om_check_interfaces_removed (signal_name, parameters, "/managed/first", + "org.project.Bar", NULL); + om_data->state = 5; + /* keep running the loop */ + break; + + case 5: + om_check_interfaces_added (signal_name, parameters, "/managed/first", + "org.project.Bar", NULL); + om_data->state = 6; + g_main_loop_quit (om_data->loop); + break; + + case 7: + om_check_interfaces_removed (signal_name, parameters, "/managed/first", + "org.project.Bar", NULL); + om_data->state = 9; + /* keep running the loop */ + break; + + case 9: + om_check_interfaces_added (signal_name, parameters, "/managed/first", + "org.project.Bar", NULL); + om_data->state = 10; + g_main_loop_quit (om_data->loop); + break; + + case 11: + om_check_interfaces_added (signal_name, parameters, "/managed/first", + "org.project.Bat", NULL); + om_data->state = 12; + g_main_loop_quit (om_data->loop); + break; + + case 13: + om_check_interfaces_removed (signal_name, parameters, "/managed/first", + "org.project.Bar", NULL); + om_data->state = 14; + g_main_loop_quit (om_data->loop); + break; + + case 15: + om_check_interfaces_removed (signal_name, parameters, "/managed/first", + "org.project.Bat", NULL); + om_data->state = 16; + g_main_loop_quit (om_data->loop); + break; + + case 17: + om_check_interfaces_added (signal_name, parameters, "/managed/first", + "com.acme.Coyote", NULL); + om_data->state = 18; + g_main_loop_quit (om_data->loop); + break; + + case 101: + om_check_interfaces_added (signal_name, parameters, "/managed/second", + "org.project.Bat", "org.project.Bar", NULL); + om_data->state = 102; + g_main_loop_quit (om_data->loop); + break; + + case 103: + om_check_interfaces_removed (signal_name, parameters, "/managed/second", + "org.project.Bat", "org.project.Bar", NULL); + om_data->state = 104; + g_main_loop_quit (om_data->loop); + break; + + case 200: + om_check_interfaces_added (signal_name, parameters, "/managed/first_1", + "com.acme.Coyote", NULL); + om_data->state = 201; + g_main_loop_quit (om_data->loop); + break; + } +} + +static GAsyncResult *om_res = NULL; + +static void +om_pm_start_cb (FooiGenObjectManagerClient *manager, + GAsyncResult *res, + gpointer user_data) +{ + GMainLoop *loop = user_data; + om_res = g_object_ref (res); + g_main_loop_quit (loop); +} + +static void +on_interface_added (GDBusObject *object, + GDBusInterface *interface, + gpointer user_data) +{ + OMData *om_data = user_data; + om_data->num_interface_added_signals += 1; +} + +static void +on_interface_removed (GDBusObject *object, + GDBusInterface *interface, + gpointer user_data) +{ + OMData *om_data = user_data; + om_data->num_interface_removed_signals += 1; +} + +static void +on_object_proxy_added (GDBusObjectManagerClient *manager, + GDBusObjectProxy *object_proxy, + gpointer user_data) +{ + OMData *om_data = user_data; + om_data->num_object_proxy_added_signals += 1; + g_signal_connect (object_proxy, + "interface-added", + G_CALLBACK (on_interface_added), + om_data); + g_signal_connect (object_proxy, + "interface-removed", + G_CALLBACK (on_interface_removed), + om_data); +} + +static void +on_object_proxy_removed (GDBusObjectManagerClient *manager, + GDBusObjectProxy *object_proxy, + gpointer user_data) +{ + OMData *om_data = user_data; + om_data->num_object_proxy_removed_signals += 1; + g_assert_cmpint (g_signal_handlers_disconnect_by_func (object_proxy, + G_CALLBACK (on_interface_added), + om_data), ==, 1); + g_assert_cmpint (g_signal_handlers_disconnect_by_func (object_proxy, + G_CALLBACK (on_interface_removed), + om_data), ==, 1); +} + +static void +property_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + gboolean *changed = user_data; + + *changed = TRUE; +} + +static void +om_check_property_and_signal_emission (GMainLoop *loop, + FooiGenBar *skeleton, + FooiGenBar *proxy) +{ + gboolean d_changed = FALSE; + gboolean quiet_changed = FALSE; + gboolean quiet_too_changed = FALSE; + guint handler; + + /* First PropertiesChanged */ + g_assert_cmpint (foo_igen_bar_get_i (skeleton), ==, 0); + g_assert_cmpint (foo_igen_bar_get_i (proxy), ==, 0); + foo_igen_bar_set_i (skeleton, 1); + _g_assert_property_notify (proxy, "i"); + g_assert_cmpint (foo_igen_bar_get_i (skeleton), ==, 1); + g_assert_cmpint (foo_igen_bar_get_i (proxy), ==, 1); + + /* Double-check the gdouble case */ + g_assert_cmpfloat (foo_igen_bar_get_d (skeleton), ==, 0.0); + g_assert_cmpfloat (foo_igen_bar_get_d (proxy), ==, 0.0); + foo_igen_bar_set_d (skeleton, 1.0); + _g_assert_property_notify (proxy, "d"); + + /* Verify that re-setting it to the same value doesn't cause a + * notify on the proxy, by taking advantage of the fact that + * notifications are serialized. + */ + handler = g_signal_connect (proxy, "notify::d", + G_CALLBACK (property_changed), &d_changed); + foo_igen_bar_set_d (skeleton, 1.0); + foo_igen_bar_set_i (skeleton, 2); + _g_assert_property_notify (proxy, "i"); + g_assert (d_changed == FALSE); + g_signal_handler_disconnect (proxy, handler); + + /* Verify that re-setting a property with the "EmitsChangedSignal" + * set to false doesn't emit a signal. */ + handler = g_signal_connect (proxy, "notify::quiet", + G_CALLBACK (property_changed), &quiet_changed); + foo_igen_bar_set_quiet (skeleton, "hush!"); + foo_igen_bar_set_i (skeleton, 3); + _g_assert_property_notify (proxy, "i"); + g_assert (quiet_changed == FALSE); + g_assert_cmpstr (foo_igen_bar_get_quiet (skeleton), ==, "hush!"); + g_signal_handler_disconnect (proxy, handler); + + /* Also verify that re-setting a property with the "EmitsChangedSignal" + * set to 'const' doesn't emit a signal. */ + handler = g_signal_connect (proxy, "notify::quiet-too", + G_CALLBACK (property_changed), &quiet_changed); + foo_igen_bar_set_quiet_too (skeleton, "hush too!"); + foo_igen_bar_set_i (skeleton, 4); + _g_assert_property_notify (proxy, "i"); + g_assert (quiet_too_changed == FALSE); + g_assert_cmpstr (foo_igen_bar_get_quiet_too (skeleton), ==, "hush too!"); + g_signal_handler_disconnect (proxy, handler); + + /* Then just a regular signal */ + foo_igen_bar_emit_another_signal (skeleton, "word"); + _g_assert_signal_received (proxy, "another-signal"); +} + +static void +check_object_manager (void) +{ + FooiGenObjectSkeleton *o = NULL; + FooiGenObjectSkeleton *o2 = NULL; + FooiGenObjectSkeleton *o3 = NULL; + GDBusInterfaceSkeleton *i; + GDBusConnection *c; + GDBusObjectManagerServer *manager = NULL; + GDBusNodeInfo *info; + GError *error; + GMainLoop *loop; + OMData *om_data = NULL; + guint om_signal_id = 0; + GDBusObjectManager *pm = NULL; + GList *object_proxies; + GList *proxies; + GDBusObject *op; + GDBusProxy *p; + FooiGenBar *bar_skeleton; + GDBusInterface *iface; + gchar *path, *name, *name_owner; + GDBusConnection *c2; + GDBusObjectManagerClientFlags flags; + + loop = g_main_loop_new (NULL, FALSE); + + om_data = g_new0 (OMData, 1); + om_data->loop = loop; + om_data->state = 0; + + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (c != NULL); + + om_signal_id = g_dbus_connection_signal_subscribe (c, + NULL, /* sender */ + "org.freedesktop.DBus.ObjectManager", + NULL, /* member */ + NULL, /* object_path */ + NULL, /* arg0 */ + G_DBUS_SIGNAL_FLAGS_NONE, + om_on_signal, + om_data, + NULL); /* user_data_free_func */ + + /* Our GDBusObjectManagerClient tests are simple - we basically just count the + * number of times the various signals have been emitted (we don't check + * that the right objects/interfaces are passed though - that's checked + * in the lower-level tests in om_on_signal()...) + * + * Note that these tests rely on the D-Bus signal handlers used by + * GDBusObjectManagerClient firing before om_on_signal(). + */ + error = NULL; + pm = foo_igen_object_manager_client_new_sync (c, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + g_dbus_connection_get_unique_name (c), + "/managed", + NULL, /* GCancellable */ + &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_error_free (error); + g_assert (pm == NULL); + + manager = g_dbus_object_manager_server_new ("/managed"); + + g_assert (g_dbus_object_manager_server_get_connection (manager) == NULL); + + g_dbus_object_manager_server_set_connection (manager, c); + + g_assert_cmpstr (g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)), ==, "/managed"); + g_object_get (manager, "object-path", &path, "connection", &c2, NULL); + g_assert_cmpstr (path, ==, "/managed"); + g_assert (c2 == c); + g_free (path); + g_clear_object (&c2); + + /* Check that the manager object is visible */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed", loop); + g_assert_cmpint (count_interfaces (info), ==, 4); /* ObjectManager + Properties,Introspectable,Peer */ + g_assert (has_interface (info, "org.freedesktop.DBus.ObjectManager")); + g_assert_cmpint (count_nodes (info), ==, 0); + g_dbus_node_info_unref (info); + + /* Check GetManagedObjects() - should be empty since we have no objects */ + om_check_get_all (c, loop, + "(@a{oa{sa{sv}}} {},)"); + + /* Now try to create the proxy manager again - this time it should work */ + error = NULL; + foo_igen_object_manager_client_new (c, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + g_dbus_connection_get_unique_name (c), + "/managed", + NULL, /* GCancellable */ + (GAsyncReadyCallback) om_pm_start_cb, + loop); + g_main_loop_run (loop); + error = NULL; + pm = foo_igen_object_manager_client_new_finish (om_res, &error); + g_clear_object (&om_res); + g_assert_no_error (error); + g_assert (pm != NULL); + g_signal_connect (pm, + "object-added", + G_CALLBACK (on_object_proxy_added), + om_data); + g_signal_connect (pm, + "object-removed", + G_CALLBACK (on_object_proxy_removed), + om_data); + + g_assert_cmpstr (g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (pm)), ==, "/managed"); + g_object_get (pm, + "object-path", &path, + "connection", &c2, + "name", &name, + "name-owner", &name_owner, + "flags", &flags, + NULL); + g_assert_cmpstr (path, ==, "/managed"); + g_assert_cmpstr (name, ==, g_dbus_connection_get_unique_name (c)); + g_assert_cmpstr (name_owner, ==, g_dbus_connection_get_unique_name (c)); + g_assert_cmpint (flags, ==, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE); + g_assert (c2 == c); + g_free (path); + g_clear_object (&c2); + g_free (name); + g_free (name_owner); + + /* ... check there are no object proxies yet */ + object_proxies = g_dbus_object_manager_get_objects (pm); + g_assert (object_proxies == NULL); + + /* First, export an object with a single interface (also check that + * g_dbus_interface_get_object() works and that the object isn't reffed) + */ + o = foo_igen_object_skeleton_new ("/managed/first"); + i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ()); + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL); + g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); + foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i)); + g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == G_DBUS_OBJECT (o)); + g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); + foo_igen_object_skeleton_set_bar (o, NULL); + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL); + g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); + foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i)); + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == G_DBUS_OBJECT (o)); + g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); + + o2 = FOO_IGEN_OBJECT_SKELETON (g_dbus_interface_dup_object (G_DBUS_INTERFACE (i))); + g_assert (G_DBUS_OBJECT (o2) == G_DBUS_OBJECT (o)); + g_assert_cmpint (G_OBJECT (o2)->ref_count, ==, 2); + g_clear_object (&o2); + + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (o)); + + /* ... check we get the InterfacesAdded signal */ + om_data->state = 1; + + g_main_loop_run (om_data->loop); + + g_assert_cmpint (om_data->state, ==, 2); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 1); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0); + /* ... check there's one non-standard interfaces */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); + g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */ + g_assert (has_interface (info, "org.project.Bar")); + g_dbus_node_info_unref (info); + + /* Also check g_dbus_object_manager_get_interface */ + iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (manager), "/managed/first", "org.project.Bar"); + g_assert (iface != NULL); + g_clear_object (&iface); + iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (manager), "/managed/first", "org.project.Bat"); + g_assert (iface == NULL); + iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (pm), "/managed/first", "org.project.Bar"); + g_assert (iface != NULL); + g_clear_object (&iface); + iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (pm), "/managed/first", "org.project.Bat"); + g_assert (iface == NULL); + + /* Now, check adding the same interface replaces the existing one */ + foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i)); + /* ... check we get the InterfacesRemoved */ + om_data->state = 3; + g_main_loop_run (om_data->loop); + /* ... and then check we get the InterfacesAdded */ + g_assert_cmpint (om_data->state, ==, 6); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 2); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0); + /* ... check introspection data */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); + g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */ + g_assert (has_interface (info, "org.project.Bar")); + g_dbus_node_info_unref (info); + g_clear_object (&i); + + /* check adding an interface of same type (but not same object) replaces the existing one */ + i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ()); + foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i)); + /* ... check we get the InterfacesRemoved and then InterfacesAdded */ + om_data->state = 7; + g_main_loop_run (om_data->loop); + g_assert_cmpint (om_data->state, ==, 10); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0); + /* ... check introspection data */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); + g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */ + g_assert (has_interface (info, "org.project.Bar")); + g_dbus_node_info_unref (info); + g_clear_object (&i); + + /* check adding an interface of another type doesn't replace the existing one */ + i = G_DBUS_INTERFACE_SKELETON (foo_igen_bat_skeleton_new ()); + foo_igen_object_skeleton_set_bat (o, FOO_IGEN_BAT (i)); + g_clear_object (&i); + /* ... check we get the InterfacesAdded */ + om_data->state = 11; + g_main_loop_run (om_data->loop); + g_assert_cmpint (om_data->state, ==, 12); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0); + /* ... check introspection data */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); + g_assert_cmpint (count_interfaces (info), ==, 5); /* Bar,Bat + Properties,Introspectable,Peer */ + g_assert (has_interface (info, "org.project.Bar")); + g_assert (has_interface (info, "org.project.Bat")); + g_dbus_node_info_unref (info); + + /* check we can remove an interface */ + foo_igen_object_skeleton_set_bar (o, NULL); + /* ... check we get the InterfacesRemoved */ + om_data->state = 13; + g_main_loop_run (om_data->loop); + g_assert_cmpint (om_data->state, ==, 14); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); + /* ... check introspection data */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); + g_assert_cmpint (count_interfaces (info), ==, 4); /* Bat + Properties,Introspectable,Peer */ + g_assert (has_interface (info, "org.project.Bat")); + g_dbus_node_info_unref (info); + /* also and that the call only has effect if the interface actually exists + * + * (Note: if a signal was emitted we'd assert in the signal handler + * because we're in state 14) + */ + foo_igen_object_skeleton_set_bar (o, NULL); + /* ... check introspection data */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); + g_assert_cmpint (count_interfaces (info), ==, 4); /* Bat + Properties,Introspectable,Peer */ + g_assert (has_interface (info, "org.project.Bat")); + g_dbus_node_info_unref (info); + + /* remove the last interface */ + foo_igen_object_skeleton_set_bat (o, NULL); + /* ... check we get the InterfacesRemoved */ + om_data->state = 15; + g_main_loop_run (om_data->loop); + g_assert_cmpint (om_data->state, ==, 16); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); + /* ... check introspection data */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); + g_assert_cmpint (count_interfaces (info), ==, 0); /* nothing */ + g_dbus_node_info_unref (info); + + /* and add an interface again */ + i = G_DBUS_INTERFACE_SKELETON (foo_igen_com_acme_coyote_skeleton_new ()); + foo_igen_object_skeleton_set_com_acme_coyote (o, FOO_IGEN_COM_ACME_COYOTE (i)); + g_clear_object (&i); + /* ... check we get the InterfacesAdded */ + om_data->state = 17; + g_main_loop_run (om_data->loop); + g_assert_cmpint (om_data->state, ==, 18); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 4); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); + /* ... check introspection data */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); + g_assert_cmpint (count_interfaces (info), ==, 4); /* com.acme.Coyote + Properties,Introspectable,Peer */ + g_assert (has_interface (info, "com.acme.Coyote")); + g_dbus_node_info_unref (info); + + /* Check GetManagedObjects() - should be just the Coyote */ + om_check_get_all (c, loop, + "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}},)"); + + /* -------------------------------------------------- */ + + /* create a new object with two interfaces */ + o2 = foo_igen_object_skeleton_new ("/managed/second"); + i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ()); + bar_skeleton = FOO_IGEN_BAR (i); /* save for later test */ + foo_igen_object_skeleton_set_bar (o2, FOO_IGEN_BAR (i)); + g_clear_object (&i); + i = G_DBUS_INTERFACE_SKELETON (foo_igen_bat_skeleton_new ()); + foo_igen_object_skeleton_set_bat (o2, FOO_IGEN_BAT (i)); + g_clear_object (&i); + /* ... add it */ + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (o2)); + /* ... check we get the InterfacesAdded with _two_ interfaces */ + om_data->state = 101; + g_main_loop_run (om_data->loop); + g_assert_cmpint (om_data->state, ==, 102); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 5); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); + + /* -------------------------------------------------- */ + + /* Now that we have a couple of objects with interfaces, check + * that ObjectManager.GetManagedObjects() works + */ + om_check_get_all (c, loop, + "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': , 'b': , 'n': , 'q': , 'i': <0>, 'u': , 'x': , 't': , 'd': <0.0>, 's': <''>, 'o': , 'g': , 'ay': , 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'quiet': <''>, 'quiet_too': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': , 'unset_g': , 'unset_ay': , 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)"); + + /* Set connection to NULL, causing everything to be unexported.. verify this.. and + * then set the connection back.. and then check things still work + */ + g_dbus_object_manager_server_set_connection (manager, NULL); + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed", loop); + g_assert_cmpint (count_interfaces (info), ==, 0); /* nothing */ + g_dbus_node_info_unref (info); + + g_dbus_object_manager_server_set_connection (manager, c); + om_check_get_all (c, loop, + "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': , 'b': , 'n': , 'q': , 'i': <0>, 'u': , 'x': , 't': , 'd': <0.0>, 's': <''>, 'o': , 'g': , 'ay': , 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'quiet': <''>, 'quiet_too': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': , 'unset_g': , 'unset_ay': , 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)"); + + /* Also check that the ObjectManagerClient returns these objects - and + * that they are of the right GType cf. what was requested via + * the generated ::get-proxy-type signal handler + */ + object_proxies = g_dbus_object_manager_get_objects (pm); + g_assert (g_list_length (object_proxies) == 2); + g_list_free_full (object_proxies, g_object_unref); + op = g_dbus_object_manager_get_object (pm, "/managed/first"); + g_assert (op != NULL); + g_assert (FOO_IGEN_IS_OBJECT_PROXY (op)); + g_assert_cmpstr (g_dbus_object_get_object_path (op), ==, "/managed/first"); + proxies = g_dbus_object_get_interfaces (op); + g_assert (g_list_length (proxies) == 1); + g_list_free_full (proxies, g_object_unref); + p = G_DBUS_PROXY (foo_igen_object_get_com_acme_coyote (FOO_IGEN_OBJECT (op))); + g_assert (p != NULL); + g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_COM_ACME_COYOTE_PROXY); + g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_COM_ACME_COYOTE)); + g_clear_object (&p); + p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting"); + g_assert (p == NULL); + g_clear_object (&op); + + /* -- */ + op = g_dbus_object_manager_get_object (pm, "/managed/second"); + g_assert (op != NULL); + g_assert (FOO_IGEN_IS_OBJECT_PROXY (op)); + g_assert_cmpstr (g_dbus_object_get_object_path (op), ==, "/managed/second"); + proxies = g_dbus_object_get_interfaces (op); + g_assert (g_list_length (proxies) == 2); + g_list_free_full (proxies, g_object_unref); + p = G_DBUS_PROXY (foo_igen_object_get_bat (FOO_IGEN_OBJECT (op))); + g_assert (p != NULL); + g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_BAT_PROXY); + g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_BAT)); + g_clear_object (&p); + p = G_DBUS_PROXY (foo_igen_object_get_bar (FOO_IGEN_OBJECT (op))); + g_assert (p != NULL); + g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_BAR_PROXY); + g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_BAR)); + /* ... now that we have a Bar instance around, also check that we get signals + * and property changes... + */ + om_check_property_and_signal_emission (loop, bar_skeleton, FOO_IGEN_BAR (p)); + g_clear_object (&p); + p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting"); + g_assert (p == NULL); + g_clear_object (&op); + + /* -------------------------------------------------- */ + + /* Now remove the second object added above */ + g_dbus_object_manager_server_unexport (manager, "/managed/second"); + /* ... check we get InterfacesRemoved with both interfaces */ + om_data->state = 103; + g_main_loop_run (om_data->loop); + g_assert_cmpint (om_data->state, ==, 104); + g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 5); + g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 4); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); + /* ... check introspection data (there should be nothing) */ + info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/second", loop); + g_assert_cmpint (count_nodes (info), ==, 0); + g_assert_cmpint (count_interfaces (info), ==, 0); + g_dbus_node_info_unref (info); + + /* Check GetManagedObjects() again */ + om_check_get_all (c, loop, + "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}},)"); + /* -------------------------------------------------- */ + + /* Check that export_uniquely() works */ + + o3 = foo_igen_object_skeleton_new ("/managed/first"); + i = G_DBUS_INTERFACE_SKELETON (foo_igen_com_acme_coyote_skeleton_new ()); + foo_igen_com_acme_coyote_set_mood (FOO_IGEN_COM_ACME_COYOTE (i), "indifferent"); + foo_igen_object_skeleton_set_com_acme_coyote (o3, FOO_IGEN_COM_ACME_COYOTE (i)); + g_clear_object (&i); + g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (o3)); + /* ... check we get the InterfacesAdded signal */ + om_data->state = 200; + g_main_loop_run (om_data->loop); + g_assert_cmpint (om_data->state, ==, 201); + + om_check_get_all (c, loop, + "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/first_1': {'com.acme.Coyote': {'Mood': <'indifferent'>}}},)"); + + //g_main_loop_run (loop); /* TODO: tmp */ + + /* Clean up objects */ + g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/first_1")); + //g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/second")); + g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/first")); + g_assert_cmpint (g_list_length (g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager))), ==, 0); + + if (loop != NULL) + g_main_loop_unref (loop); + + if (om_signal_id != 0) + g_dbus_connection_signal_unsubscribe (c, om_signal_id); + g_clear_object (&o3); + g_clear_object (&o2); + g_clear_object (&o); + g_clear_object (&manager); + if (pm != NULL) + { + g_assert_cmpint (g_signal_handlers_disconnect_by_func (pm, + G_CALLBACK (on_object_proxy_added), + om_data), ==, 1); + g_assert_cmpint (g_signal_handlers_disconnect_by_func (pm, + G_CALLBACK (on_object_proxy_removed), + om_data), ==, 1); + g_clear_object (&pm); + } + g_clear_object (&c); + + g_free (om_data); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +test_object_manager (void) +{ + GMainLoop *loop; + guint id; + + loop = g_main_loop_new (NULL, FALSE); + + id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gtk.GDBus.BindingsTool.Test", + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + loop, + NULL); + + g_main_loop_run (loop); + + check_object_manager (); + + /* uncomment to keep the service around (to e.g. introspect it) */ + /* g_main_loop_run (loop); */ + + unexport_objects (); + + g_bus_unown_name (id); + g_main_loop_unref (loop); +} + +/* ---------------------------------------------------------------------------------------------------- */ +/* This checks that forcing names via org.gtk.GDBus.Name works (see test-codegen.xml) */ + +extern gpointer name_forcing_1; +extern gpointer name_forcing_2; +extern gpointer name_forcing_3; +extern gpointer name_forcing_4; +extern gpointer name_forcing_5; +extern gpointer name_forcing_6; +extern gpointer name_forcing_7; +gpointer name_forcing_1 = foo_igen_rocket123_get_type; +gpointer name_forcing_2 = foo_igen_rocket123_call_ignite_xyz; +gpointer name_forcing_3 = foo_igen_rocket123_emit_exploded_xyz; +gpointer name_forcing_4 = foo_igen_rocket123_get_speed_xyz; +gpointer name_forcing_5 = foo_igen_test_ugly_case_interface_call_get_iscsi_servers; +gpointer name_forcing_6 = foo_igen_test_ugly_case_interface_emit_servers_updated_now; +gpointer name_forcing_7 = foo_igen_test_ugly_case_interface_get_ugly_name; + +/* ---------------------------------------------------------------------------------------------------- */ + +/* See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5 for details */ + +#define CHECK_FIELD(name, v1, v2) g_assert_cmpint (G_STRUCT_OFFSET (FooiGenChangingInterface##v1##Iface, name), ==, G_STRUCT_OFFSET (FooiGenChangingInterface##v2##Iface, name)); + +static void +test_interface_stability (void) +{ + CHECK_FIELD(handle_foo_method, V1, V2); + CHECK_FIELD(handle_bar_method, V1, V2); + CHECK_FIELD(handle_baz_method, V1, V2); + CHECK_FIELD(foo_signal, V1, V2); + CHECK_FIELD(bar_signal, V1, V2); + CHECK_FIELD(baz_signal, V1, V2); + CHECK_FIELD(handle_new_method_in2, V2, V10); + CHECK_FIELD(new_signal_in2, V2, V10); +} + +#undef CHECK_FIELD + +/* ---------------------------------------------------------------------------------------------------- */ + +/* property naming + * + * - check that a property with name "Type" is mapped into g-name "type" + * with C accessors get_type_ (to avoid clashing with the GType accessor) + * and set_type_ (for symmetry) + * (see https://bugzilla.gnome.org/show_bug.cgi?id=679473 for details) + * + * - (could add more tests here) + */ + +static void +test_property_naming (void) +{ + gpointer c_getter_name = foo_igen_naming_get_type_; + gpointer c_setter_name = foo_igen_naming_set_type_; + FooiGenNaming *skel; + + (void) c_getter_name; + (void) c_setter_name; + + skel = foo_igen_naming_skeleton_new (); + g_assert (g_object_class_find_property (G_OBJECT_GET_CLASS (skel), "type") != NULL); + g_object_unref (skel); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* autocleanups + * + * - check that g_autoptr() works for all generated types, if supported by the + * current compiler + */ + +static void +test_autocleanups (void) +{ +#ifdef g_autoptr + g_autoptr(FooiGenBar) bar = NULL; + g_autoptr(FooiGenBarProxy) bar_proxy = NULL; + g_autoptr(FooiGenBarSkeleton) bar_skeleton = NULL; + g_autoptr(FooiGenObject) object = NULL; + g_autoptr(FooiGenObjectProxy) object_proxy = NULL; + g_autoptr(FooiGenObjectSkeleton) object_skeleton = NULL; + g_autoptr(FooiGenObjectManagerClient) object_manager_client = NULL; + + (void) bar; + (void) bar_proxy; + (void) bar_skeleton; + (void) object; + (void) object_proxy; + (void) object_skeleton; + (void) object_manager_client; +#elif GLIB_CHECK_VERSION(2, 38, 0) + /* This file is compiled twice, once without GLib version guards and once + * with + * + * -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36 + * -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36 + * + * g_test_skip() was added in 2.38. + */ + g_test_skip ("g_autoptr() not supported on this compiler"); +#else + /* Let's just say it passed. */ +#endif +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/* deprecations + */ + +static void +test_deprecations (void) +{ + { + FooiGenOldieInterface *iskel; + GParamSpec *pspec; + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + iskel = foo_igen_oldie_interface_skeleton_new (); + G_GNUC_END_IGNORE_DEPRECATIONS; + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (iskel), "bat"); + g_assert_nonnull (pspec); + g_assert_cmpint (pspec->flags & G_PARAM_DEPRECATED, ==, G_PARAM_DEPRECATED); + + g_object_unref (iskel); + } + + { + FooiGenObjectSkeleton *oskel; + GParamSpec *pspec; + + oskel = foo_igen_object_skeleton_new ("/objects/first"); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (oskel), "oldie-interface"); + g_assert_nonnull (pspec); + g_assert_cmpint (pspec->flags & G_PARAM_DEPRECATED, ==, G_PARAM_DEPRECATED); + + g_object_unref (oskel); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +assert_arg_infos_equal (GDBusArgInfo **a, + GDBusArgInfo **b) +{ + if (a == NULL) + { + g_assert_null (b); + return; + } + + g_assert_nonnull (b); + + for (; *a != NULL && *b != NULL; a++, b++) + { + g_assert_cmpstr ((*a)->name, ==, (*b)->name); + g_assert_cmpstr ((*a)->signature, ==, (*b)->signature); + } + + g_assert_null (*a); + g_assert_null (*b); +} + +static void +assert_annotations_equal (GDBusAnnotationInfo **a, + GDBusAnnotationInfo **b) +{ + guint a_len = count_annotations (a); + guint b_len = count_annotations (b); + + g_assert_cmpuint (a_len, ==, b_len); + + if (a == NULL || b == NULL) + return; + + for (; *a != NULL && *b != NULL; a++, b++) + { + g_assert_cmpstr ((*a)->key, ==, (*b)->key); + g_assert_cmpstr ((*a)->value, ==, (*b)->value); + assert_annotations_equal ((*a)->annotations, (*b)->annotations); + } + + g_assert_null (*a); + g_assert_null (*b); +} + +/* Test that the GDBusInterfaceInfo structure generated by gdbus-codegen + * --interface-info-body matches that generated by the other mode. + */ +static void +test_standalone_interface_info (void) +{ + GDBusInterfaceSkeleton *skel = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ()); + GDBusInterfaceInfo *skel_info = g_dbus_interface_skeleton_get_info (skel); + const GDBusInterfaceInfo *slim_info = &org_project_bar_interface; + gsize i; + + g_assert_cmpstr (skel_info->name, ==, slim_info->name); + + for (i = 0; skel_info->methods[i] != NULL; i++) + { + GDBusMethodInfo *skel_method = skel_info->methods[i]; + GDBusMethodInfo *slim_method = slim_info->methods[i]; + + g_assert_nonnull (slim_method); + g_assert_cmpstr (skel_method->name, ==, slim_method->name); + assert_arg_infos_equal (skel_method->in_args, slim_method->in_args); + assert_arg_infos_equal (skel_method->out_args, slim_method->out_args); + assert_annotations_equal (skel_method->annotations, slim_method->annotations); + } + g_assert_null (slim_info->methods[i]); + + for (i = 0; skel_info->signals[i] != NULL; i++) + { + GDBusSignalInfo *skel_signal = skel_info->signals[i]; + GDBusSignalInfo *slim_signal = slim_info->signals[i]; + + g_assert_nonnull (slim_signal); + g_assert_cmpstr (skel_signal->name, ==, slim_signal->name); + assert_arg_infos_equal (skel_signal->args, slim_signal->args); + assert_annotations_equal (skel_signal->annotations, slim_signal->annotations); + } + g_assert_null (slim_info->signals[i]); + + for (i = 0; skel_info->properties[i] != NULL; i++) + { + GDBusPropertyInfo *skel_prop = skel_info->properties[i]; + GDBusPropertyInfo *slim_prop = slim_info->properties[i]; + + g_assert_nonnull (slim_prop); + + g_assert_cmpstr (skel_prop->name, ==, slim_prop->name); + g_assert_cmpstr (skel_prop->signature, ==, slim_prop->signature); + g_assert_cmpuint (skel_prop->flags, ==, slim_prop->flags); + assert_annotations_equal (skel_prop->annotations, slim_prop->annotations); + } + g_assert_null (slim_info->properties[i]); + + assert_annotations_equal (skel_info->annotations, slim_info->annotations); + + g_clear_object (&skel); +} + +/* ---------------------------------------------------------------------------------------------------- */ +static gboolean +handle_hello_fd (FooiGenFDPassing *object, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + const gchar *arg_greeting) +{ + foo_igen_fdpassing_complete_hello_fd (object, invocation, fd_list, arg_greeting); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_64 +static gboolean +handle_no_annotation (FooiGenFDPassing *object, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_greeting, + const gchar *arg_greeting_locale) +{ + foo_igen_fdpassing_complete_no_annotation (object, invocation, fd_list, arg_greeting, arg_greeting_locale); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +handle_no_annotation_nested (FooiGenFDPassing *object, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_files) +{ + foo_igen_fdpassing_complete_no_annotation_nested (object, invocation, fd_list); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} +#else +static gboolean +handle_no_annotation (FooiGenFDPassing *object, + GDBusMethodInvocation *invocation, + GVariant *arg_greeting, + const gchar *arg_greeting_locale) +{ + foo_igen_fdpassing_complete_no_annotation (object, invocation, arg_greeting, arg_greeting_locale); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +handle_no_annotation_nested (FooiGenFDPassing *object, + GDBusMethodInvocation *invocation, + GVariant *arg_files) +{ + foo_igen_fdpassing_complete_no_annotation_nested (object, invocation); + return G_DBUS_METHOD_INVOCATION_HANDLED; +} +#endif + +/* Test that generated code for methods includes GUnixFDList arguments + * unconditionally if the method is explicitly annotated as C.UnixFD, and only + * emits GUnixFDList arguments when there's merely an 'h' parameter if + * --glib-min-required=2.64 or greater. + */ +static void +test_unix_fd_list (void) +{ + FooiGenFDPassingIface iface; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1726"); + + /* This method is explicitly annotated. */ + iface.handle_hello_fd = handle_hello_fd; + + /* This one is not annotated; even though it's got an in and out 'h' + * parameter, for backwards compatibility we cannot emit GUnixFDList + * arguments unless --glib-min-required >= 2.64 was used. + */ + iface.handle_no_annotation = handle_no_annotation; + + /* This method has an 'h' inside a complex type. */ + iface.handle_no_annotation_nested = handle_no_annotation_nested; + + (void) iface; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gdbus/codegen/annotations", test_annotations); + g_test_add_func ("/gdbus/codegen/interface_stability", test_interface_stability); + g_test_add_func ("/gdbus/codegen/object-manager", test_object_manager); + g_test_add_func ("/gdbus/codegen/property-naming", test_property_naming); + g_test_add_func ("/gdbus/codegen/autocleanups", test_autocleanups); + g_test_add_func ("/gdbus/codegen/deprecations", test_deprecations); + g_test_add_func ("/gdbus/codegen/standalone-interface-info", test_standalone_interface_info); + g_test_add_func ("/gdbus/codegen/unix-fd-list", test_unix_fd_list); + + return session_bus_run (); +} diff --git a/gio/tests/gdbus-test-fixture.c b/gio/tests/gdbus-test-fixture.c new file mode 100644 index 0000000..2071bba --- /dev/null +++ b/gio/tests/gdbus-test-fixture.c @@ -0,0 +1,100 @@ + +#include "gdbus-object-manager-example/objectmanager-gen.h" + +/* ---------------------------------------------------------------------------------------------------- */ + +/* The fixture contains a GTestDBus object and + * a proxy to the service we're going to be testing. + */ +typedef struct { + GTestDBus *dbus; + GDBusObjectManager *manager; +} TestFixture; + +static void +fixture_setup (TestFixture *fixture, gconstpointer unused) +{ + GError *error = NULL; + gchar *relative, *servicesdir; + + /* Create the global dbus-daemon for this test suite + */ + fixture->dbus = g_test_dbus_new (G_TEST_DBUS_NONE); + + /* Add the private directory with our in-tree service files. + */ + relative = g_test_build_filename (G_TEST_BUILT, "services", NULL); + servicesdir = g_canonicalize_filename (relative, NULL); + g_free (relative); + + g_test_dbus_add_service_dir (fixture->dbus, servicesdir); + g_free (servicesdir); + + /* Start the private D-Bus daemon + */ + g_test_dbus_up (fixture->dbus); + + /* Create the proxy that we're going to test + */ + fixture->manager = + example_object_manager_client_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + "org.gtk.GDBus.Examples.ObjectManager", + "/example/Animals", + NULL, /* GCancellable */ + &error); + if (fixture->manager == NULL) + g_error ("Error getting object manager client: %s", error->message); +} + +static void +fixture_teardown (TestFixture *fixture, gconstpointer unused) +{ + /* Tear down the proxy + */ + if (fixture->manager) + g_object_unref (fixture->manager); + + /* Stop the private D-Bus daemon + */ + g_test_dbus_down (fixture->dbus); + g_object_unref (fixture->dbus); +} + +/* The gdbus-example-objectmanager-server exports 10 objects, + * to test the server has actually activated, let's ensure + * that 10 objects exist. + */ +static void +test_gtest_dbus (TestFixture *fixture, gconstpointer unused) +{ + GList *objects; + + objects = g_dbus_object_manager_get_objects (fixture->manager); + + g_assert_cmpint (g_list_length (objects), ==, 10); + g_list_free_full (objects, g_object_unref); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + /* This test simply ensures that we can bring the GTestDBus up and down a hand + * full of times in a row, each time successfully activating the in-tree service + */ + g_test_add ("/GTestDBus/Cycle1", TestFixture, NULL, + fixture_setup, test_gtest_dbus, fixture_teardown); + g_test_add ("/GTestDBus/Cycle2", TestFixture, NULL, + fixture_setup, test_gtest_dbus, fixture_teardown); + g_test_add ("/GTestDBus/Cycle3", TestFixture, NULL, + fixture_setup, test_gtest_dbus, fixture_teardown); + g_test_add ("/GTestDBus/Cycle4", TestFixture, NULL, + fixture_setup, test_gtest_dbus, fixture_teardown); + g_test_add ("/GTestDBus/Cycle5", TestFixture, NULL, + fixture_setup, test_gtest_dbus, fixture_teardown); + + return g_test_run (); +} diff --git a/gio/tests/gdbus-tests.c b/gio/tests/gdbus-tests.c new file mode 100644 index 0000000..1003d07 --- /dev/null +++ b/gio/tests/gdbus-tests.c @@ -0,0 +1,234 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#ifndef _MSC_VER +#include +#endif + +#include "gdbus-tests.h" + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GMainLoop *loop; + gboolean timed_out; +} PropertyNotifyData; + +static void +on_property_notify (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + PropertyNotifyData *data = user_data; + g_main_loop_quit (data->loop); +} + +static gboolean +on_property_notify_timeout (gpointer user_data) +{ + PropertyNotifyData *data = user_data; + data->timed_out = TRUE; + g_main_loop_quit (data->loop); + return G_SOURCE_CONTINUE; +} + +gboolean +_g_assert_property_notify_run (gpointer object, + const gchar *property_name) +{ + gchar *s; + gulong handler_id; + guint timeout_id; + PropertyNotifyData data; + + data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE); + data.timed_out = FALSE; + s = g_strdup_printf ("notify::%s", property_name); + handler_id = g_signal_connect (object, + s, + G_CALLBACK (on_property_notify), + &data); + g_free (s); + timeout_id = g_timeout_add_seconds (30, + on_property_notify_timeout, + &data); + g_main_loop_run (data.loop); + g_signal_handler_disconnect (object, handler_id); + g_source_remove (timeout_id); + g_main_loop_unref (data.loop); + + return data.timed_out; +} + +static gboolean +_give_up (gpointer data) +{ + g_error ("%s", (const gchar *) data); + g_return_val_if_reached (G_SOURCE_CONTINUE); +} + +typedef struct +{ + GMainContext *context; + gboolean name_appeared; + gboolean unwatch_complete; +} WatchData; + +static void +name_appeared_cb (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + WatchData *data = user_data; + + g_assert (name_owner != NULL); + data->name_appeared = TRUE; + g_main_context_wakeup (data->context); +} + +static void +watch_free_cb (gpointer user_data) +{ + WatchData *data = user_data; + + data->unwatch_complete = TRUE; + g_main_context_wakeup (data->context); +} + +void +ensure_gdbus_testserver_up (GDBusConnection *connection, + GMainContext *context) +{ + GSource *timeout_source = NULL; + guint watch_id; + WatchData data = { context, FALSE, FALSE }; + + g_main_context_push_thread_default (context); + + watch_id = g_bus_watch_name_on_connection (connection, + "com.example.TestService", + G_BUS_NAME_WATCHER_FLAGS_NONE, + name_appeared_cb, + NULL, + &data, + watch_free_cb); + + timeout_source = g_timeout_source_new_seconds (60); + g_source_set_callback (timeout_source, _give_up, + "waited more than ~ 60s for gdbus-testserver to take its bus name", + NULL); + g_source_attach (timeout_source, context); + + while (!data.name_appeared) + g_main_context_iteration (context, TRUE); + + g_bus_unwatch_name (watch_id); + watch_id = 0; + + while (!data.unwatch_complete) + g_main_context_iteration (context, TRUE); + + g_source_destroy (timeout_source); + g_source_unref (timeout_source); + + g_main_context_pop_thread_default (context); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + GMainLoop *loop; + gboolean timed_out; +} SignalReceivedData; + +static void +on_signal_received (gpointer user_data) +{ + SignalReceivedData *data = user_data; + g_main_loop_quit (data->loop); +} + +static gboolean +on_signal_received_timeout (gpointer user_data) +{ + SignalReceivedData *data = user_data; + data->timed_out = TRUE; + g_main_loop_quit (data->loop); + return G_SOURCE_CONTINUE; +} + +gboolean +_g_assert_signal_received_run (gpointer object, + const gchar *signal_name) +{ + gulong handler_id; + guint timeout_id; + SignalReceivedData data; + + data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE); + data.timed_out = FALSE; + handler_id = g_signal_connect_swapped (object, + signal_name, + G_CALLBACK (on_signal_received), + &data); + timeout_id = g_timeout_add_seconds (30, + on_signal_received_timeout, + &data); + g_main_loop_run (data.loop); + g_signal_handler_disconnect (object, handler_id); + g_source_remove (timeout_id); + g_main_loop_unref (data.loop); + + return data.timed_out; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +GDBusConnection * +_g_bus_get_priv (GBusType bus_type, + GCancellable *cancellable, + GError **error) +{ + gchar *address; + GDBusConnection *ret; + + ret = NULL; + + address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error); + if (address == NULL) + goto out; + + ret = g_dbus_connection_new_for_address_sync (address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, + NULL, /* GDBusAuthObserver */ + cancellable, + error); + g_free (address); + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/tests/gdbus-tests.h b/gio/tests/gdbus-tests.h new file mode 100644 index 0000000..eaef234 --- /dev/null +++ b/gio/tests/gdbus-tests.h @@ -0,0 +1,122 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#ifndef __TESTS_H__ +#define __TESTS_H__ + +#include +#include "gdbus-sessionbus.h" + +G_BEGIN_DECLS + +/* TODO: clean up and move to gtestutils.c + * + * This is needed because libdbus-1 does not give predictable error messages - e.g. you + * get a different error message on connecting to a bus if the socket file is there vs + * if the socket file is missing. + */ + +#define _g_assert_error_domain(err, dom) do { if (!err || (err)->domain != dom) \ + g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #err, err, dom, -1); } while (0) + +#define _g_assert_property_notify(object, property_name) \ + do \ + { \ + if (!G_IS_OBJECT (object)) \ + { \ + g_assertion_message (G_LOG_DOMAIN, \ + __FILE__, \ + __LINE__, \ + G_STRFUNC, \ + "Not a GObject instance"); \ + } \ + if (g_object_class_find_property (G_OBJECT_GET_CLASS (object), \ + property_name) == NULL) \ + { \ + g_assertion_message (G_LOG_DOMAIN, \ + __FILE__, \ + __LINE__, \ + G_STRFUNC, \ + "Property " property_name " does not " \ + "exist on object"); \ + } \ + if (_g_assert_property_notify_run (object, property_name)) \ + { \ + g_assertion_message (G_LOG_DOMAIN, \ + __FILE__, \ + __LINE__, \ + G_STRFUNC, \ + "Timed out waiting for notification " \ + "on property " property_name); \ + } \ + } \ + while (FALSE) + +#define _g_assert_signal_received(object, signal_name) \ + do \ + { \ + if (!G_IS_OBJECT (object)) \ + { \ + g_assertion_message (G_LOG_DOMAIN, \ + __FILE__, \ + __LINE__, \ + G_STRFUNC, \ + "Not a GObject instance"); \ + } \ + if (g_signal_lookup (signal_name, \ + G_TYPE_FROM_INSTANCE (object)) == 0) \ + { \ + g_assertion_message (G_LOG_DOMAIN, \ + __FILE__, \ + __LINE__, \ + G_STRFUNC, \ + "Signal '" signal_name "' does not " \ + "exist on object"); \ + } \ + if (_g_assert_signal_received_run (object, signal_name)) \ + { \ + g_assertion_message (G_LOG_DOMAIN, \ + __FILE__, \ + __LINE__, \ + G_STRFUNC, \ + "Timed out waiting for signal '" \ + signal_name "'"); \ + } \ + } \ + while (FALSE) + +gboolean _g_assert_property_notify_run (gpointer object, + const gchar *property_name); + + +gboolean _g_assert_signal_received_run (gpointer object, + const gchar *signal_name); + +GDBusConnection *_g_bus_get_priv (GBusType bus_type, + GCancellable *cancellable, + GError **error); + +void ensure_gdbus_testserver_up (GDBusConnection *connection, + GMainContext *context); + +G_END_DECLS + +#endif /* __TESTS_H__ */ diff --git a/gio/tests/gdbus-testserver.c b/gio/tests/gdbus-testserver.c new file mode 100644 index 0000000..ae8e47b --- /dev/null +++ b/gio/tests/gdbus-testserver.c @@ -0,0 +1,891 @@ +#include +#include + +static GDBusNodeInfo *introspection_data = NULL; +static GMainLoop *loop = NULL; +static GHashTable *properties = NULL; + +static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +static gboolean +end_sleep (gpointer data) +{ + GDBusMethodInvocation *invocation = data; + + g_dbus_method_invocation_return_value (invocation, NULL); + g_object_unref (invocation); + + return G_SOURCE_REMOVE; +} + +static void +handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + if (g_strcmp0 (method_name, "HelloWorld") == 0) + { + const gchar *greeting; + + g_variant_get (parameters, "(&s)", &greeting); + if (g_strcmp0 (greeting, "Yo") == 0) + { + g_dbus_method_invocation_return_dbus_error (invocation, + "com.example.TestException", + "Yo is not a proper greeting"); + } + else + { + gchar *response; + response = g_strdup_printf ("You greeted me with '%s'. Thanks!", greeting); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", response)); + g_free ( response); + } + } + else if (g_strcmp0 (method_name, "DoubleHelloWorld") == 0) + { + const gchar *hello1, *hello2; + gchar *reply1, *reply2; + + g_variant_get (parameters, "(&s&s)", &hello1, &hello2); + reply1 = g_strdup_printf ("You greeted me with '%s'. Thanks!", hello1); + reply2 = g_strdup_printf ("Yo dawg, you uttered '%s'. Thanks!", hello2); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(ss)", reply1, reply2)); + g_free (reply1); + g_free (reply2); + } + else if (g_strcmp0 (method_name, "PairReturn") == 0) + { + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(su)", "foo", 42)); + } + else if (g_strcmp0 (method_name, "TestPrimitiveTypes") == 0) + { + guchar val_byte; + gboolean val_boolean; + gint16 val_int16; + guint16 val_uint16; + gint32 val_int32; + guint32 val_uint32; + gint64 val_int64; + guint64 val_uint64; + gdouble val_double; + const gchar *val_string; + const gchar *val_objpath; + const gchar *val_signature; + gchar *ret_string; + gchar *ret_objpath; + gchar *ret_signature; + + g_variant_get (parameters, "(ybnqiuxtd&s&o&g)", + &val_byte, + &val_boolean, + &val_int16, + &val_uint16, + &val_int32, + &val_uint32, + &val_int64, + &val_uint64, + &val_double, + &val_string, + &val_objpath, + &val_signature); + + ret_string = g_strconcat (val_string, val_string, NULL); + ret_objpath = g_strconcat (val_objpath, "/modified", NULL); + ret_signature = g_strconcat (val_signature, val_signature, NULL); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(ybnqiuxtdsog)", + val_byte + 1, + !val_boolean, + val_int16 + 1, + val_uint16 + 1, + val_int32 + 1, + val_uint32 + 1, + val_int64 + 1, + val_uint64 + 1, + - val_double + 0.123, + ret_string, + ret_objpath, + ret_signature)); + + g_free (ret_string); + g_free (ret_objpath); + g_free (ret_signature); + } + else if (g_strcmp0 (method_name, "TestArrayOfPrimitiveTypes") == 0) + { + GVariant *v; + const guchar *bytes; + const gint16 *int16s; + const guint16 *uint16s; + const gint32 *int32s; + const guint32 *uint32s; + const gint64 *int64s; + const guint64 *uint64s; + const gdouble *doubles; + gsize n_elts; + gsize i, j; + GVariantBuilder ret; + + g_variant_builder_init (&ret, G_VARIANT_TYPE ("(ayabanaqaiauaxatad)")); + + v = g_variant_get_child_value (parameters, 0); + bytes = g_variant_get_fixed_array (v, &n_elts, 1); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("ay")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "y", bytes[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + v = g_variant_get_child_value (parameters, 1); + bytes = g_variant_get_fixed_array (v, &n_elts, 1); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("ab")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "b", (gboolean)bytes[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + v = g_variant_get_child_value (parameters, 2); + int16s = g_variant_get_fixed_array (v, &n_elts, 2); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("an")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "n", int16s[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + v = g_variant_get_child_value (parameters, 3); + uint16s = g_variant_get_fixed_array (v, &n_elts, 2); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("aq")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "q", uint16s[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + v = g_variant_get_child_value (parameters, 4); + int32s = g_variant_get_fixed_array (v, &n_elts, 4); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("ai")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "i", int32s[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + v = g_variant_get_child_value (parameters, 5); + uint32s = g_variant_get_fixed_array (v, &n_elts, 4); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("au")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "u", uint32s[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + v = g_variant_get_child_value (parameters, 6); + int64s = g_variant_get_fixed_array (v, &n_elts, 8); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("ax")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "x", int64s[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + v = g_variant_get_child_value (parameters, 7); + uint64s = g_variant_get_fixed_array (v, &n_elts, 8); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("at")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "t", uint64s[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + v = g_variant_get_child_value (parameters, 8); + doubles = g_variant_get_fixed_array (v, &n_elts, sizeof (gdouble)); + g_variant_builder_open (&ret, G_VARIANT_TYPE ("ad")); + for (j = 0; j < 2; j++) + for (i = 0; i < n_elts; i++) + g_variant_builder_add (&ret, "d", doubles[i]); + g_variant_builder_close (&ret); + g_variant_unref (v); + + g_dbus_method_invocation_return_value (invocation, + g_variant_builder_end (&ret)); + } + else if (g_strcmp0 (method_name, "TestArrayOfStringTypes") == 0) + { + GVariantIter *iter1; + GVariantIter *iter2; + GVariantIter *iter3; + GVariantIter *iter; + GVariantBuilder ret; + const gchar *s; + gint i; + + g_variant_builder_init (&ret, G_VARIANT_TYPE ("(asaoag)")); + g_variant_get (parameters, "(asaoag)", &iter1, &iter2, &iter3); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("as")); + for (i = 0; i < 2; i++) + { + iter = g_variant_iter_copy (iter1); + while (g_variant_iter_loop (iter, "s", &s)) + g_variant_builder_add (&ret, "s", s); + g_variant_iter_free (iter); + } + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("ao")); + for (i = 0; i < 2; i++) + { + iter = g_variant_iter_copy (iter1); + while (g_variant_iter_loop (iter, "o", &s)) + g_variant_builder_add (&ret, "o", s); + g_variant_iter_free (iter); + } + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("ag")); + for (i = 0; i < 2; i++) + { + iter = g_variant_iter_copy (iter1); + while (g_variant_iter_loop (iter, "g", &s)) + g_variant_builder_add (&ret, "g", s); + g_variant_iter_free (iter); + } + g_variant_builder_close (&ret); + + g_variant_iter_free (iter1); + g_variant_iter_free (iter2); + g_variant_iter_free (iter3); + + g_dbus_method_invocation_return_value (invocation, + g_variant_builder_end (&ret)); + } + else if (g_strcmp0 (method_name, "TestHashTables") == 0) + { + GVariant *v; + GVariantIter iter; + GVariantBuilder ret; + guint8 y1, y2; + gboolean b1, b2; + gint16 n1, n2; + guint16 q1, q2; + gint i1, i2; + guint u1, u2; + gint64 x1, x2; + guint64 t1, t2; + gdouble d1, d2; + gchar *s1, *s2; + + g_variant_builder_init (&ret, G_VARIANT_TYPE ("(a{yy}a{bb}a{nn}a{qq}a{ii}a{uu}a{xx}a{tt}a{dd}a{ss}a{oo}a{gg})")); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{yy}")); + v = g_variant_get_child_value (parameters, 0); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "yy", &y1, &y2)) + g_variant_builder_add (&ret, "{yy}", y1 * 2, (y2 * 3) & 255); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{bb}")); + v = g_variant_get_child_value (parameters, 1); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "bb", &b1, &b2)) + g_variant_builder_add (&ret, "{bb}", b1, TRUE); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{nn}")); + v = g_variant_get_child_value (parameters, 2); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "nn", &n1, &n2)) + g_variant_builder_add (&ret, "{nn}", n1 * 2, n2 * 3); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{qq}")); + v = g_variant_get_child_value (parameters, 3); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "qq", &q1, &q2)) + g_variant_builder_add (&ret, "{qq}", q1 * 2, q2 * 3); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{ii}")); + v = g_variant_get_child_value (parameters, 4); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "ii", &i1, &i2)) + g_variant_builder_add (&ret, "{ii}", i1 * 2, i2 * 3); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{uu}")); + v = g_variant_get_child_value (parameters, 5); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "uu", &u1, &u2)) + g_variant_builder_add (&ret, "{uu}", u1 * 2, u2 * 3); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{xx}")); + v = g_variant_get_child_value (parameters, 6); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "xx", &x1, &x2)) + g_variant_builder_add (&ret, "{xx}", x1 + 2, x2 + 1); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{tt}")); + v = g_variant_get_child_value (parameters, 7); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "tt", &t1, &t2)) + g_variant_builder_add (&ret, "{tt}", t1 + 2, t2 + 1); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{dd}")); + v = g_variant_get_child_value (parameters, 8); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "dd", &d1, &d2)) + g_variant_builder_add (&ret, "{dd}", d1 + 2.5, d2 + 5.0); + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{ss}")); + v = g_variant_get_child_value (parameters, 9); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "ss", &s1, &s2)) + { + gchar *tmp1, *tmp2; + tmp1 = g_strconcat (s1, "mod", NULL); + tmp2 = g_strconcat (s2, s2, NULL); + g_variant_builder_add (&ret, "{ss}", tmp1, tmp2); + g_free (tmp1); + g_free (tmp2); + } + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{oo}")); + v = g_variant_get_child_value (parameters, 10); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "oo", &s1, &s2)) + { + gchar *tmp1, *tmp2; + tmp1 = g_strconcat (s1, "/mod", NULL); + tmp2 = g_strconcat (s2, "/mod2", NULL); + g_variant_builder_add (&ret, "{oo}", tmp1, tmp2); + g_free (tmp1); + g_free (tmp2); + } + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_variant_builder_open (&ret, G_VARIANT_TYPE ("a{gg}")); + v = g_variant_get_child_value (parameters, 11); + g_variant_iter_init (&iter, v); + while (g_variant_iter_loop (&iter, "gg", &s1, &s2)) + { + gchar *tmp1, *tmp2; + tmp1 = g_strconcat (s1, "assgit", NULL); + tmp2 = g_strconcat (s2, s2, NULL); + g_variant_builder_add (&ret, "{gg}", tmp1, tmp2); + g_free (tmp1); + g_free (tmp2); + } + g_variant_unref (v); + g_variant_builder_close (&ret); + + g_dbus_method_invocation_return_value (invocation, + g_variant_builder_end (&ret)); + } + else if (g_strcmp0 (method_name, "TestStructureTypes") == 0) + { + gint x, y, x1, y1; + const gchar *desc; + GVariantIter *iter1, *iter2; + gchar *desc_ret; + GVariantBuilder ret1, ret2; + GVariantIter *iter; + GVariant *v; + gchar *s1, *s2; + + g_variant_get (parameters, "((ii)(&s(ii)aya{ss}))", + &x, &y, &desc, &x1, &y1, &iter1, &iter2); + + desc_ret = g_strconcat (desc, "... in bed!", NULL); + + g_variant_builder_init (&ret1, G_VARIANT_TYPE ("ay")); + iter = g_variant_iter_copy (iter1); + while (g_variant_iter_loop (iter1, "y", &v)) + g_variant_builder_add (&ret1, "y", v); + while (g_variant_iter_loop (iter, "y", &v)) + g_variant_builder_add (&ret1, "y", v); + g_variant_iter_free (iter); + g_variant_iter_free (iter1); + + g_variant_builder_init (&ret2, G_VARIANT_TYPE ("a{ss}")); + while (g_variant_iter_loop (iter1, "ss", &s1, &s2)) + { + gchar *tmp; + tmp = g_strconcat (s2, " ... in bed!", NULL); + g_variant_builder_add (&ret1, "{ss}", s1, tmp); + g_free (tmp); + } + g_variant_iter_free (iter2); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("((ii)(&s(ii)aya{ss}))", + x + 1, y + 1, desc_ret, x1 + 2, y1 + 2, + &ret1, &ret2)); + + g_free (desc_ret); + } + else if (g_strcmp0 (method_name, "TestVariant") == 0) + { + GVariant *v; + gboolean modify; + GVariant *ret; + + g_variant_get (parameters, "(vb)", &v, &modify); + + /* FIXME handle more cases */ + if (modify) + { + if (g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) + { + ret = g_variant_new_boolean (FALSE); + } + else if (g_variant_is_of_type (v, G_VARIANT_TYPE_TUPLE)) + { + ret = g_variant_new ("(si)", "other struct", 100); + } + else + g_assert_not_reached (); + } + else + ret = v; + + g_dbus_method_invocation_return_value (invocation, ret); + g_variant_unref (v); + } + else if (g_strcmp0 (method_name, "TestComplexArrays") == 0) + { + /* FIXME */ + g_dbus_method_invocation_return_value (invocation, parameters); + } + else if (g_strcmp0 (method_name, "TestComplexHashTables") == 0) + { + /* FIXME */ + g_dbus_method_invocation_return_value (invocation, parameters); + } + else if (g_strcmp0 (method_name, "FrobSetProperty") == 0) + { + gchar *name; + GVariant *value; + g_variant_get (parameters, "(sv)", &name, &value); + g_hash_table_replace (properties, name, value); + g_dbus_connection_emit_signal (connection, + NULL, + "/com/example/TestObject", + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new_parsed ("('com.example.Frob', [{%s, %v}], @as [])", name, value), + NULL); + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_strcmp0 (method_name, "FrobInvalidateProperty") == 0) + { + const gchar *value; + g_variant_get (parameters, "(&s)", &value); + g_hash_table_replace (properties, g_strdup ("PropertyThatWillBeInvalidated"), g_variant_ref_sink (g_variant_new_string (value))); + + g_dbus_connection_emit_signal (connection, + NULL, + "/com/example/TestObject", + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new_parsed ("('com.example.Frob', @a{sv} [], ['PropertyThatWillBeInvalidated'])"), + NULL); + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_strcmp0 (method_name, "EmitSignal") == 0) + { + const gchar *str; + const gchar *path; + gchar *str_ret; + gchar *path_ret; + g_variant_get (parameters, "(&s&o)", &str, &path); + str_ret = g_strconcat (str, " .. in bed!", NULL); + path_ret = g_strconcat (path, "/in/bed", NULL); + g_dbus_connection_emit_signal (connection, + NULL, + "/com/example/TestObject", + "com.example.Frob", + "TestSignal", + g_variant_new_parsed ("(%s, %o, <'a variant'>)", str_ret, path_ret), + NULL); + g_free (str_ret); + g_free (path_ret); + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_strcmp0 (method_name, "EmitSignal2") == 0) + { + g_dbus_connection_emit_signal (connection, + NULL, + "/com/example/TestObject", + "com.example.Frob", + "TestSignal2", + g_variant_new_parsed ("(42, )"), + NULL); + g_dbus_method_invocation_return_value (invocation, NULL); + } + else if (g_strcmp0 (method_name, "Sleep") == 0) + { + gint msec; + + g_variant_get (parameters, "(i)", &msec); + + g_timeout_add ((guint)msec, end_sleep, g_object_ref (invocation)); + } + else if (g_strcmp0 (method_name, "Quit") == 0) + { + g_dbus_method_invocation_return_value (invocation, NULL); + g_main_loop_quit (loop); + } +} + +static GVariant * +handle_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + GVariant *ret; + + ret = g_hash_table_lookup (properties, property_name); + if (ret) + { + g_assert (!g_variant_is_floating (ret)); + g_variant_ref (ret); + } + else + { + g_set_error (error, + G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "no such property: %s", property_name); + } + + return ret; +} + +static gboolean +handle_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data) +{ + g_set_error (error, + G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "SetProperty not implemented"); + return FALSE; +} + +static const GDBusInterfaceVTable interface_vtable = +{ + handle_method_call, + handle_get_property, + handle_set_property, + { 0 } +}; + +static void +on_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + guint id; + + id = g_dbus_connection_register_object (connection, + "/com/example/TestObject", + introspection_data->interfaces[0], + &interface_vtable, + NULL, + NULL, + NULL); + g_assert (id > 0); +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + exit (1); +} + +int +main (int argc, char *argv[]) +{ + guint owner_id; + + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); + g_hash_table_insert (properties, g_strdup ("y"), g_variant_ref_sink (g_variant_new_byte (1))); + g_hash_table_insert (properties, g_strdup ("b"), g_variant_ref_sink (g_variant_new_boolean (TRUE))); + g_hash_table_insert (properties, g_strdup ("n"), g_variant_ref_sink (g_variant_new_int16 (2))); + g_hash_table_insert (properties, g_strdup ("q"), g_variant_ref_sink (g_variant_new_uint16 (3))); + g_hash_table_insert (properties, g_strdup ("i"), g_variant_ref_sink (g_variant_new_int32 (4))); + g_hash_table_insert (properties, g_strdup ("u"), g_variant_ref_sink (g_variant_new_uint32 (5))); + g_hash_table_insert (properties, g_strdup ("x"), g_variant_ref_sink (g_variant_new_int64 (6))); + g_hash_table_insert (properties, g_strdup ("t"), g_variant_ref_sink (g_variant_new_uint64 (7))); + g_hash_table_insert (properties, g_strdup ("d"), g_variant_ref_sink (g_variant_new_double (7.5))); + g_hash_table_insert (properties, g_strdup ("s"), g_variant_ref_sink (g_variant_new_string ("a string"))); + g_hash_table_insert (properties, g_strdup ("o"), g_variant_ref_sink (g_variant_new_object_path ("/some/path"))); + g_hash_table_insert (properties, g_strdup ("ay"), g_variant_ref_sink (g_variant_new_parsed ("[@y 1, @y 11]"))); + g_hash_table_insert (properties, g_strdup ("ab"), g_variant_ref_sink (g_variant_new_parsed ("[true, false]"))); + g_hash_table_insert (properties, g_strdup ("an"), g_variant_ref_sink (g_variant_new_parsed ("[@n 2, @n 12]"))); + g_hash_table_insert (properties, g_strdup ("aq"), g_variant_ref_sink (g_variant_new_parsed ("[@q 3, @q 13]"))); + g_hash_table_insert (properties, g_strdup ("ai"), g_variant_ref_sink (g_variant_new_parsed ("[@i 4, @i 14]"))); + g_hash_table_insert (properties, g_strdup ("au"), g_variant_ref_sink (g_variant_new_parsed ("[@u 5, @u 15]"))); + g_hash_table_insert (properties, g_strdup ("ax"), g_variant_ref_sink (g_variant_new_parsed ("[@x 6, @x 16]"))); + g_hash_table_insert (properties, g_strdup ("at"), g_variant_ref_sink (g_variant_new_parsed ("[@t 7, @t 17]"))); + g_hash_table_insert (properties, g_strdup ("ad"), g_variant_ref_sink (g_variant_new_parsed ("[7.5, 17.5]"))); + g_hash_table_insert (properties, g_strdup ("as"), g_variant_ref_sink (g_variant_new_parsed ("['a string', 'another string']"))); + g_hash_table_insert (properties, g_strdup ("ao"), g_variant_ref_sink (g_variant_new_parsed ("[@o '/some/path', @o '/another/path']"))); + g_hash_table_insert (properties, g_strdup ("foo"), g_variant_ref_sink (g_variant_new_string ("a frobbed string"))); + g_hash_table_insert (properties, g_strdup ("PropertyThatWillBeInvalidated"), g_variant_ref_sink (g_variant_new_string ("InitialValue"))); + + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "com.example.TestService", + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_bus_unown_name (owner_id); + + g_dbus_node_info_unref (introspection_data); + g_hash_table_unref (properties); + + return 0; +} diff --git a/gio/tests/gdbus-threading.c b/gio/tests/gdbus-threading.c new file mode 100644 index 0000000..23dc1fd --- /dev/null +++ b/gio/tests/gdbus-threading.c @@ -0,0 +1,686 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a global connection */ +static GDBusConnection *c = NULL; + +typedef struct +{ + GMainContext *context; + gboolean timed_out; +} TimeoutData; + +static gboolean +timeout_cb (gpointer user_data) +{ + TimeoutData *data = user_data; + + data->timed_out = TRUE; + g_main_context_wakeup (data->context); + + return G_SOURCE_REMOVE; +} + +/* Check that the given @connection has only one ref, waiting to let any pending + * unrefs complete first. This is typically used on the shared connection, to + * ensure it’s in a correct state before beginning the next test. */ +static void +(assert_connection_has_one_ref) (GDBusConnection *connection, + GMainContext *context, + const gchar *calling_function) +{ + GSource *timeout_source = NULL; + TimeoutData data = { context, FALSE }; + + if (g_atomic_int_get (&G_OBJECT (connection)->ref_count) == 1) + return; + + timeout_source = g_timeout_source_new_seconds (3); + g_source_set_callback (timeout_source, timeout_cb, &data, NULL); + g_source_attach (timeout_source, context); + + while (g_atomic_int_get (&G_OBJECT (connection)->ref_count) != 1 && !data.timed_out) + { + g_debug ("refcount of %p is not right (%u rather than 1) in %s(), sleeping", + connection, g_atomic_int_get (&G_OBJECT (connection)->ref_count), calling_function); + g_main_context_iteration (NULL, TRUE); + } + + g_source_destroy (timeout_source); + g_source_unref (timeout_source); + + if (g_atomic_int_get (&G_OBJECT (connection)->ref_count) != 1) + g_error ("connection %p had too many refs (%u rather than 1) in %s()", + connection, g_atomic_int_get (&G_OBJECT (connection)->ref_count), calling_function); +} + +/* Macro wrapper to add in the calling function name */ +#define assert_connection_has_one_ref(connection, context) \ + (assert_connection_has_one_ref) (connection, context, G_STRFUNC) + +/* ---------------------------------------------------------------------------------------------------- */ +/* Ensure that signal and method replies are delivered in the right thread */ +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + GThread *thread; + GMainContext *context; + guint signal_count; + gboolean unsubscribe_complete; + GAsyncResult *async_result; +} DeliveryData; + +static void +async_result_cb (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + DeliveryData *data = user_data; + + data->async_result = g_object_ref (res); + + g_assert_true (g_thread_self () == data->thread); + + g_main_context_wakeup (data->context); +} + +static void +signal_handler (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + DeliveryData *data = user_data; + + g_assert_true (g_thread_self () == data->thread); + + data->signal_count++; + + g_main_context_wakeup (data->context); +} + +static void +signal_data_free_cb (gpointer user_data) +{ + DeliveryData *data = user_data; + + g_assert_true (g_thread_self () == data->thread); + + data->unsubscribe_complete = TRUE; + + g_main_context_wakeup (data->context); +} + +static gpointer +test_delivery_in_thread_func (gpointer _data) +{ + GMainContext *thread_context; + DeliveryData data; + GCancellable *ca; + guint subscription_id; + GError *error = NULL; + GVariant *result_variant = NULL; + + thread_context = g_main_context_new (); + g_main_context_push_thread_default (thread_context); + + data.thread = g_thread_self (); + data.context = thread_context; + data.signal_count = 0; + data.unsubscribe_complete = FALSE; + data.async_result = NULL; + + /* ---------------------------------------------------------------------------------------------------- */ + + /* + * Check that we get a reply to the GetId() method call. + */ + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) async_result_cb, + &data); + while (data.async_result == NULL) + g_main_context_iteration (thread_context, TRUE); + + result_variant = g_dbus_connection_call_finish (c, data.async_result, &error); + g_assert_no_error (error); + g_assert_nonnull (result_variant); + g_clear_pointer (&result_variant, g_variant_unref); + g_clear_object (&data.async_result); + + /* + * Check that we never actually send a message if the GCancellable + * is already cancelled - i.e. we should get G_IO_ERROR_CANCELLED + * when the actual connection is not up. + */ + ca = g_cancellable_new (); + g_cancellable_cancel (ca); + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + ca, + (GAsyncReadyCallback) async_result_cb, + &data); + while (data.async_result == NULL) + g_main_context_iteration (thread_context, TRUE); + + result_variant = g_dbus_connection_call_finish (c, data.async_result, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_clear_error (&error); + g_assert_null (result_variant); + g_clear_object (&data.async_result); + + g_object_unref (ca); + + /* + * Check that cancellation works when the message is already in flight. + */ + ca = g_cancellable_new (); + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + ca, + (GAsyncReadyCallback) async_result_cb, + &data); + g_cancellable_cancel (ca); + + while (data.async_result == NULL) + g_main_context_iteration (thread_context, TRUE); + + result_variant = g_dbus_connection_call_finish (c, data.async_result, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_clear_error (&error); + g_assert_null (result_variant); + g_clear_object (&data.async_result); + + g_object_unref (ca); + + /* + * Check that signals are delivered to the correct thread. + * + * First we subscribe to the signal, then we call EmitSignal(). This should + * cause a TestSignal emission from the testserver. + */ + subscription_id = g_dbus_connection_signal_subscribe (c, + "com.example.TestService", /* sender */ + "com.example.Frob", /* interface */ + "TestSignal", /* member */ + "/com/example/TestObject", /* path */ + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + signal_handler, + &data, + signal_data_free_cb); + g_assert_cmpuint (subscription_id, !=, 0); + g_assert_cmpuint (data.signal_count, ==, 0); + + g_dbus_connection_call (c, + "com.example.TestService", /* bus_name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface name */ + "EmitSignal", /* method name */ + g_variant_new_parsed ("('hello', @o '/com/example/TestObject')"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) async_result_cb, + &data); + while (data.async_result == NULL || data.signal_count < 1) + g_main_context_iteration (thread_context, TRUE); + + result_variant = g_dbus_connection_call_finish (c, data.async_result, &error); + g_assert_no_error (error); + g_assert_nonnull (result_variant); + g_clear_pointer (&result_variant, g_variant_unref); + g_clear_object (&data.async_result); + + g_assert_cmpuint (data.signal_count, ==, 1); + + g_dbus_connection_signal_unsubscribe (c, subscription_id); + subscription_id = 0; + + while (!data.unsubscribe_complete) + g_main_context_iteration (thread_context, TRUE); + g_assert_true (data.unsubscribe_complete); + + /* ---------------------------------------------------------------------------------------------------- */ + + g_main_context_pop_thread_default (thread_context); + g_main_context_unref (thread_context); + + return NULL; +} + +static void +test_delivery_in_thread (void) +{ + GThread *thread; + + thread = g_thread_new ("deliver", + test_delivery_in_thread_func, + NULL); + + g_thread_join (thread); + + assert_connection_has_one_ref (c, NULL); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + GDBusProxy *proxy; + gint msec; + guint num; + gboolean async; + + GMainLoop *thread_loop; + GThread *thread; +} SyncThreadData; + +static void +sleep_cb (GDBusProxy *proxy, + GAsyncResult *res, + gpointer user_data) +{ + SyncThreadData *data = user_data; + GError *error; + GVariant *result; + + error = NULL; + result = g_dbus_proxy_call_finish (proxy, + res, + &error); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + + g_assert_true (data->thread == g_thread_self ()); + + g_main_loop_quit (data->thread_loop); + + //g_debug ("async cb (%p)", g_thread_self ()); +} + +static gpointer +test_sleep_in_thread_func (gpointer _data) +{ + SyncThreadData *data = _data; + GMainContext *thread_context; + guint n; + + thread_context = g_main_context_new (); + data->thread_loop = g_main_loop_new (thread_context, FALSE); + g_main_context_push_thread_default (thread_context); + + data->thread = g_thread_self (); + + for (n = 0; n < data->num; n++) + { + if (data->async) + { + //g_debug ("invoking async (%p)", g_thread_self ()); + g_dbus_proxy_call (data->proxy, + "Sleep", + g_variant_new ("(i)", data->msec), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) sleep_cb, + data); + g_main_loop_run (data->thread_loop); + if (g_test_verbose ()) + g_printerr ("A"); + //g_debug ("done invoking async (%p)", g_thread_self ()); + } + else + { + GError *error; + GVariant *result; + + error = NULL; + //g_debug ("invoking sync (%p)", g_thread_self ()); + result = g_dbus_proxy_call_sync (data->proxy, + "Sleep", + g_variant_new ("(i)", data->msec), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (g_test_verbose ()) + g_printerr ("S"); + //g_debug ("done invoking sync (%p)", g_thread_self ()); + g_assert_no_error (error); + g_assert_nonnull (result); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + } + } + + g_main_context_pop_thread_default (thread_context); + g_main_loop_unref (data->thread_loop); + g_main_context_unref (thread_context); + + return NULL; +} + +static void +test_method_calls_on_proxy (GDBusProxy *proxy) +{ + guint n, divisor; + + /* + * Check that multiple threads can do calls without interfering with + * each other. We do this by creating three threads that call the + * Sleep() method on the server (which handles it asynchronously, e.g. + * it won't block other requests) with different sleep durations and + * a number of times. We do this so each set of calls add up to 4000 + * milliseconds. + * + * The dbus test server that this code calls into uses glib timeouts + * to do the sleeping which have only a granularity of 1ms. It is + * therefore possible to lose as much as 40ms; the test could finish + * in slightly less than 4 seconds. + * + * We run this test twice - first with async calls in each thread, then + * again with sync calls + */ + + if (g_test_thorough ()) + divisor = 1; + else + divisor = 10; + + for (n = 0; n < 2; n++) + { + gboolean do_async; + GThread *thread1; + GThread *thread2; + GThread *thread3; + SyncThreadData data1; + SyncThreadData data2; + SyncThreadData data3; + gint64 start_time, end_time; + guint elapsed_msec; + + do_async = (n == 0); + + start_time = g_get_real_time (); + + data1.proxy = proxy; + data1.msec = 40; + data1.num = 100 / divisor; + data1.async = do_async; + thread1 = g_thread_new ("sleep", + test_sleep_in_thread_func, + &data1); + + data2.proxy = proxy; + data2.msec = 20; + data2.num = 200 / divisor; + data2.async = do_async; + thread2 = g_thread_new ("sleep2", + test_sleep_in_thread_func, + &data2); + + data3.proxy = proxy; + data3.msec = 100; + data3.num = 40 / divisor; + data3.async = do_async; + thread3 = g_thread_new ("sleep3", + test_sleep_in_thread_func, + &data3); + + g_thread_join (thread1); + g_thread_join (thread2); + g_thread_join (thread3); + + end_time = g_get_real_time (); + + elapsed_msec = (end_time - start_time) / 1000; + + //g_debug ("Elapsed time for %s = %d msec", n == 0 ? "async" : "sync", elapsed_msec); + + /* elapsed_msec should be 4000 msec +/- change for overhead/inaccuracy */ + g_assert_cmpint (elapsed_msec, >=, 3950 / divisor); + g_assert_cmpint (elapsed_msec, <, 30000 / divisor); + + if (g_test_verbose ()) + g_printerr (" "); + } +} + +static void +test_method_calls_in_thread (void) +{ + GDBusProxy *proxy; + GDBusConnection *connection; + GError *error; + + error = NULL; + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, + NULL, + &error); + g_assert_no_error (error); + error = NULL; + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + test_method_calls_on_proxy (proxy); + + g_object_unref (proxy); + g_object_unref (connection); + + if (g_test_verbose ()) + g_printerr ("\n"); + + assert_connection_has_one_ref (c, NULL); +} + +#define SLEEP_MIN_USEC 1 +#define SLEEP_MAX_USEC 10 + +/* Can run in any thread */ +static void +ensure_connection_works (GDBusConnection *conn) +{ + GVariant *v; + GError *error = NULL; + + v = g_dbus_connection_call_sync (conn, "org.freedesktop.DBus", + "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetId", NULL, NULL, 0, -1, + NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (v); + g_assert_true (g_variant_is_of_type (v, G_VARIANT_TYPE ("(s)"))); + g_variant_unref (v); +} + +/** + * get_sync_in_thread: + * @data: (type guint): delay in microseconds + * + * Sleep for a short time, then get a session bus connection and call + * a method on it. + * + * Runs in a non-main thread. + * + * Returns: (transfer full): the connection + */ +static gpointer +get_sync_in_thread (gpointer data) +{ + guint delay = GPOINTER_TO_UINT (data); + GError *error = NULL; + GDBusConnection *conn; + + g_usleep (delay); + + conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + + ensure_connection_works (conn); + + return conn; +} + +static void +test_threaded_singleton (void) +{ + guint i, n; + guint unref_wins = 0; + guint get_wins = 0; + + if (g_test_thorough ()) + n = 100000; + else + n = 1000; + + for (i = 0; i < n; i++) + { + GThread *thread; + guint unref_delay, get_delay; + GDBusConnection *new_conn; + + /* We want to be the last ref, so let it finish setting up */ + assert_connection_has_one_ref (c, NULL); + + if (g_test_verbose () && (i % (n/50)) == 0) + g_printerr ("%u%%\n", ((i * 100) / n)); + + /* Delay for a random time on each side of the race, to perturb the + * timing. Ideally, we want each side to win half the races; these + * timings are about right on smcv's laptop. + */ + unref_delay = g_random_int_range (SLEEP_MIN_USEC, SLEEP_MAX_USEC); + get_delay = g_random_int_range (SLEEP_MIN_USEC / 2, SLEEP_MAX_USEC / 2); + + /* One half of the race is to call g_bus_get_sync... */ + thread = g_thread_new ("get_sync_in_thread", get_sync_in_thread, + GUINT_TO_POINTER (get_delay)); + + /* ... and the other half is to unref the shared connection, which must + * have exactly one ref at this point + */ + g_usleep (unref_delay); + g_object_unref (c); + + /* Wait for the thread to run; see what it got */ + new_conn = g_thread_join (thread); + + /* If the thread won the race, it will have kept the same connection, + * and it'll have one ref + */ + if (new_conn == c) + { + get_wins++; + } + else + { + unref_wins++; + /* c is invalid now, but new_conn is suitable for the + * next round + */ + c = new_conn; + } + + ensure_connection_works (c); + } + + if (g_test_verbose ()) + g_printerr ("Unref won %u races; Get won %u races\n", unref_wins, get_wins); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + GError *error; + gint ret; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + session_bus_up (); + + /* this is safe; testserver will exit once the bus goes away */ + path = g_test_build_filename (G_TEST_BUILT, "gdbus-testserver", NULL); + g_assert_true (g_spawn_command_line_async (path, NULL)); + g_free (path); + + /* Create the connection in the main thread */ + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (c); + + ensure_gdbus_testserver_up (c, NULL); + + g_test_add_func ("/gdbus/delivery-in-thread", test_delivery_in_thread); + g_test_add_func ("/gdbus/method-calls-in-thread", test_method_calls_in_thread); + g_test_add_func ("/gdbus/threaded-singleton", test_threaded_singleton); + + ret = g_test_run(); + + g_object_unref (c); + + /* tear down bus */ + session_bus_down (); + + return ret; +} diff --git a/gio/tests/gen-big-test-resource.py b/gio/tests/gen-big-test-resource.py new file mode 100644 index 0000000..b2e478d --- /dev/null +++ b/gio/tests/gen-big-test-resource.py @@ -0,0 +1,26 @@ +# Generate a large text file to test compile +# the resulting code that contains a large (>65536 bytes) +# resource entry. Just have 12 iterations of the following: +# +# -100 of each of the lowercase letters +# -100 of each of the uppercase letters +# -100 of the numbers 0 to 9 +# +# See issue #1580 + +import string +import sys + +if len(sys.argv) != 2: + raise SystemExit("Usage: %s " % sys.argv[0]) + +with open(sys.argv[1], "w", newline="\n") as f: + for count in range(12): + for c in string.ascii_lowercase: + f.write("%s\n" % (c * 100)) + + for c in string.ascii_uppercase: + f.write("%s\n" % (c * 100)) + + for i in range(10): + f.write("%s\n" % (str(i) * 100)) diff --git a/gio/tests/gengiotypefuncs.py b/gio/tests/gengiotypefuncs.py new file mode 100644 index 0000000..dbd8195 --- /dev/null +++ b/gio/tests/gengiotypefuncs.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys +import re +import os + +debug = os.getenv("GIO_GENTYPEFUNCS_DEBUG") is not None + +out_file = sys.argv[1] +in_files = sys.argv[2:] + +funcs = [] + + +if debug: + print("Output file: ", out_file) + +if debug: + print(len(in_files), "input files") + +for filename in in_files: + if debug: + print("Input file: ", filename) + with open(filename, "rb") as f: + for line in f: + line = line.rstrip(b"\n").rstrip(b"\r") + # print line + match = re.search(b"\bg_[a-zA-Z0-9_]*_get_type\b", line) + if match: + func = match.group(0) + if func not in funcs: + funcs.append(func) + if debug: + print("Found ", func) + +file_output = "G_GNUC_BEGIN_IGNORE_DEPRECATIONS\n" + +funcs = sorted(funcs) + +for f in funcs: + if f not in ["g_io_extension_get_type", "g_settings_backend_get_type"]: + file_output += "*tp++ = {0} ();\n".format(f) + +if debug: + print(len(funcs), "functions") + +ofile = open(out_file, "w") +ofile.write(file_output) +ofile.close() diff --git a/gio/tests/gio-du.c b/gio/tests/gio-du.c new file mode 100644 index 0000000..253a21f --- /dev/null +++ b/gio/tests/gio-du.c @@ -0,0 +1,163 @@ +#include +#include + +static gboolean option_use_async; +static gint option_format_size; + +static gint outstanding_asyncs; + +static void +print_result (const gchar *filename, + guint64 disk_usage, + guint64 num_dirs, + guint64 num_files, + GError *error, + gchar nl) +{ + if (!error) + { + if (option_format_size) + { + GFormatSizeFlags format_flags; + gchar *str; + + format_flags = (option_format_size > 1) ? G_FORMAT_SIZE_LONG_FORMAT : G_FORMAT_SIZE_DEFAULT; + str = g_format_size_full (disk_usage, format_flags); + g_print ("%s: %s (%"G_GUINT64_FORMAT" dirs, %"G_GUINT64_FORMAT" files)%c", + filename, str, num_dirs, num_files, nl); + g_free (str); + } + else + g_print ("%s: %"G_GUINT64_FORMAT" (%"G_GUINT64_FORMAT" dirs, %"G_GUINT64_FORMAT" files)%c", + filename, disk_usage, num_dirs, num_files, nl); + } + else + { + g_printerr ("%s: %s\n", filename, error->message); + g_error_free (error); + } +} + +static void +async_ready_func (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + gchar *filename = user_data; + GError *error = NULL; + guint64 disk_usage; + guint64 num_dirs; + guint64 num_files; + + g_file_measure_disk_usage_finish (G_FILE (source), result, &disk_usage, &num_dirs, &num_files, &error); + print_result (filename, disk_usage, num_dirs, num_files, error, '\n'); + outstanding_asyncs--; + g_free (filename); +} + +static void +report_progress (gboolean reporting, + guint64 disk_usage, + guint64 num_dirs, + guint64 num_files, + gpointer user_data) +{ + const gchar *filename = user_data; + + if (!reporting) + g_printerr ("%s: warning: does not support progress reporting\n", filename); + + print_result (filename, disk_usage, num_dirs, num_files, NULL, '\r'); +} + +int +main (int argc, char **argv) +{ + GFileMeasureProgressCallback progress = NULL; + GFileMeasureFlags flags = 0; + gint i; + +#ifdef G_OS_WIN32 + argv = g_win32_get_command_line (); +#endif + + setlocale (LC_ALL, ""); + + + + for (i = 1; argv[i] && argv[i][0] == '-'; i++) + { + if (g_str_equal (argv[i], "--")) + break; + + if (g_str_equal (argv[i], "--help")) + { + g_print ("usage: du [--progress] [--async] [-x] [-h] [-h] [--apparent-size] [--any-error] [--] files...\n"); +#ifdef G_OS_WIN32 + g_strfreev (argv); +#endif + return 0; + } + else if (g_str_equal (argv[i], "-x")) + flags |= G_FILE_MEASURE_NO_XDEV; + else if (g_str_equal (argv[i], "-h")) + option_format_size++; + else if (g_str_equal (argv[i], "--apparent-size")) + flags |= G_FILE_MEASURE_APPARENT_SIZE; + else if (g_str_equal (argv[i], "--any-error")) + flags |= G_FILE_MEASURE_REPORT_ANY_ERROR; + else if (g_str_equal (argv[i], "--async")) + option_use_async = TRUE; + else if (g_str_equal (argv[i], "--progress")) + progress = report_progress; + else + { + g_printerr ("unrecognised flag %s\n", argv[i]); + } + } + + if (!argv[i]) + { + g_printerr ("usage: du [--progress] [--async] [-x] [-h] [-h] [--apparent-size] [--any-error] [--] files...\n"); +#ifdef G_OS_WIN32 + g_strfreev (argv); +#endif + return 1; + } + + while (argv[i]) + { + GFile *file = g_file_new_for_commandline_arg (argv[i]); + + if (option_use_async) + { + g_file_measure_disk_usage_async (file, flags, G_PRIORITY_DEFAULT, NULL, + progress, argv[i], async_ready_func, argv[i]); + outstanding_asyncs++; + } + else + { + GError *error = NULL; + guint64 disk_usage; + guint64 num_dirs; + guint64 num_files; + + g_file_measure_disk_usage (file, flags, NULL, progress, argv[i], + &disk_usage, &num_dirs, &num_files, &error); + print_result (argv[i], disk_usage, num_dirs, num_files, error, '\n'); + } + + g_object_unref (file); + + i++; + } + + while (outstanding_asyncs) + g_main_context_iteration (NULL, TRUE); + +#ifdef G_OS_WIN32 + g_strfreev (argv); +#endif + + return 0; +} diff --git a/gio/tests/giomodule.c b/gio/tests/giomodule.c new file mode 100644 index 0000000..b4923ee --- /dev/null +++ b/gio/tests/giomodule.c @@ -0,0 +1,153 @@ +/* Unit tests for GIOModule + * Copyright (C) 2013 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include + +#ifdef _MSC_VER +# define MODULE_FILENAME_PREFIX "" +#else +# define MODULE_FILENAME_PREFIX "lib" +#endif + +static void +test_extension_point (void) +{ + GIOExtensionPoint *ep, *ep2; + GIOExtension *ext; + GList *list; + GType req; + GTypeClass *class; + + ep = g_io_extension_point_lookup ("test-extension-point"); + g_assert_null (ep); + ep = g_io_extension_point_register ("test-extension-point"); + ep2 = g_io_extension_point_lookup ("test-extension-point"); + g_assert (ep2 == ep); + + req = g_io_extension_point_get_required_type (ep); + g_assert (req == G_TYPE_INVALID); + g_io_extension_point_set_required_type (ep, G_TYPE_OBJECT); + req = g_io_extension_point_get_required_type (ep); + g_assert (req == G_TYPE_OBJECT); + + list = g_io_extension_point_get_extensions (ep); + g_assert_null (list); + + g_io_extension_point_implement ("test-extension-point", + G_TYPE_VFS, + "extension1", + 10); + + g_io_extension_point_implement ("test-extension-point", + G_TYPE_OBJECT, + "extension2", + 20); + + list = g_io_extension_point_get_extensions (ep); + g_assert_cmpint (g_list_length (list), ==, 2); + + ext = list->data; + g_assert_cmpstr (g_io_extension_get_name (ext), ==, "extension2"); + g_assert (g_io_extension_get_type (ext) == G_TYPE_OBJECT); + g_assert (g_io_extension_get_priority (ext) == 20); + class = g_io_extension_ref_class (ext); + g_assert (class == g_type_class_peek (G_TYPE_OBJECT)); + g_type_class_unref (class); + + ext = list->next->data; + g_assert_cmpstr (g_io_extension_get_name (ext), ==, "extension1"); + g_assert (g_io_extension_get_type (ext) == G_TYPE_VFS); + g_assert (g_io_extension_get_priority (ext) == 10); +} + +static void +test_module_scan_all (void) +{ +#ifdef GLIB_STATIC_COMPILATION + /* The plugin module is statically linked with a separate copy + * of GLib so g_io_extension_point_implement won't work. */ + g_test_skip ("GIOExtensionPoint with dynamic modules isn't supported in static builds."); + return; +#endif + + if (g_test_subprocess ()) + { + GIOExtensionPoint *ep; + GIOExtension *ext; + GList *list; + ep = g_io_extension_point_register ("test-extension-point"); + g_io_modules_scan_all_in_directory (g_test_get_filename (G_TEST_BUILT, "modules", NULL)); + list = g_io_extension_point_get_extensions (ep); + g_assert_cmpint (g_list_length (list), ==, 2); + ext = list->data; + g_assert_cmpstr (g_io_extension_get_name (ext), ==, "test-b"); + ext = list->next->data; + g_assert_cmpstr (g_io_extension_get_name (ext), ==, "test-a"); + return; + } + g_test_trap_subprocess (NULL, 0, 7); + g_test_trap_assert_passed (); +} + +static void +test_module_scan_all_with_scope (void) +{ +#ifdef GLIB_STATIC_COMPILATION + /* Disabled for the same reason as test_module_scan_all. */ + g_test_skip ("GIOExtensionPoint with dynamic modules isn't supported in static builds."); + return; +#endif + + if (g_test_subprocess ()) + { + GIOExtensionPoint *ep; + GIOModuleScope *scope; + GIOExtension *ext; + GList *list; + + ep = g_io_extension_point_register ("test-extension-point"); + scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES); + g_io_module_scope_block (scope, MODULE_FILENAME_PREFIX "testmoduleb." G_MODULE_SUFFIX); + g_io_modules_scan_all_in_directory_with_scope (g_test_get_filename (G_TEST_BUILT, "modules", NULL), scope); + list = g_io_extension_point_get_extensions (ep); + g_assert_cmpint (g_list_length (list), ==, 1); + ext = list->data; + g_assert_cmpstr (g_io_extension_get_name (ext), ==, "test-a"); + g_io_module_scope_free (scope); + return; + } + g_test_trap_subprocess (NULL, 0, 7); + g_test_trap_assert_passed (); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/giomodule/extension-point", test_extension_point); + g_test_add_func ("/giomodule/module-scan-all", test_module_scan_all); + g_test_add_func ("/giomodule/module-scan-all-with-scope", test_module_scan_all_with_scope); + + return g_test_run (); +} diff --git a/gio/tests/glistmodel.c b/gio/tests/glistmodel.c new file mode 100644 index 0000000..e50969e --- /dev/null +++ b/gio/tests/glistmodel.c @@ -0,0 +1,908 @@ +/* + * Copyright 2015 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#include + +#include + +/* Wrapper around g_list_model_get_item() and g_list_model_get_object() which + * checks they return the same thing. */ +static gpointer +list_model_get (GListModel *model, + guint position) +{ + GObject *item = g_list_model_get_item (model, position); + GObject *object = g_list_model_get_object (model, position); + + g_assert_true (item == object); + + g_clear_object (&object); + return g_steal_pointer (&item); +} + +/* Test that constructing/getting/setting properties on a #GListStore works. */ +static void +test_store_properties (void) +{ + GListStore *store = NULL; + GType item_type; + + store = g_list_store_new (G_TYPE_MENU_ITEM); + g_object_get (store, "item-type", &item_type, NULL); + g_assert_cmpint (item_type, ==, G_TYPE_MENU_ITEM); + + g_clear_object (&store); +} + +/* Test that #GListStore rejects non-GObject item types. */ +static void +test_store_non_gobjects (void) +{ + if (g_test_subprocess ()) + { + /* We have to use g_object_new() since g_list_store_new() checks the item + * type. We want to check the property setter code works properly. */ + g_object_new (G_TYPE_LIST_STORE, "item-type", G_TYPE_LONG, NULL); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*WARNING*value * of type 'GType' is invalid or " + "out of range for property 'item-type'*"); +} + +static void +test_store_boundaries (void) +{ + GListStore *store; + GMenuItem *item; + + store = g_list_store_new (G_TYPE_MENU_ITEM); + + item = g_menu_item_new (NULL, NULL); + + /* remove an item from an empty list */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*g_sequence*"); + g_list_store_remove (store, 0); + g_test_assert_expected_messages (); + + /* don't allow inserting an item past the end ... */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*g_sequence*"); + g_list_store_insert (store, 1, item); + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 0); + g_test_assert_expected_messages (); + + /* ... except exactly at the end */ + g_list_store_insert (store, 0, item); + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 1); + + /* remove a non-existing item at exactly the end of the list */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*g_sequence*"); + g_list_store_remove (store, 1); + g_test_assert_expected_messages (); + + g_list_store_remove (store, 0); + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 0); + + /* splice beyond the end of the list */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*position*"); + g_list_store_splice (store, 1, 0, NULL, 0); + g_test_assert_expected_messages (); + + /* remove items from an empty list */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*position*"); + g_list_store_splice (store, 0, 1, NULL, 0); + g_test_assert_expected_messages (); + + g_list_store_append (store, item); + g_list_store_splice (store, 0, 1, (gpointer *) &item, 1); + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 1); + + /* remove more items than exist */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*position*"); + g_list_store_splice (store, 0, 5, NULL, 0); + g_test_assert_expected_messages (); + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 1); + + g_object_unref (store); + g_assert_finalize_object (item); +} + +static void +test_store_refcounts (void) +{ + GListStore *store; + GMenuItem *items[10]; + GMenuItem *tmp; + guint i; + guint n_items; + + store = g_list_store_new (G_TYPE_MENU_ITEM); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 0); + g_assert_null (list_model_get (G_LIST_MODEL (store), 0)); + + n_items = G_N_ELEMENTS (items); + for (i = 0; i < n_items; i++) + { + items[i] = g_menu_item_new (NULL, NULL); + g_object_add_weak_pointer (G_OBJECT (items[i]), (gpointer *) &items[i]); + g_list_store_append (store, items[i]); + + g_object_unref (items[i]); + g_assert_nonnull (items[i]); + } + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, n_items); + g_assert_null (list_model_get (G_LIST_MODEL (store), n_items)); + + tmp = list_model_get (G_LIST_MODEL (store), 3); + g_assert_true (tmp == items[3]); + g_object_unref (tmp); + + g_list_store_remove (store, 4); + g_assert_null (items[4]); + n_items--; + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, n_items); + g_assert_null (list_model_get (G_LIST_MODEL (store), n_items)); + + g_object_unref (store); + for (i = 0; i < G_N_ELEMENTS (items); i++) + g_assert_null (items[i]); +} + +static gchar * +make_random_string (void) +{ + gchar *str = g_malloc (10); + gint i; + + for (i = 0; i < 9; i++) + str[i] = g_test_rand_int_range ('a', 'z'); + str[i] = '\0'; + + return str; +} + +static gint +compare_items (gconstpointer a_p, + gconstpointer b_p, + gpointer user_data) +{ + GObject *a_o = (GObject *) a_p; + GObject *b_o = (GObject *) b_p; + + gchar *a = g_object_get_data (a_o, "key"); + gchar *b = g_object_get_data (b_o, "key"); + + g_assert (user_data == GUINT_TO_POINTER(0x1234u)); + + return strcmp (a, b); +} + +static void +insert_string (GListStore *store, + const gchar *str) +{ + GObject *obj; + + obj = g_object_new (G_TYPE_OBJECT, NULL); + g_object_set_data_full (obj, "key", g_strdup (str), g_free); + + g_list_store_insert_sorted (store, obj, compare_items, GUINT_TO_POINTER(0x1234u)); + + g_object_unref (obj); +} + +static void +test_store_sorted (void) +{ + GListStore *store; + guint i; + + store = g_list_store_new (G_TYPE_OBJECT); + + for (i = 0; i < 1000; i++) + { + gchar *str = make_random_string (); + insert_string (store, str); + insert_string (store, str); /* multiple copies of the same are OK */ + g_free (str); + } + + g_assert_cmpint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 2000); + + for (i = 0; i < 1000; i++) + { + GObject *a, *b; + + /* should see our two copies */ + a = list_model_get (G_LIST_MODEL (store), i * 2); + b = list_model_get (G_LIST_MODEL (store), i * 2 + 1); + + g_assert (compare_items (a, b, GUINT_TO_POINTER(0x1234)) == 0); + g_assert (a != b); + + if (i) + { + GObject *c; + + c = list_model_get (G_LIST_MODEL (store), i * 2 - 1); + g_assert (c != a); + g_assert (c != b); + + g_assert (compare_items (b, c, GUINT_TO_POINTER(0x1234)) > 0); + g_assert (compare_items (a, c, GUINT_TO_POINTER(0x1234)) > 0); + + g_object_unref (c); + } + + g_object_unref (a); + g_object_unref (b); + } + + g_object_unref (store); +} + +/* Test that using splice() to replace the middle element in a list store works. */ +static void +test_store_splice_replace_middle (void) +{ + GListStore *store; + GListModel *model; + GAction *item; + GPtrArray *array; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=795307"); + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + array = g_ptr_array_new_full (0, g_object_unref); + g_ptr_array_add (array, g_simple_action_new ("1", NULL)); + g_ptr_array_add (array, g_simple_action_new ("2", NULL)); + g_ptr_array_add (array, g_simple_action_new ("3", NULL)); + g_ptr_array_add (array, g_simple_action_new ("4", NULL)); + g_ptr_array_add (array, g_simple_action_new ("5", NULL)); + + /* Add three items through splice */ + g_list_store_splice (store, 0, 0, array->pdata, 3); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 3); + + item = list_model_get (model, 0); + g_assert_cmpstr (g_action_get_name (item), ==, "1"); + g_object_unref (item); + item = list_model_get (model, 1); + g_assert_cmpstr (g_action_get_name (item), ==, "2"); + g_object_unref (item); + item = list_model_get (model, 2); + g_assert_cmpstr (g_action_get_name (item), ==, "3"); + g_object_unref (item); + + /* Replace the middle one with two new items */ + g_list_store_splice (store, 1, 1, array->pdata + 3, 2); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 4); + + item = list_model_get (model, 0); + g_assert_cmpstr (g_action_get_name (item), ==, "1"); + g_object_unref (item); + item = list_model_get (model, 1); + g_assert_cmpstr (g_action_get_name (item), ==, "4"); + g_object_unref (item); + item = list_model_get (model, 2); + g_assert_cmpstr (g_action_get_name (item), ==, "5"); + g_object_unref (item); + item = list_model_get (model, 3); + g_assert_cmpstr (g_action_get_name (item), ==, "3"); + g_object_unref (item); + + g_ptr_array_unref (array); + g_object_unref (store); +} + +/* Test that using splice() to replace the whole list store works. */ +static void +test_store_splice_replace_all (void) +{ + GListStore *store; + GListModel *model; + GPtrArray *array; + GAction *item; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=795307"); + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + array = g_ptr_array_new_full (0, g_object_unref); + g_ptr_array_add (array, g_simple_action_new ("1", NULL)); + g_ptr_array_add (array, g_simple_action_new ("2", NULL)); + g_ptr_array_add (array, g_simple_action_new ("3", NULL)); + g_ptr_array_add (array, g_simple_action_new ("4", NULL)); + + /* Add the first two */ + g_list_store_splice (store, 0, 0, array->pdata, 2); + + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2); + item = list_model_get (model, 0); + g_assert_cmpstr (g_action_get_name (item), ==, "1"); + g_object_unref (item); + item = list_model_get (model, 1); + g_assert_cmpstr (g_action_get_name (item), ==, "2"); + g_object_unref (item); + + /* Replace all with the last two */ + g_list_store_splice (store, 0, 2, array->pdata + 2, 2); + + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2); + item = list_model_get (model, 0); + g_assert_cmpstr (g_action_get_name (item), ==, "3"); + g_object_unref (item); + item = list_model_get (model, 1); + g_assert_cmpstr (g_action_get_name (item), ==, "4"); + g_object_unref (item); + + g_ptr_array_unref (array); + g_object_unref (store); +} + +/* Test that using splice() without removing or adding anything works */ +static void +test_store_splice_noop (void) +{ + GListStore *store; + GListModel *model; + GAction *item; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + /* splice noop with an empty list */ + g_list_store_splice (store, 0, 0, NULL, 0); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0); + + /* splice noop with a non-empty list */ + item = G_ACTION (g_simple_action_new ("1", NULL)); + g_list_store_append (store, item); + g_object_unref (item); + + g_list_store_splice (store, 0, 0, NULL, 0); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1); + + g_list_store_splice (store, 1, 0, NULL, 0); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1); + + item = list_model_get (model, 0); + g_assert_cmpstr (g_action_get_name (item), ==, "1"); + g_object_unref (item); + + g_object_unref (store); +} + +static gboolean +model_array_equal (GListModel *model, GPtrArray *array) +{ + guint i; + + if (g_list_model_get_n_items (model) != array->len) + return FALSE; + + for (i = 0; i < array->len; i++) + { + GObject *ptr; + gboolean ptrs_equal; + + ptr = list_model_get (model, i); + ptrs_equal = (g_ptr_array_index (array, i) == ptr); + g_object_unref (ptr); + if (!ptrs_equal) + return FALSE; + } + + return TRUE; +} + +/* Test that using splice() to remove multiple items at different + * positions works */ +static void +test_store_splice_remove_multiple (void) +{ + GListStore *store; + GListModel *model; + GPtrArray *array; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + array = g_ptr_array_new_full (0, g_object_unref); + g_ptr_array_add (array, g_simple_action_new ("1", NULL)); + g_ptr_array_add (array, g_simple_action_new ("2", NULL)); + g_ptr_array_add (array, g_simple_action_new ("3", NULL)); + g_ptr_array_add (array, g_simple_action_new ("4", NULL)); + g_ptr_array_add (array, g_simple_action_new ("5", NULL)); + g_ptr_array_add (array, g_simple_action_new ("6", NULL)); + g_ptr_array_add (array, g_simple_action_new ("7", NULL)); + g_ptr_array_add (array, g_simple_action_new ("8", NULL)); + g_ptr_array_add (array, g_simple_action_new ("9", NULL)); + g_ptr_array_add (array, g_simple_action_new ("10", NULL)); + + /* Add all */ + g_list_store_splice (store, 0, 0, array->pdata, array->len); + g_assert_true (model_array_equal (model, array)); + + /* Remove the first two */ + g_list_store_splice (store, 0, 2, NULL, 0); + g_assert_false (model_array_equal (model, array)); + g_ptr_array_remove_range (array, 0, 2); + g_assert_true (model_array_equal (model, array)); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 8); + + /* Remove two in the middle */ + g_list_store_splice (store, 2, 2, NULL, 0); + g_assert_false (model_array_equal (model, array)); + g_ptr_array_remove_range (array, 2, 2); + g_assert_true (model_array_equal (model, array)); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 6); + + /* Remove two at the end */ + g_list_store_splice (store, 4, 2, NULL, 0); + g_assert_false (model_array_equal (model, array)); + g_ptr_array_remove_range (array, 4, 2); + g_assert_true (model_array_equal (model, array)); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 4); + + g_ptr_array_unref (array); + g_object_unref (store); +} + +/* Test that using splice() to add multiple items at different + * positions works */ +static void +test_store_splice_add_multiple (void) +{ + GListStore *store; + GListModel *model; + GPtrArray *array; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + array = g_ptr_array_new_full (0, g_object_unref); + g_ptr_array_add (array, g_simple_action_new ("1", NULL)); + g_ptr_array_add (array, g_simple_action_new ("2", NULL)); + g_ptr_array_add (array, g_simple_action_new ("3", NULL)); + g_ptr_array_add (array, g_simple_action_new ("4", NULL)); + g_ptr_array_add (array, g_simple_action_new ("5", NULL)); + g_ptr_array_add (array, g_simple_action_new ("6", NULL)); + + /* Add two at the beginning */ + g_list_store_splice (store, 0, 0, array->pdata, 2); + + /* Add two at the end */ + g_list_store_splice (store, 2, 0, array->pdata + 4, 2); + + /* Add two in the middle */ + g_list_store_splice (store, 2, 0, array->pdata + 2, 2); + + g_assert_true (model_array_equal (model, array)); + + g_ptr_array_unref (array); + g_object_unref (store); +} + +/* Test that get_item_type() returns the right type */ +static void +test_store_item_type (void) +{ + GListStore *store; + GType gtype; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + gtype = g_list_model_get_item_type (G_LIST_MODEL (store)); + g_assert (gtype == G_TYPE_SIMPLE_ACTION); + + g_object_unref (store); +} + +/* Test that remove_all() removes all items */ +static void +test_store_remove_all (void) +{ + GListStore *store; + GListModel *model; + GSimpleAction *item; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + /* Test with an empty list */ + g_list_store_remove_all (store); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0); + + /* Test with a non-empty list */ + item = g_simple_action_new ("42", NULL); + g_list_store_append (store, item); + g_list_store_append (store, item); + g_object_unref (item); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2); + g_list_store_remove_all (store); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0); + + g_object_unref (store); +} + +/* Test that splice() logs an error when passed the wrong item type */ +static void +test_store_splice_wrong_type (void) +{ + GListStore *store; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + + g_test_expect_message (G_LOG_DOMAIN, + G_LOG_LEVEL_CRITICAL, + "*GListStore instead of a GSimpleAction*"); + g_list_store_splice (store, 0, 0, (gpointer)&store, 1); + + g_object_unref (store); +} + +static gint +ptr_array_cmp_action_by_name (GAction **a, GAction **b) +{ + return g_strcmp0 (g_action_get_name (*a), g_action_get_name (*b)); +} + +static gint +list_model_cmp_action_by_name (GAction *a, GAction *b, gpointer user_data) +{ + return g_strcmp0 (g_action_get_name (a), g_action_get_name (b)); +} + +/* Test if sort() works */ +static void +test_store_sort (void) +{ + GListStore *store; + GListModel *model; + GPtrArray *array; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + array = g_ptr_array_new_full (0, g_object_unref); + g_ptr_array_add (array, g_simple_action_new ("2", NULL)); + g_ptr_array_add (array, g_simple_action_new ("3", NULL)); + g_ptr_array_add (array, g_simple_action_new ("9", NULL)); + g_ptr_array_add (array, g_simple_action_new ("4", NULL)); + g_ptr_array_add (array, g_simple_action_new ("5", NULL)); + g_ptr_array_add (array, g_simple_action_new ("8", NULL)); + g_ptr_array_add (array, g_simple_action_new ("6", NULL)); + g_ptr_array_add (array, g_simple_action_new ("7", NULL)); + g_ptr_array_add (array, g_simple_action_new ("1", NULL)); + + /* Sort an empty list */ + g_list_store_sort (store, (GCompareDataFunc)list_model_cmp_action_by_name, NULL); + + /* Add all */ + g_list_store_splice (store, 0, 0, array->pdata, array->len); + g_assert_true (model_array_equal (model, array)); + + /* Sort both and check if the result is the same */ + g_ptr_array_sort (array, (GCompareFunc)ptr_array_cmp_action_by_name); + g_assert_false (model_array_equal (model, array)); + g_list_store_sort (store, (GCompareDataFunc)list_model_cmp_action_by_name, NULL); + g_assert_true (model_array_equal (model, array)); + + g_ptr_array_unref (array); + g_object_unref (store); +} + +/* Test the cases where the item store tries to speed up item access by caching + * the last iter/position */ +static void +test_store_get_item_cache (void) +{ + GListStore *store; + GListModel *model; + GSimpleAction *item1, *item2, *temp; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + /* Add two */ + item1 = g_simple_action_new ("1", NULL); + g_list_store_append (store, item1); + item2 = g_simple_action_new ("2", NULL); + g_list_store_append (store, item2); + + /* Clear the cache */ + g_assert_null (list_model_get (model, 42)); + + /* Access the same position twice */ + temp = list_model_get (model, 1); + g_assert (temp == item2); + g_object_unref (temp); + temp = list_model_get (model, 1); + g_assert (temp == item2); + g_object_unref (temp); + + g_assert_null (list_model_get (model, 42)); + + /* Access forwards */ + temp = list_model_get (model, 0); + g_assert (temp == item1); + g_object_unref (temp); + temp = list_model_get (model, 1); + g_assert (temp == item2); + g_object_unref (temp); + + g_assert_null (list_model_get (model, 42)); + + /* Access backwards */ + temp = list_model_get (model, 1); + g_assert (temp == item2); + g_object_unref (temp); + temp = list_model_get (model, 0); + g_assert (temp == item1); + g_object_unref (temp); + + g_object_unref (item1); + g_object_unref (item2); + g_object_unref (store); +} + +struct ItemsChangedData +{ + guint position; + guint removed; + guint added; + gboolean called; +}; + +static void +expect_items_changed (struct ItemsChangedData *expected, + guint position, + guint removed, + guint added) +{ + expected->position = position; + expected->removed = removed; + expected->added = added; + expected->called = FALSE; +} + +static void +on_items_changed (GListModel *model, + guint position, + guint removed, + guint added, + struct ItemsChangedData *expected) +{ + g_assert_false (expected->called); + g_assert_cmpuint (expected->position, ==, position); + g_assert_cmpuint (expected->removed, ==, removed); + g_assert_cmpuint (expected->added, ==, added); + expected->called = TRUE; +} + +/* Test that all operations on the list emit the items-changed signal */ +static void +test_store_signal_items_changed (void) +{ + GListStore *store; + GListModel *model; + GSimpleAction *item; + struct ItemsChangedData expected = {0}; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + g_object_connect (model, "signal::items-changed", + on_items_changed, &expected, NULL); + + /* Emit the signal manually */ + expect_items_changed (&expected, 0, 0, 0); + g_list_model_items_changed (model, 0, 0, 0); + g_assert_true (expected.called); + + /* Append an item */ + expect_items_changed (&expected, 0, 0, 1); + item = g_simple_action_new ("2", NULL); + g_list_store_append (store, item); + g_object_unref (item); + g_assert_true (expected.called); + + /* Insert an item */ + expect_items_changed (&expected, 1, 0, 1); + item = g_simple_action_new ("1", NULL); + g_list_store_insert (store, 1, item); + g_object_unref (item); + g_assert_true (expected.called); + + /* Sort the list */ + expect_items_changed (&expected, 0, 2, 2); + g_list_store_sort (store, + (GCompareDataFunc)list_model_cmp_action_by_name, + NULL); + g_assert_true (expected.called); + + /* Insert sorted */ + expect_items_changed (&expected, 2, 0, 1); + item = g_simple_action_new ("3", NULL); + g_list_store_insert_sorted (store, + item, + (GCompareDataFunc)list_model_cmp_action_by_name, + NULL); + g_object_unref (item); + g_assert_true (expected.called); + + /* Remove an item */ + expect_items_changed (&expected, 1, 1, 0); + g_list_store_remove (store, 1); + g_assert_true (expected.called); + + /* Splice */ + expect_items_changed (&expected, 0, 2, 1); + item = g_simple_action_new ("4", NULL); + g_assert_cmpuint (g_list_model_get_n_items (model), >=, 2); + g_list_store_splice (store, 0, 2, (gpointer)&item, 1); + g_object_unref (item); + g_assert_true (expected.called); + + /* Remove all */ + expect_items_changed (&expected, 0, 1, 0); + g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1); + g_list_store_remove_all (store); + g_assert_true (expected.called); + + g_object_unref (store); +} + +/* Due to an overflow in the list store last-iter optimization, + * the sequence 'lookup 0; lookup MAXUINT' was returning the + * same item twice, and not NULL for the second lookup. + * See #1639. + */ +static void +test_store_past_end (void) +{ + GListStore *store; + GListModel *model; + GSimpleAction *item; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + model = G_LIST_MODEL (store); + + item = g_simple_action_new ("2", NULL); + g_list_store_append (store, item); + g_object_unref (item); + + g_assert_cmpint (g_list_model_get_n_items (model), ==, 1); + item = g_list_model_get_item (model, 0); + g_assert_nonnull (item); + g_object_unref (item); + item = g_list_model_get_item (model, G_MAXUINT); + g_assert_null (item); + + g_object_unref (store); +} + +static gboolean +list_model_casecmp_action_by_name (gconstpointer a, + gconstpointer b) +{ + return g_ascii_strcasecmp (g_action_get_name (G_ACTION (a)), + g_action_get_name (G_ACTION (b))) == 0; +} + +/* Test if find() and find_with_equal_func() works */ +static void +test_store_find (void) +{ + GListStore *store; + guint position = 100; + const gchar *item_strs[4] = { "aaa", "bbb", "xxx", "ccc" }; + GSimpleAction *items[4] = { NULL, }; + GSimpleAction *other_item; + guint i; + + store = g_list_store_new (G_TYPE_SIMPLE_ACTION); + + for (i = 0; i < G_N_ELEMENTS (item_strs); i++) + items[i] = g_simple_action_new (item_strs[i], NULL); + + /* Shouldn't crash on an empty list, or change the position pointer */ + g_assert_false (g_list_store_find (store, items[0], NULL)); + g_assert_false (g_list_store_find (store, items[0], &position)); + g_assert_cmpint (position, ==, 100); + + for (i = 0; i < G_N_ELEMENTS (item_strs); i++) + g_list_store_append (store, items[i]); + + /* Check whether it could still find the the elements */ + for (i = 0; i < G_N_ELEMENTS (item_strs); i++) + { + g_assert_true (g_list_store_find (store, items[i], &position)); + g_assert_cmpint (position, ==, i); + /* Shouldn't try to write to position pointer if NULL given */ + g_assert_true (g_list_store_find (store, items[i], NULL)); + } + + /* try to find element not part of the list */ + other_item = g_simple_action_new ("111", NULL); + g_assert_false (g_list_store_find (store, other_item, NULL)); + g_clear_object (&other_item); + + /* Re-add item; find() should only return the first position */ + g_list_store_append (store, items[0]); + g_assert_true (g_list_store_find (store, items[0], &position)); + g_assert_cmpint (position, ==, 0); + + /* try to find element which should only work with custom equality check */ + other_item = g_simple_action_new ("XXX", NULL); + g_assert_false (g_list_store_find (store, other_item, NULL)); + g_assert_true (g_list_store_find_with_equal_func (store, + other_item, + list_model_casecmp_action_by_name, + &position)); + g_assert_cmpint (position, ==, 2); + g_clear_object (&other_item); + + for (i = 0; i < G_N_ELEMENTS (item_strs); i++) + g_clear_object(&items[i]); + g_clear_object (&store); +} + +int main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/glistmodel/store/properties", test_store_properties); + g_test_add_func ("/glistmodel/store/non-gobjects", test_store_non_gobjects); + g_test_add_func ("/glistmodel/store/boundaries", test_store_boundaries); + g_test_add_func ("/glistmodel/store/refcounts", test_store_refcounts); + g_test_add_func ("/glistmodel/store/sorted", test_store_sorted); + g_test_add_func ("/glistmodel/store/splice-replace-middle", + test_store_splice_replace_middle); + g_test_add_func ("/glistmodel/store/splice-replace-all", + test_store_splice_replace_all); + g_test_add_func ("/glistmodel/store/splice-noop", test_store_splice_noop); + g_test_add_func ("/glistmodel/store/splice-remove-multiple", + test_store_splice_remove_multiple); + g_test_add_func ("/glistmodel/store/splice-add-multiple", + test_store_splice_add_multiple); + g_test_add_func ("/glistmodel/store/splice-wrong-type", + test_store_splice_wrong_type); + g_test_add_func ("/glistmodel/store/item-type", + test_store_item_type); + g_test_add_func ("/glistmodel/store/remove-all", + test_store_remove_all); + g_test_add_func ("/glistmodel/store/sort", + test_store_sort); + g_test_add_func ("/glistmodel/store/get-item-cache", + test_store_get_item_cache); + g_test_add_func ("/glistmodel/store/items-changed", + test_store_signal_items_changed); + g_test_add_func ("/glistmodel/store/past-end", test_store_past_end); + g_test_add_func ("/glistmodel/store/find", test_store_find); + + return g_test_run (); +} diff --git a/gio/tests/gmenumodel.c b/gio/tests/gmenumodel.c new file mode 100644 index 0000000..492daf8 --- /dev/null +++ b/gio/tests/gmenumodel.c @@ -0,0 +1,1532 @@ +#include +#include +#include +#include + +#include "gdbus-sessionbus.h" + +#include "glib/glib-private.h" + +static gboolean +time_out (gpointer unused G_GNUC_UNUSED) +{ + g_error ("Timed out"); + /* not reached */ + return FALSE; +} + +static guint +add_timeout (guint seconds) +{ +#ifdef G_OS_UNIX + /* Safety-catch against the main loop having blocked */ + alarm (seconds + 5); +#endif + return g_timeout_add_seconds (seconds, time_out, NULL); +} + +static void +cancel_timeout (guint timeout_id) +{ +#ifdef G_OS_UNIX + alarm (0); +#endif + g_source_remove (timeout_id); +} + +/* Markup printing {{{1 */ + +/* This used to be part of GLib, but it was removed before the stable + * release because it wasn't generally useful. We want it here, though. + */ +static void +indent_string (GString *string, + gint indent) +{ + while (indent--) + g_string_append_c (string, ' '); +} + +static GString * +g_menu_markup_print_string (GString *string, + GMenuModel *model, + gint indent, + gint tabstop) +{ + gboolean need_nl = FALSE; + gint i, n; + + if G_UNLIKELY (string == NULL) + string = g_string_new (NULL); + + n = g_menu_model_get_n_items (model); + + for (i = 0; i < n; i++) + { + GMenuAttributeIter *attr_iter; + GMenuLinkIter *link_iter; + GString *contents; + GString *attrs; + + attr_iter = g_menu_model_iterate_item_attributes (model, i); + link_iter = g_menu_model_iterate_item_links (model, i); + contents = g_string_new (NULL); + attrs = g_string_new (NULL); + + while (g_menu_attribute_iter_next (attr_iter)) + { + const char *name = g_menu_attribute_iter_get_name (attr_iter); + GVariant *value = g_menu_attribute_iter_get_value (attr_iter); + + if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) + { + gchar *str; + str = g_markup_printf_escaped (" %s='%s'", name, g_variant_get_string (value, NULL)); + g_string_append (attrs, str); + g_free (str); + } + + else + { + gchar *printed; + gchar *str; + const gchar *type; + + printed = g_variant_print (value, TRUE); + type = g_variant_type_peek_string (g_variant_get_type (value)); + str = g_markup_printf_escaped ("%s\n", name, type, printed); + indent_string (contents, indent + tabstop); + g_string_append (contents, str); + g_free (printed); + g_free (str); + } + + g_variant_unref (value); + } + g_object_unref (attr_iter); + + while (g_menu_link_iter_next (link_iter)) + { + const gchar *name = g_menu_link_iter_get_name (link_iter); + GMenuModel *menu = g_menu_link_iter_get_value (link_iter); + gchar *str; + + if (contents->str[0]) + g_string_append_c (contents, '\n'); + + str = g_markup_printf_escaped ("\n", name); + indent_string (contents, indent + tabstop); + g_string_append (contents, str); + g_free (str); + + g_menu_markup_print_string (contents, menu, indent + 2 * tabstop, tabstop); + + indent_string (contents, indent + tabstop); + g_string_append (contents, "\n"); + g_object_unref (menu); + } + g_object_unref (link_iter); + + if (contents->str[0]) + { + indent_string (string, indent); + g_string_append_printf (string, "\n", attrs->str); + g_string_append (string, contents->str); + indent_string (string, indent); + g_string_append (string, "\n"); + need_nl = TRUE; + } + + else + { + if (need_nl) + g_string_append_c (string, '\n'); + + indent_string (string, indent); + g_string_append_printf (string, "\n", attrs->str); + need_nl = FALSE; + } + + g_string_free (contents, TRUE); + g_string_free (attrs, TRUE); + } + + return string; +} + +/* TestItem {{{1 */ + +/* This utility struct is used by both the RandomMenu and MirrorMenu + * class implementations below. + */ +typedef struct { + GHashTable *attributes; + GHashTable *links; +} TestItem; + +static TestItem * +test_item_new (GHashTable *attributes, + GHashTable *links) +{ + TestItem *item; + + item = g_slice_new (TestItem); + item->attributes = g_hash_table_ref (attributes); + item->links = g_hash_table_ref (links); + + return item; +} + +static void +test_item_free (gpointer data) +{ + TestItem *item = data; + + g_hash_table_unref (item->attributes); + g_hash_table_unref (item->links); + + g_slice_free (TestItem, item); +} + +/* RandomMenu {{{1 */ +#define MAX_ITEMS 5 +#define TOP_ORDER 4 + +typedef struct { + GMenuModel parent_instance; + + GSequence *items; + gint order; +} RandomMenu; + +typedef GMenuModelClass RandomMenuClass; + +static GType random_menu_get_type (void); +G_DEFINE_TYPE (RandomMenu, random_menu, G_TYPE_MENU_MODEL) + +static gboolean +random_menu_is_mutable (GMenuModel *model) +{ + return TRUE; +} + +static gint +random_menu_get_n_items (GMenuModel *model) +{ + RandomMenu *menu = (RandomMenu *) model; + + return g_sequence_get_length (menu->items); +} + +static void +random_menu_get_item_attributes (GMenuModel *model, + gint position, + GHashTable **table) +{ + RandomMenu *menu = (RandomMenu *) model; + TestItem *item; + + item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position)); + *table = g_hash_table_ref (item->attributes); +} + +static void +random_menu_get_item_links (GMenuModel *model, + gint position, + GHashTable **table) +{ + RandomMenu *menu = (RandomMenu *) model; + TestItem *item; + + item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position)); + *table = g_hash_table_ref (item->links); +} + +static void +random_menu_finalize (GObject *object) +{ + RandomMenu *menu = (RandomMenu *) object; + + g_sequence_free (menu->items); + + G_OBJECT_CLASS (random_menu_parent_class) + ->finalize (object); +} + +static void +random_menu_init (RandomMenu *menu) +{ +} + +static void +random_menu_class_init (GMenuModelClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + class->is_mutable = random_menu_is_mutable; + class->get_n_items = random_menu_get_n_items; + class->get_item_attributes = random_menu_get_item_attributes; + class->get_item_links = random_menu_get_item_links; + + object_class->finalize = random_menu_finalize; +} + +static RandomMenu * random_menu_new (GRand *rand, gint order); + +static void +random_menu_change (RandomMenu *menu, + GRand *rand) +{ + gint position, removes, adds; + GSequenceIter *point; + gint n_items; + gint i; + + n_items = g_sequence_get_length (menu->items); + + do + { + position = g_rand_int_range (rand, 0, n_items + 1); + removes = g_rand_int_range (rand, 0, n_items - position + 1); + adds = g_rand_int_range (rand, 0, MAX_ITEMS - (n_items - removes) + 1); + } + while (removes == 0 && adds == 0); + + point = g_sequence_get_iter_at_pos (menu->items, position + removes); + + if (removes) + { + GSequenceIter *start; + + start = g_sequence_get_iter_at_pos (menu->items, position); + g_sequence_remove_range (start, point); + } + + for (i = 0; i < adds; i++) + { + const gchar *label; + GHashTable *links; + GHashTable *attributes; + + attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); + + if (menu->order > 0 && g_rand_boolean (rand)) + { + RandomMenu *child; + const gchar *subtype; + + child = random_menu_new (rand, menu->order - 1); + + if (g_rand_boolean (rand)) + { + subtype = G_MENU_LINK_SECTION; + /* label some section headers */ + if (g_rand_boolean (rand)) + label = "Section"; + else + label = NULL; + } + else + { + /* label all submenus */ + subtype = G_MENU_LINK_SUBMENU; + label = "Submenu"; + } + + g_hash_table_insert (links, g_strdup (subtype), child); + } + else + /* label all terminals */ + label = "Menu Item"; + + if (label) + g_hash_table_insert (attributes, g_strdup ("label"), g_variant_ref_sink (g_variant_new_string (label))); + + g_sequence_insert_before (point, test_item_new (attributes, links)); + g_hash_table_unref (links); + g_hash_table_unref (attributes); + } + + g_menu_model_items_changed (G_MENU_MODEL (menu), position, removes, adds); +} + +static RandomMenu * +random_menu_new (GRand *rand, + gint order) +{ + RandomMenu *menu; + + menu = g_object_new (random_menu_get_type (), NULL); + menu->items = g_sequence_new (test_item_free); + menu->order = order; + + random_menu_change (menu, rand); + + return menu; +} + +/* MirrorMenu {{{1 */ +typedef struct { + GMenuModel parent_instance; + + GMenuModel *clone_of; + GSequence *items; + gulong handler_id; +} MirrorMenu; + +typedef GMenuModelClass MirrorMenuClass; + +static GType mirror_menu_get_type (void); +G_DEFINE_TYPE (MirrorMenu, mirror_menu, G_TYPE_MENU_MODEL) + +static gboolean +mirror_menu_is_mutable (GMenuModel *model) +{ + MirrorMenu *menu = (MirrorMenu *) model; + + return menu->handler_id != 0; +} + +static gint +mirror_menu_get_n_items (GMenuModel *model) +{ + MirrorMenu *menu = (MirrorMenu *) model; + + return g_sequence_get_length (menu->items); +} + +static void +mirror_menu_get_item_attributes (GMenuModel *model, + gint position, + GHashTable **table) +{ + MirrorMenu *menu = (MirrorMenu *) model; + TestItem *item; + + item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position)); + *table = g_hash_table_ref (item->attributes); +} + +static void +mirror_menu_get_item_links (GMenuModel *model, + gint position, + GHashTable **table) +{ + MirrorMenu *menu = (MirrorMenu *) model; + TestItem *item; + + item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position)); + *table = g_hash_table_ref (item->links); +} + +static void +mirror_menu_finalize (GObject *object) +{ + MirrorMenu *menu = (MirrorMenu *) object; + + if (menu->handler_id) + g_signal_handler_disconnect (menu->clone_of, menu->handler_id); + + g_sequence_free (menu->items); + g_object_unref (menu->clone_of); + + G_OBJECT_CLASS (mirror_menu_parent_class) + ->finalize (object); +} + +static void +mirror_menu_init (MirrorMenu *menu) +{ +} + +static void +mirror_menu_class_init (GMenuModelClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + class->is_mutable = mirror_menu_is_mutable; + class->get_n_items = mirror_menu_get_n_items; + class->get_item_attributes = mirror_menu_get_item_attributes; + class->get_item_links = mirror_menu_get_item_links; + + object_class->finalize = mirror_menu_finalize; +} + +static MirrorMenu * mirror_menu_new (GMenuModel *clone_of); + +static void +mirror_menu_changed (GMenuModel *model, + gint position, + gint removed, + gint added, + gpointer user_data) +{ + MirrorMenu *menu = user_data; + GSequenceIter *point; + gint i; + + g_assert (model == menu->clone_of); + + point = g_sequence_get_iter_at_pos (menu->items, position + removed); + + if (removed) + { + GSequenceIter *start; + + start = g_sequence_get_iter_at_pos (menu->items, position); + g_sequence_remove_range (start, point); + } + + for (i = position; i < position + added; i++) + { + GMenuAttributeIter *attr_iter; + GMenuLinkIter *link_iter; + GHashTable *links; + GHashTable *attributes; + const gchar *name; + GMenuModel *child; + GVariant *value; + + attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); + links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); + + attr_iter = g_menu_model_iterate_item_attributes (model, i); + while (g_menu_attribute_iter_get_next (attr_iter, &name, &value)) + { + g_hash_table_insert (attributes, g_strdup (name), value); + } + g_object_unref (attr_iter); + + link_iter = g_menu_model_iterate_item_links (model, i); + while (g_menu_link_iter_get_next (link_iter, &name, &child)) + { + g_hash_table_insert (links, g_strdup (name), mirror_menu_new (child)); + g_object_unref (child); + } + g_object_unref (link_iter); + + g_sequence_insert_before (point, test_item_new (attributes, links)); + g_hash_table_unref (attributes); + g_hash_table_unref (links); + } + + g_menu_model_items_changed (G_MENU_MODEL (menu), position, removed, added); +} + +static MirrorMenu * +mirror_menu_new (GMenuModel *clone_of) +{ + MirrorMenu *menu; + + menu = g_object_new (mirror_menu_get_type (), NULL); + menu->items = g_sequence_new (test_item_free); + menu->clone_of = g_object_ref (clone_of); + + if (g_menu_model_is_mutable (clone_of)) + menu->handler_id = g_signal_connect (clone_of, "items-changed", G_CALLBACK (mirror_menu_changed), menu); + mirror_menu_changed (clone_of, 0, 0, g_menu_model_get_n_items (clone_of), menu); + + return menu; +} + +/* check_menus_equal(), assert_menus_equal() {{{1 */ +static gboolean +check_menus_equal (GMenuModel *a, + GMenuModel *b) +{ + gboolean equal = TRUE; + gint a_n, b_n; + gint i; + + a_n = g_menu_model_get_n_items (a); + b_n = g_menu_model_get_n_items (b); + + if (a_n != b_n) + return FALSE; + + for (i = 0; i < a_n; i++) + { + GMenuAttributeIter *attr_iter; + GVariant *a_value, *b_value; + GMenuLinkIter *link_iter; + GMenuModel *a_menu, *b_menu; + const gchar *name; + + attr_iter = g_menu_model_iterate_item_attributes (a, i); + while (g_menu_attribute_iter_get_next (attr_iter, &name, &a_value)) + { + b_value = g_menu_model_get_item_attribute_value (b, i, name, NULL); + equal &= b_value && g_variant_equal (a_value, b_value); + if (b_value) + g_variant_unref (b_value); + g_variant_unref (a_value); + } + g_object_unref (attr_iter); + + attr_iter = g_menu_model_iterate_item_attributes (b, i); + while (g_menu_attribute_iter_get_next (attr_iter, &name, &b_value)) + { + a_value = g_menu_model_get_item_attribute_value (a, i, name, NULL); + equal &= a_value && g_variant_equal (a_value, b_value); + if (a_value) + g_variant_unref (a_value); + g_variant_unref (b_value); + } + g_object_unref (attr_iter); + + link_iter = g_menu_model_iterate_item_links (a, i); + while (g_menu_link_iter_get_next (link_iter, &name, &a_menu)) + { + b_menu = g_menu_model_get_item_link (b, i, name); + equal &= b_menu && check_menus_equal (a_menu, b_menu); + if (b_menu) + g_object_unref (b_menu); + g_object_unref (a_menu); + } + g_object_unref (link_iter); + + link_iter = g_menu_model_iterate_item_links (b, i); + while (g_menu_link_iter_get_next (link_iter, &name, &b_menu)) + { + a_menu = g_menu_model_get_item_link (a, i, name); + equal &= a_menu && check_menus_equal (a_menu, b_menu); + if (a_menu) + g_object_unref (a_menu); + g_object_unref (b_menu); + } + g_object_unref (link_iter); + } + + return equal; +} + +static void +assert_menus_equal (GMenuModel *a, + GMenuModel *b) +{ + if (!check_menus_equal (a, b)) + { + GString *string; + + string = g_string_new ("\n \n"); + g_menu_markup_print_string (string, G_MENU_MODEL (a), 4, 2); + g_string_append (string, " \n\n-------------\n \n"); + g_menu_markup_print_string (string, G_MENU_MODEL (b), 4, 2); + g_string_append (string, " \n"); + g_error ("%s", string->str); + } +} + +static void +assert_menuitem_equal (GMenuItem *item, + GMenuModel *model, + gint index) +{ + GMenuAttributeIter *attr_iter; + GMenuLinkIter *link_iter; + const gchar *name; + GVariant *value; + GMenuModel *linked_model; + + /* NOTE we can't yet test whether item has attributes or links that + * are not in the model, because there's no iterator API for menu + * items */ + + attr_iter = g_menu_model_iterate_item_attributes (model, index); + while (g_menu_attribute_iter_get_next (attr_iter, &name, &value)) + { + GVariant *item_value; + + item_value = g_menu_item_get_attribute_value (item, name, g_variant_get_type (value)); + g_assert (item_value && g_variant_equal (item_value, value)); + + g_variant_unref (item_value); + g_variant_unref (value); + } + + link_iter = g_menu_model_iterate_item_links (model, index); + while (g_menu_link_iter_get_next (link_iter, &name, &linked_model)) + { + GMenuModel *item_linked_model; + + item_linked_model = g_menu_item_get_link (item, name); + g_assert (linked_model == item_linked_model); + + g_object_unref (item_linked_model); + g_object_unref (linked_model); + } + + g_object_unref (attr_iter); + g_object_unref (link_iter); +} + +/* Test cases {{{1 */ +static void +test_equality (void) +{ + GRand *randa, *randb; + guint32 seed; + gint i; + + seed = g_test_rand_int (); + + randa = g_rand_new_with_seed (seed); + randb = g_rand_new_with_seed (seed); + + for (i = 0; i < 500; i++) + { + RandomMenu *a, *b; + + a = random_menu_new (randa, TOP_ORDER); + b = random_menu_new (randb, TOP_ORDER); + assert_menus_equal (G_MENU_MODEL (a), G_MENU_MODEL (b)); + g_object_unref (b); + g_object_unref (a); + } + + g_rand_int (randa); + + for (i = 0; i < 500;) + { + RandomMenu *a, *b; + + a = random_menu_new (randa, TOP_ORDER); + b = random_menu_new (randb, TOP_ORDER); + if (check_menus_equal (G_MENU_MODEL (a), G_MENU_MODEL (b))) + { + /* by chance, they may really be equal. double check. */ + GString *as, *bs; + + as = g_menu_markup_print_string (NULL, G_MENU_MODEL (a), 4, 2); + bs = g_menu_markup_print_string (NULL, G_MENU_MODEL (b), 4, 2); + g_assert_cmpstr (as->str, ==, bs->str); + g_string_free (bs, TRUE); + g_string_free (as, TRUE); + + /* we're here because randa and randb just generated equal + * menus. they may do it again, so throw away randb and make + * a fresh one. + */ + g_rand_free (randb); + randb = g_rand_new_with_seed (g_rand_int (randa)); + } + else + /* make sure we get enough unequals (ie: no GRand failure) */ + i++; + + g_object_unref (b); + g_object_unref (a); + } + + g_rand_free (randb); + g_rand_free (randa); +} + +static void +test_random (void) +{ + RandomMenu *random; + MirrorMenu *mirror; + GRand *rand; + gint i; + + rand = g_rand_new_with_seed (g_test_rand_int ()); + random = random_menu_new (rand, TOP_ORDER); + mirror = mirror_menu_new (G_MENU_MODEL (random)); + + for (i = 0; i < 500; i++) + { + assert_menus_equal (G_MENU_MODEL (random), G_MENU_MODEL (mirror)); + random_menu_change (random, rand); + } + + g_object_unref (mirror); + g_object_unref (random); + + g_rand_free (rand); +} + +typedef struct +{ + GDBusConnection *client_connection; + GDBusConnection *server_connection; + GDBusServer *server; + + GThread *service_thread; + /* Protects server_connection and service_loop. */ + GMutex service_loop_lock; + GCond service_loop_cond; + + GMainLoop *service_loop; +} PeerConnection; + +static gboolean +on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + PeerConnection *data = user_data; + + g_mutex_lock (&data->service_loop_lock); + data->server_connection = g_object_ref (connection); + g_cond_broadcast (&data->service_loop_cond); + g_mutex_unlock (&data->service_loop_lock); + + return TRUE; +} + +static void +create_service_loop (GMainContext *service_context, + PeerConnection *data) +{ + g_assert (data->service_loop == NULL); + g_mutex_lock (&data->service_loop_lock); + data->service_loop = g_main_loop_new (service_context, FALSE); + g_cond_broadcast (&data->service_loop_cond); + g_mutex_unlock (&data->service_loop_lock); +} + +static void +teardown_service_loop (PeerConnection *data) +{ + g_mutex_lock (&data->service_loop_lock); + g_clear_pointer (&data->service_loop, g_main_loop_unref); + g_mutex_unlock (&data->service_loop_lock); +} + +static void +await_service_loop (PeerConnection *data) +{ + g_mutex_lock (&data->service_loop_lock); + while (data->service_loop == NULL) + g_cond_wait (&data->service_loop_cond, &data->service_loop_lock); + g_mutex_unlock (&data->service_loop_lock); +} + +static void +await_server_connection (PeerConnection *data) +{ + g_mutex_lock (&data->service_loop_lock); + while (data->server_connection == NULL) + g_cond_wait (&data->service_loop_cond, &data->service_loop_lock); + g_mutex_unlock (&data->service_loop_lock); +} + +static gpointer +service_thread_func (gpointer user_data) +{ + PeerConnection *data = user_data; + GMainContext *service_context; + GError *error; + gchar *address; + gchar *tmpdir; + GDBusServerFlags flags; + gchar *guid; + + service_context = g_main_context_new (); + g_main_context_push_thread_default (service_context); + + tmpdir = NULL; + flags = G_DBUS_SERVER_FLAGS_NONE; + +#ifdef G_OS_UNIX + if (g_unix_socket_address_abstract_names_supported ()) + address = g_strdup ("unix:tmpdir=/tmp/test-dbus-peer"); + else + { + tmpdir = g_dir_make_tmp ("test-dbus-peer-XXXXXX", NULL); + address = g_strdup_printf ("unix:tmpdir=%s", tmpdir); + } +#else + address = g_strdup ("nonce-tcp:"); + flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; +#endif + + guid = g_dbus_generate_guid (); + + error = NULL; + data->server = g_dbus_server_new_sync (address, + flags, + guid, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_free (address); + g_free (guid); + + g_signal_connect (data->server, + "new-connection", + G_CALLBACK (on_new_connection), + data); + + g_dbus_server_start (data->server); + + create_service_loop (service_context, data); + g_main_loop_run (data->service_loop); + + g_main_context_pop_thread_default (service_context); + + teardown_service_loop (data); + g_main_context_unref (service_context); + + if (tmpdir) + { + g_rmdir (tmpdir); + g_free (tmpdir); + } + + return NULL; +} + +static void +peer_connection_up (PeerConnection *data) +{ + GError *error; + + memset (data, '\0', sizeof (PeerConnection)); + + g_mutex_init (&data->service_loop_lock); + g_cond_init (&data->service_loop_cond); + + /* bring up a server - we run the server in a different thread to + avoid deadlocks */ + data->service_thread = g_thread_new ("test_dbus_peer", + service_thread_func, + data); + await_service_loop (data); + g_assert (data->server != NULL); + + /* bring up a connection and accept it */ + error = NULL; + data->client_connection = + g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (data->server), + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, /* GDBusAuthObserver */ + NULL, /* cancellable */ + &error); + g_assert_no_error (error); + g_assert (data->client_connection != NULL); + await_server_connection (data); +} + +static void +peer_connection_down (PeerConnection *data) +{ + g_object_unref (data->client_connection); + g_object_unref (data->server_connection); + + g_dbus_server_stop (data->server); + g_object_unref (data->server); + + g_main_loop_quit (data->service_loop); + g_thread_join (data->service_thread); + + g_mutex_clear (&data->service_loop_lock); + g_cond_clear (&data->service_loop_cond); +} + +struct roundtrip_state +{ + RandomMenu *random; + MirrorMenu *proxy_mirror; + GDBusMenuModel *proxy; + GMainLoop *loop; + GRand *rand; + gint success; + gint count; +}; + +static gboolean +roundtrip_step (gpointer data) +{ + struct roundtrip_state *state = data; + + if (check_menus_equal (G_MENU_MODEL (state->random), G_MENU_MODEL (state->proxy)) && + check_menus_equal (G_MENU_MODEL (state->random), G_MENU_MODEL (state->proxy_mirror))) + { + state->success++; + state->count = 0; + + if (state->success < 100) + random_menu_change (state->random, state->rand); + else + g_main_loop_quit (state->loop); + } + else if (state->count == 100) + { + assert_menus_equal (G_MENU_MODEL (state->random), G_MENU_MODEL (state->proxy)); + g_assert_not_reached (); + } + else + state->count++; + + return G_SOURCE_CONTINUE; +} + +static void +do_roundtrip (GDBusConnection *exporter_connection, + GDBusConnection *proxy_connection) +{ + struct roundtrip_state state; + guint export_id; + guint id; + + state.rand = g_rand_new_with_seed (g_test_rand_int ()); + + state.random = random_menu_new (state.rand, 2); + export_id = g_dbus_connection_export_menu_model (exporter_connection, + "/", + G_MENU_MODEL (state.random), + NULL); + state.proxy = g_dbus_menu_model_get (proxy_connection, + g_dbus_connection_get_unique_name (proxy_connection), + "/"); + state.proxy_mirror = mirror_menu_new (G_MENU_MODEL (state.proxy)); + state.count = 0; + state.success = 0; + + id = g_timeout_add (10, roundtrip_step, &state); + + state.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (state.loop); + + g_main_loop_unref (state.loop); + g_source_remove (id); + g_object_unref (state.proxy); + g_dbus_connection_unexport_menu_model (exporter_connection, export_id); + g_object_unref (state.random); + g_object_unref (state.proxy_mirror); + g_rand_free (state.rand); +} + +static void +test_dbus_roundtrip (void) +{ + GDBusConnection *bus; + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + do_roundtrip (bus, bus); + g_object_unref (bus); +} + +static void +test_dbus_peer_roundtrip (void) +{ +#ifdef _GLIB_ADDRESS_SANITIZER + g_test_incomplete ("FIXME: Leaks a GCancellableSource, see glib#2313"); + (void) peer_connection_up; + (void) peer_connection_down; +#else + PeerConnection peer; + + peer_connection_up (&peer); + do_roundtrip (peer.server_connection, peer.client_connection); + peer_connection_down (&peer); +#endif +} + +static gint items_changed_count; + +static void +items_changed (GMenuModel *model, + gint position, + gint removed, + gint added, + gpointer data) +{ + items_changed_count++; +} + +static gboolean +stop_loop (gpointer data) +{ + GMainLoop *loop = data; + + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static void +do_subscriptions (GDBusConnection *exporter_connection, + GDBusConnection *proxy_connection) +{ + GMenu *menu; + GDBusMenuModel *proxy; + GMainLoop *loop; + GError *error = NULL; + guint export_id; + guint timeout_id; + + timeout_id = add_timeout (60); + loop = g_main_loop_new (NULL, FALSE); + + menu = g_menu_new (); + + export_id = g_dbus_connection_export_menu_model (exporter_connection, + "/", + G_MENU_MODEL (menu), + &error); + g_assert_no_error (error); + + proxy = g_dbus_menu_model_get (proxy_connection, + g_dbus_connection_get_unique_name (proxy_connection), + "/"); + items_changed_count = 0; + g_signal_connect (proxy, "items-changed", + G_CALLBACK (items_changed), NULL); + + g_menu_append (menu, "item1", NULL); + g_menu_append (menu, "item2", NULL); + g_menu_append (menu, "item3", NULL); + + g_assert_cmpint (items_changed_count, ==, 0); + + /* We don't subscribe to change-notification until we look at the items */ + g_timeout_add (100, stop_loop, loop); + g_main_loop_run (loop); + + /* Looking at the items triggers subscription */ + g_menu_model_get_n_items (G_MENU_MODEL (proxy)); + + while (items_changed_count < 1) + g_main_context_iteration (NULL, TRUE); + + /* We get all three items in one batch */ + g_assert_cmpint (items_changed_count, ==, 1); + g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (proxy)), ==, 3); + + /* If we wait, we don't get any more */ + g_timeout_add (100, stop_loop, loop); + g_main_loop_run (loop); + g_assert_cmpint (items_changed_count, ==, 1); + g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (proxy)), ==, 3); + + /* Now we're subscribed, we get changes individually */ + g_menu_append (menu, "item4", NULL); + g_menu_append (menu, "item5", NULL); + g_menu_append (menu, "item6", NULL); + g_menu_remove (menu, 0); + g_menu_remove (menu, 0); + + while (items_changed_count < 6) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpint (items_changed_count, ==, 6); + + g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (proxy)), ==, 4); + + /* After destroying the proxy and waiting a bit, we don't get any more + * items-changed signals */ + g_object_unref (proxy); + + g_timeout_add (100, stop_loop, loop); + g_main_loop_run (loop); + + g_menu_remove (menu, 0); + g_menu_remove (menu, 0); + + g_timeout_add (100, stop_loop, loop); + g_main_loop_run (loop); + + g_assert_cmpint (items_changed_count, ==, 6); + + g_dbus_connection_unexport_menu_model (exporter_connection, export_id); + g_object_unref (menu); + + g_main_loop_unref (loop); + cancel_timeout (timeout_id); +} + +static void +test_dbus_subscriptions (void) +{ + GDBusConnection *bus; + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + do_subscriptions (bus, bus); + g_object_unref (bus); +} + +static void +test_dbus_peer_subscriptions (void) +{ +#ifdef _GLIB_ADDRESS_SANITIZER + g_test_incomplete ("FIXME: Leaks a GCancellableSource, see glib#2313"); + (void) peer_connection_up; + (void) peer_connection_down; +#else + PeerConnection peer; + + peer_connection_up (&peer); + do_subscriptions (peer.server_connection, peer.client_connection); + peer_connection_down (&peer); +#endif +} + +static gpointer +do_modify (gpointer data) +{ + RandomMenu *menu = data; + GRand *rand; + gint i; + + rand = g_rand_new_with_seed (g_test_rand_int ()); + + for (i = 0; i < 10000; i++) + { + random_menu_change (menu, rand); + } + + g_rand_free (rand); + + return NULL; +} + +static gpointer +do_export (gpointer data) +{ + GMenuModel *menu = data; + gint i; + GDBusConnection *bus; + gchar *path; + GError *error = NULL; + guint id; + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + path = g_strdup_printf ("/%p", data); + + for (i = 0; i < 10000; i++) + { + id = g_dbus_connection_export_menu_model (bus, path, menu, &error); + g_assert_no_error (error); + g_dbus_connection_unexport_menu_model (bus, id); + while (g_main_context_iteration (NULL, FALSE)); + } + + g_free (path); + + g_object_unref (bus); + + return NULL; +} + +static void +test_dbus_threaded (void) +{ + RandomMenu *menu[10]; + GThread *call[10]; + GThread *export[10]; + gint i; + + for (i = 0; i < 10; i++) + { + GRand *rand = g_rand_new_with_seed (g_test_rand_int ()); + menu[i] = random_menu_new (rand, 2); + call[i] = g_thread_new ("call", do_modify, menu[i]); + export[i] = g_thread_new ("export", do_export, menu[i]); + g_rand_free (rand); + } + + for (i = 0; i < 10; i++) + { + g_thread_join (call[i]); + g_thread_join (export[i]); + } + + for (i = 0; i < 10; i++) + g_object_unref (menu[i]); +} + +static void +test_attributes (void) +{ + GMenu *menu; + GMenuItem *item; + GVariant *v; + + menu = g_menu_new (); + + item = g_menu_item_new ("test", NULL); + g_menu_item_set_attribute_value (item, "boolean", g_variant_new_boolean (FALSE)); + g_menu_item_set_attribute_value (item, "string", g_variant_new_string ("bla")); + + g_menu_item_set_attribute (item, "double", "d", 1.5); + v = g_variant_new_parsed ("[('one', 1), ('two', %i), (%s, 3)]", 2, "three"); + g_menu_item_set_attribute_value (item, "complex", v); + g_menu_item_set_attribute_value (item, "test-123", g_variant_new_string ("test-123")); + + g_menu_append_item (menu, item); + + g_menu_item_set_attribute (item, "double", "d", G_PI); + + g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (menu)), ==, 1); + + v = g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu), 0, "boolean", NULL); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)); + g_variant_unref (v); + + v = g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu), 0, "string", NULL); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)); + g_variant_unref (v); + + v = g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu), 0, "double", NULL); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_DOUBLE)); + g_variant_unref (v); + + v = g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu), 0, "complex", NULL); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE("a(si)"))); + g_variant_unref (v); + + g_menu_remove_all (menu); + + g_object_unref (menu); + g_object_unref (item); +} + +static void +test_attribute_iter (void) +{ + GMenu *menu; + GMenuItem *item; + const gchar *name; + GVariant *v; + GMenuAttributeIter *iter; + GHashTable *found; + + menu = g_menu_new (); + + item = g_menu_item_new ("test", NULL); + g_menu_item_set_attribute_value (item, "boolean", g_variant_new_boolean (FALSE)); + g_menu_item_set_attribute_value (item, "string", g_variant_new_string ("bla")); + + g_menu_item_set_attribute (item, "double", "d", 1.5); + v = g_variant_new_parsed ("[('one', 1), ('two', %i), (%s, 3)]", 2, "three"); + g_menu_item_set_attribute_value (item, "complex", v); + g_menu_item_set_attribute_value (item, "test-123", g_variant_new_string ("test-123")); + + g_menu_append_item (menu, item); + + g_menu_item_set_attribute (item, "double", "d", G_PI); + + g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (menu)), ==, 1); + + found = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); + + iter = g_menu_model_iterate_item_attributes (G_MENU_MODEL (menu), 0); + while (g_menu_attribute_iter_get_next (iter, &name, &v)) + g_hash_table_insert (found, g_strdup (name), v); + + g_assert_cmpint (g_hash_table_size (found), ==, 6); + + v = g_hash_table_lookup (found, "label"); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)); + + v = g_hash_table_lookup (found, "boolean"); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)); + + v = g_hash_table_lookup (found, "string"); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)); + + v = g_hash_table_lookup (found, "double"); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_DOUBLE)); + + v = g_hash_table_lookup (found, "complex"); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE("a(si)"))); + + v = g_hash_table_lookup (found, "test-123"); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)); + + g_hash_table_unref (found); + + g_menu_remove_all (menu); + + g_object_unref (menu); + g_object_unref (item); +} + +static void +test_links (void) +{ + GMenu *menu; + GMenuModel *m; + GMenuModel *x; + GMenuItem *item; + + m = G_MENU_MODEL (g_menu_new ()); + g_menu_append (G_MENU (m), "test", NULL); + + menu = g_menu_new (); + + item = g_menu_item_new ("test2", NULL); + g_menu_item_set_link (item, "submenu", m); + g_menu_prepend_item (menu, item); + + item = g_menu_item_new ("test1", NULL); + g_menu_item_set_link (item, "section", m); + g_menu_insert_item (menu, 0, item); + + item = g_menu_item_new ("test3", NULL); + g_menu_item_set_link (item, "wallet", m); + g_menu_insert_item (menu, 1000, item); + + item = g_menu_item_new ("test4", NULL); + g_menu_item_set_link (item, "purse", m); + g_menu_item_set_link (item, "purse", NULL); + g_menu_append_item (menu, item); + + g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (menu)), ==, 4); + + x = g_menu_model_get_item_link (G_MENU_MODEL (menu), 0, "section"); + g_assert (x == m); + g_object_unref (x); + + x = g_menu_model_get_item_link (G_MENU_MODEL (menu), 1, "submenu"); + g_assert (x == m); + g_object_unref (x); + + x = g_menu_model_get_item_link (G_MENU_MODEL (menu), 2, "wallet"); + g_assert (x == m); + g_object_unref (x); + + x = g_menu_model_get_item_link (G_MENU_MODEL (menu), 3, "purse"); + g_assert (x == NULL); + + g_object_unref (m); + g_object_unref (menu); +} + +static void +test_mutable (void) +{ + GMenu *menu; + + menu = g_menu_new (); + g_menu_append (menu, "test", "test"); + + g_assert (g_menu_model_is_mutable (G_MENU_MODEL (menu))); + g_menu_freeze (menu); + g_assert (!g_menu_model_is_mutable (G_MENU_MODEL (menu))); + + g_object_unref (menu); +} + +static void +test_convenience (void) +{ + GMenu *m1, *m2; + GMenu *sub; + GMenuItem *item; + + m1 = g_menu_new (); + m2 = g_menu_new (); + sub = g_menu_new (); + + g_menu_prepend (m1, "label1", "do::something"); + g_menu_insert (m2, 0, "label1", "do::something"); + + g_menu_append (m1, "label2", "do::somethingelse"); + g_menu_insert (m2, -1, "label2", "do::somethingelse"); + + g_menu_insert_section (m1, 10, "label3", G_MENU_MODEL (sub)); + item = g_menu_item_new_section ("label3", G_MENU_MODEL (sub)); + g_menu_insert_item (m2, 10, item); + g_object_unref (item); + + g_menu_prepend_section (m1, "label4", G_MENU_MODEL (sub)); + g_menu_insert_section (m2, 0, "label4", G_MENU_MODEL (sub)); + + g_menu_append_section (m1, "label5", G_MENU_MODEL (sub)); + g_menu_insert_section (m2, -1, "label5", G_MENU_MODEL (sub)); + + g_menu_insert_submenu (m1, 5, "label6", G_MENU_MODEL (sub)); + item = g_menu_item_new_submenu ("label6", G_MENU_MODEL (sub)); + g_menu_insert_item (m2, 5, item); + g_object_unref (item); + + g_menu_prepend_submenu (m1, "label7", G_MENU_MODEL (sub)); + g_menu_insert_submenu (m2, 0, "label7", G_MENU_MODEL (sub)); + + g_menu_append_submenu (m1, "label8", G_MENU_MODEL (sub)); + g_menu_insert_submenu (m2, -1, "label8", G_MENU_MODEL (sub)); + + assert_menus_equal (G_MENU_MODEL (m1), G_MENU_MODEL (m2)); + + g_object_unref (m1); + g_object_unref (m2); +} + +static void +test_menuitem (void) +{ + GMenu *menu; + GMenu *submenu; + GMenuItem *item; + GIcon *icon; + gboolean b; + gchar *s; + + menu = g_menu_new (); + submenu = g_menu_new (); + + item = g_menu_item_new ("label", "action"); + g_menu_item_set_attribute (item, "attribute", "b", TRUE); + g_menu_item_set_link (item, G_MENU_LINK_SUBMENU, G_MENU_MODEL (submenu)); + g_menu_append_item (menu, item); + + icon = g_themed_icon_new ("bla"); + g_menu_item_set_icon (item, icon); + g_object_unref (icon); + + g_assert (g_menu_item_get_attribute (item, "attribute", "b", &b)); + g_assert (b); + + g_menu_item_set_action_and_target (item, "action", "(bs)", TRUE, "string"); + g_assert (g_menu_item_get_attribute (item, "target", "(bs)", &b, &s)); + g_assert (b); + g_assert_cmpstr (s, ==, "string"); + g_free (s); + + g_object_unref (item); + + item = g_menu_item_new_from_model (G_MENU_MODEL (menu), 0); + assert_menuitem_equal (item, G_MENU_MODEL (menu), 0); + g_object_unref (item); + + g_object_unref (menu); + g_object_unref (submenu); +} + +/* Epilogue {{{1 */ +int +main (int argc, char **argv) +{ + gboolean ret; + + g_test_init (&argc, &argv, NULL); + + session_bus_up (); + + g_test_add_func ("/gmenu/equality", test_equality); + g_test_add_func ("/gmenu/random", test_random); + g_test_add_func ("/gmenu/dbus/roundtrip", test_dbus_roundtrip); + g_test_add_func ("/gmenu/dbus/subscriptions", test_dbus_subscriptions); + g_test_add_func ("/gmenu/dbus/threaded", test_dbus_threaded); + g_test_add_func ("/gmenu/dbus/peer/roundtrip", test_dbus_peer_roundtrip); + g_test_add_func ("/gmenu/dbus/peer/subscriptions", test_dbus_peer_subscriptions); + g_test_add_func ("/gmenu/attributes", test_attributes); + g_test_add_func ("/gmenu/attributes/iterate", test_attribute_iter); + g_test_add_func ("/gmenu/links", test_links); + g_test_add_func ("/gmenu/mutable", test_mutable); + g_test_add_func ("/gmenu/convenience", test_convenience); + g_test_add_func ("/gmenu/menuitem", test_menuitem); + + ret = g_test_run (); + + session_bus_down (); + + return ret; +} +/* vim:set foldmethod=marker: */ diff --git a/gio/tests/gnotification-server.c b/gio/tests/gnotification-server.c new file mode 100644 index 0000000..c98cbf0 --- /dev/null +++ b/gio/tests/gnotification-server.c @@ -0,0 +1,337 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#include "gnotification-server.h" + +#include + +typedef GObjectClass GNotificationServerClass; + +struct _GNotificationServer +{ + GObject parent; + + GDBusConnection *connection; + guint name_owner_id; + guint object_id; + + guint is_running; + + /* app_ids -> hashtables of notification ids -> a{sv} */ + GHashTable *applications; +}; + +G_DEFINE_TYPE (GNotificationServer, g_notification_server, G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_IS_RUNNING +}; + +static GDBusInterfaceInfo * +org_gtk_Notifications_get_interface (void) +{ + static GDBusInterfaceInfo *iface_info; + + if (iface_info == NULL) + { + GDBusNodeInfo *info; + GError *error = NULL; + + info = g_dbus_node_info_new_for_xml ( + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "", &error); + + if (info == NULL) + g_error ("%s", error->message); + + iface_info = g_dbus_node_info_lookup_interface (info, "org.gtk.Notifications"); + g_assert (iface_info); + + g_dbus_interface_info_ref (iface_info); + g_dbus_node_info_unref (info); + } + + return iface_info; +} + +static void +g_notification_server_notification_added (GNotificationServer *server, + const gchar *app_id, + const gchar *notification_id, + GVariant *notification) +{ + GHashTable *notifications; + + notifications = g_hash_table_lookup (server->applications, app_id); + if (notifications == NULL) + { + notifications = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_variant_unref); + g_hash_table_insert (server->applications, g_strdup (app_id), notifications); + } + + g_hash_table_replace (notifications, g_strdup (notification_id), g_variant_ref (notification)); + + g_signal_emit_by_name (server, "notification-received", app_id, notification_id, notification); +} + +static void +g_notification_server_notification_removed (GNotificationServer *server, + const gchar *app_id, + const gchar *notification_id) +{ + GHashTable *notifications; + + notifications = g_hash_table_lookup (server->applications, app_id); + if (notifications) + { + g_hash_table_remove (notifications, notification_id); + if (g_hash_table_size (notifications) == 0) + g_hash_table_remove (server->applications, app_id); + } + + g_signal_emit_by_name (server, "notification-removed", app_id, notification_id); +} + +static void +org_gtk_Notifications_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GNotificationServer *server = user_data; + + if (g_str_equal (method_name, "AddNotification")) + { + const gchar *app_id; + const gchar *notification_id; + GVariant *notification; + + g_variant_get (parameters, "(&s&s@a{sv})", &app_id, ¬ification_id, ¬ification); + g_notification_server_notification_added (server, app_id, notification_id, notification); + g_dbus_method_invocation_return_value (invocation, NULL); + + g_variant_unref (notification); + } + else if (g_str_equal (method_name, "RemoveNotification")) + { + const gchar *app_id; + const gchar *notification_id; + + g_variant_get (parameters, "(&s&s)", &app_id, ¬ification_id); + g_notification_server_notification_removed (server, app_id, notification_id); + g_dbus_method_invocation_return_value (invocation, NULL); + } + else + { + g_dbus_method_invocation_return_dbus_error (invocation, "UnknownMethod", "No such method"); + } +} + +static void +g_notification_server_dispose (GObject *object) +{ + GNotificationServer *server = G_NOTIFICATION_SERVER (object); + + g_notification_server_stop (server); + + g_clear_pointer (&server->applications, g_hash_table_unref); + g_clear_object (&server->connection); + + G_OBJECT_CLASS (g_notification_server_parent_class)->dispose (object); +} + +static void +g_notification_server_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GNotificationServer *server = G_NOTIFICATION_SERVER (object); + + switch (property_id) + { + case PROP_IS_RUNNING: + g_value_set_boolean (value, server->is_running); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +g_notification_server_class_init (GNotificationServerClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->get_property = g_notification_server_get_property; + object_class->dispose = g_notification_server_dispose; + + g_object_class_install_property (object_class, PROP_IS_RUNNING, + g_param_spec_boolean ("is-running", "", "", FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_signal_new ("notification-received", G_TYPE_NOTIFICATION_SERVER, G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 3, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_VARIANT); + + g_signal_new ("notification-removed", G_TYPE_NOTIFICATION_SERVER, G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, + G_TYPE_STRING, G_TYPE_STRING); +} + +static void +g_notification_server_bus_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + const GDBusInterfaceVTable vtable = { + org_gtk_Notifications_method_call, NULL, NULL, { 0 } + }; + GNotificationServer *server = user_data; + + server->object_id = g_dbus_connection_register_object (connection, "/org/gtk/Notifications", + org_gtk_Notifications_get_interface (), + &vtable, server, NULL, NULL); + + /* register_object only fails if the same object is exported more than once */ + g_assert (server->object_id > 0); + + server->connection = g_object_ref (connection); +} + +static void +g_notification_server_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GNotificationServer *server = user_data; + + server->is_running = TRUE; + g_object_notify (G_OBJECT (server), "is-running"); +} + +static void +g_notification_server_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GNotificationServer *server = user_data; + + g_notification_server_stop (server); + + if (connection == NULL && server->connection) + g_clear_object (&server->connection); +} + +static void +g_notification_server_init (GNotificationServer *server) +{ + server->applications = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_hash_table_unref); + + server->name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gtk.Notifications", + G_BUS_NAME_OWNER_FLAGS_NONE, + g_notification_server_bus_acquired, + g_notification_server_name_acquired, + g_notification_server_name_lost, + server, NULL); +} + +GNotificationServer * +g_notification_server_new (void) +{ + return g_object_new (G_TYPE_NOTIFICATION_SERVER, NULL); +} + +void +g_notification_server_stop (GNotificationServer *server) +{ + g_return_if_fail (G_IS_NOTIFICATION_SERVER (server)); + + if (server->name_owner_id) + { + g_bus_unown_name (server->name_owner_id); + server->name_owner_id = 0; + } + + if (server->object_id && server->connection) + { + g_dbus_connection_unregister_object (server->connection, server->object_id); + server->object_id = 0; + } + + if (server->is_running) + { + server->is_running = FALSE; + g_object_notify (G_OBJECT (server), "is-running"); + } +} + +gboolean +g_notification_server_get_is_running (GNotificationServer *server) +{ + g_return_val_if_fail (G_IS_NOTIFICATION_SERVER (server), FALSE); + + return server->is_running; +} + +gchar ** +g_notification_server_list_applications (GNotificationServer *server) +{ + g_return_val_if_fail (G_IS_NOTIFICATION_SERVER (server), NULL); + + return (gchar **) g_hash_table_get_keys_as_array (server->applications, NULL); +} + +gchar ** +g_notification_server_list_notifications (GNotificationServer *server, + const gchar *app_id) +{ + GHashTable *notifications; + + g_return_val_if_fail (G_IS_NOTIFICATION_SERVER (server), NULL); + g_return_val_if_fail (app_id != NULL, NULL); + + notifications = g_hash_table_lookup (server->applications, app_id); + + if (notifications == NULL) + return NULL; + + return (gchar **) g_hash_table_get_keys_as_array (notifications, NULL); +} diff --git a/gio/tests/gnotification-server.h b/gio/tests/gnotification-server.h new file mode 100644 index 0000000..d7b69cc --- /dev/null +++ b/gio/tests/gnotification-server.h @@ -0,0 +1,44 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#ifndef __G_NOTIFICATION_SERVER_H__ +#define __G_NOTIFICATION_SERVER_H__ + +#include + +#define G_TYPE_NOTIFICATION_SERVER (g_notification_server_get_type ()) +#define G_NOTIFICATION_SERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NOTIFICATION_SERVER, GNotificationServer)) +#define G_IS_NOTIFICATION_SERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NOTIFICATION_SERVER)) + +typedef struct _GNotificationServer GNotificationServer; + +GType g_notification_server_get_type (void); + +GNotificationServer * g_notification_server_new (void); + +void g_notification_server_stop (GNotificationServer *server); + +gboolean g_notification_server_get_is_running (GNotificationServer *server); + +gchar ** g_notification_server_list_applications (GNotificationServer *server); + +gchar ** g_notification_server_list_notifications (GNotificationServer *server, + const gchar *app_id); + +#endif diff --git a/gio/tests/gnotification.c b/gio/tests/gnotification.c new file mode 100644 index 0000000..853983c --- /dev/null +++ b/gio/tests/gnotification.c @@ -0,0 +1,250 @@ +/* + * Copyright © 2013 Lars Uebernickel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Lars Uebernickel + */ + +#include + +#include "gnotification-server.h" +#include "gdbus-sessionbus.h" + +static void +activate_app (GApplication *application, + gpointer user_data) +{ + GNotification *notification; + GIcon *icon; + + notification = g_notification_new ("Test"); + + g_application_send_notification (application, "test1", notification); + g_application_send_notification (application, "test2", notification); + g_application_withdraw_notification (application, "test1"); + g_application_send_notification (application, "test3", notification); + + icon = g_themed_icon_new ("i-c-o-n"); + g_notification_set_icon (notification, icon); + g_object_unref (icon); + + g_notification_set_body (notification, "body"); + g_notification_set_priority (notification, G_NOTIFICATION_PRIORITY_URGENT); + g_notification_set_default_action_and_target (notification, "app.action", "i", 42); + g_notification_add_button_with_target (notification, "label", "app.action2", "s", "bla"); + + g_application_send_notification (application, "test4", notification); + g_application_send_notification (application, NULL, notification); + + g_dbus_connection_flush_sync (g_application_get_dbus_connection (application), NULL, NULL); + + g_object_unref (notification); +} + +static void +notification_received (GNotificationServer *server, + const gchar *app_id, + const gchar *notification_id, + GVariant *notification, + gpointer user_data) +{ + gint *count = user_data; + const gchar *title; + + g_assert_cmpstr (app_id, ==, "org.gtk.TestApplication"); + + switch (*count) + { + case 0: + g_assert_cmpstr (notification_id, ==, "test1"); + g_assert (g_variant_lookup (notification, "title", "&s", &title)); + g_assert_cmpstr (title, ==, "Test"); + break; + + case 1: + g_assert_cmpstr (notification_id, ==, "test2"); + break; + + case 2: + g_assert_cmpstr (notification_id, ==, "test3"); + break; + + case 3: + g_assert_cmpstr (notification_id, ==, "test4"); + break; + + case 4: + g_assert (g_dbus_is_guid (notification_id)); + + g_notification_server_stop (server); + break; + } + + (*count)++; +} + +static void +notification_removed (GNotificationServer *server, + const gchar *app_id, + const gchar *notification_id, + gpointer user_data) +{ + gint *count = user_data; + + g_assert_cmpstr (app_id, ==, "org.gtk.TestApplication"); + g_assert_cmpstr (notification_id, ==, "test1"); + + (*count)++; +} + +static void +server_notify_is_running (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + GMainLoop *loop = user_data; + GNotificationServer *server = G_NOTIFICATION_SERVER (object); + + if (g_notification_server_get_is_running (server)) + { + GApplication *app; + + app = g_application_new ("org.gtk.TestApplication", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (activate_app), NULL); + + g_application_run (app, 0, NULL); + + g_object_unref (app); + } + else + { + g_main_loop_quit (loop); + } +} + +static gboolean +timeout (gpointer user_data) +{ + GNotificationServer *server = user_data; + + g_notification_server_stop (server); + + return G_SOURCE_REMOVE; +} + +static void +basic (void) +{ + GNotificationServer *server; + GMainLoop *loop; + gint received_count = 0; + gint removed_count = 0; + + session_bus_up (); + + loop = g_main_loop_new (NULL, FALSE); + + server = g_notification_server_new (); + g_signal_connect (server, "notification-received", G_CALLBACK (notification_received), &received_count); + g_signal_connect (server, "notification-removed", G_CALLBACK (notification_removed), &removed_count); + g_signal_connect (server, "notify::is-running", G_CALLBACK (server_notify_is_running), loop); + g_timeout_add_seconds (1, timeout, server); + + g_main_loop_run (loop); + + g_assert_cmpint (received_count, ==, 5); + g_assert_cmpint (removed_count, ==, 1); + + g_object_unref (server); + g_main_loop_unref (loop); + session_bus_stop (); +} + +struct _GNotification +{ + GObject parent; + + gchar *title; + gchar *body; + GIcon *icon; + GNotificationPriority priority; + gchar *category; + GPtrArray *buttons; + gchar *default_action; + GVariant *default_action_target; +}; + +typedef struct +{ + gchar *label; + gchar *action_name; + GVariant *target; +} Button; + +static void +test_properties (void) +{ + GNotification *n; + struct _GNotification *rn; + GIcon *icon; + const gchar * const *names; + Button *b; + + n = g_notification_new ("Test"); + + g_notification_set_title (n, "title"); + g_notification_set_body (n, "body"); + g_notification_set_category (n, "cate.gory"); + icon = g_themed_icon_new ("i-c-o-n"); + g_notification_set_icon (n, icon); + g_object_unref (icon); + g_notification_set_priority (n, G_NOTIFICATION_PRIORITY_HIGH); + g_notification_set_category (n, "cate.gory"); + g_notification_add_button (n, "label1", "app.action1::target1"); + g_notification_set_default_action (n, "app.action2::target2"); + + rn = (struct _GNotification *)n; + + g_assert_cmpstr (rn->title, ==, "title"); + g_assert_cmpstr (rn->body, ==, "body"); + g_assert (G_IS_THEMED_ICON (rn->icon)); + names = g_themed_icon_get_names (G_THEMED_ICON (rn->icon)); + g_assert_cmpstr (names[0], ==, "i-c-o-n"); + g_assert_cmpstr (names[1], ==, "i-c-o-n-symbolic"); + g_assert_null (names[2]); + g_assert (rn->priority == G_NOTIFICATION_PRIORITY_HIGH); + g_assert_cmpstr (rn->category, ==, "cate.gory"); + + g_assert_cmpint (rn->buttons->len, ==, 1); + b = (Button*)rn->buttons->pdata[0]; + g_assert_cmpstr (b->label, ==, "label1"); + g_assert_cmpstr (b->action_name, ==, "app.action1"); + g_assert_cmpstr (g_variant_get_string (b->target, NULL), ==, "target1"); + + g_assert_cmpstr (rn->default_action, ==, "app.action2"); + g_assert_cmpstr (g_variant_get_string (rn->default_action_target, NULL), ==, "target2"); + + g_object_unref (n); +} + +int main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gnotification/basic", basic); + g_test_add_func ("/gnotification/properties", test_properties); + + return g_test_run (); +} diff --git a/gio/tests/gschema-compile.c b/gio/tests/gschema-compile.c new file mode 100644 index 0000000..8dc4985 --- /dev/null +++ b/gio/tests/gschema-compile.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include + +typedef struct { + const gchar *name; + const gchar *opt; + const gchar *err; +} SchemaTest; + +static void +test_schema_do_compile (gpointer data) +{ + SchemaTest *test = (SchemaTest *) data; + gchar *filename = g_strconcat (test->name, ".gschema.xml", NULL); + gchar *path = g_test_build_filename (G_TEST_DIST, "schema-tests", filename, NULL); + const gchar *argv[] = { + GLIB_COMPILE_SCHEMAS, /* defined in meson.build */ + "--strict", + "--dry-run", + "--schema-file", path, + test->opt, + NULL + }; + gchar *envp[] = { NULL }; + + execve (argv[0], (char **) argv, envp); + g_assert_not_reached (); +} + +static void +test_schema (gpointer data) +{ + SchemaTest *test = (SchemaTest *) data; + gchar *child_name; + + child_name = g_strdup_printf ("/gschema/%s%s/subprocess/do_compile", test->name, test->opt ? "/opt" : ""); + g_test_trap_subprocess (child_name, 0, 0); + g_free (child_name); + + if (test->err) + { + g_test_trap_assert_failed (); + g_test_trap_assert_stderr_unmatched ("*CRITICAL*"); + g_test_trap_assert_stderr_unmatched ("*WARNING*"); + g_test_trap_assert_stderr (test->err); + } + else + g_test_trap_assert_passed(); +} + +static const SchemaTest tests[] = { + { "no-default", NULL, "* is required in *" }, + { "missing-quotes", NULL, "*unknown keyword*" }, + { "incomplete-list", NULL, "*to follow array element*" }, + { "wrong-category", NULL, "*unsupported l10n category*" }, + { "bad-type", NULL, "*Invalid GVariant type string*" }, + { "overflow", NULL, "*out of range*" }, + { "range-wrong-type", NULL, "* not allowed for keys of type*" }, + { "range-missing-min", NULL, NULL }, + { "range-missing-max", NULL, NULL }, + { "default-out-of-range", NULL, "* is not contained in the specified range*" }, + { "choices-wrong-type", NULL, "* not allowed for keys of type*" }, + { "choice-missing-value", NULL, "*element 'choice' requires attribute 'value'*" }, + { "default-not-in-choices", NULL, "* contains a string not in *" }, + { "array-default-not-in-choices", NULL, "* contains a string not in *" }, + { "bad-key", NULL, "*Invalid name*" }, + { "invalid-path", NULL, "*must begin and end with a slash*" }, + { "bad-key", "--allow-any-name", NULL }, + { "bad-key2", NULL, "*Invalid name*" }, + { "bad-key2", "--allow-any-name", NULL }, + { "bad-key3", NULL, "*Invalid name*" }, + { "bad-key3", "--allow-any-name", NULL }, + { "bad-key4", NULL, "*Invalid name*" }, + { "bad-key4", "--allow-any-name", NULL }, + { "empty-key", NULL, "*Empty names*" }, + { "empty-key", "--allow-any-name", "*Empty names*" }, + { "enum", NULL, NULL }, + { "enum-with-aliases", NULL, NULL }, + { "enum-with-invalid-alias", NULL, "*“banger†is not in enumerated type*" }, + { "enum-with-invalid-value", NULL, "*Invalid numeric value*" }, + { "enum-with-repeated-alias", NULL, "* already specified*" }, + { "enum-with-repeated-nick", NULL, "* already specified*" }, + { "enum-with-repeated-value", NULL, "*value='1' already specified*" }, + { "enum-with-chained-alias", NULL, "*“sausages†is not in enumerated type*" }, + { "enum-with-shadow-alias", NULL, "*“mash†is already a member of the enum*" }, + { "enum-with-choice", NULL, "* cannot be specified*" }, + { "enum-with-bad-default", NULL, "* is not a valid member*" }, + { "choice", NULL, NULL }, + { "choice-upside-down", NULL, NULL }, + { "bad-choice", NULL, "* contains a string not in *" }, + { "choice-bad", NULL, "* contains a string not in *" }, + { "choice-badtype", NULL, "* not allowed for keys of type “iâ€*" }, + { "bare-alias", NULL, "*enumerated or flags types or after *" }, + { "choice-alias", NULL, NULL }, + { "default-in-aliases", NULL, "* contains a string not in *" }, + { "choice-invalid-alias", NULL, "*“befor†is not in *" }, + { "choice-shadowed-alias", NULL, "*given when was already*" }, + { "range", NULL, NULL }, + { "range-badtype", NULL, "* not allowed for keys of type “sâ€*" }, + { "range-low-default", NULL, "* is not contained in the specified range*" }, + { "range-high-default", NULL, "* is not contained in the specified range*" }, + { "range-default-low", NULL, "* is not contained in the specified range*" }, + { "range-default-high", NULL, "* is not contained in the specified range*" }, + { "range-parse-error", NULL, "*invalid character in number*" }, + { "from-docs", NULL, NULL }, + { "extending", NULL, NULL }, + { "extend-missing", NULL, "*extends not yet existing schema*" }, + { "extend-nonlist", NULL, "*which is not a list*" }, + { "extend-self", NULL, "*not yet existing*" }, + { "extend-wrong-list-indirect", NULL, "*“y†does not extend “xâ€*" }, + { "extend-wrong-list", NULL, "*“y†does not extend “xâ€*" }, + { "key-in-list-indirect", NULL, "*Cannot add keys to a “list*" }, + { "key-in-list", NULL, "*Cannot add keys to a “list*" }, + { "list-of-missing", NULL, "*is list of not yet existing schema*" }, + { "extend-and-shadow", NULL, "*shadows*use *" }, + { "extend-and-shadow-indirect", NULL, "*shadows*use *" }, + { "override", NULL, NULL }, + { "override-missing", NULL, "*No to override*" }, + { "override-range-error", NULL, "* is not contained in the specified range*"}, + { "override-then-key", NULL, "*shadows in *" }, + { "override-twice", NULL, "* already specified*" }, + { "override-type-error", NULL, "*invalid character in number*" }, + { "flags-aliased-default", NULL, "* * not in the specified flags type*" }, + { "flags-bad-default", NULL, "* * not in the specified flags type*" }, + { "flags-more-than-one-bit", NULL, "*flags values must have at most 1 bit set*" }, + { "flags-with-enum-attr", NULL, "* not (yet) defined*" }, + { "flags-with-enum-tag", NULL, "* not (yet) defined*" }, + { "summary-xmllang", NULL, "*Only one element allowed*" }, + { "description-xmllang", NULL, "*Only one element allowed*" }, + { "summary-xmllang-and-attrs", NULL, "*attribute 'lang' invalid for element 'summary'*" }, + { "inherit-gettext-domain", NULL, NULL }, + { "range-type-test", NULL, NULL }, + { "cdata", NULL, NULL } +}; + + +int +main (int argc, char *argv[]) +{ + guint i; + + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS (tests); ++i) + { + gchar *name; + + name = g_strdup_printf ("/gschema/%s%s", tests[i].name, tests[i].opt ? "/opt" : ""); + g_test_add_data_func (name, &tests[i], (gpointer) test_schema); + g_free (name); + + name = g_strdup_printf ("/gschema/%s%s/subprocess/do_compile", tests[i].name, tests[i].opt ? "/opt" : ""); + g_test_add_data_func (name, &tests[i], (gpointer) test_schema_do_compile); + g_free (name); + } + + return g_test_run (); +} diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c new file mode 100644 index 0000000..35d958e --- /dev/null +++ b/gio/tests/gsettings.c @@ -0,0 +1,3157 @@ +#include +#include +#include +#include +#include +#include +#include +#define G_SETTINGS_ENABLE_BACKEND +#include + +#include "testenum.h" + +static const gchar *locale_dir = "."; + +static gboolean backend_set; + +/* These tests rely on the schemas in org.gtk.test.gschema.xml + * to be compiled and installed in the same directory. + */ + +typedef struct +{ + gchar *tmp_dir; +} Fixture; + +static void +setup (Fixture *fixture, + gconstpointer user_data) +{ + GError *error = NULL; + + fixture->tmp_dir = g_dir_make_tmp ("gio-test-gsettings_XXXXXX", &error); + g_assert_no_error (error); + + g_test_message ("Using temporary directory: %s", fixture->tmp_dir); +} + +static void +teardown (Fixture *fixture, + gconstpointer user_data) +{ + g_assert_no_errno (g_rmdir (fixture->tmp_dir)); + g_clear_pointer (&fixture->tmp_dir, g_free); +} + +static void +check_and_free (GVariant *value, + const gchar *expected) +{ + gchar *printed; + + printed = g_variant_print (value, TRUE); + g_assert_cmpstr (printed, ==, expected); + g_free (printed); + + g_variant_unref (value); +} + +/* Wrapper around g_assert_cmpstr() which gets a setting from a #GSettings + * using g_settings_get(). */ +#define settings_assert_cmpstr(settings, key, op, expected_value) G_STMT_START { \ + gchar *__str; \ + g_settings_get ((settings), (key), "s", &__str); \ + g_assert_cmpstr (__str, op, (expected_value)); \ + g_free (__str); \ +} G_STMT_END + + +/* Just to get warmed up: Read and set a string, and + * verify that can read the changed string back + */ +static void +test_basic (void) +{ + gchar *str = NULL; + GObject *b; + gchar *path; + gboolean has_unapplied; + gboolean delay_apply; + GSettings *settings; + + settings = g_settings_new ("org.gtk.test"); + + g_object_get (settings, + "schema-id", &str, + "backend", &b, + "path", &path, + "has-unapplied", &has_unapplied, + "delay-apply", &delay_apply, + NULL); + g_assert_cmpstr (str, ==, "org.gtk.test"); + g_assert_nonnull (b); + g_assert_cmpstr (path, ==, "/tests/"); + g_assert_false (has_unapplied); + g_assert_false (delay_apply); + g_free (str); + g_object_unref (b); + g_free (path); + + settings_assert_cmpstr (settings, "greeting", ==, "Hello, earthlings"); + + g_settings_set (settings, "greeting", "s", "goodbye world"); + settings_assert_cmpstr (settings, "greeting", ==, "goodbye world"); + + if (!backend_set && g_test_undefined ()) + { + GSettings *tmp_settings = g_settings_new ("org.gtk.test"); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*g_settings_set_value*expects type*"); + g_settings_set (tmp_settings, "greeting", "i", 555); + g_test_assert_expected_messages (); + + g_object_unref (tmp_settings); + } + + settings_assert_cmpstr (settings, "greeting", ==, "goodbye world"); + + g_settings_reset (settings, "greeting"); + str = g_settings_get_string (settings, "greeting"); + g_assert_cmpstr (str, ==, "Hello, earthlings"); + g_free (str); + + g_settings_set (settings, "greeting", "s", "this is the end"); + g_object_unref (settings); +} + +/* Check that we get an error when getting a key + * that is not in the schema + */ +static void +test_unknown_key (void) +{ + if (!g_test_undefined ()) + return; + + if (g_test_subprocess ()) + { + GSettings *settings; + GVariant *value; + + settings = g_settings_new ("org.gtk.test"); + value = g_settings_get_value (settings, "no_such_key"); + + g_assert_null (value); + + g_object_unref (settings); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*does not contain*"); +} + +/* Check that we get an error when the schema + * has not been installed + */ +static void +test_no_schema (void) +{ + if (!g_test_undefined ()) + return; + + if (g_test_subprocess ()) + { + GSettings *settings; + + settings = g_settings_new ("no.such.schema"); + + g_assert_null (settings); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Settings schema 'no.such.schema' is not installed*"); +} + +/* Check that we get an error when passing a type string + * that does not match the schema + */ +static void +test_wrong_type (void) +{ + GSettings *settings; + gchar *str = NULL; + + if (!g_test_undefined ()) + return; + + settings = g_settings_new ("org.gtk.test"); + + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, + "*given value has a type of*"); + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, + "*valid_format_string*"); + g_settings_get (settings, "greeting", "o", &str); + g_test_assert_expected_messages (); + + g_assert_null (str); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*expects type 's'*"); + g_settings_set (settings, "greeting", "o", "/a/path"); + g_test_assert_expected_messages (); + + g_object_unref (settings); +} + +/* Check errors with explicit paths */ +static void +test_wrong_path (void) +{ + if (!g_test_undefined ()) + return; + + if (g_test_subprocess ()) + { + GSettings *settings G_GNUC_UNUSED; + + settings = g_settings_new_with_path ("org.gtk.test", "/wrong-path/"); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*but path * specified by schema*"); +} + +static void +test_no_path (void) +{ + if (!g_test_undefined ()) + return; + + if (g_test_subprocess ()) + { + GSettings *settings G_GNUC_UNUSED; + + settings = g_settings_new ("org.gtk.test.no-path"); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*attempting to create schema * without a path**"); +} + + +/* Check that we can successfully read and set the full + * range of all basic types + */ +static void +test_basic_types (void) +{ + GSettings *settings; + gboolean b; + guint8 byte; + gint16 i16; + guint16 u16; + gint32 i32; + guint32 u32; + gint64 i64; + guint64 u64; + gdouble d; + gchar *str; + + settings = g_settings_new ("org.gtk.test.basic-types"); + + g_settings_get (settings, "test-boolean", "b", &b); + g_assert_cmpint (b, ==, 1); + + g_settings_set (settings, "test-boolean", "b", 0); + g_settings_get (settings, "test-boolean", "b", &b); + g_assert_cmpint (b, ==, 0); + + g_settings_get (settings, "test-byte", "y", &byte); + g_assert_cmpint (byte, ==, 25); + + g_settings_set (settings, "test-byte", "y", G_MAXUINT8); + g_settings_get (settings, "test-byte", "y", &byte); + g_assert_cmpint (byte, ==, G_MAXUINT8); + + g_settings_get (settings, "test-int16", "n", &i16); + g_assert_cmpint (i16, ==, -1234); + + g_settings_set (settings, "test-int16", "n", G_MININT16); + g_settings_get (settings, "test-int16", "n", &i16); + g_assert_cmpint (i16, ==, G_MININT16); + + g_settings_set (settings, "test-int16", "n", G_MAXINT16); + g_settings_get (settings, "test-int16", "n", &i16); + g_assert_cmpint (i16, ==, G_MAXINT16); + + g_settings_get (settings, "test-uint16", "q", &u16); + g_assert_cmpuint (u16, ==, 1234); + + g_settings_set (settings, "test-uint16", "q", G_MAXUINT16); + g_settings_get (settings, "test-uint16", "q", &u16); + g_assert_cmpuint (u16, ==, G_MAXUINT16); + + g_settings_get (settings, "test-int32", "i", &i32); + g_assert_cmpint (i32, ==, -123456); + + g_settings_set (settings, "test-int32", "i", G_MININT32); + g_settings_get (settings, "test-int32", "i", &i32); + g_assert_cmpint (i32, ==, G_MININT32); + + g_settings_set (settings, "test-int32", "i", G_MAXINT32); + g_settings_get (settings, "test-int32", "i", &i32); + g_assert_cmpint (i32, ==, G_MAXINT32); + + g_settings_get (settings, "test-uint32", "u", &u32); + g_assert_cmpuint (u32, ==, 123456); + + g_settings_set (settings, "test-uint32", "u", G_MAXUINT32); + g_settings_get (settings, "test-uint32", "u", &u32); + g_assert_cmpuint (u32, ==, G_MAXUINT32); + + g_settings_get (settings, "test-int64", "x", &i64); + g_assert_cmpuint (i64, ==, -123456789); + + g_settings_set (settings, "test-int64", "x", G_MININT64); + g_settings_get (settings, "test-int64", "x", &i64); + g_assert_cmpuint (i64, ==, G_MININT64); + + g_settings_set (settings, "test-int64", "x", G_MAXINT64); + g_settings_get (settings, "test-int64", "x", &i64); + g_assert_cmpuint (i64, ==, G_MAXINT64); + + g_settings_get (settings, "test-uint64", "t", &u64); + g_assert_cmpuint (u64, ==, 123456789); + + g_settings_set (settings, "test-uint64", "t", G_MAXUINT64); + g_settings_get (settings, "test-uint64", "t", &u64); + g_assert_cmpuint (u64, ==, G_MAXUINT64); + + g_settings_get (settings, "test-double", "d", &d); + g_assert_cmpfloat (d, ==, 123.456); + + g_settings_set (settings, "test-double", "d", G_MINDOUBLE); + g_settings_get (settings, "test-double", "d", &d); + g_assert_cmpfloat (d, ==, G_MINDOUBLE); + + g_settings_set (settings, "test-double", "d", G_MAXDOUBLE); + g_settings_get (settings, "test-double", "d", &d); + g_assert_cmpfloat (d, ==, G_MAXDOUBLE); + + settings_assert_cmpstr (settings, "test-string", ==, "a string, it seems"); + + g_settings_get (settings, "test-objectpath", "o", &str); + g_assert_cmpstr (str, ==, "/a/object/path"); + g_object_unref (settings); + g_free (str); + str = NULL; +} + +/* Check that we can read an set complex types like + * tuples, arrays and dictionaries + */ +static void +test_complex_types (void) +{ + GSettings *settings; + gchar *s; + gint i1, i2; + GVariantIter *iter = NULL; + GVariant *v = NULL; + + settings = g_settings_new ("org.gtk.test.complex-types"); + + g_settings_get (settings, "test-tuple", "(s(ii))", &s, &i1, &i2); + g_assert_cmpstr (s, ==, "one"); + g_assert_cmpint (i1,==, 2); + g_assert_cmpint (i2,==, 3); + g_free (s) ; + s = NULL; + + g_settings_set (settings, "test-tuple", "(s(ii))", "none", 0, 0); + g_settings_get (settings, "test-tuple", "(s(ii))", &s, &i1, &i2); + g_assert_cmpstr (s, ==, "none"); + g_assert_cmpint (i1,==, 0); + g_assert_cmpint (i2,==, 0); + g_free (s); + s = NULL; + + g_settings_get (settings, "test-array", "ai", &iter); + g_assert_cmpint (g_variant_iter_n_children (iter), ==, 6); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); + g_assert_cmpint (i1, ==, 0); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); + g_assert_cmpint (i1, ==, 1); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); + g_assert_cmpint (i1, ==, 2); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); + g_assert_cmpint (i1, ==, 3); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); + g_assert_cmpint (i1, ==, 4); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); + g_assert_cmpint (i1, ==, 5); + g_assert_false (g_variant_iter_next (iter, "i", &i1)); + g_variant_iter_free (iter); + + g_settings_get (settings, "test-dict", "a{sau}", &iter); + g_assert_cmpint (g_variant_iter_n_children (iter), ==, 2); + g_assert_true (g_variant_iter_next (iter, "{&s@au}", &s, &v)); + g_assert_cmpstr (s, ==, "AC"); + g_assert_cmpstr ((char *)g_variant_get_type (v), ==, "au"); + g_variant_unref (v); + g_assert_true (g_variant_iter_next (iter, "{&s@au}", &s, &v)); + g_assert_cmpstr (s, ==, "IV"); + g_assert_cmpstr ((char *)g_variant_get_type (v), ==, "au"); + g_variant_unref (v); + g_variant_iter_free (iter); + + v = g_settings_get_value (settings, "test-dict"); + g_assert_cmpstr ((char *)g_variant_get_type (v), ==, "a{sau}"); + g_variant_unref (v); + + g_object_unref (settings); +} + +static gboolean changed_cb_called; + +static void +changed_cb (GSettings *settings, + const gchar *key, + gpointer data) +{ + changed_cb_called = TRUE; + + g_assert_cmpstr (key, ==, data); +} + +/* Test that basic change notification with the changed signal works. + */ +static void +test_changes (void) +{ + GSettings *settings; + GSettings *settings2; + + settings = g_settings_new ("org.gtk.test"); + + g_signal_connect (settings, "changed", + G_CALLBACK (changed_cb), "greeting"); + + changed_cb_called = FALSE; + + g_settings_set (settings, "greeting", "s", "new greeting"); + g_assert_true (changed_cb_called); + + settings2 = g_settings_new ("org.gtk.test"); + + changed_cb_called = FALSE; + + g_settings_set (settings2, "greeting", "s", "hi"); + g_assert_true (changed_cb_called); + + g_object_unref (settings2); + g_object_unref (settings); +} + +static gboolean changed_cb_called2; + +static void +changed_cb2 (GSettings *settings, + const gchar *key, + gpointer data) +{ + gboolean *p = data; + + *p = TRUE; +} + +/* Test that changes done to a delay-mode instance + * don't appear to the outside world until apply. Also + * check that we get change notification when they are + * applied. + * Also test that the has-unapplied property is properly + * maintained. + */ +static void +test_delay_apply (void) +{ + GSettings *settings; + GSettings *settings2; + gboolean writable; + GVariant *v; + const gchar *s; + + settings = g_settings_new ("org.gtk.test"); + settings2 = g_settings_new ("org.gtk.test"); + + g_settings_set (settings2, "greeting", "s", "top o' the morning"); + + changed_cb_called = FALSE; + changed_cb_called2 = FALSE; + + g_signal_connect (settings, "changed", + G_CALLBACK (changed_cb2), &changed_cb_called); + g_signal_connect (settings2, "changed", + G_CALLBACK (changed_cb2), &changed_cb_called2); + + g_settings_delay (settings); + + g_settings_set (settings, "greeting", "s", "greetings from test_delay_apply"); + + g_assert_true (changed_cb_called); + g_assert_false (changed_cb_called2); + + /* Try resetting the key and ensure a notification is emitted on the delayed #GSettings object. */ + changed_cb_called = FALSE; + changed_cb_called2 = FALSE; + + g_settings_reset (settings, "greeting"); + + g_assert_true (changed_cb_called); + g_assert_false (changed_cb_called2); + + /* Locally change the greeting again. */ + changed_cb_called = FALSE; + changed_cb_called2 = FALSE; + + g_settings_set (settings, "greeting", "s", "greetings from test_delay_apply"); + + g_assert_true (changed_cb_called); + g_assert_false (changed_cb_called2); + + writable = g_settings_is_writable (settings, "greeting"); + g_assert_true (writable); + + settings_assert_cmpstr (settings, "greeting", ==, "greetings from test_delay_apply"); + + v = g_settings_get_user_value (settings, "greeting"); + s = g_variant_get_string (v, NULL); + g_assert_cmpstr (s, ==, "greetings from test_delay_apply"); + g_variant_unref (v); + + settings_assert_cmpstr (settings2, "greeting", ==, "top o' the morning"); + + g_assert_true (g_settings_get_has_unapplied (settings)); + g_assert_false (g_settings_get_has_unapplied (settings2)); + + changed_cb_called = FALSE; + changed_cb_called2 = FALSE; + + g_settings_apply (settings); + + g_assert_false (changed_cb_called); + g_assert_true (changed_cb_called2); + + settings_assert_cmpstr (settings, "greeting", ==, "greetings from test_delay_apply"); + settings_assert_cmpstr (settings2, "greeting", ==, "greetings from test_delay_apply"); + + g_assert_false (g_settings_get_has_unapplied (settings)); + g_assert_false (g_settings_get_has_unapplied (settings2)); + + g_settings_reset (settings, "greeting"); + g_settings_apply (settings); + + settings_assert_cmpstr (settings, "greeting", ==, "Hello, earthlings"); + + g_object_unref (settings2); + g_object_unref (settings); +} + +/* Test that reverting unapplied changes in a delay-apply + * settings instance works. + */ +static void +test_delay_revert (void) +{ + GSettings *settings; + GSettings *settings2; + + settings = g_settings_new ("org.gtk.test"); + settings2 = g_settings_new ("org.gtk.test"); + + g_settings_set (settings2, "greeting", "s", "top o' the morning"); + + settings_assert_cmpstr (settings, "greeting", ==, "top o' the morning"); + + g_settings_delay (settings); + + g_settings_set (settings, "greeting", "s", "greetings from test_delay_revert"); + + settings_assert_cmpstr (settings, "greeting", ==, "greetings from test_delay_revert"); + settings_assert_cmpstr (settings2, "greeting", ==, "top o' the morning"); + + g_assert_true (g_settings_get_has_unapplied (settings)); + + g_settings_revert (settings); + + g_assert_false (g_settings_get_has_unapplied (settings)); + + settings_assert_cmpstr (settings, "greeting", ==, "top o' the morning"); + settings_assert_cmpstr (settings2, "greeting", ==, "top o' the morning"); + + g_object_unref (settings2); + g_object_unref (settings); +} + +static void +test_delay_child (void) +{ + GSettings *base; + GSettings *settings; + GSettings *child; + guint8 byte; + gboolean delay; + + base = g_settings_new ("org.gtk.test.basic-types"); + g_settings_set (base, "test-byte", "y", 36); + + settings = g_settings_new ("org.gtk.test"); + g_settings_delay (settings); + g_object_get (settings, "delay-apply", &delay, NULL); + g_assert_true (delay); + + child = g_settings_get_child (settings, "basic-types"); + g_assert_nonnull (child); + + g_object_get (child, "delay-apply", &delay, NULL); + g_assert_true (delay); + + g_settings_get (child, "test-byte", "y", &byte); + g_assert_cmpuint (byte, ==, 36); + + g_settings_set (child, "test-byte", "y", 42); + + /* make sure the child was delayed too */ + g_settings_get (base, "test-byte", "y", &byte); + g_assert_cmpuint (byte, ==, 36); + + /* apply the child and the changes should be saved */ + g_settings_apply (child); + g_settings_get (base, "test-byte", "y", &byte); + g_assert_cmpuint (byte, ==, 42); + + g_object_unref (child); + g_object_unref (settings); + g_object_unref (base); +} + +static void +test_delay_reset_key (void) +{ + GSettings *direct_settings = NULL, *delayed_settings = NULL; + + g_test_summary ("Test that resetting a key on a delayed settings instance works"); + + delayed_settings = g_settings_new ("org.gtk.test"); + direct_settings = g_settings_new ("org.gtk.test"); + + g_settings_set (direct_settings, "greeting", "s", "ey up"); + + settings_assert_cmpstr (delayed_settings, "greeting", ==, "ey up"); + + /* Set up a delayed settings backend. */ + g_settings_delay (delayed_settings); + + g_settings_set (delayed_settings, "greeting", "s", "how do"); + + settings_assert_cmpstr (delayed_settings, "greeting", ==, "how do"); + settings_assert_cmpstr (direct_settings, "greeting", ==, "ey up"); + + g_assert_true (g_settings_get_has_unapplied (delayed_settings)); + + g_settings_reset (delayed_settings, "greeting"); + + /* There are still unapplied settings, because the reset is resetting to the + * value from the schema, not the value from @direct_settings. */ + g_assert_true (g_settings_get_has_unapplied (delayed_settings)); + + settings_assert_cmpstr (delayed_settings, "greeting", ==, "Hello, earthlings"); + settings_assert_cmpstr (direct_settings, "greeting", ==, "ey up"); + + /* Apply the settings changes (i.e. the reset). */ + g_settings_apply (delayed_settings); + + g_assert_false (g_settings_get_has_unapplied (delayed_settings)); + + settings_assert_cmpstr (delayed_settings, "greeting", ==, "Hello, earthlings"); + settings_assert_cmpstr (direct_settings, "greeting", ==, "Hello, earthlings"); + + g_object_unref (direct_settings); + g_object_unref (delayed_settings); +} + +static void +keys_changed_cb (GSettings *settings, + const GQuark *keys, + gint n_keys) +{ + g_assert_cmpint (n_keys, ==, 2); + + g_assert_true ((keys[0] == g_quark_from_static_string ("greeting") && + keys[1] == g_quark_from_static_string ("farewell")) || + (keys[1] == g_quark_from_static_string ("greeting") && + keys[0] == g_quark_from_static_string ("farewell"))); + + settings_assert_cmpstr (settings, "greeting", ==, "greetings from test_atomic"); + settings_assert_cmpstr (settings, "farewell", ==, "atomic bye-bye"); +} + +/* Check that delay-applied changes appear atomically. + * More specifically, verify that all changed keys appear + * with their new value while handling the change-event signal. + */ +static void +test_atomic (void) +{ + GSettings *settings; + GSettings *settings2; + + settings = g_settings_new ("org.gtk.test"); + settings2 = g_settings_new ("org.gtk.test"); + + g_settings_set (settings2, "greeting", "s", "top o' the morning"); + + changed_cb_called = FALSE; + changed_cb_called2 = FALSE; + + g_signal_connect (settings2, "change-event", + G_CALLBACK (keys_changed_cb), NULL); + + g_settings_delay (settings); + + g_settings_set (settings, "greeting", "s", "greetings from test_atomic"); + g_settings_set (settings, "farewell", "s", "atomic bye-bye"); + + g_settings_apply (settings); + + settings_assert_cmpstr (settings, "greeting", ==, "greetings from test_atomic"); + settings_assert_cmpstr (settings, "farewell", ==, "atomic bye-bye"); + settings_assert_cmpstr (settings2, "greeting", ==, "greetings from test_atomic"); + settings_assert_cmpstr (settings2, "farewell", ==, "atomic bye-bye"); + + g_object_unref (settings2); + g_object_unref (settings); +} + +/* On Windows the interaction between the C library locale and libintl + * (from GNU gettext) is not like on POSIX, so just skip these tests + * for now. + * + * There are several issues: + * + * 1) The C library doesn't use LC_MESSAGES, that is implemented only + * in libintl (defined in its ). + * + * 2) The locale names that setlocale() accepts and returns aren't in + * the "de_DE" style, but like "German_Germany". + * + * 3) libintl looks at the Win32 thread locale and not the C library + * locale. (And even if libintl would use the C library's locale, as + * there are several alternative C library DLLs, libintl might be + * linked to a different one than the application code, so they + * wouldn't have the same C library locale anyway.) + */ + +/* Test that translations work for schema defaults. + * + * This test relies on the de.po file in the same directory + * to be compiled into ./de/LC_MESSAGES/test.mo + */ +static void +test_l10n (void) +{ + GSettings *settings; + gchar *str; + gchar *locale; + + bindtextdomain ("test", locale_dir); + bind_textdomain_codeset ("test", "UTF-8"); + + locale = g_strdup (setlocale (LC_MESSAGES, NULL)); + + settings = g_settings_new ("org.gtk.test.localized"); + + g_setenv ("LC_MESSAGES", "C", TRUE); + setlocale (LC_MESSAGES, "C"); + str = g_settings_get_string (settings, "error-message"); + g_setenv ("LC_MESSAGES", locale, TRUE); + setlocale (LC_MESSAGES, locale); + + g_assert_cmpstr (str, ==, "Unnamed"); + g_free (str); + str = NULL; + + g_setenv ("LC_MESSAGES", "de_DE.UTF-8", TRUE); + setlocale (LC_MESSAGES, "de_DE.UTF-8"); + /* Only do the test if translation is actually working... */ + if (g_str_equal (dgettext ("test", "\"Unnamed\""), "\"Unbenannt\"")) + { + str = g_settings_get_string (settings, "error-message"); + + g_assert_cmpstr (str, ==, "Unbenannt"); + g_free (str); + str = NULL; + } + else + g_printerr ("warning: translation is not working... skipping test. "); + + g_setenv ("LC_MESSAGES", locale, TRUE); + setlocale (LC_MESSAGES, locale); + g_free (locale); + g_object_unref (settings); +} + +/* Test that message context works as expected with translated + * schema defaults. Also, verify that non-ASCII UTF-8 content + * works. + * + * This test relies on the de.po file in the same directory + * to be compiled into ./de/LC_MESSAGES/test.mo + */ +static void +test_l10n_context (void) +{ + GSettings *settings; + gchar *str; + gchar *locale; + + bindtextdomain ("test", locale_dir); + bind_textdomain_codeset ("test", "UTF-8"); + + locale = g_strdup (setlocale (LC_MESSAGES, NULL)); + + settings = g_settings_new ("org.gtk.test.localized"); + + g_setenv ("LC_MESSAGES", "C", TRUE); + setlocale (LC_MESSAGES, "C"); + g_settings_get (settings, "backspace", "s", &str); + g_setenv ("LC_MESSAGES", locale, TRUE); + setlocale (LC_MESSAGES, locale); + + g_assert_cmpstr (str, ==, "BackSpace"); + g_free (str); + str = NULL; + + g_setenv ("LC_MESSAGES", "de_DE.UTF-8", TRUE); + setlocale (LC_MESSAGES, "de_DE.UTF-8"); + /* Only do the test if translation is actually working... */ + if (g_str_equal (dgettext ("test", "\"Unnamed\""), "\"Unbenannt\"")) + settings_assert_cmpstr (settings, "backspace", ==, "Löschen"); + else + g_printerr ("warning: translation is not working... skipping test. "); + + g_setenv ("LC_MESSAGES", locale, TRUE); + setlocale (LC_MESSAGES, locale); + g_free (locale); + g_object_unref (settings); +} + +enum +{ + PROP_0, + PROP_BOOL, + PROP_ANTI_BOOL, + PROP_BYTE, + PROP_INT16, + PROP_UINT16, + PROP_INT, + PROP_UINT, + PROP_INT64, + PROP_UINT64, + PROP_DOUBLE, + PROP_STRING, + PROP_NO_READ, + PROP_NO_WRITE, + PROP_STRV, + PROP_ENUM, + PROP_FLAGS +}; + +typedef struct +{ + GObject parent_instance; + + gboolean bool_prop; + gboolean anti_bool_prop; + gint8 byte_prop; + gint int16_prop; + guint16 uint16_prop; + gint int_prop; + guint uint_prop; + gint64 int64_prop; + guint64 uint64_prop; + gdouble double_prop; + gchar *string_prop; + gchar *no_read_prop; + gchar *no_write_prop; + gchar **strv_prop; + guint enum_prop; + guint flags_prop; +} TestObject; + +typedef struct +{ + GObjectClass parent_class; +} TestObjectClass; + +static GType test_object_get_type (void); +G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT) + +static void +test_object_init (TestObject *object) +{ +} + +static void +test_object_finalize (GObject *object) +{ + TestObject *testo = (TestObject*)object; + g_strfreev (testo->strv_prop); + g_free (testo->string_prop); + G_OBJECT_CLASS (test_object_parent_class)->finalize (object); +} + +static void +test_object_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + TestObject *test_object = (TestObject *)object; + + switch (prop_id) + { + case PROP_BOOL: + g_value_set_boolean (value, test_object->bool_prop); + break; + case PROP_ANTI_BOOL: + g_value_set_boolean (value, test_object->anti_bool_prop); + break; + case PROP_BYTE: + g_value_set_schar (value, test_object->byte_prop); + break; + case PROP_UINT16: + g_value_set_uint (value, test_object->uint16_prop); + break; + case PROP_INT16: + g_value_set_int (value, test_object->int16_prop); + break; + case PROP_INT: + g_value_set_int (value, test_object->int_prop); + break; + case PROP_UINT: + g_value_set_uint (value, test_object->uint_prop); + break; + case PROP_INT64: + g_value_set_int64 (value, test_object->int64_prop); + break; + case PROP_UINT64: + g_value_set_uint64 (value, test_object->uint64_prop); + break; + case PROP_DOUBLE: + g_value_set_double (value, test_object->double_prop); + break; + case PROP_STRING: + g_value_set_string (value, test_object->string_prop); + break; + case PROP_NO_WRITE: + g_value_set_string (value, test_object->no_write_prop); + break; + case PROP_STRV: + g_value_set_boxed (value, test_object->strv_prop); + break; + case PROP_ENUM: + g_value_set_enum (value, test_object->enum_prop); + break; + case PROP_FLAGS: + g_value_set_flags (value, test_object->flags_prop); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +test_object_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + TestObject *test_object = (TestObject *)object; + + switch (prop_id) + { + case PROP_BOOL: + test_object->bool_prop = g_value_get_boolean (value); + break; + case PROP_ANTI_BOOL: + test_object->anti_bool_prop = g_value_get_boolean (value); + break; + case PROP_BYTE: + test_object->byte_prop = g_value_get_schar (value); + break; + case PROP_INT16: + test_object->int16_prop = g_value_get_int (value); + break; + case PROP_UINT16: + test_object->uint16_prop = g_value_get_uint (value); + break; + case PROP_INT: + test_object->int_prop = g_value_get_int (value); + break; + case PROP_UINT: + test_object->uint_prop = g_value_get_uint (value); + break; + case PROP_INT64: + test_object->int64_prop = g_value_get_int64 (value); + break; + case PROP_UINT64: + test_object->uint64_prop = g_value_get_uint64 (value); + break; + case PROP_DOUBLE: + test_object->double_prop = g_value_get_double (value); + break; + case PROP_STRING: + g_free (test_object->string_prop); + test_object->string_prop = g_value_dup_string (value); + break; + case PROP_NO_READ: + g_free (test_object->no_read_prop); + test_object->no_read_prop = g_value_dup_string (value); + break; + case PROP_STRV: + g_strfreev (test_object->strv_prop); + test_object->strv_prop = g_value_dup_boxed (value); + break; + case PROP_ENUM: + test_object->enum_prop = g_value_get_enum (value); + break; + case PROP_FLAGS: + test_object->flags_prop = g_value_get_flags (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GType +test_enum_get_type (void) +{ + static gsize define_type_id = 0; + + if (g_once_init_enter (&define_type_id)) + { + static const GEnumValue values[] = { + { TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" }, + { TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" }, + { TEST_ENUM_BAZ, "TEST_ENUM_BAZ", "baz" }, + { TEST_ENUM_QUUX, "TEST_ENUM_QUUX", "quux" }, + { 0, NULL, NULL } + }; + + GType type_id = g_enum_register_static ("TestEnum", values); + g_once_init_leave (&define_type_id, type_id); + } + + return define_type_id; +} + +static GType +test_flags_get_type (void) +{ + static gsize define_type_id = 0; + + if (g_once_init_enter (&define_type_id)) + { + static const GFlagsValue values[] = { + { TEST_FLAGS_NONE, "TEST_FLAGS_NONE", "none" }, + { TEST_FLAGS_MOURNING, "TEST_FLAGS_MOURNING", "mourning" }, + { TEST_FLAGS_LAUGHING, "TEST_FLAGS_LAUGHING", "laughing" }, + { TEST_FLAGS_WALKING, "TEST_FLAGS_WALKING", "walking" }, + { 0, NULL, NULL } + }; + + GType type_id = g_flags_register_static ("TestFlags", values); + g_once_init_leave (&define_type_id, type_id); + } + + return define_type_id; +} + +static void +test_object_class_init (TestObjectClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + gobject_class->get_property = test_object_get_property; + gobject_class->set_property = test_object_set_property; + gobject_class->finalize = test_object_finalize; + + g_object_class_install_property (gobject_class, PROP_BOOL, + g_param_spec_boolean ("bool", "", "", FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_ANTI_BOOL, + g_param_spec_boolean ("anti-bool", "", "", FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_BYTE, + g_param_spec_char ("byte", "", "", G_MININT8, G_MAXINT8, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_INT16, + g_param_spec_int ("int16", "", "", -G_MAXINT16, G_MAXINT16, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_UINT16, + g_param_spec_uint ("uint16", "", "", 0, G_MAXUINT16, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_INT, + g_param_spec_int ("int", "", "", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_UINT, + g_param_spec_uint ("uint", "", "", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_INT64, + g_param_spec_int64 ("int64", "", "", G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_UINT64, + g_param_spec_uint64 ("uint64", "", "", 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_DOUBLE, + g_param_spec_double ("double", "", "", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_STRING, + g_param_spec_string ("string", "", "", NULL, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_NO_WRITE, + g_param_spec_string ("no-write", "", "", NULL, G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, PROP_NO_READ, + g_param_spec_string ("no-read", "", "", NULL, G_PARAM_WRITABLE)); + g_object_class_install_property (gobject_class, PROP_STRV, + g_param_spec_boxed ("strv", "", "", G_TYPE_STRV, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_ENUM, + g_param_spec_enum ("enum", "", "", test_enum_get_type (), TEST_ENUM_FOO, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_FLAGS, + g_param_spec_flags ("flags", "", "", test_flags_get_type (), TEST_FLAGS_NONE, G_PARAM_READWRITE)); +} + +static TestObject * +test_object_new (void) +{ + return (TestObject*)g_object_new (test_object_get_type (), NULL); +} + +/* Test basic binding functionality for simple types. + * Verify that with bidirectional bindings, changes on either side + * are notified on the other end. + */ +static void +test_simple_binding (void) +{ + TestObject *obj; + GSettings *settings; + gboolean b; + gchar y; + gint i; + guint u; + gint16 n; + guint16 q; + gint n2; + guint q2; + gint64 i64; + guint64 u64; + gdouble d; + gchar *s; + GVariant *value; + gchar **strv; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_DEFAULT); + g_object_set (obj, "bool", TRUE, NULL); + g_assert_cmpint (g_settings_get_boolean (settings, "bool"), ==, TRUE); + + g_settings_set_boolean (settings, "bool", FALSE); + b = TRUE; + g_object_get (obj, "bool", &b, NULL); + g_assert_cmpint (b, ==, FALSE); + + g_settings_bind (settings, "anti-bool", obj, "anti-bool", + G_SETTINGS_BIND_INVERT_BOOLEAN); + g_object_set (obj, "anti-bool", FALSE, NULL); + g_assert_cmpint (g_settings_get_boolean (settings, "anti-bool"), ==, TRUE); + + g_settings_set_boolean (settings, "anti-bool", FALSE); + b = FALSE; + g_object_get (obj, "anti-bool", &b, NULL); + g_assert_cmpint (b, ==, TRUE); + + g_settings_bind (settings, "byte", obj, "byte", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "byte", 123, NULL); + y = 'c'; + g_settings_get (settings, "byte", "y", &y); + g_assert_cmpint (y, ==, 123); + + g_settings_set (settings, "byte", "y", 54); + y = 'c'; + g_object_get (obj, "byte", &y, NULL); + g_assert_cmpint (y, ==, 54); + + g_settings_bind (settings, "int16", obj, "int16", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "int16", 1234, NULL); + n = 4321; + g_settings_get (settings, "int16", "n", &n); + g_assert_cmpint (n, ==, 1234); + + g_settings_set (settings, "int16", "n", 4321); + n2 = 1111; + g_object_get (obj, "int16", &n2, NULL); + g_assert_cmpint (n2, ==, 4321); + + g_settings_bind (settings, "uint16", obj, "uint16", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "uint16", (guint16) G_MAXUINT16, NULL); + q = 1111; + g_settings_get (settings, "uint16", "q", &q); + g_assert_cmpuint (q, ==, G_MAXUINT16); + + g_settings_set (settings, "uint16", "q", (guint16) G_MAXINT16); + q2 = 1111; + g_object_get (obj, "uint16", &q2, NULL); + g_assert_cmpuint (q2, ==, (guint16) G_MAXINT16); + + g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "int", 12345, NULL); + g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 12345); + + g_settings_set_int (settings, "int", 54321); + i = 1111; + g_object_get (obj, "int", &i, NULL); + g_assert_cmpint (i, ==, 54321); + + g_settings_bind (settings, "uint", obj, "uint", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "uint", 12345, NULL); + g_assert_cmpuint (g_settings_get_uint (settings, "uint"), ==, 12345); + + g_settings_set_uint (settings, "uint", 54321); + u = 1111; + g_object_get (obj, "uint", &u, NULL); + g_assert_cmpuint (u, ==, 54321); + + g_settings_bind (settings, "uint64", obj, "uint64", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "uint64", (guint64) 12345, NULL); + g_assert_cmpuint (g_settings_get_uint64 (settings, "uint64"), ==, 12345); + + g_settings_set_uint64 (settings, "uint64", 54321); + u64 = 1111; + g_object_get (obj, "uint64", &u64, NULL); + g_assert_cmpuint (u64, ==, 54321); + + g_settings_bind (settings, "int64", obj, "int64", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "int64", (gint64) G_MAXINT64, NULL); + i64 = 1111; + g_settings_get (settings, "int64", "x", &i64); + g_assert_cmpint (i64, ==, G_MAXINT64); + + g_settings_set (settings, "int64", "x", (gint64) G_MININT64); + i64 = 1111; + g_object_get (obj, "int64", &i64, NULL); + g_assert_cmpint (i64, ==, G_MININT64); + + g_settings_bind (settings, "uint64", obj, "uint64", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "uint64", (guint64) G_MAXUINT64, NULL); + u64 = 1111; + g_settings_get (settings, "uint64", "t", &u64); + g_assert_cmpuint (u64, ==, G_MAXUINT64); + + g_settings_set (settings, "uint64", "t", (guint64) G_MAXINT64); + u64 = 1111; + g_object_get (obj, "uint64", &u64, NULL); + g_assert_cmpuint (u64, ==, (guint64) G_MAXINT64); + + g_settings_bind (settings, "string", obj, "string", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "string", "bu ba", NULL); + s = g_settings_get_string (settings, "string"); + g_assert_cmpstr (s, ==, "bu ba"); + g_free (s); + + g_settings_set_string (settings, "string", "bla bla"); + g_object_get (obj, "string", &s, NULL); + g_assert_cmpstr (s, ==, "bla bla"); + g_free (s); + + g_settings_bind (settings, "chararray", obj, "string", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "string", "non-unicode:\315", NULL); + value = g_settings_get_value (settings, "chararray"); + g_assert_cmpstr (g_variant_get_bytestring (value), ==, "non-unicode:\315"); + g_variant_unref (value); + + g_settings_bind (settings, "double", obj, "double", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "double", G_MAXFLOAT, NULL); + g_assert_cmpfloat (g_settings_get_double (settings, "double"), ==, G_MAXFLOAT); + + g_settings_set_double (settings, "double", G_MINFLOAT); + d = 1.0; + g_object_get (obj, "double", &d, NULL); + g_assert_cmpfloat (d, ==, G_MINFLOAT); + + g_object_set (obj, "double", G_MAXDOUBLE, NULL); + g_assert_cmpfloat (g_settings_get_double (settings, "double"), ==, G_MAXDOUBLE); + + g_settings_set_double (settings, "double", -G_MINDOUBLE); + d = 1.0; + g_object_get (obj, "double", &d, NULL); + g_assert_cmpfloat (d, ==, -G_MINDOUBLE); + + strv = g_strsplit ("plastic bag,middle class,polyethylene", ",", 0); + g_settings_bind (settings, "strv", obj, "strv", G_SETTINGS_BIND_DEFAULT); + g_object_set (obj, "strv", strv, NULL); + g_strfreev (strv); + strv = g_settings_get_strv (settings, "strv"); + s = g_strjoinv (",", strv); + g_assert_cmpstr (s, ==, "plastic bag,middle class,polyethylene"); + g_strfreev (strv); + g_free (s); + strv = g_strsplit ("decaffeinate,unleaded,keep all surfaces clean", ",", 0); + g_settings_set_strv (settings, "strv", (const gchar **) strv); + g_strfreev (strv); + g_object_get (obj, "strv", &strv, NULL); + s = g_strjoinv (",", strv); + g_assert_cmpstr (s, ==, "decaffeinate,unleaded,keep all surfaces clean"); + g_strfreev (strv); + g_free (s); + g_settings_set_strv (settings, "strv", NULL); + g_object_get (obj, "strv", &strv, NULL); + g_assert_nonnull (strv); + g_assert_cmpint (g_strv_length (strv), ==, 0); + g_strfreev (strv); + + g_settings_bind (settings, "enum", obj, "enum", G_SETTINGS_BIND_DEFAULT); + g_object_set (obj, "enum", TEST_ENUM_BAZ, NULL); + s = g_settings_get_string (settings, "enum"); + g_assert_cmpstr (s, ==, "baz"); + g_free (s); + g_assert_cmpint (g_settings_get_enum (settings, "enum"), ==, TEST_ENUM_BAZ); + + g_settings_set_enum (settings, "enum", TEST_ENUM_QUUX); + i = 230; + g_object_get (obj, "enum", &i, NULL); + g_assert_cmpint (i, ==, TEST_ENUM_QUUX); + + g_settings_set_string (settings, "enum", "baz"); + i = 230; + g_object_get (obj, "enum", &i, NULL); + g_assert_cmpint (i, ==, TEST_ENUM_BAZ); + + g_settings_bind (settings, "flags", obj, "flags", G_SETTINGS_BIND_DEFAULT); + g_object_set (obj, "flags", TEST_FLAGS_MOURNING, NULL); + strv = g_settings_get_strv (settings, "flags"); + g_assert_cmpint (g_strv_length (strv), ==, 1); + g_assert_cmpstr (strv[0], ==, "mourning"); + g_strfreev (strv); + + g_assert_cmpint (g_settings_get_flags (settings, "flags"), ==, TEST_FLAGS_MOURNING); + + g_settings_set_flags (settings, "flags", TEST_FLAGS_MOURNING | TEST_FLAGS_WALKING); + i = 230; + g_object_get (obj, "flags", &i, NULL); + g_assert_cmpint (i, ==, TEST_FLAGS_MOURNING | TEST_FLAGS_WALKING); + + g_settings_bind (settings, "uint", obj, "uint", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "uint", 12345, NULL); + g_assert_cmpuint (g_settings_get_uint (settings, "uint"), ==, 12345); + + g_settings_set_uint (settings, "uint", 54321); + u = 1111; + g_object_get (obj, "uint", &u, NULL); + g_assert_cmpuint (u, ==, 54321); + + g_settings_bind (settings, "range", obj, "uint", G_SETTINGS_BIND_DEFAULT); + g_object_set (obj, "uint", 22, NULL); + u = 1111; + g_assert_cmpuint (g_settings_get_uint (settings, "range"), ==, 22); + g_object_get (obj, "uint", &u, NULL); + g_assert_cmpuint (u, ==, 22); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "* is out of schema-specified range for*"); + g_object_set (obj, "uint", 45, NULL); + g_test_assert_expected_messages (); + u = 1111; + g_object_get (obj, "uint", &u, NULL); + g_assert_cmpuint (g_settings_get_uint (settings, "range"), ==, 22); + /* The value of the object is currently not reset back to its initial value + g_assert_cmpuint (u, ==, 22); */ + + g_object_unref (obj); + g_object_unref (settings); +} + +static void +test_unbind (void) +{ + TestObject *obj; + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_DEFAULT); + + g_object_set (obj, "int", 12345, NULL); + g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 12345); + + g_settings_unbind (obj, "int"); + + g_object_set (obj, "int", 54321, NULL); + g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 12345); + + g_object_unref (obj); + g_object_unref (settings); +} + +static void +test_bind_writable (void) +{ + TestObject *obj; + GSettings *settings; + gboolean b; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_object_set (obj, "bool", FALSE, NULL); + + g_settings_bind_writable (settings, "int", obj, "bool", FALSE); + + g_object_get (obj, "bool", &b, NULL); + g_assert_true (b); + + g_settings_unbind (obj, "bool"); + + g_settings_bind_writable (settings, "int", obj, "bool", TRUE); + + g_object_get (obj, "bool", &b, NULL); + g_assert_false (b); + + g_object_unref (obj); + g_object_unref (settings); +} + +/* Test one-way bindings. + * Verify that changes on one side show up on the other, + * but not vice versa + */ +static void +test_directional_binding (void) +{ + TestObject *obj; + GSettings *settings; + gboolean b; + gint i; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_object_set (obj, "bool", FALSE, NULL); + g_settings_set_boolean (settings, "bool", FALSE); + + g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_GET); + + g_settings_set_boolean (settings, "bool", TRUE); + g_object_get (obj, "bool", &b, NULL); + g_assert_cmpint (b, ==, TRUE); + + g_object_set (obj, "bool", FALSE, NULL); + g_assert_cmpint (g_settings_get_boolean (settings, "bool"), ==, TRUE); + + g_object_set (obj, "int", 20, NULL); + g_settings_set_int (settings, "int", 20); + + g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_SET); + + g_object_set (obj, "int", 32, NULL); + g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 32); + + g_settings_set_int (settings, "int", 20); + g_object_get (obj, "int", &i, NULL); + g_assert_cmpint (i, ==, 32); + + g_object_unref (obj); + g_object_unref (settings); +} + +/* Test that type mismatch is caught when creating a binding */ +static void +test_typesafe_binding (void) +{ + if (!g_test_undefined ()) + return; + + if (g_test_subprocess ()) + { + TestObject *obj; + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_settings_bind (settings, "string", obj, "int", G_SETTINGS_BIND_DEFAULT); + + g_object_unref (obj); + g_object_unref (settings); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not compatible*"); +} + +static gboolean +string_to_bool (GValue *value, + GVariant *variant, + gpointer user_data) +{ + const gchar *s; + + s = g_variant_get_string (variant, NULL); + g_value_set_boolean (value, g_strcmp0 (s, "true") == 0); + + return TRUE; +} + +static GVariant * +bool_to_string (const GValue *value, + const GVariantType *expected_type, + gpointer user_data) +{ + if (g_value_get_boolean (value)) + return g_variant_new_string ("true"); + else + return g_variant_new_string ("false"); +} + +static GVariant * +bool_to_bool (const GValue *value, + const GVariantType *expected_type, + gpointer user_data) +{ + return g_variant_new_boolean (g_value_get_boolean (value)); +} + +/* Test custom bindings. + * Translate strings to booleans and back + */ +static void +test_custom_binding (void) +{ + TestObject *obj; + GSettings *settings; + gchar *s; + gboolean b; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_settings_set_string (settings, "string", "true"); + + g_settings_bind_with_mapping (settings, "string", + obj, "bool", + G_SETTINGS_BIND_DEFAULT, + string_to_bool, + bool_to_string, + NULL, NULL); + + g_settings_set_string (settings, "string", "false"); + g_object_get (obj, "bool", &b, NULL); + g_assert_cmpint (b, ==, FALSE); + + g_settings_set_string (settings, "string", "not true"); + g_object_get (obj, "bool", &b, NULL); + g_assert_cmpint (b, ==, FALSE); + + g_object_set (obj, "bool", TRUE, NULL); + s = g_settings_get_string (settings, "string"); + g_assert_cmpstr (s, ==, "true"); + g_free (s); + + g_settings_bind_with_mapping (settings, "string", + obj, "bool", + G_SETTINGS_BIND_DEFAULT, + string_to_bool, bool_to_bool, + NULL, NULL); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*binding mapping function for key 'string' returned" + " GVariant of type 'b' when type 's' was requested*"); + g_object_set (obj, "bool", FALSE, NULL); + g_test_assert_expected_messages (); + + g_object_unref (obj); + g_object_unref (settings); +} + +/* Test that with G_SETTINGS_BIND_NO_CHANGES, the + * initial settings value is transported to the object + * side, but later settings changes do not affect the + * object + */ +static void +test_no_change_binding (void) +{ + TestObject *obj; + GSettings *settings; + gboolean b; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_object_set (obj, "bool", TRUE, NULL); + g_settings_set_boolean (settings, "bool", FALSE); + + g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_GET_NO_CHANGES); + + g_object_get (obj, "bool", &b, NULL); + g_assert_cmpint (b, ==, FALSE); + + g_settings_set_boolean (settings, "bool", TRUE); + g_object_get (obj, "bool", &b, NULL); + g_assert_cmpint (b, ==, FALSE); + + g_settings_set_boolean (settings, "bool", FALSE); + g_object_set (obj, "bool", TRUE, NULL); + b = g_settings_get_boolean (settings, "bool"); + g_assert_cmpint (b, ==, TRUE); + + g_object_unref (obj); + g_object_unref (settings); +} + +/* Test that binding a non-readable property only + * works in 'GET' mode. + */ +static void +test_no_read_binding_fail (void) +{ + TestObject *obj; + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_settings_bind (settings, "string", obj, "no-read", 0); +} + +static void +test_no_read_binding_pass (void) +{ + TestObject *obj; + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_settings_bind (settings, "string", obj, "no-read", G_SETTINGS_BIND_GET); + + exit (0); +} + +static void +test_no_read_binding (void) +{ + if (g_test_undefined ()) + { + g_test_trap_subprocess ("/gsettings/no-read-binding/subprocess/fail", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*property*is not readable*"); + } + + g_test_trap_subprocess ("/gsettings/no-read-binding/subprocess/pass", 0, 0); + g_test_trap_assert_passed (); +} + +/* Test that binding a non-writable property only + * works in 'SET' mode. + */ +static void +test_no_write_binding_fail (void) +{ + TestObject *obj; + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_settings_bind (settings, "string", obj, "no-write", 0); +} + +static void +test_no_write_binding_pass (void) +{ + TestObject *obj; + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.binding"); + obj = test_object_new (); + + g_settings_bind (settings, "string", obj, "no-write", G_SETTINGS_BIND_SET); + + exit (0); +} + +static void +test_no_write_binding (void) +{ + if (g_test_undefined ()) + { + g_test_trap_subprocess ("/gsettings/no-write-binding/subprocess/fail", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*property*is not writable*"); + } + + g_test_trap_subprocess ("/gsettings/no-write-binding/subprocess/pass", 0, 0); + g_test_trap_assert_passed (); +} + +static void +key_changed_cb (GSettings *settings, const gchar *key, gpointer data) +{ + gboolean *b = data; + (*b) = TRUE; +} + +typedef struct +{ + const gchar *path; + const gchar *root_group; + const gchar *keyfile_group; + const gchar *root_path; +} KeyfileTestData; + +/* + * Test that using a keyfile works + */ +static void +test_keyfile (Fixture *fixture, + gconstpointer user_data) +{ + GSettingsBackend *kf_backend; + GSettings *settings; + GKeyFile *keyfile; + gchar *str; + gboolean writable; + GError *error = NULL; + gchar *data; + gsize len; + gboolean called = FALSE; + gchar *keyfile_path = NULL, *store_path = NULL; + + keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL); + store_path = g_build_filename (keyfile_path, "gsettings.store", NULL); + kf_backend = g_keyfile_settings_backend_new (store_path, "/", "root"); + settings = g_settings_new_with_backend ("org.gtk.test", kf_backend); + g_object_unref (kf_backend); + + g_settings_reset (settings, "greeting"); + str = g_settings_get_string (settings, "greeting"); + g_assert_cmpstr (str, ==, "Hello, earthlings"); + g_free (str); + + writable = g_settings_is_writable (settings, "greeting"); + g_assert_true (writable); + g_settings_set (settings, "greeting", "s", "see if this works"); + + str = g_settings_get_string (settings, "greeting"); + g_assert_cmpstr (str, ==, "see if this works"); + g_free (str); + + g_settings_delay (settings); + g_settings_set (settings, "farewell", "s", "cheerio"); + g_settings_apply (settings); + + keyfile = g_key_file_new (); + g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); + + str = g_key_file_get_string (keyfile, "tests", "greeting", NULL); + g_assert_cmpstr (str, ==, "'see if this works'"); + g_free (str); + + str = g_key_file_get_string (keyfile, "tests", "farewell", NULL); + g_assert_cmpstr (str, ==, "'cheerio'"); + g_free (str); + g_key_file_free (keyfile); + + g_settings_reset (settings, "greeting"); + g_settings_apply (settings); + keyfile = g_key_file_new (); + g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); + + str = g_key_file_get_string (keyfile, "tests", "greeting", NULL); + g_assert_null (str); + + called = FALSE; + g_signal_connect (settings, "changed::greeting", G_CALLBACK (key_changed_cb), &called); + + g_key_file_set_string (keyfile, "tests", "greeting", "'howdy'"); + data = g_key_file_to_data (keyfile, &len, NULL); + g_file_set_contents (store_path, data, len, &error); + g_assert_no_error (error); + while (!called) + g_main_context_iteration (NULL, FALSE); + g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); + + str = g_settings_get_string (settings, "greeting"); + g_assert_cmpstr (str, ==, "howdy"); + g_free (str); + + /* Now check setting a string without quotes */ + called = FALSE; + g_signal_connect (settings, "changed::greeting", G_CALLBACK (key_changed_cb), &called); + + g_key_file_set_string (keyfile, "tests", "greeting", "he\"l🤗uÅ„"); + g_free (data); + data = g_key_file_to_data (keyfile, &len, NULL); + g_file_set_contents (store_path, data, len, &error); + g_assert_no_error (error); + while (!called) + g_main_context_iteration (NULL, FALSE); + g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); + + str = g_settings_get_string (settings, "greeting"); + g_assert_cmpstr (str, ==, "he\"l🤗uÅ„"); + g_free (str); + + g_settings_set (settings, "farewell", "s", "cheerio"); + + /* Check that empty keys/groups are not allowed. */ + g_assert_false (g_settings_is_writable (settings, "")); + g_assert_false (g_settings_is_writable (settings, "/")); + + /* When executing as root, changing the mode of the keyfile will have + * no effect on the writability of the settings. + */ + if (geteuid () != 0) + { + called = FALSE; + g_signal_connect (settings, "writable-changed::greeting", + G_CALLBACK (key_changed_cb), &called); + + g_assert_no_errno (g_chmod (keyfile_path, 0500)); + while (!called) + g_main_context_iteration (NULL, FALSE); + g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); + + writable = g_settings_is_writable (settings, "greeting"); + g_assert_false (writable); + } + + g_key_file_free (keyfile); + g_free (data); + + g_object_unref (settings); + + /* Clean up the temporary directory. */ + g_assert_no_errno (g_chmod (keyfile_path, 0777)); + g_assert_no_errno (g_remove (store_path)); + g_assert_no_errno (g_rmdir (keyfile_path)); + g_free (store_path); + g_free (keyfile_path); +} + +/* + * Test that using a keyfile works with a schema with no path set. + */ +static void +test_keyfile_no_path (Fixture *fixture, + gconstpointer user_data) +{ + const KeyfileTestData *test_data = user_data; + GSettingsBackend *kf_backend; + GSettings *settings; + GKeyFile *keyfile; + gboolean writable; + gchar *key = NULL; + GError *error = NULL; + gchar *keyfile_path = NULL, *store_path = NULL; + + keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL); + store_path = g_build_filename (keyfile_path, "gsettings.store", NULL); + kf_backend = g_keyfile_settings_backend_new (store_path, test_data->root_path, test_data->root_group); + settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, test_data->path); + g_object_unref (kf_backend); + + g_settings_reset (settings, "test-boolean"); + g_assert_true (g_settings_get_boolean (settings, "test-boolean")); + + writable = g_settings_is_writable (settings, "test-boolean"); + g_assert_true (writable); + g_settings_set (settings, "test-boolean", "b", FALSE); + + g_assert_false (g_settings_get_boolean (settings, "test-boolean")); + + g_settings_delay (settings); + g_settings_set (settings, "test-boolean", "b", TRUE); + g_settings_apply (settings); + + keyfile = g_key_file_new (); + g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); + + g_assert_true (g_key_file_get_boolean (keyfile, test_data->keyfile_group, "test-boolean", NULL)); + + g_key_file_free (keyfile); + + g_settings_reset (settings, "test-boolean"); + g_settings_apply (settings); + keyfile = g_key_file_new (); + g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); + + g_assert_false (g_key_file_get_string (keyfile, test_data->keyfile_group, "test-boolean", &error)); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); + g_clear_error (&error); + + /* Check that empty keys/groups are not allowed. */ + g_assert_false (g_settings_is_writable (settings, "")); + g_assert_false (g_settings_is_writable (settings, "/")); + + /* Keys which ghost the root group name are not allowed. This can only be + * tested when the path is `/` as otherwise it acts as a prefix and prevents + * any ghosting. */ + if (g_str_equal (test_data->path, "/")) + { + key = g_strdup_printf ("%s/%s", test_data->root_group, ""); + g_assert_false (g_settings_is_writable (settings, key)); + g_free (key); + + key = g_strdup_printf ("%s/%s", test_data->root_group, "/"); + g_assert_false (g_settings_is_writable (settings, key)); + g_free (key); + + key = g_strdup_printf ("%s/%s", test_data->root_group, "test-boolean"); + g_assert_false (g_settings_is_writable (settings, key)); + g_free (key); + } + + g_key_file_free (keyfile); + g_object_unref (settings); + + /* Clean up the temporary directory. */ + g_assert_no_errno (g_chmod (keyfile_path, 0777)); + g_assert_no_errno (g_remove (store_path)); + g_assert_no_errno (g_rmdir (keyfile_path)); + g_free (store_path); + g_free (keyfile_path); +} + +/* + * Test that a keyfile rejects writes to keys outside its root path. + */ +static void +test_keyfile_outside_root_path (Fixture *fixture, + gconstpointer user_data) +{ + GSettingsBackend *kf_backend; + GSettings *settings; + gchar *keyfile_path = NULL, *store_path = NULL; + + keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL); + store_path = g_build_filename (keyfile_path, "gsettings.store", NULL); + kf_backend = g_keyfile_settings_backend_new (store_path, "/tests/basic-types/", "root"); + settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/tests/"); + g_object_unref (kf_backend); + + g_assert_false (g_settings_is_writable (settings, "test-boolean")); + + g_object_unref (settings); + + /* Clean up the temporary directory. The keyfile probably doesn’t exist, so + * don’t error on failure. */ + g_remove (store_path); + g_assert_no_errno (g_rmdir (keyfile_path)); + g_free (store_path); + g_free (keyfile_path); +} + +/* + * Test that a keyfile rejects writes to keys in the root if no root group is set. + */ +static void +test_keyfile_no_root_group (Fixture *fixture, + gconstpointer user_data) +{ + GSettingsBackend *kf_backend; + GSettings *settings; + gchar *keyfile_path = NULL, *store_path = NULL; + + keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL); + store_path = g_build_filename (keyfile_path, "gsettings.store", NULL); + kf_backend = g_keyfile_settings_backend_new (store_path, "/", NULL); + settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/"); + g_object_unref (kf_backend); + + g_assert_false (g_settings_is_writable (settings, "test-boolean")); + g_assert_true (g_settings_is_writable (settings, "child/test-boolean")); + + g_object_unref (settings); + + /* Clean up the temporary directory. The keyfile probably doesn’t exist, so + * don’t error on failure. */ + g_remove (store_path); + g_assert_no_errno (g_rmdir (keyfile_path)); + g_free (store_path); + g_free (keyfile_path); +} + +/* Test that getting child schemas works + */ +static void +test_child_schema (void) +{ + GSettings *settings; + GSettings *child; + guint8 byte; + + /* first establish some known conditions */ + settings = g_settings_new ("org.gtk.test.basic-types"); + g_settings_set (settings, "test-byte", "y", 36); + + g_settings_get (settings, "test-byte", "y", &byte); + g_assert_cmpint (byte, ==, 36); + + g_object_unref (settings); + + settings = g_settings_new ("org.gtk.test"); + child = g_settings_get_child (settings, "basic-types"); + g_assert_nonnull (child); + + g_settings_get (child, "test-byte", "y", &byte); + g_assert_cmpint (byte, ==, 36); + + g_object_unref (child); + g_object_unref (settings); +} + +#include "../strinfo.c" + +static void +test_strinfo (void) +{ + /* "foo" has a value of 1 + * "bar" has a value of 2 + * "baz" is an alias for "bar" + */ + gchar array[] = + "\1\0\0\0" "\xff""foo" "\0\0\0\xff" "\2\0\0\0" + "\xff" "bar" "\0\0\0\xff" "\3\0\0\0" "\xfe""baz" + "\0\0\0\xff"; + const guint32 *strinfo = (guint32 *) array; + guint length = sizeof array / 4; + guint result = 0; + + { + /* build it and compare */ + GString *builder; + + builder = g_string_new (NULL); + strinfo_builder_append_item (builder, "foo", 1); + strinfo_builder_append_item (builder, "bar", 2); + g_assert_true (strinfo_builder_append_alias (builder, "baz", "bar")); + g_assert_cmpmem (builder->str, builder->len, strinfo, length * 4); + g_string_free (builder, TRUE); + } + + g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "foo"), + ==, NULL); + g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "bar"), + ==, NULL); + g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "baz"), + ==, "bar"); + g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "quux"), + ==, NULL); + + g_assert_true (strinfo_enum_from_string (strinfo, length, "foo", &result)); + g_assert_cmpint (result, ==, 1); + g_assert_true (strinfo_enum_from_string (strinfo, length, "bar", &result)); + g_assert_cmpint (result, ==, 2); + g_assert_false (strinfo_enum_from_string (strinfo, length, "baz", &result)); + g_assert_false (strinfo_enum_from_string (strinfo, length, "quux", &result)); + + g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 0), ==, NULL); + g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 1), ==, "foo"); + g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 2), ==, "bar"); + g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 3), ==, NULL); + + g_assert_true (strinfo_is_string_valid (strinfo, length, "foo")); + g_assert_true (strinfo_is_string_valid (strinfo, length, "bar")); + g_assert_false (strinfo_is_string_valid (strinfo, length, "baz")); + g_assert_false (strinfo_is_string_valid (strinfo, length, "quux")); +} + +static void +test_enums_non_enum_key (void) +{ + GSettings *direct; + + direct = g_settings_new ("org.gtk.test.enums.direct"); + g_settings_get_enum (direct, "test"); + g_assert_not_reached (); +} + +static void +test_enums_non_enum_value (void) +{ + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.enums"); + g_settings_set_enum (settings, "test", 42); + g_assert_not_reached (); +} + +static void +test_enums_range (void) +{ + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.enums"); + g_settings_set_string (settings, "test", "qux"); + g_assert_not_reached (); +} + +static void +test_enums_non_flags (void) +{ + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.enums"); + g_settings_get_flags (settings, "test"); + g_assert_not_reached (); +} + +static void +test_enums (void) +{ + GSettings *settings, *direct; + gchar *str; + + settings = g_settings_new ("org.gtk.test.enums"); + direct = g_settings_new ("org.gtk.test.enums.direct"); + + if (g_test_undefined () && !backend_set) + { + g_test_trap_subprocess ("/gsettings/enums/subprocess/non-enum-key", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not associated with an enum*"); + + g_test_trap_subprocess ("/gsettings/enums/subprocess/non-enum-value", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*invalid enum value 42*"); + + g_test_trap_subprocess ("/gsettings/enums/subprocess/range", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_settings_set_value*valid range*"); + + g_test_trap_subprocess ("/gsettings/enums/subprocess/non-flags", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not associated with a flags*"); + } + + str = g_settings_get_string (settings, "test"); + g_assert_cmpstr (str, ==, "bar"); + g_free (str); + + g_settings_set_enum (settings, "test", TEST_ENUM_FOO); + + str = g_settings_get_string (settings, "test"); + g_assert_cmpstr (str, ==, "foo"); + g_free (str); + + g_assert_cmpint (g_settings_get_enum (settings, "test"), ==, TEST_ENUM_FOO); + + g_settings_set_string (direct, "test", "qux"); + + str = g_settings_get_string (direct, "test"); + g_assert_cmpstr (str, ==, "qux"); + g_free (str); + + str = g_settings_get_string (settings, "test"); + g_assert_cmpstr (str, ==, "quux"); + g_free (str); + + g_assert_cmpint (g_settings_get_enum (settings, "test"), ==, TEST_ENUM_QUUX); + + g_object_unref (direct); + g_object_unref (settings); +} + +static void +test_flags_non_flags_key (void) +{ + GSettings *direct; + + direct = g_settings_new ("org.gtk.test.enums.direct"); + g_settings_get_flags (direct, "test"); + g_assert_not_reached (); +} + +static void +test_flags_non_flags_value (void) +{ + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.enums"); + g_settings_set_flags (settings, "f-test", 0x42); + g_assert_not_reached (); +} + +static void +test_flags_range (void) +{ + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.enums"); + g_settings_set_strv (settings, "f-test", + (const gchar **) g_strsplit ("rock", ",", 0)); + g_assert_not_reached (); +} + +static void +test_flags_non_enum (void) +{ + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.enums"); + g_settings_get_enum (settings, "f-test"); + g_assert_not_reached (); +} + +static void +test_flags (void) +{ + GSettings *settings, *direct; + gchar **strv; + gchar *str; + + settings = g_settings_new ("org.gtk.test.enums"); + direct = g_settings_new ("org.gtk.test.enums.direct"); + + if (g_test_undefined () && !backend_set) + { + g_test_trap_subprocess ("/gsettings/flags/subprocess/non-flags-key", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not associated with a flags*"); + + g_test_trap_subprocess ("/gsettings/flags/subprocess/non-flags-value", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*invalid flags value 0x00000042*"); + + g_test_trap_subprocess ("/gsettings/flags/subprocess/range", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_settings_set_value*valid range*"); + + g_test_trap_subprocess ("/gsettings/flags/subprocess/non-enum", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not associated with an enum*"); + } + + strv = g_settings_get_strv (settings, "f-test"); + str = g_strjoinv (",", strv); + g_assert_cmpstr (str, ==, ""); + g_strfreev (strv); + g_free (str); + + g_settings_set_flags (settings, "f-test", + TEST_FLAGS_WALKING | TEST_FLAGS_TALKING); + + strv = g_settings_get_strv (settings, "f-test"); + str = g_strjoinv (",", strv); + g_assert_cmpstr (str, ==, "talking,walking"); + g_strfreev (strv); + g_free (str); + + g_assert_cmpint (g_settings_get_flags (settings, "f-test"), ==, + TEST_FLAGS_WALKING | TEST_FLAGS_TALKING); + + strv = g_strsplit ("speaking,laughing", ",", 0); + g_settings_set_strv (direct, "f-test", (const gchar **) strv); + g_strfreev (strv); + + strv = g_settings_get_strv (direct, "f-test"); + str = g_strjoinv (",", strv); + g_assert_cmpstr (str, ==, "speaking,laughing"); + g_strfreev (strv); + g_free (str); + + strv = g_settings_get_strv (settings, "f-test"); + str = g_strjoinv (",", strv); + g_assert_cmpstr (str, ==, "talking,laughing"); + g_strfreev (strv); + g_free (str); + + g_assert_cmpint (g_settings_get_flags (settings, "f-test"), ==, + TEST_FLAGS_TALKING | TEST_FLAGS_LAUGHING); + + g_object_unref (direct); + g_object_unref (settings); +} + +static void +test_range_high (void) +{ + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.range"); + g_settings_set_int (settings, "val", 45); + g_assert_not_reached (); +} + +static void +test_range_low (void) +{ + GSettings *settings; + + settings = g_settings_new ("org.gtk.test.range"); + g_settings_set_int (settings, "val", 1); + g_assert_not_reached (); +} + +static void +test_range (void) +{ + GSettings *settings, *direct; + GVariant *value; + + settings = g_settings_new ("org.gtk.test.range"); + direct = g_settings_new ("org.gtk.test.range.direct"); + + if (g_test_undefined () && !backend_set) + { + g_test_trap_subprocess ("/gsettings/range/subprocess/high", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_settings_set_value*valid range*"); + + g_test_trap_subprocess ("/gsettings/range/subprocess/low", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_settings_set_value*valid range*"); + } + + g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33); + g_settings_set_int (direct, "val", 22); + g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 22); + g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 22); + g_settings_set_int (direct, "val", 45); + g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 45); + g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33); + g_settings_set_int (direct, "val", 1); + g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 1); + g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + value = g_variant_new_int32 (1); + g_assert_false (g_settings_range_check (settings, "val", value)); + g_variant_unref (value); + value = g_variant_new_int32 (33); + g_assert_true (g_settings_range_check (settings, "val", value)); + g_variant_unref (value); + value = g_variant_new_int32 (45); + g_assert_false (g_settings_range_check (settings, "val", value)); + g_variant_unref (value); +G_GNUC_END_IGNORE_DEPRECATIONS + + g_object_unref (direct); + g_object_unref (settings); +} + +static gboolean +strv_set_equal (const gchar * const *strv, ...) +{ + gsize count; + va_list list; + const gchar *str; + gboolean res; + + res = TRUE; + count = 0; + va_start (list, strv); + while (1) + { + str = va_arg (list, const gchar *); + if (str == NULL) + break; + if (!g_strv_contains (strv, str)) + { + res = FALSE; + break; + } + count++; + } + va_end (list); + + if (res) + res = g_strv_length ((gchar**)strv) == count; + + return res; +} + +static void +test_list_items (void) +{ + GSettingsSchema *schema; + GSettings *settings; + gchar **children; + gchar **keys; + + settings = g_settings_new ("org.gtk.test"); + g_object_get (settings, "settings-schema", &schema, NULL); + children = g_settings_list_children (settings); + keys = g_settings_schema_list_keys (schema); + + g_assert_true (strv_set_equal ((const gchar * const *) children, "basic-types", "complex-types", "localized", NULL)); + g_assert_true (strv_set_equal ((const gchar * const *) keys, "greeting", "farewell", NULL)); + + g_strfreev (children); + g_strfreev (keys); + + g_settings_schema_unref (schema); + g_object_unref (settings); +} + +static void +test_list_schemas (void) +{ + const gchar * const *schemas; + const gchar * const *relocs; + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + relocs = g_settings_list_relocatable_schemas (); + schemas = g_settings_list_schemas (); +G_GNUC_END_IGNORE_DEPRECATIONS + + g_assert_true (strv_set_equal (relocs, + "org.gtk.test.no-path", + "org.gtk.test.extends.base", + "org.gtk.test.extends.extended", + NULL)); + + g_assert_true (strv_set_equal (schemas, + "org.gtk.test", + "org.gtk.test.basic-types", + "org.gtk.test.complex-types", + "org.gtk.test.localized", + "org.gtk.test.binding", + "org.gtk.test.enums", + "org.gtk.test.enums.direct", + "org.gtk.test.range", + "org.gtk.test.range.direct", + "org.gtk.test.mapped", + "org.gtk.test.descriptions", + "org.gtk.test.per-desktop", + NULL)); +} + +static gboolean +map_func (GVariant *value, + gpointer *result, + gpointer user_data) +{ + gint *state = user_data; + gint v; + + if (value) + v = g_variant_get_int32 (value); + else + v = -1; + + if (*state == 0) + { + g_assert_cmpint (v, ==, 1); + (*state)++; + return FALSE; + } + else if (*state == 1) + { + g_assert_cmpint (v, ==, 0); + (*state)++; + return FALSE; + } + else + { + g_assert_null (value); + *result = g_variant_new_int32 (5); + return TRUE; + } +} + +static void +test_get_mapped (void) +{ + GSettings *settings; + gint state; + gpointer p; + gint val; + + settings = g_settings_new ("org.gtk.test.mapped"); + g_settings_set_int (settings, "val", 1); + + state = 0; + p = g_settings_get_mapped (settings, "val", map_func, &state); + val = g_variant_get_int32 ((GVariant*)p); + g_assert_cmpint (val, ==, 5); + + g_variant_unref (p); + g_object_unref (settings); +} + +static void +test_get_range (void) +{ + GSettings *settings; + GVariant *range; + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + settings = g_settings_new ("org.gtk.test.range"); + range = g_settings_get_range (settings, "val"); + check_and_free (range, "('range', <(2, 44)>)"); + g_object_unref (settings); + + settings = g_settings_new ("org.gtk.test.enums"); + range = g_settings_get_range (settings, "test"); + check_and_free (range, "('enum', <['foo', 'bar', 'baz', 'quux']>)"); + g_object_unref (settings); + + settings = g_settings_new ("org.gtk.test.enums"); + range = g_settings_get_range (settings, "f-test"); + check_and_free (range, "('flags', " + "<['mourning', 'laughing', 'talking', 'walking']>)"); + g_object_unref (settings); + + settings = g_settings_new ("org.gtk.test"); + range = g_settings_get_range (settings, "greeting"); + check_and_free (range, "('type', <@as []>)"); + g_object_unref (settings); +G_GNUC_END_IGNORE_DEPRECATIONS +} + +static void +test_schema_source (void) +{ + GSettingsSchemaSource *parent; + GSettingsSchemaSource *source; + GSettingsBackend *backend; + GSettingsSchema *schema; + GError *error = NULL; + GSettings *settings, *child; + gboolean enabled; + + backend = g_settings_backend_get_default (); + + /* make sure it fails properly */ + parent = g_settings_schema_source_get_default (); + source = g_settings_schema_source_new_from_directory ("/path/that/does/not/exist", parent, TRUE, &error); + g_assert_null (source); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); + g_clear_error (&error); + + /* Test error handling of corrupt compiled files. */ + source = g_settings_schema_source_new_from_directory ("schema-source-corrupt", parent, TRUE, &error); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL); + g_assert_null (source); + g_clear_error (&error); + + /* Test error handling of empty compiled files. */ + source = g_settings_schema_source_new_from_directory ("schema-source-empty", parent, TRUE, &error); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL); + g_assert_null (source); + g_clear_error (&error); + + /* create a source with the parent */ + source = g_settings_schema_source_new_from_directory ("schema-source", parent, TRUE, &error); + g_assert_no_error (error); + g_assert_nonnull (source); + + /* check recursive lookups are working */ + schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE); + g_assert_nonnull (schema); + g_settings_schema_unref (schema); + + /* check recursive lookups for non-existent schemas */ + schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", TRUE); + g_assert_null (schema); + + /* check non-recursive for schema that only exists in lower layers */ + schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE); + g_assert_null (schema); + + /* check non-recursive lookup for non-existent */ + schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", FALSE); + g_assert_null (schema); + + /* check non-recursive for schema that exists in toplevel */ + schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE); + g_assert_nonnull (schema); + g_settings_schema_unref (schema); + + /* check recursive for schema that exists in toplevel */ + schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE); + g_assert_nonnull (schema); + + /* try to use it for something */ + settings = g_settings_new_full (schema, backend, "/test/"); + g_settings_schema_unref (schema); + enabled = FALSE; + g_settings_get (settings, "enabled", "b", &enabled); + g_assert_true (enabled); + + /* Check that child schemas are resolved from the correct schema source, see glib#1884 */ + child = g_settings_get_child (settings, "child"); + g_settings_get (settings, "enabled", "b", &enabled); + + g_object_unref (child); + g_object_unref (settings); + g_settings_schema_source_unref (source); + + /* try again, but with no parent */ + source = g_settings_schema_source_new_from_directory ("schema-source", NULL, FALSE, NULL); + g_assert_nonnull (source); + + /* should not find it this time, even if recursive... */ + schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE); + g_assert_null (schema); + schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE); + g_assert_null (schema); + + /* should still find our own... */ + schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE); + g_assert_nonnull (schema); + g_settings_schema_unref (schema); + schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE); + g_assert_nonnull (schema); + g_settings_schema_unref (schema); + + g_settings_schema_source_unref (source); + g_object_unref (backend); +} + +static void +test_schema_list_keys (void) +{ + gchar **keys; + GSettingsSchemaSource *src = g_settings_schema_source_get_default (); + GSettingsSchema *schema = g_settings_schema_source_lookup (src, "org.gtk.test", TRUE); + g_assert_nonnull (schema); + + keys = g_settings_schema_list_keys (schema); + + g_assert_true (strv_set_equal ((const gchar * const *) keys, + "greeting", + "farewell", + NULL)); + + g_strfreev (keys); + g_settings_schema_unref (schema); +} + +static void +test_actions (void) +{ + GAction *string, *toggle; + gboolean c1, c2, c3; + GSettings *settings; + gchar *name; + GVariantType *param_type; + gboolean enabled; + GVariantType *state_type; + GVariant *state; + + settings = g_settings_new ("org.gtk.test.basic-types"); + string = g_settings_create_action (settings, "test-string"); + toggle = g_settings_create_action (settings, "test-boolean"); + g_object_unref (settings); /* should be held by the actions */ + + g_signal_connect (settings, "changed", G_CALLBACK (changed_cb2), &c1); + g_signal_connect (string, "notify::state", G_CALLBACK (changed_cb2), &c2); + g_signal_connect (toggle, "notify::state", G_CALLBACK (changed_cb2), &c3); + + c1 = c2 = c3 = FALSE; + g_settings_set_string (settings, "test-string", "hello world"); + check_and_free (g_action_get_state (string), "'hello world'"); + g_assert_true (c1 && c2 && !c3); + c1 = c2 = c3 = FALSE; + + g_action_activate (string, g_variant_new_string ("hihi")); + check_and_free (g_settings_get_value (settings, "test-string"), "'hihi'"); + g_assert_true (c1 && c2 && !c3); + c1 = c2 = c3 = FALSE; + + g_action_change_state (string, g_variant_new_string ("kthxbye")); + check_and_free (g_settings_get_value (settings, "test-string"), "'kthxbye'"); + g_assert_true (c1 && c2 && !c3); + c1 = c2 = c3 = FALSE; + + g_action_change_state (toggle, g_variant_new_boolean (TRUE)); + g_assert_true (g_settings_get_boolean (settings, "test-boolean")); + g_assert_true (c1 && !c2 && c3); + c1 = c2 = c3 = FALSE; + + g_action_activate (toggle, NULL); + g_assert_false (g_settings_get_boolean (settings, "test-boolean")); + g_assert_true (c1 && !c2 && c3); + + g_object_get (string, + "name", &name, + "parameter-type", ¶m_type, + "enabled", &enabled, + "state-type", &state_type, + "state", &state, + NULL); + + g_assert_cmpstr (name, ==, "test-string"); + g_assert_true (g_variant_type_equal (param_type, G_VARIANT_TYPE_STRING)); + g_assert_true (enabled); + g_assert_true (g_variant_type_equal (state_type, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "kthxbye"); + + g_free (name); + g_variant_type_free (param_type); + g_variant_type_free (state_type); + g_variant_unref (state); + + g_object_unref (string); + g_object_unref (toggle); +} + +static void +test_null_backend (void) +{ + GSettingsBackend *backend; + GSettings *settings; + gchar *str; + gboolean writable; + + backend = g_null_settings_backend_new (); + settings = g_settings_new_with_backend_and_path ("org.gtk.test", backend, "/tests/"); + + g_object_get (settings, "schema-id", &str, NULL); + g_assert_cmpstr (str, ==, "org.gtk.test"); + g_free (str); + + settings_assert_cmpstr (settings, "greeting", ==, "Hello, earthlings"); + + g_settings_set (settings, "greeting", "s", "goodbye world"); + settings_assert_cmpstr (settings, "greeting", ==, "Hello, earthlings"); + + writable = g_settings_is_writable (settings, "greeting"); + g_assert_false (writable); + + g_settings_reset (settings, "greeting"); + + g_settings_delay (settings); + g_settings_set (settings, "greeting", "s", "goodbye world"); + g_settings_apply (settings); + settings_assert_cmpstr (settings, "greeting", ==, "Hello, earthlings"); + + g_object_unref (settings); + g_object_unref (backend); +} + +static void +test_memory_backend (void) +{ + GSettingsBackend *backend; + + backend = g_memory_settings_backend_new (); + g_assert_true (G_IS_SETTINGS_BACKEND (backend)); + g_object_unref (backend); +} + +static void +test_read_descriptions (void) +{ + GSettingsSchema *schema; + GSettingsSchemaKey *key; + GSettings *settings; + + settings = g_settings_new ("org.gtk.test"); + g_object_get (settings, "settings-schema", &schema, NULL); + key = g_settings_schema_get_key (schema, "greeting"); + + g_assert_cmpstr (g_settings_schema_key_get_summary (key), ==, "A greeting"); + g_assert_cmpstr (g_settings_schema_key_get_description (key), ==, "Greeting of the invading martians"); + + g_settings_schema_key_unref (key); + g_settings_schema_unref (schema); + + g_object_unref (settings); + + settings = g_settings_new ("org.gtk.test.descriptions"); + g_object_get (settings, "settings-schema", &schema, NULL); + key = g_settings_schema_get_key (schema, "a"); + + g_assert_cmpstr (g_settings_schema_key_get_summary (key), ==, + "a paragraph.\n\n" + "with some whitespace.\n\n" + "because not everyone has a great editor.\n\n" + "lots of space is as one."); + + g_settings_schema_key_unref (key); + g_settings_schema_unref (schema); + + g_object_unref (settings); +} + +static void +test_default_value (void) +{ + GSettings *settings; + GSettingsSchema *schema; + GSettingsSchemaKey *key; + GVariant *v; + const gchar *str; + gchar *s; + + settings = g_settings_new ("org.gtk.test"); + g_object_get (settings, "settings-schema", &schema, NULL); + key = g_settings_schema_get_key (schema, "greeting"); + g_settings_schema_unref (schema); + g_settings_schema_key_ref (key); + + g_assert_true (g_variant_type_equal (g_settings_schema_key_get_value_type (key), G_VARIANT_TYPE_STRING)); + + v = g_settings_schema_key_get_default_value (key); + str = g_variant_get_string (v, NULL); + g_assert_cmpstr (str, ==, "Hello, earthlings"); + g_variant_unref (v); + + g_settings_schema_key_unref (key); + g_settings_schema_key_unref (key); + + g_settings_set (settings, "greeting", "s", "goodbye world"); + + v = g_settings_get_user_value (settings, "greeting"); + str = g_variant_get_string (v, NULL); + g_assert_cmpstr (str, ==, "goodbye world"); + g_variant_unref (v); + + v = g_settings_get_default_value (settings, "greeting"); + str = g_variant_get_string (v, NULL); + g_assert_cmpstr (str, ==, "Hello, earthlings"); + g_variant_unref (v); + + g_settings_reset (settings, "greeting"); + + v = g_settings_get_user_value (settings, "greeting"); + g_assert_null (v); + + s = g_settings_get_string (settings, "greeting"); + g_assert_cmpstr (s, ==, "Hello, earthlings"); + g_free (s); + + g_object_unref (settings); +} + +static gboolean +string_map_func (GVariant *value, + gpointer *result, + gpointer user_data) +{ + const gchar *str; + + str = g_variant_get_string (value, NULL); + *result = g_variant_new_string (str); + + return TRUE; +} + +/* Test that per-desktop values from org.gtk.test.gschema.override + * does not change default value if current desktop is not listed in + * $XDG_CURRENT_DESKTOP. + */ +static void +test_per_desktop (void) +{ + GSettings *settings; + TestObject *obj; + gpointer p; + gchar *str; + + settings = g_settings_new ("org.gtk.test.per-desktop"); + obj = test_object_new (); + + if (!g_test_subprocess ()) + { + g_test_trap_subprocess ("/gsettings/per-desktop/subprocess", 0, 0); + g_test_trap_assert_passed (); + } + + str = g_settings_get_string (settings, "desktop"); + g_assert_cmpstr (str, ==, "GNOME"); + g_free (str); + + p = g_settings_get_mapped (settings, "desktop", string_map_func, NULL); + + str = g_variant_dup_string (p, NULL); + g_assert_cmpstr (str, ==, "GNOME"); + g_free (str); + + g_variant_unref (p); + + g_settings_bind (settings, "desktop", obj, "string", G_SETTINGS_BIND_DEFAULT); + + g_object_get (obj, "string", &str, NULL); + g_assert_cmpstr (str, ==, "GNOME"); + g_free (str); + + g_object_unref (settings); + g_object_unref (obj); +} + +/* Test that per-desktop values from org.gtk.test.gschema.override + * are successfully loaded based on the value of $XDG_CURRENT_DESKTOP. + */ +static void +test_per_desktop_subprocess (void) +{ + GSettings *settings; + TestObject *obj; + gpointer p; + gchar *str; + + g_setenv ("XDG_CURRENT_DESKTOP", "GNOME-Classic:GNOME", TRUE); + + settings = g_settings_new ("org.gtk.test.per-desktop"); + obj = test_object_new (); + + str = g_settings_get_string (settings, "desktop"); + g_assert_cmpstr (str, ==, "GNOME Classic"); + g_free (str); + + p = g_settings_get_mapped (settings, "desktop", string_map_func, NULL); + + str = g_variant_dup_string (p, NULL); + g_assert_cmpstr (str, ==, "GNOME Classic"); + g_free (str); + + g_variant_unref (p); + + g_settings_bind (settings, "desktop", obj, "string", G_SETTINGS_BIND_DEFAULT); + + g_object_get (obj, "string", &str, NULL); + g_assert_cmpstr (str, ==, "GNOME Classic"); + g_free (str); + + g_object_unref (settings); + g_object_unref (obj); +} + +static void +test_extended_schema (void) +{ + GSettingsSchema *schema; + GSettings *settings; + gchar **keys; + + settings = g_settings_new_with_path ("org.gtk.test.extends.extended", "/test/extendes/"); + g_object_get (settings, "settings-schema", &schema, NULL); + keys = g_settings_schema_list_keys (schema); + g_assert_true (strv_set_equal ((const gchar * const *) keys, "int32", "string", "another-int32", NULL)); + g_strfreev (keys); + g_object_unref (settings); + g_settings_schema_unref (schema); +} + +int +main (int argc, char *argv[]) +{ + gchar *schema_text; + gchar *override_text; + gchar *enums; + gint result; + const KeyfileTestData keyfile_test_data_explicit_path = { "/tests/", "root", "tests", "/" }; + const KeyfileTestData keyfile_test_data_empty_path = { "/", "root", "root", "/" }; + const KeyfileTestData keyfile_test_data_long_path = { + "/tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch/", + "root", + "tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch", + "/" + }; + +/* Meson build sets this */ +#ifdef TEST_LOCALE_PATH + if (g_str_has_suffix (TEST_LOCALE_PATH, "LC_MESSAGES")) + { + locale_dir = TEST_LOCALE_PATH G_DIR_SEPARATOR_S ".." G_DIR_SEPARATOR_S ".."; + } +#endif + + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + if (!g_test_subprocess ()) + { + GError *local_error = NULL; + /* A GVDB header is 6 guint32s, and requires a magic number in the first + * two guint32s. A set of zero bytes of a greater length is considered + * corrupt. */ + const guint8 gschemas_compiled_corrupt[sizeof (guint32) * 7] = { 0, }; + + backend_set = g_getenv ("GSETTINGS_BACKEND") != NULL; + + g_setenv ("XDG_DATA_DIRS", ".", TRUE); + g_setenv ("XDG_DATA_HOME", ".", TRUE); + g_setenv ("GSETTINGS_SCHEMA_DIR", ".", TRUE); + g_setenv ("XDG_CURRENT_DESKTOP", "", TRUE); + + if (!backend_set) + g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); + + g_remove ("org.gtk.test.enums.xml"); + /* #GLIB_MKENUMS is defined in meson.build */ + g_assert_true (g_spawn_command_line_sync (GLIB_MKENUMS " " + "--template " SRCDIR "/enums.xml.template " + SRCDIR "/testenum.h", + &enums, NULL, &result, NULL)); + g_assert_cmpint (result, ==, 0); + g_assert_true (g_file_set_contents ("org.gtk.test.enums.xml", enums, -1, NULL)); + g_free (enums); + + g_assert_true (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.xml.orig", &schema_text, NULL, NULL)); + g_assert_true (g_file_set_contents ("org.gtk.test.gschema.xml", schema_text, -1, NULL)); + g_free (schema_text); + + g_assert_true (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.override.orig", &override_text, NULL, NULL)); + g_assert_true (g_file_set_contents ("org.gtk.test.gschema.override", override_text, -1, NULL)); + g_free (override_text); + + g_remove ("gschemas.compiled"); + /* #GLIB_COMPILE_SCHEMAS is defined in meson.build */ + g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=. " + "--schema-file=org.gtk.test.enums.xml " + "--schema-file=org.gtk.test.gschema.xml " + "--override-file=org.gtk.test.gschema.override", + NULL, NULL, &result, NULL)); + g_assert_cmpint (result, ==, 0); + + g_remove ("schema-source/gschemas.compiled"); + g_mkdir ("schema-source", 0777); + g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=schema-source " + "--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml", + NULL, NULL, &result, NULL)); + g_assert_cmpint (result, ==, 0); + + g_remove ("schema-source-corrupt/gschemas.compiled"); + g_mkdir ("schema-source-corrupt", 0777); + g_file_set_contents ("schema-source-corrupt/gschemas.compiled", + (const gchar *) gschemas_compiled_corrupt, + sizeof (gschemas_compiled_corrupt), + &local_error); + g_assert_no_error (local_error); + + g_remove ("schema-source-empty/gschemas.compiled"); + g_mkdir ("schema-source-empty", 0777); + g_file_set_contents ("schema-source-empty/gschemas.compiled", + "", 0, + &local_error); + g_assert_no_error (local_error); + } + + g_test_add_func ("/gsettings/basic", test_basic); + + if (!backend_set) + { + g_test_add_func ("/gsettings/no-schema", test_no_schema); + g_test_add_func ("/gsettings/unknown-key", test_unknown_key); + g_test_add_func ("/gsettings/wrong-type", test_wrong_type); + g_test_add_func ("/gsettings/wrong-path", test_wrong_path); + g_test_add_func ("/gsettings/no-path", test_no_path); + } + + g_test_add_func ("/gsettings/basic-types", test_basic_types); + g_test_add_func ("/gsettings/complex-types", test_complex_types); + g_test_add_func ("/gsettings/changes", test_changes); + + g_test_add_func ("/gsettings/l10n", test_l10n); + g_test_add_func ("/gsettings/l10n-context", test_l10n_context); + + g_test_add_func ("/gsettings/delay-apply", test_delay_apply); + g_test_add_func ("/gsettings/delay-revert", test_delay_revert); + g_test_add_func ("/gsettings/delay-child", test_delay_child); + g_test_add_func ("/gsettings/delay-reset-key", test_delay_reset_key); + g_test_add_func ("/gsettings/atomic", test_atomic); + + g_test_add_func ("/gsettings/simple-binding", test_simple_binding); + g_test_add_func ("/gsettings/directional-binding", test_directional_binding); + g_test_add_func ("/gsettings/custom-binding", test_custom_binding); + g_test_add_func ("/gsettings/no-change-binding", test_no_change_binding); + g_test_add_func ("/gsettings/unbinding", test_unbind); + g_test_add_func ("/gsettings/writable-binding", test_bind_writable); + + if (!backend_set) + { + g_test_add_func ("/gsettings/typesafe-binding", test_typesafe_binding); + g_test_add_func ("/gsettings/no-read-binding", test_no_read_binding); + g_test_add_func ("/gsettings/no-read-binding/subprocess/fail", test_no_read_binding_fail); + g_test_add_func ("/gsettings/no-read-binding/subprocess/pass", test_no_read_binding_pass); + g_test_add_func ("/gsettings/no-write-binding", test_no_write_binding); + g_test_add_func ("/gsettings/no-write-binding/subprocess/fail", test_no_write_binding_fail); + g_test_add_func ("/gsettings/no-write-binding/subprocess/pass", test_no_write_binding_pass); + } + + g_test_add ("/gsettings/keyfile", Fixture, NULL, setup, test_keyfile, teardown); + g_test_add ("/gsettings/keyfile/explicit-path", Fixture, &keyfile_test_data_explicit_path, setup, test_keyfile_no_path, teardown); + g_test_add ("/gsettings/keyfile/empty-path", Fixture, &keyfile_test_data_empty_path, setup, test_keyfile_no_path, teardown); + g_test_add ("/gsettings/keyfile/long-path", Fixture, &keyfile_test_data_long_path, setup, test_keyfile_no_path, teardown); + g_test_add ("/gsettings/keyfile/outside-root-path", Fixture, NULL, setup, test_keyfile_outside_root_path, teardown); + g_test_add ("/gsettings/keyfile/no-root-group", Fixture, NULL, setup, test_keyfile_no_root_group, teardown); + g_test_add_func ("/gsettings/child-schema", test_child_schema); + g_test_add_func ("/gsettings/strinfo", test_strinfo); + g_test_add_func ("/gsettings/enums", test_enums); + g_test_add_func ("/gsettings/enums/subprocess/non-enum-key", test_enums_non_enum_key); + g_test_add_func ("/gsettings/enums/subprocess/non-enum-value", test_enums_non_enum_value); + g_test_add_func ("/gsettings/enums/subprocess/range", test_enums_range); + g_test_add_func ("/gsettings/enums/subprocess/non-flags", test_enums_non_flags); + g_test_add_func ("/gsettings/flags", test_flags); + g_test_add_func ("/gsettings/flags/subprocess/non-flags-key", test_flags_non_flags_key); + g_test_add_func ("/gsettings/flags/subprocess/non-flags-value", test_flags_non_flags_value); + g_test_add_func ("/gsettings/flags/subprocess/range", test_flags_range); + g_test_add_func ("/gsettings/flags/subprocess/non-enum", test_flags_non_enum); + g_test_add_func ("/gsettings/range", test_range); + g_test_add_func ("/gsettings/range/subprocess/high", test_range_high); + g_test_add_func ("/gsettings/range/subprocess/low", test_range_low); + g_test_add_func ("/gsettings/list-items", test_list_items); + g_test_add_func ("/gsettings/list-schemas", test_list_schemas); + g_test_add_func ("/gsettings/mapped", test_get_mapped); + g_test_add_func ("/gsettings/get-range", test_get_range); + g_test_add_func ("/gsettings/schema-source", test_schema_source); + g_test_add_func ("/gsettings/schema-list-keys", test_schema_list_keys); + g_test_add_func ("/gsettings/actions", test_actions); + g_test_add_func ("/gsettings/null-backend", test_null_backend); + g_test_add_func ("/gsettings/memory-backend", test_memory_backend); + g_test_add_func ("/gsettings/read-descriptions", test_read_descriptions); + g_test_add_func ("/gsettings/test-extended-schema", test_extended_schema); + g_test_add_func ("/gsettings/default-value", test_default_value); + g_test_add_func ("/gsettings/per-desktop", test_per_desktop); + g_test_add_func ("/gsettings/per-desktop/subprocess", test_per_desktop_subprocess); + + result = g_test_run (); + + g_settings_sync (); + + /* FIXME: Due to the way #GSettings objects can be used without specifying a + * backend, the default backend is leaked. In order to be able to run this + * test under valgrind and get meaningful checking for real leaks, use this + * hack to drop the final reference to the default #GSettingsBackend. + * + * This should not be used in production code. */ + { + GSettingsBackend *backend; + + backend = g_settings_backend_get_default (); + g_object_unref (backend); /* reference from the *_get_default() call */ + g_assert_finalize_object (backend); /* singleton reference owned by GLib */ + } + + return result; +} diff --git a/gio/tests/gsocketclient-slow.c b/gio/tests/gsocketclient-slow.c new file mode 100644 index 0000000..803ed90 --- /dev/null +++ b/gio/tests/gsocketclient-slow.c @@ -0,0 +1,185 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +static void +on_connected (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GError *error = NULL; + + conn = g_socket_client_connect_to_uri_finish (G_SOCKET_CLIENT (source_object), result, &error); + g_assert_no_error (error); + + g_object_unref (conn); + g_main_loop_quit (user_data); +} + +static void +test_happy_eyeballs (void) +{ + GSocketClient *client; + GSocketService *service; + GError *error = NULL; + guint16 port; + GMainLoop *loop; + + loop = g_main_loop_new (NULL, FALSE); + + service = g_socket_service_new (); + port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL, &error); + g_assert_no_error (error); + g_socket_service_start (service); + + /* All of the magic here actually happens in slow-connect-preload.c + * which as you would guess is preloaded. So this is just making a + * normal connection that happens to take 600ms each time. This will + * trigger the logic to make multiple parallel connections. + */ + client = g_socket_client_new (); + g_socket_client_connect_to_host_async (client, "localhost", port, NULL, on_connected, loop); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + g_object_unref (service); + g_object_unref (client); +} + +static void +on_connected_cancelled (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GError *error = NULL; + + conn = g_socket_client_connect_to_uri_finish (G_SOCKET_CLIENT (source_object), result, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert_null (conn); + + g_error_free (error); + g_main_loop_quit (user_data); +} + +typedef struct +{ + GCancellable *cancellable; + gboolean completed; +} EventCallbackData; + +static void +on_event (GSocketClient *client, + GSocketClientEvent event, + GSocketConnectable *connectable, + GIOStream *connection, + EventCallbackData *data) +{ + if (data->cancellable && event == G_SOCKET_CLIENT_CONNECTED) + { + g_cancellable_cancel (data->cancellable); + } + else if (event == G_SOCKET_CLIENT_COMPLETE) + { + data->completed = TRUE; + g_assert_null (connection); + } +} + +static void +test_happy_eyeballs_cancel_delayed (void) +{ + GSocketClient *client; + GSocketService *service; + GError *error = NULL; + guint16 port; + GMainLoop *loop; + EventCallbackData data = { NULL, FALSE }; + + /* This just tests that cancellation works as expected, still emits the completed signal, + * and never returns a connection */ + + loop = g_main_loop_new (NULL, FALSE); + + service = g_socket_service_new (); + port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL, &error); + g_assert_no_error (error); + g_socket_service_start (service); + + client = g_socket_client_new (); + data.cancellable = g_cancellable_new (); + g_socket_client_connect_to_host_async (client, "localhost", port, data.cancellable, on_connected_cancelled, loop); + g_signal_connect (client, "event", G_CALLBACK (on_event), &data); + g_main_loop_run (loop); + + g_assert_true (data.completed); + g_main_loop_unref (loop); + g_object_unref (service); + g_object_unref (client); + g_object_unref (data.cancellable); +} + +static void +test_happy_eyeballs_cancel_instant (void) +{ + GSocketClient *client; + GSocketService *service; + GError *error = NULL; + guint16 port; + GMainLoop *loop; + GCancellable *cancel; + EventCallbackData data = { NULL, FALSE }; + + /* This tests the same things as above, test_happy_eyeballs_cancel_delayed(), but + * with different timing since it sends an already cancelled cancellable */ + + loop = g_main_loop_new (NULL, FALSE); + + service = g_socket_service_new (); + port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL, &error); + g_assert_no_error (error); + g_socket_service_start (service); + + client = g_socket_client_new (); + cancel = g_cancellable_new (); + g_cancellable_cancel (cancel); + g_socket_client_connect_to_host_async (client, "localhost", port, cancel, on_connected_cancelled, loop); + g_signal_connect (client, "event", G_CALLBACK (on_event), &data); + g_main_loop_run (loop); + + g_assert_true (data.completed); + g_main_loop_unref (loop); + g_object_unref (service); + g_object_unref (client); + g_object_unref (cancel); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/socket-client/happy-eyeballs/slow", test_happy_eyeballs); + g_test_add_func ("/socket-client/happy-eyeballs/cancellation/instant", test_happy_eyeballs_cancel_instant); + g_test_add_func ("/socket-client/happy-eyeballs/cancellation/delayed", test_happy_eyeballs_cancel_delayed); + + + return g_test_run (); +} diff --git a/gio/tests/gsubprocess-testprog.c b/gio/tests/gsubprocess-testprog.c new file mode 100644 index 0000000..eee759d --- /dev/null +++ b/gio/tests/gsubprocess-testprog.c @@ -0,0 +1,307 @@ +#include +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#else +#include +#endif + +static GOptionEntry options[] = { + G_OPTION_ENTRY_NULL +}; + +static void +write_all (int fd, + const guint8* buf, + gsize len) +{ + while (len > 0) + { + gssize bytes_written = write (fd, buf, len); + int errsv = errno; + if (bytes_written < 0) + g_error ("Failed to write to fd %d: %s", + fd, g_strerror (errsv)); + buf += bytes_written; + len -= bytes_written; + } +} + +static int +echo_mode (int argc, + char **argv) +{ + int i; + + for (i = 2; i < argc; i++) + { + write_all (1, (guint8*)argv[i], strlen (argv[i])); + write_all (1, (guint8*)"\n", 1); + } + + return 0; +} + +static int +echo_stdout_and_stderr_mode (int argc, + char **argv) +{ + int i; + + for (i = 2; i < argc; i++) + { + write_all (1, (guint8*)argv[i], strlen (argv[i])); + write_all (1, (guint8*)"\n", 1); + write_all (2, (guint8*)argv[i], strlen (argv[i])); + write_all (2, (guint8*)"\n", 1); + } + + return 0; +} + +static int +cat_mode (int argc, + char **argv) +{ + GIOChannel *chan_stdin; + GIOChannel *chan_stdout; + GIOStatus status; + char buf[1024]; + gsize bytes_read, bytes_written; + GError *local_error = NULL; + GError **error = &local_error; + + chan_stdin = g_io_channel_unix_new (0); + g_io_channel_set_encoding (chan_stdin, NULL, error); + g_assert_no_error (local_error); + chan_stdout = g_io_channel_unix_new (1); + g_io_channel_set_encoding (chan_stdout, NULL, error); + g_assert_no_error (local_error); + + while (TRUE) + { + do + status = g_io_channel_read_chars (chan_stdin, buf, sizeof (buf), + &bytes_read, error); + while (status == G_IO_STATUS_AGAIN); + + if (status == G_IO_STATUS_EOF || status == G_IO_STATUS_ERROR) + break; + + do + status = g_io_channel_write_chars (chan_stdout, buf, bytes_read, + &bytes_written, error); + while (status == G_IO_STATUS_AGAIN); + + if (status == G_IO_STATUS_EOF || status == G_IO_STATUS_ERROR) + break; + } + + g_io_channel_unref (chan_stdin); + g_io_channel_unref (chan_stdout); + + if (local_error) + { + g_printerr ("I/O error: %s\n", local_error->message); + g_clear_error (&local_error); + return 1; + } + return 0; +} + +static gint +sleep_forever_mode (int argc, + char **argv) +{ + GMainLoop *loop; + + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); + + return 0; +} + +static int +write_to_fds (int argc, char **argv) +{ + int i; + + for (i = 2; i < argc; i++) + { + int fd = atoi (argv[i]); + FILE *f = fdopen (fd, "w"); + const char buf[] = "hello world\n"; + size_t bytes_written; + + g_assert (f != NULL); + + bytes_written = fwrite (buf, 1, sizeof (buf), f); + g_assert (bytes_written == sizeof (buf)); + + if (fclose (f) == -1) + g_assert_not_reached (); + } + + return 0; +} + +static int +read_from_fd (int argc, char **argv) +{ + int fd; + const char expected_result[] = "Yay success!"; + guint8 buf[sizeof (expected_result) + 1]; + gsize bytes_read; + FILE *f; + + if (argc != 3) + { + g_print ("Usage: %s read-from-fd FD\n", argv[0]); + return 1; + } + + fd = atoi (argv[2]); + if (fd == 0) + { + g_warning ("Argument \"%s\" does not look like a valid nonzero file descriptor", argv[2]); + return 1; + } + + f = fdopen (fd, "r"); + if (f == NULL) + { + g_warning ("Failed to open fd %d: %s", fd, g_strerror (errno)); + return 1; + } + + bytes_read = fread (buf, 1, sizeof (buf), f); + if (bytes_read != sizeof (expected_result)) + { + g_warning ("Read %zu bytes, but expected %zu", bytes_read, sizeof (expected_result)); + return 1; + } + + if (memcmp (expected_result, buf, sizeof (expected_result)) != 0) + { + buf[sizeof (expected_result)] = '\0'; + g_warning ("Expected \"%s\" but read \"%s\"", expected_result, (char *)buf); + return 1; + } + + if (fclose (f) == -1) + g_assert_not_reached (); + + return 0; +} + +static int +env_mode (int argc, char **argv) +{ + char **env; + int i; + + env = g_get_environ (); + + for (i = 0; env[i]; i++) + g_print ("%s\n", env[i]); + + g_strfreev (env); + + return 0; +} + +static int +cwd_mode (int argc, char **argv) +{ + char *cwd; + + cwd = g_get_current_dir (); + g_print ("%s\n", cwd); + g_free (cwd); + + return 0; +} + +static int +printenv_mode (int argc, char **argv) +{ + gint i; + + for (i = 2; i < argc; i++) + { + const gchar *value = g_getenv (argv[i]); + + if (value != NULL) + g_print ("%s=%s\n", argv[i], value); + } + + return 0; +} + +int +main (int argc, char **argv) +{ + GOptionContext *context; + GError *error = NULL; + const char *mode; + gboolean ret; + + context = g_option_context_new ("MODE - Test GSubprocess stuff"); + g_option_context_add_main_entries (context, options, NULL); + ret = g_option_context_parse (context, &argc, &argv, &error); + g_option_context_free (context); + + if (!ret) + { + g_printerr ("%s: %s\n", argv[0], error->message); + g_error_free (error); + return 1; + } + + if (argc < 2) + { + g_printerr ("MODE argument required\n"); + return 1; + } + + mode = argv[1]; + if (strcmp (mode, "noop") == 0) + return 0; + else if (strcmp (mode, "exit1") == 0) + return 1; + else if (strcmp (mode, "assert-argv0") == 0) + { + if (strcmp (argv[0], "moocow") == 0) + return 0; + g_printerr ("argv0=%s != moocow\n", argv[0]); + return 1; + } + else if (strcmp (mode, "echo") == 0) + return echo_mode (argc, argv); + else if (strcmp (mode, "echo-stdout-and-stderr") == 0) + return echo_stdout_and_stderr_mode (argc, argv); + else if (strcmp (mode, "cat") == 0) + return cat_mode (argc, argv); + else if (strcmp (mode, "sleep-forever") == 0) + return sleep_forever_mode (argc, argv); + else if (strcmp (mode, "write-to-fds") == 0) + return write_to_fds (argc, argv); + else if (strcmp (mode, "read-from-fd") == 0) + return read_from_fd (argc, argv); + else if (strcmp (mode, "env") == 0) + return env_mode (argc, argv); + else if (strcmp (mode, "cwd") == 0) + return cwd_mode (argc, argv); + else if (strcmp (mode, "printenv") == 0) + return printenv_mode (argc, argv); + else + { + g_printerr ("Unknown MODE %s\n", argv[1]); + return 1; + } + + return TRUE; +} diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c new file mode 100644 index 0000000..fc5d462 --- /dev/null +++ b/gio/tests/gsubprocess.c @@ -0,0 +1,2135 @@ +#include +#include + +#ifdef G_OS_UNIX +#include +#include +#include +#include +#include +#include +#include +#endif + +/* We write 2^1 + 2^2 ... + 2^10 or 2047 copies of "Hello World!\n" + * ultimately + */ +#define TOTAL_HELLOS 2047 +#define HELLO_WORLD "hello world!\n" + +#ifdef G_OS_WIN32 +#define LINEEND "\r\n" +#define EXEEXT ".exe" +#define SPLICELEN (TOTAL_HELLOS * (strlen (HELLO_WORLD) + 1)) /* because \r */ +#else +#define LINEEND "\n" +#define EXEEXT +#define SPLICELEN (TOTAL_HELLOS * strlen (HELLO_WORLD)) +#endif + + + +#ifdef G_OS_WIN32 +#define TESTPROG "gsubprocess-testprog.exe" +#else +#define TESTPROG "gsubprocess-testprog" +#endif + +static GPtrArray * +get_test_subprocess_args (const char *mode, + ...) G_GNUC_NULL_TERMINATED; + +static GPtrArray * +get_test_subprocess_args (const char *mode, + ...) +{ + GPtrArray *ret; + char *path; + va_list args; + gpointer arg; + + ret = g_ptr_array_new_with_free_func (g_free); + + path = g_test_build_filename (G_TEST_BUILT, TESTPROG, NULL); + g_ptr_array_add (ret, path); + g_ptr_array_add (ret, g_strdup (mode)); + + va_start (args, mode); + while ((arg = va_arg (args, gpointer)) != NULL) + g_ptr_array_add (ret, g_strdup (arg)); + va_end (args); + + g_ptr_array_add (ret, NULL); + return ret; +} + +static void +test_noop (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GPtrArray *args; + GSubprocess *proc; + + args = get_test_subprocess_args ("noop", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + g_subprocess_wait_check (proc, NULL, error); + g_assert_no_error (local_error); + g_assert_true (g_subprocess_get_successful (proc)); + + g_object_unref (proc); +} + +static void +check_ready (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + gboolean ret; + GError *error = NULL; + + ret = g_subprocess_wait_check_finish (G_SUBPROCESS (source), + res, + &error); + g_assert_true (ret); + g_assert_no_error (error); + + g_object_unref (source); +} + +static void +test_noop_all_to_null (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GPtrArray *args; + GSubprocess *proc; + + args = get_test_subprocess_args ("noop", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, + G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE, + error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + g_subprocess_wait_check_async (proc, NULL, check_ready, NULL); +} + +static void +test_noop_no_wait (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GPtrArray *args; + GSubprocess *proc; + + args = get_test_subprocess_args ("noop", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + g_object_unref (proc); +} + +static void +test_noop_stdin_inherit (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GPtrArray *args; + GSubprocess *proc; + + args = get_test_subprocess_args ("noop", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_STDIN_INHERIT, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + g_subprocess_wait_check (proc, NULL, error); + g_assert_no_error (local_error); + + g_object_unref (proc); +} + +#ifdef G_OS_UNIX +static void +test_search_path (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocess *proc; + + proc = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE, error, "true", NULL); + g_assert_no_error (local_error); + + g_subprocess_wait_check (proc, NULL, error); + g_assert_no_error (local_error); + + g_object_unref (proc); +} + +static void +test_search_path_from_envp (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocessLauncher *launcher; + GSubprocess *proc; + const char *path; + + path = g_test_get_dir (G_TEST_BUILT); + + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP); + g_subprocess_launcher_setenv (launcher, "PATH", path, TRUE); + + proc = g_subprocess_launcher_spawn (launcher, error, TESTPROG, "exit1", NULL); + g_assert_no_error (local_error); + g_object_unref (launcher); + + g_subprocess_wait_check (proc, NULL, error); + g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (error); + + g_object_unref (proc); +} +#endif + +static void +test_exit1 (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GPtrArray *args; + GSubprocess *proc; + + args = get_test_subprocess_args ("exit1", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + g_subprocess_wait_check (proc, NULL, error); + g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (error); + + g_object_unref (proc); +} + +typedef struct { + GMainLoop *loop; + GCancellable *cancellable; + gboolean cb_called; +} TestExit1CancelData; + +static gboolean +test_exit1_cancel_idle_quit_cb (gpointer user_data) +{ + GMainLoop *loop = user_data; + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; +} + +static void +test_exit1_cancel_wait_check_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSubprocess *subprocess = G_SUBPROCESS (source); + TestExit1CancelData *data = user_data; + gboolean ret; + GError *error = NULL; + + g_assert_false (data->cb_called); + data->cb_called = TRUE; + + ret = g_subprocess_wait_check_finish (subprocess, result, &error); + g_assert_false (ret); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + + g_idle_add (test_exit1_cancel_idle_quit_cb, data->loop); +} + +static void +test_exit1_cancel (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GPtrArray *args; + GSubprocess *proc; + TestExit1CancelData data = { 0 }; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=786456"); + + args = get_test_subprocess_args ("exit1", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + data.loop = g_main_loop_new (NULL, FALSE); + data.cancellable = g_cancellable_new (); + g_subprocess_wait_check_async (proc, data.cancellable, test_exit1_cancel_wait_check_cb, &data); + + g_subprocess_wait_check (proc, NULL, error); + g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (error); + + g_cancellable_cancel (data.cancellable); + g_main_loop_run (data.loop); + + g_object_unref (proc); + g_main_loop_unref (data.loop); + g_clear_object (&data.cancellable); +} + +static void +test_exit1_cancel_in_cb_wait_check_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSubprocess *subprocess = G_SUBPROCESS (source); + TestExit1CancelData *data = user_data; + gboolean ret; + GError *error = NULL; + + g_assert_false (data->cb_called); + data->cb_called = TRUE; + + ret = g_subprocess_wait_check_finish (subprocess, result, &error); + g_assert_false (ret); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (&error); + + g_cancellable_cancel (data->cancellable); + + g_idle_add (test_exit1_cancel_idle_quit_cb, data->loop); +} + +static void +test_exit1_cancel_in_cb (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GPtrArray *args; + GSubprocess *proc; + TestExit1CancelData data = { 0 }; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=786456"); + + args = get_test_subprocess_args ("exit1", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + data.loop = g_main_loop_new (NULL, FALSE); + data.cancellable = g_cancellable_new (); + g_subprocess_wait_check_async (proc, data.cancellable, test_exit1_cancel_in_cb_wait_check_cb, &data); + + g_subprocess_wait_check (proc, NULL, error); + g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (error); + + g_main_loop_run (data.loop); + + g_object_unref (proc); + g_main_loop_unref (data.loop); + g_clear_object (&data.cancellable); +} + +static gchar * +splice_to_string (GInputStream *stream, + GError **error) +{ + GMemoryOutputStream *buffer = NULL; + char *ret = NULL; + + buffer = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + if (g_output_stream_splice ((GOutputStream*)buffer, stream, 0, NULL, error) < 0) + goto out; + + if (!g_output_stream_write ((GOutputStream*)buffer, "\0", 1, NULL, error)) + goto out; + + if (!g_output_stream_close ((GOutputStream*)buffer, NULL, error)) + goto out; + + ret = g_memory_output_stream_steal_data (buffer); + out: + g_clear_object (&buffer); + return ret; +} + +static void +test_echo1 (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocess *proc; + GPtrArray *args; + GInputStream *stdout_stream; + gchar *result; + + args = get_test_subprocess_args ("echo", "hello", "world!", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + stdout_stream = g_subprocess_get_stdout_pipe (proc); + + result = splice_to_string (stdout_stream, error); + g_assert_no_error (local_error); + + g_assert_cmpstr (result, ==, "hello" LINEEND "world!" LINEEND); + + g_free (result); + g_object_unref (proc); +} + +#ifdef G_OS_UNIX +static void +test_echo_merged (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocess *proc; + GPtrArray *args; + GInputStream *stdout_stream; + gchar *result; + + args = get_test_subprocess_args ("echo-stdout-and-stderr", "merge", "this", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, + G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_MERGE, + error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + stdout_stream = g_subprocess_get_stdout_pipe (proc); + result = splice_to_string (stdout_stream, error); + g_assert_no_error (local_error); + + g_assert_cmpstr (result, ==, "merge\nmerge\nthis\nthis\n"); + + g_free (result); + g_object_unref (proc); +} +#endif + +typedef struct { + guint events_pending; + GMainLoop *loop; +} TestCatData; + +static void +test_cat_on_input_splice_complete (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + TestCatData *data = user_data; + GError *error = NULL; + + (void)g_output_stream_splice_finish ((GOutputStream*)object, result, &error); + g_assert_no_error (error); + + data->events_pending--; + if (data->events_pending == 0) + g_main_loop_quit (data->loop); +} + +static void +test_cat_utf8 (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocess *proc; + GPtrArray *args; + GBytes *input_buf; + GBytes *output_buf; + GInputStream *input_buf_stream = NULL; + GOutputStream *output_buf_stream = NULL; + GOutputStream *stdin_stream = NULL; + GInputStream *stdout_stream = NULL; + TestCatData data; + + memset (&data, 0, sizeof (data)); + data.loop = g_main_loop_new (NULL, TRUE); + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE, + error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + stdin_stream = g_subprocess_get_stdin_pipe (proc); + stdout_stream = g_subprocess_get_stdout_pipe (proc); + + input_buf = g_bytes_new_static ("hello, world!", strlen ("hello, world!")); + input_buf_stream = g_memory_input_stream_new_from_bytes (input_buf); + g_bytes_unref (input_buf); + + output_buf_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + + g_output_stream_splice_async (stdin_stream, input_buf_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + G_PRIORITY_DEFAULT, NULL, test_cat_on_input_splice_complete, + &data); + data.events_pending++; + g_output_stream_splice_async (output_buf_stream, stdout_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + G_PRIORITY_DEFAULT, NULL, test_cat_on_input_splice_complete, + &data); + data.events_pending++; + + g_main_loop_run (data.loop); + + g_subprocess_wait_check (proc, NULL, error); + g_assert_no_error (local_error); + + output_buf = g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)output_buf_stream); + + g_assert_cmpmem (g_bytes_get_data (output_buf, NULL), + g_bytes_get_size (output_buf), + "hello, world!", 13); + + g_bytes_unref (output_buf); + g_main_loop_unref (data.loop); + g_object_unref (input_buf_stream); + g_object_unref (output_buf_stream); + g_object_unref (proc); +} + +static gpointer +cancel_soon (gpointer user_data) +{ + GCancellable *cancellable = user_data; + + g_usleep (G_TIME_SPAN_SECOND); + g_cancellable_cancel (cancellable); + g_object_unref (cancellable); + + return NULL; +} + +static void +test_cat_eof (void) +{ + GCancellable *cancellable; + GError *error = NULL; + GSubprocess *cat; + gboolean result; + gchar buffer; + gssize s; + +#ifdef G_OS_WIN32 + g_test_skip ("This test has not been ported to Win32"); + return; +#endif + + /* Spawn 'cat' */ + cat = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error, "cat", NULL); + g_assert_no_error (error); + g_assert_nonnull (cat); + + /* Make sure that reading stdout blocks (until we cancel) */ + cancellable = g_cancellable_new (); + g_thread_unref (g_thread_new ("cancel thread", cancel_soon, g_object_ref (cancellable))); + s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, cancellable, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert_cmpint (s, ==, -1); + g_object_unref (cancellable); + g_clear_error (&error); + + /* Close the stream (EOF on cat's stdin) */ + result = g_output_stream_close (g_subprocess_get_stdin_pipe (cat), NULL, &error); + g_assert_no_error (error); + g_assert_true (result); + + /* Now check that reading cat's stdout gets us an EOF (since it quit) */ + s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, NULL, &error); + g_assert_no_error (error); + g_assert_false (s); + + /* Check that the process has exited as a result of the EOF */ + result = g_subprocess_wait (cat, NULL, &error); + g_assert_no_error (error); + g_assert_true (g_subprocess_get_if_exited (cat)); + g_assert_cmpint (g_subprocess_get_exit_status (cat), ==, 0); + g_assert_true (result); + + g_object_unref (cat); +} + +typedef struct { + guint events_pending; + gboolean caught_error; + GError *error; + GMainLoop *loop; + + gint counter; + GOutputStream *first_stdin; +} TestMultiSpliceData; + +static void +on_one_multi_splice_done (GObject *obj, + GAsyncResult *res, + gpointer user_data) +{ + TestMultiSpliceData *data = user_data; + + if (!data->caught_error) + { + if (g_output_stream_splice_finish ((GOutputStream*)obj, res, &data->error) < 0) + data->caught_error = TRUE; + } + + data->events_pending--; + if (data->events_pending == 0) + g_main_loop_quit (data->loop); +} + +static gboolean +on_idle_multisplice (gpointer user_data) +{ + TestMultiSpliceData *data = user_data; + + if (data->counter >= TOTAL_HELLOS || data->caught_error) + { + if (!g_output_stream_close (data->first_stdin, NULL, &data->error)) + data->caught_error = TRUE; + data->events_pending--; + if (data->events_pending == 0) + { + g_main_loop_quit (data->loop); + } + return FALSE; + } + else + { + int i; + for (i = 0; i < data->counter; i++) + { + gsize bytes_written; + if (!g_output_stream_write_all (data->first_stdin, HELLO_WORLD, + strlen (HELLO_WORLD), &bytes_written, + NULL, &data->error)) + { + data->caught_error = TRUE; + return FALSE; + } + } + data->counter *= 2; + return TRUE; + } +} + +static void +on_subprocess_exited (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSubprocess *subprocess = G_SUBPROCESS (object); + TestMultiSpliceData *data = user_data; + GError *error = NULL; + + if (!g_subprocess_wait_finish (subprocess, result, &error)) + { + if (!data->caught_error) + { + data->caught_error = TRUE; + g_propagate_error (&data->error, error); + } + } + g_spawn_check_wait_status (g_subprocess_get_status (subprocess), &error); + g_assert_no_error (error); + data->events_pending--; + if (data->events_pending == 0) + g_main_loop_quit (data->loop); +} + +static void +test_multi_1 (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GPtrArray *args; + GSubprocessLauncher *launcher; + GSubprocess *first; + GSubprocess *second; + GSubprocess *third; + GOutputStream *first_stdin; + GInputStream *first_stdout; + GOutputStream *second_stdin; + GInputStream *second_stdout; + GOutputStream *third_stdin; + GInputStream *third_stdout; + GOutputStream *membuf; + TestMultiSpliceData data; + int splice_flags = G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET; + + args = get_test_subprocess_args ("cat", NULL); + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE); + first = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + g_assert_no_error (local_error); + second = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + g_assert_no_error (local_error); + third = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + g_assert_no_error (local_error); + + g_ptr_array_free (args, TRUE); + + membuf = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + + first_stdin = g_subprocess_get_stdin_pipe (first); + first_stdout = g_subprocess_get_stdout_pipe (first); + second_stdin = g_subprocess_get_stdin_pipe (second); + second_stdout = g_subprocess_get_stdout_pipe (second); + third_stdin = g_subprocess_get_stdin_pipe (third); + third_stdout = g_subprocess_get_stdout_pipe (third); + + memset (&data, 0, sizeof (data)); + data.loop = g_main_loop_new (NULL, TRUE); + data.counter = 1; + data.first_stdin = first_stdin; + + data.events_pending++; + g_output_stream_splice_async (second_stdin, first_stdout, splice_flags, G_PRIORITY_DEFAULT, + NULL, on_one_multi_splice_done, &data); + data.events_pending++; + g_output_stream_splice_async (third_stdin, second_stdout, splice_flags, G_PRIORITY_DEFAULT, + NULL, on_one_multi_splice_done, &data); + data.events_pending++; + g_output_stream_splice_async (membuf, third_stdout, splice_flags, G_PRIORITY_DEFAULT, + NULL, on_one_multi_splice_done, &data); + + data.events_pending++; + g_timeout_add (250, on_idle_multisplice, &data); + + data.events_pending++; + g_subprocess_wait_async (first, NULL, on_subprocess_exited, &data); + data.events_pending++; + g_subprocess_wait_async (second, NULL, on_subprocess_exited, &data); + data.events_pending++; + g_subprocess_wait_async (third, NULL, on_subprocess_exited, &data); + + g_main_loop_run (data.loop); + + g_assert_false (data.caught_error); + g_assert_no_error (data.error); + + g_assert_cmpint (g_memory_output_stream_get_data_size ((GMemoryOutputStream*)membuf), ==, SPLICELEN); + + g_main_loop_unref (data.loop); + g_object_unref (membuf); + g_object_unref (launcher); + g_object_unref (first); + g_object_unref (second); + g_object_unref (third); +} + +typedef struct { + GSubprocessFlags flags; + gboolean is_utf8; + gboolean running; + GError *error; +} TestAsyncCommunicateData; + +static void +on_communicate_complete (GObject *proc, + GAsyncResult *result, + gpointer user_data) +{ + TestAsyncCommunicateData *data = user_data; + GBytes *stdout_bytes = NULL, *stderr_bytes = NULL; + char *stdout_str = NULL, *stderr_str = NULL; + const guint8 *stdout_data; + gsize stdout_len; + + data->running = FALSE; + if (data->is_utf8) + (void) g_subprocess_communicate_utf8_finish ((GSubprocess*)proc, result, + &stdout_str, &stderr_str, &data->error); + else + (void) g_subprocess_communicate_finish ((GSubprocess*)proc, result, + &stdout_bytes, &stderr_bytes, &data->error); + if (data->error) + return; + + if (data->flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE) + { + if (data->is_utf8) + { + stdout_data = (guint8*)stdout_str; + stdout_len = strlen (stdout_str); + } + else + stdout_data = g_bytes_get_data (stdout_bytes, &stdout_len); + + g_assert_cmpmem (stdout_data, stdout_len, "# hello world" LINEEND, 13 + strlen (LINEEND)); + } + else + { + g_assert_null (stdout_str); + g_assert_null (stdout_bytes); + } + + if (data->flags & G_SUBPROCESS_FLAGS_STDERR_PIPE) + { + if (data->is_utf8) + g_assert_nonnull (stderr_str); + else + g_assert_nonnull (stderr_bytes); + } + else + { + g_assert_null (stderr_str); + g_assert_null (stderr_bytes); + } + + g_clear_pointer (&stdout_bytes, g_bytes_unref); + g_clear_pointer (&stderr_bytes, g_bytes_unref); + g_free (stdout_str); + g_free (stderr_str); +} + +/* Test g_subprocess_communicate_async() works correctly with a variety of flags, + * as passed in via @test_data. */ +static void +test_communicate_async (gconstpointer test_data) +{ + GSubprocessFlags flags = GPOINTER_TO_INT (test_data); + GError *error = NULL; + GPtrArray *args; + TestAsyncCommunicateData data = { flags, 0, 0, NULL }; + GSubprocess *proc; + GCancellable *cancellable = NULL; + GBytes *input; + const char *hellostring; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + /* Include a leading hash and trailing newline so that if this gets onto the + * test’s stdout, it doesn’t mess up TAP output. */ + hellostring = "# hello world\n"; + input = g_bytes_new_static (hellostring, strlen (hellostring)); + + g_subprocess_communicate_async (proc, input, + cancellable, + on_communicate_complete, + &data); + + data.running = TRUE; + while (data.running) + g_main_context_iteration (NULL, TRUE); + + g_assert_no_error (data.error); + + g_bytes_unref (input); + g_object_unref (proc); +} + +/* Test g_subprocess_communicate() works correctly with a variety of flags, + * as passed in via @test_data. */ +static void +test_communicate (gconstpointer test_data) +{ + GSubprocessFlags flags = GPOINTER_TO_INT (test_data); + GError *error = NULL; + GPtrArray *args; + GSubprocess *proc; + GCancellable *cancellable = NULL; + GBytes *input; + const gchar *hellostring; + GBytes *stdout_bytes, *stderr_bytes; + const gchar *stdout_data; + gsize stdout_len; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + /* Include a leading hash and trailing newline so that if this gets onto the + * test’s stdout, it doesn’t mess up TAP output. */ + hellostring = "# hello world\n"; + input = g_bytes_new_static (hellostring, strlen (hellostring)); + + g_subprocess_communicate (proc, input, cancellable, &stdout_bytes, &stderr_bytes, &error); + g_assert_no_error (error); + + if (flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE) + { + stdout_data = g_bytes_get_data (stdout_bytes, &stdout_len); + g_assert_cmpmem (stdout_data, stdout_len, "# hello world" LINEEND, 13 + strlen (LINEEND)); + } + else + g_assert_null (stdout_bytes); + if (flags & G_SUBPROCESS_FLAGS_STDERR_PIPE) + g_assert_nonnull (stderr_bytes); + else + g_assert_null (stderr_bytes); + + g_bytes_unref (input); + g_clear_pointer (&stdout_bytes, g_bytes_unref); + g_clear_pointer (&stderr_bytes, g_bytes_unref); + g_object_unref (proc); +} + +typedef struct { + GSubprocess *proc; + GCancellable *cancellable; + gboolean is_utf8; + gboolean running; + GError *error; +} TestCancelledCommunicateData; + +static gboolean +on_test_communicate_cancelled_idle (gpointer user_data) +{ + TestCancelledCommunicateData *data = user_data; + GBytes *input; + const gchar *hellostring; + GBytes *stdout_bytes = NULL, *stderr_bytes = NULL; + gchar *stdout_buf = NULL, *stderr_buf = NULL; + + /* Include a leading hash and trailing newline so that if this gets onto the + * test’s stdout, it doesn’t mess up TAP output. */ + hellostring = "# hello world\n"; + input = g_bytes_new_static (hellostring, strlen (hellostring)); + + if (data->is_utf8) + g_subprocess_communicate_utf8 (data->proc, hellostring, data->cancellable, + &stdout_buf, &stderr_buf, &data->error); + else + g_subprocess_communicate (data->proc, input, data->cancellable, &stdout_bytes, + &stderr_bytes, &data->error); + + data->running = FALSE; + + if (data->is_utf8) + { + g_assert_null (stdout_buf); + g_assert_null (stderr_buf); + } + else + { + g_assert_null (stdout_bytes); + g_assert_null (stderr_bytes); + } + + g_bytes_unref (input); + + return G_SOURCE_REMOVE; +} + +/* Test g_subprocess_communicate() can be cancelled correctly */ +static void +test_communicate_cancelled (gconstpointer test_data) +{ + GSubprocessFlags flags = GPOINTER_TO_INT (test_data); + GPtrArray *args; + GSubprocess *proc; + GCancellable *cancellable = NULL; + GError *error = NULL; + TestCancelledCommunicateData data = { 0 }; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + cancellable = g_cancellable_new (); + + data.proc = proc; + data.cancellable = cancellable; + data.error = error; + + g_cancellable_cancel (cancellable); + g_idle_add (on_test_communicate_cancelled_idle, &data); + + data.running = TRUE; + while (data.running) + g_main_context_iteration (NULL, TRUE); + + g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&data.error); + + g_object_unref (cancellable); + g_object_unref (proc); +} + +static void +on_communicate_cancelled_complete (GObject *proc, + GAsyncResult *result, + gpointer user_data) +{ + TestAsyncCommunicateData *data = user_data; + GBytes *stdout_bytes = NULL, *stderr_bytes = NULL; + char *stdout_str = NULL, *stderr_str = NULL; + + data->running = FALSE; + if (data->is_utf8) + (void) g_subprocess_communicate_utf8_finish ((GSubprocess*)proc, result, + &stdout_str, &stderr_str, &data->error); + else + (void) g_subprocess_communicate_finish ((GSubprocess*)proc, result, + &stdout_bytes, &stderr_bytes, &data->error); + + if (data->is_utf8) + { + g_assert_null (stdout_str); + g_assert_null (stderr_str); + } + else + { + g_assert_null (stdout_bytes); + g_assert_null (stderr_bytes); + } +} + +/* Test g_subprocess_communicate_async() can be cancelled correctly, + * as passed in via @test_data. */ +static void +test_communicate_cancelled_async (gconstpointer test_data) +{ + GSubprocessFlags flags = GPOINTER_TO_INT (test_data); + GError *error = NULL; + GPtrArray *args; + TestAsyncCommunicateData data = { 0 }; + GSubprocess *proc; + GCancellable *cancellable = NULL; + GBytes *input; + const char *hellostring; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + /* Include a leading hash and trailing newline so that if this gets onto the + * test’s stdout, it doesn’t mess up TAP output. */ + hellostring = "# hello world\n"; + input = g_bytes_new_static (hellostring, strlen (hellostring)); + + cancellable = g_cancellable_new (); + + g_subprocess_communicate_async (proc, input, + cancellable, + on_communicate_cancelled_complete, + &data); + + g_cancellable_cancel (cancellable); + + data.running = TRUE; + while (data.running) + g_main_context_iteration (NULL, TRUE); + + g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&data.error); + + g_bytes_unref (input); + g_object_unref (cancellable); + g_object_unref (proc); +} + +/* Test g_subprocess_communicate_utf8_async() works correctly with a variety of + * flags, as passed in via @test_data. */ +static void +test_communicate_utf8_async (gconstpointer test_data) +{ + GSubprocessFlags flags = GPOINTER_TO_INT (test_data); + GError *error = NULL; + GPtrArray *args; + TestAsyncCommunicateData data = { flags, 0, 0, NULL }; + GSubprocess *proc; + GCancellable *cancellable = NULL; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + data.is_utf8 = TRUE; + g_subprocess_communicate_utf8_async (proc, "# hello world\n", + cancellable, + on_communicate_complete, + &data); + + data.running = TRUE; + while (data.running) + g_main_context_iteration (NULL, TRUE); + + g_assert_no_error (data.error); + + g_object_unref (proc); +} + +/* Test g_subprocess_communicate_utf8_async() can be cancelled correctly. */ +static void +test_communicate_utf8_cancelled_async (gconstpointer test_data) +{ + GSubprocessFlags flags = GPOINTER_TO_INT (test_data); + GError *error = NULL; + GPtrArray *args; + TestAsyncCommunicateData data = { flags, 0, 0, NULL }; + GSubprocess *proc; + GCancellable *cancellable = NULL; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + cancellable = g_cancellable_new (); + data.is_utf8 = TRUE; + g_subprocess_communicate_utf8_async (proc, "# hello world\n", + cancellable, + on_communicate_cancelled_complete, + &data); + + g_cancellable_cancel (cancellable); + + data.running = TRUE; + while (data.running) + g_main_context_iteration (NULL, TRUE); + + g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&data.error); + + g_object_unref (cancellable); + g_object_unref (proc); +} + +/* Test g_subprocess_communicate_utf8() works correctly with a variety of flags, + * as passed in via @test_data. */ +static void +test_communicate_utf8 (gconstpointer test_data) +{ + GSubprocessFlags flags = GPOINTER_TO_INT (test_data); + GError *error = NULL; + GPtrArray *args; + GSubprocess *proc; + GCancellable *cancellable = NULL; + const gchar *stdin_buf; + gchar *stdout_buf, *stderr_buf; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + /* Include a leading hash and trailing newline so that if this gets onto the + * test’s stdout, it doesn’t mess up TAP output. */ + stdin_buf = "# hello world\n"; + + g_subprocess_communicate_utf8 (proc, stdin_buf, cancellable, &stdout_buf, &stderr_buf, &error); + g_assert_no_error (error); + + if (flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE) + g_assert_cmpstr (stdout_buf, ==, "# hello world" LINEEND); + else + g_assert_null (stdout_buf); + if (flags & G_SUBPROCESS_FLAGS_STDERR_PIPE) + g_assert_nonnull (stderr_buf); + else g_assert_null (stderr_buf); + + g_free (stdout_buf); + g_free (stderr_buf); + g_object_unref (proc); +} + +/* Test g_subprocess_communicate_utf8() can be cancelled correctly */ +static void +test_communicate_utf8_cancelled (gconstpointer test_data) +{ + GSubprocessFlags flags = GPOINTER_TO_INT (test_data); + GPtrArray *args; + GSubprocess *proc; + GCancellable *cancellable = NULL; + GError *error = NULL; + TestCancelledCommunicateData data = { 0 }; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + cancellable = g_cancellable_new (); + + data.proc = proc; + data.cancellable = cancellable; + data.error = error; + + g_cancellable_cancel (cancellable); + g_idle_add (on_test_communicate_cancelled_idle, &data); + + data.is_utf8 = TRUE; + data.running = TRUE; + while (data.running) + g_main_context_iteration (NULL, TRUE); + + g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&data.error); + + g_object_unref (cancellable); + g_object_unref (proc); +} + +static void +test_communicate_nothing (void) +{ + GError *error = NULL; + GPtrArray *args; + GSubprocess *proc; + GCancellable *cancellable = NULL; + gchar *stdout_buf; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE + | G_SUBPROCESS_FLAGS_STDOUT_PIPE + | G_SUBPROCESS_FLAGS_STDERR_MERGE, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + g_subprocess_communicate_utf8 (proc, "", cancellable, &stdout_buf, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (stdout_buf, ==, ""); + + g_free (stdout_buf); + + g_object_unref (proc); +} + +static void +test_communicate_utf8_async_invalid (void) +{ + GSubprocessFlags flags = G_SUBPROCESS_FLAGS_STDOUT_PIPE; + GError *error = NULL; + GPtrArray *args; + TestAsyncCommunicateData data = { flags, 0, 0, NULL }; + GSubprocess *proc; + GCancellable *cancellable = NULL; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &error); + g_assert_no_error (error); + g_ptr_array_free (args, TRUE); + + data.is_utf8 = TRUE; + g_subprocess_communicate_utf8_async (proc, "\xFF\xFF", + cancellable, + on_communicate_complete, + &data); + + data.running = TRUE; + while (data.running) + g_main_context_iteration (NULL, TRUE); + + g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_error_free (data.error); + + g_object_unref (proc); +} + +/* Test that invalid UTF-8 received using g_subprocess_communicate_utf8() + * results in an error. */ +static void +test_communicate_utf8_invalid (void) +{ + GSubprocessFlags flags = G_SUBPROCESS_FLAGS_STDOUT_PIPE; + GError *local_error = NULL; + gboolean ret; + GPtrArray *args; + gchar *stdout_str = NULL, *stderr_str = NULL; + GSubprocess *proc; + + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_newv ((const gchar* const*)args->pdata, + G_SUBPROCESS_FLAGS_STDIN_PIPE | flags, + &local_error); + g_assert_no_error (local_error); + g_ptr_array_free (args, TRUE); + + ret = g_subprocess_communicate_utf8 (proc, "\xFF\xFF", NULL, + &stdout_str, &stderr_str, &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_error_free (local_error); + g_assert_false (ret); + + g_assert_null (stdout_str); + g_assert_null (stderr_str); + + g_object_unref (proc); +} + +static gboolean +send_terminate (gpointer user_data) +{ + GSubprocess *proc = user_data; + + g_subprocess_force_exit (proc); + + return FALSE; +} + +static void +on_request_quit_exited (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSubprocess *subprocess = G_SUBPROCESS (object); + GError *error = NULL; + + g_subprocess_wait_finish (subprocess, result, &error); + g_assert_no_error (error); +#ifdef G_OS_UNIX + g_assert_true (g_subprocess_get_if_signaled (subprocess)); + g_assert_cmpint (g_subprocess_get_term_sig (subprocess), ==, 9); +#endif + g_spawn_check_wait_status (g_subprocess_get_status (subprocess), &error); + g_assert_nonnull (error); + g_clear_error (&error); + + g_main_loop_quit ((GMainLoop*)user_data); +} + +static void +test_terminate (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocess *proc; + GPtrArray *args; + GMainLoop *loop; + const gchar *id; + + args = get_test_subprocess_args ("sleep-forever", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + id = g_subprocess_get_identifier (proc); + g_assert_nonnull (id); + + loop = g_main_loop_new (NULL, TRUE); + + g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop); + + g_timeout_add_seconds (3, send_terminate, proc); + + g_main_loop_run (loop); + + g_main_loop_unref (loop); + g_object_unref (proc); +} + +#ifdef G_OS_UNIX +static gboolean +send_signal (gpointer user_data) +{ + GSubprocess *proc = user_data; + + g_subprocess_send_signal (proc, SIGKILL); + + return FALSE; +} + +static void +test_signal (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocess *proc; + GPtrArray *args; + GMainLoop *loop; + + args = get_test_subprocess_args ("sleep-forever", NULL); + proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + loop = g_main_loop_new (NULL, TRUE); + + g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop); + + g_timeout_add_seconds (3, send_signal, proc); + + g_main_loop_run (loop); + + g_main_loop_unref (loop); + g_object_unref (proc); +} +#endif + +static void +test_env (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + GInputStream *stdout_stream; + gchar *result; + gchar *envp[] = { NULL, "ONE=1", "TWO=1", "THREE=3", "FOUR=1", NULL }; + gchar **split; + + envp[0] = g_strdup_printf ("PATH=%s", g_getenv ("PATH")); + args = get_test_subprocess_args ("env", NULL); + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); + g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE); + g_subprocess_launcher_set_environ (launcher, envp); + g_subprocess_launcher_setenv (launcher, "TWO", "2", TRUE); + g_subprocess_launcher_setenv (launcher, "THREE", "1", FALSE); + g_subprocess_launcher_unsetenv (launcher, "FOUR"); + + g_assert_null (g_subprocess_launcher_getenv (launcher, "FOUR")); + + proc = g_subprocess_launcher_spawn (launcher, error, args->pdata[0], "env", NULL); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + g_free (envp[0]); + + stdout_stream = g_subprocess_get_stdout_pipe (proc); + + result = splice_to_string (stdout_stream, error); + split = g_strsplit (result, LINEEND, -1); + g_assert_cmpstr (g_environ_getenv (split, "ONE"), ==, "1"); + g_assert_cmpstr (g_environ_getenv (split, "TWO"), ==, "2"); + g_assert_cmpstr (g_environ_getenv (split, "THREE"), ==, "3"); + g_assert_null (g_environ_getenv (split, "FOUR")); + + g_strfreev (split); + g_free (result); + g_object_unref (proc); + g_object_unref (launcher); +} + +/* Test that explicitly inheriting and modifying the parent process’ + * environment works. */ +static void +test_env_inherit (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + GInputStream *stdout_stream; + gchar *result; + gchar **split; + + g_setenv ("TEST_ENV_INHERIT1", "1", TRUE); + g_setenv ("TEST_ENV_INHERIT2", "2", TRUE); + + args = get_test_subprocess_args ("env", NULL); + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); + g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE); + g_subprocess_launcher_set_environ (launcher, NULL); + g_subprocess_launcher_setenv (launcher, "TWO", "2", TRUE); + g_subprocess_launcher_unsetenv (launcher, "TEST_ENV_INHERIT1"); + + g_assert_null (g_subprocess_launcher_getenv (launcher, "TEST_ENV_INHERIT1")); + g_assert_cmpstr (g_subprocess_launcher_getenv (launcher, "TEST_ENV_INHERIT2"), ==, "2"); + g_assert_cmpstr (g_subprocess_launcher_getenv (launcher, "TWO"), ==, "2"); + + proc = g_subprocess_launcher_spawn (launcher, error, args->pdata[0], "env", NULL); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + stdout_stream = g_subprocess_get_stdout_pipe (proc); + + result = splice_to_string (stdout_stream, error); + split = g_strsplit (result, LINEEND, -1); + g_assert_null (g_environ_getenv (split, "TEST_ENV_INHERIT1")); + g_assert_cmpstr (g_environ_getenv (split, "TEST_ENV_INHERIT2"), ==, "2"); + g_assert_cmpstr (g_environ_getenv (split, "TWO"), ==, "2"); + + g_strfreev (split); + g_free (result); + g_object_unref (proc); + g_object_unref (launcher); +} + +static void +test_cwd (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + GInputStream *stdout_stream; + gchar *result; + const char *basename; + gchar *tmp_lineend; + const gchar *tmp_lineend_basename; + + args = get_test_subprocess_args ("cwd", NULL); + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE); + g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE); + g_subprocess_launcher_set_cwd (launcher, g_get_tmp_dir ()); + tmp_lineend = g_strdup_printf ("%s%s", g_get_tmp_dir (), LINEEND); + tmp_lineend_basename = g_strrstr (tmp_lineend, G_DIR_SEPARATOR_S); + + proc = g_subprocess_launcher_spawnv (launcher, (const char * const *)args->pdata, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + stdout_stream = g_subprocess_get_stdout_pipe (proc); + + result = splice_to_string (stdout_stream, error); + + basename = g_strrstr (result, G_DIR_SEPARATOR_S); + g_assert_nonnull (basename); + g_assert_cmpstr (basename, ==, tmp_lineend_basename); + g_free (tmp_lineend); + + g_free (result); + g_object_unref (proc); + g_object_unref (launcher); +} +#ifdef G_OS_UNIX + +static void +test_subprocess_launcher_close (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + int fd, fd2; + gboolean is_open; + + /* Open two arbitrary FDs. One of them, @fd, will be transferred to the + * launcher, and the other’s FD integer will be used as its target FD, giving + * the mapping `fd → fd2` if a child process were to be spawned. + * + * The launcher will then be closed, which should close @fd but *not* @fd2, + * as the value of @fd2 is only valid as an FD in a child process. (A child + * process is not actually spawned in this test.) + */ + fd = dup (0); + fd2 = dup (0); + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); + g_subprocess_launcher_take_fd (launcher, fd, fd2); + + is_open = fcntl (fd, F_GETFD) != -1; + g_assert_true (is_open); + is_open = fcntl (fd2, F_GETFD) != -1; + g_assert_true (is_open); + + g_subprocess_launcher_close (launcher); + + is_open = fcntl (fd, F_GETFD) != -1; + g_assert_false (is_open); + is_open = fcntl (fd2, F_GETFD) != -1; + g_assert_true (is_open); + + /* Now test that actually trying to spawn the child gives %G_IO_ERROR_CLOSED, + * as g_subprocess_launcher_close() has been called. */ + args = get_test_subprocess_args ("cat", NULL); + proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + g_ptr_array_free (args, TRUE); + g_assert_null (proc); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_CLOSED); + g_clear_error (error); + + close (fd2); + g_object_unref (launcher); +} + +static void +test_stdout_file (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + GFile *tmpfile; + GFileIOStream *iostream; + GOutputStream *stdin_stream; + const char *test_data = "this is some test data\n"; + char *tmp_contents; + char *tmp_file_path; + + tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error); + g_assert_no_error (local_error); + g_clear_object (&iostream); + + tmp_file_path = g_file_get_path (tmpfile); + + args = get_test_subprocess_args ("cat", NULL); + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE); + g_subprocess_launcher_set_stdout_file_path (launcher, tmp_file_path); + proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + stdin_stream = g_subprocess_get_stdin_pipe (proc); + + g_output_stream_write_all (stdin_stream, test_data, strlen (test_data), NULL, NULL, error); + g_assert_no_error (local_error); + + g_output_stream_close (stdin_stream, NULL, error); + g_assert_no_error (local_error); + + g_subprocess_wait_check (proc, NULL, error); + + g_object_unref (launcher); + g_object_unref (proc); + + g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error); + g_assert_no_error (local_error); + + g_assert_cmpstr (test_data, ==, tmp_contents); + g_free (tmp_contents); + + (void) g_file_delete (tmpfile, NULL, NULL); + g_object_unref (tmpfile); + g_free (tmp_file_path); +} + +static void +test_stdout_fd (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + GFile *tmpfile; + GFileIOStream *iostream; + GFileDescriptorBased *descriptor_stream; + GOutputStream *stdin_stream; + const char *test_data = "this is some test data\n"; + char *tmp_contents; + + tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error); + g_assert_no_error (local_error); + + args = get_test_subprocess_args ("cat", NULL); + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE); + descriptor_stream = G_FILE_DESCRIPTOR_BASED (g_io_stream_get_output_stream (G_IO_STREAM (iostream))); + g_subprocess_launcher_take_stdout_fd (launcher, dup (g_file_descriptor_based_get_fd (descriptor_stream))); + proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + g_clear_object (&iostream); + + stdin_stream = g_subprocess_get_stdin_pipe (proc); + + g_output_stream_write_all (stdin_stream, test_data, strlen (test_data), NULL, NULL, error); + g_assert_no_error (local_error); + + g_output_stream_close (stdin_stream, NULL, error); + g_assert_no_error (local_error); + + g_subprocess_wait_check (proc, NULL, error); + + g_object_unref (launcher); + g_object_unref (proc); + + g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error); + g_assert_no_error (local_error); + + g_assert_cmpstr (test_data, ==, tmp_contents); + g_free (tmp_contents); + + (void) g_file_delete (tmpfile, NULL, NULL); + g_object_unref (tmpfile); +} + +static void +child_setup (gpointer user_data) +{ + dup2 (GPOINTER_TO_INT (user_data), 1); +} + +static void +test_child_setup (void) +{ + GError *local_error = NULL; + GError **error = &local_error; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + GFile *tmpfile; + GFileIOStream *iostream; + GOutputStream *stdin_stream; + const char *test_data = "this is some test data\n"; + char *tmp_contents; + int fd; + + tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error); + g_assert_no_error (local_error); + + fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (g_io_stream_get_output_stream (G_IO_STREAM (iostream)))); + + args = get_test_subprocess_args ("cat", NULL); + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE); + g_subprocess_launcher_set_child_setup (launcher, child_setup, GINT_TO_POINTER (fd), NULL); + proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + g_clear_object (&iostream); + + stdin_stream = g_subprocess_get_stdin_pipe (proc); + + g_output_stream_write_all (stdin_stream, test_data, strlen (test_data), NULL, NULL, error); + g_assert_no_error (local_error); + + g_output_stream_close (stdin_stream, NULL, error); + g_assert_no_error (local_error); + + g_subprocess_wait_check (proc, NULL, error); + + g_object_unref (launcher); + g_object_unref (proc); + + g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error); + g_assert_no_error (local_error); + + g_assert_cmpstr (test_data, ==, tmp_contents); + g_free (tmp_contents); + + (void) g_file_delete (tmpfile, NULL, NULL); + g_object_unref (tmpfile); +} + +static void +do_test_pass_fd (GSubprocessFlags flags, + GSpawnChildSetupFunc child_setup) +{ + GError *local_error = NULL; + GError **error = &local_error; + GInputStream *child_input; + GDataInputStream *child_datainput; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + int basic_pipefds[2]; + int needdup_pipefds[2]; + char *buf; + gsize len; + char *basic_fd_str; + char *needdup_fd_str; + + g_unix_open_pipe (basic_pipefds, FD_CLOEXEC, error); + g_assert_no_error (local_error); + g_unix_open_pipe (needdup_pipefds, FD_CLOEXEC, error); + g_assert_no_error (local_error); + + basic_fd_str = g_strdup_printf ("%d", basic_pipefds[1]); + needdup_fd_str = g_strdup_printf ("%d", needdup_pipefds[1] + 1); + + args = get_test_subprocess_args ("write-to-fds", basic_fd_str, needdup_fd_str, NULL); + launcher = g_subprocess_launcher_new (flags); + g_subprocess_launcher_take_fd (launcher, basic_pipefds[1], basic_pipefds[1]); + g_subprocess_launcher_take_fd (launcher, needdup_pipefds[1], needdup_pipefds[1] + 1); + if (child_setup != NULL) + g_subprocess_launcher_set_child_setup (launcher, child_setup, NULL, NULL); + proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error); + g_ptr_array_free (args, TRUE); + g_assert_no_error (local_error); + + g_free (basic_fd_str); + g_free (needdup_fd_str); + + child_input = g_unix_input_stream_new (basic_pipefds[0], TRUE); + child_datainput = g_data_input_stream_new (child_input); + buf = g_data_input_stream_read_line_utf8 (child_datainput, &len, NULL, error); + g_assert_no_error (local_error); + g_assert_cmpstr (buf, ==, "hello world"); + g_object_unref (child_datainput); + g_object_unref (child_input); + g_free (buf); + + child_input = g_unix_input_stream_new (needdup_pipefds[0], TRUE); + child_datainput = g_data_input_stream_new (child_input); + buf = g_data_input_stream_read_line_utf8 (child_datainput, &len, NULL, error); + g_assert_no_error (local_error); + g_assert_cmpstr (buf, ==, "hello world"); + g_free (buf); + g_object_unref (child_datainput); + g_object_unref (child_input); + + g_object_unref (launcher); + g_object_unref (proc); +} + +static void +test_pass_fd (void) +{ + do_test_pass_fd (G_SUBPROCESS_FLAGS_NONE, NULL); +} + +static void +empty_child_setup (gpointer user_data) +{ +} + +static void +test_pass_fd_empty_child_setup (void) +{ + /* Using a child setup function forces gspawn to use fork/exec + * rather than posix_spawn. + */ + do_test_pass_fd (G_SUBPROCESS_FLAGS_NONE, empty_child_setup); +} + +static void +test_pass_fd_inherit_fds (void) +{ + /* Try to test the optimized posix_spawn codepath instead of + * fork/exec. Currently this requires using INHERIT_FDS since gspawn's + * posix_spawn codepath does not currently handle closing + * non-inherited fds. Note that using INHERIT_FDS means our testing of + * g_subprocess_launcher_take_fd() is less-comprehensive than when + * using G_SUBPROCESS_FLAGS_NONE. + */ + do_test_pass_fd (G_SUBPROCESS_FLAGS_INHERIT_FDS, NULL); +} + +static void +do_test_fd_conflation (GSubprocessFlags flags, + GSpawnChildSetupFunc child_setup, + gboolean test_child_err_report_fd) +{ + char success_message[] = "Yay success!"; + GError *error = NULL; + GOutputStream *output_stream; + GSubprocessLauncher *launcher; + GSubprocess *proc; + GPtrArray *args; + int unused_pipefds[2]; + int pipefds[2]; + int fd_to_pass_to_child; + gsize bytes_written; + gboolean success; + char *fd_str; + + /* This test must run in a new process because it is extremely sensitive to + * order of opened fds. + */ + if (!g_test_subprocess ()) + { + g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR); + g_test_trap_assert_passed (); + return; + } + + g_unix_open_pipe (unused_pipefds, FD_CLOEXEC, &error); + g_assert_no_error (error); + + g_unix_open_pipe (pipefds, FD_CLOEXEC, &error); + g_assert_no_error (error); + + /* The fds should be sequential since we are in a new process. */ + g_assert_cmpint (unused_pipefds[0] /* 3 */, ==, unused_pipefds[1] - 1); + g_assert_cmpint (unused_pipefds[1] /* 4 */, ==, pipefds[0] - 1); + g_assert_cmpint (pipefds[0] /* 5 */, ==, pipefds[1] /* 6 */ - 1); + + /* Because GSubprocess allows arbitrary remapping of fds, it has to be careful + * to avoid fd conflation issues, e.g. it should properly handle 5 -> 4 and + * 4 -> 5 at the same time. GIO previously attempted to handle this by naively + * dup'ing the source fds, but this was not good enough because it was + * possible that the dup'ed result could still conflict with one of the target + * fds. For example: + * + * source_fd 5 -> target_fd 9, source_fd 3 -> target_fd 7 + * + * dup(5) -> dup returns 8 + * dup(3) -> dup returns 9 + * + * After dup'ing, we wind up with: 8 -> 9, 9 -> 7. That means that after we + * dup2(8, 9), we have clobbered fd 9 before we dup2(9, 7). The end result is + * we have remapped 5 -> 9 as expected, but then remapped 5 -> 7 instead of + * 3 -> 7 as the application intended. + * + * This issue has been fixed in the simplest way possible, by passing a + * minimum fd value when using F_DUPFD_CLOEXEC that is higher than any of the + * target fds, to guarantee all source fds are different than all target fds, + * eliminating any possibility of conflation. + * + * Anyway, that is why we have the unused_pipefds here. We need to open fds in + * a certain order in order to trick older GSubprocess into conflating the + * fds. The primary goal of this test is to ensure this particular conflation + * issue is not reintroduced. See glib#2503. + * + * This test also has an alternate mode of operation where it instead tests + * for conflation with gspawn's child_err_report_fd, glib#2506. + * + * Be aware this test is necessarily extremely fragile. To reproduce these + * bugs, it relies on internals of gspawn and gmain that will likely change + * in the future, eventually causing this test to no longer test the bugs + * it was originally designed to test. That is OK! If the test fails, at + * least you know *something* is wrong. + */ + if (test_child_err_report_fd) + fd_to_pass_to_child = pipefds[1] + 2 /* 8 */; + else + fd_to_pass_to_child = pipefds[1] + 3 /* 9 */; + + launcher = g_subprocess_launcher_new (flags); + g_subprocess_launcher_take_fd (launcher, pipefds[0] /* 5 */, fd_to_pass_to_child); + g_subprocess_launcher_take_fd (launcher, unused_pipefds[0] /* 3 */, pipefds[1] + 1 /* 7 */); + if (child_setup != NULL) + g_subprocess_launcher_set_child_setup (launcher, child_setup, NULL, NULL); + fd_str = g_strdup_printf ("%d", fd_to_pass_to_child); + args = get_test_subprocess_args ("read-from-fd", fd_str, NULL); + proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, &error); + g_assert_no_error (error); + g_assert_nonnull (proc); + g_ptr_array_free (args, TRUE); + g_object_unref (launcher); + g_free (fd_str); + + /* Close the read ends of the pipes. */ + close (unused_pipefds[0]); + close (pipefds[0]); + + /* Also close the write end of the unused pipe. */ + close (unused_pipefds[1]); + + /* If doing our normal test: + * + * So now pipefds[0] should be inherited into the subprocess as + * pipefds[1] + 2, and unused_pipefds[0] should be inherited as + * pipefds[1] + 1. We will write to pipefds[1] and the subprocess will verify + * that it reads the expected data. But older broken GIO will accidentally + * clobber pipefds[1] + 2 with pipefds[1] + 1! This will cause the subprocess + * to hang trying to read from the wrong pipe. + * + * If testing conflation with child_err_report_fd: + * + * We are actually already done. The real test succeeded if we made it this + * far without hanging while spawning the child. But let's continue with our + * write and read anyway, to ensure things are good. + */ + output_stream = g_unix_output_stream_new (pipefds[1], TRUE); + success = g_output_stream_write_all (output_stream, + success_message, sizeof (success_message), + &bytes_written, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpint (bytes_written, ==, sizeof (success_message)); + g_assert_true (success); + g_object_unref (output_stream); + + success = g_subprocess_wait_check (proc, NULL, &error); + g_assert_no_error (error); + g_object_unref (proc); +} + +static void +test_fd_conflation (void) +{ + do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, NULL, FALSE); +} + +static void +test_fd_conflation_empty_child_setup (void) +{ + /* Using a child setup function forces gspawn to use fork/exec + * rather than posix_spawn. + */ + do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, empty_child_setup, FALSE); +} + +static void +test_fd_conflation_inherit_fds (void) +{ + /* Try to test the optimized posix_spawn codepath instead of + * fork/exec. Currently this requires using INHERIT_FDS since gspawn's + * posix_spawn codepath does not currently handle closing + * non-inherited fds. + */ + do_test_fd_conflation (G_SUBPROCESS_FLAGS_INHERIT_FDS, NULL, FALSE); +} + +static void +test_fd_conflation_child_err_report_fd (void) +{ + /* Using a child setup function forces gspawn to use fork/exec + * rather than posix_spawn. + */ + do_test_fd_conflation (G_SUBPROCESS_FLAGS_NONE, empty_child_setup, TRUE); +} + +#endif + +static void +test_launcher_environment (void) +{ + GSubprocessLauncher *launcher; + GError *error = NULL; + GSubprocess *proc; + GPtrArray *args; + gchar *out; + + g_setenv ("A", "B", TRUE); + g_setenv ("C", "D", TRUE); + + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE); + + /* unset a variable */ + g_subprocess_launcher_unsetenv (launcher, "A"); + + /* and set a different one */ + g_subprocess_launcher_setenv (launcher, "E", "F", TRUE); + + args = get_test_subprocess_args ("printenv", "A", "C", "E", NULL); + proc = g_subprocess_launcher_spawnv (launcher, (const gchar **) args->pdata, &error); + g_assert_no_error (error); + g_assert_nonnull (proc); + + g_subprocess_communicate_utf8 (proc, NULL, NULL, &out, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (out, ==, "C=D" LINEEND "E=F" LINEEND); + g_free (out); + + g_object_unref (proc); + g_object_unref (launcher); + g_ptr_array_unref (args); +} + +int +main (int argc, char **argv) +{ + const struct + { + const gchar *subtest; + GSubprocessFlags flags; + } + flags_vectors[] = + { + { "", G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_MERGE }, + { "/no-pipes", G_SUBPROCESS_FLAGS_NONE }, + { "/separate-stderr", G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE }, + { "/stdout-only", G_SUBPROCESS_FLAGS_STDOUT_PIPE }, + { "/stderr-only", G_SUBPROCESS_FLAGS_STDERR_PIPE }, + { "/stdout-silence", G_SUBPROCESS_FLAGS_STDOUT_SILENCE }, + }; + gsize i; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gsubprocess/noop", test_noop); + g_test_add_func ("/gsubprocess/noop-all-to-null", test_noop_all_to_null); + g_test_add_func ("/gsubprocess/noop-no-wait", test_noop_no_wait); + g_test_add_func ("/gsubprocess/noop-stdin-inherit", test_noop_stdin_inherit); +#ifdef G_OS_UNIX + g_test_add_func ("/gsubprocess/search-path", test_search_path); + g_test_add_func ("/gsubprocess/search-path-from-envp", test_search_path_from_envp); + g_test_add_func ("/gsubprocess/signal", test_signal); +#endif + g_test_add_func ("/gsubprocess/exit1", test_exit1); + g_test_add_func ("/gsubprocess/exit1/cancel", test_exit1_cancel); + g_test_add_func ("/gsubprocess/exit1/cancel_in_cb", test_exit1_cancel_in_cb); + g_test_add_func ("/gsubprocess/echo1", test_echo1); +#ifdef G_OS_UNIX + g_test_add_func ("/gsubprocess/echo-merged", test_echo_merged); +#endif + g_test_add_func ("/gsubprocess/cat-utf8", test_cat_utf8); + g_test_add_func ("/gsubprocess/cat-eof", test_cat_eof); + g_test_add_func ("/gsubprocess/multi1", test_multi_1); + + /* Add various tests for g_subprocess_communicate() with different flags. */ + for (i = 0; i < G_N_ELEMENTS (flags_vectors); i++) + { + gchar *test_path = NULL; + + test_path = g_strdup_printf ("/gsubprocess/communicate%s", flags_vectors[i].subtest); + g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags), + test_communicate); + g_free (test_path); + + test_path = g_strdup_printf ("/gsubprocess/communicate/cancelled%s", flags_vectors[i].subtest); + g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags), + test_communicate_cancelled); + g_free (test_path); + + test_path = g_strdup_printf ("/gsubprocess/communicate/async%s", flags_vectors[i].subtest); + g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags), + test_communicate_async); + g_free (test_path); + + test_path = g_strdup_printf ("/gsubprocess/communicate/async/cancelled%s", flags_vectors[i].subtest); + g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags), + test_communicate_cancelled_async); + g_free (test_path); + + test_path = g_strdup_printf ("/gsubprocess/communicate/utf8%s", flags_vectors[i].subtest); + g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags), + test_communicate_utf8); + g_free (test_path); + + test_path = g_strdup_printf ("/gsubprocess/communicate/utf8/cancelled%s", flags_vectors[i].subtest); + g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags), + test_communicate_utf8_cancelled); + g_free (test_path); + + test_path = g_strdup_printf ("/gsubprocess/communicate/utf8/async%s", flags_vectors[i].subtest); + g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags), + test_communicate_utf8_async); + g_free (test_path); + + test_path = g_strdup_printf ("/gsubprocess/communicate/utf8/async/cancelled%s", flags_vectors[i].subtest); + g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags), + test_communicate_utf8_cancelled_async); + g_free (test_path); + } + + g_test_add_func ("/gsubprocess/communicate/utf8/async/invalid", test_communicate_utf8_async_invalid); + g_test_add_func ("/gsubprocess/communicate/utf8/invalid", test_communicate_utf8_invalid); + g_test_add_func ("/gsubprocess/communicate/nothing", test_communicate_nothing); + g_test_add_func ("/gsubprocess/terminate", test_terminate); + g_test_add_func ("/gsubprocess/env", test_env); + g_test_add_func ("/gsubprocess/env/inherit", test_env_inherit); + g_test_add_func ("/gsubprocess/cwd", test_cwd); +#ifdef G_OS_UNIX + g_test_add_func ("/gsubprocess/launcher-close", test_subprocess_launcher_close); + g_test_add_func ("/gsubprocess/stdout-file", test_stdout_file); + g_test_add_func ("/gsubprocess/stdout-fd", test_stdout_fd); + g_test_add_func ("/gsubprocess/child-setup", test_child_setup); + g_test_add_func ("/gsubprocess/pass-fd/basic", test_pass_fd); + g_test_add_func ("/gsubprocess/pass-fd/empty-child-setup", test_pass_fd_empty_child_setup); + g_test_add_func ("/gsubprocess/pass-fd/inherit-fds", test_pass_fd_inherit_fds); + g_test_add_func ("/gsubprocess/fd-conflation/basic", test_fd_conflation); + g_test_add_func ("/gsubprocess/fd-conflation/empty-child-setup", test_fd_conflation_empty_child_setup); + g_test_add_func ("/gsubprocess/fd-conflation/inherit-fds", test_fd_conflation_inherit_fds); + g_test_add_func ("/gsubprocess/fd-conflation/child-err-report-fd", test_fd_conflation_child_err_report_fd); +#endif + g_test_add_func ("/gsubprocess/launcher-environment", test_launcher_environment); + + return g_test_run (); +} diff --git a/gio/tests/gtesttlsbackend.c b/gio/tests/gtesttlsbackend.c new file mode 100644 index 0000000..6c48c23 --- /dev/null +++ b/gio/tests/gtesttlsbackend.c @@ -0,0 +1,522 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "gtesttlsbackend.h" + +#include + +static GType _g_test_tls_certificate_get_type (void); +static GType _g_test_tls_connection_get_type (void); +static GTlsDatabase * _g_test_tls_backend_get_default_database (GTlsBackend * backend); +static GType _g_test_tls_database_get_type (void); + +struct _GTestTlsBackend { + GObject parent_instance; +}; + +static void g_test_tls_backend_iface_init (GTlsBackendInterface *iface); + +#define g_test_tls_backend_get_type _g_test_tls_backend_get_type +G_DEFINE_TYPE_WITH_CODE (GTestTlsBackend, g_test_tls_backend, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_TLS_BACKEND, + g_test_tls_backend_iface_init) + g_io_extension_point_set_required_type ( + g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME), + G_TYPE_TLS_BACKEND); + g_io_extension_point_implement (G_TLS_BACKEND_EXTENSION_POINT_NAME, + g_define_type_id, + "test", + 999);) + +static void +g_test_tls_backend_init (GTestTlsBackend *backend) +{ +} + +static void +g_test_tls_backend_class_init (GTestTlsBackendClass *backend_class) +{ +} + +static void +g_test_tls_backend_iface_init (GTlsBackendInterface *iface) +{ + iface->get_certificate_type = _g_test_tls_certificate_get_type; + iface->get_client_connection_type = _g_test_tls_connection_get_type; + iface->get_server_connection_type = _g_test_tls_connection_get_type; + iface->get_dtls_client_connection_type = _g_test_tls_connection_get_type; + iface->get_dtls_server_connection_type = _g_test_tls_connection_get_type; + iface->get_default_database = _g_test_tls_backend_get_default_database; + iface->get_file_database_type = _g_test_tls_database_get_type; +} + +static GTlsDatabase * +_g_test_tls_backend_get_default_database (GTlsBackend * backend) +{ + static GTlsDatabase *default_db; + GError *error = NULL; + + if (!default_db) + { + default_db = g_initable_new (_g_test_tls_database_get_type (), + NULL, + &error, + NULL); + g_assert_no_error (error); + } + + return default_db; +} + +/* Test certificate type */ + +typedef struct _GTestTlsCertificate GTestTlsCertificate; +typedef struct _GTestTlsCertificateClass GTestTlsCertificateClass; + +struct _GTestTlsCertificate { + GTlsCertificate parent_instance; + gchar *key_pem; + gchar *cert_pem; + GTlsCertificate *issuer; + gchar *pkcs11_uri; + gchar *private_key_pkcs11_uri; +}; + +struct _GTestTlsCertificateClass { + GTlsCertificateClass parent_class; +}; + +enum +{ + PROP_CERT_CERTIFICATE = 1, + PROP_CERT_CERTIFICATE_PEM, + PROP_CERT_PRIVATE_KEY, + PROP_CERT_PRIVATE_KEY_PEM, + PROP_CERT_ISSUER, + PROP_CERT_PKCS11_URI, + PROP_CERT_PRIVATE_KEY_PKCS11_URI, + PROP_CERT_NOT_VALID_BEFORE, + PROP_CERT_NOT_VALID_AFTER, + PROP_CERT_SUBJECT_NAME, + PROP_CERT_ISSUER_NAME, + PROP_CERT_DNS_NAMES, + PROP_CERT_IP_ADDRESSES, +}; + +static void g_test_tls_certificate_initable_iface_init (GInitableIface *iface); + +#define g_test_tls_certificate_get_type _g_test_tls_certificate_get_type +G_DEFINE_TYPE_WITH_CODE (GTestTlsCertificate, g_test_tls_certificate, G_TYPE_TLS_CERTIFICATE, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_test_tls_certificate_initable_iface_init)) + +static GTlsCertificateFlags +g_test_tls_certificate_verify (GTlsCertificate *cert, + GSocketConnectable *identity, + GTlsCertificate *trusted_ca) +{ + /* For now, all of the tests expect the certificate to verify */ + return 0; +} + +static void +g_test_tls_certificate_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTestTlsCertificate *cert = (GTestTlsCertificate *) object; + GPtrArray *data = NULL; + const gchar *dns_name = "a.example.com"; + + switch (prop_id) + { + case PROP_CERT_CERTIFICATE_PEM: + g_value_set_string (value, cert->cert_pem); + break; + case PROP_CERT_PRIVATE_KEY_PEM: + g_value_set_string (value, cert->key_pem); + break; + case PROP_CERT_ISSUER: + g_value_set_object (value, cert->issuer); + break; + case PROP_CERT_PKCS11_URI: + /* This test value simulates a backend that ignores the value + because it is unsupported */ + if (g_strcmp0 (cert->pkcs11_uri, "unsupported") != 0) + g_value_set_string (value, cert->pkcs11_uri); + break; + case PROP_CERT_PRIVATE_KEY_PKCS11_URI: + g_value_set_string (value, cert->private_key_pkcs11_uri); + break; + case PROP_CERT_NOT_VALID_BEFORE: + g_value_take_boxed (value, g_date_time_new_from_iso8601 ("2020-10-12T17:49:44Z", NULL)); + break; + case PROP_CERT_NOT_VALID_AFTER: + g_value_take_boxed (value, g_date_time_new_from_iso8601 ("2045-10-06T17:49:44Z", NULL)); + break; + case PROP_CERT_SUBJECT_NAME: + g_value_set_string (value, "DC=COM,DC=EXAMPLE,CN=server.example.com"); + break; + case PROP_CERT_ISSUER_NAME: + g_value_set_string (value, "DC=COM,DC=EXAMPLE,OU=Certificate Authority,CN=ca.example.com,emailAddress=ca@example.com"); + break; + case PROP_CERT_DNS_NAMES: + data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref); + g_ptr_array_add (data, g_bytes_new_static (dns_name, strlen (dns_name))); + g_value_take_boxed (value, data); + break; + case PROP_CERT_IP_ADDRESSES: + data = g_ptr_array_new_with_free_func (g_object_unref); + g_ptr_array_add (data, g_inet_address_new_from_string ("192.0.2.1")); + g_value_take_boxed (value, data); + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +g_test_tls_certificate_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTestTlsCertificate *cert = (GTestTlsCertificate *) object; + + switch (prop_id) + { + case PROP_CERT_CERTIFICATE_PEM: + cert->cert_pem = g_value_dup_string (value); + break; + case PROP_CERT_PRIVATE_KEY_PEM: + cert->key_pem = g_value_dup_string (value); + break; + case PROP_CERT_ISSUER: + cert->issuer = g_value_dup_object (value); + break; + case PROP_CERT_PKCS11_URI: + cert->pkcs11_uri = g_value_dup_string (value); + break; + case PROP_CERT_PRIVATE_KEY_PKCS11_URI: + cert->private_key_pkcs11_uri = g_value_dup_string (value); + break; + case PROP_CERT_CERTIFICATE: + case PROP_CERT_PRIVATE_KEY: + /* ignore */ + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +g_test_tls_certificate_finalize (GObject *object) +{ + GTestTlsCertificate *cert = (GTestTlsCertificate *) object; + + g_free (cert->cert_pem); + g_free (cert->key_pem); + g_free (cert->pkcs11_uri); + g_free (cert->private_key_pkcs11_uri); + g_clear_object (&cert->issuer); + + G_OBJECT_CLASS (g_test_tls_certificate_parent_class)->finalize (object); +} + +static void +g_test_tls_certificate_class_init (GTestTlsCertificateClass *test_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (test_class); + GTlsCertificateClass *certificate_class = G_TLS_CERTIFICATE_CLASS (test_class); + + gobject_class->get_property = g_test_tls_certificate_get_property; + gobject_class->set_property = g_test_tls_certificate_set_property; + gobject_class->finalize = g_test_tls_certificate_finalize; + + certificate_class->verify = g_test_tls_certificate_verify; + + g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE, "certificate"); + g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE_PEM, "certificate-pem"); + g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY, "private-key"); + g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PEM, "private-key-pem"); + g_object_class_override_property (gobject_class, PROP_CERT_ISSUER, "issuer"); + g_object_class_override_property (gobject_class, PROP_CERT_PKCS11_URI, "pkcs11-uri"); + g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PKCS11_URI, "private-key-pkcs11-uri"); + g_object_class_override_property (gobject_class, PROP_CERT_NOT_VALID_BEFORE, "not-valid-before"); + g_object_class_override_property (gobject_class, PROP_CERT_NOT_VALID_AFTER, "not-valid-after"); + g_object_class_override_property (gobject_class, PROP_CERT_SUBJECT_NAME, "subject-name"); + g_object_class_override_property (gobject_class, PROP_CERT_ISSUER_NAME, "issuer-name"); + g_object_class_override_property (gobject_class, PROP_CERT_DNS_NAMES, "dns-names"); + g_object_class_override_property (gobject_class, PROP_CERT_IP_ADDRESSES, "ip-addresses"); +} + +static void +g_test_tls_certificate_init (GTestTlsCertificate *certificate) +{ +} + +static gboolean +g_test_tls_certificate_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + return TRUE; +} + +static void +g_test_tls_certificate_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_test_tls_certificate_initable_init; +} + +/* Dummy connection type; since GTlsClientConnection and + * GTlsServerConnection are just interfaces, we can implement them + * both on a single object. + */ + +typedef struct _GTestTlsConnection GTestTlsConnection; +typedef struct _GTestTlsConnectionClass GTestTlsConnectionClass; + +struct _GTestTlsConnection { + GTlsConnection parent_instance; +}; + +struct _GTestTlsConnectionClass { + GTlsConnectionClass parent_class; +}; + +enum +{ + PROP_CONN_BASE_IO_STREAM = 1, + PROP_CONN_BASE_SOCKET, + PROP_CONN_USE_SYSTEM_CERTDB, + PROP_CONN_REQUIRE_CLOSE_NOTIFY, + PROP_CONN_REHANDSHAKE_MODE, + PROP_CONN_CERTIFICATE, + PROP_CONN_PEER_CERTIFICATE, + PROP_CONN_PEER_CERTIFICATE_ERRORS, + PROP_CONN_VALIDATION_FLAGS, + PROP_CONN_SERVER_IDENTITY, + PROP_CONN_USE_SSL3, + PROP_CONN_ACCEPTED_CAS, + PROP_CONN_AUTHENTICATION_MODE +}; + +static void g_test_tls_connection_initable_iface_init (GInitableIface *iface); + +#define g_test_tls_connection_get_type _g_test_tls_connection_get_type +G_DEFINE_TYPE_WITH_CODE (GTestTlsConnection, g_test_tls_connection, G_TYPE_TLS_CONNECTION, + G_IMPLEMENT_INTERFACE (G_TYPE_TLS_CLIENT_CONNECTION, NULL) + G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION, NULL) + G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED, NULL) + G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_CONNECTION, NULL) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_test_tls_connection_initable_iface_init)) + +static void +g_test_tls_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ +} + +static void +g_test_tls_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ +} + +static gboolean +g_test_tls_connection_close (GIOStream *stream, + GCancellable *cancellable, + GError **error) +{ + return TRUE; +} + +static void +g_test_tls_connection_class_init (GTestTlsConnectionClass *connection_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (connection_class); + GIOStreamClass *io_stream_class = G_IO_STREAM_CLASS (connection_class); + + gobject_class->get_property = g_test_tls_connection_get_property; + gobject_class->set_property = g_test_tls_connection_set_property; + + /* Need to override this because when initable_init fails it will + * dispose the connection, which will close it, which would + * otherwise try to close its input/output streams, which don't + * exist. + */ + io_stream_class->close_fn = g_test_tls_connection_close; + + g_object_class_override_property (gobject_class, PROP_CONN_BASE_IO_STREAM, "base-io-stream"); + g_object_class_override_property (gobject_class, PROP_CONN_BASE_SOCKET, "base-socket"); + g_object_class_override_property (gobject_class, PROP_CONN_USE_SYSTEM_CERTDB, "use-system-certdb"); + g_object_class_override_property (gobject_class, PROP_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify"); + g_object_class_override_property (gobject_class, PROP_CONN_REHANDSHAKE_MODE, "rehandshake-mode"); + g_object_class_override_property (gobject_class, PROP_CONN_CERTIFICATE, "certificate"); + g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE, "peer-certificate"); + g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors"); + g_object_class_override_property (gobject_class, PROP_CONN_VALIDATION_FLAGS, "validation-flags"); + g_object_class_override_property (gobject_class, PROP_CONN_SERVER_IDENTITY, "server-identity"); + g_object_class_override_property (gobject_class, PROP_CONN_USE_SSL3, "use-ssl3"); + g_object_class_override_property (gobject_class, PROP_CONN_ACCEPTED_CAS, "accepted-cas"); + g_object_class_override_property (gobject_class, PROP_CONN_AUTHENTICATION_MODE, "authentication-mode"); +} + +static void +g_test_tls_connection_init (GTestTlsConnection *connection) +{ +} + +static gboolean +g_test_tls_connection_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE, + "TLS Connection support is not available"); + return FALSE; +} + +static void +g_test_tls_connection_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_test_tls_connection_initable_init; +} + +/* Test database type */ + +typedef struct _GTestTlsDatabase GTestTlsDatabase; +typedef struct _GTestTlsDatabaseClass GTestTlsDatabaseClass; + +struct _GTestTlsDatabase { + GTlsDatabase parent_instance; + gchar *anchors; +}; + +struct _GTestTlsDatabaseClass { + GTlsDatabaseClass parent_class; +}; + +enum +{ + PROP_DATABASE_ANCHORS = 1, +}; + +static void g_test_tls_database_initable_iface_init (GInitableIface *iface); +static void g_test_tls_file_database_file_database_interface_init (GInitableIface *iface); + +#define g_test_tls_database_get_type _g_test_tls_database_get_type +G_DEFINE_TYPE_WITH_CODE (GTestTlsDatabase, g_test_tls_database, G_TYPE_TLS_DATABASE, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + g_test_tls_database_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE, + g_test_tls_file_database_file_database_interface_init)) + +static void +g_test_tls_database_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTestTlsDatabase *db = (GTestTlsDatabase *) object; + + switch (prop_id) + { + case PROP_DATABASE_ANCHORS: + g_value_set_string (value, db->anchors); + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +g_test_tls_database_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTestTlsDatabase *db = (GTestTlsDatabase *) object; + + switch (prop_id) + { + case PROP_DATABASE_ANCHORS: + g_free (db->anchors); + db->anchors = g_value_dup_string (value); + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +g_test_tls_database_finalize (GObject *object) +{ + GTestTlsDatabase *db = (GTestTlsDatabase *) object; + + g_free (db->anchors); + + G_OBJECT_CLASS (g_test_tls_database_parent_class)->finalize (object); +} + +static void +g_test_tls_database_class_init (GTestTlsDatabaseClass *test_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (test_class); + + gobject_class->get_property = g_test_tls_database_get_property; + gobject_class->set_property = g_test_tls_database_set_property; + gobject_class->finalize = g_test_tls_database_finalize; + + g_object_class_override_property (gobject_class, PROP_DATABASE_ANCHORS, "anchors"); +} + +static void +g_test_tls_database_init (GTestTlsDatabase *database) +{ +} + +static gboolean +g_test_tls_database_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + return TRUE; +} + +static void +g_test_tls_file_database_file_database_interface_init (GInitableIface *iface) +{ +} + +static void +g_test_tls_database_initable_iface_init (GInitableIface *iface) +{ + iface->init = g_test_tls_database_initable_init; +} diff --git a/gio/tests/gtesttlsbackend.h b/gio/tests/gtesttlsbackend.h new file mode 100644 index 0000000..07948fd --- /dev/null +++ b/gio/tests/gtesttlsbackend.h @@ -0,0 +1,44 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_TEST_TLS_BACKEND_H__ +#define __G_TEST_TLS_BACKEND_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TEST_TLS_BACKEND (_g_test_tls_backend_get_type ()) +#define G_TEST_TLS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TEST_TLS_BACKEND, GTestTlsBackend)) +#define G_TEST_TLS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TEST_TLS_BACKEND, GTestTlsBackendClass)) +#define G_IS_TEST_TLS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TEST_TLS_BACKEND)) +#define G_IS_TEST_TLS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TEST_TLS_BACKEND)) +#define G_TEST_TLS_BACKEND_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TEST_TLS_BACKEND, GTestTlsBackendClass)) + +typedef struct _GTestTlsBackend GTestTlsBackend; +typedef struct _GTestTlsBackendClass GTestTlsBackendClass; + +struct _GTestTlsBackendClass { + GObjectClass parent_class; +}; + +GType _g_test_tls_backend_get_type (void); + +G_END_DECLS + +#endif /* __G_TEST_TLS_BACKEND_H__ */ diff --git a/gio/tests/gtlsconsoleinteraction.c b/gio/tests/gtlsconsoleinteraction.c new file mode 100644 index 0000000..4a12ea8 --- /dev/null +++ b/gio/tests/gtlsconsoleinteraction.c @@ -0,0 +1,162 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#include "config.h" + +#include +#include +#include + +#ifdef G_OS_WIN32 +#include +#endif + +#include "gtlsconsoleinteraction.h" + +/* + * WARNING: This is not the example you're looking for [slow hand wave]. This + * is not industrial strength, it's just for testing. It uses embarrassing + * functions like getpass() and does lazy things with threads. + */ + +G_DEFINE_TYPE (GTlsConsoleInteraction, g_tls_console_interaction, G_TYPE_TLS_INTERACTION) + +#if defined(G_OS_WIN32) || defined(__BIONIC__) +/* win32 doesn't have getpass() */ +#include +#ifndef BUFSIZ +#define BUFSIZ 8192 +#endif +static gchar * +getpass (const gchar *prompt) +{ + static gchar buf[BUFSIZ]; + gint i; + + g_printf ("%s", prompt); + fflush (stdout); + + for (i = 0; i < BUFSIZ - 1; ++i) + { +#ifdef __BIONIC__ + buf[i] = getc (stdin); +#else + buf[i] = _getch (); +#endif + if (buf[i] == '\r') + break; + } + buf[i] = '\0'; + + g_printf ("\n"); + + return &buf[0]; +} +#endif + +static GTlsInteractionResult +g_tls_console_interaction_ask_password (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GError **error) +{ + const gchar *value; + gchar *prompt; + + prompt = g_strdup_printf ("Password \"%s\"': ", g_tls_password_get_description (password)); + value = getpass (prompt); + g_free (prompt); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return G_TLS_INTERACTION_FAILED; + + g_tls_password_set_value (password, (guchar *)value, -1); + return G_TLS_INTERACTION_HANDLED; +} + +static void +ask_password_with_getpass (GTask *task, + gpointer object, + gpointer task_data, + GCancellable *cancellable) +{ + GTlsPassword *password = task_data; + GError *error = NULL; + + g_tls_console_interaction_ask_password (G_TLS_INTERACTION (object), password, + cancellable, &error); + if (error != NULL) + g_task_return_error (task, error); + else + g_task_return_int (task, G_TLS_INTERACTION_HANDLED); +} + +static void +g_tls_console_interaction_ask_password_async (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (interaction, cancellable, callback, user_data); + g_task_set_task_data (task, g_object_ref (password), g_object_unref); + g_task_run_in_thread (task, ask_password_with_getpass); + g_object_unref (task); +} + +static GTlsInteractionResult +g_tls_console_interaction_ask_password_finish (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error) +{ + GTlsInteractionResult ret; + + g_return_val_if_fail (g_task_is_valid (result, interaction), + G_TLS_INTERACTION_FAILED); + + ret = g_task_propagate_int (G_TASK (result), error); + if (ret == (GTlsInteractionResult)-1) + return G_TLS_INTERACTION_FAILED; + else + return ret; +} + +static void +g_tls_console_interaction_init (GTlsConsoleInteraction *interaction) +{ + +} + +static void +g_tls_console_interaction_class_init (GTlsConsoleInteractionClass *klass) +{ + GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass); + interaction_class->ask_password = g_tls_console_interaction_ask_password; + interaction_class->ask_password_async = g_tls_console_interaction_ask_password_async; + interaction_class->ask_password_finish = g_tls_console_interaction_ask_password_finish; +} + +GTlsInteraction * +g_tls_console_interaction_new (void) +{ + return g_object_new (G_TYPE_TLS_CONSOLE_INTERACTION, NULL); +} diff --git a/gio/tests/gtlsconsoleinteraction.h b/gio/tests/gtlsconsoleinteraction.h new file mode 100644 index 0000000..7860ba2 --- /dev/null +++ b/gio/tests/gtlsconsoleinteraction.h @@ -0,0 +1,54 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2011 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#ifndef __G_TLS_CONSOLE_INTERACTION_H__ +#define __G_TLS_CONSOLE_INTERACTION_H__ + +#include + +G_BEGIN_DECLS + +#define G_TYPE_TLS_CONSOLE_INTERACTION (g_tls_console_interaction_get_type ()) +#define G_TLS_CONSOLE_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteraction)) +#define G_TLS_CONSOLE_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteractionClass)) +#define G_IS_TLS_CONSOLE_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_CONSOLE_INTERACTION)) +#define G_IS_TLS_CONSOLE_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_CONSOLE_INTERACTION)) +#define G_TLS_CONSOLE_INTERACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteractionClass)) + +typedef struct _GTlsConsoleInteraction GTlsConsoleInteraction; +typedef struct _GTlsConsoleInteractionClass GTlsConsoleInteractionClass; + +struct _GTlsConsoleInteraction +{ + GTlsInteraction parent_instance; +}; + +struct _GTlsConsoleInteractionClass +{ + GTlsInteractionClass parent_class; +}; + +GType g_tls_console_interaction_get_type (void) G_GNUC_CONST; + +GTlsInteraction * g_tls_console_interaction_new (void); + +G_END_DECLS + +#endif /* __G_TLS_CONSOLE_INTERACTION_H__ */ diff --git a/gio/tests/httpd.c b/gio/tests/httpd.c new file mode 100644 index 0000000..6658e15 --- /dev/null +++ b/gio/tests/httpd.c @@ -0,0 +1,188 @@ +#include +#include + +static int port = 8080; +static char *root = NULL; +static GOptionEntry cmd_entries[] = { + {"port", 'p', 0, G_OPTION_ARG_INT, &port, + "Local port to bind to", NULL}, + G_OPTION_ENTRY_NULL +}; + +static void +send_error (GOutputStream *out, + int error_code, + const char *reason) +{ + char *res; + + res = g_strdup_printf ("HTTP/1.0 %d %s\r\n\r\n" + "%d %s" + "%s", + error_code, reason, + error_code, reason, + reason); + g_output_stream_write_all (out, res, strlen (res), NULL, NULL, NULL); + g_free (res); +} + +static gboolean +handler (GThreadedSocketService *service, + GSocketConnection *connection, + GSocketListener *listener, + gpointer user_data) +{ + GOutputStream *out; + GInputStream *in; + GFileInputStream *file_in; + GDataInputStream *data; + char *line, *escaped, *tmp, *query, *unescaped, *path, *version; + GFile *f; + GError *error; + GFileInfo *info; + GString *s; + + in = g_io_stream_get_input_stream (G_IO_STREAM (connection)); + out = g_io_stream_get_output_stream (G_IO_STREAM (connection)); + + data = g_data_input_stream_new (in); + /* Be tolerant of input */ + g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_ANY); + + line = g_data_input_stream_read_line (data, NULL, NULL, NULL); + + if (line == NULL) + { + send_error (out, 400, "Invalid request"); + goto out; + } + + if (!g_str_has_prefix (line, "GET ")) + { + send_error (out, 501, "Only GET implemented"); + goto out; + } + + escaped = line + 4; /* Skip "GET " */ + + version = NULL; + tmp = strchr (escaped, ' '); + if (tmp == NULL) + { + send_error (out, 400, "Bad Request"); + goto out; + } + *tmp = 0; + + version = tmp + 1; + if (!g_str_has_prefix (version, "HTTP/1.")) + { + send_error(out, 505, "HTTP Version Not Supported"); + goto out; + } + + query = strchr (escaped, '?'); + if (query != NULL) + *query++ = 0; + + unescaped = g_uri_unescape_string (escaped, NULL); + path = g_build_filename (root, unescaped, NULL); + g_free (unescaped); + f = g_file_new_for_path (path); + g_free (path); + + error = NULL; + file_in = g_file_read (f, NULL, &error); + if (file_in == NULL) + { + send_error (out, 404, error->message); + g_error_free (error); + goto out; + } + + s = g_string_new ("HTTP/1.0 200 OK\r\n"); + info = g_file_input_stream_query_info (file_in, + G_FILE_ATTRIBUTE_STANDARD_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + NULL, NULL); + if (info) + { + const char *content_type; + char *mime_type; + + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)) + g_string_append_printf (s, "Content-Length: %"G_GINT64_FORMAT"\r\n", + g_file_info_get_size (info)); + content_type = g_file_info_get_content_type (info); + if (content_type) + { + mime_type = g_content_type_get_mime_type (content_type); + if (mime_type) + { + g_string_append_printf (s, "Content-Type: %s\r\n", + mime_type); + g_free (mime_type); + } + } + } + g_string_append (s, "\r\n"); + + if (g_output_stream_write_all (out, + s->str, s->len, + NULL, NULL, NULL)) + { + g_output_stream_splice (out, + G_INPUT_STREAM (file_in), + 0, NULL, NULL); + } + g_string_free (s, TRUE); + + g_input_stream_close (G_INPUT_STREAM (file_in), NULL, NULL); + g_object_unref (file_in); + + out: + g_object_unref (data); + + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + GSocketService *service; + GOptionContext *context; + GError *error = NULL; + + context = g_option_context_new (" - Simple HTTP server"); + g_option_context_add_main_entries (context, cmd_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + if (argc != 2) + { + g_printerr ("Root directory not specified\n"); + return 1; + } + + root = g_strdup (argv[1]); + + service = g_threaded_socket_service_new (10); + if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service), + port, + NULL, + &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + g_print ("Http server listening on port %d\n", port); + + g_signal_connect (service, "run", G_CALLBACK (handler), NULL); + + g_main_loop_run (g_main_loop_new (NULL, FALSE)); + g_assert_not_reached (); +} diff --git a/gio/tests/inet-address.c b/gio/tests/inet-address.c new file mode 100644 index 0000000..cae2004 --- /dev/null +++ b/gio/tests/inet-address.c @@ -0,0 +1,427 @@ +/* Unit tests for GInetAddress + * Copyright (C) 2012 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "config.h" + +#include +#include + +static void +test_parse (void) +{ + GInetAddress *addr; + + addr = g_inet_address_new_from_string ("0:0:0:0:0:0:0:0"); + g_assert (addr != NULL); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("1:0:0:0:0:0:0:8"); + g_assert (addr != NULL); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("0:0:0:0:0:FFFF:204.152.189.116"); + g_assert (addr != NULL); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("::1"); + g_assert (addr != NULL); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("::"); + g_assert (addr != NULL); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("::FFFF:204.152.189.116"); + g_assert (addr != NULL); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("204.152.189.116"); + g_assert (addr != NULL); + g_object_unref (addr); + + addr = g_inet_address_new_from_string ("::1::2"); + g_assert (addr == NULL); + addr = g_inet_address_new_from_string ("2001:1:2:3:4:5:6:7]"); + g_assert (addr == NULL); + addr = g_inet_address_new_from_string ("[2001:1:2:3:4:5:6:7"); + g_assert (addr == NULL); + addr = g_inet_address_new_from_string ("[2001:1:2:3:4:5:6:7]"); + g_assert (addr == NULL); + addr = g_inet_address_new_from_string ("[2001:1:2:3:4:5:6:7]:80"); + g_assert (addr == NULL); + addr = g_inet_address_new_from_string ("0:1:2:3:4:5:6:7:8:9"); + g_assert (addr == NULL); + addr = g_inet_address_new_from_string ("::FFFFFFF"); + g_assert (addr == NULL); + addr = g_inet_address_new_from_string ("204.152.189.116:80"); + g_assert (addr == NULL); +} + +static void +test_any (void) +{ + GInetAddress *addr; + GSocketFamily family[2] = { G_SOCKET_FAMILY_IPV4, G_SOCKET_FAMILY_IPV6 }; + gsize size[2] = { 4, 16 }; + gint i; + + for (i = 0; i < 2; i++) + { + addr = g_inet_address_new_any (family[i]); + + g_assert (g_inet_address_get_is_any (addr)); + g_assert (g_inet_address_get_family (addr) == family[i]); + g_assert (g_inet_address_get_native_size (addr) == size[i]); + g_assert (!g_inet_address_get_is_loopback (addr)); + g_assert (!g_inet_address_get_is_link_local (addr)); + g_assert (!g_inet_address_get_is_site_local (addr)); + g_assert (!g_inet_address_get_is_multicast (addr)); + g_assert (!g_inet_address_get_is_mc_global (addr)); + g_assert (!g_inet_address_get_is_mc_link_local (addr)); + g_assert (!g_inet_address_get_is_mc_node_local (addr)); + g_assert (!g_inet_address_get_is_mc_org_local (addr)); + g_assert (!g_inet_address_get_is_mc_site_local (addr)); + + g_object_unref (addr); + } +} + +static void +test_loopback (void) +{ + GInetAddress *addr; + + addr = g_inet_address_new_from_string ("::1"); + g_assert (g_inet_address_get_family (addr) == G_SOCKET_FAMILY_IPV6); + g_assert (g_inet_address_get_is_loopback (addr)); + g_object_unref (addr); + + addr = g_inet_address_new_from_string ("127.0.0.0"); + g_assert (g_inet_address_get_family (addr) == G_SOCKET_FAMILY_IPV4); + g_assert (g_inet_address_get_is_loopback (addr)); + g_object_unref (addr); +} + +static void +test_bytes (void) +{ + GInetAddress *addr1, *addr2, *addr3; + const guint8 *bytes; + + addr1 = g_inet_address_new_from_string ("192.168.0.100"); + addr2 = g_inet_address_new_from_string ("192.168.0.101"); + bytes = g_inet_address_to_bytes (addr1); + addr3 = g_inet_address_new_from_bytes (bytes, G_SOCKET_FAMILY_IPV4); + + g_assert (!g_inet_address_equal (addr1, addr2)); + g_assert (g_inet_address_equal (addr1, addr3)); + + g_object_unref (addr1); + g_object_unref (addr2); + g_object_unref (addr3); +} + +static void +test_property (void) +{ + GInetAddress *addr; + GSocketFamily family; + const guint8 *bytes; + gboolean any; + gboolean loopback; + gboolean link_local; + gboolean site_local; + gboolean multicast; + gboolean mc_global; + gboolean mc_link_local; + gboolean mc_node_local; + gboolean mc_org_local; + gboolean mc_site_local; + + addr = g_inet_address_new_from_string ("ff85::"); + g_object_get (addr, + "family", &family, + "bytes", &bytes, + "is-any", &any, + "is-loopback", &loopback, + "is-link-local", &link_local, + "is-site-local", &site_local, + "is-multicast", &multicast, + "is-mc-global", &mc_global, + "is-mc-link-local", &mc_link_local, + "is-mc-node-local", &mc_node_local, + "is-mc-org-local", &mc_org_local, + "is-mc-site-local", &mc_site_local, + NULL); + + g_assert (family == G_SOCKET_FAMILY_IPV6); + g_assert (!any); + g_assert (!loopback); + g_assert (!link_local); + g_assert (!site_local); + g_assert (multicast); + g_assert (!mc_global); + g_assert (!mc_link_local); + g_assert (!mc_node_local); + g_assert (!mc_org_local); + g_assert (mc_site_local); + + g_object_unref (addr); +} + +static void +test_socket_address (void) +{ + GInetAddress *addr; + GInetSocketAddress *saddr; + guint port; + guint32 flowinfo; + guint32 scope_id; + GSocketFamily family; + + addr = g_inet_address_new_from_string ("::ffff:125.1.15.5"); + saddr = G_INET_SOCKET_ADDRESS (g_inet_socket_address_new (addr, 308)); + + g_assert (g_inet_address_equal (addr, g_inet_socket_address_get_address (saddr))); + g_object_unref (addr); + + g_assert (g_inet_socket_address_get_port (saddr) == 308); + g_assert (g_inet_socket_address_get_flowinfo (saddr) == 0); + g_assert (g_inet_socket_address_get_scope_id (saddr) == 0); + + g_object_unref (saddr); + + addr = g_inet_address_new_from_string ("::1"); + saddr = G_INET_SOCKET_ADDRESS (g_object_new (G_TYPE_INET_SOCKET_ADDRESS, + "address", addr, + "port", 308, + "flowinfo", 10, + "scope-id", 25, + NULL)); + g_object_unref (addr); + + g_assert (g_inet_socket_address_get_port (saddr) == 308); + g_assert (g_inet_socket_address_get_flowinfo (saddr) == 10); + g_assert (g_inet_socket_address_get_scope_id (saddr) == 25); + + g_object_get (saddr, + "family", &family, + "address", &addr, + "port", &port, + "flowinfo", &flowinfo, + "scope-id", &scope_id, + NULL); + + g_assert (family == G_SOCKET_FAMILY_IPV6); + g_assert (addr != NULL); + g_assert (port == 308); + g_assert (flowinfo == 10); + g_assert (scope_id == 25); + + g_object_unref (addr); + g_object_unref (saddr); +} + +static void +test_socket_address_to_string (void) +{ + GSocketAddress *sa = NULL; + GInetAddress *ia = NULL; + gchar *str = NULL; + + /* IPv4. */ + ia = g_inet_address_new_from_string ("123.1.123.1"); + sa = g_inet_socket_address_new (ia, 80); + str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (sa)); + g_assert_cmpstr (str, ==, "123.1.123.1:80"); + g_free (str); + g_object_unref (sa); + g_object_unref (ia); + + /* IPv6. */ + ia = g_inet_address_new_from_string ("fe80::80"); + sa = g_inet_socket_address_new (ia, 80); + str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (sa)); + g_assert_cmpstr (str, ==, "[fe80::80]:80"); + g_free (str); + g_object_unref (sa); + g_object_unref (ia); + + /* IPv6 without port. */ + ia = g_inet_address_new_from_string ("fe80::80"); + sa = g_inet_socket_address_new (ia, 0); + str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (sa)); + g_assert_cmpstr (str, ==, "fe80::80"); + g_free (str); + g_object_unref (sa); + g_object_unref (ia); + + /* IPv6 with scope. */ + ia = g_inet_address_new_from_string ("::1"); + sa = G_SOCKET_ADDRESS (g_object_new (G_TYPE_INET_SOCKET_ADDRESS, + "address", ia, + "port", 123, + "flowinfo", 10, + "scope-id", 25, + NULL)); + str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (sa)); + g_assert_cmpstr (str, ==, "[::1%25]:123"); + g_free (str); + g_object_unref (sa); + g_object_unref (ia); +} + +static void +test_mask_parse (void) +{ + GInetAddressMask *mask; + GError *error = NULL; + + mask = g_inet_address_mask_new_from_string ("10.0.0.0/8", &error); + g_assert_no_error (error); + g_assert (mask != NULL); + g_object_unref (mask); + + mask = g_inet_address_mask_new_from_string ("fe80::/10", &error); + g_assert_no_error (error); + g_assert (mask != NULL); + g_object_unref (mask); + + mask = g_inet_address_mask_new_from_string ("::", &error); + g_assert_no_error (error); + g_assert (mask != NULL); + g_object_unref (mask); + + mask = g_inet_address_mask_new_from_string ("::/abc", &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert (mask == NULL); + g_clear_error (&error); + + mask = g_inet_address_mask_new_from_string ("127.0.0.1/128", &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert (mask == NULL); + g_clear_error (&error); +} + +static void +test_mask_property (void) +{ + GInetAddressMask *mask; + GInetAddress *addr; + GSocketFamily family; + guint len; + + addr = g_inet_address_new_from_string ("fe80::"); + mask = g_inet_address_mask_new_from_string ("fe80::/10", NULL); + g_assert (g_inet_address_mask_get_family (mask) == G_SOCKET_FAMILY_IPV6); + g_assert (g_inet_address_equal (addr, g_inet_address_mask_get_address (mask))); + g_assert (g_inet_address_mask_get_length (mask) == 10); + g_object_unref (addr); + + g_object_get (mask, + "family", &family, + "address", &addr, + "length", &len, + NULL); + g_assert (family == G_SOCKET_FAMILY_IPV6); + g_assert (addr != NULL); + g_assert (len == 10); + g_object_unref (addr); + + g_object_unref (mask); +} + +static void +test_mask_equal (void) +{ + GInetAddressMask *mask; + GInetAddressMask *mask2; + gchar *str; + + mask = g_inet_address_mask_new_from_string ("fe80:0:0::/10", NULL); + str = g_inet_address_mask_to_string (mask); + g_assert_cmpstr (str, ==, "fe80::/10"); + mask2 = g_inet_address_mask_new_from_string (str, NULL); + g_assert (g_inet_address_mask_equal (mask, mask2)); + g_object_unref (mask2); + g_free (str); + + mask2 = g_inet_address_mask_new_from_string ("fe80::/12", NULL); + g_assert (!g_inet_address_mask_equal (mask, mask2)); + g_object_unref (mask2); + + mask2 = g_inet_address_mask_new_from_string ("ff80::/10", NULL); + g_assert (!g_inet_address_mask_equal (mask, mask2)); + g_object_unref (mask2); + + g_object_unref (mask); +} + +static void +test_mask_match (void) +{ + GInetAddressMask *mask; + GInetAddress *addr; + + mask = g_inet_address_mask_new_from_string ("1.2.0.0/16", NULL); + + addr = g_inet_address_new_from_string ("1.2.0.0"); + g_assert (g_inet_address_mask_matches (mask, addr)); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("1.2.3.4"); + g_assert (g_inet_address_mask_matches (mask, addr)); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("1.3.1.1"); + g_assert (!g_inet_address_mask_matches (mask, addr)); + g_object_unref (addr); + + g_object_unref (mask); + + mask = g_inet_address_mask_new_from_string ("1.2.0.0/24", NULL); + + addr = g_inet_address_new_from_string ("1.2.0.0"); + g_assert (g_inet_address_mask_matches (mask, addr)); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("1.2.3.4"); + g_assert (!g_inet_address_mask_matches (mask, addr)); + g_object_unref (addr); + addr = g_inet_address_new_from_string ("1.2.0.24"); + g_assert (g_inet_address_mask_matches (mask, addr)); + g_object_unref (addr); + + g_object_unref (mask); + +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/inet-address/parse", test_parse); + g_test_add_func ("/inet-address/any", test_any); + g_test_add_func ("/inet-address/loopback", test_loopback); + g_test_add_func ("/inet-address/bytes", test_bytes); + g_test_add_func ("/inet-address/property", test_property); + g_test_add_func ("/socket-address/basic", test_socket_address); + g_test_add_func ("/socket-address/to-string", test_socket_address_to_string); + g_test_add_func ("/address-mask/parse", test_mask_parse); + g_test_add_func ("/address-mask/property", test_mask_property); + g_test_add_func ("/address-mask/equal", test_mask_equal); + g_test_add_func ("/address-mask/match", test_mask_match); + + return g_test_run (); +} diff --git a/gio/tests/io-stream.c b/gio/tests/io-stream.c new file mode 100644 index 0000000..90c7357 --- /dev/null +++ b/gio/tests/io-stream.c @@ -0,0 +1,171 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2010 Collabora Ltd. + * Authors: Xavier Claessens + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +typedef struct +{ + GMainLoop *main_loop; + const gchar *data1; + const gchar *data2; + GIOStream *iostream1; + GIOStream *iostream2; +} TestCopyChunksData; + +static void +test_copy_chunks_splice_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + TestCopyChunksData *data = user_data; + GMemoryOutputStream *ostream; + gchar *received_data; + GError *error = NULL; + + g_io_stream_splice_finish (res, &error); + g_assert_no_error (error); + + ostream = G_MEMORY_OUTPUT_STREAM (g_io_stream_get_output_stream (data->iostream1)); + received_data = g_memory_output_stream_get_data (ostream); + g_assert_cmpstr (received_data, ==, data->data2); + + ostream = G_MEMORY_OUTPUT_STREAM (g_io_stream_get_output_stream (data->iostream2)); + received_data = g_memory_output_stream_get_data (ostream); + g_assert_cmpstr (received_data, ==, data->data1); + + g_assert (g_io_stream_is_closed (data->iostream1)); + g_assert (g_io_stream_is_closed (data->iostream2)); + + g_main_loop_quit (data->main_loop); +} + +static void +test_copy_chunks (void) +{ + TestCopyChunksData data; + GInputStream *istream; + GOutputStream *ostream; + + data.main_loop = g_main_loop_new (NULL, FALSE); + data.data1 = "abcdefghijklmnopqrstuvwxyz"; + data.data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + istream = g_memory_input_stream_new_from_data (data.data1, -1, NULL); + ostream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + data.iostream1 = g_simple_io_stream_new (istream, ostream); + g_object_unref (istream); + g_object_unref (ostream); + + istream = g_memory_input_stream_new_from_data (data.data2, -1, NULL); + ostream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); + data.iostream2 = g_simple_io_stream_new (istream, ostream); + g_object_unref (istream); + g_object_unref (ostream); + + g_io_stream_splice_async (data.iostream1, data.iostream2, + G_IO_STREAM_SPLICE_CLOSE_STREAM1 | G_IO_STREAM_SPLICE_CLOSE_STREAM2 | + G_IO_STREAM_SPLICE_WAIT_FOR_BOTH, G_PRIORITY_DEFAULT, + NULL, test_copy_chunks_splice_cb, &data); + + /* We do not hold a ref in data struct, this is to make sure the operation + * keeps the iostream objects alive until it finishes */ + g_object_unref (data.iostream1); + g_object_unref (data.iostream2); + + g_main_loop_run (data.main_loop); + g_main_loop_unref (data.main_loop); +} + +static void +close_async_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *done = user_data; + + *done = TRUE; +} + +static void +test_close_file (void) +{ +#ifdef G_OS_UNIX + GFileIOStream *fios; + gboolean done; + GIOStream *io; + GFile *file; + + file = g_file_new_for_path ("/dev/null"); + fios = g_file_open_readwrite (file, NULL, NULL); + g_object_unref (file); + g_assert (fios); + + io = g_simple_io_stream_new (g_io_stream_get_input_stream (G_IO_STREAM (fios)), + g_io_stream_get_output_stream (G_IO_STREAM (fios))); + g_object_unref (fios); + + g_io_stream_close_async (io, 0, NULL, close_async_done, &done); + g_object_unref (io); + + done = FALSE; + while (!done) + g_main_context_iteration (NULL, TRUE); +#endif +} + +static void +test_close_memory (void) +{ + GInputStream *in; + GOutputStream *out; + gboolean done; + GIOStream *io; + + in = g_memory_input_stream_new (); + out = g_memory_output_stream_new_resizable (); + io = g_simple_io_stream_new (in, out); + g_object_unref (out); + g_object_unref (in); + + g_io_stream_close_async (io, 0, NULL, close_async_done, &done); + g_object_unref (io); + + done = FALSE; + while (!done) + g_main_context_iteration (NULL, TRUE); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/io-stream/copy-chunks", test_copy_chunks); + g_test_add_func ("/io-stream/close/async/memory", test_close_memory); + g_test_add_func ("/io-stream/close/async/file", test_close_file); + + return g_test_run(); +} diff --git a/gio/tests/live-g-file.c b/gio/tests/live-g-file.c new file mode 100644 index 0000000..9e2cc0c --- /dev/null +++ b/gio/tests/live-g-file.c @@ -0,0 +1,1493 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc. + * Authors: Tomas Bzatek + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_TEST_DIR "testdir_live-g-file" + +#define PATTERN_FILE_SIZE 0x10000 +#define TEST_HANDLE_SPECIAL TRUE + +enum StructureExtraFlags +{ + TEST_DELETE_NORMAL = 1 << 0, + TEST_DELETE_TRASH = 1 << 1, + TEST_DELETE_NON_EMPTY = 1 << 2, + TEST_DELETE_FAILURE = 1 << 3, + TEST_NOT_EXISTS = 1 << 4, + TEST_ENUMERATE_FILE = 1 << 5, + TEST_NO_ACCESS = 1 << 6, + TEST_COPY = 1 << 7, + TEST_MOVE = 1 << 8, + TEST_COPY_ERROR_RECURSE = 1 << 9, + TEST_ALREADY_EXISTS = 1 << 10, + TEST_TARGET_IS_FILE = 1 << 11, + TEST_CREATE = 1 << 12, + TEST_REPLACE = 1 << 13, + TEST_APPEND = 1 << 14, + TEST_OPEN = 1 << 15, + TEST_OVERWRITE = 1 << 16, + TEST_INVALID_SYMLINK = 1 << 17, + TEST_HIDDEN = 1 << 18, + TEST_DOT_HIDDEN = 1 << 19, +}; + +struct StructureItem +{ + const char *filename; + const char *link_to; + GFileType file_type; + GFileCreateFlags create_flags; + guint32 mode; + gboolean handle_special; + enum StructureExtraFlags extra_flags; +}; + +#define TEST_DIR_NO_ACCESS "dir_no-access" +#define TEST_DIR_NO_WRITE "dir_no-write" +#define TEST_DIR_TARGET "dir-target" +#define TEST_NAME_NOT_EXISTS "not_exists" +#define TEST_TARGET_FILE "target-file" + + +static const struct StructureItem sample_struct[] = { +/* filename link file_type create_flags mode | handle_special | extra_flags */ + {"dir1", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_DELETE_NON_EMPTY | TEST_REPLACE | TEST_OPEN}, + {"dir1/subdir", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_COPY_ERROR_RECURSE | TEST_APPEND}, + {"dir2", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_MOVE | TEST_CREATE}, + {TEST_DIR_TARGET, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_COPY_ERROR_RECURSE}, + {TEST_DIR_NO_ACCESS, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_PRIVATE, S_IRUSR + S_IWUSR + S_IRGRP + S_IWGRP + S_IROTH + S_IWOTH, 0, TEST_NO_ACCESS | TEST_OPEN}, + {TEST_DIR_NO_WRITE, NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_PRIVATE, S_IRUSR + S_IXUSR + S_IRGRP + S_IXGRP + S_IROTH + S_IXOTH, 0, 0}, + {TEST_TARGET_FILE, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OPEN}, + {"normal_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_CREATE | TEST_OVERWRITE}, + {"normal_file-symlink", "normal_file", G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_ENUMERATE_FILE | TEST_COPY | TEST_OPEN}, + {"executable_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, S_IRWXU + S_IRWXG + S_IRWXO, 0, TEST_DELETE_TRASH | TEST_COPY | TEST_OPEN | TEST_OVERWRITE | TEST_REPLACE}, + {"private_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_PRIVATE, 0, 0, TEST_COPY | TEST_OPEN | TEST_OVERWRITE | TEST_APPEND}, + {"normal_file2", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_OVERWRITE | TEST_REPLACE}, + {"readonly_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, S_IRUSR + S_IRGRP + S_IROTH, 0, TEST_DELETE_NORMAL | TEST_OPEN}, + {"UTF_pr\xcc\x8ci\xcc\x81lis\xcc\x8c z", + NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_CREATE | TEST_OPEN | TEST_OVERWRITE}, + {"dir_pr\xcc\x8ci\xcc\x81lis\xcc\x8c z", + NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, TEST_DELETE_NORMAL | TEST_CREATE}, + {"pattern_file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_COPY | TEST_OPEN | TEST_APPEND}, + {TEST_NAME_NOT_EXISTS, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_NORMAL | TEST_NOT_EXISTS | TEST_COPY | TEST_OPEN}, + {TEST_NAME_NOT_EXISTS, NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_TRASH | TEST_NOT_EXISTS | TEST_MOVE}, + {"not_exists2", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_CREATE}, + {"not_exists3", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_REPLACE}, + {"not_exists4", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_NOT_EXISTS | TEST_APPEND}, + {"dir_no-execute/file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, TEST_DELETE_NORMAL | TEST_DELETE_FAILURE | TEST_NOT_EXISTS | TEST_OPEN}, + {"lost_symlink", "nowhere", G_FILE_TYPE_SYMBOLIC_LINK, G_FILE_CREATE_NONE, 0, 0, TEST_COPY | TEST_DELETE_NORMAL | TEST_OPEN | TEST_INVALID_SYMLINK}, + {"dir_hidden", NULL, G_FILE_TYPE_DIRECTORY, G_FILE_CREATE_NONE, 0, 0, 0}, + {"dir_hidden/.hidden", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, TEST_HANDLE_SPECIAL, 0}, + {"dir_hidden/.a-hidden-file", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN}, + {"dir_hidden/file-in-.hidden1", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN | TEST_DOT_HIDDEN}, + {"dir_hidden/file-in-.hidden2", NULL, G_FILE_TYPE_REGULAR, G_FILE_CREATE_NONE, 0, 0, TEST_HIDDEN | TEST_DOT_HIDDEN}, + }; + +static gboolean test_suite; +static gboolean write_test; +static gboolean verbose; +static gboolean posix_compat; + +#ifdef G_OS_UNIX +/* + * check_cap_dac_override: + * @tmpdir: A temporary directory in which we can create and delete files + * + * Check whether the current process can bypass DAC permissions. + * + * Traditionally, "privileged" processes (those with effective uid 0) + * could do this (and bypass many other checks), and "unprivileged" + * processes could not. + * + * In Linux, the special powers of euid 0 are divided into many + * capabilities: see `capabilities(7)`. The one we are interested in + * here is `CAP_DAC_OVERRIDE`. + * + * We do this generically instead of actually looking at the capability + * bits, so that the right thing will happen on non-Linux Unix + * implementations, in particular if they have something equivalent to + * but not identical to Linux permissions. + * + * Returns: %TRUE if we have Linux `CAP_DAC_OVERRIDE` or equivalent + * privileges + */ +static gboolean +check_cap_dac_override (const char *tmpdir) +{ + gchar *dac_denies_write; + gchar *inside; + gboolean have_cap; + + dac_denies_write = g_build_filename (tmpdir, "dac-denies-write", NULL); + inside = g_build_filename (dac_denies_write, "inside", NULL); + + g_assert_no_errno (mkdir (dac_denies_write, S_IRWXU)); + g_assert_no_errno (chmod (dac_denies_write, 0)); + + if (mkdir (inside, S_IRWXU) == 0) + { + g_test_message ("Looks like we have CAP_DAC_OVERRIDE or equivalent"); + g_assert_no_errno (rmdir (inside)); + have_cap = TRUE; + } + else + { + int saved_errno = errno; + + g_test_message ("We do not have CAP_DAC_OVERRIDE or equivalent"); + g_assert_cmpint (saved_errno, ==, EACCES); + have_cap = FALSE; + } + + g_assert_no_errno (chmod (dac_denies_write, S_IRWXU)); + g_assert_no_errno (rmdir (dac_denies_write)); + g_free (dac_denies_write); + g_free (inside); + return have_cap; +} +#endif + +#ifdef G_HAVE_ISO_VARARGS +#define log(...) if (verbose) g_printerr (__VA_ARGS__) +#elif defined(G_HAVE_GNUC_VARARGS) +#define log(msg...) if (verbose) g_printerr (msg) +#else /* no varargs macros */ +static void log (const g_char *format, ...) +{ + va_list args; + va_start (args, format); + if (verbose) g_printerr (format, args); + va_end (args); +} +#endif + +static GFile * +create_empty_file (GFile * parent, const char *filename, + GFileCreateFlags create_flags) +{ + GFile *child; + GError *error; + GFileOutputStream *outs; + + child = g_file_get_child (parent, filename); + g_assert_nonnull (child); + + error = NULL; + outs = g_file_replace (child, NULL, FALSE, create_flags, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (outs); + error = NULL; + g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error); + g_object_unref (outs); + return child; +} + +static GFile * +create_empty_dir (GFile * parent, const char *filename) +{ + GFile *child; + gboolean res; + GError *error; + + child = g_file_get_child (parent, filename); + g_assert_nonnull (child); + error = NULL; + res = g_file_make_directory (child, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + return child; +} + +static GFile * +create_symlink (GFile * parent, const char *filename, const char *points_to) +{ + GFile *child; + gboolean res; + GError *error; + + child = g_file_get_child (parent, filename); + g_assert_nonnull (child); + error = NULL; + res = g_file_make_symbolic_link (child, points_to, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + return child; +} + +static void +test_create_structure (gconstpointer test_data) +{ + GFile *root; + GFile *child; + gboolean res; + GError *error = NULL; + GFileOutputStream *outs; + GDataOutputStream *outds; + guint i; + struct StructureItem item; + + g_assert_nonnull (test_data); + log ("\n Going to create testing structure in '%s'...\n", + (char *) test_data); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + + /* create root directory */ + g_file_make_directory (root, NULL, &error); + g_assert_no_error (error); + + /* create any other items */ + for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) + { + item = sample_struct[i]; + if ((item.handle_special) + || ((!posix_compat) + && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK))) + continue; + + child = NULL; + switch (item.file_type) + { + case G_FILE_TYPE_REGULAR: + log (" Creating file '%s'...\n", item.filename); + child = create_empty_file (root, item.filename, item.create_flags); + break; + case G_FILE_TYPE_DIRECTORY: + log (" Creating directory '%s'...\n", item.filename); + child = create_empty_dir (root, item.filename); + break; + case G_FILE_TYPE_SYMBOLIC_LINK: + log (" Creating symlink '%s' --> '%s'...\n", item.filename, + item.link_to); + child = create_symlink (root, item.filename, item.link_to); + break; + case G_FILE_TYPE_UNKNOWN: + case G_FILE_TYPE_SPECIAL: + case G_FILE_TYPE_SHORTCUT: + case G_FILE_TYPE_MOUNTABLE: + default: + break; + } + g_assert_nonnull (child); + + if ((item.mode > 0) && (posix_compat)) + { + res = + g_file_set_attribute_uint32 (child, G_FILE_ATTRIBUTE_UNIX_MODE, + item.mode, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + } + + if ((item.extra_flags & TEST_DOT_HIDDEN) == TEST_DOT_HIDDEN) + { + gchar *dir, *path, *basename; + FILE *f; + + dir = g_path_get_dirname (item.filename); + basename = g_path_get_basename (item.filename); + path = g_build_filename (test_data, dir, ".hidden", NULL); + + f = fopen (path, "a"); + fprintf (f, "%s\n", basename); + fclose (f); + + g_free (dir); + g_free (path); + g_free (basename); + } + + g_object_unref (child); + } + + /* create a pattern file */ + log (" Creating pattern file..."); + child = g_file_get_child (root, "pattern_file"); + g_assert_nonnull (child); + + outs = + g_file_replace (child, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error); + g_assert_no_error (error); + + g_assert_nonnull (outs); + outds = g_data_output_stream_new (G_OUTPUT_STREAM (outs)); + g_assert_nonnull (outds); + for (i = 0; i < PATTERN_FILE_SIZE; i++) + { + g_data_output_stream_put_byte (outds, i % 256, NULL, &error); + g_assert_no_error (error); + } + + g_output_stream_close (G_OUTPUT_STREAM (outs), NULL, &error); + g_assert_no_error (error); + g_object_unref (outds); + g_object_unref (outs); + g_object_unref (child); + log (" done.\n"); + + g_object_unref (root); +} + +static GFile * +file_exists (GFile * parent, const char *filename, gboolean * result) +{ + GFile *child; + gboolean res; + + if (result) + *result = FALSE; + + child = g_file_get_child (parent, filename); + g_assert_nonnull (child); + res = g_file_query_exists (child, NULL); + if (result) + *result = res; + + return child; +} + +static void +test_attributes (struct StructureItem item, GFileInfo * info) +{ + GFileType ftype; + guint32 mode; + const char *name, *display_name, *edit_name, *copy_name, *symlink_target; + gboolean utf8_valid; + gboolean has_attr; + gboolean is_symlink; + gboolean is_hidden; + gboolean can_read, can_write; + + /* standard::type */ + has_attr = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE); + g_assert_true (has_attr); + ftype = g_file_info_get_file_type (info); + g_assert_cmpint (ftype, !=, G_FILE_TYPE_UNKNOWN); + g_assert_cmpint (ftype, ==, item.file_type); + + /* unix::mode */ + if ((item.mode > 0) && (posix_compat)) + { + mode = + g_file_info_get_attribute_uint32 (info, + G_FILE_ATTRIBUTE_UNIX_MODE) & 0xFFF; + g_assert_cmpint (mode, ==, item.mode); + } + + /* access::can-read */ + if (item.file_type != G_FILE_TYPE_SYMBOLIC_LINK) + { + can_read = + g_file_info_get_attribute_boolean (info, + G_FILE_ATTRIBUTE_ACCESS_CAN_READ); + g_assert_true (can_read); + } + + /* access::can-write */ + if ((write_test) && ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE)) + { + can_write = + g_file_info_get_attribute_boolean (info, + G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); + g_assert_true (can_write); + } + + /* standard::name */ + name = g_file_info_get_name (info); + g_assert_nonnull (name); + + /* standard::display-name */ + display_name = g_file_info_get_display_name (info); + g_assert_nonnull (display_name); + utf8_valid = g_utf8_validate (display_name, -1, NULL); + g_assert_true (utf8_valid); + + /* standard::edit-name */ + edit_name = g_file_info_get_edit_name (info); + if (edit_name) + { + utf8_valid = g_utf8_validate (edit_name, -1, NULL); + g_assert_true (utf8_valid); + } + + /* standard::copy-name */ + copy_name = + g_file_info_get_attribute_string (info, + G_FILE_ATTRIBUTE_STANDARD_COPY_NAME); + if (copy_name) + { + utf8_valid = g_utf8_validate (copy_name, -1, NULL); + g_assert_true (utf8_valid); + } + + /* standard::is-symlink */ + if (posix_compat) + { + is_symlink = g_file_info_get_is_symlink (info); + g_assert_cmpint (is_symlink, ==, + item.file_type == G_FILE_TYPE_SYMBOLIC_LINK); + } + + /* standard::symlink-target */ + if ((item.file_type == G_FILE_TYPE_SYMBOLIC_LINK) && (posix_compat)) + { + symlink_target = g_file_info_get_symlink_target (info); + g_assert_cmpstr (symlink_target, ==, item.link_to); + } + + /* standard::is-hidden */ + if ((item.extra_flags & TEST_HIDDEN) == TEST_HIDDEN) + { + is_hidden = + g_file_info_get_attribute_boolean (info, + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN); + g_assert_true (is_hidden); + } + + /* unix::is-mountpoint */ + if (posix_compat) + { + gboolean is_mountpoint = + g_file_info_get_attribute_boolean (info, + G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT); + g_assert_false (is_mountpoint); + } +} + +static void +test_initial_structure (gconstpointer test_data) +{ + GFile *root; + GFile *child; + gboolean res; + GError *error; + GFileInputStream *ins; + guint i; + GFileInfo *info; + guint32 size; + guchar *buffer; + gssize read, total_read; + struct StructureItem item; + + g_assert_nonnull (test_data); + log ("\n Testing sample structure in '%s'...\n", (char *) test_data); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + res = g_file_query_exists (root, NULL); + g_assert_true (res); + + /* test the structure */ + for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) + { + item = sample_struct[i]; + if (((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)) + || (item.handle_special)) + continue; + + log (" Testing file '%s'...\n", item.filename); + + child = file_exists (root, item.filename, &res); + g_assert_nonnull (child); + g_assert_true (res); + + error = NULL; + info = + g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (info); + + test_attributes (item, info); + + g_object_unref (child); + g_object_unref (info); + } + + /* read and test the pattern file */ + log (" Testing pattern file...\n"); + child = file_exists (root, "pattern_file", &res); + g_assert_nonnull (child); + g_assert_true (res); + + error = NULL; + info = + g_file_query_info (child, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (info); + size = g_file_info_get_size (info); + g_assert_cmpint (size, ==, PATTERN_FILE_SIZE); + g_object_unref (info); + + error = NULL; + ins = g_file_read (child, NULL, &error); + g_assert_nonnull (ins); + g_assert_no_error (error); + + buffer = g_malloc (PATTERN_FILE_SIZE); + total_read = 0; + + while (total_read < PATTERN_FILE_SIZE) + { + error = NULL; + read = + g_input_stream_read (G_INPUT_STREAM (ins), buffer + total_read, + PATTERN_FILE_SIZE, NULL, &error); + g_assert_no_error (error); + total_read += read; + log (" read %"G_GSSIZE_FORMAT" bytes, total = %"G_GSSIZE_FORMAT" of %d.\n", + read, total_read, PATTERN_FILE_SIZE); + } + g_assert_cmpint (total_read, ==, PATTERN_FILE_SIZE); + + error = NULL; + res = g_input_stream_close (G_INPUT_STREAM (ins), NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + + for (i = 0; i < PATTERN_FILE_SIZE; i++) + g_assert_cmpint (*(buffer + i), ==, i % 256); + + g_object_unref (ins); + g_object_unref (child); + g_free (buffer); + g_object_unref (root); +} + +static void +traverse_recurse_dirs (GFile * parent, GFile * root) +{ + gboolean res; + GError *error; + GFileEnumerator *enumerator; + GFileInfo *info; + GFile *descend; + char *relative_path; + guint i; + gboolean found; + + g_assert_nonnull (root); + + error = NULL; + enumerator = + g_file_enumerate_children (parent, "*", + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, + &error); + g_assert_nonnull (enumerator); + g_assert_no_error (error); + + g_assert_true (g_file_enumerator_get_container (enumerator) == parent); + + error = NULL; + info = g_file_enumerator_next_file (enumerator, NULL, &error); + while ((info) && (!error)) + { + descend = g_file_enumerator_get_child (enumerator, info); + g_assert_nonnull (descend); + relative_path = g_file_get_relative_path (root, descend); + g_assert_nonnull (relative_path); + + found = FALSE; + for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) + { + if (strcmp (sample_struct[i].filename, relative_path) == 0) + { + /* test the attributes again */ + test_attributes (sample_struct[i], info); + + found = TRUE; + break; + } + } + g_assert_true (found); + + log (" Found file %s, relative to root: %s\n", + g_file_info_get_display_name (info), relative_path); + + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + traverse_recurse_dirs (descend, root); + + g_object_unref (descend); + error = NULL; + g_object_unref (info); + g_free (relative_path); + + info = g_file_enumerator_next_file (enumerator, NULL, &error); + } + g_assert_no_error (error); + + error = NULL; + res = g_file_enumerator_close (enumerator, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_true (g_file_enumerator_is_closed (enumerator)); + + g_object_unref (enumerator); +} + +static void +test_traverse_structure (gconstpointer test_data) +{ + GFile *root; + gboolean res; + + g_assert_nonnull (test_data); + log ("\n Traversing through the sample structure in '%s'...\n", + (char *) test_data); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + res = g_file_query_exists (root, NULL); + g_assert_true (res); + + traverse_recurse_dirs (root, root); + + g_object_unref (root); +} + + + + +static void +test_enumerate (gconstpointer test_data) +{ + GFile *root, *child; + gboolean res; + GError *error; + GFileEnumerator *enumerator; + GFileInfo *info; + guint i; + struct StructureItem item; + + + g_assert_nonnull (test_data); + log ("\n Test enumerate '%s'...\n", (char *) test_data); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + res = g_file_query_exists (root, NULL); + g_assert_true (res); + + + for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) + { + item = sample_struct[i]; + if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)) + continue; + + if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) || + (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS) + && posix_compat) + || ((item.extra_flags & TEST_ENUMERATE_FILE) == + TEST_ENUMERATE_FILE)) + { + log (" Testing file '%s'\n", item.filename); + child = g_file_get_child (root, item.filename); + g_assert_nonnull (child); + error = NULL; + enumerator = + g_file_enumerate_children (child, "*", + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, &error); + + if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) + { + g_assert_null (enumerator); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND); + } + if ((item.extra_flags & TEST_ENUMERATE_FILE) == TEST_ENUMERATE_FILE) + { + g_assert_null (enumerator); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY); + } + if ((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS) + { + g_assert_nonnull (enumerator); + + error = NULL; + info = g_file_enumerator_next_file (enumerator, NULL, &error); + g_assert_null (info); + g_assert_no_error (error); + /* no items should be found, no error should be logged */ + } + + if (error) + g_error_free (error); + + if (enumerator) + { + error = NULL; + res = g_file_enumerator_close (enumerator, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + + g_object_unref (enumerator); + } + g_object_unref (child); + } + } + g_object_unref (root); +} + +static void +do_copy_move (GFile * root, struct StructureItem item, const char *target_dir, + enum StructureExtraFlags extra_flags) +{ + GFile *dst_dir, *src_file, *dst_file; + gboolean res; + GError *error; +#ifdef G_OS_UNIX + gboolean have_cap_dac_override = check_cap_dac_override (g_file_peek_path (root)); +#endif + + log (" do_copy_move: '%s' --> '%s'\n", item.filename, target_dir); + + dst_dir = g_file_get_child (root, target_dir); + g_assert_nonnull (dst_dir); + src_file = g_file_get_child (root, item.filename); + g_assert_nonnull (src_file); + dst_file = g_file_get_child (dst_dir, item.filename); + g_assert_nonnull (dst_file); + + error = NULL; + if ((item.extra_flags & TEST_COPY) == TEST_COPY) + res = + g_file_copy (src_file, dst_file, + G_FILE_COPY_NOFOLLOW_SYMLINKS | + ((extra_flags == + TEST_OVERWRITE) ? G_FILE_COPY_OVERWRITE : + G_FILE_COPY_NONE), NULL, NULL, NULL, &error); + else + res = + g_file_move (src_file, dst_file, G_FILE_COPY_NOFOLLOW_SYMLINKS, NULL, + NULL, NULL, &error); + + if (error) + log (" res = %d, error code %d = %s\n", res, error->code, + error->message); + + /* copying file/directory to itself (".") */ + if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) && + (extra_flags == TEST_ALREADY_EXISTS)) + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS); + } + /* target file is a file, overwrite is not set */ + else if (((item.extra_flags & TEST_NOT_EXISTS) != TEST_NOT_EXISTS) && + (extra_flags == TEST_TARGET_IS_FILE)) + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY); + } + /* source file is directory */ + else if ((item.extra_flags & TEST_COPY_ERROR_RECURSE) == + TEST_COPY_ERROR_RECURSE) + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE); + } + /* source or target path doesn't exist */ + else if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) || + (extra_flags == TEST_NOT_EXISTS)) + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND); + } + /* source or target path permission denied */ + else if (((item.extra_flags & TEST_NO_ACCESS) == TEST_NO_ACCESS) || + (extra_flags == TEST_NO_ACCESS)) + { + /* This works for root, see bug #552912 */ +#ifdef G_OS_UNIX + if (have_cap_dac_override) + { + g_test_message ("Unable to exercise g_file_copy() or g_file_move() " + "failing with EACCES: we probably have " + "CAP_DAC_OVERRIDE"); + g_assert_true (res); + g_assert_no_error (error); + } + else +#endif + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED); + } + } + /* no error should be found, all exceptions defined above */ + else + { + g_assert_true (res); + g_assert_no_error (error); + } + + if (error) + g_error_free (error); + + + g_object_unref (dst_dir); + g_object_unref (src_file); + g_object_unref (dst_file); +} + +static void +test_copy_move (gconstpointer test_data) +{ + GFile *root; + gboolean res; + guint i; + struct StructureItem item; + + log ("\n"); + + g_assert_nonnull (test_data); + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + res = g_file_query_exists (root, NULL); + g_assert_true (res); + + + for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) + { + item = sample_struct[i]; + + if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)) + continue; + + if (((item.extra_flags & TEST_COPY) == TEST_COPY) || + ((item.extra_flags & TEST_MOVE) == TEST_MOVE)) + { + /* test copy/move to a directory, expecting no errors if source files exist */ + do_copy_move (root, item, TEST_DIR_TARGET, 0); + + /* some files have been already moved so we can't count with them in the tests */ + if ((item.extra_flags & TEST_COPY) == TEST_COPY) + { + /* test overwrite for flagged files */ + if ((item.extra_flags & TEST_OVERWRITE) == TEST_OVERWRITE) + { + do_copy_move (root, item, TEST_DIR_TARGET, TEST_OVERWRITE); + } + /* source = target, should return G_IO_ERROR_EXISTS */ + do_copy_move (root, item, ".", TEST_ALREADY_EXISTS); + /* target is file */ + do_copy_move (root, item, TEST_TARGET_FILE, + TEST_TARGET_IS_FILE); + /* target path is invalid */ + do_copy_move (root, item, TEST_NAME_NOT_EXISTS, + TEST_NOT_EXISTS); + + /* tests on POSIX-compatible filesystems */ + if (posix_compat) + { + /* target directory is not accessible (no execute flag) */ + do_copy_move (root, item, TEST_DIR_NO_ACCESS, + TEST_NO_ACCESS); + /* target directory is readonly */ + do_copy_move (root, item, TEST_DIR_NO_WRITE, + TEST_NO_ACCESS); + } + } + } + } + g_object_unref (root); +} + +/* Test that G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT is TRUE for / and for another + * known mountpoint. The FALSE case is tested for many directories and files by + * test_initial_structure(), via test_attributes(). + */ +static void +test_unix_is_mountpoint (gconstpointer data) +{ + const gchar *path = data; + GFile *file = g_file_new_for_path (path); + GFileInfo *info; + gboolean is_mountpoint; + GError *error = NULL; + + info = g_file_query_info (file, G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT, + G_FILE_QUERY_INFO_NONE, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (info); + + is_mountpoint = + g_file_info_get_attribute_boolean (info, + G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT); + g_assert_true (is_mountpoint); + + g_clear_object (&info); + g_clear_object (&file); +} + +static void +test_create (gconstpointer test_data) +{ + GFile *root, *child; + gboolean res; + GError *error; + guint i; + struct StructureItem item; + GFileOutputStream *os; + + g_assert_nonnull (test_data); + log ("\n"); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + res = g_file_query_exists (root, NULL); + g_assert_true (res); + + for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) + { + item = sample_struct[i]; + + if (((item.extra_flags & TEST_CREATE) == TEST_CREATE) || + ((item.extra_flags & TEST_REPLACE) == TEST_REPLACE) || + ((item.extra_flags & TEST_APPEND) == TEST_APPEND)) + { + log (" test_create: '%s'\n", item.filename); + + child = g_file_get_child (root, item.filename); + g_assert_nonnull (child); + error = NULL; + os = NULL; + + if ((item.extra_flags & TEST_CREATE) == TEST_CREATE) + os = g_file_create (child, item.create_flags, NULL, &error); + else if ((item.extra_flags & TEST_REPLACE) == TEST_REPLACE) + os = + g_file_replace (child, NULL, TRUE, item.create_flags, NULL, + &error); + else if ((item.extra_flags & TEST_APPEND) == TEST_APPEND) + os = g_file_append_to (child, item.create_flags, NULL, &error); + + + if (error) + log (" error code %d = %s\n", error->code, error->message); + + if (((item.extra_flags & TEST_NOT_EXISTS) == 0) && + ((item.extra_flags & TEST_CREATE) == TEST_CREATE)) + { + g_assert_null (os); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS); + } + else if (item.file_type == G_FILE_TYPE_DIRECTORY) + { + g_assert_null (os); + if ((item.extra_flags & TEST_CREATE) == TEST_CREATE) + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS); + else + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY); + } + else + { + g_assert_nonnull (os); + g_assert_no_error (error); + } + + if (error) + g_error_free (error); + + if (os) + { + error = NULL; + res = + g_output_stream_close (G_OUTPUT_STREAM (os), NULL, &error); + if (error) + log (" g_output_stream_close: error %d = %s\n", + error->code, error->message); + g_assert_true (res); + g_assert_no_error (error); + g_object_unref (os); + } + g_object_unref (child); + } + } + g_object_unref (root); +} + +static void +test_open (gconstpointer test_data) +{ + GFile *root, *child; + gboolean res; + GError *error; + guint i; + struct StructureItem item; + GFileInputStream *input_stream; + + g_assert_nonnull (test_data); + log ("\n"); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + res = g_file_query_exists (root, NULL); + g_assert_true (res); + + for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) + { + item = sample_struct[i]; + + if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)) + continue; + + if ((item.extra_flags & TEST_OPEN) == TEST_OPEN) + { + log (" test_open: '%s'\n", item.filename); + + child = g_file_get_child (root, item.filename); + g_assert_nonnull (child); + error = NULL; + input_stream = g_file_read (child, NULL, &error); + + if (((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) || + ((item.extra_flags & TEST_INVALID_SYMLINK) == + TEST_INVALID_SYMLINK)) + { + g_assert_null (input_stream); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND); + } + else if (item.file_type == G_FILE_TYPE_DIRECTORY) + { + g_assert_null (input_stream); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY); + } + else + { + g_assert_nonnull (input_stream); + g_assert_no_error (error); + } + + if (error) + g_error_free (error); + + if (input_stream) + { + error = NULL; + res = + g_input_stream_close (G_INPUT_STREAM (input_stream), NULL, + &error); + g_assert_true (res); + g_assert_no_error (error); + g_object_unref (input_stream); + } + g_object_unref (child); + } + } + g_object_unref (root); +} + +static void +test_delete (gconstpointer test_data) +{ + GFile *root; + GFile *child; + gboolean res; + GError *error; + guint i; + struct StructureItem item; + gchar *path; + + g_assert_nonnull (test_data); + log ("\n"); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + res = g_file_query_exists (root, NULL); + g_assert_true (res); + + for (i = 0; i < G_N_ELEMENTS (sample_struct); i++) + { + item = sample_struct[i]; + + if ((!posix_compat) && (item.file_type == G_FILE_TYPE_SYMBOLIC_LINK)) + continue; + + if (((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL) || + ((item.extra_flags & TEST_DELETE_TRASH) == TEST_DELETE_TRASH)) + { + child = file_exists (root, item.filename, &res); + g_assert_nonnull (child); + /* we don't care about result here */ + + path = g_file_get_path (child); + log (" Deleting %s, path = %s\n", item.filename, path); + g_free (path); + + error = NULL; + if ((item.extra_flags & TEST_DELETE_NORMAL) == TEST_DELETE_NORMAL) + res = g_file_delete (child, NULL, &error); + else + res = g_file_trash (child, NULL, &error); + + if ((item.extra_flags & TEST_DELETE_NON_EMPTY) == + TEST_DELETE_NON_EMPTY) + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY); + } + if ((item.extra_flags & TEST_DELETE_FAILURE) == TEST_DELETE_FAILURE) + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND); + } + if ((item.extra_flags & TEST_NOT_EXISTS) == TEST_NOT_EXISTS) + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND); + } + + if (error) + { + log (" result = %d, error = %s\n", res, error->message); + g_error_free (error); + } + + g_object_unref (child); + } + } + g_object_unref (root); +} + +static void +test_make_directory_with_parents (gconstpointer test_data) +{ + GFile *root, *child, *grandchild, *greatgrandchild; + gboolean res; + GError *error = NULL; +#ifdef G_OS_UNIX + gboolean have_cap_dac_override = check_cap_dac_override (test_data); +#endif + + g_assert_nonnull (test_data); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + res = g_file_query_exists (root, NULL); + g_assert_true (res); + + child = g_file_get_child (root, "a"); + grandchild = g_file_get_child (child, "b"); + greatgrandchild = g_file_get_child (grandchild, "c"); + + /* Check that we can successfully make directory hierarchies of + * depth 1, 2, or 3 + */ + res = g_file_make_directory_with_parents (child, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + res = g_file_query_exists (child, NULL); + g_assert_true (res); + + g_file_delete (child, NULL, NULL); + + res = g_file_make_directory_with_parents (grandchild, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + res = g_file_query_exists (grandchild, NULL); + g_assert_true (res); + + g_file_delete (grandchild, NULL, NULL); + g_file_delete (child, NULL, NULL); + + res = g_file_make_directory_with_parents (greatgrandchild, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + res = g_file_query_exists (greatgrandchild, NULL); + g_assert_true (res); + + g_file_delete (greatgrandchild, NULL, NULL); + g_file_delete (grandchild, NULL, NULL); + g_file_delete (child, NULL, NULL); + + /* Now test failure by trying to create a directory hierarchy + * where a ancestor exists but is read-only + */ + + /* No obvious way to do this on Windows */ + if (!posix_compat) + goto out; + +#ifdef G_OS_UNIX + /* Permissions are ignored if we have CAP_DAC_OVERRIDE or equivalent, + * and in particular if we're root */ + if (have_cap_dac_override) + { + g_test_skip ("Unable to exercise g_file_make_directory_with_parents " + "failing with EACCES: we probably have " + "CAP_DAC_OVERRIDE"); + goto out; + } +#endif + + g_file_make_directory (child, NULL, NULL); + g_assert_true (res); + + res = g_file_set_attribute_uint32 (child, + G_FILE_ATTRIBUTE_UNIX_MODE, + S_IRUSR + S_IXUSR, /* -r-x------ */ + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, NULL); + g_assert_true (res); + + res = g_file_make_directory_with_parents (grandchild, NULL, &error); + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED); + g_clear_error (&error); + + res = g_file_make_directory_with_parents (greatgrandchild, NULL, &error); + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED); + g_clear_error (&error); + +out: + g_object_unref (greatgrandchild); + g_object_unref (grandchild); + g_object_unref (child); + g_object_unref (root); +} + + +static void +cleanup_dir_recurse (GFile *parent, GFile *root) +{ + gboolean res; + GError *error; + GFileEnumerator *enumerator; + GFileInfo *info; + GFile *descend; + char *relative_path; + + g_assert_nonnull (root); + + enumerator = + g_file_enumerate_children (parent, "*", + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, + NULL); + if (! enumerator) + return; + + error = NULL; + info = g_file_enumerator_next_file (enumerator, NULL, &error); + while ((info) && (!error)) + { + descend = g_file_enumerator_get_child (enumerator, info); + g_assert_nonnull (descend); + relative_path = g_file_get_relative_path (root, descend); + g_assert_nonnull (relative_path); + g_free (relative_path); + + log (" deleting '%s'\n", g_file_info_get_display_name (info)); + + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + cleanup_dir_recurse (descend, root); + + error = NULL; + res = g_file_delete (descend, NULL, &error); + g_assert_true (res); + + g_object_unref (descend); + error = NULL; + g_object_unref (info); + + info = g_file_enumerator_next_file (enumerator, NULL, &error); + } + g_assert_no_error (error); + + error = NULL; + res = g_file_enumerator_close (enumerator, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + + g_object_unref (enumerator); +} + +static void +prep_clean_structure (gconstpointer test_data) +{ + GFile *root; + + g_assert_nonnull (test_data); + log ("\n Cleaning target testing structure in '%s'...\n", + (char *) test_data); + + root = g_file_new_for_commandline_arg ((char *) test_data); + g_assert_nonnull (root); + + cleanup_dir_recurse (root, root); + + g_file_delete (root, NULL, NULL); + + g_object_unref (root); +} + +int +main (int argc, char *argv[]) +{ + static gboolean only_create_struct; + const char *target_path; + GError *error; + GOptionContext *context; + + static GOptionEntry cmd_entries[] = { + {"read-write", 'w', 0, G_OPTION_ARG_NONE, &write_test, + "Perform write tests (incl. structure creation)", NULL}, + {"create-struct", 'c', 0, G_OPTION_ARG_NONE, &only_create_struct, + "Only create testing structure (no tests)", NULL}, + {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL}, + {"posix", 'x', 0, G_OPTION_ARG_NONE, &posix_compat, + "Test POSIX-specific features (unix permissions, symlinks)", NULL}, + G_OPTION_ENTRY_NULL + }; + + test_suite = FALSE; + verbose = FALSE; + write_test = FALSE; + only_create_struct = FALSE; + target_path = NULL; + posix_compat = FALSE; + + /* strip all gtester-specific args */ + g_test_init (&argc, &argv, NULL); + + /* no extra parameters specified, assume we're executed from glib test suite */ + if (argc < 2) + { + test_suite = TRUE; + verbose = TRUE; + write_test = TRUE; + only_create_struct = FALSE; + target_path = DEFAULT_TEST_DIR; +#ifdef G_PLATFORM_WIN32 + posix_compat = FALSE; +#else + posix_compat = TRUE; +#endif + } + + /* add trailing args */ + error = NULL; + context = g_option_context_new ("target_path"); + g_option_context_add_main_entries (context, cmd_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("option parsing failed: %s\n", error->message); + return g_test_run (); + } + + /* remaining arg should is the target path; we don't care of the extra args here */ + if (argc >= 2) + target_path = strdup (argv[1]); + + if (! target_path) + { + g_printerr ("error: target path was not specified\n"); + g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); + return g_test_run (); + } + + g_option_context_free (context); + + /* Write test - clean target directory first */ + /* this can be also considered as a test - enumerate + delete */ + if (write_test || only_create_struct) + g_test_add_data_func ("/live-g-file/prep_clean_structure", target_path, + prep_clean_structure); + + /* Write test - create new testing structure */ + if (write_test || only_create_struct) + g_test_add_data_func ("/live-g-file/create_structure", target_path, + test_create_structure); + + /* Read test - test the sample structure - expect defined attributes to be there */ + if (!only_create_struct) + g_test_add_data_func ("/live-g-file/test_initial_structure", target_path, + test_initial_structure); + + /* Read test - test traverse the structure - no special file should appear */ + if (!only_create_struct) + g_test_add_data_func ("/live-g-file/test_traverse_structure", target_path, + test_traverse_structure); + + /* Read test - enumerate */ + if (!only_create_struct) + g_test_add_data_func ("/live-g-file/test_enumerate", target_path, + test_enumerate); + + /* Read test - open (g_file_read()) */ + if (!only_create_struct) + g_test_add_data_func ("/live-g-file/test_open", target_path, test_open); + + if (posix_compat) + { + g_test_add_data_func ("/live-g-file/test_unix_is_mountpoint/sysroot", + "/", + test_unix_is_mountpoint); +#ifdef __linux__ + g_test_add_data_func ("/live-g-file/test_unix_is_mountpoint/proc", + "/proc", + test_unix_is_mountpoint); +#endif + } + + /* Write test - create */ + if (write_test && (!only_create_struct)) + g_test_add_data_func ("/live-g-file/test_create", target_path, + test_create); + + /* Write test - copy, move */ + if (write_test && (!only_create_struct)) + g_test_add_data_func ("/live-g-file/test_copy_move", target_path, + test_copy_move); + + /* Write test - delete, trash */ + if (write_test && (!only_create_struct)) + g_test_add_data_func ("/live-g-file/test_delete", target_path, + test_delete); + + /* Write test - make_directory_with_parents */ + if (write_test && (!only_create_struct)) + g_test_add_data_func ("/live-g-file/test_make_directory_with_parents", target_path, + test_make_directory_with_parents); + + if (write_test || only_create_struct) + g_test_add_data_func ("/live-g-file/final_clean", target_path, + prep_clean_structure); + + return g_test_run (); + +} diff --git a/gio/tests/live-g-file.txt b/gio/tests/live-g-file.txt new file mode 100644 index 0000000..1873a05 --- /dev/null +++ b/gio/tests/live-g-file.txt @@ -0,0 +1,27 @@ +Before you start testing it would be good to explain how it works. + +The script works in three modes: + 1. read-only (no special arguments) - suitable for read-only backends. Just + create the sample structure using the second mode, pack it (tar -p is + preferred to preserve unix modes) and put it on a reachable place. + 2. create-structure - only creates reference structure for later testing + in read-only mode + 3. write mode - full test suite, creates testing structure and performs all + read and write tests. Please note the delete/move tests are included + in this mode and target directory structure is unusable after the script + is finished. + + +To see the list of available parameters just run 'live-g-file --help' + + +Notes: + - it's advised to clean target directory first, otherwise some tests might fail + (i.e. the tests creating testing structure) + + +Tested: + - local filesystem (/tmp/...) + - file:// uri (file:///tmp/...) + - locatest:// gvfs backend (localtest:///tmp/...) + - FAT16 filesystem (no POSIX extensions) diff --git a/gio/tests/memory-input-stream.c b/gio/tests/memory-input-stream.c new file mode 100644 index 0000000..2bf3d45 --- /dev/null +++ b/gio/tests/memory-input-stream.c @@ -0,0 +1,302 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2007 Imendio AB + * Authors: Tim Janik + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +static void +test_read_chunks (void) +{ + const char *data1 = "abcdefghijklmnopqrstuvwxyz"; + const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *result = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char buffer[128]; + gsize bytes_read, pos, len, chunk_size; + GError *error = NULL; + GInputStream *stream; + gboolean res; + + stream = g_memory_input_stream_new (); + + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data1, -1, NULL); + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data2, -1, NULL); + len = strlen (data1) + strlen (data2); + + for (chunk_size = 1; chunk_size < len - 1; chunk_size++) + { + pos = 0; + while (pos < len) + { + bytes_read = g_input_stream_read (stream, buffer, chunk_size, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, MIN (chunk_size, len - pos)); + g_assert (strncmp (buffer, result + pos, bytes_read) == 0); + + pos += bytes_read; + } + + g_assert_cmpint (pos, ==, len); + res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error); + g_assert_cmpint (res, ==, TRUE); + g_assert_no_error (error); + } + + g_object_unref (stream); +} + +GMainLoop *loop; + +static void +async_read_chunk (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gsize *bytes_read = user_data; + GError *error = NULL; + + *bytes_read = g_input_stream_read_finish (G_INPUT_STREAM (object), + result, &error); + g_assert_no_error (error); + + g_main_loop_quit (loop); +} + +static void +async_skipped_chunk (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gsize *bytes_skipped = user_data; + GError *error = NULL; + + *bytes_skipped = g_input_stream_skip_finish (G_INPUT_STREAM (object), + result, &error); + g_assert_no_error (error); + + g_main_loop_quit (loop); +} + +static void +test_async (void) +{ + const char *data1 = "abcdefghijklmnopqrstuvwxyz"; + const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *result = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char buffer[128]; + gsize bytes_read, bytes_skipped; + gsize pos, len, chunk_size; + GError *error = NULL; + GInputStream *stream; + gboolean res; + + loop = g_main_loop_new (NULL, FALSE); + + stream = g_memory_input_stream_new (); + + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data1, -1, NULL); + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data2, -1, NULL); + len = strlen (data1) + strlen (data2); + + for (chunk_size = 1; chunk_size < len - 1; chunk_size++) + { + pos = 0; + while (pos < len) + { + g_input_stream_read_async (stream, buffer, chunk_size, + G_PRIORITY_DEFAULT, NULL, + async_read_chunk, &bytes_read); + g_main_loop_run (loop); + + g_assert_cmpint (bytes_read, ==, MIN (chunk_size, len - pos)); + g_assert (strncmp (buffer, result + pos, bytes_read) == 0); + + pos += bytes_read; + } + + g_assert_cmpint (pos, ==, len); + res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error); + g_assert_cmpint (res, ==, TRUE); + g_assert_no_error (error); + + pos = 0; + while (pos + chunk_size + 1 < len) + { + g_input_stream_skip_async (stream, chunk_size, + G_PRIORITY_DEFAULT, NULL, + async_skipped_chunk, &bytes_skipped); + g_main_loop_run (loop); + + g_assert_cmpint (bytes_skipped, ==, MIN (chunk_size, len - pos)); + + pos += bytes_skipped; + } + + g_input_stream_read_async (stream, buffer, len - pos, + G_PRIORITY_DEFAULT, NULL, + async_read_chunk, &bytes_read); + g_main_loop_run (loop); + + g_assert_cmpint (bytes_read, ==, len - pos); + g_assert (strncmp (buffer, result + pos, bytes_read) == 0); + + res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error); + g_assert_cmpint (res, ==, TRUE); + g_assert_no_error (error); + } + + g_object_unref (stream); + g_main_loop_unref (loop); +} + +static void +test_seek (void) +{ + const char *data1 = "abcdefghijklmnopqrstuvwxyz"; + const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + GInputStream *stream; + GError *error; + char buffer[10]; + + stream = g_memory_input_stream_new (); + + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data1, -1, NULL); + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data2, -1, NULL); + + g_assert (G_IS_SEEKABLE (stream)); + g_assert (g_seekable_can_seek (G_SEEKABLE (stream))); + + error = NULL; + g_assert (g_seekable_seek (G_SEEKABLE (stream), 26, G_SEEK_SET, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (stream)), ==, 26); + + g_assert (g_input_stream_read (stream, buffer, 1, NULL, &error) == 1); + g_assert_no_error (error); + + g_assert (buffer[0] == 'A'); + + g_assert (!g_seekable_seek (G_SEEKABLE (stream), 26, G_SEEK_CUR, NULL, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_error_free (error); + + g_object_unref (stream); +} + +static void +test_truncate (void) +{ + const char *data1 = "abcdefghijklmnopqrstuvwxyz"; + const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + GInputStream *stream; + GError *error; + + stream = g_memory_input_stream_new (); + + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data1, -1, NULL); + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data2, -1, NULL); + + g_assert (G_IS_SEEKABLE (stream)); + g_assert (!g_seekable_can_truncate (G_SEEKABLE (stream))); + + error = NULL; + g_assert (!g_seekable_truncate (G_SEEKABLE (stream), 26, NULL, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_error_free (error); + + g_object_unref (stream); +} + +static void +test_read_bytes (void) +{ + const char *data1 = "abcdefghijklmnopqrstuvwxyz"; + const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + GInputStream *stream; + GError *error = NULL; + GBytes *bytes; + gsize size; + gconstpointer data; + + stream = g_memory_input_stream_new (); + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data1, -1, NULL); + g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream), + data2, -1, NULL); + + bytes = g_input_stream_read_bytes (stream, 26, NULL, &error); + g_assert_no_error (error); + + data = g_bytes_get_data (bytes, &size); + g_assert_cmpint (size, ==, 26); + g_assert (strncmp (data, data1, 26) == 0); + + g_bytes_unref (bytes); + g_object_unref (stream); +} + +static void +test_from_bytes (void) +{ + gchar data[4096], buffer[4096]; + GBytes *bytes; + GError *error = NULL; + GInputStream *stream; + gint i; + + for (i = 0; i < 4096; i++) + data[i] = 1 + i % 255; + + bytes = g_bytes_new_static (data, 4096); + stream = g_memory_input_stream_new_from_bytes (bytes); + g_assert (g_input_stream_read (stream, buffer, 2048, NULL, &error) == 2048); + g_assert_no_error (error); + g_assert (strncmp (data, buffer, 2048) == 0); + + g_object_unref (stream); + g_bytes_unref (bytes); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/memory-input-stream/read-chunks", test_read_chunks); + g_test_add_func ("/memory-input-stream/async", test_async); + g_test_add_func ("/memory-input-stream/seek", test_seek); + g_test_add_func ("/memory-input-stream/truncate", test_truncate); + g_test_add_func ("/memory-input-stream/read-bytes", test_read_bytes); + g_test_add_func ("/memory-input-stream/from-bytes", test_from_bytes); + + return g_test_run(); +} diff --git a/gio/tests/memory-monitor-dbus.py.in b/gio/tests/memory-monitor-dbus.py.in new file mode 100755 index 0000000..bf32918 --- /dev/null +++ b/gio/tests/memory-monitor-dbus.py.in @@ -0,0 +1,115 @@ +#!/usr/bin/python3 + +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) any +# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text +# of the license. + +__author__ = 'Bastien Nocera' +__email__ = 'hadess@hadess.net' +__copyright__ = '(c) 2019 Red Hat Inc.' +__license__ = 'LGPL 3+' + +import unittest +import sys +import subprocess +import fcntl +import os +import time + +import taptestrunner + +try: + # Do all non-standard imports here so we can skip the tests if any + # needed packages are not available. + import dbus + import dbus.mainloop.glib + import dbusmock + from gi.repository import GLib + from gi.repository import Gio + + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + class TestLowMemoryMonitor(dbusmock.DBusTestCase): + '''Test GMemoryMonitorDBus''' + + @classmethod + def setUpClass(klass): + klass.start_system_bus() + klass.dbus_con = klass.get_dbus(True) + + def setUp(self): + try: + Gio.MemoryMonitor + except AttributeError: + raise unittest.SkipTest('Low memory monitor not in ' + 'introspection data. Requires ' + 'GObject-Introspection ≥ 1.63.2') + try: + (self.p_mock, self.obj_lmm) = self.spawn_server_template( + 'low_memory_monitor', {}, stdout=subprocess.PIPE) + except ModuleNotFoundError: + raise unittest.SkipTest("Low memory monitor dbusmock template not " + "found. Requires dbusmock ≥ 0.18.4.") + # set log to nonblocking + flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) + fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) + self.last_warning = -1 + self.dbusmock = dbus.Interface(self.obj_lmm, dbusmock.MOCK_IFACE) + self.memory_monitor = Gio.MemoryMonitor.dup_default() + self.memory_monitor.connect("low-memory-warning", self.memory_warning_cb) + self.mainloop = GLib.MainLoop() + self.main_context = self.mainloop.get_context() + + def tearDown(self): + self.p_mock.terminate() + self.p_mock.wait() + + def assertEventually(self, condition, message=None, timeout=50): + '''Assert that condition function eventually returns True. + + Timeout is in deciseconds, defaulting to 50 (5 seconds). message is + printed on failure. + ''' + while timeout >= 0: + context = GLib.MainContext.default() + while context.iteration(False): + pass + if condition(): + break + timeout -= 1 + time.sleep(0.1) + else: + self.fail(message or 'timed out waiting for ' + str(condition)) + + def memory_warning_cb(self, monitor, level): + self.last_warning = level + self.main_context.wakeup() + + def test_low_memory_warning_signal(self): + '''LowMemoryWarning signal''' + + # Wait 2 seconds + timeout = 2 + while timeout > 0: + time.sleep(0.5) + timeout -= 0.5 + self.main_context.iteration(False) + + self.dbusmock.EmitWarning(100) + # Wait 2 seconds or until warning + self.assertEventually(lambda: self.last_warning == 100, "'100' low-memory warning not received", 20) + + self.dbusmock.EmitWarning(255) + # Wait 2 seconds or until warning + self.assertEventually(lambda: self.last_warning == 255, "'255' low-memory warning not received", 20) + +except ImportError as e: + @unittest.skip("Cannot import %s" % e.name) + class TestLowMemoryMonitor(unittest.TestCase): + def test_low_memory_warning_signal(self): + pass + +if __name__ == '__main__': + unittest.main(testRunner=taptestrunner.TAPTestRunner()) diff --git a/gio/tests/memory-monitor-portal.py.in b/gio/tests/memory-monitor-portal.py.in new file mode 100755 index 0000000..748cee8 --- /dev/null +++ b/gio/tests/memory-monitor-portal.py.in @@ -0,0 +1,133 @@ +#!/usr/bin/python3 + +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) any +# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text +# of the license. + +__author__ = 'Bastien Nocera' +__email__ = 'hadess@hadess.net' +__copyright__ = '(c) 2019 Red Hat Inc.' +__license__ = 'LGPL 3+' + +import unittest +import sys +import subprocess +import fcntl +import os +import time + +import taptestrunner + +try: + # Do all non-standard imports here so we can skip the tests if any + # needed packages are not available. + import dbus + import dbus.mainloop.glib + import dbusmock + from gi.repository import GLib + from gi.repository import Gio + + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal" + + class TestLowMemoryMonitorPortal(dbusmock.DBusTestCase): + '''Test GMemoryMonitorPortal''' + + @classmethod + def setUpClass(klass): + klass.start_system_bus() + klass.dbus_con = klass.get_dbus(True) + # Start session bus so that xdg-desktop-portal can run on it + klass.start_session_bus() + + def setUp(self): + try: + Gio.MemoryMonitor + except AttributeError: + raise unittest.SkipTest('Low memory monitor not in ' + 'introspection data. Requires ' + 'GObject-Introspection ≥ 1.63.2') + try: + (self.p_mock, self.obj_lmm) = self.spawn_server_template( + 'low_memory_monitor', {}, stdout=subprocess.PIPE) + except ModuleNotFoundError: + raise unittest.SkipTest("Low memory monitor dbusmock template not " + "found. Requires dbusmock ≥ 0.18.4.") + # set log to nonblocking + flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) + fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) + self.last_warning = -1 + self.dbusmock = dbus.Interface(self.obj_lmm, dbusmock.MOCK_IFACE) + try: + self.xdp = subprocess.Popen([XDG_DESKTOP_PORTAL_PATH]) + except FileNotFoundError: + raise unittest.SkipTest("xdg-desktop-portal not available") + + try: + self.wait_for_bus_object('org.freedesktop.portal.Desktop', + '/org/freedesktop/portal/desktop') + except: + raise + # subprocess.Popen(['gdbus', 'monitor', '--session', '--dest', 'org.freedesktop.portal.Desktop']) + + os.environ['GTK_USE_PORTAL'] = "1" + self.memory_monitor = Gio.MemoryMonitor.dup_default() + assert("GMemoryMonitorPortal" in str(self.memory_monitor)) + self.memory_monitor.connect("low-memory-warning", self.portal_memory_warning_cb) + self.mainloop = GLib.MainLoop() + self.main_context = self.mainloop.get_context() + + def tearDown(self): + self.p_mock.terminate() + self.p_mock.wait() + + def assertEventually(self, condition, message=None, timeout=50): + '''Assert that condition function eventually returns True. + + Timeout is in deciseconds, defaulting to 50 (5 seconds). message is + printed on failure. + ''' + while timeout >= 0: + context = GLib.MainContext.default() + while context.iteration(False): + pass + if condition(): + break + timeout -= 1 + time.sleep(0.1) + else: + self.fail(message or 'timed out waiting for ' + str(condition)) + + def portal_memory_warning_cb(self, monitor, level): + self.last_warning = level + self.main_context.wakeup() + + def test_low_memory_warning_portal_signal(self): + '''LowMemoryWarning signal''' + + # Wait 2 seconds + timeout = 2 + while timeout > 0: + time.sleep(0.5) + timeout -= 0.5 + self.main_context.iteration(False) + + self.dbusmock.EmitWarning(100) + # Wait 2 seconds or until warning + self.assertEventually(lambda: self.last_warning == 100, "'100' low-memory warning not received", 20) + + self.dbusmock.EmitWarning(255) + # Wait 2 seconds or until warning + self.assertEventually(lambda: self.last_warning == 255, "'255' low-memory warning not received", 20) + +except ImportError as e: + @unittest.skip("Cannot import %s" % e.name) + class TestLowMemoryMonitorPortal(unittest.TestCase): + def test_low_memory_warning_portal_signal(self): + pass + +if __name__ == '__main__': + unittest.main(testRunner=taptestrunner.TAPTestRunner()) diff --git a/gio/tests/memory-monitor.c b/gio/tests/memory-monitor.c new file mode 100644 index 0000000..bef6d0f --- /dev/null +++ b/gio/tests/memory-monitor.c @@ -0,0 +1,72 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +static void +test_dup_default (void) +{ + GMemoryMonitor *monitor; + + monitor = g_memory_monitor_dup_default (); + g_assert_nonnull (monitor); + g_object_unref (monitor); +} + +static void +warning_cb (GMemoryMonitor *m, + GMemoryMonitorWarningLevel level) +{ + char *str = g_enum_to_string (G_TYPE_MEMORY_MONITOR_WARNING_LEVEL, level); + g_message ("Warning level: %s (%d)", str , level); + g_free (str); +} + +static void +do_watch_memory (void) +{ + GMemoryMonitor *m; + GMainLoop *loop; + + m = g_memory_monitor_dup_default (); + g_signal_connect (G_OBJECT (m), "low-memory-warning", + G_CALLBACK (warning_cb), NULL); + + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); +} + +int +main (int argc, char **argv) +{ + int ret; + + if (argc == 2 && !strcmp (argv[1], "--watch")) + { + do_watch_memory (); + return 0; + } + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/memory-monitor/default", test_dup_default); + + ret = g_test_run (); + + return ret; +} diff --git a/gio/tests/memory-output-stream.c b/gio/tests/memory-output-stream.c new file mode 100644 index 0000000..ec1644e --- /dev/null +++ b/gio/tests/memory-output-stream.c @@ -0,0 +1,465 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc. + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#include +#include +#include +#include + +static void +test_truncate (void) +{ + GOutputStream *mo; + GDataOutputStream *o; + int i; + GError *error = NULL; + guint8 *data; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540423"); + + mo = g_memory_output_stream_new_resizable (); + g_assert (g_seekable_can_truncate (G_SEEKABLE (mo))); + o = g_data_output_stream_new (mo); + for (i = 0; i < 1000; i++) + { + g_data_output_stream_put_byte (o, 1, NULL, &error); + g_assert_no_error (error); + } + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 1000); + g_seekable_truncate (G_SEEKABLE (mo), 0, NULL, &error); + g_assert_cmpuint (g_seekable_tell (G_SEEKABLE (mo)), ==, 1000); + + g_assert_no_error (error); + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 0); + for (i = 0; i < 2000; i++) + { + g_data_output_stream_put_byte (o, 2, NULL, &error); + g_assert_no_error (error); + } + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 3000); + + data = (guint8 *)g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo)); + + /* The 1's written initially were lost when we truncated to 0 + * and then started writing at position 1000. + */ + for (i = 0; i < 1000; i++) + g_assert_cmpuint (data[i], ==, 0); + for (i = 1000; i < 3000; i++) + g_assert_cmpuint (data[i], ==, 2); + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=720080"); + + g_seekable_truncate (G_SEEKABLE (mo), 8192, NULL, &error); + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 8192); + + data = (guint8 *)g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo)); + for (i = 3000; i < 8192; i++) + g_assert_cmpuint (data[i], ==, 0); + + g_object_unref (o); + g_object_unref (mo); +} + +static void +test_seek_fixed (void) +{ + GOutputStream *mo; + GError *error; + + mo = g_memory_output_stream_new (g_new (gchar, 100), 100, NULL, g_free); + + g_assert (G_IS_SEEKABLE (mo)); + g_assert (g_seekable_can_seek (G_SEEKABLE (mo))); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0); + + error = NULL; + g_assert (!g_seekable_seek (G_SEEKABLE (mo), 222, G_SEEK_CUR, NULL, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_clear_error (&error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), 26, G_SEEK_SET, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 26); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), 20, G_SEEK_CUR, NULL, &error)); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46); + g_assert_no_error (error); + + g_assert (!g_seekable_seek (G_SEEKABLE (mo), 200, G_SEEK_CUR, NULL, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_clear_error (&error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46); + + g_assert (!g_seekable_seek (G_SEEKABLE (mo), 1, G_SEEK_END, NULL, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_clear_error (&error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_END, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 100); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), -1, G_SEEK_END, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 99); + + g_object_unref (mo); +} + +static void +test_seek_resizable_stream (GOutputStream *mo) +{ + GError *error; + + g_assert (G_IS_SEEKABLE (mo)); + g_assert (g_seekable_can_seek (G_SEEKABLE (mo))); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0); + + error = NULL; + g_assert (g_seekable_seek (G_SEEKABLE (mo), 222, G_SEEK_CUR, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 222); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), 26, G_SEEK_SET, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 26); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), 20, G_SEEK_CUR, NULL, &error)); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46); + g_assert_no_error (error); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), 200, G_SEEK_CUR, NULL, &error)); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 246); + g_assert_no_error (error); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), 1, G_SEEK_END, NULL, &error)); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 1); + g_assert_no_error (error); + + g_assert (g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_END, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0); + + /* The 'end' is still zero, so this should fail */ + g_assert (!g_seekable_seek (G_SEEKABLE (mo), -1, G_SEEK_END, NULL, &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_clear_error (&error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0); +} + +static void +test_seek_resizable (void) +{ + GOutputStream *mo; + gint i; + + /* For resizable streams, the initially allocated size is purely an + * implementation detail. We should not be able to tell the + * difference based on the seek API, so make a bunch of streams with + * different sizes and subject them to the same test. + */ + for (i = 0; i < 1024; i++) + { + mo = g_memory_output_stream_new (g_malloc (i), i, g_realloc, g_free); + + test_seek_resizable_stream (mo); + + g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 0); + /* No writes = no resizes */ + g_assert_cmpint (g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, i); + + g_object_unref (mo); + } +} + +static void +test_data_size (void) +{ + GOutputStream *mo; + GDataOutputStream *o; + int pos; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540459"); + + mo = g_memory_output_stream_new_resizable (); + o = g_data_output_stream_new (mo); + g_data_output_stream_put_byte (o, 1, NULL, NULL); + pos = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)); + g_assert_cmpint (pos, ==, 1); + + g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_CUR, NULL, NULL); + pos = g_seekable_tell (G_SEEKABLE (mo)); + g_assert_cmpint (pos, ==, 1); + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540461"); + + g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_SET, NULL, NULL); + pos = g_seekable_tell (G_SEEKABLE (mo)); + g_assert_cmpint (pos, ==, 0); + + pos = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)); + g_assert_cmpint (pos, ==, 1); + + g_assert_cmpint (g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 16); + + g_object_unref (o); + g_object_unref (mo); +} + +static void +test_properties (void) +{ + GOutputStream *mo; + GDataOutputStream *o; + int i; + GError *error = NULL; + gsize data_size_fun; + gsize data_size_prop = 0; + gpointer data_fun; + gpointer data_prop; + gpointer func; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=605733"); + + mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM, + "realloc-function", g_realloc, + "destroy-function", g_free, + NULL); + o = g_data_output_stream_new (mo); + + for (i = 0; i < 1000; i++) + { + g_data_output_stream_put_byte (o, 1, NULL, &error); + g_assert_no_error (error); + } + + data_size_fun = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)); + g_object_get (mo, "data-size", &data_size_prop, NULL); + g_assert_cmpint (data_size_fun, ==, data_size_prop); + + data_fun = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo)); + g_object_get (mo, "data", &data_prop, NULL); + g_assert_cmphex (GPOINTER_TO_SIZE (data_fun), ==, GPOINTER_TO_SIZE (data_prop)); + + g_object_get (mo, "realloc-function", &func, NULL); + g_assert (func == g_realloc); + g_object_get (mo, "destroy-function", &func, NULL); + g_assert (func == g_free); + + data_size_fun = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo)); + g_object_get (mo, "size", &data_size_prop, NULL); + g_assert_cmpint (data_size_fun, ==, data_size_prop); + + g_object_unref (o); + g_object_unref (mo); +} + +static void +test_write_bytes (void) +{ + GOutputStream *mo; + GBytes *bytes, *bytes2; + GError *error = NULL; + + mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM, + "realloc-function", g_realloc, + "destroy-function", g_free, + NULL); + bytes = g_bytes_new_static ("hello world!", strlen ("hello world!") + 1); + g_output_stream_write_bytes (mo, bytes, NULL, &error); + g_assert_no_error (error); + + g_output_stream_close (mo, NULL, &error); + g_assert_no_error (error); + + bytes2 = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mo)); + g_object_unref (mo); + g_assert (g_bytes_equal (bytes, bytes2)); + + g_bytes_unref (bytes); + g_bytes_unref (bytes2); +} + +static void +test_write_null (void) +{ + GOutputStream *mo; + GError *error = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2471"); + + mo = g_memory_output_stream_new_resizable (); + g_output_stream_write_all (mo, NULL, 0, NULL, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (0, ==, g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo))); + + g_output_stream_close (mo, NULL, &error); + g_assert_no_error (error); + g_object_unref (mo); +} + +/* Test that writev() works on #GMemoryOutputStream with a non-empty set of vectors. This + * covers the default writev() implementation around write(). */ +static void +test_writev (void) +{ + GOutputStream *mo; + GError *error = NULL; + gboolean res; + gsize bytes_written; + GOutputVector vectors[3]; + const guint8 buffer[] = {1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 1, 2, 3}; + guint8 *output_buffer; + + vectors[0].buffer = buffer; + vectors[0].size = 5; + + vectors[1].buffer = buffer + vectors[0].size; + vectors[1].size = 12; + + vectors[2].buffer = buffer + vectors[0].size + vectors[1].size; + vectors[2].size = 3; + + mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM, + "realloc-function", g_realloc, + "destroy-function", g_free, + NULL); + res = g_output_stream_writev_all (mo, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (bytes_written, ==, sizeof buffer); + + g_output_stream_close (mo, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpuint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, sizeof buffer); + output_buffer = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo)); + g_assert_cmpmem (output_buffer, sizeof buffer, buffer, sizeof buffer); + + g_object_unref (mo); +} + +/* Test that writev_nonblocking() works on #GMemoryOutputStream with a non-empty set of vectors. This + * covers the default writev_nonblocking() implementation around write_nonblocking(). */ +static void +test_writev_nonblocking (void) +{ + GOutputStream *mo; + GError *error = NULL; + gboolean res; + gsize bytes_written; + GOutputVector vectors[3]; + const guint8 buffer[] = {1, 2, 3, 4, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 1, 2, 3}; + guint8 *output_buffer; + + vectors[0].buffer = buffer; + vectors[0].size = 5; + + vectors[1].buffer = buffer + vectors[0].size; + vectors[1].size = 12; + + vectors[2].buffer = buffer + vectors[0].size + vectors[1].size; + vectors[2].size = 3; + + mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM, + "realloc-function", g_realloc, + "destroy-function", g_free, + NULL); + res = g_pollable_output_stream_writev_nonblocking (G_POLLABLE_OUTPUT_STREAM (mo), + vectors, G_N_ELEMENTS (vectors), + &bytes_written, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (res, ==, G_POLLABLE_RETURN_OK); + g_assert_cmpuint (bytes_written, ==, sizeof buffer); + + g_output_stream_close (mo, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpuint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, sizeof buffer); + output_buffer = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo)); + g_assert_cmpmem (output_buffer, sizeof buffer, buffer, sizeof buffer); + + g_object_unref (mo); +} + +static void +test_steal_as_bytes (void) +{ + GOutputStream *mo; + GDataOutputStream *o; + GError *error = NULL; + GBytes *bytes; + gsize size; + + mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM, + "realloc-function", g_realloc, + "destroy-function", g_free, + NULL); + o = g_data_output_stream_new (mo); + + g_data_output_stream_put_string (o, "hello ", NULL, &error); + g_assert_no_error (error); + + g_data_output_stream_put_string (o, "world!", NULL, &error); + g_assert_no_error (error); + + g_data_output_stream_put_byte (o, '\0', NULL, &error); + g_assert_no_error (error); + + g_output_stream_close ((GOutputStream*) o, NULL, &error); + g_assert_no_error (error); + + bytes = g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)mo); + g_object_unref (mo); + + g_assert_cmpint (g_bytes_get_size (bytes), ==, strlen ("hello world!") + 1); + g_assert_cmpstr (g_bytes_get_data (bytes, &size), ==, "hello world!"); + + g_bytes_unref (bytes); + g_object_unref (o); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/memory-output-stream/truncate", test_truncate); + g_test_add_func ("/memory-output-stream/seek/fixed", test_seek_fixed); + g_test_add_func ("/memory-output-stream/seek/resizable", test_seek_resizable); + g_test_add_func ("/memory-output-stream/get-data-size", test_data_size); + g_test_add_func ("/memory-output-stream/properties", test_properties); + g_test_add_func ("/memory-output-stream/write-bytes", test_write_bytes); + g_test_add_func ("/memory-output-stream/write-null", test_write_null); + g_test_add_func ("/memory-output-stream/writev", test_writev); + g_test_add_func ("/memory-output-stream/writev_nonblocking", test_writev_nonblocking); + g_test_add_func ("/memory-output-stream/steal_as_bytes", test_steal_as_bytes); + + return g_test_run(); +} diff --git a/gio/tests/memory-settings-backend.c b/gio/tests/memory-settings-backend.c new file mode 100644 index 0000000..80e9919 --- /dev/null +++ b/gio/tests/memory-settings-backend.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2022 Ryan Hope + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Hope + */ + +#include +#include +#define G_SETTINGS_ENABLE_BACKEND +#include + +/* Test that the "gsettings-backend" extension point has been registered. + * Must be run first and separetly from other GSettingsBackend, + * as they will register the extension point making the test useless. + */ +static void +test_extension_point_registered (void) +{ + GSettingsBackend *backend; + GIOExtensionPoint *extension_point; + + backend = g_memory_settings_backend_new (); + g_assert_true (G_IS_SETTINGS_BACKEND (backend)); + + extension_point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME); + g_assert_nonnull (extension_point); + + g_object_unref (backend); +} + +int +main (int argc, char *argv[]) +{ + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + /* Must be run first */ + g_test_add_func ("/memory-settings-backend/extension-point-registered", test_extension_point_registered); + + return g_test_run (); +} diff --git a/gio/tests/meson.build b/gio/tests/meson.build new file mode 100644 index 0000000..383d843 --- /dev/null +++ b/gio/tests/meson.build @@ -0,0 +1,927 @@ +common_gio_tests_deps = [ + libglib_dep, + libgmodule_dep, + libgobject_dep, + libgio_dep, +] + +test_c_args = [ + '-DG_LOG_DOMAIN="GLib-GIO"', + '-DGLIB_MKENUMS="@0@"'.format(glib_mkenums), + '-DGLIB_COMPILE_SCHEMAS="@0@"'.format(glib_compile_schemas.full_path()), + '-UG_DISABLE_ASSERT', +] + +# workaround for https://github.com/mesonbuild/meson/issues/6880 +if build_machine.system() == 'linux' + libutil_name = 'libutil' + libutil = run_command('sh', '-c', + '''ldconfig -p | grep -o "[[:space:]]@0@\.so\(\.[0-9]\+\)\?\b"''' + .format(libutil_name), check: false).stdout().strip().split('\n') + + if libutil.length() > 0 + message('Found libutil as @0@'.format(libutil[0])) + test_c_args += '-DLIBUTIL_SONAME="@0@"'.format(libutil[0]) + else + warning('libutil not found') + endif # libutil.length() > 0 +endif # build_machine.system() == 'linux' + +if host_machine.system() == 'windows' + common_gio_tests_deps += [iphlpapi_dep, winsock2, cc.find_library ('secur32')] +endif + +subdir('gdbus-object-manager-example') + +gengiotypefuncs_prog = find_program('gengiotypefuncs.py') +giotypefuncs_inc = custom_target( + 'giotypefuncs.inc', + output : 'giotypefuncs.inc', + input : gio_headers + [gioenumtypes_h] + gobject_install_headers, + command: [gengiotypefuncs_prog, '@OUTPUT@', '@INPUT@']) + +# Test programs buildable on all platforms +gio_tests = { + 'appmonitor' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'async-close-output-stream' : {}, + 'async-splice-output-stream' : {}, + 'buffered-input-stream' : {}, + 'buffered-output-stream' : {}, + 'cancellable' : {}, + 'contexts' : {}, + 'contenttype' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 / https://gitlab.gnome.org/GNOME/glib/-/issues/1251 + 'should_fail' : host_system == 'darwin', + }, + 'converter-stream' : {}, + 'credentials' : {}, + 'data-input-stream' : {}, + 'data-output-stream' : {}, + 'fileattributematcher' : {}, + 'filter-streams' : {}, + 'giomodule' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'gsubprocess' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'g-file' : {}, + 'g-file-info' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'g-icon' : {}, + 'gdbus-addresses' : {}, + 'gdbus-message' : {}, + 'inet-address' : {}, + 'io-stream' : {}, + 'memory-input-stream' : {}, + 'memory-monitor' : {}, + 'memory-output-stream' : {}, + 'memory-settings-backend' : {}, + 'mount-operation' : {}, + 'network-address' : {'extra_sources': ['mock-resolver.c']}, + 'network-monitor' : {}, + 'network-monitor-race' : {}, + 'null-settings-backend' : {}, + 'permission' : {}, + 'pollable' : {'dependencies' : [libdl_dep]}, + 'power-profile-monitor' : {}, + 'proxy-test' : {}, + 'readwrite' : {}, + 'simple-async-result' : {}, + 'simple-proxy' : {}, + 'sleepy-stream' : {}, + 'socket' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'socket-listener' : {}, + 'socket-service' : {}, + 'srvtarget' : {}, + 'task' : {}, + 'vfs' : {}, + 'volumemonitor' : {}, + 'glistmodel' : {}, + 'testfilemonitor' : {'suite' : ['slow', 'flaky']}, + 'thumbnail-verification' : {}, + 'tls-certificate' : {'extra_sources' : ['gtesttlsbackend.c']}, + 'tls-interaction' : {'extra_sources' : ['gtesttlsbackend.c']}, + 'tls-database' : {'extra_sources' : ['gtesttlsbackend.c']}, + 'tls-bindings' : {'extra_sources' : ['gtesttlsbackend.c']}, + 'gdbus-address-get-session' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'win32-appinfo' : {}, +} + +if have_cxx + gio_tests += { + 'cxx' : { + 'source' : ['cxx.cpp'], + }, + } +endif + +test_extra_programs = { + 'gdbus-connection-flush-helper' : {}, + 'gdbus-testserver' : {}, + 'gsubprocess-testprog' : {}, +} + +python_tests = [ + 'codegen.py', +] + +test_env = environment() +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +test_env.set('GIO_MODULE_DIR', '') + +# Check for libdbus1 - Optional - is only used in the GDBus test cases +# 1.2.14 required for dbus_message_set_serial +dbus1_dep = dependency('dbus-1', required : false, version : '>= 1.2.14') +if not dbus1_dep.found() + if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' + # MSVC: Search for the DBus library by the configuration, which corresponds + # to the output of CMake builds of DBus. Note that debugoptimized + # is really a Release build with .PDB files. + if vs_crt == 'debug' + dbus1_dep = cc.find_library('dbus-1d', required : false) + else + dbus1_dep = cc.find_library('dbus-1', required : false) + endif + endif +endif +if dbus1_dep.found() + glib_conf.set('HAVE_DBUS1', 1) + + gio_tests += { + 'gdbus-serialization' : { + 'extra_sources' : ['gdbus-tests.c'], + 'dependencies' : [dbus1_dep], + }, + 'gdbus-server-auth' : { + 'dependencies' : [dbus1_dep], + }, + } +else + # We can build a cut-down version of this test without libdbus + gio_tests += { + 'gdbus-server-auth' : {}, + } +endif + +have_dbus_daemon = find_program('dbus-daemon', required : false).found() +if have_dbus_daemon + gio_tests += { + 'debugcontroller' : {}, + 'defaultvalue' : {'extra_sources' : [giotypefuncs_inc]}, + } +endif + +# Test programs buildable on UNIX only +if host_machine.system() != 'windows' + gio_tests += { + 'file' : {}, + 'gdbus-peer' : { + 'dependencies' : [libgdbus_example_objectmanager_dep], + 'install_rpath' : installed_tests_execdir, + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'gdbus-peer-object-manager' : {}, + 'live-g-file' : {}, + 'resolver-parsing' : {'dependencies' : [network_libs]}, + 'socket-address' : {}, + 'stream-rw_all' : {}, + 'unix-fd' : {}, + 'unix-mounts' : {}, + 'unix-streams' : {}, + 'g-file-info-filesystem-readonly' : {}, + 'gschema-compile' : {'install' : false}, + 'trash' : {}, + } + + # LD_PRELOAD modules don't work so well with AddressSanitizer + if have_rtld_next and get_option('b_sanitize') == 'none' + gio_tests += { + 'gsocketclient-slow' : { + 'depends' : [ + shared_library('slow-connect-preload', + 'slow-connect-preload.c', + name_prefix : '', + dependencies: libdl_dep, + install_dir : installed_tests_execdir, + install: installed_tests_enabled, + ) + ], + 'env' : { + 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(meson.current_build_dir()) + }, + 'installed_tests_env' : { + 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(installed_tests_execdir), + }, + }, + } + endif + + # Uninstalled because of the check-for-executable logic in DesktopAppInfo + # unable to find the installed executable + if not glib_have_cocoa + gio_tests += { + 'appinfo' : { + 'install' : false, + }, + 'desktop-app-info' : { + 'install' : false, + }, + } + endif + + test_extra_programs += { + 'basic-application' : {}, + 'dbus-launch' : {}, + 'appinfo-test' : {}, + } + + if not glib_have_cocoa + test_extra_programs += { + 'apps' : {}, + } + gio_tests += { + 'mimeapps' : {}, + } + endif + + if have_dbus_daemon + annotate_args = [ + '--annotate', 'org.project.Bar', 'Key1', 'Value1', + '--annotate', 'org.project.Bar', 'org.gtk.GDBus.Internal', 'Value2', + '--annotate', 'org.project.Bar.HelloWorld()', 'Key3', 'Value3', + '--annotate', 'org.project.Bar::TestSignal', 'Key4', 'Value4', + '--annotate', 'org.project.Bar:ay', 'Key5', 'Value5', + '--annotate', 'org.project.Bar.TestPrimitiveTypes()[val_int32]', 'Key6', 'Value6', + '--annotate', 'org.project.Bar.TestPrimitiveTypes()[ret_uint32]', 'Key7', 'Value7', + '--annotate', 'org.project.Bar::TestSignal[array_of_strings]', 'Key8', 'Value8', + ] + # Generate gdbus-test-codegen-generated.{c,h} + gdbus_test_codegen_generated = custom_target('gdbus-test-codegen-generated', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated.h', + 'gdbus-test-codegen-generated.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.project.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'gdbus-test-codegen-generated', + '--c-generate-object-manager', + '--c-generate-autocleanup', 'all', + '--c-namespace', 'Foo_iGen', + '--generate-docbook', 'gdbus-test-codegen-generated-doc', + annotate_args, + '@INPUT@']) + # Generate gdbus-test-codegen-generated-min-required-2-64.{c,h} + gdbus_test_codegen_generated_min_required_2_64 = custom_target('gdbus-test-codegen-generated-min-required-2-64', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated-min-required-2-64.h', + 'gdbus-test-codegen-generated-min-required-2-64.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--glib-min-required', '2.64', + '--interface-prefix', 'org.project.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'gdbus-test-codegen-generated-min-required-2-64', + '--c-generate-object-manager', + '--c-generate-autocleanup', 'all', + '--c-namespace', 'Foo_iGen', + '--generate-docbook', 'gdbus-test-codegen-generated-doc', + annotate_args, + '@INPUT@']) + gdbus_test_codegen_generated_interface_info = [ + custom_target('gdbus-test-codegen-generated-interface-info-h', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated-interface-info.h'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-info-header', + annotate_args, + '--output', '@OUTPUT@', + '@INPUT@']), + custom_target('gdbus-test-codegen-generated-interface-info-c', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated-interface-info.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-info-body', + annotate_args, + '--output', '@OUTPUT@', + '@INPUT@']), + ] + + extra_sources = ['gdbus-sessionbus.c', 'gdbus-tests.c'] + + gio_tests += { + 'actions' : { + 'extra_sources' : extra_sources, + 'suite' : ['slow'], + }, + 'gdbus-auth' : {'extra_sources' : extra_sources}, + 'gdbus-bz627724' : {'extra_sources' : extra_sources}, + 'gdbus-close-pending' : {'extra_sources' : extra_sources}, + 'gdbus-connection' : {'extra_sources' : extra_sources}, + 'gdbus-connection-loss' : {'extra_sources' : extra_sources}, + 'gdbus-connection-slow' : {'extra_sources' : extra_sources}, + 'gdbus-error' : {'extra_sources' : extra_sources}, + 'gdbus-exit-on-close' : {'extra_sources' : extra_sources}, + 'gdbus-export' : { + 'extra_sources' : extra_sources, + 'suite' : ['slow'], + }, + 'gdbus-introspection' : {'extra_sources' : extra_sources}, + 'gdbus-method-invocation' : {'extra_sources' : extra_sources}, + 'gdbus-names' : {'extra_sources' : extra_sources}, + 'gdbus-proxy' : {'extra_sources' : extra_sources}, + 'gdbus-proxy-threads' : { + 'extra_sources' : extra_sources, + 'dependencies' : [dbus1_dep], + }, + 'gdbus-proxy-unique-name' : {'extra_sources' : extra_sources}, + 'gdbus-proxy-well-known-name' : {'extra_sources' : extra_sources}, + 'gdbus-test-codegen' : { + 'extra_sources' : [extra_sources, gdbus_test_codegen_generated, gdbus_test_codegen_generated_interface_info], + 'c_args' : ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'], + }, + 'gdbus-threading' : { + 'extra_sources' : extra_sources, + 'suite' : ['slow'], + }, + 'gmenumodel' : { + 'extra_sources' : extra_sources, + 'suite' : ['slow'], + }, + 'gnotification' : { + 'extra_sources' : [extra_sources, 'gnotification-server.c'], + }, + 'gdbus-test-codegen-old' : { + 'source' : 'gdbus-test-codegen.c', + 'extra_sources' : [extra_sources, gdbus_test_codegen_generated, gdbus_test_codegen_generated_interface_info], + 'c_args' : ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36', + '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36'], + }, + 'gdbus-test-codegen-min-required-2-64' : { + 'source' : 'gdbus-test-codegen.c', + 'extra_sources' : [extra_sources, gdbus_test_codegen_generated_min_required_2_64, gdbus_test_codegen_generated_interface_info], + 'c_args' : ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_64'], + }, + 'gapplication' : {'extra_sources' : extra_sources}, + } + + if not glib_have_cocoa + gio_tests += { + 'dbus-appinfo' : { + 'extra_sources' : extra_sources, + }, + } + endif + + fake_document_portal_generated = custom_target('fake-document-portal-generated', + input : ['../org.freedesktop.portal.Documents.xml'], + output : ['fake-document-portal-generated.h', + 'fake-document-portal-generated.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.freedesktop.portal.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'fake-document-portal-generated', + '--c-namespace', 'Fake', + '@INPUT@']) + + test_extra_programs += { + 'fake-document-portal' : { + 'extra_sources': fake_document_portal_generated, + }, + 'fake-service-name' : {} + } + endif # have_dbus_daemon + + # This test is currently unreliable + executable('gdbus-overflow', 'gdbus-overflow.c', + c_args : test_c_args, + dependencies : common_gio_tests_deps, + install_dir : installed_tests_execdir, + install : installed_tests_enabled) + + gio_tests += { + 'gdbus-connection-flush' : { + 'extra_sources' : ['test-io-stream.c', 'test-pipe-unix.c'], + }, + 'gdbus-non-socket' : { + 'extra_sources' : ['gdbus-tests.c', 'test-io-stream.c', 'test-pipe-unix.c'], + }, + } + + # Generate test.mo from de.po using msgfmt + msgfmt = find_program('msgfmt', required : false) + if msgfmt.found() + subdir('de/LC_MESSAGES') + gio_tests += { + 'gsettings' : { + 'extra_sources' : [test_mo], + 'c_args' : ['-DSRCDIR="@0@"'.format(meson.current_source_dir()), + '-DTEST_LOCALE_PATH="@0@"'.format(test_mo_dir)], + 'install' : false, + }, + } + endif +endif # unix + +# Test programs buildable on Windows only +if host_machine.system() == 'windows' + gio_tests += {'win32-streams' : {}} +endif + +if cc.get_id() != 'msvc' + gio_tests += { + 'autoptr-gio' : { + 'source' : 'autoptr.c', + }, + } +endif + +test_extra_programs += { + 'gio-du' : {'install' : false}, + 'echo-server' : {'install' : false}, + 'filter-cat' : {'install' : false}, + 'gapplication-example-actions' : {'install' : false}, + 'gapplication-example-cmdline' : {'install' : false}, + 'gapplication-example-cmdline2' : {'install' : false}, + 'gapplication-example-cmdline3' : {'install' : false}, + 'gapplication-example-cmdline4' : {'install' : false}, + 'gapplication-example-dbushooks' : {'install' : false}, + 'gapplication-example-open' : {'install' : false}, + 'gdbus-daemon' : { + 'extra_sources' : gdbus_daemon_sources, + 'install' : false, + }, + 'gdbus-example-export' : {'install' : false}, + 'gdbus-example-own-name' : {'install' : false}, + 'gdbus-example-peer' : {'install' : false}, + 'gdbus-example-proxy-subclass' : {'install' : false}, + 'gdbus-example-server' : {'install' : false}, + 'gdbus-example-subtree' : {'install' : false}, + 'gdbus-example-watch-name' : {'install' : false}, + 'gdbus-example-watch-proxy' : {'install' : false}, + 'httpd' : {'install' : false}, + 'proxy' : {'install' : false}, + 'resolver' : {'install' : false}, + 'send-data' : {'install' : false}, + 'socket-server' : {'install' : false}, + 'socket-client' : { + 'extra_sources' : ['gtlsconsoleinteraction.c'], + 'install' : false, + }, +} + +gdbus_example_objectmanager_sources = files( + 'gdbus-example-objectmanager-client.c', + 'gdbus-example-objectmanager-server.c', +) + +if cc.get_id() != 'msvc' and cc.get_id() != 'clang-cl' + test_extra_programs += { + # These three are manual-run tests because they need a session bus but don't bring one up themselves + # FIXME: these build but don't seem to work! + 'gdbus-example-objectmanager-client' : { + 'dependencies' : [libgdbus_example_objectmanager_dep], + 'install' : false, + }, + 'gdbus-example-objectmanager-server' : { + 'dependencies' : [libgdbus_example_objectmanager_dep], + 'install' : false, + }, + 'gdbus-test-fixture' : { + 'dependencies' : [libgdbus_example_objectmanager_dep], + 'install' : false, + }, + } +endif + +if host_machine.system() != 'windows' + test_extra_programs += { + 'gdbus-example-unix-fd-client' : { + 'install' : false, + }, + } +endif + +appinfo_test_desktop_files = [ + 'appinfo-test-gnome.desktop', + 'appinfo-test-notgnome.desktop', + 'appinfo-test.desktop', + 'appinfo-test2.desktop', +] + +cdata = configuration_data() +if installed_tests_enabled + cdata.set('installed_tests_dir', installed_tests_execdir) +else + cdata.set('installed_tests_dir', meson.current_build_dir()) +endif + +foreach appinfo_test_desktop_file : appinfo_test_desktop_files + if installed_tests_enabled + configure_file( + input: appinfo_test_desktop_file + '.in', + output: appinfo_test_desktop_file, + install_dir: installed_tests_execdir, + configuration: cdata, + ) + else + configure_file( + input: appinfo_test_desktop_file + '.in', + output: appinfo_test_desktop_file, + configuration: cdata, + ) + endif +endforeach + +if installed_tests_enabled + install_data( + 'contexts.c', + 'g-icon.c', + 'appinfo-test-actions.desktop', + 'appinfo-test-static.desktop', + 'file.c', + 'org.gtk.test.dbusappinfo.desktop', + 'org.gtk.test.dbusappinfo.flatpak.desktop', + 'test1.overlay', + install_dir : installed_tests_execdir, + ) + install_subdir('x-content', install_dir : installed_tests_execdir) + install_subdir('desktop-files', install_dir : installed_tests_execdir) + install_subdir('thumbnails', install_dir : installed_tests_execdir) + install_subdir('cert-tests', install_dir : installed_tests_execdir) + + cdata = configuration_data() + cdata.set('installed_tests_dir', installed_tests_execdir) + cdata.set('program', 'static-link.py ' + glib_pkgconfigreldir) + configure_file( + input: installed_tests_template, + output: 'static-link.test', + install_dir: installed_tests_metadir, + configuration: cdata + ) + install_subdir('static-link', install_dir : installed_tests_execdir) + install_data('static-link.py', install_dir : installed_tests_execdir) + + monitor_tests = [ + 'memory-monitor-dbus', + 'memory-monitor-portal', + 'power-profile-monitor-dbus', + 'power-profile-monitor-portal' + ] + + foreach monitor_test : monitor_tests + cdata = configuration_data() + cdata.set('installed_tests_dir', installed_tests_execdir) + cdata.set('program', monitor_test + '.py') + cdata.set('env', '') + configure_file( + input: installed_tests_template_tap, + output: monitor_test + '.test', + install_dir: installed_tests_metadir, + configuration: cdata + ) + cdata = configuration_data() + cdata.set('libexecdir', join_paths(glib_prefix, get_option('libexecdir'))) + configure_file( + input: monitor_test + '.py.in', + output: monitor_test + '.py', + install_dir : installed_tests_execdir, + configuration: cdata, + ) + endforeach +endif + +if not meson.is_cross_build() or meson.has_exe_wrapper() + + compiler_type = '--compiler=@0@'.format(cc.get_id()) + + plugin_resources_c = custom_target('plugin-resources.c', + input : 'test4.gresource.xml', + output : 'plugin-resources.c', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--internal', + '--generate-source', + '--c-name', '_g_plugin', + '@INPUT@']) + + shared_module('resourceplugin', 'resourceplugin.c', plugin_resources_c, + link_args : export_dynamic_ldflags, + dependencies : common_gio_tests_deps, + install_dir : installed_tests_execdir, + install : installed_tests_enabled + ) + + # referenced by test2.gresource.xml + big_test_resource = custom_target( + 'gresource-big-test.txt', + input : ['gen-big-test-resource.py'], + output : ['gresource-big-test.txt'], + command : [python, '@INPUT0@', '@OUTPUT@']) + + test_gresource = custom_target('test.gresource', + input : 'test.gresource.xml', + output : 'test.gresource', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '--internal', + '@INPUT@'], + install_dir : installed_tests_execdir, + install : installed_tests_enabled) + + test_resources2_c = custom_target('test_resources2.c', + input : 'test3.gresource.xml', + output : 'test_resources2.c', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--internal', + '--generate', + '--c-name', '_g_test2', + '--manual-register', + '@INPUT@']) + + test_resources2_h = custom_target('test_resources2.h', + input : 'test3.gresource.xml', + output : 'test_resources2.h', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--internal', + '--generate', + '--c-name', '_g_test2', + '--manual-register', + '@INPUT@']) + + test_resources_c = custom_target('test_resources.c', + input : 'test2.gresource.xml', + depends : big_test_resource, + output : 'test_resources.c', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '--internal', + '--generate-source', + '--c-name', '_g_test1', + '@INPUT@']) + + digit_test_resources_c = custom_target('digit_test_resources.c', + input : '111_digit_test.gresource.xml', + output : 'digit_test_resources.c', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '--internal', + '--generate-source', + '--manual-register', + '@INPUT@']) + + digit_test_resources_h = custom_target('digit_test_resources.h', + input : '111_digit_test.gresource.xml', + output : 'digit_test_resources.h', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--internal', + '--generate', + '--manual-register', + '@INPUT@']) + + # referenced by test.gresource.xml + test_generated_txt = configure_file(input : 'test1.txt', + output : 'test-generated.txt', + copy : true, + ) + + resources_extra_sources = [ + test_gresource, + test_resources_c, + test_resources2_c, + test_resources2_h, + digit_test_resources_c, + digit_test_resources_h, + ] + + # Create object file containing resource data for testing the --external-data + # option. Currently only GNU ld and objcopy, or (as of 2019) LLVM ld and + # objcopy, support the right options. + objcopy_supports_add_symbol = false + objcopy = find_program('objcopy', required : false) + if objcopy.found() + # FIXME: This should be `check: true` because we never really expect + # `objcopy --help` to fail, given that `objcopy` exists. However, it does + # fail on FreeBSD because ELF Tool Chain has + # [a bug](https://sourceforge.net/p/elftoolchain/code/3950/). + # This can be changed back to `check: true` once our CI uses a FreeBSD + # version which includes the fix. + # See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2360#note_1318608 + objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol') + endif + + ld = find_program('ld', required : false) + + if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found() + test_gresource_binary = custom_target('test5.gresource', + input : 'test5.gresource.xml', + output : 'test5.gresource', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '--internal', + '@INPUT@'], + install_dir : installed_tests_execdir, + install : installed_tests_enabled) + + # Create resource data file + test_resources_binary_c = custom_target('test_resources_binary.c', + input : 'test5.gresource.xml', + output : 'test_resources_binary.c', + command : [glib_compile_resources, + compiler_type, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '--internal', + '--generate-source', + '--external-data', + '--c-name', '_g_binary_test1', + '@INPUT@']) + + # Create object file containing resource data + test_resources_binary = custom_target('test_resources.o', + input : test_gresource_binary, + output : 'test_resources.o', + command : [ld, + '-z', 'noexecstack', + '-r', + '-b','binary', + '@INPUT@', + '-o','@OUTPUT@']) + + # Rename symbol to match the one in the C file + if cc.get_id() == 'gcc' and host_system == 'windows' + underscore = '_' + else + underscore = '' + endif + test_resources_binary2 = custom_target('test_resources2.o', + input : test_resources_binary, + output : 'test_resources2.o', + command : [objcopy, + '--strip-all', + '--add-symbol', underscore + '_g_binary_test1_resource_data=.data:0', + '@INPUT@', + '@OUTPUT@']) + + resources_extra_sources += [ + test_resources_binary_c, + test_resources_binary2, + ] + endif + + gio_tests += { + 'resources' : { + 'extra_sources' : resources_extra_sources, + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + } +endif + +foreach test_name, extra_args : gio_tests + source = extra_args.get('source', test_name + '.c') + extra_sources = extra_args.get('extra_sources', []) + install = installed_tests_enabled and extra_args.get('install', true) + installed_tests_env = extra_args.get('installed_tests_env', {}) + + if install + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_env_override = '' + if installed_tests_env != {} + envs = [] + foreach var, value : installed_tests_env + envs += '@0@=@1@'.format(var, value) + endforeach + test_env_override = '@0@ @1@ '.format(env_program.path(), ' '.join(envs)) + endif + test_conf.set('env', test_env_override) + configure_file( + input: installed_tests_template_tap, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf + ) + endif + + exe = executable(test_name, [source, extra_sources], + c_args : test_c_args + extra_args.get('c_args', []), + dependencies : common_gio_tests_deps + extra_args.get('dependencies', []), + install_rpath : extra_args.get('install_rpath', ''), + install_dir: installed_tests_execdir, + install: install, + ) + + suite = ['gio'] + extra_args.get('suite', []) + timeout = suite.contains('slow') ? test_timeout_slow : test_timeout + local_test_env = test_env + + foreach var, value : extra_args.get('env', {}) + local_test_env.append(var, value) + endforeach + + test(test_name, exe, + env : local_test_env, + timeout : timeout, + suite : suite, + is_parallel : extra_args.get('is_parallel', true), + depends : extra_args.get('depends', []), + should_fail : extra_args.get('should_fail', false), + ) +endforeach + +foreach program_name, extra_args : test_extra_programs + source = extra_args.get('source', program_name + '.c') + extra_sources = extra_args.get('extra_sources', []) + install = installed_tests_enabled and extra_args.get('install', true) + executable(program_name, [source, extra_sources], + c_args : test_c_args, + dependencies : common_gio_tests_deps + extra_args.get('dependencies', []), + install_dir : installed_tests_execdir, + install : install, + ) +endforeach + +foreach test_name : python_tests + test( + test_name, + python, + args: ['-B', files(test_name)], + env: test_env, + suite: ['gio', 'no-valgrind'], + ) + + if installed_tests_enabled + install_data( + files(test_name), + install_dir: installed_tests_execdir, + install_mode: 'rwxr-xr-x', + ) + + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_conf.set('env', '') + configure_file( + input: installed_tests_template_tap, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf, + ) + endif +endforeach + +# TAP test runner for Python tests +if installed_tests_enabled + install_data( + files('taptestrunner.py'), + install_dir: installed_tests_execdir, + ) +endif + +subdir('services') +subdir('modules') diff --git a/gio/tests/mimeapps.c b/gio/tests/mimeapps.c new file mode 100644 index 0000000..6d77852 --- /dev/null +++ b/gio/tests/mimeapps.c @@ -0,0 +1,648 @@ +#include +#include +#include + +static gboolean +strv_equal (gchar **strv, ...) +{ + gsize count; + va_list list; + const gchar *str; + gboolean res; + + res = TRUE; + count = 0; + va_start (list, strv); + while (1) + { + str = va_arg (list, const gchar *); + if (str == NULL) + break; + if (g_strcmp0 (str, strv[count]) != 0) + { + res = FALSE; + break; + } + count++; + } + va_end (list); + + if (res) + res = g_strv_length (strv) == count; + + return res; +} + +const gchar *myapp_data = + "[Desktop Entry]\n" + "Encoding=UTF-8\n" + "Version=1.0\n" + "Type=Application\n" + "Exec=true %f\n" + "Name=my app\n"; + +const gchar *myapp2_data = + "[Desktop Entry]\n" + "Encoding=UTF-8\n" + "Version=1.0\n" + "Type=Application\n" + "Exec=sleep %f\n" + "Name=my app 2\n"; + +const gchar *myapp3_data = + "[Desktop Entry]\n" + "Encoding=UTF-8\n" + "Version=1.0\n" + "Type=Application\n" + "Exec=sleep 1\n" + "Name=my app 3\n" + "MimeType=image/png;"; + +const gchar *myapp4_data = + "[Desktop Entry]\n" + "Encoding=UTF-8\n" + "Version=1.0\n" + "Type=Application\n" + "Exec=echo %f\n" + "Name=my app 4\n" + "MimeType=image/bmp;"; + +const gchar *myapp5_data = + "[Desktop Entry]\n" + "Encoding=UTF-8\n" + "Version=1.0\n" + "Type=Application\n" + "Exec=true %f\n" + "Name=my app 5\n" + "MimeType=image/bmp;x-scheme-handler/ftp;"; + +const gchar *nosuchapp_data = + "[Desktop Entry]\n" + "Encoding=UTF-8\n" + "Version=1.0\n" + "Type=Application\n" + "Exec=no_such_application %f\n" + "Name=no such app\n"; + +const gchar *defaults_data = + "[Default Applications]\n" + "image/bmp=myapp4.desktop;\n" + "image/png=myapp3.desktop;\n" + "x-scheme-handler/ftp=myapp5.desktop;\n"; + +const gchar *mimecache_data = + "[MIME Cache]\n" + "image/bmp=myapp4.desktop;myapp5.desktop;\n" + "image/png=myapp3.desktop;\n"; + +typedef struct +{ + gchar *mimeapps_list_home; /* (owned) */ +} Fixture; + +/* Set up XDG_DATA_HOME and XDG_DATA_DIRS. + * XDG_DATA_DIRS/applications will contain mimeapps.list + * XDG_DATA_HOME/applications will contain myapp.desktop + * and myapp2.desktop, and no mimeapps.list + */ +static void +setup (Fixture *fixture, + gconstpointer test_data) +{ + const gchar *xdgdatahome; + const gchar * const *xdgdatadirs; + gchar *appdir; + gchar *apphome; + gchar *mimeapps; + gchar *name; + gint res; + GError *error = NULL; + + /* These are already set to a temporary directory through our use of + * %G_TEST_OPTION_ISOLATE_DIRS below. */ + xdgdatahome = g_get_user_data_dir (); + xdgdatadirs = g_get_system_data_dirs (); + + appdir = g_build_filename (xdgdatadirs[0], "applications", NULL); + g_test_message ("creating '%s'", appdir); + res = g_mkdir_with_parents (appdir, 0700); + g_assert_cmpint (res, ==, 0); + + name = g_build_filename (appdir, "mimeapps.list", NULL); + g_test_message ("creating '%s'", name); + g_file_set_contents (name, defaults_data, -1, &error); + g_assert_no_error (error); + g_free (name); + + apphome = g_build_filename (xdgdatahome, "applications", NULL); + g_test_message ("creating '%s'", apphome); + res = g_mkdir_with_parents (apphome, 0700); + g_assert_cmpint (res, ==, 0); + + name = g_build_filename (apphome, "myapp.desktop", NULL); + g_test_message ("creating '%s'", name); + g_file_set_contents (name, myapp_data, -1, &error); + g_assert_no_error (error); + g_free (name); + + name = g_build_filename (apphome, "myapp2.desktop", NULL); + g_test_message ("creating '%s'", name); + g_file_set_contents (name, myapp2_data, -1, &error); + g_assert_no_error (error); + g_free (name); + + name = g_build_filename (apphome, "myapp3.desktop", NULL); + g_test_message ("creating '%s'", name); + g_file_set_contents (name, myapp3_data, -1, &error); + g_assert_no_error (error); + g_free (name); + + name = g_build_filename (apphome, "myapp4.desktop", NULL); + g_test_message ("creating '%s'", name); + g_file_set_contents (name, myapp4_data, -1, &error); + g_assert_no_error (error); + g_free (name); + + name = g_build_filename (apphome, "myapp5.desktop", NULL); + g_test_message ("creating '%s'", name); + g_file_set_contents (name, myapp5_data, -1, &error); + g_assert_no_error (error); + g_free (name); + + name = g_build_filename (apphome, "nosuchapp.desktop", NULL); + g_test_message ("creating '%s'", name); + g_file_set_contents (name, nosuchapp_data, -1, &error); + g_assert_no_error (error); + g_free (name); + + mimeapps = g_build_filename (apphome, "mimeapps.list", NULL); + g_test_message ("removing '%s'", mimeapps); + g_remove (mimeapps); + + name = g_build_filename (apphome, "mimeinfo.cache", NULL); + g_test_message ("creating '%s'", name); + g_file_set_contents (name, mimecache_data, -1, &error); + g_assert_no_error (error); + g_free (name); + + g_free (apphome); + g_free (appdir); + g_free (mimeapps); + + /* Pointer to one of the temporary directories. */ + fixture->mimeapps_list_home = g_build_filename (g_get_user_config_dir (), "mimeapps.list", NULL); +} + +static void +teardown (Fixture *fixture, + gconstpointer test_data) +{ + g_free (fixture->mimeapps_list_home); +} + +static void +test_mime_api (Fixture *fixture, + gconstpointer test_data) +{ + GAppInfo *appinfo; + GAppInfo *appinfo2; + GError *error = NULL; + GAppInfo *def; + GList *list; + const gchar *contenttype = "application/pdf"; + + /* clear things out */ + g_app_info_reset_type_associations (contenttype); + + appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop"); + appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop"); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_null (def); + g_assert_null (list); + + /* 1. add a non-default association */ + g_app_info_add_supports_type (appinfo, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo)); + g_assert_cmpint (g_list_length (list), ==, 1); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 2. add another non-default association */ + g_app_info_add_supports_type (appinfo2, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo)); + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 3. make the first app the default */ + g_app_info_set_as_default_for_type (appinfo, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo)); + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 4. make the second app the last used one */ + g_app_info_set_as_last_used_for_type (appinfo2, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo)); + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo2)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 5. reset everything */ + g_app_info_reset_type_associations (contenttype); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_null (def); + g_assert_null (list); + + g_object_unref (appinfo); + g_object_unref (appinfo2); +} + +/* Repeat the same tests, this time checking that we handle + * mimeapps.list as expected. These tests are different from + * the ones in test_mime_api() in that we directly parse + * mimeapps.list to verify the results. + */ +static void +test_mime_file (Fixture *fixture, + gconstpointer test_data) +{ + gchar **assoc; + GAppInfo *appinfo; + GAppInfo *appinfo2; + GError *error = NULL; + GKeyFile *keyfile; + gchar *str; + gboolean res; + GAppInfo *def; + GList *list; + const gchar *contenttype = "application/pdf"; + + /* clear things out */ + g_app_info_reset_type_associations (contenttype); + + appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop"); + appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop"); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_null (def); + g_assert_null (list); + + /* 1. add a non-default association */ + g_app_info_add_supports_type (appinfo, contenttype, &error); + g_assert_no_error (error); + + keyfile = g_key_file_new (); + g_key_file_load_from_file (keyfile, fixture->mimeapps_list_home, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + + assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error); + g_assert_no_error (error); + g_assert_true (strv_equal (assoc, "myapp.desktop", NULL)); + g_strfreev (assoc); + + /* we've unset XDG_DATA_DIRS so there should be no default */ + assoc = g_key_file_get_string_list (keyfile, "Default Applications", contenttype, NULL, &error); + g_assert_nonnull (error); + g_clear_error (&error); + + g_key_file_free (keyfile); + + /* 2. add another non-default association */ + g_app_info_add_supports_type (appinfo2, contenttype, &error); + g_assert_no_error (error); + + keyfile = g_key_file_new (); + g_key_file_load_from_file (keyfile, fixture->mimeapps_list_home, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + + assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error); + g_assert_no_error (error); + g_assert_true (strv_equal (assoc, "myapp.desktop", "myapp2.desktop", NULL)); + g_strfreev (assoc); + + assoc = g_key_file_get_string_list (keyfile, "Default Applications", contenttype, NULL, &error); + g_assert_nonnull (error); + g_clear_error (&error); + + g_key_file_free (keyfile); + + /* 3. make the first app the default */ + g_app_info_set_as_default_for_type (appinfo, contenttype, &error); + g_assert_no_error (error); + + keyfile = g_key_file_new (); + g_key_file_load_from_file (keyfile, fixture->mimeapps_list_home, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + + assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error); + g_assert_no_error (error); + g_assert_true (strv_equal (assoc, "myapp.desktop", "myapp2.desktop", NULL)); + g_strfreev (assoc); + + str = g_key_file_get_string (keyfile, "Default Applications", contenttype, &error); + g_assert_no_error (error); + g_assert_cmpstr (str, ==, "myapp.desktop"); + g_free (str); + + g_key_file_free (keyfile); + + /* 4. make the second app the last used one */ + g_app_info_set_as_last_used_for_type (appinfo2, contenttype, &error); + g_assert_no_error (error); + + keyfile = g_key_file_new (); + g_key_file_load_from_file (keyfile, fixture->mimeapps_list_home, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + + assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error); + g_assert_no_error (error); + g_assert_true (strv_equal (assoc, "myapp2.desktop", "myapp.desktop", NULL)); + g_strfreev (assoc); + + g_key_file_free (keyfile); + + /* 5. reset everything */ + g_app_info_reset_type_associations (contenttype); + + keyfile = g_key_file_new (); + g_key_file_load_from_file (keyfile, fixture->mimeapps_list_home, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + + res = g_key_file_has_key (keyfile, "Added Associations", contenttype, NULL); + g_assert_false (res); + + res = g_key_file_has_key (keyfile, "Default Applications", contenttype, NULL); + g_assert_false (res); + + g_key_file_free (keyfile); + + g_object_unref (appinfo); + g_object_unref (appinfo2); +} + +/* test interaction between mimeapps.list at different levels */ +static void +test_mime_default (Fixture *fixture, + gconstpointer test_data) +{ + GAppInfo *appinfo; + GAppInfo *appinfo2; + GAppInfo *appinfo3; + GError *error = NULL; + GAppInfo *def; + GList *list; + const gchar *contenttype = "image/png"; + + /* clear things out */ + g_app_info_reset_type_associations (contenttype); + + appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop"); + appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop"); + appinfo3 = (GAppInfo*)g_desktop_app_info_new ("myapp3.desktop"); + + /* myapp3 is set as the default in defaults.list */ + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo3)); + g_assert_cmpint (g_list_length (list), ==, 1); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo3)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 1. add a non-default association */ + g_app_info_add_supports_type (appinfo, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo3)); /* default is unaffected */ + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo3)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 2. add another non-default association */ + g_app_info_add_supports_type (appinfo2, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo3)); + g_assert_cmpint (g_list_length (list), ==, 3); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->next->data, appinfo3)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 3. make the first app the default */ + g_app_info_set_as_default_for_type (appinfo, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo)); + g_assert_cmpint (g_list_length (list), ==, 3); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->next->data, appinfo3)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + g_object_unref (appinfo); + g_object_unref (appinfo2); + g_object_unref (appinfo3); +} + +/* test interaction between mimeinfo.cache, defaults.list and mimeapps.list + * to ensure g_app_info_set_as_last_used_for_type doesn't incorrectly + * change the default + */ +static void +test_mime_default_last_used (Fixture *fixture, + gconstpointer test_data) +{ + GAppInfo *appinfo4; + GAppInfo *appinfo5; + GError *error = NULL; + GAppInfo *def; + GList *list; + const gchar *contenttype = "image/bmp"; + + /* clear things out */ + g_app_info_reset_type_associations (contenttype); + + appinfo4 = (GAppInfo*)g_desktop_app_info_new ("myapp4.desktop"); + appinfo5 = (GAppInfo*)g_desktop_app_info_new ("myapp5.desktop"); + + /* myapp4 is set as the default in defaults.list */ + /* myapp4 and myapp5 can both handle image/bmp */ + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo4)); + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo4)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 1. set default (myapp4) as last used */ + g_app_info_set_as_last_used_for_type (appinfo4, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo4)); /* default is unaffected */ + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo4)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 2. set other (myapp5) as last used */ + g_app_info_set_as_last_used_for_type (appinfo5, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo4)); + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo5)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 3. change the default to myapp5 */ + g_app_info_set_as_default_for_type (appinfo5, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo5)); + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo5)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 4. set myapp4 as last used */ + g_app_info_set_as_last_used_for_type (appinfo4, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo5)); + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo4)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + /* 5. set myapp5 as last used again */ + g_app_info_set_as_last_used_for_type (appinfo5, contenttype, &error); + g_assert_no_error (error); + + def = g_app_info_get_default_for_type (contenttype, FALSE); + list = g_app_info_get_recommended_for_type (contenttype); + g_assert_true (g_app_info_equal (def, appinfo5)); + g_assert_cmpint (g_list_length (list), ==, 2); + g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo5)); + g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4)); + g_object_unref (def); + g_list_free_full (list, g_object_unref); + + g_object_unref (appinfo4); + g_object_unref (appinfo5); +} + +static void +test_scheme_handler (Fixture *fixture, + gconstpointer test_data) +{ + GAppInfo *info, *info5; + + info5 = (GAppInfo*)g_desktop_app_info_new ("myapp5.desktop"); + info = g_app_info_get_default_for_uri_scheme ("ftp"); + g_assert_true (g_app_info_equal (info, info5)); + + g_object_unref (info); + g_object_unref (info5); +} + +/* test that g_app_info_* ignores desktop files with nonexisting executables + */ +static void +test_mime_ignore_nonexisting (Fixture *fixture, + gconstpointer test_data) +{ + GAppInfo *appinfo; + + appinfo = (GAppInfo*)g_desktop_app_info_new ("nosuchapp.desktop"); + g_assert_null (appinfo); +} + +static void +test_all (Fixture *fixture, + gconstpointer test_data) +{ + GList *all, *l; + + all = g_app_info_get_all (); + + for (l = all; l; l = l->next) + g_assert_true (G_IS_APP_INFO (l->data)); + + g_list_free_full (all, g_object_unref); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add ("/appinfo/mime/api", Fixture, NULL, setup, + test_mime_api, teardown); + g_test_add ("/appinfo/mime/default", Fixture, NULL, setup, + test_mime_default, teardown); + g_test_add ("/appinfo/mime/file", Fixture, NULL, setup, + test_mime_file, teardown); + g_test_add ("/appinfo/mime/scheme-handler", Fixture, NULL, setup, + test_scheme_handler, teardown); + g_test_add ("/appinfo/mime/default-last-used", Fixture, NULL, setup, + test_mime_default_last_used, teardown); + g_test_add ("/appinfo/mime/ignore-nonexisting", Fixture, NULL, setup, + test_mime_ignore_nonexisting, teardown); + g_test_add ("/appinfo/all", Fixture, NULL, setup, test_all, teardown); + + return g_test_run (); +} diff --git a/gio/tests/mock-resolver.c b/gio/tests/mock-resolver.c new file mode 100644 index 0000000..397be27 --- /dev/null +++ b/gio/tests/mock-resolver.c @@ -0,0 +1,263 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "mock-resolver.h" + +struct _MockResolver +{ + GResolver parent_instance; + guint ipv4_delay_ms; + guint ipv6_delay_ms; + GList *ipv4_results; + GList *ipv6_results; + GError *ipv4_error; + GError *ipv6_error; +}; + +G_DEFINE_TYPE (MockResolver, mock_resolver, G_TYPE_RESOLVER) + +MockResolver * +mock_resolver_new (void) +{ + return g_object_new (MOCK_TYPE_RESOLVER, NULL); +} + +void +mock_resolver_set_ipv4_delay_ms (MockResolver *self, guint delay_ms) +{ + self->ipv4_delay_ms = delay_ms; +} + +static gpointer +copy_object (gconstpointer obj, gpointer user_data) +{ + return g_object_ref (G_OBJECT (obj)); +} + +void +mock_resolver_set_ipv4_results (MockResolver *self, GList *results) +{ + if (self->ipv4_results) + g_list_free_full (self->ipv4_results, g_object_unref); + self->ipv4_results = g_list_copy_deep (results, copy_object, NULL); +} + +void +mock_resolver_set_ipv4_error (MockResolver *self, GError *error) +{ + g_clear_error (&self->ipv4_error); + if (error) + self->ipv4_error = g_error_copy (error); +} + +void +mock_resolver_set_ipv6_delay_ms (MockResolver *self, guint delay_ms) +{ + self->ipv6_delay_ms = delay_ms; +} + +void +mock_resolver_set_ipv6_results (MockResolver *self, GList *results) +{ + if (self->ipv6_results) + g_list_free_full (self->ipv6_results, g_object_unref); + self->ipv6_results = g_list_copy_deep (results, copy_object, NULL); +} + +void +mock_resolver_set_ipv6_error (MockResolver *self, GError *error) +{ + g_clear_error (&self->ipv6_error); + if (error) + self->ipv6_error = g_error_copy (error); +} + +static gboolean lookup_by_name_cb (gpointer user_data); + +/* Core of the implementation of `lookup_by_name()` in the mock resolver. + * + * It creates a #GSource which will become ready with the resolver results. It + * will become ready either after a timeout, or as an idle callback. This + * simulates doing some actual network-based resolution work. + * + * A previous implementation of this did the work in a thread, but that made it + * hard to synchronise the timeouts with the #GResolver failure timeouts in the + * calling thread, as spawning a worker thread could be subject to non-trivial + * delays. */ +static void +do_lookup_by_name (MockResolver *self, + GTask *task, + GResolverNameLookupFlags flags) +{ + GSource *source = NULL; + + g_task_set_task_data (task, GINT_TO_POINTER (flags), NULL); + + if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY) + source = g_timeout_source_new (self->ipv4_delay_ms); + else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY) + source = g_timeout_source_new (self->ipv6_delay_ms); + else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT) + source = g_idle_source_new (); + else + g_assert_not_reached (); + + g_source_set_callback (source, lookup_by_name_cb, g_object_ref (task), g_object_unref); + g_source_attach (source, g_main_context_get_thread_default ()); + g_source_unref (source); +} + +static gboolean +lookup_by_name_cb (gpointer user_data) +{ + GTask *task = G_TASK (user_data); + MockResolver *self = g_task_get_source_object (task); + GResolverNameLookupFlags flags = GPOINTER_TO_INT (g_task_get_task_data (task)); + + if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY) + { + if (self->ipv4_error) + g_task_return_error (task, g_error_copy (self->ipv4_error)); + else + g_task_return_pointer (task, g_list_copy_deep (self->ipv4_results, copy_object, NULL), NULL); + } + else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY) + { + if (self->ipv6_error) + g_task_return_error (task, g_error_copy (self->ipv6_error)); + else + g_task_return_pointer (task, g_list_copy_deep (self->ipv6_results, copy_object, NULL), NULL); + } + else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT) + { + /* This is only the minimal implementation needed for some tests */ + g_assert (self->ipv4_error == NULL && self->ipv6_error == NULL && self->ipv6_results == NULL); + g_task_return_pointer (task, g_list_copy_deep (self->ipv4_results, copy_object, NULL), NULL); + } + else + g_assert_not_reached (); + + return G_SOURCE_REMOVE; +} + +static void +lookup_by_name_with_flags_async (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MockResolver *self = MOCK_RESOLVER (resolver); + GTask *task = NULL; + + task = g_task_new (resolver, cancellable, callback, user_data); + g_task_set_source_tag (task, lookup_by_name_with_flags_async); + + do_lookup_by_name (self, task, flags); + + g_object_unref (task); +} + +static void +async_result_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GAsyncResult **result_out = user_data; + + g_assert (*result_out == NULL); + *result_out = g_object_ref (result); + + g_main_context_wakeup (g_main_context_get_thread_default ()); +} + +static GList * +lookup_by_name (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GError **error) +{ + MockResolver *self = MOCK_RESOLVER (resolver); + GMainContext *context = NULL; + GList *result = NULL; + GAsyncResult *async_result = NULL; + GTask *task = NULL; + + context = g_main_context_new (); + g_main_context_push_thread_default (context); + + task = g_task_new (resolver, cancellable, async_result_cb, &async_result); + g_task_set_source_tag (task, lookup_by_name); + + /* Set up the resolution job. */ + do_lookup_by_name (self, task, G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT); + + /* Wait for it to complete synchronously. */ + while (async_result == NULL) + g_main_context_iteration (context, TRUE); + + result = g_task_propagate_pointer (G_TASK (async_result), error); + g_object_unref (async_result); + + g_assert_finalize_object (task); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); + + return g_steal_pointer (&result); +} + +static GList * +lookup_by_name_with_flags_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +mock_resolver_finalize (GObject *object) +{ + MockResolver *self = (MockResolver*)object; + + g_clear_error (&self->ipv4_error); + g_clear_error (&self->ipv6_error); + if (self->ipv6_results) + g_list_free_full (self->ipv6_results, g_object_unref); + if (self->ipv4_results) + g_list_free_full (self->ipv4_results, g_object_unref); + + G_OBJECT_CLASS (mock_resolver_parent_class)->finalize (object); +} + +static void +mock_resolver_class_init (MockResolverClass *klass) +{ + GResolverClass *resolver_class = G_RESOLVER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + resolver_class->lookup_by_name_with_flags_async = lookup_by_name_with_flags_async; + resolver_class->lookup_by_name_with_flags_finish = lookup_by_name_with_flags_finish; + resolver_class->lookup_by_name = lookup_by_name; + object_class->finalize = mock_resolver_finalize; +} + +static void +mock_resolver_init (MockResolver *self) +{ +} diff --git a/gio/tests/mock-resolver.h b/gio/tests/mock-resolver.h new file mode 100644 index 0000000..54391d0 --- /dev/null +++ b/gio/tests/mock-resolver.h @@ -0,0 +1,35 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define MOCK_TYPE_RESOLVER (mock_resolver_get_type()) +G_DECLARE_FINAL_TYPE (MockResolver, mock_resolver, MOCK, RESOLVER, GResolver) + +MockResolver *mock_resolver_new (void); +void mock_resolver_set_ipv4_delay_ms (MockResolver *self, guint delay_ms); +void mock_resolver_set_ipv4_results (MockResolver *self, GList *results); +void mock_resolver_set_ipv4_error (MockResolver *self, GError *error); +void mock_resolver_set_ipv6_delay_ms (MockResolver *self, guint delay_ms); +void mock_resolver_set_ipv6_results (MockResolver *self, GList *results); +void mock_resolver_set_ipv6_error (MockResolver *self, GError *error); +G_END_DECLS diff --git a/gio/tests/modules/meson.build b/gio/tests/modules/meson.build new file mode 100644 index 0000000..fa981c4 --- /dev/null +++ b/gio/tests/modules/meson.build @@ -0,0 +1,13 @@ +libtestmodulea = shared_module('testmodulea', 'test-module-a.c', + dependencies : [libglib_dep, libgobject_dep, libgmodule_dep, libgio_dep], + c_args : [ ], + install : installed_tests_enabled, + install_dir : join_paths(installed_tests_execdir, 'modules'), +) + +libtestmoduleb = shared_module('testmoduleb', 'test-module-b.c', + dependencies : [libglib_dep, libgobject_dep, libgmodule_dep, libgio_dep], + c_args : [ ], + install : installed_tests_enabled, + install_dir : join_paths(installed_tests_execdir, 'modules'), +) diff --git a/gio/tests/modules/symbol-visibility.h b/gio/tests/modules/symbol-visibility.h new file mode 100644 index 0000000..e838944 --- /dev/null +++ b/gio/tests/modules/symbol-visibility.h @@ -0,0 +1,20 @@ +#ifndef GLIB_TEST_SYMBOL_VISIBILITY +#define GLIB_TEST_SYMBOL_VISIBILITY + +/* This is the same check that's done in configure to create config.h */ +#ifdef _WIN32 +#ifdef GLIB_STATIC_COMPILATION +#define GLIB_TEST_EXPORT_SYMBOL extern +#else +#ifdef _MSC_VER +#define GLIB_TEST_EXPORT_SYMBOL __declspec(dllexport) extern +#else +#define GLIB_TEST_EXPORT_SYMBOL __attribute__ ((visibility ("default"))) __declspec(dllexport) extern +#endif +#endif +/* Matches GCC and Clang */ +#elif defined(__GNUC__) && (__GNUC__ >= 4) +# define GLIB_TEST_EXPORT_SYMBOL __attribute__((visibility("default"))) extern +#endif + +#endif /* GLIB_TEST_SYMBOL_VISIBILITY */ diff --git a/gio/tests/modules/test-module-a.c b/gio/tests/modules/test-module-a.c new file mode 100644 index 0000000..0a64ea6 --- /dev/null +++ b/gio/tests/modules/test-module-a.c @@ -0,0 +1,63 @@ +/* Test module for GIOModule tests + * Copyright (C) 2013 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "config.h" /* for _GLIB_EXTERN */ + +#include + +#include "symbol-visibility.h" + +typedef struct _TestA { + GObject parent; +} TestA; + +typedef struct _TestAClass { + GObjectClass parent_class; +} TestAClass; + +GType test_a_get_type (void); + +G_DEFINE_TYPE (TestA, test_a, G_TYPE_OBJECT) + +static void +test_a_class_init (TestAClass *class) +{ +} + +static void +test_a_init (TestA *self) +{ +} + +GLIB_TEST_EXPORT_SYMBOL void +g_io_module_load (GIOModule *module) +{ + g_io_extension_point_implement ("test-extension-point", + test_a_get_type (), + "test-a", + 30); +} + +GLIB_TEST_EXPORT_SYMBOL void +g_io_module_unload (GIOModule *module) +{ +} diff --git a/gio/tests/modules/test-module-b.c b/gio/tests/modules/test-module-b.c new file mode 100644 index 0000000..8d3527e --- /dev/null +++ b/gio/tests/modules/test-module-b.c @@ -0,0 +1,63 @@ +/* Test module for GIOModule tests + * Copyright (C) 2013 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "config.h" /* for _GLIB_EXTERN */ + +#include + +#include "symbol-visibility.h" + +typedef struct _TestB { + GObject parent; +} TestB; + +typedef struct _TestBClass { + GObjectClass parent_class; +} TestBClass; + +GType test_b_get_type (void); + +G_DEFINE_TYPE (TestB, test_b, G_TYPE_OBJECT) + +static void +test_b_class_init (TestBClass *class) +{ +} + +static void +test_b_init (TestB *self) +{ +} + +GLIB_TEST_EXPORT_SYMBOL void +g_io_module_load (GIOModule *module) +{ + g_io_extension_point_implement ("test-extension-point", + test_b_get_type (), + "test-b", + 40); +} + +GLIB_TEST_EXPORT_SYMBOL void +g_io_module_unload (GIOModule *module) +{ +} diff --git a/gio/tests/mount-operation.c b/gio/tests/mount-operation.c new file mode 100644 index 0000000..0f8566a --- /dev/null +++ b/gio/tests/mount-operation.c @@ -0,0 +1,132 @@ +/* GLib testing framework examples and tests + * + * Copyright © 2018 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Philip Withnall + */ + +#include +#include + + +/* Smoketest for construction of a #GMountOperation. */ +static void +test_construction (void) +{ + GMountOperation *op = NULL; + + op = g_mount_operation_new (); + g_assert_nonnull (op); + g_assert_true (G_IS_MOUNT_OPERATION (op)); + g_object_unref (op); +} + +/* Test the property getters and setters on #GMountOperation work correctly. */ +static void +test_properties (void) +{ + GMountOperation *op = NULL; + gchar *username = NULL; + gchar *password = NULL; + gboolean anonymous; + gchar *domain = NULL; + GPasswordSave password_save; + int choice; + gboolean hidden_volume; + gboolean system_volume; + guint pim; + + op = g_mount_operation_new (); + + g_object_get (op, + "username", &username, + "password", &password, + "anonymous", &anonymous, + "domain", &domain, + "password-save", &password_save, + "choice", &choice, + "is-tcrypt-hidden-volume", &hidden_volume, + "is-tcrypt-system-volume", &system_volume, + "pim", &pim, + NULL); + + g_assert_cmpstr (username, ==, g_mount_operation_get_username (op)); + g_assert_cmpstr (password, ==, g_mount_operation_get_password (op)); + g_assert_cmpint (anonymous, ==, g_mount_operation_get_anonymous (op)); + g_assert_cmpstr (domain, ==, g_mount_operation_get_domain (op)); + g_assert_cmpint (password_save, ==, g_mount_operation_get_password_save (op)); + g_assert_cmpint (choice, ==, g_mount_operation_get_choice (op)); + g_assert_cmpint (hidden_volume, ==, g_mount_operation_get_is_tcrypt_hidden_volume (op)); + g_assert_cmpint (system_volume, ==, g_mount_operation_get_is_tcrypt_system_volume (op)); + g_assert_cmpuint (pim, ==, g_mount_operation_get_pim (op)); + + g_mount_operation_set_username (op, "username"); + g_assert_cmpstr (g_mount_operation_get_username (op), ==, "username"); + + g_mount_operation_set_password (op, "password"); + g_assert_cmpstr (g_mount_operation_get_password (op), ==, "password"); + + g_mount_operation_set_anonymous (op, !anonymous); + g_assert_cmpint (g_mount_operation_get_anonymous (op), ==, !anonymous); + + g_mount_operation_set_domain (op, "domain"); + g_assert_cmpstr (g_mount_operation_get_domain (op), ==, "domain"); + + g_mount_operation_set_password_save (op, G_PASSWORD_SAVE_NEVER); + g_assert_cmpint (g_mount_operation_get_password_save (op), ==, G_PASSWORD_SAVE_NEVER); + + g_mount_operation_set_choice (op, 5); + g_assert_cmpint (g_mount_operation_get_choice (op), ==, 5); + + g_mount_operation_set_is_tcrypt_hidden_volume (op, !hidden_volume); + g_assert_cmpint (g_mount_operation_get_is_tcrypt_hidden_volume (op), ==, !hidden_volume); + + g_mount_operation_set_is_tcrypt_system_volume (op, !system_volume); + g_assert_cmpint (g_mount_operation_get_is_tcrypt_system_volume (op), ==, !system_volume); + + g_mount_operation_set_pim (op, 5); + g_assert_cmpuint (g_mount_operation_get_pim (op), ==, 5); + + g_object_set (op, + "username", "other-username", + "password", "other-password", + "anonymous", FALSE, + "domain", "other-domain", + "password-save", G_PASSWORD_SAVE_PERMANENTLY, + "choice", 4, + "is-tcrypt-hidden-volume", FALSE, + "is-tcrypt-system-volume", FALSE, + "pim", 4, + NULL); + + g_free (domain); + g_free (password); + g_free (username); + g_object_unref (op); +} + +int +main (int argc, + char *argv[]) +{ + setlocale (LC_ALL, ""); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/mount-operation/construction", test_construction); + g_test_add_func ("/mount-operation/properties", test_properties); + + return g_test_run (); +} diff --git a/gio/tests/network-address.c b/gio/tests/network-address.c new file mode 100644 index 0000000..da4d7f7 --- /dev/null +++ b/gio/tests/network-address.c @@ -0,0 +1,1286 @@ +#include "config.h" +#include "mock-resolver.h" + +#include +#include + +static void +test_basic (void) +{ + GNetworkAddress *address; + guint port; + gchar *hostname; + gchar *scheme; + + address = (GNetworkAddress*)g_network_address_new ("www.gnome.org", 8080); + + g_assert_cmpstr (g_network_address_get_hostname (address), ==, "www.gnome.org"); + g_assert_cmpint (g_network_address_get_port (address), ==, 8080); + + g_object_get (address, "hostname", &hostname, "port", &port, "scheme", &scheme, NULL); + g_assert_cmpstr (hostname, ==, "www.gnome.org"); + g_assert_cmpint (port, ==, 8080); + g_assert_null (scheme); + g_free (hostname); + + g_object_unref (address); +} + +typedef struct { + const gchar *input; + const gchar *scheme; + const gchar *hostname; + guint16 port; + gint error_code; +} ParseTest; + +static ParseTest uri_tests[] = { + { "http://www.gnome.org:2020/start", "http", "www.gnome.org", 2020, -1 }, + { "ftp://joe~:(*)%46@ftp.gnome.org:2020/start", "ftp", "ftp.gnome.org", 2020, -1 }, + { "ftp://[fec0::abcd]/start", "ftp", "fec0::abcd", 8080, -1 }, + { "ftp://[fec0::abcd]:999/start", "ftp", "fec0::abcd", 999, -1 }, + { "ftp://joe%x-@ftp.gnome.org:2020/start", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT }, + { "http://[fec0::abcd%em1]/start", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT }, + { "http://[fec0::abcd%25em1]/start", "http", "fec0::abcd%em1", 8080, -1 }, + { "http://[fec0::abcd%10]/start", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT }, + { "http://[fec0::abcd%25em%31]/start", "http", "fec0::abcd%em1", 8080, -1 }, + { "ftp://ftp.gnome.org/start?foo=bar@baz", "ftp", "ftp.gnome.org", 8080, -1 } +}; + +static void +test_parse_uri (gconstpointer d) +{ + const ParseTest *test = d; + GNetworkAddress *address; + GError *error; + + error = NULL; + address = (GNetworkAddress*)g_network_address_parse_uri (test->input, 8080, &error); + + if (address) + { + g_assert_cmpstr (g_network_address_get_scheme (address), ==, test->scheme); + g_assert_cmpstr (g_network_address_get_hostname (address), ==, test->hostname); + g_assert_cmpint (g_network_address_get_port (address), ==, test->port); + g_assert_no_error (error); + } + else + g_assert_error (error, G_IO_ERROR, test->error_code); + + if (address) + g_object_unref (address); + if (error) + g_error_free (error); +} + +static ParseTest host_tests[] = +{ + { "www.gnome.org", NULL, "www.gnome.org", 1234, -1 }, + { "www.gnome.org:8080", NULL, "www.gnome.org", 8080, -1 }, + { "[2001:db8::1]", NULL, "2001:db8::1", 1234, -1 }, + { "[2001:db8::1]:888", NULL, "2001:db8::1", 888, -1 }, + { "[2001:db8::1%em1]", NULL, "2001:db8::1%em1", 1234, -1 }, + { "[2001:db8::1%25em1]", NULL, "2001:db8::1%25em1", 1234, -1 }, + { "[hostname", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT }, + { "[hostnam]e", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT }, + { "hostname:", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT }, + { "hostname:-1", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT }, + { "hostname:9999999", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT } +}; + +static void +test_parse_host (gconstpointer d) +{ + const ParseTest *test = d; + GNetworkAddress *address; + GError *error; + + error = NULL; + address = (GNetworkAddress*)g_network_address_parse (test->input, 1234, &error); + + if (address) + { + g_assert_null (g_network_address_get_scheme (address)); + g_assert_cmpstr (g_network_address_get_hostname (address), ==, test->hostname); + g_assert_cmpint (g_network_address_get_port (address), ==, test->port); + g_assert_no_error (error); + } + else + { + g_assert_error (error, G_IO_ERROR, test->error_code); + } + + if (address) + g_object_unref (address); + if (error) + g_error_free (error); +} + +typedef struct { + const gchar *input; + gboolean valid_parse, valid_resolve, valid_ip; +} ResolveTest; + +static ResolveTest address_tests[] = { + { "192.168.1.2", TRUE, TRUE, TRUE }, + { "fe80::42", TRUE, TRUE, TRUE }, + + /* g_network_address_parse() accepts these, but they are not + * (just) IP addresses. + */ + { "192.168.1.2:80", TRUE, FALSE, FALSE }, + { "[fe80::42]", TRUE, FALSE, FALSE }, + { "[fe80::42]:80", TRUE, FALSE, FALSE }, + + /* These should not be considered IP addresses by anyone. */ + { "192.168.258", FALSE, FALSE, FALSE }, + { "192.11010306", FALSE, FALSE, FALSE }, + { "3232235778", FALSE, FALSE, FALSE }, + { "0300.0250.0001.0001", FALSE, FALSE, FALSE }, + { "0xC0.0xA8.0x01.0x02", FALSE, FALSE, FALSE }, + { "0xc0.0xa8.0x01.0x02", FALSE, FALSE, FALSE }, + { "0xc0a80102", FALSE, FALSE, FALSE } +}; + +static void +test_resolve_address (gconstpointer d) +{ + const ResolveTest *test = d; + GSocketConnectable *connectable; + GSocketAddressEnumerator *addr_enum; + GSocketAddress *addr; + GError *error = NULL; + + g_test_message ("Input: %s", test->input); + + g_assert_cmpint (test->valid_ip, ==, g_hostname_is_ip_address (test->input)); + + connectable = g_network_address_parse (test->input, 1234, &error); + g_assert_no_error (error); + + addr_enum = g_socket_connectable_enumerate (connectable); + addr = g_socket_address_enumerator_next (addr_enum, NULL, &error); + g_object_unref (addr_enum); + g_object_unref (connectable); + + if (addr) + { + g_assert_true (test->valid_parse); + g_assert_true (G_IS_INET_SOCKET_ADDRESS (addr)); + g_object_unref (addr); + } + else + { + g_assert_false (test->valid_parse); + g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND); + g_error_free (error); + return; + } +} + +/* Technically this should be in a GResolver test program, but we don't + * have one of those since it's mostly impossible to test programmatically. + * So it goes here so it can share the tests. + */ +static void +test_resolve_address_gresolver (gconstpointer d) +{ + const ResolveTest *test = d; + GResolver *resolver; + GList *addrs; + GInetAddress *iaddr; + GError *error = NULL; + + g_test_message ("Input: %s", test->input); + + resolver = g_resolver_get_default (); + addrs = g_resolver_lookup_by_name (resolver, test->input, NULL, &error); + g_object_unref (resolver); + + if (addrs) + { + g_assert_true (test->valid_resolve); + g_assert_cmpint (g_list_length (addrs), ==, 1); + + iaddr = addrs->data; + g_assert_true (G_IS_INET_ADDRESS (iaddr)); + + g_object_unref (iaddr); + g_list_free (addrs); + } + else + { + g_assert_nonnull (error); + g_test_message ("Error: %s", error->message); + g_assert_false (test->valid_resolve); + + if (!test->valid_parse) + { + /* GResolver should have rejected the address internally, in + * which case we're guaranteed to get G_RESOLVER_ERROR_NOT_FOUND. + */ + g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND); + } + else + { + /* If GResolver didn't reject the string itself, then we + * might have attempted to send it over the network. If that + * attempt succeeded, we'd get back NOT_FOUND, but if + * there's no network available we might have gotten some + * other error instead. + */ + } + + g_error_free (error); + return; + } +} + +#define SCOPE_ID_TEST_ADDR "fe80::42" +#define SCOPE_ID_TEST_PORT 99 + +#if defined (HAVE_IF_INDEXTONAME) && defined (HAVE_IF_NAMETOINDEX) +static char SCOPE_ID_TEST_IFNAME[IF_NAMESIZE]; +static int SCOPE_ID_TEST_INDEX; +#else +#define SCOPE_ID_TEST_IFNAME "1" +#define SCOPE_ID_TEST_INDEX 1 +#endif + +static void +find_ifname_and_index (void) +{ + if (SCOPE_ID_TEST_INDEX != 0) + return; + +#if defined (HAVE_IF_INDEXTONAME) && defined (HAVE_IF_NAMETOINDEX) + SCOPE_ID_TEST_INDEX = if_nametoindex ("lo"); + if (SCOPE_ID_TEST_INDEX != 0) + { + g_strlcpy (SCOPE_ID_TEST_IFNAME, "lo", sizeof (SCOPE_ID_TEST_IFNAME)); + return; + } + + for (SCOPE_ID_TEST_INDEX = 1; SCOPE_ID_TEST_INDEX < 1024; SCOPE_ID_TEST_INDEX++) { + if (if_indextoname (SCOPE_ID_TEST_INDEX, SCOPE_ID_TEST_IFNAME)) + break; + } + g_assert_cmpstr (SCOPE_ID_TEST_IFNAME, !=, ""); +#endif +} + +static void +test_scope_id (GSocketConnectable *addr) +{ +#ifndef G_OS_WIN32 + GSocketAddressEnumerator *addr_enum; + GSocketAddress *saddr; + GInetSocketAddress *isaddr; + GInetAddress *iaddr; + char *tostring; + GError *error = NULL; + + addr_enum = g_socket_connectable_enumerate (addr); + saddr = g_socket_address_enumerator_next (addr_enum, NULL, &error); + g_assert_no_error (error); + + g_assert_nonnull (saddr); + g_assert_true (G_IS_INET_SOCKET_ADDRESS (saddr)); + + isaddr = G_INET_SOCKET_ADDRESS (saddr); + g_assert_cmpint (g_inet_socket_address_get_scope_id (isaddr), ==, SCOPE_ID_TEST_INDEX); + g_assert_cmpint (g_inet_socket_address_get_port (isaddr), ==, SCOPE_ID_TEST_PORT); + + iaddr = g_inet_socket_address_get_address (isaddr); + tostring = g_inet_address_to_string (iaddr); + g_assert_cmpstr (tostring, ==, SCOPE_ID_TEST_ADDR); + g_free (tostring); + + g_object_unref (saddr); + saddr = g_socket_address_enumerator_next (addr_enum, NULL, &error); + g_assert_no_error (error); + g_assert_null (saddr); + + g_object_unref (addr_enum); +#else + g_test_skip ("winsock2 getaddrinfo() can’t understand scope IDs"); +#endif +} + +static void +test_host_scope_id (void) +{ + GSocketConnectable *addr; + char *str; + + find_ifname_and_index (); + + str = g_strdup_printf ("%s%%%s", SCOPE_ID_TEST_ADDR, SCOPE_ID_TEST_IFNAME); + addr = g_network_address_new (str, SCOPE_ID_TEST_PORT); + g_free (str); + + test_scope_id (addr); + g_object_unref (addr); +} + +static void +test_uri_scope_id (void) +{ + GSocketConnectable *addr; + char *uri; + GError *error = NULL; + + find_ifname_and_index (); + + uri = g_strdup_printf ("http://[%s%%%s]:%d/foo", + SCOPE_ID_TEST_ADDR, + SCOPE_ID_TEST_IFNAME, + SCOPE_ID_TEST_PORT); + addr = g_network_address_parse_uri (uri, 0, &error); + g_free (uri); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_null (addr); + g_clear_error (&error); + + uri = g_strdup_printf ("http://[%s%%25%s]:%d/foo", + SCOPE_ID_TEST_ADDR, + SCOPE_ID_TEST_IFNAME, + SCOPE_ID_TEST_PORT); + addr = g_network_address_parse_uri (uri, 0, &error); + g_free (uri); + g_assert_no_error (error); + + test_scope_id (addr); + g_object_unref (addr); +} + +static void +test_loopback_basic (void) +{ + GNetworkAddress *addr; /* owned */ + + addr = G_NETWORK_ADDRESS (g_network_address_new_loopback (666)); + + /* Test basic properties. */ + g_assert_cmpstr (g_network_address_get_hostname (addr), ==, "localhost"); + g_assert_cmpuint (g_network_address_get_port (addr), ==, 666); + g_assert_null (g_network_address_get_scheme (addr)); + + g_object_unref (addr); +} + +static void +assert_socket_address_matches (GSocketAddress *a, + const gchar *expected_address, + guint16 expected_port) +{ + GInetSocketAddress *sa; + gchar *str; /* owned */ + + g_assert_true (G_IS_INET_SOCKET_ADDRESS (a)); + + sa = G_INET_SOCKET_ADDRESS (a); + g_assert_cmpint (g_inet_socket_address_get_port (sa), ==, expected_port); + + str = g_inet_address_to_string (g_inet_socket_address_get_address (sa)); + g_assert_cmpstr (str, ==, expected_address); + g_free (str); +} + +static void +test_loopback_sync (void) +{ + GSocketConnectable *addr; /* owned */ + GSocketAddressEnumerator *enumerator; /* owned */ + GSocketAddress *a; /* owned */ + GError *error = NULL; + + addr = g_network_address_new_loopback (616); + enumerator = g_socket_connectable_enumerate (addr); + + /* IPv6 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "::1", 616); + g_object_unref (a); + + /* IPv4 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "127.0.0.1", 616); + g_object_unref (a); + + /* End of results. */ + g_assert_null (g_socket_address_enumerator_next (enumerator, NULL, &error)); + g_assert_no_error (error); + + g_object_unref (enumerator); + g_object_unref (addr); +} + +static void +test_localhost_sync (void) +{ + GSocketConnectable *addr; /* owned */ + GSocketAddressEnumerator *enumerator; /* owned */ + GSocketAddress *a; /* owned */ + GError *error = NULL; + GResolver *original_resolver; /* owned */ + MockResolver *mock_resolver; /* owned */ + GList *ipv4_results = NULL; /* owned */ + + /* This test ensures that variations of the "localhost" hostname always resolve to a loopback address */ + + /* Set up a DNS resolver that returns nonsense for "localhost" */ + original_resolver = g_resolver_get_default (); + mock_resolver = mock_resolver_new (); + g_resolver_set_default (G_RESOLVER (mock_resolver)); + ipv4_results = g_list_append (ipv4_results, g_inet_address_new_from_string ("123.123.123.123")); + mock_resolver_set_ipv4_results (mock_resolver, ipv4_results); + + addr = g_network_address_new ("localhost.", 616); + enumerator = g_socket_connectable_enumerate (addr); + + /* IPv6 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "::1", 616); + g_object_unref (a); + + /* IPv4 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "127.0.0.1", 616); + g_object_unref (a); + + /* End of results. */ + g_assert_null (g_socket_address_enumerator_next (enumerator, NULL, &error)); + g_assert_no_error (error); + g_object_unref (enumerator); + g_object_unref (addr); + + addr = g_network_address_new (".localhost", 616); + enumerator = g_socket_connectable_enumerate (addr); + + /* IPv6 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "::1", 616); + g_object_unref (a); + + /* IPv4 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "127.0.0.1", 616); + g_object_unref (a); + + /* End of results. */ + g_assert_null (g_socket_address_enumerator_next (enumerator, NULL, &error)); + g_assert_no_error (error); + g_object_unref (enumerator); + g_object_unref (addr); + + addr = g_network_address_new ("foo.localhost", 616); + enumerator = g_socket_connectable_enumerate (addr); + + /* IPv6 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "::1", 616); + g_object_unref (a); + + /* IPv4 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "127.0.0.1", 616); + g_object_unref (a); + + /* End of results. */ + g_assert_null (g_socket_address_enumerator_next (enumerator, NULL, &error)); + g_assert_no_error (error); + g_object_unref (enumerator); + g_object_unref (addr); + + addr = g_network_address_new (".localhost.", 616); + enumerator = g_socket_connectable_enumerate (addr); + + /* IPv6 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "::1", 616); + g_object_unref (a); + + /* IPv4 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "127.0.0.1", 616); + g_object_unref (a); + + /* End of results. */ + g_assert_null (g_socket_address_enumerator_next (enumerator, NULL, &error)); + g_assert_no_error (error); + g_object_unref (enumerator); + g_object_unref (addr); + + addr = g_network_address_new ("invalid", 616); + enumerator = g_socket_connectable_enumerate (addr); + + /* IPv4 address. */ + a = g_socket_address_enumerator_next (enumerator, NULL, &error); + g_assert_no_error (error); + assert_socket_address_matches (a, "123.123.123.123", 616); + g_object_unref (a); + + /* End of results. */ + g_assert_null (g_socket_address_enumerator_next (enumerator, NULL, &error)); + g_assert_no_error (error); + g_object_unref (enumerator); + g_object_unref (addr); + + g_resolver_set_default (original_resolver); + g_list_free_full (ipv4_results, (GDestroyNotify) g_object_unref); + g_object_unref (original_resolver); + g_object_unref (mock_resolver); +} + +typedef struct { + GList/* */ *addrs; /* owned */ + GMainLoop *loop; /* owned */ + GSocketAddressEnumerator *enumerator; /* unowned */ + guint delay_ms; + gint expected_error_code; +} AsyncData; + +static void got_addr (GObject *source_object, GAsyncResult *result, gpointer user_data); + +static int +on_delayed_get_addr (gpointer user_data) +{ + AsyncData *data = user_data; + g_socket_address_enumerator_next_async (data->enumerator, NULL, + got_addr, user_data); + return G_SOURCE_REMOVE; +} + +static void +got_addr (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GSocketAddressEnumerator *enumerator; + AsyncData *data; + GSocketAddress *a; /* owned */ + GError *error = NULL; + + enumerator = G_SOCKET_ADDRESS_ENUMERATOR (source_object); + data = user_data; + + a = g_socket_address_enumerator_next_finish (enumerator, result, &error); + + if (data->expected_error_code) + { + g_assert_error (error, G_IO_ERROR, data->expected_error_code); + g_clear_error (&error); + } + else + g_assert_no_error (error); + + if (a == NULL) + { + /* End of results. */ + data->addrs = g_list_reverse (data->addrs); + g_main_loop_quit (data->loop); + } + else + { + g_assert_true (G_IS_INET_SOCKET_ADDRESS (a)); + data->addrs = g_list_prepend (data->addrs, a); + + if (!data->delay_ms) + g_socket_address_enumerator_next_async (enumerator, NULL, + got_addr, user_data); + else + { + data->enumerator = enumerator; + g_timeout_add (data->delay_ms, on_delayed_get_addr, data); + } + } +} + +static void +got_addr_ignored (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GSocketAddressEnumerator *enumerator; + GSocketAddress *a; /* owned */ + GError *error = NULL; + + /* This function simply ignores the returned addresses but keeps enumerating */ + + enumerator = G_SOCKET_ADDRESS_ENUMERATOR (source_object); + + a = g_socket_address_enumerator_next_finish (enumerator, result, &error); + g_assert_no_error (error); + if (a != NULL) + { + g_object_unref (a); + g_socket_address_enumerator_next_async (enumerator, NULL, + got_addr_ignored, user_data); + } +} + + +static void +test_loopback_async (void) +{ + GSocketConnectable *addr; /* owned */ + GSocketAddressEnumerator *enumerator; /* owned */ + AsyncData data = { 0, }; + + addr = g_network_address_new_loopback (610); + enumerator = g_socket_connectable_enumerate (addr); + + /* Get all the addresses. */ + data.addrs = NULL; + data.loop = g_main_loop_new (NULL, FALSE); + + g_socket_address_enumerator_next_async (enumerator, NULL, got_addr, &data); + + g_main_loop_run (data.loop); + g_main_loop_unref (data.loop); + + /* Check results. */ + g_assert_cmpuint (g_list_length (data.addrs), ==, 2); + assert_socket_address_matches (data.addrs->data, "::1", 610); + assert_socket_address_matches (data.addrs->next->data, "127.0.0.1", 610); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); + + g_object_unref (enumerator); + g_object_unref (addr); +} + +static void +test_localhost_async (void) +{ + GSocketConnectable *addr; /* owned */ + GSocketAddressEnumerator *enumerator; /* owned */ + AsyncData data = { 0, }; + GResolver *original_resolver; /* owned */ + MockResolver *mock_resolver; /* owned */ + GList *ipv4_results = NULL; /* owned */ + + /* This test ensures that variations of the "localhost" hostname always resolve to a loopback address */ + + /* Set up a DNS resolver that returns nonsense for "localhost" */ + original_resolver = g_resolver_get_default (); + mock_resolver = mock_resolver_new (); + g_resolver_set_default (G_RESOLVER (mock_resolver)); + ipv4_results = g_list_append (ipv4_results, g_inet_address_new_from_string ("123.123.123.123")); + mock_resolver_set_ipv4_results (mock_resolver, ipv4_results); + + addr = g_network_address_new ("localhost", 610); + enumerator = g_socket_connectable_enumerate (addr); + + /* Get all the addresses. */ + data.addrs = NULL; + data.delay_ms = 1; + data.loop = g_main_loop_new (NULL, FALSE); + + g_socket_address_enumerator_next_async (enumerator, NULL, got_addr, &data); + g_main_loop_run (data.loop); + + /* Check results. */ + g_assert_cmpuint (g_list_length (data.addrs), ==, 2); + assert_socket_address_matches (data.addrs->data, "::1", 610); + assert_socket_address_matches (data.addrs->next->data, "127.0.0.1", 610); + + g_resolver_set_default (original_resolver); + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); + g_list_free_full (ipv4_results, (GDestroyNotify) g_object_unref); + g_object_unref (original_resolver); + g_object_unref (mock_resolver); + g_object_unref (enumerator); + g_object_unref (addr); + g_main_loop_unref (data.loop); +} + +static void +test_to_string (void) +{ + GSocketConnectable *addr = NULL; + gchar *str = NULL; + GError *error = NULL; + + /* Without port. */ + addr = g_network_address_new ("some-hostname", 0); + str = g_socket_connectable_to_string (addr); + g_assert_cmpstr (str, ==, "some-hostname"); + g_free (str); + g_object_unref (addr); + + /* With port. */ + addr = g_network_address_new ("some-hostname", 123); + str = g_socket_connectable_to_string (addr); + g_assert_cmpstr (str, ==, "some-hostname:123"); + g_free (str); + g_object_unref (addr); + + /* With scheme and port. */ + addr = g_network_address_parse_uri ("http://some-hostname:123", 80, &error); + g_assert_no_error (error); + str = g_socket_connectable_to_string (addr); + g_assert_cmpstr (str, ==, "http:some-hostname:123"); + g_free (str); + g_object_unref (addr); + + /* Loopback. */ + addr = g_network_address_new ("localhost", 456); + str = g_socket_connectable_to_string (addr); + g_assert_cmpstr (str, ==, "localhost:456"); + g_free (str); + g_object_unref (addr); +} + +static int +sort_addresses (gconstpointer a, gconstpointer b) +{ + GSocketFamily family_a = g_inet_address_get_family (G_INET_ADDRESS (a)); + GSocketFamily family_b = g_inet_address_get_family (G_INET_ADDRESS (b)); + + if (family_a == family_b) + return 0; + else if (family_a == G_SOCKET_FAMILY_IPV4) + return -1; + else + return 1; +} + +static int +sort_socket_addresses (gconstpointer a, gconstpointer b) +{ + GInetAddress *addr_a = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (a)); + GInetAddress *addr_b = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (b)); + return sort_addresses (addr_a, addr_b); +} + +static void +assert_list_matches_expected (GList *result, GList *expected) +{ + GList *result_copy = NULL; + + g_assert_cmpint (g_list_length (result), ==, g_list_length (expected)); + + /* Sort by ipv4 first which matches the expected list. Do this on a copy of + * @result to avoid modifying the original. */ + result_copy = g_list_copy (result); + result = result_copy = g_list_sort (result_copy, sort_socket_addresses); + + for (; result != NULL; result = result->next, expected = expected->next) + { + GInetAddress *address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (result->data)); + g_assert_true (g_inet_address_equal (address, expected->data)); + } + + g_list_free (result_copy); +} + +typedef struct { + MockResolver *mock_resolver; + GResolver *original_resolver; + GList *input_ipv4_results; + GList *input_ipv6_results; + GList *input_all_results; + GSocketConnectable *addr; + GSocketAddressEnumerator *enumerator; + GMainLoop *loop; +} HappyEyeballsFixture; + +static void +happy_eyeballs_setup (HappyEyeballsFixture *fixture, + gconstpointer data) +{ + static const char * const ipv4_address_strings[] = { "1.1.1.1", "2.2.2.2" }; + static const char * const ipv6_address_strings[] = { "ff::11", "ff::22" }; + gsize i; + + fixture->original_resolver = g_resolver_get_default (); + fixture->mock_resolver = mock_resolver_new (); + g_resolver_set_default (G_RESOLVER (fixture->mock_resolver)); + + for (i = 0; i < G_N_ELEMENTS (ipv4_address_strings); ++i) + { + GInetAddress *ipv4_addr = g_inet_address_new_from_string (ipv4_address_strings[i]); + GInetAddress *ipv6_addr = g_inet_address_new_from_string (ipv6_address_strings[i]); + fixture->input_ipv4_results = g_list_append (fixture->input_ipv4_results, ipv4_addr); + fixture->input_ipv6_results = g_list_append (fixture->input_ipv6_results, ipv6_addr); + fixture->input_all_results = g_list_append (fixture->input_all_results, ipv4_addr); + fixture->input_all_results = g_list_append (fixture->input_all_results, ipv6_addr); + } + fixture->input_all_results = g_list_sort (fixture->input_all_results, sort_addresses); + mock_resolver_set_ipv4_results (fixture->mock_resolver, fixture->input_ipv4_results); + mock_resolver_set_ipv6_results (fixture->mock_resolver, fixture->input_ipv6_results); + + fixture->addr = g_network_address_new ("test.fake", 80); + fixture->enumerator = g_socket_connectable_enumerate (fixture->addr); + + fixture->loop = g_main_loop_new (NULL, FALSE); +} + +static void +happy_eyeballs_teardown (HappyEyeballsFixture *fixture, + gconstpointer data) +{ + g_object_unref (fixture->addr); + g_object_unref (fixture->enumerator); + g_resolver_free_addresses (fixture->input_all_results); + g_list_free (fixture->input_ipv4_results); + g_list_free (fixture->input_ipv6_results); + g_resolver_set_default (fixture->original_resolver); + g_object_unref (fixture->original_resolver); + g_object_unref (fixture->mock_resolver); + g_main_loop_unref (fixture->loop); +} + +static const guint FAST_DELAY_LESS_THAN_TIMEOUT = 25; +static const guint SLOW_DELAY_MORE_THAN_TIMEOUT = 100; + +static void +test_happy_eyeballs_basic (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + + data.delay_ms = FAST_DELAY_LESS_THAN_TIMEOUT; + data.loop = fixture->loop; + + /* This just tests in the common case it gets all results */ + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_all_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); +} + +static void +test_happy_eyeballs_parallel (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GSocketAddressEnumerator *enumerator2; + + enumerator2 = g_socket_connectable_enumerate (fixture->addr); + + data.delay_ms = FAST_DELAY_LESS_THAN_TIMEOUT; + data.loop = fixture->loop; + + /* We run multiple enumerations at once, the results shouldn't be affected. */ + + g_socket_address_enumerator_next_async (enumerator2, NULL, got_addr_ignored, &data); + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_all_results); + + /* Run again to ensure the cache from the previous one is correct */ + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); + data.addrs = NULL; + g_object_unref (enumerator2); + + enumerator2 = g_socket_connectable_enumerate (fixture->addr); + g_socket_address_enumerator_next_async (enumerator2, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_all_results); + + g_object_unref (enumerator2); + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); +} + +static void +test_happy_eyeballs_slow_ipv4 (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + + /* If ipv4 dns response is a bit slow we still get everything */ + + data.loop = fixture->loop; + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_all_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); +} + +static void +test_happy_eyeballs_slow_ipv6 (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + + /* If ipv6 is a bit slow it waits for them */ + + data.loop = fixture->loop; + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_all_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); +} + +static void +test_happy_eyeballs_very_slow_ipv6 (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + + /* If ipv6 is very slow we still get everything */ + + data.loop = fixture->loop; + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, SLOW_DELAY_MORE_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_all_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); +} + +static void +test_happy_eyeballs_slow_connection_and_ipv4 (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + + /* Even if the dns response is slow we still get them if our connection attempts + * take long enough. */ + + data.loop = fixture->loop; + data.delay_ms = SLOW_DELAY_MORE_THAN_TIMEOUT * 2; + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, SLOW_DELAY_MORE_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_all_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); +} + +static void +test_happy_eyeballs_ipv6_error_ipv4_first (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv6_error; + + /* If ipv6 fails, ensuring that ipv4 finishes before ipv6 errors, we still get ipv4. */ + + data.loop = fixture->loop; + ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); + mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_ipv4_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); + g_error_free (ipv6_error); +} + +static void +test_happy_eyeballs_ipv6_error_ipv6_first (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv6_error; + + /* If ipv6 fails, ensuring that ipv6 errors before ipv4 finishes, we still get ipv4. */ + + data.loop = fixture->loop; + ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); + mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_ipv4_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); + g_error_free (ipv6_error); +} + +static void +test_happy_eyeballs_ipv6_error_ipv4_very_slow (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv6_error; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/merge_requests/865"); + g_test_summary ("Ensure that we successfully return IPv4 results even when they come significantly later than an IPv6 failure."); + + /* If ipv6 fails, ensuring that ipv6 errors before ipv4 finishes, we still get ipv4. */ + + data.loop = fixture->loop; + ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); + mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, SLOW_DELAY_MORE_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_ipv4_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); + g_error_free (ipv6_error); +} + +static void +test_happy_eyeballs_ipv4_error_ipv4_first (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv4_error; + + /* If ipv4 fails, ensuring that ipv4 errors before ipv6 finishes, we still get ipv6. */ + + data.loop = fixture->loop; + ipv4_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv4 Broken"); + mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_ipv6_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); + g_error_free (ipv4_error); +} + +static void +test_happy_eyeballs_ipv4_error_ipv6_first (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv4_error; + + /* If ipv4 fails, ensuring that ipv6 finishes before ipv4 errors, we still get ipv6. */ + + data.loop = fixture->loop; + ipv4_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv4 Broken"); + mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_ipv6_results); + + g_list_free_full (data.addrs, (GDestroyNotify) g_object_unref); + g_error_free (ipv4_error); +} + +static void +test_happy_eyeballs_both_error (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv4_error, *ipv6_error; + + /* If both fail we get an error. */ + + data.loop = fixture->loop; + data.expected_error_code = G_IO_ERROR_TIMED_OUT; + ipv4_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv4 Broken"); + ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); + + mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); + mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + g_assert_null (data.addrs); + + g_error_free (ipv4_error); + g_error_free (ipv6_error); +} + +static void +test_happy_eyeballs_both_error_delays_1 (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv4_error, *ipv6_error; + + /* The same with some different timings */ + + data.loop = fixture->loop; + data.expected_error_code = G_IO_ERROR_TIMED_OUT; + ipv4_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv4 Broken"); + ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); + + mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + g_assert_null (data.addrs); + + g_error_free (ipv4_error); + g_error_free (ipv6_error); +} + +static void +test_happy_eyeballs_both_error_delays_2 (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv4_error, *ipv6_error; + + /* The same with some different timings */ + + data.loop = fixture->loop; + data.expected_error_code = G_IO_ERROR_TIMED_OUT; + ipv4_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv4 Broken"); + ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); + + mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); + mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + g_assert_null (data.addrs); + + g_error_free (ipv4_error); + g_error_free (ipv6_error); +} + +static void +test_happy_eyeballs_both_error_delays_3 (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv4_error, *ipv6_error; + + /* The same with some different timings */ + + data.loop = fixture->loop; + data.expected_error_code = G_IO_ERROR_TIMED_OUT; + ipv4_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv4 Broken"); + ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); + + mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); + mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, SLOW_DELAY_MORE_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + g_assert_null (data.addrs); + + g_error_free (ipv4_error); + g_error_free (ipv6_error); +} + +int +main (int argc, char *argv[]) +{ + gsize i; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/network-address/basic", test_basic); + + for (i = 0; i < G_N_ELEMENTS (host_tests); i++) + { + path = g_strdup_printf ("/network-address/parse-host/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &host_tests[i], test_parse_host); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (uri_tests); i++) + { + path = g_strdup_printf ("/network-address/parse-uri/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &uri_tests[i], test_parse_uri); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (address_tests); i++) + { + path = g_strdup_printf ("/network-address/resolve-address/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &address_tests[i], test_resolve_address); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (address_tests); i++) + { + path = g_strdup_printf ("/gresolver/resolve-address/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &address_tests[i], test_resolve_address_gresolver); + g_free (path); + } + + g_test_add_func ("/network-address/scope-id", test_host_scope_id); + g_test_add_func ("/network-address/uri-scope-id", test_uri_scope_id); + g_test_add_func ("/network-address/loopback/basic", test_loopback_basic); + g_test_add_func ("/network-address/loopback/sync", test_loopback_sync); + g_test_add_func ("/network-address/loopback/async", test_loopback_async); + g_test_add_func ("/network-address/localhost/async", test_localhost_async); + g_test_add_func ("/network-address/localhost/sync", test_localhost_sync); + g_test_add_func ("/network-address/to-string", test_to_string); + + g_test_add ("/network-address/happy-eyeballs/basic", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_basic, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/parallel", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_parallel, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/slow-ipv4", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_slow_ipv4, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/slow-ipv6", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_slow_ipv6, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/very-slow-ipv6", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_very_slow_ipv6, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/slow-connection-and-ipv4", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_slow_connection_and_ipv4, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv6-error-ipv4-first", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv6_error_ipv4_first, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv6-error-ipv6-first", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv6_error_ipv6_first, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv6-error-ipv4-very-slow", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv6_error_ipv4_very_slow, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv4-error-ipv6-first", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv4_error_ipv6_first, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv4-error-ipv4-first", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv4_error_ipv4_first, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/both-error", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_both_error, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/both-error-delays-1", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_both_error_delays_1, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/both-error-delays-2", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_both_error_delays_2, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/both-error-delays-3", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_both_error_delays_3, happy_eyeballs_teardown); + + return g_test_run (); +} diff --git a/gio/tests/network-monitor-race.c b/gio/tests/network-monitor-race.c new file mode 100644 index 0000000..00bd6fa --- /dev/null +++ b/gio/tests/network-monitor-race.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * licence, or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include + +#define MAX_RUNS 20 + +static gboolean +quit_loop (gpointer user_data) +{ + g_main_loop_quit (user_data); + + return FALSE; +} + +static gpointer +thread_func (gpointer user_data) +{ + g_network_monitor_get_default (); + g_timeout_add (100, quit_loop, user_data); + + return NULL; +} + +static gboolean +call_func (gpointer user_data) +{ + GThread *thread; + + thread = g_thread_new (NULL, thread_func, user_data); + g_thread_unref (thread); + + return FALSE; +} + +/* Test that calling g_network_monitor_get_default() in a thread doesn’t cause + * a crash. This is a probabilistic test; since it’s testing a race condition, + * it can’t deterministically reproduce the problem. The threading has to + * happen in subprocesses, since the result of g_network_monitor_get_default() + * is unavoidably cached once created. */ +static void +test_network_monitor (void) +{ + guint ii; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=793727"); + + if (g_test_subprocess ()) + { + GMainLoop *main_loop; + + main_loop = g_main_loop_new (NULL, FALSE); + g_timeout_add (1, call_func, main_loop); + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + return; + } + + for (ii = 0; ii < MAX_RUNS; ii++) + { + g_test_trap_subprocess (NULL, + 0, + G_TEST_SUBPROCESS_INHERIT_STDOUT | + G_TEST_SUBPROCESS_INHERIT_STDERR); + g_test_trap_assert_passed (); + } +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/network-monitor/create-in-thread", + test_network_monitor); + + return g_test_run (); +} diff --git a/gio/tests/network-monitor.c b/gio/tests/network-monitor.c new file mode 100644 index 0000000..33e9176 --- /dev/null +++ b/gio/tests/network-monitor.c @@ -0,0 +1,580 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "gio.h" + +/* hack */ +#define GIO_COMPILATION +#include "gnetworkmonitorbase.h" + +#include + +/* Test data; the GInetAddresses and GInetAddressMasks get filled in + * in main(). Each address in a TestAddress matches the mask in its + * corresponding TestMask, and none of them match any of the other + * masks. The addresses in unmatched don't match any of the masks. + */ + +typedef struct { + const char *string; + GInetAddress *address; +} TestAddress; + +typedef struct { + const char *mask_string; + GInetAddressMask *mask; + TestAddress *addresses; +} TestMask; + +TestAddress net127addrs[] = { + { "127.0.0.1", NULL }, + { "127.0.0.2", NULL }, + { "127.0.0.255", NULL }, + { "127.0.1.0", NULL }, + { "127.0.255.0", NULL }, + { "127.0.255.0", NULL }, + { "127.255.255.255", NULL }, + { NULL, NULL } +}; +TestMask net127 = { "127.0.0.0/8", NULL, net127addrs }; + +TestAddress net10addrs[] = { + { "10.0.0.1", NULL }, + { "10.0.0.2", NULL }, + { "10.0.0.255", NULL }, + { NULL, NULL } +}; +TestMask net10 = { "10.0.0.0/24", NULL, net10addrs }; + +TestAddress net192addrs[] = { + { "192.168.0.1", NULL }, + { "192.168.0.2", NULL }, + { "192.168.0.255", NULL }, + { "192.168.1.0", NULL }, + { "192.168.15.0", NULL }, + { NULL, NULL } +}; +TestMask net192 = { "192.168.0.0/20", NULL, net192addrs }; + +TestAddress netlocal6addrs[] = { + { "::1", NULL }, + { NULL, NULL } +}; +TestMask netlocal6 = { "::1/128", NULL, netlocal6addrs }; + +TestAddress netfe80addrs[] = { + { "fe80::", NULL }, + { "fe80::1", NULL }, + { "fe80::21b:77ff:fea2:972a", NULL }, + { NULL, NULL } +}; +TestMask netfe80 = { "fe80::/64", NULL, netfe80addrs }; + +TestAddress unmatched[] = { + { "10.0.1.0", NULL }, + { "10.0.255.0", NULL }, + { "10.255.255.255", NULL }, + { "192.168.16.0", NULL }, + { "192.168.255.0", NULL }, + { "192.169.0.0", NULL }, + { "192.255.255.255", NULL }, + { "::2", NULL }, + { "1::1", NULL }, + { "fe80::1:0:0:0:0", NULL }, + { "fe80:8000::0:0:0:0", NULL }, + { NULL, NULL } +}; + +GInetAddressMask *ip4_default, *ip6_default; + +static void +notify_handler (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + gboolean *emitted = user_data; + + *emitted = TRUE; +} + +static void +network_changed_handler (GNetworkMonitor *monitor, + gboolean available, + gpointer user_data) +{ + gboolean *emitted = user_data; + + *emitted = TRUE; +} + +static void +assert_signals (GNetworkMonitor *monitor, + gboolean should_emit_notify, + gboolean should_emit_network_changed, + gboolean expected_network_available) +{ + gboolean emitted_notify = FALSE, emitted_network_changed = FALSE; + guint h1, h2; + + h1 = g_signal_connect (monitor, "notify::network-available", + G_CALLBACK (notify_handler), + &emitted_notify); + h2 = g_signal_connect (monitor, "network-changed", + G_CALLBACK (network_changed_handler), + &emitted_network_changed); + + g_main_context_iteration (NULL, FALSE); + + g_signal_handler_disconnect (monitor, h1); + g_signal_handler_disconnect (monitor, h2); + + g_assert (emitted_notify == should_emit_notify); + g_assert (emitted_network_changed == should_emit_network_changed); + + g_assert (g_network_monitor_get_network_available (monitor) == expected_network_available); +} + +typedef struct { + GNetworkMonitor *monitor; + GMainLoop *loop; + GSocketAddress *sockaddr; + gboolean should_be_reachable; +} CanReachData; + +static void +reach_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + gboolean reachable; + CanReachData *data = user_data; + + reachable = g_network_monitor_can_reach_finish (data->monitor, res, &error); + + if (data->should_be_reachable) + g_assert_no_error (error); + else + { + g_assert (error != NULL); + g_clear_error (&error); + } + g_assert (reachable == data->should_be_reachable); + + g_main_loop_quit (data->loop); +} + +static gboolean +test_reach_async (gpointer user_data) +{ + CanReachData *data = user_data; + + g_network_monitor_can_reach_async (data->monitor, + G_SOCKET_CONNECTABLE (data->sockaddr), + NULL, + reach_cb, + data); + return G_SOURCE_REMOVE; +} + +static void +run_tests (GNetworkMonitor *monitor, + TestAddress *addresses, + gboolean should_be_reachable) +{ + GError *error = NULL; + int i; + gboolean reachable; + GSocketAddress *sockaddr; + CanReachData data; + + data.monitor = monitor; + data.loop = g_main_loop_new (NULL, FALSE); + + for (i = 0; addresses[i].address; i++) + { + sockaddr = g_inet_socket_address_new (addresses[i].address, 0); + reachable = g_network_monitor_can_reach (monitor, + G_SOCKET_CONNECTABLE (sockaddr), + NULL, &error); + data.sockaddr = sockaddr; + data.should_be_reachable = should_be_reachable; + + g_idle_add (test_reach_async, &data); + g_main_loop_run (data.loop); + + g_object_unref (sockaddr); + g_assert_cmpint (reachable, ==, should_be_reachable); + if (should_be_reachable) + g_assert_no_error (error); + else + { + g_assert (error != NULL); + g_clear_error (&error); + } + } + + g_main_loop_unref (data.loop); +} + +static void +test_default (void) +{ + GNetworkMonitor *monitor, *m; + GError *error = NULL; + + m = g_network_monitor_get_default (); + g_assert (G_IS_NETWORK_MONITOR (m)); + + monitor = g_object_new (G_TYPE_NETWORK_MONITOR_BASE, NULL); + g_initable_init (G_INITABLE (monitor), NULL, &error); + g_assert_no_error (error); + + /* In the default configuration, all addresses are reachable */ + run_tests (monitor, net127.addresses, TRUE); + run_tests (monitor, net10.addresses, TRUE); + run_tests (monitor, net192.addresses, TRUE); + run_tests (monitor, netlocal6.addresses, TRUE); + run_tests (monitor, netfe80.addresses, TRUE); + run_tests (monitor, unmatched, TRUE); + + assert_signals (monitor, FALSE, FALSE, TRUE); + + g_object_unref (monitor); +} + +static void +test_remove_default (void) +{ + GNetworkMonitor *monitor; + GError *error = NULL; + + monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL); + g_assert_no_error (error); + assert_signals (monitor, FALSE, FALSE, TRUE); + + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + ip4_default); + assert_signals (monitor, FALSE, TRUE, TRUE); + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + ip6_default); + assert_signals (monitor, TRUE, TRUE, FALSE); + + /* Now nothing should be reachable */ + run_tests (monitor, net127.addresses, FALSE); + run_tests (monitor, net10.addresses, FALSE); + run_tests (monitor, net192.addresses, FALSE); + run_tests (monitor, netlocal6.addresses, FALSE); + run_tests (monitor, netfe80.addresses, FALSE); + run_tests (monitor, unmatched, FALSE); + + g_object_unref (monitor); +} + +static void +test_add_networks (void) +{ + GNetworkMonitor *monitor; + GError *error = NULL; + + monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL); + g_assert_no_error (error); + assert_signals (monitor, FALSE, FALSE, TRUE); + + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + ip4_default); + assert_signals (monitor, FALSE, TRUE, TRUE); + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + ip6_default); + assert_signals (monitor, TRUE, TRUE, FALSE); + + /* Now add the masks one by one */ + + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + net127.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + + run_tests (monitor, net127.addresses, TRUE); + run_tests (monitor, net10.addresses, FALSE); + run_tests (monitor, net192.addresses, FALSE); + run_tests (monitor, netlocal6.addresses, FALSE); + run_tests (monitor, netfe80.addresses, FALSE); + run_tests (monitor, unmatched, FALSE); + + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + net10.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, TRUE); + run_tests (monitor, net10.addresses, TRUE); + run_tests (monitor, net192.addresses, FALSE); + run_tests (monitor, netlocal6.addresses, FALSE); + run_tests (monitor, netfe80.addresses, FALSE); + run_tests (monitor, unmatched, FALSE); + + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + net192.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, TRUE); + run_tests (monitor, net10.addresses, TRUE); + run_tests (monitor, net192.addresses, TRUE); + run_tests (monitor, netlocal6.addresses, FALSE); + run_tests (monitor, netfe80.addresses, FALSE); + run_tests (monitor, unmatched, FALSE); + + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + netlocal6.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, TRUE); + run_tests (monitor, net10.addresses, TRUE); + run_tests (monitor, net192.addresses, TRUE); + run_tests (monitor, netlocal6.addresses, TRUE); + run_tests (monitor, netfe80.addresses, FALSE); + run_tests (monitor, unmatched, FALSE); + + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + netfe80.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, TRUE); + run_tests (monitor, net10.addresses, TRUE); + run_tests (monitor, net192.addresses, TRUE); + run_tests (monitor, netlocal6.addresses, TRUE); + run_tests (monitor, netfe80.addresses, TRUE); + run_tests (monitor, unmatched, FALSE); + + g_object_unref (monitor); +} + +static void +test_remove_networks (void) +{ + GNetworkMonitor *monitor; + GError *error = NULL; + + monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL); + g_assert_no_error (error); + assert_signals (monitor, FALSE, FALSE, TRUE); + + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + ip4_default); + assert_signals (monitor, FALSE, TRUE, TRUE); + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + ip6_default); + assert_signals (monitor, TRUE, TRUE, FALSE); + + /* First add them */ + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + net127.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + net10.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + net192.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + netlocal6.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor), + netfe80.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + + run_tests (monitor, net127.addresses, TRUE); + run_tests (monitor, net10.addresses, TRUE); + run_tests (monitor, net192.addresses, TRUE); + run_tests (monitor, netlocal6.addresses, TRUE); + run_tests (monitor, netfe80.addresses, TRUE); + run_tests (monitor, unmatched, FALSE); + + /* Now remove them one by one */ + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + net127.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, FALSE); + run_tests (monitor, net10.addresses, TRUE); + run_tests (monitor, net192.addresses, TRUE); + run_tests (monitor, netlocal6.addresses, TRUE); + run_tests (monitor, netfe80.addresses, TRUE); + run_tests (monitor, unmatched, FALSE); + + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + net10.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, FALSE); + run_tests (monitor, net10.addresses, FALSE); + run_tests (monitor, net192.addresses, TRUE); + run_tests (monitor, netlocal6.addresses, TRUE); + run_tests (monitor, netfe80.addresses, TRUE); + run_tests (monitor, unmatched, FALSE); + + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + net192.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, FALSE); + run_tests (monitor, net10.addresses, FALSE); + run_tests (monitor, net192.addresses, FALSE); + run_tests (monitor, netlocal6.addresses, TRUE); + run_tests (monitor, netfe80.addresses, TRUE); + run_tests (monitor, unmatched, FALSE); + + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + netlocal6.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, FALSE); + run_tests (monitor, net10.addresses, FALSE); + run_tests (monitor, net192.addresses, FALSE); + run_tests (monitor, netlocal6.addresses, FALSE); + run_tests (monitor, netfe80.addresses, TRUE); + run_tests (monitor, unmatched, FALSE); + + g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor), + netfe80.mask); + assert_signals (monitor, FALSE, TRUE, FALSE); + run_tests (monitor, net127.addresses, FALSE); + run_tests (monitor, net10.addresses, FALSE); + run_tests (monitor, net192.addresses, FALSE); + run_tests (monitor, netlocal6.addresses, FALSE); + run_tests (monitor, netfe80.addresses, FALSE); + run_tests (monitor, unmatched, FALSE); + + g_object_unref (monitor); +} + + +static void +init_test (TestMask *test) +{ + GError *error = NULL; + int i; + + test->mask = g_inet_address_mask_new_from_string (test->mask_string, &error); + g_assert_no_error (error); + + for (i = 0; test->addresses[i].string; i++) + { + test->addresses[i].address = g_inet_address_new_from_string (test->addresses[i].string); + if (strchr (test->addresses[i].string, ':')) + g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV6); + else + g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV4); + } +} + +static void +cleanup_test (TestMask *test) +{ + int i; + + g_object_unref (test->mask); + for (i = 0; test->addresses[i].string; i++) + g_object_unref (test->addresses[i].address); +} + +static void +watch_network_changed (GNetworkMonitor *monitor, + gboolean available, + gpointer user_data) +{ + g_print ("Network is %s\n", available ? "up" : "down"); +} + +static void +watch_connectivity_changed (GNetworkMonitor *monitor, + GParamSpec *pspec, + gpointer user_data) +{ + g_print ("Connectivity is %d\n", g_network_monitor_get_connectivity (monitor)); +} + +static void +watch_metered_changed (GNetworkMonitor *monitor, + GParamSpec *pspec, + gpointer user_data) +{ + g_print ("Metered is %d\n", g_network_monitor_get_network_metered (monitor)); +} + +static void +do_watch_network (void) +{ + GNetworkMonitor *monitor = g_network_monitor_get_default (); + GMainLoop *loop; + + g_print ("Monitoring via %s\n", g_type_name_from_instance ((GTypeInstance *) monitor)); + + g_signal_connect (monitor, "network-changed", + G_CALLBACK (watch_network_changed), NULL); + g_signal_connect (monitor, "notify::connectivity", + G_CALLBACK (watch_connectivity_changed), NULL); + g_signal_connect (monitor, "notify::network-metered", + G_CALLBACK (watch_metered_changed), NULL); + watch_network_changed (monitor, g_network_monitor_get_network_available (monitor), NULL); + watch_connectivity_changed (monitor, NULL, NULL); + watch_metered_changed (monitor, NULL, NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); +} + +int +main (int argc, char **argv) +{ + int ret; + + if (argc == 2 && !strcmp (argv[1], "--watch")) + { + do_watch_network (); + return 0; + } + + g_test_init (&argc, &argv, NULL); + + /* GNetworkMonitor will resolve addresses through a proxy if one is set and a + * GIO module is available to handle it. In these tests we deliberately + * change the idea of a reachable network to exclude the proxy, which will + * lead to negative results. We're not trying to test the proxy-resolving + * functionality (that would be for e.g. glib-networking's testsuite), so + * let's just use the dummy proxy resolver, which always pretends the + * passed-in URL is directly resolvable. + */ + g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE); + + init_test (&net127); + init_test (&net10); + init_test (&net192); + init_test (&netlocal6); + init_test (&netfe80); + ip4_default = g_inet_address_mask_new_from_string ("0.0.0.0/0", NULL); + ip6_default = g_inet_address_mask_new_from_string ("::/0", NULL); + + g_test_add_func ("/network-monitor/default", test_default); + g_test_add_func ("/network-monitor/remove_default", test_remove_default); + g_test_add_func ("/network-monitor/add_networks", test_add_networks); + g_test_add_func ("/network-monitor/remove_networks", test_remove_networks); + + ret = g_test_run (); + + cleanup_test (&net127); + cleanup_test (&net10); + cleanup_test (&net192); + cleanup_test (&netlocal6); + cleanup_test (&netfe80); + g_object_unref (ip4_default); + g_object_unref (ip6_default); + + return ret; +} diff --git a/gio/tests/null-settings-backend.c b/gio/tests/null-settings-backend.c new file mode 100644 index 0000000..34dee56 --- /dev/null +++ b/gio/tests/null-settings-backend.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022 Ryan Hope + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Hope + */ + +#include +#define G_SETTINGS_ENABLE_BACKEND +#include + +/* Test that the "gsettings-backend" extension point has been registered. + * Must be run first and separetly from other GSettingsBackend, + * as they will register the extension point making the test useless. + */ +static void +test_extension_point_registered (void) +{ + GSettingsBackend *backend; + GIOExtensionPoint *extension_point; + + backend = g_null_settings_backend_new (); + g_assert_true (G_IS_SETTINGS_BACKEND (backend)); + extension_point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME); + + g_assert_nonnull (extension_point); + + g_object_unref (backend); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + /* Must be run first */ + g_test_add_func ("/null-settings-backend/extension-point-registered", test_extension_point_registered); + + return g_test_run (); +} diff --git a/gio/tests/org.gtk.schemasourcecheck.gschema.xml b/gio/tests/org.gtk.schemasourcecheck.gschema.xml new file mode 100644 index 0000000..b484da1 --- /dev/null +++ b/gio/tests/org.gtk.schemasourcecheck.gschema.xml @@ -0,0 +1,8 @@ + + + + true + + + + diff --git a/gio/tests/org.gtk.test.dbusappinfo.desktop b/gio/tests/org.gtk.test.dbusappinfo.desktop new file mode 100644 index 0000000..9bb257c --- /dev/null +++ b/gio/tests/org.gtk.test.dbusappinfo.desktop @@ -0,0 +1,18 @@ +[Desktop Entry] +Type=Application +Name=Test +Actions=frob;tweak;twiddle;quit; +StartupNotify=true +DBusActivatable=true + +[Desktop Action frob] +Name=Frobnicate + +[Desktop Action tweak] +Name=Tweak + +[Desktop Action twiddle] +Name=Twiddle + +[Desktop Action quit] +Name=Quit diff --git a/gio/tests/org.gtk.test.dbusappinfo.flatpak.desktop b/gio/tests/org.gtk.test.dbusappinfo.flatpak.desktop new file mode 100644 index 0000000..9ef248a --- /dev/null +++ b/gio/tests/org.gtk.test.dbusappinfo.flatpak.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Type=Application +Name=Test +DBusActivatable=true +X-Flatpak=org.gtk.test.dbusappinfo.flatpak diff --git a/gio/tests/org.gtk.test.gschema.override.orig b/gio/tests/org.gtk.test.gschema.override.orig new file mode 100644 index 0000000..6694baa --- /dev/null +++ b/gio/tests/org.gtk.test.gschema.override.orig @@ -0,0 +1,2 @@ +[org.gtk.test.per-desktop:GNOME-Classic] +desktop = "GNOME Classic" diff --git a/gio/tests/org.gtk.test.gschema.xml.orig b/gio/tests/org.gtk.test.gschema.xml.orig new file mode 100644 index 0000000..aad4e54 --- /dev/null +++ b/gio/tests/org.gtk.test.gschema.xml.orig @@ -0,0 +1,222 @@ + + + + + "Hello, earthlings" + A greeting + + Greeting of the invading martians + + + + "So long" + + + + + + + + + + true + + + + + + true + + + 25 + + + -1234 + + + 1234 + + + -123456 + + + 123456 + + + -123456789 + + + 123456789 + + + 123.456 + + + "a string, it seems" + + + "/a/object/path" + + + + + + ("one",(2,3)) + + + [0,1,2,3,4,5] + + + + { + "AC": [0,0, 0,0,0,0,0,0], + "IV": [0,0, 0,0,0,0,0,0] + } + + + + + + + "Unnamed" + + + "BackSpace" + + + + + + false + + + false + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + "" + + + [48, 49] + + + [] + + + 'foo' + + + ['mourning', 'laughing'] + + + 33 + + + + + + + 'bar' + + + + + + [] + + + + + + + + + [] + + + 'bar' + + + + + + 33 + + + + + + + 33 + + + + + + 0 + + + + + + + a paragraph. + + with some whitespace. + + because not everyone has a great editor. + + + + + lots of space is as one. + + 0 + + + + + + 0 + + + '' + + + + 42 + + 0 + + + + + + "GNOME" + + + + diff --git a/gio/tests/permission.c b/gio/tests/permission.c new file mode 100644 index 0000000..14094a0 --- /dev/null +++ b/gio/tests/permission.c @@ -0,0 +1,117 @@ +/* Unit tests for GPermission + * Copyright (C) 2012 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include + +static void +acquired (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GPermission *p = G_PERMISSION (source); + GMainLoop *loop = user_data; + GError *error = NULL; + gboolean ret; + + ret = g_permission_acquire_finish (p, res, &error); + g_assert (!ret); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + + g_main_loop_quit (loop); +} + +static void +released (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GPermission *p = G_PERMISSION (source); + GMainLoop *loop = user_data; + GError *error = NULL; + gboolean ret; + + ret = g_permission_release_finish (p, res, &error); + g_assert (!ret); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + + g_main_loop_quit (loop); +} + +static void +test_simple (void) +{ + GPermission *p; + gboolean allowed; + gboolean can_acquire; + gboolean can_release; + gboolean ret; + GError *error = NULL; + GMainLoop *loop; + + p = g_simple_permission_new (TRUE); + + g_assert (g_permission_get_allowed (p)); + g_assert (!g_permission_get_can_acquire (p)); + g_assert (!g_permission_get_can_release (p)); + + g_object_get (p, + "allowed", &allowed, + "can-acquire", &can_acquire, + "can-release", &can_release, + NULL); + + g_assert (allowed); + g_assert (!can_acquire); + g_assert (!can_release); + + ret = g_permission_acquire (p, NULL, &error); + g_assert (!ret); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + + ret = g_permission_release (p, NULL, &error); + g_assert (!ret); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + + loop = g_main_loop_new (NULL, FALSE); + g_permission_acquire_async (p, NULL, acquired, loop); + g_main_loop_run (loop); + g_permission_release_async (p, NULL, released, loop); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + + g_object_unref (p); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/permission/simple", test_simple); + + return g_test_run (); +} diff --git a/gio/tests/pollable.c b/gio/tests/pollable.c new file mode 100644 index 0000000..516d7f4 --- /dev/null +++ b/gio/tests/pollable.c @@ -0,0 +1,392 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include + +#ifdef G_OS_UNIX +#include +#include +#include +#include +#endif + +GMainLoop *loop; +GPollableInputStream *in; +GOutputStream *out; + +static gboolean +poll_source_callback (GPollableInputStream *in, + gpointer user_data) +{ + GError *error = NULL; + char buf[2]; + gssize nread; + gboolean *success = user_data; + + g_assert_true (g_pollable_input_stream_is_readable (G_POLLABLE_INPUT_STREAM (in))); + + nread = g_pollable_input_stream_read_nonblocking (in, buf, 2, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nread, ==, 2); + g_assert_cmpstr (buf, ==, "x"); + g_assert_false (g_pollable_input_stream_is_readable (G_POLLABLE_INPUT_STREAM (in))); + + *success = TRUE; + return G_SOURCE_REMOVE; +} + +static gboolean +check_source_readability_callback (gpointer user_data) +{ + gboolean expected = GPOINTER_TO_INT (user_data); + gboolean readable; + + readable = g_pollable_input_stream_is_readable (in); + g_assert_cmpint (readable, ==, expected); + return G_SOURCE_REMOVE; +} + +static gboolean +write_callback (gpointer user_data) +{ + const char *buf = "x"; + gssize nwrote; + GError *error = NULL; + + g_assert_true (g_pollable_output_stream_is_writable (G_POLLABLE_OUTPUT_STREAM (out))); + + nwrote = g_output_stream_write (out, buf, 2, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, 2); + g_assert_true (g_pollable_output_stream_is_writable (G_POLLABLE_OUTPUT_STREAM (out))); + +/* Give the pipe a few ticks to propagate the write for sockets. On my + * iMac i7, 40 works, 30 doesn't. */ + g_usleep (80L); + + check_source_readability_callback (GINT_TO_POINTER (TRUE)); + + return G_SOURCE_REMOVE; +} + +static gboolean +check_source_and_quit_callback (gpointer user_data) +{ + check_source_readability_callback (user_data); + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; +} + +static void +test_streams (void) +{ + gboolean readable; + GError *error = NULL; + char buf[1]; + gssize nread; + GSource *poll_source; + gboolean success = FALSE; + + g_assert (g_pollable_input_stream_can_poll (in)); + g_assert (g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (out))); + + readable = g_pollable_input_stream_is_readable (in); + g_assert (!readable); + + nread = g_pollable_input_stream_read_nonblocking (in, buf, 1, NULL, &error); + g_assert_cmpint (nread, ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_clear_error (&error); + + /* Create 4 sources, in decreasing order of priority: + * 1. poll source on @in + * 2. idle source that checks if @in is readable once + * (it won't be) and then removes itself + * 3. idle source that writes a byte to @out, checks that + * @in is now readable, and removes itself + * 4. idle source that checks if @in is readable once + * (it won't be, since the poll source will fire before + * this one does) and then quits the loop. + * + * If the poll source triggers before it should, then it will get a + * %G_IO_ERROR_WOULD_BLOCK, and if check() fails in either + * direction, we will catch it at some point. + */ + + poll_source = g_pollable_input_stream_create_source (in, NULL); + g_source_set_priority (poll_source, 1); + g_source_set_callback (poll_source, (GSourceFunc) poll_source_callback, &success, NULL); + g_source_attach (poll_source, NULL); + g_source_unref (poll_source); + + g_idle_add_full (2, check_source_readability_callback, GINT_TO_POINTER (FALSE), NULL); + g_idle_add_full (3, write_callback, NULL, NULL); + g_idle_add_full (4, check_source_and_quit_callback, GINT_TO_POINTER (FALSE), NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_assert_cmpint (success, ==, TRUE); +} + +#ifdef G_OS_UNIX + +#define g_assert_not_pollable(fd) \ + G_STMT_START { \ + in = G_POLLABLE_INPUT_STREAM (g_unix_input_stream_new (fd, FALSE)); \ + out = g_unix_output_stream_new (fd, FALSE); \ + \ + g_assert (!g_pollable_input_stream_can_poll (in)); \ + g_assert (!g_pollable_output_stream_can_poll ( \ + G_POLLABLE_OUTPUT_STREAM (out))); \ + \ + g_clear_object (&in); \ + g_clear_object (&out); \ + } G_STMT_END + +static void +test_pollable_unix_pipe (void) +{ + int pipefds[2], status; + + g_test_summary ("Test that pipes are considered pollable, just like sockets"); + + status = pipe (pipefds); + g_assert_cmpint (status, ==, 0); + + in = G_POLLABLE_INPUT_STREAM (g_unix_input_stream_new (pipefds[0], TRUE)); + out = g_unix_output_stream_new (pipefds[1], TRUE); + + test_streams (); + + g_object_unref (in); + g_object_unref (out); +} + +static void +test_pollable_unix_pty (void) +{ + int (*openpty_impl) (int *, int *, char *, void *, void *); + int a, b, status; +#ifdef LIBUTIL_SONAME + void *handle; +#endif + + g_test_summary ("Test that PTYs are considered pollable"); + +#ifdef LIBUTIL_SONAME + handle = dlopen (LIBUTIL_SONAME, RTLD_GLOBAL | RTLD_LAZY); + g_assert_nonnull (handle); +#endif + + openpty_impl = dlsym (RTLD_DEFAULT, "openpty"); + if (openpty_impl == NULL) + { + g_test_skip ("System does not support openpty()"); + goto close_libutil; + } + + status = openpty_impl (&a, &b, NULL, NULL, NULL); + if (status == -1) + { + g_test_skip ("Unable to open PTY"); + goto close_libutil; + } + + in = G_POLLABLE_INPUT_STREAM (g_unix_input_stream_new (a, TRUE)); + out = g_unix_output_stream_new (b, TRUE); + + test_streams (); + + g_object_unref (in); + g_object_unref (out); + + close (a); + close (b); + +close_libutil: +#ifdef LIBUTIL_SONAME + dlclose (handle); +#else + return; +#endif +} + +static void +test_pollable_unix_file (void) +{ + int fd; + + g_test_summary ("Test that regular files are not considered pollable"); + + fd = g_open ("/etc/hosts", O_RDONLY, 0); + if (fd == -1) + { + g_test_skip ("Unable to open /etc/hosts"); + return; + } + + g_assert_not_pollable (fd); + + close (fd); +} + +static void +test_pollable_unix_nulldev (void) +{ + int fd; + + g_test_summary ("Test that /dev/null is not considered pollable, but only if " + "on a system where we are able to tell it apart from devices " + "that actually implement poll"); + +#if defined (HAVE_EPOLL_CREATE) || defined (HAVE_KQUEUE) + fd = g_open ("/dev/null", O_RDWR, 0); + g_assert_cmpint (fd, !=, -1); + + g_assert_not_pollable (fd); + + close (fd); +#else + g_test_skip ("Cannot detect /dev/null as non-pollable on this system"); +#endif +} + +static void +test_pollable_converter (void) +{ + GConverter *converter; + GError *error = NULL; + GInputStream *ibase; + int pipefds[2], status; + + status = pipe (pipefds); + g_assert_cmpint (status, ==, 0); + + ibase = G_INPUT_STREAM (g_unix_input_stream_new (pipefds[0], TRUE)); + converter = G_CONVERTER (g_charset_converter_new ("UTF-8", "UTF-8", &error)); + g_assert_no_error (error); + + in = G_POLLABLE_INPUT_STREAM (g_converter_input_stream_new (ibase, converter)); + g_object_unref (converter); + g_object_unref (ibase); + + out = g_unix_output_stream_new (pipefds[1], TRUE); + + test_streams (); + + g_object_unref (in); + g_object_unref (out); +} + +#endif + +static void +client_connected (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSocketClient *client = G_SOCKET_CLIENT (source); + GSocketConnection **conn = user_data; + GError *error = NULL; + + *conn = g_socket_client_connect_finish (client, result, &error); + g_assert_no_error (error); +} + +static void +server_connected (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSocketListener *listener = G_SOCKET_LISTENER (source); + GSocketConnection **conn = user_data; + GError *error = NULL; + + *conn = g_socket_listener_accept_finish (listener, result, NULL, &error); + g_assert_no_error (error); +} + +static void +test_pollable_socket (void) +{ + GInetAddress *iaddr; + GSocketAddress *saddr, *effective_address; + GSocketListener *listener; + GSocketClient *client; + GError *error = NULL; + GSocketConnection *client_conn = NULL, *server_conn = NULL; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + listener = g_socket_listener_new (); + g_socket_listener_add_address (listener, saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &effective_address, + &error); + g_assert_no_error (error); + g_object_unref (saddr); + + client = g_socket_client_new (); + + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (effective_address), + NULL, client_connected, &client_conn); + g_socket_listener_accept_async (listener, NULL, + server_connected, &server_conn); + + while (!client_conn || !server_conn) + g_main_context_iteration (NULL, TRUE); + + in = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (G_IO_STREAM (client_conn))); + out = g_io_stream_get_output_stream (G_IO_STREAM (server_conn)); + + test_streams (); + + g_object_unref (client_conn); + g_object_unref (server_conn); + g_object_unref (client); + g_object_unref (listener); + g_object_unref (effective_address); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + +#ifdef G_OS_UNIX + g_test_add_func ("/pollable/unix/pipe", test_pollable_unix_pipe); + g_test_add_func ("/pollable/unix/pty", test_pollable_unix_pty); + g_test_add_func ("/pollable/unix/file", test_pollable_unix_file); + g_test_add_func ("/pollable/unix/nulldev", test_pollable_unix_nulldev); + g_test_add_func ("/pollable/converter", test_pollable_converter); +#endif + g_test_add_func ("/pollable/socket", test_pollable_socket); + + return g_test_run(); +} diff --git a/gio/tests/power-profile-monitor-dbus.py.in b/gio/tests/power-profile-monitor-dbus.py.in new file mode 100755 index 0000000..06e594f --- /dev/null +++ b/gio/tests/power-profile-monitor-dbus.py.in @@ -0,0 +1,107 @@ +#!/usr/bin/python3 + +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) any +# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text +# of the license. + +__author__ = 'Bastien Nocera' +__email__ = 'hadess@hadess.net' +__copyright__ = '(c) 2019, 2021 Red Hat Inc.' +__license__ = 'LGPL 3+' + +import unittest +import sys +import subprocess +import fcntl +import os +import time + +import taptestrunner + +try: + # Do all non-standard imports here so we can skip the tests if any + # needed packages are not available. + import dbus + import dbus.mainloop.glib + import dbusmock + from gi.repository import GLib + from gi.repository import Gio + + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + class TestPowerProfileMonitor(dbusmock.DBusTestCase): + '''Test GPowerProfileMonitorDBus''' + + @classmethod + def setUpClass(klass): + klass.start_system_bus() + klass.dbus_con = klass.get_dbus(True) + + def setUp(self): + try: + Gio.PowerProfileMonitor + except AttributeError: + raise unittest.SkipTest('Power Profile Monitor not in ' + 'introspection data. Requires ' + 'GObject-Introspection ≥ 1.63.2') # FIXME version + try: + (self.p_mock, self.obj_ppd) = self.spawn_server_template( + 'power_profiles_daemon', {}, stdout=subprocess.PIPE) + except ModuleNotFoundError: + raise unittest.SkipTest("power-profiles-daemon dbusmock template not " + "found. Requires dbusmock > 0.23.1.") # FIXME version + # set log to nonblocking + flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) + fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) + self.power_saver_enabled = False + self.dbus_props = dbus.Interface(self.obj_ppd, dbus.PROPERTIES_IFACE) + self.power_profile_monitor = Gio.PowerProfileMonitor.dup_default() + self.power_profile_monitor.connect("notify::power-saver-enabled", self.power_saver_enabled_cb) + self.mainloop = GLib.MainLoop() + self.main_context = self.mainloop.get_context() + + def tearDown(self): + self.p_mock.terminate() + self.p_mock.wait() + + def assertEventually(self, condition, message=None, timeout=50): + '''Assert that condition function eventually returns True. + + Timeout is in deciseconds, defaulting to 50 (5 seconds). message is + printed on failure. + ''' + while timeout >= 0: + context = GLib.MainContext.default() + while context.iteration(False): + pass + if condition(): + break + timeout -= 1 + time.sleep(0.1) + else: + self.fail(message or 'timed out waiting for ' + str(condition)) + + def power_saver_enabled_cb(self, spec, data): + self.power_saver_enabled = self.power_profile_monitor.get_power_saver_enabled() + self.main_context.wakeup() + + def test_power_profile_power_saver_enabled(self): + '''power-saver-enabled property''' + + self.assertEqual(self.power_profile_monitor.get_power_saver_enabled(), False) + self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('power-saver', variant_level=1)) + self.assertEventually(lambda: self.power_saver_enabled == True, "power-saver didn't become enabled", 10) + + self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('balanced', variant_level=1)) + self.assertEventually(lambda: self.power_saver_enabled == False, "power-saver didn't become disabled", 10) + +except ImportError as e: + @unittest.skip("Cannot import %s" % e.name) + class TestPowerProfileMonitor(unittest.TestCase): + def test_power_profile_power_saver_enabled(self): + pass + +if __name__ == '__main__': + unittest.main(testRunner=taptestrunner.TAPTestRunner()) diff --git a/gio/tests/power-profile-monitor-portal.py.in b/gio/tests/power-profile-monitor-portal.py.in new file mode 100755 index 0000000..09e9a45 --- /dev/null +++ b/gio/tests/power-profile-monitor-portal.py.in @@ -0,0 +1,142 @@ +#!/usr/bin/python3 + +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) any +# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text +# of the license. + +__author__ = 'Bastien Nocera' +__email__ = 'hadess@hadess.net' +__copyright__ = '(c) 2021 Red Hat Inc.' +__license__ = 'LGPL 3+' + +import unittest +import sys +import subprocess +import fcntl +import os +import time + +import taptestrunner + +try: + # Do all non-standard imports here so we can skip the tests if any + # needed packages are not available. + import dbus + import dbus.mainloop.glib + import dbusmock + from gi.repository import GLib + from gi.repository import Gio + from gi.repository import GObject + + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + # XDG_DESKTOP_PORTAL_PATH = os.path.expanduser("~/.cache/jhbuild/build/xdg-desktop-portal/xdg-desktop-portal") + XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal" + + class TestPowerProfileMonitorPortal(dbusmock.DBusTestCase): + '''Test GPowerProfileMonitorPortal''' + + @classmethod + def setUpClass(klass): + klass.start_system_bus() + klass.dbus_con = klass.get_dbus(True) + # Start session bus so that xdg-desktop-portal can run on it + klass.start_session_bus() + + def setUp(self): + try: + Gio.PowerProfileMonitor + except AttributeError: + raise unittest.SkipTest('Power Profile Monitor not in ' + 'introspection data. Requires ' + 'GObject-Introspection > 1.69.0') + try: + (self.p_mock, self.obj_ppd) = self.spawn_server_template( + 'power_profiles_daemon', {}, stdout=subprocess.PIPE) + except ModuleNotFoundError: + raise unittest.SkipTest("power-profiles-daemon dbusmock template not " + "found. Requires dbusmock > 0.23.1.") + # set log to nonblocking + flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) + fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) + self.power_saver_enabled = False + self.dbus_props = dbus.Interface(self.obj_ppd, dbus.PROPERTIES_IFACE) + try: + self.xdp = subprocess.Popen([XDG_DESKTOP_PORTAL_PATH]) + except FileNotFoundError: + self.p_mock.terminate() + self.p_mock.wait() + raise unittest.SkipTest("xdg-desktop-portal not available") + + try: + self.wait_for_bus_object('org.freedesktop.portal.Desktop', + '/org/freedesktop/portal/desktop') + except: + self.p_mock.terminate() + self.p_mock.wait() + raise + # subprocess.Popen(['gdbus', 'monitor', '--session', '--dest', 'org.freedesktop.portal.Desktop']) + + os.environ['GTK_USE_PORTAL'] = "1" + self.power_profile_monitor = Gio.PowerProfileMonitor.dup_default() + assert("GPowerProfileMonitorPortal" in str(self.power_profile_monitor)) + self.power_profile_monitor.connect("notify::power-saver-enabled", self.power_saver_enabled_cb) + self.mainloop = GLib.MainLoop() + self.main_context = self.mainloop.get_context() + + def tearDown(self): + self.p_mock.terminate() + self.p_mock.wait() + + def assertEventually(self, condition, message=None, timeout=50): + '''Assert that condition function eventually returns True. + + Timeout is in deciseconds, defaulting to 50 (5 seconds). message is + printed on failure. + ''' + while timeout >= 0: + context = GLib.MainContext.default() + while context.iteration(False): + pass + if condition(): + break + timeout -= 1 + time.sleep(0.1) + else: + self.fail(message or 'timed out waiting for ' + str(condition)) + + def power_saver_enabled_cb(self, spec, data): + self.power_saver_enabled = self.power_profile_monitor.get_power_saver_enabled() + self.main_context.wakeup() + + def test_power_profile_power_saver_enabled_portal(self): + '''power-saver-enabled property''' + + self.assertEqual(self.power_profile_monitor.get_power_saver_enabled(), False) + self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('power-saver', variant_level=1)) + self.assertEventually(lambda: self.power_saver_enabled == True, "power-saver didn't become enabled", 10) + + self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('balanced', variant_level=1)) + self.assertEventually(lambda: self.power_saver_enabled == False, "power-saver didn't become disabled", 10) + + def test_power_profile_power_saver_enabled_portal_default(self): + '''power-saver-enabled property default value''' + + self.dbus_props.Set('net.hadess.PowerProfiles', 'ActiveProfile', dbus.String('power-saver', variant_level=1)) + + # Create a new power profile monitor and check its property value is + # correct by default. + new_power_profile_monitor = GObject.new(GObject.type_from_name('GPowerProfileMonitorPortal')) + new_power_profile_monitor.init() + self.assertTrue(new_power_profile_monitor.get_power_saver_enabled()) + +except ImportError as e: + @unittest.skip("Cannot import %s" % e.name) + class TestPowerProfileMonitorPortal(unittest.TestCase): + def test_power_profile_power_saver_enabled_portal(self): + pass + +if __name__ == '__main__': + unittest.main(testRunner=taptestrunner.TAPTestRunner()) diff --git a/gio/tests/power-profile-monitor.c b/gio/tests/power-profile-monitor.c new file mode 100644 index 0000000..bb32f18 --- /dev/null +++ b/gio/tests/power-profile-monitor.c @@ -0,0 +1,79 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright 2021 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +static void +test_dup_default (void) +{ + GPowerProfileMonitor *monitor; + + monitor = g_power_profile_monitor_dup_default (); + g_assert_nonnull (monitor); + g_object_unref (monitor); +} + +static void +power_saver_enabled_cb (GPowerProfileMonitor *monitor, + GParamSpec *pspec, + gpointer user_data) +{ + gboolean enabled; + + enabled = g_power_profile_monitor_get_power_saver_enabled (monitor); + g_debug ("Power Saver %s (%d)", enabled ? "enabled" : "disabled", enabled); +} + +static void +do_watch_power_profile (void) +{ + GPowerProfileMonitor *monitor; + GMainLoop *loop; + gulong signal_id; + + monitor = g_power_profile_monitor_dup_default (); + signal_id = g_signal_connect (G_OBJECT (monitor), "notify::power-saver-enabled", + G_CALLBACK (power_saver_enabled_cb), NULL); + + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); + + g_signal_handler_disconnect (monitor, signal_id); + g_object_unref (monitor); + g_main_loop_unref (loop); +} + +int +main (int argc, char **argv) +{ + int ret; + + if (argc == 2 && !strcmp (argv[1], "--watch")) + { + do_watch_power_profile (); + return 0; + } + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/power-profile-monitor/default", test_dup_default); + + ret = g_test_run (); + + return ret; +} diff --git a/gio/tests/proxy-test.c b/gio/tests/proxy-test.c new file mode 100644 index 0000000..d4b71a4 --- /dev/null +++ b/gio/tests/proxy-test.c @@ -0,0 +1,1527 @@ +/* GLib testing framework examples and tests + * + * Copyright 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_34 +#include + +/* Overview: + * + * We have an echo server, two proxy servers, two GProxy + * implementations, and two GProxyResolver implementations. + * + * The echo server runs at @server.server_addr (on + * @server.server_port). + * + * The two proxy servers, A and B, run on @proxy_a.port and + * @proxy_b.port, with @proxy_a.uri and @proxy_b.uri pointing to them. + * The "negotiation" with the two proxies is just sending the single + * letter "a" or "b" and receiving it back in uppercase; the proxy + * then connects to @server_addr. + * + * Proxy A supports "alpha://" URIs, and does not support hostname + * resolution, and Proxy B supports "beta://" URIs, and does support + * hostname resolution (but it just ignores the hostname and always + * connects to @server_addr anyway). + * + * The default GProxyResolver (GTestProxyResolver) looks at its URI + * and returns [ "direct://" ] for "simple://" URIs, and + * [ proxy_a.uri, proxy_b.uri ] for most other URIs. It can also return + * invalid results for other URIs (empty://, invalid://, + * invalid-then-simple://, and simple-then-invalid://) to test error + * handling. + * + * The other GProxyResolver (GTestAltProxyResolver) always returns + * [ proxy_a.uri ]. + */ + +typedef struct { + gchar *proxy_command; + gchar *supported_protocol; + + GSocket *server; + GThread *thread; + GCancellable *cancellable; + gchar *uri; + gushort port; + + GSocket *client_sock, *server_sock; + GMainLoop *loop; + + GError *last_error; +} ProxyData; + +static ProxyData proxy_a, proxy_b; + +typedef struct { + GSocket *server; + GThread *server_thread; + GCancellable *cancellable; + GSocketAddress *server_addr; + gushort server_port; +} ServerData; + +static ServerData server; + +static gchar **last_proxies; + +static GSocketClient *client; + + +/**************************************/ +/* Test GProxyResolver implementation */ +/**************************************/ + +typedef struct { + GObject parent_instance; +} GTestProxyResolver; + +typedef struct { + GObjectClass parent_class; +} GTestProxyResolverClass; + +static void g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface); + +static GType _g_test_proxy_resolver_get_type (void); +#define g_test_proxy_resolver_get_type _g_test_proxy_resolver_get_type +G_DEFINE_TYPE_WITH_CODE (GTestProxyResolver, g_test_proxy_resolver, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER, + g_test_proxy_resolver_iface_init) + g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME, + g_define_type_id, + "test", + 0)) + +static void +g_test_proxy_resolver_init (GTestProxyResolver *resolver) +{ +} + +static gboolean +g_test_proxy_resolver_is_supported (GProxyResolver *resolver) +{ + return TRUE; +} + +static gchar ** +g_test_proxy_resolver_lookup (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GError **error) +{ + gchar **proxies; + + g_assert (last_proxies == NULL); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return NULL; + + proxies = g_new (gchar *, 3); + + if (!strncmp (uri, "simple://", 4)) + { + proxies[0] = g_strdup ("direct://"); + proxies[1] = NULL; + } + else if (g_str_has_prefix (uri, "empty://")) + { + proxies[0] = g_strdup (""); + proxies[1] = NULL; + } + else if (g_str_has_prefix (uri, "invalid://")) + { + proxies[0] = g_strdup ("😼"); + proxies[1] = NULL; + } + else if (g_str_has_prefix (uri, "invalid-then-simple://")) + { + proxies[0] = g_strdup ("😼"); + proxies[1] = g_strdup ("direct://"); + proxies[2] = NULL; + } + else if (g_str_has_prefix (uri, "simple-then-invalid://")) + { + proxies[0] = g_strdup ("direct://"); + proxies[1] = g_strdup ("😼"); + proxies[2] = NULL; + } + else + { + /* Proxy A can only deal with "alpha://" URIs, not + * "beta://", but we always return both URIs + * anyway so we can test error handling when the first + * fails. + */ + proxies[0] = g_strdup (proxy_a.uri); + proxies[1] = g_strdup (proxy_b.uri); + proxies[2] = NULL; + } + + last_proxies = g_strdupv (proxies); + + return proxies; +} + +static void +g_test_proxy_resolver_lookup_async (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GError *error = NULL; + GTask *task; + gchar **proxies; + + proxies = g_proxy_resolver_lookup (resolver, uri, cancellable, &error); + + task = g_task_new (resolver, NULL, callback, user_data); + if (proxies == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, proxies, (GDestroyNotify) g_strfreev); + + g_object_unref (task); +} + +static gchar ** +g_test_proxy_resolver_lookup_finish (GProxyResolver *resolver, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +g_test_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class) +{ +} + +static void +g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface) +{ + iface->is_supported = g_test_proxy_resolver_is_supported; + iface->lookup = g_test_proxy_resolver_lookup; + iface->lookup_async = g_test_proxy_resolver_lookup_async; + iface->lookup_finish = g_test_proxy_resolver_lookup_finish; +} + +/****************************/ +/* Alternate GProxyResolver */ +/****************************/ + +typedef GTestProxyResolver GTestAltProxyResolver; +typedef GTestProxyResolverClass GTestAltProxyResolverClass; + +static void g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface); + +static GType _g_test_alt_proxy_resolver_get_type (void); +#define g_test_alt_proxy_resolver_get_type _g_test_alt_proxy_resolver_get_type +G_DEFINE_TYPE_WITH_CODE (GTestAltProxyResolver, g_test_alt_proxy_resolver, g_test_proxy_resolver_get_type (), + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER, + g_test_alt_proxy_resolver_iface_init); + ) + +static void +g_test_alt_proxy_resolver_init (GTestProxyResolver *resolver) +{ +} + +static gchar ** +g_test_alt_proxy_resolver_lookup (GProxyResolver *resolver, + const gchar *uri, + GCancellable *cancellable, + GError **error) +{ + gchar **proxies; + + proxies = g_new (gchar *, 2); + + proxies[0] = g_strdup (proxy_a.uri); + proxies[1] = NULL; + + last_proxies = g_strdupv (proxies); + + return proxies; +} + +static void +g_test_alt_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class) +{ +} + +static void +g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface) +{ + iface->lookup = g_test_alt_proxy_resolver_lookup; +} + + +/****************************************/ +/* Test proxy implementation base class */ +/****************************************/ + +typedef struct { + GObject parent; + + ProxyData *proxy_data; +} GProxyBase; + +typedef struct { + GObjectClass parent_class; +} GProxyBaseClass; + +static GType _g_proxy_base_get_type (void); +#define g_proxy_base_get_type _g_proxy_base_get_type +G_DEFINE_ABSTRACT_TYPE (GProxyBase, g_proxy_base, G_TYPE_OBJECT) + +static void +g_proxy_base_init (GProxyBase *proxy) +{ +} + +static GIOStream * +g_proxy_base_connect (GProxy *proxy, + GIOStream *io_stream, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GError **error) +{ + ProxyData *data = ((GProxyBase *) proxy)->proxy_data; + const gchar *protocol; + GOutputStream *ostream; + GInputStream *istream; + gchar response; + + g_assert_no_error (data->last_error); + + protocol = g_proxy_address_get_destination_protocol (proxy_address); + if (strcmp (protocol, data->supported_protocol) != 0) + { + g_set_error_literal (&data->last_error, + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Unsupported protocol"); + goto fail; + } + + ostream = g_io_stream_get_output_stream (io_stream); + if (g_output_stream_write (ostream, data->proxy_command, 1, cancellable, + &data->last_error) != 1) + goto fail; + + istream = g_io_stream_get_input_stream (io_stream); + if (g_input_stream_read (istream, &response, 1, cancellable, + &data->last_error) != 1) + goto fail; + + if (response != g_ascii_toupper (*data->proxy_command)) + { + g_set_error_literal (&data->last_error, + G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed"); + goto fail; + } + + return g_object_ref (io_stream); + + fail: + g_propagate_error (error, g_error_copy (data->last_error)); + return NULL; +} + +static void +g_proxy_base_connect_async (GProxy *proxy, + GIOStream *io_stream, + GProxyAddress *proxy_address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GError *error = NULL; + GTask *task; + GIOStream *proxy_io_stream; + + task = g_task_new (proxy, NULL, callback, user_data); + + proxy_io_stream = g_proxy_connect (proxy, io_stream, proxy_address, + cancellable, &error); + if (proxy_io_stream) + g_task_return_pointer (task, proxy_io_stream, g_object_unref); + else + g_task_return_error (task, error); + g_object_unref (task); +} + +static GIOStream * +g_proxy_base_connect_finish (GProxy *proxy, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +g_proxy_base_class_init (GProxyBaseClass *class) +{ +} + + +/********************************************/ +/* Test proxy implementation #1 ("Proxy A") */ +/********************************************/ + +typedef GProxyBase GProxyA; +typedef GProxyBaseClass GProxyAClass; + +static void g_proxy_a_iface_init (GProxyInterface *proxy_iface); + +static GType _g_proxy_a_get_type (void); +#define g_proxy_a_get_type _g_proxy_a_get_type +G_DEFINE_TYPE_WITH_CODE (GProxyA, g_proxy_a, g_proxy_base_get_type (), + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY, + g_proxy_a_iface_init) + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME, + g_define_type_id, + "proxy-a", + 0)) + +static void +g_proxy_a_init (GProxyA *proxy) +{ + ((GProxyBase *) proxy)->proxy_data = &proxy_a; +} + +static gboolean +g_proxy_a_supports_hostname (GProxy *proxy) +{ + return FALSE; +} + +static void +g_proxy_a_class_init (GProxyAClass *class) +{ +} + +static void +g_proxy_a_iface_init (GProxyInterface *proxy_iface) +{ + proxy_iface->connect = g_proxy_base_connect; + proxy_iface->connect_async = g_proxy_base_connect_async; + proxy_iface->connect_finish = g_proxy_base_connect_finish; + proxy_iface->supports_hostname = g_proxy_a_supports_hostname; +} + +/********************************************/ +/* Test proxy implementation #2 ("Proxy B") */ +/********************************************/ + +typedef GProxyBase GProxyB; +typedef GProxyBaseClass GProxyBClass; + +static void g_proxy_b_iface_init (GProxyInterface *proxy_iface); + +static GType _g_proxy_b_get_type (void); +#define g_proxy_b_get_type _g_proxy_b_get_type +G_DEFINE_TYPE_WITH_CODE (GProxyB, g_proxy_b, g_proxy_base_get_type (), + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY, + g_proxy_b_iface_init) + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME, + g_define_type_id, + "proxy-b", + 0)) + +static void +g_proxy_b_init (GProxyB *proxy) +{ + ((GProxyBase *) proxy)->proxy_data = &proxy_b; +} + +static gboolean +g_proxy_b_supports_hostname (GProxy *proxy) +{ + return TRUE; +} + +static void +g_proxy_b_class_init (GProxyBClass *class) +{ +} + +static void +g_proxy_b_iface_init (GProxyInterface *proxy_iface) +{ + proxy_iface->connect = g_proxy_base_connect; + proxy_iface->connect_async = g_proxy_base_connect_async; + proxy_iface->connect_finish = g_proxy_base_connect_finish; + proxy_iface->supports_hostname = g_proxy_b_supports_hostname; +} + + +/***********************************/ +/* The proxy server implementation */ +/***********************************/ + +static gboolean +proxy_bytes (GSocket *socket, + GIOCondition condition, + gpointer user_data) +{ + ProxyData *proxy = user_data; + gssize nread, nwrote, total; + gchar buffer[8]; + GSocket *out_socket; + GError *error = NULL; + + nread = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer), + TRUE, NULL, &error); + if (nread == -1) + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); + return FALSE; + } + else + g_assert_no_error (error); + + if (nread == 0) + { + g_main_loop_quit (proxy->loop); + return FALSE; + } + + if (socket == proxy->client_sock) + out_socket = proxy->server_sock; + else + out_socket = proxy->client_sock; + + for (total = 0; total < nread; total += nwrote) + { + nwrote = g_socket_send_with_blocking (out_socket, + buffer + total, nread - total, + TRUE, NULL, &error); + g_assert_no_error (error); + } + + return TRUE; +} + +static gpointer +proxy_thread (gpointer user_data) +{ + ProxyData *proxy = user_data; + GError *error = NULL; + gssize nread, nwrote; + gchar command[2] = { 0, 0 }; + GMainContext *context; + GSource *read_source, *write_source; + + context = g_main_context_new (); + proxy->loop = g_main_loop_new (context, FALSE); + + while (TRUE) + { + proxy->client_sock = g_socket_accept (proxy->server, proxy->cancellable, &error); + if (!proxy->client_sock) + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_error_free (error); + break; + } + else + g_assert_no_error (error); + + nread = g_socket_receive (proxy->client_sock, command, 1, NULL, &error); + g_assert_no_error (error); + + if (nread == 0) + { + g_clear_object (&proxy->client_sock); + continue; + } + + g_assert_cmpint (nread, ==, 1); + g_assert_cmpstr (command, ==, proxy->proxy_command); + + *command = g_ascii_toupper (*command); + nwrote = g_socket_send (proxy->client_sock, command, 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, 1); + + proxy->server_sock = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + g_socket_connect (proxy->server_sock, server.server_addr, NULL, &error); + g_assert_no_error (error); + + read_source = g_socket_create_source (proxy->client_sock, G_IO_IN, NULL); + g_source_set_callback (read_source, (GSourceFunc)proxy_bytes, proxy, NULL); + g_source_attach (read_source, context); + + write_source = g_socket_create_source (proxy->server_sock, G_IO_IN, NULL); + g_source_set_callback (write_source, (GSourceFunc)proxy_bytes, proxy, NULL); + g_source_attach (write_source, context); + + g_main_loop_run (proxy->loop); + + g_socket_close (proxy->client_sock, &error); + g_assert_no_error (error); + g_clear_object (&proxy->client_sock); + + g_socket_close (proxy->server_sock, &error); + g_assert_no_error (error); + g_clear_object (&proxy->server_sock); + + g_source_destroy (read_source); + g_source_unref (read_source); + g_source_destroy (write_source); + g_source_unref (write_source); + } + + g_main_loop_unref (proxy->loop); + g_main_context_unref (context); + + g_object_unref (proxy->server); + g_object_unref (proxy->cancellable); + + g_free (proxy->proxy_command); + g_free (proxy->supported_protocol); + g_free (proxy->uri); + + return NULL; +} + +static void +create_proxy (ProxyData *proxy, + gchar proxy_protocol, + const gchar *destination_protocol, + GCancellable *cancellable) +{ + GError *error = NULL; + GSocketAddress *addr; + GInetAddress *iaddr; + + proxy->proxy_command = g_strdup_printf ("%c", proxy_protocol); + proxy->supported_protocol = g_strdup (destination_protocol); + proxy->cancellable = g_object_ref (cancellable); + + proxy->server = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + g_socket_bind (proxy->server, addr, TRUE, &error); + g_assert_no_error (error); + g_object_unref (addr); + + addr = g_socket_get_local_address (proxy->server, &error); + proxy->port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)); + proxy->uri = g_strdup_printf ("proxy-%c://127.0.0.1:%u", + g_ascii_tolower (proxy_protocol), + proxy->port); + g_object_unref (addr); + + g_socket_listen (proxy->server, &error); + g_assert_no_error (error); + + proxy->thread = g_thread_new ("proxy", proxy_thread, proxy); +} + + + +/**************************/ +/* The actual echo server */ +/**************************/ + +static gpointer +echo_server_thread (gpointer user_data) +{ + ServerData *data = user_data; + GSocket *sock; + GError *error = NULL; + gssize nread, nwrote; + gchar buf[128]; + + while (TRUE) + { + sock = g_socket_accept (data->server, data->cancellable, &error); + if (!sock) + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_error_free (error); + break; + } + else + g_assert_no_error (error); + + while (TRUE) + { + nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nread, >=, 0); + + if (nread == 0) + break; + + nwrote = g_socket_send (sock, buf, nread, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, nread); + } + + g_socket_close (sock, &error); + g_assert_no_error (error); + g_object_unref (sock); + } + + g_object_unref (data->server); + g_object_unref (data->server_addr); + g_object_unref (data->cancellable); + + return NULL; +} + +static void +create_server (ServerData *data, GCancellable *cancellable) +{ + GError *error = NULL; + GSocketAddress *addr; + GInetAddress *iaddr; + + data->cancellable = g_object_ref (cancellable); + + data->server = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (data->server, TRUE); + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + g_socket_bind (data->server, addr, TRUE, &error); + g_assert_no_error (error); + g_object_unref (addr); + + data->server_addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + data->server_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (data->server_addr)); + + g_socket_listen (data->server, &error); + g_assert_no_error (error); + + data->server_thread = g_thread_new ("server", echo_server_thread, data); +} + + +/******************************************************************/ +/* Now a GResolver implementation, so the can't-resolve test will */ +/* pass even if you have an evil DNS-faking ISP. */ +/******************************************************************/ + +typedef GResolver GFakeResolver; +typedef GResolverClass GFakeResolverClass; + +static GType g_fake_resolver_get_type (void); +G_DEFINE_TYPE (GFakeResolver, g_fake_resolver, G_TYPE_RESOLVER) + +static void +g_fake_resolver_init (GFakeResolver *gtr) +{ +} + +static GList * +g_fake_resolver_lookup_by_name (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GError **error) +{ + if (!strcmp (hostname, "example.com")) + return g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1")); + else + { + /* Anything else is expected to fail. */ + g_set_error (error, + G_RESOLVER_ERROR, + G_RESOLVER_ERROR_NOT_FOUND, + "Not found"); + return NULL; + } +} + +static void +g_fake_resolver_lookup_by_name_async (GResolver *resolver, + const gchar *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (resolver, cancellable, callback, user_data); + + if (!strcmp (hostname, "example.com")) + { + GList *result; + + result = g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1")); + g_task_return_pointer (task, result, (GDestroyNotify) g_resolver_free_addresses); + } + else + { + g_task_return_new_error (task, + G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, + "Not found"); + } + g_object_unref (task); +} + +static void +g_fake_resolver_lookup_by_name_with_flags_async (GResolver *resolver, + const gchar *hostname, + GResolverNameLookupFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + /* Note this isn't a real implementation as it ignores the flags */ + g_fake_resolver_lookup_by_name_async (resolver, + hostname, + cancellable, + callback, + user_data); +} + +static GList * +g_fake_resolver_lookup_by_name_finish (GResolver *resolver, + GAsyncResult *result, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (result), error); +} + +static void +g_fake_resolver_class_init (GFakeResolverClass *fake_class) +{ + GResolverClass *resolver_class = G_RESOLVER_CLASS (fake_class); + + resolver_class->lookup_by_name = g_fake_resolver_lookup_by_name; + resolver_class->lookup_by_name_async = g_fake_resolver_lookup_by_name_async; + resolver_class->lookup_by_name_finish = g_fake_resolver_lookup_by_name_finish; + resolver_class->lookup_by_name_with_flags_async = g_fake_resolver_lookup_by_name_with_flags_async; + resolver_class->lookup_by_name_with_flags_finish = g_fake_resolver_lookup_by_name_finish; +} + + + +/****************************************/ +/* We made it! Now for the actual test! */ +/****************************************/ + +static void +setup_test (gpointer fixture, + gconstpointer user_data) +{ +} + +static void +teardown_test (gpointer fixture, + gconstpointer user_data) +{ + g_clear_pointer (&last_proxies, g_strfreev); + + g_clear_error (&proxy_a.last_error); + g_clear_error (&proxy_b.last_error); +} + + +static const gchar *testbuf = "0123456789abcdef"; + +static void +do_echo_test (GSocketConnection *conn) +{ + GIOStream *iostream = G_IO_STREAM (conn); + GInputStream *istream = g_io_stream_get_input_stream (iostream); + GOutputStream *ostream = g_io_stream_get_output_stream (iostream); + gssize nread; + gsize nwrote, total; + gchar buf[128]; + GError *error = NULL; + + g_output_stream_write_all (ostream, testbuf, strlen (testbuf), + &nwrote, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, strlen (testbuf)); + + for (total = 0; total < nwrote; total += nread) + { + nread = g_input_stream_read (istream, + buf + total, sizeof (buf) - total, + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nread, >, 0); + } + + buf[total] = '\0'; + g_assert_cmpstr (buf, ==, testbuf); +} + +static void +async_got_conn (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection **conn = user_data; + GError *error = NULL; + + *conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (source), + result, &error); + g_assert_no_error (error); +} + +static void +async_got_error (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GError **error = user_data; + + g_assert (error != NULL && *error == NULL); + g_socket_client_connect_finish (G_SOCKET_CLIENT (source), + result, error); + g_assert (*error != NULL); +} + + +static void +assert_direct (GSocketConnection *conn) +{ + GSocketAddress *addr; + GError *error = NULL; + + g_assert_cmpint (g_strv_length (last_proxies), ==, 1); + g_assert_cmpstr (last_proxies[0], ==, "direct://"); + g_assert_no_error (proxy_a.last_error); + g_assert_no_error (proxy_b.last_error); + + addr = g_socket_connection_get_remote_address (conn, &error); + g_assert_no_error (error); + g_assert (addr != NULL && !G_IS_PROXY_ADDRESS (addr)); + g_object_unref (addr); + + addr = g_socket_connection_get_local_address (conn, &error); + g_assert_no_error (error); + g_object_unref (addr); + + g_assert (g_socket_connection_is_connected (conn)); +} + +static void +test_direct_sync (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + gchar *uri; + GError *error = NULL; + + /* The simple:// URI should not require any proxy. */ + + uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_free (uri); + g_assert_no_error (error); + + assert_direct (conn); + do_echo_test (conn); + g_object_unref (conn); +} + +static void +test_direct_async (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + gchar *uri; + + /* The simple:// URI should not require any proxy. */ + uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port); + conn = NULL; + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_conn, &conn); + g_free (uri); + while (conn == NULL) + g_main_context_iteration (NULL, TRUE); + + assert_direct (conn); + do_echo_test (conn); + g_object_unref (conn); +} + +static void +assert_single (GSocketConnection *conn) +{ + GSocketAddress *addr; + const gchar *proxy_uri; + gushort proxy_port; + GError *error = NULL; + + g_assert_cmpint (g_strv_length (last_proxies), ==, 2); + g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri); + g_assert_cmpstr (last_proxies[1], ==, proxy_b.uri); + g_assert_no_error (proxy_a.last_error); + g_assert_no_error (proxy_b.last_error); + + addr = g_socket_connection_get_remote_address (conn, &error); + g_assert_no_error (error); + g_assert (G_IS_PROXY_ADDRESS (addr)); + proxy_uri = g_proxy_address_get_uri (G_PROXY_ADDRESS (addr)); + g_assert_cmpstr (proxy_uri, ==, proxy_a.uri); + proxy_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)); + g_assert_cmpint (proxy_port, ==, proxy_a.port); + + g_object_unref (addr); +} + +static void +test_single_sync (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + GError *error = NULL; + gchar *uri; + + /* The alpha:// URI should be proxied via Proxy A */ + uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_free (uri); + g_assert_no_error (error); + + assert_single (conn); + + do_echo_test (conn); + g_object_unref (conn); +} + +static void +test_single_async (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + gchar *uri; + + /* The alpha:// URI should be proxied via Proxy A */ + uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port); + conn = NULL; + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_conn, &conn); + g_free (uri); + while (conn == NULL) + g_main_context_iteration (NULL, TRUE); + + assert_single (conn); + do_echo_test (conn); + g_object_unref (conn); +} + +static void +assert_multiple (GSocketConnection *conn) +{ + GSocketAddress *addr; + const gchar *proxy_uri; + gushort proxy_port; + GError *error = NULL; + + g_assert_cmpint (g_strv_length (last_proxies), ==, 2); + g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri); + g_assert_cmpstr (last_proxies[1], ==, proxy_b.uri); + g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_assert_no_error (proxy_b.last_error); + + addr = g_socket_connection_get_remote_address (conn, &error); + g_assert_no_error (error); + g_assert (G_IS_PROXY_ADDRESS (addr)); + proxy_uri = g_proxy_address_get_uri (G_PROXY_ADDRESS (addr)); + g_assert_cmpstr (proxy_uri, ==, proxy_b.uri); + proxy_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)); + g_assert_cmpint (proxy_port, ==, proxy_b.port); + + g_object_unref (addr); +} + +static void +test_multiple_sync (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + GError *error = NULL; + gchar *uri; + + /* The beta:// URI should be proxied via Proxy B, after failing + * via Proxy A. + */ + uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_free (uri); + g_assert_no_error (error); + + assert_multiple (conn); + do_echo_test (conn); + g_object_unref (conn); +} + +static void +test_multiple_async (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + gchar *uri; + + /* The beta:// URI should be proxied via Proxy B, after failing + * via Proxy A. + */ + uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port); + conn = NULL; + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_conn, &conn); + g_free (uri); + while (conn == NULL) + g_main_context_iteration (NULL, TRUE); + + assert_multiple (conn); + do_echo_test (conn); + g_object_unref (conn); +} + +static void +test_invalid_uris_sync (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + gchar *uri; + GError *error = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2597"); + + /* The empty:// URI causes the proxy resolver to return an empty string. */ + uri = g_strdup_printf ("empty://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_free (uri); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_assert_null (conn); + g_clear_error (&error); + g_clear_pointer (&last_proxies, g_strfreev); + + /* The invalid:// URI causes the proxy resolver to return a cat emoji. */ + uri = g_strdup_printf ("invalid://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_free (uri); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_assert_null (conn); + g_clear_error (&error); + g_clear_pointer (&last_proxies, g_strfreev); + + /* If the proxy resolver returns an invalid URI before a valid URI, + * we should succeed. + */ + uri = g_strdup_printf ("invalid-then-simple://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_free (uri); + g_assert_no_error (error); + do_echo_test (conn); + g_object_unref (conn); + g_clear_pointer (&last_proxies, g_strfreev); + + /* If the proxy resolver returns a valid URI before an invalid URI, + * we should succeed. + */ + uri = g_strdup_printf ("simple-then-invalid://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_free (uri); + g_assert_no_error (error); + do_echo_test (conn); + g_object_unref (conn); + g_clear_pointer (&last_proxies, g_strfreev); +} + +static void +test_invalid_uris_async (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + GError *error = NULL; + gchar *uri; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2597"); + + /* The empty:// URI causes the proxy resolver to return an empty string. */ + uri = g_strdup_printf ("empty://127.0.0.1:%u", server.server_port); + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_error, &error); + g_free (uri); + while (error == NULL) + g_main_context_iteration (NULL, TRUE); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_clear_error (&error); + g_clear_pointer (&last_proxies, g_strfreev); + + /* The invalid:// URI causes the proxy resolver to return a cat emoji. */ + uri = g_strdup_printf ("invalid://127.0.0.1:%u", server.server_port); + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_error, &error); + g_free (uri); + while (error == NULL) + g_main_context_iteration (NULL, TRUE); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_clear_error (&error); + g_clear_pointer (&last_proxies, g_strfreev); + + /* If the proxy resolver returns an invalid URI before a valid URI, + * we should succeed. + */ + uri = g_strdup_printf ("invalid-then-simple://127.0.0.1:%u", server.server_port); + conn = NULL; + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_conn, &conn); + g_free (uri); + while (conn == NULL) + g_main_context_iteration (NULL, TRUE); + do_echo_test (conn); + g_object_unref (conn); + g_clear_pointer (&last_proxies, g_strfreev); + + /* If the proxy resolver returns a valid URI before an invalid URI, + * we should succeed. + */ + uri = g_strdup_printf ("simple-then-invalid://127.0.0.1:%u", server.server_port); + conn = NULL; + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_conn, &conn); + g_free (uri); + while (conn == NULL) + g_main_context_iteration (NULL, TRUE); + do_echo_test (conn); + g_object_unref (conn); + g_clear_pointer (&last_proxies, g_strfreev); +} + +static void +test_dns (gpointer fixture, + gconstpointer user_data) +{ + GSocketConnection *conn; + GError *error = NULL; + gchar *uri; + + /* The simple:// and alpha:// URIs should fail with a DNS error, + * but the beta:// URI should succeed, because we pass it to + * Proxy B without trying to resolve it first + */ + + /* simple */ + uri = g_strdup_printf ("simple://no-such-host.xx:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND); + g_clear_error (&error); + + g_assert_no_error (proxy_a.last_error); + g_assert_no_error (proxy_b.last_error); + teardown_test (NULL, NULL); + + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_error, &error); + while (error == NULL) + g_main_context_iteration (NULL, TRUE); + g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND); + g_clear_error (&error); + g_free (uri); + + g_assert_no_error (proxy_a.last_error); + g_assert_no_error (proxy_b.last_error); + teardown_test (NULL, NULL); + + /* alpha */ + uri = g_strdup_printf ("alpha://no-such-host.xx:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + /* Since Proxy A fails, @client will try Proxy B too, which won't + * load an alpha:// URI. + */ + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + + g_assert_no_error (proxy_a.last_error); + g_assert_error (proxy_b.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + teardown_test (NULL, NULL); + + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_error, &error); + while (error == NULL) + g_main_context_iteration (NULL, TRUE); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + g_free (uri); + + g_assert_no_error (proxy_a.last_error); + g_assert_error (proxy_b.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + teardown_test (NULL, NULL); + + /* beta */ + uri = g_strdup_printf ("beta://no-such-host.xx:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_assert_no_error (error); + + g_assert_no_error (proxy_a.last_error); + g_assert_no_error (proxy_b.last_error); + + do_echo_test (conn); + g_clear_object (&conn); + teardown_test (NULL, NULL); + + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_conn, &conn); + while (conn == NULL) + g_main_context_iteration (NULL, TRUE); + g_free (uri); + + g_assert_no_error (proxy_a.last_error); + g_assert_no_error (proxy_b.last_error); + + do_echo_test (conn); + g_clear_object (&conn); + teardown_test (NULL, NULL); +} + +static void +assert_override (GSocketConnection *conn) +{ + g_assert_cmpint (g_strv_length (last_proxies), ==, 1); + g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri); + + if (conn) + g_assert_no_error (proxy_a.last_error); + else + g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); +} + +static void +test_override (gpointer fixture, + gconstpointer user_data) +{ + GProxyResolver *alt_resolver; + GSocketConnection *conn; + GError *error = NULL; + gchar *uri; + + g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ()); + alt_resolver = g_object_new (g_test_alt_proxy_resolver_get_type (), NULL); + g_socket_client_set_proxy_resolver (client, alt_resolver); + g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver); + + /* Alt proxy resolver always returns Proxy A, so alpha:// should + * succeed, and simple:// and beta:// should fail. + */ + + /* simple */ + uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + assert_override (conn); + teardown_test (NULL, NULL); + + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_error, &error); + while (error == NULL) + g_main_context_iteration (NULL, TRUE); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + assert_override (conn); + g_free (uri); + teardown_test (NULL, NULL); + + /* alpha */ + uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_assert_no_error (error); + assert_override (conn); + do_echo_test (conn); + g_clear_object (&conn); + teardown_test (NULL, NULL); + + conn = NULL; + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_conn, &conn); + while (conn == NULL) + g_main_context_iteration (NULL, TRUE); + assert_override (conn); + do_echo_test (conn); + g_clear_object (&conn); + g_free (uri); + teardown_test (NULL, NULL); + + /* beta */ + uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port); + conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + assert_override (conn); + teardown_test (NULL, NULL); + + g_socket_client_connect_to_uri_async (client, uri, 0, NULL, + async_got_error, &error); + while (error == NULL) + g_main_context_iteration (NULL, TRUE); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + assert_override (conn); + g_free (uri); + teardown_test (NULL, NULL); + + g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver); + g_socket_client_set_proxy_resolver (client, NULL); + g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ()); + g_object_unref (alt_resolver); +} + +static void +assert_destination_port (GSocketAddressEnumerator *etor, + guint16 port) +{ + GSocketAddress *addr; + GProxyAddress *paddr; + GError *error = NULL; + + while ((addr = g_socket_address_enumerator_next (etor, NULL, &error))) + { + g_assert_no_error (error); + + g_assert (G_IS_PROXY_ADDRESS (addr)); + paddr = G_PROXY_ADDRESS (addr); + g_assert_cmpint (g_proxy_address_get_destination_port (paddr), ==, port); + g_object_unref (addr); + } + g_assert_no_error (error); +} + +static void +test_proxy_enumerator_ports (void) +{ + GSocketAddressEnumerator *etor; + + etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, + "uri", "http://example.com/", + NULL); + assert_destination_port (etor, 0); + g_object_unref (etor); + + /* Have to call this to clear last_proxies so the next call to + * g_test_proxy_resolver_lookup() won't assert. + */ + teardown_test (NULL, NULL); + + etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, + "uri", "http://example.com:8080/", + NULL); + assert_destination_port (etor, 8080); + g_object_unref (etor); + + teardown_test (NULL, NULL); + + etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, + "uri", "http://example.com/", + "default-port", 80, + NULL); + assert_destination_port (etor, 80); + g_object_unref (etor); + + teardown_test (NULL, NULL); + + etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, + "uri", "http://example.com:8080/", + "default-port", 80, + NULL); + assert_destination_port (etor, 8080); + g_object_unref (etor); + + teardown_test (NULL, NULL); +} + +int +main (int argc, + char *argv[]) +{ + GResolver *fake_resolver; + GCancellable *cancellable; + gint result; + + g_test_init (&argc, &argv, NULL); + + /* Register stuff. The dummy g_proxy_get_default_for_protocol() call + * is to force _g_io_modules_ensure_extension_points_registered() to + * get called, so we can then register a proxy resolver extension + * point. + */ + g_proxy_get_default_for_protocol ("foo"); + g_test_proxy_resolver_get_type (); + g_proxy_a_get_type (); + g_proxy_b_get_type (); + g_setenv ("GIO_USE_PROXY_RESOLVER", "test", TRUE); + + fake_resolver = g_object_new (g_fake_resolver_get_type (), NULL); + g_resolver_set_default (fake_resolver); + + cancellable = g_cancellable_new (); + create_server (&server, cancellable); + create_proxy (&proxy_a, 'a', "alpha", cancellable); + create_proxy (&proxy_b, 'b', "beta", cancellable); + + client = g_socket_client_new (); + g_assert_cmpint (g_socket_client_get_enable_proxy (client), ==, TRUE); + + g_test_add_vtable ("/proxy/direct_sync", 0, NULL, setup_test, test_direct_sync, teardown_test); + g_test_add_vtable ("/proxy/direct_async", 0, NULL, setup_test, test_direct_async, teardown_test); + g_test_add_vtable ("/proxy/single_sync", 0, NULL, setup_test, test_single_sync, teardown_test); + g_test_add_vtable ("/proxy/single_async", 0, NULL, setup_test, test_single_async, teardown_test); + g_test_add_vtable ("/proxy/multiple_sync", 0, NULL, setup_test, test_multiple_sync, teardown_test); + g_test_add_vtable ("/proxy/multiple_async", 0, NULL, setup_test, test_multiple_async, teardown_test); + g_test_add_vtable ("/proxy/invalid-uris-sync", 0, NULL, setup_test, test_invalid_uris_sync, teardown_test); + g_test_add_vtable ("/proxy/invalid-uris-async", 0, NULL, setup_test, test_invalid_uris_async, teardown_test); + g_test_add_vtable ("/proxy/dns", 0, NULL, setup_test, test_dns, teardown_test); + g_test_add_vtable ("/proxy/override", 0, NULL, setup_test, test_override, teardown_test); + g_test_add_func ("/proxy/enumerator-ports", test_proxy_enumerator_ports); + + result = g_test_run(); + + g_object_unref (client); + + g_cancellable_cancel (cancellable); + g_thread_join (proxy_a.thread); + g_thread_join (proxy_b.thread); + g_thread_join (server.server_thread); + + g_object_unref (cancellable); + + return result; +} diff --git a/gio/tests/proxy.c b/gio/tests/proxy.c new file mode 100644 index 0000000..e64355a --- /dev/null +++ b/gio/tests/proxy.c @@ -0,0 +1,658 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2010 Collabora, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Nicolas Dufresne + */ + +#include "config.h" + +#include +#include +#include + +#include +#include + +#include "glibintl.h" + +#ifdef G_OS_UNIX +#include "gio/gunixsocketaddress.h" +#endif + +static const gchar *info = NULL; +static GCancellable *cancellable = NULL; +static gint return_value = 0; + +static G_NORETURN void +usage (void) +{ + fprintf (stderr, "Usage: proxy [-s] (uri|host:port|ip:port|path|srv/protocol/domain)\n"); + fprintf (stderr, " Use -t to enable threading.\n"); + fprintf (stderr, " Use -s to do synchronous lookups.\n"); + fprintf (stderr, " Use -c to cancel operation.\n"); + fprintf (stderr, " Use -e to use enumerator.\n"); + fprintf (stderr, " Use -inet to use GInetSocketAddress enumerator (ip:port).\n"); +#ifdef G_OS_UNIX + fprintf (stderr, " Use -unix to use GUnixSocketAddress enumerator (path).\n"); +#endif + fprintf (stderr, " Use -proxyaddr tp use GProxyAddress enumerator " + "(ip:port:protocol:dest_host:dest_port[:username[:password]]).\n"); + fprintf (stderr, " Use -netaddr to use GNetworkAddress enumerator (host:port).\n"); + fprintf (stderr, " Use -neturi to use GNetworkAddress enumerator (uri).\n"); + fprintf (stderr, " Use -netsrv to use GNetworkService enumerator (srv/protocol/domain).\n"); + fprintf (stderr, " Use -connect to create a connection using GSocketClient object (uri).\n"); + exit (1); +} + +static void +print_and_free_error (GError *error) +{ + fprintf (stderr, "Failed to obtain proxies: %s\n", error->message); + g_error_free (error); + return_value = 1; +} + +static void +print_proxies (const gchar *info, gchar **proxies) +{ + printf ("Proxies for URI '%s' are:\n", info); + + if (proxies == NULL || proxies[0] == NULL) + printf ("\tnone\n"); + else + for (; proxies[0]; proxies++) + printf ("\t%s\n", proxies[0]); +} + +static void +_proxy_lookup_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + gchar **proxies; + GMainLoop *loop = user_data; + + proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (source_object), + result, + &error); + if (error) + { + print_and_free_error (error); + } + else + { + print_proxies (info, proxies); + g_strfreev (proxies); + } + + g_main_loop_quit (loop); +} + +static void +use_resolver (gboolean synchronous) +{ + GProxyResolver *resolver; + + resolver = g_proxy_resolver_get_default (); + + if (synchronous) + { + GError *error = NULL; + gchar **proxies; + + proxies = g_proxy_resolver_lookup (resolver, info, cancellable, &error); + + if (error) + print_and_free_error (error); + else + print_proxies (info, proxies); + + g_strfreev (proxies); + } + else + { + GMainLoop *loop = g_main_loop_new (NULL, FALSE); + + g_proxy_resolver_lookup_async (resolver, + info, + cancellable, + _proxy_lookup_cb, + loop); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + } +} + +static void +print_proxy_address (GSocketAddress *sockaddr) +{ + GProxyAddress *proxy = NULL; + + if (sockaddr == NULL) + { + printf ("\tdirect://\n"); + return; + } + + if (G_IS_PROXY_ADDRESS (sockaddr)) + { + proxy = G_PROXY_ADDRESS (sockaddr); + printf ("\t%s://", g_proxy_address_get_protocol(proxy)); + } + else + { + printf ("\tdirect://"); + } + + if (G_IS_INET_SOCKET_ADDRESS (sockaddr)) + { + GInetAddress *inetaddr; + guint port; + gchar *addr; + + g_object_get (sockaddr, + "address", &inetaddr, + "port", &port, + NULL); + + addr = g_inet_address_to_string (inetaddr); + + printf ("%s:%u", addr, port); + + g_free (addr); + } + + if (proxy) + { + if (g_proxy_address_get_username(proxy)) + printf (" (Username: %s Password: %s)", + g_proxy_address_get_username(proxy), + g_proxy_address_get_password(proxy)); + printf (" (Hostname: %s, Port: %i)", + g_proxy_address_get_destination_hostname (proxy), + g_proxy_address_get_destination_port (proxy)); + } + + printf ("\n"); +} + +static void +_proxy_enumerate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + GMainLoop *loop = user_data; + GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object); + GSocketAddress *sockaddr; + + sockaddr = g_socket_address_enumerator_next_finish (enumerator, + result, + &error); + if (sockaddr) + { + print_proxy_address (sockaddr); + g_socket_address_enumerator_next_async (enumerator, + cancellable, + _proxy_enumerate_cb, + loop); + g_object_unref (sockaddr); + } + else + { + if (error) + print_and_free_error (error); + + g_main_loop_quit (loop); + } +} + +static void +run_with_enumerator (gboolean synchronous, GSocketAddressEnumerator *enumerator) +{ + GError *error = NULL; + + if (synchronous) + { + GSocketAddress *sockaddr; + + while ((sockaddr = g_socket_address_enumerator_next (enumerator, + cancellable, + &error))) + { + print_proxy_address (sockaddr); + g_object_unref (sockaddr); + } + + if (error) + print_and_free_error (error); + } + else + { + GMainLoop *loop = g_main_loop_new (NULL, FALSE); + + g_socket_address_enumerator_next_async (enumerator, + cancellable, + _proxy_enumerate_cb, + loop); + g_main_loop_run (loop); + g_main_loop_unref (loop); + } +} + +static void +use_enumerator (gboolean synchronous) +{ + GSocketAddressEnumerator *enumerator; + + enumerator = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, + "uri", info, + NULL); + + printf ("Proxies for URI '%s' are:\n", info); + run_with_enumerator (synchronous, enumerator); + + g_object_unref (enumerator); +} + +static void +use_inet_address (gboolean synchronous) +{ + GSocketAddressEnumerator *enumerator; + GSocketAddress *sockaddr; + GInetAddress *addr = NULL; + guint port = 0; + gchar **ip_and_port; + + ip_and_port = g_strsplit (info, ":", 2); + + if (ip_and_port[0]) + { + addr = g_inet_address_new_from_string (ip_and_port[0]); + if (ip_and_port [1]) + port = strtoul (ip_and_port [1], NULL, 10); + } + + g_strfreev (ip_and_port); + + if (addr == NULL || port <= 0 || port >= 65535) + { + fprintf (stderr, "Bad 'ip:port' parameter '%s'\n", info); + if (addr) + g_object_unref (addr); + return_value = 1; + return; + } + + sockaddr = g_inet_socket_address_new (addr, port); + g_object_unref (addr); + + enumerator = + g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr)); + g_object_unref (sockaddr); + + printf ("Proxies for ip and port '%s' are:\n", info); + run_with_enumerator (synchronous, enumerator); + + g_object_unref (enumerator); +} + +#ifdef G_OS_UNIX +static void +use_unix_address (gboolean synchronous) +{ + GSocketAddressEnumerator *enumerator; + GSocketAddress *sockaddr; + + sockaddr = g_unix_socket_address_new_with_type (info, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); + + if (sockaddr == NULL) + { + fprintf (stderr, "Failed to create unix socket with name '%s'\n", info); + return_value = 1; + return; + } + + enumerator = + g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr)); + g_object_unref (sockaddr); + + printf ("Proxies for path '%s' are:\n", info); + run_with_enumerator (synchronous, enumerator); + + g_object_unref (enumerator); +} +#endif + +static void +use_proxy_address (gboolean synchronous) +{ + GSocketAddressEnumerator *enumerator; + GSocketAddress *sockaddr; + GInetAddress *addr; + guint port = 0; + gchar *protocol; + gchar *dest_host; + guint dest_port; + gchar *username = NULL; + gchar *password = NULL; + gchar **split_info; + + split_info = g_strsplit (info, ":", 7); + + if (!split_info[0] + || !split_info[1] + || !split_info[2] + || !split_info[3] + || !split_info[4]) + { + fprintf (stderr, "Bad 'ip:port:protocol:dest_host:dest_port' parameter '%s'\n", info); + return_value = 1; + return; + } + + addr = g_inet_address_new_from_string (split_info[0]); + port = strtoul (split_info [1], NULL, 10); + protocol = g_strdup (split_info[2]); + dest_host = g_strdup (split_info[3]); + dest_port = strtoul (split_info[4], NULL, 10); + + if (split_info[5]) + { + username = g_strdup (split_info[5]); + if (split_info[6]) + password = g_strdup (split_info[6]); + } + + g_strfreev (split_info); + + sockaddr = g_proxy_address_new (addr, port, + protocol, dest_host, dest_port, + username, password); + + g_object_unref (addr); + g_free (protocol); + g_free (dest_host); + g_free (username); + g_free (password); + + enumerator = + g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr)); + g_object_unref (sockaddr); + + printf ("Proxies for ip and port '%s' are:\n", info); + run_with_enumerator (synchronous, enumerator); + + g_object_unref (enumerator); +} + +static void +use_network_address (gboolean synchronous) +{ + GError *error = NULL; + GSocketAddressEnumerator *enumerator; + GSocketConnectable *connectable; + + connectable = g_network_address_parse (info, -1, &error); + + if (error) + { + print_and_free_error (error); + return; + } + + enumerator = g_socket_connectable_proxy_enumerate (connectable); + g_object_unref (connectable); + + printf ("Proxies for hostname and port '%s' are:\n", info); + run_with_enumerator (synchronous, enumerator); + + g_object_unref (enumerator); +} + +static void +use_network_uri (gboolean synchronous) +{ + GError *error = NULL; + GSocketAddressEnumerator *enumerator; + GSocketConnectable *connectable; + + connectable = g_network_address_parse_uri (info, 0, &error); + + if (error) + { + print_and_free_error (error); + return; + } + + enumerator = g_socket_connectable_proxy_enumerate (connectable); + g_object_unref (connectable); + + printf ("Proxies for URI '%s' are:\n", info); + run_with_enumerator (synchronous, enumerator); + + g_object_unref (enumerator); +} + +static void +use_network_service (gboolean synchronous) +{ + GSocketAddressEnumerator *enumerator; + GSocketConnectable *connectable = NULL; + gchar **split; + + split = g_strsplit (info, "/", 3); + + if (split[0] && split[1] && split[2]) + connectable = g_network_service_new (split[0], split[1], split[2]); + + g_strfreev (split); + + if (connectable == NULL) + { + fprintf (stderr, "Bad 'srv/protocol/domain' parameter '%s'\n", info); + return_value = 1; + return; + } + + enumerator = g_socket_connectable_proxy_enumerate (connectable); + g_object_unref (connectable); + + printf ("Proxies for hostname and port '%s' are:\n", info); + run_with_enumerator (synchronous, enumerator); + + g_object_unref (enumerator); +} + +static void +_socket_connect_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + GMainLoop *loop = user_data; + GSocketClient *client = G_SOCKET_CLIENT (object); + GSocketConnection *connection; + + connection = g_socket_client_connect_to_uri_finish (client, + result, + &error); + if (connection) + { + GSocketAddress *proxy_addr; + proxy_addr = g_socket_connection_get_remote_address (connection, NULL); + print_proxy_address (proxy_addr); + } + else + { + print_and_free_error (error); + } + + g_main_loop_quit (loop); +} + +static void +use_socket_client (gboolean synchronous) +{ + GError *error = NULL; + GSocketClient *client; + + client = g_socket_client_new (); + + printf ("Proxies for URI '%s' are:\n", info); + + if (synchronous) + { + GSocketConnection *connection; + GSocketAddress *proxy_addr; + + connection = g_socket_client_connect_to_uri (client, + info, + 0, + cancellable, + &error); + + if (connection) + { + proxy_addr = g_socket_connection_get_remote_address (connection, NULL); + print_proxy_address (proxy_addr); + } + else + { + print_and_free_error (error); + } + } + else + { + GMainLoop *loop = g_main_loop_new (NULL, FALSE); + + g_socket_client_connect_to_uri_async (client, + info, + 0, + cancellable, + _socket_connect_cb, + loop); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + } + + g_object_unref (client); +} + +typedef enum +{ + USE_RESOLVER, + USE_ENUMERATOR, +#ifdef G_OS_UNIX + USE_UNIX_SOCKET_ADDRESS, +#endif + USE_INET_SOCKET_ADDRESS, + USE_PROXY_ADDRESS, + USE_NETWORK_ADDRESS, + USE_NETWORK_URI, + USE_NETWORK_SERVICE, + USE_SOCKET_CLIENT, +} ProxyTestType; + +gint +main (gint argc, gchar **argv) +{ + gboolean synchronous = FALSE; + gboolean cancel = FALSE; + ProxyTestType type = USE_RESOLVER; + + while (argc >= 2 && argv[1][0] == '-') + { + if (!strcmp (argv[1], "-s")) + synchronous = TRUE; + else if (!strcmp (argv[1], "-c")) + cancel = TRUE; + else if (!strcmp (argv[1], "-e")) + type = USE_ENUMERATOR; + else if (!strcmp (argv[1], "-inet")) + type = USE_INET_SOCKET_ADDRESS; +#ifdef G_OS_UNIX + else if (!strcmp (argv[1], "-unix")) + type = USE_UNIX_SOCKET_ADDRESS; +#endif + else if (!strcmp (argv[1], "-proxyaddr")) + type = USE_PROXY_ADDRESS; + else if (!strcmp (argv[1], "-netaddr")) + type = USE_NETWORK_ADDRESS; + else if (!strcmp (argv[1], "-neturi")) + type = USE_NETWORK_URI; + else if (!strcmp (argv[1], "-netsrv")) + type = USE_NETWORK_SERVICE; + else if (!strcmp (argv[1], "-connect")) + type = USE_SOCKET_CLIENT; + else + usage (); + + argv++; + argc--; + } + + if (argc != 2) + usage (); + + /* Save URI for asynchronous callback */ + info = argv[1]; + + if (cancel) + { + cancellable = g_cancellable_new (); + g_cancellable_cancel (cancellable); + } + + switch (type) + { + case USE_RESOLVER: + use_resolver (synchronous); + break; + case USE_ENUMERATOR: + use_enumerator (synchronous); + break; + case USE_INET_SOCKET_ADDRESS: + use_inet_address (synchronous); + break; +#ifdef G_OS_UNIX + case USE_UNIX_SOCKET_ADDRESS: + use_unix_address (synchronous); + break; +#endif + case USE_PROXY_ADDRESS: + use_proxy_address (synchronous); + break; + case USE_NETWORK_ADDRESS: + use_network_address (synchronous); + break; + case USE_NETWORK_URI: + use_network_uri (synchronous); + break; + case USE_NETWORK_SERVICE: + use_network_service (synchronous); + break; + case USE_SOCKET_CLIENT: + use_socket_client (synchronous); + break; + } + + return return_value; +} diff --git a/gio/tests/readwrite.c b/gio/tests/readwrite.c new file mode 100644 index 0000000..7551e53 --- /dev/null +++ b/gio/tests/readwrite.c @@ -0,0 +1,313 @@ +#include +#include +#include +#include + +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include /* for close() */ +#endif + +static const char *original_data = "This is some test data that we can put in a file..."; +static const char *new_data = "new data.."; + +static void +verify_pos (GIOStream *iostream, goffset expected_pos) +{ + goffset pos; + + pos = g_seekable_tell (G_SEEKABLE (iostream)); + g_assert_cmpint (pos, ==, expected_pos); + + pos = g_seekable_tell (G_SEEKABLE (g_io_stream_get_input_stream (iostream))); + g_assert_cmpint (pos, ==, expected_pos); + + pos = g_seekable_tell (G_SEEKABLE (g_io_stream_get_output_stream (iostream))); + g_assert_cmpint (pos, ==, expected_pos); +} + +static void +verify_iostream (GFileIOStream *file_iostream) +{ + gboolean res; + gssize skipped; + GIOStream *iostream; + GError *error; + GInputStream *in; + GOutputStream *out; + char buffer[1024]; + gsize n_bytes; + char *modified_data; + + iostream = G_IO_STREAM (file_iostream); + + verify_pos (iostream, 0); + + in = g_io_stream_get_input_stream (iostream); + out = g_io_stream_get_output_stream (iostream); + + res = g_input_stream_read_all (in, buffer, 20, &n_bytes, NULL, NULL); + g_assert (res); + g_assert_cmpmem (buffer, n_bytes, original_data, 20); + + verify_pos (iostream, 20); + + res = g_seekable_seek (G_SEEKABLE (iostream), + -10, G_SEEK_END, + NULL, NULL); + g_assert (res); + verify_pos (iostream, strlen (original_data) - 10); + + res = g_input_stream_read_all (in, buffer, 20, &n_bytes, NULL, NULL); + g_assert (res); + g_assert_cmpmem (buffer, n_bytes, original_data + strlen (original_data) - 10, 10); + + verify_pos (iostream, strlen (original_data)); + + res = g_seekable_seek (G_SEEKABLE (iostream), + 10, G_SEEK_SET, + NULL, NULL); + + res = g_input_stream_skip (in, 5, NULL, NULL); + g_assert (res == 5); + verify_pos (iostream, 15); + + skipped = g_input_stream_skip (in, 10000, NULL, NULL); + g_assert_cmpint (skipped, >=, 0); + g_assert ((gsize) skipped == strlen (original_data) - 15); + verify_pos (iostream, strlen (original_data)); + + res = g_seekable_seek (G_SEEKABLE (iostream), + 10, G_SEEK_SET, + NULL, NULL); + + verify_pos (iostream, 10); + + res = g_output_stream_write_all (out, new_data, strlen (new_data), + &n_bytes, NULL, NULL); + g_assert (res); + g_assert_cmpint (n_bytes, ==, strlen (new_data)); + + verify_pos (iostream, 10 + strlen (new_data)); + + res = g_seekable_seek (G_SEEKABLE (iostream), + 0, G_SEEK_SET, + NULL, NULL); + g_assert (res); + verify_pos (iostream, 0); + + res = g_input_stream_read_all (in, buffer, strlen (original_data), &n_bytes, NULL, NULL); + g_assert (res); + g_assert_cmpint ((int)n_bytes, ==, strlen (original_data)); + buffer[n_bytes] = 0; + + modified_data = g_strdup (original_data); + memcpy (modified_data + 10, new_data, strlen (new_data)); + g_assert_cmpstr (buffer, ==, modified_data); + + verify_pos (iostream, strlen (original_data)); + + res = g_seekable_seek (G_SEEKABLE (iostream), + 0, G_SEEK_SET, + NULL, NULL); + g_assert (res); + verify_pos (iostream, 0); + + res = g_output_stream_close (out, NULL, NULL); + g_assert (res); + + res = g_input_stream_read_all (in, buffer, 15, &n_bytes, NULL, NULL); + g_assert (res); + g_assert_cmpmem (buffer, n_bytes, modified_data, 15); + + error = NULL; + res = g_output_stream_write_all (out, new_data, strlen (new_data), + &n_bytes, NULL, &error); + g_assert (!res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); + g_error_free (error); + + error = NULL; + res = g_io_stream_close (iostream, NULL, &error); + g_assert (res); + g_assert_no_error (error); + + g_free (modified_data); +} + +static void +test_g_file_open_readwrite (void) +{ + char *tmp_file; + int fd; + gboolean res; + GFileIOStream *file_iostream; + char *path; + GFile *file; + GError *error; + + fd = g_file_open_tmp ("readwrite_XXXXXX", + &tmp_file, NULL); + g_assert (fd != -1); + close (fd); + + res = g_file_set_contents (tmp_file, + original_data, -1, NULL); + g_assert (res); + + path = g_build_filename (g_get_tmp_dir (), "g-a-nonexisting-file", NULL); + file = g_file_new_for_path (path); + g_free (path); + error = NULL; + file_iostream = g_file_open_readwrite (file, NULL, &error); + g_assert (file_iostream == NULL); + g_assert (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)); + g_error_free (error); + g_object_unref (file); + + file = g_file_new_for_path (tmp_file); + error = NULL; + file_iostream = g_file_open_readwrite (file, NULL, &error); + g_assert (file_iostream != NULL); + g_object_unref (file); + + verify_iostream (file_iostream); + + g_object_unref (file_iostream); + + g_unlink (tmp_file); + g_free (tmp_file); +} + +static void +test_g_file_create_readwrite (void) +{ + char *tmp_file; + int fd; + gboolean res; + GFileIOStream *file_iostream; + GOutputStream *out; + GFile *file; + GError *error; + gsize n_bytes; + + fd = g_file_open_tmp ("readwrite_XXXXXX", + &tmp_file, NULL); + g_assert (fd != -1); + close (fd); + + file = g_file_new_for_path (tmp_file); + error = NULL; + file_iostream = g_file_create_readwrite (file, 0, NULL, &error); + g_assert (file_iostream == NULL); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS); + g_error_free (error); + + g_unlink (tmp_file); + file_iostream = g_file_create_readwrite (file, 0, NULL, &error); + g_assert (file_iostream != NULL); + + out = g_io_stream_get_output_stream (G_IO_STREAM (file_iostream)); + res = g_output_stream_write_all (out, original_data, strlen (original_data), + &n_bytes, NULL, NULL); + g_assert (res); + g_assert_cmpint (n_bytes, ==, strlen (original_data)); + + res = g_seekable_seek (G_SEEKABLE (file_iostream), + 0, G_SEEK_SET, + NULL, NULL); + g_assert (res); + + verify_iostream (file_iostream); + + g_object_unref (file_iostream); + g_object_unref (file); + + g_unlink (tmp_file); + g_free (tmp_file); +} + +static void +test_g_file_replace_readwrite (void) +{ + char *tmp_file, *backup, *data; + int fd; + gboolean res; + GFileIOStream *file_iostream; + GInputStream *in; + GOutputStream *out; + GFile *file; + GError *error; + char buffer[1024]; + gsize n_bytes; + + fd = g_file_open_tmp ("readwrite_XXXXXX", + &tmp_file, NULL); + g_assert (fd != -1); + close (fd); + + res = g_file_set_contents (tmp_file, + new_data, -1, NULL); + g_assert (res); + + file = g_file_new_for_path (tmp_file); + error = NULL; + file_iostream = g_file_replace_readwrite (file, NULL, + TRUE, 0, NULL, &error); + g_assert (file_iostream != NULL); + + in = g_io_stream_get_input_stream (G_IO_STREAM (file_iostream)); + + /* Ensure its empty */ + res = g_input_stream_read_all (in, buffer, sizeof buffer, &n_bytes, NULL, NULL); + g_assert (res); + g_assert_cmpint ((int)n_bytes, ==, 0); + + out = g_io_stream_get_output_stream (G_IO_STREAM (file_iostream)); + res = g_output_stream_write_all (out, original_data, strlen (original_data), + &n_bytes, NULL, NULL); + g_assert (res); + g_assert_cmpint (n_bytes, ==, strlen (original_data)); + + res = g_seekable_seek (G_SEEKABLE (file_iostream), + 0, G_SEEK_SET, + NULL, NULL); + g_assert (res); + + verify_iostream (file_iostream); + + g_object_unref (file_iostream); + g_object_unref (file); + + backup = g_strconcat (tmp_file, "~", NULL); + res = g_file_get_contents (backup, + &data, + NULL, NULL); + g_assert (res); + g_assert_cmpstr (data, ==, new_data); + g_free (data); + g_unlink (backup); + g_free (backup); + + g_unlink (tmp_file); + g_free (tmp_file); +} + + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/readwrite/test_g_file_open_readwrite", + test_g_file_open_readwrite); + g_test_add_func ("/readwrite/test_g_file_create_readwrite", + test_g_file_create_readwrite); + g_test_add_func ("/readwrite/test_g_file_replace_readwrite", + test_g_file_replace_readwrite); + + return g_test_run(); +} diff --git a/gio/tests/resolver-parsing.c b/gio/tests/resolver-parsing.c new file mode 100644 index 0000000..d9cf052 --- /dev/null +++ b/gio/tests/resolver-parsing.c @@ -0,0 +1,879 @@ +/* + * Copyright (c) 2021 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Patrick Griffis + */ + +#include "config.h" + +#include +#include + +#define GIO_COMPILATION +#include "gthreadedresolver.h" +#undef GIO_COMPILATION + +#ifdef HAVE_DN_COMP +static void +dns_builder_add_uint8 (GByteArray *builder, + guint8 value) +{ + g_byte_array_append (builder, &value, 1); +} + +static void +dns_builder_add_uint16 (GByteArray *builder, + guint16 value) +{ + dns_builder_add_uint8 (builder, (value >> 8) & 0xFF); + dns_builder_add_uint8 (builder, (value) & 0xFF); +} + +static void +dns_builder_add_uint32 (GByteArray *builder, + guint32 value) +{ + dns_builder_add_uint8 (builder, (value >> 24) & 0xFF); + dns_builder_add_uint8 (builder, (value >> 16) & 0xFF); + dns_builder_add_uint8 (builder, (value >> 8) & 0xFF); + dns_builder_add_uint8 (builder, (value) & 0xFF); +} + +static void +dns_builder_add_length_prefixed_string (GByteArray *builder, + const char *string) +{ + guint8 length; + + g_assert (strlen (string) <= G_MAXUINT8); + + length = (guint8) strlen (string); + dns_builder_add_uint8 (builder, length); + + /* Don't include trailing NUL */ + g_byte_array_append (builder, (const guchar *)string, length); +} + +static void +dns_builder_add_domain (GByteArray *builder, + const char *string) +{ + int ret; + guchar buffer[256]; + + ret = dn_comp (string, buffer, sizeof (buffer), NULL, NULL); + g_assert (ret != -1); + + g_byte_array_append (builder, buffer, ret); +} + +/* Append an invalid domain name to the DNS response. This is implemented by + * appending a single label followed by a pointer back to that label. This is + * invalid regardless of any other context in the response as its expansion is + * infinite. + * + * See https://datatracker.ietf.org/doc/html/rfc1035#section-4.1.4 + * + * In order to create a pointer to the label, the label’s final offset in the + * DNS response must be known. The current length of @builder, plus @offset, is + * used for this. Hence, @offset is the additional offset (in bytes) to add, and + * typically corresponds to the length of the parent #GByteArray that @builder + * will eventually be added to. Potentially plus 2 bytes for the rdlength, as + * per dns_builder_add_answer_data(). */ +static void +dns_builder_add_invalid_domain (GByteArray *builder, + gsize offset) +{ + offset += builder->len; + g_assert ((offset & 0xc0) == 0); + + dns_builder_add_uint8 (builder, 1); + dns_builder_add_uint8 (builder, 'f'); + dns_builder_add_uint8 (builder, 0xc0 | offset); +} + +static void +dns_builder_add_answer_data (GByteArray *builder, + GByteArray *answer) +{ + dns_builder_add_uint16 (builder, answer->len); /* rdlength */ + g_byte_array_append (builder, answer->data, answer->len); +} + +static GByteArray * +dns_header (void) +{ + GByteArray *answer = g_byte_array_sized_new (2046); + + /* Start with a header, we ignore everything except ancount. + https://datatracker.ietf.org/doc/html/rfc1035#section-4.1.1 */ + dns_builder_add_uint16 (answer, 0); /* ID */ + dns_builder_add_uint16 (answer, 0); /* |QR| Opcode |AA|TC|RD|RA| Z | RCODE | */ + dns_builder_add_uint16 (answer, 0); /* QDCOUNT */ + dns_builder_add_uint16 (answer, 1); /* ANCOUNT (1 answer) */ + dns_builder_add_uint16 (answer, 0); /* NSCOUNT */ + dns_builder_add_uint16 (answer, 0); /* ARCOUNT */ + + return g_steal_pointer (&answer); +} + +static void +assert_query_fails (const gchar *rrname, + GResolverRecordType record_type, + GByteArray *answer) +{ + GList *records = NULL; + GError *local_error = NULL; + + records = g_resolver_records_from_res_query (rrname, + g_resolver_record_type_to_rrtype (record_type), + answer->data, + answer->len, + 0, + &local_error); + + g_assert_error (local_error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL); + g_assert_null (records); + g_clear_error (&local_error); +} + +static void +assert_query_succeeds (const gchar *rrname, + GResolverRecordType record_type, + GByteArray *answer, + const gchar *expected_answer_variant_str) +{ + GList *records = NULL; + GVariant *answer_variant, *expected_answer_variant = NULL; + GError *local_error = NULL; + + records = g_resolver_records_from_res_query (rrname, + g_resolver_record_type_to_rrtype (record_type), + answer->data, + answer->len, + 0, + &local_error); + + g_assert_no_error (local_error); + g_assert_nonnull (records); + + /* Test the results. */ + answer_variant = records->data; + expected_answer_variant = g_variant_new_parsed (expected_answer_variant_str); + g_assert_cmpvariant (answer_variant, expected_answer_variant); + + g_variant_unref (expected_answer_variant); + g_list_free_full (records, (GDestroyNotify) g_variant_unref); +} +#endif /* HAVE_DN_COMP */ + +static void +test_invalid_header (void) +{ + const struct + { + const guint8 *answer; + gsize answer_len; + GResolverError expected_error_code; + } + vectors[] = + { + /* No answer: */ + { (const guint8 *) "", 0, G_RESOLVER_ERROR_NOT_FOUND }, + /* Definitely too short to be a valid header: */ + { (const guint8 *) "\x20", 1, G_RESOLVER_ERROR_INTERNAL }, + /* One byte too short to be a valid header: */ + { (const guint8 *) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 11, G_RESOLVER_ERROR_INTERNAL }, + /* Valid header indicating no answers: */ + { (const guint8 *) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, G_RESOLVER_ERROR_NOT_FOUND }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + GList *records = NULL; + GError *local_error = NULL; + + records = g_resolver_records_from_res_query ("example.org", + g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_NS), + vectors[i].answer, + vectors[i].answer_len, + 0, + &local_error); + + g_assert_error (local_error, G_RESOLVER_ERROR, (gint) vectors[i].expected_error_code); + g_assert_null (records); + g_clear_error (&local_error); + } +} + +static void +test_unknown_record_type (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL; + GList *records = NULL; + GError *local_error = NULL; + const guint type_id = 20; /* ISDN, not supported anywhere */ + + /* An answer with an unsupported type chosen from + * https://en.wikipedia.org/wiki/List_of_DNS_record_types#[1]_Obsolete_record_types */ + answer = dns_header (); + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, type_id); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + dns_builder_add_uint16 (answer, 0); /* rdlength */ + + records = g_resolver_records_from_res_query ("example.org", + type_id, + answer->data, + answer->len, + 0, + &local_error); + + g_assert_error (local_error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND); + g_assert_null (records); + g_clear_error (&local_error); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_mx_valid (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *mx_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_MX)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* MX rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.9 */ + mx_rdata = g_byte_array_new (); + dns_builder_add_uint16 (mx_rdata, 0); /* preference */ + dns_builder_add_domain (mx_rdata, "mail.example.org"); + dns_builder_add_answer_data (answer, mx_rdata); + g_byte_array_unref (mx_rdata); + + assert_query_succeeds ("example.org", G_RESOLVER_RECORD_MX, answer, + "(@q 0, 'mail.example.org')"); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_mx_invalid (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *mx_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_MX)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* MX rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.9 + * + * Use an invalid domain to trigger parsing failure. */ + mx_rdata = g_byte_array_new (); + dns_builder_add_uint16 (mx_rdata, 0); /* preference */ + dns_builder_add_invalid_domain (mx_rdata, answer->len + 2); + dns_builder_add_answer_data (answer, mx_rdata); + g_byte_array_unref (mx_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_MX, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_mx_invalid_too_short (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *mx_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_MX)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* MX rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.9 + * + * Miss out the domain field to trigger failure */ + mx_rdata = g_byte_array_new (); + dns_builder_add_uint16 (mx_rdata, 0); /* preference */ + /* missing domain field */ + dns_builder_add_answer_data (answer, mx_rdata); + g_byte_array_unref (mx_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_MX, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_mx_invalid_too_short2 (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *mx_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_MX)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* MX rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.9 + * + * Miss out all fields to trigger failure */ + mx_rdata = g_byte_array_new (); + /* missing preference and domain fields */ + dns_builder_add_answer_data (answer, mx_rdata); + g_byte_array_unref (mx_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_MX, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_ns_valid (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *ns_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_NS)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* NS rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.11 */ + ns_rdata = g_byte_array_new (); + dns_builder_add_domain (ns_rdata, "ns.example.org"); + dns_builder_add_answer_data (answer, ns_rdata); + g_byte_array_unref (ns_rdata); + + assert_query_succeeds ("example.org", G_RESOLVER_RECORD_NS, answer, + "('ns.example.org',)"); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_ns_invalid (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *ns_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_NS)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* NS rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.11 + * + * Use an invalid domain to trigger parsing failure. */ + ns_rdata = g_byte_array_new (); + dns_builder_add_invalid_domain (ns_rdata, answer->len + 2); + dns_builder_add_answer_data (answer, ns_rdata); + g_byte_array_unref (ns_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_NS, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_soa_valid (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *soa_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_SOA)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* SOA rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.13 */ + soa_rdata = g_byte_array_new (); + dns_builder_add_domain (soa_rdata, "mname.example.org"); + dns_builder_add_domain (soa_rdata, "rname.example.org"); + dns_builder_add_uint32 (soa_rdata, 0); /* serial */ + dns_builder_add_uint32 (soa_rdata, 0); /* refresh */ + dns_builder_add_uint32 (soa_rdata, 0); /* retry */ + dns_builder_add_uint32 (soa_rdata, 0); /* expire */ + dns_builder_add_uint32 (soa_rdata, 0); /* minimum */ + dns_builder_add_answer_data (answer, soa_rdata); + g_byte_array_unref (soa_rdata); + + assert_query_succeeds ("example.org", G_RESOLVER_RECORD_SOA, answer, + "('mname.example.org', 'rname.example.org', @u 0, @u 0, @u 0, @u 0, @u 0)"); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_soa_invalid_mname (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *soa_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_SOA)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* SOA rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.13 + * + * Use an invalid domain to trigger parsing failure. */ + soa_rdata = g_byte_array_new (); + dns_builder_add_invalid_domain (soa_rdata, answer->len + 2); /* mname */ + dns_builder_add_domain (soa_rdata, "rname.example.org"); + dns_builder_add_uint32 (soa_rdata, 0); /* serial */ + dns_builder_add_uint32 (soa_rdata, 0); /* refresh */ + dns_builder_add_uint32 (soa_rdata, 0); /* retry */ + dns_builder_add_uint32 (soa_rdata, 0); /* expire */ + dns_builder_add_uint32 (soa_rdata, 0); /* minimum */ + dns_builder_add_answer_data (answer, soa_rdata); + g_byte_array_unref (soa_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_SOA, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_soa_invalid_rname (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *soa_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_SOA)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* SOA rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.13 + * + * Use an invalid domain to trigger parsing failure. */ + soa_rdata = g_byte_array_new (); + dns_builder_add_domain (soa_rdata, "mname.example.org"); + dns_builder_add_invalid_domain (soa_rdata, answer->len + 2); /* rname */ + dns_builder_add_uint32 (soa_rdata, 0); /* serial */ + dns_builder_add_uint32 (soa_rdata, 0); /* refresh */ + dns_builder_add_uint32 (soa_rdata, 0); /* retry */ + dns_builder_add_uint32 (soa_rdata, 0); /* expire */ + dns_builder_add_uint32 (soa_rdata, 0); /* minimum */ + dns_builder_add_answer_data (answer, soa_rdata); + g_byte_array_unref (soa_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_SOA, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_soa_invalid_too_short (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *soa_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_SOA)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* SOA rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.13 + * + * Miss out one of the fields to trigger a failure. */ + soa_rdata = g_byte_array_new (); + dns_builder_add_domain (soa_rdata, "mname.example.org"); + dns_builder_add_domain (soa_rdata, "rname.example.org"); + dns_builder_add_uint32 (soa_rdata, 0); /* serial */ + dns_builder_add_uint32 (soa_rdata, 0); /* refresh */ + dns_builder_add_uint32 (soa_rdata, 0); /* retry */ + dns_builder_add_uint32 (soa_rdata, 0); /* expire */ + /* missing minimum field */ + dns_builder_add_answer_data (answer, soa_rdata); + g_byte_array_unref (soa_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_SOA, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_txt_valid (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *txt_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_TXT)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* TXT rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.14 */ + txt_rdata = g_byte_array_new (); + dns_builder_add_length_prefixed_string (txt_rdata, "some test content"); + dns_builder_add_answer_data (answer, txt_rdata); + g_byte_array_unref (txt_rdata); + + assert_query_succeeds ("example.org", G_RESOLVER_RECORD_TXT, answer, + "(['some test content'],)"); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_txt_valid_multiple_strings (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *txt_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_TXT)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* TXT rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.14 */ + txt_rdata = g_byte_array_new (); + dns_builder_add_length_prefixed_string (txt_rdata, "some test content"); + dns_builder_add_length_prefixed_string (txt_rdata, "more test content"); + dns_builder_add_answer_data (answer, txt_rdata); + g_byte_array_unref (txt_rdata); + + assert_query_succeeds ("example.org", G_RESOLVER_RECORD_TXT, answer, + "(['some test content', 'more test content'],)"); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_txt_invalid_empty (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *txt_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_TXT)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* TXT rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.14 + * + * Provide zero character strings (i.e. an empty rdata section) to trigger + * failure. */ + txt_rdata = g_byte_array_new (); + dns_builder_add_answer_data (answer, txt_rdata); + g_byte_array_unref (txt_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_TXT, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_txt_invalid_overflow (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *txt_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_TXT)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* TXT rdata, https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.14 + * + * Use a character string whose length exceeds the remaining length in the + * answer record, to trigger failure. */ + txt_rdata = g_byte_array_new (); + dns_builder_add_uint8 (txt_rdata, 10); /* length, but no content */ + dns_builder_add_answer_data (answer, txt_rdata); + g_byte_array_unref (txt_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_TXT, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_srv_valid (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *srv_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_SRV)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* SRV rdata, https://datatracker.ietf.org/doc/html/rfc2782 */ + srv_rdata = g_byte_array_new (); + dns_builder_add_uint16 (srv_rdata, 0); /* priority */ + dns_builder_add_uint16 (srv_rdata, 0); /* weight */ + dns_builder_add_uint16 (srv_rdata, 0); /* port */ + dns_builder_add_domain (srv_rdata, "target.example.org"); + dns_builder_add_answer_data (answer, srv_rdata); + g_byte_array_unref (srv_rdata); + + assert_query_succeeds ("example.org", G_RESOLVER_RECORD_SRV, answer, + "(@q 0, @q 0, @q 0, 'target.example.org')"); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_srv_invalid (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *srv_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_SRV)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* SRV rdata, https://datatracker.ietf.org/doc/html/rfc2782 + * + * Use an invalid domain to trigger parsing failure. */ + srv_rdata = g_byte_array_new (); + dns_builder_add_uint16 (srv_rdata, 0); /* priority */ + dns_builder_add_uint16 (srv_rdata, 0); /* weight */ + dns_builder_add_uint16 (srv_rdata, 0); /* port */ + dns_builder_add_invalid_domain (srv_rdata, answer->len + 2); + dns_builder_add_answer_data (answer, srv_rdata); + g_byte_array_unref (srv_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_SRV, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_srv_invalid_too_short (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *srv_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_SRV)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* SRV rdata, https://datatracker.ietf.org/doc/html/rfc2782 + * + * Miss out the target field to trigger failure */ + srv_rdata = g_byte_array_new (); + dns_builder_add_uint16 (srv_rdata, 0); /* priority */ + dns_builder_add_uint16 (srv_rdata, 0); /* weight */ + dns_builder_add_uint16 (srv_rdata, 0); /* port */ + /* missing target field */ + dns_builder_add_answer_data (answer, srv_rdata); + g_byte_array_unref (srv_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_SRV, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +static void +test_srv_invalid_too_short2 (void) +{ +#ifndef HAVE_DN_COMP + g_test_skip ("The dn_comp() function was not available."); + return; +#else + GByteArray *answer = NULL, *srv_rdata = NULL; + + answer = dns_header (); + + /* Resource record */ + dns_builder_add_domain (answer, "example.org"); + dns_builder_add_uint16 (answer, g_resolver_record_type_to_rrtype (G_RESOLVER_RECORD_SRV)); + dns_builder_add_uint16 (answer, 1); /* qclass=C_IN */ + dns_builder_add_uint32 (answer, 0); /* ttl (ignored) */ + + /* SRV rdata, https://datatracker.ietf.org/doc/html/rfc2782 + * + * Miss out the target and port fields to trigger failure */ + srv_rdata = g_byte_array_new (); + dns_builder_add_uint16 (srv_rdata, 0); /* priority */ + dns_builder_add_uint16 (srv_rdata, 0); /* weight */ + /* missing port and target fields */ + dns_builder_add_answer_data (answer, srv_rdata); + g_byte_array_unref (srv_rdata); + + assert_query_fails ("example.org", G_RESOLVER_RECORD_SRV, answer); + + g_byte_array_free (answer, TRUE); +#endif +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + + g_test_add_func ("/gresolver/invalid-header", test_invalid_header); + g_test_add_func ("/gresolver/unknown-record-type", test_unknown_record_type); + g_test_add_func ("/gresolver/mx/valid", test_mx_valid); + g_test_add_func ("/gresolver/mx/invalid", test_mx_invalid); + g_test_add_func ("/gresolver/mx/invalid/too-short", test_mx_invalid_too_short); + g_test_add_func ("/gresolver/mx/invalid/too-short2", test_mx_invalid_too_short2); + g_test_add_func ("/gresolver/ns/valid", test_ns_valid); + g_test_add_func ("/gresolver/ns/invalid", test_ns_invalid); + g_test_add_func ("/gresolver/soa/valid", test_soa_valid); + g_test_add_func ("/gresolver/soa/invalid/mname", test_soa_invalid_mname); + g_test_add_func ("/gresolver/soa/invalid/rname", test_soa_invalid_rname); + g_test_add_func ("/gresolver/soa/invalid/too-short", test_soa_invalid_too_short); + g_test_add_func ("/gresolver/srv/valid", test_srv_valid); + g_test_add_func ("/gresolver/srv/invalid", test_srv_invalid); + g_test_add_func ("/gresolver/srv/invalid/too-short", test_srv_invalid_too_short); + g_test_add_func ("/gresolver/srv/invalid/too-short2", test_srv_invalid_too_short2); + g_test_add_func ("/gresolver/txt/valid", test_txt_valid); + g_test_add_func ("/gresolver/txt/valid/multiple-strings", test_txt_valid_multiple_strings); + g_test_add_func ("/gresolver/txt/invalid/empty", test_txt_invalid_empty); + g_test_add_func ("/gresolver/txt/invalid/overflow", test_txt_invalid_overflow); + + return g_test_run (); +} diff --git a/gio/tests/resolver.c b/gio/tests/resolver.c new file mode 100644 index 0000000..d62a4fd --- /dev/null +++ b/gio/tests/resolver.c @@ -0,0 +1,794 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" +#include +#include "glibintl.h" + +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#endif + +#include + +static GResolver *resolver; +static GCancellable *cancellable; +static GMainLoop *loop; +static int nlookups = 0; +static gboolean synchronous = FALSE; +static guint connectable_count = 0; +static GResolverRecordType record_type = 0; + +static G_NORETURN void +usage (void) +{ + fprintf (stderr, "Usage: resolver [-s] [hostname | IP | service/protocol/domain ] ...\n"); + fprintf (stderr, "Usage: resolver [-s] [-t MX|TXT|NS|SOA|SRV] rrname ...\n"); + fprintf (stderr, " resolver [-s] -c NUMBER [hostname | IP | service/protocol/domain ]\n"); + fprintf (stderr, " Use -s to do synchronous lookups.\n"); + fprintf (stderr, " Use -c NUMBER (and only a single resolvable argument) to test GSocketConnectable.\n"); + fprintf (stderr, " The given NUMBER determines how many times the connectable will be enumerated.\n"); + fprintf (stderr, " Use -t with MX, TXT, NS, SOA or SRV to look up DNS records of those types.\n"); + exit (1); +} + +G_LOCK_DEFINE_STATIC (response); + +static void +done_lookup (void) +{ + nlookups--; + if (nlookups == 0) + { + /* In the sync case we need to make sure we don't call + * g_main_loop_quit before the loop is actually running... + */ + g_idle_add ((GSourceFunc)g_main_loop_quit, loop); + } +} + +static void +print_resolved_name (const char *phys, + char *name, + GError *error) +{ + G_LOCK (response); + printf ("Address: %s\n", phys); + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else + { + printf ("Name: %s\n", name); + g_free (name); + } + printf ("\n"); + + done_lookup (); + G_UNLOCK (response); +} + +static void +print_resolved_addresses (const char *name, + GList *addresses, + GError *error) +{ + char *phys; + GList *a; + + G_LOCK (response); + printf ("Name: %s\n", name); + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else + { + for (a = addresses; a; a = a->next) + { + phys = g_inet_address_to_string (a->data); + printf ("Address: %s\n", phys); + g_free (phys); + g_object_unref (a->data); + } + g_list_free (addresses); + } + printf ("\n"); + + done_lookup (); + G_UNLOCK (response); +} + +static void +print_resolved_service (const char *service, + GList *targets, + GError *error) +{ + GList *t; + + G_LOCK (response); + printf ("Service: %s\n", service); + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else + { + for (t = targets; t; t = t->next) + { + printf ("%s:%u (pri %u, weight %u)\n", + g_srv_target_get_hostname (t->data), + (guint)g_srv_target_get_port (t->data), + (guint)g_srv_target_get_priority (t->data), + (guint)g_srv_target_get_weight (t->data)); + g_srv_target_free (t->data); + } + g_list_free (targets); + } + printf ("\n"); + + done_lookup (); + G_UNLOCK (response); +} + +static void +print_resolved_mx (const char *rrname, + GList *records, + GError *error) +{ + const gchar *hostname; + guint16 priority; + GList *t; + + G_LOCK (response); + printf ("Domain: %s\n", rrname); + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else if (!records) + { + printf ("no MX records\n"); + } + else + { + for (t = records; t; t = t->next) + { + g_variant_get (t->data, "(q&s)", &priority, &hostname); + printf ("%s (pri %u)\n", hostname, (guint)priority); + g_variant_unref (t->data); + } + g_list_free (records); + } + printf ("\n"); + + done_lookup (); + G_UNLOCK (response); +} + +static void +print_resolved_txt (const char *rrname, + GList *records, + GError *error) +{ + const gchar **contents; + GList *t; + gint i; + + G_LOCK (response); + printf ("Domain: %s\n", rrname); + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else if (!records) + { + printf ("no TXT records\n"); + } + else + { + for (t = records; t; t = t->next) + { + if (t != records) + printf ("\n"); + g_variant_get (t->data, "(^a&s)", &contents); + for (i = 0; contents[i] != NULL; i++) + printf ("%s\n", contents[i]); + g_variant_unref (t->data); + g_free (contents); + } + g_list_free (records); + } + printf ("\n"); + + done_lookup (); + G_UNLOCK (response); +} + +static void +print_resolved_srv (const char *rrname, + GList *records, + GError *error) +{ + G_LOCK (response); + printf ("Domain: %s\n", rrname); + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else if (!records) + { + printf ("no SRV records\n"); + } + else + { + GList *t; + + for (t = records; t != NULL; t = t->next) + { + guint16 priority, weight, port; + const gchar *target; + + g_variant_get (t->data, "(qqq&s)", &priority, &weight, &port, &target); + + printf ("%s (priority %u, weight %u, port %u)\n", + target, (guint) priority, (guint) weight, (guint) port); + g_variant_unref (t->data); + } + + g_list_free (records); + } + printf ("\n"); + + done_lookup (); + G_UNLOCK (response); +} + +static void +print_resolved_soa (const char *rrname, + GList *records, + GError *error) +{ + GList *t; + const gchar *primary_ns; + const gchar *administrator; + guint32 serial, refresh, retry, expire, ttl; + + G_LOCK (response); + printf ("Zone: %s\n", rrname); + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else if (!records) + { + printf ("no SOA records\n"); + } + else + { + for (t = records; t; t = t->next) + { + g_variant_get (t->data, "(&s&suuuuu)", &primary_ns, &administrator, + &serial, &refresh, &retry, &expire, &ttl); + printf ("%s %s (serial %u, refresh %u, retry %u, expire %u, ttl %u)\n", + primary_ns, administrator, (guint)serial, (guint)refresh, + (guint)retry, (guint)expire, (guint)ttl); + g_variant_unref (t->data); + } + g_list_free (records); + } + printf ("\n"); + + done_lookup (); + G_UNLOCK (response); +} + +static void +print_resolved_ns (const char *rrname, + GList *records, + GError *error) +{ + GList *t; + const gchar *hostname; + + G_LOCK (response); + printf ("Zone: %s\n", rrname); + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else if (!records) + { + printf ("no NS records\n"); + } + else + { + for (t = records; t; t = t->next) + { + g_variant_get (t->data, "(&s)", &hostname); + printf ("%s\n", hostname); + g_variant_unref (t->data); + } + g_list_free (records); + } + printf ("\n"); + + done_lookup (); + G_UNLOCK (response); +} + +static void +lookup_one_sync (const char *arg) +{ + GError *error = NULL; + + if (record_type != 0) + { + GList *records; + + records = g_resolver_lookup_records (resolver, arg, record_type, cancellable, &error); + switch (record_type) + { + case G_RESOLVER_RECORD_MX: + print_resolved_mx (arg, records, error); + break; + case G_RESOLVER_RECORD_SOA: + print_resolved_soa (arg, records, error); + break; + case G_RESOLVER_RECORD_NS: + print_resolved_ns (arg, records, error); + break; + case G_RESOLVER_RECORD_TXT: + print_resolved_txt (arg, records, error); + break; + case G_RESOLVER_RECORD_SRV: + print_resolved_srv (arg, records, error); + break; + default: + g_warn_if_reached (); + break; + } + } + else if (strchr (arg, '/')) + { + GList *targets; + /* service/protocol/domain */ + char **parts = g_strsplit (arg, "/", 3); + + if (!parts || !parts[2]) + usage (); + + targets = g_resolver_lookup_service (resolver, + parts[0], parts[1], parts[2], + cancellable, &error); + print_resolved_service (arg, targets, error); + } + else if (g_hostname_is_ip_address (arg)) + { + GInetAddress *addr = g_inet_address_new_from_string (arg); + char *name; + + name = g_resolver_lookup_by_address (resolver, addr, cancellable, &error); + print_resolved_name (arg, name, error); + g_object_unref (addr); + } + else + { + GList *addresses; + + addresses = g_resolver_lookup_by_name (resolver, arg, cancellable, &error); + print_resolved_addresses (arg, addresses, error); + } +} + +static gpointer +lookup_thread (gpointer arg) +{ + lookup_one_sync (arg); + return NULL; +} + +static void +start_sync_lookups (char **argv, int argc) +{ + int i; + + for (i = 0; i < argc; i++) + { + GThread *thread; + thread = g_thread_new ("lookup", lookup_thread, argv[i]); + g_thread_unref (thread); + } +} + +static void +lookup_by_addr_callback (GObject *source, GAsyncResult *result, + gpointer user_data) +{ + const char *phys = user_data; + GError *error = NULL; + char *name; + + name = g_resolver_lookup_by_address_finish (resolver, result, &error); + print_resolved_name (phys, name, error); +} + +static void +lookup_by_name_callback (GObject *source, GAsyncResult *result, + gpointer user_data) +{ + const char *name = user_data; + GError *error = NULL; + GList *addresses; + + addresses = g_resolver_lookup_by_name_finish (resolver, result, &error); + print_resolved_addresses (name, addresses, error); +} + +static void +lookup_service_callback (GObject *source, GAsyncResult *result, + gpointer user_data) +{ + const char *service = user_data; + GError *error = NULL; + GList *targets; + + targets = g_resolver_lookup_service_finish (resolver, result, &error); + print_resolved_service (service, targets, error); +} + +static void +lookup_records_callback (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + const char *arg = user_data; + GError *error = NULL; + GList *records; + + records = g_resolver_lookup_records_finish (resolver, result, &error); + + switch (record_type) + { + case G_RESOLVER_RECORD_MX: + print_resolved_mx (arg, records, error); + break; + case G_RESOLVER_RECORD_SOA: + print_resolved_soa (arg, records, error); + break; + case G_RESOLVER_RECORD_NS: + print_resolved_ns (arg, records, error); + break; + case G_RESOLVER_RECORD_TXT: + print_resolved_txt (arg, records, error); + break; + case G_RESOLVER_RECORD_SRV: + print_resolved_srv (arg, records, error); + break; + default: + g_warn_if_reached (); + break; + } +} + +static void +start_async_lookups (char **argv, int argc) +{ + int i; + + for (i = 0; i < argc; i++) + { + if (record_type != 0) + { + g_resolver_lookup_records_async (resolver, argv[i], record_type, + cancellable, lookup_records_callback, argv[i]); + } + else if (strchr (argv[i], '/')) + { + /* service/protocol/domain */ + char **parts = g_strsplit (argv[i], "/", 3); + + if (!parts || !parts[2]) + usage (); + + g_resolver_lookup_service_async (resolver, + parts[0], parts[1], parts[2], + cancellable, + lookup_service_callback, argv[i]); + } + else if (g_hostname_is_ip_address (argv[i])) + { + GInetAddress *addr = g_inet_address_new_from_string (argv[i]); + + g_resolver_lookup_by_address_async (resolver, addr, cancellable, + lookup_by_addr_callback, argv[i]); + g_object_unref (addr); + } + else + { + g_resolver_lookup_by_name_async (resolver, argv[i], cancellable, + lookup_by_name_callback, + argv[i]); + } + + /* Stress-test the reloading code */ + g_signal_emit_by_name (resolver, "reload"); + } +} + +static void +print_connectable_sockaddr (GSocketAddress *sockaddr, + GError *error) +{ + char *phys; + + if (error) + { + printf ("Error: %s\n", error->message); + g_error_free (error); + } + else if (!G_IS_INET_SOCKET_ADDRESS (sockaddr)) + { + printf ("Error: Unexpected sockaddr type '%s'\n", g_type_name_from_instance ((GTypeInstance *)sockaddr)); + g_object_unref (sockaddr); + } + else + { + GInetSocketAddress *isa = G_INET_SOCKET_ADDRESS (sockaddr); + phys = g_inet_address_to_string (g_inet_socket_address_get_address (isa)); + printf ("Address: %s%s%s:%d\n", + strchr (phys, ':') ? "[" : "", phys, strchr (phys, ':') ? "]" : "", + g_inet_socket_address_get_port (isa)); + g_free (phys); + g_object_unref (sockaddr); + } +} + +static void +do_sync_connectable (GSocketAddressEnumerator *enumerator) +{ + GSocketAddress *sockaddr; + GError *error = NULL; + + while ((sockaddr = g_socket_address_enumerator_next (enumerator, cancellable, &error))) + print_connectable_sockaddr (sockaddr, error); + + g_object_unref (enumerator); + done_lookup (); +} + +static void do_async_connectable (GSocketAddressEnumerator *enumerator); + +static void +got_next_async (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (source); + GSocketAddress *sockaddr; + GError *error = NULL; + + sockaddr = g_socket_address_enumerator_next_finish (enumerator, result, &error); + if (sockaddr || error) + print_connectable_sockaddr (sockaddr, error); + if (sockaddr) + do_async_connectable (enumerator); + else + { + g_object_unref (enumerator); + done_lookup (); + } +} + +static void +do_async_connectable (GSocketAddressEnumerator *enumerator) +{ + g_socket_address_enumerator_next_async (enumerator, cancellable, + got_next_async, NULL); +} + +static void +do_connectable (const char *arg, gboolean synchronous, guint count) +{ + char **parts; + GSocketConnectable *connectable; + GSocketAddressEnumerator *enumerator; + + if (strchr (arg, '/')) + { + /* service/protocol/domain */ + parts = g_strsplit (arg, "/", 3); + if (!parts || !parts[2]) + usage (); + + connectable = g_network_service_new (parts[0], parts[1], parts[2]); + } + else + { + guint16 port; + + parts = g_strsplit (arg, ":", 2); + if (parts && parts[1]) + { + arg = parts[0]; + port = strtoul (parts[1], NULL, 10); + } + else + port = 0; + + if (g_hostname_is_ip_address (arg)) + { + GInetAddress *addr = g_inet_address_new_from_string (arg); + GSocketAddress *sockaddr = g_inet_socket_address_new (addr, port); + + g_object_unref (addr); + connectable = G_SOCKET_CONNECTABLE (sockaddr); + } + else + connectable = g_network_address_new (arg, port); + } + + while (count--) + { + enumerator = g_socket_connectable_enumerate (connectable); + + if (synchronous) + do_sync_connectable (enumerator); + else + do_async_connectable (enumerator); + } + + g_object_unref (connectable); +} + +#ifdef G_OS_UNIX +static int cancel_fds[2]; + +static void +interrupted (int sig) +{ + gssize c; + + signal (SIGINT, SIG_DFL); + c = write (cancel_fds[1], "x", 1); + g_assert_cmpint(c, ==, 1); +} + +static gboolean +async_cancel (GIOChannel *source, GIOCondition cond, gpointer cancel) +{ + g_cancellable_cancel (cancel); + return FALSE; +} +#endif + + +static gboolean +record_type_arg (const gchar *option_name, + const gchar *value, + gpointer data, + GError **error) +{ + if (g_ascii_strcasecmp (value, "MX") == 0) { + record_type = G_RESOLVER_RECORD_MX; + } else if (g_ascii_strcasecmp (value, "TXT") == 0) { + record_type = G_RESOLVER_RECORD_TXT; + } else if (g_ascii_strcasecmp (value, "SOA") == 0) { + record_type = G_RESOLVER_RECORD_SOA; + } else if (g_ascii_strcasecmp (value, "NS") == 0) { + record_type = G_RESOLVER_RECORD_NS; + } else if (g_ascii_strcasecmp (value, "SRV") == 0) { + record_type = G_RESOLVER_RECORD_SRV; + } else { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Specify MX, TXT, NS, SOA or SRV for the special record lookup types"); + return FALSE; + } + + return TRUE; +} + +static const GOptionEntry option_entries[] = { + { "synchronous", 's', 0, G_OPTION_ARG_NONE, &synchronous, "Synchronous connections", NULL }, + { "connectable", 'c', 0, G_OPTION_ARG_INT, &connectable_count, "Connectable count", "C" }, + { "special-type", 't', 0, G_OPTION_ARG_CALLBACK, record_type_arg, "Record type like MX, TXT, NS or SOA", "RR" }, + G_OPTION_ENTRY_NULL, +}; + +int +main (int argc, char **argv) +{ + GOptionContext *context; + GError *error = NULL; +#ifdef G_OS_UNIX + GIOChannel *chan; + guint watch; +#endif + + context = g_option_context_new ("lookups ..."); + g_option_context_add_main_entries (context, option_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + usage(); + } + + if (argc < 2 || (argc > 2 && connectable_count)) + usage (); + + resolver = g_resolver_get_default (); + + cancellable = g_cancellable_new (); + +#ifdef G_OS_UNIX + /* Set up cancellation; we want to cancel if the user ^C's the + * program, but we can't cancel directly from an interrupt. + */ + signal (SIGINT, interrupted); + + if (pipe (cancel_fds) == -1) + { + perror ("pipe"); + exit (1); + } + chan = g_io_channel_unix_new (cancel_fds[0]); + watch = g_io_add_watch (chan, G_IO_IN, async_cancel, cancellable); + g_io_channel_unref (chan); +#endif + + nlookups = argc - 1; + loop = g_main_loop_new (NULL, TRUE); + + if (connectable_count) + { + nlookups = connectable_count; + do_connectable (argv[1], synchronous, connectable_count); + } + else + { + if (synchronous) + start_sync_lookups (argv + 1, argc - 1); + else + start_async_lookups (argv + 1, argc - 1); + } + + g_main_loop_run (loop); + g_main_loop_unref (loop); + +#ifdef G_OS_UNIX + g_source_remove (watch); +#endif + g_object_unref (cancellable); + g_option_context_free (context); + + return 0; +} diff --git a/gio/tests/resourceplugin.c b/gio/tests/resourceplugin.c new file mode 100644 index 0000000..1f218f2 --- /dev/null +++ b/gio/tests/resourceplugin.c @@ -0,0 +1,28 @@ +/* + * Ensure the g_io_module_*() symbols are exported + * on all supported compilers without using config.h. + * This must be done before including any GLib headers, + * since GLIB_AVAILABLE_IN_ALL, which is used to mark the + * g_io_module*() symbols, is defined to be _GLIB_EXTERN, + * which must be overridden to export the symbols. + */ +#include "modules/symbol-visibility.h" +#define _GLIB_EXTERN GLIB_TEST_EXPORT_SYMBOL + +#include + +void +g_io_module_load (GIOModule *module) +{ +} + +void +g_io_module_unload (GIOModule *module) +{ +} + +char ** +g_io_module_query (void) +{ + return NULL; +} diff --git a/gio/tests/resources.c b/gio/tests/resources.c new file mode 100644 index 0000000..7ba5896 --- /dev/null +++ b/gio/tests/resources.c @@ -0,0 +1,1074 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include +#include +#include +#include "gconstructor.h" +#include "test_resources2.h" +#include "digit_test_resources.h" + +#ifdef _MSC_VER +# define MODULE_FILENAME_PREFIX "" +#else +# define MODULE_FILENAME_PREFIX "lib" +#endif + +static void +test_resource (GResource *resource) +{ + GError *error = NULL; + gboolean found, success; + gsize size; + guint32 flags; + GBytes *data; + char **children; + GInputStream *in; + char buffer[128]; + const gchar *not_found_paths[] = + { + "/not/there", + "/", + "", + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++) + { + found = g_resource_get_info (resource, + not_found_paths[i], + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); + g_assert_false (found); + } + + found = g_resource_get_info (resource, + "/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpuint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED); + + found = g_resource_get_info (resource, + "/empty.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 0); + g_assert_cmpuint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED); + + found = g_resource_get_info (resource, + "/a_prefix/test2.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpuint (flags, ==, 0); + + found = g_resource_get_info (resource, + "/a_prefix/test2-alias.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpuint (flags, ==, 0); + + for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++) + { + data = g_resource_lookup_data (resource, + not_found_paths[i], + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); + g_assert_null (data); + } + + data = g_resource_lookup_data (resource, + "/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n"); + g_assert_no_error (error); + g_bytes_unref (data); + + data = g_resource_lookup_data (resource, + "/empty.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_cmpuint (g_bytes_get_size (data), ==, 0); + g_assert_no_error (error); + g_bytes_unref (data); + + for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++) + { + in = g_resource_open_stream (resource, + not_found_paths[i], + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); + g_assert_null (in); + } + + in = g_resource_open_stream (resource, + "/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (in); + g_assert_no_error (error); + + success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1, + &size, + NULL, &error); + g_assert_true (success); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + buffer[size] = 0; + g_assert_cmpstr (buffer, ==, "test1\n"); + + g_input_stream_close (in, NULL, &error); + g_assert_no_error (error); + g_clear_object (&in); + + in = g_resource_open_stream (resource, + "/empty.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_no_error (error); + g_assert_nonnull (in); + + success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1, + &size, + NULL, &error); + g_assert_no_error (error); + g_assert_true (success); + g_assert_cmpint (size, ==, 0); + + g_input_stream_close (in, NULL, &error); + g_assert_no_error (error); + g_clear_object (&in); + + data = g_resource_lookup_data (resource, + "/a_prefix/test2.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n"); + g_bytes_unref (data); + + data = g_resource_lookup_data (resource, + "/a_prefix/test2-alias.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n"); + g_bytes_unref (data); + + for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++) + { + if (g_str_equal (not_found_paths[i], "/")) + continue; + + children = g_resource_enumerate_children (resource, + not_found_paths[i], + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); + g_assert_null (children); + } + + children = g_resource_enumerate_children (resource, + "/a_prefix", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (children); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (children), ==, 2); + g_strfreev (children); + + /* Test the preferred lookup where we have a trailing slash. */ + children = g_resource_enumerate_children (resource, + "/a_prefix/", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (children); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (children), ==, 2); + g_strfreev (children); + + /* test with a path > 256 and no trailing slash to test the + * slow path of resources where we allocate a modified path. + */ + children = g_resource_enumerate_children (resource, + "/not/here/not/here/not/here/not/here/not/here/not/here/not/here" + "/not/here/not/here/not/here/not/here/not/here/not/here/not/here" + "/not/here/not/here/not/here/not/here/not/here/not/here/not/here" + "/not/here/not/here/not/here/not/here/not/here/not/here/not/here" + "/not/here/not/here/not/here/not/here/not/here/not/here/not/here" + "/with/no/trailing/slash", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_null (children); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); +} + +static void +test_resource_file (void) +{ + GResource *resource; + GError *error = NULL; + + resource = g_resource_load ("not-there", &error); + g_assert_null (resource); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); + g_clear_error (&error); + + resource = g_resource_load (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), &error); + g_assert_nonnull (resource); + g_assert_no_error (error); + + test_resource (resource); + g_resource_unref (resource); +} + +static void +test_resource_file_path (void) +{ + static const struct { + const gchar *input; + const gchar *expected; + } test_uris[] = { + { "resource://", "resource:///" }, + { "resource:///", "resource:///" }, + { "resource://////", "resource:///" }, + { "resource:///../../../", "resource:///" }, + { "resource:///../../..", "resource:///" }, + { "resource://abc", "resource:///abc" }, + { "resource:///abc/", "resource:///abc" }, + { "resource:/a/b/../c/", "resource:///a/c" }, + { "resource://../a/b/../c/../", "resource:///a" }, + { "resource://a/b/cc//bb//a///", "resource:///a/b/cc/bb/a" }, + { "resource://././././", "resource:///" }, + { "resource://././././../", "resource:///" }, + { "resource://a/b/c/d.png", "resource:///a/b/c/d.png" }, + { "resource://a/b/c/..png", "resource:///a/b/c/..png" }, + { "resource://a/b/c/./png", "resource:///a/b/c/png" }, + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (test_uris); i++) + { + GFile *file; + gchar *uri; + + file = g_file_new_for_uri (test_uris[i].input); + g_assert_nonnull (file); + + uri = g_file_get_uri (file); + g_assert_nonnull (uri); + + g_assert_cmpstr (uri, ==, test_uris[i].expected); + + g_object_unref (file); + g_free (uri); + } +} + +static void +test_resource_data (void) +{ + GResource *resource; + GError *error = NULL; + gboolean loaded_file; + char *content; + gsize content_size; + GBytes *data; + + loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), + &content, &content_size, NULL); + g_assert_true (loaded_file); + + data = g_bytes_new_take (content, content_size); + resource = g_resource_new_from_data (data, &error); + g_bytes_unref (data); + g_assert_nonnull (resource); + g_assert_no_error (error); + + test_resource (resource); + + g_resource_unref (resource); +} + +static void +test_resource_data_unaligned (void) +{ + GResource *resource; + GError *error = NULL; + gboolean loaded_file; + char *content, *content_copy; + gsize content_size; + GBytes *data; + + loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), + &content, &content_size, NULL); + g_assert_true (loaded_file); + + content_copy = g_new (char, content_size + 1); + memcpy (content_copy + 1, content, content_size); + + data = g_bytes_new_with_free_func (content_copy + 1, content_size, + (GDestroyNotify) g_free, content_copy); + g_free (content); + resource = g_resource_new_from_data (data, &error); + g_bytes_unref (data); + g_assert_nonnull (resource); + g_assert_no_error (error); + + test_resource (resource); + + g_resource_unref (resource); +} + +/* Test error handling for corrupt GResource files (specifically, a corrupt + * GVDB header). */ +static void +test_resource_data_corrupt (void) +{ + /* A GVDB header is 6 guint32s, and requires a magic number in the first two + * guint32s. A set of zero bytes of a greater length is considered corrupt. */ + static const guint8 data[sizeof (guint32) * 7] = { 0, }; + GBytes *bytes = NULL; + GResource *resource = NULL; + GError *local_error = NULL; + + bytes = g_bytes_new_static (data, sizeof (data)); + resource = g_resource_new_from_data (bytes, &local_error); + g_bytes_unref (bytes); + g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL); + g_assert_null (resource); + + g_clear_error (&local_error); +} + +/* Test handling for empty GResource files. They should also be treated as + * corrupt. */ +static void +test_resource_data_empty (void) +{ + GBytes *bytes = NULL; + GResource *resource = NULL; + GError *local_error = NULL; + + bytes = g_bytes_new_static (NULL, 0); + resource = g_resource_new_from_data (bytes, &local_error); + g_bytes_unref (bytes); + g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL); + g_assert_null (resource); + + g_clear_error (&local_error); +} + +static void +test_resource_registered (void) +{ + GResource *resource; + GError *error = NULL; + gboolean found, success; + gsize size; + guint32 flags; + GBytes *data; + char **children; + GInputStream *in; + char buffer[128]; + + resource = g_resource_load (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), &error); + g_assert_nonnull (resource); + g_assert_no_error (error); + + found = g_resources_get_info ("/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_false (found); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); + + g_resources_register (resource); + + found = g_resources_get_info ("/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED); + + found = g_resources_get_info ("/empty.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_no_error (error); + g_assert_true (found); + g_assert_cmpint (size, ==, 0); + g_assert_cmpint (flags, ==, G_RESOURCE_FLAGS_COMPRESSED); + + found = g_resources_get_info ("/a_prefix/test2.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpint (flags, ==, 0); + + found = g_resources_get_info ("/a_prefix/test2-alias.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpuint (flags, ==, 0); + + data = g_resources_lookup_data ("/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n"); + g_assert_no_error (error); + g_bytes_unref (data); + + in = g_resources_open_stream ("/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (in); + g_assert_no_error (error); + + success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1, + &size, + NULL, &error); + g_assert_true (success); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + buffer[size] = 0; + g_assert_cmpstr (buffer, ==, "test1\n"); + + g_input_stream_close (in, NULL, &error); + g_assert_no_error (error); + g_clear_object (&in); + + data = g_resources_lookup_data ("/empty.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_no_error (error); + g_assert_cmpuint (g_bytes_get_size (data), ==, 0); + g_bytes_unref (data); + + in = g_resources_open_stream ("/empty.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_no_error (error); + g_assert_nonnull (in); + + success = g_input_stream_read_all (in, buffer, sizeof (buffer) - 1, + &size, + NULL, &error); + g_assert_no_error (error); + g_assert_true (success); + g_assert_cmpint (size, ==, 0); + + g_input_stream_close (in, NULL, &error); + g_assert_no_error (error); + g_clear_object (&in); + + data = g_resources_lookup_data ("/a_prefix/test2.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n"); + g_bytes_unref (data); + + data = g_resources_lookup_data ("/a_prefix/test2-alias.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n"); + g_bytes_unref (data); + + children = g_resources_enumerate_children ("/not/here", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_null (children); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); + + children = g_resources_enumerate_children ("/a_prefix", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (children); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (children), ==, 2); + g_strfreev (children); + + g_resources_unregister (resource); + g_resource_unref (resource); + + found = g_resources_get_info ("/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_false (found); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); +} + +static void +test_resource_automatic (void) +{ + GError *error = NULL; + gboolean found; + gsize size; + guint32 flags; + GBytes *data; + + found = g_resources_get_info ("/auto_loaded/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpint (flags, ==, 0); + + data = g_resources_lookup_data ("/auto_loaded/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n"); + g_bytes_unref (data); +} + +static void +test_resource_manual (void) +{ + GError *error = NULL; + gboolean found; + gsize size; + guint32 flags; + GBytes *data; + + found = g_resources_get_info ("/manual_loaded/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpuint (flags, ==, 0); + + data = g_resources_lookup_data ("/manual_loaded/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n"); + g_bytes_unref (data); +} + +static void +test_resource_manual2 (void) +{ + GResource *resource; + GBytes *data; + gsize size; + GError *error = NULL; + + resource = _g_test2_get_resource (); + + data = g_resource_lookup_data (resource, + "/manual_loaded/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n"); + g_bytes_unref (data); + + g_resource_unref (resource); +} + +/* Test building resources with external data option, + * where data is linked in as binary instead of compiled in. + * Checks if resources are automatically registered and + * data can be found and read. */ +static void +test_resource_binary_linked (void) +{ + #ifndef __linux__ + g_test_skip ("--external-data test only works on Linux"); + return; + #else /* if __linux__ */ + GError *error = NULL; + gboolean found; + gsize size; + guint32 flags; + GBytes *data; + + found = g_resources_get_info ("/binary_linked/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpuint (flags, ==, 0); + + data = g_resources_lookup_data ("/binary_linked/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n"); + g_bytes_unref (data); + #endif /* if __linux__ */ +} + +/* Test resource whose xml file starts with more than one digit + * and where no explicit c-name is given + * Checks if resources are successfully registered and + * data can be found and read. */ +static void +test_resource_digits (void) +{ + GError *error = NULL; + gboolean found; + gsize size; + guint32 flags; + GBytes *data; + + found = g_resources_get_info ("/digit_test/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpuint (flags, ==, 0); + + data = g_resources_lookup_data ("/digit_test/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n"); + g_bytes_unref (data); +} + +static void +test_resource_module (void) +{ + GIOModule *module; + gboolean found; + gsize size; + guint32 flags; + GBytes *data; + GError *error; + +#ifdef GLIB_STATIC_COMPILATION + /* The resource module is statically linked with a separate copy + * of a GLib so g_static_resource_init won't work as expected. */ + g_test_skip ("Resource modules aren't supported in static builds."); + return; +#endif + + if (g_module_supported ()) + { + module = g_io_module_new (g_test_get_filename (G_TEST_BUILT, + MODULE_FILENAME_PREFIX "resourceplugin", + NULL)); + + error = NULL; + + found = g_resources_get_info ("/resourceplugin/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_false (found); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); + + g_type_module_use (G_TYPE_MODULE (module)); + + found = g_resources_get_info ("/resourceplugin/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + g_assert_cmpint (size, ==, 6); + g_assert_cmpuint (flags, ==, 0); + + data = g_resources_lookup_data ("/resourceplugin/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + g_assert_cmpint (size, ==, 6); + g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n"); + g_bytes_unref (data); + + g_type_module_unuse (G_TYPE_MODULE (module)); + + found = g_resources_get_info ("/resourceplugin/test1.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_false (found); + g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + g_clear_error (&error); + + g_clear_object (&module); + } +} + +static void +test_uri_query_info (void) +{ + GResource *resource; + GError *error = NULL; + gboolean loaded_file; + char *content; + gsize content_size; + GBytes *data; + GFile *file; + GFileInfo *info; + const char *content_type; + gchar *mime_type = NULL; + const char *fs_type; + gboolean readonly; + + loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), + &content, &content_size, NULL); + g_assert_true (loaded_file); + + data = g_bytes_new_take (content, content_size); + resource = g_resource_new_from_data (data, &error); + g_bytes_unref (data); + g_assert_nonnull (resource); + g_assert_no_error (error); + + g_resources_register (resource); + + file = g_file_new_for_uri ("resource://" "/a_prefix/test2-alias.txt"); + info = g_file_query_info (file, "*", 0, NULL, &error); + g_assert_no_error (error); + + content_type = g_file_info_get_content_type (info); + g_assert_nonnull (content_type); + mime_type = g_content_type_get_mime_type (content_type); + g_assert_nonnull (mime_type); + g_assert_cmpstr (mime_type, ==, "text/plain"); + g_free (mime_type); + + g_object_unref (info); + + info = g_file_query_filesystem_info (file, "*", NULL, &error); + g_assert_no_error (error); + + fs_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE); + g_assert_cmpstr (fs_type, ==, "resource"); + readonly = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY); + g_assert_true (readonly); + + g_object_unref (info); + + g_assert_cmpuint (g_file_hash (file), !=, 0); + + g_object_unref (file); + + g_resources_unregister (resource); + g_resource_unref (resource); +} + +static void +test_uri_file (void) +{ + GResource *resource; + GError *error = NULL; + gboolean loaded_file; + char *content; + gsize content_size; + GBytes *data; + GFile *file; + GFileInfo *info; + gchar *name; + GFile *file2, *parent; + GFileEnumerator *enumerator; + gchar *scheme; + GFileAttributeInfoList *attrs; + GInputStream *stream; + gchar buf[1024]; + gboolean ret; + gssize skipped; + + loaded_file = g_file_get_contents (g_test_get_filename (G_TEST_BUILT, "test.gresource", NULL), + &content, &content_size, NULL); + g_assert_true (loaded_file); + + data = g_bytes_new_take (content, content_size); + resource = g_resource_new_from_data (data, &error); + g_bytes_unref (data); + g_assert_nonnull (resource); + g_assert_no_error (error); + + g_resources_register (resource); + + file = g_file_new_for_uri ("resource://" "/a_prefix/test2-alias.txt"); + + g_assert_null (g_file_get_path (file)); + + name = g_file_get_parse_name (file); + g_assert_cmpstr (name, ==, "resource:///a_prefix/test2-alias.txt"); + g_free (name); + + name = g_file_get_uri (file); + g_assert_cmpstr (name, ==, "resource:///a_prefix/test2-alias.txt"); + g_free (name); + + g_assert_false (g_file_is_native (file)); + g_assert_false (g_file_has_uri_scheme (file, "http")); + g_assert_true (g_file_has_uri_scheme (file, "resource")); + scheme = g_file_get_uri_scheme (file); + g_assert_cmpstr (scheme, ==, "resource"); + g_free (scheme); + + file2 = g_file_dup (file); + g_assert_true (g_file_equal (file, file2)); + g_object_unref (file2); + + parent = g_file_get_parent (file); + enumerator = g_file_enumerate_children (parent, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error); + g_assert_no_error (error); + + file2 = g_file_get_child_for_display_name (parent, "test2-alias.txt", &error); + g_assert_no_error (error); + g_assert_true (g_file_equal (file, file2)); + g_object_unref (file2); + + info = g_file_enumerator_next_file (enumerator, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (info); + g_object_unref (info); + + info = g_file_enumerator_next_file (enumerator, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (info); + g_object_unref (info); + + info = g_file_enumerator_next_file (enumerator, NULL, &error); + g_assert_no_error (error); + g_assert_null (info); + + g_file_enumerator_close (enumerator, NULL, &error); + g_assert_no_error (error); + g_object_unref (enumerator); + + file2 = g_file_new_for_uri ("resource://" "a_prefix/../a_prefix//test2-alias.txt"); + g_assert_true (g_file_equal (file, file2)); + + g_assert_true (g_file_has_prefix (file, parent)); + + name = g_file_get_relative_path (parent, file); + g_assert_cmpstr (name, ==, "test2-alias.txt"); + g_free (name); + + g_object_unref (parent); + + attrs = g_file_query_settable_attributes (file, NULL, &error); + g_assert_no_error (error); + g_file_attribute_info_list_unref (attrs); + + attrs = g_file_query_writable_namespaces (file, NULL, &error); + g_assert_no_error (error); + g_file_attribute_info_list_unref (attrs); + + stream = G_INPUT_STREAM (g_file_read (file, NULL, &error)); + g_assert_no_error (error); + g_assert_cmpint (g_seekable_tell (G_SEEKABLE (stream)), ==, 0); + g_assert_true (g_seekable_can_seek (G_SEEKABLE (G_SEEKABLE (stream)))); + ret = g_seekable_seek (G_SEEKABLE (stream), 1, G_SEEK_SET, NULL, &error); + g_assert_true (ret); + g_assert_no_error (error); + skipped = g_input_stream_skip (stream, 1, NULL, &error); + g_assert_cmpint (skipped, ==, 1); + g_assert_no_error (error); + + memset (buf, 0, 1024); + ret = g_input_stream_read_all (stream, &buf, 1024, NULL, NULL, &error); + g_assert_true (ret); + g_assert_no_error (error); + g_assert_cmpstr (buf, ==, "st2\n"); + info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (stream), + G_FILE_ATTRIBUTE_STANDARD_SIZE, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (info); + g_assert_cmpint (g_file_info_get_size (info), ==, 6); + g_object_unref (info); + + ret = g_input_stream_close (stream, NULL, &error); + g_assert_true (ret); + g_assert_no_error (error); + g_object_unref (stream); + + g_object_unref (file); + g_object_unref (file2); + + g_resources_unregister (resource); + g_resource_unref (resource); +} + +static void +test_resource_64k (void) +{ + GError *error = NULL; + gboolean found; + gsize size; + guint32 flags; + GBytes *data; + gchar **tokens; + + found = g_resources_get_info ("/big_prefix/gresource-big-test.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &size, &flags, &error); + g_assert_true (found); + g_assert_no_error (error); + + /* Check size: 100 of all lower case letters + newline char + + * 100 all upper case letters + newline char + + * 100 of all numbers between 0 to 9 + newline char + * (for 12 iterations) + */ + + g_assert_cmpint (size, ==, (26 + 26 + 10) * (100 + 1) * 12); + g_assert_cmpuint (flags, ==, 0); + data = g_resources_lookup_data ("/big_prefix/gresource-big-test.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + g_assert_nonnull (data); + g_assert_no_error (error); + size = g_bytes_get_size (data); + + g_assert_cmpint (size, ==, (26 + 26 + 10) * (100 + 1) * 12); + tokens = g_strsplit ((const gchar *) g_bytes_get_data (data, NULL), "\n", -1); + + /* check tokens[x] == entry at gresource-big-test.txt's line, where x = line - 1 */ + g_assert_cmpstr (tokens[0], ==, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + g_assert_cmpstr (tokens[27], ==, "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); + g_assert_cmpstr (tokens[183], ==, "7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777"); + g_assert_cmpstr (tokens[600], ==, "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"); + g_assert_cmpstr (tokens[742], ==, "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"); + g_strfreev (tokens); + g_bytes_unref (data); +} + +/* Check that g_resources_get_info() respects G_RESOURCE_OVERLAYS */ +static void +test_overlay (void) +{ + if (g_test_subprocess ()) + { + GError *error = NULL; + gboolean res; + gsize size; + char *overlay; + char *path; + + path = g_test_build_filename (G_TEST_DIST, "test1.overlay", NULL); + overlay = g_strconcat ("/auto_loaded/test1.txt=", path, NULL); + + g_setenv ("G_RESOURCE_OVERLAYS", overlay, TRUE); + res = g_resources_get_info ("/auto_loaded/test1.txt", 0, &size, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + /* test1.txt is 6 bytes, test1.overlay is 23 */ + g_assert_cmpint (size, ==, 23); + + g_free (overlay); + g_free (path); + + return; + } + g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDERR); + g_test_trap_assert_passed (); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + _g_test2_register_resource (); + _digit_test_register_resource (); + + g_test_add_func ("/resource/file", test_resource_file); + g_test_add_func ("/resource/file-path", test_resource_file_path); + g_test_add_func ("/resource/data", test_resource_data); + g_test_add_func ("/resource/data_unaligned", test_resource_data_unaligned); + g_test_add_func ("/resource/data-corrupt", test_resource_data_corrupt); + g_test_add_func ("/resource/data-empty", test_resource_data_empty); + g_test_add_func ("/resource/registered", test_resource_registered); + g_test_add_func ("/resource/manual", test_resource_manual); + g_test_add_func ("/resource/manual2", test_resource_manual2); +#ifdef G_HAS_CONSTRUCTORS + g_test_add_func ("/resource/automatic", test_resource_automatic); + /* This only uses automatic resources too, so it tests the constructors and destructors */ + g_test_add_func ("/resource/module", test_resource_module); + g_test_add_func ("/resource/binary-linked", test_resource_binary_linked); +#endif + g_test_add_func ("/resource/uri/query-info", test_uri_query_info); + g_test_add_func ("/resource/uri/file", test_uri_file); + g_test_add_func ("/resource/64k", test_resource_64k); + g_test_add_func ("/resource/overlay", test_overlay); + g_test_add_func ("/resource/digits", test_resource_digits); + + return g_test_run(); +} diff --git a/gio/tests/schema-tests/array-default-not-in-choices.gschema.xml b/gio/tests/schema-tests/array-default-not-in-choices.gschema.xml new file mode 100644 index 0000000..b6fffc6 --- /dev/null +++ b/gio/tests/schema-tests/array-default-not-in-choices.gschema.xml @@ -0,0 +1,11 @@ + + + + + + + + ["first","last","second"] + + + diff --git a/gio/tests/schema-tests/bad-choice.gschema.xml b/gio/tests/schema-tests/bad-choice.gschema.xml new file mode 100644 index 0000000..07640d5 --- /dev/null +++ b/gio/tests/schema-tests/bad-choice.gschema.xml @@ -0,0 +1,14 @@ + + + + 'how' + + + + + + + + + + diff --git a/gio/tests/schema-tests/bad-key.gschema.xml b/gio/tests/schema-tests/bad-key.gschema.xml new file mode 100644 index 0000000..f98cc7c --- /dev/null +++ b/gio/tests/schema-tests/bad-key.gschema.xml @@ -0,0 +1,7 @@ + + + + '' + + + diff --git a/gio/tests/schema-tests/bad-key2.gschema.xml b/gio/tests/schema-tests/bad-key2.gschema.xml new file mode 100644 index 0000000..b7c4e7b --- /dev/null +++ b/gio/tests/schema-tests/bad-key2.gschema.xml @@ -0,0 +1,7 @@ + + + + '' + + + diff --git a/gio/tests/schema-tests/bad-key3.gschema.xml b/gio/tests/schema-tests/bad-key3.gschema.xml new file mode 100644 index 0000000..208a02d --- /dev/null +++ b/gio/tests/schema-tests/bad-key3.gschema.xml @@ -0,0 +1,7 @@ + + + + '' + + + diff --git a/gio/tests/schema-tests/bad-key4.gschema.xml b/gio/tests/schema-tests/bad-key4.gschema.xml new file mode 100644 index 0000000..6a3777c --- /dev/null +++ b/gio/tests/schema-tests/bad-key4.gschema.xml @@ -0,0 +1,7 @@ + + + + '' + + + diff --git a/gio/tests/schema-tests/bad-type.gschema.xml b/gio/tests/schema-tests/bad-type.gschema.xml new file mode 100644 index 0000000..9b74684 --- /dev/null +++ b/gio/tests/schema-tests/bad-type.gschema.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gio/tests/schema-tests/bare-alias.gschema.xml b/gio/tests/schema-tests/bare-alias.gschema.xml new file mode 100644 index 0000000..52184cd --- /dev/null +++ b/gio/tests/schema-tests/bare-alias.gschema.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gio/tests/schema-tests/cdata.gschema.xml b/gio/tests/schema-tests/cdata.gschema.xml new file mode 100644 index 0000000..be2aac8 --- /dev/null +++ b/gio/tests/schema-tests/cdata.gschema.xml @@ -0,0 +1,7 @@ + + + + ','']]]> + + + diff --git a/gio/tests/schema-tests/choice-alias.gschema.xml b/gio/tests/schema-tests/choice-alias.gschema.xml new file mode 100644 index 0000000..d5c9279 --- /dev/null +++ b/gio/tests/schema-tests/choice-alias.gschema.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + 'after' + + + diff --git a/gio/tests/schema-tests/choice-bad.gschema.xml b/gio/tests/schema-tests/choice-bad.gschema.xml new file mode 100644 index 0000000..4a2dbc2 --- /dev/null +++ b/gio/tests/schema-tests/choice-bad.gschema.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + 'how' + + + diff --git a/gio/tests/schema-tests/choice-badtype.gschema.xml b/gio/tests/schema-tests/choice-badtype.gschema.xml new file mode 100644 index 0000000..88104c5 --- /dev/null +++ b/gio/tests/schema-tests/choice-badtype.gschema.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gio/tests/schema-tests/choice-invalid-alias.gschema.xml b/gio/tests/schema-tests/choice-invalid-alias.gschema.xml new file mode 100644 index 0000000..ae5bcd3 --- /dev/null +++ b/gio/tests/schema-tests/choice-invalid-alias.gschema.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + 'after' + + + diff --git a/gio/tests/schema-tests/choice-missing-value.gschema.xml b/gio/tests/schema-tests/choice-missing-value.gschema.xml new file mode 100644 index 0000000..d900fc5 --- /dev/null +++ b/gio/tests/schema-tests/choice-missing-value.gschema.xml @@ -0,0 +1,10 @@ + + + + + + + "a" + + + diff --git a/gio/tests/schema-tests/choice-shadowed-alias.gschema.xml b/gio/tests/schema-tests/choice-shadowed-alias.gschema.xml new file mode 100644 index 0000000..fb68e32 --- /dev/null +++ b/gio/tests/schema-tests/choice-shadowed-alias.gschema.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + 'after' + + + diff --git a/gio/tests/schema-tests/choice-upside-down.gschema.xml b/gio/tests/schema-tests/choice-upside-down.gschema.xml new file mode 100644 index 0000000..ea6f532 --- /dev/null +++ b/gio/tests/schema-tests/choice-upside-down.gschema.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + 'who' + + + diff --git a/gio/tests/schema-tests/choice.gschema.xml b/gio/tests/schema-tests/choice.gschema.xml new file mode 100644 index 0000000..c9d7426 --- /dev/null +++ b/gio/tests/schema-tests/choice.gschema.xml @@ -0,0 +1,14 @@ + + + + 'who' + + + + + + + + + + diff --git a/gio/tests/schema-tests/choices-wrong-type.gschema.xml b/gio/tests/schema-tests/choices-wrong-type.gschema.xml new file mode 100644 index 0000000..7e6f14c --- /dev/null +++ b/gio/tests/schema-tests/choices-wrong-type.gschema.xml @@ -0,0 +1,8 @@ + + + + + (1,"a") + + + diff --git a/gio/tests/schema-tests/default-in-aliases.gschema.xml b/gio/tests/schema-tests/default-in-aliases.gschema.xml new file mode 100644 index 0000000..81d639f --- /dev/null +++ b/gio/tests/schema-tests/default-in-aliases.gschema.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + 'pre' + + + diff --git a/gio/tests/schema-tests/default-not-in-choices.gschema.xml b/gio/tests/schema-tests/default-not-in-choices.gschema.xml new file mode 100644 index 0000000..ec4a08d --- /dev/null +++ b/gio/tests/schema-tests/default-not-in-choices.gschema.xml @@ -0,0 +1,11 @@ + + + + + + + + "next-to-last" + + + diff --git a/gio/tests/schema-tests/default-out-of-range.gschema.xml b/gio/tests/schema-tests/default-out-of-range.gschema.xml new file mode 100644 index 0000000..8b3cbd3 --- /dev/null +++ b/gio/tests/schema-tests/default-out-of-range.gschema.xml @@ -0,0 +1,8 @@ + + + + + -1 + + + diff --git a/gio/tests/schema-tests/description-xmllang.gschema.xml b/gio/tests/schema-tests/description-xmllang.gschema.xml new file mode 100644 index 0000000..29e771b --- /dev/null +++ b/gio/tests/schema-tests/description-xmllang.gschema.xml @@ -0,0 +1,13 @@ + + + + false + Bla + Window-specific screenshot (deprecated) + Captura especifica de finestra (obsoleto) + لقطة شاشة مختصّة Ø¨Ù†Ø§ÙØ°Ø© (Ù…ÙØ¨Ø·Ù„) + উইনà§à¦¡à§‹à§° কà§à¦·à§‡à¦¤à§à§°à¦¤ নিৰà§à¦¦à¦¿à¦·à§à¦Ÿ সà§à¦•à§à§°à¦¿à¦¨à¦¶à§à¦¬à¦Ÿ (সà§à¦–লিত) + Captura específica de ventana (obsoleto) + + + diff --git a/gio/tests/schema-tests/empty-key.gschema.xml b/gio/tests/schema-tests/empty-key.gschema.xml new file mode 100644 index 0000000..3c5c05c --- /dev/null +++ b/gio/tests/schema-tests/empty-key.gschema.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gio/tests/schema-tests/enum-with-aliases.gschema.xml b/gio/tests/schema-tests/enum-with-aliases.gschema.xml new file mode 100644 index 0000000..e8c1e68 --- /dev/null +++ b/gio/tests/schema-tests/enum-with-aliases.gschema.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + 'spam' + + + + + + + diff --git a/gio/tests/schema-tests/enum-with-bad-default.gschema.xml b/gio/tests/schema-tests/enum-with-bad-default.gschema.xml new file mode 100644 index 0000000..aee0867 --- /dev/null +++ b/gio/tests/schema-tests/enum-with-bad-default.gschema.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + 'nie' + + + diff --git a/gio/tests/schema-tests/enum-with-chained-alias.gschema.xml b/gio/tests/schema-tests/enum-with-chained-alias.gschema.xml new file mode 100644 index 0000000..65c31e3 --- /dev/null +++ b/gio/tests/schema-tests/enum-with-chained-alias.gschema.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + 'spam' + + + + + + + + diff --git a/gio/tests/schema-tests/enum-with-choice.gschema.xml b/gio/tests/schema-tests/enum-with-choice.gschema.xml new file mode 100644 index 0000000..50caf21 --- /dev/null +++ b/gio/tests/schema-tests/enum-with-choice.gschema.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + 'spam' + + + + diff --git a/gio/tests/schema-tests/enum-with-invalid-alias.gschema.xml b/gio/tests/schema-tests/enum-with-invalid-alias.gschema.xml new file mode 100644 index 0000000..51a51fd --- /dev/null +++ b/gio/tests/schema-tests/enum-with-invalid-alias.gschema.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + 'spam' + + + + + + + diff --git a/gio/tests/schema-tests/enum-with-invalid-value.gschema.xml b/gio/tests/schema-tests/enum-with-invalid-value.gschema.xml new file mode 100644 index 0000000..02071e0 --- /dev/null +++ b/gio/tests/schema-tests/enum-with-invalid-value.gschema.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gio/tests/schema-tests/enum-with-repeated-alias.gschema.xml b/gio/tests/schema-tests/enum-with-repeated-alias.gschema.xml new file mode 100644 index 0000000..a13ef89 --- /dev/null +++ b/gio/tests/schema-tests/enum-with-repeated-alias.gschema.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + 'spam' + + + + + + + + diff --git a/gio/tests/schema-tests/enum-with-repeated-nick.gschema.xml b/gio/tests/schema-tests/enum-with-repeated-nick.gschema.xml new file mode 100644 index 0000000..8910711 --- /dev/null +++ b/gio/tests/schema-tests/enum-with-repeated-nick.gschema.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gio/tests/schema-tests/enum-with-repeated-value.gschema.xml b/gio/tests/schema-tests/enum-with-repeated-value.gschema.xml new file mode 100644 index 0000000..a357d11 --- /dev/null +++ b/gio/tests/schema-tests/enum-with-repeated-value.gschema.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gio/tests/schema-tests/enum-with-shadow-alias.gschema.xml b/gio/tests/schema-tests/enum-with-shadow-alias.gschema.xml new file mode 100644 index 0000000..52e30ee --- /dev/null +++ b/gio/tests/schema-tests/enum-with-shadow-alias.gschema.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + 'spam' + + + + + + + diff --git a/gio/tests/schema-tests/enum.gschema.xml b/gio/tests/schema-tests/enum.gschema.xml new file mode 100644 index 0000000..8cf5879 --- /dev/null +++ b/gio/tests/schema-tests/enum.gschema.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + 'spam' + + + diff --git a/gio/tests/schema-tests/extend-and-shadow-indirect.gschema.xml b/gio/tests/schema-tests/extend-and-shadow-indirect.gschema.xml new file mode 100644 index 0000000..dc066dd --- /dev/null +++ b/gio/tests/schema-tests/extend-and-shadow-indirect.gschema.xml @@ -0,0 +1,17 @@ + + + + '' + + + + + + '' + + + + + + + diff --git a/gio/tests/schema-tests/extend-and-shadow.gschema.xml b/gio/tests/schema-tests/extend-and-shadow.gschema.xml new file mode 100644 index 0000000..79935b4 --- /dev/null +++ b/gio/tests/schema-tests/extend-and-shadow.gschema.xml @@ -0,0 +1,17 @@ + + + + '' + + + + + + '' + + + + + + + diff --git a/gio/tests/schema-tests/extend-missing.gschema.xml b/gio/tests/schema-tests/extend-missing.gschema.xml new file mode 100644 index 0000000..675803a --- /dev/null +++ b/gio/tests/schema-tests/extend-missing.gschema.xml @@ -0,0 +1,3 @@ + + + diff --git a/gio/tests/schema-tests/extend-nonlist.gschema.xml b/gio/tests/schema-tests/extend-nonlist.gschema.xml new file mode 100644 index 0000000..7008cee --- /dev/null +++ b/gio/tests/schema-tests/extend-nonlist.gschema.xml @@ -0,0 +1,4 @@ + + + + diff --git a/gio/tests/schema-tests/extend-self.gschema.xml b/gio/tests/schema-tests/extend-self.gschema.xml new file mode 100644 index 0000000..f5b0c3d --- /dev/null +++ b/gio/tests/schema-tests/extend-self.gschema.xml @@ -0,0 +1,3 @@ + + + diff --git a/gio/tests/schema-tests/extend-wrong-list-indirect.gschema.xml b/gio/tests/schema-tests/extend-wrong-list-indirect.gschema.xml new file mode 100644 index 0000000..a336db7 --- /dev/null +++ b/gio/tests/schema-tests/extend-wrong-list-indirect.gschema.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/gio/tests/schema-tests/extend-wrong-list.gschema.xml b/gio/tests/schema-tests/extend-wrong-list.gschema.xml new file mode 100644 index 0000000..4232dc2 --- /dev/null +++ b/gio/tests/schema-tests/extend-wrong-list.gschema.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/gio/tests/schema-tests/extending.gschema.xml b/gio/tests/schema-tests/extending.gschema.xml new file mode 100644 index 0000000..98882c7 --- /dev/null +++ b/gio/tests/schema-tests/extending.gschema.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/gio/tests/schema-tests/flags-aliased-default.gschema.xml b/gio/tests/schema-tests/flags-aliased-default.gschema.xml new file mode 100644 index 0000000..c36bd62 --- /dev/null +++ b/gio/tests/schema-tests/flags-aliased-default.gschema.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + ['speaking'] + + + + diff --git a/gio/tests/schema-tests/flags-bad-default.gschema.xml b/gio/tests/schema-tests/flags-bad-default.gschema.xml new file mode 100644 index 0000000..d412057 --- /dev/null +++ b/gio/tests/schema-tests/flags-bad-default.gschema.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + ['speaking'] + + + + diff --git a/gio/tests/schema-tests/flags-more-than-one-bit.gschema.xml b/gio/tests/schema-tests/flags-more-than-one-bit.gschema.xml new file mode 100644 index 0000000..ce2faaf --- /dev/null +++ b/gio/tests/schema-tests/flags-more-than-one-bit.gschema.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/gio/tests/schema-tests/flags-with-enum-attr.gschema.xml b/gio/tests/schema-tests/flags-with-enum-attr.gschema.xml new file mode 100644 index 0000000..a48547f --- /dev/null +++ b/gio/tests/schema-tests/flags-with-enum-attr.gschema.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/gio/tests/schema-tests/flags-with-enum-tag.gschema.xml b/gio/tests/schema-tests/flags-with-enum-tag.gschema.xml new file mode 100644 index 0000000..4b2fb90 --- /dev/null +++ b/gio/tests/schema-tests/flags-with-enum-tag.gschema.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/gio/tests/schema-tests/from-docs.gschema.xml b/gio/tests/schema-tests/from-docs.gschema.xml new file mode 100644 index 0000000..4fe45c7 --- /dev/null +++ b/gio/tests/schema-tests/from-docs.gschema.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + 10 + + + + + + + + + + + + + 'Joe' + + + + 'first' + + + + diff --git a/gio/tests/schema-tests/incomplete-list.gschema.xml b/gio/tests/schema-tests/incomplete-list.gschema.xml new file mode 100644 index 0000000..df33e84 --- /dev/null +++ b/gio/tests/schema-tests/incomplete-list.gschema.xml @@ -0,0 +1,7 @@ + + + + [1,2,3 + + + diff --git a/gio/tests/schema-tests/inherit-gettext-domain.gschema.xml b/gio/tests/schema-tests/inherit-gettext-domain.gschema.xml new file mode 100644 index 0000000..1f0ca89 --- /dev/null +++ b/gio/tests/schema-tests/inherit-gettext-domain.gschema.xml @@ -0,0 +1,8 @@ + + + + + 'value' + + + diff --git a/gio/tests/schema-tests/invalid-path.gschema.xml b/gio/tests/schema-tests/invalid-path.gschema.xml new file mode 100644 index 0000000..85ecd4c --- /dev/null +++ b/gio/tests/schema-tests/invalid-path.gschema.xml @@ -0,0 +1,3 @@ + + + diff --git a/gio/tests/schema-tests/key-in-list-indirect.gschema.xml b/gio/tests/schema-tests/key-in-list-indirect.gschema.xml new file mode 100644 index 0000000..6f0bea1 --- /dev/null +++ b/gio/tests/schema-tests/key-in-list-indirect.gschema.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gio/tests/schema-tests/key-in-list.gschema.xml b/gio/tests/schema-tests/key-in-list.gschema.xml new file mode 100644 index 0000000..e2a967a --- /dev/null +++ b/gio/tests/schema-tests/key-in-list.gschema.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/gio/tests/schema-tests/list-of-missing.gschema.xml b/gio/tests/schema-tests/list-of-missing.gschema.xml new file mode 100644 index 0000000..f5ef476 --- /dev/null +++ b/gio/tests/schema-tests/list-of-missing.gschema.xml @@ -0,0 +1,3 @@ + + + diff --git a/gio/tests/schema-tests/missing-quotes.gschema.xml b/gio/tests/schema-tests/missing-quotes.gschema.xml new file mode 100644 index 0000000..4400a62 --- /dev/null +++ b/gio/tests/schema-tests/missing-quotes.gschema.xml @@ -0,0 +1,7 @@ + + + + foo + + + diff --git a/gio/tests/schema-tests/no-default.gschema.xml b/gio/tests/schema-tests/no-default.gschema.xml new file mode 100644 index 0000000..5496ce3 --- /dev/null +++ b/gio/tests/schema-tests/no-default.gschema.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/gio/tests/schema-tests/overflow.gschema.xml b/gio/tests/schema-tests/overflow.gschema.xml new file mode 100644 index 0000000..19d4176 --- /dev/null +++ b/gio/tests/schema-tests/overflow.gschema.xml @@ -0,0 +1,7 @@ + + + + 512 + + + diff --git a/gio/tests/schema-tests/override-missing.gschema.xml b/gio/tests/schema-tests/override-missing.gschema.xml new file mode 100644 index 0000000..9a3c781 --- /dev/null +++ b/gio/tests/schema-tests/override-missing.gschema.xml @@ -0,0 +1,11 @@ + + + + 'bar' + + + + + 'baz' + + diff --git a/gio/tests/schema-tests/override-range-error.gschema.xml b/gio/tests/schema-tests/override-range-error.gschema.xml new file mode 100644 index 0000000..4887ac3 --- /dev/null +++ b/gio/tests/schema-tests/override-range-error.gschema.xml @@ -0,0 +1,12 @@ + + + + + 10 + + + + + 77 + + diff --git a/gio/tests/schema-tests/override-then-key.gschema.xml b/gio/tests/schema-tests/override-then-key.gschema.xml new file mode 100644 index 0000000..85b70bd --- /dev/null +++ b/gio/tests/schema-tests/override-then-key.gschema.xml @@ -0,0 +1,15 @@ + + + + 'bar' + + + + + 'baz' + + + + + + diff --git a/gio/tests/schema-tests/override-twice.gschema.xml b/gio/tests/schema-tests/override-twice.gschema.xml new file mode 100644 index 0000000..fe6bb64 --- /dev/null +++ b/gio/tests/schema-tests/override-twice.gschema.xml @@ -0,0 +1,12 @@ + + + + 'bar' + + + + + 'baz' + 'baz' + + diff --git a/gio/tests/schema-tests/override-type-error.gschema.xml b/gio/tests/schema-tests/override-type-error.gschema.xml new file mode 100644 index 0000000..a16ec02 --- /dev/null +++ b/gio/tests/schema-tests/override-type-error.gschema.xml @@ -0,0 +1,11 @@ + + + + 10 + + + + + 37.5 + + diff --git a/gio/tests/schema-tests/override.gschema.xml b/gio/tests/schema-tests/override.gschema.xml new file mode 100644 index 0000000..6309884 --- /dev/null +++ b/gio/tests/schema-tests/override.gschema.xml @@ -0,0 +1,34 @@ + + + + 'bar' + + + + + 10 + + + + + + + + + 'aaaaa' + + + + + + + + 'baz' + 0 + 'aaa' + + + + 'foo' + + diff --git a/gio/tests/schema-tests/range-badtype.gschema.xml b/gio/tests/schema-tests/range-badtype.gschema.xml new file mode 100644 index 0000000..14a7217 --- /dev/null +++ b/gio/tests/schema-tests/range-badtype.gschema.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gio/tests/schema-tests/range-default-high.gschema.xml b/gio/tests/schema-tests/range-default-high.gschema.xml new file mode 100644 index 0000000..b5feb3e --- /dev/null +++ b/gio/tests/schema-tests/range-default-high.gschema.xml @@ -0,0 +1,8 @@ + + + + 28 + + + + diff --git a/gio/tests/schema-tests/range-default-low.gschema.xml b/gio/tests/schema-tests/range-default-low.gschema.xml new file mode 100644 index 0000000..f8fb9ef --- /dev/null +++ b/gio/tests/schema-tests/range-default-low.gschema.xml @@ -0,0 +1,8 @@ + + + + 21 + + + + diff --git a/gio/tests/schema-tests/range-high-default.gschema.xml b/gio/tests/schema-tests/range-high-default.gschema.xml new file mode 100644 index 0000000..0f01fc8 --- /dev/null +++ b/gio/tests/schema-tests/range-high-default.gschema.xml @@ -0,0 +1,8 @@ + + + + + 28 + + + diff --git a/gio/tests/schema-tests/range-low-default.gschema.xml b/gio/tests/schema-tests/range-low-default.gschema.xml new file mode 100644 index 0000000..49db491 --- /dev/null +++ b/gio/tests/schema-tests/range-low-default.gschema.xml @@ -0,0 +1,8 @@ + + + + + 21 + + + diff --git a/gio/tests/schema-tests/range-missing-max.gschema.xml b/gio/tests/schema-tests/range-missing-max.gschema.xml new file mode 100644 index 0000000..c5c43b9 --- /dev/null +++ b/gio/tests/schema-tests/range-missing-max.gschema.xml @@ -0,0 +1,8 @@ + + + + + 200 + + + diff --git a/gio/tests/schema-tests/range-missing-min.gschema.xml b/gio/tests/schema-tests/range-missing-min.gschema.xml new file mode 100644 index 0000000..f4de90c --- /dev/null +++ b/gio/tests/schema-tests/range-missing-min.gschema.xml @@ -0,0 +1,8 @@ + + + + + 2 + + + diff --git a/gio/tests/schema-tests/range-parse-error.gschema.xml b/gio/tests/schema-tests/range-parse-error.gschema.xml new file mode 100644 index 0000000..58ddb50 --- /dev/null +++ b/gio/tests/schema-tests/range-parse-error.gschema.xml @@ -0,0 +1,8 @@ + + + + + 25 + + + diff --git a/gio/tests/schema-tests/range-type-test.gschema.xml b/gio/tests/schema-tests/range-type-test.gschema.xml new file mode 100644 index 0000000..80072bb --- /dev/null +++ b/gio/tests/schema-tests/range-type-test.gschema.xml @@ -0,0 +1,76 @@ + + + + + + 0 + + + + 0 + + + + + 0 + + + + 0 + + + + + 0 + + + + 0 + + + + + 0 + + + + 0 + + + + + 0 + + + + 0 + + + + + 0 + + + + 0 + + + + + 0 + + + + 0 + + + + + 0 + + + + 0 + + + diff --git a/gio/tests/schema-tests/range-wrong-type.gschema.xml b/gio/tests/schema-tests/range-wrong-type.gschema.xml new file mode 100644 index 0000000..033767f --- /dev/null +++ b/gio/tests/schema-tests/range-wrong-type.gschema.xml @@ -0,0 +1,8 @@ + + + + + "a" + + + diff --git a/gio/tests/schema-tests/range.gschema.xml b/gio/tests/schema-tests/range.gschema.xml new file mode 100644 index 0000000..59118bd --- /dev/null +++ b/gio/tests/schema-tests/range.gschema.xml @@ -0,0 +1,8 @@ + + + + + 25 + + + diff --git a/gio/tests/schema-tests/summary-xmllang-and-attrs.gschema.xml b/gio/tests/schema-tests/summary-xmllang-and-attrs.gschema.xml new file mode 100644 index 0000000..b1da54e --- /dev/null +++ b/gio/tests/schema-tests/summary-xmllang-and-attrs.gschema.xml @@ -0,0 +1,13 @@ + + + + false + Window-specific screenshot (deprecated) + Captura especifica de finestra (obsoleto) + لقطة شاشة مختصّة Ø¨Ù†Ø§ÙØ°Ø© (Ù…ÙØ¨Ø·Ù„) + উইনà§à¦¡à§‹à§° কà§à¦·à§‡à¦¤à§à§°à¦¤ নিৰà§à¦¦à¦¿à¦·à§à¦Ÿ সà§à¦•à§à§°à¦¿à¦¨à¦¶à§à¦¬à¦Ÿ (সà§à¦–লিত) + Captura específica de ventana (obsoleto) + Bla + + + diff --git a/gio/tests/schema-tests/summary-xmllang.gschema.xml b/gio/tests/schema-tests/summary-xmllang.gschema.xml new file mode 100644 index 0000000..a3a8675 --- /dev/null +++ b/gio/tests/schema-tests/summary-xmllang.gschema.xml @@ -0,0 +1,13 @@ + + + + false + Window-specific screenshot (deprecated) + Captura especifica de finestra (obsoleto) + لقطة شاشة مختصّة Ø¨Ù†Ø§ÙØ°Ø© (Ù…ÙØ¨Ø·Ù„) + উইনà§à¦¡à§‹à§° কà§à¦·à§‡à¦¤à§à§°à¦¤ নিৰà§à¦¦à¦¿à¦·à§à¦Ÿ সà§à¦•à§à§°à¦¿à¦¨à¦¶à§à¦¬à¦Ÿ (সà§à¦–লিত) + Captura específica de ventana (obsoleto) + Bla + + + diff --git a/gio/tests/schema-tests/wrong-category.gschema.xml b/gio/tests/schema-tests/wrong-category.gschema.xml new file mode 100644 index 0000000..c548248 --- /dev/null +++ b/gio/tests/schema-tests/wrong-category.gschema.xml @@ -0,0 +1,7 @@ + + + + 'foo' + + + diff --git a/gio/tests/send-data.c b/gio/tests/send-data.c new file mode 100644 index 0000000..d70502e --- /dev/null +++ b/gio/tests/send-data.c @@ -0,0 +1,207 @@ +#include +#include +#include + +GMainLoop *loop; + +int cancel_timeout = 0; +int io_timeout = 0; +gboolean async = FALSE; +gboolean graceful = FALSE; +gboolean verbose = FALSE; +static GOptionEntry cmd_entries[] = { + {"cancel", 'c', 0, G_OPTION_ARG_INT, &cancel_timeout, + "Cancel any op after the specified amount of seconds", NULL}, + {"async", 'a', 0, G_OPTION_ARG_NONE, &async, + "Use async ops", NULL}, + {"graceful-disconnect", 'g', 0, G_OPTION_ARG_NONE, &graceful, + "Use graceful disconnect", NULL}, + {"timeout", 't', 0, G_OPTION_ARG_INT, &io_timeout, + "Time out socket I/O after the specified number of seconds", NULL}, + {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, + "Verbose debugging output", NULL}, + G_OPTION_ENTRY_NULL +}; + +static gpointer +cancel_thread (gpointer data) +{ + GCancellable *cancellable = data; + + g_usleep (1000*1000*cancel_timeout); + g_print ("Cancelling\n"); + g_cancellable_cancel (cancellable); + return NULL; +} + +static char * +socket_address_to_string (GSocketAddress *address) +{ + GInetAddress *inet_address; + char *str, *res; + int port; + + inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)); + str = g_inet_address_to_string (inet_address); + port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); + res = g_strdup_printf ("%s:%d", str, port); + g_free (str); + return res; +} + +static void +async_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GAsyncResult **resp = user_data; + *resp = g_object_ref (res); + g_main_loop_quit (loop); +} + +static void +socket_client_event (GSocketClient *client, + GSocketClientEvent event, + GSocketConnectable *connectable, + GSocketConnection *connection) +{ + static GEnumClass *event_class; + gint64 now_us; + + if (!event_class) + event_class = g_type_class_ref (G_TYPE_SOCKET_CLIENT_EVENT); + + now_us = g_get_real_time (); + g_print ("%" G_GINT64_FORMAT " GSocketClient => %s [%s]\n", + now_us, + g_enum_get_value (event_class, event)->value_nick, + connection ? G_OBJECT_TYPE_NAME (connection) : ""); +} + +int +main (int argc, char *argv[]) +{ + GOptionContext *context; + GSocketClient *client; + GSocketConnection *connection; + GSocketAddress *address; + GCancellable *cancellable; + GOutputStream *out; + GError *error = NULL; + char buffer[1000]; + + context = g_option_context_new (" [:port] - send data to tcp host"); + g_option_context_add_main_entries (context, cmd_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + if (argc != 2) + { + g_printerr ("%s: %s\n", argv[0], "Need to specify hostname"); + return 1; + } + + if (async) + loop = g_main_loop_new (NULL, FALSE); + + if (cancel_timeout) + { + GThread *thread; + cancellable = g_cancellable_new (); + thread = g_thread_new ("cancel", cancel_thread, cancellable); + g_thread_unref (thread); + } + else + { + cancellable = NULL; + } + + client = g_socket_client_new (); + if (io_timeout) + g_socket_client_set_timeout (client, io_timeout); + if (verbose) + g_signal_connect (client, "event", G_CALLBACK (socket_client_event), NULL); + + if (async) + { + GAsyncResult *res; + g_socket_client_connect_to_host_async (client, argv[1], 7777, + cancellable, async_cb, &res); + g_main_loop_run (loop); + connection = g_socket_client_connect_to_host_finish (client, res, &error); + g_object_unref (res); + } + else + { + connection = g_socket_client_connect_to_host (client, + argv[1], + 7777, + cancellable, &error); + } + if (connection == NULL) + { + g_printerr ("%s can't connect: %s\n", argv[0], error->message); + return 1; + } + g_object_unref (client); + + address = g_socket_connection_get_remote_address (connection, &error); + if (!address) + { + g_printerr ("Error getting remote address: %s\n", + error->message); + return 1; + } + g_print ("Connected to address: %s\n", + socket_address_to_string (address)); + g_object_unref (address); + + if (graceful) + g_tcp_connection_set_graceful_disconnect (G_TCP_CONNECTION (connection), TRUE); + + out = g_io_stream_get_output_stream (G_IO_STREAM (connection)); + + while (fgets(buffer, sizeof (buffer), stdin) != NULL) + { + /* FIXME if (async) */ + if (!g_output_stream_write_all (out, buffer, strlen (buffer), + NULL, cancellable, &error)) + { + g_warning ("send error: %s", error->message); + g_error_free (error); + error = NULL; + } + } + + g_print ("closing stream\n"); + if (async) + { + GAsyncResult *res; + g_io_stream_close_async (G_IO_STREAM (connection), + 0, cancellable, async_cb, &res); + g_main_loop_run (loop); + if (!g_io_stream_close_finish (G_IO_STREAM (connection), + res, &error)) + { + g_object_unref (res); + g_warning ("close error: %s", error->message); + return 1; + } + g_object_unref (res); + } + else + { + if (!g_io_stream_close (G_IO_STREAM (connection), cancellable, &error)) + { + g_warning ("close error: %s", error->message); + return 1; + } + } + + g_object_unref (connection); + + return 0; +} diff --git a/gio/tests/services/meson.build b/gio/tests/services/meson.build new file mode 100644 index 0000000..fd5117e --- /dev/null +++ b/gio/tests/services/meson.build @@ -0,0 +1,31 @@ +dbus_service_files = [ + 'org.freedesktop.portal.Documents.service', + 'org.gtk.GDBus.FakeService.service' +] + +srcdir_cdata = configuration_data() +srcdir_cdata.set('installed_tests_dir', meson.current_build_dir() / '..') + +installed_cdata = configuration_data() +installed_cdata.set('installed_tests_dir', installed_tests_execdir) + +foreach service_file : dbus_service_files + configure_file( + input: service_file + '.in', + output: service_file, + configuration: srcdir_cdata, + ) + if installed_tests_enabled + # Build a second copy of the service file for the installed + # version of the tests. + configure_file( + input: service_file + '.in', + output: service_file + '.to-install', + configuration: installed_cdata, + ) + install_data(meson.current_build_dir() / service_file + '.to-install', + install_dir: installed_tests_execdir / 'services', + rename: [service_file], + ) + endif +endforeach diff --git a/gio/tests/services/org.freedesktop.portal.Documents.service.in b/gio/tests/services/org.freedesktop.portal.Documents.service.in new file mode 100644 index 0000000..2769ff7 --- /dev/null +++ b/gio/tests/services/org.freedesktop.portal.Documents.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.freedesktop.portal.Documents +Exec=@installed_tests_dir@/fake-document-portal diff --git a/gio/tests/services/org.gtk.GDBus.Examples.ObjectManager.service.in b/gio/tests/services/org.gtk.GDBus.Examples.ObjectManager.service.in new file mode 100644 index 0000000..5820b1a --- /dev/null +++ b/gio/tests/services/org.gtk.GDBus.Examples.ObjectManager.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.gtk.GDBus.Examples.ObjectManager +Exec=@abs_top_builddir@/gio/tests/gdbus-example-objectmanager-server diff --git a/gio/tests/services/org.gtk.GDBus.FakeService.service.in b/gio/tests/services/org.gtk.GDBus.FakeService.service.in new file mode 100644 index 0000000..bbfcd73 --- /dev/null +++ b/gio/tests/services/org.gtk.GDBus.FakeService.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.gtk.GDBus.FakeService +Exec=@installed_tests_dir@/fake-service-name diff --git a/gio/tests/simple-async-result.c b/gio/tests/simple-async-result.c new file mode 100644 index 0000000..86ba22d --- /dev/null +++ b/gio/tests/simple-async-result.c @@ -0,0 +1,199 @@ +/* + * Copyright © 2009 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +#include +#include +#include +#include + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +static GObject *got_source; +static GAsyncResult *got_result; +static gpointer got_user_data; + +static void +ensure_destroyed (gpointer obj) +{ + g_object_add_weak_pointer (obj, &obj); + g_object_unref (obj); + g_assert (obj == NULL); +} + +static void +reset (void) +{ + got_source = NULL; + + if (got_result) + ensure_destroyed (got_result); + + got_result = NULL; + got_user_data = NULL; +} + +static void +check (gpointer a, gpointer b, gpointer c) +{ + g_assert (a == got_source); + g_assert (b == got_result); + g_assert (c == got_user_data); +} + +static void +callback_func (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + got_source = source; + got_result = g_object_ref (result); + got_user_data = user_data; +} + +static gboolean +test_simple_async_idle (gpointer user_data) +{ + GSimpleAsyncResult *result; + GObject *a, *b, *c; + gboolean *ran = user_data; + + a = g_object_new (G_TYPE_OBJECT, NULL); + b = g_object_new (G_TYPE_OBJECT, NULL); + c = g_object_new (G_TYPE_OBJECT, NULL); + + result = g_simple_async_result_new (a, callback_func, b, test_simple_async_idle); + g_assert (g_async_result_get_user_data (G_ASYNC_RESULT (result)) == b); + check (NULL, NULL, NULL); + g_simple_async_result_complete (result); + check (a, result, b); + g_object_unref (result); + + g_assert (g_simple_async_result_is_valid (got_result, a, test_simple_async_idle)); + g_assert (!g_simple_async_result_is_valid (got_result, b, test_simple_async_idle)); + g_assert (!g_simple_async_result_is_valid (got_result, c, test_simple_async_idle)); + g_assert (!g_simple_async_result_is_valid (got_result, b, callback_func)); + g_assert (!g_simple_async_result_is_valid ((gpointer) a, NULL, NULL)); + reset (); + reset (); + reset (); + + ensure_destroyed (a); + ensure_destroyed (b); + ensure_destroyed (c); + + *ran = TRUE; + return G_SOURCE_REMOVE; +} + +static void +test_simple_async (void) +{ + GSimpleAsyncResult *result; + GObject *a, *b; + gboolean ran_test_in_idle = FALSE; + + g_idle_add (test_simple_async_idle, &ran_test_in_idle); + g_main_context_iteration (NULL, FALSE); + + g_assert (ran_test_in_idle); + + a = g_object_new (G_TYPE_OBJECT, NULL); + b = g_object_new (G_TYPE_OBJECT, NULL); + + result = g_simple_async_result_new (a, callback_func, b, test_simple_async); + check (NULL, NULL, NULL); + g_simple_async_result_complete_in_idle (result); + g_object_unref (result); + check (NULL, NULL, NULL); + g_main_context_iteration (NULL, FALSE); + check (a, result, b); + reset (); + + ensure_destroyed (a); + ensure_destroyed (b); +} + +static void +test_valid (void) +{ + GAsyncResult *result; + GObject *a, *b; + + a = g_object_new (G_TYPE_OBJECT, NULL); + b = g_object_new (G_TYPE_OBJECT, NULL); + + /* Without source or tag */ + result = (GAsyncResult *) g_simple_async_result_new (NULL, NULL, NULL, NULL); + g_assert_true (g_simple_async_result_is_valid (result, NULL, NULL)); + g_assert_true (g_simple_async_result_is_valid (result, NULL, test_valid)); + g_assert_true (g_simple_async_result_is_valid (result, NULL, test_simple_async)); + g_assert_false (g_simple_async_result_is_valid (result, a, NULL)); + g_assert_false (g_simple_async_result_is_valid (result, a, test_valid)); + g_assert_false (g_simple_async_result_is_valid (result, a, test_simple_async)); + g_object_unref (result); + + /* Without source, with tag */ + result = (GAsyncResult *) g_simple_async_result_new (NULL, NULL, NULL, test_valid); + g_assert_true (g_simple_async_result_is_valid (result, NULL, NULL)); + g_assert_true (g_simple_async_result_is_valid (result, NULL, test_valid)); + g_assert_false (g_simple_async_result_is_valid (result, NULL, test_simple_async)); + g_assert_false (g_simple_async_result_is_valid (result, a, NULL)); + g_assert_false (g_simple_async_result_is_valid (result, a, test_valid)); + g_assert_false (g_simple_async_result_is_valid (result, a, test_simple_async)); + g_object_unref (result); + + /* With source, without tag */ + result = (GAsyncResult *) g_simple_async_result_new (a, NULL, NULL, NULL); + g_assert_true (g_simple_async_result_is_valid (result, a, NULL)); + g_assert_true (g_simple_async_result_is_valid (result, a, test_valid)); + g_assert_true (g_simple_async_result_is_valid (result, a, test_simple_async)); + g_assert_false (g_simple_async_result_is_valid (result, NULL, NULL)); + g_assert_false (g_simple_async_result_is_valid (result, NULL, test_valid)); + g_assert_false (g_simple_async_result_is_valid (result, NULL, test_simple_async)); + g_assert_false (g_simple_async_result_is_valid (result, b, NULL)); + g_assert_false (g_simple_async_result_is_valid (result, b, test_valid)); + g_assert_false (g_simple_async_result_is_valid (result, b, test_simple_async)); + g_object_unref (result); + + /* With source and tag */ + result = (GAsyncResult *) g_simple_async_result_new (a, NULL, NULL, test_valid); + g_assert_true (g_simple_async_result_is_valid (result, a, test_valid)); + g_assert_true (g_simple_async_result_is_valid (result, a, NULL)); + g_assert_false (g_simple_async_result_is_valid (result, a, test_simple_async)); + g_assert_false (g_simple_async_result_is_valid (result, NULL, NULL)); + g_assert_false (g_simple_async_result_is_valid (result, NULL, test_valid)); + g_assert_false (g_simple_async_result_is_valid (result, NULL, test_simple_async)); + g_assert_false (g_simple_async_result_is_valid (result, b, NULL)); + g_assert_false (g_simple_async_result_is_valid (result, b, test_valid)); + g_assert_false (g_simple_async_result_is_valid (result, b, test_simple_async)); + g_object_unref (result); + + /* Non-GSimpleAsyncResult */ + result = (GAsyncResult *) g_task_new (NULL, NULL, NULL, NULL); + g_assert_false (g_simple_async_result_is_valid (result, NULL, NULL)); + g_object_unref (result); + + g_object_unref (a); + g_object_unref (b); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gio/simple-async-result/test", test_simple_async); + g_test_add_func ("/gio/simple-async-result/valid", test_valid); + + return g_test_run(); +} + +G_GNUC_END_IGNORE_DEPRECATIONS diff --git a/gio/tests/simple-proxy.c b/gio/tests/simple-proxy.c new file mode 100644 index 0000000..ffc16ed --- /dev/null +++ b/gio/tests/simple-proxy.c @@ -0,0 +1,293 @@ +/* GStaticProxyResolver tests + * + * Copyright 2011, 2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + */ + +#include + +static void +async_result_cb (GObject *obj, + GAsyncResult *result, + gpointer user_data) +{ + GAsyncResult **result_out = user_data; + *result_out = g_object_ref (result); +} + +static void +test_uris (void) +{ + GProxyResolver *resolver; + const gchar *ignore_hosts[2] = { "127.0.0.1", NULL }; + gchar **proxies; + GError *error = NULL; + const gchar *uri; + gchar *str = NULL; + GAsyncResult *result = NULL; + + /* Valid URI. */ + uri = "http://%E0%B4%A8%E0%B4%B2:80/"; + resolver = g_simple_proxy_resolver_new (NULL, (char **) ignore_hosts); + + proxies = g_proxy_resolver_lookup (resolver, uri, NULL, &error); + g_assert_no_error (error); + g_strfreev (proxies); + + g_proxy_resolver_lookup_async (resolver, uri, NULL, async_result_cb, &result); + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + proxies = g_proxy_resolver_lookup_finish (resolver, result, &error); + g_assert_no_error (error); + g_strfreev (proxies); + g_clear_object (&result); + + g_object_unref (resolver); + + /* Invalid URI. */ + uri = "%E0%B4%A8%E0%B4%B2"; + str = g_strdup_printf ("Invalid URI ‘%s’", uri); + resolver = g_simple_proxy_resolver_new (NULL, (char **) ignore_hosts); + + proxies = g_proxy_resolver_lookup (resolver, uri, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, str); + g_clear_error (&error); + g_assert_null (proxies); + g_clear_object (&result); + + g_proxy_resolver_lookup_async (resolver, uri, NULL, async_result_cb, &result); + while (result == NULL) + g_main_context_iteration (NULL, TRUE); + proxies = g_proxy_resolver_lookup_finish (resolver, result, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, str); + g_clear_error (&error); + g_assert_null (proxies); + g_object_unref (result); + + g_object_unref (resolver); + g_free (str); + + resolver = g_simple_proxy_resolver_new ("default://", (char **) ignore_hosts); + g_simple_proxy_resolver_set_uri_proxy (G_SIMPLE_PROXY_RESOLVER (resolver), + "http", "http://proxy.example.com"); + g_simple_proxy_resolver_set_uri_proxy (G_SIMPLE_PROXY_RESOLVER (resolver), + "ftp", "ftp://proxy.example.com"); + + proxies = g_proxy_resolver_lookup (resolver, "http://one.example.com/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "http://proxy.example.com"); + g_strfreev (proxies); + + proxies = g_proxy_resolver_lookup (resolver, "HTTP://uppercase.example.com/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "http://proxy.example.com"); + g_strfreev (proxies); + + proxies = g_proxy_resolver_lookup (resolver, "htt://missing-letter.example.com/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "default://"); + g_strfreev (proxies); + + proxies = g_proxy_resolver_lookup (resolver, "https://extra-letter.example.com/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "default://"); + g_strfreev (proxies); + + proxies = g_proxy_resolver_lookup (resolver, "ftp://five.example.com/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "ftp://proxy.example.com"); + g_strfreev (proxies); + + proxies = g_proxy_resolver_lookup (resolver, "http://127.0.0.1/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "direct://"); + g_strfreev (proxies); + + g_object_unref (resolver); +} + +static void +test_socks (void) +{ + GProxyResolver *resolver; + const gchar *ignore_hosts[2] = { "127.0.0.1", NULL }; + gchar **proxies; + GError *error = NULL; + + resolver = g_simple_proxy_resolver_new ("socks://proxy.example.com", (char **) ignore_hosts); + + proxies = g_proxy_resolver_lookup (resolver, "http://one.example.com/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 3); + g_assert_cmpstr (proxies[0], ==, "socks5://proxy.example.com"); + g_assert_cmpstr (proxies[1], ==, "socks4a://proxy.example.com"); + g_assert_cmpstr (proxies[2], ==, "socks4://proxy.example.com"); + g_strfreev (proxies); + + proxies = g_proxy_resolver_lookup (resolver, "http://127.0.0.1/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "direct://"); + g_strfreev (proxies); + + g_object_unref (resolver); + + resolver = g_simple_proxy_resolver_new ("default-proxy://", (char **) ignore_hosts); + g_simple_proxy_resolver_set_uri_proxy (G_SIMPLE_PROXY_RESOLVER (resolver), + "http", "socks://proxy.example.com"); + + proxies = g_proxy_resolver_lookup (resolver, "http://one.example.com/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 3); + g_assert_cmpstr (proxies[0], ==, "socks5://proxy.example.com"); + g_assert_cmpstr (proxies[1], ==, "socks4a://proxy.example.com"); + g_assert_cmpstr (proxies[2], ==, "socks4://proxy.example.com"); + g_strfreev (proxies); + + proxies = g_proxy_resolver_lookup (resolver, "ftp://two.example.com/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "default-proxy://"); + g_strfreev (proxies); + + proxies = g_proxy_resolver_lookup (resolver, "http://127.0.0.1/", + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (g_strv_length (proxies), ==, 1); + g_assert_cmpstr (proxies[0], ==, "direct://"); + g_strfreev (proxies); + + g_object_unref (resolver); +} + +static const char *ignore_hosts[] = { + ".bbb.xx", + "*.ccc.xx", + "ddd.xx", + "*.eee.xx:8000", + "127.0.0.0/24", + "10.0.0.1:8000", + "::1", + "fe80::/10", + NULL +}; + +static const struct { + const char *uri; + const char *proxy; +} ignore_tests[] = { + { "http://aaa.xx/", "http://localhost:8080" }, + { "http://aaa.xx:8000/", "http://localhost:8080" }, + { "http://www.aaa.xx/", "http://localhost:8080" }, + { "http://www.aaa.xx:8000/", "http://localhost:8080" }, + { "https://aaa.xx/", "http://localhost:8080" }, + { "http://bbb.xx/", "direct://" }, + { "http://www.bbb.xx/", "direct://" }, + { "http://bbb.xx:8000/", "direct://" }, + { "http://www.bbb.xx:8000/", "direct://" }, + { "https://bbb.xx/", "direct://" }, + { "http://nobbb.xx/", "http://localhost:8080" }, + { "http://www.nobbb.xx/", "http://localhost:8080" }, + { "http://nobbb.xx:8000/", "http://localhost:8080" }, + { "http://www.nobbb.xx:8000/", "http://localhost:8080" }, + { "https://nobbb.xx/", "http://localhost:8080" }, + { "http://ccc.xx/", "direct://" }, + { "http://www.ccc.xx/", "direct://" }, + { "http://ccc.xx:8000/", "direct://" }, + { "http://www.ccc.xx:8000/", "direct://" }, + { "https://ccc.xx/", "direct://" }, + { "http://ddd.xx/", "direct://" }, + { "http://ddd.xx:8000/", "direct://" }, + { "http://www.ddd.xx/", "direct://" }, + { "http://www.ddd.xx:8000/", "direct://" }, + { "https://ddd.xx/", "direct://" }, + { "http://eee.xx/", "http://localhost:8080" }, + { "http://eee.xx:8000/", "direct://" }, + { "http://www.eee.xx/", "http://localhost:8080" }, + { "http://www.eee.xx:8000/", "direct://" }, + { "https://eee.xx/", "http://localhost:8080" }, + { "http://1.2.3.4/", "http://localhost:8080" }, + { "http://127.0.0.1/", "direct://" }, + { "http://127.0.0.2/", "direct://" }, + { "http://127.0.0.255/", "direct://" }, + { "http://127.0.1.0/", "http://localhost:8080" }, + { "http://10.0.0.1/", "http://localhost:8080" }, + { "http://10.0.0.1:8000/", "direct://" }, + { "http://[::1]/", "direct://" }, + { "http://[::1]:80/", "direct://" }, + { "http://[::1:1]/", "http://localhost:8080" }, + { "http://[::1:1]:80/", "http://localhost:8080" }, + { "http://[fe80::1]/", "direct://" }, + { "http://[fe80::1]:80/", "direct://" }, + { "http://[fec0::1]/", "http://localhost:8080" }, + { "http://[fec0::1]:80/", "http://localhost:8080" } +}; +static const int n_ignore_tests = G_N_ELEMENTS (ignore_tests); + +static void +test_ignore (void) +{ + GProxyResolver *resolver; + GError *error = NULL; + char **proxies; + int i; + + resolver = g_simple_proxy_resolver_new ("http://localhost:8080", + (char **)ignore_hosts); + + for (i = 0; i < n_ignore_tests; i++) + { + proxies = g_proxy_resolver_lookup (resolver, ignore_tests[i].uri, + NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (proxies[0], ==, ignore_tests[i].proxy); + g_strfreev (proxies); + } + + g_object_unref (resolver); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/static-proxy/uri", test_uris); + g_test_add_func ("/static-proxy/socks", test_socks); + g_test_add_func ("/static-proxy/ignore", test_ignore); + + return g_test_run(); +} diff --git a/gio/tests/sleepy-stream.c b/gio/tests/sleepy-stream.c new file mode 100644 index 0000000..bbbeb25 --- /dev/null +++ b/gio/tests/sleepy-stream.c @@ -0,0 +1,293 @@ +/* + * Copyright © 2009 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Author: Ryan Lortie + */ + +#include +#include + +#define MAX_PIECE_SIZE 100 +#define MAX_PIECES 60 + +static gchar * +cook_piece (void) +{ + char buffer[MAX_PIECE_SIZE * 2]; + gint symbols, i = 0; + + symbols = g_test_rand_int_range (1, MAX_PIECE_SIZE + 1); + + while (symbols--) + { + gint c = g_test_rand_int_range (0, 30); + + switch (c) + { + case 26: + buffer[i++] = '\n'; + G_GNUC_FALLTHROUGH; + case 27: + buffer[i++] = '\r'; + break; + + case 28: + buffer[i++] = '\r'; + G_GNUC_FALLTHROUGH; + case 29: + buffer[i++] = '\n'; + break; + + default: + buffer[i++] = c + 'a'; + break; + } + + g_assert_cmpint (i, <=, sizeof buffer); + } + + return g_strndup (buffer, i); +} + +static gchar ** +cook_pieces (void) +{ + gchar **array; + gint pieces; + + pieces = g_test_rand_int_range (0, MAX_PIECES + 1); + array = g_new (char *, pieces + 1); + array[pieces] = NULL; + + while (pieces--) + array[pieces] = cook_piece (); + + return array; +} + +typedef struct +{ + GInputStream parent_instance; + + gboolean built_to_fail; + gchar **pieces; + gint index; + + const gchar *current; +} SleepyStream; + +typedef GInputStreamClass SleepyStreamClass; + +GType sleepy_stream_get_type (void); + +G_DEFINE_TYPE (SleepyStream, sleepy_stream, G_TYPE_INPUT_STREAM) + +static gssize +sleepy_stream_read (GInputStream *stream, + void *buffer, + gsize length, + GCancellable *cancellable, + GError **error) +{ + SleepyStream *sleepy = (SleepyStream *) stream; + + if (sleepy->pieces[sleepy->index] == NULL) + { + if (sleepy->built_to_fail) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "fail"); + return -1; + } + else + return 0; + } + else + { + if (!sleepy->current) + sleepy->current = sleepy->pieces[sleepy->index++]; + + length = MIN (strlen (sleepy->current), length); + memcpy (buffer, sleepy->current, length); + + sleepy->current += length; + if (*sleepy->current == '\0') + sleepy->current = NULL; + + return length; + } +} + +static void +sleepy_stream_init (SleepyStream *sleepy) +{ + sleepy->pieces = cook_pieces (); + sleepy->built_to_fail = FALSE; + sleepy->index = 0; +} + +static void +sleepy_stream_finalize (GObject *object) +{ + SleepyStream *sleepy = (SleepyStream *) object; + + g_strfreev (sleepy->pieces); + G_OBJECT_CLASS (sleepy_stream_parent_class) + ->finalize (object); +} + +static void +sleepy_stream_class_init (SleepyStreamClass *class) +{ + G_OBJECT_CLASS (class)->finalize = sleepy_stream_finalize; + class->read_fn = sleepy_stream_read; + + /* no read_async implementation. + * main thread will sleep while read runs in a worker. + */ +} + +static SleepyStream * +sleepy_stream_new (void) +{ + return g_object_new (sleepy_stream_get_type (), NULL); +} + +static gboolean +read_line (GDataInputStream *stream, + GString *string, + const gchar *eol, + GError **error) +{ + gsize length; + char *str; + + str = g_data_input_stream_read_line (stream, &length, NULL, error); + + if (str == NULL) + return FALSE; + + g_assert (strstr (str, eol) == NULL); + g_assert (strlen (str) == length); + + g_string_append (string, str); + g_string_append (string, eol); + g_free (str); + + return TRUE; +} + +static void +build_comparison (GString *str, + SleepyStream *stream) +{ + /* build this for comparison */ + gint i; + + for (i = 0; stream->pieces[i]; i++) + g_string_append (str, stream->pieces[i]); + + if (str->len && str->str[str->len - 1] != '\n') + g_string_append_c (str, '\n'); +} + + +static void +test (void) +{ + SleepyStream *stream = sleepy_stream_new (); + GDataInputStream *data; + GError *error = NULL; + GString *one; + GString *two; + + one = g_string_new (NULL); + two = g_string_new (NULL); + + data = g_data_input_stream_new (G_INPUT_STREAM (stream)); + g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_LF); + build_comparison (one, stream); + + while (read_line (data, two, "\n", &error)); + + g_assert_cmpstr (one->str, ==, two->str); + g_string_free (one, TRUE); + g_string_free (two, TRUE); + g_object_unref (stream); + g_object_unref (data); +} + +static GDataInputStream *data; +static GString *one, *two; +static GMainLoop *loop; +static const gchar *eol; + +static void +asynch_ready (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + gsize length; + gchar *str; + + g_assert (data == G_DATA_INPUT_STREAM (object)); + + str = g_data_input_stream_read_line_finish (data, result, &length, &error); + + if (str == NULL) + { + g_main_loop_quit (loop); + if (error) + g_error_free (error); + } + else + { + g_assert (length == strlen (str)); + g_string_append (two, str); + g_string_append (two, eol); + g_free (str); + + /* MOAR!! */ + g_data_input_stream_read_line_async (data, 0, NULL, asynch_ready, NULL); + } +} + + +static void +asynch (void) +{ + SleepyStream *sleepy = sleepy_stream_new (); + + data = g_data_input_stream_new (G_INPUT_STREAM (sleepy)); + one = g_string_new (NULL); + two = g_string_new (NULL); + eol = "\n"; + + build_comparison (one, sleepy); + g_data_input_stream_read_line_async (data, 0, NULL, asynch_ready, NULL); + g_main_loop_run (loop = g_main_loop_new (NULL, FALSE)); + + g_assert_cmpstr (one->str, ==, two->str); + g_string_free (one, TRUE); + g_string_free (two, TRUE); + g_object_unref (sleepy); + g_object_unref (data); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/filter-stream/input", test); + g_test_add_func ("/filter-stream/async", asynch); + + return g_test_run(); +} diff --git a/gio/tests/slow-connect-preload.c b/gio/tests/slow-connect-preload.c new file mode 100644 index 0000000..9fdb431 --- /dev/null +++ b/gio/tests/slow-connect-preload.c @@ -0,0 +1,43 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2018 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include +#include +#include +#include +#include + +/* This is used in gsocketclient-slow.c used to test + * and get coverage on how GSocketClient reacts to + * slow connections. + */ +int +connect (int sockfd, + const struct sockaddr *addr, + socklen_t addrlen) +{ + static int (*real_connect)(int, const struct sockaddr *, socklen_t); + + if (real_connect == NULL) + real_connect = dlsym (RTLD_NEXT, "connect"); + + /* This is long enough for multiple connection attempts to be done + * in parallel given that their timeout is 250ms */ + usleep (600 * 1000); + return real_connect (sockfd, addr, addrlen); +} diff --git a/gio/tests/socket-address.c b/gio/tests/socket-address.c new file mode 100644 index 0000000..b3323c2 --- /dev/null +++ b/gio/tests/socket-address.c @@ -0,0 +1,119 @@ +#include + +static void +test_unix_socket_address_construct (void) +{ + GUnixSocketAddress *a; + + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH); + g_object_unref (a); + + /* Try passing some default values for the arguments explicitly and + * make sure it makes no difference. + */ + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, "address-type", G_UNIX_SOCKET_ADDRESS_PATH, NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH); + g_object_unref (a); + + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, "abstract", FALSE, NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH); + g_object_unref (a); + + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, + "abstract", FALSE, + "address-type", G_UNIX_SOCKET_ADDRESS_PATH, + NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH); + g_object_unref (a); + + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, + "address-type", G_UNIX_SOCKET_ADDRESS_PATH, + "abstract", FALSE, + NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_PATH); + g_object_unref (a); + + /* Try explicitly setting abstract to TRUE */ + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, + "abstract", TRUE, + NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED); + g_object_unref (a); + + /* Try explicitly setting a different kind of address */ + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, + "address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS, + NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + g_object_unref (a); + + /* Now try explicitly setting a different type of address after + * setting abstract to FALSE. + */ + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, + "abstract", FALSE, + "address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS, + NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + g_object_unref (a); + + /* And the other way around */ + a = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS, + "address-type", G_UNIX_SOCKET_ADDRESS_ANONYMOUS, + "abstract", FALSE, + NULL); + g_assert_cmpint (g_unix_socket_address_get_address_type (a), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + g_object_unref (a); +} + +static void +test_unix_socket_address_to_string (void) +{ + GSocketAddress *addr = NULL; + gchar *str = NULL; + + /* ADDRESS_PATH. */ + addr = g_unix_socket_address_new_with_type ("/some/path", -1, + G_UNIX_SOCKET_ADDRESS_PATH); + str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr)); + g_assert_cmpstr (str, ==, "/some/path"); + g_free (str); + g_object_unref (addr); + + /* ADDRESS_ANONYMOUS. */ + addr = g_unix_socket_address_new_with_type ("", 0, + G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr)); + g_assert_cmpstr (str, ==, "anonymous"); + g_free (str); + g_object_unref (addr); + + /* ADDRESS_ABSTRACT. */ + addr = g_unix_socket_address_new_with_type ("abstract-path\0✋", 17, + G_UNIX_SOCKET_ADDRESS_ABSTRACT); + str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr)); + g_assert_cmpstr (str, ==, "abstract-path\\x00\\xe2\\x9c\\x8b"); + g_free (str); + g_object_unref (addr); + + /* ADDRESS_ABSTRACT_PADDED. */ + addr = g_unix_socket_address_new_with_type ("abstract-path\0✋", 17, + G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED); + str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (addr)); + g_assert_cmpstr (str, ==, "abstract-path\\x00\\xe2\\x9c\\x8b"); + g_free (str); + g_object_unref (addr); +} + +int +main (int argc, + char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/socket/address/unix/construct", test_unix_socket_address_construct); + g_test_add_func ("/socket/address/unix/to-string", test_unix_socket_address_to_string); + + return g_test_run (); +} diff --git a/gio/tests/socket-client.c b/gio/tests/socket-client.c new file mode 100644 index 0000000..6c25e08 --- /dev/null +++ b/gio/tests/socket-client.c @@ -0,0 +1,444 @@ +#include +#include +#include +#include +#include +#include + +#include "gtlsconsoleinteraction.h" + +GMainLoop *loop; + +gboolean verbose = FALSE; +gboolean non_blocking = FALSE; +gboolean use_udp = FALSE; +int cancel_timeout = 0; +int read_timeout = 0; +gboolean unix_socket = FALSE; +gboolean tls = FALSE; + +static GOptionEntry cmd_entries[] = { + {"cancel", 'c', 0, G_OPTION_ARG_INT, &cancel_timeout, + "Cancel any op after the specified amount of seconds", NULL}, + {"udp", 'u', 0, G_OPTION_ARG_NONE, &use_udp, + "Use udp instead of tcp", NULL}, + {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, + "Be verbose", NULL}, + {"non-blocking", 'n', 0, G_OPTION_ARG_NONE, &non_blocking, + "Enable non-blocking i/o", NULL}, +#ifdef G_OS_UNIX + {"unix", 'U', 0, G_OPTION_ARG_NONE, &unix_socket, + "Use a unix socket instead of IP", NULL}, +#endif + {"timeout", 't', 0, G_OPTION_ARG_INT, &read_timeout, + "Time out reads after the specified number of seconds", NULL}, + {"tls", 'T', 0, G_OPTION_ARG_NONE, &tls, + "Use TLS (SSL)", NULL}, + G_OPTION_ENTRY_NULL +}; + +#include "socket-common.c" + +static gboolean +accept_certificate (GTlsClientConnection *conn, + GTlsCertificate *cert, + GTlsCertificateFlags errors, + gpointer user_data) +{ + g_print ("Certificate would have been rejected ( "); + if (errors & G_TLS_CERTIFICATE_UNKNOWN_CA) + g_print ("unknown-ca "); + if (errors & G_TLS_CERTIFICATE_BAD_IDENTITY) + g_print ("bad-identity "); + if (errors & G_TLS_CERTIFICATE_NOT_ACTIVATED) + g_print ("not-activated "); + if (errors & G_TLS_CERTIFICATE_EXPIRED) + g_print ("expired "); + if (errors & G_TLS_CERTIFICATE_REVOKED) + g_print ("revoked "); + if (errors & G_TLS_CERTIFICATE_INSECURE) + g_print ("insecure "); + g_print (") but accepting anyway.\n"); + + return TRUE; +} + +static GTlsCertificate * +lookup_client_certificate (GTlsClientConnection *conn, + GError **error) +{ + GList *l, *accepted; + GList *c, *certificates; + GTlsDatabase *database; + GTlsCertificate *certificate = NULL; + GTlsConnection *base; + + accepted = g_tls_client_connection_get_accepted_cas (conn); + for (l = accepted; l != NULL; l = g_list_next (l)) + { + base = G_TLS_CONNECTION (conn); + database = g_tls_connection_get_database (base); + certificates = g_tls_database_lookup_certificates_issued_by (database, l->data, + g_tls_connection_get_interaction (base), + G_TLS_DATABASE_LOOKUP_KEYPAIR, + NULL, error); + if (error && *error) + break; + + if (certificates) + certificate = g_object_ref (certificates->data); + + for (c = certificates; c != NULL; c = g_list_next (c)) + g_object_unref (c->data); + g_list_free (certificates); + } + + for (l = accepted; l != NULL; l = g_list_next (l)) + g_byte_array_unref (l->data); + g_list_free (accepted); + + if (certificate == NULL && error && !*error) + g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED, + "Server requested a certificate, but could not find relevant certificate in database."); + return certificate; +} + +static gboolean +make_connection (const char *argument, + GTlsCertificate *certificate, + GCancellable *cancellable, + GSocket **socket, + GSocketAddress **address, + GIOStream **connection, + GInputStream **istream, + GOutputStream **ostream, + GError **error) +{ + GSocketType socket_type; + GSocketFamily socket_family; + GSocketAddressEnumerator *enumerator; + GSocketConnectable *connectable; + GSocketAddress *src_address; + GTlsInteraction *interaction; + GError *err = NULL; + + if (use_udp) + socket_type = G_SOCKET_TYPE_DATAGRAM; + else + socket_type = G_SOCKET_TYPE_STREAM; + + if (unix_socket) + socket_family = G_SOCKET_FAMILY_UNIX; + else + socket_family = G_SOCKET_FAMILY_IPV4; + + *socket = g_socket_new (socket_family, socket_type, 0, error); + if (*socket == NULL) + return FALSE; + + if (read_timeout) + g_socket_set_timeout (*socket, read_timeout); + + if (unix_socket) + { + GSocketAddress *addr; + + addr = socket_address_from_string (argument); + if (addr == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Could not parse '%s' as unix socket name", argument); + return FALSE; + } + connectable = G_SOCKET_CONNECTABLE (addr); + } + else + { + connectable = g_network_address_parse (argument, 7777, error); + if (connectable == NULL) + return FALSE; + } + + enumerator = g_socket_connectable_enumerate (connectable); + while (TRUE) + { + *address = g_socket_address_enumerator_next (enumerator, cancellable, error); + if (*address == NULL) + { + if (error != NULL && *error == NULL) + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No more addresses to try"); + return FALSE; + } + + if (g_socket_connect (*socket, *address, cancellable, &err)) + break; + g_message ("Connection to %s failed: %s, trying next", socket_address_to_string (*address), err->message); + g_clear_error (&err); + + g_object_unref (*address); + } + g_object_unref (enumerator); + + g_print ("Connected to %s\n", + socket_address_to_string (*address)); + + src_address = g_socket_get_local_address (*socket, error); + if (!src_address) + { + g_prefix_error (error, "Error getting local address: "); + return FALSE; + } + + g_print ("local address: %s\n", + socket_address_to_string (src_address)); + g_object_unref (src_address); + + if (use_udp) + { + *connection = NULL; + *istream = NULL; + *ostream = NULL; + } + else + *connection = G_IO_STREAM (g_socket_connection_factory_create_connection (*socket)); + + if (tls) + { + GIOStream *tls_conn; + + tls_conn = g_tls_client_connection_new (*connection, connectable, error); + if (!tls_conn) + { + g_prefix_error (error, "Could not create TLS connection: "); + return FALSE; + } + + g_signal_connect (tls_conn, "accept-certificate", + G_CALLBACK (accept_certificate), NULL); + + interaction = g_tls_console_interaction_new (); + g_tls_connection_set_interaction (G_TLS_CONNECTION (tls_conn), interaction); + g_object_unref (interaction); + + if (certificate) + g_tls_connection_set_certificate (G_TLS_CONNECTION (tls_conn), certificate); + + g_object_unref (*connection); + *connection = G_IO_STREAM (tls_conn); + + if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn), + cancellable, error)) + { + g_prefix_error (error, "Error during TLS handshake: "); + return FALSE; + } + } + g_object_unref (connectable); + + if (*connection) + { + *istream = g_io_stream_get_input_stream (*connection); + *ostream = g_io_stream_get_output_stream (*connection); + } + + return TRUE; +} + +int +main (int argc, + char *argv[]) +{ + GSocket *socket; + GSocketAddress *address; + GError *error = NULL; + GOptionContext *context; + GCancellable *cancellable; + GIOStream *connection; + GInputStream *istream; + GOutputStream *ostream; + GSocketAddress *src_address; + GTlsCertificate *certificate = NULL; + gint i; + + address = NULL; + connection = NULL; + + context = g_option_context_new (" [:port] - Test GSocket client stuff"); + g_option_context_add_main_entries (context, cmd_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + if (argc != 2) + { + g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name"); + return 1; + } + + if (use_udp && tls) + { + g_printerr ("DTLS (TLS over UDP) is not supported"); + return 1; + } + + if (cancel_timeout) + { + GThread *thread; + cancellable = g_cancellable_new (); + thread = g_thread_new ("cancel", cancel_thread, cancellable); + g_thread_unref (thread); + } + else + { + cancellable = NULL; + } + + loop = g_main_loop_new (NULL, FALSE); + + for (i = 0; i < 2; i++) + { + if (make_connection (argv[1], certificate, cancellable, &socket, &address, + &connection, &istream, &ostream, &error)) + break; + + if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED)) + { + g_clear_error (&error); + certificate = lookup_client_certificate (G_TLS_CLIENT_CONNECTION (connection), &error); + if (certificate != NULL) + continue; + } + + g_printerr ("%s: %s", argv[0], error->message); + return 1; + } + + /* TODO: Test non-blocking connect/handshake */ + if (non_blocking) + g_socket_set_blocking (socket, FALSE); + + while (TRUE) + { + gchar buffer[4096]; + gssize size; + gsize to_send; + + if (fgets (buffer, sizeof buffer, stdin) == NULL) + break; + + to_send = strlen (buffer); + while (to_send > 0) + { + if (use_udp) + { + ensure_socket_condition (socket, G_IO_OUT, cancellable); + size = g_socket_send_to (socket, address, + buffer, to_send, + cancellable, &error); + } + else + { + ensure_connection_condition (connection, G_IO_OUT, cancellable); + size = g_output_stream_write (ostream, + buffer, to_send, + cancellable, &error); + } + + if (size < 0) + { + if (g_error_matches (error, + G_IO_ERROR, + G_IO_ERROR_WOULD_BLOCK)) + { + g_print ("socket send would block, handling\n"); + g_error_free (error); + error = NULL; + continue; + } + else + { + g_printerr ("Error sending to socket: %s\n", + error->message); + return 1; + } + } + + g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size); + + if (size == 0) + { + g_printerr ("Unexpected short write\n"); + return 1; + } + + to_send -= size; + } + + if (use_udp) + { + ensure_socket_condition (socket, G_IO_IN, cancellable); + size = g_socket_receive_from (socket, &src_address, + buffer, sizeof buffer, + cancellable, &error); + } + else + { + ensure_connection_condition (connection, G_IO_IN, cancellable); + size = g_input_stream_read (istream, + buffer, sizeof buffer, + cancellable, &error); + } + + if (size < 0) + { + g_printerr ("Error receiving from socket: %s\n", + error->message); + return 1; + } + + if (size == 0) + break; + + g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size); + if (use_udp) + g_print (" from %s", socket_address_to_string (src_address)); + g_print ("\n"); + + if (verbose) + g_print ("-------------------------\n" + "%.*s" + "-------------------------\n", + (int)size, buffer); + + } + + g_print ("closing socket\n"); + + if (connection) + { + if (!g_io_stream_close (connection, cancellable, &error)) + { + g_printerr ("Error closing connection: %s\n", + error->message); + return 1; + } + g_object_unref (connection); + } + else + { + if (!g_socket_close (socket, &error)) + { + g_printerr ("Error closing socket: %s\n", + error->message); + return 1; + } + } + + g_object_unref (socket); + g_object_unref (address); + + return 0; +} diff --git a/gio/tests/socket-common.c b/gio/tests/socket-common.c new file mode 100644 index 0000000..18d083a --- /dev/null +++ b/gio/tests/socket-common.c @@ -0,0 +1,123 @@ +/* #included into both socket-client.c and socket-server.c */ + +#ifdef G_OS_UNIX +static const char *unix_socket_address_types[] = { + "invalid", + "anonymous", + "path", + "abstract", + "padded" +}; +#endif + +static char * +socket_address_to_string (GSocketAddress *address) +{ + char *res = NULL; + + if (G_IS_INET_SOCKET_ADDRESS (address)) + { + GInetAddress *inet_address; + char *str; + int port; + + inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)); + str = g_inet_address_to_string (inet_address); + port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); + res = g_strdup_printf ("%s:%d", str, port); + g_free (str); + } +#ifdef G_OS_UNIX + else if (G_IS_UNIX_SOCKET_ADDRESS (address)) + { + GUnixSocketAddress *uaddr = G_UNIX_SOCKET_ADDRESS (address); + + res = g_strdup_printf ("%s:%s", + unix_socket_address_types[g_unix_socket_address_get_address_type (uaddr)], + g_unix_socket_address_get_path (uaddr)); + } +#endif + + return res; +} + +static GSocketAddress * +socket_address_from_string (const char *name) +{ +#ifdef G_OS_UNIX + gsize i, len; + + for (i = 0; i < G_N_ELEMENTS (unix_socket_address_types); i++) + { + len = strlen (unix_socket_address_types[i]); + if (!strncmp (name, unix_socket_address_types[i], len) && + name[len] == ':') + { + return g_unix_socket_address_new_with_type (name + len + 1, -1, + (GUnixSocketAddressType)i); + } + } +#endif + return NULL; +} + +static gboolean +source_ready (GPollableInputStream *stream, + gpointer data) +{ + g_main_loop_quit (loop); + return FALSE; +} + +static void +ensure_socket_condition (GSocket *socket, + GIOCondition condition, + GCancellable *cancellable) +{ + GSource *source; + + if (!non_blocking) + return; + + source = g_socket_create_source (socket, condition, cancellable); + g_source_set_callback (source, + (GSourceFunc) source_ready, + NULL, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + g_main_loop_run (loop); +} + +static void +ensure_connection_condition (GIOStream *stream, + GIOCondition condition, + GCancellable *cancellable) +{ + GSource *source; + + if (!non_blocking) + return; + + if (condition & G_IO_IN) + source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (stream)), cancellable); + else + source = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (stream)), cancellable); + + g_source_set_callback (source, + (GSourceFunc) source_ready, + NULL, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + g_main_loop_run (loop); +} + +static gpointer +cancel_thread (gpointer data) +{ + GCancellable *cancellable = data; + + g_usleep (1000*1000*cancel_timeout); + g_print ("Cancelling\n"); + g_cancellable_cancel (cancellable); + return NULL; +} diff --git a/gio/tests/socket-listener.c b/gio/tests/socket-listener.c new file mode 100644 index 0000000..6ceed13 --- /dev/null +++ b/gio/tests/socket-listener.c @@ -0,0 +1,92 @@ +/* GLib testing framework examples and tests + * + * Copyright 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * . + */ + +#include + +static void +event_cb (GSocketListener *listener, + GSocketListenerEvent event, + GSocket *socket, + gpointer data) +{ + static GSocketListenerEvent expected_event = G_SOCKET_LISTENER_BINDING; + gboolean *success = (gboolean *)data; + + g_assert (G_IS_SOCKET_LISTENER (listener)); + g_assert (G_IS_SOCKET (socket)); + g_assert (event == expected_event); + + switch (event) + { + case G_SOCKET_LISTENER_BINDING: + expected_event = G_SOCKET_LISTENER_BOUND; + break; + case G_SOCKET_LISTENER_BOUND: + expected_event = G_SOCKET_LISTENER_LISTENING; + break; + case G_SOCKET_LISTENER_LISTENING: + expected_event = G_SOCKET_LISTENER_LISTENED; + break; + case G_SOCKET_LISTENER_LISTENED: + *success = TRUE; + break; + } +} + +static void +test_event_signal (void) +{ + gboolean success = FALSE; + GInetAddress *iaddr; + GSocketAddress *saddr; + GSocketListener *listener; + GError *error = NULL; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + listener = g_socket_listener_new (); + + g_signal_connect (listener, "event", G_CALLBACK (event_cb), &success); + + g_socket_listener_add_address (listener, + saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert_true (success); + + g_object_unref (saddr); + g_object_unref (listener); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/socket-listener/event-signal", test_event_signal); + + return g_test_run(); +} diff --git a/gio/tests/socket-server.c b/gio/tests/socket-server.c new file mode 100644 index 0000000..8b0d2a9 --- /dev/null +++ b/gio/tests/socket-server.c @@ -0,0 +1,366 @@ +#include +#include +#include +#include +#include + +GMainLoop *loop; + +int port = 7777; +gboolean verbose = FALSE; +gboolean dont_reuse_address = FALSE; +gboolean non_blocking = FALSE; +gboolean use_udp = FALSE; +int cancel_timeout = 0; +int read_timeout = 0; +int delay = 0; +gboolean unix_socket = FALSE; +const char *tls_cert_file = NULL; + +static GOptionEntry cmd_entries[] = { + {"port", 'p', 0, G_OPTION_ARG_INT, &port, + "Local port to bind to", NULL}, + {"cancel", 'c', 0, G_OPTION_ARG_INT, &cancel_timeout, + "Cancel any op after the specified amount of seconds", NULL}, + {"udp", 'u', 0, G_OPTION_ARG_NONE, &use_udp, + "Use udp instead of tcp", NULL}, + {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, + "Be verbose", NULL}, + {"no-reuse", 0, 0, G_OPTION_ARG_NONE, &dont_reuse_address, + "Don't SOADDRREUSE", NULL}, + {"non-blocking", 'n', 0, G_OPTION_ARG_NONE, &non_blocking, + "Enable non-blocking i/o", NULL}, +#ifdef G_OS_UNIX + {"unix", 'U', 0, G_OPTION_ARG_NONE, &unix_socket, + "Use a unix socket instead of IP", NULL}, +#endif + {"delay", 'd', 0, G_OPTION_ARG_INT, &delay, + "Delay responses by the specified number of seconds", NULL}, + {"timeout", 't', 0, G_OPTION_ARG_INT, &read_timeout, + "Time out reads after the specified number of seconds", NULL}, + {"tls", 'T', 0, G_OPTION_ARG_STRING, &tls_cert_file, + "Use TLS (SSL) with indicated server certificate", "CERTFILE"}, + G_OPTION_ENTRY_NULL +}; + +#include "socket-common.c" + +int +main (int argc, + char *argv[]) +{ + GSocket *socket, *new_socket, *recv_socket; + GSocketAddress *src_address; + GSocketAddress *address; + GSocketType socket_type; + GSocketFamily socket_family; + GError *error = NULL; + GOptionContext *context; + GCancellable *cancellable; + char *display_addr; + GTlsCertificate *tlscert = NULL; + GIOStream *connection; + GInputStream *istream; + GOutputStream *ostream; + + context = g_option_context_new (" - Test GSocket server stuff"); + g_option_context_add_main_entries (context, cmd_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + if (unix_socket && argc != 2) + { + g_printerr ("%s: %s\n", argv[0], "Need to specify unix socket name"); + return 1; + } + + if (cancel_timeout) + { + GThread *thread; + cancellable = g_cancellable_new (); + thread = g_thread_new ("cancel", cancel_thread, cancellable); + g_thread_unref (thread); + } + else + { + cancellable = NULL; + } + + if (tls_cert_file) + { + if (use_udp) + { + g_printerr ("DTLS (TLS over UDP) is not supported"); + return 1; + } + + tlscert = g_tls_certificate_new_from_file (tls_cert_file, &error); + if (!tlscert) + { + g_printerr ("Could not read server certificate '%s': %s\n", + tls_cert_file, error->message); + return 1; + } + } + + loop = g_main_loop_new (NULL, FALSE); + + if (use_udp) + socket_type = G_SOCKET_TYPE_DATAGRAM; + else + socket_type = G_SOCKET_TYPE_STREAM; + + if (unix_socket) + socket_family = G_SOCKET_FAMILY_UNIX; + else + socket_family = G_SOCKET_FAMILY_IPV4; + + socket = g_socket_new (socket_family, socket_type, 0, &error); + + if (socket == NULL) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + if (non_blocking) + g_socket_set_blocking (socket, FALSE); + + if (unix_socket) + { + src_address = socket_address_from_string (argv[1]); + if (src_address == NULL) + { + g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]); + return 1; + } + } + else + { + src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port); + } + + if (!g_socket_bind (socket, src_address, !dont_reuse_address, &error)) + { + g_printerr ("Can't bind socket: %s\n", error->message); + return 1; + } + g_object_unref (src_address); + + if (!use_udp) + { + if (!g_socket_listen (socket, &error)) + { + g_printerr ("Can't listen on socket: %s\n", error->message); + return 1; + } + + address = g_socket_get_local_address (socket, &error); + if (!address) + { + g_printerr ("Error getting local address: %s\n", + error->message); + return 1; + } + display_addr = socket_address_to_string (address); + g_print ("listening on %s...\n", display_addr); + g_free (display_addr); + + ensure_socket_condition (socket, G_IO_IN, cancellable); + new_socket = g_socket_accept (socket, cancellable, &error); + if (!new_socket) + { + g_printerr ("Error accepting socket: %s\n", + error->message); + return 1; + } + + if (non_blocking) + g_socket_set_blocking (new_socket, FALSE); + if (read_timeout) + g_socket_set_timeout (new_socket, read_timeout); + + address = g_socket_get_remote_address (new_socket, &error); + if (!address) + { + g_printerr ("Error getting remote address: %s\n", + error->message); + return 1; + } + + display_addr = socket_address_to_string (address); + g_print ("got a new connection from %s\n", display_addr); + g_free(display_addr); + g_object_unref (address); + + recv_socket = new_socket; + + connection = G_IO_STREAM (g_socket_connection_factory_create_connection (recv_socket)); + g_object_unref (new_socket); + } + else + { + recv_socket = socket; + connection = NULL; + } + + if (tlscert) + { + GIOStream *tls_conn; + + tls_conn = g_tls_server_connection_new (connection, tlscert, &error); + if (!tls_conn) + { + g_printerr ("Could not create TLS connection: %s\n", + error->message); + return 1; + } + + if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn), + cancellable, &error)) + { + g_printerr ("Error during TLS handshake: %s\n", + error->message); + return 1; + } + + g_object_unref (connection); + connection = tls_conn; + } + + if (connection) + { + istream = g_io_stream_get_input_stream (connection); + ostream = g_io_stream_get_output_stream (connection); + } + else + { + g_assert (use_udp); + istream = NULL; + ostream = NULL; + } + + while (TRUE) + { + gchar buffer[4096]; + gssize size; + gsize to_send; + + if (use_udp) + { + ensure_socket_condition (recv_socket, G_IO_IN, cancellable); + size = g_socket_receive_from (recv_socket, &address, + buffer, sizeof buffer, + cancellable, &error); + } + else + { + ensure_connection_condition (connection, G_IO_IN, cancellable); + size = g_input_stream_read (istream, + buffer, sizeof buffer, + cancellable, &error); + } + + if (size < 0) + { + g_printerr ("Error receiving from socket: %s\n", + error->message); + return 1; + } + + if (size == 0) + break; + + g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size); + if (use_udp) + g_print (" from %s", socket_address_to_string (address)); + g_print ("\n"); + + if (verbose) + g_print ("-------------------------\n" + "%.*s\n" + "-------------------------\n", + (int)size, buffer); + + to_send = size; + + if (delay) + { + if (verbose) + g_print ("delaying %d seconds before response\n", delay); + g_usleep (1000 * 1000 * delay); + } + + while (to_send > 0) + { + if (use_udp) + { + ensure_socket_condition (recv_socket, G_IO_OUT, cancellable); + size = g_socket_send_to (recv_socket, address, + buffer, to_send, cancellable, &error); + } + else + { + ensure_connection_condition (connection, G_IO_OUT, cancellable); + size = g_output_stream_write (ostream, + buffer, to_send, + cancellable, &error); + } + + if (size < 0) + { + if (g_error_matches (error, + G_IO_ERROR, + G_IO_ERROR_WOULD_BLOCK)) + { + g_print ("socket send would block, handling\n"); + g_error_free (error); + error = NULL; + continue; + } + else + { + g_printerr ("Error sending to socket: %s\n", + error->message); + return 1; + } + } + + g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size); + + if (size == 0) + { + g_printerr ("Unexpected short write\n"); + return 1; + } + + to_send -= size; + } + } + + g_print ("connection closed\n"); + + if (connection) + { + if (!g_io_stream_close (connection, NULL, &error)) + { + g_printerr ("Error closing connection stream: %s\n", + error->message); + return 1; + } + g_object_unref (connection); + } + + if (!g_socket_close (socket, &error)) + { + g_printerr ("Error closing socket: %s\n", + error->message); + return 1; + } + g_object_unref (socket); + + return 0; +} diff --git a/gio/tests/socket-service.c b/gio/tests/socket-service.c new file mode 100644 index 0000000..a00c0c4 --- /dev/null +++ b/gio/tests/socket-service.c @@ -0,0 +1,566 @@ +/* GLib testing framework examples and tests + * + * Copyright 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * . + */ + +#include + +static void +active_notify_cb (GSocketService *service, + GParamSpec *pspec, + gpointer data) +{ + gboolean *success = (gboolean *)data; + + if (g_socket_service_is_active (service)) + *success = TRUE; +} + +static void +connected_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketService *service = G_SOCKET_SERVICE (user_data); + GSocketConnection *conn; + GError *error = NULL; + + g_assert_true (g_socket_service_is_active (service)); + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_object_unref (conn); + + g_socket_service_stop (service); + g_assert_false (g_socket_service_is_active (service)); +} + +static void +test_start_stop (void) +{ + gboolean success = FALSE; + GInetAddress *iaddr; + GSocketAddress *saddr, *listening_addr; + GSocketService *service; + GError *error = NULL; + GSocketClient *client; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + /* instantiate with g_object_new so we can pass active = false */ + service = g_object_new (G_TYPE_SOCKET_SERVICE, "active", FALSE, NULL); + g_assert_false (g_socket_service_is_active (service)); + + g_signal_connect (service, "notify::active", G_CALLBACK (active_notify_cb), &success); + + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (saddr); + + client = g_socket_client_new (); + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_cb, service); + g_object_unref (client); + g_object_unref (listening_addr); + + g_socket_service_start (service); + g_assert_true (g_socket_service_is_active (service)); + + do + g_main_context_iteration (NULL, TRUE); + while (!success); + + g_object_unref (service); +} + +GMutex mutex_712570; +GCond cond_712570; +gboolean finalized; /* (atomic) */ + +GType test_threaded_socket_service_get_type (void); +typedef GThreadedSocketService TestThreadedSocketService; +typedef GThreadedSocketServiceClass TestThreadedSocketServiceClass; + +G_DEFINE_TYPE (TestThreadedSocketService, test_threaded_socket_service, G_TYPE_THREADED_SOCKET_SERVICE) + +static void +test_threaded_socket_service_init (TestThreadedSocketService *service) +{ +} + +static void +test_threaded_socket_service_finalize (GObject *object) +{ + G_OBJECT_CLASS (test_threaded_socket_service_parent_class)->finalize (object); + + /* Signal the main thread that finalization completed successfully + * rather than hanging. + */ + g_atomic_int_set (&finalized, TRUE); + g_cond_signal (&cond_712570); + g_mutex_unlock (&mutex_712570); +} + +static void +test_threaded_socket_service_class_init (TestThreadedSocketServiceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = test_threaded_socket_service_finalize; +} + +static gboolean +connection_cb (GThreadedSocketService *service, + GSocketConnection *connection, + GObject *source_object, + gpointer user_data) +{ + GMainLoop *loop = user_data; + + /* Since the connection attempt has come through to be handled, stop the main + * thread waiting for it; this causes the #GSocketService to be stopped. */ + g_main_loop_quit (loop); + + /* Block until the main thread has dropped its ref to @service, so that we + * will drop the final ref from this thread. + */ + g_mutex_lock (&mutex_712570); + + /* The service should now have 1 ref owned by the current "run" + * signal emission, and another added by GThreadedSocketService for + * this thread. Both will be dropped after we return. + */ + g_assert_cmpint (G_OBJECT (service)->ref_count, ==, 2); + + return FALSE; +} + +static void +client_connected_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GError *error = NULL; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + + g_object_unref (conn); +} + +static void +test_threaded_712570 (void) +{ + GSocketService *service; + GSocketAddress *addr, *listening_addr; + GMainLoop *loop; + GSocketClient *client; + GError *error = NULL; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=712570"); + + g_mutex_lock (&mutex_712570); + + service = g_object_new (test_threaded_socket_service_get_type (), NULL); + + addr = g_inet_socket_address_new_from_string ("127.0.0.1", 0); + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + addr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (addr); + + loop = g_main_loop_new (NULL, FALSE); + g_signal_connect (service, "run", G_CALLBACK (connection_cb), loop); + + client = g_socket_client_new (); + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + client_connected_cb, loop); + g_object_unref (client); + g_object_unref (listening_addr); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + /* Stop the service and then wait for it to asynchronously cancel + * its outstanding accept() call (and drop the associated ref). + * At least one main context iteration is required in some circumstances + * to ensure that the cancellation actually happens. + */ + g_socket_service_stop (G_SOCKET_SERVICE (service)); + g_assert_false (g_socket_service_is_active (G_SOCKET_SERVICE (service))); + + do + g_main_context_iteration (NULL, TRUE); + while (G_OBJECT (service)->ref_count > 3); + + /* Wait some more iterations, as #GTask results are deferred to the next + * #GMainContext iteration, and propagation of a #GTask result takes an + * additional ref on the source object. */ + g_main_context_iteration (NULL, FALSE); + + /* Drop our ref, then unlock the mutex and wait for the service to be + * finalized. (Without the fix for 712570 it would hang forever here.) + */ + g_object_unref (service); + + while (!g_atomic_int_get (&finalized)) + g_cond_wait (&cond_712570, &mutex_712570); + g_mutex_unlock (&mutex_712570); +} + +static void +closed_read_write_async_cb (GSocketConnection *conn, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + gboolean res; + + res = g_io_stream_close_finish (G_IO_STREAM (conn), result, &error); + g_assert_no_error (error); + g_assert_true (res); +} + +typedef struct { + GSocketConnection *conn; + guint8 *data; +} WriteAsyncData; + +static void +written_read_write_async_cb (GOutputStream *ostream, + GAsyncResult *result, + gpointer user_data) +{ + WriteAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_written; + GSocketConnection *conn; + + conn = data->conn; + + g_free (data->data); + g_free (data); + + res = g_output_stream_write_all_finish (ostream, result, &bytes_written, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (bytes_written, ==, 20); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +connected_read_write_async_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GOutputStream *ostream; + GError *error = NULL; + WriteAsyncData *data; + gsize i; + GSocketConnection **sconn = user_data; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_assert_nonnull (conn); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (conn)); + + data = g_new0 (WriteAsyncData, 1); + data->conn = conn; + data->data = g_new0 (guint8, 20); + for (i = 0; i < 20; i++) + data->data[i] = i; + + g_output_stream_write_all_async (ostream, + data->data, + 20, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) written_read_write_async_cb, + data /* stolen */); + + *sconn = g_object_ref (conn); +} + +typedef struct { + GSocketConnection *conn; + GOutputVector *vectors; + guint n_vectors; + guint8 *data; +} WritevAsyncData; + +static void +writtenv_read_write_async_cb (GOutputStream *ostream, + GAsyncResult *result, + gpointer user_data) +{ + WritevAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_written; + GSocketConnection *conn; + + conn = data->conn; + g_free (data->data); + g_free (data->vectors); + g_free (data); + + res = g_output_stream_writev_all_finish (ostream, result, &bytes_written, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (bytes_written, ==, 20); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +connected_read_writev_async_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GOutputStream *ostream; + GError *error = NULL; + WritevAsyncData *data; + gsize i; + GSocketConnection **sconn = user_data; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_assert_nonnull (conn); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (conn)); + + data = g_new0 (WritevAsyncData, 1); + data->conn = conn; + data->vectors = g_new0 (GOutputVector, 3); + data->n_vectors = 3; + data->data = g_new0 (guint8, 20); + for (i = 0; i < 20; i++) + data->data[i] = i; + + data->vectors[0].buffer = data->data; + data->vectors[0].size = 5; + data->vectors[1].buffer = data->data + 5; + data->vectors[1].size = 10; + data->vectors[2].buffer = data->data + 15; + data->vectors[2].size = 5; + + g_output_stream_writev_all_async (ostream, + data->vectors, + data->n_vectors, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) writtenv_read_write_async_cb, + data /* stolen */); + + *sconn = g_object_ref (conn); +} + +typedef struct { + GSocketConnection *conn; + guint8 *data; +} ReadAsyncData; + +static void +read_read_write_async_cb (GInputStream *istream, + GAsyncResult *result, + gpointer user_data) +{ + ReadAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_read; + GSocketConnection *conn; + const guint8 expected_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + + res = g_input_stream_read_all_finish (istream, result, &bytes_read, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_assert_cmpmem (expected_data, sizeof expected_data, data->data, bytes_read); + + conn = data->conn; + g_object_set_data (G_OBJECT (conn), "test-data-read", GINT_TO_POINTER (TRUE)); + + g_free (data->data); + g_free (data); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +incoming_read_write_async_cb (GSocketService *service, + GSocketConnection *conn, + GObject *source_object, + gpointer user_data) +{ + ReadAsyncData *data; + GSocketConnection **cconn = user_data; + GInputStream *istream; + + istream = g_io_stream_get_input_stream (G_IO_STREAM (conn)); + + data = g_new0 (ReadAsyncData, 1); + data->conn = g_object_ref (conn); + data->data = g_new0 (guint8, 20); + + g_input_stream_read_all_async (istream, + data->data, + 20, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) read_read_write_async_cb, + data /* stolen */); + + *cconn = g_object_ref (conn); +} + +static void +test_read_write_async_internal (gboolean writev) +{ + GInetAddress *iaddr; + GSocketAddress *saddr, *listening_addr; + GSocketService *service; + GError *error = NULL; + GSocketClient *client; + GSocketConnection *sconn = NULL, *cconn = NULL; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + service = g_socket_service_new (); + + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (saddr); + + g_signal_connect (service, "incoming", G_CALLBACK (incoming_read_write_async_cb), &sconn); + + client = g_socket_client_new (); + + if (writev) + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_read_writev_async_cb, + &cconn); + else + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_read_write_async_cb, + &cconn); + + g_object_unref (client); + g_object_unref (listening_addr); + + g_socket_service_start (service); + g_assert_true (g_socket_service_is_active (service)); + + do + { + g_main_context_iteration (NULL, TRUE); + } + while (!sconn || !cconn || + !g_io_stream_is_closed (G_IO_STREAM (sconn)) || + !g_io_stream_is_closed (G_IO_STREAM (cconn))); + + g_assert_true (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (sconn), "test-data-read"))); + + g_object_unref (sconn); + g_object_unref (cconn); + g_object_unref (service); +} + +/* Test if connecting to a socket service and asynchronously writing data on + * one side followed by reading the same data on the other side of the + * connection works correctly + */ +static void +test_read_write_async (void) +{ + test_read_write_async_internal (FALSE); +} + +/* Test if connecting to a socket service and asynchronously writing data on + * one side followed by reading the same data on the other side of the + * connection works correctly. This uses writev() instead of normal write(). + */ +static void +test_read_writev_async (void) +{ + test_read_write_async_internal (TRUE); +} + + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/socket-service/start-stop", test_start_stop); + g_test_add_func ("/socket-service/threaded/712570", test_threaded_712570); + g_test_add_func ("/socket-service/read_write_async", test_read_write_async); + g_test_add_func ("/socket-service/read_writev_async", test_read_writev_async); + + return g_test_run(); +} diff --git a/gio/tests/socket.c b/gio/tests/socket.c new file mode 100644 index 0000000..4dae36b --- /dev/null +++ b/gio/tests/socket.c @@ -0,0 +1,2350 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include +#include + +#include +#include + +#ifdef G_OS_UNIX +#include +#include +#include +#include +#include +#endif + +#ifdef G_OS_WIN32 +#include "giowin32-afunix.h" +#endif + +#include "gnetworkingprivate.h" + +static gboolean ipv6_supported; + +typedef struct { + GSocket *server; + GSocket *client; + GSocketFamily family; + GThread *thread; + GMainLoop *loop; + GCancellable *cancellable; /* to shut down dgram echo server thread */ +} IPTestData; + +static gpointer +echo_server_dgram_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocketAddress *sa; + GCancellable *cancellable = data->cancellable; + GSocket *sock; + GError *error = NULL; + gssize nread, nwrote; + gchar buf[128]; + + sock = data->server; + + while (TRUE) + { + nread = g_socket_receive_from (sock, &sa, buf, sizeof (buf), cancellable, &error); + if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + break; + g_assert_no_error (error); + g_assert_cmpint (nread, >=, 0); + + nwrote = g_socket_send_to (sock, sa, buf, nread, cancellable, &error); + if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + break; + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, nread); + + g_object_unref (sa); + } + + g_clear_error (&error); + + return NULL; +} + +static gpointer +echo_server_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocket *sock; + GError *error = NULL; + gssize nread, nwrote; + gchar buf[128]; + + sock = g_socket_accept (data->server, NULL, &error); + g_assert_no_error (error); + + while (TRUE) + { + nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nread, >=, 0); + + if (nread == 0) + break; + + nwrote = g_socket_send (sock, buf, nread, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, nread); + } + + g_socket_close (sock, &error); + g_assert_no_error (error); + g_object_unref (sock); + return NULL; +} + +static IPTestData * +create_server_full (GSocketFamily family, + GSocketType socket_type, + GThreadFunc server_thread, + gboolean v4mapped, + GError **error) +{ + IPTestData *data; + GSocket *server; + GSocketAddress *addr; + GInetAddress *iaddr; + + data = g_slice_new (IPTestData); + data->family = family; + + data->server = server = g_socket_new (family, + socket_type, + G_SOCKET_PROTOCOL_DEFAULT, + error); + if (server == NULL) + goto error; + + g_assert_cmpint (g_socket_get_family (server), ==, family); + g_assert_cmpint (g_socket_get_socket_type (server), ==, socket_type); + g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (server, TRUE); + +#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY) + if (v4mapped) + { + g_socket_set_option (data->server, IPPROTO_IPV6, IPV6_V6ONLY, FALSE, NULL); + if (!g_socket_speaks_ipv4 (data->server)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "IPv6-only server cannot speak IPv4"); + goto error; + } + } +#endif + + if (v4mapped) + iaddr = g_inet_address_new_any (family); + else + iaddr = g_inet_address_new_loopback (family); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), ==, 0); + if (!g_socket_bind (server, addr, TRUE, error)) + { + g_object_unref (addr); + goto error; + } + g_object_unref (addr); + + addr = g_socket_get_local_address (server, error); + if (addr == NULL) + goto error; + g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), !=, 0); + g_object_unref (addr); + + if (socket_type == G_SOCKET_TYPE_STREAM) + { + if (!g_socket_listen (server, error)) + goto error; + } + else + { + data->cancellable = g_cancellable_new (); + } + + data->thread = g_thread_new ("server", server_thread, data); + + return data; + +error: + g_clear_object (&data->server); + g_slice_free (IPTestData, data); + + return NULL; +} + +static IPTestData * +create_server (GSocketFamily family, + GThreadFunc server_thread, + gboolean v4mapped, + GError **error) +{ + return create_server_full (family, G_SOCKET_TYPE_STREAM, server_thread, v4mapped, error); +} + +static const gchar *testbuf = "0123456789abcdef"; + +static gboolean +test_ip_async_read_ready (GSocket *client, + GIOCondition cond, + gpointer user_data) +{ + IPTestData *data = user_data; + GError *error = NULL; + gssize len; + gchar buf[128]; + + g_assert_cmpint (cond, ==, G_IO_IN); + + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + g_assert_cmpstr (testbuf, ==, buf); + + g_main_loop_quit (data->loop); + + return FALSE; +} + +static gboolean +test_ip_async_write_ready (GSocket *client, + GIOCondition cond, + gpointer user_data) +{ + IPTestData *data = user_data; + GError *error = NULL; + GSource *source; + gssize len; + + g_assert_cmpint (cond, ==, G_IO_OUT); + + len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + source = g_socket_create_source (client, G_IO_IN, NULL); + g_source_set_callback (source, (GSourceFunc)test_ip_async_read_ready, + data, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + + return FALSE; +} + +static gboolean +test_ip_async_timed_out (GSocket *client, + GIOCondition cond, + gpointer user_data) +{ + IPTestData *data = user_data; + GError *error = NULL; + GSource *source; + gssize len; + gchar buf[128]; + + if (data->family == G_SOCKET_FAMILY_IPV4) + { + g_assert_cmpint (cond, ==, G_IO_IN); + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_cmpint (len, ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_clear_error (&error); + } + + source = g_socket_create_source (client, G_IO_OUT, NULL); + g_source_set_callback (source, (GSourceFunc)test_ip_async_write_ready, + data, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + + return FALSE; +} + +static gboolean +test_ip_async_connected (GSocket *client, + GIOCondition cond, + gpointer user_data) +{ + IPTestData *data = user_data; + GError *error = NULL; + GSource *source; + gssize len; + gchar buf[128]; + + g_socket_check_connect_result (client, &error); + g_assert_no_error (error); + /* We do this after the check_connect_result, since that will give a + * more useful assertion in case of error. + */ + g_assert_cmpint (cond, ==, G_IO_OUT); + + g_assert (g_socket_is_connected (client)); + + /* This adds 1 second to "make check", so let's just only do it once. */ + if (data->family == G_SOCKET_FAMILY_IPV4) + { + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_cmpint (len, ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_clear_error (&error); + + source = g_socket_create_source (client, G_IO_IN, NULL); + g_source_set_callback (source, (GSourceFunc)test_ip_async_timed_out, + data, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + } + else + test_ip_async_timed_out (client, 0, data); + + return FALSE; +} + +static gboolean +idle_test_ip_async_connected (gpointer user_data) +{ + IPTestData *data = user_data; + + return test_ip_async_connected (data->client, G_IO_OUT, data); +} + +static void +test_ip_async (GSocketFamily family) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr; + GSource *source; + gssize len; + gchar buf[128]; + + data = create_server (family, echo_server_thread, FALSE, &error); + if (error != NULL) + { + g_test_skip_printf ("Failed to create server: %s", error->message); + g_clear_error (&error); + return; + } + g_assert_nonnull (data); + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + data->client = client; + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (client, FALSE); + g_socket_set_timeout (client, 1); + + if (g_socket_connect (client, addr, NULL, &error)) + { + g_assert_no_error (error); + g_idle_add (idle_test_ip_async_connected, data); + } + else + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING); + g_clear_error (&error); + source = g_socket_create_source (client, G_IO_OUT, NULL); + g_source_set_callback (source, (GSourceFunc)test_ip_async_connected, + data, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + } + g_object_unref (addr); + + data->loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (data->loop); + g_main_loop_unref (data->loop); + + g_socket_shutdown (client, FALSE, TRUE, &error); + g_assert_no_error (error); + + g_thread_join (data->thread); + + if (family == G_SOCKET_FAMILY_IPV4) + { + /* Test that reading on a remote-closed socket gets back 0 bytes. */ + len = g_socket_receive_with_blocking (client, buf, sizeof (buf), + TRUE, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 0); + } + else + { + /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */ + len = g_socket_send_with_blocking (client, testbuf, strlen (testbuf) + 1, + TRUE, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED); + g_assert_cmpint (len, ==, -1); + g_clear_error (&error); + } + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +static void +test_ipv4_async (void) +{ + test_ip_async (G_SOCKET_FAMILY_IPV4); +} + +static void +test_ipv6_async (void) +{ + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + test_ip_async (G_SOCKET_FAMILY_IPV6); +} + +static const gchar testbuf2[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + +static void +test_ip_sync (GSocketFamily family) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr; + gssize len; + gchar buf[128]; + + data = create_server (family, echo_server_thread, FALSE, &error); + if (error != NULL) + { + g_test_skip_printf ("Failed to create server: %s", error->message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_assert (g_socket_is_connected (client)); + g_object_unref (addr); + + /* This adds 1 second to "make check", so let's just only do it once. */ + if (family == G_SOCKET_FAMILY_IPV4) + { + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_cmpint (len, ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_clear_error (&error); + } + + len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + g_assert_cmpstr (testbuf, ==, buf); + + { + GOutputVector v[7] = { { NULL, 0 }, }; + + v[0].buffer = testbuf2 + 0; + v[0].size = 3; + v[1].buffer = testbuf2 + 3; + v[1].size = 5; + v[2].buffer = testbuf2 + 3 + 5; + v[2].size = 0; + v[3].buffer = testbuf2 + 3 + 5; + v[3].size = 6; + v[4].buffer = testbuf2 + 3 + 5 + 6; + v[4].size = 2; + v[5].buffer = testbuf2 + 3 + 5 + 6 + 2; + v[5].size = 1; + v[6].buffer = testbuf2 + 3 + 5 + 6 + 2 + 1; + v[6].size = strlen (testbuf2) - (3 + 5 + 6 + 2 + 1); + + len = g_socket_send_message (client, NULL, v, G_N_ELEMENTS (v), NULL, 0, 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf2)); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf2)); + g_assert_cmpstr (testbuf2, ==, buf); + } + + g_socket_shutdown (client, FALSE, TRUE, &error); + g_assert_no_error (error); + + g_thread_join (data->thread); + + if (family == G_SOCKET_FAMILY_IPV4) + { + /* Test that reading on a remote-closed socket gets back 0 bytes. */ + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 0); + } + else + { + /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */ + len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED); + g_assert_cmpint (len, ==, -1); + g_clear_error (&error); + } + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +static void +test_ipv4_sync (void) +{ + test_ip_sync (G_SOCKET_FAMILY_IPV4); +} + +static void +test_ipv6_sync (void) +{ + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + test_ip_sync (G_SOCKET_FAMILY_IPV6); +} + +static void +test_ip_sync_dgram (GSocketFamily family) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *dest_addr; + gssize len; + gchar buf[128]; + + data = create_server_full (family, G_SOCKET_TYPE_DATAGRAM, + echo_server_dgram_thread, FALSE, &error); + if (error != NULL) + { + g_test_skip_printf ("Failed to create server: %s", error->message); + g_clear_error (&error); + return; + } + + dest_addr = g_socket_get_local_address (data->server, &error); + + client = g_socket_new (family, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + len = g_socket_send_to (client, dest_addr, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + g_assert_cmpstr (testbuf, ==, buf); + + { + GOutputMessage m[3] = { { NULL, NULL, 0, 0, NULL, 0 }, }; + GInputMessage im[3] = { { NULL, NULL, 0, 0, 0, NULL, 0 }, }; + GOutputVector v[7] = { { NULL, 0 }, }; + GInputVector iv[7] = { { NULL, 0 }, }; + + v[0].buffer = testbuf2 + 0; + v[0].size = 3; + v[1].buffer = testbuf2 + 3; + v[1].size = 5; + v[2].buffer = testbuf2 + 3 + 5; + v[2].size = 0; + v[3].buffer = testbuf2 + 3 + 5; + v[3].size = 6; + v[4].buffer = testbuf2 + 3 + 5 + 6; + v[4].size = 2; + v[5].buffer = testbuf2 + 3 + 5 + 6 + 2; + v[5].size = 1; + v[6].buffer = testbuf2 + 3 + 5 + 6 + 2 + 1; + v[6].size = strlen (testbuf2) - (3 + 5 + 6 + 2 + 1); + + iv[0].buffer = buf + 0; + iv[0].size = 3; + iv[1].buffer = buf + 3; + iv[1].size = 5; + iv[2].buffer = buf + 3 + 5; + iv[2].size = 0; + iv[3].buffer = buf + 3 + 5; + iv[3].size = 6; + iv[4].buffer = buf + 3 + 5 + 6; + iv[4].size = 2; + iv[5].buffer = buf + 3 + 5 + 6 + 2; + iv[5].size = 1; + iv[6].buffer = buf + 3 + 5 + 6 + 2 + 1; + iv[6].size = sizeof (buf) - (3 + 5 + 6 + 2 + 1); + + len = g_socket_send_message (client, dest_addr, v, G_N_ELEMENTS (v), NULL, 0, 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf2)); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf2)); + g_assert_cmpstr (testbuf2, ==, buf); + + m[0].vectors = &v[0]; + m[0].num_vectors = 1; + m[0].address = dest_addr; + m[1].vectors = &v[0]; + m[1].num_vectors = 6; + m[1].address = dest_addr; + m[2].vectors = &v[6]; + m[2].num_vectors = 1; + m[2].address = dest_addr; + + len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, G_N_ELEMENTS (m)); + g_assert_cmpint (m[0].bytes_sent, ==, 3); + g_assert_cmpint (m[1].bytes_sent, ==, 17); + g_assert_cmpint (m[2].bytes_sent, ==, v[6].size); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 3); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + /* v[0].size + v[1].size + v[2].size + v[3].size + v[4].size + v[5].size */ + g_assert_cmpint (len, ==, 17); + g_assert (memcmp (testbuf2, buf, 17) == 0); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, v[6].size); + g_assert_cmpstr (buf, ==, v[6].buffer); + + /* reset since we're re-using the message structs */ + m[0].bytes_sent = 0; + m[1].bytes_sent = 0; + m[2].bytes_sent = 0; + + /* now try receiving multiple messages */ + len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, G_N_ELEMENTS (m)); + g_assert_cmpint (m[0].bytes_sent, ==, 3); + g_assert_cmpint (m[1].bytes_sent, ==, 17); + g_assert_cmpint (m[2].bytes_sent, ==, v[6].size); + + im[0].vectors = &iv[0]; + im[0].num_vectors = 1; + im[1].vectors = &iv[0]; + im[1].num_vectors = 6; + im[2].vectors = &iv[6]; + im[2].num_vectors = 1; + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_messages (client, im, G_N_ELEMENTS (im), 0, + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, G_N_ELEMENTS (im)); + + g_assert_cmpuint (im[0].bytes_received, ==, 3); + /* v[0].size + v[1].size + v[2].size + v[3].size + v[4].size + v[5].size */ + g_assert_cmpuint (im[1].bytes_received, ==, 17); + g_assert_cmpuint (im[2].bytes_received, ==, v[6].size); + + /* reset since we're re-using the message structs */ + m[0].bytes_sent = 0; + m[1].bytes_sent = 0; + m[2].bytes_sent = 0; + + /* now try to generate an early return by omitting the destination address on [1] */ + m[1].address = NULL; + len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 1); + + g_assert_cmpint (m[0].bytes_sent, ==, 3); + g_assert_cmpint (m[1].bytes_sent, ==, 0); + g_assert_cmpint (m[2].bytes_sent, ==, 0); + + /* reset since we're re-using the message structs */ + m[0].bytes_sent = 0; + m[1].bytes_sent = 0; + m[2].bytes_sent = 0; + + /* now try to generate an error by omitting all destination addresses */ + m[0].address = NULL; + m[1].address = NULL; + m[2].address = NULL; + len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error); + /* This error code may vary between platforms and over time; it is not guaranteed API: */ +#ifndef G_OS_WIN32 + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); +#else + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_CONNECTED); +#endif + g_clear_error (&error); + g_assert_cmpint (len, ==, -1); + + g_assert_cmpint (m[0].bytes_sent, ==, 0); + g_assert_cmpint (m[1].bytes_sent, ==, 0); + g_assert_cmpint (m[2].bytes_sent, ==, 0); + + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_cmpint (len, ==, 3); + } + + g_cancellable_cancel (data->cancellable); + + g_thread_join (data->thread); + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (data->cancellable); + g_object_unref (client); + g_object_unref (dest_addr); + + g_slice_free (IPTestData, data); +} + +static void +test_ipv4_sync_dgram (void) +{ + test_ip_sync_dgram (G_SOCKET_FAMILY_IPV4); +} + +static void +test_ipv6_sync_dgram (void) +{ + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + test_ip_sync_dgram (G_SOCKET_FAMILY_IPV6); +} + +static gpointer +cancellable_thread_cb (gpointer data) +{ + GCancellable *cancellable = data; + + g_usleep (0.1 * G_USEC_PER_SEC); + g_cancellable_cancel (cancellable); + g_object_unref (cancellable); + + return NULL; +} + +static void +test_ip_sync_dgram_timeouts (GSocketFamily family) +{ + GError *error = NULL; + GSocket *client = NULL; + GCancellable *cancellable = NULL; + GThread *cancellable_thread = NULL; + gssize len; +#ifdef G_OS_WIN32 + GInetAddress *iaddr; + GSocketAddress *addr; +#endif + + client = g_socket_new (family, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + +#ifdef G_OS_WIN32 + /* Winsock can't recv() on unbound udp socket */ + iaddr = g_inet_address_new_loopback (family); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + g_socket_bind (client, addr, TRUE, &error); + g_object_unref (addr); + g_assert_no_error (error); +#endif + + /* No overall timeout: test the per-operation timeouts instead. */ + g_socket_set_timeout (client, 0); + + cancellable = g_cancellable_new (); + + /* Check for timeouts when no server is running. */ + { + gint64 start_time; + GInputMessage im = { NULL, NULL, 0, 0, 0, NULL, 0 }; + GInputVector iv = { NULL, 0 }; + guint8 buf[128]; + + iv.buffer = buf; + iv.size = sizeof (buf); + + im.vectors = &iv; + im.num_vectors = 1; + + memset (buf, 0, sizeof (buf)); + + /* Try a non-blocking read. */ + g_socket_set_blocking (client, FALSE); + len = g_socket_receive_messages (client, &im, 1, 0 /* flags */, + NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_assert_cmpint (len, ==, -1); + g_clear_error (&error); + + /* Try a timeout read. Can’t really validate the time taken more than + * checking it’s positive. */ + g_socket_set_timeout (client, 1); + g_socket_set_blocking (client, TRUE); + start_time = g_get_monotonic_time (); + len = g_socket_receive_messages (client, &im, 1, 0 /* flags */, + NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_assert_cmpint (len, ==, -1); + g_assert_cmpint (g_get_monotonic_time () - start_time, >, 0); + g_clear_error (&error); + + /* Try a blocking read, cancelled from another thread. */ + g_socket_set_timeout (client, 0); + cancellable_thread = g_thread_new ("cancellable", + cancellable_thread_cb, + g_object_ref (cancellable)); + + start_time = g_get_monotonic_time (); + len = g_socket_receive_messages (client, &im, 1, 0 /* flags */, + cancellable, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert_cmpint (len, ==, -1); + g_assert_cmpint (g_get_monotonic_time () - start_time, >, 0); + g_clear_error (&error); + + g_thread_join (cancellable_thread); + } + + g_socket_close (client, &error); + g_assert_no_error (error); + + g_object_unref (client); + g_object_unref (cancellable); +} + +static void +test_ipv4_sync_dgram_timeouts (void) +{ + test_ip_sync_dgram_timeouts (G_SOCKET_FAMILY_IPV4); +} + +static void +test_ipv6_sync_dgram_timeouts (void) +{ + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + test_ip_sync_dgram_timeouts (G_SOCKET_FAMILY_IPV6); +} + +static gpointer +graceful_server_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocket *sock; + GError *error = NULL; + gssize len; + + sock = g_socket_accept (data->server, NULL, &error); + g_assert_no_error (error); + + len = g_socket_send (sock, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + return sock; +} + +static void +test_close_graceful (void) +{ + GSocketFamily family = G_SOCKET_FAMILY_IPV4; + IPTestData *data; + GError *error = NULL; + GSocket *client, *server; + GSocketAddress *addr; + gssize len; + gchar buf[128]; + + data = create_server (family, graceful_server_thread, FALSE, &error); + if (error != NULL) + { + g_test_skip_printf ("Failed to create server: %s", error->message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_assert (g_socket_is_connected (client)); + g_object_unref (addr); + + server = g_thread_join (data->thread); + + /* similar to g_tcp_connection_set_graceful_disconnect(), but explicit */ + g_socket_shutdown (server, FALSE, TRUE, &error); + g_assert_no_error (error); + + /* we must timeout */ + g_socket_condition_wait (client, G_IO_HUP, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_clear_error (&error); + + /* check that the remaining data is received */ + len = g_socket_receive (client, buf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + /* and only then the connection is closed */ + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 0); + + g_socket_close (server, &error); + g_assert_no_error (error); + + g_socket_close (client, &error); + g_assert_no_error (error); + + g_object_unref (server); + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY) +static gpointer +v4mapped_server_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocket *sock; + GError *error = NULL; + GSocketAddress *addr; + + sock = g_socket_accept (data->server, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (sock), ==, G_SOCKET_FAMILY_IPV6); + + addr = g_socket_get_local_address (sock, &error); + g_assert_no_error (error); + g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4); + g_object_unref (addr); + + addr = g_socket_get_remote_address (sock, &error); + g_assert_no_error (error); + g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4); + g_object_unref (addr); + + g_socket_close (sock, &error); + g_assert_no_error (error); + g_object_unref (sock); + return NULL; +} + +static void +test_ipv6_v4mapped (void) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr, *v4addr; + GInetAddress *iaddr; + + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + data = create_server (G_SOCKET_FAMILY_IPV6, v4mapped_server_thread, TRUE, &error); + if (error != NULL) + { + g_test_skip_printf ("Failed to create server: %s", error->message); + g_clear_error (&error); + return; + } + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + v4addr = g_inet_socket_address_new (iaddr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr))); + g_object_unref (iaddr); + g_object_unref (addr); + + g_socket_connect (client, v4addr, NULL, &error); + g_assert_no_error (error); + g_assert (g_socket_is_connected (client)); + + g_thread_join (data->thread); + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + g_object_unref (v4addr); + + g_slice_free (IPTestData, data); +} +#endif + +static void +test_timed_wait (void) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr; + gint64 start_time; + gint poll_duration; + + if (!g_test_thorough ()) + { + g_test_skip ("Not running timing heavy test"); + return; + } + + data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error); + if (error != NULL) + { + g_test_skip_printf ("Failed to create server: %s", error->message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_object_unref (addr); + + start_time = g_get_monotonic_time (); + g_socket_condition_timed_wait (client, G_IO_IN, 100000 /* 100 ms */, + NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_clear_error (&error); + poll_duration = g_get_monotonic_time () - start_time; + + g_assert_cmpint (poll_duration, >=, 98000); + g_assert_cmpint (poll_duration, <, 112000); + + g_socket_close (client, &error); + g_assert_no_error (error); + + g_thread_join (data->thread); + + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +static int +duplicate_fd (int fd) +{ +#ifdef G_OS_WIN32 + HANDLE newfd; + + if (!DuplicateHandle (GetCurrentProcess (), + (HANDLE)fd, + GetCurrentProcess (), + &newfd, + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) + { + return -1; + } + + return (int)newfd; +#else + return dup (fd); +#endif +} + +static void +test_fd_reuse (void) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocket *client2; + GSocketAddress *addr; + int fd; + gssize len; + gchar buf[128]; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=741707"); + + data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error); + if (error != NULL) + { + g_test_skip_printf ("Failed to create server: %s", error->message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_assert (g_socket_is_connected (client)); + g_object_unref (addr); + + /* we have to dup otherwise the fd gets closed twice on unref */ + fd = duplicate_fd (g_socket_get_fd (client)); + client2 = g_socket_new_from_fd (fd, &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client2), ==, g_socket_get_family (client)); + g_assert_cmpint (g_socket_get_socket_type (client2), ==, g_socket_get_socket_type (client)); + g_assert_cmpint (g_socket_get_protocol (client2), ==, G_SOCKET_PROTOCOL_TCP); + + len = g_socket_send (client2, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + len = g_socket_receive (client2, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + g_assert_cmpstr (testbuf, ==, buf); + + g_socket_shutdown (client, FALSE, TRUE, &error); + g_assert_no_error (error); + /* The semantics of dup()+shutdown() are ambiguous; this call will succeed + * on Linux, but return ENOTCONN on OS X. + */ + g_socket_shutdown (client2, FALSE, TRUE, NULL); + + g_thread_join (data->thread); + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (client2, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_fd (client), ==, -1); + g_assert_cmpint (g_socket_get_fd (client2), ==, -1); + g_assert_cmpint (g_socket_get_fd (data->server), ==, -1); + + g_object_unref (data->server); + g_object_unref (client); + g_object_unref (client2); + + g_slice_free (IPTestData, data); +} + +static void +test_sockaddr (void) +{ + struct sockaddr_in6 sin6, gsin6; + GSocketAddress *saddr; + GInetSocketAddress *isaddr; + GInetAddress *iaddr; + GError *error = NULL; + + memset (&sin6, 0, sizeof (sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = in6addr_loopback; + sin6.sin6_port = g_htons (42); + sin6.sin6_scope_id = 17; + sin6.sin6_flowinfo = 1729; + + saddr = g_socket_address_new_from_native (&sin6, sizeof (sin6)); + g_assert (G_IS_INET_SOCKET_ADDRESS (saddr)); + + isaddr = G_INET_SOCKET_ADDRESS (saddr); + iaddr = g_inet_socket_address_get_address (isaddr); + g_assert_cmpint (g_inet_address_get_family (iaddr), ==, G_SOCKET_FAMILY_IPV6); + g_assert (g_inet_address_get_is_loopback (iaddr)); + + g_assert_cmpint (g_inet_socket_address_get_port (isaddr), ==, 42); + g_assert_cmpint (g_inet_socket_address_get_scope_id (isaddr), ==, 17); + g_assert_cmpint (g_inet_socket_address_get_flowinfo (isaddr), ==, 1729); + + g_socket_address_to_native (saddr, &gsin6, sizeof (gsin6), &error); + g_assert_no_error (error); + + g_assert (memcmp (&sin6.sin6_addr, &gsin6.sin6_addr, sizeof (struct in6_addr)) == 0); + g_assert_cmpint (sin6.sin6_port, ==, gsin6.sin6_port); + g_assert_cmpint (sin6.sin6_scope_id, ==, gsin6.sin6_scope_id); + g_assert_cmpint (sin6.sin6_flowinfo, ==, gsin6.sin6_flowinfo); + + g_object_unref (saddr); +} + +static void +bind_win32_unixfd (int fd) +{ +#ifdef G_OS_WIN32 + gint len, ret; + struct sockaddr_un addr; + + memset (&addr, 0, sizeof addr); + addr.sun_family = AF_UNIX; + len = g_snprintf (addr.sun_path, sizeof addr.sun_path, "%s" G_DIR_SEPARATOR_S "%d.sock", g_get_tmp_dir (), fd); + g_assert_cmpint (len, <=, sizeof addr.sun_path); + ret = bind (fd, (struct sockaddr *)&addr, sizeof addr); + g_assert_cmpint (ret, ==, 0); + g_remove (addr.sun_path); +#endif +} + +static void +test_unix_from_fd (void) +{ + gint fd; + GError *error; + GSocket *s; + + fd = socket (AF_UNIX, SOCK_STREAM, 0); +#ifdef G_OS_WIN32 + if (fd == -1) + { + g_test_skip ("AF_UNIX not supported on this Windows system."); + return; + } +#endif + g_assert_cmpint (fd, !=, -1); + + bind_win32_unixfd (fd); + + error = NULL; + s = g_socket_new_from_fd (fd, &error); + g_assert_no_error (error); + g_assert_cmpint (g_socket_get_family (s), ==, G_SOCKET_FAMILY_UNIX); + g_assert_cmpint (g_socket_get_socket_type (s), ==, G_SOCKET_TYPE_STREAM); + g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT); + g_object_unref (s); +} + +static void +test_unix_connection (void) +{ + gint fd; + GError *error; + GSocket *s; + GSocketConnection *c; + + fd = socket (AF_UNIX, SOCK_STREAM, 0); +#ifdef G_OS_WIN32 + if (fd == -1) + { + g_test_skip ("AF_UNIX not supported on this Windows system."); + return; + } +#endif + g_assert_cmpint (fd, !=, -1); + + bind_win32_unixfd (fd); + + error = NULL; + s = g_socket_new_from_fd (fd, &error); + g_assert_no_error (error); + c = g_socket_connection_factory_create_connection (s); + g_assert (G_IS_UNIX_CONNECTION (c)); + g_object_unref (c); + g_object_unref (s); +} + +#ifdef G_OS_UNIX +static GSocketConnection * +create_connection_for_fd (int fd) +{ + GError *err = NULL; + GSocket *socket; + GSocketConnection *connection; + + socket = g_socket_new_from_fd (fd, &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (socket)); + connection = g_socket_connection_factory_create_connection (socket); + g_assert (G_IS_UNIX_CONNECTION (connection)); + g_object_unref (socket); + return connection; +} + +#define TEST_DATA "failure to say failure to say 'i love gnome-panel!'." + +static void +test_unix_connection_ancillary_data (void) +{ + GError *err = NULL; + gint pv[2], sv[3]; + gint status, fd, len; + char buffer[1024]; + pid_t pid; + + status = pipe (pv); + g_assert_cmpint (status, ==, 0); + + status = socketpair (PF_UNIX, SOCK_STREAM, 0, sv); + g_assert_cmpint (status, ==, 0); + + pid = fork (); + g_assert_cmpint (pid, >=, 0); + + /* Child: close its copy of the write end of the pipe, receive it + * again from the parent over the socket, and write some text to it. + * + * Parent: send the write end of the pipe (still open for the + * parent) over the socket, close it, and read some text from the + * read end of the pipe. + */ + if (pid == 0) + { + GSocketConnection *connection; + + close (sv[1]); + connection = create_connection_for_fd (sv[0]); + + status = close (pv[1]); + g_assert_cmpint (status, ==, 0); + + err = NULL; + fd = g_unix_connection_receive_fd (G_UNIX_CONNECTION (connection), NULL, + &err); + g_assert_no_error (err); + g_assert_cmpint (fd, >, -1); + g_object_unref (connection); + + do + len = write (fd, TEST_DATA, sizeof (TEST_DATA)); + while (len == -1 && errno == EINTR); + g_assert_cmpint (len, ==, sizeof (TEST_DATA)); + exit (0); + } + else + { + GSocketConnection *connection; + + close (sv[0]); + connection = create_connection_for_fd (sv[1]); + + err = NULL; + g_unix_connection_send_fd (G_UNIX_CONNECTION (connection), pv[1], NULL, + &err); + g_assert_no_error (err); + g_object_unref (connection); + + status = close (pv[1]); + g_assert_cmpint (status, ==, 0); + + memset (buffer, 0xff, sizeof buffer); + do + len = read (pv[0], buffer, sizeof buffer); + while (len == -1 && errno == EINTR); + + g_assert_cmpint (len, ==, sizeof (TEST_DATA)); + g_assert_cmpstr (buffer, ==, TEST_DATA); + + waitpid (pid, &status, 0); + g_assert (WIFEXITED (status)); + g_assert_cmpint (WEXITSTATUS (status), ==, 0); + } + + /* TODO: add test for g_unix_connection_send_credentials() and + * g_unix_connection_receive_credentials(). + */ +} +#endif + +static gboolean +postmortem_source_cb (GSocket *socket, + GIOCondition condition, + gpointer user_data) +{ + gboolean *been_here = user_data; + + g_assert_cmpint (condition, ==, G_IO_NVAL); + + *been_here = TRUE; + return FALSE; +} + +static void +test_source_postmortem (void) +{ + GMainContext *context; + GSocket *socket; + GSource *source; + GError *error = NULL; + gboolean callback_visited = FALSE; + + socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error); +#ifdef G_OS_WIN32 + if (error) + { + g_test_skip_printf ("AF_UNIX not supported on this Windows system: %s", error->message); + g_clear_error (&error); + return; + } +#endif + g_assert_no_error (error); + + context = g_main_context_new (); + + source = g_socket_create_source (socket, G_IO_IN, NULL); + g_source_set_callback (source, (GSourceFunc) postmortem_source_cb, + &callback_visited, NULL); + g_source_attach (source, context); + g_source_unref (source); + + g_socket_close (socket, &error); + g_assert_no_error (error); + g_object_unref (socket); + + /* Test that, after a socket is closed, its source callback should be called + * exactly once. */ + g_main_context_iteration (context, FALSE); + g_assert (callback_visited); + g_assert (!g_main_context_pending (context)); + + g_main_context_unref (context); +} + +static void +test_reuse_tcp (void) +{ + GSocket *sock1, *sock2; + GError *error = NULL; + GInetAddress *iaddr; + GSocketAddress *addr; + + sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + g_socket_bind (sock1, addr, TRUE, &error); + g_object_unref (addr); + g_assert_no_error (error); + + g_socket_listen (sock1, &error); + g_assert_no_error (error); + + sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + addr = g_socket_get_local_address (sock1, &error); + g_assert_no_error (error); + g_socket_bind (sock2, addr, TRUE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE); + g_clear_error (&error); + g_object_unref (addr); + + g_object_unref (sock1); + g_object_unref (sock2); +} + +static void +test_reuse_udp (void) +{ + GSocket *sock1, *sock2; + GError *error = NULL; + GInetAddress *iaddr; + GSocketAddress *addr; + + sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + g_socket_bind (sock1, addr, TRUE, &error); + g_object_unref (addr); + g_assert_no_error (error); + + sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + addr = g_socket_get_local_address (sock1, &error); + g_assert_no_error (error); + g_socket_bind (sock2, addr, TRUE, &error); + g_object_unref (addr); + g_assert_no_error (error); + + g_object_unref (sock1); + g_object_unref (sock2); +} + +static void +test_get_available (gconstpointer user_data) +{ + GSocketType socket_type = GPOINTER_TO_UINT (user_data); + GError *err = NULL; + GSocket *listener, *server, *client; + GInetAddress *addr; + GSocketAddress *saddr, *boundaddr; + gchar data[] = "0123456789abcdef"; + gchar buf[34]; + gssize nread; + + listener = g_socket_new (G_SOCKET_FAMILY_IPV4, + socket_type, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (listener)); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + socket_type, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (client)); + + if (socket_type == G_SOCKET_TYPE_STREAM) + { + g_socket_set_option (client, IPPROTO_TCP, TCP_NODELAY, TRUE, &err); + g_assert_no_error (err); + } + + addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (addr, 0); + + g_socket_bind (listener, saddr, TRUE, &err); + g_assert_no_error (err); + g_object_unref (saddr); + g_object_unref (addr); + + boundaddr = g_socket_get_local_address (listener, &err); + g_assert_no_error (err); + + addr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (addr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (boundaddr))); + g_object_unref (addr); + g_object_unref (boundaddr); + + if (socket_type == G_SOCKET_TYPE_STREAM) + { + g_socket_listen (listener, &err); + g_assert_no_error (err); + g_socket_connect (client, saddr, NULL, &err); + g_assert_no_error (err); + + server = g_socket_accept (listener, NULL, &err); + g_assert_no_error (err); + g_socket_set_blocking (server, FALSE); + g_object_unref (listener); + } + else + server = listener; + + g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err); + g_assert_no_error (err); + + while (!g_socket_condition_wait (server, G_IO_IN, NULL, NULL)) + ; + g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data)); + + g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err); + g_assert_no_error (err); + + /* We need to wait until the data has actually been copied into the + * server socket's buffers, but g_socket_condition_wait() won't help + * here since the socket is definitely already readable. So there's + * a race condition in checking its available bytes. In the TCP + * case, we poll for a bit until the new data shows up. In the UDP + * case, there's not much we can do, but at least the failure mode + * is passes-when-it-shouldn't, not fails-when-it-shouldn't. + */ + if (socket_type == G_SOCKET_TYPE_STREAM) + { + int tries; + + for (tries = 0; tries < 100; tries++) + { + gssize res = g_socket_get_available_bytes (server); + if ((res == -1) || ((gsize) res > sizeof (data))) + break; + g_usleep (100000); + } + + g_assert_cmpint (g_socket_get_available_bytes (server), ==, 2 * sizeof (data)); + } + else + { + g_usleep (100000); + g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data)); + } + + g_assert_cmpint (sizeof (buf), >=, 2 * sizeof (data)); + nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err); + g_assert_no_error (err); + + if (socket_type == G_SOCKET_TYPE_STREAM) + { + g_assert_cmpint (nread, ==, 2 * sizeof (data)); + g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0); + } + else + { + g_assert_cmpint (nread, ==, sizeof (data)); + g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data)); + } + + nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err); + if (socket_type == G_SOCKET_TYPE_STREAM) + { + g_assert_cmpint (nread, ==, -1); + g_assert_error (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_clear_error (&err); + } + else + { + g_assert_cmpint (nread, ==, sizeof (data)); + g_assert_no_error (err); + } + + g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0); + + g_socket_close (server, &err); + g_assert_no_error (err); + + g_object_unref (saddr); + g_object_unref (server); + g_object_unref (client); +} + +typedef struct { + GInputStream *is; + GOutputStream *os; + const guint8 *write_data; + guint8 *read_data; +} TestReadWriteData; + +static gpointer +test_read_write_write_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_written; + GError *error = NULL; + gboolean res; + + res = g_output_stream_write_all (data->os, data->write_data, 1024, &bytes_written, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_written, ==, 1024); + + return NULL; +} + +static gpointer +test_read_write_read_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_read; + GError *error = NULL; + gboolean res; + + res = g_input_stream_read_all (data->is, data->read_data, 1024, &bytes_read, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, 1024); + + return NULL; +} + +static gpointer +test_read_write_writev_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_written; + GError *error = NULL; + gboolean res; + GOutputVector vectors[3]; + + vectors[0].buffer = data->write_data; + vectors[0].size = 256; + vectors[1].buffer = data->write_data + 256; + vectors[1].size = 256; + vectors[2].buffer = data->write_data + 512; + vectors[2].size = 512; + + res = g_output_stream_writev_all (data->os, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_written, ==, 1024); + + return NULL; +} + +/* test if normal read/write/writev via the GSocket*Streams works on TCP sockets */ +static void +test_read_write (gconstpointer user_data) +{ + gboolean writev = GPOINTER_TO_INT (user_data); + GError *err = NULL; + GSocket *listener, *server, *client; + GInetAddress *addr; + GSocketAddress *saddr, *boundaddr; + TestReadWriteData data; + guint8 data_write[1024], data_read[1024]; + GSocketConnection *server_stream, *client_stream; + GThread *write_thread, *read_thread; + guint i; + + listener = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (listener)); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (client)); + + addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (addr, 0); + + g_socket_bind (listener, saddr, TRUE, &err); + g_assert_no_error (err); + g_object_unref (saddr); + g_object_unref (addr); + + boundaddr = g_socket_get_local_address (listener, &err); + g_assert_no_error (err); + + g_socket_listen (listener, &err); + g_assert_no_error (err); + + addr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (addr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (boundaddr))); + g_object_unref (addr); + g_object_unref (boundaddr); + + g_socket_connect (client, saddr, NULL, &err); + g_assert_no_error (err); + + server = g_socket_accept (listener, NULL, &err); + g_assert_no_error (err); + g_socket_set_blocking (server, FALSE); + g_object_unref (listener); + + server_stream = g_socket_connection_factory_create_connection (server); + g_assert_nonnull (server_stream); + client_stream = g_socket_connection_factory_create_connection (client); + g_assert_nonnull (client_stream); + + for (i = 0; i < sizeof (data_write); i++) + data_write[i] = i; + + data.is = g_io_stream_get_input_stream (G_IO_STREAM (server_stream)); + data.os = g_io_stream_get_output_stream (G_IO_STREAM (client_stream)); + data.read_data = data_read; + data.write_data = data_write; + + if (writev) + write_thread = g_thread_new ("writer", test_read_write_writev_thread, &data); + else + write_thread = g_thread_new ("writer", test_read_write_write_thread, &data); + read_thread = g_thread_new ("reader", test_read_write_read_thread, &data); + + g_thread_join (write_thread); + g_thread_join (read_thread); + + g_assert_cmpmem (data_write, sizeof data_write, data_read, sizeof data_read); + + g_socket_close (server, &err); + g_assert_no_error (err); + + g_object_unref (server_stream); + g_object_unref (client_stream); + + g_object_unref (saddr); + g_object_unref (server); + g_object_unref (client); +} + +#ifdef SO_NOSIGPIPE +static void +test_nosigpipe (void) +{ + GSocket *sock; + GError *error = NULL; + gint value; + + sock = g_socket_new (AF_INET, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_get_option (sock, SOL_SOCKET, SO_NOSIGPIPE, &value, &error); + g_assert_no_error (error); + g_assert_true (value); + + g_object_unref (sock); +} +#endif + +#if G_CREDENTIALS_SUPPORTED +static gpointer client_setup_thread (gpointer user_data); + +static void +test_credentials_tcp_client (void) +{ + const GSocketFamily family = G_SOCKET_FAMILY_IPV4; + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr; + GCredentials *creds; + + data = create_server (family, echo_server_thread, FALSE, &error); + if (error != NULL) + { + g_test_skip_printf ("Failed to create server: %s", error->message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_object_unref (addr); + + creds = g_socket_get_credentials (client, &error); + if (creds != NULL) + { + gchar *str = g_credentials_to_string (creds); + g_print ("Supported on this OS: %s\n", str); + g_free (str); + g_clear_object (&creds); + } + else + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_print ("Unsupported on this OS: %s\n", error->message); + g_clear_error (&error); + } + + g_socket_close (client, &error); + g_assert_no_error (error); + + g_thread_join (data->thread); + + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +static void +test_credentials_tcp_server (void) +{ + const GSocketFamily family = G_SOCKET_FAMILY_IPV4; + IPTestData *data; + GSocket *server; + GError *error = NULL; + GSocketAddress *addr = NULL; + GInetAddress *iaddr = NULL; + GSocket *sock = NULL; + GCredentials *creds; + + data = g_slice_new0 (IPTestData); + data->family = family; + data->server = server = g_socket_new (family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + if (error != NULL) + goto skip; + + g_socket_set_blocking (server, TRUE); + + iaddr = g_inet_address_new_loopback (family); + addr = g_inet_socket_address_new (iaddr, 0); + + if (!g_socket_bind (server, addr, TRUE, &error)) + goto skip; + + if (!g_socket_listen (server, &error)) + goto skip; + + data->thread = g_thread_new ("client", client_setup_thread, data); + + sock = g_socket_accept (server, NULL, &error); + g_assert_no_error (error); + + creds = g_socket_get_credentials (sock, &error); + if (creds != NULL) + { + gchar *str = g_credentials_to_string (creds); + g_print ("Supported on this OS: %s\n", str); + g_free (str); + g_clear_object (&creds); + } + else + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_print ("Unsupported on this OS: %s\n", error->message); + g_clear_error (&error); + } + + goto beach; + +skip: + g_test_skip_printf ("Failed to create server: %s", error->message); + goto beach; + +beach: + { + g_clear_error (&error); + + g_clear_object (&sock); + g_clear_object (&addr); + g_clear_object (&iaddr); + + g_clear_pointer (&data->thread, g_thread_join); + g_clear_object (&data->server); + g_clear_object (&data->client); + + g_slice_free (IPTestData, data); + } +} + +static gpointer +client_setup_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocketAddress *addr; + GSocket *client; + GError *error = NULL; + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + data->client = client = g_socket_new (data->family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + + g_object_unref (addr); + + return NULL; +} + +#ifdef G_OS_WIN32 +/* + * _g_win32_socketpair: + * + * Create a pair of connected sockets, similar to POSIX/BSD socketpair(). + * + * Windows does not (yet) provide a socketpair() function. However, since the + * introduction of AF_UNIX sockets, it is possible to implement a fairly close + * function. + */ +static gint +_g_win32_socketpair (gint domain, + gint type, + gint protocol, + gint sv[2]) +{ + struct sockaddr_un addr = { 0, }; + socklen_t socklen; + SOCKET listener = INVALID_SOCKET; + SOCKET client = INVALID_SOCKET; + SOCKET server = INVALID_SOCKET; + gchar *path = NULL; + int tmpfd, rv = -1; + u_long arg, br; + + g_return_val_if_fail (sv != NULL, -1); + + addr.sun_family = AF_UNIX; + socklen = sizeof (addr); + + tmpfd = g_file_open_tmp (NULL, &path, NULL); + if (tmpfd == -1) + { + WSASetLastError (WSAEACCES); + goto out; + } + + g_close (tmpfd, NULL); + + if (strlen (path) >= sizeof (addr.sun_path)) + { + WSASetLastError (WSAEACCES); + goto out; + } + + strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1); + + listener = socket (domain, type, protocol); + if (listener == INVALID_SOCKET) + goto out; + + if (DeleteFile (path) == 0) + { + if (GetLastError () != ERROR_FILE_NOT_FOUND) + goto out; + } + + if (bind (listener, (struct sockaddr *) &addr, socklen) == SOCKET_ERROR) + goto out; + + if (listen (listener, 1) == SOCKET_ERROR) + goto out; + + client = socket (domain, type, protocol); + if (client == INVALID_SOCKET) + goto out; + + arg = 1; + if (ioctlsocket (client, FIONBIO, &arg) == SOCKET_ERROR) + goto out; + + if (connect (client, (struct sockaddr *) &addr, socklen) == SOCKET_ERROR && + WSAGetLastError () != WSAEWOULDBLOCK) + goto out; + + server = accept (listener, NULL, NULL); + if (server == INVALID_SOCKET) + goto out; + + arg = 0; + if (ioctlsocket (client, FIONBIO, &arg) == SOCKET_ERROR) + goto out; + + if (WSAIoctl (server, SIO_AF_UNIX_GETPEERPID, + NULL, 0U, + &arg, sizeof (arg), &br, + NULL, NULL) == SOCKET_ERROR || arg != GetCurrentProcessId ()) + { + WSASetLastError (WSAEACCES); + goto out; + } + + sv[0] = server; + server = INVALID_SOCKET; + sv[1] = client; + client = INVALID_SOCKET; + rv = 0; + + out: + if (listener != INVALID_SOCKET) + closesocket (listener); + if (client != INVALID_SOCKET) + closesocket (client); + if (server != INVALID_SOCKET) + closesocket (server); + + DeleteFile (path); + g_free (path); + return rv; +} +#endif /* G_OS_WIN32 */ + +static void +test_credentials_unix_socketpair (void) +{ + gint fds[2]; + gint status; + GSocket *sock[2]; + GError *error = NULL; + GCredentials *creds; + +#ifdef G_OS_WIN32 + status = _g_win32_socketpair (PF_UNIX, SOCK_STREAM, 0, fds); + if (status != 0) + { + g_test_skip ("AF_UNIX not supported on this Windows system."); + return; + } +#else + status = socketpair (PF_UNIX, SOCK_STREAM, 0, fds); +#endif + g_assert_cmpint (status, ==, 0); + + sock[0] = g_socket_new_from_fd (fds[0], &error); + g_assert_no_error (error); + sock[1] = g_socket_new_from_fd (fds[1], &error); + g_assert_no_error (error); + + creds = g_socket_get_credentials (sock[0], &error); + if (creds != NULL) + { + gchar *str = g_credentials_to_string (creds); + g_print ("Supported on this OS: %s\n", str); + g_free (str); + g_clear_object (&creds); + } + else + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_print ("Unsupported on this OS: %s\n", error->message); + g_clear_error (&error); + } + + g_object_unref (sock[0]); + g_object_unref (sock[1]); +} +#endif + +int +main (int argc, + char *argv[]) +{ + GSocket *sock; + GError *error = NULL; + + g_test_init (&argc, &argv, NULL); + + sock = g_socket_new (G_SOCKET_FAMILY_IPV6, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + if (sock != NULL) + { + ipv6_supported = TRUE; + g_object_unref (sock); + } + else + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + } + + g_test_add_func ("/socket/ipv4_sync", test_ipv4_sync); + g_test_add_func ("/socket/ipv4_async", test_ipv4_async); + g_test_add_func ("/socket/ipv6_sync", test_ipv6_sync); + g_test_add_func ("/socket/ipv6_async", test_ipv6_async); + g_test_add_func ("/socket/ipv4_sync/datagram", test_ipv4_sync_dgram); + g_test_add_func ("/socket/ipv4_sync/datagram/timeouts", test_ipv4_sync_dgram_timeouts); + g_test_add_func ("/socket/ipv6_sync/datagram", test_ipv6_sync_dgram); + g_test_add_func ("/socket/ipv6_sync/datagram/timeouts", test_ipv6_sync_dgram_timeouts); +#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY) + g_test_add_func ("/socket/ipv6_v4mapped", test_ipv6_v4mapped); +#endif + g_test_add_func ("/socket/close_graceful", test_close_graceful); + g_test_add_func ("/socket/timed_wait", test_timed_wait); + g_test_add_func ("/socket/fd_reuse", test_fd_reuse); + g_test_add_func ("/socket/address", test_sockaddr); + g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd); + g_test_add_func ("/socket/unix-connection", test_unix_connection); +#ifdef G_OS_UNIX + g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data); +#endif + g_test_add_func ("/socket/source-postmortem", test_source_postmortem); + g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp); + g_test_add_func ("/socket/reuse/udp", test_reuse_udp); + g_test_add_data_func ("/socket/get_available/datagram", GUINT_TO_POINTER (G_SOCKET_TYPE_DATAGRAM), + test_get_available); + g_test_add_data_func ("/socket/get_available/stream", GUINT_TO_POINTER (G_SOCKET_TYPE_STREAM), + test_get_available); + g_test_add_data_func ("/socket/read_write", GUINT_TO_POINTER (FALSE), + test_read_write); + g_test_add_data_func ("/socket/read_writev", GUINT_TO_POINTER (TRUE), + test_read_write); +#ifdef SO_NOSIGPIPE + g_test_add_func ("/socket/nosigpipe", test_nosigpipe); +#endif +#if G_CREDENTIALS_SUPPORTED + g_test_add_func ("/socket/credentials/tcp_client", test_credentials_tcp_client); + g_test_add_func ("/socket/credentials/tcp_server", test_credentials_tcp_server); + g_test_add_func ("/socket/credentials/unix_socketpair", test_credentials_unix_socketpair); +#endif + + return g_test_run(); +} diff --git a/gio/tests/srvtarget.c b/gio/tests/srvtarget.c new file mode 100644 index 0000000..84f803e --- /dev/null +++ b/gio/tests/srvtarget.c @@ -0,0 +1,157 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2009 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include + +#define NUM_TRIALS 250000 + +struct { + const char *order; + int expected, seen; +} ordering[] = { + /* There are 32 legitimate orderings; the result always has to start + * with either "fe" (usually) or "ef" (rarely). For the remaining + * letters, "cbda" is the most likely, with various other orders + * possible, down to "adbc" being the most improbable. However, + * almost all "fe" orderings are more likely than almost any "ef" + * orderings. The complete probability ordering, from most-likely + * to least-likely is something roughly like: + */ + { "fecbda", 0.2468 * NUM_TRIALS, 0}, + { "febcda", 0.1885 * NUM_TRIALS, 0}, + { "fecdba", 0.1346 * NUM_TRIALS, 0}, + { "fedcba", 0.0830 * NUM_TRIALS, 0}, + { "febdca", 0.0706 * NUM_TRIALS, 0}, + { "fedbca", 0.0571 * NUM_TRIALS, 0}, + { "fecbad", 0.0496 * NUM_TRIALS, 0}, + { "febcad", 0.0374 * NUM_TRIALS, 0}, + { "fecabd", 0.0185 * NUM_TRIALS, 0}, + { "fecdab", 0.0136 * NUM_TRIALS, 0}, + { "fecadb", 0.0110 * NUM_TRIALS, 0}, + { "febacd", 0.0108 * NUM_TRIALS, 0}, + { "feacbd", 0.0096 * NUM_TRIALS, 0}, + { "fedcab", 0.0083 * NUM_TRIALS, 0}, + { "feabcd", 0.0073 * NUM_TRIALS, 0}, + { "feacdb", 0.0058 * NUM_TRIALS, 0}, + { "efcbda", 0.0049 * NUM_TRIALS, 0}, + { "febdac", 0.0048 * NUM_TRIALS, 0}, + { "febadc", 0.0043 * NUM_TRIALS, 0}, + { "fedbac", 0.0038 * NUM_TRIALS, 0}, + { "efbcda", 0.0038 * NUM_TRIALS, 0}, + { "feadcb", 0.0036 * NUM_TRIALS, 0}, + { "fedacb", 0.0035 * NUM_TRIALS, 0}, + { "feabdc", 0.0029 * NUM_TRIALS, 0}, + { "feadbc", 0.0026 * NUM_TRIALS, 0}, + { "fedabc", 0.0026 * NUM_TRIALS, 0}, + { "efcdba", 0.0026 * NUM_TRIALS, 0}, + { "efdcba", 0.0017 * NUM_TRIALS, 0}, + { "efbdca", 0.0014 * NUM_TRIALS, 0}, + { "efdbca", 0.0011 * NUM_TRIALS, 0}, + { "efcbad", 0.0010 * NUM_TRIALS, 0}, + { "efbcad", 0.0008 * NUM_TRIALS, 0}, + { "efcabd", 0.0004 * NUM_TRIALS, 0}, + { "efcdab", 0.0003 * NUM_TRIALS, 0}, + { "efcadb", 0.0002 * NUM_TRIALS, 0}, + { "efbacd", 0.0002 * NUM_TRIALS, 0}, + { "efacbd", 0.0002 * NUM_TRIALS, 0}, + { "efdcab", 0.0002 * NUM_TRIALS, 0}, + { "efabcd", 0.0002 * NUM_TRIALS, 0}, + { "efacdb", 0.0001 * NUM_TRIALS, 0}, + { "efbdac", 0.0001 * NUM_TRIALS, 0}, + { "efadcb", 0.0001 * NUM_TRIALS, 0}, + { "efdbac", 0.0001 * NUM_TRIALS, 0}, + { "efbadc", 0.0001 * NUM_TRIALS, 0}, + { "efdacb", 0.0001 * NUM_TRIALS, 0}, + { "efabdc", 0.0001 * NUM_TRIALS, 0}, + { "efadbc", 0.00005 * NUM_TRIALS, 0}, + { "efdabc", 0.00005 * NUM_TRIALS, 0} +}; +#define NUM_ORDERINGS G_N_ELEMENTS (ordering) + +static void +test_srv_target_ordering (void) +{ + GList *targets, *sorted, *t; + char result[7], *p; + int i; + guint o; + + targets = NULL; + /* name, port, priority, weight */ + targets = g_list_append (targets, g_srv_target_new ("a", 0, 2, 0)); + targets = g_list_append (targets, g_srv_target_new ("b", 0, 2, 10)); + targets = g_list_append (targets, g_srv_target_new ("c", 0, 2, 15)); + targets = g_list_append (targets, g_srv_target_new ("d", 0, 2, 5)); + targets = g_list_append (targets, g_srv_target_new ("e", 0, 1, 0)); + targets = g_list_append (targets, g_srv_target_new ("f", 0, 1, 50)); + + for (i = 0; i < NUM_TRIALS; i++) + { + g_random_set_seed (i); + + sorted = g_srv_target_list_sort (g_list_copy (targets)); + + for (t = sorted, p = result; t; t = t->next) + *(p++) = *g_srv_target_get_hostname (t->data); + *p = '\0'; + g_list_free (sorted); + + for (o = 0; o < NUM_ORDERINGS; o++) + { + if (!strcmp (result, ordering[o].order)) + { + ordering[o].seen++; + break; + } + } + + /* Assert that @result matched one of the valid orderings */ + if (o == NUM_ORDERINGS) + { + char *msg = g_strdup_printf ("result '%s' is invalid", result); + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); + } + } + + /* Assert that each ordering appeared roughly the expected + * number of times. + */ + for (o = 0; o < NUM_ORDERINGS; o++) + { + g_assert_cmpint (ordering[o].seen, >, ordering[o].expected / 2); + g_assert_cmpint (ordering[o].seen, <, ordering[o].expected * 2); + } + + g_resolver_free_targets (targets); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/srvtarget/srv-target-ordering", test_srv_target_ordering); + + return g_test_run(); +} diff --git a/gio/tests/static-link.py b/gio/tests/static-link.py new file mode 100755 index 0000000..a8bda5b --- /dev/null +++ b/gio/tests/static-link.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright (C) 2018 Collabora Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: Xavier Claessens + +import os +import sys +import tempfile +import subprocess + +if "GLIB_TEST_COMPILATION" not in os.environ: + print( + """Test disabled because GLIB_TEST_COMPILATION is not set in the env. +If you wish to run this test, set GLIB_TEST_COMPILATION=1 in the env, +and make sure you have glib build dependencies installed, including +meson.""" + ) + sys.exit(77) + +if len(sys.argv) != 2: + print("Usage: {} ".format(os.path.basename(sys.argv[0]))) + sys.exit(1) + +test_dir = os.path.dirname(sys.argv[0]) + +with tempfile.TemporaryDirectory() as builddir: + env = os.environ.copy() + env["PKG_CONFIG_PATH"] = sys.argv[1] + sourcedir = os.path.join(test_dir, "static-link") + + # Ensure we can static link and run a test app + subprocess.check_call(["meson", sourcedir, builddir], env=env) + subprocess.check_call(["ninja", "-C", builddir, "test"], env=env) + # FIXME: This probably only works on Linux + out = subprocess.check_output( + ["ldd", os.path.join(builddir, "test-static-link")], env=env + ).decode() + if "libgio" in out: + print("test-static-link is dynamically linked on libgio") + exit(1) diff --git a/gio/tests/static-link/app.c b/gio/tests/static-link/app.c new file mode 100644 index 0000000..94baf60 --- /dev/null +++ b/gio/tests/static-link/app.c @@ -0,0 +1,8 @@ +#include + +int main(int argc, char *argv[]) +{ + GApplication *app = g_application_new (NULL, 0); + g_object_unref (app); + return 0; +} diff --git a/gio/tests/static-link/meson.build b/gio/tests/static-link/meson.build new file mode 100644 index 0000000..c0b638f --- /dev/null +++ b/gio/tests/static-link/meson.build @@ -0,0 +1,8 @@ +project('test-static-link', 'c') + +# This is a dummy project that static links against installed gio. +# See gio/tests/static-link.py. +app = executable('test-static-link', 'app.c', + dependencies : dependency('gio-2.0', static : true) +) +test('test-static-link', app) diff --git a/gio/tests/stream-rw_all.c b/gio/tests/stream-rw_all.c new file mode 100644 index 0000000..a5210b5 --- /dev/null +++ b/gio/tests/stream-rw_all.c @@ -0,0 +1,258 @@ +/* + * Copyright © 2014 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Ryan Lortie + */ + +#include +#include + +static gboolean expected_read_success; +static guint expected_read; +static gboolean got_read_done; + +static void +read_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + gboolean success; + gsize read; + + success = g_input_stream_read_all_finish (G_INPUT_STREAM (source), result, &read, NULL); + g_assert_cmpint (expected_read_success, ==, success); + g_assert_cmpint (expected_read, ==, read); + got_read_done = TRUE; +} + +static void +wait_for_read (gboolean success, + gsize read) +{ + g_assert (!got_read_done); + expected_read_success = success; + expected_read = read; + + while (!got_read_done) + g_main_context_iteration (NULL, TRUE); + + got_read_done = FALSE; +} + +static gboolean expected_write_success; +static guint expected_written; +static gboolean got_write_done; + +static void +write_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + gboolean success; + gsize written; + + success = g_output_stream_write_all_finish (G_OUTPUT_STREAM (source), result, &written, NULL); + g_assert_cmpint (expected_write_success, ==, success); + g_assert_cmpint (expected_written, ==, written); + got_write_done = TRUE; +} + +static void +wait_for_write (gboolean success, + gsize written) +{ + g_assert (!got_write_done); + expected_write_success = success; + expected_written = written; + + while (!got_write_done) + g_main_context_iteration (NULL, TRUE); + + got_write_done = FALSE; +} + +static void +test_write_all_async_memory (void) +{ + GOutputStream *ms; + gchar b[24]; + + ms = g_memory_output_stream_new (b, sizeof b, NULL, NULL); + + g_output_stream_write_all_async (ms, "0123456789", 10, 0, NULL, write_done, NULL); + wait_for_write (TRUE, 10); + + g_output_stream_write_all_async (ms, "0123456789", 10, 0, NULL, write_done, NULL); + wait_for_write (TRUE, 10); + + /* this will trigger an out-of-space error, but we will see the + * partial write... + */ + g_output_stream_write_all_async (ms, "0123456789", 10, 0, NULL, write_done, NULL); + wait_for_write (FALSE, 4); + + /* and still an error, but no further bytes written */ + g_output_stream_write_all_async (ms, "0123456789", 10, 0, NULL, write_done, NULL); + wait_for_write (FALSE, 0); + + g_assert (!memcmp (b, "012345678901234567890123", 24)); + + g_object_unref (ms); +} + +static void +test_read_all_async_memory (void) +{ + GInputStream *ms; + gchar b[24] = "0123456789ABCDEFGHIJ!@#$"; + gchar buf[10]; + + ms = g_memory_input_stream_new_from_data (b, sizeof b, NULL); + + g_input_stream_read_all_async (ms, buf, 10, 0, NULL, read_done, NULL); + wait_for_read (TRUE, 10); + g_assert (!memcmp (buf, "0123456789", 10)); + + g_input_stream_read_all_async (ms, buf, 10, 0, NULL, read_done, NULL); + wait_for_read (TRUE, 10); + g_assert (!memcmp (buf, "ABCDEFGHIJ", 10)); + + /* partial read... */ + g_input_stream_read_all_async (ms, buf, 10, 0, NULL, read_done, NULL); + wait_for_read (TRUE, 4); + g_assert (!memcmp (buf, "!@#$", 4)); + + /* EOF */ + g_input_stream_read_all_async (ms, buf, 10, 0, NULL, read_done, NULL); + wait_for_read (TRUE, 0); + + g_object_unref (ms); +} + +#ifdef G_OS_UNIX +#include +#include +#include +#include +#include + +static void +test_read_write_all_async_pipe (void) +{ + GCancellable *cancellable; + GError *error = NULL; + GOutputStream *out; + GInputStream *in; + gsize in_flight; + gsize s; + gchar wbuf[100] = { 0, }; + gchar rbuf[100]; + + { + gint sv[2]; + gint s; + + s = socketpair (AF_UNIX, SOCK_STREAM, 0, sv); + g_assert (s == 0); + + out = g_unix_output_stream_new (sv[0], TRUE); + in = g_unix_input_stream_new (sv[1], TRUE); + } + + /* Try to fill up the buffer */ + in_flight = 0; + while (g_pollable_output_stream_is_writable (G_POLLABLE_OUTPUT_STREAM (out))) + { + s = g_output_stream_write (out, wbuf, sizeof wbuf, NULL, &error); + g_assert_no_error (error); + g_assert (s > 0); + in_flight += s; + } + + /* Now start a blocking write_all; nothing should happen. */ + cancellable = g_cancellable_new (); + g_output_stream_write_all_async (out, "0123456789", 10, 0, cancellable, write_done, NULL); + while (g_main_context_iteration (NULL, FALSE)) + ; + g_assert (!got_write_done); + + /* Cancel that to make sure it works */ + g_cancellable_cancel (cancellable); + g_object_unref (cancellable); + wait_for_write (FALSE, 0); + + /* Start it again */ + g_output_stream_write_all_async (out, "0123456789", 10, 0, NULL, write_done, NULL); + while (g_main_context_iteration (NULL, FALSE)) + ; + g_assert (!got_write_done); + + /* Now drain as much as we originally put in the buffer to make it + * block -- this will unblock the writer. + */ + while (in_flight) + { + s = g_input_stream_read (in, rbuf, MIN (sizeof wbuf, in_flight), NULL, &error); + g_assert_no_error (error); + g_assert (s > 0); + in_flight -= s; + } + + /* That will have caused some writing to start happening. Do a + * read_all as well, for more bytes than was written. + */ + g_input_stream_read_all_async (in, rbuf, sizeof rbuf, 0, NULL, read_done, NULL); + + /* The write is surely finished by now */ + wait_for_write (TRUE, 10); + /* ...but the read will not yet be satisfied */ + g_assert (!got_read_done); + + /* Feed the read more than it asked for; this really should not block + * since the buffer is so small... + */ + g_output_stream_write_all (out, wbuf, sizeof wbuf, 0, NULL, &error); + g_assert_no_error (error); + + /* Read will have finished now */ + wait_for_read (TRUE, sizeof rbuf); + + /* Close the writer end to make an EOF condition */ + g_output_stream_close (out, NULL, NULL); + + /* ... and we should have exactly 10 extra bytes left in the buffer */ + g_input_stream_read_all_async (in, rbuf, sizeof rbuf, 0, NULL, read_done, NULL); + wait_for_read (TRUE, 10); + + g_object_unref (out); + g_object_unref (in); +} +#endif + +int +main (int argc, + char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/stream/read_all_async/memory", test_read_all_async_memory); + g_test_add_func ("/stream/write_all_async/memory", test_write_all_async_memory); +#ifdef G_OS_UNIX + g_test_add_func ("/stream/read_write_all_async/pipe", test_read_write_all_async_pipe); +#endif + + return g_test_run(); +} diff --git a/gio/tests/taptestrunner.py b/gio/tests/taptestrunner.py new file mode 100644 index 0000000..9ce3b43 --- /dev/null +++ b/gio/tests/taptestrunner.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright (c) 2015 Remko Tronçon (https://el-tramo.be) +# Copied from https://github.com/remko/pycotap/ +# +# Released under the MIT license +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +import unittest +import sys +import base64 +from io import StringIO + + +# Log modes +class LogMode(object): + LogToError, LogToDiagnostics, LogToYAML, LogToAttachment = range(4) + + +class TAPTestResult(unittest.TestResult): + def __init__(self, output_stream, error_stream, message_log, test_output_log): + super(TAPTestResult, self).__init__(self, output_stream) + self.output_stream = output_stream + self.error_stream = error_stream + self.orig_stdout = None + self.orig_stderr = None + self.message = None + self.test_output = None + self.message_log = message_log + self.test_output_log = test_output_log + self.output_stream.write("TAP version 13\n") + self._set_streams() + + def printErrors(self): + self.print_raw("1..%d\n" % self.testsRun) + self._reset_streams() + + def _set_streams(self): + self.orig_stdout = sys.stdout + self.orig_stderr = sys.stderr + if self.message_log == LogMode.LogToError: + self.message = self.error_stream + else: + self.message = StringIO() + if self.test_output_log == LogMode.LogToError: + self.test_output = self.error_stream + else: + self.test_output = StringIO() + + if self.message_log == self.test_output_log: + self.test_output = self.message + sys.stdout = sys.stderr = self.test_output + + def _reset_streams(self): + sys.stdout = self.orig_stdout + sys.stderr = self.orig_stderr + + def print_raw(self, text): + self.output_stream.write(text) + self.output_stream.flush() + + def print_result(self, result, test, directive=None): + self.output_stream.write("%s %d %s" % (result, self.testsRun, test.id())) + if directive: + self.output_stream.write(" # " + directive) + self.output_stream.write("\n") + self.output_stream.flush() + + def ok(self, test, directive=None): + self.print_result("ok", test, directive) + + def not_ok(self, test): + self.print_result("not ok", test) + + def startTest(self, test): + super(TAPTestResult, self).startTest(test) + + def stopTest(self, test): + super(TAPTestResult, self).stopTest(test) + if self.message_log == self.test_output_log: + logs = [(self.message_log, self.message, "output")] + else: + logs = [ + (self.test_output_log, self.test_output, "test_output"), + (self.message_log, self.message, "message"), + ] + for log_mode, log, log_name in logs: + if log_mode != LogMode.LogToError: + output = log.getvalue() + if len(output): + if log_mode == LogMode.LogToYAML: + self.print_raw(" ---\n") + self.print_raw(" " + log_name + ": |\n") + self.print_raw( + " " + output.rstrip().replace("\n", "\n ") + "\n" + ) + self.print_raw(" ...\n") + elif log_mode == LogMode.LogToAttachment: + self.print_raw(" ---\n") + self.print_raw(" " + log_name + ":\n") + self.print_raw(" File-Name: " + log_name + ".txt\n") + self.print_raw(" File-Type: text/plain\n") + self.print_raw( + " File-Content: " + base64.b64encode(output) + "\n" + ) + self.print_raw(" ...\n") + else: + self.print_raw( + "# " + output.rstrip().replace("\n", "\n# ") + "\n" + ) + # Truncate doesn't change the current stream position. + # Seek to the beginning to avoid extensions on subsequent writes. + log.seek(0) + log.truncate(0) + + def addSuccess(self, test): + super(TAPTestResult, self).addSuccess(test) + self.ok(test) + + def addError(self, test, err): + super(TAPTestResult, self).addError(test, err) + self.message.write(self.errors[-1][1] + "\n") + self.not_ok(test) + + def addFailure(self, test, err): + super(TAPTestResult, self).addFailure(test, err) + self.message.write(self.failures[-1][1] + "\n") + self.not_ok(test) + + def addSkip(self, test, reason): + super(TAPTestResult, self).addSkip(test, reason) + self.ok(test, "SKIP " + reason) + + def addExpectedFailure(self, test, err): + super(TAPTestResult, self).addExpectedFailure(test, err) + self.ok(test) + + def addUnexpectedSuccess(self, test): + super(TAPTestResult, self).addUnexpectedSuccess(test) + self.message.write("Unexpected success" + "\n") + self.not_ok(test) + + +class TAPTestRunner(object): + def __init__( + self, + message_log=LogMode.LogToYAML, + test_output_log=LogMode.LogToDiagnostics, + output_stream=sys.stdout, + error_stream=sys.stderr, + ): + self.output_stream = output_stream + self.error_stream = error_stream + self.message_log = message_log + self.test_output_log = test_output_log + + def run(self, test): + result = TAPTestResult( + self.output_stream, + self.error_stream, + self.message_log, + self.test_output_log, + ) + test(result) + result.printErrors() + + return result diff --git a/gio/tests/task.c b/gio/tests/task.c new file mode 100644 index 0000000..7ce8438 --- /dev/null +++ b/gio/tests/task.c @@ -0,0 +1,2405 @@ +/* + * Copyright 2012-2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +#include +#include + +static GMainLoop *loop; +static GThread *main_thread; +static gssize magic; + +/* We need objects for a few tests where we don't care what type + * they are, just that they're GObjects. + */ +#define g_dummy_object_new g_socket_client_new + +static gboolean +idle_quit_loop (gpointer user_data) +{ + g_main_loop_quit (loop); + return FALSE; +} + +static void +completed_cb (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + gboolean *notification_emitted = user_data; + *notification_emitted = TRUE; +} + +static void +wait_for_completed_notification (GTask *task) +{ + gboolean notification_emitted = FALSE; + gboolean is_completed = FALSE; + + /* Hold a ref. so we can check the :completed property afterwards. */ + g_object_ref (task); + + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + g_idle_add (idle_quit_loop, NULL); + g_main_loop_run (loop); + g_assert_true (notification_emitted); + + g_assert_true (g_task_get_completed (task)); + g_object_get (G_OBJECT (task), "completed", &is_completed, NULL); + g_assert_true (is_completed); + + g_object_unref (task); +} + +/* test_basic */ + +static void +basic_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gssize *result_out = user_data; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + *result_out = g_task_propagate_int (G_TASK (result), &error); + g_assert_no_error (error); + + g_assert (!g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static gboolean +basic_return (gpointer user_data) +{ + GTask *task = user_data; + + g_task_return_int (task, magic); + g_object_unref (task); + + return FALSE; +} + +static void +basic_destroy_notify (gpointer user_data) +{ + gboolean *destroyed = user_data; + + *destroyed = TRUE; +} + +static void +test_basic (void) +{ + GTask *task; + gssize result; + gboolean task_data_destroyed = FALSE; + gboolean notification_emitted = FALSE; + + task = g_task_new (NULL, NULL, basic_callback, &result); + g_task_set_task_data (task, &task_data_destroyed, basic_destroy_notify); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + g_idle_add (basic_return, task); + g_main_loop_run (loop); + + g_assert_cmpint (result, ==, magic); + g_assert (task_data_destroyed == TRUE); + g_assert_true (notification_emitted); + g_assert (task == NULL); +} + +/* test_error */ + +static void +error_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gssize *result_out = user_data; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + *result_out = g_task_propagate_int (G_TASK (result), &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_error_free (error); + + g_assert (g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static gboolean +error_return (gpointer user_data) +{ + GTask *task = user_data; + + g_task_return_new_error (task, + G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed"); + g_object_unref (task); + + return FALSE; +} + +static void +error_destroy_notify (gpointer user_data) +{ + gboolean *destroyed = user_data; + + *destroyed = TRUE; +} + +static void +test_error (void) +{ + GTask *task; + gssize result; + gboolean first_task_data_destroyed = FALSE; + gboolean second_task_data_destroyed = FALSE; + gboolean notification_emitted = FALSE; + + task = g_task_new (NULL, NULL, error_callback, &result); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + g_assert (first_task_data_destroyed == FALSE); + g_task_set_task_data (task, &first_task_data_destroyed, error_destroy_notify); + g_assert (first_task_data_destroyed == FALSE); + + /* Calling g_task_set_task_data() again will destroy the first data */ + g_task_set_task_data (task, &second_task_data_destroyed, error_destroy_notify); + g_assert (first_task_data_destroyed == TRUE); + g_assert (second_task_data_destroyed == FALSE); + + g_idle_add (error_return, task); + g_main_loop_run (loop); + + g_assert_cmpint (result, ==, -1); + g_assert (second_task_data_destroyed == TRUE); + g_assert_true (notification_emitted); + g_assert (task == NULL); +} + +/* test_return_from_same_iteration: calling g_task_return_* from the + * loop iteration the task was created in defers completion until the + * next iteration. + */ +gboolean same_result = FALSE; +gboolean same_notification_emitted = FALSE; + +static void +same_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *result_out = user_data; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + *result_out = g_task_propagate_boolean (G_TASK (result), &error); + g_assert_no_error (error); + + g_assert (!g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static gboolean +same_start (gpointer user_data) +{ + gpointer *weak_pointer = user_data; + GTask *task; + + task = g_task_new (NULL, NULL, same_callback, &same_result); + *weak_pointer = task; + g_object_add_weak_pointer (G_OBJECT (task), weak_pointer); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, &same_notification_emitted); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); + + /* same_callback should not have been invoked yet */ + g_assert (same_result == FALSE); + g_assert (*weak_pointer == task); + g_assert_false (same_notification_emitted); + + return FALSE; +} + +static void +test_return_from_same_iteration (void) +{ + gpointer weak_pointer; + + g_idle_add (same_start, &weak_pointer); + g_main_loop_run (loop); + + g_assert (same_result == TRUE); + g_assert (weak_pointer == NULL); + g_assert_true (same_notification_emitted); +} + +/* test_return_from_toplevel: calling g_task_return_* from outside any + * main loop completes the task inside the main loop. + */ +gboolean toplevel_notification_emitted = FALSE; + +static void +toplevel_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *result_out = user_data; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + *result_out = g_task_propagate_boolean (G_TASK (result), &error); + g_assert_no_error (error); + + g_assert (!g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static void +test_return_from_toplevel (void) +{ + GTask *task; + gboolean result = FALSE; + + task = g_task_new (NULL, NULL, toplevel_callback, &result); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, &toplevel_notification_emitted); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); + + /* toplevel_callback should not have been invoked yet */ + g_assert (result == FALSE); + g_assert (task != NULL); + g_assert_false (toplevel_notification_emitted); + + g_main_loop_run (loop); + + g_assert (result == TRUE); + g_assert (task == NULL); + g_assert_true (toplevel_notification_emitted); +} + +/* test_return_from_anon_thread: calling g_task_return_* from a + * thread with no thread-default main context will complete the + * task in the task's context/thread. + */ + +gboolean anon_thread_notification_emitted = FALSE; +GThread *anon_thread; + +static void +anon_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gssize *result_out = user_data; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + g_assert (g_thread_self () == main_thread); + + *result_out = g_task_propagate_int (G_TASK (result), &error); + g_assert_no_error (error); + + g_assert (!g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static gpointer +anon_thread_func (gpointer user_data) +{ + GTask *task = user_data; + + g_task_return_int (task, magic); + g_object_unref (task); + + return NULL; +} + +static gboolean +anon_start (gpointer user_data) +{ + GTask *task = user_data; + + anon_thread = g_thread_new ("test_return_from_anon_thread", + anon_thread_func, task); + return FALSE; +} + +static void +test_return_from_anon_thread (void) +{ + GTask *task; + gssize result = 0; + + task = g_task_new (NULL, NULL, anon_callback, &result); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, + &anon_thread_notification_emitted); + + g_idle_add (anon_start, task); + g_main_loop_run (loop); + + g_thread_join (anon_thread); + + g_assert_cmpint (result, ==, magic); + g_assert (task == NULL); + g_assert_true (anon_thread_notification_emitted); +} + +/* test_return_from_wrong_thread: calling g_task_return_* from a + * thread with its own thread-default main context will complete the + * task in the task's context/thread. + */ + +gboolean wrong_thread_notification_emitted = FALSE; +GThread *wrong_thread; + +static void +wrong_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gssize *result_out = user_data; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + g_assert (g_thread_self () == main_thread); + + *result_out = g_task_propagate_int (G_TASK (result), &error); + g_assert_no_error (error); + + g_assert (!g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static gpointer +wrong_thread_func (gpointer user_data) +{ + GTask *task = user_data; + GMainContext *context; + + context = g_main_context_new (); + g_main_context_push_thread_default (context); + + g_assert (g_task_get_context (task) != context); + + g_task_return_int (task, magic); + g_object_unref (task); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); + + return NULL; +} + +static gboolean +wrong_start (gpointer user_data) +{ + GTask *task = user_data; + + wrong_thread = g_thread_new ("test_return_from_anon_thread", + wrong_thread_func, task); + return FALSE; +} + +static void +test_return_from_wrong_thread (void) +{ + GTask *task; + gssize result = 0; + + task = g_task_new (NULL, NULL, wrong_callback, &result); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, + &wrong_thread_notification_emitted); + + g_idle_add (wrong_start, task); + g_main_loop_run (loop); + + g_thread_join (wrong_thread); + + g_assert_cmpint (result, ==, magic); + g_assert (task == NULL); + g_assert_true (wrong_thread_notification_emitted); +} + +/* test_no_callback */ + +static void +test_no_callback (void) +{ + GTask *task; + + task = g_task_new (NULL, NULL, NULL, NULL); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); + + /* Even though there’s no callback, the :completed notification has to + * happen in an idle handler. */ + g_assert_nonnull (task); + wait_for_completed_notification (task); + g_assert_null (task); +} + +/* test_report_error */ + +static void test_report_error (void); +gboolean error_notification_emitted = FALSE; + +static void +report_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gpointer *weak_pointer = user_data; + GError *error = NULL; + gssize ret; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (g_async_result_is_tagged (result, test_report_error)); + g_assert (g_task_get_source_tag (G_TASK (result)) == test_report_error); + g_assert (g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + ret = g_task_propagate_int (G_TASK (result), &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_assert_cmpint (ret, ==, -1); + g_error_free (error); + + g_assert (g_task_had_error (G_TASK (result))); + + *weak_pointer = result; + g_object_add_weak_pointer (G_OBJECT (result), weak_pointer); + g_signal_connect (result, "notify::completed", + (GCallback) completed_cb, &error_notification_emitted); + + g_main_loop_quit (loop); +} + +static void +test_report_error (void) +{ + gpointer weak_pointer = (gpointer)-1; + + g_task_report_new_error (NULL, report_callback, &weak_pointer, + test_report_error, + G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed"); + g_main_loop_run (loop); + + g_assert (weak_pointer == NULL); + g_assert_true (error_notification_emitted); +} + +/* test_priority: tasks complete in priority order */ + +static int counter = 0; + +static void +priority_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gssize *ret_out = user_data; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + g_task_propagate_boolean (G_TASK (result), &error); + g_assert_no_error (error); + + g_assert (!g_task_had_error (G_TASK (result))); + + *ret_out = ++counter; + + if (counter == 3) + g_main_loop_quit (loop); +} + +static void +test_priority (void) +{ + GTask *t1, *t2, *t3; + gssize ret1, ret2, ret3; + + /* t2 has higher priority than either t1 or t3, so we can't + * accidentally pass the test just by completing the tasks in the + * order they were created (or in reverse order). + */ + + t1 = g_task_new (NULL, NULL, priority_callback, &ret1); + g_task_set_priority (t1, G_PRIORITY_DEFAULT); + g_task_return_boolean (t1, TRUE); + g_object_unref (t1); + + t2 = g_task_new (NULL, NULL, priority_callback, &ret2); + g_task_set_priority (t2, G_PRIORITY_HIGH); + g_task_return_boolean (t2, TRUE); + g_object_unref (t2); + + t3 = g_task_new (NULL, NULL, priority_callback, &ret3); + g_task_set_priority (t3, G_PRIORITY_LOW); + g_task_return_boolean (t3, TRUE); + g_object_unref (t3); + + g_main_loop_run (loop); + + g_assert_cmpint (ret2, ==, 1); + g_assert_cmpint (ret1, ==, 2); + g_assert_cmpint (ret3, ==, 3); +} + +/* Test that getting and setting the task name works. */ +static void name_callback (GObject *object, + GAsyncResult *result, + gpointer user_data); + +static void +test_name (void) +{ + GTask *t1 = NULL; + gchar *name1 = NULL; + + t1 = g_task_new (NULL, NULL, name_callback, &name1); + g_task_set_name (t1, "some task"); + g_task_return_boolean (t1, TRUE); + g_object_unref (t1); + + g_main_loop_run (loop); + + g_assert_cmpstr (name1, ==, "some task"); + + g_free (name1); +} + +static void +name_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gchar **name_out = user_data; + GError *local_error = NULL; + + g_assert_null (*name_out); + *name_out = g_strdup (g_task_get_name (G_TASK (result))); + + g_task_propagate_boolean (G_TASK (result), &local_error); + g_assert_no_error (local_error); + + g_main_loop_quit (loop); +} + +/* test_asynchronous_cancellation: cancelled tasks are returned + * asynchronously, i.e. not from inside the GCancellable::cancelled + * handler. + * + * The test is set up further below in test_asynchronous_cancellation. + */ + +/* asynchronous_cancellation_callback represents the callback that the + * caller of a typical asynchronous API would have passed. See + * test_asynchronous_cancellation. + */ +static void +asynchronous_cancellation_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + guint run_task_id; + + g_assert_null (object); + g_assert_true (g_task_is_valid (result, object)); + g_assert_true (g_async_result_get_user_data (result) == user_data); + g_assert_true (g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (G_TASK (result))); + g_assert_cmpuint (run_task_id, ==, 0); + + g_task_propagate_boolean (G_TASK (result), &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + + g_assert_true (g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +/* asynchronous_cancellation_cancel_task represents a user cancelling + * the ongoing operation. To make it somewhat realistic it is delayed + * by 50ms via a timeout GSource. See test_asynchronous_cancellation. + */ +static gboolean +asynchronous_cancellation_cancel_task (gpointer user_data) +{ + GCancellable *cancellable; + GTask *task = G_TASK (user_data); + + cancellable = g_task_get_cancellable (task); + g_assert_true (G_IS_CANCELLABLE (cancellable)); + + g_cancellable_cancel (cancellable); + g_assert_false (g_task_get_completed (task)); + + return G_SOURCE_REMOVE; +} + +/* asynchronous_cancellation_cancelled is the GCancellable::cancelled + * handler that's used by the asynchronous implementation for + * cancelling itself. + */ +static void +asynchronous_cancellation_cancelled (GCancellable *cancellable, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + guint run_task_id; + + g_assert_true (cancellable == g_task_get_cancellable (task)); + + run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (task)); + g_assert_cmpuint (run_task_id, !=, 0); + + g_source_remove (run_task_id); + g_task_set_task_data (task, GUINT_TO_POINTER (0), NULL); + + g_task_return_boolean (task, FALSE); + g_assert_false (g_task_get_completed (task)); +} + +/* asynchronous_cancellation_run_task represents the actual + * asynchronous work being done in an idle GSource as was mentioned + * above. This is effectively meant to be an infinite loop so that + * the only way to break out of it is via cancellation. + */ +static gboolean +asynchronous_cancellation_run_task (gpointer user_data) +{ + GCancellable *cancellable; + GTask *task = G_TASK (user_data); + + cancellable = g_task_get_cancellable (task); + g_assert_true (G_IS_CANCELLABLE (cancellable)); + g_assert_false (g_cancellable_is_cancelled (cancellable)); + + return G_SOURCE_CONTINUE; +} + +/* Test that cancellation is always asynchronous. The completion callback for + * a #GTask must not be called from inside the cancellation handler. + * + * The body of the loop inside test_asynchronous_cancellation + * represents what would have been a typical asynchronous API call, + * and its implementation. They are fused together without an API + * boundary. The actual work done by this asynchronous API is + * represented by an idle GSource. + */ +static void +test_asynchronous_cancellation (void) +{ + guint i; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1608"); + + /* Run a few times to shake out any timing issues between the + * cancellation and task sources. + */ + for (i = 0; i < 5; i++) + { + GCancellable *cancellable; + GTask *task; + gboolean notification_emitted = FALSE; + guint run_task_id; + + cancellable = g_cancellable_new (); + + task = g_task_new (NULL, cancellable, asynchronous_cancellation_callback, NULL); + g_cancellable_connect (cancellable, (GCallback) asynchronous_cancellation_cancelled, task, NULL); + g_signal_connect (task, "notify::completed", (GCallback) completed_cb, ¬ification_emitted); + + run_task_id = g_idle_add (asynchronous_cancellation_run_task, task); + g_source_set_name_by_id (run_task_id, "[test_asynchronous_cancellation] run_task"); + g_task_set_task_data (task, GUINT_TO_POINTER (run_task_id), NULL); + + g_timeout_add (50, asynchronous_cancellation_cancel_task, task); + + g_main_loop_run (loop); + + g_assert_true (g_task_get_completed (task)); + g_assert_true (notification_emitted); + + g_object_unref (cancellable); + g_object_unref (task); + } +} + +/* test_check_cancellable: cancellation overrides return value */ + +enum { + CANCEL_BEFORE = (1 << 1), + CANCEL_AFTER = (1 << 2), + CHECK_CANCELLABLE = (1 << 3) +}; +#define NUM_CANCEL_TESTS (CANCEL_BEFORE | CANCEL_AFTER | CHECK_CANCELLABLE) + +static void +cancel_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + int state = GPOINTER_TO_INT (user_data); + GTask *task; + GCancellable *cancellable; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + + task = G_TASK (result); + cancellable = g_task_get_cancellable (task); + g_assert (G_IS_CANCELLABLE (cancellable)); + + if (state & (CANCEL_BEFORE | CANCEL_AFTER)) + g_assert (g_cancellable_is_cancelled (cancellable)); + else + g_assert (!g_cancellable_is_cancelled (cancellable)); + + if (state & CHECK_CANCELLABLE) + g_assert (g_task_get_check_cancellable (task)); + else + g_assert (!g_task_get_check_cancellable (task)); + + if (g_task_propagate_boolean (task, &error)) + { + g_assert (!g_cancellable_is_cancelled (cancellable) || + !g_task_get_check_cancellable (task)); + } + else + { + g_assert (g_cancellable_is_cancelled (cancellable) && + g_task_get_check_cancellable (task)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_error_free (error); + } + + g_main_loop_quit (loop); +} + +static void +test_check_cancellable (void) +{ + GTask *task; + GCancellable *cancellable; + int state; + + cancellable = g_cancellable_new (); + + for (state = 0; state <= NUM_CANCEL_TESTS; state++) + { + task = g_task_new (NULL, cancellable, cancel_callback, + GINT_TO_POINTER (state)); + g_task_set_check_cancellable (task, (state & CHECK_CANCELLABLE) != 0); + + if (state & CANCEL_BEFORE) + g_cancellable_cancel (cancellable); + g_task_return_boolean (task, TRUE); + if (state & CANCEL_AFTER) + g_cancellable_cancel (cancellable); + + g_main_loop_run (loop); + g_object_unref (task); + g_cancellable_reset (cancellable); + } + + g_object_unref (cancellable); +} + +/* test_return_if_cancelled */ + +static void +return_if_cancelled_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + g_task_propagate_boolean (G_TASK (result), &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + + g_assert (g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static void +test_return_if_cancelled (void) +{ + GTask *task; + GCancellable *cancellable; + gboolean cancelled; + gboolean notification_emitted = FALSE; + + cancellable = g_cancellable_new (); + + task = g_task_new (NULL, cancellable, return_if_cancelled_callback, NULL); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + g_cancellable_cancel (cancellable); + cancelled = g_task_return_error_if_cancelled (task); + g_assert (cancelled); + g_assert_false (notification_emitted); + g_main_loop_run (loop); + g_object_unref (task); + g_assert_true (notification_emitted); + g_cancellable_reset (cancellable); + + notification_emitted = FALSE; + + task = g_task_new (NULL, cancellable, return_if_cancelled_callback, NULL); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + g_task_set_check_cancellable (task, FALSE); + g_cancellable_cancel (cancellable); + cancelled = g_task_return_error_if_cancelled (task); + g_assert (cancelled); + g_assert_false (notification_emitted); + g_main_loop_run (loop); + g_object_unref (task); + g_assert_true (notification_emitted); + g_object_unref (cancellable); +} + +/* test_run_in_thread */ + +static GMutex run_in_thread_mutex; +static GCond run_in_thread_cond; + +static void +task_weak_notify (gpointer user_data, + GObject *ex_task) +{ + gboolean *weak_notify_ran = user_data; + + g_mutex_lock (&run_in_thread_mutex); + g_atomic_int_set (weak_notify_ran, TRUE); + g_cond_signal (&run_in_thread_cond); + g_mutex_unlock (&run_in_thread_mutex); +} + +static void +run_in_thread_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *done = user_data; + GError *error = NULL; + gssize ret; + + g_assert (g_thread_self () == main_thread); + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + g_assert_cmpstr (g_task_get_name (G_TASK (result)), ==, "test_run_in_thread name"); + + ret = g_task_propagate_int (G_TASK (result), &error); + g_assert_no_error (error); + g_assert_cmpint (ret, ==, magic); + + g_assert (!g_task_had_error (G_TASK (result))); + + *done = TRUE; + g_main_loop_quit (loop); +} + +static void +run_in_thread_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + gboolean *thread_ran = task_data; + + g_assert (source_object == g_task_get_source_object (task)); + g_assert (task_data == g_task_get_task_data (task)); + g_assert (cancellable == g_task_get_cancellable (task)); + g_assert_false (g_task_get_completed (task)); + g_assert_cmpstr (g_task_get_name (task), ==, "test_run_in_thread name"); + + g_assert (g_thread_self () != main_thread); + + g_mutex_lock (&run_in_thread_mutex); + g_atomic_int_set (thread_ran, TRUE); + g_cond_signal (&run_in_thread_cond); + g_mutex_unlock (&run_in_thread_mutex); + + g_task_return_int (task, magic); +} + +static void +test_run_in_thread (void) +{ + GTask *task; + gboolean thread_ran = FALSE; /* (atomic) */ + gboolean weak_notify_ran = FALSE; /* (atomic) */ + gboolean notification_emitted = FALSE; + gboolean done = FALSE; + + task = g_task_new (NULL, NULL, run_in_thread_callback, &done); + g_task_set_name (task, "test_run_in_thread name"); + g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + g_task_set_task_data (task, (gpointer)&thread_ran, NULL); + g_task_run_in_thread (task, run_in_thread_thread); + + g_mutex_lock (&run_in_thread_mutex); + while (!g_atomic_int_get (&thread_ran)) + g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); + g_mutex_unlock (&run_in_thread_mutex); + + g_assert (done == FALSE); + g_assert_false (g_atomic_int_get (&weak_notify_ran)); + + g_main_loop_run (loop); + + g_assert (done == TRUE); + g_assert_true (notification_emitted); + + g_assert_cmpstr (g_task_get_name (task), ==, "test_run_in_thread name"); + + g_object_unref (task); + + g_mutex_lock (&run_in_thread_mutex); + while (!g_atomic_int_get (&weak_notify_ran)) + g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); + g_mutex_unlock (&run_in_thread_mutex); +} + +/* test_run_in_thread_sync */ + +static void +run_in_thread_sync_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + /* g_task_run_in_thread_sync() does not invoke the task's callback */ + g_assert_not_reached (); +} + +static void +run_in_thread_sync_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + gboolean *thread_ran = task_data; + + g_assert (source_object == g_task_get_source_object (task)); + g_assert (task_data == g_task_get_task_data (task)); + g_assert (cancellable == g_task_get_cancellable (task)); + g_assert_false (g_task_get_completed (task)); + + g_assert (g_thread_self () != main_thread); + + g_atomic_int_set (thread_ran, TRUE); + g_task_return_int (task, magic); +} + +static void +test_run_in_thread_sync (void) +{ + GTask *task; + gboolean thread_ran = FALSE; + gssize ret; + gboolean notification_emitted = FALSE; + GError *error = NULL; + + task = g_task_new (NULL, NULL, run_in_thread_sync_callback, NULL); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, + ¬ification_emitted); + + g_task_set_task_data (task, &thread_ran, NULL); + g_task_run_in_thread_sync (task, run_in_thread_sync_thread); + + g_assert_true (g_atomic_int_get (&thread_ran)); + g_assert (task != NULL); + g_assert (!g_task_had_error (task)); + g_assert_true (g_task_get_completed (task)); + g_assert_true (notification_emitted); + + ret = g_task_propagate_int (task, &error); + g_assert_no_error (error); + g_assert_cmpint (ret, ==, magic); + + g_assert (!g_task_had_error (task)); + + g_object_unref (task); +} + +/* test_run_in_thread_priority */ + +static GMutex fake_task_mutex, last_fake_task_mutex; +static gint sequence_number = 0; + +static void +quit_main_loop_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + gboolean ret; + + g_assert (g_thread_self () == main_thread); + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + ret = g_task_propagate_boolean (G_TASK (result), &error); + g_assert_no_error (error); + g_assert_cmpint (ret, ==, TRUE); + + g_assert (!g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static void +set_sequence_number_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + gint *seq_no_p = task_data; + + *seq_no_p = ++sequence_number; + g_task_return_boolean (task, TRUE); +} + +static void +fake_task_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GMutex *mutex = task_data; + + g_mutex_lock (mutex); + g_mutex_unlock (mutex); + g_task_return_boolean (task, TRUE); +} + +#define G_TASK_THREAD_POOL_SIZE 10 +static int fake_tasks_running; + +static void +fake_task_callback (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + if (--fake_tasks_running == 0) + g_main_loop_quit (loop); +} + +static void +clog_up_thread_pool (void) +{ + GTask *task; + int i; + + g_thread_pool_stop_unused_threads (); + + g_mutex_lock (&fake_task_mutex); + for (i = 0; i < G_TASK_THREAD_POOL_SIZE - 1; i++) + { + task = g_task_new (NULL, NULL, fake_task_callback, NULL); + g_task_set_task_data (task, &fake_task_mutex, NULL); + g_assert_cmpint (g_task_get_priority (task), ==, G_PRIORITY_DEFAULT); + g_task_set_priority (task, G_PRIORITY_HIGH * 2); + g_assert_cmpint (g_task_get_priority (task), ==, G_PRIORITY_HIGH * 2); + g_task_run_in_thread (task, fake_task_thread); + g_object_unref (task); + fake_tasks_running++; + } + + g_mutex_lock (&last_fake_task_mutex); + task = g_task_new (NULL, NULL, NULL, NULL); + g_task_set_task_data (task, &last_fake_task_mutex, NULL); + g_task_set_priority (task, G_PRIORITY_HIGH * 2); + g_task_run_in_thread (task, fake_task_thread); + g_object_unref (task); +} + +static void +unclog_thread_pool (void) +{ + g_mutex_unlock (&fake_task_mutex); + g_main_loop_run (loop); +} + +static void +test_run_in_thread_priority (void) +{ + GTask *task; + GCancellable *cancellable; + int seq_a, seq_b, seq_c, seq_d; + + clog_up_thread_pool (); + + /* Queue three more tasks that we'll arrange to have run serially */ + task = g_task_new (NULL, NULL, NULL, NULL); + g_task_set_task_data (task, &seq_a, NULL); + g_task_run_in_thread (task, set_sequence_number_thread); + g_object_unref (task); + + task = g_task_new (NULL, NULL, quit_main_loop_callback, NULL); + g_task_set_task_data (task, &seq_b, NULL); + g_task_set_priority (task, G_PRIORITY_LOW); + g_task_run_in_thread (task, set_sequence_number_thread); + g_object_unref (task); + + task = g_task_new (NULL, NULL, NULL, NULL); + g_task_set_task_data (task, &seq_c, NULL); + g_task_set_priority (task, G_PRIORITY_HIGH); + g_task_run_in_thread (task, set_sequence_number_thread); + g_object_unref (task); + + cancellable = g_cancellable_new (); + task = g_task_new (NULL, cancellable, NULL, NULL); + g_task_set_task_data (task, &seq_d, NULL); + g_task_run_in_thread (task, set_sequence_number_thread); + g_cancellable_cancel (cancellable); + g_object_unref (cancellable); + g_object_unref (task); + + /* Let the last fake task complete; the four other tasks will then + * complete serially, in the order D, C, A, B, and B will quit the + * main loop. + */ + g_mutex_unlock (&last_fake_task_mutex); + g_main_loop_run (loop); + + g_assert_cmpint (seq_d, ==, 1); + g_assert_cmpint (seq_c, ==, 2); + g_assert_cmpint (seq_a, ==, 3); + g_assert_cmpint (seq_b, ==, 4); + + unclog_thread_pool (); +} + +/* test_run_in_thread_nested: task threads that block waiting on + * other task threads will not cause the thread pool to starve. + */ + +static void +run_nested_task_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GTask *nested; + int *nested_tasks_left = task_data; + + if ((*nested_tasks_left)--) + { + nested = g_task_new (NULL, NULL, NULL, NULL); + g_task_set_task_data (nested, nested_tasks_left, NULL); + g_task_run_in_thread_sync (nested, run_nested_task_thread); + g_object_unref (nested); + } + + g_task_return_boolean (task, TRUE); +} + +static void +test_run_in_thread_nested (void) +{ + GTask *task; + int nested_tasks_left = 2; + + clog_up_thread_pool (); + + task = g_task_new (NULL, NULL, quit_main_loop_callback, NULL); + g_task_set_task_data (task, &nested_tasks_left, NULL); + g_task_run_in_thread (task, run_nested_task_thread); + g_object_unref (task); + + g_mutex_unlock (&last_fake_task_mutex); + g_main_loop_run (loop); + + unclog_thread_pool (); +} + +/* test_run_in_thread_overflow: if you queue lots and lots and lots of + * tasks, they won't all run at once. + */ +static GMutex overflow_mutex; +static guint overflow_completed; + +static void +run_overflow_task_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + gchar *result = task_data; + + if (g_task_return_error_if_cancelled (task)) + { + *result = 'X'; + } + else + { + /* Block until the main thread is ready. */ + g_mutex_lock (&overflow_mutex); + g_mutex_unlock (&overflow_mutex); + + *result = '.'; + + g_task_return_boolean (task, TRUE); + } + + g_atomic_int_inc (&overflow_completed); +} + +#define NUM_OVERFLOW_TASKS 1024 + +static void +test_run_in_thread_overflow (void) +{ + GCancellable *cancellable; + GTask *task; + gchar buf[NUM_OVERFLOW_TASKS + 1]; + gint i; + + /* Queue way too many tasks and then sleep for a bit. The first 10 + * tasks will be dispatched to threads and will then block on + * overflow_mutex, so more threads will be created while this thread + * is sleeping. Then we cancel the cancellable, unlock the mutex, + * wait for all of the tasks to complete, and make sure that we got + * the behavior we expected. + */ + + memset (buf, 0, sizeof (buf)); + cancellable = g_cancellable_new (); + + g_mutex_lock (&overflow_mutex); + + for (i = 0; i < NUM_OVERFLOW_TASKS; i++) + { + task = g_task_new (NULL, cancellable, NULL, NULL); + g_task_set_task_data (task, buf + i, NULL); + g_task_run_in_thread (task, run_overflow_task_thread); + g_object_unref (task); + } + + if (g_test_slow ()) + g_usleep (5000000); /* 5 s */ + else + g_usleep (500000); /* 0.5 s */ + g_cancellable_cancel (cancellable); + g_object_unref (cancellable); + + g_mutex_unlock (&overflow_mutex); + + /* Wait for all tasks to complete. */ + while (g_atomic_int_get (&overflow_completed) != NUM_OVERFLOW_TASKS) + g_usleep (1000); + + g_assert_cmpint (strlen (buf), ==, NUM_OVERFLOW_TASKS); + + i = strspn (buf, "."); + /* Given the sleep times above, i should be 14 for normal, 40 for + * slow. But if the machine is too slow/busy then the scheduling + * might get messed up and we'll get more or fewer threads than + * expected. But there are limits to how messed up it could + * plausibly get (and we hope that if gtask is actually broken then + * it will exceed those limits). + */ + g_assert_cmpint (i, >=, 10); + if (g_test_slow ()) + g_assert_cmpint (i, <, 50); + else + g_assert_cmpint (i, <, 20); + + g_assert_cmpint (i + strspn (buf + i, "X"), ==, NUM_OVERFLOW_TASKS); +} + +/* test_return_on_cancel */ + +GMutex roc_init_mutex, roc_finish_mutex; +GCond roc_init_cond, roc_finish_cond; + +typedef enum { + THREAD_STARTING, + THREAD_RUNNING, + THREAD_CANCELLED, + THREAD_COMPLETED +} ThreadState; + +static void +return_on_cancel_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *callback_ran = user_data; + GError *error = NULL; + gssize ret; + + g_assert (g_thread_self () == main_thread); + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + ret = g_task_propagate_int (G_TASK (result), &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + g_assert_cmpint (ret, ==, -1); + + g_assert (g_task_had_error (G_TASK (result))); + + *callback_ran = TRUE; + g_main_loop_quit (loop); +} + +static void +return_on_cancel_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + ThreadState *state = task_data; + + g_assert (source_object == g_task_get_source_object (task)); + g_assert (task_data == g_task_get_task_data (task)); + g_assert (cancellable == g_task_get_cancellable (task)); + + g_assert (g_thread_self () != main_thread); + + g_mutex_lock (&roc_init_mutex); + *state = THREAD_RUNNING; + g_cond_signal (&roc_init_cond); + g_mutex_unlock (&roc_init_mutex); + + g_mutex_lock (&roc_finish_mutex); + + if (!g_task_get_return_on_cancel (task) || + g_task_set_return_on_cancel (task, FALSE)) + { + *state = THREAD_COMPLETED; + g_task_return_int (task, magic); + } + else + *state = THREAD_CANCELLED; + + g_cond_signal (&roc_finish_cond); + g_mutex_unlock (&roc_finish_mutex); +} + +static void +test_return_on_cancel (void) +{ + GTask *task; + GCancellable *cancellable; + ThreadState thread_state; /* (atomic) */ + gboolean weak_notify_ran = FALSE; /* (atomic) */ + gboolean callback_ran; + gboolean notification_emitted = FALSE; + + cancellable = g_cancellable_new (); + + /* If return-on-cancel is FALSE (default), the task does not return + * early. + */ + callback_ran = FALSE; + g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + g_task_set_task_data (task, (gpointer)&thread_state, NULL); + g_mutex_lock (&roc_init_mutex); + g_mutex_lock (&roc_finish_mutex); + g_task_run_in_thread (task, return_on_cancel_thread); + g_object_unref (task); + + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + g_assert (callback_ran == FALSE); + + g_cancellable_cancel (cancellable); + g_mutex_unlock (&roc_finish_mutex); + g_main_loop_run (loop); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED); + g_assert (callback_ran == TRUE); + g_assert_true (notification_emitted); + + g_cancellable_reset (cancellable); + + /* If return-on-cancel is TRUE, it does return early */ + callback_ran = FALSE; + notification_emitted = FALSE; + g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); + g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + g_task_set_return_on_cancel (task, TRUE); + + g_task_set_task_data (task, (gpointer)&thread_state, NULL); + g_mutex_lock (&roc_init_mutex); + g_mutex_lock (&roc_finish_mutex); + g_task_run_in_thread (task, return_on_cancel_thread); + g_object_unref (task); + + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + g_assert (callback_ran == FALSE); + + g_cancellable_cancel (cancellable); + g_main_loop_run (loop); + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + g_assert (callback_ran == TRUE); + + g_assert_false (g_atomic_int_get (&weak_notify_ran)); + + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) + g_cond_wait (&roc_finish_cond, &roc_finish_mutex); + g_mutex_unlock (&roc_finish_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); + g_mutex_lock (&run_in_thread_mutex); + while (!g_atomic_int_get (&weak_notify_ran)) + g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); + g_mutex_unlock (&run_in_thread_mutex); + + g_assert_true (notification_emitted); + g_cancellable_reset (cancellable); + + /* If the task is already cancelled before it starts, it returns + * immediately, but the thread func still runs. + */ + callback_ran = FALSE; + notification_emitted = FALSE; + g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + g_task_set_return_on_cancel (task, TRUE); + + g_cancellable_cancel (cancellable); + + g_task_set_task_data (task, (gpointer)&thread_state, NULL); + g_mutex_lock (&roc_init_mutex); + g_mutex_lock (&roc_finish_mutex); + g_task_run_in_thread (task, return_on_cancel_thread); + g_object_unref (task); + + g_main_loop_run (loop); + g_assert (callback_ran == TRUE); + + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) + g_cond_wait (&roc_finish_cond, &roc_finish_mutex); + g_mutex_unlock (&roc_finish_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); + g_assert_true (notification_emitted); + + g_object_unref (cancellable); +} + +/* test_return_on_cancel_sync */ + +static gpointer +cancel_sync_runner_thread (gpointer task) +{ + g_task_run_in_thread_sync (task, return_on_cancel_thread); + return NULL; +} + +static void +test_return_on_cancel_sync (void) +{ + GTask *task; + GCancellable *cancellable; + ThreadState thread_state; /* (atomic) */ + GThread *runner_thread; + gssize ret; + GError *error = NULL; + + cancellable = g_cancellable_new (); + + /* If return-on-cancel is FALSE, the task does not return early. + */ + g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); + + g_task_set_task_data (task, (gpointer)&thread_state, NULL); + g_mutex_lock (&roc_init_mutex); + g_mutex_lock (&roc_finish_mutex); + runner_thread = g_thread_new ("return-on-cancel-sync runner thread", + cancel_sync_runner_thread, task); + + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + + g_cancellable_cancel (cancellable); + g_mutex_unlock (&roc_finish_mutex); + g_thread_join (runner_thread); + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED); + + ret = g_task_propagate_int (task, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + g_assert_cmpint (ret, ==, -1); + + g_object_unref (task); + + g_cancellable_reset (cancellable); + + /* If return-on-cancel is TRUE, it does return early */ + g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); + g_task_set_return_on_cancel (task, TRUE); + + g_task_set_task_data (task, (gpointer)&thread_state, NULL); + g_mutex_lock (&roc_init_mutex); + g_mutex_lock (&roc_finish_mutex); + runner_thread = g_thread_new ("return-on-cancel-sync runner thread", + cancel_sync_runner_thread, task); + + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + + g_cancellable_cancel (cancellable); + g_thread_join (runner_thread); + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + + ret = g_task_propagate_int (task, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + g_assert_cmpint (ret, ==, -1); + + g_object_unref (task); + + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) + g_cond_wait (&roc_finish_cond, &roc_finish_mutex); + g_mutex_unlock (&roc_finish_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); + + g_cancellable_reset (cancellable); + + /* If the task is already cancelled before it starts, it returns + * immediately, but the thread func still runs. + */ + g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); + g_task_set_return_on_cancel (task, TRUE); + + g_cancellable_cancel (cancellable); + + g_task_set_task_data (task, (gpointer)&thread_state, NULL); + g_mutex_lock (&roc_init_mutex); + g_mutex_lock (&roc_finish_mutex); + runner_thread = g_thread_new ("return-on-cancel-sync runner thread", + cancel_sync_runner_thread, task); + + g_thread_join (runner_thread); + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_STARTING); + + ret = g_task_propagate_int (task, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + g_assert_cmpint (ret, ==, -1); + + g_object_unref (task); + + while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + + while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) + g_cond_wait (&roc_finish_cond, &roc_finish_mutex); + g_mutex_unlock (&roc_finish_mutex); + + g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); + + g_object_unref (cancellable); +} + +/* test_return_on_cancel_atomic: turning return-on-cancel on/off is + * non-racy + */ + +GMutex roca_mutex_1, roca_mutex_2; +GCond roca_cond_1, roca_cond_2; + +static void +return_on_cancel_atomic_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *callback_ran = user_data; + GError *error = NULL; + gssize ret; + + g_assert (g_thread_self () == main_thread); + + g_assert (object == NULL); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + ret = g_task_propagate_int (G_TASK (result), &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + g_assert_cmpint (ret, ==, -1); + + g_assert (g_task_had_error (G_TASK (result))); + + *callback_ran = TRUE; + g_main_loop_quit (loop); +} + +static void +return_on_cancel_atomic_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + gint *state = task_data; /* (atomic) */ + + g_assert (source_object == g_task_get_source_object (task)); + g_assert (task_data == g_task_get_task_data (task)); + g_assert (cancellable == g_task_get_cancellable (task)); + g_assert_false (g_task_get_completed (task)); + + g_assert (g_thread_self () != main_thread); + g_assert_cmpint (g_atomic_int_get (state), ==, 0); + + g_mutex_lock (&roca_mutex_1); + g_atomic_int_set (state, 1); + g_cond_signal (&roca_cond_1); + g_mutex_unlock (&roca_mutex_1); + + g_mutex_lock (&roca_mutex_2); + if (g_task_set_return_on_cancel (task, FALSE)) + g_atomic_int_set (state, 2); + else + g_atomic_int_set (state, 3); + g_cond_signal (&roca_cond_2); + g_mutex_unlock (&roca_mutex_2); + + g_mutex_lock (&roca_mutex_1); + if (g_task_set_return_on_cancel (task, TRUE)) + g_atomic_int_set (state, 4); + else + g_atomic_int_set (state, 5); + g_cond_signal (&roca_cond_1); + g_mutex_unlock (&roca_mutex_1); + + g_mutex_lock (&roca_mutex_2); + if (g_task_set_return_on_cancel (task, TRUE)) + g_atomic_int_set (state, 6); + else + g_atomic_int_set (state, 7); + g_cond_signal (&roca_cond_2); + g_mutex_unlock (&roca_mutex_2); + + g_task_return_int (task, magic); +} + +static void +test_return_on_cancel_atomic (void) +{ + GTask *task; + GCancellable *cancellable; + gint state; /* (atomic) */ + gboolean notification_emitted = FALSE; + gboolean callback_ran; + + cancellable = g_cancellable_new (); + g_mutex_lock (&roca_mutex_1); + g_mutex_lock (&roca_mutex_2); + + /* If we don't cancel it, each set_return_on_cancel() call will succeed */ + g_atomic_int_set (&state, 0); + callback_ran = FALSE; + task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran); + g_task_set_return_on_cancel (task, TRUE); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + g_task_set_task_data (task, (gpointer)&state, NULL); + g_task_run_in_thread (task, return_on_cancel_atomic_thread); + g_object_unref (task); + + g_assert_cmpint (g_atomic_int_get (&state), ==, 0); + + while (g_atomic_int_get (&state) == 0) + g_cond_wait (&roca_cond_1, &roca_mutex_1); + g_assert_cmpint (g_atomic_int_get (&state), ==, 1); + + while (g_atomic_int_get (&state) == 1) + g_cond_wait (&roca_cond_2, &roca_mutex_2); + g_assert_cmpint (g_atomic_int_get (&state), ==, 2); + + while (g_atomic_int_get (&state) == 2) + g_cond_wait (&roca_cond_1, &roca_mutex_1); + g_assert_cmpint (g_atomic_int_get (&state), ==, 4); + + while (g_atomic_int_get (&state) == 4) + g_cond_wait (&roca_cond_2, &roca_mutex_2); + g_assert_cmpint (g_atomic_int_get (&state), ==, 6); + + /* callback assumes there'll be a cancelled error */ + g_cancellable_cancel (cancellable); + + g_assert (callback_ran == FALSE); + g_main_loop_run (loop); + g_assert (callback_ran == TRUE); + g_assert_true (notification_emitted); + + g_cancellable_reset (cancellable); + + + /* If we cancel while it's temporarily not return-on-cancel, the + * task won't complete right away, and further + * g_task_set_return_on_cancel() calls will return FALSE. + */ + g_atomic_int_set (&state, 0); + callback_ran = FALSE; + notification_emitted = FALSE; + task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran); + g_task_set_return_on_cancel (task, TRUE); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + g_task_set_task_data (task, (gpointer)&state, NULL); + g_task_run_in_thread (task, return_on_cancel_atomic_thread); + + g_assert_cmpint (g_atomic_int_get (&state), ==, 0); + + while (g_atomic_int_get (&state) == 0) + g_cond_wait (&roca_cond_1, &roca_mutex_1); + g_assert_cmpint (g_atomic_int_get (&state), ==, 1); + g_assert (g_task_get_return_on_cancel (task)); + + while (g_atomic_int_get (&state) == 1) + g_cond_wait (&roca_cond_2, &roca_mutex_2); + g_assert_cmpint (g_atomic_int_get (&state), ==, 2); + g_assert (!g_task_get_return_on_cancel (task)); + + g_cancellable_cancel (cancellable); + g_idle_add (idle_quit_loop, NULL); + g_main_loop_run (loop); + g_assert (callback_ran == FALSE); + + while (g_atomic_int_get (&state) == 2) + g_cond_wait (&roca_cond_1, &roca_mutex_1); + g_assert_cmpint (g_atomic_int_get (&state), ==, 5); + g_assert (!g_task_get_return_on_cancel (task)); + + g_main_loop_run (loop); + g_assert (callback_ran == TRUE); + g_assert_true (notification_emitted); + + while (g_atomic_int_get (&state) == 5) + g_cond_wait (&roca_cond_2, &roca_mutex_2); + g_assert_cmpint (g_atomic_int_get (&state), ==, 7); + + g_object_unref (cancellable); + g_mutex_unlock (&roca_mutex_1); + g_mutex_unlock (&roca_mutex_2); + g_object_unref (task); +} + +/* test_return_pointer: memory management of pointer returns */ + +static void +test_return_pointer (void) +{ + GObject *object, *ret; + GTask *task; + GCancellable *cancellable; + GError *error = NULL; + + /* If we don't read back the return value, the task will + * run its destroy notify. + */ + object = (GObject *)g_dummy_object_new (); + g_assert_cmpint (object->ref_count, ==, 1); + g_object_add_weak_pointer (object, (gpointer *)&object); + + task = g_task_new (NULL, NULL, NULL, NULL); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_task_return_pointer (task, object, g_object_unref); + g_assert_cmpint (object->ref_count, ==, 1); + + /* Task and object are reffed until the :completed notification in idle. */ + g_object_unref (task); + g_assert_nonnull (task); + g_assert_nonnull (object); + + wait_for_completed_notification (task); + + g_assert_null (task); + g_assert_null (object); + + /* Likewise, if the return value is overwritten by an error */ + object = (GObject *)g_dummy_object_new (); + g_assert_cmpint (object->ref_count, ==, 1); + g_object_add_weak_pointer (object, (gpointer *)&object); + + cancellable = g_cancellable_new (); + task = g_task_new (NULL, cancellable, NULL, NULL); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_task_return_pointer (task, object, g_object_unref); + g_assert_cmpint (object->ref_count, ==, 1); + g_cancellable_cancel (cancellable); + g_assert_cmpint (object->ref_count, ==, 1); + + ret = g_task_propagate_pointer (task, &error); + g_assert (ret == NULL); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + g_assert_cmpint (object->ref_count, ==, 1); + + g_object_unref (task); + g_object_unref (cancellable); + g_assert_nonnull (task); + g_assert_nonnull (object); + + wait_for_completed_notification (task); + + g_assert_null (task); + g_assert_null (object); + + /* If we read back the return value, we steal its ref */ + object = (GObject *)g_dummy_object_new (); + g_assert_cmpint (object->ref_count, ==, 1); + g_object_add_weak_pointer (object, (gpointer *)&object); + + task = g_task_new (NULL, NULL, NULL, NULL); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_task_return_pointer (task, object, g_object_unref); + g_assert_cmpint (object->ref_count, ==, 1); + + ret = g_task_propagate_pointer (task, &error); + g_assert_no_error (error); + g_assert (ret == object); + g_assert_cmpint (object->ref_count, ==, 1); + + g_object_unref (task); + g_assert_nonnull (task); + g_assert_cmpint (object->ref_count, ==, 1); + g_object_unref (object); + g_assert (object == NULL); + + wait_for_completed_notification (task); + g_assert_null (task); +} + +static void +test_return_value (void) +{ + GObject *object; + GValue value = G_VALUE_INIT; + GValue ret = G_VALUE_INIT; + GTask *task; + GError *error = NULL; + + object = (GObject *)g_dummy_object_new (); + g_assert_cmpint (object->ref_count, ==, 1); + g_object_add_weak_pointer (object, (gpointer *)&object); + + g_value_init (&value, G_TYPE_OBJECT); + g_value_set_object (&value, object); + g_assert_cmpint (object->ref_count, ==, 2); + + task = g_task_new (NULL, NULL, NULL, NULL); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_task_return_value (task, &value); + g_assert_cmpint (object->ref_count, ==, 3); + + g_assert_true (g_task_propagate_value (task, &ret, &error)); + g_assert_no_error (error); + g_assert_true (g_value_get_object (&ret) == object); + g_assert_cmpint (object->ref_count, ==, 3); + + g_object_unref (task); + g_assert_nonnull (task); + wait_for_completed_notification (task); + g_assert_null (task); + + g_assert_cmpint (object->ref_count, ==, 3); + g_value_unset (&ret); + g_assert_cmpint (object->ref_count, ==, 2); + g_value_unset (&value); + g_assert_cmpint (object->ref_count, ==, 1); + g_object_unref (object); + g_assert_null (object); +} + +/* test_object_keepalive: GTask takes a ref on its source object */ + +static GObject *keepalive_object; + +static void +keepalive_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gssize *result_out = user_data; + GError *error = NULL; + + g_assert (object == keepalive_object); + g_assert (g_task_is_valid (result, object)); + g_assert (g_async_result_get_user_data (result) == user_data); + g_assert (!g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + *result_out = g_task_propagate_int (G_TASK (result), &error); + g_assert_no_error (error); + + g_assert (!g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +static void +test_object_keepalive (void) +{ + GObject *object; + GTask *task; + gssize result; + int ref_count; + gboolean notification_emitted = FALSE; + + keepalive_object = object = (GObject *)g_dummy_object_new (); + g_object_add_weak_pointer (object, (gpointer *)&object); + + task = g_task_new (object, NULL, keepalive_callback, &result); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); + + ref_count = object->ref_count; + g_assert_cmpint (ref_count, >, 1); + + g_assert (g_task_get_source_object (task) == object); + g_assert (g_async_result_get_source_object (G_ASYNC_RESULT (task)) == object); + g_assert_cmpint (object->ref_count, ==, ref_count + 1); + g_object_unref (object); + + g_object_unref (object); + g_assert (object != NULL); + + g_task_return_int (task, magic); + g_main_loop_run (loop); + + g_assert (object != NULL); + g_assert_cmpint (result, ==, magic); + g_assert_true (notification_emitted); + + g_object_unref (task); + g_assert (task == NULL); + g_assert (object == NULL); +} + +/* test_legacy_error: legacy GSimpleAsyncResult handling */ +static void test_legacy_error (void); + +static void +legacy_error_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + gssize *result_out = user_data; + GError *error = NULL; + + g_assert (object == NULL); + g_assert (g_async_result_is_tagged (result, test_legacy_error)); + g_assert (g_async_result_get_user_data (result) == user_data); + + if (g_async_result_legacy_propagate_error (result, &error)) + { + g_assert (!g_task_is_valid (result, object)); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + g_assert (g_simple_async_result_is_valid (result, object, test_legacy_error)); + G_GNUC_END_IGNORE_DEPRECATIONS; + + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + *result_out = -2; + g_clear_error (&error); + } + else + { + g_assert (g_task_is_valid (result, object)); + + *result_out = g_task_propagate_int (G_TASK (result), NULL); + /* Might be error, might not */ + } + + g_main_loop_quit (loop); +} + +static gboolean +legacy_error_return (gpointer user_data) +{ + if (G_IS_TASK (user_data)) + { + GTask *task = user_data; + + g_task_return_int (task, magic); + g_object_unref (task); + } + else + { + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + g_simple_async_result_set_error (simple, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed"); + g_simple_async_result_complete (simple); + G_GNUC_END_IGNORE_DEPRECATIONS; + g_object_unref (simple); + } + + return FALSE; +} + +static void +test_legacy_error (void) +{ + GTask *task; + GSimpleAsyncResult *simple; + gssize result; + + /* GTask success */ + task = g_task_new (NULL, NULL, legacy_error_callback, &result); + g_task_set_source_tag (task, test_legacy_error); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + + g_idle_add (legacy_error_return, task); + g_main_loop_run (loop); + + g_assert_cmpint (result, ==, magic); + g_assert (task == NULL); + + /* GTask error */ + task = g_task_new (NULL, NULL, legacy_error_callback, &result); + g_task_set_source_tag (task, test_legacy_error); + g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task); + + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed"); + g_object_unref (task); + g_main_loop_run (loop); + + g_assert_cmpint (result, ==, -1); + g_assert (task == NULL); + + /* GSimpleAsyncResult error */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + simple = g_simple_async_result_new (NULL, legacy_error_callback, &result, + test_legacy_error); + G_GNUC_END_IGNORE_DEPRECATIONS; + g_object_add_weak_pointer (G_OBJECT (simple), (gpointer *)&simple); + + g_idle_add (legacy_error_return, simple); + g_main_loop_run (loop); + + g_assert_cmpint (result, ==, -2); + g_assert (simple == NULL); +} + +/* Various helper functions for the return tests below. */ +static void +task_complete_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (result); + guint *calls = user_data; + + g_assert_cmpint (++*calls, <=, 1); + + /* Propagate the result, so it’s removed from the task’s internal state. */ + g_task_propagate_boolean (task, NULL); +} + +static void +return_twice (GTask *task) +{ + gboolean error_first = GPOINTER_TO_UINT (g_task_get_task_data (task)); + + if (error_first) + { + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_UNKNOWN, "oh no"); + g_task_return_boolean (task, TRUE); + } + else + { + g_task_return_boolean (task, TRUE); + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_UNKNOWN, "oh no"); + } +} + +static gboolean +idle_cb (gpointer user_data) +{ + GTask *task = user_data; + return_twice (task); + g_object_unref (task); + + return G_SOURCE_REMOVE; +} + +static void +test_return_permutation (gboolean error_first, + gboolean return_in_idle) +{ + guint calls = 0; + GTask *task = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1525"); + + task = g_task_new (NULL, NULL, task_complete_cb, &calls); + g_task_set_task_data (task, GUINT_TO_POINTER (error_first), NULL); + + if (return_in_idle) + g_idle_add (idle_cb, g_object_ref (task)); + else + return_twice (task); + + while (calls == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpint (calls, ==, 1); + + g_object_unref (task); +} + +/* Test that calling g_task_return_boolean() after g_task_return_error(), when + * returning in an idle callback, correctly results in a critical warning. */ +static void +test_return_in_idle_error_first (void) +{ + if (g_test_subprocess ()) + { + test_return_permutation (TRUE, TRUE); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*"); +} + +/* Test that calling g_task_return_error() after g_task_return_boolean(), when + * returning in an idle callback, correctly results in a critical warning. */ +static void +test_return_in_idle_value_first (void) +{ + if (g_test_subprocess ()) + { + test_return_permutation (FALSE, TRUE); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*"); +} + +/* Test that calling g_task_return_boolean() after g_task_return_error(), when + * returning synchronously, correctly results in a critical warning. */ +static void +test_return_error_first (void) +{ + if (g_test_subprocess ()) + { + test_return_permutation (TRUE, FALSE); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*"); +} + +/* Test that calling g_task_return_error() after g_task_return_boolean(), when + * returning synchronously, correctly results in a critical warning. */ +static void +test_return_value_first (void) +{ + if (g_test_subprocess ()) + { + test_return_permutation (FALSE, FALSE); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*"); +} + +int +main (int argc, char **argv) +{ + int ret; + + g_test_init (&argc, &argv, NULL); + + loop = g_main_loop_new (NULL, FALSE); + main_thread = g_thread_self (); + magic = g_get_monotonic_time (); + + g_test_add_func ("/gtask/basic", test_basic); + g_test_add_func ("/gtask/error", test_error); + g_test_add_func ("/gtask/return-from-same-iteration", test_return_from_same_iteration); + g_test_add_func ("/gtask/return-from-toplevel", test_return_from_toplevel); + g_test_add_func ("/gtask/return-from-anon-thread", test_return_from_anon_thread); + g_test_add_func ("/gtask/return-from-wrong-thread", test_return_from_wrong_thread); + g_test_add_func ("/gtask/no-callback", test_no_callback); + g_test_add_func ("/gtask/report-error", test_report_error); + g_test_add_func ("/gtask/priority", test_priority); + g_test_add_func ("/gtask/name", test_name); + g_test_add_func ("/gtask/asynchronous-cancellation", test_asynchronous_cancellation); + g_test_add_func ("/gtask/check-cancellable", test_check_cancellable); + g_test_add_func ("/gtask/return-if-cancelled", test_return_if_cancelled); + g_test_add_func ("/gtask/run-in-thread", test_run_in_thread); + g_test_add_func ("/gtask/run-in-thread-sync", test_run_in_thread_sync); + g_test_add_func ("/gtask/run-in-thread-priority", test_run_in_thread_priority); + g_test_add_func ("/gtask/run-in-thread-nested", test_run_in_thread_nested); + g_test_add_func ("/gtask/run-in-thread-overflow", test_run_in_thread_overflow); + g_test_add_func ("/gtask/return-on-cancel", test_return_on_cancel); + g_test_add_func ("/gtask/return-on-cancel-sync", test_return_on_cancel_sync); + g_test_add_func ("/gtask/return-on-cancel-atomic", test_return_on_cancel_atomic); + g_test_add_func ("/gtask/return-pointer", test_return_pointer); + g_test_add_func ("/gtask/return-value", test_return_value); + g_test_add_func ("/gtask/object-keepalive", test_object_keepalive); + g_test_add_func ("/gtask/legacy-error", test_legacy_error); + g_test_add_func ("/gtask/return/in-idle/error-first", test_return_in_idle_error_first); + g_test_add_func ("/gtask/return/in-idle/value-first", test_return_in_idle_value_first); + g_test_add_func ("/gtask/return/error-first", test_return_error_first); + g_test_add_func ("/gtask/return/value-first", test_return_value_first); + + ret = g_test_run(); + + g_main_loop_unref (loop); + + return ret; +} diff --git a/gio/tests/test-codegen.xml b/gio/tests/test-codegen.xml new file mode 100644 index 0000000..3090cad --- /dev/null +++ b/gio/tests/test-codegen.xml @@ -0,0 +1,499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + yadaydaydaydayda + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gio/tests/test-io-stream.c b/gio/tests/test-io-stream.c new file mode 100644 index 0000000..cbca9b7 --- /dev/null +++ b/gio/tests/test-io-stream.c @@ -0,0 +1,102 @@ +/* Simple I/O stream. This is a utility class for tests, not a test. + * + * Copyright © 2008-2010 Red Hat, Inc. + * Copyright © 2011 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + * Author: Simon McVittie + */ + +#include + +#include "test-io-stream.h" + +G_DEFINE_TYPE (TestIOStream, test_io_stream, G_TYPE_IO_STREAM) + +static void +test_io_stream_finalize (GObject *object) +{ + TestIOStream *stream = TEST_IO_STREAM (object); + + /* strictly speaking we should unref these in dispose, but + * g_io_stream_dispose() wants them to still exist + */ + g_clear_object (&stream->input_stream); + g_clear_object (&stream->output_stream); + + G_OBJECT_CLASS (test_io_stream_parent_class)->finalize (object); +} + +static void +test_io_stream_init (TestIOStream *stream) +{ +} + +static GInputStream * +test_io_stream_get_input_stream (GIOStream *_stream) +{ + TestIOStream *stream = TEST_IO_STREAM (_stream); + + return stream->input_stream; +} + +static GOutputStream * +test_io_stream_get_output_stream (GIOStream *_stream) +{ + TestIOStream *stream = TEST_IO_STREAM (_stream); + + return stream->output_stream; +} + +static void +test_io_stream_class_init (TestIOStreamClass *klass) +{ + GObjectClass *gobject_class; + GIOStreamClass *giostream_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = test_io_stream_finalize; + + giostream_class = G_IO_STREAM_CLASS (klass); + giostream_class->get_input_stream = test_io_stream_get_input_stream; + giostream_class->get_output_stream = test_io_stream_get_output_stream; +} + +/** + * test_io_stream_new: + * @input_stream: an input stream + * @output_stream: an output stream + * + * Return a simple #GIOStream binding together @input_stream and + * @output_stream. They have no additional semantics as a result of being + * part of this I/O stream: in particular, closing one does not close + * the other (although closing the #GIOStream will close both sub-streams). + * + * Returns: (transfer full): a new #GIOStream + */ +GIOStream * +test_io_stream_new (GInputStream *input_stream, + GOutputStream *output_stream) +{ + TestIOStream *stream; + + g_return_val_if_fail (G_IS_INPUT_STREAM (input_stream), NULL); + g_return_val_if_fail (G_IS_OUTPUT_STREAM (output_stream), NULL); + stream = TEST_IO_STREAM (g_object_new (TEST_TYPE_IO_STREAM, NULL)); + stream->input_stream = g_object_ref (input_stream); + stream->output_stream = g_object_ref (output_stream); + return G_IO_STREAM (stream); +} diff --git a/gio/tests/test-io-stream.h b/gio/tests/test-io-stream.h new file mode 100644 index 0000000..1331c99 --- /dev/null +++ b/gio/tests/test-io-stream.h @@ -0,0 +1,51 @@ +/* Simple I/O stream. This is a utility module for tests, not a test. + * + * Copyright © 2008-2010 Red Hat, Inc. + * Copyright © 2011 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: David Zeuthen + * Author: Simon McVittie + */ + +#ifndef TEST_IO_STREAM_H +#define TEST_IO_STREAM_H + +#include + +typedef struct +{ + GIOStream parent_instance; + GInputStream *input_stream; + GOutputStream *output_stream; +} TestIOStream; + +typedef struct +{ + GIOStreamClass parent_class; +} TestIOStreamClass; + +GType test_io_stream_get_type (void) G_GNUC_CONST; + +#define TEST_TYPE_IO_STREAM (test_io_stream_get_type ()) +#define TEST_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \ + TEST_TYPE_IO_STREAM, TestIOStream)) +#define TEST_IS_IO_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \ + TEST_TYPE_IO_STREAM)) + +GIOStream *test_io_stream_new (GInputStream *input_stream, + GOutputStream *output_stream); + +#endif /* guard */ diff --git a/gio/tests/test-pipe-unix.c b/gio/tests/test-pipe-unix.c new file mode 100644 index 0000000..ccf9faa --- /dev/null +++ b/gio/tests/test-pipe-unix.c @@ -0,0 +1,129 @@ +/* Unix pipe-to-self. This is a utility module for tests, not a test. + * + * Copyright © 2008-2010 Red Hat, Inc. + * Copyright © 2011 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Simon McVittie + */ + +#include +#include + +#include + +#include "test-io-stream.h" +#include "test-pipe-unix.h" + +#ifdef G_OS_UNIX +# include +# include +#else +# error This module only exists on Unix +#endif + +/** + * test_pipe: + * @is: (out) (optional): used to return a #GInputStream + * @os: (out) (optional): used to return a #GOutputStream + * @error: used to raise an error + * + * Return a "pipe to self" connecting @is to @os. This can be used + * as a unidirectional pipe to or from a child process, for instance. + * + * See test_bidi_pipe() if you want to emulate a bidirectional pipe + * via a pair of unidirectional pipes. + * + * Returns: %TRUE on success + */ +gboolean +test_pipe (GInputStream **is, + GOutputStream **os, + GError **error) +{ + int pipefd[2]; + int ret; + + ret = pipe (pipefd); + + if (ret != 0) + { + int e = errno; + + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (e), + "%s", g_strerror (e)); + return FALSE; + } + + if (is != NULL) + *is = g_unix_input_stream_new (pipefd[0], TRUE); + else + close (pipefd[0]); + + if (os != NULL) + *os = g_unix_output_stream_new (pipefd[1], TRUE); + else + close (pipefd[1]); + + return TRUE; +} + +/** + * test_bidi_pipe: + * @left: (out) (optional): used to return one #GIOStream + * @right: (out) (optional): used to return the other #GIOStream + * @error: used to raise an error + * + * Return two #GIOStreams connected to each other with pipes. + * The "left" input stream is connected by a unidirectional pipe + * to the "right" output stream, and vice versa. This can be used + * as a bidirectional pipe to a child process, for instance. + * + * See test_pipe() if you only need a one-way pipe. + * + * Returns: %TRUE on success + */ +gboolean +test_bidi_pipe (GIOStream **left, + GIOStream **right, + GError **error) +{ + GInputStream *left_in = NULL; + GOutputStream *left_out = NULL; + GInputStream *right_in = NULL; + GOutputStream *right_out = NULL; + gboolean ret = FALSE; + + if (!test_pipe (&left_in, &right_out, error)) + goto out; + + if (!test_pipe (&right_in, &left_out, error)) + goto out; + + if (left != NULL) + *left = test_io_stream_new (left_in, left_out); + + if (right != NULL) + *right = test_io_stream_new (right_in, right_out); + + ret = TRUE; + +out: + g_clear_object (&left_in); + g_clear_object (&left_out); + g_clear_object (&right_in); + g_clear_object (&right_out); + return ret; +} diff --git a/gio/tests/test-pipe-unix.h b/gio/tests/test-pipe-unix.h new file mode 100644 index 0000000..3c47c55 --- /dev/null +++ b/gio/tests/test-pipe-unix.h @@ -0,0 +1,35 @@ +/* Unix pipe-to-self. This is a utility module for tests, not a test. + * + * Copyright © 2008-2010 Red Hat, Inc. + * Copyright © 2011 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Simon McVittie + */ + +#ifndef TEST_PIPE_UNIX_H +#define TEST_PIPE_UNIX_H + +#include + +gboolean test_pipe (GInputStream **is, + GOutputStream **os, + GError **error); + +gboolean test_bidi_pipe (GIOStream **left, + GIOStream **right, + GError **error); + +#endif /* guard */ diff --git a/gio/tests/test.gresource.xml b/gio/tests/test.gresource.xml new file mode 100644 index 0000000..62a31f4 --- /dev/null +++ b/gio/tests/test.gresource.xml @@ -0,0 +1,13 @@ + + + + test-generated.txt + test1.txt + test.gresource.xml + empty.txt + + + test2.txt + test2.txt + + diff --git a/gio/tests/test1.overlay b/gio/tests/test1.overlay new file mode 100644 index 0000000..687d69b --- /dev/null +++ b/gio/tests/test1.overlay @@ -0,0 +1 @@ +It is a beautiful day! diff --git a/gio/tests/test1.txt b/gio/tests/test1.txt new file mode 100644 index 0000000..a5bce3f --- /dev/null +++ b/gio/tests/test1.txt @@ -0,0 +1 @@ +test1 diff --git a/gio/tests/test2.gresource.xml b/gio/tests/test2.gresource.xml new file mode 100644 index 0000000..b6dca2b --- /dev/null +++ b/gio/tests/test2.gresource.xml @@ -0,0 +1,11 @@ + + + + test1.txt + + + + gresource-big-test.txt + + diff --git a/gio/tests/test2.txt b/gio/tests/test2.txt new file mode 100644 index 0000000..180cf83 --- /dev/null +++ b/gio/tests/test2.txt @@ -0,0 +1 @@ +test2 diff --git a/gio/tests/test3.gresource.xml b/gio/tests/test3.gresource.xml new file mode 100644 index 0000000..fdf26fa --- /dev/null +++ b/gio/tests/test3.gresource.xml @@ -0,0 +1,6 @@ + + + + test1.txt + + diff --git a/gio/tests/test3.txt b/gio/tests/test3.txt new file mode 100644 index 0000000..df6b0d2 --- /dev/null +++ b/gio/tests/test3.txt @@ -0,0 +1 @@ +test3 diff --git a/gio/tests/test4.gresource.xml b/gio/tests/test4.gresource.xml new file mode 100644 index 0000000..ddd7304 --- /dev/null +++ b/gio/tests/test4.gresource.xml @@ -0,0 +1,6 @@ + + + + test1.txt + + diff --git a/gio/tests/test5.gresource.xml b/gio/tests/test5.gresource.xml new file mode 100644 index 0000000..8e81a51 --- /dev/null +++ b/gio/tests/test5.gresource.xml @@ -0,0 +1,6 @@ + + + + test1.txt + + diff --git a/gio/tests/testenum.h b/gio/tests/testenum.h new file mode 100644 index 0000000..def8713 --- /dev/null +++ b/gio/tests/testenum.h @@ -0,0 +1,16 @@ +typedef enum +{ + TEST_ENUM_FOO, + TEST_ENUM_BAR, + TEST_ENUM_BAZ, + TEST_ENUM_QUUX +} TestEnum; + +typedef enum +{ + TEST_FLAGS_NONE = 0, + TEST_FLAGS_MOURNING = (1 << 0), + TEST_FLAGS_LAUGHING = (1 << 1), + TEST_FLAGS_TALKING = (1 << 2), + TEST_FLAGS_WALKING = (1 << 3) +} TestFlags; diff --git a/gio/tests/testfilemonitor.c b/gio/tests/testfilemonitor.c new file mode 100644 index 0000000..082f0db --- /dev/null +++ b/gio/tests/testfilemonitor.c @@ -0,0 +1,1104 @@ +#include "config.h" + +#include +#include +#include + +static gboolean +skip_win32 (void) +{ +#ifdef G_OS_WIN32 + g_test_skip ("FIXME, test is broken on win32"); + return TRUE; +#else + return FALSE; +#endif +} + +/* These tests were written for the inotify implementation. + * Other implementations may require slight adjustments in + * the tests, e.g. the length of timeouts + */ + +typedef struct +{ + GFile *tmp_dir; +} Fixture; + +static void +setup (Fixture *fixture, + gconstpointer user_data) +{ + gchar *path = NULL; + GError *local_error = NULL; + + path = g_dir_make_tmp ("gio-test-testfilemonitor_XXXXXX", &local_error); + g_assert_no_error (local_error); + + fixture->tmp_dir = g_file_new_for_path (path); + + g_test_message ("Using temporary directory: %s", path); + + g_free (path); +} + +static void +teardown (Fixture *fixture, + gconstpointer user_data) +{ + GError *local_error = NULL; + + g_file_delete (fixture->tmp_dir, NULL, &local_error); + g_assert_no_error (local_error); + g_clear_object (&fixture->tmp_dir); +} + +typedef enum { + NONE = 0, + INOTIFY = (1 << 1), + KQUEUE = (1 << 2) +} Environment; + +typedef struct +{ + gint event_type; + gchar *file; + gchar *other_file; + gint step; + + /* Since different file monitor implementation has different capabilities, + * we cannot expect all implementations to report all kind of events without + * any loss. This 'optional' field is a bit mask used to mark events which + * may be lost under specific platforms. + */ + Environment optional; +} RecordedEvent; + +static void +free_recorded_event (RecordedEvent *event) +{ + g_free (event->file); + g_free (event->other_file); + g_free (event); +} + +typedef struct +{ + GFile *file; + GFileMonitor *monitor; + GMainLoop *loop; + gint step; + GList *events; + GFileOutputStream *output_stream; +} TestData; + +static void +output_event (const RecordedEvent *event) +{ + if (event->step >= 0) + g_test_message (">>>> step %d", event->step); + else + { + GTypeClass *class; + + class = g_type_class_ref (g_type_from_name ("GFileMonitorEvent")); + g_test_message ("%s file=%s other_file=%s\n", + g_enum_get_value (G_ENUM_CLASS (class), event->event_type)->value_nick, + event->file, + event->other_file); + g_type_class_unref (class); + } +} + +/* a placeholder for temp file names we don't want to compare */ +static const gchar DONT_CARE[] = ""; + +static Environment +get_environment (GFileMonitor *monitor) +{ + if (g_str_equal (G_OBJECT_TYPE_NAME (monitor), "GInotifyFileMonitor")) + return INOTIFY; + if (g_str_equal (G_OBJECT_TYPE_NAME (monitor), "GKqueueFileMonitor")) + return KQUEUE; + return NONE; +} + +static void +check_expected_events (RecordedEvent *expected, + gsize n_expected, + GList *recorded, + Environment env) +{ + gsize i; + gint li; + GList *l; + + for (i = 0, li = 0, l = recorded; i < n_expected && l != NULL;) + { + RecordedEvent *e1 = &expected[i]; + RecordedEvent *e2 = l->data; + gboolean mismatch = TRUE; + gboolean l_extra_step = FALSE; + + do + { + gboolean ignore_other_file = FALSE; + + if (e1->step != e2->step) + break; + + /* Kqueue isn't good at detecting file renaming, so + * G_FILE_MONITOR_WATCH_MOVES is mostly useless there. */ + if (e1->event_type != e2->event_type && env & KQUEUE) + { + /* It is possible for kqueue file monitor to emit 'RENAMED' event, + * but most of the time it is reported as a 'DELETED' event and + * a 'CREATED' event. */ + if (e1->event_type == G_FILE_MONITOR_EVENT_RENAMED) + { + RecordedEvent *e2_next; + + if (l->next == NULL) + break; + e2_next = l->next->data; + + if (e2->event_type != G_FILE_MONITOR_EVENT_DELETED) + break; + if (e2_next->event_type != G_FILE_MONITOR_EVENT_CREATED) + break; + + if (e1->step != e2_next->step) + break; + + if (e1->file != DONT_CARE && + (g_strcmp0 (e1->file, e2->file) != 0 || + e2->other_file != NULL)) + break; + + if (e1->other_file != DONT_CARE && + (g_strcmp0 (e1->other_file, e2_next->file) != 0 || + e2_next->other_file != NULL)) + break; + + l_extra_step = TRUE; + mismatch = FALSE; + break; + } + /* Kqueue won't report 'MOVED_IN' and 'MOVED_OUT' events. We set + * 'ignore_other_file' here to let the following code know that + * 'other_file' may not match. */ + else if (e1->event_type == G_FILE_MONITOR_EVENT_MOVED_IN) + { + if (e2->event_type != G_FILE_MONITOR_EVENT_CREATED) + break; + ignore_other_file = TRUE; + } + else if (e1->event_type == G_FILE_MONITOR_EVENT_MOVED_OUT) + { + if (e2->event_type != G_FILE_MONITOR_EVENT_DELETED) + break; + ignore_other_file = TRUE; + } + else + break; + } + + if (e1->file != DONT_CARE && + g_strcmp0 (e1->file, e2->file) != 0) + break; + + if (e1->other_file != DONT_CARE && !ignore_other_file && + g_strcmp0 (e1->other_file, e2->other_file) != 0) + break; + + mismatch = FALSE; + } + while (0); + + if (mismatch) + { + /* Sometimes the emission of 'CHANGES_DONE_HINT' may be late because + * it depends on the ability of file monitor implementation to report + * 'CHANGES_DONE_HINT' itself. If the file monitor implementation + * doesn't report 'CHANGES_DONE_HINT' itself, it may be emitted by + * GLocalFileMonitor after a few seconds, which causes the event to + * mix with results from different steps. Since 'CHANGES_DONE_HINT' + * is just a hint, we don't require it to be reliable and we simply + * ignore unexpected 'CHANGES_DONE_HINT' events here. */ + if (e1->event_type != G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT && + e2->event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) + { + g_test_message ("Event CHANGES_DONE_HINT ignored at " + "expected index %" G_GSIZE_FORMAT ", recorded index %d", i, li); + li++, l = l->next; + continue; + } + /* If an event is marked as optional in the current environment and + * the event doesn't match, it means the expected event has lost. */ + else if (env & e1->optional) + { + g_test_message ("Event %d at expected index %" G_GSIZE_FORMAT " skipped because " + "it is marked as optional", e1->event_type, i); + i++; + continue; + } + /* Run above checks under g_assert_* again to provide more useful + * error messages. Print the expected and actual events first. */ + else + { + GList *l; + gsize j; + + g_test_message ("Recorded events:"); + for (l = recorded; l != NULL; l = l->next) + output_event ((RecordedEvent *) l->data); + + g_test_message ("Expected events:"); + for (j = 0; j < n_expected; j++) + output_event (&expected[j]); + + g_assert_cmpint (e1->step, ==, e2->step); + g_assert_cmpint (e1->event_type, ==, e2->event_type); + + if (e1->file != DONT_CARE) + g_assert_cmpstr (e1->file, ==, e2->file); + + if (e1->other_file != DONT_CARE) + g_assert_cmpstr (e1->other_file, ==, e2->other_file); + + g_assert_not_reached (); + } + } + + i++, li++, l = l->next; + if (l_extra_step) + li++, l = l->next; + } + + g_assert_cmpint (i, ==, n_expected); + g_assert_cmpint (li, ==, g_list_length (recorded)); +} + +static void +record_event (TestData *data, + gint event_type, + const gchar *file, + const gchar *other_file, + gint step) +{ + RecordedEvent *event; + + event = g_new0 (RecordedEvent, 1); + event->event_type = event_type; + event->file = g_strdup (file); + event->other_file = g_strdup (other_file); + event->step = step; + + data->events = g_list_append (data->events, event); +} + +static void +monitor_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + TestData *data = user_data; + gchar *basename, *other_base; + + basename = g_file_get_basename (file); + if (other_file) + other_base = g_file_get_basename (other_file); + else + other_base = NULL; + + record_event (data, event_type, basename, other_base, -1); + + g_free (basename); + g_free (other_base); +} + +static gboolean +atomic_replace_step (gpointer user_data) +{ + TestData *data = user_data; + GError *error = NULL; + + switch (data->step) + { + case 0: + record_event (data, -1, NULL, NULL, 0); + g_file_replace_contents (data->file, "step 0", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); + g_assert_no_error (error); + break; + case 1: + record_event (data, -1, NULL, NULL, 1); + g_file_replace_contents (data->file, "step 1", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); + g_assert_no_error (error); + break; + case 2: + record_event (data, -1, NULL, NULL, 2); + g_file_delete (data->file, NULL, NULL); + break; + case 3: + record_event (data, -1, NULL, NULL, 3); + g_main_loop_quit (data->loop); + return G_SOURCE_REMOVE; + } + + data->step++; + + return G_SOURCE_CONTINUE; +} + +/* this is the output we expect from the above steps */ +static RecordedEvent atomic_replace_output[] = { + { -1, NULL, NULL, 0, NONE }, + { G_FILE_MONITOR_EVENT_CREATED, "atomic_replace_file", NULL, -1, NONE }, + { G_FILE_MONITOR_EVENT_CHANGED, "atomic_replace_file", NULL, -1, KQUEUE }, + { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "atomic_replace_file", NULL, -1, KQUEUE }, + { -1, NULL, NULL, 1, NONE }, + { G_FILE_MONITOR_EVENT_RENAMED, (gchar*)DONT_CARE, "atomic_replace_file", -1, NONE }, + { -1, NULL, NULL, 2, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "atomic_replace_file", NULL, -1, NONE }, + { -1, NULL, NULL, 3, NONE } +}; + +static void +test_atomic_replace (Fixture *fixture, + gconstpointer user_data) +{ + GError *error = NULL; + TestData data; + + if (skip_win32 ()) + return; + + data.step = 0; + data.events = NULL; + + data.file = g_file_get_child (fixture->tmp_dir, "atomic_replace_file"); + g_file_delete (data.file, NULL, NULL); + + data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); + g_assert_no_error (error); + + g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor)); + + g_file_monitor_set_rate_limit (data.monitor, 200); + g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data); + + data.loop = g_main_loop_new (NULL, TRUE); + + g_timeout_add (500, atomic_replace_step, &data); + + g_main_loop_run (data.loop); + + check_expected_events (atomic_replace_output, + G_N_ELEMENTS (atomic_replace_output), + data.events, + get_environment (data.monitor)); + + g_list_free_full (data.events, (GDestroyNotify)free_recorded_event); + g_main_loop_unref (data.loop); + g_object_unref (data.monitor); + g_object_unref (data.file); +} + +static gboolean +change_step (gpointer user_data) +{ + TestData *data = user_data; + GOutputStream *stream; + GError *error = NULL; + guint32 mode = 0660; + + switch (data->step) + { + case 0: + record_event (data, -1, NULL, NULL, 0); + g_file_replace_contents (data->file, "step 0", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); + g_assert_no_error (error); + break; + case 1: + record_event (data, -1, NULL, NULL, 1); + stream = (GOutputStream *)g_file_append_to (data->file, G_FILE_CREATE_NONE, NULL, &error); + g_assert_no_error (error); + g_output_stream_write_all (stream, " step 1", 7, NULL, NULL, &error); + g_assert_no_error (error); + g_output_stream_close (stream, NULL, &error); + g_assert_no_error (error); + g_object_unref (stream); + break; + case 2: + record_event (data, -1, NULL, NULL, 2); + g_file_set_attribute (data->file, + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_ATTRIBUTE_TYPE_UINT32, + &mode, + G_FILE_QUERY_INFO_NONE, + NULL, + &error); + g_assert_no_error (error); + break; + case 3: + record_event (data, -1, NULL, NULL, 3); + g_file_delete (data->file, NULL, NULL); + break; + case 4: + record_event (data, -1, NULL, NULL, 4); + g_main_loop_quit (data->loop); + return G_SOURCE_REMOVE; + } + + data->step++; + + return G_SOURCE_CONTINUE; +} + +/* this is the output we expect from the above steps */ +static RecordedEvent change_output[] = { + { -1, NULL, NULL, 0, NONE }, + { G_FILE_MONITOR_EVENT_CREATED, "change_file", NULL, -1, NONE }, + { G_FILE_MONITOR_EVENT_CHANGED, "change_file", NULL, -1, KQUEUE }, + { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "change_file", NULL, -1, KQUEUE }, + { -1, NULL, NULL, 1, NONE }, + { G_FILE_MONITOR_EVENT_CHANGED, "change_file", NULL, -1, NONE }, + { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "change_file", NULL, -1, NONE }, + { -1, NULL, NULL, 2, NONE }, + { G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED, "change_file", NULL, -1, NONE }, + { -1, NULL, NULL, 3, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "change_file", NULL, -1, NONE }, + { -1, NULL, NULL, 4, NONE } +}; + +static void +test_file_changes (Fixture *fixture, + gconstpointer user_data) +{ + GError *error = NULL; + TestData data; + + if (skip_win32 ()) + return; + + data.step = 0; + data.events = NULL; + + data.file = g_file_get_child (fixture->tmp_dir, "change_file"); + g_file_delete (data.file, NULL, NULL); + + data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); + g_assert_no_error (error); + + g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor)); + + g_file_monitor_set_rate_limit (data.monitor, 200); + g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data); + + data.loop = g_main_loop_new (NULL, TRUE); + + g_timeout_add (500, change_step, &data); + + g_main_loop_run (data.loop); + + check_expected_events (change_output, + G_N_ELEMENTS (change_output), + data.events, + get_environment (data.monitor)); + + g_list_free_full (data.events, (GDestroyNotify)free_recorded_event); + g_main_loop_unref (data.loop); + g_object_unref (data.monitor); + g_object_unref (data.file); +} + +static gboolean +dir_step (gpointer user_data) +{ + TestData *data = user_data; + GFile *parent, *file, *file2; + GError *error = NULL; + + switch (data->step) + { + case 1: + record_event (data, -1, NULL, NULL, 1); + parent = g_file_get_parent (data->file); + file = g_file_get_child (parent, "dir_test_file"); + g_file_replace_contents (file, "step 1", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); + g_assert_no_error (error); + g_object_unref (file); + g_object_unref (parent); + break; + case 2: + record_event (data, -1, NULL, NULL, 2); + parent = g_file_get_parent (data->file); + file = g_file_get_child (parent, "dir_test_file"); + file2 = g_file_get_child (data->file, "dir_test_file"); + g_file_move (file, file2, G_FILE_COPY_NONE, NULL, NULL, NULL, &error); + g_assert_no_error (error); + g_object_unref (file); + g_object_unref (file2); + g_object_unref (parent); + break; + case 3: + record_event (data, -1, NULL, NULL, 3); + file = g_file_get_child (data->file, "dir_test_file"); + file2 = g_file_get_child (data->file, "dir_test_file2"); + g_file_move (file, file2, G_FILE_COPY_NONE, NULL, NULL, NULL, &error); + g_assert_no_error (error); + g_object_unref (file); + g_object_unref (file2); + break; + case 4: + record_event (data, -1, NULL, NULL, 4); + parent = g_file_get_parent (data->file); + file = g_file_get_child (data->file, "dir_test_file2"); + file2 = g_file_get_child (parent, "dir_test_file2"); + g_file_move (file, file2, G_FILE_COPY_NONE, NULL, NULL, NULL, &error); + g_assert_no_error (error); + g_file_delete (file2, NULL, NULL); + g_object_unref (file); + g_object_unref (file2); + g_object_unref (parent); + break; + case 5: + record_event (data, -1, NULL, NULL, 5); + g_file_delete (data->file, NULL, NULL); + break; + case 6: + record_event (data, -1, NULL, NULL, 6); + g_main_loop_quit (data->loop); + return G_SOURCE_REMOVE; + } + + data->step++; + + return G_SOURCE_CONTINUE; +} + +/* this is the output we expect from the above steps */ +static RecordedEvent dir_output[] = { + { -1, NULL, NULL, 1, NONE }, + { -1, NULL, NULL, 2, NONE }, + { G_FILE_MONITOR_EVENT_MOVED_IN, "dir_test_file", NULL, -1, NONE }, + { -1, NULL, NULL, 3, NONE }, + { G_FILE_MONITOR_EVENT_RENAMED, "dir_test_file", "dir_test_file2", -1, NONE }, + { -1, NULL, NULL, 4, NONE }, + { G_FILE_MONITOR_EVENT_MOVED_OUT, "dir_test_file2", NULL, -1, NONE }, + { -1, NULL, NULL, 5, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "dir_monitor_test", NULL, -1, NONE }, + { -1, NULL, NULL, 6, NONE } +}; + +static void +test_dir_monitor (Fixture *fixture, + gconstpointer user_data) +{ + GError *error = NULL; + TestData data; + + if (skip_win32 ()) + return; + + data.step = 0; + data.events = NULL; + + data.file = g_file_get_child (fixture->tmp_dir, "dir_monitor_test"); + g_file_delete (data.file, NULL, NULL); + g_file_make_directory (data.file, NULL, &error); + + data.monitor = g_file_monitor_directory (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); + g_assert_no_error (error); + + g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor)); + + g_file_monitor_set_rate_limit (data.monitor, 200); + g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data); + + data.loop = g_main_loop_new (NULL, TRUE); + + g_timeout_add (500, dir_step, &data); + + g_main_loop_run (data.loop); + + check_expected_events (dir_output, + G_N_ELEMENTS (dir_output), + data.events, + get_environment (data.monitor)); + + g_list_free_full (data.events, (GDestroyNotify)free_recorded_event); + g_main_loop_unref (data.loop); + g_object_unref (data.monitor); + g_object_unref (data.file); +} + +static gboolean +nodir_step (gpointer user_data) +{ + TestData *data = user_data; + GFile *parent; + GError *error = NULL; + + switch (data->step) + { + case 0: + record_event (data, -1, NULL, NULL, 0); + parent = g_file_get_parent (data->file); + g_file_make_directory (parent, NULL, &error); + g_assert_no_error (error); + g_object_unref (parent); + break; + case 1: + record_event (data, -1, NULL, NULL, 1); + g_file_replace_contents (data->file, "step 1", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); + g_assert_no_error (error); + break; + case 2: + record_event (data, -1, NULL, NULL, 2); + g_file_delete (data->file, NULL, &error); + g_assert_no_error (error); + break; + case 3: + record_event (data, -1, NULL, NULL, 3); + parent = g_file_get_parent (data->file); + g_file_delete (parent, NULL, &error); + g_assert_no_error (error); + g_object_unref (parent); + break; + case 4: + record_event (data, -1, NULL, NULL, 4); + g_main_loop_quit (data->loop); + return G_SOURCE_REMOVE; + } + + data->step++; + + return G_SOURCE_CONTINUE; +} + +static RecordedEvent nodir_output[] = { + { -1, NULL, NULL, 0, NONE }, + { G_FILE_MONITOR_EVENT_CREATED, "nosuchfile", NULL, -1, KQUEUE }, + { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "nosuchfile", NULL, -1, KQUEUE }, + { -1, NULL, NULL, 1, NONE }, + { G_FILE_MONITOR_EVENT_CREATED, "nosuchfile", NULL, -1, NONE }, + { G_FILE_MONITOR_EVENT_CHANGED, "nosuchfile", NULL, -1, KQUEUE }, + { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "nosuchfile", NULL, -1, KQUEUE }, + { -1, NULL, NULL, 2, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "nosuchfile", NULL, -1, NONE }, + { -1, NULL, NULL, 3, NONE }, + { -1, NULL, NULL, 4, NONE } +}; + +static void +test_dir_non_existent (Fixture *fixture, + gconstpointer user_data) +{ + TestData data; + GError *error = NULL; + + if (skip_win32 ()) + return; + + data.step = 0; + data.events = NULL; + + data.file = g_file_get_child (fixture->tmp_dir, "nosuchdir/nosuchfile"); + data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); + g_assert_no_error (error); + + g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor)); + + g_file_monitor_set_rate_limit (data.monitor, 200); + g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data); + + data.loop = g_main_loop_new (NULL, TRUE); + + /* we need a long timeout here, since the inotify implementation only scans + * for missing files every 4 seconds. + */ + g_timeout_add (5000, nodir_step, &data); + + g_main_loop_run (data.loop); + + check_expected_events (nodir_output, + G_N_ELEMENTS (nodir_output), + data.events, + get_environment (data.monitor)); + + g_list_free_full (data.events, (GDestroyNotify)free_recorded_event); + g_main_loop_unref (data.loop); + g_object_unref (data.monitor); + g_object_unref (data.file); +} + +static gboolean +cross_dir_step (gpointer user_data) +{ + TestData *data = user_data; + GFile *file, *file2; + GError *error = NULL; + + switch (data[0].step) + { + case 0: + record_event (&data[0], -1, NULL, NULL, 0); + record_event (&data[1], -1, NULL, NULL, 0); + file = g_file_get_child (data[1].file, "a"); + g_file_replace_contents (file, "step 0", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); + g_assert_no_error (error); + g_object_unref (file); + break; + case 1: + record_event (&data[0], -1, NULL, NULL, 1); + record_event (&data[1], -1, NULL, NULL, 1); + file = g_file_get_child (data[1].file, "a"); + file2 = g_file_get_child (data[0].file, "a"); + g_file_move (file, file2, 0, NULL, NULL, NULL, &error); + g_assert_no_error (error); + g_object_unref (file); + g_object_unref (file2); + break; + case 2: + record_event (&data[0], -1, NULL, NULL, 2); + record_event (&data[1], -1, NULL, NULL, 2); + file2 = g_file_get_child (data[0].file, "a"); + g_file_delete (file2, NULL, NULL); + g_file_delete (data[0].file, NULL, NULL); + g_file_delete (data[1].file, NULL, NULL); + g_object_unref (file2); + break; + case 3: + record_event (&data[0], -1, NULL, NULL, 3); + record_event (&data[1], -1, NULL, NULL, 3); + g_main_loop_quit (data->loop); + return G_SOURCE_REMOVE; + } + + data->step++; + + return G_SOURCE_CONTINUE; +} + +static RecordedEvent cross_dir_a_output[] = { + { -1, NULL, NULL, 0, NONE }, + { -1, NULL, NULL, 1, NONE }, + { G_FILE_MONITOR_EVENT_CREATED, "a", NULL, -1, NONE }, + { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "a", NULL, -1, KQUEUE }, + { -1, NULL, NULL, 2, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "a", NULL, -1, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "cross_dir_a", NULL, -1, NONE }, + { -1, NULL, NULL, 3, NONE }, +}; + +static RecordedEvent cross_dir_b_output[] = { + { -1, NULL, NULL, 0, NONE }, + { G_FILE_MONITOR_EVENT_CREATED, "a", NULL, -1, NONE }, + { G_FILE_MONITOR_EVENT_CHANGED, "a", NULL, -1, KQUEUE }, + { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "a", NULL, -1, KQUEUE }, + { -1, NULL, NULL, 1, NONE }, + { G_FILE_MONITOR_EVENT_MOVED_OUT, "a", "a", -1, NONE }, + { -1, NULL, NULL, 2, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "cross_dir_b", NULL, -1, NONE }, + { -1, NULL, NULL, 3, NONE }, +}; +static void +test_cross_dir_moves (Fixture *fixture, + gconstpointer user_data) +{ + GError *error = NULL; + TestData data[2]; + + if (skip_win32 ()) + return; + + data[0].step = 0; + data[0].events = NULL; + + data[0].file = g_file_get_child (fixture->tmp_dir, "cross_dir_a"); + g_file_delete (data[0].file, NULL, NULL); + g_file_make_directory (data[0].file, NULL, &error); + + data[0].monitor = g_file_monitor_directory (data[0].file, 0, NULL, &error); + g_assert_no_error (error); + + g_test_message ("Using GFileMonitor 0 %s", G_OBJECT_TYPE_NAME (data[0].monitor)); + + g_file_monitor_set_rate_limit (data[0].monitor, 200); + g_signal_connect (data[0].monitor, "changed", G_CALLBACK (monitor_changed), &data[0]); + + data[1].step = 0; + data[1].events = NULL; + + data[1].file = g_file_get_child (fixture->tmp_dir, "cross_dir_b"); + g_file_delete (data[1].file, NULL, NULL); + g_file_make_directory (data[1].file, NULL, &error); + + data[1].monitor = g_file_monitor_directory (data[1].file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); + g_assert_no_error (error); + + g_test_message ("Using GFileMonitor 1 %s", G_OBJECT_TYPE_NAME (data[1].monitor)); + + g_file_monitor_set_rate_limit (data[1].monitor, 200); + g_signal_connect (data[1].monitor, "changed", G_CALLBACK (monitor_changed), &data[1]); + + data[0].loop = g_main_loop_new (NULL, TRUE); + + g_timeout_add (500, cross_dir_step, data); + + g_main_loop_run (data[0].loop); + + check_expected_events (cross_dir_a_output, + G_N_ELEMENTS (cross_dir_a_output), + data[0].events, + get_environment (data[0].monitor)); + check_expected_events (cross_dir_b_output, + G_N_ELEMENTS (cross_dir_b_output), + data[1].events, + get_environment (data[1].monitor)); + + g_list_free_full (data[0].events, (GDestroyNotify)free_recorded_event); + g_main_loop_unref (data[0].loop); + g_object_unref (data[0].monitor); + g_object_unref (data[0].file); + + g_list_free_full (data[1].events, (GDestroyNotify)free_recorded_event); + g_object_unref (data[1].monitor); + g_object_unref (data[1].file); +} + +static gboolean +file_hard_links_step (gpointer user_data) +{ + gboolean retval = G_SOURCE_CONTINUE; + TestData *data = user_data; + GError *error = NULL; + + gchar *filename = g_file_get_path (data->file); + gchar *hard_link_name = g_strdup_printf ("%s2", filename); + GFile *hard_link_file = g_file_new_for_path (hard_link_name); + + switch (data->step) + { + case 0: + record_event (data, -1, NULL, NULL, 0); + g_output_stream_write_all (G_OUTPUT_STREAM (data->output_stream), + "hello, step 0", 13, NULL, NULL, &error); + g_assert_no_error (error); + g_output_stream_close (G_OUTPUT_STREAM (data->output_stream), NULL, &error); + g_assert_no_error (error); + break; + case 1: + record_event (data, -1, NULL, NULL, 1); + g_file_replace_contents (data->file, "step 1", 6, NULL, FALSE, + G_FILE_CREATE_NONE, NULL, NULL, &error); + g_assert_no_error (error); + break; + case 2: + record_event (data, -1, NULL, NULL, 2); +#ifdef HAVE_LINK + if (link (filename, hard_link_name) < 0) + { + g_error ("link(%s, %s) failed: %s", filename, hard_link_name, g_strerror (errno)); + } +#endif /* HAVE_LINK */ + break; + case 3: + record_event (data, -1, NULL, NULL, 3); +#ifdef HAVE_LINK + { + GOutputStream *hard_link_stream = NULL; + + /* Deliberately don’t do an atomic swap on the hard-linked file. */ + hard_link_stream = G_OUTPUT_STREAM (g_file_append_to (hard_link_file, + G_FILE_CREATE_NONE, + NULL, &error)); + g_assert_no_error (error); + g_output_stream_write_all (hard_link_stream, " step 3", 7, NULL, NULL, &error); + g_assert_no_error (error); + g_output_stream_close (hard_link_stream, NULL, &error); + g_assert_no_error (error); + g_object_unref (hard_link_stream); + } +#endif /* HAVE_LINK */ + break; + case 4: + record_event (data, -1, NULL, NULL, 4); + g_file_delete (data->file, NULL, &error); + g_assert_no_error (error); + break; + case 5: + record_event (data, -1, NULL, NULL, 5); +#ifdef HAVE_LINK + g_file_delete (hard_link_file, NULL, &error); + g_assert_no_error (error); +#endif /* HAVE_LINK */ + break; + case 6: + record_event (data, -1, NULL, NULL, 6); + g_main_loop_quit (data->loop); + retval = G_SOURCE_REMOVE; + break; + } + + if (retval != G_SOURCE_REMOVE) + data->step++; + + g_object_unref (hard_link_file); + g_free (hard_link_name); + g_free (filename); + + return retval; +} + +static RecordedEvent file_hard_links_output[] = { + { -1, NULL, NULL, 0, NONE }, + { G_FILE_MONITOR_EVENT_CHANGED, "testfilemonitor.db", NULL, -1, NONE }, + { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "testfilemonitor.db", NULL, -1, NONE }, + { -1, NULL, NULL, 1, NONE }, + { G_FILE_MONITOR_EVENT_RENAMED, (gchar*)DONT_CARE /* .goutputstream-XXXXXX */, "testfilemonitor.db", -1, NONE }, + { -1, NULL, NULL, 2, NONE }, + { -1, NULL, NULL, 3, NONE }, + /* Kqueue is based on file descriptors. You can get events from all hard + * links by just monitoring one open file descriptor, and it is not possible + * to know whether it is done on the file name we use to open the file. Since + * the hard link count of 'testfilemonitor.db' is 2, it is expected to see + * two 'DELETED' events reported here. You have to call 'unlink' twice on + * different file names to remove 'testfilemonitor.db' from the file system, + * and each 'unlink' call generates a 'DELETED' event. */ + { G_FILE_MONITOR_EVENT_CHANGED, "testfilemonitor.db", NULL, -1, INOTIFY }, + { -1, NULL, NULL, 4, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "testfilemonitor.db", NULL, -1, NONE }, + { -1, NULL, NULL, 5, NONE }, + { G_FILE_MONITOR_EVENT_DELETED, "testfilemonitor.db", NULL, -1, INOTIFY }, + { -1, NULL, NULL, 6, NONE }, +}; + +static void +test_file_hard_links (Fixture *fixture, + gconstpointer user_data) +{ + GError *error = NULL; + TestData data; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=755721"); + + if (skip_win32 ()) + return; + +#ifdef HAVE_LINK + g_test_message ("Running with hard link tests"); +#else /* if !HAVE_LINK */ + g_test_message ("Running without hard link tests"); +#endif /* !HAVE_LINK */ + + data.step = 0; + data.events = NULL; + + /* Create a file which exists and is not a directory. */ + data.file = g_file_get_child (fixture->tmp_dir, "testfilemonitor.db"); + data.output_stream = g_file_replace (data.file, NULL, FALSE, + G_FILE_CREATE_NONE, NULL, &error); + g_assert_no_error (error); + + /* Monitor it. Creating the monitor should not crash (bug #755721). */ + data.monitor = g_file_monitor_file (data.file, + G_FILE_MONITOR_WATCH_MOUNTS | + G_FILE_MONITOR_WATCH_MOVES | + G_FILE_MONITOR_WATCH_HARD_LINKS, + NULL, + &error); + g_assert_no_error (error); + g_assert_nonnull (data.monitor); + + g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor)); + + /* Change the file a bit. */ + g_file_monitor_set_rate_limit (data.monitor, 200); + g_signal_connect (data.monitor, "changed", (GCallback) monitor_changed, &data); + + data.loop = g_main_loop_new (NULL, TRUE); + g_timeout_add (500, file_hard_links_step, &data); + g_main_loop_run (data.loop); + + check_expected_events (file_hard_links_output, + G_N_ELEMENTS (file_hard_links_output), + data.events, + get_environment (data.monitor)); + + g_list_free_full (data.events, (GDestroyNotify) free_recorded_event); + g_main_loop_unref (data.loop); + g_object_unref (data.monitor); + g_object_unref (data.file); + g_object_unref (data.output_stream); +} + +static void +test_finalize_in_callback (Fixture *fixture, + gconstpointer user_data) +{ + GFile *file = NULL; + guint i; + + g_test_summary ("Test that finalization of a GFileMonitor in one of its " + "callbacks doesn’t cause a deadlock."); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1941"); + + file = g_file_get_child (fixture->tmp_dir, "race-file"); + + for (i = 0; i < 50; i++) + { + GFileMonitor *monitor = NULL; + GError *local_error = NULL; + + /* Monitor the file. */ + monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (monitor); + + /* Create the file. */ + g_file_replace_contents (file, "hello", 5, NULL, FALSE, + G_FILE_CREATE_NONE, NULL, NULL, &local_error); + g_assert_no_error (local_error); + + /* Immediately drop the last ref to the monitor in the hope that this + * happens in the middle of the critical section in + * g_file_monitor_source_handle_event(), so that any cleanup at the end + * of that function is done with a now-finalised file monitor. */ + g_object_unref (monitor); + + /* Re-create the monitor and do the same again for deleting the file, to + * give a second chance at hitting the race condition. */ + monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (monitor); + + /* Delete the file. */ + g_file_delete (file, NULL, &local_error); + g_assert_no_error (local_error); + + /* Drop the ref again. */ + g_object_unref (monitor); + } + + g_object_unref (file); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add ("/monitor/atomic-replace", Fixture, NULL, setup, test_atomic_replace, teardown); + g_test_add ("/monitor/file-changes", Fixture, NULL, setup, test_file_changes, teardown); + g_test_add ("/monitor/dir-monitor", Fixture, NULL, setup, test_dir_monitor, teardown); + g_test_add ("/monitor/dir-not-existent", Fixture, NULL, setup, test_dir_non_existent, teardown); + g_test_add ("/monitor/cross-dir-moves", Fixture, NULL, setup, test_cross_dir_moves, teardown); + g_test_add ("/monitor/file/hard-links", Fixture, NULL, setup, test_file_hard_links, teardown); + g_test_add ("/monitor/finalize-in-callback", Fixture, NULL, setup, test_finalize_in_callback, teardown); + + return g_test_run (); +} diff --git a/gio/tests/thumbnail-verification.c b/gio/tests/thumbnail-verification.c new file mode 100644 index 0000000..f439c8b --- /dev/null +++ b/gio/tests/thumbnail-verification.c @@ -0,0 +1,131 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2013 Collabora, Ltd. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Philip Withnall + */ + +#define GIO_COMPILATION 1 +#include "../thumbnail-verify.c" + +static void +test_validity (void) +{ + struct + { + const gchar *filename; /* name of a file in the tests/thumbnails dir */ + guint64 mtime; /* asserted mtime of @filename */ + guint64 size; /* asserted size of @filename */ + gboolean expected_validity; /* should thumbnail_verify() succeed? */ + } + tests[] = + { + /* + * Tests with well-formed PNG files. + * + * Note that these files have all been brutally truncated to a reasonable + * size, so aren't actually valid PNG files. Their headers are valid, + * however, and that's all we care about. + */ + + /* Test that validation succeeds against a valid PNG file with URI, + * mtime and size which match the expected values. */ + { "valid.png", 1382429848, 93654, TRUE }, + /* Test that validation succeeds with URI and mtime, but no size in the + * tEXt data. */ + { "valid-no-size.png", 1382429848, 93633, TRUE }, + /* Test that a missing file fails validation. */ + { "missing.png", 123456789, 12345, FALSE }, + /* Test that an existing file with no tEXt data fails validation. */ + { "no-text-data.png", 123 /* invalid */, 26378, FALSE }, + /* Test that a URI mismatch fails validation. */ + { "uri-mismatch.png" /* invalid */, 1382429848, 93654, FALSE }, + /* Test that an mtime mismatch fails validation. */ + { "valid.png", 123 /* invalid */, 93654, FALSE }, + /* Test that a valid URI and mtime, but a mismatched size, fails + * validation. */ + { "valid.png", 1382429848, 123 /* invalid */, FALSE }, + /* Test that validation succeeds with an mtime of 0. */ + { "mtime-zero.png", 0, 93621, TRUE }, + /* Test that validation fails if the mtime is only a prefix match. */ + { "valid.png", 9848 /* invalid */, 93654, FALSE }, + + /* + * Tests with PNG files which have malicious or badly-formed headers. + * + * As above, the files have all been truncated to reduce their size. + */ + + /* Check a corrupted PNG header fails validation. */ + { "bad-header.png", 1382429848, 93654, FALSE }, + /* Check a PNG header by itself fails. */ + { "header-only.png", 1382429848, 8, FALSE }, + /* Check a PNG header and initial chunk size fails. */ + { "header-and-chunk-size.png", 1382429848, 20, FALSE }, + /* Check a huge chunk size fails. */ + { "huge-chunk-size.png", 1382429848, 93654, FALSE }, + /* Check that an empty key fails. */ + { "empty-key.png", 1382429848, 93654, FALSE }, + /* Check that an over-long value fails (even if nul-terminated). */ + { "overlong-value.png", 1382429848, 93660, FALSE }, + }; + guint i; + + /* Run all the tests. */ + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + GLocalFileStat stat_buf; + const gchar *thumbnail_path; + gchar *file_uri; + gboolean result; + + thumbnail_path = g_test_get_filename (G_TEST_DIST, "thumbnails", + tests[i].filename, NULL); + file_uri = g_strconcat ("file:///tmp/", tests[i].filename, NULL); +#ifdef HAVE_STATX + stat_buf.stx_mtime.tv_sec = tests[i].mtime; + stat_buf.stx_size = tests[i].size; +#else +#ifdef G_OS_WIN32 + stat_buf.st_mtim.tv_sec = tests[i].mtime; +#else + stat_buf.st_mtime = tests[i].mtime; +#endif + stat_buf.st_size = tests[i].size; +#endif + + result = thumbnail_verify (thumbnail_path, file_uri, &stat_buf); + + g_free (file_uri); + + g_assert (result == tests[i].expected_validity); + } +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/png-thumbs/validity", test_validity); + + return g_test_run (); +} diff --git a/gio/tests/thumbnails/bad-header.png b/gio/tests/thumbnails/bad-header.png new file mode 100644 index 0000000000000000000000000000000000000000..36c15249115d9ce2b10520937802bfa1f7d66ba8 GIT binary patch literal 512 zcmeAS@b`1)<&xrJU|`_&^l%AcU|_h)z`)4B!NkD8uzJ~&KMV{E%*9TgAsieWw;%dH zU|?VnFL8}13CSqUO|r7`%uP&BwXzD&Oex7=Fg7rF|3sgefq_8+Q;A1vW_m^mgRz-m ztj7yK1_lNVBsHNyo(yT3IjL6q`uZig1^Q))IhiTCdHK4=iJaDG}zd16s2gS(%dQCY+#xV=&gPkdg~sVBpYozSKLtKKef#PDU+e$R YF27&(FZ}=Y|KGa%|9!iBzh=`K0CbqkUH||9 literal 0 HcmV?d00001 diff --git a/gio/tests/thumbnails/empty-key.png b/gio/tests/thumbnails/empty-key.png new file mode 100644 index 0000000000000000000000000000000000000000..b02088158618d1cf291c0c5d990cb4b2e174380c GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0y~yV7SV_z{tSC#K6F?dfAdc3=9m+#ZI0f92^|CANoIF zU|~fk6UOiAQQ?dPWI@v6*44 z#|u9O1_lL?8U~0lp+TMuX_+~xR{Hw-CAkIqWr;bNDS8EY>6N@a=NK3m1VL({Rt9HQ zr7~C=o0*zGC6V3Z8BY zU~aH?L-aDu;+f1Rng6r!KiU6quKOo*9@mP8YB4Q`XTD49Um(pZ!d0ysId!7o!*^+` zeu>FlQJyg4m`{IaN>}^t_Uak8E`Q(mz4pFwh^>oDi+js%X9mU{*2c^YGnpzHk{K8j z7kGSQP*M|o!s1X+&%(g4fVroi@x!;1>;Jv0|MC9+?(_Dwu2XCu72MF@dhOP;vpp{F z_TA2%SQ*R5;pee6%(&Yj%}Hc5q0aLKSEdT%j literal 0 HcmV?d00001 diff --git a/gio/tests/thumbnails/header-and-chunk-size.png b/gio/tests/thumbnails/header-and-chunk-size.png new file mode 100644 index 0000000000000000000000000000000000000000..1fdf4447b6031ec251ec00138e33d4cbceb8a396 GIT binary patch literal 20 bcmeAS@N?(olHy`uVBq!ia0y~yV7LkZCi?@k literal 0 HcmV?d00001 diff --git a/gio/tests/thumbnails/header-only.png b/gio/tests/thumbnails/header-only.png new file mode 100644 index 0000000..91d64e9 --- /dev/null +++ b/gio/tests/thumbnails/header-only.png @@ -0,0 +1,2 @@ +‰PNG + diff --git a/gio/tests/thumbnails/huge-chunk-size.png b/gio/tests/thumbnails/huge-chunk-size.png new file mode 100644 index 0000000000000000000000000000000000000000..730855360765849d7464f40416a532f5bcbfc390 GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0y~yV7SV_z{tSC#K6F?dfAdc3=9m+#ZI0f92^|CANoIF zU|~fk6UOiAQQ?dPWI@v6*44 z#|yvz|Ns9-QWF~F$&i+rlWL`}uV0c|pkJ1llbNDdke6P`+jEYAfk6;SZE$8)Dubo5 znW+g>64^bzA(^?U42H%QMkYp<7A6*73#WAE}PR}0C$towOs(mvHH7))gQMC4qQ|=0;3k+Ni z<_3E=L@(1Up2>WY`9BN)ll>3px_>g~ajkf$7SnQg=DWoH1=74CT-CafQzr^Oe3!QB zmzdlYq);!43Vb*KR#K+vDt<8 literal 0 HcmV?d00001 diff --git a/gio/tests/thumbnails/mtime-zero.png b/gio/tests/thumbnails/mtime-zero.png new file mode 100644 index 0000000000000000000000000000000000000000..8bac5f917d1bfa72c7181925efd02ff3a82d055b GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0y~yV7SV_z{tSC#K6F?dfAdc3=9m+#ZI0f92^|CANoIF zU|~fk6UOiAQQ?dPWI@v6*44 z#|u9O1_o6mHK9SC3~8A;saE>>`X#vq`ne^Uxv9EUsYUsE1$pU}ygla_7#R4FH28*O z=B6?je336Y#K6Fy0FnvLPb(=;EJ|f?_w)C4wXy=cFfTDP$1O3rB)_OK-zD?`1A_vC zr;B4q#hji!o|9EhPF4G67HV4jJ)&ss8K>M8Ocxlq9Lx>&Zirr{Sv-^ZB=dh3{wMn% z&UOD}&f{9~P%WnA@XU9K{R^adMYyVUBd1OjeE2SH)h{u*E6NjQ9P{b#OzCRh-CjN8 z*5&W}zSrJ24zYD{X>o7a?aaWq!`hg+VJ1^WLox${;sTFv3`%N(PgooZ>RA{V7BKhp zGk*AXa{a$|^*`SK-+kV`)^&>Qqku{#t-7!M`JS}k^M|fx>}+%D9h4rY%*mhg+46q#|F`wu z?;9&G6c%Ecn7}Y|H~Ws}4ws7cb2&MCXKLh2CfdGf)R<7rw0WM#9T5ggPNm(uce}e( LXlSu@E;#}KGDl>p literal 0 HcmV?d00001 diff --git a/gio/tests/thumbnails/overlong-value.png b/gio/tests/thumbnails/overlong-value.png new file mode 100644 index 0000000000000000000000000000000000000000..0f3c56e32487f819c82d8aeeb599dc9539d74c99 GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0y~yV7SV_z{tSC#K6F?dfAdc3=9m+#ZI0f92^|CANoIF zU|~fk6UOiAQQ?dPWI@v6*44 z#|u9O1_m`GHK9SC3~8A;saE>>`X#vq`elhZnJIb&dFc#3{(kNZmApOY7#J7?k#q!S zR;4mn8k?D#KqZk~|Y?wE5cQ+8##5N z;KO%mtA2^eT~VGeXG&N5?)K^#w=RF*_r3PMafq#pON)EUZf6F@9oELo4KtZ4 z8j=|p6c>1WV^C5Pe8S>TP|w1^uz$GYo;lhvuCdA%QxQKAuw^y=9z+p#_1}b L@}fLH1wI4-5Td=r literal 0 HcmV?d00001 diff --git a/gio/tests/thumbnails/uri-mismatch.png b/gio/tests/thumbnails/uri-mismatch.png new file mode 100644 index 0000000000000000000000000000000000000000..7629983a85dd7ba58329681713c90aba207047e9 GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0y~yV7SV_z{tSC#K6F?dfAdc3=9m+#ZI0f92^|CANoIF zU|~fk6UOiAQQ?dPWI@v6*44 z#|u9O1_lizHK9SC3~8A;saE>>`X#vq`elhZnJKz?`MSlKRjGOfdFhqBJ?GG@_6^C* zO=U1NwlFd=va~R<_#$6)h=GAY0c31&ep*R+Vo@rCyPv|Y?wE5cQ+8##5N;KO%mtA2^eT~VGe zXG&N5?)K^#w=RF*_r3PMafq#pON)EUZf6F@9oELo4KtZ48j=|p6c>1WV^C5Pe8S>T zP|w1^uz$GYo;lhvuCdA%QxQKAuw^y=9z+p#_1}b@}fLH1wK4|`|18)>;KO# YzhCt){Qvd;-@5z%eY~fk6UOiAQQ?dPWI@v6*44 z#|u9O1_lizHK9SC3~8A;saE>>`X#vq`elhZnJKz?`MSlKRjGOfdFhqBJ?GG@_6^C* zO=U1NwlFd=va~R<_#$6)h=GAY0c31&ep*R+Vo@rCyPv|Y?wE5cQ+8##5N;KO%mtA2^eT~VGe zXG&N5?)K^#w=RF*_r3PMafq#pON)EUZf6F@9oELo4KtZ48j=|p6c>1WV^C5Pe8S>T zP|w1^uz$GYo;lhvuCdA%QxQKAuw^y=9z+p#_1}b@}fLH1wK4|`|18)>;KO# YzhCt){Qvd;-@5z%eY~fk6UOiAQQ?dPWI@v6*44 z#|u9O1_lKrHK9SC3~8A;saE>>`X#vq`elhZnJIb&dFhqBJ?9u07zB~j24_~KGFTd$ znVLW)k=^4Pl9`*zU}$V%WMX7#VPf$`zUUCluHgK%lJdl&R0elHe_vNCE3g;x5;Jq$ z5|c~viz@S7LLV?NC@^@sIEGZr>Dl8sS>@zZwQpvjrp4bQiq@WS%3Z;9fq~1x++gp9 z=w+J4Gnr2^|7YQUvj5>+_fO_Lt`!f}VpO{eZ@6uNN5|g{4 zJYmK$pZ?C2uJ+yS)iZ8g{=V;f?S11ATNjrW_m|9e;e4C! I{lC@&0MZ1(fdBvi literal 0 HcmV?d00001 diff --git a/gio/tests/tls-bindings.c b/gio/tests/tls-bindings.c new file mode 100644 index 0000000..681b658 --- /dev/null +++ b/gio/tests/tls-bindings.c @@ -0,0 +1,95 @@ +/* + * Copyright 2020 (C) Ruslan N. Marchenko + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" + +#include + +#include "gtesttlsbackend.h" + +static void +get_tls_channel_binding (void) +{ + GTlsBackend *backend; + gchar *not_null = "NOT_NULL"; + GTlsConnection *tls = NULL; + GError *error = NULL; + + backend = g_tls_backend_get_default (); + g_assert_nonnull (backend); + + /* check unimplemented GTlsConnection API sanity */ + tls = G_TLS_CONNECTION (g_object_new ( + g_tls_backend_get_client_connection_type (backend), NULL)); + g_assert_nonnull (tls); + + g_assert_false (g_tls_connection_get_channel_binding_data (tls, + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, NULL, NULL)); + + g_assert_false (g_tls_connection_get_channel_binding_data (tls, + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, NULL, &error)); + g_assert_error (error, G_TLS_CHANNEL_BINDING_ERROR, + G_TLS_CHANNEL_BINDING_ERROR_NOT_IMPLEMENTED); + g_clear_error (&error); + + if (g_test_subprocess ()) + g_assert_false (g_tls_connection_get_channel_binding_data (tls, + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, NULL, (GError **)¬_null)); + + g_object_unref (tls); + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib-GIO-CRITICAL*"); +} + +static void +get_dtls_channel_binding (void) +{ + GTlsBackend *backend; + gchar *not_null = "NOT_NULL"; + GDtlsConnection *dtls = NULL; + GError *error = NULL; + + backend = g_tls_backend_get_default (); + g_assert_nonnull (backend); + + /* repeat for the dtls now */ + dtls = G_DTLS_CONNECTION (g_object_new ( + g_tls_backend_get_dtls_client_connection_type (backend), NULL)); + g_assert_nonnull (dtls); + + g_assert_false (g_dtls_connection_get_channel_binding_data (dtls, + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, NULL, NULL)); + + g_assert_false (g_dtls_connection_get_channel_binding_data (dtls, + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, NULL, &error)); + g_assert_error (error, G_TLS_CHANNEL_BINDING_ERROR, + G_TLS_CHANNEL_BINDING_ERROR_NOT_IMPLEMENTED); + g_clear_error (&error); + + if (g_test_subprocess ()) + g_assert_false (g_dtls_connection_get_channel_binding_data (dtls, + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, NULL, (GError **)¬_null)); + + g_object_unref (dtls); + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib-GIO-CRITICAL*"); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + _g_test_tls_backend_get_type (); + + g_test_add_func ("/tls-connection/get-tls-channel-binding", get_tls_channel_binding); + g_test_add_func ("/tls-connection/get-dtls-channel-binding", get_dtls_channel_binding); + + return g_test_run (); +} diff --git a/gio/tests/tls-certificate.c b/gio/tests/tls-certificate.c new file mode 100644 index 0000000..bae5823 --- /dev/null +++ b/gio/tests/tls-certificate.c @@ -0,0 +1,728 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Nicolas Dufresne + */ + +#include "config.h" + +#include + +#include "gtesttlsbackend.h" + +typedef struct +{ + gchar *cert_pems[3]; + gchar *cert_crlf_pem; + gchar *key_pem; + gchar *key_crlf_pem; + gchar *key8_pem; +} Reference; + +static void +pem_parser (const Reference *ref) +{ + GTlsCertificate *cert; + gchar *pem; + gsize pem_len = 0; + gchar *parsed_cert_pem = NULL; + gchar *parsed_key_pem = NULL; + GError *error = NULL; + + /* Check PEM parsing in certificate, private key order. */ + g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-key.pem", NULL), &pem, &pem_len, &error); + g_assert_no_error (error); + g_assert_nonnull (pem); + g_assert_cmpuint (pem_len, >=, 10); + + cert = g_tls_certificate_new_from_pem (pem, -1, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]); + g_clear_pointer (&parsed_cert_pem, g_free); + g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem); + g_clear_pointer (&parsed_key_pem, g_free); + + g_object_unref (cert); + + /* Make sure length is respected and parser detect invalid PEM + * when cert is truncated. */ + cert = g_tls_certificate_new_from_pem (pem, 10, &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); + g_clear_error (&error); + + /* Make sure length is respected and parser detect invalid PEM + * when cert exists but key is truncated. */ + cert = g_tls_certificate_new_from_pem (pem, pem_len - 10, &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); + g_clear_error (&error); + g_free (pem); + + /* Check PEM parsing in private key, certificate order */ + g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL), &pem, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (pem); + + cert = g_tls_certificate_new_from_pem (pem, -1, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]); + g_clear_pointer (&parsed_cert_pem, g_free); + g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem); + g_clear_pointer (&parsed_key_pem, g_free); + + g_free (pem); + g_object_unref (cert); + + /* Check certificate only PEM */ + g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), &pem, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (pem); + + cert = g_tls_certificate_new_from_pem (pem, -1, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]); + g_clear_pointer (&parsed_cert_pem, g_free); + g_assert_null (parsed_key_pem); + + g_free (pem); + g_object_unref (cert); + + /* Check error with private key only PEM */ + g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL), &pem, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (pem); + + cert = g_tls_certificate_new_from_pem (pem, -1, &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); + g_clear_error (&error); + g_assert_null (cert); + g_free (pem); +} + +static void +pem_parser_handles_chain (const Reference *ref) +{ + GTlsCertificate *cert; + GTlsCertificate *issuer; + GTlsCertificate *original_cert; + gchar *pem; + gchar *parsed_cert_pem = NULL; + gchar *parsed_key_pem = NULL; + GError *error = NULL; + + /* Check that a chain with exactly three certificates is returned */ + g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-list.pem", NULL), &pem, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (pem); + + cert = original_cert = g_tls_certificate_new_from_pem (pem, -1, &error); + g_free (pem); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]); + g_clear_pointer (&parsed_cert_pem, g_free); + + /* Make sure the private key was parsed */ + g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem); + g_clear_pointer (&parsed_key_pem, g_free); + + /* Now test the second cert */ + issuer = g_tls_certificate_get_issuer (cert); + g_assert_nonnull (issuer); + + cert = issuer; + issuer = g_tls_certificate_get_issuer (cert); + g_assert_nonnull (issuer); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[1]); + g_clear_pointer (&parsed_cert_pem, g_free); + + /* Only the first cert should have a private key */ + g_assert_null (parsed_key_pem); + + /* Now test the final cert */ + cert = issuer; + issuer = g_tls_certificate_get_issuer (cert); + g_assert_null (issuer); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[2]); + g_clear_pointer (&parsed_cert_pem, g_free); + + g_assert_null (parsed_key_pem); + + g_object_unref (original_cert); +} + +static void +pem_parser_no_sentinel (void) +{ + GTlsCertificate *cert; + gchar *pem; + gsize pem_len = 0; + gchar *pem_copy; + GError *error = NULL; + + /* Check certificate from not-nul-terminated PEM */ + g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), &pem, &pem_len, &error); + g_assert_no_error (error); + g_assert_nonnull (pem); + g_assert_cmpuint (pem_len, >=, 10); + + pem_copy = g_new (char, pem_len); + /* Do not copy the terminating nul: */ + memmove (pem_copy, pem, pem_len); + g_free (pem); + + /* Check whether the parser respects the @length parameter. + * pem_copy is allocated exactly pem_len bytes, so accessing memory + * outside its bounds will be detected by, for example, valgrind or + * asan. */ + cert = g_tls_certificate_new_from_pem (pem_copy, pem_len, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_free (pem_copy); + g_object_unref (cert); +} + +static void +from_file (const Reference *ref) +{ + GTlsCertificate *cert; + gchar *parsed_cert_pem = NULL; + gchar *parsed_key_pem = NULL; + GError *error = NULL; + + cert = g_tls_certificate_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL), + &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]); + g_clear_pointer (&parsed_cert_pem, g_free); + g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem); + g_clear_pointer (&parsed_key_pem, g_free); + + g_object_unref (cert); +} + +static void +from_files (const Reference *ref) +{ + GTlsCertificate *cert; + gchar *parsed_cert_pem = NULL; + gchar *parsed_key_pem = NULL; + GError *error = NULL; + + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL), + &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]); + g_clear_pointer (&parsed_cert_pem, g_free); + g_assert_cmpstr (parsed_key_pem, ==, ref->key_pem); + g_clear_pointer (&parsed_key_pem, g_free); + + g_object_unref (cert); + + /* Missing private key */ + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "cert2.pem", NULL), + &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); + g_clear_error (&error); + g_assert_null (cert); + + /* Missing header private key */ + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "key_missing-header.pem", NULL), + &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); + g_clear_error (&error); + g_assert_null (cert); + + /* Missing footer private key */ + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "key_missing-footer.pem", NULL), + &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); + g_clear_error (&error); + g_assert_null (cert); + + /* Missing certificate */ + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL), + &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); + g_clear_error (&error); + g_assert_null (cert); + + /* Using this method twice with a file containing both private key and + * certificate as a way to enforce private key presence is a fair use + */ + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "key-cert.pem", NULL), + &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + g_object_unref (cert); +} + +static void +from_files_crlf (const Reference *ref) +{ + GTlsCertificate *cert; + gchar *parsed_cert_pem = NULL; + gchar *parsed_key_pem = NULL; + GError *error = NULL; + + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-crlf.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "key-crlf.pem", NULL), + &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_crlf_pem); + g_clear_pointer (&parsed_cert_pem, g_free); + g_assert_cmpstr (parsed_key_pem, ==, ref->key_crlf_pem); + g_clear_pointer (&parsed_key_pem, g_free); + + g_object_unref (cert); +} + +static void +from_files_pkcs8 (const Reference *ref) +{ + GTlsCertificate *cert; + gchar *parsed_cert_pem = NULL; + gchar *parsed_key_pem = NULL; + GError *error = NULL; + + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "key8.pem", NULL), + &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + "private-key-pem", &parsed_key_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[0]); + g_clear_pointer (&parsed_cert_pem, g_free); + g_assert_cmpstr (parsed_key_pem, ==, ref->key8_pem); + g_clear_pointer (&parsed_key_pem, g_free); + + g_object_unref (cert); +} + +static void +from_files_pkcs8enc (const Reference *ref) +{ + GTlsCertificate *cert; + GError *error = NULL; + + /* Mare sure an error is returned for encrypted key */ + cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), + g_test_get_filename (G_TEST_DIST, "cert-tests", "key8enc.pem", NULL), + &error); + g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE); + g_clear_error (&error); + g_assert_null (cert); +} + +static void +list_from_file (const Reference *ref) +{ + GList *list, *l; + GError *error = NULL; + int i; + + list = g_tls_certificate_list_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert-list.pem", NULL), + &error); + g_assert_no_error (error); + g_assert_cmpint (g_list_length (list), ==, 3); + + l = list; + for (i = 0; i < 3; i++) + { + GTlsCertificate *cert = l->data; + gchar *parsed_cert_pem = NULL; + g_object_get (cert, + "certificate-pem", &parsed_cert_pem, + NULL); + g_assert_cmpstr (parsed_cert_pem, ==, ref->cert_pems[i]); + g_free (parsed_cert_pem); + l = g_list_next (l); + } + + g_list_free_full (list, g_object_unref); + + /* Empty list is not an error */ + list = g_tls_certificate_list_new_from_file (g_test_get_filename (G_TEST_DIST, "cert-tests", "nothing.pem", NULL), + &error); + g_assert_no_error (error); + g_assert_cmpint (g_list_length (list), ==, 0); +} + +static void +from_pkcs11_uri (void) +{ + GError *error = NULL; + GTlsCertificate *cert; + gchar *pkcs11_uri = NULL; + + cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + g_object_get (cert, "pkcs11-uri", &pkcs11_uri, NULL); + g_assert_cmpstr ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", ==, pkcs11_uri); + g_free (pkcs11_uri); + + g_object_unref (cert); +} + +static void +from_unsupported_pkcs11_uri (void) +{ + GError *error = NULL; + GTlsCertificate *cert; + + /* This is a magic value in gtesttlsbackend.c simulating an unsupported backend */ + cert = g_tls_certificate_new_from_pkcs11_uris ("unsupported", NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_assert_null (cert); + + g_clear_error (&error); +} + +static void +not_valid_before (void) +{ + const gchar *EXPECTED_NOT_VALID_BEFORE = "2020-10-12T17:49:44Z"; + + GTlsCertificate *cert; + GError *error = NULL; + GDateTime *actual; + gchar *actual_str; + + cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + actual = g_tls_certificate_get_not_valid_before (cert); + g_assert_nonnull (actual); + actual_str = g_date_time_format_iso8601 (actual); + g_assert_cmpstr (actual_str, ==, EXPECTED_NOT_VALID_BEFORE); + g_free (actual_str); + g_date_time_unref (actual); + g_object_unref (cert); +} + +static void +not_valid_after (void) +{ + const gchar *EXPECTED_NOT_VALID_AFTER = "2045-10-06T17:49:44Z"; + + GTlsCertificate *cert; + GError *error = NULL; + GDateTime *actual; + gchar *actual_str; + + cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + actual = g_tls_certificate_get_not_valid_after (cert); + g_assert_nonnull (actual); + actual_str = g_date_time_format_iso8601 (actual); + g_assert_cmpstr (actual_str, ==, EXPECTED_NOT_VALID_AFTER); + g_free (actual_str); + g_date_time_unref (actual); + g_object_unref (cert); +} + +static void +subject_name (void) +{ + const gchar *EXPECTED_SUBJECT_NAME = "DC=COM,DC=EXAMPLE,CN=server.example.com"; + + GTlsCertificate *cert; + GError *error = NULL; + gchar *actual; + + cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + actual = g_tls_certificate_get_subject_name (cert); + g_assert_nonnull (actual); + g_assert_cmpstr (actual, ==, EXPECTED_SUBJECT_NAME); + g_free (actual); + g_object_unref (cert); +} + +static void +issuer_name (void) +{ + const gchar *EXPECTED_ISSUER_NAME = "DC=COM,DC=EXAMPLE,OU=Certificate Authority,CN=ca.example.com,emailAddress=ca@example.com"; + + GTlsCertificate *cert; + GError *error = NULL; + gchar *actual; + + cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + actual = g_tls_certificate_get_issuer_name (cert); + g_assert_nonnull (actual); + g_assert_cmpstr (actual, ==, EXPECTED_ISSUER_NAME); + g_free (actual); + g_object_unref (cert); +} + +static void +dns_names (void) +{ + GTlsCertificate *cert; + GError *error = NULL; + GPtrArray *actual; + const gchar *dns_name = "a.example.com"; + GBytes *expected = g_bytes_new_static (dns_name, strlen (dns_name)); + + cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + actual = g_tls_certificate_get_dns_names (cert); + g_assert_nonnull (actual); + g_assert_cmpuint (actual->len, ==, 1); + g_assert_true (g_ptr_array_find_with_equal_func (actual, expected, (GEqualFunc)g_bytes_equal, NULL)); + + g_ptr_array_unref (actual); + g_bytes_unref (expected); + g_object_unref (cert); +} + +static void +ip_addresses (void) +{ + GTlsCertificate *cert; + GError *error = NULL; + GPtrArray *actual; + GInetAddress *expected = g_inet_address_new_from_string ("192.0.2.1"); + + cert = g_tls_certificate_new_from_pkcs11_uris ("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (cert); + + actual = g_tls_certificate_get_ip_addresses (cert); + g_assert_nonnull (actual); + g_assert_cmpuint (actual->len, ==, 1); + g_assert_true (g_ptr_array_find_with_equal_func (actual, expected, (GEqualFunc)g_inet_address_equal, NULL)); + + g_ptr_array_free (actual, TRUE); + g_object_unref (expected); + g_object_unref (cert); +} + +static void +from_pkcs12 (void) +{ + GTlsCertificate *cert; + GError *error = NULL; + const guint8 data[1] = { 0 }; + + /* This simply fails because our test backend doesn't support this + * property. This reflects using a backend that doesn't support it. + * The real test lives in glib-networking. */ + cert = g_tls_certificate_new_from_pkcs12 (data, 1, NULL, &error); + + g_assert_null (cert); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_error_free (error); +} + +static void +from_pkcs12_file (void) +{ + GTlsCertificate *cert; + GError *error = NULL; + char *path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key-cert-password-123.p12", NULL); + + /* Fails on our test backend, see from_pkcs12() above. */ + cert = g_tls_certificate_new_from_file_with_password (path, "123", &error); + g_assert_null (cert); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + + /* Just for coverage. */ + cert = g_tls_certificate_new_from_file (path, &error); + g_assert_null (cert); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_error_free (error); + + g_free (path); +} + +int +main (int argc, + char *argv[]) +{ + int rtv; + Reference ref; + GError *error = NULL; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + _g_test_tls_backend_get_type (); + + /* Load reference PEM */ + path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL); + g_file_get_contents (path, &ref.cert_pems[0], NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (ref.cert_pems[0]); + g_free (path); + path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert2.pem", NULL); + g_file_get_contents (path, &ref.cert_pems[1], NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (ref.cert_pems[1]); + g_free (path); + path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert3.pem", NULL); + g_file_get_contents (path, &ref.cert_pems[2], NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (ref.cert_pems[2]); + g_free (path); + path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert-crlf.pem", NULL); + g_file_get_contents (path, &ref.cert_crlf_pem, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (ref.cert_crlf_pem); + g_free (path); + path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL); + g_file_get_contents (path, &ref.key_pem, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (ref.key_pem); + g_free (path); + path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key-crlf.pem", NULL); + g_file_get_contents (path, &ref.key_crlf_pem, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (ref.key_crlf_pem); + g_free (path); + path = g_test_build_filename (G_TEST_DIST, "cert-tests", "key8.pem", NULL); + g_file_get_contents (path, &ref.key8_pem, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (ref.key8_pem); + g_free (path); + + g_test_add_data_func ("/tls-certificate/pem-parser", + &ref, (GTestDataFunc)pem_parser); + g_test_add_data_func ("/tls-certificate/pem-parser-handles-chain", + &ref, (GTestDataFunc)pem_parser_handles_chain); + g_test_add_data_func ("/tls-certificate/from_file", + &ref, (GTestDataFunc)from_file); + g_test_add_data_func ("/tls-certificate/from_files", + &ref, (GTestDataFunc)from_files); + g_test_add_data_func ("/tls-certificate/from_files_crlf", + &ref, (GTestDataFunc)from_files_crlf); + g_test_add_data_func ("/tls-certificate/from_files_pkcs8", + &ref, (GTestDataFunc)from_files_pkcs8); + g_test_add_data_func ("/tls-certificate/from_files_pkcs8enc", + &ref, (GTestDataFunc)from_files_pkcs8enc); + g_test_add_data_func ("/tls-certificate/list_from_file", + &ref, (GTestDataFunc)list_from_file); + g_test_add_func ("/tls-certificate/pkcs11-uri", + from_pkcs11_uri); + g_test_add_func ("/tls-certificate/pkcs11-uri-unsupported", + from_unsupported_pkcs11_uri); + g_test_add_func ("/tls-certificate/from_pkcs12", + from_pkcs12); + g_test_add_func ("/tls-certificate/from_pkcs12_file", + from_pkcs12_file); + g_test_add_func ("/tls-certificate/not-valid-before", + not_valid_before); + g_test_add_func ("/tls-certificate/not-valid-after", + not_valid_after); + g_test_add_func ("/tls-certificate/subject-name", + subject_name); + g_test_add_func ("/tls-certificate/issuer-name", + issuer_name); + g_test_add_func ("/tls-certificate/dns-names", + dns_names); + g_test_add_func ("/tls-certificate/ip-addresses", + ip_addresses); + g_test_add_func ("/tls-certificate/pem-parser-no-sentinel", + pem_parser_no_sentinel); + + rtv = g_test_run(); + + g_free (ref.cert_pems[0]); + g_free (ref.cert_pems[1]); + g_free (ref.cert_pems[2]); + g_free (ref.cert_crlf_pem); + g_free (ref.key_pem); + g_free (ref.key_crlf_pem); + g_free (ref.key8_pem); + + return rtv; +} diff --git a/gio/tests/tls-database.c b/gio/tests/tls-database.c new file mode 100644 index 0000000..1bad255 --- /dev/null +++ b/gio/tests/tls-database.c @@ -0,0 +1,75 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) Matthew Waters . + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include + +#include "gtesttlsbackend.h" + +static void +set_default_database (void) +{ + GTlsBackend *backend; + GTlsDatabase *default_db, *file_db, *test_db; + GError *error = NULL; + gchar *path; + + backend = g_tls_backend_get_default (); + g_assert_nonnull (backend); + + default_db = g_tls_backend_get_default_database (backend); + g_assert_nonnull (default_db); + + path = g_test_build_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL); + file_db = g_tls_file_database_new (path, &error); + g_assert_no_error (error); + g_assert_nonnull (file_db); + + /* setting a default database makes get_default_database return that database */ + g_tls_backend_set_default_database (backend, file_db); + test_db = g_tls_backend_get_default_database (backend); + g_assert_nonnull (test_db); + g_assert_true (test_db == file_db); + g_object_unref (test_db); + + /* setting a NULL default database returns the original default database */ + g_tls_backend_set_default_database (backend, NULL); + test_db = g_tls_backend_get_default_database (backend); + g_assert_nonnull (test_db); + g_assert_true (test_db == default_db); + + g_object_unref (default_db); + g_object_unref (file_db); + g_object_unref (test_db); + g_free (path); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + _g_test_tls_backend_get_type (); + + g_test_add_func ("/tls-backend/set-default-database", + set_default_database); + + return g_test_run(); +} diff --git a/gio/tests/tls-interaction.c b/gio/tests/tls-interaction.c new file mode 100644 index 0000000..5661e8e --- /dev/null +++ b/gio/tests/tls-interaction.c @@ -0,0 +1,1107 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Stef Walter + */ + +#include "config.h" + +#include + +#include "gtesttlsbackend.h" + +static GPtrArray *fixtures = NULL; + +typedef struct { + /* Class virtual interaction methods */ + gpointer ask_password_func; + gpointer ask_password_async_func; + gpointer ask_password_finish_func; + gpointer request_certificate_func; + gpointer request_certificate_async_func; + gpointer request_certificate_finish_func; + + /* Expected results */ + GTlsInteractionResult result; + GQuark error_domain; + gint error_code; + const gchar *error_message; +} Fixture; + +typedef struct { + GTlsInteraction *interaction; + GTlsPassword *password; + GTlsConnection *connection; + GMainLoop *loop; + GThread *interaction_thread; + GThread *test_thread; + GThread *loop_thread; + const Fixture *fixture; +} Test; + +typedef struct { + GTlsInteraction parent; + Test *test; +} TestInteraction; + +typedef struct { + GTlsInteractionClass parent; +} TestInteractionClass; + +static GType test_interaction_get_type (void); +G_DEFINE_TYPE (TestInteraction, test_interaction, G_TYPE_TLS_INTERACTION) + +#define TEST_TYPE_INTERACTION (test_interaction_get_type ()) +#define TEST_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_INTERACTION, TestInteraction)) +#define TEST_IS_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TEST_TYPE_INTERACTION)) + +static void +test_interaction_init (TestInteraction *self) +{ + +} + +static void +test_interaction_class_init (TestInteractionClass *klass) +{ + /* By default no virtual methods */ +} + +static void +test_interaction_ask_password_async_success (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (G_IS_TLS_PASSWORD (password)); + g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + task = g_task_new (self, cancellable, callback, user_data); + + /* Don't do this in real life. Include a null terminator for testing */ + g_tls_password_set_value (password, (const guchar *)"the password", 13); + g_task_return_int (task, G_TLS_INTERACTION_HANDLED); + g_object_unref (task); +} + + +static GTlsInteractionResult +test_interaction_ask_password_finish_success (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error) +{ + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (g_task_is_valid (result, interaction)); + g_assert (error != NULL); + g_assert (*error == NULL); + + return g_task_propagate_int (G_TASK (result), error); +} + +static void +test_interaction_ask_password_async_failure (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (G_IS_TLS_PASSWORD (password)); + g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + task = g_task_new (self, cancellable, callback, user_data); + + g_task_return_new_error (task, G_FILE_ERROR, G_FILE_ERROR_ACCES, "The message"); + g_object_unref (task); +} + +static GTlsInteractionResult +test_interaction_ask_password_finish_failure (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error) +{ + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (g_task_is_valid (result, interaction)); + g_assert (error != NULL); + g_assert (*error == NULL); + + if (g_task_propagate_int (G_TASK (result), error) != -1) + g_assert_not_reached (); + + return G_TLS_INTERACTION_FAILED; +} + + +/* Return a copy of @str that is allocated in a silly way, to exercise + * custom free-functions. The returned pointer points to a copy of @str + * in a buffer of the form "BEFORE \0 str \0 AFTER". */ +static guchar * +special_dup (const char *str) +{ + GString *buf = g_string_new ("BEFORE"); + guchar *ret; + + g_string_append_c (buf, '\0'); + g_string_append (buf, str); + g_string_append_c (buf, '\0'); + g_string_append (buf, "AFTER"); + ret = (guchar *) g_string_free (buf, FALSE); + return ret + strlen ("BEFORE") + 1; +} + + +/* Free a copy of @str that was made with special_dup(), after asserting + * that it has not been corrupted. */ +static void +special_free (gpointer p) +{ + gchar *s = p; + gchar *buf = s - strlen ("BEFORE") - 1; + + g_assert_cmpstr (buf, ==, "BEFORE"); + g_assert_cmpstr (s + strlen (s) + 1, ==, "AFTER"); + g_free (buf); +} + + +static GTlsInteractionResult +test_interaction_ask_password_sync_success (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GError **error) +{ + TestInteraction *self; + const guchar *value; + gsize len; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (G_IS_TLS_PASSWORD (password)); + g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_assert (error != NULL); + g_assert (*error == NULL); + + /* Exercise different ways to set the value */ + g_tls_password_set_value (password, (const guchar *) "foo", 4); + len = 0; + value = g_tls_password_get_value (password, &len); + g_assert_cmpmem (value, len, "foo", 4); + + g_tls_password_set_value (password, (const guchar *) "bar", -1); + len = 0; + value = g_tls_password_get_value (password, &len); + g_assert_cmpmem (value, len, "bar", 3); + + g_tls_password_set_value_full (password, special_dup ("baa"), 4, special_free); + len = 0; + value = g_tls_password_get_value (password, &len); + g_assert_cmpmem (value, len, "baa", 4); + + g_tls_password_set_value_full (password, special_dup ("baz"), -1, special_free); + len = 0; + value = g_tls_password_get_value (password, &len); + g_assert_cmpmem (value, len, "baz", 3); + + /* Don't do this in real life. Include a null terminator for testing */ + g_tls_password_set_value (password, (const guchar *)"the password", 13); + return G_TLS_INTERACTION_HANDLED; +} + +static GTlsInteractionResult +test_interaction_ask_password_sync_failure (GTlsInteraction *interaction, + GTlsPassword *password, + GCancellable *cancellable, + GError **error) +{ + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (G_IS_TLS_PASSWORD (password)); + g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_assert (error != NULL); + g_assert (*error == NULL); + + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES, "The message"); + return G_TLS_INTERACTION_FAILED; +} + +static void +test_interaction_request_certificate_async_success (GTlsInteraction *interaction, + GTlsConnection *connection, + gint unused_flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (G_IS_TLS_CONNECTION (connection)); + g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_assert (unused_flags == 0); + + task = g_task_new (self, cancellable, callback, user_data); + + /* + * IRL would call g_tls_connection_set_certificate(). But here just touch + * the connection in a detectable way. + */ + g_object_set_data (G_OBJECT (connection), "chosen-certificate", "my-certificate"); + g_task_return_int (task, G_TLS_INTERACTION_HANDLED); + g_object_unref (task); +} + +static GTlsInteractionResult +test_interaction_request_certificate_finish_success (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error) +{ + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (g_task_is_valid (result, interaction)); + g_assert (error != NULL); + g_assert (*error == NULL); + + return g_task_propagate_int (G_TASK (result), error); +} + +static void +test_interaction_request_certificate_async_failure (GTlsInteraction *interaction, + GTlsConnection *connection, + gint unused_flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (G_IS_TLS_CONNECTION (connection)); + g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_assert (unused_flags == 0); + + task = g_task_new (self, cancellable, callback, user_data); + + g_task_return_new_error (task, G_FILE_ERROR, G_FILE_ERROR_NOENT, "Another message"); + g_object_unref (task); +} + +static GTlsInteractionResult +test_interaction_request_certificate_finish_failure (GTlsInteraction *interaction, + GAsyncResult *result, + GError **error) +{ + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (g_task_is_valid (result, interaction)); + g_assert (error != NULL); + g_assert (*error == NULL); + + if (g_task_propagate_int (G_TASK (result), error) != -1) + g_assert_not_reached (); + + return G_TLS_INTERACTION_FAILED; +} + +static GTlsInteractionResult +test_interaction_request_certificate_sync_success (GTlsInteraction *interaction, + GTlsConnection *connection, + gint unused_flags, + GCancellable *cancellable, + GError **error) +{ + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (G_IS_TLS_CONNECTION (connection)); + g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_assert (error != NULL); + g_assert (*error == NULL); + + /* + * IRL would call g_tls_connection_set_certificate(). But here just touch + * the connection in a detectable way. + */ + g_object_set_data (G_OBJECT (connection), "chosen-certificate", "my-certificate"); + return G_TLS_INTERACTION_HANDLED; +} + +static GTlsInteractionResult +test_interaction_request_certificate_sync_failure (GTlsInteraction *interaction, + GTlsConnection *connection, + gint unused_flags, + GCancellable *cancellable, + GError **error) +{ + TestInteraction *self; + + g_assert (TEST_IS_INTERACTION (interaction)); + self = TEST_INTERACTION (interaction); + + g_assert (g_thread_self () == self->test->interaction_thread); + + g_assert (G_IS_TLS_CONNECTION (connection)); + g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + g_assert (unused_flags == 0); + g_assert (error != NULL); + g_assert (*error == NULL); + + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, "Another message"); + return G_TLS_INTERACTION_FAILED; +} + +/* ---------------------------------------------------------------------------- + * ACTUAL TESTS + */ + +static void +on_ask_password_async_call (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + Test *test = user_data; + GTlsInteractionResult res; + GError *error = NULL; + + g_assert (G_IS_TLS_INTERACTION (source)); + g_assert (G_TLS_INTERACTION (source) == test->interaction); + + /* Check that this callback is being run in the right place */ + g_assert (g_thread_self () == test->interaction_thread); + + res = g_tls_interaction_ask_password_finish (test->interaction, result, + &error); + + /* Check that the results match the fixture */ + g_assert_cmpuint (test->fixture->result, ==, res); + switch (test->fixture->result) + { + case G_TLS_INTERACTION_HANDLED: + g_assert_no_error (error); + g_assert_cmpstr ((const gchar *)g_tls_password_get_value (test->password, NULL), ==, "the password"); + break; + case G_TLS_INTERACTION_FAILED: + g_assert_error (error, test->fixture->error_domain, test->fixture->error_code); + g_assert_cmpstr (error->message, ==, test->fixture->error_message); + g_clear_error (&error); + break; + case G_TLS_INTERACTION_UNHANDLED: + g_assert_no_error (error); + break; + default: + g_assert_not_reached (); + } + + /* Signal the end of the test */ + g_main_loop_quit (test->loop); +} + +static void +test_ask_password_async (Test *test, + gconstpointer unused) +{ + /* This test only works with a main loop */ + g_assert (test->loop); + + g_tls_interaction_ask_password_async (test->interaction, + test->password, NULL, + on_ask_password_async_call, + test); + + /* teardown waits until g_main_loop_quit(). called from callback */ +} + +static void +test_invoke_ask_password (Test *test, + gconstpointer unused) +{ + GTlsInteractionResult res; + GError *error = NULL; + + res = g_tls_interaction_invoke_ask_password (test->interaction, test->password, + NULL, &error); + + /* Check that the results match the fixture */ + g_assert_cmpuint (test->fixture->result, ==, res); + switch (test->fixture->result) + { + case G_TLS_INTERACTION_HANDLED: + g_assert_no_error (error); + g_assert_cmpstr ((const gchar *)g_tls_password_get_value (test->password, NULL), ==, "the password"); + break; + case G_TLS_INTERACTION_FAILED: + g_assert_error (error, test->fixture->error_domain, test->fixture->error_code); + g_assert_cmpstr (error->message, ==, test->fixture->error_message); + g_clear_error (&error); + break; + case G_TLS_INTERACTION_UNHANDLED: + g_assert_no_error (error); + break; + default: + g_assert_not_reached (); + } + + /* This allows teardown to stop if running with loop */ + if (test->loop) + g_main_loop_quit (test->loop); +} + +static void +test_ask_password (Test *test, + gconstpointer unused) +{ + GTlsInteractionResult res; + GError *error = NULL; + + res = g_tls_interaction_ask_password (test->interaction, test->password, + NULL, &error); + + /* Check that the results match the fixture */ + g_assert_cmpuint (test->fixture->result, ==, res); + switch (test->fixture->result) + { + case G_TLS_INTERACTION_HANDLED: + g_assert_no_error (error); + g_assert_cmpstr ((const gchar *)g_tls_password_get_value (test->password, NULL), ==, "the password"); + break; + case G_TLS_INTERACTION_FAILED: + g_assert_error (error, test->fixture->error_domain, test->fixture->error_code); + g_assert_cmpstr (error->message, ==, test->fixture->error_message); + g_clear_error (&error); + break; + case G_TLS_INTERACTION_UNHANDLED: + g_assert_no_error (error); + break; + default: + g_assert_not_reached (); + } + + /* This allows teardown to stop if running with loop */ + if (test->loop) + g_main_loop_quit (test->loop); +} + +static void +on_request_certificate_async_call (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + Test *test = user_data; + GTlsInteractionResult res; + GError *error = NULL; + + g_assert (G_IS_TLS_INTERACTION (source)); + g_assert (G_TLS_INTERACTION (source) == test->interaction); + + /* Check that this callback is being run in the right place */ + g_assert (g_thread_self () == test->interaction_thread); + + res = g_tls_interaction_request_certificate_finish (test->interaction, result, &error); + + /* Check that the results match the fixture */ + g_assert_cmpuint (test->fixture->result, ==, res); + switch (test->fixture->result) + { + case G_TLS_INTERACTION_HANDLED: + g_assert_no_error (error); + g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate"); + break; + case G_TLS_INTERACTION_FAILED: + g_assert_error (error, test->fixture->error_domain, test->fixture->error_code); + g_assert_cmpstr (error->message, ==, test->fixture->error_message); + g_clear_error (&error); + break; + case G_TLS_INTERACTION_UNHANDLED: + g_assert_no_error (error); + break; + default: + g_assert_not_reached (); + } + + /* Signal the end of the test */ + g_main_loop_quit (test->loop); +} + +static void +test_request_certificate_async (Test *test, + gconstpointer unused) +{ + /* This test only works with a main loop */ + g_assert (test->loop); + + g_tls_interaction_request_certificate_async (test->interaction, + test->connection, 0, NULL, + on_request_certificate_async_call, + test); + + /* teardown waits until g_main_loop_quit(). called from callback */ +} + +static void +test_invoke_request_certificate (Test *test, + gconstpointer unused) +{ + GTlsInteractionResult res; + GError *error = NULL; + + res = g_tls_interaction_invoke_request_certificate (test->interaction, + test->connection, + 0, NULL, &error); + + /* Check that the results match the fixture */ + g_assert_cmpuint (test->fixture->result, ==, res); + switch (test->fixture->result) + { + case G_TLS_INTERACTION_HANDLED: + g_assert_no_error (error); + g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate"); + break; + case G_TLS_INTERACTION_FAILED: + g_assert_error (error, test->fixture->error_domain, test->fixture->error_code); + g_assert_cmpstr (error->message, ==, test->fixture->error_message); + g_clear_error (&error); + break; + case G_TLS_INTERACTION_UNHANDLED: + g_assert_no_error (error); + break; + default: + g_assert_not_reached (); + } + + /* This allows teardown to stop if running with loop */ + if (test->loop) + g_main_loop_quit (test->loop); +} + +static void +test_request_certificate (Test *test, + gconstpointer unused) +{ + GTlsInteractionResult res; + GError *error = NULL; + + res = g_tls_interaction_request_certificate (test->interaction, test->connection, + 0, NULL, &error); + + /* Check that the results match the fixture */ + g_assert_cmpuint (test->fixture->result, ==, res); + switch (test->fixture->result) + { + case G_TLS_INTERACTION_HANDLED: + g_assert_no_error (error); + g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate"); + break; + case G_TLS_INTERACTION_FAILED: + g_assert_error (error, test->fixture->error_domain, test->fixture->error_code); + g_assert_cmpstr (error->message, ==, test->fixture->error_message); + g_clear_error (&error); + break; + case G_TLS_INTERACTION_UNHANDLED: + g_assert_no_error (error); + break; + default: + g_assert_not_reached (); + } + + /* This allows teardown to stop if running with loop */ + if (test->loop) + g_main_loop_quit (test->loop); +} + +/* ---------------------------------------------------------------------------- + * TEST SETUP + */ + +static void +setup_without_loop (Test *test, + gconstpointer user_data) +{ + const Fixture *fixture = user_data; + GTlsInteractionClass *klass; + GTlsBackend *backend; + GError *error = NULL; + + test->fixture = fixture; + + test->interaction = g_object_new (TEST_TYPE_INTERACTION, NULL); + g_assert (TEST_IS_INTERACTION (test->interaction)); + + TEST_INTERACTION (test->interaction)->test = test; + + klass = G_TLS_INTERACTION_GET_CLASS (test->interaction); + klass->ask_password = fixture->ask_password_func; + klass->ask_password_async = fixture->ask_password_async_func; + klass->ask_password_finish = fixture->ask_password_finish_func; + klass->request_certificate = fixture->request_certificate_func; + klass->request_certificate_async = fixture->request_certificate_async_func; + klass->request_certificate_finish = fixture->request_certificate_finish_func; + + backend = g_object_new (G_TYPE_TEST_TLS_BACKEND, NULL); + test->connection = g_object_new (g_tls_backend_get_server_connection_type (backend), NULL); + g_assert_no_error (error); + g_object_unref (backend); + + test->password = g_tls_password_new (0, "Description"); + test->test_thread = g_thread_self (); + + /* + * If no loop is running then interaction should happen in the same + * thread that the tests are running in. + */ + test->interaction_thread = test->test_thread; +} + +static void +teardown_without_loop (Test *test, + gconstpointer unused) +{ + g_object_unref (test->connection); + g_object_unref (test->password); + + g_assert_finalize_object (test->interaction); +} + +typedef struct { + GMutex loop_mutex; + GCond loop_started; + gboolean started; + Test *test; +} ThreadLoop; + +static gpointer +thread_loop (gpointer user_data) +{ + GMainContext *context = g_main_context_default (); + ThreadLoop *closure = user_data; + Test *test = closure->test; + + g_mutex_lock (&closure->loop_mutex); + + g_assert (test->loop_thread == g_thread_self ()); + g_assert (test->loop == NULL); + test->loop = g_main_loop_new (context, TRUE); + + g_main_context_acquire (context); + closure->started = TRUE; + g_cond_signal (&closure->loop_started); + g_mutex_unlock (&closure->loop_mutex); + + while (g_main_loop_is_running (test->loop)) + g_main_context_iteration (context, TRUE); + + g_main_context_release (context); + return test; +} + +static void +setup_with_thread_loop (Test *test, + gconstpointer user_data) +{ + ThreadLoop closure; + + setup_without_loop (test, user_data); + + g_mutex_init (&closure.loop_mutex); + g_cond_init (&closure.loop_started); + closure.started = FALSE; + closure.test = test; + + g_mutex_lock (&closure.loop_mutex); + test->loop_thread = g_thread_new ("loop", thread_loop, &closure); + while (!closure.started) + g_cond_wait (&closure.loop_started, &closure.loop_mutex); + g_mutex_unlock (&closure.loop_mutex); + + /* + * When a loop is running then interaction should always occur in the main + * context of that loop. + */ + test->interaction_thread = test->loop_thread; + + g_mutex_clear (&closure.loop_mutex); + g_cond_clear (&closure.loop_started); +} + +static void +teardown_with_thread_loop (Test *test, + gconstpointer unused) +{ + gpointer check; + + g_assert (test->loop_thread); + check = g_thread_join (test->loop_thread); + g_assert (check == test); + test->loop_thread = NULL; + + g_main_loop_unref (test->loop); + + teardown_without_loop (test, unused); +} + +static void +setup_with_normal_loop (Test *test, + gconstpointer user_data) +{ + GMainContext *context; + + setup_without_loop (test, user_data); + + context = g_main_context_default (); + if (!g_main_context_acquire (context)) + g_assert_not_reached (); + + test->loop = g_main_loop_new (context, TRUE); + g_assert (g_main_loop_is_running (test->loop)); +} + +static void +teardown_with_normal_loop (Test *test, + gconstpointer unused) +{ + GMainContext *context; + + context = g_main_context_default (); + while (g_main_loop_is_running (test->loop)) + g_main_context_iteration (context, TRUE); + + g_main_context_release (context); + + /* Run test until complete */ + g_main_loop_unref (test->loop); + test->loop = NULL; + + teardown_without_loop (test, unused); +} + +typedef void (*TestFunc) (Test *test, gconstpointer data); + +static void +test_with_async_ask_password (const gchar *name, + TestFunc setup, + TestFunc func, + TestFunc teardown) +{ + gchar *test_name; + Fixture *fixture; + + /* Async implementation that succeeds */ + fixture = g_new0 (Fixture, 1); + fixture->ask_password_async_func = test_interaction_ask_password_async_success; + fixture->ask_password_finish_func = test_interaction_ask_password_finish_success; + fixture->ask_password_func = NULL; + fixture->result = G_TLS_INTERACTION_HANDLED; + test_name = g_strdup_printf ("%s/async-implementation-success", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); + + /* Async implementation that fails */ + fixture = g_new0 (Fixture, 1); + fixture->ask_password_async_func = test_interaction_ask_password_async_failure; + fixture->ask_password_finish_func = test_interaction_ask_password_finish_failure; + fixture->ask_password_func = NULL; + fixture->result = G_TLS_INTERACTION_FAILED; + fixture->error_domain = G_FILE_ERROR; + fixture->error_code = G_FILE_ERROR_ACCES; + fixture->error_message = "The message"; + test_name = g_strdup_printf ("%s/async-implementation-failure", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); +} + +static void +test_with_unhandled_ask_password (const gchar *name, + TestFunc setup, + TestFunc func, + TestFunc teardown) +{ + gchar *test_name; + Fixture *fixture; + + /* Unhandled implementation */ + fixture = g_new0 (Fixture, 1); + fixture->ask_password_async_func = NULL; + fixture->ask_password_finish_func = NULL; + fixture->ask_password_func = NULL; + fixture->result = G_TLS_INTERACTION_UNHANDLED; + test_name = g_strdup_printf ("%s/unhandled-implementation", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); +} + +static void +test_with_sync_ask_password (const gchar *name, + TestFunc setup, + TestFunc func, + TestFunc teardown) +{ + gchar *test_name; + Fixture *fixture; + + /* Sync implementation that succeeds */ + fixture = g_new0 (Fixture, 1); + fixture->ask_password_async_func = NULL; + fixture->ask_password_finish_func = NULL; + fixture->ask_password_func = test_interaction_ask_password_sync_success; + fixture->result = G_TLS_INTERACTION_HANDLED; + test_name = g_strdup_printf ("%s/sync-implementation-success", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); + + /* Async implementation that fails */ + fixture = g_new0 (Fixture, 1); + fixture->ask_password_async_func = NULL; + fixture->ask_password_finish_func = NULL; + fixture->ask_password_func = test_interaction_ask_password_sync_failure; + fixture->result = G_TLS_INTERACTION_FAILED; + fixture->error_domain = G_FILE_ERROR; + fixture->error_code = G_FILE_ERROR_ACCES; + fixture->error_message = "The message"; + test_name = g_strdup_printf ("%s/sync-implementation-failure", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); +} + +static void +test_with_all_ask_password (const gchar *name, + TestFunc setup, + TestFunc func, + TestFunc teardown) +{ + test_with_unhandled_ask_password (name, setup, func, teardown); + test_with_async_ask_password (name, setup, func, teardown); + test_with_sync_ask_password (name, setup, func, teardown); +} + +static void +test_with_async_request_certificate (const gchar *name, + TestFunc setup, + TestFunc func, + TestFunc teardown) +{ + gchar *test_name; + Fixture *fixture; + + /* Async implementation that succeeds */ + fixture = g_new0 (Fixture, 1); + fixture->request_certificate_async_func = test_interaction_request_certificate_async_success; + fixture->request_certificate_finish_func = test_interaction_request_certificate_finish_success; + fixture->request_certificate_func = NULL; + fixture->result = G_TLS_INTERACTION_HANDLED; + test_name = g_strdup_printf ("%s/async-implementation-success", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); + + /* Async implementation that fails */ + fixture = g_new0 (Fixture, 1); + fixture->request_certificate_async_func = test_interaction_request_certificate_async_failure; + fixture->request_certificate_finish_func = test_interaction_request_certificate_finish_failure; + fixture->request_certificate_func = NULL; + fixture->result = G_TLS_INTERACTION_FAILED; + fixture->error_domain = G_FILE_ERROR; + fixture->error_code = G_FILE_ERROR_NOENT; + fixture->error_message = "Another message"; + test_name = g_strdup_printf ("%s/async-implementation-failure", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); +} + +static void +test_with_unhandled_request_certificate (const gchar *name, + TestFunc setup, + TestFunc func, + TestFunc teardown) +{ + gchar *test_name; + Fixture *fixture; + + /* Unhandled implementation */ + fixture = g_new0 (Fixture, 1); + fixture->request_certificate_async_func = NULL; + fixture->request_certificate_finish_func = NULL; + fixture->request_certificate_func = NULL; + fixture->result = G_TLS_INTERACTION_UNHANDLED; + test_name = g_strdup_printf ("%s/unhandled-implementation", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); +} + +static void +test_with_sync_request_certificate (const gchar *name, + TestFunc setup, + TestFunc func, + TestFunc teardown) +{ + gchar *test_name; + Fixture *fixture; + + /* Sync implementation that succeeds */ + fixture = g_new0 (Fixture, 1); + fixture->request_certificate_async_func = NULL; + fixture->request_certificate_finish_func = NULL; + fixture->request_certificate_func = test_interaction_request_certificate_sync_success; + fixture->result = G_TLS_INTERACTION_HANDLED; + test_name = g_strdup_printf ("%s/sync-implementation-success", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); + + /* Async implementation that fails */ + fixture = g_new0 (Fixture, 1); + fixture->request_certificate_async_func = NULL; + fixture->request_certificate_finish_func = NULL; + fixture->request_certificate_func = test_interaction_request_certificate_sync_failure; + fixture->result = G_TLS_INTERACTION_FAILED; + fixture->error_domain = G_FILE_ERROR; + fixture->error_code = G_FILE_ERROR_NOENT; + fixture->error_message = "Another message"; + test_name = g_strdup_printf ("%s/sync-implementation-failure", name); + g_test_add (test_name, Test, fixture, setup, func, teardown); + g_free (test_name); + g_ptr_array_add (fixtures, fixture); +} + +static void +test_with_all_request_certificate (const gchar *name, + TestFunc setup, + TestFunc func, + TestFunc teardown) +{ + test_with_unhandled_request_certificate (name, setup, func, teardown); + test_with_async_request_certificate (name, setup, func, teardown); + test_with_sync_request_certificate (name, setup, func, teardown); +} +int +main (int argc, + char *argv[]) +{ + gint ret; + + g_test_init (&argc, &argv, NULL); + + fixtures = g_ptr_array_new_with_free_func (g_free); + + /* Tests for g_tls_interaction_invoke_ask_password */ + test_with_all_ask_password ("/tls-interaction/ask-password/invoke-with-loop", + setup_with_thread_loop, test_invoke_ask_password, teardown_with_thread_loop); + test_with_all_ask_password ("/tls-interaction/ask-password/invoke-without-loop", + setup_without_loop, test_invoke_ask_password, teardown_without_loop); + test_with_all_ask_password ("/tls-interaction/ask-password/invoke-in-loop", + setup_with_normal_loop, test_invoke_ask_password, teardown_with_normal_loop); + + /* Tests for g_tls_interaction_ask_password */ + test_with_unhandled_ask_password ("/tls-interaction/ask-password/sync", + setup_without_loop, test_ask_password, teardown_without_loop); + test_with_sync_ask_password ("/tls-interaction/ask-password/sync", + setup_without_loop, test_ask_password, teardown_without_loop); + + /* Tests for g_tls_interaction_ask_password_async */ + test_with_unhandled_ask_password ("/tls-interaction/ask-password/async", + setup_with_normal_loop, test_ask_password_async, teardown_with_normal_loop); + test_with_async_ask_password ("/tls-interaction/ask-password/async", + setup_with_normal_loop, test_ask_password_async, teardown_with_normal_loop); + + /* Tests for g_tls_interaction_invoke_request_certificate */ + test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-with-loop", + setup_with_thread_loop, test_invoke_request_certificate, teardown_with_thread_loop); + test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-without-loop", + setup_without_loop, test_invoke_request_certificate, teardown_without_loop); + test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-in-loop", + setup_with_normal_loop, test_invoke_request_certificate, teardown_with_normal_loop); + + /* Tests for g_tls_interaction_ask_password */ + test_with_unhandled_request_certificate ("/tls-interaction/request-certificate/sync", + setup_without_loop, test_request_certificate, teardown_without_loop); + test_with_sync_request_certificate ("/tls-interaction/request-certificate/sync", + setup_without_loop, test_request_certificate, teardown_without_loop); + + /* Tests for g_tls_interaction_ask_password_async */ + test_with_unhandled_request_certificate ("/tls-interaction/request-certificate/async", + setup_with_normal_loop, test_request_certificate_async, teardown_with_normal_loop); + test_with_async_request_certificate ("/tls-interaction/request-certificate/async", + setup_with_normal_loop, test_request_certificate_async, teardown_with_normal_loop); + + ret = g_test_run(); + g_ptr_array_free (fixtures, TRUE); + return ret; +} diff --git a/gio/tests/trash.c b/gio/tests/trash.c new file mode 100644 index 0000000..b5fa4be --- /dev/null +++ b/gio/tests/trash.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * licence, or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include + +#ifndef G_OS_UNIX +#error This is a Unix-specific test +#endif + +#include +#include +#include + +/* Test that g_file_trash() returns G_IO_ERROR_NOT_SUPPORTED for files on system mounts. */ +static void +test_trash_not_supported (void) +{ + GFile *file; + GFileIOStream *stream; + GUnixMountEntry *mount; + GFileInfo *info; + GError *error = NULL; + gboolean ret; + gchar *parent_dirname; + GStatBuf parent_stat, home_stat; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/251"); + + /* The test assumes that tmp file is located on system internal mount. */ + file = g_file_new_tmp ("test-trashXXXXXX", &stream, &error); + parent_dirname = g_path_get_dirname (g_file_peek_path (file)); + g_assert_no_error (error); + g_assert_cmpint (g_stat (parent_dirname, &parent_stat), ==, 0); + g_test_message ("File: %s (parent st_dev: %" G_GUINT64_FORMAT ")", + g_file_peek_path (file), (guint64) parent_stat.st_dev); + + g_assert_cmpint (g_stat (g_get_home_dir (), &home_stat), ==, 0); + g_test_message ("Home: %s (st_dev: %" G_GUINT64_FORMAT ")", + g_get_home_dir (), (guint64) home_stat.st_dev); + + if (parent_stat.st_dev == home_stat.st_dev) + { + g_test_skip ("The file has to be on another filesystem than the home trash to run this test"); + + g_free (parent_dirname); + g_object_unref (stream); + g_object_unref (file); + + return; + } + + mount = g_unix_mount_for (g_file_peek_path (file), NULL); + g_assert_true (mount == NULL || g_unix_mount_is_system_internal (mount)); + g_test_message ("Mount: %s", (mount != NULL) ? g_unix_mount_get_mount_path (mount) : "(null)"); + g_clear_pointer (&mount, g_unix_mount_free); + + /* g_file_trash() shouldn't be supported on system internal mounts, + * because those are not monitored by gvfsd-trash. + */ + ret = g_file_trash (file, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_test_message ("Error: %s", error->message); + g_assert_false (ret); + g_clear_error (&error); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, + &error); + g_assert_no_error (error); + + g_assert_false (g_file_info_get_attribute_boolean (info, + G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH)); + + g_io_stream_close (G_IO_STREAM (stream), NULL, &error); + g_assert_no_error (error); + + g_free (parent_dirname); + g_object_unref (info); + g_object_unref (stream); + g_object_unref (file); +} + +/* Test that symlinks are properly expaned when looking for topdir (e.g. for trash folder). */ +static void +test_trash_symlinks (void) +{ + GFile *symlink; + GUnixMountEntry *target_mount, *tmp_mount, *symlink_mount, *target_over_symlink_mount; + gchar *target, *tmp, *target_over_symlink; + GError *error = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1522"); + + target = g_build_filename (g_get_home_dir (), ".local", NULL); + + if (!g_file_test (target, G_FILE_TEST_IS_DIR)) + { + g_test_skip_printf ("Directory '%s' does not exist", target); + g_free (target); + return; + } + + target_mount = g_unix_mount_for (target, NULL); + + if (target_mount == NULL) + { + g_test_skip_printf ("Unable to determine mount point for %s", target); + g_free (target); + return; + } + + g_assert_nonnull (target_mount); + g_test_message ("Target: %s (mount: %s)", target, g_unix_mount_get_mount_path (target_mount)); + + tmp = g_dir_make_tmp ("test-trashXXXXXX", &error); + g_assert_no_error (error); + g_assert_nonnull (tmp); + tmp_mount = g_unix_mount_for (tmp, NULL); + + if (tmp_mount == NULL) + { + g_test_skip_printf ("Unable to determine mount point for %s", tmp); + g_unix_mount_free (target_mount); + g_free (target); + g_free (tmp); + return; + } + + g_assert_nonnull (tmp_mount); + g_test_message ("Tmp: %s (mount: %s)", tmp, g_unix_mount_get_mount_path (tmp_mount)); + + if (g_unix_mount_compare (target_mount, tmp_mount) == 0) + { + g_test_skip ("The tmp has to be on another mount than the home to run this test"); + + g_unix_mount_free (tmp_mount); + g_free (tmp); + g_unix_mount_free (target_mount); + g_free (target); + + return; + } + + symlink = g_file_new_build_filename (tmp, "symlink", NULL); + g_file_make_symbolic_link (symlink, g_get_home_dir (), NULL, &error); + g_assert_no_error (error); + + symlink_mount = g_unix_mount_for (g_file_peek_path (symlink), NULL); + g_assert_nonnull (symlink_mount); + g_test_message ("Symlink: %s (mount: %s)", g_file_peek_path (symlink), g_unix_mount_get_mount_path (symlink_mount)); + + g_assert_cmpint (g_unix_mount_compare (symlink_mount, tmp_mount), ==, 0); + + target_over_symlink = g_build_filename (g_file_peek_path (symlink), + ".local", + NULL); + target_over_symlink_mount = g_unix_mount_for (target_over_symlink, NULL); + g_assert_nonnull (symlink_mount); + g_test_message ("Target over symlink: %s (mount: %s)", target_over_symlink, g_unix_mount_get_mount_path (target_over_symlink_mount)); + + g_assert_cmpint (g_unix_mount_compare (target_over_symlink_mount, target_mount), ==, 0); + + g_unix_mount_free (target_over_symlink_mount); + g_unix_mount_free (symlink_mount); + g_free (target_over_symlink); + g_object_unref (symlink); + g_unix_mount_free (tmp_mount); + g_free (tmp); + g_unix_mount_free (target_mount); + g_free (target); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/trash/not-supported", test_trash_not_supported); + g_test_add_func ("/trash/symlinks", test_trash_symlinks); + + return g_test_run (); +} diff --git a/gio/tests/unix-fd.c b/gio/tests/unix-fd.c new file mode 100644 index 0000000..4d984df --- /dev/null +++ b/gio/tests/unix-fd.c @@ -0,0 +1,242 @@ +#include +#include +#include +#include +#include +#include + +/* ensures that no FDs are left open at the end */ +static void +check_fd_list (const gint *fd_list) +{ + gint i; + + for (i = 0; i < 40; i++) + { + int my_fd; + + my_fd = dup (0); + g_assert_cmpint (fd_list[i], ==, my_fd); + } + + for (i = 0; i < 40; i++) + close (fd_list[i]); +} + +static void +create_fd_list (gint *fd_list) +{ + gint i; + + for (i = 0; i < 40; i++) + { + fd_list[i] = dup (0); + g_assert_cmpint (fd_list[i], >, 0); + } + + for (i = 0; i < 40; i++) + close (fd_list[i]); +} + +static void +test_fds (void) +{ + GError *err = NULL; + GUnixFDMessage *message; + GUnixFDMessage **mv; + GUnixFDList *list, *l2; + GSocket *sockets[2]; + GSocketAddress *addr; + const gint *peek; + char buffer[1024]; + gint fd_list[40]; + GOutputVector ov; + GInputVector iv; + gint *stolen; + gint sv[3]; + gint flags; + gint nm; + gint s; + gchar *path; + GByteArray *array; + gboolean abstract; + GUnixSocketAddressType type; + + create_fd_list (fd_list); + + s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv); + g_assert_cmpint (s, ==, 0); + sv[2] = -1; + + list = g_unix_fd_list_new_from_array (sv, -1); + message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new_with_fd_list (list)); + g_object_unref (list); + + g_assert (g_unix_fd_message_get_fd_list (message) == list); + g_object_get (message, "fd-list", &l2, NULL); + g_assert (l2 == list); + g_assert_cmpint (g_unix_fd_list_get_length (list), ==, 2); + + peek = g_unix_fd_list_peek_fds (list, &s); + g_assert_cmpint (s, ==, 2); + stolen = g_unix_fd_message_steal_fds (message, &s); + g_assert_cmpint (s, ==, 2); + g_assert (stolen == peek); + + g_assert_cmpint (stolen[0], ==, sv[0]); + g_assert_cmpint (stolen[1], ==, sv[1]); + g_assert_cmpint (stolen[2], ==, sv[2]); + g_free (stolen); + + g_unix_fd_message_append_fd (message, sv[0], &err); + g_assert_no_error (err); + s = close (sv[0]); + g_assert_cmpint (s, ==, 0); + g_unix_fd_message_append_fd (message, sv[1], &err); + g_assert_no_error (err); + s = close (sv[1]); + g_assert_cmpint (s, ==, 0); + + s = close (g_unix_fd_list_get (list, 0, &err)); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 0); + s = close (g_unix_fd_list_get (list, 1, &err)); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 0); + s = close (g_unix_fd_list_get (list, 0, &err)); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 0); + s = close (g_unix_fd_list_get (list, 1, &err)); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 0); + s = close (g_unix_fd_list_get (list, 0, &err)); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 0); + s = close (g_unix_fd_list_get (list, 1, &err)); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 0); + + g_object_unref (message); + g_object_unref (list); + + message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new ()); + list = g_unix_fd_message_get_fd_list (message); + s = pipe (sv); + g_assert_cmpint (s, ==, 0); + + s = g_unix_fd_list_append (list, sv[0], &err); + g_assert_no_error (err); + g_assert_cmpint (s, >=, 0); + s = g_unix_fd_list_append (list, sv[1], &err); + g_assert_no_error (err); + g_assert_cmpint (s, >=, 0); + + s = close (sv[0]); + g_assert_cmpint (s, ==, 0); + s = close (sv[1]); + g_assert_cmpint (s, ==, 0); + s = close (g_unix_fd_list_get (list, 0, &err)); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 0); + s = close (g_unix_fd_list_get (list, 1, &err)); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 0); + + s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv); + g_assert_cmpint (s, ==, 0); + + sockets[0] = g_socket_new_from_fd (sv[0], &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (sockets[0])); + sockets[1] = g_socket_new_from_fd (sv[1], &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (sockets[1])); + + addr = g_socket_get_local_address (sockets[0], &err); + g_assert_no_error (err); + g_assert (G_IS_UNIX_SOCKET_ADDRESS (addr)); + g_assert_cmpint (g_unix_socket_address_get_address_type (G_UNIX_SOCKET_ADDRESS (addr)), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + g_assert_cmpint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (addr)), ==, 0); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_assert (!g_unix_socket_address_get_is_abstract (G_UNIX_SOCKET_ADDRESS (addr))); +G_GNUC_END_IGNORE_DEPRECATIONS + + g_object_get (addr, + "path", &path, + "path-as-array", &array, + "abstract", &abstract, + "address-type", &type, + NULL); + g_assert_cmpstr (path, ==, ""); + g_assert_cmpint (array->len, ==, 0); + g_assert (!abstract); + g_assert (type == G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + g_free (path); + g_byte_array_free (array, TRUE); + + g_object_unref (addr); + + buffer[0] = 0xff; + ov.buffer = buffer; + ov.size = 1; + s = g_socket_send_message (sockets[0], NULL, &ov, 1, + (GSocketControlMessage **) &message, + 1, 0, NULL, &err); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 1); + g_object_unref (message); + + message = NULL; + + flags = 0; + iv.buffer = buffer; + iv.size = 1; + s = g_socket_receive_message (sockets[1], NULL, &iv, 1, + (GSocketControlMessage ***) &mv, + &nm, &flags, NULL, &err); + g_assert_no_error (err); + g_assert_cmpint (s, ==, 1); + g_object_unref (sockets[0]); + g_object_unref (sockets[1]); + + g_assert_cmpint (nm, ==, 1); + message = mv[0]; + g_free (mv); + + g_assert (G_IS_UNIX_FD_MESSAGE (message)); + list = g_object_ref (g_unix_fd_message_get_fd_list (message)); + g_object_unref (message); + + peek = g_unix_fd_list_peek_fds (list, &s); + g_assert_cmpint (s, ==, 2); + sv[0] = g_unix_fd_list_get (list, 1, &err); + g_assert_no_error (err); + + strcpy (buffer, "failure to say failure to say 'i love gnome-panel!'."); + s = write (sv[0], buffer, strlen (buffer) + 1); + g_assert_cmpint (s, ==, strlen (buffer) + 1); + + close (sv[0]); + memset (buffer, 0xff, sizeof buffer); + + s = read (peek[0], buffer, sizeof buffer); + g_assert_cmpint (s, ==, 53); + g_assert_cmpstr (buffer, ==, + "failure to say failure to say 'i love gnome-panel!'."); + + g_object_unref (list); + + check_fd_list (fd_list); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/unix-streams/file-descriptors", test_fds); + + return g_test_run(); + +} diff --git a/gio/tests/unix-mounts.c b/gio/tests/unix-mounts.c new file mode 100644 index 0000000..67b8c8d --- /dev/null +++ b/gio/tests/unix-mounts.c @@ -0,0 +1,63 @@ +/* GLib testing framework examples and tests + * + * Copyright © 2017 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +#ifndef G_OS_UNIX +#error This is a Unix-specific test +#endif + +#include +#include +#include +#include +#include + +static void +test_is_system_fs_type (void) +{ + g_assert_true (g_unix_is_system_fs_type ("tmpfs")); + g_assert_false (g_unix_is_system_fs_type ("ext4")); + + /* Check that some common network file systems aren’t considered ‘system’. */ + g_assert_false (g_unix_is_system_fs_type ("cifs")); + g_assert_false (g_unix_is_system_fs_type ("nfs")); + g_assert_false (g_unix_is_system_fs_type ("nfs4")); + g_assert_false (g_unix_is_system_fs_type ("smbfs")); +} + +static void +test_is_system_device_path (void) +{ + g_assert_true (g_unix_is_system_device_path ("devpts")); + g_assert_false (g_unix_is_system_device_path ("/")); +} + +int +main (int argc, + char *argv[]) +{ + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/unix-mounts/is-system-fs-type", test_is_system_fs_type); + g_test_add_func ("/unix-mounts/is-system-device-path", test_is_system_device_path); + + return g_test_run (); +} diff --git a/gio/tests/unix-streams.c b/gio/tests/unix-streams.c new file mode 100644 index 0000000..407a67d --- /dev/null +++ b/gio/tests/unix-streams.c @@ -0,0 +1,872 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* sizeof(DATA) will give the number of bytes in the array, plus the terminating nul */ +static const gchar DATA[] = "abcdefghijklmnopqrstuvwxyz"; + +int writer_pipe[2], reader_pipe[2]; +GCancellable *writer_cancel, *reader_cancel, *main_cancel; +GMainLoop *loop; + + +static gpointer +writer_thread (gpointer user_data) +{ + GOutputStream *out; + gssize nwrote, offset; + GError *err = NULL; + + out = g_unix_output_stream_new (writer_pipe[1], TRUE); + + do + { + g_usleep (10); + + offset = 0; + while (offset < (gssize) sizeof (DATA)) + { + nwrote = g_output_stream_write (out, DATA + offset, + sizeof (DATA) - offset, + writer_cancel, &err); + if (nwrote <= 0 || err != NULL) + break; + offset += nwrote; + } + + g_assert (nwrote > 0 || err != NULL); + } + while (err == NULL); + + if (g_cancellable_is_cancelled (writer_cancel)) + { + g_clear_error (&err); + g_cancellable_cancel (main_cancel); + g_object_unref (out); + return NULL; + } + + g_warning ("writer: %s", err->message); + g_assert_not_reached (); +} + +static gpointer +reader_thread (gpointer user_data) +{ + GInputStream *in; + gssize nread = 0, total; + GError *err = NULL; + char buf[sizeof (DATA)]; + + in = g_unix_input_stream_new (reader_pipe[0], TRUE); + + do + { + total = 0; + while (total < (gssize) sizeof (DATA)) + { + nread = g_input_stream_read (in, buf + total, sizeof (buf) - total, + reader_cancel, &err); + if (nread <= 0 || err != NULL) + break; + total += nread; + } + + if (err) + break; + + if (nread == 0) + { + g_assert (err == NULL); + /* pipe closed */ + g_object_unref (in); + return NULL; + } + + g_assert_cmpstr (buf, ==, DATA); + g_assert (!g_cancellable_is_cancelled (reader_cancel)); + } + while (err == NULL); + + g_warning ("reader: %s", err->message); + g_assert_not_reached (); +} + +static char main_buf[sizeof (DATA)]; +static gssize main_len, main_offset; + +static void main_thread_read (GObject *source, GAsyncResult *res, gpointer user_data); +static void main_thread_skipped (GObject *source, GAsyncResult *res, gpointer user_data); +static void main_thread_wrote (GObject *source, GAsyncResult *res, gpointer user_data); + +static void +do_main_cancel (GOutputStream *out) +{ + g_output_stream_close (out, NULL, NULL); + g_main_loop_quit (loop); +} + +static void +main_thread_skipped (GObject *source, GAsyncResult *res, gpointer user_data) +{ + GInputStream *in = G_INPUT_STREAM (source); + GOutputStream *out = user_data; + GError *err = NULL; + gssize nskipped; + + nskipped = g_input_stream_skip_finish (in, res, &err); + + if (g_cancellable_is_cancelled (main_cancel)) + { + do_main_cancel (out); + return; + } + + g_assert_no_error (err); + + main_offset += nskipped; + if (main_offset == main_len) + { + main_offset = 0; + g_output_stream_write_async (out, main_buf, main_len, + G_PRIORITY_DEFAULT, main_cancel, + main_thread_wrote, in); + } + else + { + g_input_stream_skip_async (in, main_len - main_offset, + G_PRIORITY_DEFAULT, main_cancel, + main_thread_skipped, out); + } +} + +static void +main_thread_read (GObject *source, GAsyncResult *res, gpointer user_data) +{ + GInputStream *in = G_INPUT_STREAM (source); + GOutputStream *out = user_data; + GError *err = NULL; + gssize nread; + + nread = g_input_stream_read_finish (in, res, &err); + + if (g_cancellable_is_cancelled (main_cancel)) + { + do_main_cancel (out); + g_clear_error (&err); + return; + } + + g_assert_no_error (err); + + main_offset += nread; + if (main_offset == sizeof (DATA)) + { + main_len = main_offset; + main_offset = 0; + /* Now skip the same amount */ + g_input_stream_skip_async (in, main_len, + G_PRIORITY_DEFAULT, main_cancel, + main_thread_skipped, out); + } + else + { + g_input_stream_read_async (in, main_buf, sizeof (main_buf), + G_PRIORITY_DEFAULT, main_cancel, + main_thread_read, out); + } +} + +static void +main_thread_wrote (GObject *source, GAsyncResult *res, gpointer user_data) +{ + GOutputStream *out = G_OUTPUT_STREAM (source); + GInputStream *in = user_data; + GError *err = NULL; + gssize nwrote; + + nwrote = g_output_stream_write_finish (out, res, &err); + + if (g_cancellable_is_cancelled (main_cancel)) + { + do_main_cancel (out); + g_clear_error (&err); + return; + } + + g_assert_no_error (err); + g_assert_cmpint (nwrote, <=, main_len - main_offset); + + main_offset += nwrote; + if (main_offset == main_len) + { + main_offset = 0; + g_input_stream_read_async (in, main_buf, sizeof (main_buf), + G_PRIORITY_DEFAULT, main_cancel, + main_thread_read, out); + } + else + { + g_output_stream_write_async (out, main_buf + main_offset, + main_len - main_offset, + G_PRIORITY_DEFAULT, main_cancel, + main_thread_wrote, in); + } +} + +static gboolean +timeout (gpointer cancellable) +{ + g_cancellable_cancel (cancellable); + return FALSE; +} + +static void +test_pipe_io (gconstpointer nonblocking) +{ + GThread *writer, *reader; + GInputStream *in; + GOutputStream *out; + + /* Split off two (additional) threads, a reader and a writer. From + * the writer thread, write data synchronously in small chunks, + * which gets alternately read and skipped asynchronously by the + * main thread and then (if not skipped) written asynchronously to + * the reader thread, which reads it synchronously. Eventually a + * timeout in the main thread will cause it to cancel the writer + * thread, which will in turn cancel the read op in the main thread, + * which will then close the pipe to the reader thread, causing the + * read op to fail. + */ + + g_assert (pipe (writer_pipe) == 0 && pipe (reader_pipe) == 0); + + if (nonblocking) + { + GError *error = NULL; + + g_unix_set_fd_nonblocking (writer_pipe[0], TRUE, &error); + g_assert_no_error (error); + g_unix_set_fd_nonblocking (writer_pipe[1], TRUE, &error); + g_assert_no_error (error); + g_unix_set_fd_nonblocking (reader_pipe[0], TRUE, &error); + g_assert_no_error (error); + g_unix_set_fd_nonblocking (reader_pipe[1], TRUE, &error); + g_assert_no_error (error); + } + + writer_cancel = g_cancellable_new (); + reader_cancel = g_cancellable_new (); + main_cancel = g_cancellable_new (); + + writer = g_thread_new ("writer", writer_thread, NULL); + reader = g_thread_new ("reader", reader_thread, NULL); + + in = g_unix_input_stream_new (writer_pipe[0], TRUE); + out = g_unix_output_stream_new (reader_pipe[1], TRUE); + + g_input_stream_read_async (in, main_buf, sizeof (main_buf), + G_PRIORITY_DEFAULT, main_cancel, + main_thread_read, out); + + g_timeout_add (500, timeout, writer_cancel); + + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_thread_join (reader); + g_thread_join (writer); + + g_object_unref (main_cancel); + g_object_unref (reader_cancel); + g_object_unref (writer_cancel); + g_object_unref (in); + g_object_unref (out); +} + +static void +test_basic (void) +{ + GUnixInputStream *is; + GUnixOutputStream *os; + gint fd; + gboolean close_fd; + + is = G_UNIX_INPUT_STREAM (g_unix_input_stream_new (0, TRUE)); + g_object_get (is, + "fd", &fd, + "close-fd", &close_fd, + NULL); + g_assert_cmpint (fd, ==, 0); + g_assert (close_fd); + + g_unix_input_stream_set_close_fd (is, FALSE); + g_assert (!g_unix_input_stream_get_close_fd (is)); + g_assert_cmpint (g_unix_input_stream_get_fd (is), ==, 0); + + g_assert (!g_input_stream_has_pending (G_INPUT_STREAM (is))); + + g_object_unref (is); + + os = G_UNIX_OUTPUT_STREAM (g_unix_output_stream_new (1, TRUE)); + g_object_get (os, + "fd", &fd, + "close-fd", &close_fd, + NULL); + g_assert_cmpint (fd, ==, 1); + g_assert (close_fd); + + g_unix_output_stream_set_close_fd (os, FALSE); + g_assert (!g_unix_output_stream_get_close_fd (os)); + g_assert_cmpint (g_unix_output_stream_get_fd (os), ==, 1); + + g_assert (!g_output_stream_has_pending (G_OUTPUT_STREAM (os))); + + g_object_unref (os); +} + +typedef struct { + GInputStream *is; + GOutputStream *os; + const guint8 *write_data; + guint8 *read_data; +} TestReadWriteData; + +static gpointer +test_read_write_write_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_written; + GError *error = NULL; + gboolean res; + + res = g_output_stream_write_all (data->os, data->write_data, 1024, &bytes_written, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpuint (bytes_written, ==, 1024); + + return NULL; +} + +static gpointer +test_read_write_read_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_read; + GError *error = NULL; + gboolean res; + + res = g_input_stream_read_all (data->is, data->read_data, 1024, &bytes_read, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpuint (bytes_read, ==, 1024); + + return NULL; +} + +static gpointer +test_read_write_writev_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_written; + GError *error = NULL; + gboolean res; + GOutputVector vectors[3]; + + vectors[0].buffer = data->write_data; + vectors[0].size = 256; + vectors[1].buffer = data->write_data + 256; + vectors[1].size = 256; + vectors[2].buffer = data->write_data + 512; + vectors[2].size = 512; + + res = g_output_stream_writev_all (data->os, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpuint (bytes_written, ==, 1024); + + return NULL; +} + +/* test if normal writing/reading from a pipe works */ +static void +test_read_write (gconstpointer user_data) +{ + gboolean writev = GPOINTER_TO_INT (user_data); + GUnixInputStream *is; + GUnixOutputStream *os; + gint fd[2]; + guint8 data_write[1024], data_read[1024]; + guint i; + GThread *write_thread, *read_thread; + TestReadWriteData data; + + for (i = 0; i < sizeof (data_write); i++) + data_write[i] = i; + + g_assert_cmpint (pipe (fd), ==, 0); + + is = G_UNIX_INPUT_STREAM (g_unix_input_stream_new (fd[0], TRUE)); + os = G_UNIX_OUTPUT_STREAM (g_unix_output_stream_new (fd[1], TRUE)); + + data.is = G_INPUT_STREAM (is); + data.os = G_OUTPUT_STREAM (os); + data.read_data = data_read; + data.write_data = data_write; + + if (writev) + write_thread = g_thread_new ("writer", test_read_write_writev_thread, &data); + else + write_thread = g_thread_new ("writer", test_read_write_write_thread, &data); + read_thread = g_thread_new ("reader", test_read_write_read_thread, &data); + + g_thread_join (write_thread); + g_thread_join (read_thread); + + g_assert_cmpmem (data_write, sizeof data_write, data_read, sizeof data_read); + + g_object_unref (os); + g_object_unref (is); +} + +/* test if g_pollable_output_stream_write_nonblocking() and + * g_pollable_output_stream_read_nonblocking() correctly return WOULD_BLOCK + * and correctly reset their status afterwards again, and all data that is + * written can also be read again. + */ +static void +test_write_wouldblock (void) +{ +#ifndef F_GETPIPE_SZ + g_test_skip ("F_GETPIPE_SZ not defined"); +#else /* if F_GETPIPE_SZ */ + GUnixInputStream *is; + GUnixOutputStream *os; + gint fd[2]; + GError *err = NULL; + guint8 data_write[1024], data_read[1024]; + gsize i; + int retval; + gsize pipe_capacity; + + for (i = 0; i < sizeof (data_write); i++) + data_write[i] = i; + + g_assert_cmpint (pipe (fd), ==, 0); + + g_assert_cmpint (fcntl (fd[0], F_SETPIPE_SZ, 4096, NULL), !=, 0); + retval = fcntl (fd[0], F_GETPIPE_SZ); + g_assert_cmpint (retval, >=, 0); + pipe_capacity = (gsize) retval; + g_assert_cmpint (pipe_capacity, >=, 4096); + g_assert_cmpint (pipe_capacity % 1024, >=, 0); + + is = G_UNIX_INPUT_STREAM (g_unix_input_stream_new (fd[0], TRUE)); + os = G_UNIX_OUTPUT_STREAM (g_unix_output_stream_new (fd[1], TRUE)); + + /* Run the whole thing three times to make sure that the streams + * reset the writability/readability state again */ + for (i = 0; i < 3; i++) { + gssize written = 0, written_complete = 0; + gssize read = 0, read_complete = 0; + + do + { + written_complete += written; + written = g_pollable_output_stream_write_nonblocking (G_POLLABLE_OUTPUT_STREAM (os), + data_write, + sizeof (data_write), + NULL, + &err); + } + while (written > 0); + + g_assert_cmpuint (written_complete, >, 0); + g_assert_nonnull (err); + g_assert_error (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_clear_error (&err); + + do + { + read_complete += read; + read = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (is), + data_read, + sizeof (data_read), + NULL, + &err); + if (read > 0) + g_assert_cmpmem (data_read, read, data_write, sizeof (data_write)); + } + while (read > 0); + + g_assert_cmpuint (read_complete, ==, written_complete); + g_assert_nonnull (err); + g_assert_error (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_clear_error (&err); + } + + g_object_unref (os); + g_object_unref (is); +#endif /* if F_GETPIPE_SZ */ +} + +/* test if g_pollable_output_stream_writev_nonblocking() and + * g_pollable_output_stream_read_nonblocking() correctly return WOULD_BLOCK + * and correctly reset their status afterwards again, and all data that is + * written can also be read again. + */ +static void +test_writev_wouldblock (void) +{ +#ifndef F_GETPIPE_SZ + g_test_skip ("F_GETPIPE_SZ not defined"); +#else /* if F_GETPIPE_SZ */ + GUnixInputStream *is; + GUnixOutputStream *os; + gint fd[2]; + GError *err = NULL; + guint8 data_write[1024], data_read[1024]; + gsize i; + int retval; + gsize pipe_capacity; + GOutputVector vectors[4]; + GPollableReturn res; + + for (i = 0; i < sizeof (data_write); i++) + data_write[i] = i; + + g_assert_cmpint (pipe (fd), ==, 0); + + g_assert_cmpint (fcntl (fd[0], F_SETPIPE_SZ, 4096, NULL), !=, 0); + retval = fcntl (fd[0], F_GETPIPE_SZ); + g_assert_cmpint (retval, >=, 0); + pipe_capacity = (gsize) retval; + g_assert_cmpint (pipe_capacity, >=, 4096); + g_assert_cmpint (pipe_capacity % 1024, >=, 0); + + is = G_UNIX_INPUT_STREAM (g_unix_input_stream_new (fd[0], TRUE)); + os = G_UNIX_OUTPUT_STREAM (g_unix_output_stream_new (fd[1], TRUE)); + + /* Run the whole thing three times to make sure that the streams + * reset the writability/readability state again */ + for (i = 0; i < 3; i++) { + gsize written = 0, written_complete = 0; + gssize read = 0, read_complete = 0; + + do + { + written_complete += written; + + vectors[0].buffer = data_write; + vectors[0].size = 256; + vectors[1].buffer = data_write + 256; + vectors[1].size = 256; + vectors[2].buffer = data_write + 512; + vectors[2].size = 256; + vectors[3].buffer = data_write + 768; + vectors[3].size = 256; + + res = g_pollable_output_stream_writev_nonblocking (G_POLLABLE_OUTPUT_STREAM (os), + vectors, + G_N_ELEMENTS (vectors), + &written, + NULL, + &err); + } + while (res == G_POLLABLE_RETURN_OK); + + g_assert_cmpuint (written_complete, >, 0); + g_assert_null (err); + g_assert_cmpint (res, ==, G_POLLABLE_RETURN_WOULD_BLOCK); + /* writev() on UNIX streams either succeeds fully or not at all */ + g_assert_cmpuint (written, ==, 0); + + do + { + read_complete += read; + read = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (is), + data_read, + sizeof (data_read), + NULL, + &err); + if (read > 0) + g_assert_cmpmem (data_read, read, data_write, sizeof (data_write)); + } + while (read > 0); + + g_assert_cmpuint (read_complete, ==, written_complete); + g_assert_nonnull (err); + g_assert_error (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_clear_error (&err); + } + + g_object_unref (os); + g_object_unref (is); +#endif /* if F_GETPIPE_SZ */ +} + +#ifdef F_GETPIPE_SZ +static void +write_async_wouldblock_cb (GUnixOutputStream *os, + GAsyncResult *result, + gpointer user_data) +{ + gsize *bytes_written = user_data; + GError *err = NULL; + + g_output_stream_write_all_finish (G_OUTPUT_STREAM (os), result, bytes_written, &err); + g_assert_no_error (err); +} + +static void +read_async_wouldblock_cb (GUnixInputStream *is, + GAsyncResult *result, + gpointer user_data) +{ + gsize *bytes_read = user_data; + GError *err = NULL; + + g_input_stream_read_all_finish (G_INPUT_STREAM (is), result, bytes_read, &err); + g_assert_no_error (err); +} +#endif /* if F_GETPIPE_SZ */ + +/* test if the async implementation of write_all() and read_all() in G*Stream + * around the GPollable*Stream API is working correctly. + */ +static void +test_write_async_wouldblock (void) +{ +#ifndef F_GETPIPE_SZ + g_test_skip ("F_GETPIPE_SZ not defined"); +#else /* if F_GETPIPE_SZ */ + GUnixInputStream *is; + GUnixOutputStream *os; + gint fd[2]; + guint8 *data, *data_read; + gsize i; + int retval; + gsize pipe_capacity; + gsize bytes_written = 0, bytes_read = 0; + + g_assert_cmpint (pipe (fd), ==, 0); + + /* FIXME: These should not be needed but otherwise + * g_unix_output_stream_write() will block because + * a) the fd is writable + * b) writing 4x capacity will block because writes are atomic + * c) the fd is blocking + * + * See https://gitlab.gnome.org/GNOME/glib/issues/1654 + */ + g_unix_set_fd_nonblocking (fd[0], TRUE, NULL); + g_unix_set_fd_nonblocking (fd[1], TRUE, NULL); + + g_assert_cmpint (fcntl (fd[0], F_SETPIPE_SZ, 4096, NULL), !=, 0); + retval = fcntl (fd[0], F_GETPIPE_SZ); + g_assert_cmpint (retval, >=, 0); + pipe_capacity = (gsize) retval; + g_assert_cmpint (pipe_capacity, >=, 4096); + + data = g_new (guint8, 4 * pipe_capacity); + for (i = 0; i < 4 * pipe_capacity; i++) + data[i] = i; + data_read = g_new (guint8, 4 * pipe_capacity); + + is = G_UNIX_INPUT_STREAM (g_unix_input_stream_new (fd[0], TRUE)); + os = G_UNIX_OUTPUT_STREAM (g_unix_output_stream_new (fd[1], TRUE)); + + g_output_stream_write_all_async (G_OUTPUT_STREAM (os), + data, + 4 * pipe_capacity, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) write_async_wouldblock_cb, + &bytes_written); + + g_input_stream_read_all_async (G_INPUT_STREAM (is), + data_read, + 4 * pipe_capacity, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) read_async_wouldblock_cb, + &bytes_read); + + while (bytes_written == 0 && bytes_read == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (bytes_written, ==, 4 * pipe_capacity); + g_assert_cmpuint (bytes_read, ==, 4 * pipe_capacity); + g_assert_cmpmem (data_read, bytes_read, data, bytes_written); + + g_free (data); + g_free (data_read); + + g_object_unref (os); + g_object_unref (is); +#endif /* if F_GETPIPE_SZ */ +} + +#ifdef F_GETPIPE_SZ +static void +writev_async_wouldblock_cb (GUnixOutputStream *os, + GAsyncResult *result, + gpointer user_data) +{ + gsize *bytes_written = user_data; + GError *err = NULL; + + g_output_stream_writev_all_finish (G_OUTPUT_STREAM (os), result, bytes_written, &err); + g_assert_no_error (err); +} +#endif /* if F_GETPIPE_SZ */ + +/* test if the async implementation of writev_all() and read_all() in G*Stream + * around the GPollable*Stream API is working correctly. + */ +static void +test_writev_async_wouldblock (void) +{ +#ifndef F_GETPIPE_SZ + g_test_skip ("F_GETPIPE_SZ not defined"); +#else /* if F_GETPIPE_SZ */ + GUnixInputStream *is; + GUnixOutputStream *os; + gint fd[2]; + guint8 *data, *data_read; + gsize i; + int retval; + gsize pipe_capacity; + gsize bytes_written = 0, bytes_read = 0; + GOutputVector vectors[4]; + + g_assert_cmpint (pipe (fd), ==, 0); + + /* FIXME: These should not be needed but otherwise + * g_unix_output_stream_writev() will block because + * a) the fd is writable + * b) writing 4x capacity will block because writes are atomic + * c) the fd is blocking + * + * See https://gitlab.gnome.org/GNOME/glib/issues/1654 + */ + g_unix_set_fd_nonblocking (fd[0], TRUE, NULL); + g_unix_set_fd_nonblocking (fd[1], TRUE, NULL); + + g_assert_cmpint (fcntl (fd[0], F_SETPIPE_SZ, 4096, NULL), !=, 0); + retval = fcntl (fd[0], F_GETPIPE_SZ); + g_assert_cmpint (retval, >=, 0); + pipe_capacity = (gsize) retval; + g_assert_cmpint (pipe_capacity, >=, 4096); + + data = g_new (guint8, 4 * pipe_capacity); + for (i = 0; i < 4 * pipe_capacity; i++) + data[i] = i; + data_read = g_new (guint8, 4 * pipe_capacity); + + vectors[0].buffer = data; + vectors[0].size = 1024; + vectors[1].buffer = data + 1024; + vectors[1].size = 1024; + vectors[2].buffer = data + 2048; + vectors[2].size = 1024; + vectors[3].buffer = data + 3072; + vectors[3].size = 4 * pipe_capacity - 3072; + + is = G_UNIX_INPUT_STREAM (g_unix_input_stream_new (fd[0], TRUE)); + os = G_UNIX_OUTPUT_STREAM (g_unix_output_stream_new (fd[1], TRUE)); + + g_output_stream_writev_all_async (G_OUTPUT_STREAM (os), + vectors, + G_N_ELEMENTS (vectors), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) writev_async_wouldblock_cb, + &bytes_written); + + g_input_stream_read_all_async (G_INPUT_STREAM (is), + data_read, + 4 * pipe_capacity, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) read_async_wouldblock_cb, + &bytes_read); + + while (bytes_written == 0 && bytes_read == 0) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (bytes_written, ==, 4 * pipe_capacity); + g_assert_cmpuint (bytes_read, ==, 4 * pipe_capacity); + g_assert_cmpmem (data_read, bytes_read, data, bytes_written); + + g_free (data); + g_free (data_read); + + g_object_unref (os); + g_object_unref (is); +#endif /* F_GETPIPE_SZ */ +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/unix-streams/basic", test_basic); + g_test_add_data_func ("/unix-streams/pipe-io-test", + GINT_TO_POINTER (FALSE), + test_pipe_io); + g_test_add_data_func ("/unix-streams/nonblocking-io-test", + GINT_TO_POINTER (TRUE), + test_pipe_io); + + g_test_add_data_func ("/unix-streams/read_write", + GINT_TO_POINTER (FALSE), + test_read_write); + + g_test_add_data_func ("/unix-streams/read_writev", + GINT_TO_POINTER (TRUE), + test_read_write); + + g_test_add_func ("/unix-streams/write-wouldblock", + test_write_wouldblock); + g_test_add_func ("/unix-streams/writev-wouldblock", + test_writev_wouldblock); + + g_test_add_func ("/unix-streams/write-async-wouldblock", + test_write_async_wouldblock); + g_test_add_func ("/unix-streams/writev-async-wouldblock", + test_writev_async_wouldblock); + + return g_test_run(); +} diff --git a/gio/tests/vfs.c b/gio/tests/vfs.c new file mode 100644 index 0000000..b8a850d --- /dev/null +++ b/gio/tests/vfs.c @@ -0,0 +1,130 @@ + +/* Unit tests for GVfs + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include + +static GFile * +test_vfs_parse_name (GVfs *vfs, + const char *parse_name, + gpointer user_data) +{ + GFile *file = NULL; + + if (g_strcmp0 ((parse_name), "testfile") == 0) + { + file = g_file_new_for_uri ("file:///"); + g_object_set_data (G_OBJECT (file), "testfile", GINT_TO_POINTER (1)); + } + + return file; +} + +static GFile * +test_vfs_lookup (GVfs *vfs, + const char *uri, + gpointer user_data) +{ + GFile *file; + file = g_file_new_for_uri ("file:///"); + g_object_set_data (G_OBJECT (file), "testfile", GINT_TO_POINTER (1)); + + return file; +} + +static void +test_register_scheme (void) +{ + GVfs *vfs; + GFile *file; + const gchar * const *schemes; + gboolean res; + + vfs = g_vfs_get_default (); + g_assert_nonnull (vfs); + g_assert_true (g_vfs_is_active (vfs)); + + schemes = g_vfs_get_supported_uri_schemes (vfs); + g_assert_false (g_strv_contains (schemes, "test")); + + res = g_vfs_unregister_uri_scheme (vfs, "test"); + g_assert_false (res); + + res = g_vfs_register_uri_scheme (vfs, "test", + test_vfs_lookup, NULL, NULL, + test_vfs_parse_name, NULL, NULL); + g_assert_true (res); + + schemes = g_vfs_get_supported_uri_schemes (vfs); + g_assert_true (g_strv_contains (schemes, "test")); + + file = g_file_new_for_uri ("test:///foo"); + g_assert_cmpint (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (file), "testfile")), ==, 1); + g_object_unref (file); + + file = g_file_parse_name ("testfile"); + g_assert_cmpint (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (file), "testfile")), ==, 1); + g_object_unref (file); + + res = g_vfs_register_uri_scheme (vfs, "test", + test_vfs_lookup, NULL, NULL, + test_vfs_parse_name, NULL, NULL); + g_assert_false (res); + + res = g_vfs_unregister_uri_scheme (vfs, "test"); + g_assert_true (res); + + file = g_file_new_for_uri ("test:///foo"); + g_assert_null (g_object_get_data (G_OBJECT (file), "testfile")); + g_object_unref (file); +} + +static void +test_local (void) +{ + GVfs *vfs; + GFile *file; + gchar **schemes; + + vfs = g_vfs_get_local (); + g_assert (g_vfs_is_active (vfs)); + + file = g_vfs_get_file_for_uri (vfs, "not a good uri"); + g_assert (G_IS_FILE (file)); + g_object_unref (file); + + schemes = (gchar **)g_vfs_get_supported_uri_schemes (vfs); + + g_assert (g_strv_length (schemes) > 0); + g_assert_cmpstr (schemes[0], ==, "file"); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gvfs/local", test_local); + g_test_add_func ("/gvfs/register-scheme", test_register_scheme); + + return g_test_run (); +} diff --git a/gio/tests/volumemonitor.c b/gio/tests/volumemonitor.c new file mode 100644 index 0000000..e902eab --- /dev/null +++ b/gio/tests/volumemonitor.c @@ -0,0 +1,180 @@ +#include + +static GVolumeMonitor *monitor; + +static void +do_mount_tests (GDrive *drive, GVolume *volume, GMount *mount) +{ + GDrive *d; + GVolume *v; + gchar *name; + gchar *uuid; + + name = g_mount_get_name (mount); + g_assert (name != NULL); + g_free (name); + + v = g_mount_get_volume (mount); + g_assert (v == volume); + if (v != NULL) + g_object_unref (v); + + d = g_mount_get_drive (mount); + g_assert (d == drive); + if (d != NULL) + g_object_unref (d); + + uuid = g_mount_get_uuid (mount); + if (uuid) + { + GMount *m; + m = g_volume_monitor_get_mount_for_uuid (monitor, uuid); + g_assert (m == mount); + g_object_unref (m); + g_free (uuid); + } +} + +static void +do_volume_tests (GDrive *drive, GVolume *volume) +{ + GDrive *d; + gchar *name; + GMount *mount; + gchar *uuid; + + name = g_volume_get_name (volume); + g_assert (name != NULL); + g_free (name); + + d = g_volume_get_drive (volume); + g_assert (d == drive); + if (d != NULL) + g_object_unref (d); + + mount = g_volume_get_mount (volume); + if (mount != NULL) + { + do_mount_tests (drive, volume, mount); + g_object_unref (mount); + } + + uuid = g_volume_get_uuid (volume); + if (uuid) + { + GVolume *v; + v = g_volume_monitor_get_volume_for_uuid (monitor, uuid); + g_assert (v == volume); + g_object_unref (v); + g_free (uuid); + } +} + +static void +do_drive_tests (GDrive *drive) +{ + GList *volumes, *l; + gchar *name; + gboolean has_volumes; + + g_assert (G_IS_DRIVE (drive)); + name = g_drive_get_name (drive); + g_assert (name != NULL); + g_free (name); + + has_volumes = g_drive_has_volumes (drive); + volumes = g_drive_get_volumes (drive); + g_assert (has_volumes == (volumes != NULL)); + for (l = volumes; l; l = l->next) + { + GVolume *volume = l->data; + do_volume_tests (drive, volume); + } + + g_list_free_full (volumes, g_object_unref); +} + +static void +test_connected_drives (void) +{ + GList *drives; + GList *l; + + drives = g_volume_monitor_get_connected_drives (monitor); + + for (l = drives; l; l = l->next) + { + GDrive *drive = l->data; + do_drive_tests (drive); + } + + g_list_free_full (drives, g_object_unref); +} + +static void +test_volumes (void) +{ + GList *volumes, *l; + + volumes = g_volume_monitor_get_volumes (monitor); + + for (l = volumes; l; l = l->next) + { + GVolume *volume = l->data; + GDrive *drive; + + drive = g_volume_get_drive (volume); + do_volume_tests (drive, volume); + if (drive != NULL) + g_object_unref (drive); + } + + g_list_free_full (volumes, g_object_unref); +} + +static void +test_mounts (void) +{ + GList *mounts, *l; + + mounts = g_volume_monitor_get_mounts (monitor); + + for (l = mounts; l; l = l->next) + { + GMount *mount = l->data; + GVolume *volume; + GDrive *drive; + + drive = g_mount_get_drive (mount); + volume = g_mount_get_volume (mount); + do_mount_tests (drive, volume, mount); + + if (drive != NULL) + g_object_unref (drive); + if (volume != NULL) + g_object_unref (volume); + } + + g_list_free_full (mounts, g_object_unref); +} +int +main (int argc, char *argv[]) +{ + gboolean ret; + + g_setenv ("GIO_USE_VFS", "local", FALSE); + + g_test_init (&argc, &argv, NULL); + + monitor = g_volume_monitor_get (); + + g_test_add_func ("/volumemonitor/connected_drives", test_connected_drives); + g_test_add_func ("/volumemonitor/volumes", test_volumes); + g_test_add_func ("/volumemonitor/mounts", test_mounts); + + ret = g_test_run (); + + g_object_unref (monitor); + + return ret; +} diff --git a/gio/tests/win32-appinfo.c b/gio/tests/win32-appinfo.c new file mode 100644 index 0000000..fa8aa2a --- /dev/null +++ b/gio/tests/win32-appinfo.c @@ -0,0 +1,469 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2019 РуÑлан Ижбулатов + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include + +#include "../giowin32-private.c" + +static int +g_utf16_cmp0 (const gunichar2 *str1, + const gunichar2 *str2) +{ + if (!str1) + return -(str1 != str2); + if (!str2) + return str1 != str2; + + while (TRUE) + { + if (str1[0] > str2[0]) + return 1; + else if (str1[0] < str2[0]) + return -1; + else if (str1[0] == 0 && str2[0] == 0) + return 0; + + str1++; + str2++; + } +} + +#define g_assert_cmputf16(s1, cmp, s2, s1u8, s2u8) \ +G_STMT_START { \ + const gunichar2 *__s1 = (s1), *__s2 = (s2); \ + if (g_utf16_cmp0 (__s1, __s2) cmp 0) ; else \ + g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #s1u8 " " #cmp " " #s2u8, s1u8, #cmp, s2u8); \ +} G_STMT_END + +static void +test_utf16_strfuncs (void) +{ + gsize i; + + struct { + gsize len; + const gunichar2 utf16[10]; + const gchar *utf8; + const gchar *utf8_folded; + } string_cases[] = { + { + 0, + { 0x0000 }, + "", + "", + }, + { + 1, + { 0x0020, 0x0000 }, + " ", + " ", + }, + { + 2, + { 0x0020, 0xd800, 0x0000 }, + NULL, + NULL, + }, + }; + + for (i = 0; i < G_N_ELEMENTS (string_cases); i++) + { + gsize len; + gunichar2 *str; + gboolean success; + gchar *utf8; + gchar *utf8_folded; + + len = g_utf16_len (string_cases[i].utf16); + g_assert_cmpuint (len, ==, string_cases[i].len); + + str = (gunichar2 *) g_utf16_find_basename (string_cases[i].utf16, -1); + /* This only works because all testcases lack separators */ + g_assert_true (string_cases[i].utf16 == str); + + str = g_wcsdup (string_cases[i].utf16, string_cases[i].len); + g_assert_cmpmem (string_cases[i].utf16, len, str, len); + g_free (str); + + str = g_wcsdup (string_cases[i].utf16, -1); + g_assert_cmpmem (string_cases[i].utf16, len, str, len); + g_free (str); + + success = g_utf16_to_utf8_and_fold (string_cases[i].utf16, -1, NULL, NULL); + + if (string_cases[i].utf8 == NULL) + g_assert_false (success); + else + g_assert_true (success); + + utf8 = NULL; + success = g_utf16_to_utf8_and_fold (string_cases[i].utf16, -1, &utf8, NULL); + + if (string_cases[i].utf8 != NULL) + { + g_assert_true (success); + g_assert_cmpstr (string_cases[i].utf8, ==, utf8); + /* This only works because all testcases lack separators */ + g_assert_true (utf8 == g_utf8_find_basename (utf8, len)); + } + + g_free (utf8); + + utf8 = NULL; + utf8_folded = NULL; + success = g_utf16_to_utf8_and_fold (string_cases[i].utf16, -1, &utf8, &utf8_folded); + + if (string_cases[i].utf8 != NULL) + { + g_assert_true (success); + g_assert_cmpstr (string_cases[i].utf8_folded, ==, utf8_folded); + } + + g_free (utf8); + g_free (utf8_folded); + } +} + +struct { + const char *orig; + const char *executable; + const char *executable_basename; + gboolean is_rundll32; + const char *fixed; +} rundll32_commandlines[] = { + { + "%SystemRoot%\\System32\\rundll32.exe \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\", ImageView_Fullscreen %1", + "%SystemRoot%\\System32\\rundll32.exe", + "rundll32.exe", + TRUE, + "%SystemRoot%\\System32\\rundll32.exe \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen %1", + }, + { + "%SystemRoot%/System32/rundll32.exe \"%ProgramFiles%/Windows Photo Viewer/PhotoViewer.dll\", ImageView_Fullscreen %1", + "%SystemRoot%/System32/rundll32.exe", + "rundll32.exe", + TRUE, + "%SystemRoot%/System32/rundll32.exe \"%ProgramFiles%/Windows Photo Viewer/PhotoViewer.dll\" ImageView_Fullscreen %1", + }, + { + "%SystemRoot%\\System32/rundll32.exe \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\", ImageView_Fullscreen %1", + "%SystemRoot%\\System32/rundll32.exe", + "rundll32.exe", + TRUE, + "%SystemRoot%\\System32/rundll32.exe \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen %1", + }, + { + "\"some path with spaces\\rundll32.exe\" \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\", ImageView_Fullscreen %1", + "some path with spaces\\rundll32.exe", + "rundll32.exe", + TRUE, + "\"some path with spaces\\rundll32.exe\" \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen %1", + }, + { + " \"some path with spaces\\rundll32.exe\"\"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\",ImageView_Fullscreen %1", + "some path with spaces\\rundll32.exe", + "rundll32.exe", + TRUE, + " \"some path with spaces\\rundll32.exe\"\"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\" ImageView_Fullscreen %1", + }, + { + "rundll32.exe foo.bar,baz", + "rundll32.exe", + "rundll32.exe", + TRUE, + "rundll32.exe foo.bar baz", + }, + { + " rundll32.exe foo.bar,baz", + "rundll32.exe", + "rundll32.exe", + TRUE, + " rundll32.exe foo.bar baz", + }, + { + "rundll32.exe", + "rundll32.exe", + "rundll32.exe", + FALSE, + NULL, + }, + { + "rundll32.exe ,foobar", + "rundll32.exe", + "rundll32.exe", + FALSE, + NULL, + }, + { + "rundll32.exe ,foobar", + "rundll32.exe", + "rundll32.exe", + FALSE, + NULL, + }, + { + "rundll32.exe foo.dll", + "rundll32.exe", + "rundll32.exe", + FALSE, + NULL, + }, + { + "rundll32.exe \"foo bar\",baz", + "rundll32.exe", + "rundll32.exe", + TRUE, + "rundll32.exe \"foo bar\" baz", + }, + { + "\"rundll32.exe\" \"foo bar\",baz", + "rundll32.exe", + "rundll32.exe", + TRUE, + "\"rundll32.exe\" \"foo bar\" baz", + }, + { + "\"rundll32.exe\" \"foo bar\",, , ,,, , ,,baz", + "rundll32.exe", + "rundll32.exe", + TRUE, + "\"rundll32.exe\" \"foo bar\" , , ,,, , ,,baz", + }, + { + "\"rundll32.exe\" foo.bar,,,,,,,,,baz", + "rundll32.exe", + "rundll32.exe", + TRUE, + "\"rundll32.exe\" foo.bar ,,,,,,,,baz", + }, + { + "\"rundll32.exe\" foo.bar baz", + "rundll32.exe", + "rundll32.exe", + TRUE, + "\"rundll32.exe\" foo.bar baz", + }, + { + "\"RuNdlL32.exe\" foo.bar baz", + "RuNdlL32.exe", + "RuNdlL32.exe", + TRUE, + "\"RuNdlL32.exe\" foo.bar baz", + }, + { + "%SystemRoot%\\System32\\rundll32.exe \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll,\" ImageView_Fullscreen %1", + "%SystemRoot%\\System32\\rundll32.exe", + "rundll32.exe", + TRUE, + "%SystemRoot%\\System32\\rundll32.exe \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll,\" ImageView_Fullscreen %1", + }, + { + "\"rundll32.exe\" \"foo bar,\"baz", + "rundll32.exe", + "rundll32.exe", + TRUE, + "\"rundll32.exe\" \"foo bar,\"baz", + }, + { + "\"rundll32.exe\" some,thing", + "rundll32.exe", + "rundll32.exe", + TRUE, + "\"rundll32.exe\" some thing", + }, + { + "\"rundll32.exe\" some,", + "rundll32.exe", + "rundll32.exe", + FALSE, + "\"rundll32.exe\" some,", + }, + /* These filenames are not allowed on Windows, but our function doesn't care about that */ + { + "run\"dll32.exe foo\".bar,baz", + "run\"dll32.exe", + "run\"dll32.exe", + FALSE, + NULL, + }, + { + "run,dll32.exe foo.bar,baz", + "run,dll32.exe", + "run,dll32.exe", + FALSE, + NULL, + }, + { + "\"rundll32.exe\" some, thing", + "rundll32.exe", + "rundll32.exe", + TRUE, + "\"rundll32.exe\" some thing", + }, + /* Commands with "rundll32" (without the .exe suffix) do exist, + * but GLib currently does not recognize them, so there's no point + * in testing these. + */ +}; + +static void +test_win32_rundll32_fixup (void) +{ + gsize i; + + for (i = 0; i < G_N_ELEMENTS (rundll32_commandlines); i++) + { + gunichar2 *argument; + gunichar2 *expected; + + if (!rundll32_commandlines[i].is_rundll32) + continue; + + argument = g_utf8_to_utf16 (rundll32_commandlines[i].orig, -1, NULL, NULL, NULL); + expected = g_utf8_to_utf16 (rundll32_commandlines[i].fixed, -1, NULL, NULL, NULL); + + g_assert_nonnull (argument); + g_assert_nonnull (expected); + _g_win32_fixup_broken_microsoft_rundll_commandline (argument); + + g_assert_cmputf16 (argument, ==, expected, rundll32_commandlines[i].orig, rundll32_commandlines[i].fixed); + + g_free (argument); + g_free (expected); + } +} + +static void +test_win32_extract_executable (void) +{ + gsize i; + + for (i = 0; i < G_N_ELEMENTS (rundll32_commandlines); i++) + { + gunichar2 *argument; + gchar *dll_function; + gchar *executable; + gchar *executable_basename; + gchar *executable_folded; + gchar *executable_folded_basename; + + argument = g_utf8_to_utf16 (rundll32_commandlines[i].orig, -1, NULL, NULL, NULL); + + _g_win32_extract_executable (argument, NULL, NULL, NULL, NULL, &dll_function); + + if (rundll32_commandlines[i].is_rundll32) + g_assert_nonnull (dll_function); + else + g_assert_null (dll_function); + + g_free (dll_function); + + executable = NULL; + executable_basename = NULL; + executable_folded = NULL; + executable_folded_basename = NULL; + _g_win32_extract_executable (argument, &executable, &executable_basename, &executable_folded, &executable_folded_basename, NULL); + + g_assert_cmpstr (rundll32_commandlines[i].executable, ==, executable); + g_assert_cmpstr (rundll32_commandlines[i].executable_basename, ==, executable_basename); + g_assert_nonnull (executable_folded); + + g_free (executable); + g_free (executable_folded); + + /* Check the corner-case where we don't want to know where basename is */ + executable = NULL; + executable_folded = NULL; + _g_win32_extract_executable (argument, &executable, NULL, &executable_folded, NULL, NULL); + + g_assert_cmpstr (rundll32_commandlines[i].executable, ==, executable); + g_assert_nonnull (executable_folded); + + g_free (executable); + g_free (executable_folded); + + g_free (argument); + } +} + +static void +test_win32_parse_filename (void) +{ + gsize i; + + for (i = 0; i < G_N_ELEMENTS (rundll32_commandlines); i++) + { + gunichar2 *argument; + argument = g_utf8_to_utf16 (rundll32_commandlines[i].orig, -1, NULL, NULL, NULL); + /* Just checking that it doesn't blow up on various (sometimes incorrect) strings */ + _g_win32_parse_filename (argument, FALSE, NULL, NULL, NULL, NULL); + g_free (argument); + } +} + +static void +do_fail_on_broken_utf16_1 (void) +{ + const gunichar2 utf16[] = { 0xd800, 0x0000 }; + _g_win32_extract_executable (utf16, NULL, NULL, NULL, NULL, NULL); +} + +static void +do_fail_on_broken_utf16_2 (void) +{ + /* "rundll32.exe r" */ + gchar *dll_function; + const gunichar2 utf16[] = { 0x0072, 0x0075, 0x006E, 0x0064, 0x006C, 0x006C, 0x0033, 0x0032, + 0x002E, 0x0065, 0x0078, 0x0065, 0x0020, 0xd800, 0x0020, 0x0072, 0x0000 }; + _g_win32_extract_executable (utf16, NULL, NULL, NULL, NULL, &dll_function); +} + +static void +test_fail_on_broken_utf16 (void) +{ + g_test_trap_subprocess ("/appinfo/subprocess/win32-assert-broken-utf16_1", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib-GIO:ERROR:*giowin32-private.c:*:_g_win32_extract_executable: assertion failed: (folded)*"); + g_test_trap_subprocess ("/appinfo/subprocess/win32-assert-broken-utf16_2", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib-GIO:ERROR:*giowin32-private.c:*:_g_win32_extract_executable: assertion failed: (folded)*"); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/appinfo/utf16-strfuncs", test_utf16_strfuncs); + g_test_add_func ("/appinfo/win32-extract-executable", test_win32_extract_executable); + g_test_add_func ("/appinfo/win32-rundll32-fixup", test_win32_rundll32_fixup); + g_test_add_func ("/appinfo/win32-parse-filename", test_win32_parse_filename); + g_test_add_func ("/appinfo/win32-utf16-conversion-fail", test_fail_on_broken_utf16); + + g_test_add_func ("/appinfo/subprocess/win32-assert-broken-utf16_1", do_fail_on_broken_utf16_1); + g_test_add_func ("/appinfo/subprocess/win32-assert-broken-utf16_2", do_fail_on_broken_utf16_2); + + return g_test_run (); +} diff --git a/gio/tests/win32-streams.c b/gio/tests/win32-streams.c new file mode 100644 index 0000000..6451a9f --- /dev/null +++ b/gio/tests/win32-streams.c @@ -0,0 +1,535 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Red Hat, Inc + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DATA "abcdefghijklmnopqrstuvwxyz" + +int writer_pipe[2], reader_pipe[2]; +GCancellable *writer_cancel, *reader_cancel, *main_cancel; +GMainLoop *loop; + +static gpointer +writer_thread (gpointer user_data) +{ + GOutputStream *out; + gssize nwrote, offset; + GError *err = NULL; + HANDLE out_handle; + + g_assert (DuplicateHandle (GetCurrentProcess (), + (HANDLE) (gintptr) _get_osfhandle (writer_pipe[1]), + GetCurrentProcess (), + &out_handle, + 0, FALSE, + DUPLICATE_SAME_ACCESS)); + close (writer_pipe[1]); + + out = g_win32_output_stream_new (out_handle, TRUE); + do + { + g_usleep (10); + + offset = 0; + while (offset < (gssize) sizeof (DATA)) + { + nwrote = g_output_stream_write (out, DATA + offset, + sizeof (DATA) - offset, + writer_cancel, &err); + if (nwrote <= 0 || err != NULL) + break; + offset += nwrote; + } + + g_assert (nwrote > 0 || err != NULL); + } + while (err == NULL); + + if (g_cancellable_is_cancelled (writer_cancel)) + { + g_cancellable_cancel (main_cancel); + g_object_unref (out); + return NULL; + } + + g_warning ("writer: %s", err->message); + g_assert_not_reached (); +} + +static gpointer +reader_thread (gpointer user_data) +{ + GInputStream *in; + gssize nread = 0, total; + GError *err = NULL; + char buf[sizeof (DATA)]; + HANDLE in_handle; + + g_assert (DuplicateHandle (GetCurrentProcess (), + (HANDLE) (gintptr) _get_osfhandle (reader_pipe[0]), + GetCurrentProcess (), + &in_handle, + 0, FALSE, + DUPLICATE_SAME_ACCESS)); + close (reader_pipe[0]); + + in = g_win32_input_stream_new (in_handle, TRUE); + + do + { + total = 0; + while (total < (gssize) sizeof (DATA)) + { + nread = g_input_stream_read (in, buf + total, sizeof (buf) - total, + reader_cancel, &err); + if (nread <= 0 || err != NULL) + break; + total += nread; + } + + if (err) + break; + + if (nread == 0) + { + g_assert (err == NULL); + /* pipe closed */ + g_object_unref (in); + return NULL; + } + + g_assert_cmpstr (buf, ==, DATA); + g_assert (!g_cancellable_is_cancelled (reader_cancel)); + } + while (err == NULL); + + g_warning ("reader: %s", err->message); + g_assert_not_reached (); +} + +char main_buf[sizeof (DATA)]; +gssize main_len, main_offset; + +static void readable (GObject *source, GAsyncResult *res, gpointer user_data); +static void writable (GObject *source, GAsyncResult *res, gpointer user_data); + +static void +do_main_cancel (GOutputStream *out) +{ + g_output_stream_close (out, NULL, NULL); + g_main_loop_quit (loop); +} + +static void +readable (GObject *source, GAsyncResult *res, gpointer user_data) +{ + GInputStream *in = G_INPUT_STREAM (source); + GOutputStream *out = user_data; + GError *err = NULL; + + main_len = g_input_stream_read_finish (in, res, &err); + + if (g_cancellable_is_cancelled (main_cancel)) + { + do_main_cancel (out); + return; + } + + g_assert (err == NULL); + + main_offset = 0; + g_output_stream_write_async (out, main_buf, main_len, + G_PRIORITY_DEFAULT, main_cancel, + writable, in); +} + +static void +writable (GObject *source, GAsyncResult *res, gpointer user_data) +{ + GOutputStream *out = G_OUTPUT_STREAM (source); + GInputStream *in = user_data; + GError *err = NULL; + gssize nwrote; + + nwrote = g_output_stream_write_finish (out, res, &err); + + if (g_cancellable_is_cancelled (main_cancel)) + { + do_main_cancel (out); + return; + } + + g_assert (err == NULL); + g_assert_cmpint (nwrote, <=, main_len - main_offset); + + main_offset += nwrote; + if (main_offset == main_len) + { + g_input_stream_read_async (in, main_buf, sizeof (main_buf), + G_PRIORITY_DEFAULT, main_cancel, + readable, out); + } + else + { + g_output_stream_write_async (out, main_buf + main_offset, + main_len - main_offset, + G_PRIORITY_DEFAULT, main_cancel, + writable, in); + } +} + +static gboolean +timeout (gpointer cancellable) +{ + g_cancellable_cancel (cancellable); + return FALSE; +} + +static void +test_pipe_io (void) +{ + GThread *writer, *reader; + GInputStream *in; + GOutputStream *out; + HANDLE in_handle, out_handle; + + /* Split off two (additional) threads, a reader and a writer. From + * the writer thread, write data synchronously in small chunks, + * which gets read asynchronously by the main thread and then + * written asynchronously to the reader thread, which reads it + * synchronously. Eventually a timeout in the main thread will cause + * it to cancel the writer thread, which will in turn cancel the + * read op in the main thread, which will then close the pipe to + * the reader thread, causing the read op to fail. + */ + + g_assert (_pipe (writer_pipe, 10, _O_BINARY) == 0 && _pipe (reader_pipe, 10, _O_BINARY) == 0); + + writer_cancel = g_cancellable_new (); + reader_cancel = g_cancellable_new (); + main_cancel = g_cancellable_new (); + + writer = g_thread_new ("writer", writer_thread, NULL); + reader = g_thread_new ("reader", reader_thread, NULL); + + g_assert (DuplicateHandle (GetCurrentProcess (), + (HANDLE) (gintptr) _get_osfhandle (writer_pipe[0]), + GetCurrentProcess (), + &in_handle, + 0, FALSE, + DUPLICATE_SAME_ACCESS)); + close (writer_pipe[0]); + + g_assert (DuplicateHandle (GetCurrentProcess (), + (HANDLE) (gintptr) _get_osfhandle (reader_pipe[1]), + GetCurrentProcess (), + &out_handle, + 0, FALSE, + DUPLICATE_SAME_ACCESS)); + close (reader_pipe[1]); + + in = g_win32_input_stream_new (in_handle, TRUE); + out = g_win32_output_stream_new (out_handle, TRUE); + + g_input_stream_read_async (in, main_buf, sizeof (main_buf), + G_PRIORITY_DEFAULT, main_cancel, + readable, out); + + g_timeout_add (500, timeout, writer_cancel); + + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_thread_join (reader); + g_thread_join (writer); + + g_object_unref (main_cancel); + g_object_unref (reader_cancel); + g_object_unref (writer_cancel); + g_object_unref (in); + g_object_unref (out); +} + +typedef struct _PipeIOOverlapReader +{ + char buf[sizeof (DATA)]; + GInputStream *in; + GThread *thread; + GCancellable *cancellable; + gboolean success; +} PipeIOOverlapReader; + +#define TEST_PIPE_IO_OVERLAP (1024 * 4) + +static gpointer +pipe_io_overlap_reader_thread (gpointer user_data) +{ + PipeIOOverlapReader *p = user_data; + GError *err = NULL; + gsize read; + guint i; + + for (i = 0; i < TEST_PIPE_IO_OVERLAP; ++i) { + memset (p->buf, 0, sizeof (p->buf)); + g_input_stream_read_all (p->in, p->buf, sizeof (p->buf), + &read, NULL, &err); + + g_assert_cmpuint (read, ==, sizeof (p->buf)); + g_assert_no_error (err); + g_assert_cmpstr (p->buf, ==, DATA); + } + + return NULL; +} + +static gpointer +pipe_io_overlap_writer_thread (gpointer user_data) +{ + GOutputStream *out = user_data; + GError *err = NULL; + gsize bytes_written; + guint i; + + for (i = 0; i < TEST_PIPE_IO_OVERLAP; ++i) { + g_output_stream_write_all (out, DATA, sizeof (DATA), + &bytes_written, NULL, &err); + + g_assert_cmpuint (bytes_written, ==, sizeof (DATA)); + g_assert_no_error (err); + } + + return NULL; +} + +static void +test_pipe_io_overlap (void) +{ + GOutputStream *out_server, *out_client; + GThread *writer_server, *writer_client; + PipeIOOverlapReader rs, rc; + HANDLE server, client; + gchar name[256]; + + g_snprintf (name, sizeof (name), + "\\\\.\\pipe\\gtest-io-overlap-%u", (guint) GetCurrentProcessId ()); + + server = CreateNamedPipe (name, + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_READMODE_BYTE | PIPE_WAIT, + 1, 0, 0, 0, NULL); + g_assert (server != INVALID_HANDLE_VALUE); + + client = CreateFile (name, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + g_assert (client != INVALID_HANDLE_VALUE); + + out_server = g_win32_output_stream_new (server, TRUE); + writer_server = g_thread_new ("writer_server", pipe_io_overlap_writer_thread, out_server); + rs.in = g_win32_input_stream_new (server, TRUE); + rs.thread = g_thread_new ("reader_server", pipe_io_overlap_reader_thread, &rs); + + out_client = g_win32_output_stream_new (client, TRUE); + writer_client = g_thread_new ("writer_client", pipe_io_overlap_writer_thread, out_client); + rc.in = g_win32_input_stream_new (client, TRUE); + rc.thread = g_thread_new ("reader_client", pipe_io_overlap_reader_thread, &rc); + + g_thread_join (writer_client); + g_thread_join (writer_server); + g_thread_join (rc.thread); + g_thread_join (rs.thread); + + g_object_unref (rs.in); + g_object_unref (rc.in); + g_object_unref (out_server); + g_object_unref (out_client); +} + +static gpointer +pipe_io_concurrent_writer_thread (gpointer user_data) +{ + GOutputStream *out = user_data; + GError *err = NULL; + gsize bytes_written; + + g_output_stream_write_all (out, DATA, 1, &bytes_written, NULL, &err); + + g_assert_cmpuint (bytes_written, ==, 1); + g_assert_no_error (err); + + return NULL; +} + +static gpointer +pipe_io_concurrent_reader_thread (gpointer user_data) +{ + PipeIOOverlapReader *p = user_data; + GError *err = NULL; + gsize read; + + memset (p->buf, 0, sizeof (p->buf)); + p->success = g_input_stream_read_all (p->in, p->buf, 1, &read, p->cancellable, &err); + + /* only one thread will succeed, the other will be cancelled */ + if (p->success) + { + /* continue the main thread */ + write (writer_pipe[1], "", 1); + g_assert_cmpuint (read, ==, 1); + g_assert_no_error (err); + } + + return NULL; +} + +static void +test_pipe_io_concurrent (void) +{ + GOutputStream *out_server; + GThread *writer_server; + PipeIOOverlapReader rc1, rc2; + HANDLE server, client; + gchar name[256], c; + + g_snprintf (name, sizeof (name), + "\\\\.\\pipe\\gtest-io-concurrent-%u", (guint) GetCurrentProcessId ()); + + server = CreateNamedPipe (name, + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_READMODE_BYTE | PIPE_WAIT, + 1, 0, 0, 0, NULL); + g_assert (server != INVALID_HANDLE_VALUE); + g_assert (_pipe (writer_pipe, 10, _O_BINARY) == 0); + + client = CreateFile (name, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + g_assert (client != INVALID_HANDLE_VALUE); + + rc1.in = g_win32_input_stream_new (client, TRUE); + rc1.success = FALSE; + rc1.cancellable = g_cancellable_new (); + rc1.thread = g_thread_new ("reader_client", pipe_io_concurrent_reader_thread, &rc1); + + rc2.in = g_win32_input_stream_new (client, TRUE); + rc2.success = FALSE; + rc2.cancellable = g_cancellable_new (); + rc2.thread = g_thread_new ("reader_client", pipe_io_concurrent_reader_thread, &rc2); + + /* FIXME: how to synchronize on both reader thread waiting in read, + before starting the writer thread? */ + g_usleep (G_USEC_PER_SEC / 10); + + out_server = g_win32_output_stream_new (server, TRUE); + writer_server = g_thread_new ("writer_server", pipe_io_concurrent_writer_thread, out_server); + + read (writer_pipe[0], &c, 1); + + g_assert (rc1.success ^ rc2.success); + + g_cancellable_cancel (rc1.cancellable); + g_cancellable_cancel (rc2.cancellable); + + g_thread_join (writer_server); + g_thread_join (rc1.thread); + g_thread_join (rc2.thread); + + g_object_unref (rc1.in); + g_object_unref (rc2.in); + g_object_unref (out_server); + + close (writer_pipe[0]); + close (writer_pipe[1]); +} + +static void +readable_cancel (GObject *source, GAsyncResult *res, gpointer user_data) +{ + GInputStream *in = G_INPUT_STREAM (source); + GError *err = NULL; + gssize len; + + len = g_input_stream_read_finish (in, res, &err); + g_assert_cmpint (len, ==, -1); + g_assert_error (err, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_error_free (err); + + g_main_loop_quit (loop); +} + +static void +test_pipe_io_cancel (void) +{ + GInputStream *in; + GOutputStream *out; + HANDLE in_handle, out_handle; + gchar name[256]; + + g_snprintf (name, sizeof (name), + "\\\\.\\pipe\\gtest-io-cancel-%u", (guint) GetCurrentProcessId ()); + + in_handle = CreateNamedPipe (name, + PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_READMODE_BYTE | PIPE_WAIT, + 1, 0, 0, 0, NULL); + g_assert (in_handle != INVALID_HANDLE_VALUE); + + out_handle = CreateFile (name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + g_assert (out_handle != INVALID_HANDLE_VALUE); + + in = g_win32_input_stream_new (in_handle, TRUE); + out = g_win32_output_stream_new (out_handle, TRUE); + + reader_cancel = g_cancellable_new (); + g_input_stream_read_async (in, main_buf, sizeof (main_buf), + G_PRIORITY_DEFAULT, reader_cancel, + readable_cancel, out); + + g_timeout_add (500, timeout, reader_cancel); + + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_object_unref (reader_cancel); + g_object_unref (in); + g_object_unref (out); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/win32-streams/pipe-io-test", test_pipe_io); + g_test_add_func ("/win32-streams/pipe-io-cancel-test", test_pipe_io_cancel); + g_test_add_func ("/win32-streams/pipe-io-overlap-test", test_pipe_io_overlap); + g_test_add_func ("/win32-streams/pipe-io-concurrent-test", test_pipe_io_concurrent); + + return g_test_run(); +} diff --git a/gio/tests/x-content/image-dcf/DCIM/Camera/20130831_203925.jpg b/gio/tests/x-content/image-dcf/DCIM/Camera/20130831_203925.jpg new file mode 100644 index 0000000..e69de29 diff --git a/gio/tests/x-content/image-dcf/DCIM/Camera/20130831_203928.jpg b/gio/tests/x-content/image-dcf/DCIM/Camera/20130831_203928.jpg new file mode 100644 index 0000000..e69de29 diff --git a/gio/tests/x-content/unix-software/autorun.sh b/gio/tests/x-content/unix-software/autorun.sh new file mode 100644 index 0000000..ef09a62 --- /dev/null +++ b/gio/tests/x-content/unix-software/autorun.sh @@ -0,0 +1,3 @@ +#! /bin/sh + +# do something here diff --git a/gio/tests/x-content/win32-software/autorun.exe b/gio/tests/x-content/win32-software/autorun.exe new file mode 100755 index 0000000..e69de29 diff --git a/gio/thumbnail-verify.c b/gio/thumbnail-verify.c new file mode 100644 index 0000000..316e8a6 --- /dev/null +++ b/gio/thumbnail-verify.c @@ -0,0 +1,252 @@ +/* Copyright © 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "thumbnail-verify.h" + +#include + +/* Begin code to check the validity of thumbnail files. In order to do + * that we need to parse enough PNG in order to get the Thumb::URI, + * Thumb::MTime and Thumb::Size tags out of the file. Fortunately this + * is relatively easy. + */ +typedef struct +{ + const gchar *uri; + guint64 mtime; + guint64 size; +} ExpectedInfo; + +/* We *require* matches on URI and MTime, but the Size field is optional + * (as per the spec). + * + * http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html + */ +#define MATCHED_URI (1u << 0) +#define MATCHED_MTIME (1u << 1) +#define MATCHED_ALL (MATCHED_URI | MATCHED_MTIME) + +static gboolean +check_integer_match (guint64 expected, + const gchar *value, + guint32 value_size) +{ + /* Would be nice to g_ascii_strtoll here, but we don't have a variant + * that works on strings that are not nul-terminated. + * + * It's easy enough to do it ourselves... + */ + if (expected == 0) /* special case: "0" */ + return value_size == 1 && value[0] == '0'; + + /* Check each digit, as long as we have data from both */ + while (expected && value_size) + { + /* Check the low-order digit */ + if (value[value_size - 1] != (gchar) ((expected % 10) + '0')) + return FALSE; + + /* Move on... */ + expected /= 10; + value_size--; + } + + /* Make sure nothing is left over, on either side */ + return !expected && !value_size; +} + +static gboolean +check_png_info_chunk (ExpectedInfo *expected_info, + const gchar *key, + guint32 key_size, + const gchar *value, + guint32 value_size, + guint *required_matches) +{ + if (key_size == 10 && memcmp (key, "Thumb::URI", 10) == 0) + { + gsize expected_size; + + expected_size = strlen (expected_info->uri); + + if (expected_size != value_size) + return FALSE; + + if (memcmp (expected_info->uri, value, value_size) != 0) + return FALSE; + + *required_matches |= MATCHED_URI; + } + + else if (key_size == 12 && memcmp (key, "Thumb::MTime", 12) == 0) + { + if (!check_integer_match (expected_info->mtime, value, value_size)) + return FALSE; + + *required_matches |= MATCHED_MTIME; + } + + else if (key_size == 11 && memcmp (key, "Thumb::Size", 11) == 0) + { + /* A match on Thumb::Size is not required for success, but if we + * find this optional field and it's wrong, we should reject the + * thumbnail. + */ + if (!check_integer_match (expected_info->size, value, value_size)) + return FALSE; + } + + return TRUE; +} + +static gboolean +check_thumbnail_validity (ExpectedInfo *expected_info, + const gchar *contents, + gsize size) +{ + guint required_matches = 0; + + /* Reference: http://www.w3.org/TR/PNG/ */ + if (size < 8) + return FALSE; + + if (memcmp (contents, "\x89PNG\r\n\x1a\n", 8) != 0) + return FALSE; + + contents += 8, size -= 8; + + /* We need at least 12 bytes to have a chunk... */ + while (size >= 12) + { + guint32 chunk_size_be; + guint32 chunk_size; + + /* PNG is not an aligned file format so we have to be careful + * about reading integers... + */ + memcpy (&chunk_size_be, contents, 4); + chunk_size = GUINT32_FROM_BE (chunk_size_be); + + contents += 4, size -= 4; + + /* After consuming the size field, we need to have enough bytes + * for 4 bytes type field, chunk_size bytes for data, then 4 byte + * for CRC (which we ignore) + * + * We just read chunk_size from the file, so it may be very large. + * Make sure it won't wrap when we add 8 to it. + */ + if (G_MAXUINT32 - chunk_size < 8 || size < chunk_size + 8) + goto out; + + /* We are only interested in tEXt fields */ + if (memcmp (contents, "tEXt", 4) == 0) + { + const gchar *key = contents + 4; + guint32 key_size; + + /* We need to find the nul separator character that splits the + * key/value. The value is not terminated. + * + * If we find no nul then we just ignore the field. + * + * value may contain extra nuls, but check_png_info_chunk() + * can handle that. + */ + for (key_size = 0; key_size < chunk_size; key_size++) + { + if (key[key_size] == '\0') + { + const gchar *value; + guint32 value_size; + + /* Since key_size < chunk_size, value_size is + * definitely non-negative. + */ + value_size = chunk_size - key_size - 1; + value = key + key_size + 1; + + /* We found the separator character. */ + if (!check_png_info_chunk (expected_info, + key, key_size, + value, value_size, + &required_matches)) + return FALSE; + } + } + } + else + { + /* A bit of a hack: assume that all tEXt chunks will appear + * together. Therefore, if we have already seen both required + * fields and then see a non-tEXt chunk then we can assume we + * are done. + * + * The common case is that the tEXt chunks come at the start + * of the file before any of the image data. This trick means + * that we will only fault in a single page (4k) whereas many + * thumbnails (particularly the large ones) can approach 100k + * in size. + */ + if (required_matches == MATCHED_ALL) + goto out; + } + + /* skip to the next chunk, ignoring CRC. */ + contents += 4, size -= 4; /* type field */ + contents += chunk_size, size -= chunk_size; /* data */ + contents += 4, size -= 4; /* CRC */ + } + +out: + return required_matches == MATCHED_ALL; +} + +gboolean +thumbnail_verify (const char *thumbnail_path, + const gchar *file_uri, + const GLocalFileStat *file_stat_buf) +{ + gboolean thumbnail_is_valid = FALSE; + ExpectedInfo expected_info; + GMappedFile *file; + + if (file_stat_buf == NULL) + return FALSE; + + expected_info.uri = file_uri; +#ifdef G_OS_WIN32 + expected_info.mtime = (guint64) file_stat_buf->st_mtim.tv_sec; +#else + expected_info.mtime = _g_stat_mtime (file_stat_buf); +#endif + expected_info.size = _g_stat_size (file_stat_buf); + + file = g_mapped_file_new (thumbnail_path, FALSE, NULL); + if (file) + { + thumbnail_is_valid = check_thumbnail_validity (&expected_info, + g_mapped_file_get_contents (file), + g_mapped_file_get_length (file)); + g_mapped_file_unref (file); + } + + return thumbnail_is_valid; +} diff --git a/gio/thumbnail-verify.h b/gio/thumbnail-verify.h new file mode 100644 index 0000000..e406809 --- /dev/null +++ b/gio/thumbnail-verify.h @@ -0,0 +1,30 @@ +/* Copyright © 2013 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef _thumbnail_verify_h_ +#define _thumbnail_verify_h_ + +#include +#include +#include "glocalfileinfo.h" + +gboolean thumbnail_verify (const gchar *thumbnail_path, + const gchar *file_uri, + const GLocalFileStat *file_stat_buf); + +#endif /* _thumbnail_verify_h_ */ diff --git a/gio/win32/gwin32filemonitor.c b/gio/win32/gwin32filemonitor.c new file mode 100644 index 0000000..8383570 --- /dev/null +++ b/gio/win32/gwin32filemonitor.c @@ -0,0 +1,104 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Vlad Grecescu + * Author: Chun-wei Fan + * + */ + +#include "config.h" + +#include "gwin32filemonitor.h" +#include "gwin32fsmonitorutils.h" + +#include + +G_DEFINE_TYPE_WITH_CODE (GWin32FileMonitor, g_win32_file_monitor, G_TYPE_LOCAL_FILE_MONITOR, + g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, + g_define_type_id, "win32filemonitor", 20)) + +static void +g_win32_file_monitor_start (GLocalFileMonitor *monitor, + const gchar *dirname, + const gchar *basename, + const gchar *filename, + GFileMonitorSource *source) +{ + GWin32FileMonitor *win32_monitor = G_WIN32_FILE_MONITOR (monitor); + + win32_monitor->priv->fms = source; + + if (filename == NULL && basename == NULL) + g_win32_fs_monitor_init (win32_monitor->priv, dirname, NULL, FALSE); + else if (basename != NULL) + g_win32_fs_monitor_init (win32_monitor->priv, dirname, basename, TRUE); + else + g_win32_fs_monitor_init (win32_monitor->priv, NULL, filename, TRUE); +} + +static gboolean +g_win32_file_monitor_is_supported (void) +{ + return TRUE; +} + +static void +g_win32_file_monitor_init (GWin32FileMonitor *monitor) +{ + monitor->priv = g_win32_fs_monitor_create (TRUE); + + monitor->priv->self = G_FILE_MONITOR (monitor); +} + +static void +g_win32_file_monitor_finalize (GObject *object) +{ + GWin32FileMonitor *monitor; + + monitor = G_WIN32_FILE_MONITOR (object); + + g_win32_fs_monitor_finalize (monitor->priv); + + G_OBJECT_CLASS (g_win32_file_monitor_parent_class)->finalize (object); +} + +static gboolean +g_win32_file_monitor_cancel (GFileMonitor* monitor) +{ + GWin32FileMonitor *file_monitor; + + file_monitor = G_WIN32_FILE_MONITOR (monitor); + + g_win32_fs_monitor_close_handle (file_monitor->priv); + + return TRUE; +} + +static void +g_win32_file_monitor_class_init (GWin32FileMonitorClass *klass) +{ + GObjectClass* gobject_class = G_OBJECT_CLASS (klass); + GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass); + GLocalFileMonitorClass *local_file_monitor_class = G_LOCAL_FILE_MONITOR_CLASS (klass); + + gobject_class->finalize = g_win32_file_monitor_finalize; + file_monitor_class->cancel = g_win32_file_monitor_cancel; + + local_file_monitor_class->is_supported = g_win32_file_monitor_is_supported; + local_file_monitor_class->start = g_win32_file_monitor_start; +} diff --git a/gio/win32/gwin32filemonitor.h b/gio/win32/gwin32filemonitor.h new file mode 100644 index 0000000..132bd24 --- /dev/null +++ b/gio/win32/gwin32filemonitor.h @@ -0,0 +1,62 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Chun-wei Fan + * + */ +#ifndef __G_WIN32_FILE_MONITOR_H__ +#define __G_WIN32_FILE_MONITOR_H__ + +#include +#include +#include +#include +#include + +#include "gio/gfilemonitor.h" +#include "gio/glocalfilemonitor.h" +#include "gio/giomodule.h" + +#include "gwin32fsmonitorutils.h" + +G_BEGIN_DECLS + +#define G_TYPE_WIN32_FILE_MONITOR (g_win32_file_monitor_get_type ()) +#define G_WIN32_FILE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_WIN32_FILE_MONITOR, GWin32FileMonitor)) +#define G_WIN32_FILE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_WIN32_FILE_MONITOR, GWin32FileMonitorClass)) +#define G_IS_WIN32_FILE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_WIN32_FILE_MONITOR)) +#define G_IS_WIN32_FILE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_WIN32_FILE_MONITOR)) +#define G_WIN32_FILE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_WIN32_FILE_MONITOR, GWin32FileMonitorClass)) + +typedef struct _GWin32FileMonitor GWin32FileMonitor; +typedef struct _GWin32FileMonitorClass GWin32FileMonitorClass; +typedef struct _GWin32FileMonitorPrivate GWin32FileMonitorPrivate; + +struct _GWin32FileMonitor { + GLocalFileMonitor parent_instance; + GWin32FSMonitorPrivate * priv; +}; +struct _GWin32FileMonitorClass { + GLocalFileMonitorClass parent_class; +}; + +GType g_win32_file_monitor_get_type (void); +void g_win32_file_monitor_register (GIOModule *module); + +G_END_DECLS + +#endif /* __G_WIN32_FILE_MONITOR_H__ */ diff --git a/gio/win32/gwin32fsmonitorutils.c b/gio/win32/gwin32fsmonitorutils.c new file mode 100644 index 0000000..f2ab547 --- /dev/null +++ b/gio/win32/gwin32fsmonitorutils.c @@ -0,0 +1,425 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2015 Chun-wei Fan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Vlad Grecescu + * Author: Chun-wei Fan + * + */ + +#include "config.h" + +#include "gwin32fsmonitorutils.h" +#include "gio/gfile.h" + +#include + +#define MAX_PATH_LONG 32767 /* Support Paths longer than MAX_PATH (260) characters */ + +static gboolean +g_win32_fs_monitor_handle_event (GWin32FSMonitorPrivate *monitor, + const gchar *filename, + PFILE_NOTIFY_INFORMATION pfni) +{ + GFileMonitorEvent fme; + PFILE_NOTIFY_INFORMATION pfni_next; + WIN32_FILE_ATTRIBUTE_DATA attrib_data = {0, }; + gchar *renamed_file = NULL; + + switch (pfni->Action) + { + case FILE_ACTION_ADDED: + fme = G_FILE_MONITOR_EVENT_CREATED; + break; + + case FILE_ACTION_REMOVED: + fme = G_FILE_MONITOR_EVENT_DELETED; + break; + + case FILE_ACTION_MODIFIED: + { + gboolean success_attribs = GetFileAttributesExW (monitor->wfullpath_with_long_prefix, + GetFileExInfoStandard, + &attrib_data); + + if (monitor->file_attribs != INVALID_FILE_ATTRIBUTES && + success_attribs && + attrib_data.dwFileAttributes != monitor->file_attribs) + fme = G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED; + else + fme = G_FILE_MONITOR_EVENT_CHANGED; + + monitor->file_attribs = attrib_data.dwFileAttributes; + } + break; + + case FILE_ACTION_RENAMED_OLD_NAME: + if (pfni->NextEntryOffset != 0) + { + /* If the file was renamed in the same directory, we would get a + * FILE_ACTION_RENAMED_NEW_NAME action in the next FILE_NOTIFY_INFORMATION + * structure. + */ + glong file_name_len = 0; + + pfni_next = (PFILE_NOTIFY_INFORMATION) ((BYTE*)pfni + pfni->NextEntryOffset); + renamed_file = g_utf16_to_utf8 (pfni_next->FileName, pfni_next->FileNameLength / sizeof(WCHAR), NULL, &file_name_len, NULL); + if (pfni_next->Action == FILE_ACTION_RENAMED_NEW_NAME) + fme = G_FILE_MONITOR_EVENT_RENAMED; + else + fme = G_FILE_MONITOR_EVENT_MOVED_OUT; + } + else + fme = G_FILE_MONITOR_EVENT_MOVED_OUT; + break; + + case FILE_ACTION_RENAMED_NEW_NAME: + if (monitor->pfni_prev != NULL && + monitor->pfni_prev->Action == FILE_ACTION_RENAMED_OLD_NAME) + { + /* don't bother sending events, was already sent (rename) */ + fme = (GFileMonitorEvent) -1; + } + else + fme = G_FILE_MONITOR_EVENT_MOVED_IN; + break; + + default: + /* The possible Windows actions are all above, so shouldn't get here */ + g_assert_not_reached (); + break; + } + + if (fme != (GFileMonitorEvent) -1) + return g_file_monitor_source_handle_event (monitor->fms, + fme, + filename, + renamed_file, + NULL, + g_get_monotonic_time ()); + else + return FALSE; +} + + +static void CALLBACK +g_win32_fs_monitor_callback (DWORD error, + DWORD nBytes, + LPOVERLAPPED lpOverlapped) +{ + gulong offset; + PFILE_NOTIFY_INFORMATION pfile_notify_walker; + GWin32FSMonitorPrivate *monitor = (GWin32FSMonitorPrivate *) lpOverlapped; + + DWORD notify_filter = monitor->isfile ? + (FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE) : + (FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE); + + /* If monitor->self is NULL the GWin32FileMonitor object has been destroyed. */ + if (monitor->self == NULL || + g_file_monitor_is_cancelled (monitor->self) || + monitor->file_notify_buffer == NULL) + { + g_free (monitor->file_notify_buffer); + g_free (monitor); + return; + } + + offset = 0; + + do + { + pfile_notify_walker = (PFILE_NOTIFY_INFORMATION)((BYTE *)monitor->file_notify_buffer + offset); + if (pfile_notify_walker->Action > 0) + { + glong file_name_len; + gchar *changed_file; + + changed_file = g_utf16_to_utf8 (pfile_notify_walker->FileName, + pfile_notify_walker->FileNameLength / sizeof(WCHAR), + NULL, &file_name_len, NULL); + + if (monitor->isfile) + { + gint long_filename_length = wcslen (monitor->wfilename_long); + gint short_filename_length = wcslen (monitor->wfilename_short); + enum GWin32FileMonitorFileAlias alias_state; + + /* If monitoring a file, check that the changed file + * in the directory matches the file that is to be monitored + * We need to check both the long and short file names for the same file. + * + * We need to send in the name of the monitored file, not its long (or short) variant, + * if they exist. + */ + + if (_wcsnicmp (pfile_notify_walker->FileName, + monitor->wfilename_long, + long_filename_length) == 0) + { + if (_wcsnicmp (pfile_notify_walker->FileName, + monitor->wfilename_short, + short_filename_length) == 0) + { + alias_state = G_WIN32_FILE_MONITOR_NO_ALIAS; + } + else + alias_state = G_WIN32_FILE_MONITOR_LONG_FILENAME; + } + else if (_wcsnicmp (pfile_notify_walker->FileName, + monitor->wfilename_short, + short_filename_length) == 0) + { + alias_state = G_WIN32_FILE_MONITOR_SHORT_FILENAME; + } + else + alias_state = G_WIN32_FILE_MONITOR_NO_MATCH_FOUND; + + if (alias_state != G_WIN32_FILE_MONITOR_NO_MATCH_FOUND) + { + wchar_t *monitored_file_w; + gchar *monitored_file; + + switch (alias_state) + { + case G_WIN32_FILE_MONITOR_NO_ALIAS: + monitored_file = g_strdup (changed_file); + break; + case G_WIN32_FILE_MONITOR_LONG_FILENAME: + case G_WIN32_FILE_MONITOR_SHORT_FILENAME: + monitored_file_w = wcsrchr (monitor->wfullpath_with_long_prefix, L'\\'); + monitored_file = g_utf16_to_utf8 (monitored_file_w + 1, -1, NULL, NULL, NULL); + break; + default: + g_assert_not_reached (); + break; + } + + g_win32_fs_monitor_handle_event (monitor, monitored_file, pfile_notify_walker); + g_free (monitored_file); + } + } + else + g_win32_fs_monitor_handle_event (monitor, changed_file, pfile_notify_walker); + + g_free (changed_file); + } + + monitor->pfni_prev = pfile_notify_walker; + offset += pfile_notify_walker->NextEntryOffset; + } + while (pfile_notify_walker->NextEntryOffset); + + ReadDirectoryChangesW (monitor->hDirectory, + monitor->file_notify_buffer, + monitor->buffer_allocated_bytes, + FALSE, + notify_filter, + &monitor->buffer_filled_bytes, + &monitor->overlapped, + g_win32_fs_monitor_callback); +} + +void +g_win32_fs_monitor_init (GWin32FSMonitorPrivate *monitor, + const gchar *dirname, + const gchar *filename, + gboolean isfile) +{ + wchar_t *wdirname_with_long_prefix = NULL; + const gchar LONGPFX[] = "\\\\?\\"; + gchar *fullpath_with_long_prefix, *dirname_with_long_prefix; + DWORD notify_filter = isfile ? + (FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE) : + (FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE); + + gboolean success_attribs; + WIN32_FILE_ATTRIBUTE_DATA attrib_data = {0, }; + + + if (dirname != NULL) + { + dirname_with_long_prefix = g_strconcat (LONGPFX, dirname, NULL); + wdirname_with_long_prefix = g_utf8_to_utf16 (dirname_with_long_prefix, -1, NULL, NULL, NULL); + + if (isfile) + { + gchar *fullpath; + wchar_t wlongname[MAX_PATH_LONG]; + wchar_t wshortname[MAX_PATH_LONG]; + wchar_t *wfullpath, *wbasename_long, *wbasename_short; + + fullpath = g_build_filename (dirname, filename, NULL); + fullpath_with_long_prefix = g_strconcat (LONGPFX, fullpath, NULL); + + wfullpath = g_utf8_to_utf16 (fullpath, -1, NULL, NULL, NULL); + + monitor->wfullpath_with_long_prefix = + g_utf8_to_utf16 (fullpath_with_long_prefix, -1, NULL, NULL, NULL); + + /* ReadDirectoryChangesW() can return the normal filename or the + * "8.3" format filename, so we need to keep track of both these names + * so that we can check against them later when it returns + */ + if (GetLongPathNameW (monitor->wfullpath_with_long_prefix, wlongname, MAX_PATH_LONG) == 0) + { + wbasename_long = wcsrchr (monitor->wfullpath_with_long_prefix, L'\\'); + monitor->wfilename_long = wbasename_long != NULL ? + wcsdup (wbasename_long + 1) : + wcsdup (wfullpath); + } + else + { + wbasename_long = wcsrchr (wlongname, L'\\'); + monitor->wfilename_long = wbasename_long != NULL ? + wcsdup (wbasename_long + 1) : + wcsdup (wlongname); + + } + + if (GetShortPathNameW (monitor->wfullpath_with_long_prefix, wshortname, MAX_PATH_LONG) == 0) + { + wbasename_short = wcsrchr (monitor->wfullpath_with_long_prefix, L'\\'); + monitor->wfilename_short = wbasename_short != NULL ? + wcsdup (wbasename_short + 1) : + wcsdup (wfullpath); + } + else + { + wbasename_short = wcsrchr (wshortname, L'\\'); + monitor->wfilename_short = wbasename_short != NULL ? + wcsdup (wbasename_short + 1) : + wcsdup (wshortname); + } + + g_free (fullpath); + } + else + { + monitor->wfilename_short = NULL; + monitor->wfilename_long = NULL; + monitor->wfullpath_with_long_prefix = g_utf8_to_utf16 (dirname_with_long_prefix, -1, NULL, NULL, NULL); + } + + monitor->isfile = isfile; + } + else + { + dirname_with_long_prefix = g_strconcat (LONGPFX, filename, NULL); + monitor->wfullpath_with_long_prefix = g_utf8_to_utf16 (dirname_with_long_prefix, -1, NULL, NULL, NULL); + monitor->wfilename_long = NULL; + monitor->wfilename_short = NULL; + monitor->isfile = FALSE; + } + + success_attribs = GetFileAttributesExW (monitor->wfullpath_with_long_prefix, + GetFileExInfoStandard, + &attrib_data); + if (success_attribs) + monitor->file_attribs = attrib_data.dwFileAttributes; /* Store up original attributes */ + else + monitor->file_attribs = INVALID_FILE_ATTRIBUTES; + monitor->pfni_prev = NULL; + monitor->hDirectory = CreateFileW (wdirname_with_long_prefix != NULL ? wdirname_with_long_prefix : monitor->wfullpath_with_long_prefix, + FILE_LIST_DIRECTORY, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, + NULL); + + g_free (wdirname_with_long_prefix); + g_free (dirname_with_long_prefix); + + if (monitor->hDirectory != INVALID_HANDLE_VALUE) + { + ReadDirectoryChangesW (monitor->hDirectory, + monitor->file_notify_buffer, + monitor->buffer_allocated_bytes, + FALSE, + notify_filter, + &monitor->buffer_filled_bytes, + &monitor->overlapped, + g_win32_fs_monitor_callback); + } +} + +GWin32FSMonitorPrivate * +g_win32_fs_monitor_create (gboolean isfile) +{ + GWin32FSMonitorPrivate *monitor = g_new0 (GWin32FSMonitorPrivate, 1); + + monitor->buffer_allocated_bytes = 32784; + monitor->file_notify_buffer = g_new0 (FILE_NOTIFY_INFORMATION, monitor->buffer_allocated_bytes); + + return monitor; +} + +void +g_win32_fs_monitor_finalize (GWin32FSMonitorPrivate *monitor) +{ + g_free (monitor->wfullpath_with_long_prefix); + g_free (monitor->wfilename_long); + g_free (monitor->wfilename_short); + + if (monitor->hDirectory == INVALID_HANDLE_VALUE) + { + /* If we don't have a directory handle we can free + * monitor->file_notify_buffer and monitor here. The + * callback won't be called obviously any more (and presumably + * never has been called). + */ + g_free (monitor->file_notify_buffer); + monitor->file_notify_buffer = NULL; + g_free (monitor); + } + else + { + /* If we have a directory handle, the OVERLAPPED struct is + * passed once more to the callback as a result of the + * CloseHandle() done in the cancel method, so monitor has to + * be kept around. The GWin32DirectoryMonitor object is + * disappearing, so can't leave a pointer to it in + * monitor->self. + */ + monitor->self = NULL; + } +} + +void +g_win32_fs_monitor_close_handle (GWin32FSMonitorPrivate *monitor) +{ + /* This triggers a last callback() with nBytes==0. */ + + /* Actually I am not so sure about that, it seems to trigger a last + * callback correctly, but the way to recognize that it is the final + * one is not to check for nBytes==0, I think that was a + * misunderstanding. + */ + if (monitor->hDirectory != INVALID_HANDLE_VALUE) + CloseHandle (monitor->hDirectory); +} diff --git a/gio/win32/gwin32fsmonitorutils.h b/gio/win32/gwin32fsmonitorutils.h new file mode 100644 index 0000000..b42507f --- /dev/null +++ b/gio/win32/gwin32fsmonitorutils.h @@ -0,0 +1,76 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2014 Chun-wei Fan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Vlad Grecescu + * Author: Chun-wei Fan + * + */ + +#ifndef __G_WIN32_FS_MONITOR_UTILS_H__ +#define __G_WIN32_FS_MONITOR_UTILS_H__ + +#include + +#include "gio/glocalfilemonitor.h" + +#include "gio/gfilemonitor.h" + +G_BEGIN_DECLS + +typedef struct _GWin32FSMonitorPrivate GWin32FSMonitorPrivate; + +struct _GWin32FSMonitorPrivate +{ + OVERLAPPED overlapped; + DWORD buffer_allocated_bytes; + PFILE_NOTIFY_INFORMATION file_notify_buffer; + DWORD buffer_filled_bytes; + HANDLE hDirectory; + gboolean isfile; + wchar_t *wfullpath_with_long_prefix; + wchar_t *wfilename_short; + wchar_t *wfilename_long; + DWORD file_attribs; + PFILE_NOTIFY_INFORMATION pfni_prev; + /* Needed in the APC where we only have this private struct */ + GFileMonitor *self; + GFileMonitorSource *fms; +}; + +enum GWin32FileMonitorFileAlias +{ + G_WIN32_FILE_MONITOR_NO_ALIAS = 0, + G_WIN32_FILE_MONITOR_LONG_FILENAME, + G_WIN32_FILE_MONITOR_SHORT_FILENAME, + G_WIN32_FILE_MONITOR_NO_MATCH_FOUND +}; + +GWin32FSMonitorPrivate* g_win32_fs_monitor_create (gboolean isfile); + +void g_win32_fs_monitor_init (GWin32FSMonitorPrivate *monitor, + const gchar *dirname, + const gchar *filename, + gboolean isfile); + +void g_win32_fs_monitor_finalize (GWin32FSMonitorPrivate *monitor); + +void g_win32_fs_monitor_close_handle (GWin32FSMonitorPrivate *monitor); + +G_END_DECLS + +#endif diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c new file mode 100644 index 0000000..e73c876 --- /dev/null +++ b/gio/win32/gwinhttpfile.c @@ -0,0 +1,788 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#include "config.h" + +#include +#include +#include + +#include "gio/gfile.h" +#include "gio/gfileattribute.h" +#include "gio/gfileinfo.h" +#include "gio/gfileinfo-priv.h" +#include "gwinhttpfile.h" +#include "gwinhttpfileinputstream.h" +#include "gwinhttpfileoutputstream.h" +#include "gio/gioerror.h" + +#include "glibintl.h" + +static void g_winhttp_file_file_iface_init (GFileIface *iface); + +#define g_winhttp_file_get_type _g_winhttp_file_get_type +G_DEFINE_TYPE_WITH_CODE (GWinHttpFile, g_winhttp_file, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_FILE, + g_winhttp_file_file_iface_init)) + +static void +g_winhttp_file_finalize (GObject *object) +{ + GWinHttpFile *file; + + file = G_WINHTTP_FILE (object); + + g_free (file->url.lpszScheme); + g_free (file->url.lpszHostName); + g_free (file->url.lpszUserName); + g_free (file->url.lpszPassword); + g_free (file->url.lpszUrlPath); + g_free (file->url.lpszExtraInfo); + + g_object_unref (file->vfs); + + G_OBJECT_CLASS (g_winhttp_file_parent_class)->finalize (object); +} + +static void +g_winhttp_file_class_init (GWinHttpFileClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_winhttp_file_finalize; +} + +static void +g_winhttp_file_init (GWinHttpFile *winhttp) +{ +} + +/* + * _g_winhttp_file_new: + * @vfs: GWinHttpVfs to use + * @uri: URI of the GWinHttpFile to create. + * + * Returns: (nullable): new winhttp #GFile, or %NULL if there was an error constructing it. + */ +GFile * +_g_winhttp_file_new (GWinHttpVfs *vfs, + const char *uri) +{ + wchar_t *wuri; + GWinHttpFile *file; + + wuri = g_utf8_to_utf16 (uri, -1, NULL, NULL, NULL); + + if (wuri == NULL) + return NULL; + + file = g_object_new (G_TYPE_WINHTTP_FILE, NULL); + file->vfs = g_object_ref (vfs); + + memset (&file->url, 0, sizeof (file->url)); + file->url.dwStructSize = sizeof (file->url); + file->url.dwSchemeLength = 1; + file->url.dwHostNameLength = 1; + file->url.dwUserNameLength = 1; + file->url.dwPasswordLength = 1; + file->url.dwUrlPathLength = 1; + file->url.dwExtraInfoLength = 1; + + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCrackUrl (wuri, 0, 0, &file->url)) + { + g_free (wuri); + return NULL; + } + + file->url.lpszScheme = g_new (wchar_t, ++file->url.dwSchemeLength); + file->url.lpszHostName = g_new (wchar_t, ++file->url.dwHostNameLength); + file->url.lpszUserName = g_new (wchar_t, ++file->url.dwUserNameLength); + file->url.lpszPassword = g_new (wchar_t, ++file->url.dwPasswordLength); + file->url.lpszUrlPath = g_new (wchar_t, ++file->url.dwUrlPathLength); + file->url.lpszExtraInfo = g_new (wchar_t, ++file->url.dwExtraInfoLength); + + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCrackUrl (wuri, 0, 0, &file->url)) + { + g_free (file->url.lpszScheme); + g_free (file->url.lpszHostName); + g_free (file->url.lpszUserName); + g_free (file->url.lpszPassword); + g_free (file->url.lpszUrlPath); + g_free (file->url.lpszExtraInfo); + g_free (wuri); + return NULL; + } + + g_free (wuri); + return G_FILE (file); +} + +static gboolean +g_winhttp_file_is_native (GFile *file) +{ + return FALSE; +} + +static gboolean +g_winhttp_file_has_uri_scheme (GFile *file, + const char *uri_scheme) +{ + return (g_ascii_strcasecmp (uri_scheme, "http") == 0 || + g_ascii_strcasecmp (uri_scheme, "https") == 0); +} + +static char * +g_winhttp_file_get_uri_scheme (GFile *file) +{ + GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); + + return g_utf16_to_utf8 (winhttp_file->url.lpszScheme, -1, NULL, NULL, NULL); +} + +static char * +g_winhttp_file_get_basename (GFile *file) +{ + GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); + char *basename; + char *last_slash; + char *retval; + + basename = g_utf16_to_utf8 (winhttp_file->url.lpszUrlPath, -1, NULL, NULL, NULL); + last_slash = strrchr (basename, '/'); + /* If no slash, or only "/" fallback to full path part of URI */ + if (last_slash == NULL || last_slash[1] == '\0') + return basename; + + retval = g_strdup (last_slash + 1); + g_free (basename); + + return retval; +} + +static char * +g_winhttp_file_get_display_name (GFile *file) +{ + char *basename; + + /* FIXME: This could be improved by using a new g_utf16_make_valid() function + * to recover what we can from the URI, and then suffixing it with + * “ (invalid encoding)†as per g_filename_display_basename(). */ + basename = g_winhttp_file_get_basename (file); + if (!basename) + return g_strdup (_(" (invalid encoding)")); + + return g_steal_pointer (&basename); +} + +static char * +g_winhttp_file_get_path (GFile *file) +{ + return NULL; +} + +static char * +g_winhttp_file_get_uri (GFile *file) +{ + GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); + DWORD len; + wchar_t *wuri; + char *retval; + + len = 0; + if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, NULL, &len) && + GetLastError () != ERROR_INSUFFICIENT_BUFFER) + return NULL; + + wuri = g_new (wchar_t, ++len); + + if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, wuri, &len)) + { + g_free (wuri); + return NULL; + } + + retval = g_utf16_to_utf8 (wuri, -1, NULL, NULL, NULL); + g_free (wuri); + + if (g_str_has_prefix (retval, "http://:@")) + { + memmove (retval + 7, retval + 9, strlen (retval) - 9); + retval[strlen (retval) - 2] = '\0'; + } + else if (g_str_has_prefix (retval, "https://:@")) + { + memmove (retval + 8, retval + 10, strlen (retval) - 10); + retval[strlen (retval) - 2] = '\0'; + } + + return retval; +} + +static char * +g_winhttp_file_get_parse_name (GFile *file) +{ + /* FIXME: More hair surely needed */ + + return g_winhttp_file_get_uri (file); +} + +static GFile * +g_winhttp_file_get_parent (GFile *file) +{ + GWinHttpFile *winhttp_file; + char *uri; + char *last_slash; + GFile *parent; + + winhttp_file = G_WINHTTP_FILE (file); + + uri = g_winhttp_file_get_uri (file); + if (uri == NULL) + return NULL; + + last_slash = strrchr (uri, '/'); + if (last_slash == NULL || *(last_slash+1) == 0) + { + g_free (uri); + return NULL; + } + + while (last_slash > uri && *last_slash == '/') + last_slash--; + + last_slash[1] = '\0'; + + parent = _g_winhttp_file_new (winhttp_file->vfs, uri); + g_free (uri); + + return parent; +} + +static GFile * +g_winhttp_file_dup (GFile *file) +{ + GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); + char *uri = g_winhttp_file_get_uri (file); + GFile *retval = _g_winhttp_file_new (winhttp_file->vfs, uri); + + g_free (uri); + + return retval; +} + +static guint +g_winhttp_file_hash (GFile *file) +{ + char *uri = g_winhttp_file_get_uri (file); + guint retval = g_str_hash (uri); + + g_free (uri); + + return retval; +} + +static gboolean +g_winhttp_file_equal (GFile *file1, + GFile *file2) +{ + char *uri1 = g_winhttp_file_get_uri (file1); + char *uri2 = g_winhttp_file_get_uri (file2); + gboolean retval = g_str_equal (uri1, uri2); + + g_free (uri1); + g_free (uri2); + + return retval; +} + +static const char * +match_prefix (const char *path, + const char *prefix) +{ + int prefix_len; + + prefix_len = strlen (prefix); + if (strncmp (path, prefix, prefix_len) != 0) + return NULL; + + if (prefix_len > 0 && prefix[prefix_len-1] == '/') + prefix_len--; + + return path + prefix_len; +} + +static gboolean +g_winhttp_file_prefix_matches (GFile *parent, + GFile *descendant) +{ + char *parent_uri = g_winhttp_file_get_uri (parent); + char *descendant_uri = g_winhttp_file_get_uri (descendant); + const char *remainder; + gboolean retval; + + remainder = match_prefix (descendant_uri, parent_uri); + + if (remainder != NULL && *remainder == '/') + retval = TRUE; + else + retval = FALSE; + + g_free (parent_uri); + g_free (descendant_uri); + + return retval; +} + +static char * +g_winhttp_file_get_relative_path (GFile *parent, + GFile *descendant) +{ + char *parent_uri = g_winhttp_file_get_uri (parent); + char *descendant_uri = g_winhttp_file_get_uri (descendant); + const char *remainder; + char *retval; + + remainder = match_prefix (descendant_uri, parent_uri); + + if (remainder != NULL && *remainder == '/') + retval = g_strdup (remainder + 1); + else + retval = NULL; + + g_free (parent_uri); + g_free (descendant_uri); + + return retval; +} + +static GFile * +g_winhttp_file_resolve_relative_path (GFile *file, + const char *relative_path) +{ + GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); + GWinHttpFile *child; + wchar_t *wnew_path = g_utf8_to_utf16 (relative_path, -1, NULL, NULL, NULL); + + if (wnew_path == NULL) + return NULL; + + if (*wnew_path != '/') + { + wchar_t *tmp = NULL; + int trailing_slash = winhttp_file->url.lpszUrlPath[winhttp_file->url.dwUrlPathLength-1] == L'/'? 1 : 0; + if (trailing_slash) + { + tmp = g_new (wchar_t, wcslen (winhttp_file->url.lpszUrlPath) + wcslen (wnew_path) + 1); + wcscpy (tmp, winhttp_file->url.lpszUrlPath); + } + else + { + tmp = g_new (wchar_t, wcslen (winhttp_file->url.lpszUrlPath) + 1 + wcslen (wnew_path) + 1); + wcscpy (tmp, winhttp_file->url.lpszUrlPath); + wcscat (tmp, L"/"); + } + wcscat (tmp, wnew_path); + + g_free (wnew_path); + wnew_path = tmp; + } + + child = g_object_new (G_TYPE_WINHTTP_FILE, NULL); + child->vfs = winhttp_file->vfs; + child->url = winhttp_file->url; + child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, ((gsize) winhttp_file->url.dwSchemeLength + 1) * 2); + child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, ((gsize) winhttp_file->url.dwHostNameLength + 1) * 2); + child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, ((gsize) winhttp_file->url.dwUserNameLength + 1) * 2); + child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, ((gsize) winhttp_file->url.dwPasswordLength + 1) * 2); + child->url.lpszUrlPath = wnew_path; + child->url.dwUrlPathLength = wcslen (wnew_path); + child->url.lpszExtraInfo = NULL; + child->url.dwExtraInfoLength = 0; + + return (GFile *) child; +} + +static GFile * +g_winhttp_file_get_child_for_display_name (GFile *file, + const char *display_name, + GError **error) +{ + GFile *new_file; + char *basename; + + basename = g_locale_from_utf8 (display_name, -1, NULL, NULL, NULL); + if (basename == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, + _("Invalid filename %s"), display_name); + return NULL; + } + + new_file = g_file_get_child (file, basename); + g_free (basename); + + return new_file; +} + +static GFile * +g_winhttp_file_set_display_name (GFile *file, + const char *display_name, + GCancellable *cancellable, + GError **error) +{ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported")); + + return NULL; +} + +static GFileInfo * +g_winhttp_file_query_info (GFile *file, + const char *attributes, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error) +{ + GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); + HINTERNET connection, request; + const wchar_t *accept_types[] = + { + L"*/*", + NULL, + }; + GFileInfo *info; + GFileAttributeMatcher *matcher; + char *basename; + wchar_t *content_length; + wchar_t *content_type; + SYSTEMTIME last_modified; + DWORD last_modified_len; + + connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect + (G_WINHTTP_VFS (winhttp_file->vfs)->session, + winhttp_file->url.lpszHostName, + winhttp_file->url.nPort, + 0); + + if (connection == NULL) + { + _g_winhttp_set_error (error, GetLastError (), "HTTP connection"); + + return NULL; + } + + request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpOpenRequest + (connection, + L"HEAD", + winhttp_file->url.lpszUrlPath, + NULL, + WINHTTP_NO_REFERER, + accept_types, + winhttp_file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0); + + if (request == NULL) + { + _g_winhttp_set_error (error, GetLastError (), "HEAD request"); + + return NULL; + } + + if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpSendRequest + (request, + NULL, 0, + NULL, 0, + 0, + 0)) + { + _g_winhttp_set_error (error, GetLastError (), "HEAD request"); + + return NULL; + } + + if (!_g_winhttp_response (winhttp_file->vfs, request, error, "HEAD request")) + return NULL; + + matcher = g_file_attribute_matcher_new (attributes); + info = g_file_info_new (); + g_file_info_set_attribute_mask (info, matcher); + + basename = g_winhttp_file_get_basename (file); + g_file_info_set_name (info, basename); + g_free (basename); + + if (_g_file_attribute_matcher_matches_id (matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_DISPLAY_NAME)) + { + char *display_name = g_winhttp_file_get_display_name (file); + g_file_info_set_display_name (info, display_name); + g_free (display_name); + } + + content_length = NULL; + if (_g_winhttp_query_header (winhttp_file->vfs, + request, + "HEAD request", + WINHTTP_QUERY_CONTENT_LENGTH, + &content_length, + NULL)) + { + gint64 cl; + size_t n; + const char *gint64_format = "%"G_GINT64_FORMAT"%n"; + wchar_t *gint64_format_w = g_utf8_to_utf16 (gint64_format, -1, NULL, NULL, NULL); + + if (swscanf (content_length, gint64_format_w, &cl, &n) == 1 && + n == wcslen (content_length)) + g_file_info_set_size (info, cl); + + g_free (content_length); + g_free (gint64_format_w); + } + + if (matcher == NULL) + return info; + + content_type = NULL; + if (_g_winhttp_query_header (winhttp_file->vfs, + request, + "HEAD request", + WINHTTP_QUERY_CONTENT_TYPE, + &content_type, + NULL)) + { + char *ct = g_utf16_to_utf8 (content_type, -1, NULL, NULL, NULL); + + if (ct != NULL) + { + char *p = strchr (ct, ';'); + + if (p != NULL) + { + char *tmp = g_strndup (ct, p - ct); + + g_file_info_set_content_type (info, tmp); + g_free (tmp); + } + else + g_file_info_set_content_type (info, ct); + } + + g_free (ct); + } + + last_modified_len = sizeof (last_modified); + if (G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpQueryHeaders + (request, + WINHTTP_QUERY_LAST_MODIFIED | WINHTTP_QUERY_FLAG_SYSTEMTIME, + NULL, + &last_modified, + &last_modified_len, + NULL) && + last_modified_len == sizeof (last_modified) && + /* Don't bother comparing to the exact Y2038 moment */ + last_modified.wYear >= 1970 && + last_modified.wYear < 2038) + { + GDateTime *dt = NULL, *dt2 = NULL; + + dt = g_date_time_new_from_unix_utc (last_modified.wMilliseconds / 1000); + dt2 = g_date_time_add_seconds (dt, (last_modified.wMilliseconds % 1000) / 1000); + + g_file_info_set_modification_date_time (info, dt2); + + g_date_time_unref (dt2); + g_date_time_unref (dt); + } + + g_file_attribute_matcher_unref (matcher); + + return info; +} + +static GFileInputStream * +g_winhttp_file_read (GFile *file, + GCancellable *cancellable, + GError **error) +{ + GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); + HINTERNET connection, request; + const wchar_t *accept_types[] = + { + L"*/*", + NULL, + }; + + connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect + (G_WINHTTP_VFS (winhttp_file->vfs)->session, + winhttp_file->url.lpszHostName, + winhttp_file->url.nPort, + 0); + + if (connection == NULL) + { + _g_winhttp_set_error (error, GetLastError (), "HTTP connection"); + + return NULL; + } + + request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpOpenRequest + (connection, + L"GET", + winhttp_file->url.lpszUrlPath, + NULL, + WINHTTP_NO_REFERER, + accept_types, + winhttp_file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0); + + if (request == NULL) + { + _g_winhttp_set_error (error, GetLastError (), "GET request"); + + return NULL; + } + + return _g_winhttp_file_input_stream_new (winhttp_file, connection, request); +} + +static GFileOutputStream * +g_winhttp_file_create (GFile *file, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); + HINTERNET connection; + + connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpConnect + (G_WINHTTP_VFS (winhttp_file->vfs)->session, + winhttp_file->url.lpszHostName, + winhttp_file->url.nPort, + 0); + + if (connection == NULL) + { + _g_winhttp_set_error (error, GetLastError (), "HTTP connection"); + + return NULL; + } + + return _g_winhttp_file_output_stream_new (winhttp_file, connection); +} + +#if 0 + +static GFileOutputStream * +g_winhttp_file_replace (GFile *file, + const char *etag, + gboolean make_backup, + GFileCreateFlags flags, + GCancellable *cancellable, + GError **error) +{ + /* FIXME: Implement */ + + return NULL; +} + + +static gboolean +g_winhttp_file_delete (GFile *file, + GCancellable *cancellable, + GError **error) +{ + /* FIXME: Implement */ + + return FALSE; +} + +static gboolean +g_winhttp_file_make_directory (GFile *file, + GCancellable *cancellable, + GError **error) +{ + /* FIXME: Implement */ + + return FALSE; +} + +static gboolean +g_winhttp_file_copy (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + /* Fall back to default copy?? */ + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Copy not supported"); + + return FALSE; +} + +static gboolean +g_winhttp_file_move (GFile *source, + GFile *destination, + GFileCopyFlags flags, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GError **error) +{ + /* FIXME: Implement */ + + return FALSE; +} + +#endif + +static void +g_winhttp_file_file_iface_init (GFileIface *iface) +{ + iface->dup = g_winhttp_file_dup; + iface->hash = g_winhttp_file_hash; + iface->equal = g_winhttp_file_equal; + iface->is_native = g_winhttp_file_is_native; + iface->has_uri_scheme = g_winhttp_file_has_uri_scheme; + iface->get_uri_scheme = g_winhttp_file_get_uri_scheme; + iface->get_basename = g_winhttp_file_get_basename; + iface->get_path = g_winhttp_file_get_path; + iface->get_uri = g_winhttp_file_get_uri; + iface->get_parse_name = g_winhttp_file_get_parse_name; + iface->get_parent = g_winhttp_file_get_parent; + iface->prefix_matches = g_winhttp_file_prefix_matches; + iface->get_relative_path = g_winhttp_file_get_relative_path; + iface->resolve_relative_path = g_winhttp_file_resolve_relative_path; + iface->get_child_for_display_name = g_winhttp_file_get_child_for_display_name; + iface->set_display_name = g_winhttp_file_set_display_name; + iface->query_info = g_winhttp_file_query_info; + iface->read_fn = g_winhttp_file_read; + iface->create = g_winhttp_file_create; +#if 0 + iface->replace = g_winhttp_file_replace; + iface->delete_file = g_winhttp_file_delete; + iface->make_directory = g_winhttp_file_make_directory; + iface->copy = g_winhttp_file_copy; + iface->move = g_winhttp_file_move; +#endif +} diff --git a/gio/win32/gwinhttpfile.h b/gio/win32/gwinhttpfile.h new file mode 100644 index 0000000..69b9d15 --- /dev/null +++ b/gio/win32/gwinhttpfile.h @@ -0,0 +1,62 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#ifndef __G_WINHTTP_FILE_H__ +#define __G_WINHTTP_FILE_H__ + +#include + +#include "gwinhttpvfs.h" + +G_BEGIN_DECLS + +#define G_TYPE_WINHTTP_FILE (_g_winhttp_file_get_type ()) +#define G_WINHTTP_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WINHTTP_FILE, GWinHttpFile)) +#define G_WINHTTP_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WINHTTP_FILE, GWinHttpFileClass)) +#define G_IS_WINHTTP_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WINHTTP_FILE)) +#define G_IS_WINHTTP_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WINHTTP_FILE)) +#define G_WINHTTP_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WINHTTP_FILE, GWinHttpFileClass)) + +typedef struct _GWinHttpFile GWinHttpFile; +typedef struct _GWinHttpFileClass GWinHttpFileClass; + +struct _GWinHttpFile +{ + GObject parent_instance; + + GWinHttpVfs *vfs; + + URL_COMPONENTS url; +}; + +struct _GWinHttpFileClass +{ + GObjectClass parent_class; +}; + +GType _g_winhttp_file_get_type (void) G_GNUC_CONST; + +GFile * _g_winhttp_file_new (GWinHttpVfs *vfs, const char *uri); + +G_END_DECLS + +#endif /* __G_WINHTTP_FILE_H__ */ diff --git a/gio/win32/gwinhttpfileinputstream.c b/gio/win32/gwinhttpfileinputstream.c new file mode 100644 index 0000000..871274e --- /dev/null +++ b/gio/win32/gwinhttpfileinputstream.c @@ -0,0 +1,175 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#include "config.h" + +#include + +#include "gio/gcancellable.h" +#include "gio/gioerror.h" +#include "gwinhttpfileinputstream.h" +#include "glibintl.h" + +struct _GWinHttpFileInputStream +{ + GFileInputStream parent_instance; + + GWinHttpFile *file; + gboolean request_sent; + HINTERNET connection; + HINTERNET request; +}; + +struct _GWinHttpFileInputStreamClass +{ + GFileInputStreamClass parent_class; +}; + +#define g_winhttp_file_input_stream_get_type _g_winhttp_file_input_stream_get_type +G_DEFINE_TYPE (GWinHttpFileInputStream, g_winhttp_file_input_stream, G_TYPE_FILE_INPUT_STREAM) + +static gssize g_winhttp_file_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); + +static gboolean g_winhttp_file_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error); + +static void +g_winhttp_file_input_stream_finalize (GObject *object) +{ + GWinHttpFileInputStream *winhttp_stream; + + winhttp_stream = G_WINHTTP_FILE_INPUT_STREAM (object); + + if (winhttp_stream->request != NULL) + G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (winhttp_stream->request); + if (winhttp_stream->connection != NULL) + G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (winhttp_stream->connection); + + g_object_unref (winhttp_stream->file); + winhttp_stream->file = NULL; + + G_OBJECT_CLASS (g_winhttp_file_input_stream_parent_class)->finalize (object); +} + +static void +g_winhttp_file_input_stream_class_init (GWinHttpFileInputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass); + + gobject_class->finalize = g_winhttp_file_input_stream_finalize; + + stream_class->read_fn = g_winhttp_file_input_stream_read; + stream_class->close_fn = g_winhttp_file_input_stream_close; +} + +static void +g_winhttp_file_input_stream_init (GWinHttpFileInputStream *info) +{ +} + +/* + * g_winhttp_file_input_stream_new: + * @file: the GWinHttpFile being read + * @connection: handle to the HTTP connection, as from WinHttpConnect() + * @request: handle to the HTTP request, as from WinHttpOpenRequest + * + * Returns: #GFileInputStream for the given request + */ +GFileInputStream * +_g_winhttp_file_input_stream_new (GWinHttpFile *file, + HINTERNET connection, + HINTERNET request) +{ + GWinHttpFileInputStream *stream; + + stream = g_object_new (G_TYPE_WINHTTP_FILE_INPUT_STREAM, NULL); + + stream->file = g_object_ref (file); + stream->request_sent = FALSE; + stream->connection = connection; + stream->request = request; + + return G_FILE_INPUT_STREAM (stream); +} + +static gssize +g_winhttp_file_input_stream_read (GInputStream *stream, + void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GWinHttpFileInputStream *winhttp_stream = G_WINHTTP_FILE_INPUT_STREAM (stream); + DWORD bytes_read; + + if (!winhttp_stream->request_sent) + { + if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpSendRequest + (winhttp_stream->request, + NULL, 0, + NULL, 0, + 0, + 0)) + { + _g_winhttp_set_error (error, GetLastError (), "GET request"); + + return -1; + } + + if (!_g_winhttp_response (winhttp_stream->file->vfs, + winhttp_stream->request, + error, + "GET request")) + return -1; + + winhttp_stream->request_sent = TRUE; + } + + if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpReadData + (winhttp_stream->request, buffer, count, &bytes_read)) + { + _g_winhttp_set_error (error, GetLastError (), "GET request"); + + return -1; + } + + return bytes_read; +} + +static gboolean +g_winhttp_file_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GWinHttpFileInputStream *winhttp_stream = G_WINHTTP_FILE_INPUT_STREAM (stream); + + if (winhttp_stream->connection != NULL) + G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (winhttp_stream->connection); + winhttp_stream->connection = NULL; + return TRUE; +} diff --git a/gio/win32/gwinhttpfileinputstream.h b/gio/win32/gwinhttpfileinputstream.h new file mode 100644 index 0000000..e27ea54 --- /dev/null +++ b/gio/win32/gwinhttpfileinputstream.h @@ -0,0 +1,50 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#ifndef __G_WINHTTP_FILE_INPUT_STREAM_H__ +#define __G_WINHTTP_FILE_INPUT_STREAM_H__ + +#include + +#include "gwinhttpfile.h" + +G_BEGIN_DECLS + +#define G_TYPE_WINHTTP_FILE_INPUT_STREAM (_g_winhttp_file_input_stream_get_type ()) +#define G_WINHTTP_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WINHTTP_FILE_INPUT_STREAM, GWinHttpFileInputStream)) +#define G_WINHTTP_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WINHTTP_FILE_INPUT_STREAM, GWinHttpFileInputStreamClass)) +#define G_IS_WINHTTP_FILE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WINHTTP_FILE_INPUT_STREAM)) +#define G_IS_WINHTTP_FILE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WINHTTP_FILE_INPUT_STREAM)) +#define G_WINHTTP_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WINHTTP_FILE_INPUT_STREAM, GWinHttpFileInputStreamClass)) + +typedef struct _GWinHttpFileInputStream GWinHttpFileInputStream; +typedef struct _GWinHttpFileInputStreamClass GWinHttpFileInputStreamClass; + +GType _g_winhttp_file_input_stream_get_type (void) G_GNUC_CONST; + +GFileInputStream *_g_winhttp_file_input_stream_new (GWinHttpFile *file, + HINTERNET connection, + HINTERNET request); + +G_END_DECLS + +#endif /* __G_WINHTTP_FILE_INPUT_STREAM_H__ */ diff --git a/gio/win32/gwinhttpfileoutputstream.c b/gio/win32/gwinhttpfileoutputstream.c new file mode 100644 index 0000000..f54f86c --- /dev/null +++ b/gio/win32/gwinhttpfileoutputstream.c @@ -0,0 +1,183 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#include "config.h" + +#include + +#include "gio/gcancellable.h" +#include "gio/gioerror.h" +#include "gwinhttpfileoutputstream.h" +#include "glibintl.h" + +struct _GWinHttpFileOutputStream +{ + GFileOutputStream parent_instance; + + GWinHttpFile *file; + HINTERNET connection; + goffset offset; +}; + +struct _GWinHttpFileOutputStreamClass +{ + GFileOutputStreamClass parent_class; +}; + +#define g_winhttp_file_output_stream_get_type _g_winhttp_file_output_stream_get_type +G_DEFINE_TYPE (GWinHttpFileOutputStream, g_winhttp_file_output_stream, G_TYPE_FILE_OUTPUT_STREAM) + +static gssize g_winhttp_file_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error); + +static void +g_winhttp_file_output_stream_finalize (GObject *object) +{ + GWinHttpFileOutputStream *winhttp_stream; + + winhttp_stream = G_WINHTTP_FILE_OUTPUT_STREAM (object); + + if (winhttp_stream->connection != NULL) + G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (winhttp_stream->connection); + + G_OBJECT_CLASS (g_winhttp_file_output_stream_parent_class)->finalize (object); +} + +static void +g_winhttp_file_output_stream_class_init (GWinHttpFileOutputStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass); + + gobject_class->finalize = g_winhttp_file_output_stream_finalize; + + stream_class->write_fn = g_winhttp_file_output_stream_write; +} + +static void +g_winhttp_file_output_stream_init (GWinHttpFileOutputStream *info) +{ +} + +/* + * g_winhttp_file_output_stream_new: + * @file: the GWinHttpFile being read + * @connection: handle to the HTTP connection, as from WinHttpConnect() + * @request: handle to the HTTP request, as from WinHttpOpenRequest + * + * Returns: #GFileOutputStream for the given request + */ +GFileOutputStream * +_g_winhttp_file_output_stream_new (GWinHttpFile *file, + HINTERNET connection) +{ + GWinHttpFileOutputStream *stream; + + stream = g_object_new (G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, NULL); + + stream->file = file; + stream->connection = connection; + stream->offset = 0; + + return G_FILE_OUTPUT_STREAM (stream); +} + +static gssize +g_winhttp_file_output_stream_write (GOutputStream *stream, + const void *buffer, + gsize count, + GCancellable *cancellable, + GError **error) +{ + GWinHttpFileOutputStream *winhttp_stream = G_WINHTTP_FILE_OUTPUT_STREAM (stream); + HINTERNET request; + char *headers; + wchar_t *wheaders; + DWORD bytes_written; + + request = G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpOpenRequest + (winhttp_stream->connection, + L"PUT", + winhttp_stream->file->url.lpszUrlPath, + NULL, + WINHTTP_NO_REFERER, + NULL, + winhttp_stream->file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0); + + if (request == NULL) + { + _g_winhttp_set_error (error, GetLastError (), "PUT request"); + + return -1; + } + + headers = g_strdup_printf ("Content-Range: bytes %" G_GINT64_FORMAT "-%" G_GINT64_FORMAT "/*\r\n", + winhttp_stream->offset, winhttp_stream->offset + count); + wheaders = g_utf8_to_utf16 (headers, -1, NULL, NULL, NULL); + g_free (headers); + + if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpSendRequest + (request, + wheaders, -1, + NULL, 0, + count, + 0)) + { + _g_winhttp_set_error (error, GetLastError (), "PUT request"); + + G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request); + g_free (wheaders); + + return -1; + } + + g_free (wheaders); + + if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpWriteData + (request, buffer, count, &bytes_written)) + { + _g_winhttp_set_error (error, GetLastError (), "PUT request"); + + G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request); + + return -1; + } + + winhttp_stream->offset += bytes_written; + + if (!_g_winhttp_response (winhttp_stream->file->vfs, + request, + error, + "PUT request")) + { + G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request); + + return -1; + } + + G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request); + + return bytes_written; +} diff --git a/gio/win32/gwinhttpfileoutputstream.h b/gio/win32/gwinhttpfileoutputstream.h new file mode 100644 index 0000000..fc7019c --- /dev/null +++ b/gio/win32/gwinhttpfileoutputstream.h @@ -0,0 +1,49 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#ifndef __G_WINHTTP_FILE_OUTPUT_STREAM_H__ +#define __G_WINHTTP_FILE_OUTPUT_STREAM_H__ + +#include + +#include "gwinhttpfile.h" + +G_BEGIN_DECLS + +#define G_TYPE_WINHTTP_FILE_OUTPUT_STREAM (_g_winhttp_file_output_stream_get_type ()) +#define G_WINHTTP_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, GWinHttpFileOutputStream)) +#define G_WINHTTP_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, GWinHttpFileOutputStreamClass)) +#define G_IS_WINHTTP_FILE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM)) +#define G_IS_WINHTTP_FILE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM)) +#define G_WINHTTP_FILE_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, GWinHttpFileOutputStreamClass)) + +typedef struct _GWinHttpFileOutputStream GWinHttpFileOutputStream; +typedef struct _GWinHttpFileOutputStreamClass GWinHttpFileOutputStreamClass; + +GType _g_winhttp_file_output_stream_get_type (void) G_GNUC_CONST; + +GFileOutputStream *_g_winhttp_file_output_stream_new (GWinHttpFile *file, + HINTERNET connection); + +G_END_DECLS + +#endif /* __G_WINHTTP_FILE_OUTPUT_STREAM_H__ */ diff --git a/gio/win32/gwinhttpvfs.c b/gio/win32/gwinhttpvfs.c new file mode 100644 index 0000000..4d5f514 --- /dev/null +++ b/gio/win32/gwinhttpvfs.c @@ -0,0 +1,479 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#include "config.h" + +#include + +#include "gio/gioerror.h" +#include "gio/giomodule.h" +#include "gio/gvfs.h" + +#include "gwinhttpfile.h" +#include "gwinhttpvfs.h" + +static gboolean lookup_done = FALSE; +static gboolean funcs_found = FALSE; +static GWinHttpDllFuncs funcs; + +static void +lookup_funcs (void) +{ + HMODULE winhttp = NULL; + WCHAR winhttp_dll[MAX_PATH + 100]; + int n; + + if (lookup_done) + return; + + n = GetSystemDirectoryW (winhttp_dll, MAX_PATH); + if (n > 0 && n < MAX_PATH) + { + if (winhttp_dll[n-1] != L'\\' && + winhttp_dll[n-1] != L'/') + wcscat (winhttp_dll, L"\\"); + wcscat (winhttp_dll, L"winhttp.dll"); + winhttp = LoadLibraryW (winhttp_dll); + } + + if (winhttp != NULL) + { + funcs.pWinHttpCloseHandle = (BOOL (WINAPI *) (HINTERNET)) GetProcAddress (winhttp, "WinHttpCloseHandle"); + funcs.pWinHttpCrackUrl = (BOOL (WINAPI *) (LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS)) GetProcAddress (winhttp, "WinHttpCrackUrl"); + funcs.pWinHttpConnect = (HINTERNET (WINAPI *) (HINTERNET,LPCWSTR,INTERNET_PORT,DWORD)) GetProcAddress (winhttp, "WinHttpConnect"); + funcs.pWinHttpCreateUrl = (BOOL (WINAPI *) (LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD)) GetProcAddress (winhttp, "WinHttpCreateUrl"); + funcs.pWinHttpOpen = (HINTERNET (WINAPI *) (LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD)) GetProcAddress (winhttp, "WinHttpOpen"); + funcs.pWinHttpOpenRequest = (HINTERNET (WINAPI *) (HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD)) GetProcAddress (winhttp, "WinHttpOpenRequest"); + funcs.pWinHttpQueryDataAvailable = (BOOL (WINAPI *) (HINTERNET,LPDWORD)) GetProcAddress (winhttp, "WinHttpQueryDataAvailable"); + funcs.pWinHttpQueryHeaders = (BOOL (WINAPI *) (HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpQueryHeaders"); + funcs.pWinHttpReadData = (BOOL (WINAPI *) (HINTERNET,LPVOID,DWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpReadData"); + funcs.pWinHttpReceiveResponse = (BOOL (WINAPI *) (HINTERNET,LPVOID)) GetProcAddress (winhttp, "WinHttpReceiveResponse"); + funcs.pWinHttpSendRequest = (BOOL (WINAPI *) (HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR)) GetProcAddress (winhttp, "WinHttpSendRequest"); + funcs.pWinHttpWriteData = (BOOL (WINAPI *) (HINTERNET,LPCVOID,DWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpWriteData"); + + if (funcs.pWinHttpCloseHandle && + funcs.pWinHttpCrackUrl && + funcs.pWinHttpConnect && + funcs.pWinHttpCreateUrl && + funcs.pWinHttpOpen && + funcs.pWinHttpOpenRequest && + funcs.pWinHttpQueryDataAvailable && + funcs.pWinHttpQueryHeaders && + funcs.pWinHttpReadData && + funcs.pWinHttpReceiveResponse && + funcs.pWinHttpSendRequest && + funcs.pWinHttpWriteData) + funcs_found = TRUE; + } + lookup_done = TRUE; +} + +#define g_winhttp_vfs_get_type _g_winhttp_vfs_get_type +G_DEFINE_TYPE_WITH_CODE (GWinHttpVfs, g_winhttp_vfs, G_TYPE_VFS, + { + lookup_funcs (); + if (funcs_found) + g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME, + g_define_type_id, + "winhttp", + 10); + }) + +static const gchar *winhttp_uri_schemes[] = { "http", "https" }; + +static void +g_winhttp_vfs_finalize (GObject *object) +{ + GWinHttpVfs *vfs; + + vfs = G_WINHTTP_VFS (object); + + (G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCloseHandle) (vfs->session); + vfs->session = NULL; + + if (vfs->wrapped_vfs) + g_object_unref (vfs->wrapped_vfs); + vfs->wrapped_vfs = NULL; + + G_OBJECT_CLASS (g_winhttp_vfs_parent_class)->finalize (object); +} + +static void +g_winhttp_vfs_init (GWinHttpVfs *vfs) +{ + wchar_t *wagent; + const gchar *prgname = g_get_prgname (); + + vfs->wrapped_vfs = g_vfs_get_local (); + + if (prgname) + wagent = g_utf8_to_utf16 (prgname, -1, NULL, NULL, NULL); + else + wagent = g_utf8_to_utf16 ("GWinHttpVfs", -1, NULL, NULL, NULL); + + vfs->session = (G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpOpen) + (wagent, + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, + 0); + + g_free (wagent); +} + +/** + * g_winhttp_vfs_new: + * + * Returns a new #GVfs handle for a WinHttp vfs. + * + * Returns: a new #GVfs handle. + **/ +GVfs * +_g_winhttp_vfs_new (void) +{ + return g_object_new (G_TYPE_WINHTTP_VFS, NULL); +} + +static GFile * +g_winhttp_vfs_get_file_for_path (GVfs *vfs, + const char *path) +{ + return g_vfs_get_file_for_path (G_WINHTTP_VFS (vfs)->wrapped_vfs, path); +} + +static GFile * +g_winhttp_vfs_get_file_for_uri (GVfs *vfs, + const char *uri) +{ + GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs); + gsize i; + GFile *ret = NULL; + + /* If it matches one of "our" schemes, handle it */ + for (i = 0; i < G_N_ELEMENTS (winhttp_uri_schemes); i++) + { + if (g_ascii_strncasecmp (uri, winhttp_uri_schemes[i], strlen (winhttp_uri_schemes[i])) == 0 && + uri[strlen (winhttp_uri_schemes[i])] == ':') + { + ret = _g_winhttp_file_new (winhttp_vfs, uri); + } + } + + /* For other URIs fallback to the wrapped GVfs */ + if (ret == NULL) + ret = g_vfs_get_file_for_uri (winhttp_vfs->wrapped_vfs, uri); + + g_assert (ret != NULL); + + return g_steal_pointer (&ret); +} + +static const gchar * const * +g_winhttp_vfs_get_supported_uri_schemes (GVfs *vfs) +{ + GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs); + const gchar * const *wrapped_vfs_uri_schemes = g_vfs_get_supported_uri_schemes (winhttp_vfs->wrapped_vfs); + gsize i, n; + const gchar **retval; + + n = 0; + while (wrapped_vfs_uri_schemes[n] != NULL) + n++; + + retval = g_new (const gchar *, n + G_N_ELEMENTS (winhttp_uri_schemes) + 1); + n = 0; + while (wrapped_vfs_uri_schemes[n] != NULL) + { + retval[n] = wrapped_vfs_uri_schemes[n]; + n++; + } + + for (i = 0; i < G_N_ELEMENTS (winhttp_uri_schemes); i++) + { + retval[n] = winhttp_uri_schemes[i]; + n++; + } + + retval[n] = NULL; + + return retval; +} + +static GFile * +g_winhttp_vfs_parse_name (GVfs *vfs, + const char *parse_name) +{ + GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs); + + g_return_val_if_fail (G_IS_VFS (vfs), NULL); + g_return_val_if_fail (parse_name != NULL, NULL); + + /* For plain file paths fallback to the wrapped GVfs */ + if (g_path_is_absolute (parse_name)) + return g_vfs_parse_name (winhttp_vfs->wrapped_vfs, parse_name); + + /* Otherwise assume it is an URI, so pass on to + * g_winhttp_vfs_get_file_for_uri(). + */ + return g_winhttp_vfs_get_file_for_uri (vfs, parse_name); +} + +static gboolean +g_winhttp_vfs_is_active (GVfs *vfs) +{ + return TRUE; +} + +static void +g_winhttp_vfs_class_init (GWinHttpVfsClass *class) +{ + GObjectClass *object_class; + GVfsClass *vfs_class; + + object_class = (GObjectClass *) class; + + object_class->finalize = g_winhttp_vfs_finalize; + + vfs_class = G_VFS_CLASS (class); + + vfs_class->is_active = g_winhttp_vfs_is_active; + vfs_class->get_file_for_path = g_winhttp_vfs_get_file_for_path; + vfs_class->get_file_for_uri = g_winhttp_vfs_get_file_for_uri; + vfs_class->get_supported_uri_schemes = g_winhttp_vfs_get_supported_uri_schemes; + vfs_class->parse_name = g_winhttp_vfs_parse_name; + + lookup_funcs (); + if (funcs_found) + class->funcs = &funcs; + else + class->funcs = NULL; +} + +char * +_g_winhttp_error_message (DWORD error_code) +{ + /* The FormatMessage() API that g_win32_error_message() uses doesn't + * seem to know about WinHttp errors, unfortunately. + */ + if (error_code >= WINHTTP_ERROR_BASE && error_code < WINHTTP_ERROR_BASE + 200) + { + switch (error_code) + { + /* FIXME: Use meaningful error messages */ +#define CASE(x) case ERROR_WINHTTP_##x: return g_strdup ("WinHttp error: " #x); + CASE (AUTO_PROXY_SERVICE_ERROR); + CASE (AUTODETECTION_FAILED); + CASE (BAD_AUTO_PROXY_SCRIPT); + CASE (CANNOT_CALL_AFTER_OPEN); + CASE (CANNOT_CALL_AFTER_SEND); + CASE (CANNOT_CALL_BEFORE_OPEN); + CASE (CANNOT_CALL_BEFORE_SEND); + CASE (CANNOT_CONNECT); + CASE (CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW); + CASE (CLIENT_AUTH_CERT_NEEDED); + CASE (CONNECTION_ERROR); + CASE (HEADER_ALREADY_EXISTS); + CASE (HEADER_COUNT_EXCEEDED); + CASE (HEADER_NOT_FOUND); + CASE (HEADER_SIZE_OVERFLOW); + CASE (INCORRECT_HANDLE_STATE); + CASE (INCORRECT_HANDLE_TYPE); + CASE (INTERNAL_ERROR); + CASE (INVALID_OPTION); + CASE (INVALID_QUERY_REQUEST); + CASE (INVALID_SERVER_RESPONSE); + CASE (INVALID_URL); + CASE (LOGIN_FAILURE); + CASE (NAME_NOT_RESOLVED); + CASE (NOT_INITIALIZED); + CASE (OPERATION_CANCELLED); + CASE (OPTION_NOT_SETTABLE); + CASE (OUT_OF_HANDLES); + CASE (REDIRECT_FAILED); + CASE (RESEND_REQUEST); + CASE (RESPONSE_DRAIN_OVERFLOW); + CASE (SECURE_CERT_CN_INVALID); + CASE (SECURE_CERT_DATE_INVALID); + CASE (SECURE_CERT_REV_FAILED); + CASE (SECURE_CERT_REVOKED); + CASE (SECURE_CERT_WRONG_USAGE); + CASE (SECURE_CHANNEL_ERROR); + CASE (SECURE_FAILURE); + CASE (SECURE_INVALID_CA); + CASE (SECURE_INVALID_CERT); + CASE (SHUTDOWN); + CASE (TIMEOUT); + CASE (UNABLE_TO_DOWNLOAD_SCRIPT); + CASE (UNRECOGNIZED_SCHEME); + #undef CASE + default: + return g_strdup_printf ("WinHttp error %ld", error_code); + } + } + else + return g_win32_error_message (error_code); +} + +void +_g_winhttp_set_error (GError **error, + DWORD error_code, + const char *what) +{ + char *emsg = _g_winhttp_error_message (error_code); + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "%s failed: %s", what, emsg); + g_free (emsg); +} + +gboolean +_g_winhttp_response (GWinHttpVfs *vfs, + HINTERNET request, + GError **error, + const char *what) +{ + wchar_t *status_code; + DWORD status_code_len; + + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpReceiveResponse (request, NULL)) + { + _g_winhttp_set_error (error, GetLastError (), what); + + return FALSE; + } + + status_code_len = 0; + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders + (request, + WINHTTP_QUERY_STATUS_CODE, + NULL, + NULL, + &status_code_len, + NULL) && + GetLastError () != ERROR_INSUFFICIENT_BUFFER) + { + _g_winhttp_set_error (error, GetLastError (), what); + + return FALSE; + } + + status_code = g_malloc (status_code_len); + + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders + (request, + WINHTTP_QUERY_STATUS_CODE, + NULL, + status_code, + &status_code_len, + NULL)) + { + _g_winhttp_set_error (error, GetLastError (), what); + g_free (status_code); + + return FALSE; + } + + if (status_code[0] != L'2') + { + wchar_t *status_text = NULL; + DWORD status_text_len; + + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders + (request, + WINHTTP_QUERY_STATUS_TEXT, + NULL, + NULL, + &status_text_len, + NULL) && + GetLastError () == ERROR_INSUFFICIENT_BUFFER) + { + status_text = g_malloc (status_text_len); + + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders + (request, + WINHTTP_QUERY_STATUS_TEXT, + NULL, + status_text, + &status_text_len, + NULL)) + { + g_free (status_text); + status_text = NULL; + } + } + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "%s failed: %S %S", + what, status_code, status_text ? status_text : L""); + g_free (status_code); + g_free (status_text); + + return FALSE; + } + + g_free (status_code); + + return TRUE; +} + +gboolean +_g_winhttp_query_header (GWinHttpVfs *vfs, + HINTERNET request, + const char *request_description, + DWORD which_header, + wchar_t **header, + GError **error) +{ + DWORD header_len = 0; + + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders + (request, + which_header, + NULL, + NULL, + &header_len, + NULL) && + GetLastError () != ERROR_INSUFFICIENT_BUFFER) + { + _g_winhttp_set_error (error, GetLastError (), request_description); + + return FALSE; + } + + *header = g_malloc (header_len); + if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpQueryHeaders + (request, + which_header, + NULL, + *header, + &header_len, + NULL)) + { + _g_winhttp_set_error (error, GetLastError (), request_description); + g_free (*header); + *header = NULL; + + return FALSE; + } + + return TRUE; +} diff --git a/gio/win32/gwinhttpvfs.h b/gio/win32/gwinhttpvfs.h new file mode 100644 index 0000000..fdac94a --- /dev/null +++ b/gio/win32/gwinhttpvfs.h @@ -0,0 +1,106 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + * Author: Tor Lillqvist + */ + +#ifndef __G_WINHTTP_VFS_H__ +#define __G_WINHTTP_VFS_H__ + +#include +#include + +#include + +#include "winhttp.h" + +G_BEGIN_DECLS + +#define G_TYPE_WINHTTP_VFS (_g_winhttp_vfs_get_type ()) +#define G_WINHTTP_VFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_WINHTTP_VFS, GWinHttpVfs)) +#define G_WINHTTP_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_WINHTTP_VFS, GWinHttpVfsClass)) +#define G_IS_WINHTTP_VFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_WINHTTP_VFS)) +#define G_IS_WINHTTP_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_WINHTTP_VFS)) +#define G_WINHTTP_VFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_WINHTTP_VFS, GWinHttpVfsClass)) + +typedef struct _GWinHttpVfs GWinHttpVfs; +typedef struct _GWinHttpDllFuncs GWinHttpDllFuncs; +typedef struct _GWinHttpVfsClass GWinHttpVfsClass; + +struct _GWinHttpVfs +{ + GVfs parent; + + GVfs *wrapped_vfs; + HINTERNET session; +}; + +struct _GWinHttpDllFuncs +{ + BOOL (WINAPI *pWinHttpCloseHandle) (HINTERNET); + BOOL (WINAPI *pWinHttpCrackUrl) (LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS); + HINTERNET (WINAPI *pWinHttpConnect) (HINTERNET,LPCWSTR,INTERNET_PORT,DWORD); + BOOL (WINAPI *pWinHttpCreateUrl) (LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD); + HINTERNET (WINAPI *pWinHttpOpen) (LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD); + HINTERNET (WINAPI *pWinHttpOpenRequest) (HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD); + BOOL (WINAPI *pWinHttpQueryDataAvailable) (HINTERNET,LPDWORD); + BOOL (WINAPI *pWinHttpQueryHeaders) (HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD); + BOOL (WINAPI *pWinHttpReadData) (HINTERNET,LPVOID,DWORD,LPDWORD); + BOOL (WINAPI *pWinHttpReceiveResponse) (HINTERNET,LPVOID); + BOOL (WINAPI *pWinHttpSendRequest) (HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR); + BOOL (WINAPI *pWinHttpWriteData) (HINTERNET,LPCVOID,DWORD,LPDWORD); +}; + +struct _GWinHttpVfsClass +{ + GVfsClass parent_class; + + /* As there is no import library for winhttp.dll in mingw, and + * winhttp.dll isn't present on Windows 2000 anyway, we must look up + * the functions we need dynamically. Store the pointers here. + */ + GWinHttpDllFuncs *funcs; +}; + + +GType _g_winhttp_vfs_get_type (void) G_GNUC_CONST; + +GVfs *_g_winhttp_vfs_new (void); + +char *_g_winhttp_error_message (DWORD error_code); + +void _g_winhttp_set_error (GError **error, + DWORD error_code, + const char *what); + +gboolean _g_winhttp_response (GWinHttpVfs *vfs, + HINTERNET request, + GError **error, + const char *what); + +gboolean _g_winhttp_query_header (GWinHttpVfs *vfs, + HINTERNET request, + const char *request_description, + DWORD which_header, + wchar_t **header, + GError **error); + +G_END_DECLS + +#endif /* __G_WINHTTP_VFS_H__ */ diff --git a/gio/win32/meson.build b/gio/win32/meson.build new file mode 100644 index 0000000..8d58998 --- /dev/null +++ b/gio/win32/meson.build @@ -0,0 +1,15 @@ +giowin32_sources = [ + 'gwin32fsmonitorutils.c', + 'gwin32filemonitor.c', + 'gwinhttpvfs.c', + 'gwinhttpfile.c', + 'gwinhttpfileinputstream.c', + 'gwinhttpfileoutputstream.c', +] + +giowin32_lib = static_library('giowin32', + sources : [giowin32_sources], + include_directories : [configinc, glibinc, gioinc, gmoduleinc], + dependencies : [libintl, gioenumtypes_dep], + pic : true, + c_args : gio_c_args) diff --git a/gio/win32/winhttp.h b/gio/win32/winhttp.h new file mode 100644 index 0000000..2f0041a --- /dev/null +++ b/gio/win32/winhttp.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2007 Francois Gouget + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef __WINE_WINHTTP_H +#define __WINE_WINHTTP_H + +#define WINHTTPAPI +#define BOOLAPI WINHTTPAPI BOOL WINAPI + + +typedef LPVOID HINTERNET; +typedef HINTERNET *LPHINTERNET; + +#define INTERNET_DEFAULT_PORT 0 +#define INTERNET_DEFAULT_HTTP_PORT 80 +#define INTERNET_DEFAULT_HTTPS_PORT 443 +typedef WORD INTERNET_PORT; +typedef INTERNET_PORT *LPINTERNET_PORT; + +#define INTERNET_SCHEME_HTTP 1 +#define INTERNET_SCHEME_HTTPS 2 +typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME; + +/* flags for WinHttpOpen */ +#define WINHTTP_FLAG_ASYNC 0x10000000 + +/* flags for WinHttpOpenRequest */ +#define WINHTTP_FLAG_ESCAPE_PERCENT 0x00000004 +#define WINHTTP_FLAG_NULL_CODEPAGE 0x00000008 +#define WINHTTP_FLAG_ESCAPE_DISABLE 0x00000040 +#define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY 0x00000080 +#define WINHTTP_FLAG_BYPASS_PROXY_CACHE 0x00000100 +#define WINHTTP_FLAG_REFRESH WINHTTP_FLAG_BYPASS_PROXY_CACHE +#define WINHTTP_FLAG_SECURE 0x00800000 + +#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 +#define WINHTTP_ACCESS_TYPE_NO_PROXY 1 +#define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 + +#define WINHTTP_NO_PROXY_NAME NULL +#define WINHTTP_NO_PROXY_BYPASS NULL + +#define WINHTTP_NO_REFERER NULL +#define WINHTTP_DEFAULT_ACCEPT_TYPES NULL + +#define WINHTTP_ERROR_BASE 12000 + +/* The original WINE winhttp.h didn't contain symbolic names for the + * error codes. However, the values of most of them are publicly + * documented at + * http://msdn.microsoft.com/en-us/library/aa383770(VS.85).aspx so + * we can add them here. + */ +#define ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR 12178 +#define ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT 12166 +#define ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN 12103 +#define ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND 12102 +#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN 12100 +#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND 12101 +#define ERROR_WINHTTP_CANNOT_CONNECT 12029 +#define ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW 12183 +#define ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED 12044 +#define ERROR_WINHTTP_CONNECTION_ERROR 12030 +#define ERROR_WINHTTP_HEADER_ALREADY_EXISTS 12155 +#define ERROR_WINHTTP_HEADER_COUNT_EXCEEDED 12181 +#define ERROR_WINHTTP_HEADER_NOT_FOUND 12150 +#define ERROR_WINHTTP_HEADER_SIZE_OVERFLOW 12182 +#define ERROR_WINHTTP_INCORRECT_HANDLE_STATE 12019 +#define ERROR_WINHTTP_INCORRECT_HANDLE_TYPE 12018 +#define ERROR_WINHTTP_INTERNAL_ERROR 12004 +#define ERROR_WINHTTP_INVALID_OPTION 12009 +#define ERROR_WINHTTP_INVALID_QUERY_REQUEST 12154 +#define ERROR_WINHTTP_INVALID_SERVER_RESPONSE 12152 +#define ERROR_WINHTTP_INVALID_URL 12005 +#define ERROR_WINHTTP_LOGIN_FAILURE 12015 +#define ERROR_WINHTTP_NAME_NOT_RESOLVED 12007 +#define ERROR_WINHTTP_NOT_INITIALIZED 12172 +#define ERROR_WINHTTP_OPERATION_CANCELLED 12017 +#define ERROR_WINHTTP_OPTION_NOT_SETTABLE 12011 +#define ERROR_WINHTTP_OUT_OF_HANDLES 12001 +#define ERROR_WINHTTP_REDIRECT_FAILED 12156 +#define ERROR_WINHTTP_RESEND_REQUEST 12032 +#define ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW 12184 +#define ERROR_WINHTTP_SECURE_CERT_CN_INVALID 12038 +#define ERROR_WINHTTP_SECURE_CERT_DATE_INVALID 12037 +#define ERROR_WINHTTP_SECURE_CERT_REV_FAILED 12057 +#define ERROR_WINHTTP_SECURE_CERT_REVOKED 12170 +#define ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE 12179 +#define ERROR_WINHTTP_SECURE_CHANNEL_ERROR 12157 +#define ERROR_WINHTTP_SECURE_FAILURE 12175 +#define ERROR_WINHTTP_SECURE_INVALID_CA 12045 +#define ERROR_WINHTTP_SECURE_INVALID_CERT 12169 +#define ERROR_WINHTTP_SHUTDOWN 12012 +#define ERROR_WINHTTP_TIMEOUT 12002 +#define ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT 12167 +#define ERROR_WINHTTP_UNRECOGNIZED_SCHEME 12006 +/* End of added error codes */ + +#define ERROR_WINHTTP_AUTODETECTION_FAILED (WINHTTP_ERROR_BASE + 180) + +typedef struct +{ + DWORD dwStructSize; + LPWSTR lpszScheme; + DWORD dwSchemeLength; + INTERNET_SCHEME nScheme; + LPWSTR lpszHostName; + DWORD dwHostNameLength; + INTERNET_PORT nPort; + LPWSTR lpszUserName; + DWORD dwUserNameLength; + LPWSTR lpszPassword; + DWORD dwPasswordLength; + LPWSTR lpszUrlPath; + DWORD dwUrlPathLength; + LPWSTR lpszExtraInfo; + DWORD dwExtraInfoLength; +} URL_COMPONENTS, *LPURL_COMPONENTS; +typedef URL_COMPONENTS URL_COMPONENTSW; +typedef LPURL_COMPONENTS LPURL_COMPONENTSW; + +typedef struct +{ + DWORD_PTR dwResult; + DWORD dwError; +} WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT; + +typedef struct +{ + FILETIME ftExpiry; + FILETIME ftStart; + LPWSTR lpszSubjectInfo; + LPWSTR lpszIssuerInfo; + LPWSTR lpszProtocolName; + LPWSTR lpszSignatureAlgName; + LPWSTR lpszEncryptionAlgName; + DWORD dwKeySize; +} WINHTTP_CERTIFICATE_INFO; + +typedef struct +{ + DWORD dwAccessType; + LPCWSTR lpszProxy; + LPCWSTR lpszProxyBypass; +} WINHTTP_PROXY_INFO, *LPWINHTTP_PROXY_INFO; +typedef WINHTTP_PROXY_INFO WINHTTP_PROXY_INFOW; +typedef LPWINHTTP_PROXY_INFO LPWINHTTP_PROXY_INFOW; + +typedef struct +{ + BOOL fAutoDetect; + LPWSTR lpszAutoConfigUrl; + LPWSTR lpszProxy; + LPWSTR lpszProxyBypass; +} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; + +typedef VOID (CALLBACK *WINHTTP_STATUS_CALLBACK)(HINTERNET,DWORD_PTR,DWORD,LPVOID,DWORD); + +typedef struct +{ + DWORD dwFlags; + DWORD dwAutoDetectFlags; + LPCWSTR lpszAutoConfigUrl; + LPVOID lpvReserved; + DWORD dwReserved; + BOOL fAutoLogonIfChallenged; +} WINHTTP_AUTOPROXY_OPTIONS; + +typedef struct +{ + DWORD dwMajorVersion; + DWORD dwMinorVersion; +} HTTP_VERSION_INFO, *LPHTTP_VERSION_INFO; + + +#ifdef __cplusplus +extern "C" { +#endif + +BOOL WINAPI WinHttpAddRequestHeaders(HINTERNET,LPCWSTR,DWORD,DWORD); +BOOL WINAPI WinHttpDetectAutoProxyConfigUrl(DWORD,LPWSTR*); +BOOL WINAPI WinHttpCheckPlatform(void); +BOOL WINAPI WinHttpCloseHandle(HINTERNET); +HINTERNET WINAPI WinHttpConnect(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD); +BOOL WINAPI WinHttpCrackUrl(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS); +BOOL WINAPI WinHttpCreateUrl(LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD); +BOOL WINAPI WinHttpGetDefaultProxyConfiguration(WINHTTP_PROXY_INFO*); +BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config); +BOOL WINAPI WinHttpGetProxyForUrl(HINTERNET,LPCWSTR,WINHTTP_AUTOPROXY_OPTIONS*,WINHTTP_PROXY_INFO*); +HINTERNET WINAPI WinHttpOpen(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD); + +/* The sixth parameter to WinHttpOpenRequest was wrong in the original + * WINE header. It should be LPCWSTR*, not LPCWSTR, as it points to an + * array of wide strings. + */ +HINTERNET WINAPI WinHttpOpenRequest(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD); +BOOL WINAPI WinHttpQueryAuthParams(HINTERNET,DWORD,LPVOID*); +BOOL WINAPI WinHttpQueryAuthSchemes(HINTERNET,LPDWORD,LPDWORD,LPDWORD); +BOOL WINAPI WinHttpQueryDataAvailable(HINTERNET,LPDWORD); +BOOL WINAPI WinHttpQueryHeaders(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD); +BOOL WINAPI WinHttpReadData(HINTERNET,LPVOID,DWORD,LPDWORD); +BOOL WINAPI WinHttpReceiveResponse(HINTERNET,LPVOID); +BOOL WINAPI WinHttpSendRequest(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR); +BOOL WINAPI WinHttpSetDefaultProxyConfiguration(WINHTTP_PROXY_INFO*); +BOOL WINAPI WinHttpSetCredentials(HINTERNET,DWORD,DWORD,LPCWSTR,LPCWSTR,LPVOID); +BOOL WINAPI WinHttpSetOption(HINTERNET,DWORD,LPVOID,DWORD); +WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback(HINTERNET,WINHTTP_STATUS_CALLBACK,DWORD,DWORD_PTR); +BOOL WINAPI WinHttpSetTimeouts(HINTERNET,int,int,int,int); +BOOL WINAPI WinHttpTimeFromSystemTime(CONST SYSTEMTIME *,LPWSTR); +BOOL WINAPI WinHttpTimeToSystemTime(LPCWSTR,SYSTEMTIME*); +BOOL WINAPI WinHttpWriteData(HINTERNET,LPCVOID,DWORD,LPDWORD); + +/* Additional definitions, from the public domain in mingw */ +#define ICU_ESCAPE 0x80000000 +#define ICU_DECODE 0x10000000 + +/* A few constants I couldn't find publicly documented, so I looked up + * their value from the Windows SDK . Presumably this falls + * under fair use. + */ +#define WINHTTP_QUERY_CONTENT_LENGTH 5 +#define WINHTTP_QUERY_CONTENT_TYPE 1 +#define WINHTTP_QUERY_LAST_MODIFIED 11 +#define WINHTTP_QUERY_STATUS_CODE 19 +#define WINHTTP_QUERY_STATUS_TEXT 20 + +#define WINHTTP_QUERY_FLAG_SYSTEMTIME 0x40000000 + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_WINHTTP_H */ diff --git a/gio/xdgmime/.gitignore b/gio/xdgmime/.gitignore new file mode 100644 index 0000000..56e6945 --- /dev/null +++ b/gio/xdgmime/.gitignore @@ -0,0 +1 @@ +test-mime diff --git a/gio/xdgmime/meson.build b/gio/xdgmime/meson.build new file mode 100644 index 0000000..4c8a552 --- /dev/null +++ b/gio/xdgmime/meson.build @@ -0,0 +1,17 @@ +xdgmime_sources = files( + 'xdgmime.c', + 'xdgmimealias.c', + 'xdgmimecache.c', + 'xdgmimeglob.c', + 'xdgmimeicon.c', + 'xdgmimeint.c', + 'xdgmimemagic.c', + 'xdgmimeparent.c', +) + +xdgmime_lib = static_library('xdgmime', + sources : xdgmime_sources, + include_directories : [configinc], + pic : true, + c_args : [ '-DHAVE_CONFIG_H', + '-DXDG_PREFIX=_gio_xdg' ] + glib_hidden_visibility_args) diff --git a/gio/xdgmime/xdgmime.c b/gio/xdgmime/xdgmime.c new file mode 100644 index 0000000..c3c1162 --- /dev/null +++ b/gio/xdgmime/xdgmime.c @@ -0,0 +1,1012 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmime.c: XDG Mime Spec mime resolver. Based on version 0.11 of the spec. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003,2004 Red Hat, Inc. + * Copyright (C) 2003,2004 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmime.h" +#include "xdgmimeint.h" +#include "xdgmimeglob.h" +#include "xdgmimemagic.h" +#include "xdgmimealias.h" +#include "xdgmimeicon.h" +#include "xdgmimeparent.h" +#include "xdgmimecache.h" +#include +#include +#include +#include +#include +#include +#include + +#ifndef S_ISREG +#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif + +typedef struct XdgDirTimeList XdgDirTimeList; +typedef struct XdgCallbackList XdgCallbackList; + +static int need_reread = TRUE; +static time_t last_stat_time = 0; + +static XdgGlobHash *global_hash = NULL; +static XdgMimeMagic *global_magic = NULL; +static XdgAliasList *alias_list = NULL; +static XdgParentList *parent_list = NULL; +static XdgDirTimeList *dir_time_list = NULL; +static XdgCallbackList *callback_list = NULL; +static XdgIconList *icon_list = NULL; +static XdgIconList *generic_icon_list = NULL; + +static char **xdg_dirs = NULL; /* NULL terminated */ + +XdgMimeCache **_caches = NULL; +static int n_caches = 0; + +const char xdg_mime_type_unknown[] = "application/octet-stream"; +const char xdg_mime_type_empty[] = "application/x-zerosize"; +const char xdg_mime_type_textplain[] = "text/plain"; + + +enum +{ + XDG_CHECKED_UNCHECKED, + XDG_CHECKED_VALID, + XDG_CHECKED_INVALID +}; + +struct XdgDirTimeList +{ + time_t mtime; + char *directory_name; + int checked; + XdgDirTimeList *next; +}; + +struct XdgCallbackList +{ + XdgCallbackList *next; + XdgCallbackList *prev; + int callback_id; + XdgMimeCallback callback; + void *data; + XdgMimeDestroy destroy; +}; + +/* Function called by xdg_run_command_on_dirs. If it returns TRUE, further + * directories aren't looked at */ +typedef int (*XdgDirectoryFunc) (const char *directory, + void *user_data); + +static void +xdg_dir_time_list_add (char *file_name, + time_t mtime) +{ + XdgDirTimeList *list; + + for (list = dir_time_list; list; list = list->next) + { + if (strcmp (list->directory_name, file_name) == 0) + { + free (file_name); + return; + } + } + + list = calloc (1, sizeof (XdgDirTimeList)); + list->checked = XDG_CHECKED_UNCHECKED; + list->directory_name = file_name; + list->mtime = mtime; + list->next = dir_time_list; + dir_time_list = list; +} + +static void +xdg_dir_time_list_free (XdgDirTimeList *list) +{ + XdgDirTimeList *next; + + while (list) + { + next = list->next; + free (list->directory_name); + free (list); + list = next; + } +} + +static int +xdg_mime_init_from_directory (const char *directory, + void *user_data) +{ + char *file_name; + struct stat st; + + assert (directory != NULL); + + file_name = malloc (strlen (directory) + strlen ("/mime.cache") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime.cache"); + if (stat (file_name, &st) == 0) + { + XdgMimeCache *cache = _xdg_mime_cache_new_from_file (file_name); + + if (cache != NULL) + { + xdg_dir_time_list_add (file_name, st.st_mtime); + + _caches = realloc (_caches, sizeof (XdgMimeCache *) * (n_caches + 2)); + _caches[n_caches] = cache; + _caches[n_caches + 1] = NULL; + n_caches++; + + return FALSE; + } + } + free (file_name); + + file_name = malloc (strlen (directory) + strlen ("/globs2") + 1); + strcpy (file_name, directory); strcat (file_name, "/globs2"); + if (stat (file_name, &st) == 0) + { + _xdg_mime_glob_read_from_file (global_hash, file_name, TRUE); + xdg_dir_time_list_add (file_name, st.st_mtime); + } + else + { + free (file_name); + file_name = malloc (strlen (directory) + strlen ("/globs") + 1); + strcpy (file_name, directory); strcat (file_name, "/globs"); + if (stat (file_name, &st) == 0) + { + _xdg_mime_glob_read_from_file (global_hash, file_name, FALSE); + xdg_dir_time_list_add (file_name, st.st_mtime); + } + else + { + free (file_name); + } + } + + file_name = malloc (strlen (directory) + strlen ("/magic") + 1); + strcpy (file_name, directory); strcat (file_name, "/magic"); + if (stat (file_name, &st) == 0) + { + _xdg_mime_magic_read_from_file (global_magic, file_name); + xdg_dir_time_list_add (file_name, st.st_mtime); + } + else + { + free (file_name); + } + + file_name = malloc (strlen (directory) + strlen ("/aliases") + 1); + strcpy (file_name, directory); strcat (file_name, "/aliases"); + _xdg_mime_alias_read_from_file (alias_list, file_name); + free (file_name); + + file_name = malloc (strlen (directory) + strlen ("/subclasses") + 1); + strcpy (file_name, directory); strcat (file_name, "/subclasses"); + _xdg_mime_parent_read_from_file (parent_list, file_name); + free (file_name); + + file_name = malloc (strlen (directory) + strlen ("/icons") + 1); + strcpy (file_name, directory); strcat (file_name, "/icons"); + _xdg_mime_icon_read_from_file (icon_list, file_name); + free (file_name); + + file_name = malloc (strlen (directory) + strlen ("/generic-icons") + 1); + strcpy (file_name, directory); strcat (file_name, "/generic-icons"); + _xdg_mime_icon_read_from_file (generic_icon_list, file_name); + free (file_name); + + return FALSE; /* Keep processing */ +} + +/* Set @xdg_dirs from the environment. It must not have been set already. */ +static void +xdg_init_dirs (void) +{ + const char *xdg_data_home, *home, *xdg_data_dirs; + const char *ptr; + size_t n_dirs = 0; + size_t i, current_dir; + + assert (xdg_dirs == NULL); + + xdg_data_home = getenv ("XDG_DATA_HOME"); + home = getenv ("HOME"); + xdg_data_dirs = getenv ("XDG_DATA_DIRS"); + + if (xdg_data_dirs == NULL) + xdg_data_dirs = "/usr/local/share/:/usr/share/"; + + /* Work out how many dirs we’re dealing with. */ + if (xdg_data_home != NULL || home != NULL) + n_dirs++; + n_dirs++; /* initial entry in @xdg_data_dirs */ + for (i = 0; xdg_data_dirs[i] != '\0'; i++) + if (xdg_data_dirs[i] == ':') + n_dirs++; + + xdg_dirs = calloc (n_dirs + 1 /* NULL terminator */, sizeof (char *)); + current_dir = 0; + + /* $XDG_DATA_HOME */ + if (xdg_data_home != NULL) + { + char *mime_subdir; + + mime_subdir = malloc (strlen (xdg_data_home) + strlen ("/mime/") + 1); + strcpy (mime_subdir, xdg_data_home); + strcat (mime_subdir, "/mime/"); + + xdg_dirs[current_dir++] = mime_subdir; + } + else if (home != NULL) + { + char *guessed_xdg_home; + + guessed_xdg_home = malloc (strlen (home) + strlen ("/.local/share/mime/") + 1); + strcpy (guessed_xdg_home, home); + strcat (guessed_xdg_home, "/.local/share/mime/"); + + xdg_dirs[current_dir++] = guessed_xdg_home; + } + + /* $XDG_DATA_DIRS */ + ptr = xdg_data_dirs; + + while (*ptr != '\000') + { + const char *end_ptr; + char *dir; + int len; + + end_ptr = ptr; + while (*end_ptr != ':' && *end_ptr != '\000') + end_ptr ++; + + if (end_ptr == ptr) + { + ptr++; + continue; + } + + if (*end_ptr == ':') + len = end_ptr - ptr; + else + len = end_ptr - ptr + 1; + dir = malloc (len + strlen ("/mime/") + 1); + strncpy (dir, ptr, len); + dir[len] = '\0'; + strcat (dir, "/mime/"); + + xdg_dirs[current_dir++] = dir; + + ptr = end_ptr; + } + + /* NULL terminator */ + xdg_dirs[current_dir] = NULL; + + need_reread = TRUE; +} + +/* Runs a command on all the directories in the search path (@xdg_dirs). */ +static void +xdg_run_command_on_dirs (XdgDirectoryFunc func, + void *user_data) +{ + size_t i; + + if (xdg_dirs == NULL) + xdg_init_dirs (); + + for (i = 0; xdg_dirs[i] != NULL; i++) + { + if ((func) (xdg_dirs[i], user_data)) + return; + } +} + +/* Allows the calling code to override the directories used by xdgmime, without + * having to change environment variables in a running process (which is not + * thread safe). This is intended to be used by tests. The changes will be + * picked up by xdg_mime_init() next time public API is called. + * + * This will set @xdg_dirs. Directories in @dirs must be complete, including + * the conventional `/mime` subdirectory. This is to allow tests to override + * them without the need to create a subdirectory. */ +void +xdg_mime_set_dirs (const char * const *dirs) +{ + size_t i; + + for (i = 0; xdg_dirs != NULL && xdg_dirs[i] != NULL; i++) + free (xdg_dirs[i]); + free (xdg_dirs); + xdg_dirs = NULL; + + if (dirs != NULL) + { + for (i = 0; dirs[i] != NULL; i++); + xdg_dirs = calloc (i + 1 /* NULL terminator */, sizeof (char*)); + for (i = 0; dirs[i] != NULL; i++) + xdg_dirs[i] = strdup (dirs[i]); + xdg_dirs[i] = NULL; + } + + need_reread = TRUE; +} + +/* Checks file_path to make sure it has the same mtime as last time it was + * checked. If it has a different mtime, or if the file doesn't exist, it + * returns FALSE. + * + * FIXME: This doesn't protect against permission changes. + */ +static int +xdg_check_file (const char *file_path, + int *exists) +{ + struct stat st; + + /* If the file exists */ + if (stat (file_path, &st) == 0) + { + XdgDirTimeList *list; + + if (exists) + *exists = TRUE; + + for (list = dir_time_list; list; list = list->next) + { + if (! strcmp (list->directory_name, file_path)) + { + if (st.st_mtime == list->mtime) + list->checked = XDG_CHECKED_VALID; + else + list->checked = XDG_CHECKED_INVALID; + + return (list->checked != XDG_CHECKED_VALID); + } + } + return TRUE; + } + + if (exists) + *exists = FALSE; + + return FALSE; +} + +static int +xdg_check_dir (const char *directory, + void *user_data) +{ + int invalid, exists; + char *file_name; + int* invalid_dir_list = user_data; + + assert (directory != NULL); + + /* Check the mime.cache file */ + file_name = malloc (strlen (directory) + strlen ("/mime.cache") + 1); + strcpy (file_name, directory); strcat (file_name, "/mime.cache"); + invalid = xdg_check_file (file_name, &exists); + free (file_name); + if (invalid) + { + *invalid_dir_list = TRUE; + return TRUE; + } + else if (exists) + { + return FALSE; + } + + /* Check the globs file */ + file_name = malloc (strlen (directory) + strlen ("/globs") + 1); + strcpy (file_name, directory); strcat (file_name, "/globs"); + invalid = xdg_check_file (file_name, NULL); + free (file_name); + if (invalid) + { + *invalid_dir_list = TRUE; + return TRUE; + } + + /* Check the magic file */ + file_name = malloc (strlen (directory) + strlen ("/magic") + 1); + strcpy (file_name, directory); strcat (file_name, "/magic"); + invalid = xdg_check_file (file_name, NULL); + free (file_name); + if (invalid) + { + *invalid_dir_list = TRUE; + return TRUE; + } + + return FALSE; /* Keep processing */ +} + +/* Walks through all the mime files stat()ing them to see if they've changed. + * Returns TRUE if they have. */ +static int +xdg_check_dirs (void) +{ + XdgDirTimeList *list; + int invalid_dir_list = FALSE; + + for (list = dir_time_list; list; list = list->next) + list->checked = XDG_CHECKED_UNCHECKED; + + xdg_run_command_on_dirs (xdg_check_dir, &invalid_dir_list); + + if (invalid_dir_list) + return TRUE; + + for (list = dir_time_list; list; list = list->next) + { + if (list->checked != XDG_CHECKED_VALID) + return TRUE; + } + + return FALSE; +} + +/* We want to avoid stat()ing on every single mime call, so we only look for + * newer files every 5 seconds. This will return TRUE if we need to reread the + * mime data from disk. + */ +static int +xdg_check_time_and_dirs (void) +{ + struct timeval tv; + time_t current_time; + int retval = FALSE; + + gettimeofday (&tv, NULL); + current_time = tv.tv_sec; + + if (current_time >= last_stat_time + 5) + { + retval = xdg_check_dirs (); + last_stat_time = current_time; + } + + return retval; +} + +/* Called in every public function. It reloads the hash function if need be. + */ +static void +xdg_mime_init (void) +{ + if (xdg_check_time_and_dirs ()) + { + xdg_mime_shutdown (); + } + + if (need_reread) + { + global_hash = _xdg_glob_hash_new (); + global_magic = _xdg_mime_magic_new (); + alias_list = _xdg_mime_alias_list_new (); + parent_list = _xdg_mime_parent_list_new (); + icon_list = _xdg_mime_icon_list_new (); + generic_icon_list = _xdg_mime_icon_list_new (); + + xdg_run_command_on_dirs (xdg_mime_init_from_directory, NULL); + + need_reread = FALSE; + } +} + +const char * +xdg_mime_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio) +{ + const char *mime_type; + + if (len == 0) + { + if (result_prio != NULL) + *result_prio = 100; + return XDG_MIME_TYPE_EMPTY; + } + + xdg_mime_init (); + + if (_caches) + mime_type = _xdg_mime_cache_get_mime_type_for_data (data, len, result_prio); + else + mime_type = _xdg_mime_magic_lookup_data (global_magic, data, len, result_prio, NULL, 0); + + if (mime_type) + return mime_type; + + return _xdg_binary_or_text_fallback(data, len); +} + +const char * +xdg_mime_get_mime_type_for_file (const char *file_name, + struct stat *statbuf) +{ + const char *mime_type; + /* currently, only a few globs occur twice, and none + * more often, so 5 seems plenty. + */ + const char *mime_types[5]; + FILE *file; + unsigned char *data; + int max_extent; + int bytes_read; + struct stat buf; + const char *base_name; + int n; + + if (file_name == NULL) + return NULL; + if (! _xdg_utf8_validate (file_name)) + return NULL; + + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_mime_type_for_file (file_name, statbuf); + + base_name = _xdg_get_base_name (file_name); + n = _xdg_glob_hash_lookup_file_name (global_hash, base_name, mime_types, 5); + + if (n == 1) + return mime_types[0]; + + if (!statbuf) + { + if (stat (file_name, &buf) != 0) + return XDG_MIME_TYPE_UNKNOWN; + + statbuf = &buf; + } + + if (!S_ISREG (statbuf->st_mode)) + return XDG_MIME_TYPE_UNKNOWN; + + /* FIXME: Need to make sure that max_extent isn't totally broken. This could + * be large and need getting from a stream instead of just reading it all + * in. */ + max_extent = _xdg_mime_magic_get_buffer_extents (global_magic); + data = malloc (max_extent); + if (data == NULL) + return XDG_MIME_TYPE_UNKNOWN; + + file = fopen (file_name, "r"); + if (file == NULL) + { + free (data); + return XDG_MIME_TYPE_UNKNOWN; + } + + bytes_read = fread (data, 1, max_extent, file); + if (ferror (file)) + { + free (data); + fclose (file); + return XDG_MIME_TYPE_UNKNOWN; + } + + mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read, NULL, + mime_types, n); + + if (!mime_type) + mime_type = _xdg_binary_or_text_fallback (data, bytes_read); + + free (data); + fclose (file); + + return mime_type; +} + +const char * +xdg_mime_get_mime_type_from_file_name (const char *file_name) +{ + const char *mime_type; + + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_mime_type_from_file_name (file_name); + + if (_xdg_glob_hash_lookup_file_name (global_hash, file_name, &mime_type, 1)) + return mime_type; + else + return XDG_MIME_TYPE_UNKNOWN; +} + +int +xdg_mime_get_mime_types_from_file_name (const char *file_name, + const char *mime_types[], + int n_mime_types) +{ + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_mime_types_from_file_name (file_name, mime_types, n_mime_types); + + return _xdg_glob_hash_lookup_file_name (global_hash, file_name, mime_types, n_mime_types); +} + +int +xdg_mime_is_valid_mime_type (const char *mime_type) +{ + /* FIXME: We should make this a better test + */ + return _xdg_utf8_validate (mime_type); +} + +void +xdg_mime_shutdown (void) +{ + XdgCallbackList *list; + + /* FIXME: Need to make this (and the whole library) thread safe */ + if (dir_time_list) + { + xdg_dir_time_list_free (dir_time_list); + dir_time_list = NULL; + } + + if (global_hash) + { + _xdg_glob_hash_free (global_hash); + global_hash = NULL; + } + if (global_magic) + { + _xdg_mime_magic_free (global_magic); + global_magic = NULL; + } + + if (alias_list) + { + _xdg_mime_alias_list_free (alias_list); + alias_list = NULL; + } + + if (parent_list) + { + _xdg_mime_parent_list_free (parent_list); + parent_list = NULL; + } + + if (icon_list) + { + _xdg_mime_icon_list_free (icon_list); + icon_list = NULL; + } + + if (generic_icon_list) + { + _xdg_mime_icon_list_free (generic_icon_list); + generic_icon_list = NULL; + } + + if (_caches) + { + int i; + + for (i = 0; i < n_caches; i++) + _xdg_mime_cache_unref (_caches[i]); + free (_caches); + _caches = NULL; + n_caches = 0; + } + + for (list = callback_list; list; list = list->next) + (list->callback) (list->data); + + need_reread = TRUE; +} + +int +xdg_mime_get_max_buffer_extents (void) +{ + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_max_buffer_extents (); + + return _xdg_mime_magic_get_buffer_extents (global_magic); +} + +const char * +_xdg_mime_unalias_mime_type (const char *mime_type) +{ + const char *lookup; + + if (_caches) + return _xdg_mime_cache_unalias_mime_type (mime_type); + + if ((lookup = _xdg_mime_alias_list_lookup (alias_list, mime_type)) != NULL) + return lookup; + + return mime_type; +} + +const char * +xdg_mime_unalias_mime_type (const char *mime_type) +{ + xdg_mime_init (); + + return _xdg_mime_unalias_mime_type (mime_type); +} + +int +_xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b) +{ + const char *unalias_a, *unalias_b; + + unalias_a = _xdg_mime_unalias_mime_type (mime_a); + unalias_b = _xdg_mime_unalias_mime_type (mime_b); + + if (strcmp (unalias_a, unalias_b) == 0) + return 1; + + return 0; +} + +int +xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b) +{ + xdg_mime_init (); + + return _xdg_mime_mime_type_equal (mime_a, mime_b); +} + +int +xdg_mime_media_type_equal (const char *mime_a, + const char *mime_b) +{ + char *sep; + + sep = strchr (mime_a, '/'); + + if (sep && strncmp (mime_a, mime_b, sep - mime_a + 1) == 0) + return 1; + + return 0; +} + +#if 1 +static int +ends_with (const char *str, + const char *suffix) +{ + int length; + int suffix_length; + + length = strlen (str); + suffix_length = strlen (suffix); + if (length < suffix_length) + return 0; + + if (strcmp (str + length - suffix_length, suffix) == 0) + return 1; + + return 0; +} + +static int +xdg_mime_is_super_type (const char *mime) +{ + return ends_with (mime, "/*"); +} +#endif + +int +_xdg_mime_mime_type_subclass (const char *mime, + const char *base) +{ + const char *umime, *ubase; + const char **parents; + + if (_caches) + return _xdg_mime_cache_mime_type_subclass (mime, base); + + umime = _xdg_mime_unalias_mime_type (mime); + ubase = _xdg_mime_unalias_mime_type (base); + + if (strcmp (umime, ubase) == 0) + return 1; + +#if 1 + /* Handle supertypes */ + if (xdg_mime_is_super_type (ubase) && + xdg_mime_media_type_equal (umime, ubase)) + return 1; +#endif + + /* Handle special cases text/plain and application/octet-stream */ + if (strcmp (ubase, "text/plain") == 0 && + strncmp (umime, "text/", 5) == 0) + return 1; + + if (strcmp (ubase, "application/octet-stream") == 0 && + strncmp (umime, "inode/", 6) != 0) + return 1; + + parents = _xdg_mime_parent_list_lookup (parent_list, umime); + for (; parents && *parents; parents++) + { + if (_xdg_mime_mime_type_subclass (*parents, ubase)) + return 1; + } + + return 0; +} + +int +xdg_mime_mime_type_subclass (const char *mime, + const char *base) +{ + xdg_mime_init (); + + return _xdg_mime_mime_type_subclass (mime, base); +} + +char ** +xdg_mime_list_mime_parents (const char *mime) +{ + const char **parents; + char **result; + int i, n; + + if (_caches) + return _xdg_mime_cache_list_mime_parents (mime); + + parents = xdg_mime_get_mime_parents (mime); + + if (!parents) + return NULL; + + for (i = 0; parents[i]; i++) ; + + n = (i + 1) * sizeof (char *); + result = (char **) malloc (n); + memcpy (result, parents, n); + + return result; +} + +const char ** +xdg_mime_get_mime_parents (const char *mime) +{ + const char *umime; + + xdg_mime_init (); + + umime = _xdg_mime_unalias_mime_type (mime); + + return _xdg_mime_parent_list_lookup (parent_list, umime); +} + +void +xdg_mime_dump (void) +{ + xdg_mime_init(); + + printf ("*** ALIASES ***\n\n"); + _xdg_mime_alias_list_dump (alias_list); + printf ("\n*** PARENTS ***\n\n"); + _xdg_mime_parent_list_dump (parent_list); + printf ("\n*** CACHE ***\n\n"); + _xdg_glob_hash_dump (global_hash); + printf ("\n*** GLOBS ***\n\n"); + _xdg_glob_hash_dump (global_hash); + printf ("\n*** GLOBS REVERSE TREE ***\n\n"); + _xdg_mime_cache_glob_dump (); +} + + +/* Registers a function to be called every time the mime database reloads its files + */ +int +xdg_mime_register_reload_callback (XdgMimeCallback callback, + void *data, + XdgMimeDestroy destroy) +{ + XdgCallbackList *list_el; + static int callback_id = 1; + + /* Make a new list element */ + list_el = calloc (1, sizeof (XdgCallbackList)); + list_el->callback_id = callback_id; + list_el->callback = callback; + list_el->data = data; + list_el->destroy = destroy; + list_el->next = callback_list; + if (list_el->next) + list_el->next->prev = list_el; + + callback_list = list_el; + callback_id ++; + + return callback_id - 1; +} + +void +xdg_mime_remove_callback (int callback_id) +{ + XdgCallbackList *list; + + for (list = callback_list; list; list = list->next) + { + if (list->callback_id == callback_id) + { + if (list->next) + list->next = list->prev; + + if (list->prev) + list->prev->next = list->next; + else + callback_list = list->next; + + /* invoke the destroy handler */ + (list->destroy) (list->data); + free (list); + return; + } + } +} + +const char * +xdg_mime_get_icon (const char *mime) +{ + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_icon (mime); + + return _xdg_mime_icon_list_lookup (icon_list, mime); +} + +const char * +xdg_mime_get_generic_icon (const char *mime) +{ + xdg_mime_init (); + + if (_caches) + return _xdg_mime_cache_get_generic_icon (mime); + + return _xdg_mime_icon_list_lookup (generic_icon_list, mime); +} diff --git a/gio/xdgmime/xdgmime.h b/gio/xdgmime/xdgmime.h new file mode 100644 index 0000000..c590996 --- /dev/null +++ b/gio/xdgmime/xdgmime.h @@ -0,0 +1,135 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmime.h: XDG Mime Spec mime resolver. Based on version 0.11 of the spec. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __XDG_MIME_H__ +#define __XDG_MIME_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef XDG_PREFIX +#define XDG_ENTRY(func) _XDG_ENTRY2(XDG_PREFIX,func) +#define _XDG_ENTRY2(prefix,func) _XDG_ENTRY3(prefix,func) +#define _XDG_ENTRY3(prefix,func) prefix##_##func + +#define XDG_RESERVED_ENTRY(func) _XDG_RESERVED_ENTRY2(XDG_PREFIX,func) +#define _XDG_RESERVED_ENTRY2(prefix,func) _XDG_RESERVED_ENTRY3(prefix,func) +#define _XDG_RESERVED_ENTRY3(prefix,func) _##prefix##_##func +#endif + +typedef void (*XdgMimeCallback) (void *user_data); +typedef void (*XdgMimeDestroy) (void *user_data); + + +#ifdef XDG_PREFIX +#define xdg_mime_get_mime_type_for_data XDG_ENTRY(get_mime_type_for_data) +#define xdg_mime_get_mime_type_for_file XDG_ENTRY(get_mime_type_for_file) +#define xdg_mime_get_mime_type_from_file_name XDG_ENTRY(get_mime_type_from_file_name) +#define xdg_mime_get_mime_types_from_file_name XDG_ENTRY(get_mime_types_from_file_name) +#define xdg_mime_is_valid_mime_type XDG_ENTRY(is_valid_mime_type) +#define xdg_mime_mime_type_equal XDG_ENTRY(mime_type_equal) +#define xdg_mime_media_type_equal XDG_ENTRY(media_type_equal) +#define xdg_mime_mime_type_subclass XDG_ENTRY(mime_type_subclass) +#define xdg_mime_get_mime_parents XDG_ENTRY(get_mime_parents) +#define xdg_mime_list_mime_parents XDG_ENTRY(list_mime_parents) +#define xdg_mime_unalias_mime_type XDG_ENTRY(unalias_mime_type) +#define xdg_mime_get_max_buffer_extents XDG_ENTRY(get_max_buffer_extents) +#define xdg_mime_shutdown XDG_ENTRY(shutdown) +#define xdg_mime_dump XDG_ENTRY(dump) +#define xdg_mime_register_reload_callback XDG_ENTRY(register_reload_callback) +#define xdg_mime_remove_callback XDG_ENTRY(remove_callback) +#define xdg_mime_type_unknown XDG_ENTRY(type_unknown) +#define xdg_mime_type_empty XDG_ENTRY(type_empty) +#define xdg_mime_type_textplain XDG_ENTRY(type_textplain) +#define xdg_mime_get_icon XDG_ENTRY(get_icon) +#define xdg_mime_get_generic_icon XDG_ENTRY(get_generic_icon) + +#define _xdg_mime_mime_type_equal XDG_RESERVED_ENTRY(mime_type_equal) +#define _xdg_mime_mime_type_subclass XDG_RESERVED_ENTRY(mime_type_subclass) +#define _xdg_mime_unalias_mime_type XDG_RESERVED_ENTRY(unalias_mime_type) +#endif + +extern const char xdg_mime_type_unknown[]; +extern const char xdg_mime_type_empty[]; +extern const char xdg_mime_type_textplain[]; +#define XDG_MIME_TYPE_UNKNOWN xdg_mime_type_unknown +#define XDG_MIME_TYPE_EMPTY xdg_mime_type_empty +#define XDG_MIME_TYPE_TEXTPLAIN xdg_mime_type_textplain + +const char *xdg_mime_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio); +const char *xdg_mime_get_mime_type_for_file (const char *file_name, + struct stat *statbuf); +const char *xdg_mime_get_mime_type_from_file_name (const char *file_name); +int xdg_mime_get_mime_types_from_file_name(const char *file_name, + const char *mime_types[], + int n_mime_types); +int xdg_mime_is_valid_mime_type (const char *mime_type); +int xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b); +int xdg_mime_media_type_equal (const char *mime_a, + const char *mime_b); +int xdg_mime_mime_type_subclass (const char *mime_a, + const char *mime_b); + /* xdg_mime_get_mime_parents() is deprecated since it does + * not work correctly with caches. Use xdg_mime_list_parents() + * instead, but notice that that function expects you to free + * the array it returns. + */ +const char **xdg_mime_get_mime_parents (const char *mime); +char ** xdg_mime_list_mime_parents (const char *mime); +const char *xdg_mime_unalias_mime_type (const char *mime); +const char *xdg_mime_get_icon (const char *mime); +const char *xdg_mime_get_generic_icon (const char *mime); +int xdg_mime_get_max_buffer_extents (void); +void xdg_mime_shutdown (void); +void xdg_mime_dump (void); +int xdg_mime_register_reload_callback (XdgMimeCallback callback, + void *data, + XdgMimeDestroy destroy); +void xdg_mime_remove_callback (int callback_id); + +void xdg_mime_set_dirs (const char * const *dirs); + + /* Private versions of functions that don't call xdg_mime_init () */ +int _xdg_mime_mime_type_equal (const char *mime_a, + const char *mime_b); +int _xdg_mime_mime_type_subclass (const char *mime, + const char *base); +const char *_xdg_mime_unalias_mime_type (const char *mime); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __XDG_MIME_H__ */ diff --git a/gio/xdgmime/xdgmimealias.c b/gio/xdgmime/xdgmimealias.c new file mode 100644 index 0000000..0fc51f9 --- /dev/null +++ b/gio/xdgmime/xdgmimealias.c @@ -0,0 +1,184 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimealias.c: Private file. Datastructure for storing the aliases. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 2004 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimealias.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef struct XdgAlias XdgAlias; + +struct XdgAlias +{ + char *alias; + char *mime_type; +}; + +struct XdgAliasList +{ + struct XdgAlias *aliases; + int n_aliases; +}; + +XdgAliasList * +_xdg_mime_alias_list_new (void) +{ + XdgAliasList *list; + + list = malloc (sizeof (XdgAliasList)); + + list->aliases = NULL; + list->n_aliases = 0; + + return list; +} + +void +_xdg_mime_alias_list_free (XdgAliasList *list) +{ + int i; + + if (list->aliases) + { + for (i = 0; i < list->n_aliases; i++) + { + free (list->aliases[i].alias); + free (list->aliases[i].mime_type); + } + free (list->aliases); + } + free (list); +} + +static int +alias_entry_cmp (const void *v1, const void *v2) +{ + return strcmp (((XdgAlias *)v1)->alias, ((XdgAlias *)v2)->alias); +} + +const char * +_xdg_mime_alias_list_lookup (XdgAliasList *list, + const char *alias) +{ + XdgAlias *entry; + XdgAlias key; + + if (list->n_aliases > 0) + { + key.alias = (char *)alias; + key.mime_type = NULL; + + entry = bsearch (&key, list->aliases, list->n_aliases, + sizeof (XdgAlias), alias_entry_cmp); + if (entry) + return entry->mime_type; + } + + return NULL; +} + +void +_xdg_mime_alias_read_from_file (XdgAliasList *list, + const char *file_name) +{ + FILE *file; + char line[255]; + int alloc; + + file = fopen (file_name, "r"); + + if (file == NULL) + return; + + /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. + * Blah */ + alloc = list->n_aliases + 16; + list->aliases = realloc (list->aliases, alloc * sizeof (XdgAlias)); + while (fgets (line, 255, file) != NULL) + { + char *sep; + if (line[0] == '#') + continue; + + sep = strchr (line, ' '); + if (sep == NULL) + continue; + *(sep++) = '\000'; + sep[strlen (sep) -1] = '\000'; + if (list->n_aliases == alloc) + { + alloc <<= 1; + list->aliases = realloc (list->aliases, + alloc * sizeof (XdgAlias)); + } + list->aliases[list->n_aliases].alias = strdup (line); + list->aliases[list->n_aliases].mime_type = strdup (sep); + list->n_aliases++; + } + list->aliases = realloc (list->aliases, + list->n_aliases * sizeof (XdgAlias)); + + fclose (file); + + if (list->n_aliases > 1) + qsort (list->aliases, list->n_aliases, + sizeof (XdgAlias), alias_entry_cmp); +} + + +void +_xdg_mime_alias_list_dump (XdgAliasList *list) +{ + int i; + + if (list->aliases) + { + for (i = 0; i < list->n_aliases; i++) + { + printf ("%s %s\n", + list->aliases[i].alias, + list->aliases[i].mime_type); + } + } +} + + diff --git a/gio/xdgmime/xdgmimealias.h b/gio/xdgmime/xdgmimealias.h new file mode 100644 index 0000000..6e0cfff --- /dev/null +++ b/gio/xdgmime/xdgmimealias.h @@ -0,0 +1,51 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimealias.h: Private file. Datastructure for storing the aliases. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 200 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_ALIAS_H__ +#define __XDG_MIME_ALIAS_H__ + +#include "xdgmime.h" + +typedef struct XdgAliasList XdgAliasList; + +#ifdef XDG_PREFIX +#define _xdg_mime_alias_read_from_file XDG_RESERVED_ENTRY(alias_read_from_file) +#define _xdg_mime_alias_list_new XDG_RESERVED_ENTRY(alias_list_new) +#define _xdg_mime_alias_list_free XDG_RESERVED_ENTRY(alias_list_free) +#define _xdg_mime_alias_list_lookup XDG_RESERVED_ENTRY(alias_list_lookup) +#define _xdg_mime_alias_list_dump XDG_RESERVED_ENTRY(alias_list_dump) +#endif + +void _xdg_mime_alias_read_from_file (XdgAliasList *list, + const char *file_name); +XdgAliasList *_xdg_mime_alias_list_new (void); +void _xdg_mime_alias_list_free (XdgAliasList *list); +const char *_xdg_mime_alias_list_lookup (XdgAliasList *list, + const char *alias); +void _xdg_mime_alias_list_dump (XdgAliasList *list); + +#endif /* __XDG_MIME_ALIAS_H__ */ diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c new file mode 100644 index 0000000..234e4b4 --- /dev/null +++ b/gio/xdgmime/xdgmimecache.c @@ -0,0 +1,1165 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimealias.c: Private file. mmappable caches for mime data + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2005 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include /* for ntohl/ntohs */ + +#ifdef HAVE_MMAP +#include +#else +#warning Building xdgmime without MMAP support. Binary "mime.cache" files will not be used. +#endif + +#include +#include + +#include "xdgmimecache.h" +#include "xdgmimeint.h" + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#ifndef _O_BINARY +#define _O_BINARY 0 +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *) -1) +#endif + +#ifndef S_ISREG +#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif + +#define MAJOR_VERSION 1 +#define MINOR_VERSION_MIN 1 +#define MINOR_VERSION_MAX 2 + +struct _XdgMimeCache +{ + int ref_count; + int minor; + + size_t size; + char *buffer; +}; + +#define GET_UINT16(cache,offset) (ntohs(*(xdg_uint16_t*)((cache) + (offset)))) +#define GET_UINT32(cache,offset) (ntohl(*(xdg_uint32_t*)((cache) + (offset)))) + +XdgMimeCache * +_xdg_mime_cache_ref (XdgMimeCache *cache) +{ + cache->ref_count++; + return cache; +} + +void +_xdg_mime_cache_unref (XdgMimeCache *cache) +{ + cache->ref_count--; + + if (cache->ref_count == 0) + { +#ifdef HAVE_MMAP + munmap (cache->buffer, cache->size); +#endif + free (cache); + } +} + +XdgMimeCache * +_xdg_mime_cache_new_from_file (const char *file_name) +{ + XdgMimeCache *cache = NULL; + +#ifdef HAVE_MMAP + int fd = -1; + struct stat st; + char *buffer = NULL; + int minor; + + /* Open the file and map it into memory */ + do { + fd = open (file_name, O_RDONLY|_O_BINARY, 0); + } while (fd == -1 && errno == EINTR); + + if (fd < 0) + return NULL; + + if (fstat (fd, &st) < 0 || st.st_size < 4) + goto done; + + buffer = (char *) mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + + if (buffer == MAP_FAILED) + goto done; + + minor = GET_UINT16 (buffer, 2); + /* Verify version */ + if (GET_UINT16 (buffer, 0) != MAJOR_VERSION || + (minor < MINOR_VERSION_MIN || + minor > MINOR_VERSION_MAX)) + { + munmap (buffer, st.st_size); + + goto done; + } + + cache = (XdgMimeCache *) malloc (sizeof (XdgMimeCache)); + cache->minor = minor; + cache->ref_count = 1; + cache->buffer = buffer; + cache->size = st.st_size; + + done: + if (fd != -1) + close (fd); + +#else /* HAVE_MMAP */ + cache = (XdgMimeCache *) malloc (sizeof (XdgMimeCache)); + cache->minor = 0; + cache->ref_count = 1; + cache->buffer = NULL; + cache->size = 0; +#endif /* HAVE_MMAP */ + + return cache; +} + +static int +cache_magic_matchlet_compare_to_data (XdgMimeCache *cache, + xdg_uint32_t offset, + const void *data, + size_t len) +{ + xdg_uint32_t range_start = GET_UINT32 (cache->buffer, offset); + xdg_uint32_t range_length = GET_UINT32 (cache->buffer, offset + 4); + xdg_uint32_t data_length = GET_UINT32 (cache->buffer, offset + 12); + xdg_uint32_t data_offset = GET_UINT32 (cache->buffer, offset + 16); + xdg_uint32_t mask_offset = GET_UINT32 (cache->buffer, offset + 20); + + xdg_uint32_t i, j; + + for (i = range_start; i < range_start + range_length; i++) + { + int valid_matchlet = TRUE; + + if (i + data_length > len) + return FALSE; + + if (mask_offset) + { + for (j = 0; j < data_length; j++) + { + if ((((unsigned char *)cache->buffer)[data_offset + j] & ((unsigned char *)cache->buffer)[mask_offset + j]) != + ((((unsigned char *) data)[j + i]) & ((unsigned char *)cache->buffer)[mask_offset + j])) + { + valid_matchlet = FALSE; + break; + } + } + } + else + { + valid_matchlet = memcmp(cache->buffer + data_offset, (unsigned char *)data + i, data_length) == 0; + } + + if (valid_matchlet) + return TRUE; + } + + return FALSE; +} + +static int +cache_magic_matchlet_compare (XdgMimeCache *cache, + xdg_uint32_t offset, + const void *data, + size_t len) +{ + xdg_uint32_t n_children = GET_UINT32 (cache->buffer, offset + 24); + xdg_uint32_t child_offset = GET_UINT32 (cache->buffer, offset + 28); + + xdg_uint32_t i; + + if (cache_magic_matchlet_compare_to_data (cache, offset, data, len)) + { + if (n_children == 0) + return TRUE; + + for (i = 0; i < n_children; i++) + { + if (cache_magic_matchlet_compare (cache, child_offset + 32 * i, + data, len)) + return TRUE; + } + } + + return FALSE; +} + +static const char * +cache_magic_compare_to_data (XdgMimeCache *cache, + xdg_uint32_t offset, + const void *data, + size_t len, + int *prio) +{ + xdg_uint32_t priority = GET_UINT32 (cache->buffer, offset); + xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, offset + 4); + xdg_uint32_t n_matchlets = GET_UINT32 (cache->buffer, offset + 8); + xdg_uint32_t matchlet_offset = GET_UINT32 (cache->buffer, offset + 12); + + xdg_uint32_t i; + + for (i = 0; i < n_matchlets; i++) + { + if (cache_magic_matchlet_compare (cache, matchlet_offset + i * 32, + data, len)) + { + *prio = priority; + + return cache->buffer + mimetype_offset; + } + } + + return NULL; +} + +static const char * +cache_magic_lookup_data (XdgMimeCache *cache, + const void *data, + size_t len, + int *prio) +{ + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset; + + xdg_uint32_t j; + + *prio = 0; + + list_offset = GET_UINT32 (cache->buffer, 24); + n_entries = GET_UINT32 (cache->buffer, list_offset); + offset = GET_UINT32 (cache->buffer, list_offset + 8); + + for (j = 0; j < n_entries; j++) + { + const char *match; + + match = cache_magic_compare_to_data (cache, offset + 16 * j, + data, len, prio); + if (match) + return match; + } + + return NULL; +} + +static const char * +cache_alias_lookup (const char *alias) +{ + const char *ptr; + int i, min, max, mid, cmp; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset; + + if (cache->buffer == NULL) + continue; + + list_offset = GET_UINT32 (cache->buffer, 4); + n_entries = GET_UINT32 (cache->buffer, list_offset); + + min = 0; + max = n_entries - 1; + while (max >= min) + { + mid = (min + max) / 2; + + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid); + ptr = cache->buffer + offset; + cmp = strcmp (ptr, alias); + + if (cmp < 0) + min = mid + 1; + else if (cmp > 0) + max = mid - 1; + else + { + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4); + return cache->buffer + offset; + } + } + } + + return NULL; +} + +typedef struct { + const char *mime; + int weight; +} MimeWeight; + +static int +cache_glob_lookup_literal (const char *file_name, + const char *mime_types[], + int n_mime_types, + int case_sensitive_check) +{ + const char *ptr; + int i, min, max, mid, cmp; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset; + + if (cache->buffer == NULL) + continue; + + list_offset = GET_UINT32 (cache->buffer, 12); + n_entries = GET_UINT32 (cache->buffer, list_offset); + + min = 0; + max = n_entries - 1; + while (max >= min) + { + mid = (min + max) / 2; + + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid); + ptr = cache->buffer + offset; + cmp = strcmp (ptr, file_name); + + if (cmp < 0) + min = mid + 1; + else if (cmp > 0) + max = mid - 1; + else + { + int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 8); + int case_sensitive = weight & 0x100; + weight = weight & 0xff; + + if (case_sensitive_check || !case_sensitive) + { + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 4); + mime_types[0] = (const char *)(cache->buffer + offset); + + return 1; + } + return 0; + } + } + } + + return 0; +} + +static int +cache_glob_lookup_fnmatch (const char *file_name, + MimeWeight mime_types[], + int n_mime_types, + int case_sensitive_check) +{ + const char *mime_type; + const char *ptr; + + int i, n; + xdg_uint32_t j; + + n = 0; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + + if (cache->buffer == NULL) + continue; + + list_offset = GET_UINT32 (cache->buffer, 20); + n_entries = GET_UINT32 (cache->buffer, list_offset); + + for (j = 0; j < n_entries && n < n_mime_types; j++) + { + xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j); + xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 4); + int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 8); + int case_sensitive = weight & 0x100; + weight = weight & 0xff; + ptr = cache->buffer + offset; + mime_type = cache->buffer + mimetype_offset; + if (case_sensitive_check || !case_sensitive) + { + /* FIXME: Not UTF-8 safe */ + if (fnmatch (ptr, file_name, 0) == 0) + { + mime_types[n].mime = mime_type; + mime_types[n].weight = weight; + n++; + } + } + } + + if (n == n_mime_types) + break; + } + + return n; +} + +static int +cache_glob_node_lookup_suffix (XdgMimeCache *cache, + xdg_uint32_t n_entries, + xdg_uint32_t offset, + const char *file_name, + int len, + int case_sensitive_check, + MimeWeight mime_types[], + int n_mime_types) +{ + xdg_unichar_t character; + xdg_unichar_t match_char; + xdg_uint32_t mimetype_offset; + xdg_uint32_t n_children; + xdg_uint32_t child_offset; + int weight; + int case_sensitive; + + xdg_uint32_t i; + int min, max, mid, n; + + character = file_name[len - 1]; + + assert (character != 0); + + min = 0; + max = n_entries - 1; + while (max >= min) + { + mid = (min + max) / 2; + match_char = GET_UINT32 (cache->buffer, offset + 12 * mid); + if (match_char < character) + min = mid + 1; + else if (match_char > character) + max = mid - 1; + else + { + len--; + n = 0; + n_children = GET_UINT32 (cache->buffer, offset + 12 * mid + 4); + child_offset = GET_UINT32 (cache->buffer, offset + 12 * mid + 8); + + if (len > 0) + { + n = cache_glob_node_lookup_suffix (cache, + n_children, child_offset, + file_name, len, + case_sensitive_check, + mime_types, + n_mime_types); + } + if (n == 0) + { + i = 0; + while (n < n_mime_types && i < n_children) + { + match_char = GET_UINT32 (cache->buffer, child_offset + 12 * i); + if (match_char != 0) + break; + + mimetype_offset = GET_UINT32 (cache->buffer, child_offset + 12 * i + 4); + weight = GET_UINT32 (cache->buffer, child_offset + 12 * i + 8); + case_sensitive = weight & 0x100; + weight = weight & 0xff; + + if (case_sensitive_check || !case_sensitive) + { + mime_types[n].mime = cache->buffer + mimetype_offset; + mime_types[n].weight = weight; + n++; + } + i++; + } + } + return n; + } + } + return 0; +} + +static int +cache_glob_lookup_suffix (const char *file_name, + int len, + int ignore_case, + MimeWeight mime_types[], + int n_mime_types) +{ + int i, n; + + n = 0; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset; + + if (cache->buffer == NULL) + continue; + + list_offset = GET_UINT32 (cache->buffer, 16); + n_entries = GET_UINT32 (cache->buffer, list_offset); + offset = GET_UINT32 (cache->buffer, list_offset + 4); + + n += cache_glob_node_lookup_suffix (cache, + n_entries, offset, + file_name, len, + ignore_case, + mime_types + n, + n_mime_types - n); + if (n == n_mime_types) + break; + } + + return n; +} + +static int compare_mime_weight (const void *a, const void *b) +{ + const MimeWeight *aa = (const MimeWeight *)a; + const MimeWeight *bb = (const MimeWeight *)b; + + return bb->weight - aa->weight; +} + +#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') +static char * +ascii_tolower (const char *str) +{ + char *p, *lower; + + lower = strdup (str); + p = lower; + while (*p != 0) + { + char c = *p; + *p++ = ISUPPER (c) ? c - 'A' + 'a' : c; + } + return lower; +} + +static int +filter_out_dupes (MimeWeight mimes[], int n_mimes) +{ + int last; + int i, j; + + last = n_mimes; + + for (i = 0; i < last; i++) + { + j = i + 1; + while (j < last) + { + if (strcmp (mimes[i].mime, mimes[j].mime) == 0) + { + mimes[i].weight = MAX (mimes[i].weight, mimes[j].weight); + last--; + mimes[j].mime = mimes[last].mime; + mimes[j].weight = mimes[last].weight; + } + else + j++; + } + } + + return last; +} + +static int +cache_glob_lookup_file_name (const char *file_name, + const char *mime_types[], + int n_mime_types) +{ + int n; + MimeWeight mimes[10]; + int n_mimes = 10; + int i; + int len; + char *lower_case; + + assert (file_name != NULL && n_mime_types > 0); + + /* First, check the literals */ + + lower_case = ascii_tolower (file_name); + + n = cache_glob_lookup_literal (lower_case, mime_types, n_mime_types, FALSE); + if (n > 0) + { + free (lower_case); + return n; + } + + n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types, TRUE); + if (n > 0) + { + free (lower_case); + return n; + } + + len = strlen (file_name); + n = cache_glob_lookup_suffix (lower_case, len, FALSE, mimes, n_mimes); + if (n < 2) + n += cache_glob_lookup_suffix (file_name, len, TRUE, mimes + n, n_mimes - n); + + /* Last, try fnmatch */ + if (n == 0) + n = cache_glob_lookup_fnmatch (lower_case, mimes, n_mimes, FALSE); + if (n < 2) + n += cache_glob_lookup_fnmatch (file_name, mimes + n, n_mimes - n, TRUE); + + n = filter_out_dupes (mimes, n); + + free (lower_case); + + qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); + + if (n_mime_types < n) + n = n_mime_types; + + for (i = 0; i < n; i++) + mime_types[i] = mimes[i].mime; + + return n; +} + +int +_xdg_mime_cache_get_max_buffer_extents (void) +{ + xdg_uint32_t offset; + xdg_uint32_t max_extent; + int i; + + max_extent = 0; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + if (cache->buffer == NULL) + continue; + + offset = GET_UINT32 (cache->buffer, 24); + max_extent = MAX (max_extent, GET_UINT32 (cache->buffer, offset + 4)); + } + + return max_extent; +} + +static const char * +cache_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio, + const char *mime_types[], + int n_mime_types) +{ + const char *mime_type; + int i, n, priority; + + priority = 0; + mime_type = NULL; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + + int prio; + const char *match; + + if (cache->buffer == NULL) + continue; + + match = cache_magic_lookup_data (cache, data, len, &prio); + if (prio > priority) + { + priority = prio; + mime_type = match; + } + } + + if (result_prio) + *result_prio = priority; + + if (priority > 0) + { + /* Pick glob-result R where mime_type inherits from R */ + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n] && _xdg_mime_cache_mime_type_subclass(mime_types[n], mime_type)) + return mime_types[n]; + } + if (n == 0) + { + /* No globs: return magic match */ + return mime_type; + } + } + + /* Pick first glob result, as fallback */ + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n]) + return mime_types[n]; + } + + return NULL; +} + +const char * +_xdg_mime_cache_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio) +{ + return cache_get_mime_type_for_data (data, len, result_prio, NULL, 0); +} + +const char * +_xdg_mime_cache_get_mime_type_for_file (const char *file_name, + struct stat *statbuf) +{ + const char *mime_type; + const char *mime_types[10]; + FILE *file; + unsigned char *data; + int max_extent; + int bytes_read; + struct stat buf; + const char *base_name; + int n; + + if (file_name == NULL) + return NULL; + + if (! _xdg_utf8_validate (file_name)) + return NULL; + + base_name = _xdg_get_base_name (file_name); + n = cache_glob_lookup_file_name (base_name, mime_types, 10); + + if (n == 1) + return mime_types[0]; + + if (!statbuf) + { + if (stat (file_name, &buf) != 0) + return XDG_MIME_TYPE_UNKNOWN; + + statbuf = &buf; + } + + if (statbuf->st_size == 0) + return XDG_MIME_TYPE_EMPTY; + + if (!S_ISREG (statbuf->st_mode)) + return XDG_MIME_TYPE_UNKNOWN; + + /* FIXME: Need to make sure that max_extent isn't totally broken. This could + * be large and need getting from a stream instead of just reading it all + * in. */ + max_extent = _xdg_mime_cache_get_max_buffer_extents (); + data = malloc (max_extent); + if (data == NULL) + return XDG_MIME_TYPE_UNKNOWN; + + file = fopen (file_name, "r"); + if (file == NULL) + { + free (data); + return XDG_MIME_TYPE_UNKNOWN; + } + + bytes_read = fread (data, 1, max_extent, file); + if (ferror (file)) + { + free (data); + fclose (file); + return XDG_MIME_TYPE_UNKNOWN; + } + + mime_type = cache_get_mime_type_for_data (data, bytes_read, NULL, + mime_types, n); + + if (!mime_type) + mime_type = _xdg_binary_or_text_fallback (data, bytes_read); + + free (data); + fclose (file); + + return mime_type; +} + +const char * +_xdg_mime_cache_get_mime_type_from_file_name (const char *file_name) +{ + const char *mime_type; + + if (cache_glob_lookup_file_name (file_name, &mime_type, 1)) + return mime_type; + else + return XDG_MIME_TYPE_UNKNOWN; +} + +int +_xdg_mime_cache_get_mime_types_from_file_name (const char *file_name, + const char *mime_types[], + int n_mime_types) +{ + return cache_glob_lookup_file_name (file_name, mime_types, n_mime_types); +} + +#if 1 +static int +ends_with (const char *str, + const char *suffix) +{ + int length; + int suffix_length; + + length = strlen (str); + suffix_length = strlen (suffix); + if (length < suffix_length) + return 0; + + if (strcmp (str + length - suffix_length, suffix) == 0) + return 1; + + return 0; +} + +static int +is_super_type (const char *mime) +{ + return ends_with (mime, "/*"); +} +#endif + +int +_xdg_mime_cache_mime_type_subclass (const char *mime, + const char *base) +{ + const char *umime, *ubase; + + xdg_uint32_t j; + int i, min, max, med, cmp; + + umime = _xdg_mime_cache_unalias_mime_type (mime); + ubase = _xdg_mime_cache_unalias_mime_type (base); + + if (strcmp (umime, ubase) == 0) + return 1; + + /* We really want to handle text/ * in GtkFileFilter, so we just + * turn on the supertype matching + */ +#if 1 + /* Handle supertypes */ + if (is_super_type (ubase) && + xdg_mime_media_type_equal (umime, ubase)) + return 1; +#endif + + /* Handle special cases text/plain and application/octet-stream */ + if (strcmp (ubase, "text/plain") == 0 && + strncmp (umime, "text/", 5) == 0) + return 1; + + if (strcmp (ubase, "application/octet-stream") == 0 && + strncmp (umime, "inode/", 6) != 0) + return 1; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset, n_parents, parent_offset; + + if (cache->buffer == NULL) + continue; + + list_offset = GET_UINT32 (cache->buffer, 8); + n_entries = GET_UINT32 (cache->buffer, list_offset); + + min = 0; + max = n_entries - 1; + while (max >= min) + { + med = (min + max)/2; + + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * med); + cmp = strcmp (cache->buffer + offset, umime); + if (cmp < 0) + min = med + 1; + else if (cmp > 0) + max = med - 1; + else + { + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * med + 4); + n_parents = GET_UINT32 (cache->buffer, offset); + + for (j = 0; j < n_parents; j++) + { + parent_offset = GET_UINT32 (cache->buffer, offset + 4 + 4 * j); + if (strcmp (cache->buffer + parent_offset, mime) != 0 && + strcmp (cache->buffer + parent_offset, umime) != 0 && + _xdg_mime_cache_mime_type_subclass (cache->buffer + parent_offset, ubase)) + return 1; + } + + break; + } + } + } + + return 0; +} + +const char * +_xdg_mime_cache_unalias_mime_type (const char *mime) +{ + const char *lookup; + + lookup = cache_alias_lookup (mime); + + if (lookup) + return lookup; + + return mime; +} + +char ** +_xdg_mime_cache_list_mime_parents (const char *mime) +{ + int i, l, p; + xdg_uint32_t j, k; + char *all_parents[128]; /* we'll stop at 128 */ + char **result; + + mime = xdg_mime_unalias_mime_type (mime); + + p = 0; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + + if (cache->buffer == NULL) + continue; + + list_offset = GET_UINT32 (cache->buffer, 8); + n_entries = GET_UINT32 (cache->buffer, list_offset); + + for (j = 0; j < n_entries; j++) + { + xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j); + xdg_uint32_t parents_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j + 4); + + if (strcmp (cache->buffer + mimetype_offset, mime) == 0) + { + xdg_uint32_t parent_mime_offset; + xdg_uint32_t n_parents = GET_UINT32 (cache->buffer, parents_offset); + + for (k = 0; k < n_parents && p < 127; k++) + { + parent_mime_offset = GET_UINT32 (cache->buffer, parents_offset + 4 + 4 * k); + + /* Don't add same parent multiple times. + * This can happen for instance if the same type is listed in multiple directories + */ + for (l = 0; l < p; l++) + { + if (strcmp (all_parents[l], cache->buffer + parent_mime_offset) == 0) + break; + } + + if (l == p) + all_parents[p++] = cache->buffer + parent_mime_offset; + } + + break; + } + } + } + all_parents[p++] = NULL; + + result = (char **) malloc (p * sizeof (char *)); + memcpy (result, all_parents, p * sizeof (char *)); + + return result; +} + +static const char * +cache_lookup_icon (const char *mime, int header) +{ + const char *ptr; + int i, min, max, mid, cmp; + + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset; + + if (cache->buffer == NULL) + continue; + + list_offset = GET_UINT32 (cache->buffer, header); + n_entries = GET_UINT32 (cache->buffer, list_offset); + + min = 0; + max = n_entries - 1; + while (max >= min) + { + mid = (min + max) / 2; + + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid); + ptr = cache->buffer + offset; + cmp = strcmp (ptr, mime); + + if (cmp < 0) + min = mid + 1; + else if (cmp > 0) + max = mid - 1; + else + { + offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4); + return cache->buffer + offset; + } + } + } + + return NULL; +} + +const char * +_xdg_mime_cache_get_generic_icon (const char *mime) +{ + return cache_lookup_icon (mime, 36); +} + +const char * +_xdg_mime_cache_get_icon (const char *mime) +{ + return cache_lookup_icon (mime, 32); +} + +static void +dump_glob_node (XdgMimeCache *cache, + xdg_uint32_t offset, + int depth) +{ + xdg_unichar_t character; + xdg_uint32_t mime_offset; + xdg_uint32_t n_children; + xdg_uint32_t child_offset; + xdg_uint32_t k; + int i; + + character = GET_UINT32 (cache->buffer, offset); + mime_offset = GET_UINT32 (cache->buffer, offset + 4); + n_children = GET_UINT32 (cache->buffer, offset + 8); + child_offset = GET_UINT32 (cache->buffer, offset + 12); + for (i = 0; i < depth; i++) + printf (" "); + printf ("%c", character); + if (mime_offset) + printf (" - %s", cache->buffer + mime_offset); + printf ("\n"); + if (child_offset) + { + for (k = 0; k < n_children; k++) + dump_glob_node (cache, child_offset + 20 * k, depth + 1); + } +} + +void +_xdg_mime_cache_glob_dump (void) +{ + xdg_uint32_t i, j; + for (i = 0; _caches[i]; i++) + { + XdgMimeCache *cache = _caches[i]; + xdg_uint32_t list_offset; + xdg_uint32_t n_entries; + xdg_uint32_t offset; + + if (cache->buffer == NULL) + continue; + + list_offset = GET_UINT32 (cache->buffer, 16); + n_entries = GET_UINT32 (cache->buffer, list_offset); + offset = GET_UINT32 (cache->buffer, list_offset + 4); + for (j = 0; j < n_entries; j++) + dump_glob_node (cache, offset + 20 * j, 0); + } +} + + diff --git a/gio/xdgmime/xdgmimecache.h b/gio/xdgmime/xdgmimecache.h new file mode 100644 index 0000000..df25b2a --- /dev/null +++ b/gio/xdgmime/xdgmimecache.h @@ -0,0 +1,81 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimecache.h: Private file. Datastructure for mmapped caches. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2005 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_CACHE_H__ +#define __XDG_MIME_CACHE_H__ + +#include "xdgmime.h" + +typedef struct _XdgMimeCache XdgMimeCache; + +#ifdef XDG_PREFIX +#define _xdg_mime_cache_new_from_file XDG_RESERVED_ENTRY(cache_new_from_file) +#define _xdg_mime_cache_ref XDG_RESERVED_ENTRY(cache_ref) +#define _xdg_mime_cache_unref XDG_RESERVED_ENTRY(cache_unref) +#define _xdg_mime_cache_get_max_buffer_extents XDG_RESERVED_ENTRY(cache_get_max_buffer_extents) +#define _xdg_mime_cache_get_mime_type_for_data XDG_RESERVED_ENTRY(cache_get_mime_type_for_data) +#define _xdg_mime_cache_get_mime_type_for_file XDG_RESERVED_ENTRY(cache_get_mime_type_for_file) +#define _xdg_mime_cache_get_mime_type_from_file_name XDG_RESERVED_ENTRY(cache_get_mime_type_from_file_name) +#define _xdg_mime_cache_get_mime_types_from_file_name XDG_RESERVED_ENTRY(cache_get_mime_types_from_file_name) +#define _xdg_mime_cache_list_mime_parents XDG_RESERVED_ENTRY(cache_list_mime_parents) +#define _xdg_mime_cache_mime_type_subclass XDG_RESERVED_ENTRY(cache_mime_type_subclass) +#define _xdg_mime_cache_unalias_mime_type XDG_RESERVED_ENTRY(cache_unalias_mime_type) +#define _xdg_mime_cache_get_icon XDG_RESERVED_ENTRY(cache_get_icon) +#define _xdg_mime_cache_get_generic_icon XDG_RESERVED_ENTRY(cache_get_generic_icon) +#define _xdg_mime_cache_glob_dump XDG_RESERVED_ENTRY(cache_glob_dump) +#endif + +extern XdgMimeCache **_caches; + +XdgMimeCache *_xdg_mime_cache_new_from_file (const char *file_name); +XdgMimeCache *_xdg_mime_cache_ref (XdgMimeCache *cache); +void _xdg_mime_cache_unref (XdgMimeCache *cache); + + +const char *_xdg_mime_cache_get_mime_type_for_data (const void *data, + size_t len, + int *result_prio); +const char *_xdg_mime_cache_get_mime_type_for_file (const char *file_name, + struct stat *statbuf); +int _xdg_mime_cache_get_mime_types_from_file_name (const char *file_name, + const char *mime_types[], + int n_mime_types); +const char *_xdg_mime_cache_get_mime_type_from_file_name (const char *file_name); +int _xdg_mime_cache_is_valid_mime_type (const char *mime_type); +int _xdg_mime_cache_mime_type_equal (const char *mime_a, + const char *mime_b); +int _xdg_mime_cache_media_type_equal (const char *mime_a, + const char *mime_b); +int _xdg_mime_cache_mime_type_subclass (const char *mime_a, + const char *mime_b); +char **_xdg_mime_cache_list_mime_parents (const char *mime); +const char *_xdg_mime_cache_unalias_mime_type (const char *mime); +int _xdg_mime_cache_get_max_buffer_extents (void); +const char *_xdg_mime_cache_get_icon (const char *mime); +const char *_xdg_mime_cache_get_generic_icon (const char *mime); +void _xdg_mime_cache_glob_dump (void); + +#endif /* __XDG_MIME_CACHE_H__ */ diff --git a/gio/xdgmime/xdgmimeglob.c b/gio/xdgmime/xdgmimeglob.c new file mode 100644 index 0000000..d68435c --- /dev/null +++ b/gio/xdgmime/xdgmimeglob.c @@ -0,0 +1,725 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeglob.c: Private file. Datastructure for storing the globs. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimeglob.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef struct XdgGlobHashNode XdgGlobHashNode; +typedef struct XdgGlobList XdgGlobList; + +struct XdgGlobHashNode +{ + xdg_unichar_t character; + const char *mime_type; + int weight; + int case_sensitive; + XdgGlobHashNode *next; + XdgGlobHashNode *child; +}; +struct XdgGlobList +{ + const char *data; + const char *mime_type; + int weight; + int case_sensitive; + XdgGlobList *next; +}; + +struct XdgGlobHash +{ + XdgGlobList *literal_list; + XdgGlobHashNode *simple_node; + XdgGlobList *full_list; +}; + + +/* XdgGlobList + */ +static XdgGlobList * +_xdg_glob_list_new (void) +{ + XdgGlobList *new_element; + + new_element = calloc (1, sizeof (XdgGlobList)); + + return new_element; +} + +/* Frees glob_list and all of its children */ +static void +_xdg_glob_list_free (XdgGlobList *glob_list) +{ + XdgGlobList *ptr, *next; + + ptr = glob_list; + + while (ptr != NULL) + { + next = ptr->next; + + if (ptr->data) + free ((void *) ptr->data); + if (ptr->mime_type) + free ((void *) ptr->mime_type); + free (ptr); + + ptr = next; + } +} + +static XdgGlobList * +_xdg_glob_list_append (XdgGlobList *glob_list, + void *data, + const char *mime_type, + int weight, + int case_sensitive) +{ + XdgGlobList *new_element; + XdgGlobList *tmp_element; + + tmp_element = glob_list; + while (tmp_element != NULL) + { + if (strcmp (tmp_element->data, data) == 0 && + strcmp (tmp_element->mime_type, mime_type) == 0) + return glob_list; + + tmp_element = tmp_element->next; + } + + new_element = _xdg_glob_list_new (); + new_element->data = data; + new_element->mime_type = mime_type; + new_element->weight = weight; + new_element->case_sensitive = case_sensitive; + if (glob_list == NULL) + return new_element; + + tmp_element = glob_list; + while (tmp_element->next != NULL) + tmp_element = tmp_element->next; + + tmp_element->next = new_element; + + return glob_list; +} + +/* XdgGlobHashNode + */ + +static XdgGlobHashNode * +_xdg_glob_hash_node_new (void) +{ + XdgGlobHashNode *glob_hash_node; + + glob_hash_node = calloc (1, sizeof (XdgGlobHashNode)); + + return glob_hash_node; +} + +static void +_xdg_glob_hash_node_dump (XdgGlobHashNode *glob_hash_node, + int depth) +{ + int i; + for (i = 0; i < depth; i++) + printf (" "); + + printf ("%c", (char)glob_hash_node->character); + if (glob_hash_node->mime_type) + printf (" - %s %d\n", glob_hash_node->mime_type, glob_hash_node->weight); + else + printf ("\n"); + if (glob_hash_node->child) + _xdg_glob_hash_node_dump (glob_hash_node->child, depth + 1); + if (glob_hash_node->next) + _xdg_glob_hash_node_dump (glob_hash_node->next, depth); +} + +static XdgGlobHashNode * +_xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node, + xdg_unichar_t *text, + const char *mime_type, + int weight, + int case_sensitive) +{ + XdgGlobHashNode *node; + xdg_unichar_t character; + + character = text[0]; + + if ((glob_hash_node == NULL) || + (character < glob_hash_node->character)) + { + node = _xdg_glob_hash_node_new (); + node->character = character; + node->next = glob_hash_node; + glob_hash_node = node; + } + else if (character == glob_hash_node->character) + { + node = glob_hash_node; + } + else + { + XdgGlobHashNode *prev_node; + int found_node = FALSE; + + /* Look for the first character of text in glob_hash_node, and insert it if we + * have to.*/ + prev_node = glob_hash_node; + node = prev_node->next; + + while (node != NULL) + { + if (character < node->character) + { + node = _xdg_glob_hash_node_new (); + node->character = character; + node->next = prev_node->next; + prev_node->next = node; + + found_node = TRUE; + break; + } + else if (character == node->character) + { + found_node = TRUE; + break; + } + prev_node = node; + node = node->next; + } + + if (! found_node) + { + node = _xdg_glob_hash_node_new (); + node->character = character; + node->next = prev_node->next; + prev_node->next = node; + } + } + + text++; + if (*text == 0) + { + if (node->mime_type) + { + if (strcmp (node->mime_type, mime_type) != 0) + { + XdgGlobHashNode *child; + int found_node = FALSE; + + child = node->child; + while (child && child->character == 0) + { + if (strcmp (child->mime_type, mime_type) == 0) + { + found_node = TRUE; + break; + } + child = child->next; + } + + if (!found_node) + { + child = _xdg_glob_hash_node_new (); + child->character = 0; + child->mime_type = strdup (mime_type); + child->weight = weight; + child->case_sensitive = case_sensitive; + child->child = NULL; + child->next = node->child; + node->child = child; + } + } + } + else + { + node->mime_type = strdup (mime_type); + node->weight = weight; + node->case_sensitive = case_sensitive; + } + } + else + { + node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, weight, case_sensitive); + } + return glob_hash_node; +} + +/* glob must be valid UTF-8 */ +static XdgGlobHashNode * +_xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node, + const char *text, + const char *mime_type, + int weight, + int case_sensitive) +{ + XdgGlobHashNode *node; + xdg_unichar_t *unitext; + int len; + + unitext = _xdg_convert_to_ucs4 (text, &len); + _xdg_reverse_ucs4 (unitext, len); + node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight, case_sensitive); + free (unitext); + return node; +} + +typedef struct { + const char *mime; + int weight; +} MimeWeight; + +static int +_xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node, + const char *file_name, + int len, + int case_sensitive_check, + MimeWeight mime_types[], + int n_mime_types) +{ + int n; + XdgGlobHashNode *node; + xdg_unichar_t character; + + if (glob_hash_node == NULL) + return 0; + + character = file_name[len - 1]; + + for (node = glob_hash_node; node && character >= node->character; node = node->next) + { + if (character == node->character) + { + len--; + n = 0; + if (len > 0) + { + n = _xdg_glob_hash_node_lookup_file_name (node->child, + file_name, + len, + case_sensitive_check, + mime_types, + n_mime_types); + } + if (n == 0) + { + if (node->mime_type && + (case_sensitive_check || + !node->case_sensitive)) + { + mime_types[n].mime = node->mime_type; + mime_types[n].weight = node->weight; + n++; + } + node = node->child; + while (n < n_mime_types && node && node->character == 0) + { + if (node->mime_type && + (case_sensitive_check || + !node->case_sensitive)) + { + mime_types[n].mime = node->mime_type; + mime_types[n].weight = node->weight; + n++; + } + node = node->next; + } + } + return n; + } + } + + return 0; +} + +static int compare_mime_weight (const void *a, const void *b) +{ + const MimeWeight *aa = (const MimeWeight *)a; + const MimeWeight *bb = (const MimeWeight *)b; + + return bb->weight - aa->weight; +} + +#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') +static char * +ascii_tolower (const char *str) +{ + char *p, *lower; + + lower = strdup (str); + p = lower; + while (*p != 0) + { + char c = *p; + *p++ = ISUPPER (c) ? c - 'A' + 'a' : c; + } + return lower; +} + +static int +filter_out_dupes (MimeWeight mimes[], int n_mimes) +{ + int last; + int i, j; + + last = n_mimes; + + for (i = 0; i < last; i++) + { + j = i + 1; + while (j < last) + { + if (strcmp (mimes[i].mime, mimes[j].mime) == 0) + { + mimes[i].weight = MAX (mimes[i].weight, mimes[j].weight); + last--; + mimes[j].mime = mimes[last].mime; + mimes[j].weight = mimes[last].weight; + } + else + j++; + } + } + + return last; +} + +int +_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, + const char *file_name, + const char *mime_types[], + int n_mime_types) +{ + XdgGlobList *list; + int i, n; + MimeWeight mimes[10]; + int n_mimes = 10; + int len; + char *lower_case; + + /* First, check the literals */ + + assert (file_name != NULL && n_mime_types > 0); + + n = 0; + + lower_case = ascii_tolower (file_name); + + for (list = glob_hash->literal_list; list; list = list->next) + { + if (strcmp ((const char *)list->data, file_name) == 0) + { + mime_types[0] = list->mime_type; + free (lower_case); + return 1; + } + } + + for (list = glob_hash->literal_list; list; list = list->next) + { + if (!list->case_sensitive && + strcmp ((const char *)list->data, lower_case) == 0) + { + mime_types[0] = list->mime_type; + free (lower_case); + return 1; + } + } + + + len = strlen (file_name); + n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case, len, FALSE, + mimes, n_mimes); + if (n < 2) + n += _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE, + mimes + n, n_mimes - n); + + if (n < 2) + { + for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next) + { + if (fnmatch ((const char *)list->data, file_name, 0) == 0) + { + mimes[n].mime = list->mime_type; + mimes[n].weight = list->weight; + n++; + } + } + } + free (lower_case); + + n = filter_out_dupes (mimes, n); + + qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight); + + if (n_mime_types < n) + n = n_mime_types; + + for (i = 0; i < n; i++) + mime_types[i] = mimes[i].mime; + + return n; +} + + + +/* XdgGlobHash + */ + +XdgGlobHash * +_xdg_glob_hash_new (void) +{ + XdgGlobHash *glob_hash; + + glob_hash = calloc (1, sizeof (XdgGlobHash)); + + return glob_hash; +} + + +static void +_xdg_glob_hash_free_nodes (XdgGlobHashNode *node) +{ + if (node) + { + if (node->child) + _xdg_glob_hash_free_nodes (node->child); + if (node->next) + _xdg_glob_hash_free_nodes (node->next); + if (node->mime_type) + free ((void *) node->mime_type); + free (node); + } +} + +void +_xdg_glob_hash_free (XdgGlobHash *glob_hash) +{ + _xdg_glob_list_free (glob_hash->literal_list); + _xdg_glob_list_free (glob_hash->full_list); + _xdg_glob_hash_free_nodes (glob_hash->simple_node); + free (glob_hash); +} + +XdgGlobType +_xdg_glob_determine_type (const char *glob) +{ + const char *ptr; + int maybe_in_simple_glob = FALSE; + int first_char = TRUE; + + ptr = glob; + + while (*ptr != '\0') + { + if (*ptr == '*' && first_char) + maybe_in_simple_glob = TRUE; + else if (*ptr == '\\' || *ptr == '[' || *ptr == '?' || *ptr == '*') + return XDG_GLOB_FULL; + + first_char = FALSE; + ptr = _xdg_utf8_next_char (ptr); + } + if (maybe_in_simple_glob) + return XDG_GLOB_SIMPLE; + else + return XDG_GLOB_LITERAL; +} + +/* glob must be valid UTF-8 */ +void +_xdg_glob_hash_append_glob (XdgGlobHash *glob_hash, + const char *glob, + const char *mime_type, + int weight, + int case_sensitive) +{ + XdgGlobType type; + + assert (glob_hash != NULL); + assert (glob != NULL); + + type = _xdg_glob_determine_type (glob); + + switch (type) + { + case XDG_GLOB_LITERAL: + glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type), weight, case_sensitive); + break; + case XDG_GLOB_SIMPLE: + glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, mime_type, weight, case_sensitive); + break; + case XDG_GLOB_FULL: + glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type), weight, case_sensitive); + break; + } +} + +void +_xdg_glob_hash_dump (XdgGlobHash *glob_hash) +{ + XdgGlobList *list; + printf ("LITERAL STRINGS\n"); + if (!glob_hash || glob_hash->literal_list == NULL) + { + printf (" None\n"); + } + else + { + for (list = glob_hash->literal_list; list; list = list->next) + printf (" %s - %s %d\n", (char *)list->data, list->mime_type, list->weight); + } + printf ("\nSIMPLE GLOBS\n"); + if (!glob_hash || glob_hash->simple_node == NULL) + { + printf (" None\n"); + } + else + { + _xdg_glob_hash_node_dump (glob_hash->simple_node, 4); + } + + printf ("\nFULL GLOBS\n"); + if (!glob_hash || glob_hash->full_list == NULL) + { + printf (" None\n"); + } + else + { + for (list = glob_hash->full_list; list; list = list->next) + printf (" %s - %s %d\n", (char *)list->data, list->mime_type, list->weight); + } +} + + +void +_xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash, + const char *file_name, + int version_two) +{ + FILE *glob_file; + char line[255]; + char *p; + + glob_file = fopen (file_name, "r"); + + if (glob_file == NULL) + return; + + /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. + * Blah */ + while (fgets (line, 255, glob_file) != NULL) + { + char *colon; + char *mimetype, *glob, *end; + int weight; + int case_sensitive; + + if (line[0] == '#' || line[0] == 0) + continue; + + end = line + strlen(line) - 1; + if (*end == '\n') + *end = 0; + + p = line; + if (version_two) + { + colon = strchr (p, ':'); + if (colon == NULL) + continue; + *colon = 0; + weight = atoi (p); + p = colon + 1; + } + else + weight = 50; + + colon = strchr (p, ':'); + if (colon == NULL) + continue; + *colon = 0; + + mimetype = p; + p = colon + 1; + glob = p; + case_sensitive = FALSE; + + colon = strchr (p, ':'); + if (version_two && colon != NULL) + { + char *flag; + + /* We got flags */ + *colon = 0; + p = colon + 1; + + /* Flags end at next colon */ + colon = strchr (p, ':'); + if (colon != NULL) + *colon = 0; + + flag = strstr (p, "cs"); + if (flag != NULL && + /* Start or after comma */ + (flag == p || + flag[-1] == ',') && + /* ends with comma or end of string */ + (flag[2] == 0 || + flag[2] == ',')) + case_sensitive = TRUE; + } + + _xdg_glob_hash_append_glob (glob_hash, glob, mimetype, weight, case_sensitive); + } + + fclose (glob_file); +} diff --git a/gio/xdgmime/xdgmimeglob.h b/gio/xdgmime/xdgmimeglob.h new file mode 100644 index 0000000..8b1fa3a --- /dev/null +++ b/gio/xdgmime/xdgmimeglob.h @@ -0,0 +1,70 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeglob.h: Private file. Datastructure for storing the globs. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_GLOB_H__ +#define __XDG_MIME_GLOB_H__ + +#include "xdgmime.h" + +typedef struct XdgGlobHash XdgGlobHash; + +typedef enum +{ + XDG_GLOB_LITERAL, /* Makefile */ + XDG_GLOB_SIMPLE, /* *.gif */ + XDG_GLOB_FULL /* x*.[ch] */ +} XdgGlobType; + + +#ifdef XDG_PREFIX +#define _xdg_mime_glob_read_from_file XDG_RESERVED_ENTRY(glob_read_from_file) +#define _xdg_glob_hash_new XDG_RESERVED_ENTRY(hash_new) +#define _xdg_glob_hash_free XDG_RESERVED_ENTRY(hash_free) +#define _xdg_glob_hash_lookup_file_name XDG_RESERVED_ENTRY(hash_lookup_file_name) +#define _xdg_glob_hash_append_glob XDG_RESERVED_ENTRY(hash_append_glob) +#define _xdg_glob_determine_type XDG_RESERVED_ENTRY(determine_type) +#define _xdg_glob_hash_dump XDG_RESERVED_ENTRY(hash_dump) +#endif + +void _xdg_mime_glob_read_from_file (XdgGlobHash *glob_hash, + const char *file_name, + int version_two); +XdgGlobHash *_xdg_glob_hash_new (void); +void _xdg_glob_hash_free (XdgGlobHash *glob_hash); +int _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash, + const char *text, + const char *mime_types[], + int n_mime_types); +void _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash, + const char *glob, + const char *mime_type, + int weight, + int case_sensitive); +XdgGlobType _xdg_glob_determine_type (const char *glob); +void _xdg_glob_hash_dump (XdgGlobHash *glob_hash); + +#endif /* __XDG_MIME_GLOB_H__ */ diff --git a/gio/xdgmime/xdgmimeicon.c b/gio/xdgmime/xdgmimeicon.c new file mode 100644 index 0000000..feb6c86 --- /dev/null +++ b/gio/xdgmime/xdgmimeicon.c @@ -0,0 +1,183 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeicon.c: Private file. Datastructure for storing the aliases. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2008 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimeicon.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef struct XdgIcon XdgIcon; + +struct XdgIcon +{ + char *mime_type; + char *icon_name; +}; + +struct XdgIconList +{ + struct XdgIcon *icons; + int n_icons; +}; + +XdgIconList * +_xdg_mime_icon_list_new (void) +{ + XdgIconList *list; + + list = malloc (sizeof (XdgIconList)); + + list->icons = NULL; + list->n_icons = 0; + + return list; +} + +void +_xdg_mime_icon_list_free (XdgIconList *list) +{ + int i; + + if (list->icons) + { + for (i = 0; i < list->n_icons; i++) + { + free (list->icons[i].mime_type); + free (list->icons[i].icon_name); + } + free (list->icons); + } + free (list); +} + +static int +icon_entry_cmp (const void *v1, const void *v2) +{ + return strcmp (((XdgIcon *)v1)->mime_type, ((XdgIcon *)v2)->mime_type); +} + +const char * +_xdg_mime_icon_list_lookup (XdgIconList *list, + const char *mime_type) +{ + XdgIcon *entry; + XdgIcon key; + + if (list->n_icons > 0) + { + key.mime_type = (char *)mime_type; + key.icon_name = NULL; + + entry = bsearch (&key, list->icons, list->n_icons, + sizeof (XdgIcon), icon_entry_cmp); + if (entry) + return entry->icon_name; + } + + return NULL; +} + +void +_xdg_mime_icon_read_from_file (XdgIconList *list, + const char *file_name) +{ + FILE *file; + char line[255]; + int alloc; + + file = fopen (file_name, "r"); + + if (file == NULL) + return; + + /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. + * Blah */ + alloc = list->n_icons + 16; + list->icons = realloc (list->icons, alloc * sizeof (XdgIcon)); + while (fgets (line, 255, file) != NULL) + { + char *sep; + if (line[0] == '#') + continue; + + sep = strchr (line, ':'); + if (sep == NULL) + continue; + *(sep++) = '\000'; + sep[strlen (sep) -1] = '\000'; + if (list->n_icons == alloc) + { + alloc <<= 1; + list->icons = realloc (list->icons, + alloc * sizeof (XdgIcon)); + } + list->icons[list->n_icons].mime_type = strdup (line); + list->icons[list->n_icons].icon_name = strdup (sep); + list->n_icons++; + } + list->icons = realloc (list->icons, + list->n_icons * sizeof (XdgIcon)); + + fclose (file); + + if (list->n_icons > 1) + qsort (list->icons, list->n_icons, + sizeof (XdgIcon), icon_entry_cmp); +} + + +void +_xdg_mime_icon_list_dump (XdgIconList *list) +{ + int i; + + if (list->icons) + { + for (i = 0; i < list->n_icons; i++) + { + printf ("%s %s\n", + list->icons[i].mime_type, + list->icons[i].icon_name); + } + } +} + + diff --git a/gio/xdgmime/xdgmimeicon.h b/gio/xdgmime/xdgmimeicon.h new file mode 100644 index 0000000..c416b3c --- /dev/null +++ b/gio/xdgmime/xdgmimeicon.h @@ -0,0 +1,50 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeicon.h: Private file. Datastructure for storing the aliases. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2008 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_ICON_H__ +#define __XDG_MIME_ICON_H__ + +#include "xdgmime.h" + +typedef struct XdgIconList XdgIconList; + +#ifdef XDG_PREFIX +#define _xdg_mime_icon_read_from_file XDG_ENTRY(icon_read_from_file) +#define _xdg_mime_icon_list_new XDG_ENTRY(icon_list_new) +#define _xdg_mime_icon_list_free XDG_ENTRY(icon_list_free) +#define _xdg_mime_icon_list_lookup XDG_ENTRY(icon_list_lookup) +#define _xdg_mime_icon_list_dump XDG_ENTRY(icon_list_dump) +#endif + +void _xdg_mime_icon_read_from_file (XdgIconList *list, + const char *file_name); +XdgIconList *_xdg_mime_icon_list_new (void); +void _xdg_mime_icon_list_free (XdgIconList *list); +const char *_xdg_mime_icon_list_lookup (XdgIconList *list, + const char *mime); +void _xdg_mime_icon_list_dump (XdgIconList *list); + +#endif /* __XDG_MIME_ICON_H__ */ diff --git a/gio/xdgmime/xdgmimeint.c b/gio/xdgmime/xdgmimeint.c new file mode 100644 index 0000000..5e4513c --- /dev/null +++ b/gio/xdgmime/xdgmimeint.c @@ -0,0 +1,206 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeint.c: Internal defines and functions. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimeint.h" +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +static const char _xdg_utf8_skip_data[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 +}; + +const char * const _xdg_utf8_skip = _xdg_utf8_skip_data; + + + +/* Returns the number of unprocessed characters. */ +xdg_unichar_t +_xdg_utf8_to_ucs4(const char *source) +{ + xdg_unichar_t ucs32; + if( ! ( *source & 0x80 ) ) + { + ucs32 = *source; + } + else + { + int bytelength = 0; + xdg_unichar_t result; + if ( ! (*source & 0x40) ) + { + ucs32 = *source; + } + else + { + if ( ! (*source & 0x20) ) + { + result = *source++ & 0x1F; + bytelength = 2; + } + else if ( ! (*source & 0x10) ) + { + result = *source++ & 0x0F; + bytelength = 3; + } + else if ( ! (*source & 0x08) ) + { + result = *source++ & 0x07; + bytelength = 4; + } + else if ( ! (*source & 0x04) ) + { + result = *source++ & 0x03; + bytelength = 5; + } + else if ( ! (*source & 0x02) ) + { + result = *source++ & 0x01; + bytelength = 6; + } + else + { + result = *source++; + bytelength = 1; + } + + for ( bytelength --; bytelength > 0; bytelength -- ) + { + result <<= 6; + result |= *source++ & 0x3F; + } + ucs32 = result; + } + } + return ucs32; +} + + +/* hullo. this is great code. don't rewrite it */ + +xdg_unichar_t +_xdg_ucs4_to_lower (xdg_unichar_t source) +{ + /* FIXME: Do a real to_upper sometime */ + /* CaseFolding-3.2.0.txt has a table of rules. */ + if ((source & 0xFF) == source) + return (xdg_unichar_t) tolower ((unsigned char) source); + return source; +} + +int +_xdg_utf8_validate (const char *source) +{ + /* FIXME: actually write */ + return TRUE; +} + +const char * +_xdg_get_base_name (const char *file_name) +{ + const char *base_name; + + if (file_name == NULL) + return NULL; + + base_name = strrchr (file_name, '/'); + + if (base_name == NULL) + return file_name; + else + return base_name + 1; +} + +xdg_unichar_t * +_xdg_convert_to_ucs4 (const char *source, int *len) +{ + xdg_unichar_t *out; + int i; + const char *p; + + out = malloc (sizeof (xdg_unichar_t) * (strlen (source) + 1)); + + p = source; + i = 0; + while (*p) + { + out[i++] = _xdg_utf8_to_ucs4 (p); + p = _xdg_utf8_next_char (p); + } + out[i] = 0; + *len = i; + + return out; +} + +void +_xdg_reverse_ucs4 (xdg_unichar_t *source, int len) +{ + xdg_unichar_t c; + int i; + + for (i = 0; i < len - i - 1; i++) + { + c = source[i]; + source[i] = source[len - i - 1]; + source[len - i - 1] = c; + } +} + +const char * +_xdg_binary_or_text_fallback(const void *data, size_t len) +{ + unsigned char *chardata; + size_t i; + + chardata = (unsigned char *) data; + for (i = 0; i < 128 && i < len; ++i) + { + if (chardata[i] < 32 && chardata[i] != 9 && chardata[i] != 10 && chardata[i] != 13) + return XDG_MIME_TYPE_UNKNOWN; /* binary data */ + } + + return XDG_MIME_TYPE_TEXTPLAIN; +} diff --git a/gio/xdgmime/xdgmimeint.h b/gio/xdgmime/xdgmimeint.h new file mode 100644 index 0000000..9a8256d --- /dev/null +++ b/gio/xdgmime/xdgmimeint.h @@ -0,0 +1,78 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeint.h: Internal defines and functions. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_INT_H__ +#define __XDG_MIME_INT_H__ + +#include "xdgmime.h" + + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +/* FIXME: Needs to be configure check */ +typedef unsigned int xdg_unichar_t; +typedef unsigned char xdg_uchar8_t; +typedef unsigned short xdg_uint16_t; +typedef unsigned int xdg_uint32_t; + +#ifdef XDG_PREFIX +#define _xdg_utf8_skip XDG_RESERVED_ENTRY(utf8_skip) +#define _xdg_utf8_to_ucs4 XDG_RESERVED_ENTRY(utf8_to_ucs4) +#define _xdg_ucs4_to_lower XDG_RESERVED_ENTRY(ucs4_to_lower) +#define _xdg_utf8_validate XDG_RESERVED_ENTRY(utf8_validate) +#define _xdg_get_base_name XDG_RESERVED_ENTRY(get_base_name) +#define _xdg_convert_to_ucs4 XDG_RESERVED_ENTRY(convert_to_ucs4) +#define _xdg_reverse_ucs4 XDG_RESERVED_ENTRY(reverse_ucs4) +#endif + +#define SWAP_BE16_TO_LE16(val) (xdg_uint16_t)(((xdg_uint16_t)(val) << 8)|((xdg_uint16_t)(val) >> 8)) + +#define SWAP_BE32_TO_LE32(val) (xdg_uint32_t)((((xdg_uint32_t)(val) & 0xFF000000U) >> 24) | \ + (((xdg_uint32_t)(val) & 0x00FF0000U) >> 8) | \ + (((xdg_uint32_t)(val) & 0x0000FF00U) << 8) | \ + (((xdg_uint32_t)(val) & 0x000000FFU) << 24)) +/* UTF-8 utils + */ +extern const char *const _xdg_utf8_skip; +#define _xdg_utf8_next_char(p) (char *)((p) + _xdg_utf8_skip[*(unsigned char *)(p)]) +#define _xdg_utf8_char_size(p) (int) (_xdg_utf8_skip[*(unsigned char *)(p)]) + +xdg_unichar_t _xdg_utf8_to_ucs4 (const char *source); +xdg_unichar_t _xdg_ucs4_to_lower (xdg_unichar_t source); +int _xdg_utf8_validate (const char *source); +xdg_unichar_t *_xdg_convert_to_ucs4 (const char *source, int *len); +void _xdg_reverse_ucs4 (xdg_unichar_t *source, int len); +const char *_xdg_get_base_name (const char *file_name); +const char *_xdg_binary_or_text_fallback(const void *data, size_t len); + +#endif /* __XDG_MIME_INT_H__ */ diff --git a/gio/xdgmime/xdgmimemagic.c b/gio/xdgmime/xdgmimemagic.c new file mode 100644 index 0000000..dcee0fd --- /dev/null +++ b/gio/xdgmime/xdgmimemagic.c @@ -0,0 +1,830 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimemagic.: Private file. Datastructure for storing magic files. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "xdgmimemagic.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#if !defined getc_unlocked && !defined HAVE_GETC_UNLOCKED +# define getc_unlocked(fp) getc (fp) +#endif + +typedef struct XdgMimeMagicMatch XdgMimeMagicMatch; +typedef struct XdgMimeMagicMatchlet XdgMimeMagicMatchlet; + +typedef enum +{ + XDG_MIME_MAGIC_SECTION, + XDG_MIME_MAGIC_MAGIC, + XDG_MIME_MAGIC_ERROR, + XDG_MIME_MAGIC_EOF +} XdgMimeMagicState; + +struct XdgMimeMagicMatch +{ + const char *mime_type; + int priority; + XdgMimeMagicMatchlet *matchlet; + XdgMimeMagicMatch *next; +}; + + +struct XdgMimeMagicMatchlet +{ + int indent; + int offset; + unsigned int value_length; + unsigned char *value; + unsigned char *mask; + unsigned int range_length; + unsigned int word_size; + XdgMimeMagicMatchlet *next; +}; + + +struct XdgMimeMagic +{ + XdgMimeMagicMatch *match_list; + int max_extent; +}; + +static XdgMimeMagicMatch * +_xdg_mime_magic_match_new (void) +{ + return calloc (1, sizeof (XdgMimeMagicMatch)); +} + + +static XdgMimeMagicMatchlet * +_xdg_mime_magic_matchlet_new (void) +{ + XdgMimeMagicMatchlet *matchlet; + + matchlet = malloc (sizeof (XdgMimeMagicMatchlet)); + if (matchlet == NULL) + return NULL; + + matchlet->indent = 0; + matchlet->offset = 0; + matchlet->value_length = 0; + matchlet->value = NULL; + matchlet->mask = NULL; + matchlet->range_length = 1; + matchlet->word_size = 1; + matchlet->next = NULL; + + return matchlet; +} + + +static void +_xdg_mime_magic_matchlet_free (XdgMimeMagicMatchlet *mime_magic_matchlet) +{ + if (mime_magic_matchlet) + { + if (mime_magic_matchlet->next) + _xdg_mime_magic_matchlet_free (mime_magic_matchlet->next); + if (mime_magic_matchlet->value) + free (mime_magic_matchlet->value); + if (mime_magic_matchlet->mask) + free (mime_magic_matchlet->mask); + free (mime_magic_matchlet); + } +} + + +/* Frees mime_magic_match and the remainder of its list + */ +static void +_xdg_mime_magic_match_free (XdgMimeMagicMatch *mime_magic_match) +{ + XdgMimeMagicMatch *ptr, *next; + + ptr = mime_magic_match; + while (ptr) + { + next = ptr->next; + + if (ptr->mime_type) + free ((void *) ptr->mime_type); + if (ptr->matchlet) + _xdg_mime_magic_matchlet_free (ptr->matchlet); + free (ptr); + + ptr = next; + } +} + +/* Reads in a hunk of data until a newline character or a '\000' is hit. The + * returned string is null terminated, and doesn't include the newline. + */ +static unsigned char * +_xdg_mime_magic_read_to_newline (FILE *magic_file, + int *end_of_file) +{ + unsigned char *retval; + int c; + int len, pos; + + len = 128; + pos = 0; + retval = malloc (len); + *end_of_file = FALSE; + + while (TRUE) + { + c = getc_unlocked (magic_file); + if (c == EOF) + { + *end_of_file = TRUE; + break; + } + if (c == '\n' || c == '\000') + break; + retval[pos++] = (unsigned char) c; + if (pos % 128 == 127) + { + len = len + 128; + retval = realloc (retval, len); + } + } + + retval[pos] = '\000'; + return retval; +} + +/* Returns the number read from the file, or -1 if no number could be read. + */ +static int +_xdg_mime_magic_read_a_number (FILE *magic_file, + int *end_of_file) +{ + /* LONG_MAX is about 20 characters on my system */ +#define MAX_NUMBER_SIZE 30 + char number_string[MAX_NUMBER_SIZE + 1]; + int pos = 0; + int c; + long retval = -1; + + while (TRUE) + { + c = getc_unlocked (magic_file); + + if (c == EOF) + { + *end_of_file = TRUE; + break; + } + if (! isdigit (c)) + { + ungetc (c, magic_file); + break; + } + number_string[pos] = (char) c; + pos++; + if (pos == MAX_NUMBER_SIZE) + break; + } + if (pos > 0) + { + number_string[pos] = '\000'; + errno = 0; + retval = strtol (number_string, NULL, 10); + + if ((retval < INT_MIN) || (retval > INT_MAX) || (errno != 0)) + return -1; + } + + return retval; +} + +/* Headers are of the format: + * [:] + */ +static XdgMimeMagicState +_xdg_mime_magic_parse_header (FILE *magic_file, XdgMimeMagicMatch *match) +{ + int c; + char *buffer; + char *end_ptr; + int end_of_file = 0; + + assert (magic_file != NULL); + assert (match != NULL); + + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + if (c != '[') + return XDG_MIME_MAGIC_ERROR; + + match->priority = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + return XDG_MIME_MAGIC_EOF; + if (match->priority == -1) + return XDG_MIME_MAGIC_ERROR; + + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + if (c != ':') + return XDG_MIME_MAGIC_ERROR; + + buffer = (char *)_xdg_mime_magic_read_to_newline (magic_file, &end_of_file); + if (end_of_file) + { + free (buffer); + return XDG_MIME_MAGIC_EOF; + } + + end_ptr = buffer; + while (*end_ptr != ']' && *end_ptr != '\000' && *end_ptr != '\n') + end_ptr++; + if (*end_ptr != ']') + { + free (buffer); + return XDG_MIME_MAGIC_ERROR; + } + *end_ptr = '\000'; + + match->mime_type = strdup (buffer); + free (buffer); + + return XDG_MIME_MAGIC_MAGIC; +} + +static XdgMimeMagicState +_xdg_mime_magic_parse_error (FILE *magic_file) +{ + int c; + + while (1) + { + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + if (c == '\n') + return XDG_MIME_MAGIC_SECTION; + } +} + +/* Headers are of the format: + * [ indent ] ">" start-offset "=" value + * [ "&" mask ] [ "~" word-size ] [ "+" range-length ] "\n" + */ +static XdgMimeMagicState +_xdg_mime_magic_parse_magic_line (FILE *magic_file, + XdgMimeMagicMatch *match) +{ + XdgMimeMagicMatchlet *matchlet; + int c; + int end_of_file; + int indent = 0; + size_t bytes_read; + + assert (magic_file != NULL); + + /* Sniff the buffer to make sure it's a valid line */ + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + else if (c == '[') + { + ungetc (c, magic_file); + return XDG_MIME_MAGIC_SECTION; + } + else if (c == '\n') + return XDG_MIME_MAGIC_MAGIC; + + /* At this point, it must be a digit or a '>' */ + end_of_file = FALSE; + if (isdigit (c)) + { + ungetc (c, magic_file); + indent = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + return XDG_MIME_MAGIC_EOF; + if (indent == -1) + return XDG_MIME_MAGIC_ERROR; + c = getc_unlocked (magic_file); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + } + + if (c != '>') + return XDG_MIME_MAGIC_ERROR; + + matchlet = _xdg_mime_magic_matchlet_new (); + + /* OOM */ + if (matchlet == NULL) + return XDG_MIME_MAGIC_ERROR; + + matchlet->indent = indent; + matchlet->offset = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + if (matchlet->offset == -1) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + c = getc_unlocked (magic_file); + if (c == EOF) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + else if (c != '=') + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + + /* Next two bytes determine how long the value is */ + matchlet->value_length = 0; + c = getc_unlocked (magic_file); + if (c == EOF) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + matchlet->value_length = c & 0xFF; + matchlet->value_length = matchlet->value_length << 8; + + c = getc_unlocked (magic_file); + if (c == EOF) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + matchlet->value_length = matchlet->value_length + (c & 0xFF); + + matchlet->value = malloc (matchlet->value_length); + + /* OOM */ + if (matchlet->value == NULL) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + bytes_read = fread (matchlet->value, 1, matchlet->value_length, magic_file); + if (bytes_read != (size_t) matchlet->value_length) + { + _xdg_mime_magic_matchlet_free (matchlet); + if (feof (magic_file)) + return XDG_MIME_MAGIC_EOF; + else + return XDG_MIME_MAGIC_ERROR; + } + + c = getc_unlocked (magic_file); + if (c == '&') + { + matchlet->mask = malloc (matchlet->value_length); + /* OOM */ + if (matchlet->mask == NULL) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + bytes_read = fread (matchlet->mask, 1, matchlet->value_length, magic_file); + if (bytes_read != (size_t) matchlet->value_length) + { + _xdg_mime_magic_matchlet_free (matchlet); + if (feof (magic_file)) + return XDG_MIME_MAGIC_EOF; + else + return XDG_MIME_MAGIC_ERROR; + } + c = getc_unlocked (magic_file); + } + + if (c == '~') + { + matchlet->word_size = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + if (matchlet->word_size != 0 && + matchlet->word_size != 1 && + matchlet->word_size != 2 && + matchlet->word_size != 4) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + c = getc_unlocked (magic_file); + } + + if (c == '+') + { + matchlet->range_length = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); + if (end_of_file) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_EOF; + } + if (matchlet->range_length == (unsigned int) -1) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + c = getc_unlocked (magic_file); + } + + + if (c == '\n') + { + /* We clean up the matchlet, byte swapping if needed */ + if (matchlet->word_size > 1) + { +#if LITTLE_ENDIAN + unsigned int i; +#endif + if (matchlet->value_length % matchlet->word_size != 0) + { + _xdg_mime_magic_matchlet_free (matchlet); + return XDG_MIME_MAGIC_ERROR; + } + /* FIXME: need to get this defined in a style file */ +#if LITTLE_ENDIAN + for (i = 0; i < matchlet->value_length; i = i + matchlet->word_size) + { + if (matchlet->word_size == 2) + *((xdg_uint16_t *) matchlet->value + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->value + i))); + else if (matchlet->word_size == 4) + *((xdg_uint32_t *) matchlet->value + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->value + i))); + if (matchlet->mask) + { + if (matchlet->word_size == 2) + *((xdg_uint16_t *) matchlet->mask + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->mask + i))); + else if (matchlet->word_size == 4) + *((xdg_uint32_t *) matchlet->mask + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->mask + i))); + + } + } +#endif + } + + matchlet->next = match->matchlet; + match->matchlet = matchlet; + + + return XDG_MIME_MAGIC_MAGIC; + } + + _xdg_mime_magic_matchlet_free (matchlet); + if (c == EOF) + return XDG_MIME_MAGIC_EOF; + + return XDG_MIME_MAGIC_ERROR; +} + +static int +_xdg_mime_magic_matchlet_compare_to_data (XdgMimeMagicMatchlet *matchlet, + const void *data, + size_t len) +{ + unsigned int i, j; + for (i = matchlet->offset; i < matchlet->offset + matchlet->range_length; i++) + { + int valid_matchlet = TRUE; + + if (i + matchlet->value_length > len) + return FALSE; + + if (matchlet->mask) + { + for (j = 0; j < matchlet->value_length; j++) + { + if ((matchlet->value[j] & matchlet->mask[j]) != + ((((unsigned char *) data)[j + i]) & matchlet->mask[j])) + { + valid_matchlet = FALSE; + break; + } + } + } + else + { + for (j = 0; j < matchlet->value_length; j++) + { + if (matchlet->value[j] != ((unsigned char *) data)[j + i]) + { + valid_matchlet = FALSE; + break; + } + } + } + if (valid_matchlet) + return TRUE; + } + return FALSE; +} + +static int +_xdg_mime_magic_matchlet_compare_level (XdgMimeMagicMatchlet *matchlet, + const void *data, + size_t len, + int indent) +{ + while ((matchlet != NULL) && (matchlet->indent == indent)) + { + if (_xdg_mime_magic_matchlet_compare_to_data (matchlet, data, len)) + { + if ((matchlet->next == NULL) || + (matchlet->next->indent <= indent)) + return TRUE; + + if (_xdg_mime_magic_matchlet_compare_level (matchlet->next, + data, + len, + indent + 1)) + return TRUE; + } + + do + { + matchlet = matchlet->next; + } + while (matchlet && matchlet->indent > indent); + } + + return FALSE; +} + +static int +_xdg_mime_magic_match_compare_to_data (XdgMimeMagicMatch *match, + const void *data, + size_t len) +{ + return _xdg_mime_magic_matchlet_compare_level (match->matchlet, data, len, 0); +} + +static void +_xdg_mime_magic_insert_match (XdgMimeMagic *mime_magic, + XdgMimeMagicMatch *match) +{ + XdgMimeMagicMatch *list; + + if (mime_magic->match_list == NULL) + { + mime_magic->match_list = match; + return; + } + + if (match->priority > mime_magic->match_list->priority) + { + match->next = mime_magic->match_list; + mime_magic->match_list = match; + return; + } + + list = mime_magic->match_list; + while (list->next != NULL) + { + if (list->next->priority < match->priority) + { + match->next = list->next; + list->next = match; + return; + } + list = list->next; + } + list->next = match; + match->next = NULL; +} + +XdgMimeMagic * +_xdg_mime_magic_new (void) +{ + return calloc (1, sizeof (XdgMimeMagic)); +} + +void +_xdg_mime_magic_free (XdgMimeMagic *mime_magic) +{ + if (mime_magic) { + _xdg_mime_magic_match_free (mime_magic->match_list); + free (mime_magic); + } +} + +int +_xdg_mime_magic_get_buffer_extents (XdgMimeMagic *mime_magic) +{ + return mime_magic->max_extent; +} + +const char * +_xdg_mime_magic_lookup_data (XdgMimeMagic *mime_magic, + const void *data, + size_t len, + int *result_prio, + const char *mime_types[], + int n_mime_types) +{ + XdgMimeMagicMatch *match; + const char *mime_type; + int n; + int prio; + + prio = 0; + mime_type = NULL; + for (match = mime_magic->match_list; match; match = match->next) + { + if (_xdg_mime_magic_match_compare_to_data (match, data, len)) + { + prio = match->priority; + mime_type = match->mime_type; + break; + } + else + { + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n] && + _xdg_mime_mime_type_equal (mime_types[n], match->mime_type)) + mime_types[n] = NULL; + } + } + } + + if (mime_type == NULL) + { + for (n = 0; n < n_mime_types; n++) + { + if (mime_types[n]) + mime_type = mime_types[n]; + } + } + + if (result_prio) + *result_prio = prio; + + return mime_type; +} + +static void +_xdg_mime_update_mime_magic_extents (XdgMimeMagic *mime_magic) +{ + XdgMimeMagicMatch *match; + int max_extent = 0; + + for (match = mime_magic->match_list; match; match = match->next) + { + XdgMimeMagicMatchlet *matchlet; + + for (matchlet = match->matchlet; matchlet; matchlet = matchlet->next) + { + int extent; + + extent = matchlet->value_length + matchlet->offset + matchlet->range_length; + if (max_extent < extent) + max_extent = extent; + } + } + + mime_magic->max_extent = max_extent; +} + +static XdgMimeMagicMatchlet * +_xdg_mime_magic_matchlet_mirror (XdgMimeMagicMatchlet *matchlets) +{ + XdgMimeMagicMatchlet *new_list; + XdgMimeMagicMatchlet *tmp; + + if ((matchlets == NULL) || (matchlets->next == NULL)) + return matchlets; + + new_list = NULL; + tmp = matchlets; + while (tmp != NULL) + { + XdgMimeMagicMatchlet *matchlet; + + matchlet = tmp; + tmp = tmp->next; + matchlet->next = new_list; + new_list = matchlet; + } + + return new_list; + +} + +static void +_xdg_mime_magic_read_magic_file (XdgMimeMagic *mime_magic, + FILE *magic_file) +{ + XdgMimeMagicState state; + XdgMimeMagicMatch *match = NULL; /* Quiet compiler */ + + state = XDG_MIME_MAGIC_SECTION; + + while (state != XDG_MIME_MAGIC_EOF) + { + switch (state) + { + case XDG_MIME_MAGIC_SECTION: + match = _xdg_mime_magic_match_new (); + + /* OOM */ + if (match == NULL) + return; + + state = _xdg_mime_magic_parse_header (magic_file, match); + if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR) + _xdg_mime_magic_match_free (match); + break; + case XDG_MIME_MAGIC_MAGIC: + state = _xdg_mime_magic_parse_magic_line (magic_file, match); + if (state == XDG_MIME_MAGIC_SECTION || + (state == XDG_MIME_MAGIC_EOF && match->mime_type)) + { + match->matchlet = _xdg_mime_magic_matchlet_mirror (match->matchlet); + _xdg_mime_magic_insert_match (mime_magic, match); + } + else if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR) + _xdg_mime_magic_match_free (match); + break; + case XDG_MIME_MAGIC_ERROR: + state = _xdg_mime_magic_parse_error (magic_file); + break; + case XDG_MIME_MAGIC_EOF: + default: + /* Make the compiler happy */ + assert (0); + } + } + _xdg_mime_update_mime_magic_extents (mime_magic); +} + +void +_xdg_mime_magic_read_from_file (XdgMimeMagic *mime_magic, + const char *file_name) +{ + FILE *magic_file; + char header[12]; + + magic_file = fopen (file_name, "r"); + + if (magic_file == NULL) + return; + + if (fread (header, 1, 12, magic_file) == 12) + { + if (memcmp ("MIME-Magic\0\n", header, 12) == 0) + _xdg_mime_magic_read_magic_file (mime_magic, magic_file); + } + + fclose (magic_file); +} diff --git a/gio/xdgmime/xdgmimemagic.h b/gio/xdgmime/xdgmimemagic.h new file mode 100644 index 0000000..eb06a81 --- /dev/null +++ b/gio/xdgmime/xdgmimemagic.h @@ -0,0 +1,57 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimemagic.h: Private file. Datastructure for storing the magic files. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003 Jonathan Blandford + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_MAGIC_H__ +#define __XDG_MIME_MAGIC_H__ + +#include +#include "xdgmime.h" +typedef struct XdgMimeMagic XdgMimeMagic; + +#ifdef XDG_PREFIX +#define _xdg_mime_glob_read_from_file XDG_RESERVED_ENTRY(glob_read_from_file) +#define _xdg_mime_magic_new XDG_RESERVED_ENTRY(magic_new) +#define _xdg_mime_magic_read_from_file XDG_RESERVED_ENTRY(magic_read_from_file) +#define _xdg_mime_magic_free XDG_RESERVED_ENTRY(magic_free) +#define _xdg_mime_magic_get_buffer_extents XDG_RESERVED_ENTRY(magic_get_buffer_extents) +#define _xdg_mime_magic_lookup_data XDG_RESERVED_ENTRY(magic_lookup_data) +#endif + + +XdgMimeMagic *_xdg_mime_magic_new (void); +void _xdg_mime_magic_read_from_file (XdgMimeMagic *mime_magic, + const char *file_name); +void _xdg_mime_magic_free (XdgMimeMagic *mime_magic); +int _xdg_mime_magic_get_buffer_extents (XdgMimeMagic *mime_magic); +const char *_xdg_mime_magic_lookup_data (XdgMimeMagic *mime_magic, + const void *data, + size_t len, + int *result_prio, + const char *mime_types[], + int n_mime_types); + +#endif /* __XDG_MIME_MAGIC_H__ */ diff --git a/gio/xdgmime/xdgmimeparent.c b/gio/xdgmime/xdgmimeparent.c new file mode 100644 index 0000000..89b48fc --- /dev/null +++ b/gio/xdgmime/xdgmimeparent.c @@ -0,0 +1,220 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimealias.c: Private file. Datastructure for storing the hierarchy. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 2004 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xdgmimeparent.h" +#include "xdgmimeint.h" +#include +#include +#include +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef struct XdgMimeParents XdgMimeParents; + +struct XdgMimeParents +{ + char *mime; + char **parents; + int n_parents; +}; + +struct XdgParentList +{ + struct XdgMimeParents *parents; + int n_mimes; +}; + +XdgParentList * +_xdg_mime_parent_list_new (void) +{ + XdgParentList *list; + + list = malloc (sizeof (XdgParentList)); + + list->parents = NULL; + list->n_mimes = 0; + + return list; +} + +void +_xdg_mime_parent_list_free (XdgParentList *list) +{ + int i; + char **p; + + if (list->parents) + { + for (i = 0; i < list->n_mimes; i++) + { + for (p = list->parents[i].parents; *p; p++) + free (*p); + + free (list->parents[i].parents); + free (list->parents[i].mime); + } + free (list->parents); + } + free (list); +} + +static int +parent_entry_cmp (const void *v1, const void *v2) +{ + return strcmp (((XdgMimeParents *)v1)->mime, ((XdgMimeParents *)v2)->mime); +} + +const char ** +_xdg_mime_parent_list_lookup (XdgParentList *list, + const char *mime) +{ + XdgMimeParents *entry; + XdgMimeParents key; + + if (list->n_mimes > 0) + { + key.mime = (char *)mime; + key.parents = NULL; + key.n_parents = 0; + + entry = bsearch (&key, list->parents, list->n_mimes, + sizeof (XdgMimeParents), &parent_entry_cmp); + if (entry) + return (const char **)entry->parents; + } + + return NULL; +} + +void +_xdg_mime_parent_read_from_file (XdgParentList *list, + const char *file_name) +{ + FILE *file; + char line[255]; + int i, alloc; + XdgMimeParents *entry; + + file = fopen (file_name, "r"); + + if (file == NULL) + return; + + /* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars. + * Blah */ + alloc = list->n_mimes + 16; + list->parents = realloc (list->parents, alloc * sizeof (XdgMimeParents)); + while (fgets (line, 255, file) != NULL) + { + char *sep; + if (line[0] == '#') + continue; + + sep = strchr (line, ' '); + if (sep == NULL) + continue; + *(sep++) = '\000'; + sep[strlen (sep) -1] = '\000'; + entry = NULL; + for (i = 0; i < list->n_mimes; i++) + { + if (strcmp (list->parents[i].mime, line) == 0) + { + entry = &(list->parents[i]); + break; + } + } + + if (!entry) + { + if (list->n_mimes == alloc) + { + alloc <<= 1; + list->parents = realloc (list->parents, + alloc * sizeof (XdgMimeParents)); + } + list->parents[list->n_mimes].mime = strdup (line); + list->parents[list->n_mimes].parents = NULL; + entry = &(list->parents[list->n_mimes]); + list->n_mimes++; + } + + if (!entry->parents) + { + entry->n_parents = 1; + entry->parents = malloc ((entry->n_parents + 1) * sizeof (char *)); + } + else + { + entry->n_parents += 1; + entry->parents = realloc (entry->parents, + (entry->n_parents + 2) * sizeof (char *)); + } + entry->parents[entry->n_parents - 1] = strdup (sep); + entry->parents[entry->n_parents] = NULL; + } + + list->parents = realloc (list->parents, + list->n_mimes * sizeof (XdgMimeParents)); + + fclose (file); + + if (list->n_mimes > 1) + qsort (list->parents, list->n_mimes, + sizeof (XdgMimeParents), &parent_entry_cmp); +} + + +void +_xdg_mime_parent_list_dump (XdgParentList *list) +{ + int i; + char **p; + + if (list->parents) + { + for (i = 0; i < list->n_mimes; i++) + { + for (p = list->parents[i].parents; *p; p++) + printf ("%s %s\n", list->parents[i].mime, *p); + } + } +} + + diff --git a/gio/xdgmime/xdgmimeparent.h b/gio/xdgmime/xdgmimeparent.h new file mode 100644 index 0000000..29f43bc --- /dev/null +++ b/gio/xdgmime/xdgmimeparent.h @@ -0,0 +1,51 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* xdgmimeparent.h: Private file. Datastructure for storing the hierarchy. + * + * More info can be found at http://www.freedesktop.org/standards/ + * + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 200 Matthias Clasen + * + * Licensed under the Academic Free License version 2.0 + * Or under the following terms: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __XDG_MIME_PARENT_H__ +#define __XDG_MIME_PARENT_H__ + +#include "xdgmime.h" + +typedef struct XdgParentList XdgParentList; + +#ifdef XDG_PREFIX +#define _xdg_mime_parent_read_from_file XDG_RESERVED_ENTRY(parent_read_from_file) +#define _xdg_mime_parent_list_new XDG_RESERVED_ENTRY(parent_list_new) +#define _xdg_mime_parent_list_free XDG_RESERVED_ENTRY(parent_list_free) +#define _xdg_mime_parent_list_lookup XDG_RESERVED_ENTRY(parent_list_lookup) +#define _xdg_mime_parent_list_dump XDG_RESERVED_ENTRY(parent_list_dump) +#endif + +void _xdg_mime_parent_read_from_file (XdgParentList *list, + const char *file_name); +XdgParentList *_xdg_mime_parent_list_new (void); +void _xdg_mime_parent_list_free (XdgParentList *list); +const char **_xdg_mime_parent_list_lookup (XdgParentList *list, + const char *mime); +void _xdg_mime_parent_list_dump (XdgParentList *list); + +#endif /* __XDG_MIME_PARENT_H__ */ diff --git a/glib-gettextize.in b/glib-gettextize.in new file mode 100755 index 0000000..05ec43c --- /dev/null +++ b/glib-gettextize.in @@ -0,0 +1,187 @@ +#! /bin/sh +# +# Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# + +# - Modified in October 2001 by jacob berkman to +# work with glib's Makefile.in.in and po2tbl.sed.in, to not copy in +# intl/, and to not add ChangeLog entries to po/ChangeLog + +# This file is meant for authors or maintainers which want to +# internationalize their package with the help of GNU gettext. For +# further information how to use it consult the GNU gettext manual. + +echo=echo +progname=$0 +force=0 +configstatus=0 +origdir=`pwd` +usage="\ +Usage: glib-gettextize [OPTION]... [package-dir] + --help print this help and exit + --version print version information and exit + -c, --copy copy files instead of making symlinks + -f, --force force writing of new files even if old exist +Report bugs to https://gitlab.gnome.org/GNOME/glib/issues/new." +package=@PACKAGE@ +version=@VERSION@ +try_ln_s=: + +# Directory where the sources are stored. +prefix=@prefix@ +case `uname` in +MINGW32*) + prefix="`dirname $0`/.." + ;; +esac + +datarootdir=@datarootdir@ +datadir=@datadir@ + +gettext_dir=$datadir/glib-2.0/gettext + +while test $# -gt 0; do + case "$1" in + -c | --copy | --c* ) + shift + try_ln_s=false ;; + -f | --force | --f* ) + shift + force=1 ;; + -r | --run | --r* ) + shift + configstatus=1 ;; + --help | --h* ) + $echo "$usage"; exit 0 ;; + --version | --v* ) + echo "$progname (GNU $package) $version" + $echo "Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + $echo "Written by" "Ulrich Drepper" + exit 0 ;; + -- ) # Stop option processing + shift; break ;; + -* ) + $echo "glib-gettextize: unknown option $1" + $echo "Try \`glib-gettextize --help' for more information."; exit 1 ;; + * ) + break ;; + esac +done + +if test $# -gt 1; then + $echo "$usage" + exit 1 +fi + +# Fill in the command line options value. +if test $# -eq 1; then + srcdir=$1 + if cd "$srcdir"; then + srcdir=`pwd` + else + $echo "Cannot change directory to \`$srcdir'" + exit 1 + fi +else + srcdir=$origdir +fi + +test -f configure.in || test -f configure.ac || { + $echo "Missing configure.in or configure.ac, please cd to your package first." + exit 1 +} + +configure_in=NONE +if test -f configure.in; then + configure_in=configure.in +else + if test -f configure.ac; then + configure_in=configure.ac + fi +fi +# Check in which directory config.rpath, mkinstalldirs etc. belong. +auxdir=`cat "$configure_in" | grep '^AC_CONFIG_AUX_DIR' | sed -n -e 's/AC_CONFIG_AUX_DIR(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q` +if test -n "$auxdir"; then + auxdir="$auxdir/" +fi + +if test -f po/Makefile.in.in && test $force -eq 0; then + $echo "\ +po/Makefile.in.in exists: use option -f if you really want to delete it." + exit 1 +fi + +test -d po || { + $echo "Creating po/ subdirectory" + mkdir po || { + $echo "failed to create po/ subdirectory" + exit 1 + } +} + +# For simplicity we changed to the gettext source directory. +cd $gettext_dir || { + $echo "gettext source directory '${gettext_dir}' doesn't exist" + exit 1 +} + +# Now copy all files. Take care for the destination directories. +for file in *; do + case $file in + intl | po) + ;; + mkinstalldirs) + rm -f "$srcdir/$auxdir$file" + ($try_ln_s && ln -s $gettext_dir/$file "$srcdir/$auxdir$file" && $echo "Symlinking file $file") 2>/dev/null || + { $echo "Copying file $file"; cp $file "$srcdir/$auxdir$file"; } + ;; + *) + rm -f "$srcdir/$file" + ($try_ln_s && ln -s $gettext_dir/$file "$srcdir/$file" && $echo "Symlinking file $file") 2>/dev/null || + { $echo "Copying file $file"; cp $file "$srcdir/$file"; } + ;; + esac +done + +# Copy files to po/ subdirectory. +cd po +for file in *; do + rm -f "$srcdir/po/$file" + ($try_ln_s && ln -s $gettext_dir/po/$file "$srcdir/po/$file" && $echo "Symlinking file po/$file") 2>/dev/null || + { $echo "Copying file po/$file"; cp $file "$srcdir/po/$file"; } +done +if test -f "$srcdir/po/cat-id-tbl.c"; then + $echo "Removing po/cat-id-tbl.c" + rm -f "$srcdir/po/cat-id-tbl.c" +fi +if test -f "$srcdir/po/stamp-cat-id"; then + $echo "Removing po/stamp-cat-id" + rm -f "$srcdir/po/stamp-cat-id" +fi + +echo +echo "Please add the files" +echo " codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lcmessage.m4" +echo " progtest.m4" +echo "from the $datadir/aclocal directory to your autoconf macro directory" +echo "or directly to your aclocal.m4 file." +echo "You will also need config.guess and config.sub, which you can get from" +echo "ftp://ftp.gnu.org/pub/gnu/config/." +echo + +exit 0 diff --git a/glib.doap b/glib.doap new file mode 100644 index 0000000..2d19910 --- /dev/null +++ b/glib.doap @@ -0,0 +1,64 @@ + + + + GLib + glib + + Low level core library + + GLib is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system. + + + + + + + + + C + + + + Matthias Clasen + + matthiasc + + + + + + Allison Ryan Lortie + + desrt + + + + + + Philip Withnall + + + pwithnall + + + + + + Emmanuele Bassi + + ebassi + + + + + + + + + + + diff --git a/glib.supp b/glib.supp new file mode 100644 index 0000000..79faa9f --- /dev/null +++ b/glib.supp @@ -0,0 +1,1111 @@ +# GLib Valgrind suppressions file +# +# This provides a list of suppressions for all of GLib (including GIO), for all +# Valgrind tools (memcheck, drd, helgrind, etc.) for the false positives and +# deliberate one-time leaks which GLib causes to be reported when running under +# Valgrind. +# +# When running an application which links to GLib under Valgrind, you can pass +# this suppression file to Valgrind using --suppressions=/path/to/glib-2.0.supp. +# +# http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress +# +# Note that there is currently no way for Valgrind to load this automatically +# (https://bugs.kde.org/show_bug.cgi?id=160905), so the best GLib can currently +# do is to install this file as part of its development package. +# +# This file should be updated if GLib introduces a new deliberate one-time leak, +# or another false race positive in Valgrind: please file bugs at: +# +# https://gitlab.gnome.org/GNOME/glib/issues/new + +{ + gnutls-init-calloc + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:gtls_gnutls_init +} + +{ + gnutls-init-realloc + Memcheck:Leak + match-leak-kinds:reachable + fun:realloc + ... + fun:gtls_gnutls_init +} + +{ + g-tls-backend-gnutls-init + Memcheck:Leak + match-leak-kinds:reachable + fun:g_once_impl + fun:g_tls_backend_gnutls_init +} + +{ + p11-tokens-init + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:create_tokens_inlock + fun:initialize_module_inlock_reentrant +} + +# One-time allocation from libc for getpwnam() results +{ + g-local-vfs-getpwnam + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:getpwnam + fun:g_local_vfs_parse_name +} + +{ + glib-init-malloc + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_quark_init +} + +{ + glib-init-calloc + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_quark_init +} + +{ + gobject-init-malloc + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:gobject_init* +} + +{ + gobject-init-realloc + Memcheck:Leak + match-leak-kinds:reachable + fun:realloc + ... + fun:gobject_init* +} + +{ + gobject-init-calloc + Memcheck:Leak + match-leak-kinds:possible,reachable + fun:calloc + ... + fun:gobject_init* +} + +{ + g-type-register-dynamic + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_type_register_dynamic +} + +{ + g-type-register-static + Memcheck:Leak + match-leak-kinds:possible,reachable + fun:malloc + ... + fun:g_type_register_static +} + +{ + g-type-register-static-realloc + Memcheck:Leak + match-leak-kinds:possible,reachable + fun:realloc + ... + fun:g_type_register_static +} + +{ + g-type-register-static-calloc + Memcheck:Leak + match-leak-kinds:possible,reachable + fun:calloc + ... + fun:g_type_register_static +} + +{ + g-type-register-fundamental + Memcheck:Leak + match-leak-kinds:possible,reachable + fun:malloc + ... + fun:g_type_register_fundamental +} + +{ + g-type-register-fundamental-calloc + Memcheck:Leak + match-leak-kinds:possible,reachable + fun:calloc + ... + fun:g_type_register_fundamental +} + +{ + g-type-add-interface-dynamic + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_type_add_interface_dynamic +} + +{ + g-type-add-interface-static + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_type_add_interface_static +} + +{ + g-type-add-interface-static-realloc + Memcheck:Leak + match-leak-kinds:reachable + fun:realloc + ... + fun:g_type_add_interface_static +} + +{ + g-type-add-interface-static-calloc + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_type_add_interface_static +} + +{ + g-test-rand-init + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_rand_new_with_seed_array + fun:test_run_seed + ... + fun:g_test_run +} + +{ + g-rand-init2 + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_rand_new_with_seed_array + ... + fun:get_global_random +} + +{ + g-quark-table-new + Memcheck:Leak + match-leak-kinds:reachable + fun:g_hash_table_new + ... + fun:quark_new +} + +{ + g-quark-table-resize + Memcheck:Leak + match-leak-kinds:reachable + ... + fun:g_hash_table_resize + ... + fun:quark_new +} + +{ + g-type-interface-init + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:type_iface_vtable_base_init_Wm +} + +{ + g-type-class-init-calloc + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:type_class_init_Wm +} + +{ + g-type-class-init + Memcheck:Leak + match-leak-kinds:reachable + fun:g_type_create_instance + ... + fun:type_class_init_Wm +} + +{ + g-object-do-class-init-signals + Memcheck:Leak + match-leak-kinds:reachable + ... + fun:g_signal_new + ... + fun:type_class_init_Wm +} + +{ + g-type-prerequisites + Memcheck:Leak + match-leak-kinds:reachable + fun:realloc + ... + fun:type_iface_add_prerequisite_W +} + +{ + g-type-add-interface-check + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_type_add_interface_check + ... + fun:type_class_init_Wm +} + +{ + g-type-add-interface-check-realloc + Memcheck:Leak + match-leak-kinds:reachable + fun:realloc + ... + fun:g_type_add_interface_check + ... + fun:type_class_init_Wm +} + +{ + g-object-class-install-property + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:validate_and_install_class_property + ... + fun:type_class_init_Wm +} + +{ + g-param-spec-pool-new + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_param_spec_pool_new + ... + fun:type_class_init_Wm +} + +# weak_locations_lock in gobject.c +{ + g-weak-ref-lock + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_rw_lock_get_impl + ... + fun:g_weak_ref_set +} + +{ + g-object-base-class-init-construct-pproperties + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_slist_copy + fun:g_object_base_class_init + fun:type_class_init_Wm +} + +{ + g-type-class-ref + Memcheck:Leak + fun:calloc + ... + fun:type_class_init_Wm + ... + fun:g_type_class_ref +} + +{ + g-type-class-ref-inlined + Memcheck:Leak + fun:calloc + ... + fun:UnknownInlinedFun + ... + fun:g_type_class_ref +} + +{ + g-io-module-default-singleton-malloc + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_type_create_instance + ... + fun:_g_io_module_get_default +} + +{ + g-io-module-default-singleton-calloc + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_type_create_instance + ... + fun:_g_io_module_get_default +} + +# This one seems to show up sometimes with g_type_create_instance() at the top +# of the stack, as well. +{ + g-io-module-default-singleton + Memcheck:Leak + match-leak-kinds:reachable + fun:g_type_create_instance + ... + fun:_g_io_module_get_default +} + +{ + g-io-module-default-singleton-module + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_module_open + ... + fun:_g_io_module_get_default +} + +{ + g-io-module-default-singleton-name + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_strdup + ... + fun:_g_io_module_get_default* +} + +{ + g-io-module-default-singleton-weak-ref + Memcheck:Leak + fun:calloc + ... + fun:_g_io_module_get_default +} + +{ + g-get-language-names-malloc + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_get_language_names +} + +{ + g-get-language-names-calloc + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_get_language_names +} + +{ + g-get-language_names-with-category-malloc + Memcheck:Leak + match-leak-kinds:possible,reachable,definite + fun:malloc + ... + fun:g_get_language_names_with_category +} + +{ + g-get-language_names-with-category-calloc + Memcheck:Leak + match-leak-kinds:possible,reachable,definite + fun:calloc + ... + fun:g_get_language_names_with_category +} + +{ + g-get-language_names-with-category-realloc + Memcheck:Leak + match-leak-kinds:possible,reachable,definite + fun:realloc + ... + fun:g_get_language_names_with_category +} + +{ + g-static-mutex + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_static_mutex_get_mutex_impl +} + +{ + g-system-thread-init + Memcheck:Leak + match-leak-kinds:possible,reachable + fun:calloc + ... + fun:g_system_thread_new +} + +{ + g-system-thread-init-malloc + Memcheck:Leak + match-leak-kinds:possible,reachable + fun:malloc + ... + fun:g_system_thread_new +} + +{ + g-task-thread-pool-init + Memcheck:Leak + match-leak-kinds:possible,reachable,definite + fun:malloc + ... + fun:g_thread_new + ... + fun:g_task_thread_pool_init +} + +{ + g-io-module-default-proxy-resolver-gnome + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_proxy_resolver_gnome_init + ... + fun:_g_io_module_get_default +} + +# One-time getaddrinfo() configuration loading +{ + g-threaded-resolver-getaddrinfo-config + Memcheck:Leak + match-leak-kinds:reachable,definite + fun:malloc + ... + fun:__resolv_conf_allocate + ... + fun:getaddrinfo + fun:do_lookup_by_name +} + +# memcheck checks that the third argument to ioctl() is a valid pointer, but +# some ioctls use that argument as an integer +{ + ioctl-with-non-pointer-param + Memcheck:Param + ioctl(generic) + fun:ioctl + fun:btrfs_reflink_with_progress +} + +{ + g-private-get + drd:ConflictingAccess + fun:g_private_get +} +{ + g-private-get-helgrind + Helgrind:Race + fun:g_private_get +} + + +{ + g-private-set + drd:ConflictingAccess + fun:g_private_set +} +{ + g-private-set-helgrind + Helgrind:Race + fun:g_private_set +} + +{ + g-type-construct-free + drd:ConflictingAccess + fun:g_type_free_instance +} +{ + g-type-construct-free-helgrind + Helgrind:Race + fun:g_type_free_instance +} + +{ + g-variant-unref + drd:ConflictingAccess + fun:g_variant_unref +} +{ + g-variant-unref-helgrind + Helgrind:Race + fun:g_variant_unref +} + +{ + g-unix-signals-main + drd:ConflictingAccess + fun:_g_main_create_unix_signal_watch +} +{ + g-unix-signals-dispatch + drd:ConflictingAccess + ... + fun:dispatch_unix_signals* +} +{ + g-unix-signals-dispatch-helgrind + Helgrind:Race + ... + fun:dispatch_unix_signals* +} +{ + g-unix-signals-other + drd:ConflictingAccess + fun:g_unix_signal_watch* +} +{ + g-unix-signals-other-helgrind + Helgrind:Race + fun:g_unix_signal_watch* +} +{ + g-unix-signals-handler + drd:ConflictingAccess + fun:g_unix_signal_handler* +} +{ + g-unix-signals-handler-helgrind + Helgrind:Race + fun:g_unix_signal_handler* +} +{ + g-unix-signals-worker + drd:ConflictingAccess + fun:glib_worker_main +} +{ + g-unix-signals-worker-helgrind + Helgrind:Race + fun:glib_worker_main +} + +{ + g-wakeup-acknowledge + drd:ConflictingAccess + fun:read + fun:g_wakeup_acknowledge +} + +{ + g-type-fundamental + drd:ConflictingAccess + fun:g_type_fundamental +} +{ + g-type-fundamental-helgrind + Helgrind:Race + fun:g_type_fundamental +} +{ + g-type-class-peek-static + drd:ConflictingAccess + fun:g_type_class_peek_static +} +{ + g-type-class-peek-static-helgrind + Helgrind:Race + fun:g_type_class_peek_static +} +{ + g-type-is-a + drd:ConflictingAccess + ... + fun:g_type_is_a +} +{ + g-type-is-a-helgrind + Helgrind:Race + ... + fun:g_type_is_a +} + +{ + g-inet-address-get-type + drd:ConflictingAccess + fun:g_inet_address_get_type +} +{ + g-inet-address-get-type-helgrind + Helgrind:Race + fun:g_inet_address_get_type +} + +# From: https://github.com/fredericgermain/valgrind/blob/HEAD/glibc-2.X-drd.supp +{ + drd-libc-stdio + drd:ConflictingAccess + obj:*/lib*/libc-* +} +{ + drd-libc-recv + drd:ConflictingAccess + fun:recv +} +{ + drd-libc-send + drd:ConflictingAccess + fun:send +} + +# GSources do an opportunistic ref count check +{ + g-source-set-ready-time + drd:ConflictingAccess + fun:g_source_set_ready_time +} +{ + g-source-set-ready-time-helgrind + Helgrind:Race + fun:g_source_set_ready_time +} + +{ + g-source-iter-next + Helgrind:Race + fun:g_source_iter_next + fun:g_main_context_* + fun:g_main_context_iterate +} + +{ + g-object-instance-private + drd:ConflictingAccess + fun:*_get_instance_private +} +{ + g-object-instance-private-helgrind + Helgrind:Race + fun:*_get_instance_private +} + +# GLib legitimately calls pthread_cond_signal without a mutex held +{ + g-task-thread-complete + drd:CondErr + ... + fun:g_cond_signal + fun:g_task_thread_complete +} +{ + g-task-thread-complete + Helgrind:Misc + ... + fun:g_cond_signal + fun:g_task_thread_complete +} + +# False positive, but I can't explain how (FIXME) +{ + g-task-cond + Helgrind:Misc + ... + fun:g_cond_clear + fun:g_task_finalize +} + +# Real race, but is_cancelled() is an opportunistic function anyway +{ + g-cancellable-is-cancelled + Helgrind:Race + fun:g_cancellable_is_cancelled +} + +# False positive +{ + g-main-context-cond + Helgrind:Misc + ... + fun:g_cond_clear + fun:g_main_context_unref +} + +# False positives +{ + g-source-unlocked + Helgrind:Race + fun:g_source_*_unlocked +} +{ + g-source-internal + Helgrind:Race + fun:g_source_*_internal +} + +# False positive +{ + g_object_real_dispose + Helgrind:Race + fun:g_object_real_dispose +} + +# False positive +{ + g_object_new_valist + Helgrind:Race + ... + fun:g_object_new_valist +} + +# g_set_user_dirs() deliberately leaks the previous cached g_get_user_*() values. +# These will not all be reachable on exit. +{ + g_set_user_dirs_str + Memcheck:Leak + match-leak-kinds:definite,reachable + fun:malloc + ... + fun:set_str_if_different + fun:g_set_user_dirs +} + +# g_set_user_dirs() deliberately leaks the previous cached g_get_user_*() values. +# These will not all be reachable on exit. +{ + g_set_user_dirs_strv + Memcheck:Leak + match-leak-kinds:definite,reachable + fun:malloc + ... + fun:set_strv_if_different + fun:g_set_user_dirs +} + +# g_get_system_data_dirs() caches a one-time allocation +{ + g_get_system_data_dirs + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_build_system_data_dirs + fun:g_get_system_data_dirs +} + +# g_get_user_data_dir() caches a one-time allocation +{ + g_get_user_data_dir + Memcheck:Leak + match-leak-kinds:reachable + fun:realloc + ... + fun:g_build_user_data_dir + fun:g_get_user_data_dir +} + +# g_get_home_dir() caches a one-time allocation +{ + g_get_home_dir + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_build_home_dir + fun:g_get_home_dir +} + +# gdesktopappinfo.c caches a one-time allocation global table of @desktop_file_dirs. +{ + desktop_file_dirs_malloc + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:desktop_file_dirs_lock +} + +# gdesktopappinfo.c caches a one-time allocation global table of @desktop_file_dirs. +{ + desktop_file_dirs_realloc + Memcheck:Leak + match-leak-kinds:reachable + fun:realloc + ... + fun:desktop_file_dirs_lock +} + +# gdesktopappinfo.c caches a one-time allocation global table of @desktop_file_dirs. +{ + desktop_file_dir_unindexed_setup_search + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:desktop_file_dir_unindexed_setup_search + fun:desktop_file_dir_unindexed_setup_search +} + +# g_io_extension_point_register() caches a one-time allocation global table of @extension_points. +{ + g_io_extension_point_register + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_io_extension_point_register +} + +# g_strerror() caches a one-time allocation global table of @errors. +{ + g_strerror + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_locale_to_utf8 + fun:g_strerror +} + +# g_socket_connection_factory_register_type() caches a one-time allocation global table of @connection_types. +{ + g_socket_connection_factory_register_type + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_socket_connection_factory_register_type +} + +# g_dbus_error_quark() never unregisters itself as a GDBusError domain, as it’s always available +{ + g_dbus_error_quark + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_dbus_error_register_error_domain + fun:g_dbus_error_quark +} + +# g_win32_registry_get_os_dirs_w*() caches an array of strings that is allocated only once. +{ + g_win32_registry_get_os_dirs + Memcheck:Leak + match-leak-kinds:reachable,definite + fun:malloc + ... + fun:g_win32_registry_get_os_dirs* +} + +# Thread-private data allocated once per thread +{ + g_private_set_alloc0 + Memcheck:Leak + match-leak-kinds:definite,reachable + fun:malloc + ... + fun:g_private_set_alloc0 +} +{ + g_private_set_alloc0-calloc + Memcheck:Leak + match-leak-kinds:definite,reachable + fun:calloc + ... + fun:g_private_set_alloc0 +} + +# Keys for thread-private data +{ + g_private_key + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + fun:g_private_impl_new +} + +# Thread-private GMainContext stack +{ + g_main_context_push_thread_default + Memcheck:Leak + match-leak-kinds:definite,reachable + fun:malloc + ... + fun:g_queue_new + fun:g_main_context_push_thread_default +} + +# One-time allocations for #GFileInfo attribute cache +{ + g_file_info_attribute_cache + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:ensure_attribute_hash + ... + fun:g_file_* +} +{ + g_file_info_attribute_cache2 + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:ensure_attribute_hash + ... + fun:g_file_* +} +{ + g_file_info_attribute_cache3 + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:lookup_namespace + ... + fun:g_file_* +} +{ + g_file_info_attribute_cache4 + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:lookup_namespace + ... + fun:g_file_* +} + +# Cached charset +{ + g_get_charset + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_get_charset +} + +{ + g_get_charset_calloc + Memcheck:Leak + match-leak-kinds:reachable + fun:calloc + ... + fun:g_get_charset +} + +# Global unused thread queue +{ + g_thread_pool_unused_thread_queue + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_async_queue_new_full + ... + fun:g_thread_pool_new +} + +# One-time program name storage +{ + g_set_prgname + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_set_prgname +} + +# Error domains hash +{ + g_error_init + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:g_hash_table_new_full + fun:g_error_init +} + +# Error domain static registration +{ + g_error_domain_register_static + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:g_hash_table_insert + fun:error_domain_register + fun:g_error_domain_register_static +} + +{ + new_quark + Memcheck:Leak + match-leak-kinds:reachable + fun:malloc + ... + fun:g_hash_table_insert + fun:quark_new +} diff --git a/glib/deprecated/gallocator.c b/glib/deprecated/gallocator.c new file mode 100644 index 0000000..66483b6 --- /dev/null +++ b/glib/deprecated/gallocator.c @@ -0,0 +1,104 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "gallocator.h" + +#include +#include + +struct _GMemChunk { + guint alloc_size; /* the size of an atom */ +}; + +GMemChunk* +g_mem_chunk_new (const gchar *name, + gint atom_size, + gsize area_size, + gint type) +{ + GMemChunk *mem_chunk; + + g_return_val_if_fail (atom_size > 0, NULL); + + mem_chunk = g_slice_new (GMemChunk); + mem_chunk->alloc_size = atom_size; + + return mem_chunk; +} + +void +g_mem_chunk_destroy (GMemChunk *mem_chunk) +{ + g_return_if_fail (mem_chunk != NULL); + + g_slice_free (GMemChunk, mem_chunk); +} + +gpointer +g_mem_chunk_alloc (GMemChunk *mem_chunk) +{ + g_return_val_if_fail (mem_chunk != NULL, NULL); + + return g_slice_alloc (mem_chunk->alloc_size); +} + +gpointer +g_mem_chunk_alloc0 (GMemChunk *mem_chunk) +{ + g_return_val_if_fail (mem_chunk != NULL, NULL); + + return g_slice_alloc0 (mem_chunk->alloc_size); +} + +void +g_mem_chunk_free (GMemChunk *mem_chunk, + gpointer mem) +{ + g_return_if_fail (mem_chunk != NULL); + + g_slice_free1 (mem_chunk->alloc_size, mem); +} + +GAllocator* +g_allocator_new (const gchar *name, + guint n_preallocs) +{ + /* some (broken) GAllocator uses depend on non-NULL allocators */ + return (void *) 1; +} + +void g_allocator_free (GAllocator *allocator) { } + +void g_mem_chunk_clean (GMemChunk *mem_chunk) { } +void g_mem_chunk_reset (GMemChunk *mem_chunk) { } +void g_mem_chunk_print (GMemChunk *mem_chunk) { } +void g_mem_chunk_info (void) { } +void g_blow_chunks (void) { } + +void g_list_push_allocator (GAllocator *allocator) { } +void g_list_pop_allocator (void) { } + +void g_slist_push_allocator (GAllocator *allocator) { } +void g_slist_pop_allocator (void) { } + +void g_node_push_allocator (GAllocator *allocator) { } +void g_node_pop_allocator (void) { } diff --git a/glib/deprecated/gallocator.h b/glib/deprecated/gallocator.h new file mode 100644 index 0000000..005e92b --- /dev/null +++ b/glib/deprecated/gallocator.h @@ -0,0 +1,88 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __G_ALLOCATOR_H__ +#define __G_ALLOCATOR_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GAllocator GAllocator; +typedef struct _GMemChunk GMemChunk; + +#define G_ALLOC_ONLY 1 +#define G_ALLOC_AND_FREE 2 +#define G_ALLOCATOR_LIST 1 +#define G_ALLOCATOR_SLIST 2 +#define G_ALLOCATOR_NODE 3 + +#define g_chunk_new(type, chunk) ((type *) g_mem_chunk_alloc (chunk)) +#define g_chunk_new0(type, chunk) ((type *) g_mem_chunk_alloc0 (chunk)) +#define g_chunk_free(mem, mem_chunk) (g_mem_chunk_free (mem_chunk, mem)) +#define g_mem_chunk_create(type, x, y) (g_mem_chunk_new (NULL, sizeof (type), 0, 0)) + + +GLIB_DEPRECATED +GMemChunk * g_mem_chunk_new (const gchar *name, + gint atom_size, + gsize area_size, + gint type); +GLIB_DEPRECATED +void g_mem_chunk_destroy (GMemChunk *mem_chunk); +GLIB_DEPRECATED +gpointer g_mem_chunk_alloc (GMemChunk *mem_chunk); +GLIB_DEPRECATED +gpointer g_mem_chunk_alloc0 (GMemChunk *mem_chunk); +GLIB_DEPRECATED +void g_mem_chunk_free (GMemChunk *mem_chunk, + gpointer mem); +GLIB_DEPRECATED +void g_mem_chunk_clean (GMemChunk *mem_chunk); +GLIB_DEPRECATED +void g_mem_chunk_reset (GMemChunk *mem_chunk); +GLIB_DEPRECATED +void g_mem_chunk_print (GMemChunk *mem_chunk); +GLIB_DEPRECATED +void g_mem_chunk_info (void); +GLIB_DEPRECATED +void g_blow_chunks (void); + + +GLIB_DEPRECATED +GAllocator * g_allocator_new (const gchar *name, + guint n_preallocs); +GLIB_DEPRECATED +void g_allocator_free (GAllocator *allocator); +GLIB_DEPRECATED +void g_list_push_allocator (GAllocator *allocator); +GLIB_DEPRECATED +void g_list_pop_allocator (void); +GLIB_DEPRECATED +void g_slist_push_allocator (GAllocator *allocator); +GLIB_DEPRECATED +void g_slist_pop_allocator (void); +GLIB_DEPRECATED +void g_node_push_allocator (GAllocator *allocator); +GLIB_DEPRECATED +void g_node_pop_allocator (void); + +G_END_DECLS + +#endif /* __G_ALLOCATOR_H__ */ diff --git a/glib/deprecated/gcache.c b/glib/deprecated/gcache.c new file mode 100644 index 0000000..9e04145 --- /dev/null +++ b/glib/deprecated/gcache.c @@ -0,0 +1,350 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "gcache.h" + +#include "gslice.h" +#include "ghash.h" +#include "gtestutils.h" + +/** + * SECTION:caches + * @title: Caches + * @short_description: caches allow sharing of complex data structures + * to save resources + * + * A #GCache allows sharing of complex data structures, in order to + * save system resources. + * + * GCache uses keys and values. A GCache key describes the properties + * of a particular resource. A GCache value is the actual resource. + * + * GCache has been marked as deprecated, since this API is rarely + * used and not very actively maintained. + */ + +typedef struct _GCacheNode GCacheNode; + +struct _GCacheNode +{ + /* A reference counted node */ + gpointer value; + gint ref_count; +}; + +/** + * GCache: + * + * The #GCache struct is an opaque data structure containing + * information about a #GCache. It should only be accessed via the + * following functions. + * + * Deprecated:2.32: Use a #GHashTable instead + */ +struct _GCache +{ + /* Called to create a value from a key */ + GCacheNewFunc value_new_func; + + /* Called to destroy a value */ + GCacheDestroyFunc value_destroy_func; + + /* Called to duplicate a key */ + GCacheDupFunc key_dup_func; + + /* Called to destroy a key */ + GCacheDestroyFunc key_destroy_func; + + /* Associates keys with nodes */ + GHashTable *key_table; + + /* Associates nodes with keys */ + GHashTable *value_table; +}; + +static inline GCacheNode* +g_cache_node_new (gpointer value) +{ + GCacheNode *node = g_slice_new (GCacheNode); + node->value = value; + node->ref_count = 1; + return node; +} + +static inline void +g_cache_node_destroy (GCacheNode *node) +{ + g_slice_free (GCacheNode, node); +} + +/** + * g_cache_new: + * @value_new_func: a function to create a new object given a key. + * This is called by g_cache_insert() if an object + * with the given key does not already exist + * @value_destroy_func: a function to destroy an object. It is called + * by g_cache_remove() when the object is no + * longer needed (i.e. its reference count drops + * to 0) + * @key_dup_func: a function to copy a key. It is called by + * g_cache_insert() if the key does not already exist in + * the #GCache + * @key_destroy_func: a function to destroy a key. It is called by + * g_cache_remove() when the object is no longer + * needed (i.e. its reference count drops to 0) + * @hash_key_func: a function to create a hash value from a key + * @hash_value_func: a function to create a hash value from a value + * @key_equal_func: a function to compare two keys. It should return + * %TRUE if the two keys are equivalent + * + * Creates a new #GCache. + * + * Returns: a new #GCache + * + * Deprecated:2.32: Use a #GHashTable instead + */ + +/** + * GCacheNewFunc: + * @key: a #GCache key + * + * Specifies the type of the @value_new_func function passed to + * g_cache_new(). It is passed a #GCache key and should create the + * value corresponding to the key. + * + * Returns: a new #GCache value corresponding to the key. + */ + +/** + * GCacheDestroyFunc: + * @value: the #GCache value to destroy + * + * Specifies the type of the @value_destroy_func and @key_destroy_func + * functions passed to g_cache_new(). The functions are passed a + * pointer to the #GCache key or #GCache value and should free any + * memory and other resources associated with it. + */ + +/** + * GCacheDupFunc: + * @value: the #GCache key to destroy (__not__ a + * #GCache value as it seems) + * + * Specifies the type of the @key_dup_func function passed to + * g_cache_new(). The function is passed a key + * (__not__ a value as the prototype implies) and + * should return a duplicate of the key. + * + * Returns: a copy of the #GCache key + */ +GCache* +g_cache_new (GCacheNewFunc value_new_func, + GCacheDestroyFunc value_destroy_func, + GCacheDupFunc key_dup_func, + GCacheDestroyFunc key_destroy_func, + GHashFunc hash_key_func, + GHashFunc hash_value_func, + GEqualFunc key_equal_func) +{ + GCache *cache; + + g_return_val_if_fail (value_new_func != NULL, NULL); + g_return_val_if_fail (value_destroy_func != NULL, NULL); + g_return_val_if_fail (key_dup_func != NULL, NULL); + g_return_val_if_fail (key_destroy_func != NULL, NULL); + g_return_val_if_fail (hash_key_func != NULL, NULL); + g_return_val_if_fail (hash_value_func != NULL, NULL); + g_return_val_if_fail (key_equal_func != NULL, NULL); + + cache = g_slice_new (GCache); + cache->value_new_func = value_new_func; + cache->value_destroy_func = value_destroy_func; + cache->key_dup_func = key_dup_func; + cache->key_destroy_func = key_destroy_func; + cache->key_table = g_hash_table_new (hash_key_func, key_equal_func); + cache->value_table = g_hash_table_new (hash_value_func, NULL); + + return cache; +} + +/** + * g_cache_destroy: + * @cache: a #GCache + * + * Frees the memory allocated for the #GCache. + * + * Note that it does not destroy the keys and values which were + * contained in the #GCache. + * + * Deprecated:2.32: Use a #GHashTable instead + */ +void +g_cache_destroy (GCache *cache) +{ + g_return_if_fail (cache != NULL); + + g_hash_table_destroy (cache->key_table); + g_hash_table_destroy (cache->value_table); + g_slice_free (GCache, cache); +} + +/** + * g_cache_insert: + * @cache: a #GCache + * @key: a key describing a #GCache object + * + * Gets the value corresponding to the given key, creating it if + * necessary. It first checks if the value already exists in the + * #GCache, by using the @key_equal_func function passed to + * g_cache_new(). If it does already exist it is returned, and its + * reference count is increased by one. If the value does not currently + * exist, if is created by calling the @value_new_func. The key is + * duplicated by calling @key_dup_func and the duplicated key and value + * are inserted into the #GCache. + * + * Returns: a pointer to a #GCache value + * + * Deprecated:2.32: Use a #GHashTable instead + */ +gpointer +g_cache_insert (GCache *cache, + gpointer key) +{ + GCacheNode *node; + gpointer value; + + g_return_val_if_fail (cache != NULL, NULL); + + node = g_hash_table_lookup (cache->key_table, key); + if (node) + { + node->ref_count += 1; + return node->value; + } + + key = (* cache->key_dup_func) (key); + value = (* cache->value_new_func) (key); + node = g_cache_node_new (value); + + g_hash_table_insert (cache->key_table, key, node); + g_hash_table_insert (cache->value_table, value, key); + + return node->value; +} + +/** + * g_cache_remove: + * @cache: a #GCache + * @value: the value to remove + * + * Decreases the reference count of the given value. If it drops to 0 + * then the value and its corresponding key are destroyed, using the + * @value_destroy_func and @key_destroy_func passed to g_cache_new(). + * + * Deprecated:2.32: Use a #GHashTable instead + */ +void +g_cache_remove (GCache *cache, + gconstpointer value) +{ + GCacheNode *node; + gpointer key; + + g_return_if_fail (cache != NULL); + + key = g_hash_table_lookup (cache->value_table, value); + node = g_hash_table_lookup (cache->key_table, key); + + g_return_if_fail (node != NULL); + + node->ref_count -= 1; + if (node->ref_count == 0) + { + g_hash_table_remove (cache->value_table, value); + g_hash_table_remove (cache->key_table, key); + + (* cache->key_destroy_func) (key); + (* cache->value_destroy_func) (node->value); + g_cache_node_destroy (node); + } +} + +/** + * g_cache_key_foreach: + * @cache: a #GCache + * @func: the function to call with each #GCache key + * @user_data: user data to pass to the function + * + * Calls the given function for each of the keys in the #GCache. + * + * NOTE @func is passed three parameters, the value and key of a cache + * entry and the @user_data. The order of value and key is different + * from the order in which g_hash_table_foreach() passes key-value + * pairs to its callback function ! + * + * Deprecated:2.32: Use a #GHashTable instead + */ +void +g_cache_key_foreach (GCache *cache, + GHFunc func, + gpointer user_data) +{ + g_return_if_fail (cache != NULL); + g_return_if_fail (func != NULL); + + g_hash_table_foreach (cache->value_table, func, user_data); +} + +/** + * g_cache_value_foreach: + * @cache: a #GCache + * @func: the function to call with each #GCache value + * @user_data: user data to pass to the function + * + * Calls the given function for each of the values in the #GCache. + * + * Deprecated:2.10: The reason is that it passes pointers to internal + * data structures to @func; use g_cache_key_foreach() instead + */ +void +g_cache_value_foreach (GCache *cache, + GHFunc func, + gpointer user_data) +{ + g_return_if_fail (cache != NULL); + g_return_if_fail (func != NULL); + + g_hash_table_foreach (cache->key_table, func, user_data); +} diff --git a/glib/deprecated/gcache.h b/glib/deprecated/gcache.h new file mode 100644 index 0000000..e1c1f2c --- /dev/null +++ b/glib/deprecated/gcache.h @@ -0,0 +1,75 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_CACHE_H__ +#define __G_CACHE_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GCache GCache GLIB_DEPRECATED_TYPE_IN_2_26_FOR(GHashTable); + +typedef gpointer (*GCacheNewFunc) (gpointer key) GLIB_DEPRECATED_TYPE_IN_2_26; +typedef gpointer (*GCacheDupFunc) (gpointer value) GLIB_DEPRECATED_TYPE_IN_2_26; +typedef void (*GCacheDestroyFunc) (gpointer value) GLIB_DEPRECATED_TYPE_IN_2_26; + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +/* Caches + */ +GLIB_DEPRECATED +GCache* g_cache_new (GCacheNewFunc value_new_func, + GCacheDestroyFunc value_destroy_func, + GCacheDupFunc key_dup_func, + GCacheDestroyFunc key_destroy_func, + GHashFunc hash_key_func, + GHashFunc hash_value_func, + GEqualFunc key_equal_func); +GLIB_DEPRECATED +void g_cache_destroy (GCache *cache); +GLIB_DEPRECATED +gpointer g_cache_insert (GCache *cache, + gpointer key); +GLIB_DEPRECATED +void g_cache_remove (GCache *cache, + gconstpointer value); +GLIB_DEPRECATED +void g_cache_key_foreach (GCache *cache, + GHFunc func, + gpointer user_data); +GLIB_DEPRECATED +void g_cache_value_foreach (GCache *cache, + GHFunc func, + gpointer user_data); + +G_GNUC_END_IGNORE_DEPRECATIONS + +G_END_DECLS + +#endif /* __G_CACHE_H__ */ diff --git a/glib/deprecated/gcompletion.c b/glib/deprecated/gcompletion.c new file mode 100644 index 0000000..5f0979b --- /dev/null +++ b/glib/deprecated/gcompletion.c @@ -0,0 +1,503 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "gcompletion.h" + +#include +#include +#include + +#include + +/** + * SECTION:completion + * @title: Automatic String Completion + * @short_description: support for automatic completion using a group + * of target strings + * + * #GCompletion provides support for automatic completion of a string + * using any group of target strings. It is typically used for file + * name completion as is common in many UNIX shells. + * + * A #GCompletion is created using g_completion_new(). Target items are + * added and removed with g_completion_add_items(), + * g_completion_remove_items() and g_completion_clear_items(). A + * completion attempt is requested with g_completion_complete() or + * g_completion_complete_utf8(). When no longer needed, the + * #GCompletion is freed with g_completion_free(). + * + * Items in the completion can be simple strings (e.g. filenames), or + * pointers to arbitrary data structures. If data structures are used + * you must provide a #GCompletionFunc in g_completion_new(), which + * retrieves the item's string from the data structure. You can change + * the way in which strings are compared by setting a different + * #GCompletionStrncmpFunc in g_completion_set_compare(). + * + * GCompletion has been marked as deprecated, since this API is rarely + * used and not very actively maintained. + **/ + +/** + * GCompletion: + * @items: list of target items (strings or data structures). + * @func: function which is called to get the string associated with a + * target item. It is %NULL if the target items are strings. + * @prefix: the last prefix passed to g_completion_complete() or + * g_completion_complete_utf8(). + * @cache: the list of items which begin with @prefix. + * @strncmp_func: The function to use when comparing strings. Use + * g_completion_set_compare() to modify this function. + * + * The data structure used for automatic completion. + **/ + +/** + * GCompletionFunc: + * @Param1: the completion item. + * + * Specifies the type of the function passed to g_completion_new(). It + * should return the string corresponding to the given target item. + * This is used when you use data structures as #GCompletion items. + * + * Returns: the string corresponding to the item. + **/ + +/** + * GCompletionStrncmpFunc: + * @s1: string to compare with @s2. + * @s2: string to compare with @s1. + * @n: maximal number of bytes to compare. + * + * Specifies the type of the function passed to + * g_completion_set_compare(). This is used when you use strings as + * #GCompletion items. + * + * Returns: an integer less than, equal to, or greater than zero if + * the first @n bytes of @s1 is found, respectively, to be + * less than, to match, or to be greater than the first @n + * bytes of @s2. + **/ + +static void completion_check_cache (GCompletion* cmp, + gchar** new_prefix); + +/** + * g_completion_new: + * @func: the function to be called to return the string representing + * an item in the #GCompletion, or %NULL if strings are going to + * be used as the #GCompletion items. + * + * Creates a new #GCompletion. + * + * Returns: the new #GCompletion. + **/ +GCompletion* +g_completion_new (GCompletionFunc func) +{ + GCompletion* gcomp; + + gcomp = g_new (GCompletion, 1); + gcomp->items = NULL; + gcomp->cache = NULL; + gcomp->prefix = NULL; + gcomp->func = func; + gcomp->strncmp_func = strncmp; + + return gcomp; +} + +/** + * g_completion_add_items: + * @cmp: the #GCompletion. + * @items: (transfer none): the list of items to add. + * + * Adds items to the #GCompletion. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_add_items (GCompletion* cmp, + GList* items) +{ + GList* it; + + g_return_if_fail (cmp != NULL); + + /* optimize adding to cache? */ + if (cmp->cache) + { + g_list_free (cmp->cache); + cmp->cache = NULL; + } + + if (cmp->prefix) + { + g_free (cmp->prefix); + cmp->prefix = NULL; + } + + it = items; + while (it) + { + cmp->items = g_list_prepend (cmp->items, it->data); + it = it->next; + } +} + +/** + * g_completion_remove_items: + * @cmp: the #GCompletion. + * @items: (transfer none): the items to remove. + * + * Removes items from a #GCompletion. The items are not freed, so if the memory + * was dynamically allocated, free @items with g_list_free_full() after calling + * this function. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_remove_items (GCompletion* cmp, + GList* items) +{ + GList* it; + + g_return_if_fail (cmp != NULL); + + it = items; + while (cmp->items && it) + { + cmp->items = g_list_remove (cmp->items, it->data); + it = it->next; + } + + it = items; + while (cmp->cache && it) + { + cmp->cache = g_list_remove(cmp->cache, it->data); + it = it->next; + } +} + +/** + * g_completion_clear_items: + * @cmp: the #GCompletion. + * + * Removes all items from the #GCompletion. The items are not freed, so if the + * memory was dynamically allocated, it should be freed after calling this + * function. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_clear_items (GCompletion* cmp) +{ + g_return_if_fail (cmp != NULL); + + g_list_free (cmp->items); + cmp->items = NULL; + g_list_free (cmp->cache); + cmp->cache = NULL; + g_free (cmp->prefix); + cmp->prefix = NULL; +} + +static void +completion_check_cache (GCompletion* cmp, + gchar** new_prefix) +{ + GList* list; + gsize len; + gsize i; + gsize plen; + gchar* postfix; + gchar* s; + + if (!new_prefix) + return; + if (!cmp->cache) + { + *new_prefix = NULL; + return; + } + + len = strlen(cmp->prefix); + list = cmp->cache; + s = cmp->func ? cmp->func (list->data) : (gchar*) list->data; + postfix = s + len; + plen = strlen (postfix); + list = list->next; + + while (list && plen) + { + s = cmp->func ? cmp->func (list->data) : (gchar*) list->data; + s += len; + for (i = 0; i < plen; ++i) + { + if (postfix[i] != s[i]) + break; + } + plen = i; + list = list->next; + } + + *new_prefix = g_new0 (gchar, len + plen + 1); + strncpy (*new_prefix, cmp->prefix, len); + strncpy (*new_prefix + len, postfix, plen); +} + +/** + * g_completion_complete_utf8: + * @cmp: the #GCompletion + * @prefix: the prefix string, typically used by the user, which is compared + * with each of the items + * @new_prefix: if non-%NULL, returns the longest prefix which is common to all + * items that matched @prefix, or %NULL if no items matched @prefix. + * This string should be freed when no longer needed. + * + * Attempts to complete the string @prefix using the #GCompletion target items. + * In contrast to g_completion_complete(), this function returns the largest common + * prefix that is a valid UTF-8 string, omitting a possible common partial + * character. + * + * You should use this function instead of g_completion_complete() if your + * items are UTF-8 strings. + * + * Returns: (element-type utf8) (transfer none): the list of items whose strings begin with @prefix. This should + * not be changed. + * + * Since: 2.4 + * + * Deprecated: 2.26: Rarely used API + **/ +GList* +g_completion_complete_utf8 (GCompletion *cmp, + const gchar *prefix, + gchar **new_prefix) +{ + GList *list; + gchar *p, *q; + + list = g_completion_complete (cmp, prefix, new_prefix); + + if (new_prefix && *new_prefix) + { + p = *new_prefix + strlen (*new_prefix); + q = g_utf8_find_prev_char (*new_prefix, p); + + switch (g_utf8_get_char_validated (q, p - q)) + { + case (gunichar)-2: + case (gunichar)-1: + *q = 0; + break; + default: ; + } + + } + + return list; +} + +/** + * g_completion_complete: + * @cmp: the #GCompletion. + * @prefix: the prefix string, typically typed by the user, which is + * compared with each of the items. + * @new_prefix: if non-%NULL, returns the longest prefix which is + * common to all items that matched @prefix, or %NULL if + * no items matched @prefix. This string should be freed + * when no longer needed. + * + * Attempts to complete the string @prefix using the #GCompletion + * target items. + * + * Returns: (transfer none): the list of items whose strings begin with + * @prefix. This should not be changed. + * + * Deprecated: 2.26: Rarely used API + **/ +GList* +g_completion_complete (GCompletion* cmp, + const gchar* prefix, + gchar** new_prefix) +{ + gsize plen, len; + gboolean done = FALSE; + GList* list; + + g_return_val_if_fail (cmp != NULL, NULL); + g_return_val_if_fail (prefix != NULL, NULL); + + len = strlen (prefix); + if (cmp->prefix && cmp->cache) + { + plen = strlen (cmp->prefix); + if (plen <= len && ! cmp->strncmp_func (prefix, cmp->prefix, plen)) + { + /* use the cache */ + list = cmp->cache; + while (list) + { + GList *next = list->next; + + if (cmp->strncmp_func (prefix, + cmp->func ? cmp->func (list->data) : (gchar*) list->data, + len)) + cmp->cache = g_list_delete_link (cmp->cache, list); + + list = next; + } + done = TRUE; + } + } + + if (!done) + { + /* normal code */ + g_list_free (cmp->cache); + cmp->cache = NULL; + list = cmp->items; + while (*prefix && list) + { + if (!cmp->strncmp_func (prefix, + cmp->func ? cmp->func (list->data) : (gchar*) list->data, + len)) + cmp->cache = g_list_prepend (cmp->cache, list->data); + list = list->next; + } + } + if (cmp->prefix) + { + g_free (cmp->prefix); + cmp->prefix = NULL; + } + if (cmp->cache) + cmp->prefix = g_strdup (prefix); + completion_check_cache (cmp, new_prefix); + + return *prefix ? cmp->cache : cmp->items; +} + +/** + * g_completion_free: + * @cmp: the #GCompletion. + * + * Frees all memory used by the #GCompletion. The items are not freed, so if + * the memory was dynamically allocated, it should be freed after calling this + * function. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_free (GCompletion* cmp) +{ + g_return_if_fail (cmp != NULL); + + g_completion_clear_items (cmp); + g_free (cmp); +} + +/** + * g_completion_set_compare: + * @cmp: a #GCompletion. + * @strncmp_func: the string comparison function. + * + * Sets the function to use for string comparisons. The default string + * comparison function is strncmp(). + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_set_compare(GCompletion *cmp, + GCompletionStrncmpFunc strncmp_func) +{ + cmp->strncmp_func = strncmp_func; +} + +#ifdef TEST_COMPLETION +#include +int +main (int argc, + char* argv[]) +{ + FILE *file; + gchar buf[1024]; + GList *list; + GList *result; + GList *tmp; + GCompletion *cmp; + gint i; + gchar *longp = NULL; + + if (argc < 3) + { + g_warning ("Usage: %s filename prefix1 [prefix2 ...]", + (argc > 0) ? argv[0] : "gcompletion"); + return 1; + } + + file = fopen (argv[1], "r"); + if (!file) + { + g_warning ("Cannot open %s", argv[1]); + return 1; + } + + cmp = g_completion_new (NULL); + list = g_list_alloc (); + while (fgets (buf, 1024, file)) + { + list->data = g_strdup (buf); + g_completion_add_items (cmp, list); + } + fclose (file); + + for (i = 2; i < argc; ++i) + { + printf ("COMPLETING: %s\n", argv[i]); + result = g_completion_complete (cmp, argv[i], &longp); + g_list_foreach (result, (GFunc) printf, NULL); + printf ("LONG MATCH: %s\n", longp); + g_free (longp); + longp = NULL; + } + + g_list_foreach (cmp->items, (GFunc) g_free, NULL); + g_completion_free (cmp); + g_list_free (list); + + return 0; +} +#endif diff --git a/glib/deprecated/gcompletion.h b/glib/deprecated/gcompletion.h new file mode 100644 index 0000000..2fd1f03 --- /dev/null +++ b/glib/deprecated/gcompletion.h @@ -0,0 +1,83 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_COMPLETION_H__ +#define __G_COMPLETION_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GCompletion GCompletion; + +typedef gchar* (*GCompletionFunc) (gpointer); + +/* GCompletion + */ + +typedef gint (*GCompletionStrncmpFunc) (const gchar *s1, + const gchar *s2, + gsize n); + +struct _GCompletion +{ + GList* items; + GCompletionFunc func; + + gchar* prefix; + GList* cache; + GCompletionStrncmpFunc strncmp_func; +}; + +GLIB_DEPRECATED_IN_2_26 +GCompletion* g_completion_new (GCompletionFunc func); +GLIB_DEPRECATED_IN_2_26 +void g_completion_add_items (GCompletion* cmp, + GList* items); +GLIB_DEPRECATED_IN_2_26 +void g_completion_remove_items (GCompletion* cmp, + GList* items); +GLIB_DEPRECATED_IN_2_26 +void g_completion_clear_items (GCompletion* cmp); +GLIB_DEPRECATED_IN_2_26 +GList* g_completion_complete (GCompletion* cmp, + const gchar* prefix, + gchar** new_prefix); +GLIB_DEPRECATED_IN_2_26 +GList* g_completion_complete_utf8 (GCompletion *cmp, + const gchar* prefix, + gchar** new_prefix); +GLIB_DEPRECATED_IN_2_26 +void g_completion_set_compare (GCompletion *cmp, + GCompletionStrncmpFunc strncmp_func); +GLIB_DEPRECATED_IN_2_26 +void g_completion_free (GCompletion* cmp); + +G_END_DECLS + +#endif /* __G_COMPLETION_H__ */ diff --git a/glib/deprecated/gmain.h b/glib/deprecated/gmain.h new file mode 100644 index 0000000..5d08eb6 --- /dev/null +++ b/glib/deprecated/gmain.h @@ -0,0 +1,135 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_DEPRECATED_MAIN_H__ +#define __G_DEPRECATED_MAIN_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* ============== Compat main loop stuff ================== */ + +/** + * g_main_new: + * @is_running: set to %TRUE to indicate that the loop is running. This + * is not very important since calling g_main_run() will set this + * to %TRUE anyway. + * + * Creates a new #GMainLoop for th default main context. + * + * Returns: a new #GMainLoop + * + * Deprecated: 2.2: Use g_main_loop_new() instead + */ +#define g_main_new(is_running) g_main_loop_new (NULL, is_running) GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_main_loop_new) + +/** + * g_main_run: + * @loop: a #GMainLoop + * + * Runs a main loop until it stops running. + * + * Deprecated: 2.2: Use g_main_loop_run() instead + */ +#define g_main_run(loop) g_main_loop_run(loop) GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_main_loop_run) + +/** + * g_main_quit: + * @loop: a #GMainLoop + * + * Stops the #GMainLoop. + * If g_main_run() was called to run the #GMainLoop, it will now return. + * + * Deprecated: 2.2: Use g_main_loop_quit() instead + */ +#define g_main_quit(loop) g_main_loop_quit(loop) GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_main_loop_quit) + +/** + * g_main_destroy: + * @loop: a #GMainLoop + * + * Frees the memory allocated for the #GMainLoop. + * + * Deprecated: 2.2: Use g_main_loop_unref() instead + */ +#define g_main_destroy(loop) g_main_loop_unref(loop) GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_main_loop_unref) + +/** + * g_main_is_running: + * @loop: a #GMainLoop + * + * Checks if the main loop is running. + * + * Returns: %TRUE if the main loop is running + * + * Deprecated: 2.2: Use g_main_loop_is_running() instead + */ +#define g_main_is_running(loop) g_main_loop_is_running(loop) GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_main_loop_is_running) + +/** + * g_main_iteration: + * @may_block: set to %TRUE if it should block (i.e. wait) until an event + * source becomes ready. It will return after an event source has been + * processed. If set to %FALSE it will return immediately if no event + * source is ready to be processed. + * + * Runs a single iteration for the default #GMainContext. + * + * Returns: %TRUE if more events are pending. + * + * Deprecated: 2.2: Use g_main_context_iteration() instead. + */ +#define g_main_iteration(may_block) g_main_context_iteration (NULL, may_block) GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_main_context_iteration) + +/** + * g_main_pending: + * + * Checks if any events are pending for the default #GMainContext + * (i.e. ready to be processed). + * + * Returns: %TRUE if any events are pending. + * + * Deprecated: 2.2: Use g_main_context_pending() instead. + */ +#define g_main_pending() g_main_context_pending (NULL) GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_main_context_pending) + +/** + * g_main_set_poll_func: + * @func: the function to call to poll all file descriptors + * + * Sets the function to use for the handle polling of file descriptors + * for the default main context. + * + * Deprecated: 2.2: Use g_main_context_set_poll_func() again + */ +#define g_main_set_poll_func(func) g_main_context_set_poll_func (NULL, func) GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_main_context_set_poll_func) + +G_END_DECLS + +#endif /* __G_DEPRECATED_MAIN_H__ */ diff --git a/glib/deprecated/grel.c b/glib/deprecated/grel.c new file mode 100644 index 0000000..b48ec11 --- /dev/null +++ b/glib/deprecated/grel.c @@ -0,0 +1,685 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "grel.h" + +#include +#include +#include +#include +#include + +#include +#include + +/** + * SECTION:relations + * @title: Relations and Tuples + * @short_description: tables of data which can be indexed on any + * number of fields + * + * A #GRelation is a table of data which can be indexed on any number + * of fields, rather like simple database tables. A #GRelation contains + * a number of records, called tuples. Each record contains a number of + * fields. Records are not ordered, so it is not possible to find the + * record at a particular index. + * + * Note that #GRelation tables are currently limited to 2 fields. + * + * To create a GRelation, use g_relation_new(). + * + * To specify which fields should be indexed, use g_relation_index(). + * Note that this must be called before any tuples are added to the + * #GRelation. + * + * To add records to a #GRelation use g_relation_insert(). + * + * To determine if a given record appears in a #GRelation, use + * g_relation_exists(). Note that fields are compared directly, so + * pointers must point to the exact same position (i.e. different + * copies of the same string will not match.) + * + * To count the number of records which have a particular value in a + * given field, use g_relation_count(). + * + * To get all the records which have a particular value in a given + * field, use g_relation_select(). To access fields of the resulting + * records, use g_tuples_index(). To free the resulting records use + * g_tuples_destroy(). + * + * To delete all records which have a particular value in a given + * field, use g_relation_delete(). + * + * To destroy the #GRelation, use g_relation_destroy(). + * + * To help debug #GRelation objects, use g_relation_print(). + * + * GRelation has been marked as deprecated, since this API has never + * been fully implemented, is not very actively maintained and rarely + * used. + **/ + +typedef struct _GRealTuples GRealTuples; + +/** + * GRelation: + * + * The #GRelation struct is an opaque data structure to represent a + * [Relation][glib-Relations-and-Tuples]. It should + * only be accessed via the following functions. + **/ +struct _GRelation +{ + gint fields; + gint current_field; + + GHashTable *all_tuples; + GHashTable **hashed_tuple_tables; + + gint count; +}; + +/** + * GTuples: + * @len: the number of records that matched. + * + * The #GTuples struct is used to return records (or tuples) from the + * #GRelation by g_relation_select(). It only contains one public + * member - the number of records that matched. To access the matched + * records, you must use g_tuples_index(). + **/ +struct _GRealTuples +{ + gint len; + gint width; + gpointer *data; +}; + +static gboolean +tuple_equal_2 (gconstpointer v_a, + gconstpointer v_b) +{ + gpointer* a = (gpointer*) v_a; + gpointer* b = (gpointer*) v_b; + + return a[0] == b[0] && a[1] == b[1]; +} + +static guint +tuple_hash_2 (gconstpointer v_a) +{ +#if GLIB_SIZEOF_VOID_P > GLIB_SIZEOF_LONG + /* In practise this snippet has been written for 64-bit Windows + * where ints are 32 bits, pointers 64 bits. More exotic platforms + * need more tweaks. + */ + guint* a = (guint*) v_a; + + return (a[0] ^ a[1] ^ a[2] ^ a[3]); +#else + gpointer* a = (gpointer*) v_a; + + return (gulong)a[0] ^ (gulong)a[1]; +#endif +} + +static GHashFunc +tuple_hash (gint fields) +{ + switch (fields) + { + case 2: + return tuple_hash_2; + default: + g_error ("no tuple hash for %d", fields); + } + + return NULL; +} + +static GEqualFunc +tuple_equal (gint fields) +{ + switch (fields) + { + case 2: + return tuple_equal_2; + default: + g_error ("no tuple equal for %d", fields); + } + + return NULL; +} + +/** + * g_relation_new: + * @fields: the number of fields. + * + * Creates a new #GRelation with the given number of fields. Note that + * currently the number of fields must be 2. + * + * Returns: a new #GRelation. + * + * Deprecated: 2.26: Rarely used API + **/ +GRelation* +g_relation_new (gint fields) +{ + GRelation* rel = g_new0 (GRelation, 1); + + rel->fields = fields; + rel->all_tuples = g_hash_table_new (tuple_hash (fields), tuple_equal (fields)); + rel->hashed_tuple_tables = g_new0 (GHashTable*, fields); + + return rel; +} + +static void +relation_delete_value_tuple (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + GRelation *relation = user_data; + gpointer *tuple = tuple_value; + g_slice_free1 (relation->fields * sizeof (gpointer), tuple); +} + +static void +g_relation_free_array (gpointer key, gpointer value, gpointer user_data) +{ + g_hash_table_destroy ((GHashTable*) value); +} + +/** + * g_relation_destroy: + * @relation: a #GRelation. + * + * Destroys the #GRelation, freeing all memory allocated. However, it + * does not free memory allocated for the tuple data, so you should + * free that first if appropriate. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_relation_destroy (GRelation *relation) +{ + gint i; + + if (relation) + { + for (i = 0; i < relation->fields; i += 1) + { + if (relation->hashed_tuple_tables[i]) + { + g_hash_table_foreach (relation->hashed_tuple_tables[i], g_relation_free_array, NULL); + g_hash_table_destroy (relation->hashed_tuple_tables[i]); + } + } + + g_hash_table_foreach (relation->all_tuples, relation_delete_value_tuple, relation); + g_hash_table_destroy (relation->all_tuples); + + g_free (relation->hashed_tuple_tables); + g_free (relation); + } +} + +/** + * g_relation_index: + * @relation: a #GRelation. + * @field: the field to index, counting from 0. + * @hash_func: a function to produce a hash value from the field data. + * @key_equal_func: a function to compare two values of the given field. + * + * Creates an index on the given field. Note that this must be called + * before any records are added to the #GRelation. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_relation_index (GRelation *relation, + gint field, + GHashFunc hash_func, + GEqualFunc key_equal_func) +{ + g_return_if_fail (relation != NULL); + + g_return_if_fail (relation->count == 0 && relation->hashed_tuple_tables[field] == NULL); + + relation->hashed_tuple_tables[field] = g_hash_table_new (hash_func, key_equal_func); +} + +/** + * g_relation_insert: + * @relation: a #GRelation. + * @...: the fields of the record to add. These must match the + * number of fields in the #GRelation, and of type #gpointer + * or #gconstpointer. + * + * Inserts a record into a #GRelation. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_relation_insert (GRelation *relation, + ...) +{ + gpointer* tuple = g_slice_alloc (relation->fields * sizeof (gpointer)); + va_list args; + gint i; + + va_start (args, relation); + + for (i = 0; i < relation->fields; i += 1) + tuple[i] = va_arg (args, gpointer); + + va_end (args); + + g_hash_table_insert (relation->all_tuples, tuple, tuple); + + relation->count += 1; + + for (i = 0; i < relation->fields; i += 1) + { + GHashTable *table; + gpointer key; + GHashTable *per_key_table; + + table = relation->hashed_tuple_tables[i]; + + if (table == NULL) + continue; + + key = tuple[i]; + per_key_table = g_hash_table_lookup (table, key); + + if (per_key_table == NULL) + { + per_key_table = g_hash_table_new (tuple_hash (relation->fields), tuple_equal (relation->fields)); + g_hash_table_insert (table, key, per_key_table); + } + + g_hash_table_insert (per_key_table, tuple, tuple); + } +} + +static void +g_relation_delete_tuple (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + gpointer *tuple = (gpointer*) tuple_value; + GRelation *relation = (GRelation *) user_data; + gint j; + + g_assert (tuple_key == tuple_value); + + for (j = 0; j < relation->fields; j += 1) + { + GHashTable *one_table = relation->hashed_tuple_tables[j]; + gpointer one_key; + GHashTable *per_key_table; + + if (one_table == NULL) + continue; + + if (j == relation->current_field) + /* can't delete from the table we're foreaching in */ + continue; + + one_key = tuple[j]; + + per_key_table = g_hash_table_lookup (one_table, one_key); + + g_hash_table_remove (per_key_table, tuple); + } + + if (g_hash_table_remove (relation->all_tuples, tuple)) + g_slice_free1 (relation->fields * sizeof (gpointer), tuple); + + relation->count -= 1; +} + +/** + * g_relation_delete: + * @relation: a #GRelation. + * @key: the value to compare with. + * @field: the field of each record to match. + * + * Deletes any records from a #GRelation that have the given key value + * in the given field. + * + * Returns: the number of records deleted. + * + * Deprecated: 2.26: Rarely used API + **/ +gint +g_relation_delete (GRelation *relation, + gconstpointer key, + gint field) +{ + GHashTable *table; + GHashTable *key_table; + gint count; + + g_return_val_if_fail (relation != NULL, 0); + + table = relation->hashed_tuple_tables[field]; + count = relation->count; + + g_return_val_if_fail (table != NULL, 0); + + key_table = g_hash_table_lookup (table, key); + + if (!key_table) + return 0; + + relation->current_field = field; + + g_hash_table_foreach (key_table, g_relation_delete_tuple, relation); + + g_hash_table_remove (table, key); + + g_hash_table_destroy (key_table); + + /* @@@ FIXME: Remove empty hash tables. */ + + return count - relation->count; +} + +static void +g_relation_select_tuple (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + gpointer *tuple = (gpointer*) tuple_value; + GRealTuples *tuples = (GRealTuples*) user_data; + gint stride = sizeof (gpointer) * tuples->width; + + g_assert (tuple_key == tuple_value); + + memcpy (tuples->data + (tuples->len * tuples->width), + tuple, + stride); + + tuples->len += 1; +} + +/** + * g_relation_select: + * @relation: a #GRelation. + * @key: the value to compare with. + * @field: the field of each record to match. + * + * Returns all of the tuples which have the given key in the given + * field. Use g_tuples_index() to access the returned records. The + * returned records should be freed with g_tuples_destroy(). + * + * Returns: the records (tuples) that matched. + * + * Deprecated: 2.26: Rarely used API + **/ +GTuples* +g_relation_select (GRelation *relation, + gconstpointer key, + gint field) +{ + GHashTable *table; + GHashTable *key_table; + GRealTuples *tuples; + gint count; + + g_return_val_if_fail (relation != NULL, NULL); + + table = relation->hashed_tuple_tables[field]; + + g_return_val_if_fail (table != NULL, NULL); + + tuples = g_new0 (GRealTuples, 1); + key_table = g_hash_table_lookup (table, key); + + if (!key_table) + return (GTuples*)tuples; + + count = g_relation_count (relation, key, field); + + tuples->data = g_malloc (sizeof (gpointer) * relation->fields * count); + tuples->width = relation->fields; + + g_hash_table_foreach (key_table, g_relation_select_tuple, tuples); + + g_assert (count == tuples->len); + + return (GTuples*)tuples; +} + +/** + * g_relation_count: + * @relation: a #GRelation. + * @key: the value to compare with. + * @field: the field of each record to match. + * + * Returns the number of tuples in a #GRelation that have the given + * value in the given field. + * + * Returns: the number of matches. + * + * Deprecated: 2.26: Rarely used API + **/ +gint +g_relation_count (GRelation *relation, + gconstpointer key, + gint field) +{ + GHashTable *table; + GHashTable *key_table; + + g_return_val_if_fail (relation != NULL, 0); + + table = relation->hashed_tuple_tables[field]; + + g_return_val_if_fail (table != NULL, 0); + + key_table = g_hash_table_lookup (table, key); + + if (!key_table) + return 0; + + return g_hash_table_size (key_table); +} + +/** + * g_relation_exists: + * @relation: a #GRelation. + * @...: the fields of the record to compare. The number must match + * the number of fields in the #GRelation. + * + * Returns %TRUE if a record with the given values exists in a + * #GRelation. Note that the values are compared directly, so that, for + * example, two copies of the same string will not match. + * + * Returns: %TRUE if a record matches. + * + * Deprecated: 2.26: Rarely used API + **/ +gboolean +g_relation_exists (GRelation *relation, ...) +{ + gpointer *tuple = g_slice_alloc (relation->fields * sizeof (gpointer)); + va_list args; + gint i; + gboolean result; + + va_start(args, relation); + + for (i = 0; i < relation->fields; i += 1) + tuple[i] = va_arg(args, gpointer); + + va_end(args); + + result = g_hash_table_lookup (relation->all_tuples, tuple) != NULL; + + g_slice_free1 (relation->fields * sizeof (gpointer), tuple); + + return result; +} + +/** + * g_tuples_destroy: + * @tuples: the tuple data to free. + * + * Frees the records which were returned by g_relation_select(). This + * should always be called after g_relation_select() when you are + * finished with the records. The records are not removed from the + * #GRelation. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_tuples_destroy (GTuples *tuples0) +{ + GRealTuples *tuples = (GRealTuples*) tuples0; + + if (tuples) + { + g_free (tuples->data); + g_free (tuples); + } +} + +/** + * g_tuples_index: + * @tuples: the tuple data, returned by g_relation_select(). + * @index_: the index of the record. + * @field: the field to return. + * + * Gets a field from the records returned by g_relation_select(). It + * returns the given field of the record at the given index. The + * returned value should not be changed. + * + * Returns: the field of the record. + * + * Deprecated: 2.26: Rarely used API + **/ +gpointer +g_tuples_index (GTuples *tuples0, + gint index, + gint field) +{ + GRealTuples *tuples = (GRealTuples*) tuples0; + + g_return_val_if_fail (tuples0 != NULL, NULL); + g_return_val_if_fail (field < tuples->width, NULL); + + return tuples->data[index * tuples->width + field]; +} + +/* Print + */ + +static void +g_relation_print_one (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + gint i; + GString *gstring; + GRelation* rel = (GRelation*) user_data; + gpointer* tuples = (gpointer*) tuple_value; + + gstring = g_string_new ("["); + + for (i = 0; i < rel->fields; i += 1) + { + g_string_append_printf (gstring, "%p", tuples[i]); + + if (i < (rel->fields - 1)) + g_string_append (gstring, ","); + } + + g_string_append (gstring, "]"); + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "%s", gstring->str); + g_string_free (gstring, TRUE); +} + +static void +g_relation_print_index (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + GRelation* rel = (GRelation*) user_data; + GHashTable* table = (GHashTable*) tuple_value; + + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** key %p", tuple_key); + + g_hash_table_foreach (table, + g_relation_print_one, + rel); +} + +/** + * g_relation_print: + * @relation: a #GRelation. + * + * Outputs information about all records in a #GRelation, as well as + * the indexes. It is for debugging. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_relation_print (GRelation *relation) +{ + gint i; + + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** all tuples (%d)", relation->count); + + g_hash_table_foreach (relation->all_tuples, + g_relation_print_one, + relation); + + for (i = 0; i < relation->fields; i += 1) + { + if (relation->hashed_tuple_tables[i] == NULL) + continue; + + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** index %d", i); + + g_hash_table_foreach (relation->hashed_tuple_tables[i], + g_relation_print_index, + relation); + } + +} diff --git a/glib/deprecated/grel.h b/glib/deprecated/grel.h new file mode 100644 index 0000000..3a65240 --- /dev/null +++ b/glib/deprecated/grel.h @@ -0,0 +1,105 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_REL_H__ +#define __G_REL_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GRelation GRelation; +typedef struct _GTuples GTuples; + +struct _GTuples +{ + guint len; +}; + +/* GRelation + * + * Indexed Relations. Imagine a really simple table in a + * database. Relations are not ordered. This data type is meant for + * maintaining a N-way mapping. + * + * g_relation_new() creates a relation with FIELDS fields + * + * g_relation_destroy() frees all resources + * g_tuples_destroy() frees the result of g_relation_select() + * + * g_relation_index() indexes relation FIELD with the provided + * equality and hash functions. this must be done before any + * calls to insert are made. + * + * g_relation_insert() inserts a new tuple. you are expected to + * provide the right number of fields. + * + * g_relation_delete() deletes all relations with KEY in FIELD + * g_relation_select() returns ... + * g_relation_count() counts ... + */ + +GLIB_DEPRECATED_IN_2_26 +GRelation* g_relation_new (gint fields); +GLIB_DEPRECATED_IN_2_26 +void g_relation_destroy (GRelation *relation); +GLIB_DEPRECATED_IN_2_26 +void g_relation_index (GRelation *relation, + gint field, + GHashFunc hash_func, + GEqualFunc key_equal_func); +GLIB_DEPRECATED_IN_2_26 +void g_relation_insert (GRelation *relation, + ...); +GLIB_DEPRECATED_IN_2_26 +gint g_relation_delete (GRelation *relation, + gconstpointer key, + gint field); +GLIB_DEPRECATED_IN_2_26 +GTuples* g_relation_select (GRelation *relation, + gconstpointer key, + gint field); +GLIB_DEPRECATED_IN_2_26 +gint g_relation_count (GRelation *relation, + gconstpointer key, + gint field); +GLIB_DEPRECATED_IN_2_26 +gboolean g_relation_exists (GRelation *relation, + ...); +GLIB_DEPRECATED_IN_2_26 +void g_relation_print (GRelation *relation); +GLIB_DEPRECATED_IN_2_26 +void g_tuples_destroy (GTuples *tuples); +GLIB_DEPRECATED_IN_2_26 +gpointer g_tuples_index (GTuples *tuples, + gint index_, + gint field); + +G_END_DECLS + +#endif /* __G_REL_H__ */ diff --git a/glib/deprecated/gthread-deprecated.c b/glib/deprecated/gthread-deprecated.c new file mode 100644 index 0000000..be98a74 --- /dev/null +++ b/glib/deprecated/gthread-deprecated.c @@ -0,0 +1,1578 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: MT safety related functions + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * Owen Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "gmessages.h" +#include "gslice.h" +#include "gmain.h" +#include "gthread.h" +#include "gthreadprivate.h" +#include "deprecated/gthread.h" +#include "garray.h" + +#include "gutils.h" + +/* {{{1 Documentation */ + +/** + * SECTION:threads-deprecated + * @title: Deprecated thread API + * @short_description: old thread APIs (for reference only) + * @see_also: #GThread + * + * These APIs are deprecated. You should not use them in new code. + * This section remains only to assist with understanding code that was + * written to use these APIs at some point in the past. + **/ + +/** + * GThreadPriority: + * @G_THREAD_PRIORITY_LOW: a priority lower than normal + * @G_THREAD_PRIORITY_NORMAL: the default priority + * @G_THREAD_PRIORITY_HIGH: a priority higher than normal + * @G_THREAD_PRIORITY_URGENT: the highest priority + * + * Thread priorities. + * + * Deprecated:2.32: Thread priorities no longer have any effect. + */ + +/** + * GThreadFunctions: + * @mutex_new: virtual function pointer for g_mutex_new() + * @mutex_lock: virtual function pointer for g_mutex_lock() + * @mutex_trylock: virtual function pointer for g_mutex_trylock() + * @mutex_unlock: virtual function pointer for g_mutex_unlock() + * @mutex_free: virtual function pointer for g_mutex_free() + * @cond_new: virtual function pointer for g_cond_new() + * @cond_signal: virtual function pointer for g_cond_signal() + * @cond_broadcast: virtual function pointer for g_cond_broadcast() + * @cond_wait: virtual function pointer for g_cond_wait() + * @cond_timed_wait: virtual function pointer for g_cond_timed_wait() + * @cond_free: virtual function pointer for g_cond_free() + * @private_new: virtual function pointer for g_private_new() + * @private_get: virtual function pointer for g_private_get() + * @private_set: virtual function pointer for g_private_set() + * @thread_create: virtual function pointer for g_thread_create() + * @thread_yield: virtual function pointer for g_thread_yield() + * @thread_join: virtual function pointer for g_thread_join() + * @thread_exit: virtual function pointer for g_thread_exit() + * @thread_set_priority: virtual function pointer for + * g_thread_set_priority() + * @thread_self: virtual function pointer for g_thread_self() + * @thread_equal: used internally by recursive mutex locks and by some + * assertion checks + * + * This function table is no longer used by g_thread_init() + * to initialize the thread system. + */ + +/** + * G_THREADS_IMPL_POSIX: + * + * This macro is defined if POSIX style threads are used. + * + * Deprecated:2.32:POSIX threads are in use on all non-Windows systems. + * Use %G_OS_WIN32 to detect Windows. + */ + +/** + * G_THREADS_IMPL_WIN32: + * + * This macro is defined if Windows style threads are used. + * + * Deprecated:2.32:Use %G_OS_WIN32 to detect Windows. + */ + + +/* {{{1 Exported Variables */ + +/* Set this FALSE to have previously-compiled GStaticMutex code use the + * slow path (ie: call into us) to avoid compatibility problems. + */ +gboolean g_thread_use_default_impl = FALSE; + +GThreadFunctions g_thread_functions_for_glib_use = +{ + g_mutex_new, + g_mutex_lock, + g_mutex_trylock, + g_mutex_unlock, + g_mutex_free, + g_cond_new, + g_cond_signal, + g_cond_broadcast, + g_cond_wait, + g_cond_timed_wait, + g_cond_free, + g_private_new, + g_private_get, + g_private_set, + NULL, + g_thread_yield, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +static guint64 +gettime (void) +{ + return g_get_monotonic_time () * 1000; +} + +guint64 (*g_thread_gettime) (void) = gettime; + +/* Initialisation {{{1 ---------------------------------------------------- */ +gboolean g_threads_got_initialized = TRUE; + +/** + * g_thread_init: + * @vtable: a function table of type #GThreadFunctions, that provides + * the entry points to the thread system to be used. Since 2.32, + * this parameter is ignored and should always be %NULL + * + * If you use GLib from more than one thread, you must initialize the + * thread system by calling g_thread_init(). + * + * Since version 2.24, calling g_thread_init() multiple times is allowed, + * but nothing happens except for the first call. + * + * Since version 2.32, GLib does not support custom thread implementations + * anymore and the @vtable parameter is ignored and you should pass %NULL. + * + * g_thread_init() must not be called directly or indirectly + * in a callback from GLib. Also no mutexes may be currently locked while + * calling g_thread_init(). + * + * To use g_thread_init() in your program, you have to link + * with the libraries that the command pkg-config --libs + * gthread-2.0 outputs. This is not the case for all the + * other thread-related functions of GLib. Those can be used without + * having to link with the thread libraries. + * + * Deprecated:2.32: This function is no longer necessary. The GLib + * threading system is automatically initialized at the start + * of your program. + */ + +/** + * g_thread_get_initialized: + * + * Indicates if g_thread_init() has been called. + * + * Returns: %TRUE if threads have been initialized. + * + * Since: 2.20 + */ +gboolean +g_thread_get_initialized (void) +{ + return g_thread_supported (); +} + +/* We need this for ABI compatibility */ +GLIB_AVAILABLE_IN_ALL +void g_thread_init_glib (void); +void g_thread_init_glib (void) { } + +/* Internal variables {{{1 */ + +static GSList *g_thread_all_threads = NULL; +static GSList *g_thread_free_indices = NULL; + +/* Protects g_thread_all_threads and g_thread_free_indices */ +G_LOCK_DEFINE_STATIC (g_static_mutex); +G_LOCK_DEFINE_STATIC (g_thread); + +/* Misc. GThread functions {{{1 */ + +/** + * g_thread_set_priority: + * @thread: a #GThread. + * @priority: ignored + * + * This function does nothing. + * + * Deprecated:2.32: Thread priorities no longer have any effect. + */ +void +g_thread_set_priority (GThread *thread, + GThreadPriority priority) +{ +} + +/** + * g_thread_foreach: + * @thread_func: function to call for all #GThread structures + * @user_data: second argument to @thread_func + * + * Call @thread_func on all #GThreads that have been + * created with g_thread_create(). + * + * Note that threads may decide to exit while @thread_func is + * running, so without intimate knowledge about the lifetime of + * foreign threads, @thread_func shouldn't access the GThread* + * pointer passed in as first argument. However, @thread_func will + * not be called for threads which are known to have exited already. + * + * Due to thread lifetime checks, this function has an execution complexity + * which is quadratic in the number of existing threads. + * + * Since: 2.10 + * + * Deprecated:2.32: There aren't many things you can do with a #GThread, + * except comparing it with one that was returned from g_thread_create(). + * There are better ways to find out if your thread is still alive. + */ +void +g_thread_foreach (GFunc thread_func, + gpointer user_data) +{ + GSList *slist = NULL; + GRealThread *thread; + g_return_if_fail (thread_func != NULL); + /* snapshot the list of threads for iteration */ + G_LOCK (g_thread); + slist = g_slist_copy (g_thread_all_threads); + G_UNLOCK (g_thread); + /* walk the list, skipping non-existent threads */ + while (slist) + { + GSList *node = slist; + slist = node->next; + /* check whether the current thread still exists */ + G_LOCK (g_thread); + if (g_slist_find (g_thread_all_threads, node->data)) + thread = node->data; + else + thread = NULL; + G_UNLOCK (g_thread); + if (thread) + thread_func (thread, user_data); + g_slist_free_1 (node); + } +} + +static void +g_enumerable_thread_remove (gpointer data) +{ + GRealThread *thread = data; + + G_LOCK (g_thread); + g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread); + G_UNLOCK (g_thread); +} + +GPrivate enumerable_thread_private = G_PRIVATE_INIT (g_enumerable_thread_remove); + +static void +g_enumerable_thread_add (GRealThread *thread) +{ + G_LOCK (g_thread); + g_thread_all_threads = g_slist_prepend (g_thread_all_threads, thread); + G_UNLOCK (g_thread); + + g_private_set (&enumerable_thread_private, thread); +} + +static gpointer +g_deprecated_thread_proxy (gpointer data) +{ + GRealThread *real = data; + + g_enumerable_thread_add (real); + + return g_thread_proxy (data); +} + +/** + * g_thread_create: + * @func: a function to execute in the new thread + * @data: an argument to supply to the new thread + * @joinable: should this thread be joinable? + * @error: return location for error, or %NULL + * + * This function creates a new thread. + * + * The new thread executes the function @func with the argument @data. + * If the thread was created successfully, it is returned. + * + * @error can be %NULL to ignore errors, or non-%NULL to report errors. + * The error is set, if and only if the function returns %NULL. + * + * This function returns a reference to the created thread only if + * @joinable is %TRUE. In that case, you must free this reference by + * calling g_thread_unref() or g_thread_join(). If @joinable is %FALSE + * then you should probably not touch the return value. + * + * Returns: the new #GThread on success + * + * Deprecated:2.32: Use g_thread_new() instead + */ +GThread * +g_thread_create (GThreadFunc func, + gpointer data, + gboolean joinable, + GError **error) +{ + return g_thread_create_full (func, data, 0, joinable, 0, 0, error); +} + +/** + * g_thread_create_full: + * @func: a function to execute in the new thread. + * @data: an argument to supply to the new thread. + * @stack_size: a stack size for the new thread. + * @joinable: should this thread be joinable? + * @bound: ignored + * @priority: ignored + * @error: return location for error. + * + * This function creates a new thread. + * + * Returns: the new #GThread on success. + * + * Deprecated:2.32: The @bound and @priority arguments are now ignored. + * Use g_thread_new(). + */ +GThread * +g_thread_create_full (GThreadFunc func, + gpointer data, + gulong stack_size, + gboolean joinable, + gboolean bound, + GThreadPriority priority, + GError **error) +{ + GThread *thread; + + thread = g_thread_new_internal (NULL, g_deprecated_thread_proxy, + func, data, stack_size, NULL, error); + + if (thread && !joinable) + { + thread->joinable = FALSE; + g_thread_unref (thread); + } + + return thread; +} + +/* GOnce {{{1 ------------------------------------------------------------- */ +gboolean +g_once_init_enter_impl (volatile gsize *location) +{ + return (g_once_init_enter) (location); +} + +/* GStaticMutex {{{1 ------------------------------------------------------ */ + +/** + * GStaticMutex: + * + * A #GStaticMutex works like a #GMutex. + * + * Prior to GLib 2.32, GStaticMutex had the significant advantage + * that it doesn't need to be created at run-time, but can be defined + * at compile-time. Since 2.32, #GMutex can be statically allocated + * as well, and GStaticMutex has been deprecated. + * + * Here is a version of our give_me_next_number() example using + * a GStaticMutex: + * |[ + * int + * give_me_next_number (void) + * { + * static int current_number = 0; + * int ret_val; + * static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + * + * g_static_mutex_lock (&mutex); + * ret_val = current_number = calc_next_number (current_number); + * g_static_mutex_unlock (&mutex); + * + * return ret_val; + * } + * ]| + * + * Sometimes you would like to dynamically create a mutex. If you don't + * want to require prior calling to g_thread_init(), because your code + * should also be usable in non-threaded programs, you are not able to + * use g_mutex_new() and thus #GMutex, as that requires a prior call to + * g_thread_init(). In these cases you can also use a #GStaticMutex. + * It must be initialized with g_static_mutex_init() before using it + * and freed with with g_static_mutex_free() when not needed anymore to + * free up any allocated resources. + * + * Even though #GStaticMutex is not opaque, it should only be used with + * the following functions, as it is defined differently on different + * platforms. + * + * All of the g_static_mutex_* functions apart from + * g_static_mutex_get_mutex() can also be used even if g_thread_init() + * has not yet been called. Then they do nothing, apart from + * g_static_mutex_trylock() which does nothing but returning %TRUE. + * + * All of the g_static_mutex_* functions are actually macros. Apart from + * taking their addresses, you can however use them as if they were + * functions. + */ + +/** + * G_STATIC_MUTEX_INIT: + * + * A #GStaticMutex must be initialized with this macro, before it can + * be used. This macro can used be to initialize a variable, but it + * cannot be assigned to a variable. In that case you have to use + * g_static_mutex_init(). + * + * |[ + * GStaticMutex my_mutex = G_STATIC_MUTEX_INIT; + * ]| + **/ + +/** + * g_static_mutex_init: + * @mutex: a #GStaticMutex to be initialized. + * + * Initializes @mutex. + * Alternatively you can initialize it with %G_STATIC_MUTEX_INIT. + * + * Deprecated: 2.32: Use g_mutex_init() + */ +void +g_static_mutex_init (GStaticMutex *mutex) +{ + static const GStaticMutex init_mutex = G_STATIC_MUTEX_INIT; + + g_return_if_fail (mutex); + + *mutex = init_mutex; +} + +/* IMPLEMENTATION NOTE: + * + * On some platforms a GStaticMutex is actually a normal GMutex stored + * inside of a structure instead of being allocated dynamically. We can + * only do this for platforms on which we know, in advance, how to + * allocate (size) and initialise (value) that memory. + * + * On other platforms, a GStaticMutex is nothing more than a pointer to + * a GMutex. In that case, the first access we make to the static mutex + * must first allocate the normal GMutex and store it into the pointer. + * + * configure.ac writes macros into glibconfig.h to determine if + * g_static_mutex_get_mutex() accesses the structure in memory directly + * (on platforms where we are able to do that) or if it ends up here, + * where we may have to allocate the GMutex before returning it. + */ + +/** + * g_static_mutex_get_mutex: + * @mutex: a #GStaticMutex. + * + * For some operations (like g_cond_wait()) you must have a #GMutex + * instead of a #GStaticMutex. This function will return the + * corresponding #GMutex for @mutex. + * + * Returns: the #GMutex corresponding to @mutex. + * + * Deprecated: 2.32: Just use a #GMutex + */ +GMutex * +g_static_mutex_get_mutex_impl (GStaticMutex* mutex) +{ + GMutex *result; + + if (!g_thread_supported ()) + return NULL; + + result = g_atomic_pointer_get (&mutex->mutex); + + if (!result) + { + G_LOCK (g_static_mutex); + + result = mutex->mutex; + if (!result) + { + result = g_mutex_new (); + g_atomic_pointer_set (&mutex->mutex, result); + } + + G_UNLOCK (g_static_mutex); + } + + return result; +} + +/* IMPLEMENTATION NOTE: + * + * g_static_mutex_lock(), g_static_mutex_trylock() and + * g_static_mutex_unlock() are all preprocessor macros that wrap the + * corresponding g_mutex_*() function around a call to + * g_static_mutex_get_mutex(). + */ + +/** + * g_static_mutex_lock: + * @mutex: a #GStaticMutex. + * + * Works like g_mutex_lock(), but for a #GStaticMutex. + * + * Deprecated: 2.32: Use g_mutex_lock() + */ + +/** + * g_static_mutex_trylock: + * @mutex: a #GStaticMutex. + * + * Works like g_mutex_trylock(), but for a #GStaticMutex. + * + * Returns: %TRUE, if the #GStaticMutex could be locked. + * + * Deprecated: 2.32: Use g_mutex_trylock() + */ + +/** + * g_static_mutex_unlock: + * @mutex: a #GStaticMutex. + * + * Works like g_mutex_unlock(), but for a #GStaticMutex. + * + * Deprecated: 2.32: Use g_mutex_unlock() + */ + +/** + * g_static_mutex_free: + * @mutex: a #GStaticMutex to be freed. + * + * Releases all resources allocated to @mutex. + * + * You don't have to call this functions for a #GStaticMutex with an + * unbounded lifetime, i.e. objects declared 'static', but if you have + * a #GStaticMutex as a member of a structure and the structure is + * freed, you should also free the #GStaticMutex. + * + * Calling g_static_mutex_free() on a locked mutex may result in + * undefined behaviour. + * + * Deprecated: 2.32: Use g_mutex_clear() + */ +void +g_static_mutex_free (GStaticMutex* mutex) +{ + GMutex **runtime_mutex; + + g_return_if_fail (mutex); + + /* The runtime_mutex is the first (or only) member of GStaticMutex, + * see both versions (of glibconfig.h) in configure.ac. Note, that + * this variable is NULL, if g_thread_init() hasn't been called or + * if we're using the default thread implementation and it provides + * static mutexes. */ + runtime_mutex = ((GMutex**)mutex); + + if (*runtime_mutex) + g_mutex_free (*runtime_mutex); + + *runtime_mutex = NULL; +} + +/* {{{1 GStaticRecMutex */ + +/** + * GStaticRecMutex: + * + * A #GStaticRecMutex works like a #GStaticMutex, but it can be locked + * multiple times by one thread. If you enter it n times, you have to + * unlock it n times again to let other threads lock it. An exception + * is the function g_static_rec_mutex_unlock_full(): that allows you to + * unlock a #GStaticRecMutex completely returning the depth, (i.e. the + * number of times this mutex was locked). The depth can later be used + * to restore the state of the #GStaticRecMutex by calling + * g_static_rec_mutex_lock_full(). In GLib 2.32, #GStaticRecMutex has + * been deprecated in favor of #GRecMutex. + * + * Even though #GStaticRecMutex is not opaque, it should only be used + * with the following functions. + * + * All of the g_static_rec_mutex_* functions can be used even if + * g_thread_init() has not been called. Then they do nothing, apart + * from g_static_rec_mutex_trylock(), which does nothing but returning + * %TRUE. + */ + +/** + * G_STATIC_REC_MUTEX_INIT: + * + * A #GStaticRecMutex must be initialized with this macro before it can + * be used. This macro can used be to initialize a variable, but it + * cannot be assigned to a variable. In that case you have to use + * g_static_rec_mutex_init(). + * + * |[ + * GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT; + * ]| + */ + +/** + * g_static_rec_mutex_init: + * @mutex: a #GStaticRecMutex to be initialized. + * + * A #GStaticRecMutex must be initialized with this function before it + * can be used. Alternatively you can initialize it with + * %G_STATIC_REC_MUTEX_INIT. + * + * Deprecated: 2.32: Use g_rec_mutex_init() + */ +void +g_static_rec_mutex_init (GStaticRecMutex *mutex) +{ + static const GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT; + + g_return_if_fail (mutex); + + *mutex = init_mutex; +} + +static GRecMutex * +g_static_rec_mutex_get_rec_mutex_impl (GStaticRecMutex* mutex) +{ + GRecMutex *result; + + if (!g_thread_supported ()) + return NULL; + + result = (GRecMutex *) g_atomic_pointer_get (&mutex->mutex.mutex); + + if (!result) + { + G_LOCK (g_static_mutex); + + result = (GRecMutex *) mutex->mutex.mutex; + if (!result) + { + result = g_slice_new (GRecMutex); + g_rec_mutex_init (result); + g_atomic_pointer_set (&mutex->mutex.mutex, (GMutex *) result); + } + + G_UNLOCK (g_static_mutex); + } + + return result; +} + +/** + * g_static_rec_mutex_lock: + * @mutex: a #GStaticRecMutex to lock. + * + * Locks @mutex. If @mutex is already locked by another thread, the + * current thread will block until @mutex is unlocked by the other + * thread. If @mutex is already locked by the calling thread, this + * functions increases the depth of @mutex and returns immediately. + * + * Deprecated: 2.32: Use g_rec_mutex_lock() + */ +void +g_static_rec_mutex_lock (GStaticRecMutex* mutex) +{ + GRecMutex *rm; + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + g_rec_mutex_lock (rm); + mutex->depth++; +} + +/** + * g_static_rec_mutex_trylock: + * @mutex: a #GStaticRecMutex to lock. + * + * Tries to lock @mutex. If @mutex is already locked by another thread, + * it immediately returns %FALSE. Otherwise it locks @mutex and returns + * %TRUE. If @mutex is already locked by the calling thread, this + * functions increases the depth of @mutex and immediately returns + * %TRUE. + * + * Returns: %TRUE, if @mutex could be locked. + * + * Deprecated: 2.32: Use g_rec_mutex_trylock() + */ +gboolean +g_static_rec_mutex_trylock (GStaticRecMutex* mutex) +{ + GRecMutex *rm; + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + + if (g_rec_mutex_trylock (rm)) + { + mutex->depth++; + return TRUE; + } + else + return FALSE; +} + +/** + * g_static_rec_mutex_unlock: + * @mutex: a #GStaticRecMutex to unlock. + * + * Unlocks @mutex. Another thread will be allowed to lock @mutex only + * when it has been unlocked as many times as it had been locked + * before. If @mutex is completely unlocked and another thread is + * blocked in a g_static_rec_mutex_lock() call for @mutex, it will be + * woken and can lock @mutex itself. + * + * Deprecated: 2.32: Use g_rec_mutex_unlock() + */ +void +g_static_rec_mutex_unlock (GStaticRecMutex* mutex) +{ + GRecMutex *rm; + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + mutex->depth--; + g_rec_mutex_unlock (rm); +} + +/** + * g_static_rec_mutex_lock_full: + * @mutex: a #GStaticRecMutex to lock. + * @depth: number of times this mutex has to be unlocked to be + * completely unlocked. + * + * Works like calling g_static_rec_mutex_lock() for @mutex @depth times. + * + * Deprecated: 2.32: Use g_rec_mutex_lock() + */ +void +g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, + guint depth) +{ + GRecMutex *rm; + + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + while (depth--) + { + g_rec_mutex_lock (rm); + mutex->depth++; + } +} + +/** + * g_static_rec_mutex_unlock_full: + * @mutex: a #GStaticRecMutex to completely unlock. + * + * Completely unlocks @mutex. If another thread is blocked in a + * g_static_rec_mutex_lock() call for @mutex, it will be woken and can + * lock @mutex itself. This function returns the number of times that + * @mutex has been locked by the current thread. To restore the state + * before the call to g_static_rec_mutex_unlock_full() you can call + * g_static_rec_mutex_lock_full() with the depth returned by this + * function. + * + * Returns: number of times @mutex has been locked by the current + * thread. + * + * Deprecated: 2.32: Use g_rec_mutex_unlock() + */ +guint +g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex) +{ + GRecMutex *rm; + gint depth; + gint i; + + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + + /* all access to mutex->depth done while still holding the lock */ + depth = mutex->depth; + i = mutex->depth; + mutex->depth = 0; + + while (i--) + g_rec_mutex_unlock (rm); + + return depth; +} + +/** + * g_static_rec_mutex_free: + * @mutex: a #GStaticRecMutex to be freed. + * + * Releases all resources allocated to a #GStaticRecMutex. + * + * You don't have to call this functions for a #GStaticRecMutex with an + * unbounded lifetime, i.e. objects declared 'static', but if you have + * a #GStaticRecMutex as a member of a structure and the structure is + * freed, you should also free the #GStaticRecMutex. + * + * Deprecated: 2.32: Use g_rec_mutex_clear() + */ +void +g_static_rec_mutex_free (GStaticRecMutex *mutex) +{ + g_return_if_fail (mutex); + + if (mutex->mutex.mutex) + { + GRecMutex *rm = (GRecMutex *) mutex->mutex.mutex; + + g_rec_mutex_clear (rm); + g_slice_free (GRecMutex, rm); + } +} + +/* GStaticRWLock {{{1 ----------------------------------------------------- */ + +/** + * GStaticRWLock: + * + * The #GStaticRWLock struct represents a read-write lock. A read-write + * lock can be used for protecting data that some portions of code only + * read from, while others also write. In such situations it is + * desirable that several readers can read at once, whereas of course + * only one writer may write at a time. + * + * Take a look at the following example: + * |[ + * GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT; + * GPtrArray *array; + * + * gpointer + * my_array_get (guint index) + * { + * gpointer retval = NULL; + * + * if (!array) + * return NULL; + * + * g_static_rw_lock_reader_lock (&rwlock); + * if (index < array->len) + * retval = g_ptr_array_index (array, index); + * g_static_rw_lock_reader_unlock (&rwlock); + * + * return retval; + * } + * + * void + * my_array_set (guint index, gpointer data) + * { + * g_static_rw_lock_writer_lock (&rwlock); + * + * if (!array) + * array = g_ptr_array_new (); + * + * if (index >= array->len) + * g_ptr_array_set_size (array, index + 1); + * g_ptr_array_index (array, index) = data; + * + * g_static_rw_lock_writer_unlock (&rwlock); + * } + * ]| + * + * This example shows an array which can be accessed by many readers + * (the my_array_get() function) simultaneously, whereas the writers + * (the my_array_set() function) will only be allowed once at a time + * and only if no readers currently access the array. This is because + * of the potentially dangerous resizing of the array. Using these + * functions is fully multi-thread safe now. + * + * Most of the time, writers should have precedence over readers. That + * means, for this implementation, that as soon as a writer wants to + * lock the data, no other reader is allowed to lock the data, whereas, + * of course, the readers that already have locked the data are allowed + * to finish their operation. As soon as the last reader unlocks the + * data, the writer will lock it. + * + * Even though #GStaticRWLock is not opaque, it should only be used + * with the following functions. + * + * All of the g_static_rw_lock_* functions can be used even if + * g_thread_init() has not been called. Then they do nothing, apart + * from g_static_rw_lock_*_trylock, which does nothing but returning %TRUE. + * + * A read-write lock has a higher overhead than a mutex. For example, both + * g_static_rw_lock_reader_lock() and g_static_rw_lock_reader_unlock() have + * to lock and unlock a #GStaticMutex, so it takes at least twice the time + * to lock and unlock a #GStaticRWLock that it does to lock and unlock a + * #GStaticMutex. So only data structures that are accessed by multiple + * readers, and which keep the lock for a considerable time justify a + * #GStaticRWLock. The above example most probably would fare better with a + * #GStaticMutex. + * + * Deprecated: 2.32: Use a #GRWLock instead + **/ + +/** + * G_STATIC_RW_LOCK_INIT: + * + * A #GStaticRWLock must be initialized with this macro before it can + * be used. This macro can used be to initialize a variable, but it + * cannot be assigned to a variable. In that case you have to use + * g_static_rw_lock_init(). + * + * |[ + * GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT; + * ]| + */ + +/** + * g_static_rw_lock_init: + * @lock: a #GStaticRWLock to be initialized. + * + * A #GStaticRWLock must be initialized with this function before it + * can be used. Alternatively you can initialize it with + * %G_STATIC_RW_LOCK_INIT. + * + * Deprecated: 2.32: Use g_rw_lock_init() instead + */ +void +g_static_rw_lock_init (GStaticRWLock* lock) +{ + static const GStaticRWLock init_lock = G_STATIC_RW_LOCK_INIT; + + g_return_if_fail (lock); + + *lock = init_lock; +} + +inline static void +g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex) +{ + if (!*cond) + *cond = g_cond_new (); + g_cond_wait (*cond, g_static_mutex_get_mutex (mutex)); +} + +inline static void +g_static_rw_lock_signal (GStaticRWLock* lock) +{ + if (lock->want_to_write && lock->write_cond) + g_cond_signal (lock->write_cond); + else if (lock->want_to_read && lock->read_cond) + g_cond_broadcast (lock->read_cond); +} + +/** + * g_static_rw_lock_reader_lock: + * @lock: a #GStaticRWLock to lock for reading. + * + * Locks @lock for reading. There may be unlimited concurrent locks for + * reading of a #GStaticRWLock at the same time. If @lock is already + * locked for writing by another thread or if another thread is already + * waiting to lock @lock for writing, this function will block until + * @lock is unlocked by the other writing thread and no other writing + * threads want to lock @lock. This lock has to be unlocked by + * g_static_rw_lock_reader_unlock(). + * + * #GStaticRWLock is not recursive. It might seem to be possible to + * recursively lock for reading, but that can result in a deadlock, due + * to writer preference. + * + * Deprecated: 2.32: Use g_rw_lock_reader_lock() instead + */ +void +g_static_rw_lock_reader_lock (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (!g_threads_got_initialized) + return; + + g_static_mutex_lock (&lock->mutex); + lock->want_to_read++; + while (lock->have_writer || lock->want_to_write) + g_static_rw_lock_wait (&lock->read_cond, &lock->mutex); + lock->want_to_read--; + lock->read_counter++; + g_static_mutex_unlock (&lock->mutex); +} + +/** + * g_static_rw_lock_reader_trylock: + * @lock: a #GStaticRWLock to lock for reading + * + * Tries to lock @lock for reading. If @lock is already locked for + * writing by another thread or if another thread is already waiting to + * lock @lock for writing, immediately returns %FALSE. Otherwise locks + * @lock for reading and returns %TRUE. This lock has to be unlocked by + * g_static_rw_lock_reader_unlock(). + * + * Returns: %TRUE, if @lock could be locked for reading + * + * Deprecated: 2.32: Use g_rw_lock_reader_trylock() instead + */ +gboolean +g_static_rw_lock_reader_trylock (GStaticRWLock* lock) +{ + gboolean ret_val = FALSE; + + g_return_val_if_fail (lock, FALSE); + + if (!g_threads_got_initialized) + return TRUE; + + g_static_mutex_lock (&lock->mutex); + if (!lock->have_writer && !lock->want_to_write) + { + lock->read_counter++; + ret_val = TRUE; + } + g_static_mutex_unlock (&lock->mutex); + return ret_val; +} + +/** + * g_static_rw_lock_reader_unlock: + * @lock: a #GStaticRWLock to unlock after reading + * + * Unlocks @lock. If a thread waits to lock @lock for writing and all + * locks for reading have been unlocked, the waiting thread is woken up + * and can lock @lock for writing. + * + * Deprecated: 2.32: Use g_rw_lock_reader_unlock() instead + */ +void +g_static_rw_lock_reader_unlock (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (!g_threads_got_initialized) + return; + + g_static_mutex_lock (&lock->mutex); + lock->read_counter--; + if (lock->read_counter == 0) + g_static_rw_lock_signal (lock); + g_static_mutex_unlock (&lock->mutex); +} + +/** + * g_static_rw_lock_writer_lock: + * @lock: a #GStaticRWLock to lock for writing + * + * Locks @lock for writing. If @lock is already locked for writing or + * reading by other threads, this function will block until @lock is + * completely unlocked and then lock @lock for writing. While this + * functions waits to lock @lock, no other thread can lock @lock for + * reading. When @lock is locked for writing, no other thread can lock + * @lock (neither for reading nor writing). This lock has to be + * unlocked by g_static_rw_lock_writer_unlock(). + * + * Deprecated: 2.32: Use g_rw_lock_writer_lock() instead + */ +void +g_static_rw_lock_writer_lock (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (!g_threads_got_initialized) + return; + + g_static_mutex_lock (&lock->mutex); + lock->want_to_write++; + while (lock->have_writer || lock->read_counter) + g_static_rw_lock_wait (&lock->write_cond, &lock->mutex); + lock->want_to_write--; + lock->have_writer = TRUE; + g_static_mutex_unlock (&lock->mutex); +} + +/** + * g_static_rw_lock_writer_trylock: + * @lock: a #GStaticRWLock to lock for writing + * + * Tries to lock @lock for writing. If @lock is already locked (for + * either reading or writing) by another thread, it immediately returns + * %FALSE. Otherwise it locks @lock for writing and returns %TRUE. This + * lock has to be unlocked by g_static_rw_lock_writer_unlock(). + * + * Returns: %TRUE, if @lock could be locked for writing + * + * Deprecated: 2.32: Use g_rw_lock_writer_trylock() instead + */ +gboolean +g_static_rw_lock_writer_trylock (GStaticRWLock* lock) +{ + gboolean ret_val = FALSE; + + g_return_val_if_fail (lock, FALSE); + + if (!g_threads_got_initialized) + return TRUE; + + g_static_mutex_lock (&lock->mutex); + if (!lock->have_writer && !lock->read_counter) + { + lock->have_writer = TRUE; + ret_val = TRUE; + } + g_static_mutex_unlock (&lock->mutex); + return ret_val; +} + +/** + * g_static_rw_lock_writer_unlock: + * @lock: a #GStaticRWLock to unlock after writing. + * + * Unlocks @lock. If a thread is waiting to lock @lock for writing and + * all locks for reading have been unlocked, the waiting thread is + * woken up and can lock @lock for writing. If no thread is waiting to + * lock @lock for writing, and some thread or threads are waiting to + * lock @lock for reading, the waiting threads are woken up and can + * lock @lock for reading. + * + * Deprecated: 2.32: Use g_rw_lock_writer_unlock() instead + */ +void +g_static_rw_lock_writer_unlock (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (!g_threads_got_initialized) + return; + + g_static_mutex_lock (&lock->mutex); + lock->have_writer = FALSE; + g_static_rw_lock_signal (lock); + g_static_mutex_unlock (&lock->mutex); +} + +/** + * g_static_rw_lock_free: + * @lock: a #GStaticRWLock to be freed. + * + * Releases all resources allocated to @lock. + * + * You don't have to call this functions for a #GStaticRWLock with an + * unbounded lifetime, i.e. objects declared 'static', but if you have + * a #GStaticRWLock as a member of a structure, and the structure is + * freed, you should also free the #GStaticRWLock. + * + * Deprecated: 2.32: Use a #GRWLock instead + */ +void +g_static_rw_lock_free (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (lock->read_cond) + { + g_cond_free (lock->read_cond); + lock->read_cond = NULL; + } + if (lock->write_cond) + { + g_cond_free (lock->write_cond); + lock->write_cond = NULL; + } + g_static_mutex_free (&lock->mutex); +} + +/* GPrivate {{{1 ------------------------------------------------------ */ + +/** + * g_private_new: + * @notify: a #GDestroyNotify + * + * Creates a new #GPrivate. + * + * Deprecated:2.32: dynamic allocation of #GPrivate is a bad idea. Use + * static storage and G_PRIVATE_INIT() instead. + * + * Returns: a newly allocated #GPrivate (which can never be destroyed) + */ +GPrivate * +g_private_new (GDestroyNotify notify) +{ + GPrivate tmp = G_PRIVATE_INIT (notify); + GPrivate *key; + + key = g_slice_new (GPrivate); + *key = tmp; + + return key; +} + +/* {{{1 GStaticPrivate */ + +typedef struct _GStaticPrivateNode GStaticPrivateNode; +struct _GStaticPrivateNode +{ + gpointer data; + GDestroyNotify destroy; + GStaticPrivate *owner; +}; + +static void +g_static_private_cleanup (gpointer data) +{ + GArray *array = data; + guint i; + + for (i = 0; i < array->len; i++ ) + { + GStaticPrivateNode *node = &g_array_index (array, GStaticPrivateNode, i); + if (node->destroy) + node->destroy (node->data); + } + + g_array_free (array, TRUE); +} + +GPrivate static_private_private = G_PRIVATE_INIT (g_static_private_cleanup); + +/** + * GStaticPrivate: + * + * A #GStaticPrivate works almost like a #GPrivate, but it has one + * significant advantage. It doesn't need to be created at run-time + * like a #GPrivate, but can be defined at compile-time. This is + * similar to the difference between #GMutex and #GStaticMutex. + * + * Now look at our give_me_next_number() example with #GStaticPrivate: + * |[ + * int + * give_me_next_number () + * { + * static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT; + * int *current_number = g_static_private_get (¤t_number_key); + * + * if (!current_number) + * { + * current_number = g_new (int, 1); + * *current_number = 0; + * g_static_private_set (¤t_number_key, current_number, g_free); + * } + * + * *current_number = calc_next_number (*current_number); + * + * return *current_number; + * } + * ]| + */ + +/** + * G_STATIC_PRIVATE_INIT: + * + * Every #GStaticPrivate must be initialized with this macro, before it + * can be used. + * + * |[ + * GStaticPrivate my_private = G_STATIC_PRIVATE_INIT; + * ]| + */ + +/** + * g_static_private_init: + * @private_key: a #GStaticPrivate to be initialized + * + * Initializes @private_key. Alternatively you can initialize it with + * %G_STATIC_PRIVATE_INIT. + */ +void +g_static_private_init (GStaticPrivate *private_key) +{ + private_key->index = 0; +} + +/** + * g_static_private_get: + * @private_key: a #GStaticPrivate + * + * Works like g_private_get() only for a #GStaticPrivate. + * + * This function works even if g_thread_init() has not yet been called. + * + * Returns: the corresponding pointer + */ +gpointer +g_static_private_get (GStaticPrivate *private_key) +{ + GArray *array; + gpointer ret = NULL; + + array = g_private_get (&static_private_private); + + if (array && private_key->index != 0 && private_key->index <= array->len) + { + GStaticPrivateNode *node; + + node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1); + + /* Deal with the possibility that the GStaticPrivate which used + * to have this index got freed and the index got allocated to + * a new one. In this case, the data in the node is stale, so + * free it and return NULL. + */ + if (G_UNLIKELY (node->owner != private_key)) + { + if (node->destroy) + node->destroy (node->data); + node->destroy = NULL; + node->data = NULL; + node->owner = NULL; + } + ret = node->data; + } + + return ret; +} + +/** + * g_static_private_set: + * @private_key: a #GStaticPrivate + * @data: the new pointer + * @notify: a function to be called with the pointer whenever the + * current thread ends or sets this pointer again + * + * Sets the pointer keyed to @private_key for the current thread and + * the function @notify to be called with that pointer (%NULL or + * non-%NULL), whenever the pointer is set again or whenever the + * current thread ends. + * + * This function works even if g_thread_init() has not yet been called. + * If g_thread_init() is called later, the @data keyed to @private_key + * will be inherited only by the main thread, i.e. the one that called + * g_thread_init(). + * + * @notify is used quite differently from @destructor in g_private_new(). + */ +void +g_static_private_set (GStaticPrivate *private_key, + gpointer data, + GDestroyNotify notify) +{ + GArray *array; + static guint next_index = 0; + GStaticPrivateNode *node; + + if (!private_key->index) + { + G_LOCK (g_thread); + + if (!private_key->index) + { + if (g_thread_free_indices) + { + private_key->index = GPOINTER_TO_UINT (g_thread_free_indices->data); + g_thread_free_indices = g_slist_delete_link (g_thread_free_indices, + g_thread_free_indices); + } + else + private_key->index = ++next_index; + } + + G_UNLOCK (g_thread); + } + + array = g_private_get (&static_private_private); + if (!array) + { + array = g_array_new (FALSE, TRUE, sizeof (GStaticPrivateNode)); + g_private_set (&static_private_private, array); + } + if (private_key->index > array->len) + g_array_set_size (array, private_key->index); + + node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1); + + if (node->destroy) + node->destroy (node->data); + + node->data = data; + node->destroy = notify; + node->owner = private_key; +} + +/** + * g_static_private_free: + * @private_key: a #GStaticPrivate to be freed + * + * Releases all resources allocated to @private_key. + * + * You don't have to call this functions for a #GStaticPrivate with an + * unbounded lifetime, i.e. objects declared 'static', but if you have + * a #GStaticPrivate as a member of a structure and the structure is + * freed, you should also free the #GStaticPrivate. + */ +void +g_static_private_free (GStaticPrivate *private_key) +{ + guint idx = private_key->index; + + if (!idx) + return; + + private_key->index = 0; + + /* Freeing the per-thread data is deferred to either the + * thread end or the next g_static_private_get() call for + * the same index. + */ + G_LOCK (g_thread); + g_thread_free_indices = g_slist_prepend (g_thread_free_indices, + GUINT_TO_POINTER (idx)); + G_UNLOCK (g_thread); +} + +/* GMutex {{{1 ------------------------------------------------------ */ + +/** + * g_mutex_new: + * + * Allocates and initializes a new #GMutex. + * + * Returns: a newly allocated #GMutex. Use g_mutex_free() to free + * + * Deprecated: 2.32: GMutex can now be statically allocated, or embedded + * in structures and initialised with g_mutex_init(). + */ +GMutex * +g_mutex_new (void) +{ + GMutex *mutex; + + mutex = g_slice_new (GMutex); + g_mutex_init (mutex); + + return mutex; +} + +/** + * g_mutex_free: + * @mutex: a #GMutex + * + * Destroys a @mutex that has been created with g_mutex_new(). + * + * Calling g_mutex_free() on a locked mutex may result + * in undefined behaviour. + * + * Deprecated: 2.32: GMutex can now be statically allocated, or embedded + * in structures and initialised with g_mutex_init(). + */ +void +g_mutex_free (GMutex *mutex) +{ + g_mutex_clear (mutex); + g_slice_free (GMutex, mutex); +} + +/* GCond {{{1 ------------------------------------------------------ */ + +/** + * g_cond_new: + * + * Allocates and initializes a new #GCond. + * + * Returns: a newly allocated #GCond. Free with g_cond_free() + * + * Deprecated: 2.32: GCond can now be statically allocated, or embedded + * in structures and initialised with g_cond_init(). + */ +GCond * +g_cond_new (void) +{ + GCond *cond; + + cond = g_slice_new (GCond); + g_cond_init (cond); + + return cond; +} + +/** + * g_cond_free: + * @cond: a #GCond + * + * Destroys a #GCond that has been created with g_cond_new(). + * + * Calling g_cond_free() for a #GCond on which threads are + * blocking leads to undefined behaviour. + * + * Deprecated: 2.32: GCond can now be statically allocated, or embedded + * in structures and initialised with g_cond_init(). + */ +void +g_cond_free (GCond *cond) +{ + g_cond_clear (cond); + g_slice_free (GCond, cond); +} + +/** + * g_cond_timed_wait: + * @cond: a #GCond + * @mutex: a #GMutex that is currently locked + * @abs_time: a #GTimeVal, determining the final time + * + * Waits until this thread is woken up on @cond, but not longer than + * until the time specified by @abs_time. The @mutex is unlocked before + * falling asleep and locked again before resuming. + * + * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait(). + * + * This function can be used even if g_thread_init() has not yet been + * called, and, in that case, will immediately return %TRUE. + * + * To easily calculate @abs_time a combination of g_get_real_time() + * and g_time_val_add() can be used. + * + * Returns: %TRUE if @cond was signalled, or %FALSE on timeout + * + * Deprecated:2.32: Use g_cond_wait_until() instead. + */ +gboolean +g_cond_timed_wait (GCond *cond, + GMutex *mutex, + GTimeVal *abs_time) +{ + gint64 end_time; + + if (abs_time == NULL) + { + g_cond_wait (cond, mutex); + return TRUE; + } + + end_time = abs_time->tv_sec; + end_time *= 1000000; + end_time += abs_time->tv_usec; + + /* would be nice if we had clock_rtoffset, but that didn't seem to + * make it into the kernel yet... + */ + end_time += g_get_monotonic_time () - g_get_real_time (); + + return g_cond_wait_until (cond, mutex, end_time); +} + +/* {{{1 Epilogue */ +/* vim: set foldmethod=marker: */ diff --git a/glib/deprecated/gthread.h b/glib/deprecated/gthread.h new file mode 100644 index 0000000..2d490a1 --- /dev/null +++ b/glib/deprecated/gthread.h @@ -0,0 +1,293 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_DEPRECATED_THREAD_H__ +#define __G_DEPRECATED_THREAD_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +typedef enum +{ + G_THREAD_PRIORITY_LOW, + G_THREAD_PRIORITY_NORMAL, + G_THREAD_PRIORITY_HIGH, + G_THREAD_PRIORITY_URGENT +} GThreadPriority GLIB_DEPRECATED_TYPE_IN_2_32; + +struct _GThread +{ + /*< private >*/ + GThreadFunc func; + gpointer data; + gboolean joinable; + GThreadPriority priority; +}; + +typedef struct _GThreadFunctions GThreadFunctions GLIB_DEPRECATED_TYPE_IN_2_32; +struct _GThreadFunctions +{ + GMutex* (*mutex_new) (void); + void (*mutex_lock) (GMutex *mutex); + gboolean (*mutex_trylock) (GMutex *mutex); + void (*mutex_unlock) (GMutex *mutex); + void (*mutex_free) (GMutex *mutex); + GCond* (*cond_new) (void); + void (*cond_signal) (GCond *cond); + void (*cond_broadcast) (GCond *cond); + void (*cond_wait) (GCond *cond, + GMutex *mutex); + gboolean (*cond_timed_wait) (GCond *cond, + GMutex *mutex, + GTimeVal *end_time); + void (*cond_free) (GCond *cond); + GPrivate* (*private_new) (GDestroyNotify destructor); + gpointer (*private_get) (GPrivate *private_key); + void (*private_set) (GPrivate *private_key, + gpointer data); + void (*thread_create) (GThreadFunc func, + gpointer data, + gulong stack_size, + gboolean joinable, + gboolean bound, + GThreadPriority priority, + gpointer thread, + GError **error); + void (*thread_yield) (void); + void (*thread_join) (gpointer thread); + void (*thread_exit) (void); + void (*thread_set_priority)(gpointer thread, + GThreadPriority priority); + void (*thread_self) (gpointer thread); + gboolean (*thread_equal) (gpointer thread1, + gpointer thread2); +} GLIB_DEPRECATED_TYPE_IN_2_32; + +GLIB_VAR GThreadFunctions g_thread_functions_for_glib_use; +GLIB_VAR gboolean g_thread_use_default_impl; + +GLIB_VAR guint64 (*g_thread_gettime) (void); + +GLIB_DEPRECATED_IN_2_32_FOR(g_thread_new) +GThread *g_thread_create (GThreadFunc func, + gpointer data, + gboolean joinable, + GError **error); + +GLIB_DEPRECATED_IN_2_32_FOR(g_thread_new) +GThread *g_thread_create_full (GThreadFunc func, + gpointer data, + gulong stack_size, + gboolean joinable, + gboolean bound, + GThreadPriority priority, + GError **error); + +GLIB_DEPRECATED_IN_2_32 +void g_thread_set_priority (GThread *thread, + GThreadPriority priority); + +GLIB_DEPRECATED_IN_2_32 +void g_thread_foreach (GFunc thread_func, + gpointer user_data); + +#ifndef G_OS_WIN32 +#include +#include +#endif + +#define g_static_mutex_get_mutex g_static_mutex_get_mutex_impl GLIB_DEPRECATED_MACRO_IN_2_32 +#ifndef G_OS_WIN32 +#define G_STATIC_MUTEX_INIT { NULL, PTHREAD_MUTEX_INITIALIZER } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_mutex_init) +#else +#define G_STATIC_MUTEX_INIT { NULL } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_mutex_init) +#endif +typedef struct +{ + GMutex *mutex; +#ifndef G_OS_WIN32 + /* only for ABI compatibility reasons */ + pthread_mutex_t unused; +#endif +} GStaticMutex GLIB_DEPRECATED_TYPE_IN_2_32_FOR(GMutex); + +#define g_static_mutex_lock(mutex) \ + g_mutex_lock (g_static_mutex_get_mutex (mutex)) GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_mutex_lock) +#define g_static_mutex_trylock(mutex) \ + g_mutex_trylock (g_static_mutex_get_mutex (mutex)) GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_mutex_trylock) +#define g_static_mutex_unlock(mutex) \ + g_mutex_unlock (g_static_mutex_get_mutex (mutex)) GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_mutex_unlock) + +GLIB_DEPRECATED_IN_2_32_FOR(g_mutex_init) +void g_static_mutex_init (GStaticMutex *mutex); +GLIB_DEPRECATED_IN_2_32_FOR(g_mutex_clear) +void g_static_mutex_free (GStaticMutex *mutex); +GLIB_DEPRECATED_IN_2_32_FOR(GMutex) +GMutex *g_static_mutex_get_mutex_impl (GStaticMutex *mutex); + +typedef struct _GStaticRecMutex GStaticRecMutex GLIB_DEPRECATED_TYPE_IN_2_32_FOR(GRecMutex); +struct _GStaticRecMutex +{ + /*< private >*/ + GStaticMutex mutex; + guint depth; + + /* ABI compat only */ + union { +#ifdef G_OS_WIN32 + void *owner; +#else + pthread_t owner; +#endif + gdouble dummy; + } unused; +} GLIB_DEPRECATED_TYPE_IN_2_32_FOR(GRecMutex); + +#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT, 0, { 0 } } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_rec_mutex_init) +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_init) +void g_static_rec_mutex_init (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_lock) +void g_static_rec_mutex_lock (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_try_lock) +gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_unlock) +void g_static_rec_mutex_unlock (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32 +void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, + guint depth); + +GLIB_DEPRECATED_IN_2_32 +guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_free) +void g_static_rec_mutex_free (GStaticRecMutex *mutex); + +typedef struct _GStaticRWLock GStaticRWLock GLIB_DEPRECATED_TYPE_IN_2_32_FOR(GRWLock); +struct _GStaticRWLock +{ + /*< private >*/ + GStaticMutex mutex; + GCond *read_cond; + GCond *write_cond; + guint read_counter; + gboolean have_writer; + guint want_to_read; + guint want_to_write; +} GLIB_DEPRECATED_TYPE_IN_2_32_FOR(GRWLock); + +#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_rw_lock_init) + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_init) +void g_static_rw_lock_init (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_reader_lock) +void g_static_rw_lock_reader_lock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_reader_trylock) +gboolean g_static_rw_lock_reader_trylock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_reader_unlock) +void g_static_rw_lock_reader_unlock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_writer_lock) +void g_static_rw_lock_writer_lock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_writer_trylock) +gboolean g_static_rw_lock_writer_trylock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_writer_unlock) +void g_static_rw_lock_writer_unlock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_free) +void g_static_rw_lock_free (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32 +GPrivate * g_private_new (GDestroyNotify notify); + +typedef struct _GStaticPrivate GStaticPrivate GLIB_DEPRECATED_TYPE_IN_2_32_FOR(GPrivate); +struct _GStaticPrivate +{ + /*< private >*/ + guint index; +} GLIB_DEPRECATED_TYPE_IN_2_32_FOR(GPrivate); + +#define G_STATIC_PRIVATE_INIT { 0 } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(G_PRIVATE_INIT) +GLIB_DEPRECATED_IN_2_32 +void g_static_private_init (GStaticPrivate *private_key); + +GLIB_DEPRECATED_IN_2_32_FOR(g_private_get) +gpointer g_static_private_get (GStaticPrivate *private_key); + +GLIB_DEPRECATED_IN_2_32_FOR(g_private_set) +void g_static_private_set (GStaticPrivate *private_key, + gpointer data, + GDestroyNotify notify); + +GLIB_DEPRECATED_IN_2_32 +void g_static_private_free (GStaticPrivate *private_key); + +GLIB_DEPRECATED_IN_2_32 +gboolean g_once_init_enter_impl (volatile gsize *location); + +GLIB_DEPRECATED_IN_2_32 +void g_thread_init (gpointer vtable); +GLIB_DEPRECATED_IN_2_32 +void g_thread_init_with_errorcheck_mutexes (gpointer vtable); + +GLIB_DEPRECATED_IN_2_32 +gboolean g_thread_get_initialized (void); + +GLIB_VAR gboolean g_threads_got_initialized; + +#define g_thread_supported() (1) GLIB_DEPRECATED_MACRO_IN_2_32 + +GLIB_DEPRECATED_IN_2_32 +GMutex * g_mutex_new (void); +GLIB_DEPRECATED_IN_2_32 +void g_mutex_free (GMutex *mutex); +GLIB_DEPRECATED_IN_2_32 +GCond * g_cond_new (void); +GLIB_DEPRECATED_IN_2_32 +void g_cond_free (GCond *cond); +GLIB_DEPRECATED_IN_2_32 +gboolean g_cond_timed_wait (GCond *cond, + GMutex *mutex, + GTimeVal *timeval); + +G_GNUC_END_IGNORE_DEPRECATIONS + +G_END_DECLS + +#endif /* __G_DEPRECATED_THREAD_H__ */ diff --git a/glib/dirent/README b/glib/dirent/README new file mode 100644 index 0000000..e31ac1f --- /dev/null +++ b/glib/dirent/README @@ -0,0 +1,2 @@ +This is dirent from mingw-runtime-3.3, separated for MSVC user's +benefit. diff --git a/glib/dirent/dirent-zip b/glib/dirent/dirent-zip new file mode 100644 index 0000000..7301987 --- /dev/null +++ b/glib/dirent/dirent-zip @@ -0,0 +1,19 @@ +#!/bin/sh + +# Build developer package for the dirent library. + +ZIP=/tmp/dirent.zip + +mkdir -p dist/include dist/lib +cp dirent.h dist/include +cp dirent.lib dist/lib + +(cd dist +rm $ZIP +zip $ZIP -@ < + * Significantly revised and rewinddir, seekdir and telldir added by Colin + * Peters + * + */ + +#include +#include +#include +#include +#include + +#include "dirent.h" + +#define WIN32_LEAN_AND_MEAN +#include /* for GetFileAttributes */ + +#include + +#ifdef _UNICODE +#define _tdirent _wdirent +#define _TDIR _WDIR +#define _topendir _wopendir +#define _tclosedir _wclosedir +#define _treaddir _wreaddir +#define _trewinddir _wrewinddir +#define _ttelldir _wtelldir +#define _tseekdir _wseekdir +#else +#define _tdirent dirent +#define _TDIR DIR +#define _topendir opendir +#define _tclosedir closedir +#define _treaddir readdir +#define _trewinddir rewinddir +#define _ttelldir telldir +#define _tseekdir seekdir +#endif + +#define SUFFIX _T("*") +#define SLASH _T("\\") + + +/* + * opendir + * + * Returns a pointer to a DIR structure appropriately filled in to begin + * searching a directory. + */ +_TDIR * +_topendir (const _TCHAR *szPath) +{ + _TDIR *nd; + unsigned int rc; + _TCHAR szFullPath[MAX_PATH]; + + errno = 0; + + if (!szPath) + { + errno = EFAULT; + return (_TDIR *) 0; + } + + if (szPath[0] == _T('\0')) + { + errno = ENOTDIR; + return (_TDIR *) 0; + } + + /* Attempt to determine if the given path really is a directory. */ + rc = GetFileAttributes (szPath); + if (rc == (unsigned int)-1) + { + /* call GetLastError for more error info */ + errno = ENOENT; + return (_TDIR *) 0; + } + if (!(rc & FILE_ATTRIBUTE_DIRECTORY)) + { + /* Error, entry exists but not a directory. */ + errno = ENOTDIR; + return (_TDIR *) 0; + } + + /* Make an absolute pathname. */ + _tfullpath (szFullPath, szPath, MAX_PATH); + + /* Allocate enough space to store DIR structure and the complete + * directory path given. */ + nd = (_TDIR *) malloc (sizeof (_TDIR) + (_tcslen(szFullPath) + _tcslen (SLASH) + + _tcslen(SUFFIX) + 1) * sizeof(_TCHAR)); + + if (!nd) + { + /* Error, out of memory. */ + errno = ENOMEM; + return (_TDIR *) 0; + } + + /* Create the search expression. */ + _tcscpy (nd->dd_name, szFullPath); + + /* Add on a slash if the path does not end with one. */ + if (nd->dd_name[0] != _T('\0') && + nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('/') && + nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('\\')) + { + _tcscat (nd->dd_name, SLASH); + } + + /* Add on the search pattern */ + _tcscat (nd->dd_name, SUFFIX); + + /* Initialize handle to -1 so that a premature closedir doesn't try + * to call _findclose on it. */ + nd->dd_handle = -1; + + /* Initialize the status. */ + nd->dd_stat = 0; + + /* Initialize the dirent structure. ino and reclen are invalid under + * Win32, and name simply points at the appropriate part of the + * findfirst_t structure. */ + nd->dd_dir.d_ino = 0; + nd->dd_dir.d_reclen = 0; + nd->dd_dir.d_namlen = 0; + memset (nd->dd_dir.d_name, 0, sizeof (nd->dd_dir.d_name)); + + return nd; +} + + +/* + * readdir + * + * Return a pointer to a dirent structure filled with the information on the + * next entry in the directory. + */ +struct _tdirent * +_treaddir (_TDIR * dirp) +{ + errno = 0; + + /* Check for valid DIR struct. */ + if (!dirp) + { + errno = EFAULT; + return (struct _tdirent *) 0; + } + + if (dirp->dd_stat < 0) + { + /* We have already returned all files in the directory + * (or the structure has an invalid dd_stat). */ + return (struct _tdirent *) 0; + } + else if (dirp->dd_stat == 0) + { + /* We haven't started the search yet. */ + /* Start the search */ + dirp->dd_handle = _tfindfirst (dirp->dd_name, &(dirp->dd_dta)); + + if (dirp->dd_handle == -1) + { + /* Whoops! Seems there are no files in that + * directory. */ + dirp->dd_stat = -1; + } + else + { + dirp->dd_stat = 1; + } + } + else + { + /* Get the next search entry. */ + if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta))) + { + /* We are off the end or otherwise error. + _findnext sets errno to ENOENT if no more file + Undo this. */ + DWORD winerr = GetLastError(); + if (winerr == ERROR_NO_MORE_FILES) + errno = 0; + _findclose (dirp->dd_handle); + dirp->dd_handle = -1; + dirp->dd_stat = -1; + } + else + { + /* Update the status to indicate the correct + * number. */ + dirp->dd_stat++; + } + } + + if (dirp->dd_stat > 0) + { + /* Successfully got an entry. Everything about the file is + * already appropriately filled in except the length of the + * file name. */ + dirp->dd_dir.d_namlen = _tcslen (dirp->dd_dta.name); + _tcscpy (dirp->dd_dir.d_name, dirp->dd_dta.name); + return &dirp->dd_dir; + } + + return (struct _tdirent *) 0; +} + + +/* + * closedir + * + * Frees up resources allocated by opendir. + */ +int +_tclosedir (_TDIR * dirp) +{ + int rc; + + errno = 0; + rc = 0; + + if (!dirp) + { + errno = EFAULT; + return -1; + } + + if (dirp->dd_handle != -1) + { + rc = _findclose (dirp->dd_handle); + } + + /* Delete the dir structure. */ + free (dirp); + + return rc; +} + +/* + * rewinddir + * + * Return to the beginning of the directory "stream". We simply call findclose + * and then reset things like an opendir. + */ +void +_trewinddir (_TDIR * dirp) +{ + errno = 0; + + if (!dirp) + { + errno = EFAULT; + return; + } + + if (dirp->dd_handle != -1) + { + _findclose (dirp->dd_handle); + } + + dirp->dd_handle = -1; + dirp->dd_stat = 0; +} + +/* + * telldir + * + * Returns the "position" in the "directory stream" which can be used with + * seekdir to go back to an old entry. We simply return the value in stat. + */ +long +_ttelldir (_TDIR * dirp) +{ + errno = 0; + + if (!dirp) + { + errno = EFAULT; + return -1; + } + return dirp->dd_stat; +} + +/* + * seekdir + * + * Seek to an entry previously returned by telldir. We rewind the directory + * and call readdir repeatedly until either dd_stat is the position number + * or -1 (off the end). This is not perfect, in that the directory may + * have changed while we weren't looking. But that is probably the case with + * any such system. + */ +void +_tseekdir (_TDIR * dirp, long lPos) +{ + errno = 0; + + if (!dirp) + { + errno = EFAULT; + return; + } + + if (lPos < -1) + { + /* Seeking to an invalid position. */ + errno = EINVAL; + return; + } + else if (lPos == -1) + { + /* Seek past end. */ + if (dirp->dd_handle != -1) + { + _findclose (dirp->dd_handle); + } + dirp->dd_handle = -1; + dirp->dd_stat = -1; + } + else + { + /* Rewind and read forward to the appropriate index. */ + _trewinddir (dirp); + + while ((dirp->dd_stat < lPos) && _treaddir (dirp)) + ; + } +} diff --git a/glib/dirent/dirent.h b/glib/dirent/dirent.h new file mode 100644 index 0000000..857710f --- /dev/null +++ b/glib/dirent/dirent.h @@ -0,0 +1,127 @@ +/* + * DIRENT.H (formerly DIRLIB.H) + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + */ +#ifndef _DIRENT_H_ +#define _DIRENT_H_ + +#include +#include + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +struct dirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + char d_name[FILENAME_MAX+1]; /* File name plus nul delimiter. */ +}; + +#ifdef _WIN64 +#define INTPTR __int64 +#else +#define INTPTR long +#endif + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + * dd_stat field is now int (was short in older versions). + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _finddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct dirent dd_dir; + + /* _findnext handle */ + INTPTR dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + char dd_name[1]; +} DIR; + +DIR* __cdecl opendir (const char*); +struct dirent* __cdecl readdir (DIR*); +int __cdecl closedir (DIR*); +void __cdecl rewinddir (DIR*); +long __cdecl telldir (DIR*); +void __cdecl seekdir (DIR*, long); + + +/* wide char versions */ + +struct _wdirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + wchar_t d_name[FILENAME_MAX+1]; /* File name plus nul delimiter. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _wfinddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct _wdirent dd_dir; + + /* _findnext handle */ + INTPTR dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + wchar_t dd_name[1]; +} _WDIR; + + + +_WDIR* __cdecl _wopendir (const wchar_t*); +struct _wdirent* __cdecl _wreaddir (_WDIR*); +int __cdecl _wclosedir (_WDIR*); +void __cdecl _wrewinddir (_WDIR*); +long __cdecl _wtelldir (_WDIR*); +void __cdecl _wseekdir (_WDIR*, long); + + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _DIRENT_H_ */ diff --git a/glib/dirent/wdirent.c b/glib/dirent/wdirent.c new file mode 100644 index 0000000..098d854 --- /dev/null +++ b/glib/dirent/wdirent.c @@ -0,0 +1,3 @@ +#define _UNICODE 1 +#define UNICODE 1 +#include "dirent.c" diff --git a/glib/docs.c b/glib/docs.c new file mode 100644 index 0000000..9d6321b --- /dev/null +++ b/glib/docs.c @@ -0,0 +1,2636 @@ +/* + * Copyright © 2011 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Matthias Clasen + */ + + +/* This file collects documentation for macros, typedefs and + * the like, which have no good home in any of the 'real' source + * files. + */ + +/* Basic types {{{1 */ + +/** + * SECTION:types + * @title: Basic Types + * @short_description: standard GLib types, defined for ease-of-use + * and portability + * + * GLib defines a number of commonly used types, which can be divided + * into several groups: + * - New types which are not part of standard C (but are defined in + * various C standard library header files) — #gboolean, #gssize. + * - Integer types which are guaranteed to be the same size across + * all platforms — #gint8, #guint8, #gint16, #guint16, #gint32, + * #guint32, #gint64, #guint64. + * - Types which are easier to use than their standard C counterparts - + * #gpointer, #gconstpointer, #guchar, #guint, #gushort, #gulong. + * - Types which correspond exactly to standard C types, but are + * included for completeness — #gchar, #gint, #gshort, #glong, + * #gfloat, #gdouble. + * - Types which correspond exactly to standard C99 types, but are available + * to use even if your compiler does not support C99 — #gsize, #goffset, + * #gintptr, #guintptr. + * + * GLib also defines macros for the limits of some of the standard + * integer and floating point types, as well as macros for suitable + * printf() formats for these types. + * + * Note that depending on the platform and build configuration, the format + * macros might not be compatible with the system provided printf() function, + * because GLib might use a different printf() implementation internally. + * The format macros will always work with GLib API (like g_print()), and with + * any C99 compatible printf() implementation. + */ + +/** + * gboolean: + * + * A standard boolean type. + * Variables of this type should only contain the value + * %TRUE or %FALSE. + * + * Never directly compare the contents of a #gboolean variable with the values + * %TRUE or %FALSE. Use `if (condition)` to check a #gboolean is "true", instead + * of `if (condition == TRUE)`. Likewise use `if (!condition)` to check a + * #gboolean is "false". + * + * There is no validation when assigning to a #gboolean variable and so it could + * contain any value represented by a #gint. This is why the use of `if + * (condition)` is recommended. All non-zero values in C evaluate to "true". + */ + +/** + * gpointer: + * + * An untyped pointer. + * #gpointer looks better and is easier to use than void*. + */ + +/** + * gconstpointer: + * + * An untyped pointer to constant data. + * The data pointed to should not be changed. + * + * This is typically used in function prototypes to indicate + * that the data pointed to will not be altered by the function. + */ + +/** + * gchar: + * + * Corresponds to the standard C char type. + */ + +/** + * guchar: + * + * Corresponds to the standard C unsigned char type. + */ + +/** + * gint: + * + * Corresponds to the standard C int type. + * Values of this type can range from %G_MININT to %G_MAXINT. + */ + +/** + * G_MININT: + * + * The minimum value which can be held in a #gint. + */ + +/** + * G_MAXINT: + * + * The maximum value which can be held in a #gint. + */ + +/** + * guint: + * + * Corresponds to the standard C unsigned int type. + * Values of this type can range from 0 to %G_MAXUINT. + */ + +/** + * G_MAXUINT: + * + * The maximum value which can be held in a #guint. + */ + +/** + * gshort: + * + * Corresponds to the standard C short type. + * Values of this type can range from %G_MINSHORT to %G_MAXSHORT. + */ + +/** + * G_MINSHORT: + * + * The minimum value which can be held in a #gshort. + */ + +/** + * G_MAXSHORT: + * + * The maximum value which can be held in a #gshort. + */ + +/** + * gushort: + * + * Corresponds to the standard C unsigned short type. + * Values of this type can range from 0 to %G_MAXUSHORT. + */ + +/** + * G_MAXUSHORT: + * + * The maximum value which can be held in a #gushort. + */ + +/** + * glong: + * + * Corresponds to the standard C long type. + * Values of this type can range from %G_MINLONG to %G_MAXLONG. + */ + +/** + * G_MINLONG: + * + * The minimum value which can be held in a #glong. + */ + +/** + * G_MAXLONG: + * + * The maximum value which can be held in a #glong. + */ + +/** + * gulong: + * + * Corresponds to the standard C unsigned long type. + * Values of this type can range from 0 to %G_MAXULONG. + */ + +/** + * G_MAXULONG: + * + * The maximum value which can be held in a #gulong. + */ + +/** + * gint8: + * + * A signed integer guaranteed to be 8 bits on all platforms. + * Values of this type can range from %G_MININT8 (= -128) to + * %G_MAXINT8 (= 127). + */ + +/** + * G_MAXINT8: + * + * The maximum value which can be held in a #gint8. + * + * Since: 2.4 + */ + +/** + * guint8: + * + * An unsigned integer guaranteed to be 8 bits on all platforms. + * Values of this type can range from 0 to %G_MAXUINT8 (= 255). + */ + +/** + * G_MAXUINT8: + * + * The maximum value which can be held in a #guint8. + * + * Since: 2.4 + */ + +/** + * gint16: + * + * A signed integer guaranteed to be 16 bits on all platforms. + * Values of this type can range from %G_MININT16 (= -32,768) to + * %G_MAXINT16 (= 32,767). + * + * To print or scan values of this type, use + * %G_GINT16_MODIFIER and/or %G_GINT16_FORMAT. + */ + +/** + * G_MAXINT16: + * + * The maximum value which can be held in a #gint16. + * + * Since: 2.4 + */ + +/** + * G_GINT16_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gint16 or #guint16. It + * is a string literal, but doesn't include the percent-sign, such + * that you can add precision and length modifiers between percent-sign + * and conversion specifier and append a conversion specifier. + * + * The following example prints "0x7b"; + * |[ + * gint16 value = 123; + * g_print ("%#" G_GINT16_MODIFIER "x", value); + * ]| + * + * Since: 2.4 + */ + +/** + * G_GINT16_FORMAT: + * + * This is the platform dependent conversion specifier for scanning and + * printing values of type #gint16. It is a string literal, but doesn't + * include the percent-sign, such that you can add precision and length + * modifiers between percent-sign and conversion specifier. + * + * |[ + * gint16 in; + * gint32 out; + * sscanf ("42", "%" G_GINT16_FORMAT, &in) + * out = in * 1000; + * g_print ("%" G_GINT32_FORMAT, out); + * ]| + */ + +/** + * guint16: + * + * An unsigned integer guaranteed to be 16 bits on all platforms. + * Values of this type can range from 0 to %G_MAXUINT16 (= 65,535). + * + * To print or scan values of this type, use + * %G_GINT16_MODIFIER and/or %G_GUINT16_FORMAT. + */ + +/** + * G_MAXUINT16: + * + * The maximum value which can be held in a #guint16. + * + * Since: 2.4 + */ + +/** + * G_GUINT16_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #guint16. See also %G_GINT16_FORMAT + */ + +/** + * gint32: + * + * A signed integer guaranteed to be 32 bits on all platforms. + * Values of this type can range from %G_MININT32 (= -2,147,483,648) + * to %G_MAXINT32 (= 2,147,483,647). + * + * To print or scan values of this type, use + * %G_GINT32_MODIFIER and/or %G_GINT32_FORMAT. + */ + +/** + * G_MAXINT32: + * + * The maximum value which can be held in a #gint32. + * + * Since: 2.4 + */ + +/** + * G_GINT32_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gint32 or #guint32. It + * is a string literal. See also %G_GINT16_MODIFIER. + * + * Since: 2.4 + */ + +/** + * G_GINT32_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gint32. See also %G_GINT16_FORMAT. + */ + +/** + * guint32: + * + * An unsigned integer guaranteed to be 32 bits on all platforms. + * Values of this type can range from 0 to %G_MAXUINT32 (= 4,294,967,295). + * + * To print or scan values of this type, use + * %G_GINT32_MODIFIER and/or %G_GUINT32_FORMAT. + */ + +/** + * G_MAXUINT32: + * + * The maximum value which can be held in a #guint32. + * + * Since: 2.4 + */ + +/** + * G_GUINT32_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #guint32. See also %G_GINT16_FORMAT. + */ + +/** + * gint64: + * + * A signed integer guaranteed to be 64 bits on all platforms. + * Values of this type can range from %G_MININT64 + * (= -9,223,372,036,854,775,808) to %G_MAXINT64 + * (= 9,223,372,036,854,775,807). + * + * To print or scan values of this type, use + * %G_GINT64_MODIFIER and/or %G_GINT64_FORMAT. + */ + +/** + * G_MAXINT64: + * + * The maximum value which can be held in a #gint64. + */ + +/** + * G_GINT64_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gint64 or #guint64. + * It is a string literal. + * + * Some platforms do not support printing 64-bit integers, even + * though the types are supported. On such platforms %G_GINT64_MODIFIER + * is not defined. + * + * Since: 2.4 + */ + +/** + * G_GINT64_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gint64. See also %G_GINT16_FORMAT. + * + * Some platforms do not support scanning and printing 64-bit integers, + * even though the types are supported. On such platforms %G_GINT64_FORMAT + * is not defined. Note that scanf() may not support 64-bit integers, even + * if %G_GINT64_FORMAT is defined. Due to its weak error handling, scanf() + * is not recommended for parsing anyway; consider using g_ascii_strtoull() + * instead. + */ + +/** + * guint64: + * + * An unsigned integer guaranteed to be 64-bits on all platforms. + * Values of this type can range from 0 to %G_MAXUINT64 + * (= 18,446,744,073,709,551,615). + * + * To print or scan values of this type, use + * %G_GINT64_MODIFIER and/or %G_GUINT64_FORMAT. + */ + +/** + * G_MAXUINT64: + * + * The maximum value which can be held in a #guint64. + */ + +/** + * G_GUINT64_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #guint64. See also %G_GINT16_FORMAT. + * + * Some platforms do not support scanning and printing 64-bit integers, + * even though the types are supported. On such platforms %G_GUINT64_FORMAT + * is not defined. Note that scanf() may not support 64-bit integers, even + * if %G_GINT64_FORMAT is defined. Due to its weak error handling, scanf() + * is not recommended for parsing anyway; consider using g_ascii_strtoull() + * instead. + */ + +/** + * G_GINT64_CONSTANT: + * @val: a literal integer value, e.g. 0x1d636b02300a7aa7 + * + * This macro is used to insert 64-bit integer literals + * into the source code. + */ + +/** + * G_GUINT64_CONSTANT: + * @val: a literal integer value, e.g. 0x1d636b02300a7aa7U + * + * This macro is used to insert 64-bit unsigned integer + * literals into the source code. + * + * Since: 2.10 + */ + +/** + * gfloat: + * + * Corresponds to the standard C float type. + * Values of this type can range from -%G_MAXFLOAT to %G_MAXFLOAT. + */ + +/** + * G_MINFLOAT: + * + * The minimum positive value which can be held in a #gfloat. + * + * If you are interested in the smallest value which can be held + * in a #gfloat, use -%G_MAXFLOAT. + */ + +/** + * G_MAXFLOAT: + * + * The maximum value which can be held in a #gfloat. + */ + +/** + * gdouble: + * + * Corresponds to the standard C double type. + * Values of this type can range from -%G_MAXDOUBLE to %G_MAXDOUBLE. + */ + +/** + * G_MINDOUBLE: + * + * The minimum positive value which can be held in a #gdouble. + * + * If you are interested in the smallest value which can be held + * in a #gdouble, use -%G_MAXDOUBLE. + */ + +/** + * G_MAXDOUBLE: + * + * The maximum value which can be held in a #gdouble. + */ + +/** + * gsize: + * + * An unsigned integer type of the result of the sizeof operator, + * corresponding to the size_t type defined in C99. + * This type is wide enough to hold the numeric value of a pointer, + * so it is usually 32 bit wide on a 32-bit platform and 64 bit wide + * on a 64-bit platform. Values of this type can range from 0 to + * %G_MAXSIZE. + * + * To print or scan values of this type, use + * %G_GSIZE_MODIFIER and/or %G_GSIZE_FORMAT. + */ + +/** + * G_MAXSIZE: + * + * The maximum value which can be held in a #gsize. + * + * Since: 2.4 + */ + +/** + * G_GSIZE_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gsize. It + * is a string literal. + * + * Since: 2.6 + */ + +/** + * G_GSIZE_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gsize. See also %G_GINT16_FORMAT. + * + * Since: 2.6 + */ + +/** + * gssize: + * + * A signed variant of #gsize, corresponding to the + * ssize_t defined on most platforms. + * Values of this type can range from %G_MINSSIZE + * to %G_MAXSSIZE. + * + * To print or scan values of this type, use + * %G_GSSIZE_MODIFIER and/or %G_GSSIZE_FORMAT. + */ + +/** + * G_MINSSIZE: + * + * The minimum value which can be held in a #gssize. + * + * Since: 2.14 + */ + +/** + * G_MAXSSIZE: + * + * The maximum value which can be held in a #gssize. + * + * Since: 2.14 + */ + +/** + * G_GSSIZE_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gssize. See also %G_GINT16_FORMAT. + * + * Since: 2.6 + */ + +/** + * G_GSSIZE_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gssize. It + * is a string literal. + * + * Since: 2.6 + */ + +/** + * goffset: + * + * A signed integer type that is used for file offsets, + * corresponding to the POSIX type `off_t` as if compiling with + * `_FILE_OFFSET_BITS` set to 64. #goffset is always 64 bits wide, even on + * 32-bit architectures. + * Values of this type can range from %G_MINOFFSET to + * %G_MAXOFFSET. + * + * To print or scan values of this type, use + * %G_GOFFSET_MODIFIER and/or %G_GOFFSET_FORMAT. + * + * Since: 2.14 + */ + +/** + * G_MINOFFSET: + * + * The minimum value which can be held in a #goffset. + */ + +/** + * G_MAXOFFSET: + * + * The maximum value which can be held in a #goffset. + */ + +/** + * G_GOFFSET_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #goffset. It is a string + * literal. See also %G_GINT64_MODIFIER. + * + * Since: 2.20 + */ + +/** + * G_GOFFSET_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #goffset. See also %G_GINT64_FORMAT. + * + * Since: 2.20 + */ + +/** + * G_GOFFSET_CONSTANT: + * @val: a literal integer value, e.g. 0x1d636b02300a7aa7 + * + * This macro is used to insert #goffset 64-bit integer literals + * into the source code. + * + * See also G_GINT64_CONSTANT(). + * + * Since: 2.20 + */ + +/** + * gintptr: + * + * Corresponds to the C99 type intptr_t, + * a signed integer type that can hold any pointer. + * + * To print or scan values of this type, use + * %G_GINTPTR_MODIFIER and/or %G_GINTPTR_FORMAT. + * + * Since: 2.18 + */ + +/** + * G_GINTPTR_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gintptr or #guintptr. + * It is a string literal. + * + * Since: 2.22 + */ + +/** + * G_GINTPTR_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gintptr. + * + * Since: 2.22 + */ + +/** + * guintptr: + * + * Corresponds to the C99 type uintptr_t, + * an unsigned integer type that can hold any pointer. + * + * To print or scan values of this type, use + * %G_GINTPTR_MODIFIER and/or %G_GUINTPTR_FORMAT. + * + * Since: 2.18 + */ + +/** + * G_GUINTPTR_FORMAT: + * + * This is the platform dependent conversion specifier + * for scanning and printing values of type #guintptr. + * + * Since: 2.22 + */ + +/* Type conversion {{{1 */ + +/** + * SECTION:type_conversion + * @title: Type Conversion Macros + * @short_description: portably storing integers in pointer variables + * + * Many times GLib, GTK+, and other libraries allow you to pass "user + * data" to a callback, in the form of a void pointer. From time to time + * you want to pass an integer instead of a pointer. You could allocate + * an integer, with something like: + * |[ + * int *ip = g_new (int, 1); + * *ip = 42; + * ]| + * But this is inconvenient, and it's annoying to have to free the + * memory at some later time. + * + * Pointers are always at least 32 bits in size (on all platforms GLib + * intends to support). Thus you can store at least 32-bit integer values + * in a pointer value. Naively, you might try this, but it's incorrect: + * |[ + * gpointer p; + * int i; + * p = (void*) 42; + * i = (int) p; + * ]| + * Again, that example was not correct, don't copy it. + * The problem is that on some systems you need to do this: + * |[ + * gpointer p; + * int i; + * p = (void*) (long) 42; + * i = (int) (long) p; + * ]| + * The GLib macros GPOINTER_TO_INT(), GINT_TO_POINTER(), etc. take care + * to do the right thing on every platform. + * + * Warning: You may not store pointers in integers. This is not + * portable in any way, shape or form. These macros only allow storing + * integers in pointers, and only preserve 32 bits of the integer; values + * outside the range of a 32-bit integer will be mangled. + */ + +/** + * GINT_TO_POINTER: + * @i: integer to stuff into a pointer + * + * Stuffs an integer into a pointer type. + * + * Remember, you may not store pointers in integers. This is not portable + * in any way, shape or form. These macros only allow storing integers in + * pointers, and only preserve 32 bits of the integer; values outside the + * range of a 32-bit integer will be mangled. + */ + +/** + * GPOINTER_TO_INT: + * @p: pointer containing an integer + * + * Extracts an integer from a pointer. The integer must have + * been stored in the pointer with GINT_TO_POINTER(). + * + * Remember, you may not store pointers in integers. This is not portable + * in any way, shape or form. These macros only allow storing integers in + * pointers, and only preserve 32 bits of the integer; values outside the + * range of a 32-bit integer will be mangled. + */ + +/** + * GUINT_TO_POINTER: + * @u: unsigned integer to stuff into the pointer + * + * Stuffs an unsigned integer into a pointer type. + */ + +/** + * GPOINTER_TO_UINT: + * @p: pointer to extract an unsigned integer from + * + * Extracts an unsigned integer from a pointer. The integer must have + * been stored in the pointer with GUINT_TO_POINTER(). + */ + +/** + * GSIZE_TO_POINTER: + * @s: #gsize to stuff into the pointer + * + * Stuffs a #gsize into a pointer type. + */ + +/** + * GPOINTER_TO_SIZE: + * @p: pointer to extract a #gsize from + * + * Extracts a #gsize from a pointer. The #gsize must have + * been stored in the pointer with GSIZE_TO_POINTER(). + */ + +/* Byte order {{{1 */ + +/** + * SECTION:byte_order + * @title: Byte Order Macros + * @short_description: a portable way to convert between different byte orders + * + * These macros provide a portable way to determine the host byte order + * and to convert values between different byte orders. + * + * The byte order is the order in which bytes are stored to create larger + * data types such as the #gint and #glong values. + * The host byte order is the byte order used on the current machine. + * + * Some processors store the most significant bytes (i.e. the bytes that + * hold the largest part of the value) first. These are known as big-endian + * processors. Other processors (notably the x86 family) store the most + * significant byte last. These are known as little-endian processors. + * + * Finally, to complicate matters, some other processors store the bytes in + * a rather curious order known as PDP-endian. For a 4-byte word, the 3rd + * most significant byte is stored first, then the 4th, then the 1st and + * finally the 2nd. + * + * Obviously there is a problem when these different processors communicate + * with each other, for example over networks or by using binary file formats. + * This is where these macros come in. They are typically used to convert + * values into a byte order which has been agreed on for use when + * communicating between different processors. The Internet uses what is + * known as 'network byte order' as the standard byte order (which is in + * fact the big-endian byte order). + * + * Note that the byte order conversion macros may evaluate their arguments + * multiple times, thus you should not use them with arguments which have + * side-effects. + */ + +/** + * G_BYTE_ORDER: + * + * The host byte order. + * This can be either %G_LITTLE_ENDIAN or %G_BIG_ENDIAN (support for + * %G_PDP_ENDIAN may be added in future.) + */ + +/** + * G_LITTLE_ENDIAN: + * + * Specifies one of the possible types of byte order. + * See %G_BYTE_ORDER. + */ + +/** + * G_BIG_ENDIAN: + * + * Specifies one of the possible types of byte order. + * See %G_BYTE_ORDER. + */ + +/** + * G_PDP_ENDIAN: + * + * Specifies one of the possible types of byte order + * (currently unused). See %G_BYTE_ORDER. + */ + +/** + * g_htonl: + * @val: a 32-bit integer value in host byte order + * + * Converts a 32-bit integer value from host to network byte order. + * + * Returns: @val converted to network byte order + */ + +/** + * g_htons: + * @val: a 16-bit integer value in host byte order + * + * Converts a 16-bit integer value from host to network byte order. + * + * Returns: @val converted to network byte order + */ + +/** + * g_ntohl: + * @val: a 32-bit integer value in network byte order + * + * Converts a 32-bit integer value from network to host byte order. + * + * Returns: @val converted to host byte order. + */ + +/** + * g_ntohs: + * @val: a 16-bit integer value in network byte order + * + * Converts a 16-bit integer value from network to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT_FROM_BE: + * @val: a #gint value in big-endian byte order + * + * Converts a #gint value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT_FROM_LE: + * @val: a #gint value in little-endian byte order + * + * Converts a #gint value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT_TO_BE: + * @val: a #gint value in host byte order + * + * Converts a #gint value from host byte order to big-endian. + * + * Returns: @val converted to big-endian byte order + */ + +/** + * GINT_TO_LE: + * @val: a #gint value in host byte order + * + * Converts a #gint value from host byte order to little-endian. + * + * Returns: @val converted to little-endian byte order + */ + +/** + * GUINT_FROM_BE: + * @val: a #guint value in big-endian byte order + * + * Converts a #guint value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT_FROM_LE: + * @val: a #guint value in little-endian byte order + * + * Converts a #guint value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT_TO_BE: + * @val: a #guint value in host byte order + * + * Converts a #guint value from host byte order to big-endian. + * + * Returns: @val converted to big-endian byte order + */ + +/** + * GUINT_TO_LE: + * @val: a #guint value in host byte order + * + * Converts a #guint value from host byte order to little-endian. + * + * Returns: @val converted to little-endian byte order. + */ + +/** + * GLONG_FROM_BE: + * @val: a #glong value in big-endian byte order + * + * Converts a #glong value from big-endian to the host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GLONG_FROM_LE: + * @val: a #glong value in little-endian byte order + * + * Converts a #glong value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GLONG_TO_BE: + * @val: a #glong value in host byte order + * + * Converts a #glong value from host byte order to big-endian. + * + * Returns: @val converted to big-endian byte order + */ + +/** + * GLONG_TO_LE: + * @val: a #glong value in host byte order + * + * Converts a #glong value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GULONG_FROM_BE: + * @val: a #gulong value in big-endian byte order + * + * Converts a #gulong value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GULONG_FROM_LE: + * @val: a #gulong value in little-endian byte order + * + * Converts a #gulong value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GULONG_TO_BE: + * @val: a #gulong value in host byte order + * + * Converts a #gulong value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GULONG_TO_LE: + * @val: a #gulong value in host byte order + * + * Converts a #gulong value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GSIZE_FROM_BE: + * @val: a #gsize value in big-endian byte order + * + * Converts a #gsize value from big-endian to the host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GSIZE_FROM_LE: + * @val: a #gsize value in little-endian byte order + * + * Converts a #gsize value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GSIZE_TO_BE: + * @val: a #gsize value in host byte order + * + * Converts a #gsize value from host byte order to big-endian. + * + * Returns: @val converted to big-endian byte order + */ + +/** + * GSIZE_TO_LE: + * @val: a #gsize value in host byte order + * + * Converts a #gsize value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GSSIZE_FROM_BE: + * @val: a #gssize value in big-endian byte order + * + * Converts a #gssize value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GSSIZE_FROM_LE: + * @val: a #gssize value in little-endian byte order + * + * Converts a #gssize value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GSSIZE_TO_BE: + * @val: a #gssize value in host byte order + * + * Converts a #gssize value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GSSIZE_TO_LE: + * @val: a #gssize value in host byte order + * + * Converts a #gssize value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GINT16_FROM_BE: + * @val: a #gint16 value in big-endian byte order + * + * Converts a #gint16 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT16_FROM_LE: + * @val: a #gint16 value in little-endian byte order + * + * Converts a #gint16 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT16_TO_BE: + * @val: a #gint16 value in host byte order + * + * Converts a #gint16 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GINT16_TO_LE: + * @val: a #gint16 value in host byte order + * + * Converts a #gint16 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GUINT16_FROM_BE: + * @val: a #guint16 value in big-endian byte order + * + * Converts a #guint16 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT16_FROM_LE: + * @val: a #guint16 value in little-endian byte order + * + * Converts a #guint16 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT16_TO_BE: + * @val: a #guint16 value in host byte order + * + * Converts a #guint16 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GUINT16_TO_LE: + * @val: a #guint16 value in host byte order + * + * Converts a #guint16 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GINT32_FROM_BE: + * @val: a #gint32 value in big-endian byte order + * + * Converts a #gint32 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT32_FROM_LE: + * @val: a #gint32 value in little-endian byte order + * + * Converts a #gint32 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT32_TO_BE: + * @val: a #gint32 value in host byte order + * + * Converts a #gint32 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GINT32_TO_LE: + * @val: a #gint32 value in host byte order + * + * Converts a #gint32 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GUINT32_FROM_BE: + * @val: a #guint32 value in big-endian byte order + * + * Converts a #guint32 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT32_FROM_LE: + * @val: a #guint32 value in little-endian byte order + * + * Converts a #guint32 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT32_TO_BE: + * @val: a #guint32 value in host byte order + * + * Converts a #guint32 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GUINT32_TO_LE: + * @val: a #guint32 value in host byte order + * + * Converts a #guint32 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GINT64_FROM_BE: + * @val: a #gint64 value in big-endian byte order + * + * Converts a #gint64 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT64_FROM_LE: + * @val: a #gint64 value in little-endian byte order + * + * Converts a #gint64 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT64_TO_BE: + * @val: a #gint64 value in host byte order + * + * Converts a #gint64 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GINT64_TO_LE: + * @val: a #gint64 value in host byte order + * + * Converts a #gint64 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GUINT64_FROM_BE: + * @val: a #guint64 value in big-endian byte order + * + * Converts a #guint64 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT64_FROM_LE: + * @val: a #guint64 value in little-endian byte order + * + * Converts a #guint64 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT64_TO_BE: + * @val: a #guint64 value in host byte order + * + * Converts a #guint64 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GUINT64_TO_LE: + * @val: a #guint64 value in host byte order + * + * Converts a #guint64 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GUINT16_SWAP_BE_PDP: + * @val: a #guint16 value in big-endian or pdp-endian byte order + * + * Converts a #guint16 value between big-endian and pdp-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT16_SWAP_LE_BE: + * @val: a #guint16 value in little-endian or big-endian byte order + * + * Converts a #guint16 value between little-endian and big-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT16_SWAP_LE_PDP: + * @val: a #guint16 value in little-endian or pdp-endian byte order + * + * Converts a #guint16 value between little-endian and pdp-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT32_SWAP_BE_PDP: + * @val: a #guint32 value in big-endian or pdp-endian byte order + * + * Converts a #guint32 value between big-endian and pdp-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT32_SWAP_LE_BE: + * @val: a #guint32 value in little-endian or big-endian byte order + * + * Converts a #guint32 value between little-endian and big-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT32_SWAP_LE_PDP: + * @val: a #guint32 value in little-endian or pdp-endian byte order + * + * Converts a #guint32 value between little-endian and pdp-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT64_SWAP_LE_BE: + * @val: a #guint64 value in little-endian or big-endian byte order + * + * Converts a #guint64 value between little-endian and big-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/* Bounds-checked integer arithmetic {{{1 */ +/** + * SECTION:checkedmath + * @title: Bounds-checking integer arithmetic + * @short_description: a set of helpers for performing checked integer arithmetic + * + * GLib offers a set of macros for doing additions and multiplications + * of unsigned integers, with checks for overflows. + * + * The helpers all have three arguments. A pointer to the destination + * is always the first argument and the operands to the operation are + * the other two. + * + * Following standard GLib convention, the helpers return %TRUE in case + * of success (ie: no overflow). + * + * The helpers may be macros, normal functions or inlines. They may be + * implemented with inline assembly or compiler intrinsics where + * available. + * + * Since: 2.48 + */ + +/** + * g_uint_checked_add + * @dest: a pointer to the #guint destination + * @a: the #guint left operand + * @b: the #guint right operand + * + * Performs a checked addition of @a and @b, storing the result in + * @dest. + * + * If the operation is successful, %TRUE is returned. If the operation + * overflows then the state of @dest is undefined and %FALSE is + * returned. + * + * Returns: %TRUE if there was no overflow + * Since: 2.48 + */ + +/** + * g_uint_checked_mul + * @dest: a pointer to the #guint destination + * @a: the #guint left operand + * @b: the #guint right operand + * + * Performs a checked multiplication of @a and @b, storing the result in + * @dest. + * + * If the operation is successful, %TRUE is returned. If the operation + * overflows then the state of @dest is undefined and %FALSE is + * returned. + * + * Returns: %TRUE if there was no overflow + * Since: 2.48 + */ + +/** + * g_uint64_checked_add + * @dest: a pointer to the #guint64 destination + * @a: the #guint64 left operand + * @b: the #guint64 right operand + * + * Performs a checked addition of @a and @b, storing the result in + * @dest. + * + * If the operation is successful, %TRUE is returned. If the operation + * overflows then the state of @dest is undefined and %FALSE is + * returned. + * + * Returns: %TRUE if there was no overflow + * Since: 2.48 + */ + +/** + * g_uint64_checked_mul + * @dest: a pointer to the #guint64 destination + * @a: the #guint64 left operand + * @b: the #guint64 right operand + * + * Performs a checked multiplication of @a and @b, storing the result in + * @dest. + * + * If the operation is successful, %TRUE is returned. If the operation + * overflows then the state of @dest is undefined and %FALSE is + * returned. + * + * Returns: %TRUE if there was no overflow + * Since: 2.48 + */ + +/** + * g_size_checked_add + * @dest: a pointer to the #gsize destination + * @a: the #gsize left operand + * @b: the #gsize right operand + * + * Performs a checked addition of @a and @b, storing the result in + * @dest. + * + * If the operation is successful, %TRUE is returned. If the operation + * overflows then the state of @dest is undefined and %FALSE is + * returned. + * + * Returns: %TRUE if there was no overflow + * Since: 2.48 + */ + +/** + * g_size_checked_mul + * @dest: a pointer to the #gsize destination + * @a: the #gsize left operand + * @b: the #gsize right operand + * + * Performs a checked multiplication of @a and @b, storing the result in + * @dest. + * + * If the operation is successful, %TRUE is returned. If the operation + * overflows then the state of @dest is undefined and %FALSE is + * returned. + * + * Returns: %TRUE if there was no overflow + * Since: 2.48 + */ +/* Numerical Definitions {{{1 */ + +/** + * SECTION:numerical + * @title: Numerical Definitions + * @short_description: mathematical constants, and floating point decomposition + * + * GLib offers mathematical constants such as %G_PI for the value of pi; + * many platforms have these in the C library, but some don't, the GLib + * versions always exist. + * + * The #GFloatIEEE754 and #GDoubleIEEE754 unions are used to access the + * sign, mantissa and exponent of IEEE floats and doubles. These unions are + * defined as appropriate for a given platform. IEEE floats and doubles are + * supported (used for storage) by at least Intel, PPC and Sparc. See + * [IEEE 754-2008](http://en.wikipedia.org/wiki/IEEE_float) + * for more information about IEEE number formats. + */ + +/** + * G_IEEE754_FLOAT_BIAS: + * + * The bias by which exponents in single-precision floats are offset. + */ + +/** + * G_IEEE754_DOUBLE_BIAS: + * + * The bias by which exponents in double-precision floats are offset. + */ + +/** + * GFloatIEEE754: + * @v_float: the double value + * + * The #GFloatIEEE754 and #GDoubleIEEE754 unions are used to access the sign, + * mantissa and exponent of IEEE floats and doubles. These unions are defined + * as appropriate for a given platform. IEEE floats and doubles are supported + * (used for storage) by at least Intel, PPC and Sparc. + */ + +/** + * GDoubleIEEE754: + * @v_double: the double value + * + * The #GFloatIEEE754 and #GDoubleIEEE754 unions are used to access the sign, + * mantissa and exponent of IEEE floats and doubles. These unions are defined + * as appropriate for a given platform. IEEE floats and doubles are supported + * (used for storage) by at least Intel, PPC and Sparc. + */ + +/** + * G_E: + * + * The base of natural logarithms. + */ + +/** + * G_LN2: + * + * The natural logarithm of 2. + */ + +/** + * G_LN10: + * + * The natural logarithm of 10. + */ + +/** + * G_PI: + * + * The value of pi (ratio of circle's circumference to its diameter). + */ + +/** + * G_PI_2: + * + * Pi divided by 2. + */ + +/** + * G_PI_4: + * + * Pi divided by 4. + */ + +/** + * G_SQRT2: + * + * The square root of two. + */ + +/** + * G_LOG_2_BASE_10: + * + * Multiplying the base 2 exponent by this number yields the base 10 exponent. + */ + +/* Macros {{{1 */ + +/** + * SECTION:macros + * @title: Standard Macros + * @short_description: commonly-used macros + * + * These macros provide a few commonly-used features. + */ + +/** + * G_OS_WIN32: + * + * This macro is defined only on Windows. So you can bracket + * Windows-specific code in "\#ifdef G_OS_WIN32". + */ + +/** + * G_OS_UNIX: + * + * This macro is defined only on UNIX. So you can bracket + * UNIX-specific code in "\#ifdef G_OS_UNIX". + */ + +/** + * G_DIR_SEPARATOR: + * + * The directory separator character. + * This is '/' on UNIX machines and '\' under Windows. + */ + +/** + * G_DIR_SEPARATOR_S: + * + * The directory separator as a string. + * This is "/" on UNIX machines and "\" under Windows. + */ + +/** + * G_IS_DIR_SEPARATOR: + * @c: a character + * + * Checks whether a character is a directory + * separator. It returns %TRUE for '/' on UNIX + * machines and for '\' or '/' under Windows. + * + * Since: 2.6 + */ + +/** + * G_SEARCHPATH_SEPARATOR: + * + * The search path separator character. + * This is ':' on UNIX machines and ';' under Windows. + */ + +/** + * G_SEARCHPATH_SEPARATOR_S: + * + * The search path separator as a string. + * This is ":" on UNIX machines and ";" under Windows. + */ + +/** + * TRUE: + * + * Defines the %TRUE value for the #gboolean type. + */ + +/** + * FALSE: + * + * Defines the %FALSE value for the #gboolean type. + */ + +/** + * NULL: + * + * Defines the standard %NULL pointer. + */ + +/** + * MIN: + * @a: a numeric value + * @b: a numeric value + * + * Calculates the minimum of @a and @b. + * + * Returns: the minimum of @a and @b. + */ + +/** + * MAX: + * @a: a numeric value + * @b: a numeric value + * + * Calculates the maximum of @a and @b. + * + * Returns: the maximum of @a and @b. + */ + +/** + * ABS: + * @a: a numeric value + * + * Calculates the absolute value of @a. + * The absolute value is simply the number with any negative sign taken away. + * + * For example, + * - ABS(-10) is 10. + * - ABS(10) is also 10. + * + * Returns: the absolute value of @a. + */ + +/** + * CLAMP: + * @x: the value to clamp + * @low: the minimum value allowed + * @high: the maximum value allowed + * + * Ensures that @x is between the limits set by @low and @high. If @low is + * greater than @high the result is undefined. + * + * For example, + * - CLAMP(5, 10, 15) is 10. + * - CLAMP(15, 5, 10) is 10. + * - CLAMP(20, 15, 25) is 20. + * + * Returns: the value of @x clamped to the range between @low and @high + */ + +/** + * G_APPROX_VALUE: + * @a: a numeric value + * @b: a numeric value + * @epsilon: a numeric value that expresses the tolerance between @a and @b + * + * Evaluates to a truth value if the absolute difference between @a and @b is + * smaller than @epsilon, and to a false value otherwise. + * + * For example, + * - `G_APPROX_VALUE (5, 6, 2)` evaluates to true + * - `G_APPROX_VALUE (3.14, 3.15, 0.001)` evaluates to false + * - `G_APPROX_VALUE (n, 0.f, FLT_EPSILON)` evaluates to true if `n` is within + * the single precision floating point epsilon from zero + * + * Returns: %TRUE if the two values are within the desired range + * + * Since: 2.58 + */ + +/** + * G_STRUCT_MEMBER: + * @member_type: the type of the struct field + * @struct_p: a pointer to a struct + * @struct_offset: the offset of the field from the start of the struct, + * in bytes + * + * Returns a member of a structure at a given offset, using the given type. + * + * Returns: the struct member + */ + +/** + * G_STRUCT_MEMBER_P: + * @struct_p: a pointer to a struct + * @struct_offset: the offset from the start of the struct, in bytes + * + * Returns an untyped pointer to a given offset of a struct. + * + * Returns: an untyped pointer to @struct_p plus @struct_offset bytes + */ + +/** + * G_STRUCT_OFFSET: + * @struct_type: a structure type, e.g. #GtkWidget + * @member: a field in the structure, e.g. @window + * + * Returns the offset, in bytes, of a member of a struct. + * + * Returns: the offset of @member from the start of @struct_type + */ + +/** + * G_N_ELEMENTS: + * @arr: the array + * + * Determines the number of elements in an array. The array must be + * declared so the compiler knows its size at compile-time; this + * macro will not work on an array allocated on the heap, only static + * arrays or arrays on the stack. + */ + +/* Miscellaneous Macros {{{1 */ + +/** + * SECTION:macros_misc + * @title: Miscellaneous Macros + * @short_description: specialized macros which are not used often + * + * These macros provide more specialized features which are not + * needed so often by application programmers. + */ + +/** + * G_STMT_START: + * + * Used within multi-statement macros so that they can be used in places + * where only one statement is expected by the compiler. + */ + +/** + * G_STMT_END: + * + * Used within multi-statement macros so that they can be used in places + * where only one statement is expected by the compiler. + */ + +/** + * G_BEGIN_DECLS: + * + * Used (along with %G_END_DECLS) to bracket header files. If the + * compiler in use is a C++ compiler, adds extern "C" + * around the header. + */ + +/** + * G_END_DECLS: + * + * Used (along with %G_BEGIN_DECLS) to bracket header files. If the + * compiler in use is a C++ compiler, adds extern "C" + * around the header. + */ + +/** + * G_VA_COPY: + * @ap1: the va_list variable to place a copy of @ap2 in + * @ap2: a va_list + * + * Portable way to copy va_list variables. + * + * In order to use this function, you must include string.h yourself, + * because this macro may use memmove() and GLib does not include + * string.h for you. + * + * Each invocation of `G_VA_COPY (ap1, ap2)` must be matched with a + * corresponding `va_end (ap1)` call in the same function. + */ + +/** + * G_STRINGIFY: + * @macro_or_string: a macro or a string + * + * Accepts a macro or a string and converts it into a string after + * preprocessor argument expansion. For example, the following code: + * + * |[ + * #define AGE 27 + * const gchar *greeting = G_STRINGIFY (AGE) " today!"; + * ]| + * + * is transformed by the preprocessor into (code equivalent to): + * + * |[ + * const gchar *greeting = "27 today!"; + * ]| + */ + +/** + * G_PASTE: + * @identifier1: an identifier + * @identifier2: an identifier + * + * Yields a new preprocessor pasted identifier + * @identifier1identifier2 from its expanded + * arguments @identifier1 and @identifier2. For example, + * the following code: + * |[ + * #define GET(traveller,method) G_PASTE(traveller_get_, method) (traveller) + * const gchar *name = GET (traveller, name); + * const gchar *quest = GET (traveller, quest); + * GdkColor *favourite = GET (traveller, favourite_colour); + * ]| + * + * is transformed by the preprocessor into: + * |[ + * const gchar *name = traveller_get_name (traveller); + * const gchar *quest = traveller_get_quest (traveller); + * GdkColor *favourite = traveller_get_favourite_colour (traveller); + * ]| + * + * Since: 2.20 + */ + +/** + * G_STATIC_ASSERT: + * @expr: a constant expression + * + * The G_STATIC_ASSERT() macro lets the programmer check + * a condition at compile time, the condition needs to + * be compile time computable. The macro can be used in + * any place where a typedef is valid. + * + * A typedef is generally allowed in exactly the same places that + * a variable declaration is allowed. For this reason, you should + * not use G_STATIC_ASSERT() in the middle of blocks of code. + * + * The macro should only be used once per source code line. + * + * Since: 2.20 + */ + +/** + * G_STATIC_ASSERT_EXPR: + * @expr: a constant expression + * + * The G_STATIC_ASSERT_EXPR() macro lets the programmer check + * a condition at compile time. The condition needs to be + * compile time computable. + * + * Unlike G_STATIC_ASSERT(), this macro evaluates to an expression + * and, as such, can be used in the middle of other expressions. + * Its value should be ignored. This can be accomplished by placing + * it as the first argument of a comma expression. + * + * |[ + * #define ADD_ONE_TO_INT(x) \ + * (G_STATIC_ASSERT_EXPR(sizeof (x) == sizeof (int)), ((x) + 1)) + * ]| + * + * Since: 2.30 + */ + +/** + * G_GNUC_EXTENSION: + * + * Expands to __extension__ when gcc is used as the compiler. This simply + * tells gcc not to warn about the following non-standard code when compiling + * with the `-pedantic` option. + */ + +/** + * G_GNUC_CHECK_VERSION: + * @major: major version to check against + * @minor: minor version to check against + * + * Expands to a check for a compiler with __GNUC__ defined and a version + * greater than or equal to the major and minor numbers provided. For example, + * the following would only match on compilers such as GCC 4.8 or newer. + * + * |[ + * #if G_GNUC_CHECK_VERSION(4, 8) + * #endif + * ]| + * + * Since: 2.42 + */ + +/** + * G_GNUC_BEGIN_IGNORE_DEPRECATIONS: + * + * Tells gcc (if it is a new enough version) to temporarily stop emitting + * warnings when functions marked with %G_GNUC_DEPRECATED or + * %G_GNUC_DEPRECATED_FOR are called. This is useful for when you have + * one deprecated function calling another one, or when you still have + * regression tests for deprecated functions. + * + * Use %G_GNUC_END_IGNORE_DEPRECATIONS to begin warning again. (If you + * are not compiling with `-Wdeprecated-declarations` then neither macro + * has any effect.) + * + * This macro can be used either inside or outside of a function body, + * but must appear on a line by itself. Both this macro and the corresponding + * %G_GNUC_END_IGNORE_DEPRECATIONS are considered statements, so they + * should not be used around branching or loop conditions; for instance, + * this use is invalid: + * + * |[ + * G_GNUC_BEGIN_IGNORE_DEPRECATIONS + * if (check == some_deprecated_function ()) + * G_GNUC_END_IGNORE_DEPRECATIONS + * { + * do_something (); + * } + * ]| + * + * and you should move the deprecated section outside the condition + * + * |[ + * + * // Solution A + * some_data_t *res; + * + * G_GNUC_BEGIN_IGNORE_DEPRECATIONS + * res = some_deprecated_function (); + * G_GNUC_END_IGNORE_DEPRECATIONS + * + * if (check == res) + * { + * do_something (); + * } + * + * // Solution B + * G_GNUC_BEGIN_IGNORE_DEPRECATIONS + * if (check == some_deprecated_function ()) + * { + * do_something (); + * } + * G_GNUC_END_IGNORE_DEPRECATIONS + * ]| + * + * |[ + * G_GNUC_INTERNAL + * void _g_log_fallback_handler (const gchar *log_domain, + * GLogLevelFlags log_level, + * const gchar *message, + * gpointer unused_data); + * ]| + * + * Since: 2.6 + */ + +/** + * G_LIKELY: + * @expr: the expression + * + * Hints the compiler that the expression is likely to evaluate to + * a true value. The compiler may use this information for optimizations. + * + * |[ + * if (G_LIKELY (random () != 1)) + * g_print ("not one"); + * ]| + * + * Returns: the value of @expr + * + * Since: 2.2 + */ + +/** + * G_UNLIKELY: + * @expr: the expression + * + * Hints the compiler that the expression is unlikely to evaluate to + * a true value. The compiler may use this information for optimizations. + * + * |[ + * if (G_UNLIKELY (random () == 1)) + * g_print ("a random one"); + * ]| + * + * Returns: the value of @expr + * + * Since: 2.2 + */ + +/** + * G_STRLOC: + * + * Expands to a string identifying the current code position. + */ + +/** + * G_STRFUNC: + * + * Expands to a string identifying the current function. + * + * Since: 2.4 + */ + +/** + * G_HAVE_GNUC_VISIBILITY: + * + * Defined to 1 if gcc-style visibility handling is supported. + */ + +/* g_auto(), g_autoptr() and helpers {{{1 */ + +/** + * g_auto: + * @TypeName: a supported variable type + * + * Helper to declare a variable with automatic cleanup. + * + * The variable is cleaned up in a way appropriate to its type when the + * variable goes out of scope. The type must support this. + * The way to clean up the type must have been defined using one of the macros + * G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC() or G_DEFINE_AUTO_CLEANUP_FREE_FUNC(). + * + * This feature is only supported on GCC and clang. This macro is not + * defined on other compilers and should not be used in programs that + * are intended to be portable to those compilers. + * + * This is meant to be used with stack-allocated structures and + * non-pointer types. For the (more commonly used) pointer version, see + * g_autoptr(). + * + * This macro can be used to avoid having to do explicit cleanups of + * local variables when exiting functions. It often vastly simplifies + * handling of error conditions, removing the need for various tricks + * such as `goto out` or repeating of cleanup code. It is also helpful + * for non-error cases. + * + * Consider the following example: + * + * |[ + * GVariant * + * my_func(void) + * { + * g_auto(GQueue) queue = G_QUEUE_INIT; + * g_auto(GVariantBuilder) builder; + * g_auto(GStrv) strv; + * + * g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + * strv = g_strsplit("a:b:c", ":", -1); + * + * ... + * + * if (error_condition) + * return NULL; + * + * ... + * + * return g_variant_builder_end (&builder); + * } + * ]| + * + * You must initialize the variable in some way — either by use of an + * initialiser or by ensuring that an `_init` function will be called on + * it unconditionally before it goes out of scope. + * + * Since: 2.44 + */ + +/** + * g_autoptr: + * @TypeName: a supported variable type + * + * Helper to declare a pointer variable with automatic cleanup. + * + * The variable is cleaned up in a way appropriate to its type when the + * variable goes out of scope. The type must support this. + * The way to clean up the type must have been defined using the macro + * G_DEFINE_AUTOPTR_CLEANUP_FUNC(). + * + * This feature is only supported on GCC and clang. This macro is not + * defined on other compilers and should not be used in programs that + * are intended to be portable to those compilers. + * + * This is meant to be used to declare pointers to types with cleanup + * functions. The type of the variable is a pointer to @TypeName. You + * must not add your own `*`. + * + * This macro can be used to avoid having to do explicit cleanups of + * local variables when exiting functions. It often vastly simplifies + * handling of error conditions, removing the need for various tricks + * such as `goto out` or repeating of cleanup code. It is also helpful + * for non-error cases. + * + * Consider the following example: + * + * |[ + * gboolean + * check_exists(GVariant *dict) + * { + * g_autoptr(GVariant) dirname, basename = NULL; + * g_autofree gchar *path = NULL; + * + * dirname = g_variant_lookup_value (dict, "dirname", G_VARIANT_TYPE_STRING); + * + * if (dirname == NULL) + * return FALSE; + * + * basename = g_variant_lookup_value (dict, "basename", G_VARIANT_TYPE_STRING); + * + * if (basename == NULL) + * return FALSE; + * + * path = g_build_filename (g_variant_get_string (dirname, NULL), + * g_variant_get_string (basename, NULL), + * NULL); + * + * return g_access (path, R_OK) == 0; + * } + * ]| + * + * You must initialise the variable in some way — either by use of an + * initialiser or by ensuring that it is assigned to unconditionally + * before it goes out of scope. + * + * See also g_auto(), g_autofree() and g_steal_pointer(). + * + * Since: 2.44 + */ + +/** + * g_autofree: + * + * Macro to add an attribute to pointer variable to ensure automatic + * cleanup using g_free(). + * + * This macro differs from g_autoptr() in that it is an attribute supplied + * before the type name, rather than wrapping the type definition. Instead + * of using a type-specific lookup, this macro always calls g_free() directly. + * + * This means it's useful for any type that is returned from + * g_malloc(). + * + * Otherwise, this macro has similar constraints as g_autoptr(): only + * supported on GCC and clang, the variable must be initialized, etc. + * + * |[ + * gboolean + * operate_on_malloc_buf (void) + * { + * g_autofree guint8* membuf = NULL; + * + * membuf = g_malloc (8192); + * + * // Some computation on membuf + * + * // membuf will be automatically freed here + * return TRUE; + * } + * ]| + * + * Since: 2.44 + */ + +/** + * g_autolist: + * @TypeName: a supported variable type + * + * Helper to declare a list variable with automatic deep cleanup. + * + * The list is deeply freed, in a way appropriate to the specified type, when the + * variable goes out of scope. The type must support this. + * + * This feature is only supported on GCC and clang. This macro is not + * defined on other compilers and should not be used in programs that + * are intended to be portable to those compilers. + * + * This is meant to be used to declare lists of a type with a cleanup + * function. The type of the variable is a `GList *`. You + * must not add your own `*`. + * + * This macro can be used to avoid having to do explicit cleanups of + * local variables when exiting functions. It often vastly simplifies + * handling of error conditions, removing the need for various tricks + * such as `goto out` or repeating of cleanup code. It is also helpful + * for non-error cases. + * + * See also g_autoslist(), g_autoptr() and g_steal_pointer(). + * + * Since: 2.56 + */ + +/** + * g_autoslist: + * @TypeName: a supported variable type + * + * Helper to declare a singly linked list variable with automatic deep cleanup. + * + * The list is deeply freed, in a way appropriate to the specified type, when the + * variable goes out of scope. The type must support this. + * + * This feature is only supported on GCC and clang. This macro is not + * defined on other compilers and should not be used in programs that + * are intended to be portable to those compilers. + * + * This is meant to be used to declare lists of a type with a cleanup + * function. The type of the variable is a `GSList *`. You + * must not add your own `*`. + * + * This macro can be used to avoid having to do explicit cleanups of + * local variables when exiting functions. It often vastly simplifies + * handling of error conditions, removing the need for various tricks + * such as `goto out` or repeating of cleanup code. It is also helpful + * for non-error cases. + * + * See also g_autolist(), g_autoptr() and g_steal_pointer(). + * + * Since: 2.56 + */ + +/** + * g_autoqueue: + * @TypeName: a supported variable type + * + * Helper to declare a double-ended queue variable with automatic deep cleanup. + * + * The queue is deeply freed, in a way appropriate to the specified type, when the + * variable goes out of scope. The type must support this. + * + * This feature is only supported on GCC and clang. This macro is not + * defined on other compilers and should not be used in programs that + * are intended to be portable to those compilers. + * + * This is meant to be used to declare queues of a type with a cleanup + * function. The type of the variable is a `GQueue *`. You + * must not add your own `*`. + * + * This macro can be used to avoid having to do explicit cleanups of + * local variables when exiting functions. It often vastly simplifies + * handling of error conditions, removing the need for various tricks + * such as `goto out` or repeating of cleanup code. It is also helpful + * for non-error cases. + * + * See also g_autolist(), g_autoptr() and g_steal_pointer(). + * + * Since: 2.62 + */ + + +/** + * G_DEFINE_AUTOPTR_CLEANUP_FUNC: + * @TypeName: a type name to define a g_autoptr() cleanup function for + * @func: the cleanup function + * + * Defines the appropriate cleanup function for a pointer type. + * + * The function will not be called if the variable to be cleaned up + * contains %NULL. + * + * This will typically be the `_free()` or `_unref()` function for the given + * type. + * + * With this definition, it will be possible to use g_autoptr() with + * @TypeName. + * + * |[ + * G_DEFINE_AUTOPTR_CLEANUP_FUNC(GObject, g_object_unref) + * ]| + * + * This macro should be used unconditionally; it is a no-op on compilers + * where cleanup is not supported. + * + * Since: 2.44 + */ + +/** + * G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC: + * @TypeName: a type name to define a g_auto() cleanup function for + * @func: the clear function + * + * Defines the appropriate cleanup function for a type. + * + * This will typically be the `_clear()` function for the given type. + * + * With this definition, it will be possible to use g_auto() with + * @TypeName. + * + * |[ + * G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GQueue, g_queue_clear) + * ]| + * + * This macro should be used unconditionally; it is a no-op on compilers + * where cleanup is not supported. + * + * Since: 2.44 + */ + +/** + * G_DEFINE_AUTO_CLEANUP_FREE_FUNC: + * @TypeName: a type name to define a g_auto() cleanup function for + * @func: the free function + * @none: the "none" value for the type + * + * Defines the appropriate cleanup function for a type. + * + * With this definition, it will be possible to use g_auto() with + * @TypeName. + * + * This function will be rarely used. It is used with pointer-based + * typedefs and non-pointer types where the value of the variable + * represents a resource that must be freed. Two examples are #GStrv + * and file descriptors. + * + * @none specifies the "none" value for the type in question. It is + * probably something like %NULL or `-1`. If the variable is found to + * contain this value then the free function will not be called. + * + * |[ + * G_DEFINE_AUTO_CLEANUP_FREE_FUNC(GStrv, g_strfreev, NULL) + * ]| + * + * This macro should be used unconditionally; it is a no-op on compilers + * where cleanup is not supported. + * + * Since: 2.44 + */ + +/* Warnings and Assertions {{{1 */ + +/** + * SECTION:warnings + * @title: Warnings and Assertions + * @short_description: warnings and assertions to use in runtime code + * + * GLib defines several warning functions and assertions which can be used to + * warn of programmer errors when calling functions, and print error messages + * from command line programs. + * + * The g_return_if_fail(), g_return_val_if_fail(), g_return_if_reached() and + * g_return_val_if_reached() macros are intended as pre-condition assertions, to + * be used at the top of a public function to check that the function’s + * arguments are acceptable. Any failure of such a pre-condition assertion is + * considered a programming error on the part of the caller of the public API, + * and the program is considered to be in an undefined state afterwards. They + * are similar to the libc assert() function, but provide more context on + * failures. + * + * For example: + * |[ + * gboolean + * g_dtls_connection_shutdown (GDtlsConnection *conn, + * gboolean shutdown_read, + * gboolean shutdown_write, + * GCancellable *cancellable, + * GError **error) + * { + * // local variable declarations + * + * g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), FALSE); + * g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + * g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + * + * // function body + * + * return return_val; + * } + * ]| + * + * g_print(), g_printerr() and g_set_print_handler() are intended to be used for + * output from command line applications, since they output to standard output + * and standard error by default — whereas functions like g_message() and + * g_log() may be redirected to special purpose message windows, files, or the + * system journal. + */ + +/* Windows Compatibility Functions {{{1 */ + +/** + * SECTION:windows + * @title: Windows Compatibility Functions + * @short_description: UNIX emulation on Windows + * + * These functions provide some level of UNIX emulation on the + * Windows platform. If your application really needs the POSIX + * APIs, we suggest you try the Cygwin project. + */ + +/** + * MAXPATHLEN: + * + * Provided for UNIX emulation on Windows; equivalent to UNIX + * macro %MAXPATHLEN, which is the maximum length of a filename + * (including full path). + */ + +/** + * G_WIN32_DLLMAIN_FOR_DLL_NAME: + * @static: empty or "static" + * @dll_name: the name of the (pointer to the) char array where + * the DLL name will be stored. If this is used, you must also + * include `windows.h`. If you need a more complex DLL entry + * point function, you cannot use this + * + * On Windows, this macro defines a DllMain() function that stores + * the actual DLL name that the code being compiled will be included in. + * + * On non-Windows platforms, expands to nothing. + */ + +/** + * G_WIN32_HAVE_WIDECHAR_API: + * + * On Windows, this macro defines an expression which evaluates to + * %TRUE if the code is running on a version of Windows where the wide + * character versions of the Win32 API functions, and the wide character + * versions of the C library functions work. (They are always present in + * the DLLs, but don't work on Windows 9x and Me.) + * + * On non-Windows platforms, it is not defined. + * + * Since: 2.6 + */ + + +/** + * G_WIN32_IS_NT_BASED: + * + * On Windows, this macro defines an expression which evaluates to + * %TRUE if the code is running on an NT-based Windows operating system. + * + * On non-Windows platforms, it is not defined. + * + * Since: 2.6 + */ + + /* Epilogue {{{1 */ +/* vim: set foldmethod=marker: */ diff --git a/glib/galloca.h b/glib/galloca.h new file mode 100644 index 0000000..86f0d76 --- /dev/null +++ b/glib/galloca.h @@ -0,0 +1,145 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_ALLOCA_H__ +#define __G_ALLOCA_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +#if defined(__BIONIC__) && defined (GLIB_HAVE_ALLOCA_H) +# include +#elif defined(__GNUC__) +/* GCC does the right thing */ +# undef alloca +# define alloca(size) __builtin_alloca (size) +#elif defined (GLIB_HAVE_ALLOCA_H) +/* a native and working alloca.h is there */ +# include +#else /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */ +# if defined(_MSC_VER) || defined(__DMC__) +# include +# define alloca _alloca +# else /* !_MSC_VER && !__DMC__ */ +# ifdef _AIX +# pragma alloca +# else /* !_AIX */ +# ifndef alloca /* predefined by HP cc +Olibcalls */ +G_BEGIN_DECLS +char *alloca (); +G_END_DECLS +# endif /* !alloca */ +# endif /* !_AIX */ +# endif /* !_MSC_VER && !__DMC__ */ +#endif /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */ + +/** + * g_alloca: + * @size: number of bytes to allocate. + * + * Allocates @size bytes on the stack; these bytes will be freed when the current + * stack frame is cleaned up. This macro essentially just wraps the alloca() + * function present on most UNIX variants. + * Thus it provides the same advantages and pitfalls as alloca(): + * + * - alloca() is very fast, as on most systems it's implemented by just adjusting + * the stack pointer register. + * + * - It doesn't cause any memory fragmentation, within its scope, separate alloca() + * blocks just build up and are released together at function end. + * + * - Allocation sizes have to fit into the current stack frame. For instance in a + * threaded environment on Linux, the per-thread stack size is limited to 2 Megabytes, + * so be sparse with alloca() uses. + * + * - Allocation failure due to insufficient stack space is not indicated with a %NULL + * return like e.g. with malloc(). Instead, most systems probably handle it the same + * way as out of stack space situations from infinite function recursion, i.e. + * with a segmentation fault. + * + * - Allowing @size to be specified by an untrusted party would allow for them + * to trigger a segmentation fault by specifying a large size, leading to a + * denial of service vulnerability. @size must always be entirely under the + * control of the program. + * + * - Special care has to be taken when mixing alloca() with GNU C variable sized arrays. + * Stack space allocated with alloca() in the same scope as a variable sized array + * will be freed together with the variable sized array upon exit of that scope, and + * not upon exit of the enclosing function scope. + * + * Returns: space for @size bytes, allocated on the stack + */ +#define g_alloca(size) alloca (size) + +/** + * g_alloca0: + * @size: number of bytes to allocate. + * + * Wraps g_alloca() and initializes allocated memory to zeroes. + * If @size is `0` it returns %NULL. + * + * Note that the @size argument will be evaluated multiple times. + * + * Returns: (nullable) (transfer full): space for @size bytes, allocated on the stack + * + * Since: 2.72 + */ +#define g_alloca0(size) ((size) == 0 ? NULL : memset (g_alloca (size), 0, (size))) + +/** + * g_newa: + * @struct_type: Type of memory chunks to be allocated + * @n_structs: Number of chunks to be allocated + * + * Wraps g_alloca() in a more typesafe manner. + * + * As mentioned in the documentation for g_alloca(), @n_structs must always be + * entirely under the control of the program, or you may introduce a denial of + * service vulnerability. In addition, the multiplication of @struct_type by + * @n_structs is not checked, so an overflow may lead to a remote code execution + * vulnerability. + * + * Returns: Pointer to stack space for @n_structs chunks of type @struct_type + */ +#define g_newa(struct_type, n_structs) ((struct_type*) g_alloca (sizeof (struct_type) * (gsize) (n_structs))) + +/** + * g_newa0: + * @struct_type: the type of the elements to allocate. + * @n_structs: the number of elements to allocate. + * + * Wraps g_alloca0() in a more typesafe manner. + * + * Returns: (nullable) (transfer full): Pointer to stack space for @n_structs + * chunks of type @struct_type + * + * Since: 2.72 + */ +#define g_newa0(struct_type, n_structs) ((struct_type*) g_alloca0 (sizeof (struct_type) * (gsize) (n_structs))) + +#endif /* __G_ALLOCA_H__ */ diff --git a/glib/garcbox.c b/glib/garcbox.c new file mode 100644 index 0000000..70aebb6 --- /dev/null +++ b/glib/garcbox.c @@ -0,0 +1,381 @@ +/* garcbox.c: Atomically reference counted data + * + * Copyright 2018 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" + +#include "grcboxprivate.h" + +#include "gmessages.h" +#include "grefcount.h" + +#ifdef ENABLE_VALGRIND +#include "valgrind.h" +#endif + +#include "glib_trace.h" + +#include + +#define G_ARC_BOX(p) (GArcBox *) (((char *) (p)) - G_ARC_BOX_SIZE) + +/** + * SECTION:arcbox + * @Title: Atomically reference counted data + * @Short_description: Allocated memory with atomic reference counting semantics + * + * An "atomically reference counted box", or "ArcBox", is an opaque wrapper + * data type that is guaranteed to be as big as the size of a given data type, + * and which augments the given data type with thread safe reference counting + * semantics for its memory management. + * + * ArcBox is useful if you have a plain old data type, like a structure + * typically placed on the stack, and you wish to provide additional API + * to use it on the heap; or if you want to implement a new type to be + * passed around by reference without necessarily implementing copy/free + * semantics or your own reference counting. + * + * The typical use is: + * + * |[ + * typedef struct { + * char *name; + * char *address; + * char *city; + * char *state; + * int age; + * } Person; + * + * Person * + * person_new (void) + * { + * return g_atomic_rc_box_new0 (Person); + * } + * ]| + * + * Every time you wish to acquire a reference on the memory, you should + * call g_atomic_rc_box_acquire(); similarly, when you wish to release a reference + * you should call g_atomic_rc_box_release(): + * + * |[ + * // Add a Person to the Database; the Database acquires ownership + * // of the Person instance + * void + * add_person_to_database (Database *db, Person *p) + * { + * db->persons = g_list_prepend (db->persons, g_atomic_rc_box_acquire (p)); + * } + * + * // Removes a Person from the Database; the reference acquired by + * // add_person_to_database() is released here + * void + * remove_person_from_database (Database *db, Person *p) + * { + * db->persons = g_list_remove (db->persons, p); + * g_atomic_rc_box_release (p); + * } + * ]| + * + * If you have additional memory allocated inside the structure, you can + * use g_atomic_rc_box_release_full(), which takes a function pointer, which + * will be called if the reference released was the last: + * + * |[ + * void + * person_clear (Person *p) + * { + * g_free (p->name); + * g_free (p->address); + * g_free (p->city); + * g_free (p->state); + * } + * + * void + * remove_person_from_database (Database *db, Person *p) + * { + * db->persons = g_list_remove (db->persons, p); + * g_atomic_rc_box_release_full (p, (GDestroyNotify) person_clear); + * } + * ]| + * + * If you wish to transfer the ownership of a reference counted data + * type without increasing the reference count, you can use g_steal_pointer(): + * + * |[ + * Person *p = g_atomic_rc_box_new (Person); + * + * fill_person_details (p); + * + * add_person_to_database (db, g_steal_pointer (&p)); + * ]| + * + * ## Thread safety + * + * The reference counting operations on data allocated using g_atomic_rc_box_alloc(), + * g_atomic_rc_box_new(), and g_atomic_rc_box_dup() are guaranteed to be atomic, and thus + * can be safely be performed by different threads. It is important to note that + * only the reference acquisition and release are atomic; changes to the content + * of the data are your responsibility. + * + * ## Automatic pointer clean up + * + * If you want to add g_autoptr() support to your plain old data type through + * reference counting, you can use the G_DEFINE_AUTOPTR_CLEANUP_FUNC() and + * g_atomic_rc_box_release(): + * + * |[ + * G_DEFINE_AUTOPTR_CLEANUP_FUNC (MyDataStruct, g_atomic_rc_box_release) + * ]| + * + * If you need to clear the contents of the data, you will need to use an + * ancillary function that calls g_rc_box_release_full(): + * + * |[ + * static void + * my_data_struct_release (MyDataStruct *data) + * { + * // my_data_struct_clear() is defined elsewhere + * g_atomic_rc_box_release_full (data, (GDestroyNotify) my_data_struct_clear); + * } + * + * G_DEFINE_AUTOPTR_CLEANUP_FUNC (MyDataStruct, my_data_struct_release) + * ]| + * + * Since: 2.58 + */ + +/** + * g_atomic_rc_box_alloc: + * @block_size: the size of the allocation, must be greater than 0 + * + * Allocates @block_size bytes of memory, and adds atomic + * reference counting semantics to it. + * + * The data will be freed when its reference count drops to + * zero. + * + * The allocated data is guaranteed to be suitably aligned for any + * built-in type. + * + * Returns: (transfer full) (not nullable): a pointer to the allocated memory + * + * Since: 2.58 + */ +gpointer +g_atomic_rc_box_alloc (gsize block_size) +{ + g_return_val_if_fail (block_size > 0, NULL); + + return g_rc_box_alloc_full (block_size, STRUCT_ALIGNMENT, TRUE, FALSE); +} + +/** + * g_atomic_rc_box_alloc0: + * @block_size: the size of the allocation, must be greater than 0 + * + * Allocates @block_size bytes of memory, and adds atomic + * reference counting semantics to it. + * + * The contents of the returned data is set to zero. + * + * The data will be freed when its reference count drops to + * zero. + * + * The allocated data is guaranteed to be suitably aligned for any + * built-in type. + * + * Returns: (transfer full) (not nullable): a pointer to the allocated memory + * + * Since: 2.58 + */ +gpointer +g_atomic_rc_box_alloc0 (gsize block_size) +{ + g_return_val_if_fail (block_size > 0, NULL); + + return g_rc_box_alloc_full (block_size, STRUCT_ALIGNMENT, TRUE, TRUE); +} + +/** + * g_atomic_rc_box_new: + * @type: the type to allocate, typically a structure name + * + * A convenience macro to allocate atomically reference counted + * data with the size of the given @type. + * + * This macro calls g_atomic_rc_box_alloc() with `sizeof (@type)` and + * casts the returned pointer to a pointer of the given @type, + * avoiding a type cast in the source code. + * + * Returns: (transfer full) (not nullable): a pointer to the allocated + * memory, cast to a pointer for the given @type + * + * Since: 2.58 + */ + +/** + * g_atomic_rc_box_new0: + * @type: the type to allocate, typically a structure name + * + * A convenience macro to allocate atomically reference counted + * data with the size of the given @type, and set its contents + * to zero. + * + * This macro calls g_atomic_rc_box_alloc0() with `sizeof (@type)` and + * casts the returned pointer to a pointer of the given @type, + * avoiding a type cast in the source code. + * + * Returns: (transfer full) (not nullable): a pointer to the allocated + * memory, cast to a pointer for the given @type + * + * Since: 2.58 + */ + +/** + * g_atomic_rc_box_dup: + * @block_size: the number of bytes to copy, must be greater than 0 + * @mem_block: (not nullable): the memory to copy + * + * Allocates a new block of data with atomic reference counting + * semantics, and copies @block_size bytes of @mem_block + * into it. + * + * Returns: (transfer full) (not nullable): a pointer to the allocated + * memory + * + * Since: 2.58 + */ +gpointer +(g_atomic_rc_box_dup) (gsize block_size, + gconstpointer mem_block) +{ + gpointer res; + + g_return_val_if_fail (block_size > 0, NULL); + g_return_val_if_fail (mem_block != NULL, NULL); + + res = g_rc_box_alloc_full (block_size, STRUCT_ALIGNMENT, TRUE, FALSE); + memcpy (res, mem_block, block_size); + + return res; +} + +/** + * g_atomic_rc_box_acquire: + * @mem_block: (not nullable): a pointer to reference counted data + * + * Atomically acquires a reference on the data pointed by @mem_block. + * + * Returns: (transfer full) (not nullable): a pointer to the data, + * with its reference count increased + * + * Since: 2.58 + */ +gpointer +(g_atomic_rc_box_acquire) (gpointer mem_block) +{ + GArcBox *real_box = G_ARC_BOX (mem_block); + + g_return_val_if_fail (mem_block != NULL, NULL); +#ifndef G_DISABLE_ASSERT + g_return_val_if_fail (real_box->magic == G_BOX_MAGIC, NULL); +#endif + + g_atomic_ref_count_inc (&real_box->ref_count); + + TRACE (GLIB_RCBOX_ACQUIRE (mem_block, 1)); + + return mem_block; +} + +/** + * g_atomic_rc_box_release: + * @mem_block: (transfer full) (not nullable): a pointer to reference counted data + * + * Atomically releases a reference on the data pointed by @mem_block. + * + * If the reference was the last one, it will free the + * resources allocated for @mem_block. + * + * Since: 2.58 + */ +void +g_atomic_rc_box_release (gpointer mem_block) +{ + g_atomic_rc_box_release_full (mem_block, NULL); +} + +/** + * g_atomic_rc_box_release_full: + * @mem_block: (transfer full) (not nullable): a pointer to reference counted data + * @clear_func: (not nullable): a function to call when clearing the data + * + * Atomically releases a reference on the data pointed by @mem_block. + * + * If the reference was the last one, it will call @clear_func + * to clear the contents of @mem_block, and then will free the + * resources allocated for @mem_block. + * + * Since: 2.58 + */ +void +g_atomic_rc_box_release_full (gpointer mem_block, + GDestroyNotify clear_func) +{ + GArcBox *real_box = G_ARC_BOX (mem_block); + + g_return_if_fail (mem_block != NULL); +#ifndef G_DISABLE_ASSERT + g_return_if_fail (real_box->magic == G_BOX_MAGIC); +#endif + + if (g_atomic_ref_count_dec (&real_box->ref_count)) + { + char *real_mem = (char *) real_box - real_box->private_offset; + + TRACE (GLIB_RCBOX_RELEASE (mem_block, 1)); + + if (clear_func != NULL) + clear_func (mem_block); + + TRACE (GLIB_RCBOX_FREE (mem_block)); + g_free (real_mem); + } +} + +/** + * g_atomic_rc_box_get_size: + * @mem_block: (not nullable): a pointer to reference counted data + * + * Retrieves the size of the reference counted data pointed by @mem_block. + * + * Returns: the size of the data, in bytes + * + * Since: 2.58 + */ +gsize +g_atomic_rc_box_get_size (gpointer mem_block) +{ + GArcBox *real_box = G_ARC_BOX (mem_block); + + g_return_val_if_fail (mem_block != NULL, 0); +#ifndef G_DISABLE_ASSERT + g_return_val_if_fail (real_box->magic == G_BOX_MAGIC, 0); +#endif + + return real_box->mem_size; +} diff --git a/glib/garray.c b/glib/garray.c new file mode 100644 index 0000000..739141e --- /dev/null +++ b/glib/garray.c @@ -0,0 +1,2576 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include + +#include "garray.h" + +#include "gbytes.h" +#include "ghash.h" +#include "gslice.h" +#include "gmem.h" +#include "gtestutils.h" +#include "gthread.h" +#include "gmessages.h" +#include "gqsort.h" +#include "grefcount.h" +#include "gutilsprivate.h" + +/** + * SECTION:arrays + * @title: Arrays + * @short_description: arrays of arbitrary elements which grow + * automatically as elements are added + * + * Arrays are similar to standard C arrays, except that they grow + * automatically as elements are added. + * + * Array elements can be of any size (though all elements of one array + * are the same size), and the array can be automatically cleared to + * '0's and zero-terminated. + * + * To create a new array use g_array_new(). + * + * To add elements to an array with a cost of O(n) at worst, use + * g_array_append_val(), g_array_append_vals(), g_array_prepend_val(), + * g_array_prepend_vals(), g_array_insert_val() and g_array_insert_vals(). + * + * To access an element of an array in O(1) (to read it or to write it), + * use g_array_index(). + * + * To set the size of an array, use g_array_set_size(). + * + * To free an array, use g_array_unref() or g_array_free(). + * + * All the sort functions are internally calling a quick-sort (or similar) + * function with an average cost of O(n log(n)) and a worst case + * cost of O(n^2). + * + * Here is an example that stores integers in a #GArray: + * |[ + * GArray *garray; + * gint i; + * // We create a new array to store gint values. + * // We don't want it zero-terminated or cleared to 0's. + * garray = g_array_new (FALSE, FALSE, sizeof (gint)); + * for (i = 0; i < 10000; i++) + * g_array_append_val (garray, i); + * for (i = 0; i < 10000; i++) + * if (g_array_index (garray, gint, i) != i) + * g_print ("ERROR: got %d instead of %d\n", + * g_array_index (garray, gint, i), i); + * g_array_free (garray, TRUE); + * ]| + */ + +#define MIN_ARRAY_SIZE 16 + +typedef struct _GRealArray GRealArray; + +/** + * GArray: + * @data: a pointer to the element data. The data may be moved as + * elements are added to the #GArray. + * @len: the number of elements in the #GArray not including the + * possible terminating zero element. + * + * Contains the public fields of a GArray. + */ +struct _GRealArray +{ + guint8 *data; + guint len; + guint elt_capacity; + guint elt_size; + guint zero_terminated : 1; + guint clear : 1; + gatomicrefcount ref_count; + GDestroyNotify clear_func; +}; + +/** + * g_array_index: + * @a: a #GArray + * @t: the type of the elements + * @i: the index of the element to return + * + * Returns the element of a #GArray at the given index. The return + * value is cast to the given type. This is the main way to read or write an + * element in a #GArray. + * + * Writing an element is typically done by reference, as in the following + * example. This example gets a pointer to an element in a #GArray, and then + * writes to a field in it: + * |[ + * EDayViewEvent *event; + * // This gets a pointer to the 4th element in the array of + * // EDayViewEvent structs. + * event = &g_array_index (events, EDayViewEvent, 3); + * event->start_time = g_get_current_time (); + * ]| + * + * This example reads from and writes to an array of integers: + * |[ + * g_autoptr(GArray) int_array = g_array_new (FALSE, FALSE, sizeof (guint)); + * for (guint i = 0; i < 10; i++) + * g_array_append_val (int_array, i); + * + * guint *my_int = &g_array_index (int_array, guint, 1); + * g_print ("Int at index 1 is %u; decrementing it\n", *my_int); + * *my_int = *my_int - 1; + * ]| + * + * Returns: the element of the #GArray at the index given by @i + */ + +#define g_array_elt_len(array,i) ((gsize)(array)->elt_size * (i)) +#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i))) +#define g_array_elt_zero(array, pos, len) \ + (memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len))) +#define g_array_zero_terminate(array) G_STMT_START{ \ + if ((array)->zero_terminated) \ + g_array_elt_zero ((array), (array)->len, 1); \ +}G_STMT_END + +static void g_array_maybe_expand (GRealArray *array, + guint len); + +/** + * g_array_new: + * @zero_terminated: %TRUE if the array should have an extra element at + * the end which is set to 0 + * @clear_: %TRUE if #GArray elements should be automatically cleared + * to 0 when they are allocated + * @element_size: the size of each element in bytes + * + * Creates a new #GArray with a reference count of 1. + * + * Returns: the new #GArray + */ +GArray* +g_array_new (gboolean zero_terminated, + gboolean clear, + guint elt_size) +{ + g_return_val_if_fail (elt_size > 0, NULL); +#if (UINT_WIDTH / 8) >= GLIB_SIZEOF_SIZE_T + g_return_val_if_fail (elt_size <= G_MAXSIZE / 2 - 1, NULL); +#endif + + return g_array_sized_new (zero_terminated, clear, elt_size, 0); +} + +/** + * g_array_steal: + * @array: a #GArray. + * @len: (optional) (out): pointer to retrieve the number of + * elements of the original array + * + * Frees the data in the array and resets the size to zero, while + * the underlying array is preserved for use elsewhere and returned + * to the caller. + * + * If the array was created with the @zero_terminate property + * set to %TRUE, the returned data is zero terminated too. + * + * If array elements contain dynamically-allocated memory, + * the array elements should also be freed by the caller. + * + * A short example of use: + * |[ + * ... + * gpointer data; + * gsize data_len; + * data = g_array_steal (some_array, &data_len); + * ... + * ]| + + * Returns: (transfer full): the element data, which should be + * freed using g_free(). + * + * Since: 2.64 + */ +gpointer +g_array_steal (GArray *array, + gsize *len) +{ + GRealArray *rarray; + gpointer segment; + + g_return_val_if_fail (array != NULL, NULL); + + rarray = (GRealArray *) array; + segment = (gpointer) rarray->data; + + if (len != NULL) + *len = rarray->len; + + rarray->data = NULL; + rarray->len = 0; + rarray->elt_capacity = 0; + return segment; +} + +/** + * g_array_sized_new: + * @zero_terminated: %TRUE if the array should have an extra element at + * the end with all bits cleared + * @clear_: %TRUE if all bits in the array should be cleared to 0 on + * allocation + * @element_size: size of each element in the array + * @reserved_size: number of elements preallocated + * + * Creates a new #GArray with @reserved_size elements preallocated and + * a reference count of 1. This avoids frequent reallocation, if you + * are going to add many elements to the array. Note however that the + * size of the array is still 0. + * + * Returns: the new #GArray + */ +GArray* +g_array_sized_new (gboolean zero_terminated, + gboolean clear, + guint elt_size, + guint reserved_size) +{ + GRealArray *array; + + g_return_val_if_fail (elt_size > 0, NULL); +#if (UINT_WIDTH / 8) >= GLIB_SIZEOF_SIZE_T + g_return_val_if_fail (elt_size <= G_MAXSIZE / 2 - 1, NULL); +#endif + + array = g_slice_new (GRealArray); + + array->data = NULL; + array->len = 0; + array->elt_capacity = 0; + array->zero_terminated = (zero_terminated ? 1 : 0); + array->clear = (clear ? 1 : 0); + array->elt_size = elt_size; + array->clear_func = NULL; + + g_atomic_ref_count_init (&array->ref_count); + + if (array->zero_terminated || reserved_size != 0) + { + g_array_maybe_expand (array, reserved_size); + g_array_zero_terminate(array); + } + + return (GArray*) array; +} + +/** + * g_array_set_clear_func: + * @array: A #GArray + * @clear_func: a function to clear an element of @array + * + * Sets a function to clear an element of @array. + * + * The @clear_func will be called when an element in the array + * data segment is removed and when the array is freed and data + * segment is deallocated as well. @clear_func will be passed a + * pointer to the element to clear, rather than the element itself. + * + * Note that in contrast with other uses of #GDestroyNotify + * functions, @clear_func is expected to clear the contents of + * the array element it is given, but not free the element itself. + * + * |[ + * typedef struct + * { + * gchar *str; + * GObject *obj; + * } ArrayElement; + * + * static void + * array_element_clear (ArrayElement *element) + * { + * g_clear_pointer (&element->str, g_free); + * g_clear_object (&element->obj); + * } + * + * // main code + * GArray *garray = g_array_new (FALSE, FALSE, sizeof (ArrayElement)); + * g_array_set_clear_func (garray, (GDestroyNotify) array_element_clear); + * // assign data to the structure + * g_array_free (garray, TRUE); + * ]| + * + * Since: 2.32 + */ +void +g_array_set_clear_func (GArray *array, + GDestroyNotify clear_func) +{ + GRealArray *rarray = (GRealArray *) array; + + g_return_if_fail (array != NULL); + + rarray->clear_func = clear_func; +} + +/** + * g_array_ref: + * @array: A #GArray + * + * Atomically increments the reference count of @array by one. + * This function is thread-safe and may be called from any thread. + * + * Returns: The passed in #GArray + * + * Since: 2.22 + */ +GArray * +g_array_ref (GArray *array) +{ + GRealArray *rarray = (GRealArray*) array; + g_return_val_if_fail (array, NULL); + + g_atomic_ref_count_inc (&rarray->ref_count); + + return array; +} + +typedef enum +{ + FREE_SEGMENT = 1 << 0, + PRESERVE_WRAPPER = 1 << 1 +} ArrayFreeFlags; + +static gchar *array_free (GRealArray *, ArrayFreeFlags); + +/** + * g_array_unref: + * @array: A #GArray + * + * Atomically decrements the reference count of @array by one. If the + * reference count drops to 0, all memory allocated by the array is + * released. This function is thread-safe and may be called from any + * thread. + * + * Since: 2.22 + */ +void +g_array_unref (GArray *array) +{ + GRealArray *rarray = (GRealArray*) array; + g_return_if_fail (array); + + if (g_atomic_ref_count_dec (&rarray->ref_count)) + array_free (rarray, FREE_SEGMENT); +} + +/** + * g_array_get_element_size: + * @array: A #GArray + * + * Gets the size of the elements in @array. + * + * Returns: Size of each element, in bytes + * + * Since: 2.22 + */ +guint +g_array_get_element_size (GArray *array) +{ + GRealArray *rarray = (GRealArray*) array; + + g_return_val_if_fail (array, 0); + + return rarray->elt_size; +} + +/** + * g_array_free: + * @array: a #GArray + * @free_segment: if %TRUE the actual element data is freed as well + * + * Frees the memory allocated for the #GArray. If @free_segment is + * %TRUE it frees the memory block holding the elements as well. Pass + * %FALSE if you want to free the #GArray wrapper but preserve the + * underlying array for use elsewhere. If the reference count of + * @array is greater than one, the #GArray wrapper is preserved but + * the size of @array will be set to zero. + * + * If array contents point to dynamically-allocated memory, they should + * be freed separately if @free_seg is %TRUE and no @clear_func + * function has been set for @array. + * + * This function is not thread-safe. If using a #GArray from multiple + * threads, use only the atomic g_array_ref() and g_array_unref() + * functions. + * + * Returns: the element data if @free_segment is %FALSE, otherwise + * %NULL. The element data should be freed using g_free(). + */ +gchar* +g_array_free (GArray *farray, + gboolean free_segment) +{ + GRealArray *array = (GRealArray*) farray; + ArrayFreeFlags flags; + + g_return_val_if_fail (array, NULL); + + flags = (free_segment ? FREE_SEGMENT : 0); + + /* if others are holding a reference, preserve the wrapper but do free/return the data */ + if (!g_atomic_ref_count_dec (&array->ref_count)) + flags |= PRESERVE_WRAPPER; + + return array_free (array, flags); +} + +static gchar * +array_free (GRealArray *array, + ArrayFreeFlags flags) +{ + gchar *segment; + + if (flags & FREE_SEGMENT) + { + if (array->clear_func != NULL) + { + guint i; + + for (i = 0; i < array->len; i++) + array->clear_func (g_array_elt_pos (array, i)); + } + + g_free (array->data); + segment = NULL; + } + else + segment = (gchar*) array->data; + + if (flags & PRESERVE_WRAPPER) + { + array->data = NULL; + array->len = 0; + array->elt_capacity = 0; + } + else + { + g_slice_free1 (sizeof (GRealArray), array); + } + + return segment; +} + +/** + * g_array_append_vals: + * @array: a #GArray + * @data: (not nullable): a pointer to the elements to append to the end of the array + * @len: the number of elements to append + * + * Adds @len elements onto the end of the array. + * + * Returns: the #GArray + */ +/** + * g_array_append_val: + * @a: a #GArray + * @v: the value to append to the #GArray + * + * Adds the value on to the end of the array. The array will grow in + * size automatically if necessary. + * + * g_array_append_val() is a macro which uses a reference to the value + * parameter @v. This means that you cannot use it with literal values + * such as "27". You must use variables. + * + * Returns: the #GArray + */ +GArray* +g_array_append_vals (GArray *farray, + gconstpointer data, + guint len) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + if (len == 0) + return farray; + + g_array_maybe_expand (array, len); + + memcpy (g_array_elt_pos (array, array->len), data, + g_array_elt_len (array, len)); + + array->len += len; + + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_prepend_vals: + * @array: a #GArray + * @data: (nullable): a pointer to the elements to prepend to the start of the array + * @len: the number of elements to prepend, which may be zero + * + * Adds @len elements onto the start of the array. + * + * @data may be %NULL if (and only if) @len is zero. If @len is zero, this + * function is a no-op. + * + * This operation is slower than g_array_append_vals() since the + * existing elements in the array have to be moved to make space for + * the new elements. + * + * Returns: the #GArray + */ +/** + * g_array_prepend_val: + * @a: a #GArray + * @v: the value to prepend to the #GArray + * + * Adds the value on to the start of the array. The array will grow in + * size automatically if necessary. + * + * This operation is slower than g_array_append_val() since the + * existing elements in the array have to be moved to make space for + * the new element. + * + * g_array_prepend_val() is a macro which uses a reference to the value + * parameter @v. This means that you cannot use it with literal values + * such as "27". You must use variables. + * + * Returns: the #GArray + */ +GArray* +g_array_prepend_vals (GArray *farray, + gconstpointer data, + guint len) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + if (len == 0) + return farray; + + g_array_maybe_expand (array, len); + + memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0), + g_array_elt_len (array, array->len)); + + memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len)); + + array->len += len; + + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_insert_vals: + * @array: a #GArray + * @index_: the index to place the elements at + * @data: (nullable): a pointer to the elements to insert + * @len: the number of elements to insert + * + * Inserts @len elements into a #GArray at the given index. + * + * If @index_ is greater than the array’s current length, the array is expanded. + * The elements between the old end of the array and the newly inserted elements + * will be initialised to zero if the array was configured to clear elements; + * otherwise their values will be undefined. + * + * If @index_ is less than the array’s current length, new entries will be + * inserted into the array, and the existing entries above @index_ will be moved + * upwards. + * + * @data may be %NULL if (and only if) @len is zero. If @len is zero, this + * function is a no-op. + * + * Returns: the #GArray + */ +/** + * g_array_insert_val: + * @a: a #GArray + * @i: the index to place the element at + * @v: the value to insert into the array + * + * Inserts an element into an array at the given index. + * + * g_array_insert_val() is a macro which uses a reference to the value + * parameter @v. This means that you cannot use it with literal values + * such as "27". You must use variables. + * + * Returns: the #GArray + */ +GArray* +g_array_insert_vals (GArray *farray, + guint index_, + gconstpointer data, + guint len) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + if (len == 0) + return farray; + + /* Is the index off the end of the array, and hence do we need to over-allocate + * and clear some elements? */ + if (index_ >= array->len) + { + g_array_maybe_expand (array, index_ - array->len + len); + return g_array_append_vals (g_array_set_size (farray, index_), data, len); + } + + g_array_maybe_expand (array, len); + + memmove (g_array_elt_pos (array, len + index_), + g_array_elt_pos (array, index_), + g_array_elt_len (array, array->len - index_)); + + memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len)); + + array->len += len; + + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_set_size: + * @array: a #GArray + * @length: the new size of the #GArray + * + * Sets the size of the array, expanding it if necessary. If the array + * was created with @clear_ set to %TRUE, the new elements are set to 0. + * + * Returns: the #GArray + */ +GArray* +g_array_set_size (GArray *farray, + guint length) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + if (length > array->len) + { + g_array_maybe_expand (array, length - array->len); + + if (array->clear) + g_array_elt_zero (array, array->len, length - array->len); + } + else if (length < array->len) + g_array_remove_range (farray, length, array->len - length); + + array->len = length; + + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_remove_index: + * @array: a #GArray + * @index_: the index of the element to remove + * + * Removes the element at the given index from a #GArray. The following + * elements are moved down one place. + * + * Returns: the #GArray + */ +GArray* +g_array_remove_index (GArray *farray, + guint index_) +{ + GRealArray* array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + g_return_val_if_fail (index_ < array->len, NULL); + + if (array->clear_func != NULL) + array->clear_func (g_array_elt_pos (array, index_)); + + if (index_ != array->len - 1) + memmove (g_array_elt_pos (array, index_), + g_array_elt_pos (array, index_ + 1), + g_array_elt_len (array, array->len - index_ - 1)); + + array->len -= 1; + + if (G_UNLIKELY (g_mem_gc_friendly)) + g_array_elt_zero (array, array->len, 1); + else + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_remove_index_fast: + * @array: a @GArray + * @index_: the index of the element to remove + * + * Removes the element at the given index from a #GArray. The last + * element in the array is used to fill in the space, so this function + * does not preserve the order of the #GArray. But it is faster than + * g_array_remove_index(). + * + * Returns: the #GArray + */ +GArray* +g_array_remove_index_fast (GArray *farray, + guint index_) +{ + GRealArray* array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + g_return_val_if_fail (index_ < array->len, NULL); + + if (array->clear_func != NULL) + array->clear_func (g_array_elt_pos (array, index_)); + + if (index_ != array->len - 1) + memcpy (g_array_elt_pos (array, index_), + g_array_elt_pos (array, array->len - 1), + g_array_elt_len (array, 1)); + + array->len -= 1; + + if (G_UNLIKELY (g_mem_gc_friendly)) + g_array_elt_zero (array, array->len, 1); + else + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_remove_range: + * @array: a @GArray + * @index_: the index of the first element to remove + * @length: the number of elements to remove + * + * Removes the given number of elements starting at the given index + * from a #GArray. The following elements are moved to close the gap. + * + * Returns: the #GArray + * + * Since: 2.4 + */ +GArray* +g_array_remove_range (GArray *farray, + guint index_, + guint length) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + g_return_val_if_fail (index_ <= array->len, NULL); + g_return_val_if_fail (index_ + length <= array->len, NULL); + + if (array->clear_func != NULL) + { + guint i; + + for (i = 0; i < length; i++) + array->clear_func (g_array_elt_pos (array, index_ + i)); + } + + if (index_ + length != array->len) + memmove (g_array_elt_pos (array, index_), + g_array_elt_pos (array, index_ + length), + (array->len - (index_ + length)) * array->elt_size); + + array->len -= length; + if (G_UNLIKELY (g_mem_gc_friendly)) + g_array_elt_zero (array, array->len, length); + else + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_sort: + * @array: a #GArray + * @compare_func: comparison function + * + * Sorts a #GArray using @compare_func which should be a qsort()-style + * comparison function (returns less than zero for first arg is less + * than second arg, zero for equal, greater zero if first arg is + * greater than second arg). + * + * This is guaranteed to be a stable sort since version 2.32. + */ +void +g_array_sort (GArray *farray, + GCompareFunc compare_func) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_if_fail (array != NULL); + + /* Don't use qsort as we want a guaranteed stable sort */ + if (array->len > 0) + g_qsort_with_data (array->data, + array->len, + array->elt_size, + (GCompareDataFunc)compare_func, + NULL); +} + +/** + * g_array_sort_with_data: + * @array: a #GArray + * @compare_func: comparison function + * @user_data: data to pass to @compare_func + * + * Like g_array_sort(), but the comparison function receives an extra + * user data argument. + * + * This is guaranteed to be a stable sort since version 2.32. + * + * There used to be a comment here about making the sort stable by + * using the addresses of the elements in the comparison function. + * This did not actually work, so any such code should be removed. + */ +void +g_array_sort_with_data (GArray *farray, + GCompareDataFunc compare_func, + gpointer user_data) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_if_fail (array != NULL); + + if (array->len > 0) + g_qsort_with_data (array->data, + array->len, + array->elt_size, + compare_func, + user_data); +} + +/** + * g_array_binary_search: + * @array: a #GArray. + * @target: a pointer to the item to look up. + * @compare_func: A #GCompareFunc used to locate @target. + * @out_match_index: (optional) (out): return location + * for the index of the element, if found. + * + * Checks whether @target exists in @array by performing a binary + * search based on the given comparison function @compare_func which + * get pointers to items as arguments. If the element is found, %TRUE + * is returned and the element’s index is returned in @out_match_index + * (if non-%NULL). Otherwise, %FALSE is returned and @out_match_index + * is undefined. If @target exists multiple times in @array, the index + * of the first instance is returned. This search is using a binary + * search, so the @array must absolutely be sorted to return a correct + * result (if not, the function may produce false-negative). + * + * This example defines a comparison function and search an element in a #GArray: + * |[ + * static gint* + * cmpint (gconstpointer a, gconstpointer b) + * { + * const gint *_a = a; + * const gint *_b = b; + * + * return *_a - *_b; + * } + * ... + * gint i = 424242; + * guint matched_index; + * gboolean result = g_array_binary_search (garray, &i, cmpint, &matched_index); + * ... + * ]| + * + * Returns: %TRUE if @target is one of the elements of @array, %FALSE otherwise. + * + * Since: 2.62 + */ +gboolean +g_array_binary_search (GArray *array, + gconstpointer target, + GCompareFunc compare_func, + guint *out_match_index) +{ + gboolean result = FALSE; + GRealArray *_array = (GRealArray *) array; + guint left, middle = 0, right; + gint val; + + g_return_val_if_fail (_array != NULL, FALSE); + g_return_val_if_fail (compare_func != NULL, FALSE); + + if (G_LIKELY(_array->len)) + { + left = 0; + right = _array->len - 1; + + while (left <= right) + { + middle = left + (right - left) / 2; + + val = compare_func (_array->data + (_array->elt_size * middle), target); + if (val == 0) + { + result = TRUE; + break; + } + else if (val < 0) + left = middle + 1; + else if (/* val > 0 && */ middle > 0) + right = middle - 1; + else + break; /* element not found */ + } + } + + if (result && out_match_index != NULL) + *out_match_index = middle; + + return result; +} + +static void +g_array_maybe_expand (GRealArray *array, + guint len) +{ + guint max_len, want_len; + + /* The maximum array length is derived from following constraints: + * - The number of bytes must fit into a gsize / 2. + * - The number of elements must fit into guint. + * - zero terminated arrays must leave space for the terminating element + */ + max_len = MIN (G_MAXSIZE / 2 / array->elt_size, G_MAXUINT) - array->zero_terminated; + + /* Detect potential overflow */ + if G_UNLIKELY ((max_len - array->len) < len) + g_error ("adding %u to array would overflow", len); + + want_len = array->len + len + array->zero_terminated; + if (want_len > array->elt_capacity) + { + gsize want_alloc = g_nearest_pow (g_array_elt_len (array, want_len)); + want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE); + + array->data = g_realloc (array->data, want_alloc); + + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (g_array_elt_pos (array, array->elt_capacity), 0, + g_array_elt_len (array, want_len - array->elt_capacity)); + + array->elt_capacity = MIN (want_alloc / array->elt_size, G_MAXUINT); + } +} + +/** + * SECTION:arrays_pointer + * @title: Pointer Arrays + * @short_description: arrays of pointers to any type of data, which + * grow automatically as new elements are added + * + * Pointer Arrays are similar to Arrays but are used only for storing + * pointers. + * + * If you remove elements from the array, elements at the end of the + * array are moved into the space previously occupied by the removed + * element. This means that you should not rely on the index of particular + * elements remaining the same. You should also be careful when deleting + * elements while iterating over the array. + * + * To create a pointer array, use g_ptr_array_new(). + * + * To add elements to a pointer array, use g_ptr_array_add(). + * + * To remove elements from a pointer array, use g_ptr_array_remove(), + * g_ptr_array_remove_index() or g_ptr_array_remove_index_fast(). + * + * To access an element of a pointer array, use g_ptr_array_index(). + * + * To set the size of a pointer array, use g_ptr_array_set_size(). + * + * To free a pointer array, use g_ptr_array_free(). + * + * An example using a #GPtrArray: + * |[ + * GPtrArray *array; + * gchar *string1 = "one"; + * gchar *string2 = "two"; + * gchar *string3 = "three"; + * + * array = g_ptr_array_new (); + * g_ptr_array_add (array, (gpointer) string1); + * g_ptr_array_add (array, (gpointer) string2); + * g_ptr_array_add (array, (gpointer) string3); + * + * if (g_ptr_array_index (array, 0) != (gpointer) string1) + * g_print ("ERROR: got %p instead of %p\n", + * g_ptr_array_index (array, 0), string1); + * + * g_ptr_array_free (array, TRUE); + * ]| + */ + +typedef struct _GRealPtrArray GRealPtrArray; + +/** + * GPtrArray: + * @pdata: points to the array of pointers, which may be moved when the + * array grows + * @len: number of pointers in the array + * + * Contains the public fields of a pointer array. + */ +struct _GRealPtrArray +{ + gpointer *pdata; + guint len; + guint alloc; + gatomicrefcount ref_count; + GDestroyNotify element_free_func; +}; + +/** + * g_ptr_array_index: + * @array: a #GPtrArray + * @index_: the index of the pointer to return + * + * Returns the pointer at the given index of the pointer array. + * + * This does not perform bounds checking on the given @index_, + * so you are responsible for checking it against the array length. + * + * Returns: the pointer at the given index + */ + +static void g_ptr_array_maybe_expand (GRealPtrArray *array, + guint len); + +static GPtrArray * +ptr_array_new (guint reserved_size, + GDestroyNotify element_free_func) +{ + GRealPtrArray *array; + + array = g_slice_new (GRealPtrArray); + + array->pdata = NULL; + array->len = 0; + array->alloc = 0; + array->element_free_func = element_free_func; + + g_atomic_ref_count_init (&array->ref_count); + + if (reserved_size != 0) + g_ptr_array_maybe_expand (array, reserved_size); + + return (GPtrArray *) array; +} + +/** + * g_ptr_array_new: + * + * Creates a new #GPtrArray with a reference count of 1. + * + * Returns: the new #GPtrArray + */ +GPtrArray* +g_ptr_array_new (void) +{ + return ptr_array_new (0, NULL); +} + +/** + * g_ptr_array_steal: + * @array: a #GPtrArray. + * @len: (optional) (out): pointer to retrieve the number of + * elements of the original array + * + * Frees the data in the array and resets the size to zero, while + * the underlying array is preserved for use elsewhere and returned + * to the caller. + * + * Even if set, the #GDestroyNotify function will never be called + * on the current contents of the array and the caller is + * responsible for freeing the array elements. + * + * An example of use: + * |[ + * g_autoptr(GPtrArray) chunk_buffer = g_ptr_array_new_with_free_func (g_bytes_unref); + * + * // Some part of your application appends a number of chunks to the pointer array. + * g_ptr_array_add (chunk_buffer, g_bytes_new_static ("hello", 5)); + * g_ptr_array_add (chunk_buffer, g_bytes_new_static ("world", 5)); + * + * … + * + * // Periodically, the chunks need to be sent as an array-and-length to some + * // other part of the program. + * GBytes **chunks; + * gsize n_chunks; + * + * chunks = g_ptr_array_steal (chunk_buffer, &n_chunks); + * for (gsize i = 0; i < n_chunks; i++) + * { + * // Do something with each chunk here, and then free them, since + * // g_ptr_array_steal() transfers ownership of all the elements and the + * // array to the caller. + * … + * + * g_bytes_unref (chunks[i]); + * } + * + * g_free (chunks); + * + * // After calling g_ptr_array_steal(), the pointer array can be reused for the + * // next set of chunks. + * g_assert (chunk_buffer->len == 0); + * ]| + * + * Returns: (transfer full) (nullable): the element data, which should be + * freed using g_free(). This may be %NULL if the array doesn’t have any + * elements (i.e. if `*len` is zero). + * + * Since: 2.64 + */ +gpointer * +g_ptr_array_steal (GPtrArray *array, + gsize *len) +{ + GRealPtrArray *rarray; + gpointer *segment; + + g_return_val_if_fail (array != NULL, NULL); + + rarray = (GRealPtrArray *) array; + segment = (gpointer *) rarray->pdata; + + if (len != NULL) + *len = rarray->len; + + rarray->pdata = NULL; + rarray->len = 0; + rarray->alloc = 0; + return segment; +} + +/** + * g_ptr_array_copy: + * @array: #GPtrArray to duplicate + * @func: (nullable): a copy function used to copy every element in the array + * @user_data: user data passed to the copy function @func, or %NULL + * + * Makes a full (deep) copy of a #GPtrArray. + * + * @func, as a #GCopyFunc, takes two arguments, the data to be copied + * and a @user_data pointer. On common processor architectures, it's safe to + * pass %NULL as @user_data if the copy function takes only one argument. You + * may get compiler warnings from this though if compiling with GCC’s + * `-Wcast-function-type` warning. + * + * If @func is %NULL, then only the pointers (and not what they are + * pointing to) are copied to the new #GPtrArray. + * + * The copy of @array will have the same #GDestroyNotify for its elements as + * @array. + * + * Returns: (transfer full): a deep copy of the initial #GPtrArray. + * + * Since: 2.62 + **/ +GPtrArray * +g_ptr_array_copy (GPtrArray *array, + GCopyFunc func, + gpointer user_data) +{ + GPtrArray *new_array; + + g_return_val_if_fail (array != NULL, NULL); + + new_array = ptr_array_new (array->len, + ((GRealPtrArray *) array)->element_free_func); + + if (func != NULL) + { + guint i; + + for (i = 0; i < array->len; i++) + new_array->pdata[i] = func (array->pdata[i], user_data); + } + else if (array->len > 0) + { + memcpy (new_array->pdata, array->pdata, + array->len * sizeof (*array->pdata)); + } + + new_array->len = array->len; + + return new_array; +} + +/** + * g_ptr_array_sized_new: + * @reserved_size: number of pointers preallocated + * + * Creates a new #GPtrArray with @reserved_size pointers preallocated + * and a reference count of 1. This avoids frequent reallocation, if + * you are going to add many pointers to the array. Note however that + * the size of the array is still 0. + * + * Returns: the new #GPtrArray + */ +GPtrArray* +g_ptr_array_sized_new (guint reserved_size) +{ + return ptr_array_new (reserved_size, NULL); +} + +/** + * g_array_copy: + * @array: A #GArray. + * + * Create a shallow copy of a #GArray. If the array elements consist of + * pointers to data, the pointers are copied but the actual data is not. + * + * Returns: (transfer container): A copy of @array. + * + * Since: 2.62 + **/ +GArray * +g_array_copy (GArray *array) +{ + GRealArray *rarray = (GRealArray *) array; + GRealArray *new_rarray; + + g_return_val_if_fail (rarray != NULL, NULL); + + new_rarray = + (GRealArray *) g_array_sized_new (rarray->zero_terminated, rarray->clear, + rarray->elt_size, rarray->elt_capacity); + new_rarray->len = rarray->len; + if (rarray->len > 0) + memcpy (new_rarray->data, rarray->data, rarray->len * rarray->elt_size); + + g_array_zero_terminate (new_rarray); + + return (GArray *) new_rarray; +} + +/** + * g_ptr_array_new_with_free_func: + * @element_free_func: (nullable): A function to free elements with + * destroy @array or %NULL + * + * Creates a new #GPtrArray with a reference count of 1 and use + * @element_free_func for freeing each element when the array is destroyed + * either via g_ptr_array_unref(), when g_ptr_array_free() is called with + * @free_segment set to %TRUE or when removing elements. + * + * Returns: (transfer full): A new #GPtrArray + * + * Since: 2.22 + */ +GPtrArray* +g_ptr_array_new_with_free_func (GDestroyNotify element_free_func) +{ + return ptr_array_new (0, element_free_func); +} + +/** + * g_ptr_array_new_full: + * @reserved_size: number of pointers preallocated + * @element_free_func: (nullable): A function to free elements with + * destroy @array or %NULL + * + * Creates a new #GPtrArray with @reserved_size pointers preallocated + * and a reference count of 1. This avoids frequent reallocation, if + * you are going to add many pointers to the array. Note however that + * the size of the array is still 0. It also set @element_free_func + * for freeing each element when the array is destroyed either via + * g_ptr_array_unref(), when g_ptr_array_free() is called with + * @free_segment set to %TRUE or when removing elements. + * + * Returns: (transfer full): A new #GPtrArray + * + * Since: 2.30 + */ +GPtrArray* +g_ptr_array_new_full (guint reserved_size, + GDestroyNotify element_free_func) +{ + return ptr_array_new (reserved_size, element_free_func); +} + +/** + * g_ptr_array_set_free_func: + * @array: A #GPtrArray + * @element_free_func: (nullable): A function to free elements with + * destroy @array or %NULL + * + * Sets a function for freeing each element when @array is destroyed + * either via g_ptr_array_unref(), when g_ptr_array_free() is called + * with @free_segment set to %TRUE or when removing elements. + * + * Since: 2.22 + */ +void +g_ptr_array_set_free_func (GPtrArray *array, + GDestroyNotify element_free_func) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + + g_return_if_fail (array); + + rarray->element_free_func = element_free_func; +} + +/** + * g_ptr_array_ref: + * @array: a #GPtrArray + * + * Atomically increments the reference count of @array by one. + * This function is thread-safe and may be called from any thread. + * + * Returns: The passed in #GPtrArray + * + * Since: 2.22 + */ +GPtrArray* +g_ptr_array_ref (GPtrArray *array) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + + g_return_val_if_fail (array, NULL); + + g_atomic_ref_count_inc (&rarray->ref_count); + + return array; +} + +static gpointer *ptr_array_free (GPtrArray *, ArrayFreeFlags); + +/** + * g_ptr_array_unref: + * @array: A #GPtrArray + * + * Atomically decrements the reference count of @array by one. If the + * reference count drops to 0, the effect is the same as calling + * g_ptr_array_free() with @free_segment set to %TRUE. This function + * is thread-safe and may be called from any thread. + * + * Since: 2.22 + */ +void +g_ptr_array_unref (GPtrArray *array) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + + g_return_if_fail (array); + + if (g_atomic_ref_count_dec (&rarray->ref_count)) + ptr_array_free (array, FREE_SEGMENT); +} + +/** + * g_ptr_array_free: + * @array: a #GPtrArray + * @free_seg: if %TRUE the actual pointer array is freed as well + * + * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE + * it frees the memory block holding the elements as well. Pass %FALSE + * if you want to free the #GPtrArray wrapper but preserve the + * underlying array for use elsewhere. If the reference count of @array + * is greater than one, the #GPtrArray wrapper is preserved but the + * size of @array will be set to zero. + * + * If array contents point to dynamically-allocated memory, they should + * be freed separately if @free_seg is %TRUE and no #GDestroyNotify + * function has been set for @array. + * + * This function is not thread-safe. If using a #GPtrArray from multiple + * threads, use only the atomic g_ptr_array_ref() and g_ptr_array_unref() + * functions. + * + * Returns: (transfer full) (nullable): the pointer array if @free_seg is + * %FALSE, otherwise %NULL. The pointer array should be freed using g_free(). + */ +gpointer* +g_ptr_array_free (GPtrArray *array, + gboolean free_segment) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + ArrayFreeFlags flags; + + g_return_val_if_fail (rarray, NULL); + + flags = (free_segment ? FREE_SEGMENT : 0); + + /* if others are holding a reference, preserve the wrapper but + * do free/return the data + */ + if (!g_atomic_ref_count_dec (&rarray->ref_count)) + flags |= PRESERVE_WRAPPER; + + return ptr_array_free (array, flags); +} + +static gpointer * +ptr_array_free (GPtrArray *array, + ArrayFreeFlags flags) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + gpointer *segment; + + if (flags & FREE_SEGMENT) + { + /* Data here is stolen and freed manually. It is an + * error to attempt to access the array data (including + * mutating the array bounds) during destruction). + * + * https://bugzilla.gnome.org/show_bug.cgi?id=769064 + */ + gpointer *stolen_pdata = g_steal_pointer (&rarray->pdata); + if (rarray->element_free_func != NULL) + { + guint i; + + for (i = 0; i < rarray->len; ++i) + rarray->element_free_func (stolen_pdata[i]); + } + + g_free (stolen_pdata); + segment = NULL; + } + else + segment = rarray->pdata; + + if (flags & PRESERVE_WRAPPER) + { + rarray->pdata = NULL; + rarray->len = 0; + rarray->alloc = 0; + } + else + { + g_slice_free1 (sizeof (GRealPtrArray), rarray); + } + + return segment; +} + +static void +g_ptr_array_maybe_expand (GRealPtrArray *array, + guint len) +{ + guint max_len; + + /* The maximum array length is derived from following constraints: + * - The number of bytes must fit into a gsize / 2. + * - The number of elements must fit into guint. + */ + max_len = MIN (G_MAXSIZE / 2 / sizeof (gpointer), G_MAXUINT); + + /* Detect potential overflow */ + if G_UNLIKELY ((max_len - array->len) < len) + g_error ("adding %u to array would overflow", len); + + if ((array->len + len) > array->alloc) + { + guint old_alloc = array->alloc; + gsize want_alloc = g_nearest_pow (sizeof (gpointer) * (array->len + len)); + want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE); + array->alloc = MIN (want_alloc / sizeof (gpointer), G_MAXUINT); + array->pdata = g_realloc (array->pdata, want_alloc); + if (G_UNLIKELY (g_mem_gc_friendly)) + for ( ; old_alloc < array->alloc; old_alloc++) + array->pdata [old_alloc] = NULL; + } +} + +/** + * g_ptr_array_set_size: + * @array: a #GPtrArray + * @length: the new length of the pointer array + * + * Sets the size of the array. When making the array larger, + * newly-added elements will be set to %NULL. When making it smaller, + * if @array has a non-%NULL #GDestroyNotify function then it will be + * called for the removed elements. + */ +void +g_ptr_array_set_size (GPtrArray *array, + gint length) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + guint length_unsigned; + + g_return_if_fail (rarray); + g_return_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL)); + g_return_if_fail (length >= 0); + + length_unsigned = (guint) length; + + if (length_unsigned > rarray->len) + { + guint i; + g_ptr_array_maybe_expand (rarray, (length_unsigned - rarray->len)); + /* This is not + * memset (array->pdata + array->len, 0, + * sizeof (gpointer) * (length_unsigned - array->len)); + * to make it really portable. Remember (void*)NULL needn't be + * bitwise zero. It of course is silly not to use memset (..,0,..). + */ + for (i = rarray->len; i < length_unsigned; i++) + rarray->pdata[i] = NULL; + } + else if (length_unsigned < rarray->len) + g_ptr_array_remove_range (array, length_unsigned, rarray->len - length_unsigned); + + rarray->len = length_unsigned; +} + +static gpointer +ptr_array_remove_index (GPtrArray *array, + guint index_, + gboolean fast, + gboolean free_element) +{ + GRealPtrArray *rarray = (GRealPtrArray *) array; + gpointer result; + + g_return_val_if_fail (rarray, NULL); + g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), NULL); + + g_return_val_if_fail (index_ < rarray->len, NULL); + + result = rarray->pdata[index_]; + + if (rarray->element_free_func != NULL && free_element) + rarray->element_free_func (rarray->pdata[index_]); + + if (index_ != rarray->len - 1 && !fast) + memmove (rarray->pdata + index_, rarray->pdata + index_ + 1, + sizeof (gpointer) * (rarray->len - index_ - 1)); + else if (index_ != rarray->len - 1) + rarray->pdata[index_] = rarray->pdata[rarray->len - 1]; + + rarray->len -= 1; + + if (G_UNLIKELY (g_mem_gc_friendly)) + rarray->pdata[rarray->len] = NULL; + + return result; +} + +/** + * g_ptr_array_remove_index: + * @array: a #GPtrArray + * @index_: the index of the pointer to remove + * + * Removes the pointer at the given index from the pointer array. + * The following elements are moved down one place. If @array has + * a non-%NULL #GDestroyNotify function it is called for the removed + * element. If so, the return value from this function will potentially point + * to freed memory (depending on the #GDestroyNotify implementation). + * + * Returns: (nullable): the pointer which was removed + */ +gpointer +g_ptr_array_remove_index (GPtrArray *array, + guint index_) +{ + return ptr_array_remove_index (array, index_, FALSE, TRUE); +} + +/** + * g_ptr_array_remove_index_fast: + * @array: a #GPtrArray + * @index_: the index of the pointer to remove + * + * Removes the pointer at the given index from the pointer array. + * The last element in the array is used to fill in the space, so + * this function does not preserve the order of the array. But it + * is faster than g_ptr_array_remove_index(). If @array has a non-%NULL + * #GDestroyNotify function it is called for the removed element. If so, the + * return value from this function will potentially point to freed memory + * (depending on the #GDestroyNotify implementation). + * + * Returns: (nullable): the pointer which was removed + */ +gpointer +g_ptr_array_remove_index_fast (GPtrArray *array, + guint index_) +{ + return ptr_array_remove_index (array, index_, TRUE, TRUE); +} + +/** + * g_ptr_array_steal_index: + * @array: a #GPtrArray + * @index_: the index of the pointer to steal + * + * Removes the pointer at the given index from the pointer array. + * The following elements are moved down one place. The #GDestroyNotify for + * @array is *not* called on the removed element; ownership is transferred to + * the caller of this function. + * + * Returns: (transfer full) (nullable): the pointer which was removed + * Since: 2.58 + */ +gpointer +g_ptr_array_steal_index (GPtrArray *array, + guint index_) +{ + return ptr_array_remove_index (array, index_, FALSE, FALSE); +} + +/** + * g_ptr_array_steal_index_fast: + * @array: a #GPtrArray + * @index_: the index of the pointer to steal + * + * Removes the pointer at the given index from the pointer array. + * The last element in the array is used to fill in the space, so + * this function does not preserve the order of the array. But it + * is faster than g_ptr_array_steal_index(). The #GDestroyNotify for @array is + * *not* called on the removed element; ownership is transferred to the caller + * of this function. + * + * Returns: (transfer full) (nullable): the pointer which was removed + * Since: 2.58 + */ +gpointer +g_ptr_array_steal_index_fast (GPtrArray *array, + guint index_) +{ + return ptr_array_remove_index (array, index_, TRUE, FALSE); +} + +/** + * g_ptr_array_remove_range: + * @array: a @GPtrArray + * @index_: the index of the first pointer to remove + * @length: the number of pointers to remove + * + * Removes the given number of pointers starting at the given index + * from a #GPtrArray. The following elements are moved to close the + * gap. If @array has a non-%NULL #GDestroyNotify function it is + * called for the removed elements. + * + * Returns: the @array + * + * Since: 2.4 + */ +GPtrArray* +g_ptr_array_remove_range (GPtrArray *array, + guint index_, + guint length) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + guint i; + + g_return_val_if_fail (rarray != NULL, NULL); + g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), NULL); + g_return_val_if_fail (index_ <= rarray->len, NULL); + g_return_val_if_fail (index_ + length <= rarray->len, NULL); + + if (rarray->element_free_func != NULL) + { + for (i = index_; i < index_ + length; i++) + rarray->element_free_func (rarray->pdata[i]); + } + + if (index_ + length != rarray->len) + { + memmove (&rarray->pdata[index_], + &rarray->pdata[index_ + length], + (rarray->len - (index_ + length)) * sizeof (gpointer)); + } + + rarray->len -= length; + if (G_UNLIKELY (g_mem_gc_friendly)) + { + for (i = 0; i < length; i++) + rarray->pdata[rarray->len + i] = NULL; + } + + return array; +} + +/** + * g_ptr_array_remove: + * @array: a #GPtrArray + * @data: the pointer to remove + * + * Removes the first occurrence of the given pointer from the pointer + * array. The following elements are moved down one place. If @array + * has a non-%NULL #GDestroyNotify function it is called for the + * removed element. + * + * It returns %TRUE if the pointer was removed, or %FALSE if the + * pointer was not found. + * + * Returns: %TRUE if the pointer is removed, %FALSE if the pointer + * is not found in the array + */ +gboolean +g_ptr_array_remove (GPtrArray *array, + gpointer data) +{ + guint i; + + g_return_val_if_fail (array, FALSE); + g_return_val_if_fail (array->len == 0 || (array->len != 0 && array->pdata != NULL), FALSE); + + for (i = 0; i < array->len; i += 1) + { + if (array->pdata[i] == data) + { + g_ptr_array_remove_index (array, i); + return TRUE; + } + } + + return FALSE; +} + +/** + * g_ptr_array_remove_fast: + * @array: a #GPtrArray + * @data: the pointer to remove + * + * Removes the first occurrence of the given pointer from the pointer + * array. The last element in the array is used to fill in the space, + * so this function does not preserve the order of the array. But it + * is faster than g_ptr_array_remove(). If @array has a non-%NULL + * #GDestroyNotify function it is called for the removed element. + * + * It returns %TRUE if the pointer was removed, or %FALSE if the + * pointer was not found. + * + * Returns: %TRUE if the pointer was found in the array + */ +gboolean +g_ptr_array_remove_fast (GPtrArray *array, + gpointer data) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + guint i; + + g_return_val_if_fail (rarray, FALSE); + g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), FALSE); + + for (i = 0; i < rarray->len; i += 1) + { + if (rarray->pdata[i] == data) + { + g_ptr_array_remove_index_fast (array, i); + return TRUE; + } + } + + return FALSE; +} + +/** + * g_ptr_array_add: + * @array: a #GPtrArray + * @data: the pointer to add + * + * Adds a pointer to the end of the pointer array. The array will grow + * in size automatically if necessary. + */ +void +g_ptr_array_add (GPtrArray *array, + gpointer data) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + + g_return_if_fail (rarray); + g_return_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL)); + + g_ptr_array_maybe_expand (rarray, 1); + + rarray->pdata[rarray->len++] = data; +} + +/** + * g_ptr_array_extend: + * @array_to_extend: a #GPtrArray. + * @array: (transfer none): a #GPtrArray to add to the end of @array_to_extend. + * @func: (nullable): a copy function used to copy every element in the array + * @user_data: user data passed to the copy function @func, or %NULL + * + * Adds all pointers of @array to the end of the array @array_to_extend. + * The array will grow in size automatically if needed. @array_to_extend is + * modified in-place. + * + * @func, as a #GCopyFunc, takes two arguments, the data to be copied + * and a @user_data pointer. On common processor architectures, it's safe to + * pass %NULL as @user_data if the copy function takes only one argument. You + * may get compiler warnings from this though if compiling with GCC’s + * `-Wcast-function-type` warning. + * + * If @func is %NULL, then only the pointers (and not what they are + * pointing to) are copied to the new #GPtrArray. + * + * Since: 2.62 + **/ +void +g_ptr_array_extend (GPtrArray *array_to_extend, + GPtrArray *array, + GCopyFunc func, + gpointer user_data) +{ + GRealPtrArray *rarray_to_extend = (GRealPtrArray *) array_to_extend; + + g_return_if_fail (array_to_extend != NULL); + g_return_if_fail (array != NULL); + + g_ptr_array_maybe_expand (rarray_to_extend, array->len); + + if (func != NULL) + { + guint i; + + for (i = 0; i < array->len; i++) + rarray_to_extend->pdata[i + rarray_to_extend->len] = + func (array->pdata[i], user_data); + } + else if (array->len > 0) + { + memcpy (rarray_to_extend->pdata + rarray_to_extend->len, array->pdata, + array->len * sizeof (*array->pdata)); + } + + rarray_to_extend->len += array->len; +} + +/** + * g_ptr_array_extend_and_steal: + * @array_to_extend: (transfer none): a #GPtrArray. + * @array: (transfer container): a #GPtrArray to add to the end of + * @array_to_extend. + * + * Adds all the pointers in @array to the end of @array_to_extend, transferring + * ownership of each element from @array to @array_to_extend and modifying + * @array_to_extend in-place. @array is then freed. + * + * As with g_ptr_array_free(), @array will be destroyed if its reference count + * is 1. If its reference count is higher, it will be decremented and the + * length of @array set to zero. + * + * Since: 2.62 + **/ +void +g_ptr_array_extend_and_steal (GPtrArray *array_to_extend, + GPtrArray *array) +{ + gpointer *pdata; + + g_ptr_array_extend (array_to_extend, array, NULL, NULL); + + /* Get rid of @array without triggering the GDestroyNotify attached + * to the elements moved from @array to @array_to_extend. */ + pdata = g_steal_pointer (&array->pdata); + array->len = 0; + ((GRealPtrArray *) array)->alloc = 0; + g_ptr_array_unref (array); + g_free (pdata); +} + +/** + * g_ptr_array_insert: + * @array: a #GPtrArray + * @index_: the index to place the new element at, or -1 to append + * @data: the pointer to add. + * + * Inserts an element into the pointer array at the given index. The + * array will grow in size automatically if necessary. + * + * Since: 2.40 + */ +void +g_ptr_array_insert (GPtrArray *array, + gint index_, + gpointer data) +{ + GRealPtrArray *rarray = (GRealPtrArray *)array; + + g_return_if_fail (rarray); + g_return_if_fail (index_ >= -1); + g_return_if_fail (index_ <= (gint)rarray->len); + + g_ptr_array_maybe_expand (rarray, 1); + + if (index_ < 0) + index_ = rarray->len; + + if ((guint) index_ < rarray->len) + memmove (&(rarray->pdata[index_ + 1]), + &(rarray->pdata[index_]), + (rarray->len - index_) * sizeof (gpointer)); + + rarray->len++; + rarray->pdata[index_] = data; +} + +/* Please keep this doc-comment in sync with pointer_array_sort_example() + * in glib/tests/array-test.c */ +/** + * g_ptr_array_sort: + * @array: a #GPtrArray + * @compare_func: comparison function + * + * Sorts the array, using @compare_func which should be a qsort()-style + * comparison function (returns less than zero for first arg is less + * than second arg, zero for equal, greater than zero if irst arg is + * greater than second arg). + * + * Note that the comparison function for g_ptr_array_sort() doesn't + * take the pointers from the array as arguments, it takes pointers to + * the pointers in the array. Here is a full example of usage: + * + * |[ + * typedef struct + * { + * gchar *name; + * gint size; + * } FileListEntry; + * + * static gint + * sort_filelist (gconstpointer a, gconstpointer b) + * { + * const FileListEntry *entry1 = *((FileListEntry **) a); + * const FileListEntry *entry2 = *((FileListEntry **) b); + * + * return g_ascii_strcasecmp (entry1->name, entry2->name); + * } + * + * … + * g_autoptr (GPtrArray) file_list = NULL; + * + * // initialize file_list array and load with many FileListEntry entries + * ... + * // now sort it with + * g_ptr_array_sort (file_list, sort_filelist); + * ]| + * + * This is guaranteed to be a stable sort since version 2.32. + */ +void +g_ptr_array_sort (GPtrArray *array, + GCompareFunc compare_func) +{ + g_return_if_fail (array != NULL); + + /* Don't use qsort as we want a guaranteed stable sort */ + if (array->len > 0) + g_qsort_with_data (array->pdata, + array->len, + sizeof (gpointer), + (GCompareDataFunc)compare_func, + NULL); +} + +/* Please keep this doc-comment in sync with + * pointer_array_sort_with_data_example() in glib/tests/array-test.c */ +/** + * g_ptr_array_sort_with_data: + * @array: a #GPtrArray + * @compare_func: comparison function + * @user_data: data to pass to @compare_func + * + * Like g_ptr_array_sort(), but the comparison function has an extra + * user data argument. + * + * Note that the comparison function for g_ptr_array_sort_with_data() + * doesn't take the pointers from the array as arguments, it takes + * pointers to the pointers in the array. Here is a full example of use: + * + * |[ + * typedef enum { SORT_NAME, SORT_SIZE } SortMode; + * + * typedef struct + * { + * gchar *name; + * gint size; + * } FileListEntry; + * + * static gint + * sort_filelist (gconstpointer a, gconstpointer b, gpointer user_data) + * { + * gint order; + * const SortMode sort_mode = GPOINTER_TO_INT (user_data); + * const FileListEntry *entry1 = *((FileListEntry **) a); + * const FileListEntry *entry2 = *((FileListEntry **) b); + * + * switch (sort_mode) + * { + * case SORT_NAME: + * order = g_ascii_strcasecmp (entry1->name, entry2->name); + * break; + * case SORT_SIZE: + * order = entry1->size - entry2->size; + * break; + * default: + * order = 0; + * break; + * } + * return order; + * } + * + * ... + * g_autoptr (GPtrArray) file_list = NULL; + * SortMode sort_mode; + * + * // initialize file_list array and load with many FileListEntry entries + * ... + * // now sort it with + * sort_mode = SORT_NAME; + * g_ptr_array_sort_with_data (file_list, + * sort_filelist, + * GINT_TO_POINTER (sort_mode)); + * ]| + * + * This is guaranteed to be a stable sort since version 2.32. + */ +void +g_ptr_array_sort_with_data (GPtrArray *array, + GCompareDataFunc compare_func, + gpointer user_data) +{ + g_return_if_fail (array != NULL); + + if (array->len > 0) + g_qsort_with_data (array->pdata, + array->len, + sizeof (gpointer), + compare_func, + user_data); +} + +/** + * g_ptr_array_foreach: + * @array: a #GPtrArray + * @func: the function to call for each array element + * @user_data: user data to pass to the function + * + * Calls a function for each element of a #GPtrArray. @func must not + * add elements to or remove elements from the array. + * + * Since: 2.4 + */ +void +g_ptr_array_foreach (GPtrArray *array, + GFunc func, + gpointer user_data) +{ + guint i; + + g_return_if_fail (array); + + for (i = 0; i < array->len; i++) + (*func) (array->pdata[i], user_data); +} + +/** + * g_ptr_array_find: (skip) + * @haystack: pointer array to be searched + * @needle: pointer to look for + * @index_: (optional) (out): return location for the index of + * the element, if found + * + * Checks whether @needle exists in @haystack. If the element is found, %TRUE is + * returned and the element’s index is returned in @index_ (if non-%NULL). + * Otherwise, %FALSE is returned and @index_ is undefined. If @needle exists + * multiple times in @haystack, the index of the first instance is returned. + * + * This does pointer comparisons only. If you want to use more complex equality + * checks, such as string comparisons, use g_ptr_array_find_with_equal_func(). + * + * Returns: %TRUE if @needle is one of the elements of @haystack + * Since: 2.54 + */ +gboolean +g_ptr_array_find (GPtrArray *haystack, + gconstpointer needle, + guint *index_) +{ + return g_ptr_array_find_with_equal_func (haystack, needle, NULL, index_); +} + +/** + * g_ptr_array_find_with_equal_func: (skip) + * @haystack: pointer array to be searched + * @needle: pointer to look for + * @equal_func: (nullable): the function to call for each element, which should + * return %TRUE when the desired element is found; or %NULL to use pointer + * equality + * @index_: (optional) (out): return location for the index of + * the element, if found + * + * Checks whether @needle exists in @haystack, using the given @equal_func. + * If the element is found, %TRUE is returned and the element’s index is + * returned in @index_ (if non-%NULL). Otherwise, %FALSE is returned and @index_ + * is undefined. If @needle exists multiple times in @haystack, the index of + * the first instance is returned. + * + * @equal_func is called with the element from the array as its first parameter, + * and @needle as its second parameter. If @equal_func is %NULL, pointer + * equality is used. + * + * Returns: %TRUE if @needle is one of the elements of @haystack + * Since: 2.54 + */ +gboolean +g_ptr_array_find_with_equal_func (GPtrArray *haystack, + gconstpointer needle, + GEqualFunc equal_func, + guint *index_) +{ + guint i; + + g_return_val_if_fail (haystack != NULL, FALSE); + + if (equal_func == NULL) + equal_func = g_direct_equal; + + for (i = 0; i < haystack->len; i++) + { + if (equal_func (g_ptr_array_index (haystack, i), needle)) + { + if (index_ != NULL) + *index_ = i; + return TRUE; + } + } + + return FALSE; +} + +/** + * SECTION:arrays_byte + * @title: Byte Arrays + * @short_description: arrays of bytes + * + * #GByteArray is a mutable array of bytes based on #GArray, to provide arrays + * of bytes which grow automatically as elements are added. + * + * To create a new #GByteArray use g_byte_array_new(). To add elements to a + * #GByteArray, use g_byte_array_append(), and g_byte_array_prepend(). + * + * To set the size of a #GByteArray, use g_byte_array_set_size(). + * + * To free a #GByteArray, use g_byte_array_free(). + * + * An example for using a #GByteArray: + * |[ + * GByteArray *gbarray; + * gint i; + * + * gbarray = g_byte_array_new (); + * for (i = 0; i < 10000; i++) + * g_byte_array_append (gbarray, (guint8*) "abcd", 4); + * + * for (i = 0; i < 10000; i++) + * { + * g_assert (gbarray->data[4*i] == 'a'); + * g_assert (gbarray->data[4*i+1] == 'b'); + * g_assert (gbarray->data[4*i+2] == 'c'); + * g_assert (gbarray->data[4*i+3] == 'd'); + * } + * + * g_byte_array_free (gbarray, TRUE); + * ]| + * + * See #GBytes if you are interested in an immutable object representing a + * sequence of bytes. + */ + +/** + * GByteArray: + * @data: a pointer to the element data. The data may be moved as + * elements are added to the #GByteArray + * @len: the number of elements in the #GByteArray + * + * Contains the public fields of a GByteArray. + */ + +/** + * g_byte_array_new: + * + * Creates a new #GByteArray with a reference count of 1. + * + * Returns: (transfer full): the new #GByteArray + */ +GByteArray* +g_byte_array_new (void) +{ + return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, 0); +} + +/** + * g_byte_array_steal: + * @array: a #GByteArray. + * @len: (optional) (out): pointer to retrieve the number of + * elements of the original array + * + * Frees the data in the array and resets the size to zero, while + * the underlying array is preserved for use elsewhere and returned + * to the caller. + * + * Returns: (transfer full): the element data, which should be + * freed using g_free(). + * + * Since: 2.64 + */ +guint8 * +g_byte_array_steal (GByteArray *array, + gsize *len) +{ + return (guint8 *) g_array_steal ((GArray *) array, len); +} + +/** + * g_byte_array_new_take: + * @data: (transfer full) (array length=len): byte data for the array + * @len: length of @data + * + * Create byte array containing the data. The data will be owned by the array + * and will be freed with g_free(), i.e. it could be allocated using g_strdup(). + * + * Do not use it if @len is greater than %G_MAXUINT. #GByteArray + * stores the length of its data in #guint, which may be shorter than + * #gsize. + * + * Since: 2.32 + * + * Returns: (transfer full): a new #GByteArray + */ +GByteArray* +g_byte_array_new_take (guint8 *data, + gsize len) +{ + GByteArray *array; + GRealArray *real; + + g_return_val_if_fail (len <= G_MAXUINT, NULL); + array = g_byte_array_new (); + real = (GRealArray *)array; + g_assert (real->data == NULL); + g_assert (real->len == 0); + + real->data = data; + real->len = len; + real->elt_capacity = len; + + return array; +} + +/** + * g_byte_array_sized_new: + * @reserved_size: number of bytes preallocated + * + * Creates a new #GByteArray with @reserved_size bytes preallocated. + * This avoids frequent reallocation, if you are going to add many + * bytes to the array. Note however that the size of the array is still + * 0. + * + * Returns: the new #GByteArray + */ +GByteArray* +g_byte_array_sized_new (guint reserved_size) +{ + return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, reserved_size); +} + +/** + * g_byte_array_free: + * @array: a #GByteArray + * @free_segment: if %TRUE the actual byte data is freed as well + * + * Frees the memory allocated by the #GByteArray. If @free_segment is + * %TRUE it frees the actual byte data. If the reference count of + * @array is greater than one, the #GByteArray wrapper is preserved but + * the size of @array will be set to zero. + * + * Returns: the element data if @free_segment is %FALSE, otherwise + * %NULL. The element data should be freed using g_free(). + */ +guint8* +g_byte_array_free (GByteArray *array, + gboolean free_segment) +{ + return (guint8 *)g_array_free ((GArray *)array, free_segment); +} + +/** + * g_byte_array_free_to_bytes: + * @array: (transfer full): a #GByteArray + * + * Transfers the data from the #GByteArray into a new immutable #GBytes. + * + * The #GByteArray is freed unless the reference count of @array is greater + * than one, the #GByteArray wrapper is preserved but the size of @array + * will be set to zero. + * + * This is identical to using g_bytes_new_take() and g_byte_array_free() + * together. + * + * Since: 2.32 + * + * Returns: (transfer full): a new immutable #GBytes representing same + * byte data that was in the array + */ +GBytes* +g_byte_array_free_to_bytes (GByteArray *array) +{ + gsize length; + + g_return_val_if_fail (array != NULL, NULL); + + length = array->len; + return g_bytes_new_take (g_byte_array_free (array, FALSE), length); +} + +/** + * g_byte_array_ref: + * @array: A #GByteArray + * + * Atomically increments the reference count of @array by one. + * This function is thread-safe and may be called from any thread. + * + * Returns: The passed in #GByteArray + * + * Since: 2.22 + */ +GByteArray* +g_byte_array_ref (GByteArray *array) +{ + return (GByteArray *)g_array_ref ((GArray *)array); +} + +/** + * g_byte_array_unref: + * @array: A #GByteArray + * + * Atomically decrements the reference count of @array by one. If the + * reference count drops to 0, all memory allocated by the array is + * released. This function is thread-safe and may be called from any + * thread. + * + * Since: 2.22 + */ +void +g_byte_array_unref (GByteArray *array) +{ + g_array_unref ((GArray *)array); +} + +/** + * g_byte_array_append: + * @array: a #GByteArray + * @data: the byte data to be added + * @len: the number of bytes to add + * + * Adds the given bytes to the end of the #GByteArray. + * The array will grow in size automatically if necessary. + * + * Returns: the #GByteArray + */ +GByteArray* +g_byte_array_append (GByteArray *array, + const guint8 *data, + guint len) +{ + g_array_append_vals ((GArray *)array, (guint8 *)data, len); + + return array; +} + +/** + * g_byte_array_prepend: + * @array: a #GByteArray + * @data: the byte data to be added + * @len: the number of bytes to add + * + * Adds the given data to the start of the #GByteArray. + * The array will grow in size automatically if necessary. + * + * Returns: the #GByteArray + */ +GByteArray* +g_byte_array_prepend (GByteArray *array, + const guint8 *data, + guint len) +{ + g_array_prepend_vals ((GArray *)array, (guint8 *)data, len); + + return array; +} + +/** + * g_byte_array_set_size: + * @array: a #GByteArray + * @length: the new size of the #GByteArray + * + * Sets the size of the #GByteArray, expanding it if necessary. + * + * Returns: the #GByteArray + */ +GByteArray* +g_byte_array_set_size (GByteArray *array, + guint length) +{ + g_array_set_size ((GArray *)array, length); + + return array; +} + +/** + * g_byte_array_remove_index: + * @array: a #GByteArray + * @index_: the index of the byte to remove + * + * Removes the byte at the given index from a #GByteArray. + * The following bytes are moved down one place. + * + * Returns: the #GByteArray + **/ +GByteArray* +g_byte_array_remove_index (GByteArray *array, + guint index_) +{ + g_array_remove_index ((GArray *)array, index_); + + return array; +} + +/** + * g_byte_array_remove_index_fast: + * @array: a #GByteArray + * @index_: the index of the byte to remove + * + * Removes the byte at the given index from a #GByteArray. The last + * element in the array is used to fill in the space, so this function + * does not preserve the order of the #GByteArray. But it is faster + * than g_byte_array_remove_index(). + * + * Returns: the #GByteArray + */ +GByteArray* +g_byte_array_remove_index_fast (GByteArray *array, + guint index_) +{ + g_array_remove_index_fast ((GArray *)array, index_); + + return array; +} + +/** + * g_byte_array_remove_range: + * @array: a @GByteArray + * @index_: the index of the first byte to remove + * @length: the number of bytes to remove + * + * Removes the given number of bytes starting at the given index from a + * #GByteArray. The following elements are moved to close the gap. + * + * Returns: the #GByteArray + * + * Since: 2.4 + */ +GByteArray* +g_byte_array_remove_range (GByteArray *array, + guint index_, + guint length) +{ + g_return_val_if_fail (array, NULL); + g_return_val_if_fail (index_ <= array->len, NULL); + g_return_val_if_fail (index_ + length <= array->len, NULL); + + return (GByteArray *)g_array_remove_range ((GArray *)array, index_, length); +} + +/** + * g_byte_array_sort: + * @array: a #GByteArray + * @compare_func: comparison function + * + * Sorts a byte array, using @compare_func which should be a + * qsort()-style comparison function (returns less than zero for first + * arg is less than second arg, zero for equal, greater than zero if + * first arg is greater than second arg). + * + * If two array elements compare equal, their order in the sorted array + * is undefined. If you want equal elements to keep their order (i.e. + * you want a stable sort) you can write a comparison function that, + * if two elements would otherwise compare equal, compares them by + * their addresses. + */ +void +g_byte_array_sort (GByteArray *array, + GCompareFunc compare_func) +{ + g_array_sort ((GArray *)array, compare_func); +} + +/** + * g_byte_array_sort_with_data: + * @array: a #GByteArray + * @compare_func: comparison function + * @user_data: data to pass to @compare_func + * + * Like g_byte_array_sort(), but the comparison function takes an extra + * user data argument. + */ +void +g_byte_array_sort_with_data (GByteArray *array, + GCompareDataFunc compare_func, + gpointer user_data) +{ + g_array_sort_with_data ((GArray *)array, compare_func, user_data); +} diff --git a/glib/garray.h b/glib/garray.h new file mode 100644 index 0000000..67131b5 --- /dev/null +++ b/glib/garray.h @@ -0,0 +1,281 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_ARRAY_H__ +#define __G_ARRAY_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GBytes GBytes; +typedef struct _GArray GArray; +typedef struct _GByteArray GByteArray; +typedef struct _GPtrArray GPtrArray; + +struct _GArray +{ + gchar *data; + guint len; +}; + +struct _GByteArray +{ + guint8 *data; + guint len; +}; + +struct _GPtrArray +{ + gpointer *pdata; + guint len; +}; + +/* Resizable arrays. remove fills any cleared spot and shortens the + * array, while preserving the order. remove_fast will distort the + * order by moving the last element to the position of the removed. + */ + +#define g_array_append_val(a,v) g_array_append_vals (a, &(v), 1) +#define g_array_prepend_val(a,v) g_array_prepend_vals (a, &(v), 1) +#define g_array_insert_val(a,i,v) g_array_insert_vals (a, i, &(v), 1) +#define g_array_index(a,t,i) (((t*) (void *) (a)->data) [(i)]) + +GLIB_AVAILABLE_IN_ALL +GArray* g_array_new (gboolean zero_terminated, + gboolean clear_, + guint element_size); +GLIB_AVAILABLE_IN_2_64 +gpointer g_array_steal (GArray *array, + gsize *len); +GLIB_AVAILABLE_IN_ALL +GArray* g_array_sized_new (gboolean zero_terminated, + gboolean clear_, + guint element_size, + guint reserved_size); +GLIB_AVAILABLE_IN_2_62 +GArray* g_array_copy (GArray *array); +GLIB_AVAILABLE_IN_ALL +gchar* g_array_free (GArray *array, + gboolean free_segment); +GLIB_AVAILABLE_IN_ALL +GArray *g_array_ref (GArray *array); +GLIB_AVAILABLE_IN_ALL +void g_array_unref (GArray *array); +GLIB_AVAILABLE_IN_ALL +guint g_array_get_element_size (GArray *array); +GLIB_AVAILABLE_IN_ALL +GArray* g_array_append_vals (GArray *array, + gconstpointer data, + guint len); +GLIB_AVAILABLE_IN_ALL +GArray* g_array_prepend_vals (GArray *array, + gconstpointer data, + guint len); +GLIB_AVAILABLE_IN_ALL +GArray* g_array_insert_vals (GArray *array, + guint index_, + gconstpointer data, + guint len); +GLIB_AVAILABLE_IN_ALL +GArray* g_array_set_size (GArray *array, + guint length); +GLIB_AVAILABLE_IN_ALL +GArray* g_array_remove_index (GArray *array, + guint index_); +GLIB_AVAILABLE_IN_ALL +GArray* g_array_remove_index_fast (GArray *array, + guint index_); +GLIB_AVAILABLE_IN_ALL +GArray* g_array_remove_range (GArray *array, + guint index_, + guint length); +GLIB_AVAILABLE_IN_ALL +void g_array_sort (GArray *array, + GCompareFunc compare_func); +GLIB_AVAILABLE_IN_ALL +void g_array_sort_with_data (GArray *array, + GCompareDataFunc compare_func, + gpointer user_data); +GLIB_AVAILABLE_IN_2_62 +gboolean g_array_binary_search (GArray *array, + gconstpointer target, + GCompareFunc compare_func, + guint *out_match_index); +GLIB_AVAILABLE_IN_ALL +void g_array_set_clear_func (GArray *array, + GDestroyNotify clear_func); + +/* Resizable pointer array. This interface is much less complicated + * than the above. Add appends a pointer. Remove fills any cleared + * spot and shortens the array. remove_fast will again distort order. + */ +#define g_ptr_array_index(array,index_) ((array)->pdata)[index_] +GLIB_AVAILABLE_IN_ALL +GPtrArray* g_ptr_array_new (void); +GLIB_AVAILABLE_IN_ALL +GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify element_free_func); +GLIB_AVAILABLE_IN_2_64 +gpointer* g_ptr_array_steal (GPtrArray *array, + gsize *len); +GLIB_AVAILABLE_IN_2_62 +GPtrArray *g_ptr_array_copy (GPtrArray *array, + GCopyFunc func, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +GPtrArray* g_ptr_array_sized_new (guint reserved_size); +GLIB_AVAILABLE_IN_ALL +GPtrArray* g_ptr_array_new_full (guint reserved_size, + GDestroyNotify element_free_func); +GLIB_AVAILABLE_IN_ALL +gpointer* g_ptr_array_free (GPtrArray *array, + gboolean free_seg); +GLIB_AVAILABLE_IN_ALL +GPtrArray* g_ptr_array_ref (GPtrArray *array); +GLIB_AVAILABLE_IN_ALL +void g_ptr_array_unref (GPtrArray *array); +GLIB_AVAILABLE_IN_ALL +void g_ptr_array_set_free_func (GPtrArray *array, + GDestroyNotify element_free_func); +GLIB_AVAILABLE_IN_ALL +void g_ptr_array_set_size (GPtrArray *array, + gint length); +GLIB_AVAILABLE_IN_ALL +gpointer g_ptr_array_remove_index (GPtrArray *array, + guint index_); +GLIB_AVAILABLE_IN_ALL +gpointer g_ptr_array_remove_index_fast (GPtrArray *array, + guint index_); +GLIB_AVAILABLE_IN_2_58 +gpointer g_ptr_array_steal_index (GPtrArray *array, + guint index_); +GLIB_AVAILABLE_IN_2_58 +gpointer g_ptr_array_steal_index_fast (GPtrArray *array, + guint index_); +GLIB_AVAILABLE_IN_ALL +gboolean g_ptr_array_remove (GPtrArray *array, + gpointer data); +GLIB_AVAILABLE_IN_ALL +gboolean g_ptr_array_remove_fast (GPtrArray *array, + gpointer data); +GLIB_AVAILABLE_IN_ALL +GPtrArray *g_ptr_array_remove_range (GPtrArray *array, + guint index_, + guint length); +GLIB_AVAILABLE_IN_ALL +void g_ptr_array_add (GPtrArray *array, + gpointer data); +GLIB_AVAILABLE_IN_2_62 +void g_ptr_array_extend (GPtrArray *array_to_extend, + GPtrArray *array, + GCopyFunc func, + gpointer user_data); +GLIB_AVAILABLE_IN_2_62 +void g_ptr_array_extend_and_steal (GPtrArray *array_to_extend, + GPtrArray *array); +GLIB_AVAILABLE_IN_2_40 +void g_ptr_array_insert (GPtrArray *array, + gint index_, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_ptr_array_sort (GPtrArray *array, + GCompareFunc compare_func); +GLIB_AVAILABLE_IN_ALL +void g_ptr_array_sort_with_data (GPtrArray *array, + GCompareDataFunc compare_func, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +void g_ptr_array_foreach (GPtrArray *array, + GFunc func, + gpointer user_data); +GLIB_AVAILABLE_IN_2_54 +gboolean g_ptr_array_find (GPtrArray *haystack, + gconstpointer needle, + guint *index_); +GLIB_AVAILABLE_IN_2_54 +gboolean g_ptr_array_find_with_equal_func (GPtrArray *haystack, + gconstpointer needle, + GEqualFunc equal_func, + guint *index_); + + +/* Byte arrays, an array of guint8. Implemented as a GArray, + * but type-safe. + */ + +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_new (void); +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_new_take (guint8 *data, + gsize len); +GLIB_AVAILABLE_IN_2_64 +guint8* g_byte_array_steal (GByteArray *array, + gsize *len); +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_sized_new (guint reserved_size); +GLIB_AVAILABLE_IN_ALL +guint8* g_byte_array_free (GByteArray *array, + gboolean free_segment); +GLIB_AVAILABLE_IN_ALL +GBytes* g_byte_array_free_to_bytes (GByteArray *array); +GLIB_AVAILABLE_IN_ALL +GByteArray *g_byte_array_ref (GByteArray *array); +GLIB_AVAILABLE_IN_ALL +void g_byte_array_unref (GByteArray *array); +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_append (GByteArray *array, + const guint8 *data, + guint len); +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_prepend (GByteArray *array, + const guint8 *data, + guint len); +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_set_size (GByteArray *array, + guint length); +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_remove_index (GByteArray *array, + guint index_); +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_remove_index_fast (GByteArray *array, + guint index_); +GLIB_AVAILABLE_IN_ALL +GByteArray* g_byte_array_remove_range (GByteArray *array, + guint index_, + guint length); +GLIB_AVAILABLE_IN_ALL +void g_byte_array_sort (GByteArray *array, + GCompareFunc compare_func); +GLIB_AVAILABLE_IN_ALL +void g_byte_array_sort_with_data (GByteArray *array, + GCompareDataFunc compare_func, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_ARRAY_H__ */ diff --git a/glib/gasyncqueue.c b/glib/gasyncqueue.c new file mode 100644 index 0000000..98c7d8a --- /dev/null +++ b/glib/gasyncqueue.c @@ -0,0 +1,906 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GAsyncQueue: asynchronous queue implementation, based on GQueue. + * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "gasyncqueue.h" +#include "gasyncqueueprivate.h" + +#include "gmain.h" +#include "gmem.h" +#include "gqueue.h" +#include "gtestutils.h" +#include "gtimer.h" +#include "gthread.h" +#include "deprecated/gthread.h" + + +/** + * SECTION:async_queues + * @title: Asynchronous Queues + * @short_description: asynchronous communication between threads + * @see_also: #GThreadPool + * + * Often you need to communicate between different threads. In general + * it's safer not to do this by shared memory, but by explicit message + * passing. These messages only make sense asynchronously for + * multi-threaded applications though, as a synchronous operation could + * as well be done in the same thread. + * + * Asynchronous queues are an exception from most other GLib data + * structures, as they can be used simultaneously from multiple threads + * without explicit locking and they bring their own builtin reference + * counting. This is because the nature of an asynchronous queue is that + * it will always be used by at least 2 concurrent threads. + * + * For using an asynchronous queue you first have to create one with + * g_async_queue_new(). #GAsyncQueue structs are reference counted, + * use g_async_queue_ref() and g_async_queue_unref() to manage your + * references. + * + * A thread which wants to send a message to that queue simply calls + * g_async_queue_push() to push the message to the queue. + * + * A thread which is expecting messages from an asynchronous queue + * simply calls g_async_queue_pop() for that queue. If no message is + * available in the queue at that point, the thread is now put to sleep + * until a message arrives. The message will be removed from the queue + * and returned. The functions g_async_queue_try_pop() and + * g_async_queue_timeout_pop() can be used to only check for the presence + * of messages or to only wait a certain time for messages respectively. + * + * For almost every function there exist two variants, one that locks + * the queue and one that doesn't. That way you can hold the queue lock + * (acquire it with g_async_queue_lock() and release it with + * g_async_queue_unlock()) over multiple queue accessing instructions. + * This can be necessary to ensure the integrity of the queue, but should + * only be used when really necessary, as it can make your life harder + * if used unwisely. Normally you should only use the locking function + * variants (those without the _unlocked suffix). + * + * In many cases, it may be more convenient to use #GThreadPool when + * you need to distribute work to a set of worker threads instead of + * using #GAsyncQueue manually. #GThreadPool uses a GAsyncQueue + * internally. + */ + +/** + * GAsyncQueue: + * + * An opaque data structure which represents an asynchronous queue. + * + * It should only be accessed through the `g_async_queue_*` functions. + */ +struct _GAsyncQueue +{ + GMutex mutex; + GCond cond; + GQueue queue; + GDestroyNotify item_free_func; + guint waiting_threads; + gint ref_count; +}; + +typedef struct +{ + GCompareDataFunc func; + gpointer user_data; +} SortData; + +/** + * g_async_queue_new: + * + * Creates a new asynchronous queue. + * + * Returns: a new #GAsyncQueue. Free with g_async_queue_unref() + */ +GAsyncQueue * +g_async_queue_new (void) +{ + return g_async_queue_new_full (NULL); +} + +/** + * g_async_queue_new_full: + * @item_free_func: (nullable): function to free queue elements + * + * Creates a new asynchronous queue and sets up a destroy notify + * function that is used to free any remaining queue items when + * the queue is destroyed after the final unref. + * + * Returns: a new #GAsyncQueue. Free with g_async_queue_unref() + * + * Since: 2.16 + */ +GAsyncQueue * +g_async_queue_new_full (GDestroyNotify item_free_func) +{ + GAsyncQueue *queue; + + queue = g_new (GAsyncQueue, 1); + g_mutex_init (&queue->mutex); + g_cond_init (&queue->cond); + g_queue_init (&queue->queue); + queue->waiting_threads = 0; + queue->ref_count = 1; + queue->item_free_func = item_free_func; + + return queue; +} + +/** + * g_async_queue_ref: + * @queue: a #GAsyncQueue + * + * Increases the reference count of the asynchronous @queue by 1. + * You do not need to hold the lock to call this function. + * + * Returns: the @queue that was passed in (since 2.6) + */ +GAsyncQueue * +g_async_queue_ref (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + + g_atomic_int_inc (&queue->ref_count); + + return queue; +} + +/** + * g_async_queue_ref_unlocked: + * @queue: a #GAsyncQueue + * + * Increases the reference count of the asynchronous @queue by 1. + * + * Deprecated: 2.8: Reference counting is done atomically. + * so g_async_queue_ref() can be used regardless of the @queue's + * lock. + */ +void +g_async_queue_ref_unlocked (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + g_atomic_int_inc (&queue->ref_count); +} + +/** + * g_async_queue_unref_and_unlock: + * @queue: a #GAsyncQueue + * + * Decreases the reference count of the asynchronous @queue by 1 + * and releases the lock. This function must be called while holding + * the @queue's lock. If the reference count went to 0, the @queue + * will be destroyed and the memory allocated will be freed. + * + * Deprecated: 2.8: Reference counting is done atomically. + * so g_async_queue_unref() can be used regardless of the @queue's + * lock. + */ +void +g_async_queue_unref_and_unlock (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + g_mutex_unlock (&queue->mutex); + g_async_queue_unref (queue); +} + +/** + * g_async_queue_unref: + * @queue: a #GAsyncQueue. + * + * Decreases the reference count of the asynchronous @queue by 1. + * + * If the reference count went to 0, the @queue will be destroyed + * and the memory allocated will be freed. So you are not allowed + * to use the @queue afterwards, as it might have disappeared. + * You do not need to hold the lock to call this function. + */ +void +g_async_queue_unref (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + if (g_atomic_int_dec_and_test (&queue->ref_count)) + { + g_return_if_fail (queue->waiting_threads == 0); + g_mutex_clear (&queue->mutex); + g_cond_clear (&queue->cond); + if (queue->item_free_func) + g_queue_foreach (&queue->queue, (GFunc) queue->item_free_func, NULL); + g_queue_clear (&queue->queue); + g_free (queue); + } +} + +/** + * g_async_queue_lock: + * @queue: a #GAsyncQueue + * + * Acquires the @queue's lock. If another thread is already + * holding the lock, this call will block until the lock + * becomes available. + * + * Call g_async_queue_unlock() to drop the lock again. + * + * While holding the lock, you can only call the + * g_async_queue_*_unlocked() functions on @queue. Otherwise, + * deadlock may occur. + */ +void +g_async_queue_lock (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + g_mutex_lock (&queue->mutex); +} + +/** + * g_async_queue_unlock: + * @queue: a #GAsyncQueue + * + * Releases the queue's lock. + * + * Calling this function when you have not acquired + * the with g_async_queue_lock() leads to undefined + * behaviour. + */ +void +g_async_queue_unlock (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + g_mutex_unlock (&queue->mutex); +} + +/** + * g_async_queue_push: + * @queue: a #GAsyncQueue + * @data: @data to push into the @queue + * + * Pushes the @data into the @queue. @data must not be %NULL. + */ +void +g_async_queue_push (GAsyncQueue *queue, + gpointer data) +{ + g_return_if_fail (queue); + g_return_if_fail (data); + + g_mutex_lock (&queue->mutex); + g_async_queue_push_unlocked (queue, data); + g_mutex_unlock (&queue->mutex); +} + +/** + * g_async_queue_push_unlocked: + * @queue: a #GAsyncQueue + * @data: @data to push into the @queue + * + * Pushes the @data into the @queue. @data must not be %NULL. + * + * This function must be called while holding the @queue's lock. + */ +void +g_async_queue_push_unlocked (GAsyncQueue *queue, + gpointer data) +{ + g_return_if_fail (queue); + g_return_if_fail (data); + + g_queue_push_head (&queue->queue, data); + if (queue->waiting_threads > 0) + g_cond_signal (&queue->cond); +} + +/** + * g_async_queue_push_sorted: + * @queue: a #GAsyncQueue + * @data: the @data to push into the @queue + * @func: the #GCompareDataFunc is used to sort @queue + * @user_data: user data passed to @func. + * + * Inserts @data into @queue using @func to determine the new + * position. + * + * This function requires that the @queue is sorted before pushing on + * new elements, see g_async_queue_sort(). + * + * This function will lock @queue before it sorts the queue and unlock + * it when it is finished. + * + * For an example of @func see g_async_queue_sort(). + * + * Since: 2.10 + */ +void +g_async_queue_push_sorted (GAsyncQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data) +{ + g_return_if_fail (queue != NULL); + + g_mutex_lock (&queue->mutex); + g_async_queue_push_sorted_unlocked (queue, data, func, user_data); + g_mutex_unlock (&queue->mutex); +} + +static gint +g_async_queue_invert_compare (gpointer v1, + gpointer v2, + SortData *sd) +{ + return -sd->func (v1, v2, sd->user_data); +} + +/** + * g_async_queue_push_sorted_unlocked: + * @queue: a #GAsyncQueue + * @data: the @data to push into the @queue + * @func: the #GCompareDataFunc is used to sort @queue + * @user_data: user data passed to @func. + * + * Inserts @data into @queue using @func to determine the new + * position. + * + * The sort function @func is passed two elements of the @queue. + * It should return 0 if they are equal, a negative value if the + * first element should be higher in the @queue or a positive value + * if the first element should be lower in the @queue than the second + * element. + * + * This function requires that the @queue is sorted before pushing on + * new elements, see g_async_queue_sort(). + * + * This function must be called while holding the @queue's lock. + * + * For an example of @func see g_async_queue_sort(). + * + * Since: 2.10 + */ +void +g_async_queue_push_sorted_unlocked (GAsyncQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data) +{ + SortData sd; + + g_return_if_fail (queue != NULL); + + sd.func = func; + sd.user_data = user_data; + + g_queue_insert_sorted (&queue->queue, + data, + (GCompareDataFunc)g_async_queue_invert_compare, + &sd); + if (queue->waiting_threads > 0) + g_cond_signal (&queue->cond); +} + +static gpointer +g_async_queue_pop_intern_unlocked (GAsyncQueue *queue, + gboolean wait, + gint64 end_time) +{ + gpointer retval; + + if (!g_queue_peek_tail_link (&queue->queue) && wait) + { + queue->waiting_threads++; + while (!g_queue_peek_tail_link (&queue->queue)) + { + if (end_time == -1) + g_cond_wait (&queue->cond, &queue->mutex); + else + { + if (!g_cond_wait_until (&queue->cond, &queue->mutex, end_time)) + break; + } + } + queue->waiting_threads--; + } + + retval = g_queue_pop_tail (&queue->queue); + + g_assert (retval || !wait || end_time > 0); + + return retval; +} + +/** + * g_async_queue_pop: + * @queue: a #GAsyncQueue + * + * Pops data from the @queue. If @queue is empty, this function + * blocks until data becomes available. + * + * Returns: data from the queue + */ +gpointer +g_async_queue_pop (GAsyncQueue *queue) +{ + gpointer retval; + + g_return_val_if_fail (queue, NULL); + + g_mutex_lock (&queue->mutex); + retval = g_async_queue_pop_intern_unlocked (queue, TRUE, -1); + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_pop_unlocked: + * @queue: a #GAsyncQueue + * + * Pops data from the @queue. If @queue is empty, this function + * blocks until data becomes available. + * + * This function must be called while holding the @queue's lock. + * + * Returns: data from the queue. + */ +gpointer +g_async_queue_pop_unlocked (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + + return g_async_queue_pop_intern_unlocked (queue, TRUE, -1); +} + +/** + * g_async_queue_try_pop: + * @queue: a #GAsyncQueue + * + * Tries to pop data from the @queue. If no data is available, + * %NULL is returned. + * + * Returns: (nullable): data from the queue or %NULL, when no data is + * available immediately. + */ +gpointer +g_async_queue_try_pop (GAsyncQueue *queue) +{ + gpointer retval; + + g_return_val_if_fail (queue, NULL); + + g_mutex_lock (&queue->mutex); + retval = g_async_queue_pop_intern_unlocked (queue, FALSE, -1); + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_try_pop_unlocked: + * @queue: a #GAsyncQueue + * + * Tries to pop data from the @queue. If no data is available, + * %NULL is returned. + * + * This function must be called while holding the @queue's lock. + * + * Returns: (nullable): data from the queue or %NULL, when no data is + * available immediately. + */ +gpointer +g_async_queue_try_pop_unlocked (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + + return g_async_queue_pop_intern_unlocked (queue, FALSE, -1); +} + +/** + * g_async_queue_timeout_pop: + * @queue: a #GAsyncQueue + * @timeout: the number of microseconds to wait + * + * Pops data from the @queue. If the queue is empty, blocks for + * @timeout microseconds, or until data becomes available. + * + * If no data is received before the timeout, %NULL is returned. + * + * Returns: (nullable): data from the queue or %NULL, when no data is + * received before the timeout. + */ +gpointer +g_async_queue_timeout_pop (GAsyncQueue *queue, + guint64 timeout) +{ + gint64 end_time = g_get_monotonic_time () + timeout; + gpointer retval; + + g_return_val_if_fail (queue != NULL, NULL); + + g_mutex_lock (&queue->mutex); + retval = g_async_queue_pop_intern_unlocked (queue, TRUE, end_time); + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_timeout_pop_unlocked: + * @queue: a #GAsyncQueue + * @timeout: the number of microseconds to wait + * + * Pops data from the @queue. If the queue is empty, blocks for + * @timeout microseconds, or until data becomes available. + * + * If no data is received before the timeout, %NULL is returned. + * + * This function must be called while holding the @queue's lock. + * + * Returns: (nullable): data from the queue or %NULL, when no data is + * received before the timeout. + */ +gpointer +g_async_queue_timeout_pop_unlocked (GAsyncQueue *queue, + guint64 timeout) +{ + gint64 end_time = g_get_monotonic_time () + timeout; + + g_return_val_if_fail (queue != NULL, NULL); + + return g_async_queue_pop_intern_unlocked (queue, TRUE, end_time); +} + +/** + * g_async_queue_timed_pop: + * @queue: a #GAsyncQueue + * @end_time: a #GTimeVal, determining the final time + * + * Pops data from the @queue. If the queue is empty, blocks until + * @end_time or until data becomes available. + * + * If no data is received before @end_time, %NULL is returned. + * + * To easily calculate @end_time, a combination of g_get_real_time() + * and g_time_val_add() can be used. + * + * Returns: (nullable): data from the queue or %NULL, when no data is + * received before @end_time. + * + * Deprecated: use g_async_queue_timeout_pop(). + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +gpointer +g_async_queue_timed_pop (GAsyncQueue *queue, + GTimeVal *end_time) +{ + gint64 m_end_time; + gpointer retval; + + g_return_val_if_fail (queue, NULL); + + if (end_time != NULL) + { + m_end_time = g_get_monotonic_time () + + ((gint64) end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec - g_get_real_time ()); + } + else + m_end_time = -1; + + g_mutex_lock (&queue->mutex); + retval = g_async_queue_pop_intern_unlocked (queue, TRUE, m_end_time); + g_mutex_unlock (&queue->mutex); + + return retval; +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_async_queue_timed_pop_unlocked: + * @queue: a #GAsyncQueue + * @end_time: a #GTimeVal, determining the final time + * + * Pops data from the @queue. If the queue is empty, blocks until + * @end_time or until data becomes available. + * + * If no data is received before @end_time, %NULL is returned. + * + * To easily calculate @end_time, a combination of g_get_real_time() + * and g_time_val_add() can be used. + * + * This function must be called while holding the @queue's lock. + * + * Returns: (nullable): data from the queue or %NULL, when no data is + * received before @end_time. + * + * Deprecated: use g_async_queue_timeout_pop_unlocked(). + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +gpointer +g_async_queue_timed_pop_unlocked (GAsyncQueue *queue, + GTimeVal *end_time) +{ + gint64 m_end_time; + + g_return_val_if_fail (queue, NULL); + + if (end_time != NULL) + { + m_end_time = g_get_monotonic_time () + + ((gint64) end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec - g_get_real_time ()); + } + else + m_end_time = -1; + + return g_async_queue_pop_intern_unlocked (queue, TRUE, m_end_time); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_async_queue_length: + * @queue: a #GAsyncQueue. + * + * Returns the length of the queue. + * + * Actually this function returns the number of data items in + * the queue minus the number of waiting threads, so a negative + * value means waiting threads, and a positive value means available + * entries in the @queue. A return value of 0 could mean n entries + * in the queue and n threads waiting. This can happen due to locking + * of the queue or due to scheduling. + * + * Returns: the length of the @queue + */ +gint +g_async_queue_length (GAsyncQueue *queue) +{ + gint retval; + + g_return_val_if_fail (queue, 0); + + g_mutex_lock (&queue->mutex); + retval = queue->queue.length - queue->waiting_threads; + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_length_unlocked: + * @queue: a #GAsyncQueue + * + * Returns the length of the queue. + * + * Actually this function returns the number of data items in + * the queue minus the number of waiting threads, so a negative + * value means waiting threads, and a positive value means available + * entries in the @queue. A return value of 0 could mean n entries + * in the queue and n threads waiting. This can happen due to locking + * of the queue or due to scheduling. + * + * This function must be called while holding the @queue's lock. + * + * Returns: the length of the @queue. + */ +gint +g_async_queue_length_unlocked (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, 0); + + return queue->queue.length - queue->waiting_threads; +} + +/** + * g_async_queue_sort: + * @queue: a #GAsyncQueue + * @func: the #GCompareDataFunc is used to sort @queue + * @user_data: user data passed to @func + * + * Sorts @queue using @func. + * + * The sort function @func is passed two elements of the @queue. + * It should return 0 if they are equal, a negative value if the + * first element should be higher in the @queue or a positive value + * if the first element should be lower in the @queue than the second + * element. + * + * This function will lock @queue before it sorts the queue and unlock + * it when it is finished. + * + * If you were sorting a list of priority numbers to make sure the + * lowest priority would be at the top of the queue, you could use: + * |[ + * gint32 id1; + * gint32 id2; + * + * id1 = GPOINTER_TO_INT (element1); + * id2 = GPOINTER_TO_INT (element2); + * + * return (id1 > id2 ? +1 : id1 == id2 ? 0 : -1); + * ]| + * + * Since: 2.10 + */ +void +g_async_queue_sort (GAsyncQueue *queue, + GCompareDataFunc func, + gpointer user_data) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (func != NULL); + + g_mutex_lock (&queue->mutex); + g_async_queue_sort_unlocked (queue, func, user_data); + g_mutex_unlock (&queue->mutex); +} + +/** + * g_async_queue_sort_unlocked: + * @queue: a #GAsyncQueue + * @func: the #GCompareDataFunc is used to sort @queue + * @user_data: user data passed to @func + * + * Sorts @queue using @func. + * + * The sort function @func is passed two elements of the @queue. + * It should return 0 if they are equal, a negative value if the + * first element should be higher in the @queue or a positive value + * if the first element should be lower in the @queue than the second + * element. + * + * This function must be called while holding the @queue's lock. + * + * Since: 2.10 + */ +void +g_async_queue_sort_unlocked (GAsyncQueue *queue, + GCompareDataFunc func, + gpointer user_data) +{ + SortData sd; + + g_return_if_fail (queue != NULL); + g_return_if_fail (func != NULL); + + sd.func = func; + sd.user_data = user_data; + + g_queue_sort (&queue->queue, + (GCompareDataFunc)g_async_queue_invert_compare, + &sd); +} + +/** + * g_async_queue_remove: + * @queue: a #GAsyncQueue + * @item: the data to remove from the @queue + * + * Remove an item from the queue. + * + * Returns: %TRUE if the item was removed + * + * Since: 2.46 + */ +gboolean +g_async_queue_remove (GAsyncQueue *queue, + gpointer item) +{ + gboolean ret; + + g_return_val_if_fail (queue != NULL, FALSE); + g_return_val_if_fail (item != NULL, FALSE); + + g_mutex_lock (&queue->mutex); + ret = g_async_queue_remove_unlocked (queue, item); + g_mutex_unlock (&queue->mutex); + + return ret; +} + +/** + * g_async_queue_remove_unlocked: + * @queue: a #GAsyncQueue + * @item: the data to remove from the @queue + * + * Remove an item from the queue. + * + * This function must be called while holding the @queue's lock. + * + * Returns: %TRUE if the item was removed + * + * Since: 2.46 + */ +gboolean +g_async_queue_remove_unlocked (GAsyncQueue *queue, + gpointer item) +{ + g_return_val_if_fail (queue != NULL, FALSE); + g_return_val_if_fail (item != NULL, FALSE); + + return g_queue_remove (&queue->queue, item); +} + +/** + * g_async_queue_push_front: + * @queue: a #GAsyncQueue + * @item: data to push into the @queue + * + * Pushes the @item into the @queue. @item must not be %NULL. + * In contrast to g_async_queue_push(), this function + * pushes the new item ahead of the items already in the queue, + * so that it will be the next one to be popped off the queue. + * + * Since: 2.46 + */ +void +g_async_queue_push_front (GAsyncQueue *queue, + gpointer item) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (item != NULL); + + g_mutex_lock (&queue->mutex); + g_async_queue_push_front_unlocked (queue, item); + g_mutex_unlock (&queue->mutex); +} + +/** + * g_async_queue_push_front_unlocked: + * @queue: a #GAsyncQueue + * @item: data to push into the @queue + * + * Pushes the @item into the @queue. @item must not be %NULL. + * In contrast to g_async_queue_push_unlocked(), this function + * pushes the new item ahead of the items already in the queue, + * so that it will be the next one to be popped off the queue. + * + * This function must be called while holding the @queue's lock. + * + * Since: 2.46 + */ +void +g_async_queue_push_front_unlocked (GAsyncQueue *queue, + gpointer item) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (item != NULL); + + g_queue_push_tail (&queue->queue, item); + if (queue->waiting_threads > 0) + g_cond_signal (&queue->cond); +} + +/* + * Private API + */ + +GMutex * +_g_async_queue_get_mutex (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + + return &queue->mutex; +} diff --git a/glib/gasyncqueue.h b/glib/gasyncqueue.h new file mode 100644 index 0000000..73e537b --- /dev/null +++ b/glib/gasyncqueue.h @@ -0,0 +1,124 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_ASYNCQUEUE_H__ +#define __G_ASYNCQUEUE_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GAsyncQueue GAsyncQueue; + +GLIB_AVAILABLE_IN_ALL +GAsyncQueue *g_async_queue_new (void); +GLIB_AVAILABLE_IN_ALL +GAsyncQueue *g_async_queue_new_full (GDestroyNotify item_free_func); +GLIB_AVAILABLE_IN_ALL +void g_async_queue_lock (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +void g_async_queue_unlock (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +GAsyncQueue *g_async_queue_ref (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +void g_async_queue_unref (GAsyncQueue *queue); + +GLIB_DEPRECATED_FOR(g_async_queue_ref) +void g_async_queue_ref_unlocked (GAsyncQueue *queue); + +GLIB_DEPRECATED_FOR(g_async_queue_unref) +void g_async_queue_unref_and_unlock (GAsyncQueue *queue); + +GLIB_AVAILABLE_IN_ALL +void g_async_queue_push (GAsyncQueue *queue, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_async_queue_push_unlocked (GAsyncQueue *queue, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_async_queue_push_sorted (GAsyncQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +void g_async_queue_push_sorted_unlocked (GAsyncQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +gpointer g_async_queue_pop (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +gpointer g_async_queue_pop_unlocked (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +gpointer g_async_queue_try_pop (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +gpointer g_async_queue_try_pop_unlocked (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +gpointer g_async_queue_timeout_pop (GAsyncQueue *queue, + guint64 timeout); +GLIB_AVAILABLE_IN_ALL +gpointer g_async_queue_timeout_pop_unlocked (GAsyncQueue *queue, + guint64 timeout); +GLIB_AVAILABLE_IN_ALL +gint g_async_queue_length (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +gint g_async_queue_length_unlocked (GAsyncQueue *queue); +GLIB_AVAILABLE_IN_ALL +void g_async_queue_sort (GAsyncQueue *queue, + GCompareDataFunc func, + gpointer user_data); +GLIB_AVAILABLE_IN_ALL +void g_async_queue_sort_unlocked (GAsyncQueue *queue, + GCompareDataFunc func, + gpointer user_data); + +GLIB_AVAILABLE_IN_2_46 +gboolean g_async_queue_remove (GAsyncQueue *queue, + gpointer item); +GLIB_AVAILABLE_IN_2_46 +gboolean g_async_queue_remove_unlocked (GAsyncQueue *queue, + gpointer item); +GLIB_AVAILABLE_IN_2_46 +void g_async_queue_push_front (GAsyncQueue *queue, + gpointer item); +GLIB_AVAILABLE_IN_2_46 +void g_async_queue_push_front_unlocked (GAsyncQueue *queue, + gpointer item); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_DEPRECATED_FOR(g_async_queue_timeout_pop) +gpointer g_async_queue_timed_pop (GAsyncQueue *queue, + GTimeVal *end_time); +GLIB_DEPRECATED_FOR(g_async_queue_timeout_pop_unlocked) +gpointer g_async_queue_timed_pop_unlocked (GAsyncQueue *queue, + GTimeVal *end_time); +G_GNUC_END_IGNORE_DEPRECATIONS + +G_END_DECLS + +#endif /* __G_ASYNCQUEUE_H__ */ diff --git a/glib/gasyncqueueprivate.h b/glib/gasyncqueueprivate.h new file mode 100644 index 0000000..b1622c5 --- /dev/null +++ b/glib/gasyncqueueprivate.h @@ -0,0 +1,29 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __G_ASYNCQUEUEPRIVATE_H__ +#define __G_ASYNCQUEUEPRIVATE_H__ + +#include "gasyncqueue.h" + +G_BEGIN_DECLS + +GMutex *_g_async_queue_get_mutex (GAsyncQueue *queue); + +G_END_DECLS + +#endif /* __G_ASYNCQUEUEPRIVATE_H__ */ diff --git a/glib/gatomic.c b/glib/gatomic.c new file mode 100644 index 0000000..0bc67aa --- /dev/null +++ b/glib/gatomic.c @@ -0,0 +1,967 @@ +/* + * Copyright © 2011 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gatomic.h" + +/** + * SECTION:atomic_operations + * @title: Atomic Operations + * @short_description: basic atomic integer and pointer operations + * @see_also: #GMutex + * + * The following is a collection of compiler macros to provide atomic + * access to integer and pointer-sized values. + * + * The macros that have 'int' in the name will operate on pointers to + * #gint and #guint. The macros with 'pointer' in the name will operate + * on pointers to any pointer-sized value, including #gsize. There is + * no support for 64bit operations on platforms with 32bit pointers + * because it is not generally possible to perform these operations + * atomically. + * + * The get, set and exchange operations for integers and pointers + * nominally operate on #gint and #gpointer, respectively. Of the + * arithmetic operations, the 'add' operation operates on (and returns) + * signed integer values (#gint and #gssize) and the 'and', 'or', and + * 'xor' operations operate on (and return) unsigned integer values + * (#guint and #gsize). + * + * All of the operations act as a full compiler and (where appropriate) + * hardware memory barrier. Acquire and release or producer and + * consumer barrier semantics are not available through this API. + * + * It is very important that all accesses to a particular integer or + * pointer be performed using only this API and that different sizes of + * operation are not mixed or used on overlapping memory regions. Never + * read or assign directly from or to a value -- always use this API. + * + * For simple reference counting purposes you should use + * g_atomic_int_inc() and g_atomic_int_dec_and_test(). Other uses that + * fall outside of simple reference counting patterns are prone to + * subtle bugs and occasionally undefined behaviour. It is also worth + * noting that since all of these operations require global + * synchronisation of the entire machine, they can be quite slow. In + * the case of performing multiple atomic operations it can often be + * faster to simply acquire a mutex lock around the critical area, + * perform the operations normally and then release the lock. + **/ + +/** + * G_ATOMIC_LOCK_FREE: + * + * This macro is defined if the atomic operations of GLib are + * implemented using real hardware atomic operations. This means that + * the GLib atomic API can be used between processes and safely mixed + * with other (hardware) atomic APIs. + * + * If this macro is not defined, the atomic operations may be + * emulated using a mutex. In that case, the GLib atomic operations are + * only atomic relative to themselves and within a single process. + **/ + +/* NOTE CAREFULLY: + * + * This file is the lowest-level part of GLib. + * + * Other lowlevel parts of GLib (threads, slice allocator, g_malloc, + * messages, etc) call into these functions and macros to get work done. + * + * As such, these functions can not call back into any part of GLib + * without risking recursion. + */ + +#ifdef G_ATOMIC_LOCK_FREE + +/* if G_ATOMIC_LOCK_FREE was defined by `meson configure` then we MUST + * implement the atomic operations in a lock-free manner. + */ + +#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + +/** + * g_atomic_int_get: + * @atomic: a pointer to a #gint or #guint + * + * Gets the current value of @atomic. + * + * This call acts as a full compiler and hardware + * memory barrier (before the get). + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of the integer + * + * Since: 2.4 + **/ +gint +(g_atomic_int_get) (const volatile gint *atomic) +{ + return g_atomic_int_get (atomic); +} + +/** + * g_atomic_int_set: + * @atomic: a pointer to a #gint or #guint + * @newval: a new value to store + * + * Sets the value of @atomic to @newval. + * + * This call acts as a full compiler and hardware + * memory barrier (after the set). + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Since: 2.4 + */ +void +(g_atomic_int_set) (volatile gint *atomic, + gint newval) +{ + g_atomic_int_set (atomic, newval); +} + +/** + * g_atomic_int_inc: + * @atomic: a pointer to a #gint or #guint + * + * Increments the value of @atomic by 1. + * + * Think of this operation as an atomic version of `{ *atomic += 1; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Since: 2.4 + **/ +void +(g_atomic_int_inc) (volatile gint *atomic) +{ + g_atomic_int_inc (atomic); +} + +/** + * g_atomic_int_dec_and_test: + * @atomic: a pointer to a #gint or #guint + * + * Decrements the value of @atomic by 1. + * + * Think of this operation as an atomic version of + * `{ *atomic -= 1; return (*atomic == 0); }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: %TRUE if the resultant value is zero + * + * Since: 2.4 + **/ +gboolean +(g_atomic_int_dec_and_test) (volatile gint *atomic) +{ + return g_atomic_int_dec_and_test (atomic); +} + +/** + * g_atomic_int_compare_and_exchange: + * @atomic: a pointer to a #gint or #guint + * @oldval: the value to compare with + * @newval: the value to conditionally replace with + * + * Compares @atomic to @oldval and, if equal, sets it to @newval. + * If @atomic was not equal to @oldval then no change occurs. + * + * This compare and exchange is done atomically. + * + * Think of this operation as an atomic version of + * `{ if (*atomic == oldval) { *atomic = newval; return TRUE; } else return FALSE; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: %TRUE if the exchange took place + * + * Since: 2.4 + **/ +gboolean +(g_atomic_int_compare_and_exchange) (volatile gint *atomic, + gint oldval, + gint newval) +{ + return g_atomic_int_compare_and_exchange (atomic, oldval, newval); +} + +/** + * g_atomic_int_add: + * @atomic: a pointer to a #gint or #guint + * @val: the value to add + * + * Atomically adds @val to the value of @atomic. + * + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic += val; return tmp; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * Before version 2.30, this function did not return a value + * (but g_atomic_int_exchange_and_add() did, and had the same meaning). + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of @atomic before the add, signed + * + * Since: 2.4 + **/ +gint +(g_atomic_int_add) (volatile gint *atomic, + gint val) +{ + return g_atomic_int_add (atomic, val); +} + +/** + * g_atomic_int_and: + * @atomic: a pointer to a #gint or #guint + * @val: the value to 'and' + * + * Performs an atomic bitwise 'and' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * This call acts as a full compiler and hardware memory barrier. + * + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic &= val; return tmp; }`. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +guint +(g_atomic_int_and) (volatile guint *atomic, + guint val) +{ + return g_atomic_int_and (atomic, val); +} + +/** + * g_atomic_int_or: + * @atomic: a pointer to a #gint or #guint + * @val: the value to 'or' + * + * Performs an atomic bitwise 'or' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic |= val; return tmp; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +guint +(g_atomic_int_or) (volatile guint *atomic, + guint val) +{ + return g_atomic_int_or (atomic, val); +} + +/** + * g_atomic_int_xor: + * @atomic: a pointer to a #gint or #guint + * @val: the value to 'xor' + * + * Performs an atomic bitwise 'xor' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic ^= val; return tmp; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +guint +(g_atomic_int_xor) (volatile guint *atomic, + guint val) +{ + return g_atomic_int_xor (atomic, val); +} + + +/** + * g_atomic_pointer_get: + * @atomic: (not nullable): a pointer to a #gpointer-sized value + * + * Gets the current value of @atomic. + * + * This call acts as a full compiler and hardware + * memory barrier (before the get). + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of the pointer + * + * Since: 2.4 + **/ +gpointer +(g_atomic_pointer_get) (const volatile void *atomic) +{ + return g_atomic_pointer_get ((gpointer *) atomic); +} + +/** + * g_atomic_pointer_set: + * @atomic: (not nullable): a pointer to a #gpointer-sized value + * @newval: a new value to store + * + * Sets the value of @atomic to @newval. + * + * This call acts as a full compiler and hardware + * memory barrier (after the set). + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Since: 2.4 + **/ +void +(g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) +{ + g_atomic_pointer_set ((gpointer *) atomic, newval); +} + +/** + * g_atomic_pointer_compare_and_exchange: + * @atomic: (not nullable): a pointer to a #gpointer-sized value + * @oldval: the value to compare with + * @newval: the value to conditionally replace with + * + * Compares @atomic to @oldval and, if equal, sets it to @newval. + * If @atomic was not equal to @oldval then no change occurs. + * + * This compare and exchange is done atomically. + * + * Think of this operation as an atomic version of + * `{ if (*atomic == oldval) { *atomic = newval; return TRUE; } else return FALSE; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: %TRUE if the exchange took place + * + * Since: 2.4 + **/ +gboolean +(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, + gpointer oldval, + gpointer newval) +{ + return g_atomic_pointer_compare_and_exchange ((gpointer *) atomic, + oldval, newval); +} + +/** + * g_atomic_pointer_add: + * @atomic: (not nullable): a pointer to a #gpointer-sized value + * @val: the value to add + * + * Atomically adds @val to the value of @atomic. + * + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic += val; return tmp; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of @atomic before the add, signed + * + * Since: 2.30 + **/ +gssize +(g_atomic_pointer_add) (volatile void *atomic, + gssize val) +{ + return g_atomic_pointer_add ((gpointer *) atomic, val); +} + +/** + * g_atomic_pointer_and: + * @atomic: (not nullable): a pointer to a #gpointer-sized value + * @val: the value to 'and' + * + * Performs an atomic bitwise 'and' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic &= val; return tmp; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +gsize +(g_atomic_pointer_and) (volatile void *atomic, + gsize val) +{ + return g_atomic_pointer_and ((gpointer *) atomic, val); +} + +/** + * g_atomic_pointer_or: + * @atomic: (not nullable): a pointer to a #gpointer-sized value + * @val: the value to 'or' + * + * Performs an atomic bitwise 'or' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic |= val; return tmp; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +gsize +(g_atomic_pointer_or) (volatile void *atomic, + gsize val) +{ + return g_atomic_pointer_or ((gpointer *) atomic, val); +} + +/** + * g_atomic_pointer_xor: + * @atomic: (not nullable): a pointer to a #gpointer-sized value + * @val: the value to 'xor' + * + * Performs an atomic bitwise 'xor' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic ^= val; return tmp; }`. + * + * This call acts as a full compiler and hardware memory barrier. + * + * While @atomic has a `volatile` qualifier, this is a historical artifact and + * the pointer passed to it should not be `volatile`. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +gsize +(g_atomic_pointer_xor) (volatile void *atomic, + gsize val) +{ + return g_atomic_pointer_xor ((gpointer *) atomic, val); +} + +#elif defined (G_PLATFORM_WIN32) + +#include +#if !defined(_M_AMD64) && !defined (_M_IA64) && !defined(_M_X64) && !(defined _MSC_VER && _MSC_VER <= 1200) +#define InterlockedAnd _InterlockedAnd +#define InterlockedOr _InterlockedOr +#define InterlockedXor _InterlockedXor +#endif + +#if !defined (_MSC_VER) || _MSC_VER <= 1200 +#include "gmessages.h" +/* Inlined versions for older compiler */ +static LONG +_gInterlockedAnd (volatile guint *atomic, + guint val) +{ + LONG i, j; + + j = *atomic; + do { + i = j; + j = InterlockedCompareExchange(atomic, i & val, i); + } while (i != j); + + return j; +} +#define InterlockedAnd(a,b) _gInterlockedAnd(a,b) +static LONG +_gInterlockedOr (volatile guint *atomic, + guint val) +{ + LONG i, j; + + j = *atomic; + do { + i = j; + j = InterlockedCompareExchange(atomic, i | val, i); + } while (i != j); + + return j; +} +#define InterlockedOr(a,b) _gInterlockedOr(a,b) +static LONG +_gInterlockedXor (volatile guint *atomic, + guint val) +{ + LONG i, j; + + j = *atomic; + do { + i = j; + j = InterlockedCompareExchange(atomic, i ^ val, i); + } while (i != j); + + return j; +} +#define InterlockedXor(a,b) _gInterlockedXor(a,b) +#endif + +/* + * http://msdn.microsoft.com/en-us/library/ms684122(v=vs.85).aspx + */ +gint +(g_atomic_int_get) (const volatile gint *atomic) +{ + MemoryBarrier (); + return *atomic; +} + +void +(g_atomic_int_set) (volatile gint *atomic, + gint newval) +{ + *atomic = newval; + MemoryBarrier (); +} + +void +(g_atomic_int_inc) (volatile gint *atomic) +{ + InterlockedIncrement (atomic); +} + +gboolean +(g_atomic_int_dec_and_test) (volatile gint *atomic) +{ + return InterlockedDecrement (atomic) == 0; +} + +gboolean +(g_atomic_int_compare_and_exchange) (volatile gint *atomic, + gint oldval, + gint newval) +{ + return InterlockedCompareExchange (atomic, newval, oldval) == oldval; +} + +gint +(g_atomic_int_add) (volatile gint *atomic, + gint val) +{ + return InterlockedExchangeAdd (atomic, val); +} + +guint +(g_atomic_int_and) (volatile guint *atomic, + guint val) +{ + return InterlockedAnd (atomic, val); +} + +guint +(g_atomic_int_or) (volatile guint *atomic, + guint val) +{ + return InterlockedOr (atomic, val); +} + +guint +(g_atomic_int_xor) (volatile guint *atomic, + guint val) +{ + return InterlockedXor (atomic, val); +} + + +gpointer +(g_atomic_pointer_get) (const volatile void *atomic) +{ + const gpointer *ptr = atomic; + + MemoryBarrier (); + return *ptr; +} + +void +(g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) +{ + gpointer *ptr = atomic; + + *ptr = newval; + MemoryBarrier (); +} + +gboolean +(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, + gpointer oldval, + gpointer newval) +{ + return InterlockedCompareExchangePointer (atomic, newval, oldval) == oldval; +} + +gssize +(g_atomic_pointer_add) (volatile void *atomic, + gssize val) +{ +#if GLIB_SIZEOF_VOID_P == 8 + return InterlockedExchangeAdd64 (atomic, val); +#else + return InterlockedExchangeAdd (atomic, val); +#endif +} + +gsize +(g_atomic_pointer_and) (volatile void *atomic, + gsize val) +{ +#if GLIB_SIZEOF_VOID_P == 8 + return InterlockedAnd64 (atomic, val); +#else + return InterlockedAnd (atomic, val); +#endif +} + +gsize +(g_atomic_pointer_or) (volatile void *atomic, + gsize val) +{ +#if GLIB_SIZEOF_VOID_P == 8 + return InterlockedOr64 (atomic, val); +#else + return InterlockedOr (atomic, val); +#endif +} + +gsize +(g_atomic_pointer_xor) (volatile void *atomic, + gsize val) +{ +#if GLIB_SIZEOF_VOID_P == 8 + return InterlockedXor64 (atomic, val); +#else + return InterlockedXor (atomic, val); +#endif +} +#else + +/* This error occurs when `meson configure` decided that we should be capable + * of lock-free atomics but we find at compile-time that we are not. + */ +#error G_ATOMIC_LOCK_FREE defined, but incapable of lock-free atomics. + +#endif /* defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) */ + +#else /* G_ATOMIC_LOCK_FREE */ + +/* We are not permitted to call into any GLib functions from here, so we + * can not use GMutex. + * + * Fortunately, we already take care of the Windows case above, and all + * non-Windows platforms on which glib runs have pthreads. Use those. + */ +#include + +static pthread_mutex_t g_atomic_lock = PTHREAD_MUTEX_INITIALIZER; + +gint +(g_atomic_int_get) (const volatile gint *atomic) +{ + gint value; + + pthread_mutex_lock (&g_atomic_lock); + value = *atomic; + pthread_mutex_unlock (&g_atomic_lock); + + return value; +} + +void +(g_atomic_int_set) (volatile gint *atomic, + gint value) +{ + pthread_mutex_lock (&g_atomic_lock); + *atomic = value; + pthread_mutex_unlock (&g_atomic_lock); +} + +void +(g_atomic_int_inc) (volatile gint *atomic) +{ + pthread_mutex_lock (&g_atomic_lock); + (*atomic)++; + pthread_mutex_unlock (&g_atomic_lock); +} + +gboolean +(g_atomic_int_dec_and_test) (volatile gint *atomic) +{ + gboolean is_zero; + + pthread_mutex_lock (&g_atomic_lock); + is_zero = --(*atomic) == 0; + pthread_mutex_unlock (&g_atomic_lock); + + return is_zero; +} + +gboolean +(g_atomic_int_compare_and_exchange) (volatile gint *atomic, + gint oldval, + gint newval) +{ + gboolean success; + + pthread_mutex_lock (&g_atomic_lock); + + if ((success = (*atomic == oldval))) + *atomic = newval; + + pthread_mutex_unlock (&g_atomic_lock); + + return success; +} + +gint +(g_atomic_int_add) (volatile gint *atomic, + gint val) +{ + gint oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *atomic; + *atomic = oldval + val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +guint +(g_atomic_int_and) (volatile guint *atomic, + guint val) +{ + guint oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *atomic; + *atomic = oldval & val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +guint +(g_atomic_int_or) (volatile guint *atomic, + guint val) +{ + guint oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *atomic; + *atomic = oldval | val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +guint +(g_atomic_int_xor) (volatile guint *atomic, + guint val) +{ + guint oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *atomic; + *atomic = oldval ^ val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + + +gpointer +(g_atomic_pointer_get) (const volatile void *atomic) +{ + const gpointer *ptr = atomic; + gpointer value; + + pthread_mutex_lock (&g_atomic_lock); + value = *ptr; + pthread_mutex_unlock (&g_atomic_lock); + + return value; +} + +void +(g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) +{ + gpointer *ptr = atomic; + + pthread_mutex_lock (&g_atomic_lock); + *ptr = newval; + pthread_mutex_unlock (&g_atomic_lock); +} + +gboolean +(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, + gpointer oldval, + gpointer newval) +{ + gpointer *ptr = atomic; + gboolean success; + + pthread_mutex_lock (&g_atomic_lock); + + if ((success = (*ptr == oldval))) + *ptr = newval; + + pthread_mutex_unlock (&g_atomic_lock); + + return success; +} + +gssize +(g_atomic_pointer_add) (volatile void *atomic, + gssize val) +{ + gssize *ptr = atomic; + gssize oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *ptr; + *ptr = oldval + val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +gsize +(g_atomic_pointer_and) (volatile void *atomic, + gsize val) +{ + gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *ptr; + *ptr = oldval & val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +gsize +(g_atomic_pointer_or) (volatile void *atomic, + gsize val) +{ + gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *ptr; + *ptr = oldval | val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +gsize +(g_atomic_pointer_xor) (volatile void *atomic, + gsize val) +{ + gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *ptr; + *ptr = oldval ^ val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +#endif + +/** + * g_atomic_int_exchange_and_add: + * @atomic: a pointer to a #gint + * @val: the value to add + * + * This function existed before g_atomic_int_add() returned the prior + * value of the integer (which it now does). It is retained only for + * compatibility reasons. Don't use this function in new code. + * + * Returns: the value of @atomic before the add, signed + * Since: 2.4 + * Deprecated: 2.30: Use g_atomic_int_add() instead. + **/ +gint +g_atomic_int_exchange_and_add (volatile gint *atomic, + gint val) +{ + return (g_atomic_int_add) ((gint *) atomic, val); +} diff --git a/glib/gatomic.h b/glib/gatomic.h new file mode 100644 index 0000000..8b2b880 --- /dev/null +++ b/glib/gatomic.h @@ -0,0 +1,470 @@ +/* + * Copyright © 2011 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_ATOMIC_H__ +#define __G_ATOMIC_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +gint g_atomic_int_get (const volatile gint *atomic); +GLIB_AVAILABLE_IN_ALL +void g_atomic_int_set (volatile gint *atomic, + gint newval); +GLIB_AVAILABLE_IN_ALL +void g_atomic_int_inc (volatile gint *atomic); +GLIB_AVAILABLE_IN_ALL +gboolean g_atomic_int_dec_and_test (volatile gint *atomic); +GLIB_AVAILABLE_IN_ALL +gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic, + gint oldval, + gint newval); +GLIB_AVAILABLE_IN_ALL +gint g_atomic_int_add (volatile gint *atomic, + gint val); +GLIB_AVAILABLE_IN_2_30 +guint g_atomic_int_and (volatile guint *atomic, + guint val); +GLIB_AVAILABLE_IN_2_30 +guint g_atomic_int_or (volatile guint *atomic, + guint val); +GLIB_AVAILABLE_IN_ALL +guint g_atomic_int_xor (volatile guint *atomic, + guint val); + +GLIB_AVAILABLE_IN_ALL +gpointer g_atomic_pointer_get (const volatile void *atomic); +GLIB_AVAILABLE_IN_ALL +void g_atomic_pointer_set (volatile void *atomic, + gpointer newval); +GLIB_AVAILABLE_IN_ALL +gboolean g_atomic_pointer_compare_and_exchange (volatile void *atomic, + gpointer oldval, + gpointer newval); +GLIB_AVAILABLE_IN_ALL +gssize g_atomic_pointer_add (volatile void *atomic, + gssize val); +GLIB_AVAILABLE_IN_2_30 +gsize g_atomic_pointer_and (volatile void *atomic, + gsize val); +GLIB_AVAILABLE_IN_2_30 +gsize g_atomic_pointer_or (volatile void *atomic, + gsize val); +GLIB_AVAILABLE_IN_ALL +gsize g_atomic_pointer_xor (volatile void *atomic, + gsize val); + +GLIB_DEPRECATED_IN_2_30_FOR(g_atomic_int_add) +gint g_atomic_int_exchange_and_add (volatile gint *atomic, + gint val); + +G_END_DECLS + +#if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + +/* We prefer the new C11-style atomic extension of GCC if available */ +#if defined(__ATOMIC_SEQ_CST) + +#define g_atomic_int_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + gint gaig_temp; \ + (void) (0 ? *(atomic) ^ *(atomic) : 1); \ + __atomic_load ((gint *)(atomic), &gaig_temp, __ATOMIC_SEQ_CST); \ + (gint) gaig_temp; \ + })) +#define g_atomic_int_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + gint gais_temp = (gint) (newval); \ + (void) (0 ? *(atomic) ^ (newval) : 1); \ + __atomic_store ((gint *)(atomic), &gais_temp, __ATOMIC_SEQ_CST); \ + })) + +#if defined(glib_typeof) +#define g_atomic_pointer_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + glib_typeof (*(atomic)) gapg_temp_newval; \ + glib_typeof ((atomic)) gapg_temp_atomic = (atomic); \ + __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \ + gapg_temp_newval; \ + })) +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + glib_typeof ((atomic)) gaps_temp_atomic = (atomic); \ + glib_typeof (*(atomic)) gaps_temp_newval = (newval); \ + (void) (0 ? (gpointer) * (atomic) : NULL); \ + __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \ + })) +#else /* if !(defined(glib_typeof) */ +#define g_atomic_pointer_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + gpointer gapg_temp_newval; \ + gpointer *gapg_temp_atomic = (gpointer *)(atomic); \ + __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \ + gapg_temp_newval; \ + })) +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + gpointer *gaps_temp_atomic = (gpointer *)(atomic); \ + gpointer gaps_temp_newval = (gpointer)(newval); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \ + })) +#endif /* if defined(glib_typeof) */ + +#define g_atomic_int_inc(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 1); \ + (void) __atomic_fetch_add ((atomic), 1, __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_int_dec_and_test(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 1); \ + __atomic_fetch_sub ((atomic), 1, __ATOMIC_SEQ_CST) == 1; \ + })) +#if defined(glib_typeof) && defined(__cplusplus) && __cplusplus >= 201103L +/* See comments below about equivalent g_atomic_pointer_compare_and_exchange() + * shenanigans for type-safety when compiling in C++ mode. */ +#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + glib_typeof (*(atomic)) gaicae_oldval = (oldval); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 1); \ + __atomic_compare_exchange_n ((atomic), &gaicae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \ + })) +#else /* if !(defined(glib_typeof) && defined(__cplusplus) && __cplusplus >= 201103L) */ +#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + gint gaicae_oldval = (oldval); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 1); \ + __atomic_compare_exchange_n ((atomic), (void *) (&(gaicae_oldval)), (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \ + })) +#endif /* defined(glib_typeof) */ +#define g_atomic_int_add(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 1); \ + (gint) __atomic_fetch_add ((atomic), (val), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_int_and(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 1); \ + (guint) __atomic_fetch_and ((atomic), (val), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_int_or(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 1); \ + (guint) __atomic_fetch_or ((atomic), (val), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_int_xor(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 1); \ + (guint) __atomic_fetch_xor ((atomic), (val), __ATOMIC_SEQ_CST); \ + })) + +#if defined(glib_typeof) && defined(__cplusplus) && __cplusplus >= 201103L +/* This is typesafe because we check we can assign oldval to the type of + * (*atomic). Unfortunately it can only be done in C++ because gcc/clang warn + * when atomic is volatile and not oldval, or when atomic is gsize* and oldval + * is NULL. Note that clang++ force us to be typesafe because it is an error if the 2nd + * argument of __atomic_compare_exchange_n() has a different type than the + * first. + * https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1919 + * https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1715#note_1024120. */ +#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof (oldval) == sizeof (gpointer)); \ + glib_typeof (*(atomic)) gapcae_oldval = (oldval); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + __atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \ + })) +#else /* if !(defined(glib_typeof) && defined(__cplusplus) && __cplusplus >= 201103L) */ +#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof (oldval) == sizeof (gpointer)); \ + gpointer gapcae_oldval = (gpointer)(oldval); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + __atomic_compare_exchange_n ((atomic), (void *) (&(gapcae_oldval)), (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \ + })) +#endif /* defined(glib_typeof) */ +#define g_atomic_pointer_add(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + (void) (0 ? (val) ^ (val) : 1); \ + (gssize) __atomic_fetch_add ((atomic), (val), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_pointer_and(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + gsize *gapa_atomic = (gsize *) (atomic); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + (void) (0 ? (val) ^ (val) : 1); \ + (gsize) __atomic_fetch_and (gapa_atomic, (val), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_pointer_or(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + gsize *gapo_atomic = (gsize *) (atomic); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + (void) (0 ? (val) ^ (val) : 1); \ + (gsize) __atomic_fetch_or (gapo_atomic, (val), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_pointer_xor(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + gsize *gapx_atomic = (gsize *) (atomic); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + (void) (0 ? (val) ^ (val) : 1); \ + (gsize) __atomic_fetch_xor (gapx_atomic, (val), __ATOMIC_SEQ_CST); \ + })) + +#else /* defined(__ATOMIC_SEQ_CST) */ + +/* We want to achieve __ATOMIC_SEQ_CST semantics here. See + * https://en.cppreference.com/w/c/atomic/memory_order#Constants. For load + * operations, that means performing an *acquire*: + * > A load operation with this memory order performs the acquire operation on + * > the affected memory location: no reads or writes in the current thread can + * > be reordered before this load. All writes in other threads that release + * > the same atomic variable are visible in the current thread. + * + * “no reads or writes in the current thread can be reordered before this load†+ * is implemented using a compiler barrier (a no-op `__asm__` section) to + * prevent instruction reordering. Writes in other threads are synchronised + * using `__sync_synchronize()`. It’s unclear from the GCC documentation whether + * `__sync_synchronize()` acts as a compiler barrier, hence our explicit use of + * one. + * + * For store operations, `__ATOMIC_SEQ_CST` means performing a *release*: + * > A store operation with this memory order performs the release operation: + * > no reads or writes in the current thread can be reordered after this store. + * > All writes in the current thread are visible in other threads that acquire + * > the same atomic variable (see Release-Acquire ordering below) and writes + * > that carry a dependency into the atomic variable become visible in other + * > threads that consume the same atomic (see Release-Consume ordering below). + * + * “no reads or writes in the current thread can be reordered after this store†+ * is implemented using a compiler barrier to prevent instruction reordering. + * “All writes in the current thread are visible in other threads†is implemented + * using `__sync_synchronize()`; similarly for “writes that carry a dependencyâ€. + */ +#define g_atomic_int_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + gint gaig_result; \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 1); \ + gaig_result = (gint) *(atomic); \ + __sync_synchronize (); \ + __asm__ __volatile__ ("" : : : "memory"); \ + gaig_result; \ + })) +#define g_atomic_int_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (newval) : 1); \ + __sync_synchronize (); \ + __asm__ __volatile__ ("" : : : "memory"); \ + *(atomic) = (newval); \ + })) +#define g_atomic_pointer_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + gpointer gapg_result; \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + gapg_result = (gpointer) *(atomic); \ + __sync_synchronize (); \ + __asm__ __volatile__ ("" : : : "memory"); \ + gapg_result; \ + })) +#if defined(glib_typeof) +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + __sync_synchronize (); \ + __asm__ __volatile__ ("" : : : "memory"); \ + *(atomic) = (glib_typeof (*(atomic))) (gsize) (newval); \ + })) +#else /* if !(defined(glib_typeof) */ +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + __sync_synchronize (); \ + __asm__ __volatile__ ("" : : : "memory"); \ + *(atomic) = (gpointer) (gsize) (newval); \ + })) +#endif /* if defined(glib_typeof) */ + +#define g_atomic_int_inc(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 1); \ + (void) __sync_fetch_and_add ((atomic), 1); \ + })) +#define g_atomic_int_dec_and_test(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 1); \ + __sync_fetch_and_sub ((atomic), 1) == 1; \ + })) +#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 1); \ + __sync_bool_compare_and_swap ((atomic), (oldval), (newval)) ? TRUE : FALSE; \ + })) +#define g_atomic_int_add(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 1); \ + (gint) __sync_fetch_and_add ((atomic), (val)); \ + })) +#define g_atomic_int_and(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 1); \ + (guint) __sync_fetch_and_and ((atomic), (val)); \ + })) +#define g_atomic_int_or(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 1); \ + (guint) __sync_fetch_and_or ((atomic), (val)); \ + })) +#define g_atomic_int_xor(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 1); \ + (guint) __sync_fetch_and_xor ((atomic), (val)); \ + })) + +#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + __sync_bool_compare_and_swap ((atomic), (oldval), (newval)) ? TRUE : FALSE; \ + })) +#define g_atomic_pointer_add(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + (void) (0 ? (val) ^ (val) : 1); \ + (gssize) __sync_fetch_and_add ((atomic), (val)); \ + })) +#define g_atomic_pointer_and(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + (void) (0 ? (val) ^ (val) : 1); \ + (gsize) __sync_fetch_and_and ((atomic), (val)); \ + })) +#define g_atomic_pointer_or(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + (void) (0 ? (val) ^ (val) : 1); \ + (gsize) __sync_fetch_and_or ((atomic), (val)); \ + })) +#define g_atomic_pointer_xor(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + (void) (0 ? (val) ^ (val) : 1); \ + (gsize) __sync_fetch_and_xor ((atomic), (val)); \ + })) + +#endif /* !defined(__ATOMIC_SEQ_CST) */ + +#else /* defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) */ + +#define g_atomic_int_get(atomic) \ + (g_atomic_int_get ((gint *) (atomic))) +#define g_atomic_int_set(atomic, newval) \ + (g_atomic_int_set ((gint *) (atomic), (gint) (newval))) +#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ + (g_atomic_int_compare_and_exchange ((gint *) (atomic), (oldval), (newval))) +#define g_atomic_int_add(atomic, val) \ + (g_atomic_int_add ((gint *) (atomic), (val))) +#define g_atomic_int_and(atomic, val) \ + (g_atomic_int_and ((guint *) (atomic), (val))) +#define g_atomic_int_or(atomic, val) \ + (g_atomic_int_or ((guint *) (atomic), (val))) +#define g_atomic_int_xor(atomic, val) \ + (g_atomic_int_xor ((guint *) (atomic), (val))) +#define g_atomic_int_inc(atomic) \ + (g_atomic_int_inc ((gint *) (atomic))) +#define g_atomic_int_dec_and_test(atomic) \ + (g_atomic_int_dec_and_test ((gint *) (atomic))) + +#if defined(glib_typeof) + /* The (void *) cast in the middle *looks* redundant, because + * g_atomic_pointer_get returns void * already, but it's to silence + * -Werror=bad-function-cast when we're doing something like: + * guintptr a, b; ...; a = g_atomic_pointer_get (&b); + * which would otherwise be assigning the void * result of + * g_atomic_pointer_get directly to the pointer-sized but + * non-pointer-typed result. */ +#define g_atomic_pointer_get(atomic) \ + (glib_typeof (*(atomic))) (void *) ((g_atomic_pointer_get) ((void *) atomic)) +#else /* !(defined(glib_typeof) */ +#define g_atomic_pointer_get(atomic) \ + (g_atomic_pointer_get (atomic)) +#endif + +#define g_atomic_pointer_set(atomic, newval) \ + (g_atomic_pointer_set ((atomic), (gpointer) (newval))) + +#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ + (g_atomic_pointer_compare_and_exchange ((atomic), (gpointer) (oldval), (gpointer) (newval))) +#define g_atomic_pointer_add(atomic, val) \ + (g_atomic_pointer_add ((atomic), (gssize) (val))) +#define g_atomic_pointer_and(atomic, val) \ + (g_atomic_pointer_and ((atomic), (gsize) (val))) +#define g_atomic_pointer_or(atomic, val) \ + (g_atomic_pointer_or ((atomic), (gsize) (val))) +#define g_atomic_pointer_xor(atomic, val) \ + (g_atomic_pointer_xor ((atomic), (gsize) (val))) + +#endif /* defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) */ + +#endif /* __G_ATOMIC_H__ */ diff --git a/glib/gbacktrace.c b/glib/gbacktrace.c new file mode 100644 index 0000000..77cef10 --- /dev/null +++ b/glib/gbacktrace.c @@ -0,0 +1,455 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe ; except for g_on_error_stack_trace, but who wants thread safety + * then + */ + +#include "config.h" +#include "glibconfig.h" + +#include +#include +#include +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#include + +#include + +#ifdef G_OS_UNIX +#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ +#endif + +#include + +#ifdef G_OS_WIN32 +# define STRICT /* Strict typing, please */ +# define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */ +# include +# undef STRICT +#else +# include +#endif + +#include "gbacktrace.h" + +#include "gtypes.h" +#include "gmain.h" +#include "gprintfint.h" +#include "gunicode.h" +#include "gutils.h" + +#ifndef G_OS_WIN32 +static void stack_trace (const char * const *args); +#endif + +/* Default to using LLDB for backtraces on macOS. */ +#ifdef __APPLE__ +#define USE_LLDB +#endif + +#ifdef USE_LLDB +#define DEBUGGER "lldb" +#else +#define DEBUGGER "gdb" +#endif + +/* People want to hit this from their debugger... */ +GLIB_AVAILABLE_IN_ALL volatile gboolean glib_on_error_halt; +volatile gboolean glib_on_error_halt = TRUE; + +/** + * g_on_error_query: + * @prg_name: the program name, needed by gdb for the "[S]tack trace" + * option. If @prg_name is %NULL, g_get_prgname() is called to get + * the program name (which will work correctly if gdk_init() or + * gtk_init() has been called) + * + * Prompts the user with + * `[E]xit, [H]alt, show [S]tack trace or [P]roceed`. + * This function is intended to be used for debugging use only. + * The following example shows how it can be used together with + * the g_log() functions. + * + * |[ + * #include + * + * static void + * log_handler (const gchar *log_domain, + * GLogLevelFlags log_level, + * const gchar *message, + * gpointer user_data) + * { + * g_log_default_handler (log_domain, log_level, message, user_data); + * + * g_on_error_query (MY_PROGRAM_NAME); + * } + * + * int + * main (int argc, char *argv[]) + * { + * g_log_set_handler (MY_LOG_DOMAIN, + * G_LOG_LEVEL_WARNING | + * G_LOG_LEVEL_ERROR | + * G_LOG_LEVEL_CRITICAL, + * log_handler, + * NULL); + * ... + * ]| + * + * If "[E]xit" is selected, the application terminates with a call + * to _exit(0). + * + * If "[S]tack" trace is selected, g_on_error_stack_trace() is called. + * This invokes gdb, which attaches to the current process and shows + * a stack trace. The prompt is then shown again. + * + * If "[P]roceed" is selected, the function returns. + * + * This function may cause different actions on non-UNIX platforms. + * + * On Windows consider using the `G_DEBUGGER` environment + * variable (see [Running GLib Applications](glib-running.html)) and + * calling g_on_error_stack_trace() instead. + */ +void +g_on_error_query (const gchar *prg_name) +{ +#ifndef G_OS_WIN32 + static const gchar * const query1 = "[E]xit, [H]alt"; + static const gchar * const query2 = ", show [S]tack trace"; + static const gchar * const query3 = " or [P]roceed"; + gchar buf[16]; + + if (!prg_name) + prg_name = g_get_prgname (); + + retry: + + if (prg_name) + _g_fprintf (stdout, + "%s (pid:%u): %s%s%s: ", + prg_name, + (guint) getpid (), + query1, + query2, + query3); + else + _g_fprintf (stdout, + "(process:%u): %s%s: ", + (guint) getpid (), + query1, + query3); + fflush (stdout); + + if (isatty(0) && isatty(1)) + fgets (buf, 8, stdin); + else + strcpy (buf, "E\n"); + + if ((buf[0] == 'E' || buf[0] == 'e') + && buf[1] == '\n') + _exit (0); + else if ((buf[0] == 'P' || buf[0] == 'p') + && buf[1] == '\n') + return; + else if (prg_name + && (buf[0] == 'S' || buf[0] == 's') + && buf[1] == '\n') + { + g_on_error_stack_trace (prg_name); + goto retry; + } + else if ((buf[0] == 'H' || buf[0] == 'h') + && buf[1] == '\n') + { + while (glib_on_error_halt) + ; + glib_on_error_halt = TRUE; + return; + } + else + goto retry; +#else + if (!prg_name) + prg_name = g_get_prgname (); + + /* MessageBox is allowed on UWP apps only when building against + * the debug CRT, which will set -D_DEBUG */ +#if defined(_DEBUG) || !defined(G_WINAPI_ONLY_APP) + { + WCHAR *caption = NULL; + + if (prg_name && *prg_name) + { + caption = g_utf8_to_utf16 (prg_name, -1, NULL, NULL, NULL); + } + + MessageBoxW (NULL, L"g_on_error_query called, program terminating", + caption, + MB_OK|MB_ICONERROR); + + g_free (caption); + } +#else + printf ("g_on_error_query called, program '%s' terminating\n", + (prg_name && *prg_name) ? prg_name : "(null)"); +#endif + _exit(0); +#endif +} + +/** + * g_on_error_stack_trace: + * @prg_name: the program name, needed by gdb for the "[S]tack trace" + * option + * + * Invokes gdb, which attaches to the current process and shows a + * stack trace. Called by g_on_error_query() when the "[S]tack trace" + * option is selected. You can get the current process's program name + * with g_get_prgname(), assuming that you have called gtk_init() or + * gdk_init(). + * + * This function may cause different actions on non-UNIX platforms. + * + * When running on Windows, this function is *not* called by + * g_on_error_query(). If called directly, it will raise an + * exception, which will crash the program. If the `G_DEBUGGER` environment + * variable is set, a debugger will be invoked to attach and + * handle that exception (see [Running GLib Applications](glib-running.html)). + */ +void +g_on_error_stack_trace (const gchar *prg_name) +{ +#if defined(G_OS_UNIX) + pid_t pid; + gchar buf[16]; + const gchar *args[5] = { DEBUGGER, NULL, NULL, NULL, NULL }; + int status; + + if (!prg_name) + return; + + _g_sprintf (buf, "%u", (guint) getpid ()); + +#ifdef USE_LLDB + args[1] = prg_name; + args[2] = "-p"; + args[3] = buf; +#else + args[1] = prg_name; + args[2] = buf; +#endif + + pid = fork (); + if (pid == 0) + { + stack_trace (args); + _exit (0); + } + else if (pid == (pid_t) -1) + { + perror ("unable to fork " DEBUGGER); + return; + } + + /* Wait until the child really terminates. On Mac OS X waitpid () + * will also return when the child is being stopped due to tracing. + */ + while (1) + { + pid_t retval = waitpid (pid, &status, 0); + if (WIFEXITED (retval) || WIFSIGNALED (retval)) + break; + } +#else + if (IsDebuggerPresent ()) + G_BREAKPOINT (); + else + g_abort (); +#endif +} + +#ifndef G_OS_WIN32 + +static gboolean stack_trace_done = FALSE; + +static void +stack_trace_sigchld (int signum) +{ + stack_trace_done = TRUE; +} + +#define BUFSIZE 1024 + +static void +stack_trace (const char * const *args) +{ + pid_t pid; + int in_fd[2]; + int out_fd[2]; + fd_set fdset; + fd_set readset; + struct timeval tv; + int sel, idx, state; +#ifdef USE_LLDB + int line_idx; +#endif + char buffer[BUFSIZE]; + char c; + + stack_trace_done = FALSE; + signal (SIGCHLD, stack_trace_sigchld); + + if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1)) + { + perror ("unable to open pipe"); + _exit (0); + } + + pid = fork (); + if (pid == 0) + { + /* Save stderr for printing failure below */ + int old_err = dup (2); + if (old_err != -1) + { + int getfd = fcntl (old_err, F_GETFD); + if (getfd != -1) + (void) fcntl (old_err, F_SETFD, getfd | FD_CLOEXEC); + } + + close (0); dup (in_fd[0]); /* set the stdin to the in pipe */ + close (1); dup (out_fd[1]); /* set the stdout to the out pipe */ + close (2); dup (out_fd[1]); /* set the stderr to the out pipe */ + + execvp (args[0], (char **) args); /* exec gdb */ + + /* Print failure to original stderr */ + if (old_err != -1) + { + close (2); + dup (old_err); + } + perror ("exec " DEBUGGER " failed"); + _exit (0); + } + else if (pid == (pid_t) -1) + { + perror ("unable to fork"); + _exit (0); + } + + FD_ZERO (&fdset); + FD_SET (out_fd[0], &fdset); + +#ifdef USE_LLDB + write (in_fd[1], "bt\n", 3); + write (in_fd[1], "p x = 0\n", 8); + write (in_fd[1], "process detach\n", 15); + write (in_fd[1], "quit\n", 5); +#else + write (in_fd[1], "backtrace\n", 10); + write (in_fd[1], "p x = 0\n", 8); + write (in_fd[1], "quit\n", 5); +#endif + + idx = 0; +#ifdef USE_LLDB + line_idx = 0; +#endif + state = 0; + + while (1) + { + readset = fdset; + tv.tv_sec = 1; + tv.tv_usec = 0; + + sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv); + if (sel == -1) + break; + + if ((sel > 0) && (FD_ISSET (out_fd[0], &readset))) + { + if (read (out_fd[0], &c, 1)) + { +#ifdef USE_LLDB + line_idx += 1; +#endif + + switch (state) + { + case 0: +#ifdef USE_LLDB + if (c == '*' || (c == ' ' && line_idx == 1)) +#else + if (c == '#') +#endif + { + state = 1; + idx = 0; + buffer[idx++] = c; + } + break; + case 1: + if (idx < BUFSIZE) + buffer[idx++] = c; + if ((c == '\n') || (c == '\r')) + { + buffer[idx] = 0; + _g_fprintf (stdout, "%s", buffer); + state = 0; + idx = 0; +#ifdef USE_LLDB + line_idx = 0; +#endif + } + break; + default: + break; + } + } + } + else if (stack_trace_done) + break; + } + + close (in_fd[0]); + close (in_fd[1]); + close (out_fd[0]); + close (out_fd[1]); + _exit (0); +} + +#endif /* !G_OS_WIN32 */ diff --git a/glib/gbacktrace.h b/glib/gbacktrace.h new file mode 100644 index 0000000..09b8ccb --- /dev/null +++ b/glib/gbacktrace.h @@ -0,0 +1,72 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_BACKTRACE_H__ +#define __G_BACKTRACE_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#ifdef __sun__ +#include +#endif +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +void g_on_error_query (const gchar *prg_name); +GLIB_AVAILABLE_IN_ALL +void g_on_error_stack_trace (const gchar *prg_name); + +/** + * G_BREAKPOINT: + * + * Inserts a breakpoint instruction into the code. + * + * On architectures which support it, this is implemented as a soft interrupt + * and on other architectures it raises a `SIGTRAP` signal. + * + * `SIGTRAP` is used rather than abort() to allow breakpoints to be skipped past + * in a debugger if they are not the desired target of debugging. + */ +#if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__) && __GNUC__ >= 2 +# define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("int $03"); }G_STMT_END +#elif (defined (_MSC_VER) || defined (__DMC__)) && defined (_M_IX86) +# define G_BREAKPOINT() G_STMT_START{ __asm int 3h }G_STMT_END +#elif defined (_MSC_VER) +# define G_BREAKPOINT() G_STMT_START{ __debugbreak(); }G_STMT_END +#elif defined (__alpha__) && !defined(__osf__) && defined (__GNUC__) && __GNUC__ >= 2 +# define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("bpt"); }G_STMT_END +#elif defined (__APPLE__) || (defined(_WIN32) && (defined(__clang__) || defined(__GNUC__))) +# define G_BREAKPOINT() G_STMT_START{ __builtin_trap(); }G_STMT_END +#else /* !__i386__ && !__alpha__ */ +# define G_BREAKPOINT() G_STMT_START{ raise (SIGTRAP); }G_STMT_END +#endif /* __i386__ */ + +G_END_DECLS + +#endif /* __G_BACKTRACE_H__ */ diff --git a/glib/gbase64.c b/glib/gbase64.c new file mode 100644 index 0000000..f2d110e --- /dev/null +++ b/glib/gbase64.c @@ -0,0 +1,462 @@ +/* gbase64.c - Base64 encoding/decoding + * + * Copyright (C) 2006 Alexander Larsson + * Copyright (C) 2000-2003 Ximian Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + * + * This is based on code in camel, written by: + * Michael Zucchi + * Jeffrey Stedfast + */ + +#include "config.h" + +#include + +#include "gbase64.h" +#include "gtestutils.h" +#include "glibintl.h" + + +/** + * SECTION:base64 + * @title: Base64 Encoding + * @short_description: encodes and decodes data in Base64 format + * + * Base64 is an encoding that allows a sequence of arbitrary bytes to be + * encoded as a sequence of printable ASCII characters. For the definition + * of Base64, see + * [RFC 1421](http://www.ietf.org/rfc/rfc1421.txt) + * or + * [RFC 2045](http://www.ietf.org/rfc/rfc2045.txt). + * Base64 is most commonly used as a MIME transfer encoding + * for email. + * + * GLib supports incremental encoding using g_base64_encode_step() and + * g_base64_encode_close(). Incremental decoding can be done with + * g_base64_decode_step(). To encode or decode data in one go, use + * g_base64_encode() or g_base64_decode(). To avoid memory allocation when + * decoding, you can use g_base64_decode_inplace(). + * + * Support for Base64 encoding has been added in GLib 2.12. + */ + +static const char base64_alphabet[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * g_base64_encode_step: + * @in: (array length=len) (element-type guint8): the binary data to encode + * @len: the length of @in + * @break_lines: whether to break long lines + * @out: (out) (array) (element-type guint8): pointer to destination buffer + * @state: (inout): Saved state between steps, initialize to 0 + * @save: (inout): Saved state between steps, initialize to 0 + * + * Incrementally encode a sequence of binary data into its Base-64 stringified + * representation. By calling this function multiple times you can convert + * data in chunks to avoid having to have the full encoded data in memory. + * + * When all of the data has been converted you must call + * g_base64_encode_close() to flush the saved state. + * + * The output buffer must be large enough to fit all the data that will + * be written to it. Due to the way base64 encodes you will need + * at least: (@len / 3 + 1) * 4 + 4 bytes (+ 4 may be needed in case of + * non-zero state). If you enable line-breaking you will need at least: + * ((@len / 3 + 1) * 4 + 4) / 76 + 1 bytes of extra space. + * + * @break_lines is typically used when putting base64-encoded data in emails. + * It breaks the lines at 76 columns instead of putting all of the text on + * the same line. This avoids problems with long lines in the email system. + * Note however that it breaks the lines with `LF` characters, not + * `CR LF` sequences, so the result cannot be passed directly to SMTP + * or certain other protocols. + * + * Returns: The number of bytes of output that was written + * + * Since: 2.12 + */ +gsize +g_base64_encode_step (const guchar *in, + gsize len, + gboolean break_lines, + gchar *out, + gint *state, + gint *save) +{ + char *outptr; + const guchar *inptr; + + g_return_val_if_fail (in != NULL || len == 0, 0); + g_return_val_if_fail (out != NULL, 0); + g_return_val_if_fail (state != NULL, 0); + g_return_val_if_fail (save != NULL, 0); + + if (len == 0) + return 0; + + inptr = in; + outptr = out; + + if (len + ((char *) save) [0] > 2) + { + const guchar *inend = in+len-2; + int c1, c2, c3; + int already; + + already = *state; + + switch (((char *) save) [0]) + { + case 1: + c1 = ((unsigned char *) save) [1]; + goto skip1; + case 2: + c1 = ((unsigned char *) save) [1]; + c2 = ((unsigned char *) save) [2]; + goto skip2; + } + + /* + * yes, we jump into the loop, no i'm not going to change it, + * it's beautiful! + */ + while (inptr < inend) + { + c1 = *inptr++; + skip1: + c2 = *inptr++; + skip2: + c3 = *inptr++; + *outptr++ = base64_alphabet [ c1 >> 2 ]; + *outptr++ = base64_alphabet [ c2 >> 4 | + ((c1&0x3) << 4) ]; + *outptr++ = base64_alphabet [ ((c2 &0x0f) << 2) | + (c3 >> 6) ]; + *outptr++ = base64_alphabet [ c3 & 0x3f ]; + /* this is a bit ugly ... */ + if (break_lines && (++already) >= 19) + { + *outptr++ = '\n'; + already = 0; + } + } + + ((char *)save)[0] = 0; + len = 2 - (inptr - inend); + *state = already; + } + + g_assert (len == 0 || len == 1 || len == 2); + + { + char *saveout; + + /* points to the slot for the next char to save */ + saveout = & (((char *)save)[1]) + ((char *)save)[0]; + + /* len can only be 0 1 or 2 */ + switch(len) + { + case 2: + *saveout++ = *inptr++; + G_GNUC_FALLTHROUGH; + case 1: + *saveout++ = *inptr++; + } + ((char *)save)[0] += len; + } + + return outptr - out; +} + +/** + * g_base64_encode_close: + * @break_lines: whether to break long lines + * @out: (out) (array) (element-type guint8): pointer to destination buffer + * @state: (inout): Saved state from g_base64_encode_step() + * @save: (inout): Saved state from g_base64_encode_step() + * + * Flush the status from a sequence of calls to g_base64_encode_step(). + * + * The output buffer must be large enough to fit all the data that will + * be written to it. It will need up to 4 bytes, or up to 5 bytes if + * line-breaking is enabled. + * + * The @out array will not be automatically nul-terminated. + * + * Returns: The number of bytes of output that was written + * + * Since: 2.12 + */ +gsize +g_base64_encode_close (gboolean break_lines, + gchar *out, + gint *state, + gint *save) +{ + int c1, c2; + char *outptr = out; + + g_return_val_if_fail (out != NULL, 0); + g_return_val_if_fail (state != NULL, 0); + g_return_val_if_fail (save != NULL, 0); + + c1 = ((unsigned char *) save) [1]; + c2 = ((unsigned char *) save) [2]; + + switch (((char *) save) [0]) + { + case 2: + outptr [2] = base64_alphabet[ ( (c2 &0x0f) << 2 ) ]; + g_assert (outptr [2] != 0); + goto skip; + case 1: + outptr[2] = '='; + c2 = 0; /* saved state here is not relevant */ + skip: + outptr [0] = base64_alphabet [ c1 >> 2 ]; + outptr [1] = base64_alphabet [ c2 >> 4 | ( (c1&0x3) << 4 )]; + outptr [3] = '='; + outptr += 4; + break; + } + if (break_lines) + *outptr++ = '\n'; + + *save = 0; + *state = 0; + + return outptr - out; +} + +/** + * g_base64_encode: + * @data: (array length=len) (element-type guint8) (nullable): the binary data to encode + * @len: the length of @data + * + * Encode a sequence of binary data into its Base-64 stringified + * representation. + * + * Returns: (transfer full): a newly allocated, zero-terminated Base-64 + * encoded string representing @data. The returned string must + * be freed with g_free(). + * + * Since: 2.12 + */ +gchar * +g_base64_encode (const guchar *data, + gsize len) +{ + gchar *out; + gint state = 0, outlen; + gint save = 0; + + g_return_val_if_fail (data != NULL || len == 0, NULL); + + /* We can use a smaller limit here, since we know the saved state is 0, + +1 is needed for trailing \0, also check for unlikely integer overflow */ + g_return_val_if_fail (len < ((G_MAXSIZE - 1) / 4 - 1) * 3, NULL); + + out = g_malloc ((len / 3 + 1) * 4 + 1); + + outlen = g_base64_encode_step (data, len, FALSE, out, &state, &save); + outlen += g_base64_encode_close (FALSE, out + outlen, &state, &save); + out[outlen] = '\0'; + + return (gchar *) out; +} + +static const unsigned char mime_base64_rank[256] = { + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, + 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +}; + +/** + * g_base64_decode_step: (skip) + * @in: (array length=len) (element-type guint8): binary input data + * @len: max length of @in data to decode + * @out: (out caller-allocates) (array) (element-type guint8): output buffer + * @state: (inout): Saved state between steps, initialize to 0 + * @save: (inout): Saved state between steps, initialize to 0 + * + * Incrementally decode a sequence of binary data from its Base-64 stringified + * representation. By calling this function multiple times you can convert + * data in chunks to avoid having to have the full encoded data in memory. + * + * The output buffer must be large enough to fit all the data that will + * be written to it. Since base64 encodes 3 bytes in 4 chars you need + * at least: (@len / 4) * 3 + 3 bytes (+ 3 may be needed in case of non-zero + * state). + * + * Returns: The number of bytes of output that was written + * + * Since: 2.12 + **/ +gsize +g_base64_decode_step (const gchar *in, + gsize len, + guchar *out, + gint *state, + guint *save) +{ + const guchar *inptr; + guchar *outptr; + const guchar *inend; + guchar c, rank; + guchar last[2]; + unsigned int v; + int i; + + g_return_val_if_fail (in != NULL || len == 0, 0); + g_return_val_if_fail (out != NULL, 0); + g_return_val_if_fail (state != NULL, 0); + g_return_val_if_fail (save != NULL, 0); + + if (len == 0) + return 0; + + inend = (const guchar *)in+len; + outptr = out; + + /* convert 4 base64 bytes to 3 normal bytes */ + v=*save; + i=*state; + + last[0] = last[1] = 0; + + /* we use the sign in the state to determine if we got a padding character + in the previous sequence */ + if (i < 0) + { + i = -i; + last[0] = '='; + } + + inptr = (const guchar *)in; + while (inptr < inend) + { + c = *inptr++; + rank = mime_base64_rank [c]; + if (rank != 0xff) + { + last[1] = last[0]; + last[0] = c; + v = (v<<6) | rank; + i++; + if (i==4) + { + *outptr++ = v>>16; + if (last[1] != '=') + *outptr++ = v>>8; + if (last[0] != '=') + *outptr++ = v; + i=0; + } + } + } + + *save = v; + *state = last[0] == '=' ? -i : i; + + return outptr - out; +} + +/** + * g_base64_decode: + * @text: (not nullable): zero-terminated string with base64 text to decode + * @out_len: (out): The length of the decoded data is written here + * + * Decode a sequence of Base-64 encoded text into binary data. Note + * that the returned binary data is not necessarily zero-terminated, + * so it should not be used as a character string. + * + * Returns: (transfer full) (array length=out_len) (element-type guint8): + * newly allocated buffer containing the binary data + * that @text represents. The returned buffer must + * be freed with g_free(). + * + * Since: 2.12 + */ +guchar * +g_base64_decode (const gchar *text, + gsize *out_len) +{ + guchar *ret; + gsize input_length; + gint state = 0; + guint save = 0; + + g_return_val_if_fail (text != NULL, NULL); + g_return_val_if_fail (out_len != NULL, NULL); + + input_length = strlen (text); + + /* We can use a smaller limit here, since we know the saved state is 0, + +1 used to avoid calling g_malloc0(0), and hence returning NULL */ + ret = g_malloc0 ((input_length / 4) * 3 + 1); + + *out_len = g_base64_decode_step (text, input_length, ret, &state, &save); + + return ret; +} + +/** + * g_base64_decode_inplace: + * @text: (inout) (array length=out_len) (element-type guint8): zero-terminated + * string with base64 text to decode + * @out_len: (inout): The length of the decoded data is written here + * + * Decode a sequence of Base-64 encoded text into binary data + * by overwriting the input data. + * + * Returns: (transfer none): The binary data that @text responds. This pointer + * is the same as the input @text. + * + * Since: 2.20 + */ +guchar * +g_base64_decode_inplace (gchar *text, + gsize *out_len) +{ + gint input_length, state = 0; + guint save = 0; + + g_return_val_if_fail (text != NULL, NULL); + g_return_val_if_fail (out_len != NULL, NULL); + + input_length = strlen (text); + + g_return_val_if_fail (input_length > 1, NULL); + + *out_len = g_base64_decode_step (text, input_length, (guchar *) text, &state, &save); + + return (guchar *) text; +} diff --git a/glib/gbase64.h b/glib/gbase64.h new file mode 100644 index 0000000..662c597 --- /dev/null +++ b/glib/gbase64.h @@ -0,0 +1,61 @@ +/* gbase64.h - Base64 coding functions + * + * Copyright (C) 2005 Alexander Larsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef __G_BASE64_H__ +#define __G_BASE64_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +gsize g_base64_encode_step (const guchar *in, + gsize len, + gboolean break_lines, + gchar *out, + gint *state, + gint *save); +GLIB_AVAILABLE_IN_ALL +gsize g_base64_encode_close (gboolean break_lines, + gchar *out, + gint *state, + gint *save); +GLIB_AVAILABLE_IN_ALL +gchar* g_base64_encode (const guchar *data, + gsize len) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gsize g_base64_decode_step (const gchar *in, + gsize len, + guchar *out, + gint *state, + guint *save); +GLIB_AVAILABLE_IN_ALL +guchar *g_base64_decode (const gchar *text, + gsize *out_len) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +guchar *g_base64_decode_inplace (gchar *text, + gsize *out_len); + + +G_END_DECLS + +#endif /* __G_BASE64_H__ */ diff --git a/glib/gbitlock.c b/glib/gbitlock.c new file mode 100644 index 0000000..9384d1a --- /dev/null +++ b/glib/gbitlock.c @@ -0,0 +1,563 @@ +/* + * Copyright © 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gbitlock.h" + +#include +#include +#include +#include +#include +#include + +#include "gthreadprivate.h" + +#ifdef G_BIT_LOCK_FORCE_FUTEX_EMULATION +#undef HAVE_FUTEX +#endif + +#ifndef HAVE_FUTEX +static GMutex g_futex_mutex; +static GSList *g_futex_address_list = NULL; +#endif + +#ifdef HAVE_FUTEX +/* + * We have headers for futex(2) on the build machine. This does not + * imply that every system that ever runs the resulting glib will have + * kernel support for futex, but you'd have to have a pretty old + * kernel in order for that not to be the case. + * + * If anyone actually gets bit by this, please file a bug. :) + */ +#include +#include +#include + +#ifndef FUTEX_WAIT_PRIVATE +#define FUTEX_WAIT_PRIVATE FUTEX_WAIT +#define FUTEX_WAKE_PRIVATE FUTEX_WAKE +#endif + +/* < private > + * g_futex_wait: + * @address: a pointer to an integer + * @value: the value that should be at @address + * + * Atomically checks that the value stored at @address is equal to + * @value and then blocks. If the value stored at @address is not + * equal to @value then this function returns immediately. + * + * To unblock, call g_futex_wake() on @address. + * + * This call may spuriously unblock (for example, in response to the + * process receiving a signal) but this is not guaranteed. Unlike the + * Linux system call of a similar name, there is no guarantee that a + * waiting process will unblock due to a g_futex_wake() call in a + * separate process. + */ +static void +g_futex_wait (const gint *address, + gint value) +{ + syscall (__NR_futex, address, (gsize) FUTEX_WAIT_PRIVATE, (gsize) value, NULL); +} + +/* < private > + * g_futex_wake: + * @address: a pointer to an integer + * + * Nominally, wakes one thread that is blocked in g_futex_wait() on + * @address (if any thread is currently waiting). + * + * As mentioned in the documentation for g_futex_wait(), spurious + * wakeups may occur. As such, this call may result in more than one + * thread being woken up. + */ +static void +g_futex_wake (const gint *address) +{ + syscall (__NR_futex, address, (gsize) FUTEX_WAKE_PRIVATE, (gsize) 1, NULL); +} + +#else + +/* emulate futex(2) */ +typedef struct +{ + const gint *address; + gint ref_count; + GCond wait_queue; +} WaitAddress; + +static WaitAddress * +g_futex_find_address (const gint *address) +{ + GSList *node; + + for (node = g_futex_address_list; node; node = node->next) + { + WaitAddress *waiter = node->data; + + if (waiter->address == address) + return waiter; + } + + return NULL; +} + +static void +g_futex_wait (const gint *address, + gint value) +{ + g_mutex_lock (&g_futex_mutex); + if G_LIKELY (g_atomic_int_get (address) == value) + { + WaitAddress *waiter; + + if ((waiter = g_futex_find_address (address)) == NULL) + { + waiter = g_slice_new (WaitAddress); + waiter->address = address; + g_cond_init (&waiter->wait_queue); + waiter->ref_count = 0; + g_futex_address_list = + g_slist_prepend (g_futex_address_list, waiter); + } + + waiter->ref_count++; + g_cond_wait (&waiter->wait_queue, &g_futex_mutex); + + if (!--waiter->ref_count) + { + g_futex_address_list = + g_slist_remove (g_futex_address_list, waiter); + g_cond_clear (&waiter->wait_queue); + g_slice_free (WaitAddress, waiter); + } + } + g_mutex_unlock (&g_futex_mutex); +} + +static void +g_futex_wake (const gint *address) +{ + WaitAddress *waiter; + + /* need to lock here for two reasons: + * 1) need to acquire/release lock to ensure waiter is not in + * the process of registering a wait + * 2) need to -stay- locked until the end to ensure a wake() + * in another thread doesn't cause 'waiter' to stop existing + */ + g_mutex_lock (&g_futex_mutex); + if ((waiter = g_futex_find_address (address))) + g_cond_signal (&waiter->wait_queue); + g_mutex_unlock (&g_futex_mutex); +} +#endif + +#define CONTENTION_CLASSES 11 +static gint g_bit_lock_contended[CONTENTION_CLASSES]; /* (atomic) */ + +#if (defined (i386) || defined (__amd64__)) + #if G_GNUC_CHECK_VERSION(4, 5) + #define USE_ASM_GOTO 1 + #endif +#endif + +/** + * g_bit_lock: + * @address: a pointer to an integer + * @lock_bit: a bit value between 0 and 31 + * + * Sets the indicated @lock_bit in @address. If the bit is already + * set, this call will block until g_bit_unlock() unsets the + * corresponding bit. + * + * Attempting to lock on two different bits within the same integer is + * not supported and will very probably cause deadlocks. + * + * The value of the bit that is set is (1u << @bit). If @bit is not + * between 0 and 31 then the result is undefined. + * + * This function accesses @address atomically. All other accesses to + * @address must be atomic in order for this function to work + * reliably. While @address has a `volatile` qualifier, this is a historical + * artifact and the argument passed to it should not be `volatile`. + * + * Since: 2.24 + **/ +void +g_bit_lock (volatile gint *address, + gint lock_bit) +{ + gint *address_nonvolatile = (gint *) address; + +#ifdef USE_ASM_GOTO + retry: + __asm__ volatile goto ("lock bts %1, (%0)\n" + "jc %l[contended]" + : /* no output */ + : "r" (address), "r" (lock_bit) + : "cc", "memory" + : contended); + return; + + contended: + { + guint mask = 1u << lock_bit; + guint v; + + v = (guint) g_atomic_int_get (address_nonvolatile); + if (v & mask) + { + guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended); + + g_atomic_int_add (&g_bit_lock_contended[class], +1); + g_futex_wait (address_nonvolatile, v); + g_atomic_int_add (&g_bit_lock_contended[class], -1); + } + } + goto retry; +#else + guint mask = 1u << lock_bit; + guint v; + + retry: + v = g_atomic_int_or (address_nonvolatile, mask); + if (v & mask) + /* already locked */ + { + guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended); + + g_atomic_int_add (&g_bit_lock_contended[class], +1); + g_futex_wait (address_nonvolatile, v); + g_atomic_int_add (&g_bit_lock_contended[class], -1); + + goto retry; + } +#endif +} + +/** + * g_bit_trylock: + * @address: a pointer to an integer + * @lock_bit: a bit value between 0 and 31 + * + * Sets the indicated @lock_bit in @address, returning %TRUE if + * successful. If the bit is already set, returns %FALSE immediately. + * + * Attempting to lock on two different bits within the same integer is + * not supported. + * + * The value of the bit that is set is (1u << @bit). If @bit is not + * between 0 and 31 then the result is undefined. + * + * This function accesses @address atomically. All other accesses to + * @address must be atomic in order for this function to work + * reliably. While @address has a `volatile` qualifier, this is a historical + * artifact and the argument passed to it should not be `volatile`. + * + * Returns: %TRUE if the lock was acquired + * + * Since: 2.24 + **/ +gboolean +g_bit_trylock (volatile gint *address, + gint lock_bit) +{ +#ifdef USE_ASM_GOTO + gboolean result; + + __asm__ volatile ("lock bts %2, (%1)\n" + "setnc %%al\n" + "movzx %%al, %0" + : "=r" (result) + : "r" (address), "r" (lock_bit) + : "cc", "memory"); + + return result; +#else + gint *address_nonvolatile = (gint *) address; + guint mask = 1u << lock_bit; + guint v; + + v = g_atomic_int_or (address_nonvolatile, mask); + + return ~v & mask; +#endif +} + +/** + * g_bit_unlock: + * @address: a pointer to an integer + * @lock_bit: a bit value between 0 and 31 + * + * Clears the indicated @lock_bit in @address. If another thread is + * currently blocked in g_bit_lock() on this same bit then it will be + * woken up. + * + * This function accesses @address atomically. All other accesses to + * @address must be atomic in order for this function to work + * reliably. While @address has a `volatile` qualifier, this is a historical + * artifact and the argument passed to it should not be `volatile`. + * + * Since: 2.24 + **/ +void +g_bit_unlock (volatile gint *address, + gint lock_bit) +{ + gint *address_nonvolatile = (gint *) address; + +#ifdef USE_ASM_GOTO + __asm__ volatile ("lock btr %1, (%0)" + : /* no output */ + : "r" (address), "r" (lock_bit) + : "cc", "memory"); +#else + guint mask = 1u << lock_bit; + + g_atomic_int_and (address_nonvolatile, ~mask); +#endif + + { + guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended); + + if (g_atomic_int_get (&g_bit_lock_contended[class])) + g_futex_wake (address_nonvolatile); + } +} + + +/* We emulate pointer-sized futex(2) because the kernel API only + * supports integers. + * + * We assume that the 'interesting' part is always the lower order bits. + * This assumption holds because pointer bitlocks are restricted to + * using the low order bits of the pointer as the lock. + * + * On 32 bits, there is nothing to do since the pointer size is equal to + * the integer size. On little endian the lower-order bits don't move, + * so do nothing. Only on 64bit big endian do we need to do a bit of + * pointer arithmetic: the low order bits are shifted by 4 bytes. We + * have a helper function that always does the right thing here. + * + * Since we always consider the low-order bits of the integer value, a + * simple cast from (gsize) to (guint) always takes care of that. + * + * After that, pointer-sized futex becomes as simple as: + * + * g_futex_wait (g_futex_int_address (address), (guint) value); + * + * and + * + * g_futex_wake (g_futex_int_address (int_address)); + */ +static const gint * +g_futex_int_address (const void *address) +{ + const gint *int_address = address; + + /* this implementation makes these (reasonable) assumptions: */ + G_STATIC_ASSERT (G_BYTE_ORDER == G_LITTLE_ENDIAN || + (G_BYTE_ORDER == G_BIG_ENDIAN && + sizeof (int) == 4 && + (sizeof (gpointer) == 4 || sizeof (gpointer) == 8))); + +#if G_BYTE_ORDER == G_BIG_ENDIAN && GLIB_SIZEOF_VOID_P == 8 + int_address++; +#endif + + return int_address; +} + +/** + * g_pointer_bit_lock: + * @address: (not nullable): a pointer to a #gpointer-sized value + * @lock_bit: a bit value between 0 and 31 + * + * This is equivalent to g_bit_lock, but working on pointers (or other + * pointer-sized values). + * + * For portability reasons, you may only lock on the bottom 32 bits of + * the pointer. + * + * While @address has a `volatile` qualifier, this is a historical + * artifact and the argument passed to it should not be `volatile`. + * + * Since: 2.30 + **/ +void +(g_pointer_bit_lock) (volatile void *address, + gint lock_bit) +{ + void *address_nonvolatile = (void *) address; + + g_return_if_fail (lock_bit < 32); + + { +#ifdef USE_ASM_GOTO + retry: + __asm__ volatile goto ("lock bts %1, (%0)\n" + "jc %l[contended]" + : /* no output */ + : "r" (address), "r" ((gsize) lock_bit) + : "cc", "memory" + : contended); + return; + + contended: + { + gsize *pointer_address = address_nonvolatile; + gsize mask = 1u << lock_bit; + gsize v; + + v = (gsize) g_atomic_pointer_get (pointer_address); + if (v & mask) + { + guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended); + + g_atomic_int_add (&g_bit_lock_contended[class], +1); + g_futex_wait (g_futex_int_address (address_nonvolatile), v); + g_atomic_int_add (&g_bit_lock_contended[class], -1); + } + } + goto retry; +#else + gsize *pointer_address = address_nonvolatile; + gsize mask = 1u << lock_bit; + gsize v; + + retry: + v = g_atomic_pointer_or (pointer_address, mask); + if (v & mask) + /* already locked */ + { + guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended); + + g_atomic_int_add (&g_bit_lock_contended[class], +1); + g_futex_wait (g_futex_int_address (address_nonvolatile), (guint) v); + g_atomic_int_add (&g_bit_lock_contended[class], -1); + + goto retry; + } +#endif + } +} + +/** + * g_pointer_bit_trylock: + * @address: (not nullable): a pointer to a #gpointer-sized value + * @lock_bit: a bit value between 0 and 31 + * + * This is equivalent to g_bit_trylock(), but working on pointers (or + * other pointer-sized values). + * + * For portability reasons, you may only lock on the bottom 32 bits of + * the pointer. + * + * While @address has a `volatile` qualifier, this is a historical + * artifact and the argument passed to it should not be `volatile`. + * + * Returns: %TRUE if the lock was acquired + * + * Since: 2.30 + **/ +gboolean +(g_pointer_bit_trylock) (volatile void *address, + gint lock_bit) +{ + g_return_val_if_fail (lock_bit < 32, FALSE); + + { +#ifdef USE_ASM_GOTO + gboolean result; + + __asm__ volatile ("lock bts %2, (%1)\n" + "setnc %%al\n" + "movzx %%al, %0" + : "=r" (result) + : "r" (address), "r" ((gsize) lock_bit) + : "cc", "memory"); + + return result; +#else + void *address_nonvolatile = (void *) address; + gsize *pointer_address = address_nonvolatile; + gsize mask = 1u << lock_bit; + gsize v; + + g_return_val_if_fail (lock_bit < 32, FALSE); + + v = g_atomic_pointer_or (pointer_address, mask); + + return ~v & mask; +#endif + } +} + +/** + * g_pointer_bit_unlock: + * @address: (not nullable): a pointer to a #gpointer-sized value + * @lock_bit: a bit value between 0 and 31 + * + * This is equivalent to g_bit_unlock, but working on pointers (or other + * pointer-sized values). + * + * For portability reasons, you may only lock on the bottom 32 bits of + * the pointer. + * + * While @address has a `volatile` qualifier, this is a historical + * artifact and the argument passed to it should not be `volatile`. + * + * Since: 2.30 + **/ +void +(g_pointer_bit_unlock) (volatile void *address, + gint lock_bit) +{ + void *address_nonvolatile = (void *) address; + + g_return_if_fail (lock_bit < 32); + + { +#ifdef USE_ASM_GOTO + __asm__ volatile ("lock btr %1, (%0)" + : /* no output */ + : "r" (address), "r" ((gsize) lock_bit) + : "cc", "memory"); +#else + gsize *pointer_address = address_nonvolatile; + gsize mask = 1u << lock_bit; + + g_atomic_pointer_and (pointer_address, ~mask); +#endif + + { + guint class = ((gsize) address_nonvolatile) % G_N_ELEMENTS (g_bit_lock_contended); + if (g_atomic_int_get (&g_bit_lock_contended[class])) + g_futex_wake (g_futex_int_address (address_nonvolatile)); + } + } +} diff --git a/glib/gbitlock.h b/glib/gbitlock.h new file mode 100644 index 0000000..8054bc8 --- /dev/null +++ b/glib/gbitlock.h @@ -0,0 +1,76 @@ +/* + * Copyright © 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#ifndef __G_BITLOCK_H__ +#define __G_BITLOCK_H__ + +#include + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +void g_bit_lock (volatile gint *address, + gint lock_bit); +GLIB_AVAILABLE_IN_ALL +gboolean g_bit_trylock (volatile gint *address, + gint lock_bit); +GLIB_AVAILABLE_IN_ALL +void g_bit_unlock (volatile gint *address, + gint lock_bit); + +GLIB_AVAILABLE_IN_ALL +void g_pointer_bit_lock (volatile void *address, + gint lock_bit); +GLIB_AVAILABLE_IN_ALL +gboolean g_pointer_bit_trylock (volatile void *address, + gint lock_bit); +GLIB_AVAILABLE_IN_ALL +void g_pointer_bit_unlock (volatile void *address, + gint lock_bit); + +#ifdef __GNUC__ + +#define g_pointer_bit_lock(address, lock_bit) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ + g_pointer_bit_lock ((address), (lock_bit)); \ + })) + +#define g_pointer_bit_trylock(address, lock_bit) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ + g_pointer_bit_trylock ((address), (lock_bit)); \ + })) + +#define g_pointer_bit_unlock(address, lock_bit) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ + g_pointer_bit_unlock ((address), (lock_bit)); \ + })) + +#endif + +G_END_DECLS + +#endif /* __G_BITLOCK_H_ */ diff --git a/glib/gbookmarkfile.c b/glib/gbookmarkfile.c new file mode 100644 index 0000000..51dfa23 --- /dev/null +++ b/glib/gbookmarkfile.c @@ -0,0 +1,4022 @@ +/* gbookmarkfile.c: parsing and building desktop bookmarks + * + * Copyright (C) 2005-2006 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include "config.h" + +#include "gbookmarkfile.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gconvert.h" +#include "gdataset.h" +#include "gdatetime.h" +#include "gerror.h" +#include "gfileutils.h" +#include "ghash.h" +#include "glibintl.h" +#include "glist.h" +#include "gmain.h" +#include "gmarkup.h" +#include "gmem.h" +#include "gmessages.h" +#include "gshell.h" +#include "gslice.h" +#include "gstdio.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "gtimer.h" +#include "gutils.h" + + +/** + * SECTION:bookmarkfile + * @title: Bookmark file parser + * @short_description: parses files containing bookmarks + * + * GBookmarkFile lets you parse, edit or create files containing bookmarks + * to URI, along with some meta-data about the resource pointed by the URI + * like its MIME type, the application that is registering the bookmark and + * the icon that should be used to represent the bookmark. The data is stored + * using the + * [Desktop Bookmark Specification](http://www.gnome.org/~ebassi/bookmark-spec). + * + * The syntax of the bookmark files is described in detail inside the + * Desktop Bookmark Specification, here is a quick summary: bookmark + * files use a sub-class of the XML Bookmark Exchange Language + * specification, consisting of valid UTF-8 encoded XML, under the + * root element; each bookmark is stored inside a + * element, using its URI: no relative paths can + * be used inside a bookmark file. The bookmark may have a user defined + * title and description, to be used instead of the URI. Under the + * element, with its owner attribute set to + * `http://freedesktop.org`, is stored the meta-data about a resource + * pointed by its URI. The meta-data consists of the resource's MIME + * type; the applications that have registered a bookmark; the groups + * to which a bookmark belongs to; a visibility flag, used to set the + * bookmark as "private" to the applications and groups that has it + * registered; the URI and MIME type of an icon, to be used when + * displaying the bookmark inside a GUI. + * + * Here is an example of a bookmark file: + * [bookmarks.xbel](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/glib/tests/bookmarks.xbel) + * + * A bookmark file might contain more than one bookmark; each bookmark + * is accessed through its URI. + * + * The important caveat of bookmark files is that when you add a new + * bookmark you must also add the application that is registering it, using + * g_bookmark_file_add_application() or g_bookmark_file_set_application_info(). + * If a bookmark has no applications then it won't be dumped when creating + * the on disk representation, using g_bookmark_file_to_data() or + * g_bookmark_file_to_file(). + * + * The #GBookmarkFile parser was added in GLib 2.12. + */ + +/* XBEL 1.0 standard entities */ +#define XBEL_VERSION "1.0" +#define XBEL_DTD_NICK "xbel" +#define XBEL_DTD_SYSTEM "+//IDN python.org//DTD XML Bookmark " \ + "Exchange Language 1.0//EN//XML" + +#define XBEL_DTD_URI "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd" + +#define XBEL_ROOT_ELEMENT "xbel" +#define XBEL_FOLDER_ELEMENT "folder" /* unused */ +#define XBEL_BOOKMARK_ELEMENT "bookmark" +#define XBEL_ALIAS_ELEMENT "alias" /* unused */ +#define XBEL_SEPARATOR_ELEMENT "separator" /* unused */ +#define XBEL_TITLE_ELEMENT "title" +#define XBEL_DESC_ELEMENT "desc" +#define XBEL_INFO_ELEMENT "info" +#define XBEL_METADATA_ELEMENT "metadata" + +#define XBEL_VERSION_ATTRIBUTE "version" +#define XBEL_FOLDED_ATTRIBUTE "folded" /* unused */ +#define XBEL_OWNER_ATTRIBUTE "owner" +#define XBEL_ADDED_ATTRIBUTE "added" +#define XBEL_VISITED_ATTRIBUTE "visited" +#define XBEL_MODIFIED_ATTRIBUTE "modified" +#define XBEL_ID_ATTRIBUTE "id" +#define XBEL_HREF_ATTRIBUTE "href" +#define XBEL_REF_ATTRIBUTE "ref" /* unused */ + +#define XBEL_YES_VALUE "yes" +#define XBEL_NO_VALUE "no" + +/* Desktop bookmark spec entities */ +#define BOOKMARK_METADATA_OWNER "http://freedesktop.org" + +#define BOOKMARK_NAMESPACE_NAME "bookmark" +#define BOOKMARK_NAMESPACE_URI "http://www.freedesktop.org/standards/desktop-bookmarks" + +#define BOOKMARK_GROUPS_ELEMENT "groups" +#define BOOKMARK_GROUP_ELEMENT "group" +#define BOOKMARK_APPLICATIONS_ELEMENT "applications" +#define BOOKMARK_APPLICATION_ELEMENT "application" +#define BOOKMARK_ICON_ELEMENT "icon" +#define BOOKMARK_PRIVATE_ELEMENT "private" + +#define BOOKMARK_NAME_ATTRIBUTE "name" +#define BOOKMARK_EXEC_ATTRIBUTE "exec" +#define BOOKMARK_COUNT_ATTRIBUTE "count" +#define BOOKMARK_TIMESTAMP_ATTRIBUTE "timestamp" /* deprecated by "modified" */ +#define BOOKMARK_MODIFIED_ATTRIBUTE "modified" +#define BOOKMARK_HREF_ATTRIBUTE "href" +#define BOOKMARK_TYPE_ATTRIBUTE "type" + +/* Shared MIME Info entities */ +#define MIME_NAMESPACE_NAME "mime" +#define MIME_NAMESPACE_URI "http://www.freedesktop.org/standards/shared-mime-info" +#define MIME_TYPE_ELEMENT "mime-type" +#define MIME_TYPE_ATTRIBUTE "type" + + +typedef struct _BookmarkAppInfo BookmarkAppInfo; +typedef struct _BookmarkMetadata BookmarkMetadata; +typedef struct _BookmarkItem BookmarkItem; +typedef struct _ParseData ParseData; + +struct _BookmarkAppInfo +{ + gchar *name; + gchar *exec; + + guint count; + + GDateTime *stamp; /* (owned) */ +}; + +struct _BookmarkMetadata +{ + gchar *mime_type; + + GList *groups; + + GList *applications; + GHashTable *apps_by_name; + + gchar *icon_href; + gchar *icon_mime; + + guint is_private : 1; +}; + +struct _BookmarkItem +{ + gchar *uri; + + gchar *title; + gchar *description; + + GDateTime *added; /* (owned) */ + GDateTime *modified; /* (owned) */ + GDateTime *visited; /* (owned) */ + + BookmarkMetadata *metadata; +}; + +struct _GBookmarkFile +{ + gchar *title; + gchar *description; + + /* we store our items in a list and keep a copy inside + * a hash table for faster lookup performances + */ + GList *items; + GHashTable *items_by_uri; +}; + +/* parser state machine */ +typedef enum +{ + STATE_STARTED = 0, + + STATE_ROOT, + STATE_BOOKMARK, + STATE_TITLE, + STATE_DESC, + STATE_INFO, + STATE_METADATA, + STATE_APPLICATIONS, + STATE_APPLICATION, + STATE_GROUPS, + STATE_GROUP, + STATE_MIME, + STATE_ICON, + + STATE_FINISHED +} ParserState; + +static void g_bookmark_file_init (GBookmarkFile *bookmark); +static void g_bookmark_file_clear (GBookmarkFile *bookmark); +static gboolean g_bookmark_file_parse (GBookmarkFile *bookmark, + const gchar *buffer, + gsize length, + GError **error); +static gchar * g_bookmark_file_dump (GBookmarkFile *bookmark, + gsize *length, + GError **error); +static BookmarkItem *g_bookmark_file_lookup_item (GBookmarkFile *bookmark, + const gchar *uri); +static void g_bookmark_file_add_item (GBookmarkFile *bookmark, + BookmarkItem *item, + GError **error); + +static gboolean timestamp_from_iso8601 (const gchar *iso_date, + GDateTime **out_date_time, + GError **error); + +/******************************** + * BookmarkAppInfo * + * * + * Application metadata storage * + ********************************/ +static BookmarkAppInfo * +bookmark_app_info_new (const gchar *name) +{ + BookmarkAppInfo *retval; + + g_warn_if_fail (name != NULL); + + retval = g_slice_new (BookmarkAppInfo); + + retval->name = g_strdup (name); + retval->exec = NULL; + retval->count = 0; + retval->stamp = NULL; + + return retval; +} + +static void +bookmark_app_info_free (BookmarkAppInfo *app_info) +{ + if (!app_info) + return; + + g_free (app_info->name); + g_free (app_info->exec); + g_clear_pointer (&app_info->stamp, g_date_time_unref); + + g_slice_free (BookmarkAppInfo, app_info); +} + +static gchar * +bookmark_app_info_dump (BookmarkAppInfo *app_info) +{ + gchar *retval; + gchar *name, *exec, *modified, *count; + + g_warn_if_fail (app_info != NULL); + + if (app_info->count == 0) + return NULL; + + name = g_markup_escape_text (app_info->name, -1); + exec = g_markup_escape_text (app_info->exec, -1); + modified = g_date_time_format_iso8601 (app_info->stamp); + count = g_strdup_printf ("%u", app_info->count); + + retval = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME ":" BOOKMARK_APPLICATION_ELEMENT + " " BOOKMARK_NAME_ATTRIBUTE "=\"", name, "\"" + " " BOOKMARK_EXEC_ATTRIBUTE "=\"", exec, "\"" + " " BOOKMARK_MODIFIED_ATTRIBUTE "=\"", modified, "\"" + " " BOOKMARK_COUNT_ATTRIBUTE "=\"", count, "\"/>\n", + NULL); + + g_free (name); + g_free (exec); + g_free (modified); + g_free (count); + + return retval; +} + + +/*********************** + * BookmarkMetadata * + * * + * Metadata storage * + ***********************/ +static BookmarkMetadata * +bookmark_metadata_new (void) +{ + BookmarkMetadata *retval; + + retval = g_slice_new (BookmarkMetadata); + + retval->mime_type = NULL; + + retval->groups = NULL; + + retval->applications = NULL; + retval->apps_by_name = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + + retval->is_private = FALSE; + + retval->icon_href = NULL; + retval->icon_mime = NULL; + + return retval; +} + +static void +bookmark_metadata_free (BookmarkMetadata *metadata) +{ + if (!metadata) + return; + + g_free (metadata->mime_type); + + g_list_free_full (metadata->groups, g_free); + g_list_free_full (metadata->applications, (GDestroyNotify) bookmark_app_info_free); + + g_hash_table_destroy (metadata->apps_by_name); + + g_free (metadata->icon_href); + g_free (metadata->icon_mime); + + g_slice_free (BookmarkMetadata, metadata); +} + +static gchar * +bookmark_metadata_dump (BookmarkMetadata *metadata) +{ + GString *retval; + gchar *buffer; + + if (!metadata->applications) + return NULL; + + retval = g_string_sized_new (1024); + + /* metadata container */ + g_string_append (retval, + " " + "<" XBEL_METADATA_ELEMENT + " " XBEL_OWNER_ATTRIBUTE "=\"" BOOKMARK_METADATA_OWNER + "\">\n"); + + /* mime type */ + if (metadata->mime_type) { + buffer = g_strconcat (" " + "<" MIME_NAMESPACE_NAME ":" MIME_TYPE_ELEMENT " " + MIME_TYPE_ATTRIBUTE "=\"", metadata->mime_type, "\"/>\n", + NULL); + g_string_append (retval, buffer); + g_free (buffer); + } + + if (metadata->groups) + { + GList *l; + + /* open groups container */ + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_GROUPS_ELEMENT ">\n"); + + for (l = g_list_last (metadata->groups); l != NULL; l = l->prev) + { + gchar *group_name; + + group_name = g_markup_escape_text ((gchar *) l->data, -1); + buffer = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_GROUP_ELEMENT ">", + group_name, + "\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); + g_free (group_name); + } + + /* close groups container */ + g_string_append (retval, + " " + "\n"); + } + + if (metadata->applications) + { + GList *l; + + /* open applications container */ + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_APPLICATIONS_ELEMENT ">\n"); + + for (l = g_list_last (metadata->applications); l != NULL; l = l->prev) + { + BookmarkAppInfo *app_info = (BookmarkAppInfo *) l->data; + gchar *app_data; + + g_warn_if_fail (app_info != NULL); + + app_data = bookmark_app_info_dump (app_info); + + if (app_data) + { + retval = g_string_append (retval, app_data); + + g_free (app_data); + } + } + + /* close applications container */ + g_string_append (retval, + " " + "\n"); + } + + /* icon */ + if (metadata->icon_href) + { + if (!metadata->icon_mime) + metadata->icon_mime = g_strdup ("application/octet-stream"); + + buffer = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_ICON_ELEMENT + " " BOOKMARK_HREF_ATTRIBUTE "=\"", metadata->icon_href, + "\" " BOOKMARK_TYPE_ATTRIBUTE "=\"", metadata->icon_mime, "\"/>\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); + } + + /* private hint */ + if (metadata->is_private) + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_PRIVATE_ELEMENT "/>\n"); + + /* close metadata container */ + g_string_append (retval, + " " + "\n"); + + return g_string_free (retval, FALSE); +} + +/****************************************************** + * BookmarkItem * + * * + * Storage for a single bookmark item inside the list * + ******************************************************/ +static BookmarkItem * +bookmark_item_new (const gchar *uri) +{ + BookmarkItem *item; + + g_warn_if_fail (uri != NULL); + + item = g_slice_new (BookmarkItem); + item->uri = g_strdup (uri); + + item->title = NULL; + item->description = NULL; + + item->added = NULL; + item->modified = NULL; + item->visited = NULL; + + item->metadata = NULL; + + return item; +} + +static void +bookmark_item_free (BookmarkItem *item) +{ + if (!item) + return; + + g_free (item->uri); + g_free (item->title); + g_free (item->description); + + if (item->metadata) + bookmark_metadata_free (item->metadata); + + g_clear_pointer (&item->added, g_date_time_unref); + g_clear_pointer (&item->modified, g_date_time_unref); + g_clear_pointer (&item->visited, g_date_time_unref); + + g_slice_free (BookmarkItem, item); +} + +static void +bookmark_item_touch_modified (BookmarkItem *item) +{ + g_clear_pointer (&item->modified, g_date_time_unref); + item->modified = g_date_time_new_now_utc (); +} + +static gchar * +bookmark_item_dump (BookmarkItem *item) +{ + GString *retval; + gchar *escaped_uri; + + /* at this point, we must have at least a registered application; if we don't + * we don't screw up the bookmark file, and just skip this item + */ + if (!item->metadata || !item->metadata->applications) + { + g_warning ("Item for URI '%s' has no registered applications: skipping.", item->uri); + return NULL; + } + + retval = g_string_sized_new (4096); + + g_string_append (retval, " <" XBEL_BOOKMARK_ELEMENT " "); + + escaped_uri = g_markup_escape_text (item->uri, -1); + + g_string_append (retval, XBEL_HREF_ATTRIBUTE "=\""); + g_string_append (retval, escaped_uri); + g_string_append (retval , "\" "); + + g_free (escaped_uri); + + if (item->added) + { + char *added; + + added = g_date_time_format_iso8601 (item->added); + g_string_append (retval, XBEL_ADDED_ATTRIBUTE "=\""); + g_string_append (retval, added); + g_string_append (retval, "\" "); + g_free (added); + } + + if (item->modified) + { + char *modified; + + modified = g_date_time_format_iso8601 (item->modified); + g_string_append (retval, XBEL_MODIFIED_ATTRIBUTE "=\""); + g_string_append (retval, modified); + g_string_append (retval, "\" "); + g_free (modified); + } + + if (item->visited) + { + char *visited; + + visited = g_date_time_format_iso8601 (item->visited); + g_string_append (retval, XBEL_VISITED_ATTRIBUTE "=\""); + g_string_append (retval, visited); + g_string_append (retval, "\" "); + g_free (visited); + } + + if (retval->str[retval->len - 1] == ' ') + g_string_truncate (retval, retval->len - 1); + g_string_append (retval, ">\n"); + + if (item->title) + { + gchar *escaped_title; + + escaped_title = g_markup_escape_text (item->title, -1); + g_string_append (retval, " " "<" XBEL_TITLE_ELEMENT ">"); + g_string_append (retval, escaped_title); + g_string_append (retval, "\n"); + + g_free (escaped_title); + } + + if (item->description) + { + gchar *escaped_desc; + + escaped_desc = g_markup_escape_text (item->description, -1); + g_string_append (retval, " " "<" XBEL_DESC_ELEMENT ">"); + g_string_append (retval, escaped_desc); + g_string_append (retval, "\n"); + + g_free (escaped_desc); + } + + if (item->metadata) + { + gchar *metadata; + + metadata = bookmark_metadata_dump (item->metadata); + if (metadata) + { + g_string_append (retval, " " "<" XBEL_INFO_ELEMENT ">\n"); + g_string_append (retval, metadata); + g_string_append (retval, " " "\n"); + + g_free (metadata); + } + } + + g_string_append (retval, " \n"); + + return g_string_free (retval, FALSE); +} + +static BookmarkAppInfo * +bookmark_item_lookup_app_info (BookmarkItem *item, + const gchar *app_name) +{ + g_warn_if_fail (item != NULL && app_name != NULL); + + if (!item->metadata) + return NULL; + + return g_hash_table_lookup (item->metadata->apps_by_name, app_name); +} + +/************************* + * GBookmarkFile * + *************************/ + +static void +g_bookmark_file_init (GBookmarkFile *bookmark) +{ + bookmark->title = NULL; + bookmark->description = NULL; + + bookmark->items = NULL; + bookmark->items_by_uri = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); +} + +static void +g_bookmark_file_clear (GBookmarkFile *bookmark) +{ + g_free (bookmark->title); + g_free (bookmark->description); + + g_list_free_full (bookmark->items, (GDestroyNotify) bookmark_item_free); + bookmark->items = NULL; + + if (bookmark->items_by_uri) + { + g_hash_table_destroy (bookmark->items_by_uri); + + bookmark->items_by_uri = NULL; + } +} + +struct _ParseData +{ + ParserState state; + + GHashTable *namespaces; + + GBookmarkFile *bookmark_file; + BookmarkItem *current_item; +}; + +static ParseData * +parse_data_new (void) +{ + ParseData *retval; + + retval = g_new (ParseData, 1); + + retval->state = STATE_STARTED; + retval->namespaces = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); + retval->bookmark_file = NULL; + retval->current_item = NULL; + + return retval; +} + +static void +parse_data_free (ParseData *parse_data) +{ + g_hash_table_destroy (parse_data->namespaces); + + g_free (parse_data); +} + +#define IS_ATTRIBUTE(s,a) ((0 == strcmp ((s), (a)))) + +static void +parse_bookmark_element (GMarkupParseContext *context, + ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error) +{ + const gchar *uri, *added, *modified, *visited; + const gchar *attr; + gint i; + BookmarkItem *item; + GError *add_error; + + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_BOOKMARK)); + + i = 0; + uri = added = modified = visited = NULL; + for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) + { + if (IS_ATTRIBUTE (attr, XBEL_HREF_ATTRIBUTE)) + uri = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, XBEL_ADDED_ATTRIBUTE)) + added = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, XBEL_MODIFIED_ATTRIBUTE)) + modified = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, XBEL_VISITED_ATTRIBUTE)) + visited = attribute_values[i]; + else + { + /* bookmark is defined by the XBEL spec, so we need + * to error out if the element has different or + * missing attributes + */ + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, + _("Unexpected attribute “%s†for element “%sâ€"), + attr, + XBEL_BOOKMARK_ELEMENT); + return; + } + } + + if (!uri) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Attribute “%s†of element “%s†not found"), + XBEL_HREF_ATTRIBUTE, + XBEL_BOOKMARK_ELEMENT); + return; + } + + g_warn_if_fail (parse_data->current_item == NULL); + + item = bookmark_item_new (uri); + + if (added != NULL && !timestamp_from_iso8601 (added, &item->added, error)) + { + bookmark_item_free (item); + return; + } + + if (modified != NULL && !timestamp_from_iso8601 (modified, &item->modified, error)) + { + bookmark_item_free (item); + return; + } + + if (visited != NULL && !timestamp_from_iso8601 (visited, &item->visited, error)) + { + bookmark_item_free (item); + return; + } + + add_error = NULL; + g_bookmark_file_add_item (parse_data->bookmark_file, + item, + &add_error); + if (add_error) + { + bookmark_item_free (item); + + g_propagate_error (error, add_error); + + return; + } + + parse_data->current_item = item; +} + +static void +parse_application_element (GMarkupParseContext *context, + ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error) +{ + const gchar *name, *exec, *count, *stamp, *modified; + const gchar *attr; + gint i; + BookmarkItem *item; + BookmarkAppInfo *ai; + + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_APPLICATION)); + + i = 0; + name = exec = count = stamp = modified = NULL; + for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) + { + if (IS_ATTRIBUTE (attr, BOOKMARK_NAME_ATTRIBUTE)) + name = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_EXEC_ATTRIBUTE)) + exec = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_COUNT_ATTRIBUTE)) + count = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_TIMESTAMP_ATTRIBUTE)) + stamp = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_MODIFIED_ATTRIBUTE)) + modified = attribute_values[i]; + } + + /* the "name" and "exec" attributes are mandatory */ + if (!name) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Attribute “%s†of element “%s†not found"), + BOOKMARK_NAME_ATTRIBUTE, + BOOKMARK_APPLICATION_ELEMENT); + return; + } + + if (!exec) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Attribute “%s†of element “%s†not found"), + BOOKMARK_EXEC_ATTRIBUTE, + BOOKMARK_APPLICATION_ELEMENT); + return; + } + + g_warn_if_fail (parse_data->current_item != NULL); + item = parse_data->current_item; + + ai = bookmark_item_lookup_app_info (item, name); + if (!ai) + { + ai = bookmark_app_info_new (name); + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + item->metadata->applications = g_list_prepend (item->metadata->applications, ai); + g_hash_table_replace (item->metadata->apps_by_name, ai->name, ai); + } + + g_free (ai->exec); + ai->exec = g_strdup (exec); + + if (count) + ai->count = atoi (count); + else + ai->count = 1; + + g_clear_pointer (&ai->stamp, g_date_time_unref); + if (modified != NULL) + { + if (!timestamp_from_iso8601 (modified, &ai->stamp, error)) + return; + } + else + { + /* the timestamp attribute has been deprecated but we still parse + * it for backward compatibility + */ + if (stamp) + ai->stamp = g_date_time_new_from_unix_utc (atol (stamp)); + else + ai->stamp = g_date_time_new_now_utc (); + } +} + +static void +parse_mime_type_element (GMarkupParseContext *context, + ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error) +{ + const gchar *type; + const gchar *attr; + gint i; + BookmarkItem *item; + + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_MIME)); + + i = 0; + type = NULL; + for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) + { + if (IS_ATTRIBUTE (attr, MIME_TYPE_ATTRIBUTE)) + type = attribute_values[i]; + } + + if (!type) + type = "application/octet-stream"; + + g_warn_if_fail (parse_data->current_item != NULL); + item = parse_data->current_item; + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + g_free (item->metadata->mime_type); + item->metadata->mime_type = g_strdup (type); +} + +static void +parse_icon_element (GMarkupParseContext *context, + ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error) +{ + const gchar *href; + const gchar *type; + const gchar *attr; + gint i; + BookmarkItem *item; + + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_ICON)); + + i = 0; + href = NULL; + type = NULL; + for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) + { + if (IS_ATTRIBUTE (attr, BOOKMARK_HREF_ATTRIBUTE)) + href = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_TYPE_ATTRIBUTE)) + type = attribute_values[i]; + } + + /* the "href" attribute is mandatory */ + if (!href) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Attribute “%s†of element “%s†not found"), + BOOKMARK_HREF_ATTRIBUTE, + BOOKMARK_ICON_ELEMENT); + return; + } + + if (!type) + type = "application/octet-stream"; + + g_warn_if_fail (parse_data->current_item != NULL); + item = parse_data->current_item; + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + g_free (item->metadata->icon_href); + g_free (item->metadata->icon_mime); + item->metadata->icon_href = g_strdup (href); + item->metadata->icon_mime = g_strdup (type); +} + +/* scans through the attributes of an element for the "xmlns" pragma, and + * adds any resulting namespace declaration to a per-parser hashtable, using + * the namespace name as a key for the namespace URI; if no key was found, + * the namespace is considered as default, and stored under the "default" key. + * + * FIXME: this works on the assumption that the generator of the XBEL file + * is either this code or is smart enough to place the namespace declarations + * inside the main root node or inside the metadata node and does not redefine + * a namespace inside an inner node; this does *not* conform to the + * XML-NS standard, although is a close approximation. In order to make this + * conformant to the XML-NS specification we should use a per-element + * namespace table inside GMarkup and ask it to resolve the namespaces for us. + */ +static void +map_namespace_to_name (ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values) +{ + const gchar *attr; + gint i; + + g_warn_if_fail (parse_data != NULL); + + if (!attribute_names || !attribute_names[0]) + return; + + i = 0; + for (attr = attribute_names[i]; attr; attr = attribute_names[++i]) + { + if (g_str_has_prefix (attr, "xmlns")) + { + gchar *namespace_name, *namespace_uri; + gchar *p; + + p = g_utf8_strchr (attr, -1, ':'); + if (p) + p = g_utf8_next_char (p); + else + p = "default"; + + namespace_name = g_strdup (p); + namespace_uri = g_strdup (attribute_values[i]); + + g_hash_table_replace (parse_data->namespaces, + namespace_name, + namespace_uri); + } + } +} + +/* checks whether @element_full is equal to @element. + * + * if @namespace is set, it tries to resolve the namespace to a known URI, + * and if found is prepended to the element name, from which is separated + * using the character specified in the @sep parameter. + */ +static gboolean +is_element_full (ParseData *parse_data, + const gchar *element_full, + const gchar *namespace, + const gchar *element, + const gchar sep) +{ + gchar *ns_uri, *ns_name; + const gchar *p, *element_name; + gboolean retval; + + g_warn_if_fail (parse_data != NULL); + g_warn_if_fail (element_full != NULL); + + if (!element) + return FALSE; + + /* no namespace requested: dumb element compare */ + if (!namespace) + return (0 == strcmp (element_full, element)); + + /* search for namespace separator; if none found, assume we are under the + * default namespace, and set ns_name to our "default" marker; if no default + * namespace has been set, just do a plain comparison between @full_element + * and @element. + */ + p = g_utf8_strchr (element_full, -1, ':'); + if (p) + { + ns_name = g_strndup (element_full, p - element_full); + element_name = g_utf8_next_char (p); + } + else + { + ns_name = g_strdup ("default"); + element_name = element_full; + } + + ns_uri = g_hash_table_lookup (parse_data->namespaces, ns_name); + if (!ns_uri) + { + /* no default namespace found */ + g_free (ns_name); + + return (0 == strcmp (element_full, element)); + } + + retval = (0 == strcmp (ns_uri, namespace) && + 0 == strcmp (element_name, element)); + + g_free (ns_name); + + return retval; +} + +#define IS_ELEMENT(p,s,e) (is_element_full ((p), (s), NULL, (e), '\0')) +#define IS_ELEMENT_NS(p,s,n,e) (is_element_full ((p), (s), (n), (e), '|')) + +static const gchar * +parser_state_to_element_name (ParserState state) +{ + switch (state) + { + case STATE_STARTED: + case STATE_FINISHED: + return "(top-level)"; + case STATE_ROOT: + return XBEL_ROOT_ELEMENT; + case STATE_BOOKMARK: + return XBEL_BOOKMARK_ELEMENT; + case STATE_TITLE: + return XBEL_TITLE_ELEMENT; + case STATE_DESC: + return XBEL_DESC_ELEMENT; + case STATE_INFO: + return XBEL_INFO_ELEMENT; + case STATE_METADATA: + return XBEL_METADATA_ELEMENT; + case STATE_APPLICATIONS: + return BOOKMARK_APPLICATIONS_ELEMENT; + case STATE_APPLICATION: + return BOOKMARK_APPLICATION_ELEMENT; + case STATE_GROUPS: + return BOOKMARK_GROUPS_ELEMENT; + case STATE_GROUP: + return BOOKMARK_GROUP_ELEMENT; + case STATE_MIME: + return MIME_TYPE_ELEMENT; + case STATE_ICON: + return BOOKMARK_ICON_ELEMENT; + default: + g_assert_not_reached (); + } +} + +static void +start_element_raw_cb (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseData *parse_data = (ParseData *) user_data; + + /* we must check for namespace declarations first + * + * XXX - we could speed up things by checking for namespace declarations + * only on the root node, where they usually are; this would probably break + * on streams not produced by us or by "smart" generators + */ + map_namespace_to_name (parse_data, attribute_names, attribute_values); + + switch (parse_data->state) + { + case STATE_STARTED: + if (IS_ELEMENT (parse_data, element_name, XBEL_ROOT_ELEMENT)) + { + const gchar *attr; + gint i; + + i = 0; + for (attr = attribute_names[i]; attr; attr = attribute_names[++i]) + { + if ((IS_ATTRIBUTE (attr, XBEL_VERSION_ATTRIBUTE)) && + (0 == strcmp (attribute_values[i], XBEL_VERSION))) + parse_data->state = STATE_ROOT; + } + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag “%sâ€, tag “%s†expected"), + element_name, XBEL_ROOT_ELEMENT); + break; + case STATE_ROOT: + if (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT)) + parse_data->state = STATE_TITLE; + else if (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT)) + parse_data->state = STATE_DESC; + else if (IS_ELEMENT (parse_data, element_name, XBEL_BOOKMARK_ELEMENT)) + { + GError *inner_error = NULL; + + parse_data->state = STATE_BOOKMARK; + + parse_bookmark_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag “%s†inside “%sâ€"), + element_name, + XBEL_ROOT_ELEMENT); + break; + case STATE_BOOKMARK: + if (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT)) + parse_data->state = STATE_TITLE; + else if (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT)) + parse_data->state = STATE_DESC; + else if (IS_ELEMENT (parse_data, element_name, XBEL_INFO_ELEMENT)) + parse_data->state = STATE_INFO; + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag “%s†inside “%sâ€"), + element_name, + XBEL_BOOKMARK_ELEMENT); + break; + case STATE_INFO: + if (IS_ELEMENT (parse_data, element_name, XBEL_METADATA_ELEMENT)) + { + const gchar *attr; + gint i; + + i = 0; + for (attr = attribute_names[i]; attr; attr = attribute_names[++i]) + { + if ((IS_ATTRIBUTE (attr, XBEL_OWNER_ATTRIBUTE)) && + (0 == strcmp (attribute_values[i], BOOKMARK_METADATA_OWNER))) + { + parse_data->state = STATE_METADATA; + + if (!parse_data->current_item->metadata) + parse_data->current_item->metadata = bookmark_metadata_new (); + } + } + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag “%sâ€, tag “%s†expected"), + element_name, + XBEL_METADATA_ELEMENT); + break; + case STATE_METADATA: + if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATIONS_ELEMENT)) + parse_data->state = STATE_APPLICATIONS; + else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUPS_ELEMENT)) + parse_data->state = STATE_GROUPS; + else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_PRIVATE_ELEMENT)) + parse_data->current_item->metadata->is_private = TRUE; + else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT)) + { + GError *inner_error = NULL; + + parse_data->state = STATE_ICON; + + parse_icon_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else if (IS_ELEMENT_NS (parse_data, element_name, MIME_NAMESPACE_URI, MIME_TYPE_ELEMENT)) + { + GError *inner_error = NULL; + + parse_data->state = STATE_MIME; + + parse_mime_type_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Unexpected tag “%s†inside “%sâ€"), + element_name, + XBEL_METADATA_ELEMENT); + break; + case STATE_APPLICATIONS: + if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATION_ELEMENT)) + { + GError *inner_error = NULL; + + parse_data->state = STATE_APPLICATION; + + parse_application_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag “%sâ€, tag “%s†expected"), + element_name, + BOOKMARK_APPLICATION_ELEMENT); + break; + case STATE_GROUPS: + if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUP_ELEMENT)) + parse_data->state = STATE_GROUP; + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag “%sâ€, tag “%s†expected"), + element_name, + BOOKMARK_GROUP_ELEMENT); + break; + + case STATE_TITLE: + case STATE_DESC: + case STATE_APPLICATION: + case STATE_GROUP: + case STATE_MIME: + case STATE_ICON: + case STATE_FINISHED: + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag “%s†inside “%sâ€"), + element_name, + parser_state_to_element_name (parse_data->state)); + break; + + default: + g_assert_not_reached (); + break; + } +} + +static void +end_element_raw_cb (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseData *parse_data = (ParseData *) user_data; + + if (IS_ELEMENT (parse_data, element_name, XBEL_ROOT_ELEMENT)) + parse_data->state = STATE_FINISHED; + else if (IS_ELEMENT (parse_data, element_name, XBEL_BOOKMARK_ELEMENT)) + { + parse_data->current_item = NULL; + + parse_data->state = STATE_ROOT; + } + else if ((IS_ELEMENT (parse_data, element_name, XBEL_INFO_ELEMENT)) || + (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT)) || + (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT))) + { + if (parse_data->current_item) + parse_data->state = STATE_BOOKMARK; + else + parse_data->state = STATE_ROOT; + } + else if (IS_ELEMENT (parse_data, element_name, XBEL_METADATA_ELEMENT)) + parse_data->state = STATE_INFO; + else if (IS_ELEMENT_NS (parse_data, element_name, + BOOKMARK_NAMESPACE_URI, + BOOKMARK_APPLICATION_ELEMENT)) + parse_data->state = STATE_APPLICATIONS; + else if (IS_ELEMENT_NS (parse_data, element_name, + BOOKMARK_NAMESPACE_URI, + BOOKMARK_GROUP_ELEMENT)) + parse_data->state = STATE_GROUPS; + else if ((IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATIONS_ELEMENT)) || + (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUPS_ELEMENT)) || + (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_PRIVATE_ELEMENT)) || + (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT)) || + (IS_ELEMENT_NS (parse_data, element_name, MIME_NAMESPACE_URI, MIME_TYPE_ELEMENT))) + parse_data->state = STATE_METADATA; +} + +static void +text_raw_cb (GMarkupParseContext *context, + const gchar *text, + gsize length, + gpointer user_data, + GError **error) +{ + ParseData *parse_data = (ParseData *) user_data; + gchar *payload; + + payload = g_strndup (text, length); + + switch (parse_data->state) + { + case STATE_TITLE: + if (parse_data->current_item) + { + g_free (parse_data->current_item->title); + parse_data->current_item->title = g_strdup (payload); + } + else + { + g_free (parse_data->bookmark_file->title); + parse_data->bookmark_file->title = g_strdup (payload); + } + break; + case STATE_DESC: + if (parse_data->current_item) + { + g_free (parse_data->current_item->description); + parse_data->current_item->description = g_strdup (payload); + } + else + { + g_free (parse_data->bookmark_file->description); + parse_data->bookmark_file->description = g_strdup (payload); + } + break; + case STATE_GROUP: + { + GList *groups; + + g_warn_if_fail (parse_data->current_item != NULL); + + if (!parse_data->current_item->metadata) + parse_data->current_item->metadata = bookmark_metadata_new (); + + groups = parse_data->current_item->metadata->groups; + parse_data->current_item->metadata->groups = g_list_prepend (groups, g_strdup (payload)); + } + break; + case STATE_ROOT: + case STATE_BOOKMARK: + case STATE_INFO: + case STATE_METADATA: + case STATE_APPLICATIONS: + case STATE_APPLICATION: + case STATE_GROUPS: + case STATE_MIME: + case STATE_ICON: + break; + default: + g_warn_if_reached (); + break; + } + + g_free (payload); +} + +static const GMarkupParser markup_parser = +{ + start_element_raw_cb, /* start_element */ + end_element_raw_cb, /* end_element */ + text_raw_cb, /* text */ + NULL, /* passthrough */ + NULL +}; + +static gboolean +g_bookmark_file_parse (GBookmarkFile *bookmark, + const gchar *buffer, + gsize length, + GError **error) +{ + GMarkupParseContext *context; + ParseData *parse_data; + GError *parse_error, *end_error; + gboolean retval; + + g_warn_if_fail (bookmark != NULL); + + if (!buffer) + return FALSE; + + parse_error = NULL; + end_error = NULL; + + if (length == (gsize) -1) + length = strlen (buffer); + + parse_data = parse_data_new (); + parse_data->bookmark_file = bookmark; + + context = g_markup_parse_context_new (&markup_parser, + 0, + parse_data, + (GDestroyNotify) parse_data_free); + + retval = g_markup_parse_context_parse (context, + buffer, + length, + &parse_error); + if (!retval) + g_propagate_error (error, parse_error); + else + { + retval = g_markup_parse_context_end_parse (context, &end_error); + if (!retval) + g_propagate_error (error, end_error); + } + + g_markup_parse_context_free (context); + + return retval; +} + +static gchar * +g_bookmark_file_dump (GBookmarkFile *bookmark, + gsize *length, + GError **error) +{ + GString *retval; + gchar *buffer; + GList *l; + + retval = g_string_sized_new (4096); + + g_string_append (retval, + "\n" +#if 0 + /* XXX - do we really need the doctype? */ + "\n" +#endif + "<" XBEL_ROOT_ELEMENT " " XBEL_VERSION_ATTRIBUTE "=\"" XBEL_VERSION "\"\n" + " xmlns:" BOOKMARK_NAMESPACE_NAME "=\"" BOOKMARK_NAMESPACE_URI "\"\n" + " xmlns:" MIME_NAMESPACE_NAME "=\"" MIME_NAMESPACE_URI "\"\n>"); + + if (bookmark->title) + { + gchar *escaped_title; + + escaped_title = g_markup_escape_text (bookmark->title, -1); + + buffer = g_strconcat (" " + "<" XBEL_TITLE_ELEMENT ">", + escaped_title, + "\n", NULL); + + g_string_append (retval, buffer); + + g_free (buffer); + g_free (escaped_title); + } + + if (bookmark->description) + { + gchar *escaped_desc; + + escaped_desc = g_markup_escape_text (bookmark->description, -1); + + buffer = g_strconcat (" " + "<" XBEL_DESC_ELEMENT ">", + escaped_desc, + "\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); + g_free (escaped_desc); + } + + if (!bookmark->items) + goto out; + else + retval = g_string_append (retval, "\n"); + + /* the items are stored in reverse order */ + for (l = g_list_last (bookmark->items); + l != NULL; + l = l->prev) + { + BookmarkItem *item = (BookmarkItem *) l->data; + gchar *item_dump; + + item_dump = bookmark_item_dump (item); + if (!item_dump) + continue; + + retval = g_string_append (retval, item_dump); + + g_free (item_dump); + } + +out: + g_string_append (retval, ""); + + if (length) + *length = retval->len; + + return g_string_free (retval, FALSE); +} + +/************** + * Misc * + **************/ + +static gboolean +timestamp_from_iso8601 (const gchar *iso_date, + GDateTime **out_date_time, + GError **error) +{ + GDateTime *dt = g_date_time_new_from_iso8601 (iso_date, NULL); + if (dt == NULL) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, G_BOOKMARK_FILE_ERROR_READ, + _("Invalid date/time ‘%s’ in bookmark file"), iso_date); + return FALSE; + } + + *out_date_time = g_steal_pointer (&dt); + return TRUE; +} + +G_DEFINE_QUARK (g-bookmark-file-error-quark, g_bookmark_file_error) + +/******************** + * Public API * + ********************/ + +/** + * g_bookmark_file_new: (constructor) + * + * Creates a new empty #GBookmarkFile object. + * + * Use g_bookmark_file_load_from_file(), g_bookmark_file_load_from_data() + * or g_bookmark_file_load_from_data_dirs() to read an existing bookmark + * file. + * + * Returns: an empty #GBookmarkFile + * + * Since: 2.12 + */ +GBookmarkFile * +g_bookmark_file_new (void) +{ + GBookmarkFile *bookmark; + + bookmark = g_new (GBookmarkFile, 1); + + g_bookmark_file_init (bookmark); + + return bookmark; +} + +/** + * g_bookmark_file_free: + * @bookmark: a #GBookmarkFile + * + * Frees a #GBookmarkFile. + * + * Since: 2.12 + */ +void +g_bookmark_file_free (GBookmarkFile *bookmark) +{ + if (!bookmark) + return; + + g_bookmark_file_clear (bookmark); + + g_free (bookmark); +} + +/** + * g_bookmark_file_load_from_data: + * @bookmark: an empty #GBookmarkFile struct + * @data: (array length=length) (element-type guint8): desktop bookmarks + * loaded in memory + * @length: the length of @data in bytes + * @error: return location for a #GError, or %NULL + * + * Loads a bookmark file from memory into an empty #GBookmarkFile + * structure. If the object cannot be created then @error is set to a + * #GBookmarkFileError. + * + * Returns: %TRUE if a desktop bookmark could be loaded. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_load_from_data (GBookmarkFile *bookmark, + const gchar *data, + gsize length, + GError **error) +{ + GError *parse_error; + gboolean retval; + + g_return_val_if_fail (bookmark != NULL, FALSE); + + if (length == (gsize) -1) + length = strlen (data); + + if (bookmark->items) + { + g_bookmark_file_clear (bookmark); + g_bookmark_file_init (bookmark); + } + + parse_error = NULL; + retval = g_bookmark_file_parse (bookmark, data, length, &parse_error); + + if (!retval) + g_propagate_error (error, parse_error); + + return retval; +} + +/** + * g_bookmark_file_load_from_file: + * @bookmark: an empty #GBookmarkFile struct + * @filename: (type filename): the path of a filename to load, in the + * GLib file name encoding + * @error: return location for a #GError, or %NULL + * + * Loads a desktop bookmark file into an empty #GBookmarkFile structure. + * If the file could not be loaded then @error is set to either a #GFileError + * or #GBookmarkFileError. + * + * Returns: %TRUE if a desktop bookmark file could be loaded + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_load_from_file (GBookmarkFile *bookmark, + const gchar *filename, + GError **error) +{ + gboolean ret = FALSE; + gchar *buffer = NULL; + gsize len; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + + if (!g_file_get_contents (filename, &buffer, &len, error)) + goto out; + + if (!g_bookmark_file_load_from_data (bookmark, buffer, len, error)) + goto out; + + ret = TRUE; + out: + g_free (buffer); + return ret; +} + + +/* Iterates through all the directories in *dirs trying to + * find file. When it successfully locates file, returns a + * string its absolute path. It also leaves the unchecked + * directories in *dirs. You should free the returned string + * + * Adapted from gkeyfile.c + */ +static gchar * +find_file_in_data_dirs (const gchar *file, + gchar ***dirs, + GError **error) +{ + gchar **data_dirs, *data_dir, *path; + + path = NULL; + + if (dirs == NULL) + return NULL; + + data_dirs = *dirs; + path = NULL; + while (data_dirs && (data_dir = *data_dirs) && !path) + { + gchar *candidate_file, *sub_dir; + + candidate_file = (gchar *) file; + sub_dir = g_strdup (""); + while (candidate_file != NULL && !path) + { + gchar *p; + + path = g_build_filename (data_dir, sub_dir, + candidate_file, NULL); + + candidate_file = strchr (candidate_file, '-'); + + if (candidate_file == NULL) + break; + + candidate_file++; + + g_free (sub_dir); + sub_dir = g_strndup (file, candidate_file - file - 1); + + for (p = sub_dir; *p != '\0'; p++) + { + if (*p == '-') + *p = G_DIR_SEPARATOR; + } + } + g_free (sub_dir); + data_dirs++; + } + + *dirs = data_dirs; + + if (!path) + { + g_set_error_literal (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND, + _("No valid bookmark file found in data dirs")); + + return NULL; + } + + return path; +} + + +/** + * g_bookmark_file_load_from_data_dirs: + * @bookmark: a #GBookmarkFile + * @file: (type filename): a relative path to a filename to open and parse + * @full_path: (out) (optional) (type filename): return location for a string + * containing the full path of the file, or %NULL + * @error: return location for a #GError, or %NULL + * + * This function looks for a desktop bookmark file named @file in the + * paths returned from g_get_user_data_dir() and g_get_system_data_dirs(), + * loads the file into @bookmark and returns the file's full path in + * @full_path. If the file could not be loaded then @error is + * set to either a #GFileError or #GBookmarkFileError. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_load_from_data_dirs (GBookmarkFile *bookmark, + const gchar *file, + gchar **full_path, + GError **error) +{ + GError *file_error = NULL; + gchar **all_data_dirs, **data_dirs; + const gchar *user_data_dir; + const gchar * const * system_data_dirs; + gsize i, j; + gchar *output_path; + gboolean found_file; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (!g_path_is_absolute (file), FALSE); + + user_data_dir = g_get_user_data_dir (); + system_data_dirs = g_get_system_data_dirs (); + all_data_dirs = g_new0 (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2); + + i = 0; + all_data_dirs[i++] = g_strdup (user_data_dir); + + j = 0; + while (system_data_dirs[j] != NULL) + all_data_dirs[i++] = g_strdup (system_data_dirs[j++]); + + found_file = FALSE; + data_dirs = all_data_dirs; + output_path = NULL; + while (*data_dirs != NULL && !found_file) + { + g_free (output_path); + + output_path = find_file_in_data_dirs (file, &data_dirs, &file_error); + + if (file_error) + { + g_propagate_error (error, file_error); + break; + } + + found_file = g_bookmark_file_load_from_file (bookmark, + output_path, + &file_error); + if (file_error) + { + g_propagate_error (error, file_error); + break; + } + } + + if (found_file && full_path) + *full_path = output_path; + else + g_free (output_path); + + g_strfreev (all_data_dirs); + + return found_file; +} + + +/** + * g_bookmark_file_to_data: + * @bookmark: a #GBookmarkFile + * @length: (out) (optional): return location for the length of the returned string, or %NULL + * @error: return location for a #GError, or %NULL + * + * This function outputs @bookmark as a string. + * + * Returns: (transfer full) (array length=length) (element-type guint8): + * a newly allocated string holding the contents of the #GBookmarkFile + * + * Since: 2.12 + */ +gchar * +g_bookmark_file_to_data (GBookmarkFile *bookmark, + gsize *length, + GError **error) +{ + GError *write_error = NULL; + gchar *retval; + + g_return_val_if_fail (bookmark != NULL, NULL); + + retval = g_bookmark_file_dump (bookmark, length, &write_error); + if (write_error) + { + g_propagate_error (error, write_error); + + return NULL; + } + + return retval; +} + +/** + * g_bookmark_file_to_file: + * @bookmark: a #GBookmarkFile + * @filename: (type filename): path of the output file + * @error: return location for a #GError, or %NULL + * + * This function outputs @bookmark into a file. The write process is + * guaranteed to be atomic by using g_file_set_contents() internally. + * + * Returns: %TRUE if the file was successfully written. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_to_file (GBookmarkFile *bookmark, + const gchar *filename, + GError **error) +{ + gchar *data; + GError *data_error, *write_error; + gsize len; + gboolean retval; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + + data_error = NULL; + data = g_bookmark_file_to_data (bookmark, &len, &data_error); + if (data_error) + { + g_propagate_error (error, data_error); + + return FALSE; + } + + write_error = NULL; + g_file_set_contents (filename, data, len, &write_error); + if (write_error) + { + g_propagate_error (error, write_error); + + retval = FALSE; + } + else + retval = TRUE; + + g_free (data); + + return retval; +} + +static BookmarkItem * +g_bookmark_file_lookup_item (GBookmarkFile *bookmark, + const gchar *uri) +{ + g_warn_if_fail (bookmark != NULL && uri != NULL); + + return g_hash_table_lookup (bookmark->items_by_uri, uri); +} + +/* this function adds a new item to the list */ +static void +g_bookmark_file_add_item (GBookmarkFile *bookmark, + BookmarkItem *item, + GError **error) +{ + g_warn_if_fail (bookmark != NULL); + g_warn_if_fail (item != NULL); + + /* this should never happen; and if it does, then we are + * screwing up something big time. + */ + if (G_UNLIKELY (g_bookmark_file_has_item (bookmark, item->uri))) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_URI, + _("A bookmark for URI “%s†already exists"), + item->uri); + return; + } + + bookmark->items = g_list_prepend (bookmark->items, item); + + g_hash_table_replace (bookmark->items_by_uri, + item->uri, + item); + + if (item->added == NULL) + item->added = g_date_time_new_now_utc (); + + if (item->modified == NULL) + item->modified = g_date_time_new_now_utc (); + + if (item->visited == NULL) + item->visited = g_date_time_new_now_utc (); +} + +/** + * g_bookmark_file_remove_item: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Removes the bookmark for @uri from the bookmark file @bookmark. + * + * Returns: %TRUE if the bookmark was removed successfully. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_remove_item (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return FALSE; + } + + bookmark->items = g_list_remove (bookmark->items, item); + g_hash_table_remove (bookmark->items_by_uri, item->uri); + + bookmark_item_free (item); + + return TRUE; +} + +/** + * g_bookmark_file_has_item: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * + * Looks whether the desktop bookmark has an item with its URI set to @uri. + * + * Returns: %TRUE if @uri is inside @bookmark, %FALSE otherwise + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_has_item (GBookmarkFile *bookmark, + const gchar *uri) +{ + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + return (NULL != g_hash_table_lookup (bookmark->items_by_uri, uri)); +} + +/** + * g_bookmark_file_get_uris: + * @bookmark: a #GBookmarkFile + * @length: (out) (optional): return location for the number of returned URIs, or %NULL + * + * Returns all URIs of the bookmarks in the bookmark file @bookmark. + * The array of returned URIs will be %NULL-terminated, so @length may + * optionally be %NULL. + * + * Returns: (array length=length) (transfer full): a newly allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * + * Since: 2.12 + */ +gchar ** +g_bookmark_file_get_uris (GBookmarkFile *bookmark, + gsize *length) +{ + GList *l; + gchar **uris; + gsize i, n_items; + + g_return_val_if_fail (bookmark != NULL, NULL); + + n_items = g_list_length (bookmark->items); + uris = g_new0 (gchar *, n_items + 1); + + /* the items are stored in reverse order, so we walk the list backward */ + for (l = g_list_last (bookmark->items), i = 0; l != NULL; l = l->prev) + { + BookmarkItem *item = (BookmarkItem *) l->data; + + g_warn_if_fail (item != NULL); + + uris[i++] = g_strdup (item->uri); + } + uris[i] = NULL; + + if (length) + *length = i; + + return uris; +} + +/** + * g_bookmark_file_set_title: + * @bookmark: a #GBookmarkFile + * @uri: (nullable): a valid URI or %NULL + * @title: a UTF-8 encoded string + * + * Sets @title as the title of the bookmark for @uri inside the + * bookmark file @bookmark. + * + * If @uri is %NULL, the title of @bookmark is set. + * + * If a bookmark for @uri cannot be found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_title (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *title) +{ + g_return_if_fail (bookmark != NULL); + + if (!uri) + { + g_free (bookmark->title); + bookmark->title = g_strdup (title); + } + else + { + BookmarkItem *item; + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + g_free (item->title); + item->title = g_strdup (title); + + bookmark_item_touch_modified (item); + } +} + +/** + * g_bookmark_file_get_title: + * @bookmark: a #GBookmarkFile + * @uri: (nullable): a valid URI or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns the title of the bookmark for @uri. + * + * If @uri is %NULL, the title of @bookmark is returned. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: (transfer full): a newly allocated string or %NULL if the specified + * URI cannot be found. + * + * Since: 2.12 + */ +gchar * +g_bookmark_file_get_title (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + + if (!uri) + return g_strdup (bookmark->title); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return NULL; + } + + return g_strdup (item->title); +} + +/** + * g_bookmark_file_set_description: + * @bookmark: a #GBookmarkFile + * @uri: (nullable): a valid URI or %NULL + * @description: a string + * + * Sets @description as the description of the bookmark for @uri. + * + * If @uri is %NULL, the description of @bookmark is set. + * + * If a bookmark for @uri cannot be found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_description (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *description) +{ + g_return_if_fail (bookmark != NULL); + + if (!uri) + { + g_free (bookmark->description); + bookmark->description = g_strdup (description); + } + else + { + BookmarkItem *item; + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + g_free (item->description); + item->description = g_strdup (description); + + bookmark_item_touch_modified (item); + } +} + +/** + * g_bookmark_file_get_description: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Retrieves the description of the bookmark for @uri. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: (transfer full): a newly allocated string or %NULL if the specified + * URI cannot be found. + * + * Since: 2.12 + */ +gchar * +g_bookmark_file_get_description (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + + if (!uri) + return g_strdup (bookmark->description); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return NULL; + } + + return g_strdup (item->description); +} + +/** + * g_bookmark_file_set_mime_type: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @mime_type: a MIME type + * + * Sets @mime_type as the MIME type of the bookmark for @uri. + * + * If a bookmark for @uri cannot be found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_mime_type (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *mime_type) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (mime_type != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + g_free (item->metadata->mime_type); + + item->metadata->mime_type = g_strdup (mime_type); + bookmark_item_touch_modified (item); +} + +/** + * g_bookmark_file_get_mime_type: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Retrieves the MIME type of the resource pointed by @uri. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the + * event that the MIME type cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_INVALID_VALUE. + * + * Returns: (transfer full): a newly allocated string or %NULL if the specified + * URI cannot be found. + * + * Since: 2.12 + */ +gchar * +g_bookmark_file_get_mime_type (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return NULL; + } + + if (!item->metadata) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_VALUE, + _("No MIME type defined in the bookmark for URI “%sâ€"), + uri); + return NULL; + } + + return g_strdup (item->metadata->mime_type); +} + +/** + * g_bookmark_file_set_is_private: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @is_private: %TRUE if the bookmark should be marked as private + * + * Sets the private flag of the bookmark for @uri. + * + * If a bookmark for @uri cannot be found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_is_private (GBookmarkFile *bookmark, + const gchar *uri, + gboolean is_private) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + item->metadata->is_private = (is_private == TRUE); + bookmark_item_touch_modified (item); +} + +/** + * g_bookmark_file_get_is_private: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets whether the private flag of the bookmark for @uri is set. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the + * event that the private flag cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_INVALID_VALUE. + * + * Returns: %TRUE if the private flag is set, %FALSE otherwise. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_get_is_private (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return FALSE; + } + + if (!item->metadata) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_VALUE, + _("No private flag has been defined in bookmark for URI “%sâ€"), + uri); + return FALSE; + } + + return item->metadata->is_private; +} + +/** + * g_bookmark_file_set_added: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @added: a timestamp or -1 to use the current time + * + * Sets the time the bookmark for @uri was added into @bookmark. + * + * If no bookmark for @uri is found then it is created. + * + * Since: 2.12 + * Deprecated: 2.66: Use g_bookmark_file_set_added_date_time() instead, as + * `time_t` is deprecated due to the year 2038 problem. + */ +void +g_bookmark_file_set_added (GBookmarkFile *bookmark, + const gchar *uri, + time_t added) +{ + GDateTime *added_dt = (added != (time_t) -1) ? g_date_time_new_from_unix_utc (added) : g_date_time_new_now_utc (); + g_bookmark_file_set_added_date_time (bookmark, uri, added_dt); + g_date_time_unref (added_dt); +} + +/** + * g_bookmark_file_set_added_date_time: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @added: a #GDateTime + * + * Sets the time the bookmark for @uri was added into @bookmark. + * + * If no bookmark for @uri is found then it is created. + * + * Since: 2.66 + */ +void +g_bookmark_file_set_added_date_time (GBookmarkFile *bookmark, + const char *uri, + GDateTime *added) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (added != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + g_clear_pointer (&item->added, g_date_time_unref); + item->added = g_date_time_ref (added); + g_clear_pointer (&item->modified, g_date_time_unref); + item->modified = g_date_time_ref (added); +} + +/** + * g_bookmark_file_get_added: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time the bookmark for @uri was added to @bookmark + * + * In the event the URI cannot be found, -1 is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: a timestamp + * + * Since: 2.12 + * Deprecated: 2.66: Use g_bookmark_file_get_added_date_time() instead, as + * `time_t` is deprecated due to the year 2038 problem. + */ +time_t +g_bookmark_file_get_added (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + GDateTime *added = g_bookmark_file_get_added_date_time (bookmark, uri, error); + return (added != NULL) ? g_date_time_to_unix (added) : (time_t) -1; +} + +/** + * g_bookmark_file_get_added_date_time: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time the bookmark for @uri was added to @bookmark + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: (transfer none): a #GDateTime + * + * Since: 2.66 + */ +GDateTime * +g_bookmark_file_get_added_date_time (GBookmarkFile *bookmark, + const char *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return NULL; + } + + return item->added; +} + +/** + * g_bookmark_file_set_modified: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @modified: a timestamp or -1 to use the current time + * + * Sets the last time the bookmark for @uri was last modified. + * + * If no bookmark for @uri is found then it is created. + * + * The "modified" time should only be set when the bookmark's meta-data + * was actually changed. Every function of #GBookmarkFile that + * modifies a bookmark also changes the modification time, except for + * g_bookmark_file_set_visited_date_time(). + * + * Since: 2.12 + * Deprecated: 2.66: Use g_bookmark_file_set_modified_date_time() instead, as + * `time_t` is deprecated due to the year 2038 problem. + */ +void +g_bookmark_file_set_modified (GBookmarkFile *bookmark, + const gchar *uri, + time_t modified) +{ + GDateTime *modified_dt = (modified != (time_t) -1) ? g_date_time_new_from_unix_utc (modified) : g_date_time_new_now_utc (); + g_bookmark_file_set_modified_date_time (bookmark, uri, modified_dt); + g_date_time_unref (modified_dt); +} + +/** + * g_bookmark_file_set_modified_date_time: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @modified: a #GDateTime + * + * Sets the last time the bookmark for @uri was last modified. + * + * If no bookmark for @uri is found then it is created. + * + * The "modified" time should only be set when the bookmark's meta-data + * was actually changed. Every function of #GBookmarkFile that + * modifies a bookmark also changes the modification time, except for + * g_bookmark_file_set_visited_date_time(). + * + * Since: 2.66 + */ +void +g_bookmark_file_set_modified_date_time (GBookmarkFile *bookmark, + const char *uri, + GDateTime *modified) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (modified != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + g_clear_pointer (&item->modified, g_date_time_unref); + item->modified = g_date_time_ref (modified); +} + +/** + * g_bookmark_file_get_modified: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time when the bookmark for @uri was last modified. + * + * In the event the URI cannot be found, -1 is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: a timestamp + * + * Since: 2.12 + * Deprecated: 2.66: Use g_bookmark_file_get_modified_date_time() instead, as + * `time_t` is deprecated due to the year 2038 problem. + */ +time_t +g_bookmark_file_get_modified (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + GDateTime *modified = g_bookmark_file_get_modified_date_time (bookmark, uri, error); + return (modified != NULL) ? g_date_time_to_unix (modified) : (time_t) -1; +} + +/** + * g_bookmark_file_get_modified_date_time: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time when the bookmark for @uri was last modified. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: (transfer none): a #GDateTime + * + * Since: 2.66 + */ +GDateTime * +g_bookmark_file_get_modified_date_time (GBookmarkFile *bookmark, + const char *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return NULL; + } + + return item->modified; +} + +/** + * g_bookmark_file_set_visited: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @visited: a timestamp or -1 to use the current time + * + * Sets the time the bookmark for @uri was last visited. + * + * If no bookmark for @uri is found then it is created. + * + * The "visited" time should only be set if the bookmark was launched, + * either using the command line retrieved by g_bookmark_file_get_application_info() + * or by the default application for the bookmark's MIME type, retrieved + * using g_bookmark_file_get_mime_type(). Changing the "visited" time + * does not affect the "modified" time. + * + * Since: 2.12 + * Deprecated: 2.66: Use g_bookmark_file_set_visited_date_time() instead, as + * `time_t` is deprecated due to the year 2038 problem. + */ +void +g_bookmark_file_set_visited (GBookmarkFile *bookmark, + const gchar *uri, + time_t visited) +{ + GDateTime *visited_dt = (visited != (time_t) -1) ? g_date_time_new_from_unix_utc (visited) : g_date_time_new_now_utc (); + g_bookmark_file_set_visited_date_time (bookmark, uri, visited_dt); + g_date_time_unref (visited_dt); +} + +/** + * g_bookmark_file_set_visited_date_time: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @visited: a #GDateTime + * + * Sets the time the bookmark for @uri was last visited. + * + * If no bookmark for @uri is found then it is created. + * + * The "visited" time should only be set if the bookmark was launched, + * either using the command line retrieved by g_bookmark_file_get_application_info() + * or by the default application for the bookmark's MIME type, retrieved + * using g_bookmark_file_get_mime_type(). Changing the "visited" time + * does not affect the "modified" time. + * + * Since: 2.66 + */ +void +g_bookmark_file_set_visited_date_time (GBookmarkFile *bookmark, + const char *uri, + GDateTime *visited) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (visited != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + g_clear_pointer (&item->visited, g_date_time_unref); + item->visited = g_date_time_ref (visited); +} + +/** + * g_bookmark_file_get_visited: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time the bookmark for @uri was last visited. + * + * In the event the URI cannot be found, -1 is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: a timestamp. + * + * Since: 2.12 + * Deprecated: 2.66: Use g_bookmark_file_get_visited_date_time() instead, as + * `time_t` is deprecated due to the year 2038 problem. + */ +time_t +g_bookmark_file_get_visited (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + GDateTime *visited = g_bookmark_file_get_visited_date_time (bookmark, uri, error); + return (visited != NULL) ? g_date_time_to_unix (visited) : (time_t) -1; +} + +/** + * g_bookmark_file_get_visited_date_time: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time the bookmark for @uri was last visited. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: (transfer none): a #GDateTime + * + * Since: 2.66 + */ +GDateTime * +g_bookmark_file_get_visited_date_time (GBookmarkFile *bookmark, + const char *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return NULL; + } + + return item->visited; +} + +/** + * g_bookmark_file_has_group: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @group: the group name to be searched + * @error: return location for a #GError, or %NULL + * + * Checks whether @group appears in the list of groups to which + * the bookmark for @uri belongs to. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: %TRUE if @group was found. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_has_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group, + GError **error) +{ + BookmarkItem *item; + GList *l; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return FALSE; + } + + if (!item->metadata) + return FALSE; + + for (l = item->metadata->groups; l != NULL; l = l->next) + { + if (strcmp (l->data, group) == 0) + return TRUE; + } + + return FALSE; + +} + +/** + * g_bookmark_file_add_group: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @group: the group name to be added + * + * Adds @group to the list of groups to which the bookmark for @uri + * belongs to. + * + * If no bookmark for @uri is found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_add_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (group != NULL && group[0] != '\0'); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + if (!g_bookmark_file_has_group (bookmark, uri, group, NULL)) + { + item->metadata->groups = g_list_prepend (item->metadata->groups, + g_strdup (group)); + + bookmark_item_touch_modified (item); + } +} + +/** + * g_bookmark_file_remove_group: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @group: the group name to be removed + * @error: return location for a #GError, or %NULL + * + * Removes @group from the list of groups to which the bookmark + * for @uri belongs to. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * In the event no group was defined, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_INVALID_VALUE. + * + * Returns: %TRUE if @group was successfully removed. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_remove_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group, + GError **error) +{ + BookmarkItem *item; + GList *l; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return FALSE; + } + + if (!item->metadata) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_VALUE, + _("No groups set in bookmark for URI “%sâ€"), + uri); + return FALSE; + } + + for (l = item->metadata->groups; l != NULL; l = l->next) + { + if (strcmp (l->data, group) == 0) + { + item->metadata->groups = g_list_remove_link (item->metadata->groups, l); + g_free (l->data); + g_list_free_1 (l); + + bookmark_item_touch_modified (item); + + return TRUE; + } + } + + return FALSE; +} + +/** + * g_bookmark_file_set_groups: + * @bookmark: a #GBookmarkFile + * @uri: an item's URI + * @groups: (nullable) (array length=length) (element-type utf8): an array of + * group names, or %NULL to remove all groups + * @length: number of group name values in @groups + * + * Sets a list of group names for the item with URI @uri. Each previously + * set group name list is removed. + * + * If @uri cannot be found then an item for it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_groups (GBookmarkFile *bookmark, + const gchar *uri, + const gchar **groups, + gsize length) +{ + BookmarkItem *item; + gsize i; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (groups != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + g_list_free_full (item->metadata->groups, g_free); + item->metadata->groups = NULL; + + if (groups) + { + for (i = 0; i < length && groups[i] != NULL; i++) + item->metadata->groups = g_list_append (item->metadata->groups, + g_strdup (groups[i])); + } + + bookmark_item_touch_modified (item); +} + +/** + * g_bookmark_file_get_groups: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @length: (out) (optional): return location for the length of the returned string, or %NULL + * @error: return location for a #GError, or %NULL + * + * Retrieves the list of group names of the bookmark for @uri. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * The returned array is %NULL terminated, so @length may optionally + * be %NULL. + * + * Returns: (array length=length) (transfer full): a newly allocated %NULL-terminated array of group names. + * Use g_strfreev() to free it. + * + * Since: 2.12 + */ +gchar ** +g_bookmark_file_get_groups (GBookmarkFile *bookmark, + const gchar *uri, + gsize *length, + GError **error) +{ + BookmarkItem *item; + GList *l; + gsize len, i; + gchar **retval; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return NULL; + } + + if (!item->metadata) + { + if (length) + *length = 0; + + return NULL; + } + + len = g_list_length (item->metadata->groups); + retval = g_new0 (gchar *, len + 1); + for (l = g_list_last (item->metadata->groups), i = 0; + l != NULL; + l = l->prev) + { + gchar *group_name = (gchar *) l->data; + + g_warn_if_fail (group_name != NULL); + + retval[i++] = g_strdup (group_name); + } + retval[i] = NULL; + + if (length) + *length = len; + + return retval; +} + +/** + * g_bookmark_file_add_application: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: (nullable): the name of the application registering the bookmark + * or %NULL + * @exec: (nullable): command line to be used to launch the bookmark or %NULL + * + * Adds the application with @name and @exec to the list of + * applications that have registered a bookmark for @uri into + * @bookmark. + * + * Every bookmark inside a #GBookmarkFile must have at least an + * application registered. Each application must provide a name, a + * command line useful for launching the bookmark, the number of times + * the bookmark has been registered by the application and the last + * time the application registered this bookmark. + * + * If @name is %NULL, the name of the application will be the + * same returned by g_get_application_name(); if @exec is %NULL, the + * command line will be a composition of the program name as + * returned by g_get_prgname() and the "\%u" modifier, which will be + * expanded to the bookmark's URI. + * + * This function will automatically take care of updating the + * registrations count and timestamping in case an application + * with the same @name had already registered a bookmark for + * @uri inside @bookmark. + * + * If no bookmark for @uri is found, one is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_add_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + const gchar *exec) +{ + BookmarkItem *item; + gchar *app_name, *app_exec; + GDateTime *stamp; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (name && name[0] != '\0') + app_name = g_strdup (name); + else + app_name = g_strdup (g_get_application_name ()); + + if (exec && exec[0] != '\0') + app_exec = g_strdup (exec); + else + app_exec = g_strjoin (" ", g_get_prgname(), "%u", NULL); + + stamp = g_date_time_new_now_utc (); + + g_bookmark_file_set_application_info (bookmark, uri, + app_name, + app_exec, + -1, + stamp, + NULL); + + g_date_time_unref (stamp); + g_free (app_exec); + g_free (app_name); +} + +/** + * g_bookmark_file_remove_application: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: the name of the application + * @error: return location for a #GError or %NULL + * + * Removes application registered with @name from the list of applications + * that have registered a bookmark for @uri inside @bookmark. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * In the event that no application with name @app_name has registered + * a bookmark for @uri, %FALSE is returned and error is set to + * %G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. + * + * Returns: %TRUE if the application was successfully removed. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_remove_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + GError **error) +{ + GError *set_error; + gboolean retval; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + set_error = NULL; + retval = g_bookmark_file_set_application_info (bookmark, uri, + name, + "", + 0, + NULL, + &set_error); + if (set_error) + { + g_propagate_error (error, set_error); + + return FALSE; + } + + return retval; +} + +/** + * g_bookmark_file_has_application: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: the name of the application + * @error: return location for a #GError or %NULL + * + * Checks whether the bookmark for @uri inside @bookmark has been + * registered by application @name. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: %TRUE if the application @name was found + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_has_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return FALSE; + } + + return (NULL != bookmark_item_lookup_app_info (item, name)); +} + +/** + * g_bookmark_file_set_app_info: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: an application's name + * @exec: an application's command line + * @count: the number of registrations done for this application + * @stamp: the time of the last registration for this application + * @error: return location for a #GError or %NULL + * + * Sets the meta-data of application @name inside the list of + * applications that have registered a bookmark for @uri inside + * @bookmark. + * + * You should rarely use this function; use g_bookmark_file_add_application() + * and g_bookmark_file_remove_application() instead. + * + * @name can be any UTF-8 encoded string used to identify an + * application. + * @exec can have one of these two modifiers: "\%f", which will + * be expanded as the local file name retrieved from the bookmark's + * URI; "\%u", which will be expanded as the bookmark's URI. + * The expansion is done automatically when retrieving the stored + * command line using the g_bookmark_file_get_application_info() function. + * @count is the number of times the application has registered the + * bookmark; if is < 0, the current registration count will be increased + * by one, if is 0, the application with @name will be removed from + * the list of registered applications. + * @stamp is the Unix time of the last registration; if it is -1, the + * current time will be used. + * + * If you try to remove an application by setting its registration count to + * zero, and no bookmark for @uri is found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND; similarly, + * in the event that no application @name has registered a bookmark + * for @uri, %FALSE is returned and error is set to + * %G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. Otherwise, if no bookmark + * for @uri is found, one is created. + * + * Returns: %TRUE if the application's meta-data was successfully + * changed. + * + * Since: 2.12 + * Deprecated: 2.66: Use g_bookmark_file_set_application_info() instead, as + * `time_t` is deprecated due to the year 2038 problem. + */ +gboolean +g_bookmark_file_set_app_info (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + const gchar *exec, + gint count, + time_t stamp, + GError **error) +{ + GDateTime *stamp_dt = (stamp != (time_t) -1) ? g_date_time_new_from_unix_utc (stamp) : g_date_time_new_now_utc (); + gboolean retval; + retval = g_bookmark_file_set_application_info (bookmark, uri, name, exec, count, + stamp_dt, error); + g_date_time_unref (stamp_dt); + return retval; +} + +/** + * g_bookmark_file_set_application_info: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: an application's name + * @exec: an application's command line + * @count: the number of registrations done for this application + * @stamp: (nullable): the time of the last registration for this application, + * which may be %NULL if @count is 0 + * @error: return location for a #GError or %NULL + * + * Sets the meta-data of application @name inside the list of + * applications that have registered a bookmark for @uri inside + * @bookmark. + * + * You should rarely use this function; use g_bookmark_file_add_application() + * and g_bookmark_file_remove_application() instead. + * + * @name can be any UTF-8 encoded string used to identify an + * application. + * @exec can have one of these two modifiers: "\%f", which will + * be expanded as the local file name retrieved from the bookmark's + * URI; "\%u", which will be expanded as the bookmark's URI. + * The expansion is done automatically when retrieving the stored + * command line using the g_bookmark_file_get_application_info() function. + * @count is the number of times the application has registered the + * bookmark; if is < 0, the current registration count will be increased + * by one, if is 0, the application with @name will be removed from + * the list of registered applications. + * @stamp is the Unix time of the last registration. + * + * If you try to remove an application by setting its registration count to + * zero, and no bookmark for @uri is found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND; similarly, + * in the event that no application @name has registered a bookmark + * for @uri, %FALSE is returned and error is set to + * %G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. Otherwise, if no bookmark + * for @uri is found, one is created. + * + * Returns: %TRUE if the application's meta-data was successfully + * changed. + * + * Since: 2.66 + */ +gboolean +g_bookmark_file_set_application_info (GBookmarkFile *bookmark, + const char *uri, + const char *name, + const char *exec, + int count, + GDateTime *stamp, + GError **error) +{ + BookmarkItem *item; + BookmarkAppInfo *ai; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (exec != NULL, FALSE); + g_return_val_if_fail (count == 0 || stamp != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + if (count == 0) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return FALSE; + } + else + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + ai = bookmark_item_lookup_app_info (item, name); + if (!ai) + { + if (count == 0) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED, + _("No application with name “%s†registered a bookmark for “%sâ€"), + name, + uri); + return FALSE; + } + else + { + ai = bookmark_app_info_new (name); + + item->metadata->applications = g_list_prepend (item->metadata->applications, ai); + g_hash_table_replace (item->metadata->apps_by_name, ai->name, ai); + } + } + + if (count == 0) + { + item->metadata->applications = g_list_remove (item->metadata->applications, ai); + g_hash_table_remove (item->metadata->apps_by_name, ai->name); + bookmark_app_info_free (ai); + + bookmark_item_touch_modified (item); + + return TRUE; + } + else if (count > 0) + ai->count = count; + else + ai->count += 1; + + g_clear_pointer (&ai->stamp, g_date_time_unref); + ai->stamp = g_date_time_ref (stamp); + + if (exec && exec[0] != '\0') + { + g_free (ai->exec); + ai->exec = g_shell_quote (exec); + } + + bookmark_item_touch_modified (item); + + return TRUE; +} + +/* expands the application's command line */ +static gchar * +expand_exec_line (const gchar *exec_fmt, + const gchar *uri) +{ + GString *exec; + gchar ch; + + exec = g_string_sized_new (512); + while ((ch = *exec_fmt++) != '\0') + { + if (ch != '%') + { + exec = g_string_append_c (exec, ch); + continue; + } + + ch = *exec_fmt++; + switch (ch) + { + case '\0': + goto out; + case 'U': + case 'u': + g_string_append (exec, uri); + break; + case 'F': + case 'f': + { + gchar *file = g_filename_from_uri (uri, NULL, NULL); + if (file) + { + g_string_append (exec, file); + g_free (file); + } + else + { + g_string_free (exec, TRUE); + return NULL; + } + } + break; + case '%': + default: + exec = g_string_append_c (exec, ch); + break; + } + } + + out: + return g_string_free (exec, FALSE); +} + +/** + * g_bookmark_file_get_app_info: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: an application's name + * @exec: (out) (optional): return location for the command line of the application, or %NULL + * @count: (out) (optional): return location for the registration count, or %NULL + * @stamp: (out) (optional): return location for the last registration time, or %NULL + * @error: return location for a #GError, or %NULL + * + * Gets the registration information of @app_name for the bookmark for + * @uri. See g_bookmark_file_set_application_info() for more information about + * the returned data. + * + * The string returned in @app_exec must be freed. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the + * event that no application with name @app_name has registered a bookmark + * for @uri, %FALSE is returned and error is set to + * %G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. In the event that unquoting + * the command line fails, an error of the %G_SHELL_ERROR domain is + * set and %FALSE is returned. + * + * Returns: %TRUE on success. + * + * Since: 2.12 + * Deprecated: 2.66: Use g_bookmark_file_get_application_info() instead, as + * `time_t` is deprecated due to the year 2038 problem. + */ +gboolean +g_bookmark_file_get_app_info (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + gchar **exec, + guint *count, + time_t *stamp, + GError **error) +{ + GDateTime *stamp_dt = NULL; + gboolean retval; + + retval = g_bookmark_file_get_application_info (bookmark, uri, name, exec, count, &stamp_dt, error); + if (!retval) + return FALSE; + + if (stamp != NULL) + *stamp = g_date_time_to_unix (stamp_dt); + + return TRUE; +} + +/** + * g_bookmark_file_get_application_info: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: an application's name + * @exec: (out) (optional): return location for the command line of the application, or %NULL + * @count: (out) (optional): return location for the registration count, or %NULL + * @stamp: (out) (optional) (transfer none): return location for the last registration time, or %NULL + * @error: return location for a #GError, or %NULL + * + * Gets the registration information of @app_name for the bookmark for + * @uri. See g_bookmark_file_set_application_info() for more information about + * the returned data. + * + * The string returned in @app_exec must be freed. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the + * event that no application with name @app_name has registered a bookmark + * for @uri, %FALSE is returned and error is set to + * %G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. In the event that unquoting + * the command line fails, an error of the %G_SHELL_ERROR domain is + * set and %FALSE is returned. + * + * Returns: %TRUE on success. + * + * Since: 2.66 + */ +gboolean +g_bookmark_file_get_application_info (GBookmarkFile *bookmark, + const char *uri, + const char *name, + char **exec, + unsigned int *count, + GDateTime **stamp, + GError **error) +{ + BookmarkItem *item; + BookmarkAppInfo *ai; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return FALSE; + } + + ai = bookmark_item_lookup_app_info (item, name); + if (!ai) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED, + _("No application with name “%s†registered a bookmark for “%sâ€"), + name, + uri); + return FALSE; + } + + if (exec) + { + GError *unquote_error = NULL; + gchar *command_line; + + command_line = g_shell_unquote (ai->exec, &unquote_error); + if (unquote_error) + { + g_propagate_error (error, unquote_error); + return FALSE; + } + + *exec = expand_exec_line (command_line, uri); + if (!*exec) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_URI, + _("Failed to expand exec line “%s†with URI “%sâ€"), + ai->exec, uri); + g_free (command_line); + + return FALSE; + } + else + g_free (command_line); + } + + if (count) + *count = ai->count; + + if (stamp) + *stamp = ai->stamp; + + return TRUE; +} + +/** + * g_bookmark_file_get_applications: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @length: (out) (optional): return location of the length of the returned list, or %NULL + * @error: return location for a #GError, or %NULL + * + * Retrieves the names of the applications that have registered the + * bookmark for @uri. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: (array length=length) (transfer full): a newly allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * + * Since: 2.12 + */ +gchar ** +g_bookmark_file_get_applications (GBookmarkFile *bookmark, + const gchar *uri, + gsize *length, + GError **error) +{ + BookmarkItem *item; + GList *l; + gchar **apps; + gsize i, n_apps; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return NULL; + } + + if (!item->metadata) + { + if (length) + *length = 0; + + return NULL; + } + + n_apps = g_list_length (item->metadata->applications); + apps = g_new0 (gchar *, n_apps + 1); + + for (l = g_list_last (item->metadata->applications), i = 0; + l != NULL; + l = l->prev) + { + BookmarkAppInfo *ai; + + ai = (BookmarkAppInfo *) l->data; + + g_warn_if_fail (ai != NULL); + g_warn_if_fail (ai->name != NULL); + + apps[i++] = g_strdup (ai->name); + } + apps[i] = NULL; + + if (length) + *length = i; + + return apps; +} + +/** + * g_bookmark_file_get_size: + * @bookmark: a #GBookmarkFile + * + * Gets the number of bookmarks inside @bookmark. + * + * Returns: the number of bookmarks + * + * Since: 2.12 + */ +gint +g_bookmark_file_get_size (GBookmarkFile *bookmark) +{ + g_return_val_if_fail (bookmark != NULL, 0); + + return g_list_length (bookmark->items); +} + +/** + * g_bookmark_file_move_item: + * @bookmark: a #GBookmarkFile + * @old_uri: a valid URI + * @new_uri: (nullable): a valid URI, or %NULL + * @error: return location for a #GError or %NULL + * + * Changes the URI of a bookmark item from @old_uri to @new_uri. Any + * existing bookmark for @new_uri will be overwritten. If @new_uri is + * %NULL, then the bookmark is removed. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: %TRUE if the URI was successfully changed + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_move_item (GBookmarkFile *bookmark, + const gchar *old_uri, + const gchar *new_uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (old_uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, old_uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + old_uri); + return FALSE; + } + + if (new_uri && new_uri[0] != '\0') + { + if (g_strcmp0 (old_uri, new_uri) == 0) + return TRUE; + + if (g_bookmark_file_has_item (bookmark, new_uri)) + { + if (!g_bookmark_file_remove_item (bookmark, new_uri, error)) + return FALSE; + } + + g_hash_table_steal (bookmark->items_by_uri, item->uri); + + g_free (item->uri); + item->uri = g_strdup (new_uri); + bookmark_item_touch_modified (item); + + g_hash_table_replace (bookmark->items_by_uri, item->uri, item); + + return TRUE; + } + else + { + if (!g_bookmark_file_remove_item (bookmark, old_uri, error)) + return FALSE; + + return TRUE; + } +} + +/** + * g_bookmark_file_set_icon: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @href: (nullable): the URI of the icon for the bookmark, or %NULL + * @mime_type: the MIME type of the icon for the bookmark + * + * Sets the icon for the bookmark for @uri. If @href is %NULL, unsets + * the currently set icon. @href can either be a full URL for the icon + * file or the icon name following the Icon Naming specification. + * + * If no bookmark for @uri is found one is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_icon (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *href, + const gchar *mime_type) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + g_free (item->metadata->icon_href); + g_free (item->metadata->icon_mime); + + item->metadata->icon_href = g_strdup (href); + + if (mime_type && mime_type[0] != '\0') + item->metadata->icon_mime = g_strdup (mime_type); + else + item->metadata->icon_mime = g_strdup ("application/octet-stream"); + + bookmark_item_touch_modified (item); +} + +/** + * g_bookmark_file_get_icon: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @href: (out) (optional): return location for the icon's location or %NULL + * @mime_type: (out) (optional): return location for the icon's MIME type or %NULL + * @error: return location for a #GError or %NULL + * + * Gets the icon of the bookmark for @uri. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to %G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Returns: %TRUE if the icon for the bookmark for the URI was found. + * You should free the returned strings. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_get_icon (GBookmarkFile *bookmark, + const gchar *uri, + gchar **href, + gchar **mime_type, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI “%sâ€"), + uri); + return FALSE; + } + + if ((!item->metadata) || (!item->metadata->icon_href)) + return FALSE; + + if (href) + *href = g_strdup (item->metadata->icon_href); + + if (mime_type) + *mime_type = g_strdup (item->metadata->icon_mime); + + return TRUE; +} diff --git a/glib/gbookmarkfile.h b/glib/gbookmarkfile.h new file mode 100644 index 0000000..82ea98d --- /dev/null +++ b/glib/gbookmarkfile.h @@ -0,0 +1,295 @@ +/* gbookmarkfile.h: parsing and building desktop bookmarks + * + * Copyright (C) 2005-2006 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef __G_BOOKMARK_FILE_H__ +#define __G_BOOKMARK_FILE_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +/** + * G_BOOKMARK_FILE_ERROR: + * + * Error domain for bookmark file parsing. + * + * Errors in this domain will be from the #GBookmarkFileError + * enumeration. See #GError for information on error domains. + */ +#define G_BOOKMARK_FILE_ERROR (g_bookmark_file_error_quark ()) + + +/** + * GBookmarkFileError: + * @G_BOOKMARK_FILE_ERROR_INVALID_URI: URI was ill-formed + * @G_BOOKMARK_FILE_ERROR_INVALID_VALUE: a requested field was not found + * @G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED: a requested application did + * not register a bookmark + * @G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND: a requested URI was not found + * @G_BOOKMARK_FILE_ERROR_READ: document was ill formed + * @G_BOOKMARK_FILE_ERROR_UNKNOWN_ENCODING: the text being parsed was + * in an unknown encoding + * @G_BOOKMARK_FILE_ERROR_WRITE: an error occurred while writing + * @G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND: requested file was not found + * + * Error codes returned by bookmark file parsing. + */ +typedef enum +{ + G_BOOKMARK_FILE_ERROR_INVALID_URI, + G_BOOKMARK_FILE_ERROR_INVALID_VALUE, + G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + G_BOOKMARK_FILE_ERROR_READ, + G_BOOKMARK_FILE_ERROR_UNKNOWN_ENCODING, + G_BOOKMARK_FILE_ERROR_WRITE, + G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND +} GBookmarkFileError; + +GLIB_AVAILABLE_IN_ALL +GQuark g_bookmark_file_error_quark (void); + +/** + * GBookmarkFile: + * + * An opaque data structure representing a set of bookmarks. + */ +typedef struct _GBookmarkFile GBookmarkFile; + +GLIB_AVAILABLE_IN_ALL +GBookmarkFile *g_bookmark_file_new (void); +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_free (GBookmarkFile *bookmark); + +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_load_from_file (GBookmarkFile *bookmark, + const gchar *filename, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_load_from_data (GBookmarkFile *bookmark, + const gchar *data, + gsize length, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_load_from_data_dirs (GBookmarkFile *bookmark, + const gchar *file, + gchar **full_path, + GError **error); +GLIB_AVAILABLE_IN_ALL +gchar * g_bookmark_file_to_data (GBookmarkFile *bookmark, + gsize *length, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_to_file (GBookmarkFile *bookmark, + const gchar *filename, + GError **error); + +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_set_title (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *title); +GLIB_AVAILABLE_IN_ALL +gchar * g_bookmark_file_get_title (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_set_description (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *description); +GLIB_AVAILABLE_IN_ALL +gchar * g_bookmark_file_get_description (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_set_mime_type (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *mime_type); +GLIB_AVAILABLE_IN_ALL +gchar * g_bookmark_file_get_mime_type (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_set_groups (GBookmarkFile *bookmark, + const gchar *uri, + const gchar **groups, + gsize length); +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_add_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_has_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group, + GError **error); +GLIB_AVAILABLE_IN_ALL +gchar ** g_bookmark_file_get_groups (GBookmarkFile *bookmark, + const gchar *uri, + gsize *length, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_add_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + const gchar *exec); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_has_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + GError **error); +GLIB_AVAILABLE_IN_ALL +gchar ** g_bookmark_file_get_applications (GBookmarkFile *bookmark, + const gchar *uri, + gsize *length, + GError **error); +GLIB_DEPRECATED_IN_2_66_FOR(g_bookmark_file_set_application_info) +gboolean g_bookmark_file_set_app_info (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + const gchar *exec, + gint count, + time_t stamp, + GError **error); +GLIB_AVAILABLE_IN_2_66 +gboolean g_bookmark_file_set_application_info (GBookmarkFile *bookmark, + const char *uri, + const char *name, + const char *exec, + int count, + GDateTime *stamp, + GError **error); +GLIB_DEPRECATED_IN_2_66_FOR(g_bookmark_file_get_application_info) +gboolean g_bookmark_file_get_app_info (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + gchar **exec, + guint *count, + time_t *stamp, + GError **error); +GLIB_AVAILABLE_IN_2_66 +gboolean g_bookmark_file_get_application_info (GBookmarkFile *bookmark, + const char *uri, + const char *name, + char **exec, + unsigned int *count, + GDateTime **stamp, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_set_is_private (GBookmarkFile *bookmark, + const gchar *uri, + gboolean is_private); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_get_is_private (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_bookmark_file_set_icon (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *href, + const gchar *mime_type); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_get_icon (GBookmarkFile *bookmark, + const gchar *uri, + gchar **href, + gchar **mime_type, + GError **error); +GLIB_DEPRECATED_IN_2_66_FOR(g_bookmark_file_set_added_date_time) +void g_bookmark_file_set_added (GBookmarkFile *bookmark, + const gchar *uri, + time_t added); +GLIB_AVAILABLE_IN_2_66 +void g_bookmark_file_set_added_date_time (GBookmarkFile *bookmark, + const char *uri, + GDateTime *added); +GLIB_DEPRECATED_IN_2_66_FOR(g_bookmark_file_get_added_date_time) +time_t g_bookmark_file_get_added (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +GLIB_AVAILABLE_IN_2_66 +GDateTime *g_bookmark_file_get_added_date_time (GBookmarkFile *bookmark, + const char *uri, + GError **error); +GLIB_DEPRECATED_IN_2_66_FOR(g_bookmark_file_set_modified_date_time) +void g_bookmark_file_set_modified (GBookmarkFile *bookmark, + const gchar *uri, + time_t modified); +GLIB_AVAILABLE_IN_2_66 +void g_bookmark_file_set_modified_date_time (GBookmarkFile *bookmark, + const char *uri, + GDateTime *modified); +GLIB_DEPRECATED_IN_2_66_FOR(g_bookmark_file_get_modified_date_time) +time_t g_bookmark_file_get_modified (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +GLIB_AVAILABLE_IN_2_66 +GDateTime *g_bookmark_file_get_modified_date_time (GBookmarkFile *bookmark, + const char *uri, + GError **error); +GLIB_DEPRECATED_IN_2_66_FOR(g_bookmark_file_set_visited_date_time) +void g_bookmark_file_set_visited (GBookmarkFile *bookmark, + const gchar *uri, + time_t visited); +GLIB_AVAILABLE_IN_2_66 +void g_bookmark_file_set_visited_date_time (GBookmarkFile *bookmark, + const char *uri, + GDateTime *visited); +GLIB_DEPRECATED_IN_2_66_FOR(g_bookmark_file_get_visited_date_time) +time_t g_bookmark_file_get_visited (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +GLIB_AVAILABLE_IN_2_66 +GDateTime *g_bookmark_file_get_visited_date_time (GBookmarkFile *bookmark, + const char *uri, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_has_item (GBookmarkFile *bookmark, + const gchar *uri); +GLIB_AVAILABLE_IN_ALL +gint g_bookmark_file_get_size (GBookmarkFile *bookmark); +GLIB_AVAILABLE_IN_ALL +gchar ** g_bookmark_file_get_uris (GBookmarkFile *bookmark, + gsize *length); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_remove_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_remove_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_remove_item (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_bookmark_file_move_item (GBookmarkFile *bookmark, + const gchar *old_uri, + const gchar *new_uri, + GError **error); + +G_END_DECLS + +#endif /* __G_BOOKMARK_FILE_H__ */ diff --git a/glib/gbsearcharray.h b/glib/gbsearcharray.h new file mode 100644 index 0000000..39afa3f --- /dev/null +++ b/glib/gbsearcharray.h @@ -0,0 +1,299 @@ +/* GBSearchArray - Binary Searchable Array implementation + * Copyright (C) 2000-2003 Tim Janik + * + * This software is provided "as is"; redistribution and modification + * is permitted, provided that the following disclaimer is retained. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#ifndef __G_BSEARCH_ARRAY_H__ +#define __G_BSEARCH_ARRAY_H__ + +#include +#include + + +G_BEGIN_DECLS /* c++ guards */ + +/* this implementation is intended to be usable in third-party code + * simply by pasting the contents of this file. as such, the + * implementation needs to be self-contained within this file. + */ + +/* convenience macro to avoid signed overflow for value comparisons */ +#define G_BSEARCH_ARRAY_CMP(v1,v2) ((v1) > (v2) ? +1 : (v1) == (v2) ? 0 : -1) + + +/* --- typedefs --- */ +typedef gint (*GBSearchCompareFunc) (gconstpointer bsearch_node1, /* key */ + gconstpointer bsearch_node2); +typedef enum +{ + G_BSEARCH_ARRAY_ALIGN_POWER2 = 1 << 0, /* align memory to power2 sizes */ + G_BSEARCH_ARRAY_AUTO_SHRINK = 1 << 1 /* shrink array upon removal */ +} GBSearchArrayFlags; + + +/* --- structures --- */ +typedef struct +{ + guint sizeof_node; + GBSearchCompareFunc cmp_nodes; + guint flags; +} GBSearchConfig; +typedef union +{ + guint n_nodes; + /*< private >*/ + gpointer alignment_dummy1; + glong alignment_dummy2; + gdouble alignment_dummy3; +} GBSearchArray; + + +/* --- public API --- */ +static inline GBSearchArray* g_bsearch_array_create (const GBSearchConfig *bconfig); +static inline gpointer g_bsearch_array_get_nth (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint nth); +static inline guint g_bsearch_array_get_index (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer node_in_array); +static inline GBSearchArray* g_bsearch_array_remove (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint index_); +/* provide uninitialized space at index for node insertion */ +static inline GBSearchArray* g_bsearch_array_grow (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint index); +/* insert key_node into array if it does not exist, otherwise do nothing */ +static inline GBSearchArray* g_bsearch_array_insert (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node); +/* insert key_node into array if it does not exist, + * otherwise replace the existing node's contents with key_node + */ +static inline GBSearchArray* g_bsearch_array_replace (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node); +static inline void g_bsearch_array_free (GBSearchArray *barray, + const GBSearchConfig *bconfig); +#define g_bsearch_array_get_n_nodes(barray) (((GBSearchArray*) (barray))->n_nodes) + +/* g_bsearch_array_lookup(): + * return NULL or exact match node + */ +#define g_bsearch_array_lookup(barray, bconfig, key_node) \ + g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 0) + +/* g_bsearch_array_lookup_sibling(): + * return NULL for barray->n_nodes==0, otherwise return the + * exact match node, or, if there's no such node, return the + * node last visited, which is pretty close to an exact match + * (will be one off into either direction). + */ +#define g_bsearch_array_lookup_sibling(barray, bconfig, key_node) \ + g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 1) + +/* g_bsearch_array_lookup_insertion(): + * return NULL for barray->n_nodes==0 or exact match, otherwise + * return the node where key_node should be inserted (may be one + * after end, i.e. g_bsearch_array_get_index(result) <= barray->n_nodes). + */ +#define g_bsearch_array_lookup_insertion(barray, bconfig, key_node) \ + g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 2) + + +/* --- implementation --- */ +/* helper macro to cut down realloc()s */ +#define G_BSEARCH_UPPER_POWER2(n) ((n) ? 1 << g_bit_storage ((n) - 1) : 0) +#define G_BSEARCH_ARRAY_NODES(barray) (((guint8*) (barray)) + sizeof (GBSearchArray)) +static inline GBSearchArray* +g_bsearch_array_create (const GBSearchConfig *bconfig) +{ + GBSearchArray *barray; + guint size; + + g_return_val_if_fail (bconfig != NULL, NULL); + + size = sizeof (GBSearchArray) + bconfig->sizeof_node; + if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2) + size = G_BSEARCH_UPPER_POWER2 (size); + barray = (GBSearchArray *) g_malloc (size); + memset (barray, 0, sizeof (GBSearchArray)); + + return barray; +} +static inline gpointer +g_bsearch_array_lookup_fuzzy (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node, + const guint sibling_or_after); +static inline gpointer +g_bsearch_array_lookup_fuzzy (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node, + const guint sibling_or_after) +{ + GBSearchCompareFunc cmp_nodes = bconfig->cmp_nodes; + guint8 *check = NULL, *nodes = G_BSEARCH_ARRAY_NODES (barray); + guint n_nodes = barray->n_nodes, offs = 0; + guint sizeof_node = bconfig->sizeof_node; + gint cmp = 0; + + while (offs < n_nodes) + { + guint i = (offs + n_nodes) >> 1; + + check = nodes + i * sizeof_node; + cmp = cmp_nodes (key_node, check); + if (cmp == 0) + return sibling_or_after > 1 ? NULL : check; + else if (cmp < 0) + n_nodes = i; + else /* (cmp > 0) */ + offs = i + 1; + } + + /* check is last mismatch, cmp > 0 indicates greater key */ + return G_LIKELY (!sibling_or_after) ? NULL : (sibling_or_after > 1 && cmp > 0) ? check + sizeof_node : check; +} +static inline gpointer +g_bsearch_array_get_nth (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint nth) +{ + return (G_LIKELY (nth < barray->n_nodes) ? + G_BSEARCH_ARRAY_NODES (barray) + nth * bconfig->sizeof_node : + NULL); +} +static inline guint +g_bsearch_array_get_index (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer node_in_array) +{ + guint distance = ((guint8*) node_in_array) - G_BSEARCH_ARRAY_NODES (barray); + + g_return_val_if_fail (node_in_array != NULL, barray->n_nodes); + + distance /= bconfig->sizeof_node; + + return MIN (distance, barray->n_nodes + 1); /* may return one after end */ +} +static inline GBSearchArray* +g_bsearch_array_grow (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint index_) +{ + guint old_size = barray->n_nodes * bconfig->sizeof_node; + guint new_size = old_size + bconfig->sizeof_node; + guint8 *node; + + g_return_val_if_fail (index_ <= barray->n_nodes, NULL); + + if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)) + { + new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size); + old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size); + if (old_size != new_size) + barray = (GBSearchArray *) g_realloc (barray, new_size); + } + else + barray = (GBSearchArray *) g_realloc (barray, sizeof (GBSearchArray) + new_size); + node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node; + memmove (node + bconfig->sizeof_node, node, (barray->n_nodes - index_) * bconfig->sizeof_node); + barray->n_nodes += 1; + return barray; +} +static inline GBSearchArray* +g_bsearch_array_insert (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node) +{ + guint8 *node; + + if (G_UNLIKELY (!barray->n_nodes)) + { + barray = g_bsearch_array_grow (barray, bconfig, 0); + node = G_BSEARCH_ARRAY_NODES (barray); + } + else + { + node = (guint8 *) g_bsearch_array_lookup_insertion (barray, bconfig, key_node); + if (G_LIKELY (node)) + { + guint index_ = g_bsearch_array_get_index (barray, bconfig, node); + + /* grow and insert */ + barray = g_bsearch_array_grow (barray, bconfig, index_); + node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node; + } + else /* no insertion needed, node already there */ + return barray; + } + memcpy (node, key_node, bconfig->sizeof_node); + return barray; +} +static inline GBSearchArray* +g_bsearch_array_replace (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node) +{ + guint8 *node = (guint8 *) g_bsearch_array_lookup (barray, bconfig, key_node); + if (G_LIKELY (node)) /* expected path */ + memcpy (node, key_node, bconfig->sizeof_node); + else /* revert to insertion */ + barray = g_bsearch_array_insert (barray, bconfig, key_node); + return barray; +} +static inline GBSearchArray* +g_bsearch_array_remove (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint index_) +{ + guint8 *node; + + g_return_val_if_fail (index_ < barray->n_nodes, NULL); + + barray->n_nodes -= 1; + node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node; + memmove (node, node + bconfig->sizeof_node, (barray->n_nodes - index_) * bconfig->sizeof_node); + if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_AUTO_SHRINK)) + { + guint new_size = barray->n_nodes * bconfig->sizeof_node; + guint old_size = new_size + bconfig->sizeof_node; + + if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)) + { + new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size); + old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size); + if (old_size != new_size) + barray = (GBSearchArray *) g_realloc (barray, new_size); + } + else + barray = (GBSearchArray *) g_realloc (barray, sizeof (GBSearchArray) + new_size); + } + return barray; +} +static inline void +g_bsearch_array_free (GBSearchArray *barray, + const GBSearchConfig *bconfig) +{ + g_return_if_fail (barray != NULL); + + g_free (barray); +} + +G_END_DECLS /* c++ guards */ + +#endif /* !__G_BSEARCH_ARRAY_H__ */ diff --git a/glib/gbytes.c b/glib/gbytes.c new file mode 100644 index 0000000..a6ca0e3 --- /dev/null +++ b/glib/gbytes.c @@ -0,0 +1,612 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * Copyright © 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + * Stef Walter + */ + +#include "config.h" + +#include "gbytes.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * GBytes: + * + * A simple refcounted data type representing an immutable sequence of zero or + * more bytes from an unspecified origin. + * + * The purpose of a #GBytes is to keep the memory region that it holds + * alive for as long as anyone holds a reference to the bytes. When + * the last reference count is dropped, the memory is released. Multiple + * unrelated callers can use byte data in the #GBytes without coordinating + * their activities, resting assured that the byte data will not change or + * move while they hold a reference. + * + * A #GBytes can come from many different origins that may have + * different procedures for freeing the memory region. Examples are + * memory from g_malloc(), from memory slices, from a #GMappedFile or + * memory from other allocators. + * + * #GBytes work well as keys in #GHashTable. Use g_bytes_equal() and + * g_bytes_hash() as parameters to g_hash_table_new() or g_hash_table_new_full(). + * #GBytes can also be used as keys in a #GTree by passing the g_bytes_compare() + * function to g_tree_new(). + * + * The data pointed to by this bytes must not be modified. For a mutable + * array of bytes see #GByteArray. Use g_bytes_unref_to_array() to create a + * mutable array for a #GBytes sequence. To create an immutable #GBytes from + * a mutable #GByteArray, use the g_byte_array_free_to_bytes() function. + * + * Since: 2.32 + **/ + +/* Keep in sync with glib/tests/bytes.c */ +struct _GBytes +{ + gconstpointer data; /* may be NULL iff (size == 0) */ + gsize size; /* may be 0 */ + gatomicrefcount ref_count; + GDestroyNotify free_func; + gpointer user_data; +}; + +/** + * g_bytes_new: + * @data: (transfer none) (array length=size) (element-type guint8) (nullable): + * the data to be used for the bytes + * @size: the size of @data + * + * Creates a new #GBytes from @data. + * + * @data is copied. If @size is 0, @data may be %NULL. + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new (gconstpointer data, + gsize size) +{ + g_return_val_if_fail (data != NULL || size == 0, NULL); + + return g_bytes_new_take (g_memdup2 (data, size), size); +} + +/** + * g_bytes_new_take: + * @data: (transfer full) (array length=size) (element-type guint8) (nullable): + * the data to be used for the bytes + * @size: the size of @data + * + * Creates a new #GBytes from @data. + * + * After this call, @data belongs to the bytes and may no longer be + * modified by the caller. g_free() will be called on @data when the + * bytes is no longer in use. Because of this @data must have been created by + * a call to g_malloc(), g_malloc0() or g_realloc() or by one of the many + * functions that wrap these calls (such as g_new(), g_strdup(), etc). + * + * For creating #GBytes with memory from other allocators, see + * g_bytes_new_with_free_func(). + * + * @data may be %NULL if @size is 0. + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new_take (gpointer data, + gsize size) +{ + return g_bytes_new_with_free_func (data, size, g_free, data); +} + + +/** + * g_bytes_new_static: (skip) + * @data: (transfer full) (array length=size) (element-type guint8) (nullable): + * the data to be used for the bytes + * @size: the size of @data + * + * Creates a new #GBytes from static data. + * + * @data must be static (ie: never modified or freed). It may be %NULL if @size + * is 0. + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new_static (gconstpointer data, + gsize size) +{ + return g_bytes_new_with_free_func (data, size, NULL, NULL); +} + +/** + * g_bytes_new_with_free_func: (skip) + * @data: (array length=size) (element-type guint8) (nullable): + * the data to be used for the bytes + * @size: the size of @data + * @free_func: the function to call to release the data + * @user_data: data to pass to @free_func + * + * Creates a #GBytes from @data. + * + * When the last reference is dropped, @free_func will be called with the + * @user_data argument. + * + * @data must not be modified after this call is made until @free_func has + * been called to indicate that the bytes is no longer in use. + * + * @data may be %NULL if @size is 0. + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new_with_free_func (gconstpointer data, + gsize size, + GDestroyNotify free_func, + gpointer user_data) +{ + GBytes *bytes; + + g_return_val_if_fail (data != NULL || size == 0, NULL); + + bytes = g_slice_new (GBytes); + bytes->data = data; + bytes->size = size; + bytes->free_func = free_func; + bytes->user_data = user_data; + g_atomic_ref_count_init (&bytes->ref_count); + + return (GBytes *)bytes; +} + +/** + * g_bytes_new_from_bytes: + * @bytes: a #GBytes + * @offset: offset which subsection starts at + * @length: length of subsection + * + * Creates a #GBytes which is a subsection of another #GBytes. The @offset + + * @length may not be longer than the size of @bytes. + * + * A reference to @bytes will be held by the newly created #GBytes until + * the byte data is no longer needed. + * + * Since 2.56, if @offset is 0 and @length matches the size of @bytes, then + * @bytes will be returned with the reference count incremented by 1. If @bytes + * is a slice of another #GBytes, then the resulting #GBytes will reference + * the same #GBytes instead of @bytes. This allows consumers to simplify the + * usage of #GBytes when asynchronously writing to streams. + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new_from_bytes (GBytes *bytes, + gsize offset, + gsize length) +{ + gchar *base; + + /* Note that length may be 0. */ + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (offset <= bytes->size, NULL); + g_return_val_if_fail (offset + length <= bytes->size, NULL); + + /* Avoid an extra GBytes if all bytes were requested */ + if (offset == 0 && length == bytes->size) + return g_bytes_ref (bytes); + + base = (gchar *)bytes->data + offset; + + /* Avoid referencing intermediate GBytes. In practice, this should + * only loop once. + */ + while (bytes->free_func == (gpointer)g_bytes_unref) + bytes = bytes->user_data; + + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (base >= (gchar *)bytes->data, NULL); + g_return_val_if_fail (base <= (gchar *)bytes->data + bytes->size, NULL); + g_return_val_if_fail (base + length <= (gchar *)bytes->data + bytes->size, NULL); + + return g_bytes_new_with_free_func (base, length, + (GDestroyNotify)g_bytes_unref, g_bytes_ref (bytes)); +} + +/** + * g_bytes_get_data: + * @bytes: a #GBytes + * @size: (out) (optional): location to return size of byte data + * + * Get the byte data in the #GBytes. This data should not be modified. + * + * This function will always return the same pointer for a given #GBytes. + * + * %NULL may be returned if @size is 0. This is not guaranteed, as the #GBytes + * may represent an empty string with @data non-%NULL and @size as 0. %NULL will + * not be returned if @size is non-zero. + * + * Returns: (transfer none) (array length=size) (element-type guint8) (nullable): + * a pointer to the byte data, or %NULL + * + * Since: 2.32 + */ +gconstpointer +g_bytes_get_data (GBytes *bytes, + gsize *size) +{ + g_return_val_if_fail (bytes != NULL, NULL); + if (size) + *size = bytes->size; + return bytes->data; +} + +/** + * g_bytes_get_size: + * @bytes: a #GBytes + * + * Get the size of the byte data in the #GBytes. + * + * This function will always return the same value for a given #GBytes. + * + * Returns: the size + * + * Since: 2.32 + */ +gsize +g_bytes_get_size (GBytes *bytes) +{ + g_return_val_if_fail (bytes != NULL, 0); + return bytes->size; +} + + +/** + * g_bytes_ref: + * @bytes: a #GBytes + * + * Increase the reference count on @bytes. + * + * Returns: the #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_ref (GBytes *bytes) +{ + g_return_val_if_fail (bytes != NULL, NULL); + + g_atomic_ref_count_inc (&bytes->ref_count); + + return bytes; +} + +/** + * g_bytes_unref: + * @bytes: (nullable): a #GBytes + * + * Releases a reference on @bytes. This may result in the bytes being + * freed. If @bytes is %NULL, it will return immediately. + * + * Since: 2.32 + */ +void +g_bytes_unref (GBytes *bytes) +{ + if (bytes == NULL) + return; + + if (g_atomic_ref_count_dec (&bytes->ref_count)) + { + if (bytes->free_func != NULL) + bytes->free_func (bytes->user_data); + g_slice_free (GBytes, bytes); + } +} + +/** + * g_bytes_equal: + * @bytes1: (type GLib.Bytes): a pointer to a #GBytes + * @bytes2: (type GLib.Bytes): a pointer to a #GBytes to compare with @bytes1 + * + * Compares the two #GBytes values being pointed to and returns + * %TRUE if they are equal. + * + * This function can be passed to g_hash_table_new() as the @key_equal_func + * parameter, when using non-%NULL #GBytes pointers as keys in a #GHashTable. + * + * Returns: %TRUE if the two keys match. + * + * Since: 2.32 + */ +gboolean +g_bytes_equal (gconstpointer bytes1, + gconstpointer bytes2) +{ + const GBytes *b1 = bytes1; + const GBytes *b2 = bytes2; + + g_return_val_if_fail (bytes1 != NULL, FALSE); + g_return_val_if_fail (bytes2 != NULL, FALSE); + + return b1->size == b2->size && + (b1->size == 0 || memcmp (b1->data, b2->data, b1->size) == 0); +} + +/** + * g_bytes_hash: + * @bytes: (type GLib.Bytes): a pointer to a #GBytes key + * + * Creates an integer hash code for the byte data in the #GBytes. + * + * This function can be passed to g_hash_table_new() as the @key_hash_func + * parameter, when using non-%NULL #GBytes pointers as keys in a #GHashTable. + * + * Returns: a hash value corresponding to the key. + * + * Since: 2.32 + */ +guint +g_bytes_hash (gconstpointer bytes) +{ + const GBytes *a = bytes; + const signed char *p, *e; + guint32 h = 5381; + + g_return_val_if_fail (bytes != NULL, 0); + + for (p = (signed char *)a->data, e = (signed char *)a->data + a->size; p != e; p++) + h = (h << 5) + h + *p; + + return h; +} + +/** + * g_bytes_compare: + * @bytes1: (type GLib.Bytes): a pointer to a #GBytes + * @bytes2: (type GLib.Bytes): a pointer to a #GBytes to compare with @bytes1 + * + * Compares the two #GBytes values. + * + * This function can be used to sort GBytes instances in lexicographical order. + * + * If @bytes1 and @bytes2 have different length but the shorter one is a + * prefix of the longer one then the shorter one is considered to be less than + * the longer one. Otherwise the first byte where both differ is used for + * comparison. If @bytes1 has a smaller value at that position it is + * considered less, otherwise greater than @bytes2. + * + * Returns: a negative value if @bytes1 is less than @bytes2, a positive value + * if @bytes1 is greater than @bytes2, and zero if @bytes1 is equal to + * @bytes2 + * + * + * Since: 2.32 + */ +gint +g_bytes_compare (gconstpointer bytes1, + gconstpointer bytes2) +{ + const GBytes *b1 = bytes1; + const GBytes *b2 = bytes2; + gint ret; + + g_return_val_if_fail (bytes1 != NULL, 0); + g_return_val_if_fail (bytes2 != NULL, 0); + + ret = memcmp (b1->data, b2->data, MIN (b1->size, b2->size)); + if (ret == 0 && b1->size != b2->size) + ret = b1->size < b2->size ? -1 : 1; + return ret; +} + +static gpointer +try_steal_and_unref (GBytes *bytes, + GDestroyNotify free_func, + gsize *size) +{ + gpointer result; + + if (bytes->free_func != free_func || bytes->data == NULL || + bytes->user_data != bytes->data) + return NULL; + + /* Are we the only reference? */ + if (g_atomic_ref_count_compare (&bytes->ref_count, 1)) + { + *size = bytes->size; + result = (gpointer)bytes->data; + g_slice_free (GBytes, bytes); + return result; + } + + return NULL; +} + + +/** + * g_bytes_unref_to_data: + * @bytes: (transfer full): a #GBytes + * @size: (out): location to place the length of the returned data + * + * Unreferences the bytes, and returns a pointer the same byte data + * contents. + * + * As an optimization, the byte data is returned without copying if this was + * the last reference to bytes and bytes was created with g_bytes_new(), + * g_bytes_new_take() or g_byte_array_free_to_bytes(). In all other cases the + * data is copied. + * + * Returns: (transfer full) (array length=size) (element-type guint8) + * (not nullable): a pointer to the same byte data, which should be + * freed with g_free() + * + * Since: 2.32 + */ +gpointer +g_bytes_unref_to_data (GBytes *bytes, + gsize *size) +{ + gpointer result; + + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (size != NULL, NULL); + + /* + * Optimal path: if this is was the last reference, then we can return + * the data from this GBytes without copying. + */ + + result = try_steal_and_unref (bytes, g_free, size); + if (result == NULL) + { + /* + * Copy: Non g_malloc (or compatible) allocator, or static memory, + * so we have to copy, and then unref. + */ + result = g_memdup2 (bytes->data, bytes->size); + *size = bytes->size; + g_bytes_unref (bytes); + } + + return result; +} + +/** + * g_bytes_unref_to_array: + * @bytes: (transfer full): a #GBytes + * + * Unreferences the bytes, and returns a new mutable #GByteArray containing + * the same byte data. + * + * As an optimization, the byte data is transferred to the array without copying + * if this was the last reference to bytes and bytes was created with + * g_bytes_new(), g_bytes_new_take() or g_byte_array_free_to_bytes(). In all + * other cases the data is copied. + * + * Do not use it if @bytes contains more than %G_MAXUINT + * bytes. #GByteArray stores the length of its data in #guint, which + * may be shorter than #gsize, that @bytes is using. + * + * Returns: (transfer full): a new mutable #GByteArray containing the same byte data + * + * Since: 2.32 + */ +GByteArray * +g_bytes_unref_to_array (GBytes *bytes) +{ + gpointer data; + gsize size; + + g_return_val_if_fail (bytes != NULL, NULL); + + data = g_bytes_unref_to_data (bytes, &size); + return g_byte_array_new_take (data, size); +} + +/** + * g_bytes_get_region: + * @bytes: a #GBytes + * @element_size: a non-zero element size + * @offset: an offset to the start of the region within the @bytes + * @n_elements: the number of elements in the region + * + * Gets a pointer to a region in @bytes. + * + * The region starts at @offset many bytes from the start of the data + * and contains @n_elements many elements of @element_size size. + * + * @n_elements may be zero, but @element_size must always be non-zero. + * Ideally, @element_size is a static constant (eg: sizeof a struct). + * + * This function does careful bounds checking (including checking for + * arithmetic overflows) and returns a non-%NULL pointer if the + * specified region lies entirely within the @bytes. If the region is + * in some way out of range, or if an overflow has occurred, then %NULL + * is returned. + * + * Note: it is possible to have a valid zero-size region. In this case, + * the returned pointer will be equal to the base pointer of the data of + * @bytes, plus @offset. This will be non-%NULL except for the case + * where @bytes itself was a zero-sized region. Since it is unlikely + * that you will be using this function to check for a zero-sized region + * in a zero-sized @bytes, %NULL effectively always means "error". + * + * Returns: (nullable): the requested region, or %NULL in case of an error + * + * Since: 2.70 + */ +gconstpointer +g_bytes_get_region (GBytes *bytes, + gsize element_size, + gsize offset, + gsize n_elements) +{ + gsize total_size; + gsize end_offset; + + g_return_val_if_fail (element_size > 0, NULL); + + /* No other assertion checks here. If something is wrong then we will + * simply crash (via NULL dereference or divide-by-zero). + */ + + if (!g_size_checked_mul (&total_size, element_size, n_elements)) + return NULL; + + if (!g_size_checked_add (&end_offset, offset, total_size)) + return NULL; + + /* We now have: + * + * 0 <= offset <= end_offset + * + * So we need only check that end_offset is within the range of the + * size of @bytes and we're good to go. + */ + + if (end_offset > bytes->size) + return NULL; + + /* We now have: + * + * 0 <= offset <= end_offset <= bytes->size + */ + + return ((guchar *) bytes->data) + offset; +} \ No newline at end of file diff --git a/glib/gbytes.h b/glib/gbytes.h new file mode 100644 index 0000000..37cad86 --- /dev/null +++ b/glib/gbytes.h @@ -0,0 +1,97 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * Copyright © 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + * Stef Walter + */ + +#ifndef __G_BYTES_H__ +#define __G_BYTES_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +GBytes * g_bytes_new (gconstpointer data, + gsize size); + +GLIB_AVAILABLE_IN_ALL +GBytes * g_bytes_new_take (gpointer data, + gsize size); + +GLIB_AVAILABLE_IN_ALL +GBytes * g_bytes_new_static (gconstpointer data, + gsize size); + +GLIB_AVAILABLE_IN_ALL +GBytes * g_bytes_new_with_free_func (gconstpointer data, + gsize size, + GDestroyNotify free_func, + gpointer user_data); + +GLIB_AVAILABLE_IN_ALL +GBytes * g_bytes_new_from_bytes (GBytes *bytes, + gsize offset, + gsize length); + +GLIB_AVAILABLE_IN_ALL +gconstpointer g_bytes_get_data (GBytes *bytes, + gsize *size); + +GLIB_AVAILABLE_IN_ALL +gsize g_bytes_get_size (GBytes *bytes); + +GLIB_AVAILABLE_IN_ALL +GBytes * g_bytes_ref (GBytes *bytes); + +GLIB_AVAILABLE_IN_ALL +void g_bytes_unref (GBytes *bytes); + +GLIB_AVAILABLE_IN_ALL +gpointer g_bytes_unref_to_data (GBytes *bytes, + gsize *size); + +GLIB_AVAILABLE_IN_ALL +GByteArray * g_bytes_unref_to_array (GBytes *bytes); + +GLIB_AVAILABLE_IN_ALL +guint g_bytes_hash (gconstpointer bytes); + +GLIB_AVAILABLE_IN_ALL +gboolean g_bytes_equal (gconstpointer bytes1, + gconstpointer bytes2); + +GLIB_AVAILABLE_IN_ALL +gint g_bytes_compare (gconstpointer bytes1, + gconstpointer bytes2); + +GLIB_AVAILABLE_IN_2_70 +gconstpointer g_bytes_get_region (GBytes *bytes, + gsize element_size, + gsize offset, + gsize n_elements); + + +G_END_DECLS + +#endif /* __G_BYTES_H__ */ diff --git a/glib/gcharset.c b/glib/gcharset.c new file mode 100644 index 0000000..09d3fa4 --- /dev/null +++ b/glib/gcharset.c @@ -0,0 +1,838 @@ +/* gcharset.c - Charset information + * + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" + +#include "gcharset.h" +#include "gcharsetprivate.h" + +#include "garray.h" +#include "genviron.h" +#include "ghash.h" +#include "gmessages.h" +#include "gstrfuncs.h" +#include "gthread.h" +#include "gthreadprivate.h" +#ifdef G_OS_WIN32 +#include "gwin32.h" +#endif + +#include "libcharset/libcharset.h" + +#include +#include + +#if (HAVE_LANGINFO_TIME_CODESET || HAVE_LANGINFO_CODESET) +#include +#endif + +#include +#ifdef G_OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + +G_LOCK_DEFINE_STATIC (aliases); + +static GHashTable * +get_alias_hash (void) +{ + static GHashTable *alias_hash = NULL; + const char *aliases; + + G_LOCK (aliases); + + if (!alias_hash) + { + alias_hash = g_hash_table_new (g_str_hash, g_str_equal); + + aliases = _g_locale_get_charset_aliases (); + while (*aliases != '\0') + { + const char *canonical; + const char *alias; + const char **alias_array; + int count = 0; + + alias = aliases; + aliases += strlen (aliases) + 1; + canonical = aliases; + aliases += strlen (aliases) + 1; + + alias_array = g_hash_table_lookup (alias_hash, canonical); + if (alias_array) + { + while (alias_array[count]) + count++; + } + + alias_array = g_renew (const char *, alias_array, count + 2); + alias_array[count] = alias; + alias_array[count + 1] = NULL; + + g_hash_table_insert (alias_hash, (char *)canonical, alias_array); + } + } + + G_UNLOCK (aliases); + + return alias_hash; +} + +/* As an abuse of the alias table, the following routines gets + * the charsets that are aliases for the canonical name. + */ +const char ** +_g_charset_get_aliases (const char *canonical_name) +{ + GHashTable *alias_hash = get_alias_hash (); + + return g_hash_table_lookup (alias_hash, canonical_name); +} + +static gboolean +g_utf8_get_charset_internal (const char *raw_data, + const char **a) +{ + /* Allow CHARSET to override the charset of any locale category. Users should + * probably never be setting this — instead, just add the charset after a `.` + * in `LANGUAGE`/`LC_ALL`/`LC_*`/`LANG`. I can’t find any reference (in + * `git log`, code comments, or man pages) to this environment variable being + * standardised or documented or even used anywhere outside GLib. Perhaps it + * should eventually be removed. */ + const char *charset = g_getenv ("CHARSET"); + + if (charset && *charset) + { + *a = charset; + + if (charset && strstr (charset, "UTF-8")) + return TRUE; + else + return FALSE; + } + + /* The libcharset code tries to be thread-safe without + * a lock, but has a memory leak and a missing memory + * barrier, so we lock for it + */ + G_LOCK (aliases); + charset = _g_locale_charset_unalias (raw_data); + G_UNLOCK (aliases); + + if (charset && *charset) + { + *a = charset; + + if (charset && strstr (charset, "UTF-8")) + return TRUE; + else + return FALSE; + } + + /* Assume this for compatibility at present. */ + *a = "US-ASCII"; + + return FALSE; +} + +typedef struct _GCharsetCache GCharsetCache; + +struct _GCharsetCache { + gboolean is_utf8; + gchar *raw; + gchar *charset; +}; + +static void +charset_cache_free (gpointer data) +{ + GCharsetCache *cache = data; + g_free (cache->raw); + g_free (cache->charset); + g_free (cache); +} + +/** + * g_get_charset: + * @charset: (out) (optional) (transfer none): return location for character set + * name, or %NULL. + * + * Obtains the character set for the [current locale][setlocale]; you + * might use this character set as an argument to g_convert(), to convert + * from the current locale's encoding to some other encoding. (Frequently + * g_locale_to_utf8() and g_locale_from_utf8() are nice shortcuts, though.) + * + * On Windows the character set returned by this function is the + * so-called system default ANSI code-page. That is the character set + * used by the "narrow" versions of C library and Win32 functions that + * handle file names. It might be different from the character set + * used by the C library's current locale. + * + * On Linux, the character set is found by consulting nl_langinfo() if + * available. If not, the environment variables `LC_ALL`, `LC_CTYPE`, `LANG` + * and `CHARSET` are queried in order. + * + * The return value is %TRUE if the locale's encoding is UTF-8, in that + * case you can perhaps avoid calling g_convert(). + * + * The string returned in @charset is not allocated, and should not be + * freed. + * + * Returns: %TRUE if the returned charset is UTF-8 + */ +gboolean +g_get_charset (const char **charset) +{ + static GPrivate cache_private = G_PRIVATE_INIT (charset_cache_free); + GCharsetCache *cache = g_private_get (&cache_private); + const gchar *raw; + + if (!cache) + cache = g_private_set_alloc0 (&cache_private, sizeof (GCharsetCache)); + + G_LOCK (aliases); + raw = _g_locale_charset_raw (); + G_UNLOCK (aliases); + + if (cache->raw == NULL || strcmp (cache->raw, raw) != 0) + { + const gchar *new_charset; + + g_free (cache->raw); + g_free (cache->charset); + cache->raw = g_strdup (raw); + cache->is_utf8 = g_utf8_get_charset_internal (raw, &new_charset); + cache->charset = g_strdup (new_charset); + } + + if (charset) + *charset = cache->charset; + + return cache->is_utf8; +} + +/* + * Do the same as g_get_charset() but it temporarily set locale (LC_ALL to + * LC_TIME) to correctly check for charset about time conversion relatives. + * + * Returns: %TRUE if the returned charset is UTF-8 + */ +gboolean +_g_get_time_charset (const char **charset) +{ + static GPrivate cache_private = G_PRIVATE_INIT (charset_cache_free); + GCharsetCache *cache = g_private_get (&cache_private); + const gchar *raw; + + if (!cache) + cache = g_private_set_alloc0 (&cache_private, sizeof (GCharsetCache)); + +#ifdef HAVE_LANGINFO_TIME_CODESET + raw = nl_langinfo (_NL_TIME_CODESET); +#else + G_LOCK (aliases); + raw = _g_locale_charset_raw (); + G_UNLOCK (aliases); +#endif + + if (cache->raw == NULL || strcmp (cache->raw, raw) != 0) + { + const gchar *new_charset; + + g_free (cache->raw); + g_free (cache->charset); + cache->raw = g_strdup (raw); + cache->is_utf8 = g_utf8_get_charset_internal (raw, &new_charset); + cache->charset = g_strdup (new_charset); + } + + if (charset) + *charset = cache->charset; + + return cache->is_utf8; +} +/* + * Do the same as g_get_charset() but it temporarily set locale (LC_ALL to + * LC_CTYPE) to correctly check for charset about CTYPE conversion relatives. + * + * Returns: %TRUE if the returned charset is UTF-8 + */ +gboolean +_g_get_ctype_charset (const char **charset) +{ + static GPrivate cache_private = G_PRIVATE_INIT (charset_cache_free); + GCharsetCache *cache = g_private_get (&cache_private); + const gchar *raw; + + if (!cache) + cache = g_private_set_alloc0 (&cache_private, sizeof (GCharsetCache)); + +#ifdef HAVE_LANGINFO_CODESET + raw = nl_langinfo (CODESET); +#else + G_LOCK (aliases); + raw = _g_locale_charset_raw (); + G_UNLOCK (aliases); +#endif + + if (cache->raw == NULL || strcmp (cache->raw, raw) != 0) + { + const gchar *new_charset; + + g_free (cache->raw); + g_free (cache->charset); + cache->raw = g_strdup (raw); + cache->is_utf8 = g_utf8_get_charset_internal (raw, &new_charset); + cache->charset = g_strdup (new_charset); + } + + if (charset) + *charset = cache->charset; + + return cache->is_utf8; +} + +/** + * g_get_codeset: + * + * Gets the character set for the current locale. + * + * Returns: a newly allocated string containing the name + * of the character set. This string must be freed with g_free(). + */ +gchar * +g_get_codeset (void) +{ + const gchar *charset; + + g_get_charset (&charset); + + return g_strdup (charset); +} + +/** + * g_get_console_charset: + * @charset: (out) (optional) (transfer none): return location for character set + * name, or %NULL. + * + * Obtains the character set used by the console attached to the process, + * which is suitable for printing output to the terminal. + * + * Usually this matches the result returned by g_get_charset(), but in + * environments where the locale's character set does not match the encoding + * of the console this function tries to guess a more suitable value instead. + * + * On Windows the character set returned by this function is the + * output code page used by the console associated with the calling process. + * If the codepage can't be determined (for example because there is no + * console attached) UTF-8 is assumed. + * + * The return value is %TRUE if the locale's encoding is UTF-8, in that + * case you can perhaps avoid calling g_convert(). + * + * The string returned in @charset is not allocated, and should not be + * freed. + * + * Returns: %TRUE if the returned charset is UTF-8 + * + * Since: 2.62 + */ +gboolean +g_get_console_charset (const char **charset) +{ +#ifdef G_OS_WIN32 + static GPrivate cache_private = G_PRIVATE_INIT (charset_cache_free); + GCharsetCache *cache = g_private_get (&cache_private); + const gchar *locale; + unsigned int cp; + char buf[2 + 20 + 1]; /* "CP" + G_MAXUINT64 (to be safe) in decimal form (20 bytes) + "\0" */ + const gchar *raw = NULL; + + if (!cache) + cache = g_private_set_alloc0 (&cache_private, sizeof (GCharsetCache)); + + /* first try to query $LANG (works for Cygwin/MSYS/MSYS2 and others using mintty) */ + locale = g_getenv ("LANG"); + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + raw = dot; + else if ((gsize) (modifier - dot) < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf[modifier - dot] = '\0'; + raw = buf; + } + } + } + /* next try querying console codepage using native win32 API */ + if (raw == NULL) + { + cp = GetConsoleOutputCP (); + if (cp) + { + sprintf (buf, "CP%u", cp); + raw = buf; + } + else if (GetLastError () != ERROR_INVALID_HANDLE) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + g_warning ("Failed to determine console output code page: %s. " + "Falling back to UTF-8", emsg); + g_free (emsg); + } + } + /* fall-back to UTF-8 if the rest failed (it's a universal default) */ + if (raw == NULL) + raw = "UTF-8"; + + if (cache->raw == NULL || strcmp (cache->raw, raw) != 0) + { + const gchar *new_charset; + + g_free (cache->raw); + g_free (cache->charset); + cache->raw = g_strdup (raw); + cache->is_utf8 = g_utf8_get_charset_internal (raw, &new_charset); + cache->charset = g_strdup (new_charset); + } + + if (charset) + *charset = cache->charset; + + return cache->is_utf8; +#else + /* assume the locale settings match the console encoding on non-Windows OSs */ + return g_get_charset (charset); +#endif +} + +#ifndef G_OS_WIN32 + +/* read an alias file for the locales */ +static void +read_aliases (const gchar *file, + GHashTable *alias_table) +{ + FILE *fp; + char buf[256]; + + fp = fopen (file,"r"); + if (!fp) + return; + while (fgets (buf, 256, fp)) + { + char *p, *q; + + g_strstrip (buf); + + /* Line is a comment */ + if ((buf[0] == '#') || (buf[0] == '\0')) + continue; + + /* Reads first column */ + for (p = buf, q = NULL; *p; p++) { + if ((*p == '\t') || (*p == ' ') || (*p == ':')) { + *p = '\0'; + q = p+1; + while ((*q == '\t') || (*q == ' ')) { + q++; + } + break; + } + } + /* The line only had one column */ + if (!q || *q == '\0') + continue; + + /* Read second column */ + for (p = q; *p; p++) { + if ((*p == '\t') || (*p == ' ')) { + *p = '\0'; + break; + } + } + + /* Add to alias table if necessary */ + if (!g_hash_table_lookup (alias_table, buf)) { + g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q)); + } + } + fclose (fp); +} + +#endif + +static char * +unalias_lang (char *lang) +{ +#ifndef G_OS_WIN32 + static GHashTable *alias_table = NULL; + char *p; + int i; + + if (g_once_init_enter (&alias_table)) + { + GHashTable *table = g_hash_table_new (g_str_hash, g_str_equal); + read_aliases ("/usr/share/locale/locale.alias", table); + g_once_init_leave (&alias_table, table); + } + + i = 0; + while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0)) + { + lang = p; + if (i++ == 30) + { + static gboolean said_before = FALSE; + if (!said_before) + g_warning ("Too many alias levels for a locale, " + "may indicate a loop"); + said_before = TRUE; + return lang; + } + } +#endif + return lang; +} + +/* Mask for components of locale spec. The ordering here is from + * least significant to most significant + */ +enum +{ + COMPONENT_CODESET = 1 << 0, + COMPONENT_TERRITORY = 1 << 1, + COMPONENT_MODIFIER = 1 << 2 +}; + +/* Break an X/Open style locale specification into components + */ +static guint +explode_locale (const gchar *locale, + gchar **language, + gchar **territory, + gchar **codeset, + gchar **modifier) +{ + const gchar *uscore_pos; + const gchar *at_pos; + const gchar *dot_pos; + + guint mask = 0; + + uscore_pos = strchr (locale, '_'); + dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.'); + at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@'); + + if (at_pos) + { + mask |= COMPONENT_MODIFIER; + *modifier = g_strdup (at_pos); + } + else + at_pos = locale + strlen (locale); + + if (dot_pos) + { + mask |= COMPONENT_CODESET; + *codeset = g_strndup (dot_pos, at_pos - dot_pos); + } + else + dot_pos = at_pos; + + if (uscore_pos) + { + mask |= COMPONENT_TERRITORY; + *territory = g_strndup (uscore_pos, dot_pos - uscore_pos); + } + else + uscore_pos = dot_pos; + + *language = g_strndup (locale, uscore_pos - locale); + + return mask; +} + +/* + * Compute all interesting variants for a given locale name - + * by stripping off different components of the value. + * + * For simplicity, we assume that the locale is in + * X/Open format: language[_territory][.codeset][@modifier] + * + * TODO: Extend this to handle the CEN format (see the GNUlibc docs) + * as well. We could just copy the code from glibc wholesale + * but it is big, ugly, and complicated, so I'm reluctant + * to do so when this should handle 99% of the time... + */ +static void +append_locale_variants (GPtrArray *array, + const gchar *locale) +{ + gchar *language = NULL; + gchar *territory = NULL; + gchar *codeset = NULL; + gchar *modifier = NULL; + + guint mask; + guint i, j; + + g_return_if_fail (locale != NULL); + + mask = explode_locale (locale, &language, &territory, &codeset, &modifier); + + /* Iterate through all possible combinations, from least attractive + * to most attractive. + */ + for (j = 0; j <= mask; ++j) + { + i = mask - j; + + if ((i & ~mask) == 0) + { + gchar *val = g_strconcat (language, + (i & COMPONENT_TERRITORY) ? territory : "", + (i & COMPONENT_CODESET) ? codeset : "", + (i & COMPONENT_MODIFIER) ? modifier : "", + NULL); + g_ptr_array_add (array, val); + } + } + + g_free (language); + if (mask & COMPONENT_CODESET) + g_free (codeset); + if (mask & COMPONENT_TERRITORY) + g_free (territory); + if (mask & COMPONENT_MODIFIER) + g_free (modifier); +} + +/** + * g_get_locale_variants: + * @locale: a locale identifier + * + * Returns a list of derived variants of @locale, which can be used to + * e.g. construct locale-dependent filenames or search paths. The returned + * list is sorted from most desirable to least desirable. + * This function handles territory, charset and extra locale modifiers. See + * [`setlocale(3)`](man:setlocale) for information about locales and their format. + * + * @locale itself is guaranteed to be returned in the output. + * + * For example, if @locale is `fr_BE`, then the returned list + * is `fr_BE`, `fr`. If @locale is `en_GB.UTF-8@euro`, then the returned list + * is `en_GB.UTF-8@euro`, `en_GB.UTF-8`, `en_GB@euro`, `en_GB`, `en.UTF-8@euro`, + * `en.UTF-8`, `en@euro`, `en`. + * + * If you need the list of variants for the current locale, + * use g_get_language_names(). + * + * Returns: (transfer full) (array zero-terminated=1) (element-type utf8): a newly + * allocated array of newly allocated strings with the locale variants. Free with + * g_strfreev(). + * + * Since: 2.28 + */ +gchar ** +g_get_locale_variants (const gchar *locale) +{ + GPtrArray *array; + + g_return_val_if_fail (locale != NULL, NULL); + + array = g_ptr_array_sized_new (8); + append_locale_variants (array, locale); + g_ptr_array_add (array, NULL); + + return (gchar **) g_ptr_array_free (array, FALSE); +} + +/* The following is (partly) taken from the gettext package. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. */ + +static const gchar * +guess_category_value (const gchar *category_name) +{ + const gchar *retval; + + /* The highest priority value is the 'LANGUAGE' environment + variable. This is a GNU extension. */ + retval = g_getenv ("LANGUAGE"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* 'LANGUAGE' is not set. So we have to proceed with the POSIX + methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'. On some + systems this can be done by the 'setlocale' function itself. */ + + /* Setting of LC_ALL overwrites all other. */ + retval = g_getenv ("LC_ALL"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* Next comes the name of the desired category. */ + retval = g_getenv (category_name); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* Last possibility is the LANG environment variable. */ + retval = g_getenv ("LANG"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + +#ifdef G_PLATFORM_WIN32 + /* g_win32_getlocale() first checks for LC_ALL, LC_MESSAGES and + * LANG, which we already did above. Oh well. The main point of + * calling g_win32_getlocale() is to get the thread's locale as used + * by Windows and the Microsoft C runtime (in the "English_United + * States" format) translated into the Unixish format. + */ + { + char *locale = g_win32_getlocale (); + retval = g_intern_string (locale); + g_free (locale); + return retval; + } +#endif + + return NULL; +} + +typedef struct _GLanguageNamesCache GLanguageNamesCache; + +struct _GLanguageNamesCache { + gchar *languages; + gchar **language_names; +}; + +static void +language_names_cache_free (gpointer data) +{ + GLanguageNamesCache *cache = data; + g_free (cache->languages); + g_strfreev (cache->language_names); + g_free (cache); +} + +/** + * g_get_language_names: + * + * Computes a list of applicable locale names, which can be used to + * e.g. construct locale-dependent filenames or search paths. The returned + * list is sorted from most desirable to least desirable and always contains + * the default locale "C". + * + * For example, if LANGUAGE=de:en_US, then the returned list is + * "de", "en_US", "en", "C". + * + * This function consults the environment variables `LANGUAGE`, `LC_ALL`, + * `LC_MESSAGES` and `LANG` to find the list of locales specified by the + * user. + * + * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by GLib + * that must not be modified or freed. + * + * Since: 2.6 + */ +const gchar * const * +g_get_language_names (void) +{ + return g_get_language_names_with_category ("LC_MESSAGES"); +} + +/** + * g_get_language_names_with_category: + * @category_name: a locale category name + * + * Computes a list of applicable locale names with a locale category name, + * which can be used to construct the fallback locale-dependent filenames + * or search paths. The returned list is sorted from most desirable to + * least desirable and always contains the default locale "C". + * + * This function consults the environment variables `LANGUAGE`, `LC_ALL`, + * @category_name, and `LANG` to find the list of locales specified by the + * user. + * + * g_get_language_names() returns g_get_language_names_with_category("LC_MESSAGES"). + * + * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by + * the thread g_get_language_names_with_category was called from. + * It must not be modified or freed. It must be copied if planned to be used in another thread. + * + * Since: 2.58 + */ +const gchar * const * +g_get_language_names_with_category (const gchar *category_name) +{ + static GPrivate cache_private = G_PRIVATE_INIT ((void (*)(gpointer)) g_hash_table_unref); + GHashTable *cache = g_private_get (&cache_private); + const gchar *languages; + GLanguageNamesCache *name_cache; + + g_return_val_if_fail (category_name != NULL, NULL); + + if (!cache) + { + cache = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, language_names_cache_free); + g_private_set (&cache_private, cache); + } + + languages = guess_category_value (category_name); + if (!languages) + languages = "C"; + + name_cache = (GLanguageNamesCache *) g_hash_table_lookup (cache, category_name); + if (!(name_cache && name_cache->languages && + strcmp (name_cache->languages, languages) == 0)) + { + GPtrArray *array; + gchar **alist, **a; + + g_hash_table_remove (cache, category_name); + + array = g_ptr_array_sized_new (8); + + alist = g_strsplit (languages, ":", 0); + for (a = alist; *a; a++) + append_locale_variants (array, unalias_lang (*a)); + g_strfreev (alist); + g_ptr_array_add (array, g_strdup ("C")); + g_ptr_array_add (array, NULL); + + name_cache = g_new0 (GLanguageNamesCache, 1); + name_cache->languages = g_strdup (languages); + name_cache->language_names = (gchar **) g_ptr_array_free (array, FALSE); + g_hash_table_insert (cache, g_strdup (category_name), name_cache); + } + + return (const gchar * const *) name_cache->language_names; +} diff --git a/glib/gcharset.h b/glib/gcharset.h new file mode 100644 index 0000000..82020f6 --- /dev/null +++ b/glib/gcharset.h @@ -0,0 +1,47 @@ +/* gcharset.h - Charset functions + * + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef __G_CHARSET_H__ +#define __G_CHARSET_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +gboolean g_get_charset (const char **charset); +GLIB_AVAILABLE_IN_ALL +gchar * g_get_codeset (void); +GLIB_AVAILABLE_IN_2_62 +gboolean g_get_console_charset (const char **charset); + +GLIB_AVAILABLE_IN_ALL +const gchar * const * g_get_language_names (void); +GLIB_AVAILABLE_IN_2_58 +const gchar * const * g_get_language_names_with_category + (const gchar *category_name); +GLIB_AVAILABLE_IN_ALL +gchar ** g_get_locale_variants (const gchar *locale); + +G_END_DECLS + +#endif /* __G_CHARSET_H__ */ diff --git a/glib/gcharsetprivate.h b/glib/gcharsetprivate.h new file mode 100644 index 0000000..9b1def2 --- /dev/null +++ b/glib/gcharsetprivate.h @@ -0,0 +1,34 @@ +/* gunicodeprivate.h + * + * Copyright (C) 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __G_CHARSET_PRIVATE_H__ +#define __G_CHARSET_PRIVATE_H__ + +#include "gcharset.h" + +G_BEGIN_DECLS + +const char ** _g_charset_get_aliases (const char *canonical_name); + +gboolean _g_get_time_charset (const char **charset); + +gboolean _g_get_ctype_charset (const char **charset); + +G_END_DECLS + +#endif diff --git a/glib/gchecksum.c b/glib/gchecksum.c new file mode 100644 index 0000000..29b479b --- /dev/null +++ b/glib/gchecksum.c @@ -0,0 +1,1864 @@ +/* gchecksum.h - data hashing functions + * + * Copyright (C) 2007 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include "config.h" + +#include + +#include "gchecksum.h" + +#include "gslice.h" +#include "gmem.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gtypes.h" +#include "glibintl.h" + + +/** + * SECTION:checksum + * @title: Data Checksums + * @short_description: computes the checksum for data + * + * GLib provides a generic API for computing checksums (or "digests") + * for a sequence of arbitrary bytes, using various hashing algorithms + * like MD5, SHA-1 and SHA-256. Checksums are commonly used in various + * environments and specifications. + * + * GLib supports incremental checksums using the GChecksum data + * structure, by calling g_checksum_update() as long as there's data + * available and then using g_checksum_get_string() or + * g_checksum_get_digest() to compute the checksum and return it either + * as a string in hexadecimal form, or as a raw sequence of bytes. To + * compute the checksum for binary blobs and NUL-terminated strings in + * one go, use the convenience functions g_compute_checksum_for_data() + * and g_compute_checksum_for_string(), respectively. + * + * Support for checksums has been added in GLib 2.16 + **/ + +#define IS_VALID_TYPE(type) ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA384) + +/* The fact that these are lower case characters is part of the ABI */ +static const gchar hex_digits[] = "0123456789abcdef"; + +#define MD5_DATASIZE 64 +#define MD5_DIGEST_LEN 16 + +typedef struct +{ + guint32 buf[4]; + guint32 bits[2]; + + union { + guchar data[MD5_DATASIZE]; + guint32 data32[MD5_DATASIZE / 4]; + } u; + + guchar digest[MD5_DIGEST_LEN]; +} Md5sum; + +#define SHA1_DATASIZE 64 +#define SHA1_DIGEST_LEN 20 + +typedef struct +{ + guint32 buf[5]; + guint32 bits[2]; + + /* we pack 64 unsigned chars into 16 32-bit unsigned integers */ + guint32 data[16]; + + guchar digest[SHA1_DIGEST_LEN]; +} Sha1sum; + +#define SHA256_DATASIZE 64 +#define SHA256_DIGEST_LEN 32 + +typedef struct +{ + guint32 buf[8]; + guint32 bits[2]; + + guint8 data[SHA256_DATASIZE]; + + guchar digest[SHA256_DIGEST_LEN]; +} Sha256sum; + +/* SHA2 is common thing for SHA-384, SHA-512, SHA-512/224 and SHA-512/256 */ +#define SHA2_BLOCK_LEN 128 /* 1024 bits message block */ +#define SHA384_DIGEST_LEN 48 +#define SHA512_DIGEST_LEN 64 + +typedef struct +{ + guint64 H[8]; + + guint8 block[SHA2_BLOCK_LEN]; + guint8 block_len; + + guint64 data_len[2]; + + guchar digest[SHA512_DIGEST_LEN]; +} Sha512sum; + +struct _GChecksum +{ + GChecksumType type; + + gchar *digest_str; + + union { + Md5sum md5; + Sha1sum sha1; + Sha256sum sha256; + Sha512sum sha512; + } sum; +}; + +/* we need different byte swapping functions because MD5 expects buffers + * to be little-endian, while SHA1 and SHA256 expect them in big-endian + * form. + */ + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define md5_byte_reverse(buffer,length) +#else +/* assume that the passed buffer is integer aligned */ +static inline void +md5_byte_reverse (guchar *buffer, + gulong length) +{ + guint32 bit; + + do + { + bit = (guint32) ((unsigned) buffer[3] << 8 | buffer[2]) << 16 | + ((unsigned) buffer[1] << 8 | buffer[0]); + * (guint32 *) buffer = bit; + buffer += 4; + } + while (--length); +} +#endif /* G_BYTE_ORDER == G_LITTLE_ENDIAN */ + +#if G_BYTE_ORDER == G_BIG_ENDIAN +#define sha_byte_reverse(buffer,length) +#else +static inline void +sha_byte_reverse (guint32 *buffer, + gint length) +{ + length /= sizeof (guint32); + while (length--) + { + *buffer = GUINT32_SWAP_LE_BE (*buffer); + ++buffer; + } +} +#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */ + +static gchar * +digest_to_string (guint8 *digest, + gsize digest_len) +{ + gsize i, len = digest_len * 2; + gchar *retval; + + retval = g_new (gchar, len + 1); + + for (i = 0; i < digest_len; i++) + { + guint8 byte = digest[i]; + + retval[2 * i] = hex_digits[byte >> 4]; + retval[2 * i + 1] = hex_digits[byte & 0xf]; + } + + retval[len] = 0; + + return retval; +} + +/* + * MD5 Checksum + */ + +/* This MD5 digest computation is based on the equivalent code + * written by Colin Plumb. It came with this notice: + * + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + */ + +static void +md5_sum_init (Md5sum *md5) +{ + /* arbitrary constants */ + md5->buf[0] = 0x67452301; + md5->buf[1] = 0xefcdab89; + md5->buf[2] = 0x98badcfe; + md5->buf[3] = 0x10325476; + + md5->bits[0] = md5->bits[1] = 0; +} + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. md5_sum_update() + * blocks the data and converts bytes into longwords for this routine. + */ +static void +md5_transform (guint32 buf[4], + guint32 const in[16]) +{ + guint32 a, b, c, d; + +/* The four core functions - F1 is optimized somewhat */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1 (z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define md5_step(f, w, x, y, z, data, s) \ + ( w += f (x, y, z) + data, w = w << s | w >> (32 - s), w += x ) + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + md5_step (F1, a, b, c, d, in[0] + 0xd76aa478, 7); + md5_step (F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + md5_step (F1, c, d, a, b, in[2] + 0x242070db, 17); + md5_step (F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + md5_step (F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + md5_step (F1, d, a, b, c, in[5] + 0x4787c62a, 12); + md5_step (F1, c, d, a, b, in[6] + 0xa8304613, 17); + md5_step (F1, b, c, d, a, in[7] + 0xfd469501, 22); + md5_step (F1, a, b, c, d, in[8] + 0x698098d8, 7); + md5_step (F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + md5_step (F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + md5_step (F1, b, c, d, a, in[11] + 0x895cd7be, 22); + md5_step (F1, a, b, c, d, in[12] + 0x6b901122, 7); + md5_step (F1, d, a, b, c, in[13] + 0xfd987193, 12); + md5_step (F1, c, d, a, b, in[14] + 0xa679438e, 17); + md5_step (F1, b, c, d, a, in[15] + 0x49b40821, 22); + + md5_step (F2, a, b, c, d, in[1] + 0xf61e2562, 5); + md5_step (F2, d, a, b, c, in[6] + 0xc040b340, 9); + md5_step (F2, c, d, a, b, in[11] + 0x265e5a51, 14); + md5_step (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + md5_step (F2, a, b, c, d, in[5] + 0xd62f105d, 5); + md5_step (F2, d, a, b, c, in[10] + 0x02441453, 9); + md5_step (F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + md5_step (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + md5_step (F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + md5_step (F2, d, a, b, c, in[14] + 0xc33707d6, 9); + md5_step (F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + md5_step (F2, b, c, d, a, in[8] + 0x455a14ed, 20); + md5_step (F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + md5_step (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + md5_step (F2, c, d, a, b, in[7] + 0x676f02d9, 14); + md5_step (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + md5_step (F3, a, b, c, d, in[5] + 0xfffa3942, 4); + md5_step (F3, d, a, b, c, in[8] + 0x8771f681, 11); + md5_step (F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + md5_step (F3, b, c, d, a, in[14] + 0xfde5380c, 23); + md5_step (F3, a, b, c, d, in[1] + 0xa4beea44, 4); + md5_step (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + md5_step (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + md5_step (F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + md5_step (F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + md5_step (F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + md5_step (F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + md5_step (F3, b, c, d, a, in[6] + 0x04881d05, 23); + md5_step (F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + md5_step (F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + md5_step (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + md5_step (F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + md5_step (F4, a, b, c, d, in[0] + 0xf4292244, 6); + md5_step (F4, d, a, b, c, in[7] + 0x432aff97, 10); + md5_step (F4, c, d, a, b, in[14] + 0xab9423a7, 15); + md5_step (F4, b, c, d, a, in[5] + 0xfc93a039, 21); + md5_step (F4, a, b, c, d, in[12] + 0x655b59c3, 6); + md5_step (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + md5_step (F4, c, d, a, b, in[10] + 0xffeff47d, 15); + md5_step (F4, b, c, d, a, in[1] + 0x85845dd1, 21); + md5_step (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + md5_step (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + md5_step (F4, c, d, a, b, in[6] + 0xa3014314, 15); + md5_step (F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + md5_step (F4, a, b, c, d, in[4] + 0xf7537e82, 6); + md5_step (F4, d, a, b, c, in[11] + 0xbd3af235, 10); + md5_step (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + md5_step (F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; + +#undef F1 +#undef F2 +#undef F3 +#undef F4 +#undef md5_step +} + +static void +md5_sum_update (Md5sum *md5, + const guchar *data, + gsize length) +{ + guint32 bit; + + bit = md5->bits[0]; + md5->bits[0] = bit + ((guint32) length << 3); + + /* carry from low to high */ + if (md5->bits[0] < bit) + md5->bits[1] += 1; + + md5->bits[1] += length >> 29; + + /* bytes already in Md5sum->u.data */ + bit = (bit >> 3) & 0x3f; + + /* handle any leading odd-sized chunks */ + if (bit) + { + guchar *p = md5->u.data + bit; + + bit = MD5_DATASIZE - bit; + if (length < bit) + { + memcpy (p, data, length); + return; + } + + memcpy (p, data, bit); + + md5_byte_reverse (md5->u.data, 16); + md5_transform (md5->buf, md5->u.data32); + + data += bit; + length -= bit; + } + + /* process data in 64-byte chunks */ + while (length >= MD5_DATASIZE) + { + memcpy (md5->u.data, data, MD5_DATASIZE); + + md5_byte_reverse (md5->u.data, 16); + md5_transform (md5->buf, md5->u.data32); + + data += MD5_DATASIZE; + length -= MD5_DATASIZE; + } + + /* handle any remaining bytes of data */ + memcpy (md5->u.data, data, length); +} + +/* closes a checksum */ +static void +md5_sum_close (Md5sum *md5) +{ + guint count; + guchar *p; + + /* Compute number of bytes mod 64 */ + count = (md5->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. + * This is safe since there is always at least one byte free + */ + p = md5->u.data + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = MD5_DATASIZE - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) + { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset (p, 0, count); + + md5_byte_reverse (md5->u.data, 16); + md5_transform (md5->buf, md5->u.data32); + + /* Now fill the next block with 56 bytes */ + memset (md5->u.data, 0, MD5_DATASIZE - 8); + } + else + { + /* Pad block to 56 bytes */ + memset (p, 0, count - 8); + } + + md5_byte_reverse (md5->u.data, 14); + + /* Append length in bits and transform */ + md5->u.data32[14] = md5->bits[0]; + md5->u.data32[15] = md5->bits[1]; + + md5_transform (md5->buf, md5->u.data32); + md5_byte_reverse ((guchar *) md5->buf, 4); + + memcpy (md5->digest, md5->buf, 16); + + /* Reset buffers in case they contain sensitive data */ + memset (md5->buf, 0, sizeof (md5->buf)); + memset (md5->u.data, 0, sizeof (md5->u.data)); +} + +static gchar * +md5_sum_to_string (Md5sum *md5) +{ + return digest_to_string (md5->digest, MD5_DIGEST_LEN); +} + +static void +md5_sum_digest (Md5sum *md5, + guint8 *digest) +{ + gint i; + + for (i = 0; i < MD5_DIGEST_LEN; i++) + digest[i] = md5->digest[i]; +} + +/* + * SHA-1 Checksum + */ + +/* The following implementation comes from D-Bus dbus-sha.c. I've changed + * it to use GLib types and to work more like the MD5 implementation above. + * I left the comments to have a history of this code. + * -- Emmanuele Bassi, ebassi@gnome.org + */ + +/* The following comments have the history of where this code + * comes from. I actually copied it from GNet in GNOME CVS. + * - hp@redhat.com + */ + +/* + * sha.h : Implementation of the Secure Hash Algorithm + * + * Part of the Python Cryptography Toolkit, version 1.0.0 + * + * Copyright (C) 1995, A.M. Kuchling + * + * Distribute and use freely; there are no restrictions on further + * dissemination and usage except those imposed by the laws of your + * country of residence. + * + */ + +/* SHA: NIST's Secure Hash Algorithm */ + +/* Based on SHA code originally posted to sci.crypt by Peter Gutmann + in message <30ajo5$oe8@ccu2.auckland.ac.nz>. + Modified to test for endianness on creation of SHA objects by AMK. + Also, the original specification of SHA was found to have a weakness + by NSA/NIST. This code implements the fixed version of SHA. +*/ + +/* Here's the first paragraph of Peter Gutmann's posting: + +The following is my SHA (FIPS 180) code updated to allow use of the "fixed" +SHA, thanks to Jim Gillogly and an anonymous contributor for the information on +what's changed in the new version. The fix is a simple change which involves +adding a single rotate in the initial expansion function. It is unknown +whether this is an optimal solution to the problem which was discovered in the +SHA or whether it's simply a bandaid which fixes the problem with a minimum of +effort (for example the reengineering of a great many Capstone chips). +*/ + +static void +sha1_sum_init (Sha1sum *sha1) +{ + /* initialize constants */ + sha1->buf[0] = 0x67452301L; + sha1->buf[1] = 0xEFCDAB89L; + sha1->buf[2] = 0x98BADCFEL; + sha1->buf[3] = 0x10325476L; + sha1->buf[4] = 0xC3D2E1F0L; + + /* initialize bits */ + sha1->bits[0] = sha1->bits[1] = 0; +} + +/* The SHA f()-functions. */ + +#define f1(x,y,z) (z ^ (x & (y ^ z))) /* Rounds 0-19 */ +#define f2(x,y,z) (x ^ y ^ z) /* Rounds 20-39 */ +#define f3(x,y,z) (( x & y) | (z & (x | y))) /* Rounds 40-59 */ +#define f4(x,y,z) (x ^ y ^ z) /* Rounds 60-79 */ + +/* The SHA Mysterious Constants */ +#define K1 0x5A827999L /* Rounds 0-19 */ +#define K2 0x6ED9EBA1L /* Rounds 20-39 */ +#define K3 0x8F1BBCDCL /* Rounds 40-59 */ +#define K4 0xCA62C1D6L /* Rounds 60-79 */ + +/* 32-bit rotate left - kludged with shifts */ +#define ROTL(n,X) (((X) << n ) | ((X) >> (32 - n))) + +/* The initial expanding function. The hash function is defined over an + 80-word expanded input array W, where the first 16 are copies of the input + data, and the remaining 64 are defined by + + W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ] + + This implementation generates these values on the fly in a circular + buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this + optimization. + + The updated SHA changes the expanding function by adding a rotate of 1 + bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor + for this information */ + +#define expand(W,i) (W[ i & 15 ] = ROTL (1, (W[ i & 15] ^ \ + W[(i - 14) & 15] ^ \ + W[(i - 8) & 15] ^ \ + W[(i - 3) & 15]))) + + +/* The prototype SHA sub-round. The fundamental sub-round is: + + a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data; + b' = a; + c' = ROTL( 30, b ); + d' = c; + e' = d; + + but this is implemented by unrolling the loop 5 times and renaming the + variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration. + This code is then replicated 20 times for each of the 4 functions, using + the next 20 values from the W[] array each time */ + +#define subRound(a, b, c, d, e, f, k, data) \ + (e += ROTL (5, a) + f(b, c, d) + k + data, b = ROTL (30, b)) + +static void +sha1_transform (guint32 buf[5], + guint32 in[16]) +{ + guint32 A, B, C, D, E; + + A = buf[0]; + B = buf[1]; + C = buf[2]; + D = buf[3]; + E = buf[4]; + + /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */ + subRound (A, B, C, D, E, f1, K1, in[0]); + subRound (E, A, B, C, D, f1, K1, in[1]); + subRound (D, E, A, B, C, f1, K1, in[2]); + subRound (C, D, E, A, B, f1, K1, in[3]); + subRound (B, C, D, E, A, f1, K1, in[4]); + subRound (A, B, C, D, E, f1, K1, in[5]); + subRound (E, A, B, C, D, f1, K1, in[6]); + subRound (D, E, A, B, C, f1, K1, in[7]); + subRound (C, D, E, A, B, f1, K1, in[8]); + subRound (B, C, D, E, A, f1, K1, in[9]); + subRound (A, B, C, D, E, f1, K1, in[10]); + subRound (E, A, B, C, D, f1, K1, in[11]); + subRound (D, E, A, B, C, f1, K1, in[12]); + subRound (C, D, E, A, B, f1, K1, in[13]); + subRound (B, C, D, E, A, f1, K1, in[14]); + subRound (A, B, C, D, E, f1, K1, in[15]); + subRound (E, A, B, C, D, f1, K1, expand (in, 16)); + subRound (D, E, A, B, C, f1, K1, expand (in, 17)); + subRound (C, D, E, A, B, f1, K1, expand (in, 18)); + subRound (B, C, D, E, A, f1, K1, expand (in, 19)); + + subRound (A, B, C, D, E, f2, K2, expand (in, 20)); + subRound (E, A, B, C, D, f2, K2, expand (in, 21)); + subRound (D, E, A, B, C, f2, K2, expand (in, 22)); + subRound (C, D, E, A, B, f2, K2, expand (in, 23)); + subRound (B, C, D, E, A, f2, K2, expand (in, 24)); + subRound (A, B, C, D, E, f2, K2, expand (in, 25)); + subRound (E, A, B, C, D, f2, K2, expand (in, 26)); + subRound (D, E, A, B, C, f2, K2, expand (in, 27)); + subRound (C, D, E, A, B, f2, K2, expand (in, 28)); + subRound (B, C, D, E, A, f2, K2, expand (in, 29)); + subRound (A, B, C, D, E, f2, K2, expand (in, 30)); + subRound (E, A, B, C, D, f2, K2, expand (in, 31)); + subRound (D, E, A, B, C, f2, K2, expand (in, 32)); + subRound (C, D, E, A, B, f2, K2, expand (in, 33)); + subRound (B, C, D, E, A, f2, K2, expand (in, 34)); + subRound (A, B, C, D, E, f2, K2, expand (in, 35)); + subRound (E, A, B, C, D, f2, K2, expand (in, 36)); + subRound (D, E, A, B, C, f2, K2, expand (in, 37)); + subRound (C, D, E, A, B, f2, K2, expand (in, 38)); + subRound (B, C, D, E, A, f2, K2, expand (in, 39)); + + subRound (A, B, C, D, E, f3, K3, expand (in, 40)); + subRound (E, A, B, C, D, f3, K3, expand (in, 41)); + subRound (D, E, A, B, C, f3, K3, expand (in, 42)); + subRound (C, D, E, A, B, f3, K3, expand (in, 43)); + subRound (B, C, D, E, A, f3, K3, expand (in, 44)); + subRound (A, B, C, D, E, f3, K3, expand (in, 45)); + subRound (E, A, B, C, D, f3, K3, expand (in, 46)); + subRound (D, E, A, B, C, f3, K3, expand (in, 47)); + subRound (C, D, E, A, B, f3, K3, expand (in, 48)); + subRound (B, C, D, E, A, f3, K3, expand (in, 49)); + subRound (A, B, C, D, E, f3, K3, expand (in, 50)); + subRound (E, A, B, C, D, f3, K3, expand (in, 51)); + subRound (D, E, A, B, C, f3, K3, expand (in, 52)); + subRound (C, D, E, A, B, f3, K3, expand (in, 53)); + subRound (B, C, D, E, A, f3, K3, expand (in, 54)); + subRound (A, B, C, D, E, f3, K3, expand (in, 55)); + subRound (E, A, B, C, D, f3, K3, expand (in, 56)); + subRound (D, E, A, B, C, f3, K3, expand (in, 57)); + subRound (C, D, E, A, B, f3, K3, expand (in, 58)); + subRound (B, C, D, E, A, f3, K3, expand (in, 59)); + + subRound (A, B, C, D, E, f4, K4, expand (in, 60)); + subRound (E, A, B, C, D, f4, K4, expand (in, 61)); + subRound (D, E, A, B, C, f4, K4, expand (in, 62)); + subRound (C, D, E, A, B, f4, K4, expand (in, 63)); + subRound (B, C, D, E, A, f4, K4, expand (in, 64)); + subRound (A, B, C, D, E, f4, K4, expand (in, 65)); + subRound (E, A, B, C, D, f4, K4, expand (in, 66)); + subRound (D, E, A, B, C, f4, K4, expand (in, 67)); + subRound (C, D, E, A, B, f4, K4, expand (in, 68)); + subRound (B, C, D, E, A, f4, K4, expand (in, 69)); + subRound (A, B, C, D, E, f4, K4, expand (in, 70)); + subRound (E, A, B, C, D, f4, K4, expand (in, 71)); + subRound (D, E, A, B, C, f4, K4, expand (in, 72)); + subRound (C, D, E, A, B, f4, K4, expand (in, 73)); + subRound (B, C, D, E, A, f4, K4, expand (in, 74)); + subRound (A, B, C, D, E, f4, K4, expand (in, 75)); + subRound (E, A, B, C, D, f4, K4, expand (in, 76)); + subRound (D, E, A, B, C, f4, K4, expand (in, 77)); + subRound (C, D, E, A, B, f4, K4, expand (in, 78)); + subRound (B, C, D, E, A, f4, K4, expand (in, 79)); + + /* Build message digest */ + buf[0] += A; + buf[1] += B; + buf[2] += C; + buf[3] += D; + buf[4] += E; +} + +#undef K1 +#undef K2 +#undef K3 +#undef K4 +#undef f1 +#undef f2 +#undef f3 +#undef f4 +#undef ROTL +#undef expand +#undef subRound + +static void +sha1_sum_update (Sha1sum *sha1, + const guchar *buffer, + gsize count) +{ + guint32 tmp; + guint dataCount; + + /* Update bitcount */ + tmp = sha1->bits[0]; + if ((sha1->bits[0] = tmp + ((guint32) count << 3) ) < tmp) + sha1->bits[1] += 1; /* Carry from low to high */ + sha1->bits[1] += count >> 29; + + /* Get count of bytes already in data */ + dataCount = (guint) (tmp >> 3) & 0x3F; + + /* Handle any leading odd-sized chunks */ + if (dataCount) + { + guchar *p = (guchar *) sha1->data + dataCount; + + dataCount = SHA1_DATASIZE - dataCount; + if (count < dataCount) + { + memcpy (p, buffer, count); + return; + } + + memcpy (p, buffer, dataCount); + + sha_byte_reverse (sha1->data, SHA1_DATASIZE); + sha1_transform (sha1->buf, sha1->data); + + buffer += dataCount; + count -= dataCount; + } + + /* Process data in SHA1_DATASIZE chunks */ + while (count >= SHA1_DATASIZE) + { + memcpy (sha1->data, buffer, SHA1_DATASIZE); + + sha_byte_reverse (sha1->data, SHA1_DATASIZE); + sha1_transform (sha1->buf, sha1->data); + + buffer += SHA1_DATASIZE; + count -= SHA1_DATASIZE; + } + + /* Handle any remaining bytes of data. */ + memcpy (sha1->data, buffer, count); +} + +/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ +static void +sha1_sum_close (Sha1sum *sha1) +{ + gint count; + guchar *data_p; + + /* Compute number of bytes mod 64 */ + count = (gint) ((sha1->bits[0] >> 3) & 0x3f); + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + data_p = (guchar *) sha1->data + count; + *data_p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = SHA1_DATASIZE - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) + { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset (data_p, 0, count); + + sha_byte_reverse (sha1->data, SHA1_DATASIZE); + sha1_transform (sha1->buf, sha1->data); + + /* Now fill the next block with 56 bytes */ + memset (sha1->data, 0, SHA1_DATASIZE - 8); + } + else + { + /* Pad block to 56 bytes */ + memset (data_p, 0, count - 8); + } + + /* Append length in bits and transform */ + sha1->data[14] = sha1->bits[1]; + sha1->data[15] = sha1->bits[0]; + + sha_byte_reverse (sha1->data, SHA1_DATASIZE - 8); + sha1_transform (sha1->buf, sha1->data); + sha_byte_reverse (sha1->buf, SHA1_DIGEST_LEN); + + memcpy (sha1->digest, sha1->buf, SHA1_DIGEST_LEN); + + /* Reset buffers in case they contain sensitive data */ + memset (sha1->buf, 0, sizeof (sha1->buf)); + memset (sha1->data, 0, sizeof (sha1->data)); +} + +static gchar * +sha1_sum_to_string (Sha1sum *sha1) +{ + return digest_to_string (sha1->digest, SHA1_DIGEST_LEN); +} + +static void +sha1_sum_digest (Sha1sum *sha1, + guint8 *digest) +{ + gint i; + + for (i = 0; i < SHA1_DIGEST_LEN; i++) + digest[i] = sha1->digest[i]; +} + +/* + * SHA-256 Checksum + */ + +/* adapted from the SHA256 implementation in gsk/src/hash/gskhash.c. + * + * Copyright (C) 2006 Dave Benson + * Released under the terms of the GNU Lesser General Public License + */ + +static void +sha256_sum_init (Sha256sum *sha256) +{ + sha256->buf[0] = 0x6a09e667; + sha256->buf[1] = 0xbb67ae85; + sha256->buf[2] = 0x3c6ef372; + sha256->buf[3] = 0xa54ff53a; + sha256->buf[4] = 0x510e527f; + sha256->buf[5] = 0x9b05688c; + sha256->buf[6] = 0x1f83d9ab; + sha256->buf[7] = 0x5be0cd19; + + sha256->bits[0] = sha256->bits[1] = 0; +} + +#define GET_UINT32(n,b,i) G_STMT_START{ \ + (n) = ((guint32) (b)[(i) ] << 24) \ + | ((guint32) (b)[(i) + 1] << 16) \ + | ((guint32) (b)[(i) + 2] << 8) \ + | ((guint32) (b)[(i) + 3] ); } G_STMT_END + +#define PUT_UINT32(n,b,i) G_STMT_START{ \ + (b)[(i) ] = (guint8) ((n) >> 24); \ + (b)[(i) + 1] = (guint8) ((n) >> 16); \ + (b)[(i) + 2] = (guint8) ((n) >> 8); \ + (b)[(i) + 3] = (guint8) ((n) ); } G_STMT_END + +static void +sha256_transform (guint32 buf[8], + guint8 const data[64]) +{ + guint32 temp1, temp2, W[64]; + guint32 A, B, C, D, E, F, G, H; + + GET_UINT32 (W[0], data, 0); + GET_UINT32 (W[1], data, 4); + GET_UINT32 (W[2], data, 8); + GET_UINT32 (W[3], data, 12); + GET_UINT32 (W[4], data, 16); + GET_UINT32 (W[5], data, 20); + GET_UINT32 (W[6], data, 24); + GET_UINT32 (W[7], data, 28); + GET_UINT32 (W[8], data, 32); + GET_UINT32 (W[9], data, 36); + GET_UINT32 (W[10], data, 40); + GET_UINT32 (W[11], data, 44); + GET_UINT32 (W[12], data, 48); + GET_UINT32 (W[13], data, 52); + GET_UINT32 (W[14], data, 56); + GET_UINT32 (W[15], data, 60); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR (x,n) | (x << (32 - n))) + +#define S0(x) (ROTR (x, 7) ^ ROTR (x,18) ^ SHR (x, 3)) +#define S1(x) (ROTR (x,17) ^ ROTR (x,19) ^ SHR (x,10)) +#define S2(x) (ROTR (x, 2) ^ ROTR (x,13) ^ ROTR (x,22)) +#define S3(x) (ROTR (x, 6) ^ ROTR (x,11) ^ ROTR (x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) (W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16]) + +#define P(a,b,c,d,e,f,g,h,x,K) G_STMT_START { \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; } G_STMT_END + + A = buf[0]; + B = buf[1]; + C = buf[2]; + D = buf[3]; + E = buf[4]; + F = buf[5]; + G = buf[6]; + H = buf[7]; + + P (A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); + P (H, A, B, C, D, E, F, G, W[ 1], 0x71374491); + P (G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF); + P (F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5); + P (E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B); + P (D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1); + P (C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4); + P (B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5); + P (A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98); + P (H, A, B, C, D, E, F, G, W[ 9], 0x12835B01); + P (G, H, A, B, C, D, E, F, W[10], 0x243185BE); + P (F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); + P (E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); + P (D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); + P (C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); + P (B, C, D, E, F, G, H, A, W[15], 0xC19BF174); + P (A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); + P (H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); + P (G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); + P (F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); + P (E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); + P (D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); + P (C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); + P (B, C, D, E, F, G, H, A, R(23), 0x76F988DA); + P (A, B, C, D, E, F, G, H, R(24), 0x983E5152); + P (H, A, B, C, D, E, F, G, R(25), 0xA831C66D); + P (G, H, A, B, C, D, E, F, R(26), 0xB00327C8); + P (F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); + P (E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); + P (D, E, F, G, H, A, B, C, R(29), 0xD5A79147); + P (C, D, E, F, G, H, A, B, R(30), 0x06CA6351); + P (B, C, D, E, F, G, H, A, R(31), 0x14292967); + P (A, B, C, D, E, F, G, H, R(32), 0x27B70A85); + P (H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); + P (G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); + P (F, G, H, A, B, C, D, E, R(35), 0x53380D13); + P (E, F, G, H, A, B, C, D, R(36), 0x650A7354); + P (D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); + P (C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); + P (B, C, D, E, F, G, H, A, R(39), 0x92722C85); + P (A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); + P (H, A, B, C, D, E, F, G, R(41), 0xA81A664B); + P (G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); + P (F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); + P (E, F, G, H, A, B, C, D, R(44), 0xD192E819); + P (D, E, F, G, H, A, B, C, R(45), 0xD6990624); + P (C, D, E, F, G, H, A, B, R(46), 0xF40E3585); + P (B, C, D, E, F, G, H, A, R(47), 0x106AA070); + P (A, B, C, D, E, F, G, H, R(48), 0x19A4C116); + P (H, A, B, C, D, E, F, G, R(49), 0x1E376C08); + P (G, H, A, B, C, D, E, F, R(50), 0x2748774C); + P (F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); + P (E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); + P (D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); + P (C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); + P (B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); + P (A, B, C, D, E, F, G, H, R(56), 0x748F82EE); + P (H, A, B, C, D, E, F, G, R(57), 0x78A5636F); + P (G, H, A, B, C, D, E, F, R(58), 0x84C87814); + P (F, G, H, A, B, C, D, E, R(59), 0x8CC70208); + P (E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); + P (D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); + P (C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); + P (B, C, D, E, F, G, H, A, R(63), 0xC67178F2); + +#undef SHR +#undef ROTR +#undef S0 +#undef S1 +#undef S2 +#undef S3 +#undef F0 +#undef F1 +#undef R +#undef P + + buf[0] += A; + buf[1] += B; + buf[2] += C; + buf[3] += D; + buf[4] += E; + buf[5] += F; + buf[6] += G; + buf[7] += H; +} + +static void +sha256_sum_update (Sha256sum *sha256, + const guchar *buffer, + gsize length) +{ + guint32 left, fill; + const guint8 *input = buffer; + + if (length == 0) + return; + + left = sha256->bits[0] & 0x3F; + fill = 64 - left; + + sha256->bits[0] += length; + sha256->bits[0] &= 0xFFFFFFFF; + + if (sha256->bits[0] < length) + sha256->bits[1]++; + + if (left > 0 && length >= fill) + { + memcpy ((sha256->data + left), input, fill); + + sha256_transform (sha256->buf, sha256->data); + length -= fill; + input += fill; + + left = 0; + } + + while (length >= SHA256_DATASIZE) + { + sha256_transform (sha256->buf, input); + + length -= 64; + input += 64; + } + + if (length) + memcpy (sha256->data + left, input, length); +} + +static guint8 sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void +sha256_sum_close (Sha256sum *sha256) +{ + guint32 last, padn; + guint32 high, low; + guint8 msglen[8]; + + high = (sha256->bits[0] >> 29) + | (sha256->bits[1] << 3); + low = (sha256->bits[0] << 3); + + PUT_UINT32 (high, msglen, 0); + PUT_UINT32 (low, msglen, 4); + + last = sha256->bits[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + sha256_sum_update (sha256, sha256_padding, padn); + sha256_sum_update (sha256, msglen, 8); + + PUT_UINT32 (sha256->buf[0], sha256->digest, 0); + PUT_UINT32 (sha256->buf[1], sha256->digest, 4); + PUT_UINT32 (sha256->buf[2], sha256->digest, 8); + PUT_UINT32 (sha256->buf[3], sha256->digest, 12); + PUT_UINT32 (sha256->buf[4], sha256->digest, 16); + PUT_UINT32 (sha256->buf[5], sha256->digest, 20); + PUT_UINT32 (sha256->buf[6], sha256->digest, 24); + PUT_UINT32 (sha256->buf[7], sha256->digest, 28); +} + +#undef PUT_UINT32 +#undef GET_UINT32 + +static gchar * +sha256_sum_to_string (Sha256sum *sha256) +{ + return digest_to_string (sha256->digest, SHA256_DIGEST_LEN); +} + +static void +sha256_sum_digest (Sha256sum *sha256, + guint8 *digest) +{ + gint i; + + for (i = 0; i < SHA256_DIGEST_LEN; i++) + digest[i] = sha256->digest[i]; +} + +/* + * SHA-384, SHA-512, SHA-512/224 and SHA-512/256 Checksums + * + * Implemented following FIPS-180-4 standard at + * http://csrc.nist.gov/publications/fips/fips180-4/fips180-4.pdf. + * References in the form [§x.y.z] map to sections in that document. + * + * Author(s): Eduardo Lima Mitev + * Igor Gnatenko + */ + +/* SHA-384, SHA-512, SHA-512/224 and SHA-512/256 functions [§4.1.3] */ +#define Ch(x,y,z) ((x & y) ^ (~x & z)) +#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) +#define SHR(n,x) (x >> n) +#define ROTR(n,x) (SHR (n, x) | (x << (64 - n))) +#define SIGMA0(x) (ROTR (28, x) ^ ROTR (34, x) ^ ROTR (39, x)) +#define SIGMA1(x) (ROTR (14, x) ^ ROTR (18, x) ^ ROTR (41, x)) +#define sigma0(x) (ROTR ( 1, x) ^ ROTR ( 8, x) ^ SHR ( 7, x)) +#define sigma1(x) (ROTR (19, x) ^ ROTR (61, x) ^ SHR ( 6, x)) + +#define PUT_UINT64(n,b,i) G_STMT_START{ \ + (b)[(i) ] = (guint8) (n >> 56); \ + (b)[(i) + 1] = (guint8) (n >> 48); \ + (b)[(i) + 2] = (guint8) (n >> 40); \ + (b)[(i) + 3] = (guint8) (n >> 32); \ + (b)[(i) + 4] = (guint8) (n >> 24); \ + (b)[(i) + 5] = (guint8) (n >> 16); \ + (b)[(i) + 6] = (guint8) (n >> 8); \ + (b)[(i) + 7] = (guint8) (n ); } G_STMT_END + +/* SHA-384 and SHA-512 constants [§4.2.3] */ +static const guint64 SHA2_K[80] = { + G_GUINT64_CONSTANT (0x428a2f98d728ae22), G_GUINT64_CONSTANT (0x7137449123ef65cd), + G_GUINT64_CONSTANT (0xb5c0fbcfec4d3b2f), G_GUINT64_CONSTANT (0xe9b5dba58189dbbc), + G_GUINT64_CONSTANT (0x3956c25bf348b538), G_GUINT64_CONSTANT (0x59f111f1b605d019), + G_GUINT64_CONSTANT (0x923f82a4af194f9b), G_GUINT64_CONSTANT (0xab1c5ed5da6d8118), + G_GUINT64_CONSTANT (0xd807aa98a3030242), G_GUINT64_CONSTANT (0x12835b0145706fbe), + G_GUINT64_CONSTANT (0x243185be4ee4b28c), G_GUINT64_CONSTANT (0x550c7dc3d5ffb4e2), + G_GUINT64_CONSTANT (0x72be5d74f27b896f), G_GUINT64_CONSTANT (0x80deb1fe3b1696b1), + G_GUINT64_CONSTANT (0x9bdc06a725c71235), G_GUINT64_CONSTANT (0xc19bf174cf692694), + G_GUINT64_CONSTANT (0xe49b69c19ef14ad2), G_GUINT64_CONSTANT (0xefbe4786384f25e3), + G_GUINT64_CONSTANT (0x0fc19dc68b8cd5b5), G_GUINT64_CONSTANT (0x240ca1cc77ac9c65), + G_GUINT64_CONSTANT (0x2de92c6f592b0275), G_GUINT64_CONSTANT (0x4a7484aa6ea6e483), + G_GUINT64_CONSTANT (0x5cb0a9dcbd41fbd4), G_GUINT64_CONSTANT (0x76f988da831153b5), + G_GUINT64_CONSTANT (0x983e5152ee66dfab), G_GUINT64_CONSTANT (0xa831c66d2db43210), + G_GUINT64_CONSTANT (0xb00327c898fb213f), G_GUINT64_CONSTANT (0xbf597fc7beef0ee4), + G_GUINT64_CONSTANT (0xc6e00bf33da88fc2), G_GUINT64_CONSTANT (0xd5a79147930aa725), + G_GUINT64_CONSTANT (0x06ca6351e003826f), G_GUINT64_CONSTANT (0x142929670a0e6e70), + G_GUINT64_CONSTANT (0x27b70a8546d22ffc), G_GUINT64_CONSTANT (0x2e1b21385c26c926), + G_GUINT64_CONSTANT (0x4d2c6dfc5ac42aed), G_GUINT64_CONSTANT (0x53380d139d95b3df), + G_GUINT64_CONSTANT (0x650a73548baf63de), G_GUINT64_CONSTANT (0x766a0abb3c77b2a8), + G_GUINT64_CONSTANT (0x81c2c92e47edaee6), G_GUINT64_CONSTANT (0x92722c851482353b), + G_GUINT64_CONSTANT (0xa2bfe8a14cf10364), G_GUINT64_CONSTANT (0xa81a664bbc423001), + G_GUINT64_CONSTANT (0xc24b8b70d0f89791), G_GUINT64_CONSTANT (0xc76c51a30654be30), + G_GUINT64_CONSTANT (0xd192e819d6ef5218), G_GUINT64_CONSTANT (0xd69906245565a910), + G_GUINT64_CONSTANT (0xf40e35855771202a), G_GUINT64_CONSTANT (0x106aa07032bbd1b8), + G_GUINT64_CONSTANT (0x19a4c116b8d2d0c8), G_GUINT64_CONSTANT (0x1e376c085141ab53), + G_GUINT64_CONSTANT (0x2748774cdf8eeb99), G_GUINT64_CONSTANT (0x34b0bcb5e19b48a8), + G_GUINT64_CONSTANT (0x391c0cb3c5c95a63), G_GUINT64_CONSTANT (0x4ed8aa4ae3418acb), + G_GUINT64_CONSTANT (0x5b9cca4f7763e373), G_GUINT64_CONSTANT (0x682e6ff3d6b2b8a3), + G_GUINT64_CONSTANT (0x748f82ee5defb2fc), G_GUINT64_CONSTANT (0x78a5636f43172f60), + G_GUINT64_CONSTANT (0x84c87814a1f0ab72), G_GUINT64_CONSTANT (0x8cc702081a6439ec), + G_GUINT64_CONSTANT (0x90befffa23631e28), G_GUINT64_CONSTANT (0xa4506cebde82bde9), + G_GUINT64_CONSTANT (0xbef9a3f7b2c67915), G_GUINT64_CONSTANT (0xc67178f2e372532b), + G_GUINT64_CONSTANT (0xca273eceea26619c), G_GUINT64_CONSTANT (0xd186b8c721c0c207), + G_GUINT64_CONSTANT (0xeada7dd6cde0eb1e), G_GUINT64_CONSTANT (0xf57d4f7fee6ed178), + G_GUINT64_CONSTANT (0x06f067aa72176fba), G_GUINT64_CONSTANT (0x0a637dc5a2c898a6), + G_GUINT64_CONSTANT (0x113f9804bef90dae), G_GUINT64_CONSTANT (0x1b710b35131c471b), + G_GUINT64_CONSTANT (0x28db77f523047d84), G_GUINT64_CONSTANT (0x32caab7b40c72493), + G_GUINT64_CONSTANT (0x3c9ebe0a15c9bebc), G_GUINT64_CONSTANT (0x431d67c49c100d4c), + G_GUINT64_CONSTANT (0x4cc5d4becb3e42b6), G_GUINT64_CONSTANT (0x597f299cfc657e2a), + G_GUINT64_CONSTANT (0x5fcb6fab3ad6faec), G_GUINT64_CONSTANT (0x6c44198c4a475817) +}; + + +static void +sha384_sum_init (Sha512sum *sha512) +{ + /* Initial Hash Value [§5.3.4] */ + sha512->H[0] = G_GUINT64_CONSTANT (0xcbbb9d5dc1059ed8); + sha512->H[1] = G_GUINT64_CONSTANT (0x629a292a367cd507); + sha512->H[2] = G_GUINT64_CONSTANT (0x9159015a3070dd17); + sha512->H[3] = G_GUINT64_CONSTANT (0x152fecd8f70e5939); + sha512->H[4] = G_GUINT64_CONSTANT (0x67332667ffc00b31); + sha512->H[5] = G_GUINT64_CONSTANT (0x8eb44a8768581511); + sha512->H[6] = G_GUINT64_CONSTANT (0xdb0c2e0d64f98fa7); + sha512->H[7] = G_GUINT64_CONSTANT (0x47b5481dbefa4fa4); + + sha512->block_len = 0; + + sha512->data_len[0] = 0; + sha512->data_len[1] = 0; +} + +static void +sha512_sum_init (Sha512sum *sha512) +{ + /* Initial Hash Value [§5.3.5] */ + sha512->H[0] = G_GUINT64_CONSTANT (0x6a09e667f3bcc908); + sha512->H[1] = G_GUINT64_CONSTANT (0xbb67ae8584caa73b); + sha512->H[2] = G_GUINT64_CONSTANT (0x3c6ef372fe94f82b); + sha512->H[3] = G_GUINT64_CONSTANT (0xa54ff53a5f1d36f1); + sha512->H[4] = G_GUINT64_CONSTANT (0x510e527fade682d1); + sha512->H[5] = G_GUINT64_CONSTANT (0x9b05688c2b3e6c1f); + sha512->H[6] = G_GUINT64_CONSTANT (0x1f83d9abfb41bd6b); + sha512->H[7] = G_GUINT64_CONSTANT (0x5be0cd19137e2179); + + sha512->block_len = 0; + + sha512->data_len[0] = 0; + sha512->data_len[1] = 0; +} + +static void +sha512_transform (guint64 H[8], + guint8 const data[SHA2_BLOCK_LEN]) +{ + gint i; + gint t; + guint64 a, b, c, d, e, f, g, h; + guint64 M[16]; + guint64 W[80]; + + /* SHA-512 hash computation [§6.4.2] */ + + /* prepare the message schedule */ + for (i = 0; i < 16; i++) + { + gint p = i * 8; + + M[i] = + ((guint64) data[p + 0] << 56) | + ((guint64) data[p + 1] << 48) | + ((guint64) data[p + 2] << 40) | + ((guint64) data[p + 3] << 32) | + ((guint64) data[p + 4] << 24) | + ((guint64) data[p + 5] << 16) | + ((guint64) data[p + 6] << 8) | + ((guint64) data[p + 7] ); + } + + for (t = 0; t < 80; t++) + if (t < 16) + W[t] = M[t]; + else + W[t] = sigma1 (W[t - 2]) + W[t - 7] + sigma0 (W[t - 15]) + W[t - 16]; + + /* initialize the eight working variables */ + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; + + for (t = 0; t < 80; t++) + { + guint64 T1, T2; + + T1 = h + SIGMA1 (e) + Ch (e, f, g) + SHA2_K[t] + W[t]; + T2 = SIGMA0 (a) + Maj (a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + /* Compute the intermediate hash value H */ + H[0] += a; + H[1] += b; + H[2] += c; + H[3] += d; + H[4] += e; + H[5] += f; + H[6] += g; + H[7] += h; +} + +static void +sha512_sum_update (Sha512sum *sha512, + const guchar *buffer, + gsize length) +{ + gsize block_left, offset = 0; + + if (length == 0) + return; + + sha512->data_len[0] += length * 8; + if (sha512->data_len[0] < length) + sha512->data_len[1]++; + + /* try to fill current block */ + block_left = SHA2_BLOCK_LEN - sha512->block_len; + if (block_left > 0) + { + gsize fill_len; + + fill_len = MIN (block_left, length); + memcpy (sha512->block + sha512->block_len, buffer, fill_len); + sha512->block_len += fill_len; + length -= fill_len; + offset += fill_len; + + if (sha512->block_len == SHA2_BLOCK_LEN) + { + sha512_transform (sha512->H, sha512->block); + sha512->block_len = 0; + } + } + + /* process complete blocks */ + while (length >= SHA2_BLOCK_LEN) + { + memcpy (sha512->block, buffer + offset, SHA2_BLOCK_LEN); + + sha512_transform (sha512->H, sha512->block); + + length -= SHA2_BLOCK_LEN; + offset += SHA2_BLOCK_LEN; + } + + /* keep remaining data for next block */ + if (length > 0) + { + memcpy (sha512->block, buffer + offset, length); + sha512->block_len = length; + } +} + +static void +sha512_sum_close (Sha512sum *sha512) +{ + guint l; + gint zeros; + guint8 pad[SHA2_BLOCK_LEN * 2] = { 0, }; + guint pad_len = 0; + gint i; + + /* apply padding [§5.1.2] */ + l = sha512->block_len * 8; + zeros = 896 - (l + 1); + + if (zeros < 0) + zeros += 128 * 8; + + pad[0] = 0x80; /* 1000 0000 */ + zeros -= 7; + pad_len++; + + memset (pad + pad_len, 0x00, zeros / 8); + pad_len += zeros / 8; + zeros = zeros % 8; + (void) zeros; /* don’t care about the dead store */ + + /* put message bit length at the end of padding */ + PUT_UINT64 (sha512->data_len[1], pad, pad_len); + pad_len += 8; + + PUT_UINT64 (sha512->data_len[0], pad, pad_len); + pad_len += 8; + + /* update checksum with the padded block */ + sha512_sum_update (sha512, pad, pad_len); + + /* copy resulting 64-bit words into digest */ + for (i = 0; i < 8; i++) + PUT_UINT64 (sha512->H[i], sha512->digest, i * 8); +} + +static gchar * +sha384_sum_to_string (Sha512sum *sha512) +{ + return digest_to_string (sha512->digest, SHA384_DIGEST_LEN); +} + +static gchar * +sha512_sum_to_string (Sha512sum *sha512) +{ + return digest_to_string (sha512->digest, SHA512_DIGEST_LEN); +} + +static void +sha384_sum_digest (Sha512sum *sha512, + guint8 *digest) +{ + memcpy (digest, sha512->digest, SHA384_DIGEST_LEN); +} + +static void +sha512_sum_digest (Sha512sum *sha512, + guint8 *digest) +{ + memcpy (digest, sha512->digest, SHA512_DIGEST_LEN); +} + +#undef Ch +#undef Maj +#undef SHR +#undef ROTR +#undef SIGMA0 +#undef SIGMA1 +#undef sigma0 +#undef sigma1 + +#undef PUT_UINT64 + +/* + * Public API + */ + +/** + * g_checksum_type_get_length: + * @checksum_type: a #GChecksumType + * + * Gets the length in bytes of digests of type @checksum_type + * + * Returns: the checksum length, or -1 if @checksum_type is + * not supported. + * + * Since: 2.16 + */ +gssize +g_checksum_type_get_length (GChecksumType checksum_type) +{ + gssize len = -1; + + switch (checksum_type) + { + case G_CHECKSUM_MD5: + len = MD5_DIGEST_LEN; + break; + case G_CHECKSUM_SHA1: + len = SHA1_DIGEST_LEN; + break; + case G_CHECKSUM_SHA256: + len = SHA256_DIGEST_LEN; + break; + case G_CHECKSUM_SHA384: + len = SHA384_DIGEST_LEN; + break; + case G_CHECKSUM_SHA512: + len = SHA512_DIGEST_LEN; + break; + default: + len = -1; + break; + } + + return len; +} + +/** + * g_checksum_new: + * @checksum_type: the desired type of checksum + * + * Creates a new #GChecksum, using the checksum algorithm @checksum_type. + * If the @checksum_type is not known, %NULL is returned. + * A #GChecksum can be used to compute the checksum, or digest, of an + * arbitrary binary blob, using different hashing algorithms. + * + * A #GChecksum works by feeding a binary blob through g_checksum_update() + * until there is data to be checked; the digest can then be extracted + * using g_checksum_get_string(), which will return the checksum as a + * hexadecimal string; or g_checksum_get_digest(), which will return a + * vector of raw bytes. Once either g_checksum_get_string() or + * g_checksum_get_digest() have been called on a #GChecksum, the checksum + * will be closed and it won't be possible to call g_checksum_update() + * on it anymore. + * + * Returns: (transfer full) (nullable): the newly created #GChecksum, or %NULL. + * Use g_checksum_free() to free the memory allocated by it. + * + * Since: 2.16 + */ +GChecksum * +g_checksum_new (GChecksumType checksum_type) +{ + GChecksum *checksum; + + if (! IS_VALID_TYPE (checksum_type)) + return NULL; + + checksum = g_slice_new0 (GChecksum); + checksum->type = checksum_type; + + g_checksum_reset (checksum); + + return checksum; +} + +/** + * g_checksum_reset: + * @checksum: the #GChecksum to reset + * + * Resets the state of the @checksum back to its initial state. + * + * Since: 2.18 + **/ +void +g_checksum_reset (GChecksum *checksum) +{ + g_return_if_fail (checksum != NULL); + + g_free (checksum->digest_str); + checksum->digest_str = NULL; + + switch (checksum->type) + { + case G_CHECKSUM_MD5: + md5_sum_init (&(checksum->sum.md5)); + break; + case G_CHECKSUM_SHA1: + sha1_sum_init (&(checksum->sum.sha1)); + break; + case G_CHECKSUM_SHA256: + sha256_sum_init (&(checksum->sum.sha256)); + break; + case G_CHECKSUM_SHA384: + sha384_sum_init (&(checksum->sum.sha512)); + break; + case G_CHECKSUM_SHA512: + sha512_sum_init (&(checksum->sum.sha512)); + break; + default: + g_assert_not_reached (); + break; + } +} + +/** + * g_checksum_copy: + * @checksum: the #GChecksum to copy + * + * Copies a #GChecksum. If @checksum has been closed, by calling + * g_checksum_get_string() or g_checksum_get_digest(), the copied + * checksum will be closed as well. + * + * Returns: (transfer full): the copy of the passed #GChecksum. Use + * g_checksum_free() when finished using it. + * + * Since: 2.16 + */ +GChecksum * +g_checksum_copy (const GChecksum *checksum) +{ + GChecksum *copy; + + g_return_val_if_fail (checksum != NULL, NULL); + + copy = g_slice_new (GChecksum); + *copy = *checksum; + + copy->digest_str = g_strdup (checksum->digest_str); + + return copy; +} + +/** + * g_checksum_free: + * @checksum: a #GChecksum + * + * Frees the memory allocated for @checksum. + * + * Since: 2.16 + */ +void +g_checksum_free (GChecksum *checksum) +{ + if (G_LIKELY (checksum)) + { + g_free (checksum->digest_str); + + g_slice_free (GChecksum, checksum); + } +} + +/** + * g_checksum_update: + * @checksum: a #GChecksum + * @data: (array length=length) (element-type guint8): buffer used to compute the checksum + * @length: size of the buffer, or -1 if it is a null-terminated string. + * + * Feeds @data into an existing #GChecksum. The checksum must still be + * open, that is g_checksum_get_string() or g_checksum_get_digest() must + * not have been called on @checksum. + * + * Since: 2.16 + */ +void +g_checksum_update (GChecksum *checksum, + const guchar *data, + gssize length) +{ + g_return_if_fail (checksum != NULL); + g_return_if_fail (length == 0 || data != NULL); + + if (length < 0) + length = strlen ((const gchar *) data); + + if (checksum->digest_str) + { + g_warning ("The checksum '%s' has been closed and cannot be updated " + "anymore.", + checksum->digest_str); + return; + } + + switch (checksum->type) + { + case G_CHECKSUM_MD5: + md5_sum_update (&(checksum->sum.md5), data, length); + break; + case G_CHECKSUM_SHA1: + sha1_sum_update (&(checksum->sum.sha1), data, length); + break; + case G_CHECKSUM_SHA256: + sha256_sum_update (&(checksum->sum.sha256), data, length); + break; + case G_CHECKSUM_SHA384: + case G_CHECKSUM_SHA512: + sha512_sum_update (&(checksum->sum.sha512), data, length); + break; + default: + g_assert_not_reached (); + break; + } +} + +/** + * g_checksum_get_string: + * @checksum: a #GChecksum + * + * Gets the digest as a hexadecimal string. + * + * Once this function has been called the #GChecksum can no longer be + * updated with g_checksum_update(). + * + * The hexadecimal characters will be lower case. + * + * Returns: the hexadecimal representation of the checksum. The + * returned string is owned by the checksum and should not be modified + * or freed. + * + * Since: 2.16 + */ +const gchar * +g_checksum_get_string (GChecksum *checksum) +{ + gchar *str = NULL; + + g_return_val_if_fail (checksum != NULL, NULL); + + if (checksum->digest_str) + return checksum->digest_str; + + switch (checksum->type) + { + case G_CHECKSUM_MD5: + md5_sum_close (&(checksum->sum.md5)); + str = md5_sum_to_string (&(checksum->sum.md5)); + break; + case G_CHECKSUM_SHA1: + sha1_sum_close (&(checksum->sum.sha1)); + str = sha1_sum_to_string (&(checksum->sum.sha1)); + break; + case G_CHECKSUM_SHA256: + sha256_sum_close (&(checksum->sum.sha256)); + str = sha256_sum_to_string (&(checksum->sum.sha256)); + break; + case G_CHECKSUM_SHA384: + sha512_sum_close (&(checksum->sum.sha512)); + str = sha384_sum_to_string (&(checksum->sum.sha512)); + break; + case G_CHECKSUM_SHA512: + sha512_sum_close (&(checksum->sum.sha512)); + str = sha512_sum_to_string (&(checksum->sum.sha512)); + break; + default: + g_assert_not_reached (); + break; + } + + checksum->digest_str = str; + + return checksum->digest_str; +} + +/** + * g_checksum_get_digest: (skip) + * @checksum: a #GChecksum + * @buffer: (array length=digest_len): output buffer + * @digest_len: (inout): an inout parameter. The caller initializes it to the size of @buffer. + * After the call it contains the length of the digest. + * + * Gets the digest from @checksum as a raw binary vector and places it + * into @buffer. The size of the digest depends on the type of checksum. + * + * Once this function has been called, the #GChecksum is closed and can + * no longer be updated with g_checksum_update(). + * + * Since: 2.16 + */ +void +g_checksum_get_digest (GChecksum *checksum, + guint8 *buffer, + gsize *digest_len) +{ + gboolean checksum_open = FALSE; + gchar *str = NULL; + gsize len; + + g_return_if_fail (checksum != NULL); + + len = g_checksum_type_get_length (checksum->type); + g_return_if_fail (*digest_len >= len); + + checksum_open = !!(checksum->digest_str == NULL); + + switch (checksum->type) + { + case G_CHECKSUM_MD5: + if (checksum_open) + { + md5_sum_close (&(checksum->sum.md5)); + str = md5_sum_to_string (&(checksum->sum.md5)); + } + md5_sum_digest (&(checksum->sum.md5), buffer); + break; + case G_CHECKSUM_SHA1: + if (checksum_open) + { + sha1_sum_close (&(checksum->sum.sha1)); + str = sha1_sum_to_string (&(checksum->sum.sha1)); + } + sha1_sum_digest (&(checksum->sum.sha1), buffer); + break; + case G_CHECKSUM_SHA256: + if (checksum_open) + { + sha256_sum_close (&(checksum->sum.sha256)); + str = sha256_sum_to_string (&(checksum->sum.sha256)); + } + sha256_sum_digest (&(checksum->sum.sha256), buffer); + break; + case G_CHECKSUM_SHA384: + if (checksum_open) + { + sha512_sum_close (&(checksum->sum.sha512)); + str = sha384_sum_to_string (&(checksum->sum.sha512)); + } + sha384_sum_digest (&(checksum->sum.sha512), buffer); + break; + case G_CHECKSUM_SHA512: + if (checksum_open) + { + sha512_sum_close (&(checksum->sum.sha512)); + str = sha512_sum_to_string (&(checksum->sum.sha512)); + } + sha512_sum_digest (&(checksum->sum.sha512), buffer); + break; + default: + g_assert_not_reached (); + break; + } + + if (str) + checksum->digest_str = str; + + *digest_len = len; +} + +/** + * g_compute_checksum_for_data: + * @checksum_type: a #GChecksumType + * @data: (array length=length) (element-type guint8): binary blob to compute the digest of + * @length: length of @data + * + * Computes the checksum for a binary @data of @length. This is a + * convenience wrapper for g_checksum_new(), g_checksum_get_string() + * and g_checksum_free(). + * + * The hexadecimal string returned will be in lower case. + * + * Returns: (transfer full) (nullable): the digest of the binary data as a + * string in hexadecimal, or %NULL if g_checksum_new() fails for + * @checksum_type. The returned string should be freed with g_free() when + * done using it. + * + * Since: 2.16 + */ +gchar * +g_compute_checksum_for_data (GChecksumType checksum_type, + const guchar *data, + gsize length) +{ + GChecksum *checksum; + gchar *retval; + + g_return_val_if_fail (length == 0 || data != NULL, NULL); + + checksum = g_checksum_new (checksum_type); + if (!checksum) + return NULL; + + g_checksum_update (checksum, data, length); + retval = g_strdup (g_checksum_get_string (checksum)); + g_checksum_free (checksum); + + return retval; +} + +/** + * g_compute_checksum_for_string: + * @checksum_type: a #GChecksumType + * @str: the string to compute the checksum of + * @length: the length of the string, or -1 if the string is null-terminated. + * + * Computes the checksum of a string. + * + * The hexadecimal string returned will be in lower case. + * + * Returns: (transfer full) (nullable): the checksum as a hexadecimal string, + * or %NULL if g_checksum_new() fails for @checksum_type. The returned string + * should be freed with g_free() when done using it. + * + * Since: 2.16 + */ +gchar * +g_compute_checksum_for_string (GChecksumType checksum_type, + const gchar *str, + gssize length) +{ + g_return_val_if_fail (length == 0 || str != NULL, NULL); + + if (length < 0) + length = strlen (str); + + return g_compute_checksum_for_data (checksum_type, (const guchar *) str, length); +} + +/** + * g_compute_checksum_for_bytes: + * @checksum_type: a #GChecksumType + * @data: binary blob to compute the digest of + * + * Computes the checksum for a binary @data. This is a + * convenience wrapper for g_checksum_new(), g_checksum_get_string() + * and g_checksum_free(). + * + * The hexadecimal string returned will be in lower case. + * + * Returns: (transfer full) (nullable): the digest of the binary data as a + * string in hexadecimal, or %NULL if g_checksum_new() fails for + * @checksum_type. The returned string should be freed with g_free() when + * done using it. + * + * Since: 2.34 + */ +gchar * +g_compute_checksum_for_bytes (GChecksumType checksum_type, + GBytes *data) +{ + gconstpointer byte_data; + gsize length; + + g_return_val_if_fail (data != NULL, NULL); + + byte_data = g_bytes_get_data (data, &length); + return g_compute_checksum_for_data (checksum_type, byte_data, length); +} diff --git a/glib/gchecksum.h b/glib/gchecksum.h new file mode 100644 index 0000000..5bb52d8 --- /dev/null +++ b/glib/gchecksum.h @@ -0,0 +1,104 @@ +/* gchecksum.h - data hashing functions + * + * Copyright (C) 2007 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef __G_CHECKSUM_H__ +#define __G_CHECKSUM_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +/** + * GChecksumType: + * @G_CHECKSUM_MD5: Use the MD5 hashing algorithm + * @G_CHECKSUM_SHA1: Use the SHA-1 hashing algorithm + * @G_CHECKSUM_SHA256: Use the SHA-256 hashing algorithm + * @G_CHECKSUM_SHA384: Use the SHA-384 hashing algorithm (Since: 2.51) + * @G_CHECKSUM_SHA512: Use the SHA-512 hashing algorithm (Since: 2.36) + * + * The hashing algorithm to be used by #GChecksum when performing the + * digest of some data. + * + * Note that the #GChecksumType enumeration may be extended at a later + * date to include new hashing algorithm types. + * + * Since: 2.16 + */ +typedef enum { + G_CHECKSUM_MD5, + G_CHECKSUM_SHA1, + G_CHECKSUM_SHA256, + G_CHECKSUM_SHA512, + G_CHECKSUM_SHA384 +} GChecksumType; + +/** + * GChecksum: + * + * An opaque structure representing a checksumming operation. + * + * To create a new GChecksum, use g_checksum_new(). To free + * a GChecksum, use g_checksum_free(). + * + * Since: 2.16 + */ +typedef struct _GChecksum GChecksum; + +GLIB_AVAILABLE_IN_ALL +gssize g_checksum_type_get_length (GChecksumType checksum_type); + +GLIB_AVAILABLE_IN_ALL +GChecksum * g_checksum_new (GChecksumType checksum_type); +GLIB_AVAILABLE_IN_ALL +void g_checksum_reset (GChecksum *checksum); +GLIB_AVAILABLE_IN_ALL +GChecksum * g_checksum_copy (const GChecksum *checksum); +GLIB_AVAILABLE_IN_ALL +void g_checksum_free (GChecksum *checksum); +GLIB_AVAILABLE_IN_ALL +void g_checksum_update (GChecksum *checksum, + const guchar *data, + gssize length); +GLIB_AVAILABLE_IN_ALL +const gchar * g_checksum_get_string (GChecksum *checksum); +GLIB_AVAILABLE_IN_ALL +void g_checksum_get_digest (GChecksum *checksum, + guint8 *buffer, + gsize *digest_len); + +GLIB_AVAILABLE_IN_ALL +gchar *g_compute_checksum_for_data (GChecksumType checksum_type, + const guchar *data, + gsize length); +GLIB_AVAILABLE_IN_ALL +gchar *g_compute_checksum_for_string (GChecksumType checksum_type, + const gchar *str, + gssize length); + +GLIB_AVAILABLE_IN_2_34 +gchar *g_compute_checksum_for_bytes (GChecksumType checksum_type, + GBytes *data); + +G_END_DECLS + +#endif /* __G_CHECKSUM_H__ */ diff --git a/glib/gconstructor.h b/glib/gconstructor.h new file mode 100644 index 0000000..c5e0dfa --- /dev/null +++ b/glib/gconstructor.h @@ -0,0 +1,159 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_CONSTRUCTOR_H__ +#define __G_CONSTRUCTOR_H__ + +/* + If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and + destructors, in a usable way, including e.g. on library unload. If not you're on + your own. + + Some compilers need #pragma to handle this, which does not work with macros, + so the way you need to use this is (for constructors): + + #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA + #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor) + #endif + G_DEFINE_CONSTRUCTOR(my_constructor) + static void my_constructor(void) { + ... + } + +*/ + +#ifndef __GTK_DOC_IGNORE__ + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) + +#define G_HAS_CONSTRUCTORS 1 + +#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void); +#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void); + +#elif defined (_MSC_VER) && (_MSC_VER >= 1500) +/* Visual studio 2008 and later has _Pragma */ + +/* + * Only try to include gslist.h if not already included via glib.h, + * so that items using gconstructor.h outside of GLib (such as + * GResources) continue to build properly. + */ +#ifndef __G_LIB_H__ +#include "gslist.h" +#endif + +#include + +#define G_HAS_CONSTRUCTORS 1 + +/* We do some weird things to avoid the constructors being optimized + * away on VS2015 if WholeProgramOptimization is enabled. First we + * make a reference to the array from the wrapper to make sure its + * references. Then we use a pragma to make sure the wrapper function + * symbol is always included at the link stage. Also, the symbols + * need to be extern (but not dllexport), even though they are not + * really used from another object file. + */ + +/* We need to account for differences between the mangling of symbols + * for x86 and x64/ARM/ARM64 programs, as symbols on x86 are prefixed + * with an underscore but symbols on x64/ARM/ARM64 are not. + */ +#ifdef _M_IX86 +#define G_MSVC_SYMBOL_PREFIX "_" +#else +#define G_MSVC_SYMBOL_PREFIX "" +#endif + +#define G_DEFINE_CONSTRUCTOR(_func) G_MSVC_CTOR (_func, G_MSVC_SYMBOL_PREFIX) +#define G_DEFINE_DESTRUCTOR(_func) G_MSVC_DTOR (_func, G_MSVC_SYMBOL_PREFIX) + +#define G_MSVC_CTOR(_func,_sym_prefix) \ + static void _func(void); \ + extern int (* _array ## _func)(void); \ + int _func ## _wrapper(void) { _func(); g_slist_find (NULL, _array ## _func); return 0; } \ + __pragma(comment(linker,"/include:" _sym_prefix # _func "_wrapper")) \ + __pragma(section(".CRT$XCU",read)) \ + __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _wrapper; + +#define G_MSVC_DTOR(_func,_sym_prefix) \ + static void _func(void); \ + extern int (* _array ## _func)(void); \ + int _func ## _constructor(void) { atexit (_func); g_slist_find (NULL, _array ## _func); return 0; } \ + __pragma(comment(linker,"/include:" _sym_prefix # _func "_constructor")) \ + __pragma(section(".CRT$XCU",read)) \ + __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _constructor; + +#elif defined (_MSC_VER) + +#define G_HAS_CONSTRUCTORS 1 + +/* Pre Visual studio 2008 must use #pragma section */ +#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 +#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 + +#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ + section(".CRT$XCU",read) +#define G_DEFINE_CONSTRUCTOR(_func) \ + static void _func(void); \ + static int _func ## _wrapper(void) { _func(); return 0; } \ + __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper; + +#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ + section(".CRT$XCU",read) +#define G_DEFINE_DESTRUCTOR(_func) \ + static void _func(void); \ + static int _func ## _constructor(void) { atexit (_func); return 0; } \ + __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor; + +#elif defined(__SUNPRO_C) + +/* This is not tested, but i believe it should work, based on: + * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c + */ + +#define G_HAS_CONSTRUCTORS 1 + +#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 +#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 + +#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ + init(_func) +#define G_DEFINE_CONSTRUCTOR(_func) \ + static void _func(void); + +#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ + fini(_func) +#define G_DEFINE_DESTRUCTOR(_func) \ + static void _func(void); + +#else + +/* constructors not supported for this compiler */ + +#endif + +#endif /* __GTK_DOC_IGNORE__ */ +#endif /* __G_CONSTRUCTOR_H__ */ diff --git a/glib/gconvert.c b/glib/gconvert.c new file mode 100644 index 0000000..052f019 --- /dev/null +++ b/glib/gconvert.c @@ -0,0 +1,2066 @@ +/* GLIB - Library of useful routines for C programming + * + * gconvert.c: Convert between character sets using iconv + * Copyright Red Hat Inc., 2000 + * Authors: Havoc Pennington , Owen Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" +#include "glibconfig.h" + +#ifndef G_OS_WIN32 +#include +#endif +#include +#include +#include +#include + +#ifdef G_OS_WIN32 +#include "win_iconv.c" +#endif + +#ifdef G_PLATFORM_WIN32 +#define STRICT +#include +#undef STRICT +#endif + +#include "gconvert.h" +#include "gconvertprivate.h" + +#include "gcharsetprivate.h" +#include "gslist.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gthread.h" +#include "gthreadprivate.h" +#include "gunicode.h" +#include "gfileutils.h" +#include "genviron.h" + +#include "glibintl.h" + + +/** + * SECTION:conversions + * @title: Character Set Conversion + * @short_description: convert strings between different character sets + * + * The g_convert() family of function wraps the functionality of iconv(). + * In addition to pure character set conversions, GLib has functions to + * deal with the extra complications of encodings for file names. + * + * ## File Name Encodings + * + * Historically, UNIX has not had a defined encoding for file names: + * a file name is valid as long as it does not have path separators + * in it ("/"). However, displaying file names may require conversion: + * from the character set in which they were created, to the character + * set in which the application operates. Consider the Spanish file name + * "Presentación.sxi". If the application which created it uses + * ISO-8859-1 for its encoding, + * |[ + * Character: P r e s e n t a c i ó n . s x i + * Hex code: 50 72 65 73 65 6e 74 61 63 69 f3 6e 2e 73 78 69 + * ]| + * However, if the application use UTF-8, the actual file name on + * disk would look like this: + * |[ + * Character: P r e s e n t a c i ó n . s x i + * Hex code: 50 72 65 73 65 6e 74 61 63 69 c3 b3 6e 2e 73 78 69 + * ]| + * Glib uses UTF-8 for its strings, and GUI toolkits like GTK+ that use + * GLib do the same thing. If you get a file name from the file system, + * for example, from readdir() or from g_dir_read_name(), and you wish + * to display the file name to the user, you will need to convert it + * into UTF-8. The opposite case is when the user types the name of a + * file they wish to save: the toolkit will give you that string in + * UTF-8 encoding, and you will need to convert it to the character + * set used for file names before you can create the file with open() + * or fopen(). + * + * By default, GLib assumes that file names on disk are in UTF-8 + * encoding. This is a valid assumption for file systems which + * were created relatively recently: most applications use UTF-8 + * encoding for their strings, and that is also what they use for + * the file names they create. However, older file systems may + * still contain file names created in "older" encodings, such as + * ISO-8859-1. In this case, for compatibility reasons, you may want + * to instruct GLib to use that particular encoding for file names + * rather than UTF-8. You can do this by specifying the encoding for + * file names in the [`G_FILENAME_ENCODING`][G_FILENAME_ENCODING] + * environment variable. For example, if your installation uses + * ISO-8859-1 for file names, you can put this in your `~/.profile`: + * |[ + * export G_FILENAME_ENCODING=ISO-8859-1 + * ]| + * GLib provides the functions g_filename_to_utf8() and + * g_filename_from_utf8() to perform the necessary conversions. + * These functions convert file names from the encoding specified + * in `G_FILENAME_ENCODING` to UTF-8 and vice-versa. This + * [diagram][file-name-encodings-diagram] illustrates how + * these functions are used to convert between UTF-8 and the + * encoding for file names in the file system. + * + * ## Conversion between file name encodings # {#file-name-encodings-diagram) + * + * ![](file-name-encodings.png) + * + * ## Checklist for Application Writers + * + * This section is a practical summary of the detailed + * things to do to make sure your applications process file + * name encodings correctly. + * + * 1. If you get a file name from the file system from a function + * such as readdir() or gtk_file_chooser_get_filename(), you do + * not need to do any conversion to pass that file name to + * functions like open(), rename(), or fopen() -- those are "raw" + * file names which the file system understands. + * + * 2. If you need to display a file name, convert it to UTF-8 first + * by using g_filename_to_utf8(). If conversion fails, display a + * string like "Unknown file name". Do not convert this string back + * into the encoding used for file names if you wish to pass it to + * the file system; use the original file name instead. + * + * For example, the document window of a word processor could display + * "Unknown file name" in its title bar but still let the user save + * the file, as it would keep the raw file name internally. This + * can happen if the user has not set the `G_FILENAME_ENCODING` + * environment variable even though they have files whose names are + * not encoded in UTF-8. + * + * 3. If your user interface lets the user type a file name for saving + * or renaming, convert it to the encoding used for file names in + * the file system by using g_filename_from_utf8(). Pass the converted + * file name to functions like fopen(). If conversion fails, ask the + * user to enter a different file name. This can happen if the user + * types Japanese characters when `G_FILENAME_ENCODING` is set to + * `ISO-8859-1`, for example. + */ + +/* We try to terminate strings in unknown charsets with this many zero bytes + * to ensure that multibyte strings really are nul-terminated when we return + * them from g_convert() and friends. + */ +#define NUL_TERMINATOR_LENGTH 4 + +G_DEFINE_QUARK (g_convert_error, g_convert_error) + +static gboolean +try_conversion (const char *to_codeset, + const char *from_codeset, + iconv_t *cd) +{ + *cd = iconv_open (to_codeset, from_codeset); + + if (*cd == (iconv_t)-1 && errno == EINVAL) + return FALSE; + else + return TRUE; +} + +static gboolean +try_to_aliases (const char **to_aliases, + const char *from_codeset, + iconv_t *cd) +{ + if (to_aliases) + { + const char **p = to_aliases; + while (*p) + { + if (try_conversion (*p, from_codeset, cd)) + return TRUE; + + p++; + } + } + + return FALSE; +} + +/** + * g_iconv_open: (skip) + * @to_codeset: destination codeset + * @from_codeset: source codeset + * + * Same as the standard UNIX routine iconv_open(), but + * may be implemented via libiconv on UNIX flavors that lack + * a native implementation. + * + * GLib provides g_convert() and g_locale_to_utf8() which are likely + * more convenient than the raw iconv wrappers. + * + * Returns: a "conversion descriptor", or (GIConv)-1 if + * opening the converter failed. + **/ +GIConv +g_iconv_open (const gchar *to_codeset, + const gchar *from_codeset) +{ + iconv_t cd; + + if (!try_conversion (to_codeset, from_codeset, &cd)) + { + const char **to_aliases = _g_charset_get_aliases (to_codeset); + const char **from_aliases = _g_charset_get_aliases (from_codeset); + + if (from_aliases) + { + const char **p = from_aliases; + while (*p) + { + if (try_conversion (to_codeset, *p, &cd)) + goto out; + + if (try_to_aliases (to_aliases, *p, &cd)) + goto out; + + p++; + } + } + + if (try_to_aliases (to_aliases, from_codeset, &cd)) + goto out; + } + + out: + return (cd == (iconv_t)-1) ? (GIConv)-1 : (GIConv)cd; +} + +/** + * g_iconv: (skip) + * @converter: conversion descriptor from g_iconv_open() + * @inbuf: bytes to convert + * @inbytes_left: inout parameter, bytes remaining to convert in @inbuf + * @outbuf: converted output bytes + * @outbytes_left: inout parameter, bytes available to fill in @outbuf + * + * Same as the standard UNIX routine iconv(), but + * may be implemented via libiconv on UNIX flavors that lack + * a native implementation. + * + * GLib provides g_convert() and g_locale_to_utf8() which are likely + * more convenient than the raw iconv wrappers. + * + * Note that the behaviour of iconv() for characters which are valid in the + * input character set, but which have no representation in the output character + * set, is implementation defined. This function may return success (with a + * positive number of non-reversible conversions as replacement characters were + * used), or it may return -1 and set an error such as %EILSEQ, in such a + * situation. + * + * Returns: count of non-reversible conversions, or -1 on error + **/ +gsize +g_iconv (GIConv converter, + gchar **inbuf, + gsize *inbytes_left, + gchar **outbuf, + gsize *outbytes_left) +{ + iconv_t cd = (iconv_t)converter; + + return iconv (cd, inbuf, inbytes_left, outbuf, outbytes_left); +} + +/** + * g_iconv_close: (skip) + * @converter: a conversion descriptor from g_iconv_open() + * + * Same as the standard UNIX routine iconv_close(), but + * may be implemented via libiconv on UNIX flavors that lack + * a native implementation. Should be called to clean up + * the conversion descriptor from g_iconv_open() when + * you are done converting things. + * + * GLib provides g_convert() and g_locale_to_utf8() which are likely + * more convenient than the raw iconv wrappers. + * + * Returns: -1 on error, 0 on success + **/ +gint +g_iconv_close (GIConv converter) +{ + iconv_t cd = (iconv_t)converter; + + return iconv_close (cd); +} + +static GIConv +open_converter (const gchar *to_codeset, + const gchar *from_codeset, + GError **error) +{ + GIConv cd; + + cd = g_iconv_open (to_codeset, from_codeset); + + if (cd == (GIConv) -1) + { + /* Something went wrong. */ + if (error) + { + if (errno == EINVAL) + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION, + _("Conversion from character set “%s†to “%s†is not supported"), + from_codeset, to_codeset); + else + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Could not open converter from “%s†to “%sâ€"), + from_codeset, to_codeset); + } + } + + return cd; +} + +static int +close_converter (GIConv cd) +{ + if (cd == (GIConv) -1) + return 0; + + return g_iconv_close (cd); +} + +/** + * g_convert_with_iconv: (skip) + * @str: (array length=len) (element-type guint8): + * the string to convert. + * @len: the length of the string in bytes, or -1 if the string is + * nul-terminated (Note that some encodings may allow nul + * bytes to occur inside strings. In that case, using -1 + * for the @len parameter is unsafe) + * @converter: conversion descriptor from g_iconv_open() + * @bytes_read: (out) (optional): location to store the number of bytes in + * the input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will be the byte offset after the last valid + * input sequence. + * @bytes_written: (out) (optional): the number of bytes stored in + * the output buffer (not including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from one character set to another. + * + * Note that you should use g_iconv() for streaming conversions. + * Despite the fact that @bytes_read can return information about partial + * characters, the g_convert_... functions are not generally suitable + * for streaming. If the underlying converter maintains internal state, + * then this won't be preserved across successive calls to g_convert(), + * g_convert_with_iconv() or g_convert_with_fallback(). (An example of + * this is the GNU C converter for CP1255 which does not emit a base + * character until it knows that the next character is not a mark that + * could combine with the base character.) + * + * Characters which are valid in the input character set, but which have no + * representation in the output character set will result in a + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE error. This is in contrast to the iconv() + * specification, which leaves this behaviour implementation defined. Note that + * this is the same error code as is returned for an invalid byte sequence in + * the input character set. To get defined behaviour for conversion of + * unrepresentable characters, use g_convert_with_fallback(). + * + * Returns: (array length=bytes_written) (element-type guint8) (transfer full): + * If the conversion was successful, a newly allocated buffer + * containing the converted string, which must be freed with + * g_free(). Otherwise %NULL and @error will be set. + **/ +gchar* +g_convert_with_iconv (const gchar *str, + gssize len, + GIConv converter, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + gchar *dest; + gchar *outp; + const gchar *p; + gsize inbytes_remaining; + gsize outbytes_remaining; + gsize err; + gsize outbuf_size; + gboolean have_error = FALSE; + gboolean done = FALSE; + gboolean reset = FALSE; + + g_return_val_if_fail (converter != (GIConv) -1, NULL); + + if (len < 0) + len = strlen (str); + + p = str; + inbytes_remaining = len; + outbuf_size = len + NUL_TERMINATOR_LENGTH; + + outbytes_remaining = outbuf_size - NUL_TERMINATOR_LENGTH; + outp = dest = g_malloc (outbuf_size); + + while (!done && !have_error) + { + if (reset) + err = g_iconv (converter, NULL, &inbytes_remaining, &outp, &outbytes_remaining); + else + err = g_iconv (converter, (char **)&p, &inbytes_remaining, &outp, &outbytes_remaining); + + if (err == (gsize) -1) + { + switch (errno) + { + case EINVAL: + /* Incomplete text, do not report an error */ + done = TRUE; + break; + case E2BIG: + { + gsize used = outp - dest; + + outbuf_size *= 2; + dest = g_realloc (dest, outbuf_size); + + outp = dest + used; + outbytes_remaining = outbuf_size - used - NUL_TERMINATOR_LENGTH; + } + break; + case EILSEQ: + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + have_error = TRUE; + break; + default: + { + int errsv = errno; + + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Error during conversion: %s"), + g_strerror (errsv)); + } + have_error = TRUE; + break; + } + } + else if (err > 0) + { + /* @err gives the number of replacement characters used. */ + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Unrepresentable character in conversion input")); + have_error = TRUE; + } + else + { + if (!reset) + { + /* call g_iconv with NULL inbuf to cleanup shift state */ + reset = TRUE; + inbytes_remaining = 0; + } + else + done = TRUE; + } + } + + memset (outp, 0, NUL_TERMINATOR_LENGTH); + + if (bytes_read) + *bytes_read = p - str; + else + { + if ((p - str) != len) + { + if (!have_error) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + _("Partial character sequence at end of input")); + have_error = TRUE; + } + } + } + + if (bytes_written) + *bytes_written = outp - dest; /* Doesn't include '\0' */ + + if (have_error) + { + g_free (dest); + return NULL; + } + else + return dest; +} + +/** + * g_convert: + * @str: (array length=len) (element-type guint8): + * the string to convert. + * @len: the length of the string in bytes, or -1 if the string is + * nul-terminated (Note that some encodings may allow nul + * bytes to occur inside strings. In that case, using -1 + * for the @len parameter is unsafe) + * @to_codeset: name of character set into which to convert @str + * @from_codeset: character set of @str. + * @bytes_read: (out) (optional): location to store the number of bytes in + * the input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will be the byte offset after the last valid + * input sequence. + * @bytes_written: (out) (optional): the number of bytes stored in + * the output buffer (not including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from one character set to another. + * + * Note that you should use g_iconv() for streaming conversions. + * Despite the fact that @bytes_read can return information about partial + * characters, the g_convert_... functions are not generally suitable + * for streaming. If the underlying converter maintains internal state, + * then this won't be preserved across successive calls to g_convert(), + * g_convert_with_iconv() or g_convert_with_fallback(). (An example of + * this is the GNU C converter for CP1255 which does not emit a base + * character until it knows that the next character is not a mark that + * could combine with the base character.) + * + * Using extensions such as "//TRANSLIT" may not work (or may not work + * well) on many platforms. Consider using g_str_to_ascii() instead. + * + * Returns: (array length=bytes_written) (element-type guint8) (transfer full): + * If the conversion was successful, a newly allocated buffer + * containing the converted string, which must be freed with g_free(). + * Otherwise %NULL and @error will be set. + **/ +gchar* +g_convert (const gchar *str, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + gchar *res; + GIConv cd; + + g_return_val_if_fail (str != NULL, NULL); + g_return_val_if_fail (to_codeset != NULL, NULL); + g_return_val_if_fail (from_codeset != NULL, NULL); + + cd = open_converter (to_codeset, from_codeset, error); + + if (cd == (GIConv) -1) + { + if (bytes_read) + *bytes_read = 0; + + if (bytes_written) + *bytes_written = 0; + + return NULL; + } + + res = g_convert_with_iconv (str, len, cd, + bytes_read, bytes_written, + error); + + close_converter (cd); + + return res; +} + +/** + * g_convert_with_fallback: + * @str: (array length=len) (element-type guint8): + * the string to convert. + * @len: the length of the string in bytes, or -1 if the string is + * nul-terminated (Note that some encodings may allow nul + * bytes to occur inside strings. In that case, using -1 + * for the @len parameter is unsafe) + * @to_codeset: name of character set into which to convert @str + * @from_codeset: character set of @str. + * @fallback: UTF-8 string to use in place of characters not + * present in the target encoding. (The string must be + * representable in the target encoding). + * If %NULL, characters not in the target encoding will + * be represented as Unicode escapes \uxxxx or \Uxxxxyyyy. + * @bytes_read: (out) (optional): location to store the number of bytes in + * the input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. + * @bytes_written: (out) (optional): the number of bytes stored in + * the output buffer (not including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from one character set to another, possibly + * including fallback sequences for characters not representable + * in the output. Note that it is not guaranteed that the specification + * for the fallback sequences in @fallback will be honored. Some + * systems may do an approximate conversion from @from_codeset + * to @to_codeset in their iconv() functions, + * in which case GLib will simply return that approximate conversion. + * + * Note that you should use g_iconv() for streaming conversions. + * Despite the fact that @bytes_read can return information about partial + * characters, the g_convert_... functions are not generally suitable + * for streaming. If the underlying converter maintains internal state, + * then this won't be preserved across successive calls to g_convert(), + * g_convert_with_iconv() or g_convert_with_fallback(). (An example of + * this is the GNU C converter for CP1255 which does not emit a base + * character until it knows that the next character is not a mark that + * could combine with the base character.) + * + * Returns: (array length=bytes_written) (element-type guint8) (transfer full): + * If the conversion was successful, a newly allocated buffer + * containing the converted string, which must be freed with g_free(). + * Otherwise %NULL and @error will be set. + **/ +gchar* +g_convert_with_fallback (const gchar *str, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + const gchar *fallback, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + gchar *utf8; + gchar *dest; + gchar *outp; + const gchar *insert_str = NULL; + const gchar *p; + gsize inbytes_remaining; + const gchar *save_p = NULL; + gsize save_inbytes = 0; + gsize outbytes_remaining; + gsize err; + GIConv cd; + gsize outbuf_size; + gboolean have_error = FALSE; + gboolean done = FALSE; + + GError *local_error = NULL; + + g_return_val_if_fail (str != NULL, NULL); + g_return_val_if_fail (to_codeset != NULL, NULL); + g_return_val_if_fail (from_codeset != NULL, NULL); + + if (len < 0) + len = strlen (str); + + /* Try an exact conversion; we only proceed if this fails + * due to an illegal sequence in the input string. + */ + dest = g_convert (str, len, to_codeset, from_codeset, + bytes_read, bytes_written, &local_error); + if (!local_error) + return dest; + + if (!g_error_matches (local_error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE)) + { + g_propagate_error (error, local_error); + return NULL; + } + else + g_error_free (local_error); + + local_error = NULL; + + /* No go; to proceed, we need a converter from "UTF-8" to + * to_codeset, and the string as UTF-8. + */ + cd = open_converter (to_codeset, "UTF-8", error); + if (cd == (GIConv) -1) + { + if (bytes_read) + *bytes_read = 0; + + if (bytes_written) + *bytes_written = 0; + + return NULL; + } + + utf8 = g_convert (str, len, "UTF-8", from_codeset, + bytes_read, &inbytes_remaining, error); + if (!utf8) + { + close_converter (cd); + if (bytes_written) + *bytes_written = 0; + return NULL; + } + + /* Now the heart of the code. We loop through the UTF-8 string, and + * whenever we hit an offending character, we form fallback, convert + * the fallback to the target codeset, and then go back to + * converting the original string after finishing with the fallback. + * + * The variables save_p and save_inbytes store the input state + * for the original string while we are converting the fallback + */ + p = utf8; + + outbuf_size = len + NUL_TERMINATOR_LENGTH; + outbytes_remaining = outbuf_size - NUL_TERMINATOR_LENGTH; + outp = dest = g_malloc (outbuf_size); + + while (!done && !have_error) + { + gsize inbytes_tmp = inbytes_remaining; + err = g_iconv (cd, (char **)&p, &inbytes_tmp, &outp, &outbytes_remaining); + inbytes_remaining = inbytes_tmp; + + if (err == (gsize) -1) + { + switch (errno) + { + case EINVAL: + g_assert_not_reached(); + break; + case E2BIG: + { + gsize used = outp - dest; + + outbuf_size *= 2; + dest = g_realloc (dest, outbuf_size); + + outp = dest + used; + outbytes_remaining = outbuf_size - used - NUL_TERMINATOR_LENGTH; + + break; + } + case EILSEQ: + if (save_p) + { + /* Error converting fallback string - fatal + */ + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Cannot convert fallback “%s†to codeset “%sâ€"), + insert_str, to_codeset); + have_error = TRUE; + break; + } + else if (p) + { + if (!fallback) + { + gunichar ch = g_utf8_get_char (p); + insert_str = g_strdup_printf (ch < 0x10000 ? "\\u%04x" : "\\U%08x", + ch); + } + else + insert_str = fallback; + + save_p = g_utf8_next_char (p); + save_inbytes = inbytes_remaining - (save_p - p); + p = insert_str; + inbytes_remaining = strlen (p); + break; + } + /* if p is null */ + G_GNUC_FALLTHROUGH; + default: + { + int errsv = errno; + + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Error during conversion: %s"), + g_strerror (errsv)); + } + + have_error = TRUE; + break; + } + } + else + { + if (save_p) + { + if (!fallback) + g_free ((gchar *)insert_str); + p = save_p; + inbytes_remaining = save_inbytes; + save_p = NULL; + } + else if (p) + { + /* call g_iconv with NULL inbuf to cleanup shift state */ + p = NULL; + inbytes_remaining = 0; + } + else + done = TRUE; + } + } + + /* Cleanup + */ + memset (outp, 0, NUL_TERMINATOR_LENGTH); + + close_converter (cd); + + if (bytes_written) + *bytes_written = outp - dest; /* Doesn't include '\0' */ + + g_free (utf8); + + if (have_error) + { + if (save_p && !fallback) + g_free ((gchar *)insert_str); + g_free (dest); + return NULL; + } + else + return dest; +} + +/* + * g_locale_to_utf8 + * + * + */ + +/* + * Validate @string as UTF-8. @len can be negative if @string is + * nul-terminated, or a non-negative value in bytes. If @string ends in an + * incomplete sequence, or contains any illegal sequences or nul codepoints, + * %NULL will be returned and the error set to + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE. + * On success, @bytes_read and @bytes_written, if provided, will be set to + * the number of bytes in @string up to @len or the terminating nul byte. + * On error, @bytes_read will be set to the byte offset after the last valid + * and non-nul UTF-8 sequence in @string, and @bytes_written will be set to 0. + */ +static gchar * +strdup_len (const gchar *string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + gsize real_len; + const gchar *end_valid; + + if (!g_utf8_validate (string, len, &end_valid)) + { + if (bytes_read) + *bytes_read = end_valid - string; + if (bytes_written) + *bytes_written = 0; + + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + return NULL; + } + + real_len = end_valid - string; + + if (bytes_read) + *bytes_read = real_len; + if (bytes_written) + *bytes_written = real_len; + + return g_strndup (string, real_len); +} + +typedef enum +{ + CONVERT_CHECK_NO_NULS_IN_INPUT = 1 << 0, + CONVERT_CHECK_NO_NULS_IN_OUTPUT = 1 << 1 +} ConvertCheckFlags; + +/* + * Convert from @string in the encoding identified by @from_codeset, + * returning a string in the encoding identifed by @to_codeset. + * @len can be negative if @string is nul-terminated, or a non-negative + * value in bytes. Flags defined in #ConvertCheckFlags can be set in @flags + * to check the input, the output, or both, for embedded nul bytes. + * On success, @bytes_read, if provided, will be set to the number of bytes + * in @string up to @len or the terminating nul byte, and @bytes_written, if + * provided, will be set to the number of output bytes written into the + * returned buffer, excluding the terminating nul sequence. + * On error, @bytes_read will be set to the byte offset after the last valid + * sequence in @string, and @bytes_written will be set to 0. + */ +static gchar * +convert_checked (const gchar *string, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + ConvertCheckFlags flags, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + gchar *out; + gsize outbytes; + + if ((flags & CONVERT_CHECK_NO_NULS_IN_INPUT) && len > 0) + { + const gchar *early_nul = memchr (string, '\0', len); + if (early_nul != NULL) + { + if (bytes_read) + *bytes_read = early_nul - string; + if (bytes_written) + *bytes_written = 0; + + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Embedded NUL byte in conversion input")); + return NULL; + } + } + + out = g_convert (string, len, to_codeset, from_codeset, + bytes_read, &outbytes, error); + if (out == NULL) + { + if (bytes_written) + *bytes_written = 0; + return NULL; + } + + if ((flags & CONVERT_CHECK_NO_NULS_IN_OUTPUT) + && memchr (out, '\0', outbytes) != NULL) + { + g_free (out); + if (bytes_written) + *bytes_written = 0; + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_EMBEDDED_NUL, + _("Embedded NUL byte in conversion output")); + return NULL; + } + + if (bytes_written) + *bytes_written = outbytes; + return out; +} + +/** + * g_locale_to_utf8: + * @opsysstring: (array length=len) (element-type guint8): a string in the + * encoding of the current locale. On Windows + * this means the system codepage. + * @len: the length of the string, or -1 if the string is + * nul-terminated (Note that some encodings may allow nul + * bytes to occur inside strings. In that case, using -1 + * for the @len parameter is unsafe) + * @bytes_read: (out) (optional): location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will be the byte offset after the last valid + * input sequence. + * @bytes_written: (out) (optional): the number of bytes stored in the output + * buffer (not including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string which is in the encoding used for strings by + * the C runtime (usually the same as that used by the operating + * system) in the [current locale][setlocale] into a UTF-8 string. + * + * If the source encoding is not UTF-8 and the conversion output contains a + * nul character, the error %G_CONVERT_ERROR_EMBEDDED_NUL is set and the + * function returns %NULL. + * If the source encoding is UTF-8, an embedded nul character is treated with + * the %G_CONVERT_ERROR_ILLEGAL_SEQUENCE error for backward compatibility with + * earlier versions of this library. Use g_convert() to produce output that + * may contain embedded nul characters. + * + * Returns: (type utf8): The converted string, or %NULL on an error. + **/ +gchar * +g_locale_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const char *charset; + + if (g_get_charset (&charset)) + return strdup_len (opsysstring, len, bytes_read, bytes_written, error); + else + return convert_checked (opsysstring, len, "UTF-8", charset, + CONVERT_CHECK_NO_NULS_IN_OUTPUT, + bytes_read, bytes_written, error); +} + +/* + * Do the exact same as g_locale_to_utf8 except that the charset would + * be retrieved from _g_get_time_charset (which uses LC_TIME) + * + * Returns: The converted string, or %NULL on an error. + */ +gchar * +_g_time_locale_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const char *charset; + + if (_g_get_time_charset (&charset)) + return strdup_len (opsysstring, len, bytes_read, bytes_written, error); + else + return convert_checked (opsysstring, len, "UTF-8", charset, + CONVERT_CHECK_NO_NULS_IN_OUTPUT, + bytes_read, bytes_written, error); +} + +/* + * Do the exact same as g_locale_to_utf8 except that the charset would + * be retrieved from _g_get_ctype_charset (which uses LC_CTYPE) + * + * Returns: The converted string, or %NULL on an error. + */ +gchar * +_g_ctype_locale_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const char *charset; + + if (_g_get_ctype_charset (&charset)) + return strdup_len (opsysstring, len, bytes_read, bytes_written, error); + else + return convert_checked (opsysstring, len, "UTF-8", charset, + CONVERT_CHECK_NO_NULS_IN_OUTPUT, + bytes_read, bytes_written, error); +} + +/** + * g_locale_from_utf8: + * @utf8string: a UTF-8 encoded string + * @len: the length of the string, or -1 if the string is + * nul-terminated. + * @bytes_read: (out) (optional): location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will be the byte offset after the last valid + * input sequence. + * @bytes_written: (out) (optional): the number of bytes stored in the output + * buffer (not including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from UTF-8 to the encoding used for strings by + * the C runtime (usually the same as that used by the operating + * system) in the [current locale][setlocale]. On Windows this means + * the system codepage. + * + * The input string shall not contain nul characters even if the @len + * argument is positive. A nul character found inside the string will result + * in error %G_CONVERT_ERROR_ILLEGAL_SEQUENCE. Use g_convert() to convert + * input that may contain embedded nul characters. + * + * Returns: (array length=bytes_written) (element-type guint8) (transfer full): + * A newly-allocated buffer containing the converted string, + * or %NULL on an error, and error will be set. + **/ +gchar * +g_locale_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const gchar *charset; + + if (g_get_charset (&charset)) + return strdup_len (utf8string, len, bytes_read, bytes_written, error); + else + return convert_checked (utf8string, len, charset, "UTF-8", + CONVERT_CHECK_NO_NULS_IN_INPUT, + bytes_read, bytes_written, error); +} + +#ifndef G_PLATFORM_WIN32 + +typedef struct _GFilenameCharsetCache GFilenameCharsetCache; + +struct _GFilenameCharsetCache { + gboolean is_utf8; + gchar *charset; + gchar **filename_charsets; +}; + +static void +filename_charset_cache_free (gpointer data) +{ + GFilenameCharsetCache *cache = data; + g_free (cache->charset); + g_strfreev (cache->filename_charsets); + g_free (cache); +} + +/** + * g_get_filename_charsets: + * @filename_charsets: (out) (transfer none) (array zero-terminated=1): + * return location for the %NULL-terminated list of encoding names + * + * Determines the preferred character sets used for filenames. + * The first character set from the @charsets is the filename encoding, the + * subsequent character sets are used when trying to generate a displayable + * representation of a filename, see g_filename_display_name(). + * + * On Unix, the character sets are determined by consulting the + * environment variables `G_FILENAME_ENCODING` and `G_BROKEN_FILENAMES`. + * On Windows, the character set used in the GLib API is always UTF-8 + * and said environment variables have no effect. + * + * `G_FILENAME_ENCODING` may be set to a comma-separated list of + * character set names. The special token "\@locale" is taken + * to mean the character set for the [current locale][setlocale]. + * If `G_FILENAME_ENCODING` is not set, but `G_BROKEN_FILENAMES` is, + * the character set of the current locale is taken as the filename + * encoding. If neither environment variable is set, UTF-8 is taken + * as the filename encoding, but the character set of the current locale + * is also put in the list of encodings. + * + * The returned @charsets belong to GLib and must not be freed. + * + * Note that on Unix, regardless of the locale character set or + * `G_FILENAME_ENCODING` value, the actual file names present + * on a system might be in any random encoding or just gibberish. + * + * Returns: %TRUE if the filename encoding is UTF-8. + * + * Since: 2.6 + */ +gboolean +g_get_filename_charsets (const gchar ***filename_charsets) +{ + static GPrivate cache_private = G_PRIVATE_INIT (filename_charset_cache_free); + GFilenameCharsetCache *cache = g_private_get (&cache_private); + const gchar *charset; + + if (!cache) + cache = g_private_set_alloc0 (&cache_private, sizeof (GFilenameCharsetCache)); + + g_get_charset (&charset); + + if (!(cache->charset && strcmp (cache->charset, charset) == 0)) + { + const gchar *new_charset; + const gchar *p; + gint i; + + g_free (cache->charset); + g_strfreev (cache->filename_charsets); + cache->charset = g_strdup (charset); + + p = g_getenv ("G_FILENAME_ENCODING"); + if (p != NULL && p[0] != '\0') + { + cache->filename_charsets = g_strsplit (p, ",", 0); + cache->is_utf8 = (strcmp (cache->filename_charsets[0], "UTF-8") == 0); + + for (i = 0; cache->filename_charsets[i]; i++) + { + if (strcmp ("@locale", cache->filename_charsets[i]) == 0) + { + g_get_charset (&new_charset); + g_free (cache->filename_charsets[i]); + cache->filename_charsets[i] = g_strdup (new_charset); + } + } + } + else if (g_getenv ("G_BROKEN_FILENAMES") != NULL) + { + cache->filename_charsets = g_new0 (gchar *, 2); + cache->is_utf8 = g_get_charset (&new_charset); + cache->filename_charsets[0] = g_strdup (new_charset); + } + else + { + cache->filename_charsets = g_new0 (gchar *, 3); + cache->is_utf8 = TRUE; + cache->filename_charsets[0] = g_strdup ("UTF-8"); + if (!g_get_charset (&new_charset)) + cache->filename_charsets[1] = g_strdup (new_charset); + } + } + + if (filename_charsets) + *filename_charsets = (const gchar **)cache->filename_charsets; + + return cache->is_utf8; +} + +#else /* G_PLATFORM_WIN32 */ + +gboolean +g_get_filename_charsets (const gchar ***filename_charsets) +{ + static const gchar *charsets[] = { + "UTF-8", + NULL + }; + +#ifdef G_OS_WIN32 + /* On Windows GLib pretends that the filename charset is UTF-8 */ + if (filename_charsets) + *filename_charsets = charsets; + + return TRUE; +#else + gboolean result; + + /* Cygwin works like before */ + result = g_get_charset (&(charsets[0])); + + if (filename_charsets) + *filename_charsets = charsets; + + return result; +#endif +} + +#endif /* G_PLATFORM_WIN32 */ + +static gboolean +get_filename_charset (const gchar **filename_charset) +{ + const gchar **charsets; + gboolean is_utf8; + + is_utf8 = g_get_filename_charsets (&charsets); + + if (filename_charset) + *filename_charset = charsets[0]; + + return is_utf8; +} + +/** + * g_filename_to_utf8: + * @opsysstring: (type filename): a string in the encoding for filenames + * @len: the length of the string, or -1 if the string is + * nul-terminated (Note that some encodings may allow nul + * bytes to occur inside strings. In that case, using -1 + * for the @len parameter is unsafe) + * @bytes_read: (out) (optional): location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will be the byte offset after the last valid + * input sequence. + * @bytes_written: (out) (optional): the number of bytes stored in the output + * buffer (not including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string which is in the encoding used by GLib for + * filenames into a UTF-8 string. Note that on Windows GLib uses UTF-8 + * for filenames; on other platforms, this function indirectly depends on + * the [current locale][setlocale]. + * + * The input string shall not contain nul characters even if the @len + * argument is positive. A nul character found inside the string will result + * in error %G_CONVERT_ERROR_ILLEGAL_SEQUENCE. + * If the source encoding is not UTF-8 and the conversion output contains a + * nul character, the error %G_CONVERT_ERROR_EMBEDDED_NUL is set and the + * function returns %NULL. Use g_convert() to produce output that + * may contain embedded nul characters. + * + * Returns: (type utf8): The converted string, or %NULL on an error. + **/ +gchar* +g_filename_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const gchar *charset; + + g_return_val_if_fail (opsysstring != NULL, NULL); + + if (get_filename_charset (&charset)) + return strdup_len (opsysstring, len, bytes_read, bytes_written, error); + else + return convert_checked (opsysstring, len, "UTF-8", charset, + CONVERT_CHECK_NO_NULS_IN_INPUT | + CONVERT_CHECK_NO_NULS_IN_OUTPUT, + bytes_read, bytes_written, error); +} + +/** + * g_filename_from_utf8: + * @utf8string: (type utf8): a UTF-8 encoded string. + * @len: the length of the string, or -1 if the string is + * nul-terminated. + * @bytes_read: (out) (optional): location to store the number of bytes in + * the input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will be the byte offset after the last valid + * input sequence. + * @bytes_written: (out) (optional): the number of bytes stored in + * the output buffer (not including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from UTF-8 to the encoding GLib uses for + * filenames. Note that on Windows GLib uses UTF-8 for filenames; + * on other platforms, this function indirectly depends on the + * [current locale][setlocale]. + * + * The input string shall not contain nul characters even if the @len + * argument is positive. A nul character found inside the string will result + * in error %G_CONVERT_ERROR_ILLEGAL_SEQUENCE. If the filename encoding is + * not UTF-8 and the conversion output contains a nul character, the error + * %G_CONVERT_ERROR_EMBEDDED_NUL is set and the function returns %NULL. + * + * Returns: (type filename): + * The converted string, or %NULL on an error. + **/ +gchar* +g_filename_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const gchar *charset; + + if (get_filename_charset (&charset)) + return strdup_len (utf8string, len, bytes_read, bytes_written, error); + else + return convert_checked (utf8string, len, charset, "UTF-8", + CONVERT_CHECK_NO_NULS_IN_INPUT | + CONVERT_CHECK_NO_NULS_IN_OUTPUT, + bytes_read, bytes_written, error); +} + +/* Test of haystack has the needle prefix, comparing case + * insensitive. haystack may be UTF-8, but needle must + * contain only ascii. */ +static gboolean +has_case_prefix (const gchar *haystack, const gchar *needle) +{ + const gchar *h, *n; + + /* Eat one character at a time. */ + h = haystack; + n = needle; + + while (*n && *h && + g_ascii_tolower (*n) == g_ascii_tolower (*h)) + { + n++; + h++; + } + + return *n == '\0'; +} + +typedef enum { + UNSAFE_ALL = 0x1, /* Escape all unsafe characters */ + UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */ + UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */ + UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */ + UNSAFE_SLASHES = 0x20 /* Allows all characters except for '/' and '%' */ +} UnsafeCharacterSet; + +static const guchar acceptable[96] = { + /* A table of the ASCII chars from space (32) to DEL (127) */ + /* ! " # $ % & ' ( ) * + , - . / */ + 0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C, + /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20, + /* @ A B C D E F G H I J K L M N O */ + 0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + /* P Q R S T U V W X Y Z [ \ ] ^ _ */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F, + /* ` a b c d e f g h i j k l m n o */ + 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + /* p q r s t u v w x y z { | } ~ DEL */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20 +}; + +static const gchar hex[] = "0123456789ABCDEF"; + +/* Note: This escape function works on file: URIs, but if you want to + * escape something else, please read RFC-2396 */ +static gchar * +g_escape_uri_string (const gchar *string, + UnsafeCharacterSet mask) +{ +#define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask)) + + const gchar *p; + gchar *q; + gchar *result; + int c; + gint unacceptable; + UnsafeCharacterSet use_mask; + + g_return_val_if_fail (mask == UNSAFE_ALL + || mask == UNSAFE_ALLOW_PLUS + || mask == UNSAFE_PATH + || mask == UNSAFE_HOST + || mask == UNSAFE_SLASHES, NULL); + + unacceptable = 0; + use_mask = mask; + for (p = string; *p != '\0'; p++) + { + c = (guchar) *p; + if (!ACCEPTABLE (c)) + unacceptable++; + } + + result = g_malloc (p - string + unacceptable * 2 + 1); + + use_mask = mask; + for (q = result, p = string; *p != '\0'; p++) + { + c = (guchar) *p; + + if (!ACCEPTABLE (c)) + { + *q++ = '%'; /* means hex coming */ + *q++ = hex[c >> 4]; + *q++ = hex[c & 15]; + } + else + *q++ = *p; + } + + *q = '\0'; + + return result; +} + + +static gchar * +g_escape_file_uri (const gchar *hostname, + const gchar *pathname) +{ + char *escaped_hostname = NULL; + char *escaped_path; + char *res; + +#ifdef G_OS_WIN32 + char *p, *backslash; + + /* Turn backslashes into forward slashes. That's what Netscape + * does, and they are actually more or less equivalent in Windows. + */ + + pathname = g_strdup (pathname); + p = (char *) pathname; + + while ((backslash = strchr (p, '\\')) != NULL) + { + *backslash = '/'; + p = backslash + 1; + } +#endif + + if (hostname && *hostname != '\0') + { + escaped_hostname = g_escape_uri_string (hostname, UNSAFE_HOST); + } + + escaped_path = g_escape_uri_string (pathname, UNSAFE_PATH); + + res = g_strconcat ("file://", + (escaped_hostname) ? escaped_hostname : "", + (*escaped_path != '/') ? "/" : "", + escaped_path, + NULL); + +#ifdef G_OS_WIN32 + g_free ((char *) pathname); +#endif + + g_free (escaped_hostname); + g_free (escaped_path); + + return res; +} + +static int +unescape_character (const char *scanner) +{ + int first_digit; + int second_digit; + + first_digit = g_ascii_xdigit_value (scanner[0]); + if (first_digit < 0) + return -1; + + second_digit = g_ascii_xdigit_value (scanner[1]); + if (second_digit < 0) + return -1; + + return (first_digit << 4) | second_digit; +} + +static gchar * +g_unescape_uri_string (const char *escaped, + int len, + const char *illegal_escaped_characters, + gboolean ascii_must_not_be_escaped) +{ + const gchar *in, *in_end; + gchar *out, *result; + int c; + + if (escaped == NULL) + return NULL; + + if (len < 0) + len = strlen (escaped); + + result = g_malloc (len + 1); + + out = result; + for (in = escaped, in_end = escaped + len; in < in_end; in++) + { + c = *in; + + if (c == '%') + { + /* catch partial escape sequences past the end of the substring */ + if (in + 3 > in_end) + break; + + c = unescape_character (in + 1); + + /* catch bad escape sequences and NUL characters */ + if (c <= 0) + break; + + /* catch escaped ASCII */ + if (ascii_must_not_be_escaped && c <= 0x7F) + break; + + /* catch other illegal escaped characters */ + if (strchr (illegal_escaped_characters, c) != NULL) + break; + + in += 2; + } + + *out++ = c; + } + + g_assert (out - result <= len); + *out = '\0'; + + if (in != in_end) + { + g_free (result); + return NULL; + } + + return result; +} + +static gboolean +is_asciialphanum (gunichar c) +{ + return c <= 0x7F && g_ascii_isalnum (c); +} + +static gboolean +is_asciialpha (gunichar c) +{ + return c <= 0x7F && g_ascii_isalpha (c); +} + +/* allows an empty string */ +static gboolean +hostname_validate (const char *hostname) +{ + const char *p; + gunichar c, first_char, last_char; + + p = hostname; + if (*p == '\0') + return TRUE; + do + { + /* read in a label */ + c = g_utf8_get_char (p); + p = g_utf8_next_char (p); + if (!is_asciialphanum (c)) + return FALSE; + first_char = c; + do + { + last_char = c; + c = g_utf8_get_char (p); + p = g_utf8_next_char (p); + } + while (is_asciialphanum (c) || c == '-'); + if (last_char == '-') + return FALSE; + + /* if that was the last label, check that it was a toplabel */ + if (c == '\0' || (c == '.' && *p == '\0')) + return is_asciialpha (first_char); + } + while (c == '.'); + return FALSE; +} + +/** + * g_filename_from_uri: + * @uri: a uri describing a filename (escaped, encoded in ASCII). + * @hostname: (out) (optional) (nullable): Location to store hostname for the URI. + * If there is no hostname in the URI, %NULL will be + * stored in this location. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts an escaped ASCII-encoded URI to a local filename in the + * encoding used for filenames. + * + * Returns: (type filename): a newly-allocated string holding + * the resulting filename, or %NULL on an error. + **/ +gchar * +g_filename_from_uri (const gchar *uri, + gchar **hostname, + GError **error) +{ + const char *path_part; + const char *host_part; + char *unescaped_hostname; + char *result; + char *filename; + int offs; +#ifdef G_OS_WIN32 + char *p, *slash; +#endif + + if (hostname) + *hostname = NULL; + + if (!has_case_prefix (uri, "file:/")) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The URI “%s†is not an absolute URI using the “file†scheme"), + uri); + return NULL; + } + + path_part = uri + strlen ("file:"); + + if (strchr (path_part, '#') != NULL) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The local file URI “%s†may not include a “#â€"), + uri); + return NULL; + } + + if (has_case_prefix (path_part, "///")) + path_part += 2; + else if (has_case_prefix (path_part, "//")) + { + path_part += 2; + host_part = path_part; + + path_part = strchr (path_part, '/'); + + if (path_part == NULL) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The URI “%s†is invalid"), + uri); + return NULL; + } + + unescaped_hostname = g_unescape_uri_string (host_part, path_part - host_part, "", TRUE); + + if (unescaped_hostname == NULL || + !hostname_validate (unescaped_hostname)) + { + g_free (unescaped_hostname); + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The hostname of the URI “%s†is invalid"), + uri); + return NULL; + } + + if (hostname) + *hostname = unescaped_hostname; + else + g_free (unescaped_hostname); + } + + filename = g_unescape_uri_string (path_part, -1, "/", FALSE); + + if (filename == NULL) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The URI “%s†contains invalidly escaped characters"), + uri); + return NULL; + } + + offs = 0; +#ifdef G_OS_WIN32 + /* Drop localhost */ + if (hostname && *hostname != NULL && + g_ascii_strcasecmp (*hostname, "localhost") == 0) + { + g_free (*hostname); + *hostname = NULL; + } + + /* Turn slashes into backslashes, because that's the canonical spelling */ + p = filename; + while ((slash = strchr (p, '/')) != NULL) + { + *slash = '\\'; + p = slash + 1; + } + + /* Windows URIs with a drive letter can be like "file://host/c:/foo" + * or "file://host/c|/foo" (some Netscape versions). In those cases, start + * the filename from the drive letter. + */ + if (g_ascii_isalpha (filename[1])) + { + if (filename[2] == ':') + offs = 1; + else if (filename[2] == '|') + { + filename[2] = ':'; + offs = 1; + } + } +#endif + + result = g_strdup (filename + offs); + g_free (filename); + + return result; +} + +/** + * g_filename_to_uri: + * @filename: (type filename): an absolute filename specified in the GLib file + * name encoding, which is the on-disk file name bytes on Unix, and UTF-8 + * on Windows + * @hostname: (nullable): A UTF-8 encoded hostname, or %NULL for none. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts an absolute filename to an escaped ASCII-encoded URI, with the path + * component following Section 3.3. of RFC 2396. + * + * Returns: a newly-allocated string holding the resulting + * URI, or %NULL on an error. + **/ +gchar * +g_filename_to_uri (const gchar *filename, + const gchar *hostname, + GError **error) +{ + char *escaped_uri; + + g_return_val_if_fail (filename != NULL, NULL); + + if (!g_path_is_absolute (filename)) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH, + _("The pathname “%s†is not an absolute path"), + filename); + return NULL; + } + + if (hostname && + !(g_utf8_validate (hostname, -1, NULL) + && hostname_validate (hostname))) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid hostname")); + return NULL; + } + +#ifdef G_OS_WIN32 + /* Don't use localhost unnecessarily */ + if (hostname && g_ascii_strcasecmp (hostname, "localhost") == 0) + hostname = NULL; +#endif + + escaped_uri = g_escape_file_uri (hostname, filename); + + return escaped_uri; +} + +/** + * g_uri_list_extract_uris: + * @uri_list: an URI list + * + * Splits an URI list conforming to the text/uri-list + * mime type defined in RFC 2483 into individual URIs, + * discarding any comments. The URIs are not validated. + * + * Returns: (transfer full): a newly allocated %NULL-terminated list + * of strings holding the individual URIs. The array should be freed + * with g_strfreev(). + * + * Since: 2.6 + */ +gchar ** +g_uri_list_extract_uris (const gchar *uri_list) +{ + GPtrArray *uris; + const gchar *p, *q; + + uris = g_ptr_array_new (); + + p = uri_list; + + /* We don't actually try to validate the URI according to RFC + * 2396, or even check for allowed characters - we just ignore + * comments and trim whitespace off the ends. We also + * allow LF delimination as well as the specified CRLF. + * + * We do allow comments like specified in RFC 2483. + */ + while (p) + { + if (*p != '#') + { + while (g_ascii_isspace (*p)) + p++; + + q = p; + while (*q && (*q != '\n') && (*q != '\r')) + q++; + + if (q > p) + { + q--; + while (q > p && g_ascii_isspace (*q)) + q--; + + if (q > p) + g_ptr_array_add (uris, g_strndup (p, q - p + 1)); + } + } + p = strchr (p, '\n'); + if (p) + p++; + } + + g_ptr_array_add (uris, NULL); + + return (gchar **) g_ptr_array_free (uris, FALSE); +} + +/** + * g_filename_display_basename: + * @filename: (type filename): an absolute pathname in the + * GLib file name encoding + * + * Returns the display basename for the particular filename, guaranteed + * to be valid UTF-8. The display name might not be identical to the filename, + * for instance there might be problems converting it to UTF-8, and some files + * can be translated in the display. + * + * If GLib cannot make sense of the encoding of @filename, as a last resort it + * replaces unknown characters with U+FFFD, the Unicode replacement character. + * You can search the result for the UTF-8 encoding of this character (which is + * "\357\277\275" in octal notation) to find out if @filename was in an invalid + * encoding. + * + * You must pass the whole absolute pathname to this functions so that + * translation of well known locations can be done. + * + * This function is preferred over g_filename_display_name() if you know the + * whole path, as it allows translation. + * + * Returns: a newly allocated string containing + * a rendition of the basename of the filename in valid UTF-8 + * + * Since: 2.6 + **/ +gchar * +g_filename_display_basename (const gchar *filename) +{ + char *basename; + char *display_name; + + g_return_val_if_fail (filename != NULL, NULL); + + basename = g_path_get_basename (filename); + display_name = g_filename_display_name (basename); + g_free (basename); + return display_name; +} + +/** + * g_filename_display_name: + * @filename: (type filename): a pathname hopefully in the + * GLib file name encoding + * + * Converts a filename into a valid UTF-8 string. The conversion is + * not necessarily reversible, so you should keep the original around + * and use the return value of this function only for display purposes. + * Unlike g_filename_to_utf8(), the result is guaranteed to be non-%NULL + * even if the filename actually isn't in the GLib file name encoding. + * + * If GLib cannot make sense of the encoding of @filename, as a last resort it + * replaces unknown characters with U+FFFD, the Unicode replacement character. + * You can search the result for the UTF-8 encoding of this character (which is + * "\357\277\275" in octal notation) to find out if @filename was in an invalid + * encoding. + * + * If you know the whole pathname of the file you should use + * g_filename_display_basename(), since that allows location-based + * translation of filenames. + * + * Returns: a newly allocated string containing + * a rendition of the filename in valid UTF-8 + * + * Since: 2.6 + **/ +gchar * +g_filename_display_name (const gchar *filename) +{ + gint i; + const gchar **charsets; + gchar *display_name = NULL; + gboolean is_utf8; + + is_utf8 = g_get_filename_charsets (&charsets); + + if (is_utf8) + { + if (g_utf8_validate (filename, -1, NULL)) + display_name = g_strdup (filename); + } + + if (!display_name) + { + /* Try to convert from the filename charsets to UTF-8. + * Skip the first charset if it is UTF-8. + */ + for (i = is_utf8 ? 1 : 0; charsets[i]; i++) + { + display_name = g_convert (filename, -1, "UTF-8", charsets[i], + NULL, NULL, NULL); + + if (display_name) + break; + } + } + + /* if all conversions failed, we replace invalid UTF-8 + * by a question mark + */ + if (!display_name) + display_name = g_utf8_make_valid (filename, -1); + + return display_name; +} + +#ifdef G_OS_WIN32 + +/* Binary compatibility versions. Not for newly compiled code. */ + +_GLIB_EXTERN gchar *g_filename_to_utf8_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +_GLIB_EXTERN gchar *g_filename_from_utf8_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +_GLIB_EXTERN gchar *g_filename_from_uri_utf8 (const gchar *uri, + gchar **hostname, + GError **error) G_GNUC_MALLOC; +_GLIB_EXTERN gchar *g_filename_to_uri_utf8 (const gchar *filename, + const gchar *hostname, + GError **error) G_GNUC_MALLOC; + +gchar * +g_filename_to_utf8_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + return g_filename_to_utf8 (opsysstring, len, bytes_read, bytes_written, error); +} + +gchar * +g_filename_from_utf8_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + return g_filename_from_utf8 (utf8string, len, bytes_read, bytes_written, error); +} + +gchar * +g_filename_from_uri_utf8 (const gchar *uri, + gchar **hostname, + GError **error) +{ + return g_filename_from_uri (uri, hostname, error); +} + +gchar * +g_filename_to_uri_utf8 (const gchar *filename, + const gchar *hostname, + GError **error) +{ + return g_filename_to_uri (filename, hostname, error); +} + +#endif diff --git a/glib/gconvert.h b/glib/gconvert.h new file mode 100644 index 0000000..be58ecf --- /dev/null +++ b/glib/gconvert.h @@ -0,0 +1,177 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_CONVERT_H__ +#define __G_CONVERT_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * GConvertError: + * @G_CONVERT_ERROR_NO_CONVERSION: Conversion between the requested character + * sets is not supported. + * @G_CONVERT_ERROR_ILLEGAL_SEQUENCE: Invalid byte sequence in conversion input; + * or the character sequence could not be represented in the target + * character set. + * @G_CONVERT_ERROR_FAILED: Conversion failed for some reason. + * @G_CONVERT_ERROR_PARTIAL_INPUT: Partial character sequence at end of input. + * @G_CONVERT_ERROR_BAD_URI: URI is invalid. + * @G_CONVERT_ERROR_NOT_ABSOLUTE_PATH: Pathname is not an absolute path. + * @G_CONVERT_ERROR_NO_MEMORY: No memory available. Since: 2.40 + * @G_CONVERT_ERROR_EMBEDDED_NUL: An embedded NUL character is present in + * conversion output where a NUL-terminated string is expected. + * Since: 2.56 + * + * Error codes returned by character set conversion routines. + */ +typedef enum +{ + G_CONVERT_ERROR_NO_CONVERSION, + G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + G_CONVERT_ERROR_FAILED, + G_CONVERT_ERROR_PARTIAL_INPUT, + G_CONVERT_ERROR_BAD_URI, + G_CONVERT_ERROR_NOT_ABSOLUTE_PATH, + G_CONVERT_ERROR_NO_MEMORY, + G_CONVERT_ERROR_EMBEDDED_NUL +} GConvertError; + +/** + * G_CONVERT_ERROR: + * + * Error domain for character set conversions. Errors in this domain will + * be from the #GConvertError enumeration. See #GError for information on + * error domains. + */ +#define G_CONVERT_ERROR g_convert_error_quark() +GLIB_AVAILABLE_IN_ALL +GQuark g_convert_error_quark (void); + +/** + * GIConv: (skip) + * + * The GIConv struct wraps an iconv() conversion descriptor. It contains + * private data and should only be accessed using the following functions. + */ +typedef struct _GIConv *GIConv; + +GLIB_AVAILABLE_IN_ALL +GIConv g_iconv_open (const gchar *to_codeset, + const gchar *from_codeset); +GLIB_AVAILABLE_IN_ALL +gsize g_iconv (GIConv converter, + gchar **inbuf, + gsize *inbytes_left, + gchar **outbuf, + gsize *outbytes_left); +GLIB_AVAILABLE_IN_ALL +gint g_iconv_close (GIConv converter); + + +GLIB_AVAILABLE_IN_ALL +gchar* g_convert (const gchar *str, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gchar* g_convert_with_iconv (const gchar *str, + gssize len, + GIConv converter, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gchar* g_convert_with_fallback (const gchar *str, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + const gchar *fallback, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; + + +/* Convert between libc's idea of strings and UTF-8. + */ +GLIB_AVAILABLE_IN_ALL +gchar* g_locale_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gchar* g_locale_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; + +/* Convert between the operating system (or C runtime) + * representation of file names and UTF-8. + */ +GLIB_AVAILABLE_IN_ALL +gchar* g_filename_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gchar* g_filename_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; + +GLIB_AVAILABLE_IN_ALL +gchar *g_filename_from_uri (const gchar *uri, + gchar **hostname, + GError **error) G_GNUC_MALLOC; + +GLIB_AVAILABLE_IN_ALL +gchar *g_filename_to_uri (const gchar *filename, + const gchar *hostname, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gchar *g_filename_display_name (const gchar *filename) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gboolean g_get_filename_charsets (const gchar ***filename_charsets); + +GLIB_AVAILABLE_IN_ALL +gchar *g_filename_display_basename (const gchar *filename) G_GNUC_MALLOC; + +GLIB_AVAILABLE_IN_ALL +gchar **g_uri_list_extract_uris (const gchar *uri_list); + +G_END_DECLS + +#endif /* __G_CONVERT_H__ */ diff --git a/glib/gconvertprivate.h b/glib/gconvertprivate.h new file mode 100644 index 0000000..5bdc87f --- /dev/null +++ b/glib/gconvertprivate.h @@ -0,0 +1,40 @@ +/* gconvertprivate.h - Private GLib gconvert functions + * + * Copyright 2020 Frederic Martinsons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef __G_CONVERTPRIVATE_H__ +#define __G_CONVERTPRIVATE_H__ + +G_BEGIN_DECLS + +#include "glib.h" + +gchar *_g_time_locale_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; + +gchar *_g_ctype_locale_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; + +G_END_DECLS + +#endif /* __G_CONVERTPRIVATE_H__ */ diff --git a/glib/gdataset.c b/glib/gdataset.c new file mode 100644 index 0000000..796d203 --- /dev/null +++ b/glib/gdataset.c @@ -0,0 +1,1251 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gdataset.c: Generic dataset mechanism, similar to GtkObject data. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe ; except for g_data*_foreach() + */ + +#include "config.h" + +#include + +#include "gdataset.h" +#include "gbitlock.h" + +#include "gslice.h" +#include "gdatasetprivate.h" +#include "ghash.h" +#include "gquark.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gthread.h" +#include "glib_trace.h" + +/** + * SECTION:datasets + * @title: Datasets + * @short_description: associate groups of data elements with + * particular memory locations + * + * Datasets associate groups of data elements with particular memory + * locations. These are useful if you need to associate data with a + * structure returned from an external library. Since you cannot modify + * the structure, you use its location in memory as the key into a + * dataset, where you can associate any number of data elements with it. + * + * There are two forms of most of the dataset functions. The first form + * uses strings to identify the data elements associated with a + * location. The second form uses #GQuark identifiers, which are + * created with a call to g_quark_from_string() or + * g_quark_from_static_string(). The second form is quicker, since it + * does not require looking up the string in the hash table of #GQuark + * identifiers. + * + * There is no function to create a dataset. It is automatically + * created as soon as you add elements to it. + * + * To add data elements to a dataset use g_dataset_id_set_data(), + * g_dataset_id_set_data_full(), g_dataset_set_data() and + * g_dataset_set_data_full(). + * + * To get data elements from a dataset use g_dataset_id_get_data() and + * g_dataset_get_data(). + * + * To iterate over all data elements in a dataset use + * g_dataset_foreach() (not thread-safe). + * + * To remove data elements from a dataset use + * g_dataset_id_remove_data() and g_dataset_remove_data(). + * + * To destroy a dataset, use g_dataset_destroy(). + **/ + +/** + * SECTION:datalist + * @title: Keyed Data Lists + * @short_description: lists of data elements which are accessible by a + * string or GQuark identifier + * + * Keyed data lists provide lists of arbitrary data elements which can + * be accessed either with a string or with a #GQuark corresponding to + * the string. + * + * The #GQuark methods are quicker, since the strings have to be + * converted to #GQuarks anyway. + * + * Data lists are used for associating arbitrary data with #GObjects, + * using g_object_set_data() and related functions. + * + * To create a datalist, use g_datalist_init(). + * + * To add data elements to a datalist use g_datalist_id_set_data(), + * g_datalist_id_set_data_full(), g_datalist_set_data() and + * g_datalist_set_data_full(). + * + * To get data elements from a datalist use g_datalist_id_get_data() + * and g_datalist_get_data(). + * + * To iterate over all data elements in a datalist use + * g_datalist_foreach() (not thread-safe). + * + * To remove data elements from a datalist use + * g_datalist_id_remove_data() and g_datalist_remove_data(). + * + * To remove all data elements from a datalist, use g_datalist_clear(). + **/ + +/** + * GData: + * + * An opaque data structure that represents a keyed data list. + * + * See also: [Keyed data lists][glib-Keyed-Data-Lists]. + **/ + +/** + * GDestroyNotify: + * @data: the data element. + * + * Specifies the type of function which is called when a data element + * is destroyed. It is passed the pointer to the data element and + * should free any memory and resources allocated for it. + **/ + +#define G_DATALIST_FLAGS_MASK_INTERNAL 0x7 + +/* datalist pointer accesses have to be carried out atomically */ +#define G_DATALIST_GET_POINTER(datalist) \ + ((GData*) ((gsize) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK_INTERNAL)) + +#define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \ + gpointer _oldv, _newv; \ + do { \ + _oldv = g_atomic_pointer_get (datalist); \ + _newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK_INTERNAL) | (gsize) pointer); \ + } while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, _oldv, _newv)); \ +} G_STMT_END + +/* --- structures --- */ +typedef struct { + GQuark key; + gpointer data; + GDestroyNotify destroy; +} GDataElt; + +typedef struct _GDataset GDataset; +struct _GData +{ + guint32 len; /* Number of elements */ + guint32 alloc; /* Number of allocated elements */ + GDataElt data[1]; /* Flexible array */ +}; + +struct _GDataset +{ + gconstpointer location; + GData *datalist; +}; + + +/* --- prototypes --- */ +static inline GDataset* g_dataset_lookup (gconstpointer dataset_location); +static inline void g_datalist_clear_i (GData **datalist); +static void g_dataset_destroy_internal (GDataset *dataset); +static inline gpointer g_data_set_internal (GData **datalist, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func, + GDataset *dataset); +static void g_data_initialize (void); + +/* Locking model: + * Each standalone GDataList is protected by a bitlock in the datalist pointer, + * which protects that modification of the non-flags part of the datalist pointer + * and the contents of the datalist. + * + * For GDataSet we have a global lock g_dataset_global that protects + * the global dataset hash and cache, and additionally it protects the + * datalist such that we can avoid to use the bit lock in a few places + * where it is easy. + */ + +/* --- variables --- */ +G_LOCK_DEFINE_STATIC (g_dataset_global); +static GHashTable *g_dataset_location_ht = NULL; +static GDataset *g_dataset_cached = NULL; /* should this be + thread specific? */ + +/* --- functions --- */ + +#define DATALIST_LOCK_BIT 2 + +static void +g_datalist_lock (GData **datalist) +{ + g_pointer_bit_lock ((void **)datalist, DATALIST_LOCK_BIT); +} + +static void +g_datalist_unlock (GData **datalist) +{ + g_pointer_bit_unlock ((void **)datalist, DATALIST_LOCK_BIT); +} + +/* Called with the datalist lock held, or the dataset global + * lock for dataset lists + */ +static void +g_datalist_clear_i (GData **datalist) +{ + GData *data; + guint i; + + data = G_DATALIST_GET_POINTER (datalist); + G_DATALIST_SET_POINTER (datalist, NULL); + + if (data) + { + G_UNLOCK (g_dataset_global); + for (i = 0; i < data->len; i++) + { + if (data->data[i].data && data->data[i].destroy) + data->data[i].destroy (data->data[i].data); + } + G_LOCK (g_dataset_global); + + g_free (data); + } + +} + +/** + * g_datalist_clear: (skip) + * @datalist: a datalist. + * + * Frees all the data elements of the datalist. + * The data elements' destroy functions are called + * if they have been set. + **/ +void +g_datalist_clear (GData **datalist) +{ + GData *data; + guint i; + + g_return_if_fail (datalist != NULL); + + g_datalist_lock (datalist); + + data = G_DATALIST_GET_POINTER (datalist); + G_DATALIST_SET_POINTER (datalist, NULL); + + g_datalist_unlock (datalist); + + if (data) + { + for (i = 0; i < data->len; i++) + { + if (data->data[i].data && data->data[i].destroy) + data->data[i].destroy (data->data[i].data); + } + + g_free (data); + } +} + +/* HOLDS: g_dataset_global_lock */ +static inline GDataset* +g_dataset_lookup (gconstpointer dataset_location) +{ + GDataset *dataset; + + if (g_dataset_cached && g_dataset_cached->location == dataset_location) + return g_dataset_cached; + + dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location); + if (dataset) + g_dataset_cached = dataset; + + return dataset; +} + +/* HOLDS: g_dataset_global_lock */ +static void +g_dataset_destroy_internal (GDataset *dataset) +{ + gconstpointer dataset_location; + + dataset_location = dataset->location; + while (dataset) + { + if (G_DATALIST_GET_POINTER(&dataset->datalist) == NULL) + { + if (dataset == g_dataset_cached) + g_dataset_cached = NULL; + g_hash_table_remove (g_dataset_location_ht, dataset_location); + g_slice_free (GDataset, dataset); + break; + } + + g_datalist_clear_i (&dataset->datalist); + dataset = g_dataset_lookup (dataset_location); + } +} + +/** + * g_dataset_destroy: + * @dataset_location: (not nullable): the location identifying the dataset. + * + * Destroys the dataset, freeing all memory allocated, and calling any + * destroy functions set for data elements. + */ +void +g_dataset_destroy (gconstpointer dataset_location) +{ + g_return_if_fail (dataset_location != NULL); + + G_LOCK (g_dataset_global); + if (g_dataset_location_ht) + { + GDataset *dataset; + + dataset = g_dataset_lookup (dataset_location); + if (dataset) + g_dataset_destroy_internal (dataset); + } + G_UNLOCK (g_dataset_global); +} + +/* HOLDS: g_dataset_global_lock if dataset != null */ +static inline gpointer +g_data_set_internal (GData **datalist, + GQuark key_id, + gpointer new_data, + GDestroyNotify new_destroy_func, + GDataset *dataset) +{ + GData *d, *old_d; + GDataElt old, *data, *data_last, *data_end; + + g_datalist_lock (datalist); + + d = G_DATALIST_GET_POINTER (datalist); + + if (new_data == NULL) /* remove */ + { + if (d) + { + data = d->data; + data_last = data + d->len - 1; + while (data <= data_last) + { + if (data->key == key_id) + { + old = *data; + if (data != data_last) + *data = *data_last; + d->len--; + + /* We don't bother to shrink, but if all data are now gone + * we at least free the memory + */ + if (d->len == 0) + { + G_DATALIST_SET_POINTER (datalist, NULL); + g_free (d); + /* datalist may be situated in dataset, so must not be + * unlocked after we free it + */ + g_datalist_unlock (datalist); + + /* the dataset destruction *must* be done + * prior to invocation of the data destroy function + */ + if (dataset) + g_dataset_destroy_internal (dataset); + } + else + { + g_datalist_unlock (datalist); + } + + /* We found and removed an old value + * the GData struct *must* already be unlinked + * when invoking the destroy function. + * we use (new_data==NULL && new_destroy_func!=NULL) as + * a special hint combination to "steal" + * data without destroy notification + */ + if (old.destroy && !new_destroy_func) + { + if (dataset) + G_UNLOCK (g_dataset_global); + old.destroy (old.data); + if (dataset) + G_LOCK (g_dataset_global); + old.data = NULL; + } + + return old.data; + } + data++; + } + } + } + else + { + old.data = NULL; + if (d) + { + data = d->data; + data_end = data + d->len; + while (data < data_end) + { + if (data->key == key_id) + { + if (!data->destroy) + { + data->data = new_data; + data->destroy = new_destroy_func; + g_datalist_unlock (datalist); + } + else + { + old = *data; + data->data = new_data; + data->destroy = new_destroy_func; + + g_datalist_unlock (datalist); + + /* We found and replaced an old value + * the GData struct *must* already be unlinked + * when invoking the destroy function. + */ + if (dataset) + G_UNLOCK (g_dataset_global); + old.destroy (old.data); + if (dataset) + G_LOCK (g_dataset_global); + } + return NULL; + } + data++; + } + } + + /* The key was not found, insert it */ + old_d = d; + if (d == NULL) + { + d = g_malloc (sizeof (GData)); + d->len = 0; + d->alloc = 1; + } + else if (d->len == d->alloc) + { + d->alloc = d->alloc * 2; + d = g_realloc (d, sizeof (GData) + (d->alloc - 1) * sizeof (GDataElt)); + } + if (old_d != d) + G_DATALIST_SET_POINTER (datalist, d); + + d->data[d->len].key = key_id; + d->data[d->len].data = new_data; + d->data[d->len].destroy = new_destroy_func; + d->len++; + } + + g_datalist_unlock (datalist); + + return NULL; + +} + +/** + * g_dataset_id_set_data_full: (skip) + * @dataset_location: (not nullable): the location identifying the dataset. + * @key_id: the #GQuark id to identify the data element. + * @data: the data element. + * @destroy_func: the function to call when the data element is + * removed. This function will be called with the data + * element and can be used to free any memory allocated + * for it. + * + * Sets the data element associated with the given #GQuark id, and also + * the function to call when the data element is destroyed. Any + * previous data with the same key is removed, and its destroy function + * is called. + **/ +/** + * g_dataset_set_data_full: (skip) + * @l: the location identifying the dataset. + * @k: the string to identify the data element. + * @d: the data element. + * @f: the function to call when the data element is removed. This + * function will be called with the data element and can be used to + * free any memory allocated for it. + * + * Sets the data corresponding to the given string identifier, and the + * function to call when the data element is destroyed. + **/ +/** + * g_dataset_id_set_data: + * @l: the location identifying the dataset. + * @k: the #GQuark id to identify the data element. + * @d: the data element. + * + * Sets the data element associated with the given #GQuark id. Any + * previous data with the same key is removed, and its destroy function + * is called. + **/ +/** + * g_dataset_set_data: + * @l: the location identifying the dataset. + * @k: the string to identify the data element. + * @d: the data element. + * + * Sets the data corresponding to the given string identifier. + **/ +/** + * g_dataset_id_remove_data: + * @l: the location identifying the dataset. + * @k: the #GQuark id identifying the data element. + * + * Removes a data element from a dataset. The data element's destroy + * function is called if it has been set. + **/ +/** + * g_dataset_remove_data: + * @l: the location identifying the dataset. + * @k: the string identifying the data element. + * + * Removes a data element corresponding to a string. Its destroy + * function is called if it has been set. + **/ +void +g_dataset_id_set_data_full (gconstpointer dataset_location, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func) +{ + GDataset *dataset; + + g_return_if_fail (dataset_location != NULL); + if (!data) + g_return_if_fail (destroy_func == NULL); + if (!key_id) + { + if (data) + g_return_if_fail (key_id > 0); + else + return; + } + + G_LOCK (g_dataset_global); + if (!g_dataset_location_ht) + g_data_initialize (); + + dataset = g_dataset_lookup (dataset_location); + if (!dataset) + { + dataset = g_slice_new (GDataset); + dataset->location = dataset_location; + g_datalist_init (&dataset->datalist); + g_hash_table_insert (g_dataset_location_ht, + (gpointer) dataset->location, + dataset); + } + + g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset); + G_UNLOCK (g_dataset_global); +} + +/** + * g_datalist_id_set_data_full: (skip) + * @datalist: a datalist. + * @key_id: the #GQuark to identify the data element. + * @data: (nullable): the data element or %NULL to remove any previous element + * corresponding to @key_id. + * @destroy_func: (nullable): the function to call when the data element is + * removed. This function will be called with the data + * element and can be used to free any memory allocated + * for it. If @data is %NULL, then @destroy_func must + * also be %NULL. + * + * Sets the data corresponding to the given #GQuark id, and the + * function to be called when the element is removed from the datalist. + * Any previous data with the same key is removed, and its destroy + * function is called. + **/ +/** + * g_datalist_set_data_full: (skip) + * @dl: a datalist. + * @k: the string to identify the data element. + * @d: (nullable): the data element, or %NULL to remove any previous element + * corresponding to @k. + * @f: (nullable): the function to call when the data element is removed. + * This function will be called with the data element and can be used to + * free any memory allocated for it. If @d is %NULL, then @f must + * also be %NULL. + * + * Sets the data element corresponding to the given string identifier, + * and the function to be called when the data element is removed. + **/ +/** + * g_datalist_id_set_data: + * @dl: a datalist. + * @q: the #GQuark to identify the data element. + * @d: (nullable): the data element, or %NULL to remove any previous element + * corresponding to @q. + * + * Sets the data corresponding to the given #GQuark id. Any previous + * data with the same key is removed, and its destroy function is + * called. + **/ +/** + * g_datalist_set_data: + * @dl: a datalist. + * @k: the string to identify the data element. + * @d: (nullable): the data element, or %NULL to remove any previous element + * corresponding to @k. + * + * Sets the data element corresponding to the given string identifier. + **/ +/** + * g_datalist_id_remove_data: + * @dl: a datalist. + * @q: the #GQuark identifying the data element. + * + * Removes an element, using its #GQuark identifier. + **/ +/** + * g_datalist_remove_data: + * @dl: a datalist. + * @k: the string identifying the data element. + * + * Removes an element using its string identifier. The data element's + * destroy function is called if it has been set. + **/ +void +g_datalist_id_set_data_full (GData **datalist, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func) +{ + g_return_if_fail (datalist != NULL); + if (!data) + g_return_if_fail (destroy_func == NULL); + if (!key_id) + { + if (data) + g_return_if_fail (key_id > 0); + else + return; + } + + g_data_set_internal (datalist, key_id, data, destroy_func, NULL); +} + +/** + * g_dataset_id_remove_no_notify: (skip) + * @dataset_location: (not nullable): the location identifying the dataset. + * @key_id: the #GQuark ID identifying the data element. + * + * Removes an element, without calling its destroy notification + * function. + * + * Returns: (nullable): the data previously stored at @key_id, + * or %NULL if none. + **/ +/** + * g_dataset_remove_no_notify: (skip) + * @l: the location identifying the dataset. + * @k: the string identifying the data element. + * + * Removes an element, without calling its destroy notifier. + **/ +gpointer +g_dataset_id_remove_no_notify (gconstpointer dataset_location, + GQuark key_id) +{ + gpointer ret_data = NULL; + + g_return_val_if_fail (dataset_location != NULL, NULL); + + G_LOCK (g_dataset_global); + if (key_id && g_dataset_location_ht) + { + GDataset *dataset; + + dataset = g_dataset_lookup (dataset_location); + if (dataset) + ret_data = g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset); + } + G_UNLOCK (g_dataset_global); + + return ret_data; +} + +/** + * g_datalist_id_remove_no_notify: (skip) + * @datalist: a datalist. + * @key_id: the #GQuark identifying a data element. + * + * Removes an element, without calling its destroy notification + * function. + * + * Returns: (nullable): the data previously stored at @key_id, + * or %NULL if none. + **/ +/** + * g_datalist_remove_no_notify: (skip) + * @dl: a datalist. + * @k: the string identifying the data element. + * + * Removes an element, without calling its destroy notifier. + **/ +gpointer +g_datalist_id_remove_no_notify (GData **datalist, + GQuark key_id) +{ + gpointer ret_data = NULL; + + g_return_val_if_fail (datalist != NULL, NULL); + + if (key_id) + ret_data = g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL); + + return ret_data; +} + +/** + * g_dataset_id_get_data: + * @dataset_location: (not nullable): the location identifying the dataset. + * @key_id: the #GQuark id to identify the data element. + * + * Gets the data element corresponding to a #GQuark. + * + * Returns: (transfer none) (nullable): the data element corresponding to + * the #GQuark, or %NULL if it is not found. + **/ +/** + * g_dataset_get_data: + * @l: the location identifying the dataset. + * @k: the string identifying the data element. + * + * Gets the data element corresponding to a string. + * + * Returns: (transfer none) (nullable): the data element corresponding to + * the string, or %NULL if it is not found. + **/ +gpointer +g_dataset_id_get_data (gconstpointer dataset_location, + GQuark key_id) +{ + gpointer retval = NULL; + + g_return_val_if_fail (dataset_location != NULL, NULL); + + G_LOCK (g_dataset_global); + if (key_id && g_dataset_location_ht) + { + GDataset *dataset; + + dataset = g_dataset_lookup (dataset_location); + if (dataset) + retval = g_datalist_id_get_data (&dataset->datalist, key_id); + } + G_UNLOCK (g_dataset_global); + + return retval; +} + +/** + * g_datalist_id_get_data: + * @datalist: a datalist. + * @key_id: the #GQuark identifying a data element. + * + * Retrieves the data element corresponding to @key_id. + * + * Returns: (transfer none) (nullable): the data element, or %NULL if + * it is not found. + */ +gpointer +g_datalist_id_get_data (GData **datalist, + GQuark key_id) +{ + return g_datalist_id_dup_data (datalist, key_id, NULL, NULL); +} + +/** + * GDuplicateFunc: + * @data: the data to duplicate + * @user_data: (closure): user data that was specified in + * g_datalist_id_dup_data() + * + * The type of functions that are used to 'duplicate' an object. + * What this means depends on the context, it could just be + * incrementing the reference count, if @data is a ref-counted + * object. + * + * Returns: a duplicate of data + */ + +/** + * g_datalist_id_dup_data: (skip) + * @datalist: location of a datalist + * @key_id: the #GQuark identifying a data element + * @dup_func: (nullable) (scope call): function to duplicate the old value + * @user_data: (closure): passed as user_data to @dup_func + * + * This is a variant of g_datalist_id_get_data() which + * returns a 'duplicate' of the value. @dup_func defines the + * meaning of 'duplicate' in this context, it could e.g. + * take a reference on a ref-counted object. + * + * If the @key_id is not set in the datalist then @dup_func + * will be called with a %NULL argument. + * + * Note that @dup_func is called while the datalist is locked, so it + * is not allowed to read or modify the datalist. + * + * This function can be useful to avoid races when multiple + * threads are using the same datalist and the same key. + * + * Returns: (nullable): the result of calling @dup_func on the value + * associated with @key_id in @datalist, or %NULL if not set. + * If @dup_func is %NULL, the value is returned unmodified. + * + * Since: 2.34 + */ +gpointer +g_datalist_id_dup_data (GData **datalist, + GQuark key_id, + GDuplicateFunc dup_func, + gpointer user_data) +{ + gpointer val = NULL; + gpointer retval = NULL; + GData *d; + GDataElt *data, *data_end; + + g_datalist_lock (datalist); + + d = G_DATALIST_GET_POINTER (datalist); + if (d) + { + data = d->data; + data_end = data + d->len; + do + { + if (data->key == key_id) + { + val = data->data; + break; + } + data++; + } + while (data < data_end); + } + + if (dup_func) + retval = dup_func (val, user_data); + else + retval = val; + + g_datalist_unlock (datalist); + + return retval; +} + +/** + * g_datalist_id_replace_data: (skip) + * @datalist: location of a datalist + * @key_id: the #GQuark identifying a data element + * @oldval: (nullable): the old value to compare against + * @newval: (nullable): the new value to replace it with + * @destroy: (nullable): destroy notify for the new value + * @old_destroy: (out) (optional): destroy notify for the existing value + * + * Compares the member that is associated with @key_id in + * @datalist to @oldval, and if they are the same, replace + * @oldval with @newval. + * + * This is like a typical atomic compare-and-exchange + * operation, for a member of @datalist. + * + * If the previous value was replaced then ownership of the + * old value (@oldval) is passed to the caller, including + * the registered destroy notify for it (passed out in @old_destroy). + * Its up to the caller to free this as they wish, which may + * or may not include using @old_destroy as sometimes replacement + * should not destroy the object in the normal way. + * + * Returns: %TRUE if the existing value for @key_id was replaced + * by @newval, %FALSE otherwise. + * + * Since: 2.34 + */ +gboolean +g_datalist_id_replace_data (GData **datalist, + GQuark key_id, + gpointer oldval, + gpointer newval, + GDestroyNotify destroy, + GDestroyNotify *old_destroy) +{ + gpointer val = NULL; + GData *d; + GDataElt *data, *data_end; + + g_return_val_if_fail (datalist != NULL, FALSE); + g_return_val_if_fail (key_id != 0, FALSE); + + if (old_destroy) + *old_destroy = NULL; + + g_datalist_lock (datalist); + + d = G_DATALIST_GET_POINTER (datalist); + if (d) + { + data = d->data; + data_end = data + d->len - 1; + while (data <= data_end) + { + if (data->key == key_id) + { + val = data->data; + if (val == oldval) + { + if (old_destroy) + *old_destroy = data->destroy; + if (newval != NULL) + { + data->data = newval; + data->destroy = destroy; + } + else + { + if (data != data_end) + *data = *data_end; + d->len--; + + /* We don't bother to shrink, but if all data are now gone + * we at least free the memory + */ + if (d->len == 0) + { + G_DATALIST_SET_POINTER (datalist, NULL); + g_free (d); + } + } + } + break; + } + data++; + } + } + + if (val == NULL && oldval == NULL && newval != NULL) + { + GData *old_d; + + /* insert newval */ + old_d = d; + if (d == NULL) + { + d = g_malloc (sizeof (GData)); + d->len = 0; + d->alloc = 1; + } + else if (d->len == d->alloc) + { + d->alloc = d->alloc * 2; + d = g_realloc (d, sizeof (GData) + (d->alloc - 1) * sizeof (GDataElt)); + } + if (old_d != d) + G_DATALIST_SET_POINTER (datalist, d); + + d->data[d->len].key = key_id; + d->data[d->len].data = newval; + d->data[d->len].destroy = destroy; + d->len++; + } + + g_datalist_unlock (datalist); + + return val == oldval; +} + +/** + * g_datalist_get_data: + * @datalist: a datalist. + * @key: the string identifying a data element. + * + * Gets a data element, using its string identifier. This is slower than + * g_datalist_id_get_data() because it compares strings. + * + * Returns: (transfer none) (nullable): the data element, or %NULL if it + * is not found. + **/ +gpointer +g_datalist_get_data (GData **datalist, + const gchar *key) +{ + gpointer res = NULL; + GData *d; + GDataElt *data, *data_end; + + g_return_val_if_fail (datalist != NULL, NULL); + + g_datalist_lock (datalist); + + d = G_DATALIST_GET_POINTER (datalist); + if (d) + { + data = d->data; + data_end = data + d->len; + while (data < data_end) + { + if (g_strcmp0 (g_quark_to_string (data->key), key) == 0) + { + res = data->data; + break; + } + data++; + } + } + + g_datalist_unlock (datalist); + + return res; +} + +/** + * GDataForeachFunc: + * @key_id: the #GQuark id to identifying the data element. + * @data: the data element. + * @user_data: (closure): user data passed to g_dataset_foreach(). + * + * Specifies the type of function passed to g_dataset_foreach(). It is + * called with each #GQuark id and associated data element, together + * with the @user_data parameter supplied to g_dataset_foreach(). + **/ + +/** + * g_dataset_foreach: + * @dataset_location: (not nullable): the location identifying the dataset. + * @func: (scope call): the function to call for each data element. + * @user_data: (closure): user data to pass to the function. + * + * Calls the given function for each data element which is associated + * with the given location. Note that this function is NOT thread-safe. + * So unless @dataset_location can be protected from any modifications + * during invocation of this function, it should not be called. + * + * @func can make changes to the dataset, but the iteration will not + * reflect changes made during the g_dataset_foreach() call, other + * than skipping over elements that are removed. + **/ +void +g_dataset_foreach (gconstpointer dataset_location, + GDataForeachFunc func, + gpointer user_data) +{ + GDataset *dataset; + + g_return_if_fail (dataset_location != NULL); + g_return_if_fail (func != NULL); + + G_LOCK (g_dataset_global); + if (g_dataset_location_ht) + { + dataset = g_dataset_lookup (dataset_location); + G_UNLOCK (g_dataset_global); + if (dataset) + g_datalist_foreach (&dataset->datalist, func, user_data); + } + else + { + G_UNLOCK (g_dataset_global); + } +} + +/** + * g_datalist_foreach: + * @datalist: a datalist. + * @func: (scope call): the function to call for each data element. + * @user_data: (closure): user data to pass to the function. + * + * Calls the given function for each data element of the datalist. The + * function is called with each data element's #GQuark id and data, + * together with the given @user_data parameter. Note that this + * function is NOT thread-safe. So unless @datalist can be protected + * from any modifications during invocation of this function, it should + * not be called. + * + * @func can make changes to @datalist, but the iteration will not + * reflect changes made during the g_datalist_foreach() call, other + * than skipping over elements that are removed. + **/ +void +g_datalist_foreach (GData **datalist, + GDataForeachFunc func, + gpointer user_data) +{ + GData *d; + guint i, j, len; + GQuark *keys; + + g_return_if_fail (datalist != NULL); + g_return_if_fail (func != NULL); + + d = G_DATALIST_GET_POINTER (datalist); + if (d == NULL) + return; + + /* We make a copy of the keys so that we can handle it changing + in the callback */ + len = d->len; + keys = g_new (GQuark, len); + for (i = 0; i < len; i++) + keys[i] = d->data[i].key; + + for (i = 0; i < len; i++) + { + /* A previous callback might have removed a later item, so always check that + it still exists before calling */ + d = G_DATALIST_GET_POINTER (datalist); + + if (d == NULL) + break; + for (j = 0; j < d->len; j++) + { + if (d->data[j].key == keys[i]) { + func (d->data[i].key, d->data[i].data, user_data); + break; + } + } + } + g_free (keys); +} + +/** + * g_datalist_init: (skip) + * @datalist: a pointer to a pointer to a datalist. + * + * Resets the datalist to %NULL. It does not free any memory or call + * any destroy functions. + **/ +void +g_datalist_init (GData **datalist) +{ + g_return_if_fail (datalist != NULL); + + g_atomic_pointer_set (datalist, NULL); +} + +/** + * g_datalist_set_flags: + * @datalist: pointer to the location that holds a list + * @flags: the flags to turn on. The values of the flags are + * restricted by %G_DATALIST_FLAGS_MASK (currently + * 3; giving two possible boolean flags). + * A value for @flags that doesn't fit within the mask is + * an error. + * + * Turns on flag values for a data list. This function is used + * to keep a small number of boolean flags in an object with + * a data list without using any additional space. It is + * not generally useful except in circumstances where space + * is very tight. (It is used in the base #GObject type, for + * example.) + * + * Since: 2.8 + **/ +void +g_datalist_set_flags (GData **datalist, + guint flags) +{ + g_return_if_fail (datalist != NULL); + g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); + + g_atomic_pointer_or (datalist, (gsize)flags); +} + +/** + * g_datalist_unset_flags: + * @datalist: pointer to the location that holds a list + * @flags: the flags to turn off. The values of the flags are + * restricted by %G_DATALIST_FLAGS_MASK (currently + * 3: giving two possible boolean flags). + * A value for @flags that doesn't fit within the mask is + * an error. + * + * Turns off flag values for a data list. See g_datalist_unset_flags() + * + * Since: 2.8 + **/ +void +g_datalist_unset_flags (GData **datalist, + guint flags) +{ + g_return_if_fail (datalist != NULL); + g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); + + g_atomic_pointer_and (datalist, ~(gsize)flags); +} + +/** + * g_datalist_get_flags: + * @datalist: pointer to the location that holds a list + * + * Gets flags values packed in together with the datalist. + * See g_datalist_set_flags(). + * + * Returns: the flags of the datalist + * + * Since: 2.8 + **/ +guint +g_datalist_get_flags (GData **datalist) +{ + g_return_val_if_fail (datalist != NULL, 0); + + return G_DATALIST_GET_FLAGS (datalist); /* atomic macro */ +} + +/* HOLDS: g_dataset_global_lock */ +static void +g_data_initialize (void) +{ + g_return_if_fail (g_dataset_location_ht == NULL); + + g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL); + g_dataset_cached = NULL; +} diff --git a/glib/gdataset.h b/glib/gdataset.h new file mode 100644 index 0000000..89a34c7 --- /dev/null +++ b/glib/gdataset.h @@ -0,0 +1,150 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_DATASET_H__ +#define __G_DATASET_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GData GData; + +typedef void (*GDataForeachFunc) (GQuark key_id, + gpointer data, + gpointer user_data); + +/* Keyed Data List + */ +GLIB_AVAILABLE_IN_ALL +void g_datalist_init (GData **datalist); +GLIB_AVAILABLE_IN_ALL +void g_datalist_clear (GData **datalist); +GLIB_AVAILABLE_IN_ALL +gpointer g_datalist_id_get_data (GData **datalist, + GQuark key_id); +GLIB_AVAILABLE_IN_ALL +void g_datalist_id_set_data_full (GData **datalist, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func); + +typedef gpointer (*GDuplicateFunc) (gpointer data, gpointer user_data); + +GLIB_AVAILABLE_IN_2_34 +gpointer g_datalist_id_dup_data (GData **datalist, + GQuark key_id, + GDuplicateFunc dup_func, + gpointer user_data); +GLIB_AVAILABLE_IN_2_34 +gboolean g_datalist_id_replace_data (GData **datalist, + GQuark key_id, + gpointer oldval, + gpointer newval, + GDestroyNotify destroy, + GDestroyNotify *old_destroy); + +GLIB_AVAILABLE_IN_ALL +gpointer g_datalist_id_remove_no_notify (GData **datalist, + GQuark key_id); +GLIB_AVAILABLE_IN_ALL +void g_datalist_foreach (GData **datalist, + GDataForeachFunc func, + gpointer user_data); + +/** + * G_DATALIST_FLAGS_MASK: + * + * A bitmask that restricts the possible flags passed to + * g_datalist_set_flags(). Passing a flags value where + * flags & ~G_DATALIST_FLAGS_MASK != 0 is an error. + */ +#define G_DATALIST_FLAGS_MASK 0x3 + +GLIB_AVAILABLE_IN_ALL +void g_datalist_set_flags (GData **datalist, + guint flags); +GLIB_AVAILABLE_IN_ALL +void g_datalist_unset_flags (GData **datalist, + guint flags); +GLIB_AVAILABLE_IN_ALL +guint g_datalist_get_flags (GData **datalist); + +#define g_datalist_id_set_data(dl, q, d) \ + g_datalist_id_set_data_full ((dl), (q), (d), NULL) +#define g_datalist_id_remove_data(dl, q) \ + g_datalist_id_set_data ((dl), (q), NULL) +#define g_datalist_set_data_full(dl, k, d, f) \ + g_datalist_id_set_data_full ((dl), g_quark_from_string (k), (d), (f)) +#define g_datalist_remove_no_notify(dl, k) \ + g_datalist_id_remove_no_notify ((dl), g_quark_try_string (k)) +#define g_datalist_set_data(dl, k, d) \ + g_datalist_set_data_full ((dl), (k), (d), NULL) +#define g_datalist_remove_data(dl, k) \ + g_datalist_id_set_data ((dl), g_quark_try_string (k), NULL) + +/* Location Associated Keyed Data + */ +GLIB_AVAILABLE_IN_ALL +void g_dataset_destroy (gconstpointer dataset_location); +GLIB_AVAILABLE_IN_ALL +gpointer g_dataset_id_get_data (gconstpointer dataset_location, + GQuark key_id); +GLIB_AVAILABLE_IN_ALL +gpointer g_datalist_get_data (GData **datalist, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +void g_dataset_id_set_data_full (gconstpointer dataset_location, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func); +GLIB_AVAILABLE_IN_ALL +gpointer g_dataset_id_remove_no_notify (gconstpointer dataset_location, + GQuark key_id); +GLIB_AVAILABLE_IN_ALL +void g_dataset_foreach (gconstpointer dataset_location, + GDataForeachFunc func, + gpointer user_data); +#define g_dataset_id_set_data(l, k, d) \ + g_dataset_id_set_data_full ((l), (k), (d), NULL) +#define g_dataset_id_remove_data(l, k) \ + g_dataset_id_set_data ((l), (k), NULL) +#define g_dataset_get_data(l, k) \ + (g_dataset_id_get_data ((l), g_quark_try_string (k))) +#define g_dataset_set_data_full(l, k, d, f) \ + g_dataset_id_set_data_full ((l), g_quark_from_string (k), (d), (f)) +#define g_dataset_remove_no_notify(l, k) \ + g_dataset_id_remove_no_notify ((l), g_quark_try_string (k)) +#define g_dataset_set_data(l, k, d) \ + g_dataset_set_data_full ((l), (k), (d), NULL) +#define g_dataset_remove_data(l, k) \ + g_dataset_id_set_data ((l), g_quark_try_string (k), NULL) + +G_END_DECLS + +#endif /* __G_DATASET_H__ */ diff --git a/glib/gdatasetprivate.h b/glib/gdatasetprivate.h new file mode 100644 index 0000000..eb95278 --- /dev/null +++ b/glib/gdatasetprivate.h @@ -0,0 +1,42 @@ +/* GLIB - Library of useful routines for C programming + * gdataset-private.h: Internal macros for accessing dataset values + * Copyright (C) 2005 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_DATASETPRIVATE_H__ +#define __G_DATASETPRIVATE_H__ + +#include + +G_BEGIN_DECLS + +/* GET_FLAGS is implemented via atomic pointer access, to allow memory + * barriers to take effect without acquiring the global dataset mutex. + */ +#define G_DATALIST_GET_FLAGS(datalist) \ + ((gsize) g_atomic_pointer_get (datalist) & G_DATALIST_FLAGS_MASK) + + +G_END_DECLS + +#endif /* __G_DATASETPRIVATE_H__ */ diff --git a/glib/gdate.c b/glib/gdate.c new file mode 100644 index 0000000..68c8689 --- /dev/null +++ b/glib/gdate.c @@ -0,0 +1,2755 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" +#include "glibconfig.h" + +#define DEBUG_MSG(x) /* */ +#ifdef G_ENABLE_DEBUG +/* #define DEBUG_MSG(args) g_message args ; */ +#endif + +#include +#include +#include +#include + +#ifdef G_OS_WIN32 +#include +#endif + +#include "gdate.h" + +#include "gconvert.h" +#include "gmem.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gthread.h" +#include "gunicode.h" + +#ifdef G_OS_WIN32 +#include "garray.h" +#endif + +/** + * SECTION:date + * @title: Date and Time Functions + * @short_description: calendrical calculations and miscellaneous time stuff + * + * The #GDate data structure represents a day between January 1, Year 1, + * and sometime a few thousand years in the future (right now it will go + * to the year 65535 or so, but g_date_set_parse() only parses up to the + * year 8000 or so - just count on "a few thousand"). #GDate is meant to + * represent everyday dates, not astronomical dates or historical dates + * or ISO timestamps or the like. It extrapolates the current Gregorian + * calendar forward and backward in time; there is no attempt to change + * the calendar to match time periods or locations. #GDate does not store + * time information; it represents a day. + * + * The #GDate implementation has several nice features; it is only a + * 64-bit struct, so storing large numbers of dates is very efficient. It + * can keep both a Julian and day-month-year representation of the date, + * since some calculations are much easier with one representation or the + * other. A Julian representation is simply a count of days since some + * fixed day in the past; for #GDate the fixed day is January 1, 1 AD. + * ("Julian" dates in the #GDate API aren't really Julian dates in the + * technical sense; technically, Julian dates count from the start of the + * Julian period, Jan 1, 4713 BC). + * + * #GDate is simple to use. First you need a "blank" date; you can get a + * dynamically allocated date from g_date_new(), or you can declare an + * automatic variable or array and initialize it by + * calling g_date_clear(). A cleared date is safe; it's safe to call + * g_date_set_dmy() and the other mutator functions to initialize the + * value of a cleared date. However, a cleared date is initially + * invalid, meaning that it doesn't represent a day that exists. + * It is undefined to call any of the date calculation routines on an + * invalid date. If you obtain a date from a user or other + * unpredictable source, you should check its validity with the + * g_date_valid() predicate. g_date_valid() is also used to check for + * errors with g_date_set_parse() and other functions that can + * fail. Dates can be invalidated by calling g_date_clear() again. + * + * It is very important to use the API to access the #GDate + * struct. Often only the day-month-year or only the Julian + * representation is valid. Sometimes neither is valid. Use the API. + * + * GLib also features #GDateTime which represents a precise time. + */ + +/** + * G_USEC_PER_SEC: + * + * Number of microseconds in one second (1 million). + * This macro is provided for code readability. + */ + +/** + * GTimeVal: + * @tv_sec: seconds + * @tv_usec: microseconds + * + * Represents a precise time, with seconds and microseconds. + * + * Similar to the struct timeval returned by the `gettimeofday()` + * UNIX system call. + * + * GLib is attempting to unify around the use of 64-bit integers to + * represent microsecond-precision time. As such, this type will be + * removed from a future version of GLib. A consequence of using `glong` for + * `tv_sec` is that on 32-bit systems `GTimeVal` is subject to the year 2038 + * problem. + * + * Deprecated: 2.62: Use #GDateTime or #guint64 instead. + */ + +/** + * GDate: + * @julian_days: the Julian representation of the date + * @julian: this bit is set if @julian_days is valid + * @dmy: this is set if @day, @month and @year are valid + * @day: the day of the day-month-year representation of the date, + * as a number between 1 and 31 + * @month: the day of the day-month-year representation of the date, + * as a number between 1 and 12 + * @year: the day of the day-month-year representation of the date + * + * Represents a day between January 1, Year 1 and a few thousand years in + * the future. None of its members should be accessed directly. + * + * If the `GDate` is obtained from g_date_new(), it will be safe + * to mutate but invalid and thus not safe for calendrical computations. + * + * If it's declared on the stack, it will contain garbage so must be + * initialized with g_date_clear(). g_date_clear() makes the date invalid + * but safe. An invalid date doesn't represent a day, it's "empty." A date + * becomes valid after you set it to a Julian day or you set a day, month, + * and year. + */ + +/** + * GTime: + * + * Simply a replacement for `time_t`. It has been deprecated + * since it is not equivalent to `time_t` on 64-bit platforms + * with a 64-bit `time_t`. + * + * Unrelated to #GTimer. + * + * Note that #GTime is defined to always be a 32-bit integer, + * unlike `time_t` which may be 64-bit on some systems. Therefore, + * #GTime will overflow in the year 2038, and you cannot use the + * address of a #GTime variable as argument to the UNIX time() + * function. + * + * Instead, do the following: + * + * |[ + * time_t ttime; + * GTime gtime; + * + * time (&ttime); + * gtime = (GTime)ttime; + * ]| + * + * Deprecated: 2.62: This is not [Y2038-safe](https://en.wikipedia.org/wiki/Year_2038_problem). + * Use #GDateTime or #time_t instead. + */ + +/** + * GDateDMY: + * @G_DATE_DAY: a day + * @G_DATE_MONTH: a month + * @G_DATE_YEAR: a year + * + * This enumeration isn't used in the API, but may be useful if you need + * to mark a number as a day, month, or year. + */ + +/** + * GDateDay: + * + * Integer representing a day of the month; between 1 and 31. + * + * The %G_DATE_BAD_DAY value represents an invalid day of the month. + */ + +/** + * GDateMonth: + * @G_DATE_BAD_MONTH: invalid value + * @G_DATE_JANUARY: January + * @G_DATE_FEBRUARY: February + * @G_DATE_MARCH: March + * @G_DATE_APRIL: April + * @G_DATE_MAY: May + * @G_DATE_JUNE: June + * @G_DATE_JULY: July + * @G_DATE_AUGUST: August + * @G_DATE_SEPTEMBER: September + * @G_DATE_OCTOBER: October + * @G_DATE_NOVEMBER: November + * @G_DATE_DECEMBER: December + * + * Enumeration representing a month; values are %G_DATE_JANUARY, + * %G_DATE_FEBRUARY, etc. %G_DATE_BAD_MONTH is the invalid value. + */ + +/** + * GDateYear: + * + * Integer type representing a year. + * + * The %G_DATE_BAD_YEAR value is the invalid value. The year + * must be 1 or higher; negative ([BCE](https://en.wikipedia.org/wiki/Common_Era)) + * years are not allowed. + * + * The year is represented with four digits. + */ + +/** + * GDateWeekday: + * @G_DATE_BAD_WEEKDAY: invalid value + * @G_DATE_MONDAY: Monday + * @G_DATE_TUESDAY: Tuesday + * @G_DATE_WEDNESDAY: Wednesday + * @G_DATE_THURSDAY: Thursday + * @G_DATE_FRIDAY: Friday + * @G_DATE_SATURDAY: Saturday + * @G_DATE_SUNDAY: Sunday + * + * Enumeration representing a day of the week; %G_DATE_MONDAY, + * %G_DATE_TUESDAY, etc. %G_DATE_BAD_WEEKDAY is an invalid weekday. + */ + +/** + * G_DATE_BAD_DAY: + * + * Represents an invalid #GDateDay. + */ + +/** + * G_DATE_BAD_JULIAN: + * + * Represents an invalid Julian day number. + */ + +/** + * G_DATE_BAD_YEAR: + * + * Represents an invalid year. + */ + +/** + * g_date_new: + * + * Allocates a #GDate and initializes + * it to a safe state. The new date will + * be cleared (as if you'd called g_date_clear()) but invalid (it won't + * represent an existing day). Free the return value with g_date_free(). + * + * Returns: a newly-allocated #GDate + */ +GDate* +g_date_new (void) +{ + GDate *d = g_new0 (GDate, 1); /* happily, 0 is the invalid flag for everything. */ + + return d; +} + +/** + * g_date_new_dmy: + * @day: day of the month + * @month: month of the year + * @year: year + * + * Create a new #GDate representing the given day-month-year triplet. + * + * The triplet you pass in must represent a valid date. Use g_date_valid_dmy() + * if needed to validate it. The returned #GDate is guaranteed to be non-%NULL + * and valid. + * + * Returns: (transfer full) (not nullable): a newly-allocated #GDate + * initialized with @day, @month, and @year + */ +GDate* +g_date_new_dmy (GDateDay day, + GDateMonth m, + GDateYear y) +{ + GDate *d; + g_return_val_if_fail (g_date_valid_dmy (day, m, y), NULL); + + d = g_new (GDate, 1); + + d->julian = FALSE; + d->dmy = TRUE; + + d->month = m; + d->day = day; + d->year = y; + + g_assert (g_date_valid (d)); + + return d; +} + +/** + * g_date_new_julian: + * @julian_day: days since January 1, Year 1 + * + * Create a new #GDate representing the given Julian date. + * + * The @julian_day you pass in must be valid. Use g_date_valid_julian() if + * needed to validate it. The returned #GDate is guaranteed to be non-%NULL and + * valid. + * + * Returns: (transfer full) (not nullable): a newly-allocated #GDate initialized + * with @julian_day + */ +GDate* +g_date_new_julian (guint32 julian_day) +{ + GDate *d; + g_return_val_if_fail (g_date_valid_julian (julian_day), NULL); + + d = g_new (GDate, 1); + + d->julian = TRUE; + d->dmy = FALSE; + + d->julian_days = julian_day; + + g_assert (g_date_valid (d)); + + return d; +} + +/** + * g_date_free: + * @date: a #GDate to free + * + * Frees a #GDate returned from g_date_new(). + */ +void +g_date_free (GDate *date) +{ + g_return_if_fail (date != NULL); + + g_free (date); +} + +/** + * g_date_copy: + * @date: a #GDate to copy + * + * Copies a GDate to a newly-allocated GDate. If the input was invalid + * (as determined by g_date_valid()), the invalid state will be copied + * as is into the new object. + * + * Returns: (transfer full): a newly-allocated #GDate initialized from @date + * + * Since: 2.56 + */ +GDate * +g_date_copy (const GDate *date) +{ + GDate *res; + g_return_val_if_fail (date != NULL, NULL); + + if (g_date_valid (date)) + res = g_date_new_julian (g_date_get_julian (date)); + else + { + res = g_date_new (); + *res = *date; + } + + return res; +} + +/** + * g_date_valid: + * @date: a #GDate to check + * + * Returns %TRUE if the #GDate represents an existing day. The date must not + * contain garbage; it should have been initialized with g_date_clear() + * if it wasn't allocated by one of the g_date_new() variants. + * + * Returns: Whether the date is valid + */ +gboolean +g_date_valid (const GDate *d) +{ + g_return_val_if_fail (d != NULL, FALSE); + + return (d->julian || d->dmy); +} + +static const guint8 days_in_months[2][13] = +{ /* error, jan feb mar apr may jun jul aug sep oct nov dec */ + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } /* leap year */ +}; + +static const guint16 days_in_year[2][14] = +{ /* 0, jan feb mar apr may jun jul aug sep oct nov dec */ + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +/** + * g_date_valid_month: + * @month: month + * + * Returns %TRUE if the month value is valid. The 12 #GDateMonth + * enumeration values are the only valid months. + * + * Returns: %TRUE if the month is valid + */ +gboolean +g_date_valid_month (GDateMonth m) +{ + return (((gint) m > G_DATE_BAD_MONTH) && ((gint) m < 13)); +} + +/** + * g_date_valid_year: + * @year: year + * + * Returns %TRUE if the year is valid. Any year greater than 0 is valid, + * though there is a 16-bit limit to what #GDate will understand. + * + * Returns: %TRUE if the year is valid + */ +gboolean +g_date_valid_year (GDateYear y) +{ + return ( y > G_DATE_BAD_YEAR ); +} + +/** + * g_date_valid_day: + * @day: day to check + * + * Returns %TRUE if the day of the month is valid (a day is valid if it's + * between 1 and 31 inclusive). + * + * Returns: %TRUE if the day is valid + */ + +gboolean +g_date_valid_day (GDateDay d) +{ + return ( (d > G_DATE_BAD_DAY) && (d < 32) ); +} + +/** + * g_date_valid_weekday: + * @weekday: weekday + * + * Returns %TRUE if the weekday is valid. The seven #GDateWeekday enumeration + * values are the only valid weekdays. + * + * Returns: %TRUE if the weekday is valid + */ +gboolean +g_date_valid_weekday (GDateWeekday w) +{ + return (((gint) w > G_DATE_BAD_WEEKDAY) && ((gint) w < 8)); +} + +/** + * g_date_valid_julian: + * @julian_date: Julian day to check + * + * Returns %TRUE if the Julian day is valid. Anything greater than zero + * is basically a valid Julian, though there is a 32-bit limit. + * + * Returns: %TRUE if the Julian day is valid + */ +gboolean +g_date_valid_julian (guint32 j) +{ + return (j > G_DATE_BAD_JULIAN); +} + +/** + * g_date_valid_dmy: + * @day: day + * @month: month + * @year: year + * + * Returns %TRUE if the day-month-year triplet forms a valid, existing day + * in the range of days #GDate understands (Year 1 or later, no more than + * a few thousand years in the future). + * + * Returns: %TRUE if the date is a valid one + */ +gboolean +g_date_valid_dmy (GDateDay d, + GDateMonth m, + GDateYear y) +{ + /* No need to check the upper bound of @y, because #GDateYear is 16 bits wide, + * just like #GDate.year. */ + return ( (m > G_DATE_BAD_MONTH) && + (m < 13) && + (d > G_DATE_BAD_DAY) && + (y > G_DATE_BAD_YEAR) && /* must check before using g_date_is_leap_year */ + (d <= (g_date_is_leap_year (y) ? + days_in_months[1][m] : days_in_months[0][m])) ); +} + + +/* "Julian days" just means an absolute number of days, where Day 1 == + * Jan 1, Year 1 + */ +static void +g_date_update_julian (const GDate *const_d) +{ + GDate *d = (GDate *) const_d; + GDateYear year; + gint idx; + + g_return_if_fail (d != NULL); + g_return_if_fail (d->dmy != 0); + g_return_if_fail (!d->julian); + g_return_if_fail (g_date_valid_dmy (d->day, d->month, d->year)); + + /* What we actually do is: multiply years * 365 days in the year, + * add the number of years divided by 4, subtract the number of + * years divided by 100 and add the number of years divided by 400, + * which accounts for leap year stuff. Code from Steffen Beyer's + * DateCalc. + */ + + year = d->year - 1; /* we know d->year > 0 since it's valid */ + + d->julian_days = year * 365U; + d->julian_days += (year >>= 2); /* divide by 4 and add */ + d->julian_days -= (year /= 25); /* divides original # years by 100 */ + d->julian_days += year >> 2; /* divides by 4, which divides original by 400 */ + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + d->julian_days += days_in_year[idx][d->month] + d->day; + + g_return_if_fail (g_date_valid_julian (d->julian_days)); + + d->julian = TRUE; +} + +static void +g_date_update_dmy (const GDate *const_d) +{ + GDate *d = (GDate *) const_d; + GDateYear y; + GDateMonth m; + GDateDay day; + + guint32 A, B, C, D, E, M; + + g_return_if_fail (d != NULL); + g_return_if_fail (d->julian); + g_return_if_fail (!d->dmy); + g_return_if_fail (g_date_valid_julian (d->julian_days)); + + /* Formula taken from the Calendar FAQ; the formula was for the + * Julian Period which starts on 1 January 4713 BC, so we add + * 1,721,425 to the number of days before doing the formula. + * + * I'm sure this can be simplified for our 1 January 1 AD period + * start, but I can't figure out how to unpack the formula. + */ + + A = d->julian_days + 1721425 + 32045; + B = ( 4 *(A + 36524) )/ 146097 - 1; + C = A - (146097 * B)/4; + D = ( 4 * (C + 365) ) / 1461 - 1; + E = C - ((1461*D) / 4); + M = (5 * (E - 1) + 2)/153; + + m = M + 3 - (12*(M/10)); + day = E - (153*M + 2)/5; + y = 100 * B + D - 4800 + (M/10); + +#ifdef G_ENABLE_DEBUG + if (!g_date_valid_dmy (day, m, y)) + g_warning ("OOPS julian: %u computed dmy: %u %u %u", + d->julian_days, day, m, y); +#endif + + d->month = m; + d->day = day; + d->year = y; + + d->dmy = TRUE; +} + +/** + * g_date_get_weekday: + * @date: a #GDate + * + * Returns the day of the week for a #GDate. The date must be valid. + * + * Returns: day of the week as a #GDateWeekday. + */ +GDateWeekday +g_date_get_weekday (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_WEEKDAY); + + if (!d->julian) + g_date_update_julian (d); + + g_return_val_if_fail (d->julian, G_DATE_BAD_WEEKDAY); + + return ((d->julian_days - 1) % 7) + 1; +} + +/** + * g_date_get_month: + * @date: a #GDate to get the month from + * + * Returns the month of the year. The date must be valid. + * + * Returns: month of the year as a #GDateMonth + */ +GDateMonth +g_date_get_month (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_MONTH); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, G_DATE_BAD_MONTH); + + return d->month; +} + +/** + * g_date_get_year: + * @date: a #GDate + * + * Returns the year of a #GDate. The date must be valid. + * + * Returns: year in which the date falls + */ +GDateYear +g_date_get_year (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_YEAR); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, G_DATE_BAD_YEAR); + + return d->year; +} + +/** + * g_date_get_day: + * @date: a #GDate to extract the day of the month from + * + * Returns the day of the month. The date must be valid. + * + * Returns: day of the month + */ +GDateDay +g_date_get_day (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_DAY); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, G_DATE_BAD_DAY); + + return d->day; +} + +/** + * g_date_get_julian: + * @date: a #GDate to extract the Julian day from + * + * Returns the Julian day or "serial number" of the #GDate. The + * Julian day is simply the number of days since January 1, Year 1; i.e., + * January 1, Year 1 is Julian day 1; January 2, Year 1 is Julian day 2, + * etc. The date must be valid. + * + * Returns: Julian day + */ +guint32 +g_date_get_julian (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_JULIAN); + + if (!d->julian) + g_date_update_julian (d); + + g_return_val_if_fail (d->julian, G_DATE_BAD_JULIAN); + + return d->julian_days; +} + +/** + * g_date_get_day_of_year: + * @date: a #GDate to extract day of year from + * + * Returns the day of the year, where Jan 1 is the first day of the + * year. The date must be valid. + * + * Returns: day of the year + */ +guint +g_date_get_day_of_year (const GDate *d) +{ + gint idx; + + g_return_val_if_fail (g_date_valid (d), 0); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, 0); + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + return (days_in_year[idx][d->month] + d->day); +} + +/** + * g_date_get_monday_week_of_year: + * @date: a #GDate + * + * Returns the week of the year, where weeks are understood to start on + * Monday. If the date is before the first Monday of the year, return 0. + * The date must be valid. + * + * Returns: week of the year + */ +guint +g_date_get_monday_week_of_year (const GDate *d) +{ + GDateWeekday wd; + guint day; + GDate first; + + g_return_val_if_fail (g_date_valid (d), 0); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, 0); + + g_date_clear (&first, 1); + + g_date_set_dmy (&first, 1, 1, d->year); + + wd = g_date_get_weekday (&first) - 1; /* make Monday day 0 */ + day = g_date_get_day_of_year (d) - 1; + + return ((day + wd)/7U + (wd == 0 ? 1 : 0)); +} + +/** + * g_date_get_sunday_week_of_year: + * @date: a #GDate + * + * Returns the week of the year during which this date falls, if + * weeks are understood to begin on Sunday. The date must be valid. + * Can return 0 if the day is before the first Sunday of the year. + * + * Returns: week number + */ +guint +g_date_get_sunday_week_of_year (const GDate *d) +{ + GDateWeekday wd; + guint day; + GDate first; + + g_return_val_if_fail (g_date_valid (d), 0); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, 0); + + g_date_clear (&first, 1); + + g_date_set_dmy (&first, 1, 1, d->year); + + wd = g_date_get_weekday (&first); + if (wd == 7) wd = 0; /* make Sunday day 0 */ + day = g_date_get_day_of_year (d) - 1; + + return ((day + wd)/7U + (wd == 0 ? 1 : 0)); +} + +/** + * g_date_get_iso8601_week_of_year: + * @date: a valid #GDate + * + * Returns the week of the year, where weeks are interpreted according + * to ISO 8601. + * + * Returns: ISO 8601 week number of the year. + * + * Since: 2.6 + **/ +guint +g_date_get_iso8601_week_of_year (const GDate *d) +{ + guint j, d4, L, d1, w; + + g_return_val_if_fail (g_date_valid (d), 0); + + if (!d->julian) + g_date_update_julian (d); + + g_return_val_if_fail (d->julian, 0); + + /* Formula taken from the Calendar FAQ; the formula was for the + * Julian Period which starts on 1 January 4713 BC, so we add + * 1,721,425 to the number of days before doing the formula. + */ + j = d->julian_days + 1721425; + d4 = (j + 31741 - (j % 7)) % 146097 % 36524 % 1461; + L = d4 / 1460; + d1 = ((d4 - L) % 365) + L; + w = d1 / 7 + 1; + + return w; +} + +/** + * g_date_days_between: + * @date1: the first date + * @date2: the second date + * + * Computes the number of days between two dates. + * If @date2 is prior to @date1, the returned value is negative. + * Both dates must be valid. + * + * Returns: the number of days between @date1 and @date2 + */ +gint +g_date_days_between (const GDate *d1, + const GDate *d2) +{ + g_return_val_if_fail (g_date_valid (d1), 0); + g_return_val_if_fail (g_date_valid (d2), 0); + + return (gint)g_date_get_julian (d2) - (gint)g_date_get_julian (d1); +} + +/** + * g_date_clear: + * @date: pointer to one or more dates to clear + * @n_dates: number of dates to clear + * + * Initializes one or more #GDate structs to a safe but invalid + * state. The cleared dates will not represent an existing date, but will + * not contain garbage. Useful to init a date declared on the stack. + * Validity can be tested with g_date_valid(). + */ +void +g_date_clear (GDate *d, guint ndates) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (ndates != 0); + + memset (d, 0x0, ndates*sizeof (GDate)); +} + +G_LOCK_DEFINE_STATIC (g_date_global); + +/* These are for the parser, output to the user should use * + * g_date_strftime () - this creates more never-freed memory to annoy + * all those memory debugger users. :-) + */ + +static gchar *long_month_names[13] = +{ + NULL, +}; + +static gchar *long_month_names_alternative[13] = +{ + NULL, +}; + +static gchar *short_month_names[13] = +{ + NULL, +}; + +static gchar *short_month_names_alternative[13] = +{ + NULL, +}; + +/* This tells us if we need to update the parse info */ +static gchar *current_locale = NULL; + +/* order of these in the current locale */ +static GDateDMY dmy_order[3] = +{ + G_DATE_DAY, G_DATE_MONTH, G_DATE_YEAR +}; + +/* Where to chop two-digit years: i.e., for the 1930 default, numbers + * 29 and below are counted as in the year 2000, numbers 30 and above + * are counted as in the year 1900. + */ + +static const GDateYear twodigit_start_year = 1930; + +/* It is impossible to enter a year between 1 AD and 99 AD with this + * in effect. + */ +static gboolean using_twodigit_years = FALSE; + +/* Adjustment of locale era to AD, non-zero means using locale era + */ +static gint locale_era_adjust = 0; + +struct _GDateParseTokens { + gint num_ints; + gint n[3]; + guint month; +}; + +typedef struct _GDateParseTokens GDateParseTokens; + +static inline gboolean +update_month_match (gsize *longest, + const gchar *haystack, + const gchar *needle) +{ + gsize length; + + if (needle == NULL) + return FALSE; + + length = strlen (needle); + if (*longest >= length) + return FALSE; + + if (strstr (haystack, needle) == NULL) + return FALSE; + + *longest = length; + return TRUE; +} + +#define NUM_LEN 10 + +/* HOLDS: g_date_global_lock */ +static void +g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt) +{ + gchar num[4][NUM_LEN+1]; + gint i; + const guchar *s; + + /* We count 4, but store 3; so we can give an error + * if there are 4. + */ + num[0][0] = num[1][0] = num[2][0] = num[3][0] = '\0'; + + s = (const guchar *) str; + pt->num_ints = 0; + while (*s && pt->num_ints < 4) + { + + i = 0; + while (*s && g_ascii_isdigit (*s) && i < NUM_LEN) + { + num[pt->num_ints][i] = *s; + ++s; + ++i; + } + + if (i > 0) + { + num[pt->num_ints][i] = '\0'; + ++(pt->num_ints); + } + + if (*s == '\0') break; + + ++s; + } + + pt->n[0] = pt->num_ints > 0 ? atoi (num[0]) : 0; + pt->n[1] = pt->num_ints > 1 ? atoi (num[1]) : 0; + pt->n[2] = pt->num_ints > 2 ? atoi (num[2]) : 0; + + pt->month = G_DATE_BAD_MONTH; + + if (pt->num_ints < 3) + { + gsize longest = 0; + gchar *casefold; + gchar *normalized; + + casefold = g_utf8_casefold (str, -1); + normalized = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL); + g_free (casefold); + + for (i = 1; i < 13; ++i) + { + /* Here month names may be in a genitive case if the language + * grammatical rules require it. + * Examples of how January may look in some languages: + * Catalan: "de gener", Croatian: "sijeÄnja", Polish: "stycznia", + * Upper Sorbian: "januara". + * Note that most of the languages can't or don't use the the + * genitive case here so they use nominative everywhere. + * For example, English always uses "January". + */ + if (update_month_match (&longest, normalized, long_month_names[i])) + pt->month = i; + + /* Here month names will be in a nominative case. + * Examples of how January may look in some languages: + * Catalan: "gener", Croatian: "SijeÄanj", Polish: "styczeÅ„", + * Upper Sorbian: "Januar". + */ + if (update_month_match (&longest, normalized, long_month_names_alternative[i])) + pt->month = i; + + /* Differences between abbreviated nominative and abbreviated + * genitive month names are visible in very few languages but + * let's handle them. + */ + if (update_month_match (&longest, normalized, short_month_names[i])) + pt->month = i; + + if (update_month_match (&longest, normalized, short_month_names_alternative[i])) + pt->month = i; + } + + g_free (normalized); + } +} + +/* HOLDS: g_date_global_lock */ +static void +g_date_prepare_to_parse (const gchar *str, + GDateParseTokens *pt) +{ + const gchar *locale = setlocale (LC_TIME, NULL); + gboolean recompute_localeinfo = FALSE; + GDate d; + + g_return_if_fail (locale != NULL); /* should not happen */ + + g_date_clear (&d, 1); /* clear for scratch use */ + + if ( (current_locale == NULL) || (strcmp (locale, current_locale) != 0) ) + recompute_localeinfo = TRUE; /* Uh, there used to be a reason for the temporary */ + + if (recompute_localeinfo) + { + int i = 1; + GDateParseTokens testpt; + gchar buf[128]; + + g_free (current_locale); /* still works if current_locale == NULL */ + + current_locale = g_strdup (locale); + + short_month_names[0] = "Error"; + long_month_names[0] = "Error"; + + while (i < 13) + { + gchar *casefold; + + g_date_set_dmy (&d, 1, i, 1976); + + g_return_if_fail (g_date_valid (&d)); + + g_date_strftime (buf, 127, "%b", &d); + + casefold = g_utf8_casefold (buf, -1); + g_free (short_month_names[i]); + short_month_names[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL); + g_free (casefold); + + g_date_strftime (buf, 127, "%B", &d); + casefold = g_utf8_casefold (buf, -1); + g_free (long_month_names[i]); + long_month_names[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL); + g_free (casefold); + + g_date_strftime (buf, 127, "%Ob", &d); + casefold = g_utf8_casefold (buf, -1); + g_free (short_month_names_alternative[i]); + short_month_names_alternative[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL); + g_free (casefold); + + g_date_strftime (buf, 127, "%OB", &d); + casefold = g_utf8_casefold (buf, -1); + g_free (long_month_names_alternative[i]); + long_month_names_alternative[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL); + g_free (casefold); + + ++i; + } + + /* Determine DMY order */ + + /* had to pick a random day - don't change this, some strftimes + * are broken on some days, and this one is good so far. */ + g_date_set_dmy (&d, 4, 7, 1976); + + g_date_strftime (buf, 127, "%x", &d); + + g_date_fill_parse_tokens (buf, &testpt); + + using_twodigit_years = FALSE; + locale_era_adjust = 0; + dmy_order[0] = G_DATE_DAY; + dmy_order[1] = G_DATE_MONTH; + dmy_order[2] = G_DATE_YEAR; + + i = 0; + while (i < testpt.num_ints) + { + switch (testpt.n[i]) + { + case 7: + dmy_order[i] = G_DATE_MONTH; + break; + case 4: + dmy_order[i] = G_DATE_DAY; + break; + case 76: + using_twodigit_years = TRUE; + G_GNUC_FALLTHROUGH; + case 1976: + dmy_order[i] = G_DATE_YEAR; + break; + default: + /* assume locale era */ + locale_era_adjust = 1976 - testpt.n[i]; + dmy_order[i] = G_DATE_YEAR; + break; + } + ++i; + } + +#if defined(G_ENABLE_DEBUG) && 0 + DEBUG_MSG (("**GDate prepared a new set of locale-specific parse rules.")); + i = 1; + while (i < 13) + { + DEBUG_MSG ((" %s %s", long_month_names[i], short_month_names[i])); + ++i; + } + DEBUG_MSG (("Alternative month names:")); + i = 1; + while (i < 13) + { + DEBUG_MSG ((" %s %s", long_month_names_alternative[i], short_month_names_alternative[i])); + ++i; + } + if (using_twodigit_years) + { + DEBUG_MSG (("**Using twodigit years with cutoff year: %u", twodigit_start_year)); + } + { + gchar *strings[3]; + i = 0; + while (i < 3) + { + switch (dmy_order[i]) + { + case G_DATE_MONTH: + strings[i] = "Month"; + break; + case G_DATE_YEAR: + strings[i] = "Year"; + break; + case G_DATE_DAY: + strings[i] = "Day"; + break; + default: + strings[i] = NULL; + break; + } + ++i; + } + DEBUG_MSG (("**Order: %s, %s, %s", strings[0], strings[1], strings[2])); + DEBUG_MSG (("**Sample date in this locale: '%s'", buf)); + } +#endif + } + + g_date_fill_parse_tokens (str, pt); +} + +static guint +convert_twodigit_year (guint y) +{ + if (using_twodigit_years && y < 100) + { + guint two = twodigit_start_year % 100; + guint century = (twodigit_start_year / 100) * 100; + + if (y < two) + century += 100; + + y += century; + } + return y; +} + +/** + * g_date_set_parse: + * @date: a #GDate to fill in + * @str: string to parse + * + * Parses a user-inputted string @str, and try to figure out what date it + * represents, taking the [current locale][setlocale] into account. If the + * string is successfully parsed, the date will be valid after the call. + * Otherwise, it will be invalid. You should check using g_date_valid() + * to see whether the parsing succeeded. + * + * This function is not appropriate for file formats and the like; it + * isn't very precise, and its exact behavior varies with the locale. + * It's intended to be a heuristic routine that guesses what the user + * means by a given string (and it does work pretty well in that + * capacity). + */ +void +g_date_set_parse (GDate *d, + const gchar *str) +{ + GDateParseTokens pt; + guint m = G_DATE_BAD_MONTH, day = G_DATE_BAD_DAY, y = G_DATE_BAD_YEAR; + gsize str_len; + + g_return_if_fail (d != NULL); + + /* set invalid */ + g_date_clear (d, 1); + + /* Anything longer than this is ridiculous and could take a while to normalize. + * This limit is chosen arbitrarily. */ + str_len = strlen (str); + if (str_len > 200) + return; + + /* The input has to be valid UTF-8. */ + if (!g_utf8_validate_len (str, str_len, NULL)) + return; + + G_LOCK (g_date_global); + + g_date_prepare_to_parse (str, &pt); + + DEBUG_MSG (("Found %d ints, '%d' '%d' '%d' and written out month %d", + pt.num_ints, pt.n[0], pt.n[1], pt.n[2], pt.month)); + + + if (pt.num_ints == 4) + { + G_UNLOCK (g_date_global); + return; /* presumably a typo; bail out. */ + } + + if (pt.num_ints > 1) + { + int i = 0; + int j = 0; + + g_assert (pt.num_ints < 4); /* i.e., it is 2 or 3 */ + + while (i < pt.num_ints && j < 3) + { + switch (dmy_order[j]) + { + case G_DATE_MONTH: + { + if (pt.num_ints == 2 && pt.month != G_DATE_BAD_MONTH) + { + m = pt.month; + ++j; /* skip months, but don't skip this number */ + continue; + } + else + m = pt.n[i]; + } + break; + case G_DATE_DAY: + { + if (pt.num_ints == 2 && pt.month == G_DATE_BAD_MONTH) + { + day = 1; + ++j; /* skip days, since we may have month/year */ + continue; + } + day = pt.n[i]; + } + break; + case G_DATE_YEAR: + { + y = pt.n[i]; + + if (locale_era_adjust != 0) + { + y += locale_era_adjust; + } + + y = convert_twodigit_year (y); + } + break; + default: + break; + } + + ++i; + ++j; + } + + + if (pt.num_ints == 3 && !g_date_valid_dmy (day, m, y)) + { + /* Try YYYY MM DD */ + y = pt.n[0]; + m = pt.n[1]; + day = pt.n[2]; + + if (using_twodigit_years && y < 100) + y = G_DATE_BAD_YEAR; /* avoids ambiguity */ + } + else if (pt.num_ints == 2) + { + if (m == G_DATE_BAD_MONTH && pt.month != G_DATE_BAD_MONTH) + m = pt.month; + } + } + else if (pt.num_ints == 1) + { + if (pt.month != G_DATE_BAD_MONTH) + { + /* Month name and year? */ + m = pt.month; + day = 1; + y = pt.n[0]; + } + else + { + /* Try yyyymmdd and yymmdd */ + + m = (pt.n[0]/100) % 100; + day = pt.n[0] % 100; + y = pt.n[0]/10000; + + y = convert_twodigit_year (y); + } + } + + /* See if we got anything valid out of all this. */ + /* y < 8000 is to catch 19998 style typos; the library is OK up to 65535 or so */ + if (y < 8000 && g_date_valid_dmy (day, m, y)) + { + d->month = m; + d->day = day; + d->year = y; + d->dmy = TRUE; + } +#ifdef G_ENABLE_DEBUG + else + { + DEBUG_MSG (("Rejected DMY %u %u %u", day, m, y)); + } +#endif + G_UNLOCK (g_date_global); +} + +/** + * g_date_set_time_t: + * @date: a #GDate + * @timet: time_t value to set + * + * Sets the value of a date to the date corresponding to a time + * specified as a time_t. The time to date conversion is done using + * the user's current timezone. + * + * To set the value of a date to the current day, you could write: + * |[ + * time_t now = time (NULL); + * if (now == (time_t) -1) + * // handle the error + * g_date_set_time_t (date, now); + * ]| + * + * Since: 2.10 + */ +void +g_date_set_time_t (GDate *date, + time_t timet) +{ + struct tm tm; + + g_return_if_fail (date != NULL); + +#ifdef HAVE_LOCALTIME_R + localtime_r (&timet, &tm); +#else + { + struct tm *ptm = localtime (&timet); + + if (ptm == NULL) + { + /* Happens at least in Microsoft's C library if you pass a + * negative time_t. Use 2000-01-01 as default date. + */ +#ifndef G_DISABLE_CHECKS + g_return_if_fail_warning (G_LOG_DOMAIN, "g_date_set_time", "ptm != NULL"); +#endif + + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_year = 100; + } + else + memcpy ((void *) &tm, (void *) ptm, sizeof(struct tm)); + } +#endif + + date->julian = FALSE; + + date->month = tm.tm_mon + 1; + date->day = tm.tm_mday; + date->year = tm.tm_year + 1900; + + g_return_if_fail (g_date_valid_dmy (date->day, date->month, date->year)); + + date->dmy = TRUE; +} + + +/** + * g_date_set_time: + * @date: a #GDate. + * @time_: #GTime value to set. + * + * Sets the value of a date from a #GTime value. + * The time to date conversion is done using the user's current timezone. + * + * Deprecated: 2.10: Use g_date_set_time_t() instead. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +void +g_date_set_time (GDate *date, + GTime time_) +{ + g_date_set_time_t (date, (time_t) time_); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_date_set_time_val: + * @date: a #GDate + * @timeval: #GTimeVal value to set + * + * Sets the value of a date from a #GTimeVal value. Note that the + * @tv_usec member is ignored, because #GDate can't make use of the + * additional precision. + * + * The time to date conversion is done using the user's current timezone. + * + * Since: 2.10 + * Deprecated: 2.62: #GTimeVal is not year-2038-safe. Use g_date_set_time_t() + * instead. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +void +g_date_set_time_val (GDate *date, + GTimeVal *timeval) +{ + g_date_set_time_t (date, (time_t) timeval->tv_sec); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_date_set_month: + * @date: a #GDate + * @month: month to set + * + * Sets the month of the year for a #GDate. If the resulting + * day-month-year triplet is invalid, the date will be invalid. + */ +void +g_date_set_month (GDate *d, + GDateMonth m) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_month (m)); + + if (d->julian && !d->dmy) g_date_update_dmy(d); + d->julian = FALSE; + + d->month = m; + + if (g_date_valid_dmy (d->day, d->month, d->year)) + d->dmy = TRUE; + else + d->dmy = FALSE; +} + +/** + * g_date_set_day: + * @date: a #GDate + * @day: day to set + * + * Sets the day of the month for a #GDate. If the resulting + * day-month-year triplet is invalid, the date will be invalid. + */ +void +g_date_set_day (GDate *d, + GDateDay day) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_day (day)); + + if (d->julian && !d->dmy) g_date_update_dmy(d); + d->julian = FALSE; + + d->day = day; + + if (g_date_valid_dmy (d->day, d->month, d->year)) + d->dmy = TRUE; + else + d->dmy = FALSE; +} + +/** + * g_date_set_year: + * @date: a #GDate + * @year: year to set + * + * Sets the year for a #GDate. If the resulting day-month-year + * triplet is invalid, the date will be invalid. + */ +void +g_date_set_year (GDate *d, + GDateYear y) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_year (y)); + + if (d->julian && !d->dmy) g_date_update_dmy(d); + d->julian = FALSE; + + d->year = y; + + if (g_date_valid_dmy (d->day, d->month, d->year)) + d->dmy = TRUE; + else + d->dmy = FALSE; +} + +/** + * g_date_set_dmy: + * @date: a #GDate + * @day: day + * @month: month + * @y: year + * + * Sets the value of a #GDate from a day, month, and year. + * The day-month-year triplet must be valid; if you aren't + * sure it is, call g_date_valid_dmy() to check before you + * set it. + */ +void +g_date_set_dmy (GDate *d, + GDateDay day, + GDateMonth m, + GDateYear y) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_dmy (day, m, y)); + + d->julian = FALSE; + + d->month = m; + d->day = day; + d->year = y; + + d->dmy = TRUE; +} + +/** + * g_date_set_julian: + * @date: a #GDate + * @julian_date: Julian day number (days since January 1, Year 1) + * + * Sets the value of a #GDate from a Julian day number. + */ +void +g_date_set_julian (GDate *d, + guint32 j) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_julian (j)); + + d->julian_days = j; + d->julian = TRUE; + d->dmy = FALSE; +} + +/** + * g_date_is_first_of_month: + * @date: a #GDate to check + * + * Returns %TRUE if the date is on the first of a month. + * The date must be valid. + * + * Returns: %TRUE if the date is the first of the month + */ +gboolean +g_date_is_first_of_month (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), FALSE); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, FALSE); + + if (d->day == 1) return TRUE; + else return FALSE; +} + +/** + * g_date_is_last_of_month: + * @date: a #GDate to check + * + * Returns %TRUE if the date is the last day of the month. + * The date must be valid. + * + * Returns: %TRUE if the date is the last day of the month + */ +gboolean +g_date_is_last_of_month (const GDate *d) +{ + gint idx; + + g_return_val_if_fail (g_date_valid (d), FALSE); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, FALSE); + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + if (d->day == days_in_months[idx][d->month]) return TRUE; + else return FALSE; +} + +/** + * g_date_add_days: + * @date: a #GDate to increment + * @n_days: number of days to move the date forward + * + * Increments a date some number of days. + * To move forward by weeks, add weeks*7 days. + * The date must be valid. + */ +void +g_date_add_days (GDate *d, + guint ndays) +{ + g_return_if_fail (g_date_valid (d)); + + if (!d->julian) + g_date_update_julian (d); + + g_return_if_fail (d->julian); + g_return_if_fail (ndays <= G_MAXUINT32 - d->julian_days); + + d->julian_days += ndays; + d->dmy = FALSE; +} + +/** + * g_date_subtract_days: + * @date: a #GDate to decrement + * @n_days: number of days to move + * + * Moves a date some number of days into the past. + * To move by weeks, just move by weeks*7 days. + * The date must be valid. + */ +void +g_date_subtract_days (GDate *d, + guint ndays) +{ + g_return_if_fail (g_date_valid (d)); + + if (!d->julian) + g_date_update_julian (d); + + g_return_if_fail (d->julian); + g_return_if_fail (d->julian_days > ndays); + + d->julian_days -= ndays; + d->dmy = FALSE; +} + +/** + * g_date_add_months: + * @date: a #GDate to increment + * @n_months: number of months to move forward + * + * Increments a date by some number of months. + * If the day of the month is greater than 28, + * this routine may change the day of the month + * (because the destination month may not have + * the current day in it). The date must be valid. + */ +void +g_date_add_months (GDate *d, + guint nmonths) +{ + guint years, months; + gint idx; + + g_return_if_fail (g_date_valid (d)); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy != 0); + g_return_if_fail (nmonths <= G_MAXUINT - (d->month - 1)); + + nmonths += d->month - 1; + + years = nmonths/12; + months = nmonths%12; + + g_return_if_fail (years <= (guint) (G_MAXUINT16 - d->year)); + + d->month = months + 1; + d->year += years; + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + if (d->day > days_in_months[idx][d->month]) + d->day = days_in_months[idx][d->month]; + + d->julian = FALSE; + + g_return_if_fail (g_date_valid (d)); +} + +/** + * g_date_subtract_months: + * @date: a #GDate to decrement + * @n_months: number of months to move + * + * Moves a date some number of months into the past. + * If the current day of the month doesn't exist in + * the destination month, the day of the month + * may change. The date must be valid. + */ +void +g_date_subtract_months (GDate *d, + guint nmonths) +{ + guint years, months; + gint idx; + + g_return_if_fail (g_date_valid (d)); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy != 0); + + years = nmonths/12; + months = nmonths%12; + + g_return_if_fail (d->year > years); + + d->year -= years; + + if (d->month > months) d->month -= months; + else + { + months -= d->month; + d->month = 12 - months; + d->year -= 1; + } + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + if (d->day > days_in_months[idx][d->month]) + d->day = days_in_months[idx][d->month]; + + d->julian = FALSE; + + g_return_if_fail (g_date_valid (d)); +} + +/** + * g_date_add_years: + * @date: a #GDate to increment + * @n_years: number of years to move forward + * + * Increments a date by some number of years. + * If the date is February 29, and the destination + * year is not a leap year, the date will be changed + * to February 28. The date must be valid. + */ +void +g_date_add_years (GDate *d, + guint nyears) +{ + g_return_if_fail (g_date_valid (d)); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy != 0); + g_return_if_fail (nyears <= (guint) (G_MAXUINT16 - d->year)); + + d->year += nyears; + + if (d->month == 2 && d->day == 29) + { + if (!g_date_is_leap_year (d->year)) + d->day = 28; + } + + d->julian = FALSE; +} + +/** + * g_date_subtract_years: + * @date: a #GDate to decrement + * @n_years: number of years to move + * + * Moves a date some number of years into the past. + * If the current day doesn't exist in the destination + * year (i.e. it's February 29 and you move to a non-leap-year) + * then the day is changed to February 29. The date + * must be valid. + */ +void +g_date_subtract_years (GDate *d, + guint nyears) +{ + g_return_if_fail (g_date_valid (d)); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy != 0); + g_return_if_fail (d->year > nyears); + + d->year -= nyears; + + if (d->month == 2 && d->day == 29) + { + if (!g_date_is_leap_year (d->year)) + d->day = 28; + } + + d->julian = FALSE; +} + +/** + * g_date_is_leap_year: + * @year: year to check + * + * Returns %TRUE if the year is a leap year. + * + * For the purposes of this function, leap year is every year + * divisible by 4 unless that year is divisible by 100. If it + * is divisible by 100 it would be a leap year only if that year + * is also divisible by 400. + * + * Returns: %TRUE if the year is a leap year + */ +gboolean +g_date_is_leap_year (GDateYear year) +{ + g_return_val_if_fail (g_date_valid_year (year), FALSE); + + return ( (((year % 4) == 0) && ((year % 100) != 0)) || + (year % 400) == 0 ); +} + +/** + * g_date_get_days_in_month: + * @month: month + * @year: year + * + * Returns the number of days in a month, taking leap + * years into account. + * + * Returns: number of days in @month during the @year + */ +guint8 +g_date_get_days_in_month (GDateMonth month, + GDateYear year) +{ + gint idx; + + g_return_val_if_fail (g_date_valid_year (year), 0); + g_return_val_if_fail (g_date_valid_month (month), 0); + + idx = g_date_is_leap_year (year) ? 1 : 0; + + return days_in_months[idx][month]; +} + +/** + * g_date_get_monday_weeks_in_year: + * @year: a year + * + * Returns the number of weeks in the year, where weeks + * are taken to start on Monday. Will be 52 or 53. The + * date must be valid. (Years always have 52 7-day periods, + * plus 1 or 2 extra days depending on whether it's a leap + * year. This function is basically telling you how many + * Mondays are in the year, i.e. there are 53 Mondays if + * one of the extra days happens to be a Monday.) + * + * Returns: number of Mondays in the year + */ +guint8 +g_date_get_monday_weeks_in_year (GDateYear year) +{ + GDate d; + + g_return_val_if_fail (g_date_valid_year (year), 0); + + g_date_clear (&d, 1); + g_date_set_dmy (&d, 1, 1, year); + if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53; + g_date_set_dmy (&d, 31, 12, year); + if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53; + if (g_date_is_leap_year (year)) + { + g_date_set_dmy (&d, 2, 1, year); + if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53; + g_date_set_dmy (&d, 30, 12, year); + if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53; + } + return 52; +} + +/** + * g_date_get_sunday_weeks_in_year: + * @year: year to count weeks in + * + * Returns the number of weeks in the year, where weeks + * are taken to start on Sunday. Will be 52 or 53. The + * date must be valid. (Years always have 52 7-day periods, + * plus 1 or 2 extra days depending on whether it's a leap + * year. This function is basically telling you how many + * Sundays are in the year, i.e. there are 53 Sundays if + * one of the extra days happens to be a Sunday.) + * + * Returns: the number of weeks in @year + */ +guint8 +g_date_get_sunday_weeks_in_year (GDateYear year) +{ + GDate d; + + g_return_val_if_fail (g_date_valid_year (year), 0); + + g_date_clear (&d, 1); + g_date_set_dmy (&d, 1, 1, year); + if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53; + g_date_set_dmy (&d, 31, 12, year); + if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53; + if (g_date_is_leap_year (year)) + { + g_date_set_dmy (&d, 2, 1, year); + if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53; + g_date_set_dmy (&d, 30, 12, year); + if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53; + } + return 52; +} + +/** + * g_date_compare: + * @lhs: first date to compare + * @rhs: second date to compare + * + * qsort()-style comparison function for dates. + * Both dates must be valid. + * + * Returns: 0 for equal, less than zero if @lhs is less than @rhs, + * greater than zero if @lhs is greater than @rhs + */ +gint +g_date_compare (const GDate *lhs, + const GDate *rhs) +{ + g_return_val_if_fail (lhs != NULL, 0); + g_return_val_if_fail (rhs != NULL, 0); + g_return_val_if_fail (g_date_valid (lhs), 0); + g_return_val_if_fail (g_date_valid (rhs), 0); + + /* Remember the self-comparison case! I think it works right now. */ + + while (TRUE) + { + if (lhs->julian && rhs->julian) + { + if (lhs->julian_days < rhs->julian_days) return -1; + else if (lhs->julian_days > rhs->julian_days) return 1; + else return 0; + } + else if (lhs->dmy && rhs->dmy) + { + if (lhs->year < rhs->year) return -1; + else if (lhs->year > rhs->year) return 1; + else + { + if (lhs->month < rhs->month) return -1; + else if (lhs->month > rhs->month) return 1; + else + { + if (lhs->day < rhs->day) return -1; + else if (lhs->day > rhs->day) return 1; + else return 0; + } + + } + + } + else + { + if (!lhs->julian) g_date_update_julian (lhs); + if (!rhs->julian) g_date_update_julian (rhs); + g_return_val_if_fail (lhs->julian, 0); + g_return_val_if_fail (rhs->julian, 0); + } + + } + return 0; /* warnings */ +} + +/** + * g_date_to_struct_tm: + * @date: a #GDate to set the struct tm from + * @tm: (not nullable): struct tm to fill + * + * Fills in the date-related bits of a struct tm using the @date value. + * Initializes the non-date parts with something safe but meaningless. + */ +void +g_date_to_struct_tm (const GDate *d, + struct tm *tm) +{ + GDateWeekday day; + + g_return_if_fail (g_date_valid (d)); + g_return_if_fail (tm != NULL); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy != 0); + + /* zero all the irrelevant fields to be sure they're valid */ + + /* On Linux and maybe other systems, there are weird non-POSIX + * fields on the end of struct tm that choke strftime if they + * contain garbage. So we need to 0 the entire struct, not just the + * fields we know to exist. + */ + + memset (tm, 0x0, sizeof (struct tm)); + + tm->tm_mday = d->day; + tm->tm_mon = d->month - 1; /* 0-11 goes in tm */ + tm->tm_year = ((int)d->year) - 1900; /* X/Open says tm_year can be negative */ + + day = g_date_get_weekday (d); + if (day == 7) day = 0; /* struct tm wants days since Sunday, so Sunday is 0 */ + + tm->tm_wday = (int)day; + + tm->tm_yday = g_date_get_day_of_year (d) - 1; /* 0 to 365 */ + tm->tm_isdst = -1; /* -1 means "information not available" */ +} + +/** + * g_date_clamp: + * @date: a #GDate to clamp + * @min_date: minimum accepted value for @date + * @max_date: maximum accepted value for @date + * + * If @date is prior to @min_date, sets @date equal to @min_date. + * If @date falls after @max_date, sets @date equal to @max_date. + * Otherwise, @date is unchanged. + * Either of @min_date and @max_date may be %NULL. + * All non-%NULL dates must be valid. + */ +void +g_date_clamp (GDate *date, + const GDate *min_date, + const GDate *max_date) +{ + g_return_if_fail (g_date_valid (date)); + + if (min_date != NULL) + g_return_if_fail (g_date_valid (min_date)); + + if (max_date != NULL) + g_return_if_fail (g_date_valid (max_date)); + + if (min_date != NULL && max_date != NULL) + g_return_if_fail (g_date_compare (min_date, max_date) <= 0); + + if (min_date && g_date_compare (date, min_date) < 0) + *date = *min_date; + + if (max_date && g_date_compare (max_date, date) < 0) + *date = *max_date; +} + +/** + * g_date_order: + * @date1: the first date + * @date2: the second date + * + * Checks if @date1 is less than or equal to @date2, + * and swap the values if this is not the case. + */ +void +g_date_order (GDate *date1, + GDate *date2) +{ + g_return_if_fail (g_date_valid (date1)); + g_return_if_fail (g_date_valid (date2)); + + if (g_date_compare (date1, date2) > 0) + { + GDate tmp = *date1; + *date1 = *date2; + *date2 = tmp; + } +} + +#ifdef G_OS_WIN32 +static gboolean +append_month_name (GArray *result, + LCID lcid, + SYSTEMTIME *systemtime, + gboolean abbreviated, + gboolean alternative) +{ + int n; + WORD base; + LPCWSTR lpFormat; + + if (alternative) + { + base = abbreviated ? LOCALE_SABBREVMONTHNAME1 : LOCALE_SMONTHNAME1; + n = GetLocaleInfoW (lcid, base + systemtime->wMonth - 1, NULL, 0); + if (n == 0) + return FALSE; + + g_array_set_size (result, result->len + n); + if (GetLocaleInfoW (lcid, base + systemtime->wMonth - 1, + ((wchar_t *) result->data) + result->len - n, n) != n) + return FALSE; + + g_array_set_size (result, result->len - 1); + } + else + { + /* According to MSDN, this is the correct method to obtain + * the form of the month name used when formatting a full + * date; it must be a genitive case in some languages. + * + * (n == 0) indicates an error, whereas (n < 2) is something we’d never + * expect from the given format string, and would break the subsequent code. + */ + lpFormat = abbreviated ? L"ddMMM" : L"ddMMMM"; + n = GetDateFormatW (lcid, 0, systemtime, lpFormat, NULL, 0); + if (n < 2) + return FALSE; + + g_array_set_size (result, result->len + n); + if (GetDateFormatW (lcid, 0, systemtime, lpFormat, + ((wchar_t *) result->data) + result->len - n, n) != n) + return FALSE; + + /* We have obtained a day number as two digits and the month name. + * Now let's get rid of those two digits: overwrite them with the + * month name. + */ + memmove (((wchar_t *) result->data) + result->len - n, + ((wchar_t *) result->data) + result->len - n + 2, + (n - 2) * sizeof (wchar_t)); + g_array_set_size (result, result->len - 3); + } + + return TRUE; +} + +static gsize +win32_strftime_helper (const GDate *d, + const gchar *format, + const struct tm *tm, + gchar *s, + gsize slen) +{ + SYSTEMTIME systemtime; + TIME_ZONE_INFORMATION tzinfo; + LCID lcid; + int n, k; + GArray *result; + const gchar *p; + gunichar c, modifier; + const wchar_t digits[] = L"0123456789"; + gchar *convbuf; + glong convlen = 0; + gsize retval; + + systemtime.wYear = tm->tm_year + 1900; + systemtime.wMonth = tm->tm_mon + 1; + systemtime.wDayOfWeek = tm->tm_wday; + systemtime.wDay = tm->tm_mday; + systemtime.wHour = tm->tm_hour; + systemtime.wMinute = tm->tm_min; + systemtime.wSecond = tm->tm_sec; + systemtime.wMilliseconds = 0; + + lcid = GetThreadLocale (); + result = g_array_sized_new (FALSE, FALSE, sizeof (wchar_t), MAX (128, strlen (format) * 2)); + + p = format; + while (*p) + { + c = g_utf8_get_char (p); + if (c == '%') + { + p = g_utf8_next_char (p); + if (!*p) + { + s[0] = '\0'; + g_array_free (result, TRUE); + + return 0; + } + + modifier = '\0'; + c = g_utf8_get_char (p); + if (c == 'E' || c == 'O') + { + /* "%OB", "%Ob", and "%Oh" are supported, ignore other modified + * conversion specifiers for now. + */ + modifier = c; + p = g_utf8_next_char (p); + if (!*p) + { + s[0] = '\0'; + g_array_free (result, TRUE); + + return 0; + } + + c = g_utf8_get_char (p); + } + + switch (c) + { + case 'a': + if (systemtime.wDayOfWeek == 0) + k = 6; + else + k = systemtime.wDayOfWeek - 1; + n = GetLocaleInfoW (lcid, LOCALE_SABBREVDAYNAME1+k, NULL, 0); + g_array_set_size (result, result->len + n); + GetLocaleInfoW (lcid, LOCALE_SABBREVDAYNAME1+k, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + break; + case 'A': + if (systemtime.wDayOfWeek == 0) + k = 6; + else + k = systemtime.wDayOfWeek - 1; + n = GetLocaleInfoW (lcid, LOCALE_SDAYNAME1+k, NULL, 0); + g_array_set_size (result, result->len + n); + GetLocaleInfoW (lcid, LOCALE_SDAYNAME1+k, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + break; + case 'b': + case 'h': + if (!append_month_name (result, lcid, &systemtime, TRUE, modifier == 'O')) + { + /* Ignore the error; this placeholder will be replaced with nothing */ + } + break; + case 'B': + if (!append_month_name (result, lcid, &systemtime, FALSE, modifier == 'O')) + { + /* Ignore the error; this placeholder will be replaced with nothing */ + } + break; + case 'c': + n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetDateFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + g_array_append_vals (result, L" ", 1); + n = GetTimeFormatW (lcid, 0, &systemtime, NULL, NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetTimeFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'C': + g_array_append_vals (result, digits + systemtime.wYear/1000, 1); + g_array_append_vals (result, digits + (systemtime.wYear/1000)%10, 1); + break; + case 'd': + g_array_append_vals (result, digits + systemtime.wDay/10, 1); + g_array_append_vals (result, digits + systemtime.wDay%10, 1); + break; + case 'D': + g_array_append_vals (result, digits + systemtime.wMonth/10, 1); + g_array_append_vals (result, digits + systemtime.wMonth%10, 1); + g_array_append_vals (result, L"/", 1); + g_array_append_vals (result, digits + systemtime.wDay/10, 1); + g_array_append_vals (result, digits + systemtime.wDay%10, 1); + g_array_append_vals (result, L"/", 1); + g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1); + g_array_append_vals (result, digits + systemtime.wYear%10, 1); + break; + case 'e': + if (systemtime.wDay >= 10) + g_array_append_vals (result, digits + systemtime.wDay/10, 1); + else + g_array_append_vals (result, L" ", 1); + g_array_append_vals (result, digits + systemtime.wDay%10, 1); + break; + + /* A GDate has no time fields, so for now we can + * hardcode all time conversions into zeros (or 12 for + * %I). The alternative code snippets in the #else + * branches are here ready to be taken into use when + * needed by a g_strftime() or g_date_and_time_format() + * or whatever. + */ + case 'H': +#if 1 + g_array_append_vals (result, L"00", 2); +#else + g_array_append_vals (result, digits + systemtime.wHour/10, 1); + g_array_append_vals (result, digits + systemtime.wHour%10, 1); +#endif + break; + case 'I': +#if 1 + g_array_append_vals (result, L"12", 2); +#else + if (systemtime.wHour == 0) + g_array_append_vals (result, L"12", 2); + else + { + g_array_append_vals (result, digits + (systemtime.wHour%12)/10, 1); + g_array_append_vals (result, digits + (systemtime.wHour%12)%10, 1); + } +#endif + break; + case 'j': + g_array_append_vals (result, digits + (tm->tm_yday+1)/100, 1); + g_array_append_vals (result, digits + ((tm->tm_yday+1)/10)%10, 1); + g_array_append_vals (result, digits + (tm->tm_yday+1)%10, 1); + break; + case 'm': + g_array_append_vals (result, digits + systemtime.wMonth/10, 1); + g_array_append_vals (result, digits + systemtime.wMonth%10, 1); + break; + case 'M': +#if 1 + g_array_append_vals (result, L"00", 2); +#else + g_array_append_vals (result, digits + systemtime.wMinute/10, 1); + g_array_append_vals (result, digits + systemtime.wMinute%10, 1); +#endif + break; + case 'n': + g_array_append_vals (result, L"\n", 1); + break; + case 'p': + n = GetTimeFormatW (lcid, 0, &systemtime, L"tt", NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetTimeFormatW (lcid, 0, &systemtime, L"tt", ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'r': + /* This is a rather odd format. Hard to say what to do. + * Let's always use the POSIX %I:%M:%S %p + */ +#if 1 + g_array_append_vals (result, L"12:00:00", 8); +#else + if (systemtime.wHour == 0) + g_array_append_vals (result, L"12", 2); + else + { + g_array_append_vals (result, digits + (systemtime.wHour%12)/10, 1); + g_array_append_vals (result, digits + (systemtime.wHour%12)%10, 1); + } + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wMinute/10, 1); + g_array_append_vals (result, digits + systemtime.wMinute%10, 1); + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wSecond/10, 1); + g_array_append_vals (result, digits + systemtime.wSecond%10, 1); + g_array_append_vals (result, L" ", 1); +#endif + n = GetTimeFormatW (lcid, 0, &systemtime, L"tt", NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetTimeFormatW (lcid, 0, &systemtime, L"tt", ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'R': +#if 1 + g_array_append_vals (result, L"00:00", 5); +#else + g_array_append_vals (result, digits + systemtime.wHour/10, 1); + g_array_append_vals (result, digits + systemtime.wHour%10, 1); + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wMinute/10, 1); + g_array_append_vals (result, digits + systemtime.wMinute%10, 1); +#endif + break; + case 'S': +#if 1 + g_array_append_vals (result, L"00", 2); +#else + g_array_append_vals (result, digits + systemtime.wSecond/10, 1); + g_array_append_vals (result, digits + systemtime.wSecond%10, 1); +#endif + break; + case 't': + g_array_append_vals (result, L"\t", 1); + break; + case 'T': +#if 1 + g_array_append_vals (result, L"00:00:00", 8); +#else + g_array_append_vals (result, digits + systemtime.wHour/10, 1); + g_array_append_vals (result, digits + systemtime.wHour%10, 1); + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wMinute/10, 1); + g_array_append_vals (result, digits + systemtime.wMinute%10, 1); + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wSecond/10, 1); + g_array_append_vals (result, digits + systemtime.wSecond%10, 1); +#endif + break; + case 'u': + if (systemtime.wDayOfWeek == 0) + g_array_append_vals (result, L"7", 1); + else + g_array_append_vals (result, digits + systemtime.wDayOfWeek, 1); + break; + case 'U': + n = g_date_get_sunday_week_of_year (d); + g_array_append_vals (result, digits + n/10, 1); + g_array_append_vals (result, digits + n%10, 1); + break; + case 'V': + n = g_date_get_iso8601_week_of_year (d); + g_array_append_vals (result, digits + n/10, 1); + g_array_append_vals (result, digits + n%10, 1); + break; + case 'w': + g_array_append_vals (result, digits + systemtime.wDayOfWeek, 1); + break; + case 'W': + n = g_date_get_monday_week_of_year (d); + g_array_append_vals (result, digits + n/10, 1); + g_array_append_vals (result, digits + n%10, 1); + break; + case 'x': + n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetDateFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'X': + n = GetTimeFormatW (lcid, 0, &systemtime, NULL, NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetTimeFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'y': + g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1); + g_array_append_vals (result, digits + systemtime.wYear%10, 1); + break; + case 'Y': + g_array_append_vals (result, digits + systemtime.wYear/1000, 1); + g_array_append_vals (result, digits + (systemtime.wYear/100)%10, 1); + g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1); + g_array_append_vals (result, digits + systemtime.wYear%10, 1); + break; + case 'Z': + n = GetTimeZoneInformation (&tzinfo); + if (n == TIME_ZONE_ID_UNKNOWN || n == TIME_ZONE_ID_STANDARD) + g_array_append_vals (result, tzinfo.StandardName, wcslen (tzinfo.StandardName)); + else if (n == TIME_ZONE_ID_DAYLIGHT) + g_array_append_vals (result, tzinfo.DaylightName, wcslen (tzinfo.DaylightName)); + break; + case '%': + g_array_append_vals (result, L"%", 1); + break; + } + } + else if (c <= 0xFFFF) + { + wchar_t wc = c; + g_array_append_vals (result, &wc, 1); + } + else + { + glong nwc; + wchar_t *ws; + + ws = g_ucs4_to_utf16 (&c, 1, NULL, &nwc, NULL); + g_array_append_vals (result, ws, nwc); + g_free (ws); + } + p = g_utf8_next_char (p); + } + + convbuf = g_utf16_to_utf8 ((wchar_t *) result->data, result->len, NULL, &convlen, NULL); + g_array_free (result, TRUE); + + if (!convbuf) + { + s[0] = '\0'; + return 0; + } + + g_assert (convlen >= 0); + if ((gsize) convlen >= slen) + { + /* Ensure only whole characters are copied into the buffer. */ + gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen); + g_assert (end != NULL); + convlen = end - convbuf; + + /* Return 0 because the buffer isn't large enough. */ + retval = 0; + } + else + retval = convlen; + + memcpy (s, convbuf, convlen); + s[convlen] = '\0'; + g_free (convbuf); + + return retval; +} + +#endif + +/** + * g_date_strftime: + * @s: destination buffer + * @slen: buffer size + * @format: format string + * @date: valid #GDate + * + * Generates a printed representation of the date, in a + * [locale][setlocale]-specific way. + * Works just like the platform's C library strftime() function, + * but only accepts date-related formats; time-related formats + * give undefined results. Date must be valid. Unlike strftime() + * (which uses the locale encoding), works on a UTF-8 format + * string and stores a UTF-8 result. + * + * This function does not provide any conversion specifiers in + * addition to those implemented by the platform's C library. + * For example, don't expect that using g_date_strftime() would + * make the \%F provided by the C99 strftime() work on Windows + * where the C library only complies to C89. + * + * Returns: number of characters written to the buffer, or 0 the buffer was too small + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +gsize +g_date_strftime (gchar *s, + gsize slen, + const gchar *format, + const GDate *d) +{ + struct tm tm; +#ifndef G_OS_WIN32 + gsize locale_format_len = 0; + gchar *locale_format; + gsize tmplen; + gchar *tmpbuf; + gsize tmpbufsize; + gsize convlen = 0; + gchar *convbuf; + GError *error = NULL; + gsize retval; +#endif + + g_return_val_if_fail (g_date_valid (d), 0); + g_return_val_if_fail (slen > 0, 0); + g_return_val_if_fail (format != NULL, 0); + g_return_val_if_fail (s != NULL, 0); + + g_date_to_struct_tm (d, &tm); + +#ifdef G_OS_WIN32 + if (!g_utf8_validate (format, -1, NULL)) + { + s[0] = '\0'; + return 0; + } + return win32_strftime_helper (d, format, &tm, s, slen); +#else + + locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error); + + if (error) + { + g_warning (G_STRLOC "Error converting format to locale encoding: %s", error->message); + g_error_free (error); + + s[0] = '\0'; + return 0; + } + + tmpbufsize = MAX (128, locale_format_len * 2); + while (TRUE) + { + tmpbuf = g_malloc (tmpbufsize); + + /* Set the first byte to something other than '\0', to be able to + * recognize whether strftime actually failed or just returned "". + */ + tmpbuf[0] = '\1'; + tmplen = strftime (tmpbuf, tmpbufsize, locale_format, &tm); + + if (tmplen == 0 && tmpbuf[0] != '\0') + { + g_free (tmpbuf); + tmpbufsize *= 2; + + if (tmpbufsize > 65536) + { + g_warning (G_STRLOC "Maximum buffer size for g_date_strftime exceeded: giving up"); + g_free (locale_format); + + s[0] = '\0'; + return 0; + } + } + else + break; + } + g_free (locale_format); + + convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error); + g_free (tmpbuf); + + if (error) + { + g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s", error->message); + g_error_free (error); + + s[0] = '\0'; + return 0; + } + + if (slen <= convlen) + { + /* Ensure only whole characters are copied into the buffer. + */ + gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen); + g_assert (end != NULL); + convlen = end - convbuf; + + /* Return 0 because the buffer isn't large enough. + */ + retval = 0; + } + else + retval = convlen; + + memcpy (s, convbuf, convlen); + s[convlen] = '\0'; + g_free (convbuf); + + return retval; +#endif +} + +#pragma GCC diagnostic pop diff --git a/glib/gdate.h b/glib/gdate.h new file mode 100644 index 0000000..65fe811 --- /dev/null +++ b/glib/gdate.h @@ -0,0 +1,307 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_DATE_H__ +#define __G_DATE_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +#include +#include + +G_BEGIN_DECLS + +/* GDate + * + * Date calculations (not time for now, to be resolved). These are a + * mutant combination of Steffen Beyer's DateCalc routines + * (http://www.perl.com/CPAN/authors/id/STBEY/) and Jon Trowbridge's + * date routines (written for in-house software). Written by Havoc + * Pennington + */ + +typedef gint32 GTime GLIB_DEPRECATED_TYPE_IN_2_62_FOR(GDateTime); +typedef guint16 GDateYear; +typedef guint8 GDateDay; /* day of the month */ +typedef struct _GDate GDate; + +/* enum used to specify order of appearance in parsed date strings */ +typedef enum +{ + G_DATE_DAY = 0, + G_DATE_MONTH = 1, + G_DATE_YEAR = 2 +} GDateDMY; + +/* actual week and month values */ +typedef enum +{ + G_DATE_BAD_WEEKDAY = 0, + G_DATE_MONDAY = 1, + G_DATE_TUESDAY = 2, + G_DATE_WEDNESDAY = 3, + G_DATE_THURSDAY = 4, + G_DATE_FRIDAY = 5, + G_DATE_SATURDAY = 6, + G_DATE_SUNDAY = 7 +} GDateWeekday; +typedef enum +{ + G_DATE_BAD_MONTH = 0, + G_DATE_JANUARY = 1, + G_DATE_FEBRUARY = 2, + G_DATE_MARCH = 3, + G_DATE_APRIL = 4, + G_DATE_MAY = 5, + G_DATE_JUNE = 6, + G_DATE_JULY = 7, + G_DATE_AUGUST = 8, + G_DATE_SEPTEMBER = 9, + G_DATE_OCTOBER = 10, + G_DATE_NOVEMBER = 11, + G_DATE_DECEMBER = 12 +} GDateMonth; + +#define G_DATE_BAD_JULIAN 0U +#define G_DATE_BAD_DAY 0U +#define G_DATE_BAD_YEAR 0U + +/* Note: directly manipulating structs is generally a bad idea, but + * in this case it's an *incredibly* bad idea, because all or part + * of this struct can be invalid at any given time. Use the functions, + * or you will get hosed, I promise. + */ +struct _GDate +{ + guint julian_days : 32; /* julian days representation - we use a + * bitfield hoping that 64 bit platforms + * will pack this whole struct in one big + * int + */ + + guint julian : 1; /* julian is valid */ + guint dmy : 1; /* dmy is valid */ + + /* DMY representation */ + guint day : 6; + guint month : 4; + guint year : 16; +}; + +/* g_date_new() returns an invalid date, you then have to _set() stuff + * to get a usable object. You can also allocate a GDate statically, + * then call g_date_clear() to initialize. + */ +GLIB_AVAILABLE_IN_ALL +GDate* g_date_new (void); +GLIB_AVAILABLE_IN_ALL +GDate* g_date_new_dmy (GDateDay day, + GDateMonth month, + GDateYear year); +GLIB_AVAILABLE_IN_ALL +GDate* g_date_new_julian (guint32 julian_day); +GLIB_AVAILABLE_IN_ALL +void g_date_free (GDate *date); +GLIB_AVAILABLE_IN_2_56 +GDate* g_date_copy (const GDate *date); + +/* check g_date_valid() after doing an operation that might fail, like + * _parse. Almost all g_date operations are undefined on invalid + * dates (the exceptions are the mutators, since you need those to + * return to validity). + */ +GLIB_AVAILABLE_IN_ALL +gboolean g_date_valid (const GDate *date); +GLIB_AVAILABLE_IN_ALL +gboolean g_date_valid_day (GDateDay day) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gboolean g_date_valid_month (GDateMonth month) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gboolean g_date_valid_year (GDateYear year) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gboolean g_date_valid_weekday (GDateWeekday weekday) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gboolean g_date_valid_julian (guint32 julian_date) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gboolean g_date_valid_dmy (GDateDay day, + GDateMonth month, + GDateYear year) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GDateWeekday g_date_get_weekday (const GDate *date); +GLIB_AVAILABLE_IN_ALL +GDateMonth g_date_get_month (const GDate *date); +GLIB_AVAILABLE_IN_ALL +GDateYear g_date_get_year (const GDate *date); +GLIB_AVAILABLE_IN_ALL +GDateDay g_date_get_day (const GDate *date); +GLIB_AVAILABLE_IN_ALL +guint32 g_date_get_julian (const GDate *date); +GLIB_AVAILABLE_IN_ALL +guint g_date_get_day_of_year (const GDate *date); +/* First monday/sunday is the start of week 1; if we haven't reached + * that day, return 0. These are not ISO weeks of the year; that + * routine needs to be added. + * these functions return the number of weeks, starting on the + * corrsponding day + */ +GLIB_AVAILABLE_IN_ALL +guint g_date_get_monday_week_of_year (const GDate *date); +GLIB_AVAILABLE_IN_ALL +guint g_date_get_sunday_week_of_year (const GDate *date); +GLIB_AVAILABLE_IN_ALL +guint g_date_get_iso8601_week_of_year (const GDate *date); + +/* If you create a static date struct you need to clear it to get it + * in a safe state before use. You can clear a whole array at + * once with the ndates argument. + */ +GLIB_AVAILABLE_IN_ALL +void g_date_clear (GDate *date, + guint n_dates); + +/* The parse routine is meant for dates typed in by a user, so it + * permits many formats but tries to catch common typos. If your data + * needs to be strictly validated, it is not an appropriate function. + */ +GLIB_AVAILABLE_IN_ALL +void g_date_set_parse (GDate *date, + const gchar *str); +GLIB_AVAILABLE_IN_ALL +void g_date_set_time_t (GDate *date, + time_t timet); +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_DEPRECATED_IN_2_62_FOR(g_date_set_time_t) +void g_date_set_time_val (GDate *date, + GTimeVal *timeval); +GLIB_DEPRECATED_FOR(g_date_set_time_t) +void g_date_set_time (GDate *date, + GTime time_); +G_GNUC_END_IGNORE_DEPRECATIONS +GLIB_AVAILABLE_IN_ALL +void g_date_set_month (GDate *date, + GDateMonth month); +GLIB_AVAILABLE_IN_ALL +void g_date_set_day (GDate *date, + GDateDay day); +GLIB_AVAILABLE_IN_ALL +void g_date_set_year (GDate *date, + GDateYear year); +GLIB_AVAILABLE_IN_ALL +void g_date_set_dmy (GDate *date, + GDateDay day, + GDateMonth month, + GDateYear y); +GLIB_AVAILABLE_IN_ALL +void g_date_set_julian (GDate *date, + guint32 julian_date); +GLIB_AVAILABLE_IN_ALL +gboolean g_date_is_first_of_month (const GDate *date); +GLIB_AVAILABLE_IN_ALL +gboolean g_date_is_last_of_month (const GDate *date); + +/* To go forward by some number of weeks just go forward weeks*7 days */ +GLIB_AVAILABLE_IN_ALL +void g_date_add_days (GDate *date, + guint n_days); +GLIB_AVAILABLE_IN_ALL +void g_date_subtract_days (GDate *date, + guint n_days); + +/* If you add/sub months while day > 28, the day might change */ +GLIB_AVAILABLE_IN_ALL +void g_date_add_months (GDate *date, + guint n_months); +GLIB_AVAILABLE_IN_ALL +void g_date_subtract_months (GDate *date, + guint n_months); + +/* If it's feb 29, changing years can move you to the 28th */ +GLIB_AVAILABLE_IN_ALL +void g_date_add_years (GDate *date, + guint n_years); +GLIB_AVAILABLE_IN_ALL +void g_date_subtract_years (GDate *date, + guint n_years); +GLIB_AVAILABLE_IN_ALL +gboolean g_date_is_leap_year (GDateYear year) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +guint8 g_date_get_days_in_month (GDateMonth month, + GDateYear year) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +guint8 g_date_get_monday_weeks_in_year (GDateYear year) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +guint8 g_date_get_sunday_weeks_in_year (GDateYear year) G_GNUC_CONST; + +/* Returns the number of days between the two dates. If date2 comes + before date1, a negative value is return. */ +GLIB_AVAILABLE_IN_ALL +gint g_date_days_between (const GDate *date1, + const GDate *date2); + +/* qsort-friendly (with a cast...) */ +GLIB_AVAILABLE_IN_ALL +gint g_date_compare (const GDate *lhs, + const GDate *rhs); +GLIB_AVAILABLE_IN_ALL +void g_date_to_struct_tm (const GDate *date, + struct tm *tm); + +GLIB_AVAILABLE_IN_ALL +void g_date_clamp (GDate *date, + const GDate *min_date, + const GDate *max_date); + +/* Swap date1 and date2's values if date1 > date2. */ +GLIB_AVAILABLE_IN_ALL +void g_date_order (GDate *date1, GDate *date2); + +/* Just like strftime() except you can only use date-related formats. + * Using a time format is undefined. + */ +GLIB_AVAILABLE_IN_ALL +gsize g_date_strftime (gchar *s, + gsize slen, + const gchar *format, + const GDate *date); + +#define g_date_weekday g_date_get_weekday GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_weekday) +#define g_date_month g_date_get_month GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_month) +#define g_date_year g_date_get_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_year) +#define g_date_day g_date_get_day GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_day) +#define g_date_julian g_date_get_julian GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_julian) +#define g_date_day_of_year g_date_get_day_of_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_day_of_year) +#define g_date_monday_week_of_year g_date_get_monday_week_of_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_monday_week_of_year) +#define g_date_sunday_week_of_year g_date_get_sunday_week_of_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_sunday_week_of_year) +#define g_date_days_in_month g_date_get_days_in_month GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_days_in_month) +#define g_date_monday_weeks_in_year g_date_get_monday_weeks_in_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_monday_weeks_in_year) +#define g_date_sunday_weeks_in_year g_date_get_sunday_weeks_in_year GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_date_get_sunday_weeks_in_year) + +G_END_DECLS + +#endif /* __G_DATE_H__ */ diff --git a/glib/gdatetime.c b/glib/gdatetime.c new file mode 100644 index 0000000..0ec390c --- /dev/null +++ b/glib/gdatetime.c @@ -0,0 +1,3527 @@ +/* gdatetime.c + * + * Copyright (C) 2009-2010 Christian Hergert + * Copyright (C) 2010 Thiago Santos + * Copyright (C) 2010 Emmanuele Bassi + * Copyright © 2010 Codethink Limited + * Copyright © 2018 Tomasz MiÄ…sko + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * licence, or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + * + * Authors: Christian Hergert + * Thiago Santos + * Emmanuele Bassi + * Ryan Lortie + * Robert Ancell + */ + +/* Algorithms within this file are based on the Calendar FAQ by + * Claus Tondering. It can be found at + * http://www.tondering.dk/claus/cal/calendar29.txt + * + * Copyright and disclaimer + * ------------------------ + * This document is Copyright (C) 2008 by Claus Tondering. + * E-mail: claus@tondering.dk. (Please include the word + * "calendar" in the subject line.) + * The document may be freely distributed, provided this + * copyright notice is included and no money is charged for + * the document. + * + * This document is provided "as is". No warranties are made as + * to its correctness. + */ + +/* Prologue {{{1 */ + +#include "config.h" + +/* langinfo.h in glibc 2.27 defines ALTMON_* only if _GNU_SOURCE is defined. */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include + +#ifdef HAVE_LANGINFO_TIME +#include +#endif + +#include "gatomic.h" +#include "gcharset.h" +#include "gcharsetprivate.h" +#include "gconvert.h" +#include "gconvertprivate.h" +#include "gdatetime.h" +#include "gfileutils.h" +#include "ghash.h" +#include "glibintl.h" +#include "gmain.h" +#include "gmappedfile.h" +#include "gslice.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gthread.h" +#include "gtimezone.h" + +#ifndef G_OS_WIN32 +#include +#include +#else +#if defined (_MSC_VER) && (_MSC_VER < 1800) +/* fallback implementation for isnan() on VS2012 and earlier */ +#define isnan _isnan +#endif +#endif /* !G_OS_WIN32 */ + +/** + * SECTION:date-time + * @title: GDateTime + * @short_description: a structure representing Date and Time + * @see_also: #GTimeZone + * + * #GDateTime is a structure that combines a Gregorian date and time + * into a single structure. It provides many conversion and methods to + * manipulate dates and times. Time precision is provided down to + * microseconds and the time can range (proleptically) from 0001-01-01 + * 00:00:00 to 9999-12-31 23:59:59.999999. #GDateTime follows POSIX + * time in the sense that it is oblivious to leap seconds. + * + * #GDateTime is an immutable object; once it has been created it cannot + * be modified further. All modifiers will create a new #GDateTime. + * Nearly all such functions can fail due to the date or time going out + * of range, in which case %NULL will be returned. + * + * #GDateTime is reference counted: the reference count is increased by calling + * g_date_time_ref() and decreased by calling g_date_time_unref(). When the + * reference count drops to 0, the resources allocated by the #GDateTime + * structure are released. + * + * Many parts of the API may produce non-obvious results. As an + * example, adding two months to January 31st will yield March 31st + * whereas adding one month and then one month again will yield either + * March 28th or March 29th. Also note that adding 24 hours is not + * always the same as adding one day (since days containing daylight + * savings time transitions are either 23 or 25 hours in length). + * + * #GDateTime is available since GLib 2.26. + */ + +struct _GDateTime +{ + /* Microsecond timekeeping within Day */ + guint64 usec; + + /* TimeZone information */ + GTimeZone *tz; + gint interval; + + /* 1 is 0001-01-01 in Proleptic Gregorian */ + gint32 days; + + gint ref_count; /* (atomic) */ +}; + +/* Time conversion {{{1 */ + +#define UNIX_EPOCH_START 719163 +#define INSTANT_TO_UNIX(instant) \ + ((instant)/USEC_PER_SECOND - UNIX_EPOCH_START * SEC_PER_DAY) +#define INSTANT_TO_UNIX_USECS(instant) \ + ((instant) - UNIX_EPOCH_START * SEC_PER_DAY * USEC_PER_SECOND) +#define UNIX_TO_INSTANT(unix) \ + (((gint64) (unix) + UNIX_EPOCH_START * SEC_PER_DAY) * USEC_PER_SECOND) +#define UNIX_USECS_TO_INSTANT(unix_usecs) \ + ((gint64) (unix_usecs) + UNIX_EPOCH_START * SEC_PER_DAY * USEC_PER_SECOND) +#define UNIX_TO_INSTANT_IS_VALID(unix) \ + ((gint64) (unix) <= INSTANT_TO_UNIX (G_MAXINT64)) +#define UNIX_USECS_TO_INSTANT_IS_VALID(unix_usecs) \ + ((gint64) (unix_usecs) <= INSTANT_TO_UNIX_USECS (G_MAXINT64)) + +#define DAYS_IN_4YEARS 1461 /* days in 4 years */ +#define DAYS_IN_100YEARS 36524 /* days in 100 years */ +#define DAYS_IN_400YEARS 146097 /* days in 400 years */ + +#define USEC_PER_SECOND (G_GINT64_CONSTANT (1000000)) +#define USEC_PER_MINUTE (G_GINT64_CONSTANT (60000000)) +#define USEC_PER_HOUR (G_GINT64_CONSTANT (3600000000)) +#define USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000)) +#define USEC_PER_DAY (G_GINT64_CONSTANT (86400000000)) +#define SEC_PER_DAY (G_GINT64_CONSTANT (86400)) + +#define SECS_PER_MINUTE (60) +#define SECS_PER_HOUR (60 * SECS_PER_MINUTE) +#define SECS_PER_DAY (24 * SECS_PER_HOUR) +#define SECS_PER_YEAR (365 * SECS_PER_DAY) +#define SECS_PER_JULIAN (DAYS_PER_PERIOD * SECS_PER_DAY) + +#define GREGORIAN_LEAP(y) ((((y) % 4) == 0) && (!((((y) % 100) == 0) && (((y) % 400) != 0)))) +#define JULIAN_YEAR(d) ((d)->julian / 365.25) +#define DAYS_PER_PERIOD (G_GINT64_CONSTANT (2914695)) + +static const guint16 days_in_months[2][13] = +{ + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const guint16 days_in_year[2][13] = +{ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +#ifdef HAVE_LANGINFO_TIME + +#define GET_AMPM(d) ((g_date_time_get_hour (d) < 12) ? \ + nl_langinfo (AM_STR) : \ + nl_langinfo (PM_STR)) +#define GET_AMPM_IS_LOCALE TRUE + +#define PREFERRED_DATE_TIME_FMT nl_langinfo (D_T_FMT) +#define PREFERRED_DATE_FMT nl_langinfo (D_FMT) +#define PREFERRED_TIME_FMT nl_langinfo (T_FMT) +#define PREFERRED_12HR_TIME_FMT nl_langinfo (T_FMT_AMPM) + +static const gint weekday_item[2][7] = +{ + { ABDAY_2, ABDAY_3, ABDAY_4, ABDAY_5, ABDAY_6, ABDAY_7, ABDAY_1 }, + { DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7, DAY_1 } +}; + +static const gint month_item[2][12] = +{ + { ABMON_1, ABMON_2, ABMON_3, ABMON_4, ABMON_5, ABMON_6, ABMON_7, ABMON_8, ABMON_9, ABMON_10, ABMON_11, ABMON_12 }, + { MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7, MON_8, MON_9, MON_10, MON_11, MON_12 }, +}; + +#define WEEKDAY_ABBR(d) nl_langinfo (weekday_item[0][g_date_time_get_day_of_week (d) - 1]) +#define WEEKDAY_ABBR_IS_LOCALE TRUE +#define WEEKDAY_FULL(d) nl_langinfo (weekday_item[1][g_date_time_get_day_of_week (d) - 1]) +#define WEEKDAY_FULL_IS_LOCALE TRUE +#define MONTH_ABBR(d) nl_langinfo (month_item[0][g_date_time_get_month (d) - 1]) +#define MONTH_ABBR_IS_LOCALE TRUE +#define MONTH_FULL(d) nl_langinfo (month_item[1][g_date_time_get_month (d) - 1]) +#define MONTH_FULL_IS_LOCALE TRUE + +#else + +#define GET_AMPM(d) (get_fallback_ampm (g_date_time_get_hour (d))) +#define GET_AMPM_IS_LOCALE FALSE + +/* Translators: this is the preferred format for expressing the date and the time */ +#define PREFERRED_DATE_TIME_FMT C_("GDateTime", "%a %b %e %H:%M:%S %Y") + +/* Translators: this is the preferred format for expressing the date */ +#define PREFERRED_DATE_FMT C_("GDateTime", "%m/%d/%y") + +/* Translators: this is the preferred format for expressing the time */ +#define PREFERRED_TIME_FMT C_("GDateTime", "%H:%M:%S") + +/* Translators: this is the preferred format for expressing 12 hour time */ +#define PREFERRED_12HR_TIME_FMT C_("GDateTime", "%I:%M:%S %p") + +#define WEEKDAY_ABBR(d) (get_weekday_name_abbr (g_date_time_get_day_of_week (d))) +#define WEEKDAY_ABBR_IS_LOCALE FALSE +#define WEEKDAY_FULL(d) (get_weekday_name (g_date_time_get_day_of_week (d))) +#define WEEKDAY_FULL_IS_LOCALE FALSE +/* We don't yet know if nl_langinfo (MON_n) returns standalone or complete-date + * format forms but if nl_langinfo (ALTMON_n) is not supported then we will + * have to use MONTH_FULL as standalone. The same if nl_langinfo () does not + * exist at all. MONTH_ABBR is similar: if nl_langinfo (_NL_ABALTMON_n) is not + * supported then we will use MONTH_ABBR as standalone. + */ +#define MONTH_ABBR(d) (get_month_name_abbr_standalone (g_date_time_get_month (d))) +#define MONTH_ABBR_IS_LOCALE FALSE +#define MONTH_FULL(d) (get_month_name_standalone (g_date_time_get_month (d))) +#define MONTH_FULL_IS_LOCALE FALSE + +static const gchar * +get_month_name_standalone (gint month) +{ + switch (month) + { + case 1: + /* Translators: Some languages (Baltic, Slavic, Greek, and some more) + * need different grammatical forms of month names depending on whether + * they are standalone or in a complete date context, with the day + * number. Some other languages may prefer starting with uppercase when + * they are standalone and with lowercase when they are in a complete + * date context. Here are full month names in a form appropriate when + * they are used standalone. If your system is Linux with the glibc + * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD + * family (which includes OS X) then you can refer to the date command + * line utility and see what the command `date +%OB' produces. Also in + * the latest Linux the command `locale alt_mon' in your native locale + * produces a complete list of month names almost ready to copy and + * paste here. Note that in most of the languages (western European, + * non-European) there is no difference between the standalone and + * complete date form. + */ + return C_("full month name", "January"); + case 2: + return C_("full month name", "February"); + case 3: + return C_("full month name", "March"); + case 4: + return C_("full month name", "April"); + case 5: + return C_("full month name", "May"); + case 6: + return C_("full month name", "June"); + case 7: + return C_("full month name", "July"); + case 8: + return C_("full month name", "August"); + case 9: + return C_("full month name", "September"); + case 10: + return C_("full month name", "October"); + case 11: + return C_("full month name", "November"); + case 12: + return C_("full month name", "December"); + + default: + g_warning ("Invalid month number %d", month); + } + + return NULL; +} + +static const gchar * +get_month_name_abbr_standalone (gint month) +{ + switch (month) + { + case 1: + /* Translators: Some languages need different grammatical forms of + * month names depending on whether they are standalone or in a complete + * date context, with the day number. Some may prefer starting with + * uppercase when they are standalone and with lowercase when they are + * in a full date context. However, as these names are abbreviated + * the grammatical difference is visible probably only in Belarusian + * and Russian. In other languages there is no difference between + * the standalone and complete date form when they are abbreviated. + * If your system is Linux with the glibc version 2.27 (released + * Feb 1, 2018) or newer then you can refer to the date command line + * utility and see what the command `date +%Ob' produces. Also in + * the latest Linux the command `locale ab_alt_mon' in your native + * locale produces a complete list of month names almost ready to copy + * and paste here. Note that this feature is not yet supported by any + * other platform. Here are abbreviated month names in a form + * appropriate when they are used standalone. + */ + return C_("abbreviated month name", "Jan"); + case 2: + return C_("abbreviated month name", "Feb"); + case 3: + return C_("abbreviated month name", "Mar"); + case 4: + return C_("abbreviated month name", "Apr"); + case 5: + return C_("abbreviated month name", "May"); + case 6: + return C_("abbreviated month name", "Jun"); + case 7: + return C_("abbreviated month name", "Jul"); + case 8: + return C_("abbreviated month name", "Aug"); + case 9: + return C_("abbreviated month name", "Sep"); + case 10: + return C_("abbreviated month name", "Oct"); + case 11: + return C_("abbreviated month name", "Nov"); + case 12: + return C_("abbreviated month name", "Dec"); + + default: + g_warning ("Invalid month number %d", month); + } + + return NULL; +} + +static const gchar * +get_weekday_name (gint day) +{ + switch (day) + { + case 1: + return C_("full weekday name", "Monday"); + case 2: + return C_("full weekday name", "Tuesday"); + case 3: + return C_("full weekday name", "Wednesday"); + case 4: + return C_("full weekday name", "Thursday"); + case 5: + return C_("full weekday name", "Friday"); + case 6: + return C_("full weekday name", "Saturday"); + case 7: + return C_("full weekday name", "Sunday"); + + default: + g_warning ("Invalid week day number %d", day); + } + + return NULL; +} + +static const gchar * +get_weekday_name_abbr (gint day) +{ + switch (day) + { + case 1: + return C_("abbreviated weekday name", "Mon"); + case 2: + return C_("abbreviated weekday name", "Tue"); + case 3: + return C_("abbreviated weekday name", "Wed"); + case 4: + return C_("abbreviated weekday name", "Thu"); + case 5: + return C_("abbreviated weekday name", "Fri"); + case 6: + return C_("abbreviated weekday name", "Sat"); + case 7: + return C_("abbreviated weekday name", "Sun"); + + default: + g_warning ("Invalid week day number %d", day); + } + + return NULL; +} + +#endif /* HAVE_LANGINFO_TIME */ + +#ifdef HAVE_LANGINFO_ALTMON + +/* If nl_langinfo () supports ALTMON_n then MON_n returns full date format + * forms and ALTMON_n returns standalone forms. + */ + +#define MONTH_FULL_WITH_DAY(d) MONTH_FULL(d) +#define MONTH_FULL_WITH_DAY_IS_LOCALE MONTH_FULL_IS_LOCALE + +static const gint alt_month_item[12] = +{ + ALTMON_1, ALTMON_2, ALTMON_3, ALTMON_4, ALTMON_5, ALTMON_6, + ALTMON_7, ALTMON_8, ALTMON_9, ALTMON_10, ALTMON_11, ALTMON_12 +}; + +#define MONTH_FULL_STANDALONE(d) nl_langinfo (alt_month_item[g_date_time_get_month (d) - 1]) +#define MONTH_FULL_STANDALONE_IS_LOCALE TRUE + +#else + +/* If nl_langinfo () does not support ALTMON_n then either MON_n returns + * standalone forms or nl_langinfo (MON_n) does not work so we have defined + * it as standalone form. + */ + +#define MONTH_FULL_STANDALONE(d) MONTH_FULL(d) +#define MONTH_FULL_STANDALONE_IS_LOCALE MONTH_FULL_IS_LOCALE +#define MONTH_FULL_WITH_DAY(d) (get_month_name_with_day (g_date_time_get_month (d))) +#define MONTH_FULL_WITH_DAY_IS_LOCALE FALSE + +static const gchar * +get_month_name_with_day (gint month) +{ + switch (month) + { + case 1: + /* Translators: Some languages need different grammatical forms of + * month names depending on whether they are standalone or in a full + * date context, with the day number. Some may prefer starting with + * uppercase when they are standalone and with lowercase when they are + * in a full date context. Here are full month names in a form + * appropriate when they are used in a full date context, with the + * day number. If your system is Linux with the glibc version 2.27 + * (released Feb 1, 2018) or newer or if it is from the BSD family + * (which includes OS X) then you can refer to the date command line + * utility and see what the command `date +%B' produces. Also in + * the latest Linux the command `locale mon' in your native locale + * produces a complete list of month names almost ready to copy and + * paste here. In older Linux systems due to a bug the result is + * incorrect in some languages. Note that in most of the languages + * (western European, non-European) there is no difference between the + * standalone and complete date form. + */ + return C_("full month name with day", "January"); + case 2: + return C_("full month name with day", "February"); + case 3: + return C_("full month name with day", "March"); + case 4: + return C_("full month name with day", "April"); + case 5: + return C_("full month name with day", "May"); + case 6: + return C_("full month name with day", "June"); + case 7: + return C_("full month name with day", "July"); + case 8: + return C_("full month name with day", "August"); + case 9: + return C_("full month name with day", "September"); + case 10: + return C_("full month name with day", "October"); + case 11: + return C_("full month name with day", "November"); + case 12: + return C_("full month name with day", "December"); + + default: + g_warning ("Invalid month number %d", month); + } + + return NULL; +} + +#endif /* HAVE_LANGINFO_ALTMON */ + +#ifdef HAVE_LANGINFO_ABALTMON + +/* If nl_langinfo () supports _NL_ABALTMON_n then ABMON_n returns full + * date format forms and _NL_ABALTMON_n returns standalone forms. + */ + +#define MONTH_ABBR_WITH_DAY(d) MONTH_ABBR(d) +#define MONTH_ABBR_WITH_DAY_IS_LOCALE MONTH_ABBR_IS_LOCALE + +static const gint ab_alt_month_item[12] = +{ + _NL_ABALTMON_1, _NL_ABALTMON_2, _NL_ABALTMON_3, _NL_ABALTMON_4, + _NL_ABALTMON_5, _NL_ABALTMON_6, _NL_ABALTMON_7, _NL_ABALTMON_8, + _NL_ABALTMON_9, _NL_ABALTMON_10, _NL_ABALTMON_11, _NL_ABALTMON_12 +}; + +#define MONTH_ABBR_STANDALONE(d) nl_langinfo (ab_alt_month_item[g_date_time_get_month (d) - 1]) +#define MONTH_ABBR_STANDALONE_IS_LOCALE TRUE + +#else + +/* If nl_langinfo () does not support _NL_ABALTMON_n then either ABMON_n + * returns standalone forms or nl_langinfo (ABMON_n) does not work so we + * have defined it as standalone form. Now it's time to swap. + */ + +#define MONTH_ABBR_STANDALONE(d) MONTH_ABBR(d) +#define MONTH_ABBR_STANDALONE_IS_LOCALE MONTH_ABBR_IS_LOCALE +#define MONTH_ABBR_WITH_DAY(d) (get_month_name_abbr_with_day (g_date_time_get_month (d))) +#define MONTH_ABBR_WITH_DAY_IS_LOCALE FALSE + +static const gchar * +get_month_name_abbr_with_day (gint month) +{ + switch (month) + { + case 1: + /* Translators: Some languages need different grammatical forms of + * month names depending on whether they are standalone or in a full + * date context, with the day number. Some may prefer starting with + * uppercase when they are standalone and with lowercase when they are + * in a full date context. Here are abbreviated month names in a form + * appropriate when they are used in a full date context, with the + * day number. However, as these names are abbreviated the grammatical + * difference is visible probably only in Belarusian and Russian. + * In other languages there is no difference between the standalone + * and complete date form when they are abbreviated. If your system + * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer + * then you can refer to the date command line utility and see what the + * command `date +%b' produces. Also in the latest Linux the command + * `locale abmon' in your native locale produces a complete list of + * month names almost ready to copy and paste here. In other systems + * due to a bug the result is incorrect in some languages. + */ + return C_("abbreviated month name with day", "Jan"); + case 2: + return C_("abbreviated month name with day", "Feb"); + case 3: + return C_("abbreviated month name with day", "Mar"); + case 4: + return C_("abbreviated month name with day", "Apr"); + case 5: + return C_("abbreviated month name with day", "May"); + case 6: + return C_("abbreviated month name with day", "Jun"); + case 7: + return C_("abbreviated month name with day", "Jul"); + case 8: + return C_("abbreviated month name with day", "Aug"); + case 9: + return C_("abbreviated month name with day", "Sep"); + case 10: + return C_("abbreviated month name with day", "Oct"); + case 11: + return C_("abbreviated month name with day", "Nov"); + case 12: + return C_("abbreviated month name with day", "Dec"); + + default: + g_warning ("Invalid month number %d", month); + } + + return NULL; +} + +#endif /* HAVE_LANGINFO_ABALTMON */ + +/* Format AM/PM indicator if the locale does not have a localized version. */ +static const gchar * +get_fallback_ampm (gint hour) +{ + if (hour < 12) + /* Translators: 'before midday' indicator */ + return C_("GDateTime", "AM"); + else + /* Translators: 'after midday' indicator */ + return C_("GDateTime", "PM"); +} + +static inline gint +ymd_to_days (gint year, + gint month, + gint day) +{ + gint64 days; + + days = ((gint64) year - 1) * 365 + ((year - 1) / 4) - ((year - 1) / 100) + + ((year - 1) / 400); + + days += days_in_year[0][month - 1]; + if (GREGORIAN_LEAP (year) && month > 2) + day++; + + days += day; + + return days; +} + +static void +g_date_time_get_week_number (GDateTime *datetime, + gint *week_number, + gint *day_of_week, + gint *day_of_year) +{ + gint a, b, c, d, e, f, g, n, s, month = -1, day = -1, year = -1; + + g_date_time_get_ymd (datetime, &year, &month, &day); + + if (month <= 2) + { + a = g_date_time_get_year (datetime) - 1; + b = (a / 4) - (a / 100) + (a / 400); + c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400); + s = b - c; + e = 0; + f = day - 1 + (31 * (month - 1)); + } + else + { + a = year; + b = (a / 4) - (a / 100) + (a / 400); + c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400); + s = b - c; + e = s + 1; + f = day + (((153 * (month - 3)) + 2) / 5) + 58 + s; + } + + g = (a + b) % 7; + d = (f + g - e) % 7; + n = f + 3 - d; + + if (week_number) + { + if (n < 0) + *week_number = 53 - ((g - s) / 5); + else if (n > 364 + s) + *week_number = 1; + else + *week_number = (n / 7) + 1; + } + + if (day_of_week) + *day_of_week = d + 1; + + if (day_of_year) + *day_of_year = f + 1; +} + +/* Lifecycle {{{1 */ + +static GDateTime * +g_date_time_alloc (GTimeZone *tz) +{ + GDateTime *datetime; + + datetime = g_slice_new0 (GDateTime); + datetime->tz = g_time_zone_ref (tz); + datetime->ref_count = 1; + + return datetime; +} + +/** + * g_date_time_ref: + * @datetime: a #GDateTime + * + * Atomically increments the reference count of @datetime by one. + * + * Returns: the #GDateTime with the reference count increased + * + * Since: 2.26 + */ +GDateTime * +g_date_time_ref (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, NULL); + g_return_val_if_fail (datetime->ref_count > 0, NULL); + + g_atomic_int_inc (&datetime->ref_count); + + return datetime; +} + +/** + * g_date_time_unref: + * @datetime: a #GDateTime + * + * Atomically decrements the reference count of @datetime by one. + * + * When the reference count reaches zero, the resources allocated by + * @datetime are freed + * + * Since: 2.26 + */ +void +g_date_time_unref (GDateTime *datetime) +{ + g_return_if_fail (datetime != NULL); + g_return_if_fail (datetime->ref_count > 0); + + if (g_atomic_int_dec_and_test (&datetime->ref_count)) + { + g_time_zone_unref (datetime->tz); + g_slice_free (GDateTime, datetime); + } +} + +/* Internal state transformers {{{1 */ +/*< internal > + * g_date_time_to_instant: + * @datetime: a #GDateTime + * + * Convert a @datetime into an instant. + * + * An instant is a number that uniquely describes a particular + * microsecond in time, taking time zone considerations into account. + * (ie: "03:00 -0400" is the same instant as "02:00 -0500"). + * + * An instant is always positive but we use a signed return value to + * avoid troubles with C. + */ +static gint64 +g_date_time_to_instant (GDateTime *datetime) +{ + gint64 offset; + + offset = g_time_zone_get_offset (datetime->tz, datetime->interval); + offset *= USEC_PER_SECOND; + + return datetime->days * USEC_PER_DAY + datetime->usec - offset; +} + +/*< internal > + * g_date_time_from_instant: + * @tz: a #GTimeZone + * @instant: an instant in time + * + * Creates a #GDateTime from a time zone and an instant. + * + * This might fail if the time ends up being out of range. + */ +static GDateTime * +g_date_time_from_instant (GTimeZone *tz, + gint64 instant) +{ + GDateTime *datetime; + gint64 offset; + + if (instant < 0 || instant > G_GINT64_CONSTANT (1000000000000000000)) + return NULL; + + datetime = g_date_time_alloc (tz); + datetime->interval = g_time_zone_find_interval (tz, + G_TIME_TYPE_UNIVERSAL, + INSTANT_TO_UNIX (instant)); + offset = g_time_zone_get_offset (datetime->tz, datetime->interval); + offset *= USEC_PER_SECOND; + + instant += offset; + + datetime->days = instant / USEC_PER_DAY; + datetime->usec = instant % USEC_PER_DAY; + + if (datetime->days < 1 || 3652059 < datetime->days) + { + g_date_time_unref (datetime); + datetime = NULL; + } + + return datetime; +} + + +/*< internal > + * g_date_time_deal_with_date_change: + * @datetime: a #GDateTime + * + * This function should be called whenever the date changes by adding + * days, months or years. It does three things. + * + * First, we ensure that the date falls between 0001-01-01 and + * 9999-12-31 and return %FALSE if it does not. + * + * Next we update the ->interval field. + * + * Finally, we ensure that the resulting date and time pair exists (by + * ensuring that our time zone has an interval containing it) and + * adjusting as required. For example, if we have the time 02:30:00 on + * March 13 2010 in Toronto and we add 1 day to it, we would end up with + * 2:30am on March 14th, which doesn't exist. In that case, we bump the + * time up to 3:00am. + */ +static gboolean +g_date_time_deal_with_date_change (GDateTime *datetime) +{ + GTimeType was_dst; + gint64 full_time; + gint64 usec; + + if (datetime->days < 1 || datetime->days > 3652059) + return FALSE; + + was_dst = g_time_zone_is_dst (datetime->tz, datetime->interval); + + full_time = datetime->days * USEC_PER_DAY + datetime->usec; + + + usec = full_time % USEC_PER_SECOND; + full_time /= USEC_PER_SECOND; + full_time -= UNIX_EPOCH_START * SEC_PER_DAY; + + datetime->interval = g_time_zone_adjust_time (datetime->tz, + was_dst, + &full_time); + full_time += UNIX_EPOCH_START * SEC_PER_DAY; + full_time *= USEC_PER_SECOND; + full_time += usec; + + datetime->days = full_time / USEC_PER_DAY; + datetime->usec = full_time % USEC_PER_DAY; + + /* maybe daylight time caused us to shift to a different day, + * but it definitely didn't push us into a different year */ + return TRUE; +} + +static GDateTime * +g_date_time_replace_days (GDateTime *datetime, + gint days) +{ + GDateTime *new; + + new = g_date_time_alloc (datetime->tz); + new->interval = datetime->interval; + new->usec = datetime->usec; + new->days = days; + + if (!g_date_time_deal_with_date_change (new)) + { + g_date_time_unref (new); + new = NULL; + } + + return new; +} + +/* now/unix/timeval Constructors {{{1 */ + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +/*< internal > + * g_date_time_new_from_timeval: + * @tz: a #GTimeZone + * @tv: a #GTimeVal + * + * Creates a #GDateTime corresponding to the given #GTimeVal @tv in the + * given time zone @tz. + * + * The time contained in a #GTimeVal is always stored in the form of + * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the + * given time zone. + * + * This call can fail (returning %NULL) if @tv represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +static GDateTime * +g_date_time_new_from_timeval (GTimeZone *tz, + const GTimeVal *tv) +{ + gint64 tv_sec = tv->tv_sec; + + if (tv_sec > G_MAXINT64 - 1 || !UNIX_TO_INSTANT_IS_VALID (tv_sec + 1)) + return NULL; + + return g_date_time_from_instant (tz, tv->tv_usec + + UNIX_TO_INSTANT (tv->tv_sec)); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/*< internal > + * g_date_time_new_from_unix: + * @tz: a #GTimeZone + * @usecs: the Unix time, in microseconds since the epoch + * + * Creates a #GDateTime corresponding to the given Unix time @t_us in the + * given time zone @tz. + * + * Unix time is the number of seconds that have elapsed since 1970-01-01 + * 00:00:00 UTC, regardless of the time zone given. + * + * This call can fail (returning %NULL) if @t represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +static GDateTime * +g_date_time_new_from_unix (GTimeZone *tz, + gint64 usecs) +{ + if (!UNIX_USECS_TO_INSTANT_IS_VALID (usecs)) + return NULL; + + return g_date_time_from_instant (tz, UNIX_USECS_TO_INSTANT (usecs)); +} + +/** + * g_date_time_new_now: (constructor) + * @tz: a #GTimeZone + * + * Creates a #GDateTime corresponding to this exact instant in the given + * time zone @tz. The time is as accurate as the system allows, to a + * maximum accuracy of 1 microsecond. + * + * This function will always succeed unless GLib is still being used after the + * year 9999. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: (transfer full) (nullable): a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_now (GTimeZone *tz) +{ + gint64 now_us; + + now_us = g_get_real_time (); + + return g_date_time_new_from_unix (tz, now_us); +} + +/** + * g_date_time_new_now_local: (constructor) + * + * Creates a #GDateTime corresponding to this exact instant in the local + * time zone. + * + * This is equivalent to calling g_date_time_new_now() with the time + * zone returned by g_time_zone_new_local(). + * + * Returns: (transfer full) (nullable): a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_now_local (void) +{ + GDateTime *datetime; + GTimeZone *local; + + local = g_time_zone_new_local (); + datetime = g_date_time_new_now (local); + g_time_zone_unref (local); + + return datetime; +} + +/** + * g_date_time_new_now_utc: (constructor) + * + * Creates a #GDateTime corresponding to this exact instant in UTC. + * + * This is equivalent to calling g_date_time_new_now() with the time + * zone returned by g_time_zone_new_utc(). + * + * Returns: (transfer full) (nullable): a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_now_utc (void) +{ + GDateTime *datetime; + GTimeZone *utc; + + utc = g_time_zone_new_utc (); + datetime = g_date_time_new_now (utc); + g_time_zone_unref (utc); + + return datetime; +} + +/** + * g_date_time_new_from_unix_local: (constructor) + * @t: the Unix time + * + * Creates a #GDateTime corresponding to the given Unix time @t in the + * local time zone. + * + * Unix time is the number of seconds that have elapsed since 1970-01-01 + * 00:00:00 UTC, regardless of the local time offset. + * + * This call can fail (returning %NULL) if @t represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: (transfer full) (nullable): a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_from_unix_local (gint64 t) +{ + GDateTime *datetime; + GTimeZone *local; + + if (t > G_MAXINT64 / USEC_PER_SECOND || + t < G_MININT64 / USEC_PER_SECOND) + return NULL; + + local = g_time_zone_new_local (); + datetime = g_date_time_new_from_unix (local, t * USEC_PER_SECOND); + g_time_zone_unref (local); + + return datetime; +} + +/** + * g_date_time_new_from_unix_utc: (constructor) + * @t: the Unix time + * + * Creates a #GDateTime corresponding to the given Unix time @t in UTC. + * + * Unix time is the number of seconds that have elapsed since 1970-01-01 + * 00:00:00 UTC. + * + * This call can fail (returning %NULL) if @t represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: (transfer full) (nullable): a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_from_unix_utc (gint64 t) +{ + GDateTime *datetime; + GTimeZone *utc; + + if (t > G_MAXINT64 / USEC_PER_SECOND || + t < G_MININT64 / USEC_PER_SECOND) + return NULL; + + utc = g_time_zone_new_utc (); + datetime = g_date_time_new_from_unix (utc, t * USEC_PER_SECOND); + g_time_zone_unref (utc); + + return datetime; +} + +/** + * g_date_time_new_from_timeval_local: (constructor) + * @tv: a #GTimeVal + * + * Creates a #GDateTime corresponding to the given #GTimeVal @tv in the + * local time zone. + * + * The time contained in a #GTimeVal is always stored in the form of + * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the + * local time offset. + * + * This call can fail (returning %NULL) if @tv represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: (transfer full) (nullable): a new #GDateTime, or %NULL + * + * Since: 2.26 + * Deprecated: 2.62: #GTimeVal is not year-2038-safe. Use + * g_date_time_new_from_unix_local() instead. + **/ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GDateTime * +g_date_time_new_from_timeval_local (const GTimeVal *tv) +{ + GDateTime *datetime; + GTimeZone *local; + + local = g_time_zone_new_local (); + datetime = g_date_time_new_from_timeval (local, tv); + g_time_zone_unref (local); + + return datetime; +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_date_time_new_from_timeval_utc: (constructor) + * @tv: a #GTimeVal + * + * Creates a #GDateTime corresponding to the given #GTimeVal @tv in UTC. + * + * The time contained in a #GTimeVal is always stored in the form of + * seconds elapsed since 1970-01-01 00:00:00 UTC. + * + * This call can fail (returning %NULL) if @tv represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: (transfer full) (nullable): a new #GDateTime, or %NULL + * + * Since: 2.26 + * Deprecated: 2.62: #GTimeVal is not year-2038-safe. Use + * g_date_time_new_from_unix_utc() instead. + **/ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GDateTime * +g_date_time_new_from_timeval_utc (const GTimeVal *tv) +{ + GDateTime *datetime; + GTimeZone *utc; + + utc = g_time_zone_new_utc (); + datetime = g_date_time_new_from_timeval (utc, tv); + g_time_zone_unref (utc); + + return datetime; +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/* Parse integers in the form d (week days), dd (hours etc), ddd (ordinal days) or dddd (years) */ +static gboolean +get_iso8601_int (const gchar *text, gsize length, gint *value) +{ + gsize i; + guint v = 0; + + if (length < 1 || length > 4) + return FALSE; + + for (i = 0; i < length; i++) + { + const gchar c = text[i]; + if (c < '0' || c > '9') + return FALSE; + v = v * 10 + (c - '0'); + } + + *value = v; + return TRUE; +} + +/* Parse seconds in the form ss or ss.sss (variable length decimal) */ +static gboolean +get_iso8601_seconds (const gchar *text, gsize length, gdouble *value) +{ + gsize i; + guint64 divisor = 1, v = 0; + + if (length < 2) + return FALSE; + + for (i = 0; i < 2; i++) + { + const gchar c = text[i]; + if (c < '0' || c > '9') + return FALSE; + v = v * 10 + (c - '0'); + } + + if (length > 2 && !(text[i] == '.' || text[i] == ',')) + return FALSE; + + /* Ignore leap seconds, see g_date_time_new_from_iso8601() */ + if (v >= 60.0 && v <= 61.0) + v = 59.0; + + i++; + if (i == length) + return FALSE; + + for (; i < length; i++) + { + const gchar c = text[i]; + if (c < '0' || c > '9' || + v > (G_MAXUINT64 - (c - '0')) / 10 || + divisor > G_MAXUINT64 / 10) + return FALSE; + v = v * 10 + (c - '0'); + divisor *= 10; + } + + *value = (gdouble) v / divisor; + return TRUE; +} + +static GDateTime * +g_date_time_new_ordinal (GTimeZone *tz, gint year, gint ordinal_day, gint hour, gint minute, gdouble seconds) +{ + GDateTime *dt; + + if (ordinal_day < 1 || ordinal_day > (GREGORIAN_LEAP (year) ? 366 : 365)) + return NULL; + + dt = g_date_time_new (tz, year, 1, 1, hour, minute, seconds); + if (dt == NULL) + return NULL; + dt->days += ordinal_day - 1; + + return dt; +} + +static GDateTime * +g_date_time_new_week (GTimeZone *tz, gint year, gint week, gint week_day, gint hour, gint minute, gdouble seconds) +{ + gint64 p; + gint max_week, jan4_week_day, ordinal_day; + GDateTime *dt; + + p = (year * 365 + (year / 4) - (year / 100) + (year / 400)) % 7; + max_week = p == 4 ? 53 : 52; + + if (week < 1 || week > max_week || week_day < 1 || week_day > 7) + return NULL; + + dt = g_date_time_new (tz, year, 1, 4, 0, 0, 0); + if (dt == NULL) + return NULL; + g_date_time_get_week_number (dt, NULL, &jan4_week_day, NULL); + g_date_time_unref (dt); + + ordinal_day = (week * 7) + week_day - (jan4_week_day + 3); + if (ordinal_day < 0) + { + year--; + ordinal_day += GREGORIAN_LEAP (year) ? 366 : 365; + } + else if (ordinal_day > (GREGORIAN_LEAP (year) ? 366 : 365)) + { + ordinal_day -= (GREGORIAN_LEAP (year) ? 366 : 365); + year++; + } + + return g_date_time_new_ordinal (tz, year, ordinal_day, hour, minute, seconds); +} + +static GDateTime * +parse_iso8601_date (const gchar *text, gsize length, + gint hour, gint minute, gdouble seconds, GTimeZone *tz) +{ + /* YYYY-MM-DD */ + if (length == 10 && text[4] == '-' && text[7] == '-') + { + int year, month, day; + if (!get_iso8601_int (text, 4, &year) || + !get_iso8601_int (text + 5, 2, &month) || + !get_iso8601_int (text + 8, 2, &day)) + return NULL; + return g_date_time_new (tz, year, month, day, hour, minute, seconds); + } + /* YYYY-DDD */ + else if (length == 8 && text[4] == '-') + { + gint year, ordinal_day; + if (!get_iso8601_int (text, 4, &year) || + !get_iso8601_int (text + 5, 3, &ordinal_day)) + return NULL; + return g_date_time_new_ordinal (tz, year, ordinal_day, hour, minute, seconds); + } + /* YYYY-Www-D */ + else if (length == 10 && text[4] == '-' && text[5] == 'W' && text[8] == '-') + { + gint year, week, week_day; + if (!get_iso8601_int (text, 4, &year) || + !get_iso8601_int (text + 6, 2, &week) || + !get_iso8601_int (text + 9, 1, &week_day)) + return NULL; + return g_date_time_new_week (tz, year, week, week_day, hour, minute, seconds); + } + /* YYYYWwwD */ + else if (length == 8 && text[4] == 'W') + { + gint year, week, week_day; + if (!get_iso8601_int (text, 4, &year) || + !get_iso8601_int (text + 5, 2, &week) || + !get_iso8601_int (text + 7, 1, &week_day)) + return NULL; + return g_date_time_new_week (tz, year, week, week_day, hour, minute, seconds); + } + /* YYYYMMDD */ + else if (length == 8) + { + int year, month, day; + if (!get_iso8601_int (text, 4, &year) || + !get_iso8601_int (text + 4, 2, &month) || + !get_iso8601_int (text + 6, 2, &day)) + return NULL; + return g_date_time_new (tz, year, month, day, hour, minute, seconds); + } + /* YYYYDDD */ + else if (length == 7) + { + gint year, ordinal_day; + if (!get_iso8601_int (text, 4, &year) || + !get_iso8601_int (text + 4, 3, &ordinal_day)) + return NULL; + return g_date_time_new_ordinal (tz, year, ordinal_day, hour, minute, seconds); + } + else + return FALSE; +} + +static GTimeZone * +parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset) +{ + gint i, tz_length, offset_hours, offset_minutes; + gint offset_sign = 1; + GTimeZone *tz; + + /* UTC uses Z suffix */ + if (length > 0 && text[length - 1] == 'Z') + { + *tz_offset = length - 1; + return g_time_zone_new_utc (); + } + + /* Look for '+' or '-' of offset */ + for (i = length - 1; i >= 0; i--) + if (text[i] == '+' || text[i] == '-') + { + offset_sign = text[i] == '-' ? -1 : 1; + break; + } + if (i < 0) + return NULL; + tz_length = length - i; + + /* +hh:mm or -hh:mm */ + if (tz_length == 6 && text[i+3] == ':') + { + if (!get_iso8601_int (text + i + 1, 2, &offset_hours) || + !get_iso8601_int (text + i + 4, 2, &offset_minutes)) + return NULL; + } + /* +hhmm or -hhmm */ + else if (tz_length == 5) + { + if (!get_iso8601_int (text + i + 1, 2, &offset_hours) || + !get_iso8601_int (text + i + 3, 2, &offset_minutes)) + return NULL; + } + /* +hh or -hh */ + else if (tz_length == 3) + { + if (!get_iso8601_int (text + i + 1, 2, &offset_hours)) + return NULL; + offset_minutes = 0; + } + else + return NULL; + + *tz_offset = i; + tz = g_time_zone_new_identifier (text + i); + + /* Double-check that the GTimeZone matches our interpretation of the timezone. + * This can fail because our interpretation is less strict than (for example) + * parse_time() in gtimezone.c, which restricts the range of the parsed + * integers. */ + if (tz == NULL || g_time_zone_get_offset (tz, 0) != offset_sign * (offset_hours * 3600 + offset_minutes * 60)) + { + g_clear_pointer (&tz, g_time_zone_unref); + return NULL; + } + + return tz; +} + +static gboolean +parse_iso8601_time (const gchar *text, gsize length, + gint *hour, gint *minute, gdouble *seconds, GTimeZone **tz) +{ + gssize tz_offset = -1; + + /* Check for timezone suffix */ + *tz = parse_iso8601_timezone (text, length, &tz_offset); + if (tz_offset >= 0) + length = tz_offset; + + /* hh:mm:ss(.sss) */ + if (length >= 8 && text[2] == ':' && text[5] == ':') + { + return get_iso8601_int (text, 2, hour) && + get_iso8601_int (text + 3, 2, minute) && + get_iso8601_seconds (text + 6, length - 6, seconds); + } + /* hhmmss(.sss) */ + else if (length >= 6) + { + return get_iso8601_int (text, 2, hour) && + get_iso8601_int (text + 2, 2, minute) && + get_iso8601_seconds (text + 4, length - 4, seconds); + } + else + return FALSE; +} + +/** + * g_date_time_new_from_iso8601: (constructor) + * @text: an ISO 8601 formatted time string. + * @default_tz: (nullable): a #GTimeZone to use if the text doesn't contain a + * timezone, or %NULL. + * + * Creates a #GDateTime corresponding to the given + * [ISO 8601 formatted string](https://en.wikipedia.org/wiki/ISO_8601) + * @text. ISO 8601 strings of the form + + + diff --git a/glib/tests/bookmarks/fail-17.xbel b/glib/tests/bookmarks/fail-17.xbel new file mode 100644 index 0000000..9ad97bd --- /dev/null +++ b/glib/tests/bookmarks/fail-17.xbel @@ -0,0 +1,22 @@ + + + + Singleton + A file containing a single bookmark element + + + + + + + + + + + + diff --git a/glib/tests/bookmarks/fail-18.xbel b/glib/tests/bookmarks/fail-18.xbel new file mode 100644 index 0000000..10f3d80 --- /dev/null +++ b/glib/tests/bookmarks/fail-18.xbel @@ -0,0 +1 @@ +<bookmark:application c=""/><bookmark:application name=""exec=""/ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-19.xbel b/glib/tests/bookmarks/fail-19.xbel new file mode 100644 index 0000000..ab4edbb --- /dev/null +++ b/glib/tests/bookmarks/fail-19.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><mime:mime-type></mime:mime-type><bookmark:applications><bookmark:application name=""exec=""/ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-20.xbel b/glib/tests/bookmarks/fail-20.xbel new file mode 100644 index 0000000..a00e154 --- /dev/null +++ b/glib/tests/bookmarks/fail-20.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE<<><>>></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-21.xbel b/glib/tests/bookmarks/fail-21.xbel new file mode 100644 index 0000000..cf7fbf4 --- /dev/null +++ b/glib/tests/bookmarks/fail-21.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:application e=""/><bookmark:application name=""exec=""/ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-22.xbel b/glib/tests/bookmarks/fail-22.xbel new file mode 100644 index 0000000..abc4ceb --- /dev/null +++ b/glib/tests/bookmarks/fail-22.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:application e=""/><bookmark:application name=""exec=""> \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-23.xbel b/glib/tests/bookmarks/fail-23.xbel new file mode 100644 index 0000000..35324ad --- /dev/null +++ b/glib/tests/bookmarks/fail-23.xbel @@ -0,0 +1 @@ +</ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-24.xbel b/glib/tests/bookmarks/fail-24.xbel new file mode 100644 index 0000000..a8726e6 --- /dev/null +++ b/glib/tests/bookmarks/fail-24.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:application n=""/><bookmark:application name=""exec=""> \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-25.xbel b/glib/tests/bookmarks/fail-25.xbel new file mode 100644 index 0000000..e9bc439 --- /dev/null +++ b/glib/tests/bookmarks/fail-25.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><bookmark:applications></bookmark:applications><bookmark:groups><bookmark:group>< \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-26.xbel b/glib/tests/bookmarks/fail-26.xbel new file mode 100644 index 0000000..739aca2 --- /dev/null +++ b/glib/tests/bookmarks/fail-26.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE<><>></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-27.xbel b/glib/tests/bookmarks/fail-27.xbel new file mode 100644 index 0000000..e402095 --- /dev/null +++ b/glib/tests/bookmarks/fail-27.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"f=""><title><bookmark:application e=""/><bookmark:application name=""exec=""/ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-28.xbel b/glib/tests/bookmarks/fail-28.xbel new file mode 100644 index 0000000..131a97a --- /dev/null +++ b/glib/tests/bookmarks/fail-28.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE<><><>></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-29.xbel b/glib/tests/bookmarks/fail-29.xbel new file mode 100644 index 0000000..2cdcf9f --- /dev/null +++ b/glib/tests/bookmarks/fail-29.xbel @@ -0,0 +1 @@ +<?></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-30.xbel b/glib/tests/bookmarks/fail-30.xbel new file mode 100644 index 0000000..982ea10 --- /dev/null +++ b/glib/tests/bookmarks/fail-30.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE<><<>><>></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-31.xbel b/glib/tests/bookmarks/fail-31.xbel new file mode 100644 index 0000000..4b46cba --- /dev/null +++ b/glib/tests/bookmarks/fail-31.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE<><<>>></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-32.xbel b/glib/tests/bookmarks/fail-32.xbel new file mode 100644 index 0000000..d6de333 --- /dev/null +++ b/glib/tests/bookmarks/fail-32.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-33.xbel b/glib/tests/bookmarks/fail-33.xbel new file mode 100644 index 0000000..a72c6ff --- /dev/null +++ b/glib/tests/bookmarks/fail-33.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE<><><><>></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-34.xbel b/glib/tests/bookmarks/fail-34.xbel new file mode 100644 index 0000000..88214d9 --- /dev/null +++ b/glib/tests/bookmarks/fail-34.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE<<>>></ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-35.xbel b/glib/tests/bookmarks/fail-35.xbel new file mode 100644 index 0000000..2f8fd10 --- /dev/null +++ b/glib/tests/bookmarks/fail-35.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"m=""><title><mime:mime-type></mime:mime-type><mime:mime-type> \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-36.xbel b/glib/tests/bookmarks/fail-36.xbel new file mode 100644 index 0000000..7949a3b --- /dev/null +++ b/glib/tests/bookmarks/fail-36.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><mime:mime-type></mime:mime-type><bookmark:applications><application name=""exec=""> \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-37.xbel b/glib/tests/bookmarks/fail-37.xbel new file mode 100644 index 0000000..785f3b1 --- /dev/null +++ b/glib/tests/bookmarks/fail-37.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel version="1.0"xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><title><mime:mime-type></mime:mime-type><bookmark:applications><bookmark:application name=""exec=""> \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-38.xbel b/glib/tests/bookmarks/fail-38.xbel new file mode 100644 index 0000000..9ef34f3 --- /dev/null +++ b/glib/tests/bookmarks/fail-38.xbel @@ -0,0 +1 @@ +<?><!DOCTYPE><xbel x=""/><o xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"><bookmark:application e=""/><bookmark:application name=""exec=""/ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-39.xbel b/glib/tests/bookmarks/fail-39.xbel new file mode 100644 index 0000000..c57c837 --- /dev/null +++ b/glib/tests/bookmarks/fail-39.xbel @@ -0,0 +1 @@ +<xbel version="1.0"><bookmark href=""><info><metadata owner="http://freedesktop.org"><mime-type/><mime-type/ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-40.xbel b/glib/tests/bookmarks/fail-40.xbel new file mode 100644 index 0000000..9ce48a8 --- /dev/null +++ b/glib/tests/bookmarks/fail-40.xbel @@ -0,0 +1 @@ +<xbel version="1.0"><bookmark href=""><info><metadata owner="http://freedesktop.org"><applications><application name=""exec=""/><application name=""exec=""/ \ No newline at end of file diff --git a/glib/tests/bookmarks/fail-41.xbel b/glib/tests/bookmarks/fail-41.xbel new file mode 100644 index 0000000..8ac0c56 --- /dev/null +++ b/glib/tests/bookmarks/fail-41.xbel @@ -0,0 +1 @@ +<xbel version="1.0"><bookmark href=""added="2T0+819855292164632335"> diff --git a/glib/tests/bookmarks/fail-42.xbel b/glib/tests/bookmarks/fail-42.xbel new file mode 100644 index 0000000..c698d33 --- /dev/null +++ b/glib/tests/bookmarks/fail-42.xbel @@ -0,0 +1 @@ +<xbel version="1.0"><bookmark href=""><info><metadata owner="http://freedesktop.org"><applications><application name=""exec=""timestamp="-77873021800189"> \ No newline at end of file diff --git a/glib/tests/bookmarks/valid-01.xbel b/glib/tests/bookmarks/valid-01.xbel new file mode 100644 index 0000000..c1d4ff5 --- /dev/null +++ b/glib/tests/bookmarks/valid-01.xbel @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xbel version="1.0" + xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks" + xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info" +> <title>Singleton + A file containing a single bookmark element + + + + + + + Office + Multimedia + + + + + + + + \ No newline at end of file diff --git a/glib/tests/bookmarks/valid-02.xbel b/glib/tests/bookmarks/valid-02.xbel new file mode 100644 index 0000000..64afdd8 --- /dev/null +++ b/glib/tests/bookmarks/valid-02.xbel @@ -0,0 +1,17 @@ + + + Singleton + A file containing a single bookmark element + + Milan-Stuttgart + A schedule + + + + + + + + + + diff --git a/glib/tests/bookmarks/valid-03.xbel b/glib/tests/bookmarks/valid-03.xbel new file mode 100644 index 0000000..f3a3341 --- /dev/null +++ b/glib/tests/bookmarks/valid-03.xbel @@ -0,0 +1,22 @@ + + + + Singleton + A file containing a single bookmark element + + + + + + + + + + + + diff --git a/glib/tests/bytes.c b/glib/tests/bytes.c new file mode 100644 index 0000000..8178bc2 --- /dev/null +++ b/glib/tests/bytes.c @@ -0,0 +1,512 @@ +/* + * Copyright 2011 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +#undef G_DISABLE_ASSERT + +#include +#include +#include +#include "glib.h" + +/* Keep in sync with glib/gbytes.c */ +struct _GBytes +{ + gconstpointer data; + gsize size; + gint ref_count; + GDestroyNotify free_func; + gpointer user_data; +}; + +static const gchar *NYAN = "nyannyan"; +static const gsize N_NYAN = 8; + +static void +test_new (void) +{ + const gchar *data; + GBytes *bytes; + gsize size; + + data = "test"; + bytes = g_bytes_new (data, 4); + g_assert_nonnull (bytes); + g_assert_true (g_bytes_get_data (bytes, &size) != data); + g_assert_cmpuint (size, ==, 4); + g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4); + g_assert_cmpmem (data, 4, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes)); + + g_bytes_unref (bytes); +} + +static void +test_new_take (void) +{ + gchar *data; + GBytes *bytes; + gsize size; + + data = g_strdup ("test"); + bytes = g_bytes_new_take (data, 4); + g_assert_nonnull (bytes); + g_assert_true (g_bytes_get_data (bytes, &size) == data); + g_assert_cmpuint (size, ==, 4); + g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4); + + g_bytes_unref (bytes); +} + +static void +test_new_static (void) +{ + const gchar *data; + GBytes *bytes; + gsize size; + + data = "test"; + bytes = g_bytes_new_static (data, 4); + g_assert_nonnull (bytes); + g_assert_true (g_bytes_get_data (bytes, &size) == data); + g_assert_cmpuint (size, ==, 4); + g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4); + + g_bytes_unref (bytes); +} + +static void +test_new_from_bytes (void) +{ + const gchar *data = "smile and wave"; + GBytes *bytes; + GBytes *sub; + + bytes = g_bytes_new (data, 14); + sub = g_bytes_new_from_bytes (bytes, 10, 4); + + g_assert_nonnull (sub); + g_assert_true (g_bytes_get_data (sub, NULL) == ((gchar *)g_bytes_get_data (bytes, NULL)) + 10); + g_bytes_unref (bytes); + + g_assert_cmpmem (g_bytes_get_data (sub, NULL), g_bytes_get_size (sub), "wave", 4); + g_bytes_unref (sub); +} + +/* Verify that creating slices of GBytes reference the top-most bytes + * at the correct offset. Ensure that intermediate GBytes are not referenced. + */ +static void +test_new_from_bytes_slice (void) +{ + GBytes *bytes = g_bytes_new_static ("Some stupid data", strlen ("Some stupid data") + 1); + GBytes *bytes1 = g_bytes_new_from_bytes (bytes, 4, 13); + GBytes *bytes2 = g_bytes_new_from_bytes (bytes1, 1, 12); + GBytes *bytes3 = g_bytes_new_from_bytes (bytes2, 0, 6); + + g_assert_cmpint (bytes->ref_count, ==, 4); + g_assert_cmpint (bytes1->ref_count, ==, 1); + g_assert_cmpint (bytes2->ref_count, ==, 1); + g_assert_cmpint (bytes3->ref_count, ==, 1); + + g_assert_null (bytes->user_data); + g_assert_true (bytes1->user_data == bytes); + g_assert_true (bytes2->user_data == bytes); + g_assert_true (bytes3->user_data == bytes); + + g_assert_cmpint (17, ==, g_bytes_get_size (bytes)); + g_assert_cmpint (13, ==, g_bytes_get_size (bytes1)); + g_assert_cmpint (12, ==, g_bytes_get_size (bytes2)); + g_assert_cmpint (6, ==, g_bytes_get_size (bytes3)); + + g_assert_cmpint (0, ==, strncmp ("Some stupid data", (gchar *)bytes->data, 17)); + g_assert_cmpint (0, ==, strncmp (" stupid data", (gchar *)bytes1->data, 13)); + g_assert_cmpint (0, ==, strncmp ("stupid data", (gchar *)bytes2->data, 12)); + g_assert_cmpint (0, ==, strncmp ("stupid", (gchar *)bytes3->data, 6)); + + g_bytes_unref (bytes); + g_bytes_unref (bytes1); + g_bytes_unref (bytes2); + g_bytes_unref (bytes3); +} + +/* Ensure that referencing an entire GBytes just returns the same bytes + * instance (with incremented reference count) instead of a new instance. + */ +static void +test_new_from_bytes_shared_ref (void) +{ + GBytes *bytes = g_bytes_new_static ("Some data", strlen ("Some data") + 1); + GBytes *other = g_bytes_new_from_bytes (bytes, 0, g_bytes_get_size (bytes)); + + g_assert_true (bytes == other); + g_assert_cmpint (bytes->ref_count, ==, 2); + + g_bytes_unref (bytes); + g_bytes_unref (other); +} + +static void +on_destroy_increment (gpointer data) +{ + gint *count = data; + g_assert_nonnull (count); + (*count)++; +} + +static void +test_new_with_free_func (void) +{ + GBytes *bytes; + gchar *data; + gint count = 0; + gsize size; + + data = "test"; + bytes = g_bytes_new_with_free_func (data, 4, on_destroy_increment, &count); + g_assert_nonnull (bytes); + g_assert_cmpint (count, ==, 0); + g_assert_true (g_bytes_get_data (bytes, &size) == data); + g_assert_cmpuint (size, ==, 4); + g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4); + + g_bytes_unref (bytes); + g_assert_cmpuint (count, ==, 1); +} + +static void +test_hash (void) +{ + GBytes *bytes1; + GBytes *bytes2; + guint hash1; + guint hash2; + + bytes1 = g_bytes_new ("blah", 4); + bytes2 = g_bytes_new ("blah", 4); + + hash1 = g_bytes_hash (bytes1); + hash2 = g_bytes_hash (bytes2); + g_assert_cmpuint (hash1, ==, hash2); + + g_bytes_unref (bytes1); + g_bytes_unref (bytes2); +} + +static void +test_equal (void) +{ + GBytes *bytes; + GBytes *bytes2; + + bytes = g_bytes_new ("blah", 4); + + bytes2 = g_bytes_new ("blah", 4); + g_assert_true (g_bytes_equal (bytes, bytes2)); + g_assert_true (g_bytes_equal (bytes2, bytes)); + g_bytes_unref (bytes2); + + bytes2 = g_bytes_new ("bla", 3); + g_assert_false (g_bytes_equal (bytes, bytes2)); + g_assert_false (g_bytes_equal (bytes2, bytes)); + g_bytes_unref (bytes2); + + bytes2 = g_bytes_new ("true", 4); + g_assert_false (g_bytes_equal (bytes, bytes2)); + g_assert_false (g_bytes_equal (bytes2, bytes)); + g_bytes_unref (bytes2); + + g_bytes_unref (bytes); +} + +static void +test_compare (void) +{ + GBytes *bytes; + GBytes *bytes2; + + bytes = g_bytes_new ("blah", 4); + + bytes2 = g_bytes_new ("blah", 4); + g_assert_cmpint (g_bytes_compare (bytes, bytes2), ==, 0); + g_bytes_unref (bytes2); + + bytes2 = g_bytes_new ("bla", 3); + g_assert_cmpint (g_bytes_compare (bytes, bytes2), >, 0); + g_bytes_unref (bytes2); + + bytes2 = g_bytes_new ("abcd", 4); + g_assert_cmpint (g_bytes_compare (bytes, bytes2), >, 0); + g_bytes_unref (bytes2); + + bytes2 = g_bytes_new ("blahblah", 8); + g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0); + g_bytes_unref (bytes2); + + bytes2 = g_bytes_new ("zyx", 3); + g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0); + g_bytes_unref (bytes2); + + bytes2 = g_bytes_new ("zyxw", 4); + g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0); + g_bytes_unref (bytes2); + + g_bytes_unref (bytes); +} + +static void +test_to_data_transferred (void) +{ + gconstpointer memory; + gpointer data; + gsize size; + GBytes *bytes; + + /* Memory transferred: one reference, and allocated with g_malloc */ + bytes = g_bytes_new (NYAN, N_NYAN); + memory = g_bytes_get_data (bytes, NULL); + data = g_bytes_unref_to_data (bytes, &size); + g_assert_true (data == memory); + g_assert_cmpmem (data, size, NYAN, N_NYAN); + g_free (data); +} + +static void +test_to_data_two_refs (void) +{ + gconstpointer memory; + gpointer data; + gsize size; + GBytes *bytes; + + /* Memory copied: two references */ + bytes = g_bytes_new (NYAN, N_NYAN); + bytes = g_bytes_ref (bytes); + memory = g_bytes_get_data (bytes, NULL); + data = g_bytes_unref_to_data (bytes, &size); + g_assert_true (data != memory); + g_assert_cmpmem (data, size, NYAN, N_NYAN); + g_free (data); + g_assert_true (g_bytes_get_data (bytes, &size) == memory); + g_assert_cmpuint (size, ==, N_NYAN); + g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN); + g_bytes_unref (bytes); +} + +static void +test_to_data_non_malloc (void) +{ + gpointer data; + gsize size; + GBytes *bytes; + + /* Memory copied: non malloc memory */ + bytes = g_bytes_new_static (NYAN, N_NYAN); + g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN); + data = g_bytes_unref_to_data (bytes, &size); + g_assert_true (data != (gpointer)NYAN); + g_assert_cmpmem (data, size, NYAN, N_NYAN); + g_free (data); +} + +static void +test_to_data_different_free_func (void) +{ + gpointer data; + gsize size; + GBytes *bytes; + gchar *sentinel = g_strdup ("hello"); + + /* Memory copied: free func and user_data don’t point to the bytes data */ + bytes = g_bytes_new_with_free_func (NYAN, N_NYAN, g_free, sentinel); + g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN); + + data = g_bytes_unref_to_data (bytes, &size); + g_assert_true (data != (gpointer)NYAN); + g_assert_cmpmem (data, size, NYAN, N_NYAN); + g_free (data); + + /* @sentinel should not be leaked; testing that requires this test to be run + * under valgrind. We can’t use a custom free func to check it isn’t leaked, + * as the point of this test is to hit a condition in `try_steal_and_unref()` + * which is short-circuited if the free func isn’t g_free(). + * See discussion in https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2152 */ +} + +static void +test_to_array_transferred (void) +{ + gconstpointer memory; + GByteArray *array; + GBytes *bytes; + + /* Memory transferred: one reference, and allocated with g_malloc */ + bytes = g_bytes_new (NYAN, N_NYAN); + memory = g_bytes_get_data (bytes, NULL); + array = g_bytes_unref_to_array (bytes); + g_assert_nonnull (array); + g_assert_true (array->data == memory); + g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN); + g_byte_array_unref (array); +} + +static void +test_to_array_transferred_oversize (void) +{ + g_test_message ("g_bytes_unref_to_array() can only take GBytes up to " + "G_MAXUINT in length; test that longer ones are rejected"); + + if (sizeof (guint) >= sizeof (gsize)) + { + g_test_skip ("Skipping test as guint is not smaller than gsize"); + } + else if (g_test_undefined ()) + { + GByteArray *array = NULL; + GBytes *bytes = NULL; + gpointer data = g_memdup2 (NYAN, N_NYAN); + gsize len = ((gsize) G_MAXUINT) + 1; + + bytes = g_bytes_new_take (data, len); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "g_byte_array_new_take: assertion 'len <= G_MAXUINT' failed"); + array = g_bytes_unref_to_array (g_steal_pointer (&bytes)); + g_test_assert_expected_messages (); + g_assert_null (array); + + g_free (data); + } + else + { + g_test_skip ("Skipping test as testing undefined behaviour is disabled"); + } +} + +static void +test_to_array_two_refs (void) +{ + gconstpointer memory; + GByteArray *array; + GBytes *bytes; + gsize size; + + /* Memory copied: two references */ + bytes = g_bytes_new (NYAN, N_NYAN); + bytes = g_bytes_ref (bytes); + memory = g_bytes_get_data (bytes, NULL); + array = g_bytes_unref_to_array (bytes); + g_assert_nonnull (array); + g_assert_true (array->data != memory); + g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN); + g_byte_array_unref (array); + g_assert_true (g_bytes_get_data (bytes, &size) == memory); + g_assert_cmpuint (size, ==, N_NYAN); + g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN); + g_bytes_unref (bytes); +} + +static void +test_to_array_non_malloc (void) +{ + GByteArray *array; + GBytes *bytes; + + /* Memory copied: non malloc memory */ + bytes = g_bytes_new_static (NYAN, N_NYAN); + g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN); + array = g_bytes_unref_to_array (bytes); + g_assert_nonnull (array); + g_assert_true (array->data != (gpointer)NYAN); + g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN); + g_byte_array_unref (array); +} + +static void +test_null (void) +{ + GBytes *bytes; + gpointer data; + gsize size; + + bytes = g_bytes_new (NULL, 0); + + data = g_bytes_unref_to_data (bytes, &size); + + g_assert_null (data); + g_assert_cmpuint (size, ==, 0); +} + +static void +test_get_region (void) +{ + GBytes *bytes; + + bytes = g_bytes_new_static (NYAN, N_NYAN); + + /* simple valid gets at the start */ + g_assert_true (g_bytes_get_region (bytes, 1, 0, 1) == NYAN); + g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN) == NYAN); + + /* an invalid get because the range is too wide */ + g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN + 1) == NULL); + + /* an valid get, but of a zero-byte range at the end */ + g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 0) == NYAN + N_NYAN); + + /* not a valid get because it overlap ones byte */ + g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 1) == NULL); + + /* let's try some multiplication overflow now */ + g_assert_true (g_bytes_get_region (bytes, 32, 0, G_MAXSIZE / 32 + 1) == NULL); + g_assert_true (g_bytes_get_region (bytes, G_MAXSIZE / 32 + 1, 0, 32) == NULL); + + /* and some addition overflow */ + g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, -G_MAXSIZE) == NULL); + g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSSIZE, ((gsize) G_MAXSSIZE) + 1) == NULL); + g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, 1) == NULL); + + g_bytes_unref (bytes); +} + +static void +test_unref_null (void) +{ + g_test_summary ("Test that calling g_bytes_unref() on NULL is a no-op"); + g_bytes_unref (NULL); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/bytes/new", test_new); + g_test_add_func ("/bytes/new-take", test_new_take); + g_test_add_func ("/bytes/new-static", test_new_static); + g_test_add_func ("/bytes/new-with-free-func", test_new_with_free_func); + g_test_add_func ("/bytes/new-from-bytes", test_new_from_bytes); + g_test_add_func ("/bytes/new-from-bytes-slice", test_new_from_bytes_slice); + g_test_add_func ("/bytes/new-from-bytes-shared-ref", test_new_from_bytes_shared_ref); + g_test_add_func ("/bytes/hash", test_hash); + g_test_add_func ("/bytes/equal", test_equal); + g_test_add_func ("/bytes/compare", test_compare); + g_test_add_func ("/bytes/to-data/transferred", test_to_data_transferred); + g_test_add_func ("/bytes/to-data/two-refs", test_to_data_two_refs); + g_test_add_func ("/bytes/to-data/non-malloc", test_to_data_non_malloc); + g_test_add_func ("/bytes/to-data/different-free-func", test_to_data_different_free_func); + g_test_add_func ("/bytes/to-array/transferred", test_to_array_transferred); + g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize); + g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs); + g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc); + g_test_add_func ("/bytes/null", test_null); + g_test_add_func ("/bytes/get-region", test_get_region); + g_test_add_func ("/bytes/unref-null", test_unref_null); + + return g_test_run (); +} diff --git a/glib/tests/cache.c b/glib/tests/cache.c new file mode 100644 index 0000000..e725b73 --- /dev/null +++ b/glib/tests/cache.c @@ -0,0 +1,167 @@ +/* Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +static gint value_create_count = 0; +static gint value_destroy_count = 0; + +static gpointer +value_create (gpointer key) +{ + gint *value; + + value_create_count++; + + value = g_new (gint, 1); + *value = *(gint*)key * 2; + + return value; +} + +static void +value_destroy (gpointer value) +{ + value_destroy_count++; + g_free (value); +} + +static gpointer +key_dup (gpointer key) +{ + gint *newkey; + + newkey = g_new (gint, 1); + *newkey = *(gint*)key; + + return newkey; +} + +static void +key_destroy (gpointer key) +{ + g_free (key); +} + +static guint +key_hash (gconstpointer key) +{ + return *(guint*)key; +} + +static guint +value_hash (gconstpointer value) +{ + return *(guint*)value; +} + +static gboolean +key_equal (gconstpointer key1, gconstpointer key2) +{ + return *(gint*)key1 == *(gint*)key2; +} + +static void +key_foreach (gpointer valuep, gpointer keyp, gpointer data) +{ + gint *count = data; + gint *key = keyp; + + (*count)++; + + g_assert_cmpint (*key, ==, 2); +} + +static void +value_foreach (gpointer keyp, gpointer nodep, gpointer data) +{ + gint *count = data; + gint *key = keyp; + + (*count)++; + + g_assert_cmpint (*key, ==, 2); +} + +static void +test_cache_basic (void) +{ + GCache *c; + gint *key; + gint *value; + gint count; + + value_create_count = 0; + value_destroy_count = 0; + + c = g_cache_new (value_create, value_destroy, + key_dup, key_destroy, + key_hash, value_hash, key_equal); + + key = g_new (gint, 1); + *key = 2; + + value = g_cache_insert (c, key); + g_assert_cmpint (*value, ==, 4); + g_assert_cmpint (value_create_count, ==, 1); + g_assert_cmpint (value_destroy_count, ==, 0); + + count = 0; + g_cache_key_foreach (c, key_foreach, &count); + g_assert_cmpint (count, ==, 1); + + count = 0; + g_cache_value_foreach (c, value_foreach, &count); + g_assert_cmpint (count, ==, 1); + + value = g_cache_insert (c, key); + g_assert_cmpint (*value, ==, 4); + g_assert_cmpint (value_create_count, ==, 1); + g_assert_cmpint (value_destroy_count, ==, 0); + + g_cache_remove (c, value); + g_assert_cmpint (value_create_count, ==, 1); + g_assert_cmpint (value_destroy_count, ==, 0); + + g_cache_remove (c, value); + g_assert_cmpint (value_create_count, ==, 1); + g_assert_cmpint (value_destroy_count, ==, 1); + + value = g_cache_insert (c, key); + g_assert_cmpint (*value, ==, 4); + g_assert_cmpint (value_create_count, ==, 2); + g_assert_cmpint (value_destroy_count, ==, 1); + + g_cache_remove (c, value); + g_cache_destroy (c); + g_free (key); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/cache/basic", test_cache_basic); + + return g_test_run (); + +} diff --git a/glib/tests/casefold.txt b/glib/tests/casefold.txt new file mode 100644 index 0000000..b223771 --- /dev/null +++ b/glib/tests/casefold.txt @@ -0,0 +1,1499 @@ +# Test cases generated from Unicode 13.0.0 data +# by gen-casefold-txt.py. Do not edit. +# +# Some special hand crafted tests +# +AaBbCc@@ aabbcc@@ +# +# Now the automatic tests +# +A a +B b +C c +D d +E e +F f +G g +H h +I i +J j +K k +L l +M m +N n +O o +P p +Q q +R r +S s +T t +U u +V v +W w +X x +Y y +Z z +µ μ +À à +à á + â +à ã +Ä ä +Ã… Ã¥ +Æ æ +Ç ç +È è +É é +Ê ê +Ë ë +ÃŒ ì +à í +ÃŽ î +à ï +à ð +Ñ ñ +Ã’ ò +Ó ó +Ô ô +Õ õ +Ö ö +Ø ø +Ù ù +Ú ú +Û û +Ü ü +à ý +Þ þ +ß ss +Ä€ Ä +Ä‚ ă +Ä„ Ä… +Ć ć +Ĉ ĉ +ÄŠ Ä‹ +ÄŒ Ä +ÄŽ Ä +Ä Ä‘ +Ä’ Ä“ +Ä” Ä• +Ä– Ä— +Ę Ä™ +Äš Ä› +Äœ Ä +Äž ÄŸ +Ä  Ä¡ +Ä¢ Ä£ +Ĥ Ä¥ +Ħ ħ +Ĩ Ä© +Ī Ä« +Ĭ Ä­ +Ä® į +İ i̇ +IJ ij +Ä´ ĵ +Ķ Ä· +Ĺ ĺ +Ä» ļ +Ľ ľ +Ä¿ Å€ +Å Å‚ +Ń Å„ +Å… ņ +Ň ň +ʼn ʼn +ÅŠ Å‹ +ÅŒ Å +ÅŽ Å +Å Å‘ +Å’ Å“ +Å” Å• +Å– Å— +Ř Å™ +Åš Å› +Åœ Å +Åž ÅŸ +Å  Å¡ +Å¢ Å£ +Ť Å¥ +Ŧ ŧ +Ũ Å© +Ū Å« +Ŭ Å­ +Å® ů +Ű ű +Ų ų +Å´ ŵ +Ŷ Å· +Ÿ ÿ +Ź ź +Å» ż +Ž ž +Å¿ s +Æ É“ +Æ‚ ƃ +Æ„ Æ… +Ɔ É” +Ƈ ƈ +Ɖ É– +ÆŠ É— +Æ‹ ÆŒ +ÆŽ Ç +Æ É™ +Æ É› +Æ‘ Æ’ +Æ“ É  +Æ” É£ +Æ– É© +Æ— ɨ +Ƙ Æ™ +Æœ ɯ +Æ É² +ÆŸ ɵ +Æ  Æ¡ +Æ¢ Æ£ +Ƥ Æ¥ +Ʀ Ê€ +Ƨ ƨ +Æ© ʃ +Ƭ Æ­ +Æ® ʈ +Ư ư +Ʊ ÊŠ +Ʋ Ê‹ +Ƴ Æ´ +Ƶ ƶ +Æ· Ê’ +Ƹ ƹ +Ƽ ƽ +Ç„ dž +Ç… dž +LJ lj +Lj lj +ÇŠ ÇŒ +Ç‹ ÇŒ +Ç ÇŽ +Ç Ç +Ç‘ Ç’ +Ç“ Ç” +Ç• Ç– +Ç— ǘ +Ç™ Çš +Ç› Çœ +Çž ÇŸ +Ç  Ç¡ +Ç¢ Ç£ +Ǥ Ç¥ +Ǧ ǧ +Ǩ Ç© +Ǫ Ç« +Ǭ Ç­ +Ç® ǯ +ǰ jÌŒ +DZ dz +Dz dz +Ç´ ǵ +Ƕ Æ• +Ç· Æ¿ +Ǹ ǹ +Ǻ Ç» +Ǽ ǽ +Ǿ Ç¿ +È€ È +È‚ ȃ +È„ È… +Ȇ ȇ +Ȉ ȉ +ÈŠ È‹ +ÈŒ È +ÈŽ È +È È‘ +È’ È“ +È” È• +È– È— +Ș È™ +Èš È› +Èœ È +Èž ÈŸ +È  Æž +È¢ È£ +Ȥ È¥ +Ȧ ȧ +Ȩ È© +Ȫ È« +Ȭ È­ +È® ȯ +Ȱ ȱ +Ȳ ȳ +Ⱥ â±¥ +È» ȼ +Ƚ Æš +Ⱦ ⱦ +É É‚ +Ƀ Æ€ +É„ ʉ +É… ÊŒ +Ɇ ɇ +Ɉ ɉ +ÉŠ É‹ +ÉŒ É +ÉŽ É +Í… ι +Ͱ ͱ +Ͳ ͳ +Ͷ Í· +Í¿ ϳ +Ά ά +Έ έ +Ή ή +Ί ί +ÎŒ ÏŒ +ÎŽ Ï +Î ÏŽ +Î Î¹ÌˆÌ +Α α +Î’ β +Γ γ +Δ δ +Ε ε +Ζ ζ +Η η +Θ θ +Ι ι +Κ κ +Λ λ +Μ μ +Πν +Ξ ξ +Ο ο +Π Ï€ +Ρ Ï +Σ σ +Τ Ï„ +Î¥ Ï… +Φ φ +Χ χ +Ψ ψ +Ω ω +Ϊ ÏŠ +Ϋ Ï‹ +ΰ Ï…ÌˆÌ +Ï‚ σ +Ï Ï— +Ï Î² +Ï‘ θ +Ï• φ +Ï– Ï€ +Ϙ Ï™ +Ïš Ï› +Ïœ Ï +Ïž ÏŸ +Ï  Ï¡ +Ï¢ Ï£ +Ϥ Ï¥ +Ϧ ϧ +Ϩ Ï© +Ϫ Ï« +Ϭ Ï­ +Ï® ϯ +ϰ κ +ϱ Ï +Ï´ θ +ϵ ε +Ï· ϸ +Ϲ ϲ +Ϻ Ï» +Ͻ Í» +Ͼ ͼ +Ï¿ ͽ +Ѐ Ñ +Ð Ñ‘ +Ђ Ñ’ +Ѓ Ñ“ +Є Ñ” +Ð… Ñ• +І Ñ– +Ї Ñ— +Ј ј +Љ Ñ™ +Њ Ñš +Ћ Ñ› +ÐŒ Ñœ +Ð Ñ +ÐŽ Ñž +Ð ÑŸ +Ра +Б б +Ð’ в +Г г +Д д +Е е +Ж ж +З з +И и +Й й +К к +Л л +М м +Рн +О о +П п +Р Ñ€ +С Ñ +Т Ñ‚ +У у +Ф Ñ„ +Ð¥ Ñ… +Ц ц +Ч ч +Ш ш +Щ щ +Ъ ÑŠ +Ы Ñ‹ +Ь ÑŒ +Э Ñ +Ю ÑŽ +Я Ñ +Ñ  Ñ¡ +Ñ¢ Ñ£ +Ѥ Ñ¥ +Ѧ ѧ +Ѩ Ñ© +Ѫ Ñ« +Ѭ Ñ­ +Ñ® ѯ +Ѱ ѱ +Ѳ ѳ +Ñ´ ѵ +Ѷ Ñ· +Ѹ ѹ +Ѻ Ñ» +Ѽ ѽ +Ѿ Ñ¿ +Ò€ Ò +ÒŠ Ò‹ +ÒŒ Ò +ÒŽ Ò +Ò Ò‘ +Ò’ Ò“ +Ò” Ò• +Ò– Ò— +Ò˜ Ò™ +Òš Ò› +Òœ Ò +Òž ÒŸ +Ò  Ò¡ +Ò¢ Ò£ +Ò¤ Ò¥ +Ò¦ Ò§ +Ò¨ Ò© +Òª Ò« +Ò¬ Ò­ +Ò® Ò¯ +Ò° Ò± +Ò² Ò³ +Ò´ Òµ +Ò¶ Ò· +Ò¸ Ò¹ +Òº Ò» +Ò¼ Ò½ +Ò¾ Ò¿ +Ó€ Ó +Ó Ó‚ +Óƒ Ó„ +Ó… Ó† +Ó‡ Óˆ +Ó‰ ÓŠ +Ó‹ ÓŒ +Ó ÓŽ +Ó Ó‘ +Ó’ Ó“ +Ó” Ó• +Ó– Ó— +Ó˜ Ó™ +Óš Ó› +Óœ Ó +Óž ÓŸ +Ó  Ó¡ +Ó¢ Ó£ +Ó¤ Ó¥ +Ó¦ Ó§ +Ó¨ Ó© +Óª Ó« +Ó¬ Ó­ +Ó® Ó¯ +Ó° Ó± +Ó² Ó³ +Ó´ Óµ +Ó¶ Ó· +Ó¸ Ó¹ +Óº Ó» +Ó¼ Ó½ +Ó¾ Ó¿ +Ô€ Ô +Ô‚ Ôƒ +Ô„ Ô… +Ô† Ô‡ +Ôˆ Ô‰ +ÔŠ Ô‹ +ÔŒ Ô +ÔŽ Ô +Ô Ô‘ +Ô’ Ô“ +Ô” Ô• +Ô– Ô— +Ô˜ Ô™ +Ôš Ô› +Ôœ Ô +Ôž ÔŸ +Ô  Ô¡ +Ô¢ Ô£ +Ô¤ Ô¥ +Ô¦ Ô§ +Ô¨ Ô© +Ôª Ô« +Ô¬ Ô­ +Ô® Ô¯ +Ô± Õ¡ +Ô² Õ¢ +Ô³ Õ£ +Ô´ Õ¤ +Ôµ Õ¥ +Ô¶ Õ¦ +Ô· Õ§ +Ô¸ Õ¨ +Ô¹ Õ© +Ôº Õª +Ô» Õ« +Ô¼ Õ¬ +Ô½ Õ­ +Ô¾ Õ® +Ô¿ Õ¯ +Õ€ Õ° +Õ Õ± +Õ‚ Õ² +Õƒ Õ³ +Õ„ Õ´ +Õ… Õµ +Õ† Õ¶ +Õ‡ Õ· +Õˆ Õ¸ +Õ‰ Õ¹ +ÕŠ Õº +Õ‹ Õ» +ÕŒ Õ¼ +Õ Õ½ +ÕŽ Õ¾ +Õ Õ¿ +Õ Ö€ +Õ‘ Ö +Õ’ Ö‚ +Õ“ Öƒ +Õ” Ö„ +Õ• Ö… +Õ– Ö† +Ö‡ Õ¥Ö‚ +á‚  â´€ +á‚¡ â´ +á‚¢ â´‚ +á‚£ â´ƒ +Ⴄ â´„ +á‚¥ â´… +Ⴆ â´† +á‚§ â´‡ +Ⴈ â´ˆ +á‚© â´‰ +Ⴊ â´Š +á‚« â´‹ +Ⴌ â´Œ +á‚­ â´ +á‚® â´Ž +Ⴏ â´ +á‚° â´ +Ⴑ â´‘ +Ⴒ â´’ +Ⴓ â´“ +á‚´ â´” +Ⴕ â´• +á‚¶ â´– +á‚· â´— +Ⴘ â´˜ +Ⴙ â´™ +Ⴚ â´š +á‚» â´› +Ⴜ â´œ +Ⴝ â´ +Ⴞ â´ž +á‚¿ â´Ÿ +Ⴠ â´  +რⴡ +Ⴢ â´¢ +Ⴣ â´£ +Ⴤ â´¤ +Ⴥ â´¥ +Ⴧ â´§ +რⴭ +Ḡᰠ+á¹ á± +ẠᲠ+á» á³ +á¼ á´ +á½ áµ +á²€ в +Რд +ᲂ о +ᲃ Ñ +ᲄ Ñ‚ +á²… Ñ‚ +ᲆ ÑŠ +ᲇ Ñ£ +ᲈ ꙋ +Რრ+Ბ ბ +á²’ გ +Დ დ +á²” ე +Ვ ვ +á²– ზ +á²— თ +Ი ი +á²™ კ +Ლ ლ +á²› მ +Ნ ნ +Რრ+Პ პ +Ჟ ჟ +á²  რ +Ს ს +á²¢ ტ +á²£ უ +Ფ ფ +á²¥ ქ +Ღ ღ +á²§ ყ +Შ შ +Ჩ ჩ +Ც ც +Ძ ძ +Წ წ +á²­ ჭ +á²® ხ +Ჯ ჯ +á²° ჰ +á²± ჱ +á²² ჲ +á²³ ჳ +á²´ ჴ +á²µ ჵ +á²¶ ჶ +á²· ჷ +Ჸ ჸ +á²¹ ჹ +Ჺ ჺ +á²½ ჽ +á²¾ ჾ +Ჿ ჿ +Ḁ Ḡ+Ḃ ḃ +Ḅ ḅ +Ḇ ḇ +Ḉ ḉ +Ḋ ḋ +Ḍ Ḡ+Ḏ Ḡ+Ḡḑ +Ḓ ḓ +Ḕ ḕ +Ḗ ḗ +Ḙ ḙ +Ḛ ḛ +Ḝ Ḡ+Ḟ ḟ +Ḡ ḡ +Ḣ ḣ +Ḥ ḥ +Ḧ ḧ +Ḩ ḩ +Ḫ ḫ +Ḭ ḭ +Ḯ ḯ +Ḱ ḱ +Ḳ ḳ +Ḵ ḵ +Ḷ ḷ +Ḹ ḹ +Ḻ ḻ +Ḽ ḽ +Ḿ ḿ +á¹€ á¹ +Ṃ ṃ +Ṅ á¹… +Ṇ ṇ +Ṉ ṉ +Ṋ ṋ +Ṍ á¹ +Ṏ á¹ +Ṡṑ +á¹’ ṓ +á¹” ṕ +á¹– á¹— +Ṙ á¹™ +Ṛ á¹› +Ṝ á¹ +Ṟ ṟ +á¹  ṡ +á¹¢ á¹£ +Ṥ á¹¥ +Ṧ á¹§ +Ṩ ṩ +Ṫ ṫ +Ṭ á¹­ +á¹® ṯ +á¹° á¹± +á¹² á¹³ +á¹´ á¹µ +á¹¶ á¹· +Ṹ á¹¹ +Ṻ á¹» +á¹¼ á¹½ +á¹¾ ṿ +Ẁ Ạ+Ẃ ẃ +Ẅ ẅ +Ẇ ẇ +Ẉ ẉ +Ẋ ẋ +Ẍ Ạ+Ẏ Ạ+Ạẑ +Ẓ ẓ +Ẕ ẕ +ẖ ẖ +ẗ ẗ +ẘ wÌŠ +ẙ yÌŠ +ẚ aʾ +ẛ ṡ +ẞ ss +Ạ ạ +Ả ả +Ấ ấ +Ầ ầ +Ẩ ẩ +Ẫ ẫ +Ậ ậ +Ắ ắ +Ằ ằ +Ẳ ẳ +Ẵ ẵ +Ặ ặ +Ẹ ẹ +Ẻ ẻ +Ẽ ẽ +Ế ế +Ề á» +Ể ể +Ễ á»… +Ệ ệ +Ỉ ỉ +Ị ị +Ọ á» +Ỏ á» +Ỡố +á»’ ồ +á»” ổ +á»– á»— +Ộ á»™ +Ớ á»› +Ờ á» +Ở ở +á»  ỡ +Ợ ợ +Ụ ụ +Ủ á»§ +Ứ ứ +Ừ ừ +Ử á»­ +á»® ữ +á»° á»± +Ỳ ỳ +á»´ ỵ +á»¶ á»· +Ỹ ỹ +Ỻ á»» +Ỽ ỽ +Ỿ ỿ +Ἀ á¼€ +Ἁ á¼ +Ἂ ἂ +Ἃ ἃ +Ἄ ἄ +á¼ á¼… +Ἆ ἆ +ἠἇ +Ἐ á¼ +á¼™ ἑ +Ἒ á¼’ +á¼› ἓ +Ἔ á¼” +ἠἕ +Ἠ á¼  +Ἡ ἡ +Ἢ á¼¢ +Ἣ á¼£ +Ἤ ἤ +á¼­ á¼¥ +á¼® ἦ +Ἧ á¼§ +Ἰ á¼° +á¼¹ á¼± +Ἲ á¼² +á¼» á¼³ +á¼¼ á¼´ +á¼½ á¼µ +á¼¾ á¼¶ +Ἷ á¼· +Ὀ á½€ +Ὁ á½ +Ὂ ὂ +Ὃ ὃ +Ὄ ὄ +á½ á½… +á½ Ï…Ì“ +á½’ ὒ +á½” Ï…Ì“Ì +á½– ὖ +á½™ ὑ +á½› ὓ +ὠὕ +Ὗ á½— +Ὠ á½  +Ὡ ὡ +Ὢ á½¢ +Ὣ á½£ +Ὤ ὤ +á½­ á½¥ +á½® ὦ +Ὧ á½§ +á¾€ ἀι +á¾ á¼Î¹ +ᾂ ἂι +ᾃ ἃι +ᾄ ἄι +á¾… ἅι +ᾆ ἆι +ᾇ ἇι +ᾈ ἀι +ᾉ á¼Î¹ +ᾊ ἂι +ᾋ ἃι +ᾌ ἄι +ᾠἅι +ᾎ ἆι +ᾠἇι +ᾠἠι +ᾑ ἡι +á¾’ ἢι +ᾓ ἣι +á¾” ἤι +ᾕ ἥι +á¾– ἦι +á¾— ἧι +ᾘ ἠι +á¾™ ἡι +ᾚ ἢι +á¾› ἣι +ᾜ ἤι +ᾠἥι +ᾞ ἦι +ᾟ ἧι +á¾  ὠι +ᾡ ὡι +á¾¢ ὢι +á¾£ ὣι +ᾤ ὤι +á¾¥ ὥι +ᾦ ὦι +á¾§ ὧι +ᾨ ὠι +ᾩ ὡι +ᾪ ὢι +ᾫ ὣι +ᾬ ὤι +á¾­ ὥι +á¾® ὦι +ᾯ ὧι +á¾² ὰι +á¾³ αι +á¾´ άι +á¾¶ ᾶ +á¾· ᾶι +Ᾰ á¾° +á¾¹ á¾± +Ὰ á½° +á¾» á½± +á¾¼ αι +á¾¾ ι +á¿‚ ὴι +ῃ ηι +á¿„ ήι +ῆ ῆ +ῇ ῆι +Ὲ á½² +Έ á½³ +Ὴ á½´ +á¿‹ á½µ +ῌ ηι +á¿’ ῒ +á¿“ Î¹ÌˆÌ +á¿– ῖ +á¿— ῗ +Ῐ á¿ +á¿™ á¿‘ +Ὶ á½¶ +á¿› á½· +á¿¢ ῢ +á¿£ Ï…ÌˆÌ +ῤ ÏÌ“ +ῦ Ï…Í‚ +á¿§ ῧ +Ῠ á¿  +á¿© á¿¡ +Ὺ ὺ +á¿« á½» +Ῥ á¿¥ +ῲ ὼι +ῳ ωι +á¿´ ώι +á¿¶ ῶ +á¿· ῶι +Ὸ ὸ +Ό á½¹ +Ὼ á½¼ +á¿» á½½ +ῼ ωι +Ω ω +K k +â„« Ã¥ +Ⅎ â…Ž +â…  â…° +â…¡ â…± +â…¢ â…² +â…£ â…³ +â…¤ â…´ +â…¥ â…µ +â…¦ â…¶ +â…§ â…· +â…¨ â…¸ +â…© â…¹ +â…ª â…º +â…« â…» +â…¬ â…¼ +â…­ â…½ +â…® â…¾ +â…¯ â…¿ +Ↄ ↄ +â’¶ â“ +â’· â“‘ +â’¸ â“’ +â’¹ â““ +â’º â“” +â’» â“• +â’¼ â“– +â’½ â“— +â’¾ ⓘ +â’¿ â“™ +â“€ ⓚ +â“ â“› +â“‚ ⓜ +Ⓝ â“ +â“„ ⓞ +â“… ⓟ +Ⓠ â“  +Ⓡ â“¡ +Ⓢ â“¢ +Ⓣ â“£ +Ⓤ ⓤ +â“‹ â“¥ +Ⓦ ⓦ +â“ â“§ +Ⓨ ⓨ +â“ â“© +â°€ â°° +â° â°± +â°‚ â°² +â°ƒ â°³ +â°„ â°´ +â°… â°µ +â°† â°¶ +â°‡ â°· +â°ˆ â°¸ +â°‰ â°¹ +â°Š â°º +â°‹ â°» +â°Œ â°¼ +â° â°½ +â°Ž â°¾ +â° â°¿ +â° â±€ +â°‘ â± +â°’ ⱂ +â°“ ⱃ +â°” ⱄ +â°• â±… +â°– ⱆ +â°— ⱇ +â°˜ ⱈ +â°™ ⱉ +â°š ⱊ +â°› ⱋ +â°œ ⱌ +â° â± +â°ž ⱎ +â°Ÿ â± +â°  â± +â°¡ ⱑ +â°¢ â±’ +â°£ ⱓ +â°¤ â±” +â°¥ ⱕ +â°¦ â±– +â°§ â±— +â°¨ ⱘ +â°© â±™ +â°ª ⱚ +â°« â±› +â°¬ ⱜ +â°­ â± +â°® ⱞ +â±  ⱡ +â±¢ É« +â±£ áµ½ +Ɽ ɽ +â±§ ⱨ +Ⱪ ⱪ +Ⱬ ⱬ +â±­ É‘ +â±® ɱ +Ɐ É +â±° É’ +â±² â±³ +â±µ â±¶ +â±¾ È¿ +Ɀ É€ +â²€ â² +Ⲃ ⲃ +Ⲅ â²… +Ⲇ ⲇ +Ⲉ ⲉ +Ⲋ ⲋ +Ⲍ â² +Ⲏ â² +Ⲡⲑ +â²’ ⲓ +â²” ⲕ +â²– â²— +Ⲙ â²™ +Ⲛ â²› +Ⲝ â² +Ⲟ ⲟ +â²  ⲡ +â²¢ â²£ +Ⲥ â²¥ +Ⲧ â²§ +Ⲩ ⲩ +Ⲫ ⲫ +Ⲭ â²­ +â²® ⲯ +â²° â²± +â²² â²³ +â²´ â²µ +â²¶ â²· +Ⲹ â²¹ +Ⲻ â²» +â²¼ â²½ +â²¾ ⲿ +â³€ â³ +Ⳃ ⳃ +Ⳅ â³… +Ⳇ ⳇ +Ⳉ ⳉ +Ⳋ ⳋ +Ⳍ â³ +Ⳏ â³ +Ⳡⳑ +â³’ ⳓ +â³” ⳕ +â³– â³— +Ⳙ â³™ +Ⳛ â³› +Ⳝ â³ +Ⳟ ⳟ +â³  ⳡ +â³¢ â³£ +Ⳬ ⳬ +â³­ â³® +â³² â³³ +Ꙁ ê™ +Ꙃ ꙃ +Ꙅ ê™… +Ꙇ ꙇ +Ꙉ ꙉ +Ꙋ ꙋ +Ꙍ ê™ +Ꙏ ê™ +ê™ ê™‘ +ê™’ ꙓ +ê™” ꙕ +ê™– ê™— +Ꙙ ê™™ +Ꙛ ê™› +Ꙝ ê™ +Ꙟ ꙟ +ê™  ꙡ +Ꙣ ꙣ +Ꙥ ꙥ +Ꙧ ê™§ +Ꙩ ꙩ +Ꙫ ꙫ +Ꙭ ê™­ +Ꚁ êš +êš‚ ꚃ +êš„ êš… +Ꚇ ꚇ +Ꚉ ꚉ +Ꚋ êš‹ +Ꚍ êš +Ꚏ êš +êš êš‘ +êš’ êš“ +êš” êš• +êš– êš— +Ꚙ êš™ +êšš êš› +Ꜣ ꜣ +Ꜥ ꜥ +Ꜧ ꜧ +Ꜩ ꜩ +Ꜫ ꜫ +Ꜭ ꜭ +Ꜯ ꜯ +Ꜳ ꜳ +Ꜵ ꜵ +Ꜷ ꜷ +Ꜹ ꜹ +Ꜻ ꜻ +Ꜽ ꜽ +Ꜿ ꜿ +ê€ ê +ê‚ êƒ +ê„ ê… +ê† ê‡ +êˆ ê‰ +êŠ ê‹ +êŒ ê +êŽ ê +ê ê‘ +ê’ ê“ +ê” ê• +ê– ê— +ê˜ ê™ +êš ê› +êœ ê +êž êŸ +ê  ê¡ +ê¢ ê£ +ê¤ ê¥ +ê¦ ê§ +ê¨ ê© +êª ê« +ê¬ ê­ +ê® ê¯ +ê¹ êº +ê» ê¼ +ê½ áµ¹ +ê¾ ê¿ +Ꞁ êž +êž‚ ꞃ +êž„ êž… +Ꞇ ꞇ +êž‹ ꞌ +êž É¥ +êž êž‘ +êž’ êž“ +êž– êž— +Ꞙ êž™ +êžš êž› +êžœ êž +êžž ꞟ +êž  êž¡ +Ꞣ ꞣ +Ꞥ ꞥ +Ꞧ êž§ +Ꞩ êž© +Ɦ ɦ +êž« Éœ +Ɡ É¡ +êž­ ɬ +êž® ɪ +êž° Êž +êž± ʇ +êž² Ê +êž³ ê­“ +êž´ êžµ +êž¶ êž· +Ꞹ êž¹ +Ꞻ êž» +êž¼ êž½ +êž¾ êž¿ +Ꟃ ꟃ +Ꞔ êž” +Ʂ Ê‚ +Ᶎ á¶Ž +Ꟈ ꟈ +Ꟊ ꟊ +Ꟶ ꟶ +ê­° Ꭰ +ê­± Ꭱ +ê­² Ꭲ +ê­³ Ꭳ +ê­´ Ꭴ +ê­µ Ꭵ +ê­¶ Ꭶ +ê­· Ꭷ +ê­¸ Ꭸ +ê­¹ Ꭹ +ê­º Ꭺ +ê­» Ꭻ +ê­¼ Ꭼ +ê­½ Ꭽ +ê­¾ Ꭾ +ê­¿ Ꭿ +ꮀ Ꮀ +ê® áŽ± +ꮂ Ꮂ +ꮃ Ꮃ +ꮄ Ꮄ +ê®… Ꮅ +ꮆ Ꮆ +ꮇ Ꮇ +ꮈ Ꮈ +ꮉ Ꮉ +ꮊ Ꮊ +ꮋ Ꮋ +ꮌ Ꮌ +ê® áŽ½ +ꮎ Ꮎ +ê® áŽ¿ +ê® á€ +ꮑ á +ê®’ á‚ +ꮓ რ+ê®” á„ +ꮕ á… +ê®– ᆠ+ê®— ᇠ+ꮘ ሠ+ê®™ በ+ꮚ አ+ê®› á‹ +ꮜ ጠ+ê® á +ꮞ Ꭰ+ꮟ á +ê®  á +ꮡ á‘ +ꮢ á’ +ꮣ á“ +ꮤ á” +ꮥ á• +ꮦ á– +ê®§ á— +ꮨ ᘠ+ꮩ á™ +ꮪ áš +ꮫ á› +ꮬ ᜠ+ê®­ á +ê®® áž +ꮯ ០+ê®° á  +ê®± á¡ +ꮲ ᢠ+ꮳ ᣠ+ê®´ ᤠ+ꮵ ᥠ+ê®¶ ᦠ+ê®· á§ +ꮸ ᨠ+ꮹ á© +ꮺ ᪠+ê®» á« +ꮼ ᬠ+ꮽ á­ +ꮾ á® +ꮿ ᯠ+ff ff +ï¬ fi +fl fl +ffi ffi +ffl ffl +ſt st +st st +ﬓ Õ´Õ¶ +ﬔ Õ´Õ¥ +ﬕ Õ´Õ« +ﬖ Õ¾Õ¶ +ﬗ Õ´Õ­ +A ï½ +ï¼¢ b +ï¼£ c +D d +ï¼¥ ï½… +F f +ï¼§ g +H h +I i +J j +K k +L l +ï¼­ ï½ +ï¼® n +O ï½ +ï¼° ï½ +ï¼± q +ï¼² ï½’ +ï¼³ s +ï¼´ ï½” +ï¼µ u +ï¼¶ ï½– +ï¼· ï½— +X x +ï¼¹ ï½™ +Z z +ð€ ð¨ +ð ð© +ð‚ ðª +ðƒ ð« +ð„ ð¬ +ð… ð­ +ð† ð® +ð‡ ð¯ +ðˆ ð° +ð‰ ð± +ðŠ ð² +ð‹ ð³ +ðŒ ð´ +ð ðµ +ðŽ ð¶ +ð ð· +ð ð¸ +ð‘ ð¹ +ð’ ðº +ð“ ð» +ð” ð¼ +ð• ð½ +ð– ð¾ +ð— ð¿ +ð˜ ð‘€ +ð™ ð‘ +ðš ð‘‚ +ð› 𑃠+ðœ ð‘„ +ð ð‘… +ðž 𑆠+ðŸ 𑇠+ð  𑈠+ð¡ 𑉠+ð¢ 𑊠+ð£ ð‘‹ +ð¤ 𑌠+ð¥ ð‘ +ð¦ 𑎠+ð§ ð‘ +𒰠𓘠+ð’± ð“™ +𒲠𓚠+ð’³ ð“› +𒴠𓜠+ð’µ ð“ +𒶠𓞠+𒷠𓟠+ð’¸ ð“  +ð’¹ ð“¡ +ð’º ð“¢ +ð’» ð“£ +𒼠𓤠+ð’½ ð“¥ +𒾠𓦠+ð’¿ ð“§ +𓀠𓨠+ð“ ð“© +𓂠𓪠+𓃠𓫠+𓄠𓬠+ð“… ð“­ +𓆠𓮠+𓇠𓯠+𓈠𓰠+𓉠𓱠+𓊠𓲠+𓋠𓳠+𓌠𓴠+ð“ 𓵠+𓎠𓶠+ð“ ð“· +ð“ 𓸠+𓑠𓹠+𓒠𓺠+ð““ ð“» +ð²€ ð³€ +ð² ð³ +𲂠𳂠+𲃠𳃠+𲄠𳄠+ð²… ð³… +𲆠𳆠+𲇠𳇠+𲈠𳈠+𲉠𳉠+𲊠𳊠+𲋠𳋠+𲌠𳌠+ð² ð³ +𲎠𳎠+ð² ð³ +ð² ð³ +𲑠𳑠+ð²’ ð³’ +𲓠𳓠+ð²” ð³” +𲕠𳕠+ð²– ð³– +ð²— ð³— +𲘠𳘠+ð²™ ð³™ +𲚠𳚠+ð²› ð³› +𲜠𳜠+ð² ð³ +𲞠𳞠+𲟠𳟠+ð²  ð³  +𲡠𳡠+ð²¢ ð³¢ +ð²£ ð³£ +𲤠𳤠+ð²¥ ð³¥ +𲦠𳦠+ð²§ ð³§ +𲨠𳨠+𲩠𳩠+𲪠𳪠+𲫠𳫠+𲬠𳬠+ð²­ ð³­ +ð²® ð³® +𲯠𳯠+ð²° ð³° +ð²± ð³± +ð²² ð³² +ð‘¢  ð‘£€ +𑢡 ð‘£ +ð‘¢¢ 𑣂 +ð‘¢£ 𑣃 +𑢤 𑣄 +ð‘¢¥ ð‘£… +𑢦 𑣆 +ð‘¢§ 𑣇 +𑢨 𑣈 +𑢩 𑣉 +𑢪 𑣊 +𑢫 𑣋 +𑢬 𑣌 +ð‘¢­ ð‘£ +ð‘¢® 𑣎 +𑢯 ð‘£ +ð‘¢° ð‘£ +ð‘¢± 𑣑 +ð‘¢² ð‘£’ +ð‘¢³ 𑣓 +ð‘¢´ ð‘£” +ð‘¢µ 𑣕 +ð‘¢¶ ð‘£– +ð‘¢· ð‘£— +𑢸 𑣘 +ð‘¢¹ ð‘£™ +𑢺 𑣚 +ð‘¢» ð‘£› +ð‘¢¼ 𑣜 +ð‘¢½ ð‘£ +ð‘¢¾ 𑣞 +𑢿 𑣟 +ð–¹€ ð–¹  +𖹠𖹡 +𖹂 ð–¹¢ +𖹃 ð–¹£ +𖹄 𖹤 +ð–¹… ð–¹¥ +𖹆 𖹦 +𖹇 ð–¹§ +𖹈 𖹨 +𖹉 𖹩 +𖹊 𖹪 +𖹋 𖹫 +𖹌 𖹬 +ð–¹ ð–¹­ +𖹎 ð–¹® +𖹠𖹯 +ð–¹ ð–¹° +𖹑 ð–¹± +ð–¹’ ð–¹² +𖹓 ð–¹³ +ð–¹” ð–¹´ +𖹕 ð–¹µ +ð–¹– ð–¹¶ +ð–¹— ð–¹· +𖹘 𖹸 +ð–¹™ ð–¹¹ +𖹚 𖹺 +ð–¹› ð–¹» +𖹜 ð–¹¼ +ð–¹ ð–¹½ +𖹞 ð–¹¾ +𖹟 𖹿 +𞤀 𞤢 +𞤠𞤣 +𞤂 𞤤 +𞤃 𞤥 +𞤄 𞤦 +𞤅 𞤧 +𞤆 𞤨 +𞤇 𞤩 +𞤈 𞤪 +𞤉 𞤫 +𞤊 𞤬 +𞤋 𞤭 +𞤌 𞤮 +𞤠𞤯 +𞤎 𞤰 +𞤠𞤱 +𞤠𞤲 +𞤑 𞤳 +𞤒 𞤴 +𞤓 𞤵 +𞤔 𞤶 +𞤕 𞤷 +𞤖 𞤸 +𞤗 𞤹 +𞤘 𞤺 +𞤙 𞤻 +𞤚 𞤼 +𞤛 𞤽 +𞤜 𞤾 +𞤠𞤿 +𞤞 𞥀 +𞤟 𞥠+𞤠 𞥂 +𞤡 𞥃 diff --git a/glib/tests/casemap.txt b/glib/tests/casemap.txt new file mode 100644 index 0000000..eccc12b --- /dev/null +++ b/glib/tests/casemap.txt @@ -0,0 +1,4023 @@ +# Test cases generated from Unicode 13.0.0 data +# by gen-casemap-txt.py. Do not edit. +# +# Some special hand crafted tests +# +tr_TR i i İ İ # i => LATIN CAPITAL LETTER I WITH DOT ABOVE +tr_TR I ı I I # I => LATIN SMALL LETTER DOTLESS I +tr_TR İ i İ İ # I => LATIN SMALL LETTER DOTLESS I +tr_TR.UTF-8 i i İ İ # i => LATIN CAPITAL LETTER I WITH DOT ABOVE +tr_TR.UTF-8 I ı I I # I => LATIN SMALL LETTER DOTLESS I +tr_TR.UTF-8 İ i İ İ # I => LATIN SMALL LETTER DOTLESS I +# Test reordering of YPOGEGRAMMENI across other accents + ᾁ ᾁ ᾉ ἉΙ + ᾁ ᾁ ᾉ ἉΙ +# Handling of final and nonfinal sigma + ΜΆΙΟΣ μάιος Μάιος ΜΆΙΟΣ + ΜΆΙΟΣ μάιος Μάιος ΜΆΙΟΣ + ΣΙΓΜΑ σιγμα Σιγμα ΣΙΓΜΑ +# Lithuanian rule of i followed by letter with dot. Not at all sure +# about the titlecase part here +lt_LT iÄ— iÄ— Ie IE +lt_LT iė iė Ie IE +lt_LT ÃŒ i̇̀ ÃŒ ÃŒ # LATIN CAPITAL LETTER I WITH GRAVE +lt_LT à iÌ‡Ì Ã Ã # LATIN CAPITAL LETTER I WITH ACUTE +lt_LT Ĩ i̇̃ Ĩ Ĩ # LATIN CAPITAL LETTER I WITH TILDE +lt_LT IÌ iÌ‡Ì IÌ IÌ # LATIN CAPITAL LETTER I (with acute accent) +lt_LT IÌ€ i̇̀ IÌ€ IÌ€ # LATIN CAPITAL LETTER I (with grave accent) +lt_LT Ĩ i̇̃ Ĩ Ĩ # LATIN CAPITAL LETTER I (with tilde above) +lt_LT IÌ¨Ì iÌ‡Ì¨Ì IÌ¨Ì IÌ¨Ì # LATIN CAPITAL LETTER I (with ogonek and acute accent) +lt_LT JÌ jÌ‡Ì JÌ JÌ # LATIN CAPITAL LETTER J (with acute accent) +lt_LT Ä®Ì Ä¯Ì‡Ì Ä®Ì Ä®Ì # LATIN CAPITAL LETTER I WITH OGONEK (with acute accent) +lt_LT.UTF-8 iÄ— iÄ— Ie IE +lt_LT.UTF-8 iė iė Ie IE +lt_LT.UTF-8 ÃŒ i̇̀ ÃŒ ÃŒ # LATIN CAPITAL LETTER I WITH GRAVE +lt_LT.UTF-8 à iÌ‡Ì Ã Ã # LATIN CAPITAL LETTER I WITH ACUTE +lt_LT.UTF-8 Ĩ i̇̃ Ĩ Ĩ # LATIN CAPITAL LETTER I WITH TILDE +lt_LT.UTF-8 IÌ iÌ‡Ì IÌ IÌ # LATIN CAPITAL LETTER I (with acute accent) +lt_LT.UTF-8 IÌ€ i̇̀ IÌ€ IÌ€ # LATIN CAPITAL LETTER I (with grave accent) +lt_LT.UTF-8 Ĩ i̇̃ Ĩ Ĩ # LATIN CAPITAL LETTER I (with tilde above) +lt_LT.UTF-8 IÌ¨Ì iÌ‡Ì¨Ì IÌ¨Ì IÌ¨Ì # LATIN CAPITAL LETTER I (with ogonek and acute accent) +lt_LT.UTF-8 JÌ jÌ‡Ì JÌ JÌ # LATIN CAPITAL LETTER J (with acute accent) +lt_LT.UTF-8 Ä®Ì Ä¯Ì‡Ì Ä®Ì Ä®Ì # LATIN CAPITAL LETTER I WITH OGONEK (with acute accent) +# Special case not at initial position + affl affl Affl AFFL # FB04 +# +# Now the automatic tests +# + A a A # 41 + B b B # 42 + C c C # 43 + D d D # 44 + E e E # 45 + F f F # 46 + G g G # 47 + H h H # 48 + I i I # 49 + J j J # 4A + K k K # 4B + L l L # 4C + M m M # 4D + N n N # 4E + O o O # 4F + P p P # 50 + Q q Q # 51 + R r R # 52 + S s S # 53 + T t T # 54 + U u U # 55 + V v V # 56 + W w W # 57 + X x X # 58 + Y y Y # 59 + Z z Z # 5A + a a A A # 61 + b b B B # 62 + c c C C # 63 + d d D D # 64 + e e E E # 65 + f f F F # 66 + g g G G # 67 + h h H H # 68 + i i I I # 69 + j j J J # 6A + k k K K # 6B + l l L L # 6C + m m M M # 6D + n n N N # 6E + o o O O # 6F + p p P P # 70 + q q Q Q # 71 + r r R R # 72 + s s S S # 73 + t t T T # 74 + u u U U # 75 + v v V V # 76 + w w W W # 77 + x x X X # 78 + y y Y Y # 79 + z z Z Z # 7A + µ µ Μ Μ # B5 + À à À # C0 + à á à # C1 +  â  # C2 + à ã à # C3 + Ä ä Ä # C4 + Ã… Ã¥ Ã… # C5 + Æ æ Æ # C6 + Ç ç Ç # C7 + È è È # C8 + É é É # C9 + Ê ê Ê # CA + Ë ë Ë # CB + ÃŒ ì ÃŒ # CC + à í à # CD + ÃŽ î ÃŽ # CE + à ï à # CF + à ð à # D0 + Ñ ñ Ñ # D1 + Ã’ ò Ã’ # D2 + Ó ó Ó # D3 + Ô ô Ô # D4 + Õ õ Õ # D5 + Ö ö Ö # D6 + Ø ø Ø # D8 + Ù ù Ù # D9 + Ú ú Ú # DA + Û û Û # DB + Ü ü Ü # DC + à ý à # DD + Þ þ Þ # DE + ß ß Ss SS # DF + à à À À # E0 + á á à à # E1 + â â   # E2 + ã ã à à # E3 + ä ä Ä Ä # E4 + Ã¥ Ã¥ Ã… Ã… # E5 + æ æ Æ Æ # E6 + ç ç Ç Ç # E7 + è è È È # E8 + é é É É # E9 + ê ê Ê Ê # EA + ë ë Ë Ë # EB + ì ì ÃŒ ÃŒ # EC + í í à à # ED + î î ÃŽ ÃŽ # EE + ï ï à à # EF + ð ð à à # F0 + ñ ñ Ñ Ñ # F1 + ò ò Ã’ Ã’ # F2 + ó ó Ó Ó # F3 + ô ô Ô Ô # F4 + õ õ Õ Õ # F5 + ö ö Ö Ö # F6 + ø ø Ø Ø # F8 + ù ù Ù Ù # F9 + ú ú Ú Ú # FA + û û Û Û # FB + ü ü Ü Ü # FC + ý ý à à # FD + þ þ Þ Þ # FE + ÿ ÿ Ÿ Ÿ # FF + Ä€ Ä Ä€ # 100 + Ä Ä Ä€ Ä€ # 101 + Ä‚ ă Ä‚ # 102 + ă ă Ä‚ Ä‚ # 103 + Ä„ Ä… Ä„ # 104 + Ä… Ä… Ä„ Ä„ # 105 + Ć ć Ć # 106 + ć ć Ć Ć # 107 + Ĉ ĉ Ĉ # 108 + ĉ ĉ Ĉ Ĉ # 109 + ÄŠ Ä‹ ÄŠ # 10A + Ä‹ Ä‹ ÄŠ ÄŠ # 10B + ÄŒ Ä ÄŒ # 10C + Ä Ä ÄŒ ÄŒ # 10D + ÄŽ Ä ÄŽ # 10E + Ä Ä ÄŽ ÄŽ # 10F + Ä Ä‘ Ä # 110 + Ä‘ Ä‘ Ä Ä # 111 + Ä’ Ä“ Ä’ # 112 + Ä“ Ä“ Ä’ Ä’ # 113 + Ä” Ä• Ä” # 114 + Ä• Ä• Ä” Ä” # 115 + Ä– Ä— Ä– # 116 + Ä— Ä— Ä– Ä– # 117 + Ę Ä™ Ę # 118 + Ä™ Ä™ Ę Ę # 119 + Äš Ä› Äš # 11A + Ä› Ä› Äš Äš # 11B + Äœ Ä Äœ # 11C + Ä Ä Äœ Äœ # 11D + Äž ÄŸ Äž # 11E + ÄŸ ÄŸ Äž Äž # 11F + Ä  Ä¡ Ä  # 120 + Ä¡ Ä¡ Ä  Ä  # 121 + Ä¢ Ä£ Ä¢ # 122 + Ä£ Ä£ Ä¢ Ä¢ # 123 + Ĥ Ä¥ Ĥ # 124 + Ä¥ Ä¥ Ĥ Ĥ # 125 + Ħ ħ Ħ # 126 + ħ ħ Ħ Ħ # 127 + Ĩ Ä© Ĩ # 128 + Ä© Ä© Ĩ Ĩ # 129 + Ī Ä« Ī # 12A + Ä« Ä« Ī Ī # 12B + Ĭ Ä­ Ĭ # 12C + Ä­ Ä­ Ĭ Ĭ # 12D + Ä® į Ä® # 12E + į į Ä® Ä® # 12F + İ i̇ İ İ # 130 + ı ı I I # 131 + IJ ij IJ # 132 + ij ij IJ IJ # 133 + Ä´ ĵ Ä´ # 134 + ĵ ĵ Ä´ Ä´ # 135 + Ķ Ä· Ķ # 136 + Ä· Ä· Ķ Ķ # 137 + ĸ ĸ # 138 + Ĺ ĺ Ĺ # 139 + ĺ ĺ Ĺ Ĺ # 13A + Ä» ļ Ä» # 13B + ļ ļ Ä» Ä» # 13C + Ľ ľ Ľ # 13D + ľ ľ Ľ Ľ # 13E + Ä¿ Å€ Ä¿ # 13F + Å€ Å€ Ä¿ Ä¿ # 140 + Å Å‚ Å # 141 + Å‚ Å‚ Å Å # 142 + Ń Å„ Ń # 143 + Å„ Å„ Ń Ń # 144 + Å… ņ Å… # 145 + ņ ņ Å… Å… # 146 + Ň ň Ň # 147 + ň ň Ň Ň # 148 + ʼn ʼn ʼN ʼN # 149 + ÅŠ Å‹ ÅŠ # 14A + Å‹ Å‹ ÅŠ ÅŠ # 14B + ÅŒ Å ÅŒ # 14C + Å Å ÅŒ ÅŒ # 14D + ÅŽ Å ÅŽ # 14E + Å Å ÅŽ ÅŽ # 14F + Å Å‘ Å # 150 + Å‘ Å‘ Å Å # 151 + Å’ Å“ Å’ # 152 + Å“ Å“ Å’ Å’ # 153 + Å” Å• Å” # 154 + Å• Å• Å” Å” # 155 + Å– Å— Å– # 156 + Å— Å— Å– Å– # 157 + Ř Å™ Ř # 158 + Å™ Å™ Ř Ř # 159 + Åš Å› Åš # 15A + Å› Å› Åš Åš # 15B + Åœ Å Åœ # 15C + Å Å Åœ Åœ # 15D + Åž ÅŸ Åž # 15E + ÅŸ ÅŸ Åž Åž # 15F + Å  Å¡ Å  # 160 + Å¡ Å¡ Å  Å  # 161 + Å¢ Å£ Å¢ # 162 + Å£ Å£ Å¢ Å¢ # 163 + Ť Å¥ Ť # 164 + Å¥ Å¥ Ť Ť # 165 + Ŧ ŧ Ŧ # 166 + ŧ ŧ Ŧ Ŧ # 167 + Ũ Å© Ũ # 168 + Å© Å© Ũ Ũ # 169 + Ū Å« Ū # 16A + Å« Å« Ū Ū # 16B + Ŭ Å­ Ŭ # 16C + Å­ Å­ Ŭ Ŭ # 16D + Å® ů Å® # 16E + ů ů Å® Å® # 16F + Ű ű Ű # 170 + ű ű Ű Ű # 171 + Ų ų Ų # 172 + ų ų Ų Ų # 173 + Å´ ŵ Å´ # 174 + ŵ ŵ Å´ Å´ # 175 + Ŷ Å· Ŷ # 176 + Å· Å· Ŷ Ŷ # 177 + Ÿ ÿ Ÿ # 178 + Ź ź Ź # 179 + ź ź Ź Ź # 17A + Å» ż Å» # 17B + ż ż Å» Å» # 17C + Ž ž Ž # 17D + ž ž Ž Ž # 17E + Å¿ Å¿ S S # 17F + Æ€ Æ€ Ƀ Ƀ # 180 + Æ É“ Æ # 181 + Æ‚ ƃ Æ‚ # 182 + ƃ ƃ Æ‚ Æ‚ # 183 + Æ„ Æ… Æ„ # 184 + Æ… Æ… Æ„ Æ„ # 185 + Ɔ É” Ɔ # 186 + Ƈ ƈ Ƈ # 187 + ƈ ƈ Ƈ Ƈ # 188 + Ɖ É– Ɖ # 189 + ÆŠ É— ÆŠ # 18A + Æ‹ ÆŒ Æ‹ # 18B + ÆŒ ÆŒ Æ‹ Æ‹ # 18C + Æ Æ # 18D + ÆŽ Ç ÆŽ # 18E + Æ É™ Æ # 18F + Æ É› Æ # 190 + Æ‘ Æ’ Æ‘ # 191 + Æ’ Æ’ Æ‘ Æ‘ # 192 + Æ“ É  Æ“ # 193 + Æ” É£ Æ” # 194 + Æ• Æ• Ƕ Ƕ # 195 + Æ– É© Æ– # 196 + Æ— ɨ Æ— # 197 + Ƙ Æ™ Ƙ # 198 + Æ™ Æ™ Ƙ Ƙ # 199 + Æš Æš Ƚ Ƚ # 19A + Æ› Æ› # 19B + Æœ ɯ Æœ # 19C + Æ É² Æ # 19D + Æž Æž È  È  # 19E + ÆŸ ɵ ÆŸ # 19F + Æ  Æ¡ Æ  # 1A0 + Æ¡ Æ¡ Æ  Æ  # 1A1 + Æ¢ Æ£ Æ¢ # 1A2 + Æ£ Æ£ Æ¢ Æ¢ # 1A3 + Ƥ Æ¥ Ƥ # 1A4 + Æ¥ Æ¥ Ƥ Ƥ # 1A5 + Ʀ Ê€ Ʀ # 1A6 + Ƨ ƨ Ƨ # 1A7 + ƨ ƨ Ƨ Ƨ # 1A8 + Æ© ʃ Æ© # 1A9 + ƪ ƪ # 1AA + Æ« Æ« # 1AB + Ƭ Æ­ Ƭ # 1AC + Æ­ Æ­ Ƭ Ƭ # 1AD + Æ® ʈ Æ® # 1AE + Ư ư Ư # 1AF + ư ư Ư Ư # 1B0 + Ʊ ÊŠ Ʊ # 1B1 + Ʋ Ê‹ Ʋ # 1B2 + Ƴ Æ´ Ƴ # 1B3 + Æ´ Æ´ Ƴ Ƴ # 1B4 + Ƶ ƶ Ƶ # 1B5 + ƶ ƶ Ƶ Ƶ # 1B6 + Æ· Ê’ Æ· # 1B7 + Ƹ ƹ Ƹ # 1B8 + ƹ ƹ Ƹ Ƹ # 1B9 + ƺ ƺ # 1BA + Ƽ ƽ Ƽ # 1BC + ƽ ƽ Ƽ Ƽ # 1BD + ƾ ƾ # 1BE + Æ¿ Æ¿ Ç· Ç· # 1BF + Ç„ dž Ç… Ç„ # 1C4 + Ç… dž dž Ç„ # 1C5 + dž dž Ç… Ç„ # 1C6 + LJ lj Lj LJ # 1C7 + Lj lj lj LJ # 1C8 + lj lj Lj LJ # 1C9 + ÇŠ ÇŒ Ç‹ ÇŠ # 1CA + Ç‹ ÇŒ ÇŒ ÇŠ # 1CB + ÇŒ ÇŒ Ç‹ ÇŠ # 1CC + Ç ÇŽ Ç # 1CD + ÇŽ ÇŽ Ç Ç # 1CE + Ç Ç Ç # 1CF + Ç Ç Ç Ç # 1D0 + Ç‘ Ç’ Ç‘ # 1D1 + Ç’ Ç’ Ç‘ Ç‘ # 1D2 + Ç“ Ç” Ç“ # 1D3 + Ç” Ç” Ç“ Ç“ # 1D4 + Ç• Ç– Ç• # 1D5 + Ç– Ç– Ç• Ç• # 1D6 + Ç— ǘ Ç— # 1D7 + ǘ ǘ Ç— Ç— # 1D8 + Ç™ Çš Ç™ # 1D9 + Çš Çš Ç™ Ç™ # 1DA + Ç› Çœ Ç› # 1DB + Çœ Çœ Ç› Ç› # 1DC + Ç Ç ÆŽ ÆŽ # 1DD + Çž ÇŸ Çž # 1DE + ÇŸ ÇŸ Çž Çž # 1DF + Ç  Ç¡ Ç  # 1E0 + Ç¡ Ç¡ Ç  Ç  # 1E1 + Ç¢ Ç£ Ç¢ # 1E2 + Ç£ Ç£ Ç¢ Ç¢ # 1E3 + Ǥ Ç¥ Ǥ # 1E4 + Ç¥ Ç¥ Ǥ Ǥ # 1E5 + Ǧ ǧ Ǧ # 1E6 + ǧ ǧ Ǧ Ǧ # 1E7 + Ǩ Ç© Ǩ # 1E8 + Ç© Ç© Ǩ Ǩ # 1E9 + Ǫ Ç« Ǫ # 1EA + Ç« Ç« Ǫ Ǫ # 1EB + Ǭ Ç­ Ǭ # 1EC + Ç­ Ç­ Ǭ Ǭ # 1ED + Ç® ǯ Ç® # 1EE + ǯ ǯ Ç® Ç® # 1EF + ǰ ǰ JÌŒ JÌŒ # 1F0 + DZ dz Dz DZ # 1F1 + Dz dz dz DZ # 1F2 + dz dz Dz DZ # 1F3 + Ç´ ǵ Ç´ # 1F4 + ǵ ǵ Ç´ Ç´ # 1F5 + Ƕ Æ• Ƕ # 1F6 + Ç· Æ¿ Ç· # 1F7 + Ǹ ǹ Ǹ # 1F8 + ǹ ǹ Ǹ Ǹ # 1F9 + Ǻ Ç» Ǻ # 1FA + Ç» Ç» Ǻ Ǻ # 1FB + Ǽ ǽ Ǽ # 1FC + ǽ ǽ Ǽ Ǽ # 1FD + Ǿ Ç¿ Ǿ # 1FE + Ç¿ Ç¿ Ǿ Ǿ # 1FF + È€ È È€ # 200 + È È È€ È€ # 201 + È‚ ȃ È‚ # 202 + ȃ ȃ È‚ È‚ # 203 + È„ È… È„ # 204 + È… È… È„ È„ # 205 + Ȇ ȇ Ȇ # 206 + ȇ ȇ Ȇ Ȇ # 207 + Ȉ ȉ Ȉ # 208 + ȉ ȉ Ȉ Ȉ # 209 + ÈŠ È‹ ÈŠ # 20A + È‹ È‹ ÈŠ ÈŠ # 20B + ÈŒ È ÈŒ # 20C + È È ÈŒ ÈŒ # 20D + ÈŽ È ÈŽ # 20E + È È ÈŽ ÈŽ # 20F + È È‘ È # 210 + È‘ È‘ È È # 211 + È’ È“ È’ # 212 + È“ È“ È’ È’ # 213 + È” È• È” # 214 + È• È• È” È” # 215 + È– È— È– # 216 + È— È— È– È– # 217 + Ș È™ Ș # 218 + È™ È™ Ș Ș # 219 + Èš È› Èš # 21A + È› È› Èš Èš # 21B + Èœ È Èœ # 21C + È È Èœ Èœ # 21D + Èž ÈŸ Èž # 21E + ÈŸ ÈŸ Èž Èž # 21F + È  Æž È  # 220 + È¡ È¡ # 221 + È¢ È£ È¢ # 222 + È£ È£ È¢ È¢ # 223 + Ȥ È¥ Ȥ # 224 + È¥ È¥ Ȥ Ȥ # 225 + Ȧ ȧ Ȧ # 226 + ȧ ȧ Ȧ Ȧ # 227 + Ȩ È© Ȩ # 228 + È© È© Ȩ Ȩ # 229 + Ȫ È« Ȫ # 22A + È« È« Ȫ Ȫ # 22B + Ȭ È­ Ȭ # 22C + È­ È­ Ȭ Ȭ # 22D + È® ȯ È® # 22E + ȯ ȯ È® È® # 22F + Ȱ ȱ Ȱ # 230 + ȱ ȱ Ȱ Ȱ # 231 + Ȳ ȳ Ȳ # 232 + ȳ ȳ Ȳ Ȳ # 233 + È´ È´ # 234 + ȵ ȵ # 235 + ȶ ȶ # 236 + È· È· # 237 + ȸ ȸ # 238 + ȹ ȹ # 239 + Ⱥ â±¥ Ⱥ # 23A + È» ȼ È» # 23B + ȼ ȼ È» È» # 23C + Ƚ Æš Ƚ # 23D + Ⱦ ⱦ Ⱦ # 23E + È¿ È¿ â±¾ â±¾ # 23F + É€ É€ Ɀ Ɀ # 240 + É É‚ É # 241 + É‚ É‚ É É # 242 + Ƀ Æ€ Ƀ # 243 + É„ ʉ É„ # 244 + É… ÊŒ É… # 245 + Ɇ ɇ Ɇ # 246 + ɇ ɇ Ɇ Ɇ # 247 + Ɉ ɉ Ɉ # 248 + ɉ ɉ Ɉ Ɉ # 249 + ÉŠ É‹ ÉŠ # 24A + É‹ É‹ ÉŠ ÉŠ # 24B + ÉŒ É ÉŒ # 24C + É É ÉŒ ÉŒ # 24D + ÉŽ É ÉŽ # 24E + É É ÉŽ ÉŽ # 24F + É É â±¯ Ɐ # 250 + É‘ É‘ â±­ â±­ # 251 + É’ É’ â±° â±° # 252 + É“ É“ Æ Æ # 253 + É” É” Ɔ Ɔ # 254 + É• É• # 255 + É– É– Ɖ Ɖ # 256 + É— É— ÆŠ ÆŠ # 257 + ɘ ɘ # 258 + É™ É™ Æ Æ # 259 + Éš Éš # 25A + É› É› Æ Æ # 25B + Éœ Éœ êž« êž« # 25C + É É # 25D + Éž Éž # 25E + ÉŸ ÉŸ # 25F + É  É  Æ“ Æ“ # 260 + É¡ É¡ Ɡ Ɡ # 261 + É¢ É¢ # 262 + É£ É£ Æ” Æ” # 263 + ɤ ɤ # 264 + É¥ É¥ êž êž # 265 + ɦ ɦ Ɦ Ɦ # 266 + ɧ ɧ # 267 + ɨ ɨ Æ— Æ— # 268 + É© É© Æ– Æ– # 269 + ɪ ɪ êž® êž® # 26A + É« É« â±¢ â±¢ # 26B + ɬ ɬ êž­ êž­ # 26C + É­ É­ # 26D + É® É® # 26E + ɯ ɯ Æœ Æœ # 26F + ɰ ɰ # 270 + ɱ ɱ â±® â±® # 271 + ɲ ɲ Æ Æ # 272 + ɳ ɳ # 273 + É´ É´ # 274 + ɵ ɵ ÆŸ ÆŸ # 275 + ɶ ɶ # 276 + É· É· # 277 + ɸ ɸ # 278 + ɹ ɹ # 279 + ɺ ɺ # 27A + É» É» # 27B + ɼ ɼ # 27C + ɽ ɽ Ɽ Ɽ # 27D + ɾ ɾ # 27E + É¿ É¿ # 27F + Ê€ Ê€ Ʀ Ʀ # 280 + Ê Ê # 281 + Ê‚ Ê‚ Ʂ Ʂ # 282 + ʃ ʃ Æ© Æ© # 283 + Ê„ Ê„ # 284 + Ê… Ê… # 285 + ʆ ʆ # 286 + ʇ ʇ êž± êž± # 287 + ʈ ʈ Æ® Æ® # 288 + ʉ ʉ É„ É„ # 289 + ÊŠ ÊŠ Ʊ Ʊ # 28A + Ê‹ Ê‹ Ʋ Ʋ # 28B + ÊŒ ÊŒ É… É… # 28C + Ê Ê # 28D + ÊŽ ÊŽ # 28E + Ê Ê # 28F + Ê Ê # 290 + Ê‘ Ê‘ # 291 + Ê’ Ê’ Æ· Æ· # 292 + Ê“ Ê“ # 293 + Ê• Ê• # 295 + Ê– Ê– # 296 + Ê— Ê— # 297 + ʘ ʘ # 298 + Ê™ Ê™ # 299 + Êš Êš # 29A + Ê› Ê› # 29B + Êœ Êœ # 29C + Ê Ê êž² êž² # 29D + Êž Êž êž° êž° # 29E + ÊŸ ÊŸ # 29F + Ê  Ê  # 2A0 + Ê¡ Ê¡ # 2A1 + Ê¢ Ê¢ # 2A2 + Ê£ Ê£ # 2A3 + ʤ ʤ # 2A4 + Ê¥ Ê¥ # 2A5 + ʦ ʦ # 2A6 + ʧ ʧ # 2A7 + ʨ ʨ # 2A8 + Ê© Ê© # 2A9 + ʪ ʪ # 2AA + Ê« Ê« # 2AB + ʬ ʬ # 2AC + Ê­ Ê­ # 2AD + Ê® Ê® # 2AE + ʯ ʯ # 2AF + Ͱ ͱ Ͱ # 370 + ͱ ͱ Ͱ Ͱ # 371 + Ͳ ͳ Ͳ # 372 + ͳ ͳ Ͳ Ͳ # 373 + Ͷ Í· Ͷ # 376 + Í· Í· Ͷ Ͷ # 377 + Í» Í» Ͻ Ͻ # 37B + ͼ ͼ Ͼ Ͼ # 37C + ͽ ͽ Ï¿ Ï¿ # 37D + Í¿ ϳ Í¿ # 37F + Ά ά Ά # 386 + Έ έ Έ # 388 + Ή ή Ή # 389 + Ί ί Ί # 38A + ÎŒ ÏŒ ÎŒ # 38C + ÎŽ Ï ÎŽ # 38E + Î ÏŽ Î # 38F + Î Î Î™ÌˆÌ Î™ÌˆÌ # 390 + Α α Α # 391 + Î’ β Î’ # 392 + Γ γ Γ # 393 + Δ δ Δ # 394 + Ε ε Ε # 395 + Ζ ζ Ζ # 396 + Η η Η # 397 + Θ θ Θ # 398 + Ι ι Ι # 399 + Κ κ Κ # 39A + Λ λ Λ # 39B + Μ μ Μ # 39C + Πν Î # 39D + Ξ ξ Ξ # 39E + Ο ο Ο # 39F + Π Ï€ Π # 3A0 + Ρ Ï Î¡ # 3A1 + Τ Ï„ Τ # 3A4 + Î¥ Ï… Î¥ # 3A5 + Φ φ Φ # 3A6 + Χ χ Χ # 3A7 + Ψ ψ Ψ # 3A8 + Ω ω Ω # 3A9 + Ϊ ÏŠ Ϊ # 3AA + Ϋ Ï‹ Ϋ # 3AB + ά ά Ά Ά # 3AC + έ έ Έ Έ # 3AD + ή ή Ή Ή # 3AE + ί ί Ί Ί # 3AF + ΰ ΰ Î¥ÌˆÌ Î¥ÌˆÌ # 3B0 + α α Α Α # 3B1 + β β Î’ Î’ # 3B2 + γ γ Γ Γ # 3B3 + δ δ Δ Δ # 3B4 + ε ε Ε Ε # 3B5 + ζ ζ Ζ Ζ # 3B6 + η η Η Η # 3B7 + θ θ Θ Θ # 3B8 + ι ι Ι Ι # 3B9 + κ κ Κ Κ # 3BA + λ λ Λ Λ # 3BB + μ μ Μ Μ # 3BC + ν ν Î Î # 3BD + ξ ξ Ξ Ξ # 3BE + ο ο Ο Ο # 3BF + Ï€ Ï€ Π Π # 3C0 + Ï Ï Î¡ Ρ # 3C1 + Ï‚ Ï‚ Σ Σ # 3C2 + σ σ Σ Σ # 3C3 + Ï„ Ï„ Τ Τ # 3C4 + Ï… Ï… Î¥ Î¥ # 3C5 + φ φ Φ Φ # 3C6 + χ χ Χ Χ # 3C7 + ψ ψ Ψ Ψ # 3C8 + ω ω Ω Ω # 3C9 + ÏŠ ÏŠ Ϊ Ϊ # 3CA + Ï‹ Ï‹ Ϋ Ϋ # 3CB + ÏŒ ÏŒ ÎŒ ÎŒ # 3CC + Ï Ï ÎŽ ÎŽ # 3CD + ÏŽ ÏŽ Î Î # 3CE + Ï Ï— Ï # 3CF + Ï Ï Î’ Î’ # 3D0 + Ï‘ Ï‘ Θ Θ # 3D1 + Ï’ Ï’ # 3D2 + Ï“ Ï“ # 3D3 + Ï” Ï” # 3D4 + Ï• Ï• Φ Φ # 3D5 + Ï– Ï– Π Π # 3D6 + Ï— Ï— Ï Ï # 3D7 + Ϙ Ï™ Ϙ # 3D8 + Ï™ Ï™ Ϙ Ϙ # 3D9 + Ïš Ï› Ïš # 3DA + Ï› Ï› Ïš Ïš # 3DB + Ïœ Ï Ïœ # 3DC + Ï Ï Ïœ Ïœ # 3DD + Ïž ÏŸ Ïž # 3DE + ÏŸ ÏŸ Ïž Ïž # 3DF + Ï  Ï¡ Ï  # 3E0 + Ï¡ Ï¡ Ï  Ï  # 3E1 + Ï¢ Ï£ Ï¢ # 3E2 + Ï£ Ï£ Ï¢ Ï¢ # 3E3 + Ϥ Ï¥ Ϥ # 3E4 + Ï¥ Ï¥ Ϥ Ϥ # 3E5 + Ϧ ϧ Ϧ # 3E6 + ϧ ϧ Ϧ Ϧ # 3E7 + Ϩ Ï© Ϩ # 3E8 + Ï© Ï© Ϩ Ϩ # 3E9 + Ϫ Ï« Ϫ # 3EA + Ï« Ï« Ϫ Ϫ # 3EB + Ϭ Ï­ Ϭ # 3EC + Ï­ Ï­ Ϭ Ϭ # 3ED + Ï® ϯ Ï® # 3EE + ϯ ϯ Ï® Ï® # 3EF + ϰ ϰ Κ Κ # 3F0 + ϱ ϱ Ρ Ρ # 3F1 + ϲ ϲ Ϲ Ϲ # 3F2 + ϳ ϳ Í¿ Í¿ # 3F3 + Ï´ θ Ï´ # 3F4 + ϵ ϵ Ε Ε # 3F5 + Ï· ϸ Ï· # 3F7 + ϸ ϸ Ï· Ï· # 3F8 + Ϲ ϲ Ϲ # 3F9 + Ϻ Ï» Ϻ # 3FA + Ï» Ï» Ϻ Ϻ # 3FB + ϼ ϼ # 3FC + Ͻ Í» Ͻ # 3FD + Ͼ ͼ Ͼ # 3FE + Ï¿ ͽ Ï¿ # 3FF + Ѐ Ñ Ð€ # 400 + Ð Ñ‘ Ð # 401 + Ђ Ñ’ Ђ # 402 + Ѓ Ñ“ Ѓ # 403 + Є Ñ” Є # 404 + Ð… Ñ• Ð… # 405 + І Ñ– І # 406 + Ї Ñ— Ї # 407 + Ј ј Ј # 408 + Љ Ñ™ Љ # 409 + Њ Ñš Њ # 40A + Ћ Ñ› Ћ # 40B + ÐŒ Ñœ ÐŒ # 40C + Ð Ñ Ð # 40D + ÐŽ Ñž ÐŽ # 40E + Ð ÑŸ Ð # 40F + Ра Ð # 410 + Б б Б # 411 + Ð’ в Ð’ # 412 + Г г Г # 413 + Д д Д # 414 + Е е Е # 415 + Ж ж Ж # 416 + З з З # 417 + И и И # 418 + Й й Й # 419 + К к К # 41A + Л л Л # 41B + М м М # 41C + Рн Ð # 41D + О о О # 41E + П п П # 41F + Р Ñ€ Р # 420 + С Ñ Ð¡ # 421 + Т Ñ‚ Т # 422 + У у У # 423 + Ф Ñ„ Ф # 424 + Ð¥ Ñ… Ð¥ # 425 + Ц ц Ц # 426 + Ч ч Ч # 427 + Ш ш Ш # 428 + Щ щ Щ # 429 + Ъ ÑŠ Ъ # 42A + Ы Ñ‹ Ы # 42B + Ь ÑŒ Ь # 42C + Э Ñ Ð­ # 42D + Ю ÑŽ Ю # 42E + Я Ñ Ð¯ # 42F + а а Ð Ð # 430 + б б Б Б # 431 + в в Ð’ Ð’ # 432 + г г Г Г # 433 + д д Д Д # 434 + е е Е Е # 435 + ж ж Ж Ж # 436 + з з З З # 437 + и и И И # 438 + й й Й Й # 439 + к к К К # 43A + л л Л Л # 43B + м м М М # 43C + н н Ð Ð # 43D + о о О О # 43E + п п П П # 43F + Ñ€ Ñ€ Р Р # 440 + Ñ Ñ Ð¡ С # 441 + Ñ‚ Ñ‚ Т Т # 442 + у у У У # 443 + Ñ„ Ñ„ Ф Ф # 444 + Ñ… Ñ… Ð¥ Ð¥ # 445 + ц ц Ц Ц # 446 + ч ч Ч Ч # 447 + ш ш Ш Ш # 448 + щ щ Щ Щ # 449 + ÑŠ ÑŠ Ъ Ъ # 44A + Ñ‹ Ñ‹ Ы Ы # 44B + ÑŒ ÑŒ Ь Ь # 44C + Ñ Ñ Ð­ Э # 44D + ÑŽ ÑŽ Ю Ю # 44E + Ñ Ñ Ð¯ Я # 44F + Ñ Ñ Ð€ Ѐ # 450 + Ñ‘ Ñ‘ Ð Ð # 451 + Ñ’ Ñ’ Ђ Ђ # 452 + Ñ“ Ñ“ Ѓ Ѓ # 453 + Ñ” Ñ” Є Є # 454 + Ñ• Ñ• Ð… Ð… # 455 + Ñ– Ñ– І І # 456 + Ñ— Ñ— Ї Ї # 457 + ј ј Ј Ј # 458 + Ñ™ Ñ™ Љ Љ # 459 + Ñš Ñš Њ Њ # 45A + Ñ› Ñ› Ћ Ћ # 45B + Ñœ Ñœ ÐŒ ÐŒ # 45C + Ñ Ñ Ð Ð # 45D + Ñž Ñž ÐŽ ÐŽ # 45E + ÑŸ ÑŸ Ð Ð # 45F + Ñ  Ñ¡ Ñ  # 460 + Ñ¡ Ñ¡ Ñ  Ñ  # 461 + Ñ¢ Ñ£ Ñ¢ # 462 + Ñ£ Ñ£ Ñ¢ Ñ¢ # 463 + Ѥ Ñ¥ Ѥ # 464 + Ñ¥ Ñ¥ Ѥ Ѥ # 465 + Ѧ ѧ Ѧ # 466 + ѧ ѧ Ѧ Ѧ # 467 + Ѩ Ñ© Ѩ # 468 + Ñ© Ñ© Ѩ Ѩ # 469 + Ѫ Ñ« Ѫ # 46A + Ñ« Ñ« Ѫ Ѫ # 46B + Ѭ Ñ­ Ѭ # 46C + Ñ­ Ñ­ Ѭ Ѭ # 46D + Ñ® ѯ Ñ® # 46E + ѯ ѯ Ñ® Ñ® # 46F + Ѱ ѱ Ѱ # 470 + ѱ ѱ Ѱ Ѱ # 471 + Ѳ ѳ Ѳ # 472 + ѳ ѳ Ѳ Ѳ # 473 + Ñ´ ѵ Ñ´ # 474 + ѵ ѵ Ñ´ Ñ´ # 475 + Ѷ Ñ· Ѷ # 476 + Ñ· Ñ· Ѷ Ѷ # 477 + Ѹ ѹ Ѹ # 478 + ѹ ѹ Ѹ Ѹ # 479 + Ѻ Ñ» Ѻ # 47A + Ñ» Ñ» Ѻ Ѻ # 47B + Ѽ ѽ Ѽ # 47C + ѽ ѽ Ѽ Ѽ # 47D + Ѿ Ñ¿ Ѿ # 47E + Ñ¿ Ñ¿ Ѿ Ѿ # 47F + Ò€ Ò Ò€ # 480 + Ò Ò Ò€ Ò€ # 481 + ÒŠ Ò‹ ÒŠ # 48A + Ò‹ Ò‹ ÒŠ ÒŠ # 48B + ÒŒ Ò ÒŒ # 48C + Ò Ò ÒŒ ÒŒ # 48D + ÒŽ Ò ÒŽ # 48E + Ò Ò ÒŽ ÒŽ # 48F + Ò Ò‘ Ò # 490 + Ò‘ Ò‘ Ò Ò # 491 + Ò’ Ò“ Ò’ # 492 + Ò“ Ò“ Ò’ Ò’ # 493 + Ò” Ò• Ò” # 494 + Ò• Ò• Ò” Ò” # 495 + Ò– Ò— Ò– # 496 + Ò— Ò— Ò– Ò– # 497 + Ò˜ Ò™ Ò˜ # 498 + Ò™ Ò™ Ò˜ Ò˜ # 499 + Òš Ò› Òš # 49A + Ò› Ò› Òš Òš # 49B + Òœ Ò Òœ # 49C + Ò Ò Òœ Òœ # 49D + Òž ÒŸ Òž # 49E + ÒŸ ÒŸ Òž Òž # 49F + Ò  Ò¡ Ò  # 4A0 + Ò¡ Ò¡ Ò  Ò  # 4A1 + Ò¢ Ò£ Ò¢ # 4A2 + Ò£ Ò£ Ò¢ Ò¢ # 4A3 + Ò¤ Ò¥ Ò¤ # 4A4 + Ò¥ Ò¥ Ò¤ Ò¤ # 4A5 + Ò¦ Ò§ Ò¦ # 4A6 + Ò§ Ò§ Ò¦ Ò¦ # 4A7 + Ò¨ Ò© Ò¨ # 4A8 + Ò© Ò© Ò¨ Ò¨ # 4A9 + Òª Ò« Òª # 4AA + Ò« Ò« Òª Òª # 4AB + Ò¬ Ò­ Ò¬ # 4AC + Ò­ Ò­ Ò¬ Ò¬ # 4AD + Ò® Ò¯ Ò® # 4AE + Ò¯ Ò¯ Ò® Ò® # 4AF + Ò° Ò± Ò° # 4B0 + Ò± Ò± Ò° Ò° # 4B1 + Ò² Ò³ Ò² # 4B2 + Ò³ Ò³ Ò² Ò² # 4B3 + Ò´ Òµ Ò´ # 4B4 + Òµ Òµ Ò´ Ò´ # 4B5 + Ò¶ Ò· Ò¶ # 4B6 + Ò· Ò· Ò¶ Ò¶ # 4B7 + Ò¸ Ò¹ Ò¸ # 4B8 + Ò¹ Ò¹ Ò¸ Ò¸ # 4B9 + Òº Ò» Òº # 4BA + Ò» Ò» Òº Òº # 4BB + Ò¼ Ò½ Ò¼ # 4BC + Ò½ Ò½ Ò¼ Ò¼ # 4BD + Ò¾ Ò¿ Ò¾ # 4BE + Ò¿ Ò¿ Ò¾ Ò¾ # 4BF + Ó€ Ó Ó€ # 4C0 + Ó Ó‚ Ó # 4C1 + Ó‚ Ó‚ Ó Ó # 4C2 + Óƒ Ó„ Óƒ # 4C3 + Ó„ Ó„ Óƒ Óƒ # 4C4 + Ó… Ó† Ó… # 4C5 + Ó† Ó† Ó… Ó… # 4C6 + Ó‡ Óˆ Ó‡ # 4C7 + Óˆ Óˆ Ó‡ Ó‡ # 4C8 + Ó‰ ÓŠ Ó‰ # 4C9 + ÓŠ ÓŠ Ó‰ Ó‰ # 4CA + Ó‹ ÓŒ Ó‹ # 4CB + ÓŒ ÓŒ Ó‹ Ó‹ # 4CC + Ó ÓŽ Ó # 4CD + ÓŽ ÓŽ Ó Ó # 4CE + Ó Ó Ó€ Ó€ # 4CF + Ó Ó‘ Ó # 4D0 + Ó‘ Ó‘ Ó Ó # 4D1 + Ó’ Ó“ Ó’ # 4D2 + Ó“ Ó“ Ó’ Ó’ # 4D3 + Ó” Ó• Ó” # 4D4 + Ó• Ó• Ó” Ó” # 4D5 + Ó– Ó— Ó– # 4D6 + Ó— Ó— Ó– Ó– # 4D7 + Ó˜ Ó™ Ó˜ # 4D8 + Ó™ Ó™ Ó˜ Ó˜ # 4D9 + Óš Ó› Óš # 4DA + Ó› Ó› Óš Óš # 4DB + Óœ Ó Óœ # 4DC + Ó Ó Óœ Óœ # 4DD + Óž ÓŸ Óž # 4DE + ÓŸ ÓŸ Óž Óž # 4DF + Ó  Ó¡ Ó  # 4E0 + Ó¡ Ó¡ Ó  Ó  # 4E1 + Ó¢ Ó£ Ó¢ # 4E2 + Ó£ Ó£ Ó¢ Ó¢ # 4E3 + Ó¤ Ó¥ Ó¤ # 4E4 + Ó¥ Ó¥ Ó¤ Ó¤ # 4E5 + Ó¦ Ó§ Ó¦ # 4E6 + Ó§ Ó§ Ó¦ Ó¦ # 4E7 + Ó¨ Ó© Ó¨ # 4E8 + Ó© Ó© Ó¨ Ó¨ # 4E9 + Óª Ó« Óª # 4EA + Ó« Ó« Óª Óª # 4EB + Ó¬ Ó­ Ó¬ # 4EC + Ó­ Ó­ Ó¬ Ó¬ # 4ED + Ó® Ó¯ Ó® # 4EE + Ó¯ Ó¯ Ó® Ó® # 4EF + Ó° Ó± Ó° # 4F0 + Ó± Ó± Ó° Ó° # 4F1 + Ó² Ó³ Ó² # 4F2 + Ó³ Ó³ Ó² Ó² # 4F3 + Ó´ Óµ Ó´ # 4F4 + Óµ Óµ Ó´ Ó´ # 4F5 + Ó¶ Ó· Ó¶ # 4F6 + Ó· Ó· Ó¶ Ó¶ # 4F7 + Ó¸ Ó¹ Ó¸ # 4F8 + Ó¹ Ó¹ Ó¸ Ó¸ # 4F9 + Óº Ó» Óº # 4FA + Ó» Ó» Óº Óº # 4FB + Ó¼ Ó½ Ó¼ # 4FC + Ó½ Ó½ Ó¼ Ó¼ # 4FD + Ó¾ Ó¿ Ó¾ # 4FE + Ó¿ Ó¿ Ó¾ Ó¾ # 4FF + Ô€ Ô Ô€ # 500 + Ô Ô Ô€ Ô€ # 501 + Ô‚ Ôƒ Ô‚ # 502 + Ôƒ Ôƒ Ô‚ Ô‚ # 503 + Ô„ Ô… Ô„ # 504 + Ô… Ô… Ô„ Ô„ # 505 + Ô† Ô‡ Ô† # 506 + Ô‡ Ô‡ Ô† Ô† # 507 + Ôˆ Ô‰ Ôˆ # 508 + Ô‰ Ô‰ Ôˆ Ôˆ # 509 + ÔŠ Ô‹ ÔŠ # 50A + Ô‹ Ô‹ ÔŠ ÔŠ # 50B + ÔŒ Ô ÔŒ # 50C + Ô Ô ÔŒ ÔŒ # 50D + ÔŽ Ô ÔŽ # 50E + Ô Ô ÔŽ ÔŽ # 50F + Ô Ô‘ Ô # 510 + Ô‘ Ô‘ Ô Ô # 511 + Ô’ Ô“ Ô’ # 512 + Ô“ Ô“ Ô’ Ô’ # 513 + Ô” Ô• Ô” # 514 + Ô• Ô• Ô” Ô” # 515 + Ô– Ô— Ô– # 516 + Ô— Ô— Ô– Ô– # 517 + Ô˜ Ô™ Ô˜ # 518 + Ô™ Ô™ Ô˜ Ô˜ # 519 + Ôš Ô› Ôš # 51A + Ô› Ô› Ôš Ôš # 51B + Ôœ Ô Ôœ # 51C + Ô Ô Ôœ Ôœ # 51D + Ôž ÔŸ Ôž # 51E + ÔŸ ÔŸ Ôž Ôž # 51F + Ô  Ô¡ Ô  # 520 + Ô¡ Ô¡ Ô  Ô  # 521 + Ô¢ Ô£ Ô¢ # 522 + Ô£ Ô£ Ô¢ Ô¢ # 523 + Ô¤ Ô¥ Ô¤ # 524 + Ô¥ Ô¥ Ô¤ Ô¤ # 525 + Ô¦ Ô§ Ô¦ # 526 + Ô§ Ô§ Ô¦ Ô¦ # 527 + Ô¨ Ô© Ô¨ # 528 + Ô© Ô© Ô¨ Ô¨ # 529 + Ôª Ô« Ôª # 52A + Ô« Ô« Ôª Ôª # 52B + Ô¬ Ô­ Ô¬ # 52C + Ô­ Ô­ Ô¬ Ô¬ # 52D + Ô® Ô¯ Ô® # 52E + Ô¯ Ô¯ Ô® Ô® # 52F + Ô± Õ¡ Ô± # 531 + Ô² Õ¢ Ô² # 532 + Ô³ Õ£ Ô³ # 533 + Ô´ Õ¤ Ô´ # 534 + Ôµ Õ¥ Ôµ # 535 + Ô¶ Õ¦ Ô¶ # 536 + Ô· Õ§ Ô· # 537 + Ô¸ Õ¨ Ô¸ # 538 + Ô¹ Õ© Ô¹ # 539 + Ôº Õª Ôº # 53A + Ô» Õ« Ô» # 53B + Ô¼ Õ¬ Ô¼ # 53C + Ô½ Õ­ Ô½ # 53D + Ô¾ Õ® Ô¾ # 53E + Ô¿ Õ¯ Ô¿ # 53F + Õ€ Õ° Õ€ # 540 + Õ Õ± Õ # 541 + Õ‚ Õ² Õ‚ # 542 + Õƒ Õ³ Õƒ # 543 + Õ„ Õ´ Õ„ # 544 + Õ… Õµ Õ… # 545 + Õ† Õ¶ Õ† # 546 + Õ‡ Õ· Õ‡ # 547 + Õˆ Õ¸ Õˆ # 548 + Õ‰ Õ¹ Õ‰ # 549 + ÕŠ Õº ÕŠ # 54A + Õ‹ Õ» Õ‹ # 54B + ÕŒ Õ¼ ÕŒ # 54C + Õ Õ½ Õ # 54D + ÕŽ Õ¾ ÕŽ # 54E + Õ Õ¿ Õ # 54F + Õ Ö€ Õ # 550 + Õ‘ Ö Õ‘ # 551 + Õ’ Ö‚ Õ’ # 552 + Õ“ Öƒ Õ“ # 553 + Õ” Ö„ Õ” # 554 + Õ• Ö… Õ• # 555 + Õ– Ö† Õ– # 556 + Õ  Õ  # 560 + Õ¡ Õ¡ Ô± Ô± # 561 + Õ¢ Õ¢ Ô² Ô² # 562 + Õ£ Õ£ Ô³ Ô³ # 563 + Õ¤ Õ¤ Ô´ Ô´ # 564 + Õ¥ Õ¥ Ôµ Ôµ # 565 + Õ¦ Õ¦ Ô¶ Ô¶ # 566 + Õ§ Õ§ Ô· Ô· # 567 + Õ¨ Õ¨ Ô¸ Ô¸ # 568 + Õ© Õ© Ô¹ Ô¹ # 569 + Õª Õª Ôº Ôº # 56A + Õ« Õ« Ô» Ô» # 56B + Õ¬ Õ¬ Ô¼ Ô¼ # 56C + Õ­ Õ­ Ô½ Ô½ # 56D + Õ® Õ® Ô¾ Ô¾ # 56E + Õ¯ Õ¯ Ô¿ Ô¿ # 56F + Õ° Õ° Õ€ Õ€ # 570 + Õ± Õ± Õ Õ # 571 + Õ² Õ² Õ‚ Õ‚ # 572 + Õ³ Õ³ Õƒ Õƒ # 573 + Õ´ Õ´ Õ„ Õ„ # 574 + Õµ Õµ Õ… Õ… # 575 + Õ¶ Õ¶ Õ† Õ† # 576 + Õ· Õ· Õ‡ Õ‡ # 577 + Õ¸ Õ¸ Õˆ Õˆ # 578 + Õ¹ Õ¹ Õ‰ Õ‰ # 579 + Õº Õº ÕŠ ÕŠ # 57A + Õ» Õ» Õ‹ Õ‹ # 57B + Õ¼ Õ¼ ÕŒ ÕŒ # 57C + Õ½ Õ½ Õ Õ # 57D + Õ¾ Õ¾ ÕŽ ÕŽ # 57E + Õ¿ Õ¿ Õ Õ # 57F + Ö€ Ö€ Õ Õ # 580 + Ö Ö Õ‘ Õ‘ # 581 + Ö‚ Ö‚ Õ’ Õ’ # 582 + Öƒ Öƒ Õ“ Õ“ # 583 + Ö„ Ö„ Õ” Õ” # 584 + Ö… Ö… Õ• Õ• # 585 + Ö† Ö† Õ– Õ– # 586 + Ö‡ Ö‡ ÔµÖ‚ ÔµÕ’ # 587 + Öˆ Öˆ # 588 + á‚  â´€ á‚  # 10A0 + á‚¡ â´ á‚¡ # 10A1 + á‚¢ â´‚ á‚¢ # 10A2 + á‚£ â´ƒ á‚£ # 10A3 + Ⴄ â´„ Ⴄ # 10A4 + á‚¥ â´… á‚¥ # 10A5 + Ⴆ â´† Ⴆ # 10A6 + á‚§ â´‡ á‚§ # 10A7 + Ⴈ â´ˆ Ⴈ # 10A8 + á‚© â´‰ á‚© # 10A9 + Ⴊ â´Š Ⴊ # 10AA + á‚« â´‹ á‚« # 10AB + Ⴌ â´Œ Ⴌ # 10AC + á‚­ â´ á‚­ # 10AD + á‚® â´Ž á‚® # 10AE + Ⴏ ⴠႯ # 10AF + á‚° â´ á‚° # 10B0 + Ⴑ â´‘ Ⴑ # 10B1 + Ⴒ â´’ Ⴒ # 10B2 + Ⴓ â´“ Ⴓ # 10B3 + á‚´ â´” á‚´ # 10B4 + Ⴕ â´• Ⴕ # 10B5 + á‚¶ â´– á‚¶ # 10B6 + á‚· â´— á‚· # 10B7 + Ⴘ â´˜ Ⴘ # 10B8 + Ⴙ â´™ Ⴙ # 10B9 + Ⴚ â´š Ⴚ # 10BA + á‚» â´› á‚» # 10BB + Ⴜ â´œ Ⴜ # 10BC + Ⴝ ⴠႽ # 10BD + Ⴞ â´ž Ⴞ # 10BE + á‚¿ â´Ÿ á‚¿ # 10BF + Ⴠ â´  Ⴠ # 10C0 + რⴡ რ# 10C1 + Ⴢ â´¢ Ⴢ # 10C2 + Ⴣ â´£ Ⴣ # 10C3 + Ⴤ â´¤ Ⴤ # 10C4 + Ⴥ â´¥ Ⴥ # 10C5 + Ⴧ â´§ Ⴧ # 10C7 + რⴭ რ# 10CD + რრრᲠ# 10D0 + ბ ბ ბ Ბ # 10D1 + გ გ გ á²’ # 10D2 + დ დ დ Დ # 10D3 + ე ე ე á²” # 10D4 + ვ ვ ვ Ვ # 10D5 + ზ ზ ზ á²– # 10D6 + თ თ თ á²— # 10D7 + ი ი ი Ი # 10D8 + კ კ კ á²™ # 10D9 + ლ ლ ლ Ლ # 10DA + მ მ მ á²› # 10DB + ნ ნ ნ Ნ # 10DC + რრრᲠ# 10DD + პ პ პ Პ # 10DE + ჟ ჟ ჟ Ჟ # 10DF + რ რ რ á²  # 10E0 + ს ს ს Ს # 10E1 + ტ ტ ტ á²¢ # 10E2 + უ უ უ á²£ # 10E3 + ფ ფ ფ Ფ # 10E4 + ქ ქ ქ á²¥ # 10E5 + ღ ღ ღ Ღ # 10E6 + ყ ყ ყ á²§ # 10E7 + შ შ შ Შ # 10E8 + ჩ ჩ ჩ Ჩ # 10E9 + ც ც ც Ც # 10EA + ძ ძ ძ Ძ # 10EB + წ წ წ Წ # 10EC + ჭ ჭ ჭ á²­ # 10ED + ხ ხ ხ á²® # 10EE + ჯ ჯ ჯ Ჯ # 10EF + ჰ ჰ ჰ á²° # 10F0 + ჱ ჱ ჱ á²± # 10F1 + ჲ ჲ ჲ á²² # 10F2 + ჳ ჳ ჳ á²³ # 10F3 + ჴ ჴ ჴ á²´ # 10F4 + ჵ ჵ ჵ á²µ # 10F5 + ჶ ჶ ჶ á²¶ # 10F6 + ჷ ჷ ჷ á²· # 10F7 + ჸ ჸ ჸ Ჸ # 10F8 + ჹ ჹ ჹ á²¹ # 10F9 + ჺ ჺ ჺ Ჺ # 10FA + ჽ ჽ ჽ á²½ # 10FD + ჾ ჾ ჾ á²¾ # 10FE + ჿ ჿ ჿ Ჿ # 10FF + Ꭰ ê­° Ꭰ # 13A0 + Ꭱ ê­± Ꭱ # 13A1 + Ꭲ ê­² Ꭲ # 13A2 + Ꭳ ê­³ Ꭳ # 13A3 + Ꭴ ê­´ Ꭴ # 13A4 + Ꭵ ê­µ Ꭵ # 13A5 + Ꭶ ê­¶ Ꭶ # 13A6 + Ꭷ ê­· Ꭷ # 13A7 + Ꭸ ê­¸ Ꭸ # 13A8 + Ꭹ ê­¹ Ꭹ # 13A9 + Ꭺ ê­º Ꭺ # 13AA + Ꭻ ê­» Ꭻ # 13AB + Ꭼ ê­¼ Ꭼ # 13AC + Ꭽ ê­½ Ꭽ # 13AD + Ꭾ ê­¾ Ꭾ # 13AE + Ꭿ ê­¿ Ꭿ # 13AF + Ꮀ ꮀ Ꮀ # 13B0 + Ꮁ ê® áŽ± # 13B1 + Ꮂ ꮂ Ꮂ # 13B2 + Ꮃ ꮃ Ꮃ # 13B3 + Ꮄ ꮄ Ꮄ # 13B4 + Ꮅ ê®… Ꮅ # 13B5 + Ꮆ ꮆ Ꮆ # 13B6 + Ꮇ ꮇ Ꮇ # 13B7 + Ꮈ ꮈ Ꮈ # 13B8 + Ꮉ ꮉ Ꮉ # 13B9 + Ꮊ ꮊ Ꮊ # 13BA + Ꮋ ꮋ Ꮋ # 13BB + Ꮌ ꮌ Ꮌ # 13BC + Ꮍ ê® áŽ½ # 13BD + Ꮎ ꮎ Ꮎ # 13BE + Ꮏ ê® áŽ¿ # 13BF + á€ ê® á€ # 13C0 + á ꮑ á # 13C1 + á‚ ê®’ á‚ # 13C2 + რꮓ რ# 13C3 + á„ ê®” á„ # 13C4 + á… ê®• á… # 13C5 + ᆠꮖ ᆠ# 13C6 + ᇠꮗ ᇠ# 13C7 + ሠꮘ ሠ# 13C8 + በꮙ በ# 13C9 + አꮚ አ# 13CA + á‹ ê®› á‹ # 13CB + ጠꮜ ጠ# 13CC + á ê® á # 13CD + Ꭰꮞ Ꭰ# 13CE + á ꮟ á # 13CF + á ê®  á # 13D0 + ᑠꮡ á‘ # 13D1 + ᒠꮢ á’ # 13D2 + ᓠꮣ á“ # 13D3 + ᔠꮤ á” # 13D4 + ᕠꮥ á• # 13D5 + ᖠꮦ á– # 13D6 + á— ê®§ á— # 13D7 + ᘠꮨ ᘠ# 13D8 + ᙠꮩ á™ # 13D9 + ᚠꮪ áš # 13DA + ᛠꮫ á› # 13DB + ᜠꮬ ᜠ# 13DC + á ê®­ á # 13DD + áž ê®® áž # 13DE + ០ꮯ ០# 13DF + á  ê®° á  # 13E0 + á¡ ê®± á¡ # 13E1 + ᢠꮲ ᢠ# 13E2 + ᣠꮳ ᣠ# 13E3 + ᤠꮴ ᤠ# 13E4 + ᥠꮵ ᥠ# 13E5 + ᦠꮶ ᦠ# 13E6 + á§ ê®· á§ # 13E7 + ᨠꮸ ᨠ# 13E8 + ᩠ꮹ á© # 13E9 + ᪠ꮺ ᪠# 13EA + á« ê®» á« # 13EB + ᬠꮼ ᬠ# 13EC + ᭠ꮽ á­ # 13ED + ᮠꮾ á® # 13EE + ᯠꮿ ᯠ# 13EF + ᰠḠᰠ# 13F0 + á± á¹ á± # 13F1 + ᲠẠᲠ# 13F2 + á³ á» á³ # 13F3 + á´ á¼ á´ # 13F4 + áµ á½ áµ # 13F5 + ḠḠᰠᰠ# 13F8 + á¹ á¹ á± á± # 13F9 + ẠẠᲠᲠ# 13FA + á» á» á³ á³ # 13FB + á¼ á¼ á´ á´ # 13FC + á½ á½ áµ áµ # 13FD + á²€ á²€ Ð’ Ð’ # 1C80 + ᲠᲠД Д # 1C81 + ᲂ ᲂ О О # 1C82 + ᲃ ᲃ С С # 1C83 + ᲄ ᲄ Т Т # 1C84 + á²… á²… Т Т # 1C85 + ᲆ ᲆ Ъ Ъ # 1C86 + ᲇ ᲇ Ñ¢ Ñ¢ # 1C87 + ᲈ ᲈ Ꙋ Ꙋ # 1C88 + ᲠრᲠ# 1C90 + Ბ ბ Ბ # 1C91 + á²’ გ á²’ # 1C92 + Დ დ Დ # 1C93 + á²” ე á²” # 1C94 + Ვ ვ Ვ # 1C95 + á²– ზ á²– # 1C96 + á²— თ á²— # 1C97 + Ი ი Ი # 1C98 + á²™ კ á²™ # 1C99 + Ლ ლ Ლ # 1C9A + á²› მ á²› # 1C9B + Ნ ნ Ნ # 1C9C + ᲠრᲠ# 1C9D + Პ პ Პ # 1C9E + Ჟ ჟ Ჟ # 1C9F + á²  რ á²  # 1CA0 + Ს ს Ს # 1CA1 + á²¢ ტ á²¢ # 1CA2 + á²£ უ á²£ # 1CA3 + Ფ ფ Ფ # 1CA4 + á²¥ ქ á²¥ # 1CA5 + Ღ ღ Ღ # 1CA6 + á²§ ყ á²§ # 1CA7 + Შ შ Შ # 1CA8 + Ჩ ჩ Ჩ # 1CA9 + Ც ც Ც # 1CAA + Ძ ძ Ძ # 1CAB + Წ წ Წ # 1CAC + á²­ ჭ á²­ # 1CAD + á²® ხ á²® # 1CAE + Ჯ ჯ Ჯ # 1CAF + á²° ჰ á²° # 1CB0 + á²± ჱ á²± # 1CB1 + á²² ჲ á²² # 1CB2 + á²³ ჳ á²³ # 1CB3 + á²´ ჴ á²´ # 1CB4 + á²µ ჵ á²µ # 1CB5 + á²¶ ჶ á²¶ # 1CB6 + á²· ჷ á²· # 1CB7 + Ჸ ჸ Ჸ # 1CB8 + á²¹ ჹ á²¹ # 1CB9 + Ჺ ჺ Ჺ # 1CBA + á²½ ჽ á²½ # 1CBD + á²¾ ჾ á²¾ # 1CBE + Ჿ ჿ Ჿ # 1CBF + á´€ á´€ # 1D00 + á´ á´ # 1D01 + á´‚ á´‚ # 1D02 + á´ƒ á´ƒ # 1D03 + á´„ á´„ # 1D04 + á´… á´… # 1D05 + á´† á´† # 1D06 + á´‡ á´‡ # 1D07 + á´ˆ á´ˆ # 1D08 + á´‰ á´‰ # 1D09 + á´Š á´Š # 1D0A + á´‹ á´‹ # 1D0B + á´Œ á´Œ # 1D0C + á´ á´ # 1D0D + á´Ž á´Ž # 1D0E + á´ á´ # 1D0F + á´ á´ # 1D10 + á´‘ á´‘ # 1D11 + á´’ á´’ # 1D12 + á´“ á´“ # 1D13 + á´” á´” # 1D14 + á´• á´• # 1D15 + á´– á´– # 1D16 + á´— á´— # 1D17 + á´˜ á´˜ # 1D18 + á´™ á´™ # 1D19 + á´š á´š # 1D1A + á´› á´› # 1D1B + á´œ á´œ # 1D1C + á´ á´ # 1D1D + á´ž á´ž # 1D1E + á´Ÿ á´Ÿ # 1D1F + á´  á´  # 1D20 + á´¡ á´¡ # 1D21 + á´¢ á´¢ # 1D22 + á´£ á´£ # 1D23 + á´¤ á´¤ # 1D24 + á´¥ á´¥ # 1D25 + á´¦ á´¦ # 1D26 + á´§ á´§ # 1D27 + á´¨ á´¨ # 1D28 + á´© á´© # 1D29 + á´ª á´ª # 1D2A + á´« á´« # 1D2B + ᵫ ᵫ # 1D6B + ᵬ ᵬ # 1D6C + áµ­ áµ­ # 1D6D + áµ® áµ® # 1D6E + ᵯ ᵯ # 1D6F + áµ° áµ° # 1D70 + áµ± áµ± # 1D71 + áµ² áµ² # 1D72 + áµ³ áµ³ # 1D73 + áµ´ áµ´ # 1D74 + áµµ áµµ # 1D75 + áµ¶ áµ¶ # 1D76 + áµ· áµ· # 1D77 + áµ¹ áµ¹ ê½ ê½ # 1D79 + ᵺ ᵺ # 1D7A + áµ» áµ» # 1D7B + áµ¼ áµ¼ # 1D7C + áµ½ áµ½ â±£ â±£ # 1D7D + áµ¾ áµ¾ # 1D7E + ᵿ ᵿ # 1D7F + á¶€ á¶€ # 1D80 + á¶ á¶ # 1D81 + á¶‚ á¶‚ # 1D82 + ᶃ ᶃ # 1D83 + á¶„ á¶„ # 1D84 + á¶… á¶… # 1D85 + ᶆ ᶆ # 1D86 + ᶇ ᶇ # 1D87 + ᶈ ᶈ # 1D88 + ᶉ ᶉ # 1D89 + á¶Š á¶Š # 1D8A + á¶‹ á¶‹ # 1D8B + á¶Œ á¶Œ # 1D8C + á¶ á¶ # 1D8D + á¶Ž á¶Ž Ᶎ Ᶎ # 1D8E + á¶ á¶ # 1D8F + á¶ á¶ # 1D90 + á¶‘ á¶‘ # 1D91 + á¶’ á¶’ # 1D92 + á¶“ á¶“ # 1D93 + á¶” á¶” # 1D94 + á¶• á¶• # 1D95 + á¶– á¶– # 1D96 + á¶— á¶— # 1D97 + ᶘ ᶘ # 1D98 + á¶™ á¶™ # 1D99 + á¶š á¶š # 1D9A + Ḁ ḠḀ # 1E00 + ḠḠḀ Ḁ # 1E01 + Ḃ ḃ Ḃ # 1E02 + ḃ ḃ Ḃ Ḃ # 1E03 + Ḅ ḅ Ḅ # 1E04 + ḅ ḅ Ḅ Ḅ # 1E05 + Ḇ ḇ Ḇ # 1E06 + ḇ ḇ Ḇ Ḇ # 1E07 + Ḉ ḉ Ḉ # 1E08 + ḉ ḉ Ḉ Ḉ # 1E09 + Ḋ ḋ Ḋ # 1E0A + ḋ ḋ Ḋ Ḋ # 1E0B + Ḍ ḠḌ # 1E0C + ḠḠḌ Ḍ # 1E0D + Ḏ ḠḎ # 1E0E + ḠḠḎ Ḏ # 1E0F + Ḡḑ Ḡ# 1E10 + ḑ ḑ ḠḠ# 1E11 + Ḓ ḓ Ḓ # 1E12 + ḓ ḓ Ḓ Ḓ # 1E13 + Ḕ ḕ Ḕ # 1E14 + ḕ ḕ Ḕ Ḕ # 1E15 + Ḗ ḗ Ḗ # 1E16 + ḗ ḗ Ḗ Ḗ # 1E17 + Ḙ ḙ Ḙ # 1E18 + ḙ ḙ Ḙ Ḙ # 1E19 + Ḛ ḛ Ḛ # 1E1A + ḛ ḛ Ḛ Ḛ # 1E1B + Ḝ ḠḜ # 1E1C + ḠḠḜ Ḝ # 1E1D + Ḟ ḟ Ḟ # 1E1E + ḟ ḟ Ḟ Ḟ # 1E1F + Ḡ ḡ Ḡ # 1E20 + ḡ ḡ Ḡ Ḡ # 1E21 + Ḣ ḣ Ḣ # 1E22 + ḣ ḣ Ḣ Ḣ # 1E23 + Ḥ ḥ Ḥ # 1E24 + ḥ ḥ Ḥ Ḥ # 1E25 + Ḧ ḧ Ḧ # 1E26 + ḧ ḧ Ḧ Ḧ # 1E27 + Ḩ ḩ Ḩ # 1E28 + ḩ ḩ Ḩ Ḩ # 1E29 + Ḫ ḫ Ḫ # 1E2A + ḫ ḫ Ḫ Ḫ # 1E2B + Ḭ ḭ Ḭ # 1E2C + ḭ ḭ Ḭ Ḭ # 1E2D + Ḯ ḯ Ḯ # 1E2E + ḯ ḯ Ḯ Ḯ # 1E2F + Ḱ ḱ Ḱ # 1E30 + ḱ ḱ Ḱ Ḱ # 1E31 + Ḳ ḳ Ḳ # 1E32 + ḳ ḳ Ḳ Ḳ # 1E33 + Ḵ ḵ Ḵ # 1E34 + ḵ ḵ Ḵ Ḵ # 1E35 + Ḷ ḷ Ḷ # 1E36 + ḷ ḷ Ḷ Ḷ # 1E37 + Ḹ ḹ Ḹ # 1E38 + ḹ ḹ Ḹ Ḹ # 1E39 + Ḻ ḻ Ḻ # 1E3A + ḻ ḻ Ḻ Ḻ # 1E3B + Ḽ ḽ Ḽ # 1E3C + ḽ ḽ Ḽ Ḽ # 1E3D + Ḿ ḿ Ḿ # 1E3E + ḿ ḿ Ḿ Ḿ # 1E3F + á¹€ á¹ á¹€ # 1E40 + á¹ á¹ á¹€ á¹€ # 1E41 + Ṃ ṃ Ṃ # 1E42 + ṃ ṃ Ṃ Ṃ # 1E43 + Ṅ á¹… Ṅ # 1E44 + á¹… á¹… Ṅ Ṅ # 1E45 + Ṇ ṇ Ṇ # 1E46 + ṇ ṇ Ṇ Ṇ # 1E47 + Ṉ ṉ Ṉ # 1E48 + ṉ ṉ Ṉ Ṉ # 1E49 + Ṋ ṋ Ṋ # 1E4A + ṋ ṋ Ṋ Ṋ # 1E4B + Ṍ ṠṌ # 1E4C + ṠṠṌ Ṍ # 1E4D + Ṏ ṠṎ # 1E4E + ṠṠṎ Ṏ # 1E4F + Ṡṑ á¹ # 1E50 + ṑ ṑ á¹ á¹ # 1E51 + á¹’ ṓ á¹’ # 1E52 + ṓ ṓ á¹’ á¹’ # 1E53 + á¹” ṕ á¹” # 1E54 + ṕ ṕ á¹” á¹” # 1E55 + á¹– á¹— á¹– # 1E56 + á¹— á¹— á¹– á¹– # 1E57 + Ṙ á¹™ Ṙ # 1E58 + á¹™ á¹™ Ṙ Ṙ # 1E59 + Ṛ á¹› Ṛ # 1E5A + á¹› á¹› Ṛ Ṛ # 1E5B + Ṝ ṠṜ # 1E5C + ṠṠṜ Ṝ # 1E5D + Ṟ ṟ Ṟ # 1E5E + ṟ ṟ Ṟ Ṟ # 1E5F + á¹  ṡ á¹  # 1E60 + ṡ ṡ á¹  á¹  # 1E61 + á¹¢ á¹£ á¹¢ # 1E62 + á¹£ á¹£ á¹¢ á¹¢ # 1E63 + Ṥ á¹¥ Ṥ # 1E64 + á¹¥ á¹¥ Ṥ Ṥ # 1E65 + Ṧ á¹§ Ṧ # 1E66 + á¹§ á¹§ Ṧ Ṧ # 1E67 + Ṩ ṩ Ṩ # 1E68 + ṩ ṩ Ṩ Ṩ # 1E69 + Ṫ ṫ Ṫ # 1E6A + ṫ ṫ Ṫ Ṫ # 1E6B + Ṭ á¹­ Ṭ # 1E6C + á¹­ á¹­ Ṭ Ṭ # 1E6D + á¹® ṯ á¹® # 1E6E + ṯ ṯ á¹® á¹® # 1E6F + á¹° á¹± á¹° # 1E70 + á¹± á¹± á¹° á¹° # 1E71 + á¹² á¹³ á¹² # 1E72 + á¹³ á¹³ á¹² á¹² # 1E73 + á¹´ á¹µ á¹´ # 1E74 + á¹µ á¹µ á¹´ á¹´ # 1E75 + á¹¶ á¹· á¹¶ # 1E76 + á¹· á¹· á¹¶ á¹¶ # 1E77 + Ṹ á¹¹ Ṹ # 1E78 + á¹¹ á¹¹ Ṹ Ṹ # 1E79 + Ṻ á¹» Ṻ # 1E7A + á¹» á¹» Ṻ Ṻ # 1E7B + á¹¼ á¹½ á¹¼ # 1E7C + á¹½ á¹½ á¹¼ á¹¼ # 1E7D + á¹¾ ṿ á¹¾ # 1E7E + ṿ ṿ á¹¾ á¹¾ # 1E7F + Ẁ ẠẀ # 1E80 + ẠẠẀ Ẁ # 1E81 + Ẃ ẃ Ẃ # 1E82 + ẃ ẃ Ẃ Ẃ # 1E83 + Ẅ ẅ Ẅ # 1E84 + ẅ ẅ Ẅ Ẅ # 1E85 + Ẇ ẇ Ẇ # 1E86 + ẇ ẇ Ẇ Ẇ # 1E87 + Ẉ ẉ Ẉ # 1E88 + ẉ ẉ Ẉ Ẉ # 1E89 + Ẋ ẋ Ẋ # 1E8A + ẋ ẋ Ẋ Ẋ # 1E8B + Ẍ ẠẌ # 1E8C + ẠẠẌ Ẍ # 1E8D + Ẏ ẠẎ # 1E8E + ẠẠẎ Ẏ # 1E8F + Ạẑ Ạ# 1E90 + ẑ ẑ ẠẠ# 1E91 + Ẓ ẓ Ẓ # 1E92 + ẓ ẓ Ẓ Ẓ # 1E93 + Ẕ ẕ Ẕ # 1E94 + ẕ ẕ Ẕ Ẕ # 1E95 + ẖ ẖ H̱ H̱ # 1E96 + ẗ ẗ T̈ T̈ # 1E97 + ẘ ẘ WÌŠ WÌŠ # 1E98 + ẙ ẙ YÌŠ YÌŠ # 1E99 + ẚ ẚ Aʾ Aʾ # 1E9A + ẛ ẛ á¹  á¹  # 1E9B + ẜ ẜ # 1E9C + ẠẠ# 1E9D + ẞ ß ẞ # 1E9E + ẟ ẟ # 1E9F + Ạ ạ Ạ # 1EA0 + ạ ạ Ạ Ạ # 1EA1 + Ả ả Ả # 1EA2 + ả ả Ả Ả # 1EA3 + Ấ ấ Ấ # 1EA4 + ấ ấ Ấ Ấ # 1EA5 + Ầ ầ Ầ # 1EA6 + ầ ầ Ầ Ầ # 1EA7 + Ẩ ẩ Ẩ # 1EA8 + ẩ ẩ Ẩ Ẩ # 1EA9 + Ẫ ẫ Ẫ # 1EAA + ẫ ẫ Ẫ Ẫ # 1EAB + Ậ ậ Ậ # 1EAC + ậ ậ Ậ Ậ # 1EAD + Ắ ắ Ắ # 1EAE + ắ ắ Ắ Ắ # 1EAF + Ằ ằ Ằ # 1EB0 + ằ ằ Ằ Ằ # 1EB1 + Ẳ ẳ Ẳ # 1EB2 + ẳ ẳ Ẳ Ẳ # 1EB3 + Ẵ ẵ Ẵ # 1EB4 + ẵ ẵ Ẵ Ẵ # 1EB5 + Ặ ặ Ặ # 1EB6 + ặ ặ Ặ Ặ # 1EB7 + Ẹ ẹ Ẹ # 1EB8 + ẹ ẹ Ẹ Ẹ # 1EB9 + Ẻ ẻ Ẻ # 1EBA + ẻ ẻ Ẻ Ẻ # 1EBB + Ẽ ẽ Ẽ # 1EBC + ẽ ẽ Ẽ Ẽ # 1EBD + Ế ế Ế # 1EBE + ế ế Ế Ế # 1EBF + Ề ỠỀ # 1EC0 + ỠỠỀ Ề # 1EC1 + Ể ể Ể # 1EC2 + ể ể Ể Ể # 1EC3 + Ễ á»… Ễ # 1EC4 + á»… á»… Ễ Ễ # 1EC5 + Ệ ệ Ệ # 1EC6 + ệ ệ Ệ Ệ # 1EC7 + Ỉ ỉ Ỉ # 1EC8 + ỉ ỉ Ỉ Ỉ # 1EC9 + Ị ị Ị # 1ECA + ị ị Ị Ị # 1ECB + Ọ ỠỌ # 1ECC + ỠỠỌ Ọ # 1ECD + Ỏ ỠỎ # 1ECE + ỠỠỎ Ỏ # 1ECF + Ỡố á» # 1ED0 + ố ố á» á» # 1ED1 + á»’ ồ á»’ # 1ED2 + ồ ồ á»’ á»’ # 1ED3 + á»” ổ á»” # 1ED4 + ổ ổ á»” á»” # 1ED5 + á»– á»— á»– # 1ED6 + á»— á»— á»– á»– # 1ED7 + Ộ á»™ Ộ # 1ED8 + á»™ á»™ Ộ Ộ # 1ED9 + Ớ á»› Ớ # 1EDA + á»› á»› Ớ Ớ # 1EDB + Ờ ỠỜ # 1EDC + ỠỠỜ Ờ # 1EDD + Ở ở Ở # 1EDE + ở ở Ở Ở # 1EDF + á»  ỡ á»  # 1EE0 + ỡ ỡ á»  á»  # 1EE1 + Ợ ợ Ợ # 1EE2 + ợ ợ Ợ Ợ # 1EE3 + Ụ ụ Ụ # 1EE4 + ụ ụ Ụ Ụ # 1EE5 + Ủ á»§ Ủ # 1EE6 + á»§ á»§ Ủ Ủ # 1EE7 + Ứ ứ Ứ # 1EE8 + ứ ứ Ứ Ứ # 1EE9 + Ừ ừ Ừ # 1EEA + ừ ừ Ừ Ừ # 1EEB + Ử á»­ Ử # 1EEC + á»­ á»­ Ử Ử # 1EED + á»® ữ á»® # 1EEE + ữ ữ á»® á»® # 1EEF + á»° á»± á»° # 1EF0 + á»± á»± á»° á»° # 1EF1 + Ỳ ỳ Ỳ # 1EF2 + ỳ ỳ Ỳ Ỳ # 1EF3 + á»´ ỵ á»´ # 1EF4 + ỵ ỵ á»´ á»´ # 1EF5 + á»¶ á»· á»¶ # 1EF6 + á»· á»· á»¶ á»¶ # 1EF7 + Ỹ ỹ Ỹ # 1EF8 + ỹ ỹ Ỹ Ỹ # 1EF9 + Ỻ á»» Ỻ # 1EFA + á»» á»» Ỻ Ỻ # 1EFB + Ỽ ỽ Ỽ # 1EFC + ỽ ỽ Ỽ Ỽ # 1EFD + Ỿ ỿ Ỿ # 1EFE + ỿ ỿ Ỿ Ỿ # 1EFF + á¼€ á¼€ Ἀ Ἀ # 1F00 + ἠἠἉ Ἁ # 1F01 + ἂ ἂ Ἂ Ἂ # 1F02 + ἃ ἃ Ἃ Ἃ # 1F03 + ἄ ἄ Ἄ Ἄ # 1F04 + á¼… á¼… á¼ á¼ # 1F05 + ἆ ἆ Ἆ Ἆ # 1F06 + ἇ ἇ á¼ á¼ # 1F07 + Ἀ á¼€ Ἀ # 1F08 + Ἁ ἠἉ # 1F09 + Ἂ ἂ Ἂ # 1F0A + Ἃ ἃ Ἃ # 1F0B + Ἄ ἄ Ἄ # 1F0C + á¼ á¼… á¼ # 1F0D + Ἆ ἆ Ἆ # 1F0E + ἠἇ á¼ # 1F0F + ἠἠἘ Ἐ # 1F10 + ἑ ἑ á¼™ á¼™ # 1F11 + á¼’ á¼’ Ἒ Ἒ # 1F12 + ἓ ἓ á¼› á¼› # 1F13 + á¼” á¼” Ἔ Ἔ # 1F14 + ἕ ἕ á¼ á¼ # 1F15 + Ἐ ἠἘ # 1F18 + á¼™ ἑ á¼™ # 1F19 + Ἒ á¼’ Ἒ # 1F1A + á¼› ἓ á¼› # 1F1B + Ἔ á¼” Ἔ # 1F1C + ἠἕ á¼ # 1F1D + á¼  á¼  Ἠ Ἠ # 1F20 + ἡ ἡ Ἡ Ἡ # 1F21 + á¼¢ á¼¢ Ἢ Ἢ # 1F22 + á¼£ á¼£ Ἣ Ἣ # 1F23 + ἤ ἤ Ἤ Ἤ # 1F24 + á¼¥ á¼¥ á¼­ á¼­ # 1F25 + ἦ ἦ á¼® á¼® # 1F26 + á¼§ á¼§ Ἧ Ἧ # 1F27 + Ἠ á¼  Ἠ # 1F28 + Ἡ ἡ Ἡ # 1F29 + Ἢ á¼¢ Ἢ # 1F2A + Ἣ á¼£ Ἣ # 1F2B + Ἤ ἤ Ἤ # 1F2C + á¼­ á¼¥ á¼­ # 1F2D + á¼® ἦ á¼® # 1F2E + Ἧ á¼§ Ἧ # 1F2F + á¼° á¼° Ἰ Ἰ # 1F30 + á¼± á¼± á¼¹ á¼¹ # 1F31 + á¼² á¼² Ἲ Ἲ # 1F32 + á¼³ á¼³ á¼» á¼» # 1F33 + á¼´ á¼´ á¼¼ á¼¼ # 1F34 + á¼µ á¼µ á¼½ á¼½ # 1F35 + á¼¶ á¼¶ á¼¾ á¼¾ # 1F36 + á¼· á¼· Ἷ Ἷ # 1F37 + Ἰ á¼° Ἰ # 1F38 + á¼¹ á¼± á¼¹ # 1F39 + Ἲ á¼² Ἲ # 1F3A + á¼» á¼³ á¼» # 1F3B + á¼¼ á¼´ á¼¼ # 1F3C + á¼½ á¼µ á¼½ # 1F3D + á¼¾ á¼¶ á¼¾ # 1F3E + Ἷ á¼· Ἷ # 1F3F + á½€ á½€ Ὀ Ὀ # 1F40 + ὠὠὉ Ὁ # 1F41 + ὂ ὂ Ὂ Ὂ # 1F42 + ὃ ὃ Ὃ Ὃ # 1F43 + ὄ ὄ Ὄ Ὄ # 1F44 + á½… á½… á½ á½ # 1F45 + Ὀ á½€ Ὀ # 1F48 + Ὁ ὠὉ # 1F49 + Ὂ ὂ Ὂ # 1F4A + Ὃ ὃ Ὃ # 1F4B + Ὄ ὄ Ὄ # 1F4C + á½ á½… á½ # 1F4D + ὠὠΥ̓ Υ̓ # 1F50 + ὑ ὑ á½™ á½™ # 1F51 + á½’ á½’ Υ̓̀ Υ̓̀ # 1F52 + ὓ ὓ á½› á½› # 1F53 + á½” á½” Î¥Ì“Ì Î¥Ì“Ì # 1F54 + ὕ ὕ á½ á½ # 1F55 + á½– á½– Υ̓͂ Υ̓͂ # 1F56 + á½— á½— Ὗ Ὗ # 1F57 + á½™ ὑ á½™ # 1F59 + á½› ὓ á½› # 1F5B + ὠὕ á½ # 1F5D + Ὗ á½— Ὗ # 1F5F + á½  á½  Ὠ Ὠ # 1F60 + ὡ ὡ Ὡ Ὡ # 1F61 + á½¢ á½¢ Ὢ Ὢ # 1F62 + á½£ á½£ Ὣ Ὣ # 1F63 + ὤ ὤ Ὤ Ὤ # 1F64 + á½¥ á½¥ á½­ á½­ # 1F65 + ὦ ὦ á½® á½® # 1F66 + á½§ á½§ Ὧ Ὧ # 1F67 + Ὠ á½  Ὠ # 1F68 + Ὡ ὡ Ὡ # 1F69 + Ὢ á½¢ Ὢ # 1F6A + Ὣ á½£ Ὣ # 1F6B + Ὤ ὤ Ὤ # 1F6C + á½­ á½¥ á½­ # 1F6D + á½® ὦ á½® # 1F6E + Ὧ á½§ Ὧ # 1F6F + á½° á½° Ὰ Ὰ # 1F70 + á½± á½± á¾» á¾» # 1F71 + á½² á½² Ὲ Ὲ # 1F72 + á½³ á½³ Έ Έ # 1F73 + á½´ á½´ Ὴ Ὴ # 1F74 + á½µ á½µ á¿‹ á¿‹ # 1F75 + á½¶ á½¶ Ὶ Ὶ # 1F76 + á½· á½· á¿› á¿› # 1F77 + ὸ ὸ Ὸ Ὸ # 1F78 + á½¹ á½¹ Ό Ό # 1F79 + ὺ ὺ Ὺ Ὺ # 1F7A + á½» á½» á¿« á¿« # 1F7B + á½¼ á½¼ Ὼ Ὼ # 1F7C + á½½ á½½ á¿» á¿» # 1F7D + á¾€ á¾€ ᾈ ἈΙ # 1F80 + ᾠᾠᾉ ἉΙ # 1F81 + ᾂ ᾂ ᾊ ἊΙ # 1F82 + ᾃ ᾃ ᾋ ἋΙ # 1F83 + ᾄ ᾄ ᾌ ἌΙ # 1F84 + á¾… á¾… á¾ á¼Î™ # 1F85 + ᾆ ᾆ ᾎ ἎΙ # 1F86 + ᾇ ᾇ á¾ á¼Î™ # 1F87 + ᾈ á¾€ ᾈ ἈΙ # 1F88 + ᾉ ᾠᾉ ἉΙ # 1F89 + ᾊ ᾂ ᾊ ἊΙ # 1F8A + ᾋ ᾃ ᾋ ἋΙ # 1F8B + ᾌ ᾄ ᾌ ἌΙ # 1F8C + á¾ á¾… á¾ á¼Î™ # 1F8D + ᾎ ᾆ ᾎ ἎΙ # 1F8E + ᾠᾇ á¾ á¼Î™ # 1F8F + ᾠᾠᾘ ἨΙ # 1F90 + ᾑ ᾑ á¾™ ἩΙ # 1F91 + á¾’ á¾’ ᾚ ἪΙ # 1F92 + ᾓ ᾓ á¾› ἫΙ # 1F93 + á¾” á¾” ᾜ ἬΙ # 1F94 + ᾕ ᾕ ᾠἭΙ # 1F95 + á¾– á¾– ᾞ ἮΙ # 1F96 + á¾— á¾— ᾟ ἯΙ # 1F97 + ᾘ ᾠᾘ ἨΙ # 1F98 + á¾™ ᾑ á¾™ ἩΙ # 1F99 + ᾚ á¾’ ᾚ ἪΙ # 1F9A + á¾› ᾓ á¾› ἫΙ # 1F9B + ᾜ á¾” ᾜ ἬΙ # 1F9C + ᾠᾕ ᾠἭΙ # 1F9D + ᾞ á¾– ᾞ ἮΙ # 1F9E + ᾟ á¾— ᾟ ἯΙ # 1F9F + á¾  á¾  ᾨ ὨΙ # 1FA0 + ᾡ ᾡ ᾩ ὩΙ # 1FA1 + á¾¢ á¾¢ ᾪ ὪΙ # 1FA2 + á¾£ á¾£ ᾫ ὫΙ # 1FA3 + ᾤ ᾤ ᾬ ὬΙ # 1FA4 + á¾¥ á¾¥ á¾­ ὭΙ # 1FA5 + ᾦ ᾦ á¾® ὮΙ # 1FA6 + á¾§ á¾§ ᾯ ὯΙ # 1FA7 + ᾨ á¾  ᾨ ὨΙ # 1FA8 + ᾩ ᾡ ᾩ ὩΙ # 1FA9 + ᾪ á¾¢ ᾪ ὪΙ # 1FAA + ᾫ á¾£ ᾫ ὫΙ # 1FAB + ᾬ ᾤ ᾬ ὬΙ # 1FAC + á¾­ á¾¥ á¾­ ὭΙ # 1FAD + á¾® ᾦ á¾® ὮΙ # 1FAE + ᾯ á¾§ ᾯ ὯΙ # 1FAF + á¾° á¾° Ᾰ Ᾰ # 1FB0 + á¾± á¾± á¾¹ á¾¹ # 1FB1 + á¾² á¾² Ὰͅ ᾺΙ # 1FB2 + á¾³ á¾³ á¾¼ ΑΙ # 1FB3 + á¾´ á¾´ Άͅ ΆΙ # 1FB4 + á¾¶ á¾¶ Α͂ Α͂ # 1FB6 + á¾· á¾· ᾼ͂ Α͂Ι # 1FB7 + Ᾰ á¾° Ᾰ # 1FB8 + á¾¹ á¾± á¾¹ # 1FB9 + Ὰ á½° Ὰ # 1FBA + á¾» á½± á¾» # 1FBB + á¾¼ á¾³ á¾¼ ΑΙ # 1FBC + á¾¾ á¾¾ Ι Ι # 1FBE + á¿‚ á¿‚ Ὴͅ ῊΙ # 1FC2 + ῃ ῃ ῌ ΗΙ # 1FC3 + á¿„ á¿„ Ήͅ ΉΙ # 1FC4 + ῆ ῆ Η͂ Η͂ # 1FC6 + ῇ ῇ ῌ͂ Η͂Ι # 1FC7 + Ὲ á½² Ὲ # 1FC8 + Έ á½³ Έ # 1FC9 + Ὴ á½´ Ὴ # 1FCA + á¿‹ á½µ á¿‹ # 1FCB + ῌ ῃ ῌ ΗΙ # 1FCC + ῠῠῘ Ῐ # 1FD0 + á¿‘ á¿‘ á¿™ á¿™ # 1FD1 + á¿’ á¿’ Ϊ̀ Ϊ̀ # 1FD2 + á¿“ á¿“ Î™ÌˆÌ Î™ÌˆÌ # 1FD3 + á¿– á¿– Ι͂ Ι͂ # 1FD6 + á¿— á¿— Ϊ͂ Ϊ͂ # 1FD7 + Ῐ ῠῘ # 1FD8 + á¿™ á¿‘ á¿™ # 1FD9 + Ὶ á½¶ Ὶ # 1FDA + á¿› á½· á¿› # 1FDB + á¿  á¿  Ῠ Ῠ # 1FE0 + á¿¡ á¿¡ á¿© á¿© # 1FE1 + á¿¢ á¿¢ Ϋ̀ Ϋ̀ # 1FE2 + á¿£ á¿£ Î¥ÌˆÌ Î¥ÌˆÌ # 1FE3 + ῤ ῤ Ρ̓ Ρ̓ # 1FE4 + á¿¥ á¿¥ Ῥ Ῥ # 1FE5 + ῦ ῦ Υ͂ Υ͂ # 1FE6 + á¿§ á¿§ Ϋ͂ Ϋ͂ # 1FE7 + Ῠ á¿  Ῠ # 1FE8 + á¿© á¿¡ á¿© # 1FE9 + Ὺ ὺ Ὺ # 1FEA + á¿« á½» á¿« # 1FEB + Ῥ á¿¥ Ῥ # 1FEC + ῲ ῲ Ὼͅ ῺΙ # 1FF2 + ῳ ῳ ῼ ΩΙ # 1FF3 + á¿´ á¿´ ÎÍ… ÎΙ # 1FF4 + á¿¶ á¿¶ Ω͂ Ω͂ # 1FF6 + á¿· á¿· ῼ͂ Ω͂Ι # 1FF7 + Ὸ ὸ Ὸ # 1FF8 + Ό á½¹ Ό # 1FF9 + Ὼ á½¼ Ὼ # 1FFA + á¿» á½½ á¿» # 1FFB + ῼ ῳ ῼ ΩΙ # 1FFC + â„‚ â„‚ # 2102 + ℇ ℇ # 2107 + ℊ ℊ # 210A + â„‹ â„‹ # 210B + ℌ ℌ # 210C + â„ â„ # 210D + ℎ ℎ # 210E + â„ â„ # 210F + â„ â„ # 2110 + â„‘ â„‘ # 2111 + â„’ â„’ # 2112 + â„“ â„“ # 2113 + â„• â„• # 2115 + â„™ â„™ # 2119 + ℚ ℚ # 211A + â„› â„› # 211B + ℜ ℜ # 211C + â„ â„ # 211D + ℤ ℤ # 2124 + Ω ω Ω # 2126 + ℨ ℨ # 2128 + K k K # 212A + â„« Ã¥ â„« # 212B + ℬ ℬ # 212C + â„­ â„­ # 212D + ℯ ℯ # 212F + â„° â„° # 2130 + ℱ ℱ # 2131 + Ⅎ â…Ž Ⅎ # 2132 + ℳ ℳ # 2133 + â„´ â„´ # 2134 + ℹ ℹ # 2139 + ℼ ℼ # 213C + ℽ ℽ # 213D + ℾ ℾ # 213E + â„¿ â„¿ # 213F + â…… â…… # 2145 + â…† â…† # 2146 + â…‡ â…‡ # 2147 + â…ˆ â…ˆ # 2148 + â…‰ â…‰ # 2149 + â…Ž â…Ž Ⅎ Ⅎ # 214E + Ↄ ↄ Ↄ # 2183 + ↄ ↄ Ↄ Ↄ # 2184 + â°€ â°° â°€ # 2C00 + â° â°± â° # 2C01 + â°‚ â°² â°‚ # 2C02 + â°ƒ â°³ â°ƒ # 2C03 + â°„ â°´ â°„ # 2C04 + â°… â°µ â°… # 2C05 + â°† â°¶ â°† # 2C06 + â°‡ â°· â°‡ # 2C07 + â°ˆ â°¸ â°ˆ # 2C08 + â°‰ â°¹ â°‰ # 2C09 + â°Š â°º â°Š # 2C0A + â°‹ â°» â°‹ # 2C0B + â°Œ â°¼ â°Œ # 2C0C + â° â°½ â° # 2C0D + â°Ž â°¾ â°Ž # 2C0E + â° â°¿ â° # 2C0F + â° â±€ â° # 2C10 + â°‘ â± â°‘ # 2C11 + â°’ ⱂ â°’ # 2C12 + â°“ ⱃ â°“ # 2C13 + â°” ⱄ â°” # 2C14 + â°• â±… â°• # 2C15 + â°– ⱆ â°– # 2C16 + â°— ⱇ â°— # 2C17 + â°˜ ⱈ â°˜ # 2C18 + â°™ ⱉ â°™ # 2C19 + â°š ⱊ â°š # 2C1A + â°› ⱋ â°› # 2C1B + â°œ ⱌ â°œ # 2C1C + â° â± â° # 2C1D + â°ž ⱎ â°ž # 2C1E + â°Ÿ â± â°Ÿ # 2C1F + â°  â± â°  # 2C20 + â°¡ ⱑ â°¡ # 2C21 + â°¢ â±’ â°¢ # 2C22 + â°£ ⱓ â°£ # 2C23 + â°¤ â±” â°¤ # 2C24 + â°¥ ⱕ â°¥ # 2C25 + â°¦ â±– â°¦ # 2C26 + â°§ â±— â°§ # 2C27 + â°¨ ⱘ â°¨ # 2C28 + â°© â±™ â°© # 2C29 + â°ª ⱚ â°ª # 2C2A + â°« â±› â°« # 2C2B + â°¬ ⱜ â°¬ # 2C2C + â°­ â± â°­ # 2C2D + â°® ⱞ â°® # 2C2E + â°° â°° â°€ â°€ # 2C30 + â°± â°± â° â° # 2C31 + â°² â°² â°‚ â°‚ # 2C32 + â°³ â°³ â°ƒ â°ƒ # 2C33 + â°´ â°´ â°„ â°„ # 2C34 + â°µ â°µ â°… â°… # 2C35 + â°¶ â°¶ â°† â°† # 2C36 + â°· â°· â°‡ â°‡ # 2C37 + â°¸ â°¸ â°ˆ â°ˆ # 2C38 + â°¹ â°¹ â°‰ â°‰ # 2C39 + â°º â°º â°Š â°Š # 2C3A + â°» â°» â°‹ â°‹ # 2C3B + â°¼ â°¼ â°Œ â°Œ # 2C3C + â°½ â°½ â° â° # 2C3D + â°¾ â°¾ â°Ž â°Ž # 2C3E + â°¿ â°¿ â° â° # 2C3F + â±€ â±€ â° â° # 2C40 + â± â± â°‘ â°‘ # 2C41 + ⱂ ⱂ â°’ â°’ # 2C42 + ⱃ ⱃ â°“ â°“ # 2C43 + ⱄ ⱄ â°” â°” # 2C44 + â±… â±… â°• â°• # 2C45 + ⱆ ⱆ â°– â°– # 2C46 + ⱇ ⱇ â°— â°— # 2C47 + ⱈ ⱈ â°˜ â°˜ # 2C48 + ⱉ ⱉ â°™ â°™ # 2C49 + ⱊ ⱊ â°š â°š # 2C4A + ⱋ ⱋ â°› â°› # 2C4B + ⱌ ⱌ â°œ â°œ # 2C4C + â± â± â° â° # 2C4D + ⱎ ⱎ â°ž â°ž # 2C4E + â± â± â°Ÿ â°Ÿ # 2C4F + â± â± â°  â°  # 2C50 + ⱑ ⱑ â°¡ â°¡ # 2C51 + â±’ â±’ â°¢ â°¢ # 2C52 + ⱓ ⱓ â°£ â°£ # 2C53 + â±” â±” â°¤ â°¤ # 2C54 + ⱕ ⱕ â°¥ â°¥ # 2C55 + â±– â±– â°¦ â°¦ # 2C56 + â±— â±— â°§ â°§ # 2C57 + ⱘ ⱘ â°¨ â°¨ # 2C58 + â±™ â±™ â°© â°© # 2C59 + ⱚ ⱚ â°ª â°ª # 2C5A + â±› â±› â°« â°« # 2C5B + ⱜ ⱜ â°¬ â°¬ # 2C5C + â± â± â°­ â°­ # 2C5D + ⱞ ⱞ â°® â°® # 2C5E + â±  ⱡ â±  # 2C60 + ⱡ ⱡ â±  â±  # 2C61 + â±¢ É« â±¢ # 2C62 + â±£ áµ½ â±£ # 2C63 + Ɽ ɽ Ɽ # 2C64 + â±¥ â±¥ Ⱥ Ⱥ # 2C65 + ⱦ ⱦ Ⱦ Ⱦ # 2C66 + â±§ ⱨ â±§ # 2C67 + ⱨ ⱨ â±§ â±§ # 2C68 + Ⱪ ⱪ Ⱪ # 2C69 + ⱪ ⱪ Ⱪ Ⱪ # 2C6A + Ⱬ ⱬ Ⱬ # 2C6B + ⱬ ⱬ Ⱬ Ⱬ # 2C6C + â±­ É‘ â±­ # 2C6D + â±® ɱ â±® # 2C6E + Ɐ É â±¯ # 2C6F + â±° É’ â±° # 2C70 + â±± â±± # 2C71 + â±² â±³ â±² # 2C72 + â±³ â±³ â±² â±² # 2C73 + â±´ â±´ # 2C74 + â±µ â±¶ â±µ # 2C75 + â±¶ â±¶ â±µ â±µ # 2C76 + â±· â±· # 2C77 + ⱸ ⱸ # 2C78 + â±¹ â±¹ # 2C79 + ⱺ ⱺ # 2C7A + â±» â±» # 2C7B + â±¾ È¿ â±¾ # 2C7E + Ɀ É€ Ɀ # 2C7F + â²€ â² â²€ # 2C80 + â² â² â²€ â²€ # 2C81 + Ⲃ ⲃ Ⲃ # 2C82 + ⲃ ⲃ Ⲃ Ⲃ # 2C83 + Ⲅ â²… Ⲅ # 2C84 + â²… â²… Ⲅ Ⲅ # 2C85 + Ⲇ ⲇ Ⲇ # 2C86 + ⲇ ⲇ Ⲇ Ⲇ # 2C87 + Ⲉ ⲉ Ⲉ # 2C88 + ⲉ ⲉ Ⲉ Ⲉ # 2C89 + Ⲋ ⲋ Ⲋ # 2C8A + ⲋ ⲋ Ⲋ Ⲋ # 2C8B + Ⲍ ⲠⲌ # 2C8C + ⲠⲠⲌ Ⲍ # 2C8D + Ⲏ ⲠⲎ # 2C8E + ⲠⲠⲎ Ⲏ # 2C8F + Ⲡⲑ â² # 2C90 + ⲑ ⲑ â² â² # 2C91 + â²’ ⲓ â²’ # 2C92 + ⲓ ⲓ â²’ â²’ # 2C93 + â²” ⲕ â²” # 2C94 + ⲕ ⲕ â²” â²” # 2C95 + â²– â²— â²– # 2C96 + â²— â²— â²– â²– # 2C97 + Ⲙ â²™ Ⲙ # 2C98 + â²™ â²™ Ⲙ Ⲙ # 2C99 + Ⲛ â²› Ⲛ # 2C9A + â²› â²› Ⲛ Ⲛ # 2C9B + Ⲝ ⲠⲜ # 2C9C + ⲠⲠⲜ Ⲝ # 2C9D + Ⲟ ⲟ Ⲟ # 2C9E + ⲟ ⲟ Ⲟ Ⲟ # 2C9F + â²  ⲡ â²  # 2CA0 + ⲡ ⲡ â²  â²  # 2CA1 + â²¢ â²£ â²¢ # 2CA2 + â²£ â²£ â²¢ â²¢ # 2CA3 + Ⲥ â²¥ Ⲥ # 2CA4 + â²¥ â²¥ Ⲥ Ⲥ # 2CA5 + Ⲧ â²§ Ⲧ # 2CA6 + â²§ â²§ Ⲧ Ⲧ # 2CA7 + Ⲩ ⲩ Ⲩ # 2CA8 + ⲩ ⲩ Ⲩ Ⲩ # 2CA9 + Ⲫ ⲫ Ⲫ # 2CAA + ⲫ ⲫ Ⲫ Ⲫ # 2CAB + Ⲭ â²­ Ⲭ # 2CAC + â²­ â²­ Ⲭ Ⲭ # 2CAD + â²® ⲯ â²® # 2CAE + ⲯ ⲯ â²® â²® # 2CAF + â²° â²± â²° # 2CB0 + â²± â²± â²° â²° # 2CB1 + â²² â²³ â²² # 2CB2 + â²³ â²³ â²² â²² # 2CB3 + â²´ â²µ â²´ # 2CB4 + â²µ â²µ â²´ â²´ # 2CB5 + â²¶ â²· â²¶ # 2CB6 + â²· â²· â²¶ â²¶ # 2CB7 + Ⲹ â²¹ Ⲹ # 2CB8 + â²¹ â²¹ Ⲹ Ⲹ # 2CB9 + Ⲻ â²» Ⲻ # 2CBA + â²» â²» Ⲻ Ⲻ # 2CBB + â²¼ â²½ â²¼ # 2CBC + â²½ â²½ â²¼ â²¼ # 2CBD + â²¾ ⲿ â²¾ # 2CBE + ⲿ ⲿ â²¾ â²¾ # 2CBF + â³€ â³ â³€ # 2CC0 + â³ â³ â³€ â³€ # 2CC1 + Ⳃ ⳃ Ⳃ # 2CC2 + ⳃ ⳃ Ⳃ Ⳃ # 2CC3 + Ⳅ â³… Ⳅ # 2CC4 + â³… â³… Ⳅ Ⳅ # 2CC5 + Ⳇ ⳇ Ⳇ # 2CC6 + ⳇ ⳇ Ⳇ Ⳇ # 2CC7 + Ⳉ ⳉ Ⳉ # 2CC8 + ⳉ ⳉ Ⳉ Ⳉ # 2CC9 + Ⳋ ⳋ Ⳋ # 2CCA + ⳋ ⳋ Ⳋ Ⳋ # 2CCB + Ⳍ ⳠⳌ # 2CCC + ⳠⳠⳌ Ⳍ # 2CCD + Ⳏ ⳠⳎ # 2CCE + ⳠⳠⳎ Ⳏ # 2CCF + Ⳡⳑ â³ # 2CD0 + ⳑ ⳑ â³ â³ # 2CD1 + â³’ ⳓ â³’ # 2CD2 + ⳓ ⳓ â³’ â³’ # 2CD3 + â³” ⳕ â³” # 2CD4 + ⳕ ⳕ â³” â³” # 2CD5 + â³– â³— â³– # 2CD6 + â³— â³— â³– â³– # 2CD7 + Ⳙ â³™ Ⳙ # 2CD8 + â³™ â³™ Ⳙ Ⳙ # 2CD9 + Ⳛ â³› Ⳛ # 2CDA + â³› â³› Ⳛ Ⳛ # 2CDB + Ⳝ ⳠⳜ # 2CDC + ⳠⳠⳜ Ⳝ # 2CDD + Ⳟ ⳟ Ⳟ # 2CDE + ⳟ ⳟ Ⳟ Ⳟ # 2CDF + â³  ⳡ â³  # 2CE0 + ⳡ ⳡ â³  â³  # 2CE1 + â³¢ â³£ â³¢ # 2CE2 + â³£ â³£ â³¢ â³¢ # 2CE3 + ⳤ ⳤ # 2CE4 + Ⳬ ⳬ Ⳬ # 2CEB + ⳬ ⳬ Ⳬ Ⳬ # 2CEC + â³­ â³® â³­ # 2CED + â³® â³® â³­ â³­ # 2CEE + â³² â³³ â³² # 2CF2 + â³³ â³³ â³² â³² # 2CF3 + â´€ â´€ á‚  á‚  # 2D00 + â´ â´ á‚¡ á‚¡ # 2D01 + â´‚ â´‚ á‚¢ á‚¢ # 2D02 + â´ƒ â´ƒ á‚£ á‚£ # 2D03 + â´„ â´„ Ⴄ Ⴄ # 2D04 + â´… â´… á‚¥ á‚¥ # 2D05 + â´† â´† Ⴆ Ⴆ # 2D06 + â´‡ â´‡ á‚§ á‚§ # 2D07 + â´ˆ â´ˆ Ⴈ Ⴈ # 2D08 + â´‰ â´‰ á‚© á‚© # 2D09 + â´Š â´Š Ⴊ Ⴊ # 2D0A + â´‹ â´‹ á‚« á‚« # 2D0B + â´Œ â´Œ Ⴌ Ⴌ # 2D0C + â´ â´ á‚­ á‚­ # 2D0D + â´Ž â´Ž á‚® á‚® # 2D0E + ⴠⴠႯ Ⴏ # 2D0F + â´ â´ á‚° á‚° # 2D10 + â´‘ â´‘ Ⴑ Ⴑ # 2D11 + â´’ â´’ Ⴒ Ⴒ # 2D12 + â´“ â´“ Ⴓ Ⴓ # 2D13 + â´” â´” á‚´ á‚´ # 2D14 + â´• â´• Ⴕ Ⴕ # 2D15 + â´– â´– á‚¶ á‚¶ # 2D16 + â´— â´— á‚· á‚· # 2D17 + â´˜ â´˜ Ⴘ Ⴘ # 2D18 + â´™ â´™ Ⴙ Ⴙ # 2D19 + â´š â´š Ⴚ Ⴚ # 2D1A + â´› â´› á‚» á‚» # 2D1B + â´œ â´œ Ⴜ Ⴜ # 2D1C + ⴠⴠႽ Ⴝ # 2D1D + â´ž â´ž Ⴞ Ⴞ # 2D1E + â´Ÿ â´Ÿ á‚¿ á‚¿ # 2D1F + â´  â´  Ⴠ Ⴠ # 2D20 + â´¡ â´¡ რრ# 2D21 + â´¢ â´¢ Ⴢ Ⴢ # 2D22 + â´£ â´£ Ⴣ Ⴣ # 2D23 + â´¤ â´¤ Ⴤ Ⴤ # 2D24 + â´¥ â´¥ Ⴥ Ⴥ # 2D25 + â´§ â´§ Ⴧ Ⴧ # 2D27 + â´­ â´­ რრ# 2D2D + Ꙁ ê™ ê™€ # A640 + ê™ ê™ ê™€ Ꙁ # A641 + Ꙃ ꙃ Ꙃ # A642 + ꙃ ꙃ Ꙃ Ꙃ # A643 + Ꙅ ê™… Ꙅ # A644 + ê™… ê™… Ꙅ Ꙅ # A645 + Ꙇ ꙇ Ꙇ # A646 + ꙇ ꙇ Ꙇ Ꙇ # A647 + Ꙉ ꙉ Ꙉ # A648 + ꙉ ꙉ Ꙉ Ꙉ # A649 + Ꙋ ꙋ Ꙋ # A64A + ꙋ ꙋ Ꙋ Ꙋ # A64B + Ꙍ ê™ ê™Œ # A64C + ê™ ê™ ê™Œ Ꙍ # A64D + Ꙏ ê™ ê™Ž # A64E + ê™ ê™ ê™Ž Ꙏ # A64F + ê™ ê™‘ ê™ # A650 + ꙑ ꙑ ê™ ê™ # A651 + ê™’ ꙓ ê™’ # A652 + ꙓ ꙓ ê™’ ê™’ # A653 + ê™” ꙕ ê™” # A654 + ꙕ ꙕ ê™” ê™” # A655 + ê™– ê™— ê™– # A656 + ê™— ê™— ê™– ê™– # A657 + Ꙙ ê™™ Ꙙ # A658 + ê™™ ê™™ Ꙙ Ꙙ # A659 + Ꙛ ê™› Ꙛ # A65A + ê™› ê™› Ꙛ Ꙛ # A65B + Ꙝ ê™ ê™œ # A65C + ê™ ê™ ê™œ Ꙝ # A65D + Ꙟ ꙟ Ꙟ # A65E + ꙟ ꙟ Ꙟ Ꙟ # A65F + ê™  ꙡ ê™  # A660 + ꙡ ꙡ ê™  ê™  # A661 + Ꙣ ꙣ Ꙣ # A662 + ꙣ ꙣ Ꙣ Ꙣ # A663 + Ꙥ ꙥ Ꙥ # A664 + ꙥ ꙥ Ꙥ Ꙥ # A665 + Ꙧ ê™§ Ꙧ # A666 + ê™§ ê™§ Ꙧ Ꙧ # A667 + Ꙩ ꙩ Ꙩ # A668 + ꙩ ꙩ Ꙩ Ꙩ # A669 + Ꙫ ꙫ Ꙫ # A66A + ꙫ ꙫ Ꙫ Ꙫ # A66B + Ꙭ ê™­ Ꙭ # A66C + ê™­ ê™­ Ꙭ Ꙭ # A66D + Ꚁ êš êš€ # A680 + êš êš êš€ Ꚁ # A681 + êš‚ ꚃ êš‚ # A682 + ꚃ ꚃ êš‚ êš‚ # A683 + êš„ êš… êš„ # A684 + êš… êš… êš„ êš„ # A685 + Ꚇ ꚇ Ꚇ # A686 + ꚇ ꚇ Ꚇ Ꚇ # A687 + Ꚉ ꚉ Ꚉ # A688 + ꚉ ꚉ Ꚉ Ꚉ # A689 + Ꚋ êš‹ Ꚋ # A68A + êš‹ êš‹ Ꚋ Ꚋ # A68B + Ꚍ êš êšŒ # A68C + êš êš êšŒ Ꚍ # A68D + Ꚏ êš êšŽ # A68E + êš êš êšŽ Ꚏ # A68F + êš êš‘ êš # A690 + êš‘ êš‘ êš êš # A691 + êš’ êš“ êš’ # A692 + êš“ êš“ êš’ êš’ # A693 + êš” êš• êš” # A694 + êš• êš• êš” êš” # A695 + êš– êš— êš– # A696 + êš— êš— êš– êš– # A697 + Ꚙ êš™ Ꚙ # A698 + êš™ êš™ Ꚙ Ꚙ # A699 + êšš êš› êšš # A69A + êš› êš› êšš êšš # A69B + Ꜣ ꜣ Ꜣ # A722 + ꜣ ꜣ Ꜣ Ꜣ # A723 + Ꜥ ꜥ Ꜥ # A724 + ꜥ ꜥ Ꜥ Ꜥ # A725 + Ꜧ ꜧ Ꜧ # A726 + ꜧ ꜧ Ꜧ Ꜧ # A727 + Ꜩ ꜩ Ꜩ # A728 + ꜩ ꜩ Ꜩ Ꜩ # A729 + Ꜫ ꜫ Ꜫ # A72A + ꜫ ꜫ Ꜫ Ꜫ # A72B + Ꜭ ꜭ Ꜭ # A72C + ꜭ ꜭ Ꜭ Ꜭ # A72D + Ꜯ ꜯ Ꜯ # A72E + ꜯ ꜯ Ꜯ Ꜯ # A72F + ꜰ ꜰ # A730 + ꜱ ꜱ # A731 + Ꜳ ꜳ Ꜳ # A732 + ꜳ ꜳ Ꜳ Ꜳ # A733 + Ꜵ ꜵ Ꜵ # A734 + ꜵ ꜵ Ꜵ Ꜵ # A735 + Ꜷ ꜷ Ꜷ # A736 + ꜷ ꜷ Ꜷ Ꜷ # A737 + Ꜹ ꜹ Ꜹ # A738 + ꜹ ꜹ Ꜹ Ꜹ # A739 + Ꜻ ꜻ Ꜻ # A73A + ꜻ ꜻ Ꜻ Ꜻ # A73B + Ꜽ ꜽ Ꜽ # A73C + ꜽ ꜽ Ꜽ Ꜽ # A73D + Ꜿ ꜿ Ꜿ # A73E + ꜿ ꜿ Ꜿ Ꜿ # A73F + ê€ ê ê€ # A740 + ê ê ê€ ê€ # A741 + ê‚ êƒ ê‚ # A742 + êƒ êƒ ê‚ ê‚ # A743 + ê„ ê… ê„ # A744 + ê… ê… ê„ ê„ # A745 + ê† ê‡ ê† # A746 + ê‡ ê‡ ê† ê† # A747 + êˆ ê‰ êˆ # A748 + ê‰ ê‰ êˆ êˆ # A749 + êŠ ê‹ êŠ # A74A + ê‹ ê‹ êŠ êŠ # A74B + êŒ ê êŒ # A74C + ê ê êŒ êŒ # A74D + êŽ ê êŽ # A74E + ê ê êŽ êŽ # A74F + ê ê‘ ê # A750 + ê‘ ê‘ ê ê # A751 + ê’ ê“ ê’ # A752 + ê“ ê“ ê’ ê’ # A753 + ê” ê• ê” # A754 + ê• ê• ê” ê” # A755 + ê– ê— ê– # A756 + ê— ê— ê– ê– # A757 + ê˜ ê™ ê˜ # A758 + ê™ ê™ ê˜ ê˜ # A759 + êš ê› êš # A75A + ê› ê› êš êš # A75B + êœ ê êœ # A75C + ê ê êœ êœ # A75D + êž êŸ êž # A75E + êŸ êŸ êž êž # A75F + ê  ê¡ ê  # A760 + ê¡ ê¡ ê  ê  # A761 + ê¢ ê£ ê¢ # A762 + ê£ ê£ ê¢ ê¢ # A763 + ê¤ ê¥ ê¤ # A764 + ê¥ ê¥ ê¤ ê¤ # A765 + ê¦ ê§ ê¦ # A766 + ê§ ê§ ê¦ ê¦ # A767 + ê¨ ê© ê¨ # A768 + ê© ê© ê¨ ê¨ # A769 + êª ê« êª # A76A + ê« ê« êª êª # A76B + ê¬ ê­ ê¬ # A76C + ê­ ê­ ê¬ ê¬ # A76D + ê® ê¯ ê® # A76E + ê¯ ê¯ ê® ê® # A76F + ê± ê± # A771 + ê² ê² # A772 + ê³ ê³ # A773 + ê´ ê´ # A774 + êµ êµ # A775 + ê¶ ê¶ # A776 + ê· ê· # A777 + ê¸ ê¸ # A778 + ê¹ êº ê¹ # A779 + êº êº ê¹ ê¹ # A77A + ê» ê¼ ê» # A77B + ê¼ ê¼ ê» ê» # A77C + ê½ áµ¹ ê½ # A77D + ê¾ ê¿ ê¾ # A77E + ê¿ ê¿ ê¾ ê¾ # A77F + Ꞁ êž êž€ # A780 + êž êž êž€ Ꞁ # A781 + êž‚ ꞃ êž‚ # A782 + ꞃ ꞃ êž‚ êž‚ # A783 + êž„ êž… êž„ # A784 + êž… êž… êž„ êž„ # A785 + Ꞇ ꞇ Ꞇ # A786 + ꞇ ꞇ Ꞇ Ꞇ # A787 + êž‹ ꞌ êž‹ # A78B + ꞌ ꞌ êž‹ êž‹ # A78C + êž É¥ êž # A78D + ꞎ ꞎ # A78E + êž êž‘ êž # A790 + êž‘ êž‘ êž êž # A791 + êž’ êž“ êž’ # A792 + êž“ êž“ êž’ êž’ # A793 + êž” êž” Ꞔ Ꞔ # A794 + êž• êž• # A795 + êž– êž— êž– # A796 + êž— êž— êž– êž– # A797 + Ꞙ êž™ Ꞙ # A798 + êž™ êž™ Ꞙ Ꞙ # A799 + êžš êž› êžš # A79A + êž› êž› êžš êžš # A79B + êžœ êž êžœ # A79C + êž êž êžœ êžœ # A79D + êžž ꞟ êžž # A79E + ꞟ ꞟ êžž êžž # A79F + êž  êž¡ êž  # A7A0 + êž¡ êž¡ êž  êž  # A7A1 + Ꞣ ꞣ Ꞣ # A7A2 + ꞣ ꞣ Ꞣ Ꞣ # A7A3 + Ꞥ ꞥ Ꞥ # A7A4 + ꞥ ꞥ Ꞥ Ꞥ # A7A5 + Ꞧ êž§ Ꞧ # A7A6 + êž§ êž§ Ꞧ Ꞧ # A7A7 + Ꞩ êž© Ꞩ # A7A8 + êž© êž© Ꞩ Ꞩ # A7A9 + Ɦ ɦ Ɦ # A7AA + êž« Éœ êž« # A7AB + Ɡ É¡ Ɡ # A7AC + êž­ ɬ êž­ # A7AD + êž® ɪ êž® # A7AE + ꞯ ꞯ # A7AF + êž° Êž êž° # A7B0 + êž± ʇ êž± # A7B1 + êž² Ê êž² # A7B2 + êž³ ê­“ êž³ # A7B3 + êž´ êžµ êž´ # A7B4 + êžµ êžµ êž´ êž´ # A7B5 + êž¶ êž· êž¶ # A7B6 + êž· êž· êž¶ êž¶ # A7B7 + Ꞹ êž¹ Ꞹ # A7B8 + êž¹ êž¹ Ꞹ Ꞹ # A7B9 + Ꞻ êž» Ꞻ # A7BA + êž» êž» Ꞻ Ꞻ # A7BB + êž¼ êž½ êž¼ # A7BC + êž½ êž½ êž¼ êž¼ # A7BD + êž¾ êž¿ êž¾ # A7BE + êž¿ êž¿ êž¾ êž¾ # A7BF + Ꟃ ꟃ Ꟃ # A7C2 + ꟃ ꟃ Ꟃ Ꟃ # A7C3 + Ꞔ êž” Ꞔ # A7C4 + Ʂ Ê‚ Ʂ # A7C5 + Ᶎ á¶Ž Ᶎ # A7C6 + Ꟈ ꟈ Ꟈ # A7C7 + ꟈ ꟈ Ꟈ Ꟈ # A7C8 + Ꟊ ꟊ Ꟊ # A7C9 + ꟊ ꟊ Ꟊ Ꟊ # A7CA + Ꟶ ꟶ Ꟶ # A7F5 + ꟶ ꟶ Ꟶ Ꟶ # A7F6 + ꟺ ꟺ # A7FA + ꬰ ꬰ # AB30 + ꬱ ꬱ # AB31 + ꬲ ꬲ # AB32 + ꬳ ꬳ # AB33 + ꬴ ꬴ # AB34 + ꬵ ꬵ # AB35 + ꬶ ꬶ # AB36 + ꬷ ꬷ # AB37 + ꬸ ꬸ # AB38 + ꬹ ꬹ # AB39 + ꬺ ꬺ # AB3A + ꬻ ꬻ # AB3B + ꬼ ꬼ # AB3C + ꬽ ꬽ # AB3D + ꬾ ꬾ # AB3E + ꬿ ꬿ # AB3F + ê­€ ê­€ # AB40 + ê­ ê­ # AB41 + ê­‚ ê­‚ # AB42 + ê­ƒ ê­ƒ # AB43 + ê­„ ê­„ # AB44 + ê­… ê­… # AB45 + ê­† ê­† # AB46 + ê­‡ ê­‡ # AB47 + ê­ˆ ê­ˆ # AB48 + ê­‰ ê­‰ # AB49 + ê­Š ê­Š # AB4A + ê­‹ ê­‹ # AB4B + ê­Œ ê­Œ # AB4C + ê­ ê­ # AB4D + ê­Ž ê­Ž # AB4E + ê­ ê­ # AB4F + ê­ ê­ # AB50 + ê­‘ ê­‘ # AB51 + ê­’ ê­’ # AB52 + ê­“ ê­“ êž³ êž³ # AB53 + ê­” ê­” # AB54 + ê­• ê­• # AB55 + ê­– ê­– # AB56 + ê­— ê­— # AB57 + ê­˜ ê­˜ # AB58 + ê­™ ê­™ # AB59 + ê­š ê­š # AB5A + ê­  ê­  # AB60 + ê­¡ ê­¡ # AB61 + ê­¢ ê­¢ # AB62 + ê­£ ê­£ # AB63 + ê­¤ ê­¤ # AB64 + ê­¥ ê­¥ # AB65 + ê­¦ ê­¦ # AB66 + ê­§ ê­§ # AB67 + ê­¨ ê­¨ # AB68 + ê­° ê­° Ꭰ Ꭰ # AB70 + ê­± ê­± Ꭱ Ꭱ # AB71 + ê­² ê­² Ꭲ Ꭲ # AB72 + ê­³ ê­³ Ꭳ Ꭳ # AB73 + ê­´ ê­´ Ꭴ Ꭴ # AB74 + ê­µ ê­µ Ꭵ Ꭵ # AB75 + ê­¶ ê­¶ Ꭶ Ꭶ # AB76 + ê­· ê­· Ꭷ Ꭷ # AB77 + ê­¸ ê­¸ Ꭸ Ꭸ # AB78 + ê­¹ ê­¹ Ꭹ Ꭹ # AB79 + ê­º ê­º Ꭺ Ꭺ # AB7A + ê­» ê­» Ꭻ Ꭻ # AB7B + ê­¼ ê­¼ Ꭼ Ꭼ # AB7C + ê­½ ê­½ Ꭽ Ꭽ # AB7D + ê­¾ ê­¾ Ꭾ Ꭾ # AB7E + ê­¿ ê­¿ Ꭿ Ꭿ # AB7F + ꮀ ꮀ Ꮀ Ꮀ # AB80 + ê® ê® áŽ± Ꮁ # AB81 + ꮂ ꮂ Ꮂ Ꮂ # AB82 + ꮃ ꮃ Ꮃ Ꮃ # AB83 + ꮄ ꮄ Ꮄ Ꮄ # AB84 + ê®… ê®… Ꮅ Ꮅ # AB85 + ꮆ ꮆ Ꮆ Ꮆ # AB86 + ꮇ ꮇ Ꮇ Ꮇ # AB87 + ꮈ ꮈ Ꮈ Ꮈ # AB88 + ꮉ ꮉ Ꮉ Ꮉ # AB89 + ꮊ ꮊ Ꮊ Ꮊ # AB8A + ꮋ ꮋ Ꮋ Ꮋ # AB8B + ꮌ ꮌ Ꮌ Ꮌ # AB8C + ê® ê® áŽ½ Ꮍ # AB8D + ꮎ ꮎ Ꮎ Ꮎ # AB8E + ê® ê® áŽ¿ Ꮏ # AB8F + ê® ê® á€ á€ # AB90 + ꮑ ꮑ á á # AB91 + ê®’ ê®’ á‚ á‚ # AB92 + ꮓ ꮓ რრ# AB93 + ê®” ê®” á„ á„ # AB94 + ꮕ ꮕ á… á… # AB95 + ê®– ê®– ᆠᆠ# AB96 + ê®— ê®— ᇠᇠ# AB97 + ꮘ ꮘ ሠሠ# AB98 + ê®™ ê®™ በበ# AB99 + ꮚ ꮚ አአ# AB9A + ê®› ê®› á‹ á‹ # AB9B + ꮜ ꮜ ጠጠ# AB9C + ê® ê® á á # AB9D + ꮞ ꮞ ᎠᎠ# AB9E + ꮟ ꮟ á á # AB9F + ê®  ê®  á á # ABA0 + ꮡ ꮡ á‘ á‘ # ABA1 + ꮢ ꮢ á’ á’ # ABA2 + ꮣ ꮣ á“ á“ # ABA3 + ꮤ ꮤ á” á” # ABA4 + ꮥ ꮥ á• á• # ABA5 + ꮦ ꮦ á– á– # ABA6 + ê®§ ê®§ á— á— # ABA7 + ꮨ ꮨ ᘠᘠ# ABA8 + ꮩ ꮩ á™ á™ # ABA9 + ꮪ ꮪ áš áš # ABAA + ꮫ ꮫ á› á› # ABAB + ꮬ ꮬ ᜠᜠ# ABAC + ê®­ ê®­ á á # ABAD + ê®® ê®® áž áž # ABAE + ꮯ ꮯ ០០# ABAF + ê®° ê®° á  á  # ABB0 + ê®± ê®± á¡ á¡ # ABB1 + ꮲ ꮲ ᢠᢠ# ABB2 + ꮳ ꮳ ᣠᣠ# ABB3 + ê®´ ê®´ ᤠᤠ# ABB4 + ꮵ ꮵ ᥠᥠ# ABB5 + ê®¶ ê®¶ ᦠᦠ# ABB6 + ê®· ê®· á§ á§ # ABB7 + ꮸ ꮸ ᨠᨠ# ABB8 + ꮹ ꮹ á© á© # ABB9 + ꮺ ꮺ ᪠᪠# ABBA + ê®» ê®» á« á« # ABBB + ꮼ ꮼ ᬠᬠ# ABBC + ꮽ ꮽ á­ á­ # ABBD + ꮾ ꮾ á® á® # ABBE + ꮿ ꮿ ᯠᯠ# ABBF + ff ff Ff FF # FB00 + ï¬ ï¬ Fi FI # FB01 + fl fl Fl FL # FB02 + ffi ffi Ffi FFI # FB03 + ffl ffl Ffl FFL # FB04 + ſt ſt St ST # FB05 + st st St ST # FB06 + ﬓ ﬓ Õ„Õ¶ Õ„Õ† # FB13 + ﬔ ﬔ Õ„Õ¥ Õ„Ôµ # FB14 + ﬕ ﬕ Õ„Õ« Õ„Ô» # FB15 + ﬖ ﬖ ÕŽÕ¶ ÕŽÕ† # FB16 + ﬗ ﬗ Õ„Õ­ Õ„Ô½ # FB17 + A ï½ ï¼¡ # FF21 + ï¼¢ b ï¼¢ # FF22 + ï¼£ c ï¼£ # FF23 + D d D # FF24 + ï¼¥ ï½… ï¼¥ # FF25 + F f F # FF26 + ï¼§ g ï¼§ # FF27 + H h H # FF28 + I i I # FF29 + J j J # FF2A + K k K # FF2B + L l L # FF2C + ï¼­ ï½ ï¼­ # FF2D + ï¼® n ï¼® # FF2E + O ï½ ï¼¯ # FF2F + ï¼° ï½ ï¼° # FF30 + ï¼± q ï¼± # FF31 + ï¼² ï½’ ï¼² # FF32 + ï¼³ s ï¼³ # FF33 + ï¼´ ï½” ï¼´ # FF34 + ï¼µ u ï¼µ # FF35 + ï¼¶ ï½– ï¼¶ # FF36 + ï¼· ï½— ï¼· # FF37 + X x X # FF38 + ï¼¹ ï½™ ï¼¹ # FF39 + Z z Z # FF3A + ï½ ï½ ï¼¡ A # FF41 + b b ï¼¢ ï¼¢ # FF42 + c c ï¼£ ï¼£ # FF43 + d d D D # FF44 + ï½… ï½… ï¼¥ ï¼¥ # FF45 + f f F F # FF46 + g g ï¼§ ï¼§ # FF47 + h h H H # FF48 + i i I I # FF49 + j j J J # FF4A + k k K K # FF4B + l l L L # FF4C + ï½ ï½ ï¼­ ï¼­ # FF4D + n n ï¼® ï¼® # FF4E + ï½ ï½ ï¼¯ O # FF4F + ï½ ï½ ï¼° ï¼° # FF50 + q q ï¼± ï¼± # FF51 + ï½’ ï½’ ï¼² ï¼² # FF52 + s s ï¼³ ï¼³ # FF53 + ï½” ï½” ï¼´ ï¼´ # FF54 + u u ï¼µ ï¼µ # FF55 + ï½– ï½– ï¼¶ ï¼¶ # FF56 + ï½— ï½— ï¼· ï¼· # FF57 + x x X X # FF58 + ï½™ ï½™ ï¼¹ ï¼¹ # FF59 + z z Z Z # FF5A + ð€ ð¨ ð€ # 10400 + ð ð© ð # 10401 + ð‚ ðª ð‚ # 10402 + ðƒ ð« ðƒ # 10403 + ð„ ð¬ ð„ # 10404 + ð… ð­ ð… # 10405 + ð† ð® ð† # 10406 + ð‡ ð¯ ð‡ # 10407 + ðˆ ð° ðˆ # 10408 + ð‰ ð± ð‰ # 10409 + ðŠ ð² ðŠ # 1040A + ð‹ ð³ ð‹ # 1040B + ðŒ ð´ ðŒ # 1040C + ð ðµ ð # 1040D + ðŽ ð¶ ðŽ # 1040E + ð ð· ð # 1040F + ð ð¸ ð # 10410 + ð‘ ð¹ ð‘ # 10411 + ð’ ðº ð’ # 10412 + ð“ ð» ð“ # 10413 + ð” ð¼ ð” # 10414 + ð• ð½ ð• # 10415 + ð– ð¾ ð– # 10416 + ð— ð¿ ð— # 10417 + ð˜ ð‘€ ð˜ # 10418 + ð™ ð‘ ð™ # 10419 + ðš ð‘‚ ðš # 1041A + ð› 𑃠ð› # 1041B + ðœ ð‘„ ðœ # 1041C + ð ð‘… ð # 1041D + ðž 𑆠ðž # 1041E + ðŸ 𑇠ðŸ # 1041F + ð  𑈠ð  # 10420 + ð¡ 𑉠ð¡ # 10421 + ð¢ 𑊠ð¢ # 10422 + ð£ ð‘‹ ð£ # 10423 + ð¤ 𑌠ð¤ # 10424 + ð¥ ð‘ ð¥ # 10425 + ð¦ 𑎠ð¦ # 10426 + ð§ ð‘ ð§ # 10427 + ð¨ ð¨ ð€ ð€ # 10428 + ð© ð© ð ð # 10429 + ðª ðª ð‚ ð‚ # 1042A + ð« ð« ðƒ ðƒ # 1042B + ð¬ ð¬ ð„ ð„ # 1042C + ð­ ð­ ð… ð… # 1042D + ð® ð® ð† ð† # 1042E + ð¯ ð¯ ð‡ ð‡ # 1042F + ð° ð° ðˆ ðˆ # 10430 + ð± ð± ð‰ ð‰ # 10431 + ð² ð² ðŠ ðŠ # 10432 + ð³ ð³ ð‹ ð‹ # 10433 + ð´ ð´ ðŒ ðŒ # 10434 + ðµ ðµ ð ð # 10435 + ð¶ ð¶ ðŽ ðŽ # 10436 + ð· ð· ð ð # 10437 + ð¸ ð¸ ð ð # 10438 + ð¹ ð¹ ð‘ ð‘ # 10439 + ðº ðº ð’ ð’ # 1043A + ð» ð» ð“ ð“ # 1043B + ð¼ ð¼ ð” ð” # 1043C + ð½ ð½ ð• ð• # 1043D + ð¾ ð¾ ð– ð– # 1043E + ð¿ ð¿ ð— ð— # 1043F + ð‘€ ð‘€ ð˜ ð˜ # 10440 + ð‘ ð‘ ð™ ð™ # 10441 + ð‘‚ ð‘‚ ðš ðš # 10442 + 𑃠𑃠ð› ð› # 10443 + ð‘„ ð‘„ ðœ ðœ # 10444 + ð‘… ð‘… ð ð # 10445 + 𑆠𑆠ðž ðž # 10446 + 𑇠𑇠ðŸ ðŸ # 10447 + 𑈠𑈠ð  ð  # 10448 + 𑉠𑉠ð¡ ð¡ # 10449 + 𑊠𑊠ð¢ ð¢ # 1044A + ð‘‹ ð‘‹ ð£ ð£ # 1044B + 𑌠𑌠ð¤ ð¤ # 1044C + ð‘ ð‘ ð¥ ð¥ # 1044D + 𑎠𑎠ð¦ ð¦ # 1044E + ð‘ ð‘ ð§ ð§ # 1044F + 𒰠𓘠𒰠# 104B0 + ð’± ð“™ ð’± # 104B1 + 𒲠𓚠𒲠# 104B2 + ð’³ ð“› ð’³ # 104B3 + 𒴠𓜠𒴠# 104B4 + ð’µ ð“ ð’µ # 104B5 + 𒶠𓞠𒶠# 104B6 + 𒷠𓟠𒷠# 104B7 + ð’¸ ð“  ð’¸ # 104B8 + ð’¹ ð“¡ ð’¹ # 104B9 + ð’º ð“¢ ð’º # 104BA + ð’» ð“£ ð’» # 104BB + 𒼠𓤠𒼠# 104BC + ð’½ ð“¥ ð’½ # 104BD + 𒾠𓦠𒾠# 104BE + ð’¿ ð“§ ð’¿ # 104BF + 𓀠𓨠𓀠# 104C0 + ð“ ð“© ð“ # 104C1 + 𓂠𓪠𓂠# 104C2 + 𓃠𓫠𓃠# 104C3 + 𓄠𓬠𓄠# 104C4 + ð“… ð“­ ð“… # 104C5 + 𓆠𓮠𓆠# 104C6 + 𓇠𓯠𓇠# 104C7 + 𓈠𓰠𓈠# 104C8 + 𓉠𓱠𓉠# 104C9 + 𓊠𓲠𓊠# 104CA + 𓋠𓳠𓋠# 104CB + 𓌠𓴠𓌠# 104CC + ð“ 𓵠ð“ # 104CD + 𓎠𓶠𓎠# 104CE + ð“ ð“· ð“ # 104CF + ð“ 𓸠ð“ # 104D0 + 𓑠𓹠𓑠# 104D1 + 𓒠𓺠𓒠# 104D2 + ð““ ð“» ð““ # 104D3 + 𓘠𓘠𒰠𒰠# 104D8 + ð“™ ð“™ ð’± ð’± # 104D9 + 𓚠𓚠𒲠𒲠# 104DA + ð“› ð“› ð’³ ð’³ # 104DB + 𓜠𓜠𒴠𒴠# 104DC + ð“ ð“ ð’µ ð’µ # 104DD + 𓞠𓞠𒶠𒶠# 104DE + 𓟠𓟠𒷠𒷠# 104DF + ð“  ð“  ð’¸ ð’¸ # 104E0 + ð“¡ ð“¡ ð’¹ ð’¹ # 104E1 + ð“¢ ð“¢ ð’º ð’º # 104E2 + ð“£ ð“£ ð’» ð’» # 104E3 + 𓤠𓤠𒼠𒼠# 104E4 + ð“¥ ð“¥ ð’½ ð’½ # 104E5 + 𓦠𓦠𒾠𒾠# 104E6 + ð“§ ð“§ ð’¿ ð’¿ # 104E7 + 𓨠𓨠𓀠𓀠# 104E8 + ð“© ð“© ð“ ð“ # 104E9 + 𓪠𓪠𓂠𓂠# 104EA + 𓫠𓫠𓃠𓃠# 104EB + 𓬠𓬠𓄠𓄠# 104EC + ð“­ ð“­ ð“… ð“… # 104ED + 𓮠𓮠𓆠𓆠# 104EE + 𓯠𓯠𓇠𓇠# 104EF + 𓰠𓰠𓈠𓈠# 104F0 + 𓱠𓱠𓉠𓉠# 104F1 + 𓲠𓲠𓊠𓊠# 104F2 + 𓳠𓳠𓋠𓋠# 104F3 + 𓴠𓴠𓌠𓌠# 104F4 + 𓵠𓵠ð“ ð“ # 104F5 + 𓶠𓶠𓎠𓎠# 104F6 + ð“· ð“· ð“ ð“ # 104F7 + 𓸠𓸠ð“ ð“ # 104F8 + 𓹠𓹠𓑠𓑠# 104F9 + 𓺠𓺠𓒠𓒠# 104FA + ð“» ð“» ð““ ð““ # 104FB + ð²€ ð³€ ð²€ # 10C80 + ð² ð³ ð² # 10C81 + 𲂠𳂠𲂠# 10C82 + 𲃠𳃠𲃠# 10C83 + 𲄠𳄠𲄠# 10C84 + ð²… ð³… ð²… # 10C85 + 𲆠𳆠𲆠# 10C86 + 𲇠𳇠𲇠# 10C87 + 𲈠𳈠𲈠# 10C88 + 𲉠𳉠𲉠# 10C89 + 𲊠𳊠𲊠# 10C8A + 𲋠𳋠𲋠# 10C8B + 𲌠𳌠𲌠# 10C8C + ð² ð³ ð² # 10C8D + 𲎠𳎠𲎠# 10C8E + ð² ð³ ð² # 10C8F + ð² ð³ ð² # 10C90 + 𲑠𳑠𲑠# 10C91 + ð²’ ð³’ ð²’ # 10C92 + 𲓠𳓠𲓠# 10C93 + ð²” ð³” ð²” # 10C94 + 𲕠𳕠𲕠# 10C95 + ð²– ð³– ð²– # 10C96 + ð²— ð³— ð²— # 10C97 + 𲘠𳘠𲘠# 10C98 + ð²™ ð³™ ð²™ # 10C99 + 𲚠𳚠𲚠# 10C9A + ð²› ð³› ð²› # 10C9B + 𲜠𳜠𲜠# 10C9C + ð² ð³ ð² # 10C9D + 𲞠𳞠𲞠# 10C9E + 𲟠𳟠𲟠# 10C9F + ð²  ð³  ð²  # 10CA0 + 𲡠𳡠𲡠# 10CA1 + ð²¢ ð³¢ ð²¢ # 10CA2 + ð²£ ð³£ ð²£ # 10CA3 + 𲤠𳤠𲤠# 10CA4 + ð²¥ ð³¥ ð²¥ # 10CA5 + 𲦠𳦠𲦠# 10CA6 + ð²§ ð³§ ð²§ # 10CA7 + 𲨠𳨠𲨠# 10CA8 + 𲩠𳩠𲩠# 10CA9 + 𲪠𳪠𲪠# 10CAA + 𲫠𳫠𲫠# 10CAB + 𲬠𳬠𲬠# 10CAC + ð²­ ð³­ ð²­ # 10CAD + ð²® ð³® ð²® # 10CAE + 𲯠𳯠𲯠# 10CAF + ð²° ð³° ð²° # 10CB0 + ð²± ð³± ð²± # 10CB1 + ð²² ð³² ð²² # 10CB2 + ð³€ ð³€ ð²€ ð²€ # 10CC0 + ð³ ð³ ð² ð² # 10CC1 + 𳂠𳂠𲂠𲂠# 10CC2 + 𳃠𳃠𲃠𲃠# 10CC3 + 𳄠𳄠𲄠𲄠# 10CC4 + ð³… ð³… ð²… ð²… # 10CC5 + 𳆠𳆠𲆠𲆠# 10CC6 + 𳇠𳇠𲇠𲇠# 10CC7 + 𳈠𳈠𲈠𲈠# 10CC8 + 𳉠𳉠𲉠𲉠# 10CC9 + 𳊠𳊠𲊠𲊠# 10CCA + 𳋠𳋠𲋠𲋠# 10CCB + 𳌠𳌠𲌠𲌠# 10CCC + ð³ ð³ ð² ð² # 10CCD + 𳎠𳎠𲎠𲎠# 10CCE + ð³ ð³ ð² ð² # 10CCF + ð³ ð³ ð² ð² # 10CD0 + 𳑠𳑠𲑠𲑠# 10CD1 + ð³’ ð³’ ð²’ ð²’ # 10CD2 + 𳓠𳓠𲓠𲓠# 10CD3 + ð³” ð³” ð²” ð²” # 10CD4 + 𳕠𳕠𲕠𲕠# 10CD5 + ð³– ð³– ð²– ð²– # 10CD6 + ð³— ð³— ð²— ð²— # 10CD7 + 𳘠𳘠𲘠𲘠# 10CD8 + ð³™ ð³™ ð²™ ð²™ # 10CD9 + 𳚠𳚠𲚠𲚠# 10CDA + ð³› ð³› ð²› ð²› # 10CDB + 𳜠𳜠𲜠𲜠# 10CDC + ð³ ð³ ð² ð² # 10CDD + 𳞠𳞠𲞠𲞠# 10CDE + 𳟠𳟠𲟠𲟠# 10CDF + ð³  ð³  ð²  ð²  # 10CE0 + 𳡠𳡠𲡠𲡠# 10CE1 + ð³¢ ð³¢ ð²¢ ð²¢ # 10CE2 + ð³£ ð³£ ð²£ ð²£ # 10CE3 + 𳤠𳤠𲤠𲤠# 10CE4 + ð³¥ ð³¥ ð²¥ ð²¥ # 10CE5 + 𳦠𳦠𲦠𲦠# 10CE6 + ð³§ ð³§ ð²§ ð²§ # 10CE7 + 𳨠𳨠𲨠𲨠# 10CE8 + 𳩠𳩠𲩠𲩠# 10CE9 + 𳪠𳪠𲪠𲪠# 10CEA + 𳫠𳫠𲫠𲫠# 10CEB + 𳬠𳬠𲬠𲬠# 10CEC + ð³­ ð³­ ð²­ ð²­ # 10CED + ð³® ð³® ð²® ð²® # 10CEE + 𳯠𳯠𲯠𲯠# 10CEF + ð³° ð³° ð²° ð²° # 10CF0 + ð³± ð³± ð²± ð²± # 10CF1 + ð³² ð³² ð²² ð²² # 10CF2 + ð‘¢  ð‘£€ ð‘¢  # 118A0 + 𑢡 𑣠𑢡 # 118A1 + ð‘¢¢ 𑣂 ð‘¢¢ # 118A2 + ð‘¢£ 𑣃 ð‘¢£ # 118A3 + 𑢤 𑣄 𑢤 # 118A4 + ð‘¢¥ ð‘£… ð‘¢¥ # 118A5 + 𑢦 𑣆 𑢦 # 118A6 + ð‘¢§ 𑣇 ð‘¢§ # 118A7 + 𑢨 𑣈 𑢨 # 118A8 + 𑢩 𑣉 𑢩 # 118A9 + 𑢪 𑣊 𑢪 # 118AA + 𑢫 𑣋 𑢫 # 118AB + 𑢬 𑣌 𑢬 # 118AC + ð‘¢­ ð‘£ ð‘¢­ # 118AD + ð‘¢® 𑣎 ð‘¢® # 118AE + 𑢯 𑣠𑢯 # 118AF + ð‘¢° ð‘£ ð‘¢° # 118B0 + ð‘¢± 𑣑 ð‘¢± # 118B1 + ð‘¢² ð‘£’ ð‘¢² # 118B2 + ð‘¢³ 𑣓 ð‘¢³ # 118B3 + ð‘¢´ ð‘£” ð‘¢´ # 118B4 + ð‘¢µ 𑣕 ð‘¢µ # 118B5 + ð‘¢¶ ð‘£– ð‘¢¶ # 118B6 + ð‘¢· ð‘£— ð‘¢· # 118B7 + 𑢸 𑣘 𑢸 # 118B8 + ð‘¢¹ ð‘£™ ð‘¢¹ # 118B9 + 𑢺 𑣚 𑢺 # 118BA + ð‘¢» ð‘£› ð‘¢» # 118BB + ð‘¢¼ 𑣜 ð‘¢¼ # 118BC + ð‘¢½ ð‘£ ð‘¢½ # 118BD + ð‘¢¾ 𑣞 ð‘¢¾ # 118BE + 𑢿 𑣟 𑢿 # 118BF + ð‘£€ ð‘£€ ð‘¢  ð‘¢  # 118C0 + 𑣠𑣠𑢡 𑢡 # 118C1 + 𑣂 𑣂 ð‘¢¢ ð‘¢¢ # 118C2 + 𑣃 𑣃 ð‘¢£ ð‘¢£ # 118C3 + 𑣄 𑣄 𑢤 𑢤 # 118C4 + ð‘£… ð‘£… ð‘¢¥ ð‘¢¥ # 118C5 + 𑣆 𑣆 𑢦 𑢦 # 118C6 + 𑣇 𑣇 ð‘¢§ ð‘¢§ # 118C7 + 𑣈 𑣈 𑢨 𑢨 # 118C8 + 𑣉 𑣉 𑢩 𑢩 # 118C9 + 𑣊 𑣊 𑢪 𑢪 # 118CA + 𑣋 𑣋 𑢫 𑢫 # 118CB + 𑣌 𑣌 𑢬 𑢬 # 118CC + ð‘£ ð‘£ ð‘¢­ ð‘¢­ # 118CD + 𑣎 𑣎 ð‘¢® ð‘¢® # 118CE + 𑣠𑣠𑢯 𑢯 # 118CF + ð‘£ ð‘£ ð‘¢° ð‘¢° # 118D0 + 𑣑 𑣑 ð‘¢± ð‘¢± # 118D1 + ð‘£’ ð‘£’ ð‘¢² ð‘¢² # 118D2 + 𑣓 𑣓 ð‘¢³ ð‘¢³ # 118D3 + ð‘£” ð‘£” ð‘¢´ ð‘¢´ # 118D4 + 𑣕 𑣕 ð‘¢µ ð‘¢µ # 118D5 + ð‘£– ð‘£– ð‘¢¶ ð‘¢¶ # 118D6 + ð‘£— ð‘£— ð‘¢· ð‘¢· # 118D7 + 𑣘 𑣘 𑢸 𑢸 # 118D8 + ð‘£™ ð‘£™ ð‘¢¹ ð‘¢¹ # 118D9 + 𑣚 𑣚 𑢺 𑢺 # 118DA + ð‘£› ð‘£› ð‘¢» ð‘¢» # 118DB + 𑣜 𑣜 ð‘¢¼ ð‘¢¼ # 118DC + ð‘£ ð‘£ ð‘¢½ ð‘¢½ # 118DD + 𑣞 𑣞 ð‘¢¾ ð‘¢¾ # 118DE + 𑣟 𑣟 𑢿 𑢿 # 118DF + ð–¹€ ð–¹  ð–¹€ # 16E40 + 𖹠𖹡 ð–¹ # 16E41 + 𖹂 ð–¹¢ 𖹂 # 16E42 + 𖹃 ð–¹£ 𖹃 # 16E43 + 𖹄 𖹤 𖹄 # 16E44 + ð–¹… ð–¹¥ ð–¹… # 16E45 + 𖹆 𖹦 𖹆 # 16E46 + 𖹇 ð–¹§ 𖹇 # 16E47 + 𖹈 𖹨 𖹈 # 16E48 + 𖹉 𖹩 𖹉 # 16E49 + 𖹊 𖹪 𖹊 # 16E4A + 𖹋 𖹫 𖹋 # 16E4B + 𖹌 𖹬 𖹌 # 16E4C + ð–¹ ð–¹­ ð–¹ # 16E4D + 𖹎 ð–¹® 𖹎 # 16E4E + 𖹠𖹯 ð–¹ # 16E4F + ð–¹ ð–¹° ð–¹ # 16E50 + 𖹑 ð–¹± 𖹑 # 16E51 + ð–¹’ ð–¹² ð–¹’ # 16E52 + 𖹓 ð–¹³ 𖹓 # 16E53 + ð–¹” ð–¹´ ð–¹” # 16E54 + 𖹕 ð–¹µ 𖹕 # 16E55 + ð–¹– ð–¹¶ ð–¹– # 16E56 + ð–¹— ð–¹· ð–¹— # 16E57 + 𖹘 𖹸 𖹘 # 16E58 + ð–¹™ ð–¹¹ ð–¹™ # 16E59 + 𖹚 𖹺 𖹚 # 16E5A + ð–¹› ð–¹» ð–¹› # 16E5B + 𖹜 ð–¹¼ 𖹜 # 16E5C + ð–¹ ð–¹½ ð–¹ # 16E5D + 𖹞 ð–¹¾ 𖹞 # 16E5E + 𖹟 𖹿 𖹟 # 16E5F + ð–¹  ð–¹  ð–¹€ ð–¹€ # 16E60 + 𖹡 𖹡 ð–¹ ð–¹ # 16E61 + ð–¹¢ ð–¹¢ 𖹂 𖹂 # 16E62 + ð–¹£ ð–¹£ 𖹃 𖹃 # 16E63 + 𖹤 𖹤 𖹄 𖹄 # 16E64 + ð–¹¥ ð–¹¥ ð–¹… ð–¹… # 16E65 + 𖹦 𖹦 𖹆 𖹆 # 16E66 + ð–¹§ ð–¹§ 𖹇 𖹇 # 16E67 + 𖹨 𖹨 𖹈 𖹈 # 16E68 + 𖹩 𖹩 𖹉 𖹉 # 16E69 + 𖹪 𖹪 𖹊 𖹊 # 16E6A + 𖹫 𖹫 𖹋 𖹋 # 16E6B + 𖹬 𖹬 𖹌 𖹌 # 16E6C + ð–¹­ ð–¹­ ð–¹ ð–¹ # 16E6D + ð–¹® ð–¹® 𖹎 𖹎 # 16E6E + 𖹯 𖹯 ð–¹ ð–¹ # 16E6F + ð–¹° ð–¹° ð–¹ ð–¹ # 16E70 + ð–¹± ð–¹± 𖹑 𖹑 # 16E71 + ð–¹² ð–¹² ð–¹’ ð–¹’ # 16E72 + ð–¹³ ð–¹³ 𖹓 𖹓 # 16E73 + ð–¹´ ð–¹´ ð–¹” ð–¹” # 16E74 + ð–¹µ ð–¹µ 𖹕 𖹕 # 16E75 + ð–¹¶ ð–¹¶ ð–¹– ð–¹– # 16E76 + ð–¹· ð–¹· ð–¹— ð–¹— # 16E77 + 𖹸 𖹸 𖹘 𖹘 # 16E78 + ð–¹¹ ð–¹¹ ð–¹™ ð–¹™ # 16E79 + 𖹺 𖹺 𖹚 𖹚 # 16E7A + ð–¹» ð–¹» ð–¹› ð–¹› # 16E7B + ð–¹¼ ð–¹¼ 𖹜 𖹜 # 16E7C + ð–¹½ ð–¹½ ð–¹ ð–¹ # 16E7D + ð–¹¾ ð–¹¾ 𖹞 𖹞 # 16E7E + 𖹿 𖹿 𖹟 𖹟 # 16E7F + ð€ ð€ # 1D400 + ð ð # 1D401 + ð‚ ð‚ # 1D402 + ðƒ ðƒ # 1D403 + ð„ ð„ # 1D404 + ð… ð… # 1D405 + ð† ð† # 1D406 + ð‡ ð‡ # 1D407 + ðˆ ðˆ # 1D408 + ð‰ ð‰ # 1D409 + ðŠ ðŠ # 1D40A + ð‹ ð‹ # 1D40B + ðŒ ðŒ # 1D40C + ð ð # 1D40D + ðŽ ðŽ # 1D40E + ð ð # 1D40F + ð ð # 1D410 + ð‘ ð‘ # 1D411 + ð’ ð’ # 1D412 + ð“ ð“ # 1D413 + ð” ð” # 1D414 + ð• ð• # 1D415 + ð– ð– # 1D416 + ð— ð— # 1D417 + ð˜ ð˜ # 1D418 + ð™ ð™ # 1D419 + ðš ðš # 1D41A + ð› ð› # 1D41B + ðœ ðœ # 1D41C + ð ð # 1D41D + ðž ðž # 1D41E + ðŸ ðŸ # 1D41F + ð  ð  # 1D420 + ð¡ ð¡ # 1D421 + ð¢ ð¢ # 1D422 + ð£ ð£ # 1D423 + ð¤ ð¤ # 1D424 + ð¥ ð¥ # 1D425 + ð¦ ð¦ # 1D426 + ð§ ð§ # 1D427 + ð¨ ð¨ # 1D428 + ð© ð© # 1D429 + ðª ðª # 1D42A + ð« ð« # 1D42B + ð¬ ð¬ # 1D42C + ð­ ð­ # 1D42D + ð® ð® # 1D42E + ð¯ ð¯ # 1D42F + ð° ð° # 1D430 + ð± ð± # 1D431 + ð² ð² # 1D432 + ð³ ð³ # 1D433 + ð´ ð´ # 1D434 + ðµ ðµ # 1D435 + ð¶ ð¶ # 1D436 + ð· ð· # 1D437 + ð¸ ð¸ # 1D438 + ð¹ ð¹ # 1D439 + ðº ðº # 1D43A + ð» ð» # 1D43B + ð¼ ð¼ # 1D43C + ð½ ð½ # 1D43D + ð¾ ð¾ # 1D43E + ð¿ ð¿ # 1D43F + ð‘€ ð‘€ # 1D440 + ð‘ ð‘ # 1D441 + ð‘‚ ð‘‚ # 1D442 + 𑃠𑃠# 1D443 + ð‘„ ð‘„ # 1D444 + ð‘… ð‘… # 1D445 + 𑆠𑆠# 1D446 + 𑇠𑇠# 1D447 + 𑈠𑈠# 1D448 + 𑉠𑉠# 1D449 + 𑊠𑊠# 1D44A + ð‘‹ ð‘‹ # 1D44B + 𑌠𑌠# 1D44C + ð‘ ð‘ # 1D44D + 𑎠𑎠# 1D44E + ð‘ ð‘ # 1D44F + ð‘ ð‘ # 1D450 + ð‘‘ ð‘‘ # 1D451 + ð‘’ ð‘’ # 1D452 + ð‘“ ð‘“ # 1D453 + ð‘” ð‘” # 1D454 + ð‘– ð‘– # 1D456 + ð‘— ð‘— # 1D457 + 𑘠𑘠# 1D458 + ð‘™ ð‘™ # 1D459 + 𑚠𑚠# 1D45A + ð‘› ð‘› # 1D45B + 𑜠𑜠# 1D45C + ð‘ ð‘ # 1D45D + 𑞠𑞠# 1D45E + 𑟠𑟠# 1D45F + ð‘  ð‘  # 1D460 + ð‘¡ ð‘¡ # 1D461 + ð‘¢ ð‘¢ # 1D462 + ð‘£ ð‘£ # 1D463 + 𑤠𑤠# 1D464 + ð‘¥ ð‘¥ # 1D465 + 𑦠𑦠# 1D466 + ð‘§ ð‘§ # 1D467 + 𑨠𑨠# 1D468 + ð‘© ð‘© # 1D469 + 𑪠𑪠# 1D46A + ð‘« ð‘« # 1D46B + 𑬠𑬠# 1D46C + ð‘­ ð‘­ # 1D46D + ð‘® ð‘® # 1D46E + 𑯠𑯠# 1D46F + ð‘° ð‘° # 1D470 + 𑱠𑱠# 1D471 + 𑲠𑲠# 1D472 + 𑳠𑳠# 1D473 + ð‘´ ð‘´ # 1D474 + 𑵠𑵠# 1D475 + ð‘¶ ð‘¶ # 1D476 + ð‘· ð‘· # 1D477 + 𑸠𑸠# 1D478 + 𑹠𑹠# 1D479 + 𑺠𑺠# 1D47A + ð‘» ð‘» # 1D47B + 𑼠𑼠# 1D47C + 𑽠𑽠# 1D47D + 𑾠𑾠# 1D47E + ð‘¿ ð‘¿ # 1D47F + ð’€ ð’€ # 1D480 + ð’ ð’ # 1D481 + ð’‚ ð’‚ # 1D482 + ð’ƒ ð’ƒ # 1D483 + ð’„ ð’„ # 1D484 + ð’… ð’… # 1D485 + ð’† ð’† # 1D486 + ð’‡ ð’‡ # 1D487 + ð’ˆ ð’ˆ # 1D488 + ð’‰ ð’‰ # 1D489 + ð’Š ð’Š # 1D48A + ð’‹ ð’‹ # 1D48B + 𒌠𒌠# 1D48C + ð’ ð’ # 1D48D + ð’Ž ð’Ž # 1D48E + ð’ ð’ # 1D48F + ð’ ð’ # 1D490 + ð’‘ ð’‘ # 1D491 + ð’’ ð’’ # 1D492 + ð’“ ð’“ # 1D493 + ð’” ð’” # 1D494 + ð’• ð’• # 1D495 + ð’– ð’– # 1D496 + ð’— ð’— # 1D497 + ð’˜ ð’˜ # 1D498 + ð’™ ð’™ # 1D499 + ð’š ð’š # 1D49A + ð’› ð’› # 1D49B + 𒜠𒜠# 1D49C + ð’ž ð’ž # 1D49E + ð’Ÿ ð’Ÿ # 1D49F + ð’¢ ð’¢ # 1D4A2 + ð’¥ ð’¥ # 1D4A5 + ð’¦ ð’¦ # 1D4A6 + ð’© ð’© # 1D4A9 + ð’ª ð’ª # 1D4AA + ð’« ð’« # 1D4AB + ð’¬ ð’¬ # 1D4AC + ð’® ð’® # 1D4AE + ð’¯ ð’¯ # 1D4AF + ð’° ð’° # 1D4B0 + ð’± ð’± # 1D4B1 + ð’² ð’² # 1D4B2 + ð’³ ð’³ # 1D4B3 + ð’´ ð’´ # 1D4B4 + ð’µ ð’µ # 1D4B5 + ð’¶ ð’¶ # 1D4B6 + ð’· ð’· # 1D4B7 + ð’¸ ð’¸ # 1D4B8 + ð’¹ ð’¹ # 1D4B9 + ð’» ð’» # 1D4BB + ð’½ ð’½ # 1D4BD + ð’¾ ð’¾ # 1D4BE + ð’¿ ð’¿ # 1D4BF + ð“€ ð“€ # 1D4C0 + ð“ ð“ # 1D4C1 + ð“‚ ð“‚ # 1D4C2 + 𓃠𓃠# 1D4C3 + ð“… ð“… # 1D4C5 + 𓆠𓆠# 1D4C6 + 𓇠𓇠# 1D4C7 + 𓈠𓈠# 1D4C8 + 𓉠𓉠# 1D4C9 + 𓊠𓊠# 1D4CA + ð“‹ ð“‹ # 1D4CB + 𓌠𓌠# 1D4CC + ð“ ð“ # 1D4CD + 𓎠𓎠# 1D4CE + ð“ ð“ # 1D4CF + ð“ ð“ # 1D4D0 + ð“‘ ð“‘ # 1D4D1 + ð“’ ð“’ # 1D4D2 + ð““ ð““ # 1D4D3 + ð“” ð“” # 1D4D4 + ð“• ð“• # 1D4D5 + ð“– ð“– # 1D4D6 + ð“— ð“— # 1D4D7 + 𓘠𓘠# 1D4D8 + ð“™ ð“™ # 1D4D9 + 𓚠𓚠# 1D4DA + ð“› ð“› # 1D4DB + 𓜠𓜠# 1D4DC + ð“ ð“ # 1D4DD + 𓞠𓞠# 1D4DE + 𓟠𓟠# 1D4DF + ð“  ð“  # 1D4E0 + ð“¡ ð“¡ # 1D4E1 + ð“¢ ð“¢ # 1D4E2 + ð“£ ð“£ # 1D4E3 + 𓤠𓤠# 1D4E4 + ð“¥ ð“¥ # 1D4E5 + 𓦠𓦠# 1D4E6 + ð“§ ð“§ # 1D4E7 + 𓨠𓨠# 1D4E8 + ð“© ð“© # 1D4E9 + 𓪠𓪠# 1D4EA + ð“« ð“« # 1D4EB + 𓬠𓬠# 1D4EC + ð“­ ð“­ # 1D4ED + ð“® ð“® # 1D4EE + 𓯠𓯠# 1D4EF + ð“° ð“° # 1D4F0 + 𓱠𓱠# 1D4F1 + 𓲠𓲠# 1D4F2 + 𓳠𓳠# 1D4F3 + ð“´ ð“´ # 1D4F4 + 𓵠𓵠# 1D4F5 + ð“¶ ð“¶ # 1D4F6 + ð“· ð“· # 1D4F7 + 𓸠𓸠# 1D4F8 + 𓹠𓹠# 1D4F9 + 𓺠𓺠# 1D4FA + ð“» ð“» # 1D4FB + 𓼠𓼠# 1D4FC + 𓽠𓽠# 1D4FD + 𓾠𓾠# 1D4FE + ð“¿ ð“¿ # 1D4FF + 𔀠𔀠# 1D500 + ð” ð” # 1D501 + 𔂠𔂠# 1D502 + 𔃠𔃠# 1D503 + 𔄠𔄠# 1D504 + ð”… ð”… # 1D505 + 𔇠𔇠# 1D507 + 𔈠𔈠# 1D508 + 𔉠𔉠# 1D509 + 𔊠𔊠# 1D50A + ð” ð” # 1D50D + 𔎠𔎠# 1D50E + ð” ð” # 1D50F + ð” ð” # 1D510 + 𔑠𔑠# 1D511 + ð”’ ð”’ # 1D512 + 𔓠𔓠# 1D513 + ð”” ð”” # 1D514 + ð”– ð”– # 1D516 + ð”— ð”— # 1D517 + 𔘠𔘠# 1D518 + ð”™ ð”™ # 1D519 + 𔚠𔚠# 1D51A + ð”› ð”› # 1D51B + 𔜠𔜠# 1D51C + 𔞠𔞠# 1D51E + 𔟠𔟠# 1D51F + ð”  ð”  # 1D520 + 𔡠𔡠# 1D521 + 𔢠𔢠# 1D522 + 𔣠𔣠# 1D523 + 𔤠𔤠# 1D524 + 𔥠𔥠# 1D525 + 𔦠𔦠# 1D526 + ð”§ ð”§ # 1D527 + 𔨠𔨠# 1D528 + 𔩠𔩠# 1D529 + 𔪠𔪠# 1D52A + 𔫠𔫠# 1D52B + 𔬠𔬠# 1D52C + ð”­ ð”­ # 1D52D + ð”® ð”® # 1D52E + 𔯠𔯠# 1D52F + ð”° ð”° # 1D530 + ð”± ð”± # 1D531 + 𔲠𔲠# 1D532 + 𔳠𔳠# 1D533 + ð”´ ð”´ # 1D534 + 𔵠𔵠# 1D535 + ð”¶ ð”¶ # 1D536 + ð”· ð”· # 1D537 + 𔸠𔸠# 1D538 + 𔹠𔹠# 1D539 + ð”» ð”» # 1D53B + 𔼠𔼠# 1D53C + 𔽠𔽠# 1D53D + 𔾠𔾠# 1D53E + ð•€ ð•€ # 1D540 + ð• ð• # 1D541 + ð•‚ ð•‚ # 1D542 + 𕃠𕃠# 1D543 + ð•„ ð•„ # 1D544 + 𕆠𕆠# 1D546 + 𕊠𕊠# 1D54A + ð•‹ ð•‹ # 1D54B + 𕌠𕌠# 1D54C + ð• ð• # 1D54D + 𕎠𕎠# 1D54E + ð• ð• # 1D54F + ð• ð• # 1D550 + ð•’ ð•’ # 1D552 + ð•“ ð•“ # 1D553 + ð•” ð•” # 1D554 + ð•• ð•• # 1D555 + ð•– ð•– # 1D556 + ð•— ð•— # 1D557 + 𕘠𕘠# 1D558 + ð•™ ð•™ # 1D559 + 𕚠𕚠# 1D55A + ð•› ð•› # 1D55B + 𕜠𕜠# 1D55C + ð• ð• # 1D55D + 𕞠𕞠# 1D55E + 𕟠𕟠# 1D55F + ð•  ð•  # 1D560 + ð•¡ ð•¡ # 1D561 + ð•¢ ð•¢ # 1D562 + ð•£ ð•£ # 1D563 + 𕤠𕤠# 1D564 + ð•¥ ð•¥ # 1D565 + 𕦠𕦠# 1D566 + ð•§ ð•§ # 1D567 + 𕨠𕨠# 1D568 + ð•© ð•© # 1D569 + 𕪠𕪠# 1D56A + ð•« ð•« # 1D56B + 𕬠𕬠# 1D56C + ð•­ ð•­ # 1D56D + ð•® ð•® # 1D56E + 𕯠𕯠# 1D56F + ð•° ð•° # 1D570 + 𕱠𕱠# 1D571 + 𕲠𕲠# 1D572 + 𕳠𕳠# 1D573 + ð•´ ð•´ # 1D574 + 𕵠𕵠# 1D575 + ð•¶ ð•¶ # 1D576 + ð•· ð•· # 1D577 + 𕸠𕸠# 1D578 + 𕹠𕹠# 1D579 + 𕺠𕺠# 1D57A + ð•» ð•» # 1D57B + 𕼠𕼠# 1D57C + 𕽠𕽠# 1D57D + 𕾠𕾠# 1D57E + ð•¿ ð•¿ # 1D57F + ð–€ ð–€ # 1D580 + ð– ð– # 1D581 + ð–‚ ð–‚ # 1D582 + ð–ƒ ð–ƒ # 1D583 + ð–„ ð–„ # 1D584 + ð–… ð–… # 1D585 + ð–† ð–† # 1D586 + ð–‡ ð–‡ # 1D587 + ð–ˆ ð–ˆ # 1D588 + ð–‰ ð–‰ # 1D589 + ð–Š ð–Š # 1D58A + ð–‹ ð–‹ # 1D58B + 𖌠𖌠# 1D58C + ð– ð– # 1D58D + ð–Ž ð–Ž # 1D58E + ð– ð– # 1D58F + ð– ð– # 1D590 + ð–‘ ð–‘ # 1D591 + ð–’ ð–’ # 1D592 + ð–“ ð–“ # 1D593 + ð–” ð–” # 1D594 + ð–• ð–• # 1D595 + ð–– ð–– # 1D596 + ð–— ð–— # 1D597 + ð–˜ ð–˜ # 1D598 + ð–™ ð–™ # 1D599 + ð–š ð–š # 1D59A + ð–› ð–› # 1D59B + 𖜠𖜠# 1D59C + ð– ð– # 1D59D + ð–ž ð–ž # 1D59E + ð–Ÿ ð–Ÿ # 1D59F + ð–  ð–  # 1D5A0 + ð–¡ ð–¡ # 1D5A1 + ð–¢ ð–¢ # 1D5A2 + ð–£ ð–£ # 1D5A3 + ð–¤ ð–¤ # 1D5A4 + ð–¥ ð–¥ # 1D5A5 + ð–¦ ð–¦ # 1D5A6 + ð–§ ð–§ # 1D5A7 + ð–¨ ð–¨ # 1D5A8 + ð–© ð–© # 1D5A9 + ð–ª ð–ª # 1D5AA + ð–« ð–« # 1D5AB + ð–¬ ð–¬ # 1D5AC + ð–­ ð–­ # 1D5AD + ð–® ð–® # 1D5AE + ð–¯ ð–¯ # 1D5AF + ð–° ð–° # 1D5B0 + ð–± ð–± # 1D5B1 + ð–² ð–² # 1D5B2 + ð–³ ð–³ # 1D5B3 + ð–´ ð–´ # 1D5B4 + ð–µ ð–µ # 1D5B5 + ð–¶ ð–¶ # 1D5B6 + ð–· ð–· # 1D5B7 + ð–¸ ð–¸ # 1D5B8 + ð–¹ ð–¹ # 1D5B9 + ð–º ð–º # 1D5BA + ð–» ð–» # 1D5BB + ð–¼ ð–¼ # 1D5BC + ð–½ ð–½ # 1D5BD + ð–¾ ð–¾ # 1D5BE + ð–¿ ð–¿ # 1D5BF + ð—€ ð—€ # 1D5C0 + ð— ð— # 1D5C1 + ð—‚ ð—‚ # 1D5C2 + ð—ƒ ð—ƒ # 1D5C3 + ð—„ ð—„ # 1D5C4 + ð—… ð—… # 1D5C5 + ð—† ð—† # 1D5C6 + ð—‡ ð—‡ # 1D5C7 + ð—ˆ ð—ˆ # 1D5C8 + ð—‰ ð—‰ # 1D5C9 + ð—Š ð—Š # 1D5CA + ð—‹ ð—‹ # 1D5CB + 𗌠𗌠# 1D5CC + ð— ð— # 1D5CD + ð—Ž ð—Ž # 1D5CE + ð— ð— # 1D5CF + ð— ð— # 1D5D0 + ð—‘ ð—‘ # 1D5D1 + ð—’ ð—’ # 1D5D2 + ð—“ ð—“ # 1D5D3 + ð—” ð—” # 1D5D4 + ð—• ð—• # 1D5D5 + ð—– ð—– # 1D5D6 + ð—— ð—— # 1D5D7 + ð—˜ ð—˜ # 1D5D8 + ð—™ ð—™ # 1D5D9 + ð—š ð—š # 1D5DA + ð—› ð—› # 1D5DB + 𗜠𗜠# 1D5DC + ð— ð— # 1D5DD + ð—ž ð—ž # 1D5DE + ð—Ÿ ð—Ÿ # 1D5DF + ð—  ð—  # 1D5E0 + ð—¡ ð—¡ # 1D5E1 + ð—¢ ð—¢ # 1D5E2 + ð—£ ð—£ # 1D5E3 + ð—¤ ð—¤ # 1D5E4 + ð—¥ ð—¥ # 1D5E5 + ð—¦ ð—¦ # 1D5E6 + ð—§ ð—§ # 1D5E7 + ð—¨ ð—¨ # 1D5E8 + ð—© ð—© # 1D5E9 + ð—ª ð—ª # 1D5EA + ð—« ð—« # 1D5EB + ð—¬ ð—¬ # 1D5EC + ð—­ ð—­ # 1D5ED + ð—® ð—® # 1D5EE + ð—¯ ð—¯ # 1D5EF + ð—° ð—° # 1D5F0 + ð—± ð—± # 1D5F1 + ð—² ð—² # 1D5F2 + ð—³ ð—³ # 1D5F3 + ð—´ ð—´ # 1D5F4 + ð—µ ð—µ # 1D5F5 + ð—¶ ð—¶ # 1D5F6 + ð—· ð—· # 1D5F7 + ð—¸ ð—¸ # 1D5F8 + ð—¹ ð—¹ # 1D5F9 + ð—º ð—º # 1D5FA + ð—» ð—» # 1D5FB + ð—¼ ð—¼ # 1D5FC + ð—½ ð—½ # 1D5FD + ð—¾ ð—¾ # 1D5FE + ð—¿ ð—¿ # 1D5FF + 𘀠𘀠# 1D600 + ð˜ ð˜ # 1D601 + 𘂠𘂠# 1D602 + 𘃠𘃠# 1D603 + 𘄠𘄠# 1D604 + 𘅠𘅠# 1D605 + 𘆠𘆠# 1D606 + 𘇠𘇠# 1D607 + 𘈠𘈠# 1D608 + 𘉠𘉠# 1D609 + 𘊠𘊠# 1D60A + 𘋠𘋠# 1D60B + 𘌠𘌠# 1D60C + ð˜ ð˜ # 1D60D + 𘎠𘎠# 1D60E + ð˜ ð˜ # 1D60F + ð˜ ð˜ # 1D610 + 𘑠𘑠# 1D611 + 𘒠𘒠# 1D612 + 𘓠𘓠# 1D613 + 𘔠𘔠# 1D614 + 𘕠𘕠# 1D615 + 𘖠𘖠# 1D616 + 𘗠𘗠# 1D617 + 𘘠𘘠# 1D618 + 𘙠𘙠# 1D619 + 𘚠𘚠# 1D61A + 𘛠𘛠# 1D61B + 𘜠𘜠# 1D61C + ð˜ ð˜ # 1D61D + 𘞠𘞠# 1D61E + 𘟠𘟠# 1D61F + 𘠠𘠠# 1D620 + 𘡠𘡠# 1D621 + 𘢠𘢠# 1D622 + 𘣠𘣠# 1D623 + 𘤠𘤠# 1D624 + 𘥠𘥠# 1D625 + 𘦠𘦠# 1D626 + 𘧠𘧠# 1D627 + 𘨠𘨠# 1D628 + 𘩠𘩠# 1D629 + 𘪠𘪠# 1D62A + 𘫠𘫠# 1D62B + 𘬠𘬠# 1D62C + 𘭠𘭠# 1D62D + 𘮠𘮠# 1D62E + 𘯠𘯠# 1D62F + 𘰠𘰠# 1D630 + 𘱠𘱠# 1D631 + 𘲠𘲠# 1D632 + 𘳠𘳠# 1D633 + 𘴠𘴠# 1D634 + 𘵠𘵠# 1D635 + 𘶠𘶠# 1D636 + 𘷠𘷠# 1D637 + 𘸠𘸠# 1D638 + 𘹠𘹠# 1D639 + 𘺠𘺠# 1D63A + 𘻠𘻠# 1D63B + 𘼠𘼠# 1D63C + 𘽠𘽠# 1D63D + 𘾠𘾠# 1D63E + 𘿠𘿠# 1D63F + 𙀠𙀠# 1D640 + ð™ ð™ # 1D641 + 𙂠𙂠# 1D642 + 𙃠𙃠# 1D643 + 𙄠𙄠# 1D644 + ð™… ð™… # 1D645 + 𙆠𙆠# 1D646 + 𙇠𙇠# 1D647 + 𙈠𙈠# 1D648 + 𙉠𙉠# 1D649 + 𙊠𙊠# 1D64A + 𙋠𙋠# 1D64B + 𙌠𙌠# 1D64C + ð™ ð™ # 1D64D + 𙎠𙎠# 1D64E + ð™ ð™ # 1D64F + ð™ ð™ # 1D650 + 𙑠𙑠# 1D651 + ð™’ ð™’ # 1D652 + 𙓠𙓠# 1D653 + ð™” ð™” # 1D654 + 𙕠𙕠# 1D655 + ð™– ð™– # 1D656 + ð™— ð™— # 1D657 + 𙘠𙘠# 1D658 + ð™™ ð™™ # 1D659 + 𙚠𙚠# 1D65A + ð™› ð™› # 1D65B + 𙜠𙜠# 1D65C + ð™ ð™ # 1D65D + 𙞠𙞠# 1D65E + 𙟠𙟠# 1D65F + ð™  ð™  # 1D660 + 𙡠𙡠# 1D661 + 𙢠𙢠# 1D662 + 𙣠𙣠# 1D663 + 𙤠𙤠# 1D664 + 𙥠𙥠# 1D665 + 𙦠𙦠# 1D666 + ð™§ ð™§ # 1D667 + 𙨠𙨠# 1D668 + 𙩠𙩠# 1D669 + 𙪠𙪠# 1D66A + 𙫠𙫠# 1D66B + 𙬠𙬠# 1D66C + ð™­ ð™­ # 1D66D + ð™® ð™® # 1D66E + 𙯠𙯠# 1D66F + ð™° ð™° # 1D670 + ð™± ð™± # 1D671 + 𙲠𙲠# 1D672 + 𙳠𙳠# 1D673 + ð™´ ð™´ # 1D674 + 𙵠𙵠# 1D675 + ð™¶ ð™¶ # 1D676 + ð™· ð™· # 1D677 + 𙸠𙸠# 1D678 + 𙹠𙹠# 1D679 + 𙺠𙺠# 1D67A + ð™» ð™» # 1D67B + 𙼠𙼠# 1D67C + 𙽠𙽠# 1D67D + 𙾠𙾠# 1D67E + 𙿠𙿠# 1D67F + 𚀠𚀠# 1D680 + ðš ðš # 1D681 + ðš‚ ðš‚ # 1D682 + 𚃠𚃠# 1D683 + ðš„ ðš„ # 1D684 + ðš… ðš… # 1D685 + 𚆠𚆠# 1D686 + 𚇠𚇠# 1D687 + 𚈠𚈠# 1D688 + 𚉠𚉠# 1D689 + 𚊠𚊠# 1D68A + ðš‹ ðš‹ # 1D68B + 𚌠𚌠# 1D68C + ðš ðš # 1D68D + 𚎠𚎠# 1D68E + ðš ðš # 1D68F + ðš ðš # 1D690 + ðš‘ ðš‘ # 1D691 + ðš’ ðš’ # 1D692 + ðš“ ðš“ # 1D693 + ðš” ðš” # 1D694 + ðš• ðš• # 1D695 + ðš– ðš– # 1D696 + ðš— ðš— # 1D697 + 𚘠𚘠# 1D698 + ðš™ ðš™ # 1D699 + ðšš ðšš # 1D69A + ðš› ðš› # 1D69B + 𚜠𚜠# 1D69C + ðš ðš # 1D69D + ðšž ðšž # 1D69E + 𚟠𚟠# 1D69F + ðš  ðš  # 1D6A0 + ðš¡ ðš¡ # 1D6A1 + 𚢠𚢠# 1D6A2 + 𚣠𚣠# 1D6A3 + 𚤠𚤠# 1D6A4 + 𚥠𚥠# 1D6A5 + 𚨠𚨠# 1D6A8 + ðš© ðš© # 1D6A9 + 𚪠𚪠# 1D6AA + ðš« ðš« # 1D6AB + 𚬠𚬠# 1D6AC + ðš­ ðš­ # 1D6AD + ðš® ðš® # 1D6AE + 𚯠𚯠# 1D6AF + ðš° ðš° # 1D6B0 + ðš± ðš± # 1D6B1 + ðš² ðš² # 1D6B2 + ðš³ ðš³ # 1D6B3 + ðš´ ðš´ # 1D6B4 + ðšµ ðšµ # 1D6B5 + ðš¶ ðš¶ # 1D6B6 + ðš· ðš· # 1D6B7 + 𚸠𚸠# 1D6B8 + ðš¹ ðš¹ # 1D6B9 + 𚺠𚺠# 1D6BA + ðš» ðš» # 1D6BB + ðš¼ ðš¼ # 1D6BC + ðš½ ðš½ # 1D6BD + ðš¾ ðš¾ # 1D6BE + ðš¿ ðš¿ # 1D6BF + 𛀠𛀠# 1D6C0 + 𛂠𛂠# 1D6C2 + 𛃠𛃠# 1D6C3 + 𛄠𛄠# 1D6C4 + ð›… ð›… # 1D6C5 + 𛆠𛆠# 1D6C6 + 𛇠𛇠# 1D6C7 + 𛈠𛈠# 1D6C8 + 𛉠𛉠# 1D6C9 + 𛊠𛊠# 1D6CA + 𛋠𛋠# 1D6CB + 𛌠𛌠# 1D6CC + ð› ð› # 1D6CD + 𛎠𛎠# 1D6CE + ð› ð› # 1D6CF + ð› ð› # 1D6D0 + 𛑠𛑠# 1D6D1 + ð›’ ð›’ # 1D6D2 + 𛓠𛓠# 1D6D3 + ð›” ð›” # 1D6D4 + 𛕠𛕠# 1D6D5 + ð›– ð›– # 1D6D6 + ð›— ð›— # 1D6D7 + 𛘠𛘠# 1D6D8 + ð›™ ð›™ # 1D6D9 + 𛚠𛚠# 1D6DA + 𛜠𛜠# 1D6DC + ð› ð› # 1D6DD + 𛞠𛞠# 1D6DE + 𛟠𛟠# 1D6DF + ð›  ð›  # 1D6E0 + 𛡠𛡠# 1D6E1 + 𛢠𛢠# 1D6E2 + 𛣠𛣠# 1D6E3 + 𛤠𛤠# 1D6E4 + 𛥠𛥠# 1D6E5 + 𛦠𛦠# 1D6E6 + ð›§ ð›§ # 1D6E7 + 𛨠𛨠# 1D6E8 + 𛩠𛩠# 1D6E9 + 𛪠𛪠# 1D6EA + 𛫠𛫠# 1D6EB + 𛬠𛬠# 1D6EC + ð›­ ð›­ # 1D6ED + ð›® ð›® # 1D6EE + 𛯠𛯠# 1D6EF + ð›° ð›° # 1D6F0 + ð›± ð›± # 1D6F1 + 𛲠𛲠# 1D6F2 + 𛳠𛳠# 1D6F3 + ð›´ ð›´ # 1D6F4 + 𛵠𛵠# 1D6F5 + ð›¶ ð›¶ # 1D6F6 + ð›· ð›· # 1D6F7 + 𛸠𛸠# 1D6F8 + 𛹠𛹠# 1D6F9 + 𛺠𛺠# 1D6FA + 𛼠𛼠# 1D6FC + 𛽠𛽠# 1D6FD + 𛾠𛾠# 1D6FE + 𛿠𛿠# 1D6FF + 𜀠𜀠# 1D700 + ðœ ðœ # 1D701 + 𜂠𜂠# 1D702 + 𜃠𜃠# 1D703 + 𜄠𜄠# 1D704 + 𜅠𜅠# 1D705 + 𜆠𜆠# 1D706 + 𜇠𜇠# 1D707 + 𜈠𜈠# 1D708 + 𜉠𜉠# 1D709 + 𜊠𜊠# 1D70A + 𜋠𜋠# 1D70B + 𜌠𜌠# 1D70C + ðœ ðœ # 1D70D + 𜎠𜎠# 1D70E + ðœ ðœ # 1D70F + ðœ ðœ # 1D710 + 𜑠𜑠# 1D711 + 𜒠𜒠# 1D712 + 𜓠𜓠# 1D713 + 𜔠𜔠# 1D714 + 𜖠𜖠# 1D716 + 𜗠𜗠# 1D717 + 𜘠𜘠# 1D718 + 𜙠𜙠# 1D719 + 𜚠𜚠# 1D71A + 𜛠𜛠# 1D71B + 𜜠𜜠# 1D71C + ðœ ðœ # 1D71D + 𜞠𜞠# 1D71E + 𜟠𜟠# 1D71F + 𜠠𜠠# 1D720 + 𜡠𜡠# 1D721 + 𜢠𜢠# 1D722 + 𜣠𜣠# 1D723 + 𜤠𜤠# 1D724 + 𜥠𜥠# 1D725 + 𜦠𜦠# 1D726 + 𜧠𜧠# 1D727 + 𜨠𜨠# 1D728 + 𜩠𜩠# 1D729 + 𜪠𜪠# 1D72A + 𜫠𜫠# 1D72B + 𜬠𜬠# 1D72C + 𜭠𜭠# 1D72D + 𜮠𜮠# 1D72E + 𜯠𜯠# 1D72F + 𜰠𜰠# 1D730 + 𜱠𜱠# 1D731 + 𜲠𜲠# 1D732 + 𜳠𜳠# 1D733 + 𜴠𜴠# 1D734 + 𜶠𜶠# 1D736 + 𜷠𜷠# 1D737 + 𜸠𜸠# 1D738 + 𜹠𜹠# 1D739 + 𜺠𜺠# 1D73A + 𜻠𜻠# 1D73B + 𜼠𜼠# 1D73C + 𜽠𜽠# 1D73D + 𜾠𜾠# 1D73E + 𜿠𜿠# 1D73F + ð€ ð€ # 1D740 + ð ð # 1D741 + ð‚ ð‚ # 1D742 + ðƒ ðƒ # 1D743 + ð„ ð„ # 1D744 + ð… ð… # 1D745 + ð† ð† # 1D746 + ð‡ ð‡ # 1D747 + ðˆ ðˆ # 1D748 + ð‰ ð‰ # 1D749 + ðŠ ðŠ # 1D74A + ð‹ ð‹ # 1D74B + ðŒ ðŒ # 1D74C + ð ð # 1D74D + ðŽ ðŽ # 1D74E + ð ð # 1D750 + ð‘ ð‘ # 1D751 + ð’ ð’ # 1D752 + ð“ ð“ # 1D753 + ð” ð” # 1D754 + ð• ð• # 1D755 + ð– ð– # 1D756 + ð— ð— # 1D757 + ð˜ ð˜ # 1D758 + ð™ ð™ # 1D759 + ðš ðš # 1D75A + ð› ð› # 1D75B + ðœ ðœ # 1D75C + ð ð # 1D75D + ðž ðž # 1D75E + ðŸ ðŸ # 1D75F + ð  ð  # 1D760 + ð¡ ð¡ # 1D761 + ð¢ ð¢ # 1D762 + ð£ ð£ # 1D763 + ð¤ ð¤ # 1D764 + ð¥ ð¥ # 1D765 + ð¦ ð¦ # 1D766 + ð§ ð§ # 1D767 + ð¨ ð¨ # 1D768 + ð© ð© # 1D769 + ðª ðª # 1D76A + ð« ð« # 1D76B + ð¬ ð¬ # 1D76C + ð­ ð­ # 1D76D + ð® ð® # 1D76E + ð° ð° # 1D770 + ð± ð± # 1D771 + ð² ð² # 1D772 + ð³ ð³ # 1D773 + ð´ ð´ # 1D774 + ðµ ðµ # 1D775 + ð¶ ð¶ # 1D776 + ð· ð· # 1D777 + ð¸ ð¸ # 1D778 + ð¹ ð¹ # 1D779 + ðº ðº # 1D77A + ð» ð» # 1D77B + ð¼ ð¼ # 1D77C + ð½ ð½ # 1D77D + ð¾ ð¾ # 1D77E + ð¿ ð¿ # 1D77F + 𞀠𞀠# 1D780 + ðž ðž # 1D781 + ðž‚ ðž‚ # 1D782 + 𞃠𞃠# 1D783 + ðž„ ðž„ # 1D784 + ðž… ðž… # 1D785 + 𞆠𞆠# 1D786 + 𞇠𞇠# 1D787 + 𞈠𞈠# 1D788 + 𞊠𞊠# 1D78A + ðž‹ ðž‹ # 1D78B + 𞌠𞌠# 1D78C + ðž ðž # 1D78D + 𞎠𞎠# 1D78E + ðž ðž # 1D78F + ðž ðž # 1D790 + ðž‘ ðž‘ # 1D791 + ðž’ ðž’ # 1D792 + ðž“ ðž“ # 1D793 + ðž” ðž” # 1D794 + ðž• ðž• # 1D795 + ðž– ðž– # 1D796 + ðž— ðž— # 1D797 + 𞘠𞘠# 1D798 + ðž™ ðž™ # 1D799 + ðžš ðžš # 1D79A + ðž› ðž› # 1D79B + 𞜠𞜠# 1D79C + ðž ðž # 1D79D + ðžž ðžž # 1D79E + 𞟠𞟠# 1D79F + ðž  ðž  # 1D7A0 + ðž¡ ðž¡ # 1D7A1 + 𞢠𞢠# 1D7A2 + 𞣠𞣠# 1D7A3 + 𞤠𞤠# 1D7A4 + 𞥠𞥠# 1D7A5 + 𞦠𞦠# 1D7A6 + ðž§ ðž§ # 1D7A7 + 𞨠𞨠# 1D7A8 + 𞪠𞪠# 1D7AA + ðž« ðž« # 1D7AB + 𞬠𞬠# 1D7AC + ðž­ ðž­ # 1D7AD + ðž® ðž® # 1D7AE + 𞯠𞯠# 1D7AF + ðž° ðž° # 1D7B0 + ðž± ðž± # 1D7B1 + ðž² ðž² # 1D7B2 + ðž³ ðž³ # 1D7B3 + ðž´ ðž´ # 1D7B4 + ðžµ ðžµ # 1D7B5 + ðž¶ ðž¶ # 1D7B6 + ðž· ðž· # 1D7B7 + 𞸠𞸠# 1D7B8 + ðž¹ ðž¹ # 1D7B9 + 𞺠𞺠# 1D7BA + ðž» ðž» # 1D7BB + ðž¼ ðž¼ # 1D7BC + ðž½ ðž½ # 1D7BD + ðž¾ ðž¾ # 1D7BE + ðž¿ ðž¿ # 1D7BF + 🀠🀠# 1D7C0 + ðŸ ðŸ # 1D7C1 + 🂠🂠# 1D7C2 + 🄠🄠# 1D7C4 + 🅠🅠# 1D7C5 + 🆠🆠# 1D7C6 + 🇠🇠# 1D7C7 + 🈠🈠# 1D7C8 + 🉠🉠# 1D7C9 + 🊠🊠# 1D7CA + 🋠🋠# 1D7CB + 𞤀 𞤢 𞤀 # 1E900 + 𞤠𞤣 𞤠# 1E901 + 𞤂 𞤤 𞤂 # 1E902 + 𞤃 𞤥 𞤃 # 1E903 + 𞤄 𞤦 𞤄 # 1E904 + 𞤅 𞤧 𞤅 # 1E905 + 𞤆 𞤨 𞤆 # 1E906 + 𞤇 𞤩 𞤇 # 1E907 + 𞤈 𞤪 𞤈 # 1E908 + 𞤉 𞤫 𞤉 # 1E909 + 𞤊 𞤬 𞤊 # 1E90A + 𞤋 𞤭 𞤋 # 1E90B + 𞤌 𞤮 𞤌 # 1E90C + 𞤠𞤯 𞤠# 1E90D + 𞤎 𞤰 𞤎 # 1E90E + 𞤠𞤱 𞤠# 1E90F + 𞤠𞤲 𞤠# 1E910 + 𞤑 𞤳 𞤑 # 1E911 + 𞤒 𞤴 𞤒 # 1E912 + 𞤓 𞤵 𞤓 # 1E913 + 𞤔 𞤶 𞤔 # 1E914 + 𞤕 𞤷 𞤕 # 1E915 + 𞤖 𞤸 𞤖 # 1E916 + 𞤗 𞤹 𞤗 # 1E917 + 𞤘 𞤺 𞤘 # 1E918 + 𞤙 𞤻 𞤙 # 1E919 + 𞤚 𞤼 𞤚 # 1E91A + 𞤛 𞤽 𞤛 # 1E91B + 𞤜 𞤾 𞤜 # 1E91C + 𞤠𞤿 𞤠# 1E91D + 𞤞 𞥀 𞤞 # 1E91E + 𞤟 𞥠𞤟 # 1E91F + 𞤠 𞥂 𞤠 # 1E920 + 𞤡 𞥃 𞤡 # 1E921 + 𞤢 𞤢 𞤀 𞤀 # 1E922 + 𞤣 𞤣 𞤠𞤠# 1E923 + 𞤤 𞤤 𞤂 𞤂 # 1E924 + 𞤥 𞤥 𞤃 𞤃 # 1E925 + 𞤦 𞤦 𞤄 𞤄 # 1E926 + 𞤧 𞤧 𞤅 𞤅 # 1E927 + 𞤨 𞤨 𞤆 𞤆 # 1E928 + 𞤩 𞤩 𞤇 𞤇 # 1E929 + 𞤪 𞤪 𞤈 𞤈 # 1E92A + 𞤫 𞤫 𞤉 𞤉 # 1E92B + 𞤬 𞤬 𞤊 𞤊 # 1E92C + 𞤭 𞤭 𞤋 𞤋 # 1E92D + 𞤮 𞤮 𞤌 𞤌 # 1E92E + 𞤯 𞤯 𞤠𞤠# 1E92F + 𞤰 𞤰 𞤎 𞤎 # 1E930 + 𞤱 𞤱 𞤠𞤠# 1E931 + 𞤲 𞤲 𞤠𞤠# 1E932 + 𞤳 𞤳 𞤑 𞤑 # 1E933 + 𞤴 𞤴 𞤒 𞤒 # 1E934 + 𞤵 𞤵 𞤓 𞤓 # 1E935 + 𞤶 𞤶 𞤔 𞤔 # 1E936 + 𞤷 𞤷 𞤕 𞤕 # 1E937 + 𞤸 𞤸 𞤖 𞤖 # 1E938 + 𞤹 𞤹 𞤗 𞤗 # 1E939 + 𞤺 𞤺 𞤘 𞤘 # 1E93A + 𞤻 𞤻 𞤙 𞤙 # 1E93B + 𞤼 𞤼 𞤚 𞤚 # 1E93C + 𞤽 𞤽 𞤛 𞤛 # 1E93D + 𞤾 𞤾 𞤜 𞤜 # 1E93E + 𞤿 𞤿 𞤠𞤠# 1E93F + 𞥀 𞥀 𞤞 𞤞 # 1E940 + 𞥠𞥠𞤟 𞤟 # 1E941 + 𞥂 𞥂 𞤠 𞤠 # 1E942 + 𞥃 𞥃 𞤡 𞤡 # 1E943 diff --git a/glib/tests/charset.c b/glib/tests/charset.c new file mode 100644 index 0000000..53f12ec --- /dev/null +++ b/glib/tests/charset.c @@ -0,0 +1,83 @@ +/* + * Copyright 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +#include "glib.h" + +#define TEST_LOCALE "fr_FR.UTF-8@latin:en_US.UTF-8" + +const gchar *TEST_RESULT[] = { + "fr_FR.UTF-8@latin", + "fr_FR@latin", + "fr.UTF-8@latin", + "fr@latin", + "fr_FR.UTF-8", + "fr_FR", + "fr.UTF-8", + "fr", + "en_US.UTF-8", + "en_US", + "en.UTF-8", + "en", + "C", + NULL +}; + +const gchar *TEST_TABLE[] = { + "LANGUAGE", + "LC_ALL", + "LC_CTYPE", + "LANG", + NULL +}; + +static void +test_language_names_with_category (void) +{ + const gchar * const *language_names = NULL; + gsize i, j; + + for (i = 0; TEST_TABLE[i]; ++i) + { + g_test_message ("Test %" G_GSIZE_FORMAT, i); + g_assert_true (g_setenv (TEST_TABLE[i], TEST_LOCALE, TRUE)); + language_names = g_get_language_names_with_category ("LC_CTYPE"); + g_assert_cmpuint (g_strv_length ((gchar **)language_names), ==, g_strv_length ((gchar **)TEST_RESULT)); + + for (j = 0; language_names[j]; ++j) + { + g_assert_cmpstr (language_names[j], ==, TEST_RESULT[j]); + } + g_unsetenv (TEST_TABLE[i]); + } +} + +static void +test_language_names_with_category_async (void) +{ + g_thread_join (g_thread_new ( + NULL, (GThreadFunc)g_get_language_names_with_category, "LC_CTYPE")); + + /* g_get_language_names_with_category returns a pointer to a memory + which is owned by a thread it has been called from. The thread is dead now, + therefore returned pointer can't be used at this stage. + */ +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/charset/language_names_with_category", test_language_names_with_category); + g_test_add_func ("/charset/language_names_with_category_async", test_language_names_with_category_async); + + return g_test_run (); +} diff --git a/glib/tests/checksum.c b/glib/tests/checksum.c new file mode 100644 index 0000000..cc78d11 --- /dev/null +++ b/glib/tests/checksum.c @@ -0,0 +1,1213 @@ +#include +#include +#include + +/* Test GChecksum by computing the checksums of every initial + * substring of this string, calling g_checksum_update with chunks of + * every possible size. That is, first it computes the checksums of + * "", then "T". Then it computes the checksums of "Th", first by + * feeding the GChecksum 1 letter a time, then 2. Then it does "The", + * first feeding it one letter at a time, then 2, then 3. Etc. + * + * MD5, SHA1, and SHA256 all use a 64-byte buffer internally; this + * string is intentionally more than twice that length. + */ + +static const char FIXED_STR[] = "The quick brown fox jumps over the lazy dog. Jackdaws love my big sphinx of quartz. Pack my box with five dozen liquor jugs. How razorback-jumping frogs can level six piqued gymnasts!"; +#define FIXED_LEN (strlen (FIXED_STR)) + +const char *MD5_sums[] = { + "d41d8cd98f00b204e9800998ecf8427e", + "b9ece18c950afbfa6b0fdbfa4ff731d3", + "eeeb9a8eb45dd351d9ec0eb4acce66ce", + "a4704fd35f0308287f2937ba3eccf5fe", + "02edd93949f6d3c57d9822691b59f649", + "6131a51747610d0ae4e86c3a3416788c", + "8c871099d54c09d4099fa7a0e77c9113", + "bbb9873bad399cd1cc0d5e336ca5beee", + "b9b926544b8ecd5c3ef553a87170b726", + "912d57cea222bc1730dd531b9d6afbb6", + "03c729679ca3252a4735c4148b7c11e3", + "d7027ce01f22eb9d2bb32d9a153a7e29", + "e05e6a516c92259691cf9194dfdeff92", + "dd1ac3c70b6f51dd545cdf64053209d4", + "caa1e1e79c65480a48cf08a38ac1d87d", + "5aa207e85988921b8733912c4f526c80", + "b0e45b65d9e1d88169c40dc47605e2d9", + "e4b6d6fabe9dfcbe83a51d19df5f0ac3", + "168534eca593b6cef86aea9081f0f5bf", + "a2004f37730b9445670a738fa0fc9ee5", + "c4314972a672ded8759cafdca9af3238", + "29dcbbf4add427ccba06d3c37ad44aa9", + "d0312d0e9e2d8c063d95a06fbbba9cb1", + "770fd972e360cb8538ce6a880741936e", + "8e53cb84ef3d981a86fbb69b24827c46", + "83de97cab1f553eb3acc22866a4f6942", + "a2829f93d701f36d808d0a698dcebf02", + "efcead92aba26426db84b75413f17c10", + "60a0732774106c2348eb576596668eb9", + "d44f138aa2f39488c03391771eea258c", + "f85199fa76594dfb190fab5dfe42a769", + "cd4c02f190df2372cb703994dd84e881", + "566cb723d4fb7a7dd38163532fe760b7", + "4433001bd59da157c18b09f6c10d4163", + "b76b517e01f5b708af50af906adb2dac", + "0f611396bcfe9ab7666c45ebd37e59ba", + "4c6606c2117565959048d356c1d7f6cc", + "5f7f3f510b8a8f0a5e1d6193c6c7f3af", + "542560ce828579cfe777aa165b4d1bed", + "171e092149d366acca00d1cd783e61cd", + "4ed8b5a69f7c329f498320947db666f2", + "eb4c251a5abb3c59d306276ba2dc644d", + "2b6e07526e77047d7935681efc3b9f90", + "9e107d9d372bb6826bd81d3542a419d6", + "e4d909c290d0fb1ca068ffaddf22cbd0", + "1c6d98786bea70b9c34ce7f33201120c", + "bdda04a65a37f97d3ac3be6b0d5f58ea", + "954c69b280f0b5eed4b36eb714d26f82", + "e5fad54e00d29bf5b1671b3d351624e9", + "1a0b3d4eec1bd869af85945f60ff19c3", + "055031167bd9f17448623653eb4b27ed", + "4ca7c851615ea3abc43b5e1df410b84a", + "774873408e0032f8c56106dc28d489e2", + "fc44cc8ad9ff4aef8a4187688cb65378", + "b939f1b04b296ac8ff8261876ae86704", + "de9362af59e6e23688a243f909e9fdbd", + "6827a93d7492d3da381d7b45f2a0b94f", + "459ade91c05ca5f8bfdc8c3f6014ce04", + "55b143ec7d943b04666010e165d753e0", + "04ad29c207b52f46fd50f208744d936d", + "8d26f6529919e3d3e33b5e147e96bd8c", + "de98a267f5acd95c52bf439be075f360", + "4a8a2b0f0cc485c957992c6c9865b33d", + "566f00c9d7ac74a1daeb2925de2aca23", + "6ebee39c52840729c65d815fbdb9e9c7", + "7dc322a68ec5881e78cb718a3ca9a557", + "b00112c2c7844e0c6c0cab1fdc7a12ab", + "6f78ec779e96448daa9675bf06a0dbe3", + "8bba94005e06aefd071ed8a5c1b89068", + "220316718ce3875281be580a731ef0a1", + "7dd175908a4fce0e510287a9f884ef1d", + "030d864e63a6b67e11084f27ac5a422f", + "cad084c9d6c71aa60c414b3df22e4ef2", + "a10296630814335017df32f94b5202ff", + "de23bdf63d07cc75716e1e303df0677c", + "9718898182f2ba3a4428d9e357f5788e", + "9dfc12c4b82dcf727fc6599a0696a48c", + "6cca243870d308ffe8ae51993258e9ef", + "6b425096ac7743989c9744ff45ea027f", + "742a87784ffd6e2b0697aabf6b453309", + "b9b7f74d898d1fe768777bd7fb7844e7", + "4717614d82c1df37d608111953c75912", + "43298b7db8498f89b9aa1bcb410a8ed2", + "1b3621f615f0861d672d406257f5a97b", + "9ef3e55a2eb9d5d41f9f850cc86f8fea", + "3ec2cbcec99a048d9410c64a61796b0f", + "e75f9f48ac684c1c49a256df39ac118b", + "3518518b7b3b87f298d0518ccab65534", + "d936105bf33a89e00fe8ed8711b732d3", + "70858151e61f8862decb044c2050ae40", + "81491684aa39d20b064ceff099a3175b", + "bd73078b5a0a3a6d40fb1376347d64a6", + "9da1f6dc1bc2ffb5ccafa14a04ff5f84", + "a5c9c51a8981234ef59a969e3ad147ef", + "c105573b4d5ef469c7867094b4e589e1", + "d479c97efb06a112534196e257192c4a", + "fc7b07eb35cc515c1beb93aaa4e51a64", + "83470666e83e382a35d97f406f79eb70", + "e2ecf716fa93c1e1764a8e584cbffe04", + "534a7c131ee92bd5c9105cd293a9fa6e", + "5afea20e81c95d55e70bb0805158d207", + "8bb0ebc08bd51a0f62808c76005d5d33", + "c689312f4c99858ba414b63b61408f7b", + "cf1636f7d96fae80a428db4dbd93450d", + "963b816a27e6432c8200f35c11cb3d18", + "2dcd8661e650a8efe99642df35e1c0a4", + "2f6207c7ae99db3da286ebdb98b10f60", + "b515b746e01836e24966ff679f9dde6b", + "5b53b6ca7982077b891b03ae9546984d", + "4c57e9d52f8e782b44304f2d4613456d", + "7f28eb1a0f03dd38c73da46973299d00", + "997d1c07005040126addd2dbecc623fc", + "817dbe3e415b05eca731e27ca792adbc", + "ebffcb6fd54cfc146afe9485884b540e", + "2d6394332758bd5411eada08d85af3d6", + "27e0d08eda3a775290e0962483fa5ec8", + "d444cd632037609ccb972ce79009b16e", + "31c0453b13e1dd83f6ea55b7be54da15", + "aa95999a313b3794d7902a751ee77c05", + "cd30f6386d09f62f49537b2d23ea713e", + "149a308e31876049d76b7393512451d6", + "d0d4a7c2254d9f8c18668c103a3d7f82", + "1f822faa98bc97d382fb28019730daf3", + "a59e31843f29f63c8ec857084fd91161", + "e871798ecb332a9a082ab69d747c624d", + "dba105cfd9294cbc4269096d9c682b89", + "c9cbdc59fb3afff3051b33788d1e946a", + "890247b165402b325ac88212b21e4e42", + "777c5b13c598663f136be27451b5379a", + "888e851163704b4fed2d9b82e51aff16", + "3069f2cddd3a17dd655c61372def9c0d", + "39ae3b6ae2e9ecf5f0c25eff8d52ddef", + "058dcd07dc12be85774e7f72587bfe43", + "522c5460f239de773cdbcefb4d55b129", + "c6b5babfeaae6d7bb86c1c2b64fa1b56", + "fffa674d8c9bcb251c0ab3cf9d7aec89", + "7aabad234a1f9f05ef6c5fb6ddc15b0a", + "9b3ca93cfa10b081de65516d67170e3b", + "1990bf44ba11b087af262e017d8c823e", + "072e4bc6ef0ee5d9e7c56dafb9f65088", + "e2825a9231a65676a7b79b648fd94fcb", + "ab864a28e6eac29000429a5536fd9cf9", + "decfbab07f8d11187365c385f12d038b", + "1f0dd358531e06187d33964d0e0e115f", + "acdf4cc64f0c62013621d6ebc69687d2", + "6827965643e24616e892e5636f1265c9", + "2daed5786790d38ede194d351b383d46", + "eb05cb49a9e01e2c0a1329c2d1859394", + "83065746806dbca73e787939d359e74c", + "0a318bc9d7e2d4d03a96e755fd2214f6", + "85421302d14c37029512ab3e848c4498", + "02ee794a181044b80588bd14f76ea4dd", + "abeca493fed89cd65ed112e069a695c1", + "e5828e0a11268c9baaaac24bd46d1e15", + "e0a8b89702312967460ad9940aa108d5", + "6e5c8f2aacd19e70d15be253369cdfc4", + "eabc6ce71e74b5b48150ceda5a916948", + "5c263ad8e8dc1fd66e9b35daf7f74c48", + "030b2b56e20c53b75191369104b9509a", + "1225f4418731a8e7944d1366efd89234", + "9085ba0fe1c64c3dce45708de32c3440", + "49efb746a4938e7da19ecb3bb2c8e1d3", + "833095be66f1f7b5942a817846c97ed5", + "28f9f64eba29e57a7bd4bc0840aedf90", + "9b5984b93bd951a70dea62942634c009", + "ddb73667065d5ab761612be590e339e5", + "59c4b46e73c2679610b7a4e9b3a04bc1", + "fcc2a983de8f0ebb193864e0c60a00a6", + "af8f1f4bb88555d688508eb9f3c876ac", + "814e087171d6a45ac4fb4a110e889a38", + "733130f693a1c3a24703052717330807", + "b319f375927ed3f197a26c1112df86ae", + "ace1c7e7c2ffcfe31a042d2b9ae00905", + "5231c151c22b31180e900647fd5097ed", + "07e7238f4f3d8b3a279a2d9f78fa8b08", + "208b1f437aac92a96eef5ec9ca5d53da", + "3a675752c5faa15bd61c63499684c570", + "efa1debf8fb84e142c83c0dcf221d247", + "d940ea701a781a4ff62a99d831c2286a", + "d88294e690a6375d22b12fcc88bebb56", + "f209ebcae30e147ccd9e42d32cfe33b4", + "fbf1e18620fe5a9c40a65cbbd50af177", + "4e682a50db552d15bfe109a1147f6770", + "407b72260377f77f8e63e13dc09bda2c" +}; + +const char *SHA1_sums[] = { + "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "c2c53d66948214258a26ca9ca845d7ac0c17f8e7", + "6929e765f6bd128088cdf81ba4805d3a84da4e5e", + "93ef0dd827103681fcee453b78be2ff14e1a261d", + "9f7ed32a201bab6d11f7be88b9335973d93de3f5", + "a2b847dd0e90bca83b418103baa63c67c85b5a30", + "ee4801c9d009963ac6dda49b100f0d9a9f3983b2", + "0dab89aa7606af6df94d1c3f8872ca98440ce299", + "2eb3456b1b4fb96df1309eff21b02814663f939a", + "30b59bc6c7c1622283a23950f2984bc5cd4fdd51", + "4d39faadbf264f3fb59268228994276c36fc3172", + "8312b76dd9300bcbbd9c5148461949f31f593bdc", + "0d12bfd71a11c686cf53adaacf0bec05c557e768", + "ca150c0c3372de80daa720b7d4081022b7befbe4", + "d2ac2275af550efdde0aca4713835f3480498387", + "07bb8c8ec36e16d57141fbf95fb8478a668b451f", + "6ad802395de4400a9892c9f65868879bee5d1bf6", + "569c7018c812f0cc51c093dbc026baebaab1eb22", + "b8cfd76b506e7aaeb55c3d4e73e8868df8c4dfb1", + "c519c1a06cdbeb2bc499e22137fb48683858b345", + "3e3436a073e72c5300cdca6ce5c321e49dfc412e", + "e2b72fb64787db45dc11bca1f194bef40b5be347", + "52f4aaab2d5f9bc918700c517253e5bd6981ba95", + "001233b5471e0bfa33f8133cf3cc3b97351033a5", + "b2cc1f24e2599121adf86c5161dfe43fd5486985", + "743e27565bb39d4cf6cdf7b19450f94ef12b2206", + "6b57e81439c46aca165e5eacd44c0829670c9bb5", + "4bbe681b61206e8689fce488662e7be67053ad03", + "332ffb34a55ebf0b01beb604bca729887fd4c047", + "b09b432ae19ca6971bb28a3705c9be3b02ec388f", + "051605798e587fd98b428b88077d015494978bda", + "33d579648c883c1b3a2ba91b7d4efd79d2d04e65", + "d035de80a23137cd473991fea53b6b1b1f22e57d", + "4ed82184201c1063c9f89d83b01d277e2db0847c", + "1477d62ad76e1d543380ce2f4253a701fe039af2", + "df72568859f54940e93ba5ace28430d38e4ab10f", + "65ebceacd76a51d7076728d8ecbfcb1a4014fe3d", + "0f5f0f1c642e616224d356a835ed3d054935608a", + "caa9daf50b65b3739eb9a88547c516d89b72ac11", + "1e9c81970164a681a35993d773e1d55d328ed64b", + "8aefdcfcbaa21522fb39162d7507492e47b30f25", + "a374c23022eea446300e1b3303272bdb8f6cfab3", + "f2f38c31109f8a9421f301e9d554193bc4274a32", + "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", + "408d94384216f890ff7a0c3528e8bed1e0b01621", + "22b759d30862cc7c7eb3ce9616a9d4e853b1e14d", + "97e2821bba8dbd62f7823b7ecf095dad5d152371", + "190c9e3674d72f3abfa027a38a425de21ea124a5", + "8a9f1acbeb7dea1bdb61c0e5885043caa84c3812", + "8431fa593176872aea33d2ece77fff42f22c409b", + "08efef7adec17bd8d97f24cc373bfeab4b602d7a", + "669f7e46d635f02a355635d9a09bf3bf2936bcf8", + "695ed476d76f489707db6862a6411973d0207558", + "084ef870fa0d4674d8488040a3d147235cfcb50d", + "2a7d533528fcdaa6795ece88ab526b3e077f4f52", + "4546fb23d600a7e358edf7033eef05af19b4fb1f", + "59c3623fbc8c29341481a7fead82ef6b3aa43d93", + "806b2e0c9be4502325b23d20f085b6d8dd8f559b", + "113382ddaeee3a9880b3328b4240ae9e750be3cd", + "543bef2867245f702b77470bfe08350cff1090ab", + "977eb8d9219bae5415e13656113e30d66c2f5b45", + "58153daaa0ec2e5f3e96879a33aee162f0c1283c", + "6663fde567230f1d0247dc7ea3144b3aedac160e", + "b418a310c03a4795b9ed4577c876b9dc50c18481", + "75c2add8fd09dedee1f2728426f5e94f9860d062", + "3f188f1a66fd317b645ea7eecebcae844bba9944", + "049296261ba622294ec83fbe8f5cb0d2cc3c475e", + "c60fe6fe0ea55fb34b3b5e740400c495e305597b", + "64df347932a61deb5ed0e41e811d24cdf745c7a8", + "eaaf91d87507541a572b693cd53cb31a4ff3ac2b", + "712424206790276862399340047ca6d6028ab2e0", + "2cc40cd0dd42274998746980844a8df708a3af94", + "da0ba0bed525b2a41d906aaf078f7da4c53bfad4", + "ee16dc82f66d8f069d83b76f1c433d658367dd27", + "64fe9ccff8f5235dd72a85e6c7676bc091f34038", + "20e9001f77c5454f9b9a9fa681f40067e4e1b8c2", + "40cce478fceb688eea9d9385f00acfc73ecb2f9d", + "21955259821de3bf9de7c8708d7a4d037d244c92", + "b922eb3c6a86c38717535220cbafffe3032803a3", + "be386c5615669fb19a05101d90df850569a366a1", + "c733de72b09be501a6d8555a51bab2ca9d65b203", + "740eaaab9d5ac5a9854260b09a1127c520b7b27c", + "0b3e8e2cf27e492dfb0bfbe9b8d6a3b2e2bc17f9", + "2516ba614aced5f991fc2f67e66fa90f3dec756f", + "5abe738e94964292a2bd38e6cf048138bb593fe4", + "1c5d0b73e977edfe89b447bfca585e8826b5783a", + "e3096837858dc2247961a29fb59164d5e39d8cd1", + "9a6d5ce05968464a6c00426a5d18595e5e0c2534", + "e74f03f5e56d5a9926c6f6351fd8131242a84ef1", + "573b84daad0e7149c3b128f65d75120095a1d3c5", + "5facae19039c0444d188729f5eeaa58440b55d7a", + "e617e14b9abc583b5e31b9ee315217cf52e7053f", + "62bbd3fc168a7bbd4703fb1778d72214115dc200", + "f9fc375d30b5626eced981d4ba80d2fcf6fba368", + "01227f21040de0e7be4979604d23aaeb2d220d50", + "1e53d5126a6f21a5cd9945ce4ae79a856d1c2aa6", + "def7d9867c9ed2bcf49984cbe78066456175afa2", + "2e1fc20df269fd7c6894c61c01f6fe0518029d38", + "5d6c196729f7c0eb0850bd9093d0a018b62168ba", + "062b7865763fd8cd0ad6079ec51a97c1bc35f88c", + "4630931b71697d8ffbe6154c45be34251811e205", + "a09166918a47fbda6c96df9a83f2e3b0df9057dd", + "036e1c39411e8eb6fa3d616fcad19f92188de807", + "8e6aee80cbffd0c0a3895a29bb029f57e1d76aec", + "483a716335fd7a07acb9a8fdf759add85cd55ffb", + "b1b1d87b55275de0f3b9c1a759ec6b543282cd5b", + "cded9ffcab1c2fc873af9650ae35004160b39410", + "37cc453cada7173368bfd3ed7c86c053557e5926", + "8538eda858022257c393f2b7d72291b2a133f452", + "d68841c1696583e487cc09a4e01a27afc4753bb9", + "c29fa22be5cbc683d781ce42d325830b4337a62f", + "28863c5a458f53c87559603b6bdb2e890ff002da", + "5e4e15446aeee7ea6989e2502b20b1278ee81768", + "25cf8915d7e4510f14f83d5317e6535d6e473bfb", + "3e602c716c72f31569c1ead4ca6b8781d15f9866", + "67e03a7960ccb911c4394671aec77d22f07cb495", + "e2b3f1d1f69d2b555083899700cadb4a971349b5", + "6c423e4662e730b3885e3375ee6d914612d5867e", + "1694013c7d8caf3b3c577c8024ef1c58f94b7955", + "91630edf6358ff0411a23f0a95ffa693bae1323b", + "028454e0ff1e27ebd16cae59b2da633d377204c7", + "0d07cb105767718dcaf998f307d4a97a38b35dea", + "23c3569fc657d3a4b1bdde834df0c8f6ffacab11", + "73c30d2754cfd13d6ac47ef28af974bfb021a121", + "055890aeb6273f7a6ab5176722418048a03d3461", + "3b89112c4fdc7e3fb8dded5157ae95c6afb68da3", + "7cb3cfae1db1575b52d02afd3d12f27fbfd6b56c", + "a310e3d7c808c74a9a2dd611d0bd6eda1f5f5340", + "f329178028da5004aabd83549936ea9728326736", + "5578dbecf4f35c97fc8762721ae16e010e42330a", + "14020d1fc290f5a4c1feb06d970b395aa2d60518", + "a1b2ffe5722b3d68d3dfbd1d3135c98681f1b480", + "f3b3996a94517365815ba8bfd31306483c453afb", + "cba0a45d7202f78c1e1ec5f150a1361df0565553", + "dbe1feeba6cebaa82465ff34ac85324eb99bbd96", + "067fac1d8369638e135bebaa5fc24648efe539a4", + "18983e0eba9f797a5602dacb9e3a1fdb1b0e5b8c", + "9f5445a4bbfd237564917d8749986798d61964c1", + "79025990785dd192d5732f072e29a37728a05109", + "a7caf5831836aef6ac5e6726a05f807ac20bbebb", + "23027cde1334d6db48868b8dadb94cd027b9b7bb", + "d0b280d64748bfc59a7da25bf640aa2d5462266e", + "8a9c5dac4ddf028916e6feef81ec0cb670f1e713", + "3790e9a57245215e68c06879cfb3d49ddf511f11", + "a5004ed91303ead3670260a0e682726c42cee57c", + "23e829a6706142d16305cc8f7f8c8b9bd8ffc040", + "7e592d0d2c566b32b7c1e44b3413354cfae15e4e", + "2e7a1685959b20ba75ddbce3db38798fc18becab", + "82218944dfd3501a3d4705c5132ad06506372a0f", + "ef4930e12ae3838d6059cf4990c8a0c2f6669c59", + "574f7a6ca7a130635f84701294f347ce26d2d586", + "5c91c2f83ca9daa19786263acd958bff2c79ca44", + "65d838dfb75cda0055db5fb03f12008ede246a3f", + "3c29ee4da5392eb1bdc9eb39068ab6a870d0c16a", + "f17a673f3438bc7d8e0b0b22ccf20e4b868f0ad7", + "653bf84319d61c7b41ad67b7648c8ee8571b6a16", + "3187b6d0e15a37687fa6a8683d54e2fc5c3a13da", + "4c29e4987613d1b30fdeff0a6af7a91b3be543f2", + "ee68df44ba84a65ec112d289100ecf978485c7d0", + "59283ef51d65bf7f7b7f430059aea19533f780b4", + "7694f04e3be4bea0e35f95d4728fd65cc9ef46a7", + "dcca8b27811f93142ec2bc14762593193ea69147", + "20115938f5b50616fca15cc1816b28423c2e016b", + "07b7e2a3f9733cbff1035533d0f2ba66008266b6", + "cd2d04dd8bd78ac250a2adebede35802ad117110", + "06e86e3d4a3f735c915a770fdff73ca8bc610476", + "3014039565f5e568630f7e463c35475bdbe697c9", + "eb729c4de8839c4123d0eb24d1d35886286ffff0", + "c990f68c512ecc7c23ec6ff428d51300d6425dc2", + "f3df0f4508b4cfe7e720f830f560c4e10f900703", + "43ff171136ab1855eb37721075a9208c1de3ad20", + "5d487b6bd25daa126e8edcb23f70a87ce4f7a27f", + "84f6f72a57317242849131eb3c6aac28cb01abd3", + "fd583ad477087f488eacd4ca243f1c93f5dac09b", + "ef3cb487cb03dfde3a33b592c24dff439ce9b783", + "7bd47a7efc8448f750163b07c812654bfadbe91d", + "b9de6e1facedee977ccd4b30aea8fe957a0ae09a", + "4ae009c0577ce4d0c87dcd743de9039ef050210f", + "04280ea8afacc8b46982710da67a835b92275625", + "ba7939b877ef0c1f066f0f6944b8c834f96fb67c", + "bd735f759f8c653a215f2e9d2cc1d8a248a25567", + "e9c70b7ab18d0b07580b80f2d92c43b11be5f71e", + "795c10dada7dd963603073be205325324a1dc205", + "8802f1d217906250585b75187b1ebfbb5c6cbcae" +}; + +const char *SHA256_sums[] = { + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "e632b7095b0bf32c260fa4c539e9fd7b852d0de454e9be26f24d0d6f91d069d3", + "3bff939c10f4d9bc21c6944606bcb81901cbad80fc6801b257fd8aa127881687", + "b344d80e24a3679999fa964450b34bc24d1578a35509f934c1418b0a20d21a67", + "103c5169871d49be7a2ebf9e6fe4720244cbf1fdbccdbfaca489898ea069504c", + "5845d549b3465df3c1fe755ccd99a9252858b448fa85fbd29139c3a33418a9ba", + "2363ecd70a265e2233d2b8b0a703bcd6aa71dbf47a8716fcdb4b35ac4fded6c7", + "883dbdc815a382a8ac863a990b4a33b601acfce6286df588b1e10416ca9934c1", + "10ae0f24c936bc39be215f80c343c6e870f640fd56b0aeb842c3cd49a4e6dfa3", + "3ba62773d07dd21b5712a1c221207bf2f46e459d862e7b7062b3b9e0073bbb1e", + "1a90011d5a17cbd702ea49cddd28190439dfeec1710e0efe52315e034ef449bc", + "030b6b1f71e51020e7b34f753d26741e7ed7c5cac3324b4fb237bf7f190326a1", + "a83b8899ae591254330a059b8c5c5a0d61b8a5cb1e20cd43cf62ea950861a108", + "8536a46b036db54a1f68389081f4c5dfb36c005ca655c0d005ade052e074fefc", + "3b6052bcafcb593a2b44229d6418f3638a1040ede220a06186948e0bc2378e10", + "9bc94b608c3636f6dbd12a7a08e586f2529c1910465cf764e5a2a16260a15c3b", + "1b0b70a113cd4065b095bae73fba840f3b93912e89dd535f7f795912e9b307d6", + "33a753c1d23f6a539b55c5c35dc0174ae048bbe517c701f3959495d509b862c1", + "99159403f98a4d80adb6234c336029f32c17efdc70f1d412b7e6008d6623f3fd", + "5cac4f980fedc3d3f1f99b4be3472c9b30d56523e632d151237ec9309048bda9", + "b29d66e56ed90cce9b0165c43fedec612b60a071974d8be4513e18580d55b5bd", + "60985d1eccaf8f3b95df873307d4727bc7af67dedaca6ea3d00d7e80dbb9d95c", + "0ec4cdc3ab31a48025746379b070b1af6b152e6dd1eefe8a16d1855c85711d72", + "76169b1e79ed4d640a78d664fdaced5035e7e0f116d7f044169763763a73d6b2", + "cebf42910d175773a31cd23fc7c08eaddba11c267105e51688728efd6152f798", + "8df831769cd51e4f57808343603e97c1ea44fcab46bb595a5000b9ad1d03bd70", + "4e866f068eb39bb4465a3185badc58f8be565b3cbe0d8e79d0c893dd92ca99ae", + "4a7b18fd0454f18d0ad320d8cf874e0466490e327bc3ca3beb13b1cb0fb01fff", + "a5e86ccb68457b2e8e5591e3c132ed5f824480ab3b34e8b798b1b4e955cc2bad", + "6c007ec72ab6d8bd1e7e2b90ab06095d38d042c172100b5364687985cccb71d5", + "588f6b03a29d124ef050bc1e46bb60cd983e3d75bff45b6f1438cb58baaf1a9b", + "ce32c090e5e13b6e5967e71e0d0025ca61fb6bcd54502221e354535ee7504fbe", + "5f48828a7ecafc69180e8e9607b277b3dd17e53acc043412a06d8f170711c74b", + "2d79fab9bb7d5b49e4c7eb28c14334f9d014129ce43d1252636b23ecaa569771", + "acbe47d52e08dc6ae67b0bc249c6fe92c2fea7cb5d168d089bdb4e5f012a70dd", + "177264d66f016c32fc7a4bf3d6a18fe64f3b92aa25dee9c3b84e6e2d3dba2467", + "41555a329cd561031b7f79aa7ffe614aa341fa4c8f67be9d3169ca02ac513951", + "6c450daf0a44317b850ab800b2986e3bfa19b118d82de07331c59b4461e08bb4", + "72a0280b4079082c4823f72d5847038ca4b3d689b8d4de7f4b8565ca5cc59ad0", + "e79df309e6b0e98a1b677e5d47765063170fd0fbe136d305230dca2ca1ade525", + "119ef8154ecb9f78200ab9a95930877811261da37f9cad9e533ad34a57275fad", + "fd535438ba7bc96dc5aae8b19059fc4307c0e2df4b252dd0d4d10dedd3116fd9", + "677b9fdbe2bd79af033c224b32803a77dd284885f8655aff914ac63fb65c0a70", + "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c", + "88e197dce3e2562b9fb62bfdfb92c525328742af370fa2cd7c7bafaefb38f09c", + "6e186b825513e046ba1d030f5bd31caa27a486bab8933e3799e8fc8c7a0be919", + "ffe66f70564e2ef5b55cc4083aa1bbc24169c799a624d98182f99b8a7c950a82", + "381ba8d74f62ef53fe4d22511c9d7c9f182d719e8073a5ab0201f91676a2ee86", + "0147a26010960f5db71fcfa15c6f9278f2556905aa9fce122bbd5fe787e3d934", + "fb736023fbce2dd88d6eeffa02dc975f5b3cfa0d2c0641382ace3cf92975bda8", + "7c17ff3bf15c19d9a78f5c3f60dc38fab533ece520c8b8c73fcb0fba670c76b3", + "e32271566d6a71b90285b5d00447d1f27737d56bc14b17efea026c78e27af416", + "6867916bb6e48ee4f3b3a9eb4630233ec89fcf3722ea429ef300139d74f1f18a", + "5a0e44a7c154b01f19a6cf5d83d8ea556d17ba1ffeb05bfcacdb7c477dd1c912", + "0e9bc14d279f681c01eca319b7c22bf6e313186865a4d2111712f29ecc0223bf", + "1be2cb604f04f8538e1ab595dcceccf0b838041e72a4dfde8df53d84fc841828", + "0415d70cae1ca48b070e789748e8f3982a209a0c4b8070e2d3a26f729f04b0a6", + "0e29d748b4cca4b372d587ab8164361aa127664635f956fbbdf076c36ffb0c9b", + "8b0ccd3d72a10e396b16b67980f31823972b7114059d0d780b7c6c1d11aaab73", + "7105f8ae45fcb1a1829053f98681b526616e1d6028d1f72a6a0cea1e079c2aaf", + "5ab206331d14b2216b02eb0a58388e8209ffb396bc54eb22a47634cf236a03b9", + "71daf2e02b4b542a8064567793b62fed41f2241dd284163b15d02d279910e1d6", + "795a664f3ecfa5003b7d18e8ac44d88ed49a8ad731238e381f76cc72451e5d49", + "0d01316239b68e707e8079f02588bba156906aa0a8b328a2103f3dbe79464272", + "53798a699aaf9b5992322e27a7c48802ff41d04acc52c1e6657fdee037f9c0b0", + "250676ab47b392eaeb3bd8f7640c676e5a9fcfed22dc08948601c68d7eb867e5", + "c8c295b3179d555b5e04c82f8834b031d4dcb5df9409081e6e9b23be4d1aeb93", + "a6265afb2182630750a70887a35072908c048d5f9c831a2155da1887f1dd7709", + "78ba265740cc1335d27530a52dc456668c9475250d83f3e1c3041ab3d0856338", + "490b607d2009507689d5ce40f964e9b5c56ee54d13d99666eec256439a5d7691", + "012c3b2137fbb69e1b1457499923622d7a6639c3fcfd0c1889de9f1ae9a5224c", + "47f57d4c0eef68f4b14a02295da342bba8be6ddf901ed4ae1eaf7c3306672593", + "33eea677868305f597087e15be83723efd51e1f55342dac47afb604579fa0f74", + "f9aab1fa5ed80cd385cf625ec808339d819bd1faee979c3ee008db68db19e6bc", + "1e6279781c1a757c9cd3aaf2665c0c1d235e514065f57dff455256896313c5ae", + "fcad8c2b8ab78e1eb313f9a77b85e29ed86d4468d78e845fe7b197cff28889a0", + "0cc46a7fba1d7b1e7a7c6c438352fdde342c573550eac5a177e38d0cfd854b91", + "7d64ff1a21b7194e2a34f718bf536f4fbb636ea2d50b9de9423c1a64da67a566", + "624097dd2a64d12dbd7a9d15d58b6a31a8c11e0be67f20afd388e61ab316d6d5", + "c10ed525d528079a6ac6e6ebc51bb439a48df167c6860da2dcd8ef5a101a4bf9", + "b9ce9b34346f2d83dc60927231c14d1af0b1a915514d610cbdd69a8928ae1b57", + "4a3194983f551da64720e60b91e0bfcca2c5f7277b97ceb813b6665cbecf5078", + "cac95b35edebc00cb109d4726befb06adbadec365e102f8c9c024fec2efedd93", + "bd284ce312ff8f71a8fffd5737733c72dee0199eb5d9dea29875b02fe7dec138", + "888f4d527281b7ca77fb63651ea8c28850d62f38d6918a178bc7de7ecd61aca1", + "50839952e08506f523696a35e758eed06d7fce0a8e4c079242bd15b476dc2632", + "ce6b0b2e2494ba591909f5971d4a326c395f47d45ab2389fc5980a8d7c160373", + "328524b5f7c5de2b6fda754cd634480d2ae9953514e208d93c7b0493de3c376f", + "00e6bbca7e9f230b903d0029a603831688e37e141d283a88ff65f8a8de711214", + "e9419c75509f476ecd71c0ce5de42b13b70665182d470dc6b9389992e71ca610", + "bc93bf4ac98f5e62a180219b7cae5fe4b1a33700d1abd8769310f1b9c458052e", + "b59cbe76a3a993a8a5e93e7fae2277a99c52b27570f8cec0fc27c6407b87a863", + "7b977d99df79f3c123a551339a3584e1dbf8c6b220489c94e8b5ef241a2f4f32", + "42da1a65ef28c00d30b63128ad839782daf8437da50eaedf9e40c05daa324030", + "27b7b244d0a284afc02b21ddf8818d4934bf7d4a96db6c9be02b9a29f1d3e877", + "69e8ebc88995bfb9af4938fac297e7cc87f516d91ee3db9c385051aa67bfa291", + "e97ec334ea0e600801845a004cf943282716e537d2fb41edd3252ecc604cb868", + "61ddc6c83fcded7492a0b4e6682a2ec54ea79bd832ffacebd13eec490ae9c513", + "b1b2e4d6d5f02ab694d8be129dbf9f7fb345190927fd2732ab24e395ef877a95", + "036d3ac977186da97d849ae8706f573bae36822a83a8b820b0b09bfa7a4fde52", + "244dd1e7818cc1fc0b1790e5bdd79df79720b5ca4b30ddfbc6e03d2fa80edf24", + "025dd4c8ae7d9f3aec6b2e3014eda38ec54898c67de9ee68578ec7cc8254c345", + "e29858f925c90e19c49336f52a8acf57e7a0f10fbf1b0254ec9926afc77d34dd", + "e6ece3c684d5874497b83f6b486f0dddef4377f914e19ea717b82426d6ca37e3", + "952c6da8834e0c4c127269a6e69c59a23af9e35ed70577715979075324776eb0", + "675a0a83882910ca29d9a4b72e278afa307a2661bee3f28dee7faa7db73dde73", + "4102eada32bbc31c13f1fbf2f039bb7a46bdb3589e9bb3915046de72c0c2ead1", + "305793f522114ca65e243f80b82199425286a07585deff0d132223506c54c48a", + "c666ec59da13eae8361c08bae009f114641bb3bed6f6c88c69c888ab9b9bd2d7", + "115ad98815bdfbc2e9aa0922a63c530f2f49bb36bf339345694b6cfadc5a25bd", + "1186297e299b427c8ce24e20670156fe85eb9102f8ed7104154fbd10ad28b49a", + "2d02d02abca735d371fa9fbe2ec1fcf5c02a8eb5186140b849d13d5667c8588b", + "c8357ae61f0c6107d48ffd35b791f2a96c36d9004acbf97a7a6fe1941096e74c", + "e2f783571644ff40bb649ee1a6c7481e288eae50bd9621c638102c1222f02695", + "b057d8b05d77dfd016c7820ee32b3dcf8c0af73f79a003a68f7b344bff5f9489", + "f98a7811608e9f78df7c1dcc6765ad672d907ab49e3ab756b6ad2ff392ae3cb0", + "06727bbca9d6e47cbd4e2f61b313627cf0489c5f84850dfb45cb496f11e0d880", + "62e011d19bbb328c57808bb4dcb1fd25551a642df179615559a654e91b233afb", + "18811c3a1798f207c75d895a6deb4b2ee05a27749e5d4dab02f5299f8f62e43a", + "a2eec6a9e819ca9ae6accd714273210cad3a98ea104661b841b8b18fd695115a", + "b745658efb45b83211abaffe3af0e5fd3769866d154194c9078da9491f793bae", + "bef6454bcf2dd622f73ab849166a95f56be540ff05cc2b79412f40c60cfec3b3", + "13f42a4a6df75f6b09a53eff4a92b824b8212ce99b54169774958debe92ba00f", + "f6addf5f0a754434e6767535ee8cd12a57d3c78eb5925d421e43870ddc0c4b02", + "abbd74e4444bcf0a33da28cd9b74483d19c07c0c84c7a217ed1d8d143da44c4c", + "18c5fb1bfd33fc27a0b7799eb14d502e8b59acd5da0be6f9a7fbabd96608c61d", + "91a32360bd0152180990285fd7cb3145207d33f866c9d99e7f8bb7331a12d03a", + "3324ebb8bfd51c9ac3f3994a56b7e0c0106d9d938c147edb391a4bf812d6afb1", + "914e88337910ee43d63f77d91502eebb35ae38ac6138bd7af4d879dbb730ac85", + "bc73865737be6195981507338ef06ec2a5f34d3f12580b4f89d5e28ef8283969", + "0b41f57008120081011a2ba580d8cff17f9c1f3b2e811359cd3ecfa9b36dc5e9", + "a1702789897f4e641bf00d505549c6dc9df9daf904f3267e0cb583c7fb49e832", + "70737787a53182c78152e845e0d803171d27105c7ef9407b48ae51280b0b1ed3", + "683a017524f641b4c38c26db0df5046fbc38e30fbbe7fb7a6804e2e039c9d353", + "8bbd8c3f3c6911a3e73ba7a480f902a95fdf4c8a7c554b68e7330e4914481f15", + "66e62f07828e8a8a6ce821cb29fe34f2ec551d4422b593380e5209ee4a3a3e57", + "2aa054e91da4874329ac8946922323c8d5b114b4ddd714f54cb1fb069dc56646", + "47db1856215834b20d70031695491a4a90416bac8d231646bba8754585f67d08", + "eab539981a22c36e481b71d2c828b848b9b127963d7b5eb56c4903f5cf004296", + "cf43ef0749885e4108f8fc2774a840264980e4f2be51d1c803bbb90965745034", + "fd6847b7d5ea924beb8e7d43d0e87d4866f9744629f2768cf32e7f37efd23253", + "1c3d53f1a7fe78c34a4c33331126375e57f4f8f732d39e0ff550fb717e683724", + "f03b454c7bf5ddfe083798a85ac46bc671ef76b381b969ab4f333c74397693ab", + "0c7255ee15ceac49e1281447b159ed1ccb8fa09d3d002fe3337c80f75a247b86", + "4c69c21e1afa642423a660359e058c8d6a2dae61c1083b7dea46471ebf24f0da", + "b984e785026dabfa52ece12495df98bf80ba831ea316c08fc4b39c5fc00b50ed", + "40b33b1a89820917e19e95bf5abae2121b8f200c826a3559440010d2863a5acd", + "053de20a192f3205f46e3f68d8b9926abcf64df55d01cf166e7f8e8c8d042487", + "ababd9164d854d8a7b56fc4e6980dbafcd5aa017f5e2b5777a6e6e47460fc716", + "f3982fa10d2353163d644ab33e2c5af7264c0c9c8b14cd88d91331b5d01ae3c7", + "0d7c2df609dc5c44677d62b8839576b98ec78fa8b5913add17b7e9cfaa6aa75d", + "3b86e1a3a4e3cf19734b693cc3d9b24d4173b5e8ace1be3daa303755ce8d5737", + "dfcdb86a6ec326f0f4c8b167b5945979a5cf3a2ef20970c47b46ddd47f8fd6d1", + "e2a696a14922cdeb99abe04a66576e65142be3b0e53cf0c0f05c86acf63bc83a", + "780646dc52688aead41076d4906e17b42eb5593565f179a6bb5135143d40d03d", + "847ed344db2cdbfb7f69f9b2c9a5359e13df72c2485345a80fa9b114ec7c8c03", + "a4f5b2a505437424c3382e2d534ed2fdb55af631c5b211871f2e62acb5dd722f", + "e6e8883f5c8d840d7895afac181c6d9fb154672fb2c7ba9757ca8528242bef64", + "c89e7de64979fcbf929148c7b44322047e820219854600e88f7a7ce805971c38", + "591555d8d3936620ebb6be7549ea9eaafa9e6a562b9ebbbf4c04eb4f926d5060", + "2ec1da3a8252e21834db7c90077b12547f70890b853b5b269a38f74b421f3a4f", + "3b05f141c3855409941c6596a92ea7a3ab59764bda3cdcc6812060a5e5d1f48c", + "82b21ff095df092358450698e7a534453105014f3b227a210cb5d523191570e8", + "229da5c29efe0885663587fe0080862ef52e7504ca64f5d6ff1c26f5a7b1c0c7", + "cd3c1d86961be993a150c1126a958ef14a3e47ef21507492ffdee8b089774505", + "e346ecc2f3e8cbcbbead67341edb971f2a9e152f8c1e086693dce431d9e14335", + "5e5c06dc93c409e935b87373f2647f57a951118851b226f908751bcafb496b2a", + "2f5ded0589de3ef9f5e5b05df0a19b02fcee0e686900c5eb9e3153ba3ccdf685", + "6a0335f78e0fea8e4cdf747d6464f2de78e659b9de5be37ccf8f81f1e775ca79", + "8adfeb35e7d07f4aece0f8b4b282a303e45b11c9b4f9b1798cbcf8cf0dc5f48a", + "94dc98b89a5b498d7c7eb0fb0524af296d0181e7a4dac82c3bd7ce147019b52d", + "4b2dae26d837294c81e00c6c28692235a9ea046bc8038ea78ce1819cb5f54be4", + "77d9e99e3a956c9b52742b498b8811cb721ad798866d36d269b4b554a707e63a", + "652082a8998da5439cb5e695104febfa81d3d3a0bb4dfd49120b82e350b48f6f", + "43bf07481f0bc237e1ed2ce2b0b3cca1989f9bdbbc7cf1e78879984ff927b3e1", + "648f7216f324f0a46648d757a21dc25c9382c64a095ea95b62aed37596bdf842", + "34c3d02b75da5d2739bb8d4916110469e1b854a8104aeec7ccfef52a02f234e1", + "0d0b8d475cb50a40e2cb999757106f4576c5b69176df4c30e1c4659de1468ff8", + "63d7e84cef1bc8c74ebdf53fe795766f0fd32a9c6246586f8217010db1c2c9f5", + "99525cf2ec889a1628576099f34ece6d60de03fa85ade70a3d0913033934dc1f", + "8aa3e3cd4d678c9623caebac79ecd62fdcd15de5960c7fbffc3ab8e77788109a", + "c71259d6ad975ada31990fb7b3aa958248bd88d3563b581959acf4f18310f266", + "df3a0c35d5345d6d792415c1310bd4589cdf68bac96ed599d6bb0c1545ffc86c" +}; + +const gchar *SHA384_sums[] = { + "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", + "0dc52f16d3eca9ca8498ef2d3dc4874b3ff09ddaabbaad2b40694f028b5ce96b4f1beef0f7909216561d97f3ed52f898", + "1f523ff2c063b7e066a7939cb32835e2419fcb17a84cde41db20e6bf232a7e8bbf604b8e72a78a71b1143fed864db2fd", + "549608d5e5f1ed4de18574ad672fdfe4e90adee52212900d6aa7dee0da385ad52fb01f4a7e3389a878abb06f179856cf", + "db3ecef9235f7ae209e0d80b1cc410bcb7ea5e89723655a1bd2164d2f8dbc55a88a5c290027aa3b0f304624ee66d7d63", + "a7e6a7f853669ff6fbd8546da356fcfb2a101f673317dbc8694a133d17fcf7aa47c7f45ece36f74982713632d45e08fa", + "33374d882fd9fabf7a68c15442ee3c867eaee873660f227fa9c075b2c7d0d0847302d7362a4e44dd6c5611082e7d7e03", + "1d470f2ab6903d018db216d833c9dc593b0807ba8b2c3b262f3821ef157d3877dfe2771289681e64a32bd543044729fb", + "d743cda479245f11b02c027811fd365d3b19162678cd463ac5c25736df1348534eca57fc6c11226d2e42643274517ac9", + "898e462929c5b044f168f28480285ae9358bef0efb4178d16b4c6881dc1fe33f4878a201caf15e6fd4a3b2a60c399177", + "091bd8d09c0b65cf2df743296059e9b4a5204a639749ed8d8b84f6d96a1108ef371129e1377e93ca81df5512017abfa0", + "7eda4e628dd8c86b0219ef6cc3b6a8f8fd43bf014b3e17d235fc0efabe2496948970bb7b9381c0b16b0c582393c8d4a7", + "6ec427b055ecb6893dc1f124406cdc1b6d978fd67323876739fd51d5efd4e734f7438a4457fd12bae9b3d3bfa24b31a9", + "86748bdf10e8824de5a7e0e10401b0e56398f90e8b403e9617b3f9d8d364cc6542d7386685e2a11550eff335da121f10", + "46048fdb1112566f73260153eb15b265ca1c8baeb94e299465f5104de6eb686d04514fb80cbff214b3895c6ee05bc4ab", + "b8163ed91081d10e611865911bc9d441da490b5d0bcab4ace75c44d2e092d86b22105560b63f89896e52ea032385afba", + "a359baab8486a764723496f4676b604cbf6fc988975b5f9ae63589b22dd9474c9784f97bc7f65446b6954e4c1845286c", + "1f811cfd2f506408a76231d9e2f36521445506484b4c3fbc06aace043702a838eafaf5acf00ac34e833288192f603b27", + "3a36180fb8e4036443058d8bf458d462acf0ba502346319884b129c0f3e02315d753448234c802027d60274c05deccd8", + "2e45933dd1a1e6a6928a732d58abeb180c225e5e7b99c64eb6f233a7b99ee4635c17f44ca544cf620cf4289deb4c08cf", + "c357c3b780e1c2b39eb2a945122ebaec4ff6465e87b733220394e1cb0de112ae96b7832e81b5cbe0aee6f4e226ea4cbb", + "4541eef600241af98fbd7ef0ae051251c165876a7ee7836fbe307672339da2e3dc75ba348d1ce25aa7761f3f3812435a", + "1ec1444aa377ed39fea4f233e8083e2a3b7c467b9ca0725638eb7b7ce2d4a2e8c1b65df371db0ddf608de12c09c50357", + "c7359bc73401fbae01f673960f2151b3df8d80397a086cbd2809e91f70185db26379c52bcb98fe43e7331530bdd90e41", + "260c27c51fc73b0422b89dd2d5523da65d23d1447f8888e9a7b7971d39179a98fb1336db2652b8329a6715a6e45cfa4a", + "17ab2a4374f66611b44d072223392aac47619917f67c563be63506a2445438dac1f08aff2289b6306c63015e17f6d756", + "50ae7f616544ef154a5abc45ab755a9b39ff62a85565bad855a5446b2c5b0eee21c1707c4d00aadf38c0b5db0b961472", + "7001f37f83b37c0802cf5a4f5ae7c99b76af103465a35d396bcae22733b9b701d20fcee38efa73b80d7676e4ee067696", + "acced5edd17f02a3d4d8fd161dffc2d20c3198ebe95bb4b261d68b0184233549576513402148950d2a0d6b3d6844f584", + "45f35ba985744959bba9fb05a42f40f13fb83e13a790d300e51427c51cf3336a57f3415e3929edf746eccc3943f03287", + "a661b26f153becac9986ce69f2e941c3c2236ee8b8ca0e8848826e6d8787598dda69ae15e509476cf0c7423e9359e04f", + "5fee0cf0b2326ac6178bc8b503465d9b2006b21b31ab1d71a19251f1e5e132204abd50566b5f5b1a689ab2185d369250", + "60be6e4e5c333bfc2cf3766b9c11520e89d61701c8de9b0c2998a2ad6f28213b807e7bf9ef8eba25a1d0e57a8a60a092", + "cdd74eda2c2abd8be3108be5a78e119f56c6695ef58963aab81040daec2a48a7391c85ff89e8c97aa567199baabfa63e", + "a41e7f8ed505508ffa0bd15203c5c40516d443346faa4f3ea902c987b11d1d9235464fc4694aff5e601c128d246ee108", + "9cb7d4d38c1212ad80805d57ce34dac09df2e6094ca4f4a29b30188b6289fd4ff8896312fec927d393d70f2439f44df5", + "49b553e1e616ac5714f749e856f604dd59fc5d8c404fc1ec40ea6699769fee9eaf05a7fe3e70aa6999efaa2a30bd3a4c", + "58e0a56466cc30d767274a96d1d6361a30e837adbb08786af782994679f87ad39b49d7ec23b18cd13512da10ef533c4a", + "e7e303d2aa1747b1c0ee55f2ebf771f124d1148a7482cffcfeb3748aca02b115b3c5f161dfa66b4edb05fd5ff08163c2", + "619e5ee9fa3042860c15fc7ac487effeb5cc525f050aef88198d2eb41ac770284c55c3f330c609b1f4751757bc0dad7e", + "a0bc5c74a22b66174865386592f7447bd4337d0cf156ab87e5cfa603b5e7b65d551cfb2f9308ecc4fd68f77961a6518e", + "c9b202d9d654be8b15f9d0e6de0a0cf933404e210fed2adc10defa505b3f864fd0dcaa5f1ef74a2b6f27008fbbcfc387", + "2122ed7b325076d20268173dedfa87721598002389eb345a1bfeaa3d74212f552a6614bd4853e998d70416f7e742578d", + "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", + "ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7", + "64ec7149fa7113fceac47ad4b1aac8aad3da081edd956670fbe720c37e764ff746a6098ce3b1fe5cba172f9c78bdb092", + "85e6b0436e37262ac89afed06b7293cb5c4d1b02f5ee8947089352501d76c09844065017b9ea1e661f7669dec61da5e8", + "1e5810ba32c0cceb8953676d01ee0e23f9e1eece4fe7ac6b5c3dbe4b3e3a80d2c3ae04dfae07fd7f011ec7dc0206e4a7", + "40b72fb30ea9df3e084f1044d60594fc692b41c5b455a1473819da33865594af21173a648bf77ddb433863bdb2f549c7", + "73ca43f78cc16e1dc388e7e0c70ce98a411145893fdca7480669d4055e1c8d79cfec73de1c8759f58d6a1a45501b06a8", + "1ea9c6bb6a37ea2a86938cb4f5a49ddcd7172ff8aa9e159c80bb2c9e1340949946a0ead46a1e1321b0671d2091c123a0", + "ec183d2df6e95ccb554753fc7fdf5e925a3f8d7a7d65f29f49c49b9f1782b553f2d8dd02dc3d482f72d4b104eeef6b9c", + "639e81eccb6c0475149360dc6c4ef17a3b7a177c6365de8e9c2cf6206a09fa35871f5b09d8aedaa73f2d25c8079c11bd", + "a4a3c0672b9caaf638203ec5f59732b0ec2833c2d4268690dabd4826a7e69e1e8411a5c4136256e0f85cccface30e34d", + "d2c6d095c43c483ae7bbcabb9dfa395c4f6744e2fb372afa05b08b96e4b0f31eff793d2ea4e1a7987c2a3c7ad9a41ceb", + "893737a01c71cac766a0540a958ea8cfb76bc07f7491e725780f270e60cd2cc3e78c776ac09b4b182b6bb788a683a1c1", + "756a266a57f2eef3ebb0f25b421e128993e7e78585d40d52d167107893fd093c23c2abfa860bfc9f8257d319c4d63bc9", + "aeb27fe17ab1088f28758a6cb76fa85be060a10f049034c8a5bac616b4abe3f75b4a8ce9183fd688e415565fff51e102", + "83070b470f5da7029c0146f934445d233b5367fb7cb6ac218be976db71b7011d2853c5d47594002268398691d5755b19", + "3f2e1aba81d4662cd03a19da044d74afd07ffbc73d99d49515d7991f02e75256bdbe56cdfbb6f340b2aae0b8a57af35b", + "8e88cb931508d906d5264353aa1bf78c3d3b48247277b819d56fec4fa0842067630924b5d0635fdea27caa35eddc4d43", + "54a17c1f2453f297947922b2df622b249097e30668af87a0faea941249156026f029f4ed0b5e5ac8737a582ecc2e9e42", + "9e97e741f5a416f145b6bc226881ef30ca640ec0515f66447b82bd9d3e04efdc939b415dd161e4821ffef81dab93f853", + "1ce35a3d0221edf54a21cc302c132d36d4a40d32600362ea7143be3b2247882d5b912d72bacd2398f555805150197704", + "b386eb4ac1044eaf51a634bec4fe768d6b15caa1349a17e9c6964fa3476061e9aa36bce8ac2827dbaeff494cb13347e3", + "0f59ee1d7925ecba97426ba3f3391149fecadb0e91730fcd4dd8c3b7e33ac4ab6d176fae7f89f256bcc39e0f38614a00", + "704480c7512c0e2cecbbd7362a0cb80a3af4cf2f8bf47c043d7eee46664a1d12c3eee7774acf22ec51b412ff42b28e01", + "2d134ab108e0d48f163565d56e03d2b429d86ddc3ffe99fc1af9224e43b8a4e347e9cffb5a53f2089afec62fc0fc0535", + "aceda520bd0290eb0f1dfa55bc5cc33d86c76be3f649b721db7fb8108977645f13b9eaa56c8ff31940685eaaf1c9045f", + "25e9f8229348a67f7b206efdf72c761acd44bff13aa79577087f2a279683ae2190d2e50c2781ae13a36d27a6e0181a78", + "8e263e257424ae9ca402f76637c22f676d101ce7445161c846b6b20a82ba1a1a062be4b095cf38bd2f85b207fc69dd8d", + "a8b8a738d201b371a2a58f9f44a7378b21645c3b188d4b3dd44cd657643c40ce5db0ad47cf2ad0d906472e843999c2ce", + "9305f1e51aaad4bcaf1eedd796d224801e651a2d1024a5ed938f04cb6f31cd9ad917a3da123746f74489607bade382b9", + "846aa275cde54b1dc18e54d3f8cdbea72880b24344022dbe41f2a2411acbaa3ceb9981cca41f3bedaf11ec4f1cafccf8", + "22ec68e8240936a821bfd74fd70456d0930c5e822aeacafb7a5a56278d3f7cc7ccfb2077ccbfacabd48722bea6cdacab", + "83f85752a7ebf35248bed9ebafb7bd8f8057822fe0217653032b682b0c65f1bcb7d72d7153b753aba0391acaa00caf0e", + "807dd327e8261f03b0f0033eb5a20434455513ba767937dde25689105ce5e0afc73d5ae71fad853fbd9f5834dc0029f5", + "4474115e088371995e38864664f25858c787cd5fab3ba27e82a495417493045fa2db4c308bf361e457ea8b95fe214623", + "e300fe5cfcc832b44055e36e662a3f064a0355d3e02b913a3b4e0c1645e89f06440cc1f6cbfd800a187f071bec87586c", + "b1725159fc6cc41071234ca1c68ba5c53cfb5160f08b82a3f920e1afdec7c8e10fe47fe9ca880e0c6a28268235196226", + "f355cb21971890b902d11eb761d42fac9792f6f4522167973d11ada18689cb644d719dab95817c04e8f51e3af60455f6", + "c3bd83e2d4425f12b9408f557e6df726faaa68640b823cf987823a9a8a7bab370311ff700f921536eb7bcc0a952876a8", + "cc4870dd388f8f010d4f1853f70ff57b20dc55522c5211b7aa9adb9d87fe9a00747ac4800c7e933fbfd42466317200a7", + "026e8903c649d5f0d11689ad0a1d2505f8813dee1bc91f318992d595273b589cd1ae5288423687c5bc81a8deac20901b", + "1e9a40bdddf2e4219bb41e57d04d676005c9c9726f22d6a9084a017cad077fc72f9eb585dd56c7c6e98d2765fa638fa7", + "fac0e5025c57b9ee5259063882a0fae893a4d58b4a04966b7d30c07e6f8c94e506ca045eb7fb2ebf90a50098f67b1d21", + "b8fc895e7b16c9b77693add7142cc29479feac2200164db6c726640791f3343d67f1140191f6c098dd107489adf048bf", + "5a4f5827cea371f056314eb44d430cf01a351afde1602dc73c041bba3f857b0f89ed834c504062af234cf5d226d4fd68", + "e1e0262c44a178aa6e66b5f06a95d5c1460546fdc6fb3d4d46c9f91abf90276968eab30c8158d0f69c39be0ab46d36af", + "22f0857e546c8c9177da942a5f6d7bb4006e06ea75cf1e2f0c33abd5fbd04da7ffaeac9809ef5deae5c92e91373c3146", + "e00dfb7d2961e1c6131d4d833d7cb717606cdd2f700ee0a58cafdddd1d13bedc4e3d42baafad9291df4fa750613b5d54", + "7bd7ee14674440ee1108d8223aeaee4ba79b3dcde6131aa3180df738ac5ff8d56fb8b1e28b76569e64e8f2d01888caf6", + "90968444daa8606a654f16085567d449d9825fe4e9121eedebccd1931b1008a05314cadd3d4517ad244710bc2cd366d7", + "5479100553d648f7aa0383d976ee17644b382935370a45d1ee4719b603c8756c6768da8054dbc0b350de956b4f7cc1d9", + "2cfe35f7d56b98eed9c503add7d928fa40f36481d9081537c036e2b580461ae949942a44cd39305dd97eafd35d57e0dc", + "1af78690ff86c3f8fc618addffd185f02d34a1c7bd1a7c2437671351431bfe88473cb77f11b10019b940862675cababe", + "5438a88ae5c8c6b749e13277473604ad308f2632420bed254424476cbb37fb3c6f2dbe1d215c88baecca36364d9d7f15", + "f12ba197468e48837fce68cbccbeff29a86975cb52ab79b330fa36e1adb59d13a3565542b8224db0a2e6e18ff74ce4d3", + "9d1e560cc3f3f0b31a27005c9cd8aa7bdf3d5654893a09fe9ce8ebd70808fdedc30f1a8891618f8213c3a950e2c2d7a0", + "9a982423774d784389a44cc5be202c377f9ac24c2dc391ccad5b767528f25b71c8a344aabe5eef5708f29f70af959797", + "03f2b41094daf982ff9e3e88a617326bdac3edbc799bb4be9230d2f9ec7be0dd429fb0e2668b79773a81c3648033449f", + "6a9c2a01dd1d3f8848338e7d8576b45e0f4bda52518544bb64872bda7757b147f33f98367b30eb85fcbaafd76f60cc0c", + "83ea416d4e44772b41fa05de1252b2498e0d9f6c94499b916f4d6020129c3efcf82b56ea3e5aa096da8afc323c31fd37", + "aa10bd53633bf4e5710cde88017782ae5db69bc7e6cdbdca043ffd7745983b0e1d0c29e12bce574d565fe945f206f119", + "f1fe5c15d79e35b90f2e1b721ca818289773fe402a961578c6e3aebc320599201e8226576a367477293d40fbb4f3fc28", + "0faf4a5144a4814bdd525e90d8ef7ae5036757294c5688ede0799136e199b775e57feaee0cf71f8bdce491d1d2f024d6", + "63b6f20d0120aaa85d921f4dab46a5c714c3929ef8538c734d7a7332244e873790c7a5dc6a68bc25346957e3cc9750e4", + "0e30f7de204cc8b8823df223fd47e6d1610fb513f7c82097c655bc711693224ac2094500a7d88c82fb63d466ff344b28", + "59d2e7dcec3f682bcee635523f40274ea438798e6824a069021b6f405f3aeb28507339f4fa62d2d2ceb880232e087407", + "47c01ac096b61aa079a31ba38624e4a133db1b74c167e6367a5286836a6c43cf2ce43acb732368530d55ac51c0d2b20b", + "28e83816e04a37c8c4aafba1e10bd7b0f174ceaaf96790e247fee67444ec49e9b45778d52264679ad849b8381fa02606", + "b0a51ea444b0453b5a507e61cd8c4aadf0f16410112c41f9d0d87249240964f04dd2fa4509e3a94db1aa60f8efc9b5d0", + "e7727e316fdf5e9ca39bbbabd11d1a34164e4c888397846ebb199925b224162480c98cd28d4e9ed6a62f58e71e45e84c", + "680a954c79572c04f5b676a0c41c05373c1fd4392df600d168d12a92d93c40be45bd57d07dec9034368361128f51dc99", + "5c67745118531a6aa3d8297240c009a398d8538acbeebffd015299dba7cc09889c7a2dc89b2f5cabd3aae2f64de68ec0", + "972ba5fb43f49682599cd2139f3b472a97729e2ec1af230f4f8e82481f038fee55be151d92fcd876fa8aee1a940d9e99", + "2956fcb6e5fc8751944c41749a2df73e4c9d1ca97bf692a9bcd32f3741d40129917a09afe84cb422e3c3cbe9233930fe", + "be42a35c6d7d8f0b1ec568ad13511f16de412cf68f024c288d36dd385aabbb39a71b47e8d3ced67436f9b10f86ff79d7", + "bfc033db0076c92c90dd999af55c5a87aff33c39e1beb497d2c5b04413da304d6e4fa0757760650d3c83cebcec850665", + "5e428bf59fbac06779cf39e4c936af3449345cb0b5cf024e12f9d65b5335d48e36bc5794394e4ba6a69e376bed6c5fa2", + "2319b8a3c5d4ccc8309cea7671ba574dea6cf5a22544e5484e7cc505f4c9962d39e56038268fdd3a718439666dae4130", + "1bb8004796e666a7e190299ce4a9c0d2a3a873880d1a8514b691d083874ba87f14ca8e1012eea375d0ac2c7ea4f90c93", + "cdce59bb1419cf9414d118af0394c33cf6b00f011ae440e69814ac38062cb3a74325973753afcd7fb8e861896f655042", + "9c5f45af32bb9f5592e11f0f3b7843f48d8cdf8488d342ef5204a603701a28cc9fd203b2687c36b175724ec6a7b49c28", + "5ec187f20b00f03c65acbf2aefd41366cf13d5f65e5547e59827e31394c9dfd4b29e4c15eab2c895ca1dfe42f51bf1e0", + "37a98ad9163c780affc45d17e1c9d90385219e1fd06e1b892adafd85b7e5e93b6589dea59824c5b1ffe1f6948a6f8abc", + "1dba0337f96f1b8d389836da99f3b4d5b3f032016db5633b70523a4943c39a0bb7ac0113ff2fda8c9249504a82154985", + "4be93bcfa6659f0ce77403929e4ca829ee6ab2e6c3fccd9705827a63210d61c84d532232d10d6419fdf7530923d4d3ca", + "2c193964714b91f9a042de286978c3946562e32e411ed665d7f528dda482c40ce03af2c1d51994ee8ecafa31995d2a97", + "c0dc5fd7ecef76c407aede2e9ff953da2614a93af881e991929a9ed741d35bcba018507465c823038d8253d7793a4a6c", + "d86d195ac354c1864eba1a375fd7b8928e18c35add5fcff0eccbb9fe693841af213e5ea97c74255cf78caef05b5c333c", + "fa869704b0cd658df32859f9c39c4758d63d07a5bcb1b89d8a650f13723e09512db19e519362fd1616ff9c2931fb1ae1", + "ebaf8055f0b50a2940f355365cebd4cce547351bc3269d15e654e3fd8f4114b4ed1c2c86c1f8946bff4372f607ce04a6", + "ae2da6aae51736c0739e0082dc6e40b9b837210d9b89c3c7836c4353ec1426c5eb623ab1cdbf4950d3ef08dca449b181", + "9303a95a7f774b10b45922e67e1f4ea4262036a0f7fc6d7684d0ffc7bb8af858be4d3ddcce7bb7ede1aab5dc7239c32b", + "48c50f106e9e5c8abe13709796fc9475d15146e4583a630c333e03c537bbed82e3fdd995a35faa6a39408bbb4de650f3", + "677eb2d2c478d1df4e4c4526b6f2adfdfda823a78d9bdce68ffcc53b51c7385467d86b44f51e00c7b93ef49d611c197b", + "60bbe0d86e267db4499e80b5086695f9548b551698853e6dc5c269ff443c2faf01094ced08122fe917ac745bcf9167b1", + "634951aec5be9bf3ffcb76bac539e18c68c32086cce136234b951b7296be926778adddfa12881298f01b4c5395dcd30b", + "a2a8fe4f0f49bf109f356ee64a3d2327b22f5665e1b4598545ffbbbaedd6b83a15019a226446846050790e4a82390cb1", + "c1712b70cf9c560ffa7732f10340908a459983fe945ac52f7a5e2c032bbeed266e8d87ddb758d1aa1a369a835b640083", + "71ba3a1f425710378a448ac09af30215ef82ebac92ee36a2170e8236df7472ee34ea457432fe7159ddbbac5fcac6074a", + "35671f92bc408566d5feea3f5b40acc15fafbbb028fbac3ba75703bd67cac291c89a4a5681fddbcb73bd6a3c57d80a55", + "e6c99d9df949c9c838521b10efccbec1d477f24106270e3f404b924311ad0a980e5c76bcfc97dd49c209def6584348a6", + "8f43643d2c5cab090c7dc6322551758ab24e7752d3aece0f54f84062e487ad06ce73dfe8462c21a75043a3044b22716a", + "86c9a0b7c05609b87aa033ba84a3caac8673fbbb30988a8bf08ec29e837aaa2cd286a75e3efb23d625298ac26fbeeaff", + "5f9ef7622ad76d9fe0e54162035ec80adc38cfc037e487167453cfbff5762892f6f644213dc0900461cc824030b644f7", + "82aa3a493c757c10642f18b0d2c9fc8aac149460c52aed421a52b0bd3375891912aa9b8b96fe1d5043f1bbace8468e57", + "7bdd9da6f2522203d626dd92e9ae86cd34d09148ec13de3e99baad4f03dae30e5bb9b61a0d7448a484c621360292c4b0", + "714fee42888779ef61ab3d9070c50d036e21298263401a01449e7dfe1e332c12a873338837bf520ca70dc67e223820c6", + "41d1f3202d615686c8a93e99b2464a3a4ed33502960e931ea0a1359bc0d7b324058e6dd4319b473b3239fea0ab0dfbc0", + "70aeab1154487423db987dfcc49b3ddb070566217265355cfe369d59009cb4d421a04dd698df2784565e5e399b5e5a03", + "df3ac16ddc84b701b16d6de7cc0dde96fcad5611e4ce70aea261b71c72862dd9aa0053243417d1ae99b2b7662f9f7c40", + "cfcada0c1dcd0ac88dc68c381b3d70b3c684cac55be6b3deb3d010260910540e3fc55e01dda4b830f16fa0ef1c5d82b0", + "133e10e620019f79a67665a343586482e142787250e9b35506c3e3b66a745b6475ab1de8e4e801feb413bcc51548b326", + "530cd917d04f302e2da298689f5fcc90a9aa0047c823c873905709e404dee10c1eb79e7d6835c7417ae4191980639bae", + "a2b472e47feb5a6570dd58b95ae170ff91a192dcdecb1bc1cc70e214a51816db4f995a36fad3ba59da438e8cf0c1554b", + "2e4e5db2ed86ec4e624eecb7c97e19bfaf8084e5637781c5dcda0b1893d240d340e122c7886fb5eb815a64cf7ee91b30", + "1a4f43b0175b5e5cba118e2bb12131fb402b7d039364a0f736226cd8f3350c82618dae2d536672046f9e4538d7b991c9", + "2976c4948dd90223669a76fb6589e57643b87bee5f84414c5836b8d11be0e3383200bf71a7c684f61e77b10ef74a051c", + "003c01194b02d8bc27e86a87e0f3d20ec8f73b50ef016e88630790cbccba5b40473ad5b841af42023d37a0c97bedcd2a", + "09ea80665108b1d81d4eabfb20f2244c6a95d766d6e0569b7b588e86b1c7ec041af35fbefcb63e44923197b01e7b35f9", + "ab7772e9ee3ed234e6b25f8f1ec83e71d81ccb3b50ab500ca9c3cc1bf5a1d1b1e510c4bceb1412a6b8f76e028488a301", + "705de94139c912fbf5206fb4e25e21cf494693b6d742f415d5f612d3367e7045f4fefe8f434034dbb5b9547512673b53", + "73901bffe76b302dfeeb44f99e5d67d26cece0e8e7d2bd6cf38a3568a44b26f50b38a640dc19b27b2092397221cbc624", + "fcb3b5b2f653e4ad52761f5318d87c0221afd576b4c5284a3ee9deeeb60964e71b2097cd5a69c790599b81a9cb96094c", + "0157f14a737a42fd71984d5315d3f45bc60e500768cc3cc67631467d85f5fac35de341eddc34d67cae0be027d493aed1", + "abaa4828c22f9b759c9d08dfe9d521658d90a5ab0d36c218f35d189dd90d2a5864175d8a9dd967af7c925c1141ed2739", + "471bb865c4919443fdbf5b1242f2a0d4b1844d71436bb7eb10b4a16c25b2ed1ba328a0ebc2c54f1bb837324d53eb0c80", + "8893062264263322b741eb1e59b9342dec9c9ac566cbebc067f81ee1aaf4ee1e1e2a65ea454d491647d97bbd66e7221c", + "14656e46c052c373e3ec6973b92bfbf3e500808ba3437b97674e9895ff4299787a845539851cbcd529855fd255e8f741", + "e649c7e5b2e83c361b617d3e8445ff7aaf869038d086acf6fe869aec8402f26cd7179536f8d10191688fb69b95a2f635", + "c3df8427160197cf1e9f71def9a1e67cff7c57d649590720fb11b83d30245a654c03007f219bb11a2f6906f47b031abf", + "2cfa1eefc4d53b08e3142b78860becc51ed759c045746ac998a0a9474b994a4cfdc54de9d6db428f2a289b26913857ec", + "2af353a8c8835f6cd58444daa0a5f7284fd909848e181edde94491bb715a2bf6c7c141234ee84dc12fd3b65921d52493", + "f14039e20bc2283ab72f7ef423d8466d92617e9efb3b4ec35b4b94a93231b6c524c6817fe5b7e83aefe597c81834c132", + "91e680e587f1288c38f3ab5ab64b7f8d8b088c2500847a076375a1ab91d326c8224c387c09ebc9481343adbd1f7ccf97", + "3010d06978a08ab3f77ac955d982c5f612d3dfc5474123564be75c6b7a55286aed88b716957689b6186d9942ed407abe", + "1f411cd6eaa1b0ebf9dc107b937bd7c56555ed56424c0ded47c70be7b98303a5da7fbf1a67ed71c6d0c61949b94d7315", + "ebf54cc29cacd2529d7ce34e983d93b436459ef6024cfabbf9b015e5b5911b36f25afb0b6c64ea017b1fb6a62596997a", + "059e327ff689985ece1bcc0b6c3f958930abade7159b4f2758e9721fd32d574b2d6861bb9975d7e95b693d092d391a47", + "dd08a94bdf21b2a31d93969b0f3fa35d8740830c58304fae9fc40bb1be6c2df34053801e9b06f6878f441a0152d88abc", + "da5441a006cb855ad65e86d21b541529a73cfd852a328c8bc8402988972f78d773b3531129127746fb53131f03ea5dee", + "396d84c9c1a2ee76b0163c38533cbc8bc453089e87b9790a62bf5175e614713fea4f16378b416fd8650351345cd44c07" +}; + +const gchar *SHA512_sums[] = { + "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", + "b2396a002fe7aec008808687d7cbacb340b7f7a090008382f3c95870f6fb10415f61f5737c102d4bfec58fe525407ea2001e761dab1da8a501d9523921f0ec21", + "11ee0d7b40a7a4dd95f63b8c2a9a36b77daee5ca7d46fb5cb7f871db29650ce9c78306ec1fa9c4075ad0615a7f9e63697dd05cf79cedcdecc82cade38ce7638a", + "d1eb8fca18f1ed13c254f228435ba23ba203b42d6fb38bf84aaae54760a3964e671149b5d10317a0d3ecdcd0021053e6c596fb0b05c33214cfd5455d325ab53e", + "a4b96da738e2cf6a3d127a0ec33725a6953aa44140ad820415aab4ab3d2baf67d7c260b36d3c6d479e85cb3b0d00b54a555e41993519eeb594cb7796eb9aecec", + "c9401760fc70ce01607f7d635a8b71ff2985d543ac715e772c2252967537772392eeb9884af7a8685b099628df73650b05b5511997eafd0627c8a47d5f16cbf5", + "f8243bcab27b16f47c58d10a486775e02eae948cbb650ff22e68e501e41b78a0784abfe67b2992d5acd0d5ee4b18e495870e1189e4e9f256066fb1e28149a97d", + "dd8519e311bff211839edb8a822b6434e15d2c4e3beeb529d43646f7fcc710b393f4f7a6c928e660817e3fd70b280e9e7128a6d3b0a431f4f4dbef4b1527f35e", + "c643d169d3e822e42f2b60d2bf48b36d6bf1d8d8bbd0c18fb00fa4fca79faa6f0d3633a0ce7a2fd62fa332712a45feeedbfd4c5cbdc30f743979aec79fdf6286", + "bbedb9d77e386908fbce019fed3f8237b6c95b13137948844d68347116d2caf7a495a9f34af79cd762bba0190e1900afe3e922b5162ff77f265ccbd275718183", + "b6084d61c87ea222d8f7506fad7b7250741f34ad8a075df75c18a31ef380385587474991c3256cd8e464c0594d45c6d1505ac5fd50289731089f86bc1bf4cd5b", + "4f4fbc4b5702df96d75ef959d5aeb32a7c74dfc14358d79a473e92bc16f4848262409f35fbb2d169ce7b7f16cc9f5d661860c6393c0ad2a2b25907e177324573", + "1548bfb55f25295008b7f6e11cfab72bd7b4525902897747b585e94c7dc4b9baaca57032e2139df5fc8fbfd5f82115327db42ee15b87052f679de6a586eef4b5", + "51020dc906ee7a3fb202099269dfbdfc01e2a8477f474db279edc23b90da683de99b7c0c5367086508a89a5c76ad1ea8ed05456ddab592a5135497e92f12348b", + "a7a3e5d22ab9ec75d7e15aed5742d4c83569279f2f9c61076ebd9ca13f3c8842642df2ee03f81646ac1dbddd29a53ef816a350e662977c73b3a051a56df01965", + "c5c60fce714297d6ea30f078756b33b11bed89e69513ed900a91885c14141184bb32b65936cddd3432ace744bdab8b0fc46b0542cbad0d96726c5325ab6b148a", + "29e6100e1107481303663798fa0195a4f56cd410f52087a9b877c742fdadb293473d91b3ad3a6606a75f3b8787fefa68e94f1129bad7c77f6df251fd5b82d96e", + "bc26056e51dd3ee0747b21ba6fe7467a1256b81a595d4165e33b13810a0807b9c04b98e444aed600afff7bea013e362657090b41a10652d5d9dc8ce766f4ce7a", + "40c4a4640176132297ff0b5db944e86e0fcdc823ea2e3d30265f9889edff943b63839451d783bbd853653956ae6e9763534270539deb4bb77d814fba5f56a879", + "015e6d23e760f612cca616c54f110cb12dd54213f1e046c7607081372402eff4936b379296ed549236020afb37bd3e728a044a4243754f095498c98bc24f77e0", + "55af8ef14b57edd35334323adac3fe07e7f4de338c05877f2cc94a11da5b4291e2d4c10f1ba7e1c01b20648e8c8dde2f3df22aaa3bcbcc888e3796b1118e6679", + "aece539289caee7baa30fb7915464d12d4d2929acfcf0e12b1f81d76be8967a83b051801bdeb38a62eda5bad70cb98391d8d6767ff3f78900c18e26d9c829331", + "bf08cdc2b15698e4cb5f7ec837a7fa3630a0acac52d866b9ecf7e10083d4913bd46afdc91216f922fbae5b6e58116e9fdbde2f41dd32a0dd57bddb0455a305fc", + "5049280393cab13415d832fc7ac370e99dd413fdb7a71c213baaa98f8c45f84f892757d1b9ab6a181c84ba880b528768f32d907e89f4e0e003838c4f4f005024", + "8d81d423f7c11167a3f016489758ccf4fcb45aa1c916566352f5a0a94ea565d8120c868cf93b38e2f41b16a350fa607edaa288017f541ba36b45b55262efcadd", + "4b4c254dd0bc5c4a1a70900bc9eea84c852e11ac3d16f87f1d3aaff0478e46ee58c264d4aea58d2ce1b08e84bd7bbbf032e99521f60fcec637abdb243977dd7c", + "afc85167cf33d21418e021a4946801b91bc103c8b2d4a53e01b2a237c293915615b9f2504d117399a4eec2578683c91304a608745db331a2dd7dfa9ccf7352ef", + "a435a6f9d0bc4b66e3b62becfb3ea1cbee93b78707847e9219bc62327d9d8aedb48b765e99f5d6b334bf76aacb879d796b998b855bf6ee7db826ac16e4da693f", + "bab93872f631b5dd2be09ef4aa1c80ab92f0f3c0593c901a46a04fd2a19e8cc36fa827380da7fc663aa79e2421a6256b5b7106b15823ae49e674950b94747883", + "815fdc6d15a1ab485f274638d92442af5ad5db11200b67180bc29dcf70e0598255503431e13c7e6dea4488402f112c4574ca93df4b8b0e07f28ce3d5ff64393f", + "ad6f2a6ac5dfc9ed273c1e18f2d16c14221843ff9c2092a30108ddc127cc43c3252f821d599a5d0bb3e66eb40b59d3537ff5a90f3356f78b7075bd9a671bb30c", + "b13effea3bd3444f360ae4aaca1fd334b23a46a9d8ad64bd88de51589b80a745f794456e612921be4f4e819cf2f7661241bcb2b19afa9917ad87802008243f8c", + "afea68e278d0da3a9f07d0591dee8acee064de85ff63644f2da7e92947e4c73fa7ad2db9b2d2bb1d0b27fe16cfd274d3b230d7fc89c3159be40a8e5d2ef1fc5d", + "ca148b59a34ca4c558ccce905d557babdfa9eb8264097cc50f230d3853b5139838b52d888937e0d1de33a9c6bbd11fdfb0eebb7f805d2c090f0c4aeede00df49", + "a73db6aeeaa8ec452aad71bc56da4467d4530f67ede3cde54bbab5081e732c76ea550220125fdaf4fe874c448fd7e6400f5e1a80c3ab4f733bbeac0172a833e0", + "282a28dad323190b3d2f11035cca91fdeee4a7b0c5606e28786055c5ad96dc03ea7b05dcbad19a653fa073aaac50d5170e5de5eaf266a3fde2e59ae4ad94f2f6", + "240b9cd3ac60c56da080baf790e882eca4ea75644c5967ed8266d0f1946847f0e3e243bf1189df20c990c94683d15ec6e903ede830e57e0727ef7e4066a97b0b", + "2c247a65e8b946837e79fe8a0918a997e50766b967e0d9d14f354bbd58a9db4a7672e92649a49fb2289035a14ed0892d7592a1d269b672a4ec8867c3d346aea2", + "d7c26aead784f5ff1e87045fb9137ebea95f06498da0c2a1e9ee8793fad537b1b41090e57f30acfe43594b4c6f0184d924890ee67d92615abaa3bd2624f236b1", + "4b29f8d8420e499011e18d64c1e90446c8ab2927dd774b022fbacd7552a888fe48a172679562e69838099b6761610325d587ecd4c94a8d55e1b3ec44f5207736", + "3e5a0fd20cefab3b91f0e57f2f874601305e6781c154baf4c8e6a4e09557cb404df189b0b6a8cdb655d59ed88fccf29e6459950841c739106f0a7731e17a1053", + "f07aa6f2f93be5a8122f0ad8d659ff66488f4fcfbda7f77b2f56eee4223497a1b31a93d66d251159dac5ccc343a15a85f73e5814eb7d9baeeead010ba751222e", + "edbddb6c20b0f7d250c1dc453898b0b110c819754348e8b2fde6889dd680bec51c686ba81a52963b4a716def84b3f3f4e911191c3d6c73cc7f9e060cfe05173b", + "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", + "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed", + "5e1e2c9fd51c753fe537e43c1982035b2a86c641d22a98677af89f442bda95a509a35c4fc2861ee4ca5eea20e6450902ecd116a95976b96ec37d0f58be6f84cd", + "162930d5e90bee1c86b56fffe4bafafeee94815d343bc4184f87f3ded2fa4fc44c981199d0331c79e41eb1e2008bee02639e9a0764b9c39e00a8cbcca6f43979", + "1216c818be9f2bc1bd993d29b6931a400d474ee439e5824c879e1030206d4698daff0f51977c8e701d8ffd2d0cf9a300c7f1ae547d93058695ac034fed20c3d7", + "4039837b00e37ff43c29585971a68f89414a6951aeba2ae692e6ece11a6a3e58b9d2bad15176c918aef644a576a4dd4497cd22884067f27fadef262e79ec8a9f", + "9d7c27566c55459b1a183f2698eb5ced70a298a73e10072deedc3a200e0a391d7e5fcf6a802aa12cb469cf70f928f01960df1e8d7471c0b8ab3c572403a30098", + "b733d09fbc2b5266f4d113e1f260994f58771ac555145ae33f737ae814adf91738f37b3a982e6071d226846261c6f1440655d167c5ce04df4eba23f62a661996", + "e94f8fac70a3b7a4c0d29946e7c6433d29a749cd8f165938e8b13dadc0901b198ff6b4395c2ac802083dce48422ec3aa455d612bb379bcb0e9ff5216418acf6d", + "0039c0e979793cfa23748b7cf7a2e3982eba9aef9a301575d50f332fe20a960f300511460b6ae7645ba9b656416aa781e833ebbeb6ba9bbe5f7f643c9a156d59", + "cee648b7c0b14c531a64e6026e97adfa8d2b71f1c89985a7bac502b552eb4986bf2dcccbbe6e68040818232398d70508f90d37ec6576d216b733a7b52de78bd6", + "f96caca679e2776a8933ccfaf848f58ed1de564fcbce00ddccdbf7bdf9819f1fb06574c34323009cdb5b0ef430d90e08e4da17953d34b72bd87373de840b0299", + "7c2522efaf0251854ed9d68aed3ee646553401f87c162719b602c676d5f2f45391f7fb8d2619d3e20055435cbaa78defd51dbd95e5c351420dd62e2f53cc77d5", + "ae7572c1f8f8e89c48ea25401f79942b8cb1a0316409f29c957ac0de9b3edec509dd29baee2cbbd7fbfb81dcda750ce59d1ceed9234f4edca8194656f00831c9", + "2fbd6b7ad16da77fd307b4cd712ed70d4a21313f966fda3b6f60d73dd3cab0aaaa6c9455fc4a5103f99d80fb0490a8310c603bdbb6b925ccb14c87b1e9c2ceb7", + "3cebd0bde4ac281151020e3c944e40dc3ca9203fd8af0bd2009ded0ec50566c53f630aaca6ddd40041b1c0e6e77df43b503e37c9fe913711c03a10ef3785d54d", + "3ede082cea90fb909f21a299c1bd39494f44e9f4f614cc69d080482d12c39c6082748f7253fe9ed80cd85f09a11db35f68b453981269f4cda03728d936ac2e97", + "b60bb7fb62fcb4e673dc4c5b8c5c8ec3a9c31569f6b3425043cbe7814508373c5a07fad5d27c090ba61de97a1a3596370c77feac711af76c80f7795004de81b4", + "e7a60093f04ca5cca156ed165bb2b4cf7cc0bc538240fd121bea824f7ea309a362d1e5deb15550fe7ae56e533f99f290c5a570913e537605c53dbb525284cf54", + "e4d0de74f09f714ed7b97667f4c462f3b4b7802b1cd6698fd7d1ad97c0eb09bc39fda853f1fcca9570767738e576215bfd7ee76ac72d1da5280b582296329f24", + "f02f601c2c27fd84b75a643c8ee26e6d4421140f75d2af30709e621ef198e05615bd6b568a4f67c70f9fe898c7cd3026e3379dafb01d969dacb20049d62c4682", + "291aea713e6c8567bfaae8fa6b2711557320ffeb44ad3ded077abffde0bfec8fc9c6cb86aab677a4d99b6e150408b7a8d4bac9c876c9335e07cc25ab49162767", + "139f3f4d4009be42ae62422718bc65ae0c416916b6761b5c2a80b2b55be51cd243eeac5caee9b2bbee20f3e55a91365b86199d3fc0557db3db979219f5839bdd", + "187249bab389e589bef61e903e2c7e016d94cb0ca2491d07fe4bf2e0484ae5640145de666e0cfb577d4d60953fb9ac75db0c07dad4e3f7dfa1bc30619c88cdfb", + "bef11c0d3c5267ddfecacfee56913fb60679ea346470f6d045b48535df4a56be6edd3a57ee9c48045f8a321b4fed4cf613474220764998526541b5ae401cb1d0", + "c40ccf026171ba822e721e2ba3862cbbfd8331db99f4f580bd0388ba75f2f89b929a1ec80fc19945c0ef79fbd5b92de0cd772418ffd0c8147e1306680a9663b5", + "7c35d4fd4a95464d5191a3f5e9f3edb8893c66d5891dee0a53038a2222432a6ee88d3f887e1348beab0008472f8df84d178da7c584a00d2db43c1535203da390", + "e2de986a6b5c8ef705c59a8eda38e1855e6896e948cbdbd6042d934341a4777645d39cd8969f53415ab900138fad8a8543bc87c7371d32bc9c97566d0774aba8", + "b13c9913ec130f5bf2e40adc283a96ae4903d71782279cb8794e926abc82937e01a2cff494f4d168506341b492642dd0c04a657e016f9d8d8b57b20465aeff72", + "38e89130fabdcea2f555f71ea2094005cff7e039b4a7421a7b40d56c457705e857908ec53bfe463ece568d75f75ad959868d78c5baa7cae309ffea4cfeacb380", + "ceabf765aeed49868054c62e3bbc2c00b5368d3714b7c96649b2edb26f0b6640c69b8a04097dbcdb9664cf426f0efab7ecd8269e3cac7ee8b8784424c3389d0a", + "eac764653fe8bdf0a6f876f8c27cb9dd6b986974a405e383c840f2fa359640a580905ac37753040b8801a0ae6835d3d0d9295e9ca40bbcad903a2ece091bb547", + "a5f601eda3c483432c8b34af1ca5a5b2ed75801936ec4bed7570bda19cd4a79b2c1f24e505df4ab2b91c43028555358b44f6246062ab1f60687a98c49c5a4ccb", + "254efa3bd9575a0fc856d53f8542c0cc64cbf4891b1b3ee97060d596a51ff8471d0186868af59ca50d73b8f509352c146757a5bd86f59ebcec6ee4db2fa2fded", + "b439ae6bf400df4edaea40570cf2e6478b031355a0491f94cc213b345f0794db6773cf3779e300dcf12d42a24662a9668ecbb79c87f888454354c440366f0f1d", + "f99d86d1ea7a5dde3fae3baab3f6603b7805d6818f44b724902836bc857cad8bd9f8626cfdfaff8d76b86dad3f69bde28abbe78a0dab090e6c501166343d99bc", + "5b3f6a33c7f9e80d98c0d16f18ed989acb2c723e3f84b929f07cd9eab4a9a20e736aa12ad9808daf69310c61c2e63db15904703a9fd4e3ac74933e55772ebbdf", + "1d9e66a96556fcbaca8ef242da4dcdd83d1339369bdfa9d2af0c1940396d43adc302cfde629bdd0b5ae5d8f995a558597ef11bb04bc818e807dc5b0ac0d7a730", + "3b9279b07e9574821d827cf1985039948c26329ea5767138b06b2e91b01ad64475dc88985e5f1c664655343237d97fb884e700819b61e1cf12b7ecac38207c1a", + "5631f6bcaeb487bf843cf54e12cff6d72ab5f1786bad51d9e90ead7f340387b2a271cb85aa417a0898b6a9e4f33eac155e5224152051ca21fef4f6e0b1c76a49", + "5994362806cad2c71fa69291840f5798365b238cb710aa7515c36d059e96009bfdb41155d8f9ca008b7b536ebe1c1e49b401b5334a75a4cf8e7891f3907a864f", + "bfa6a6ae5248a4668d4dcc50b1022c76d04e6aab799a77f2641e34a8df9f30a4a0fb29de6bde727d6941adf32775c2739eb4d2ad7575661a0010ed957deed45b", + "830c371d35a9590bfc897ec2d49ed52ac1df87dcb1664eec4fa4ef13bcc80b4f8cdd9cfb29ffb32e01d3e35b44094dd43a1df0081d1435b7298a2ea729453c86", + "f0fd5c15bcbfa9041e1c53754ff0b5972930be7fee568fef02de68becd088303e4dd6da8a204bb569f0d7c73e0c478816e77cac412681ecabc3a371d5afe4b56", + "b29b5852cb2d3523aa98d0ec3f94813187c2dc0993d35be9f6247810d35bf4aacb6ee5f993fccfc8c9d7d9524ffa8c01ae2042510d3ac950ee62315235fd3afe", + "1064a5e41eb6faa80f2aba180fe59c3b0f237c43d608b235382a9b22057f4d6ac91a316c4582bfafd4ea04ecc427eca886860240d88ba8af9508064e71eaa52a", + "5574086049660e7cd1d2cd4b774758df61e8499ad2a25295322639035aa4bfa29fd1e33a438e74ebe79fd0dd17a90cc0f88e9282ff5fb2205c155094057bd27e", + "07c40b39525c7c8afbba33afb909f538aeb400286488e77cdbc195a7d135dec54d419aed450b44d7ac3b05878365d35fdef5651d6d30c2d81c5b8fb106fc3334", + "2174d552a8786edd25c3d6bcedbce5fa84a80801845ac338df4bb28f6ac51f6ac9023365bbe9b21ddd568a4465ca6ea8da356286f5b2ea627a67d8833880f78a", + "5e6ca770fa9cee048a8951e4598df26d4379111b12b62743cbae5b4b19c198e9095df55efb7f478955f3ac8e060e501a709818165b8f3c73909ea2d58227412a", + "d52feecbf5c9a9fd6097cfa06ecac142cad3421e7dab3a04ef8dbcba16e21e1a9fdf2c3fcca1f510815e194e71c45f71635427fea15f7945ccde0131452acdc6", + "1bdb98a3f797482f004e98597553cc763aec2f2896f9fb0f7fc679702eb043849b6ba3984f4ed304db6cfc82ba222215b9b5dd991b6ceff53dd1f8e67759af92", + "fb5606b7f39828a91c0ec5ffb0ecff985179c612f3c5098065d696ddbf525c8a44514b8bf05b9dd0d396420ea3bf106a0bc9d08b929d44ecb83796d146eb09fd", + "3dff123b608bfec0b02118a569b55b80f7317de4bad125a9f897a5ddfff0ca8a1382e9a72afc79ae80f2cfe59e7712f4713e68663e3cdfa0d23f5fd848354523", + "d47d6576adb48d7bebac60fbde84c92bca384318e21ddc8073ad423bf2b7cb7b9939ffa0b304cd6a522186a813acf0ca8eeae6b7a01755e92662f4fa3df0de71", + "293e7812e9fd6f39f9a81e11f858f6743e4e31553b7251edf6aea5dfada1afde12bc1578572347007484fc0e591c1fde72c254c960cedbb8eaa7ac85aac3eb7a", + "1227a9c0d52a20f00d7f085e95416b3671ddfcf5b73dfd7caf7c64cf19b95d8b762a0a578600e6af971f3b97a10d7bfaa685460a9beb92942c706c547cf813cb", + "15e2c21af9d9209606e728b4ad464c108b7e386d21da4344ecdfd03cc5827432d161b14ddeb621be6c2861ff7547e011c63c490f3d809aefac7ae5162cc6d655", + "c54c0de631c7998fb2da9d3ad2f0f8a87a5f658c292ff1e76443f19a8d51e34e0465063e49086d9c891dc79cb2bc08a9611b108ff928093e6b8c985d14cdb281", + "33b2ff02a79184ef6639867bb72bdaf0c93740c36e1b5e26a0f3db94d2af7bdc323af8b10fdaa57caa08b2ba5e17f4236753e657dbc158bae140b71955bbe120", + "0462f7739cdd8690faefe555246466bedf67b7b9b7a9694ea92c28a4af4180f42cdd7839d7db5c1f8baaa6c6340b9efcab31a8c62674ff3db8f1cca965011230", + "b3f4a7006181556befd5251a56543f14e9aa479699749f949d038020111bd305a679a83dcf66e66460b970da6cccd67f1f3f4c4da99d4e52d9ee34dcad7176c0", + "bcd2deaa39624795411746e1e33101b7e44e1e9bbec7ae104f0308c6a24dfc89271a43a547a6484194dac6ab6614e974be6990ae3d8d11bbe65d27ea68ffc144", + "b2700cab398bca05a23850a5f393ef9c71eb9cead13036e93b66cb2cdb288f00e0dfe35e1a16f1039abdc7e1d7393ed3df3eda7e75e8d0de28c6ff68066b907e", + "3e99f7ef52ae5b3eb4bafe745a7bc6170b5c4a0f61f5a0dc0294254a1e87543fac10f46ebdc29a1e8ef5ae715636e0aedc578b5560ba55365eb4c28b226682ad", + "e2e67d7cb85acfb52791fce61b08d79df6f90a92dc8e0cf26b5bddf3a7deb5ce6c23a9098cb066ba065e6991a66d9449dc9166417ef86001f48b45d7718bd124", + "a038eb72223e8fbcf4040ea988b53f8aeac0b6029a85d44182c4742bd5e9e454e3470c19ba2dfdae71c2f1f31bbf543e704e0cfa55e98772c9cc056882031bad", + "82a1d1c2764f32dd54d242b26d82a559301375e74dfdc149bdb2a3c27b2fe2645d85b2aa8e6a892a846b157bf3119c6079b3512239043de0bb77eb0612ca6dd8", + "3d04e36beac7a7d845655bb52da45d80f7862fd989c256b09d6cbf654c946b8b40b0432ea43a6b60864b1addda95501518609b690265d969ee909f07f8a02f97", + "e37d5080c16d8a2ad752796482a570759f69d9274f6b55d11ffa4b3b14350edc3dff02f83fb360086a5d53b7ad68020ec781e22a05f3984afed3002743f1e3ec", + "b3133139eefd7742f993815f8171c611209b2e76900e753517c6eb6b6482ce8f98c7a2a7e02e5cf08680115884733ebe72a7cde5604aff31e00b4d82b5fc6ca6", + "b5ec00879e0c890d570c4ed0e93b32e92579df18350835db4333318e52675b54b18ff156195c9808547ab72ea36a6dfdaf478a9360668baea162ed2d665ab54e", + "1d892e3482147fb943b8029fe2c4b8e5a711a06993d6d5b3ef66e691b2aa72ce2668c501af83f94203a40b4c37465cede2dc127b7a2dfd5e300453ecca177a39", + "ebe5dae73d7539eee9b5b281cfc36b39a749f40a7e43d7508d8fc535d3b3bc9c51bf2815b63e04ca26c4225b099cead47f37c5524e5379de221e49c59d870f2b", + "67477cf7b6f426399073619c6dbb7cb0958e8e7b41e2c3591b5a716c69aaf13ff37d53d5d8baa93dcbdef3c7fc800a0c379767ce09f714983991d3568e3265cd", + "8417261aacd1ecf031d17fad6a4ae726250f62b6ef4986fdb532086b2c2fa8afea21739eb9e949662d7512c11bc5cbb558f9ccf3bf4e69b9285964edbe0d5a96", + "bc667649dd008529a9d5fa3e8bde8420786e00a63e3481976811b2e9b395df6edc6eb6182be7d91cc92e6a4dae309456a5b3ba6754c1203a50b38d287ad7ca7f", + "bcfe7aa19ae72582d859539c050dc53f18442ccaf1a08415464a669b72503b45bdb13553653ccd20399b74069f3260d43a80d6f91dced3cf09bc72b32f05ab89", + "7d3b8dc4f5dafee652db9f134111fe3d7be1383491c308a24de6d19c85f3ed3b28543e78a360f1c7dc90ecc3f4c0731293e3523372a554af290b3e5720abacb3", + "3af3fd8d186ded54088d93099079679f30b33b472ad9c45a1ef56f66f55d324a8ac19971f7e5b585c4355fae0f5bc32437376bfa240976975f4b9a8bbee7897f", + "cbe6405ce8db3c3fcc956d76def5bb3199fbafa808cab6ee399af30998b36f0c82620e9ff9d48636157aefc92e1a4526e646c885c66f4a0a7617f4bb51da5e5c", + "4b29415c4bf027830612f3a83db423949535d6b7d036a5adce3ebe824ba200037f517de8953c000d5d2481209948f4d4b8cf90d799347b90e79c6f0593169ada", + "b0cc887af7da5630f9d9771f9c8cc8539526f045c340e08e65d6fdc97d20577d57b192c4672bfc6dfca5c800933ff2fa07d160cabea90d28ead54c05c3b7a37e", + "04bcf2550faa52348d1cfcd971ee0bb7f639d68a19c3305a109fe012e66ecbdf44c57ea0788edec16630e42247da4a3fc2e7eba13e760bd4d401bc19f09071d0", + "3a9c39158f01951db962e4d7decd60cb250f14e041c1ff88205f6c9b5daad930d2affaa896f8bbf586cfa81506c8cfeb31405b9eb1c9be6ab8b2829408219b0e", + "b2fac91e5eade54d6100b7fc4cfe42fce3e22dbdf51bd613f4e8a3496ab6101159cb2e559aa4d0d650209f2eec6a02f63f15483b899dd4e5e933273b31139dab", + "5c5568e3ad468eec55a92ba557a57ac03a6235fecf1cfb55c09796afe3e927f8f9801d1d07b2df4060470bb11b09f83f34c5122eb887d9a94c0f5f145fb9e56e", + "bdab9cac7cb2ab91d14950a32e0a62c668dd91e2b8754193d146ea8672d29222c6ed5c2ea60f0a7851eb7277ee7f9cedc0489f892adde2a04ca80e038135f198", + "af3ea76bbbcaf5774bc4958b07568c837f948a5daf8a560c5755149a70614dcb64faff186217799b7589225076f2758b8cc0d84c075a1c752a09a826004bbe76", + "3b50e163d5ba96a2e7e3329340fde381a535af02fc517168a7d6d4195cf272e61768a1f3e5d45868597bb32c49380f4ba21e788c92fc6114729a44b4706ebca4", + "37dd3a8ad218aa44b07878828283301cf39da589111e5fb65298002c3a7b9f013c36128fe66f93ea72dad5d99ff42d774ae999f1e8d84d3c1fb61d78f478c329", + "670b50a1f26c26febdb8fa31e1bc9f03afe3f725bd7deefb465070de06777de9ae55479d271961265624bb25c685b48e42e72601f52391986f2b97203d983797", + "5e2c8d428816d02642bb094f9bcb0d8a3e48108c4549fa1bb7347d0d15a3d37bbc3af5ce8f9279616dcc802f142dc0e246dc76fc182c103747f5225da8cc4841", + "8e2e77fdc06eb9324f7b1d858ce6442263d880caf256bf9d62970f1ad765e81bb6a95a5bdc88fa87b37007872443952b85448ad4dbcf7ff012e2b1d44f53f699", + "8937de9272ae5f8a1ccece91f5cccf118904a5e7fd21edc9d077a6a1d312e621f4cd96f4a950b74f2f481985495c4fdbb8500c2386aba7d133486931195a06ea", + "cdc9687c2404ecd21f1f9b7fbb272fed78ade6ad8547024dcbf931258a3f3045b0d644ec402d2bd13ac7e3c883c94800ef001b797c9e5dfebce8aa44f24829dd", + "5719bee028987d23eaf51350467f153e9d440c51e1266038b4ebbcd573ac74b79008566646075e2a1a2b5a6b3a1404450cca32b0fd29dfe2f7cc7e2f4585d07c", + "2eda00c8cf9efdd46f79b95e177cb98b1d566526ec12829ff82da0a78dc047e68d6f0e776715df6fd9aed5df4168b9e33aa015552105fa0a21e8cb038d28be1b", + "d372e62ba258d701eb7fba23617d7967e5190f8114cefee27284744952f1da02e1e8de8c9dd7a9bff520a7061a18dbe99ebf33342670644129ac8190135dde78", + "5c3a473fd13763eaea52dc52e5eb6ac7e5df5c35ea8812e8be7d41293ea8ebea66bb76d8cf58680c3859f350c98b4ad6771b8c6e4cffec4622fd3ce5ad87216b", + "d206f0f3af96718772e2362df47e0f65085033820e1eed17ada51a8c880f41e0cc4b539363fe414ffdafc87cb95053a447f154567cacb94a56faf26423614973", + "933d85bb2e7a3b8bf7437ed6fcc52202d6d797a466c21bc50c74c348dc6a8e06535e8aa9fb2c309e6cb947709992f816dd89f99205909198743848d13803713b", + "e76363cd6d53d7610f4955df2acfc305337f6e3dbbfa2be6c11ac0f486149ec402dacabe810ef305fb4fa06054b03aa06cd9d512149eb52e443de3f9d442395e", + "a3e64c7cad5a7aee65dc47c3fbbd0f52289b118eee07e43e5b997d3d71577995b906a37bc4e5688b5d36e26602276e242e49bfad1f786b927ccedb627fd61401", + "7cea74c5c65aa40575672969dab244911275c73ede90543b3e19da85a038065dd971329c8c7dc23eb260bc9e5df9e6f4e4f29f6d6ffc9fac51d2d8175f7f4342", + "a4ae36fc9c75d72384ca96cfbf5dd3d55750ff1dbbfe01d71088fc86b955faf48cd6a9bd45a8ac7d429ea4eb94a5108998f05b1c69f506f8d429e415678b35f5", + "7f27474f5ecc49c4cc5c8835a408c2137c3063402e893b6fa8435158892f7cf4066ed695053bea7c394ef3877821956a89d94632b32286ad65f6b0c6b3397f6a", + "5d868eb076cbe09c47cf570d3aef8facea44af0898a11b8500161d0f6e402a9112ea2e41e28bbea388c9234529b5fae5ef74631c044df7c218efa5d82efb78e3", + "6cec12204ee0972baeeaffca5c912647af39291a7e2b81664e562ad12a2b17fd4e092cdb1197aa9f1330a0a7c8bcc7f623069d325b21b14a5803515a61dd0fb3", + "fd3393f5c582297309610f427cb14001df921bcfb0a771f37a51e6166a2fe143ca7fd329fccc47ab5766056caa4dbfa9da5f221a4ca054644cbfa939df491e3e", + "9917e3cf093607bc286cffc60269af690f4eb9f704107c906627cf3259de31d923f696628e730283b51513890ccd90c40f4bc2cb762980b7531810bd2a333882", + "95522c31784f34aea08529a4a09a283b30085cbab3843babf96f0b45f406c9b3a76b6373635074428b23e17f4977e9fcd065b44a9161a26b7fe66fd5391d6d78", + "91778a52ce45d4b77f1d91e3cdb38464ac16c880b28916733a31367a3b2015082017f767267bafaa1ae769611f05bb6b60c307fb080cdd4bf2892704e5aa1af3", + "09a1466f07160ca2da1f999236a7cc016c9be9a5f66abe80ee2694df708d58d5b572cd9c2dbedff202b940d874938caad417183e71012b77e446afb3832b809d", + "1227c21bc6e15c7bf0aec79febae2e8787b97c33c3d96c2b2fac1a43fcb841576cc4c806aec038534cbf0476cf90fedc70eca44339523904e37020c14cbf2151", + "2ed90b58e8009fafd9c7dd299547bcdea69a6c72d4af00be9a5f5d81422cfe6f275a00af7579291fba526ea0d872620f72321b5a712e08849493024422d3009e", + "64a10ff891e361e3a7919614152053bfbce6b02c8241f6551550cf704203833c538d879c8631d04656f0e67963b8b56ff546fe9a7f1ee073f0fb92259a702328", + "d4bcc92ceeeb193aae5f673d444275bc2b400116c48c8e70e5fdc19606982f574823171a6590d377399ebbff7ea66c643998b0b9a3ede9c82acef9ec4232356c", + "407d968198d56fefb39af30c26d7af2d32231c388ae8f9d68eee68a5a491be488f21ac41c2cdbd2e5a6ca5cad398662477c070d6954e8bf2447b39b471019f0b", + "38c7a0ebfefee5d4809fdb78d07626d1fbcc7a398fed72a94623c819b8320c2744de1249d5f4fd8a40da86489d9b4c4370c8dd64cb31f072b79159a2403666be", + "36d93692644eb4a082a92e6c12ac7cd91f8b064b79f6f484f40c2ba4a1071516ab4134351661f23794199e60193dae637615eb03fa3d3d988710d0dc67a2ff3e", + "05e6f04cc9fb24de203d06a65911276d3408def644d0eaabea8daa3f05924faf79e8d14161a94e1eb2cf28dfecc9dcc63aa6f820ca28a8b6a7677f9e6f89bc5a", + "b5bdf2b8009369341985a4d6920b7dd0b2bfd088968050b208d3eeef95e2444abc88227de54866c419bbfe008a91de2c6ec7f028cf7161a7335f929b09005f3c", + "d57d75ec354a3ae54aabd4a0e4c1d352426031ae401cbd6d18d5de72cddad32822f057a9aea2f64d7531540832a8fd37498f27ecac24cf70783d8ae7dbae16da", + "9eb628ff8258d6eb5ba260cbc7f66a32d0d35f72eb7d7f70614c0c4d6ba72f8bb7204f8ee704493fc798a74de6659378ba0627b8b8a88630d4220375a5906a6e", + "d992753f9de4963cf53679d6612de1987725bb9608fe23cfd6506c4d07b1efbb4bddbad542a5f4194e6d4744bf6c3eccdddabbc04d01197f2ad84c35bf885896", + "6689fd5d94a7dcb6b20bcda530db758c5d373ebfbc0f57808b95a14f45326478a0cad7a0d6ebd22f8c70e39f41f7b9610ab9b475785b93807e16059ab5dda7bf", + "93893c6b57bcec91f2d19c8668c5b59b6c5a66492b71770e914ff30489a6efa7f030fd42bd342d8202ce9df99c0a5ed56e1e4ab06ae0ed6d359e3b140076d5bd", + "76ca602812d40fed5cef33b7310e7b8bb5a5de549fc63219f5dabb3cc8ca70658151417e2fc041d6fa05484321be2f57bca1d0300be701031646aab039125fbc", + "0c71f03a2b3ad8765aacb895f6a19de92fbf77b0e40a61622888c2886bb5bbb8c3b4ebe4e6abae661e4f0b72aae10753d890aab9d18941fdf18078b77f187d31", + "8e2d159af8fae54ca736e3f3412d7de329631db7bb561dc0e82266c50958f22fdd7ef8181ce62e9632f7443608c1d3405503af23c804083e1058c6118bd8a52e", + "83be1fa27282e68590c15074ac8443f9f53e064ff8c5c2d65304266eab1d998fb23f180f3811c5ec5cbc88597e037f5a7b908eba287dcdbab5ae473e65325611", + "681f00cf54a854e4b2d26dfd264ea4f0695360d0f23c82a024e0403775925b2f2f9f1aed94f123a5a683241c73d4e9b6abb7473787eb48dfefbbb54d0d122a71", + "4ba62bdeee45a2f100f7d7e62482913cc64b3a8fda4c1e833568d98403d0d6a9a788d3980fcb3a9b62599403012014b3f2926e264d83c4167f9f99a1f29a9e2a", + "a40d8ae569c4a15e542d0fc9a2270b1e253a5757bf64f3769ec2c0e6a2b8f82d8934c1cc0450c1cce806b6b876de1fbafcb2e06ec4519edea2fdab9a6f54ddad", + "5430372627c0d0f0e6ed0550b77a4256640c1de9da96c7faa7606c7c1b0cbc6ab793bfd279b505bdce09b46cb7f5d73217bdc0a18240541656ee9888999c3339", + "c9d0a880ded82409ac942823379d65acfc1b11e54fd44cf0d4569eb204e372bb10d4d111915de64163031dc533715b29f14a6f910a3d58662bd13768e31c2aad", + "a326708cd8da2fab8f4b7870dda03800446f520532638ed7bf8177c509c53a65ec3127730ab2f02d3f911927d1f265d147bb53ec5cc0dfebdb68d0f50eb2aff3", + "ea381acd65980fd5eb1e8cb5b25ccae38afcfb9fa1308014bbcc96d9b80255cc8ea8225f4c6fc2477b7af3aa2c61228a9d7a6be1bd92b8687ca25b0f912757d0", + "42255ddad4f1c30ad42e85752bc3685fff22da82dd8ca85f7616112acf2c4644d40330b7e7bd4707c8094d1034cae77a503cbe20d0bbf2519bed7a758817bfae", + "9da644c289075656b5339317f7100d954b49e67e6c3f981451bf7982c52f003016470c781fa0af61a965fc0ae50f1bbc8d94ffe91e10dc09f27dbe5b1fc2827c" +}; + +typedef struct { + GChecksumType checksum_type; + const gchar *sum; + int length; +} ChecksumTest; + +static void +test_checksum (gconstpointer d) +{ + const ChecksumTest *test = d; + GChecksum *checksum; + GChecksum *checksum2; + const char *p; + int chunk_length; + + for (chunk_length = MIN (test->length, 1); chunk_length < test->length; chunk_length++) + { + checksum = g_checksum_new (test->checksum_type); + for (p = FIXED_STR; p < FIXED_STR + test->length; p += chunk_length) + { + g_checksum_update (checksum, (const guchar *)p, + MIN (chunk_length, test->length - (p - FIXED_STR))); + } + checksum2 = g_checksum_copy (checksum); + g_assert_cmpstr (g_checksum_get_string (checksum), ==, test->sum); + g_checksum_free (checksum); + + g_assert_cmpstr (g_checksum_get_string (checksum2), ==, test->sum); + g_checksum_free (checksum2); + } +} + +static gint +hexval (const gchar c) +{ + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return c - '0'; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + return 10 + c - 'a'; + default: + return 0; + } +} + +static guint8 * +sum_to_digest (const gchar *sum, gsize *len) +{ + gsize i, l; + guint8 *digest; + + g_assert (strlen (sum) % 2 == 0); + l = strlen (sum) / 2; + + digest = g_malloc (l); + for (i = 0; i < l; i++) + digest[i] = (hexval(sum[2*i]) << 4) + hexval(sum[2*i+1]); + + *len = l; + return digest; +} + +static void +test_checksum_reset (gconstpointer d) +{ + const ChecksumTest *test = d; + GChecksum *checksum; + const char *p; + int chunk_length; + guint8 *digest; + guint8 *digest2; + gsize len, len2; + + checksum = g_checksum_new (test->checksum_type); + + for (chunk_length = MIN (test->length, 1); chunk_length < test->length; chunk_length++) + { + for (p = FIXED_STR; p < FIXED_STR + test->length; p += chunk_length) + { + g_checksum_update (checksum, (const guchar *)p, + MIN (chunk_length, test->length - (p - FIXED_STR))); + } + + len2 = g_checksum_type_get_length (test->checksum_type); + digest = sum_to_digest (test->sum, &len); + g_assert_cmpint (len, ==, len2); + digest2 = g_malloc (len2); + g_checksum_get_digest (checksum, digest2, &len2); + g_assert_cmpmem (digest, len, digest2, len); + g_free (digest); + g_free (digest2); + + g_checksum_reset (checksum); + } + + g_checksum_free (checksum); +} + +typedef struct { + GChecksumType checksum_type; + const gchar **sums; +} ChecksumComputeTest; + +static void +test_checksum_string (gconstpointer d) +{ + const ChecksumComputeTest *test = d; + gsize length; + gchar *checksum; + + for (length = 0; length <= FIXED_LEN; length++) + { + checksum = g_compute_checksum_for_string (test->checksum_type, + FIXED_STR, + length); + g_assert_cmpstr (checksum, ==, test->sums[length]); + g_free (checksum); + } + + checksum = g_compute_checksum_for_string (test->checksum_type, + FIXED_STR, + -1); + g_assert_cmpstr (checksum, ==, test->sums[FIXED_LEN]); + g_free (checksum); +} + +static void +test_checksum_bytes (gconstpointer d) +{ + const ChecksumComputeTest *test = d; + GBytes *input; + gsize length; + gchar *checksum; + + for (length = 0; length <= FIXED_LEN; length++) + { + input = g_bytes_new_static (FIXED_STR, length); + checksum = g_compute_checksum_for_bytes (test->checksum_type, input); + g_bytes_unref (input); + + g_assert_cmpstr (checksum, ==, test->sums[length]); + g_free (checksum); + } +} + +static void +add_checksum_test (GChecksumType type, + const char *type_name, + const char *sum, + gint length) +{ + ChecksumTest *test; + gchar *path; + + test = g_new0 (ChecksumTest, 1); + test->checksum_type = type; + test->sum = sum; + test->length = length; + + path = g_strdup_printf ("/checksum/%s/%d", type_name, length); + g_test_add_data_func (path, test, test_checksum); + g_free (path); + + path = g_strdup_printf ("/checksum/%s/reset/%d", type_name, length); + g_test_add_data_func_full (path, test, test_checksum_reset, g_free); + g_free (path); +} + +static void +add_checksum_string_test (GChecksumType type, + const gchar *type_name, + const gchar **sums) +{ + ChecksumComputeTest *test; + gchar *path; + + test = g_new0 (ChecksumComputeTest, 1); + test->checksum_type = type; + test->sums = sums; + + path = g_strdup_printf ("/checksum/%s/string", type_name); + g_test_add_data_func_full (path, test, test_checksum_string, g_free); + g_free (path); +} + +static void +add_checksum_bytes_test (GChecksumType type, + const gchar *type_name, + const gchar **sums) +{ + ChecksumComputeTest *test; + gchar *path; + + test = g_new0 (ChecksumComputeTest, 1); + test->checksum_type = type; + test->sums = sums; + + path = g_strdup_printf ("/checksum/%s/bytes", type_name); + g_test_add_data_func_full (path, test, test_checksum_bytes, g_free); + g_free (path); +} + +static void +test_unsupported (void) +{ + g_assert_cmpint (g_checksum_type_get_length (20), ==, -1); + g_assert (g_checksum_new (20) == NULL); +} + +int +main (int argc, char *argv[]) +{ + gsize length; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/checksum/unsupported", test_unsupported); + + for (length = 0; length <= FIXED_LEN; length++) + add_checksum_test (G_CHECKSUM_MD5, "MD5", MD5_sums[length], length); + add_checksum_string_test (G_CHECKSUM_MD5, "MD5", MD5_sums); + add_checksum_bytes_test (G_CHECKSUM_MD5, "MD5", MD5_sums); + + for (length = 0; length <= FIXED_LEN; length++) + add_checksum_test (G_CHECKSUM_SHA1, "SHA1", SHA1_sums[length], length); + add_checksum_string_test (G_CHECKSUM_SHA1, "SHA1", SHA1_sums); + add_checksum_bytes_test (G_CHECKSUM_SHA1, "SHA1", SHA1_sums); + + for (length = 0; length <= FIXED_LEN; length++) + add_checksum_test (G_CHECKSUM_SHA256, "SHA256", SHA256_sums[length], length); + add_checksum_string_test (G_CHECKSUM_SHA256, "SHA256", SHA256_sums); + add_checksum_bytes_test (G_CHECKSUM_SHA256, "SHA256", SHA256_sums); + + for (length = 0; length <= FIXED_LEN; length++) + add_checksum_test (G_CHECKSUM_SHA384, "SHA384", SHA384_sums[length], length); + add_checksum_string_test (G_CHECKSUM_SHA384, "SHA384", SHA384_sums); + add_checksum_bytes_test (G_CHECKSUM_SHA384, "SHA384", SHA384_sums); + + for (length = 0; length <= FIXED_LEN; length++) + add_checksum_test (G_CHECKSUM_SHA512, "SHA512", SHA512_sums[length], length); + add_checksum_string_test (G_CHECKSUM_SHA512, "SHA512", SHA512_sums); + add_checksum_bytes_test (G_CHECKSUM_SHA512, "SHA512", SHA512_sums); + + return g_test_run (); +} diff --git a/glib/tests/collate.c b/glib/tests/collate.c new file mode 100644 index 0000000..bd9ea23 --- /dev/null +++ b/glib/tests/collate.c @@ -0,0 +1,314 @@ +#include "config.h" + +#include +#include +#include +#include + +static gboolean missing_locale = FALSE; + +typedef struct { + const gchar **input; + const gchar **sorted; + const gchar **file_sorted; +} CollateTest; + +typedef struct { + gchar *key; + const gchar *str; +} Line; + +static void +clear_line (Line *line) +{ + g_free (line->key); +} + +static int +compare_collate (const void *a, const void *b) +{ + const Line *line_a = a; + const Line *line_b = b; + + return g_utf8_collate (line_a->str, line_b->str); +} + +static int +compare_key (const void *a, const void *b) +{ + const Line *line_a = a; + const Line *line_b = b; + + return strcmp (line_a->key, line_b->key); +} + +static void +do_collate (gboolean for_file, gboolean use_key, const CollateTest *test) +{ + GArray *line_array; + Line line; + gint i; + + if (missing_locale) + { + g_test_skip ("no en_US locale"); + return; + } + + line_array = g_array_new (FALSE, FALSE, sizeof(Line)); + g_array_set_clear_func (line_array, (GDestroyNotify)clear_line); + + for (i = 0; test->input[i]; i++) + { + line.str = test->input[i]; + if (for_file) + line.key = g_utf8_collate_key_for_filename (line.str, -1); + else + line.key = g_utf8_collate_key (line.str, -1); + + g_array_append_val (line_array, line); + } + + qsort (line_array->data, line_array->len, sizeof (Line), use_key ? compare_key : compare_collate); + + for (i = 0; test->input[i]; i++) + { + const gchar *str; + str = g_array_index (line_array, Line, i).str; + if (for_file) + g_assert_cmpstr (str, ==, test->file_sorted[i]); + else + g_assert_cmpstr (str, ==, test->sorted[i]); + } + + g_array_free (line_array, TRUE); +} + +static void +test_collate (gconstpointer d) +{ + const CollateTest *test = d; + do_collate (FALSE, FALSE, test); +} + +static void +test_collate_key (gconstpointer d) +{ + const CollateTest *test = d; + do_collate (FALSE, TRUE, test); +} + +static void +test_collate_file (gconstpointer d) +{ + const CollateTest *test = d; + do_collate (TRUE, TRUE, test); +} + +const gchar *input0[] = { + "z", + "c", + "eer34", + "223", + "er1", + "üĠണ", + "foo", + "bar", + "baz", + "GTK+", + NULL +}; + +const gchar *sorted0[] = { + "223", + "bar", + "baz", + "c", + "eer34", + "er1", + "foo", + "GTK+", + "üĠണ", + "z", + NULL +}; + +const gchar *file_sorted0[] = { + "223", + "bar", + "baz", + "c", + "eer34", + "er1", + "foo", + "GTK+", + "üĠണ", + "z", + NULL +}; + +const gchar *input1[] = { + "file.txt", + "file2.bla", + "file.c", + "file3.xx", + "bla001", + "bla02", + "bla03", + "bla4", + "bla10", + "bla100", + "event.c", + "eventgenerator.c", + "event.h", + NULL +}; + +const gchar *sorted1[] = { + "bla001", + "bla02", + "bla03", + "bla10", + "bla100", + "bla4", + "event.c", + "eventgenerator.c", + "event.h", + "file2.bla", + "file3.xx", + "file.c", + "file.txt", + NULL +}; + +const gchar *file_sorted1[] = { + "bla001", + "bla02", + "bla03", + "bla4", + "bla10", + "bla100", + "event.c", + "event.h", + "eventgenerator.c", + "file.c", + "file.txt", + "file2.bla", + "file3.xx", + NULL +}; + +const gchar *input2[] = { + "file26", + "file100", + "file1", + "file:foo", + "a.a", + "file027", + "file10", + "aa.a", + "file5", + "file0027", + "a-.a", + "file0000", + "file000x", + NULL +}; + +const gchar *sorted2[] = { + "a-.a", + "a.a", + "aa.a", + "file0000", + "file000x", + "file0027", + "file027", + "file1", + "file10", + "file100", + "file26", + "file5", + "file:foo", + NULL +}; + +const gchar *file_sorted2[] = { + /* Filename collation in OS X follows Finder style which gives + * a slightly different order from usual Linux locales. */ +#ifdef HAVE_CARBON + "a-.a", + "a.a", + "aa.a", + "file:foo", + "file0000", + "file000x", + "file1", + "file5", + "file10", + "file26", + "file0027", + "file027", + "file100", +#else + "a.a", + "a-.a", + "aa.a", + "file0000", + "file000x", + "file1", + "file5", + "file10", + "file26", + "file027", + "file0027", + "file100", + "file:foo", +#endif + NULL +}; + +int +main (int argc, char *argv[]) +{ + gchar *path; + guint i; + const gchar *locale; + CollateTest test[3]; + + g_test_init (&argc, &argv, NULL); + + g_setenv ("LC_ALL", "en_US", TRUE); + locale = setlocale (LC_ALL, ""); + if (locale == NULL || strcmp (locale, "en_US") != 0) + { + g_test_message ("No suitable locale, skipping tests"); + missing_locale = TRUE; + /* let the tests run to completion so they show up as SKIP'd in TAP + * output */ + } + + test[0].input = input0; + test[0].sorted = sorted0; + test[0].file_sorted = file_sorted0; + test[1].input = input1; + test[1].sorted = sorted1; + test[1].file_sorted = file_sorted1; + test[2].input = input2; + test[2].sorted = sorted2; + test[2].file_sorted = file_sorted2; + + for (i = 0; i < G_N_ELEMENTS (test); i++) + { + path = g_strdup_printf ("/unicode/collate/%d", i); + g_test_add_data_func (path, &test[i], test_collate); + g_free (path); + path = g_strdup_printf ("/unicode/collate-key/%d", i); + g_test_add_data_func (path, &test[i], test_collate_key); + g_free (path); + path = g_strdup_printf ("/unicode/collate-filename/%d", i); + g_test_add_data_func (path, &test[i], test_collate_file); + g_free (path); + } + + return g_test_run (); +} diff --git a/glib/tests/completion.c b/glib/tests/completion.c new file mode 100644 index 0000000..4f79037 --- /dev/null +++ b/glib/tests/completion.c @@ -0,0 +1,102 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +#include "glib.h" + +static void +test_completion (void) +{ + static const char *const a1 = "a\302\243"; + static const char *const a2 = "a\302\244"; + static const char *const bb = "bb"; + static const char *const bc = "bc"; + + GCompletion *cmp; + GList *items; + gchar *prefix; + + cmp = g_completion_new (NULL); + g_completion_set_compare (cmp, strncmp); + + items = NULL; + items = g_list_append (items, (gpointer) a1); + items = g_list_append (items, (gpointer) a2); + items = g_list_append (items, (gpointer) bb); + items = g_list_append (items, (gpointer) bc); + g_completion_add_items (cmp, items); + g_list_free (items); + + items = g_completion_complete (cmp, "a", &prefix); + g_assert_cmpstr (prefix, ==, "a\302"); + g_assert_cmpint (g_list_length (items), ==, 2); + g_free (prefix); + + items = g_completion_complete_utf8 (cmp, "a", &prefix); + g_assert_cmpstr (prefix, ==, "a"); + g_assert_cmpint (g_list_length (items), ==, 2); + g_free (prefix); + + items = g_completion_complete (cmp, "b", &prefix); + g_assert_cmpstr (prefix, ==, "b"); + g_assert_cmpint (g_list_length (items), ==, 2); + g_free (prefix); + + items = g_completion_complete_utf8 (cmp, "b", &prefix); + g_assert_cmpstr (prefix, ==, "b"); + g_assert_cmpint (g_list_length (items), ==, 2); + g_free (prefix); + + items = g_completion_complete (cmp, "a", NULL); + g_assert_cmpint (g_list_length (items), ==, 2); + + items = g_completion_complete_utf8 (cmp, "a", NULL); + g_assert_cmpint (g_list_length (items), ==, 2); + + items = g_list_append (NULL, (gpointer) bb); + g_completion_remove_items (cmp, items); + g_list_free (items); + + items = g_completion_complete_utf8 (cmp, "b", &prefix); + g_assert_cmpint (g_list_length (items), ==, 1); + g_free (prefix); + + g_completion_free (cmp); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + g_test_add_func ("/completion/test-completion", test_completion); + + return g_test_run (); +} diff --git a/glib/tests/cond.c b/glib/tests/cond.c new file mode 100644 index 0000000..bcd8fbd --- /dev/null +++ b/glib/tests/cond.c @@ -0,0 +1,381 @@ +/* Unit tests for GCond + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +static GCond cond; +static GMutex mutex; +static gint next; /* locked by @mutex */ + +static void +push_value (gint value) +{ + g_mutex_lock (&mutex); + while (next != 0) + g_cond_wait (&cond, &mutex); + next = value; + if (g_test_verbose ()) + g_printerr ("Thread %p producing next value: %d\n", g_thread_self (), value); + if (value % 10 == 0) + g_cond_broadcast (&cond); + else + g_cond_signal (&cond); + g_mutex_unlock (&mutex); +} + +static gint +pop_value (void) +{ + gint value; + + g_mutex_lock (&mutex); + while (next == 0) + { + if (g_test_verbose ()) + g_printerr ("Thread %p waiting for cond\n", g_thread_self ()); + g_cond_wait (&cond, &mutex); + } + value = next; + next = 0; + g_cond_broadcast (&cond); + if (g_test_verbose ()) + g_printerr ("Thread %p consuming value %d\n", g_thread_self (), value); + g_mutex_unlock (&mutex); + + return value; +} + +static gpointer +produce_values (gpointer data) +{ + gint total; + gint i; + + total = 0; + + for (i = 1; i < 100; i++) + { + total += i; + push_value (i); + } + + push_value (-1); + push_value (-1); + + if (g_test_verbose ()) + g_printerr ("Thread %p produced %d altogether\n", g_thread_self (), total); + + return GINT_TO_POINTER (total); +} + +static gpointer +consume_values (gpointer data) +{ + gint accum = 0; + gint value; + + while (TRUE) + { + value = pop_value (); + if (value == -1) + break; + + accum += value; + } + + if (g_test_verbose ()) + g_printerr ("Thread %p accumulated %d\n", g_thread_self (), accum); + + return GINT_TO_POINTER (accum); +} + +static GThread *producer, *consumer1, *consumer2; + +static void +test_cond1 (void) +{ + gint total, acc1, acc2; + + producer = g_thread_create (produce_values, NULL, TRUE, NULL); + consumer1 = g_thread_create (consume_values, NULL, TRUE, NULL); + consumer2 = g_thread_create (consume_values, NULL, TRUE, NULL); + + total = GPOINTER_TO_INT (g_thread_join (producer)); + acc1 = GPOINTER_TO_INT (g_thread_join (consumer1)); + acc2 = GPOINTER_TO_INT (g_thread_join (consumer2)); + + g_assert_cmpint (total, ==, acc1 + acc2); +} + +typedef struct +{ + GMutex mutex; + GCond cond; + gint limit; + gint count; +} Barrier; + +static void +barrier_init (Barrier *barrier, + gint limit) +{ + g_mutex_init (&barrier->mutex); + g_cond_init (&barrier->cond); + barrier->limit = limit; + barrier->count = limit; +} + +static gint +barrier_wait (Barrier *barrier) +{ + gint ret; + + g_mutex_lock (&barrier->mutex); + barrier->count--; + if (barrier->count == 0) + { + ret = -1; + barrier->count = barrier->limit; + g_cond_broadcast (&barrier->cond); + } + else + { + ret = 0; + while (barrier->count != barrier->limit) + g_cond_wait (&barrier->cond, &barrier->mutex); + } + g_mutex_unlock (&barrier->mutex); + + return ret; +} + +static void +barrier_clear (Barrier *barrier) +{ + g_mutex_clear (&barrier->mutex); + g_cond_clear (&barrier->cond); +} + +static Barrier b; +static gint check; + +static gpointer +cond2_func (gpointer data) +{ + gint value = GPOINTER_TO_INT (data); + gint ret; + + g_atomic_int_inc (&check); + + if (g_test_verbose ()) + g_printerr ("thread %d starting, check %d\n", value, g_atomic_int_get (&check)); + + g_usleep (10000 * value); + + g_atomic_int_inc (&check); + + if (g_test_verbose ()) + g_printerr ("thread %d reaching barrier, check %d\n", value, g_atomic_int_get (&check)); + + ret = barrier_wait (&b); + + g_assert_cmpint (g_atomic_int_get (&check), ==, 10); + + if (g_test_verbose ()) + g_printerr ("thread %d leaving barrier (%d), check %d\n", value, ret, g_atomic_int_get (&check)); + + return NULL; +} + +/* this test demonstrates how to use a condition variable + * to implement a barrier + */ +static void +test_cond2 (void) +{ + gint i; + GThread *threads[5]; + + g_atomic_int_set (&check, 0); + + barrier_init (&b, 5); + for (i = 0; i < 5; i++) + threads[i] = g_thread_create (cond2_func, GINT_TO_POINTER (i), TRUE, NULL); + + for (i = 0; i < 5; i++) + g_thread_join (threads[i]); + + g_assert_cmpint (g_atomic_int_get (&check), ==, 10); + + barrier_clear (&b); +} + +static void +test_wait_until (void) +{ + gint64 until; + GMutex lock; + GCond cond; + + /* This test will make sure we don't wait too much or too little. + * + * We check the 'too long' with a timeout of 60 seconds. + * + * We check the 'too short' by verifying a guarantee of the API: we + * should not wake up until the specified time has passed. + */ + g_mutex_init (&lock); + g_cond_init (&cond); + + until = g_get_monotonic_time () + G_TIME_SPAN_SECOND; + + /* Could still have spurious wakeups, so we must loop... */ + g_mutex_lock (&lock); + while (g_cond_wait_until (&cond, &lock, until)) + ; + g_mutex_unlock (&lock); + + /* Make sure it's after the until time */ + g_assert_cmpint (until, <=, g_get_monotonic_time ()); + + /* Make sure it returns FALSE on timeout */ + until = g_get_monotonic_time () + G_TIME_SPAN_SECOND / 50; + g_mutex_lock (&lock); + g_assert (g_cond_wait_until (&cond, &lock, until) == FALSE); + g_mutex_unlock (&lock); + + g_mutex_clear (&lock); + g_cond_clear (&cond); +} + +#ifdef __linux__ + +#include +#include +#include + +static pthread_t main_thread; + +static void * +mutex_holder (void *data) +{ + GMutex *lock = data; + + g_mutex_lock (lock); + + /* Let the lock become contended */ + g_usleep (G_TIME_SPAN_SECOND); + + /* Interrupt the wait on the other thread */ + pthread_kill (main_thread, SIGHUP); + + /* If we don't sleep here, then the g_mutex_unlock() below will clear + * the mutex, causing the interrupted futex call in the other thread + * to return success (which is not what we want). + * + * The other thread needs to have time to wake up and see that the + * lock is still contended. + */ + g_usleep (G_TIME_SPAN_SECOND / 10); + + g_mutex_unlock (lock); + + return NULL; +} + +static void +signal_handler (int sig) +{ +} + +static void +test_wait_until_errno (void) +{ + gboolean result; + GMutex lock; + GCond cond; + struct sigaction act = { }; + + /* important: no SA_RESTART (we want EINTR) */ + act.sa_handler = signal_handler; + + g_test_summary ("Check proper handling of errno in g_cond_wait_until with a contended mutex"); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/merge_requests/957"); + + g_mutex_init (&lock); + g_cond_init (&cond); + + main_thread = pthread_self (); + sigaction (SIGHUP, &act, NULL); + + g_mutex_lock (&lock); + + /* We create an annoying worker thread that will do two things: + * + * 1) hold the lock that we want to reacquire after returning from + * the condition variable wait + * + * 2) send us a signal to cause our wait on the contended lock to + * return EINTR, clobbering the errno return from the condition + * variable + */ + g_thread_unref (g_thread_new ("mutex-holder", mutex_holder, &lock)); + + result = g_cond_wait_until (&cond, &lock, + g_get_monotonic_time () + G_TIME_SPAN_SECOND / 50); + + /* Even after all that disruption, we should still successfully return + * 'timed out'. + */ + g_assert_false (result); + + g_mutex_unlock (&lock); + + g_cond_clear (&cond); + g_mutex_clear (&lock); +} + +#else +static void +test_wait_until_errno (void) +{ + g_test_skip ("We only test this on Linux"); +} +#endif + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/thread/cond1", test_cond1); + g_test_add_func ("/thread/cond2", test_cond2); + g_test_add_func ("/thread/cond/wait-until", test_wait_until); + g_test_add_func ("/thread/cond/wait-until/contended-and-interrupted", test_wait_until_errno); + + return g_test_run (); +} diff --git a/glib/tests/convert.c b/glib/tests/convert.c new file mode 100644 index 0000000..de6c8a7 --- /dev/null +++ b/glib/tests/convert.c @@ -0,0 +1,969 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include + +#include + +/* Bug 311337 */ +static void +test_iconv_state (void) +{ + const gchar *in = "\xf4\xe5\xf8\xe5\xed"; + const gchar *expected = "\xd7\xa4\xd7\x95\xd7\xa8\xd7\x95\xd7\x9d"; + gchar *out; + gsize bytes_read = 0; + gsize bytes_written = 0; + GError *error = NULL; + + out = g_convert (in, -1, "UTF-8", "CP1255", + &bytes_read, &bytes_written, &error); + + if (error && error->code == G_CONVERT_ERROR_NO_CONVERSION) + return; /* silently skip if CP1255 is not supported, see bug 467707 */ + + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, 5); + g_assert_cmpint (bytes_written, ==, 10); + g_assert_cmpstr (out, ==, expected); + g_free (out); +} + +/* Some tests involving "vulgar fraction one half" (U+00BD). This is + * represented in UTF-8 as \xC2\xBD, in ISO-8859-1 as \xBD, and is not + * represented in ISO-8859-15. */ +static void +test_one_half (void) +{ + const gchar *in_utf8 = "\xc2\xbd"; + gchar *out; + gsize bytes_read = 0; + gsize bytes_written = 0; + GError *error = NULL; + + out = g_convert (in_utf8, -1, + "ISO-8859-1", "UTF-8", + &bytes_read, &bytes_written, + &error); + + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, 2); + g_assert_cmpint (bytes_written, ==, 1); + g_assert_cmpstr (out, ==, "\xbd"); + g_free (out); + + out = g_convert (in_utf8, -1, + "ISO-8859-15", "UTF-8", + &bytes_read, &bytes_written, + &error); + + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE); + g_assert_cmpint (bytes_read, ==, 0); + g_assert_cmpint (bytes_written, ==, 0); + g_assert_cmpstr (out, ==, NULL); + g_clear_error (&error); + g_free (out); + + out = g_convert_with_fallback (in_utf8, -1, + "ISO8859-15", "UTF-8", + "a", + &bytes_read, &bytes_written, + &error); + + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, 2); + g_assert_cmpint (bytes_written, ==, 1); + g_assert_cmpstr (out, ==, "a"); + g_free (out); +} + +static void +test_byte_order (void) +{ + gchar in_be[4] = { 0xfe, 0xff, 0x03, 0x93}; /* capital gamma */ + gchar in_le[4] = { 0xff, 0xfe, 0x93, 0x03}; + const gchar *expected = "\xce\x93"; + gchar *out; + gsize bytes_read = 0; + gsize bytes_written = 0; + GError *error = NULL; + + out = g_convert (in_be, sizeof (in_be), + "UTF-8", "UTF-16", + &bytes_read, &bytes_written, + &error); + + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, 4); + g_assert_cmpint (bytes_written, ==, 2); + g_assert_cmpstr (out, ==, expected); + g_free (out); + + out = g_convert (in_le, sizeof (in_le), + "UTF-8", "UTF-16", + &bytes_read, &bytes_written, + &error); + + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, 4); + g_assert_cmpint (bytes_written, ==, 2); + g_assert_cmpstr (out, ==, expected); + g_free (out); +} + +static void +check_utf8_to_ucs4 (const char *utf8, + gsize utf8_len, + const gunichar *ucs4, + glong ucs4_len, + glong error_pos) +{ + gunichar *result, *result2, *result3; + glong items_read, items_read2; + glong items_written, items_written2; + GError *error, *error2, *error3; + gint i; + + if (!error_pos) + { + /* check the fast conversion */ + result = g_utf8_to_ucs4_fast (utf8, utf8_len, &items_written); + + g_assert_cmpint (items_written, ==, ucs4_len); + g_assert (result); + for (i = 0; i <= items_written; i++) + g_assert (result[i] == ucs4[i]); + + g_free (result); + } + + error = NULL; + result = g_utf8_to_ucs4 (utf8, utf8_len, &items_read, &items_written, &error); + + if (utf8_len == strlen (utf8)) + { + /* check that len == -1 yields identical results */ + error2 = NULL; + result2 = g_utf8_to_ucs4 (utf8, -1, &items_read2, &items_written2, &error2); + g_assert (error || items_read2 == items_read); + g_assert (error || items_written2 == items_written); + g_assert_cmpint (!!result, ==, !!result2); + g_assert_cmpint (!!error, ==, !!error2); + if (result) + for (i = 0; i <= items_written; i++) + g_assert (result[i] == result2[i]); + + g_free (result2); + if (error2) + g_error_free (error2); + } + + error3 = NULL; + result3 = g_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL, &error3); + + if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT) + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, error_pos); + g_assert_cmpint (items_written, ==, ucs4_len); + g_assert (result); + for (i = 0; i <= items_written; i++) + g_assert (result[i] == ucs4[i]); + g_error_free (error3); + } + else if (error_pos) + { + g_assert (error != NULL); + g_assert (result == NULL); + g_assert_cmpint (items_read, ==, error_pos); + g_error_free (error); + + g_assert (error3 != NULL); + g_assert (result3 == NULL); + g_error_free (error3); + } + else + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, utf8_len); + g_assert_cmpint (items_written, ==, ucs4_len); + g_assert (result); + for (i = 0; i <= items_written; i++) + g_assert (result[i] == ucs4[i]); + + g_assert_no_error (error3); + g_assert (result3); + for (i = 0; i <= ucs4_len; i++) + g_assert (result3[i] == ucs4[i]); + } + + g_free (result); + g_free (result3); +} + +static void +check_ucs4_to_utf8 (const gunichar *ucs4, + glong ucs4_len, + const char *utf8, + glong utf8_len, + glong error_pos) +{ + gchar *result, *result2, *result3; + glong items_read, items_read2; + glong items_written, items_written2; + GError *error, *error2, *error3; + + error = NULL; + result = g_ucs4_to_utf8 (ucs4, ucs4_len, &items_read, &items_written, &error); + + if (ucs4[ucs4_len] == 0) + { + /* check that len == -1 yields identical results */ + error2 = NULL; + result2 = g_ucs4_to_utf8 (ucs4, -1, &items_read2, &items_written2, &error2); + + g_assert (error || items_read2 == items_read); + g_assert (error || items_written2 == items_written); + g_assert_cmpint (!!result, ==, !!result2); + g_assert_cmpint (!!error, ==, !!error2); + if (result) + g_assert_cmpstr (result, ==, result2); + + g_free (result2); + if (error2) + g_error_free (error2); + } + + error3 = NULL; + result3 = g_ucs4_to_utf8 (ucs4, ucs4_len, NULL, NULL, &error3); + + if (error_pos) + { + g_assert (error != NULL); + g_assert (result == NULL); + g_assert_cmpint (items_read, ==, error_pos); + g_error_free (error); + + g_assert (error3 != NULL); + g_assert (result3 == NULL); + g_error_free (error3); + } + else + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, ucs4_len); + g_assert_cmpint (items_written, ==, utf8_len); + g_assert (result); + g_assert_cmpstr (result, ==, utf8); + + g_assert_no_error (error3); + g_assert (result3); + g_assert_cmpstr (result3, ==, utf8); + } + + g_free (result); + g_free (result3); +} + +static void +check_utf8_to_utf16 (const char *utf8, + gsize utf8_len, + const gunichar2 *utf16, + glong utf16_len, + glong error_pos) +{ + gunichar2 *result, *result2, *result3; + glong items_read, items_read2; + glong items_written, items_written2; + GError *error, *error2, *error3; + gint i; + + error = NULL; + result = g_utf8_to_utf16 (utf8, utf8_len, &items_read, &items_written, &error); + + if (utf8_len == strlen (utf8)) + { + /* check that len == -1 yields identical results */ + error2 = NULL; + result2 = g_utf8_to_utf16 (utf8, -1, &items_read2, &items_written2, &error2); + g_assert (error || items_read2 == items_read); + g_assert (error || items_written2 == items_written); + g_assert_cmpint (!!result, ==, !!result2); + g_assert_cmpint (!!error, ==, !!error2); + if (result) + for (i = 0; i <= items_written; i++) + g_assert (result[i] == result2[i]); + + g_free (result2); + if (error2) + g_error_free (error2); + } + + error3 = NULL; + result3 = g_utf8_to_utf16 (utf8, utf8_len, NULL, NULL, &error3); + + if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT) + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, error_pos); + g_assert_cmpint (items_written, ==, utf16_len); + g_assert (result); + for (i = 0; i <= items_written; i++) + g_assert (result[i] == utf16[i]); + g_error_free (error3); + } + else if (error_pos) + { + g_assert (error != NULL); + g_assert (result == NULL); + g_assert_cmpint (items_read, ==, error_pos); + g_error_free (error); + + g_assert (error3 != NULL); + g_assert (result3 == NULL); + g_error_free (error3); + } + else + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, utf8_len); + g_assert_cmpint (items_written, ==, utf16_len); + g_assert (result); + for (i = 0; i <= items_written; i++) + g_assert (result[i] == utf16[i]); + + g_assert_no_error (error3); + g_assert (result3); + for (i = 0; i <= utf16_len; i++) + g_assert (result3[i] == utf16[i]); + } + + g_free (result); + g_free (result3); +} + +static void +check_utf16_to_utf8 (const gunichar2 *utf16, + glong utf16_len, + const char *utf8, + glong utf8_len, + glong error_pos) +{ + gchar *result, *result2, *result3; + glong items_read, items_read2; + glong items_written, items_written2; + GError *error, *error2, *error3; + + error = NULL; + result = g_utf16_to_utf8 (utf16, utf16_len, &items_read, &items_written, &error); + if (utf16[utf16_len] == 0) + { + /* check that len == -1 yields identical results */ + error2 = NULL; + result2 = g_utf16_to_utf8 (utf16, -1, &items_read2, &items_written2, &error2); + + g_assert (error || items_read2 == items_read); + g_assert (error || items_written2 == items_written); + g_assert_cmpint (!!result, ==, !!result2); + g_assert_cmpint (!!error, ==, !!error2); + if (result) + g_assert_cmpstr (result, ==, result2); + + g_free (result2); + if (error2) + g_error_free (error2); + } + + error3 = NULL; + result3 = g_utf16_to_utf8 (utf16, utf16_len, NULL, NULL, &error3); + + if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT) + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, error_pos); + g_assert_cmpint (items_read + 1, ==, utf16_len); + g_assert_cmpint (items_written, ==, utf8_len); + g_assert (result); + g_assert_cmpstr (result, ==, utf8); + g_error_free (error3); + } + else if (error_pos) + { + g_assert (error != NULL); + g_assert (result == NULL); + g_assert_cmpint (items_read, ==, error_pos); + g_error_free (error); + + g_assert (error3 != NULL); + g_assert (result3 == NULL); + g_error_free (error3); + } + else + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, utf16_len); + g_assert_cmpint (items_written, ==, utf8_len); + g_assert (result); + g_assert_cmpstr (result, ==, utf8); + + g_assert_no_error (error3); + g_assert (result3); + g_assert_cmpstr (result3, ==, utf8); + } + + g_free (result); + g_free (result3); +} + +static void +check_ucs4_to_utf16 (const gunichar *ucs4, + glong ucs4_len, + const gunichar2 *utf16, + glong utf16_len, + glong error_pos) +{ + gunichar2 *result, *result2, *result3; + glong items_read, items_read2; + glong items_written, items_written2; + GError *error, *error2, *error3; + gint i; + + error = NULL; + result = g_ucs4_to_utf16 (ucs4, ucs4_len, &items_read, &items_written, &error); + + if (ucs4[ucs4_len] == 0) + { + /* check that len == -1 yields identical results */ + error2 = NULL; + result2 = g_ucs4_to_utf16 (ucs4, -1, &items_read2, &items_written2, &error2); + + g_assert (error || items_read2 == items_read); + g_assert (error || items_written2 == items_written); + g_assert_cmpint (!!result, ==, !!result2); + g_assert_cmpint (!!error, ==, !!error2); + if (result) + for (i = 0; i <= utf16_len; i++) + g_assert (result[i] == result2[i]); + + g_free (result2); + if (error2) + g_error_free (error2); + } + + error3 = NULL; + result3 = g_ucs4_to_utf16 (ucs4, -1, NULL, NULL, &error3); + + if (error_pos) + { + g_assert (error != NULL); + g_assert (result == NULL); + g_assert_cmpint (items_read, ==, error_pos); + g_error_free (error); + + g_assert (error3 != NULL); + g_assert (result3 == NULL); + g_error_free (error3); + } + else + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, ucs4_len); + g_assert_cmpint (items_written, ==, utf16_len); + g_assert (result); + for (i = 0; i <= utf16_len; i++) + g_assert (result[i] == utf16[i]); + + g_assert_no_error (error3); + g_assert (result3); + for (i = 0; i <= utf16_len; i++) + g_assert (result3[i] == utf16[i]); + } + + g_free (result); + g_free (result3); +} + +static void +check_utf16_to_ucs4 (const gunichar2 *utf16, + glong utf16_len, + const gunichar *ucs4, + glong ucs4_len, + glong error_pos) +{ + gunichar *result, *result2, *result3; + glong items_read, items_read2; + glong items_written, items_written2; + GError *error, *error2, *error3; + gint i; + + error = NULL; + result = g_utf16_to_ucs4 (utf16, utf16_len, &items_read, &items_written, &error); + if (utf16[utf16_len] == 0) + { + /* check that len == -1 yields identical results */ + error2 = NULL; + result2 = g_utf16_to_ucs4 (utf16, -1, &items_read2, &items_written2, &error2); + g_assert (error || items_read2 == items_read); + g_assert (error || items_written2 == items_written); + g_assert_cmpint (!!result, ==, !!result2); + g_assert_cmpint (!!error, ==, !!error2); + if (result) + for (i = 0; i <= items_written; i++) + g_assert (result[i] == result2[i]); + + g_free (result2); + if (error2) + g_error_free (error2); + } + + error3 = NULL; + result3 = g_utf16_to_ucs4 (utf16, utf16_len, NULL, NULL, &error3); + + if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT) + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, error_pos); + g_assert_cmpint (items_read + 1, ==, utf16_len); + g_assert_cmpint (items_written, ==, ucs4_len); + g_assert (result); + for (i = 0; i <= items_written; i++) + g_assert (result[i] == ucs4[i]); + g_error_free (error3); + } + else if (error_pos) + { + g_assert (error != NULL); + g_assert (result == NULL); + g_assert_cmpint (items_read, ==, error_pos); + g_error_free (error); + + g_assert (error3 != NULL); + g_assert (result3 == NULL); + g_error_free (error3); + } + else + { + g_assert_no_error (error); + g_assert_cmpint (items_read, ==, utf16_len); + g_assert_cmpint (items_written, ==, ucs4_len); + g_assert (result); + for (i = 0; i <= ucs4_len; i++) + g_assert (result[i] == ucs4[i]); + + g_assert_no_error (error3); + g_assert (result3); + for (i = 0; i <= ucs4_len; i++) + g_assert (result3[i] == ucs4[i]); + } + + g_free (result); + g_free (result3); +} + +static void +test_unicode_conversions (void) +{ + const char *utf8; + gunichar ucs4[100]; + gunichar2 utf16[100]; + + utf8 = "abc"; + ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x63; ucs4[3] = 0; + utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0x63; utf16[3] = 0; + + check_utf8_to_ucs4 (utf8, 3, ucs4, 3, 0); + check_ucs4_to_utf8 (ucs4, 3, utf8, 3, 0); + check_utf8_to_utf16 (utf8, 3, utf16, 3, 0); + check_utf16_to_utf8 (utf16, 3, utf8, 3, 0); + check_ucs4_to_utf16 (ucs4, 3, utf16, 3, 0); + check_utf16_to_ucs4 (utf16, 3, ucs4, 3, 0); + + utf8 = "\316\261\316\262\316\263"; + ucs4[0] = 0x03b1; ucs4[1] = 0x03b2; ucs4[2] = 0x03b3; ucs4[3] = 0; + utf16[0] = 0x03b1; utf16[1] = 0x03b2; utf16[2] = 0x03b3; utf16[3] = 0; + + check_utf8_to_ucs4 (utf8, 6, ucs4, 3, 0); + check_ucs4_to_utf8 (ucs4, 3, utf8, 6, 0); + check_utf8_to_utf16 (utf8, 6, utf16, 3, 0); + check_utf16_to_utf8 (utf16, 3, utf8, 6, 0); + check_ucs4_to_utf16 (ucs4, 3, utf16, 3, 0); + check_utf16_to_ucs4 (utf16, 3, ucs4, 3, 0); + + /* partial utf8 character */ + utf8 = "abc\316"; + ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x63; ucs4[3] = 0; + utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0x63; utf16[3] = 0; + + check_utf8_to_ucs4 (utf8, 4, ucs4, 3, 3); + check_utf8_to_utf16 (utf8, 4, utf16, 3, 3); + + /* invalid utf8 */ + utf8 = "abc\316\316"; + ucs4[0] = 0; + utf16[0] = 0; + + check_utf8_to_ucs4 (utf8, 5, ucs4, 0, 3); + check_utf8_to_utf16 (utf8, 5, utf16, 0, 3); + + /* partial utf16 character */ + utf8 = "ab"; + ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0; + utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0xd801; utf16[3] = 0; + + check_utf16_to_utf8 (utf16, 3, utf8, 2, 2); + check_utf16_to_ucs4 (utf16, 3, ucs4, 2, 2); + + /* invalid utf16 */ + utf8 = NULL; + ucs4[0] = 0; + utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0xdc01; utf16[3] = 0; + + check_utf16_to_utf8 (utf16, 3, utf8, 0, 2); + check_utf16_to_ucs4 (utf16, 3, ucs4, 0, 2); + + /* invalid ucs4 */ + utf8 = NULL; + ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x80000000; ucs4[3] = 0; + utf16[0] = 0; + + check_ucs4_to_utf8 (ucs4, 3, utf8, 0, 2); + check_ucs4_to_utf16 (ucs4, 3, utf16, 0, 2); +} + +static void +test_filename_utf8 (void) +{ + const gchar *filename = "/my/path/to/foo"; + gchar *utf8; + gchar *back; + GError *error; + + error = NULL; + utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, &error); + g_assert_no_error (error); + back = g_filename_from_utf8 (utf8, -1, NULL, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (back, ==, filename); + + g_free (utf8); + g_free (back); +} + +static void +test_filename_display (void) +{ + const gchar *filename = "/my/path/to/foo"; + char *display; + + display = g_filename_display_basename (filename); + g_assert_cmpstr (display, ==, "foo"); + + g_free (display); +} + +/* g_convert() should accept and produce text buffers with embedded + * nul bytes/characters. + */ +static void +test_convert_embedded_nul (void) +{ + gchar *res; + gsize bytes_read, bytes_written; + GError *error = NULL; + + res = g_convert ("ab\0\xf6", 4, "UTF-8", "ISO-8859-1", + &bytes_read, &bytes_written, &error); + g_assert_no_error (error); + g_assert_cmpuint (bytes_read, ==, 4); + g_assert_cmpmem (res, bytes_written, "ab\0\xc3\xb6", 5); + g_free (res); +} + +static void +test_locale_to_utf8_embedded_nul (void) +{ + g_test_trap_subprocess ("/conversion/locale-to-utf8/embedded-nul/subprocess/utf8", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_subprocess ("/conversion/locale-to-utf8/embedded-nul/subprocess/iconv", 0, 0); + g_test_trap_assert_passed (); +} + +/* Test that embedded nul characters in UTF-8 input to g_locale_to_utf8() + * result in an error. + */ +static void +test_locale_to_utf8_embedded_nul_utf8 (void) +{ + gchar *res; + gsize bytes_read; + GError *error = NULL; + + setlocale (LC_ALL, ""); + g_setenv ("CHARSET", "UTF-8", TRUE); + g_assert_true (g_get_charset (NULL)); + + res = g_locale_to_utf8 ("ab\0c", 4, &bytes_read, NULL, &error); + + g_assert_null (res); + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE); + g_assert_cmpuint (bytes_read, ==, 2); + g_error_free (error); +} + +/* Test that embedded nul characters in output of g_locale_to_utf8(), + * when converted from non-UTF8 input, result in an error. + */ +static void +test_locale_to_utf8_embedded_nul_iconv (void) +{ + gchar *res; + GError *error = NULL; + + setlocale (LC_ALL, "C"); + g_setenv ("CHARSET", "US-ASCII", TRUE); + g_assert_false (g_get_charset (NULL)); + + res = g_locale_to_utf8 ("ab\0c", 4, NULL, NULL, &error); + + g_assert_null (res); + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_EMBEDDED_NUL); + g_error_free (error); +} + +static void +test_locale_from_utf8_embedded_nul (void) +{ + g_test_trap_subprocess ("/conversion/locale-from-utf8/embedded-nul/subprocess/utf8", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_subprocess ("/conversion/locale-from-utf8/embedded-nul/subprocess/iconv", 0, 0); + g_test_trap_assert_passed (); +} + +/* Test that embedded nul characters in input to g_locale_from_utf8(), + * when converting (copying) to UTF-8 output, result in an error. + */ +static void +test_locale_from_utf8_embedded_nul_utf8 (void) +{ + gchar *res; + gsize bytes_read; + GError *error = NULL; + + setlocale (LC_ALL, ""); + g_setenv ("CHARSET", "UTF-8", TRUE); + g_assert_true (g_get_charset (NULL)); + + res = g_locale_from_utf8 ("ab\0c", 4, &bytes_read, NULL, &error); + + g_assert_null (res); + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE); + g_assert_cmpuint (bytes_read, ==, 2); + g_error_free (error); +} + +/* Test that embedded nul characters in input to g_locale_from_utf8(), + * when converting to non-UTF-8 output, result in an error. + */ +static void +test_locale_from_utf8_embedded_nul_iconv (void) +{ + gchar *res; + gsize bytes_read; + GError *error = NULL; + + setlocale (LC_ALL, "C"); + g_setenv ("CHARSET", "US-ASCII", TRUE); + g_assert_false (g_get_charset (NULL)); + + res = g_locale_from_utf8 ("ab\0c", 4, &bytes_read, NULL, &error); + + g_assert_null (res); + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE); + g_assert_cmpuint (bytes_read, ==, 2); + g_error_free (error); +} + +static void +test_filename_to_utf8_embedded_nul (void) +{ + g_test_trap_subprocess ("/conversion/filename-to-utf8/embedded-nul/subprocess/utf8", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_subprocess ("/conversion/filename-to-utf8/embedded-nul/subprocess/iconv", 0, 0); + g_test_trap_assert_passed (); +} + +/* Test that embedded nul characters in UTF-8 input to g_filename_to_utf8() + * result in an error. + */ +static void +test_filename_to_utf8_embedded_nul_utf8 (void) +{ + gchar *res; + gsize bytes_read; + GError *error = NULL; + +#ifndef G_OS_WIN32 + /* G_FILENAME_ENCODING has no effect on Windows for g_get_filename_charsets() */ + g_setenv ("G_FILENAME_ENCODING", "UTF-8", TRUE); + g_assert_true (g_get_filename_charsets (NULL)); +#endif + + res = g_filename_to_utf8 ("ab\0c", 4, &bytes_read, NULL, &error); + + g_assert_null (res); + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE); + g_assert_cmpuint (bytes_read, ==, 2); + g_error_free (error); +} + +/* Test that embedded nul characters in non-UTF-8 input of g_filename_to_utf8() + * result in an error. + */ +static void +test_filename_to_utf8_embedded_nul_iconv (void) +{ + gchar *res; + gsize bytes_read; + GError *error = NULL; + +#ifndef G_OS_WIN32 + /* G_FILENAME_ENCODING has no effect on Windows for g_get_filename_charsets() */ + g_setenv ("G_FILENAME_ENCODING", "US-ASCII", TRUE); + g_assert_false (g_get_filename_charsets (NULL)); +#endif + + res = g_filename_to_utf8 ("ab\0c", 4, &bytes_read, NULL, &error); + + g_assert_null (res); + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE); + g_assert_cmpuint (bytes_read, ==, 2); + g_error_free (error); +} + +static void +test_filename_from_utf8_embedded_nul (void) +{ + g_test_trap_subprocess ("/conversion/filename-from-utf8/embedded-nul/subprocess/utf8", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_subprocess ("/conversion/filename-from-utf8/embedded-nul/subprocess/iconv", 0, 0); + g_test_trap_assert_passed (); +} + +/* Test that embedded nul characters in input to g_filename_from_utf8(), + * when converting (copying) to UTF-8 output, result in an error. + */ +static void +test_filename_from_utf8_embedded_nul_utf8 (void) +{ + gchar *res; + gsize bytes_read; + GError *error = NULL; + +#ifndef G_OS_WIN32 + /* G_FILENAME_ENCODING has no effect on Windows for g_get_filename_charsets() */ + g_setenv ("G_FILENAME_ENCODING", "UTF-8", TRUE); + g_assert_true (g_get_filename_charsets (NULL)); +#endif + + res = g_filename_from_utf8 ("ab\0c", 4, &bytes_read, NULL, &error); + + g_assert_null (res); + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE); + g_assert_cmpuint (bytes_read, ==, 2); + g_error_free (error); +} + +/* Test that embedded nul characters in input to g_filename_from_utf8(), + * when converting to non-UTF-8 output, result in an error. + */ +static void +test_filename_from_utf8_embedded_nul_iconv (void) +{ + gchar *res; + gsize bytes_read; + GError *error = NULL; + +#ifndef G_OS_WIN32 + /* G_FILENAME_ENCODING has no effect on Windows for g_get_filename_charsets() */ + g_setenv ("G_FILENAME_ENCODING", "US-ASCII", TRUE); + g_assert_false (g_get_filename_charsets (NULL)); +#endif + + res = g_filename_from_utf8 ("ab\0c", 4, &bytes_read, NULL, &error); + + g_assert_null (res); + g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE); + g_assert_cmpuint (bytes_read, ==, 2); + g_error_free (error); +} + +static void +test_no_conv (void) +{ + const gchar *in = ""; + gchar *out G_GNUC_UNUSED; + gsize bytes_read = 0; + gsize bytes_written = 0; + GError *error = NULL; + + out = g_convert (in, -1, "XXX", "UVZ", + &bytes_read, &bytes_written, &error); + + /* error code is unreliable, since we mishandle errno there */ + g_assert (error && error->domain == G_CONVERT_ERROR); + g_error_free (error); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/conversion/no-conv", test_no_conv); + g_test_add_func ("/conversion/iconv-state", test_iconv_state); + g_test_add_func ("/conversion/illegal-sequence", test_one_half); + g_test_add_func ("/conversion/byte-order", test_byte_order); + g_test_add_func ("/conversion/unicode", test_unicode_conversions); + g_test_add_func ("/conversion/filename-utf8", test_filename_utf8); + g_test_add_func ("/conversion/filename-display", test_filename_display); + g_test_add_func ("/conversion/convert-embedded-nul", test_convert_embedded_nul); + g_test_add_func ("/conversion/locale-to-utf8/embedded-nul", test_locale_to_utf8_embedded_nul); + g_test_add_func ("/conversion/locale-to-utf8/embedded-nul/subprocess/utf8", test_locale_to_utf8_embedded_nul_utf8); + g_test_add_func ("/conversion/locale-to-utf8/embedded-nul/subprocess/iconv", test_locale_to_utf8_embedded_nul_iconv); + g_test_add_func ("/conversion/locale-from-utf8/embedded-nul", test_locale_from_utf8_embedded_nul); + g_test_add_func ("/conversion/locale-from-utf8/embedded-nul/subprocess/utf8", test_locale_from_utf8_embedded_nul_utf8); + g_test_add_func ("/conversion/locale-from-utf8/embedded-nul/subprocess/iconv", test_locale_from_utf8_embedded_nul_iconv); + g_test_add_func ("/conversion/filename-to-utf8/embedded-nul", test_filename_to_utf8_embedded_nul); + g_test_add_func ("/conversion/filename-to-utf8/embedded-nul/subprocess/utf8", test_filename_to_utf8_embedded_nul_utf8); + g_test_add_func ("/conversion/filename-to-utf8/embedded-nul/subprocess/iconv", test_filename_to_utf8_embedded_nul_iconv); + g_test_add_func ("/conversion/filename-from-utf8/embedded-nul", test_filename_from_utf8_embedded_nul); + g_test_add_func ("/conversion/filename-from-utf8/embedded-nul/subprocess/utf8", test_filename_from_utf8_embedded_nul_utf8); + g_test_add_func ("/conversion/filename-from-utf8/embedded-nul/subprocess/iconv", test_filename_from_utf8_embedded_nul_iconv); + + return g_test_run (); +} diff --git a/glib/tests/cxx.cpp b/glib/tests/cxx.cpp new file mode 100644 index 0000000..6426d43 --- /dev/null +++ b/glib/tests/cxx.cpp @@ -0,0 +1,104 @@ +/* + * Copyright 2020 Xavier Claessens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include + +typedef struct +{ + int dummy; +} MyObject; + +static void +test_typeof (void) +{ +#if __cplusplus >= 201103L + // Test that with C++11 we don't get those kind of errors: + // error: invalid conversion from ‘gpointer’ {aka ‘void*’} to ‘MyObject*’ [-fpermissive] + MyObject *obj = g_rc_box_new0 (MyObject); + MyObject *obj2 = g_rc_box_acquire (obj); + g_assert_true (obj2 == obj); + + MyObject *obj3 = g_atomic_pointer_get (&obj2); + g_assert_true (obj3 == obj); + + MyObject *obj4 = nullptr; + g_atomic_pointer_set (&obj4, obj3); + g_assert_true (obj4 == obj); + + MyObject *obj5 = nullptr; + g_atomic_pointer_compare_and_exchange (&obj5, nullptr, obj4); + g_assert_true (obj5 == obj); + + MyObject *obj6 = g_steal_pointer (&obj5); + g_assert_true (obj6 == obj); + + g_clear_pointer (&obj6, g_rc_box_release); + g_rc_box_release (obj); +#else + g_test_skip ("This test requires a C++11 compiler"); +#endif +} + +static void +test_atomic_pointer_compare_and_exchange (void) +{ +#if __cplusplus >= 201103L + const gchar *str1 = "str1"; + const gchar *str2 = "str2"; + const gchar *atomic_string = str1; + + g_test_message ("Test that g_atomic_pointer_compare_and_exchange() with a " + "non-void* pointer doesn’t have any compiler warnings in C++ mode"); + + g_assert_true (g_atomic_pointer_compare_and_exchange (&atomic_string, str1, str2)); + g_assert_true (atomic_string == str2); +#else + g_test_skip ("This test requires a C++11 compiler"); +#endif +} + +static void +test_atomic_int_compare_and_exchange (void) +{ +#if __cplusplus >= 201103L + gint atomic_int = 5; + + g_test_message ("Test that g_atomic_int_compare_and_exchange() doesn’t have " + "any compiler warnings in C++ mode"); + + g_assert_true (g_atomic_int_compare_and_exchange (&atomic_int, 5, 50)); + g_assert_cmpint (atomic_int, ==, 50); +#else + g_test_skip ("This test requires a C++11 compiler"); +#endif +} + +int +main (int argc, char *argv[]) +{ +#if __cplusplus >= 201103L + g_test_init (&argc, &argv, nullptr); +#else + g_test_init (&argc, &argv, NULL); +#endif + + g_test_add_func ("/C++/typeof", test_typeof); + g_test_add_func ("/C++/atomic-pointer-compare-and-exchange", test_atomic_pointer_compare_and_exchange); + g_test_add_func ("/C++/atomic-int-compare-and-exchange", test_atomic_int_compare_and_exchange); + + return g_test_run (); +} diff --git a/glib/tests/dataset.c b/glib/tests/dataset.c new file mode 100644 index 0000000..b02b3e4 --- /dev/null +++ b/glib/tests/dataset.c @@ -0,0 +1,270 @@ +#include +#include + +static void +test_quark_basic (void) +{ + GQuark quark; + const gchar *orig = "blargh"; + gchar *copy; + const gchar *str; + + quark = g_quark_try_string ("no-such-quark"); + g_assert (quark == 0); + + copy = g_strdup (orig); + quark = g_quark_from_static_string (orig); + g_assert (quark != 0); + g_assert (g_quark_from_string (orig) == quark); + g_assert (g_quark_from_string (copy) == quark); + g_assert (g_quark_try_string (orig) == quark); + + str = g_quark_to_string (quark); + g_assert_cmpstr (str, ==, orig); + + g_free (copy); +} + +static void +test_quark_string (void) +{ + const gchar *orig = "string1"; + gchar *copy; + const gchar *str1; + const gchar *str2; + + copy = g_strdup (orig); + + str1 = g_intern_static_string (orig); + str2 = g_intern_string (copy); + g_assert (str1 == str2); + g_assert (str1 == orig); + + g_free (copy); +} + +static void +test_dataset_basic (void) +{ + gpointer location = (gpointer)test_dataset_basic; + gpointer other = (gpointer)test_quark_basic; + gpointer data = "test1"; + gpointer ret; + + g_dataset_set_data (location, "test1", data); + + ret = g_dataset_get_data (location, "test1"); + g_assert (ret == data); + + ret = g_dataset_get_data (location, "test2"); + g_assert (ret == NULL); + + ret = g_dataset_get_data (other, "test1"); + g_assert (ret == NULL); + + g_dataset_set_data (location, "test1", "new-value"); + ret = g_dataset_get_data (location, "test1"); + g_assert (ret != data); + + g_dataset_remove_data (location, "test1"); + ret = g_dataset_get_data (location, "test1"); + g_assert (ret == NULL); + + ret = g_dataset_get_data (location, NULL); + g_assert (ret == NULL); +} + +static gint destroy_count; + +static void +notify (gpointer data) +{ + destroy_count++; +} + +static void +test_dataset_full (void) +{ + gpointer location = (gpointer)test_dataset_full; + + g_dataset_set_data_full (location, "test1", "test1", notify); + + destroy_count = 0; + g_dataset_set_data (location, "test1", NULL); + g_assert (destroy_count == 1); + + g_dataset_set_data_full (location, "test1", "test1", notify); + + destroy_count = 0; + g_dataset_remove_data (location, "test1"); + g_assert (destroy_count == 1); + + g_dataset_set_data_full (location, "test1", "test1", notify); + + destroy_count = 0; + g_dataset_remove_no_notify (location, "test1"); + g_assert (destroy_count == 0); +} + +static void +foreach (GQuark id, + gpointer data, + gpointer user_data) +{ + gint *counter = user_data; + + *counter += 1; +} + +static void +test_dataset_foreach (void) +{ + gpointer location = (gpointer)test_dataset_foreach; + gint my_count; + + my_count = 0; + g_dataset_set_data_full (location, "test1", "test1", notify); + g_dataset_set_data_full (location, "test2", "test2", notify); + g_dataset_set_data_full (location, "test3", "test3", notify); + g_dataset_foreach (location, foreach, &my_count); + g_assert (my_count == 3); + + g_dataset_destroy (location); +} + +static void +test_dataset_destroy (void) +{ + gpointer location = (gpointer)test_dataset_destroy; + + destroy_count = 0; + g_dataset_set_data_full (location, "test1", "test1", notify); + g_dataset_set_data_full (location, "test2", "test2", notify); + g_dataset_set_data_full (location, "test3", "test3", notify); + g_dataset_destroy (location); + g_assert (destroy_count == 3); +} + +static void +test_dataset_id (void) +{ + gpointer location = (gpointer)test_dataset_id; + gpointer other = (gpointer)test_quark_basic; + gpointer data = "test1"; + gpointer ret; + GQuark quark; + + quark = g_quark_from_string ("test1"); + + g_dataset_id_set_data (location, quark, data); + + ret = g_dataset_id_get_data (location, quark); + g_assert (ret == data); + + ret = g_dataset_id_get_data (location, g_quark_from_string ("test2")); + g_assert (ret == NULL); + + ret = g_dataset_id_get_data (other, quark); + g_assert (ret == NULL); + + g_dataset_id_set_data (location, quark, "new-value"); + ret = g_dataset_id_get_data (location, quark); + g_assert (ret != data); + + g_dataset_id_remove_data (location, quark); + ret = g_dataset_id_get_data (location, quark); + g_assert (ret == NULL); + + ret = g_dataset_id_get_data (location, 0); + g_assert (ret == NULL); +} + +static GData *global_list; + +static void +free_one (gpointer data) +{ + /* recurse */ + g_datalist_clear (&global_list); +} + +static void +test_datalist_clear (void) +{ + /* Need to use a subprocess because it will deadlock if it fails */ + if (g_test_subprocess ()) + { + g_datalist_init (&global_list); + g_datalist_set_data_full (&global_list, "one", GINT_TO_POINTER (1), free_one); + g_datalist_set_data_full (&global_list, "two", GINT_TO_POINTER (2), NULL); + g_datalist_clear (&global_list); + g_assert (global_list == NULL); + return; + } + + g_test_trap_subprocess (NULL, 500000, 0); + g_test_trap_assert_passed (); +} + +static void +test_datalist_basic (void) +{ + GData *list = NULL; + gpointer data; + gpointer ret; + + g_datalist_init (&list); + data = "one"; + g_datalist_set_data (&list, "one", data); + ret = g_datalist_get_data (&list, "one"); + g_assert (ret == data); + + ret = g_datalist_get_data (&list, "two"); + g_assert (ret == NULL); + + ret = g_datalist_get_data (&list, NULL); + g_assert (ret == NULL); + + g_datalist_clear (&list); +} + +static void +test_datalist_id (void) +{ + GData *list = NULL; + gpointer data; + gpointer ret; + + g_datalist_init (&list); + data = "one"; + g_datalist_id_set_data (&list, g_quark_from_string ("one"), data); + ret = g_datalist_id_get_data (&list, g_quark_from_string ("one")); + g_assert (ret == data); + + ret = g_datalist_id_get_data (&list, g_quark_from_string ("two")); + g_assert (ret == NULL); + + ret = g_datalist_id_get_data (&list, 0); + g_assert (ret == NULL); + + g_datalist_clear (&list); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/quark/basic", test_quark_basic); + g_test_add_func ("/quark/string", test_quark_string); + g_test_add_func ("/dataset/basic", test_dataset_basic); + g_test_add_func ("/dataset/id", test_dataset_id); + g_test_add_func ("/dataset/full", test_dataset_full); + g_test_add_func ("/dataset/foreach", test_dataset_foreach); + g_test_add_func ("/dataset/destroy", test_dataset_destroy); + g_test_add_func ("/datalist/basic", test_datalist_basic); + g_test_add_func ("/datalist/id", test_datalist_id); + g_test_add_func ("/datalist/recursive-clear", test_datalist_clear); + + return g_test_run (); +} diff --git a/glib/tests/date.c b/glib/tests/date.c new file mode 100644 index 0000000..e382295 --- /dev/null +++ b/glib/tests/date.c @@ -0,0 +1,1811 @@ +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "glib.h" + +#include +#include +#include +#include +#include + +#ifdef G_OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include +/* mingw defines it while msvc doesn't */ +#ifndef SUBLANG_LITHUANIAN_LITHUANIA +#define SUBLANG_LITHUANIAN_LITHUANIA 0x01 +#endif +#endif + +static void +test_basic (void) +{ + GDate *d; + struct tm tm = { 0 }; + + /* g_date_valid (d) */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_false (g_date_valid (NULL)); + g_test_assert_expected_messages (); + } + + /* g_date_new_dmy (d, m, y) */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_null (g_date_new_dmy (0, 0, 0)); + g_test_assert_expected_messages (); + } + + d = g_date_new (); + if (g_test_undefined ()) + { + /* g_date_get_weekday (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_weekday (d), ==, G_DATE_BAD_WEEKDAY); + g_test_assert_expected_messages (); + + /* g_date_get_day (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_day (d), ==, G_DATE_BAD_DAY); + g_test_assert_expected_messages (); + + /* g_date_get_month (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_month (d), ==, G_DATE_BAD_MONTH); + g_test_assert_expected_messages (); + + /* g_date_get_year (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_year (d), ==, G_DATE_BAD_YEAR); + g_test_assert_expected_messages (); + + /* g_date_to_struct_tm (d, tm) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_to_struct_tm (d, &tm); + g_test_assert_expected_messages (); + + /* g_is_leap_year (y) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_false (g_date_is_leap_year (0)); + g_test_assert_expected_messages (); + + /* g_date_get_days_in_month (m, y) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_days_in_month (0, 1), ==, 0); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_days_in_month (1, 0), ==, 0); + g_test_assert_expected_messages (); + + /* g_date_set_time_t (d, t) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_time_t (NULL, 1); + g_test_assert_expected_messages (); + + /* g_date_is_first_of_month (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_false (g_date_is_first_of_month (d)); + g_test_assert_expected_messages (); + + /* g_date_is_last_of_month (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_false (g_date_is_last_of_month (d)); + g_test_assert_expected_messages (); + + /* g_date_add_days (d, n) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_add_days (d, 1); + g_test_assert_expected_messages (); + + /* g_date_subtract_days (d, n) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_subtract_days (d, 1); + g_test_assert_expected_messages (); + + /* g_date_add_months (d, n) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_add_months (d, 1); + g_test_assert_expected_messages (); + + /* g_date_subtract_months (d, n) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_subtract_months (d, 1); + g_test_assert_expected_messages (); + + /* g_date_add_years (d, y) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_add_years (d, 1); + g_test_assert_expected_messages (); + + /* g_date_subtract_years (d, y) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_subtract_years (d, 1); + g_test_assert_expected_messages (); + + /* g_date_set_month (d, m) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_month (NULL, 1); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_month (d, 13); + g_test_assert_expected_messages (); + + /* g_date_set_day (d, day) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_day (NULL, 1); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_day (d, 32); + g_test_assert_expected_messages (); + + /* g_date_set_year (d, y) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_year (NULL, 1); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_year (d, (GDateYear) (G_MAXUINT16 + 1)); + g_test_assert_expected_messages (); + + /* g_date_set_dmy (date, d, m, y) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_dmy (NULL, 1, 1, 1); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_dmy (d, 0, 0, 0); + g_test_assert_expected_messages (); + + /* g_date_set_julian (date, d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_julian (NULL, 1); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_julian (d, 0); + g_test_assert_expected_messages (); + + /* g_date_clear (d, n) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_clear (d, 0); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_clear (NULL, 1); + g_test_assert_expected_messages (); + } + + g_date_set_dmy (d, 1, 1, 1); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_to_struct_tm (d, NULL); + g_test_assert_expected_messages (); + } + g_date_free (d); + + g_assert_cmpint (sizeof (GDate), <, 9); + g_assert_false (g_date_valid_month (G_DATE_BAD_MONTH)); + g_assert_false (g_date_valid_month (13)); + g_assert_false (g_date_valid_day (G_DATE_BAD_DAY)); + g_assert_false (g_date_valid_day (32)); + g_assert_false (g_date_valid_year (G_DATE_BAD_YEAR)); + g_assert_false (g_date_valid_julian (G_DATE_BAD_JULIAN)); + g_assert_false (g_date_valid_weekday (G_DATE_BAD_WEEKDAY)); + g_assert_true (g_date_valid_weekday ((GDateWeekday) 1)); + g_assert_false (g_date_valid_weekday ((GDateWeekday) 8)); + g_assert_true (g_date_is_leap_year (2000)); + g_assert_false (g_date_is_leap_year (1999)); + g_assert_true (g_date_is_leap_year (1996)); + g_assert_true (g_date_is_leap_year (1600)); + g_assert_false (g_date_is_leap_year (2100)); + g_assert_false (g_date_is_leap_year (1800)); +} + +static void +test_empty_constructor (void) +{ + GDate *d; + + d = g_date_new (); + g_assert_false (g_date_valid (d)); + g_date_free (d); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_free (NULL); + g_test_assert_expected_messages (); + } + +} + +static void +test_dmy_constructor (void) +{ + GDate *d; + guint32 j; + + d = g_date_new_dmy (1, 1, 1); + g_assert_true (g_date_valid (d)); + + j = g_date_get_julian (d); + g_assert_cmpint (j, ==, 1); + g_assert_cmpint (g_date_get_month (d), ==, G_DATE_JANUARY); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 1); + g_date_free (d); +} + +static void +test_date_compare (void) +{ + GDate *d1; + GDate *d2; + + d1 = g_date_new (); + d2 = g_date_new (); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_days_between (d1, d2), ==, 0); + g_test_assert_expected_messages (); + + g_date_set_dmy (d1, 1, 1, 1); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_days_between (d1, d2), ==, 0); + g_test_assert_expected_messages (); + } + g_date_free (d1); + g_date_free (d2); + + d1 = g_date_new (); + d2 = g_date_new (); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_compare (NULL, d2), ==, 0); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_compare (d1, NULL), ==, 0); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_compare (d1, d2), ==, 0); + g_test_assert_expected_messages (); + + g_date_set_dmy (d1, 1, 1, 1); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_compare (d1, d2), ==, 0); + g_test_assert_expected_messages (); + } + g_date_free (d1); + g_date_free (d2); + + d1 = g_date_new (); + d2 = g_date_new (); + + /* DMY format */ + g_date_set_dmy (d1, 1, 1, 1); + g_date_set_dmy (d2, 10, 1, 1); + + g_assert_cmpint (g_date_compare (d1, d1), ==, 0); + + g_assert_cmpint (g_date_compare (d1, d2), ==, -1); + g_assert_cmpint (g_date_compare (d2, d1), >, 0); + + g_date_set_dmy (d2, 1, 10, 1); + g_assert_cmpint (g_date_compare (d1, d2), ==, -1); + g_assert_cmpint (g_date_compare (d2, d1), >, 0); + + g_date_set_dmy (d2, 1, 1, 10); + g_assert_cmpint (g_date_compare (d1, d2), ==, -1); + g_assert_cmpint (g_date_compare (d2, d1), >, 0); + + /* Julian format */ + g_date_set_julian (d1, 1); + g_date_set_julian (d2, 10); + + g_assert_cmpint (g_date_compare (d1, d1), ==, 0); + + g_assert_cmpint (g_date_compare (d1, d2), ==, -1); + g_assert_cmpint (g_date_compare (d2, d1), >, 0); + + g_date_set_julian (d2, 32); + g_assert_cmpint (g_date_compare (d1, d2), ==, -1); + g_assert_cmpint (g_date_compare (d2, d1), >, 0); + + g_date_set_julian (d2, 366); + g_assert_cmpint (g_date_compare (d1, d2), ==, -1); + g_assert_cmpint (g_date_compare (d2, d1), >, 0); + + g_date_free (d1); + g_date_free (d2); +} + +static void +test_julian_constructor (void) +{ + GDate *d1; + GDate *d2; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_null (g_date_new_julian (0)); + g_test_assert_expected_messages (); + } + + d1 = g_date_new (); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_julian (d1), ==, G_DATE_BAD_JULIAN); + g_test_assert_expected_messages (); + } + g_date_free (d1); + + d1 = g_date_new_julian (4000); + d2 = g_date_new_julian (5000); + g_assert_cmpint (g_date_get_julian (d1), ==, 4000); + g_assert_cmpint (g_date_days_between (d1, d2), ==, 1000); + g_assert_cmpint (g_date_get_year (d1), ==, 11); + g_assert_cmpint (g_date_get_day (d2), ==, 9); + g_date_free (d1); + g_date_free (d2); +} + +static void +test_dates (void) +{ + GDate *d; + GTimeVal tv; + time_t now; + + d = g_date_new (); + + /* getters on empty date */ + if (g_test_undefined ()) + { + /* g_date_get_day_of_year (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_day_of_year (d), ==, 0); + g_test_assert_expected_messages (); + + /* g_date_get_monday_week_of_year (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_monday_week_of_year (d), ==, 0); + g_test_assert_expected_messages (); + + /* g_date_get_monday_weeks_in_year (y) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_monday_weeks_in_year (0), ==, 0); + g_test_assert_expected_messages (); + + /* g_date_get_sunday_week_of_year (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_sunday_week_of_year (d), ==, 0); + g_test_assert_expected_messages (); + + /* g_date_get_sunday_weeks_in_year (y) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_sunday_weeks_in_year (0), ==, 0); + g_test_assert_expected_messages (); + + /* g_date_get_iso8601_week_of_year (d) */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_cmpint (g_date_get_iso8601_week_of_year (d), ==, 0); + g_test_assert_expected_messages (); + } + + g_date_free (d); + + /* Remove more time than we have */ + d = g_date_new_julian (1); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_subtract_days (d, 103); + g_test_assert_expected_messages (); + } + g_date_free (d); + + d = g_date_new_julian (375); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_subtract_months (d, 13); + g_test_assert_expected_messages (); + } + g_date_free (d); + + d = g_date_new_julian (375); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_subtract_years (d, 2); + g_test_assert_expected_messages (); + } + g_date_free (d); + + /* Test on leap years */ + g_assert_cmpint (g_date_get_monday_weeks_in_year (1764), ==, 53); + g_assert_cmpint (g_date_get_monday_weeks_in_year (1776), ==, 53); + + g_assert_cmpint (g_date_get_sunday_weeks_in_year (1792), ==, 53); + + /* Trigger the update of the dmy/julian parts */ + d = g_date_new_julian (1); + g_assert_cmpint (g_date_get_day_of_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_julian (1); + g_assert_cmpint (g_date_get_monday_week_of_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_julian (1); + g_assert_cmpint (g_date_get_sunday_week_of_year (d), ==, 0); + g_date_free (d); + + d = g_date_new_julian (1); + g_assert_cmpint (g_date_is_first_of_month (d), ==, 1); + g_date_free (d); + + d = g_date_new_dmy (31, 3, 8); + g_date_subtract_months (d, 1); + g_assert_cmpint (g_date_get_month (d), ==, 2); + g_assert_cmpint (g_date_get_day (d), ==, 29); + g_assert_cmpint (g_date_get_year (d), ==, 8); + g_date_free (d); + + d = g_date_new_julian (375); + g_date_add_months (d, 1); + g_assert_cmpint (g_date_get_month (d), ==, 2); + g_assert_cmpint (g_date_get_day (d), ==, 10); + g_assert_cmpint (g_date_get_year (d), ==, 2); + g_date_free (d); + + d = g_date_new_julian (375); + g_date_subtract_months (d, 1); + g_assert_cmpint (g_date_get_month (d), ==, 12); + g_assert_cmpint (g_date_get_day (d), ==, 10); + g_assert_cmpint (g_date_get_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_julian (375); + g_date_add_years (d, 1); + g_assert_cmpint (g_date_get_month (d), ==, 1); + g_assert_cmpint (g_date_get_day (d), ==, 10); + g_assert_cmpint (g_date_get_year (d), ==, 3); + g_date_free (d); + + d = g_date_new_julian (675); + g_date_subtract_years (d, 1); + g_assert_cmpint (g_date_get_month (d), ==, 11); + g_assert_cmpint (g_date_get_day (d), ==, 6); + g_assert_cmpint (g_date_get_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_dmy (28, 2, 7); + g_date_subtract_years (d, 1); + g_assert_cmpint (g_date_get_month (d), ==, 2); + g_assert_cmpint (g_date_get_day (d), ==, 28); + g_assert_cmpint (g_date_get_year (d), ==, 6); + g_date_free (d); + + d = g_date_new_dmy (29, 2, 8); + g_date_subtract_years (d, 1); + g_assert_cmpint (g_date_get_month (d), ==, 2); + g_assert_cmpint (g_date_get_day (d), ==, 28); + g_assert_cmpint (g_date_get_year (d), ==, 7); + g_date_free (d); + + d = g_date_new_dmy (1, 1, 1); + g_assert_cmpint (g_date_get_iso8601_week_of_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_julian (1); + g_date_set_year (d, 6); + g_assert_cmpint (g_date_get_month (d), ==, 1); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 6); + g_date_free (d); + + d = g_date_new_dmy (1, 1, 1); + g_date_set_year (d, 6); + g_assert_cmpint (g_date_get_month (d), ==, 1); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 6); + g_date_free (d); + + d = g_date_new_julian (1); + g_date_set_month (d, 6); + g_assert_cmpint (g_date_get_month (d), ==, 6); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_dmy (1, 1, 1); + g_date_set_month (d, 6); + g_assert_cmpint (g_date_get_month (d), ==, 6); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_julian (1); + g_date_set_day (d, 6); + g_assert_cmpint (g_date_get_month (d), ==, 1); + g_assert_cmpint (g_date_get_day (d), ==, 6); + g_assert_cmpint (g_date_get_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_dmy (1, 1, 1); + g_date_set_day (d, 6); + g_assert_cmpint (g_date_get_month (d), ==, 1); + g_assert_cmpint (g_date_get_day (d), ==, 6); + g_assert_cmpint (g_date_get_year (d), ==, 1); + g_date_free (d); + + d = g_date_new_julian (1); + g_assert_cmpint (g_date_get_month (d), ==, 1); + g_date_free (d); + + /* Correct usage */ + d = g_date_new (); + + /* today */ + now = time (NULL); + g_assert_cmpint (now, !=, (time_t) -1); + g_date_set_time (d, now); + g_assert_true (g_date_valid (d)); + + /* Unix epoch */ + g_date_set_time (d, 1); + g_assert_true (g_date_valid (d)); + + tv.tv_sec = 0; + tv.tv_usec = 0; + g_date_set_time_val (d, &tv); + g_assert_true (g_date_valid (d)); + + /* Julian day 1 */ + g_date_set_julian (d, 1); + g_assert_true (g_date_valid (d)); + + g_date_set_year (d, 3); + g_date_set_day (d, 3); + g_date_set_month (d, 3); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_year (d), ==, 3); + g_assert_cmpint (g_date_get_month (d), ==, 3); + g_assert_cmpint (g_date_get_day (d), ==, 3); + g_assert_false (g_date_is_first_of_month (d)); + g_assert_false (g_date_is_last_of_month (d)); + g_date_set_day (d, 1); + g_assert_true (g_date_is_first_of_month (d)); + g_date_subtract_days (d, 1); + g_assert_true (g_date_is_last_of_month (d)); + + /* Testing some other corner cases */ + g_date_set_dmy (d, 29, 2, 2000); + g_date_subtract_months (d, 2); + g_assert_cmpint (g_date_get_month (d), ==, 12); + g_assert_cmpint (g_date_get_day (d), ==, 29); + g_assert_cmpint (g_date_get_year (d), ==, 1999); + + /* Attempt to assign a February 29 to a non-leap year */ + g_date_set_month (d, 2); + g_date_set_day (d, 29); + g_assert_false (g_date_valid (d)); + g_date_set_year (d, 3); + g_assert_false (g_date_valid (d)); + + g_date_free (d); +} + +static void +test_strftime (void) +{ + gsize i; + GDate *d; + gchar buf[101]; + const gchar invalid[] = "hello\xffworld%x"; + gchar *oldlocale; +#ifdef G_OS_WIN32 + LCID old_lcid; +#endif + + struct + { + const gchar *format; + const gchar *expect; + } strftime_checks[] = { + { "%A", "Monday" }, + { "%a", "Mon" }, + { "%D", "01/01/01" }, + { "%d", "01" }, + { "%e", " 1" }, + { "%H", "00" }, + { "%I", "12" }, + { "%j", "001" }, + { "%M", "00" }, + { "%m", "01" }, + { "%n", "\n" }, + { "%OB", "January" }, + { "%Ob", "Jan" }, + { "%p", "AM" }, + { "%R", "00:00" }, + { "%S", "00" }, + { "%T", "00:00:00" }, + { "%t", "\t" }, + { "%U", "00" }, + { "%u", "1" }, + { "%V", "01" }, + { "%W", "01" }, + { "%w", "1" }, + { "%y", "01" }, + { "%z", "" }, + { "%%", "%" }, +#if defined(G_OS_WIN32) + { "%C", "00" }, + { "%c", " 12:00:00 AM" }, + { "%E", "" }, + { "%F", "" }, + { "%G", "" }, + { "%g", "" }, + { "%h", "" }, + { "%k", "" }, + { "%l", "" }, + { "%O", "" }, + { "%P", "" }, + { "%r", "12:00:00AM" }, + { "%X", "12:00:00 AM" }, + { "%x", "" }, + { "%Y", "0001" }, +#else + { "%B", "January" }, + { "%b", "Jan" }, +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) + { "%C", "00" }, + { "%c", "Mon Jan 1 00:00:00 0001" }, + { "%E", "E" }, + { "%F", "0001-01-01" }, + { "%G", "0001" }, + { "%O", "O" }, + { "%P", "P" }, + { "%Y", "0001" }, +#else + { "%C", "0" }, + { "%c", "Mon Jan 1 00:00:00 1" }, + { "%E", "%E" }, + { "%F", "1-01-01" }, + { "%G", "1" }, + { "%O", "%O" }, + { "%P", "am" }, + { "%Y", "1" }, +#endif + { "%g", "01" }, + { "%h", "Jan" }, + { "%k", " 0" }, + { "%l", "12" }, + { "%r", "12:00:00 AM" }, + { "%X", "00:00:00" }, + { "%x", "01/01/01" }, + { "%Z", "" }, +#endif + }; + + oldlocale = g_strdup (setlocale (LC_ALL, NULL)); +#ifdef G_OS_WIN32 + old_lcid = GetThreadLocale (); +#endif + + /* Make sure that nothing has been changed in the original locales. */ + setlocale (LC_ALL, "C"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); +#endif + + d = g_date_new (); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_strftime (buf, sizeof (buf), "%x", d); + g_test_assert_expected_messages (); + } + + /* Trying invalid character */ +#ifndef G_OS_WIN32 + if (g_test_undefined ()) + { + g_date_set_dmy (d, 10, 1, 2000); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*Error*"); + g_date_strftime (buf, sizeof (buf), invalid, d); + g_test_assert_expected_messages (); + g_assert_cmpstr (buf, ==, ""); + } +#else + g_date_set_dmy (d, 10, 1, 2000); + g_date_strftime (buf, sizeof (buf), invalid, d); + g_assert_cmpstr (buf, ==, ""); +#endif + + /* Test positive cases */ + g_date_set_dmy (d, 1, 1, 1); + + for (i = 0; i < G_N_ELEMENTS (strftime_checks); i++) + { + g_date_strftime (buf, sizeof (buf), strftime_checks[i].format, d); + g_assert_cmpstr (buf, ==, strftime_checks[i].expect); + } + +#ifdef G_OS_WIN32 + /* + * Time zone is too versatile on OS_WIN32 to be checked precisely, + * According to msdn: "Either the locale's time-zone name + * or time zone abbreviation, depending on registry settings; no characters + * if time zone is unknown". + */ + g_assert_cmpint (g_date_strftime (buf, sizeof (buf), "%Z", d), !=, 0); +#endif + + g_date_free (d); + + setlocale (LC_ALL, oldlocale); + g_free (oldlocale); +#ifdef G_OS_WIN32 + SetThreadLocale (old_lcid); +#endif +} + +static void +test_two_digit_years (void) +{ + GDate *d; + gchar buf[101]; + gchar *old_locale; + gboolean use_alternative_format = FALSE; + +#ifdef G_OS_WIN32 + LCID old_lcid; +#endif + + old_locale = g_strdup (setlocale (LC_ALL, NULL)); +#ifdef G_OS_WIN32 + old_lcid = GetThreadLocale (); +#endif + + /* Make sure that nothing has been changed in the original locales. */ + setlocale (LC_ALL, "C"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT)); +#endif + + d = g_date_new (); + + /* Check two digit years */ + g_date_set_dmy (d, 10, 10, 1976); + g_date_strftime (buf, sizeof (buf), "%D", d); + g_assert_cmpstr (buf, ==, "10/10/76"); + g_date_set_parse (d, buf); + +#ifdef G_OS_WIN32 + /* + * It depends on the locale setting whether the dd/mm/yy + * format is allowed for g_date_set_parse() on Windows, which + * corresponds to whether there is an d/M/YY or d/M/YYYY (or so) + * option in the "Date and Time Format" setting for the selected + * locale in the Control Panel settings. If g_date_set_parse() + * renders the GDate invalid with the dd/mm/yy format, use an + * alternative format (yy/mm/dd) for g_date_set_parse() for the + * 2-digit year tests. + */ + if (!g_date_valid (d)) + use_alternative_format = TRUE; +#endif + + if (use_alternative_format) + g_date_set_parse (d, "76/10/10"); + + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 10); + g_assert_true ((g_date_get_year (d) == 1976) || + (g_date_get_year (d) == 76)); + + /* Check two digit years below 100 */ + g_date_set_dmy (d, 10, 10, 29); + g_date_strftime (buf, sizeof (buf), "%D", d); + g_assert_cmpstr (buf, ==, "10/10/29"); + g_date_set_parse (d, use_alternative_format ? "29/10/10" : buf); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 10); + g_assert_true ((g_date_get_year (d) == 2029) || + (g_date_get_year (d) == 29)); + + g_date_free (d); + + setlocale (LC_ALL, old_locale); + g_free (old_locale); +#ifdef G_OS_WIN32 + SetThreadLocale (old_lcid); +#endif +} + +static void +test_parse (void) +{ + GDate *d; + gchar buf[101]; + + d = g_date_new (); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_set_parse (NULL, ""); + g_test_assert_expected_messages (); + } + + g_date_set_time (d, 1); + g_assert_true (g_date_valid (d)); + g_date_strftime (buf, sizeof (buf), "Today is a %A, in the month of %B, %x", d); + g_date_set_parse (d, buf); + + if (g_test_undefined ()) + { + /* g_date_strftime() */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_strftime (NULL, 100, "%x", d); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_strftime (buf, 0, "%x", d); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_strftime (buf, sizeof (buf), NULL, d); + g_test_assert_expected_messages (); + } + + g_date_set_julian (d, 1); + g_assert_true (g_date_valid (d)); +#ifndef G_OS_WIN32 + /* Windows FILETIME does not support dates before Jan 1 1601, + so we can't strftime() the beginning of the "Julian" epoch. */ + g_date_strftime (buf, sizeof (buf), "Today is a %A, in the month of %B, %x", d); + g_date_set_parse (d, buf); +#endif + + g_date_set_dmy (d, 10, 1, 2000); + g_assert_true (g_date_valid (d)); + g_date_strftime (buf, sizeof (buf), "%x", d); + g_date_set_parse (d, buf); + g_assert_cmpint (g_date_get_month (d), ==, 1); + g_assert_cmpint (g_date_get_day (d), ==, 10); + g_assert_cmpint (g_date_get_year (d), ==, 2000); + + g_date_set_parse (d, "2001 10 1"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 2001); + + g_date_set_parse (d, "2001 10"); + g_assert_false (g_date_valid (d)); + + g_date_set_parse (d, "2001 10 1 1"); + g_assert_false (g_date_valid (d)); + + g_date_set_parse (d, "2001-10-01"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 2001); + + g_date_set_parse (d, "March 1999"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 3); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 1999); + + g_date_set_parse (d, "October 98"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 98); + + g_date_set_parse (d, "oCT 98"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 98); + + g_date_set_parse (d, "10/24/98"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 24); + g_assert_true (g_date_get_year (d) == 1998 || + g_date_get_year (d) == 98); + + g_date_set_parse (d, "10 -- 24 -- 98"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 24); + g_assert_true (g_date_get_year (d) == 1998 || + g_date_get_year (d) == 98); + + g_date_set_parse (d, "10/24/1998"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 24); + g_assert_cmpint (g_date_get_year (d), ==, 1998); + + g_date_set_parse (d, "October 24, 1998"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 24); + g_assert_cmpint (g_date_get_year (d), ==, 1998); + + g_date_set_parse (d, "10 Sep 1087"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 9); + g_assert_cmpint (g_date_get_day (d), ==, 10); + g_assert_cmpint (g_date_get_year (d), ==, 1087); + + g_date_set_parse (d, "19990301"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 3); + g_assert_cmpint (g_date_get_day (d), ==, 1); + g_assert_cmpint (g_date_get_year (d), ==, 1999); + + g_date_set_parse (d, "981024"); + g_assert_true (g_date_valid (d)); + g_assert_cmpint (g_date_get_month (d), ==, 10); + g_assert_cmpint (g_date_get_day (d), ==, 24); + g_assert_true (g_date_get_year (d) == 1998 || + g_date_get_year (d) == 98); + + /* Catching some invalid dates */ + g_date_set_parse (d, "20011320"); + g_assert_false (g_date_valid (d)); + + g_date_set_parse (d, "19998 10 1"); + g_assert_false (g_date_valid (d)); + + g_date_free (d); +} + +static void +test_parse_invalid (void) +{ + const gchar * const strs[] = + { + /* Incomplete UTF-8 sequence */ + "\xfd", + /* Ridiculously long input */ + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (strs); i++) + { + GDate *d = g_date_new (); + + g_test_message ("Test %" G_GSIZE_FORMAT, i); + g_date_set_parse (d, strs[i]); + + g_assert_false (g_date_valid (d)); + + g_date_free (d); + } +} + +static void +test_parse_locale_change (void) +{ + /* Checks that g_date_set_parse correctly changes locale specific data as + * necessary. In this particular case year adjustment, as Thai calendar is + * 543 years ahead of the Gregorian calendar. */ + + GDate date; + + if (setlocale (LC_ALL, "th_TH") == NULL) + { + g_test_skip ("locale th_TH not available"); + return; + } + + g_date_set_parse (&date, "04/07/2519"); + + setlocale (LC_ALL, "C"); + g_date_set_parse (&date, "07/04/76"); + g_assert_cmpint (g_date_get_day (&date), ==, 4); + g_assert_cmpint (g_date_get_month (&date), ==, 7); +#ifdef G_OS_WIN32 + /* Windows g_date_strftime() implementation doesn't use twodigit_years */ + /* FIXME: check if the function can be changed to return 4 digit years instead + * See https://gitlab.gnome.org/GNOME/glib/-/issues/2604 */ + g_assert_cmpint (g_date_get_year (&date), ==, 76); +#else + g_assert_cmpint (g_date_get_year (&date), ==, 1976); +#endif + + setlocale (LC_ALL, ""); +} + +static void +test_month_substring (void) +{ + GDate date; +#ifdef G_OS_WIN32 + LCID old_lcid; +#endif + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=793550"); + + if (setlocale (LC_ALL, "pl_PL") == NULL) + { + g_test_skip ("pl_PL locale not available"); + return; + } + +#ifdef G_OS_WIN32 + /* after the crt, set also the win32 thread locale: */ + /* https://www.codeproject.com/Articles/9600/Windows-SetThreadLocale-and-CRT-setlocale */ + old_lcid = GetThreadLocale (); + SetThreadLocale (MAKELCID (MAKELANGID (LANG_POLISH, SUBLANG_POLISH_POLAND), SORT_DEFAULT)); +#endif + + /* In Polish language September is "wrzesieÅ„" and August is "sierpieÅ„" + * abbreviated as "sie". The former used to be confused with the latter + * because "sie" is a substring of "wrzesieÅ„" and was matched first. */ + + g_date_set_parse (&date, "wrzesieÅ„ 2018"); + g_assert_true (g_date_valid (&date)); + g_assert_cmpint (g_date_get_month (&date), ==, G_DATE_SEPTEMBER); + + g_date_set_parse (&date, "sie 2018"); + g_assert_true (g_date_valid (&date)); + g_assert_cmpint (g_date_get_month (&date), ==, G_DATE_AUGUST); + + g_date_set_parse (&date, "sierpieÅ„ 2018"); + g_assert_true (g_date_valid (&date)); + g_assert_cmpint (g_date_get_month (&date), ==, G_DATE_AUGUST); + +#ifdef G_OS_WIN32 + SetThreadLocale (old_lcid); +#endif + setlocale (LC_ALL, ""); +} + + +static void +test_month_names (void) +{ +#if defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) + GDate *gdate; + gchar buf[101]; + gchar *oldlocale; +#ifdef G_OS_WIN32 + LCID old_lcid; +#endif +#endif /* defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) */ + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=749206"); + + /* If running uninstalled (G_TEST_BUILDDIR is set), skip this test, since we + * need the translations to be installed. We can’t mess around with + * bindtextdomain() here, as the compiled .gmo files in po/ are not in the + * right installed directory hierarchy to be successfully loaded by gettext. */ + if (g_getenv ("G_TEST_BUILDDIR") != NULL) + { + g_test_skip ("Skipping due to running uninstalled. " + "This test can only be run when the translations are installed."); + return; + } + + /* This test can only work (on non-Windows platforms) if libc supports + * the %OB (etc.) format placeholders. If it doesn’t, strftime() (and hence + * g_date_strftime()) will return the placeholder unsubstituted. + * g_date_strftime() explicitly documents that it doesn’t provide any more + * format placeholders than the system strftime(), so we should skip the test + * in that case. If people need %OB support, they should depend on a suitable + * version of libc, or use g_date_time_format(). Note: a test for a support + * of _NL_ABALTMON_* is not strictly the same as checking for %OB support. + * Some platforms (BSD, OS X) support %OB while _NL_ABALTMON_* and %Ob + * are supported only by glibc 2.27 and newer. But we don’t care about BSD + * here, the aim of this test is to make sure that our custom implementation + * for Windows works the same as glibc 2.27 native implementation. */ +#if !defined(HAVE_LANGINFO_ABALTMON) && !defined(G_OS_WIN32) + g_test_skip ("libc doesn’t support all alternative month names"); +#else + +#define TEST_DATE(d, m, y, f, o) \ + G_STMT_START \ + { \ + gchar *o_casefold, *buf_casefold; \ + g_date_set_dmy (gdate, d, m, y); \ + g_date_strftime (buf, sizeof (buf), f, gdate); \ + buf_casefold = g_utf8_casefold (buf, -1); \ + o_casefold = g_utf8_casefold ((o), -1); \ + g_assert_cmpstr (buf_casefold, ==, o_casefold); \ + g_free (buf_casefold); \ + g_free (o_casefold); \ + g_date_set_parse (gdate, buf); \ + g_assert_true (g_date_valid (gdate)); \ + g_assert_cmpint (g_date_get_day (gdate), ==, d); \ + g_assert_cmpint (g_date_get_month (gdate), ==, m); \ + g_assert_cmpint (g_date_get_year (gdate), ==, y); \ + } \ + G_STMT_END + + oldlocale = g_strdup (setlocale (LC_ALL, NULL)); +#ifdef G_OS_WIN32 + old_lcid = GetThreadLocale (); +#endif + + gdate = g_date_new (); + + /* Note: Windows implementation of g_date_strftime() does not support + * "-" format modifier (e.g., "%-d", "%-e") so we will not use it. + */ + + /* Make sure that nothing has been changed in western European languages. */ + setlocale (LC_ALL, "en_GB.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_UK), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "en_GB") != NULL) + { + TEST_DATE (1, 1, 2018, "%B %d, %Y", "January 01, 2018"); + TEST_DATE (1, 2, 2018, "%OB %Y", "February 2018"); + TEST_DATE (1, 3, 2018, "%e %b %Y", " 1 Mar 2018"); + TEST_DATE (1, 4, 2018, "%Ob %Y", "Apr 2018"); + TEST_DATE (1, 5, 2018, "%d %h %Y", "01 May 2018"); + TEST_DATE (1, 6, 2018, "%Oh %Y", "Jun 2018"); + } + else + g_test_skip ("locale en_GB not available, skipping English month names test"); + + setlocale (LC_ALL, "de_DE.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "de_DE") != NULL) + { + TEST_DATE (16, 7, 2018, "%d. %B %Y", "16. Juli 2018"); + TEST_DATE ( 1, 8, 2018, "%OB %Y", "August 2018"); + TEST_DATE (18, 9, 2018, "%e. %b %Y", "18. Sep 2018"); + TEST_DATE ( 1, 10, 2018, "%Ob %Y", "Okt 2018"); + TEST_DATE (20, 11, 2018, "%d. %h %Y", "20. Nov 2018"); + TEST_DATE ( 1, 12, 2018, "%Oh %Y", "Dez 2018"); + } + else + g_test_skip ("locale de_DE not available, skipping German month names test"); + + + setlocale (LC_ALL, "es_ES.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "es_ES") != NULL) + { + TEST_DATE ( 9, 1, 2018, "%d de %B de %Y", "09 de enero de 2018"); + TEST_DATE ( 1, 2, 2018, "%OB de %Y", "febrero de 2018"); +#if defined(G_OS_WIN32) && defined(_UCRT) + TEST_DATE (10, 3, 2018, "%e de %b de %Y", "10 de mar. de 2018"); + TEST_DATE ( 1, 4, 2018, "%Ob de %Y", "abr. de 2018"); + TEST_DATE (11, 5, 2018, "%d de %h de %Y", "11 de may. de 2018"); + TEST_DATE ( 1, 6, 2018, "%Oh de %Y", "jun. de 2018"); +#else + TEST_DATE (10, 3, 2018, "%e de %b de %Y", "10 de mar de 2018"); + TEST_DATE ( 1, 4, 2018, "%Ob de %Y", "abr de 2018"); + TEST_DATE (11, 5, 2018, "%d de %h de %Y", "11 de may de 2018"); + TEST_DATE ( 1, 6, 2018, "%Oh de %Y", "jun de 2018"); +#endif + } + else + g_test_skip ("locale es_ES not available, skipping Spanish month names test"); + + setlocale (LC_ALL, "fr_FR.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_FRENCH, SUBLANG_FRENCH), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "fr_FR") != NULL) + { + TEST_DATE (31, 7, 2018, "%d %B %Y", "31 juillet 2018"); + TEST_DATE ( 1, 8, 2018, "%OB %Y", "août 2018"); + TEST_DATE (30, 9, 2018, "%e %b %Y", "30 sept. 2018"); + TEST_DATE ( 1, 10, 2018, "%Ob %Y", "oct. 2018"); + TEST_DATE (29, 11, 2018, "%d %h %Y", "29 nov. 2018"); + TEST_DATE ( 1, 12, 2018, "%Oh %Y", "déc. 2018"); + } + else + g_test_skip ("locale fr_FR not available, skipping French month names test"); + + /* Make sure that there are visible changes in some European languages. */ + setlocale (LC_ALL, "el_GR.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_GREEK, SUBLANG_GREEK_GREECE), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "el_GR") != NULL) + { + TEST_DATE ( 2, 1, 2018, "%d %B %Y", "02 ΙανουαÏίου 2018"); + TEST_DATE ( 4, 2, 2018, "%e %B %Y", " 4 ΦεβÏουαÏίου 2018"); + TEST_DATE (15, 3, 2018, "%d %B %Y", "15 ΜαÏτίου 2018"); + TEST_DATE ( 1, 4, 2018, "%OB %Y", "ΑπÏίλιος 2018"); + TEST_DATE ( 1, 5, 2018, "%OB %Y", "Μάιος 2018"); + TEST_DATE ( 1, 6, 2018, "%OB %Y", "ΙοÏνιος 2018"); + TEST_DATE (16, 7, 2018, "%e %b %Y", "16 Ιουλ 2018"); +#if defined(G_OS_WIN32) && defined(_UCRT) + TEST_DATE ( 1, 8, 2018, "%Ob %Y", "Αυγ 2018"); +#else + TEST_DATE ( 1, 8, 2018, "%Ob %Y", "ΑÏγ 2018"); +#endif + } + else + g_test_skip ("locale el_GR not available, skipping Greek month names test"); + + setlocale (LC_ALL, "hr_HR.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_CROATIAN, SUBLANG_CROATIAN_CROATIA), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "hr_HR") != NULL) + { + TEST_DATE ( 8, 5, 2018, "%d. %B %Y", "08. svibnja 2018"); + TEST_DATE ( 9, 6, 2018, "%e. %B %Y", " 9. lipnja 2018"); + TEST_DATE (10, 7, 2018, "%d. %B %Y", "10. srpnja 2018"); + TEST_DATE ( 1, 8, 2018, "%OB %Y", "Kolovoz 2018"); + TEST_DATE ( 1, 9, 2018, "%OB %Y", "Rujan 2018"); + TEST_DATE ( 1, 10, 2018, "%OB %Y", "Listopad 2018"); + TEST_DATE (11, 11, 2018, "%e. %b %Y", "11. Stu 2018"); + TEST_DATE ( 1, 12, 2018, "%Ob %Y", "Pro 2018"); + } + else + g_test_skip ("locale hr_HR not available, skipping Croatian month names test"); + + setlocale (LC_ALL, "lt_LT.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_LITHUANIAN, SUBLANG_LITHUANIAN_LITHUANIA), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "lt_LT") != NULL) + { + TEST_DATE ( 1, 1, 2018, "%Y m. %B %d d.", "2018 m. sausio 01 d."); + TEST_DATE ( 2, 2, 2018, "%Y m. %B %e d.", "2018 m. vasario 2 d."); + TEST_DATE ( 3, 3, 2018, "%Y m. %B %d d.", "2018 m. kovo 03 d."); + TEST_DATE ( 1, 4, 2018, "%Y m. %OB", "2018 m. balandis"); + TEST_DATE ( 1, 5, 2018, "%Y m. %OB", "2018 m. gegužė"); + TEST_DATE ( 1, 6, 2018, "%Y m. %OB", "2018 m. birželis"); + TEST_DATE (17, 7, 2018, "%Y m. %b %e d.", "2018 m. liep. 17 d."); + TEST_DATE ( 1, 8, 2018, "%Y m. %Ob", "2018 m. rugp."); + } + else + g_test_skip ("locale lt_LT not available, skipping Lithuanian month names test"); + + setlocale (LC_ALL, "pl_PL.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_POLISH, SUBLANG_POLISH_POLAND), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "pl_PL") != NULL) + { + TEST_DATE ( 3, 5, 2018, "%d %B %Y", "03 maja 2018"); + TEST_DATE ( 4, 6, 2018, "%e %B %Y", " 4 czerwca 2018"); + TEST_DATE (20, 7, 2018, "%d %B %Y", "20 lipca 2018"); + TEST_DATE ( 1, 8, 2018, "%OB %Y", "sierpieÅ„ 2018"); + TEST_DATE ( 1, 9, 2018, "%OB %Y", "wrzesieÅ„ 2018"); + TEST_DATE ( 1, 10, 2018, "%OB %Y", "październik 2018"); + TEST_DATE (25, 11, 2018, "%e %b %Y", "25 lis 2018"); + TEST_DATE ( 1, 12, 2018, "%Ob %Y", "gru 2018"); + } + else + g_test_skip ("locale pl_PL not available, skipping Polish month names test"); + + setlocale (LC_ALL, "ru_RU.utf-8"); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA), SORT_DEFAULT)); +#endif + if (strstr (setlocale (LC_ALL, NULL), "ru_RU") != NULL) + { + TEST_DATE ( 3, 1, 2018, "%d %B %Y", "03 ÑÐ½Ð²Ð°Ñ€Ñ 2018"); + TEST_DATE ( 4, 2, 2018, "%e %B %Y", " 4 Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ 2018"); + TEST_DATE (23, 3, 2018, "%d %B %Y", "23 марта 2018"); + TEST_DATE ( 1, 4, 2018, "%OB %Y", "Ðпрель 2018"); + TEST_DATE ( 1, 5, 2018, "%OB %Y", "Май 2018"); + TEST_DATE ( 1, 6, 2018, "%OB %Y", "Июнь 2018"); + TEST_DATE (24, 7, 2018, "%e %b %Y", "24 июл 2018"); + TEST_DATE ( 1, 8, 2018, "%Ob %Y", "авг 2018"); + /* This difference is very important in Russian: */ + TEST_DATE (19, 5, 2018, "%e %b %Y", "19 Ð¼Ð°Ñ 2018"); + TEST_DATE (20, 5, 2018, "%Ob, %d-е, %Y", "май, 20-е, 2018"); + } + else + g_test_skip ("locale ru_RU not available, skipping Russian month names test"); + + g_date_free (gdate); + + setlocale (LC_ALL, oldlocale); +#ifdef G_OS_WIN32 + SetThreadLocale (old_lcid); +#endif + g_free (oldlocale); +#endif /* defined(HAVE_LANGINFO_ABALTMON) || defined(G_OS_WIN32) */ +} + +static void +test_year (gconstpointer t) +{ + GDateYear y = GPOINTER_TO_INT (t); + GDateMonth m; + GDateDay day; + guint32 j; + GDate *d; + gint i; + GDate tmp; + + guint32 first_day_of_year = G_DATE_BAD_JULIAN; + guint16 days_in_year = g_date_is_leap_year (y) ? 366 : 365; + guint sunday_week_of_year = 0; + guint sunday_weeks_in_year = g_date_get_sunday_weeks_in_year (y); + guint monday_week_of_year = 0; + guint monday_weeks_in_year = g_date_get_monday_weeks_in_year (y); + guint iso8601_week_of_year = 0; + + g_assert_true (g_date_valid_year (y)); + /* Years ought to have roundabout 52 weeks */ + g_assert (sunday_weeks_in_year == 52 || sunday_weeks_in_year == 53); + g_assert (monday_weeks_in_year == 52 || monday_weeks_in_year == 53); + + m = 1; + while (m < 13) + { + guint8 dim = g_date_get_days_in_month (m, y); + GDate days[31]; + + g_date_clear (days, 31); + + g_assert (dim > 0 && dim < 32); + g_assert_true (g_date_valid_month (m)); + + day = 1; + while (day <= dim) + { + g_assert_true (g_date_valid_dmy (day, m, y)); + + d = &days[day - 1]; + g_assert_false (g_date_valid (d)); + + g_date_set_dmy (d, day, m, y); + + g_assert_true (g_date_valid (d)); + + if (m == G_DATE_JANUARY && day == 1) + first_day_of_year = g_date_get_julian (d); + + g_assert_cmpint (first_day_of_year, !=, G_DATE_BAD_JULIAN); + + g_assert_cmpint (g_date_get_month (d), ==, m); + g_assert_cmpint (g_date_get_year (d), ==, y); + g_assert_cmpint (g_date_get_day (d), ==, day); + + g_assert_cmpint (g_date_get_julian (d) + 1 - first_day_of_year, + ==, + g_date_get_day_of_year (d)); + + if (m == G_DATE_DECEMBER && day == 31) + g_assert_cmpint (g_date_get_day_of_year (d), ==, days_in_year); + + g_assert_cmpint (g_date_get_day_of_year (d), <=, days_in_year); + g_assert_cmpint (g_date_get_monday_week_of_year (d), + <=, monday_weeks_in_year); + g_assert_cmpint (g_date_get_monday_week_of_year (d), + >=, monday_week_of_year); + + if (g_date_get_weekday(d) == G_DATE_MONDAY) + { + g_assert_cmpint (g_date_get_monday_week_of_year (d) - + monday_week_of_year, + ==, 1); + if ((m == G_DATE_JANUARY && day <= 4) || + (m == G_DATE_DECEMBER && day >= 29)) + g_assert_cmpint (g_date_get_iso8601_week_of_year (d), + ==, 1); + else + g_assert_cmpint (g_date_get_iso8601_week_of_year (d) - + iso8601_week_of_year, + ==, 1); + } + else + { + g_assert_cmpint (g_date_get_monday_week_of_year (d) - + monday_week_of_year, + ==, 0); + if (!(day == 1 && m == G_DATE_JANUARY)) + g_assert_cmpint (g_date_get_iso8601_week_of_year (d) - + iso8601_week_of_year, + ==, 0); + } + + monday_week_of_year = g_date_get_monday_week_of_year (d); + iso8601_week_of_year = g_date_get_iso8601_week_of_year (d); + + g_assert_cmpint (g_date_get_sunday_week_of_year (d), + <=, sunday_weeks_in_year); + g_assert_cmpint (g_date_get_sunday_week_of_year (d), + >=, sunday_week_of_year); + if (g_date_get_weekday(d) == G_DATE_SUNDAY) + g_assert_cmpint (g_date_get_sunday_week_of_year (d) - + sunday_week_of_year, + ==, 1); + else + g_assert_cmpint (g_date_get_sunday_week_of_year (d) - + sunday_week_of_year, + ==, 0); + + sunday_week_of_year = g_date_get_sunday_week_of_year (d); + + g_assert_cmpint (g_date_compare (d, d), ==, 0); + + i = 1; + while (i < 402) /* Need to get 400 year increments in */ + { + tmp = *d; + g_date_add_days (d, i); + g_assert_cmpint (g_date_compare (d, &tmp), >, 0); + g_date_subtract_days (d, i); + g_assert_cmpint (g_date_get_day (d), ==, day); + g_assert_cmpint (g_date_get_month (d), ==, m); + g_assert_cmpint (g_date_get_year (d), ==, y); + + tmp = *d; + g_date_add_months (d, i); + g_assert_cmpint (g_date_compare (d, &tmp), >, 0); + g_date_subtract_months (d, i); + g_assert_cmpint (g_date_get_month (d), ==, m); + g_assert_cmpint (g_date_get_year (d), ==, y); + + if (day < 29) + g_assert_cmpint (g_date_get_day (d), ==, day); + else + g_date_set_day (d, day); + + tmp = *d; + g_date_add_years (d, i); + g_assert_cmpint (g_date_compare (d, &tmp), >, 0); + g_date_subtract_years (d, i); + g_assert_cmpint (g_date_get_month (d), ==, m); + g_assert_cmpint (g_date_get_year (d), ==, y); + + if (m != 2 && day != 29) + g_assert_cmpint (g_date_get_day (d), ==, day); + else + g_date_set_day (d, day); /* reset */ + + i += 10; + } + + j = g_date_get_julian (d); + + ++day; + } + ++m; + } + + /* at this point, d is the last day of year y */ + g_date_set_dmy (&tmp, 1, 1, y + 1); + g_assert_cmpint (j + 1, ==, g_date_get_julian (&tmp)); + + g_date_add_days (&tmp, 1); + g_assert_cmpint (j + 2, ==, g_date_get_julian (&tmp)); +} + +static void +test_clamp (void) +{ + GDate *d, *d1, *d2, *o; + + d = g_date_new (); + d1 = g_date_new (); + d2 = g_date_new (); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_clamp (d, d1, d2); + g_test_assert_expected_messages (); + } + + g_date_set_dmy (d, 1, 1, 1); + g_date_clamp (d, NULL, NULL); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_clamp (d, d1, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_clamp (d, d1, d2); + g_test_assert_expected_messages (); + } + + g_date_set_dmy (d1, 1, 1, 1970); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_clamp (d, d1, d2); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_clamp (d, NULL, d2); + g_test_assert_expected_messages (); + } + + g_date_set_dmy (d2, 1, 1, 1980); + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_clamp (d, d2, d1); + g_test_assert_expected_messages (); + } + + o = g_date_copy (d); + g_date_clamp (o, NULL, NULL); + g_assert_cmpint (g_date_compare (o, d), ==, 0); + + g_date_clamp (o, d1, d2); + g_assert_cmpint (g_date_compare (o, d1), ==, 0); + + g_date_set_dmy (o, 1, 1, 2000); + + g_date_clamp (o, d1, d2); + g_assert_cmpint (g_date_compare (o, d2), ==, 0); + + g_date_free (d); + g_date_free (d1); + g_date_free (d2); + g_date_free (o); +} + +static void +test_order (void) +{ + GDate *d1, *d2; + + d1 = g_date_new (); + d2 = g_date_new (); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_order (d1, d2); + g_test_assert_expected_messages (); + } + + g_date_set_dmy (d1, 1, 1, 1970); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_date_order (d1, d2); + g_test_assert_expected_messages (); + } + + g_date_set_dmy (d2, 1, 1, 1980); + + g_date_order (d1, d2); + g_assert_cmpint (g_date_compare (d1, d2), ==, -1); + g_date_order (d2, d1); + g_assert_cmpint (g_date_compare (d1, d2), ==, 1); + + g_date_free (d1); + g_date_free (d2); +} + +static void +test_copy (void) +{ + GDate *d; + GDate *c; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion *failed*"); + g_assert_null (g_date_copy (NULL)); + g_test_assert_expected_messages (); + } + + d = g_date_new (); + g_assert_false (g_date_valid (d)); + + c = g_date_copy (d); + g_assert_nonnull (c); + g_assert_false (g_date_valid (c)); + g_date_free (c); + + g_date_set_day (d, 10); + + c = g_date_copy (d); + g_date_set_month (c, 1); + g_date_set_year (c, 2015); + g_assert_true (g_date_valid (c)); + g_assert_cmpuint (g_date_get_day (c), ==, 10); + g_date_free (c); + + g_date_free (d); +} + +/* Check the results of g_date_valid_dmy() for various inputs. */ +static void +test_valid_dmy (void) +{ + const struct + { + GDateDay day; + GDateMonth month; + GDateYear year; + gboolean expected_valid; + } + vectors[] = + { + /* Lower bounds */ + { 0, 0, 0, FALSE }, + { 1, 1, 1, TRUE }, + { 1, 1, 0, FALSE }, + /* Leap year month lengths */ + { 30, 2, 2000, FALSE }, + { 29, 2, 2000, TRUE }, + { 29, 2, 2001, FALSE }, + /* Maximum year */ + { 1, 1, G_MAXUINT16, TRUE }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + gboolean valid; + g_test_message ("Vector %" G_GSIZE_FORMAT ": %04u-%02u-%02u, %s", + i, vectors[i].year, vectors[i].month, vectors[i].day, + vectors[i].expected_valid ? "valid" : "invalid"); + + valid = g_date_valid_dmy (vectors[i].day, + vectors[i].month, + vectors[i].year); + + if (vectors[i].expected_valid) + g_assert_true (valid); + else + g_assert_false (valid); + } +} + +int +main (int argc, char** argv) +{ + gchar *path; + gsize i; + + /* Try to get all the leap year cases. */ + int check_years[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 98, 99, 100, 101, 102, 103, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, + 1598, 1599, 1600, 1601, 1602, 1650, 1651, + 1897, 1898, 1899, 1900, 1901, 1902, 1903, + 1961, 1962, 1963, 1964, 1965, 1967, + 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, + 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, + 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, + 3000, 3001, 3002, 3998, 3999, 4000, 4001, 4002, 4003 + }; + + g_setenv ("LC_ALL", "en_US.utf-8", TRUE); + setlocale (LC_ALL, ""); +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); +#endif + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/date/basic", test_basic); + g_test_add_func ("/date/empty", test_empty_constructor); + g_test_add_func ("/date/dmy", test_dmy_constructor); + g_test_add_func ("/date/julian", test_julian_constructor); + g_test_add_func ("/date/compare", test_date_compare); + g_test_add_func ("/date/dates", test_dates); + g_test_add_func ("/date/strftime", test_strftime); + g_test_add_func ("/date/two-digit-years", test_two_digit_years); + g_test_add_func ("/date/parse", test_parse); + g_test_add_func ("/date/parse/invalid", test_parse_invalid); + g_test_add_func ("/date/parse_locale_change", test_parse_locale_change); + g_test_add_func ("/date/month_substring", test_month_substring); + g_test_add_func ("/date/month_names", test_month_names); + g_test_add_func ("/date/clamp", test_clamp); + g_test_add_func ("/date/order", test_order); + for (i = 0; i < G_N_ELEMENTS (check_years); i++) + { + path = g_strdup_printf ("/date/year/%d", check_years[i]); + g_test_add_data_func (path, GINT_TO_POINTER(check_years[i]), test_year); + g_free (path); + } + g_test_add_func ("/date/copy", test_copy); + g_test_add_func ("/date/valid-dmy", test_valid_dmy); + + return g_test_run (); +} diff --git a/glib/tests/dir.c b/glib/tests/dir.c new file mode 100644 index 0000000..74dbe14 --- /dev/null +++ b/glib/tests/dir.c @@ -0,0 +1,53 @@ +#include + +static void +test_dir_read (void) +{ + GDir *dir; + GError *error; + gchar *first; + const gchar *name; + + error = NULL; + dir = g_dir_open (".", 0, &error); + g_assert_no_error (error); + + first = NULL; + while ((name = g_dir_read_name (dir)) != NULL) + { + if (first == NULL) + first = g_strdup (name); + g_assert_cmpstr (name, !=, "."); + g_assert_cmpstr (name, !=, ".."); + } + + g_dir_rewind (dir); + g_assert_cmpstr (g_dir_read_name (dir), ==, first); + + g_free (first); + g_dir_close (dir); +} + +static void +test_dir_nonexisting (void) +{ + GDir *dir; + GError *error; + + error = NULL; + dir = g_dir_open ("/pfrkstrf", 0, &error); + g_assert (dir == NULL); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); + g_error_free (error); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/dir/read", test_dir_read); + g_test_add_func ("/dir/nonexisting", test_dir_nonexisting); + + return g_test_run (); +} diff --git a/glib/tests/echo-script b/glib/tests/echo-script new file mode 100755 index 0000000..b609f2d --- /dev/null +++ b/glib/tests/echo-script @@ -0,0 +1,2 @@ +#!/bin/sh +echo "echo" diff --git a/glib/tests/echo-script.bat b/glib/tests/echo-script.bat new file mode 100644 index 0000000..96c45c2 --- /dev/null +++ b/glib/tests/echo-script.bat @@ -0,0 +1,2 @@ +@echo off +echo echo diff --git a/glib/tests/empty b/glib/tests/empty new file mode 100644 index 0000000..e69de29 diff --git a/glib/tests/environment.c b/glib/tests/environment.c new file mode 100644 index 0000000..9413550 --- /dev/null +++ b/glib/tests/environment.c @@ -0,0 +1,305 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2010 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include + +static void +test_listenv (void) +{ + GHashTable *table; + gchar **list; + gint i; + + table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); + + list = g_get_environ (); + for (i = 0; list[i]; i++) + { + gchar **parts; + + parts = g_strsplit (list[i], "=", 2); + g_assert_null (g_hash_table_lookup (table, parts[0])); + if (g_strcmp0 (parts[0], "")) + g_hash_table_insert (table, parts[0], parts[1]); + g_free (parts); + } + g_strfreev (list); + + g_assert_cmpint (g_hash_table_size (table), >, 0); + + list = g_listenv (); + for (i = 0; list[i]; i++) + { + const gchar *expected; + const gchar *value; + + expected = g_hash_table_lookup (table, list[i]); + value = g_getenv (list[i]); + g_assert_cmpstr (value, ==, expected); + g_hash_table_remove (table, list[i]); + } + g_assert_cmpint (g_hash_table_size (table), ==, 0); + g_hash_table_unref (table); + g_strfreev (list); +} + +static void +test_getenv (void) +{ + const gchar *data; + const gchar *variable = "TEST_G_SETENV"; + const gchar *value1 = "works"; + const gchar *value2 = "again"; + + /* Check that TEST_G_SETENV is not already set */ + g_assert_null (g_getenv (variable)); + + /* Check if g_setenv() failed */ + g_assert_cmpint (g_setenv (variable, value1, TRUE), !=, 0); + + data = g_getenv (variable); + g_assert_nonnull (data); + g_assert_cmpstr (data, ==, value1); + + g_assert_cmpint (g_setenv (variable, value2, FALSE), !=, 0); + + data = g_getenv (variable); + g_assert_nonnull (data); + g_assert_cmpstr (data, !=, value2); + g_assert_cmpstr (data, ==, value1); + + g_assert_cmpint (g_setenv (variable, value2, TRUE), !=, 0); + + data = g_getenv (variable); + g_assert_nonnull (data); + g_assert_cmpstr (data, !=, value1); + g_assert_cmpstr (data, ==, value2); + + g_unsetenv (variable); + g_assert_null (g_getenv (variable)); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* != NULL*"); + g_assert_false (g_setenv (NULL, "baz", TRUE)); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* != NULL*"); + g_assert_false (g_setenv ("foo", NULL, TRUE)); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* == NULL*"); + g_assert_false (g_setenv ("foo=bar", "baz", TRUE)); + g_test_assert_expected_messages (); + } + + g_assert_true (g_setenv ("foo", "bar=baz", TRUE)); + + /* Different OSs return different values; some return NULL because the key + * is invalid, but some are happy to return what we set above. */ + data = g_getenv ("foo=bar"); + if (data != NULL) + g_assert_cmpstr (data, ==, "baz"); + + data = g_getenv ("foo"); + g_assert_cmpstr (data, ==, "bar=baz"); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* != NULL*"); + g_unsetenv (NULL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* == NULL*"); + g_unsetenv ("foo=bar"); + g_test_assert_expected_messages (); + } + + g_unsetenv ("foo"); + g_assert_null (g_getenv ("foo")); +} + +static void +test_setenv (void) +{ + const gchar *var, *value; + + var = "NOSUCHENVVAR"; + value = "value1"; + + g_assert_null (g_getenv (var)); + g_setenv (var, value, FALSE); + g_assert_cmpstr (g_getenv (var), ==, value); + g_assert_true (g_setenv (var, "value2", FALSE)); + g_assert_cmpstr (g_getenv (var), ==, value); + g_assert_true (g_setenv (var, "value2", TRUE)); + g_assert_cmpstr (g_getenv (var), ==, "value2"); + g_unsetenv (var); + g_assert_null (g_getenv (var)); +} + +static void +test_environ_array (void) +{ + gchar **env; + const gchar *value; + + env = g_new (gchar *, 1); + env[0] = NULL; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* != NULL*"); + g_environ_getenv (env, NULL); + g_test_assert_expected_messages (); + } + + value = g_environ_getenv (env, "foo"); + g_assert_null (value); + + if (g_test_undefined ()) + { + gchar **undefined_env; + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* != NULL*"); + undefined_env = g_environ_setenv (env, NULL, "bar", TRUE); + g_test_assert_expected_messages (); + g_strfreev (undefined_env); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* == NULL*"); + undefined_env = g_environ_setenv (env, "foo=fuz", "bar", TRUE); + g_test_assert_expected_messages (); + g_strfreev (undefined_env); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* != NULL*"); + undefined_env = g_environ_setenv (env, "foo", NULL, TRUE); + g_test_assert_expected_messages (); + g_strfreev (undefined_env); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion* != NULL*"); + undefined_env = g_environ_unsetenv (env, NULL); + g_test_assert_expected_messages (); + g_strfreev (undefined_env); + } + + env = g_environ_setenv (env, "foo", "bar", TRUE); + value = g_environ_getenv (env, "foo"); + g_assert_cmpstr (value, ==, "bar"); + + env = g_environ_setenv (env, "foo2", "bar2", FALSE); + value = g_environ_getenv (env, "foo"); + g_assert_cmpstr (value, ==, "bar"); + value = g_environ_getenv (env, "foo2"); + g_assert_cmpstr (value, ==, "bar2"); + + env = g_environ_setenv (env, "foo", "x", FALSE); + value = g_environ_getenv (env, "foo"); + g_assert_cmpstr (value, ==, "bar"); + + env = g_environ_setenv (env, "foo", "x", TRUE); + value = g_environ_getenv (env, "foo"); + g_assert_cmpstr (value, ==, "x"); + + env = g_environ_unsetenv (env, "foo2"); + value = g_environ_getenv (env, "foo2"); + g_assert_null (value); + + g_strfreev (env); +} + +static void +test_environ_null (void) +{ + gchar **env; + const gchar *value; + + env = NULL; + + value = g_environ_getenv (env, "foo"); + g_assert_null (value); + + env = g_environ_setenv (NULL, "foo", "bar", TRUE); + g_assert_nonnull (env); + g_strfreev (env); + + env = g_environ_unsetenv (NULL, "foo"); + g_assert_null (env); +} + +static void +test_environ_case (void) +{ + gchar **env; + const gchar *value; + + env = NULL; + + env = g_environ_setenv (env, "foo", "bar", TRUE); + value = g_environ_getenv (env, "foo"); + g_assert_cmpstr (value, ==, "bar"); + + value = g_environ_getenv (env, "Foo"); +#ifdef G_OS_WIN32 + g_assert_cmpstr (value, ==, "bar"); +#else + g_assert_null (value); +#endif + + env = g_environ_setenv (env, "FOO", "x", TRUE); + value = g_environ_getenv (env, "foo"); +#ifdef G_OS_WIN32 + g_assert_cmpstr (value, ==, "x"); +#else + g_assert_cmpstr (value, ==, "bar"); +#endif + + env = g_environ_unsetenv (env, "Foo"); + value = g_environ_getenv (env, "foo"); +#ifdef G_OS_WIN32 + g_assert_null (value); +#else + g_assert_cmpstr (value, ==, "bar"); +#endif + + g_strfreev (env); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/environ/listenv", test_listenv); + g_test_add_func ("/environ/getenv", test_getenv); + g_test_add_func ("/environ/setenv", test_setenv); + g_test_add_func ("/environ/array", test_environ_array); + g_test_add_func ("/environ/null", test_environ_null); + g_test_add_func ("/environ/case", test_environ_case); + + return g_test_run (); +} diff --git a/glib/tests/error.c b/glib/tests/error.c new file mode 100644 index 0000000..51a0c35 --- /dev/null +++ b/glib/tests/error.c @@ -0,0 +1,409 @@ +#include + +#include "glib-private.h" + +static void +test_overwrite (void) +{ + GError *error, *dest, *src; + + if (!g_test_undefined ()) + return; + + error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla"); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*set over the top*"); + g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla"); + g_test_assert_expected_messages (); + + g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY); + g_error_free (error); + + + error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla"); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*set over the top*"); + g_set_error (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla"); + g_test_assert_expected_messages (); + + g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY); + g_error_free (error); + + + dest = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla"); + src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla"); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*set over the top*"); + g_propagate_error (&dest, src); + g_test_assert_expected_messages (); + + g_assert_error (dest, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY); + g_error_free (dest); +} + +static void +test_prefix (void) +{ + GError *error; + GError *dest, *src; + + error = NULL; + g_prefix_error (&error, "foo %d %s: ", 1, "two"); + g_assert (error == NULL); + + error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla"); + g_prefix_error (&error, "foo %d %s: ", 1, "two"); + g_assert_cmpstr (error->message, ==, "foo 1 two: bla"); + g_error_free (error); + + dest = NULL; + src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla"); + g_propagate_prefixed_error (&dest, src, "foo %d %s: ", 1, "two"); + g_assert_cmpstr (dest->message, ==, "foo 1 two: bla"); + g_error_free (dest); + + src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla"); + g_propagate_prefixed_error (NULL, src, "foo %d %s: ", 1, "two"); +} + +static void +test_prefix_literal (void) +{ + GError *error = NULL; + + g_prefix_error_literal (NULL, "foo: "); + + g_prefix_error_literal (&error, "foo: "); + g_assert_null (error); + + error = NULL; + g_prefix_error_literal (&error, "foo: "); + g_assert_null (error); + + error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla"); + g_assert_nonnull (error); + g_prefix_error_literal (&error, "foo: "); + g_assert_cmpstr (error->message, ==, "foo: bla"); + g_error_free (error); +} + +static void +test_literal (void) +{ + GError *error; + + error = NULL; + g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "%s %d %x"); + g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY); + g_assert_cmpstr (error->message, ==, "%s %d %x"); + g_error_free (error); +} + +static void +test_copy (void) +{ + GError *error; + GError *copy; + + error = NULL; + g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "%s %d %x"); + copy = g_error_copy (error); + + g_assert_error (copy, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY); + g_assert_cmpstr (copy->message, ==, "%s %d %x"); + + g_error_free (error); + g_error_free (copy); +} + +static void +test_new_valist_invalid_va (gpointer dummy, + ...) +{ +#ifdef __linux__ + /* Only worth testing this on Linux; if other platforms regress on this legacy + * behaviour, we don’t care. In particular, calling g_error_new_valist() with + * a %NULL format will crash on FreeBSD as its implementation of vasprintf() + * is less forgiving than Linux’s. That’s fine: it’s a programmer error in + * either case. */ + const struct + { + GQuark domain; + const gchar *format; + } + tests[] = + { + { G_MARKUP_ERROR, NULL }, + { 0, "Message" }, + }; + gsize i; + + g_test_summary ("Test that g_error_new_valist() rejects invalid input"); + + if (!g_test_undefined ()) + { + g_test_skip ("Not testing response to programmer error"); + return; + } + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + GError *error = NULL, *error_copy = NULL; + va_list ap; + + g_test_message ("Test %" G_GSIZE_FORMAT, i); + + va_start (ap, dummy); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + + g_test_expect_message (G_LOG_DOMAIN, + G_LOG_LEVEL_WARNING, + "*g_error_new_valist: runtime check failed*"); + error = g_error_new_valist (tests[i].domain, G_MARKUP_ERROR_EMPTY, tests[i].format, ap); + g_test_assert_expected_messages (); + g_assert_nonnull (error); + +#pragma GCC diagnostic pop + + g_test_expect_message (G_LOG_DOMAIN, + G_LOG_LEVEL_WARNING, + "*g_error_copy: runtime check failed*"); + error_copy = g_error_copy (error); + g_test_assert_expected_messages (); + g_assert_nonnull (error_copy); + + g_clear_error (&error); + g_clear_error (&error_copy); + + va_end (ap); + } +#else /* if !__linux__ */ + g_test_skip ("g_error_new_valist() programmer error handling is only relevant on Linux"); +#endif /* !__linux__ */ +} + +static void +test_new_valist_invalid (void) +{ + /* We need a wrapper function so we can build a va_list */ + test_new_valist_invalid_va (NULL); +} + +static void +test_matches (void) +{ + GError *error = NULL; + + g_test_summary ("Test g_error_matches()"); + + error = g_error_new (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "Oh no!"); + + g_assert_true (g_error_matches (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY)); + g_assert_false (g_error_matches (NULL, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY)); + g_assert_false (g_error_matches (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE)); /* same numeric value as G_MARKUP_ERROR_EMPTY */ + g_assert_false (g_error_matches (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED)); /* different numeric value from G_MARKUP_ERROR_EMPTY */ + g_assert_false (g_error_matches (error, G_MARKUP_ERROR, G_MARKUP_ERROR_BAD_UTF8)); + + g_error_free (error); +} + +static void +test_clear (void) +{ + GError *error = NULL; + + g_test_summary ("Test g_error_clear()"); + + g_clear_error (&error); + g_assert_null (error); + + g_clear_error (NULL); + + error = g_error_new (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "Oh no!"); + g_clear_error (&error); + g_assert_null (error); +} + +typedef struct +{ + int init_called; + int copy_called; + int free_called; +} TestErrorCheck; + +static TestErrorCheck *init_check; + +GQuark test_error_quark (void); +#define TEST_ERROR (test_error_quark ()) + +typedef struct +{ + int foo; + TestErrorCheck *check; +} TestErrorPrivate; + +static void +test_error_private_init (TestErrorPrivate *priv) +{ + priv->foo = 13; + /* If that triggers, it's test bug. + */ + g_assert_nonnull (init_check); + /* Using global init_check, because error->check is still nil at + * this point. + */ + init_check->init_called++; +} + +static void +test_error_private_copy (const TestErrorPrivate *src_priv, + TestErrorPrivate *dest_priv) +{ + dest_priv->foo = src_priv->foo; + dest_priv->check = src_priv->check; + + dest_priv->check->copy_called++; +} + +static void +test_error_private_clear (TestErrorPrivate *priv) +{ + priv->check->free_called++; +} + +G_DEFINE_EXTENDED_ERROR (TestError, test_error) + +static TestErrorPrivate * +fill_test_error (GError *error, TestErrorCheck *check) +{ + TestErrorPrivate *test_error = test_error_get_private (error); + + test_error->check = check; + + return test_error; +} + +static void +test_extended (void) +{ + TestErrorCheck check = { 0, 0, 0 }; + GError *error; + TestErrorPrivate *test_priv; + GError *copy_error; + TestErrorPrivate *copy_test_priv; + + init_check = ✓ + error = g_error_new_literal (TEST_ERROR, 0, "foo"); + test_priv = fill_test_error (error, &check); + + g_assert_cmpint (check.init_called, ==, 1); + g_assert_cmpint (check.copy_called, ==, 0); + g_assert_cmpint (check.free_called, ==, 0); + + g_assert_cmpuint (error->domain, ==, TEST_ERROR); + g_assert_cmpint (test_priv->foo, ==, 13); + + copy_error = g_error_copy (error); + g_assert_cmpint (check.init_called, ==, 2); + g_assert_cmpint (check.copy_called, ==, 1); + g_assert_cmpint (check.free_called, ==, 0); + + g_assert_cmpuint (error->domain, ==, copy_error->domain); + g_assert_cmpint (error->code, ==, copy_error->code); + g_assert_cmpstr (error->message, ==, copy_error->message); + + copy_test_priv = test_error_get_private (copy_error); + g_assert_cmpint (test_priv->foo, ==, copy_test_priv->foo); + + g_error_free (error); + g_error_free (copy_error); + + g_assert_cmpint (check.init_called, ==, 2); + g_assert_cmpint (check.copy_called, ==, 1); + g_assert_cmpint (check.free_called, ==, 2); +} + +static void +test_extended_duplicate (void) +{ + g_test_summary ("Test that registering a duplicate extended error domain doesn’t work"); + + if (!g_test_subprocess ()) + { + /* Spawn a subprocess and expect it to fail. */ + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*Attempted to register an extended error domain for TestError more than once*"); + } + else + { + GQuark q; + guint i; + + for (i = 0; i < 2; i++) + { + q = g_error_domain_register_static ("TestError", + sizeof (TestErrorPrivate), + g_error_with_test_error_private_init, + g_error_with_test_error_private_copy, + g_error_with_test_error_private_clear); + g_assert_cmpstr (g_quark_to_string (q), ==, "TestError"); + } + } +} + +typedef struct +{ + int dummy; +} TestErrorNonStaticPrivate; + +static void test_error_non_static_private_init (GError *error) {} +static void test_error_non_static_private_copy (const GError *src_error, GError *dest_error) {} +static void test_error_non_static_private_clear (GError *error) {} + +static void +test_extended_non_static (void) +{ + gchar *domain_name = g_strdup ("TestErrorNonStatic"); + GQuark q; + GError *error = NULL; + + g_test_summary ("Test registering an extended error domain with a non-static name"); + + q = g_error_domain_register (domain_name, + sizeof (TestErrorNonStaticPrivate), + test_error_non_static_private_init, + test_error_non_static_private_copy, + test_error_non_static_private_clear); + g_free (domain_name); + + error = g_error_new (q, 0, "Test error: %s", "hello"); + g_assert_true (g_error_matches (error, q, 0)); + g_assert_cmpstr (g_quark_to_string (q), ==, "TestErrorNonStatic"); + g_error_free (error); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/error/overwrite", test_overwrite); + g_test_add_func ("/error/prefix", test_prefix); + g_test_add_func ("/error/prefix-literal", test_prefix_literal); + g_test_add_func ("/error/literal", test_literal); + g_test_add_func ("/error/copy", test_copy); + g_test_add_func ("/error/matches", test_matches); + g_test_add_func ("/error/clear", test_clear); + g_test_add_func ("/error/new-valist/invalid", test_new_valist_invalid); + g_test_add_func ("/error/extended", test_extended); + g_test_add_func ("/error/extended/duplicate", test_extended_duplicate); + g_test_add_func ("/error/extended/non-static", test_extended_non_static); + + return g_test_run (); +} diff --git a/glib/tests/fileutils.c b/glib/tests/fileutils.c new file mode 100644 index 0000000..e0ade53 --- /dev/null +++ b/glib/tests/fileutils.c @@ -0,0 +1,2468 @@ +/* Unit tests for gfileutils + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "config.h" +#include +#include + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +/* Test our stdio wrappers here; this disables redefining (e.g.) g_open() to open() */ +#define G_STDIO_WRAP_ON_UNIX +#include + +#ifdef G_OS_UNIX +#include +#include +#include +#include + +#define G_TEST_DIR_MODE 0555 +#endif +#include +#ifdef G_OS_WIN32 +#include +#include +#include +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#endif +#ifndef F_OK +#define F_OK 0 +#endif + +#define G_TEST_DIR_MODE (S_IWRITE | S_IREAD) +#endif + +#define S G_DIR_SEPARATOR_S + +static void +check_string (gchar *str, const gchar *expected) +{ + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, expected); + g_free (str); +} + +static void +test_paths (void) +{ + struct + { + gchar *filename; + gchar *dirname; + } dirname_checks[] = { + { "/", "/" }, + { "////", "/" }, + { ".////", "." }, + { "../", ".." }, + { "..////", ".." }, + { "a/b", "a" }, + { "a/b/", "a/b" }, + { "c///", "c" }, +#ifdef G_OS_WIN32 + { "\\", "\\" }, + { ".\\\\\\\\", "." }, + { "..\\", ".." }, + { "..\\\\\\\\", ".." }, + { "a\\b", "a" }, + { "a\\b/", "a\\b" }, + { "a/b\\", "a/b" }, + { "c\\\\/", "c" }, + { "//\\", "/" }, +#endif +#ifdef G_WITH_CYGWIN + { "//server/share///x", "//server/share" }, +#endif + { ".", "." }, + { "..", "." }, + { "", "." }, + }; + const guint n_dirname_checks = G_N_ELEMENTS (dirname_checks); + struct + { + gchar *filename; + gchar *without_root; + } skip_root_checks[] = { + { "/", "" }, + { "//", "" }, + { "/foo", "foo" }, + { "//foo", "foo" }, + { "a/b", NULL }, +#ifdef G_OS_WIN32 + { "\\", "" }, + { "\\foo", "foo" }, + { "\\\\server\\foo", "" }, + { "\\\\server\\foo\\bar", "bar" }, + { "a\\b", NULL }, +#endif +#ifdef G_WITH_CYGWIN + { "//server/share///x", "//x" }, +#endif + { ".", NULL }, + { "", NULL }, + }; + const guint n_skip_root_checks = G_N_ELEMENTS (skip_root_checks); + struct + { + gchar *cwd; + gchar *relative_path; + gchar *canonical_path; + } canonicalize_filename_checks[] = { +#ifndef G_OS_WIN32 + { "/etc", "../usr/share", "/usr/share" }, + { "/", "/foo/bar", "/foo/bar" }, + { "/usr/bin", "../../foo/bar", "/foo/bar" }, + { "/", "../../foo/bar", "/foo/bar" }, + { "/double//dash", "../../foo/bar", "/foo/bar" }, + { "/usr/share/foo", ".././././bar", "/usr/share/bar" }, + { "/foo/bar", "../bar/./.././bar", "/foo/bar" }, + { "/test///dir", "../../././foo/bar", "/foo/bar" }, + { "/test///dir", "../../././/foo///bar", "/foo/bar" }, + { "/etc", "///triple/slash", "/triple/slash" }, + { "/etc", "//double/slash", "//double/slash" }, + { "///triple/slash", ".", "/triple/slash" }, + { "//double/slash", ".", "//double/slash" }, + { "/cwd/../with/./complexities/", "./hello", "/with/complexities/hello" }, + { "/", ".dot-dir", "/.dot-dir" }, + { "/cwd", "..", "/" }, + { "/etc", "hello/..", "/etc" }, + { "/etc", "hello/../", "/etc" }, + { "/", "..", "/" }, + { "/", "../", "/" }, + { "/", "/..", "/" }, + { "/", "/../", "/" }, + { "/", ".", "/" }, + { "/", "./", "/" }, + { "/", "/.", "/" }, + { "/", "/./", "/" }, + { "/", "///usr/../usr", "/usr" }, +#else + { "/etc", "../usr/share", "\\usr\\share" }, + { "/", "/foo/bar", "\\foo\\bar" }, + { "/usr/bin", "../../foo/bar", "\\foo\\bar" }, + { "/", "../../foo/bar", "\\foo\\bar" }, + { "/double//dash", "../../foo/bar", "\\foo\\bar" }, + { "/usr/share/foo", ".././././bar", "\\usr\\share\\bar" }, + { "/foo/bar", "../bar/./.././bar", "\\foo\\bar" }, + { "/test///dir", "../../././foo/bar", "\\foo\\bar" }, + { "/test///dir", "../../././/foo///bar", "\\foo\\bar" }, + { "/etc", "///triple/slash", "\\triple\\slash" }, + { "/etc", "//double/slash", "//double/slash" }, + { "///triple/slash", ".", "\\triple\\slash" }, + { "//double/slash", ".", "//double/slash\\" }, + { "/cwd/../with/./complexities/", "./hello", "\\with\\complexities\\hello" }, + { "/", ".dot-dir", "\\.dot-dir" }, + { "/cwd", "..", "\\" }, + { "/etc", "hello/..", "\\etc" }, + { "/etc", "hello/../", "\\etc" }, + { "/", "..", "\\" }, + { "/", "../", "\\" }, + { "/", "/..", "\\" }, + { "/", "/../", "\\" }, + { "/", ".", "\\" }, + { "/", "./", "\\" }, + { "/", "/.", "\\" }, + { "/", "/./", "\\" }, + { "/", "///usr/../usr", "\\usr" }, + + { "\\etc", "..\\usr\\share", "\\usr\\share" }, + { "\\", "\\foo\\bar", "\\foo\\bar" }, + { "\\usr\\bin", "..\\..\\foo\\bar", "\\foo\\bar" }, + { "\\", "..\\..\\foo\\bar", "\\foo\\bar" }, + { "\\double\\\\dash", "..\\..\\foo\\bar", "\\foo\\bar" }, + { "\\usr\\share\\foo", "..\\.\\.\\.\\bar", "\\usr\\share\\bar" }, + { "\\foo\\bar", "..\\bar\\.\\..\\.\\bar", "\\foo\\bar" }, + { "\\test\\\\\\dir", "..\\..\\.\\.\\foo\\bar", "\\foo\\bar" }, + { "\\test\\\\\\dir", "..\\..\\.\\.\\\\foo\\\\\\bar", "\\foo\\bar" }, + { "\\etc", "\\\\\\triple\\slash", "\\triple\\slash" }, + { "\\etc", "\\\\double\\slash", "\\\\double\\slash" }, + { "\\\\\\triple\\slash", ".", "\\triple\\slash" }, + { "\\\\double\\slash", ".", "\\\\double\\slash\\" }, + { "\\cwd\\..\\with\\.\\complexities\\", ".\\hello", "\\with\\complexities\\hello" }, + { "\\", ".dot-dir", "\\.dot-dir" }, + { "\\cwd", "..", "\\" }, + { "\\etc", "hello\\..", "\\etc" }, + { "\\etc", "hello\\..\\", "\\etc" }, + { "\\", "..", "\\" }, + { "\\", "..\\", "\\" }, + { "\\", "\\..", "\\" }, + { "\\", "\\..\\", "\\" }, + { "\\", ".", "\\" }, + { "\\", ".\\", "\\" }, + { "\\", "\\.", "\\" }, + { "\\", "\\.\\", "\\" }, + { "\\", "\\\\\\usr\\..\\usr", "\\usr" }, +#endif + }; + const guint n_canonicalize_filename_checks = G_N_ELEMENTS (canonicalize_filename_checks); + gchar *string; + guint i; + + string = g_path_get_basename (G_DIR_SEPARATOR_S "foo" G_DIR_SEPARATOR_S "dir" G_DIR_SEPARATOR_S); + g_assert_cmpstr (string, ==, "dir"); + g_free (string); + string = g_path_get_basename (G_DIR_SEPARATOR_S "foo" G_DIR_SEPARATOR_S "file"); + g_assert_cmpstr (string, ==, "file"); + g_free (string); + +#ifdef G_OS_WIN32 + string = g_path_get_basename ("/foo/dir/"); + g_assert_cmpstr (string, ==, "dir"); + g_free (string); + string = g_path_get_basename ("/foo/file"); + g_assert_cmpstr (string, ==, "file"); + g_free (string); +#endif + + for (i = 0; i < n_dirname_checks; i++) + { + gchar *dirname = g_path_get_dirname (dirname_checks[i].filename); + g_assert_cmpstr (dirname, ==, dirname_checks[i].dirname); + g_free (dirname); + } + + for (i = 0; i < n_skip_root_checks; i++) + { + const gchar *skipped = g_path_skip_root (skip_root_checks[i].filename); + if ((skipped && !skip_root_checks[i].without_root) || + (!skipped && skip_root_checks[i].without_root) || + ((skipped && skip_root_checks[i].without_root) && + strcmp (skipped, skip_root_checks[i].without_root))) + { + g_error ("failed for \"%s\"==\"%s\" (returned: \"%s\")", + skip_root_checks[i].filename, + (skip_root_checks[i].without_root ? skip_root_checks[i].without_root : ""), + (skipped ? skipped : "")); + } + } + + for (i = 0; i < n_canonicalize_filename_checks; i++) + { + gchar *canonical_path = + g_canonicalize_filename (canonicalize_filename_checks[i].relative_path, + canonicalize_filename_checks[i].cwd); + g_assert_cmpstr (canonical_path, ==, + canonicalize_filename_checks[i].canonical_path); + g_free (canonical_path); + } + + { + const gchar *relative_path = "./"; + gchar *canonical_path = g_canonicalize_filename (relative_path, NULL); + gchar *cwd = g_get_current_dir (); + g_assert_cmpstr (canonical_path, ==, cwd); + g_free (cwd); + g_free (canonical_path); + } +} + +static void +test_build_path (void) +{ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_assert_null (g_build_path (NULL, "x", "y", NULL)); + g_test_assert_expected_messages (); + } + +/* check_string (g_build_path ("", NULL), "");*/ + check_string (g_build_path ("", "", NULL), ""); + check_string (g_build_path ("", "x", NULL), "x"); + check_string (g_build_path ("", "x", "y", NULL), "xy"); + check_string (g_build_path ("", "x", "y", "z", NULL), "xyz"); + +/* check_string (g_build_path (":", NULL), "");*/ + check_string (g_build_path (":", ":", NULL), ":"); + check_string (g_build_path (":", ":x", NULL), ":x"); + check_string (g_build_path (":", "x:", NULL), "x:"); + check_string (g_build_path (":", "", "x", NULL), "x"); + check_string (g_build_path (":", "", ":x", NULL), ":x"); + check_string (g_build_path (":", ":", "x", NULL), ":x"); + check_string (g_build_path (":", "::", "x", NULL), "::x"); + check_string (g_build_path (":", "x", "", NULL), "x"); + check_string (g_build_path (":", "x:", "", NULL), "x:"); + check_string (g_build_path (":", "x", ":", NULL), "x:"); + check_string (g_build_path (":", "x", "::", NULL), "x::"); + check_string (g_build_path (":", "x", "y", NULL), "x:y"); + check_string (g_build_path (":", ":x", "y", NULL), ":x:y"); + check_string (g_build_path (":", "x", "y:", NULL), "x:y:"); + check_string (g_build_path (":", ":x:", ":y:", NULL), ":x:y:"); + check_string (g_build_path (":", ":x::", "::y:", NULL), ":x:y:"); + check_string (g_build_path (":", "x", "","y", NULL), "x:y"); + check_string (g_build_path (":", "x", ":", "y", NULL), "x:y"); + check_string (g_build_path (":", "x", "::", "y", NULL), "x:y"); + check_string (g_build_path (":", "x", "y", "z", NULL), "x:y:z"); + check_string (g_build_path (":", ":x:", ":y:", ":z:", NULL), ":x:y:z:"); + check_string (g_build_path (":", "::x::", "::y::", "::z::", NULL), "::x:y:z::"); + +/* check_string (g_build_path ("::", NULL), "");*/ + check_string (g_build_path ("::", "::", NULL), "::"); + check_string (g_build_path ("::", ":::", NULL), ":::"); + check_string (g_build_path ("::", "::x", NULL), "::x"); + check_string (g_build_path ("::", "x::", NULL), "x::"); + check_string (g_build_path ("::", "", "x", NULL), "x"); + check_string (g_build_path ("::", "", "::x", NULL), "::x"); + check_string (g_build_path ("::", "::", "x", NULL), "::x"); + check_string (g_build_path ("::", "::::", "x", NULL), "::::x"); + check_string (g_build_path ("::", "x", "", NULL), "x"); + check_string (g_build_path ("::", "x::", "", NULL), "x::"); + check_string (g_build_path ("::", "x", "::", NULL), "x::"); + + /* This following is weird, but keeps the definition simple */ + check_string (g_build_path ("::", "x", ":::", NULL), "x:::::"); + check_string (g_build_path ("::", "x", "::::", NULL), "x::::"); + check_string (g_build_path ("::", "x", "y", NULL), "x::y"); + check_string (g_build_path ("::", "::x", "y", NULL), "::x::y"); + check_string (g_build_path ("::", "x", "y::", NULL), "x::y::"); + check_string (g_build_path ("::", "::x::", "::y::", NULL), "::x::y::"); + check_string (g_build_path ("::", "::x:::", ":::y::", NULL), "::x::::y::"); + check_string (g_build_path ("::", "::x::::", "::::y::", NULL), "::x::y::"); + check_string (g_build_path ("::", "x", "", "y", NULL), "x::y"); + check_string (g_build_path ("::", "x", "::", "y", NULL), "x::y"); + check_string (g_build_path ("::", "x", "::::", "y", NULL), "x::y"); + check_string (g_build_path ("::", "x", "y", "z", NULL), "x::y::z"); + check_string (g_build_path ("::", "::x::", "::y::", "::z::", NULL), "::x::y::z::"); + check_string (g_build_path ("::", ":::x:::", ":::y:::", ":::z:::", NULL), ":::x::::y::::z:::"); + check_string (g_build_path ("::", "::::x::::", "::::y::::", "::::z::::", NULL), "::::x::y::z::::"); +} + +static void +test_build_pathv (void) +{ + gchar *args[10]; + + g_assert_null (g_build_pathv ("", NULL)); + args[0] = NULL; + check_string (g_build_pathv ("", args), ""); + args[0] = ""; args[1] = NULL; + check_string (g_build_pathv ("", args), ""); + args[0] = "x"; args[1] = NULL; + check_string (g_build_pathv ("", args), "x"); + args[0] = "x"; args[1] = "y"; args[2] = NULL; + check_string (g_build_pathv ("", args), "xy"); + args[0] = "x"; args[1] = "y"; args[2] = "z", args[3] = NULL; + check_string (g_build_pathv ("", args), "xyz"); + + args[0] = NULL; + check_string (g_build_pathv (":", args), ""); + args[0] = ":"; args[1] = NULL; + check_string (g_build_pathv (":", args), ":"); + args[0] = ":x"; args[1] = NULL; + check_string (g_build_pathv (":", args), ":x"); + args[0] = "x:"; args[1] = NULL; + check_string (g_build_pathv (":", args), "x:"); + args[0] = ""; args[1] = "x"; args[2] = NULL; + check_string (g_build_pathv (":", args), "x"); + args[0] = ""; args[1] = ":x"; args[2] = NULL; + check_string (g_build_pathv (":", args), ":x"); + args[0] = ":"; args[1] = "x"; args[2] = NULL; + check_string (g_build_pathv (":", args), ":x"); + args[0] = "::"; args[1] = "x"; args[2] = NULL; + check_string (g_build_pathv (":", args), "::x"); + args[0] = "x"; args[1] = ""; args[2] = NULL; + check_string (g_build_pathv (":", args), "x"); + args[0] = "x:"; args[1] = ""; args[2] = NULL; + check_string (g_build_pathv (":", args), "x:"); + args[0] = "x"; args[1] = ":"; args[2] = NULL; + check_string (g_build_pathv (":", args), "x:"); + args[0] = "x"; args[1] = "::"; args[2] = NULL; + check_string (g_build_pathv (":", args), "x::"); + args[0] = "x"; args[1] = "y"; args[2] = NULL; + check_string (g_build_pathv (":", args), "x:y"); + args[0] = ":x"; args[1] = "y"; args[2] = NULL; + check_string (g_build_pathv (":", args), ":x:y"); + args[0] = "x"; args[1] = "y:"; args[2] = NULL; + check_string (g_build_pathv (":", args), "x:y:"); + args[0] = ":x:"; args[1] = ":y:"; args[2] = NULL; + check_string (g_build_pathv (":", args), ":x:y:"); + args[0] = ":x::"; args[1] = "::y:"; args[2] = NULL; + check_string (g_build_pathv (":", args), ":x:y:"); + args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL; + check_string (g_build_pathv (":", args), "x:y"); + args[0] = "x"; args[1] = ":"; args[2] = "y"; args[3] = NULL; + check_string (g_build_pathv (":", args), "x:y"); + args[0] = "x"; args[1] = "::"; args[2] = "y"; args[3] = NULL; + check_string (g_build_pathv (":", args), "x:y"); + args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL; + check_string (g_build_pathv (":", args), "x:y:z"); + args[0] = ":x:"; args[1] = ":y:"; args[2] = ":z:"; args[3] = NULL; + check_string (g_build_pathv (":", args), ":x:y:z:"); + args[0] = "::x::"; args[1] = "::y::"; args[2] = "::z::"; args[3] = NULL; + check_string (g_build_pathv (":", args), "::x:y:z::"); + + args[0] = NULL; + check_string (g_build_pathv ("::", args), ""); + args[0] = "::"; args[1] = NULL; + check_string (g_build_pathv ("::", args), "::"); + args[0] = ":::"; args[1] = NULL; + check_string (g_build_pathv ("::", args), ":::"); + args[0] = "::x"; args[1] = NULL; + check_string (g_build_pathv ("::", args), "::x"); + args[0] = "x::"; args[1] = NULL; + check_string (g_build_pathv ("::", args), "x::"); + args[0] = ""; args[1] = "x"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "x"); + args[0] = ""; args[1] = "::x"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "::x"); + args[0] = "::"; args[1] = "x"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "::x"); + args[0] = "::::"; args[1] = "x"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "::::x"); + args[0] = "x"; args[1] = ""; args[2] = NULL; + check_string (g_build_pathv ("::", args), "x"); + args[0] = "x::"; args[1] = ""; args[2] = NULL; + check_string (g_build_pathv ("::", args), "x::"); + args[0] = "x"; args[1] = "::"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "x::"); + /* This following is weird, but keeps the definition simple */ + args[0] = "x"; args[1] = ":::"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "x:::::"); + args[0] = "x"; args[1] = "::::"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "x::::"); + args[0] = "x"; args[1] = "y"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "x::y"); + args[0] = "::x"; args[1] = "y"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "::x::y"); + args[0] = "x"; args[1] = "y::"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "x::y::"); + args[0] = "::x::"; args[1] = "::y::"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "::x::y::"); + args[0] = "::x:::"; args[1] = ":::y::"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "::x::::y::"); + args[0] = "::x::::"; args[1] = "::::y::"; args[2] = NULL; + check_string (g_build_pathv ("::", args), "::x::y::"); + args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL; + check_string (g_build_pathv ("::", args), "x::y"); + args[0] = "x"; args[1] = "::"; args[2] = "y"; args[3] = NULL; + check_string (g_build_pathv ("::", args), "x::y"); + args[0] = "x"; args[1] = "::::"; args[2] = "y"; args[3] = NULL; + check_string (g_build_pathv ("::", args), "x::y"); + args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL; + check_string (g_build_pathv ("::", args), "x::y::z"); + args[0] = "::x::"; args[1] = "::y::"; args[2] = "::z::"; args[3] = NULL; + check_string (g_build_pathv ("::", args), "::x::y::z::"); + args[0] = ":::x:::"; args[1] = ":::y:::"; args[2] = ":::z:::"; args[3] = NULL; + check_string (g_build_pathv ("::", args), ":::x::::y::::z:::"); + args[0] = "::::x::::"; args[1] = "::::y::::"; args[2] = "::::z::::"; args[3] = NULL; + check_string (g_build_pathv ("::", args), "::::x::y::z::::"); +} + +static void +test_build_filename (void) +{ + check_string (g_build_filename (S, NULL), S); + check_string (g_build_filename (S"x", NULL), S"x"); + check_string (g_build_filename ("x"S, NULL), "x"S); + check_string (g_build_filename ("", "x", NULL), "x"); + check_string (g_build_filename ("", S"x", NULL), S"x"); + check_string (g_build_filename (S, "x", NULL), S"x"); + check_string (g_build_filename (S S, "x", NULL), S S"x"); + check_string (g_build_filename ("x", "", NULL), "x"); + check_string (g_build_filename ("x"S, "", NULL), "x"S); + check_string (g_build_filename ("x", S, NULL), "x"S); + check_string (g_build_filename ("x", S S, NULL), "x"S S); + check_string (g_build_filename ("x", "y", NULL), "x"S"y"); + check_string (g_build_filename (S"x", "y", NULL), S"x"S"y"); + check_string (g_build_filename ("x", "y"S, NULL), "x"S"y"S); + check_string (g_build_filename (S"x"S, S"y"S, NULL), S"x"S"y"S); + check_string (g_build_filename (S"x"S S, S S"y"S, NULL), S"x"S"y"S); + check_string (g_build_filename ("x", "", "y", NULL), "x"S"y"); + check_string (g_build_filename ("x", S, "y", NULL), "x"S"y"); + check_string (g_build_filename ("x", S S, "y", NULL), "x"S"y"); + check_string (g_build_filename ("x", "y", "z", NULL), "x"S"y"S"z"); + check_string (g_build_filename (S"x"S, S"y"S, S"z"S, NULL), S"x"S"y"S"z"S); + check_string (g_build_filename (S S"x"S S, S S"y"S S, S S"z"S S, NULL), S S"x"S"y"S"z"S S); + +#ifdef G_OS_WIN32 + + /* Test also using the slash as file name separator */ +#define Z "/" + /* check_string (g_build_filename (NULL), ""); */ + check_string (g_build_filename (Z, NULL), Z); + check_string (g_build_filename (Z"x", NULL), Z"x"); + check_string (g_build_filename ("x"Z, NULL), "x"Z); + check_string (g_build_filename ("", Z"x", NULL), Z"x"); + check_string (g_build_filename ("", Z"x", NULL), Z"x"); + check_string (g_build_filename (Z, "x", NULL), Z"x"); + check_string (g_build_filename (Z Z, "x", NULL), Z Z"x"); + check_string (g_build_filename (Z S, "x", NULL), Z S"x"); + check_string (g_build_filename ("x"Z, "", NULL), "x"Z); + check_string (g_build_filename ("x"S"y", "z"Z"a", NULL), "x"S"y"S"z"Z"a"); + check_string (g_build_filename ("x", Z, NULL), "x"Z); + check_string (g_build_filename ("x", Z Z, NULL), "x"Z Z); + check_string (g_build_filename ("x", S Z, NULL), "x"S Z); + check_string (g_build_filename (Z"x", "y", NULL), Z"x"Z"y"); + check_string (g_build_filename ("x", "y"Z, NULL), "x"Z"y"Z); + check_string (g_build_filename (Z"x"Z, Z"y"Z, NULL), Z"x"Z"y"Z); + check_string (g_build_filename (Z"x"Z Z, Z Z"y"Z, NULL), Z"x"Z"y"Z); + check_string (g_build_filename ("x", Z, "y", NULL), "x"Z"y"); + check_string (g_build_filename ("x", Z Z, "y", NULL), "x"Z"y"); + check_string (g_build_filename ("x", Z S, "y", NULL), "x"S"y"); + check_string (g_build_filename ("x", S Z, "y", NULL), "x"Z"y"); + check_string (g_build_filename ("x", Z "y", "z", NULL), "x"Z"y"Z"z"); + check_string (g_build_filename ("x", S "y", "z", NULL), "x"S"y"S"z"); + check_string (g_build_filename ("x", S "y", "z", Z, "a", "b", NULL), "x"S"y"S"z"Z"a"Z"b"); + check_string (g_build_filename (Z"x"Z, Z"y"Z, Z"z"Z, NULL), Z"x"Z"y"Z"z"Z); + check_string (g_build_filename (Z Z"x"Z Z, Z Z"y"Z Z, Z Z"z"Z Z, NULL), Z Z"x"Z"y"Z"z"Z Z); + +#undef Z + +#endif /* G_OS_WIN32 */ + +} + +static void +test_build_filenamev (void) +{ + gchar *args[10]; + + args[0] = NULL; + check_string (g_build_filenamev (args), ""); + args[0] = S; args[1] = NULL; + check_string (g_build_filenamev (args), S); + args[0] = S"x"; args[1] = NULL; + check_string (g_build_filenamev (args), S"x"); + args[0] = "x"S; args[1] = NULL; + check_string (g_build_filenamev (args), "x"S); + args[0] = ""; args[1] = "x"; args[2] = NULL; + check_string (g_build_filenamev (args), "x"); + args[0] = ""; args[1] = S"x"; args[2] = NULL; + check_string (g_build_filenamev (args), S"x"); + args[0] = S; args[1] = "x"; args[2] = NULL; + check_string (g_build_filenamev (args), S"x"); + args[0] = S S; args[1] = "x"; args[2] = NULL; + check_string (g_build_filenamev (args), S S"x"); + args[0] = "x"; args[1] = ""; args[2] = NULL; + check_string (g_build_filenamev (args), "x"); + args[0] = "x"S; args[1] = ""; args[2] = NULL; + check_string (g_build_filenamev (args), "x"S); + args[0] = "x"; args[1] = S; args[2] = NULL; + check_string (g_build_filenamev (args), "x"S); + args[0] = "x"; args[1] = S S; args[2] = NULL; + check_string (g_build_filenamev (args), "x"S S); + args[0] = "x"; args[1] = "y"; args[2] = NULL; + check_string (g_build_filenamev (args), "x"S"y"); + args[0] = S"x"; args[1] = "y"; args[2] = NULL; + check_string (g_build_filenamev (args), S"x"S"y"); + args[0] = "x"; args[1] = "y"S; args[2] = NULL; + check_string (g_build_filenamev (args), "x"S"y"S); + args[0] = S"x"S; args[1] = S"y"S; args[2] = NULL; + check_string (g_build_filenamev (args), S"x"S"y"S); + args[0] = S"x"S S; args[1] = S S"y"S; args[2] = NULL; + check_string (g_build_filenamev (args), S"x"S"y"S); + args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL; + check_string (g_build_filenamev (args), "x"S"y"); + args[0] = "x"; args[1] = S; args[2] = "y"; args[3] = NULL; + check_string (g_build_filenamev (args), "x"S"y"); + args[0] = "x"; args[1] = S S; args[2] = "y"; args[3] = NULL; + check_string (g_build_filenamev (args), "x"S"y"); + args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL; + check_string (g_build_filenamev (args), "x"S"y"S"z"); + args[0] = S"x"S; args[1] = S"y"S; args[2] = S"z"S; args[3] = NULL; + check_string (g_build_filenamev (args), S"x"S"y"S"z"S); + args[0] = S S"x"S S; args[1] = S S"y"S S; args[2] = S S"z"S S; args[3] = NULL; + check_string (g_build_filenamev (args), S S"x"S"y"S"z"S S); + +#ifdef G_OS_WIN32 + + /* Test also using the slash as file name separator */ +#define Z "/" + args[0] = NULL; + check_string (g_build_filenamev (args), ""); + args[0] = Z; args[1] = NULL; + check_string (g_build_filenamev (args), Z); + args[0] = Z"x"; args[1] = NULL; + check_string (g_build_filenamev (args), Z"x"); + args[0] = "x"Z; args[1] = NULL; + check_string (g_build_filenamev (args), "x"Z); + args[0] = ""; args[1] = Z"x"; args[2] = NULL; + check_string (g_build_filenamev (args), Z"x"); + args[0] = ""; args[1] = Z"x"; args[2] = NULL; + check_string (g_build_filenamev (args), Z"x"); + args[0] = Z; args[1] = "x"; args[2] = NULL; + check_string (g_build_filenamev (args), Z"x"); + args[0] = Z Z; args[1] = "x"; args[2] = NULL; + check_string (g_build_filenamev (args), Z Z"x"); + args[0] = Z S; args[1] = "x"; args[2] = NULL; + check_string (g_build_filenamev (args), Z S"x"); + args[0] = "x"Z; args[1] = ""; args[2] = NULL; + check_string (g_build_filenamev (args), "x"Z); + args[0] = "x"S"y"; args[1] = "z"Z"a"; args[2] = NULL; + check_string (g_build_filenamev (args), "x"S"y"S"z"Z"a"); + args[0] = "x"; args[1] = Z; args[2] = NULL; + check_string (g_build_filenamev (args), "x"Z); + args[0] = "x"; args[1] = Z Z; args[2] = NULL; + check_string (g_build_filenamev (args), "x"Z Z); + args[0] = "x"; args[1] = S Z; args[2] = NULL; + check_string (g_build_filenamev (args), "x"S Z); + args[0] = Z"x"; args[1] = "y"; args[2] = NULL; + check_string (g_build_filenamev (args), Z"x"Z"y"); + args[0] = "x"; args[1] = "y"Z; args[2] = NULL; + check_string (g_build_filenamev (args), "x"Z"y"Z); + args[0] = Z"x"Z; args[1] = Z"y"Z; args[2] = NULL; + check_string (g_build_filenamev (args), Z"x"Z"y"Z); + args[0] = Z"x"Z Z; args[1] = Z Z"y"Z; args[2] = NULL; + check_string (g_build_filenamev (args), Z"x"Z"y"Z); + args[0] = "x"; args[1] = Z; args[2] = "y", args[3] = NULL; + check_string (g_build_filenamev (args), "x"Z"y"); + args[0] = "x"; args[1] = Z Z; args[2] = "y", args[3] = NULL; + check_string (g_build_filenamev (args), "x"Z"y"); + args[0] = "x"; args[1] = Z S; args[2] = "y", args[3] = NULL; + check_string (g_build_filenamev (args), "x"S"y"); + args[0] = "x"; args[1] = S Z; args[2] = "y", args[3] = NULL; + check_string (g_build_filenamev (args), "x"Z"y"); + args[0] = "x"; args[1] = Z "y"; args[2] = "z", args[3] = NULL; + check_string (g_build_filenamev (args), "x"Z"y"Z"z"); + args[0] = "x"; args[1] = S "y"; args[2] = "z", args[3] = NULL; + check_string (g_build_filenamev (args), "x"S"y"S"z"); + args[0] = "x"; args[1] = S "y"; args[2] = "z", args[3] = Z; + args[4] = "a"; args[5] = "b"; args[6] = NULL; + check_string (g_build_filenamev (args), "x"S"y"S"z"Z"a"Z"b"); + args[0] = Z"x"Z; args[1] = Z"y"Z; args[2] = Z"z"Z, args[3] = NULL; + check_string (g_build_filenamev (args), Z"x"Z"y"Z"z"Z); + args[0] = Z Z"x"Z Z; args[1] = Z Z"y"Z Z; args[2] = Z Z"z"Z Z, args[3] = NULL; + check_string (g_build_filenamev (args), Z Z"x"Z"y"Z"z"Z Z); + +#undef Z + +#endif /* G_OS_WIN32 */ +} + +#undef S + +static void +test_mkdir_with_parents_1 (const gchar *base) +{ + char *p0 = g_build_filename (base, "fum", NULL); + char *p1 = g_build_filename (p0, "tem", NULL); + char *p2 = g_build_filename (p1, "zap", NULL); + FILE *f; + + g_remove (p2); + g_remove (p1); + g_remove (p0); + + if (g_file_test (p0, G_FILE_TEST_EXISTS)) + g_error ("failed, %s exists, cannot test g_mkdir_with_parents", p0); + + if (g_file_test (p1, G_FILE_TEST_EXISTS)) + g_error ("failed, %s exists, cannot test g_mkdir_with_parents", p1); + + if (g_file_test (p2, G_FILE_TEST_EXISTS)) + g_error ("failed, %s exists, cannot test g_mkdir_with_parents", p2); + + if (g_mkdir_with_parents (p2, 0777) == -1) + { + int errsv = errno; + g_error ("failed, g_mkdir_with_parents(%s) failed: %s", p2, g_strerror (errsv)); + } + + if (!g_file_test (p2, G_FILE_TEST_IS_DIR)) + g_error ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory", p2, p2); + + if (!g_file_test (p1, G_FILE_TEST_IS_DIR)) + g_error ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory", p2, p1); + + if (!g_file_test (p0, G_FILE_TEST_IS_DIR)) + g_error ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory", p2, p0); + + g_rmdir (p2); + if (g_file_test (p2, G_FILE_TEST_EXISTS)) + g_error ("failed, did g_rmdir(%s), but %s is still there", p2, p2); + + g_rmdir (p1); + if (g_file_test (p1, G_FILE_TEST_EXISTS)) + g_error ("failed, did g_rmdir(%s), but %s is still there", p1, p1); + + f = g_fopen (p1, "w"); + if (f == NULL) + g_error ("failed, couldn't create file %s", p1); + fclose (f); + + if (g_mkdir_with_parents (p1, 0666) == 0) + g_error ("failed, g_mkdir_with_parents(%s) succeeded, even if %s is a file", p1, p1); + + if (g_mkdir_with_parents (p2, 0666) == 0) + g_error("failed, g_mkdir_with_parents(%s) succeeded, even if %s is a file", p2, p1); + + g_remove (p2); + g_remove (p1); + g_remove (p0); + + g_free (p2); + g_free (p1); + g_free (p0); +} + +static void +test_mkdir_with_parents (void) +{ + gchar *cwd, *new_path; + if (g_test_verbose()) + g_printerr ("checking g_mkdir_with_parents() in subdir ./hum/"); + test_mkdir_with_parents_1 ("hum"); + g_remove ("hum"); + if (g_test_verbose()) + g_printerr ("checking g_mkdir_with_parents() in subdir ./hii///haa/hee/"); + test_mkdir_with_parents_1 ("./hii///haa/hee///"); + g_remove ("hii/haa/hee"); + g_remove ("hii/haa"); + g_remove ("hii"); + cwd = g_get_current_dir (); + if (g_test_verbose()) + g_printerr ("checking g_mkdir_with_parents() in cwd: %s", cwd); + test_mkdir_with_parents_1 (cwd); + + new_path = g_build_filename (cwd, "new", NULL); + g_assert_cmpint (g_mkdir_with_parents (new_path, 0), ==, 0); + g_assert_cmpint (g_rmdir (new_path), ==, 0); + g_free (new_path); + g_free (cwd); + + g_assert_cmpint (g_mkdir_with_parents ("./test", 0), ==, 0); + g_assert_cmpint (g_mkdir_with_parents ("./test", 0), ==, 0); + g_remove ("./test"); + +#ifdef G_OS_WIN32 + g_assert_cmpint (g_mkdir_with_parents ("\\Windows\\b\\c", 0), ==, -1); +#else + g_assert_cmpint (g_mkdir_with_parents ("/usr/b/c", 0), ==, -1); + /* EPERM may be returned if the filesystem as a whole is read-only */ + if (errno != EPERM) + g_assert_cmpint (errno, ==, EACCES); +#endif + + g_assert_cmpint (g_mkdir_with_parents (NULL, 0), ==, -1); + g_assert_cmpint (errno, ==, EINVAL); +} + +/* + * check_cap_dac_override: + * @tmpdir: (nullable): A temporary directory in which we can create + * and delete files. If %NULL, use the g_get_tmp_dir(), safely. + * + * Check whether the current process can bypass DAC permissions. + * + * Traditionally, "privileged" processes (those with effective uid 0) + * could do this (and bypass many other checks), and "unprivileged" + * processes could not. + * + * In Linux, the special powers of euid 0 are divided into many + * capabilities: see `capabilities(7)`. The one we are interested in + * here is `CAP_DAC_OVERRIDE`. + * + * We do this generically instead of actually looking at the capability + * bits, so that the right thing will happen on non-Linux Unix + * implementations, in particular if they have something equivalent to + * but not identical to Linux permissions. + * + * Returns: %TRUE if we have Linux `CAP_DAC_OVERRIDE` or equivalent + * privileges + */ +static gboolean +check_cap_dac_override (const char *tmpdir) +{ +#ifdef G_OS_UNIX + gchar *safe_tmpdir = NULL; + gchar *dac_denies_write; + gchar *inside; + gboolean have_cap; + + if (tmpdir == NULL) + { + /* It's unsafe to write predictable filenames into g_get_tmp_dir(), + * because it's usually a shared directory that can be subject to + * symlink attacks, so use a subdirectory for this check. */ + GError *error = NULL; + + safe_tmpdir = g_dir_make_tmp (NULL, &error); + g_assert_no_error (error); + g_clear_error (&error); + + if (safe_tmpdir == NULL) + return FALSE; + + tmpdir = safe_tmpdir; + } + + dac_denies_write = g_build_filename (tmpdir, "dac-denies-write", NULL); + inside = g_build_filename (dac_denies_write, "inside", NULL); + + g_assert_no_errno (mkdir (dac_denies_write, S_IRWXU)); + g_assert_no_errno (g_chmod (dac_denies_write, 0)); + + if (mkdir (inside, S_IRWXU) == 0) + { + g_test_message ("Looks like we have CAP_DAC_OVERRIDE or equivalent"); + g_assert_no_errno (rmdir (inside)); + have_cap = TRUE; + } + else + { + int saved_errno = errno; + + g_test_message ("We do not have CAP_DAC_OVERRIDE or equivalent"); + g_assert_cmpint (saved_errno, ==, EACCES); + have_cap = FALSE; + } + + g_assert_no_errno (g_chmod (dac_denies_write, S_IRWXU)); + g_assert_no_errno (rmdir (dac_denies_write)); + + if (safe_tmpdir != NULL) + g_assert_no_errno (rmdir (safe_tmpdir)); + + g_free (dac_denies_write); + g_free (inside); + g_free (safe_tmpdir); + return have_cap; +#else + return FALSE; +#endif +} + +/* Reproducer for https://gitlab.gnome.org/GNOME/glib/issues/1852 */ +static void +test_mkdir_with_parents_permission (void) +{ +#ifdef G_OS_UNIX + gchar *tmpdir; + gchar *subdir; + gchar *subdir2; + gchar *subdir3; + GError *error = NULL; + int result; + int saved_errno; + gboolean have_cap_dac_override; + + tmpdir = g_dir_make_tmp ("test-fileutils.XXXXXX", &error); + g_assert_no_error (error); + g_assert_nonnull (tmpdir); + + have_cap_dac_override = check_cap_dac_override (tmpdir); + + subdir = g_build_filename (tmpdir, "sub", NULL); + subdir2 = g_build_filename (subdir, "sub2", NULL); + subdir3 = g_build_filename (subdir2, "sub3", NULL); + g_assert_no_errno (g_mkdir (subdir, 0700)); + g_assert_no_errno (g_chmod (subdir, 0)); + + if (have_cap_dac_override) + { + g_test_skip ("have CAP_DAC_OVERRIDE or equivalent, cannot test"); + } + else + { + result = g_mkdir_with_parents (subdir2, 0700); + saved_errno = errno; + g_assert_cmpint (result, ==, -1); + g_assert_cmpint (saved_errno, ==, EACCES); + + result = g_mkdir_with_parents (subdir3, 0700); + saved_errno = errno; + g_assert_cmpint (result, ==, -1); + g_assert_cmpint (saved_errno, ==, EACCES); + + g_assert_no_errno (g_chmod (subdir, 0700)); + } + + g_assert_no_errno (g_remove (subdir)); + g_assert_no_errno (g_remove (tmpdir)); + g_free (subdir3); + g_free (subdir2); + g_free (subdir); + g_free (tmpdir); +#else + g_test_skip ("cannot test without Unix-style permissions"); +#endif +} + +static void +test_format_size_for_display (void) +{ +#ifdef G_OS_WIN32 + SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); +#endif + /* nobody called setlocale(), so we should get "C" behaviour... */ + check_string (g_format_size_for_display (0), "0 bytes"); + check_string (g_format_size_for_display (1), "1 byte"); + check_string (g_format_size_for_display (2), "2 bytes"); + check_string (g_format_size_for_display (1024), "1.0 KB"); + check_string (g_format_size_for_display (1024 * 1024), "1.0 MB"); + check_string (g_format_size_for_display (1024 * 1024 * 1024), "1.0 GB"); + check_string (g_format_size_for_display (1024ULL * 1024 * 1024 * 1024), "1.0 TB"); + check_string (g_format_size_for_display (1024ULL * 1024 * 1024 * 1024 * 1024), "1.0 PB"); + check_string (g_format_size_for_display (1024ULL * 1024 * 1024 * 1024 * 1024 * 1024), "1.0 EB"); + + check_string (g_format_size (0), "0 bytes"); + check_string (g_format_size (1), "1 byte"); + check_string (g_format_size (2), "2 bytes"); + /* '\302\240' is a no-break space, to keep quantity and unit symbol together at line breaks*/ + check_string (g_format_size (1000ULL), "1.0\302\240kB"); + check_string (g_format_size (1000ULL * 1000), "1.0\302\240MB"); + check_string (g_format_size (1000ULL * 1000 * 1000), "1.0\302\240GB"); + check_string (g_format_size (1000ULL * 1000 * 1000 * 1000), "1.0\302\240TB"); + check_string (g_format_size (1000ULL * 1000 * 1000 * 1000 * 1000), "1.0\302\240PB"); + check_string (g_format_size (1000ULL * 1000 * 1000 * 1000 * 1000 * 1000), "1.0\302\240EB"); + + check_string (g_format_size_full (0, G_FORMAT_SIZE_IEC_UNITS), "0 bytes"); + check_string (g_format_size_full (1, G_FORMAT_SIZE_IEC_UNITS), "1 byte"); + check_string (g_format_size_full (2, G_FORMAT_SIZE_IEC_UNITS), "2 bytes"); + + check_string (g_format_size_full (2048ULL, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240KiB"); + check_string (g_format_size_full (2048ULL * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240MiB"); + check_string (g_format_size_full (2048ULL * 1024 * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240GiB"); + check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240TiB"); + check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240PiB"); + check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240EiB"); + + check_string (g_format_size_full (238472938, G_FORMAT_SIZE_IEC_UNITS), "227.4\302\240MiB"); + check_string (g_format_size_full (238472938, G_FORMAT_SIZE_DEFAULT), "238.5\302\240MB"); + check_string (g_format_size_full (238472938, G_FORMAT_SIZE_LONG_FORMAT), "238.5\302\240MB (238472938 bytes)"); + + + check_string (g_format_size_full (0, G_FORMAT_SIZE_BITS), "0 bits"); + check_string (g_format_size_full (1, G_FORMAT_SIZE_BITS), "1 bit"); + check_string (g_format_size_full (2, G_FORMAT_SIZE_BITS), "2 bits"); + + check_string (g_format_size_full (2000ULL, G_FORMAT_SIZE_BITS), "2.0\302\240kb"); + check_string (g_format_size_full (2000ULL * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Mb"); + check_string (g_format_size_full (2000ULL * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Gb"); + check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Tb"); + check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Pb"); + check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Eb"); + + check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS), "238.5\302\240Mb"); + check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_LONG_FORMAT), "238.5\302\240Mb (238472938 bits)"); + + + check_string (g_format_size_full (0, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "0 bits"); + check_string (g_format_size_full (1, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "1 bit"); + check_string (g_format_size_full (2, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2 bits"); + + check_string (g_format_size_full (2048ULL, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Kib"); + check_string (g_format_size_full (2048ULL * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Mib"); + check_string (g_format_size_full (2048ULL * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Gib"); + check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Tib"); + check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Pib"); + check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Eib"); + + check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "227.4\302\240Mib"); + check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS | G_FORMAT_SIZE_LONG_FORMAT), "227.4\302\240Mib (238472938 bits)"); +} + +static void +test_file_errors (void) +{ + g_assert_cmpint (g_file_error_from_errno (-1), ==, G_FILE_ERROR_FAILED); + +#ifdef EEXIST + g_assert_cmpint (g_file_error_from_errno (EEXIST), ==, G_FILE_ERROR_EXIST); +#endif +#ifdef EISDIR + g_assert_cmpint (g_file_error_from_errno (EISDIR), ==, G_FILE_ERROR_ISDIR); +#endif +#ifdef EACCES + g_assert_cmpint (g_file_error_from_errno (EACCES), ==, G_FILE_ERROR_ACCES); +#endif +#ifdef ENAMETOOLONG + g_assert_cmpint (g_file_error_from_errno (ENAMETOOLONG), ==, G_FILE_ERROR_NAMETOOLONG); +#endif +#ifdef ENOENT + g_assert_cmpint (g_file_error_from_errno (ENOENT), ==, G_FILE_ERROR_NOENT); +#endif +#ifdef ENOTDIR + g_assert_cmpint (g_file_error_from_errno (ENOTDIR), ==, G_FILE_ERROR_NOTDIR); +#endif +#ifdef ENXIO + g_assert_cmpint (g_file_error_from_errno (ENXIO), ==, G_FILE_ERROR_NXIO); +#endif +#ifdef ENODEV + g_assert_cmpint (g_file_error_from_errno (ENODEV), ==, G_FILE_ERROR_NODEV); +#endif +#ifdef EROFS + g_assert_cmpint (g_file_error_from_errno (EROFS), ==, G_FILE_ERROR_ROFS); +#endif +#ifdef ETXTBSY + g_assert_cmpint (g_file_error_from_errno (ETXTBSY), ==, G_FILE_ERROR_TXTBSY); +#endif +#ifdef EFAULT + g_assert_cmpint (g_file_error_from_errno (EFAULT), ==, G_FILE_ERROR_FAULT); +#endif +#ifdef ELOOP + g_assert_cmpint (g_file_error_from_errno (ELOOP), ==, G_FILE_ERROR_LOOP); +#endif +#ifdef ENOSPC + g_assert_cmpint (g_file_error_from_errno (ENOSPC), ==, G_FILE_ERROR_NOSPC); +#endif +#ifdef ENOMEM + g_assert_cmpint (g_file_error_from_errno (ENOMEM), ==, G_FILE_ERROR_NOMEM); +#endif +#ifdef EMFILE + g_assert_cmpint (g_file_error_from_errno (EMFILE), ==, G_FILE_ERROR_MFILE); +#endif +#ifdef ENFILE + g_assert_cmpint (g_file_error_from_errno (ENFILE), ==, G_FILE_ERROR_NFILE); +#endif +#ifdef EBADF + g_assert_cmpint (g_file_error_from_errno (EBADF), ==, G_FILE_ERROR_BADF); +#endif +#ifdef EINVAL + g_assert_cmpint (g_file_error_from_errno (EINVAL), ==, G_FILE_ERROR_INVAL); +#endif +#ifdef EPIPE + g_assert_cmpint (g_file_error_from_errno (EPIPE), ==, G_FILE_ERROR_PIPE); +#endif +#ifdef EAGAIN + g_assert_cmpint (g_file_error_from_errno (EAGAIN), ==, G_FILE_ERROR_AGAIN); +#endif +#ifdef EINTR + g_assert_cmpint (g_file_error_from_errno (EINTR), ==, G_FILE_ERROR_INTR); +#endif +#ifdef EIO + g_assert_cmpint (g_file_error_from_errno (EIO), ==, G_FILE_ERROR_IO); +#endif +#ifdef EPERM + g_assert_cmpint (g_file_error_from_errno (EPERM), ==, G_FILE_ERROR_PERM); +#endif +#ifdef ENOSYS + g_assert_cmpint (g_file_error_from_errno (ENOSYS), ==, G_FILE_ERROR_NOSYS); +#endif +} + +static void +test_basename (void) +{ + const gchar *path = "/path/to/a/file/deep/down.sh"; + const gchar *b; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_assert_null (g_basename (NULL)); + g_test_assert_expected_messages (); + } + + b = g_basename (path); + + g_assert_cmpstr (b, ==, "down.sh"); +} + +static void +test_get_basename (void) +{ + gchar *b; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_assert_null (g_path_get_basename (NULL)); + g_test_assert_expected_messages (); + } + + b = g_path_get_basename (""); + g_assert_cmpstr (b, ==, "."); + g_free (b); + + b = g_path_get_basename ("///"); + g_assert_cmpstr (b, ==, G_DIR_SEPARATOR_S); + g_free (b); + + b = g_path_get_basename ("/a/b/c/d"); + g_assert_cmpstr (b, ==, "d"); + g_free (b); +} + +static void +test_dirname (void) +{ + gsize i; + struct { + const gchar *filename; + const gchar *dirname; + } dirname_checks[] = { + { "/", "/" }, + { "////", "/" }, + { ".////", "." }, + { ".", "." }, + { "..", "." }, + { "../", ".." }, + { "..////", ".." }, + { "", "." }, + { "a/b", "a" }, + { "a/b/", "a/b" }, + { "c///", "c" }, + { "/a/b", "/a" }, + { "/a/b/", "/a/b" }, +#ifdef G_OS_WIN32 + { "\\", "\\" }, + { ".\\\\\\\\", "." }, + { ".\\/\\/", "." }, + { ".", "." }, + { "..", "." }, + { "..\\", ".." }, + { "..\\\\\\\\", ".." }, + { "..\\//\\", ".." }, + { "", "." }, + { "a\\b", "a" }, + { "a\\b\\", "a\\b" }, + { "\\a\\b", "\\a" }, + { "\\a\\b\\", "\\a\\b" }, + { "c\\\\\\", "c" }, + { "c/\\\\", "c" }, + { "a:", "a:." }, + { "a:foo", "a:." }, + { "a:foo\\bar", "a:foo" }, + { "a:/foo", "a:/" }, + { "a:/foo/bar", "a:/foo" }, + { "a:/", "a:/" }, + { "a://", "a:/" }, + { "a:\\foo", "a:\\" }, + { "a:\\", "a:\\" }, + { "a:\\\\", "a:\\" }, + { "a:\\/", "a:\\" }, +#endif + }; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_assert_null (g_path_get_dirname (NULL)); + g_test_assert_expected_messages (); + } + + for (i = 0; i < G_N_ELEMENTS (dirname_checks); i++) + { + gchar *dirname; + + dirname = g_path_get_dirname (dirname_checks[i].filename); + g_assert_cmpstr (dirname, ==, dirname_checks[i].dirname); + g_free (dirname); + } +} + +static void +test_dir_make_tmp (void) +{ + gchar *name; + GError *error = NULL; + gint ret; + + name = g_dir_make_tmp ("testXXXXXXtest", &error); + g_assert_no_error (error); + g_assert_true (g_file_test (name, G_FILE_TEST_IS_DIR)); + ret = g_rmdir (name); + g_assert_cmpint (ret, ==, 0); + g_free (name); + + name = g_dir_make_tmp (NULL, &error); + g_assert_no_error (error); + g_assert_true (g_file_test (name, G_FILE_TEST_IS_DIR)); + ret = g_rmdir (name); + g_assert_cmpint (ret, ==, 0); + g_free (name); + + name = g_dir_make_tmp ("test/XXXXXX", &error); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED); + g_clear_error (&error); + g_assert_null (name); + + name = g_dir_make_tmp ("XXXXxX", &error); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED); + g_clear_error (&error); + g_assert_null (name); +} + +static void +test_file_open_tmp (void) +{ + gchar *name = NULL; + GError *error = NULL; + gint fd; + + fd = g_file_open_tmp ("testXXXXXXtest", &name, &error); + g_assert_cmpint (fd, !=, -1); + g_assert_no_error (error); + g_assert_nonnull (name); + unlink (name); + g_free (name); + close (fd); + + fd = g_file_open_tmp (NULL, &name, &error); + g_assert_cmpint (fd, !=, -1); + g_assert_no_error (error); + g_assert_nonnull (name); + g_unlink (name); + g_free (name); + close (fd); + + name = NULL; + fd = g_file_open_tmp ("test/XXXXXX", &name, &error); + g_assert_cmpint (fd, ==, -1); + g_assert_null (name); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED); + g_clear_error (&error); + + fd = g_file_open_tmp ("XXXXxX", &name, &error); + g_assert_cmpint (fd, ==, -1); + g_assert_null (name); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED); + g_clear_error (&error); + + error = NULL; + name = NULL; + fd = g_file_open_tmp ("zap" G_DIR_SEPARATOR_S "barXXXXXX", &name, &error); + g_assert_cmpint (fd, ==, -1); + + g_clear_error (&error); + g_free (name); + +#ifdef G_OS_WIN32 + name = NULL; + fd = g_file_open_tmp ("zap/barXXXXXX", &name, &error); + g_assert_cmpint (fd, ==, -1); + + g_clear_error (&error); + g_free (name); +#endif + + name = NULL; + fd = g_file_open_tmp ("zapXXXXXX", &name, &error); + g_assert_cmpint (fd, !=, -1); + + close (fd); + g_clear_error (&error); + remove (name); + g_free (name); + + name = NULL; + fd = g_file_open_tmp (NULL, &name, &error); + g_assert_cmpint (fd, !=, -1); + + close (fd); + g_clear_error (&error); + remove (name); + g_free (name); +} + +static void +test_mkstemp (void) +{ + gint fd; + gint result; + gchar *name; + char chars[62]; + char template[32]; + const char hello[] = "Hello, World"; + const gsize hellolen = sizeof (hello) - 1; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_assert_cmpint (g_mkstemp (NULL), ==, -1); + g_test_assert_expected_messages (); + } + + /* Expect to fail if no 'XXXXXX' is given */ + name = g_strdup ("test"); + g_assert_cmpint (g_mkstemp (name), ==, -1); + g_free (name); + + /* Test normal case */ + name = g_strdup ("testXXXXXXtest"), + fd = g_mkstemp (name); + g_assert_cmpint (fd, !=, -1); + g_assert_null (strstr (name, "XXXXXX")); + unlink (name); + close (fd); + g_free (name); + + /* g_mkstemp() must not work if template doesn't contain XXXXXX */ + strcpy (template, "foobar"); + g_assert_cmpint (g_mkstemp (template), ==, -1); + + /* g_mkstemp() must not work if template doesn't contain six X */ + strcpy (template, "foobarXXX"); + g_assert_cmpint (g_mkstemp (template), ==, -1); + + strcpy (template, "fooXXXXXX"); + fd = g_mkstemp (template); + g_assert_cmpint (fd, !=, -1); + result = write (fd, hello, hellolen); + g_assert_cmpint (result, !=, -1); + g_assert_cmpint (result, ==, hellolen); + + lseek (fd, 0, 0); + result = read (fd, chars, sizeof (chars)); + g_assert_cmpint (result, !=, -1); + g_assert_cmpint (result, ==, hellolen); + + chars[result] = '\0'; + g_assert_cmpstr (chars, ==, hello); + + close (fd); + remove (template); + + /* Check that is does not work for "fooXXXXXX.pdf" */ + strcpy (template, "fooXXXXXX.pdf"); + fd = g_mkstemp (template); + g_assert_cmpint (fd, !=, -1); + + close (fd); + remove (template); +} + +static void +test_mkdtemp (void) +{ + gint fd; + gchar *ret; + gchar *name; + char template[32]; + + name = g_strdup ("testXXXXXXtest"), + ret = g_mkdtemp (name); + g_assert (ret == name); + g_assert_null (strstr (name, "XXXXXX")); + g_rmdir (name); + g_free (name); + + name = g_strdup ("testYYYYYYtest"), + ret = g_mkdtemp (name); + g_assert_null (ret); + g_free (name); + + strcpy (template, "foodir"); + g_assert_null (g_mkdtemp (template)); + + strcpy (template, "foodir"); + g_assert_null (g_mkdtemp (template)); + + strcpy (template, "fooXXXXXX"); + ret = g_mkdtemp (template); + g_assert_nonnull (ret); + g_assert_true (ret == template); + g_assert_false (g_file_test (template, G_FILE_TEST_IS_REGULAR)); + g_assert_true (g_file_test (template, G_FILE_TEST_IS_DIR)); + + strcat (template, "/abc"); + fd = g_open (template, O_WRONLY | O_CREAT, 0600); + g_assert_cmpint (fd, !=, -1); + close (fd); + g_assert_true (g_file_test (template, G_FILE_TEST_IS_REGULAR)); + g_assert_cmpint (g_unlink (template), !=, -1); + + template[9] = '\0'; + g_assert_cmpint (g_rmdir (template), !=, -1); + + strcpy (template, "fooXXXXXX.dir"); + g_assert_nonnull (g_mkdtemp (template)); + g_assert_true (g_file_test (template, G_FILE_TEST_IS_DIR)); + g_rmdir (template); +} + +static void +test_get_contents (void) +{ + FILE *f; + gsize len; + gchar *contents; + GError *error = NULL; + const gchar *text = "abcdefghijklmnopqrstuvwxyz"; + const gchar *filename = "file-test-get-contents"; + + f = g_fopen (filename, "w"); + fwrite (text, 1, strlen (text), f); + fclose (f); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_assert_false (g_file_get_contents (NULL, &contents, &len, &error)); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_assert_false (g_file_get_contents (filename, NULL, &len, &error)); + g_test_assert_expected_messages (); + } + + g_assert_true (g_file_test (filename, G_FILE_TEST_IS_REGULAR)); + + g_assert_true (g_file_get_contents (filename, &contents, &len, &error)); + g_assert_cmpstr (text, ==, contents); + g_assert_no_error (error); + + g_free (contents); +} + +static void +test_file_test (void) +{ + GError *error = NULL; + gboolean result; + gchar *name; + gint fd; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_file_test (NULL, G_FILE_TEST_EXISTS); + g_assert_false (result); + g_test_assert_expected_messages (); + } + + fd = g_file_open_tmp (NULL, &name, &error); + g_assert_no_error (error); + write (fd, "a", 1); + g_assert_cmpint (g_fsync (fd), ==, 0); + close (fd); + +#ifndef G_OS_WIN32 + result = g_file_test (name, G_FILE_TEST_IS_SYMLINK); + g_assert_false (result); + + symlink (name, "symlink"); + result = g_file_test ("symlink", G_FILE_TEST_IS_SYMLINK); + g_assert_true (result); + unlink ("symlink"); +#endif + + /* Cleaning */ + g_remove (name); + g_free (name); +} + +static void +test_set_contents (void) +{ + GError *error = NULL; + gint fd; + gchar *name; + gchar *buf; + gsize len; + gboolean ret; + + fd = g_file_open_tmp (NULL, &name, &error); + g_assert_no_error (error); + write (fd, "a", 1); + g_assert_cmpint (g_fsync (fd), ==, 0); + close (fd); + + ret = g_file_get_contents (name, &buf, &len, &error); + g_assert_true (ret); + g_assert_no_error (error); + g_assert_cmpstr (buf, ==, "a"); + g_free (buf); + + ret = g_file_set_contents (name, "b", 1, &error); + g_assert_true (ret); + g_assert_no_error (error); + + ret = g_file_get_contents (name, &buf, &len, &error); + g_assert_true (ret); + g_assert_no_error (error); + g_assert_cmpstr (buf, ==, "b"); + g_free (buf); + + g_remove (name); + g_free (name); +} + +static void +test_set_contents_full (void) +{ + GFileSetContentsFlags flags_mask = + G_FILE_SET_CONTENTS_ONLY_EXISTING | + G_FILE_SET_CONTENTS_DURABLE | + G_FILE_SET_CONTENTS_CONSISTENT; + gint flags; + const struct + { + enum + { + EXISTING_FILE_NONE, + EXISTING_FILE_REGULAR, +#ifndef G_OS_WIN32 + EXISTING_FILE_SYMLINK, +#endif + EXISTING_FILE_DIRECTORY, + } + existing_file; + int new_mode; /* only relevant if @existing_file is %EXISTING_FILE_NONE */ + gboolean use_strlen; + + gboolean expected_success; + gint expected_error; + } + tests[] = + { + { EXISTING_FILE_NONE, 0644, FALSE, TRUE, 0 }, + { EXISTING_FILE_NONE, 0644, TRUE, TRUE, 0 }, + { EXISTING_FILE_NONE, 0600, FALSE, TRUE, 0 }, + { EXISTING_FILE_REGULAR, 0644, FALSE, TRUE, 0 }, +#ifndef G_OS_WIN32 + { EXISTING_FILE_SYMLINK, 0644, FALSE, TRUE, 0 }, + { EXISTING_FILE_DIRECTORY, 0644, FALSE, FALSE, G_FILE_ERROR_ISDIR }, +#else + /* on win32, _wopen returns EACCES if path is a directory */ + { EXISTING_FILE_DIRECTORY, 0644, FALSE, FALSE, G_FILE_ERROR_ACCES }, +#endif + }; + gsize i; + + g_test_summary ("Test g_file_set_contents_full() with various flags"); + + for (flags = 0; flags < (gint) flags_mask; flags++) + { + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + GError *error = NULL; + gchar *file_name = NULL, *link_name = NULL, *dir_name = NULL; + const gchar *set_contents_name; + gchar *buf = NULL; + gsize len; + gboolean ret; + GStatBuf statbuf; + + g_test_message ("Flags %d and test %" G_GSIZE_FORMAT, flags, i); + + switch (tests[i].existing_file) + { + case EXISTING_FILE_REGULAR: +#ifndef G_OS_WIN32 + case EXISTING_FILE_SYMLINK: +#endif + { + gint fd; + + fd = g_file_open_tmp (NULL, &file_name, &error); + g_assert_no_error (error); + write (fd, "a", 1); + g_assert_no_errno (g_fsync (fd)); + close (fd); + +#ifndef G_OS_WIN32 + /* Pass an existing symlink to g_file_set_contents_full() to see + * what it does. */ + if (tests[i].existing_file == EXISTING_FILE_SYMLINK) + { + link_name = g_strconcat (file_name, ".link", NULL); + g_assert_no_errno (symlink (file_name, link_name)); + + set_contents_name = link_name; + } + else +#endif /* !G_OS_WIN32 */ + { + set_contents_name = file_name; + } + break; + } + case EXISTING_FILE_DIRECTORY: + { + dir_name = g_dir_make_tmp ("glib-fileutils-set-contents-full-XXXXXX", &error); + g_assert_no_error (error); + + set_contents_name = dir_name; + break; + } + case EXISTING_FILE_NONE: + { + file_name = g_build_filename (g_get_tmp_dir (), "glib-file-set-contents-full-test", NULL); + g_remove (file_name); + g_assert_false (g_file_test (file_name, G_FILE_TEST_EXISTS)); + + set_contents_name = file_name; + break; + } + default: + { + g_assert_not_reached (); + } + } + + /* Set the file contents */ + ret = g_file_set_contents_full (set_contents_name, "b", + tests[i].use_strlen ? -1 : 1, + flags, tests[i].new_mode, &error); + + if (!tests[i].expected_success) + { + g_assert_error (error, G_FILE_ERROR, tests[i].expected_error); + g_assert_false (ret); + g_clear_error (&error); + } + else + { + g_assert_no_error (error); + g_assert_true (ret); + + /* Check the contents and mode were set correctly. The mode isn’t + * changed on existing files. */ + ret = g_file_get_contents (set_contents_name, &buf, &len, &error); + g_assert_no_error (error); + g_assert_true (ret); + g_assert_cmpstr (buf, ==, "b"); + g_assert_cmpuint (len, ==, 1); + g_free (buf); + + g_assert_no_errno (g_lstat (set_contents_name, &statbuf)); + + if (tests[i].existing_file == EXISTING_FILE_NONE) + { + int mode = statbuf.st_mode & ~S_IFMT; + int new_mode = tests[i].new_mode; +#ifdef G_OS_WIN32 + /* on windows, group and others perms handling is different */ + /* only check the rwx user permissions */ + mode &= (_S_IREAD|_S_IWRITE|_S_IEXEC); + new_mode &= (_S_IREAD|_S_IWRITE|_S_IEXEC); +#endif + g_assert_cmpint (mode, ==, new_mode); + } + +#ifndef G_OS_WIN32 + if (tests[i].existing_file == EXISTING_FILE_SYMLINK) + { + gchar *target_contents = NULL; + + /* If the @set_contents_name was a symlink, it should now be a + * regular file, and the file it pointed to should not have + * changed. */ + g_assert_cmpint (statbuf.st_mode & S_IFMT, ==, S_IFREG); + + g_file_get_contents (file_name, &target_contents, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (target_contents, ==, "a"); + + g_free (target_contents); + } +#endif /* !G_OS_WIN32 */ + } + + if (dir_name != NULL) + g_rmdir (dir_name); + if (link_name != NULL) + g_remove (link_name); + if (file_name != NULL) + g_remove (file_name); + + g_free (dir_name); + g_free (link_name); + g_free (file_name); + } + } +} + +static void +test_set_contents_full_read_only_file (void) +{ + gint fd; + GError *error = NULL; + gchar *file_name = NULL; + gboolean ret; + gboolean can_override_dac = check_cap_dac_override (NULL); + + g_test_summary ("Test g_file_set_contents_full() on a read-only file"); + + /* Can’t test this with different #GFileSetContentsFlags as they all have + * different behaviours wrt replacing the file while noticing/ignoring the + * existing file permissions. */ + fd = g_file_open_tmp (NULL, &file_name, &error); + g_assert_no_error (error); + write (fd, "a", 1); + g_assert_no_errno (g_fsync (fd)); + close (fd); + g_assert_no_errno (g_chmod (file_name, 0400)); /* S_IREAD */ + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + ret = g_file_set_contents_full (NULL, "b", 1, + G_FILE_SET_CONTENTS_NONE, 0644, &error); + g_assert_false (ret); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + ret = g_file_set_contents_full (file_name, NULL, 1, + G_FILE_SET_CONTENTS_NONE, 0644, &error); + g_assert_false (ret); + g_test_assert_expected_messages (); + } + + /* Set the file contents */ + ret = g_file_set_contents_full (file_name, "b", 1, G_FILE_SET_CONTENTS_NONE, 0644, &error); + + if (can_override_dac) + { + g_assert_no_error (error); + g_assert_true (ret); + } + else + { + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES); + g_assert_false (ret); + } + + g_clear_error (&error); + + g_remove (file_name); + + g_free (file_name); +} + +static void +test_set_contents_full_read_only_directory (void) +{ +#ifndef G_OS_WIN32 +/* windows mostly ignores read-only flagged directories, chmod doesn't work */ + GFileSetContentsFlags flags_mask = + G_FILE_SET_CONTENTS_ONLY_EXISTING | + G_FILE_SET_CONTENTS_DURABLE | + G_FILE_SET_CONTENTS_CONSISTENT; + gint flags; + + g_test_summary ("Test g_file_set_contents_full() on a file in a read-only directory"); + + for (flags = 0; flags < (gint) flags_mask; flags++) + { + gint fd; + GError *error = NULL; + gchar *dir_name = NULL; + gchar *file_name = NULL; + gboolean ret; + gboolean can_override_dac; + + g_test_message ("Flags %d", flags); + + dir_name = g_dir_make_tmp ("glib-file-set-contents-full-rodir-XXXXXX", &error); + g_assert_no_error (error); + can_override_dac = check_cap_dac_override (dir_name); + + file_name = g_build_filename (dir_name, "file", NULL); + fd = g_open (file_name, O_CREAT | O_RDWR, 0644); + g_assert_cmpint (fd, >=, 0); + write (fd, "a", 1); + g_assert_no_errno (g_fsync (fd)); + close (fd); + + g_assert_no_errno (g_chmod (dir_name, 0)); + + /* Set the file contents */ + ret = g_file_set_contents_full (file_name, "b", 1, flags, 0644, &error); + + if (can_override_dac) + { + g_assert_no_error (error); + g_assert_true (ret); + } + else + { + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES); + g_assert_false (ret); + } + + g_clear_error (&error); + g_remove (file_name); + g_unlink (dir_name); + + g_free (file_name); + g_free (dir_name); + } +#else + g_test_skip ("Windows doesn’t support read-only directories in the same way as Unix"); +#endif +} + +static void +test_read_link (void) +{ +#ifdef HAVE_READLINK +#ifdef G_OS_UNIX + int ret; + FILE *file; + gchar *cwd; + gchar *data; + gchar *newpath; + gchar *badpath; + gchar *path; + GError *error = NULL; + const gchar *oldpath; + const gchar *filename = "file-test-data"; + const gchar *link1 = "file-test-link1"; + const gchar *link2 = "file-test-link2"; + const gchar *link3 = "file-test-link3"; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + newpath = g_file_read_link (NULL, &error); + g_test_assert_expected_messages (); + } + + cwd = g_get_current_dir (); + + oldpath = g_test_get_filename (G_TEST_DIST, "4096-random-bytes", NULL); + newpath = g_build_filename (cwd, "page-of-junk", NULL); + badpath = g_build_filename (cwd, "4097-random-bytes", NULL); + remove (newpath); + ret = symlink (oldpath, newpath); + g_assert_cmpint (ret, ==, 0); + path = g_file_read_link (newpath, &error); + g_assert_no_error (error); + g_assert_cmpstr (path, ==, oldpath); + g_free (path); + + remove (newpath); + ret = symlink (badpath, newpath); + g_assert_cmpint (ret, ==, 0); + path = g_file_read_link (newpath, &error); + g_assert_no_error (error); + g_assert_cmpstr (path, ==, badpath); + g_free (path); + + path = g_file_read_link (oldpath, &error); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL); + g_assert_null (path); + g_error_free (error); + + remove (newpath); + g_free (cwd); + g_free (newpath); + g_free (badpath); + + file = fopen (filename, "w"); + g_assert_nonnull (file); + fclose (file); + + g_assert_cmpint (symlink (filename, link1), ==, 0); + g_assert_cmpint (symlink (link1, link2), ==, 0); + + error = NULL; + data = g_file_read_link (link1, &error); + g_assert_nonnull (data); + g_assert_cmpstr (data, ==, filename); + g_assert_no_error (error); + g_free (data); + + error = NULL; + data = g_file_read_link (link2, &error); + g_assert_nonnull (data); + g_assert_cmpstr (data, ==, link1); + g_assert_no_error (error); + g_free (data); + + error = NULL; + data = g_file_read_link (link3, &error); + g_assert_null (data); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); + g_error_free (error); + + error = NULL; + data = g_file_read_link (filename, &error); + g_assert_null (data); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL); + g_error_free (error); + + remove (filename); + remove (link1); + remove (link2); +#endif +#else + g_test_skip ("Symbolic links not supported"); +#endif +} + +static void +test_stdio_wrappers (void) +{ + GStatBuf buf; + gchar *cwd, *path; + gint ret; + struct utimbuf ut; + GError *error = NULL; + GStatBuf path_statbuf, cwd_statbuf; + time_t now; +#ifdef G_OS_UNIX + gboolean have_cap_dac_override; +#endif + + g_remove ("mkdir-test/test-create"); + ret = g_rmdir ("mkdir-test"); + g_assert (ret == 0 || errno == ENOENT); + + ret = g_stat ("mkdir-test", &buf); + g_assert_cmpint (ret, ==, -1); + ret = g_mkdir ("mkdir-test", 0666); + g_assert_cmpint (ret, ==, 0); + ret = g_stat ("mkdir-test", &buf); + g_assert_cmpint (ret, ==, 0); + g_assert_cmpint (S_ISDIR (buf.st_mode), !=, 0); + + cwd = g_get_current_dir (); + path = g_build_filename (cwd, "mkdir-test", NULL); +#ifdef G_OS_UNIX + have_cap_dac_override = check_cap_dac_override (cwd); +#endif + g_free (cwd); + + /* 0666 on directories means nothing to Windows, it only obeys ACLs. + * It doesn't necessarily mean anything on Unix either: if we have + * Linux CAP_DAC_OVERRIDE or equivalent (in particular if we're root), + * then we ignore filesystem permissions. */ +#ifdef G_OS_UNIX + if (have_cap_dac_override) + { + g_test_message ("Cannot test g_chdir() failing with EACCES: we " + "probably have CAP_DAC_OVERRIDE or equivalent"); + } + else + { + ret = g_chdir (path); + g_assert_cmpint (ret == 0 ? 0 : errno, ==, EACCES); + g_assert_cmpint (ret, ==, -1); + } +#else + g_test_message ("Cannot test g_chdir() failing with EACCES: " + "it's Unix-specific behaviour"); +#endif + + ret = g_chmod (path, 0777); + g_assert_cmpint (ret, ==, 0); + ret = g_chdir (path); + g_assert_cmpint (ret, ==, 0); + cwd = g_get_current_dir (); + /* We essentially want to check that cwd == path, but we can’t compare the + * paths directly since the tests might be running under a symlink (for + * example, /tmp is sometimes a symlink). Compare the inode numbers instead. */ + g_assert_cmpint (g_stat (cwd, &cwd_statbuf), ==, 0); + g_assert_cmpint (g_stat (path, &path_statbuf), ==, 0); + g_assert_true (cwd_statbuf.st_dev == path_statbuf.st_dev && + cwd_statbuf.st_ino == path_statbuf.st_ino); + g_free (cwd); + g_free (path); + + ret = g_creat ("test-creat", G_TEST_DIR_MODE); + g_close (ret, &error); + g_assert_no_error (error); + + ret = g_access ("test-creat", F_OK); + g_assert_cmpint (ret, ==, 0); + + ret = g_rename ("test-creat", "test-create"); + g_assert_cmpint (ret, ==, 0); + + ret = g_open ("test-create", O_RDONLY, 0666); + g_close (ret, &error); + g_assert_no_error (error); + +#ifdef G_OS_WIN32 + /* On Windows the 5 permission bit results in a read-only file + * that cannot be modified in any way (attribute changes included). + * Remove the read-only attribute via chmod(). + */ + ret = g_chmod ("test-create", 0666); + g_assert_cmpint (ret, ==, 0); +#endif + + now = time (NULL); + + ut.actime = ut.modtime = now; + ret = g_utime ("test-create", &ut); + g_assert_cmpint (ret, ==, 0); + + ret = g_lstat ("test-create", &buf); + g_assert_cmpint (ret, ==, 0); + g_assert_cmpint (buf.st_atime, ==, now); + g_assert_cmpint (buf.st_mtime, ==, now); + + g_chdir (".."); + g_remove ("mkdir-test/test-create"); + g_rmdir ("mkdir-test"); +} + +/* Win32 does not support "wb+", but g_fopen() should automatically + * translate this mode to its alias "w+b". + * Also check various other file open modes for correct support across + * platforms. + * See: https://gitlab.gnome.org/GNOME/glib/merge_requests/119 + */ +static void +test_fopen_modes (void) +{ + char *path = g_build_filename ("temp-fopen", NULL); + gsize i; + const gchar *modes[] = + { + "w", + "r", + "a", + "w+", + "r+", + "a+", + "wb", + "rb", + "ab", + "w+b", + "r+b", + "a+b", + "wb+", + "rb+", + "ab+" + }; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/merge_requests/119"); + + if (g_file_test (path, G_FILE_TEST_EXISTS)) + g_error ("failed, %s exists, cannot test g_fopen()", path); + + for (i = 0; i < G_N_ELEMENTS (modes); i++) + { + FILE *f; + + g_test_message ("Testing fopen() mode '%s'", modes[i]); + + f = g_fopen (path, modes[i]); + g_assert_nonnull (f); + fclose (f); + } + + g_remove (path); + g_free (path); +} + +#ifdef G_OS_WIN32 +#include "../gstdio-private.c" + +static int +g_wcscmp0 (const gunichar2 *str1, + const gunichar2 *str2) +{ + if (!str1) + return -(str1 != str2); + if (!str2) + return str1 != str2; + return wcscmp (str1, str2); +} + +#define g_assert_cmpwcs(s1, cmp, s2, s1u8, s2u8) \ +G_STMT_START { \ + const gunichar2 *__s1 = (s1), *__s2 = (s2); \ + if (g_wcscmp0 (__s1, __s2) cmp 0) ; else \ + g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #s1u8 " " #cmp " " #s2u8, s1u8, #cmp, s2u8); \ +} G_STMT_END + +static void +test_win32_pathstrip (void) +{ + gunichar2 *buf; + gsize i; +#define IDENTITY_TEST(x) { x, x, FALSE } + struct + { + gunichar2 *in; + gunichar2 *out; + gboolean result; + } testcases[] = { + IDENTITY_TEST (L"\\\\?\\V"), + IDENTITY_TEST (L"\\\\?\\Vo"), + IDENTITY_TEST (L"\\\\?\\Volume{0700f3d3-6d24-11e3-8b2f-806e6f6e6963}\\"), + IDENTITY_TEST (L"\\??\\V"), + IDENTITY_TEST (L"\\??\\Vo"), + IDENTITY_TEST (L"\\??\\Volume{0700f3d3-6d24-11e3-8b2f-806e6f6e6963}\\"), + IDENTITY_TEST (L"\\\\?\\\x0441:\\"), + IDENTITY_TEST (L"\\??\\\x0441:\\"), + IDENTITY_TEST (L"a:\\"), + IDENTITY_TEST (L"a:\\b\\c"), + IDENTITY_TEST (L"x"), +#undef IDENTITY_TEST + { + L"\\\\?\\c:\\", + L"c:\\", + TRUE, + }, + { + L"\\\\?\\C:\\", + L"C:\\", + TRUE, + }, + { + L"\\\\?\\c:\\", + L"c:\\", + TRUE, + }, + { + L"\\\\?\\C:\\", + L"C:\\", + TRUE, + }, + { + L"\\\\?\\C:\\", + L"C:\\", + TRUE, + }, + { 0, } + }; + + for (i = 0; testcases[i].in; i++) + { + gsize str_len = wcslen (testcases[i].in) + 1; + gchar *in_u8 = g_utf16_to_utf8 (testcases[i].in, -1, NULL, NULL, NULL); + gchar *out_u8 = g_utf16_to_utf8 (testcases[i].out, -1, NULL, NULL, NULL); + + g_assert_nonnull (in_u8); + g_assert_nonnull (out_u8); + + buf = g_new0 (gunichar2, str_len); + memcpy (buf, testcases[i].in, str_len * sizeof (gunichar2)); + _g_win32_strip_extended_ntobjm_prefix (buf, &str_len); + g_assert_cmpwcs (buf, ==, testcases[i].out, in_u8, out_u8); + g_free (buf); + g_free (in_u8); + g_free (out_u8); + } + /* Check for correct behaviour on non-NUL-terminated strings */ + for (i = 0; testcases[i].in; i++) + { + gsize str_len = wcslen (testcases[i].in) + 1; + wchar_t old_endchar; + gchar *in_u8 = g_utf16_to_utf8 (testcases[i].in, -1, NULL, NULL, NULL); + gchar *out_u8 = g_utf16_to_utf8 (testcases[i].out, -1, NULL, NULL, NULL); + + g_assert_nonnull (in_u8); + g_assert_nonnull (out_u8); + + buf = g_new0 (gunichar2, str_len); + memcpy (buf, testcases[i].in, (str_len) * sizeof (gunichar2)); + + old_endchar = buf[wcslen (testcases[i].out)]; + str_len -= 1; + + if (testcases[i].result) + { + /* Given "\\\\?\\C:\\" (len 7, unterminated), + * we should get "C:\\" (len 3, unterminated). + * Put a character different from "\\" (4-th character of the buffer) + * at the end of the unterminated source buffer, into a position + * where NUL-terminator would normally be. Then later test that 4-th character + * in the buffer is still the old "\\". + * After that terminate the string and use normal g_wcscmp0(). + */ + buf[str_len] = old_endchar - 1; + } + + _g_win32_strip_extended_ntobjm_prefix (buf, &str_len); + g_assert_cmpuint (old_endchar, ==, buf[wcslen (testcases[i].out)]); + buf[str_len] = L'\0'; + g_assert_cmpwcs (buf, ==, testcases[i].out, in_u8, out_u8); + g_free (buf); + g_free (in_u8); + g_free (out_u8); + } +} + +#define g_assert_memcmp(m1, cmp, m2, memlen, m1hex, m2hex, testcase_num) \ +G_STMT_START { \ + if (memcmp (m1, m2, memlen) cmp 0); else \ + g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #m1hex " " #cmp " " #m2hex, m1hex, #cmp, m2hex); \ +} G_STMT_END + +static gchar * +to_hex (const guchar *buf, + gsize len) +{ + gsize i; + GString *s = g_string_new (NULL); + if (len > 0) + g_string_append_printf (s, "%02x", buf[0]); + for (i = 1; i < len; i++) + g_string_append_printf (s, " %02x", buf[i]); + return g_string_free (s, FALSE); +} + +static void +test_win32_zero_terminate_symlink (void) +{ + gsize i; +#define TESTCASE(data, len_mod, use_buf, buf_size, terminate, reported_len, returned_string) \ + { (const guchar *) data, wcslen (data) * 2 + len_mod, use_buf, buf_size, terminate, reported_len, (guchar *) returned_string}, + + struct + { + const guchar *data; + gsize data_size; + gboolean use_buf; + gsize buf_size; + gboolean terminate; + int reported_len; + const guchar *returned_string; + } testcases[] = { + TESTCASE (L"foobar", +2, TRUE, 12 + 4, FALSE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 + 3, FALSE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 + 2, FALSE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 + 1, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 + 0, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0") + TESTCASE (L"foobar", +2, TRUE, 12 - 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", +2, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", +2, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a") + TESTCASE (L"foobar", +1, TRUE, 12 + 4, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 3, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 2, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 1, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 0, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0") + TESTCASE (L"foobar", +1, TRUE, 12 - 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", +1, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", +1, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a") + TESTCASE (L"foobar", +0, TRUE, 12 + 4, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 3, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 2, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 1, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 0, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0") + TESTCASE (L"foobar", +0, TRUE, 12 - 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", +0, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", +0, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a") + TESTCASE (L"foobar", -1, TRUE, 12 + 3, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", -1, TRUE, 12 + 2, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", -1, TRUE, 12 + 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", -1, TRUE, 12 + 0, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", -1, TRUE, 12 - 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", -1, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", -1, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a") + TESTCASE (L"foobar", -1, TRUE, 12 - 4, FALSE, 12 - 4, "f\0o\0o\0b\0") + TESTCASE (L"foobar", -2, TRUE, 12 + 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", -2, TRUE, 12 + 1, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", -2, TRUE, 12 + 0, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 1, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a") + TESTCASE (L"foobar", -2, TRUE, 12 - 4, FALSE, 12 - 4, "f\0o\0o\0b\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 5, FALSE, 12 - 5, "f\0o\0o\0b") + TESTCASE (L"foobar", +2, TRUE, 12 + 4, TRUE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 + 3, TRUE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 + 2, TRUE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 + 1, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 + 0, TRUE, 12 + 0, "f\0o\0o\0b\0a\0\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0") + TESTCASE (L"foobar", +2, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 4, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 3, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 2, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 1, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 + 0, TRUE, 12 + 0, "f\0o\0o\0b\0a\0\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0") + TESTCASE (L"foobar", +1, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 4, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 3, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 2, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 1, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +0, TRUE, 12 + 0, TRUE, 12 + 0, "f\0o\0o\0b\0a\0\0\0") + TESTCASE (L"foobar", +0, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"foobar", +0, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0") + TESTCASE (L"foobar", +0, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0") + TESTCASE (L"foobar", -1, TRUE, 12 + 3, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", -1, TRUE, 12 + 2, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", -1, TRUE, 12 + 1, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", -1, TRUE, 12 + 0, TRUE, 12 + 0, "f\0o\0o\0b\0a\0\0\0") + TESTCASE (L"foobar", -1, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"foobar", -1, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0") + TESTCASE (L"foobar", -1, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0") + TESTCASE (L"foobar", -1, TRUE, 12 - 4, TRUE, 12 - 4, "f\0o\0o\0\0\0") + TESTCASE (L"foobar", -2, TRUE, 12 + 2, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"foobar", -2, TRUE, 12 + 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"foobar", -2, TRUE, 12 + 0, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 4, TRUE, 12 - 4, "f\0o\0o\0\0\0") + TESTCASE (L"foobar", -2, TRUE, 12 - 5, TRUE, 12 - 5, "f\0o\0o\0\0") + TESTCASE (L"foobar", +2, FALSE, 0, FALSE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0") + TESTCASE (L"foobar", +1, FALSE, 0, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +0, FALSE, 0, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0") + TESTCASE (L"foobar", -1, FALSE, 0, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r") + TESTCASE (L"foobar", -2, FALSE, 0, FALSE, 12 - 2, "f\0o\0o\0b\0a\0") + TESTCASE (L"foobar", +2, FALSE, 0, TRUE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0") + TESTCASE (L"foobar", +1, FALSE, 0, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", +0, FALSE, 0, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", -1, FALSE, 0, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0") + TESTCASE (L"foobar", -2, FALSE, 0, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 4, FALSE, 2 + 2, "x\0\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 3, FALSE, 2 + 2, "x\0\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 2, FALSE, 2 + 2, "x\0\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 1, FALSE, 2 + 1, "x\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 0, FALSE, 2 + 0, "x\0") + TESTCASE (L"x", +2, TRUE, 2 - 1, FALSE, 2 - 1, "x") + TESTCASE (L"x", +2, TRUE, 2 - 2, FALSE, 2 - 2, "") + TESTCASE (L"x", +1, TRUE, 2 + 3, FALSE, 2 + 1, "x\0\0") + TESTCASE (L"x", +1, TRUE, 2 + 2, FALSE, 2 + 1, "x\0\0") + TESTCASE (L"x", +1, TRUE, 2 + 1, FALSE, 2 + 1, "x\0\0") + TESTCASE (L"x", +1, TRUE, 2 + 0, FALSE, 2 + 0, "x\0") + TESTCASE (L"x", +1, TRUE, 2 - 1, FALSE, 2 - 1, "x") + TESTCASE (L"x", +1, TRUE, 2 - 2, FALSE, 2 - 2, "") + TESTCASE (L"x", +0, TRUE, 2 + 2, FALSE, 2 + 0, "x\0") + TESTCASE (L"x", +0, TRUE, 2 + 1, FALSE, 2 + 0, "x\0") + TESTCASE (L"x", +0, TRUE, 2 + 0, FALSE, 2 + 0, "x\0") + TESTCASE (L"x", +0, TRUE, 2 - 1, FALSE, 2 - 1, "x") + TESTCASE (L"x", +0, TRUE, 2 - 2, FALSE, 2 - 2, "") + TESTCASE (L"x", -1, TRUE, 2 + 1, FALSE, 2 - 1, "x") + TESTCASE (L"x", -1, TRUE, 2 + 0, FALSE, 2 - 1, "x") + TESTCASE (L"x", -1, TRUE, 2 - 1, FALSE, 2 - 1, "x") + TESTCASE (L"x", -1, TRUE, 2 - 2, FALSE, 2 - 2, "") + TESTCASE (L"x", -2, TRUE, 2 + 0, FALSE, 2 - 2, "") + TESTCASE (L"x", -2, TRUE, 2 - 1, FALSE, 2 - 2, "") + TESTCASE (L"x", -2, TRUE, 2 - 2, FALSE, 2 - 2, "") + TESTCASE (L"x", +2, TRUE, 2 + 4, TRUE, 2 + 2, "x\0\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 3, TRUE, 2 + 2, "x\0\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 2, TRUE, 2 + 2, "x\0\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 1, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", +2, TRUE, 2 + 0, TRUE, 2 + 0, "\0\0") + TESTCASE (L"x", +2, TRUE, 2 - 1, TRUE, 2 - 1, "\0") + TESTCASE (L"x", +2, TRUE, 2 - 2, TRUE, 2 - 2, "") + TESTCASE (L"x", +1, TRUE, 2 + 3, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", +1, TRUE, 2 + 2, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", +1, TRUE, 2 + 1, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", +1, TRUE, 2 + 0, TRUE, 2 + 0, "\0\0") + TESTCASE (L"x", +1, TRUE, 2 - 1, TRUE, 2 - 1, "\0") + TESTCASE (L"x", +1, TRUE, 2 - 2, TRUE, 2 - 2, "") + TESTCASE (L"x", +0, TRUE, 2 + 2, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", +0, TRUE, 2 + 1, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", +0, TRUE, 2 + 0, TRUE, 2 + 0, "\0\0") + TESTCASE (L"x", +0, TRUE, 2 - 1, TRUE, 2 - 1, "\0") + TESTCASE (L"x", +0, TRUE, 2 - 2, TRUE, 2 - 2, "") + TESTCASE (L"x", -1, TRUE, 2 + 1, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", -1, TRUE, 2 + 0, TRUE, 2 + 0, "\0\0") + TESTCASE (L"x", -1, TRUE, 2 - 1, TRUE, 2 - 1, "\0") + TESTCASE (L"x", -1, TRUE, 2 - 2, TRUE, 2 - 2, "") + TESTCASE (L"x", -2, TRUE, 2 + 0, TRUE, 2 - 2, "") + TESTCASE (L"x", -2, TRUE, 2 - 1, TRUE, 2 - 2, "") + TESTCASE (L"x", -2, TRUE, 2 - 2, TRUE, 2 - 2, "") + TESTCASE (L"x", +2, FALSE, 0, FALSE, 2 + 2, "x\0\0\0") + TESTCASE (L"x", +1, FALSE, 0, FALSE, 2 + 1, "x\0\0") + TESTCASE (L"x", +0, FALSE, 0, FALSE, 2 + 0, "x\0") + TESTCASE (L"x", -1, FALSE, 0, FALSE, 2 - 1, "x") + TESTCASE (L"x", -2, FALSE, 0, FALSE, 2 - 2, "") + TESTCASE (L"x", +2, FALSE, 0, TRUE, 2 + 2, "x\0\0\0") + TESTCASE (L"x", +1, FALSE, 0, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", +0, FALSE, 0, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", -1, FALSE, 0, TRUE, 2 + 1, "x\0\0") + TESTCASE (L"x", -2, FALSE, 0, TRUE, 2 - 2, "") + { 0, }, + }; +#undef TESTCASE + + for (i = 0; testcases[i].data != NULL; i++) + { + gunichar2 *buf; + int result; + gchar *buf_hex, *expected_hex; + if (testcases[i].use_buf) + buf = g_malloc0 (testcases[i].buf_size + 1); /* +1 to ensure it succeeds with buf_size == 0 */ + else + buf = NULL; + result = _g_win32_copy_and_maybe_terminate (testcases[i].data, + testcases[i].data_size, + testcases[i].use_buf ? buf : NULL, + testcases[i].buf_size, + testcases[i].use_buf ? NULL : &buf, + testcases[i].terminate); + if (testcases[i].reported_len != result) + g_error ("Test %" G_GSIZE_FORMAT " failed, result %d != %d", i, result, testcases[i].reported_len); + if (buf == NULL && testcases[i].buf_size != 0) + g_error ("Test %" G_GSIZE_FORMAT " failed, buf == NULL", i); + g_assert_cmpint (testcases[i].reported_len, ==, result); + if ((testcases[i].use_buf && testcases[i].buf_size != 0) || + (!testcases[i].use_buf && testcases[i].reported_len != 0)) + { + g_assert_nonnull (buf); + buf_hex = to_hex ((const guchar *) buf, result); + expected_hex = to_hex (testcases[i].returned_string, testcases[i].reported_len); + if (memcmp (buf, testcases[i].returned_string, result) != 0) + g_error ("Test %" G_GSIZE_FORMAT " failed:\n%s !=\n%s", i, buf_hex, expected_hex); + g_assert_memcmp (buf, ==, testcases[i].returned_string, testcases[i].reported_len, buf_hex, expected_hex, testcases[i].line); + g_free (buf_hex); + g_free (expected_hex); + } + g_free (buf); + } +} + +#endif + +int +main (int argc, + char *argv[]) +{ + g_setenv ("LC_ALL", "C", TRUE); + g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); + +#ifdef G_OS_WIN32 + g_test_add_func ("/fileutils/stdio-win32-pathstrip", test_win32_pathstrip); + g_test_add_func ("/fileutils/stdio-win32-zero-terminate-symlink", test_win32_zero_terminate_symlink); +#endif + g_test_add_func ("/fileutils/paths", test_paths); + g_test_add_func ("/fileutils/build-path", test_build_path); + g_test_add_func ("/fileutils/build-pathv", test_build_pathv); + g_test_add_func ("/fileutils/build-filename", test_build_filename); + g_test_add_func ("/fileutils/build-filenamev", test_build_filenamev); + g_test_add_func ("/fileutils/mkdir-with-parents", test_mkdir_with_parents); + g_test_add_func ("/fileutils/mkdir-with-parents-permission", test_mkdir_with_parents_permission); + g_test_add_func ("/fileutils/format-size-for-display", test_format_size_for_display); + g_test_add_func ("/fileutils/errors", test_file_errors); + g_test_add_func ("/fileutils/basename", test_basename); + g_test_add_func ("/fileutils/get-basename", test_get_basename); + g_test_add_func ("/fileutils/dirname", test_dirname); + g_test_add_func ("/fileutils/dir-make-tmp", test_dir_make_tmp); + g_test_add_func ("/fileutils/file-open-tmp", test_file_open_tmp); + g_test_add_func ("/fileutils/file-test", test_file_test); + g_test_add_func ("/fileutils/mkstemp", test_mkstemp); + g_test_add_func ("/fileutils/mkdtemp", test_mkdtemp); + g_test_add_func ("/fileutils/get-contents", test_get_contents); + g_test_add_func ("/fileutils/set-contents", test_set_contents); + g_test_add_func ("/fileutils/set-contents-full", test_set_contents_full); + g_test_add_func ("/fileutils/set-contents-full/read-only-file", test_set_contents_full_read_only_file); + g_test_add_func ("/fileutils/set-contents-full/read-only-directory", test_set_contents_full_read_only_directory); + g_test_add_func ("/fileutils/read-link", test_read_link); + g_test_add_func ("/fileutils/stdio-wrappers", test_stdio_wrappers); + g_test_add_func ("/fileutils/fopen-modes", test_fopen_modes); + + return g_test_run (); +} diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c new file mode 100644 index 0000000..141263b --- /dev/null +++ b/glib/tests/gdatetime.c @@ -0,0 +1,3193 @@ +/* gdatetime-tests.c + * + * Copyright (C) 2009-2010 Christian Hergert + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef G_OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include + +#ifndef NAN +#define NAN HUGE_VAL * 0.0f +#endif +#endif + +#define ASSERT_DATE(dt,y,m,d) G_STMT_START { \ + g_assert_nonnull ((dt)); \ + g_assert_cmpint ((y), ==, g_date_time_get_year ((dt))); \ + g_assert_cmpint ((m), ==, g_date_time_get_month ((dt))); \ + g_assert_cmpint ((d), ==, g_date_time_get_day_of_month ((dt))); \ +} G_STMT_END +#define ASSERT_TIME(dt,H,M,S,U) G_STMT_START { \ + g_assert_nonnull ((dt)); \ + g_assert_cmpint ((H), ==, g_date_time_get_hour ((dt))); \ + g_assert_cmpint ((M), ==, g_date_time_get_minute ((dt))); \ + g_assert_cmpint ((S), ==, g_date_time_get_second ((dt))); \ + g_assert_cmpint ((U), ==, g_date_time_get_microsecond ((dt))); \ +} G_STMT_END + +static gboolean +skip_if_running_uninstalled (void) +{ + /* If running uninstalled (G_TEST_BUILDDIR is set), skip this test, since we + * need the translations to be installed. We can’t mess around with + * bindtextdomain() here, as the compiled .gmo files in po/ are not in the + * right installed directory hierarchy to be successfully loaded by gettext. */ + if (g_getenv ("G_TEST_BUILDDIR") != NULL) + { + g_test_skip ("Skipping due to running uninstalled. " + "This test can only be run when the translations are installed."); + return TRUE; + } + + return FALSE; +} + +static void +get_localtime_tm (time_t time_, + struct tm *retval) +{ +#ifdef HAVE_LOCALTIME_R + localtime_r (&time_, retval); +#else + { + struct tm *ptm = localtime (&time_); + + if (ptm == NULL) + { + /* Happens at least in Microsoft's C library if you pass a + * negative time_t. Use 2000-01-01 as default date. + */ +#ifndef G_DISABLE_CHECKS + g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, "ptm != NULL"); +#endif + + retval->tm_mon = 0; + retval->tm_mday = 1; + retval->tm_year = 100; + } + else + memcpy ((void *) retval, (void *) ptm, sizeof (struct tm)); + } +#endif /* HAVE_LOCALTIME_R */ +} + +static void +test_GDateTime_now (void) +{ + GDateTime *dt; + struct tm tm; + time_t before; + time_t after; + + /* before <= dt.to_unix() <= after, but the inequalities might not be + * equality if we're close to the boundary between seconds. + * We loop until before == after (and hence dt.to_unix() should equal both) + * to guard against that. */ + do + { + before = g_get_real_time () / G_TIME_SPAN_SECOND; + + memset (&tm, 0, sizeof (tm)); + get_localtime_tm (before, &tm); + + dt = g_date_time_new_now_local (); + + after = g_get_real_time () / G_TIME_SPAN_SECOND; + } + while (before != after); + + g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year); + g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon); + g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, tm.tm_mday); + g_assert_cmpint (g_date_time_get_hour (dt), ==, tm.tm_hour); + g_assert_cmpint (g_date_time_get_minute (dt), ==, tm.tm_min); + g_assert_cmpint (g_date_time_get_second (dt), ==, tm.tm_sec); + + g_date_time_unref (dt); +} + +static void +test_GDateTime_new_from_unix (void) +{ + GDateTime *dt; + struct tm tm; + time_t t; + + memset (&tm, 0, sizeof (tm)); + t = time (NULL); + g_assert_cmpint (t, !=, (time_t) -1); + get_localtime_tm (t, &tm); + + dt = g_date_time_new_from_unix_local (t); + g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year); + g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon); + g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, tm.tm_mday); + g_assert_cmpint (g_date_time_get_hour (dt), ==, tm.tm_hour); + g_assert_cmpint (g_date_time_get_minute (dt), ==, tm.tm_min); + g_assert_cmpint (g_date_time_get_second (dt), ==, tm.tm_sec); + g_date_time_unref (dt); + + /* Choose 1990-01-01 04:00:00 because no DST leaps happened then. The more + * obvious 1990-01-01 00:00:00 was a DST leap in America/Lima (which has, + * confusingly, since stopped using DST). */ + memset (&tm, 0, sizeof (tm)); + tm.tm_year = 90; + tm.tm_mday = 1; + tm.tm_mon = 0; + tm.tm_hour = 4; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_isdst = -1; + t = mktime (&tm); + + dt = g_date_time_new_from_unix_local (t); + g_assert_cmpint (g_date_time_get_year (dt), ==, 1990); + g_assert_cmpint (g_date_time_get_month (dt), ==, 1); + g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 1); + g_assert_cmpint (g_date_time_get_hour (dt), ==, 4); + g_assert_cmpint (g_date_time_get_minute (dt), ==, 0); + g_assert_cmpint (g_date_time_get_second (dt), ==, 0); + g_date_time_unref (dt); +} + +/* Check that trying to create a #GDateTime too far in the future (or past) reliably + * fails. Previously, the checks for this overflowed and it silently returned + * an incorrect #GDateTime. */ +static void +test_GDateTime_new_from_unix_overflow (void) +{ + GDateTime *dt; + + g_test_bug ("http://bugzilla.gnome.org/782089"); + + dt = g_date_time_new_from_unix_utc (G_MAXINT64); + g_assert_null (dt); + + dt = g_date_time_new_from_unix_local (G_MAXINT64); + g_assert_null (dt); + + dt = g_date_time_new_from_unix_utc (G_MININT64); + g_assert_null (dt); + + dt = g_date_time_new_from_unix_local (G_MININT64); + g_assert_null (dt); +} + +static void +test_GDateTime_invalid (void) +{ + GDateTime *dt; + + g_test_bug ("http://bugzilla.gnome.org/702674"); + + dt = g_date_time_new_utc (2013, -2147483647, 31, 17, 15, 48); + g_assert (dt == NULL); +} + +static void +test_GDateTime_compare (void) +{ + GDateTime *dt1, *dt2; + gint i; + + dt1 = g_date_time_new_utc (2000, 1, 1, 0, 0, 0); + + for (i = 1; i < 2000; i++) + { + dt2 = g_date_time_new_utc (i, 12, 31, 0, 0, 0); + g_assert_cmpint (1, ==, g_date_time_compare (dt1, dt2)); + g_date_time_unref (dt2); + } + + dt2 = g_date_time_new_utc (1999, 12, 31, 23, 59, 59); + g_assert_cmpint (1, ==, g_date_time_compare (dt1, dt2)); + g_date_time_unref (dt2); + + dt2 = g_date_time_new_utc (2000, 1, 1, 0, 0, 1); + g_assert_cmpint (-1, ==, g_date_time_compare (dt1, dt2)); + g_date_time_unref (dt2); + + dt2 = g_date_time_new_utc (2000, 1, 1, 0, 0, 0); + g_assert_cmpint (0, ==, g_date_time_compare (dt1, dt2)); + g_date_time_unref (dt2); + g_date_time_unref (dt1); +} + +static void +test_GDateTime_equal (void) +{ + GDateTime *dt1, *dt2; + GTimeZone *tz; + + dt1 = g_date_time_new_local (2009, 10, 19, 0, 0, 0); + dt2 = g_date_time_new_local (2009, 10, 19, 0, 0, 0); + g_assert (g_date_time_equal (dt1, dt2)); + g_date_time_unref (dt1); + g_date_time_unref (dt2); + + dt1 = g_date_time_new_local (2009, 10, 18, 0, 0, 0); + dt2 = g_date_time_new_local (2009, 10, 19, 0, 0, 0); + g_assert (!g_date_time_equal (dt1, dt2)); + g_date_time_unref (dt1); + g_date_time_unref (dt2); + + /* UTC-0300 and not in DST */ + tz = g_time_zone_new_identifier ("-03:00"); + g_assert_nonnull (tz); + dt1 = g_date_time_new (tz, 2010, 5, 24, 8, 0, 0); + g_time_zone_unref (tz); + g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600)); + /* UTC */ + dt2 = g_date_time_new_utc (2010, 5, 24, 11, 0, 0); + g_assert_cmpint (g_date_time_get_utc_offset (dt2), ==, 0); + + g_assert (g_date_time_equal (dt1, dt2)); + g_date_time_unref (dt1); + + /* America/Recife is in UTC-0300 */ +#ifdef G_OS_UNIX + tz = g_time_zone_new_identifier ("America/Recife"); +#elif defined G_OS_WIN32 + tz = g_time_zone_new_identifier ("E. South America Standard Time"); +#endif + g_assert_nonnull (tz); + dt1 = g_date_time_new (tz, 2010, 5, 24, 8, 0, 0); + g_time_zone_unref (tz); + g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600)); + g_assert (g_date_time_equal (dt1, dt2)); + g_date_time_unref (dt1); + g_date_time_unref (dt2); +} + +static void +test_GDateTime_get_day_of_week (void) +{ + GDateTime *dt; + + dt = g_date_time_new_local (2009, 10, 19, 0, 0, 0); + g_assert_cmpint (1, ==, g_date_time_get_day_of_week (dt)); + g_date_time_unref (dt); + + dt = g_date_time_new_local (2000, 10, 1, 0, 0, 0); + g_assert_cmpint (7, ==, g_date_time_get_day_of_week (dt)); + g_date_time_unref (dt); +} + +static void +test_GDateTime_get_day_of_month (void) +{ + GDateTime *dt; + + dt = g_date_time_new_local (2009, 10, 19, 0, 0, 0); + g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 19); + g_date_time_unref (dt); + + dt = g_date_time_new_local (1400, 3, 12, 0, 0, 0); + g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 12); + g_date_time_unref (dt); + + dt = g_date_time_new_local (1800, 12, 31, 0, 0, 0); + g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 31); + g_date_time_unref (dt); + + dt = g_date_time_new_local (1000, 1, 1, 0, 0, 0); + g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 1); + g_date_time_unref (dt); +} + +static void +test_GDateTime_get_hour (void) +{ + GDateTime *dt; + + dt = g_date_time_new_utc (2009, 10, 19, 15, 13, 11); + g_assert_cmpint (15, ==, g_date_time_get_hour (dt)); + g_date_time_unref (dt); + + dt = g_date_time_new_utc (100, 10, 19, 1, 0, 0); + g_assert_cmpint (1, ==, g_date_time_get_hour (dt)); + g_date_time_unref (dt); + + dt = g_date_time_new_utc (100, 10, 19, 0, 0, 0); + g_assert_cmpint (0, ==, g_date_time_get_hour (dt)); + g_date_time_unref (dt); + + dt = g_date_time_new_utc (100, 10, 1, 23, 59, 59); + g_assert_cmpint (23, ==, g_date_time_get_hour (dt)); + g_date_time_unref (dt); +} + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +static void +test_GDateTime_get_microsecond (void) +{ + GTimeVal tv; + GDateTime *dt; + + g_get_current_time (&tv); + dt = g_date_time_new_from_timeval_local (&tv); + g_assert_cmpint (tv.tv_usec, ==, g_date_time_get_microsecond (dt)); + g_date_time_unref (dt); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +static void +test_GDateTime_get_year (void) +{ + GDateTime *dt; + + dt = g_date_time_new_local (2009, 1, 1, 0, 0, 0); + g_assert_cmpint (2009, ==, g_date_time_get_year (dt)); + g_date_time_unref (dt); + + dt = g_date_time_new_local (1, 1, 1, 0, 0, 0); + g_assert_cmpint (1, ==, g_date_time_get_year (dt)); + g_date_time_unref (dt); + + dt = g_date_time_new_local (13, 1, 1, 0, 0, 0); + g_assert_cmpint (13, ==, g_date_time_get_year (dt)); + g_date_time_unref (dt); + + dt = g_date_time_new_local (3000, 1, 1, 0, 0, 0); + g_assert_cmpint (3000, ==, g_date_time_get_year (dt)); + g_date_time_unref (dt); +} + +static void +test_GDateTime_hash (void) +{ + GHashTable *h; + + h = g_hash_table_new_full (g_date_time_hash, g_date_time_equal, + (GDestroyNotify)g_date_time_unref, + NULL); + g_hash_table_add (h, g_date_time_new_now_local ()); + g_hash_table_remove_all (h); + g_hash_table_destroy (h); +} + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +static void +test_GDateTime_new_from_timeval (void) +{ + GDateTime *dt; + GTimeVal tv, tv2; + + g_get_current_time (&tv); + dt = g_date_time_new_from_timeval_local (&tv); + + if (g_test_verbose ()) + g_printerr ("\nDT%04d-%02d-%02dT%02d:%02d:%02d%s\n", + g_date_time_get_year (dt), + g_date_time_get_month (dt), + g_date_time_get_day_of_month (dt), + g_date_time_get_hour (dt), + g_date_time_get_minute (dt), + g_date_time_get_second (dt), + g_date_time_get_timezone_abbreviation (dt)); + + g_date_time_to_timeval (dt, &tv2); + g_assert_cmpint (tv.tv_sec, ==, tv2.tv_sec); + g_assert_cmpint (tv.tv_usec, ==, tv2.tv_usec); + g_date_time_unref (dt); +} + +static glong +find_maximum_supported_tv_sec (void) +{ + glong highest_success = 0, lowest_failure = G_MAXLONG; + GTimeVal tv; + GDateTime *dt = NULL; + + tv.tv_usec = 0; + + /* Corner case of all glong values being valid. */ + tv.tv_sec = G_MAXLONG; + dt = g_date_time_new_from_timeval_utc (&tv); + if (dt != NULL) + { + highest_success = tv.tv_sec; + g_date_time_unref (dt); + } + + while (highest_success < lowest_failure - 1) + { + tv.tv_sec = highest_success + (lowest_failure - highest_success) / 2; + dt = g_date_time_new_from_timeval_utc (&tv); + + if (dt != NULL) + { + highest_success = tv.tv_sec; + g_date_time_unref (dt); + } + else + { + lowest_failure = tv.tv_sec; + } + } + + return highest_success; +} + +/* Check that trying to create a #GDateTime too far in the future reliably + * fails. With a #GTimeVal, this is subtle, as the tv_usec are added into the + * calculation part-way through. + * + * This varies a bit between 32- and 64-bit architectures, due to the + * differences in the size of glong (tv.tv_sec). */ +static void +test_GDateTime_new_from_timeval_overflow (void) +{ + GDateTime *dt; + GTimeVal tv; + + g_test_bug ("http://bugzilla.gnome.org/782089"); + + tv.tv_sec = find_maximum_supported_tv_sec (); + tv.tv_usec = G_USEC_PER_SEC - 1; + + g_test_message ("Maximum supported GTimeVal.tv_sec = %lu", tv.tv_sec); + + /* Sanity check: do we support the year 2000? */ + g_assert_cmpint (tv.tv_sec, >=, 946684800); + + dt = g_date_time_new_from_timeval_utc (&tv); + g_assert_nonnull (dt); + g_date_time_unref (dt); + + if (tv.tv_sec < G_MAXLONG) + { + tv.tv_sec++; + tv.tv_usec = 0; + + dt = g_date_time_new_from_timeval_utc (&tv); + g_assert_null (dt); + } +} + +static void +test_GDateTime_new_from_timeval_utc (void) +{ + GDateTime *dt; + GTimeVal tv, tv2; + + g_get_current_time (&tv); + dt = g_date_time_new_from_timeval_utc (&tv); + + if (g_test_verbose ()) + g_printerr ("\nDT%04d-%02d-%02dT%02d:%02d:%02d%s\n", + g_date_time_get_year (dt), + g_date_time_get_month (dt), + g_date_time_get_day_of_month (dt), + g_date_time_get_hour (dt), + g_date_time_get_minute (dt), + g_date_time_get_second (dt), + g_date_time_get_timezone_abbreviation (dt)); + + g_date_time_to_timeval (dt, &tv2); + g_assert_cmpint (tv.tv_sec, ==, tv2.tv_sec); + g_assert_cmpint (tv.tv_usec, ==, tv2.tv_usec); + g_date_time_unref (dt); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +static void +test_GDateTime_new_from_iso8601 (void) +{ + GDateTime *dt; + GTimeZone *tz; + + /* Need non-empty string */ + dt = g_date_time_new_from_iso8601 ("", NULL); + g_assert_null (dt); + + /* Needs to be correctly formatted */ + dt = g_date_time_new_from_iso8601 ("not a date", NULL); + g_assert_null (dt); + + dt = g_date_time_new_from_iso8601 (" +55", NULL); + g_assert_null (dt); + + /* Check common case */ + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + + /* Timezone is required in text or passed as arg */ + tz = g_time_zone_new_utc (); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42", tz); + ASSERT_DATE (dt, 2016, 8, 24); + g_date_time_unref (dt); + g_time_zone_unref (tz); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42", NULL); + g_assert_null (dt); + + /* Can't have whitespace */ + dt = g_date_time_new_from_iso8601 ("2016 08 24T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42Z ", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 (" 2016-08-24T22:10:42Z", NULL); + g_assert_null (dt); + + /* Check lowercase time separator or space allowed */ + dt = g_date_time_new_from_iso8601 ("2016-08-24t22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24 22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + + /* Check dates without separators allowed */ + dt = g_date_time_new_from_iso8601 ("20160824T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + + /* Months are two digits */ + dt = g_date_time_new_from_iso8601 ("2016-1-01T22:10:42Z", NULL); + g_assert_null (dt); + + /* Days are two digits */ + dt = g_date_time_new_from_iso8601 ("2016-01-1T22:10:42Z", NULL); + g_assert_null (dt); + + /* Need consistent usage of separators */ + dt = g_date_time_new_from_iso8601 ("2016-0824T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("201608-24T22:10:42Z", NULL); + g_assert_null (dt); + + /* Check month within valid range */ + dt = g_date_time_new_from_iso8601 ("2016-00-13T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-13-13T22:10:42Z", NULL); + g_assert_null (dt); + + /* Check day within valid range */ + dt = g_date_time_new_from_iso8601 ("2016-01-00T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-01-31T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 1, 31); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-01-32T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-02-29T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 2, 29); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-02-30T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2017-02-28T22:10:42Z", NULL); + ASSERT_DATE (dt, 2017, 2, 28); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2017-02-29T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-03-31T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 3, 31); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-03-32T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-04-30T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 4, 30); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-04-31T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-05-31T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 5, 31); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-05-32T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-06-30T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 6, 30); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-06-31T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-07-31T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 7, 31); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-07-32T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-31T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 31); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-32T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-09-30T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 9, 30); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-09-31T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-10-31T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 10, 31); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-10-32T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-11-30T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 11, 30); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-11-31T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-12-31T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 12, 31); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-12-32T22:10:42Z", NULL); + g_assert_null (dt); + + /* Check ordinal days work */ + dt = g_date_time_new_from_iso8601 ("2016-237T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016237T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + + /* Check ordinal leap days */ + dt = g_date_time_new_from_iso8601 ("2016-366T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 12, 31); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2017-365T22:10:42Z", NULL); + ASSERT_DATE (dt, 2017, 12, 31); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2017-366T22:10:42Z", NULL); + g_assert_null (dt); + + /* Days start at 1 */ + dt = g_date_time_new_from_iso8601 ("2016-000T22:10:42Z", NULL); + g_assert_null (dt); + + /* Limited to number of days in the year (2016 is a leap year) */ + dt = g_date_time_new_from_iso8601 ("2016-367T22:10:42Z", NULL); + g_assert_null (dt); + + /* Days are two digits */ + dt = g_date_time_new_from_iso8601 ("2016-1T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-12T22:10:42Z", NULL); + g_assert_null (dt); + + /* Check week days work */ + dt = g_date_time_new_from_iso8601 ("2016-W34-3T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016W343T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_date_time_unref (dt); + + /* We don't support weeks without weekdays (valid ISO 8601) */ + dt = g_date_time_new_from_iso8601 ("2016-W34T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016W34T22:10:42Z", NULL); + g_assert_null (dt); + + /* Weeks are two digits */ + dt = g_date_time_new_from_iso8601 ("2016-W3-1T22:10:42Z", NULL); + g_assert_null (dt); + + /* Weeks start at 1 */ + dt = g_date_time_new_from_iso8601 ("2016-W00-1T22:10:42Z", NULL); + g_assert_null (dt); + + /* Week one might be in the previous year */ + dt = g_date_time_new_from_iso8601 ("2015-W01-1T22:10:42Z", NULL); + ASSERT_DATE (dt, 2014, 12, 29); + g_date_time_unref (dt); + + /* Last week might be in next year */ + dt = g_date_time_new_from_iso8601 ("2015-W53-7T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 1, 3); + g_date_time_unref (dt); + + /* Week 53 doesn't always exist */ + dt = g_date_time_new_from_iso8601 ("2016-W53-1T22:10:42Z", NULL); + g_assert_null (dt); + + /* Limited to number of days in the week */ + dt = g_date_time_new_from_iso8601 ("2016-W34-0T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-W34-8T22:10:42Z", NULL); + g_assert_null (dt); + + /* Days are one digit */ + dt = g_date_time_new_from_iso8601 ("2016-W34-99T22:10:42Z", NULL); + g_assert_null (dt); + + /* Check week day changes depending on year */ + dt = g_date_time_new_from_iso8601 ("2017-W34-1T22:10:42Z", NULL); + ASSERT_DATE (dt, 2017, 8, 21); + g_date_time_unref (dt); + + /* Check week day changes depending on leap years */ + dt = g_date_time_new_from_iso8601 ("1900-W01-1T22:10:42Z", NULL); + ASSERT_DATE (dt, 1900, 1, 1); + g_date_time_unref (dt); + + /* YYYY-MM not allowed (NOT valid ISO 8601) */ + dt = g_date_time_new_from_iso8601 ("2016-08T22:10:42Z", NULL); + g_assert_null (dt); + + /* We don't support omitted year (valid ISO 8601) */ + dt = g_date_time_new_from_iso8601 ("--08-24T22:10:42Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("--0824T22:10:42Z", NULL); + g_assert_null (dt); + + /* Seconds must be two digits. */ + dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:4Z", NULL); + g_assert_null (dt); + + /* Seconds must all be digits. */ + dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:4aZ", NULL); + g_assert_null (dt); + + /* Check subseconds work */ + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42.123456Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 123456); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42,123456Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 123456); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42.Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T221042.123456Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 123456); + g_date_time_unref (dt); + + /* Subseconds must all be digits. */ + dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:42.5aZ", NULL); + g_assert_null (dt); + + /* Subseconds can be an arbitrary length, but must not overflow. + * The ASSERT_TIME() comparisons are constrained by only comparing up to + * microsecond granularity. */ + dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:09.222222222222222222Z", NULL); + ASSERT_DATE (dt, 2016, 8, 10); + ASSERT_TIME (dt, 22, 10, 9, 222222); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:09.2222222222222222222Z", NULL); + g_assert_null (dt); + + /* Small numerator, large divisor when parsing the subseconds. */ + dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:00.0000000000000000001Z", NULL); + ASSERT_DATE (dt, 2016, 8, 10); + ASSERT_TIME (dt, 22, 10, 0, 0); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-10T22:10:00.00000000000000000001Z", NULL); + g_assert_null (dt); + + /* We don't support times without minutes / seconds (valid ISO 8601) */ + dt = g_date_time_new_from_iso8601 ("2016-08-24T22Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10Z", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T2210Z", NULL); + g_assert_null (dt); + + /* UTC time uses 'Z' */ + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42Z", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, 0); + g_date_time_unref (dt); + + /* Check timezone works */ + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42+12:00", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, 12 * G_TIME_SPAN_HOUR); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42+12", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, 12 * G_TIME_SPAN_HOUR); + g_date_time_unref (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22:10:42-02", NULL); + ASSERT_DATE (dt, 2016, 8, 24); + ASSERT_TIME (dt, 22, 10, 42, 0); + g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, -2 * G_TIME_SPAN_HOUR); + g_date_time_unref (dt); + + /* Timezone seconds not allowed */ + dt = g_date_time_new_from_iso8601 ("2016-08-24T22-12:00:00", NULL); + g_assert_null (dt); + dt = g_date_time_new_from_iso8601 ("2016-08-24T22-12:00:00.000", NULL); + g_assert_null (dt); + + /* Timezone hours two digits */ + dt = g_date_time_new_from_iso8601 ("2016-08-24T22-2Z", NULL); + g_assert_null (dt); + + /* Ordinal date (YYYYDDD), space separator, and then time as HHMMSS,SSS + * The interesting bit is that the seconds field is so long as to parse as + * NaN */ + dt = g_date_time_new_from_iso8601 ("0005306 000001,666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666600080000-00", NULL); + g_assert_null (dt); +} + +typedef struct { + gboolean success; + const gchar *in; + + /* Expected result: */ + guint year; + guint month; + guint day; + guint hour; + guint minute; + guint second; + guint microsecond; + GTimeSpan utc_offset; +} Iso8601ParseTest; + +static void +test_GDateTime_new_from_iso8601_2 (void) +{ + const Iso8601ParseTest tests[] = { + { TRUE, "1990-11-01T10:21:17Z", 1990, 11, 1, 10, 21, 17, 0, 0 }, + { TRUE, "19901101T102117Z", 1990, 11, 1, 10, 21, 17, 0, 0 }, + { TRUE, "1970-01-01T00:00:17.12Z", 1970, 1, 1, 0, 0, 17, 120000, 0 }, + { TRUE, "1970-01-01T00:00:17.1234Z", 1970, 1, 1, 0, 0, 17, 123400, 0 }, + { TRUE, "1970-01-01T00:00:17.123456Z", 1970, 1, 1, 0, 0, 17, 123456, 0 }, + { TRUE, "1980-02-22T12:36:00+02:00", 1980, 2, 22, 12, 36, 0, 0, 2 * G_TIME_SPAN_HOUR }, + { TRUE, "1990-12-31T15:59:60-08:00", 1990, 12, 31, 15, 59, 59, 0, -8 * G_TIME_SPAN_HOUR }, + { FALSE, " ", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "x", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "123x", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2001-10+x", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "1980-02-22T", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2001-10-08Tx", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2001-10-08T10:11x", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "Wed Dec 19 17:20:20 GMT 2007", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "1980-02-22T10:36:00Zulu", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2T0+819855292164632335", 0, 0, 0, 0, 0, 0, 0, 0 }, + { TRUE, "2018-08-03T14:08:05.446178377+01:00", 2018, 8, 3, 14, 8, 5, 446178, 1 * G_TIME_SPAN_HOUR }, + { FALSE, "2147483648-08-03T14:08:05.446178377+01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-13-03T14:08:05.446178377+01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-00-03T14:08:05.446178377+01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-08-00T14:08:05.446178377+01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-08-32T14:08:05.446178377+01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-08-03T24:08:05.446178377+01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-08-03T14:60:05.446178377+01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-08-03T14:08:63.446178377+01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-08-03T14:08:05.446178377+100:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { TRUE, "20180803T140805.446178377+0100", 2018, 8, 3, 14, 8, 5, 446178, 1 * G_TIME_SPAN_HOUR }, + { FALSE, "21474836480803T140805.446178377+0100", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20181303T140805.446178377+0100", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20180003T140805.446178377+0100", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20180800T140805.446178377+0100", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20180832T140805.446178377+0100", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20180803T240805.446178377+0100", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20180803T146005.446178377+0100", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20180803T140863.446178377+0100", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20180803T140805.446178377+10000", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "-0005-01-01T00:00:00Z", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "2018-08-06", 0, 0, 0, 0, 0, 0, 0, 0 }, + /* This is not accepted by g_time_val_from_iso8601(), but is accepted by g_date_time_new_from_iso8601(): + { FALSE, "2018-08-06 13:51:00Z", 0, 0, 0, 0, 0, 0, 0, 0 }, + * */ + { TRUE, "20180803T140805,446178377+0100", 2018, 8, 3, 14, 8, 5, 446178, 1 * G_TIME_SPAN_HOUR }, + { TRUE, "2018-08-03T14:08:05.446178377-01:00", 2018, 8, 3, 14, 8, 5, 446178, -1 * G_TIME_SPAN_HOUR }, + { FALSE, "2018-08-03T14:08:05.446178377 01:00", 0, 0, 0, 0, 0, 0, 0, 0 }, + { TRUE, "1990-11-01T10:21:17", 1990, 11, 1, 10, 21, 17, 0, 0 }, + /* These are accepted by g_time_val_from_iso8601(), but not by g_date_time_new_from_iso8601(): + { TRUE, "19901101T102117+5", 1990, 11, 1, 10, 21, 17, 0, 5 * G_TIME_SPAN_HOUR }, + { TRUE, "19901101T102117+3:15", 1990, 11, 1, 10, 21, 17, 0, 3 * G_TIME_SPAN_HOUR + 15 * G_TIME_SPAN_MINUTE }, + { TRUE, " 1990-11-01T10:21:17Z ", 1990, 11, 1, 10, 21, 17, 0, 0 }, + { FALSE, "2018-08-03T14:08:05.446178377+01:60", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "20180803T140805.446178377+0160", 0, 0, 0, 0, 0, 0, 0, 0 }, + { TRUE, "+1980-02-22T12:36:00+02:00", 1980, 2, 22, 12, 36, 0, 0, 2 * G_TIME_SPAN_HOUR }, + { TRUE, "1990-11-01T10:21:17 ", 1990, 11, 1, 10, 21, 17, 0, 0 }, + */ + { FALSE, "1719W462 407777-07", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "4011090 260528Z", 0, 0, 0, 0, 0, 0, 0, 0 }, + { FALSE, "0000W011 228214-22", 0, 0, 0, 0, 0, 0, 0, 0 }, + }; + GTimeZone *tz = NULL; + GDateTime *dt = NULL; + gsize i; + + g_test_summary ("Further parser tests for g_date_time_new_from_iso8601(), " + "checking success and failure using test vectors."); + + tz = g_time_zone_new_utc (); + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + g_test_message ("Vector %" G_GSIZE_FORMAT ": %s", i, tests[i].in); + + dt = g_date_time_new_from_iso8601 (tests[i].in, tz); + if (tests[i].success) + { + g_assert_nonnull (dt); + ASSERT_DATE (dt, tests[i].year, tests[i].month, tests[i].day); + ASSERT_TIME (dt, tests[i].hour, tests[i].minute, tests[i].second, tests[i].microsecond); + g_assert_cmpint (g_date_time_get_utc_offset (dt), ==, tests[i].utc_offset); + } + else + { + g_assert_null (dt); + } + + g_clear_pointer (&dt, g_date_time_unref); + } + + g_time_zone_unref (tz); +} + +static void +test_GDateTime_to_unix (void) +{ + GDateTime *dt; + time_t t; + + t = time (NULL); + g_assert_cmpint (t, !=, (time_t) -1); + dt = g_date_time_new_from_unix_local (t); + g_assert_cmpint (g_date_time_to_unix (dt), ==, t); + g_date_time_unref (dt); +} + +static void +test_GDateTime_add_years (void) +{ + GDateTime *dt, *dt2; + + dt = g_date_time_new_local (2009, 10, 19, 0, 0, 0); + dt2 = g_date_time_add_years (dt, 1); + g_assert_cmpint (2010, ==, g_date_time_get_year (dt2)); + g_date_time_unref (dt); + g_date_time_unref (dt2); +} + +static void +test_GDateTime_add_months (void) +{ +#define TEST_ADD_MONTHS(y,m,d,a,ny,nm,nd) G_STMT_START { \ + GDateTime *dt, *dt2; \ + dt = g_date_time_new_utc (y, m, d, 0, 0, 0); \ + dt2 = g_date_time_add_months (dt, a); \ + ASSERT_DATE (dt2, ny, nm, nd); \ + g_date_time_unref (dt); \ + g_date_time_unref (dt2); \ +} G_STMT_END + + TEST_ADD_MONTHS (2009, 12, 31, 1, 2010, 1, 31); + TEST_ADD_MONTHS (2009, 12, 31, 1, 2010, 1, 31); + TEST_ADD_MONTHS (2009, 6, 15, 1, 2009, 7, 15); + TEST_ADD_MONTHS (1400, 3, 1, 1, 1400, 4, 1); + TEST_ADD_MONTHS (1400, 1, 31, 1, 1400, 2, 28); + TEST_ADD_MONTHS (1400, 1, 31, 7200, 2000, 1, 31); + TEST_ADD_MONTHS (2008, 2, 29, 12, 2009, 2, 28); + TEST_ADD_MONTHS (2000, 8, 16, -5, 2000, 3, 16); + TEST_ADD_MONTHS (2000, 8, 16, -12, 1999, 8, 16); + TEST_ADD_MONTHS (2011, 2, 1, -13, 2010, 1, 1); + TEST_ADD_MONTHS (1776, 7, 4, 1200, 1876, 7, 4); +} + +static void +test_GDateTime_add_days (void) +{ +#define TEST_ADD_DAYS(y,m,d,a,ny,nm,nd) G_STMT_START { \ + GDateTime *dt, *dt2; \ + dt = g_date_time_new_local (y, m, d, 0, 0, 0); \ + dt2 = g_date_time_add_days (dt, a); \ + g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ + g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ + g_assert_cmpint (nd, ==, g_date_time_get_day_of_month (dt2)); \ + g_date_time_unref (dt); \ + g_date_time_unref (dt2); \ +} G_STMT_END + + TEST_ADD_DAYS (2009, 1, 31, 1, 2009, 2, 1); + TEST_ADD_DAYS (2009, 2, 1, -1, 2009, 1, 31); + TEST_ADD_DAYS (2008, 2, 28, 1, 2008, 2, 29); + TEST_ADD_DAYS (2008, 12, 31, 1, 2009, 1, 1); + TEST_ADD_DAYS (1, 1, 1, 1, 1, 1, 2); + TEST_ADD_DAYS (1955, 5, 24, 10, 1955, 6, 3); + TEST_ADD_DAYS (1955, 5, 24, -10, 1955, 5, 14); +} + +static void +test_GDateTime_add_weeks (void) +{ +#define TEST_ADD_WEEKS(y,m,d,a,ny,nm,nd) G_STMT_START { \ + GDateTime *dt, *dt2; \ + dt = g_date_time_new_local (y, m, d, 0, 0, 0); \ + dt2 = g_date_time_add_weeks (dt, a); \ + g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ + g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ + g_assert_cmpint (nd, ==, g_date_time_get_day_of_month (dt2)); \ + g_date_time_unref (dt); \ + g_date_time_unref (dt2); \ +} G_STMT_END + + TEST_ADD_WEEKS (2009, 1, 1, 1, 2009, 1, 8); + TEST_ADD_WEEKS (2009, 8, 30, 1, 2009, 9, 6); + TEST_ADD_WEEKS (2009, 12, 31, 1, 2010, 1, 7); + TEST_ADD_WEEKS (2009, 1, 1, -1, 2008, 12, 25); +} + +static void +test_GDateTime_add_hours (void) +{ +#define TEST_ADD_HOURS(y,m,d,h,mi,s,a,ny,nm,nd,nh,nmi,ns) G_STMT_START { \ + GDateTime *dt, *dt2; \ + dt = g_date_time_new_utc (y, m, d, h, mi, s); \ + dt2 = g_date_time_add_hours (dt, a); \ + g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ + g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ + g_assert_cmpint (nd, ==, g_date_time_get_day_of_month (dt2)); \ + g_assert_cmpint (nh, ==, g_date_time_get_hour (dt2)); \ + g_assert_cmpint (nmi, ==, g_date_time_get_minute (dt2)); \ + g_assert_cmpint (ns, ==, g_date_time_get_second (dt2)); \ + g_date_time_unref (dt); \ + g_date_time_unref (dt2); \ +} G_STMT_END + + TEST_ADD_HOURS (2009, 1, 1, 0, 0, 0, 1, 2009, 1, 1, 1, 0, 0); + TEST_ADD_HOURS (2008, 12, 31, 23, 0, 0, 1, 2009, 1, 1, 0, 0, 0); +} + +static void +test_GDateTime_add_full (void) +{ +#define TEST_ADD_FULL(y,m,d,h,mi,s,ay,am,ad,ah,ami,as,ny,nm,nd,nh,nmi,ns) G_STMT_START { \ + GDateTime *dt, *dt2; \ + dt = g_date_time_new_utc (y, m, d, h, mi, s); \ + dt2 = g_date_time_add_full (dt, ay, am, ad, ah, ami, as); \ + g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ + g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ + g_assert_cmpint (nd, ==, g_date_time_get_day_of_month (dt2)); \ + g_assert_cmpint (nh, ==, g_date_time_get_hour (dt2)); \ + g_assert_cmpint (nmi, ==, g_date_time_get_minute (dt2)); \ + g_assert_cmpint (ns, ==, g_date_time_get_second (dt2)); \ + g_date_time_unref (dt); \ + g_date_time_unref (dt2); \ +} G_STMT_END + + TEST_ADD_FULL (2009, 10, 21, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 2010, 11, 22, 1, 1, 1); + TEST_ADD_FULL (2000, 1, 1, 1, 1, 1, + 0, 1, 0, 0, 0, 0, + 2000, 2, 1, 1, 1, 1); + TEST_ADD_FULL (2000, 1, 1, 0, 0, 0, + -1, 1, 0, 0, 0, 0, + 1999, 2, 1, 0, 0, 0); + TEST_ADD_FULL (2010, 10, 31, 0, 0, 0, + 0, 4, 0, 0, 0, 0, + 2011, 2, 28, 0, 0, 0); + TEST_ADD_FULL (2010, 8, 25, 22, 45, 0, + 0, 1, 6, 1, 25, 0, + 2010, 10, 2, 0, 10, 0); +} + +static void +test_GDateTime_add_minutes (void) +{ +#define TEST_ADD_MINUTES(i,o) G_STMT_START { \ + GDateTime *dt, *dt2; \ + dt = g_date_time_new_local (2000, 1, 1, 0, 0, 0); \ + dt2 = g_date_time_add_minutes (dt, i); \ + g_assert_cmpint (o, ==, g_date_time_get_minute (dt2)); \ + g_date_time_unref (dt); \ + g_date_time_unref (dt2); \ +} G_STMT_END + + TEST_ADD_MINUTES (60, 0); + TEST_ADD_MINUTES (100, 40); + TEST_ADD_MINUTES (5, 5); + TEST_ADD_MINUTES (1441, 1); + TEST_ADD_MINUTES (-1441, 59); +} + +static void +test_GDateTime_add_seconds (void) +{ +#define TEST_ADD_SECONDS(i,o) G_STMT_START { \ + GDateTime *dt, *dt2; \ + dt = g_date_time_new_local (2000, 1, 1, 0, 0, 0); \ + dt2 = g_date_time_add_seconds (dt, i); \ + g_assert_cmpint (o, ==, g_date_time_get_second (dt2)); \ + g_date_time_unref (dt); \ + g_date_time_unref (dt2); \ +} G_STMT_END + + TEST_ADD_SECONDS (1, 1); + TEST_ADD_SECONDS (60, 0); + TEST_ADD_SECONDS (61, 1); + TEST_ADD_SECONDS (120, 0); + TEST_ADD_SECONDS (-61, 59); + TEST_ADD_SECONDS (86401, 1); + TEST_ADD_SECONDS (-86401, 59); + TEST_ADD_SECONDS (-31, 29); + TEST_ADD_SECONDS (13, 13); +} + +static void +test_GDateTime_diff (void) +{ +#define TEST_DIFF(y,m,d,y2,m2,d2,u) G_STMT_START { \ + GDateTime *dt1, *dt2; \ + GTimeSpan ts = 0; \ + dt1 = g_date_time_new_utc (y, m, d, 0, 0, 0); \ + dt2 = g_date_time_new_utc (y2, m2, d2, 0, 0, 0); \ + ts = g_date_time_difference (dt2, dt1); \ + g_assert_cmpint (ts, ==, u); \ + g_date_time_unref (dt1); \ + g_date_time_unref (dt2); \ +} G_STMT_END + + TEST_DIFF (2009, 1, 1, 2009, 2, 1, G_TIME_SPAN_DAY * 31); + TEST_DIFF (2009, 1, 1, 2010, 1, 1, G_TIME_SPAN_DAY * 365); + TEST_DIFF (2008, 2, 28, 2008, 2, 29, G_TIME_SPAN_DAY); + TEST_DIFF (2008, 2, 29, 2008, 2, 28, -G_TIME_SPAN_DAY); + + /* TODO: Add usec tests */ +} + +static void +test_GDateTime_get_minute (void) +{ + GDateTime *dt; + + dt = g_date_time_new_utc (2009, 12, 1, 1, 31, 0); + g_assert_cmpint (31, ==, g_date_time_get_minute (dt)); + g_date_time_unref (dt); +} + +static void +test_GDateTime_get_month (void) +{ + GDateTime *dt; + + dt = g_date_time_new_utc (2009, 12, 1, 1, 31, 0); + g_assert_cmpint (12, ==, g_date_time_get_month (dt)); + g_date_time_unref (dt); +} + +static void +test_GDateTime_get_second (void) +{ + GDateTime *dt; + + dt = g_date_time_new_utc (2009, 12, 1, 1, 31, 44); + g_assert_cmpint (44, ==, g_date_time_get_second (dt)); + g_date_time_unref (dt); +} + +static void +test_GDateTime_new_full (void) +{ + GTimeZone *tz, *dt_tz; + GDateTime *dt; + +#ifdef G_OS_WIN32 + LCID currLcid = GetThreadLocale (); + LANGID currLangId = LANGIDFROMLCID (currLcid); + LANGID en = MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US); + SetThreadUILanguage (en); +#endif + + dt = g_date_time_new_utc (2009, 12, 11, 12, 11, 10); + g_assert_cmpint (2009, ==, g_date_time_get_year (dt)); + g_assert_cmpint (12, ==, g_date_time_get_month (dt)); + g_assert_cmpint (11, ==, g_date_time_get_day_of_month (dt)); + g_assert_cmpint (12, ==, g_date_time_get_hour (dt)); + g_assert_cmpint (11, ==, g_date_time_get_minute (dt)); + g_assert_cmpint (10, ==, g_date_time_get_second (dt)); + g_date_time_unref (dt); + +#ifdef G_OS_UNIX + tz = g_time_zone_new_identifier ("America/Tijuana"); +#elif defined G_OS_WIN32 + tz = g_time_zone_new_identifier ("Pacific Standard Time"); +#endif + g_assert_nonnull (tz); + dt = g_date_time_new (tz, 2010, 11, 24, 8, 4, 0); + + dt_tz = g_date_time_get_timezone (dt); + g_assert_cmpstr (g_time_zone_get_identifier (dt_tz), ==, + g_time_zone_get_identifier (tz)); + + g_assert_cmpint (2010, ==, g_date_time_get_year (dt)); + g_assert_cmpint (11, ==, g_date_time_get_month (dt)); + g_assert_cmpint (24, ==, g_date_time_get_day_of_month (dt)); + g_assert_cmpint (8, ==, g_date_time_get_hour (dt)); + g_assert_cmpint (4, ==, g_date_time_get_minute (dt)); + g_assert_cmpint (0, ==, g_date_time_get_second (dt)); +#ifdef G_OS_UNIX + g_assert_cmpstr ("PST", ==, g_date_time_get_timezone_abbreviation (dt)); + g_assert_cmpstr ("America/Tijuana", ==, g_time_zone_get_identifier (dt_tz)); +#elif defined G_OS_WIN32 + g_assert_cmpstr ("Pacific Standard Time", ==, + g_date_time_get_timezone_abbreviation (dt)); + g_assert_cmpstr ("Pacific Standard Time", ==, + g_time_zone_get_identifier (dt_tz)); + SetThreadUILanguage (currLangId); +#endif + g_assert (!g_date_time_is_daylight_savings (dt)); + g_date_time_unref (dt); + g_time_zone_unref (tz); + + /* Check month limits */ + dt = g_date_time_new_utc (2016, 1, 31, 22, 10, 42); + ASSERT_DATE (dt, 2016, 1, 31); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 1, 32, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 2, 29, 22, 10, 42); + ASSERT_DATE (dt, 2016, 2, 29); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 2, 30, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2017, 2, 28, 22, 10, 42); + ASSERT_DATE (dt, 2017, 2, 28); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2017, 2, 29, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 3, 31, 22, 10, 42); + ASSERT_DATE (dt, 2016, 3, 31); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 3, 32, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 4, 30, 22, 10, 42); + ASSERT_DATE (dt, 2016, 4, 30); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 4, 31, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 5, 31, 22, 10, 42); + ASSERT_DATE (dt, 2016, 5, 31); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 5, 32, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 6, 30, 22, 10, 42); + ASSERT_DATE (dt, 2016, 6, 30); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 6, 31, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 7, 31, 22, 10, 42); + ASSERT_DATE (dt, 2016, 7, 31); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 7, 32, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 8, 31, 22, 10, 42); + ASSERT_DATE (dt, 2016, 8, 31); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 8, 32, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 9, 30, 22, 10, 42); + ASSERT_DATE (dt, 2016, 9, 30); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 9, 31, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 10, 31, 22, 10, 42); + ASSERT_DATE (dt, 2016, 10, 31); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 10, 32, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 11, 30, 22, 10, 42); + ASSERT_DATE (dt, 2016, 11, 30); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 11, 31, 22, 10, 42); + g_assert_null (dt); + dt = g_date_time_new_utc (2016, 12, 31, 22, 10, 42); + ASSERT_DATE (dt, 2016, 12, 31); + g_date_time_unref (dt); + dt = g_date_time_new_utc (2016, 12, 32, 22, 10, 42); + g_assert_null (dt); + + /* Seconds limits. */ + dt = g_date_time_new_utc (2020, 12, 9, 14, 49, NAN); + g_assert_null (dt); + dt = g_date_time_new_utc (2020, 12, 9, 14, 49, -0.1); + g_assert_null (dt); + dt = g_date_time_new_utc (2020, 12, 9, 14, 49, 60.0); + g_assert_null (dt); + + /* Year limits */ + dt = g_date_time_new_utc (10000, 1, 1, 0, 0, 0); + dt = g_date_time_new_utc (0, 1, 1, 0, 0, 0); +} + +static void +test_GDateTime_now_utc (void) +{ + GDateTime *dt; + struct tm tm; + time_t t; + time_t after; + + /* t <= dt.to_unix() <= after, but the inequalities might not be + * equality if we're close to the boundary between seconds. + * We loop until t == after (and hence dt.to_unix() should equal both) + * to guard against that. */ + do + { + t = g_get_real_time () / G_TIME_SPAN_SECOND; +#ifdef HAVE_GMTIME_R + gmtime_r (&t, &tm); +#else + { + struct tm *tmp = gmtime (&t); + /* Assume gmtime() can't fail as we got t from time(NULL). (Note + * that on Windows, gmtime() *is* MT-safe, it uses a thread-local + * buffer.) + */ + memcpy (&tm, tmp, sizeof (struct tm)); + } +#endif + dt = g_date_time_new_now_utc (); + + after = g_get_real_time () / G_TIME_SPAN_SECOND; + } + while (t != after); + + g_assert_cmpint (tm.tm_year + 1900, ==, g_date_time_get_year (dt)); + g_assert_cmpint (tm.tm_mon + 1, ==, g_date_time_get_month (dt)); + g_assert_cmpint (tm.tm_mday, ==, g_date_time_get_day_of_month (dt)); + g_assert_cmpint (tm.tm_hour, ==, g_date_time_get_hour (dt)); + g_assert_cmpint (tm.tm_min, ==, g_date_time_get_minute (dt)); + g_assert_cmpint (tm.tm_sec, ==, g_date_time_get_second (dt)); + g_date_time_unref (dt); +} + +static void +test_GDateTime_new_from_unix_utc (void) +{ + GDateTime *dt; + gint64 t; + + t = g_get_real_time (); + +#if 0 + dt = g_date_time_new_from_unix_utc (t); + g_assert (dt == NULL); +#endif + + t = t / 1e6; /* oops, this was microseconds */ + + dt = g_date_time_new_from_unix_utc (t); + g_assert (dt != NULL); + + g_assert (dt == g_date_time_ref (dt)); + g_date_time_unref (dt); + g_assert_cmpint (g_date_time_to_unix (dt), ==, t); + g_date_time_unref (dt); +} + +static void +test_GDateTime_get_utc_offset (void) +{ +#if defined (HAVE_STRUCT_TM_TM_GMTOFF) || defined (HAVE_STRUCT_TM___TM_GMTOFF) + GDateTime *dt; + GTimeSpan ts; + struct tm tm; + + memset (&tm, 0, sizeof (tm)); + get_localtime_tm (g_get_real_time () / G_TIME_SPAN_SECOND, &tm); + + dt = g_date_time_new_now_local (); + ts = g_date_time_get_utc_offset (dt); +#ifdef HAVE_STRUCT_TM_TM_GMTOFF + g_assert_cmpint (ts, ==, (tm.tm_gmtoff * G_TIME_SPAN_SECOND)); +#endif +#ifdef HAVE_STRUCT_TM___TM_GMTOFF + g_assert_cmpint (ts, ==, (tm.__tm_gmtoff * G_TIME_SPAN_SECOND)); +#endif + g_date_time_unref (dt); +#endif +} + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +static void +test_GDateTime_to_timeval (void) +{ + GTimeVal tv1, tv2; + GDateTime *dt; + + memset (&tv1, 0, sizeof (tv1)); + memset (&tv2, 0, sizeof (tv2)); + + g_get_current_time (&tv1); + dt = g_date_time_new_from_timeval_local (&tv1); + g_date_time_to_timeval (dt, &tv2); + g_assert_cmpint (tv1.tv_sec, ==, tv2.tv_sec); + g_assert_cmpint (tv1.tv_usec, ==, tv2.tv_usec); + g_date_time_unref (dt); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +static void +test_GDateTime_to_local (void) +{ + GDateTime *utc = NULL, *now = NULL, *dt; + time_t before, after; + + /* before <= utc.to_unix() <= now.to_unix() <= after, but the inequalities + * might not be equality if we're close to the boundary between seconds. + * We loop until before == after (and hence the GDateTimes should match) + * to guard against that. */ + do + { + before = g_get_real_time () / G_TIME_SPAN_SECOND; + g_clear_pointer (&utc, g_date_time_unref); + g_clear_pointer (&now, g_date_time_unref); + utc = g_date_time_new_now_utc (); + now = g_date_time_new_now_local (); + after = g_get_real_time () / G_TIME_SPAN_SECOND; + } + while (before != after); + + dt = g_date_time_to_local (utc); + + g_assert_cmpint (g_date_time_get_year (now), ==, g_date_time_get_year (dt)); + g_assert_cmpint (g_date_time_get_month (now), ==, g_date_time_get_month (dt)); + g_assert_cmpint (g_date_time_get_day_of_month (now), ==, g_date_time_get_day_of_month (dt)); + g_assert_cmpint (g_date_time_get_hour (now), ==, g_date_time_get_hour (dt)); + g_assert_cmpint (g_date_time_get_minute (now), ==, g_date_time_get_minute (dt)); + g_assert_cmpint (g_date_time_get_second (now), ==, g_date_time_get_second (dt)); + + g_date_time_unref (now); + g_date_time_unref (utc); + g_date_time_unref (dt); +} + +static void +test_GDateTime_to_utc (void) +{ + GDateTime *dt, *dt2; + time_t t; + struct tm tm; + + t = time (NULL); + g_assert_cmpint (t, !=, (time_t) -1); +#ifdef HAVE_GMTIME_R + gmtime_r (&t, &tm); +#else + { + struct tm *tmp = gmtime (&t); + memcpy (&tm, tmp, sizeof (struct tm)); + } +#endif + dt2 = g_date_time_new_from_unix_local (t); + dt = g_date_time_to_utc (dt2); + g_assert_cmpint (tm.tm_year + 1900, ==, g_date_time_get_year (dt)); + g_assert_cmpint (tm.tm_mon + 1, ==, g_date_time_get_month (dt)); + g_assert_cmpint (tm.tm_mday, ==, g_date_time_get_day_of_month (dt)); + g_assert_cmpint (tm.tm_hour, ==, g_date_time_get_hour (dt)); + g_assert_cmpint (tm.tm_min, ==, g_date_time_get_minute (dt)); + g_assert_cmpint (tm.tm_sec, ==, g_date_time_get_second (dt)); + g_date_time_unref (dt); + g_date_time_unref (dt2); +} + +static void +test_GDateTime_get_day_of_year (void) +{ +#define TEST_DAY_OF_YEAR(y,m,d,o) G_STMT_START { \ + GDateTime *__dt = g_date_time_new_local ((y), (m), (d), 0, 0, 0); \ + g_assert_cmpint ((o), ==, g_date_time_get_day_of_year (__dt)); \ + g_date_time_unref (__dt); } G_STMT_END + + TEST_DAY_OF_YEAR (2009, 1, 1, 1); + TEST_DAY_OF_YEAR (2009, 2, 1, 32); + TEST_DAY_OF_YEAR (2009, 8, 16, 228); + TEST_DAY_OF_YEAR (2008, 8, 16, 229); +} + +static void +test_GDateTime_printf (void) +{ +/* 64 seems big, but one zoneinfo file, Factory, has an abbreviation + * that long, and it will cause the test to fail if dst isn't big + * enough. + */ + gchar *old_lc_all; + gchar *old_lc_messages; + gchar dst[64]; + struct tm tt; + time_t t; + +#ifdef G_OS_WIN32 + gchar *current_tz = NULL; + DYNAMIC_TIME_ZONE_INFORMATION dtz_info; +#endif + +#define TEST_PRINTF(f,o) G_STMT_START { \ +GDateTime *__dt = g_date_time_new_local (2009, 10, 24, 0, 0, 0);\ + gchar *__p = g_date_time_format (__dt, (f)); \ + g_assert_cmpstr (__p, ==, (o)); \ + g_date_time_unref (__dt); \ + g_free (__p); } G_STMT_END + +#define TEST_PRINTF_DATE(y,m,d,f,o) G_STMT_START { \ + GDateTime *dt = g_date_time_new_local (y, m, d, 0, 0, 0); \ + gchar *p = g_date_time_format (dt, (f)); \ + gchar *o_casefold = g_utf8_casefold (o, -1); \ + gchar *p_casefold = g_utf8_casefold (p, -1); \ + g_assert_cmpstr (p_casefold, ==, (o_casefold)); \ + g_date_time_unref (dt); \ + g_free (p_casefold); \ + g_free (o_casefold); \ + g_free (p); } G_STMT_END + +#define TEST_PRINTF_TIME(h,m,s,f,o) G_STMT_START { \ + GDateTime *dt = g_date_time_new_local (2009, 10, 24, (h), (m), (s)); \ + gchar *p = g_date_time_format (dt, (f)); \ + g_assert_cmpstr (p, ==, (o)); \ + g_date_time_unref (dt); \ + g_free (p); } G_STMT_END + + old_lc_all = g_strdup (g_getenv ("LC_ALL")); + g_unsetenv ("LC_ALL"); + + old_lc_messages = g_strdup (g_getenv ("LC_MESSAGES")); + g_setenv ("LC_MESSAGES", "C", TRUE); + + /* + * This is a little helper to make sure we can compare timezones to + * that of the generated timezone. + */ + t = time (NULL); + g_assert_cmpint (t, !=, (time_t) -1); + memset (&tt, 0, sizeof(tt)); + get_localtime_tm (t, &tt); + tt.tm_year = 2009 - 1900; + tt.tm_mon = 9; /* 0 indexed */ + tt.tm_mday = 24; + t = mktime (&tt); + memset (&tt, 0, sizeof(tt)); + get_localtime_tm (t, &tt); + strftime (dst, sizeof(dst), "%Z", &tt); + + TEST_PRINTF ("%a", "Sat"); + TEST_PRINTF ("%A", "Saturday"); + TEST_PRINTF ("%b", "Oct"); + TEST_PRINTF ("%B", "October"); + TEST_PRINTF ("%d", "24"); + TEST_PRINTF_DATE (2009, 1, 1, "%d", "01"); + TEST_PRINTF ("%e", "24"); // fixme + TEST_PRINTF_TIME (10, 10, 1.001, "%f", "001000"); + TEST_PRINTF ("%h", "Oct"); + TEST_PRINTF ("%H", "00"); + TEST_PRINTF_TIME (15, 0, 0, "%H", "15"); + TEST_PRINTF ("%I", "12"); + TEST_PRINTF_TIME (12, 0, 0, "%I", "12"); + TEST_PRINTF_TIME (15, 0, 0, "%I", "03"); + TEST_PRINTF ("%j", "297"); + TEST_PRINTF ("%k", " 0"); + TEST_PRINTF_TIME (13, 13, 13, "%k", "13"); + TEST_PRINTF ("%l", "12"); + TEST_PRINTF_TIME (12, 0, 0, "%I", "12"); + TEST_PRINTF_TIME (13, 13, 13, "%l", " 1"); + TEST_PRINTF_TIME (10, 13, 13, "%l", "10"); + TEST_PRINTF ("%m", "10"); + TEST_PRINTF ("%M", "00"); + TEST_PRINTF ("%p", "AM"); + TEST_PRINTF_TIME (13, 13, 13, "%p", "PM"); + TEST_PRINTF ("%P", "am"); + TEST_PRINTF_TIME (13, 13, 13, "%P", "pm"); + TEST_PRINTF ("%r", "12:00:00 AM"); + TEST_PRINTF_TIME (13, 13, 13, "%r", "01:13:13 PM"); + TEST_PRINTF ("%R", "00:00"); + TEST_PRINTF_TIME (13, 13, 31, "%R", "13:13"); + TEST_PRINTF ("%S", "00"); + TEST_PRINTF ("%t", " "); + TEST_PRINTF ("%u", "6"); + TEST_PRINTF ("%x", "10/24/09"); + TEST_PRINTF ("%X", "00:00:00"); + TEST_PRINTF_TIME (13, 14, 15, "%X", "13:14:15"); + TEST_PRINTF ("%y", "09"); + TEST_PRINTF ("%Y", "2009"); + TEST_PRINTF ("%%", "%"); + TEST_PRINTF ("%", ""); + TEST_PRINTF ("%9", NULL); +#ifdef G_OS_UNIX + TEST_PRINTF ("%Z", dst); +#elif defined G_OS_WIN32 + g_assert (GetDynamicTimeZoneInformation (&dtz_info) != TIME_ZONE_ID_INVALID); + if (wcscmp (dtz_info.StandardName, L"") != 0) + current_tz = g_utf16_to_utf8 (dtz_info.StandardName, -1, NULL, NULL, NULL); + else + current_tz = g_utf16_to_utf8 (dtz_info.DaylightName, -1, NULL, NULL, NULL); + + TEST_PRINTF ("%Z", current_tz); + g_free (current_tz); +#endif + + if (old_lc_messages != NULL) + g_setenv ("LC_MESSAGES", old_lc_messages, TRUE); + else + g_unsetenv ("LC_MESSAGES"); + g_free (old_lc_messages); + + if (old_lc_all != NULL) + g_setenv ("LC_ALL", old_lc_all, TRUE); + g_free (old_lc_all); +} + +static void +test_non_utf8_printf (void) +{ + gchar *oldlocale; + + if (skip_if_running_uninstalled()) + return; + + oldlocale = g_strdup (setlocale (LC_ALL, NULL)); + setlocale (LC_ALL, "ja_JP.eucjp"); + if (strstr (setlocale (LC_ALL, NULL), "ja_JP") == NULL) + { + g_test_skip ("locale ja_JP.eucjp not available, skipping non-UTF8 tests"); + g_free (oldlocale); + return; + } + if (g_get_charset (NULL)) + { + g_test_skip ("locale ja_JP.eucjp may be available, but glib seems to think that it's equivalent to UTF-8, skipping non-UTF-8 tests. This is a known issue on Darwin"); + setlocale (LC_ALL, oldlocale); + g_free (oldlocale); + return; + } + + /* These are the outputs that ja_JP.UTF-8 generates; if everything + * is working then ja_JP.eucjp should generate the same. + */ + TEST_PRINTF ("%a", "\345\234\237"); + TEST_PRINTF ("%A", "\345\234\237\346\233\234\346\227\245"); +#ifndef __APPLE__ /* OSX just returns the number */ + TEST_PRINTF ("%b", "10\346\234\210"); +#endif + TEST_PRINTF ("%B", "10\346\234\210"); + TEST_PRINTF ("%d", "24"); + TEST_PRINTF_DATE (2009, 1, 1, "%d", "01"); + TEST_PRINTF ("%e", "24"); // fixme +#ifndef __APPLE__ /* OSX just returns the number */ + TEST_PRINTF ("%h", "10\346\234\210"); +#endif + TEST_PRINTF ("%H", "00"); + TEST_PRINTF_TIME (15, 0, 0, "%H", "15"); + TEST_PRINTF ("%I", "12"); + TEST_PRINTF_TIME (12, 0, 0, "%I", "12"); + TEST_PRINTF_TIME (15, 0, 0, "%I", "03"); + TEST_PRINTF ("%j", "297"); + TEST_PRINTF ("%k", " 0"); + TEST_PRINTF_TIME (13, 13, 13, "%k", "13"); + TEST_PRINTF ("%l", "12"); + TEST_PRINTF_TIME (12, 0, 0, "%I", "12"); + TEST_PRINTF_TIME (13, 13, 13, "%l", " 1"); + TEST_PRINTF_TIME (10, 13, 13, "%l", "10"); + TEST_PRINTF ("%m", "10"); + TEST_PRINTF ("%M", "00"); +#ifndef __APPLE__ /* OSX returns latin "AM", not japanese */ + TEST_PRINTF ("%p", "\345\215\210\345\211\215"); + TEST_PRINTF_TIME (13, 13, 13, "%p", "\345\215\210\345\276\214"); + TEST_PRINTF ("%P", "\345\215\210\345\211\215"); + TEST_PRINTF_TIME (13, 13, 13, "%P", "\345\215\210\345\276\214"); + TEST_PRINTF ("%r", "\345\215\210\345\211\21512\346\231\20200\345\210\20600\347\247\222"); + TEST_PRINTF_TIME (13, 13, 13, "%r", "\345\215\210\345\276\21401\346\231\20213\345\210\20613\347\247\222"); +#endif + TEST_PRINTF ("%R", "00:00"); + TEST_PRINTF_TIME (13, 13, 31, "%R", "13:13"); + TEST_PRINTF ("%S", "00"); + TEST_PRINTF ("%t", " "); + TEST_PRINTF ("%u", "6"); +#ifndef __APPLE__ /* OSX returns YYYY/MM/DD in ASCII */ + TEST_PRINTF ("%x", "2009\345\271\26410\346\234\21024\346\227\245"); +#endif + TEST_PRINTF ("%X", "00\346\231\20200\345\210\20600\347\247\222"); + TEST_PRINTF_TIME (13, 14, 15, "%X", "13\346\231\20214\345\210\20615\347\247\222"); + TEST_PRINTF ("%y", "09"); + TEST_PRINTF ("%Y", "2009"); + TEST_PRINTF ("%%", "%"); + TEST_PRINTF ("%", ""); + TEST_PRINTF ("%9", NULL); + + setlocale (LC_ALL, oldlocale); + g_free (oldlocale); +} + +/* Checks that it is possible to use format string that + * is unrepresentable in current locale charset. */ +static void +test_format_unrepresentable (void) +{ + gchar *oldlocale = g_strdup (setlocale (LC_ALL, NULL)); + setlocale (LC_ALL, "POSIX"); + + TEST_PRINTF ("ąśćł", "ąśćł"); + + /* We are using Unicode ratio symbol here, which is outside ASCII. */ + TEST_PRINTF_TIME (23, 15, 0, "%H∶%M", "23∶15"); + + /* Test again, this time in locale with non ASCII charset. */ + if (setlocale (LC_ALL, "pl_PL.ISO-8859-2") != NULL) + TEST_PRINTF_TIME (23, 15, 0, "%H∶%M", "23∶15"); + else + g_test_skip ("locale pl_PL.ISO-8859-2 not available, skipping test"); + + setlocale (LC_ALL, oldlocale); + g_free (oldlocale); +} + +static void +test_modifiers (void) +{ + gchar *oldlocale; + + TEST_PRINTF_DATE (2009, 1, 1, "%d", "01"); + TEST_PRINTF_DATE (2009, 1, 1, "%_d", " 1"); + TEST_PRINTF_DATE (2009, 1, 1, "%-d", "1"); + TEST_PRINTF_DATE (2009, 1, 1, "%0d", "01"); + TEST_PRINTF_DATE (2009, 1, 21, "%d", "21"); + TEST_PRINTF_DATE (2009, 1, 21, "%_d", "21"); + TEST_PRINTF_DATE (2009, 1, 21, "%-d", "21"); + TEST_PRINTF_DATE (2009, 1, 21, "%0d", "21"); + + TEST_PRINTF_DATE (2009, 1, 1, "%e", " 1"); + TEST_PRINTF_DATE (2009, 1, 1, "%_e", " 1"); + TEST_PRINTF_DATE (2009, 1, 1, "%-e", "1"); + TEST_PRINTF_DATE (2009, 1, 1, "%0e", "01"); + TEST_PRINTF_DATE (2009, 1, 21, "%e", "21"); + TEST_PRINTF_DATE (2009, 1, 21, "%_e", "21"); + TEST_PRINTF_DATE (2009, 1, 21, "%-e", "21"); + TEST_PRINTF_DATE (2009, 1, 21, "%0e", "21"); + + TEST_PRINTF_TIME ( 1, 0, 0, "%H", "01"); + TEST_PRINTF_TIME ( 1, 0, 0, "%_H", " 1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%-H", "1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%0H", "01"); + TEST_PRINTF_TIME (21, 0, 0, "%H", "21"); + TEST_PRINTF_TIME (21, 0, 0, "%_H", "21"); + TEST_PRINTF_TIME (21, 0, 0, "%-H", "21"); + TEST_PRINTF_TIME (21, 0, 0, "%0H", "21"); + + TEST_PRINTF_TIME ( 1, 0, 0, "%I", "01"); + TEST_PRINTF_TIME ( 1, 0, 0, "%_I", " 1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%-I", "1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%0I", "01"); + TEST_PRINTF_TIME (23, 0, 0, "%I", "11"); + TEST_PRINTF_TIME (23, 0, 0, "%_I", "11"); + TEST_PRINTF_TIME (23, 0, 0, "%-I", "11"); + TEST_PRINTF_TIME (23, 0, 0, "%0I", "11"); + + TEST_PRINTF_TIME ( 1, 0, 0, "%k", " 1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%_k", " 1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%-k", "1"); + TEST_PRINTF_TIME ( 1, 0, 0, "%0k", "01"); + + oldlocale = g_strdup (setlocale (LC_ALL, NULL)); + setlocale (LC_ALL, "fa_IR.utf-8"); +#ifdef HAVE_LANGINFO_OUTDIGIT + if (strstr (setlocale (LC_ALL, NULL), "fa_IR") != NULL) + { + TEST_PRINTF_TIME (23, 0, 0, "%OH", "\333\262\333\263"); /* '23' */ + TEST_PRINTF_TIME (23, 0, 0, "%OI", "\333\261\333\261"); /* '11' */ + TEST_PRINTF_TIME (23, 0, 0, "%OM", "\333\260\333\260"); /* '00' */ + + TEST_PRINTF_DATE (2011, 7, 1, "%Om", "\333\260\333\267"); /* '07' */ + TEST_PRINTF_DATE (2011, 7, 1, "%0Om", "\333\260\333\267"); /* '07' */ + TEST_PRINTF_DATE (2011, 7, 1, "%-Om", "\333\267"); /* '7' */ + TEST_PRINTF_DATE (2011, 7, 1, "%_Om", " \333\267"); /* ' 7' */ + } + else + g_test_skip ("locale fa_IR not available, skipping O modifier tests"); +#else + g_test_skip ("langinfo not available, skipping O modifier tests"); +#endif + setlocale (LC_ALL, oldlocale); + g_free (oldlocale); +} + +/* Test that the `O` modifier for g_date_time_format() works with %B, %b and %h; + * i.e. whether genitive month names are supported. */ +static void +test_month_names (void) +{ + gchar *oldlocale; + + g_test_bug ("http://bugzilla.gnome.org/749206"); + + if (skip_if_running_uninstalled()) + return; + + oldlocale = g_strdup (setlocale (LC_ALL, NULL)); + + /* Make sure that nothing has been changed in western European languages. */ + setlocale (LC_ALL, "en_GB.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "en_GB") != NULL) + { + TEST_PRINTF_DATE (2018, 1, 1, "%B", "January"); + TEST_PRINTF_DATE (2018, 2, 1, "%OB", "February"); + TEST_PRINTF_DATE (2018, 3, 1, "%b", "Mar"); + TEST_PRINTF_DATE (2018, 4, 1, "%Ob", "Apr"); + TEST_PRINTF_DATE (2018, 5, 1, "%h", "May"); + TEST_PRINTF_DATE (2018, 6, 1, "%Oh", "Jun"); + } + else + g_test_skip ("locale en_GB not available, skipping English month names test"); + + setlocale (LC_ALL, "de_DE.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "de_DE") != NULL) + { + TEST_PRINTF_DATE (2018, 7, 1, "%B", "Juli"); + TEST_PRINTF_DATE (2018, 8, 1, "%OB", "August"); + TEST_PRINTF_DATE (2018, 9, 1, "%b", "Sep"); + TEST_PRINTF_DATE (2018, 10, 1, "%Ob", "Okt"); + TEST_PRINTF_DATE (2018, 11, 1, "%h", "Nov"); + TEST_PRINTF_DATE (2018, 12, 1, "%Oh", "Dez"); + } + else + g_test_skip ("locale de_DE not available, skipping German month names test"); + + setlocale (LC_ALL, "es_ES.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "es_ES") != NULL) + { + TEST_PRINTF_DATE (2018, 1, 1, "%B", "enero"); + TEST_PRINTF_DATE (2018, 2, 1, "%OB", "febrero"); + TEST_PRINTF_DATE (2018, 3, 1, "%b", "mar"); + TEST_PRINTF_DATE (2018, 4, 1, "%Ob", "abr"); + TEST_PRINTF_DATE (2018, 5, 1, "%h", "may"); + TEST_PRINTF_DATE (2018, 6, 1, "%Oh", "jun"); + } + else + g_test_skip ("locale es_ES not available, skipping Spanish month names test"); + + setlocale (LC_ALL, "fr_FR.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "fr_FR") != NULL) + { + TEST_PRINTF_DATE (2018, 7, 1, "%B", "juillet"); + TEST_PRINTF_DATE (2018, 8, 1, "%OB", "août"); + TEST_PRINTF_DATE (2018, 9, 1, "%b", "sept."); + TEST_PRINTF_DATE (2018, 10, 1, "%Ob", "oct."); + TEST_PRINTF_DATE (2018, 11, 1, "%h", "nov."); + TEST_PRINTF_DATE (2018, 12, 1, "%Oh", "déc."); + } + else + g_test_skip ("locale fr_FR not available, skipping French month names test"); + + /* Make sure that there are visible changes in some European languages. */ + setlocale (LC_ALL, "el_GR.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "el_GR") != NULL) + { + TEST_PRINTF_DATE (2018, 1, 1, "%B", "ΙανουαÏίου"); + TEST_PRINTF_DATE (2018, 2, 1, "%B", "ΦεβÏουαÏίου"); + TEST_PRINTF_DATE (2018, 3, 1, "%B", "ΜαÏτίου"); + TEST_PRINTF_DATE (2018, 4, 1, "%OB", "ΑπÏίλιος"); + TEST_PRINTF_DATE (2018, 5, 1, "%OB", "Μάιος"); + TEST_PRINTF_DATE (2018, 6, 1, "%OB", "ΙοÏνιος"); + TEST_PRINTF_DATE (2018, 7, 1, "%b", "Ιουλ"); + TEST_PRINTF_DATE (2018, 8, 1, "%Ob", "ΑÏγ"); + } + else + g_test_skip ("locale el_GR not available, skipping Greek month names test"); + + setlocale (LC_ALL, "hr_HR.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "hr_HR") != NULL) + { + TEST_PRINTF_DATE (2018, 5, 1, "%B", "svibnja"); + TEST_PRINTF_DATE (2018, 6, 1, "%B", "lipnja"); + TEST_PRINTF_DATE (2018, 7, 1, "%B", "srpnja"); + TEST_PRINTF_DATE (2018, 8, 1, "%OB", "Kolovoz"); + TEST_PRINTF_DATE (2018, 9, 1, "%OB", "Rujan"); + TEST_PRINTF_DATE (2018, 10, 1, "%OB", "Listopad"); + TEST_PRINTF_DATE (2018, 11, 1, "%b", "Stu"); + TEST_PRINTF_DATE (2018, 12, 1, "%Ob", "Pro"); + } + else + g_test_skip ("locale hr_HR not available, skipping Croatian month names test"); + + setlocale (LC_ALL, "lt_LT.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "lt_LT") != NULL) + { + TEST_PRINTF_DATE (2018, 1, 1, "%B", "sausio"); + TEST_PRINTF_DATE (2018, 2, 1, "%B", "vasario"); + TEST_PRINTF_DATE (2018, 3, 1, "%B", "kovo"); + TEST_PRINTF_DATE (2018, 4, 1, "%OB", "balandis"); + TEST_PRINTF_DATE (2018, 5, 1, "%OB", "gegužė"); + TEST_PRINTF_DATE (2018, 6, 1, "%OB", "birželis"); + TEST_PRINTF_DATE (2018, 7, 1, "%b", "liep."); + TEST_PRINTF_DATE (2018, 8, 1, "%Ob", "rugp."); + } + else + g_test_skip ("locale lt_LT not available, skipping Lithuanian month names test"); + + setlocale (LC_ALL, "pl_PL.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "pl_PL") != NULL) + { + TEST_PRINTF_DATE (2018, 5, 1, "%B", "maja"); + TEST_PRINTF_DATE (2018, 6, 1, "%B", "czerwca"); + TEST_PRINTF_DATE (2018, 7, 1, "%B", "lipca"); + TEST_PRINTF_DATE (2018, 8, 1, "%OB", "sierpieÅ„"); + TEST_PRINTF_DATE (2018, 9, 1, "%OB", "wrzesieÅ„"); + TEST_PRINTF_DATE (2018, 10, 1, "%OB", "październik"); + TEST_PRINTF_DATE (2018, 11, 1, "%b", "lis"); + TEST_PRINTF_DATE (2018, 12, 1, "%Ob", "gru"); + } + else + g_test_skip ("locale pl_PL not available, skipping Polish month names test"); + + setlocale (LC_ALL, "ru_RU.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "ru_RU") != NULL) + { + TEST_PRINTF_DATE (2018, 1, 1, "%B", "ÑнварÑ"); + TEST_PRINTF_DATE (2018, 2, 1, "%B", "февралÑ"); + TEST_PRINTF_DATE (2018, 3, 1, "%B", "марта"); + TEST_PRINTF_DATE (2018, 4, 1, "%OB", "Ðпрель"); + TEST_PRINTF_DATE (2018, 5, 1, "%OB", "Май"); + TEST_PRINTF_DATE (2018, 6, 1, "%OB", "Июнь"); + TEST_PRINTF_DATE (2018, 7, 1, "%b", "июл"); + TEST_PRINTF_DATE (2018, 8, 1, "%Ob", "авг"); + /* This difference is very important in Russian: */ + TEST_PRINTF_DATE (2018, 5, 1, "%b", "маÑ"); + TEST_PRINTF_DATE (2018, 5, 1, "%Ob", "май"); + } + else + g_test_skip ("locale ru_RU not available, skipping Russian month names test"); + + setlocale (LC_ALL, oldlocale); + g_free (oldlocale); +} + +static void +test_GDateTime_dst (void) +{ + GDateTime *dt1, *dt2; + GTimeZone *tz; + + /* this date has the DST state set for Europe/London */ +#ifdef G_OS_UNIX + tz = g_time_zone_new_identifier ("Europe/London"); +#elif defined G_OS_WIN32 + tz = g_time_zone_new_identifier ("GMT Standard Time"); +#endif + g_assert_nonnull (tz); + dt1 = g_date_time_new (tz, 2009, 8, 15, 3, 0, 1); + g_assert (g_date_time_is_daylight_savings (dt1)); + g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, 3600); + g_assert_cmpint (g_date_time_get_hour (dt1), ==, 3); + + /* add 6 months to clear the DST flag but keep the same time */ + dt2 = g_date_time_add_months (dt1, 6); + g_assert (!g_date_time_is_daylight_savings (dt2)); + g_assert_cmpint (g_date_time_get_utc_offset (dt2) / G_USEC_PER_SEC, ==, 0); + g_assert_cmpint (g_date_time_get_hour (dt2), ==, 3); + + g_date_time_unref (dt2); + g_date_time_unref (dt1); + + /* now do the reverse: start with a non-DST state and move to DST */ + dt1 = g_date_time_new (tz, 2009, 2, 15, 2, 0, 1); + g_assert (!g_date_time_is_daylight_savings (dt1)); + g_assert_cmpint (g_date_time_get_hour (dt1), ==, 2); + + dt2 = g_date_time_add_months (dt1, 6); + g_assert (g_date_time_is_daylight_savings (dt2)); + g_assert_cmpint (g_date_time_get_hour (dt2), ==, 2); + + g_date_time_unref (dt2); + g_date_time_unref (dt1); + g_time_zone_unref (tz); +} + +static inline gboolean +is_leap_year (gint year) +{ + g_assert (1 <= year && year <= 9999); + + return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); +} + +static inline gint +days_in_month (gint year, gint month) +{ + const gint table[2][13] = { + {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + }; + + g_assert (1 <= month && month <= 12); + + return table[is_leap_year (year)][month]; +} + +static void +test_all_dates (void) +{ + gint year, month, day; + GTimeZone *timezone; + gint64 unix_time; + gint day_of_year; + gint week_year; + gint week_num; + gint weekday; + + /* save some time by hanging on to this. */ + timezone = g_time_zone_new_utc (); + + unix_time = G_GINT64_CONSTANT(-62135596800); + + /* 0001-01-01 is 0001-W01-1 */ + week_year = 1; + week_num = 1; + weekday = 1; + + + /* The calendar makes a full cycle every 400 years, so we could + * theoretically just test years 1 through 400. That assumes that our + * software has no bugs, so probably we should just test them all. :) + */ + for (year = 1; year <= 9999; year++) + { + day_of_year = 1; + + for (month = 1; month <= 12; month++) + for (day = 1; day <= days_in_month (year, month); day++) + { + GDateTime *dt; + + dt = g_date_time_new (timezone, year, month, day, 0, 0, 0); + +#if 0 + g_printerr ("%04d-%02d-%02d = %04d-W%02d-%d = %04d-%03d\n", + year, month, day, + week_year, week_num, weekday, + year, day_of_year); +#endif + + /* sanity check */ + if G_UNLIKELY (g_date_time_get_year (dt) != year || + g_date_time_get_month (dt) != month || + g_date_time_get_day_of_month (dt) != day) + g_error ("%04d-%02d-%02d comes out as %04d-%02d-%02d", + year, month, day, + g_date_time_get_year (dt), + g_date_time_get_month (dt), + g_date_time_get_day_of_month (dt)); + + if G_UNLIKELY (g_date_time_get_week_numbering_year (dt) != week_year || + g_date_time_get_week_of_year (dt) != week_num || + g_date_time_get_day_of_week (dt) != weekday) + g_error ("%04d-%02d-%02d should be %04d-W%02d-%d but " + "comes out as %04d-W%02d-%d", year, month, day, + week_year, week_num, weekday, + g_date_time_get_week_numbering_year (dt), + g_date_time_get_week_of_year (dt), + g_date_time_get_day_of_week (dt)); + + if G_UNLIKELY (g_date_time_to_unix (dt) != unix_time) + g_error ("%04d-%02d-%02d 00:00:00 UTC should have unix time %" + G_GINT64_FORMAT " but comes out as %"G_GINT64_FORMAT, + year, month, day, unix_time, g_date_time_to_unix (dt)); + + if G_UNLIKELY (g_date_time_get_day_of_year (dt) != day_of_year) + g_error ("%04d-%02d-%02d should be day of year %d" + " but comes out as %d", year, month, day, + day_of_year, g_date_time_get_day_of_year (dt)); + + if G_UNLIKELY (g_date_time_get_hour (dt) != 0 || + g_date_time_get_minute (dt) != 0 || + g_date_time_get_seconds (dt) != 0) + g_error ("%04d-%02d-%02d 00:00:00 UTC comes out " + "as %02d:%02d:%02.6f", year, month, day, + g_date_time_get_hour (dt), + g_date_time_get_minute (dt), + g_date_time_get_seconds (dt)); + /* done */ + + /* add 24 hours to unix time */ + unix_time += 24 * 60 * 60; + + /* move day of year forward */ + day_of_year++; + + /* move the week date forward */ + if (++weekday == 8) + { + weekday = 1; /* Sunday -> Monday */ + + /* NOTE: year/month/day is the final day of the week we + * just finished. + * + * If we just finished the last week of last year then + * we are definitely starting the first week of this + * year. + * + * Otherwise, if we're still in this year, but Sunday + * fell on or after December 28 then December 29, 30, 31 + * could be days within the next year's first year. + */ + if (year != week_year || (month == 12 && day >= 28)) + { + /* first week of the new year */ + week_num = 1; + week_year++; + } + else + week_num++; + } + + g_date_time_unref (dt); + } + } + + g_time_zone_unref (timezone); +} + +static void +test_z (void) +{ + GTimeZone *tz; + GDateTime *dt; + gchar *p; + + g_test_bug ("http://bugzilla.gnome.org/642935"); + + tz = g_time_zone_new_identifier ("-08:00"); + g_assert_nonnull (tz); + dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0); + + p = g_date_time_format (dt, "%z"); + g_assert_cmpstr (p, ==, "-0800"); + g_free (p); + + p = g_date_time_format (dt, "%:z"); + g_assert_cmpstr (p, ==, "-08:00"); + g_free (p); + + p = g_date_time_format (dt, "%::z"); + g_assert_cmpstr (p, ==, "-08:00:00"); + g_free (p); + + p = g_date_time_format (dt, "%:::z"); + g_assert_cmpstr (p, ==, "-08"); + g_free (p); + + g_date_time_unref (dt); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("+00:00"); + g_assert_nonnull (tz); + dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0); + p = g_date_time_format (dt, "%:::z"); + g_assert_cmpstr (p, ==, "+00"); + g_free (p); + g_date_time_unref (dt); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("+08:23"); + g_assert_nonnull (tz); + dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0); + p = g_date_time_format (dt, "%:::z"); + g_assert_cmpstr (p, ==, "+08:23"); + g_free (p); + g_date_time_unref (dt); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("+08:23:45"); + g_assert_nonnull (tz); + dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0); + p = g_date_time_format (dt, "%:::z"); + g_assert_cmpstr (p, ==, "+08:23:45"); + g_free (p); + g_date_time_unref (dt); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("-00:15"); + g_assert_nonnull (tz); + dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0); + + p = g_date_time_format (dt, "%z"); + g_assert_cmpstr (p, ==, "-0015"); + g_free (p); + + p = g_date_time_format (dt, "%:z"); + g_assert_cmpstr (p, ==, "-00:15"); + g_free (p); + + p = g_date_time_format (dt, "%::z"); + g_assert_cmpstr (p, ==, "-00:15:00"); + g_free (p); + + p = g_date_time_format (dt, "%:::z"); + g_assert_cmpstr (p, ==, "-00:15"); + g_free (p); + + g_date_time_unref (dt); + g_time_zone_unref (tz); +} + +static void +test_6_days_until_end_of_the_month (void) +{ + GTimeZone *tz; + GDateTime *dt; + gchar *p; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2215"); + +#ifdef G_OS_UNIX + /* This is the footertz string from `Europe/Paris` from tzdata 2020b. It’s + * used by GLib when the tzdata file was compiled with `zic -b slim`, which is + * the default in tzcode ≥2020b. + * + * The `M10.5.0` part indicates that the summer time end transition happens on + * the Sunday (`0`) in the last week (`5`) of October (`10`). That’s 6 days + * before the end of the month, and hence was triggering issue #2215. + * + * References: + * - https://tools.ietf.org/id/draft-murchison-tzdist-tzif-15.html#rfc.section.3.3 + * - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 + */ + tz = g_time_zone_new_identifier ("CET-1CEST,M3.5.0,M10.5.0/3"); +#elif defined (G_OS_WIN32) + tz = g_time_zone_new_identifier ("Romance Standard Time"); +#endif + g_assert_nonnull (tz); + dt = g_date_time_new (tz, 2020, 10, 5, 1, 1, 1); + + p = g_date_time_format (dt, "%Y-%m-%d %H:%M:%S%z"); + /* Incorrect output is "2020-10-05 01:01:01+0100" */ + g_assert_cmpstr (p, ==, "2020-10-05 01:01:01+0200"); + g_free (p); + + g_date_time_unref (dt); + g_time_zone_unref (tz); +} + +static void +test_format_iso8601 (void) +{ + GTimeZone *tz = NULL; + GDateTime *dt = NULL; + gchar *p = NULL; + + tz = g_time_zone_new_utc (); + dt = g_date_time_new (tz, 2019, 6, 26, 15, 1, 5); + p = g_date_time_format_iso8601 (dt); + g_assert_cmpstr (p, ==, "2019-06-26T15:01:05Z"); + g_free (p); + g_date_time_unref (dt); + g_time_zone_unref (tz); + + tz = g_time_zone_new_offset (-60 * 60); + dt = g_date_time_new (tz, 2019, 6, 26, 15, 1, 5); + p = g_date_time_format_iso8601 (dt); + g_assert_cmpstr (p, ==, "2019-06-26T15:01:05-01"); + g_free (p); + g_date_time_unref (dt); + g_time_zone_unref (tz); + + tz = g_time_zone_new_utc (); + dt = g_date_time_new (tz, 2020, 8, 5, 12, 30, 55.000001); + p = g_date_time_format_iso8601 (dt); + g_assert_cmpstr (p, ==, "2020-08-05T12:30:55.000001Z"); + g_free (p); + g_date_time_unref (dt); + g_time_zone_unref (tz); + + tz = g_time_zone_new_utc (); + dt = g_date_time_new (tz, 9, 1, 2, 3, 4, 55); + p = g_date_time_format_iso8601 (dt); + g_assert_cmpstr (p, ==, "0009-01-02T03:04:55Z"); + g_free (p); + g_date_time_unref (dt); + g_time_zone_unref (tz); + + tz = g_time_zone_new_utc (); + dt = g_date_time_new (tz, 9990, 1, 2, 3, 4, 55.000001); + p = g_date_time_format_iso8601 (dt); + g_assert_cmpstr (p, ==, "9990-01-02T03:04:55.000001Z"); + g_free (p); + g_date_time_unref (dt); + g_time_zone_unref (tz); +} + +typedef struct +{ + gboolean utf8_messages; + gboolean utf8_time; +} MixedUtf8TestData; + +static const MixedUtf8TestData utf8_time_non_utf8_messages = { + .utf8_messages = FALSE, + .utf8_time = TRUE +}; + +static const MixedUtf8TestData non_utf8_time_utf8_messages = { + .utf8_messages = TRUE, + .utf8_time = FALSE +}; + +static const MixedUtf8TestData utf8_time_utf8_messages = { + .utf8_messages = TRUE, + .utf8_time = TRUE +}; + +static const MixedUtf8TestData non_utf8_time_non_utf8_messages = { + .utf8_messages = FALSE, + .utf8_time = FALSE +}; + +static gboolean +check_and_set_locale (int category, + const gchar *name) +{ + setlocale (category, name); + if (strstr (setlocale (category, NULL), name) == NULL) + { + g_print ("Unavailable '%s' locale\n", name); + g_test_skip ("required locale not available, skipping tests"); + return FALSE; + } + return TRUE; +} + +static void +test_format_time_mixed_utf8 (gconstpointer data) +{ +#ifdef _MSC_VER + g_test_skip ("setlocale (LC_MESSAGES) asserts on ucrt"); +#else + const MixedUtf8TestData *test_data; + gchar *old_time_locale; + gchar *old_messages_locale; + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2055"); + + test_data = (MixedUtf8TestData *) data; + old_time_locale = g_strdup (setlocale (LC_TIME, NULL)); + old_messages_locale = g_strdup (setlocale (LC_MESSAGES, NULL)); + if (test_data->utf8_time) + { + if (!check_and_set_locale (LC_TIME, "C.UTF-8")) + { + g_free (old_time_locale); + setlocale (LC_MESSAGES, old_messages_locale); + g_free (old_messages_locale); + return; + } + } + else + { + if (!check_and_set_locale (LC_TIME, "de_DE.iso88591")) + { + g_free (old_time_locale); + setlocale (LC_MESSAGES, old_messages_locale); + g_free (old_messages_locale); + return; + } + } + if (test_data->utf8_messages) + { + if (!check_and_set_locale (LC_MESSAGES, "C.UTF-8")) + { + g_free (old_messages_locale); + setlocale (LC_TIME, old_time_locale); + g_free (old_time_locale); + return; + } + } + else + { + if (!check_and_set_locale (LC_MESSAGES, "de_DE.iso88591")) + { + g_free (old_messages_locale); + setlocale (LC_TIME, old_time_locale); + g_free (old_time_locale); + return; + } + } + + if (!test_data->utf8_time) + { + /* March to have März in german */ + TEST_PRINTF_DATE (2020, 3, 1, "%b", "Mär"); + TEST_PRINTF_DATE (2020, 3, 1, "%B", "März"); + } + else + { + TEST_PRINTF_DATE (2020, 3, 1, "%b", "mar"); + TEST_PRINTF_DATE (2020, 3, 1, "%B", "march"); + } + + setlocale (LC_TIME, old_time_locale); + setlocale (LC_MESSAGES, old_messages_locale); + g_free (old_time_locale); + g_free (old_messages_locale); +#endif +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-y2k" +static void +test_strftime (void) +{ +#ifdef __linux__ +#define TEST_FORMAT \ + "a%a A%A b%b B%B c%c C%C d%d e%e F%F g%g G%G h%h H%H I%I j%j m%m M%M " \ + "n%n p%p r%r R%R S%S t%t T%T u%u V%V w%w x%x X%X y%y Y%Y z%z Z%Z %%" + time_t t; + + /* 127997 is prime, 1315005118 is now */ + for (t = 0; t < 1315005118; t += 127997) + { + GDateTime *date_time; + gchar c_str[1000]; + gchar *dt_str; + + date_time = g_date_time_new_from_unix_local (t); + dt_str = g_date_time_format (date_time, TEST_FORMAT); + strftime (c_str, sizeof c_str, TEST_FORMAT, localtime (&t)); + g_assert_cmpstr (c_str, ==, dt_str); + g_date_time_unref (date_time); + g_free (dt_str); + } +#endif +} +#pragma GCC diagnostic pop + +/* Check that g_date_time_format() correctly returns %NULL for format + * placeholders which are not supported in the current locale. */ +static void +test_GDateTime_strftime_error_handling (void) +{ + gchar *oldlocale; +#ifdef G_OS_WIN32 + LCID old_lcid; +#endif + + if (skip_if_running_uninstalled()) + return; + +#ifdef G_OS_WIN32 + old_lcid = GetThreadLocale (); + SetThreadLocale (MAKELCID (MAKELANGID (LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT)); +#endif + + oldlocale = g_strdup (setlocale (LC_ALL, NULL)); + setlocale (LC_ALL, "de_DE.utf-8"); + if (strstr (setlocale (LC_ALL, NULL), "de_DE") != NULL) + { + /* de_DE doesn’t ever write time in 12-hour notation, so %r is + * unsupported for it. */ + TEST_PRINTF_TIME (23, 0, 0, "%r", NULL); + } + else + g_test_skip ("locale de_DE not available, skipping error handling tests"); + setlocale (LC_ALL, oldlocale); + g_free (oldlocale); + +#ifdef G_OS_WIN32 + SetThreadLocale (old_lcid); +#endif +} + +static void +test_find_interval (void) +{ + GTimeZone *tz; + GDateTime *dt; + gint64 u; + gint i1, i2; + +#ifdef G_OS_UNIX + tz = g_time_zone_new_identifier ("America/Toronto"); +#elif defined G_OS_WIN32 + tz = g_time_zone_new_identifier ("Eastern Standard Time"); +#endif + g_assert_nonnull (tz); + dt = g_date_time_new_utc (2010, 11, 7, 1, 30, 0); + u = g_date_time_to_unix (dt); + + i1 = g_time_zone_find_interval (tz, G_TIME_TYPE_STANDARD, u); + i2 = g_time_zone_find_interval (tz, G_TIME_TYPE_DAYLIGHT, u); + + g_assert_cmpint (i1, !=, i2); + + g_date_time_unref (dt); + + dt = g_date_time_new_utc (2010, 3, 14, 2, 0, 0); + u = g_date_time_to_unix (dt); + + i1 = g_time_zone_find_interval (tz, G_TIME_TYPE_STANDARD, u); + g_assert_cmpint (i1, ==, -1); + + g_date_time_unref (dt); + g_time_zone_unref (tz); +} + +static void +test_adjust_time (void) +{ + GTimeZone *tz; + GDateTime *dt; + gint64 u, u2; + gint i1, i2; + +#ifdef G_OS_UNIX + tz = g_time_zone_new_identifier ("America/Toronto"); +#elif defined G_OS_WIN32 + tz = g_time_zone_new_identifier ("Eastern Standard Time"); +#endif + g_assert_nonnull (tz); + dt = g_date_time_new_utc (2010, 11, 7, 1, 30, 0); + u = g_date_time_to_unix (dt); + u2 = u; + + i1 = g_time_zone_find_interval (tz, G_TIME_TYPE_DAYLIGHT, u); + i2 = g_time_zone_adjust_time (tz, G_TIME_TYPE_DAYLIGHT, &u2); + + g_assert_cmpint (i1, ==, i2); + g_assert (u == u2); + + g_date_time_unref (dt); + + dt = g_date_time_new_utc (2010, 3, 14, 2, 30, 0); + u2 = g_date_time_to_unix (dt); + g_date_time_unref (dt); + + dt = g_date_time_new_utc (2010, 3, 14, 3, 0, 0); + u = g_date_time_to_unix (dt); + g_date_time_unref (dt); + + i1 = g_time_zone_adjust_time (tz, G_TIME_TYPE_DAYLIGHT, &u2); + g_assert_cmpint (i1, >=, 0); + g_assert (u == u2); + + g_time_zone_unref (tz); +} + +static void +test_no_header (void) +{ + GTimeZone *tz; + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + tz = g_time_zone_new ("blabla"); + G_GNUC_END_IGNORE_DEPRECATIONS + + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "UTC"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 0); + g_assert (!g_time_zone_is_dst (tz, 0)); + + g_time_zone_unref (tz); +} + +static void +test_no_header_identifier (void) +{ + GTimeZone *tz; + + tz = g_time_zone_new_identifier ("blabla"); + + g_assert_null (tz); +} + +static void +test_posix_parse (void) +{ + GTimeZone *tz; + GDateTime *gdt1, *gdt2; + + /* Check that an unknown zone name falls back to UTC. */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + tz = g_time_zone_new ("nonexistent"); + G_GNUC_END_IGNORE_DEPRECATIONS + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "UTC"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 0); + g_assert (!g_time_zone_is_dst (tz, 0)); + g_time_zone_unref (tz); + + /* An existent zone name should not fall back to UTC. */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + tz = g_time_zone_new ("PST8"); + G_GNUC_END_IGNORE_DEPRECATIONS + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600); + g_assert (!g_time_zone_is_dst (tz, 0)); + g_time_zone_unref (tz); + +/* This fails rules_from_identifier on Unix (though not on Windows) + * but passes anyway because PST8PDT is a zone name. + */ + tz = g_time_zone_new_identifier ("PST8PDT"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8PDT"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600); + g_assert (!g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "PDT"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==,- 7 * 3600); + g_assert (g_time_zone_is_dst (tz, 1)); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("PST8PDT6:32:15"); +#ifdef G_OS_WIN32 + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "PST8PDT6:32:15"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "PST"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, - 8 * 3600); + g_assert (!g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "PDT"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, - 6 * 3600 - 32 *60 - 15); + g_assert (g_time_zone_is_dst (tz, 1)); + gdt1 = g_date_time_new (tz, 2012, 12, 6, 11, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 6, 6, 11, 15, 23.0); + g_assert (!g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, -28800); + g_assert (g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, -23535); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); +#else + g_assert_null (tz); +#endif + g_clear_pointer (&tz, g_time_zone_unref); + + tz = g_time_zone_new_identifier ("NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); + g_assert (!g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "NZDT"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, 13 * 3600); + g_assert (g_time_zone_is_dst (tz, 1)); + gdt1 = g_date_time_new (tz, 2012, 3, 18, 0, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 3, 18, 3, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + gdt1 = g_date_time_new (tz, 2012, 10, 7, 3, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 10, 7, 1, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("NZST-12:00:00NZDT-13:00:00,279,76"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,279,76"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); + g_assert (!g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "NZDT"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, 13 * 3600); + g_assert (g_time_zone_is_dst (tz, 1)); + gdt1 = g_date_time_new (tz, 2012, 3, 18, 0, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 3, 18, 3, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + gdt1 = g_date_time_new (tz, 2012, 10, 7, 3, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 10, 7, 1, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("NZST-12:00:00NZDT-13:00:00,J279,J76"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,J279,J76"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); + g_assert (!g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "NZDT"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, 13 * 3600); + g_assert (g_time_zone_is_dst (tz, 1)); + gdt1 = g_date_time_new (tz, 2012, 3, 18, 0, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 3, 18, 3, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + gdt1 = g_date_time_new (tz, 2012, 10, 7, 3, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 10, 7, 1, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("NZST-12:00:00NZDT-13:00:00,M10.1.0/07:00,M3.3.0/07:00"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,M10.1.0/07:00,M3.3.0/07:00"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); + g_assert (!g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "NZDT"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, 13 * 3600); + g_assert (g_time_zone_is_dst (tz, 1)); + gdt1 = g_date_time_new (tz, 2012, 3, 18, 5, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 3, 18, 8, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + gdt1 = g_date_time_new (tz, 2012, 10, 7, 8, 15, 23.0); + gdt2 = g_date_time_new (tz, 2012, 10, 7, 6, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + gdt1 = g_date_time_new (tz, 1902, 10, 7, 8, 15, 23.0); + gdt2 = g_date_time_new (tz, 1902, 10, 7, 6, 15, 23.0); + g_assert (!g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 43200); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + gdt1 = g_date_time_new (tz, 2142, 10, 7, 8, 15, 23.0); + gdt2 = g_date_time_new (tz, 2142, 10, 7, 6, 15, 23.0); + g_assert (g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 46800); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + gdt1 = g_date_time_new (tz, 3212, 10, 7, 8, 15, 23.0); + gdt2 = g_date_time_new (tz, 3212, 10, 7, 6, 15, 23.0); + g_assert (!g_date_time_is_daylight_savings (gdt1)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt1) / 1000000, ==, 43200); + g_assert (!g_date_time_is_daylight_savings (gdt2)); + g_assert_cmpint (g_date_time_get_utc_offset (gdt2) / 1000000, ==, 43200); + g_date_time_unref (gdt1); + g_date_time_unref (gdt2); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("VIR-00:30"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-00:30"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (30 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + + tz = g_time_zone_new_identifier ("VIR-00:30VID,0/00:00:00,365/23:59:59"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-00:30VID,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (30 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (90 * 60)); + g_assert_true (g_time_zone_is_dst (tz, 1)); + + tz = g_time_zone_new_identifier ("VIR-02:30VID,0/00:00:00,365/23:59:59"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-02:30VID,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (150 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (210 * 60)); + g_assert_true (g_time_zone_is_dst (tz, 1)); + + tz = g_time_zone_new_identifier ("VIR-02:30VID-04:30,0/00:00:00,365/23:59:59"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-02:30VID-04:30,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (150 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (270 * 60)); + g_assert_true (g_time_zone_is_dst (tz, 1)); + + tz = g_time_zone_new_identifier ("VIR-12:00VID-13:00,0/00:00:00,365/23:59:59"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-12:00VID-13:00,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (720 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (780 * 60)); + g_assert_true (g_time_zone_is_dst (tz, 1)); +} + +static void +test_GDateTime_floating_point (void) +{ + GDateTime *dt; + GTimeZone *tz; + + g_test_bug ("http://bugzilla.gnome.org/697715"); + + tz = g_time_zone_new_identifier ("-03:00"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "-03:00"); + dt = g_date_time_new (tz, 2010, 5, 24, 8, 0, 1.000001); + g_time_zone_unref (tz); + g_assert_cmpint (g_date_time_get_microsecond (dt), ==, 1); + g_date_time_unref (dt); +} + +/* Check that g_time_zone_get_identifier() returns the identifier given to + * g_time_zone_new(), or "UTC" if loading the timezone failed. */ +static void +test_identifier (void) +{ + GTimeZone *tz; + gchar *old_tz = g_strdup (g_getenv ("TZ")); + +#ifdef G_OS_WIN32 + const char *recife_tz = "SA Eastern Standard Time"; +#else + const char *recife_tz = "America/Recife"; +#endif + + tz = g_time_zone_new_identifier ("UTC"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC"); + g_time_zone_unref (tz); + + tz = g_time_zone_new_utc (); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC"); + g_time_zone_unref (tz); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + tz = g_time_zone_new ("some rubbish"); + G_GNUC_END_IGNORE_DEPRECATIONS + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC"); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("Z"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "Z"); + g_time_zone_unref (tz); + + tz = g_time_zone_new_identifier ("+03:15"); + g_assert_nonnull (tz); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "+03:15"); + g_time_zone_unref (tz); + + /* System timezone. We can’t change this, but we can at least assert that + * the identifier is non-NULL and non-empty. */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + tz = g_time_zone_new (NULL); + G_GNUC_END_IGNORE_DEPRECATIONS + g_test_message ("System time zone identifier: %s", g_time_zone_get_identifier (tz)); + g_assert_nonnull (g_time_zone_get_identifier (tz)); + g_assert_cmpstr (g_time_zone_get_identifier (tz), !=, ""); + g_time_zone_unref (tz); + + /* Local timezone tests. */ + if (g_setenv ("TZ", recife_tz, TRUE)) + { + tz = g_time_zone_new_local (); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, recife_tz); + g_time_zone_unref (tz); + } + + if (g_setenv ("TZ", "some rubbish", TRUE)) + { + tz = g_time_zone_new_local (); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC"); + g_time_zone_unref (tz); + } + + if (old_tz != NULL) + g_assert_true (g_setenv ("TZ", old_tz, TRUE)); + else + g_unsetenv ("TZ"); + + g_free (old_tz); +} + +/* Test various calls to g_time_zone_new_offset(). */ +static void +test_new_offset (void) +{ + const struct + { + gint32 offset; + gboolean expected_success; + } + vectors[] = + { + { -158400, FALSE }, + { -10000, TRUE }, + { -3600, TRUE }, + { -61, TRUE }, + { -60, TRUE }, + { -59, TRUE }, + { 0, TRUE }, + { 59, TRUE }, + { 60, TRUE }, + { 61, TRUE }, + { 3600, TRUE }, + { 10000, TRUE }, + { 158400, FALSE }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + GTimeZone *tz = NULL; + + g_test_message ("Vector %" G_GSIZE_FORMAT ": %d", i, vectors[i].offset); + + tz = g_time_zone_new_offset (vectors[i].offset); + g_assert_nonnull (tz); + + if (vectors[i].expected_success) + { + g_assert_cmpstr (g_time_zone_get_identifier (tz), !=, "UTC"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, vectors[i].offset); + } + else + { + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "UTC"); + } + + g_time_zone_unref (tz); + } +} + +static void +test_time_zone_parse_rfc8536 (void) +{ +#ifndef G_OS_WIN32 + const gchar *test_files[] = + { + /* Generated with `zic -b slim`; see + * https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1533#note_842235 */ + "Amsterdam-slim", + /* Generated with `zic -b fat` */ + "Amsterdam-fat", + }; + gsize i; + + g_test_summary ("Test parsing time zone files in RFC 8536 version 3 format"); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2129"); + + for (i = 0; i < G_N_ELEMENTS (test_files); i++) + { + gchar *path = NULL; + GTimeZone *tz = NULL; + + path = g_test_build_filename (G_TEST_DIST, "time-zones", test_files[i], NULL); + g_assert_true (g_path_is_absolute (path)); + tz = g_time_zone_new_identifier (path); + g_assert_nonnull (tz); + g_time_zone_unref (tz); + g_free (path); + } +#else + g_test_skip ("RFC 8536 format time zone files are not available on Windows"); +#endif +} + +/* Check GTimeZone instances are cached. */ +static void +test_time_zone_caching (void) +{ + GTimeZone *tz1 = NULL, *tz2 = NULL; + + g_test_summary ("GTimeZone instances are cached"); + + /* Check a specific (arbitrary) timezone. These are only cached while third + * party code holds a ref to at least one instance. */ +#ifdef G_OS_UNIX + tz1 = g_time_zone_new_identifier ("Europe/London"); + g_assert_nonnull (tz1); + tz2 = g_time_zone_new_identifier ("Europe/London"); + g_assert_nonnull (tz2); + g_time_zone_unref (tz1); + g_time_zone_unref (tz2); +#elif defined G_OS_WIN32 + tz1 = g_time_zone_new_identifier ("GMT Standard Time"); + g_assert_nonnull (tz1); + tz2 = g_time_zone_new_identifier ("GMT Standard Time"); + g_assert_nonnull (tz2); + g_time_zone_unref (tz1); + g_time_zone_unref (tz2); +#endif + + /* Only compare pointers */ + g_assert_true (tz1 == tz2); + + /* Check the default timezone, local and UTC. These are cached internally in + * GLib, so should persist even after the last third party reference is + * dropped. + * + * The default timezone could be NULL on some platforms (FreeBSD) if + * `/etc/localtime` is not set correctly. */ + tz1 = g_time_zone_new_identifier (NULL); + if (tz1 != NULL) + { + g_assert_nonnull (tz1); + g_time_zone_unref (tz1); + tz2 = g_time_zone_new_identifier (NULL); + g_assert_nonnull (tz2); + g_time_zone_unref (tz2); + + g_assert_true (tz1 == tz2); + } + + tz1 = g_time_zone_new_utc (); + g_time_zone_unref (tz1); + tz2 = g_time_zone_new_utc (); + g_time_zone_unref (tz2); + + g_assert_true (tz1 == tz2); + + tz1 = g_time_zone_new_local (); + g_time_zone_unref (tz1); + tz2 = g_time_zone_new_local (); + g_time_zone_unref (tz2); + + g_assert_true (tz1 == tz2); +} + + +gint +main (gint argc, + gchar *argv[]) +{ + /* In glibc, LANGUAGE is used as highest priority guess for category value. + * Unset it to avoid interference with tests using setlocale and translation. */ + g_unsetenv ("LANGUAGE"); + + /* GLib uses CHARSET to allow overriding the character set used for all locale + * categories. Unset it to avoid interference with tests. */ + g_unsetenv ("CHARSET"); + + g_test_init (&argc, &argv, NULL); + + /* GDateTime Tests */ + bind_textdomain_codeset ("glib20", "UTF-8"); + + g_test_add_func ("/GDateTime/invalid", test_GDateTime_invalid); + g_test_add_func ("/GDateTime/add_days", test_GDateTime_add_days); + g_test_add_func ("/GDateTime/add_full", test_GDateTime_add_full); + g_test_add_func ("/GDateTime/add_hours", test_GDateTime_add_hours); + g_test_add_func ("/GDateTime/add_minutes", test_GDateTime_add_minutes); + g_test_add_func ("/GDateTime/add_months", test_GDateTime_add_months); + g_test_add_func ("/GDateTime/add_seconds", test_GDateTime_add_seconds); + g_test_add_func ("/GDateTime/add_weeks", test_GDateTime_add_weeks); + g_test_add_func ("/GDateTime/add_years", test_GDateTime_add_years); + g_test_add_func ("/GDateTime/compare", test_GDateTime_compare); + g_test_add_func ("/GDateTime/diff", test_GDateTime_diff); + g_test_add_func ("/GDateTime/equal", test_GDateTime_equal); + g_test_add_func ("/GDateTime/get_day_of_week", test_GDateTime_get_day_of_week); + g_test_add_func ("/GDateTime/get_day_of_month", test_GDateTime_get_day_of_month); + g_test_add_func ("/GDateTime/get_day_of_year", test_GDateTime_get_day_of_year); + g_test_add_func ("/GDateTime/get_hour", test_GDateTime_get_hour); + g_test_add_func ("/GDateTime/get_microsecond", test_GDateTime_get_microsecond); + g_test_add_func ("/GDateTime/get_minute", test_GDateTime_get_minute); + g_test_add_func ("/GDateTime/get_month", test_GDateTime_get_month); + g_test_add_func ("/GDateTime/get_second", test_GDateTime_get_second); + g_test_add_func ("/GDateTime/get_utc_offset", test_GDateTime_get_utc_offset); + g_test_add_func ("/GDateTime/get_year", test_GDateTime_get_year); + g_test_add_func ("/GDateTime/hash", test_GDateTime_hash); + g_test_add_func ("/GDateTime/new_from_unix", test_GDateTime_new_from_unix); + g_test_add_func ("/GDateTime/new_from_unix_utc", test_GDateTime_new_from_unix_utc); + g_test_add_func ("/GDateTime/new_from_unix/overflow", test_GDateTime_new_from_unix_overflow); + g_test_add_func ("/GDateTime/new_from_timeval", test_GDateTime_new_from_timeval); + g_test_add_func ("/GDateTime/new_from_timeval_utc", test_GDateTime_new_from_timeval_utc); + g_test_add_func ("/GDateTime/new_from_timeval/overflow", test_GDateTime_new_from_timeval_overflow); + g_test_add_func ("/GDateTime/new_from_iso8601", test_GDateTime_new_from_iso8601); + g_test_add_func ("/GDateTime/new_from_iso8601/2", test_GDateTime_new_from_iso8601_2); + g_test_add_func ("/GDateTime/new_full", test_GDateTime_new_full); + g_test_add_func ("/GDateTime/now", test_GDateTime_now); + g_test_add_func ("/GDateTime/test-6-days-until-end-of-the-month", test_6_days_until_end_of_the_month); + g_test_add_func ("/GDateTime/printf", test_GDateTime_printf); + g_test_add_func ("/GDateTime/non_utf8_printf", test_non_utf8_printf); + g_test_add_func ("/GDateTime/format_unrepresentable", test_format_unrepresentable); + g_test_add_func ("/GDateTime/format_iso8601", test_format_iso8601); + g_test_add_data_func ("/GDateTime/format_mixed/utf8_time_non_utf8_messages", + &utf8_time_non_utf8_messages, + test_format_time_mixed_utf8); + g_test_add_data_func ("/GDateTime/format_mixed/utf8_time_utf8_messages", + &utf8_time_utf8_messages, + test_format_time_mixed_utf8); + g_test_add_data_func ("/GDateTime/format_mixed/non_utf8_time_non_utf8_messages", + &non_utf8_time_non_utf8_messages, + test_format_time_mixed_utf8); + g_test_add_data_func ("/GDateTime/format_mixed/non_utf8_time_utf8_messages", + &non_utf8_time_utf8_messages, + test_format_time_mixed_utf8); + g_test_add_func ("/GDateTime/strftime", test_strftime); + g_test_add_func ("/GDateTime/strftime/error_handling", test_GDateTime_strftime_error_handling); + g_test_add_func ("/GDateTime/modifiers", test_modifiers); + g_test_add_func ("/GDateTime/month_names", test_month_names); + g_test_add_func ("/GDateTime/to_local", test_GDateTime_to_local); + g_test_add_func ("/GDateTime/to_unix", test_GDateTime_to_unix); + g_test_add_func ("/GDateTime/to_timeval", test_GDateTime_to_timeval); + g_test_add_func ("/GDateTime/to_utc", test_GDateTime_to_utc); + g_test_add_func ("/GDateTime/now_utc", test_GDateTime_now_utc); + g_test_add_func ("/GDateTime/dst", test_GDateTime_dst); + g_test_add_func ("/GDateTime/test_z", test_z); + g_test_add_func ("/GDateTime/test-all-dates", test_all_dates); + g_test_add_func ("/GTimeZone/find-interval", test_find_interval); + g_test_add_func ("/GTimeZone/adjust-time", test_adjust_time); + g_test_add_func ("/GTimeZone/no-header", test_no_header); + g_test_add_func ("/GTimeZone/no-header-identifier", test_no_header_identifier); + g_test_add_func ("/GTimeZone/posix-parse", test_posix_parse); + g_test_add_func ("/GTimeZone/floating-point", test_GDateTime_floating_point); + g_test_add_func ("/GTimeZone/identifier", test_identifier); + g_test_add_func ("/GTimeZone/new-offset", test_new_offset); + g_test_add_func ("/GTimeZone/parse-rfc8536", test_time_zone_parse_rfc8536); + g_test_add_func ("/GTimeZone/caching", test_time_zone_caching); + + return g_test_run (); +} diff --git a/glib/tests/gen-casefold-txt.py b/glib/tests/gen-casefold-txt.py new file mode 100755 index 0000000..e7bafa0 --- /dev/null +++ b/glib/tests/gen-casefold-txt.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# Copyright (C) 1998, 1999 Tom Tromey +# Copyright (C) 2001 Red Hat Software +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . + +""" +gen-casefold-txt.py - Generate test cases for casefolding from Unicode data. +See http://www.unicode.org/Public/UNIDATA/UnicodeCharacterDatabase.html +Usage: + I consider the output of this program to be unrestricted. + Use it as you will. +""" + +import sys +import argparse + + +def main(argv): + parser = argparse.ArgumentParser( + description="Generate test cases for casefolding from Unicode data" + ) + parser.add_argument("UNICODE-VERSION") + parser.add_argument("CaseFolding.txt") + args = parser.parse_args(argv[1:]) + version = getattr(args, "UNICODE-VERSION") + filename = getattr(args, "CaseFolding.txt") + + print( + """\ +# Test cases generated from Unicode {} data +# by gen-casefold-txt.py. Do not edit. +# +# Some special hand crafted tests +# +AaBbCc@@\taabbcc@@ +# +# Now the automatic tests +#""".format( + version + ) + ) + + # Names of fields in the CaseFolding table + CODE, STATUS, MAPPING = range(3) + + with open(filename, encoding="utf-8") as fileobj: + for line in fileobj: + # strip comments and skip empty lines + line = line.split("#", 1)[0].strip() + if not line: + continue + + fields = [f.strip() for f in line.split(";", 3)[:3]] + if len(fields) != 3: + raise SystemExit( + "Entry for %s has wrong number of fields (%d)" + % (fields[CODE], len(fields)) + ) + + status = fields[STATUS] + # skip simple and Turkic mappings + if status in "ST": + continue + + code = chr(int(fields[CODE], 16)) + values = "".join([chr(int(v, 16)) for v in fields[MAPPING].split()]) + print("{}\t{}".format(code, values)) + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/glib/tests/gen-casemap-txt.py b/glib/tests/gen-casemap-txt.py new file mode 100755 index 0000000..62d5963 --- /dev/null +++ b/glib/tests/gen-casemap-txt.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python3 +# Copyright (C) 1998, 1999 Tom Tromey +# Copyright (C) 2001 Red Hat Software +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . + +""" +gen-casemap-txt.py - Generate test cases for case mapping from Unicode data. +See http://www.unicode.org/Public/UNIDATA/UnicodeCharacterDatabase.html +Usage: + I consider the output of this program to be unrestricted. + Use it as you will. +""" + +import sys +import argparse + + +# Disable line length warnings as wrapping the test templates would be hard +# flake8: noqa: E501 + + +def main(argv): + parser = argparse.ArgumentParser( + description="Generate test cases for case mapping from Unicode data" + ) + parser.add_argument("UNICODE-VERSION") + parser.add_argument("UnicodeData.txt") + parser.add_argument("SpecialCasing.txt") + args = parser.parse_args(argv[1:]) + version = getattr(args, "UNICODE-VERSION") + filename_udata = getattr(args, "UnicodeData.txt") + filename_casing = getattr(args, "SpecialCasing.txt") + + # Names of fields in Unicode data table. + ( + CODE, + NAME, + CATEGORY, + COMBINING_CLASSES, + BIDI_CATEGORY, + DECOMPOSITION, + DECIMAL_VALUE, + DIGIT_VALUE, + NUMERIC_VALUE, + MIRRORED, + OLD_NAME, + COMMENT, + UPPER, + LOWER, + TITLE, + ) = range(15) + + # Names of fields in the SpecialCasing table + CASE_CODE, CASE_LOWER, CASE_TITLE, CASE_UPPER, CASE_CONDITION = range(5) + + upper = {} + title = {} + lower = {} + + def make_hex(codes): + """Converts a string of white space separated code points encoded as + hex values to a Unicode string. Any extra white space is ignored. + """ + return "".join([chr(int(c, 16)) for c in codes.split()]) + + def process_one(code, fields): + type_ = fields[CATEGORY] + if type_ == "Ll": + upper[code] = make_hex(fields[UPPER]) + lower[code] = chr(code) + title[code] = make_hex(fields[TITLE]) + elif type_ == "Lu": + lower[code] = make_hex(fields[LOWER]) + upper[code] = chr(code) + title[code] = make_hex(fields[TITLE]) + elif type_ == "Lt": + upper[code] = make_hex(fields[UPPER]) + lower[code] = make_hex(fields[LOWER]) + title[code] = make_hex(fields[LOWER]) + + with open(filename_udata, encoding="utf-8") as fileobj: + last_code = -1 + for line in fileobj: + line = line.strip() + fields = [f.strip() for f in line.split(";")] + if len(fields) != 15: + raise SystemExit( + "Entry for %s has wrong number of fields (%d)" + % (fields[CODE], len(fields)) + ) + + code = int(fields[CODE], 16) + + if code > last_code + 1: + # Found a gap + if fields[NAME].endswith("Last>"): + # Fill the gap with the last character read, + # since this was a range specified in the char database + gfields = fields + else: + # The gap represents undefined characters. Only the type + # matters. + gfields = [ + "", + "", + "Cn", + "0", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ] + + last_code += 1 + while last_code < code: + gfields[CODE] = "%04x" % last_code + process_one(last_code, gfields) + last_code += 1 + + process_one(code, fields) + last_code = code + + with open(filename_casing, encoding="utf-8") as fileobj: + last_code = -1 + for line in fileobj: + # strip comments and skip empty lines + line = line.split("#", 1)[0].strip() + if not line: + continue + + # all lines end with ";" so just remove it + line = line.rstrip(";").rstrip() + fields = [f.strip() for f in line.split(";")] + if len(fields) not in (4, 5): + raise SystemExit( + "Entry for %s has wrong number of fields (%d)" + % (fields[CASE_CODE], len(fields)) + ) + + if len(fields) == 5: + # Ignore conditional special cases - we'll handle them manually + continue + + code = int(fields[CASE_CODE], 16) + + upper[code] = make_hex(fields[CASE_UPPER]) + lower[code] = make_hex(fields[CASE_LOWER]) + title[code] = make_hex(fields[CASE_TITLE]) + + print_tests(version, upper, title, lower) + + +def print_tests(version, upper, title, lower): + print( + """\ +# Test cases generated from Unicode {} data +# by gen-casemap-txt.py. Do not edit. +# +# Some special hand crafted tests +# +tr_TR\ti\ti\t\u0130\t\u0130\t# i => LATIN CAPITAL LETTER I WITH DOT ABOVE +tr_TR\tI\t\u0131\tI\tI\t# I => LATIN SMALL LETTER DOTLESS I +tr_TR\tI\u0307\ti\tI\u0307\tI\u0307\t# I => LATIN SMALL LETTER DOTLESS I +tr_TR.UTF-8\ti\ti\t\u0130\t\u0130\t# i => LATIN CAPITAL LETTER I WITH DOT ABOVE +tr_TR.UTF-8\tI\t\u0131\tI\tI\t# I => LATIN SMALL LETTER DOTLESS I +tr_TR.UTF-8\tI\u0307\ti\tI\u0307\tI\u0307\t# I => LATIN SMALL LETTER DOTLESS I +# Test reordering of YPOGEGRAMMENI across other accents +\t\u03b1\u0345\u0314\t\u03b1\u0345\u0314\t\u0391\u0345\u0314\t\u0391\u0314\u0399\t +\t\u03b1\u0314\u0345\t\u03b1\u0314\u0345\t\u0391\u0314\u0345\t\u0391\u0314\u0399\t +# Handling of final and nonfinal sigma +\tΜΆΙΟΣ μάιος Μάιος ΜΆΙΟΣ \t +\tΜΆΙΟΣ μάιος Μάιος ΜΆΙΟΣ\t +\tΣΙΓΜΑ σιγμα Σιγμα ΣΙΓΜΑ\t +# Lithuanian rule of i followed by letter with dot. Not at all sure +# about the titlecase part here +lt_LT\ti\u0117\ti\u0117\tIe\tIE\t +lt_LT\tie\u0307\tie\u0307\tIe\tIE\t +lt_LT\t\u00cc\ti\u0307\u0300\t\u00cc\t\u00cc\t # LATIN CAPITAL LETTER I WITH GRAVE +lt_LT\t\u00CD\ti\u0307\u0301\t\u00CD\t\u00CD\t # LATIN CAPITAL LETTER I WITH ACUTE +lt_LT\t\u0128\ti\u0307\u0303\t\u0128\t\u0128\t # LATIN CAPITAL LETTER I WITH TILDE +lt_LT\tI\u0301\ti\u0307\u0301\tI\u0301\tI\u0301\t # LATIN CAPITAL LETTER I (with acute accent) +lt_LT\tI\u0300\ti\u0307\u0300\tI\u0300\tI\u0300\t # LATIN CAPITAL LETTER I (with grave accent) +lt_LT\tI\u0303\ti\u0307\u0303\tI\u0303\tI\u0303\t # LATIN CAPITAL LETTER I (with tilde above) +lt_LT\tI\u0328\u0301\ti\u0307\u0328\u0301\tI\u0328\u0301\tI\u0328\u0301\t # LATIN CAPITAL LETTER I (with ogonek and acute accent) +lt_LT\tJ\u0301\tj\u0307\u0301\tJ\u0301\tJ\u0301\t # LATIN CAPITAL LETTER J (with acute accent) +lt_LT\t\u012e\u0301\t\u012f\u0307\u0301\t\u012e\u0301\t\u012e\u0301\t # LATIN CAPITAL LETTER I WITH OGONEK (with acute accent) +lt_LT.UTF-8\ti\u0117\ti\u0117\tIe\tIE\t +lt_LT.UTF-8\tie\u0307\tie\u0307\tIe\tIE\t +lt_LT.UTF-8\t\u00cc\ti\u0307\u0300\t\u00cc\t\u00cc\t # LATIN CAPITAL LETTER I WITH GRAVE +lt_LT.UTF-8\t\u00CD\ti\u0307\u0301\t\u00CD\t\u00CD\t # LATIN CAPITAL LETTER I WITH ACUTE +lt_LT.UTF-8\t\u0128\ti\u0307\u0303\t\u0128\t\u0128\t # LATIN CAPITAL LETTER I WITH TILDE +lt_LT.UTF-8\tI\u0301\ti\u0307\u0301\tI\u0301\tI\u0301\t # LATIN CAPITAL LETTER I (with acute accent) +lt_LT.UTF-8\tI\u0300\ti\u0307\u0300\tI\u0300\tI\u0300\t # LATIN CAPITAL LETTER I (with grave accent) +lt_LT.UTF-8\tI\u0303\ti\u0307\u0303\tI\u0303\tI\u0303\t # LATIN CAPITAL LETTER I (with tilde above) +lt_LT.UTF-8\tI\u0328\u0301\ti\u0307\u0328\u0301\tI\u0328\u0301\tI\u0328\u0301\t # LATIN CAPITAL LETTER I (with ogonek and acute accent) +lt_LT.UTF-8\tJ\u0301\tj\u0307\u0301\tJ\u0301\tJ\u0301\t # LATIN CAPITAL LETTER J (with acute accent) +lt_LT.UTF-8\t\u012e\u0301\t\u012f\u0307\u0301\t\u012e\u0301\t\u012e\u0301\t # LATIN CAPITAL LETTER I WITH OGONEK (with acute accent) +# Special case not at initial position +\ta\ufb04\ta\ufb04\tAffl\tAFFL\t# FB04 +# +# Now the automatic tests +#""".format( + version + ) + ) + + for i in range(0x10FFFF): + if i == 0x3A3: + # Greek sigma needs special tests + continue + + up = upper.get(i, "") + lo = lower.get(i, "") + ti = title.get(i, "") + + if any([up, lo, ti]): + print("\t%s\t%s\t%s\t%s\t# %4X" % (chr(i), lo, ti, up, i)) + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/glib/tests/getpwuid-preload.c b/glib/tests/getpwuid-preload.c new file mode 100644 index 0000000..71df9cb --- /dev/null +++ b/glib/tests/getpwuid-preload.c @@ -0,0 +1,45 @@ +/* GLIB - Library of useful routines for C programming + * + * Copyright (C) 2020 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include +#include +#include +#include + +static struct passwd my_pw; + +/* This is used in gutils.c used to make sure utility functions + * handling user information do not crash on bad data (for example + * caused by getpwuid returning some NULL elements. + */ +struct passwd * +getpwuid (uid_t uid) +{ + static struct passwd *(*real_getpwuid) (uid_t); + struct passwd *pw; + + if (real_getpwuid == NULL) + real_getpwuid = dlsym (RTLD_NEXT, "getpwuid"); + + pw = real_getpwuid (uid); + my_pw = *pw; + my_pw.pw_name = NULL; + return &my_pw; +} diff --git a/glib/tests/gpoll.c b/glib/tests/gpoll.c new file mode 100644 index 0000000..fe7c395 --- /dev/null +++ b/glib/tests/gpoll.c @@ -0,0 +1,624 @@ +/* Unit test for W32 version of g_poll() + * + * Copyright © 2017 РуÑлан Ижбулатов + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include + +#define NUM_POLLEES 999 +#define NUM_POLLFDS 1000 + +#define ASYNC_CONNECT_OK(r) (r == 0 || (r < 0 && GetLastError () == WSAEWOULDBLOCK)) + +#define REPEAT 1 + +static void +init_networking (void) +{ + WSADATA wsadata; + + if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0) + g_error ("Windows Sockets could not be initialized"); +} + +static void +prepare_fds (SOCKET sockets[], + GPollFD fds[], + int num_pollees) +{ + gint i; + + for (i = 0; i < num_pollees; i++) + { + fds[i].fd = (gintptr) WSACreateEvent (); + g_assert (WSAEventSelect (sockets[i], (HANDLE) fds[i].fd, FD_READ | FD_CLOSE) == 0); + } +} + +static void +reset_fds (GPollFD fds[], + int num_pollees) +{ + gint i; + + for (i = 0; i < num_pollees; i++) + { + WSAResetEvent ((HANDLE) fds[i].fd); + fds[i].events = G_IO_IN | G_IO_OUT | G_IO_ERR; + fds[i].revents = 0; + } +} + +static void +reset_fds_msg (GPollFD fds[], + int num_pollfds) +{ + fds[num_pollfds - 1].fd = G_WIN32_MSG_HANDLE; + fds[num_pollfds - 1].events = G_IO_IN; + fds[num_pollfds - 1].revents = 0; +} + +static void +check_fds (SOCKET sockets[], + GPollFD fds[], + int num_pollees) +{ + gint i; + + for (i = 0; i < num_pollees; i++) + { + if (fds[i].revents != 0) + { + WSANETWORKEVENTS events; + g_assert (WSAEnumNetworkEvents (sockets[i], 0, &events) == 0); + + fds[i].revents = 0; + if (events.lNetworkEvents & (FD_READ | FD_ACCEPT)) + fds[i].revents |= G_IO_IN; + + if (events.lNetworkEvents & FD_WRITE) + fds[i].revents |= G_IO_OUT; + else + { + /* We have called WSAEnumNetworkEvents() above but it didn't + * set FD_WRITE. + */ + if (events.lNetworkEvents & FD_CONNECT) + { + if (events.iErrorCode[FD_CONNECT_BIT] == 0) + fds[i].revents |= G_IO_OUT; + else + fds[i].revents |= (G_IO_HUP | G_IO_ERR); + } + if (fds[i].revents == 0 && (events.lNetworkEvents & (FD_CLOSE))) + fds[i].revents |= G_IO_HUP; + } + } + } +} + +static void +prepare_sockets (SOCKET sockets[], + SOCKET opp_sockets[], + GPollFD fds[], + int num_pollees) +{ + gint i; + SOCKET server; + struct sockaddr_in sa; + unsigned long ul = 1; + int sa_size; + int r; + + server = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + g_assert (server != INVALID_SOCKET); + + memset(&sa, 0, sizeof sa); + + sa.sin_family = AF_INET; + sa.sin_port = 0; + sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + sa_size = sizeof (sa); + + g_assert (bind (server, (const struct sockaddr *) &sa, sa_size) == 0); + g_assert (getsockname (server, (struct sockaddr *) &sa, &sa_size) == 0); + g_assert (listen (server, 1) == 0); + + for (i = 0; i < num_pollees; i++) + { + opp_sockets[i] = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + g_assert (opp_sockets[i] != INVALID_SOCKET); + g_assert (ioctlsocket (opp_sockets[i], FIONBIO, &ul) == 0); + + r = connect (opp_sockets[i], (const struct sockaddr *) &sa, sizeof (sa)); + g_assert (ASYNC_CONNECT_OK (r)); + + sockets[i] = accept (server, NULL, NULL); + g_assert (sockets[i] != INVALID_SOCKET); + g_assert (ioctlsocket (sockets[i], FIONBIO, &ul) == 0); + } + + closesocket (server); +} + +static void +cleanup_sockets (SOCKET sockets[], + SOCKET opp_sockets[], + int num_pollees) +{ + gint i; + + for (i = 0; i < num_pollees; i++) + { + closesocket (sockets[i]); + closesocket (opp_sockets[i]); + } +} + +static void +bucketize (gint64 val, + gint buckets[], + gint64 bucket_limits[], + gint count) +{ + gint i; + + if (val > bucket_limits[count - 1]) + { + buckets[count - 1] += 1; + return; + } + + for (i = count - 1; i > 0; i--) + if (val < bucket_limits[i] && val >= bucket_limits[i - 1]) + { + buckets[i] += 1; + return; + } + + buckets[0] += 1; +} + +static void +print_buckets (gint buckets[], + gint64 bucket_limits[], + gint count) +{ + gint i; + + for (i = 0; i < count; i++) + if (i < count - 1) + g_print ("%-4lld-%4lld|", i == 0 ? 0 : bucket_limits[i - 1], bucket_limits[i] - 1); + else + g_print (" >= %-4lld|", bucket_limits[i - 1]); + + g_print ("\n"); + + for (i = 0; i < count; i++) + { + gint len; + gint padding; + gint j; + if (buckets[i] < 10) + len = 1; + else if (buckets[i] < 100) + len = 2; + else if (buckets[i] < 1000) + len = 3; + else + len = 4; + padding = 9 - len; + for (j = 0; j < padding / 2; j++) + g_print (" "); + if (buckets[i] != 0) + g_print ("%*d", len, buckets[i]); + else + g_print (" "); + for (j = padding / 2; j < padding; j++) + g_print (" "); + g_print (" "); + } + + g_print ("\n\n"); +} + +static void +test_gpoll (void) +{ + SOCKET sockets[NUM_POLLEES]; + GPollFD fds[NUM_POLLFDS]; + SOCKET opp_sockets[NUM_POLLEES]; + gint i; + gint activatable; + gint64 times[REPEAT][2]; +#define BUCKET_COUNT 25 + gint64 bucket_limits[BUCKET_COUNT] = {3, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100, 120, 150, 180, 220, 280, 350, 450, 600, 800, 1000}; + gint buckets[BUCKET_COUNT]; + gint64 times_avg = 0, times_min = G_MAXINT64, times_max = 0; + + prepare_sockets (sockets, opp_sockets, fds, NUM_POLLEES); + prepare_fds (sockets, fds, NUM_POLLEES); + + times_avg = 0; + times_min = G_MAXINT64; + times_max = 0; + memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); + + for (i = 0; i < REPEAT; i++) + { + gint r; + gint64 diff; + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + times[i][0] = g_get_monotonic_time (); + r = g_poll (fds, NUM_POLLFDS, 0); + times[i][1] = g_get_monotonic_time (); + g_assert (r == 0); + diff = times[i][1] - times[i][0]; + if (times_min > diff) + times_min = diff; + if (times_max < diff) + times_max = diff; + times_avg += diff; + bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); + } + + times_avg /= NUM_POLLEES; + g_print ("\nempty poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); + print_buckets (buckets, bucket_limits, BUCKET_COUNT); + + times_avg = 0; + times_min = G_MAXINT64; + times_max = 0; + memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); + + activatable = 0; + + for (i = 0; i < REPEAT; i++) + { + gint r, s, v, t; + gint64 diff; + MSG msg; + gboolean found_app; + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + s = send (opp_sockets[activatable], (const char *) &t, 1, 0); + g_assert (PostMessage (NULL, WM_APP, 1, 2)); + /* This is to ensure that all sockets catch up, otherwise some might not poll active */ + g_usleep (G_USEC_PER_SEC / 1000); + + times[i][0] = g_get_monotonic_time (); + r = g_poll (fds, NUM_POLLFDS, 1000); + times[i][1] = g_get_monotonic_time (); + + check_fds (sockets, fds, NUM_POLLEES); + v = recv (sockets[activatable], (char *) &t, 1, 0); + found_app = FALSE; + while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2) + found_app = TRUE; + g_assert (s == 1); + g_assert (r == 2); + g_assert (v == 1); + g_assert (found_app); + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + r = g_poll (fds, NUM_POLLFDS, 0); + check_fds (sockets, fds, NUM_POLLEES); + g_assert (r == 0); + diff = times[i][1] - times[i][0]; + if (times_min > diff) + times_min = diff; + if (times_max < diff) + times_max = diff; + times_avg += diff; + activatable = (activatable + 1) % NUM_POLLEES; + bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); + } + + times_avg /= NUM_POLLEES; + g_print ("1-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); + print_buckets (buckets, bucket_limits, BUCKET_COUNT); + + times_avg = 0; + times_min = G_MAXINT64; + times_max = 0; + memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); + + activatable = 0; + + for (i = 0; i < REPEAT; i++) + { + gint r, s, v, t; + gint64 diff; + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + s = send (opp_sockets[activatable], (const char *) &t, 1, 0); + + g_usleep (G_USEC_PER_SEC / 1000); + + times[i][0] = g_get_monotonic_time (); + r = g_poll (fds, NUM_POLLFDS, 1000); + times[i][1] = g_get_monotonic_time (); + + check_fds (sockets, fds, NUM_POLLEES); + v = recv (sockets[activatable], (char *) &t, 1, 0); + g_assert (s == 1); + g_assert (r == 1); + g_assert (v == 1); + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + r = g_poll (fds, NUM_POLLFDS, 0); + check_fds (sockets, fds, NUM_POLLEES); + g_assert (r == 0); + + diff = times[i][1] - times[i][0]; + if (times_min > diff) + times_min = diff; + if (times_max < diff) + times_max = diff; + times_avg += diff; + activatable = (activatable + 1) % NUM_POLLEES; + bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); + } + + times_avg /= NUM_POLLEES; + g_print ("1-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); + print_buckets (buckets, bucket_limits, BUCKET_COUNT); + + times_avg = 0; + times_min = G_MAXINT64; + times_max = 0; + memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); + + for (i = 0; i < REPEAT; i++) + { + gint r, s, v, t; + gint64 diff; + gint j; + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + s = v = 0; + + for (j = 0; j < NUM_POLLEES / 2; j++) + s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0; + + g_usleep (G_USEC_PER_SEC / 1000); + + times[i][0] = g_get_monotonic_time (); + r = g_poll (fds, NUM_POLLFDS, 1000); + times[i][1] = g_get_monotonic_time (); + check_fds (sockets, fds, NUM_POLLEES); + for (j = 0; j < NUM_POLLEES / 2; j++) + v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0; + g_assert (s == NUM_POLLEES / 2); + g_assert (r == NUM_POLLEES / 2); + g_assert (v == NUM_POLLEES / 2); + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + r = g_poll (fds, NUM_POLLFDS, 0); + check_fds (sockets, fds, NUM_POLLEES); + g_assert (r == 0); + + diff = times[i][1] - times[i][0]; + if (times_min > diff) + times_min = diff; + if (times_max < diff) + times_max = diff; + times_avg += diff; + bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); + } + + times_avg /= NUM_POLLEES; + g_print ("half-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); + print_buckets (buckets, bucket_limits, BUCKET_COUNT); + + times_avg = 0; + times_min = G_MAXINT64; + times_max = 0; + memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); + + for (i = 0; i < REPEAT; i++) + { + gint r, s, v, t; + gint64 diff; + gint j; + MSG msg; + gboolean found_app; + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + s = v = 0; + + for (j = 0; j < NUM_POLLEES / 2; j++) + s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0; + g_assert (PostMessage (NULL, WM_APP, 1, 2)); + + /* This is to ensure that all sockets catch up, otherwise some might not poll active */ + g_usleep (G_USEC_PER_SEC / 1000); + + times[i][0] = g_get_monotonic_time (); + r = g_poll (fds, NUM_POLLFDS, 1000); + times[i][1] = g_get_monotonic_time (); + check_fds (sockets, fds, NUM_POLLEES); + for (j = 0; j < NUM_POLLEES / 2; j++) + v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0; + found_app = FALSE; + while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2) + found_app = TRUE; + g_assert (s == NUM_POLLEES / 2); + g_assert (r == NUM_POLLEES / 2 + 1); + g_assert (v == NUM_POLLEES / 2); + g_assert (found_app); + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + r = g_poll (fds, NUM_POLLFDS, 0); + check_fds (sockets, fds, NUM_POLLEES); + g_assert (r == 0); + + diff = times[i][1] - times[i][0]; + if (times_min > diff) + times_min = diff; + if (times_max < diff) + times_max = diff; + times_avg += diff; + bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); + } + + times_avg /= NUM_POLLEES; + g_print ("half-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); + print_buckets (buckets, bucket_limits, BUCKET_COUNT); + + times_avg = 0; + times_min = G_MAXINT64; + times_max = 0; + memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); + + for (i = 0; i < REPEAT; i++) + { + gint r, s, v, t; + gint64 diff; + gint j; + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + s = v = 0; + + for (j = 0; j < NUM_POLLEES; j++) + s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0; + + g_usleep (G_USEC_PER_SEC / 1000); + + times[i][0] = g_get_monotonic_time (); + r = g_poll (fds, NUM_POLLFDS, 1000); + times[i][1] = g_get_monotonic_time (); + check_fds (sockets, fds, NUM_POLLEES); + for (j = 0; j < NUM_POLLEES; j++) + v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0; + g_assert (s == NUM_POLLEES); + g_assert (r == NUM_POLLEES); + g_assert (v == NUM_POLLEES); + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + r = g_poll (fds, NUM_POLLFDS, 0); + check_fds (sockets, fds, NUM_POLLEES); + g_assert (r == 0); + + diff = times[i][1] - times[i][0]; + if (times_min > diff) + times_min = diff; + if (times_max < diff) + times_max = diff; + times_avg += diff; + bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); + } + + times_avg /= NUM_POLLEES; + g_print ("%d-socket poll time: \n%4lldns - %4lldns, average %4lldns\n", NUM_POLLEES, times_min, times_max, times_avg); + print_buckets (buckets, bucket_limits, BUCKET_COUNT); + + activatable = 0; + times_avg = 0; + times_min = G_MAXINT64; + times_max = 0; + memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); + + for (i = 0; i < REPEAT; i++) + { + gint r, s, v, t; + gint64 diff; + gint j; + MSG msg; + gboolean found_app; + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + s = v = 0; + + for (j = 0; j < activatable; j++) + s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0; + g_assert (PostMessage (NULL, WM_APP, 1, 2)); + + g_usleep (G_USEC_PER_SEC / 1000); + + times[i][0] = g_get_monotonic_time (); + r = g_poll (fds, NUM_POLLFDS, 1000); + times[i][1] = g_get_monotonic_time (); + check_fds (sockets, fds, NUM_POLLEES); + for (j = 0; j < activatable; j++) + v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0; + found_app = FALSE; + while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2) + found_app = TRUE; + g_assert (s == activatable); + g_assert (r == activatable + 1); + g_assert (v == activatable); + g_assert (found_app); + + reset_fds (fds, NUM_POLLEES); + reset_fds_msg (fds, NUM_POLLFDS); + r = g_poll (fds, NUM_POLLFDS, 0); + check_fds (sockets, fds, NUM_POLLEES); + g_assert (r == 0); + + diff = times[i][1] - times[i][0]; + if (times_min > diff) + times_min = diff; + if (times_max < diff) + times_max = diff; + times_avg += diff; + bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); + activatable = (activatable + 1) % NUM_POLLEES; + } + + times_avg /= NUM_POLLEES; + g_print ("variable socket number + msg poll time: \n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); + print_buckets (buckets, bucket_limits, BUCKET_COUNT); + + cleanup_sockets (sockets, opp_sockets, NUM_POLLEES); +} + +int +main (int argc, + char *argv[]) +{ + int result; + GMainContext *ctx; + + g_test_init (&argc, &argv, NULL); + init_networking (); + ctx = g_main_context_new (); + + g_test_add_func ("/gpoll/gpoll", test_gpoll); + + result = g_test_run (); + + g_main_context_unref (ctx); + + return result; +} diff --git a/glib/tests/gutils-user-database.c b/glib/tests/gutils-user-database.c new file mode 100644 index 0000000..89a0e0b --- /dev/null +++ b/glib/tests/gutils-user-database.c @@ -0,0 +1,42 @@ +/* + * Copyright © 2020 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +#include + +/* The function g_get_user_database_entry() is called from the + * g_get_real_name(), g_get_user_name() and g_build_home_dir() + * functions. These two calls are here just to invoke the code + * paths. The real-test is the ld_preload used to inject the + * NULL in place of pw->pw_name. + */ +static void +test_get_user_database_entry (void) +{ + const gchar *r = NULL; + + r = g_get_user_name (); + g_assert_nonnull (r); + + r = g_get_real_name (); + g_assert_nonnull (r); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gutils/get_user_database_entry", test_get_user_database_entry); + + return g_test_run (); +} diff --git a/glib/tests/guuid.c b/glib/tests/guuid.c new file mode 100644 index 0000000..bfe2795 --- /dev/null +++ b/glib/tests/guuid.c @@ -0,0 +1,70 @@ +/* guuid.c + * + * Copyright (C) 2013-2015, 2017 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#undef G_DISABLE_ASSERT + +#include +#include + +static void +test_guuid_string (void) +{ + g_assert_false (g_uuid_string_is_valid ("00010203-0405-0607-0809")); + g_assert_false (g_uuid_string_is_valid ("zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz")); + g_assert_false (g_uuid_string_is_valid ("000102030405060708090a0b0c0d0e0f")); + g_assert_false (g_uuid_string_is_valid ("{urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6}")); + g_assert_false (g_uuid_string_is_valid ("urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6")); + + g_assert_true (g_uuid_string_is_valid ("00010203-0405-0607-0809-0a0b0c0d0e0f")); + g_assert_true (g_uuid_string_is_valid ("7d444840-9dc0-11d1-b245-5ffdce74fad2")); + g_assert_true (g_uuid_string_is_valid ("e902893a-9d22-3c7e-a7b8-d6e313b71d9f")); + g_assert_true (g_uuid_string_is_valid ("6ba7b810-9dad-11d1-80b4-00c04fd430c8")); +} + +static void +test_guuid_random (void) +{ + gchar *str1, *str2; + + str1 = g_uuid_string_random (); + g_assert_cmpuint (strlen (str1), ==, 36); + g_assert_true (g_uuid_string_is_valid (str1)); + + str2 = g_uuid_string_random (); + g_assert_cmpuint (strlen (str2), ==, 36); + g_assert_true (g_uuid_string_is_valid (str2)); + g_assert_cmpstr (str1, !=, str2); + + g_free (str1); + g_free (str2); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + /* GUuid Tests */ + g_test_add_func ("/uuid/string", test_guuid_string); + g_test_add_func ("/uuid/random", test_guuid_random); + + return g_test_run (); +} diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c new file mode 100644 index 0000000..0110f26 --- /dev/null +++ b/glib/tests/gvariant.c @@ -0,0 +1,5206 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include +#include +#include +#include + +#define BASIC "bynqiuxthdsog?" +#define N_BASIC (G_N_ELEMENTS (BASIC) - 1) + +#define INVALIDS "cefjklpwz&@^$" +#define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1) + +/* see comment in gvariant-serialiser.c about this madness. + * + * we use this to get testing of non-strictly-aligned GVariant instances + * on machines that can tolerate it. it is necessary to support this + * because some systems have malloc() that returns non-8-aligned + * pointers. it is necessary to have special support in the tests + * because on most machines malloc() is 8-aligned. + */ +#define ALIGN_BITS (sizeof (struct { char a; union { \ + guint64 x; void *y; gdouble z; } b; }) - 9) + +static gboolean +randomly (gdouble prob) +{ + return g_test_rand_double_range (0, 1) < prob; +} + +/* corecursion */ +static GVariantType * +append_tuple_type_string (GString *, GString *, gboolean, gint); + +/* append a random GVariantType to a GString + * append a description of the type to another GString + * return what the type is + */ +static GVariantType * +append_type_string (GString *string, + GString *description, + gboolean definite, + gint depth) +{ + if (!depth-- || randomly (0.3)) + { + gchar b = BASIC[g_test_rand_int_range (0, N_BASIC - definite)]; + g_string_append_c (string, b); + g_string_append_c (description, b); + + switch (b) + { + case 'b': + return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN); + case 'y': + return g_variant_type_copy (G_VARIANT_TYPE_BYTE); + case 'n': + return g_variant_type_copy (G_VARIANT_TYPE_INT16); + case 'q': + return g_variant_type_copy (G_VARIANT_TYPE_UINT16); + case 'i': + return g_variant_type_copy (G_VARIANT_TYPE_INT32); + case 'u': + return g_variant_type_copy (G_VARIANT_TYPE_UINT32); + case 'x': + return g_variant_type_copy (G_VARIANT_TYPE_INT64); + case 't': + return g_variant_type_copy (G_VARIANT_TYPE_UINT64); + case 'h': + return g_variant_type_copy (G_VARIANT_TYPE_HANDLE); + case 'd': + return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE); + case 's': + return g_variant_type_copy (G_VARIANT_TYPE_STRING); + case 'o': + return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH); + case 'g': + return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE); + case '?': + return g_variant_type_copy (G_VARIANT_TYPE_BASIC); + default: + g_assert_not_reached (); + } + } + else + { + GVariantType *result; + + switch (g_test_rand_int_range (0, definite ? 5 : 7)) + { + case 0: + { + GVariantType *element; + + g_string_append_c (string, 'a'); + g_string_append (description, "a of "); + element = append_type_string (string, description, + definite, depth); + result = g_variant_type_new_array (element); + g_variant_type_free (element); + } + + g_assert_true (g_variant_type_is_array (result)); + break; + + case 1: + { + GVariantType *element; + + g_string_append_c (string, 'm'); + g_string_append (description, "m of "); + element = append_type_string (string, description, + definite, depth); + result = g_variant_type_new_maybe (element); + g_variant_type_free (element); + } + + g_assert_true (g_variant_type_is_maybe (result)); + break; + + case 2: + result = append_tuple_type_string (string, description, + definite, depth); + + g_assert_true (g_variant_type_is_tuple (result)); + break; + + case 3: + { + GVariantType *key, *value; + + g_string_append_c (string, '{'); + g_string_append (description, "e of ["); + key = append_type_string (string, description, definite, 0); + g_string_append (description, ", "); + value = append_type_string (string, description, definite, depth); + g_string_append_c (description, ']'); + g_string_append_c (string, '}'); + result = g_variant_type_new_dict_entry (key, value); + g_variant_type_free (key); + g_variant_type_free (value); + } + + g_assert_true (g_variant_type_is_dict_entry (result)); + break; + + case 4: + g_string_append_c (string, 'v'); + g_string_append_c (description, 'V'); + result = g_variant_type_copy (G_VARIANT_TYPE_VARIANT); + g_assert_true (g_variant_type_equal (result, G_VARIANT_TYPE_VARIANT)); + break; + + case 5: + g_string_append_c (string, '*'); + g_string_append_c (description, 'S'); + result = g_variant_type_copy (G_VARIANT_TYPE_ANY); + g_assert_true (g_variant_type_equal (result, G_VARIANT_TYPE_ANY)); + break; + + case 6: + g_string_append_c (string, 'r'); + g_string_append_c (description, 'R'); + result = g_variant_type_copy (G_VARIANT_TYPE_TUPLE); + g_assert_true (g_variant_type_is_tuple (result)); + break; + + default: + g_assert_not_reached (); + } + + return result; + } +} + +static GVariantType * +append_tuple_type_string (GString *string, + GString *description, + gboolean definite, + gint depth) +{ + GVariantType *result, *other_result; + GVariantType **types; + gsize i, size; + + g_string_append_c (string, '('); + g_string_append (description, "t of ["); + + size = g_test_rand_int_range (0, 20); + types = g_new (GVariantType *, size + 1); + + for (i = 0; i < size; i++) + { + types[i] = append_type_string (string, description, definite, depth); + + if (i < size - 1) + g_string_append (description, ", "); + } + + types[i] = NULL; + + g_string_append_c (description, ']'); + g_string_append_c (string, ')'); + + result = g_variant_type_new_tuple ((gpointer) types, size); + other_result = g_variant_type_new_tuple ((gpointer) types, -1); + g_assert_true (g_variant_type_equal (result, other_result)); + g_variant_type_free (other_result); + for (i = 0; i < size; i++) + g_variant_type_free (types[i]); + g_free (types); + + return result; +} + +/* given a valid type string, make it invalid */ +static gchar * +invalid_mutation (const gchar *type_string) +{ + gboolean have_parens, have_braces; + + /* it's valid, so '(' implies ')' and same for '{' and '}' */ + have_parens = strchr (type_string, '(') != NULL; + have_braces = strchr (type_string, '{') != NULL; + + if (have_parens && have_braces && randomly (0.3)) + { + /* swap a paren and a brace */ + gchar *pp, *bp; + gint np, nb; + gchar p, b; + gchar *new; + + new = g_strdup (type_string); + + if (randomly (0.5)) + p = '(', b = '{'; + else + p = ')', b = '}'; + + np = nb = 0; + pp = bp = new - 1; + + /* count number of parens/braces */ + while ((pp = strchr (pp + 1, p))) np++; + while ((bp = strchr (bp + 1, b))) nb++; + + /* randomly pick one of each */ + np = g_test_rand_int_range (0, np) + 1; + nb = g_test_rand_int_range (0, nb) + 1; + + /* find it */ + pp = bp = new - 1; + while (np--) pp = strchr (pp + 1, p); + while (nb--) bp = strchr (bp + 1, b); + + /* swap */ + g_assert_true (*bp == b && *pp == p); + *bp = p; + *pp = b; + + return new; + } + + if ((have_parens || have_braces) && randomly (0.3)) + { + /* drop a paren/brace */ + gchar *new; + gchar *pp; + gint np; + gchar p; + + if (have_parens) + if (randomly (0.5)) p = '('; else p = ')'; + else + if (randomly (0.5)) p = '{'; else p = '}'; + + new = g_strdup (type_string); + + np = 0; + pp = new - 1; + while ((pp = strchr (pp + 1, p))) np++; + np = g_test_rand_int_range (0, np) + 1; + pp = new - 1; + while (np--) pp = strchr (pp + 1, p); + g_assert_cmpint (*pp, ==, p); + + while (*pp) + { + *pp = *(pp + 1); + pp++; + } + + return new; + } + + /* else, perform a random mutation at a random point */ + { + gint length, n; + gchar *new; + gchar p; + + if (randomly (0.3)) + { + /* insert a paren/brace */ + if (randomly (0.5)) + if (randomly (0.5)) p = '('; else p = ')'; + else + if (randomly (0.5)) p = '{'; else p = '}'; + } + else if (randomly (0.5)) + { + /* insert junk */ + p = INVALIDS[g_test_rand_int_range (0, N_INVALIDS)]; + } + else + { + /* truncate */ + p = '\0'; + } + + + length = strlen (type_string); + new = g_malloc (length + 2); + n = g_test_rand_int_range (0, length); + memcpy (new, type_string, n); + new[n] = p; + memcpy (new + n + 1, type_string + n, length - n); + new[length + 1] = '\0'; + + return new; + } +} + +/* describe a type using the same language as is generated + * while generating the type with append_type_string + */ +static gchar * +describe_type (const GVariantType *type) +{ + gchar *result; + + if (g_variant_type_is_container (type)) + { + g_assert_false (g_variant_type_is_basic (type)); + + if (g_variant_type_is_array (type)) + { + gchar *subtype = describe_type (g_variant_type_element (type)); + result = g_strdup_printf ("a of %s", subtype); + g_free (subtype); + } + else if (g_variant_type_is_maybe (type)) + { + gchar *subtype = describe_type (g_variant_type_element (type)); + result = g_strdup_printf ("m of %s", subtype); + g_free (subtype); + } + else if (g_variant_type_is_tuple (type)) + { + if (!g_variant_type_equal (type, G_VARIANT_TYPE_TUPLE)) + { + const GVariantType *sub; + GString *string; + gsize i, length; + + string = g_string_new ("t of ["); + + length = g_variant_type_n_items (type); + sub = g_variant_type_first (type); + for (i = 0; i < length; i++) + { + gchar *subtype = describe_type (sub); + g_string_append (string, subtype); + g_free (subtype); + + if ((sub = g_variant_type_next (sub))) + g_string_append (string, ", "); + } + g_assert_null (sub); + g_string_append_c (string, ']'); + + result = g_string_free (string, FALSE); + } + else + result = g_strdup ("R"); + } + else if (g_variant_type_is_dict_entry (type)) + { + gchar *key, *value, *key2, *value2; + + key = describe_type (g_variant_type_key (type)); + value = describe_type (g_variant_type_value (type)); + key2 = describe_type (g_variant_type_first (type)); + value2 = describe_type ( + g_variant_type_next (g_variant_type_first (type))); + g_assert_null (g_variant_type_next (g_variant_type_next ( + g_variant_type_first (type)))); + g_assert_cmpstr (key, ==, key2); + g_assert_cmpstr (value, ==, value2); + result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL); + g_free (key2); + g_free (value2); + g_free (key); + g_free (value); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT)) + { + result = g_strdup ("V"); + } + else + g_assert_not_reached (); + } + else + { + if (g_variant_type_is_definite (type)) + { + g_assert_true (g_variant_type_is_basic (type)); + + if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN)) + result = g_strdup ("b"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE)) + result = g_strdup ("y"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16)) + result = g_strdup ("n"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16)) + result = g_strdup ("q"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) + result = g_strdup ("i"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32)) + result = g_strdup ("u"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64)) + result = g_strdup ("x"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64)) + result = g_strdup ("t"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE)) + result = g_strdup ("h"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE)) + result = g_strdup ("d"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) + result = g_strdup ("s"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH)) + result = g_strdup ("o"); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE)) + result = g_strdup ("g"); + else + g_assert_not_reached (); + } + else + { + if (g_variant_type_equal (type, G_VARIANT_TYPE_ANY)) + { + result = g_strdup ("S"); + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_BASIC)) + { + result = g_strdup ("?"); + } + else + g_assert_not_reached (); + } + } + + return result; +} + +/* given a type string, replace one of the indefinite type characters in + * it with a matching type (possibly the same type). + */ +static gchar * +generate_subtype (const gchar *type_string) +{ + GVariantType *replacement; + GString *result, *junk; + gint l; + gsize length, n = 0; + + result = g_string_new (NULL); + junk = g_string_new (NULL); + + /* count the number of indefinite type characters */ + for (length = 0; type_string[length]; length++) + n += type_string[length] == 'r' || + type_string[length] == '?' || + type_string[length] == '*'; + /* length now is strlen (type_string) */ + + /* pick one at random to replace */ + n = g_test_rand_int_range (0, n) + 1; + + /* find it */ + l = -1; + while (n--) l += strcspn (type_string + l + 1, "r?*") + 1; + g_assert_true (type_string[l] == 'r' || + type_string[l] == '?' || + type_string[l] == '*'); + + /* store up to that point in a GString */ + g_string_append_len (result, type_string, l); + + /* then store the replacement in the GString */ + if (type_string[l] == 'r') + replacement = append_tuple_type_string (result, junk, FALSE, 3); + + else if (type_string[l] == '?') + replacement = append_type_string (result, junk, FALSE, 0); + + else if (type_string[l] == '*') + replacement = append_type_string (result, junk, FALSE, 3); + + else + g_assert_not_reached (); + + /* ensure the replacement has the proper type */ + g_assert_true (g_variant_type_is_subtype_of (replacement, + (gpointer) &type_string[l])); + + /* store the rest from the original type string */ + g_string_append (result, type_string + l + 1); + + g_variant_type_free (replacement); + g_string_free (junk, TRUE); + + return g_string_free (result, FALSE); +} + +struct typestack +{ + const GVariantType *type; + struct typestack *parent; +}; + +/* given an indefinite type string, replace one of the indefinite + * characters in it with a matching type and ensure that the result is a + * subtype of the original. repeat. + */ +static void +subtype_check (const gchar *type_string, + struct typestack *parent_ts) +{ + struct typestack ts, *node; + gchar *subtype; + gint depth = 0; + + subtype = generate_subtype (type_string); + + ts.type = G_VARIANT_TYPE (subtype); + ts.parent = parent_ts; + + for (node = &ts; node; node = node->parent) + { + /* this type should be a subtype of each parent type */ + g_assert_true (g_variant_type_is_subtype_of (ts.type, node->type)); + + /* it should only be a supertype when it is exactly equal */ + g_assert_true (g_variant_type_is_subtype_of (node->type, ts.type) == + g_variant_type_equal (ts.type, node->type)); + + depth++; + } + + if (!g_variant_type_is_definite (ts.type) && depth < 5) + { + /* the type is still indefinite and we haven't repeated too many + * times. go once more. + */ + + subtype_check (subtype, &ts); + } + + g_free (subtype); +} + +static void +test_gvarianttype (void) +{ + gsize i; + + for (i = 0; i < 2000; i++) + { + GString *type_string, *description; + GVariantType *type, *other_type; + const GVariantType *ctype; + gchar *invalid; + gchar *desc; + + type_string = g_string_new (NULL); + description = g_string_new (NULL); + + /* generate a random type, its type string and a description + * + * exercises type constructor functions and g_variant_type_copy() + */ + type = append_type_string (type_string, description, FALSE, 6); + + /* convert the type string to a type and ensure that it is equal + * to the one produced with the type constructor routines + */ + ctype = G_VARIANT_TYPE (type_string->str); + g_assert_true (g_variant_type_equal (ctype, type)); + g_assert_cmpuint (g_variant_type_hash (ctype), ==, g_variant_type_hash (type)); + g_assert_true (g_variant_type_is_subtype_of (ctype, type)); + g_assert_true (g_variant_type_is_subtype_of (type, ctype)); + + /* check if the type is indefinite */ + if (!g_variant_type_is_definite (type)) + { + struct typestack ts = { type, NULL }; + + /* if it is indefinite, then replace one of the indefinite + * characters with a matching type and ensure that the result + * is a subtype of the original type. repeat. + */ + subtype_check (type_string->str, &ts); + } + else + /* ensure that no indefinite characters appear */ + g_assert_cmpint (strcspn (type_string->str, "r?*"), ==, type_string->len); + + + /* describe the type. + * + * exercises the type iterator interface + */ + desc = describe_type (type); + + /* make sure the description matches */ + g_assert_cmpstr (desc, ==, description->str); + g_free (desc); + + /* make an invalid mutation to the type and make sure the type + * validation routines catch it */ + invalid = invalid_mutation (type_string->str); + g_assert_true (g_variant_type_string_is_valid (type_string->str)); + g_assert_false (g_variant_type_string_is_valid (invalid)); + g_free (invalid); + + /* concatenate another type to the type string and ensure that + * the result is recognised as being invalid + */ + other_type = append_type_string (type_string, description, FALSE, 2); + + g_string_free (description, TRUE); + g_string_free (type_string, TRUE); + g_variant_type_free (other_type); + g_variant_type_free (type); + } +} + +/* Test that scanning a deeply recursive type string doesn’t exhaust our + * stack space (which it would if the type string scanner was recursive). */ +static void +test_gvarianttype_string_scan_recursion_tuple (void) +{ + gchar *type_string = NULL; + gsize type_string_len = 1000001; /* not including nul terminator */ + gsize i; + + /* Build a long type string of ‘((…u…))’. */ + type_string = g_new0 (gchar, type_string_len + 1); + for (i = 0; i < type_string_len; i++) + { + if (i < type_string_len / 2) + type_string[i] = '('; + else if (i == type_string_len / 2) + type_string[i] = 'u'; + else + type_string[i] = ')'; + } + + /* Goes (way) over allowed recursion limit. */ + g_assert_false (g_variant_type_string_is_valid (type_string)); + + g_free (type_string); +} + +/* Same as above, except with an array rather than a tuple. */ +static void +test_gvarianttype_string_scan_recursion_array (void) +{ + gchar *type_string = NULL; + gsize type_string_len = 1000001; /* not including nul terminator */ + gsize i; + + /* Build a long type string of ‘aaa…aau’. */ + type_string = g_new0 (gchar, type_string_len + 1); + for (i = 0; i < type_string_len; i++) + { + if (i < type_string_len - 1) + type_string[i] = 'a'; + else + type_string[i] = 'u'; + } + + /* Goes (way) over allowed recursion limit. */ + g_assert_false (g_variant_type_string_is_valid (type_string)); + + g_free (type_string); +} + +#define ALIGNED(x, y) (((x + (y - 1)) / y) * y) + +/* do our own calculation of the fixed_size and alignment of a type + * using a simple algorithm to make sure the "fancy" one in the + * implementation is correct. + */ +static void +calculate_type_info (const GVariantType *type, + gsize *fixed_size, + guint *alignment) +{ + if (g_variant_type_is_array (type) || + g_variant_type_is_maybe (type)) + { + calculate_type_info (g_variant_type_element (type), NULL, alignment); + + if (fixed_size) + *fixed_size = 0; + } + else if (g_variant_type_is_tuple (type) || + g_variant_type_is_dict_entry (type)) + { + if (g_variant_type_n_items (type)) + { + const GVariantType *sub; + gboolean variable; + gsize size; + guint al; + + variable = FALSE; + size = 0; + al = 0; + + sub = g_variant_type_first (type); + do + { + gsize this_fs; + guint this_al; + + calculate_type_info (sub, &this_fs, &this_al); + + al = MAX (al, this_al); + + if (!this_fs) + { + variable = TRUE; + size = 0; + } + + if (!variable) + { + size = ALIGNED (size, this_al); + size += this_fs; + } + } + while ((sub = g_variant_type_next (sub))); + + size = ALIGNED (size, al); + + if (alignment) + *alignment = al; + + if (fixed_size) + *fixed_size = size; + } + else + { + if (fixed_size) + *fixed_size = 1; + + if (alignment) + *alignment = 1; + } + } + else + { + gint fs, al; + + if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN) || + g_variant_type_equal (type, G_VARIANT_TYPE_BYTE)) + { + al = fs = 1; + } + + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16) || + g_variant_type_equal (type, G_VARIANT_TYPE_UINT16)) + { + al = fs = 2; + } + + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) || + g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) || + g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE)) + { + al = fs = 4; + } + + else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64) || + g_variant_type_equal (type, G_VARIANT_TYPE_UINT64) || + g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE)) + { + al = fs = 8; + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING) || + g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH) || + g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE)) + { + al = 1; + fs = 0; + } + else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT)) + { + al = 8; + fs = 0; + } + else + g_assert_not_reached (); + + if (fixed_size) + *fixed_size = fs; + + if (alignment) + *alignment = al; + } +} + +/* same as the describe_type() function above, but iterates over + * typeinfo instead of types. + */ +static gchar * +describe_info (GVariantTypeInfo *info) +{ + gchar *result; + + switch (g_variant_type_info_get_type_char (info)) + { + case G_VARIANT_TYPE_INFO_CHAR_MAYBE: + { + gchar *element; + + element = describe_info (g_variant_type_info_element (info)); + result = g_strdup_printf ("m of %s", element); + g_free (element); + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_ARRAY: + { + gchar *element; + + element = describe_info (g_variant_type_info_element (info)); + result = g_strdup_printf ("a of %s", element); + g_free (element); + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_TUPLE: + { + const gchar *sep = ""; + GString *string; + gsize i, length; + + string = g_string_new ("t of ["); + length = g_variant_type_info_n_members (info); + + for (i = 0; i < length; i++) + { + const GVariantMemberInfo *minfo; + gchar *subtype; + + g_string_append (string, sep); + sep = ", "; + + minfo = g_variant_type_info_member_info (info, i); + subtype = describe_info (minfo->type_info); + g_string_append (string, subtype); + g_free (subtype); + } + + g_string_append_c (string, ']'); + + result = g_string_free (string, FALSE); + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY: + { + const GVariantMemberInfo *keyinfo, *valueinfo; + gchar *key, *value; + + g_assert_cmpint (g_variant_type_info_n_members (info), ==, 2); + keyinfo = g_variant_type_info_member_info (info, 0); + valueinfo = g_variant_type_info_member_info (info, 1); + key = describe_info (keyinfo->type_info); + value = describe_info (valueinfo->type_info); + result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL); + g_free (key); + g_free (value); + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_VARIANT: + result = g_strdup ("V"); + break; + + default: + result = g_strdup (g_variant_type_info_get_type_string (info)); + g_assert_cmpint (strlen (result), ==, 1); + break; + } + + return result; +} + +/* check that the O(1) method of calculating offsets meshes with the + * results of simple iteration. + */ +static void +check_offsets (GVariantTypeInfo *info, + const GVariantType *type) +{ + gsize flavour, length; + + length = g_variant_type_info_n_members (info); + g_assert_cmpuint (length, ==, g_variant_type_n_items (type)); + + /* the 'flavour' is the low order bits of the ending point of + * variable-size items in the tuple. this lets us test that the type + * info is correct for various starting alignments. + */ + for (flavour = 0; flavour < 8; flavour++) + { + const GVariantType *subtype; + gsize last_offset_index; + gsize last_offset; + gsize position; + gsize i; + + subtype = g_variant_type_first (type); + last_offset_index = -1; + last_offset = 0; + position = 0; + + /* go through the tuple, keeping track of our position */ + for (i = 0; i < length; i++) + { + gsize fixed_size; + guint alignment; + + calculate_type_info (subtype, &fixed_size, &alignment); + + position = ALIGNED (position, alignment); + + /* compare our current aligned position (ie: the start of this + * item) to the start offset that would be calculated if we + * used the type info + */ + { + const GVariantMemberInfo *member; + gsize start; + + member = g_variant_type_info_member_info (info, i); + g_assert_cmpint (member->i, ==, last_offset_index); + + /* do the calculation using the typeinfo */ + start = last_offset; + start += member->a; + start &= member->b; + start |= member->c; + + /* did we reach the same spot? */ + g_assert_cmpint (start, ==, position); + } + + if (fixed_size) + { + /* fixed size. add that size. */ + position += fixed_size; + } + else + { + /* variable size. do the flavouring. */ + while ((position & 0x7) != flavour) + position++; + + /* and store the offset, just like it would be in the + * serialized data. + */ + last_offset = position; + last_offset_index++; + } + + /* next type */ + subtype = g_variant_type_next (subtype); + } + + /* make sure we used up exactly all the types */ + g_assert_null (subtype); + } +} + +static void +test_gvarianttypeinfo (void) +{ + gsize i; + + for (i = 0; i < 2000; i++) + { + GString *type_string, *description; + gsize fixed_size1, fixed_size2; + guint alignment1, alignment2; + GVariantTypeInfo *info; + GVariantType *type; + gchar *desc; + + type_string = g_string_new (NULL); + description = g_string_new (NULL); + + /* random type */ + type = append_type_string (type_string, description, TRUE, 6); + + /* create a typeinfo for it */ + info = g_variant_type_info_get (type); + + /* make sure the typeinfo has the right type string */ + g_assert_cmpstr (g_variant_type_info_get_type_string (info), ==, + type_string->str); + + /* calculate the alignment and fixed size, compare to the + * typeinfo's calculations + */ + calculate_type_info (type, &fixed_size1, &alignment1); + g_variant_type_info_query (info, &alignment2, &fixed_size2); + g_assert_cmpint (fixed_size1, ==, fixed_size2); + g_assert_cmpint (alignment1, ==, alignment2 + 1); + + /* test the iteration functions over typeinfo structures by + * "describing" the typeinfo and verifying equality. + */ + desc = describe_info (info); + g_assert_cmpstr (desc, ==, description->str); + + /* do extra checks for containers */ + if (g_variant_type_is_array (type) || + g_variant_type_is_maybe (type)) + { + const GVariantType *element; + gsize efs1, efs2; + guint ea1, ea2; + + element = g_variant_type_element (type); + calculate_type_info (element, &efs1, &ea1); + g_variant_type_info_query_element (info, &ea2, &efs2); + g_assert_cmpint (efs1, ==, efs2); + g_assert_cmpint (ea1, ==, ea2 + 1); + + g_assert_cmpint (ea1, ==, alignment1); + g_assert_cmpint (0, ==, fixed_size1); + } + else if (g_variant_type_is_tuple (type) || + g_variant_type_is_dict_entry (type)) + { + /* make sure the "magic constants" are working */ + check_offsets (info, type); + } + + g_string_free (type_string, TRUE); + g_string_free (description, TRUE); + g_variant_type_info_unref (info); + g_variant_type_free (type); + g_free (desc); + } + + g_variant_type_info_assert_no_infos (); +} + +#define MAX_FIXED_MULTIPLIER 256 +#define MAX_INSTANCE_SIZE 1024 +#define MAX_ARRAY_CHILDREN 128 +#define MAX_TUPLE_CHILDREN 128 + +/* this function generates a random type such that all characteristics + * that are "interesting" to the serializer are tested. + * + * this basically means: + * - test different alignments + * - test variable sized items and fixed sized items + * - test different fixed sizes + */ +static gchar * +random_type_string (void) +{ + const guchar base_types[] = "ynix"; + guchar base_type; + + base_type = base_types[g_test_rand_int_range (0, 4)]; + + if (g_test_rand_bit ()) + /* construct a fixed-sized type */ + { + char type_string[MAX_FIXED_MULTIPLIER]; + guint multiplier; + gsize i = 0; + + multiplier = g_test_rand_int_range (1, sizeof type_string - 1); + + type_string[i++] = '('; + while (multiplier--) + type_string[i++] = base_type; + type_string[i++] = ')'; + + return g_strndup (type_string, i); + } + else + /* construct a variable-sized type */ + { + char type_string[2] = { 'a', base_type }; + + return g_strndup (type_string, 2); + } +} + +typedef struct +{ + GVariantTypeInfo *type_info; + guint alignment; + gsize size; + gboolean is_fixed_sized; + + guint32 seed; + +#define INSTANCE_MAGIC 1287582829 + guint magic; +} RandomInstance; + +static RandomInstance * +random_instance (GVariantTypeInfo *type_info) +{ + RandomInstance *instance; + + instance = g_slice_new (RandomInstance); + + if (type_info == NULL) + { + gchar *str = random_type_string (); + instance->type_info = g_variant_type_info_get (G_VARIANT_TYPE (str)); + g_free (str); + } + else + instance->type_info = g_variant_type_info_ref (type_info); + + instance->seed = g_test_rand_int (); + + g_variant_type_info_query (instance->type_info, + &instance->alignment, + &instance->size); + + instance->is_fixed_sized = instance->size != 0; + + if (!instance->is_fixed_sized) + instance->size = g_test_rand_int_range (0, MAX_INSTANCE_SIZE); + + instance->magic = INSTANCE_MAGIC; + + return instance; +} + +static void +random_instance_free (RandomInstance *instance) +{ + g_variant_type_info_unref (instance->type_info); + g_slice_free (RandomInstance, instance); +} + +static void +append_instance_size (RandomInstance *instance, + gsize *offset) +{ + *offset += (-*offset) & instance->alignment; + *offset += instance->size; +} + +static void +random_instance_write (RandomInstance *instance, + guchar *buffer) +{ + GRand *rand; + gsize i; + + g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0); + + rand = g_rand_new_with_seed (instance->seed); + for (i = 0; i < instance->size; i++) + buffer[i] = g_rand_int (rand); + g_rand_free (rand); +} + +static void +append_instance_data (RandomInstance *instance, + guchar **buffer) +{ + while (((gsize) *buffer) & instance->alignment) + *(*buffer)++ = '\0'; + + random_instance_write (instance, *buffer); + *buffer += instance->size; +} + +static gboolean +random_instance_assert (RandomInstance *instance, + guchar *buffer, + gsize size) +{ + GRand *rand; + gsize i; + + g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0); + g_assert_cmpint (size, ==, instance->size); + + rand = g_rand_new_with_seed (instance->seed); + for (i = 0; i < instance->size; i++) + { + guchar byte = g_rand_int (rand); + + g_assert_cmpuint (buffer[i], ==, byte); + } + g_rand_free (rand); + + return i == instance->size; +} + +static gboolean +random_instance_check (RandomInstance *instance, + guchar *buffer, + gsize size) +{ + GRand *rand; + gsize i; + + g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0); + + if (size != instance->size) + return FALSE; + + rand = g_rand_new_with_seed (instance->seed); + for (i = 0; i < instance->size; i++) + if (buffer[i] != (guchar) g_rand_int (rand)) + break; + g_rand_free (rand); + + return i == instance->size; +} + +static void +random_instance_filler (GVariantSerialised *serialised, + gpointer data) +{ + RandomInstance *instance = data; + + g_assert_cmpuint (instance->magic, ==, INSTANCE_MAGIC); + + if (serialised->type_info == NULL) + serialised->type_info = instance->type_info; + + if (serialised->size == 0) + serialised->size = instance->size; + + serialised->depth = 0; + + g_assert_true (serialised->type_info == instance->type_info); + g_assert_cmpuint (serialised->size, ==, instance->size); + + if (serialised->data) + random_instance_write (instance, serialised->data); +} + +static gsize +calculate_offset_size (gsize body_size, + gsize n_offsets) +{ + if (body_size == 0) + return 0; + + if (body_size + n_offsets <= G_MAXUINT8) + return 1; + + if (body_size + 2 * n_offsets <= G_MAXUINT16) + return 2; + + if (body_size + 4 * n_offsets <= G_MAXUINT32) + return 4; + + /* the test case won't generate anything bigger */ + g_assert_not_reached (); +} + +static gpointer +flavoured_malloc (gsize size, gsize flavour) +{ + g_assert_cmpuint (flavour, <, 8); + + if (size == 0) + return NULL; + + return ((gchar *) g_malloc (size + flavour)) + flavour; +} + +static void +flavoured_free (gpointer data, + gsize flavour) +{ + if (!data) + return; + g_free (((gchar *) data) - flavour); +} + +static gpointer +align_malloc (gsize size) +{ + gpointer mem; + +#ifdef HAVE_POSIX_MEMALIGN + if (posix_memalign (&mem, 8, size)) + g_error ("posix_memalign failed"); +#else + /* NOTE: there may be platforms that lack posix_memalign() and also + * have malloc() that returns non-8-aligned. if so, we need to try + * harder here. + */ + mem = malloc (size); +#endif + + return mem; +} + +static void +align_free (gpointer mem) +{ + free (mem); +} + +static void +append_offset (guchar **offset_ptr, + gsize offset, + guint offset_size) +{ + union + { + guchar bytes[sizeof (gsize)]; + gsize integer; + } tmpvalue; + + tmpvalue.integer = GSIZE_TO_LE (offset); + memcpy (*offset_ptr, tmpvalue.bytes, offset_size); + *offset_ptr += offset_size; +} + +static void +prepend_offset (guchar **offset_ptr, + gsize offset, + guint offset_size) +{ + union + { + guchar bytes[sizeof (gsize)]; + gsize integer; + } tmpvalue; + + *offset_ptr -= offset_size; + tmpvalue.integer = GSIZE_TO_LE (offset); + memcpy (*offset_ptr, tmpvalue.bytes, offset_size); +} + +static void +test_maybe (void) +{ + GVariantTypeInfo *type_info; + RandomInstance *instance; + gsize needed_size; + guchar *data; + + instance = random_instance (NULL); + + { + const gchar *element; + gchar *tmp; + + element = g_variant_type_info_get_type_string (instance->type_info); + tmp = g_strdup_printf ("m%s", element); + type_info = g_variant_type_info_get (G_VARIANT_TYPE (tmp)); + g_free (tmp); + } + + needed_size = g_variant_serialiser_needed_size (type_info, + random_instance_filler, + NULL, 0); + g_assert_cmpint (needed_size, ==, 0); + + needed_size = g_variant_serialiser_needed_size (type_info, + random_instance_filler, + (gpointer *) &instance, 1); + + if (instance->is_fixed_sized) + g_assert_cmpint (needed_size, ==, instance->size); + else + g_assert_cmpint (needed_size, ==, instance->size + 1); + + { + guchar *ptr; + + ptr = data = align_malloc (needed_size); + append_instance_data (instance, &ptr); + + if (!instance->is_fixed_sized) + *ptr++ = '\0'; + + g_assert_cmpint (ptr - data, ==, needed_size); + } + + { + guint alignment; + gsize flavour; + + alignment = (instance->alignment & ALIGN_BITS) + 1; + + for (flavour = 0; flavour < 8; flavour += alignment) + { + GVariantSerialised serialised; + GVariantSerialised child; + + serialised.type_info = type_info; + serialised.data = flavoured_malloc (needed_size, flavour); + serialised.size = needed_size; + serialised.depth = 0; + + g_variant_serialiser_serialise (serialised, + random_instance_filler, + (gpointer *) &instance, 1); + child = g_variant_serialised_get_child (serialised, 0); + g_assert_true (child.type_info == instance->type_info); + random_instance_assert (instance, child.data, child.size); + g_variant_type_info_unref (child.type_info); + flavoured_free (serialised.data, flavour); + } + } + + g_variant_type_info_unref (type_info); + random_instance_free (instance); + align_free (data); +} + +static void +test_maybes (void) +{ + gsize i; + + for (i = 0; i < 1000; i++) + test_maybe (); + + g_variant_type_info_assert_no_infos (); +} + +static void +test_array (void) +{ + GVariantTypeInfo *element_info; + GVariantTypeInfo *array_info; + RandomInstance **instances; + gsize needed_size; + gsize offset_size; + guint n_children; + guchar *data; + + { + gchar *element_type, *array_type; + + element_type = random_type_string (); + array_type = g_strdup_printf ("a%s", element_type); + + element_info = g_variant_type_info_get (G_VARIANT_TYPE (element_type)); + array_info = g_variant_type_info_get (G_VARIANT_TYPE (array_type)); + g_assert_true (g_variant_type_info_element (array_info) == element_info); + + g_free (element_type); + g_free (array_type); + } + + { + gsize i; + + n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN); + instances = g_new (RandomInstance *, n_children); + for (i = 0; i < n_children; i++) + instances[i] = random_instance (element_info); + } + + needed_size = g_variant_serialiser_needed_size (array_info, + random_instance_filler, + (gpointer *) instances, + n_children); + + { + gsize element_fixed_size; + gsize body_size = 0; + gsize i; + + for (i = 0; i < n_children; i++) + append_instance_size (instances[i], &body_size); + + g_variant_type_info_query (element_info, NULL, &element_fixed_size); + + if (!element_fixed_size) + { + offset_size = calculate_offset_size (body_size, n_children); + + if (offset_size == 0) + offset_size = 1; + } + else + offset_size = 0; + + g_assert_cmpint (needed_size, ==, body_size + n_children * offset_size); + } + + { + guchar *offset_ptr, *body_ptr; + gsize i; + + body_ptr = data = align_malloc (needed_size); + offset_ptr = body_ptr + needed_size - offset_size * n_children; + + for (i = 0; i < n_children; i++) + { + append_instance_data (instances[i], &body_ptr); + append_offset (&offset_ptr, body_ptr - data, offset_size); + } + + g_assert_true (body_ptr == data + needed_size - offset_size * n_children); + g_assert_true (offset_ptr == data + needed_size); + } + + { + guint alignment; + gsize flavour; + gsize i; + + g_variant_type_info_query (array_info, &alignment, NULL); + alignment = (alignment & ALIGN_BITS) + 1; + + for (flavour = 0; flavour < 8; flavour += alignment) + { + GVariantSerialised serialised; + + serialised.type_info = array_info; + serialised.data = flavoured_malloc (needed_size, flavour); + serialised.size = needed_size; + serialised.depth = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) instances, n_children); + + if (serialised.size) + g_assert_cmpint (memcmp (serialised.data, data, serialised.size), ==, 0); + + g_assert_cmpuint (g_variant_serialised_n_children (serialised), ==, n_children); + + for (i = 0; i < n_children; i++) + { + GVariantSerialised child; + + child = g_variant_serialised_get_child (serialised, i); + g_assert_true (child.type_info == instances[i]->type_info); + random_instance_assert (instances[i], child.data, child.size); + g_variant_type_info_unref (child.type_info); + } + + flavoured_free (serialised.data, flavour); + } + } + + { + gsize i; + + for (i = 0; i < n_children; i++) + random_instance_free (instances[i]); + g_free (instances); + } + + g_variant_type_info_unref (element_info); + g_variant_type_info_unref (array_info); + align_free (data); +} + +static void +test_arrays (void) +{ + gsize i; + + for (i = 0; i < 100; i++) + test_array (); + + g_variant_type_info_assert_no_infos (); +} + +static void +test_tuple (void) +{ + GVariantTypeInfo *type_info; + RandomInstance **instances; + gboolean fixed_size; + gsize needed_size; + gsize offset_size; + guint n_children; + guint alignment; + guchar *data; + + n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN); + instances = g_new (RandomInstance *, n_children); + + { + GString *type_string; + gsize i; + + fixed_size = TRUE; + alignment = 0; + + type_string = g_string_new ("("); + for (i = 0; i < n_children; i++) + { + const gchar *str; + + instances[i] = random_instance (NULL); + + alignment |= instances[i]->alignment; + if (!instances[i]->is_fixed_sized) + fixed_size = FALSE; + + str = g_variant_type_info_get_type_string (instances[i]->type_info); + g_string_append (type_string, str); + } + g_string_append_c (type_string, ')'); + + type_info = g_variant_type_info_get (G_VARIANT_TYPE (type_string->str)); + g_string_free (type_string, TRUE); + } + + needed_size = g_variant_serialiser_needed_size (type_info, + random_instance_filler, + (gpointer *) instances, + n_children); + { + gsize body_size = 0; + gsize offsets = 0; + gsize i; + + for (i = 0; i < n_children; i++) + { + append_instance_size (instances[i], &body_size); + + if (i != n_children - 1 && !instances[i]->is_fixed_sized) + offsets++; + } + + if (fixed_size) + { + body_size += (-body_size) & alignment; + + g_assert_true ((body_size == 0) == (n_children == 0)); + if (n_children == 0) + body_size = 1; + } + + offset_size = calculate_offset_size (body_size, offsets); + g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size); + } + + { + guchar *body_ptr; + guchar *ofs_ptr; + gsize i; + + body_ptr = data = align_malloc (needed_size); + ofs_ptr = body_ptr + needed_size; + + for (i = 0; i < n_children; i++) + { + append_instance_data (instances[i], &body_ptr); + + if (i != n_children - 1 && !instances[i]->is_fixed_sized) + prepend_offset (&ofs_ptr, body_ptr - data, offset_size); + } + + if (fixed_size) + { + while (((gsize) body_ptr) & alignment) + *body_ptr++ = '\0'; + + g_assert_true ((body_ptr == data) == (n_children == 0)); + if (n_children == 0) + *body_ptr++ = '\0'; + + } + + + g_assert_true (body_ptr == ofs_ptr); + } + + { + gsize flavour; + gsize i; + + alignment = (alignment & ALIGN_BITS) + 1; + + for (flavour = 0; flavour < 8; flavour += alignment) + { + GVariantSerialised serialised; + + serialised.type_info = type_info; + serialised.data = flavoured_malloc (needed_size, flavour); + serialised.size = needed_size; + serialised.depth = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) instances, n_children); + + if (serialised.size) + g_assert_cmpint (memcmp (serialised.data, data, serialised.size), ==, 0); + + g_assert_cmpuint (g_variant_serialised_n_children (serialised), ==, n_children); + + for (i = 0; i < n_children; i++) + { + GVariantSerialised child; + + child = g_variant_serialised_get_child (serialised, i); + g_assert_true (child.type_info == instances[i]->type_info); + random_instance_assert (instances[i], child.data, child.size); + g_variant_type_info_unref (child.type_info); + } + + flavoured_free (serialised.data, flavour); + } + } + + { + gsize i; + + for (i = 0; i < n_children; i++) + random_instance_free (instances[i]); + g_free (instances); + } + + g_variant_type_info_unref (type_info); + align_free (data); +} + +static void +test_tuples (void) +{ + gsize i; + + for (i = 0; i < 100; i++) + test_tuple (); + + g_variant_type_info_assert_no_infos (); +} + +static void +test_variant (void) +{ + GVariantTypeInfo *type_info; + RandomInstance *instance; + const gchar *type_string; + gsize needed_size; + guchar *data; + gsize len; + + type_info = g_variant_type_info_get (G_VARIANT_TYPE_VARIANT); + instance = random_instance (NULL); + + type_string = g_variant_type_info_get_type_string (instance->type_info); + len = strlen (type_string); + + needed_size = g_variant_serialiser_needed_size (type_info, + random_instance_filler, + (gpointer *) &instance, 1); + + g_assert_cmpint (needed_size, ==, instance->size + 1 + len); + + { + guchar *ptr; + + ptr = data = align_malloc (needed_size); + append_instance_data (instance, &ptr); + *ptr++ = '\0'; + memcpy (ptr, type_string, len); + ptr += len; + + g_assert_true (data + needed_size == ptr); + } + + { + gsize alignment; + gsize flavour; + + /* variants are always 8-aligned */ + alignment = ALIGN_BITS + 1; + + for (flavour = 0; flavour < 8; flavour += alignment) + { + GVariantSerialised serialised; + GVariantSerialised child; + + serialised.type_info = type_info; + serialised.data = flavoured_malloc (needed_size, flavour); + serialised.size = needed_size; + serialised.depth = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) &instance, 1); + + if (serialised.size) + g_assert_cmpint (memcmp (serialised.data, data, serialised.size), ==, 0); + + g_assert_cmpuint (g_variant_serialised_n_children (serialised), ==, 1); + + child = g_variant_serialised_get_child (serialised, 0); + g_assert_true (child.type_info == instance->type_info); + random_instance_check (instance, child.data, child.size); + + g_variant_type_info_unref (child.type_info); + flavoured_free (serialised.data, flavour); + } + } + + g_variant_type_info_unref (type_info); + random_instance_free (instance); + align_free (data); +} + +static void +test_variants (void) +{ + gsize i; + + for (i = 0; i < 100; i++) + test_variant (); + + g_variant_type_info_assert_no_infos (); +} + +static void +test_strings (void) +{ + struct { + guint flags; + guint size; + gconstpointer data; + } test_cases[] = { +#define is_nval 0 +#define is_string 1 +#define is_objpath is_string | 2 +#define is_sig is_string | 4 + { is_sig, 1, "" }, + { is_nval, 0, NULL }, + { is_nval, 13, "hello\xffworld!" }, + { is_string, 13, "hello world!" }, + { is_nval, 13, "hello world\0" }, + { is_nval, 13, "hello\0world!" }, + { is_nval, 12, "hello world!" }, + { is_nval, 13, "hello world!\xff" }, + + { is_objpath, 2, "/" }, + { is_objpath, 3, "/a" }, + { is_string, 3, "//" }, + { is_objpath, 11, "/some/path" }, + { is_string, 12, "/some/path/" }, + { is_nval, 11, "/some\0path" }, + { is_string, 11, "/some\\path" }, + { is_string, 12, "/some//path" }, + { is_string, 12, "/some-/path" }, + + { is_sig, 2, "i" }, + { is_sig, 2, "s" }, + { is_sig, 5, "(si)" }, + { is_string, 4, "(si" }, + { is_string, 2, "*" }, + { is_sig, 3, "ai" }, + { is_string, 3, "mi" }, + { is_string, 2, "r" }, + { is_sig, 15, "(yyy{sv}ssiai)" }, + { is_string, 16, "(yyy{yv}ssiai))" }, + { is_string, 15, "(yyy{vv}ssiai)" }, + { is_string, 15, "(yyy{sv)ssiai}" } + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (test_cases); i++) + { + guint flags; + + flags = g_variant_serialiser_is_string (test_cases[i].data, + test_cases[i].size) + ? 1 : 0; + + flags |= g_variant_serialiser_is_object_path (test_cases[i].data, + test_cases[i].size) + ? 2 : 0; + + flags |= g_variant_serialiser_is_signature (test_cases[i].data, + test_cases[i].size) + ? 4 : 0; + + g_assert_cmpuint (flags, ==, test_cases[i].flags); + } +} + +typedef struct _TreeInstance TreeInstance; +struct _TreeInstance +{ + GVariantTypeInfo *info; + + TreeInstance **children; + gsize n_children; + + union { + guint64 integer; + gdouble floating; + gchar string[200]; + } data; + gsize data_size; +}; + +static GVariantType * +make_random_definite_type (int depth) +{ + GString *description; + GString *type_string; + GVariantType *type; + + description = g_string_new (NULL); + type_string = g_string_new (NULL); + type = append_type_string (type_string, description, TRUE, depth); + g_string_free (description, TRUE); + g_string_free (type_string, TRUE); + + return type; +} + +static void +make_random_string (gchar *string, + gsize size, + const GVariantType *type) +{ + gsize i; + + /* create strings that are valid signature strings */ +#define good_chars "bynqiuxthdsog" + + for (i = 0; i < size - 1; i++) + string[i] = good_chars[g_test_rand_int_range (0, strlen (good_chars))]; + string[i] = '\0'; + + /* in case we need an object path, prefix a '/' */ + if (*g_variant_type_peek_string (type) == 'o') + string[0] = '/'; + +#undef good_chars +} + +static TreeInstance * +tree_instance_new (const GVariantType *type, + int depth) +{ + const GVariantType *child_type = NULL; + GVariantType *mytype = NULL; + TreeInstance *instance; + gboolean is_tuple_type; + + if (type == NULL) + type = mytype = make_random_definite_type (depth); + + instance = g_slice_new (TreeInstance); + instance->info = g_variant_type_info_get (type); + instance->children = NULL; + instance->n_children = 0; + instance->data_size = 0; + + is_tuple_type = FALSE; + + switch (*g_variant_type_peek_string (type)) + { + case G_VARIANT_TYPE_INFO_CHAR_MAYBE: + instance->n_children = g_test_rand_int_range (0, 2); + child_type = g_variant_type_element (type); + break; + + case G_VARIANT_TYPE_INFO_CHAR_ARRAY: + instance->n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN); + child_type = g_variant_type_element (type); + break; + + case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY: + case G_VARIANT_TYPE_INFO_CHAR_TUPLE: + instance->n_children = g_variant_type_n_items (type); + child_type = g_variant_type_first (type); + is_tuple_type = TRUE; + break; + + case G_VARIANT_TYPE_INFO_CHAR_VARIANT: + instance->n_children = 1; + child_type = NULL; + break; + + case 'b': + instance->data.integer = g_test_rand_int_range (0, 2); + instance->data_size = 1; + break; + + case 'y': + instance->data.integer = g_test_rand_int (); + instance->data_size = 1; + break; + + case 'n': case 'q': + instance->data.integer = g_test_rand_int (); + instance->data_size = 2; + break; + + case 'i': case 'u': case 'h': + instance->data.integer = g_test_rand_int (); + instance->data_size = 4; + break; + + case 'x': case 't': + instance->data.integer = g_test_rand_int (); + instance->data.integer <<= 32; + instance->data.integer |= (guint32) g_test_rand_int (); + instance->data_size = 8; + break; + + case 'd': + instance->data.floating = g_test_rand_double (); + instance->data_size = 8; + break; + + case 's': case 'o': case 'g': + instance->data_size = g_test_rand_int_range (10, 200); + make_random_string (instance->data.string, instance->data_size, type); + break; + } + + if (instance->data_size == 0) + /* no data -> it is a container */ + { + gsize i; + + instance->children = g_new (TreeInstance *, instance->n_children); + + for (i = 0; i < instance->n_children; i++) + { + instance->children[i] = tree_instance_new (child_type, depth - 1); + + if (is_tuple_type) + child_type = g_variant_type_next (child_type); + } + + g_assert_true (!is_tuple_type || child_type == NULL); + } + + g_variant_type_free (mytype); + + return instance; +} + +static void +tree_instance_free (TreeInstance *instance) +{ + gsize i; + + g_variant_type_info_unref (instance->info); + for (i = 0; i < instance->n_children; i++) + tree_instance_free (instance->children[i]); + g_free (instance->children); + g_slice_free (TreeInstance, instance); +} + +static gboolean i_am_writing_byteswapped; + +static void +tree_filler (GVariantSerialised *serialised, + gpointer data) +{ + TreeInstance *instance = data; + + if (serialised->type_info == NULL) + serialised->type_info = instance->info; + + serialised->depth = 0; + + if (instance->data_size == 0) + /* is a container */ + { + if (serialised->size == 0) + serialised->size = + g_variant_serialiser_needed_size (instance->info, tree_filler, + (gpointer *) instance->children, + instance->n_children); + + if (serialised->data) + g_variant_serialiser_serialise (*serialised, tree_filler, + (gpointer *) instance->children, + instance->n_children); + } + else + /* it is a leaf */ + { + if (serialised->size == 0) + serialised->size = instance->data_size; + + if (serialised->data) + { + switch (instance->data_size) + { + case 1: + *serialised->data = instance->data.integer; + break; + + case 2: + { + guint16 value = instance->data.integer; + + if (i_am_writing_byteswapped) + value = GUINT16_SWAP_LE_BE (value); + + *(guint16 *) serialised->data = value; + } + break; + + case 4: + { + guint32 value = instance->data.integer; + + if (i_am_writing_byteswapped) + value = GUINT32_SWAP_LE_BE (value); + + *(guint32 *) serialised->data = value; + } + break; + + case 8: + { + guint64 value = instance->data.integer; + + if (i_am_writing_byteswapped) + value = GUINT64_SWAP_LE_BE (value); + + *(guint64 *) serialised->data = value; + } + break; + + default: + memcpy (serialised->data, + instance->data.string, + instance->data_size); + break; + } + } + } +} + +static gboolean +check_tree (TreeInstance *instance, + GVariantSerialised serialised) +{ + if (instance->info != serialised.type_info) + return FALSE; + + if (instance->data_size == 0) + /* is a container */ + { + gsize i; + + if (g_variant_serialised_n_children (serialised) != + instance->n_children) + return FALSE; + + for (i = 0; i < instance->n_children; i++) + { + GVariantSerialised child; + gpointer data = NULL; + gboolean ok; + + child = g_variant_serialised_get_child (serialised, i); + if (child.size && child.data == NULL) + child.data = data = g_malloc0 (child.size); + ok = check_tree (instance->children[i], child); + g_variant_type_info_unref (child.type_info); + g_free (data); + + if (!ok) + return FALSE; + } + + return TRUE; + } + else + /* it is a leaf */ + { + switch (instance->data_size) + { + case 1: + g_assert_cmpuint (serialised.size, ==, 1); + return *(guint8 *) serialised.data == + (guint8) instance->data.integer; + + case 2: + g_assert_cmpuint (serialised.size, ==, 2); + return *(guint16 *) serialised.data == + (guint16) instance->data.integer; + + case 4: + g_assert_cmpuint (serialised.size, ==, 4); + return *(guint32 *) serialised.data == + (guint32) instance->data.integer; + + case 8: + g_assert_cmpuint (serialised.size, ==, 8); + return *(guint64 *) serialised.data == + (guint64) instance->data.integer; + + default: + if (serialised.size != instance->data_size) + return FALSE; + + return memcmp (serialised.data, + instance->data.string, + instance->data_size) == 0; + } + } +} + +static void +serialise_tree (TreeInstance *tree, + GVariantSerialised *serialised) +{ + GVariantSerialised empty = {0, }; + + *serialised = empty; + tree_filler (serialised, tree); + serialised->data = g_malloc (serialised->size); + tree_filler (serialised, tree); +} + +static void +test_byteswap (void) +{ + GVariantSerialised one, two; + TreeInstance *tree; + + tree = tree_instance_new (NULL, 3); + serialise_tree (tree, &one); + + i_am_writing_byteswapped = TRUE; + serialise_tree (tree, &two); + i_am_writing_byteswapped = FALSE; + + g_variant_serialised_byteswap (two); + + g_assert_cmpmem (one.data, one.size, two.data, two.size); + g_assert_cmpuint (one.depth, ==, two.depth); + + tree_instance_free (tree); + g_free (one.data); + g_free (two.data); +} + +static void +test_byteswaps (void) +{ + int i; + + for (i = 0; i < 200; i++) + test_byteswap (); + + g_variant_type_info_assert_no_infos (); +} + +static void +test_serialiser_children (void) +{ + GBytes *data1, *data2; + GVariant *child1, *child2; + GVariantType *mv_type = g_variant_type_new_maybe (G_VARIANT_TYPE_VARIANT); + GVariant *variant, *child; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1865"); + g_test_summary ("Test that getting a child variant before and after " + "serialisation of the parent works"); + + /* Construct a variable sized array containing a child which serializes to a + * zero-length bytestring. */ + child = g_variant_new_maybe (G_VARIANT_TYPE_VARIANT, NULL); + variant = g_variant_new_array (mv_type, &child, 1); + + /* Get the child before serializing. */ + child1 = g_variant_get_child_value (variant, 0); + data1 = g_variant_get_data_as_bytes (child1); + + /* Serialize the parent variant. */ + g_variant_get_data (variant); + + /* Get the child again after serializing — this uses a different code path. */ + child2 = g_variant_get_child_value (variant, 0); + data2 = g_variant_get_data_as_bytes (child2); + + /* Check things are equal. */ + g_assert_cmpvariant (child1, child2); + g_assert_true (g_bytes_equal (data1, data2)); + + g_variant_unref (child2); + g_variant_unref (child1); + g_variant_unref (variant); + g_bytes_unref (data2); + g_bytes_unref (data1); + g_variant_type_free (mv_type); +} + +static void +test_fuzz (gdouble *fuzziness) +{ + GVariantSerialised serialised; + TreeInstance *tree; + + /* make an instance */ + tree = tree_instance_new (NULL, 3); + + /* serialize it */ + serialise_tree (tree, &serialised); + + g_assert_true (g_variant_serialised_is_normal (serialised)); + g_assert_true (check_tree (tree, serialised)); + + if (serialised.size) + { + gboolean fuzzed = FALSE; + gboolean a, b; + + while (!fuzzed) + { + gsize i; + + for (i = 0; i < serialised.size; i++) + if (randomly (*fuzziness)) + { + serialised.data[i] += g_test_rand_int_range (1, 256); + fuzzed = TRUE; + } + } + + /* at least one byte in the serialized data has changed. + * + * this means that at least one of the following is true: + * + * - the serialized data now represents a different value: + * check_tree() will return FALSE + * + * - the serialized data is in non-normal form: + * g_variant_serialiser_is_normal() will return FALSE + * + * we always do both checks to increase exposure of the serializer + * to corrupt data. + */ + a = g_variant_serialised_is_normal (serialised); + b = check_tree (tree, serialised); + + g_assert_true (!a || !b); + } + + tree_instance_free (tree); + g_free (serialised.data); +} + + +static void +test_fuzzes (gpointer data) +{ + gdouble fuzziness; + int i; + + fuzziness = GPOINTER_TO_INT (data) / 100.; + + for (i = 0; i < 200; i++) + test_fuzz (&fuzziness); + + g_variant_type_info_assert_no_infos (); +} + +static GVariant * +tree_instance_get_gvariant (TreeInstance *tree) +{ + const GVariantType *type; + GVariant *result; + + type = (GVariantType *) g_variant_type_info_get_type_string (tree->info); + + switch (g_variant_type_info_get_type_char (tree->info)) + { + case G_VARIANT_TYPE_INFO_CHAR_MAYBE: + { + const GVariantType *child_type; + GVariant *child; + + if (tree->n_children) + child = tree_instance_get_gvariant (tree->children[0]); + else + child = NULL; + + child_type = g_variant_type_element (type); + + if (child != NULL && randomly (0.5)) + child_type = NULL; + + result = g_variant_new_maybe (child_type, child); + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_ARRAY: + { + const GVariantType *child_type; + GVariant **children; + gsize i; + + children = g_new (GVariant *, tree->n_children); + for (i = 0; i < tree->n_children; i++) + children[i] = tree_instance_get_gvariant (tree->children[i]); + + child_type = g_variant_type_element (type); + + if (i > 0 && randomly (0.5)) + child_type = NULL; + + result = g_variant_new_array (child_type, children, tree->n_children); + g_free (children); + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_TUPLE: + { + GVariant **children; + gsize i; + + children = g_new (GVariant *, tree->n_children); + for (i = 0; i < tree->n_children; i++) + children[i] = tree_instance_get_gvariant (tree->children[i]); + + result = g_variant_new_tuple (children, tree->n_children); + g_free (children); + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY: + { + GVariant *key, *val; + + g_assert_cmpuint (tree->n_children, ==, 2); + + key = tree_instance_get_gvariant (tree->children[0]); + val = tree_instance_get_gvariant (tree->children[1]); + + result = g_variant_new_dict_entry (key, val); + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_VARIANT: + { + GVariant *value; + + g_assert_cmpuint (tree->n_children, ==, 1); + + value = tree_instance_get_gvariant (tree->children[0]); + result = g_variant_new_variant (value); + } + break; + + case 'b': + result = g_variant_new_boolean (tree->data.integer > 0); + break; + + case 'y': + result = g_variant_new_byte (tree->data.integer); + break; + + case 'n': + result = g_variant_new_int16 (tree->data.integer); + break; + + case 'q': + result = g_variant_new_uint16 (tree->data.integer); + break; + + case 'i': + result = g_variant_new_int32 (tree->data.integer); + break; + + case 'u': + result = g_variant_new_uint32 (tree->data.integer); + break; + + case 'x': + result = g_variant_new_int64 (tree->data.integer); + break; + + case 't': + result = g_variant_new_uint64 (tree->data.integer); + break; + + case 'h': + result = g_variant_new_handle (tree->data.integer); + break; + + case 'd': + result = g_variant_new_double (tree->data.floating); + break; + + case 's': + result = g_variant_new_string (tree->data.string); + break; + + case 'o': + result = g_variant_new_object_path (tree->data.string); + break; + + case 'g': + result = g_variant_new_signature (tree->data.string); + break; + + default: + g_assert_not_reached (); + } + + return result; +} + +static gboolean +tree_instance_check_gvariant (TreeInstance *tree, + GVariant *value) +{ + const GVariantType *type; + + type = (GVariantType *) g_variant_type_info_get_type_string (tree->info); + g_assert_true (g_variant_is_of_type (value, type)); + + switch (g_variant_type_info_get_type_char (tree->info)) + { + case G_VARIANT_TYPE_INFO_CHAR_MAYBE: + { + GVariant *child; + gboolean equal; + + child = g_variant_get_maybe (value); + + if (child != NULL && tree->n_children == 1) + equal = tree_instance_check_gvariant (tree->children[0], child); + else if (child == NULL && tree->n_children == 0) + equal = TRUE; + else + equal = FALSE; + + if (child != NULL) + g_variant_unref (child); + + return equal; + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_ARRAY: + case G_VARIANT_TYPE_INFO_CHAR_TUPLE: + case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY: + { + gsize i; + + if (g_variant_n_children (value) != tree->n_children) + return FALSE; + + for (i = 0; i < tree->n_children; i++) + { + GVariant *child; + gboolean equal; + + child = g_variant_get_child_value (value, i); + equal = tree_instance_check_gvariant (tree->children[i], child); + g_variant_unref (child); + + if (!equal) + return FALSE; + } + + return TRUE; + } + break; + + case G_VARIANT_TYPE_INFO_CHAR_VARIANT: + { + const gchar *str1, *str2; + GVariant *child; + gboolean equal; + + child = g_variant_get_variant (value); + str1 = g_variant_get_type_string (child); + str2 = g_variant_type_info_get_type_string (tree->children[0]->info); + /* GVariant only keeps one copy of type strings around */ + equal = str1 == str2 && + tree_instance_check_gvariant (tree->children[0], child); + + g_variant_unref (child); + + return equal; + } + break; + + case 'b': + return g_variant_get_boolean (value) == (gboolean) tree->data.integer; + + case 'y': + return g_variant_get_byte (value) == (guchar) tree->data.integer; + + case 'n': + return g_variant_get_int16 (value) == (gint16) tree->data.integer; + + case 'q': + return g_variant_get_uint16 (value) == (guint16) tree->data.integer; + + case 'i': + return g_variant_get_int32 (value) == (gint32) tree->data.integer; + + case 'u': + return g_variant_get_uint32 (value) == (guint32) tree->data.integer; + + case 'x': + return g_variant_get_int64 (value) == (gint64) tree->data.integer; + + case 't': + return g_variant_get_uint64 (value) == (guint64) tree->data.integer; + + case 'h': + return g_variant_get_handle (value) == (gint32) tree->data.integer; + + case 'd': + { + gdouble floating = g_variant_get_double (value); + + return memcmp (&floating, &tree->data.floating, sizeof floating) == 0; + } + + case 's': + case 'o': + case 'g': + return strcmp (g_variant_get_string (value, NULL), + tree->data.string) == 0; + + default: + g_assert_not_reached (); + } +} + +static void +tree_instance_build_gvariant (TreeInstance *tree, + GVariantBuilder *builder, + gboolean guess_ok) +{ + const GVariantType *type; + + type = (GVariantType *) g_variant_type_info_get_type_string (tree->info); + + if (g_variant_type_is_container (type)) + { + gsize i; + + /* force GVariantBuilder to guess the type half the time */ + if (guess_ok && randomly (0.5)) + { + if (g_variant_type_is_array (type) && tree->n_children) + type = G_VARIANT_TYPE_ARRAY; + + if (g_variant_type_is_maybe (type) && tree->n_children) + type = G_VARIANT_TYPE_MAYBE; + + if (g_variant_type_is_tuple (type)) + type = G_VARIANT_TYPE_TUPLE; + + if (g_variant_type_is_dict_entry (type)) + type = G_VARIANT_TYPE_DICT_ENTRY; + } + else + guess_ok = FALSE; + + g_variant_builder_open (builder, type); + + for (i = 0; i < tree->n_children; i++) + tree_instance_build_gvariant (tree->children[i], builder, guess_ok); + + g_variant_builder_close (builder); + } + else + g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree)); +} + + +static gboolean +tree_instance_check_iter (TreeInstance *tree, + GVariantIter *iter) +{ + GVariant *value; + + value = g_variant_iter_next_value (iter); + + if (g_variant_is_container (value)) + { + gsize i; + + iter = g_variant_iter_new (value); + g_variant_unref (value); + + if (g_variant_iter_n_children (iter) != tree->n_children) + { + g_variant_iter_free (iter); + return FALSE; + } + + for (i = 0; i < tree->n_children; i++) + if (!tree_instance_check_iter (tree->children[i], iter)) + { + g_variant_iter_free (iter); + return FALSE; + } + + g_assert_null (g_variant_iter_next_value (iter)); + g_variant_iter_free (iter); + + return TRUE; + } + + else + { + gboolean equal; + + equal = tree_instance_check_gvariant (tree, value); + g_variant_unref (value); + + return equal; + } +} + +static void +test_container (void) +{ + TreeInstance *tree; + GVariant *value; + gchar *s1, *s2; + + tree = tree_instance_new (NULL, 3); + value = g_variant_ref_sink (tree_instance_get_gvariant (tree)); + + s1 = g_variant_print (value, TRUE); + g_assert_true (tree_instance_check_gvariant (tree, value)); + + g_variant_get_data (value); + + s2 = g_variant_print (value, TRUE); + g_assert_true (tree_instance_check_gvariant (tree, value)); + + g_assert_cmpstr (s1, ==, s2); + + if (g_variant_is_container (value)) + { + GVariantBuilder builder; + GVariantIter iter; + GVariant *built; + GVariant *val; + gchar *s3; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT); + tree_instance_build_gvariant (tree, &builder, TRUE); + built = g_variant_builder_end (&builder); + g_variant_ref_sink (built); + g_variant_get_data (built); + val = g_variant_get_variant (built); + + s3 = g_variant_print (val, TRUE); + g_assert_cmpstr (s1, ==, s3); + + g_variant_iter_init (&iter, built); + g_assert_true (tree_instance_check_iter (tree, &iter)); + g_assert_null (g_variant_iter_next_value (&iter)); + + g_variant_unref (built); + g_variant_unref (val); + g_free (s3); + } + + tree_instance_free (tree); + g_variant_unref (value); + g_free (s2); + g_free (s1); +} + +static void +test_string (void) +{ + /* Test some different methods of creating strings */ + GVariant *v; + + v = g_variant_new_string ("foo"); + g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo"); + g_variant_unref (v); + + + v = g_variant_new_take_string (g_strdup ("foo")); + g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo"); + g_variant_unref (v); + + v = g_variant_new_printf ("%s %d", "foo", 123); + g_assert_cmpstr (g_variant_get_string (v, NULL), ==, "foo 123"); + g_variant_unref (v); +} + +static void +test_utf8 (void) +{ + const gchar invalid[] = "hello\xffworld"; + GVariant *value; + + /* ensure that the test data is not valid utf8... */ + g_assert_false (g_utf8_validate (invalid, -1, NULL)); + + /* load the data untrusted */ + value = g_variant_new_from_data (G_VARIANT_TYPE_STRING, + invalid, sizeof invalid, + FALSE, NULL, NULL); + + /* ensure that the problem is caught and we get valid UTF-8 */ + g_assert_true (g_utf8_validate (g_variant_get_string (value, NULL), -1, NULL)); + g_variant_unref (value); + + + /* now load it trusted */ + value = g_variant_new_from_data (G_VARIANT_TYPE_STRING, + invalid, sizeof invalid, + TRUE, NULL, NULL); + + /* ensure we get the invalid data (ie: make sure that time wasn't + * wasted on validating data that was marked as trusted) + */ + g_assert_true (g_variant_get_string (value, NULL) == invalid); + g_variant_unref (value); +} + +static void +test_containers (void) +{ + gsize i; + + for (i = 0; i < 100; i++) + { + test_container (); + } + + g_variant_type_info_assert_no_infos (); +} + +static void +test_format_strings (void) +{ + GVariantType *type; + const gchar *end; + + g_assert_true (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0'); + g_assert_true (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0'); + g_assert_true (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i'); + g_assert_true (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0'); + g_assert_true (g_variant_format_string_scan ("(^as)", NULL, &end) && + *end == '\0'); + g_assert_false (g_variant_format_string_scan ("(^s)", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("(^a)", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("(z)", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("az", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("{**}", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("{@**}", NULL, &end)); + g_assert_true (g_variant_format_string_scan ("{@y*}", NULL, &end) && + *end == '\0'); + g_assert_true (g_variant_format_string_scan ("{yv}", NULL, &end) && + *end == '\0'); + g_assert_false (g_variant_format_string_scan ("{&?v}", NULL, &end)); + g_assert_true (g_variant_format_string_scan ("{@?v}", NULL, &end) && + *end == '\0'); + g_assert_false (g_variant_format_string_scan ("{&@sv}", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("{@&sv}", NULL, &end)); + g_assert_true (g_variant_format_string_scan ("{&sv}", NULL, &end) && + *end == '\0'); + g_assert_false (g_variant_format_string_scan ("{vv}", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("{y}", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("{yyy}", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("{ya}", NULL, &end)); + g_assert_true (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0'); + g_assert_false (g_variant_format_string_scan ("&as", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("@z", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("az", NULL, &end)); + g_assert_false (g_variant_format_string_scan ("a&s", NULL, &end)); + + type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end); + g_assert_true (type && *end == '\0'); + g_assert_true (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)"))); + g_variant_type_free (type); + + type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL); + g_assert_null (type); +} + +static void +do_failed_test (const char *test, + const gchar *pattern) +{ + g_test_trap_subprocess (test, 1000000, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr (pattern); +} + +static void +test_invalid_varargs (void) +{ + GVariant *value; + const gchar *end; + + if (!g_test_undefined ()) + return; + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*GVariant format string*"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*valid_format_string*"); + value = g_variant_new ("z"); + g_test_assert_expected_messages (); + g_assert_null (value); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*valid GVariant format string as a prefix*"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*valid_format_string*"); + value = g_variant_new_va ("z", &end, NULL); + g_test_assert_expected_messages (); + g_assert_null (value); + + value = g_variant_new ("y", 'a'); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*type of 'q' but * has a type of 'y'*"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*valid_format_string*"); + g_variant_get (value, "q"); + g_test_assert_expected_messages (); + g_variant_unref (value); +} + +static void +check_and_free (GVariant *value, + const gchar *str) +{ + gchar *valstr = g_variant_print (value, FALSE); + g_assert_cmpstr (str, ==, valstr); + g_variant_unref (value); + g_free (valstr); +} + +static void +test_varargs_empty_array (void) +{ + g_variant_new ("(a{s*})", NULL); + + g_assert_not_reached (); +} + +static void +test_varargs (void) +{ + { + GVariantBuilder array; + + g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add_parsed (&array, "{'size', <(%i, %i)> }", 800, 600); + g_variant_builder_add (&array, "{sv}", "title", + g_variant_new_string ("Test case")); + g_variant_builder_add_value (&array, + g_variant_new_dict_entry (g_variant_new_string ("temperature"), + g_variant_new_variant ( + g_variant_new_double (37.5)))); + check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)", + NULL, FALSE, NULL, &array, 7777, 8888), + "(nothing, nothing, {'size': <(800, 600)>, " + "'title': <'Test case'>, " + "'temperature': <37.5>}, " + "7777, 8888)"); + + check_and_free (g_variant_new ("(imimimmimmimmi)", + 123, + FALSE, 321, + TRUE, 123, + FALSE, TRUE, 321, + TRUE, FALSE, 321, + TRUE, TRUE, 123), + "(123, nothing, 123, nothing, just nothing, 123)"); + + check_and_free (g_variant_new ("(ybnixd)", + 'a', 1, 22, 33, (guint64) 44, 5.5), + "(0x61, true, 22, 33, 44, 5.5)"); + + check_and_free (g_variant_new ("(@y?*rv)", + g_variant_new ("y", 'a'), + g_variant_new ("y", 'b'), + g_variant_new ("y", 'c'), + g_variant_new ("(y)", 'd'), + g_variant_new ("y", 'e')), + "(0x61, 0x62, 0x63, (0x64,), )"); + } + + { + GVariantBuilder array; + GVariantIter iter; + GVariant *value; + gchar *number; + gboolean just; + guint i; + gint val; + + g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY); + for (i = 0; i < 100; i++) + { + number = g_strdup_printf ("%u", i); + g_variant_builder_add (&array, "s", number); + g_free (number); + } + + value = g_variant_builder_end (&array); + g_variant_iter_init (&iter, value); + + i = 0; + while (g_variant_iter_loop (&iter, "s", &number)) + { + gchar *check = g_strdup_printf ("%u", i++); + g_assert_cmpstr (number, ==, check); + g_free (check); + } + g_assert_null (number); + g_assert_cmpuint (i, ==, 100); + + g_variant_unref (value); + + g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY); + for (i = 0; i < 100; i++) + g_variant_builder_add (&array, "mi", i % 2 == 0, i); + value = g_variant_builder_end (&array); + + i = 0; + g_variant_iter_init (&iter, value); + while (g_variant_iter_loop (&iter, "mi", NULL, &val)) + g_assert_true (val == (gint) i++ || val == 0); + g_assert_cmpuint (i, ==, 100); + + i = 0; + g_variant_iter_init (&iter, value); + while (g_variant_iter_loop (&iter, "mi", &just, &val)) + { + gint this = i++; + + if (this % 2 == 0) + { + g_assert_true (just); + g_assert_cmpint (val, ==, this); + } + else + { + g_assert_false (just); + g_assert_cmpint (val, ==, 0); + } + } + g_assert_cmpuint (i, ==, 100); + + g_variant_unref (value); + } + + { + const gchar *strvector[] = {"/hello", "/world", NULL}; + const gchar *test_strs[] = {"/foo", "/bar", "/baz" }; + GVariantBuilder builder; + GVariantIter *array; + GVariantIter tuple; + const gchar **strv; + gchar **my_strv; + GVariant *value; + gchar *str; + gsize i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); + g_variant_builder_add (&builder, "s", test_strs[0]); + g_variant_builder_add (&builder, "s", test_strs[1]); + g_variant_builder_add (&builder, "s", test_strs[2]); + value = g_variant_new ("(as^as^a&s)", &builder, strvector, strvector); + g_variant_iter_init (&tuple, value); + g_variant_iter_next (&tuple, "as", &array); + + i = 0; + while (g_variant_iter_loop (array, "s", &str)) + g_assert_cmpstr (str, ==, test_strs[i++]); + g_assert_cmpuint (i, ==, 3); + + g_variant_iter_free (array); + + /* start over */ + g_variant_iter_init (&tuple, value); + g_variant_iter_next (&tuple, "as", &array); + + i = 0; + while (g_variant_iter_loop (array, "&s", &str)) + g_assert_cmpstr (str, ==, test_strs[i++]); + g_assert_cmpuint (i, ==, 3); + + g_variant_iter_free (array); + + g_variant_iter_next (&tuple, "^a&s", &strv); + g_variant_iter_next (&tuple, "^as", &my_strv); + + g_assert_cmpstrv (strv, strvector); + g_assert_cmpstrv (my_strv, strvector); + + g_variant_unref (value); + g_strfreev (my_strv); + g_free (strv); + } + + { + const gchar *strvector[] = {"/hello", "/world", NULL}; + const gchar *test_strs[] = {"/foo", "/bar", "/baz" }; + GVariantBuilder builder; + GVariantIter *array; + GVariantIter tuple; + const gchar **strv; + gchar **my_strv; + GVariant *value; + gchar *str; + gsize i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aaay")); + g_variant_builder_add (&builder, "^aay", strvector); + g_variant_builder_add (&builder, "^aay", strvector); + g_variant_builder_add (&builder, "^aay", strvector); + value = g_variant_new ("aaay", &builder); + array = g_variant_iter_new (value); + i = 0; + while (g_variant_iter_loop (array, "^aay", &my_strv)) + i++; + g_assert_cmpuint (i, ==, 3); + + /* start over */ + g_variant_iter_init (array, value); + i = 0; + while (g_variant_iter_loop (array, "^a&ay", &strv)) + i++; + g_assert_cmpuint (i, ==, 3); + g_variant_unref (value); + g_variant_iter_free (array); + + /* next test */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay")); + g_variant_builder_add (&builder, "^ay", test_strs[0]); + g_variant_builder_add (&builder, "^ay", test_strs[1]); + g_variant_builder_add (&builder, "^ay", test_strs[2]); + value = g_variant_new ("(aay^aay^a&ay)", &builder, strvector, strvector); + g_variant_iter_init (&tuple, value); + g_variant_iter_next (&tuple, "aay", &array); + + i = 0; + while (g_variant_iter_loop (array, "^ay", &str)) + g_assert_cmpstr (str, ==, test_strs[i++]); + g_assert_cmpuint (i, ==, 3); + + g_variant_iter_free (array); + + /* start over */ + g_variant_iter_init (&tuple, value); + g_variant_iter_next (&tuple, "aay", &array); + + i = 0; + while (g_variant_iter_loop (array, "^&ay", &str)) + g_assert_cmpstr (str, ==, test_strs[i++]); + g_assert_cmpuint (i, ==, 3); + + g_variant_iter_free (array); + + g_variant_iter_next (&tuple, "^a&ay", &strv); + g_variant_iter_next (&tuple, "^aay", &my_strv); + + g_assert_cmpstrv (strv, strvector); + g_assert_cmpstrv (my_strv, strvector); + + g_variant_unref (value); + g_strfreev (my_strv); + g_free (strv); + } + + { + const gchar *strvector[] = {"/hello", "/world", NULL}; + const gchar *test_strs[] = {"/foo", "/bar", "/baz" }; + GVariantBuilder builder; + GVariantIter *array; + GVariantIter tuple; + const gchar **strv; + gchar **my_strv; + GVariant *value; + gchar *str; + gsize i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_OBJECT_PATH_ARRAY); + g_variant_builder_add (&builder, "o", test_strs[0]); + g_variant_builder_add (&builder, "o", test_strs[1]); + g_variant_builder_add (&builder, "o", test_strs[2]); + value = g_variant_new ("(ao^ao^a&o)", &builder, strvector, strvector); + g_variant_iter_init (&tuple, value); + g_variant_iter_next (&tuple, "ao", &array); + + i = 0; + while (g_variant_iter_loop (array, "o", &str)) + g_assert_cmpstr (str, ==, test_strs[i++]); + g_assert_cmpuint (i, ==, 3); + + g_variant_iter_free (array); + + /* start over */ + g_variant_iter_init (&tuple, value); + g_variant_iter_next (&tuple, "ao", &array); + + i = 0; + while (g_variant_iter_loop (array, "&o", &str)) + g_assert_cmpstr (str, ==, test_strs[i++]); + g_assert_cmpuint (i, ==, 3); + + g_variant_iter_free (array); + + g_variant_iter_next (&tuple, "^a&o", &strv); + g_variant_iter_next (&tuple, "^ao", &my_strv); + + g_assert_cmpstrv (strv, strvector); + g_assert_cmpstrv (my_strv, strvector); + + g_variant_unref (value); + g_strfreev (my_strv); + g_free (strv); + } + + { + const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL }; + GVariantBuilder builder; + GVariantIter iter; + GVariantIter *i2; + GVariantIter *i3; + GVariant *value; + GVariant *sub; + gchar **strv; + gsize i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aas")); + g_variant_builder_open (&builder, G_VARIANT_TYPE ("as")); + for (i = 0; i < 6; i++) + if (i & 1) + g_variant_builder_add (&builder, "s", strvector[i]); + else + g_variant_builder_add (&builder, "&s", strvector[i]); + g_variant_builder_close (&builder); + g_variant_builder_add (&builder, "^as", strvector); + g_variant_builder_add (&builder, "^as", strvector); + value = g_variant_new ("aas", &builder); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_loop (&iter, "^as", &strv)) + for (i = 0; i < 6; i++) + g_assert_cmpstr (strv[i], ==, strvector[i]); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_loop (&iter, "^a&s", &strv)) + for (i = 0; i < 6; i++) + g_assert_cmpstr (strv[i], ==, strvector[i]); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_loop (&iter, "as", &i2)) + { + gchar *str; + + i = 0; + while (g_variant_iter_loop (i2, "s", &str)) + g_assert_cmpstr (str, ==, strvector[i++]); + g_assert_cmpuint (i, ==, 6); + } + + g_variant_iter_init (&iter, value); + i3 = g_variant_iter_copy (&iter); + while (g_variant_iter_loop (&iter, "@as", &sub)) + { + gchar *str = g_variant_print (sub, TRUE); + g_assert_cmpstr (str, ==, + "['i', 'ii', 'iii', 'iv', 'v', 'vi']"); + g_free (str); + } + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*NULL has already been returned*"); + g_variant_iter_next_value (&iter); + g_test_assert_expected_messages (); + + while (g_variant_iter_loop (i3, "*", &sub)) + { + gchar *str = g_variant_print (sub, TRUE); + g_assert_cmpstr (str, ==, + "['i', 'ii', 'iii', 'iv', 'v', 'vi']"); + g_free (str); + } + + g_variant_iter_free (i3); + + for (i = 0; i < g_variant_n_children (value); i++) + { + gsize j; + + g_variant_get_child (value, i, "*", &sub); + + for (j = 0; j < g_variant_n_children (sub); j++) + { + const gchar *str = NULL; + GVariant *cval; + + g_variant_get_child (sub, j, "&s", &str); + g_assert_cmpstr (str, ==, strvector[j]); + + cval = g_variant_get_child_value (sub, j); + g_variant_get (cval, "&s", &str); + g_assert_cmpstr (str, ==, strvector[j]); + g_variant_unref (cval); + } + + g_variant_unref (sub); + } + + g_variant_unref (value); + } + + { + gboolean justs[10]; + GVariant *value; + + GVariant *vval; + guchar byteval; + gboolean bval; + gint16 i16val; + guint16 u16val; + gint32 i32val; + guint32 u32val; + gint64 i64val; + guint64 u64val; + gdouble dval; + gint32 hval; + + /* test all 'nothing' */ + value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)", + FALSE, 'a', + FALSE, TRUE, + FALSE, (gint16) 123, + FALSE, (guint16) 123, + FALSE, (gint32) 123, + FALSE, (guint32) 123, + FALSE, (gint64) 123, + FALSE, (guint64) 123, + FALSE, (gint32) -1, + FALSE, (gdouble) 37.5, + NULL); + + /* both NULL */ + g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL); + + /* NULL values */ + memset (justs, 1, sizeof justs); + g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)", + &justs[0], NULL, + &justs[1], NULL, + &justs[2], NULL, + &justs[3], NULL, + &justs[4], NULL, + &justs[5], NULL, + &justs[6], NULL, + &justs[7], NULL, + &justs[8], NULL, + &justs[9], NULL, + NULL); + g_assert_true (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] || + justs[5] || justs[6] || justs[7] || justs[8] || justs[9])); + + /* both non-NULL */ + memset (justs, 1, sizeof justs); + byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88; + vval = (void *) 1; + bval = TRUE; + dval = 88.88; + g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)", + &justs[0], &byteval, + &justs[1], &bval, + &justs[2], &i16val, + &justs[3], &u16val, + &justs[4], &i32val, + &justs[5], &u32val, + &justs[6], &i64val, + &justs[7], &u64val, + &justs[8], &hval, + &justs[9], &dval, + &vval); + g_assert_true (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] || + justs[5] || justs[6] || justs[7] || justs[8] || justs[9])); + g_assert_true (byteval == '\0' && bval == FALSE); + g_assert_true (i16val == 0 && u16val == 0 && i32val == 0 && + u32val == 0 && i64val == 0 && u64val == 0 && + hval == 0 && dval == 0.0); + g_assert_null (vval); + + /* NULL justs */ + byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88; + vval = (void *) 1; + bval = TRUE; + dval = 88.88; + g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)", + NULL, &byteval, + NULL, &bval, + NULL, &i16val, + NULL, &u16val, + NULL, &i32val, + NULL, &u32val, + NULL, &i64val, + NULL, &u64val, + NULL, &hval, + NULL, &dval, + &vval); + g_assert_true (byteval == '\0' && bval == FALSE); + g_assert_true (i16val == 0 && u16val == 0 && i32val == 0 && + u32val == 0 && i64val == 0 && u64val == 0 && + hval == 0 && dval == 0.0); + g_assert_null (vval); + + g_variant_unref (value); + + + /* test all 'just' */ + value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)", + TRUE, 'a', + TRUE, TRUE, + TRUE, (gint16) 123, + TRUE, (guint16) 123, + TRUE, (gint32) 123, + TRUE, (guint32) 123, + TRUE, (gint64) 123, + TRUE, (guint64) 123, + TRUE, (gint32) -1, + TRUE, (gdouble) 37.5, + g_variant_new ("()")); + + /* both NULL */ + g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL); + + /* NULL values */ + memset (justs, 0, sizeof justs); + g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)", + &justs[0], NULL, + &justs[1], NULL, + &justs[2], NULL, + &justs[3], NULL, + &justs[4], NULL, + &justs[5], NULL, + &justs[6], NULL, + &justs[7], NULL, + &justs[8], NULL, + &justs[9], NULL, + NULL); + g_assert_true (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] && + justs[5] && justs[6] && justs[7] && justs[8] && justs[9]); + + /* both non-NULL */ + memset (justs, 0, sizeof justs); + byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88; + vval = (void *) 1; + bval = FALSE; + dval = 88.88; + g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)", + &justs[0], &byteval, + &justs[1], &bval, + &justs[2], &i16val, + &justs[3], &u16val, + &justs[4], &i32val, + &justs[5], &u32val, + &justs[6], &i64val, + &justs[7], &u64val, + &justs[8], &hval, + &justs[9], &dval, + &vval); + g_assert_true (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] && + justs[5] && justs[6] && justs[7] && justs[8] && justs[9]); + g_assert_true (byteval == 'a' && bval == TRUE); + g_assert_true (i16val == 123 && u16val == 123 && i32val == 123 && + u32val == 123 && i64val == 123 && u64val == 123 && + hval == -1 && dval == 37.5); + g_assert_true (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT)); + g_variant_unref (vval); + + /* NULL justs */ + byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88; + vval = (void *) 1; + bval = TRUE; + dval = 88.88; + g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)", + NULL, &byteval, + NULL, &bval, + NULL, &i16val, + NULL, &u16val, + NULL, &i32val, + NULL, &u32val, + NULL, &i64val, + NULL, &u64val, + NULL, &hval, + NULL, &dval, + &vval); + g_assert_true (byteval == 'a' && bval == TRUE); + g_assert_true (i16val == 123 && u16val == 123 && i32val == 123 && + u32val == 123 && i64val == 123 && u64val == 123 && + hval == -1 && dval == 37.5); + g_assert_true (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT)); + g_variant_unref (vval); + + g_variant_unref (value); + } + + { + GVariant *value; + gchar *str; + + value = g_variant_new ("(masas)", NULL, NULL); + g_variant_ref_sink (value); + + str = g_variant_print (value, TRUE); + g_assert_cmpstr (str, ==, "(@mas nothing, @as [])"); + g_variant_unref (value); + g_free (str); + + do_failed_test ("/gvariant/varargs/subprocess/empty-array", + "*which type of empty array*"); + } + + g_variant_type_info_assert_no_infos (); +} + +static void +hash_get (GVariant *value, + const gchar *format, + ...) +{ + const gchar *endptr = NULL; + gboolean hash; + va_list ap; + + hash = g_str_has_suffix (format, "#"); + + va_start (ap, format); + g_variant_get_va (value, format, hash ? &endptr : NULL, &ap); + va_end (ap); + + if (hash) + g_assert_cmpint (*endptr, ==, '#'); +} + +static GVariant * +hash_new (const gchar *format, + ...) +{ + const gchar *endptr = NULL; + GVariant *value; + gboolean hash; + va_list ap; + + hash = g_str_has_suffix (format, "#"); + + va_start (ap, format); + value = g_variant_new_va (format, hash ? &endptr : NULL, &ap); + va_end (ap); + + if (hash) + g_assert_cmpint (*endptr, ==, '#'); + + return value; +} + +static void +test_valist (void) +{ + GVariant *value; + gint32 x; + + x = 0; + value = hash_new ("i", 234); + hash_get (value, "i", &x); + g_assert_cmpint (x, ==, 234); + g_variant_unref (value); + + x = 0; + value = hash_new ("i#", 234); + hash_get (value, "i#", &x); + g_assert_cmpint (x, ==, 234); + g_variant_unref (value); + + g_variant_type_info_assert_no_infos (); +} + +static void +test_builder_memory (void) +{ + GVariantBuilder *hb; + GVariantBuilder sb; + + hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY); + g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY); + g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (hb, "s", "some value"); + g_variant_builder_ref (hb); + g_variant_builder_unref (hb); + g_variant_builder_unref (hb); + + hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + g_variant_builder_unref (hb); + + hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + g_variant_builder_clear (hb); + g_variant_builder_unref (hb); + + g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY); + g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY); + g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (&sb, "s", "some value"); + g_variant_builder_clear (&sb); + + g_variant_type_info_assert_no_infos (); +} + +static void +test_hashing (void) +{ + GVariant *items[4096]; + GHashTable *table; + gsize i; + + table = g_hash_table_new_full (g_variant_hash, g_variant_equal, + (GDestroyNotify ) g_variant_unref, + NULL); + + for (i = 0; i < G_N_ELEMENTS (items); i++) + { + TreeInstance *tree; + gsize j; + + again: + tree = tree_instance_new (NULL, 0); + items[i] = tree_instance_get_gvariant (tree); + tree_instance_free (tree); + + for (j = 0; j < i; j++) + if (g_variant_equal (items[i], items[j])) + { + g_variant_unref (items[i]); + goto again; + } + + g_hash_table_insert (table, + g_variant_ref_sink (items[i]), + GINT_TO_POINTER (i)); + } + + for (i = 0; i < G_N_ELEMENTS (items); i++) + { + gpointer result; + + result = g_hash_table_lookup (table, items[i]); + g_assert_cmpint (GPOINTER_TO_INT (result), ==, i); + } + + g_hash_table_unref (table); + + g_variant_type_info_assert_no_infos (); +} + +static void +test_gv_byteswap (void) +{ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +# define native16(x) x, 0 +# define swapped16(x) 0, x +#else +# define native16(x) 0, x +# define swapped16(x) x, 0 +#endif + /* all kinds of of crazy randomised testing already performed on the + * byteswapper in the /gvariant/serializer/byteswap test and all kinds + * of crazy randomised testing performed against the serializer + * normalisation functions in the /gvariant/serializer/fuzz/ tests. + * + * just test a few simple cases here to make sure they each work + */ + guchar validbytes[] = { 'a', '\0', swapped16(66), 2, + 0, + 'b', '\0', swapped16(77), 2, + 5, 11 }; + guchar corruptbytes[] = { 'a', '\0', swapped16(66), 2, + 0, + 'b', '\0', swapped16(77), 2, + 6, 11 }; + guint valid_data[4], corrupt_data[4]; + GVariant *value, *swapped; + gchar *string, *string2; + + memcpy (valid_data, validbytes, sizeof validbytes); + memcpy (corrupt_data, corruptbytes, sizeof corruptbytes); + + /* trusted */ + value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"), + valid_data, sizeof validbytes, TRUE, + NULL, NULL); + swapped = g_variant_byteswap (value); + g_variant_unref (value); + g_assert_cmpuint (g_variant_get_size (swapped), ==, 13); + string = g_variant_print (swapped, FALSE); + g_variant_unref (swapped); + g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]"); + g_free (string); + + /* untrusted but valid */ + value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"), + valid_data, sizeof validbytes, FALSE, + NULL, NULL); + swapped = g_variant_byteswap (value); + g_variant_unref (value); + g_assert_cmpuint (g_variant_get_size (swapped), ==, 13); + string = g_variant_print (swapped, FALSE); + g_variant_unref (swapped); + g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]"); + g_free (string); + + /* untrusted, invalid */ + value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"), + corrupt_data, sizeof corruptbytes, FALSE, + NULL, NULL); + string = g_variant_print (value, FALSE); + swapped = g_variant_byteswap (value); + g_variant_unref (value); + g_assert_cmpuint (g_variant_get_size (swapped), ==, 13); + value = g_variant_byteswap (swapped); + g_variant_unref (swapped); + string2 = g_variant_print (value, FALSE); + g_assert_cmpuint (g_variant_get_size (value), ==, 13); + g_variant_unref (value); + g_assert_cmpstr (string, ==, string2); + g_free (string2); + g_free (string); +} + +static void +test_parser (void) +{ + TreeInstance *tree; + GVariant *parsed; + GVariant *value; + gchar *pt, *p; + gchar *res; + + tree = tree_instance_new (NULL, 3); + value = tree_instance_get_gvariant (tree); + tree_instance_free (tree); + + pt = g_variant_print (value, TRUE); + p = g_variant_print (value, FALSE); + + parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL); + res = g_variant_print (parsed, FALSE); + g_assert_cmpstr (p, ==, res); + g_variant_unref (parsed); + g_free (res); + + parsed = g_variant_parse (g_variant_get_type (value), p, + NULL, NULL, NULL); + res = g_variant_print (parsed, TRUE); + g_assert_cmpstr (pt, ==, res); + g_variant_unref (parsed); + g_free (res); + + g_variant_unref (value); + g_free (pt); + g_free (p); +} + +static void +test_parses (void) +{ + gsize i; + + for (i = 0; i < 100; i++) + { + test_parser (); + } + + /* mini test */ + { + GError *error = NULL; + gchar str[128]; + GVariant *val; + gchar *p, *p2; + + for (i = 0; i < 127; i++) + str[i] = i + 1; + str[i] = 0; + + val = g_variant_new_string (str); + p = g_variant_print (val, FALSE); + g_variant_unref (val); + + val = g_variant_parse (NULL, p, NULL, NULL, &error); + p2 = g_variant_print (val, FALSE); + + g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL)); + g_assert_cmpstr (p, ==, p2); + + g_variant_unref (val); + g_free (p2); + g_free (p); + } + + /* another mini test */ + { + const gchar *end; + GVariant *value; + + value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL); + g_assert_cmpint (g_variant_get_int32 (value), ==, 1); + /* make sure endptr returning works */ + g_assert_cmpstr (end, ==, " 2 3"); + g_variant_unref (value); + } + + /* unicode mini test */ + { + /* aÅ‚ð„ž */ + const gchar orig[] = "a\xc5\x82\xf0\x9d\x84\x9e \t\n"; + GVariant *value; + gchar *printed; + + value = g_variant_new_string (orig); + printed = g_variant_print (value, FALSE); + g_variant_unref (value); + + g_assert_cmpstr (printed, ==, "'a\xc5\x82\xf0\x9d\x84\x9e \\t\\n'"); + value = g_variant_parse (NULL, printed, NULL, NULL, NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig); + g_variant_unref (value); + g_free (printed); + } + + /* escapes */ + { + const gchar orig[] = " \342\200\254 \360\220\210\240 \a \b \f \n \r \t \v "; + GVariant *value; + gchar *printed; + + value = g_variant_new_string (orig); + printed = g_variant_print (value, FALSE); + g_variant_unref (value); + + g_assert_cmpstr (printed, ==, "' \\u202c \\U00010220 \\a \\b \\f \\n \\r \\t \\v '"); + value = g_variant_parse (NULL, printed, NULL, NULL, NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, orig); + g_variant_unref (value); + g_free (printed); + } + + /* pattern coalese of `MN` and `*` is `MN` */ + { + GVariant *value = NULL; + GError *error = NULL; + + value = g_variant_parse (NULL, "[[0], [], [nothing]]", NULL, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (g_variant_get_type_string (value), ==, "aami"); + g_variant_unref (value); + } + +#ifndef _MSC_VER + /* inf/nan strings are C99 features which Visual C++ does not support */ + /* inf/nan mini test */ + { + const gchar *tests[] = { "inf", "-inf", "nan" }; + GVariant *value; + gchar *printed; + gchar *printed_down; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + GError *error = NULL; + value = g_variant_parse (NULL, tests[i], NULL, NULL, &error); + printed = g_variant_print (value, FALSE); + /* Canonicalize to lowercase; https://bugzilla.gnome.org/show_bug.cgi?id=704585 */ + printed_down = g_ascii_strdown (printed, -1); + g_assert_true (g_str_has_prefix (printed_down, tests[i])); + g_free (printed); + g_free (printed_down); + g_variant_unref (value); + } + } +#endif + + g_variant_type_info_assert_no_infos (); +} + +static void +test_parse_failures (void) +{ + const gchar *test[] = { + "[1, 2,", "6:", "expected value", + "", "0:", "expected value", + "(1, 2,", "6:", "expected value", + "<1", "2:", "expected '>'", + "[]", "0-2:", "unable to infer", + "(,", "1:", "expected value", + "[4,'']", "1-2,3-5:", "common type", + "[4, '', 5]", "1-2,4-6:", "common type", + "['', 4, 5]", "1-3,5-6:", "common type", + "[4, 5, '']", "1-2,7-9:", "common type", + "[[4], [], ['']]", "1-4,10-14:", "common type", + "[[], [4], ['']]", "5-8,10-14:", "common type", + "just", "4:", "expected value", + "nothing", "0-7:", "unable to infer", + "just [4, '']", "6-7,9-11:", "common type", + "[[4,'']]", "2-3,4-6:", "common type", + "([4,''],)", "2-3,4-6:", "common type", + "(4)", "2:", "','", + "{}", "0-2:", "unable to infer", + "{[1,2],[3,4]}", "0-13:", "basic types", + "{[1,2]:[3,4]}", "0-13:", "basic types", + "justt", "0-5:", "unknown keyword", + "nothng", "0-6:", "unknown keyword", + "uint33", "0-6:", "unknown keyword", + "@mi just ''", "9-11:", "can not parse as", + "@ai ['']", "5-7:", "can not parse as", + "@(i) ('',)", "6-8:", "can not parse as", + "[[], 5]", "1-3,5-6:", "common type", + "[[5], 5]", "1-4,6-7:", "common type", + "5 5", "2:", "expected end of input", + "[5, [5, '']]", "5-6,8-10:", "common type", + "@i just 5", "3-9:", "can not parse as", + "@i nothing", "3-10:", "can not parse as", + "@i []", "3-5:", "can not parse as", + "@i ()", "3-5:", "can not parse as", + "@ai (4,)", "4-8:", "can not parse as", + "@(i) []", "5-7:", "can not parse as", + "(5 5)", "3:", "expected ','", + "[5 5]", "3:", "expected ',' or ']'", + "(5, 5 5)", "6:", "expected ',' or ')'", + "[5, 5 5]", "6:", "expected ',' or ']'", + "<@i []>", "4-6:", "can not parse as", + "<[5 5]>", "4:", "expected ',' or ']'", + "{[4,''],5}", "2-3,4-6:", "common type", + "{5,[4,'']}", "4-5,6-8:", "common type", + "@i {1,2}", "3-8:", "can not parse as", + "{@i '', 5}", "4-6:", "can not parse as", + "{5, @i ''}", "7-9:", "can not parse as", + "@ai {}", "4-6:", "can not parse as", + "{@i '': 5}", "4-6:", "can not parse as", + "{5: @i ''}", "7-9:", "can not parse as", + "{<4,5}", "3:", "expected '>'", + "{4,<5}", "5:", "expected '>'", + "{4,5,6}", "4:", "expected '}'", + "{5 5}", "3:", "expected ':' or ','", + "{4: 5: 6}", "5:", "expected ',' or '}'", + "{4:5,<6:7}", "7:", "expected '>'", + "{4:5,6:<7}", "9:", "expected '>'", + "{4:5,6 7}", "7:", "expected ':'", + "@o 'foo'", "3-8:", "object path", + "@g 'zzz'", "3-8:", "signature", + "@i true", "3-7:", "can not parse as", + "@z 4", "0-2:", "invalid type", + "@a* []", "0-3:", "definite", + "@ai [3 3]", "7:", "expected ',' or ']'", + "18446744073709551616", "0-20:", "too big for any type", + "-18446744073709551616", "0-21:", "too big for any type", + "byte 256", "5-8:", "out of range for type", + "byte -1", "5-7:", "out of range for type", + "int16 32768", "6-11:", "out of range for type", + "int16 -32769", "6-12:", "out of range for type", + "uint16 -1", "7-9:", "out of range for type", + "uint16 65536", "7-12:", "out of range for type", + "2147483648", "0-10:", "out of range for type", + "-2147483649", "0-11:", "out of range for type", + "uint32 -1", "7-9:", "out of range for type", + "uint32 4294967296", "7-17:", "out of range for type", + "@x 9223372036854775808", "3-22:", "out of range for type", + "@x -9223372036854775809", "3-23:", "out of range for type", + "@t -1", "3-5:", "out of range for type", + "@t 18446744073709551616", "3-23:", "too big for any type", + "handle 2147483648", "7-17:", "out of range for type", + "handle -2147483649", "7-18:", "out of range for type", + "1.798e308", "0-9:", "too big for any type", + "37.5a488", "4-5:", "invalid character", + "0x7ffgf", "5-6:", "invalid character", + "07758", "4-5:", "invalid character", + "123a5", "3-4:", "invalid character", + "@ai 123", "4-7:", "can not parse as", + "'\"\\'", "0-4:", "unterminated string", + "'\"\\'\\", "0-5:", "unterminated string", + "boolean 4", "8-9:", "can not parse as", + "int32 true", "6-10:", "can not parse as", + "[double 5, int32 5]", "1-9,11-18:", "common type", + "string 4", "7-8:", "can not parse as", + "\x0a", "1:", "expected value", + "((", "2:", "expected value", + "(b", "1:", "expected value", + "b'", "0-2:", "unterminated string constant", + "b\"", "0-2:", "unterminated string constant", + "b'a", "0-3:", "unterminated string constant", + "b\"a", "0-3:", "unterminated string constant", + "b'\\", "0-3:", "unterminated string constant", + "b\"\\", "0-3:", "unterminated string constant", + "b'\\'", "0-4:", "unterminated string constant", + "b\"\\\"", "0-4:", "unterminated string constant", + "b'\\'a", "0-5:", "unterminated string constant", + "b\"\\\"a", "0-5:", "unterminated string constant", + "'\\u-ff4'", "3:", "invalid 4-character unicode escape", + "'\\u+ff4'", "3:", "invalid 4-character unicode escape", + "'\\u'", "3:", "invalid 4-character unicode escape", + "'\\u0'", "3-4:", "invalid 4-character unicode escape", + "'\\uHELLO'", "3:", "invalid 4-character unicode escape", + "'\\u ff4'", "3:", "invalid 4-character unicode escape", + "'\\u012'", "3-6:", "invalid 4-character unicode escape", + "'\\u0xff4'", "3-4:", "invalid 4-character unicode escape", + "'\\U-ff4'", "3:", "invalid 8-character unicode escape", + "'\\U+ff4'", "3:", "invalid 8-character unicode escape", + "'\\U'", "3:", "invalid 8-character unicode escape", + "'\\U0'", "3-4:", "invalid 8-character unicode escape", + "'\\UHELLO'", "3:", "invalid 8-character unicode escape", + "'\\U ff4'", "3:", "invalid 8-character unicode escape", + "'\\U0123456'", "3-10:", "invalid 8-character unicode escape", + "'\\U0xff4'", "3-4:", "invalid 8-character unicode escape", + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (test); i += 3) + { + GError *error1 = NULL, *error2 = NULL; + GVariant *value; + + /* Copy the test string and drop its nul terminator, then use the @limit + * parameter of g_variant_parse() to set the length. This allows valgrind + * to catch 1-byte heap buffer overflows. */ + gsize test_len = MAX (strlen (test[i]), 1); + gchar *test_blob = g_malloc0 (test_len); /* no nul terminator */ + + memcpy (test_blob, test[i], test_len); + value = g_variant_parse (NULL, test_blob, test_blob + test_len, NULL, &error1); + g_assert_null (value); + + g_free (test_blob); + + if (!strstr (error1->message, test[i+2])) + g_error ("test %u: Can't find '%s' in '%s'", i / 3, + test[i+2], error1->message); + + if (!g_str_has_prefix (error1->message, test[i+1])) + g_error ("test %u: Expected location '%s' in '%s'", i / 3, + test[i+1], error1->message); + + /* Test again with the nul terminator this time. The behaviour should be + * the same. */ + value = g_variant_parse (NULL, test[i], NULL, NULL, &error2); + g_assert_null (value); + + g_assert_cmpint (error1->domain, ==, error2->domain); + g_assert_cmpint (error1->code, ==, error2->code); + g_assert_cmpstr (error1->message, ==, error2->message); + + g_clear_error (&error1); + g_clear_error (&error2); + } +} + +/* Test that parsing GVariant text format integers works at the boundaries of + * those integer types. We’re especially interested in the handling of the most + * negative numbers, since those can’t be represented in sign + absolute value + * form. */ +static void +test_parser_integer_bounds (void) +{ + GVariant *value = NULL; + GError *local_error = NULL; + +#define test_bound(TYPE, type, text, expected_value) \ + value = g_variant_parse (G_VARIANT_TYPE_##TYPE, text, NULL, NULL, &local_error); \ + g_assert_no_error (local_error); \ + g_assert_nonnull (value); \ + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_##TYPE)); \ + g_assert_cmpint (g_variant_get_##type (value), ==, expected_value); \ + g_variant_unref (value) + + test_bound (BYTE, byte, "0", 0); + test_bound (BYTE, byte, "255", G_MAXUINT8); + test_bound (INT16, int16, "-32768", G_MININT16); + test_bound (INT16, int16, "32767", G_MAXINT16); + test_bound (INT32, int32, "-2147483648", G_MININT32); + test_bound (INT32, int32, "2147483647", G_MAXINT32); + test_bound (INT64, int64, "-9223372036854775808", G_MININT64); + test_bound (INT64, int64, "9223372036854775807", G_MAXINT64); + test_bound (HANDLE, handle, "-2147483648", G_MININT32); + test_bound (HANDLE, handle, "2147483647", G_MAXINT32); + +#undef test_bound +} + +/* Test that #GVariants which recurse too deeply are rejected. */ +static void +test_parser_recursion (void) +{ + GVariant *value = NULL; + GError *local_error = NULL; + const guint recursion_depth = G_VARIANT_MAX_RECURSION_DEPTH + 1; + gchar *silly_dict = g_malloc0 (recursion_depth * 2 + 1); + gsize i; + + for (i = 0; i < recursion_depth; i++) + { + silly_dict[i] = '{'; + silly_dict[recursion_depth * 2 - i - 1] = '}'; + } + + value = g_variant_parse (NULL, silly_dict, NULL, NULL, &local_error); + g_assert_error (local_error, G_VARIANT_PARSE_ERROR, G_VARIANT_PARSE_ERROR_RECURSION); + g_assert_null (value); + g_error_free (local_error); + g_free (silly_dict); +} + +static void +test_parse_bad_format_char (void) +{ + g_variant_new_parsed ("%z"); + + g_assert_not_reached (); +} + +static void +test_parse_bad_format_string (void) +{ + g_variant_new_parsed ("uint32 %i", 2); + + g_assert_not_reached (); +} + +static void +test_parse_bad_args (void) +{ + g_variant_new_parsed ("%@i", g_variant_new_uint32 (2)); + + g_assert_not_reached (); +} + +static void +test_parse_positional (void) +{ + GVariant *value; + check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2)," + " ('three', %i)]", "two", 3), + "[('one', 1), ('two', 2), ('three', 3)]"); + value = g_variant_new_parsed ("[('one', 1), (%s, 2)," + " ('three', %u)]", "two", 3); + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)"))); + check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]"); + check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}"); + + if (g_test_undefined ()) + { + do_failed_test ("/gvariant/parse/subprocess/bad-format-char", + "*GVariant format string*"); + + do_failed_test ("/gvariant/parse/subprocess/bad-format-string", + "*can not parse as*"); + + do_failed_test ("/gvariant/parse/subprocess/bad-args", + "*expected GVariant of type 'i'*"); + } +} + +static void +test_floating (void) +{ + GVariant *value; + + value = g_variant_new_int32 (42); + g_assert_true (g_variant_is_floating (value)); + g_variant_ref_sink (value); + g_assert_true (!g_variant_is_floating (value)); + g_variant_unref (value); +} + +static void +test_bytestring (void) +{ + const gchar *test_string = "foo,bar,baz,quux,\xffoooo"; + GVariant *value; + gchar **strv; + gchar *str; + const gchar *const_str; + GVariant *untrusted_empty; + + strv = g_strsplit (test_string, ",", 0); + + value = g_variant_new_bytestring_array ((const gchar **) strv, -1); + g_assert_true (g_variant_is_floating (value)); + g_strfreev (strv); + + str = g_variant_print (value, FALSE); + g_variant_unref (value); + + value = g_variant_parse (NULL, str, NULL, NULL, NULL); + g_free (str); + + strv = g_variant_dup_bytestring_array (value, NULL); + g_variant_unref (value); + + str = g_strjoinv (",", strv); + g_strfreev (strv); + + g_assert_cmpstr (str, ==, test_string); + g_free (str); + + strv = g_strsplit (test_string, ",", 0); + value = g_variant_new ("(^aay^a&ay^ay^&ay)", + strv, strv, strv[0], strv[0]); + g_strfreev (strv); + + g_variant_get_child (value, 0, "^a&ay", &strv); + str = g_strjoinv (",", strv); + g_free (strv); + g_assert_cmpstr (str, ==, test_string); + g_free (str); + + g_variant_get_child (value, 0, "^aay", &strv); + str = g_strjoinv (",", strv); + g_strfreev (strv); + g_assert_cmpstr (str, ==, test_string); + g_free (str); + + g_variant_get_child (value, 1, "^a&ay", &strv); + str = g_strjoinv (",", strv); + g_free (strv); + g_assert_cmpstr (str, ==, test_string); + g_free (str); + + g_variant_get_child (value, 1, "^aay", &strv); + str = g_strjoinv (",", strv); + g_strfreev (strv); + g_assert_cmpstr (str, ==, test_string); + g_free (str); + + g_variant_get_child (value, 2, "^ay", &str); + g_assert_cmpstr (str, ==, "foo"); + g_free (str); + + g_variant_get_child (value, 2, "^&ay", &str); + g_assert_cmpstr (str, ==, "foo"); + + g_variant_get_child (value, 3, "^ay", &str); + g_assert_cmpstr (str, ==, "foo"); + g_free (str); + + g_variant_get_child (value, 3, "^&ay", &str); + g_assert_cmpstr (str, ==, "foo"); + g_variant_unref (value); + + untrusted_empty = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), NULL, 0, FALSE, NULL, NULL); + value = g_variant_get_normal_form (untrusted_empty); + const_str = g_variant_get_bytestring (value); + (void) const_str; + g_variant_unref (value); + g_variant_unref (untrusted_empty); +} + +static void +test_lookup_value (void) +{ + struct { + const gchar *dict, *key, *value; + } cases[] = { + { "@a{ss} {'x': 'y'}", "x", "'y'" }, + { "@a{ss} {'x': 'y'}", "y", NULL }, + { "@a{os} {'/x': 'y'}", "/x", "'y'" }, + { "@a{os} {'/x': 'y'}", "/y", NULL }, + { "@a{sv} {'x': <'y'>}", "x", "'y'" }, + { "@a{sv} {'x': <5>}", "x", "5" }, + { "@a{sv} {'x': <'y'>}", "y", NULL } + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (cases); i++) + { + GVariant *dictionary; + GVariant *value; + gchar *p; + + dictionary = g_variant_parse (NULL, cases[i].dict, NULL, NULL, NULL); + value = g_variant_lookup_value (dictionary, cases[i].key, NULL); + g_variant_unref (dictionary); + + if (value == NULL && cases[i].value == NULL) + continue; + + g_assert_true (value && cases[i].value); + p = g_variant_print (value, FALSE); + g_assert_cmpstr (cases[i].value, ==, p); + g_variant_unref (value); + g_free (p); + } +} + +static void +test_lookup (void) +{ + const gchar *str; + GVariant *dict; + gboolean ok; + gint num; + + dict = g_variant_parse (NULL, + "{'a': <5>, 'b': <'c'>}", + NULL, NULL, NULL); + + ok = g_variant_lookup (dict, "a", "i", &num); + g_assert_true (ok); + g_assert_cmpint (num, ==, 5); + + ok = g_variant_lookup (dict, "a", "&s", &str); + g_assert_false (ok); + + ok = g_variant_lookup (dict, "q", "&s", &str); + g_assert_false (ok); + + ok = g_variant_lookup (dict, "b", "i", &num); + g_assert_false (ok); + + ok = g_variant_lookup (dict, "b", "&s", &str); + g_assert_true (ok); + g_assert_cmpstr (str, ==, "c"); + + ok = g_variant_lookup (dict, "q", "&s", &str); + g_assert_false (ok); + + g_variant_unref (dict); +} + +static GVariant * +untrusted (GVariant *a) +{ + GVariant *b; + const GVariantType *type; + GBytes *bytes; + + type = g_variant_get_type (a); + bytes = g_variant_get_data_as_bytes (a); + b = g_variant_new_from_bytes (type, bytes, FALSE); + g_bytes_unref (bytes); + g_variant_unref (a); + + return b; +} + +static void +test_compare (void) +{ + GVariant *a; + GVariant *b; + + a = untrusted (g_variant_new_byte (5)); + b = g_variant_new_byte (6); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_int16 (G_MININT16)); + b = g_variant_new_int16 (G_MAXINT16); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_uint16 (0)); + b = g_variant_new_uint16 (G_MAXUINT16); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_int32 (G_MININT32)); + b = g_variant_new_int32 (G_MAXINT32); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_uint32 (0)); + b = g_variant_new_uint32 (G_MAXUINT32); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_int64 (G_MININT64)); + b = g_variant_new_int64 (G_MAXINT64); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_uint64 (0)); + b = g_variant_new_uint64 (G_MAXUINT64); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_double (G_MINDOUBLE)); + b = g_variant_new_double (G_MAXDOUBLE); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_string ("abc")); + b = g_variant_new_string ("abd"); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_object_path ("/abc")); + b = g_variant_new_object_path ("/abd"); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_signature ("g")); + b = g_variant_new_signature ("o"); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_boolean (FALSE)); + b = g_variant_new_boolean (TRUE); + g_assert_cmpint (g_variant_compare (a, b), <, 0); + g_variant_unref (a); + g_variant_unref (b); +} + +static void +test_equal (void) +{ + GVariant *a; + GVariant *b; + + a = untrusted (g_variant_new_byte (5)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_int16 (G_MININT16)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_uint16 (0)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_int32 (G_MININT32)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_uint32 (0)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_int64 (G_MININT64)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_uint64 (0)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_double (G_MINDOUBLE)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_string ("abc")); + g_assert_cmpvariant (a, a); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_object_path ("/abc")); + g_assert_cmpvariant (a, a); + b = g_variant_get_normal_form (a); + a = untrusted (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_signature ("g")); + g_assert_cmpvariant (a, a); + b = g_variant_get_normal_form (a); + a = untrusted (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); + a = untrusted (g_variant_new_boolean (FALSE)); + b = g_variant_get_normal_form (a); + g_assert_cmpvariant (a, b); + g_variant_unref (a); + g_variant_unref (b); +} + +static void +test_fixed_array (void) +{ + GVariant *a; + gint32 values[5]; + const gint32 *elts; + gsize n_elts; + gsize i; + + n_elts = 0; + a = g_variant_new_parsed ("[1,2,3,4,5]"); + elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32)); + g_assert_cmpuint (n_elts, ==, 5); + for (i = 0; i < 5; i++) + g_assert_cmpint (elts[i], ==, i + 1); + g_variant_unref (a); + + n_elts = 0; + for (i = 0; i < 5; i++) + values[i] = i + 1; + a = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, values, + G_N_ELEMENTS (values), sizeof (values[0])); + g_assert_cmpstr (g_variant_get_type_string (a), ==, "ai"); + elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32)); + g_assert_cmpuint (n_elts, ==, 5); + for (i = 0; i < 5; i++) + g_assert_cmpint (elts[i], ==, i + 1); + g_variant_unref (a); +} + +static void +test_check_format_string (void) +{ + GVariant *value; + + value = g_variant_new ("(sas)", "foo", NULL); + g_variant_ref_sink (value); + + g_assert_true (g_variant_check_format_string (value, "(s*)", TRUE)); + g_assert_true (g_variant_check_format_string (value, "(s*)", FALSE)); + g_assert_false (g_variant_check_format_string (value, "(u*)", TRUE)); + g_assert_false (g_variant_check_format_string (value, "(u*)", FALSE)); + + g_assert_true (g_variant_check_format_string (value, "(&s*)", FALSE)); + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*"); + g_assert_false (g_variant_check_format_string (value, "(&s*)", TRUE)); + g_test_assert_expected_messages (); + + g_assert_true (g_variant_check_format_string (value, "(s^as)", TRUE)); + g_assert_true (g_variant_check_format_string (value, "(s^as)", FALSE)); + + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*"); + g_assert_false (g_variant_check_format_string (value, "(s^a&s)", TRUE)); + g_test_assert_expected_messages (); + g_assert_true (g_variant_check_format_string (value, "(s^a&s)", FALSE)); + + g_variant_unref (value); + + /* Do it again with a type that will let us put a '&' after a '^' */ + value = g_variant_new ("(say)", "foo", NULL); + g_variant_ref_sink (value); + + g_assert_true (g_variant_check_format_string (value, "(s*)", TRUE)); + g_assert_true (g_variant_check_format_string (value, "(s*)", FALSE)); + g_assert_false (g_variant_check_format_string (value, "(u*)", TRUE)); + g_assert_false (g_variant_check_format_string (value, "(u*)", FALSE)); + + g_assert_true (g_variant_check_format_string (value, "(&s*)", FALSE)); + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*"); + g_assert_false (g_variant_check_format_string (value, "(&s*)", TRUE)); + g_test_assert_expected_messages (); + + g_assert_true (g_variant_check_format_string (value, "(s^ay)", TRUE)); + g_assert_true (g_variant_check_format_string (value, "(s^ay)", FALSE)); + + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*contains a '&' character*"); + g_assert_false (g_variant_check_format_string (value, "(s^&ay)", TRUE)); + g_test_assert_expected_messages (); + g_assert_true (g_variant_check_format_string (value, "(s^&ay)", FALSE)); + + g_assert_true (g_variant_check_format_string (value, "r", FALSE)); + g_assert_true (g_variant_check_format_string (value, "(?a?)", FALSE)); + + g_variant_unref (value); +} + +static void +verify_gvariant_checksum (const gchar *sha256, + GVariant *v) + +{ + gchar *checksum; + checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256, + g_variant_get_data (v), + g_variant_get_size (v)); + g_assert_cmpstr (sha256, ==, checksum); + g_free (checksum); +} + +static void +verify_gvariant_checksum_va (const gchar *sha256, + const gchar *fmt, + ...) +{ + va_list args; + GVariant *v; + + va_start (args, fmt); + + v = g_variant_new_va (fmt, NULL, &args); + g_variant_ref_sink (v); +#if G_BYTE_ORDER == G_BIG_ENDIAN + { + GVariant *byteswapped = g_variant_byteswap (v); + g_variant_unref (v); + v = byteswapped; + } +#endif + + va_end (args); + + verify_gvariant_checksum (sha256, v); + + g_variant_unref (v); +} + +static void +test_checksum_basic (void) +{ + verify_gvariant_checksum_va ("e8a4b2ee7ede79a3afb332b5b6cc3d952a65fd8cffb897f5d18016577c33d7cc", + "u", 42); + verify_gvariant_checksum_va ("c53e363c33b00cfce298229ee83856b8a98c2e6126cab13f65899f62473b0df5", + "s", "moocow"); + verify_gvariant_checksum_va ("2b4c342f5433ebe591a1da77e013d1b72475562d48578dca8b84bac6651c3cb9", + "y", 9); + verify_gvariant_checksum_va ("12a3ae445661ce5dee78d0650d33362dec29c4f82af05e7e57fb595bbbacf0ca", + "t", G_MAXUINT64); + verify_gvariant_checksum_va ("e25a59b24440eb6c833aa79c93b9840e6eab6966add0dacf31df7e9e7000f5b3", + "d", 3.14159); + verify_gvariant_checksum_va ("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", + "b", TRUE); + verify_gvariant_checksum_va ("ca2fd00fa001190744c15c317643ab092e7048ce086a243e2be9437c898de1bb", + "q", G_MAXUINT16); +} + +static void +test_checksum_nested (void) +{ + static const char* const strv[] = {"foo", "bar", "baz", NULL}; + + verify_gvariant_checksum_va ("31fbc92f08fddaca716188fe4b5d44ae122fc6306fd3c6925af53cfa47ea596d", + "(uu)", 41, 43); + verify_gvariant_checksum_va ("01759d683cead856d1d386d59af0578841698a424a265345ad5413122f220de8", + "(su)", "moocow", 79); + verify_gvariant_checksum_va ("52b3ae95f19b3e642ea1d01185aea14a09004c1d1712672644427403a8a0afe6", + "(qyst)", G_MAXUINT16, 9, "moocow", G_MAXUINT64); + verify_gvariant_checksum_va ("6fc6f4524161c3ae0d316812d7088e3fcd372023edaea2d7821093be40ae1060", + "(@ay)", g_variant_new_bytestring ("\xFF\xFF\xFF")); + verify_gvariant_checksum_va ("572aca386e1a983dd23bb6eb6e3dfa72eef9ca7c7744581aa800e18d7d9d0b0b", + "(^as)", strv); + verify_gvariant_checksum_va ("4bddf6174c791bb44fc6a4106573031690064df34b741033a0122ed8dc05bcf3", + "(yvu)", 254, g_variant_new ("(^as)", strv), 42); +} + +static void +test_gbytes (void) +{ + GVariant *a; + GVariant *tuple; + GBytes *bytes; + GBytes *bytes2; + const guint8 values[5] = { 1, 2, 3, 4, 5 }; + const guint8 *elts; + gsize n_elts; + gsize i; + + bytes = g_bytes_new (&values, 5); + a = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes, TRUE); + g_bytes_unref (bytes); + n_elts = 0; + elts = g_variant_get_fixed_array (a, &n_elts, sizeof (guint8)); + g_assert_cmpuint (n_elts, ==, 5); + for (i = 0; i < 5; i++) + g_assert_cmpuint (elts[i], ==, i + 1); + + bytes2 = g_variant_get_data_as_bytes (a); + g_variant_unref (a); + + bytes = g_bytes_new (&values, 5); + g_assert_true (g_bytes_equal (bytes, bytes2)); + g_bytes_unref (bytes); + g_bytes_unref (bytes2); + + tuple = g_variant_new_parsed ("['foo', 'bar']"); + bytes = g_variant_get_data_as_bytes (tuple); /* force serialization */ + a = g_variant_get_child_value (tuple, 1); + bytes2 = g_variant_get_data_as_bytes (a); + g_assert_false (g_bytes_equal (bytes, bytes2)); + + g_bytes_unref (bytes); + g_bytes_unref (bytes2); + g_variant_unref (a); + g_variant_unref (tuple); +} + +typedef struct { + const GVariantType *type; + const gchar *in; + const gchar *out; +} ContextTest; + +static void +test_print_context (void) +{ + ContextTest tests[] = { + { NULL, "(1, 2, 3, 'abc", " ^^^^" }, + { NULL, "[1, 2, 3, 'str']", " ^ ^^^^^" }, + { G_VARIANT_TYPE_UINT16, "{ 'abc':'def' }", " ^^^^^^^^^^^^^^^" }, + { NULL, "<5", " ^" }, + { NULL, "'ab\\ux'", " ^ " }, + { NULL, "'ab\\U00efx'", " ^^^^ " } + }; + GVariant *v; + gchar *s; + gsize i; + GError *error = NULL; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + v = g_variant_parse (tests[i].type, tests[i].in, NULL, NULL, &error); + g_assert_null (v); + s = g_variant_parse_error_print_context (error, tests[i].in); + g_assert_nonnull (strstr (s, tests[i].out)); + g_free (s); + g_clear_error (&error); + } +} + +static void +test_error_quark (void) +{ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_assert_cmpuint (g_variant_parser_get_error_quark (), ==, g_variant_parse_error_quark ()); +G_GNUC_END_IGNORE_DEPRECATIONS +} + +static void +test_stack_builder_init (void) +{ + GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_BYTESTRING); + GVariant *variant; + + g_variant_builder_add_value (&builder, g_variant_new_byte ('g')); + g_variant_builder_add_value (&builder, g_variant_new_byte ('l')); + g_variant_builder_add_value (&builder, g_variant_new_byte ('i')); + g_variant_builder_add_value (&builder, g_variant_new_byte ('b')); + g_variant_builder_add_value (&builder, g_variant_new_byte ('\0')); + + variant = g_variant_ref_sink (g_variant_builder_end (&builder)); + g_assert_nonnull (variant); + g_assert_true (g_variant_type_equal (g_variant_get_type (variant), + G_VARIANT_TYPE_BYTESTRING)); + g_assert_cmpuint (g_variant_n_children (variant), ==, 5); + g_assert_cmpstr (g_variant_get_bytestring (variant), ==, "glib"); + g_variant_unref (variant); +} + +static GVariant * +get_asv (void) +{ + GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); + + g_variant_builder_add (&builder, "{s@v}", "foo", g_variant_new_variant (g_variant_new_string ("FOO"))); + g_variant_builder_add (&builder, "{s@v}", "bar", g_variant_new_variant (g_variant_new_string ("BAR"))); + + return g_variant_ref_sink (g_variant_builder_end (&builder)); +} + +static void +test_stack_dict_init (void) +{ + GVariant *asv = get_asv (); + GVariantDict dict = G_VARIANT_DICT_INIT (asv); + GVariant *variant; + GVariantIter iter; + gchar *key; + GVariant *value; + + g_variant_dict_insert_value (&dict, "baz", g_variant_new_string ("BAZ")); + g_variant_dict_insert_value (&dict, "quux", g_variant_new_string ("QUUX")); + + variant = g_variant_ref_sink (g_variant_dict_end (&dict)); + g_assert_nonnull (variant); + g_assert_true (g_variant_type_equal (g_variant_get_type (variant), + G_VARIANT_TYPE_VARDICT)); + g_assert_cmpuint (g_variant_n_children (variant), ==, 4); + + g_variant_iter_init (&iter, variant); + while (g_variant_iter_next (&iter, "{sv}", &key, &value)) + { + gchar *strup = g_ascii_strup (key, -1); + + g_assert_cmpstr (strup, ==, g_variant_get_string (value, NULL)); + g_free (key); + g_free (strup); + g_variant_unref (value); + } + + g_variant_unref (asv); + g_variant_unref (variant); +} + +/* Test checking arbitrary binary data for normal form. This time, it’s a tuple + * with invalid element ends. */ +static void +test_normal_checking_tuples (void) +{ + const guint8 data[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 'a', '(', 'a', 'o', 'a', 'o', 'a', 'a', 'o', 'a', 'a', 'o', ')' + }; + gsize size = sizeof (data); + GVariant *variant = NULL; + GVariant *normal_variant = NULL; + + variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, + FALSE, NULL, NULL); + g_assert_nonnull (variant); + + normal_variant = g_variant_get_normal_form (variant); + g_assert_nonnull (normal_variant); + + g_variant_unref (normal_variant); + g_variant_unref (variant); +} + +/* Check that deeply nested variants are not considered in normal form when + * deserialized from untrusted data.*/ +static void +test_recursion_limits_variant_in_variant (void) +{ + GVariant *wrapper_variant = NULL; + gsize i; + GBytes *bytes = NULL; + GVariant *deserialised_variant = NULL; + + /* Construct a hierarchy of variants, containing a single string. This is just + * below the maximum recursion level, as a series of nested variant types. */ + wrapper_variant = g_variant_new_string ("hello"); + + for (i = 0; i < G_VARIANT_MAX_RECURSION_DEPTH - 1; i++) + wrapper_variant = g_variant_new_variant (g_steal_pointer (&wrapper_variant)); + + /* Serialize and deserialize it as untrusted data, to force normalisation. */ + bytes = g_variant_get_data_as_bytes (wrapper_variant); + deserialised_variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, + bytes, FALSE); + g_assert_nonnull (deserialised_variant); + g_assert_true (g_variant_is_normal_form (deserialised_variant)); + + g_bytes_unref (bytes); + g_variant_unref (deserialised_variant); + + /* Wrap it once more. Normalisation should now fail. */ + wrapper_variant = g_variant_new_variant (g_steal_pointer (&wrapper_variant)); + + bytes = g_variant_get_data_as_bytes (wrapper_variant); + deserialised_variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, + bytes, FALSE); + g_assert_nonnull (deserialised_variant); + g_assert_false (g_variant_is_normal_form (deserialised_variant)); + + g_variant_unref (deserialised_variant); + + /* Deserialize it again, but trusted this time. This should succeed. */ + deserialised_variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, + bytes, TRUE); + g_assert_nonnull (deserialised_variant); + g_assert_true (g_variant_is_normal_form (deserialised_variant)); + + g_bytes_unref (bytes); + g_variant_unref (deserialised_variant); + g_variant_unref (wrapper_variant); +} + +/* Check that deeply nested arrays are not considered in normal form when + * deserialized from untrusted data after being wrapped in a variant. This is + * worth testing, because neither the deeply nested array, nor the variant, + * have a static #GVariantType which is too deep — only when nested together do + * they become too deep. */ +static void +test_recursion_limits_array_in_variant (void) +{ + GVariant *child_variant = NULL; + GVariant *wrapper_variant = NULL; + gsize i; + GBytes *bytes = NULL; + GVariant *deserialised_variant = NULL; + + /* Construct a hierarchy of arrays, containing a single string. This is just + * below the maximum recursion level, all in a single definite type. */ + child_variant = g_variant_new_string ("hello"); + + for (i = 0; i < G_VARIANT_MAX_RECURSION_DEPTH - 1; i++) + child_variant = g_variant_new_array (NULL, &child_variant, 1); + + /* Serialize and deserialize it as untrusted data, to force normalisation. */ + bytes = g_variant_get_data_as_bytes (child_variant); + deserialised_variant = g_variant_new_from_bytes (g_variant_get_type (child_variant), + bytes, FALSE); + g_assert_nonnull (deserialised_variant); + g_assert_true (g_variant_is_normal_form (deserialised_variant)); + + g_bytes_unref (bytes); + g_variant_unref (deserialised_variant); + + /* Wrap it in a variant. Normalisation should now fail. */ + wrapper_variant = g_variant_new_variant (g_steal_pointer (&child_variant)); + + bytes = g_variant_get_data_as_bytes (wrapper_variant); + deserialised_variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, + bytes, FALSE); + g_assert_nonnull (deserialised_variant); + g_assert_false (g_variant_is_normal_form (deserialised_variant)); + + g_variant_unref (deserialised_variant); + + /* Deserialize it again, but trusted this time. This should succeed. */ + deserialised_variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, + bytes, TRUE); + g_assert_nonnull (deserialised_variant); + g_assert_true (g_variant_is_normal_form (deserialised_variant)); + + g_bytes_unref (bytes); + g_variant_unref (deserialised_variant); + g_variant_unref (wrapper_variant); +} + +/* Test that an array with invalidly large values in its offset table is + * normalised successfully without looping infinitely. */ +static void +test_normal_checking_array_offsets (void) +{ + const guint8 data[] = { + 0x07, 0xe5, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'g', + }; + gsize size = sizeof (data); + GVariant *variant = NULL; + GVariant *normal_variant = NULL; + + variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, + FALSE, NULL, NULL); + g_assert_nonnull (variant); + + normal_variant = g_variant_get_normal_form (variant); + g_assert_nonnull (normal_variant); + + g_variant_unref (normal_variant); + g_variant_unref (variant); +} + +/* Test that a tuple with invalidly large values in its offset table is + * normalised successfully without looping infinitely. */ +static void +test_normal_checking_tuple_offsets (void) +{ + const guint8 data[] = { + 0x07, 0xe5, 0x00, 0x07, 0x00, 0x07, + '(', 'a', 's', 'a', 's', 'a', 's', 'a', 's', 'a', 's', 'a', 's', ')', + }; + gsize size = sizeof (data); + GVariant *variant = NULL; + GVariant *normal_variant = NULL; + + variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, + FALSE, NULL, NULL); + g_assert_nonnull (variant); + + normal_variant = g_variant_get_normal_form (variant); + g_assert_nonnull (normal_variant); + + g_variant_unref (normal_variant); + g_variant_unref (variant); +} + +/* Test that an empty object path is normalised successfully to the base object + * path, ‘/’. */ +static void +test_normal_checking_empty_object_path (void) +{ + const guint8 data[] = { + 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, + '(', 'h', '(', 'a', 'i', 'a', 'b', 'i', 'o', ')', ')', + }; + gsize size = sizeof (data); + GVariant *variant = NULL; + GVariant *normal_variant = NULL; + + variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, + FALSE, NULL, NULL); + g_assert_nonnull (variant); + + normal_variant = g_variant_get_normal_form (variant); + g_assert_nonnull (normal_variant); + + g_variant_unref (normal_variant); + g_variant_unref (variant); +} + +/* Test that constructing a #GVariant from data which is not correctly aligned + * for the variant type is OK, by loading a variant from data at various offsets + * which are aligned and unaligned. When unaligned, a slow construction path + * should be taken. */ +static void +test_unaligned_construction (void) +{ + const guint8 data[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + }; + GVariant *variant = NULL; + GVariant *normal_variant = NULL; + gsize i, offset; + const struct { + const GVariantType *type; + gsize size; + gsize max_offset; + } vectors[] = { + { G_VARIANT_TYPE_UINT64, sizeof (guint64), sizeof (guint64) }, + { G_VARIANT_TYPE_UINT32, sizeof (guint32), sizeof (guint32) }, + { G_VARIANT_TYPE_UINT16, sizeof (guint16), sizeof (guint16) }, + { G_VARIANT_TYPE_BYTE, sizeof (guint8), 3 }, + }; + + G_STATIC_ASSERT (sizeof (guint64) * 2 <= sizeof (data)); + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + for (offset = 0; offset < vectors[i].max_offset; offset++) + { + variant = g_variant_new_from_data (vectors[i].type, data + offset, + vectors[i].size, + FALSE, NULL, NULL); + g_assert_nonnull (variant); + + normal_variant = g_variant_get_normal_form (variant); + g_assert_nonnull (normal_variant); + + g_variant_unref (normal_variant); + g_variant_unref (variant); + } + } +} + +int +main (int argc, char **argv) +{ + guint i; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gvariant/type", test_gvarianttype); + g_test_add_func ("/gvariant/type/string-scan/recursion/tuple", + test_gvarianttype_string_scan_recursion_tuple); + g_test_add_func ("/gvariant/type/string-scan/recursion/array", + test_gvarianttype_string_scan_recursion_array); + g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo); + g_test_add_func ("/gvariant/serialiser/maybe", test_maybes); + g_test_add_func ("/gvariant/serialiser/array", test_arrays); + g_test_add_func ("/gvariant/serialiser/tuple", test_tuples); + g_test_add_func ("/gvariant/serialiser/variant", test_variants); + g_test_add_func ("/gvariant/serialiser/strings", test_strings); + g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps); + g_test_add_func ("/gvariant/serialiser/children", test_serialiser_children); + + for (i = 1; i <= 20; i += 4) + { + char *testname; + + testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%u%%", i); + g_test_add_data_func (testname, GINT_TO_POINTER (i), + (gpointer) test_fuzzes); + g_free (testname); + } + + g_test_add_func ("/gvariant/string", test_string); + g_test_add_func ("/gvariant/utf8", test_utf8); + g_test_add_func ("/gvariant/containers", test_containers); + g_test_add_func ("/gvariant/format-strings", test_format_strings); + g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs); + g_test_add_func ("/gvariant/varargs", test_varargs); + g_test_add_func ("/gvariant/varargs/subprocess/empty-array", test_varargs_empty_array); + g_test_add_func ("/gvariant/valist", test_valist); + g_test_add_func ("/gvariant/builder-memory", test_builder_memory); + g_test_add_func ("/gvariant/hashing", test_hashing); + g_test_add_func ("/gvariant/byteswap", test_gv_byteswap); + g_test_add_func ("/gvariant/parser", test_parses); + g_test_add_func ("/gvariant/parser/integer-bounds", test_parser_integer_bounds); + g_test_add_func ("/gvariant/parser/recursion", test_parser_recursion); + g_test_add_func ("/gvariant/parse-failures", test_parse_failures); + g_test_add_func ("/gvariant/parse-positional", test_parse_positional); + g_test_add_func ("/gvariant/parse/subprocess/bad-format-char", test_parse_bad_format_char); + g_test_add_func ("/gvariant/parse/subprocess/bad-format-string", test_parse_bad_format_string); + g_test_add_func ("/gvariant/parse/subprocess/bad-args", test_parse_bad_args); + g_test_add_func ("/gvariant/floating", test_floating); + g_test_add_func ("/gvariant/bytestring", test_bytestring); + g_test_add_func ("/gvariant/lookup-value", test_lookup_value); + g_test_add_func ("/gvariant/lookup", test_lookup); + g_test_add_func ("/gvariant/compare", test_compare); + g_test_add_func ("/gvariant/equal", test_equal); + g_test_add_func ("/gvariant/fixed-array", test_fixed_array); + g_test_add_func ("/gvariant/check-format-string", test_check_format_string); + + g_test_add_func ("/gvariant/checksum-basic", test_checksum_basic); + g_test_add_func ("/gvariant/checksum-nested", test_checksum_nested); + + g_test_add_func ("/gvariant/gbytes", test_gbytes); + g_test_add_func ("/gvariant/print-context", test_print_context); + g_test_add_func ("/gvariant/error-quark", test_error_quark); + + g_test_add_func ("/gvariant/stack-builder-init", test_stack_builder_init); + g_test_add_func ("/gvariant/stack-dict-init", test_stack_dict_init); + + g_test_add_func ("/gvariant/normal-checking/tuples", + test_normal_checking_tuples); + g_test_add_func ("/gvariant/normal-checking/array-offsets", + test_normal_checking_array_offsets); + g_test_add_func ("/gvariant/normal-checking/tuple-offsets", + test_normal_checking_tuple_offsets); + g_test_add_func ("/gvariant/normal-checking/empty-object-path", + test_normal_checking_empty_object_path); + + g_test_add_func ("/gvariant/recursion-limits/variant-in-variant", + test_recursion_limits_variant_in_variant); + g_test_add_func ("/gvariant/recursion-limits/array-in-variant", + test_recursion_limits_array_in_variant); + + g_test_add_func ("/gvariant/unaligned-construction", + test_unaligned_construction); + + return g_test_run (); +} diff --git a/glib/tests/gwakeuptest.c b/glib/tests/gwakeuptest.c new file mode 100644 index 0000000..b37fb43 --- /dev/null +++ b/glib/tests/gwakeuptest.c @@ -0,0 +1,276 @@ +#include +#include +#ifdef G_OS_UNIX +#include +#endif + +#ifdef _WIN32 +static void alarm (int sec) { } +#endif + +static gboolean +check_signaled (GWakeup *wakeup) +{ + GPollFD fd; + + g_wakeup_get_pollfd (wakeup, &fd); + return g_poll (&fd, 1, 0); +} + +static void +wait_for_signaled (GWakeup *wakeup) +{ + GPollFD fd; + + g_wakeup_get_pollfd (wakeup, &fd); + g_poll (&fd, 1, -1); +} + +static void +test_semantics (void) +{ + GWakeup *wakeup; + gint i; + + /* prevent the test from deadlocking */ + alarm (60); + + wakeup = g_wakeup_new (); + g_assert (!check_signaled (wakeup)); + + g_wakeup_signal (wakeup); + g_assert (check_signaled (wakeup)); + + g_wakeup_acknowledge (wakeup); + g_assert (!check_signaled (wakeup)); + + g_wakeup_free (wakeup); + + /* free unused */ + wakeup = g_wakeup_new (); + g_wakeup_free (wakeup); + + /* free while signaled */ + wakeup = g_wakeup_new (); + g_wakeup_signal (wakeup); + g_wakeup_free (wakeup); + + /* ensure excessive signalling doesn't deadlock */ + wakeup = g_wakeup_new (); + for (i = 0; i < 1000000; i++) + g_wakeup_signal (wakeup); + g_assert (check_signaled (wakeup)); + + /* ensure a single acknowledgement is sufficient */ + g_wakeup_acknowledge (wakeup); + g_assert (!check_signaled (wakeup)); + + g_wakeup_free (wakeup); + + /* cancel the alarm */ + alarm (0); +} + +struct token +{ + gpointer owner; + gint ttl; +}; + +struct context +{ + GSList *pending_tokens; + GMutex lock; + GWakeup *wakeup; + gboolean quit; +}; + +#define NUM_THREADS 50 +#define NUM_TOKENS 5 +#define TOKEN_TTL 100000 + +static struct context contexts[NUM_THREADS]; +static GThread *threads[NUM_THREADS]; +static GWakeup *last_token_wakeup; +static gint tokens_alive; /* (atomic) */ + +static void +context_init (struct context *ctx) +{ + ctx->pending_tokens = NULL; + g_mutex_init (&ctx->lock); + ctx->wakeup = g_wakeup_new (); + ctx->quit = FALSE; +} + +static void +context_clear (struct context *ctx) +{ + g_assert (ctx->pending_tokens == NULL); + g_assert (ctx->quit); + + g_mutex_clear (&ctx->lock); + g_wakeup_free (ctx->wakeup); +} + +static void +context_quit (struct context *ctx) +{ + g_atomic_int_set (&ctx->quit, TRUE); + g_wakeup_signal (ctx->wakeup); +} + +static struct token * +context_try_pop_token (struct context *ctx) +{ + struct token *token = NULL; + + g_mutex_lock (&ctx->lock); + if (ctx->pending_tokens != NULL) + { + token = ctx->pending_tokens->data; + ctx->pending_tokens = g_slist_delete_link (ctx->pending_tokens, + ctx->pending_tokens); + } + g_mutex_unlock (&ctx->lock); + + return token; +} + +static void +context_push_token (struct context *ctx, + struct token *token) +{ + g_assert (token->owner == ctx); + + g_mutex_lock (&ctx->lock); + ctx->pending_tokens = g_slist_prepend (ctx->pending_tokens, token); + g_mutex_unlock (&ctx->lock); + + g_wakeup_signal (ctx->wakeup); +} + +static void +dispatch_token (struct token *token) +{ + if (token->ttl > 0) + { + struct context *ctx; + gint next_ctx; + + next_ctx = g_test_rand_int_range (0, NUM_THREADS); + ctx = &contexts[next_ctx]; + token->owner = ctx; + token->ttl--; + + context_push_token (ctx, token); + } + else + { + g_slice_free (struct token, token); + + if (g_atomic_int_dec_and_test (&tokens_alive)) + g_wakeup_signal (last_token_wakeup); + } +} + +static struct token * +token_new (int ttl) +{ + struct token *token; + + token = g_slice_new (struct token); + token->ttl = ttl; + + g_atomic_int_inc (&tokens_alive); + + return token; +} + +static gpointer +thread_func (gpointer data) +{ + struct context *ctx = data; + struct token *token; + + while (!g_atomic_int_get (&ctx->quit)) + { + wait_for_signaled (ctx->wakeup); + g_wakeup_acknowledge (ctx->wakeup); + + while ((token = context_try_pop_token (ctx)) != NULL) + { + g_assert (token->owner == ctx); + dispatch_token (token); + } + } + + return NULL; +} + +static void +test_threaded (void) +{ + gint i; + + /* make sure we don't block forever */ + alarm (60); + + /* simple mainloop test based on GWakeup. + * + * create a bunch of contexts and a thread to 'run' each one. create + * some tokens and randomly pass them between the threads, until the + * TTL on each token is zero. + * + * when no tokens are left, signal that we are done. the mainthread + * will then signal each worker thread to exit and join them to make + * sure that works. + */ + + last_token_wakeup = g_wakeup_new (); + + /* create contexts, assign to threads */ + for (i = 0; i < NUM_THREADS; i++) + { + context_init (&contexts[i]); + threads[i] = g_thread_new ("test", thread_func, &contexts[i]); + } + + /* dispatch tokens */ + for (i = 0; i < NUM_TOKENS; i++) + dispatch_token (token_new (TOKEN_TTL)); + + /* wait until all tokens are gone */ + wait_for_signaled (last_token_wakeup); + + /* ask threads to quit, join them, cleanup */ + for (i = 0; i < NUM_THREADS; i++) + { + context_quit (&contexts[i]); + g_thread_join (threads[i]); + context_clear (&contexts[i]); + } + + g_wakeup_free (last_token_wakeup); + + /* cancel alarm */ + alarm (0); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + +#ifdef TEST_EVENTFD_FALLBACK +#define TESTNAME_SUFFIX "-fallback" +#else +#define TESTNAME_SUFFIX +#endif + + + g_test_add_func ("/gwakeup/semantics" TESTNAME_SUFFIX, test_semantics); + g_test_add_func ("/gwakeup/threaded" TESTNAME_SUFFIX, test_threaded); + + return g_test_run (); +} diff --git a/glib/tests/hash.c b/glib/tests/hash.c new file mode 100644 index 0000000..114b6a2 --- /dev/null +++ b/glib/tests/hash.c @@ -0,0 +1,1742 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * Copyright (C) 1999 The Free Software Foundation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include + +#include +#include +#include + +#include + +static int global_array[10000]; + +static void +fill_hash_table_and_array (GHashTable *hash_table) +{ + int i; + + for (i = 0; i < 10000; i++) + { + global_array[i] = i; + g_hash_table_insert (hash_table, &global_array[i], &global_array[i]); + } +} + +static void +init_result_array (int result_array[10000]) +{ + int i; + + for (i = 0; i < 10000; i++) + result_array[i] = -1; +} + +static void +verify_result_array (int array[10000]) +{ + int i; + + for (i = 0; i < 10000; i++) + g_assert (array[i] == i); +} + +static void +handle_pair (gpointer key, gpointer value, int result_array[10000]) +{ + int n; + + g_assert (key == value); + + n = *((int *) value); + + g_assert (n >= 0 && n < 10000); + g_assert (result_array[n] == -1); + + result_array[n] = n; +} + +static gboolean +my_hash_callback_remove (gpointer key, + gpointer value, + gpointer user_data) +{ + int *d = value; + + if ((*d) % 2) + return TRUE; + + return FALSE; +} + +static void +my_hash_callback_remove_test (gpointer key, + gpointer value, + gpointer user_data) +{ + int *d = value; + + if ((*d) % 2) + g_assert_not_reached (); +} + +static void +my_hash_callback (gpointer key, + gpointer value, + gpointer user_data) +{ + handle_pair (key, value, user_data); +} + +static guint +my_hash (gconstpointer key) +{ + return (guint) *((const gint*) key); +} + +static gboolean +my_hash_equal (gconstpointer a, + gconstpointer b) +{ + return *((const gint*) a) == *((const gint*) b); +} + + + +/* + * This is a simplified version of the pathalias hashing function. + * Thanks to Steve Belovin and Peter Honeyman + * + * hash a string into a long int. 31 bit crc (from andrew appel). + * the crc table is computed at run time by crcinit() -- we could + * precompute, but it takes 1 clock tick on a 750. + * + * This fast table calculation works only if POLY is a prime polynomial + * in the field of integers modulo 2. Since the coefficients of a + * 32-bit polynomial won't fit in a 32-bit word, the high-order bit is + * implicit. IT MUST ALSO BE THE CASE that the coefficients of orders + * 31 down to 25 are zero. Happily, we have candidates, from + * E. J. Watson, "Primitive Polynomials (Mod 2)", Math. Comp. 16 (1962): + * x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + x^0 + * x^31 + x^3 + x^0 + * + * We reverse the bits to get: + * 111101010000000000000000000000001 but drop the last 1 + * f 5 0 0 0 0 0 0 + * 010010000000000000000000000000001 ditto, for 31-bit crc + * 4 8 0 0 0 0 0 0 + */ + +#define POLY 0x48000000L /* 31-bit polynomial (avoids sign problems) */ + +static guint CrcTable[128]; + +/* + - crcinit - initialize tables for hash function + */ +static void crcinit(void) +{ + int i, j; + guint sum; + + for (i = 0; i < 128; ++i) + { + sum = 0L; + for (j = 7 - 1; j >= 0; --j) + if (i & (1 << j)) + sum ^= POLY >> j; + CrcTable[i] = sum; + } +} + +/* + - hash - Honeyman's nice hashing function + */ +static guint +honeyman_hash (gconstpointer key) +{ + const gchar *name = (const gchar *) key; + gsize size; + guint sum = 0; + + g_assert (name != NULL); + g_assert (*name != 0); + + size = strlen (name); + + while (size--) + sum = (sum >> 7) ^ CrcTable[(sum ^ (*name++)) & 0x7f]; + + return sum; +} + + +static gboolean +second_hash_cmp (gconstpointer a, gconstpointer b) +{ + return strcmp (a, b) == 0; +} + + + +static guint +one_hash (gconstpointer key) +{ + return 1; +} + + +static void +not_even_foreach (gpointer key, + gpointer value, + gpointer user_data) +{ + const char *_key = (const char *) key; + const char *_value = (const char *) value; + int i; + char val [20]; + + g_assert (_key != NULL); + g_assert (*_key != 0); + g_assert (_value != NULL); + g_assert (*_value != 0); + + i = atoi (_key); + + sprintf (val, "%d value", i); + g_assert (strcmp (_value, val) == 0); + + g_assert ((i % 2) != 0); + g_assert (i != 3); +} + +static gboolean +remove_even_foreach (gpointer key, + gpointer value, + gpointer user_data) +{ + const char *_key = (const char *) key; + const char *_value = (const char *) value; + int i; + char val [20]; + + g_assert (_key != NULL); + g_assert (*_key != 0); + g_assert (_value != NULL); + g_assert (*_value != 0); + + i = atoi (_key); + + sprintf (val, "%d value", i); + g_assert (strcmp (_value, val) == 0); + + return ((i % 2) == 0) ? TRUE : FALSE; +} + + + + +static void +second_hash_test (gconstpointer d) +{ + gboolean simple_hash = GPOINTER_TO_INT (d); + + int i; + char key[20] = "", val[20]="", *v, *orig_key, *orig_val; + GHashTable *h; + gboolean found; + + crcinit (); + + h = g_hash_table_new_full (simple_hash ? one_hash : honeyman_hash, + second_hash_cmp, + g_free, g_free); + g_assert (h != NULL); + for (i = 0; i < 20; i++) + { + sprintf (key, "%d", i); + g_assert (atoi (key) == i); + + sprintf (val, "%d value", i); + g_assert (atoi (val) == i); + + g_hash_table_insert (h, g_strdup (key), g_strdup (val)); + } + + g_assert (g_hash_table_size (h) == 20); + + for (i = 0; i < 20; i++) + { + sprintf (key, "%d", i); + g_assert (atoi(key) == i); + + v = (char *) g_hash_table_lookup (h, key); + + g_assert (v != NULL); + g_assert (*v != 0); + g_assert (atoi (v) == i); + } + + sprintf (key, "%d", 3); + g_hash_table_remove (h, key); + g_assert (g_hash_table_size (h) == 19); + g_hash_table_foreach_remove (h, remove_even_foreach, NULL); + g_assert (g_hash_table_size (h) == 9); + g_hash_table_foreach (h, not_even_foreach, NULL); + + for (i = 0; i < 20; i++) + { + sprintf (key, "%d", i); + g_assert (atoi(key) == i); + + sprintf (val, "%d value", i); + g_assert (atoi (val) == i); + + orig_key = orig_val = NULL; + found = g_hash_table_lookup_extended (h, key, + (gpointer)&orig_key, + (gpointer)&orig_val); + if ((i % 2) == 0 || i == 3) + { + g_assert (!found); + continue; + } + + g_assert (found); + + g_assert (orig_key != NULL); + g_assert (strcmp (key, orig_key) == 0); + + g_assert (orig_val != NULL); + g_assert (strcmp (val, orig_val) == 0); + } + + g_hash_table_destroy (h); +} + +static gboolean +find_first (gpointer key, + gpointer value, + gpointer user_data) +{ + gint *v = value; + gint *test = user_data; + return (*v == *test); +} + +static void +direct_hash_test (void) +{ + gint i, rc; + GHashTable *h; + + h = g_hash_table_new (NULL, NULL); + g_assert (h != NULL); + for (i = 1; i <= 20; i++) + g_hash_table_insert (h, GINT_TO_POINTER (i), + GINT_TO_POINTER (i + 42)); + + g_assert (g_hash_table_size (h) == 20); + + for (i = 1; i <= 20; i++) + { + rc = GPOINTER_TO_INT (g_hash_table_lookup (h, GINT_TO_POINTER (i))); + + g_assert (rc != 0); + g_assert ((rc - 42) == i); + } + + g_hash_table_destroy (h); +} + +static void +direct_hash_test2 (void) +{ + gint i, rc; + GHashTable *h; + + h = g_hash_table_new (g_direct_hash, g_direct_equal); + g_assert (h != NULL); + for (i = 1; i <= 20; i++) + g_hash_table_insert (h, GINT_TO_POINTER (i), + GINT_TO_POINTER (i + 42)); + + g_assert (g_hash_table_size (h) == 20); + + for (i = 1; i <= 20; i++) + { + rc = GPOINTER_TO_INT (g_hash_table_lookup (h, GINT_TO_POINTER (i))); + + g_assert (rc != 0); + g_assert ((rc - 42) == i); + } + + g_hash_table_destroy (h); +} + +static void +int_hash_test (void) +{ + gint i, rc; + GHashTable *h; + gint values[20]; + gint key; + + h = g_hash_table_new (g_int_hash, g_int_equal); + g_assert (h != NULL); + for (i = 0; i < 20; i++) + { + values[i] = i + 42; + g_hash_table_insert (h, &values[i], GINT_TO_POINTER (i + 42)); + } + + g_assert (g_hash_table_size (h) == 20); + + for (i = 0; i < 20; i++) + { + key = i + 42; + rc = GPOINTER_TO_INT (g_hash_table_lookup (h, &key)); + + g_assert_cmpint (rc, ==, i + 42); + } + + g_hash_table_destroy (h); +} + +static void +int64_hash_test (void) +{ + gint i, rc; + GHashTable *h; + gint64 values[20]; + gint64 key; + + h = g_hash_table_new (g_int64_hash, g_int64_equal); + g_assert (h != NULL); + for (i = 0; i < 20; i++) + { + values[i] = i + 42; + g_hash_table_insert (h, &values[i], GINT_TO_POINTER (i + 42)); + } + + g_assert (g_hash_table_size (h) == 20); + + for (i = 0; i < 20; i++) + { + key = i + 42; + rc = GPOINTER_TO_INT (g_hash_table_lookup (h, &key)); + + g_assert_cmpint (rc, ==, i + 42); + } + + g_hash_table_destroy (h); +} + +static void +double_hash_test (void) +{ + gint i, rc; + GHashTable *h; + gdouble values[20]; + gdouble key; + + h = g_hash_table_new (g_double_hash, g_double_equal); + g_assert (h != NULL); + for (i = 0; i < 20; i++) + { + values[i] = i + 42.5; + g_hash_table_insert (h, &values[i], GINT_TO_POINTER (i + 42)); + } + + g_assert (g_hash_table_size (h) == 20); + + for (i = 0; i < 20; i++) + { + key = i + 42.5; + rc = GPOINTER_TO_INT (g_hash_table_lookup (h, &key)); + + g_assert_cmpint (rc, ==, i + 42); + } + + g_hash_table_destroy (h); +} + +static void +string_free (gpointer data) +{ + GString *s = data; + + g_string_free (s, TRUE); +} + +static void +string_hash_test (void) +{ + gint i, rc; + GHashTable *h; + GString *s; + + h = g_hash_table_new_full ((GHashFunc)g_string_hash, (GEqualFunc)g_string_equal, string_free, NULL); + g_assert (h != NULL); + for (i = 0; i < 20; i++) + { + s = g_string_new (""); + g_string_append_printf (s, "%d", i + 42); + g_string_append_c (s, '.'); + g_string_prepend_unichar (s, 0x2301); + g_hash_table_insert (h, s, GINT_TO_POINTER (i + 42)); + } + + g_assert (g_hash_table_size (h) == 20); + + s = g_string_new (""); + for (i = 0; i < 20; i++) + { + g_string_assign (s, ""); + g_string_append_printf (s, "%d", i + 42); + g_string_append_c (s, '.'); + g_string_prepend_unichar (s, 0x2301); + rc = GPOINTER_TO_INT (g_hash_table_lookup (h, s)); + + g_assert_cmpint (rc, ==, i + 42); + } + + g_string_free (s, TRUE); + g_hash_table_destroy (h); +} + +static void +set_check (gpointer key, + gpointer value, + gpointer user_data) +{ + int *pi = user_data; + if (key != value) + g_assert_not_reached (); + + g_assert_cmpint (atoi (key) % 7, ==, 2); + + (*pi)++; +} + +static void +set_hash_test (void) +{ + GHashTable *hash_table = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + int i; + + for (i = 2; i < 5000; i += 7) + { + char *s = g_strdup_printf ("%d", i); + g_assert (g_hash_table_add (hash_table, s)); + } + + g_assert (!g_hash_table_add (hash_table, g_strdup_printf ("%d", 2))); + + i = 0; + g_hash_table_foreach (hash_table, set_check, &i); + g_assert_cmpint (i, ==, g_hash_table_size (hash_table)); + + g_assert (g_hash_table_contains (hash_table, "2")); + g_assert (g_hash_table_contains (hash_table, "9")); + g_assert (!g_hash_table_contains (hash_table, "a")); + + /* this will cause the hash table to loose set nature */ + g_assert (g_hash_table_insert (hash_table, g_strdup ("a"), "b")); + g_assert (!g_hash_table_insert (hash_table, g_strdup ("a"), "b")); + + g_assert (g_hash_table_replace (hash_table, g_strdup ("c"), "d")); + g_assert (!g_hash_table_replace (hash_table, g_strdup ("c"), "d")); + + g_assert_cmpstr (g_hash_table_lookup (hash_table, "2"), ==, "2"); + g_assert_cmpstr (g_hash_table_lookup (hash_table, "a"), ==, "b"); + + g_hash_table_destroy (hash_table); +} + + +static void +test_hash_misc (void) +{ + GHashTable *hash_table; + gint i; + gint value = 120; + gint *pvalue; + GList *keys, *values; + gsize keys_len, values_len; + GHashTableIter iter; + gpointer ikey, ivalue; + int result_array[10000]; + int n_array[1]; + + hash_table = g_hash_table_new (my_hash, my_hash_equal); + fill_hash_table_and_array (hash_table); + pvalue = g_hash_table_find (hash_table, find_first, &value); + if (!pvalue || *pvalue != value) + g_assert_not_reached(); + + keys = g_hash_table_get_keys (hash_table); + if (!keys) + g_assert_not_reached (); + + values = g_hash_table_get_values (hash_table); + if (!values) + g_assert_not_reached (); + + keys_len = g_list_length (keys); + values_len = g_list_length (values); + if (values_len != keys_len && keys_len != g_hash_table_size (hash_table)) + g_assert_not_reached (); + + g_list_free (keys); + g_list_free (values); + + init_result_array (result_array); + g_hash_table_iter_init (&iter, hash_table); + for (i = 0; i < 10000; i++) + { + g_assert (g_hash_table_iter_next (&iter, &ikey, &ivalue)); + + handle_pair (ikey, ivalue, result_array); + + if (i % 2) + g_hash_table_iter_remove (&iter); + } + g_assert (! g_hash_table_iter_next (&iter, &ikey, &ivalue)); + g_assert (g_hash_table_size (hash_table) == 5000); + verify_result_array (result_array); + + fill_hash_table_and_array (hash_table); + + init_result_array (result_array); + g_hash_table_foreach (hash_table, my_hash_callback, result_array); + verify_result_array (result_array); + + for (i = 0; i < 10000; i++) + g_hash_table_remove (hash_table, &global_array[i]); + + fill_hash_table_and_array (hash_table); + + if (g_hash_table_foreach_remove (hash_table, my_hash_callback_remove, NULL) != 5000 || + g_hash_table_size (hash_table) != 5000) + g_assert_not_reached(); + + g_hash_table_foreach (hash_table, my_hash_callback_remove_test, NULL); + g_hash_table_destroy (hash_table); + + hash_table = g_hash_table_new (my_hash, my_hash_equal); + fill_hash_table_and_array (hash_table); + + n_array[0] = 1; + + g_hash_table_iter_init (&iter, hash_table); + for (i = 0; i < 10000; i++) + { + g_assert (g_hash_table_iter_next (&iter, &ikey, &ivalue)); + g_hash_table_iter_replace (&iter, &n_array[0]); + } + + g_hash_table_iter_init (&iter, hash_table); + for (i = 0; i < 10000; i++) + { + g_assert (g_hash_table_iter_next (&iter, &ikey, &ivalue)); + + g_assert (ivalue == &n_array[0]); + } + + g_hash_table_destroy (hash_table); +} + +static gint destroy_counter; + +static void +value_destroy (gpointer value) +{ + destroy_counter++; +} + +static void +test_hash_ref (void) +{ + GHashTable *h; + GHashTableIter iter; + gchar *key, *value; + gboolean abc_seen = FALSE; + gboolean cde_seen = FALSE; + gboolean xyz_seen = FALSE; + + h = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy); + g_hash_table_insert (h, "abc", "ABC"); + g_hash_table_insert (h, "cde", "CDE"); + g_hash_table_insert (h, "xyz", "XYZ"); + + g_assert_cmpint (g_hash_table_size (h), == , 3); + + g_hash_table_iter_init (&iter, h); + + while (g_hash_table_iter_next (&iter, (gpointer*)&key, (gpointer*)&value)) + { + if (strcmp (key, "abc") == 0) + { + g_assert_cmpstr (value, ==, "ABC"); + abc_seen = TRUE; + g_hash_table_iter_steal (&iter); + } + else if (strcmp (key, "cde") == 0) + { + g_assert_cmpstr (value, ==, "CDE"); + cde_seen = TRUE; + } + else if (strcmp (key, "xyz") == 0) + { + g_assert_cmpstr (value, ==, "XYZ"); + xyz_seen = TRUE; + } + } + g_assert_cmpint (destroy_counter, ==, 0); + + g_assert (g_hash_table_iter_get_hash_table (&iter) == h); + g_assert (abc_seen && cde_seen && xyz_seen); + g_assert_cmpint (g_hash_table_size (h), == , 2); + + g_hash_table_ref (h); + g_hash_table_destroy (h); + g_assert_cmpint (g_hash_table_size (h), == , 0); + g_assert_cmpint (destroy_counter, ==, 2); + g_hash_table_insert (h, "uvw", "UVW"); + g_hash_table_unref (h); + g_assert_cmpint (destroy_counter, ==, 3); +} + +static guint +null_safe_str_hash (gconstpointer key) +{ + if (key == NULL) + return 0; + else + return g_str_hash (key); +} + +static gboolean +null_safe_str_equal (gconstpointer a, gconstpointer b) +{ + return g_strcmp0 (a, b) == 0; +} + +static void +test_lookup_null_key (void) +{ + GHashTable *h; + gboolean res; + gpointer key; + gpointer value; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642944"); + + h = g_hash_table_new (null_safe_str_hash, null_safe_str_equal); + g_hash_table_insert (h, "abc", "ABC"); + + res = g_hash_table_lookup_extended (h, NULL, &key, &value); + g_assert (!res); + + g_hash_table_insert (h, NULL, "NULL"); + + res = g_hash_table_lookup_extended (h, NULL, &key, &value); + g_assert (res); + g_assert_cmpstr (value, ==, "NULL"); + + g_hash_table_unref (h); +} + +static gint destroy_key_counter; + +static void +key_destroy (gpointer key) +{ + destroy_key_counter++; +} + +static void +test_remove_all (void) +{ + GHashTable *h; + gboolean res; + + h = g_hash_table_new_full (g_str_hash, g_str_equal, key_destroy, value_destroy); + + g_hash_table_insert (h, "abc", "cde"); + g_hash_table_insert (h, "cde", "xyz"); + g_hash_table_insert (h, "xyz", "abc"); + + destroy_counter = 0; + destroy_key_counter = 0; + + g_hash_table_steal_all (h); + g_assert_cmpint (destroy_counter, ==, 0); + g_assert_cmpint (destroy_key_counter, ==, 0); + + /* Test stealing on an empty hash table. */ + g_hash_table_steal_all (h); + g_assert_cmpint (destroy_counter, ==, 0); + g_assert_cmpint (destroy_key_counter, ==, 0); + + g_hash_table_insert (h, "abc", "ABC"); + g_hash_table_insert (h, "cde", "CDE"); + g_hash_table_insert (h, "xyz", "XYZ"); + + res = g_hash_table_steal (h, "nosuchkey"); + g_assert (!res); + g_assert_cmpint (destroy_counter, ==, 0); + g_assert_cmpint (destroy_key_counter, ==, 0); + + res = g_hash_table_steal (h, "xyz"); + g_assert (res); + g_assert_cmpint (destroy_counter, ==, 0); + g_assert_cmpint (destroy_key_counter, ==, 0); + + g_hash_table_remove_all (h); + g_assert_cmpint (destroy_counter, ==, 2); + g_assert_cmpint (destroy_key_counter, ==, 2); + + g_hash_table_remove_all (h); + g_assert_cmpint (destroy_counter, ==, 2); + g_assert_cmpint (destroy_key_counter, ==, 2); + + g_hash_table_unref (h); +} + +GHashTable *recursive_destruction_table = NULL; +static void +recursive_value_destroy (gpointer value) +{ + destroy_counter++; + + if (recursive_destruction_table) + g_hash_table_remove (recursive_destruction_table, value); +} + +static void +test_recursive_remove_all_subprocess (void) +{ + GHashTable *h; + + h = g_hash_table_new_full (g_str_hash, g_str_equal, key_destroy, recursive_value_destroy); + recursive_destruction_table = h; + + /* Add more items compared to test_remove_all, as it would not fail otherwise. */ + g_hash_table_insert (h, "abc", "cde"); + g_hash_table_insert (h, "cde", "fgh"); + g_hash_table_insert (h, "fgh", "ijk"); + g_hash_table_insert (h, "ijk", "lmn"); + g_hash_table_insert (h, "lmn", "opq"); + g_hash_table_insert (h, "opq", "rst"); + g_hash_table_insert (h, "rst", "uvw"); + g_hash_table_insert (h, "uvw", "xyz"); + g_hash_table_insert (h, "xyz", "abc"); + + destroy_counter = 0; + destroy_key_counter = 0; + + g_hash_table_remove_all (h); + g_assert_cmpint (destroy_counter, ==, 9); + g_assert_cmpint (destroy_key_counter, ==, 9); + + g_hash_table_unref (h); +} + +static void +test_recursive_remove_all (void) +{ + g_test_trap_subprocess ("/hash/recursive-remove-all/subprocess", 1000000, 0); + g_test_trap_assert_passed (); +} + +typedef struct { + gint ref_count; + const gchar *key; +} RefCountedKey; + +static guint +hash_func (gconstpointer key) +{ + const RefCountedKey *rkey = key; + + return g_str_hash (rkey->key); +} + +static gboolean +eq_func (gconstpointer a, gconstpointer b) +{ + const RefCountedKey *aa = a; + const RefCountedKey *bb = b; + + return g_strcmp0 (aa->key, bb->key) == 0; +} + +static void +key_unref (gpointer data) +{ + RefCountedKey *key = data; + + g_assert (key->ref_count > 0); + + key->ref_count -= 1; + + if (key->ref_count == 0) + g_free (key); +} + +static RefCountedKey * +key_ref (RefCountedKey *key) +{ + key->ref_count += 1; + + return key; +} + +static RefCountedKey * +key_new (const gchar *key) +{ + RefCountedKey *rkey; + + rkey = g_new (RefCountedKey, 1); + + rkey->ref_count = 1; + rkey->key = key; + + return rkey; +} + +static void +set_ref_hash_test (void) +{ + GHashTable *h; + RefCountedKey *key1; + RefCountedKey *key2; + + h = g_hash_table_new_full (hash_func, eq_func, key_unref, key_unref); + + key1 = key_new ("a"); + key2 = key_new ("a"); + + g_assert_cmpint (key1->ref_count, ==, 1); + g_assert_cmpint (key2->ref_count, ==, 1); + + g_hash_table_insert (h, key_ref (key1), key_ref (key1)); + + g_assert_cmpint (key1->ref_count, ==, 3); + g_assert_cmpint (key2->ref_count, ==, 1); + + g_hash_table_replace (h, key_ref (key2), key_ref (key2)); + + g_assert_cmpint (key1->ref_count, ==, 1); + g_assert_cmpint (key2->ref_count, ==, 3); + + g_hash_table_remove (h, key1); + + g_assert_cmpint (key1->ref_count, ==, 1); + g_assert_cmpint (key2->ref_count, ==, 1); + + g_hash_table_unref (h); + + key_unref (key1); + key_unref (key2); +} + +static GHashTable *global_hashtable; + +typedef struct { + gchar *string; + gboolean freed; +} FakeFreeData; + +static GPtrArray *fake_free_data; + +static void +fake_free (gpointer dead) +{ + guint i; + + for (i = 0; i < fake_free_data->len; i++) + { + FakeFreeData *ffd = g_ptr_array_index (fake_free_data, i); + + if (ffd->string == (gchar *) dead) + { + g_assert (!ffd->freed); + ffd->freed = TRUE; + return; + } + } + + g_assert_not_reached (); +} + +static void +value_destroy_insert (gpointer value) +{ + g_hash_table_remove_all (global_hashtable); +} + +static void +test_destroy_modify (void) +{ + FakeFreeData *ffd; + guint i; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=650459"); + + fake_free_data = g_ptr_array_new (); + + global_hashtable = g_hash_table_new_full (g_str_hash, g_str_equal, fake_free, value_destroy_insert); + + ffd = g_new0 (FakeFreeData, 1); + ffd->string = g_strdup ("a"); + g_ptr_array_add (fake_free_data, ffd); + g_hash_table_insert (global_hashtable, ffd->string, "b"); + + ffd = g_new0 (FakeFreeData, 1); + ffd->string = g_strdup ("c"); + g_ptr_array_add (fake_free_data, ffd); + g_hash_table_insert (global_hashtable, ffd->string, "d"); + + ffd = g_new0 (FakeFreeData, 1); + ffd->string = g_strdup ("e"); + g_ptr_array_add (fake_free_data, ffd); + g_hash_table_insert (global_hashtable, ffd->string, "f"); + + ffd = g_new0 (FakeFreeData, 1); + ffd->string = g_strdup ("g"); + g_ptr_array_add (fake_free_data, ffd); + g_hash_table_insert (global_hashtable, ffd->string, "h"); + + ffd = g_new0 (FakeFreeData, 1); + ffd->string = g_strdup ("h"); + g_ptr_array_add (fake_free_data, ffd); + g_hash_table_insert (global_hashtable, ffd->string, "k"); + + ffd = g_new0 (FakeFreeData, 1); + ffd->string = g_strdup ("a"); + g_ptr_array_add (fake_free_data, ffd); + g_hash_table_insert (global_hashtable, ffd->string, "c"); + + g_hash_table_remove (global_hashtable, "c"); + + /* that removed everything... */ + for (i = 0; i < fake_free_data->len; i++) + { + ffd = g_ptr_array_index (fake_free_data, i); + + g_assert (ffd->freed); + g_free (ffd->string); + g_free (ffd); + } + + g_ptr_array_unref (fake_free_data); + + /* ... so this is a no-op */ + g_hash_table_remove (global_hashtable, "e"); + + g_hash_table_unref (global_hashtable); +} + +static gboolean +find_str (gpointer key, gpointer value, gpointer data) +{ + return g_str_equal (key, data); +} + +static void +test_find (void) +{ + GHashTable *hash; + const gchar *value; + + hash = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (hash, "a", "A"); + g_hash_table_insert (hash, "b", "B"); + g_hash_table_insert (hash, "c", "C"); + g_hash_table_insert (hash, "d", "D"); + g_hash_table_insert (hash, "e", "E"); + g_hash_table_insert (hash, "f", "F"); + + value = g_hash_table_find (hash, find_str, "a"); + g_assert_cmpstr (value, ==, "A"); + + value = g_hash_table_find (hash, find_str, "b"); + g_assert_cmpstr (value, ==, "B"); + + value = g_hash_table_find (hash, find_str, "c"); + g_assert_cmpstr (value, ==, "C"); + + value = g_hash_table_find (hash, find_str, "d"); + g_assert_cmpstr (value, ==, "D"); + + value = g_hash_table_find (hash, find_str, "e"); + g_assert_cmpstr (value, ==, "E"); + + value = g_hash_table_find (hash, find_str, "f"); + g_assert_cmpstr (value, ==, "F"); + + value = g_hash_table_find (hash, find_str, "0"); + g_assert (value == NULL); + + g_hash_table_unref (hash); +} + +gboolean seen_key[6]; + +static void +foreach_func (gpointer key, gpointer value, gpointer data) +{ + seen_key[((char*)key)[0] - 'a'] = TRUE; +} + +static void +test_foreach (void) +{ + GHashTable *hash; + gint i; + + hash = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (hash, "a", "A"); + g_hash_table_insert (hash, "b", "B"); + g_hash_table_insert (hash, "c", "C"); + g_hash_table_insert (hash, "d", "D"); + g_hash_table_insert (hash, "e", "E"); + g_hash_table_insert (hash, "f", "F"); + + for (i = 0; i < 6; i++) + seen_key[i] = FALSE; + + g_hash_table_foreach (hash, foreach_func, NULL); + + for (i = 0; i < 6; i++) + g_assert (seen_key[i]); + + g_hash_table_unref (hash); +} + +static gboolean +foreach_steal_func (gpointer key, gpointer value, gpointer data) +{ + GHashTable *hash2 = data; + + if (strstr ("ace", (gchar*)key)) + { + g_hash_table_insert (hash2, key, value); + return TRUE; + } + + return FALSE; +} + + +static void +test_foreach_steal (void) +{ + GHashTable *hash; + GHashTable *hash2; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + hash2 = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + g_hash_table_insert (hash, g_strdup ("a"), g_strdup ("A")); + g_hash_table_insert (hash, g_strdup ("b"), g_strdup ("B")); + g_hash_table_insert (hash, g_strdup ("c"), g_strdup ("C")); + g_hash_table_insert (hash, g_strdup ("d"), g_strdup ("D")); + g_hash_table_insert (hash, g_strdup ("e"), g_strdup ("E")); + g_hash_table_insert (hash, g_strdup ("f"), g_strdup ("F")); + + g_hash_table_foreach_steal (hash, foreach_steal_func, hash2); + + g_assert_cmpint (g_hash_table_size (hash), ==, 3); + g_assert_cmpint (g_hash_table_size (hash2), ==, 3); + + g_assert_cmpstr (g_hash_table_lookup (hash2, "a"), ==, "A"); + g_assert_cmpstr (g_hash_table_lookup (hash, "b"), ==, "B"); + g_assert_cmpstr (g_hash_table_lookup (hash2, "c"), ==, "C"); + g_assert_cmpstr (g_hash_table_lookup (hash, "d"), ==, "D"); + g_assert_cmpstr (g_hash_table_lookup (hash2, "e"), ==, "E"); + g_assert_cmpstr (g_hash_table_lookup (hash, "f"), ==, "F"); + + g_hash_table_unref (hash); + g_hash_table_unref (hash2); +} + +/* Test g_hash_table_steal_extended() works properly with existing and + * non-existing keys. */ +static void +test_steal_extended (void) +{ + GHashTable *hash; + gchar *stolen_key = NULL, *stolen_value = NULL; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + g_hash_table_insert (hash, g_strdup ("a"), g_strdup ("A")); + g_hash_table_insert (hash, g_strdup ("b"), g_strdup ("B")); + g_hash_table_insert (hash, g_strdup ("c"), g_strdup ("C")); + g_hash_table_insert (hash, g_strdup ("d"), g_strdup ("D")); + g_hash_table_insert (hash, g_strdup ("e"), g_strdup ("E")); + g_hash_table_insert (hash, g_strdup ("f"), g_strdup ("F")); + + g_assert_true (g_hash_table_steal_extended (hash, "a", + (gpointer *) &stolen_key, + (gpointer *) &stolen_value)); + g_assert_cmpstr (stolen_key, ==, "a"); + g_assert_cmpstr (stolen_value, ==, "A"); + g_clear_pointer (&stolen_key, g_free); + g_clear_pointer (&stolen_value, g_free); + + g_assert_cmpuint (g_hash_table_size (hash), ==, 5); + + g_assert_false (g_hash_table_steal_extended (hash, "a", + (gpointer *) &stolen_key, + (gpointer *) &stolen_value)); + g_assert_null (stolen_key); + g_assert_null (stolen_value); + + g_assert_false (g_hash_table_steal_extended (hash, "never a key", + (gpointer *) &stolen_key, + (gpointer *) &stolen_value)); + g_assert_null (stolen_key); + g_assert_null (stolen_value); + + g_assert_cmpuint (g_hash_table_size (hash), ==, 5); + + g_hash_table_unref (hash); +} + +/* Test that passing %NULL to the optional g_hash_table_steal_extended() + * arguments works. */ +static void +test_steal_extended_optional (void) +{ + GHashTable *hash; + const gchar *stolen_key = NULL, *stolen_value = NULL; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + + g_hash_table_insert (hash, "b", "B"); + g_hash_table_insert (hash, "c", "C"); + g_hash_table_insert (hash, "d", "D"); + g_hash_table_insert (hash, "e", "E"); + g_hash_table_insert (hash, "f", "F"); + + g_assert_true (g_hash_table_steal_extended (hash, "b", + (gpointer *) &stolen_key, + NULL)); + g_assert_cmpstr (stolen_key, ==, "b"); + + g_assert_cmpuint (g_hash_table_size (hash), ==, 4); + + g_assert_false (g_hash_table_steal_extended (hash, "b", + (gpointer *) &stolen_key, + NULL)); + g_assert_null (stolen_key); + + g_assert_true (g_hash_table_steal_extended (hash, "c", + NULL, + (gpointer *) &stolen_value)); + g_assert_cmpstr (stolen_value, ==, "C"); + + g_assert_cmpuint (g_hash_table_size (hash), ==, 3); + + g_assert_false (g_hash_table_steal_extended (hash, "c", + NULL, + (gpointer *) &stolen_value)); + g_assert_null (stolen_value); + + g_assert_true (g_hash_table_steal_extended (hash, "d", NULL, NULL)); + + g_assert_cmpuint (g_hash_table_size (hash), ==, 2); + + g_assert_false (g_hash_table_steal_extended (hash, "d", NULL, NULL)); + + g_assert_cmpuint (g_hash_table_size (hash), ==, 2); + + g_hash_table_unref (hash); +} + +/* Test g_hash_table_lookup_extended() works with its optional parameters + * sometimes set to %NULL. */ +static void +test_lookup_extended (void) +{ + GHashTable *hash; + const gchar *original_key = NULL, *value = NULL; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + g_hash_table_insert (hash, g_strdup ("a"), g_strdup ("A")); + g_hash_table_insert (hash, g_strdup ("b"), g_strdup ("B")); + g_hash_table_insert (hash, g_strdup ("c"), g_strdup ("C")); + g_hash_table_insert (hash, g_strdup ("d"), g_strdup ("D")); + g_hash_table_insert (hash, g_strdup ("e"), g_strdup ("E")); + g_hash_table_insert (hash, g_strdup ("f"), g_strdup ("F")); + + g_assert_true (g_hash_table_lookup_extended (hash, "a", + (gpointer *) &original_key, + (gpointer *) &value)); + g_assert_cmpstr (original_key, ==, "a"); + g_assert_cmpstr (value, ==, "A"); + + g_assert_true (g_hash_table_lookup_extended (hash, "b", + NULL, + (gpointer *) &value)); + g_assert_cmpstr (value, ==, "B"); + + g_assert_true (g_hash_table_lookup_extended (hash, "c", + (gpointer *) &original_key, + NULL)); + g_assert_cmpstr (original_key, ==, "c"); + + g_assert_true (g_hash_table_lookup_extended (hash, "d", NULL, NULL)); + + g_assert_false (g_hash_table_lookup_extended (hash, "not a key", + (gpointer *) &original_key, + (gpointer *) &value)); + g_assert_null (original_key); + g_assert_null (value); + + g_assert_false (g_hash_table_lookup_extended (hash, "not a key", + NULL, + (gpointer *) &value)); + g_assert_null (value); + + g_assert_false (g_hash_table_lookup_extended (hash, "not a key", + (gpointer *) &original_key, + NULL)); + g_assert_null (original_key); + + g_assert_false (g_hash_table_lookup_extended (hash, "not a key", NULL, NULL)); + + g_hash_table_unref (hash); +} + +static void +inc_state (gpointer user_data) +{ + int *state = user_data; + g_assert_cmpint (*state, ==, 0); + *state = 1; +} + +static void +test_new_similar (void) +{ + GHashTable *hash1; + GHashTable *hash2; + int state1; + int state2; + + hash1 = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, inc_state); + state1 = 0; + g_hash_table_insert (hash1, + g_strdup ("test"), + &state1); + g_assert_true (g_hash_table_lookup (hash1, "test") == &state1); + + hash2 = g_hash_table_new_similar (hash1); + + g_assert_true (g_hash_table_lookup (hash1, "test") == &state1); + g_assert_null (g_hash_table_lookup (hash2, "test")); + + state2 = 0; + g_hash_table_insert (hash2, g_strdup ("test"), &state2); + g_assert_true (g_hash_table_lookup (hash2, "test") == &state2); + g_hash_table_remove (hash2, "test"); + g_assert_cmpint (state2, ==, 1); + + g_assert_cmpint (state1, ==, 0); + g_hash_table_remove (hash1, "test"); + g_assert_cmpint (state1, ==, 1); + + g_hash_table_unref (hash1); + g_hash_table_unref (hash2); +} + +struct _GHashTable +{ + gsize size; + gint mod; + guint mask; + gint nnodes; + gint noccupied; /* nnodes + tombstones */ + + guint have_big_keys : 1; + guint have_big_values : 1; + + gpointer *keys; + guint *hashes; + gpointer *values; + + GHashFunc hash_func; + GEqualFunc key_equal_func; + gint ref_count; /* (atomic) */ + +#ifndef G_DISABLE_ASSERT + int version; +#endif + GDestroyNotify key_destroy_func; + GDestroyNotify value_destroy_func; +}; + +static void +count_keys (GHashTable *h, gint *unused, gint *occupied, gint *tombstones) +{ + gsize i; + + *unused = 0; + *occupied = 0; + *tombstones = 0; + for (i = 0; i < h->size; i++) + { + if (h->hashes[i] == 0) + (*unused)++; + else if (h->hashes[i] == 1) + (*tombstones)++; + else + (*occupied)++; + } +} + +#define BIG_ENTRY_SIZE (SIZEOF_VOID_P) +#define SMALL_ENTRY_SIZE (SIZEOF_INT) + +#if SMALL_ENTRY_SIZE < BIG_ENTRY_SIZE +# define USE_SMALL_ARRAYS +#endif + +static gpointer +fetch_key_or_value (gpointer a, guint index, gboolean is_big) +{ +#ifdef USE_SMALL_ARRAYS + return is_big ? *(((gpointer *) a) + index) : GUINT_TO_POINTER (*(((guint *) a) + index)); +#else + return *(((gpointer *) a) + index); +#endif +} + +static void +check_data (GHashTable *h) +{ + gsize i; + + for (i = 0; i < h->size; i++) + { + if (h->hashes[i] >= 2) + { + g_assert_cmpint (h->hashes[i], ==, h->hash_func (fetch_key_or_value (h->keys, i, h->have_big_keys))); + } + } +} + +static void +check_consistency (GHashTable *h) +{ + gint unused; + gint occupied; + gint tombstones; + + count_keys (h, &unused, &occupied, &tombstones); + + g_assert_cmpint (occupied, ==, h->nnodes); + g_assert_cmpint (occupied + tombstones, ==, h->noccupied); + g_assert_cmpint (occupied + tombstones + unused, ==, h->size); + + check_data (h); +} + +static void +check_counts (GHashTable *h, gint occupied, gint tombstones) +{ + g_assert_cmpint (occupied, ==, h->nnodes); + g_assert_cmpint (occupied + tombstones, ==, h->noccupied); +} + +static void +trivial_key_destroy (gpointer key) +{ +} + +static void +test_internal_consistency (void) +{ + GHashTable *h; + + h = g_hash_table_new_full (g_str_hash, g_str_equal, trivial_key_destroy, NULL); + + check_counts (h, 0, 0); + check_consistency (h); + + g_hash_table_insert (h, "a", "A"); + g_hash_table_insert (h, "b", "B"); + g_hash_table_insert (h, "c", "C"); + g_hash_table_insert (h, "d", "D"); + g_hash_table_insert (h, "e", "E"); + g_hash_table_insert (h, "f", "F"); + + check_counts (h, 6, 0); + check_consistency (h); + + g_hash_table_remove (h, "a"); + check_counts (h, 5, 1); + check_consistency (h); + + g_hash_table_remove (h, "b"); + check_counts (h, 4, 2); + check_consistency (h); + + g_hash_table_insert (h, "c", "c"); + check_counts (h, 4, 2); + check_consistency (h); + + g_hash_table_insert (h, "a", "A"); + check_counts (h, 5, 1); + check_consistency (h); + + g_hash_table_remove_all (h); + check_counts (h, 0, 0); + check_consistency (h); + + g_hash_table_unref (h); +} + +static void +my_key_free (gpointer v) +{ + gchar *s = v; + g_assert (s[0] != 'x'); + s[0] = 'x'; + g_free (v); +} + +static void +my_value_free (gpointer v) +{ + gchar *s = v; + g_assert (s[0] != 'y'); + s[0] = 'y'; + g_free (v); +} + +static void +test_iter_replace (void) +{ + GHashTable *h; + GHashTableIter iter; + gpointer k, v; + gchar *s; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=662544"); + + h = g_hash_table_new_full (g_str_hash, g_str_equal, my_key_free, my_value_free); + + g_hash_table_insert (h, g_strdup ("A"), g_strdup ("a")); + g_hash_table_insert (h, g_strdup ("B"), g_strdup ("b")); + g_hash_table_insert (h, g_strdup ("C"), g_strdup ("c")); + + g_hash_table_iter_init (&iter, h); + + while (g_hash_table_iter_next (&iter, &k, &v)) + { + s = (gchar*)v; + g_assert (g_ascii_islower (s[0])); + g_hash_table_iter_replace (&iter, g_strdup (k)); + } + + g_hash_table_unref (h); +} + +static void +replace_first_character (gchar *string) +{ + string[0] = 'b'; +} + +static void +test_set_insert_corruption (void) +{ + GHashTable *hash_table = + g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) replace_first_character, NULL); + GHashTableIter iter; + gchar a[] = "foo"; + gchar b[] = "foo"; + gpointer key, value; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=692815"); + + g_hash_table_insert (hash_table, a, a); + g_assert (g_hash_table_contains (hash_table, "foo")); + + g_hash_table_insert (hash_table, b, b); + + g_assert_cmpuint (g_hash_table_size (hash_table), ==, 1); + g_hash_table_iter_init (&iter, hash_table); + if (!g_hash_table_iter_next (&iter, &key, &value)) + g_assert_not_reached(); + + /* per the documentation to g_hash_table_insert(), 'b' has now been freed, + * and the sole key in 'hash_table' should be 'a'. + */ + g_assert (key != b); + g_assert (key == a); + + g_assert_cmpstr (b, ==, "boo"); + + /* g_hash_table_insert() also says that the value should now be 'b', + * which is probably not what the caller intended but is precisely what they + * asked for. + */ + g_assert (value == b); + + /* even though the hash has now been de-set-ified: */ + g_assert (g_hash_table_contains (hash_table, "foo")); + + g_hash_table_unref (hash_table); +} + +static void +test_set_to_strv (void) +{ + GHashTable *set; + gchar **strv; + guint n; + + set = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_hash_table_add (set, g_strdup ("xyz")); + g_hash_table_add (set, g_strdup ("xyz")); + g_hash_table_add (set, g_strdup ("abc")); + strv = (gchar **) g_hash_table_get_keys_as_array (set, &n); + g_hash_table_steal_all (set); + g_hash_table_unref (set); + g_assert_cmpint (n, ==, 2); + n = g_strv_length (strv); + g_assert_cmpint (n, ==, 2); + if (g_str_equal (strv[0], "abc")) + g_assert_cmpstr (strv[1], ==, "xyz"); + else + { + g_assert_cmpstr (strv[0], ==, "xyz"); + g_assert_cmpstr (strv[1], ==, "abc"); + } + g_strfreev (strv); +} + +static gboolean +is_prime (guint p) +{ + guint i; + + if (p % 2 == 0) + return FALSE; + + i = 3; + while (TRUE) + { + if (i * i > p) + return TRUE; + + if (p % i == 0) + return FALSE; + + i += 2; + } +} + +static void +test_primes (void) +{ + guint p, q; + gdouble r, min, max; + + max = 1.0; + min = 10.0; + q = 1; + while (1) { + p = q; + q = g_spaced_primes_closest (p); + g_assert (is_prime (q)); + if (p == 1) continue; + if (q == p) break; + r = q / (gdouble) p; + min = MIN (min, r); + max = MAX (max, r); + }; + + g_assert_cmpfloat (1.3, <, min); + g_assert_cmpfloat (max, <, 2.0); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/hash/misc", test_hash_misc); + g_test_add_data_func ("/hash/one", GINT_TO_POINTER (TRUE), second_hash_test); + g_test_add_data_func ("/hash/honeyman", GINT_TO_POINTER (FALSE), second_hash_test); + g_test_add_func ("/hash/direct", direct_hash_test); + g_test_add_func ("/hash/direct2", direct_hash_test2); + g_test_add_func ("/hash/int", int_hash_test); + g_test_add_func ("/hash/int64", int64_hash_test); + g_test_add_func ("/hash/double", double_hash_test); + g_test_add_func ("/hash/string", string_hash_test); + g_test_add_func ("/hash/set", set_hash_test); + g_test_add_func ("/hash/set-ref", set_ref_hash_test); + g_test_add_func ("/hash/ref", test_hash_ref); + g_test_add_func ("/hash/remove-all", test_remove_all); + g_test_add_func ("/hash/recursive-remove-all", test_recursive_remove_all); + g_test_add_func ("/hash/recursive-remove-all/subprocess", test_recursive_remove_all_subprocess); + g_test_add_func ("/hash/find", test_find); + g_test_add_func ("/hash/foreach", test_foreach); + g_test_add_func ("/hash/foreach-steal", test_foreach_steal); + g_test_add_func ("/hash/steal-extended", test_steal_extended); + g_test_add_func ("/hash/steal-extended/optional", test_steal_extended_optional); + g_test_add_func ("/hash/lookup-extended", test_lookup_extended); + g_test_add_func ("/hash/new-similar", test_new_similar); + + /* tests for individual bugs */ + g_test_add_func ("/hash/lookup-null-key", test_lookup_null_key); + g_test_add_func ("/hash/destroy-modify", test_destroy_modify); + g_test_add_func ("/hash/consistency", test_internal_consistency); + g_test_add_func ("/hash/iter-replace", test_iter_replace); + g_test_add_func ("/hash/set-insert-corruption", test_set_insert_corruption); + g_test_add_func ("/hash/set-to-strv", test_set_to_strv); + g_test_add_func ("/hash/primes", test_primes); + + return g_test_run (); + +} diff --git a/glib/tests/hmac.c b/glib/tests/hmac.c new file mode 100644 index 0000000..3ac3206 --- /dev/null +++ b/glib/tests/hmac.c @@ -0,0 +1,550 @@ +#include +#include +#include + +/* HMAC-MD5 test vectors as per RFC 2202 */ + +/* Test 1 */ +guint8 key_md5_test1[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; +guint8 result_md5_test1[] = { + 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 0x13, 0xf4, + 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }; + +/* Test 2 */ +guint8 result_md5_test2[] = { + 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 0xea, 0xa8, + 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }; + +/* Test 3 */ +guint8 key_md5_test3[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; +guint8 data_md5_test3[] = { + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }; +guint8 result_md5_test3[] = { + 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, 0xdb, 0xb8, + 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }; + +/* Test 4 */ +guint8 key_md5_test4[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19 }; +guint8 data_md5_test4[] = { + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd }; +guint8 result_md5_test4[] = { + 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, 0x3a, 0x75, + 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 }; + +/* Test 5 */ +guint8 key_md5_test5[] = { + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}; +guint8 result_md5_test5[] = { + 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, 0xf9, 0xba, + 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c }; + +/* Test 6 */ +guint8 key_md5_test6[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; +guint8 result_md5_test6[] = { + 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, 0x0b, 0x62, + 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd }; + +/* Test 6 */ +guint8 key_md5_test7[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; +guint8 result_md5_test7[] = { + 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 0x1f, 0xb1, + 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e }; + +/* HMAC-SHA1, HMAC-SHA256, HMAC-SHA384 and HMAC-SHA512 test vectors + * as per RFCs 2202 and 4868. + * + * See: https://tools.ietf.org/html/rfc4868#section-2.7.1 */ + +/* Test 1 */ +guint8 key_sha_test1[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; +guint8 result_sha1_test1[] = { + 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xe2, 0x8b, + 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1, 0x46, 0xbe, 0x00 }; +guint8 result_sha256_test1[] = { + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, + 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, + 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, + 0xcf, 0xf7 }; +guint8 result_sha384_test1[] = { + 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62, 0x6b, 0x08, + 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f, 0x15, 0xf9, 0xda, 0xdb, + 0xe4, 0x10, 0x1e, 0xc6, 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, + 0xc5, 0x9c, 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f, + 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 }; +guint8 result_sha512_test1[] = { + 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, 0x4f, 0xf0, + 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0, 0x23, 0x79, 0xf4, 0xe2, + 0xce, 0x4e, 0xc2, 0x78, 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, + 0x7c, 0xde, 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02, + 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4, 0xbe, 0x9d, + 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70, 0x2e, 0x69, 0x6c, 0x20, + 0x3a, 0x12, 0x68, 0x54 }; + +/* Test 2 */ +guint8 result_sha1_test2[] = { + 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, + 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 }; +guint8 result_sha256_test2[] = { + 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, + 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, + 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, + 0x38, 0x43 }; +guint8 result_sha384_test2[] = { + 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31, 0x61, 0x7f, + 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b, 0x9c, 0x7e, 0xf4, 0x64, + 0xf5, 0xa0, 0x1b, 0x47, 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, + 0x44, 0x5e, 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7, + 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 }; +guint8 result_sha512_test2[] = { + 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, 0xe3, 0x95, + 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3, 0x87, 0xbd, 0x64, 0x22, + 0x2e, 0x83, 0x1f, 0xd6, 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, + 0x05, 0x54, 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a, + 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd, 0xca, 0xea, + 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b, 0x63, 0x6e, 0x07, 0x0a, + 0x38, 0xbc, 0xe7, 0x37 }; + +/* Test 3 */ +guint8 key_sha_test3[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; +guint8 data_sha_test3[] = { + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }; +guint8 result_sha1_test3[] = { + 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, + 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 }; +guint8 result_sha256_test3[] = { + 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, + 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, + 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, + 0x65, 0xfe }; +guint8 result_sha384_test3[] = { + 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a, 0x0a, 0xa2, + 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f, 0x0a, 0xa6, 0x35, 0xd9, + 0x47, 0xac, 0x9f, 0xeb, 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, + 0x14, 0x4b, 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9, + 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 }; +guint8 result_sha512_test3[] = { + 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84, 0xef, 0xb0, + 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9, 0xb1, 0xb5, 0xdb, 0xdd, + 0x8e, 0xe8, 0x1a, 0x36, 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, + 0x9d, 0x39, 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8, + 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07, 0xb9, 0x46, + 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26, 0x74, 0x27, 0x88, 0x59, + 0xe1, 0x32, 0x92, 0xfb }; + +/* Test 4 */ +guint8 key_sha_test4[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19 }; +guint8 data_sha_test4[] = { + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd }; +guint8 result_sha1_test4[] = { + 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, + 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda }; +guint8 result_sha256_test4[] = { + 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, + 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3, + 0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, + 0x66, 0x5b }; +guint8 result_sha384_test4[] = { + 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85, 0x19, 0x33, + 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7, 0x7a, 0x99, 0x81, 0x48, + 0x08, 0x50, 0x00, 0x9c, 0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, + 0x3b, 0x4e, 0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79, + 0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb }; +guint8 result_sha512_test4[] = { + 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69, 0x90, 0xe5, + 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7, 0xe5, 0x76, 0xd9, 0x7f, + 0xf9, 0x4b, 0x87, 0x2d, 0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, + 0xe3, 0xdb, 0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4, + 0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63, 0xa5, 0xf1, + 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d, 0xe2, 0xad, 0xeb, 0xeb, + 0x10, 0xa2, 0x98, 0xdd }; + +/* Test 5 (note: different for SHA-256/SHA-512) */ +guint8 key_sha1_test5[] = { + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }; +guint8 result_sha1_test5[] = { + 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, + 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 }; + +/* Test 6 & 7 (note: different for SHA-1 and SHA-256/SHA-512) */ +guint8 key_sha1_test6_7[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; + +guint8 result_sha1_test6[] = { + 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, + 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 }; + +guint8 result_sha1_test7[] = { + 0xe8, 0xe9, 0x9d, 0xf, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, + 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x8, 0xbb, 0xff, 0x1a, 0x91 }; + +/* Test 5 & 6 for SHA-256 and SHA-512. */ +guint8 key_sha256_test5_6[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa }; + +guint8 result_sha256_test5[] = { + 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, + 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, + 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, + 0x7f, 0x54 }; +guint8 result_sha384_test5[] = { + 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90, 0x88, 0xd2, + 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4, 0x4f, 0x9e, 0xf1, 0x01, + 0x2a, 0x2b, 0x58, 0x8f, 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, + 0xc4, 0xc6, 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82, + 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 }; +guint8 result_sha512_test5[] = { + 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, 0xb7, 0x14, + 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4, 0x9b, 0x46, 0xd1, 0xf4, + 0x1b, 0x4a, 0xee, 0xc1, 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, + 0xf3, 0x52, 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98, + 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52, 0x95, 0xe6, + 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec, 0x8b, 0x91, 0x5a, 0x98, + 0x5d, 0x78, 0x65, 0x98 }; + +guint8 result_sha256_test6[] = { + 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, + 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, + 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, + 0x35, 0xe2 }; +guint8 result_sha384_test6[] = { + 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d, 0x35, 0x1e, + 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c, 0x60, 0x24, 0x20, 0xfe, + 0xb0, 0xb8, 0xfb, 0x9a, 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, + 0x99, 0xc5, 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d, + 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e }; +guint8 result_sha512_test6[] = { + 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba, 0xa4, 0xdf, + 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd, 0xde, 0xbd, 0x71, 0xf8, + 0x86, 0x72, 0x89, 0x86, 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, + 0xc9, 0x44, 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1, + 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15, 0x13, 0x46, + 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60, 0x65, 0xc9, 0x74, 0x40, + 0xfa, 0x8c, 0x6a, 0x58 }; + + +typedef struct { + GChecksumType digest_type; + gconstpointer key; + gsize key_len; + gconstpointer data; + gsize data_len; + gconstpointer result; +} HmacCase; + +HmacCase hmac_md5_tests[] = { + { G_CHECKSUM_MD5, key_md5_test1, 16, "Hi There", 8, result_md5_test1 }, + { G_CHECKSUM_MD5, "Jefe", 4, "what do ya want for nothing?", 28, + result_md5_test2 }, + { G_CHECKSUM_MD5, key_md5_test3, 16, data_md5_test3, 50, + result_md5_test3 }, + { G_CHECKSUM_MD5, key_md5_test4, 25, data_md5_test4, 50, + result_md5_test4 }, + { G_CHECKSUM_MD5, key_md5_test5, 16, "Test With Truncation", 20, + result_md5_test5 }, + { G_CHECKSUM_MD5, key_md5_test6, 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + result_md5_test6 }, + { G_CHECKSUM_MD5, key_md5_test7, 80, + "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", + 73, result_md5_test7 }, + { -1, NULL, 0, NULL, 0, NULL }, +}; + +HmacCase hmac_sha1_tests[] = { + { G_CHECKSUM_SHA1, key_sha_test1, 20, "Hi There", 8, result_sha1_test1 }, + { G_CHECKSUM_SHA1, "Jefe", 4, "what do ya want for nothing?", 28, + result_sha1_test2 }, + { G_CHECKSUM_SHA1, key_sha_test3, 20, data_sha_test3, 50, + result_sha1_test3 }, + { G_CHECKSUM_SHA1, key_sha_test4, 25, data_sha_test4, 50, + result_sha1_test4 }, + { G_CHECKSUM_SHA1, key_sha1_test5, 20, "Test With Truncation", 20, + result_sha1_test5 }, + { G_CHECKSUM_SHA1, key_sha1_test6_7, 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + result_sha1_test6 }, + { G_CHECKSUM_SHA1, key_sha1_test6_7, 80, + "Test Using Larger Than Block-Size Key and Larger" \ + " Than One Block-Size Data", 73, result_sha1_test7, }, + { -1, NULL, 0, NULL, 0, NULL }, +}; + +HmacCase hmac_sha256_tests[] = { + { G_CHECKSUM_SHA256, key_sha_test1, 20, "Hi There", 8, result_sha256_test1 }, + { G_CHECKSUM_SHA256, "Jefe", 4, "what do ya want for nothing?", 28, + result_sha256_test2 }, + { G_CHECKSUM_SHA256, key_sha_test3, 20, data_sha_test3, 50, + result_sha256_test3 }, + { G_CHECKSUM_SHA256, key_sha_test4, 25, data_sha_test4, 50, + result_sha256_test4 }, + { G_CHECKSUM_SHA256, key_sha256_test5_6, 131, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + result_sha256_test5 }, + { G_CHECKSUM_SHA256, key_sha256_test5_6, 131, + "This is a test using a larger than block-size key and a larger than " + "block-size data. The key needs to be hashed before being used by the " + "HMAC algorithm.", 152, result_sha256_test6, }, + { -1, NULL, 0, NULL, 0, NULL }, +}; + +HmacCase hmac_sha384_tests[] = { + { G_CHECKSUM_SHA384, key_sha_test1, 20, "Hi There", 8, result_sha384_test1 }, + { G_CHECKSUM_SHA384, "Jefe", 4, "what do ya want for nothing?", 28, + result_sha384_test2 }, + { G_CHECKSUM_SHA384, key_sha_test3, 20, data_sha_test3, 50, + result_sha384_test3 }, + { G_CHECKSUM_SHA384, key_sha_test4, 25, data_sha_test4, 50, + result_sha384_test4 }, + { G_CHECKSUM_SHA384, key_sha256_test5_6, 131, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + result_sha384_test5 }, + { G_CHECKSUM_SHA384, key_sha256_test5_6, 131, + "This is a test using a larger than block-size key and a larger than " + "block-size data. The key needs to be hashed before being used by the " + "HMAC algorithm.", 152, result_sha384_test6, }, + { -1, NULL, 0, NULL, 0, NULL }, +}; + +HmacCase hmac_sha512_tests[] = { + { G_CHECKSUM_SHA512, key_sha_test1, 20, "Hi There", 8, result_sha512_test1 }, + { G_CHECKSUM_SHA512, "Jefe", 4, "what do ya want for nothing?", 28, + result_sha512_test2 }, + { G_CHECKSUM_SHA512, key_sha_test3, 20, data_sha_test3, 50, + result_sha512_test3 }, + { G_CHECKSUM_SHA512, key_sha_test4, 25, data_sha_test4, 50, + result_sha512_test4 }, + { G_CHECKSUM_SHA512, key_sha256_test5_6, 131, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + result_sha512_test5 }, + { G_CHECKSUM_SHA512, key_sha256_test5_6, 131, + "This is a test using a larger than block-size key and a larger than " + "block-size data. The key needs to be hashed before being used by the " + "HMAC algorithm.", 152, result_sha512_test6, }, + { -1, NULL, 0, NULL, 0, NULL }, +}; + + +static void +test_hmac (HmacCase *t) +{ + GHmac *hmac; + gsize digest_len, hmac_len; + gpointer digest; + + hmac_len = digest_len = g_checksum_type_get_length (t->digest_type); + digest = g_malloc (hmac_len); + + hmac = g_hmac_new (t->digest_type, t->key, t->key_len); + g_hmac_update (hmac, t->data, t->data_len); + g_hmac_get_digest (hmac, digest, &digest_len); + + g_assert_cmpmem (digest, hmac_len, t->result, digest_len); + + g_free (digest); + g_hmac_unref (hmac); +} + +static void +test_hmac_ref_unref (void) +{ + GHmac *hmac, *check; + + hmac = g_hmac_new (G_CHECKSUM_SHA1, (guchar*)"aaa", 3); + check = g_hmac_ref (hmac); + g_assert (check == hmac); + g_hmac_unref (check); + g_hmac_unref (hmac); +} + +static void +test_hmac_copy (void) +{ + GHmac *hmac, *check; + + hmac = g_hmac_new (G_CHECKSUM_SHA256, (guchar*)"aaa", 3); + check = g_hmac_copy (hmac); + g_assert (check != hmac); + g_assert_cmpstr (g_hmac_get_string (hmac), ==, g_hmac_get_string (check)); + g_hmac_unref (check); + g_hmac_unref (hmac); +} + +static void +test_hmac_for_data (void) +{ + gchar *string; + GHmac *hmac; + + string = g_compute_hmac_for_data (G_CHECKSUM_SHA1, + (guchar*)"aaa", 3, + (guchar*)"bcdef", 5); + + hmac = g_hmac_new (G_CHECKSUM_SHA1, (guchar*)"aaa", 3); + g_hmac_update (hmac, (guchar*)"bcdef", 5); + g_assert_cmpstr (string, ==, g_hmac_get_string (hmac)); + g_hmac_unref (hmac); + g_free (string); +} + +static void +test_hmac_for_string (void) +{ + gchar *string; + GHmac *hmac; + + string = g_compute_hmac_for_string (G_CHECKSUM_SHA1, + (guchar*)"aaa", 3, + "bcdef", -1); + + hmac = g_hmac_new (G_CHECKSUM_SHA1, (guchar*)"aaa", 3); + g_hmac_update (hmac, (guchar*)"bcdef", 5); + g_assert_cmpstr (string, ==, g_hmac_get_string (hmac)); + g_hmac_unref (hmac); + g_free (string); +} + +static void +test_hmac_for_bytes (void) +{ + gchar *string; + GHmac *hmac; + GBytes *key, *data; + + key = g_bytes_new ("aaa", 3); + data = g_bytes_new ("bcdef", 5); + + string = g_compute_hmac_for_bytes (G_CHECKSUM_SHA1, key, data); + + hmac = g_hmac_new (G_CHECKSUM_SHA1, (guchar*)"aaa", 3); + g_hmac_update (hmac, (guchar*)"bcdef", 5); + g_assert_cmpstr (string, ==, g_hmac_get_string (hmac)); + g_hmac_unref (hmac); + g_free (string); + + g_bytes_unref (key); + g_bytes_unref (data); +} + +int +main (int argc, + char **argv) +{ + int i; + g_test_init (&argc, &argv, NULL); + + for (i = 0 ; hmac_sha1_tests[i].key_len > 0 ; i++) + { + gchar *name = g_strdup_printf ("/hmac/sha1-%d", i + 1); + g_test_add_data_func (name, hmac_sha1_tests + i, + (void (*)(const void *)) test_hmac); + g_free (name); + } + + for (i = 0 ; hmac_sha256_tests[i].key_len > 0 ; i++) + { + gchar *name = g_strdup_printf ("/hmac/sha256-%d", i + 1); + g_test_add_data_func (name, hmac_sha256_tests + i, + (void (*)(const void *)) test_hmac); + g_free (name); + } + + for (i = 0 ; hmac_sha384_tests[i].key_len > 0 ; i++) + { + gchar *name = g_strdup_printf ("/hmac/sha384-%d", i + 1); + g_test_add_data_func (name, hmac_sha384_tests + i, + (void (*)(const void *)) test_hmac); + g_free (name); + } + + for (i = 0 ; hmac_sha512_tests[i].key_len > 0 ; i++) + { + gchar *name = g_strdup_printf ("/hmac/sha512-%d", i + 1); + g_test_add_data_func (name, hmac_sha512_tests + i, + (void (*)(const void *)) test_hmac); + g_free (name); + } + + for (i = 0 ; hmac_md5_tests[i].key_len > 0 ; i++) + { + gchar *name = g_strdup_printf ("/hmac/md5-%d", i + 1); + g_test_add_data_func (name, hmac_md5_tests + i, + (void (*)(const void *)) test_hmac); + g_free (name); + } + + g_test_add_func ("/hmac/ref-unref", test_hmac_ref_unref); + g_test_add_func ("/hmac/copy", test_hmac_copy); + g_test_add_func ("/hmac/for-data", test_hmac_for_data); + g_test_add_func ("/hmac/for-string", test_hmac_for_string); + g_test_add_func ("/hmac/for-bytes", test_hmac_for_bytes); + + return g_test_run (); +} diff --git a/glib/tests/hook.c b/glib/tests/hook.c new file mode 100644 index 0000000..711c34e --- /dev/null +++ b/glib/tests/hook.c @@ -0,0 +1,94 @@ +/* Unit tests for hook lists + * Copyright (C) 2011 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Matthias Clasen + */ + +#include "glib.h" + +static void +hook_func (gpointer data) +{ +} + +static void +destroy (gpointer data) +{ +} + +static void +test_hook1 (void) +{ + GHookList *hl; + GHook *hook; + gulong id; + GHook *h; + + hl = g_new (GHookList, 1); + g_hook_list_init (hl, sizeof (GHook)); + + hook = g_hook_alloc (hl); + hook->data = GINT_TO_POINTER(1); + hook->func = hook_func; + hook->flags = G_HOOK_FLAG_ACTIVE; + hook->destroy = destroy; + g_hook_append (hl, hook); + id = hook->hook_id; + + h = g_hook_get (hl, id); + g_assert (h == hook); + + h = hook = g_hook_alloc (hl); + hook->data = GINT_TO_POINTER(2); + hook->func = hook_func; + hook->flags = G_HOOK_FLAG_ACTIVE; + hook->destroy = destroy; + g_hook_prepend (hl, hook); + + g_hook_destroy (hl, id); + + hook = g_hook_alloc (hl); + hook->data = GINT_TO_POINTER(3); + hook->func = hook_func; + hook->flags = G_HOOK_FLAG_ACTIVE; + hook->destroy = destroy; + g_hook_insert_sorted (hl, hook, g_hook_compare_ids); + + hook = g_hook_alloc (hl); + hook->data = GINT_TO_POINTER(4); + hook->func = hook_func; + hook->flags = G_HOOK_FLAG_ACTIVE; + hook->destroy = destroy; + g_hook_insert_before (hl, h, hook); + + g_hook_list_invoke (hl, TRUE); + + g_hook_list_clear (hl); + g_free (hl); +} + +int main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/hook/test1", test_hook1); + + return g_test_run (); +} diff --git a/glib/tests/hostutils.c b/glib/tests/hostutils.c new file mode 100644 index 0000000..1d6f855 --- /dev/null +++ b/glib/tests/hostutils.c @@ -0,0 +1,367 @@ +/* + * Copyright (C) 2008 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +#include +#include +#include + +static const struct { + const gchar *ascii_name, *unicode_name; +} idn_test_domains[] = { + /* "example.test" in various languages */ + { "xn--mgbh0fb.xn--kgbechtv", "\xd9\x85\xd8\xab\xd8\xa7\xd9\x84.\xd8\xa5\xd8\xae\xd8\xaa\xd8\xa8\xd8\xa7\xd8\xb1" }, + { "xn--fsqu00a.xn--0zwm56d", "\xe4\xbe\x8b\xe5\xad\x90.\xe6\xb5\x8b\xe8\xaf\x95" }, + { "xn--fsqu00a.xn--g6w251d", "\xe4\xbe\x8b\xe5\xad\x90.\xe6\xb8\xac\xe8\xa9\xa6" }, + { "xn--hxajbheg2az3al.xn--jxalpdlp", "\xcf\x80\xce\xb1\xcf\x81\xce\xac\xce\xb4\xce\xb5\xce\xb9\xce\xb3\xce\xbc\xce\xb1.\xce\xb4\xce\xbf\xce\xba\xce\xb9\xce\xbc\xce\xae" }, + { "xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g", "\xe0\xa4\x89\xe0\xa4\xa6\xe0\xa4\xbe\xe0\xa4\xb9\xe0\xa4\xb0\xe0\xa4\xa3.\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa5\x80\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb7\xe0\xa4\xbe" }, + { "xn--r8jz45g.xn--zckzah", "\xe4\xbe\x8b\xe3\x81\x88.\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" }, + { "xn--9n2bp8q.xn--9t4b11yi5a", "\xec\x8b\xa4\xeb\xa1\x80.\xed\x85\x8c\xec\x8a\xa4\xed\x8a\xb8" }, + { "xn--mgbh0fb.xn--hgbk6aj7f53bba", "\xd9\x85\xd8\xab\xd8\xa7\xd9\x84.\xd8\xa2\xd8\xb2\xd9\x85\xd8\xa7\xdb\x8c\xd8\xb4\xdb\x8c" }, + { "xn--e1afmkfd.xn--80akhbyknj4f", "\xd0\xbf\xd1\x80\xd0\xb8\xd0\xbc\xd0\xb5\xd1\x80.\xd0\xb8\xd1\x81\xd0\xbf\xd1\x8b\xd1\x82\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xb5" }, + { "xn--zkc6cc5bi7f6e.xn--hlcj6aya9esc7a", "\xe0\xae\x89\xe0\xae\xa4\xe0\xae\xbe\xe0\xae\xb0\xe0\xae\xa3\xe0\xae\xae\xe0\xaf\x8d.\xe0\xae\xaa\xe0\xae\xb0\xe0\xae\xbf\xe0\xae\x9f\xe0\xaf\x8d\xe0\xae\x9a\xe0\xaf\x88" }, + { "xn--fdbk5d8ap9b8a8d.xn--deba0ad", "\xd7\x91\xd7\xb2\xd6\xb7\xd7\xa9\xd7\xa4\xd6\xbc\xd7\x99\xd7\x9c.\xd7\x98\xd7\xa2\xd7\xa1\xd7\x98" }, + + /* further examples without their own IDN-ized TLD */ + { "xn--1xd0bwwra.idn.icann.org", "\xe1\x8a\xa0\xe1\x88\x9b\xe1\x88\xad\xe1\x8a\x9b.idn.icann.org" }, + { "xn--54b7fta0cc.idn.icann.org", "\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe.idn.icann.org" }, + { "xn--5dbqzzl.idn.icann.org", "\xd7\xa2\xd7\x91\xd7\xa8\xd7\x99\xd7\xaa.idn.icann.org" }, + { "xn--j2e7beiw1lb2hqg.idn.icann.org", "\xe1\x9e\x97\xe1\x9e\xb6\xe1\x9e\x9f\xe1\x9e\xb6\xe1\x9e\x81\xe1\x9f\x92\xe1\x9e\x98\xe1\x9f\x82\xe1\x9e\x9a.idn.icann.org" }, + { "xn--o3cw4h.idn.icann.org", "\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2.idn.icann.org" }, + { "xn--mgbqf7g.idn.icann.org", "\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x88.idn.icann.org" } +}; +static const gint num_idn_test_domains = G_N_ELEMENTS (idn_test_domains); + +static const struct { + const gchar *orig_name, *ascii_name; + gboolean orig_is_unicode, ascii_is_encoded; +} non_round_trip_names[] = { + /* uppercase characters */ + { "EXAMPLE.COM", "example.com", FALSE, FALSE }, + { "\xc3\x89XAMPLE.COM", "xn--xample-9ua.com", TRUE, TRUE }, + + /* unicode that decodes to ascii */ + { "\xe2\x93\x94\xe2\x93\xa7\xe2\x93\x90\xe2\x93\x9c\xe2\x93\x9f\xe2\x93\x9b\xe2\x93\x94.com", "example.com", TRUE, FALSE }, + + /* non-standard dot characters */ + { "example\xe3\x80\x82" "com", "example.com", TRUE, FALSE }, + { "\xc3\xa9xample\xe3\x80\x82" "com", "xn--xample-9ua.com", TRUE, TRUE }, + { "â„«.idn.icann.org", "xn--5ca.idn.icann.org", TRUE, TRUE }, + { "ℵℶℷ\xcd\x8f.idn.icann.org", "xn--4dbcd.idn.icann.org", TRUE, TRUE } +}; +static const gint num_non_round_trip_names = G_N_ELEMENTS (non_round_trip_names); + +static const gchar *bad_names[] = { + "disallowed\xef\xbf\xbd" "character", + "non-utf\x88", + "xn--mixed-\xc3\xbcp", + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong" + "verylongverylongverylongverylongverylongverylongverylongverylongverylong", +}; +static const gint num_bad_names = G_N_ELEMENTS (bad_names); + +static void +test_to_ascii (void) +{ + gint i; + gchar *ascii; + + for (i = 0; i < num_idn_test_domains; i++) + { + g_assert_true (g_hostname_is_non_ascii (idn_test_domains[i].unicode_name)); + ascii = g_hostname_to_ascii (idn_test_domains[i].unicode_name); + g_assert_cmpstr (idn_test_domains[i].ascii_name, ==, ascii); + g_free (ascii); + + ascii = g_hostname_to_ascii (idn_test_domains[i].ascii_name); + g_assert_cmpstr (idn_test_domains[i].ascii_name, ==, ascii); + g_free (ascii); + } + + for (i = 0; i < num_non_round_trip_names; i++) + { + if (non_round_trip_names[i].orig_is_unicode) + g_assert_true (g_hostname_is_non_ascii (non_round_trip_names[i].orig_name)); + else + g_assert_true (!g_hostname_is_non_ascii (non_round_trip_names[i].orig_name)); + + if (non_round_trip_names[i].ascii_is_encoded) + g_assert_true (g_hostname_is_ascii_encoded (non_round_trip_names[i].ascii_name)); + else + g_assert_true (!g_hostname_is_ascii_encoded (non_round_trip_names[i].ascii_name)); + + ascii = g_hostname_to_ascii (non_round_trip_names[i].orig_name); + g_assert_cmpstr (non_round_trip_names[i].ascii_name, ==, ascii); + g_free (ascii); + + ascii = g_hostname_to_ascii (non_round_trip_names[i].ascii_name); + g_assert_cmpstr (non_round_trip_names[i].ascii_name, ==, ascii); + g_free (ascii); + } + + for (i = 0; i < num_bad_names; i++) + { + ascii = g_hostname_to_ascii (bad_names[i]); + g_assert_cmpstr (ascii, ==, NULL); + } +} + +static void +test_to_unicode (void) +{ + gint i; + gchar *unicode; + + for (i = 0; i < num_idn_test_domains; i++) + { + g_assert_true (g_hostname_is_ascii_encoded (idn_test_domains[i].ascii_name)); + unicode = g_hostname_to_unicode (idn_test_domains[i].ascii_name); + g_assert_cmpstr (idn_test_domains[i].unicode_name, ==, unicode); + g_free (unicode); + + unicode = g_hostname_to_unicode (idn_test_domains[i].unicode_name); + g_assert_cmpstr (idn_test_domains[i].unicode_name, ==, unicode); + g_free (unicode); + } + + for (i = 0; i < num_bad_names; i++) + { + unicode = g_hostname_to_unicode (bad_names[i]); + g_assert_cmpstr (unicode, ==, NULL); + } +} + +static const struct { + const gchar *addr; + gboolean is_addr; +} ip_addr_tests[] = { + /* IPv6 tests */ + + { "0123:4567:89AB:cdef:3210:7654:ba98:FeDc", TRUE }, + + { "0123:4567:89AB:cdef:3210:7654:ba98::", TRUE }, + { "0123:4567:89AB:cdef:3210:7654::", TRUE }, + { "0123:4567:89AB:cdef:3210::", TRUE }, + { "0123:4567:89AB:cdef::", TRUE }, + { "0123:4567:89AB::", TRUE }, + { "0123:4567::", TRUE }, + { "0123::", TRUE }, + + { "::4567:89AB:cdef:3210:7654:ba98:FeDc", TRUE }, + { "::89AB:cdef:3210:7654:ba98:FeDc", TRUE }, + { "::cdef:3210:7654:ba98:FeDc", TRUE }, + { "::3210:7654:ba98:FeDc", TRUE }, + { "::7654:ba98:FeDc", TRUE }, + { "::ba98:FeDc", TRUE }, + { "::FeDc", TRUE }, + + { "0123::89AB:cdef:3210:7654:ba98:FeDc", TRUE }, + { "0123:4567::cdef:3210:7654:ba98:FeDc", TRUE }, + { "0123:4567:89AB::3210:7654:ba98:FeDc", TRUE }, + { "0123:4567:89AB:cdef::7654:ba98:FeDc", TRUE }, + { "0123:4567:89AB:cdef:3210::ba98:FeDc", TRUE }, + { "0123:4567:89AB:cdef:3210:7654::FeDc", TRUE }, + + { "0123::cdef:3210:7654:ba98:FeDc", TRUE }, + { "0123:4567::3210:7654:ba98:FeDc", TRUE }, + { "0123:4567:89AB::7654:ba98:FeDc", TRUE }, + { "0123:4567:89AB:cdef::ba98:FeDc", TRUE }, + { "0123:4567:89AB:cdef:3210::FeDc", TRUE }, + + { "0123::3210:7654:ba98:FeDc", TRUE }, + { "0123:4567::7654:ba98:FeDc", TRUE }, + { "0123:4567:89AB::ba98:FeDc", TRUE }, + { "0123:4567:89AB:cdef::FeDc", TRUE }, + + { "0123::7654:ba98:FeDc", TRUE }, + { "0123:4567::ba98:FeDc", TRUE }, + { "0123:4567:89AB::FeDc", TRUE }, + + { "0123::ba98:FeDc", TRUE }, + { "0123:4567::FeDc", TRUE }, + + { "0123::FeDc", TRUE }, + + { "::", TRUE }, + + { "0:12:345:6789:a:bc:def::", TRUE }, + + { "0123:4567:89AB:cdef:3210:7654:123.45.67.89", TRUE }, + { "0123:4567:89AB:cdef:3210::123.45.67.89", TRUE }, + { "0123:4567:89AB:cdef::123.45.67.89", TRUE }, + { "0123:4567:89AB::123.45.67.89", TRUE }, + { "0123:4567::123.45.67.89", TRUE }, + { "0123::123.45.67.89", TRUE }, + { "::123.45.67.89", TRUE }, + + /* accept zone-id from rfc6874 */ + { "0123:4567:89AB:cdef:3210:7654:ba98:FeDc%zoneid0", TRUE }, + { "fe80::dead:beef%zonÉid0%weird", TRUE }, + { "fe80::dead:beef%", FALSE }, + + /* Contain non-hex chars */ + { "012x:4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:45x7:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:8xAB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:xdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:321;:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210:76*4:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210:7654:b-98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210:7654:ba98:+eDc", FALSE }, + { "0123:4567:89AB:cdef:3210:7654:ba98:FeDc and some trailing junk", FALSE }, + { " 123:4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "012 :4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123: 567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210:7654:ba98:FeD ", FALSE }, + + /* Contains too-long/out-of-range segments */ + { "00123:4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:04567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:189AB:cdef:3210:7654:ba98:FeDc", FALSE }, + + /* Too short */ + { "0123:4567:89AB:cdef:3210:7654:ba98", FALSE }, + { "0123:4567:89AB:cdef:3210:7654", FALSE }, + { "0123:4567:89AB:cdef:3210", FALSE }, + { "0123", FALSE }, + { "", FALSE }, + + /* Too long */ + { "0123:4567:89AB:cdef:3210:7654:ba98:FeDc:9999", FALSE }, + { "0123::4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567::89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB::cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef::3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210::7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210:7654::ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210:7654:ba98::FeDc", FALSE }, + + /* Invalid use of ":"s */ + { "0123::89AB::3210:7654:ba98:FeDc", FALSE }, + { "::4567:89AB:cdef:3210:7654::FeDc", FALSE }, + { "0123::89AB:cdef:3210:7654:ba98::", FALSE }, + { ":4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210:7654:ba98:", FALSE }, + { "0123:::cdef:3210:7654:ba98:FeDc", FALSE }, + { "0123:4567:89AB:cdef:3210:7654:ba98:FeDc:", FALSE }, + { ":0123:4567:89AB:cdef:3210:7654:ba98:FeDc", FALSE }, + { ":::", FALSE }, + + /* IPv4 address at wrong place */ + { "0123:4567:89AB:cdef:3210:123.45.67.89", FALSE }, + { "0123:4567:89AB:cdef:3210:7654::123.45.67.89", FALSE }, + { "0123:4567:89AB:cdef:123.45.67.89", FALSE }, + { "0123:4567:89AB:cdef:3210:123.45.67.89:FeDc", FALSE }, + + /* IPv4 tests */ + + { "123.45.67.89", TRUE }, + { "1.2.3.4", TRUE }, + { "1.2.3.0", TRUE }, + + { "023.045.067.089", FALSE }, + { "1234.5.67.89", FALSE }, + { "123.45.67.00", FALSE }, + { " 1.2.3.4", FALSE }, + { "1 .2.3.4", FALSE }, + { "1. 2.3.4", FALSE }, + { "1.2.3.4 ", FALSE }, + { "1.2.3", FALSE }, + { "1.2.3.4.5", FALSE }, + { "1.b.3.4", FALSE }, + { "1.2.3:4", FALSE }, + { "1.2.3.4, etc", FALSE }, + { "1,2,3,4", FALSE }, + { "1.2.3.com", FALSE }, + { "1.2.3.4.", FALSE }, + { "1.2.3.", FALSE }, + { ".1.2.3.4", FALSE }, + { ".2.3.4", FALSE }, + { "1..2.3.4", FALSE }, + { "1..3.4", FALSE } +}; +static const gint num_ip_addr_tests = G_N_ELEMENTS (ip_addr_tests); + +static void +test_is_ip_addr (void) +{ + gint i; + + for (i = 0; i < num_ip_addr_tests; i++) + { + if (g_hostname_is_ip_address (ip_addr_tests[i].addr) != ip_addr_tests[i].is_addr) + { + char *msg = g_strdup_printf ("g_hostname_is_ip_address (\"%s\") == %s", + ip_addr_tests[i].addr, + ip_addr_tests[i].is_addr ? "TRUE" : "FALSE"); + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); + } + } +} + +/* FIXME: test names with both unicode and ACE-encoded labels */ +/* FIXME: test invalid unicode names */ + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + if (argc == 2 && argv[1][0] != '-') + { + const gchar *hostname = argv[1]; + gchar *converted; + + if (g_hostname_is_non_ascii (hostname)) + { + converted = g_hostname_to_ascii (hostname); + printf ("to_ascii: %s\n", converted); + g_free (converted); + } + else if (g_hostname_is_ascii_encoded (hostname)) + { + converted = g_hostname_to_unicode (hostname); + printf ("to_unicode: %s\n", converted); + g_free (converted); + } + else + printf ("hostname is neither unicode nor ACE encoded\n"); + return 0; + } + + g_test_add_func ("/hostutils/to_ascii", test_to_ascii); + g_test_add_func ("/hostutils/to_unicode", test_to_unicode); + g_test_add_func ("/hostutils/is_ip_addr", test_is_ip_addr); + + return g_test_run (); +} diff --git a/glib/tests/include.c b/glib/tests/include.c new file mode 100644 index 0000000..1325266 --- /dev/null +++ b/glib/tests/include.c @@ -0,0 +1,26 @@ +/* Test case for bug 659866 */ + +#define _POSIX_C_SOURCE 199309L +#undef _GNU_SOURCE +#undef _XOPEN_SOURCE +#include +#include + +static void +test_rwlock (void) +{ + GRWLock lock; + + g_rw_lock_init (&lock); + g_rw_lock_clear (&lock); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/include/rwlock", test_rwlock); + + return g_test_run (); +} diff --git a/glib/tests/io-channel.c b/glib/tests/io-channel.c new file mode 100644 index 0000000..a04bcd0 --- /dev/null +++ b/glib/tests/io-channel.c @@ -0,0 +1,222 @@ +/* GLib testing framework examples and tests + * + * Copyright © 2001 Hidetoshi Tajima + * Copyright © 2001 Ron Steinke + * Copyright © 2001 Owen Taylor + * Copyright © 2002 Manish Singh + * Copyright © 2011 Sjoerd Simons + * Copyright © 2012 Simon McVittie + * Copyright © 2013 Stef Walter + * Copyright © 2005, 2006, 2008, 2012, 2013 Matthias Clasen + * Copyright © 2020 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Philip Withnall + */ + +#include +#include + +static void +test_small_writes (void) +{ + GIOChannel *io; + GIOStatus status = G_IO_STATUS_ERROR; + guint bytes_remaining; + gchar tmp; + GError *local_error = NULL; + + io = g_io_channel_new_file ("iochannel-test-outfile", "w", &local_error); + g_assert_no_error (local_error); + + g_io_channel_set_encoding (io, NULL, NULL); + g_io_channel_set_buffer_size (io, 1022); + + bytes_remaining = 2 * g_io_channel_get_buffer_size (io); + tmp = 0; + + while (bytes_remaining) + { + status = g_io_channel_write_chars (io, &tmp, 1, NULL, NULL); + if (status == G_IO_STATUS_ERROR) + break; + if (status == G_IO_STATUS_NORMAL) + bytes_remaining--; + } + + g_assert_cmpint (status, ==, G_IO_STATUS_NORMAL); + + g_io_channel_unref (io); +} + +static void +test_read_write (void) +{ + GIOChannel *gio_r, *gio_w ; + GError *local_error = NULL; + GString *buffer; + char *filename; + gint rlength = 0; + glong wlength = 0; + gsize length_out; + const gchar *encoding = "EUC-JP"; + GIOStatus status; + const gsize buffer_size_bytes = 1024; + + filename = g_test_build_filename (G_TEST_DIST, "iochannel-test-infile", NULL); + + setbuf (stdout, NULL); /* For debugging */ + + gio_r = g_io_channel_new_file (filename, "r", &local_error); + g_assert_no_error (local_error); + + gio_w = g_io_channel_new_file ("iochannel-test-outfile", "w", &local_error); + g_assert_no_error (local_error); + + g_io_channel_set_encoding (gio_r, encoding, &local_error); + g_assert_no_error (local_error); + + g_io_channel_set_buffer_size (gio_r, buffer_size_bytes); + + status = g_io_channel_set_flags (gio_r, G_IO_FLAG_NONBLOCK, &local_error); + if (status == G_IO_STATUS_ERROR) + { + /* Errors should not happen */ + g_assert_no_error (local_error); + g_clear_error (&local_error); + } + buffer = g_string_sized_new (buffer_size_bytes); + + while (TRUE) + { + do + status = g_io_channel_read_line_string (gio_r, buffer, NULL, &local_error); + while (status == G_IO_STATUS_AGAIN); + if (status != G_IO_STATUS_NORMAL) + break; + + rlength += buffer->len; + + do + status = g_io_channel_write_chars (gio_w, buffer->str, buffer->len, + &length_out, &local_error); + while (status == G_IO_STATUS_AGAIN); + if (status != G_IO_STATUS_NORMAL) + break; + + wlength += length_out; + + /* Ensure the whole line was written */ + g_assert_cmpuint (length_out, ==, buffer->len); + + g_test_message ("%s", buffer->str); + g_string_truncate (buffer, 0); + } + + switch (status) + { + case G_IO_STATUS_EOF: + break; + case G_IO_STATUS_ERROR: + /* Errors should not happen */ + g_assert_no_error (local_error); + g_clear_error (&local_error); + break; + default: + g_assert_not_reached (); + break; + } + + do + status = g_io_channel_flush (gio_w, &local_error); + while (status == G_IO_STATUS_AGAIN); + + if (status == G_IO_STATUS_ERROR) + { + /* Errors should not happen */ + g_assert_no_error (local_error); + g_clear_error (&local_error); + } + + g_test_message ("read %d bytes, wrote %ld bytes", rlength, wlength); + + g_io_channel_unref (gio_r); + g_io_channel_unref (gio_w); + + test_small_writes (); + + g_free (filename); + g_string_free (buffer, TRUE); +} + +static void +test_read_line_embedded_nuls (void) +{ + const guint8 test_data[] = { 'H', 'i', '!', '\0', 'y', 'o', 'u', '\n', ':', ')', '\n' }; + gint fd; + gchar *filename = NULL; + GIOChannel *channel = NULL; + GError *local_error = NULL; + gchar *line = NULL; + gsize line_length, terminator_pos; + GIOStatus status; + + g_test_summary ("Test that reading a line containing embedded nuls works " + "when using non-standard line terminators."); + + /* Write out a temporary file. */ + fd = g_file_open_tmp ("glib-test-io-channel-XXXXXX", &filename, &local_error); + g_assert_no_error (local_error); + g_close (fd, NULL); + fd = -1; + + g_file_set_contents (filename, (const gchar *) test_data, sizeof (test_data), &local_error); + g_assert_no_error (local_error); + + /* Create the channel. */ + channel = g_io_channel_new_file (filename, "r", &local_error); + g_assert_no_error (local_error); + + /* Only break on newline characters, not nuls. + * Use length -1 here to exercise glib#2323; the case where length > 0 + * is covered in glib/tests/protocol.c. */ + g_io_channel_set_line_term (channel, "\n", -1); + g_io_channel_set_encoding (channel, NULL, &local_error); + g_assert_no_error (local_error); + + status = g_io_channel_read_line (channel, &line, &line_length, + &terminator_pos, &local_error); + g_assert_no_error (local_error); + g_assert_cmpint (status, ==, G_IO_STATUS_NORMAL); + g_assert_cmpuint (line_length, ==, 8); + g_assert_cmpuint (terminator_pos, ==, 7); + g_assert_cmpmem (line, line_length, test_data, 8); + + g_free (line); + g_io_channel_unref (channel); + g_free (filename); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/io-channel/read-write", test_read_write); + g_test_add_func ("/io-channel/read-line/embedded-nuls", test_read_line_embedded_nuls); + + return g_test_run (); +} diff --git a/glib/tests/iochannel-test-infile b/glib/tests/iochannel-test-infile new file mode 100644 index 0000000..86e24ee --- /dev/null +++ b/glib/tests/iochannel-test-infile @@ -0,0 +1,5 @@ +Line one +Line two +Line three +/* Hello */ +\x1234\x567890\x6666 diff --git a/glib/tests/keyfile.c b/glib/tests/keyfile.c new file mode 100644 index 0000000..3d72d96 --- /dev/null +++ b/glib/tests/keyfile.c @@ -0,0 +1,1876 @@ + +#include +#include +#include +#include +#include + +static GKeyFile * +load_data (const gchar *data, + GKeyFileFlags flags) +{ + GKeyFile *keyfile; + GError *error = NULL; + + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, flags, &error); + g_assert_no_error (error); + return keyfile; +} + +static void +check_error (GError **error, + GQuark domain, + gint code) +{ + g_assert_error (*error, domain, code); + g_error_free (*error); + *error = NULL; +} + +static void +check_no_error (GError **error) +{ + g_assert_no_error (*error); +} + +static void +check_string_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + const gchar *expected) +{ + GError *error = NULL; + gchar *value; + + value = g_key_file_get_string (keyfile, group, key, &error); + check_no_error (&error); + g_assert_nonnull (value); + g_assert_cmpstr (value, ==, expected); + g_free (value); +} + +static void +check_locale_string_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + const gchar *locale, + const gchar *expected) +{ + GError *error = NULL; + gchar *value; + + value = g_key_file_get_locale_string (keyfile, group, key, locale, &error); + check_no_error (&error); + g_assert_nonnull (value); + g_assert_cmpstr (value, ==, expected); + g_free (value); +} + +static void +check_string_locale_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + const gchar *locale, + const gchar *expected) +{ + gchar *value; + + value = g_key_file_get_locale_for_key (keyfile, group, key, locale); + g_assert_cmpstr (value, ==, expected); + g_free (value); +} + +static void +check_string_list_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + ...) +{ + gint i; + gchar *v, **value; + va_list args; + gsize len; + GError *error = NULL; + + value = g_key_file_get_string_list (keyfile, group, key, &len, &error); + check_no_error (&error); + g_assert_nonnull (value); + + va_start (args, key); + i = 0; + v = va_arg (args, gchar*); + while (v) + { + g_assert_nonnull (value[i]); + g_assert_cmpstr (v, ==, value[i]); + i++; + v = va_arg (args, gchar*); + } + + va_end (args); + + g_strfreev (value); +} + +static void +check_locale_string_list_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + const gchar *locale, + ...) +{ + gint i; + gchar *v, **value; + va_list args; + gsize len; + GError *error = NULL; + + value = g_key_file_get_locale_string_list (keyfile, group, key, locale, &len, &error); + check_no_error (&error); + g_assert_nonnull (value); + + va_start (args, locale); + i = 0; + v = va_arg (args, gchar*); + while (v) + { + g_assert_nonnull (value[i]); + g_assert_cmpstr (v, ==, value[i]); + i++; + v = va_arg (args, gchar*); + } + + va_end (args); + + g_strfreev (value); +} + +static void +check_integer_list_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + ...) +{ + gint i; + gint v, *value; + va_list args; + gsize len; + GError *error = NULL; + + value = g_key_file_get_integer_list (keyfile, group, key, &len, &error); + check_no_error (&error); + g_assert_nonnull (value); + + va_start (args, key); + i = 0; + v = va_arg (args, gint); + while (v != -100) + { + g_assert_cmpint (i, <, len); + g_assert_cmpint (value[i], ==, v); + i++; + v = va_arg (args, gint); + } + + va_end (args); + + g_free (value); +} + +static void +check_double_list_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + ...) +{ + gint i; + gdouble v, *value; + va_list args; + gsize len; + GError *error = NULL; + + value = g_key_file_get_double_list (keyfile, group, key, &len, &error); + check_no_error (&error); + g_assert_nonnull (value); + + va_start (args, key); + i = 0; + v = va_arg (args, gdouble); + while (v != -100) + { + g_assert_cmpint (i, <, len); + g_assert_cmpfloat (value[i], ==, v); + i++; + v = va_arg (args, gdouble); + } + + va_end (args); + + g_free (value); +} + +static void +check_boolean_list_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + ...) +{ + gint i; + gboolean v, *value; + va_list args; + gsize len; + GError *error = NULL; + + value = g_key_file_get_boolean_list (keyfile, group, key, &len, &error); + check_no_error (&error); + g_assert_nonnull (value); + + va_start (args, key); + i = 0; + v = va_arg (args, gboolean); + while (v != -100) + { + g_assert_cmpint (i, <, len); + g_assert_cmpint (value[i], ==, v); + i++; + v = va_arg (args, gboolean); + } + + va_end (args); + + g_free (value); +} + +static void +check_boolean_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + gboolean expected) +{ + GError *error = NULL; + gboolean value; + + value = g_key_file_get_boolean (keyfile, group, key, &error); + check_no_error (&error); + g_assert_cmpint (value, ==, expected); +} + +static void +check_integer_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + gint expected) +{ + GError *error = NULL; + gint value; + + value = g_key_file_get_integer (keyfile, group, key, &error); + check_no_error (&error); + g_assert_cmpint (value, ==, expected); +} + +static void +check_double_value (GKeyFile *keyfile, + const gchar *group, + const gchar *key, + gdouble expected) +{ + GError *error = NULL; + gdouble value; + + value = g_key_file_get_double (keyfile, group, key, &error); + check_no_error (&error); + g_assert_cmpfloat (value, ==, expected); +} + +static void +check_name (const gchar *what, + const gchar *value, + const gchar *expected, + gint position) +{ + g_assert_cmpstr (value, ==, expected); +} + +static void +check_length (const gchar *what, + gint n_items, + gint length, + gint expected) +{ + g_assert_cmpint (n_items, ==, length); + g_assert_cmpint (n_items, ==, expected); +} + + +/* check that both \n and \r\n are accepted as line ends, + * and that stray \r are passed through + */ +static void +test_line_ends (void) +{ + GKeyFile *keyfile; + + const gchar *data = + "[group1]\n" + "key1=value1\n" + "key2=value2\r\n" + "[group2]\r\n" + "key3=value3\r\r\n" + "key4=value4\n"; + + keyfile = load_data (data, 0); + + check_string_value (keyfile, "group1", "key1", "value1"); + check_string_value (keyfile, "group1", "key2", "value2"); + check_string_value (keyfile, "group2", "key3", "value3\r"); + check_string_value (keyfile, "group2", "key4", "value4"); + + g_key_file_free (keyfile); +} + +/* check handling of whitespace + */ +static void +test_whitespace (void) +{ + GKeyFile *keyfile; + + const gchar *data = + "[group1]\n" + "key1 = value1\n" + "key2\t=\tvalue2\n" + " [ group2 ] \n" + "key3 = value3 \n" + "key4 = value \t4\n" + " key5 = value5\n"; + + keyfile = load_data (data, 0); + + check_string_value (keyfile, "group1", "key1", "value1"); + check_string_value (keyfile, "group1", "key2", "value2"); + check_string_value (keyfile, " group2 ", "key3", "value3 "); + check_string_value (keyfile, " group2 ", "key4", "value \t4"); + check_string_value (keyfile, " group2 ", "key5", "value5"); + + g_key_file_free (keyfile); +} + +/* check handling of comments + */ +static void +test_comments (void) +{ + GKeyFile *keyfile; + gchar **names; + gsize len; + GError *error = NULL; + gchar *comment; + + const gchar *data = + "# top comment\n" + "# top comment, continued\n" + "[group1]\n" + "key1 = value1\n" + "# key comment\n" + "# key comment, continued\n" + "key2 = value2\n" + "# line end check\r\n" + "key3 = value3\n" + "# single line comment\n" + "key4 = value4\n" + "# group comment\n" + "# group comment, continued\n" + "[group2]\n"; + + const gchar *top_comment = " top comment\n top comment, continued"; + const gchar *group_comment = " group comment\n group comment, continued"; + const gchar *key_comment = " key comment\n key comment, continued"; + const gchar *key4_comment = " single line comment"; + + keyfile = load_data (data, 0); + + check_string_value (keyfile, "group1", "key1", "value1"); + check_string_value (keyfile, "group1", "key2", "value2"); + check_string_value (keyfile, "group1", "key3", "value3"); + check_string_value (keyfile, "group1", "key4", "value4"); + + names = g_key_file_get_keys (keyfile, "group1", &len, &error); + check_no_error (&error); + + check_length ("keys", g_strv_length (names), len, 4); + check_name ("key", names[0], "key1", 0); + check_name ("key", names[1], "key2", 1); + check_name ("key", names[2], "key3", 2); + check_name ("key", names[3], "key4", 3); + + g_strfreev (names); + + g_key_file_free (keyfile); + + keyfile = load_data (data, G_KEY_FILE_KEEP_COMMENTS); + + names = g_key_file_get_keys (keyfile, "group1", &len, &error); + check_no_error (&error); + + check_length ("keys", g_strv_length (names), len, 4); + check_name ("key", names[0], "key1", 0); + check_name ("key", names[1], "key2", 1); + check_name ("key", names[2], "key3", 2); + check_name ("key", names[3], "key4", 3); + + g_strfreev (names); + + comment = g_key_file_get_comment (keyfile, NULL, NULL, &error); + check_no_error (&error); + check_name ("top comment", comment, top_comment, 0); + g_free (comment); + + comment = g_key_file_get_comment (keyfile, "group1", "key2", &error); + check_no_error (&error); + check_name ("key comment", comment, key_comment, 0); + g_free (comment); + + g_key_file_remove_comment (keyfile, "group1", "key2", &error); + check_no_error (&error); + comment = g_key_file_get_comment (keyfile, "group1", "key2", &error); + check_no_error (&error); + g_assert_null (comment); + + comment = g_key_file_get_comment (keyfile, "group1", "key4", &error); + check_no_error (&error); + check_name ("key comment", comment, key4_comment, 0); + g_free (comment); + + comment = g_key_file_get_comment (keyfile, "group2", NULL, &error); + check_no_error (&error); + check_name ("group comment", comment, group_comment, 0); + g_free (comment); + + comment = g_key_file_get_comment (keyfile, "group3", NULL, &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_assert_null (comment); + + g_key_file_free (keyfile); +} + + +/* check key and group listing */ +static void +test_listing (void) +{ + GKeyFile *keyfile; + gchar **names; + gsize len; + gchar *start; + GError *error = NULL; + + const gchar *data = + "[group1]\n" + "key1=value1\n" + "key2=value2\n" + "[group2]\n" + "key3=value3\n" + "key4=value4\n"; + + keyfile = load_data (data, 0); + + names = g_key_file_get_groups (keyfile, &len); + g_assert_nonnull (names); + + check_length ("groups", g_strv_length (names), len, 2); + check_name ("group name", names[0], "group1", 0); + check_name ("group name", names[1], "group2", 1); + + g_strfreev (names); + + names = g_key_file_get_keys (keyfile, "group1", &len, &error); + check_no_error (&error); + + check_length ("keys", g_strv_length (names), len, 2); + check_name ("key", names[0], "key1", 0); + check_name ("key", names[1], "key2", 1); + + g_strfreev (names); + + names = g_key_file_get_keys (keyfile, "no-such-group", &len, &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + + g_strfreev (names); + + g_assert_true (g_key_file_has_group (keyfile, "group1")); + g_assert_true (g_key_file_has_group (keyfile, "group2")); + g_assert_false (g_key_file_has_group (keyfile, "group10")); + g_assert_false (g_key_file_has_group (keyfile, "group20")); + + start = g_key_file_get_start_group (keyfile); + g_assert_cmpstr (start, ==, "group1"); + g_free (start); + + g_assert_true (g_key_file_has_key (keyfile, "group1", "key1", &error)); + check_no_error (&error); + g_assert_true (g_key_file_has_key (keyfile, "group2", "key3", &error)); + check_no_error (&error); + g_assert_false (g_key_file_has_key (keyfile, "group2", "no-such-key", NULL)); + + g_key_file_has_key (keyfile, "no-such-group", "key", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + + g_key_file_free (keyfile); +} + +/* check parsing of string values */ +static void +test_string (void) +{ + GKeyFile *keyfile; + GError *error = NULL; + gchar *value; + const gchar * const list[3] = { + "one", + "two;andahalf", + "3", + }; + const gchar *data = + "[valid]\n" + "key1=\\s\\n\\t\\r\\\\\n" + "key2=\"quoted\"\n" + "key3='quoted'\n" + "key4=\xe2\x89\xa0\xe2\x89\xa0\n" + "key5= leading space\n" + "key6=trailing space \n" + "[invalid]\n" + "key1=\\a\\b\\0800xff\n" + "key2=blabla\\\n"; + + keyfile = load_data (data, 0); + + check_string_value (keyfile, "valid", "key1", " \n\t\r\\"); + check_string_value (keyfile, "valid", "key2", "\"quoted\""); + check_string_value (keyfile, "valid", "key3", "'quoted'"); + check_string_value (keyfile, "valid", "key4", "\xe2\x89\xa0\xe2\x89\xa0"); + check_string_value (keyfile, "valid", "key5", "leading space"); + check_string_value (keyfile, "valid", "key6", "trailing space "); + + value = g_key_file_get_string (keyfile, "invalid", "key1", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + g_free (value); + + value = g_key_file_get_string (keyfile, "invalid", "key2", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + g_free (value); + + g_key_file_set_string (keyfile, "inserted", "key1", "simple"); + g_key_file_set_string (keyfile, "inserted", "key2", " leading space"); + g_key_file_set_string (keyfile, "inserted", "key3", "\tleading tab"); + g_key_file_set_string (keyfile, "inserted", "key4", "new\nline"); + g_key_file_set_string (keyfile, "inserted", "key5", "carriage\rreturn"); + g_key_file_set_string (keyfile, "inserted", "key6", "slash\\yay!"); + g_key_file_set_string_list (keyfile, "inserted", "key7", list, 3); + + check_string_value (keyfile, "inserted", "key1", "simple"); + check_string_value (keyfile, "inserted", "key2", " leading space"); + check_string_value (keyfile, "inserted", "key3", "\tleading tab"); + check_string_value (keyfile, "inserted", "key4", "new\nline"); + check_string_value (keyfile, "inserted", "key5", "carriage\rreturn"); + check_string_value (keyfile, "inserted", "key6", "slash\\yay!"); + check_string_list_value (keyfile, "inserted", "key7", "one", "two;andahalf", "3", NULL); + + g_key_file_free (keyfile); +} + +/* check parsing of boolean values */ +static void +test_boolean (void) +{ + GKeyFile *keyfile; + GError *error = NULL; + + const gchar *data = + "[valid]\n" + "key1=true\n" + "key2=false\n" + "key3=1\n" + "key4=0\n" + "key5= true\n" + "key6=true \n" + "[invalid]\n" + "key1=t\n" + "key2=f\n" + "key3=yes\n" + "key4=no\n"; + + keyfile = load_data (data, 0); + + check_boolean_value (keyfile, "valid", "key1", TRUE); + check_boolean_value (keyfile, "valid", "key2", FALSE); + check_boolean_value (keyfile, "valid", "key3", TRUE); + check_boolean_value (keyfile, "valid", "key4", FALSE); + check_boolean_value (keyfile, "valid", "key5", TRUE); + check_boolean_value (keyfile, "valid", "key6", TRUE); + + g_key_file_get_boolean (keyfile, "invalid", "key1", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + + g_key_file_get_boolean (keyfile, "invalid", "key2", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + + g_key_file_get_boolean (keyfile, "invalid", "key3", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + + g_key_file_get_boolean (keyfile, "invalid", "key4", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + + g_key_file_set_boolean (keyfile, "valid", "key1", FALSE); + check_boolean_value (keyfile, "valid", "key1", FALSE); + + g_key_file_free (keyfile); +} + +/* check parsing of integer and double values */ +static void +test_number (void) +{ + GKeyFile *keyfile; + GError *error = NULL; + gdouble dval = 0.0; + + const gchar *data = + "[valid]\n" + "key1=0\n" + "key2=1\n" + "key3=-1\n" + "key4=2324431\n" + "key5=-2324431\n" + "key6=000111\n" + "key7= 1\n" + "key8=1 \n" + "dkey1=000111\n" + "dkey2=145.45\n" + "dkey3=-3453.7\n" + "[invalid]\n" + "key1=0xffff\n" + "key2=0.5\n" + "key3=1e37\n" + "key4=ten\n" + "key5=\n" + "key6=1.0.0\n" + "key7=2x2\n" + "key8=abc\n"; + + keyfile = load_data (data, 0); + + check_integer_value (keyfile, "valid", "key1", 0); + check_integer_value (keyfile, "valid", "key2", 1); + check_integer_value (keyfile, "valid", "key3", -1); + check_integer_value (keyfile, "valid", "key4", 2324431); + check_integer_value (keyfile, "valid", "key5", -2324431); + check_integer_value (keyfile, "valid", "key6", 111); + check_integer_value (keyfile, "valid", "key7", 1); + check_integer_value (keyfile, "valid", "key8", 1); + check_double_value (keyfile, "valid", "dkey1", 111.0); + check_double_value (keyfile, "valid", "dkey2", 145.45); + check_double_value (keyfile, "valid", "dkey3", -3453.7); + + g_key_file_get_integer (keyfile, "invalid", "key1", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + + g_key_file_get_integer (keyfile, "invalid", "key2", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + + g_key_file_get_integer (keyfile, "invalid", "key3", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + + g_key_file_get_integer (keyfile, "invalid", "key4", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + + dval = g_key_file_get_double (keyfile, "invalid", "key5", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + g_assert_cmpfloat (dval, ==, 0.0); + + dval = g_key_file_get_double (keyfile, "invalid", "key6", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + g_assert_cmpfloat (dval, ==, 0.0); + + dval = g_key_file_get_double (keyfile, "invalid", "key7", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + g_assert_cmpfloat (dval, ==, 0.0); + + dval = g_key_file_get_double (keyfile, "invalid", "key8", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + g_assert_cmpfloat (dval, ==, 0.0); + + g_key_file_free (keyfile); +} + +/* check handling of translated strings */ +static void +test_locale_string (void) +{ + GKeyFile *keyfile; + gchar *old_locale; + + const gchar *data = + "[valid]\n" + "key1=v1\n" + "key1[de]=v1-de\n" + "key1[de_DE]=v1-de_DE\n" + "key1[de_DE.UTF8]=v1-de_DE.UTF8\n" + "key1[fr]=v1-fr\n" + "key1[en] =v1-en\n" + "key1[sr@Latn]=v1-sr\n"; + + keyfile = load_data (data, G_KEY_FILE_KEEP_TRANSLATIONS); + + check_locale_string_value (keyfile, "valid", "key1", "it", "v1"); + check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de"); + check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de_DE"); + check_locale_string_value (keyfile, "valid", "key1", "de_DE.UTF8", "v1-de_DE.UTF8"); + check_locale_string_value (keyfile, "valid", "key1", "fr", "v1-fr"); + check_locale_string_value (keyfile, "valid", "key1", "fr_FR", "v1-fr"); + check_locale_string_value (keyfile, "valid", "key1", "en", "v1-en"); + check_locale_string_value (keyfile, "valid", "key1", "sr@Latn", "v1-sr"); + + g_key_file_free (keyfile); + + /* now test that translations are thrown away */ + + old_locale = g_strdup (setlocale (LC_ALL, NULL)); + g_setenv ("LANGUAGE", "de", TRUE); + setlocale (LC_ALL, ""); + + keyfile = load_data (data, 0); + + check_locale_string_value (keyfile, "valid", "key1", "it", "v1"); + check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de"); + check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de"); + check_locale_string_value (keyfile, "valid", "key1", "de_DE.UTF8", "v1-de"); + check_locale_string_value (keyfile, "valid", "key1", "fr", "v1"); + check_locale_string_value (keyfile, "valid", "key1", "fr_FR", "v1"); + check_locale_string_value (keyfile, "valid", "key1", "en", "v1"); + + g_key_file_free (keyfile); + + setlocale (LC_ALL, old_locale); + g_free (old_locale); +} + +static void +test_locale_string_multiple_loads (void) +{ + GKeyFile *keyfile = NULL; + GError *local_error = NULL; + gchar *old_locale = NULL; + guint i; + const gchar *data = + "[valid]\n" + "key1=v1\n" + "key1[de]=v1-de\n" + "key1[de_DE]=v1-de_DE\n" + "key1[de_DE.UTF8]=v1-de_DE.UTF8\n" + "key1[fr]=v1-fr\n" + "key1[en] =v1-en\n" + "key1[sr@Latn]=v1-sr\n"; + + g_test_summary ("Check that loading with translations multiple times works"); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2361"); + + old_locale = g_strdup (setlocale (LC_ALL, NULL)); + g_setenv ("LANGUAGE", "de", TRUE); + setlocale (LC_ALL, ""); + + keyfile = g_key_file_new (); + + for (i = 0; i < 3; i++) + { + g_key_file_load_from_data (keyfile, data, -1, G_KEY_FILE_NONE, &local_error); + g_assert_no_error (local_error); + + check_locale_string_value (keyfile, "valid", "key1", "it", "v1"); + check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de"); + check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de"); + } + + g_key_file_free (keyfile); + + setlocale (LC_ALL, old_locale); + g_free (old_locale); +} + +static void +test_lists (void) +{ + GKeyFile *keyfile; + + const gchar *data = + "[valid]\n" + "key1=v1;v2\n" + "key2=v1;v2;\n" + "key3=v1,v2\n" + "key4=v1\\;v2\n" + "key5=true;false\n" + "key6=1;0;-1\n" + "key7= 1 ; 0 ; -1 \n" + "key8=v1\\,v2\n" + "key9=0;1.3456;-76532.456\n"; + + keyfile = load_data (data, 0); + + check_string_list_value (keyfile, "valid", "key1", "v1", "v2", NULL); + check_string_list_value (keyfile, "valid", "key2", "v1", "v2", NULL); + check_string_list_value (keyfile, "valid", "key3", "v1,v2", NULL); + check_string_list_value (keyfile, "valid", "key4", "v1;v2", NULL); + check_boolean_list_value (keyfile, "valid", "key5", TRUE, FALSE, -100); + check_integer_list_value (keyfile, "valid", "key6", 1, 0, -1, -100); + check_double_list_value (keyfile, "valid", "key9", 0.0, 1.3456, -76532.456, -100.0); + /* maybe these should be valid */ + /* check_integer_list_value (keyfile, "valid", "key7", 1, 0, -1, -100);*/ + /* check_string_list_value (keyfile, "valid", "key8", "v1\\,v2", NULL);*/ + + g_key_file_free (keyfile); + + /* Now check an alternate separator */ + + keyfile = load_data (data, 0); + g_key_file_set_list_separator (keyfile, ','); + + check_string_list_value (keyfile, "valid", "key1", "v1;v2", NULL); + check_string_list_value (keyfile, "valid", "key2", "v1;v2;", NULL); + check_string_list_value (keyfile, "valid", "key3", "v1", "v2", NULL); + + g_key_file_free (keyfile); +} + +static void +test_lists_set_get (void) +{ + GKeyFile *keyfile; + static const char * const strings[] = { "v1", "v2" }; + static const char * const locale_strings[] = { "v1-l", "v2-l" }; + static int integers[] = { 1, -1, 2 }; + static gdouble doubles[] = { 3.14, 2.71 }; + + keyfile = g_key_file_new (); + g_key_file_set_string_list (keyfile, "group0", "key1", strings, G_N_ELEMENTS (strings)); + g_key_file_set_locale_string_list (keyfile, "group0", "key1", "de", locale_strings, G_N_ELEMENTS (locale_strings)); + g_key_file_set_integer_list (keyfile, "group0", "key2", integers, G_N_ELEMENTS (integers)); + g_key_file_set_double_list (keyfile, "group0", "key3", doubles, G_N_ELEMENTS (doubles)); + + check_string_list_value (keyfile, "group0", "key1", strings[0], strings[1], NULL); + check_locale_string_list_value (keyfile, "group0", "key1", "de", locale_strings[0], locale_strings[1], NULL); + check_integer_list_value (keyfile, "group0", "key2", integers[0], integers[1], -100); + check_double_list_value (keyfile, "group0", "key3", doubles[0], doubles[1], -100.0); + g_key_file_free (keyfile); + + /* and again with a different list separator */ + keyfile = g_key_file_new (); + g_key_file_set_list_separator (keyfile, ','); + g_key_file_set_string_list (keyfile, "group0", "key1", strings, G_N_ELEMENTS (strings)); + g_key_file_set_locale_string_list (keyfile, "group0", "key1", "de", locale_strings, G_N_ELEMENTS (locale_strings)); + g_key_file_set_integer_list (keyfile, "group0", "key2", integers, G_N_ELEMENTS (integers)); + g_key_file_set_double_list (keyfile, "group0", "key3", doubles, G_N_ELEMENTS (doubles)); + + check_string_list_value (keyfile, "group0", "key1", strings[0], strings[1], NULL); + check_locale_string_list_value (keyfile, "group0", "key1", "de", locale_strings[0], locale_strings[1], NULL); + check_integer_list_value (keyfile, "group0", "key2", integers[0], integers[1], -100); + check_double_list_value (keyfile, "group0", "key3", doubles[0], doubles[1], -100.0); + g_key_file_free (keyfile); +} + +static void +test_group_remove (void) +{ + GKeyFile *keyfile; + gchar **names; + gsize len; + GError *error = NULL; + + const gchar *data = + "[group1]\n" + "[group2]\n" + "key1=bla\n" + "key2=bla\n" + "[group3]\n" + "key1=bla\n" + "key2=bla\n"; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=165887"); + + keyfile = load_data (data, 0); + + names = g_key_file_get_groups (keyfile, &len); + g_assert_nonnull (names); + + check_length ("groups", g_strv_length (names), len, 3); + check_name ("group name", names[0], "group1", 0); + check_name ("group name", names[1], "group2", 1); + check_name ("group name", names[2], "group3", 2); + + g_key_file_remove_group (keyfile, "group1", &error); + check_no_error (&error); + + g_strfreev (names); + + names = g_key_file_get_groups (keyfile, &len); + g_assert_nonnull (names); + + check_length ("groups", g_strv_length (names), len, 2); + check_name ("group name", names[0], "group2", 0); + check_name ("group name", names[1], "group3", 1); + + g_key_file_remove_group (keyfile, "group2", &error); + check_no_error (&error); + + g_strfreev (names); + + names = g_key_file_get_groups (keyfile, &len); + g_assert_nonnull (names); + + check_length ("groups", g_strv_length (names), len, 1); + check_name ("group name", names[0], "group3", 0); + + g_key_file_remove_group (keyfile, "no such group", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + + g_strfreev (names); + + g_key_file_free (keyfile); +} + +static void +test_key_remove (void) +{ + GKeyFile *keyfile; + gchar *value; + GError *error = NULL; + + const gchar *data = + "[group1]\n" + "key1=bla\n" + "key2=bla\n"; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=165980"); + + keyfile = load_data (data, 0); + + check_string_value (keyfile, "group1", "key1", "bla"); + + g_key_file_remove_key (keyfile, "group1", "key1", &error); + check_no_error (&error); + + value = g_key_file_get_string (keyfile, "group1", "key1", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); + g_free (value); + + g_key_file_remove_key (keyfile, "group1", "key1", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); + + g_key_file_remove_key (keyfile, "no such group", "key1", &error); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + + g_key_file_free (keyfile); +} + + +static void +test_groups (void) +{ + GKeyFile *keyfile; + + const gchar *data = + "[1]\n" + "key1=123\n" + "[2]\n" + "key2=123\n"; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=316309"); + + keyfile = load_data (data, 0); + + check_string_value (keyfile, "1", "key1", "123"); + check_string_value (keyfile, "2", "key2", "123"); + + g_key_file_free (keyfile); +} + +static void +test_group_names (void) +{ + GKeyFile *keyfile; + GError *error = NULL; + const gchar *data; + gchar *value; + + /* [ in group name */ + data = "[a[b]\n" + "key1=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + + /* ] in group name */ + data = "[a]b]\n" + "key1=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + + /* control char in group name */ + data = "[a\tb]\n" + "key1=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + + /* empty group name */ + data = "[]\n" + "key1=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + + /* Unicode in group name */ + data = "[\xc2\xbd]\n" + "key1=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_no_error (&error); + + keyfile = g_key_file_new (); + /*g_key_file_set_string (keyfile, "a[b", "key1", "123");*/ + value = g_key_file_get_string (keyfile, "a[b", "key1", &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_assert_null (value); + g_key_file_free (keyfile); + + keyfile = g_key_file_new (); + /*g_key_file_set_string (keyfile, "a]b", "key1", "123");*/ + value = g_key_file_get_string (keyfile, "a]b", "key1", &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_assert_null (value); + g_key_file_free (keyfile); + + keyfile = g_key_file_new (); + /*g_key_file_set_string (keyfile, "a\tb", "key1", "123");*/ + value = g_key_file_get_string (keyfile, "a\tb", "key1", &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_assert_null (value); + g_key_file_free (keyfile); + + keyfile = g_key_file_new (); + g_key_file_set_string (keyfile, "\xc2\xbd", "key1", "123"); + check_string_value (keyfile, "\xc2\xbd", "key1", "123"); + g_key_file_free (keyfile); +} + +static void +test_key_names (void) +{ + GKeyFile *keyfile; + GError *error = NULL; + const gchar *data; + gchar *value; + + /* [ in key name */ + data = "[a]\n" + "key[=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + + /* empty key name */ + data = "[a]\n" + " =123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + + /* empty key name */ + data = "[a]\n" + " [de] =123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + + /* bad locale suffix */ + data = "[a]\n" + "foo[@#!&%]=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + + /* initial space */ + data = "[a]\n" + " foo=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + check_no_error (&error); + check_string_value (keyfile, "a", "foo", "123"); + g_key_file_free (keyfile); + + /* final space */ + data = "[a]\n" + "foo =123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + check_no_error (&error); + check_string_value (keyfile, "a", "foo", "123"); + g_key_file_free (keyfile); + + /* inner space */ + data = "[a]\n" + "foo bar=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + check_no_error (&error); + check_string_value (keyfile, "a", "foo bar", "123"); + g_key_file_free (keyfile); + + /* inner space */ + data = "[a]\n" + "foo [de] =123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE); + g_key_file_free (keyfile); + + /* control char in key name */ + data = "[a]\n" + "key\tfoo=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_no_error (&error); + + /* Unicode in key name */ + data = "[a]\n" + "\xc2\xbd=123\n"; + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + g_key_file_free (keyfile); + check_no_error (&error); + + keyfile = g_key_file_new (); + g_key_file_set_string (keyfile, "a", "x", "123"); + /*g_key_file_set_string (keyfile, "a", "key=", "123");*/ + value = g_key_file_get_string (keyfile, "a", "key=", &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND); + g_assert_null (value); + g_key_file_free (keyfile); + + keyfile = g_key_file_new (); + g_key_file_set_string (keyfile, "a", "x", "123"); + /*g_key_file_set_string (keyfile, "a", "key[", "123");*/ + value = g_key_file_get_string (keyfile, "a", "key[", &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND); + g_assert_null (value); + g_key_file_free (keyfile); + + keyfile = g_key_file_new (); + g_key_file_set_string (keyfile, "a", "x", "123"); + g_key_file_set_string (keyfile, "a", "key\tfoo", "123"); + value = g_key_file_get_string (keyfile, "a", "key\tfoo", &error); + check_no_error (&error); + g_free (value); + g_key_file_free (keyfile); + + keyfile = g_key_file_new (); + g_key_file_set_string (keyfile, "a", "x", "123"); + /*g_key_file_set_string (keyfile, "a", " key", "123");*/ + value = g_key_file_get_string (keyfile, "a", " key", &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND); + g_assert_null (value); + g_key_file_free (keyfile); + + keyfile = g_key_file_new (); + g_key_file_set_string (keyfile, "a", "x", "123"); + + /* Unicode key */ + g_key_file_set_string (keyfile, "a", "\xc2\xbd", "123"); + check_string_value (keyfile, "a", "\xc2\xbd", "123"); + + /* Keys with / + . (as used by the gnome-vfs mime cache) */ + g_key_file_set_string (keyfile, "a", "foo/bar", "/"); + check_string_value (keyfile, "a", "foo/bar", "/"); + g_key_file_set_string (keyfile, "a", "foo+bar", "+"); + check_string_value (keyfile, "a", "foo+bar", "+"); + g_key_file_set_string (keyfile, "a", "foo.bar", "."); + check_string_value (keyfile, "a", "foo.bar", "."); + + g_key_file_free (keyfile); +} + +static void +test_duplicate_keys (void) +{ + GKeyFile *keyfile; + const gchar *data = + "[1]\n" + "key1=123\n" + "key1=345\n"; + + keyfile = load_data (data, 0); + check_string_value (keyfile, "1", "key1", "345"); + + g_key_file_free (keyfile); +} + +static void +test_duplicate_groups (void) +{ + GKeyFile *keyfile; + const gchar *data = + "[Desktop Entry]\n" + "key1=123\n" + "[Desktop Entry]\n" + "key2=123\n"; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=157877"); + + keyfile = load_data (data, 0); + check_string_value (keyfile, "Desktop Entry", "key1", "123"); + check_string_value (keyfile, "Desktop Entry", "key2", "123"); + + g_key_file_free (keyfile); +} + +static void +test_duplicate_groups2 (void) +{ + GKeyFile *keyfile; + const gchar *data = + "[A]\n" + "foo=bar\n" + "[B]\n" + "foo=baz\n" + "[A]\n" + "foo=bang\n"; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=385910"); + + keyfile = load_data (data, 0); + check_string_value (keyfile, "A", "foo", "bang"); + check_string_value (keyfile, "B", "foo", "baz"); + + g_key_file_free (keyfile); +} + +static void +test_reload_idempotency (void) +{ + static const gchar *original_data="" + "# Top comment\n" + "\n" + "# First comment\n" + "[first]\n" + "key=value\n" + "# A random comment in the first group\n" + "anotherkey=anothervalue\n" + "# Second comment - one line\n" + "[second]\n" + "# Third comment - two lines\n" + "# Third comment - two lines\n" + "[third]\n" + "blank_line=1\n" + "\n" + "blank_lines=2\n" + "\n\n" + "[fourth]\n" + "[fifth]\n"; + GKeyFile *keyfile; + GError *error = NULL; + gchar *data1, *data2; + gsize len1, len2; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=420686"); + + /* check that we only insert a single new line between groups */ + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, + original_data, strlen(original_data), + G_KEY_FILE_KEEP_COMMENTS, + &error); + check_no_error (&error); + + data1 = g_key_file_to_data (keyfile, &len1, &error); + g_assert_nonnull (data1); + g_key_file_free (keyfile); + + keyfile = g_key_file_new (); + g_key_file_load_from_data (keyfile, + data1, len1, + G_KEY_FILE_KEEP_COMMENTS, + &error); + check_no_error (&error); + + data2 = g_key_file_to_data (keyfile, &len2, &error); + g_assert_nonnull (data2); + g_key_file_free (keyfile); + + g_assert_cmpstr (data1, ==, data2); + + g_free (data2); + g_free (data1); +} + +static const char int64_data[] = +"[bees]\n" +"a=1\n" +"b=2\n" +"c=123456789123456789\n" +"d=-123456789123456789\n"; + +static void +test_int64 (void) +{ + GKeyFile *file; + gboolean ok; + guint64 c; + gint64 d; + gchar *value; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=614864"); + + file = g_key_file_new (); + + ok = g_key_file_load_from_data (file, int64_data, strlen (int64_data), + 0, NULL); + g_assert_true (ok); + + c = g_key_file_get_uint64 (file, "bees", "c", NULL); + g_assert_cmpuint (c, ==, G_GUINT64_CONSTANT (123456789123456789)); + + d = g_key_file_get_int64 (file, "bees", "d", NULL); + g_assert_cmpint (d, ==, G_GINT64_CONSTANT (-123456789123456789)); + + g_key_file_set_uint64 (file, "bees", "c", + G_GUINT64_CONSTANT (987654321987654321)); + value = g_key_file_get_value (file, "bees", "c", NULL); + g_assert_cmpstr (value, ==, "987654321987654321"); + g_free (value); + + g_key_file_set_int64 (file, "bees", "d", + G_GINT64_CONSTANT (-987654321987654321)); + value = g_key_file_get_value (file, "bees", "d", NULL); + g_assert_cmpstr (value, ==, "-987654321987654321"); + g_free (value); + + g_key_file_free (file); +} + +static void +test_load (void) +{ + GKeyFile *file; + GError *error; + gboolean bools[2] = { TRUE, FALSE }; + gboolean loaded; + + file = g_key_file_new (); + error = NULL; +#ifdef G_OS_UNIX + /* Uses the value of $XDG_DATA_HOME we set in main() */ + loaded = g_key_file_load_from_data_dirs (file, "keyfiletest.ini", NULL, 0, &error); +#else + loaded = g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "keyfiletest.ini", NULL), 0, &error); +#endif + g_assert_no_error (error); + g_assert_true (loaded); + + g_key_file_set_locale_string (file, "test", "key4", "de", "Vierter Schlüssel"); + g_key_file_set_boolean_list (file, "test", "key5", bools, 2); + g_key_file_set_integer (file, "test", "key6", 22); + g_key_file_set_double (file, "test", "key7", 2.5); + g_key_file_set_comment (file, "test", "key7", "some float", NULL); + g_key_file_set_comment (file, "test", NULL, "the test group", NULL); + g_key_file_set_comment (file, NULL, NULL, "top comment", NULL); + + g_key_file_free (file); + + file = g_key_file_new (); + error = NULL; + g_assert_false (g_key_file_load_from_data_dirs (file, "keyfile-test.ini", NULL, 0, &error)); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND); + g_error_free (error); + g_key_file_free (file); +} + +static void +test_save (void) +{ + GKeyFile *kf; + GKeyFile *kf2; + static const char data[] = + "[bees]\n" + "a=1\n" + "b=2\n" + "c=123456789123456789\n" + "d=-123456789123456789\n"; + gboolean ok; + gchar *file; + guint64 c; + GError *error = NULL; + int fd; + + kf = g_key_file_new (); + ok = g_key_file_load_from_data (kf, data, strlen (data), 0, NULL); + g_assert_true (ok); + + file = g_strdup ("key_file_XXXXXX"); + fd = g_mkstemp (file); + g_assert_cmpint (fd, !=, -1); + ok = g_close (fd, &error); + g_assert_true (ok); + g_assert_no_error (error); + ok = g_key_file_save_to_file (kf, file, &error); + g_assert_true (ok); + g_assert_no_error (error); + + kf2 = g_key_file_new (); + ok = g_key_file_load_from_file (kf2, file, 0, &error); + g_assert_true (ok); + g_assert_no_error (error); + + c = g_key_file_get_uint64 (kf2, "bees", "c", NULL); + g_assert_cmpuint (c, ==, G_GUINT64_CONSTANT (123456789123456789)); + + remove (file); + g_free (file); + g_key_file_free (kf); + g_key_file_free (kf2); +} + +static void +test_load_fail (void) +{ + GKeyFile *file; + GError *error; + + file = g_key_file_new (); + error = NULL; + g_assert_false (g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "keyfile.c", NULL), 0, &error)); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); + g_clear_error (&error); + g_assert_false (g_key_file_load_from_file (file, "/nosuchfile", 0, &error)); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); + g_clear_error (&error); + + g_key_file_free (file); +} + +static void +test_non_utf8 (void) +{ + GKeyFile *file; + static const char data[] = +"[group]\n" +"a=\230\230\230\n" +"b=a;b;\230\230\230;\n" +"c=a\\\n"; + gboolean ok; + GError *error; + gchar *s; + gchar **l; + + file = g_key_file_new (); + + ok = g_key_file_load_from_data (file, data, strlen (data), 0, NULL); + g_assert_true (ok); + + error = NULL; + s = g_key_file_get_string (file, "group", "a", &error); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING); + g_assert_null (s); + + g_clear_error (&error); + l = g_key_file_get_string_list (file, "group", "b", NULL, &error); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING); + g_assert_null (l); + + g_clear_error (&error); + l = g_key_file_get_string_list (file, "group", "c", NULL, &error); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); + g_assert_null (l); + + g_clear_error (&error); + + g_key_file_free (file); +} + +static void +test_page_boundary (void) +{ + GKeyFile *file; + GError *error; + gint i; + +#define GROUP "main_section" +#define KEY_PREFIX "fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_" +#define FIRST_KEY 10 +#define LAST_KEY 99 +#define VALUE 92 + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=640695"); + + file = g_key_file_new (); + + error = NULL; + g_key_file_load_from_file (file, g_test_get_filename (G_TEST_DIST, "pages.ini", NULL), G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + + for (i = FIRST_KEY; i <= LAST_KEY; i++) + { + gchar *key; + gint val; + + key = g_strdup_printf (KEY_PREFIX "%d", i); + val = g_key_file_get_integer (file, GROUP, key, &error); + g_free (key); + g_assert_no_error (error); + g_assert_cmpint (val, ==, VALUE); + } + + g_key_file_free (file); +} + +static void +test_ref (void) +{ + GKeyFile *file; + static const char data[] = +"[group]\n" +"a=1\n"; + gboolean ok; + + file = g_key_file_new (); + + ok = g_key_file_load_from_data (file, data, strlen (data), 0, NULL); + g_assert_true (ok); + g_assert_true (g_key_file_has_key (file, "group", "a", NULL)); + g_key_file_ref (file); + g_key_file_free (file); + g_key_file_unref (file); +} + +/* https://bugzilla.gnome.org/show_bug.cgi?id=634232 */ +static void +test_replace_value (void) +{ + GKeyFile *keyfile; + + keyfile = g_key_file_new(); + g_key_file_set_value(keyfile, "grupo1", "chave1", "1234567890"); + g_key_file_set_value(keyfile, "grupo1", "chave1", "123123423423423432432423423"); + g_key_file_remove_group(keyfile, "grupo1", NULL); + g_free (g_key_file_to_data (keyfile, NULL, NULL)); + g_key_file_unref (keyfile); +} + +static void +test_list_separator (void) +{ + GKeyFile *keyfile; + GError *error = NULL; + + const gchar *data = + "[test]\n" + "key1=v1,v2\n"; + + keyfile = g_key_file_new (); + g_key_file_set_list_separator (keyfile, ','); + g_key_file_load_from_data (keyfile, data, -1, 0, &error); + + check_string_list_value (keyfile, "test", "key1", "v1", "v2", NULL); + g_key_file_unref (keyfile); +} + +static void +test_empty_string (void) +{ + GError *error = NULL; + GKeyFile *kf; + + kf = g_key_file_new (); + + g_key_file_load_from_data (kf, "", 0, 0, &error); + g_assert_no_error (error); + + g_key_file_load_from_data (kf, "", -1, 0, &error); + g_assert_no_error (error); + + /* NULL is a fine pointer to use if length is zero */ + g_key_file_load_from_data (kf, NULL, 0, 0, &error); + g_assert_no_error (error); + + /* should not attempt to access non-NULL pointer if length is zero */ + g_key_file_load_from_data (kf, GINT_TO_POINTER (1), 0, 0, &error); + g_assert_no_error (error); + + g_key_file_unref (kf); +} + +static void +test_limbo (void) +{ + GKeyFile *file; + static const char data[] = +"a=b\n" +"[group]\n" +"b=c\n"; + gboolean ok; + GError *error; + + file = g_key_file_new (); + + error = NULL; + ok = g_key_file_load_from_data (file, data, strlen (data), 0, &error); + g_assert_false (ok); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_clear_error (&error); + g_key_file_free (file); +} + +static void +test_utf8 (void) +{ + const gchar *invalid_encoding_names[] = + { + "non-UTF-8", + "UTF", + "UTF-9", + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (invalid_encoding_names); i++) + { + GKeyFile *file = NULL; + gchar *data = NULL; + gboolean ok; + GError *error = NULL; + + g_test_message ("Testing invalid encoding ‘%s’", invalid_encoding_names[i]); + + file = g_key_file_new (); + data = g_strdup_printf ("[group]\n" + "Encoding=%s\n", invalid_encoding_names[i]); + ok = g_key_file_load_from_data (file, data, strlen (data), 0, &error); + g_assert_false (ok); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING); + g_clear_error (&error); + g_key_file_free (file); + g_free (data); + } +} + +static void +test_roundtrip (void) +{ + GKeyFile *kf; + const gchar orig[] = + "[Group1]\n" + "key1=value1\n" + "\n" + "[Group2]\n" + "key1=value1\n"; + gsize len; + gchar *data; + + kf = load_data (orig, G_KEY_FILE_KEEP_COMMENTS); + g_key_file_set_integer (kf, "Group1", "key2", 0); + g_key_file_remove_key (kf, "Group1", "key2", NULL); + + data = g_key_file_to_data (kf, &len, NULL); + g_assert_cmpstr (data, ==, orig); + + g_free (data); + g_key_file_free (kf); +} + +static void +test_bytes (void) +{ + const gchar data[] = + "[Group1]\n" + "key1=value1\n" + "\n" + "[Group2]\n" + "key2=value2\n"; + + GKeyFile *kf = g_key_file_new (); + GBytes *bytes = g_bytes_new (data, strlen (data)); + GError *error = NULL; + + gchar **names; + gsize len; + + g_key_file_load_from_bytes (kf, bytes, 0, &error); + + g_assert_no_error (error); + + names = g_key_file_get_groups (kf, &len); + g_assert_nonnull (names); + + check_length ("groups", g_strv_length (names), len, 2); + check_name ("group name", names[0], "Group1", 0); + check_name ("group name", names[1], "Group2", 1); + + check_string_value (kf, "Group1", "key1", "value1"); + check_string_value (kf, "Group2", "key2", "value2"); + + g_strfreev (names); + g_bytes_unref (bytes); + g_key_file_free (kf); +} + +static void +test_get_locale (void) +{ + GKeyFile *kf; + + kf = g_key_file_new (); + g_key_file_load_from_data (kf, + "[Group]\n" + "x[fr_CA]=a\n" + "x[fr]=b\n" + "x=c\n", + -1, G_KEY_FILE_KEEP_TRANSLATIONS, + NULL); + + check_locale_string_value (kf, "Group", "x", "fr_CA", "a"); + check_string_locale_value (kf, "Group", "x", "fr_CA", "fr_CA"); + + check_locale_string_value (kf, "Group", "x", "fr_CH", "b"); + check_string_locale_value (kf, "Group", "x", "fr_CH", "fr"); + + check_locale_string_value (kf, "Group", "x", "eo", "c"); + check_string_locale_value (kf, "Group", "x", "eo", NULL); + + g_key_file_free (kf); +} + +static void +test_free_when_not_last_ref (void) +{ + GKeyFile *kf; + GError *error = NULL; + const gchar *data = + "[Group]\n" + "Key=Value\n"; + + kf = load_data (data, G_KEY_FILE_NONE); + /* Add a second ref */ + g_key_file_ref (kf); + + /* Quick coherence check */ + g_assert_true (g_key_file_has_group (kf, "Group")); + g_assert_true (g_key_file_has_key (kf, "Group", "Key", &error)); + g_assert_no_error (error); + + /* Should clear all keys and groups, and remove one ref */ + g_key_file_free (kf); + + /* kf should still work */ + g_assert_false (g_key_file_has_group (kf, "Group")); + g_assert_false (g_key_file_has_key (kf, "Group", "Key", &error)); + check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_clear_error (&error); + + g_key_file_load_from_data (kf, data, -1, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + + g_assert_true (g_key_file_has_group (kf, "Group")); + g_assert_true (g_key_file_has_key (kf, "Group", "Key", &error)); + + g_key_file_unref (kf); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + +#ifdef G_OS_UNIX + g_setenv ("XDG_DATA_HOME", g_test_get_dir (G_TEST_DIST), TRUE); +#endif + + g_test_add_func ("/keyfile/line-ends", test_line_ends); + g_test_add_func ("/keyfile/whitespace", test_whitespace); + g_test_add_func ("/keyfile/comments", test_comments); + g_test_add_func ("/keyfile/listing", test_listing); + g_test_add_func ("/keyfile/string", test_string); + g_test_add_func ("/keyfile/boolean", test_boolean); + g_test_add_func ("/keyfile/number", test_number); + g_test_add_func ("/keyfile/locale-string", test_locale_string); + g_test_add_func ("/keyfile/locale-string/multiple-loads", test_locale_string_multiple_loads); + g_test_add_func ("/keyfile/lists", test_lists); + g_test_add_func ("/keyfile/lists-set-get", test_lists_set_get); + g_test_add_func ("/keyfile/group-remove", test_group_remove); + g_test_add_func ("/keyfile/key-remove", test_key_remove); + g_test_add_func ("/keyfile/groups", test_groups); + g_test_add_func ("/keyfile/duplicate-keys", test_duplicate_keys); + g_test_add_func ("/keyfile/duplicate-groups", test_duplicate_groups); + g_test_add_func ("/keyfile/duplicate-groups2", test_duplicate_groups2); + g_test_add_func ("/keyfile/group-names", test_group_names); + g_test_add_func ("/keyfile/key-names", test_key_names); + g_test_add_func ("/keyfile/reload", test_reload_idempotency); + g_test_add_func ("/keyfile/int64", test_int64); + g_test_add_func ("/keyfile/load", test_load); + g_test_add_func ("/keyfile/save", test_save); + g_test_add_func ("/keyfile/load-fail", test_load_fail); + g_test_add_func ("/keyfile/non-utf8", test_non_utf8); + g_test_add_func ("/keyfile/page-boundary", test_page_boundary); + g_test_add_func ("/keyfile/ref", test_ref); + g_test_add_func ("/keyfile/replace-value", test_replace_value); + g_test_add_func ("/keyfile/list-separator", test_list_separator); + g_test_add_func ("/keyfile/empty-string", test_empty_string); + g_test_add_func ("/keyfile/limbo", test_limbo); + g_test_add_func ("/keyfile/utf8", test_utf8); + g_test_add_func ("/keyfile/roundtrip", test_roundtrip); + g_test_add_func ("/keyfile/bytes", test_bytes); + g_test_add_func ("/keyfile/get-locale", test_get_locale); + g_test_add_func ("/keyfile/free-when-not-last-ref", test_free_when_not_last_ref); + + return g_test_run (); +} diff --git a/glib/tests/keyfiletest.ini b/glib/tests/keyfiletest.ini new file mode 100644 index 0000000..62a0431 --- /dev/null +++ b/glib/tests/keyfiletest.ini @@ -0,0 +1,4 @@ +[test] +key1=16 +key2=32 +key3=fourty-eight diff --git a/glib/tests/list.c b/glib/tests/list.c new file mode 100644 index 0000000..4efd8b6 --- /dev/null +++ b/glib/tests/list.c @@ -0,0 +1,659 @@ +#include +#include + +#define SIZE 50 +#define NUMBER_MIN 0000 +#define NUMBER_MAX 9999 + + +static guint32 array[SIZE]; + + +static gint +sort (gconstpointer p1, gconstpointer p2) +{ + gint32 a, b; + + a = GPOINTER_TO_INT (p1); + b = GPOINTER_TO_INT (p2); + + return (a > b ? +1 : a == b ? 0 : -1); +} + +/* + * glist sort tests + */ +static void +test_list_sort (void) +{ + GList *list = NULL; + gint i; + + for (i = 0; i < SIZE; i++) + list = g_list_append (list, GINT_TO_POINTER (array[i])); + + list = g_list_sort (list, sort); + for (i = 0; i < SIZE - 1; i++) + { + gpointer p1, p2; + + p1 = g_list_nth_data (list, i); + p2 = g_list_nth_data (list, i+1); + + g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2)); + } + + g_list_free (list); +} + +static void +test_list_sort_with_data (void) +{ + GList *list = NULL; + gint i; + + for (i = 0; i < SIZE; i++) + list = g_list_append (list, GINT_TO_POINTER (array[i])); + + list = g_list_sort_with_data (list, (GCompareDataFunc)sort, NULL); + for (i = 0; i < SIZE - 1; i++) + { + gpointer p1, p2; + + p1 = g_list_nth_data (list, i); + p2 = g_list_nth_data (list, i+1); + + g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2)); + } + + g_list_free (list); +} + +/* Test that the sort is stable. */ +static void +test_list_sort_stable (void) +{ + GList *list = NULL; /* (element-type utf8) */ + GList *copy = NULL; /* (element-type utf8) */ + gsize i; + + /* Build a test list, already ordered. */ + for (i = 0; i < SIZE; i++) + list = g_list_append (list, g_strdup_printf ("%" G_GSIZE_FORMAT, i / 5)); + + /* Take a copy and sort it. */ + copy = g_list_copy (list); + copy = g_list_sort (copy, (GCompareFunc) g_strcmp0); + + /* Compare the two lists, checking pointers are equal to ensure the elements + * have been kept stable. */ + for (i = 0; i < SIZE; i++) + { + gpointer p1, p2; + + p1 = g_list_nth_data (list, i); + p2 = g_list_nth_data (list, i); + + g_assert (p1 == p2); + } + + g_list_free (copy); + g_list_free_full (list, g_free); +} + +static void +test_list_insert_sorted (void) +{ + GList *list = NULL; + gint i; + + for (i = 0; i < SIZE; i++) + list = g_list_insert_sorted (list, GINT_TO_POINTER (array[i]), sort); + + for (i = 0; i < SIZE - 1; i++) + { + gpointer p1, p2; + + p1 = g_list_nth_data (list, i); + p2 = g_list_nth_data (list, i+1); + + g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2)); + } + + g_list_free (list); +} + +static void +test_list_insert_sorted_with_data (void) +{ + GList *list = NULL; + gint i; + + for (i = 0; i < SIZE; i++) + list = g_list_insert_sorted_with_data (list, + GINT_TO_POINTER (array[i]), + (GCompareDataFunc)sort, + NULL); + + for (i = 0; i < SIZE - 1; i++) + { + gpointer p1, p2; + + p1 = g_list_nth_data (list, i); + p2 = g_list_nth_data (list, i+1); + + g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2)); + } + + g_list_free (list); +} + +static void +test_list_reverse (void) +{ + GList *list = NULL; + GList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + list = g_list_append (list, &nums[i]); + + list = g_list_reverse (list); + + for (i = 0; i < 10; i++) + { + st = g_list_nth (list, i); + g_assert (*((gint*) st->data) == (9 - i)); + } + + g_list_free (list); +} + +static void +test_list_nth (void) +{ + GList *list = NULL; + GList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + list = g_list_append (list, &nums[i]); + + for (i = 0; i < 10; i++) + { + st = g_list_nth (list, i); + g_assert (*((gint*) st->data) == i); + } + + g_list_free (list); +} + +static void +test_list_concat (void) +{ + GList *list1 = NULL; + GList *list2 = NULL; + GList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 5; i++) + { + list1 = g_list_append (list1, &nums[i]); + list2 = g_list_append (list2, &nums[i+5]); + } + + g_assert_cmpint (g_list_length (list1), ==, 5); + g_assert_cmpint (g_list_length (list2), ==, 5); + + list1 = g_list_concat (list1, list2); + + g_assert_cmpint (g_list_length (list1), ==, 10); + + for (i = 0; i < 10; i++) + { + st = g_list_nth (list1, i); + g_assert (*((gint*) st->data) == i); + } + + list2 = g_list_concat (NULL, list1); + g_assert_cmpint (g_list_length (list2), ==, 10); + + list2 = g_list_concat (list1, NULL); + g_assert_cmpint (g_list_length (list2), ==, 10); + + list2 = g_list_concat (NULL, NULL); + g_assert (list2 == NULL); + + g_list_free (list1); +} + +static void +test_list_remove (void) +{ + GList *list = NULL; + GList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + { + list = g_list_append (list, &nums[i]); + list = g_list_append (list, &nums[i]); + } + + g_assert_cmpint (g_list_length (list), ==, 20); + + for (i = 0; i < 10; i++) + { + list = g_list_remove (list, &nums[i]); + } + + g_assert_cmpint (g_list_length (list), ==, 10); + + for (i = 0; i < 10; i++) + { + st = g_list_nth (list, i); + g_assert (*((gint*) st->data) == i); + } + + g_list_free (list); +} + +static void +test_list_remove_all (void) +{ + GList *list = NULL; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + { + list = g_list_append (list, &nums[i]); + list = g_list_append (list, &nums[i]); + } + + g_assert_cmpint (g_list_length (list), ==, 20); + + for (i = 0; i < 5; i++) + { + list = g_list_remove_all (list, &nums[2 * i + 1]); + list = g_list_remove_all (list, &nums[8 - 2 * i]); + } + + g_assert_cmpint (g_list_length (list), ==, 0); + g_assert (list == NULL); +} + +static void +test_list_first_last (void) +{ + GList *list = NULL; + GList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + list = g_list_append (list, &nums[i]); + + st = g_list_last (list); + g_assert (*((gint*) st->data) == 9); + st = g_list_nth_prev (st, 3); + g_assert (*((gint*) st->data) == 6); + st = g_list_first (st); + g_assert (*((gint*) st->data) == 0); + + g_list_free (list); +} + +static void +test_list_insert (void) +{ + GList *list = NULL; + GList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + list = g_list_insert_before (NULL, NULL, &nums[1]); + list = g_list_insert (list, &nums[3], 1); + list = g_list_insert (list, &nums[4], -1); + list = g_list_insert (list, &nums[0], 0); + list = g_list_insert (list, &nums[5], 100); + list = g_list_insert_before (list, NULL, &nums[6]); + list = g_list_insert_before (list, list->next->next, &nums[2]); + + list = g_list_insert (list, &nums[9], 7); + list = g_list_insert (list, &nums[8], 7); + list = g_list_insert (list, &nums[7], 7); + + for (i = 0; i < 10; i++) + { + st = g_list_nth (list, i); + g_assert (*((gint*) st->data) == i); + } + + g_list_free (list); +} + +typedef struct +{ + gboolean freed; + int x; +} ListItem; + +static void +free_func (gpointer data) +{ + ListItem *item = data; + + item->freed = TRUE; +} + +static ListItem * +new_item (int x) +{ + ListItem *item; + + item = g_slice_new (ListItem); + item->freed = FALSE; + item->x = x; + + return item; +} + +static void +test_free_full (void) +{ + ListItem *one, *two, *three; + GSList *slist = NULL; + GList *list = NULL; + + slist = g_slist_prepend (slist, one = new_item (1)); + slist = g_slist_prepend (slist, two = new_item (2)); + slist = g_slist_prepend (slist, three = new_item (3)); + g_assert (!one->freed); + g_assert (!two->freed); + g_assert (!three->freed); + g_slist_free_full (slist, free_func); + g_assert (one->freed); + g_assert (two->freed); + g_assert (three->freed); + g_slice_free (ListItem, one); + g_slice_free (ListItem, two); + g_slice_free (ListItem, three); + + list = g_list_prepend (list, one = new_item (1)); + list = g_list_prepend (list, two = new_item (2)); + list = g_list_prepend (list, three = new_item (3)); + g_assert (!one->freed); + g_assert (!two->freed); + g_assert (!three->freed); + g_list_free_full (list, free_func); + g_assert (one->freed); + g_assert (two->freed); + g_assert (three->freed); + g_slice_free (ListItem, one); + g_slice_free (ListItem, two); + g_slice_free (ListItem, three); +} + +static void +test_list_copy (void) +{ + GList *l, *l2; + GList *u, *v; + + l = NULL; + l = g_list_append (l, GINT_TO_POINTER (1)); + l = g_list_append (l, GINT_TO_POINTER (2)); + l = g_list_append (l, GINT_TO_POINTER (3)); + + l2 = g_list_copy (l); + + for (u = l, v = l2; u && v; u = u->next, v = v->next) + { + g_assert (u->data == v->data); + } + + g_list_free (l); + g_list_free (l2); +} + +static gpointer +multiply_value (gconstpointer value, gpointer data) +{ + return GINT_TO_POINTER (GPOINTER_TO_INT (value) * GPOINTER_TO_INT (data)); +} + +static void +test_list_copy_deep (void) +{ + GList *l, *l2; + GList *u, *v; + + l = NULL; + l = g_list_append (l, GINT_TO_POINTER (1)); + l = g_list_append (l, GINT_TO_POINTER (2)); + l = g_list_append (l, GINT_TO_POINTER (3)); + + l2 = g_list_copy_deep (l, multiply_value, GINT_TO_POINTER (2)); + + for (u = l, v = l2; u && v; u = u->next, v = v->next) + { + g_assert_cmpint (GPOINTER_TO_INT (u->data) * 2, ==, GPOINTER_TO_INT (v->data)); + } + + g_list_free (l); + g_list_free (l2); +} + +static void +test_delete_link (void) +{ + GList *l, *l2; + + l = NULL; + l = g_list_append (l, GINT_TO_POINTER (1)); + l = g_list_append (l, GINT_TO_POINTER (2)); + l = g_list_append (l, GINT_TO_POINTER (3)); + + l2 = l->next; + + l = g_list_delete_link (l, l2); + g_assert (l->data == GINT_TO_POINTER (1)); + g_assert (l->next->data == GINT_TO_POINTER (3)); + + g_list_free (l); +} + +static void +test_prepend (void) +{ + gpointer a = "a"; + gpointer b = "b"; + gpointer c = "c"; + GList *l, *l2; + + l = NULL; + l = g_list_prepend (l, c); + l = g_list_prepend (l, a); + + g_assert (l->data == a); + g_assert (l->next->data == c); + g_assert (l->next->next == NULL); + + l2 = l->next; + l2 = g_list_prepend (l2, b); + g_assert (l2->prev == l); + + g_assert (l->data == a); + g_assert (l->next->data == b); + g_assert (l->next->next->data == c); + g_assert (l->next->next->next == NULL); + + g_list_free (l); +} + +static void +test_position (void) +{ + GList *l, *ll; + char *a = "a"; + char *b = "b"; + char *c = "c"; + char *d = "d"; + + l = NULL; + l = g_list_append (l, a); + l = g_list_append (l, b); + l = g_list_append (l, c); + + ll = g_list_find (l, a); + g_assert_cmpint (g_list_position (l, ll), ==, 0); + g_assert_cmpint (g_list_index (l, a), ==, 0); + ll = g_list_find (l, b); + g_assert_cmpint (g_list_position (l, ll), ==, 1); + g_assert_cmpint (g_list_index (l, b), ==, 1); + ll = g_list_find (l, c); + g_assert_cmpint (g_list_position (l, ll), ==, 2); + g_assert_cmpint (g_list_index (l, c), ==, 2); + + ll = g_list_append (NULL, d); + g_assert_cmpint (g_list_position (l, ll), ==, -1); + g_assert_cmpint (g_list_index (l, d), ==, -1); + + g_list_free (l); + g_list_free (ll); +} + +static void +test_double_free (void) +{ + GList *list, *link; + // Casts to size_t first ensure compilers won't warn about pointer casts that change size + // MSVC's C4312 warning with /Wp64 + GList intruder = { NULL, (gpointer)(size_t)0xDEADBEEF, (gpointer)(size_t)0xDEADBEEF }; + + if (g_test_subprocess ()) + { + list = NULL; + list = g_list_append (list, "a"); + link = list = g_list_append (list, "b"); + list = g_list_append (list, "c"); + + list = g_list_remove_link (list, link); + link->prev = list; + link->next = &intruder; + list = g_list_remove_link (list, link); + + g_list_free (list); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*corrupted double-linked list detected*"); +} + +static void +test_list_insert_before_link (void) +{ + GList a = {0}; + GList b = {0}; + GList c = {0}; + GList d = {0}; + GList e = {0}; + GList *list; + + list = g_list_insert_before_link (NULL, NULL, &a); + g_assert_nonnull (list); + g_assert_true (list == &a); + g_assert_null (a.prev); + g_assert_null (a.next); + g_assert_cmpint (g_list_length (list), ==, 1); + + list = g_list_insert_before_link (list, &a, &b); + g_assert_nonnull (list); + g_assert_true (list == &b); + g_assert_null (b.prev); + g_assert_true (b.next == &a); + g_assert_true (a.prev == &b); + g_assert_null (a.next); + g_assert_cmpint (g_list_length (list), ==, 2); + + list = g_list_insert_before_link (list, &a, &c); + g_assert_nonnull (list); + g_assert_true (list == &b); + g_assert_null (b.prev); + g_assert_true (b.next == &c); + g_assert_true (c.next == &a); + g_assert_true (c.prev == &b); + g_assert_true (a.prev == &c); + g_assert_null (a.next); + g_assert_cmpint (g_list_length (list), ==, 3); + + list = g_list_insert_before_link (list, &b, &d); + g_assert_nonnull (list); + g_assert_true (list == &d); + g_assert_null (d.prev); + g_assert_true (b.prev == &d); + g_assert_true (c.prev == &b); + g_assert_true (a.prev == &c); + g_assert_true (d.next == &b); + g_assert_true (b.next == &c); + g_assert_true (c.next == &a); + g_assert_null (a.next); + g_assert_cmpint (g_list_length (list), ==, 4); + + list = g_list_insert_before_link (list, NULL, &e); + g_assert_nonnull (list); + g_assert_true (list == &d); + g_assert_null (d.prev); + g_assert_true (b.prev == &d); + g_assert_true (c.prev == &b); + g_assert_true (a.prev == &c); + g_assert_true (d.next == &b); + g_assert_true (b.next == &c); + g_assert_true (c.next == &a); + g_assert_true (a.next == &e); + g_assert_true (e.prev == &a); + g_assert_null (e.next); + g_assert_cmpint (g_list_length (list), ==, 5); +} + +int +main (int argc, char *argv[]) +{ + gint i; + + g_test_init (&argc, &argv, NULL); + + /* Create an array of random numbers. */ + for (i = 0; i < SIZE; i++) + array[i] = g_test_rand_int_range (NUMBER_MIN, NUMBER_MAX); + + g_test_add_func ("/list/sort", test_list_sort); + g_test_add_func ("/list/sort-with-data", test_list_sort_with_data); + g_test_add_func ("/list/sort/stable", test_list_sort_stable); + g_test_add_func ("/list/insert-before-link", test_list_insert_before_link); + g_test_add_func ("/list/insert-sorted", test_list_insert_sorted); + g_test_add_func ("/list/insert-sorted-with-data", test_list_insert_sorted_with_data); + g_test_add_func ("/list/reverse", test_list_reverse); + g_test_add_func ("/list/nth", test_list_nth); + g_test_add_func ("/list/concat", test_list_concat); + g_test_add_func ("/list/remove", test_list_remove); + g_test_add_func ("/list/remove-all", test_list_remove_all); + g_test_add_func ("/list/first-last", test_list_first_last); + g_test_add_func ("/list/insert", test_list_insert); + g_test_add_func ("/list/free-full", test_free_full); + g_test_add_func ("/list/copy", test_list_copy); + g_test_add_func ("/list/copy-deep", test_list_copy_deep); + g_test_add_func ("/list/delete-link", test_delete_link); + g_test_add_func ("/list/prepend", test_prepend); + g_test_add_func ("/list/position", test_position); + g_test_add_func ("/list/double-free", test_double_free); + + return g_test_run (); +} diff --git a/glib/tests/logging.c b/glib/tests/logging.c new file mode 100644 index 0000000..e9c4e39 --- /dev/null +++ b/glib/tests/logging.c @@ -0,0 +1,668 @@ +#include +#include +#define G_LOG_USE_STRUCTURED 1 +#include + +/* Test g_warn macros */ +static void +test_warnings (void) +{ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*test_warnings*should not be reached*"); + g_warn_if_reached (); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*test_warnings*runtime check failed*"); + g_warn_if_fail (FALSE); + g_test_assert_expected_messages (); +} + +static guint log_count = 0; + +static void +log_handler (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + g_assert_cmpstr (log_domain, ==, "bu"); + g_assert_cmpint (log_level, ==, G_LOG_LEVEL_INFO); + + log_count++; +} + +/* test that custom log handlers only get called for + * their domain and level + */ +static void +test_set_handler (void) +{ + guint id; + + id = g_log_set_handler ("bu", G_LOG_LEVEL_INFO, log_handler, NULL); + + g_log ("bu", G_LOG_LEVEL_DEBUG, "message"); + g_log ("ba", G_LOG_LEVEL_DEBUG, "message"); + g_log ("bu", G_LOG_LEVEL_INFO, "message"); + g_log ("ba", G_LOG_LEVEL_INFO, "message"); + + g_assert_cmpint (log_count, ==, 1); + + g_log_remove_handler ("bu", id); +} + +static void +test_default_handler_error (void) +{ + g_log_set_default_handler (g_log_default_handler, NULL); + g_error ("message1"); + exit (0); +} + +static void +test_default_handler_critical (void) +{ + g_log_set_default_handler (g_log_default_handler, NULL); + g_critical ("message2"); + exit (0); +} + +static void +test_default_handler_warning (void) +{ + g_log_set_default_handler (g_log_default_handler, NULL); + g_warning ("message3"); + exit (0); +} + +static void +test_default_handler_message (void) +{ + g_log_set_default_handler (g_log_default_handler, NULL); + g_message ("message4"); + exit (0); +} + +static void +test_default_handler_info (void) +{ + g_log_set_default_handler (g_log_default_handler, NULL); + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "message5"); + exit (0); +} + +static void +test_default_handler_bar_info (void) +{ + g_log_set_default_handler (g_log_default_handler, NULL); + + g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE); + + g_log ("bar", G_LOG_LEVEL_INFO, "message5"); + exit (0); +} + +static void +test_default_handler_baz_debug (void) +{ + g_log_set_default_handler (g_log_default_handler, NULL); + + g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE); + + g_log ("baz", G_LOG_LEVEL_DEBUG, "message6"); + exit (0); +} + +static void +test_default_handler_debug (void) +{ + g_log_set_default_handler (g_log_default_handler, NULL); + + g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); + + g_log ("foo", G_LOG_LEVEL_DEBUG, "6"); + g_log ("bar", G_LOG_LEVEL_DEBUG, "6"); + g_log ("baz", G_LOG_LEVEL_DEBUG, "6"); + + exit (0); +} + +static void +test_default_handler_debug_stderr (void) +{ + g_log_writer_default_set_use_stderr (TRUE); + g_log_set_default_handler (g_log_default_handler, NULL); + + g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); + + g_log ("foo", G_LOG_LEVEL_DEBUG, "6"); + g_log ("bar", G_LOG_LEVEL_DEBUG, "6"); + g_log ("baz", G_LOG_LEVEL_DEBUG, "6"); + + exit (0); +} + +static void +test_default_handler_would_drop (void) +{ + g_unsetenv ("G_MESSAGES_DEBUG"); + + g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_ERROR, "foo")); + g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_CRITICAL, "foo")); + g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_WARNING, "foo")); + g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_MESSAGE, "foo")); + g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_INFO, "foo")); + g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo")); + g_assert_false (g_log_writer_default_would_drop (1<key, f2->key) != 0) + return FALSE; + if (f1->length != f2->length) + return FALSE; + + if (f1->length == -1) + return strcmp (f1->value, f2->value) == 0; + else + return memcmp (f1->value, f2->value, f1->length) == 0; +} + +static gboolean +compare_fields (const GLogField *f1, gsize n1, const GLogField *f2, gsize n2) +{ + gsize i, j; + + for (i = 0; i < n1; i++) + { + for (j = 0; j < n2; j++) + { + if (compare_field (&f1[i], &f2[j])) + break; + } + if (j == n2) + return FALSE; + } + + return TRUE; +} + +static GSList *expected_messages = NULL; +static const guchar binary_field[] = {1, 2, 3, 4, 5}; + + +static GLogWriterOutput +expect_log_writer (GLogLevelFlags log_level, + const GLogField *fields, + gsize n_fields, + gpointer user_data) +{ + ExpectedMessage *expected = expected_messages->data; + + if (compare_fields (fields, n_fields, expected->fields, expected->n_fields)) + { + expected_messages = g_slist_delete_link (expected_messages, expected_messages); + } + else if ((log_level & G_LOG_LEVEL_DEBUG) != G_LOG_LEVEL_DEBUG) + { + char *str; + + str = g_log_writer_format_fields (log_level, fields, n_fields, FALSE); + g_test_fail_printf ("Unexpected message: %s", str); + g_free (str); + } + + return G_LOG_WRITER_HANDLED; +} + +static void +test_structured_logging_no_state (void) +{ + gpointer some_pointer = GUINT_TO_POINTER (0x100); + guint some_integer = 123; + + log_count = 0; + g_log_set_writer_func (null_log_writer, NULL, NULL); + + g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE, + "MESSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e", + "MY_APPLICATION_CUSTOM_FIELD", "some debug string", + "MESSAGE", "This is a debug message about pointer %p and integer %u.", + some_pointer, some_integer); + + g_assert_cmpint (log_count, ==, 1); +} + +static void +test_structured_logging_some_state (void) +{ + gpointer state_object = NULL; /* this must not be dereferenced */ + const GLogField fields[] = { + { "MESSAGE", "This is a debug message.", -1 }, + { "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 }, + { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 }, + { "MY_APPLICATION_STATE", state_object, 0 }, + }; + + log_count = 0; + g_log_set_writer_func (null_log_writer, NULL, NULL); + + g_log_structured_array (G_LOG_LEVEL_DEBUG, fields, G_N_ELEMENTS (fields)); + + g_assert_cmpint (log_count, ==, 1); +} + +static void +test_structured_logging_robustness (void) +{ + log_count = 0; + g_log_set_writer_func (null_log_writer, NULL, NULL); + + /* NULL log_domain shouldn't crash */ + g_log (NULL, G_LOG_LEVEL_MESSAGE, "Test"); + g_log_structured (NULL, G_LOG_LEVEL_MESSAGE, "MESSAGE", "Test"); + + g_assert_cmpint (log_count, ==, 1); +} + +static void +test_structured_logging_roundtrip1 (void) +{ + gpointer some_pointer = GUINT_TO_POINTER (0x100); + gint some_integer = 123; + gchar message[200]; + GLogField fields[] = { + { "GLIB_DOMAIN", "some-domain", -1 }, + { "PRIORITY", "5", -1 }, + { "MESSAGE", "String assigned using g_snprintf() below", -1 }, + { "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 }, + { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 } + }; + ExpectedMessage expected = { fields, 5 }; + + /* %p format is implementation defined and depends on the platform */ + g_snprintf (message, sizeof (message), + "This is a debug message about pointer %p and integer %u.", + some_pointer, some_integer); + fields[2].value = message; + + expected_messages = g_slist_append (NULL, &expected); + g_log_set_writer_func (expect_log_writer, NULL, NULL); + + g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE, + "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", + "MY_APPLICATION_CUSTOM_FIELD", "some debug string", + "MESSAGE", "This is a debug message about pointer %p and integer %u.", + some_pointer, some_integer); + + if (expected_messages != NULL) + { + char *str; + ExpectedMessage *msg = expected_messages->data; + + str = g_log_writer_format_fields (0, msg->fields, msg->n_fields, FALSE); + g_test_fail_printf ("Unexpected message: %s", str); + g_free (str); + } +} + +static void +test_structured_logging_roundtrip2 (void) +{ + const gchar *some_string = "abc"; + const GLogField fields[] = { + { "GLIB_DOMAIN", "some-domain", -1 }, + { "PRIORITY", "5", -1 }, + { "MESSAGE", "This is a debug message about string 'abc'.", -1 }, + { "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", -1 }, + { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 } + }; + ExpectedMessage expected = { fields, 5 }; + + expected_messages = g_slist_append (NULL, &expected); + g_log_set_writer_func (expect_log_writer, NULL, NULL); + + g_log_structured ("some-domain", G_LOG_LEVEL_MESSAGE, + "MESSAGE_ID", "fcfb2e1e65c3494386b74878f1abf893", + "MY_APPLICATION_CUSTOM_FIELD", "some debug string", + "MESSAGE", "This is a debug message about string '%s'.", + some_string); + + g_assert (expected_messages == NULL); +} + +static void +test_structured_logging_roundtrip3 (void) +{ + const GLogField fields[] = { + { "GLIB_DOMAIN", "some-domain", -1 }, + { "PRIORITY", "4", -1 }, + { "MESSAGE", "Test test test.", -1 } + }; + ExpectedMessage expected = { fields, 3 }; + + expected_messages = g_slist_append (NULL, &expected); + g_log_set_writer_func (expect_log_writer, NULL, NULL); + + g_log_structured ("some-domain", G_LOG_LEVEL_WARNING, + "MESSAGE", "Test test test."); + + g_assert (expected_messages == NULL); +} + +static GVariant * +create_variant_fields (void) +{ + GVariant *binary; + GVariantBuilder builder; + + binary = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, binary_field, G_N_ELEMENTS (binary_field), sizeof (binary_field[0])); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", "MESSAGE_ID", g_variant_new_string ("06d4df59e6c24647bfe69d2c27ef0b4e")); + g_variant_builder_add (&builder, "{sv}", "MESSAGE", g_variant_new_string ("This is a debug message")); + g_variant_builder_add (&builder, "{sv}", "MY_APPLICATION_CUSTOM_FIELD", g_variant_new_string ("some debug string")); + g_variant_builder_add (&builder, "{sv}", "MY_APPLICATION_CUSTOM_FIELD_BINARY", binary); + + return g_variant_builder_end (&builder); +} + +static void +test_structured_logging_variant1 (void) +{ + GVariant *v = create_variant_fields (); + + log_count = 0; + g_log_set_writer_func (null_log_writer, NULL, NULL); + + g_log_variant ("some-domain", G_LOG_LEVEL_MESSAGE, v); + g_variant_unref (v); + g_assert_cmpint (log_count, ==, 1); +} + +static void +test_structured_logging_variant2 (void) +{ + const GLogField fields[] = { + { "GLIB_DOMAIN", "some-domain", -1 }, + { "PRIORITY", "5", -1 }, + { "MESSAGE", "This is a debug message", -1 }, + { "MESSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e", -1 }, + { "MY_APPLICATION_CUSTOM_FIELD", "some debug string", -1 }, + { "MY_APPLICATION_CUSTOM_FIELD_BINARY", binary_field, sizeof (binary_field) } + }; + ExpectedMessage expected = { fields, 6 }; + GVariant *v = create_variant_fields (); + + expected_messages = g_slist_append (NULL, &expected); + g_log_set_writer_func (expect_log_writer, NULL, NULL); + + g_log_variant ("some-domain", G_LOG_LEVEL_MESSAGE, v); + g_variant_unref (v); + g_assert (expected_messages == NULL); +} + +int +main (int argc, char *argv[]) +{ + g_unsetenv ("G_MESSAGES_DEBUG"); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/logging/default-handler", test_default_handler); + g_test_add_func ("/logging/default-handler/subprocess/error", test_default_handler_error); + g_test_add_func ("/logging/default-handler/subprocess/critical", test_default_handler_critical); + g_test_add_func ("/logging/default-handler/subprocess/warning", test_default_handler_warning); + g_test_add_func ("/logging/default-handler/subprocess/message", test_default_handler_message); + g_test_add_func ("/logging/default-handler/subprocess/info", test_default_handler_info); + g_test_add_func ("/logging/default-handler/subprocess/bar-info", test_default_handler_bar_info); + g_test_add_func ("/logging/default-handler/subprocess/baz-debug", test_default_handler_baz_debug); + g_test_add_func ("/logging/default-handler/subprocess/debug", test_default_handler_debug); + g_test_add_func ("/logging/default-handler/subprocess/debug-stderr", test_default_handler_debug_stderr); + g_test_add_func ("/logging/default-handler/subprocess/0x400", test_default_handler_0x400); + g_test_add_func ("/logging/default-handler/subprocess/would-drop", test_default_handler_would_drop); + g_test_add_func ("/logging/warnings", test_warnings); + g_test_add_func ("/logging/fatal-log-mask", test_fatal_log_mask); + g_test_add_func ("/logging/set-handler", test_set_handler); + g_test_add_func ("/logging/print-handler", test_print_handler); + g_test_add_func ("/logging/printerr-handler", test_printerr_handler); + g_test_add_func ("/logging/653052", bug653052); + g_test_add_func ("/logging/gibberish", test_gibberish); + g_test_add_func ("/structured-logging/no-state", test_structured_logging_no_state); + g_test_add_func ("/structured-logging/some-state", test_structured_logging_some_state); + g_test_add_func ("/structured-logging/robustness", test_structured_logging_robustness); + g_test_add_func ("/structured-logging/roundtrip1", test_structured_logging_roundtrip1); + g_test_add_func ("/structured-logging/roundtrip2", test_structured_logging_roundtrip2); + g_test_add_func ("/structured-logging/roundtrip3", test_structured_logging_roundtrip3); + g_test_add_func ("/structured-logging/variant1", test_structured_logging_variant1); + g_test_add_func ("/structured-logging/variant2", test_structured_logging_variant2); + + return g_test_run (); +} diff --git a/glib/tests/macros.c b/glib/tests/macros.c new file mode 100644 index 0000000..317832a --- /dev/null +++ b/glib/tests/macros.c @@ -0,0 +1,71 @@ +/* GLib testing framework examples and tests + * + * Copyright © 2018 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Philip Withnall + */ + +#include + +/* Test that G_STATIC_ASSERT_EXPR can be used as an expression */ +static void +test_assert_static (void) +{ + G_STATIC_ASSERT (4 == 4); + if (G_STATIC_ASSERT_EXPR (1 == 1), sizeof (gchar) == 2) + g_assert_not_reached (); +} + +/* Test G_ALIGNOF() gives the same results as the G_STRUCT_OFFSET fallback. This + * should be the minimal alignment for the given type. + * + * This is necessary because the implementation of G_ALIGNOF() varies depending + * on the compiler in use. We want all implementations to be consistent. + * + * In the case that the compiler uses the G_STRUCT_OFFSET fallback, this test + * is a no-op. */ +static void +test_alignof_fallback (void) +{ +#define check_alignof(type) \ + g_assert_cmpint (G_ALIGNOF (type), ==, G_STRUCT_OFFSET (struct { char a; type b; }, b)) + + check_alignof (char); + check_alignof (int); + check_alignof (float); + check_alignof (double); + check_alignof (struct { char a; int b; }); +} + +static void +test_struct_sizeof_member (void) +{ + G_STATIC_ASSERT (G_SIZEOF_MEMBER (struct { char a; int b; }, a) == sizeof (char)); + g_assert_cmpint (G_SIZEOF_MEMBER (struct { char a; int b; }, b), ==, sizeof (int)); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/alignof/fallback", test_alignof_fallback); + g_test_add_func ("/assert/static", test_assert_static); + g_test_add_func ("/struct/sizeof_member", test_struct_sizeof_member); + + return g_test_run (); +} diff --git a/glib/tests/mainloop.c b/glib/tests/mainloop.c new file mode 100644 index 0000000..38eee47 --- /dev/null +++ b/glib/tests/mainloop.c @@ -0,0 +1,2394 @@ +/* Unit tests for GMainLoop + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include "glib-private.h" +#include +#include + +static gboolean +cb (gpointer data) +{ + return FALSE; +} + +static gboolean +prepare (GSource *source, gint *time) +{ + return FALSE; +} +static gboolean +check (GSource *source) +{ + return FALSE; +} +static gboolean +dispatch (GSource *source, GSourceFunc cb, gpointer date) +{ + return FALSE; +} + +static GSourceFuncs global_funcs = { + prepare, + check, + dispatch, + NULL, + NULL, + NULL +}; + +static void +test_maincontext_basic (void) +{ + GMainContext *ctx; + GSource *source; + guint id; + gpointer data = &global_funcs; + + ctx = g_main_context_new (); + + g_assert_false (g_main_context_pending (ctx)); + g_assert_false (g_main_context_iteration (ctx, FALSE)); + + source = g_source_new (&global_funcs, sizeof (GSource)); + g_assert_cmpint (g_source_get_priority (source), ==, G_PRIORITY_DEFAULT); + g_assert_false (g_source_is_destroyed (source)); + + g_assert_false (g_source_get_can_recurse (source)); + g_assert_null (g_source_get_name (source)); + + g_source_set_can_recurse (source, TRUE); + g_source_set_static_name (source, "d"); + + g_assert_true (g_source_get_can_recurse (source)); + g_assert_cmpstr (g_source_get_name (source), ==, "d"); + + g_source_set_static_name (source, "still d"); + g_assert_cmpstr (g_source_get_name (source), ==, "still d"); + + g_assert_null (g_main_context_find_source_by_user_data (ctx, NULL)); + g_assert_null (g_main_context_find_source_by_funcs_user_data (ctx, &global_funcs, NULL)); + + id = g_source_attach (source, ctx); + g_assert_cmpint (g_source_get_id (source), ==, id); + g_assert_true (g_main_context_find_source_by_id (ctx, id) == source); + + g_source_set_priority (source, G_PRIORITY_HIGH); + g_assert_cmpint (g_source_get_priority (source), ==, G_PRIORITY_HIGH); + + g_source_destroy (source); + g_assert_true (g_source_get_context (source) == ctx); + g_assert_null (g_main_context_find_source_by_id (ctx, id)); + + g_main_context_unref (ctx); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*source->context != NULL*failed*"); + g_assert_null (g_source_get_context (source)); + g_test_assert_expected_messages (); + } + + g_source_unref (source); + + ctx = g_main_context_default (); + source = g_source_new (&global_funcs, sizeof (GSource)); + g_source_set_funcs (source, &global_funcs); + g_source_set_callback (source, cb, data, NULL); + id = g_source_attach (source, ctx); + g_source_unref (source); + g_source_set_name_by_id (id, "e"); + g_assert_cmpstr (g_source_get_name (source), ==, "e"); + g_assert_true (g_source_get_context (source) == ctx); + g_assert_true (g_source_remove_by_funcs_user_data (&global_funcs, data)); + + source = g_source_new (&global_funcs, sizeof (GSource)); + g_source_set_funcs (source, &global_funcs); + g_source_set_callback (source, cb, data, NULL); + id = g_source_attach (source, ctx); + g_assert_cmpint (id, >, 0); + g_source_unref (source); + g_assert_true (g_source_remove_by_user_data (data)); + g_assert_false (g_source_remove_by_user_data ((gpointer)0x1234)); + + g_idle_add (cb, data); + g_assert_true (g_idle_remove_by_data (data)); +} + +static void +test_mainloop_basic (void) +{ + GMainLoop *loop; + GMainContext *ctx; + + loop = g_main_loop_new (NULL, FALSE); + + g_assert_false (g_main_loop_is_running (loop)); + + g_main_loop_ref (loop); + + ctx = g_main_loop_get_context (loop); + g_assert_true (ctx == g_main_context_default ()); + + g_main_loop_unref (loop); + + g_assert_cmpint (g_main_depth (), ==, 0); + + g_main_loop_unref (loop); +} + +static void +test_ownerless_polling (gconstpointer test_data) +{ + gboolean attach_first = GPOINTER_TO_INT (test_data); + GMainContext *ctx = g_main_context_new_with_flags ( + G_MAIN_CONTEXT_FLAGS_OWNERLESS_POLLING); + + GPollFD fds[20]; + gint fds_size; + gint max_priority; + GSource *source = NULL; + + g_assert_true (ctx != g_main_context_default ()); + + g_main_context_push_thread_default (ctx); + + /* Drain events */ + for (;;) + { + gboolean ready_to_dispatch = g_main_context_prepare (ctx, &max_priority); + gint timeout, nready; + fds_size = g_main_context_query (ctx, max_priority, &timeout, fds, G_N_ELEMENTS (fds)); + nready = g_poll (fds, fds_size, /*timeout=*/0); + if (!ready_to_dispatch && nready == 0) + { + if (timeout == -1) + break; + else + g_usleep (timeout * 1000); + } + ready_to_dispatch = g_main_context_check (ctx, max_priority, fds, fds_size); + if (ready_to_dispatch) + g_main_context_dispatch (ctx); + } + + if (!attach_first) + g_main_context_pop_thread_default (ctx); + + source = g_idle_source_new (); + g_source_attach (source, ctx); + g_source_unref (source); + + if (attach_first) + g_main_context_pop_thread_default (ctx); + + g_assert_cmpint (g_poll (fds, fds_size, 0), >, 0); + + g_main_context_unref (ctx); +} + +static gint global_a; +static gint global_b; +static gint global_c; + +static gboolean +count_calls (gpointer data) +{ + gint *i = data; + + (*i)++; + + return TRUE; +} + +static void +test_timeouts (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *source; + + if (!g_test_thorough ()) + { + g_test_skip ("Not running timing heavy test"); + return; + } + + global_a = global_b = global_c = 0; + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + source = g_timeout_source_new (100); + g_source_set_callback (source, count_calls, &global_a, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + source = g_timeout_source_new (250); + g_source_set_callback (source, count_calls, &global_b, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + source = g_timeout_source_new (330); + g_source_set_callback (source, count_calls, &global_c, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + source = g_timeout_source_new (1050); + g_source_set_callback (source, (GSourceFunc)g_main_loop_quit, loop, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + g_main_loop_run (loop); + + /* We may be delayed for an arbitrary amount of time - for example, + * it's possible for all timeouts to fire exactly once. + */ + g_assert_cmpint (global_a, >, 0); + g_assert_cmpint (global_a, >=, global_b); + g_assert_cmpint (global_b, >=, global_c); + + g_assert_cmpint (global_a, <=, 10); + g_assert_cmpint (global_b, <=, 4); + g_assert_cmpint (global_c, <=, 3); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +static void +test_priorities (void) +{ + GMainContext *ctx; + GSource *sourcea; + GSource *sourceb; + + global_a = global_b = global_c = 0; + + ctx = g_main_context_new (); + + sourcea = g_idle_source_new (); + g_source_set_callback (sourcea, count_calls, &global_a, NULL); + g_source_set_priority (sourcea, 1); + g_source_attach (sourcea, ctx); + g_source_unref (sourcea); + + sourceb = g_idle_source_new (); + g_source_set_callback (sourceb, count_calls, &global_b, NULL); + g_source_set_priority (sourceb, 0); + g_source_attach (sourceb, ctx); + g_source_unref (sourceb); + + g_assert_true (g_main_context_pending (ctx)); + g_assert_true (g_main_context_iteration (ctx, FALSE)); + g_assert_cmpint (global_a, ==, 0); + g_assert_cmpint (global_b, ==, 1); + + g_assert_true (g_main_context_iteration (ctx, FALSE)); + g_assert_cmpint (global_a, ==, 0); + g_assert_cmpint (global_b, ==, 2); + + g_source_destroy (sourceb); + + g_assert_true (g_main_context_iteration (ctx, FALSE)); + g_assert_cmpint (global_a, ==, 1); + g_assert_cmpint (global_b, ==, 2); + + g_assert_true (g_main_context_pending (ctx)); + g_source_destroy (sourcea); + g_assert_false (g_main_context_pending (ctx)); + + g_main_context_unref (ctx); +} + +static gboolean +quit_loop (gpointer data) +{ + GMainLoop *loop = data; + + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static gint count; + +static gboolean +func (gpointer data) +{ + if (data != NULL) + g_assert_true (data == g_thread_self ()); + + count++; + + return FALSE; +} + +static gboolean +call_func (gpointer data) +{ + func (g_thread_self ()); + + return G_SOURCE_REMOVE; +} + +static GMutex mutex; +static GCond cond; +static gboolean thread_ready; + +static gpointer +thread_func (gpointer data) +{ + GMainContext *ctx = data; + GMainLoop *loop; + GSource *source; + + g_main_context_push_thread_default (ctx); + loop = g_main_loop_new (ctx, FALSE); + + g_mutex_lock (&mutex); + thread_ready = TRUE; + g_cond_signal (&cond); + g_mutex_unlock (&mutex); + + source = g_timeout_source_new (500); + g_source_set_callback (source, quit_loop, loop, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + g_main_loop_run (loop); + + g_main_context_pop_thread_default (ctx); + g_main_loop_unref (loop); + + return NULL; +} + +static void +test_invoke (void) +{ + GMainContext *ctx; + GThread *thread; + + count = 0; + + /* this one gets invoked directly */ + g_main_context_invoke (NULL, func, g_thread_self ()); + g_assert_cmpint (count, ==, 1); + + /* invoking out of an idle works too */ + g_idle_add (call_func, NULL); + g_main_context_iteration (g_main_context_default (), FALSE); + g_assert_cmpint (count, ==, 2); + + /* test thread-default forcing the invocation to go + * to another thread + */ + ctx = g_main_context_new (); + thread = g_thread_new ("worker", thread_func, ctx); + + g_mutex_lock (&mutex); + while (!thread_ready) + g_cond_wait (&cond, &mutex); + g_mutex_unlock (&mutex); + + g_main_context_invoke (ctx, func, thread); + + g_thread_join (thread); + g_assert_cmpint (count, ==, 3); + + g_main_context_unref (ctx); +} + +/* We can't use timeout sources here because on slow or heavily-loaded + * machines, the test program might not get enough cycles to hit the + * timeouts at the expected times. So instead we define a source that + * is based on the number of GMainContext iterations. + */ + +static gint counter; +static gint64 last_counter_update; + +typedef struct { + GSource source; + gint interval; + gint timeout; +} CounterSource; + +static gboolean +counter_source_prepare (GSource *source, + gint *timeout) +{ + CounterSource *csource = (CounterSource *)source; + gint64 now; + + now = g_source_get_time (source); + if (now != last_counter_update) + { + last_counter_update = now; + counter++; + } + + *timeout = 1; + return counter >= csource->timeout; +} + +static gboolean +counter_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + CounterSource *csource = (CounterSource *) source; + gboolean again; + + again = callback (user_data); + + if (again) + csource->timeout = counter + csource->interval; + + return again; +} + +static GSourceFuncs counter_source_funcs = { + counter_source_prepare, + NULL, + counter_source_dispatch, + NULL, + NULL, + NULL +}; + +static GSource * +counter_source_new (gint interval) +{ + GSource *source = g_source_new (&counter_source_funcs, sizeof (CounterSource)); + CounterSource *csource = (CounterSource *) source; + + csource->interval = interval; + csource->timeout = counter + interval; + + return source; +} + + +static gboolean +run_inner_loop (gpointer user_data) +{ + GMainContext *ctx = user_data; + GMainLoop *inner; + GSource *timeout; + + global_a++; + + inner = g_main_loop_new (ctx, FALSE); + timeout = counter_source_new (100); + g_source_set_callback (timeout, quit_loop, inner, NULL); + g_source_attach (timeout, ctx); + g_source_unref (timeout); + + g_main_loop_run (inner); + g_main_loop_unref (inner); + + return G_SOURCE_CONTINUE; +} + +static void +test_child_sources (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *parent, *child_b, *child_c, *end; + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + global_a = global_b = global_c = 0; + + parent = counter_source_new (2000); + g_source_set_callback (parent, run_inner_loop, ctx, NULL); + g_source_set_priority (parent, G_PRIORITY_LOW); + g_source_attach (parent, ctx); + + child_b = counter_source_new (250); + g_source_set_callback (child_b, count_calls, &global_b, NULL); + g_source_add_child_source (parent, child_b); + + child_c = counter_source_new (330); + g_source_set_callback (child_c, count_calls, &global_c, NULL); + g_source_set_priority (child_c, G_PRIORITY_HIGH); + g_source_add_child_source (parent, child_c); + + /* Child sources always have the priority of the parent */ + g_assert_cmpint (g_source_get_priority (parent), ==, G_PRIORITY_LOW); + g_assert_cmpint (g_source_get_priority (child_b), ==, G_PRIORITY_LOW); + g_assert_cmpint (g_source_get_priority (child_c), ==, G_PRIORITY_LOW); + g_source_set_priority (parent, G_PRIORITY_DEFAULT); + g_assert_cmpint (g_source_get_priority (parent), ==, G_PRIORITY_DEFAULT); + g_assert_cmpint (g_source_get_priority (child_b), ==, G_PRIORITY_DEFAULT); + g_assert_cmpint (g_source_get_priority (child_c), ==, G_PRIORITY_DEFAULT); + + end = counter_source_new (1050); + g_source_set_callback (end, quit_loop, loop, NULL); + g_source_attach (end, ctx); + g_source_unref (end); + + g_main_loop_run (loop); + + /* The parent source's own timeout will never trigger, so "a" will + * only get incremented when "b" or "c" does. And when timeouts get + * blocked, they still wait the full interval next time rather than + * "catching up". So the timing is: + * + * 250 - b++ -> a++, run_inner_loop + * 330 - (c is blocked) + * 350 - inner_loop ends + * 350 - c++ belatedly -> a++, run_inner_loop + * 450 - inner loop ends + * 500 - b++ -> a++, run_inner_loop + * 600 - inner_loop ends + * 680 - c++ -> a++, run_inner_loop + * 750 - (b is blocked) + * 780 - inner loop ends + * 780 - b++ belatedly -> a++, run_inner_loop + * 880 - inner loop ends + * 1010 - c++ -> a++, run_inner_loop + * 1030 - (b is blocked) + * 1050 - end runs, quits outer loop, which has no effect yet + * 1110 - inner loop ends, a returns, outer loop exits + */ + + g_assert_cmpint (global_a, ==, 6); + g_assert_cmpint (global_b, ==, 3); + g_assert_cmpint (global_c, ==, 3); + + g_source_destroy (parent); + g_source_unref (parent); + g_source_unref (child_b); + g_source_unref (child_c); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +static void +test_recursive_child_sources (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *parent, *child_b, *child_c, *end; + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + global_a = global_b = global_c = 0; + + parent = counter_source_new (500); + g_source_set_callback (parent, count_calls, &global_a, NULL); + + child_b = counter_source_new (220); + g_source_set_callback (child_b, count_calls, &global_b, NULL); + g_source_add_child_source (parent, child_b); + + child_c = counter_source_new (430); + g_source_set_callback (child_c, count_calls, &global_c, NULL); + g_source_add_child_source (child_b, child_c); + + g_source_attach (parent, ctx); + + end = counter_source_new (2010); + g_source_set_callback (end, (GSourceFunc)g_main_loop_quit, loop, NULL); + g_source_attach (end, ctx); + g_source_unref (end); + + g_main_loop_run (loop); + + /* Sequence of events: + * 220 b (b -> 440, a -> 720) + * 430 c (c -> 860, b -> 650, a -> 930) + * 650 b (b -> 870, a -> 1150) + * 860 c (c -> 1290, b -> 1080, a -> 1360) + * 1080 b (b -> 1300, a -> 1580) + * 1290 c (c -> 1720, b -> 1510, a -> 1790) + * 1510 b (b -> 1730, a -> 2010) + * 1720 c (c -> 2150, b -> 1940, a -> 2220) + * 1940 b (b -> 2160, a -> 2440) + */ + + g_assert_cmpint (global_a, ==, 9); + g_assert_cmpint (global_b, ==, 9); + g_assert_cmpint (global_c, ==, 4); + + g_source_destroy (parent); + g_source_unref (parent); + g_source_unref (child_b); + g_source_unref (child_c); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +typedef struct { + GSource *parent, *old_child, *new_child; + GMainLoop *loop; +} SwappingTestData; + +static gboolean +swap_sources (gpointer user_data) +{ + SwappingTestData *data = user_data; + + if (data->old_child) + { + g_source_remove_child_source (data->parent, data->old_child); + g_clear_pointer (&data->old_child, g_source_unref); + } + + if (!data->new_child) + { + data->new_child = g_timeout_source_new (0); + g_source_set_callback (data->new_child, quit_loop, data->loop, NULL); + g_source_add_child_source (data->parent, data->new_child); + } + + return G_SOURCE_CONTINUE; +} + +static gboolean +assert_not_reached_callback (gpointer user_data) +{ + g_assert_not_reached (); + + return G_SOURCE_REMOVE; +} + +static void +test_swapping_child_sources (void) +{ + GMainContext *ctx; + GMainLoop *loop; + SwappingTestData data; + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + data.parent = counter_source_new (50); + data.loop = loop; + g_source_set_callback (data.parent, swap_sources, &data, NULL); + g_source_attach (data.parent, ctx); + + data.old_child = counter_source_new (100); + g_source_add_child_source (data.parent, data.old_child); + g_source_set_callback (data.old_child, assert_not_reached_callback, NULL, NULL); + + data.new_child = NULL; + g_main_loop_run (loop); + + g_source_destroy (data.parent); + g_source_unref (data.parent); + g_source_unref (data.new_child); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +static gboolean +add_source_callback (gpointer user_data) +{ + GMainLoop *loop = user_data; + GSource *self = g_main_current_source (), *child; + GIOChannel *io; + + /* It doesn't matter whether this is a valid fd or not; it never + * actually gets polled; the test is just checking that + * g_source_add_child_source() doesn't crash. + */ + io = g_io_channel_unix_new (0); + child = g_io_create_watch (io, G_IO_IN); + g_source_add_child_source (self, child); + g_source_unref (child); + g_io_channel_unref (io); + + g_main_loop_quit (loop); + return FALSE; +} + +static void +test_blocked_child_sources (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *source; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=701283"); + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + source = g_idle_source_new (); + g_source_set_callback (source, add_source_callback, loop, NULL); + g_source_attach (source, ctx); + + g_main_loop_run (loop); + + g_source_destroy (source); + g_source_unref (source); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +typedef struct { + GMainContext *ctx; + GMainLoop *loop; + + GSource *timeout1, *timeout2; + gint64 time1; +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + GTimeVal tv; /* needed for g_source_get_current_time() */ +G_GNUC_END_IGNORE_DEPRECATIONS +} TimeTestData; + +static gboolean +timeout1_callback (gpointer user_data) +{ + TimeTestData *data = user_data; + GSource *source; + gint64 mtime1, mtime2, time2; + + source = g_main_current_source (); + g_assert_true (source == data->timeout1); + + if (data->time1 == -1) + { + /* First iteration */ + g_assert_false (g_source_is_destroyed (data->timeout2)); + + mtime1 = g_get_monotonic_time (); + data->time1 = g_source_get_time (source); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_source_get_current_time (source, &data->tv); +G_GNUC_END_IGNORE_DEPRECATIONS + + /* g_source_get_time() does not change during a single callback */ + g_usleep (1000000); + mtime2 = g_get_monotonic_time (); + time2 = g_source_get_time (source); + + g_assert_cmpint (mtime1, <, mtime2); + g_assert_cmpint (data->time1, ==, time2); + } + else + { +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + GTimeVal tv; +G_GNUC_END_IGNORE_DEPRECATIONS + + /* Second iteration */ + g_assert_true (g_source_is_destroyed (data->timeout2)); + + /* g_source_get_time() MAY change between iterations; in this + * case we know for sure that it did because of the g_usleep() + * last time. + */ + time2 = g_source_get_time (source); + g_assert_cmpint (data->time1, <, time2); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_source_get_current_time (source, &tv); +G_GNUC_END_IGNORE_DEPRECATIONS + + g_assert_true (tv.tv_sec > data->tv.tv_sec || + (tv.tv_sec == data->tv.tv_sec && + tv.tv_usec > data->tv.tv_usec)); + + g_main_loop_quit (data->loop); + } + + return TRUE; +} + +static gboolean +timeout2_callback (gpointer user_data) +{ + TimeTestData *data = user_data; + GSource *source; + gint64 time2, time3; + + source = g_main_current_source (); + g_assert_true (source == data->timeout2); + + g_assert_false (g_source_is_destroyed (data->timeout1)); + + /* g_source_get_time() does not change between different sources in + * a single iteration of the mainloop. + */ + time2 = g_source_get_time (source); + g_assert_cmpint (data->time1, ==, time2); + + /* The source should still have a valid time even after being + * destroyed, since it's currently running. + */ + g_source_destroy (source); + time3 = g_source_get_time (source); + g_assert_cmpint (time2, ==, time3); + + return FALSE; +} + +static void +test_source_time (void) +{ + TimeTestData data; + + data.ctx = g_main_context_new (); + data.loop = g_main_loop_new (data.ctx, FALSE); + + data.timeout1 = g_timeout_source_new (0); + g_source_set_callback (data.timeout1, timeout1_callback, &data, NULL); + g_source_attach (data.timeout1, data.ctx); + + data.timeout2 = g_timeout_source_new (0); + g_source_set_callback (data.timeout2, timeout2_callback, &data, NULL); + g_source_attach (data.timeout2, data.ctx); + + data.time1 = -1; + + g_main_loop_run (data.loop); + + g_assert_false (g_source_is_destroyed (data.timeout1)); + g_assert_true (g_source_is_destroyed (data.timeout2)); + + g_source_destroy (data.timeout1); + g_source_unref (data.timeout1); + g_source_unref (data.timeout2); + + g_main_loop_unref (data.loop); + g_main_context_unref (data.ctx); +} + +typedef struct { + guint outstanding_ops; + GMainLoop *loop; +} TestOverflowData; + +static gboolean +on_source_fired_cb (gpointer user_data) +{ + TestOverflowData *data = user_data; + GSource *current_source; + GMainContext *current_context; + guint source_id; + + data->outstanding_ops--; + + current_source = g_main_current_source (); + current_context = g_source_get_context (current_source); + source_id = g_source_get_id (current_source); + g_assert_nonnull (g_main_context_find_source_by_id (current_context, source_id)); + g_source_destroy (current_source); + g_assert_null (g_main_context_find_source_by_id (current_context, source_id)); + + if (data->outstanding_ops == 0) + g_main_loop_quit (data->loop); + return FALSE; +} + +static GSource * +add_idle_source (GMainContext *ctx, + TestOverflowData *data) +{ + GSource *source; + + source = g_idle_source_new (); + g_source_set_callback (source, on_source_fired_cb, data, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + data->outstanding_ops++; + + return source; +} + +static void +test_mainloop_overflow (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *source; + TestOverflowData data; + guint i; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=687098"); + + memset (&data, 0, sizeof (data)); + + ctx = GLIB_PRIVATE_CALL (g_main_context_new_with_next_id) (G_MAXUINT-1); + + loop = g_main_loop_new (ctx, TRUE); + data.outstanding_ops = 0; + data.loop = loop; + + source = add_idle_source (ctx, &data); + g_assert_cmpint (source->source_id, ==, G_MAXUINT-1); + + source = add_idle_source (ctx, &data); + g_assert_cmpint (source->source_id, ==, G_MAXUINT); + + source = add_idle_source (ctx, &data); + g_assert_cmpint (source->source_id, !=, 0); + + /* Now, a lot more sources */ + for (i = 0; i < 50; i++) + { + source = add_idle_source (ctx, &data); + g_assert_cmpint (source->source_id, !=, 0); + } + + g_main_loop_run (loop); + g_assert_cmpint (data.outstanding_ops, ==, 0); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +static gint ready_time_dispatched; /* (atomic) */ + +static gboolean +ready_time_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + g_atomic_int_set (&ready_time_dispatched, TRUE); + + g_source_set_ready_time (source, -1); + + return TRUE; +} + +static gpointer +run_context (gpointer user_data) +{ + g_main_loop_run (user_data); + + return NULL; +} + +static void +test_ready_time (void) +{ + GThread *thread; + GSource *source; + GSourceFuncs source_funcs = { + NULL, NULL, ready_time_dispatch, NULL, NULL, NULL + }; + GMainLoop *loop; + + source = g_source_new (&source_funcs, sizeof (GSource)); + g_source_attach (source, NULL); + g_source_unref (source); + + /* Unfortunately we can't do too many things with respect to timing + * without getting into trouble on slow systems or heavily loaded + * builders. + * + * We can test that the basics are working, though. + */ + + /* A source with no ready time set should not fire */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_false (g_atomic_int_get (&ready_time_dispatched)); + + /* The ready time should not have been changed */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* Of course this shouldn't change anything either */ + g_source_set_ready_time (source, -1); + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* A source with a ready time set to tomorrow should not fire on any + * builder, no matter how badly loaded... + */ + g_source_set_ready_time (source, g_get_monotonic_time () + G_TIME_SPAN_DAY); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_false (g_atomic_int_get (&ready_time_dispatched)); + /* Make sure it didn't get reset */ + g_assert_cmpint (g_source_get_ready_time (source), !=, -1); + + /* Ready time of -1 -> don't fire */ + g_source_set_ready_time (source, -1); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_false (g_atomic_int_get (&ready_time_dispatched)); + /* Not reset, but should still be -1 from above */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* A ready time of the current time should fire immediately */ + g_source_set_ready_time (source, g_get_monotonic_time ()); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_true (g_atomic_int_get (&ready_time_dispatched)); + g_atomic_int_set (&ready_time_dispatched, FALSE); + /* Should have gotten reset by the handler function */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* As well as one in the recent past... */ + g_source_set_ready_time (source, g_get_monotonic_time () - G_TIME_SPAN_SECOND); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_true (g_atomic_int_get (&ready_time_dispatched)); + g_atomic_int_set (&ready_time_dispatched, FALSE); + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* Zero is the 'official' way to get a source to fire immediately */ + g_source_set_ready_time (source, 0); + while (g_main_context_iteration (NULL, FALSE)); + g_assert_true (g_atomic_int_get (&ready_time_dispatched)); + g_atomic_int_set (&ready_time_dispatched, FALSE); + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* Now do some tests of cross-thread wakeups. + * + * Make sure it wakes up right away from the start. + */ + g_source_set_ready_time (source, 0); + loop = g_main_loop_new (NULL, FALSE); + thread = g_thread_new ("context thread", run_context, loop); + while (!g_atomic_int_get (&ready_time_dispatched)); + + /* Now let's see if it can wake up from sleeping. */ + g_usleep (G_TIME_SPAN_SECOND / 2); + g_atomic_int_set (&ready_time_dispatched, FALSE); + g_source_set_ready_time (source, 0); + while (!g_atomic_int_get (&ready_time_dispatched)); + + /* kill the thread */ + g_main_loop_quit (loop); + g_thread_join (thread); + g_main_loop_unref (loop); + + g_source_destroy (source); +} + +static void +test_wakeup(void) +{ + GMainContext *ctx; + int i; + + ctx = g_main_context_new (); + + /* run a random large enough number of times because + * main contexts tend to wake up a few times after creation. + */ + for (i = 0; i < 100; i++) + { + /* This is the invariant we care about: + * g_main_context_wakeup(ctx,) ensures that the next call to + * g_main_context_iteration (ctx, TRUE) returns and doesn't + * block. + * This is important in threaded apps where we might not know + * if the thread calls g_main_context_wakeup() before or after + * we enter g_main_context_iteration(). + */ + g_main_context_wakeup (ctx); + g_main_context_iteration (ctx, TRUE); + } + + g_main_context_unref (ctx); +} + +static void +test_remove_invalid (void) +{ + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "Source ID 3000000000 was not found*"); + g_source_remove (3000000000u); + g_test_assert_expected_messages (); +} + +static gboolean +trivial_prepare (GSource *source, + gint *timeout) +{ + *timeout = 0; + return TRUE; +} + +static gint n_finalized; + +static void +trivial_finalize (GSource *source) +{ + n_finalized++; +} + +static void +test_unref_while_pending (void) +{ + static GSourceFuncs funcs = { + trivial_prepare, NULL, NULL, trivial_finalize, NULL, NULL + }; + GMainContext *context; + GSource *source; + + context = g_main_context_new (); + + source = g_source_new (&funcs, sizeof (GSource)); + g_source_attach (source, context); + g_source_unref (source); + + /* Do incomplete main iteration -- get a pending source but don't dispatch it. */ + g_main_context_prepare (context, NULL); + g_main_context_query (context, 0, NULL, NULL, 0); + g_main_context_check (context, 1000, NULL, 0); + + /* Destroy the context */ + g_main_context_unref (context); + + /* Make sure we didn't leak the source */ + g_assert_cmpint (n_finalized, ==, 1); +} + +#ifdef G_OS_UNIX + +#include +#include + +static gchar zeros[1024]; + +static gsize +fill_a_pipe (gint fd) +{ + gsize written = 0; + GPollFD pfd; + + pfd.fd = fd; + pfd.events = G_IO_OUT; + while (g_poll (&pfd, 1, 0) == 1) + /* we should never see -1 here */ + written += write (fd, zeros, sizeof zeros); + + return written; +} + +static gboolean +write_bytes (gint fd, + GIOCondition condition, + gpointer user_data) +{ + gssize *to_write = user_data; + gint limit; + + if (*to_write == 0) + return FALSE; + + /* Detect if we run before we should */ + g_assert_cmpint (*to_write, >=, 0); + + limit = MIN ((gsize) *to_write, sizeof zeros); + *to_write -= write (fd, zeros, limit); + + return TRUE; +} + +static gboolean +read_bytes (gint fd, + GIOCondition condition, + gpointer user_data) +{ + static gchar buffer[1024]; + gssize *to_read = user_data; + + *to_read -= read (fd, buffer, sizeof buffer); + + /* The loop will exit when there is nothing else to read, then we will + * use g_source_remove() to destroy this source. + */ + return TRUE; +} + +#ifdef G_OS_UNIX +static void +test_unix_fd (void) +{ + gssize to_write = -1; + gssize to_read; + gint fds[2]; + gint a, b; + gint s; + GSource *source_a; + GSource *source_b; + + s = pipe (fds); + g_assert_cmpint (s, ==, 0); + + to_read = fill_a_pipe (fds[1]); + /* write at higher priority to keep the pipe full... */ + a = g_unix_fd_add_full (G_PRIORITY_HIGH, fds[1], G_IO_OUT, write_bytes, &to_write, NULL); + source_a = g_source_ref (g_main_context_find_source_by_id (NULL, a)); + /* make sure no 'writes' get dispatched yet */ + while (g_main_context_iteration (NULL, FALSE)); + + to_read += 128 * 1024 * 1024; + to_write = 128 * 1024 * 1024; + b = g_unix_fd_add (fds[0], G_IO_IN, read_bytes, &to_read); + source_b = g_source_ref (g_main_context_find_source_by_id (NULL, b)); + + /* Assuming the kernel isn't internally 'laggy' then there will always + * be either data to read or room in which to write. That will keep + * the loop running until all data has been read and written. + */ + while (TRUE) + { + gssize to_write_was = to_write; + gssize to_read_was = to_read; + + if (!g_main_context_iteration (NULL, FALSE)) + break; + + /* Since the sources are at different priority, only one of them + * should possibly have run. + */ + g_assert_true (to_write == to_write_was || to_read == to_read_was); + } + + g_assert_cmpint (to_write, ==, 0); + g_assert_cmpint (to_read, ==, 0); + + /* 'a' is already removed by itself */ + g_assert_true (g_source_is_destroyed (source_a)); + g_source_unref (source_a); + g_source_remove (b); + g_assert_true (g_source_is_destroyed (source_b)); + g_source_unref (source_b); + close (fds[1]); + close (fds[0]); +} +#endif + +static void +assert_main_context_state (gint n_to_poll, + ...) +{ + GMainContext *context; + gboolean consumed[10] = { }; + GPollFD poll_fds[10]; + gboolean acquired; + gboolean immediate; + gint max_priority; + gint timeout; + gint n; + gint i, j; + va_list ap; + + context = g_main_context_default (); + + acquired = g_main_context_acquire (context); + g_assert_true (acquired); + + immediate = g_main_context_prepare (context, &max_priority); + g_assert_false (immediate); + n = g_main_context_query (context, max_priority, &timeout, poll_fds, 10); + g_assert_cmpint (n, ==, n_to_poll + 1); /* one will be the gwakeup */ + + va_start (ap, n_to_poll); + for (i = 0; i < n_to_poll; i++) + { + gint expected_fd = va_arg (ap, gint); + GIOCondition expected_events = va_arg (ap, GIOCondition); + GIOCondition report_events = va_arg (ap, GIOCondition); + + for (j = 0; j < n; j++) + if (!consumed[j] && poll_fds[j].fd == expected_fd && poll_fds[j].events == expected_events) + { + poll_fds[j].revents = report_events; + consumed[j] = TRUE; + break; + } + + if (j == n) + g_error ("Unable to find fd %d (index %d) with events 0x%x", expected_fd, i, (guint) expected_events); + } + va_end (ap); + + /* find the gwakeup, flag as non-ready */ + for (i = 0; i < n; i++) + if (!consumed[i]) + poll_fds[i].revents = 0; + + if (g_main_context_check (context, max_priority, poll_fds, n)) + g_main_context_dispatch (context); + + g_main_context_release (context); +} + +static gboolean +flag_bool (gint fd, + GIOCondition condition, + gpointer user_data) +{ + gboolean *flag = user_data; + + *flag = TRUE; + + return TRUE; +} + +static void +test_unix_fd_source (void) +{ + GSource *out_source; + GSource *in_source; + GSource *source; + gboolean out, in; + gint fds[2]; + gint s; + + assert_main_context_state (0); + + s = pipe (fds); + g_assert_cmpint (s, ==, 0); + + source = g_unix_fd_source_new (fds[1], G_IO_OUT); + g_source_attach (source, NULL); + + /* Check that a source with no callback gets successfully detached + * with a warning printed. + */ + g_test_expect_message ("GLib", G_LOG_LEVEL_WARNING, "*GUnixFDSource dispatched without callback*"); + while (g_main_context_iteration (NULL, FALSE)); + g_test_assert_expected_messages (); + g_assert_true (g_source_is_destroyed (source)); + g_source_unref (source); + + out = in = FALSE; + out_source = g_unix_fd_source_new (fds[1], G_IO_OUT); + /* -Wcast-function-type complains about casting 'flag_bool' to GSourceFunc. + * GCC has no way of knowing that it will be cast back to GUnixFDSourceFunc + * before being called. Although GLib itself is not compiled with + * -Wcast-function-type, applications that use GLib may well be (since + * -Wextra includes it), so we provide a G_SOURCE_FUNC() macro to suppress + * the warning. We check that it works here. + */ +#if G_GNUC_CHECK_VERSION(8, 0) +#pragma GCC diagnostic push +#pragma GCC diagnostic error "-Wcast-function-type" +#endif + g_source_set_callback (out_source, G_SOURCE_FUNC (flag_bool), &out, NULL); +#if G_GNUC_CHECK_VERSION(8, 0) +#pragma GCC diagnostic pop +#endif + g_source_attach (out_source, NULL); + assert_main_context_state (1, + fds[1], G_IO_OUT, 0); + g_assert_true (!in && !out); + + in_source = g_unix_fd_source_new (fds[0], G_IO_IN); + g_source_set_callback (in_source, (GSourceFunc) flag_bool, &in, NULL); + g_source_set_priority (in_source, G_PRIORITY_DEFAULT_IDLE); + g_source_attach (in_source, NULL); + assert_main_context_state (2, + fds[0], G_IO_IN, G_IO_IN, + fds[1], G_IO_OUT, G_IO_OUT); + /* out is higher priority so only it should fire */ + g_assert_true (!in && out); + + /* raise the priority of the in source to higher than out*/ + in = out = FALSE; + g_source_set_priority (in_source, G_PRIORITY_HIGH); + assert_main_context_state (2, + fds[0], G_IO_IN, G_IO_IN, + fds[1], G_IO_OUT, G_IO_OUT); + g_assert_true (in && !out); + + /* now, let them be equal */ + in = out = FALSE; + g_source_set_priority (in_source, G_PRIORITY_DEFAULT); + assert_main_context_state (2, + fds[0], G_IO_IN, G_IO_IN, + fds[1], G_IO_OUT, G_IO_OUT); + g_assert_true (in && out); + + g_source_destroy (out_source); + g_source_unref (out_source); + g_source_destroy (in_source); + g_source_unref (in_source); + close (fds[1]); + close (fds[0]); +} + +typedef struct +{ + GSource parent; + gboolean flagged; +} FlagSource; + +static gboolean +return_true (GSource *source, GSourceFunc callback, gpointer user_data) +{ + FlagSource *flag_source = (FlagSource *) source; + + flag_source->flagged = TRUE; + + return TRUE; +} + +#define assert_flagged(s) g_assert_true (((FlagSource *) (s))->flagged); +#define assert_not_flagged(s) g_assert_true (!((FlagSource *) (s))->flagged); +#define clear_flag(s) ((FlagSource *) (s))->flagged = 0 + +static void +test_source_unix_fd_api (void) +{ + GSourceFuncs no_funcs = { + NULL, NULL, return_true, NULL, NULL, NULL + }; + GSource *source_a; + GSource *source_b; + gpointer tag1, tag2; + gint fds_a[2]; + gint fds_b[2]; + + pipe (fds_a); + pipe (fds_b); + + source_a = g_source_new (&no_funcs, sizeof (FlagSource)); + source_b = g_source_new (&no_funcs, sizeof (FlagSource)); + + /* attach a source with more than one fd */ + g_source_add_unix_fd (source_a, fds_a[0], G_IO_IN); + g_source_add_unix_fd (source_a, fds_a[1], G_IO_OUT); + g_source_attach (source_a, NULL); + assert_main_context_state (2, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, 0); + assert_not_flagged (source_a); + + /* attach a higher priority source with no fds */ + g_source_set_priority (source_b, G_PRIORITY_HIGH); + g_source_attach (source_b, NULL); + assert_main_context_state (2, + fds_a[0], G_IO_IN, G_IO_IN, + fds_a[1], G_IO_OUT, 0); + assert_flagged (source_a); + assert_not_flagged (source_b); + clear_flag (source_a); + + /* add some fds to the second source, while attached */ + tag1 = g_source_add_unix_fd (source_b, fds_b[0], G_IO_IN); + tag2 = g_source_add_unix_fd (source_b, fds_b[1], G_IO_OUT); + assert_main_context_state (4, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, G_IO_OUT, + fds_b[0], G_IO_IN, 0, + fds_b[1], G_IO_OUT, G_IO_OUT); + /* only 'b' (higher priority) should have dispatched */ + assert_not_flagged (source_a); + assert_flagged (source_b); + clear_flag (source_b); + + /* change our events on b to the same as they were before */ + g_source_modify_unix_fd (source_b, tag1, G_IO_IN); + g_source_modify_unix_fd (source_b, tag2, G_IO_OUT); + assert_main_context_state (4, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, G_IO_OUT, + fds_b[0], G_IO_IN, 0, + fds_b[1], G_IO_OUT, G_IO_OUT); + assert_not_flagged (source_a); + assert_flagged (source_b); + clear_flag (source_b); + + /* now reverse them */ + g_source_modify_unix_fd (source_b, tag1, G_IO_OUT); + g_source_modify_unix_fd (source_b, tag2, G_IO_IN); + assert_main_context_state (4, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, G_IO_OUT, + fds_b[0], G_IO_OUT, 0, + fds_b[1], G_IO_IN, 0); + /* 'b' had no events, so 'a' can go this time */ + assert_flagged (source_a); + assert_not_flagged (source_b); + clear_flag (source_a); + + /* remove one of the fds from 'b' */ + g_source_remove_unix_fd (source_b, tag1); + assert_main_context_state (3, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, 0, + fds_b[1], G_IO_IN, 0); + assert_not_flagged (source_a); + assert_not_flagged (source_b); + + /* remove the other */ + g_source_remove_unix_fd (source_b, tag2); + assert_main_context_state (2, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, 0); + assert_not_flagged (source_a); + assert_not_flagged (source_b); + + /* destroy the sources */ + g_source_destroy (source_a); + g_source_destroy (source_b); + assert_main_context_state (0); + + g_source_unref (source_a); + g_source_unref (source_b); + close (fds_a[0]); + close (fds_a[1]); + close (fds_b[0]); + close (fds_b[1]); +} + +static gboolean +unixfd_quit_loop (gint fd, + GIOCondition condition, + gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_main_loop_quit (loop); + + return FALSE; +} + +static void +test_unix_file_poll (void) +{ + gint fd; + GSource *source; + GMainLoop *loop; + + fd = open ("/dev/null", O_RDONLY); + g_assert_cmpint (fd, >=, 0); + + loop = g_main_loop_new (NULL, FALSE); + + source = g_unix_fd_source_new (fd, G_IO_IN); + g_source_set_callback (source, (GSourceFunc) unixfd_quit_loop, loop, NULL); + g_source_attach (source, NULL); + + /* Should not block */ + g_main_loop_run (loop); + + g_source_destroy (source); + + assert_main_context_state (0); + + g_source_unref (source); + + g_main_loop_unref (loop); + + close (fd); +} + +static void +test_unix_fd_priority (void) +{ + gint fd1, fd2; + GMainLoop *loop; + GSource *source; + + gint s1 = 0; + gboolean s2 = FALSE, s3 = FALSE; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1592"); + + loop = g_main_loop_new (NULL, FALSE); + + source = g_idle_source_new (); + g_source_set_callback (source, count_calls, &s1, NULL); + g_source_set_priority (source, 0); + g_source_attach (source, NULL); + g_source_unref (source); + + fd1 = open ("/dev/random", O_RDONLY); + g_assert_cmpint (fd1, >=, 0); + source = g_unix_fd_source_new (fd1, G_IO_IN); + g_source_set_callback (source, G_SOURCE_FUNC (flag_bool), &s2, NULL); + g_source_set_priority (source, 10); + g_source_attach (source, NULL); + g_source_unref (source); + + fd2 = open ("/dev/random", O_RDONLY); + g_assert_cmpint (fd2, >=, 0); + source = g_unix_fd_source_new (fd2, G_IO_IN); + g_source_set_callback (source, G_SOURCE_FUNC (flag_bool), &s3, NULL); + g_source_set_priority (source, 0); + g_source_attach (source, NULL); + g_source_unref (source); + + /* This tests a bug that depends on the source with the lowest FD + identifier to have the lowest priority. Make sure that this is + the case. */ + g_assert_cmpint (fd1, <, fd2); + + g_assert_true (g_main_context_iteration (NULL, FALSE)); + + /* Idle source should have been dispatched. */ + g_assert_cmpint (s1, ==, 1); + /* Low priority FD source shouldn't have been dispatched. */ + g_assert_false (s2); + /* Default priority FD source should have been dispatched. */ + g_assert_true (s3); + + g_main_loop_unref (loop); + + close (fd1); + close (fd2); +} + +#endif + +#ifdef G_OS_UNIX +static gboolean +timeout_cb (gpointer data) +{ + GMainLoop *loop = data; + GMainContext *context; + + context = g_main_loop_get_context (loop); + g_assert_true (g_main_loop_is_running (loop)); + g_assert_true (g_main_context_is_owner (context)); + + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static gpointer +threadf (gpointer data) +{ + GMainContext *context = data; + GMainLoop *loop; + GSource *source; + + loop = g_main_loop_new (context, FALSE); + source = g_timeout_source_new (250); + g_source_set_callback (source, timeout_cb, loop, NULL); + g_source_attach (source, context); + + g_main_loop_run (loop); + + g_source_destroy (source); + g_source_unref (source); + g_main_loop_unref (loop); + + return NULL; +} + +static void +test_mainloop_wait (void) +{ +#ifdef _GLIB_ADDRESS_SANITIZER + (void) threadf; + g_test_incomplete ("FIXME: Leaks a GMainLoop, see glib#2307"); +#else + GMainContext *context; + GThread *t1, *t2; + + context = g_main_context_new (); + + t1 = g_thread_new ("t1", threadf, context); + t2 = g_thread_new ("t2", threadf, context); + + g_thread_join (t1); + g_thread_join (t2); + + g_main_context_unref (context); +#endif +} +#endif + +static gboolean +nfds_in_cb (GIOChannel *io, + GIOCondition condition, + gpointer user_data) +{ + gboolean *in_cb_ran = user_data; + + *in_cb_ran = TRUE; + g_assert_cmpint (condition, ==, G_IO_IN); + return FALSE; +} + +static gboolean +nfds_out_cb (GIOChannel *io, + GIOCondition condition, + gpointer user_data) +{ + gboolean *out_cb_ran = user_data; + + *out_cb_ran = TRUE; + g_assert_cmpint (condition, ==, G_IO_OUT); + return FALSE; +} + +static gboolean +nfds_out_low_cb (GIOChannel *io, + GIOCondition condition, + gpointer user_data) +{ + g_assert_not_reached (); + return FALSE; +} + +static void +test_nfds (void) +{ + GMainContext *ctx; + GPollFD out_fds[3]; + gint fd, nfds; + GIOChannel *io; + GSource *source1, *source2, *source3; + gboolean source1_ran = FALSE, source3_ran = FALSE; + gchar *tmpfile; + GError *error = NULL; + + ctx = g_main_context_new (); + nfds = g_main_context_query (ctx, G_MAXINT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + /* An "empty" GMainContext will have a single GPollFD, for its + * internal GWakeup. + */ + g_assert_cmpint (nfds, ==, 1); + + fd = g_file_open_tmp (NULL, &tmpfile, &error); + g_assert_no_error (error); + + io = g_io_channel_unix_new (fd); +#ifdef G_OS_WIN32 + /* The fd in the pollfds won't be the same fd we passed in */ + g_io_channel_win32_make_pollfd (io, G_IO_IN, out_fds); + fd = out_fds[0].fd; +#endif + + /* Add our first pollfd */ + source1 = g_io_create_watch (io, G_IO_IN); + g_source_set_priority (source1, G_PRIORITY_DEFAULT); + g_source_set_callback (source1, (GSourceFunc) nfds_in_cb, + &source1_ran, NULL); + g_source_attach (source1, ctx); + + nfds = g_main_context_query (ctx, G_MAXINT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + g_assert_cmpint (nfds, ==, 2); + if (out_fds[0].fd == fd) + g_assert_cmpint (out_fds[0].events, ==, G_IO_IN); + else if (out_fds[1].fd == fd) + g_assert_cmpint (out_fds[1].events, ==, G_IO_IN); + else + g_assert_not_reached (); + + /* Add a second pollfd with the same fd but different event, and + * lower priority. + */ + source2 = g_io_create_watch (io, G_IO_OUT); + g_source_set_priority (source2, G_PRIORITY_LOW); + g_source_set_callback (source2, (GSourceFunc) nfds_out_low_cb, + NULL, NULL); + g_source_attach (source2, ctx); + + /* g_main_context_query() should still return only 2 pollfds, + * one of which has our fd, and a combined events field. + */ + nfds = g_main_context_query (ctx, G_MAXINT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + g_assert_cmpint (nfds, ==, 2); + if (out_fds[0].fd == fd) + g_assert_cmpint (out_fds[0].events, ==, G_IO_IN | G_IO_OUT); + else if (out_fds[1].fd == fd) + g_assert_cmpint (out_fds[1].events, ==, G_IO_IN | G_IO_OUT); + else + g_assert_not_reached (); + + /* But if we query with a max priority, we won't see the + * lower-priority one. + */ + nfds = g_main_context_query (ctx, G_PRIORITY_DEFAULT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + g_assert_cmpint (nfds, ==, 2); + if (out_fds[0].fd == fd) + g_assert_cmpint (out_fds[0].events, ==, G_IO_IN); + else if (out_fds[1].fd == fd) + g_assert_cmpint (out_fds[1].events, ==, G_IO_IN); + else + g_assert_not_reached (); + + /* Third pollfd */ + source3 = g_io_create_watch (io, G_IO_OUT); + g_source_set_priority (source3, G_PRIORITY_DEFAULT); + g_source_set_callback (source3, (GSourceFunc) nfds_out_cb, + &source3_ran, NULL); + g_source_attach (source3, ctx); + + nfds = g_main_context_query (ctx, G_MAXINT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + g_assert_cmpint (nfds, ==, 2); + if (out_fds[0].fd == fd) + g_assert_cmpint (out_fds[0].events, ==, G_IO_IN | G_IO_OUT); + else if (out_fds[1].fd == fd) + g_assert_cmpint (out_fds[1].events, ==, G_IO_IN | G_IO_OUT); + else + g_assert_not_reached (); + + /* Now actually iterate the loop; the fd should be readable and + * writable, so source1 and source3 should be triggered, but *not* + * source2, since it's lower priority than them. + */ + g_main_context_iteration (ctx, FALSE); + + /* FIXME: + * On win32, giowin32.c uses blocking threads for read/write on channels. They + * may not have yet triggered an event after one loop iteration. Hence, the + * following asserts are racy and disabled. + */ +#ifndef G_OS_WIN32 + g_assert_true (source1_ran); + g_assert_true (source3_ran); +#endif + + g_source_destroy (source1); + g_source_unref (source1); + g_source_destroy (source2); + g_source_unref (source2); + g_source_destroy (source3); + g_source_unref (source3); + + g_io_channel_unref (io); + remove (tmpfile); + g_free (tmpfile); + + g_main_context_unref (ctx); +} + +static gboolean +nsources_cb (gpointer user_data) +{ + g_assert_not_reached (); + return FALSE; +} + +static void +shuffle_nsources (GSource **sources, int num) +{ + int i, a, b; + GSource *tmp; + + for (i = 0; i < num * 10; i++) + { + a = g_random_int_range (0, num); + b = g_random_int_range (0, num); + tmp = sources[a]; + sources[a] = sources[b]; + sources[b] = tmp; + } +} + +static void +test_nsources_same_priority (void) +{ + GMainContext *context; + GSource **sources; + gint64 start, end; + gsize n_sources = 50000, i; + + context = g_main_context_default (); + sources = g_new0 (GSource *, n_sources); + + start = g_get_monotonic_time (); + for (i = 0; i < n_sources; i++) + { + sources[i] = g_idle_source_new (); + g_source_set_callback (sources[i], nsources_cb, NULL, NULL); + g_source_attach (sources[i], context); + } + end = g_get_monotonic_time (); + g_test_message ("Add same-priority sources: %" G_GINT64_FORMAT, + (end - start) / 1000); + + start = g_get_monotonic_time (); + for (i = 0; i < n_sources; i++) + g_assert_true (sources[i] == g_main_context_find_source_by_id (context, g_source_get_id (sources[i]))); + end = g_get_monotonic_time (); + g_test_message ("Find each source: %" G_GINT64_FORMAT, + (end - start) / 1000); + + shuffle_nsources (sources, n_sources); + + start = g_get_monotonic_time (); + for (i = 0; i < n_sources; i++) + { + g_source_destroy (sources[i]); + g_source_unref (sources[i]); + } + end = g_get_monotonic_time (); + g_test_message ("Remove in random order: %" G_GINT64_FORMAT, + (end - start) / 1000); + + /* Make sure they really did get removed */ + g_main_context_iteration (context, FALSE); + + g_free (sources); +} + +static void +test_nsources_different_priority (void) +{ + GMainContext *context; + GSource **sources; + gint64 start, end; + gsize n_sources = 50000, i; + + context = g_main_context_default (); + sources = g_new0 (GSource *, n_sources); + + start = g_get_monotonic_time (); + for (i = 0; i < n_sources; i++) + { + sources[i] = g_idle_source_new (); + g_source_set_callback (sources[i], nsources_cb, NULL, NULL); + g_source_set_priority (sources[i], i % 100); + g_source_attach (sources[i], context); + } + end = g_get_monotonic_time (); + g_test_message ("Add different-priority sources: %" G_GINT64_FORMAT, + (end - start) / 1000); + + start = g_get_monotonic_time (); + for (i = 0; i < n_sources; i++) + g_assert_true (sources[i] == g_main_context_find_source_by_id (context, g_source_get_id (sources[i]))); + end = g_get_monotonic_time (); + g_test_message ("Find each source: %" G_GINT64_FORMAT, + (end - start) / 1000); + + shuffle_nsources (sources, n_sources); + + start = g_get_monotonic_time (); + for (i = 0; i < n_sources; i++) + { + g_source_destroy (sources[i]); + g_source_unref (sources[i]); + } + end = g_get_monotonic_time (); + g_test_message ("Remove in random order: %" G_GINT64_FORMAT, + (end - start) / 1000); + + /* Make sure they really did get removed */ + g_main_context_iteration (context, FALSE); + + g_free (sources); +} + +static void +thread_pool_attach_func (gpointer data, + gpointer user_data) +{ + GMainContext *context = user_data; + GSource *source = data; + + g_source_attach (source, context); + g_source_unref (source); +} + +static void +thread_pool_destroy_func (gpointer data, + gpointer user_data) +{ + GSource *source = data; + + g_source_destroy (source); +} + +static void +test_nsources_threadpool (void) +{ + GMainContext *context; + GSource **sources; + GThreadPool *pool; + GError *error = NULL; + gint64 start, end; + gsize n_sources = 50000, i; + + context = g_main_context_default (); + sources = g_new0 (GSource *, n_sources); + + pool = g_thread_pool_new (thread_pool_attach_func, context, + 20, TRUE, NULL); + start = g_get_monotonic_time (); + for (i = 0; i < n_sources; i++) + { + sources[i] = g_idle_source_new (); + g_source_set_callback (sources[i], nsources_cb, NULL, NULL); + g_thread_pool_push (pool, sources[i], &error); + g_assert_no_error (error); + } + g_thread_pool_free (pool, FALSE, TRUE); + end = g_get_monotonic_time (); + g_test_message ("Add sources from threads: %" G_GINT64_FORMAT, + (end - start) / 1000); + + pool = g_thread_pool_new (thread_pool_destroy_func, context, + 20, TRUE, NULL); + start = g_get_monotonic_time (); + for (i = 0; i < n_sources; i++) + { + g_thread_pool_push (pool, sources[i], &error); + g_assert_no_error (error); + } + g_thread_pool_free (pool, FALSE, TRUE); + end = g_get_monotonic_time (); + g_test_message ("Remove sources from threads: %" G_GINT64_FORMAT, + (end - start) / 1000); + + /* Make sure they really did get removed */ + g_main_context_iteration (context, FALSE); + + g_free (sources); +} + +static gboolean source_finalize_called = FALSE; +static guint source_dispose_called = 0; +static gboolean source_dispose_recycle = FALSE; + +static void +finalize (GSource *source) +{ + g_assert_false (source_finalize_called); + source_finalize_called = TRUE; +} + +static void +dispose (GSource *source) +{ + /* Dispose must always be called before finalize */ + g_assert_false (source_finalize_called); + + if (source_dispose_recycle) + g_source_ref (source); + source_dispose_called++; +} + +static GSourceFuncs source_funcs = { + prepare, + check, + dispatch, + finalize, + NULL, + NULL +}; + +static void +test_maincontext_source_finalization (void) +{ + GSource *source; + + /* Check if GSource destruction without dispose function works and calls the + * finalize function as expected */ + source_finalize_called = FALSE; + source_dispose_called = 0; + source_dispose_recycle = FALSE; + source = g_source_new (&source_funcs, sizeof (GSource)); + g_source_unref (source); + g_assert_cmpint (source_dispose_called, ==, 0); + g_assert_true (source_finalize_called); + + /* Check if GSource destruction with dispose function works and calls the + * dispose and finalize function as expected */ + source_finalize_called = FALSE; + source_dispose_called = 0; + source_dispose_recycle = FALSE; + source = g_source_new (&source_funcs, sizeof (GSource)); + g_source_set_dispose_function (source, dispose); + g_source_unref (source); + g_assert_cmpint (source_dispose_called, ==, 1); + g_assert_true (source_finalize_called); + + /* Check if GSource destruction with dispose function works and recycling + * the source from dispose works without calling the finalize function */ + source_finalize_called = FALSE; + source_dispose_called = 0; + source_dispose_recycle = TRUE; + source = g_source_new (&source_funcs, sizeof (GSource)); + g_source_set_dispose_function (source, dispose); + g_source_unref (source); + g_assert_cmpint (source_dispose_called, ==, 1); + g_assert_false (source_finalize_called); + + /* Check if the source is properly recycled */ + g_assert_cmpint (source->ref_count, ==, 1); + + /* And then get rid of it properly */ + source_dispose_recycle = FALSE; + g_source_unref (source); + g_assert_cmpint (source_dispose_called, ==, 2); + g_assert_true (source_finalize_called); +} + +/* GSource implementation which optionally keeps a strong reference to another + * GSource until finalization, when it destroys and unrefs the other source. + */ +typedef struct { + GSource source; + + GSource *other_source; +} SourceWithSource; + +static void +finalize_source_with_source (GSource *source) +{ + SourceWithSource *s = (SourceWithSource *) source; + + if (s->other_source) + { + g_source_destroy (s->other_source); + g_source_unref (s->other_source); + s->other_source = NULL; + } +} + +static GSourceFuncs source_with_source_funcs = { + NULL, + NULL, + NULL, + finalize_source_with_source, + NULL, + NULL +}; + +static void +test_maincontext_source_finalization_from_source (gconstpointer user_data) +{ + GMainContext *c = g_main_context_new (); + GSource *s1, *s2; + + g_test_summary ("Tests if freeing a GSource as part of another GSource " + "during main context destruction works."); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/merge_requests/1353"); + + s1 = g_source_new (&source_with_source_funcs, sizeof (SourceWithSource)); + s2 = g_source_new (&source_with_source_funcs, sizeof (SourceWithSource)); + ((SourceWithSource *)s1)->other_source = g_source_ref (s2); + + /* Attach sources in a different order so they end up being destroyed + * in a different order by the main context */ + if (GPOINTER_TO_INT (user_data) < 5) + { + g_source_attach (s1, c); + g_source_attach (s2, c); + } + else + { + g_source_attach (s2, c); + g_source_attach (s1, c); + } + + /* Test a few different permutations here */ + if (GPOINTER_TO_INT (user_data) % 5 == 0) + { + /* Get rid of our references so that destroying the context + * will unref them immediately */ + g_source_unref (s1); + g_source_unref (s2); + g_main_context_unref (c); + } + else if (GPOINTER_TO_INT (user_data) % 5 == 1) + { + /* Destroy and free the sources before the context */ + g_source_destroy (s1); + g_source_unref (s1); + g_source_destroy (s2); + g_source_unref (s2); + g_main_context_unref (c); + } + else if (GPOINTER_TO_INT (user_data) % 5 == 2) + { + /* Destroy and free the sources before the context */ + g_source_destroy (s2); + g_source_unref (s2); + g_source_destroy (s1); + g_source_unref (s1); + g_main_context_unref (c); + } + else if (GPOINTER_TO_INT (user_data) % 5 == 3) + { + /* Destroy and free the context before the sources */ + g_main_context_unref (c); + g_source_unref (s2); + g_source_unref (s1); + } + else if (GPOINTER_TO_INT (user_data) % 5 == 4) + { + /* Destroy and free the context before the sources */ + g_main_context_unref (c); + g_source_unref (s1); + g_source_unref (s2); + } +} + +static gboolean +dispatch_source_with_source (GSource *source, GSourceFunc callback, gpointer user_data) +{ + return G_SOURCE_REMOVE; +} + +static GSourceFuncs source_with_source_funcs_dispatch = { + NULL, + NULL, + dispatch_source_with_source, + finalize_source_with_source, + NULL, + NULL +}; + +static void +test_maincontext_source_finalization_from_dispatch (gconstpointer user_data) +{ + GMainContext *c = g_main_context_new (); + GSource *s1, *s2; + + g_test_summary ("Tests if freeing a GSource as part of another GSource " + "during main context iteration works."); + + s1 = g_source_new (&source_with_source_funcs_dispatch, sizeof (SourceWithSource)); + s2 = g_source_new (&source_with_source_funcs_dispatch, sizeof (SourceWithSource)); + ((SourceWithSource *)s1)->other_source = g_source_ref (s2); + + g_source_attach (s1, c); + g_source_attach (s2, c); + + if (GPOINTER_TO_INT (user_data) == 0) + { + /* This finalizes s1 as part of the iteration, which then destroys and + * frees s2 too */ + g_source_set_ready_time (s1, 0); + } + else if (GPOINTER_TO_INT (user_data) == 1) + { + /* This destroys s2 as part of the iteration but does not free it as + * it's still referenced by s1 */ + g_source_set_ready_time (s2, 0); + } + else if (GPOINTER_TO_INT (user_data) == 2) + { + /* This destroys both s1 and s2 as part of the iteration */ + g_source_set_ready_time (s1, 0); + g_source_set_ready_time (s2, 0); + } + + /* Get rid of our references so only the main context has one now */ + g_source_unref (s1); + g_source_unref (s2); + + /* Iterate as long as there are sources to dispatch */ + while (g_main_context_iteration (c, FALSE)) + { + /* Do nothing here */ + } + + g_main_context_unref (c); +} + +static void +test_steal_fd (void) +{ + GError *error = NULL; + gchar *tmpfile = NULL; + int fd = -42; + int borrowed; + int stolen; + + g_assert_cmpint (g_steal_fd (&fd), ==, -42); + g_assert_cmpint (fd, ==, -1); + g_assert_cmpint (g_steal_fd (&fd), ==, -1); + g_assert_cmpint (fd, ==, -1); + + fd = g_file_open_tmp (NULL, &tmpfile, &error); + g_assert_cmpint (fd, >=, 0); + g_assert_no_error (error); + borrowed = fd; + stolen = g_steal_fd (&fd); + g_assert_cmpint (fd, ==, -1); + g_assert_cmpint (borrowed, ==, stolen); + + g_close (g_steal_fd (&stolen), &error); + g_assert_no_error (error); + g_assert_cmpint (stolen, ==, -1); + + g_assert_no_errno (remove (tmpfile)); + g_free (tmpfile); +} + +int +main (int argc, char *argv[]) +{ + gint i; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/maincontext/basic", test_maincontext_basic); + g_test_add_func ("/maincontext/nsources_same_priority", test_nsources_same_priority); + g_test_add_func ("/maincontext/nsources_different_priority", test_nsources_different_priority); + g_test_add_func ("/maincontext/nsources_threadpool", test_nsources_threadpool); + g_test_add_func ("/maincontext/source_finalization", test_maincontext_source_finalization); + for (i = 0; i < 10; i++) + { + gchar *name = g_strdup_printf ("/maincontext/source_finalization_from_source/%d", i); + g_test_add_data_func (name, GINT_TO_POINTER (i), test_maincontext_source_finalization_from_source); + g_free (name); + } + for (i = 0; i < 3; i++) + { + gchar *name = g_strdup_printf ("/maincontext/source_finalization_from_dispatch/%d", i); + g_test_add_data_func (name, GINT_TO_POINTER (i), test_maincontext_source_finalization_from_dispatch); + g_free (name); + } + g_test_add_func ("/mainloop/basic", test_mainloop_basic); + g_test_add_func ("/mainloop/timeouts", test_timeouts); + g_test_add_func ("/mainloop/priorities", test_priorities); + g_test_add_func ("/mainloop/invoke", test_invoke); + g_test_add_func ("/mainloop/child_sources", test_child_sources); + g_test_add_func ("/mainloop/recursive_child_sources", test_recursive_child_sources); + g_test_add_func ("/mainloop/swapping_child_sources", test_swapping_child_sources); + g_test_add_func ("/mainloop/blocked_child_sources", test_blocked_child_sources); + g_test_add_func ("/mainloop/source_time", test_source_time); + g_test_add_func ("/mainloop/overflow", test_mainloop_overflow); + g_test_add_func ("/mainloop/ready-time", test_ready_time); + g_test_add_func ("/mainloop/wakeup", test_wakeup); + g_test_add_func ("/mainloop/remove-invalid", test_remove_invalid); + g_test_add_func ("/mainloop/unref-while-pending", test_unref_while_pending); +#ifdef G_OS_UNIX + g_test_add_func ("/mainloop/unix-fd", test_unix_fd); + g_test_add_func ("/mainloop/unix-fd-source", test_unix_fd_source); + g_test_add_func ("/mainloop/source-unix-fd-api", test_source_unix_fd_api); + g_test_add_func ("/mainloop/wait", test_mainloop_wait); + g_test_add_func ("/mainloop/unix-file-poll", test_unix_file_poll); + g_test_add_func ("/mainloop/unix-fd-priority", test_unix_fd_priority); +#endif + g_test_add_func ("/mainloop/nfds", test_nfds); + g_test_add_func ("/mainloop/steal-fd", test_steal_fd); + g_test_add_data_func ("/mainloop/ownerless-polling/attach-first", GINT_TO_POINTER (TRUE), test_ownerless_polling); + g_test_add_data_func ("/mainloop/ownerless-polling/pop-first", GINT_TO_POINTER (FALSE), test_ownerless_polling); + + return g_test_run (); +} diff --git a/glib/tests/mappedfile.c b/glib/tests/mappedfile.c new file mode 100644 index 0000000..785e7c5 --- /dev/null +++ b/glib/tests/mappedfile.c @@ -0,0 +1,205 @@ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include +#endif + +static void +test_basic (void) +{ + GMappedFile *file; + GError *error; + + error = NULL; + file = g_mapped_file_new (g_test_get_filename (G_TEST_DIST, "empty", NULL), FALSE, &error); + g_assert_no_error (error); + + g_mapped_file_ref (file); + g_mapped_file_unref (file); + + g_mapped_file_unref (file); +} + +static void +test_empty (void) +{ + GMappedFile *file; + GError *error; + + error = NULL; + file = g_mapped_file_new (g_test_get_filename (G_TEST_DIST, "empty", NULL), FALSE, &error); + g_assert_no_error (error); + + g_assert_null (g_mapped_file_get_contents (file)); + + g_mapped_file_free (file); +} + +#ifdef G_OS_UNIX +static void +test_device (void) +{ + GError *error = NULL; + GMappedFile *file; + + file = g_mapped_file_new ("/dev/null", FALSE, &error); + g_assert_true (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_INVAL) || + g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NODEV) || + g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM)); + g_assert_null (file); + g_error_free (error); +} +#endif + +static void +test_nonexisting (void) +{ + GMappedFile *file; + GError *error; + + error = NULL; + file = g_mapped_file_new ("no-such-file", FALSE, &error); + g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); + g_clear_error (&error); + g_assert_null (file); +} + +static void +test_writable (void) +{ + GMappedFile *file; + GError *error = NULL; + gchar *contents; + gsize len; + const gchar *old = "MMMMMMMMMMMMMMMMMMMMMMMMM"; + const gchar *new = "abcdefghijklmnopqrstuvxyz"; + gchar *tmp_copy_path; + + tmp_copy_path = g_build_filename (g_get_tmp_dir (), "glib-test-4096-random-bytes", NULL); + + g_file_get_contents (g_test_get_filename (G_TEST_DIST, "4096-random-bytes", NULL), &contents, &len, &error); + g_assert_no_error (error); + g_file_set_contents (tmp_copy_path, contents, len, &error); + g_assert_no_error (error); + + g_free (contents); + + file = g_mapped_file_new (tmp_copy_path, TRUE, &error); + g_assert_no_error (error); + + contents = g_mapped_file_get_contents (file); + g_assert_cmpuint (strncmp (contents, old, strlen (old)), ==, 0); + + memcpy (contents, new, strlen (new)); + g_assert_cmpuint (strncmp (contents, new, strlen (new)), ==, 0); + + g_mapped_file_free (file); + + error = NULL; + file = g_mapped_file_new (tmp_copy_path, FALSE, &error); + g_assert_no_error (error); + + contents = g_mapped_file_get_contents (file); + g_assert_cmpuint (strncmp (contents, old, strlen (old)), ==, 0); + + g_mapped_file_free (file); + + g_free (tmp_copy_path); +} + +static void +test_writable_fd (void) +{ + GMappedFile *file; + GError *error = NULL; + gchar *contents; + const gchar *old = "MMMMMMMMMMMMMMMMMMMMMMMMM"; + const gchar *new = "abcdefghijklmnopqrstuvxyz"; + gsize len; + int fd; + gchar *tmp_copy_path; + + tmp_copy_path = g_build_filename (g_get_tmp_dir (), "glib-test-4096-random-bytes", NULL); + + g_file_get_contents (g_test_get_filename (G_TEST_DIST, "4096-random-bytes", NULL), &contents, &len, &error); + g_assert_no_error (error); + g_file_set_contents (tmp_copy_path, contents, len, &error); + g_assert_no_error (error); + + g_free (contents); + + fd = g_open (tmp_copy_path, O_RDWR, 0); + g_assert_cmpint (fd, !=, -1); + file = g_mapped_file_new_from_fd (fd, TRUE, &error); + g_assert_no_error (error); + + contents = g_mapped_file_get_contents (file); + g_assert_cmpuint (strncmp (contents, old, strlen (old)), ==, 0); + + memcpy (contents, new, strlen (new)); + g_assert_cmpuint (strncmp (contents, new, strlen (new)), ==, 0); + + g_mapped_file_free (file); + close (fd); + + error = NULL; + fd = g_open (tmp_copy_path, O_RDWR, 0); + g_assert_cmpint (fd, !=, -1); + file = g_mapped_file_new_from_fd (fd, TRUE, &error); + g_assert_no_error (error); + + contents = g_mapped_file_get_contents (file); + g_assert_cmpuint (strncmp (contents, old, strlen (old)), ==, 0); + + g_mapped_file_free (file); + + g_free (tmp_copy_path); +} + +static void +test_gbytes (void) +{ + GMappedFile *file; + GBytes *bytes; + GError *error; + + error = NULL; + file = g_mapped_file_new (g_test_get_filename (G_TEST_DIST, "empty", NULL), FALSE, &error); + g_assert_no_error (error); + + bytes = g_mapped_file_get_bytes (file); + g_mapped_file_unref (file); + + g_assert_cmpint (g_bytes_get_size (bytes), ==, 0); + g_bytes_unref (bytes); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/mappedfile/basic", test_basic); + g_test_add_func ("/mappedfile/empty", test_empty); +#ifdef G_OS_UNIX + g_test_add_func ("/mappedfile/device", test_device); +#endif + g_test_add_func ("/mappedfile/nonexisting", test_nonexisting); + g_test_add_func ("/mappedfile/writable", test_writable); + g_test_add_func ("/mappedfile/writable_fd", test_writable_fd); + g_test_add_func ("/mappedfile/gbytes", test_gbytes); + + return g_test_run (); +} diff --git a/glib/tests/markup-collect.c b/glib/tests/markup-collect.c new file mode 100644 index 0000000..04b814b --- /dev/null +++ b/glib/tests/markup-collect.c @@ -0,0 +1,238 @@ +/* + * Copyright © 2007 Ryan Lortie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +#include +#include +#include + +static void +start (GMarkupParseContext *context, + const char *element_name, + const char **attribute_names, + const char **attribute_values, + gpointer user_data, + GError **error) +{ + GString *string = user_data; + gboolean result; + +#define collect(...) \ + g_markup_collect_attributes (element_name, attribute_names, \ + attribute_values, error, __VA_ARGS__, \ + G_MARKUP_COLLECT_INVALID) +#define BOOL G_MARKUP_COLLECT_BOOLEAN +#define OPTBOOL G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL +#define TRI G_MARKUP_COLLECT_TRISTATE +#define STR G_MARKUP_COLLECT_STRING +#define STRDUP G_MARKUP_COLLECT_STRDUP +#define OPTSTR G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL +#define OPTDUP G_MARKUP_COLLECT_STRDUP | G_MARKUP_COLLECT_OPTIONAL +#define n(x) ((x)?(x):"(null)") + + if (strcmp (element_name, "bool") == 0) + { + gboolean mb = 2, ob = 2, tri = 2; + + result = collect (BOOL, "mb", &mb, + OPTBOOL, "ob", &ob, + TRI, "tri", &tri); + + g_assert (result || + (mb == FALSE && ob == FALSE && tri != TRUE && tri != FALSE)); + + if (tri != FALSE && tri != TRUE) + tri = -1; + + g_string_append_printf (string, "", + result, mb, ob, tri); + } + + else if (strcmp (element_name, "str") == 0) + { + const char *cm, *co; + char *am, *ao; + + result = collect (STR, "cm", &cm, + STRDUP, "am", &am, + OPTDUP, "ao", &ao, + OPTSTR, "co", &co); + + g_assert (result || + (cm == NULL && am == NULL && ao == NULL && co == NULL)); + + g_string_append_printf (string, "", + result, n (cm), n (am), n (ao), n (co)); + + g_free (am); + g_free (ao); + } +} + +static GMarkupParser parser = { start, NULL, NULL, NULL, NULL }; + +struct test +{ + const char *document; + const char *result; + GMarkupError error_code; + const char *error_info; +}; + +static struct test tests[] = +{ + { "", "", + G_MARKUP_ERROR_PARSE, "'bool'" }, + + { "", "", 0, NULL }, + { "", "", 0, NULL }, + { "", "", 0, NULL }, + { "", "", 0, NULL }, + + { "", "", 0, NULL }, + { "some text is in here", + "", 0, NULL }, + + { "", "", + G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'mb'" }, + + { "", "", + G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }, + + { "", "", + G_MARKUP_ERROR_INVALID_CONTENT, "'tri'" }, + + { "", "", 0, NULL }, + + { "", "", + G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" }, + + { "", "", + G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" }, + + { "", "", + G_MARKUP_ERROR_INVALID_CONTENT, "'am'" }, + + { "", "", + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'qm'" }, + + { "", "", + G_MARKUP_ERROR_INVALID_CONTENT, "'am'" }, + + { "", "", + G_MARKUP_ERROR_INVALID_CONTENT, "'am'" }, + + { "", + "", + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'a'" }, + + { "", "", + G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }, + + { "", "", + G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" } +}; + +static void +test_collect (gconstpointer d) +{ + const struct test *test = d; + + GMarkupParseContext *ctx; + GError *error = NULL; + GString *string; + gboolean result; + + string = g_string_new (""); + ctx = g_markup_parse_context_new (&parser, G_MARKUP_IGNORE_QUALIFIED, string, NULL); + result = g_markup_parse_context_parse (ctx, + test->document, + -1, &error); + if (result) + result = g_markup_parse_context_end_parse (ctx, &error); + + if (result) + { + g_assert_no_error (error); + g_assert_cmpint (test->error_code, ==, 0); + g_assert_cmpstr (test->result, ==, string->str); + } + else + { + g_assert_error (error, G_MARKUP_ERROR, (gint) test->error_code); + } + + g_markup_parse_context_free (ctx); + g_string_free (string, TRUE); + g_clear_error (&error); +} + +#define XML "" + +static void +start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + /* Omitting "c" attribute intentionally to trigger crash. */ + g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING, "a", NULL, + G_MARKUP_COLLECT_STRING, "b", NULL, + G_MARKUP_COLLECT_INVALID); +} + +static GMarkupParser cleanup_parser = { + start_element, NULL, NULL, NULL, NULL +}; + +static void +test_cleanup (void) +{ + GMarkupParseContext *context; + + if (!g_test_undefined ()) + return; + + context = g_markup_parse_context_new (&cleanup_parser, 0, NULL, NULL); + g_markup_parse_context_parse (context, XML, -1, NULL); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "g_markup_parse_context_end_parse: assertion 'context->state != STATE_ERROR' failed"); + g_markup_parse_context_end_parse (context, NULL); + g_test_assert_expected_messages (); + + g_markup_parse_context_free (context); +} + +int +main (int argc, char **argv) +{ + gsize i; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + path = g_strdup_printf ("/markup/collect/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &tests[i], test_collect); + g_free (path); + } + + g_test_add_func ("/markup/collect/cleanup", test_cleanup); + + return g_test_run (); +} diff --git a/glib/tests/markup-escape.c b/glib/tests/markup-escape.c new file mode 100644 index 0000000..44290fe --- /dev/null +++ b/glib/tests/markup-escape.c @@ -0,0 +1,169 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include + +typedef struct _EscapeTest EscapeTest; + +struct _EscapeTest +{ + const gchar *original; + const gchar *expected; +}; + +static EscapeTest escape_tests[] = +{ + { "&", "&" }, + { "<", "<" }, + { ">", ">" }, + { "'", "'" }, + { "\"", """ }, + { "\"\"", """" }, + { "\"à´…\"", ""à´…"" }, + { "", "" }, + { "A", "A" }, + { "A&", "A&" }, + { "&A", "&A" }, + { "A&A", "A&A" }, + { "&&A", "&&A" }, + { "A&&", "A&&" }, + { "A&&A", "A&&A" }, + { "A&A&A", "A&A&A" }, + { "AA", "A&#23;A" }, + { "A A", "A&#xa;A" }, + { "N\x2N", "NN" }, + { "N\xc2\x80N", "N€N" }, + { "N\xc2\x79N", "N\xc2\x79N" }, + { "N\xc2\x9fN", "NŸN" }, + + /* As per g_markup_escape_text()'s documentation, whitespace is not escaped: */ + { "\t", "\t" }, +}; + +static void +escape_test (gconstpointer d) +{ + const EscapeTest *test = d; + gchar *result; + + result = g_markup_escape_text (test->original, -1); + + g_assert_cmpstr (result, ==, test->expected); + + g_free (result); +} + +typedef struct _UnicharTest UnicharTest; + +struct _UnicharTest +{ + gunichar c; + gboolean entity; +}; + +static UnicharTest unichar_tests[] = +{ + { 0x1, TRUE }, + { 0x8, TRUE }, + { 0x9, FALSE }, + { 0xa, FALSE }, + { 0xb, TRUE }, + { 0xc, TRUE }, + { 0xd, FALSE }, + { 0xe, TRUE }, + { 0x1f, TRUE }, + { 0x20, FALSE }, + { 0x7e, FALSE }, + { 0x7f, TRUE }, + { 0x84, TRUE }, + { 0x85, FALSE }, + { 0x86, TRUE }, + { 0x9f, TRUE }, + { 0xa0, FALSE } +}; + +static void +unichar_test (gconstpointer d) +{ + const UnicharTest *test = d; + EscapeTest t; + gint len; + gchar outbuf[7], expected[12]; + + len = g_unichar_to_utf8 (test->c, outbuf); + outbuf[len] = 0; + + if (test->entity) + g_snprintf (expected, 12, "&#x%x;", test->c); + else + strcpy (expected, outbuf); + + t.original = outbuf; + t.expected = expected; + escape_test (&t); +} + +G_GNUC_PRINTF(1, 3) +static void +test_format (const gchar *format, + const gchar *expected, + ...) +{ + gchar *result; + va_list args; + + va_start (args, expected); + result = g_markup_vprintf_escaped (format, args); + va_end (args); + + g_assert_cmpstr (result, ==, expected); + + g_free (result); +} + +static void +format_test (void) +{ + test_format ("A", "A"); + test_format ("A%s", "A&", "&"); + test_format ("%sA", "&A", "&"); + test_format ("A%sA", "A&A", "&"); + test_format ("%s%sA", "&&A", "&", "&"); + test_format ("A%s%s", "A&&", "&", "&"); + test_format ("A%s%sA", "A&&A", "&", "&"); + test_format ("A%sA%sA", "A&A&A", "&", "&"); + test_format ("%s", "<B>&", "&"); + test_format ("%c%c", "<&", '<', '&'); + test_format (".%c.%c.", ".<.&.", '<', '&'); + test_format ("%s", "", ""); + test_format ("%-5s", "A ", "A"); + test_format ("%2$s%1$s", "B.A.", "A.", "B."); +} + +int main (int argc, char **argv) +{ + gsize i; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS (escape_tests); i++) + { + path = g_strdup_printf ("/markup/escape-text/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &escape_tests[i], escape_test); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (unichar_tests); i++) + { + path = g_strdup_printf ("/markup/escape-unichar/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &unichar_tests[i], unichar_test); + g_free (path); + } + + g_test_add_func ("/markup/format", format_test); + + return g_test_run (); +} diff --git a/glib/tests/markup-parse.c b/glib/tests/markup-parse.c new file mode 100644 index 0000000..00742d7 --- /dev/null +++ b/glib/tests/markup-parse.c @@ -0,0 +1,348 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include +#include + +static int depth = 0; +static GString *string; + +static void +indent (int extra) +{ + int i = 0; + while (i < depth) + { + g_string_append (string, " "); + ++i; + } +} + +static void +start_element_handler (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + int i; + + indent (0); + g_string_append_printf (string, "ELEMENT '%s'\n", element_name); + + i = 0; + while (attribute_names[i] != NULL) + { + indent (1); + + g_string_append_printf (string, "%s=\"%s\"\n", + attribute_names[i], + attribute_values[i]); + + ++i; + } + + ++depth; +} + +static void +end_element_handler (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + --depth; + indent (0); + g_string_append_printf (string, "END '%s'\n", element_name); + } + +static void +text_handler (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + indent (0); + g_string_append_printf (string, "TEXT '%.*s'\n", (int)text_len, text); +} + + +static void +passthrough_handler (GMarkupParseContext *context, + const gchar *passthrough_text, + gsize text_len, + gpointer user_data, + GError **error) +{ + indent (0); + + g_string_append_printf (string, "PASS '%.*s'\n", (int)text_len, passthrough_text); +} + +static void +error_handler (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ + g_string_append_printf (string, "ERROR %s\n", error->message); +} + +static const GMarkupParser parser = { + start_element_handler, + end_element_handler, + text_handler, + passthrough_handler, + error_handler +}; + +static const GMarkupParser silent_parser = { + NULL, + NULL, + NULL, + NULL, + error_handler +}; + +static int +test_in_chunks (const gchar *contents, + gint length, + gint chunk_size, + GMarkupParseFlags flags) +{ + GMarkupParseContext *context; + int i = 0; + + context = g_markup_parse_context_new (&silent_parser, flags, NULL, NULL); + + while (i < length) + { + int this_chunk = MIN (length - i, chunk_size); + + if (!g_markup_parse_context_parse (context, + contents + i, + this_chunk, + NULL)) + { + g_markup_parse_context_free (context); + return 1; + } + + i += this_chunk; + } + + if (!g_markup_parse_context_end_parse (context, NULL)) + { + g_markup_parse_context_free (context); + return 1; + } + + g_markup_parse_context_free (context); + + return 0; +} + +/* Load the given @filename and parse it multiple times with different chunking + * and length handling. All results should be equal. %TRUE is returned if the + * file was parsed successfully on every attempt; %FALSE if it failed to parse + * on every attempt. The test aborts if some attempts succeed and some fail. */ +static gboolean +test_file (const gchar *filename, + GMarkupParseFlags flags) +{ + gchar *contents = NULL, *contents_unterminated = NULL; + gsize length_bytes; + GError *local_error = NULL; + GMarkupParseContext *context; + gint line, col; + guint n_failures = 0; + guint n_tests = 0; + const gsize chunk_sizes_bytes[] = { 1, 2, 5, 12, 1024 }; + gsize i; + GString *first_string = NULL; + + g_file_get_contents (filename, &contents, &length_bytes, &local_error); + g_assert_no_error (local_error); + + /* Make a copy of the contents with no trailing nul. */ + contents_unterminated = g_malloc (length_bytes); + if (contents_unterminated != NULL) + memcpy (contents_unterminated, contents, length_bytes); + + /* Test with nul termination. */ + context = g_markup_parse_context_new (&parser, flags, NULL, NULL); + g_assert (g_markup_parse_context_get_user_data (context) == NULL); + g_markup_parse_context_get_position (context, &line, &col); + g_assert_cmpint (line, ==, 1); + g_assert_cmpint (col, ==, 1); + + if (!g_markup_parse_context_parse (context, contents, -1, NULL) || + !g_markup_parse_context_end_parse (context, NULL)) + n_failures++; + n_tests++; + + g_markup_parse_context_free (context); + + /* FIXME: Swap out the error string so we only return one copy of it, not + * @n_tests copies. This should be fixed properly by eliminating the global + * state in this file. */ + first_string = g_steal_pointer (&string); + string = g_string_new (""); + + /* With the length specified explicitly and a nul terminator present (since + * g_file_get_contents() always adds one). */ + if (test_in_chunks (contents, length_bytes, length_bytes, flags) != 0) + n_failures++; + n_tests++; + + /* With the length specified explicitly and no nul terminator present. */ + if (test_in_chunks (contents_unterminated, length_bytes, length_bytes, flags) != 0) + n_failures++; + n_tests++; + + /* In various sized chunks. */ + for (i = 0; i < G_N_ELEMENTS (chunk_sizes_bytes); i++) + { + if (test_in_chunks (contents, length_bytes, chunk_sizes_bytes[i], flags) != 0) + n_failures++; + n_tests++; + } + + g_free (contents); + g_free (contents_unterminated); + + /* FIXME: Restore the error string. */ + g_string_free (string, TRUE); + string = g_steal_pointer (&first_string); + + /* We expect the file to either always be parsed successfully, or never be + * parsed successfully. There’s a bug in GMarkup if it sometimes parses + * successfully depending on how you chunk or terminate the input. */ + if (n_failures > 0) + g_assert_cmpint (n_failures, ==, n_tests); + + return (n_failures == 0); +} + +static gchar * +get_expected_filename (const gchar *filename, + GMarkupParseFlags flags) +{ + gchar *f, *p, *expected; + + f = g_strdup (filename); + p = strstr (f, ".gmarkup"); + if (p) + *p = 0; + if (flags == 0) + expected = g_strconcat (f, ".expected", NULL); + else if (flags == G_MARKUP_TREAT_CDATA_AS_TEXT) + expected = g_strconcat (f, ".cdata-as-text", NULL); + else + g_assert_not_reached (); + + g_free (f); + + return expected; +} + +static void +test_parse (gconstpointer d) +{ + const gchar *filename = d; + gchar *expected_file; + gchar *expected; + gboolean valid_input; + GError *error = NULL; + gboolean res; + + valid_input = strstr (filename, "valid") != NULL; + expected_file = get_expected_filename (filename, 0); + + depth = 0; + string = g_string_sized_new (0); + + res = test_file (filename, 0); + g_assert_cmpint (res, ==, valid_input); + + g_file_get_contents (expected_file, &expected, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (string->str, ==, expected); + g_free (expected); + + g_string_free (string, TRUE); + + g_free (expected_file); + + expected_file = get_expected_filename (filename, G_MARKUP_TREAT_CDATA_AS_TEXT); + if (g_file_test (expected_file, G_FILE_TEST_EXISTS)) + { + depth = 0; + string = g_string_sized_new (0); + + res = test_file (filename, G_MARKUP_TREAT_CDATA_AS_TEXT); + g_assert_cmpint (res, ==, valid_input); + + g_file_get_contents (expected_file, &expected, NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (string->str, ==, expected); + g_free (expected); + + g_string_free (string, TRUE); + } + + g_free (expected_file); +} + +int +main (int argc, char *argv[]) +{ + GDir *dir; + GError *error; + const gchar *name; + gchar *path; + + g_setenv ("LC_ALL", "C", TRUE); + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + /* allow to easily generate expected output for new test cases */ + if (argc > 1) + { + gint arg = 1; + GMarkupParseFlags flags = 0; + + if (strcmp (argv[1], "--cdata-as-text") == 0) + { + flags = G_MARKUP_TREAT_CDATA_AS_TEXT; + arg = 2; + } + string = g_string_sized_new (0); + test_file (argv[arg], flags); + g_print ("%s", string->str); + return 0; + } + + error = NULL; + path = g_test_build_filename (G_TEST_DIST, "markups", NULL); + dir = g_dir_open (path, 0, &error); + g_free (path); + g_assert_no_error (error); + while ((name = g_dir_read_name (dir)) != NULL) + { + if (!strstr (name, "gmarkup")) + continue; + + path = g_strdup_printf ("/markup/parse/%s", name); + g_test_add_data_func_full (path, g_test_build_filename (G_TEST_DIST, "markups", name, NULL), + test_parse, g_free); + g_free (path); + } + g_dir_close (dir); + + return g_test_run (); +} diff --git a/glib/tests/markup-subparser.c b/glib/tests/markup-subparser.c new file mode 100644 index 0000000..71b9ac6 --- /dev/null +++ b/glib/tests/markup-subparser.c @@ -0,0 +1,385 @@ +/* + * Copyright © 2008 Ryan Lortie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +#include +#include +#include + +/* keep track of GString instances to make sure nothing leaks */ +static int strings_allocated; + +/* === the GMarkupParser functions === */ +static void +subparser_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + g_string_append_printf (user_data, "{%s}", element_name); + + /* we don't like trouble... */ + if (strcmp (element_name, "trouble") == 0) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "we don't like trouble"); +} + +static void +subparser_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + g_string_append_printf (user_data, "{/%s}", element_name); +} + +static void +subparser_error (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ + g_string_free (user_data, TRUE); + strings_allocated--; +} + +static GMarkupParser subparser_parser = +{ + subparser_start_element, + subparser_end_element, + NULL, + NULL, + subparser_error +}; + +/* convenience functions for a parser that does not + * replay the starting tag into the subparser... + */ +static void +subparser_start (GMarkupParseContext *ctx) +{ + gpointer user_data; + + user_data = g_string_new (NULL); + strings_allocated++; + g_markup_parse_context_push (ctx, &subparser_parser, user_data); +} + +static char * +subparser_end (GMarkupParseContext *ctx, + GError **error) +{ + GString *string; + char *result; + + string = g_markup_parse_context_pop (ctx); + result = string->str; + + g_string_free (string, FALSE); + strings_allocated--; + + if (result == NULL || result[0] == '\0') + { + g_free (result); + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "got no data"); + + return NULL; + } + + return result; +} + +/* convenience functions for a parser that -does- + * replay the starting tag into the subparser... + */ +static gboolean +replay_parser_start (GMarkupParseContext *ctx, + const char *element_name, + const char **attribute_names, + const char **attribute_values, + GError **error) +{ + GError *tmp_error = NULL; + gpointer user_data; + + user_data = g_string_new (NULL); + strings_allocated++; + + subparser_parser.start_element (ctx, element_name, + attribute_names, attribute_values, + user_data, &tmp_error); + + if (tmp_error) + { + g_propagate_error (error, tmp_error); + g_string_free (user_data, TRUE); + strings_allocated--; + + return FALSE; + } + + g_markup_parse_context_push (ctx, &subparser_parser, user_data); + + return TRUE; +} + +static char * +replay_parser_end (GMarkupParseContext *ctx, + GError **error) +{ + GError *tmp_error = NULL; + GString *string; + char *result; + + string = g_markup_parse_context_pop (ctx); + + subparser_parser.end_element (ctx, g_markup_parse_context_get_element (ctx), + string, &tmp_error); + + if (tmp_error) + { + g_propagate_error (error, tmp_error); + g_string_free (string, TRUE); + strings_allocated--; + + return NULL; + } + + result = string->str; + + g_string_free (string, FALSE); + strings_allocated--; + + if (result == NULL || result[0] == '\0') + { + g_free (result); + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "got no data"); + + return NULL; + } + + return result; +} + + +/* === start interface between subparser and calling parser === */ +static void subparser_start (GMarkupParseContext *ctx); +static char *subparser_end (GMarkupParseContext *ctx, + GError **error); +/* === end interface between subparser and calling parser === */ + +/* === start interface between replay parser and calling parser === */ +static gboolean replay_parser_start (GMarkupParseContext *ctx, + const char *element_name, + const char **attribute_names, + const char **attribute_values, + GError **error); +static char *replay_parser_end (GMarkupParseContext *ctx, + GError **error); +/* === end interface between replay parser and calling parser === */ + + + +/* now comes our parser for the test. + * + * we recognise the tags and . + * is ignored. + * invokes the subparser (no replay). + * + * "unknown tags" are passed to the reply subparser + * (so the unknown tag is fed to the subparser...) + */ +static void +start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + g_string_append_printf (user_data, "<%s>", element_name); + + if (strcmp (element_name, "test") == 0) + { + /* do nothing */ + } + else if (strcmp (element_name, "sub") == 0) + { + /* invoke subparser */ + subparser_start (context); + } + else + { + /* unknown tag. invoke replay subparser */ + if (!replay_parser_start (context, element_name, + attribute_names, attribute_values, + error)) + return; + } +} + +static void +end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + if (strcmp (element_name, "test") == 0) + { + /* do nothing */ + } + else if (strcmp (element_name, "sub") == 0) + { + char *result; + + if ((result = subparser_end (context, error)) == NULL) + return; + + g_string_append_printf (user_data, "<<%s>>", result); + g_free (result); + } + else + { + char *result; + + if ((result = replay_parser_end (context, error)) == NULL) + return; + + g_string_append_printf (user_data, "[[%s]]", result); + g_free (result); + } + + g_string_append_printf (user_data, "", element_name); +} + +static GMarkupParser parser = +{ + start_element, + end_element, + NULL, + NULL, + NULL +}; + +typedef struct +{ + const char *markup; + const char *result; + const char *error_message; +} TestCase; + +static void +test (gconstpointer user_data) +{ + const TestCase *tc = user_data; + GMarkupParseContext *ctx; + GString *string; + gboolean result; + GError *error; + + error = NULL; + string = g_string_new (NULL); + ctx = g_markup_parse_context_new (&parser, 0, string, NULL); + result = g_markup_parse_context_parse (ctx, tc->markup, + strlen (tc->markup), &error); + if (result) + result = g_markup_parse_context_end_parse (ctx, &error); + g_markup_parse_context_free (ctx); + g_assert (strings_allocated == 0); + + if (result) + { + if (tc->error_message) + g_error ("expected failure (about '%s') passed!\n" + " in: %s\n out: %s", + tc->error_message, tc->markup, string->str); + } + else + { + if (!tc->error_message) + g_error ("unexpected failure: '%s'\n" + " in: %s\n out: %s", + error->message, tc->markup, string->str); + + if (!strstr (error->message, tc->error_message)) + g_error ("failed for the wrong reason.\n" + " expecting message about '%s'\n" + " got message '%s'\n" + " in: %s\n out: %s", + tc->error_message, error->message, tc->markup, string->str); + } + + if (strcmp (string->str, tc->result) != 0) + g_error ("got the wrong result.\n" + " expected: '%s'\n" + " got: '%s'\n" + " input: %s", + tc->result, string->str, tc->markup); + + if (error) + g_error_free (error); + + g_string_free (string, TRUE); +} + +TestCase test_cases[] = /* successful runs */ +{ + /* in */ /* out */ /* error */ + { "", "", NULL }, + { "", "<<{foo}{/foo}>>", NULL }, + { "", "<<{foo}{/foo}{bar}{/bar}>>", NULL }, + { "", "[[{foo}{bar}{/bar}{/foo}]]", NULL }, + { "", "[[{foo}{x}{/x}{y}{/y}{/foo}]]", NULL }, + { "", "[[{foo}{/foo}]]", NULL }, + { "", "<<{foo}{/foo}>>" + "[[{bar}{/bar}]]", NULL } +}; + +TestCase error_cases[] = /* error cases */ +{ + /* in */ /* out */ /* error */ + { "<>", "", ">"}, + { "", "", "empty" }, + { "", "", "trouble" }, + { "", "", "trouble" }, + { "", "", "trouble" }, + { "", "", "no data" }, + { "", "", "no data" } +}; + +#define add_tests(func, basename, array) \ + G_STMT_START { \ + gsize __add_tests_i; \ + \ + for (__add_tests_i = 0; \ + __add_tests_i < G_N_ELEMENTS (array); \ + __add_tests_i++) \ + { \ + char *testname; \ + \ + testname = g_strdup_printf ("%s/%" G_GSIZE_FORMAT, \ + basename, __add_tests_i); \ + g_test_add_data_func (testname, &array[__add_tests_i], func); \ + g_free (testname); \ + } \ + } G_STMT_END + +int +main (int argc, char **argv) +{ + g_setenv ("LC_ALL", "C", TRUE); + g_test_init (&argc, &argv, NULL); + add_tests (test, "/glib/markup/subparser/success", test_cases); + add_tests (test, "/glib/markup/subparser/failure", error_cases); + return g_test_run (); +} diff --git a/glib/tests/markup.c b/glib/tests/markup.c new file mode 100644 index 0000000..71f9ff1 --- /dev/null +++ b/glib/tests/markup.c @@ -0,0 +1,98 @@ +/* Unit tests for GMarkup + * Copyright (C) 2013 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Matthias Clasen + */ + +#include "glib.h" + +typedef struct { + GSList *stack; +} ParseData; + +static void +start (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseData *data = user_data; + + data->stack = g_slist_prepend (data->stack, g_strdup (element_name)); +} + +static void +end (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseData *data = user_data; + const GSList *stack; + const GSList *s1, *s2; + GSList *s; + + stack = g_markup_parse_context_get_element_stack (context); + for (s1 = stack, s2 = data->stack; s1 && s2; s1 = s1->next, s2 = s2->next) + g_assert_cmpstr (s1->data, ==, s2->data); + g_assert (s1 == NULL && s2 == NULL); + + s = data->stack; + data->stack = data->stack->next; + s->next = NULL; + g_slist_free_full (s, g_free); +} + +const gchar content[] = + " bla fff"; + +static void +test_markup_stack (void) +{ + GMarkupParser parser = { + start, + end, + NULL, + NULL, + NULL + }; + GMarkupParseContext *context; + ParseData data = { NULL }; + gboolean res; + GError *error = NULL; + + context = g_markup_parse_context_new (&parser, 0, &data, NULL); + res = g_markup_parse_context_parse (context, content, -1, &error); + g_assert (res); + g_assert_no_error (error); + g_markup_parse_context_free (context); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/markup/stack", test_markup_stack); + + return g_test_run (); +} diff --git a/glib/tests/markups/fail-1.expected b/glib/tests/markups/fail-1.expected new file mode 100644 index 0000000..ccd6219 --- /dev/null +++ b/glib/tests/markups/fail-1.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 1: Document was empty or contained only whitespace diff --git a/glib/tests/markups/fail-1.gmarkup b/glib/tests/markups/fail-1.gmarkup new file mode 100644 index 0000000..e69de29 diff --git a/glib/tests/markups/fail-10.expected b/glib/tests/markups/fail-10.expected new file mode 100644 index 0000000..6462cdf --- /dev/null +++ b/glib/tests/markups/fail-10.expected @@ -0,0 +1,4 @@ +ELEMENT 'foo' + TEXT ' +' +ERROR Error on line 2 char 8: Element “|foo†was closed, but the currently open element is “foo†diff --git a/glib/tests/markups/fail-10.gmarkup b/glib/tests/markups/fail-10.gmarkup new file mode 100644 index 0000000..fe16558 --- /dev/null +++ b/glib/tests/markups/fail-10.gmarkup @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/glib/tests/markups/fail-11.expected b/glib/tests/markups/fail-11.expected new file mode 100644 index 0000000..f2331b7 --- /dev/null +++ b/glib/tests/markups/fail-11.expected @@ -0,0 +1,7 @@ +ELEMENT 'foo' + TEXT ' +' + ELEMENT 'bar' + TEXT ' +' +ERROR Error on line 3 char 7: Element “foo†was closed, but the currently open element is “bar†diff --git a/glib/tests/markups/fail-11.gmarkup b/glib/tests/markups/fail-11.gmarkup new file mode 100644 index 0000000..216f40c --- /dev/null +++ b/glib/tests/markups/fail-11.gmarkup @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/glib/tests/markups/fail-12.expected b/glib/tests/markups/fail-12.expected new file mode 100644 index 0000000..c4176b0 --- /dev/null +++ b/glib/tests/markups/fail-12.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 6: Element “foo†was closed, no element is currently open diff --git a/glib/tests/markups/fail-12.gmarkup b/glib/tests/markups/fail-12.gmarkup new file mode 100644 index 0000000..a640299 --- /dev/null +++ b/glib/tests/markups/fail-12.gmarkup @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/glib/tests/markups/fail-13.expected b/glib/tests/markups/fail-13.expected new file mode 100644 index 0000000..b2cdf9f --- /dev/null +++ b/glib/tests/markups/fail-13.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 7: Element “foo|†was closed, no element is currently open diff --git a/glib/tests/markups/fail-13.gmarkup b/glib/tests/markups/fail-13.gmarkup new file mode 100644 index 0000000..a719288 --- /dev/null +++ b/glib/tests/markups/fail-13.gmarkup @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/glib/tests/markups/fail-14.expected b/glib/tests/markups/fail-14.expected new file mode 100644 index 0000000..2f0d641 --- /dev/null +++ b/glib/tests/markups/fail-14.expected @@ -0,0 +1,4 @@ +ELEMENT 'foo' + TEXT ' +' +ERROR Error on line 2 char 3: Document ended unexpectedly just after an open angle bracket “<†diff --git a/glib/tests/markups/fail-14.gmarkup b/glib/tests/markups/fail-14.gmarkup new file mode 100644 index 0000000..ed52a60 --- /dev/null +++ b/glib/tests/markups/fail-14.gmarkup @@ -0,0 +1,2 @@ + +< \ No newline at end of file diff --git a/glib/tests/markups/fail-15.expected b/glib/tests/markups/fail-15.expected new file mode 100644 index 0000000..5b31870 --- /dev/null +++ b/glib/tests/markups/fail-15.expected @@ -0,0 +1,8 @@ +ELEMENT 'foo' + TEXT ' +' + ELEMENT 'bar' + TEXT ' +' + END 'bar' +ERROR Error on line 3 char 8: Document ended unexpectedly with elements still open — “foo†was the last element opened diff --git a/glib/tests/markups/fail-15.gmarkup b/glib/tests/markups/fail-15.gmarkup new file mode 100644 index 0000000..c3b59e0 --- /dev/null +++ b/glib/tests/markups/fail-15.gmarkup @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/glib/tests/markups/fail-16.expected b/glib/tests/markups/fail-16.expected new file mode 100644 index 0000000..a9f1f82 --- /dev/null +++ b/glib/tests/markups/fail-16.expected @@ -0,0 +1,2 @@ +ELEMENT 'foo' +ERROR Error on line 1 char 6: Document ended unexpectedly, expected to see a close angle bracket ending the tag diff --git a/glib/tests/markups/fail-16.gmarkup b/glib/tests/markups/fail-16.gmarkup new file mode 100644 index 0000000..20f0148 --- /dev/null +++ b/glib/tests/markups/fail-16.gmarkup @@ -0,0 +1 @@ +) diff --git a/glib/tests/markups/fail-2.gmarkup b/glib/tests/markups/fail-2.gmarkup new file mode 100644 index 0000000..c7e4a54 --- /dev/null +++ b/glib/tests/markups/fail-2.gmarkup @@ -0,0 +1 @@ +±Î½èªž diff --git a/glib/tests/markups/fail-20.expected b/glib/tests/markups/fail-20.expected new file mode 100644 index 0000000..0dc081b --- /dev/null +++ b/glib/tests/markups/fail-20.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 10: Document ended unexpectedly after the equals sign following an attribute name; no attribute value diff --git a/glib/tests/markups/fail-20.gmarkup b/glib/tests/markups/fail-20.gmarkup new file mode 100644 index 0000000..39fcbad --- /dev/null +++ b/glib/tests/markups/fail-20.gmarkup @@ -0,0 +1 @@ + diff --git a/glib/tests/markups/fail-43.expected b/glib/tests/markups/fail-43.expected new file mode 100644 index 0000000..64b42c2 --- /dev/null +++ b/glib/tests/markups/fail-43.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 10: Odd character “≈â€, expected a “=†after attribute name “bar†of element “foo†diff --git a/glib/tests/markups/fail-43.gmarkup b/glib/tests/markups/fail-43.gmarkup new file mode 100644 index 0000000..c247c71 --- /dev/null +++ b/glib/tests/markups/fail-43.gmarkup @@ -0,0 +1 @@ + diff --git a/glib/tests/markups/fail-44.expected b/glib/tests/markups/fail-44.expected new file mode 100644 index 0000000..0cddd72 --- /dev/null +++ b/glib/tests/markups/fail-44.expected @@ -0,0 +1,2 @@ +ELEMENT 'foo' +ERROR Error on line 1 char 6: Odd character “≻â€, expected a “>†character to end the empty-element tag “foo†diff --git a/glib/tests/markups/fail-44.gmarkup b/glib/tests/markups/fail-44.gmarkup new file mode 100644 index 0000000..f6217db --- /dev/null +++ b/glib/tests/markups/fail-44.gmarkup @@ -0,0 +1 @@ +†diff --git a/glib/tests/markups/fail-45.gmarkup b/glib/tests/markups/fail-45.gmarkup new file mode 100644 index 0000000..4183291 --- /dev/null +++ b/glib/tests/markups/fail-45.gmarkup @@ -0,0 +1 @@ + +abc diff --git a/glib/tests/markups/fail-47.expected b/glib/tests/markups/fail-47.expected new file mode 100644 index 0000000..1083489 --- /dev/null +++ b/glib/tests/markups/fail-47.expected @@ -0,0 +1 @@ +ERROR Error on line 1: Failed to parse “â€, which should have been a digit inside a character reference (ê for example) — perhaps the digit is too large diff --git a/glib/tests/markups/fail-47.gmarkup b/glib/tests/markups/fail-47.gmarkup new file mode 100644 index 0000000..bbe8179 --- /dev/null +++ b/glib/tests/markups/fail-47.gmarkup @@ -0,0 +1 @@ + diff --git a/glib/tests/markups/fail-48.expected b/glib/tests/markups/fail-48.expected new file mode 100644 index 0000000..ed546bf --- /dev/null +++ b/glib/tests/markups/fail-48.expected @@ -0,0 +1 @@ +ERROR Error on line 2 char 2: Odd character “>â€, expected a “=†after attribute name “bar†of element “fail†diff --git a/glib/tests/markups/fail-48.gmarkup b/glib/tests/markups/fail-48.gmarkup new file mode 100644 index 0000000..fcbeab6 --- /dev/null +++ b/glib/tests/markups/fail-48.gmarkup @@ -0,0 +1,2 @@ + diff --git a/glib/tests/markups/fail-49.expected b/glib/tests/markups/fail-49.expected new file mode 100644 index 0000000..386e1a4 --- /dev/null +++ b/glib/tests/markups/fail-49.expected @@ -0,0 +1,3 @@ +ELEMENT 'foo' + TEXT '' +ERROR Error on line 2 char 2: Document ended unexpectedly inside the close tag for element “foo†diff --git a/glib/tests/markups/fail-49.gmarkup b/glib/tests/markups/fail-49.gmarkup new file mode 100644 index 0000000..5e1e3bb --- /dev/null +++ b/glib/tests/markups/fail-49.gmarkup @@ -0,0 +1 @@ + + diff --git a/glib/tests/markups/fail-50.expected b/glib/tests/markups/fail-50.expected new file mode 100644 index 0000000..70d4498 --- /dev/null +++ b/glib/tests/markups/fail-50.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 5: Odd character “\xfcâ€, expected an open quote mark after the equals sign when giving value for attribute “r†of element Ҡdiff --git a/glib/tests/markups/fail-50.gmarkup b/glib/tests/markups/fail-50.gmarkup new file mode 100644 index 0000000..f110f15 --- /dev/null +++ b/glib/tests/markups/fail-50.gmarkup @@ -0,0 +1 @@ +< r=ü \ No newline at end of file diff --git a/glib/tests/markups/fail-51.expected b/glib/tests/markups/fail-51.expected new file mode 100644 index 0000000..1c7e8d4 --- /dev/null +++ b/glib/tests/markups/fail-51.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 5: Document ended unexpectedly inside the close tag for an unopened element diff --git a/glib/tests/markups/fail-51.gmarkup b/glib/tests/markups/fail-51.gmarkup new file mode 100644 index 0000000..860e1e6 --- /dev/null +++ b/glib/tests/markups/fail-51.gmarkup @@ -0,0 +1 @@ +†character to end the empty-element tag “r†diff --git a/glib/tests/markups/fail-53.gmarkup b/glib/tests/markups/fail-53.gmarkup new file mode 100644 index 0000000..4324355 --- /dev/null +++ b/glib/tests/markups/fail-53.gmarkup @@ -0,0 +1 @@ + diff --git a/glib/tests/markups/fail-6.expected b/glib/tests/markups/fail-6.expected new file mode 100644 index 0000000..d41f00e --- /dev/null +++ b/glib/tests/markups/fail-6.expected @@ -0,0 +1 @@ +ERROR Error on line 2 char 1: “foo|†is not a valid name: “|†diff --git a/glib/tests/markups/fail-6.gmarkup b/glib/tests/markups/fail-6.gmarkup new file mode 100644 index 0000000..4c63568 --- /dev/null +++ b/glib/tests/markups/fail-6.gmarkup @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/glib/tests/markups/fail-7.expected b/glib/tests/markups/fail-7.expected new file mode 100644 index 0000000..a2843cd --- /dev/null +++ b/glib/tests/markups/fail-7.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 15: “bar}"baz"†is not a valid name: “}†diff --git a/glib/tests/markups/fail-7.gmarkup b/glib/tests/markups/fail-7.gmarkup new file mode 100644 index 0000000..5585bd6 --- /dev/null +++ b/glib/tests/markups/fail-7.gmarkup @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/glib/tests/markups/fail-8.expected b/glib/tests/markups/fail-8.expected new file mode 100644 index 0000000..121163d --- /dev/null +++ b/glib/tests/markups/fail-8.expected @@ -0,0 +1,2 @@ +ELEMENT 'foo' +ERROR Error on line 1 char 6: Odd character “}â€, expected a “>†character to end the empty-element tag “foo†diff --git a/glib/tests/markups/fail-8.gmarkup b/glib/tests/markups/fail-8.gmarkup new file mode 100644 index 0000000..b355951 --- /dev/null +++ b/glib/tests/markups/fail-8.gmarkup @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/glib/tests/markups/fail-9.expected b/glib/tests/markups/fail-9.expected new file mode 100644 index 0000000..f2d77cc --- /dev/null +++ b/glib/tests/markups/fail-9.expected @@ -0,0 +1 @@ +ERROR Error on line 1 char 10: Odd character “{â€, expected an open quote mark after the equals sign when giving value for attribute “bar†of element “foo†diff --git a/glib/tests/markups/fail-9.gmarkup b/glib/tests/markups/fail-9.gmarkup new file mode 100644 index 0000000..edd5596 --- /dev/null +++ b/glib/tests/markups/fail-9.gmarkup @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/glib/tests/markups/valid-1.expected b/glib/tests/markups/valid-1.expected new file mode 100644 index 0000000..8b6cdd7 --- /dev/null +++ b/glib/tests/markups/valid-1.expected @@ -0,0 +1,37 @@ +PASS '' +PASS '' +ELEMENT 'foobar' + TEXT ' +' + ELEMENT 'e1' + TEXT 'Hi & this is some text inside an element Two 'E' chars as character refs: E E and some 'J': J J' + END 'e1' + TEXT ' +' + ELEMENT 'e2:foo' + TEXT ' Text ' + ELEMENT 'childfree' + END 'childfree' + TEXT ' with some ' + ELEMENT 'nested' + TEXT 'nested elements' + END 'nested' + TEXT ' and entities "& < >> ' and whitespace ' + END 'e2:foo' + TEXT ' +' + ELEMENT 'tag' + ab="fo + + +Hi & this is some text inside an element Two 'E' chars as character refs: E E and some 'J': J J + Text with some nested elements and entities "& < >> ' and whitespace +This element has attributes + + + \ No newline at end of file diff --git a/glib/tests/markups/valid-10.expected b/glib/tests/markups/valid-10.expected new file mode 100644 index 0000000..e7b8af8 --- /dev/null +++ b/glib/tests/markups/valid-10.expected @@ -0,0 +1,6 @@ +ELEMENT 'foo' +bar="baz" +bar2="baz2" +bar3="baz3" + TEXT 'data' +END 'foo' diff --git a/glib/tests/markups/valid-10.gmarkup b/glib/tests/markups/valid-10.gmarkup new file mode 100644 index 0000000..cbeb68e --- /dev/null +++ b/glib/tests/markups/valid-10.gmarkup @@ -0,0 +1,6 @@ +data diff --git a/glib/tests/markups/valid-11.expected b/glib/tests/markups/valid-11.expected new file mode 100644 index 0000000..7810394 --- /dev/null +++ b/glib/tests/markups/valid-11.expected @@ -0,0 +1,3 @@ +ELEMENT 'foo' + TEXT 'data' +END 'foo' diff --git a/glib/tests/markups/valid-11.gmarkup b/glib/tests/markups/valid-11.gmarkup new file mode 100644 index 0000000..fe1cc4e --- /dev/null +++ b/glib/tests/markups/valid-11.gmarkup @@ -0,0 +1,2 @@ +data diff --git a/glib/tests/markups/valid-12.expected b/glib/tests/markups/valid-12.expected new file mode 100644 index 0000000..49e2aeb --- /dev/null +++ b/glib/tests/markups/valid-12.expected @@ -0,0 +1,5 @@ +ELEMENT 'abcäöü' + TEXT ' +abcäöü +' +END 'abcäöü' diff --git a/glib/tests/markups/valid-12.gmarkup b/glib/tests/markups/valid-12.gmarkup new file mode 100644 index 0000000..34a6dec --- /dev/null +++ b/glib/tests/markups/valid-12.gmarkup @@ -0,0 +1,3 @@ + +abcäöü + diff --git a/glib/tests/markups/valid-13.expected b/glib/tests/markups/valid-13.expected new file mode 100644 index 0000000..84f0e71 --- /dev/null +++ b/glib/tests/markups/valid-13.expected @@ -0,0 +1,4 @@ +ELEMENT 'foo' +bar="a b c d eð€" + TEXT '' +END 'foo' diff --git a/glib/tests/markups/valid-13.gmarkup b/glib/tests/markups/valid-13.gmarkup new file mode 100644 index 0000000..70afdb7 --- /dev/null +++ b/glib/tests/markups/valid-13.gmarkup @@ -0,0 +1,3 @@ + diff --git a/glib/tests/markups/valid-14.expected b/glib/tests/markups/valid-14.expected new file mode 100644 index 0000000..d4b70ec --- /dev/null +++ b/glib/tests/markups/valid-14.expected @@ -0,0 +1,29 @@ +ELEMENT 'foo' + TEXT ' +' + ELEMENT 'bar' + TEXT ' +/* gmarkup.c - Simple XML-like parser + * + * Copyright 2000, 2003 Red Hat, Inc. + * Copyright 2007, 2008 Ryan Lortie + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * GLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * see . + */ +' + END 'bar' + TEXT ' +' +END 'foo' diff --git a/glib/tests/markups/valid-14.gmarkup b/glib/tests/markups/valid-14.gmarkup new file mode 100644 index 0000000..7aee1c5 --- /dev/null +++ b/glib/tests/markups/valid-14.gmarkup @@ -0,0 +1,23 @@ + + +/* gmarkup.c - Simple XML-like parser + * + * Copyright 2000, 2003 Red Hat, Inc. + * Copyright 2007, 2008 Ryan Lortie <desrt@desrt.ca> + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * GLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * see <http://www.gnu.org/licenses/>. + */ + + diff --git a/glib/tests/markups/valid-15.expected b/glib/tests/markups/valid-15.expected new file mode 100644 index 0000000..559c949 --- /dev/null +++ b/glib/tests/markups/valid-15.expected @@ -0,0 +1,3 @@ +ELEMENT 'test' + TEXT 'bla' +END 'test' diff --git a/glib/tests/markups/valid-15.gmarkup b/glib/tests/markups/valid-15.gmarkup new file mode 100644 index 0000000..ba13597 --- /dev/null +++ b/glib/tests/markups/valid-15.gmarkup @@ -0,0 +1 @@ +<bla>bla diff --git a/glib/tests/markups/valid-16.cdata-as-text b/glib/tests/markups/valid-16.cdata-as-text new file mode 100644 index 0000000..ef35ffc --- /dev/null +++ b/glib/tests/markups/valid-16.cdata-as-text @@ -0,0 +1,42 @@ +ELEMENT 'a' + TEXT ' + ' + ELEMENT 'b' + TEXT ' + ' + ELEMENT 'c1' + TEXT 'c1' + END 'c1' + TEXT ' + ' + ELEMENT 'c2' + TEXT 'c2' + END 'c2' + TEXT ' + ' + END 'b' + TEXT ' + ' + ELEMENT 'b1' + TEXT 'b1' + END 'b1' + TEXT ' + ' + ELEMENT 'b2' + TEXT 'b2' + END 'b2' + TEXT ' + ' + ELEMENT 'b3' + TEXT 'b3' + END 'b3' + TEXT ' + ' + ELEMENT 'b4' + TEXT '' + TEXT 'This is CDATA' + TEXT '' + END 'b4' + TEXT ' +' +END 'a' diff --git a/glib/tests/markups/valid-16.expected b/glib/tests/markups/valid-16.expected new file mode 100644 index 0000000..c9eca19 --- /dev/null +++ b/glib/tests/markups/valid-16.expected @@ -0,0 +1,42 @@ +ELEMENT 'a' + TEXT ' + ' + ELEMENT 'b' + TEXT ' + ' + ELEMENT 'c1' + TEXT 'c1' + END 'c1' + TEXT ' + ' + ELEMENT 'c2' + TEXT 'c2' + END 'c2' + TEXT ' + ' + END 'b' + TEXT ' + ' + ELEMENT 'b1' + TEXT 'b1' + END 'b1' + TEXT ' + ' + ELEMENT 'b2' + TEXT 'b2' + END 'b2' + TEXT ' + ' + ELEMENT 'b3' + TEXT 'b3' + END 'b3' + TEXT ' + ' + ELEMENT 'b4' + TEXT '' + PASS '' + TEXT '' + END 'b4' + TEXT ' +' +END 'a' diff --git a/glib/tests/markups/valid-16.gmarkup b/glib/tests/markups/valid-16.gmarkup new file mode 100644 index 0000000..0b67964 --- /dev/null +++ b/glib/tests/markups/valid-16.gmarkup @@ -0,0 +1,10 @@ + + + c1 + c2 + + b1 + b2 + b3 + + diff --git a/glib/tests/markups/valid-17.expected b/glib/tests/markups/valid-17.expected new file mode 100644 index 0000000..b042f4d --- /dev/null +++ b/glib/tests/markups/valid-17.expected @@ -0,0 +1,6 @@ +ELEMENT 'foo' +tab=" " +END 'foo' +ELEMENT 'bar' +tab_character_reference=" " +END 'bar' diff --git a/glib/tests/markups/valid-17.gmarkup b/glib/tests/markups/valid-17.gmarkup new file mode 100644 index 0000000..255b2f4 --- /dev/null +++ b/glib/tests/markups/valid-17.gmarkup @@ -0,0 +1,2 @@ + + diff --git a/glib/tests/markups/valid-2.expected b/glib/tests/markups/valid-2.expected new file mode 100644 index 0000000..82a531a --- /dev/null +++ b/glib/tests/markups/valid-2.expected @@ -0,0 +1,51 @@ +ELEMENT 'foobar' + TEXT ' +Παν語 + +This is a list of ways to say hello in various languages. Its purpose is to illustrate a number of scripts. + +(Converted into UTF-8) + +--------------------------------------------------------- +Arabic السلام عليكم +Czech (Äesky) Dobrý den +Danish (Dansk) Hej, Goddag +English Hello +Esperanto Saluton +Estonian Tere, Tervist +FORTRAN PROGRAM +Finnish (Suomi) Hei +French (Français) Bonjour, Salut +German (Deutsch Nord) Guten Tag +German (Deutsch Süd) Grüß Gott +Greek (Ελληνικά) Γειά σας +Hebrew ×©×œ×•× +Hindi नमसà¥à¤¤à¥‡, नमसà¥à¤•ार। +Italiano Ciao, Buon giorno +Maltese ÄŠaw, Saħħa +Nederlands, Vlaams Hallo, Dag +Norwegian (Norsk) Hei, God dag +Polish DzieÅ„ dobry, Hej +Russian (РуÑÑкий) ЗдравÑтвуйте!‎ +Slovak Dobrý deň +Spanish (Español) ‎¡Hola!‎ +Swedish (Svenska) Hej, Goddag +Thai (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ +Turkish (Türkçe) Merhaba +Vietnamese (Tiếng Việt) Xin Chào +Yiddish (ײַדישע) ד×ָס הײַזעלע + +Japanese (日本語) ã“ã‚“ã«ã¡ã¯, コï¾ï¾†ï¾ï¾Š +Chinese (中文,普通è¯,汉语) 你好 +Cantonese (粵語,廣æ±è©±) 早晨, 你好 +Korean (한글) 안녕하세요, 안녕하십니까 + +Difference among chinese characters in GB, JIS, KSC, BIG5:‎ + GB -- 元气 å¼€å‘ + JIS -- 元気 開発 + KSC -- 元氣 開發 + BIG5 -- 元氣 開發 + + +' +END 'foobar' diff --git a/glib/tests/markups/valid-2.gmarkup b/glib/tests/markups/valid-2.gmarkup new file mode 100644 index 0000000..4a3fa69 --- /dev/null +++ b/glib/tests/markups/valid-2.gmarkup @@ -0,0 +1,49 @@ + +Παν語 + +This is a list of ways to say hello in various languages. Its purpose is to illustrate a number of scripts. + +(Converted into UTF-8) + +--------------------------------------------------------- +Arabic السلام عليكم +Czech (Äesky) Dobrý den +Danish (Dansk) Hej, Goddag +English Hello +Esperanto Saluton +Estonian Tere, Tervist +FORTRAN PROGRAM +Finnish (Suomi) Hei +French (Français) Bonjour, Salut +German (Deutsch Nord) Guten Tag +German (Deutsch Süd) Grüß Gott +Greek (Ελληνικά) Γειά σας +Hebrew ×©×œ×•× +Hindi नमसà¥à¤¤à¥‡, नमसà¥à¤•ार। +Italiano Ciao, Buon giorno +Maltese ÄŠaw, Saħħa +Nederlands, Vlaams Hallo, Dag +Norwegian (Norsk) Hei, God dag +Polish DzieÅ„ dobry, Hej +Russian (РуÑÑкий) ЗдравÑтвуйте!‎ +Slovak Dobrý deň +Spanish (Español) ‎¡Hola!‎ +Swedish (Svenska) Hej, Goddag +Thai (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ +Turkish (Türkçe) Merhaba +Vietnamese (Tiếng Việt) Xin Chào +Yiddish (ײַדישע) ד×ָס הײַזעלע + +Japanese (日本語) ã“ã‚“ã«ã¡ã¯, コï¾ï¾†ï¾ï¾Š +Chinese (中文,普通è¯,汉语) 你好 +Cantonese (粵語,廣æ±è©±) 早晨, 你好 +Korean (한글) 안녕하세요, 안녕하십니까 + +Difference among chinese characters in GB, JIS, KSC, BIG5:‎ + GB -- 元气 å¼€å‘ + JIS -- 元気 開発 + KSC -- 元氣 開發 + BIG5 -- 元氣 開發 + + + \ No newline at end of file diff --git a/glib/tests/markups/valid-3.expected b/glib/tests/markups/valid-3.expected new file mode 100644 index 0000000..9b44653 --- /dev/null +++ b/glib/tests/markups/valid-3.expected @@ -0,0 +1,61 @@ +ELEMENT 'foo' + TEXT ' +' + ELEMENT 'bar' + a="1" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="1" + b="2" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="1" + b="2" + c="3" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="1" + b="2" + c="3" + d="4" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="1" + b="2" + c="3" + d="4" + e="5" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="1" + b="2" + c="3" + d="4" + e="5" + f="6" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="1" + b="2" + c="3" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="1" + END 'bar' + TEXT ' +' +END 'foo' diff --git a/glib/tests/markups/valid-3.gmarkup b/glib/tests/markups/valid-3.gmarkup new file mode 100644 index 0000000..aed984e --- /dev/null +++ b/glib/tests/markups/valid-3.gmarkup @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/glib/tests/markups/valid-4.expected b/glib/tests/markups/valid-4.expected new file mode 100644 index 0000000..395f453 --- /dev/null +++ b/glib/tests/markups/valid-4.expected @@ -0,0 +1,29 @@ +ELEMENT 'foo' + TEXT ' +' + ELEMENT 'bar' + a="1" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="2" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="3"" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="4'" + END 'bar' + TEXT ' +' + ELEMENT 'bar' + a="5''''" + END 'bar' + TEXT ' +' +END 'foo' diff --git a/glib/tests/markups/valid-4.gmarkup b/glib/tests/markups/valid-4.gmarkup new file mode 100644 index 0000000..2036162 --- /dev/null +++ b/glib/tests/markups/valid-4.gmarkup @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/glib/tests/markups/valid-5.expected b/glib/tests/markups/valid-5.expected new file mode 100644 index 0000000..12d05c8 --- /dev/null +++ b/glib/tests/markups/valid-5.expected @@ -0,0 +1,4 @@ +PASS '' +ELEMENT 'foo' + TEXT '' +END 'foo' diff --git a/glib/tests/markups/valid-5.gmarkup b/glib/tests/markups/valid-5.gmarkup new file mode 100644 index 0000000..3b861de --- /dev/null +++ b/glib/tests/markups/valid-5.gmarkup @@ -0,0 +1,2 @@ + + diff --git a/glib/tests/markups/valid-6.expected b/glib/tests/markups/valid-6.expected new file mode 100644 index 0000000..bfb41ce --- /dev/null +++ b/glib/tests/markups/valid-6.expected @@ -0,0 +1,6 @@ +PASS ' +]>' +ELEMENT 'foo' + TEXT '' +END 'foo' diff --git a/glib/tests/markups/valid-6.gmarkup b/glib/tests/markups/valid-6.gmarkup new file mode 100644 index 0000000..d7c065a --- /dev/null +++ b/glib/tests/markups/valid-6.gmarkup @@ -0,0 +1,4 @@ + +]> + diff --git a/glib/tests/markups/valid-7.expected b/glib/tests/markups/valid-7.expected new file mode 100644 index 0000000..2fe1975 --- /dev/null +++ b/glib/tests/markups/valid-7.expected @@ -0,0 +1,4 @@ +PASS '' +ELEMENT 'foo' + TEXT '' +END 'foo' diff --git a/glib/tests/markups/valid-7.gmarkup b/glib/tests/markups/valid-7.gmarkup new file mode 100644 index 0000000..832445d --- /dev/null +++ b/glib/tests/markups/valid-7.gmarkup @@ -0,0 +1,2 @@ + + diff --git a/glib/tests/markups/valid-8.cdata-as-text b/glib/tests/markups/valid-8.cdata-as-text new file mode 100644 index 0000000..e4c4639 --- /dev/null +++ b/glib/tests/markups/valid-8.cdata-as-text @@ -0,0 +1,5 @@ +ELEMENT 'foo' + TEXT '' + TEXT ' some <<<<>>>> CDATA ' + TEXT '' +END 'foo' diff --git a/glib/tests/markups/valid-8.expected b/glib/tests/markups/valid-8.expected new file mode 100644 index 0000000..5bbda04 --- /dev/null +++ b/glib/tests/markups/valid-8.expected @@ -0,0 +1,5 @@ +ELEMENT 'foo' + TEXT '' + PASS '>>> CDATA ]]>' + TEXT '' +END 'foo' diff --git a/glib/tests/markups/valid-8.gmarkup b/glib/tests/markups/valid-8.gmarkup new file mode 100644 index 0000000..a75aee0 --- /dev/null +++ b/glib/tests/markups/valid-8.gmarkup @@ -0,0 +1 @@ +>>> CDATA ]]> diff --git a/glib/tests/markups/valid-9.expected b/glib/tests/markups/valid-9.expected new file mode 100644 index 0000000..7810394 --- /dev/null +++ b/glib/tests/markups/valid-9.expected @@ -0,0 +1,3 @@ +ELEMENT 'foo' + TEXT 'data' +END 'foo' diff --git a/glib/tests/markups/valid-9.gmarkup b/glib/tests/markups/valid-9.gmarkup new file mode 100644 index 0000000..90a99a0 --- /dev/null +++ b/glib/tests/markups/valid-9.gmarkup @@ -0,0 +1,2 @@ +data diff --git a/glib/tests/mem-overflow.c b/glib/tests/mem-overflow.c new file mode 100644 index 0000000..fd92685 --- /dev/null +++ b/glib/tests/mem-overflow.c @@ -0,0 +1,258 @@ +/* Unit tests for g + * Copyright (C) 2010 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +/* We test for errors in optimize-only definitions in gmem.h */ + +#if defined(__GNUC__) && __GNUC__ > 6 +#pragma GCC optimize (1) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Walloc-size-larger-than=" +#endif + +#include "glib.h" +#include + +static gsize a = G_MAXSIZE / 10 + 10; +static gsize b = 10; +typedef char X[10]; + +#define MEM_OVERFLOW_TEST(name, code) MEM_OVERFLOW_TEST_FULL(name, code, g_free) +#define MEM_OVERFLOW_TEST_FULL(name, code, free_func) \ +static void \ +mem_overflow_ ## name (void) \ +{ \ + gpointer p; \ + code; \ + free_func (p); \ + exit (0); \ +} + +MEM_OVERFLOW_TEST (malloc_n_a_a, p = g_malloc_n (a, a)) +MEM_OVERFLOW_TEST (malloc_n_a_b, p = g_malloc_n (a, b)) +MEM_OVERFLOW_TEST (malloc_n_b_a, p = g_malloc_n (b, a)) +MEM_OVERFLOW_TEST (malloc_n_b_b, p = g_malloc_n (b, b)) + +MEM_OVERFLOW_TEST (malloc0_n_a_a, p = g_malloc0_n (a, a)) +MEM_OVERFLOW_TEST (malloc0_n_a_b, p = g_malloc0_n (a, b)) +MEM_OVERFLOW_TEST (malloc0_n_b_a, p = g_malloc0_n (b, a)) +MEM_OVERFLOW_TEST (malloc0_n_b_b, p = g_malloc0_n (b, b)) + +MEM_OVERFLOW_TEST (realloc_n_a_a, p = g_malloc (1); p = g_realloc_n (p, a, a)) +MEM_OVERFLOW_TEST (realloc_n_a_b, p = g_malloc (1); p = g_realloc_n (p, a, b)) +MEM_OVERFLOW_TEST (realloc_n_b_a, p = g_malloc (1); p = g_realloc_n (p, b, a)) +MEM_OVERFLOW_TEST (realloc_n_b_b, p = g_malloc (1); p = g_realloc_n (p, b, b)) + +MEM_OVERFLOW_TEST (new_a, p = g_new (X, a)) +MEM_OVERFLOW_TEST (new_b, p = g_new (X, b)) + +MEM_OVERFLOW_TEST (new0_a, p = g_new0 (X, a)) +MEM_OVERFLOW_TEST (new0_b, p = g_new0 (X, b)) + +MEM_OVERFLOW_TEST (renew_a, p = g_malloc (1); p = g_renew (X, p, a)) +MEM_OVERFLOW_TEST (renew_b, p = g_malloc (1); p = g_renew (X, p, b)) + +MEM_OVERFLOW_TEST_FULL (aligned_alloc_a, p = g_aligned_alloc (sizeof(X), a, 16), g_aligned_free) +MEM_OVERFLOW_TEST_FULL (aligned_alloc_b, p = g_aligned_alloc (sizeof(X), b, 16), g_aligned_free) + +MEM_OVERFLOW_TEST_FULL (aligned_alloc0_a, p = g_aligned_alloc0 (sizeof(X), a, 16), g_aligned_free) +MEM_OVERFLOW_TEST_FULL (aligned_alloc0_b, p = g_aligned_alloc0 (sizeof(X), b, 16), g_aligned_free) + +static void +mem_overflow_malloc_0 (void) +{ + gpointer p; + + p = g_malloc (0); + g_assert (p == NULL); +} + +static void +mem_overflow_realloc_0 (void) +{ + gpointer p; + + p = g_malloc (10); + g_assert (p != NULL); + p = g_realloc (p, 0); + g_assert (p == NULL); +} + +static void +mem_overflow (void) +{ + gpointer p, q; + + /* "FAIL" here apparently means "fail to overflow"... */ +#define CHECK_PASS(P) p = (P); g_assert (p == NULL); +#define CHECK_FAIL(P) p = (P); g_assert (p != NULL); + + CHECK_PASS (g_try_malloc_n (a, a)); + CHECK_PASS (g_try_malloc_n (a, b)); + CHECK_PASS (g_try_malloc_n (b, a)); + CHECK_FAIL (g_try_malloc_n (b, b)); + g_free (p); + + CHECK_PASS (g_try_malloc0_n (a, a)); + CHECK_PASS (g_try_malloc0_n (a, b)); + CHECK_PASS (g_try_malloc0_n (b, a)); + CHECK_FAIL (g_try_malloc0_n (b, b)); + g_free (p); + + q = g_malloc (1); + CHECK_PASS (g_try_realloc_n (q, a, a)); + CHECK_PASS (g_try_realloc_n (q, a, b)); + CHECK_PASS (g_try_realloc_n (q, b, a)); + CHECK_FAIL (g_try_realloc_n (q, b, b)); + g_free (p); + + CHECK_PASS (g_try_new (X, a)); + CHECK_FAIL (g_try_new (X, b)); + g_free (p); + + CHECK_PASS (g_try_new0 (X, a)); + CHECK_FAIL (g_try_new0 (X, b)); + g_free (p); + + q = g_try_malloc (1); + CHECK_PASS (g_try_renew (X, q, a)); + CHECK_FAIL (g_try_renew (X, q, b)); + free (p); + +#define CHECK_SUBPROCESS_FAIL(name) do { \ + if (g_test_undefined ()) \ + { \ + g_test_trap_subprocess ("/mem/overflow/subprocess/" #name, 0, 0); \ + g_test_trap_assert_failed(); \ + } \ + } while (0) + +#define CHECK_SUBPROCESS_PASS(name) do { \ + if (g_test_undefined ()) \ + { \ + g_test_trap_subprocess ("/mem/overflow/subprocess/" #name, 0, 0); \ + g_test_trap_assert_passed(); \ + } \ + } while (0) + + CHECK_SUBPROCESS_FAIL (malloc_n_a_a); + CHECK_SUBPROCESS_FAIL (malloc_n_a_b); + CHECK_SUBPROCESS_FAIL (malloc_n_b_a); + CHECK_SUBPROCESS_PASS (malloc_n_b_b); + + CHECK_SUBPROCESS_FAIL (malloc0_n_a_a); + CHECK_SUBPROCESS_FAIL (malloc0_n_a_b); + CHECK_SUBPROCESS_FAIL (malloc0_n_b_a); + CHECK_SUBPROCESS_PASS (malloc0_n_b_b); + + CHECK_SUBPROCESS_FAIL (realloc_n_a_a); + CHECK_SUBPROCESS_FAIL (realloc_n_a_b); + CHECK_SUBPROCESS_FAIL (realloc_n_b_a); + CHECK_SUBPROCESS_PASS (realloc_n_b_b); + + CHECK_SUBPROCESS_FAIL (new_a); + CHECK_SUBPROCESS_PASS (new_b); + + CHECK_SUBPROCESS_FAIL (new0_a); + CHECK_SUBPROCESS_PASS (new0_b); + + CHECK_SUBPROCESS_FAIL (renew_a); + CHECK_SUBPROCESS_PASS (renew_b); + + CHECK_SUBPROCESS_PASS (malloc_0); + CHECK_SUBPROCESS_PASS (realloc_0); + + CHECK_SUBPROCESS_FAIL (aligned_alloc_a); + CHECK_SUBPROCESS_PASS (aligned_alloc_b); + + CHECK_SUBPROCESS_FAIL (aligned_alloc0_a); + CHECK_SUBPROCESS_PASS (aligned_alloc0_b); +} + +#ifdef __GNUC__ +typedef struct +{ +} Empty; + +static void +empty_alloc_subprocess (void) +{ + Empty *empty; + + empty = g_new0 (Empty, 1); + g_assert (empty == NULL); + exit (0); +} + +static void +empty_alloc (void) +{ + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=615379"); + + g_assert_cmpint (sizeof (Empty), ==, 0); + + g_test_trap_subprocess ("/mem/empty-alloc/subprocess", 0, 0); + g_test_trap_assert_passed (); +} +#endif + +#if defined(__GNUC__) && __GNUC__ > 6 +#pragma GCC diagnostic pop +#endif + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/mem/overflow", mem_overflow); + g_test_add_func ("/mem/overflow/subprocess/malloc_n_a_a", mem_overflow_malloc_n_a_a); + g_test_add_func ("/mem/overflow/subprocess/malloc_n_a_b", mem_overflow_malloc_n_a_b); + g_test_add_func ("/mem/overflow/subprocess/malloc_n_b_a", mem_overflow_malloc_n_b_a); + g_test_add_func ("/mem/overflow/subprocess/malloc_n_b_b", mem_overflow_malloc_n_b_b); + g_test_add_func ("/mem/overflow/subprocess/malloc0_n_a_a", mem_overflow_malloc0_n_a_a); + g_test_add_func ("/mem/overflow/subprocess/malloc0_n_a_b", mem_overflow_malloc0_n_a_b); + g_test_add_func ("/mem/overflow/subprocess/malloc0_n_b_a", mem_overflow_malloc0_n_b_a); + g_test_add_func ("/mem/overflow/subprocess/malloc0_n_b_b", mem_overflow_malloc0_n_b_b); + g_test_add_func ("/mem/overflow/subprocess/realloc_n_a_a", mem_overflow_realloc_n_a_a); + g_test_add_func ("/mem/overflow/subprocess/realloc_n_a_b", mem_overflow_realloc_n_a_b); + g_test_add_func ("/mem/overflow/subprocess/realloc_n_b_a", mem_overflow_realloc_n_b_a); + g_test_add_func ("/mem/overflow/subprocess/realloc_n_b_b", mem_overflow_realloc_n_b_b); + g_test_add_func ("/mem/overflow/subprocess/new_a", mem_overflow_new_a); + g_test_add_func ("/mem/overflow/subprocess/new_b", mem_overflow_new_b); + g_test_add_func ("/mem/overflow/subprocess/new0_a", mem_overflow_new0_a); + g_test_add_func ("/mem/overflow/subprocess/new0_b", mem_overflow_new0_b); + g_test_add_func ("/mem/overflow/subprocess/renew_a", mem_overflow_renew_a); + g_test_add_func ("/mem/overflow/subprocess/renew_b", mem_overflow_renew_b); + g_test_add_func ("/mem/overflow/subprocess/malloc_0", mem_overflow_malloc_0); + g_test_add_func ("/mem/overflow/subprocess/realloc_0", mem_overflow_realloc_0); + g_test_add_func ("/mem/overflow/subprocess/aligned_alloc_a", mem_overflow_aligned_alloc_a); + g_test_add_func ("/mem/overflow/subprocess/aligned_alloc_b", mem_overflow_aligned_alloc_b); + g_test_add_func ("/mem/overflow/subprocess/aligned_alloc0_a", mem_overflow_aligned_alloc0_a); + g_test_add_func ("/mem/overflow/subprocess/aligned_alloc0_b", mem_overflow_aligned_alloc0_b); + +#ifdef __GNUC__ + g_test_add_func ("/mem/empty-alloc", empty_alloc); + g_test_add_func ("/mem/empty-alloc/subprocess", empty_alloc_subprocess); +#endif + + return g_test_run(); +} diff --git a/glib/tests/memchunk.c b/glib/tests/memchunk.c new file mode 100644 index 0000000..8c13787 --- /dev/null +++ b/glib/tests/memchunk.c @@ -0,0 +1,64 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +static void +test_basic (void) +{ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + + GMemChunk *mem_chunk = g_mem_chunk_new ("test mem chunk", 50, 100, G_ALLOC_AND_FREE); + gchar *mem[10000]; + guint i; + for (i = 0; i < 10000; i++) + { + guint j; + mem[i] = g_chunk_new (gchar, mem_chunk); + for (j = 0; j < 50; j++) + mem[i][j] = i * j; + } + for (i = 0; i < 10000; i++) + g_mem_chunk_free (mem_chunk, mem[i]); + + g_mem_chunk_destroy (mem_chunk); + + G_GNUC_END_IGNORE_DEPRECATIONS +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/memchunk/basic", test_basic); + + return g_test_run (); +} diff --git a/glib/tests/meson.build b/glib/tests/meson.build new file mode 100644 index 0000000..48d12d7 --- /dev/null +++ b/glib/tests/meson.build @@ -0,0 +1,326 @@ +glib_tests = { + 'array-test' : {}, + 'asyncqueue' : {}, + 'atomic' : { + 'c_args' : cc.get_id() == 'gcc' ? ['-Wstrict-aliasing=2'] : [], + }, + 'base64' : {}, + 'bitlock' : {}, + 'bookmarkfile' : {}, + 'bytes' : {}, + 'cache' : {}, + 'charset' : {}, + 'checksum' : {}, + 'collate' : {}, + 'completion' : {}, + 'cond' : {}, + 'convert' : {}, + 'dataset' : {}, + 'date' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'dir' : {}, + 'environment' : { + # FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/1392 + 'should_fail' : host_system == 'darwin', + }, + 'error' : {}, + 'fileutils' : {}, + 'gdatetime' : { + 'suite' : ['slow'], + }, + 'guuid' : {}, + 'gvariant' : { + 'suite' : ['slow'], + }, + 'gwakeup' : { + 'source' : ['gwakeuptest.c', '../gwakeup.c'], + 'install' : false, + }, + 'hash' : {}, + 'hmac' : {}, + 'hook' : {}, + 'hostutils' : {}, + 'io-channel' : {}, + 'keyfile' : {}, + 'list' : {}, + 'logging' : {}, + 'macros' : {}, + 'mainloop' : {}, + 'mappedfile' : {}, + 'markup' : {}, + 'markup-parse' : {}, + 'markup-collect' : {}, + 'markup-escape' : {}, + 'markup-subparser' : {}, + 'memchunk' : {}, + 'mem-overflow' : { + 'link_args' : cc.get_id() == 'gcc' and cc.version().version_compare('> 6') + ? ['-Wno-alloc-size-larger-than'] : [], + }, + 'mutex' : {}, + 'node' : {}, + 'once' : {}, + 'option-context' : {}, + 'option-argv0' : {}, + 'overflow' : {}, + 'overflow-fallback' : { + 'source' : 'overflow.c', + 'c_args' : ['-D_GLIB_TEST_OVERFLOW_FALLBACK'], + }, + 'pattern' : {}, + 'private' : {}, + 'protocol' : {}, + 'queue' : {}, + 'rand' : {}, + 'rcbox' : {}, + 'rec-mutex' : {}, + 'refcount' : {}, + 'refcount-macro' : { + 'source' : 'refcount.c', + 'c_args' : ['-DG_DISABLE_CHECKS'], + }, + 'refstring' : {}, + 'regex' : { + 'dependencies' : [pcre], + 'c_args' : use_pcre_static_flag ? ['-DPCRE_STATIC'] : [], + }, + 'relation' : {}, + 'rwlock' : {}, + 'scannerapi' : {}, + 'search-utils' : {}, + 'sequence' : { + 'suite' : ['slow'], + }, + 'shell' : {}, + 'slice' : {}, + 'slice-color' : { + 'extra_sources' : ['memchunks.c'], + }, + 'slice-concurrent' : {}, + 'slist' : {}, + 'sort' : {}, + 'spawn-multithreaded' : {}, + 'spawn-path-search' : {}, + 'spawn-singlethread' : {}, + 'strfuncs' : {}, + 'string' : {}, + 'strvbuilder' : {}, + 'testing' : {}, + 'test-printf' : {}, + 'thread' : {}, + 'thread-pool' : {}, + 'timeout' : {}, + 'timer' : {}, + 'tree' : {}, + 'types' : {}, + 'utf8-performance' : {}, + 'utf8-pointer' : {}, + 'utf8-validate' : {}, + 'utf8-misc' : {}, + 'utils' : {}, + 'unicode' : {}, + 'uri' : {}, + '1bit-mutex' : {}, + '1bit-emufutex' : { + 'source' : '1bit-mutex.c', + 'c_args' : ['-DTEST_EMULATED_FUTEX'], + 'install' : false, + 'suite' : ['slow'], + }, + '642026' : { + 'suite' : ['slow'], + }, + '642026-ec' : { + 'source' : '642026.c', + 'c_args' : ['-DG_ERRORCHECK_MUTEXES'], + 'suite' : ['slow'], + }, +} + +if have_cxx + glib_tests += { + 'cxx' : { + 'source' : ['cxx.cpp'], + } + } +endif + +if cc.get_id() != 'msvc' + glib_tests += {'autoptr' : {}} +endif + +if glib_conf.has('HAVE_EVENTFD') + glib_tests += { + 'gwakeup-fallback' : { + 'source' : ['gwakeuptest.c', '../gwakeup.c'], + 'c_args' : ['-DTEST_EVENTFD_FALLBACK'], + 'install' : false, + }, + } +endif + +if host_machine.system() == 'windows' + if winsock2.found() + glib_tests += { + 'gpoll' : { + 'dependencies' : [winsock2], + }, + } + endif + glib_tests += { + 'win32' : {}, + } +else + glib_tests += { + 'include' : {}, + 'unix' : {}, + } + if have_rtld_next + glib_tests += { + 'gutils-user-database' : { + 'depends' : [ + shared_library('getpwuid-preload', + 'getpwuid-preload.c', + name_prefix : '', + dependencies: libdl_dep, + install_dir : installed_tests_execdir, + install: installed_tests_enabled, + ), + ], + 'env' : { + 'LD_PRELOAD': '@0@/getpwuid-preload.so'.format(meson.current_build_dir()), + }, + 'installed_tests_env' : { + 'LD_PRELOAD': '@0@/getpwuid-preload.so'.format(installed_tests_execdir), + }, + }, + } + endif +endif + +if installed_tests_enabled + install_data( + '4096-random-bytes', + 'casefold.txt', + 'casemap.txt', + 'echo-script', + 'echo-script.bat', + 'empty', + 'iochannel-test-infile', + 'keyfile.c', + 'keyfiletest.ini', + 'pages.ini', + install_dir : installed_tests_execdir, + ) + install_subdir('bookmarks', install_dir : installed_tests_execdir) + install_subdir('markups', install_dir : installed_tests_execdir) + install_subdir('time-zones', install_dir : installed_tests_execdir) +endif + +# Not entirely random of course, but at least it changes over time +random_number = minor_version + meson.version().split('.').get(1).to_int() + +test_env = environment() +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +test_env.set('G_DEBUG', 'gc-friendly') +test_env.set('MALLOC_CHECK_', '2') +test_env.set('MALLOC_PERTURB_', '@0@'.format(random_number % 256)) + +test_deps = [libm, thread_dep, libglib_dep] +test_cargs = ['-DG_LOG_DOMAIN="GLib"', '-UG_DISABLE_ASSERT'] + +foreach test_name, extra_args : glib_tests + source = extra_args.get('source', test_name + '.c') + install = installed_tests_enabled and extra_args.get('install', true) + + if install + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_conf.set('env', '') + configure_file( + input: installed_tests_template_tap, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf + ) + endif + + exe = executable(test_name, source, + c_args : test_cargs + extra_args.get('c_args', []), + link_args : extra_args.get('link_args', []), + dependencies : test_deps + extra_args.get('dependencies', []), + install_dir: installed_tests_execdir, + install: install, + ) + + suite = ['glib'] + extra_args.get('suite', []) + timeout = suite.contains('slow') ? test_timeout_slow : test_timeout + test(test_name, exe, + env : test_env, + timeout : timeout, + suite : suite, + should_fail : extra_args.get('should_fail', false), + ) +endforeach + +executable('spawn-path-search-helper', 'spawn-path-search-helper.c', + c_args : test_cargs, + dependencies : test_deps, + install_dir: installed_tests_execdir, + install: installed_tests_enabled, +) + +executable('spawn-test-helper', 'spawn-test-helper.c', + c_args : test_cargs, + dependencies : test_deps, + install_dir: installed_tests_execdir, + install: installed_tests_enabled, +) + +# test-spawn-echo helper binary required by the spawn tests above +executable('test-spawn-echo', 'test-spawn-echo.c', + c_args : test_cargs, + dependencies : test_deps, + install_dir: installed_tests_execdir, + install: installed_tests_enabled, +) + +if host_machine.system() == 'windows' + # test-spawn-sleep helper binary required by the spawn tests above + executable('test-spawn-sleep', 'test-spawn-sleep.c', + c_args : test_cargs, + dependencies : test_deps, + install_dir: installed_tests_execdir, + install: installed_tests_enabled, + ) +endif + +executable('testing-helper', 'testing-helper.c', + c_args : test_cargs, + dependencies : test_deps, + install_dir: installed_tests_execdir, + install: installed_tests_enabled, +) + +# some testing of gtester functionality +if not meson.is_cross_build() and host_system != 'windows' + xmllint = find_program('xmllint', required: false) + if xmllint.found() + tmpsample_xml = custom_target('tmpsample.xml', + output : 'tmpsample.xml', + command : [ gtester, '-k', '--quiet', '--i-know-this-is-deprecated', '-o', '@OUTPUT@', + '--test-arg=--gtester-selftest', gtester]) + + test('gtester-xmllint-check', xmllint, + args : ['--noout', tmpsample_xml], + env : test_env, + suite : ['glib'], + ) + endif +endif + +subdir('path-test-subdir') diff --git a/glib/tests/mutex.c b/glib/tests/mutex.c new file mode 100644 index 0000000..a5ba2ea --- /dev/null +++ b/glib/tests/mutex.c @@ -0,0 +1,241 @@ +/* Unit tests for GMutex + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +#include + +static void +test_mutex1 (void) +{ + GMutex mutex; + + g_mutex_init (&mutex); + g_mutex_lock (&mutex); + g_mutex_unlock (&mutex); + g_mutex_lock (&mutex); + g_mutex_unlock (&mutex); + g_mutex_clear (&mutex); +} + +static void +test_mutex2 (void) +{ + static GMutex mutex; + + g_mutex_lock (&mutex); + g_mutex_unlock (&mutex); + g_mutex_lock (&mutex); + g_mutex_unlock (&mutex); +} + +static void +test_mutex3 (void) +{ + GMutex *mutex; + + mutex = g_mutex_new (); + g_mutex_lock (mutex); + g_mutex_unlock (mutex); + g_mutex_lock (mutex); + g_mutex_unlock (mutex); + g_mutex_free (mutex); +} + +static void +test_mutex4 (void) +{ + static GMutex mutex; + gboolean ret; + + ret = g_mutex_trylock (&mutex); + g_assert (ret); + + /* no guarantees that mutex is recursive, so could return 0 or 1 */ + if (g_mutex_trylock (&mutex)) + g_mutex_unlock (&mutex); + + g_mutex_unlock (&mutex); +} + +#define LOCKS 48 +#define ITERATIONS 10000 +#define THREADS 100 + + +GThread *owners[LOCKS]; +GMutex locks[LOCKS]; + +static void +acquire (gint nr) +{ + GThread *self; + + self = g_thread_self (); + + if (!g_mutex_trylock (&locks[nr])) + { + if (g_test_verbose ()) + g_printerr ("thread %p going to block on lock %d\n", self, nr); + + g_mutex_lock (&locks[nr]); + } + + g_assert (owners[nr] == NULL); /* hopefully nobody else is here */ + owners[nr] = self; + + /* let some other threads try to ruin our day */ + g_thread_yield (); + g_thread_yield (); + g_thread_yield (); + + g_assert (owners[nr] == self); /* hopefully this is still us... */ + owners[nr] = NULL; /* make way for the next guy */ + + g_mutex_unlock (&locks[nr]); +} + +static gpointer +thread_func (gpointer data) +{ + gint i; + GRand *rand; + + rand = g_rand_new (); + + for (i = 0; i < ITERATIONS; i++) + acquire (g_rand_int_range (rand, 0, LOCKS)); + + g_rand_free (rand); + + return NULL; +} + +static void +test_mutex5 (void) +{ + gint i; + GThread *threads[THREADS]; + + for (i = 0; i < LOCKS; i++) + g_mutex_init (&locks[i]); + + for (i = 0; i < THREADS; i++) + threads[i] = g_thread_create (thread_func, NULL, TRUE, NULL); + + for (i = 0; i < THREADS; i++) + g_thread_join (threads[i]); + + for (i = 0; i < LOCKS; i++) + g_mutex_clear (&locks[i]); + + for (i = 0; i < LOCKS; i++) + g_assert (owners[i] == NULL); +} + +#define COUNT_TO 100000000 + +static gboolean +do_addition (gint *value) +{ + static GMutex lock; + gboolean more; + + /* test performance of "good" cases (ie: short critical sections) */ + g_mutex_lock (&lock); + if ((more = *value != COUNT_TO)) + if (*value != -1) + (*value)++; + g_mutex_unlock (&lock); + + return more; +} + +static gpointer +addition_thread (gpointer value) +{ + while (do_addition (value)); + + return NULL; +} + +static void +test_mutex_perf (gconstpointer data) +{ + guint n_threads = GPOINTER_TO_UINT (data); + GThread *threads[THREADS]; + gint64 start_time; + gdouble rate; + gint x = -1; + guint i; + + g_assert (n_threads <= G_N_ELEMENTS (threads)); + + for (i = 0; n_threads > 0 && i < n_threads - 1; i++) + threads[i] = g_thread_create (addition_thread, &x, TRUE, NULL); + + /* avoid measuring thread setup/teardown time */ + start_time = g_get_monotonic_time (); + g_atomic_int_set (&x, 0); + addition_thread (&x); + g_assert_cmpint (g_atomic_int_get (&x), ==, COUNT_TO); + rate = g_get_monotonic_time () - start_time; + rate = x / rate; + + for (i = 0; n_threads > 0 && i < n_threads - 1; i++) + g_thread_join (threads[i]); + + g_test_maximized_result (rate, "%f mips", rate); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/thread/mutex1", test_mutex1); + g_test_add_func ("/thread/mutex2", test_mutex2); + g_test_add_func ("/thread/mutex3", test_mutex3); + g_test_add_func ("/thread/mutex4", test_mutex4); + g_test_add_func ("/thread/mutex5", test_mutex5); + + if (g_test_perf ()) + { + guint i; + + g_test_add_data_func ("/thread/mutex/perf/uncontended", GUINT_TO_POINTER (0), test_mutex_perf); + + for (i = 1; i <= 10; i++) + { + gchar name[80]; + sprintf (name, "/thread/mutex/perf/contended/%u", i); + g_test_add_data_func (name, GUINT_TO_POINTER (i), test_mutex_perf); + } + } + + return g_test_run (); +} diff --git a/glib/tests/node.c b/glib/tests/node.c new file mode 100644 index 0000000..e75821c --- /dev/null +++ b/glib/tests/node.c @@ -0,0 +1,522 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include + +#include "glib.h" + +typedef struct { + GString *s; + gint count; +} CallbackData; + +static gboolean +node_build_string (GNode *node, + gpointer data) +{ + CallbackData *d = data; + + g_string_append_c (d->s, GPOINTER_TO_INT (node->data)); + + d->count--; + + if (d->count == 0) + return TRUE; + + return FALSE; +} + +typedef struct { + GTraverseType traverse; + GTraverseFlags flags; + gint depth; + gint limit; + const gchar *expected; +} TraverseData; + +static void +traversal_test (void) +{ + GNode *root; + GNode *node_B; + GNode *node_C; + GNode *node_D; + GNode *node_E; + GNode *node_F; + GNode *node_G; + GNode *node_J; + GNode *n; + TraverseData orders[] = { + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, -1, "ABCDEFGHIJK" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 1, -1, "A" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 2, -1, "ABF" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, -1, "ABCDEFG" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, -1, "ABCDEFG" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, -1, "CDEBHIJKGFA" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 1, -1, "A" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 2, -1, "BFA" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, -1, "CDEBGFA" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, -1, "CBDEAHGIJKF" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 1, -1, "A" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 2, -1, "BAF" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, -1, "CBDEAGF" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, -1, "ABFCDEGHIJK" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 1, -1, "A" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 2, -1, "ABF" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, -1, "ABFCDEG" }, + { G_LEVEL_ORDER, G_TRAVERSE_LEAFS, -1, -1, "CDEHIJK" }, + { G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, -1, -1, "ABFG" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 1, "A" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 2, "AB" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 3, "ABC" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 4, "ABCD" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 5, "ABCDE" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 6, "ABCDEF" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 7, "ABCDEFG" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 8, "ABCDEFGH" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 9, "ABCDEFGHI" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, -1, 10, "ABCDEFGHIJ" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 1, "A" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 2, "AB" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 3, "ABC" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 4, "ABCD" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 5, "ABCDE" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 6, "ABCDEF" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 7, "ABCDEFG" }, + { G_PRE_ORDER, G_TRAVERSE_ALL, 3, 8, "ABCDEFG" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 1, "C" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 2, "CD" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 3, "CDE" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 4, "CDEB" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 5, "CDEBH" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 6, "CDEBHI" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 7, "CDEBHIJ" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 8, "CDEBHIJK" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 9, "CDEBHIJKG" }, + { G_POST_ORDER, G_TRAVERSE_ALL, -1, 10, "CDEBHIJKGF" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, 1, "C" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, 2, "CD" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, 3, "CDE" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, 4, "CDEB" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, 5, "CDEBG" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, 6, "CDEBGF" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, 7, "CDEBGFA" }, + { G_POST_ORDER, G_TRAVERSE_ALL, 3, 8, "CDEBGFA" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 1, "C" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 2, "CB" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 3, "CBD" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 4, "CBDE" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 5, "CBDEA" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 6, "CBDEAH" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 7, "CBDEAHG" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 8, "CBDEAHGI" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 9, "CBDEAHGIJ" }, + { G_IN_ORDER, G_TRAVERSE_ALL, -1, 10, "CBDEAHGIJK" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, 1, "C" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, 2, "CB" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, 3, "CBD" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, 4, "CBDE" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, 5, "CBDEA" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, 6, "CBDEAG" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, 7, "CBDEAGF" }, + { G_IN_ORDER, G_TRAVERSE_ALL, 3, 8, "CBDEAGF" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 1, "A" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 2, "AB" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 3, "ABF" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 4, "ABFC" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 5, "ABFCD" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 6, "ABFCDE" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 7, "ABFCDEG" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 8, "ABFCDEGH" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 9, "ABFCDEGHI" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, 10, "ABFCDEGHIJ" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 1, "A" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 2, "AB" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 3, "ABF" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 4, "ABFC" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 5, "ABFCD" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 6, "ABFCDE" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 7, "ABFCDEG" }, + { G_LEVEL_ORDER, G_TRAVERSE_ALL, 3, 8, "ABFCDEG" }, + }; + gsize i; + CallbackData data; + + root = g_node_new (GINT_TO_POINTER ('A')); + node_B = g_node_new (GINT_TO_POINTER ('B')); + g_node_append (root, node_B); + g_node_append_data (node_B, GINT_TO_POINTER ('E')); + g_node_prepend_data (node_B, GINT_TO_POINTER ('C')); + node_D = g_node_new (GINT_TO_POINTER ('D')); + g_node_insert (node_B, 1, node_D); + node_F = g_node_new (GINT_TO_POINTER ('F')); + g_node_append (root, node_F); + node_G = g_node_new (GINT_TO_POINTER ('G')); + g_node_append (node_F, node_G); + node_J = g_node_new (GINT_TO_POINTER ('J')); + g_node_prepend (node_G, node_J); + g_node_insert (node_G, 42, g_node_new (GINT_TO_POINTER ('K'))); + g_node_insert_data (node_G, 0, GINT_TO_POINTER ('H')); + g_node_insert (node_G, 1, g_node_new (GINT_TO_POINTER ('I'))); + + /* we have built: A + * / \ + * B F + * / | \ \ + * C D E G + * / /\ \ + * H I J K + * + * for in-order traversal, 'G' is considered to be the "left" + * child of 'F', which will cause 'F' to be the last node visited. + */ + + node_C = node_B->children; + node_E = node_D->next; + + n = g_node_last_sibling (node_C); + g_assert (n == node_E); + n = g_node_last_sibling (node_D); + g_assert (n == node_E); + n = g_node_last_sibling (node_E); + g_assert (n == node_E); + + data.s = g_string_new (""); + for (i = 0; i < G_N_ELEMENTS (orders); i++) + { + g_string_set_size (data.s, 0); + data.count = orders[i].limit; + g_node_traverse (root, orders[i].traverse, orders[i].flags, orders[i].depth, node_build_string, &data); + g_assert_cmpstr (data.s->str, ==, orders[i].expected); + } + + g_node_reverse_children (node_B); + g_node_reverse_children (node_G); + + g_string_set_size (data.s, 0); + data.count = -1; + g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &data); + g_assert_cmpstr (data.s->str, ==, "ABFEDCGKJIH"); + + g_node_append (node_D, g_node_new (GINT_TO_POINTER ('L'))); + g_node_insert (node_D, -1, g_node_new (GINT_TO_POINTER ('M'))); + + g_string_set_size (data.s, 0); + data.count = -1; + g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &data); + g_assert_cmpstr (data.s->str, ==, "ABFEDCGLMKJIH"); + + g_string_set_size (data.s, 0); + data.count = -1; + g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_LEAFS, -1, node_build_string, &data); + g_assert_cmpstr (data.s->str, ==, "ELMCKJIH"); + + g_string_set_size (data.s, 0); + data.count = -1; + g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_NON_LEAFS, -1, node_build_string, &data); + g_assert_cmpstr (data.s->str, ==, "ABDFG"); + + g_node_destroy (root); + g_string_free (data.s, TRUE); +} + +static void +construct_test (void) +{ + GNode *root; + GNode *node; + GNode *node_B; + GNode *node_D; + GNode *node_F; + GNode *node_G; + GNode *node_J; + GNode *node_H; + guint i; + + root = g_node_new (GINT_TO_POINTER ('A')); + g_assert_cmpint (g_node_depth (root), ==, 1); + g_assert_cmpint (g_node_max_height (root), ==, 1); + + node_B = g_node_new (GINT_TO_POINTER ('B')); + g_node_append (root, node_B); + g_assert (root->children == node_B); + + g_node_append_data (node_B, GINT_TO_POINTER ('E')); + g_node_prepend_data (node_B, GINT_TO_POINTER ('C')); + node_D = g_node_new (GINT_TO_POINTER ('D')); + g_node_insert (node_B, 1, node_D); + + node_F = g_node_new (GINT_TO_POINTER ('F')); + g_node_append (root, node_F); + g_assert (root->children->next == node_F); + + node_G = g_node_new (GINT_TO_POINTER ('G')); + g_node_append (node_F, node_G); + node_J = g_node_new (GINT_TO_POINTER ('J')); + g_node_insert_after (node_G, NULL, node_J); + g_node_insert (node_G, 42, g_node_new (GINT_TO_POINTER ('K'))); + node_H = g_node_new (GINT_TO_POINTER ('H')); + g_node_insert_after (node_G, NULL, node_H); + g_node_insert (node_G, 1, g_node_new (GINT_TO_POINTER ('I'))); + + /* we have built: A + * / \ + * B F + * / | \ \ + * C D E G + * / /\ \ + * H I J K + */ + g_assert_cmpint (g_node_depth (root), ==, 1); + g_assert_cmpint (g_node_max_height (root), ==, 4); + g_assert_cmpint (g_node_depth (node_G->children->next), ==, 4); + g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_LEAFS), ==, 7); + g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_NON_LEAFS), ==, 4); + g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_ALL), ==, 11); + g_assert_cmpint (g_node_max_height (node_F), ==, 3); + g_assert_cmpint (g_node_n_children (node_G), ==, 4); + g_assert (g_node_find_child (root, G_TRAVERSE_ALL, GINT_TO_POINTER ('F')) == node_F); + g_assert (g_node_find_child (node_G, G_TRAVERSE_LEAFS, GINT_TO_POINTER ('H')) == node_H); + g_assert (g_node_find_child (root, G_TRAVERSE_ALL, GINT_TO_POINTER ('H')) == NULL); + g_assert (g_node_find (root, G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, GINT_TO_POINTER ('I')) == NULL); + g_assert (g_node_find (root, G_IN_ORDER, G_TRAVERSE_LEAFS, GINT_TO_POINTER ('J')) == node_J); + + for (i = 0; i < g_node_n_children (node_B); i++) + { + node = g_node_nth_child (node_B, i); + g_assert_cmpint (GPOINTER_TO_INT (node->data), ==, ('C' + i)); + } + + for (i = 0; i < g_node_n_children (node_G); i++) + g_assert_cmpint (g_node_child_position (node_G, g_node_nth_child (node_G, i)), ==, i); + + g_node_destroy (root); +} + +static void +allocation_test (void) +{ + GNode *root; + GNode *node; + gint i; + + root = g_node_new (NULL); + node = root; + + for (i = 0; i < 2048; i++) + { + g_node_append (node, g_node_new (NULL)); + if ((i % 5) == 4) + node = node->children->next; + } + g_assert_cmpint (g_node_max_height (root), >, 100); + g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_ALL), ==, 1 + 2048); + + g_node_destroy (root); +} + + +static void +misc_test (void) +{ + GNode *root; + GNode *node_B; + GNode *node_C; + GNode *node_D; + GNode *node_E; + CallbackData data; + + root = g_node_new (GINT_TO_POINTER ('A')); + node_B = g_node_new (GINT_TO_POINTER ('B')); + g_node_append (root, node_B); + node_D = g_node_new (GINT_TO_POINTER ('D')); + g_node_append (root, node_D); + node_C = g_node_new (GINT_TO_POINTER ('C')); + g_node_insert_after (root, node_B, node_C); + node_E = g_node_new (GINT_TO_POINTER ('E')); + g_node_append (node_C, node_E); + + g_assert (g_node_get_root (node_E) == root); + g_assert (g_node_is_ancestor (root, node_B)); + g_assert (g_node_is_ancestor (root, node_E)); + g_assert (!g_node_is_ancestor (node_B, node_D)); + g_assert (g_node_first_sibling (node_D) == node_B); + g_assert (g_node_first_sibling (node_E) == node_E); + g_assert (g_node_first_sibling (root) == root); + g_assert_cmpint (g_node_child_index (root, GINT_TO_POINTER ('B')), ==, 0); + g_assert_cmpint (g_node_child_index (root, GINT_TO_POINTER ('C')), ==, 1); + g_assert_cmpint (g_node_child_index (root, GINT_TO_POINTER ('D')), ==, 2); + g_assert_cmpint (g_node_child_index (root, GINT_TO_POINTER ('E')), ==, -1); + + data.s = g_string_new (""); + data.count = -1; + g_node_children_foreach (root, G_TRAVERSE_ALL, (GNodeForeachFunc)node_build_string, &data); + g_assert_cmpstr (data.s->str, ==, "BCD"); + + g_string_set_size (data.s, 0); + data.count = -1; + g_node_children_foreach (root, G_TRAVERSE_LEAVES, (GNodeForeachFunc)node_build_string, &data); + g_assert_cmpstr (data.s->str, ==, "BD"); + + g_string_set_size (data.s, 0); + data.count = -1; + g_node_children_foreach (root, G_TRAVERSE_NON_LEAVES, (GNodeForeachFunc)node_build_string, &data); + g_assert_cmpstr (data.s->str, ==, "C"); + g_string_free (data.s, TRUE); + + g_node_destroy (root); +} + +static gboolean +check_order (GNode *node, + gpointer data) +{ + gchar **expected = data; + gchar d; + + d = GPOINTER_TO_INT (node->data); + g_assert_cmpint (d, ==, **expected); + (*expected)++; + + return FALSE; +} + +static void +unlink_test (void) +{ + GNode *root; + GNode *node; + GNode *bnode; + GNode *cnode; + gchar *expected; + + /* + * -------- a -------- + * / | \ + * b c d + * / | \ / | \ / | \ + * e f g h i j k l m + * + */ + + root = g_node_new (GINT_TO_POINTER ('a')); + node = bnode = g_node_append_data (root, GINT_TO_POINTER ('b')); + g_node_append_data (node, GINT_TO_POINTER ('e')); + g_node_append_data (node, GINT_TO_POINTER ('f')); + g_node_append_data (node, GINT_TO_POINTER ('g')); + + node = cnode = g_node_append_data (root, GINT_TO_POINTER ('c')); + g_node_append_data (node, GINT_TO_POINTER ('h')); + g_node_append_data (node, GINT_TO_POINTER ('i')); + g_node_append_data (node, GINT_TO_POINTER ('j')); + + node = g_node_append_data (root, GINT_TO_POINTER ('d')); + g_node_append_data (node, GINT_TO_POINTER ('k')); + g_node_append_data (node, GINT_TO_POINTER ('l')); + g_node_append_data (node, GINT_TO_POINTER ('m')); + + g_node_unlink (cnode); + + expected = "abdefgklm"; + g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected); + + expected = "abd"; + g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, 1, check_order, &expected); + + expected = "chij"; + g_node_traverse (cnode, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected); + + g_node_destroy (bnode); + + expected = "adklm"; + g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected); + + g_node_destroy (root); + g_node_destroy (cnode); +} + +static gpointer +copy_up (gconstpointer src, + gpointer data) +{ + gchar l, u; + + l = GPOINTER_TO_INT (src); + u = g_ascii_toupper (l); + + return GINT_TO_POINTER ((int)u); +} + +static void +copy_test (void) +{ + GNode *root; + GNode *copy; + gchar *expected; + + root = g_node_new (GINT_TO_POINTER ('a')); + g_node_append_data (root, GINT_TO_POINTER ('b')); + g_node_append_data (root, GINT_TO_POINTER ('c')); + g_node_append_data (root, GINT_TO_POINTER ('d')); + + expected = "abcd"; + g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected); + + copy = g_node_copy (root); + + expected = "abcd"; + g_node_traverse (copy, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected); + + g_node_destroy (copy); + + copy = g_node_copy_deep (root, copy_up, NULL); + + expected = "ABCD"; + g_node_traverse (copy, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected); + + g_node_destroy (copy); + + g_node_destroy (root); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/node/allocation", allocation_test); + g_test_add_func ("/node/construction", construct_test); + g_test_add_func ("/node/traversal", traversal_test); + g_test_add_func ("/node/misc", misc_test); + g_test_add_func ("/node/unlink", unlink_test); + g_test_add_func ("/node/copy", copy_test); + + return g_test_run (); +} diff --git a/glib/tests/once.c b/glib/tests/once.c new file mode 100644 index 0000000..ea521c0 --- /dev/null +++ b/glib/tests/once.c @@ -0,0 +1,217 @@ + +/* Unit tests for GOnce and friends + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include + +#if GLIB_SIZEOF_VOID_P > 4 +#define THREADS 1000 +#else +#define THREADS 100 +#endif + +static gpointer +do_once (gpointer data) +{ + static gint i = 0; + + i++; + + return GINT_TO_POINTER (i); +} + +static void +test_once_single_threaded (void) +{ + GOnce once = G_ONCE_INIT; + gpointer res; + + g_test_summary ("Test g_once() usage from a single thread"); + + g_assert (once.status == G_ONCE_STATUS_NOTCALLED); + + res = g_once (&once, do_once, NULL); + g_assert_cmpint (GPOINTER_TO_INT (res), ==, 1); + + g_assert (once.status == G_ONCE_STATUS_READY); + + res = g_once (&once, do_once, NULL); + g_assert_cmpint (GPOINTER_TO_INT (res), ==, 1); +} + +static GOnce once_multi_threaded = G_ONCE_INIT; +static gint once_multi_threaded_counter = 0; +static GCond once_multi_threaded_cond; +static GMutex once_multi_threaded_mutex; +static guint once_multi_threaded_n_threads_waiting = 0; + +static gpointer +do_once_multi_threaded (gpointer data) +{ + gint old_value; + + /* While this function should only ever be executed once, by one thread, + * we should use atomics to ensure that if there were a bug, writes to + * `once_multi_threaded_counter` from multiple threads would not get lost and + * mean the test erroneously succeeded. */ + old_value = g_atomic_int_add (&once_multi_threaded_counter, 1); + + return GINT_TO_POINTER (old_value + 1); +} + +static gpointer +once_thread_func (gpointer data) +{ + gpointer res; + guint n_threads_expected = GPOINTER_TO_UINT (data); + + /* Don’t immediately call g_once(), otherwise the first thread to be created + * will end up calling the once-function, and there will be very little + * contention. */ + g_mutex_lock (&once_multi_threaded_mutex); + + once_multi_threaded_n_threads_waiting++; + g_cond_broadcast (&once_multi_threaded_cond); + + while (once_multi_threaded_n_threads_waiting < n_threads_expected) + g_cond_wait (&once_multi_threaded_cond, &once_multi_threaded_mutex); + g_mutex_unlock (&once_multi_threaded_mutex); + + /* Actually run the test. */ + res = g_once (&once_multi_threaded, do_once_multi_threaded, NULL); + g_assert_cmpint (GPOINTER_TO_INT (res), ==, 1); + + return NULL; +} + +static void +test_once_multi_threaded (void) +{ + guint i; + GThread *threads[THREADS]; + + g_test_summary ("Test g_once() usage from multiple threads"); + + for (i = 0; i < G_N_ELEMENTS (threads); i++) + threads[i] = g_thread_new ("once-multi-threaded", + once_thread_func, + GUINT_TO_POINTER (G_N_ELEMENTS (threads))); + + /* All threads have started up, so start the test. */ + g_cond_broadcast (&once_multi_threaded_cond); + + for (i = 0; i < G_N_ELEMENTS (threads); i++) + g_thread_join (threads[i]); + + g_assert_cmpint (g_atomic_int_get (&once_multi_threaded_counter), ==, 1); +} + +static void +test_once_init_single_threaded (void) +{ + static gsize init = 0; + + g_test_summary ("Test g_once_init_{enter,leave}() usage from a single thread"); + + if (g_once_init_enter (&init)) + { + g_assert (TRUE); + g_once_init_leave (&init, 1); + } + + g_assert_cmpint (init, ==, 1); + if (g_once_init_enter (&init)) + { + g_assert_not_reached (); + g_once_init_leave (&init, 2); + } + g_assert_cmpint (init, ==, 1); +} + +static gint64 shared; + +static void +init_shared (void) +{ + static gsize init = 0; + + if (g_once_init_enter (&init)) + { + shared += 42; + + g_once_init_leave (&init, 1); + } +} + +static gpointer +thread_func (gpointer data) +{ + init_shared (); + + return NULL; +} + +static void +test_once_init_multi_threaded (void) +{ + gsize i; + GThread *threads[THREADS]; + + g_test_summary ("Test g_once_init_{enter,leave}() usage from multiple threads"); + + shared = 0; + + for (i = 0; i < G_N_ELEMENTS (threads); i++) + threads[i] = g_thread_new ("once-init-multi-threaded", thread_func, NULL); + + for (i = 0; i < G_N_ELEMENTS (threads); i++) + g_thread_join (threads[i]); + + g_assert_cmpint (shared, ==, 42); +} + +static void +test_once_init_string (void) +{ + static gchar *val; + + g_test_summary ("Test g_once_init_{enter,leave}() usage with a string"); + + if (g_once_init_enter (&val)) + g_once_init_leave (&val, "foo"); + + g_assert_cmpstr (val, ==, "foo"); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/once/single-threaded", test_once_single_threaded); + g_test_add_func ("/once/multi-threaded", test_once_multi_threaded); + g_test_add_func ("/once-init/single-threaded", test_once_init_single_threaded); + g_test_add_func ("/once-init/multi-threaded", test_once_init_multi_threaded); + g_test_add_func ("/once-init/string", test_once_init_string); + + return g_test_run (); +} diff --git a/glib/tests/option-argv0.c b/glib/tests/option-argv0.c new file mode 100644 index 0000000..a18e686 --- /dev/null +++ b/glib/tests/option-argv0.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Authors: Colin Walters + */ + +#include "config.h" +#include + +#include +#include +#include + +static void +test_platform_argv0 (void) +{ + GOptionContext *context; + gboolean arg; + GOptionEntry entries [] = + { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + const gchar * const expected_prgnames[] = + { + "option-argv0", +#ifdef G_OS_WIN32 + "option-argv0.exe", +#endif + NULL, + }; + gboolean retval; + gboolean fatal_errors = TRUE; + + /* This test must pass on platforms where platform_get_argv0() + * is implemented. At the moment that means Linux/Cygwin, + * (which uses /proc/self/cmdline) or OpenBSD (which uses + * sysctl and KERN_PROC_ARGS) or Windows (which uses + * GetCommandlineW ()). On other platforms the test + * is not expected to pass, but we'd still want to know + * how it does (the test code itself doesn't use any platform-specific + * functionality, the difference is internal to glib, so it's quite + * possible to run this test everywhere - it just won't pass on some + * platforms). Make errors non-fatal on these other platforms, + * to prevent them from crashing hard on failed assertions, + * and make them call g_test_skip() instead. + */ +#if !defined HAVE_PROC_SELF_CMDLINE && \ + !defined __OpenBSD__ && \ + !defined __linux && \ + !defined G_OS_WIN32 + fatal_errors = FALSE; +#endif + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + retval = g_option_context_parse (context, NULL, NULL, NULL); + if (fatal_errors) + { + g_assert_true (retval); + g_assert_true (g_strv_contains (expected_prgnames, g_get_prgname ())); + } + else + { + gboolean failed = FALSE; + + if (!retval) + { + g_print ("g_option_context_parse() failed\n"); + failed = TRUE; + } + else if (!g_strv_contains (expected_prgnames, g_get_prgname ())) + { + g_print ("program name `%s' is neither `option-argv0', nor `lt-option-argv0'\n", g_get_prgname()); + failed = TRUE; + } + else + g_print ("The test unexpectedly passed\n"); + if (failed) + g_test_skip ("platform_get_argv0() is not implemented [correctly?] on this platform"); + } + + g_option_context_free (context); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, "no_g_set_prgname", NULL); + + g_test_add_func ("/option/argv0", test_platform_argv0); + + return g_test_run (); +} diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c new file mode 100644 index 0000000..0fdb67c --- /dev/null +++ b/glib/tests/option-context.c @@ -0,0 +1,2711 @@ +/* Unit tests for GOptionContext + * Copyright (C) 2007 Openismus GmbH + * Authors: Mathias Hasselmann + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include + +#include +#include +#include +#include +#include + +static GOptionEntry global_main_entries[] = { + { "main-switch", 0, 0, + G_OPTION_ARG_NONE, NULL, + "A switch that is in the main group", NULL }, + G_OPTION_ENTRY_NULL +}; + +static GOptionEntry global_group_entries[] = { + { "test-switch", 0, 0, + G_OPTION_ARG_NONE, NULL, + "A switch that is in the test group", NULL }, + G_OPTION_ENTRY_NULL +}; + +static GOptionContext * +make_options (int test_number) +{ + GOptionContext *options; + GOptionGroup *group = NULL; + gboolean have_main_entries = (0 != (test_number & 1)); + gboolean have_test_entries = (0 != (test_number & 2)); + + options = g_option_context_new (NULL); + + if (have_main_entries) + g_option_context_add_main_entries (options, global_main_entries, NULL); + if (have_test_entries) + { + group = g_option_group_new ("test", "Test Options", + "Show all test options", + NULL, NULL); + g_option_context_add_group (options, group); + g_option_group_add_entries (group, global_group_entries); + } + + return options; +} + +static void +print_help (GOptionContext *options, gchar **argv) +{ + gint argc = 3; + GError *error = NULL; + + g_option_context_parse (options, &argc, &argv, &error); + g_option_context_free (options); + exit(0); +} + +static void +test_group_captions_help (gconstpointer test_number) +{ + GOptionContext *options; + gchar *argv[] = { __FILE__, "--help", NULL }; + + options = make_options (GPOINTER_TO_INT (test_number)); + print_help (options, argv); +} + +static void +test_group_captions_help_all (gconstpointer test_number) +{ + GOptionContext *options; + gchar *argv[] = { __FILE__, "--help-all", NULL }; + + options = make_options (GPOINTER_TO_INT (test_number)); + print_help (options, argv); +} + +static void +test_group_captions_help_test (gconstpointer test_number) +{ + GOptionContext *options; + gchar *argv[] = { __FILE__, "--help-test", NULL }; + + options = make_options (GPOINTER_TO_INT (test_number)); + print_help (options, argv); +} + +static void +test_group_captions (void) +{ + const gchar *test_name_base[] = { "help", "help-all", "help-test" }; + gchar *test_name; + guint i; + gsize j; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=504142"); + + for (i = 0; i < 4; ++i) + { + gboolean have_main_entries = (0 != (i & 1)); + gboolean have_test_entries = (0 != (i & 2)); + + for (j = 0; j < G_N_ELEMENTS (test_name_base); ++j) + { + GTestSubprocessFlags trap_flags = 0; + gboolean expect_main_description = FALSE; + gboolean expect_main_switch = FALSE; + gboolean expect_test_description = FALSE; + gboolean expect_test_switch = FALSE; + gboolean expect_test_group = FALSE; + + if (g_test_verbose ()) + trap_flags |= G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR; + + test_name = g_strdup_printf ("/option/group/captions/subprocess/%s-%u", + test_name_base[j], i); + g_test_trap_subprocess (test_name, 0, trap_flags); + g_free (test_name); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr (""); + + switch (j) + { + case 0: + g_assert_cmpstr ("help", ==, test_name_base[j]); + expect_main_switch = have_main_entries; + expect_test_group = have_test_entries; + break; + + case 1: + g_assert_cmpstr ("help-all", ==, test_name_base[j]); + expect_main_switch = have_main_entries; + expect_test_switch = have_test_entries; + expect_test_group = have_test_entries; + break; + + case 2: + g_assert_cmpstr ("help-test", ==, test_name_base[j]); + expect_test_switch = have_test_entries; + break; + + default: + g_assert_not_reached (); + break; + } + + expect_main_description |= expect_main_switch; + expect_test_description |= expect_test_switch; + + if (expect_main_description) + g_test_trap_assert_stdout ("*Application Options*"); + else + g_test_trap_assert_stdout_unmatched ("*Application Options*"); + if (expect_main_switch) + g_test_trap_assert_stdout ("*--main-switch*"); + else + g_test_trap_assert_stdout_unmatched ("*--main-switch*"); + + if (expect_test_description) + g_test_trap_assert_stdout ("*Test Options*"); + else + g_test_trap_assert_stdout_unmatched ("*Test Options*"); + if (expect_test_switch) + g_test_trap_assert_stdout ("*--test-switch*"); + else + g_test_trap_assert_stdout_unmatched ("*--test-switch*"); + + if (expect_test_group) + g_test_trap_assert_stdout ("*--help-test*"); + else + g_test_trap_assert_stdout_unmatched ("*--help-test*"); + } + } +} + +int error_test1_int; +char *error_test2_string; +gboolean error_test3_boolean; + +int arg_test1_int; +gchar *arg_test2_string; +gchar *arg_test3_filename; +gdouble arg_test4_double; +gdouble arg_test5_double; +gint64 arg_test6_int64; +gint64 arg_test6_int64_2; + +gchar *callback_test1_string; +int callback_test2_int; + +gchar *callback_test_optional_string; +gboolean callback_test_optional_boolean; + +gchar **array_test1_array; + +gboolean ignore_test1_boolean; +gboolean ignore_test2_boolean; +gchar *ignore_test3_string; + +static gchar ** +split_string (const char *str, int *argc) +{ + gchar **argv; + int len; + + argv = g_strsplit (str, " ", 0); + + for (len = 0; argv[len] != NULL; len++); + + if (argc) + *argc = len; + + return argv; +} + +static gchar * +join_stringv (int argc, char **argv) +{ + int i; + GString *str; + + str = g_string_new (NULL); + + for (i = 0; i < argc; i++) + { + g_string_append (str, argv[i]); + + if (i < argc - 1) + g_string_append_c (str, ' '); + } + + return g_string_free (str, FALSE); +} + +/* Performs a shallow copy */ +static char ** +copy_stringv (char **argv, int argc) +{ + return g_memdup2 (argv, sizeof (char *) * (argc + 1)); +} + +static void +check_identical_stringv (gchar **before, gchar **after) +{ + guint i; + + /* Not only is it the same string... */ + for (i = 0; before[i] != NULL; i++) + g_assert_cmpstr (before[i], ==, after[i]); + + /* ... it is actually the same pointer */ + for (i = 0; before[i] != NULL; i++) + g_assert (before[i] == after[i]); + + g_assert (after[i] == NULL); +} + + +static gboolean +error_test1_pre_parse (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + g_assert (error_test1_int == 0x12345678); + + return TRUE; +} + +static gboolean +error_test1_post_parse (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + g_assert (error_test1_int == 20); + + /* Set an error in the post hook */ + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " "); + + return FALSE; +} + +static void +error_test1 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionGroup *main_group; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_INT, &error_test1_int, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + error_test1_int = 0x12345678; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Set pre and post parse hooks */ + main_group = g_option_context_get_main_group (context); + g_option_group_set_parse_hooks (main_group, + error_test1_pre_parse, error_test1_post_parse); + + /* Now try parsing */ + argv = split_string ("program --test 20", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert (retval == FALSE); + g_assert (error != NULL); + /* An error occurred, so argv has not been changed */ + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); + + /* On failure, values should be reset */ + g_assert (error_test1_int == 0x12345678); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static gboolean +error_test2_pre_parse (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + g_assert (strcmp (error_test2_string, "foo") == 0); + + return TRUE; +} + +static gboolean +error_test2_post_parse (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + g_assert (strcmp (error_test2_string, "bar") == 0); + + /* Set an error in the post hook */ + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " "); + + return FALSE; +} + +static void +error_test2 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionGroup *main_group; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_STRING, &error_test2_string, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + error_test2_string = "foo"; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Set pre and post parse hooks */ + main_group = g_option_context_get_main_group (context); + g_option_group_set_parse_hooks (main_group, + error_test2_pre_parse, error_test2_post_parse); + + /* Now try parsing */ + argv = split_string ("program --test bar", &argc); + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); + + g_assert (retval == FALSE); + g_assert (error != NULL); + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); + + g_assert (strcmp (error_test2_string, "foo") == 0); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static gboolean +error_test3_pre_parse (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + g_assert (!error_test3_boolean); + + return TRUE; +} + +static gboolean +error_test3_post_parse (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + g_assert (error_test3_boolean); + + /* Set an error in the post hook */ + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " "); + + return FALSE; +} + +static void +error_test3 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionGroup *main_group; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_NONE, &error_test3_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + error_test3_boolean = FALSE; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Set pre and post parse hooks */ + main_group = g_option_context_get_main_group (context); + g_option_group_set_parse_hooks (main_group, + error_test3_pre_parse, error_test3_post_parse); + + /* Now try parsing */ + argv = split_string ("program --test", &argc); + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); + + g_assert (retval == FALSE); + g_assert (error != NULL); + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); + + g_assert (!error_test3_boolean); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +arg_test1 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test 20 --test 30", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Last arg specified is the one that should be stored */ + g_assert (arg_test1_int == 30); + + /* We free all of the strings in a copy of argv, because now argv is a + * subset - some have been removed in-place + */ + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +arg_test2 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test foo --test bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Last arg specified is the one that should be stored */ + g_assert (strcmp (arg_test2_string, "bar") == 0); + + g_free (arg_test2_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +arg_test3 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test foo.txt", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Last arg specified is the one that should be stored */ + g_assert (strcmp (arg_test3_filename, "foo.txt") == 0); + + g_free (arg_test3_filename); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +arg_test4 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv_copy; + gchar **argv; + int argc; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test4_double, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test 20.0 --test 30.03", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Last arg specified is the one that should be stored */ + g_assert (arg_test4_double == 30.03); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +arg_test5 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + char *old_locale, *current_locale; + const char *locale = "de_DE.UTF-8"; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test5_double, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test 20,0 --test 30,03", &argc); + argv_copy = copy_stringv (argv, argc); + + /* set it to some locale that uses commas instead of decimal points */ + + old_locale = g_strdup (setlocale (LC_NUMERIC, locale)); + current_locale = setlocale (LC_NUMERIC, NULL); + if (strcmp (current_locale, locale) != 0) + { + fprintf (stderr, "Cannot set locale to %s, skipping\n", locale); + goto cleanup; + } + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Last arg specified is the one that should be stored */ + g_assert (arg_test5_double == 30.03); + + cleanup: + setlocale (LC_NUMERIC, old_locale); + g_free (old_locale); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +arg_test6 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64, NULL, NULL }, + { "test2", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64_2, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test 4294967297 --test 4294967296 --test2 0xfffffffff", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Last arg specified is the one that should be stored */ + g_assert (arg_test6_int64 == G_GINT64_CONSTANT(4294967296)); + g_assert (arg_test6_int64_2 == G_GINT64_CONSTANT(0xfffffffff)); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static gboolean +callback_parse1 (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + callback_test1_string = g_strdup (value); + return TRUE; +} + +static void +callback_test1 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_CALLBACK, callback_parse1, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test foo.txt", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (strcmp (callback_test1_string, "foo.txt") == 0); + + g_free (callback_test1_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static gboolean +callback_parse2 (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + callback_test2_int++; + return TRUE; +} + +static void +callback_test2 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_parse2, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test --test", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (callback_test2_int == 2); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static gboolean +callback_parse_optional (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + callback_test_optional_boolean = TRUE; + if (value) + callback_test_optional_string = g_strdup (value); + else + callback_test_optional_string = NULL; + return TRUE; +} + +static void +callback_test_optional_1 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + callback_parse_optional, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test foo.txt", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0); + + g_assert (callback_test_optional_boolean); + + g_free (callback_test_optional_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +callback_test_optional_2 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + callback_parse_optional, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (callback_test_optional_string == NULL); + + g_assert (callback_test_optional_boolean); + + g_free (callback_test_optional_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +callback_test_optional_3 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv_copy; + gchar **argv; + int argc; + GOptionEntry entries [] = + { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + callback_parse_optional, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program -t foo.txt", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0); + + g_assert (callback_test_optional_boolean); + + g_free (callback_test_optional_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + + +static void +callback_test_optional_4 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + callback_parse_optional, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program -t", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (callback_test_optional_string == NULL); + + g_assert (callback_test_optional_boolean); + + g_free (callback_test_optional_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +callback_test_optional_5 (void) +{ + GOptionContext *context; + gboolean dummy; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL }, + { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + callback_parse_optional, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test --dummy", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (callback_test_optional_string == NULL); + + g_assert (callback_test_optional_boolean); + + g_free (callback_test_optional_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +callback_test_optional_6 (void) +{ + GOptionContext *context; + gboolean dummy; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL }, + { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + callback_parse_optional, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program -t -d", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (callback_test_optional_string == NULL); + + g_assert (callback_test_optional_boolean); + + g_free (callback_test_optional_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +callback_test_optional_7 (void) +{ + GOptionContext *context; + gboolean dummy; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL }, + { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + callback_parse_optional, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program -td", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (callback_test_optional_string == NULL); + + g_assert (callback_test_optional_boolean); + + g_free (callback_test_optional_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +callback_test_optional_8 (void) +{ + GOptionContext *context; + gboolean dummy; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL }, + { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + callback_parse_optional, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program -dt foo.txt", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (callback_test_optional_string); + + g_assert (callback_test_optional_boolean); + + g_free (callback_test_optional_string); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static GPtrArray *callback_remaining_args; +static gboolean +callback_remaining_test1_callback (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + g_ptr_array_add (callback_remaining_args, g_strdup (value)); + return TRUE; +} + +static void +callback_remaining_test1 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, callback_remaining_test1_callback, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + callback_remaining_args = g_ptr_array_new (); + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program foo.txt blah.txt", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (callback_remaining_args->len == 2); + g_assert (strcmp (callback_remaining_args->pdata[0], "foo.txt") == 0); + g_assert (strcmp (callback_remaining_args->pdata[1], "blah.txt") == 0); + + g_ptr_array_foreach (callback_remaining_args, (GFunc) g_free, NULL); + g_ptr_array_free (callback_remaining_args, TRUE); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static gboolean +callback_error (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "42"); + return FALSE; +} + +static void +callback_returns_false (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "error", 0, 0, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL }, + { "error-no-arg", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL }, + { "error-optional-arg", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --error value", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); + g_assert (retval == FALSE); + check_identical_stringv (argv_copy, argv); + + g_option_context_free (context); + g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); + + /* And again, this time with a no-arg variant */ + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + argv = split_string ("program --error-no-arg", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); + g_assert (retval == FALSE); + check_identical_stringv (argv_copy, argv); + + g_option_context_free (context); + g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); + + /* And again, this time with an optional arg variant, with argument */ + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + argv = split_string ("program --error-optional-arg value", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); + g_assert (retval == FALSE); + check_identical_stringv (argv_copy, argv); + + g_option_context_free (context); + g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); + + /* And again, this time with an optional arg variant, without argument */ + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + argv = split_string ("program --error-optional-arg", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); + g_assert (retval == FALSE); + check_identical_stringv (argv_copy, argv); + + g_option_context_free (context); + g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); +} + + +static void +ignore_test1 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv, **argv_copy; + int argc; + gchar *arg; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_set_ignore_unknown_options (context, TRUE); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test --hello", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + arg = join_stringv (argc, argv); + g_assert (strcmp (arg, "program --hello") == 0); + + g_free (arg); + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +ignore_test2 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + gchar *arg; + GOptionEntry entries [] = + { { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_set_ignore_unknown_options (context, TRUE); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program -test", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + arg = join_stringv (argc, argv); + g_assert (strcmp (arg, "program -es") == 0); + + g_free (arg); + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +ignore_test3 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv, **argv_copy; + int argc; + gchar *arg; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_set_ignore_unknown_options (context, TRUE); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test foo --hello", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + arg = join_stringv (argc, argv); + g_assert (strcmp (arg, "program --hello") == 0); + + g_assert (strcmp (ignore_test3_string, "foo") == 0); + g_free (ignore_test3_string); + + g_free (arg); + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +array_test1 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test foo --test bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (strcmp (array_test1_array[0], "foo") == 0); + g_assert (strcmp (array_test1_array[1], "bar") == 0); + g_assert (array_test1_array[2] == NULL); + + g_strfreev (array_test1_array); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +add_test1 (void) +{ + GOptionContext *context; + + GOptionEntry entries1 [] = + { { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + GOptionEntry entries2 [] = + { { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries1, NULL); + g_option_context_add_main_entries (context, entries2, NULL); + + g_option_context_free (context); +} + +static void +empty_test2 (void) +{ + GOptionContext *context; + + context = g_option_context_new (NULL); + g_option_context_parse (context, NULL, NULL, NULL); + + g_option_context_free (context); +} + +static void +empty_test3 (void) +{ + GOptionContext *context; + gint argc; + gchar **argv; + + argc = 0; + argv = NULL; + + context = g_option_context_new (NULL); + g_option_context_parse (context, &argc, &argv, NULL); + + g_option_context_free (context); +} + +/* check that non-option arguments are left in argv by default */ +static void +rest_test1 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program foo --test bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (argv[0], "program") == 0); + g_assert (strcmp (argv[1], "foo") == 0); + g_assert (strcmp (argv[2], "bar") == 0); + g_assert (argv[3] == NULL); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +/* check that -- works */ +static void +rest_test2 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program foo --test -- -bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (argv[0], "program") == 0); + g_assert (strcmp (argv[1], "foo") == 0); + g_assert (strcmp (argv[2], "--") == 0); + g_assert (strcmp (argv[3], "-bar") == 0); + g_assert (argv[4] == NULL); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +/* check that -- stripping works */ +static void +rest_test2a (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program foo --test -- bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (argv[0], "program") == 0); + g_assert (strcmp (argv[1], "foo") == 0); + g_assert (strcmp (argv[2], "bar") == 0); + g_assert (argv[3] == NULL); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +rest_test2b (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_set_ignore_unknown_options (context, TRUE); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program foo --test -bar --", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (argv[0], "program") == 0); + g_assert (strcmp (argv[1], "foo") == 0); + g_assert (strcmp (argv[2], "-bar") == 0); + g_assert (argv[3] == NULL); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +rest_test2c (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test foo -- bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (argv[0], "program") == 0); + g_assert (strcmp (argv[1], "foo") == 0); + g_assert (strcmp (argv[2], "bar") == 0); + g_assert (argv[3] == NULL); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +rest_test2d (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test -- -bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (argv[0], "program") == 0); + g_assert (strcmp (argv[1], "--") == 0); + g_assert (strcmp (argv[2], "-bar") == 0); + g_assert (argv[3] == NULL); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + + +/* check that G_OPTION_REMAINING collects non-option arguments */ +static void +rest_test3 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program foo --test bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (array_test1_array[0], "foo") == 0); + g_assert (strcmp (array_test1_array[1], "bar") == 0); + g_assert (array_test1_array[2] == NULL); + + g_strfreev (array_test1_array); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + + +/* check that G_OPTION_REMAINING and -- work together */ +static void +rest_test4 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program foo --test -- -bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (array_test1_array[0], "foo") == 0); + g_assert (strcmp (array_test1_array[1], "-bar") == 0); + g_assert (array_test1_array[2] == NULL); + + g_strfreev (array_test1_array); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +/* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */ +static void +rest_test5 (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { + { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program foo --test bar", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Check array */ + g_assert (ignore_test1_boolean); + g_assert (strcmp (array_test1_array[0], "foo") == 0); + g_assert (strcmp (array_test1_array[1], "bar") == 0); + g_assert (array_test1_array[2] == NULL); + + g_strfreev (array_test1_array); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +unknown_short_test (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + GOptionEntry entries [] = { G_OPTION_ENTRY_NULL }; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=166609"); + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program -0", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert (!retval); + g_assert (error != NULL); + g_clear_error (&error); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +/* test that lone dashes are treated as non-options */ +static void +lonely_dash_test (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=168008"); + + context = g_option_context_new (NULL); + + /* Now try parsing */ + argv = split_string ("program -", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + g_assert (argv[1] && strcmp (argv[1], "-") == 0); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +/* test that three dashes are treated as non-options */ +static void +triple_dash_test (void) +{ + GOptionContext *context; + GOptionGroup *group; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + gint arg1, arg2; + GOptionEntry entries [] = + { { "foo", 0, 0, G_OPTION_ARG_INT, &arg1, NULL, NULL}, + G_OPTION_ENTRY_NULL + }; + GOptionEntry group_entries [] = + { { "test", 0, 0, G_OPTION_ARG_INT, &arg2, NULL, NULL}, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + group = g_option_group_new ("group", "Group description", "Group help", NULL, NULL); + g_option_group_add_entries (group, group_entries); + + g_option_context_add_group (context, group); + + /* Now try parsing */ + argv = split_string ("program ---test 42", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION); + g_assert (retval == FALSE); + + g_option_context_free (context); + g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); +} + +static void +missing_arg_test (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + gchar *arg = NULL; + GOptionEntry entries [] = + { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=305576"); + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert (retval == FALSE); + g_assert (error != NULL); + /* An error occurred, so argv has not been changed */ + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); + + g_strfreev (argv_copy); + g_free (argv); + + /* Try parsing again */ + argv = split_string ("program -t", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert (retval == FALSE); + g_assert (error != NULL); + /* An error occurred, so argv has not been changed */ + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); + + /* Checking g_option_context_parse_strv on NULL args */ + context = g_option_context_new (NULL); + g_assert_true (g_option_context_parse_strv (context, NULL, NULL)); + g_option_context_free (context); +} + +static gchar *test_arg; + +static gboolean cb (const gchar *option_name, + const gchar *value, + gpointer data, + GError **error) +{ + test_arg = g_strdup (value); + return TRUE; +} + +static void +dash_arg_test (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv; + gchar **argv_copy; + int argc; + gboolean argb = FALSE; + GOptionEntry entries [] = + { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, cb, NULL, NULL }, + { "three", '3', 0, G_OPTION_ARG_NONE, &argb, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=577638"); + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test=-3", &argc); + argv_copy = copy_stringv (argv, argc); + + test_arg = NULL; + error = NULL; + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert (retval); + g_assert_no_error (error); + g_assert_cmpstr (test_arg, ==, "-3"); + + g_strfreev (argv_copy); + g_free (argv); + g_free (test_arg); + test_arg = NULL; + + /* Try parsing again */ + argv = split_string ("program --test -3", &argc); + argv_copy = copy_stringv (argv, argc); + + error = NULL; + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + g_assert_cmpstr (test_arg, ==, NULL); + + g_option_context_free (context); + g_strfreev (argv_copy); + g_free (argv); +} + +static void +test_basic (void) +{ + GOptionContext *context; + gchar *arg = NULL; + GOptionEntry entries [] = + { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + g_assert (g_option_context_get_help_enabled (context)); + g_assert (!g_option_context_get_ignore_unknown_options (context)); + g_assert_cmpstr (g_option_context_get_summary (context), ==, NULL); + g_assert_cmpstr (g_option_context_get_description (context), ==, NULL); + + g_option_context_set_help_enabled (context, FALSE); + g_option_context_set_ignore_unknown_options (context, TRUE); + g_option_context_set_summary (context, "summary"); + g_option_context_set_description(context, "description"); + + g_assert (!g_option_context_get_help_enabled (context)); + g_assert (g_option_context_get_ignore_unknown_options (context)); + g_assert_cmpstr (g_option_context_get_summary (context), ==, "summary"); + g_assert_cmpstr (g_option_context_get_description (context), ==, "description"); + + g_option_context_free (context); +} + +typedef struct { + gboolean parameter_seen; + gboolean summary_seen; + gboolean description_seen; + gboolean destroyed; +} TranslateData; + +static const gchar * +translate_func (const gchar *str, + gpointer data) +{ + TranslateData *d = data; + + if (strcmp (str, "parameter") == 0) + d->parameter_seen = TRUE; + else if (strcmp (str, "summary") == 0) + d->summary_seen = TRUE; + else if (strcmp (str, "description") == 0) + d->description_seen = TRUE; + + return str; +} + +static void +destroy_notify (gpointer data) +{ + TranslateData *d = data; + + d->destroyed = TRUE; +} + +static void +test_translate (void) +{ + GOptionContext *context; + gchar *arg = NULL; + GOptionEntry entries [] = + { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + TranslateData data = { 0, }; + gchar *str; + + context = g_option_context_new ("parameter"); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, "summary"); + g_option_context_set_description (context, "description"); + + g_option_context_set_translate_func (context, translate_func, &data, destroy_notify); + + str = g_option_context_get_help (context, FALSE, NULL); + g_free (str); + g_option_context_free (context); + + g_assert (data.parameter_seen); + g_assert (data.summary_seen); + g_assert (data.description_seen); + g_assert (data.destroyed); +} + +static void +test_help (void) +{ + GOptionContext *context; + GOptionGroup *group; + gchar *str; + gchar *arg = NULL; + gchar **sarr = NULL; + GOptionEntry entries[] = { + { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Test tests", "Argument to use in test" }, + { "test2", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, "Tests also", NULL }, + { "frob", 0, 0, G_OPTION_ARG_NONE, NULL, "Main frob", NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" }, + G_OPTION_ENTRY_NULL + }; + GOptionEntry group_entries[] = { + { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Group test", "Group test arg" }, + { "frob", 0, G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_NONE, NULL, "Group frob", NULL }, + G_OPTION_ENTRY_NULL + }; + + context = g_option_context_new ("blabla"); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, "Summary"); + g_option_context_set_description (context, "Description"); + + group = g_option_group_new ("group1", "Group1-description", "Group1-help", NULL, NULL); + g_option_group_add_entries (group, group_entries); + + g_option_context_add_group (context, group); + + str = g_option_context_get_help (context, FALSE, NULL); + g_assert (strstr (str, "blabla") != NULL); + g_assert (strstr (str, "Test tests") != NULL); + g_assert (strstr (str, "Argument to use in test") != NULL); + g_assert (strstr (str, "Tests also") == NULL); + g_assert (strstr (str, "REST") != NULL); + g_assert (strstr (str, "Summary") != NULL); + g_assert (strstr (str, "Description") != NULL); + g_assert (strstr (str, "--help") != NULL); + g_assert (strstr (str, "--help-all") != NULL); + g_assert (strstr (str, "--help-group1") != NULL); + g_assert (strstr (str, "Group1-description") != NULL); + g_assert (strstr (str, "Group1-help") != NULL); + g_assert (strstr (str, "Group test arg") != NULL); + g_assert (strstr (str, "Group frob") != NULL); + g_assert (strstr (str, "Main frob") != NULL); + g_assert (strstr (str, "--frob") != NULL); + g_assert (strstr (str, "--group1-test") != NULL); + g_assert (strstr (str, "--group1-frob") == NULL); + g_free (str); + + g_option_context_free (context); +} + +static void +test_help_no_options (void) +{ + GOptionContext *context; + gchar **sarr = NULL; + GOptionEntry entries[] = { + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" }, + G_OPTION_ENTRY_NULL + }; + gchar *str; + + context = g_option_context_new ("blabla"); + g_option_context_add_main_entries (context, entries, NULL); + + str = g_option_context_get_help (context, FALSE, NULL); + g_assert (strstr (str, "blabla") != NULL); + g_assert (strstr (str, "REST") != NULL); + g_assert (strstr (str, "Help Options") != NULL); + g_assert (strstr (str, "Application Options") == NULL); + + g_free (str); + g_option_context_free (context); +} + +static void +test_help_no_help_options (void) +{ + GOptionContext *context; + GOptionGroup *group; + gchar *str; + gchar *arg = NULL; + gchar **sarr = NULL; + GOptionEntry entries[] = { + { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Test tests", "Argument to use in test" }, + { "test2", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, "Tests also", NULL }, + { "frob", 0, 0, G_OPTION_ARG_NONE, NULL, "Main frob", NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" }, + G_OPTION_ENTRY_NULL + }; + GOptionEntry group_entries[] = { + { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Group test", "Group test arg" }, + { "frob", 0, G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_NONE, NULL, "Group frob", NULL }, + G_OPTION_ENTRY_NULL + }; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=697652"); + + context = g_option_context_new ("blabla"); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, "Summary"); + g_option_context_set_description (context, "Description"); + g_option_context_set_help_enabled (context, FALSE); + + group = g_option_group_new ("group1", "Group1-description", "Group1-help", NULL, NULL); + g_option_group_add_entries (group, group_entries); + + g_option_context_add_group (context, group); + + str = g_option_context_get_help (context, FALSE, NULL); + g_assert (strstr (str, "blabla") != NULL); + g_assert (strstr (str, "Test tests") != NULL); + g_assert (strstr (str, "Argument to use in test") != NULL); + g_assert (strstr (str, "Tests also") == NULL); + g_assert (strstr (str, "REST") != NULL); + g_assert (strstr (str, "Summary") != NULL); + g_assert (strstr (str, "Description") != NULL); + g_assert (strstr (str, "Help Options") == NULL); + g_assert (strstr (str, "--help") == NULL); + g_assert (strstr (str, "--help-all") == NULL); + g_assert (strstr (str, "--help-group1") == NULL); + g_assert (strstr (str, "Group1-description") != NULL); + g_assert (strstr (str, "Group1-help") == NULL); + g_assert (strstr (str, "Group test arg") != NULL); + g_assert (strstr (str, "Group frob") != NULL); + g_assert (strstr (str, "Main frob") != NULL); + g_assert (strstr (str, "--frob") != NULL); + g_assert (strstr (str, "--group1-test") != NULL); + g_assert (strstr (str, "--group1-frob") == NULL); + g_free (str); + + g_option_context_free (context); +} + +static void +set_bool (gpointer data) +{ + gboolean *b = data; + + *b = TRUE; +} + +static void +test_main_group (void) +{ + GOptionContext *context; + GOptionGroup *group; + gboolean b = FALSE; + + context = g_option_context_new (NULL); + g_assert (g_option_context_get_main_group (context) == NULL); + group = g_option_group_new ("name", "description", "hlep", &b, set_bool); + g_option_context_add_group (context, group); + group = g_option_group_new ("name2", "description", "hlep", NULL, NULL); + g_option_context_add_group (context, group); + g_assert (g_option_context_get_main_group (context) == NULL); + group = g_option_group_new ("name", "description", "hlep", NULL, NULL); + g_option_context_set_main_group (context, group); + g_assert (g_option_context_get_main_group (context) == group); + + g_option_context_free (context); + + g_assert (b); +} + +static gboolean error_func_called = FALSE; + +static void +error_func (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + g_assert_cmpint (GPOINTER_TO_INT(data), ==, 1234); + error_func_called = TRUE; +} + +static void +test_error_hook (void) +{ + GOptionContext *context; + gchar *arg = NULL; + GOptionEntry entries [] = + { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + GOptionGroup *group; + gchar **argv; + gchar **argv_copy; + gint argc; + gboolean retval; + GError *error = NULL; + + context = g_option_context_new (NULL); + group = g_option_group_new ("name", "description", "hlep", GINT_TO_POINTER(1234), NULL); + g_option_group_add_entries (group, entries); + g_option_context_set_main_group (context, group); + g_option_group_set_error_hook (g_option_context_get_main_group (context), + error_func); + + argv = split_string ("program --test", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert (retval == FALSE); + g_assert (error != NULL); + /* An error occurred, so argv has not been changed */ + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); + + g_assert (error_func_called); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +test_group_parse (void) +{ + GOptionContext *context; + GOptionGroup *group; + gchar *arg1 = NULL; + gchar *arg2 = NULL; + gchar *arg3 = NULL; + gchar *arg4 = NULL; + gchar *arg5 = NULL; + GOptionEntry entries[] = { + { "test", 't', 0, G_OPTION_ARG_STRING, &arg1, NULL, NULL }, + { "faz", 'f', 0, G_OPTION_ARG_STRING, &arg2, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + GOptionEntry group_entries[] = { + { "test", 0, 0, G_OPTION_ARG_STRING, &arg3, NULL, NULL }, + { "frob", 'f', 0, G_OPTION_ARG_STRING, &arg4, NULL, NULL }, + { "faz", 'z', 0, G_OPTION_ARG_STRING, &arg5, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + gchar **argv, **orig_argv; + gint argc; + GError *error = NULL; + gboolean retval; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + group = g_option_group_new ("group", "A group", "help for group", NULL, NULL); + g_option_group_add_entries (group, group_entries); + g_option_context_add_group (context, group); + + argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc); + orig_argv = g_memdup2 (argv, (argc + 1) * sizeof (char *)); + + retval = g_option_context_parse (context, &argc, &argv, &error); + + g_assert_no_error (error); + g_assert (retval); + g_assert_cmpstr (arg1, ==, "arg1"); + g_assert_cmpstr (arg2, ==, "arg2"); + g_assert_cmpstr (arg3, ==, "arg3"); + g_assert_cmpstr (arg4, ==, "arg4"); + g_assert_cmpstr (arg5, ==, "arg5"); + + g_free (arg1); + g_free (arg2); + g_free (arg3); + g_free (arg4); + g_free (arg5); + + g_free (argv); + g_strfreev (orig_argv); + g_option_context_free (context); +} + +static gint +option_context_parse_command_line (GOptionContext *context, + const gchar *command_line) +{ + gchar **argv; + guint argv_len, argv_new_len; + gboolean success; + + argv = split_string (command_line, NULL); + argv_len = g_strv_length (argv); + + success = g_option_context_parse_strv (context, &argv, NULL); + argv_new_len = g_strv_length (argv); + + g_strfreev (argv); + return success ? (gint) (argv_len - argv_new_len) : -1; +} + +static void +test_strict_posix (void) +{ + GOptionContext *context; + gboolean foo; + gboolean bar; + GOptionEntry entries[] = { + { "foo", 'f', 0, G_OPTION_ARG_NONE, &foo, NULL, NULL }, + { "bar", 'b', 0, G_OPTION_ARG_NONE, &bar, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + gint n_parsed; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + foo = bar = FALSE; + g_option_context_set_strict_posix (context, FALSE); + n_parsed = option_context_parse_command_line (context, "program --foo command --bar"); + g_assert_cmpint (n_parsed, ==, 2); + g_assert (foo == TRUE); + g_assert (bar == TRUE); + + foo = bar = FALSE; + g_option_context_set_strict_posix (context, TRUE); + n_parsed = option_context_parse_command_line (context, "program --foo command --bar"); + g_assert_cmpint (n_parsed, ==, 1); + g_assert (foo == TRUE); + g_assert (bar == FALSE); + + foo = bar = FALSE; + g_option_context_set_strict_posix (context, TRUE); + n_parsed = option_context_parse_command_line (context, "program --foo --bar command"); + g_assert_cmpint (n_parsed, ==, 2); + g_assert (foo == TRUE); + g_assert (bar == TRUE); + + foo = bar = FALSE; + g_option_context_set_strict_posix (context, TRUE); + n_parsed = option_context_parse_command_line (context, "program command --foo --bar"); + g_assert_cmpint (n_parsed, ==, 0); + g_assert (foo == FALSE); + g_assert (bar == FALSE); + + g_option_context_free (context); +} + +static void +flag_reverse_string (void) +{ + GOptionContext *context; + gchar *arg = NULL; + GOptionEntry entries [] = + { { "test", 't', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_STRING, &arg, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + gchar **argv; + gint argc; + gboolean retval; + GError *error = NULL; + + if (!g_test_undefined ()) + return; + + context = g_option_context_new (NULL); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*ignoring reverse flag*"); + g_option_context_add_main_entries (context, entries, NULL); + g_test_assert_expected_messages (); + + argv = split_string ("program --test bla", &argc); + + retval = g_option_context_parse_strv (context, &argv, &error); + g_assert (retval == TRUE); + g_assert_no_error (error); + g_strfreev (argv); + g_option_context_free (context); + g_free (arg); +} + +static void +flag_optional_int (void) +{ + GOptionContext *context; + gint arg = 0; + GOptionEntry entries [] = + { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &arg, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + gchar **argv; + gint argc; + gboolean retval; + GError *error = NULL; + + if (!g_test_undefined ()) + return; + + context = g_option_context_new (NULL); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*ignoring no-arg, optional-arg or filename flags*"); + g_option_context_add_main_entries (context, entries, NULL); + g_test_assert_expected_messages (); + + argv = split_string ("program --test 5", &argc); + + retval = g_option_context_parse_strv (context, &argv, &error); + g_assert (retval == TRUE); + g_assert_no_error (error); + g_strfreev (argv); + g_option_context_free (context); +} + +static void +short_remaining (void) +{ + gboolean ignore = FALSE; + gboolean remaining = FALSE; + gint number = 0; + gchar* text = NULL; + gchar** files = NULL; + GError* error = NULL; + GOptionEntry entries[] = + { + { "ignore", 'i', 0, G_OPTION_ARG_NONE, &ignore, NULL, NULL }, + { "remaining", 'r', 0, G_OPTION_ARG_NONE, &remaining, NULL, NULL }, + { "number", 'n', 0, G_OPTION_ARG_INT, &number, NULL, NULL }, + { "text", 't', 0, G_OPTION_ARG_STRING, &text, NULL, NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + GOptionContext* context; + gchar **argv, **argv_copy; + gint argc; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=729563"); + + argv = split_string ("program -ri -n 4 -t hello file1 file2", &argc); + argv_copy = copy_stringv (argv, argc); + + context = g_option_context_new (NULL); + + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_ignore_unknown_options (context, TRUE); + + g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + + g_assert (ignore); + g_assert (remaining); + g_assert_cmpint (number, ==, 4); + g_assert_cmpstr (text, ==, "hello"); + g_assert_cmpstr (files[0], ==, "file1"); + g_assert_cmpstr (files[1], ==, "file2"); + g_assert (files[2] == NULL); + + g_free (text); + g_strfreev (files); + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +static void +double_free (void) +{ + gchar* text = NULL; + GOptionEntry entries[] = + { + { "known", 0, 0, G_OPTION_ARG_STRING, &text, NULL, NULL }, + G_OPTION_ENTRY_NULL + }; + GOptionContext* context; + gchar **argv; + gint argc; + GError *error = NULL; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=646926"); + + argv = split_string ("program --known=foo --known=bar --unknown=baz", &argc); + + context = g_option_context_new (NULL); + + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_ignore_unknown_options (context, FALSE); + g_option_context_parse (context, &argc, &argv, &error); + + g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION); + g_assert_null (text); + + g_option_context_free (context); + g_clear_error (&error); + g_strfreev (argv); + +} + +static void +double_zero (void) +{ + GOptionContext *context; + gboolean retval; + GError *error = NULL; + gchar **argv_copy; + gchar **argv; + int argc; + double test_val = NAN; + GOptionEntry entries [] = + { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &test_val, NULL, NULL }, + G_OPTION_ENTRY_NULL }; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, NULL); + + /* Now try parsing */ + argv = split_string ("program --test 0", &argc); + argv_copy = copy_stringv (argv, argc); + + retval = g_option_context_parse (context, &argc, &argv, &error); + g_assert_no_error (error); + g_assert (retval); + + /* Last arg specified is the one that should be stored */ + g_assert (test_val == 0); + + g_strfreev (argv_copy); + g_free (argv); + g_option_context_free (context); +} + +int +main (int argc, + char *argv[]) +{ + int i; + gchar *test_name; + + g_setenv ("LC_ALL", "C", TRUE); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/option/help/options", test_help); + g_test_add_func ("/option/help/no-options", test_help_no_options); + g_test_add_func ("/option/help/no-help-options", test_help_no_help_options); + + g_test_add_func ("/option/basic", test_basic); + g_test_add_func ("/option/translate", test_translate); + + g_test_add_func ("/option/group/captions", test_group_captions); + for (i = 0; i < 4; i++) + { + test_name = g_strdup_printf ("/option/group/captions/subprocess/help-%d", i); + g_test_add_data_func (test_name, GINT_TO_POINTER (i), + test_group_captions_help); + g_free (test_name); + test_name = g_strdup_printf ("/option/group/captions/subprocess/help-all-%d", i); + g_test_add_data_func (test_name, GINT_TO_POINTER (i), + test_group_captions_help_all); + g_free (test_name); + test_name = g_strdup_printf ("/option/group/captions/subprocess/help-test-%d", i); + g_test_add_data_func (test_name, GINT_TO_POINTER (i), + test_group_captions_help_test); + + g_free (test_name); + } + + g_test_add_func ("/option/group/main", test_main_group); + g_test_add_func ("/option/group/error-hook", test_error_hook); + g_test_add_func ("/option/group/parse", test_group_parse); + g_test_add_func ("/option/strict-posix", test_strict_posix); + + /* Test that restoration on failure works */ + g_test_add_func ("/option/restoration/int", error_test1); + g_test_add_func ("/option/restoration/string", error_test2); + g_test_add_func ("/option/restoration/boolean", error_test3); + + /* Test that special argument parsing works */ + g_test_add_func ("/option/arg/repetition/int", arg_test1); + g_test_add_func ("/option/arg/repetition/string", arg_test2); + g_test_add_func ("/option/arg/repetition/filename", arg_test3); + g_test_add_func ("/option/arg/repetition/double", arg_test4); + g_test_add_func ("/option/arg/repetition/locale", arg_test5); + g_test_add_func ("/option/arg/repetition/int64", arg_test6); + + /* Test string arrays */ + g_test_add_func ("/option/arg/array/string", array_test1); + + /* Test callback args */ + g_test_add_func ("/option/arg/callback/string", callback_test1); + g_test_add_func ("/option/arg/callback/count", callback_test2); + + /* Test optional arg flag for callback */ + g_test_add_func ("/option/arg/callback/optional1", callback_test_optional_1); + g_test_add_func ("/option/arg/callback/optional2", callback_test_optional_2); + g_test_add_func ("/option/arg/callback/optional3", callback_test_optional_3); + g_test_add_func ("/option/arg/callback/optional4", callback_test_optional_4); + g_test_add_func ("/option/arg/callback/optional5", callback_test_optional_5); + g_test_add_func ("/option/arg/callback/optional6", callback_test_optional_6); + g_test_add_func ("/option/arg/callback/optional7", callback_test_optional_7); + g_test_add_func ("/option/arg/callback/optional8", callback_test_optional_8); + + /* Test callback with G_OPTION_REMAINING */ + g_test_add_func ("/option/arg/remaining/callback", callback_remaining_test1); + + /* Test callbacks which return FALSE */ + g_test_add_func ("/option/arg/remaining/callback-false", callback_returns_false); + + /* Test ignoring options */ + g_test_add_func ("/option/arg/ignore/long", ignore_test1); + g_test_add_func ("/option/arg/ignore/short", ignore_test2); + g_test_add_func ("/option/arg/ignore/arg", ignore_test3); + g_test_add_func ("/option/context/add", add_test1); + + /* Test parsing empty args */ + /* Note there used to be an empty1 here, but it effectively moved + * to option-argv0.c. + */ + g_test_add_func ("/option/context/empty2", empty_test2); + g_test_add_func ("/option/context/empty3", empty_test3); + + /* Test handling of rest args */ + g_test_add_func ("/option/arg/rest/non-option", rest_test1); + g_test_add_func ("/option/arg/rest/separator1", rest_test2); + g_test_add_func ("/option/arg/rest/separator2", rest_test2a); + g_test_add_func ("/option/arg/rest/separator3", rest_test2b); + g_test_add_func ("/option/arg/rest/separator4", rest_test2c); + g_test_add_func ("/option/arg/rest/separator5", rest_test2d); + g_test_add_func ("/option/arg/remaining/non-option", rest_test3); + g_test_add_func ("/option/arg/remaining/separator", rest_test4); + g_test_add_func ("/option/arg/remaining/array", rest_test5); + + /* Test some invalid flag combinations */ + g_test_add_func ("/option/arg/reverse-string", flag_reverse_string); + g_test_add_func ("/option/arg/optional-int", flag_optional_int); + + /* regression tests for individual bugs */ + g_test_add_func ("/option/bug/unknown-short", unknown_short_test); + g_test_add_func ("/option/bug/lonely-dash", lonely_dash_test); + g_test_add_func ("/option/bug/triple-dash", triple_dash_test); + g_test_add_func ("/option/bug/missing-arg", missing_arg_test); + g_test_add_func ("/option/bug/dash-arg", dash_arg_test); + g_test_add_func ("/option/bug/short-remaining", short_remaining); + g_test_add_func ("/option/bug/double-free", double_free); + g_test_add_func ("/option/bug/double-zero", double_zero); + + return g_test_run(); +} diff --git a/glib/tests/overflow.c b/glib/tests/overflow.c new file mode 100644 index 0000000..9e27764 --- /dev/null +++ b/glib/tests/overflow.c @@ -0,0 +1,199 @@ +/* + * Copyright 2015 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + * + * Author: Allison Ryan Lortie + */ + +#include + +typedef struct +{ + gboolean success; + guint64 c, a, b; +} Case; + +static void +test_checked_guint_add (void) +{ + static const Case cases[] = { + /* success c = a + b */ + { TRUE, 0, 0, 0 }, + { TRUE, G_MAXINT, G_MAXINT, 0 }, + { TRUE, G_MAXINT, 0, G_MAXINT }, + { TRUE, G_MAXUINT, G_MAXUINT, 0 }, + { TRUE, G_MAXUINT, 0, G_MAXUINT }, + { TRUE, G_MAXUINT - 1, G_MAXINT, G_MAXINT }, + { FALSE, 0, G_MAXUINT, 1 }, + { FALSE, 0, 1, G_MAXUINT }, + { FALSE, 0, G_MAXUINT, G_MAXUINT } + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (cases); i++) + { + guint result; + + g_assert_cmpuint (cases[i].success, ==, g_uint_checked_add (&result, cases[i].a, cases[i].b)); + if (cases[i].success) + g_assert_cmpuint (cases[i].c, ==, result); + } +} + +static void +test_checked_guint_mul (void) +{ + static const Case cases[] = { + /* success c = a * b */ + { TRUE, 0, 0, 0 }, + { TRUE, 0, G_MAXINT, 0 }, + { TRUE, G_MAXINT, G_MAXINT, 1 }, + { TRUE, 0, G_MAXUINT, 0 }, + { TRUE, G_MAXUINT, G_MAXUINT, 1 }, + { TRUE, 2 * (guint) G_MAXINT, 2, G_MAXINT }, + { TRUE, 2 * (guint) G_MAXINT, G_MAXINT, 2 }, + { FALSE, 0, 3, G_MAXINT }, + { FALSE, 0, G_MAXINT, 3 } + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (cases); i++) + { + guint result; + + g_assert_cmpuint (cases[i].success, ==, g_uint_checked_mul (&result, cases[i].a, cases[i].b)); + if (cases[i].success) + g_assert_cmpuint (cases[i].c, ==, result); + } +} + + +static void +test_checked_guint64_add (void) +{ + static const Case cases[] = { + /* success c = a + b */ + { TRUE, 0, 0, 0 }, + { TRUE, G_MAXINT64, G_MAXINT64, 0 }, + { TRUE, G_MAXINT64, 0, G_MAXINT64 }, + { TRUE, G_MAXUINT64, G_MAXUINT64, 0 }, + { TRUE, G_MAXUINT64, 0, G_MAXUINT64 }, + { TRUE, G_MAXUINT64 - 1, G_MAXINT64, G_MAXINT64 }, + { FALSE, 0, G_MAXUINT64, 1 }, + { FALSE, 0, 1, G_MAXUINT64 }, + { FALSE, 0, G_MAXUINT64, G_MAXUINT64 } + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (cases); i++) + { + guint64 result; + + g_assert_cmpuint (cases[i].success, ==, g_uint64_checked_add (&result, cases[i].a, cases[i].b)); + if (cases[i].success) + g_assert_cmpuint (cases[i].c, ==, result); + } +} + +static void +test_checked_guint64_mul (void) +{ + static const Case cases[] = { + /* success c = a * b */ + { TRUE, 0, 0, 0 }, + { TRUE, 0, G_MAXINT64, 0 }, + { TRUE, G_MAXINT64, G_MAXINT64, 1 }, + { TRUE, 0, G_MAXUINT64, 0 }, + { TRUE, G_MAXUINT64, G_MAXUINT64, 1 }, + { TRUE, 2 * (guint64) G_MAXINT64, 2, G_MAXINT64 }, + { TRUE, 2 * (guint64) G_MAXINT64, G_MAXINT64, 2 }, + { FALSE, 0, 3, G_MAXINT64 }, + { FALSE, 0, G_MAXINT64, 3 } + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (cases); i++) + { + guint64 result; + + g_assert_cmpuint (cases[i].success, ==, g_uint64_checked_mul (&result, cases[i].a, cases[i].b)); + if (cases[i].success) + g_assert_cmpuint (cases[i].c, ==, result); + } +} + + +static void +test_checked_gsize_add (void) +{ + static const Case cases[] = { + /* success c = a + b */ + { TRUE, 0, 0, 0 }, + { TRUE, G_MAXSSIZE, G_MAXSSIZE, 0 }, + { TRUE, G_MAXSSIZE, 0, G_MAXSSIZE }, + { TRUE, G_MAXSIZE, G_MAXSIZE, 0 }, + { TRUE, G_MAXSIZE, 0, G_MAXSIZE }, + { TRUE, G_MAXSIZE - 1, G_MAXSSIZE, G_MAXSSIZE }, + { FALSE, 0, G_MAXSIZE, 1 }, + { FALSE, 0, 1, G_MAXSIZE }, + { FALSE, 0, G_MAXSIZE, G_MAXSIZE } + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (cases); i++) + { + gsize result; + + g_assert_cmpuint (cases[i].success, ==, g_size_checked_add (&result, cases[i].a, cases[i].b)); + if (cases[i].success) + g_assert_cmpuint (cases[i].c, ==, result); + } +} + +static void +test_checked_gsize_mul (void) +{ + static const Case cases[] = { + /* success c = a * b */ + { TRUE, 0, 0, 0 }, + { TRUE, 0, G_MAXSSIZE, 0 }, + { TRUE, G_MAXSSIZE, G_MAXSSIZE, 1 }, + { TRUE, 0, G_MAXSIZE, 0 }, + { TRUE, G_MAXSIZE, G_MAXSIZE, 1 }, + { TRUE, 2 * (gsize) G_MAXSSIZE, 2, G_MAXSSIZE }, + { TRUE, 2 * (gsize) G_MAXSSIZE, G_MAXSSIZE, 2 }, + { FALSE, 0, 3, G_MAXSSIZE }, + { FALSE, 0, G_MAXSSIZE, 3 } + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (cases); i++) + { + gsize result; + + g_assert_cmpuint (cases[i].success, ==, g_size_checked_mul (&result, cases[i].a, cases[i].b)); + if (cases[i].success) + g_assert_cmpuint (cases[i].c, ==, result); + } +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/glib/checked-math/guint-add", test_checked_guint_add); + g_test_add_func ("/glib/checked-math/guint-mul", test_checked_guint_mul); + g_test_add_func ("/glib/checked-math/guint64-add", test_checked_guint64_add); + g_test_add_func ("/glib/checked-math/guint64-mul", test_checked_guint64_mul); + g_test_add_func ("/glib/checked-math/gsize-add", test_checked_gsize_add); + g_test_add_func ("/glib/checked-math/gsize-mul", test_checked_gsize_mul); + + return g_test_run (); +} diff --git a/glib/tests/pages.ini b/glib/tests/pages.ini new file mode 100644 index 0000000..9efdaa5 --- /dev/null +++ b/glib/tests/pages.ini @@ -0,0 +1,92 @@ +[main_section] +fill_specific_length_for_alignment_purposes = 3 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_10 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_11 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_12 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_13 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_14 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_15 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_16 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_17 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_18 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_19 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_20 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_21 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_22 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_23 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_24 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_25 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_26 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_27 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_28 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_29 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_30 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_31 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_32 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_33 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_34 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_35 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_36 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_37 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_38 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_39 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_40 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_41 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_42 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_43 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_44 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_45 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_46 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_47 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_48 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_49 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_50 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_51 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_52 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_53 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_54 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_55 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_56 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_57 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_58 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_59 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_60 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_61 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_62 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_63 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_64 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_65 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_66 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_67 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_68 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_69 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_70 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_71 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_72 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_73 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_74 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_75 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_76 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_77 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_78 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_79 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_80 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_81 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_82 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_83 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_84 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_85 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_86 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_87 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_88 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_89 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_90 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_91 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_92 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_93 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_94 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_95 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_96 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_97 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_98 = 92 +fill_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw_99 = 92 diff --git a/glib/tests/path-test-subdir/meson.build b/glib/tests/path-test-subdir/meson.build new file mode 100644 index 0000000..351254c --- /dev/null +++ b/glib/tests/path-test-subdir/meson.build @@ -0,0 +1,6 @@ +executable('spawn-test-helper', 'spawn-test-helper.c', + c_args : test_cargs, + dependencies : test_deps, + install_dir: join_paths(installed_tests_execdir, 'path-test-subdir'), + install: installed_tests_enabled, +) diff --git a/glib/tests/path-test-subdir/spawn-test-helper.c b/glib/tests/path-test-subdir/spawn-test-helper.c new file mode 100644 index 0000000..f9f2cee --- /dev/null +++ b/glib/tests/path-test-subdir/spawn-test-helper.c @@ -0,0 +1,7 @@ +#include + +int main (void) +{ + fprintf (stderr, "this is spawn-test-helper from path-test-subdir\n"); + return 5; +} diff --git a/glib/tests/pattern.c b/glib/tests/pattern.c new file mode 100644 index 0000000..ecc27db --- /dev/null +++ b/glib/tests/pattern.c @@ -0,0 +1,271 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2001 Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include + +/* keep enum and structure of gpattern.c and patterntest.c in sync */ +typedef enum +{ + G_MATCH_ALL, /* "*A?A*" */ + G_MATCH_ALL_TAIL, /* "*A?AA" */ + G_MATCH_HEAD, /* "AAAA*" */ + G_MATCH_TAIL, /* "*AAAA" */ + G_MATCH_EXACT, /* "AAAAA" */ + G_MATCH_LAST +} GMatchType; + +struct _GPatternSpec +{ + GMatchType match_type; + guint pattern_length; + guint min_length; + guint max_length; + gchar *pattern; +}; + +typedef struct _CompileTest CompileTest; + +struct _CompileTest +{ + const gchar *src; + GMatchType match_type; + gchar *pattern; + guint min; +}; + +static CompileTest compile_tests[] = { + { "*A?B*", G_MATCH_ALL, "*A?B*", 3 }, + { "ABC*DEFGH", G_MATCH_ALL_TAIL, "HGFED*CBA", 8 }, + { "ABCDEF*GH", G_MATCH_ALL, "ABCDEF*GH", 8 }, + { "ABC**?***??**DEF*GH", G_MATCH_ALL, "ABC*???DEF*GH", 11 }, + { "**ABC***?🤌DEF**", G_MATCH_ALL, "*ABC*?🤌DEF*", 11 }, + { "*A?AA", G_MATCH_ALL_TAIL, "AA?A*", 4 }, + { "ABCD*", G_MATCH_HEAD, "ABCD", 4 }, + { "*ABCD", G_MATCH_TAIL, "ABCD", 4 }, + { "ABCDE", G_MATCH_EXACT, "ABCDE", 5 }, + { "A?C?E", G_MATCH_ALL, "A?C?E", 5 }, + { "*?x", G_MATCH_ALL_TAIL, "x?*", 2 }, + { "?*x", G_MATCH_ALL_TAIL, "x?*", 2 }, + { "*?*x", G_MATCH_ALL_TAIL, "x?*", 2 }, + { "x*??", G_MATCH_ALL_TAIL, "??*x", 3 } +}; + +static void +test_compilation (gconstpointer d) +{ + const CompileTest *test = d; + GPatternSpec *spec; + + spec = g_pattern_spec_new (test->src); + + g_assert_cmpint (spec->match_type, ==, test->match_type); + g_assert_cmpstr (spec->pattern, ==, test->pattern); + g_assert_cmpint (spec->pattern_length, ==, strlen (spec->pattern)); + g_assert_cmpint (spec->min_length, ==, test->min); + + g_pattern_spec_free (spec); +} + +static void +test_copy (gconstpointer d) +{ + const CompileTest *test = d; + GPatternSpec *p1, *p2; + + p1 = g_pattern_spec_new (test->src); + p2 = g_pattern_spec_copy (p1); + + g_assert_cmpint (p2->match_type, ==, test->match_type); + g_assert_cmpstr (p2->pattern, ==, test->pattern); + g_assert_cmpint (p2->pattern_length, ==, strlen (p1->pattern)); + g_assert_cmpint (p2->min_length, ==, test->min); + + g_pattern_spec_free (p1); + g_pattern_spec_free (p2); +} + +typedef struct _MatchTest MatchTest; + +struct _MatchTest +{ + const gchar *pattern; + const gchar *string; + gboolean match; +}; + +static MatchTest match_tests[] = +{ + { "*x", "x", TRUE }, + { "*x", "xx", TRUE }, + { "*x", "yyyx", TRUE }, + { "*x", "yyxy", FALSE }, + { "?x", "x", FALSE }, + { "?x", "xx", TRUE }, + { "?x", "yyyx", FALSE }, + { "?x", "yyxy", FALSE }, + { "*?x", "xx", TRUE }, + { "?*x", "xx", TRUE }, + { "*?x", "x", FALSE }, + { "?*x", "x", FALSE }, + { "*?*x", "yx", TRUE }, + { "*?*x", "xxxx", TRUE }, + { "x*??", "xyzw", TRUE }, + { "*x", "\xc3\x84x", TRUE }, + { "?x", "\xc3\x84x", TRUE }, + { "??x", "\xc3\x84x", FALSE }, + { "ab\xc3\xa4\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE }, + { "ab\xc3\xa4\xc3\xb6", "abao", FALSE }, + { "ab?\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE }, + { "ab?\xc3\xb6", "abao", FALSE }, + { "ab\xc3\xa4?", "ab\xc3\xa4\xc3\xb6", TRUE }, + { "ab\xc3\xa4?", "abao", FALSE }, + { "ab??", "ab\xc3\xa4\xc3\xb6", TRUE }, + { "ab*", "ab\xc3\xa4\xc3\xb6", TRUE }, + { "ab*\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE }, + { "ab*\xc3\xb6", "aba\xc3\xb6x\xc3\xb6", TRUE }, + { "", "abc", FALSE }, + { "", "", TRUE }, + { "abc", "abc", TRUE }, + { "*fo1*bar", "yyyfoxfo1bar", TRUE }, + { "12*fo1g*bar", "12yyyfoxfo1gbar", TRUE }, + { "__________:*fo1g*bar", "__________:yyyfoxfo1gbar", TRUE }, + { "*abc*cde", "abcde", FALSE }, + { "*abc*cde", "abccde", TRUE }, + { "*abc*cde", "abcxcde", TRUE }, + { "*abc*?cde", "abccde", FALSE }, + { "*abc*?cde", "abcxcde", TRUE }, + { "*abc*def", "abababcdededef", TRUE }, + { "*abc*def", "abcbcbcdededef", TRUE }, + { "*acbc*def", "acbcbcbcdededef", TRUE }, + { "*a?bc*def", "acbcbcbcdededef", TRUE }, + { "*abc*def", "bcbcbcdefdef", FALSE }, + { "*abc*def*ghi", "abcbcbcbcbcbcdefefdefdefghi", TRUE }, + { "*abc*def*ghi", "bcbcbcbcbcbcdefdefdefdefghi", FALSE }, + { "_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_*abc*def*ghi", "_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_abcbcbcbcbcbcdefefdefdefghi", TRUE }, + { "fooooooo*a*bc", "fooooooo_a_bd_a_bc", TRUE }, + { "x*?", "x", FALSE }, + { "abc*", "abc", TRUE }, + { "*", "abc", TRUE } +}; + +static void +test_match (gconstpointer d) +{ + const MatchTest *test = d; + GPatternSpec *p; + gchar *r; + + g_assert_cmpint (g_pattern_match_simple (test->pattern, test->string), ==, test->match); + + p = g_pattern_spec_new (test->pattern); + g_assert_cmpint (g_pattern_spec_match_string (p, test->string), ==, test->match); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_assert_cmpint (g_pattern_match_string (p, test->string), ==, test->match); + G_GNUC_END_IGNORE_DEPRECATIONS + + r = g_utf8_strreverse (test->string, -1); + g_assert_cmpint (g_pattern_spec_match (p, strlen (test->string), test->string, r), ==, test->match); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_assert_cmpint (g_pattern_match (p, strlen (test->string), test->string, r), ==, test->match); + G_GNUC_END_IGNORE_DEPRECATIONS + g_free (r); + + g_pattern_spec_free (p); +} + +typedef struct _EqualTest EqualTest; + +struct _EqualTest +{ + const gchar *pattern1; + const gchar *pattern2; + gboolean expected; +}; + +static EqualTest equal_tests[] = +{ + { "*A?B*", "*A?B*", TRUE }, + { "A*BCD", "A*BCD", TRUE }, + { "ABCD*", "ABCD****", TRUE }, + { "A1*", "A1*", TRUE }, + { "*YZ", "*YZ", TRUE }, + { "A1x", "A1x", TRUE }, + { "AB*CD", "AB**CD", TRUE }, + { "AB*?*CD", "AB*?CD", TRUE }, + { "AB*?CD", "AB?*CD", TRUE }, + { "AB*CD", "AB*?*CD", FALSE }, + { "ABC*", "ABC?", FALSE }, +}; + +static void +test_equal (gconstpointer d) +{ + const EqualTest *test = d; + GPatternSpec *p1, *p2; + + p1 = g_pattern_spec_new (test->pattern1); + p2 = g_pattern_spec_new (test->pattern2); + + g_assert_cmpint (g_pattern_spec_equal (p1, p2), ==, test->expected); + + g_pattern_spec_free (p1); + g_pattern_spec_free (p2); +} + + +int +main (int argc, char** argv) +{ + gsize i; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS (compile_tests); i++) + { + path = g_strdup_printf ("/pattern/compile/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &compile_tests[i], test_compilation); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (compile_tests); i++) + { + path = g_strdup_printf ("/pattern/copy/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &compile_tests[i], test_copy); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (match_tests); i++) + { + path = g_strdup_printf ("/pattern/match/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &match_tests[i], test_match); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (equal_tests); i++) + { + path = g_strdup_printf ("/pattern/equal/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &equal_tests[i], test_equal); + g_free (path); + } + + return g_test_run (); +} diff --git a/glib/tests/private.c b/glib/tests/private.c new file mode 100644 index 0000000..6ecf1a8 --- /dev/null +++ b/glib/tests/private.c @@ -0,0 +1,403 @@ +/* Unit tests for GPrivate and friends + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +/* test basics: + * - initial value is NULL + * - set/get work repeatedly + */ +static void +test_private1 (void) +{ + static GPrivate private = G_PRIVATE_INIT (NULL); + gpointer value; + + value = g_private_get (&private); + g_assert (value == NULL); + + g_private_set (&private, GINT_TO_POINTER(1)); + value = g_private_get (&private); + g_assert_cmpint (GPOINTER_TO_INT (value), ==, 1); + + g_private_set (&private, GINT_TO_POINTER(2)); + value = g_private_get (&private); + g_assert_cmpint (GPOINTER_TO_INT (value), ==, 2); +} + +static gint private2_destroy_count; + +static void +private2_destroy (gpointer data) +{ + g_atomic_int_inc (&private2_destroy_count); +} + +static GPrivate private2 = G_PRIVATE_INIT (private2_destroy); + +static gpointer +private2_func (gpointer data) +{ + gint value = GPOINTER_TO_INT (data); + gint i; + gint v, v2; + + for (i = 0; i < 1000; i++) + { + v = value + (i % 5); + g_private_set (&private2, GINT_TO_POINTER (v)); + g_usleep (1000); + v2 = GPOINTER_TO_INT (g_private_get (&private2)); + g_assert_cmpint (v, ==, v2); + } + + if (value % 2 == 0) + g_thread_exit (NULL); + + return NULL; +} + +/* test that + * - threads do not interfere with each other + * - destroy notifies are called for each thread exit + * - destroy notifies are called for g_thread_exit() too + * - destroy notifies are not called on g_private_set() + * - destroy notifies are called on g_private_replace() + */ +static void +test_private2 (void) +{ + GThread *thread[10]; + gint i; + + g_private_set (&private2, GINT_TO_POINTER (234)); + g_private_replace (&private2, GINT_TO_POINTER (123)); + + for (i = 0; i < 10; i++) + thread[i] = g_thread_create (private2_func, GINT_TO_POINTER (i), TRUE, NULL); + + for (i = 0; i < 10; i++) + g_thread_join (thread[i]); + + g_assert_cmpint (private2_destroy_count, ==, 11); +} + +static gboolean private3_freed; + +static void +private3_free (gpointer data) +{ + g_assert (data == (void*) 0x1234); + private3_freed = TRUE; +} + +#ifdef G_OS_WIN32 +#include +#include + +static guint __stdcall +#else +#include + +static gpointer +#endif +private3_func (gpointer data) +{ + static GPrivate key = G_PRIVATE_INIT (private3_free); + + g_private_set (&key, (void *) 0x1234); + + return 0; +} + +static void +test_private3 (void) +{ + g_assert (!private3_freed); + +#ifdef G_OS_WIN32 + { + HANDLE thread; + guint ignore; + thread = (HANDLE) _beginthreadex (NULL, 0, private3_func, NULL, 0, &ignore); + WaitForSingleObject (thread, INFINITE); + CloseHandle (thread); + + /* FIXME: with static compilation on Windows this test will fail because + * it is mixing up glib threads with Microsoft native thread API. See + * comment in gthread-win32.c for g_system_thread_exit() implementation. + * Fix is not straightforward, possible solution could be to use FLS + * functions (instead of TLS) as proposed in + * https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1655 + */ + if (!private3_freed) + { + g_test_skip ("FIXME: GPrivate with native win32 thread"); + return; + } + } +#else + { + pthread_t thread; + + pthread_create (&thread, NULL, private3_func, NULL); + pthread_join (thread, NULL); + } +#endif + g_assert (private3_freed); +} + +/* test basics: + * - static initialization works + * - initial value is NULL + * - get/set works repeatedly + */ +static GStaticPrivate sp1 = G_STATIC_PRIVATE_INIT; + +static void +test_static_private1 (void) +{ + gpointer value; + + value = g_static_private_get (&sp1); + g_assert (value == NULL); + + g_static_private_set (&sp1, GINT_TO_POINTER(1), NULL); + value = g_static_private_get (&sp1); + g_assert_cmpint (GPOINTER_TO_INT(value), ==, 1); + + g_static_private_set (&sp1, GINT_TO_POINTER(2), NULL); + value = g_static_private_get (&sp1); + g_assert_cmpint (GPOINTER_TO_INT(value), ==, 2); + + g_static_private_free (&sp1); + + value = g_static_private_get (&sp1); + g_assert (value == NULL); +} + +static gint sp2_destroy_count; + +static void +sp2_destroy (gpointer data) +{ + sp2_destroy_count++; +} + +static void +sp2_destroy2 (gpointer data) +{ + gint value = GPOINTER_TO_INT (data); + + g_assert_cmpint (value, ==, 2); +} + +/* test that destroy notifies are called as expected + * and on the right values + */ +static void +test_static_private2 (void) +{ + GStaticPrivate sp2; + gpointer value; + + g_static_private_init (&sp2); + + value = g_static_private_get (&sp2); + g_assert (value == NULL); + + g_static_private_set (&sp2, GINT_TO_POINTER(1), sp2_destroy); + g_assert_cmpint (sp2_destroy_count, ==, 0); + value = g_static_private_get (&sp2); + g_assert_cmpint (GPOINTER_TO_INT(value), ==, 1); + + g_static_private_set (&sp2, GINT_TO_POINTER(2), sp2_destroy2); + g_assert_cmpint (sp2_destroy_count, ==, 1); + value = g_static_private_get (&sp2); + g_assert_cmpint (GPOINTER_TO_INT(value), ==, 2); + + g_static_private_set (&sp2, GINT_TO_POINTER(3), sp2_destroy); + g_assert_cmpint (sp2_destroy_count, ==, 1); + value = g_static_private_get (&sp2); + g_assert_cmpint (GPOINTER_TO_INT(value), ==, 3); + + g_static_private_free (&sp2); + + value = g_static_private_get (&sp2); + g_assert (value == NULL); +} + +/* test that freeing and reinitializing a static private + * drops previous value + */ +static void +test_static_private3 (void) +{ + GStaticPrivate sp3; + gpointer value; + + g_static_private_init (&sp3); + + value = g_static_private_get (&sp3); + g_assert (value == NULL); + + g_static_private_set (&sp3, GINT_TO_POINTER(1), NULL); + value = g_static_private_get (&sp3); + g_assert_cmpint (GPOINTER_TO_INT(value), ==, 1); + + g_static_private_free (&sp3); + g_static_private_init (&sp3); + + value = g_static_private_get (&sp3); + g_assert (value == NULL); + + g_static_private_set (&sp3, GINT_TO_POINTER(2), NULL); + value = g_static_private_get (&sp3); + g_assert_cmpint (GPOINTER_TO_INT(value), ==, 2); + + g_static_private_free (&sp3); +} + +static GStaticPrivate sp4 = G_STATIC_PRIVATE_INIT; + +static gpointer +sp4_func (gpointer data) +{ + gint value = GPOINTER_TO_INT (data); + gint i; + gint v, v2; + + for (i = 0; i < 1000; i++) + { + v = value + (i % 5); + g_static_private_set (&sp4, GINT_TO_POINTER(v), NULL); + g_usleep (1000); + v2 = GPOINTER_TO_INT(g_static_private_get (&sp4)); + g_assert_cmpint (v, ==, v2); + } + + if (value % 2 == 0) + g_thread_exit (NULL); + + return NULL; +} + +/* test that threads do not interfere with each other + */ +static void +test_static_private4 (void) +{ + GThread *thread[10]; + gint i; + + for (i = 0; i < 10; i++) + thread[i] = g_thread_create (sp4_func, GINT_TO_POINTER (i), TRUE, NULL); + + for (i = 0; i < 10; i++) + g_thread_join (thread[i]); + + g_static_private_free (&sp4); +} + +static GStaticPrivate sp5 = G_STATIC_PRIVATE_INIT; +static GMutex m5; +static GCond c5a; +static GCond c5b; +static gint count5; + +static gpointer +sp5_func (gpointer data) +{ + gint v = GPOINTER_TO_INT (data); + gpointer value; + + value = g_static_private_get (&sp5); + g_assert (value == NULL); + + g_static_private_set (&sp5, GINT_TO_POINTER (v), NULL); + value = g_static_private_get (&sp5); + g_assert_cmpint (GPOINTER_TO_INT (value), ==, v); + + if (g_test_verbose ()) + g_printerr ("thread %d set sp5\n", v); + g_mutex_lock (&m5); + g_atomic_int_inc (&count5); + g_cond_signal (&c5a); + g_cond_wait (&c5b, &m5); + g_mutex_unlock (&m5); + + if (g_test_verbose ()) + g_printerr ("thread %d get sp5\n", v); + value = g_static_private_get (&sp5); + g_assert (value == NULL); + + return NULL; +} + +static void +test_static_private5 (void) +{ + GThread *thread[10]; + gint i; + + g_atomic_int_set (&count5, 0); + + for (i = 0; i < 10; i++) + thread[i] = g_thread_create (sp5_func, GINT_TO_POINTER (i), TRUE, NULL); + + g_mutex_lock (&m5); + while (g_atomic_int_get (&count5) < 10) + g_cond_wait (&c5a, &m5); + + if (g_test_verbose ()) + g_printerr ("sp5 gets nuked\n"); + + g_static_private_free (&sp5); + + g_cond_broadcast (&c5b); + g_mutex_unlock (&m5); + + for (i = 0; i < 10; i++) + g_thread_join (thread[i]); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/thread/private1", test_private1); + g_test_add_func ("/thread/private2", test_private2); + g_test_add_func ("/thread/private3", test_private3); + g_test_add_func ("/thread/staticprivate1", test_static_private1); + g_test_add_func ("/thread/staticprivate2", test_static_private2); + g_test_add_func ("/thread/staticprivate3", test_static_private3); + g_test_add_func ("/thread/staticprivate4", test_static_private4); + g_test_add_func ("/thread/staticprivate5", test_static_private5); + + return g_test_run (); +} diff --git a/glib/tests/protocol.c b/glib/tests/protocol.c new file mode 100644 index 0000000..b03aaf9 --- /dev/null +++ b/glib/tests/protocol.c @@ -0,0 +1,382 @@ +/* This file is part of GLib + * + * Copyright (C) 2010 Sven Herzberg + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include /* errno */ +#include +#ifdef G_OS_UNIX +#include /* pipe() */ +#endif +#ifdef G_OS_WIN32 +#include +#include +#define pipe(fds) _pipe(fds, 4096, _O_BINARY) +#endif + +static const char *argv0; + +static void +debug (void) +{ + if (g_test_subprocess ()) + g_debug ("this is a regular g_debug() from the test suite"); +} + +static void +info (void) +{ + if (g_test_subprocess ()) + g_info ("this is a regular g_info from the test suite"); +} + +static void +message (void) +{ + if (g_test_subprocess ()) + g_message ("this is a regular g_message() from the test suite"); +} + +static void +warning (void) +{ + if (g_test_subprocess ()) + g_warning ("this is a regular g_warning() from the test suite"); +} + +static void +critical (void) +{ + if (g_test_subprocess ()) + g_critical ("this is a regular g_critical() from the test suite"); +} + +static void +error (void) +{ + if (g_test_subprocess ()) + g_error ("this is a regular g_error() from the test suite"); +} + +static void +gtest_message (void) +{ + if (g_test_subprocess ()) + g_test_message ("this is a regular g_test_message() from the test suite"); +} + +static gboolean +test_message_cb1 (GIOChannel * channel, + GIOCondition condition, + gpointer user_data) +{ + GIOStatus status; + guchar buf[512]; + gsize read_bytes = 0; + + g_assert_cmpuint (condition, ==, G_IO_IN); + + for (status = g_io_channel_read_chars (channel, (gchar*)buf, sizeof (buf), &read_bytes, NULL); + status == G_IO_STATUS_NORMAL; + status = g_io_channel_read_chars (channel, (gchar*)buf, sizeof (buf), &read_bytes, NULL)) + { + g_test_log_buffer_push (user_data, read_bytes, buf); + } + + if (status == G_IO_STATUS_EOF) + return FALSE; + else + g_assert_cmpuint (status, ==, G_IO_STATUS_AGAIN); + + return TRUE; +} + +static void +test_message_cb2 (GPid pid, + gint status, + gpointer user_data) +{ + g_spawn_close_pid (pid); + + g_main_loop_quit (user_data); +} + +static void +test_message (void) +{ + gchar* argv[] = { + (gchar*)argv0, + NULL, + "--GTestSubprocess", + "-p", "/glib/testing/protocol/gtest-message", + "-p", "/glib/testing/protocol/message", + "-p", "/glib/testing/protocol/debug", + NULL + }; + GTestLogBuffer* tlb; + GTestLogMsg * msg; + GIOChannel * channel; + GMainLoop * loop; + GError * error = NULL; + gulong child_source; + GPid pid = 0; + int pipes[2]; + int passed = 0; + int messages = 0; + const char * line_term; + int line_term_len; + + if (0 > pipe (pipes)) + { + int errsv = errno; + g_error ("error creating pipe: %s", g_strerror (errsv)); + } + + argv[1] = g_strdup_printf ("--GTestLogFD=%u", pipes[1]); + + if (!g_spawn_async (NULL, + argv, NULL, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_LEAVE_DESCRIPTORS_OPEN | + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &pid, + &error)) + { + g_error ("error spawning the test: %s", error->message); + } + + close (pipes[1]); + tlb = g_test_log_buffer_new (); + loop = g_main_loop_new (NULL, FALSE); + +#ifdef G_OS_WIN32 + channel = g_io_channel_win32_new_fd (pipes[0]); +#else + channel = g_io_channel_unix_new (pipes[0]); +#endif + g_io_channel_set_close_on_unref (channel, TRUE); + g_io_channel_set_encoding (channel, NULL, NULL); + g_io_channel_set_buffered (channel, FALSE); + g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); + g_assert (g_io_channel_get_line_term (channel, NULL) == NULL); + g_io_channel_set_line_term (channel, "\n", 1); + line_term = g_io_channel_get_line_term (channel, &line_term_len); + g_assert_cmpint (*line_term, ==, '\n'); + g_assert_cmpint (line_term_len, ==, 1); + + g_assert (g_io_channel_get_close_on_unref (channel)); + g_assert (g_io_channel_get_encoding (channel) == NULL); + g_assert (!g_io_channel_get_buffered (channel)); + + g_io_add_watch (channel, G_IO_IN, test_message_cb1, tlb); + child_source = g_child_watch_add (pid, test_message_cb2, loop); + + g_main_loop_run (loop); + + test_message_cb1 (channel, G_IO_IN, tlb); + + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "Source ID*"); + g_assert (!g_source_remove (child_source)); + g_test_assert_expected_messages (); + g_io_channel_unref (channel); + + for (msg = g_test_log_buffer_pop (tlb); + msg; + msg = g_test_log_buffer_pop (tlb)) + { + switch (msg->log_type) + { + case G_TEST_LOG_START_BINARY: + case G_TEST_LOG_START_CASE: + case G_TEST_LOG_START_SUITE: + case G_TEST_LOG_STOP_SUITE: + /* ignore */ + break; + case G_TEST_LOG_STOP_CASE: + passed++; + break; + case G_TEST_LOG_MESSAGE: + { + gchar const* known_messages[] = { + "this is a regular g_test_message() from the test suite", + "GLib-MESSAGE: this is a regular g_message() from the test suite", + "GLib-DEBUG: this is a regular g_debug() from the test suite" + }; + g_assert_cmpint (messages, <, G_N_ELEMENTS (known_messages)); + g_assert_cmpstr (msg->strings[0], ==, known_messages[messages]); + messages++; + } + break; + case G_TEST_LOG_ERROR: + g_assert_not_reached (); + break; + default: + g_error ("unexpected log message type: %s", g_test_log_type_name (msg->log_type)); + } + g_test_log_msg_free (msg); + } + + g_assert_cmpint (passed, ==, 3); + g_assert_cmpint (messages, ==, 3); + + g_free (argv[1]); + g_main_loop_unref (loop); + g_test_log_buffer_free (tlb); +} + +static void +test_error (void) +{ + gchar* tests[] = { + "/glib/testing/protocol/warning", + "/glib/testing/protocol/critical", + "/glib/testing/protocol/error" + }; + gsize i; + int messages = 0; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + gchar* argv[] = { + (gchar*)argv0, + NULL, + "--GTestSubprocess", + "-p", tests[i], + NULL + }; + GTestLogBuffer* tlb; + GTestLogMsg * msg; + GIOChannel * channel; + GMainLoop * loop; + GError * error = NULL; + gulong child_source; + GPid pid = 0; + int pipes[2]; + + if (0 > pipe (pipes)) + { + int errsv = errno; + g_error ("error creating pipe: %s", g_strerror (errsv)); + } + + argv[1] = g_strdup_printf ("--GTestLogFD=%u", pipes[1]); + + if (!g_spawn_async (NULL, + argv, NULL, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_LEAVE_DESCRIPTORS_OPEN | + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &pid, + &error)) + { + g_error ("error spawning the test: %s", error->message); + } + + close (pipes[1]); + tlb = g_test_log_buffer_new (); + loop = g_main_loop_new (NULL, FALSE); + +#ifdef G_OS_WIN32 + channel = g_io_channel_win32_new_fd (pipes[0]); +#else + channel = g_io_channel_unix_new (pipes[0]); +#endif + g_io_channel_set_close_on_unref (channel, TRUE); + g_io_channel_set_encoding (channel, NULL, NULL); + g_io_channel_set_buffered (channel, FALSE); + g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); + + g_io_add_watch (channel, G_IO_IN, test_message_cb1, tlb); + child_source = g_child_watch_add (pid, test_message_cb2, loop); + + g_main_loop_run (loop); + + test_message_cb1 (channel, G_IO_IN, tlb); + + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "Source ID*"); + g_assert (!g_source_remove (child_source)); + g_test_assert_expected_messages (); + g_io_channel_unref (channel); + + for (msg = g_test_log_buffer_pop (tlb); + msg; + msg = g_test_log_buffer_pop (tlb)) + { + switch (msg->log_type) + { + case G_TEST_LOG_START_BINARY: + case G_TEST_LOG_START_CASE: + case G_TEST_LOG_START_SUITE: + case G_TEST_LOG_STOP_SUITE: + /* ignore */ + break; + case G_TEST_LOG_STOP_CASE: + case G_TEST_LOG_MESSAGE: + g_assert_not_reached (); + break; + case G_TEST_LOG_ERROR: + { + gchar const* known_messages[] = { + "GLib-FATAL-WARNING: this is a regular g_warning() from the test suite", + "GLib-FATAL-CRITICAL: this is a regular g_critical() from the test suite", + "GLib-FATAL-ERROR: this is a regular g_error() from the test suite" + }; + g_assert_cmpint (messages, <, G_N_ELEMENTS (known_messages)); + g_assert_cmpstr (msg->strings[0], ==, known_messages[messages]); + messages++; + } + break; + default: + g_error ("unexpected log message type: %s", g_test_log_type_name (msg->log_type)); + } + g_test_log_msg_free (msg); + } + + g_free (argv[1]); + g_main_loop_unref (loop); + g_test_log_buffer_free (tlb); + } + + g_assert_cmpint (messages, ==, 3); +} + +int +main (int argc, + char**argv) +{ + argv0 = argv[0]; + + g_test_init (&argc, &argv, NULL); + + /* we use ourself as the testcase, these are the ones we need internally */ + g_test_add_func ("/glib/testing/protocol/debug", debug); + g_test_add_func ("/glib/testing/protocol/info", info); + g_test_add_func ("/glib/testing/protocol/message", message); + g_test_add_func ("/glib/testing/protocol/warning", warning); + g_test_add_func ("/glib/testing/protocol/critical", critical); + g_test_add_func ("/glib/testing/protocol/error", error); + g_test_add_func ("/glib/testing/protocol/gtest-message", gtest_message); + + /* these are the real tests */ + g_test_add_func ("/glib/testing/protocol/test-message", test_message); + g_test_add_func ("/glib/testing/protocol/test-error", test_error); + + return g_test_run (); +} + +/* vim:set et sw=2 cino=t0,f0,(0,{s,>2s,n-1s,^-1s,e2s: */ diff --git a/glib/tests/queue.c b/glib/tests/queue.c new file mode 100644 index 0000000..f092f6b --- /dev/null +++ b/glib/tests/queue.c @@ -0,0 +1,1298 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include + +#include + + +static void +check_integrity (GQueue *queue) +{ + GList *list; + GList *last; + GList *links; + GList *link; + guint n; + + g_assert (queue->length < 4000000000u); + + g_assert (g_queue_get_length (queue) == queue->length); + + if (!queue->head) + g_assert (!queue->tail); + if (!queue->tail) + g_assert (!queue->head); + + n = 0; + last = NULL; + for (list = queue->head; list != NULL; list = list->next) + { + if (!list->next) + last = list; + ++n; + } + g_assert (n == queue->length); + g_assert (last == queue->tail); + + n = 0; + last = NULL; + for (list = queue->tail; list != NULL; list = list->prev) + { + if (!list->prev) + last = list; + ++n; + } + g_assert (n == queue->length); + g_assert (last == queue->head); + + links = NULL; + for (list = queue->head; list != NULL; list = list->next) + links = g_list_prepend (links, list); + + link = links; + for (list = queue->tail; list != NULL; list = list->prev) + { + g_assert (list == link->data); + link = link->next; + } + g_list_free (links); + + links = NULL; + for (list = queue->tail; list != NULL; list = list->prev) + links = g_list_prepend (links, list); + + link = links; + for (list = queue->head; list != NULL; list = list->next) + { + g_assert (list == link->data); + link = link->next; + } + g_list_free (links); +} + +static gboolean +rnd_bool (void) +{ + return g_random_int_range (0, 2); +} + +static void +check_max (gpointer elm, gpointer user_data) +{ + gint *best = user_data; + gint element = GPOINTER_TO_INT (elm); + + if (element > *best) + *best = element; +} + +static void +check_min (gpointer elm, gpointer user_data) +{ + gint *best = user_data; + gint element = GPOINTER_TO_INT (elm); + + if (element < *best) + *best = element; +} + +static gint +find_min (GQueue *queue) +{ + gint min = G_MAXINT; + + g_queue_foreach (queue, check_min, &min); + + return min; +} + +static gint +find_max (GQueue *queue) +{ + gint max = G_MININT; + + g_queue_foreach (queue, check_max, &max); + + return max; +} + +static void +delete_elm (gpointer elm, gpointer user_data) +{ + g_queue_remove ((GQueue *)user_data, elm); + check_integrity ((GQueue *)user_data); +} + +static void +delete_all (GQueue *queue) +{ + g_queue_foreach (queue, delete_elm, queue); +} + +static int +compare_int (gconstpointer a, gconstpointer b, gpointer data) +{ + int ai = GPOINTER_TO_INT (a); + int bi = GPOINTER_TO_INT (b); + + if (ai > bi) + return 1; + else if (ai == bi) + return 0; + else + return -1; +} + +static gint +get_random_position (GQueue *queue, gboolean allow_offlist) +{ + int n; + enum { OFF_QUEUE, HEAD, TAIL, MIDDLE, LAST } where; + + if (allow_offlist) + where = g_random_int_range (OFF_QUEUE, LAST); + else + where = g_random_int_range (HEAD, LAST); + + switch (where) + { + case OFF_QUEUE: + n = g_random_int (); + break; + + case HEAD: + n = 0; + break; + + case TAIL: + if (allow_offlist) + n = queue->length; + else + n = queue->length - 1; + break; + + case MIDDLE: + if (queue->length == 0) + n = 0; + else + n = g_random_int_range (0, queue->length); + break; + + default: + g_assert_not_reached(); + n = 100; + break; + + } + + return n; +} + +static void +random_test (gconstpointer d) +{ + guint32 seed = GPOINTER_TO_UINT (d); + + typedef enum { + IS_EMPTY, GET_LENGTH, REVERSE, COPY, + FOREACH, FIND, FIND_CUSTOM, SORT, + PUSH_HEAD, PUSH_TAIL, PUSH_NTH, POP_HEAD, + POP_TAIL, POP_NTH, PEEK_HEAD, PEEK_TAIL, + PEEK_NTH, INDEX, REMOVE, REMOVE_ALL, + INSERT_BEFORE, INSERT_AFTER, INSERT_SORTED, PUSH_HEAD_LINK, + PUSH_TAIL_LINK, PUSH_NTH_LINK, POP_HEAD_LINK, POP_TAIL_LINK, + POP_NTH_LINK, PEEK_HEAD_LINK, PEEK_TAIL_LINK, PEEK_NTH_LINK, + LINK_INDEX, UNLINK, DELETE_LINK, LAST_OP + } QueueOp; + +#define N_ITERATIONS 500000 +#define N_QUEUES 3 + +#define RANDOM_QUEUE() &(queues[g_random_int_range(0, N_QUEUES)]) + + typedef struct QueueInfo QueueInfo; + struct QueueInfo + { + GQueue *queue; + GList *tail; + GList *head; + guint length; + }; + + gint i; + QueueOp op; + QueueInfo queues[N_QUEUES]; + + g_random_set_seed (seed); + + for (i = 0; i < N_QUEUES; ++i) + { + queues[i].queue = g_queue_new (); + queues[i].head = NULL; + queues[i].tail = NULL; + queues[i].length = 0; + } + + for (i = 0; i < N_ITERATIONS; ++i) + { + int j; + QueueInfo *qinf = RANDOM_QUEUE(); + GQueue *q = qinf->queue; + op = g_random_int_range (IS_EMPTY, LAST_OP); + + g_assert (qinf->head == q->head); + g_assert (qinf->tail == q->tail); + g_assert (qinf->length == q->length); + + switch (op) + { + case IS_EMPTY: + { + if (g_queue_is_empty (qinf->queue)) + { + g_assert (q->head == NULL); + g_assert (q->tail == NULL); + g_assert (q->length == 0); + } + else + { + g_assert (q->head); + g_assert (q->tail); + g_assert (q->length > 0); + } + } + break; + case GET_LENGTH: + { + guint l; + + l = g_queue_get_length (q); + + g_assert (qinf->length == q->length); + g_assert (qinf->length == l); + } + break; + case REVERSE: + g_queue_reverse (q); + g_assert (qinf->tail == q->head); + g_assert (qinf->head == q->tail); + g_assert (qinf->length == q->length); + qinf->tail = q->tail; + qinf->head = q->head; + break; + case COPY: + { + QueueInfo *random_queue = RANDOM_QUEUE(); + GQueue *new_queue = g_queue_copy (random_queue->queue); + + g_queue_free (qinf->queue); + q = qinf->queue = new_queue; + qinf->head = new_queue->head; + qinf->tail = g_list_last (new_queue->head); + qinf->length = new_queue->length; + } + break; + case FOREACH: + delete_all (q); + qinf->head = NULL; + qinf->tail = NULL; + qinf->length = 0; + break; + case FIND: + { + gboolean find_existing = rnd_bool (); + int first = find_max (q); + int second = find_min (q); + + if (q->length == 0) + find_existing = FALSE; + + if (!find_existing) + first++; + if (!find_existing) + second--; + + if (find_existing) + { + g_assert (g_queue_find (q, GINT_TO_POINTER (first))); + g_assert (g_queue_find (q, GINT_TO_POINTER (second))); + } + else + { + g_assert (!g_queue_find (q, GINT_TO_POINTER (first))); + g_assert (!g_queue_find (q, GINT_TO_POINTER (second))); + } + } + break; + case FIND_CUSTOM: + break; + case SORT: + { + if (!g_queue_is_empty (q)) + { + int max = find_max (q); + int min = find_min (q); + g_queue_remove_all (q, GINT_TO_POINTER (max)); + check_integrity (q); + g_queue_remove_all (q, GINT_TO_POINTER (min)); + check_integrity (q); + g_queue_push_head (q, GINT_TO_POINTER (max)); + if (max != min) + g_queue_push_head (q, GINT_TO_POINTER (min)); + qinf->length = q->length; + } + + check_integrity (q); + + g_queue_sort (q, compare_int, NULL); + + check_integrity (q); + + qinf->head = g_queue_find (q, GINT_TO_POINTER (find_min(q))); + qinf->tail = g_queue_find (q, GINT_TO_POINTER (find_max(q))); + + g_assert (qinf->tail == q->tail); + } + break; + case PUSH_HEAD: + { + int x = g_random_int_range (0, 435435); + g_queue_push_head (q, GINT_TO_POINTER (x)); + if (!qinf->head) + qinf->tail = qinf->head = q->head; + else + qinf->head = qinf->head->prev; + qinf->length++; + } + break; + case PUSH_TAIL: + { + int x = g_random_int_range (0, 236546); + g_queue_push_tail (q, GINT_TO_POINTER (x)); + if (!qinf->tail) + qinf->tail = qinf->head = q->head; + else + qinf->tail = qinf->tail->next; + qinf->length++; + } + break; + case PUSH_NTH: + { + int pos = get_random_position (q, TRUE); + int x = g_random_int_range (0, 236546); + g_queue_push_nth (q, GINT_TO_POINTER (x), pos); + if (qinf->head && qinf->head->prev) + qinf->head = qinf->head->prev; + else + qinf->head = q->head; + if (qinf->tail && qinf->tail->next) + qinf->tail = qinf->tail->next; + else + qinf->tail = g_list_last (qinf->head); + qinf->length++; + } + break; + case POP_HEAD: + if (qinf->head) + qinf->head = qinf->head->next; + if (!qinf->head) + qinf->tail = NULL; + qinf->length = (qinf->length == 0)? 0 : qinf->length - 1; + g_queue_pop_head (q); + break; + case POP_TAIL: + if (qinf->tail) + qinf->tail = qinf->tail->prev; + if (!qinf->tail) + qinf->head = NULL; + qinf->length = (qinf->length == 0)? 0 : qinf->length - 1; + g_queue_pop_tail (q); + break; + case POP_NTH: + if (!g_queue_is_empty (q)) + { + int n = get_random_position (q, TRUE); + gpointer elm = g_queue_peek_nth (q, n); + + if (n == (int) (q->length - 1)) + qinf->tail = qinf->tail->prev; + + if (n == 0) + qinf->head = qinf->head->next; + + if (n >= 0 && (guint) n < q->length) + qinf->length--; + + g_assert (elm == g_queue_pop_nth (q, n)); + } + break; + case PEEK_HEAD: + if (qinf->head) + g_assert (qinf->head->data == g_queue_peek_head (q)); + else + g_assert (g_queue_peek_head (q) == NULL); + break; + case PEEK_TAIL: + if (qinf->tail) + g_assert (qinf->tail->data == g_queue_peek_tail (q)); + else + g_assert (g_queue_peek_tail (q) == NULL); + break; + case PEEK_NTH: + if (g_queue_is_empty (q)) + { + for (j = -10; j < 10; ++j) + g_assert (g_queue_peek_nth (q, j) == NULL); + } + else + { + GList *list; + int n = get_random_position (q, TRUE); + if (n < 0 || (guint) n >= q->length) + { + g_assert (g_queue_peek_nth (q, n) == NULL); + } + else + { + list = qinf->head; + for (j = 0; j < n; ++j) + list = list->next; + + g_assert (list->data == g_queue_peek_nth (q, n)); + } + } + break; + case INDEX: + case LINK_INDEX: + { + int x = g_random_int_range (0, 386538); + int n; + GList *list; + + g_queue_remove_all (q, GINT_TO_POINTER (x)); + check_integrity (q); + g_queue_push_tail (q, GINT_TO_POINTER (x)); + check_integrity (q); + g_queue_sort (q, compare_int, NULL); + check_integrity (q); + + n = 0; + for (list = q->head; list != NULL; list = list->next) + { + if (list->data == GINT_TO_POINTER (x)) + break; + n++; + } + g_assert (list); + g_assert (g_queue_index (q, GINT_TO_POINTER (x)) == + g_queue_link_index (q, list)); + g_assert (g_queue_link_index (q, list) == n); + + qinf->head = q->head; + qinf->tail = q->tail; + qinf->length = q->length; + } + break; + case REMOVE: + if (!g_queue_is_empty (q)) + g_queue_remove (q, qinf->tail->data); + /* qinf->head/qinf->tail may be invalid at this point */ + if (!g_queue_is_empty (q)) + g_queue_remove (q, q->head->data); + if (!g_queue_is_empty (q)) + g_queue_remove (q, g_queue_peek_nth (q, get_random_position (q, TRUE))); + + qinf->head = q->head; + qinf->tail = q->tail; + qinf->length = q->length; + break; + case REMOVE_ALL: + if (!g_queue_is_empty (q)) + g_queue_remove_all (q, qinf->tail->data); + /* qinf->head/qinf->tail may be invalid at this point */ + if (!g_queue_is_empty (q)) + g_queue_remove_all (q, q->head->data); + if (!g_queue_is_empty (q)) + g_queue_remove_all (q, g_queue_peek_nth (q, get_random_position (q, TRUE))); + + qinf->head = q->head; + qinf->tail = q->tail; + qinf->length = q->length; + break; + case INSERT_BEFORE: + if (!g_queue_is_empty (q)) + { + gpointer x = GINT_TO_POINTER (g_random_int_range (0, 386538)); + + g_queue_insert_before (q, qinf->tail, x); + g_queue_insert_before (q, qinf->head, x); + g_queue_insert_before (q, g_queue_find (q, x), x); + g_queue_insert_before (q, NULL, x); + } + qinf->head = q->head; + qinf->tail = q->tail; + qinf->length = q->length; + break; + case INSERT_AFTER: + if (!g_queue_is_empty (q)) + { + gpointer x = GINT_TO_POINTER (g_random_int_range (0, 386538)); + + g_queue_insert_after (q, qinf->tail, x); + g_queue_insert_after (q, qinf->head, x); + g_queue_insert_after (q, g_queue_find (q, x), x); + g_queue_insert_after (q, NULL, x); + } + qinf->head = q->head; + qinf->tail = q->tail; + qinf->length = q->length; + break; + case INSERT_SORTED: + { + int max = find_max (q); + int min = find_min (q); + + if (g_queue_is_empty (q)) + { + max = 345; + min = -12; + } + + g_queue_sort (q, compare_int, NULL); + check_integrity (q); + g_queue_insert_sorted (q, GINT_TO_POINTER (max + 1), compare_int, NULL); + check_integrity (q); + g_assert (GPOINTER_TO_INT (q->tail->data) == max + 1); + g_queue_insert_sorted (q, GINT_TO_POINTER (min - 1), compare_int, NULL); + check_integrity (q); + g_assert (GPOINTER_TO_INT (q->head->data) == min - 1); + qinf->head = q->head; + qinf->tail = q->tail; + qinf->length = q->length; + } + break; + case PUSH_HEAD_LINK: + { + GList *link = g_list_prepend (NULL, GINT_TO_POINTER (i)); + g_queue_push_head_link (q, link); + if (!qinf->tail) + qinf->tail = link; + qinf->head = link; + qinf->length++; + } + break; + case PUSH_TAIL_LINK: + { + GList *link = g_list_prepend (NULL, GINT_TO_POINTER (i)); + g_queue_push_tail_link (q, link); + if (!qinf->head) + qinf->head = link; + qinf->tail = link; + qinf->length++; + } + break; + case PUSH_NTH_LINK: + { + GList *link = g_list_prepend (NULL, GINT_TO_POINTER (i)); + gint n = get_random_position (q, TRUE); + g_queue_push_nth_link (q, n, link); + + if (qinf->head && qinf->head->prev) + qinf->head = qinf->head->prev; + else + qinf->head = q->head; + if (qinf->tail && qinf->tail->next) + qinf->tail = qinf->tail->next; + else + qinf->tail = g_list_last (qinf->head); + qinf->length++; + } + break; + case POP_HEAD_LINK: + if (!g_queue_is_empty (q)) + { + qinf->head = qinf->head->next; + if (!qinf->head) + qinf->tail = NULL; + qinf->length--; + g_list_free (g_queue_pop_head_link (q)); + } + break; + case POP_TAIL_LINK: + if (!g_queue_is_empty (q)) + { + qinf->tail = qinf->tail->prev; + if (!qinf->tail) + qinf->head = NULL; + qinf->length--; + g_list_free (g_queue_pop_tail_link (q)); + } + break; + case POP_NTH_LINK: + if (g_queue_is_empty (q)) + g_assert (g_queue_pop_nth_link (q, 200) == NULL); + else + { + int n = get_random_position (q, FALSE); + + if (n == (int) (g_queue_get_length (q) - 1)) + qinf->tail = qinf->tail->prev; + + if (n == 0) + qinf->head = qinf->head->next; + + qinf->length--; + + g_list_free (g_queue_pop_nth_link (q, n)); + } + break; + case PEEK_HEAD_LINK: + if (g_queue_is_empty (q)) + g_assert (g_queue_peek_head_link (q) == NULL); + else + g_assert (g_queue_peek_head_link (q) == qinf->head); + break; + case PEEK_TAIL_LINK: + if (g_queue_is_empty (q)) + g_assert (g_queue_peek_tail_link (q) == NULL); + else + g_assert (g_queue_peek_tail_link (q) == qinf->tail); + break; + case PEEK_NTH_LINK: + if (g_queue_is_empty(q)) + g_assert (g_queue_peek_nth_link (q, 1000) == NULL); + else + { + gint n = get_random_position (q, FALSE); + GList *link; + + link = q->head; + for (j = 0; j < n; ++j) + link = link->next; + + g_assert (g_queue_peek_nth_link (q, n) == link); + } + break; + case UNLINK: + if (!g_queue_is_empty (q)) + { + gint n = g_random_int_range (0, g_queue_get_length (q)); + GList *link; + + link = q->head; + for (j = 0; j < n; ++j) + link = link->next; + + g_queue_unlink (q, link); + check_integrity (q); + + g_list_free (link); + + qinf->head = q->head; + qinf->tail = q->tail; + qinf->length--; + } + break; + case DELETE_LINK: + if (!g_queue_is_empty (q)) + { + gint n = g_random_int_range (0, g_queue_get_length (q)); + GList *link; + + link = q->head; + for (j = 0; j < n; ++j) + link = link->next; + + g_queue_delete_link (q, link); + check_integrity (q); + + qinf->head = q->head; + qinf->tail = q->tail; + qinf->length--; + } + break; + case LAST_OP: + default: + g_assert_not_reached(); + break; + } + + if (qinf->head != q->head || + qinf->tail != q->tail || + qinf->length != q->length) + g_printerr ("op: %d\n", op); + + g_assert (qinf->head == q->head); + g_assert (qinf->tail == q->tail); + g_assert (qinf->length == q->length); + + for (j = 0; j < N_QUEUES; ++j) + check_integrity (queues[j].queue); + } + + for (i = 0; i < N_QUEUES; ++i) + g_queue_free (queues[i].queue); +} + +static void +remove_item (gpointer data, gpointer q) +{ + GQueue *queue = q; + + g_queue_remove (queue, data); +} + +static void +test_basic (void) +{ + GQueue *q; + GList *node; + gpointer data; + + q = g_queue_new (); + + g_assert (g_queue_is_empty (q)); + g_queue_push_head (q, GINT_TO_POINTER (2)); + check_integrity (q); + g_assert (g_queue_peek_head (q) == GINT_TO_POINTER (2)); + check_integrity (q); + g_assert (!g_queue_is_empty (q)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 1); + g_assert (q->head == q->tail); + g_queue_push_head (q, GINT_TO_POINTER (1)); + check_integrity (q); + g_assert (q->head->next == q->tail); + g_assert (q->tail->prev == q->head); + g_assert_cmpint (g_list_length (q->head), ==, 2); + check_integrity (q); + g_assert (q->tail->data == GINT_TO_POINTER (2)); + g_assert (q->head->data == GINT_TO_POINTER (1)); + check_integrity (q); + g_queue_push_tail (q, GINT_TO_POINTER (3)); + g_assert_cmpint (g_list_length (q->head), ==, 3); + g_assert (q->head->data == GINT_TO_POINTER (1)); + g_assert (q->head->next->data == GINT_TO_POINTER (2)); + g_assert (q->head->next->next == q->tail); + g_assert (q->head->next == q->tail->prev); + g_assert (q->tail->data == GINT_TO_POINTER (3)); + g_queue_push_tail (q, GINT_TO_POINTER (4)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 4); + g_assert (q->head->data == GINT_TO_POINTER (1)); + g_assert (g_queue_peek_tail (q) == GINT_TO_POINTER (4)); + g_queue_push_tail (q, GINT_TO_POINTER (5)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 5); + g_assert (g_queue_is_empty (q) == FALSE); + check_integrity (q); + g_assert_cmpint (q->length, ==, 5); + g_assert (q->head->prev == NULL); + g_assert (q->head->data == GINT_TO_POINTER (1)); + g_assert (q->head->next->data == GINT_TO_POINTER (2)); + g_assert (q->head->next->next->data == GINT_TO_POINTER (3)); + g_assert (q->head->next->next->next->data == GINT_TO_POINTER (4)); + g_assert (q->head->next->next->next->next->data == GINT_TO_POINTER (5)); + g_assert (q->head->next->next->next->next->next == NULL); + g_assert (q->head->next->next->next->next == q->tail); + g_assert (q->tail->data == GINT_TO_POINTER (5)); + g_assert (q->tail->prev->data == GINT_TO_POINTER (4)); + g_assert (q->tail->prev->prev->data == GINT_TO_POINTER (3)); + g_assert (q->tail->prev->prev->prev->data == GINT_TO_POINTER (2)); + g_assert (q->tail->prev->prev->prev->prev->data == GINT_TO_POINTER (1)); + g_assert (q->tail->prev->prev->prev->prev->prev == NULL); + g_assert (q->tail->prev->prev->prev->prev == q->head); + g_assert (g_queue_peek_tail (q) == GINT_TO_POINTER (5)); + g_assert (g_queue_peek_head (q) == GINT_TO_POINTER (1)); + g_assert (g_queue_pop_head (q) == GINT_TO_POINTER (1)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 4); + g_assert_cmpint (q->length, ==, 4); + g_assert (g_queue_pop_tail (q) == GINT_TO_POINTER (5)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 3); + + node = g_queue_pop_head_link (q); + g_assert (node->data == GINT_TO_POINTER (2)); + g_list_free_1 (node); + + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 2); + g_assert (g_queue_pop_tail (q) == GINT_TO_POINTER (4)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 1); + node = g_queue_pop_head_link (q); + g_assert (node->data == GINT_TO_POINTER (3)); + g_list_free_1 (node); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 0); + g_assert (g_queue_pop_tail (q) == NULL); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 0); + g_assert (g_queue_pop_head (q) == NULL); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 0); + g_assert (g_queue_is_empty (q)); + check_integrity (q); + + g_queue_push_head (q, GINT_TO_POINTER (1)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 1); + g_assert_cmpint (q->length, ==, 1); + g_queue_push_head (q, GINT_TO_POINTER (2)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 2); + g_assert_cmpint (q->length, ==, 2); + g_queue_push_head (q, GINT_TO_POINTER (3)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 3); + g_assert_cmpint (q->length, ==, 3); + g_queue_push_head (q, GINT_TO_POINTER (4)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 4); + g_assert_cmpint (q->length, ==, 4); + g_queue_push_head (q, GINT_TO_POINTER (5)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 5); + g_assert_cmpint (q->length, ==, 5); + g_assert (g_queue_pop_head (q) == GINT_TO_POINTER (5)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 4); + node = q->tail; + g_assert (node == g_queue_pop_tail_link (q)); + check_integrity (q); + g_list_free_1 (node); + g_assert_cmpint (g_list_length (q->head), ==, 3); + data = q->head->data; + g_assert (data == g_queue_pop_head (q)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 2); + g_assert (g_queue_pop_tail (q) == GINT_TO_POINTER (2)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 1); + g_assert (q->head == q->tail); + g_assert (g_queue_pop_tail (q) == GINT_TO_POINTER (3)); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 0); + g_assert (g_queue_pop_head (q) == NULL); + check_integrity (q); + g_assert (g_queue_pop_head_link (q) == NULL); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 0); + g_assert (g_queue_pop_tail_link (q) == NULL); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 0); + + g_queue_reverse (q); + check_integrity (q); + g_assert_cmpint (g_list_length (q->head), ==, 0); + g_queue_free (q); +} + +static void +test_copy (void) +{ + GQueue *q, *q2; + gint i; + + q = g_queue_new (); + q2 = g_queue_copy (q); + check_integrity (q); + check_integrity (q2); + g_assert_cmpint (g_list_length (q->head), ==, 0); + g_assert_cmpint (g_list_length (q2->head), ==, 0); + g_queue_sort (q, compare_int, NULL); + check_integrity (q2); + check_integrity (q); + g_queue_sort (q2, compare_int, NULL); + check_integrity (q2); + check_integrity (q); + + for (i = 0; i < 200; ++i) + { + g_queue_push_nth (q, GINT_TO_POINTER (i), i); + g_assert (g_queue_find (q, GINT_TO_POINTER (i))); + check_integrity (q); + check_integrity (q2); + } + + for (i = 0; i < 200; ++i) + { + g_queue_remove (q, GINT_TO_POINTER (i)); + check_integrity (q); + check_integrity (q2); + } + + for (i = 0; i < 200; ++i) + { + GList *l = g_list_prepend (NULL, GINT_TO_POINTER (i)); + + g_queue_push_nth_link (q, i, l); + check_integrity (q); + check_integrity (q2); + g_queue_reverse (q); + check_integrity (q); + check_integrity (q2); + } + + g_queue_free (q2); + q2 = g_queue_copy (q); + + g_queue_foreach (q2, remove_item, q2); + check_integrity (q2); + check_integrity (q); + + g_queue_free (q); + g_queue_free (q2); +} + +static void +test_off_by_one (void) +{ + GQueue *q; + GList *node; + + q = g_queue_new (); + + g_queue_push_tail (q, GINT_TO_POINTER (1234)); + check_integrity (q); + node = g_queue_peek_tail_link (q); + g_assert (node != NULL && node->data == GINT_TO_POINTER (1234)); + node = g_queue_peek_nth_link (q, g_queue_get_length (q)); + g_assert (node == NULL); + node = g_queue_peek_nth_link (q, g_queue_get_length (q) - 1); + g_assert (node->data == GINT_TO_POINTER (1234)); + node = g_queue_pop_nth_link (q, g_queue_get_length (q)); + g_assert (node == NULL); + node = g_queue_pop_nth_link (q, g_queue_get_length (q) - 1); + g_assert (node != NULL && node->data == GINT_TO_POINTER (1234)); + g_list_free_1 (node); + + g_queue_free (q); +} + +static gint +find_custom (gconstpointer a, gconstpointer b) +{ + return GPOINTER_TO_INT (a) - GPOINTER_TO_INT (b); +} + +static void +test_find_custom (void) +{ + GQueue *q; + GList *node; + q = g_queue_new (); + + g_queue_push_tail (q, GINT_TO_POINTER (1234)); + g_queue_push_tail (q, GINT_TO_POINTER (1)); + g_queue_push_tail (q, GINT_TO_POINTER (2)); + node = g_queue_find_custom (q, GINT_TO_POINTER (1), find_custom); + g_assert (node != NULL); + node = g_queue_find_custom (q, GINT_TO_POINTER (2), find_custom); + g_assert (node != NULL); + node = g_queue_find_custom (q, GINT_TO_POINTER (3), find_custom); + g_assert (node == NULL); + + g_queue_free (q); +} + +static void +test_static (void) +{ + GQueue q; + GQueue q2 = G_QUEUE_INIT; + + g_queue_init (&q); + + check_integrity (&q); + g_assert (g_queue_is_empty (&q)); + + check_integrity (&q2); + g_assert (g_queue_is_empty (&q2)); +} + +static void +test_clear (void) +{ + GQueue *q; + q = g_queue_new (); + + g_queue_push_tail (q, GINT_TO_POINTER (1234)); + g_queue_push_tail (q, GINT_TO_POINTER (1)); + g_queue_push_tail (q, GINT_TO_POINTER (2)); + g_assert_cmpint (g_queue_get_length (q), ==, 3); + + g_queue_clear (q); + check_integrity (q); + g_assert (g_queue_is_empty (q)); + + g_queue_free (q); +} + +typedef struct +{ + gboolean freed; + int x; +} QueueItem; + +static void +free_func (gpointer data) +{ + QueueItem *item = data; + + item->freed = TRUE; +} + +static QueueItem * +new_item (int x) +{ + QueueItem *item; + + item = g_slice_new (QueueItem); + item->freed = FALSE; + item->x = x; + + return item; +} + +static void +test_clear_full (void) +{ + QueueItem *one, *two, *three, *four; + GQueue *queue; + + queue = g_queue_new (); + g_queue_push_tail (queue, one = new_item (1)); + g_queue_push_tail (queue, two = new_item (2)); + g_queue_push_tail (queue, three = new_item (3)); + g_queue_push_tail (queue, four = new_item (4)); + + g_assert_cmpint (g_queue_get_length (queue), ==, 4); + g_assert_false (one->freed); + g_assert_false (two->freed); + g_assert_false (three->freed); + g_assert_false (four->freed); + + g_queue_clear_full (queue, free_func); + + g_assert_true (one->freed); + g_assert_true (two->freed); + g_assert_true (three->freed); + g_assert_true (four->freed); + + g_assert_true (g_queue_is_empty (queue)); + check_integrity (queue); + + g_slice_free (QueueItem, one); + g_slice_free (QueueItem, two); + g_slice_free (QueueItem, three); + g_slice_free (QueueItem, four); + g_queue_free (queue); +} + +/* Check that g_queue_clear_full() called with a NULL free_func is equivalent + * to g_queue_clear(). */ +static void +test_clear_full_noop (void) +{ + QueueItem *one, *two, *three, *four; + GQueue *queue; + + queue = g_queue_new (); + g_queue_push_tail (queue, one = new_item (1)); + g_queue_push_tail (queue, two = new_item (2)); + g_queue_push_tail (queue, three = new_item (3)); + g_queue_push_tail (queue, four = new_item (4)); + + g_assert_cmpint (g_queue_get_length (queue), ==, 4); + g_assert_false (one->freed); + g_assert_false (two->freed); + g_assert_false (three->freed); + g_assert_false (four->freed); + + g_queue_clear_full (queue, NULL); + + g_assert_true (g_queue_is_empty (queue)); + check_integrity (queue); + + g_slice_free (QueueItem, one); + g_slice_free (QueueItem, two); + g_slice_free (QueueItem, three); + g_slice_free (QueueItem, four); + g_queue_free (queue); +} + +/* Test g_queue_push_nth_link() with various combinations of position (before, + * in the middle of, or at the end of the queue) and various existing queues + * (empty, single element, multiple elements). */ +static void +test_push_nth_link (void) +{ + GQueue *q; + q = g_queue_new (); + + /* Push onto before the front of an empty queue (which results in it being + * added to the end of the queue). */ + g_queue_push_nth_link (q, -1, g_list_prepend (NULL, GINT_TO_POINTER (1))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 1); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 1); + + g_queue_clear (q); + + /* Push onto after the rear of an empty queue. */ + g_queue_push_nth_link (q, 100, g_list_prepend (NULL, GINT_TO_POINTER (2))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 1); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 2); + + g_queue_clear (q); + + /* Push onto the front of an empty queue. */ + g_queue_push_nth_link (q, 0, g_list_prepend (NULL, GINT_TO_POINTER (3))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 1); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 3); + + g_queue_clear (q); + + /* Push onto before the front of a non-empty queue (which results in it being + * added to the end of the queue). */ + g_queue_push_head (q, GINT_TO_POINTER (4)); + g_queue_push_nth_link (q, -1, g_list_prepend (NULL, GINT_TO_POINTER (5))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 2); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 4); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 5); + + g_queue_clear (q); + + /* Push onto after the rear of a non-empty queue. */ + g_queue_push_head (q, GINT_TO_POINTER (6)); + g_queue_push_nth_link (q, 100, g_list_prepend (NULL, GINT_TO_POINTER (7))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 2); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 6); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 7); + + g_queue_clear (q); + + /* Push onto the rear of a non-empty queue. */ + g_queue_push_head (q, GINT_TO_POINTER (8)); + g_queue_push_nth_link (q, 1, g_list_prepend (NULL, GINT_TO_POINTER (9))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 2); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 8); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 9); + + g_queue_clear (q); + + /* Push onto the front of a non-empty queue. */ + g_queue_push_head (q, GINT_TO_POINTER (10)); + g_queue_push_nth_link (q, 0, g_list_prepend (NULL, GINT_TO_POINTER (11))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 2); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 11); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 10); + + g_queue_clear (q); + + /* Push into the middle of a non-empty queue. */ + g_queue_push_head (q, GINT_TO_POINTER (12)); + g_queue_push_head (q, GINT_TO_POINTER (13)); + g_queue_push_nth_link (q, 1, g_list_prepend (NULL, GINT_TO_POINTER (14))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 3); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 13); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 14); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 2)), ==, 12); + + g_queue_free (q); +} + +static void +test_free_full (void) +{ + QueueItem *one, *two, *three; + GQueue *queue = NULL; + + queue = g_queue_new(); + g_queue_push_tail (queue, one = new_item (1)); + g_queue_push_tail (queue, two = new_item (2)); + g_queue_push_tail (queue, three = new_item (3)); + g_assert (!one->freed); + g_assert (!two->freed); + g_assert (!three->freed); + g_queue_free_full (queue, free_func); + g_assert (one->freed); + g_assert (two->freed); + g_assert (three->freed); + g_slice_free (QueueItem, one); + g_slice_free (QueueItem, two); + g_slice_free (QueueItem, three); +} + +static void +test_insert_sibling_link (void) +{ + GQueue q = G_QUEUE_INIT; + GList a = {0}; + GList b = {0}; + GList c = {0}; + GList d = {0}; + GList e = {0}; + + g_queue_push_head_link (&q, &a); + g_queue_insert_after_link (&q, &a, &d); + g_queue_insert_before_link (&q, &d, &b); + g_queue_insert_after_link (&q, &b, &c); + g_queue_insert_after_link (&q, NULL, &e); + + g_assert_true (q.head == &e); + g_assert_true (q.tail == &d); + + g_assert_null (e.prev); + g_assert_true (e.next == &a); + + g_assert_true (a.prev == &e); + g_assert_true (a.next == &b); + + g_assert_true (b.prev == &a); + g_assert_true (b.next == &c); + + g_assert_true (c.prev == &b); + g_assert_true (c.next == &d); + + g_assert_true (d.prev == &c); + g_assert_null (d.next); +} + +int main (int argc, char *argv[]) +{ + guint32 seed; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/queue/basic", test_basic); + g_test_add_func ("/queue/copy", test_copy); + g_test_add_func ("/queue/off-by-one", test_off_by_one); + g_test_add_func ("/queue/find-custom", test_find_custom); + g_test_add_func ("/queue/static", test_static); + g_test_add_func ("/queue/clear", test_clear); + g_test_add_func ("/queue/free-full", test_free_full); + g_test_add_func ("/queue/clear-full", test_clear_full); + g_test_add_func ("/queue/clear-full/noop", test_clear_full_noop); + g_test_add_func ("/queue/insert-sibling-link", test_insert_sibling_link); + g_test_add_func ("/queue/push-nth-link", test_push_nth_link); + + seed = g_test_rand_int_range (0, G_MAXINT); + path = g_strdup_printf ("/queue/random/seed:%u", seed); + g_test_add_data_func (path, GUINT_TO_POINTER (seed), random_test); + g_free (path); + + return g_test_run (); +} diff --git a/glib/tests/rand.c b/glib/tests/rand.c new file mode 100644 index 0000000..37f4ddd --- /dev/null +++ b/glib/tests/rand.c @@ -0,0 +1,181 @@ +/* Unit tests for grand + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "glib.h" + +/* Outputs tested against the reference implementation mt19937ar.c from + * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html + */ + +/* Tests for a simple seed, first number is the seed */ +const guint32 first_numbers[] = +{ + 0x7a7a7a7a, + 0xfdcc2d54, + 0x3a279ceb, + 0xc4d39c33, + 0xf31895cd, + 0x46ca0afc, + 0x3f5484ff, + 0x54bc9557, + 0xed2c24b1, + 0x84062503, + 0x8f6404b3, + 0x599a94b3, + 0xe46d03d5, + 0x310beb78, + 0x7bee5d08, + 0x760d09be, + 0x59b6e163, + 0xbf6d16ec, + 0xcca5fb54, + 0x5de7259b, + 0x1696330c, +}; + +/* array seed */ +const guint32 seed_array[] = +{ + 0x6553375f, + 0xd6b8d43b, + 0xa1e7667f, + 0x2b10117c +}; + +/* tests for the array seed */ +const guint32 array_outputs[] = +{ + 0xc22b7dc3, + 0xfdecb8ae, + 0xb4af0738, + 0x516bc6e1, + 0x7e372e91, + 0x2d38ff80, + 0x6096494a, + 0xd162d5a8, + 0x3c0aaa0d, + 0x10e736ae +}; + +static void +test_rand (void) +{ + guint n; + guint ones; + double proportion; + GRand *rand; + GRand *copy; + + rand = g_rand_new_with_seed (first_numbers[0]); + + for (n = 1; n < G_N_ELEMENTS (first_numbers); n++) + g_assert_cmpuint (first_numbers[n], ==, g_rand_int (rand)); + + g_rand_set_seed (rand, 2); + g_rand_set_seed_array (rand, seed_array, G_N_ELEMENTS (seed_array)); + + for (n = 0; n < G_N_ELEMENTS (array_outputs); n++) + g_assert_cmpuint (array_outputs[n], ==, g_rand_int (rand)); + + copy = g_rand_copy (rand); + for (n = 0; n < 100; n++) + g_assert_cmpuint (g_rand_int (copy), ==, g_rand_int (rand)); + + for (n = 1; n < 100000; n++) + { + gint32 i; + gdouble d; + gboolean b; + + i = g_rand_int_range (rand, 8,16); + g_assert_cmpint (i, >=, 8); + g_assert_cmpint (i, <, 16); + + i = g_random_int_range (8,16); + g_assert_cmpint (i, >=, 8); + g_assert_cmpint (i, <, 16); + + d = g_rand_double (rand); + g_assert_cmpfloat (d, >=, 0.0); + g_assert_cmpfloat (d, <, 1.0); + + d = g_random_double (); + g_assert_cmpfloat (d, >=, 0.0); + g_assert_cmpfloat (d, <, 1.0); + + d = g_rand_double_range (rand, -8, 32); + g_assert_cmpfloat (d, >=, -8.0); + g_assert_cmpfloat (d, <, 32.0); + + d = g_random_double_range (-8, 32); + g_assert_cmpfloat (d, >=, -8.0); + g_assert_cmpfloat (d, <, 32.0); + + b = g_random_boolean (); + g_assert_true (b == TRUE || b == FALSE); + + b = g_rand_boolean (rand); + g_assert_true (b == TRUE || b == FALSE); + } + + /* Statistical sanity check, count the number of ones + * when getting random numbers in range [0,3) and see + * that it must be semi-close to 0.25 with a VERY large + * probability */ + ones = 0; + for (n = 1; n < 100000; n++) + { + if (g_random_int_range (0, 4) == 1) + ones ++; + } + + proportion = (double)ones / (double)100000; + /* 0.025 is overkill, but should suffice to test for some unreasonability */ + g_assert_cmpfloat (ABS (proportion - 0.25), <, 0.025); + + g_rand_free (rand); + g_rand_free (copy); +} + +static void +test_double_range (void) +{ + gdouble d; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=502560"); + + d = g_random_double_range (-G_MAXDOUBLE, G_MAXDOUBLE); + + g_assert_cmpfloat (-G_MAXDOUBLE, <=, d); + g_assert_cmpfloat (d, <, G_MAXDOUBLE); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/rand/test-rand", test_rand); + g_test_add_func ("/rand/double-range", test_double_range); + + return g_test_run(); +} diff --git a/glib/tests/rcbox.c b/glib/tests/rcbox.c new file mode 100644 index 0000000..fe10075 --- /dev/null +++ b/glib/tests/rcbox.c @@ -0,0 +1,298 @@ +/* rcbox.c: Reference counted data + * + * Copyright 2018 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include + +typedef struct { + float x, y; +} Point; + +static Point *global_point; + +/* test_rcbox_new: Test g_rc_box_new() */ +static void +test_rcbox_new (void) +{ + Point *a = g_rc_box_new (Point); + + g_assert_nonnull (a); + g_assert_cmpuint (g_rc_box_get_size (a), ==, sizeof (Point)); + + g_rc_box_release (a); + + a = g_rc_box_new0 (Point); + g_assert_nonnull (a); + g_assert_cmpfloat (a->x, ==, 0.f); + g_assert_cmpfloat (a->y, ==, 0.f); + + g_rc_box_release (a); +} + +/* test_atomic_rcbox_new: Test g_atomic_rc_box_new() */ +static void +test_atomic_rcbox_new (void) +{ + Point *a = g_atomic_rc_box_new (Point); + + g_assert_nonnull (a); + g_assert_cmpuint (g_atomic_rc_box_get_size (a), ==, sizeof (Point)); + + g_atomic_rc_box_release (a); + + a = g_atomic_rc_box_new0 (Point); + g_assert_nonnull (a); + g_assert_cmpfloat (a->x, ==, 0.f); + g_assert_cmpfloat (a->y, ==, 0.f); + + g_atomic_rc_box_release (a); +} + +static void +point_clear (Point *p) +{ + g_assert_nonnull (p); + g_assert_true (global_point == p); + + g_assert_cmpfloat (p->x, ==, 42.0f); + g_assert_cmpfloat (p->y, ==, 47.0f); + + g_test_message ("global_point = %p", p); + global_point = NULL; +} + +/* test_rcbox_release_full: Verify that g_rc_box_release_full() calls + * the clear function only when the last reference is released + */ +static void +test_rcbox_release_full (void) +{ + Point *p = g_rc_box_new (Point); + + g_assert_nonnull (p); + global_point = p; + + p->x = 42.0f; + p->y = 47.0f; + + g_assert_true (g_rc_box_acquire (p) == p); + + g_rc_box_release_full (p, (GDestroyNotify) point_clear); + g_assert_nonnull (global_point); + g_assert_true (p == global_point); + + g_rc_box_release_full (p, (GDestroyNotify) point_clear); + g_assert_null (global_point); +} + +/* test_atomic_rcbox_release_full: Verify that g_atomic_rc_box_release_full() + * calls the clear function only when the last reference is released + */ +static void +test_atomic_rcbox_release_full (void) +{ + Point *p = g_atomic_rc_box_new (Point); + + g_assert_nonnull (p); + global_point = p; + + p->x = 42.0f; + p->y = 47.0f; + + g_assert_true (g_atomic_rc_box_acquire (p) == p); + + g_atomic_rc_box_release_full (p, (GDestroyNotify) point_clear); + g_assert_nonnull (global_point); + g_assert_true (p == global_point); + + g_atomic_rc_box_release_full (p, (GDestroyNotify) point_clear); + g_assert_null (global_point); +} + +static Point *global_point_a; +static Point *global_point_b; + +static void +point_clear_dup_a (Point *a) +{ + g_assert_true (a == global_point_a); + + g_test_message ("global_point_a = %p", a); + global_point_a = NULL; +} + +static void +point_clear_dup_b (Point *b) +{ + g_assert_true (b == global_point_b); + + g_test_message ("global_point_b = %p", b); + global_point_b = NULL; +} + +/* test_rcbox_dup: Verify that g_rc_box_dup() copies only the + * data and does not change the reference count of the original + */ +static void +test_rcbox_dup (void) +{ + Point *a, *b; + + a = g_rc_box_new (Point); + a->x = 10.f; + a->y = 5.f; + + b = g_rc_box_dup (sizeof (Point), a); + g_assert_true (a != b); + g_assert_cmpfloat (a->x, ==, b->x); + g_assert_cmpfloat (a->y, ==, b->y); + + global_point_a = a; + global_point_b = b; + + a->x = 1.f; + a->y = 1.f; + g_assert_cmpfloat (a->x, !=, b->x); + g_assert_cmpfloat (a->y, !=, b->y); + + b->x = 5.f; + b->y = 10.f; + g_assert_cmpfloat (a->x, !=, b->x); + g_assert_cmpfloat (a->y, !=, b->y); + + g_rc_box_release_full (a, (GDestroyNotify) point_clear_dup_a); + g_assert_null (global_point_a); + g_assert_nonnull (global_point_b); + + g_rc_box_release_full (b, (GDestroyNotify) point_clear_dup_b); + g_assert_null (global_point_b); +} + +/* test_atomic_rcbox_dup: Verify that g_atomic_rc_box_dup() copies + * only the data and does not change the reference count of the original + */ +static void +test_atomic_rcbox_dup (void) +{ + Point *a, *b; + + a = g_atomic_rc_box_new (Point); + a->x = 10.f; + a->y = 5.f; + + b = g_atomic_rc_box_dup (sizeof (Point), a); + g_assert_true (a != b); + g_assert_cmpfloat (a->x, ==, b->x); + g_assert_cmpfloat (a->y, ==, b->y); + + global_point_a = a; + global_point_b = b; + + a->x = 1.f; + a->y = 1.f; + g_assert_cmpfloat (a->x, !=, b->x); + g_assert_cmpfloat (a->y, !=, b->y); + + b->x = 5.f; + b->y = 10.f; + g_assert_cmpfloat (a->x, !=, b->x); + g_assert_cmpfloat (a->y, !=, b->y); + + g_atomic_rc_box_release_full (a, (GDestroyNotify) point_clear_dup_a); + g_assert_null (global_point_a); + g_assert_nonnull (global_point_b); + + g_atomic_rc_box_release_full (b, (GDestroyNotify) point_clear_dup_b); + g_assert_null (global_point_b); +} + +/* The expected alignment of the refcounted data, absent any other + * alignment requirement, is `2 * sizeof(void*)`; GLib only really + * supports void* sized 8 or 4 (see the comment in gatomic.h) + */ +#if GLIB_SIZEOF_VOID_P == 8 +static const gsize rcbox_alignment = 16; +#else +static const gsize rcbox_alignment = 8; +#endif + +/* verify that the refcounted allocation is properly aligned */ +static void +test_rcbox_alignment (void) +{ + const gsize block_sizes[] = { + 1, + 2, + 4, + sizeof (gint32) * 3, + }; + + gsize i; + + for (i = 0; i < G_N_ELEMENTS (block_sizes); i++) + { + gpointer p = g_rc_box_alloc0 (block_sizes[i]); + + g_assert_nonnull (p); + g_assert_true (((guintptr) p & (rcbox_alignment - 1)) == 0); + + g_rc_box_release (p); + } +} + +/* verify that the atomically refcounted allocation is properly aligned */ +static void +test_atomic_rcbox_alignment (void) +{ + const gsize block_sizes[] = { + 1, + 2, + 4, + sizeof (gint32) * 3, + }; + + gsize i; + + for (i = 0; i < G_N_ELEMENTS (block_sizes); i++) + { + gpointer p = g_atomic_rc_box_alloc0 (block_sizes[i]); + + g_assert_nonnull (p); + g_assert_true (((guintptr) p & (rcbox_alignment - 1)) == 0); + + g_atomic_rc_box_release (p); + } +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/rcbox/new", test_rcbox_new); + g_test_add_func ("/rcbox/release-full", test_rcbox_release_full); + g_test_add_func ("/rcbox/dup", test_rcbox_dup); + g_test_add_func ("/rcbox/alignment", test_rcbox_alignment); + + g_test_add_func ("/atomic-rcbox/new", test_atomic_rcbox_new); + g_test_add_func ("/atomic-rcbox/release-full", test_atomic_rcbox_release_full); + g_test_add_func ("/atomic-rcbox/dup", test_atomic_rcbox_dup); + g_test_add_func ("/atomic-rcbox/alignment", test_atomic_rcbox_alignment); + + return g_test_run (); +} diff --git a/glib/tests/rec-mutex.c b/glib/tests/rec-mutex.c new file mode 100644 index 0000000..f5be715 --- /dev/null +++ b/glib/tests/rec-mutex.c @@ -0,0 +1,257 @@ +/* Unit tests for GRecMutex + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +#include + +static void +test_rec_mutex1 (void) +{ + GRecMutex mutex; + + g_rec_mutex_init (&mutex); + g_rec_mutex_lock (&mutex); + g_rec_mutex_unlock (&mutex); + g_rec_mutex_lock (&mutex); + g_rec_mutex_unlock (&mutex); + g_rec_mutex_clear (&mutex); +} + +static void +test_rec_mutex2 (void) +{ + static GRecMutex mutex; + + g_rec_mutex_lock (&mutex); + g_rec_mutex_unlock (&mutex); + g_rec_mutex_lock (&mutex); + g_rec_mutex_unlock (&mutex); +} + +static void +test_rec_mutex3 (void) +{ + static GRecMutex mutex; + gboolean ret; + + ret = g_rec_mutex_trylock (&mutex); + g_assert (ret); + + ret = g_rec_mutex_trylock (&mutex); + g_assert (ret); + + g_rec_mutex_unlock (&mutex); + g_rec_mutex_unlock (&mutex); +} + +#define LOCKS 48 +#define ITERATIONS 10000 +#define THREADS 100 + + +GThread *owners[LOCKS]; +GRecMutex locks[LOCKS]; + +static void +acquire (gint nr) +{ + GThread *self; + + self = g_thread_self (); + + if (!g_rec_mutex_trylock (&locks[nr])) + { + if (g_test_verbose ()) + g_printerr ("thread %p going to block on lock %d\n", self, nr); + + g_rec_mutex_lock (&locks[nr]); + } + + g_assert (owners[nr] == NULL); /* hopefully nobody else is here */ + owners[nr] = self; + + /* let some other threads try to ruin our day */ + g_thread_yield (); + g_thread_yield (); + + g_assert (owners[nr] == self); /* hopefully this is still us... */ + + if (g_test_verbose ()) + g_printerr ("thread %p recursively taking lock %d\n", self, nr); + + g_rec_mutex_lock (&locks[nr]); /* we're recursive, after all */ + + g_assert (owners[nr] == self); /* hopefully this is still us... */ + + g_rec_mutex_unlock (&locks[nr]); + + g_thread_yield (); + g_thread_yield (); + + g_assert (owners[nr] == self); /* hopefully this is still us... */ + owners[nr] = NULL; /* make way for the next guy */ + + g_rec_mutex_unlock (&locks[nr]); +} + +static gpointer +thread_func (gpointer data) +{ + gint i; + GRand *rand; + + rand = g_rand_new (); + + for (i = 0; i < ITERATIONS; i++) + acquire (g_rand_int_range (rand, 0, LOCKS)); + + g_rand_free (rand); + + return NULL; +} + +static void +test_rec_mutex4 (void) +{ + gint i; + GThread *threads[THREADS]; + + for (i = 0; i < LOCKS; i++) + g_rec_mutex_init (&locks[i]); + + for (i = 0; i < THREADS; i++) + threads[i] = g_thread_new ("test", thread_func, NULL); + + for (i = 0; i < THREADS; i++) + g_thread_join (threads[i]); + + for (i = 0; i < LOCKS; i++) + g_rec_mutex_clear (&locks[i]); + + for (i = 0; i < LOCKS; i++) + g_assert (owners[i] == NULL); +} + +#define COUNT_TO 100000000 + +static gint depth; + +static gboolean +do_addition (gint *value) +{ + static GRecMutex lock; + gboolean more; + gint i; + + /* test performance of "good" cases (ie: short critical sections) */ + for (i = 0; i < depth; i++) + g_rec_mutex_lock (&lock); + + if ((more = *value != COUNT_TO)) + if (*value != -1) + (*value)++; + + for (i = 0; i < depth; i++) + g_rec_mutex_unlock (&lock); + + return more; +} + +static gpointer +addition_thread (gpointer value) +{ + while (do_addition (value)); + + return NULL; +} + +static void +test_mutex_perf (gconstpointer data) +{ + gint c = GPOINTER_TO_INT (data); + GThread *threads[THREADS]; + gint64 start_time; + gint n_threads; + gdouble rate; + gint x = -1; + gint i; + + n_threads = c / 256; + depth = c % 256; + + for (i = 0; i < n_threads - 1; i++) + threads[i] = g_thread_new ("test", addition_thread, &x); + + /* avoid measuring thread setup/teardown time */ + start_time = g_get_monotonic_time (); + g_atomic_int_set (&x, 0); + addition_thread (&x); + g_assert_cmpint (g_atomic_int_get (&x), ==, COUNT_TO); + rate = g_get_monotonic_time () - start_time; + rate = x / rate; + + for (i = 0; i < n_threads - 1; i++) + g_thread_join (threads[i]); + + g_test_maximized_result (rate, "%f mips", rate); +} + + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/thread/rec-mutex1", test_rec_mutex1); + g_test_add_func ("/thread/rec-mutex2", test_rec_mutex2); + g_test_add_func ("/thread/rec-mutex3", test_rec_mutex3); + g_test_add_func ("/thread/rec-mutex4", test_rec_mutex4); + + if (g_test_perf ()) + { + gint i, j; + + for (i = 0; i < 5; i++) + for (j = 1; j <= 5; j++) + { + gchar name[80]; + guint c; + + c = i * 256 + j; + + if (i) + sprintf (name, "/thread/rec-mutex/perf/contended%d/depth%d", i, j); + else + sprintf (name, "/thread/rec-mutex/perf/uncontended/depth%d", j); + + g_test_add_data_func (name, GINT_TO_POINTER (c), test_mutex_perf); + } + } + + return g_test_run (); +} diff --git a/glib/tests/refcount.c b/glib/tests/refcount.c new file mode 100644 index 0000000..e19a2d7 --- /dev/null +++ b/glib/tests/refcount.c @@ -0,0 +1,222 @@ +/* refcount.c: Tests for reference counting types + * + * Copyright 2018 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include + +/* test_grefcount: test the behavior of the grefcount API */ +static void +test_grefcount (void) +{ + grefcount a, b; + + /* init(a): 1 */ + g_ref_count_init (&a); + if (g_test_verbose ()) + g_test_message ("init(a) := %d\n", (int) a); + g_assert_true (g_ref_count_compare (&a, 1)); + + /* inc(a): 2 */ + g_ref_count_inc (&a); + if (g_test_verbose ()) + g_test_message ("inc(a) := %d\n", (int) a); + g_assert_false (g_ref_count_compare (&a, 1)); + g_assert_false (g_ref_count_compare (&a, G_MAXINT)); + + /* b = a = 2 */ + b = a; + if (g_test_verbose ()) + g_test_message ("a := %d, b := %d\n", (int) a, (int) b); + + /* inc(a): 3 */ + g_ref_count_inc (&a); + if (g_test_verbose ()) + g_test_message ("inc(a) := %d\n", (int) a); + + /* dec(b) = 1 */ + if (g_test_verbose ()) + g_test_message ("dec(b) := %d + 1\n", (int) b); + g_assert_false (g_ref_count_dec (&b)); + + /* dec(a) = 2 */ + if (g_test_verbose ()) + g_test_message ("dec(a) := %d + 1\n", (int) a); + g_assert_false (g_ref_count_dec (&a)); + + /* dec(b) = 0 */ + if (g_test_verbose ()) + g_test_message ("dec(b) := %d + 1\n", (int) b); + g_assert_true (g_ref_count_dec (&b)); + + /* dec(a) = 1 */ + if (g_test_verbose ()) + g_test_message ("dec(a) := %d + 1\n", (int) a); + g_assert_false (g_ref_count_dec (&a)); + + /* dec(a) = 0 */ + if (g_test_verbose ()) + g_test_message ("dec(a) := %d + 1\n", (int) a); + g_assert_true (g_ref_count_dec (&a)); +} + +/* test_grefcount_saturation: Saturating a grefcount counter + * does not cause an overflow; additionally, if we're building + * with checks enabled or with non-GCC compilers, it'll cause a + * warning + */ +static void +test_grefcount_saturation (void) +{ + if (g_test_subprocess ()) + { + grefcount a; + + /* We're breaking abstraction here for convenience */ + a = G_MININT + 1; + + g_ref_count_inc (&a); + g_assert_true (a == G_MININT); + + g_ref_count_inc (&a); + g_assert_true (a == G_MININT); + + exit (0); + } + + g_test_trap_subprocess (NULL, 0, 0); + +#if defined (G_DISABLE_CHECKS) && defined (__GNUC__) + /* With checks disabled we don't get any warning */ + g_test_trap_assert_passed (); +#else + /* Ensure that we got a warning when building with checks or with + * non-GCC compilers; the test will fail because of the critical + * warning being caught by GTest + */ + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*saturation*"); +#endif +} + +/* test_gatomicrefcount: test the behavior of the gatomicrefcount API */ +static void +test_gatomicrefcount (void) +{ + gatomicrefcount a, b; + + /* init(a): 1 */ + g_atomic_ref_count_init (&a); + if (g_test_verbose ()) + g_test_message ("init(a) := %d\n", (int) a); + g_assert_true (g_atomic_ref_count_compare (&a, 1)); + + /* inc(a): 2 */ + g_atomic_ref_count_inc (&a); + if (g_test_verbose ()) + g_test_message ("inc(a) := %d\n", (int) a); + g_assert_false (g_atomic_ref_count_compare (&a, 1)); + g_assert_false (g_atomic_ref_count_compare (&a, G_MAXINT)); + + /* b = a = 2 */ + b = a; + if (g_test_verbose ()) + g_test_message ("a := %d, b := %d\n", (int) a, (int) b); + + /* inc(a): 3 */ + g_atomic_ref_count_inc (&a); + if (g_test_verbose ()) + g_test_message ("inc(a) := %d\n", (int) a); + + /* dec(b) = 1 */ + if (g_test_verbose ()) + g_test_message ("dec(b) := %d + 1\n", (int) b); + g_assert_false (g_atomic_ref_count_dec (&b)); + + /* dec(a) = 2 */ + if (g_test_verbose ()) + g_test_message ("dec(a) := %d + 1\n", (int) a); + g_assert_false (g_atomic_ref_count_dec (&a)); + + /* dec(b) = 0 */ + if (g_test_verbose ()) + g_test_message ("dec(b) := %d + 1\n", (int) b); + g_assert_true (g_atomic_ref_count_dec (&b)); + + /* dec(a) = 1 */ + if (g_test_verbose ()) + g_test_message ("dec(a) := %d + 1\n", (int) a); + g_assert_false (g_atomic_ref_count_dec (&a)); + + /* dec(a) = 0 */ + if (g_test_verbose ()) + g_test_message ("dec(a) := %d + 1\n", (int) a); + g_assert_true (g_atomic_ref_count_dec (&a)); +} + +/* test_gatomicrefcount_saturation: Saturating a gatomicrefcount counter + * does not cause an overflow; additionally, if we're building with + * checks enabled or with non-GCC compilers, it'll cause a warning + */ +static void +test_gatomicrefcount_saturation (void) +{ + if (g_test_subprocess ()) + { + gatomicrefcount a; + + /* We're breaking abstraction here for convenience */ + a = G_MAXINT - 1; + + g_atomic_ref_count_inc (&a); + g_assert_true (a == G_MAXINT); + + g_atomic_ref_count_inc (&a); + g_assert_true (a == G_MAXINT); + + exit (0); + } + + g_test_trap_subprocess (NULL, 0, 0); + +#if defined (G_DISABLE_CHECKS) && defined (__GNUC__) + /* With checks disabled we don't get any warning */ + g_test_trap_assert_passed (); +#else + /* Ensure that we got a warning when building with checks or with + * non-GCC compilers; the test will fail because of the critical + * warning being caught by GTest + */ + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*saturation*"); +#endif +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/refcount/grefcount", test_grefcount); + g_test_add_func ("/refcount/grefcount/saturation", test_grefcount_saturation); + + g_test_add_func ("/refcount/gatomicrefcount", test_gatomicrefcount); + g_test_add_func ("/refcount/gatomicrefcount/saturation", test_gatomicrefcount_saturation); + + return g_test_run (); +} diff --git a/glib/tests/refstring.c b/glib/tests/refstring.c new file mode 100644 index 0000000..edfadb5 --- /dev/null +++ b/glib/tests/refstring.c @@ -0,0 +1,116 @@ +/* refstring.c: Reference counted strings + * + * Copyright 2018 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include + +/* test_refstring_base: Test the base API of GRefString */ +static void +test_refstring_base (void) +{ + char *s = g_ref_string_new ("hello, world"); + + g_test_message ("s = '%s' (%p)", s, s); + g_assert_cmpint (strcmp (s, "hello, world"), ==, 0); + g_assert_cmpint (strlen (s), ==, strlen ("hello, world")); + g_assert_cmpuint (g_ref_string_length (s), ==, strlen ("hello, world")); + + g_assert_true (g_ref_string_acquire (s) == s); + g_ref_string_release (s); + + g_ref_string_release (s); +} + +/* test_refstring_length: Test the _len variant */ +static void +test_refstring_length (void) +{ + char buf[] = {'h', 'e', 'l', 'l', 'o'}; /* no NUL */ + char *s = g_ref_string_new_len (buf, 5); + + g_assert_cmpstr (s, ==, "hello"); + g_assert_cmpint (strlen (s), ==, strlen ("hello")); + g_assert_cmpuint (g_ref_string_length (s), ==, strlen ("hello")); + g_ref_string_release (s); +} + +/* test_refstring_length: Test the _len variant with no size set */ +static void +test_refstring_length_auto (void) +{ + char *s = g_ref_string_new_len ("hello", -1); + g_assert_cmpstr (s, ==, "hello"); + g_assert_cmpuint (g_ref_string_length (s), ==, strlen ("hello")); + g_ref_string_release (s); +} + +/* test_refstring_length_nuls: Test the _len variant */ +static void +test_refstring_length_nuls (void) +{ + char buf[] = {'h', 'e', '\0', 'l', 'o'}; /* no NUL */ + char *s = g_ref_string_new_len (buf, 5); + + g_assert_cmpstr (s, ==, "he"); + g_assert_cmpint (memcmp (s, "he\0lo", 5), ==, 0); + g_assert_cmpuint (g_ref_string_length (s), ==, 5); + g_ref_string_release (s); +} + +/* test_refstring_intern: Test the interning API of GRefString */ +static void +test_refstring_intern (void) +{ + char *s = g_ref_string_new_intern ("hello, world"); + char *p; + + g_test_message ("s = '%s' (%p)", s, s); + g_assert_cmpstr (s, ==, "hello, world"); + + p = g_ref_string_new_intern ("hello, world"); + g_test_message ("p = s = '%s' (%p)", p, p); + g_assert_true (s == p); + + g_test_message ("releasing p[%p] ('%s')", p, p); + g_ref_string_release (p); + + p = g_ref_string_new_intern ("goodbye, world"); + g_test_message ("p = '%s' (%p)", p, p); + g_assert_false (s == p); + + g_test_message ("releasing p[%p] ('%s')", p, p); + g_ref_string_release (p); + + g_test_message ("releasing s[%p] ('%s')", s, s); + g_ref_string_release (s); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/refstring/base", test_refstring_base); + g_test_add_func ("/refstring/length", test_refstring_length); + g_test_add_func ("/refstring/length-auto", test_refstring_length_auto); + g_test_add_func ("/refstring/length-nuls", test_refstring_length_nuls); + g_test_add_func ("/refstring/intern", test_refstring_intern); + + return g_test_run (); +} diff --git a/glib/tests/regex.c b/glib/tests/regex.c new file mode 100644 index 0000000..88d12ed --- /dev/null +++ b/glib/tests/regex.c @@ -0,0 +1,2867 @@ +/* + * Copyright (C) 2005 - 2006, Marco Barisione + * Copyright (C) 2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include "config.h" + +#include +#include +#include "glib.h" + +#include + +/* U+20AC EURO SIGN (symbol, currency) */ +#define EURO "\xe2\x82\xac" +/* U+00E0 LATIN SMALL LETTER A WITH GRAVE (letter, lowercase) */ +#define AGRAVE "\xc3\xa0" +/* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE (letter, uppercase) */ +#define AGRAVE_UPPER "\xc3\x80" +/* U+00E8 LATIN SMALL LETTER E WITH GRAVE (letter, lowercase) */ +#define EGRAVE "\xc3\xa8" +/* U+00F2 LATIN SMALL LETTER O WITH GRAVE (letter, lowercase) */ +#define OGRAVE "\xc3\xb2" +/* U+014B LATIN SMALL LETTER ENG (letter, lowercase) */ +#define ENG "\xc5\x8b" +/* U+0127 LATIN SMALL LETTER H WITH STROKE (letter, lowercase) */ +#define HSTROKE "\xc4\xa7" +/* U+0634 ARABIC LETTER SHEEN (letter, other) */ +#define SHEEN "\xd8\xb4" +/* U+1374 ETHIOPIC NUMBER THIRTY (number, other) */ +#define ETH30 "\xe1\x8d\xb4" + +/* A random value use to mark untouched integer variables. */ +#define UNTOUCHED -559038737 + +static gint total; + +typedef struct { + const gchar *pattern; + GRegexCompileFlags compile_opts; + GRegexMatchFlags match_opts; + gint expected_error; + gboolean check_flags; + GRegexCompileFlags real_compile_opts; + GRegexMatchFlags real_match_opts; +} TestNewData; + +static void +test_new (gconstpointer d) +{ + const TestNewData *data = d; + GRegex *regex; + GError *error = NULL; + + regex = g_regex_new (data->pattern, data->compile_opts, data->match_opts, &error); + g_assert (regex != NULL); + g_assert_no_error (error); + g_assert_cmpstr (data->pattern, ==, g_regex_get_pattern (regex)); + + if (data->check_flags) + { + g_assert_cmphex (g_regex_get_compile_flags (regex), ==, data->real_compile_opts); + g_assert_cmphex (g_regex_get_match_flags (regex), ==, data->real_match_opts); + } + + g_regex_unref (regex); +} + +#define TEST_NEW(_pattern, _compile_opts, _match_opts) { \ + TestNewData *data; \ + gchar *path; \ + data = g_new0 (TestNewData, 1); \ + data->pattern = _pattern; \ + data->compile_opts = _compile_opts; \ + data->match_opts = _match_opts; \ + data->expected_error = 0; \ + data->check_flags = FALSE; \ + path = g_strdup_printf ("/regex/new/%d", ++total); \ + g_test_add_data_func_full (path, data, test_new, g_free); \ + g_free (path); \ +} + +#define TEST_NEW_CHECK_FLAGS(_pattern, _compile_opts, _match_opts, _real_compile_opts, _real_match_opts) { \ + TestNewData *data; \ + gchar *path; \ + data = g_new0 (TestNewData, 1); \ + data->pattern = _pattern; \ + data->compile_opts = _compile_opts; \ + data->match_opts = 0; \ + data->expected_error = 0; \ + data->check_flags = TRUE; \ + data->real_compile_opts = _real_compile_opts; \ + data->real_match_opts = _real_match_opts; \ + path = g_strdup_printf ("/regex/new-check-flags/%d", ++total); \ + g_test_add_data_func_full (path, data, test_new, g_free); \ + g_free (path); \ +} + +static void +test_new_fail (gconstpointer d) +{ + const TestNewData *data = d; + GRegex *regex; + GError *error = NULL; + + regex = g_regex_new (data->pattern, data->compile_opts, data->match_opts, &error); + + g_assert (regex == NULL); + g_assert_error (error, G_REGEX_ERROR, data->expected_error); + g_error_free (error); +} + +#define TEST_NEW_FAIL(_pattern, _compile_opts, _expected_error) { \ + TestNewData *data; \ + gchar *path; \ + data = g_new0 (TestNewData, 1); \ + data->pattern = _pattern; \ + data->compile_opts = _compile_opts; \ + data->match_opts = 0; \ + data->expected_error = _expected_error; \ + path = g_strdup_printf ("/regex/new-fail/%d", ++total); \ + g_test_add_data_func_full (path, data, test_new_fail, g_free); \ + g_free (path); \ +} + +typedef struct { + const gchar *pattern; + const gchar *string; + GRegexCompileFlags compile_opts; + GRegexMatchFlags match_opts; + gboolean expected; + gssize string_len; + gint start_position; + GRegexMatchFlags match_opts2; +} TestMatchData; + +static void +test_match_simple (gconstpointer d) +{ + const TestMatchData *data = d; + gboolean match; + + match = g_regex_match_simple (data->pattern, data->string, data->compile_opts, data->match_opts); + g_assert_cmpint (match, ==, data->expected); +} + +#define TEST_MATCH_SIMPLE_NAMED(_name, _pattern, _string, _compile_opts, _match_opts, _expected) { \ + TestMatchData *data; \ + gchar *path; \ + data = g_new0 (TestMatchData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->compile_opts = _compile_opts; \ + data->match_opts = _match_opts; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/match-%s/%d", _name, ++total); \ + g_test_add_data_func_full (path, data, test_match_simple, g_free); \ + g_free (path); \ +} + +#define TEST_MATCH_SIMPLE(_pattern, _string, _compile_opts, _match_opts, _expected) \ + TEST_MATCH_SIMPLE_NAMED("simple", _pattern, _string, _compile_opts, _match_opts, _expected) +#define TEST_MATCH_NOTEMPTY(_pattern, _string, _expected) \ + TEST_MATCH_SIMPLE_NAMED("notempty", _pattern, _string, 0, G_REGEX_MATCH_NOTEMPTY, _expected) +#define TEST_MATCH_NOTEMPTY_ATSTART(_pattern, _string, _expected) \ + TEST_MATCH_SIMPLE_NAMED("notempty-atstart", _pattern, _string, 0, G_REGEX_MATCH_NOTEMPTY_ATSTART, _expected) + +static void +test_match (gconstpointer d) +{ + const TestMatchData *data = d; + GRegex *regex; + gboolean match; + GError *error = NULL; + + regex = g_regex_new (data->pattern, data->compile_opts, data->match_opts, &error); + g_assert (regex != NULL); + g_assert_no_error (error); + + match = g_regex_match_full (regex, data->string, data->string_len, + data->start_position, data->match_opts2, NULL, NULL); + + if (data->expected) + { + if (!match) + g_error ("Regex '%s' (with compile options %u and " + "match options %u) should have matched '%.*s' " + "(of length %d, at position %d, with match options %u) but did not", + data->pattern, data->compile_opts, data->match_opts, + data->string_len == -1 ? (int) strlen (data->string) : + (int) data->string_len, + data->string, (int) data->string_len, + data->start_position, data->match_opts2); + + g_assert_cmpint (match, ==, TRUE); + } + else + { + if (match) + g_error ("Regex '%s' (with compile options %u and " + "match options %u) should not have matched '%.*s' " + "(of length %d, at position %d, with match options %u) but did", + data->pattern, data->compile_opts, data->match_opts, + data->string_len == -1 ? (int) strlen (data->string) : + (int) data->string_len, + data->string, (int) data->string_len, + data->start_position, data->match_opts2); + } + + if (data->string_len == -1 && data->start_position == 0) + { + match = g_regex_match (regex, data->string, data->match_opts2, NULL); + g_assert_cmpint (match, ==, data->expected); + } + + g_regex_unref (regex); +} + +#define TEST_MATCH(_pattern, _compile_opts, _match_opts, _string, \ + _string_len, _start_position, _match_opts2, _expected) { \ + TestMatchData *data; \ + gchar *path; \ + data = g_new0 (TestMatchData, 1); \ + data->pattern = _pattern; \ + data->compile_opts = _compile_opts; \ + data->match_opts = _match_opts; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + data->match_opts2 = _match_opts2; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/match/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match, g_free); \ + g_free (path); \ +} + +struct _Match +{ + gchar *string; + gint start, end; +}; +typedef struct _Match Match; + +static void +free_match (gpointer data) +{ + Match *match = data; + if (match == NULL) + return; + g_free (match->string); + g_free (match); +} + +typedef struct { + const gchar *pattern; + const gchar *string; + gssize string_len; + gint start_position; + GSList *expected; +} TestMatchNextData; + +static void +test_match_next (gconstpointer d) +{ + const TestMatchNextData *data = d; + GRegex *regex; + GMatchInfo *match_info; + GSList *matches; + GSList *l_exp, *l_match; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + + g_assert (regex != NULL); + + g_regex_match_full (regex, data->string, data->string_len, + data->start_position, 0, &match_info, NULL); + matches = NULL; + while (g_match_info_matches (match_info)) + { + Match *match = g_new0 (Match, 1); + match->string = g_match_info_fetch (match_info, 0); + match->start = UNTOUCHED; + match->end = UNTOUCHED; + g_match_info_fetch_pos (match_info, 0, &match->start, &match->end); + matches = g_slist_prepend (matches, match); + g_match_info_next (match_info, NULL); + } + g_assert (regex == g_match_info_get_regex (match_info)); + g_assert_cmpstr (data->string, ==, g_match_info_get_string (match_info)); + g_match_info_free (match_info); + matches = g_slist_reverse (matches); + + g_assert_cmpint (g_slist_length (matches), ==, g_slist_length (data->expected)); + + l_exp = data->expected; + l_match = matches; + while (l_exp != NULL) + { + Match *exp = l_exp->data; + Match *match = l_match->data; + + g_assert_cmpstr (exp->string, ==, match->string); + g_assert_cmpint (exp->start, ==, match->start); + g_assert_cmpint (exp->end, ==, match->end); + + l_exp = g_slist_next (l_exp); + l_match = g_slist_next (l_match); + } + + g_regex_unref (regex); + g_slist_free_full (matches, free_match); +} + +static void +free_match_next_data (gpointer _data) +{ + TestMatchNextData *data = _data; + + g_slist_free_full (data->expected, g_free); + g_free (data); +} + +#define TEST_MATCH_NEXT0(_pattern, _string, _string_len, _start_position) { \ + TestMatchNextData *data; \ + gchar *path; \ + data = g_new0 (TestMatchNextData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + data->expected = NULL; \ + path = g_strdup_printf ("/regex/match/next0/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \ + g_free (path); \ +} + +#define TEST_MATCH_NEXT1(_pattern, _string, _string_len, _start_position, \ + t1, s1, e1) { \ + TestMatchNextData *data; \ + Match *match; \ + gchar *path; \ + data = g_new0 (TestMatchNextData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + match = g_new0 (Match, 1); \ + match->string = t1; \ + match->start = s1; \ + match->end = e1; \ + data->expected = g_slist_append (NULL, match); \ + path = g_strdup_printf ("/regex/match/next1/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \ + g_free (path); \ +} + +#define TEST_MATCH_NEXT2(_pattern, _string, _string_len, _start_position, \ + t1, s1, e1, t2, s2, e2) { \ + TestMatchNextData *data; \ + Match *match; \ + gchar *path; \ + data = g_new0 (TestMatchNextData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + match = g_new0 (Match, 1); \ + match->string = t1; \ + match->start = s1; \ + match->end = e1; \ + data->expected = g_slist_append (NULL, match); \ + match = g_new0 (Match, 1); \ + match->string = t2; \ + match->start = s2; \ + match->end = e2; \ + data->expected = g_slist_append (data->expected, match); \ + path = g_strdup_printf ("/regex/match/next2/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \ + g_free (path); \ +} + +#define TEST_MATCH_NEXT3(_pattern, _string, _string_len, _start_position, \ + t1, s1, e1, t2, s2, e2, t3, s3, e3) { \ + TestMatchNextData *data; \ + Match *match; \ + gchar *path; \ + data = g_new0 (TestMatchNextData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + match = g_new0 (Match, 1); \ + match->string = t1; \ + match->start = s1; \ + match->end = e1; \ + data->expected = g_slist_append (NULL, match); \ + match = g_new0 (Match, 1); \ + match->string = t2; \ + match->start = s2; \ + match->end = e2; \ + data->expected = g_slist_append (data->expected, match); \ + match = g_new0 (Match, 1); \ + match->string = t3; \ + match->start = s3; \ + match->end = e3; \ + data->expected = g_slist_append (data->expected, match); \ + path = g_strdup_printf ("/regex/match/next3/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \ + g_free (path); \ +} + +#define TEST_MATCH_NEXT4(_pattern, _string, _string_len, _start_position, \ + t1, s1, e1, t2, s2, e2, t3, s3, e3, t4, s4, e4) { \ + TestMatchNextData *data; \ + Match *match; \ + gchar *path; \ + data = g_new0 (TestMatchNextData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + match = g_new0 (Match, 1); \ + match->string = t1; \ + match->start = s1; \ + match->end = e1; \ + data->expected = g_slist_append (NULL, match); \ + match = g_new0 (Match, 1); \ + match->string = t2; \ + match->start = s2; \ + match->end = e2; \ + data->expected = g_slist_append (data->expected, match); \ + match = g_new0 (Match, 1); \ + match->string = t3; \ + match->start = s3; \ + match->end = e3; \ + data->expected = g_slist_append (data->expected, match); \ + match = g_new0 (Match, 1); \ + match->string = t4; \ + match->start = s4; \ + match->end = e4; \ + data->expected = g_slist_append (data->expected, match); \ + path = g_strdup_printf ("/regex/match/next4/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_next, free_match_next_data); \ + g_free (path); \ +} + +typedef struct { + const gchar *pattern; + const gchar *string; + gint start_position; + GRegexMatchFlags match_opts; + gint expected_count; +} TestMatchCountData; + +static void +test_match_count (gconstpointer d) +{ + const TestMatchCountData *data = d; + GRegex *regex; + GMatchInfo *match_info; + gint count; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + + g_assert (regex != NULL); + + g_regex_match_full (regex, data->string, -1, data->start_position, + data->match_opts, &match_info, NULL); + count = g_match_info_get_match_count (match_info); + + g_assert_cmpint (count, ==, data->expected_count); + + g_match_info_ref (match_info); + g_match_info_unref (match_info); + g_match_info_unref (match_info); + g_regex_unref (regex); +} + +#define TEST_MATCH_COUNT(_pattern, _string, _start_position, _match_opts, _expected_count) { \ + TestMatchCountData *data; \ + gchar *path; \ + data = g_new0 (TestMatchCountData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->start_position = _start_position; \ + data->match_opts = _match_opts; \ + data->expected_count = _expected_count; \ + path = g_strdup_printf ("/regex/match/count/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_count, g_free); \ + g_free (path); \ +} + +static void +test_partial (gconstpointer d) +{ + const TestMatchData *data = d; + GRegex *regex; + GMatchInfo *match_info; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + + g_assert (regex != NULL); + + g_regex_match (regex, data->string, data->match_opts, &match_info); + + g_assert_cmpint (data->expected, ==, g_match_info_is_partial_match (match_info)); + + if (data->expected) + { + g_assert (!g_match_info_fetch_pos (match_info, 0, NULL, NULL)); + g_assert (!g_match_info_fetch_pos (match_info, 1, NULL, NULL)); + } + + g_match_info_free (match_info); + g_regex_unref (regex); +} + +#define TEST_PARTIAL_FULL(_pattern, _string, _match_opts, _expected) { \ + TestMatchData *data; \ + gchar *path; \ + data = g_new0 (TestMatchData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->match_opts = _match_opts; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/match/partial/%d", ++total); \ + g_test_add_data_func_full (path, data, test_partial, g_free); \ + g_free (path); \ +} + +#define TEST_PARTIAL(_pattern, _string, _expected) TEST_PARTIAL_FULL(_pattern, _string, G_REGEX_MATCH_PARTIAL, _expected) + +typedef struct { + const gchar *pattern; + const gchar *string; + gint start_position; + gint sub_n; + const gchar *expected_sub; + gint expected_start; + gint expected_end; +} TestSubData; + +static void +test_sub_pattern (gconstpointer d) +{ + const TestSubData *data = d; + GRegex *regex; + GMatchInfo *match_info; + gchar *sub_expr; + gint start = UNTOUCHED, end = UNTOUCHED; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + + g_assert (regex != NULL); + + g_regex_match_full (regex, data->string, -1, data->start_position, 0, &match_info, NULL); + + sub_expr = g_match_info_fetch (match_info, data->sub_n); + g_assert_cmpstr (sub_expr, ==, data->expected_sub); + g_free (sub_expr); + + g_match_info_fetch_pos (match_info, data->sub_n, &start, &end); + g_assert_cmpint (start, ==, data->expected_start); + g_assert_cmpint (end, ==, data->expected_end); + + g_match_info_free (match_info); + g_regex_unref (regex); +} + +#define TEST_SUB_PATTERN(_pattern, _string, _start_position, _sub_n, _expected_sub, \ + _expected_start, _expected_end) { \ + TestSubData *data; \ + gchar *path; \ + data = g_new0 (TestSubData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->start_position = _start_position; \ + data->sub_n = _sub_n; \ + data->expected_sub = _expected_sub; \ + data->expected_start = _expected_start; \ + data->expected_end = _expected_end; \ + path = g_strdup_printf ("/regex/match/subpattern/%d", ++total); \ + g_test_add_data_func_full (path, data, test_sub_pattern, g_free); \ + g_free (path); \ +} + +typedef struct { + const gchar *pattern; + GRegexCompileFlags flags; + const gchar *string; + gint start_position; + const gchar *sub_name; + const gchar *expected_sub; + gint expected_start; + gint expected_end; +} TestNamedSubData; + +static void +test_named_sub_pattern (gconstpointer d) +{ + const TestNamedSubData *data = d; + GRegex *regex; + GMatchInfo *match_info; + gint start = UNTOUCHED, end = UNTOUCHED; + gchar *sub_expr; + + regex = g_regex_new (data->pattern, data->flags, 0, NULL); + + g_assert (regex != NULL); + + g_regex_match_full (regex, data->string, -1, data->start_position, 0, &match_info, NULL); + sub_expr = g_match_info_fetch_named (match_info, data->sub_name); + g_assert_cmpstr (sub_expr, ==, data->expected_sub); + g_free (sub_expr); + + g_match_info_fetch_named_pos (match_info, data->sub_name, &start, &end); + g_assert_cmpint (start, ==, data->expected_start); + g_assert_cmpint (end, ==, data->expected_end); + + g_match_info_free (match_info); + g_regex_unref (regex); +} + +#define TEST_NAMED_SUB_PATTERN(_pattern, _string, _start_position, _sub_name, \ + _expected_sub, _expected_start, _expected_end) { \ + TestNamedSubData *data; \ + gchar *path; \ + data = g_new0 (TestNamedSubData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->flags = 0; \ + data->start_position = _start_position; \ + data->sub_name = _sub_name; \ + data->expected_sub = _expected_sub; \ + data->expected_start = _expected_start; \ + data->expected_end = _expected_end; \ + path = g_strdup_printf ("/regex/match/named/subpattern/%d", ++total); \ + g_test_add_data_func_full (path, data, test_named_sub_pattern, g_free); \ + g_free (path); \ +} + +#define TEST_NAMED_SUB_PATTERN_DUPNAMES(_pattern, _string, _start_position, _sub_name, \ + _expected_sub, _expected_start, _expected_end) { \ + TestNamedSubData *data; \ + gchar *path; \ + data = g_new0 (TestNamedSubData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->flags = G_REGEX_DUPNAMES; \ + data->start_position = _start_position; \ + data->sub_name = _sub_name; \ + data->expected_sub = _expected_sub; \ + data->expected_start = _expected_start; \ + data->expected_end = _expected_end; \ + path = g_strdup_printf ("/regex/match/subpattern/named/dupnames/%d", ++total); \ + g_test_add_data_func_full (path, data, test_named_sub_pattern, g_free); \ + g_free (path); \ +} + +typedef struct { + const gchar *pattern; + const gchar *string; + GSList *expected; + gint start_position; + gint max_tokens; +} TestFetchAllData; + +static void +test_fetch_all (gconstpointer d) +{ + const TestFetchAllData *data = d; + GRegex *regex; + GMatchInfo *match_info; + GSList *l_exp; + gchar **matches; + gint match_count; + gint i; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + + g_assert (regex != NULL); + + g_regex_match (regex, data->string, 0, &match_info); + matches = g_match_info_fetch_all (match_info); + if (matches) + match_count = g_strv_length (matches); + else + match_count = 0; + + g_assert_cmpint (match_count, ==, g_slist_length (data->expected)); + + l_exp = data->expected; + for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp)) + { + g_assert_nonnull (matches); + g_assert_cmpstr (l_exp->data, ==, matches[i]); + } + + g_match_info_free (match_info); + g_regex_unref (regex); + g_strfreev (matches); +} + +static void +free_fetch_all_data (gpointer _data) +{ + TestFetchAllData *data = _data; + + g_slist_free (data->expected); + g_free (data); +} + +#define TEST_FETCH_ALL0(_pattern, _string) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->expected = NULL; \ + path = g_strdup_printf ("/regex/fetch-all0/%d", ++total); \ + g_test_add_data_func_full (path, data, test_fetch_all, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_FETCH_ALL1(_pattern, _string, e1) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->expected = g_slist_append (NULL, e1); \ + path = g_strdup_printf ("/regex/fetch-all1/%d", ++total); \ + g_test_add_data_func_full (path, data, test_fetch_all, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_FETCH_ALL2(_pattern, _string, e1, e2) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->expected = g_slist_append (NULL, e1); \ + data->expected = g_slist_append (data->expected, e2); \ + path = g_strdup_printf ("/regex/fetch-all2/%d", ++total); \ + g_test_add_data_func_full (path, data, test_fetch_all, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_FETCH_ALL3(_pattern, _string, e1, e2, e3) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->expected = g_slist_append (NULL, e1); \ + data->expected = g_slist_append (data->expected, e2); \ + data->expected = g_slist_append (data->expected, e3); \ + path = g_strdup_printf ("/regex/fetch-all3/%d", ++total); \ + g_test_add_data_func_full (path, data, test_fetch_all, free_fetch_all_data); \ + g_free (path); \ +} + +static void +test_split_simple (gconstpointer d) +{ + const TestFetchAllData *data = d; + GSList *l_exp; + gchar **tokens; + gint token_count; + gint i; + + tokens = g_regex_split_simple (data->pattern, data->string, 0, 0); + if (tokens) + token_count = g_strv_length (tokens); + else + token_count = 0; + + g_assert_cmpint (token_count, ==, g_slist_length (data->expected)); + + l_exp = data->expected; + for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp)) + { + g_assert_nonnull (tokens); + g_assert_cmpstr (l_exp->data, ==, tokens[i]); + } + + g_strfreev (tokens); +} + +#define TEST_SPLIT_SIMPLE0(_pattern, _string) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->expected = NULL; \ + path = g_strdup_printf ("/regex/split/simple0/%d", ++total); \ + g_test_add_data_func_full (path, data, test_split_simple, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_SPLIT_SIMPLE1(_pattern, _string, e1) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->expected = g_slist_append (NULL, e1); \ + path = g_strdup_printf ("/regex/split/simple1/%d", ++total); \ + g_test_add_data_func_full (path, data, test_split_simple, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_SPLIT_SIMPLE2(_pattern, _string, e1, e2) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->expected = g_slist_append (NULL, e1); \ + data->expected = g_slist_append (data->expected, e2); \ + path = g_strdup_printf ("/regex/split/simple2/%d", ++total); \ + g_test_add_data_func_full (path, data, test_split_simple, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_SPLIT_SIMPLE3(_pattern, _string, e1, e2, e3) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->expected = g_slist_append (NULL, e1); \ + data->expected = g_slist_append (data->expected, e2); \ + data->expected = g_slist_append (data->expected, e3); \ + path = g_strdup_printf ("/regex/split/simple3/%d", ++total); \ + g_test_add_data_func_full (path, data, test_split_simple, free_fetch_all_data); \ + g_free (path); \ +} + +static void +test_split_full (gconstpointer d) +{ + const TestFetchAllData *data = d; + GRegex *regex; + GSList *l_exp; + gchar **tokens; + gint token_count; + gint i; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + + g_assert (regex != NULL); + + tokens = g_regex_split_full (regex, data->string, -1, data->start_position, + 0, data->max_tokens, NULL); + if (tokens) + token_count = g_strv_length (tokens); + else + token_count = 0; + + g_assert_cmpint (token_count, ==, g_slist_length (data->expected)); + + l_exp = data->expected; + for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp)) + { + g_assert_nonnull (tokens); + g_assert_cmpstr (l_exp->data, ==, tokens[i]); + } + + g_regex_unref (regex); + g_strfreev (tokens); +} + +static void +test_split (gconstpointer d) +{ + const TestFetchAllData *data = d; + GRegex *regex; + GSList *l_exp; + gchar **tokens; + gint token_count; + gint i; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + + g_assert (regex != NULL); + + tokens = g_regex_split (regex, data->string, 0); + if (tokens) + token_count = g_strv_length (tokens); + else + token_count = 0; + + g_assert_cmpint (token_count, ==, g_slist_length (data->expected)); + + l_exp = data->expected; + for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp)) + { + g_assert_nonnull (tokens); + g_assert_cmpstr (l_exp->data, ==, tokens[i]); + } + + g_regex_unref (regex); + g_strfreev (tokens); +} + +#define TEST_SPLIT0(_pattern, _string, _start_position, _max_tokens) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->start_position = _start_position; \ + data->max_tokens = _max_tokens; \ + data->expected = NULL; \ + if (_start_position == 0 && _max_tokens <= 0) { \ + path = g_strdup_printf ("/regex/split0/%d", ++total); \ + g_test_add_data_func (path, data, test_split); \ + g_free (path); \ + } \ + path = g_strdup_printf ("/regex/full-split0/%d", ++total); \ + g_test_add_data_func_full (path, data, test_split_full, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_SPLIT1(_pattern, _string, _start_position, _max_tokens, e1) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->start_position = _start_position; \ + data->max_tokens = _max_tokens; \ + data->expected = NULL; \ + data->expected = g_slist_append (data->expected, e1); \ + if (_start_position == 0 && _max_tokens <= 0) { \ + path = g_strdup_printf ("/regex/split1/%d", ++total); \ + g_test_add_data_func (path, data, test_split); \ + g_free (path); \ + } \ + path = g_strdup_printf ("/regex/full-split1/%d", ++total); \ + g_test_add_data_func_full (path, data, test_split_full, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_SPLIT2(_pattern, _string, _start_position, _max_tokens, e1, e2) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->start_position = _start_position; \ + data->max_tokens = _max_tokens; \ + data->expected = NULL; \ + data->expected = g_slist_append (data->expected, e1); \ + data->expected = g_slist_append (data->expected, e2); \ + if (_start_position == 0 && _max_tokens <= 0) { \ + path = g_strdup_printf ("/regex/split2/%d", ++total); \ + g_test_add_data_func (path, data, test_split); \ + g_free (path); \ + } \ + path = g_strdup_printf ("/regex/full-split2/%d", ++total); \ + g_test_add_data_func_full (path, data, test_split_full, free_fetch_all_data); \ + g_free (path); \ +} + +#define TEST_SPLIT3(_pattern, _string, _start_position, _max_tokens, e1, e2, e3) { \ + TestFetchAllData *data; \ + gchar *path; \ + data = g_new0 (TestFetchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->start_position = _start_position; \ + data->max_tokens = _max_tokens; \ + data->expected = NULL; \ + data->expected = g_slist_append (data->expected, e1); \ + data->expected = g_slist_append (data->expected, e2); \ + data->expected = g_slist_append (data->expected, e3); \ + if (_start_position == 0 && _max_tokens <= 0) { \ + path = g_strdup_printf ("/regex/split3/%d", ++total); \ + g_test_add_data_func (path, data, test_split); \ + g_free (path); \ + } \ + path = g_strdup_printf ("/regex/full-split3/%d", ++total); \ + g_test_add_data_func_full (path, data, test_split_full, free_fetch_all_data); \ + g_free (path); \ +} + +typedef struct { + const gchar *string_to_expand; + gboolean expected; + gboolean expected_refs; +} TestCheckReplacementData; + +static void +test_check_replacement (gconstpointer d) +{ + const TestCheckReplacementData *data = d; + gboolean has_refs; + gboolean result; + + result = g_regex_check_replacement (data->string_to_expand, &has_refs, NULL); + g_assert_cmpint (data->expected, ==, result); + + if (data->expected) + g_assert_cmpint (data->expected_refs, ==, has_refs); +} + +#define TEST_CHECK_REPLACEMENT(_string_to_expand, _expected, _expected_refs) { \ + TestCheckReplacementData *data; \ + gchar *path; \ + data = g_new0 (TestCheckReplacementData, 1); \ + data->string_to_expand = _string_to_expand; \ + data->expected = _expected; \ + data->expected_refs = _expected_refs; \ + path = g_strdup_printf ("/regex/check-repacement/%d", ++total); \ + g_test_add_data_func_full (path, data, test_check_replacement, g_free); \ + g_free (path); \ +} + +typedef struct { + const gchar *pattern; + const gchar *string; + const gchar *string_to_expand; + gboolean raw; + const gchar *expected; +} TestExpandData; + +static void +test_expand (gconstpointer d) +{ + const TestExpandData *data = d; + GRegex *regex = NULL; + GMatchInfo *match_info = NULL; + gchar *res; + GError *error = NULL; + + if (data->pattern) + { + regex = g_regex_new (data->pattern, data->raw ? G_REGEX_RAW : 0, 0, + &error); + g_assert_no_error (error); + g_regex_match (regex, data->string, 0, &match_info); + } + + res = g_match_info_expand_references (match_info, data->string_to_expand, NULL); + g_assert_cmpstr (res, ==, data->expected); + g_free (res); + g_match_info_free (match_info); + if (regex) + g_regex_unref (regex); +} + +#define TEST_EXPAND(_pattern, _string, _string_to_expand, _raw, _expected) { \ + TestExpandData *data; \ + gchar *path; \ + data = g_new0 (TestExpandData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_to_expand = _string_to_expand; \ + data->raw = _raw; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/expand/%d", ++total); \ + g_test_add_data_func_full (path, data, test_expand, g_free); \ + g_free (path); \ +} + +typedef struct { + const gchar *pattern; + const gchar *string; + gint start_position; + const gchar *replacement; + const gchar *expected; +} TestReplaceData; + +static void +test_replace (gconstpointer d) +{ + const TestReplaceData *data = d; + GRegex *regex; + gchar *res; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + res = g_regex_replace (regex, data->string, -1, data->start_position, data->replacement, 0, NULL); + + g_assert_cmpstr (res, ==, data->expected); + + g_free (res); + g_regex_unref (regex); +} + +#define TEST_REPLACE(_pattern, _string, _start_position, _replacement, _expected) { \ + TestReplaceData *data; \ + gchar *path; \ + data = g_new0 (TestReplaceData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->start_position = _start_position; \ + data->replacement = _replacement; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/replace/%d", ++total); \ + g_test_add_data_func_full (path, data, test_replace, g_free); \ + g_free (path); \ +} + +static void +test_replace_lit (gconstpointer d) +{ + const TestReplaceData *data = d; + GRegex *regex; + gchar *res; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + res = g_regex_replace_literal (regex, data->string, -1, data->start_position, + data->replacement, 0, NULL); + g_assert_cmpstr (res, ==, data->expected); + + g_free (res); + g_regex_unref (regex); +} + +#define TEST_REPLACE_LIT(_pattern, _string, _start_position, _replacement, _expected) { \ + TestReplaceData *data; \ + gchar *path; \ + data = g_new0 (TestReplaceData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->start_position = _start_position; \ + data->replacement = _replacement; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/replace-literally/%d", ++total); \ + g_test_add_data_func_full (path, data, test_replace_lit, g_free); \ + g_free (path); \ +} + +typedef struct { + const gchar *pattern; + const gchar *name; + gint expected_num; +} TestStringNumData; + +static void +test_get_string_number (gconstpointer d) +{ + const TestStringNumData *data = d; + GRegex *regex; + gint num; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + num = g_regex_get_string_number (regex, data->name); + + g_assert_cmpint (num, ==, data->expected_num); + g_regex_unref (regex); +} + +#define TEST_GET_STRING_NUMBER(_pattern, _name, _expected_num) { \ + TestStringNumData *data; \ + gchar *path; \ + data = g_new0 (TestStringNumData, 1); \ + data->pattern = _pattern; \ + data->name = _name; \ + data->expected_num = _expected_num; \ + path = g_strdup_printf ("/regex/string-number/%d", ++total); \ + g_test_add_data_func_full (path, data, test_get_string_number, g_free); \ + g_free (path); \ +} + +typedef struct { + const gchar *string; + gint length; + const gchar *expected; +} TestEscapeData; + +static void +test_escape (gconstpointer d) +{ + const TestEscapeData *data = d; + gchar *escaped; + + escaped = g_regex_escape_string (data->string, data->length); + + g_assert_cmpstr (escaped, ==, data->expected); + + g_free (escaped); +} + +#define TEST_ESCAPE(_string, _length, _expected) { \ + TestEscapeData *data; \ + gchar *path; \ + data = g_new0 (TestEscapeData, 1); \ + data->string = _string; \ + data->length = _length; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/escape/%d", ++total); \ + g_test_add_data_func_full (path, data, test_escape, g_free); \ + g_free (path); \ +} + +static void +test_escape_nul (gconstpointer d) +{ + const TestEscapeData *data = d; + gchar *escaped; + + escaped = g_regex_escape_nul (data->string, data->length); + + g_assert_cmpstr (escaped, ==, data->expected); + + g_free (escaped); +} + +#define TEST_ESCAPE_NUL(_string, _length, _expected) { \ + TestEscapeData *data; \ + gchar *path; \ + data = g_new0 (TestEscapeData, 1); \ + data->string = _string; \ + data->length = _length; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/escape_nul/%d", ++total); \ + g_test_add_data_func_full (path, data, test_escape_nul, g_free); \ + g_free (path); \ +} + +typedef struct { + const gchar *pattern; + const gchar *string; + gssize string_len; + gint start_position; + GSList *expected; +} TestMatchAllData; + +static void +test_match_all_full (gconstpointer d) +{ + const TestMatchAllData *data = d; + GRegex *regex; + GMatchInfo *match_info; + GSList *l_exp; + gboolean match_ok; + gint match_count; + gint i; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + match_ok = g_regex_match_all_full (regex, data->string, data->string_len, data->start_position, + 0, &match_info, NULL); + + if (g_slist_length (data->expected) == 0) + g_assert (!match_ok); + else + g_assert (match_ok); + + match_count = g_match_info_get_match_count (match_info); + g_assert_cmpint (match_count, ==, g_slist_length (data->expected)); + + l_exp = data->expected; + for (i = 0; i < match_count; i++) + { + gint start, end; + gchar *matched_string; + Match *exp = l_exp->data; + + matched_string = g_match_info_fetch (match_info, i); + g_match_info_fetch_pos (match_info, i, &start, &end); + + g_assert_cmpstr (exp->string, ==, matched_string); + g_assert_cmpint (exp->start, ==, start); + g_assert_cmpint (exp->end, ==, end); + + g_free (matched_string); + + l_exp = g_slist_next (l_exp); + } + + g_match_info_free (match_info); + g_regex_unref (regex); +} + +static void +test_match_all (gconstpointer d) +{ + const TestMatchAllData *data = d; + GRegex *regex; + GMatchInfo *match_info; + GSList *l_exp; + gboolean match_ok; + guint i, match_count; + + regex = g_regex_new (data->pattern, 0, 0, NULL); + match_ok = g_regex_match_all (regex, data->string, 0, &match_info); + + if (g_slist_length (data->expected) == 0) + g_assert (!match_ok); + else + g_assert (match_ok); + + match_count = g_match_info_get_match_count (match_info); + g_assert_cmpint (match_count, >=, 0); + + if (match_count != g_slist_length (data->expected)) + { + g_message ("regex: %s", data->pattern); + g_message ("string: %s", data->string); + g_message ("matched strings:"); + + for (i = 0; i < match_count; i++) + { + gint start, end; + gchar *matched_string; + + matched_string = g_match_info_fetch (match_info, i); + g_match_info_fetch_pos (match_info, i, &start, &end); + g_message ("%u. %d-%d '%s'", i, start, end, matched_string); + g_free (matched_string); + } + + g_message ("expected strings:"); + i = 0; + + for (l_exp = data->expected; l_exp != NULL; l_exp = l_exp->next) + { + Match *exp = l_exp->data; + + g_message ("%u. %d-%d '%s'", i, exp->start, exp->end, exp->string); + i++; + } + + g_error ("match_count not as expected: %u != %d", + match_count, g_slist_length (data->expected)); + } + + l_exp = data->expected; + for (i = 0; i < match_count; i++) + { + gint start, end; + gchar *matched_string; + Match *exp = l_exp->data; + + matched_string = g_match_info_fetch (match_info, i); + g_match_info_fetch_pos (match_info, i, &start, &end); + + g_assert_cmpstr (exp->string, ==, matched_string); + g_assert_cmpint (exp->start, ==, start); + g_assert_cmpint (exp->end, ==, end); + + g_free (matched_string); + + l_exp = g_slist_next (l_exp); + } + + g_match_info_free (match_info); + g_regex_unref (regex); +} + +static void +free_match_all_data (gpointer _data) +{ + TestMatchAllData *data = _data; + + g_slist_free_full (data->expected, g_free); + g_free (data); +} + +#define TEST_MATCH_ALL0(_pattern, _string, _string_len, _start_position) { \ + TestMatchAllData *data; \ + gchar *path; \ + data = g_new0 (TestMatchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + data->expected = NULL; \ + if (_string_len == -1 && _start_position == 0) { \ + path = g_strdup_printf ("/regex/match-all0/%d", ++total); \ + g_test_add_data_func (path, data, test_match_all); \ + g_free (path); \ + } \ + path = g_strdup_printf ("/regex/match-all-full0/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_all_full, free_match_all_data); \ + g_free (path); \ +} + +#define TEST_MATCH_ALL1(_pattern, _string, _string_len, _start_position, \ + t1, s1, e1) { \ + TestMatchAllData *data; \ + Match *match; \ + gchar *path; \ + data = g_new0 (TestMatchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + data->expected = NULL; \ + match = g_new0 (Match, 1); \ + match->string = t1; \ + match->start = s1; \ + match->end = e1; \ + data->expected = g_slist_append (data->expected, match); \ + if (_string_len == -1 && _start_position == 0) { \ + path = g_strdup_printf ("/regex/match-all1/%d", ++total); \ + g_test_add_data_func (path, data, test_match_all); \ + g_free (path); \ + } \ + path = g_strdup_printf ("/regex/match-all-full1/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_all_full, free_match_all_data); \ + g_free (path); \ +} + +#define TEST_MATCH_ALL2(_pattern, _string, _string_len, _start_position, \ + t1, s1, e1, t2, s2, e2) { \ + TestMatchAllData *data; \ + Match *match; \ + gchar *path; \ + data = g_new0 (TestMatchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + data->expected = NULL; \ + match = g_new0 (Match, 1); \ + match->string = t1; \ + match->start = s1; \ + match->end = e1; \ + data->expected = g_slist_append (data->expected, match); \ + match = g_new0 (Match, 1); \ + match->string = t2; \ + match->start = s2; \ + match->end = e2; \ + data->expected = g_slist_append (data->expected, match); \ + if (_string_len == -1 && _start_position == 0) { \ + path = g_strdup_printf ("/regex/match-all2/%d", ++total); \ + g_test_add_data_func (path, data, test_match_all); \ + g_free (path); \ + } \ + path = g_strdup_printf ("/regex/match-all-full2/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_all_full, free_match_all_data); \ + g_free (path); \ +} + +#define TEST_MATCH_ALL3(_pattern, _string, _string_len, _start_position, \ + t1, s1, e1, t2, s2, e2, t3, s3, e3) { \ + TestMatchAllData *data; \ + Match *match; \ + gchar *path; \ + data = g_new0 (TestMatchAllData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ + data->string_len = _string_len; \ + data->start_position = _start_position; \ + data->expected = NULL; \ + match = g_new0 (Match, 1); \ + match->string = t1; \ + match->start = s1; \ + match->end = e1; \ + data->expected = g_slist_append (data->expected, match); \ + match = g_new0 (Match, 1); \ + match->string = t2; \ + match->start = s2; \ + match->end = e2; \ + data->expected = g_slist_append (data->expected, match); \ + match = g_new0 (Match, 1); \ + match->string = t3; \ + match->start = s3; \ + match->end = e3; \ + data->expected = g_slist_append (data->expected, match); \ + if (_string_len == -1 && _start_position == 0) { \ + path = g_strdup_printf ("/regex/match-all3/%d", ++total); \ + g_test_add_data_func (path, data, test_match_all); \ + g_free (path); \ + } \ + path = g_strdup_printf ("/regex/match-all-full3/%d", ++total); \ + g_test_add_data_func_full (path, data, test_match_all_full, free_match_all_data); \ + g_free (path); \ +} + +static void +test_properties (void) +{ + GRegex *regex; + GError *error; + gboolean res; + GMatchInfo *match; + gchar *str; + + error = NULL; + regex = g_regex_new ("\\p{L}\\p{Ll}\\p{Lu}\\p{L&}\\p{N}\\p{Nd}", G_REGEX_OPTIMIZE, 0, &error); + res = g_regex_match (regex, "ppPP01", 0, &match); + g_assert (res); + str = g_match_info_fetch (match, 0); + g_assert_cmpstr (str, ==, "ppPP01"); + g_free (str); + + g_match_info_free (match); + g_regex_unref (regex); +} + +static void +test_class (void) +{ + GRegex *regex; + GError *error; + GMatchInfo *match; + gboolean res; + gchar *str; + + error = NULL; + regex = g_regex_new ("[abc\\x{0B1E}\\p{Mn}\\x{0391}-\\x{03A9}]", G_REGEX_OPTIMIZE, 0, &error); + res = g_regex_match (regex, "a:b:\340\254\236:\333\253:\316\240", 0, &match); + g_assert (res); + str = g_match_info_fetch (match, 0); + g_assert_cmpstr (str, ==, "a"); + g_free (str); + res = g_match_info_next (match, NULL); + g_assert (res); + str = g_match_info_fetch (match, 0); + g_assert_cmpstr (str, ==, "b"); + g_free (str); + res = g_match_info_next (match, NULL); + g_assert (res); + str = g_match_info_fetch (match, 0); + g_assert_cmpstr (str, ==, "\340\254\236"); + g_free (str); + res = g_match_info_next (match, NULL); + g_assert (res); + str = g_match_info_fetch (match, 0); + g_assert_cmpstr (str, ==, "\333\253"); + g_free (str); + res = g_match_info_next (match, NULL); + g_assert (res); + str = g_match_info_fetch (match, 0); + g_assert_cmpstr (str, ==, "\316\240"); + g_free (str); + + res = g_match_info_next (match, NULL); + g_assert (!res); + + g_match_info_free (match); + g_regex_unref (regex); +} + +/* examples for lookahead assertions taken from pcrepattern(3) */ +static void +test_lookahead (void) +{ + GRegex *regex; + GError *error; + GMatchInfo *match; + gboolean res; + gchar *str; + gint start, end; + + error = NULL; + regex = g_regex_new ("\\w+(?=;)", G_REGEX_OPTIMIZE, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "word1 word2: word3;", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_assert_cmpint (g_match_info_get_match_count (match), ==, 1); + str = g_match_info_fetch (match, 0); + g_assert_cmpstr (str, ==, "word3"); + g_free (str); + g_match_info_free (match); + g_regex_unref (regex); + + error = NULL; + regex = g_regex_new ("foo(?!bar)", G_REGEX_OPTIMIZE, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "foobar foobaz", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_assert_cmpint (g_match_info_get_match_count (match), ==, 1); + res = g_match_info_fetch_pos (match, 0, &start, &end); + g_assert (res); + g_assert_cmpint (start, ==, 7); + g_assert_cmpint (end, ==, 10); + g_match_info_free (match); + g_regex_unref (regex); + + error = NULL; + regex = g_regex_new ("(?!bar)foo", G_REGEX_OPTIMIZE, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "foobar foobaz", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_assert_cmpint (g_match_info_get_match_count (match), ==, 1); + res = g_match_info_fetch_pos (match, 0, &start, &end); + g_assert (res); + g_assert_cmpint (start, ==, 0); + g_assert_cmpint (end, ==, 3); + res = g_match_info_next (match, &error); + g_assert (res); + g_assert_no_error (error); + res = g_match_info_fetch_pos (match, 0, &start, &end); + g_assert (res); + g_assert_cmpint (start, ==, 7); + g_assert_cmpint (end, ==, 10); + g_match_info_free (match); + g_regex_unref (regex); +} + +/* examples for lookbehind assertions taken from pcrepattern(3) */ +static void +test_lookbehind (void) +{ + GRegex *regex; + GError *error; + GMatchInfo *match; + gboolean res; + gint start, end; + + error = NULL; + regex = g_regex_new ("(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "Mon Tuesday Wed Saturday", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + str = g_match_info_fetch_named (match, "DN"); + g_assert_cmpstr (str, ==, "Mon"); + g_free (str); + res = g_match_info_next (match, &error); + g_assert (res); + str = g_match_info_fetch_named (match, "DN"); + g_assert_cmpstr (str, ==, "Tue"); + g_free (str); + res = g_match_info_next (match, &error); + g_assert (res); + str = g_match_info_fetch_named (match, "DN"); + g_assert_cmpstr (str, ==, "Wed"); + g_free (str); + res = g_match_info_next (match, &error); + g_assert (res); + str = g_match_info_fetch_named (match, "DN"); + g_assert_cmpstr (str, ==, "Sat"); + g_free (str); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("^(a|b\\1)+$", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "aaaaaaaaaaaaaaaa", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "ababbaa", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); +} + +/* examples for conditions taken from pcrepattern(3) */ +static void +test_condition (void) +{ + GRegex *regex; + GError *error; + GMatchInfo *match; + gboolean res; + + error = NULL; + regex = g_regex_new ("^(a+)(\\()?[^()]+(?(-1)\\))(b+)$", G_REGEX_OPTIMIZE, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a(zzzzzz)b", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "aaazzzzzzbbb", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); + + error = NULL; + regex = g_regex_new ("^(a+)(?\\()?[^()]+(?()\\))(b+)$", G_REGEX_OPTIMIZE, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a(zzzzzz)b", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "aaazzzzzzbbb", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("^(a+)(?(+1)\\[|\\<)?[^()]+(\\])?(b+)$", G_REGEX_OPTIMIZE, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a[zzzzzz]b", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "aaa 2[0-4]\\d | 25[0-5] | 1\\d\\d | [1-9]?\\d) )" + "\\b (?&byte) (\\.(?&byte)){3} \\b", + G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "128.0.0.1", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "192.168.1.1", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "209.132.180.167", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("^(?(?=[^a-z]*[a-z])" + "\\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} )$", + G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "01-abc-24", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "01-23-45", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "01-uv-45", 0, &match); + g_assert (!res); + g_assert (!g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "01-234-45", 0, &match); + g_assert (!res); + g_assert (!g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); +} + +/* examples for recursion taken from pcrepattern(3) */ +static void +test_recursion (void) +{ + GRegex *regex; + GError *error; + GMatchInfo *match; + gboolean res; + gint start; + + error = NULL; + regex = g_regex_new ("\\( ( [^()]++ | (?R) )* \\)", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "(middle)", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "((((((((((((((((middle))))))))))))))))", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "(((xxx(((", 0, &match); + g_assert (!res); + g_assert (!g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("^( \\( ( [^()]++ | (?1) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "((((((((((((((((middle))))))))))))))))", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "(((xxx((()", 0, &match); + g_assert (!res); + g_assert (!g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("^(? \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + g_regex_match (regex, "(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()", 0, &match); + g_assert (!res); + g_assert (!g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, ">>>", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + res = g_match_info_fetch_pos (match, 0, &start, NULL); + g_assert (res); + g_assert_cmpint (start, ==, 0); + g_match_info_free (match); + res = g_regex_match (regex, ">>>", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + res = g_match_info_fetch_pos (match, 0, &start, NULL); + g_assert (res); + g_assert_cmpint (start, >, 0); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("^((.)(?1)\\2|.)$", G_REGEX_OPTIMIZE, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "abcddcba", 0, &match); + g_assert (!res); + g_assert (!g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$", G_REGEX_OPTIMIZE, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "abcddcba", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); + + regex = g_regex_new ("^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$", G_REGEX_OPTIMIZE|G_REGEX_CASELESS, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "A man, a plan, a canal: Panama!", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + res = g_regex_match (regex, "Oozy rat in a sanitary zoo", 0, &match); + g_assert (res); + g_assert (g_match_info_matches (match)); + g_match_info_free (match); + g_regex_unref (regex); +} + +static void +test_multiline (void) +{ + GRegex *regex; + GMatchInfo *info; + gint count; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=640489"); + + regex = g_regex_new ("^a$", G_REGEX_MULTILINE|G_REGEX_DOTALL, 0, NULL); + + count = 0; + g_regex_match (regex, "a\nb\na", 0, &info); + while (g_match_info_matches (info)) + { + count++; + g_match_info_next (info, NULL); + } + g_match_info_free (info); + g_regex_unref (regex); + + g_assert_cmpint (count, ==, 2); +} + +static void +test_explicit_crlf (void) +{ + GRegex *regex; + + regex = g_regex_new ("[\r\n]a", 0, 0, NULL); + g_assert_cmpint (g_regex_get_has_cr_or_lf (regex), ==, TRUE); + g_regex_unref (regex); +} + +static void +test_max_lookbehind (void) +{ + GRegex *regex; + + regex = g_regex_new ("abc", 0, 0, NULL); + g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 0); + g_regex_unref (regex); + + regex = g_regex_new ("\\babc", 0, 0, NULL); + g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 1); + g_regex_unref (regex); + + regex = g_regex_new ("(?<=123)abc", 0, 0, NULL); + g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 3); + g_regex_unref (regex); +} + +static gboolean +pcre_ge (guint64 major, guint64 minor) +{ + const char *version; + gchar *ptr; + guint64 pcre_major, pcre_minor; + + /* e.g. 8.35 2014-04-04 */ + version = pcre_version (); + + pcre_major = g_ascii_strtoull (version, &ptr, 10); + /* ptr points to ".MINOR (release date)" */ + g_assert (ptr[0] == '.'); + pcre_minor = g_ascii_strtoull (ptr + 1, NULL, 10); + + return (pcre_major > major) || (pcre_major == major && pcre_minor >= minor); +} + +int +main (int argc, char *argv[]) +{ + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/regex/properties", test_properties); + g_test_add_func ("/regex/class", test_class); + g_test_add_func ("/regex/lookahead", test_lookahead); + g_test_add_func ("/regex/lookbehind", test_lookbehind); + g_test_add_func ("/regex/subpattern", test_subpattern); + g_test_add_func ("/regex/condition", test_condition); + g_test_add_func ("/regex/recursion", test_recursion); + g_test_add_func ("/regex/multiline", test_multiline); + g_test_add_func ("/regex/explicit-crlf", test_explicit_crlf); + g_test_add_func ("/regex/max-lookbehind", test_max_lookbehind); + + /* TEST_NEW(pattern, compile_opts, match_opts) */ + TEST_NEW("[A-Z]+", G_REGEX_CASELESS | G_REGEX_EXTENDED | G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTBOL | G_REGEX_MATCH_PARTIAL); + TEST_NEW("", 0, 0); + TEST_NEW(".*", 0, 0); + TEST_NEW(".*", G_REGEX_OPTIMIZE, 0); + TEST_NEW(".*", G_REGEX_MULTILINE, 0); + TEST_NEW(".*", G_REGEX_DOTALL, 0); + TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_NOTBOL); + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", 0, 0); + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS, 0); + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0); + TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES, 0); + TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, 0); + /* This gives "internal error: code overflow" with pcre 6.0 */ + TEST_NEW("(?i)(?-i)", 0, 0); + TEST_NEW ("(?i)a", 0, 0); + TEST_NEW ("(?m)a", 0, 0); + TEST_NEW ("(?s)a", 0, 0); + TEST_NEW ("(?x)a", 0, 0); + TEST_NEW ("(?J)a", 0, 0); + TEST_NEW ("(?U)[a-z]+", 0, 0); + + /* TEST_NEW_CHECK_FLAGS(pattern, compile_opts, match_ops, real_compile_opts, real_match_opts) */ + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_OPTIMIZE, 0, G_REGEX_OPTIMIZE, 0); + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_RAW, 0, G_REGEX_RAW, 0); + TEST_NEW_CHECK_FLAGS ("(?X)a", 0, 0, 0 /* not exposed by GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("^.*", 0, 0, G_REGEX_ANCHORED, 0); + TEST_NEW_CHECK_FLAGS ("(*UTF8)a", 0, 0, 0 /* this is the default in GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("(*UCP)a", 0, 0, 0 /* this always on in GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("(*CR)a", 0, 0, G_REGEX_NEWLINE_CR, 0); + TEST_NEW_CHECK_FLAGS ("(*LF)a", 0, 0, G_REGEX_NEWLINE_LF, 0); + TEST_NEW_CHECK_FLAGS ("(*CRLF)a", 0, 0, G_REGEX_NEWLINE_CRLF, 0); + TEST_NEW_CHECK_FLAGS ("(*ANY)a", 0, 0, 0 /* this is the default in GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("(*ANYCRLF)a", 0, 0, G_REGEX_NEWLINE_ANYCRLF, 0); + TEST_NEW_CHECK_FLAGS ("(*BSR_ANYCRLF)a", 0, 0, G_REGEX_BSR_ANYCRLF, 0); + TEST_NEW_CHECK_FLAGS ("(*BSR_UNICODE)a", 0, 0, 0 /* this is the default in GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("(*NO_START_OPT)a", 0, 0, 0 /* not exposed in GRegex */, 0); + + /* TEST_NEW_FAIL(pattern, compile_opts, expected_error) */ + TEST_NEW_FAIL("(", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); + TEST_NEW_FAIL(")", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); + TEST_NEW_FAIL("[", 0, G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS); + TEST_NEW_FAIL("*", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT); + TEST_NEW_FAIL("?", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT); + TEST_NEW_FAIL("(?Px)|(?Py)", 0, G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME); + + /* Check all GRegexError codes */ + TEST_NEW_FAIL ("a\\", 0, G_REGEX_ERROR_STRAY_BACKSLASH); + TEST_NEW_FAIL ("a\\c", 0, G_REGEX_ERROR_MISSING_CONTROL_CHAR); + TEST_NEW_FAIL ("a\\l", 0, G_REGEX_ERROR_UNRECOGNIZED_ESCAPE); + TEST_NEW_FAIL ("a{4,2}", 0, G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER); + TEST_NEW_FAIL ("a{999999,}", 0, G_REGEX_ERROR_QUANTIFIER_TOO_BIG); + TEST_NEW_FAIL ("[a-z", 0, G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS); + TEST_NEW_FAIL ("(?X)[\\B]", 0, G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS); + TEST_NEW_FAIL ("[z-a]", 0, G_REGEX_ERROR_RANGE_OUT_OF_ORDER); + TEST_NEW_FAIL ("{2,4}", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT); + TEST_NEW_FAIL ("a(?u)", 0, G_REGEX_ERROR_UNRECOGNIZED_CHARACTER); + TEST_NEW_FAIL ("a(?<$foo)bar", 0, G_REGEX_ERROR_UNRECOGNIZED_CHARACTER); + TEST_NEW_FAIL ("a[:alpha:]b", 0, G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS); + TEST_NEW_FAIL ("a(b", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); + TEST_NEW_FAIL ("a)b", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); + TEST_NEW_FAIL ("a(?R", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); + TEST_NEW_FAIL ("a(?-54", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); + TEST_NEW_FAIL ("(ab\\2)", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE); + TEST_NEW_FAIL ("a(?#abc", 0, G_REGEX_ERROR_UNTERMINATED_COMMENT); + TEST_NEW_FAIL ("(?<=a+)b", 0, G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND); + TEST_NEW_FAIL ("(?(1?)a|b)", 0, G_REGEX_ERROR_MALFORMED_CONDITION); + TEST_NEW_FAIL ("(a)(?(1)a|b|c)", 0, G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES); + TEST_NEW_FAIL ("(?(?i))", 0, G_REGEX_ERROR_ASSERTION_EXPECTED); + TEST_NEW_FAIL ("a[[:fubar:]]b", 0, G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME); + TEST_NEW_FAIL ("[[.ch.]]", 0, G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED); + TEST_NEW_FAIL ("\\x{110000}", 0, G_REGEX_ERROR_HEX_CODE_TOO_LARGE); + TEST_NEW_FAIL ("^(?(0)f|b)oo", 0, G_REGEX_ERROR_INVALID_CONDITION); + TEST_NEW_FAIL ("(?<=\\C)X", 0, G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND); + TEST_NEW_FAIL ("(?!\\w)(?R)", 0, G_REGEX_ERROR_INFINITE_LOOP); + if (pcre_ge (8, 37)) + { + /* The expected errors changed here. */ + TEST_NEW_FAIL ("(?(?foo)\\gfoo)\\geks)(?Peccs)", 0, G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME); +#if 0 + TEST_NEW_FAIL (?, 0, G_REGEX_ERROR_MALFORMED_PROPERTY); + TEST_NEW_FAIL (?, 0, G_REGEX_ERROR_UNKNOWN_PROPERTY); +#endif + TEST_NEW_FAIL ("\\666", G_REGEX_RAW, G_REGEX_ERROR_INVALID_OCTAL_VALUE); + TEST_NEW_FAIL ("^(?(DEFINE) abc | xyz ) ", 0, G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE); + TEST_NEW_FAIL ("a", G_REGEX_NEWLINE_CRLF | G_REGEX_NEWLINE_ANYCRLF, G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS); + TEST_NEW_FAIL ("^(a)\\g{3", 0, G_REGEX_ERROR_MISSING_BACK_REFERENCE); + TEST_NEW_FAIL ("^(a)\\g{0}", 0, G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE); + TEST_NEW_FAIL ("abc(*FAIL:123)xyz", 0, G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN); + TEST_NEW_FAIL ("a(*FOOBAR)b", 0, G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB); + TEST_NEW_FAIL ("(?i:A{1,}\\6666666666)", 0, G_REGEX_ERROR_NUMBER_TOO_BIG); + TEST_NEW_FAIL ("(?)(?&)", 0, G_REGEX_ERROR_MISSING_SUBPATTERN_NAME); + TEST_NEW_FAIL ("(?+-a)", 0, G_REGEX_ERROR_MISSING_DIGIT); + TEST_NEW_FAIL ("TA]", G_REGEX_JAVASCRIPT_COMPAT, G_REGEX_ERROR_INVALID_DATA_CHARACTER); + TEST_NEW_FAIL ("(?|(?A)|(?B))", 0, G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME); + TEST_NEW_FAIL ("a(*MARK)b", 0, G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED); + TEST_NEW_FAIL ("^\\c€", 0, G_REGEX_ERROR_INVALID_CONTROL_CHAR); + TEST_NEW_FAIL ("\\k", 0, G_REGEX_ERROR_MISSING_NAME); + TEST_NEW_FAIL ("a[\\NB]c", 0, G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS); + TEST_NEW_FAIL ("(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEFG)XX", 0, G_REGEX_ERROR_NAME_TOO_LONG); + TEST_NEW_FAIL ("\\u0100", G_REGEX_RAW | G_REGEX_JAVASCRIPT_COMPAT, G_REGEX_ERROR_CHARACTER_VALUE_TOO_LARGE); + + /* These errors can't really be tested easily: + * G_REGEX_ERROR_EXPRESSION_TOO_LARGE + * G_REGEX_ERROR_MEMORY_ERROR + * G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG + * G_REGEX_ERROR_TOO_MANY_SUBPATTERNS + * G_REGEX_ERROR_TOO_MANY_FORWARD_REFERENCES + * + * These errors are obsolete and never raised by PCRE: + * G_REGEX_ERROR_DEFINE_REPETION + */ + + /* TEST_MATCH_SIMPLE(pattern, string, compile_opts, match_opts, expected) */ + TEST_MATCH_SIMPLE("a", "", 0, 0, FALSE); + TEST_MATCH_SIMPLE("a", "a", 0, 0, TRUE); + TEST_MATCH_SIMPLE("a", "ba", 0, 0, TRUE); + TEST_MATCH_SIMPLE("^a", "ba", 0, 0, FALSE); + TEST_MATCH_SIMPLE("a", "ba", G_REGEX_ANCHORED, 0, FALSE); + TEST_MATCH_SIMPLE("a", "ba", 0, G_REGEX_MATCH_ANCHORED, FALSE); + TEST_MATCH_SIMPLE("a", "ab", G_REGEX_ANCHORED, 0, TRUE); + TEST_MATCH_SIMPLE("a", "ab", 0, G_REGEX_MATCH_ANCHORED, TRUE); + TEST_MATCH_SIMPLE("a", "a", G_REGEX_CASELESS, 0, TRUE); + TEST_MATCH_SIMPLE("a", "A", G_REGEX_CASELESS, 0, TRUE); + /* These are needed to test extended properties. */ + TEST_MATCH_SIMPLE(AGRAVE, AGRAVE, G_REGEX_CASELESS, 0, TRUE); + TEST_MATCH_SIMPLE(AGRAVE, AGRAVE_UPPER, G_REGEX_CASELESS, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{L}", "a", 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{L}", "1", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{L}", AGRAVE, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{L}", AGRAVE_UPPER, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{L}", SHEEN, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{L}", ETH30, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Ll}", "a", 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Ll}", AGRAVE, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Ll}", AGRAVE_UPPER, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Ll}", ETH30, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Sc}", AGRAVE, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Sc}", EURO, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Sc}", ETH30, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{N}", "a", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{N}", "1", 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{N}", AGRAVE, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{N}", AGRAVE_UPPER, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{N}", SHEEN, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{N}", ETH30, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Nd}", "a", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Nd}", "1", 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Nd}", AGRAVE, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Nd}", AGRAVE_UPPER, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Nd}", SHEEN, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Nd}", ETH30, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Common}", SHEEN, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Common}", "a", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Common}", AGRAVE, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Common}", AGRAVE_UPPER, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Common}", ETH30, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Common}", "%", 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Common}", "1", 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Arabic}", SHEEN, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Arabic}", "a", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Arabic}", AGRAVE, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Arabic}", AGRAVE_UPPER, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Arabic}", ETH30, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Arabic}", "%", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Arabic}", "1", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Latin}", SHEEN, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Latin}", "a", 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Latin}", AGRAVE, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Latin}", AGRAVE_UPPER, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Latin}", ETH30, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Latin}", "%", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Latin}", "1", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Ethiopic}", SHEEN, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Ethiopic}", "a", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Ethiopic}", AGRAVE, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Ethiopic}", AGRAVE_UPPER, 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Ethiopic}", ETH30, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{Ethiopic}", "%", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{Ethiopic}", "1", 0, 0, FALSE); + TEST_MATCH_SIMPLE("\\p{L}(?<=\\p{Arabic})", SHEEN, 0, 0, TRUE); + TEST_MATCH_SIMPLE("\\p{L}(?<=\\p{Latin})", SHEEN, 0, 0, FALSE); + /* Invalid patterns. */ + TEST_MATCH_SIMPLE("\\", "a", 0, 0, FALSE); + TEST_MATCH_SIMPLE("[", "", 0, 0, FALSE); + + /* TEST_MATCH(pattern, compile_opts, match_opts, string, + * string_len, start_position, match_opts2, expected) */ + TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE); + TEST_MATCH("a", 0, 0, "A", -1, 0, 0, FALSE); + TEST_MATCH("a", G_REGEX_CASELESS, 0, "A", -1, 0, 0, TRUE); + TEST_MATCH("a", 0, 0, "ab", -1, 1, 0, FALSE); + TEST_MATCH("a", 0, 0, "ba", 1, 0, 0, FALSE); + TEST_MATCH("a", 0, 0, "bab", -1, 0, 0, TRUE); + TEST_MATCH("a", 0, 0, "b", -1, 0, 0, FALSE); + TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "a", -1, 0, 0, TRUE); + TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "ab", -1, 1, 0, FALSE); + TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "ba", 1, 0, 0, FALSE); + TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "bab", -1, 0, 0, FALSE); + TEST_MATCH("a", 0, G_REGEX_MATCH_ANCHORED, "b", -1, 0, 0, FALSE); + TEST_MATCH("a", 0, 0, "a", -1, 0, G_REGEX_MATCH_ANCHORED, TRUE); + TEST_MATCH("a", 0, 0, "ab", -1, 1, G_REGEX_MATCH_ANCHORED, FALSE); + TEST_MATCH("a", 0, 0, "ba", 1, 0, G_REGEX_MATCH_ANCHORED, FALSE); + TEST_MATCH("a", 0, 0, "bab", -1, 0, G_REGEX_MATCH_ANCHORED, FALSE); + TEST_MATCH("a", 0, 0, "b", -1, 0, G_REGEX_MATCH_ANCHORED, FALSE); + TEST_MATCH("a|b", 0, 0, "a", -1, 0, 0, TRUE); + TEST_MATCH("\\d", 0, 0, EURO, -1, 0, 0, FALSE); + TEST_MATCH("^.$", 0, 0, EURO, -1, 0, 0, TRUE); + TEST_MATCH("^.{3}$", 0, 0, EURO, -1, 0, 0, FALSE); + TEST_MATCH("^.$", G_REGEX_RAW, 0, EURO, -1, 0, 0, FALSE); + TEST_MATCH("^.{3}$", G_REGEX_RAW, 0, EURO, -1, 0, 0, TRUE); + TEST_MATCH(AGRAVE, G_REGEX_CASELESS, 0, AGRAVE_UPPER, -1, 0, 0, TRUE); + + /* New lines handling. */ + TEST_MATCH("^a\\Rb$", 0, 0, "a\r\nb", -1, 0, 0, TRUE); + TEST_MATCH("^a\\Rb$", 0, 0, "a\nb", -1, 0, 0, TRUE); + TEST_MATCH("^a\\Rb$", 0, 0, "a\rb", -1, 0, 0, TRUE); + TEST_MATCH("^a\\Rb$", 0, 0, "a\n\rb", -1, 0, 0, FALSE); + TEST_MATCH("^a\\R\\Rb$", 0, 0, "a\n\rb", -1, 0, 0, TRUE); + TEST_MATCH("^a\\nb$", 0, 0, "a\r\nb", -1, 0, 0, FALSE); + TEST_MATCH("^a\\r\\nb$", 0, 0, "a\r\nb", -1, 0, 0, TRUE); + + TEST_MATCH("^b$", 0, 0, "a\nb\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\nb\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\rb\rc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\nb\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\nb\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\nb\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\rb\rc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\rb\rc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\rb\rc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\nb\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\nb\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\r\nb\r\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\r\nb\r\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\rb\rc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE); + + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\nb\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\rb\rc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\r\nb\r\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE); + + TEST_MATCH("a#\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); + TEST_MATCH("a#\r\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); + TEST_MATCH("a#\rb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); + TEST_MATCH("a#\nb", G_REGEX_EXTENDED, G_REGEX_MATCH_NEWLINE_CR, "a", -1, 0, 0, FALSE); + TEST_MATCH("a#\nb", G_REGEX_EXTENDED | G_REGEX_NEWLINE_CR, 0, "a", -1, 0, 0, TRUE); + + TEST_MATCH("line\nbreak", G_REGEX_MULTILINE, 0, "this is a line\nbreak", -1, 0, 0, TRUE); + TEST_MATCH("line\nbreak", G_REGEX_MULTILINE | G_REGEX_FIRSTLINE, 0, "first line\na line\nbreak", -1, 0, 0, FALSE); + + /* This failed with PCRE 7.2 (gnome bug #455640) */ + TEST_MATCH(".*$", 0, 0, "\xe1\xbb\x85", -1, 0, 0, TRUE); + + /* Test that othercasing in our pcre/glib integration is bug-for-bug compatible + * with pcre's internal tables. Bug #678273 */ + TEST_MATCH("[Ç„]", G_REGEX_CASELESS, 0, "Ç„", -1, 0, 0, TRUE); + TEST_MATCH("[Ç„]", G_REGEX_CASELESS, 0, "dž", -1, 0, 0, TRUE); +#if PCRE_MAJOR > 8 || (PCRE_MAJOR == 8 && PCRE_MINOR >= 32) + /* This would incorrectly fail to match in pcre < 8.32, so only assert + * this for known-good pcre. */ + TEST_MATCH("[Ç„]", G_REGEX_CASELESS, 0, "Ç…", -1, 0, 0, TRUE); +#endif + + /* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */ + TEST_MATCH_NEXT0("a", "x", -1, 0); + TEST_MATCH_NEXT0("a", "ax", -1, 1); + TEST_MATCH_NEXT0("a", "xa", 1, 0); + TEST_MATCH_NEXT0("a", "axa", 1, 2); + TEST_MATCH_NEXT1("a", "a", -1, 0, "a", 0, 1); + TEST_MATCH_NEXT1("a", "xax", -1, 0, "a", 1, 2); + TEST_MATCH_NEXT1(EURO, ENG EURO, -1, 0, EURO, 2, 5); + TEST_MATCH_NEXT1("a*", "", -1, 0, "", 0, 0); + TEST_MATCH_NEXT2("a*", "aa", -1, 0, "aa", 0, 2, "", 2, 2); + TEST_MATCH_NEXT2(EURO "*", EURO EURO, -1, 0, EURO EURO, 0, 6, "", 6, 6); + TEST_MATCH_NEXT2("a", "axa", -1, 0, "a", 0, 1, "a", 2, 3); + TEST_MATCH_NEXT2("a+", "aaxa", -1, 0, "aa", 0, 2, "a", 3, 4); + TEST_MATCH_NEXT2("a", "aa", -1, 0, "a", 0, 1, "a", 1, 2); + TEST_MATCH_NEXT2("a", "ababa", -1, 2, "a", 2, 3, "a", 4, 5); + TEST_MATCH_NEXT2(EURO "+", EURO "-" EURO, -1, 0, EURO, 0, 3, EURO, 4, 7); + TEST_MATCH_NEXT3("", "ab", -1, 0, "", 0, 0, "", 1, 1, "", 2, 2); + TEST_MATCH_NEXT3("", AGRAVE "b", -1, 0, "", 0, 0, "", 2, 2, "", 3, 3); + TEST_MATCH_NEXT3("a", "aaxa", -1, 0, "a", 0, 1, "a", 1, 2, "a", 3, 4); + TEST_MATCH_NEXT3("a", "aa" OGRAVE "a", -1, 0, "a", 0, 1, "a", 1, 2, "a", 4, 5); + TEST_MATCH_NEXT3("a*", "aax", -1, 0, "aa", 0, 2, "", 2, 2, "", 3, 3); + TEST_MATCH_NEXT3("(?=[A-Z0-9])", "RegExTest", -1, 0, "", 0, 0, "", 3, 3, "", 5, 5); + TEST_MATCH_NEXT4("a*", "aaxa", -1, 0, "aa", 0, 2, "", 2, 2, "a", 3, 4, "", 4, 4); + + /* TEST_MATCH_COUNT(pattern, string, start_position, match_opts, expected_count) */ + TEST_MATCH_COUNT("a", "", 0, 0, 0); + TEST_MATCH_COUNT("a", "a", 0, 0, 1); + TEST_MATCH_COUNT("a", "a", 1, 0, 0); + TEST_MATCH_COUNT("(.)", "a", 0, 0, 2); + TEST_MATCH_COUNT("(.)", EURO, 0, 0, 2); + TEST_MATCH_COUNT("(?:.)", "a", 0, 0, 1); + TEST_MATCH_COUNT("(?P.)", "a", 0, 0, 2); + TEST_MATCH_COUNT("a$", "a", 0, G_REGEX_MATCH_NOTEOL, 0); + TEST_MATCH_COUNT("(a)?(b)", "b", 0, 0, 3); + TEST_MATCH_COUNT("(a)?(b)", "ab", 0, 0, 3); + + /* TEST_PARTIAL(pattern, string, expected) */ + TEST_PARTIAL("^ab", "a", TRUE); + TEST_PARTIAL("^ab", "xa", FALSE); + TEST_PARTIAL("ab", "xa", TRUE); + TEST_PARTIAL("ab", "ab", FALSE); /* normal match. */ + TEST_PARTIAL("a+b", "aa", TRUE); + TEST_PARTIAL("(a)+b", "aa", TRUE); + TEST_PARTIAL("a?b", "a", TRUE); + + /* Test soft vs. hard partial matching */ + TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_MATCH_PARTIAL_SOFT, FALSE); + TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_MATCH_PARTIAL_HARD, TRUE); + + /* TEST_SUB_PATTERN(pattern, string, start_position, sub_n, expected_sub, + * expected_start, expected_end) */ + TEST_SUB_PATTERN("a", "a", 0, 0, "a", 0, 1); + TEST_SUB_PATTERN("a(.)", "ab", 0, 1, "b", 1, 2); + TEST_SUB_PATTERN("a(.)", "a" EURO, 0, 1, EURO, 1, 4); + TEST_SUB_PATTERN("(?:.*)(a)(.)", "xxa" ENG, 0, 2, ENG, 3, 5); + TEST_SUB_PATTERN("(" HSTROKE ")", "a" HSTROKE ENG, 0, 1, HSTROKE, 1, 3); + TEST_SUB_PATTERN("a", "a", 0, 1, NULL, UNTOUCHED, UNTOUCHED); + TEST_SUB_PATTERN("a", "a", 0, 1, NULL, UNTOUCHED, UNTOUCHED); + TEST_SUB_PATTERN("(a)?(b)", "b", 0, 0, "b", 0, 1); + TEST_SUB_PATTERN("(a)?(b)", "b", 0, 1, "", -1, -1); + TEST_SUB_PATTERN("(a)?(b)", "b", 0, 2, "b", 0, 1); + TEST_SUB_PATTERN("(a)?b", "b", 0, 0, "b", 0, 1); + TEST_SUB_PATTERN("(a)?b", "b", 0, 1, "", -1, -1); + TEST_SUB_PATTERN("(a)?b", "b", 0, 2, NULL, UNTOUCHED, UNTOUCHED); + + /* TEST_NAMED_SUB_PATTERN(pattern, string, start_position, sub_name, + * expected_sub, expected_start, expected_end) */ + TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", "ab", 0, "A", "b", 1, 2); + TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", "aab", 1, "A", "b", 2, 3); + TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", EURO "ab", 0, "A", "b", 4, 5); + TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", EURO "ab", 0, "B", "", -1, -1); + TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", EURO "ab", 0, "C", NULL, UNTOUCHED, UNTOUCHED); + TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", "a" EGRAVE "x", 0, "A", EGRAVE, 1, 3); + TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", "a" EGRAVE "x", 0, "B", "x", 3, 4); + TEST_NAMED_SUB_PATTERN("(?Pa)?(?Pb)", "b", 0, "A", "", -1, -1); + TEST_NAMED_SUB_PATTERN("(?Pa)?(?Pb)", "b", 0, "B", "b", 0, 1); + + /* TEST_NAMED_SUB_PATTERN_DUPNAMES(pattern, string, start_position, sub_name, + * expected_sub, expected_start, expected_end) */ + TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Pa)|(?Pb)", "ab", 0, "N", "a", 0, 1); + TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Paa)|(?Pa)", "aa", 0, "N", "aa", 0, 2); + TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Paa)(?Pa)", "aaa", 0, "N", "aa", 0, 2); + TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Px)|(?Pa)", "a", 0, "N", "a", 0, 1); + TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Px)y|(?Pa)b", "ab", 0, "N", "a", 0, 1); + + /* DUPNAMES option inside the pattern */ + TEST_NAMED_SUB_PATTERN("(?J)(?Pa)|(?Pb)", "ab", 0, "N", "a", 0, 1); + TEST_NAMED_SUB_PATTERN("(?J)(?Paa)|(?Pa)", "aa", 0, "N", "aa", 0, 2); + TEST_NAMED_SUB_PATTERN("(?J)(?Paa)(?Pa)", "aaa", 0, "N", "aa", 0, 2); + TEST_NAMED_SUB_PATTERN("(?J)(?Px)|(?Pa)", "a", 0, "N", "a", 0, 1); + TEST_NAMED_SUB_PATTERN("(?J)(?Px)y|(?Pa)b", "ab", 0, "N", "a", 0, 1); + + /* TEST_FETCH_ALL#(pattern, string, ...) */ + TEST_FETCH_ALL0("a", ""); + TEST_FETCH_ALL0("a", "b"); + TEST_FETCH_ALL1("a", "a", "a"); + TEST_FETCH_ALL1("a+", "aa", "aa"); + TEST_FETCH_ALL1("(?:a)", "a", "a"); + TEST_FETCH_ALL2("(a)", "a", "a", "a"); + TEST_FETCH_ALL2("a(.)", "ab", "ab", "b"); + TEST_FETCH_ALL2("a(.)", "a" HSTROKE, "a" HSTROKE, HSTROKE); + TEST_FETCH_ALL3("(?:.*)(a)(.)", "xyazk", "xyaz", "a", "z"); + TEST_FETCH_ALL3("(?P.)(a)", "xa", "xa", "x", "a"); + TEST_FETCH_ALL3("(?P.)(a)", ENG "a", ENG "a", ENG, "a"); + TEST_FETCH_ALL3("(a)?(b)", "b", "b", "", "b"); + TEST_FETCH_ALL3("(a)?(b)", "ab", "ab", "a", "b"); + + /* TEST_SPLIT_SIMPLE#(pattern, string, ...) */ + TEST_SPLIT_SIMPLE0("", ""); + TEST_SPLIT_SIMPLE0("a", ""); + TEST_SPLIT_SIMPLE1(",", "a", "a"); + TEST_SPLIT_SIMPLE1("(,)\\s*", "a", "a"); + TEST_SPLIT_SIMPLE2(",", "a,b", "a", "b"); + TEST_SPLIT_SIMPLE3(",", "a,b,c", "a", "b", "c"); + TEST_SPLIT_SIMPLE3(",\\s*", "a,b,c", "a", "b", "c"); + TEST_SPLIT_SIMPLE3(",\\s*", "a, b, c", "a", "b", "c"); + TEST_SPLIT_SIMPLE3("(,)\\s*", "a,b", "a", ",", "b"); + TEST_SPLIT_SIMPLE3("(,)\\s*", "a, b", "a", ",", "b"); + TEST_SPLIT_SIMPLE2("\\s", "ab c", "ab", "c"); + TEST_SPLIT_SIMPLE3("\\s*", "ab c", "a", "b", "c"); + /* Not matched sub-strings. */ + TEST_SPLIT_SIMPLE2("a|(b)", "xay", "x", "y"); + TEST_SPLIT_SIMPLE3("a|(b)", "xby", "x", "b", "y"); + /* Empty matches. */ + TEST_SPLIT_SIMPLE3("", "abc", "a", "b", "c"); + TEST_SPLIT_SIMPLE3(" *", "ab c", "a", "b", "c"); + /* Invalid patterns. */ + TEST_SPLIT_SIMPLE0("\\", ""); + TEST_SPLIT_SIMPLE0("[", ""); + + /* TEST_SPLIT#(pattern, string, start_position, max_tokens, ...) */ + TEST_SPLIT0("", "", 0, 0); + TEST_SPLIT0("a", "", 0, 0); + TEST_SPLIT0("a", "", 0, 1); + TEST_SPLIT0("a", "", 0, 2); + TEST_SPLIT0("a", "a", 1, 0); + TEST_SPLIT1(",", "a", 0, 0, "a"); + TEST_SPLIT1(",", "a,b", 0, 1, "a,b"); + TEST_SPLIT1("(,)\\s*", "a", 0, 0, "a"); + TEST_SPLIT1(",", "a,b", 2, 0, "b"); + TEST_SPLIT2(",", "a,b", 0, 0, "a", "b"); + TEST_SPLIT2(",", "a,b,c", 0, 2, "a", "b,c"); + TEST_SPLIT2(",", "a,b", 1, 0, "", "b"); + TEST_SPLIT2(",", "a,", 0, 0, "a", ""); + TEST_SPLIT3(",", "a,b,c", 0, 0, "a", "b", "c"); + TEST_SPLIT3(",\\s*", "a,b,c", 0, 0, "a", "b", "c"); + TEST_SPLIT3(",\\s*", "a, b, c", 0, 0, "a", "b", "c"); + TEST_SPLIT3("(,)\\s*", "a,b", 0, 0, "a", ",", "b"); + TEST_SPLIT3("(,)\\s*", "a, b", 0, 0, "a", ",", "b"); + /* Not matched sub-strings. */ + TEST_SPLIT2("a|(b)", "xay", 0, 0, "x", "y"); + TEST_SPLIT3("a|(b)", "xby", 0, -1, "x", "b", "y"); + /* Empty matches. */ + TEST_SPLIT2(" *", "ab c", 1, 0, "b", "c"); + TEST_SPLIT3("", "abc", 0, 0, "a", "b", "c"); + TEST_SPLIT3(" *", "ab c", 0, 0, "a", "b", "c"); + TEST_SPLIT1(" *", "ab c", 0, 1, "ab c"); + TEST_SPLIT2(" *", "ab c", 0, 2, "a", "b c"); + TEST_SPLIT3(" *", "ab c", 0, 3, "a", "b", "c"); + TEST_SPLIT3(" *", "ab c", 0, 4, "a", "b", "c"); + + /* TEST_CHECK_REPLACEMENT(string_to_expand, expected, expected_refs) */ + TEST_CHECK_REPLACEMENT("", TRUE, FALSE); + TEST_CHECK_REPLACEMENT("a", TRUE, FALSE); + TEST_CHECK_REPLACEMENT("\\t\\n\\v\\r\\f\\a\\b\\\\\\x{61}", TRUE, FALSE); + TEST_CHECK_REPLACEMENT("\\0", TRUE, TRUE); + TEST_CHECK_REPLACEMENT("\\n\\2", TRUE, TRUE); + TEST_CHECK_REPLACEMENT("\\g", TRUE, TRUE); + /* Invalid strings */ + TEST_CHECK_REPLACEMENT("\\Q", FALSE, FALSE); + TEST_CHECK_REPLACEMENT("x\\Ay", FALSE, FALSE); + + /* TEST_EXPAND(pattern, string, string_to_expand, raw, expected) */ + TEST_EXPAND("a", "a", "", FALSE, ""); + TEST_EXPAND("a", "a", "\\0", FALSE, "a"); + TEST_EXPAND("a", "a", "\\1", FALSE, ""); + TEST_EXPAND("(a)", "ab", "\\1", FALSE, "a"); + TEST_EXPAND("(a)", "a", "\\1", FALSE, "a"); + TEST_EXPAND("(a)", "a", "\\g<1>", FALSE, "a"); + TEST_EXPAND("a", "a", "\\0130", FALSE, "X"); + TEST_EXPAND("a", "a", "\\\\\\0", FALSE, "\\a"); + TEST_EXPAND("a(?P.)c", "xabcy", "X\\gX", FALSE, "XbX"); +#if !(PCRE_MAJOR > 8 || (PCRE_MAJOR == 8 && PCRE_MINOR >= 34)) + /* PCRE >= 8.34 no longer allows this usage. */ + TEST_EXPAND("(.)(?P<1>.)", "ab", "\\1", FALSE, "a"); + TEST_EXPAND("(.)(?P<1>.)", "ab", "\\g<1>", FALSE, "a"); +#endif + TEST_EXPAND(".", EURO, "\\0", FALSE, EURO); + TEST_EXPAND("(.)", EURO, "\\1", FALSE, EURO); + TEST_EXPAND("(?P.)", EURO, "\\g", FALSE, EURO); + TEST_EXPAND(".", "a", EURO, FALSE, EURO); + TEST_EXPAND(".", "a", EURO "\\0", FALSE, EURO "a"); + TEST_EXPAND(".", "", "\\Lab\\Ec", FALSE, "abc"); + TEST_EXPAND(".", "", "\\LaB\\EC", FALSE, "abC"); + TEST_EXPAND(".", "", "\\Uab\\Ec", FALSE, "ABc"); + TEST_EXPAND(".", "", "a\\ubc", FALSE, "aBc"); + TEST_EXPAND(".", "", "a\\lbc", FALSE, "abc"); + TEST_EXPAND(".", "", "A\\uBC", FALSE, "ABC"); + TEST_EXPAND(".", "", "A\\lBC", FALSE, "AbC"); + TEST_EXPAND(".", "", "A\\l\\\\BC", FALSE, "A\\BC"); + TEST_EXPAND(".", "", "\\L" AGRAVE "\\E", FALSE, AGRAVE); + TEST_EXPAND(".", "", "\\U" AGRAVE "\\E", FALSE, AGRAVE_UPPER); + TEST_EXPAND(".", "", "\\u" AGRAVE "a", FALSE, AGRAVE_UPPER "a"); + TEST_EXPAND(".", "ab", "x\\U\\0y\\Ez", FALSE, "xAYz"); + TEST_EXPAND(".(.)", "AB", "x\\L\\1y\\Ez", FALSE, "xbyz"); + TEST_EXPAND(".", "ab", "x\\u\\0y\\Ez", FALSE, "xAyz"); + TEST_EXPAND(".(.)", "AB", "x\\l\\1y\\Ez", FALSE, "xbyz"); + TEST_EXPAND(".(.)", "a" AGRAVE_UPPER, "x\\l\\1y", FALSE, "x" AGRAVE "y"); + TEST_EXPAND("a", "bab", "\\x{61}", FALSE, "a"); + TEST_EXPAND("a", "bab", "\\x61", FALSE, "a"); + TEST_EXPAND("a", "bab", "\\x5a", FALSE, "Z"); + TEST_EXPAND("a", "bab", "\\0\\x5A", FALSE, "aZ"); + TEST_EXPAND("a", "bab", "\\1\\x{5A}", FALSE, "Z"); + TEST_EXPAND("a", "bab", "\\x{00E0}", FALSE, AGRAVE); + TEST_EXPAND("", "bab", "\\x{0634}", FALSE, SHEEN); + TEST_EXPAND("", "bab", "\\x{634}", FALSE, SHEEN); + TEST_EXPAND("", "", "\\t", FALSE, "\t"); + TEST_EXPAND("", "", "\\v", FALSE, "\v"); + TEST_EXPAND("", "", "\\r", FALSE, "\r"); + TEST_EXPAND("", "", "\\n", FALSE, "\n"); + TEST_EXPAND("", "", "\\f", FALSE, "\f"); + TEST_EXPAND("", "", "\\a", FALSE, "\a"); + TEST_EXPAND("", "", "\\b", FALSE, "\b"); + TEST_EXPAND("a(.)", "abc", "\\0\\b\\1", FALSE, "ab\bb"); + TEST_EXPAND("a(.)", "abc", "\\0141", FALSE, "a"); + TEST_EXPAND("a(.)", "abc", "\\078", FALSE, "\a8"); + TEST_EXPAND("a(.)", "abc", "\\077", FALSE, "?"); + TEST_EXPAND("a(.)", "abc", "\\0778", FALSE, "?8"); + TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\1", FALSE, AGRAVE); + TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\1", TRUE, "\xc3"); + TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\0", TRUE, "a\xc3"); + /* Invalid strings. */ + TEST_EXPAND("", "", "\\Q", FALSE, NULL); + TEST_EXPAND("", "", "x\\Ay", FALSE, NULL); + TEST_EXPAND("", "", "\\g<", FALSE, NULL); + TEST_EXPAND("", "", "\\g<>", FALSE, NULL); + TEST_EXPAND("", "", "\\g<1a>", FALSE, NULL); + TEST_EXPAND("", "", "\\g", FALSE, NULL); + TEST_EXPAND("", "", "\\", FALSE, NULL); + TEST_EXPAND("a", "a", "\\x{61", FALSE, NULL); + TEST_EXPAND("a", "a", "\\x6X", FALSE, NULL); + /* Pattern-less. */ + TEST_EXPAND(NULL, NULL, "", FALSE, ""); + TEST_EXPAND(NULL, NULL, "\\n", FALSE, "\n"); + /* Invalid strings */ + TEST_EXPAND(NULL, NULL, "\\Q", FALSE, NULL); + TEST_EXPAND(NULL, NULL, "x\\Ay", FALSE, NULL); + + /* TEST_REPLACE(pattern, string, start_position, replacement, expected) */ + TEST_REPLACE("a", "ababa", 0, "A", "AbAbA"); + TEST_REPLACE("a", "ababa", 1, "A", "abAbA"); + TEST_REPLACE("a", "ababa", 2, "A", "abAbA"); + TEST_REPLACE("a", "ababa", 3, "A", "ababA"); + TEST_REPLACE("a", "ababa", 4, "A", "ababA"); + TEST_REPLACE("a", "ababa", 5, "A", "ababa"); + TEST_REPLACE("a", "ababa", 6, "A", "ababa"); + TEST_REPLACE("a", "abababa", 2, "A", "abAbAbA"); + TEST_REPLACE("a", "abab", 0, "A", "AbAb"); + TEST_REPLACE("a", "baba", 0, "A", "bAbA"); + TEST_REPLACE("a", "bab", 0, "A", "bAb"); + TEST_REPLACE("$^", "abc", 0, "X", "abc"); + TEST_REPLACE("(.)a", "ciao", 0, "a\\1", "caio"); + TEST_REPLACE("a.", "abc", 0, "\\0\\0", "ababc"); + TEST_REPLACE("a", "asd", 0, "\\0101", "Asd"); + TEST_REPLACE("(a).\\1", "aba cda", 0, "\\1\\n", "a\n cda"); + TEST_REPLACE("a" AGRAVE "a", "a" AGRAVE "a", 0, "x", "x"); + TEST_REPLACE("a" AGRAVE "a", "a" AGRAVE "a", 0, OGRAVE, OGRAVE); + TEST_REPLACE("[^-]", "-" EURO "-x-" HSTROKE, 0, "a", "-a-a-a"); + TEST_REPLACE("[^-]", "-" EURO "-" HSTROKE, 0, "a\\g<0>a", "-a" EURO "a-a" HSTROKE "a"); + TEST_REPLACE("-", "-" EURO "-" HSTROKE, 0, "", EURO HSTROKE); + TEST_REPLACE(".*", "hello", 0, "\\U\\0\\E", "HELLO"); + TEST_REPLACE(".*", "hello", 0, "\\u\\0", "Hello"); + TEST_REPLACE("\\S+", "hello world", 0, "\\U-\\0-", "-HELLO- -WORLD-"); + TEST_REPLACE(".", "a", 0, "\\A", NULL); + TEST_REPLACE(".", "a", 0, "\\g", NULL); + + /* TEST_REPLACE_LIT(pattern, string, start_position, replacement, expected) */ + TEST_REPLACE_LIT("a", "ababa", 0, "A", "AbAbA"); + TEST_REPLACE_LIT("a", "ababa", 1, "A", "abAbA"); + TEST_REPLACE_LIT("a", "ababa", 2, "A", "abAbA"); + TEST_REPLACE_LIT("a", "ababa", 3, "A", "ababA"); + TEST_REPLACE_LIT("a", "ababa", 4, "A", "ababA"); + TEST_REPLACE_LIT("a", "ababa", 5, "A", "ababa"); + TEST_REPLACE_LIT("a", "ababa", 6, "A", "ababa"); + TEST_REPLACE_LIT("a", "abababa", 2, "A", "abAbAbA"); + TEST_REPLACE_LIT("a", "abcadaa", 0, "A", "AbcAdAA"); + TEST_REPLACE_LIT("$^", "abc", 0, "X", "abc"); + TEST_REPLACE_LIT("(.)a", "ciao", 0, "a\\1", "ca\\1o"); + TEST_REPLACE_LIT("a.", "abc", 0, "\\0\\0\\n", "\\0\\0\\nc"); + TEST_REPLACE_LIT("a" AGRAVE "a", "a" AGRAVE "a", 0, "x", "x"); + TEST_REPLACE_LIT("a" AGRAVE "a", "a" AGRAVE "a", 0, OGRAVE, OGRAVE); + TEST_REPLACE_LIT(AGRAVE, "-" AGRAVE "-" HSTROKE, 0, "a" ENG "a", "-a" ENG "a-" HSTROKE); + TEST_REPLACE_LIT("[^-]", "-" EURO "-" AGRAVE "-" HSTROKE, 0, "a", "-a-a-a"); + TEST_REPLACE_LIT("[^-]", "-" EURO "-" AGRAVE, 0, "a\\g<0>a", "-a\\g<0>a-a\\g<0>a"); + TEST_REPLACE_LIT("-", "-" EURO "-" AGRAVE "-" HSTROKE, 0, "", EURO AGRAVE HSTROKE); + TEST_REPLACE_LIT("(?=[A-Z0-9])", "RegExTest", 0, "_", "_Reg_Ex_Test"); + TEST_REPLACE_LIT("(?=[A-Z0-9])", "RegExTest", 1, "_", "Reg_Ex_Test"); + + /* TEST_GET_STRING_NUMBER(pattern, name, expected_num) */ + TEST_GET_STRING_NUMBER("", "A", -1); + TEST_GET_STRING_NUMBER("(?P.)", "A", 1); + TEST_GET_STRING_NUMBER("(?P.)", "B", -1); + TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "A", 1); + TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "B", 2); + TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "C", -1); + TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "A", 1); + TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "B", 3); + TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "C", -1); + TEST_GET_STRING_NUMBER("(?:a)(?P.)", "A", 1); + TEST_GET_STRING_NUMBER("(?:a)(?P.)", "B", -1); + + /* TEST_ESCAPE_NUL(string, length, expected) */ + TEST_ESCAPE_NUL("hello world", -1, "hello world"); + TEST_ESCAPE_NUL("hello\0world", -1, "hello"); + TEST_ESCAPE_NUL("\0world", -1, ""); + TEST_ESCAPE_NUL("hello world", 5, "hello"); + TEST_ESCAPE_NUL("hello.world", 11, "hello.world"); + TEST_ESCAPE_NUL("a(b\\b.$", 7, "a(b\\b.$"); + TEST_ESCAPE_NUL("hello\0", 6, "hello\\x00"); + TEST_ESCAPE_NUL("\0world", 6, "\\x00world"); + TEST_ESCAPE_NUL("\0\0", 2, "\\x00\\x00"); + TEST_ESCAPE_NUL("hello\0world", 11, "hello\\x00world"); + TEST_ESCAPE_NUL("hello\0world\0", 12, "hello\\x00world\\x00"); + TEST_ESCAPE_NUL("hello\\\0world", 12, "hello\\x00world"); + TEST_ESCAPE_NUL("hello\\\\\0world", 13, "hello\\\\\\x00world"); + TEST_ESCAPE_NUL("|()[]{}^$*+?.", 13, "|()[]{}^$*+?."); + TEST_ESCAPE_NUL("|()[]{}^$*+?.\\\\", 15, "|()[]{}^$*+?.\\\\"); + + /* TEST_ESCAPE(string, length, expected) */ + TEST_ESCAPE("hello world", -1, "hello world"); + TEST_ESCAPE("hello world", 5, "hello"); + TEST_ESCAPE("hello.world", -1, "hello\\.world"); + TEST_ESCAPE("a(b\\b.$", -1, "a\\(b\\\\b\\.\\$"); + TEST_ESCAPE("hello\0world", -1, "hello"); + TEST_ESCAPE("hello\0world", 11, "hello\\0world"); + TEST_ESCAPE(EURO "*" ENG, -1, EURO "\\*" ENG); + TEST_ESCAPE("a$", -1, "a\\$"); + TEST_ESCAPE("$a", -1, "\\$a"); + TEST_ESCAPE("a$a", -1, "a\\$a"); + TEST_ESCAPE("$a$", -1, "\\$a\\$"); + TEST_ESCAPE("$a$", 0, ""); + TEST_ESCAPE("$a$", 1, "\\$"); + TEST_ESCAPE("$a$", 2, "\\$a"); + TEST_ESCAPE("$a$", 3, "\\$a\\$"); + TEST_ESCAPE("$a$", 4, "\\$a\\$\\0"); + TEST_ESCAPE("|()[]{}^$*+?.", -1, "\\|\\(\\)\\[\\]\\{\\}\\^\\$\\*\\+\\?\\."); + TEST_ESCAPE("a|a(a)a[a]a{a}a^a$a*a+a?a.a", -1, + "a\\|a\\(a\\)a\\[a\\]a\\{a\\}a\\^a\\$a\\*a\\+a\\?a\\.a"); + + /* TEST_MATCH_ALL#(pattern, string, string_len, start_position, ...) */ + TEST_MATCH_ALL0("<.*>", "", -1, 0); + TEST_MATCH_ALL0("a+", "", -1, 0); + TEST_MATCH_ALL0("a+", "a", 0, 0); + TEST_MATCH_ALL0("a+", "a", -1, 1); + TEST_MATCH_ALL1("<.*>", "", -1, 0, "", 0, 3); + TEST_MATCH_ALL1("a+", "a", -1, 0, "a", 0, 1); + TEST_MATCH_ALL1("a+", "aa", 1, 0, "a", 0, 1); + TEST_MATCH_ALL1("a+", "aa", -1, 1, "a", 1, 2); + TEST_MATCH_ALL1("a+", "aa", 2, 1, "a", 1, 2); + TEST_MATCH_ALL1(".+", ENG, -1, 0, ENG, 0, 2); + TEST_MATCH_ALL2("<.*>", "", -1, 0, "", 0, 6, "", 0, 3); + TEST_MATCH_ALL2("a+", "aa", -1, 0, "aa", 0, 2, "a", 0, 1); + TEST_MATCH_ALL2(".+", ENG EURO, -1, 0, ENG EURO, 0, 5, ENG, 0, 2); + TEST_MATCH_ALL3("<.*>", "", -1, 0, "", 0, 9, + "", 0, 6, "", 0, 3); + TEST_MATCH_ALL3("a+", "aaa", -1, 0, "aaa", 0, 3, "aa", 0, 2, "a", 0, 1); + + /* NOTEMPTY matching */ + TEST_MATCH_NOTEMPTY("a?b?", "xyz", FALSE); + TEST_MATCH_NOTEMPTY_ATSTART("a?b?", "xyz", TRUE); + + return g_test_run (); +} diff --git a/glib/tests/relation.c b/glib/tests/relation.c new file mode 100644 index 0000000..f96890b --- /dev/null +++ b/glib/tests/relation.c @@ -0,0 +1,128 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include + +int array[10000]; +gboolean failed = FALSE; + +#define TEST(m,cond) G_STMT_START { failed = !(cond); \ +if (failed) \ + { if (!m) \ + g_print ("\n(%s:%d) failed for: %s\n", __FILE__, __LINE__, ( # cond )); \ + else \ + g_print ("\n(%s:%d) failed for: %s: (%s)\n", __FILE__, __LINE__, ( # cond ), (gchar*)m); \ + } \ +else \ + g_print ("."); fflush (stdout); \ +} G_STMT_END + +#define C2P(c) ((gpointer) ((long) (c))) +#define P2C(p) ((gchar) ((long) (p))) + +#define GLIB_TEST_STRING "el dorado " +#define GLIB_TEST_STRING_5 "el do" + +typedef struct { + guint age; + gchar name[40]; +} GlibTestInfo; + +static void +test_relation (void) +{ + gint i; + GRelation *relation; + GTuples *tuples; + gint data [1024]; + + relation = g_relation_new (2); + + g_relation_index (relation, 0, g_int_hash, g_int_equal); + g_relation_index (relation, 1, g_int_hash, g_int_equal); + + for (i = 0; i < 1024; i += 1) + data[i] = i; + + for (i = 1; i < 1023; i += 1) + { + g_relation_insert (relation, data + i, data + i + 1); + g_relation_insert (relation, data + i, data + i - 1); + } + + for (i = 2; i < 1022; i += 1) + { + g_assert_false (g_relation_exists (relation, data + i, data + i)); + g_assert_false (g_relation_exists (relation, data + i, data + i + 2)); + g_assert_false (g_relation_exists (relation, data + i, data + i - 2)); + } + + for (i = 1; i < 1023; i += 1) + { + g_assert_true (g_relation_exists (relation, data + i, data + i + 1)); + g_assert_true (g_relation_exists (relation, data + i, data + i - 1)); + } + + for (i = 2; i < 1022; i += 1) + { + g_assert_cmpint (g_relation_count (relation, data + i, 0), ==, 2); + g_assert_cmpint (g_relation_count (relation, data + i, 1), ==, 2); + } + + g_assert_cmpint (g_relation_count (relation, data, 0), ==, 0); + + g_assert_cmpint (g_relation_count (relation, data + 42, 0), ==, 2); + g_assert_cmpint (g_relation_count (relation, data + 43, 1), ==, 2); + g_assert_cmpint (g_relation_count (relation, data + 41, 1), ==, 2); + + g_relation_delete (relation, data + 42, 0); + + g_assert_cmpint (g_relation_count (relation, data + 42, 0), ==, 0); + g_assert_cmpint (g_relation_count (relation, data + 43, 1), ==, 1); + g_assert_cmpint (g_relation_count (relation, data + 41, 1), ==, 1); + + tuples = g_relation_select (relation, data + 200, 0); + + g_assert_cmpint (tuples->len, ==, 2); + + g_assert_true (g_relation_exists (relation, data + 300, data + 301)); + g_relation_delete (relation, data + 300, 0); + g_assert_false (g_relation_exists (relation, data + 300, data + 301)); + + g_tuples_destroy (tuples); + g_relation_destroy (relation); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/glib/relation", test_relation); + + return g_test_run (); +} diff --git a/glib/tests/rwlock.c b/glib/tests/rwlock.c new file mode 100644 index 0000000..6c0b281 --- /dev/null +++ b/glib/tests/rwlock.c @@ -0,0 +1,289 @@ +/* Unit tests for GRWLock + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +static void +test_rwlock1 (void) +{ + GRWLock lock; + + g_rw_lock_init (&lock); + g_rw_lock_writer_lock (&lock); + g_rw_lock_writer_unlock (&lock); + g_rw_lock_writer_lock (&lock); + g_rw_lock_writer_unlock (&lock); + g_rw_lock_clear (&lock); +} + +static void +test_rwlock2 (void) +{ + static GRWLock lock; + + g_rw_lock_writer_lock (&lock); + g_rw_lock_writer_unlock (&lock); + g_rw_lock_writer_lock (&lock); + g_rw_lock_writer_unlock (&lock); +} + +static void +test_rwlock3 (void) +{ + static GRWLock lock; + gboolean ret; + + ret = g_rw_lock_writer_trylock (&lock); + g_assert (ret); + ret = g_rw_lock_writer_trylock (&lock); + g_assert (!ret); + + g_rw_lock_writer_unlock (&lock); +} + +static void +test_rwlock4 (void) +{ + static GRWLock lock; + + g_rw_lock_reader_lock (&lock); + g_rw_lock_reader_unlock (&lock); + g_rw_lock_reader_lock (&lock); + g_rw_lock_reader_unlock (&lock); +} + +static void +test_rwlock5 (void) +{ + static GRWLock lock; + gboolean ret; + + ret = g_rw_lock_reader_trylock (&lock); + g_assert (ret); + ret = g_rw_lock_reader_trylock (&lock); + g_assert (ret); + + g_rw_lock_reader_unlock (&lock); + g_rw_lock_reader_unlock (&lock); +} + +static void +test_rwlock6 (void) +{ + static GRWLock lock; + gboolean ret; + + g_rw_lock_writer_lock (&lock); + ret = g_rw_lock_reader_trylock (&lock); + g_assert (!ret); + g_rw_lock_writer_unlock (&lock); + + g_rw_lock_reader_lock (&lock); + ret = g_rw_lock_writer_trylock (&lock); + g_assert (!ret); + g_rw_lock_reader_unlock (&lock); +} + + +#define LOCKS 48 +#define ITERATIONS 10000 +#define THREADS 100 + + +GThread *owners[LOCKS]; +GRWLock locks[LOCKS]; + +static void +acquire (gint nr) +{ + GThread *self; + + self = g_thread_self (); + + if (!g_rw_lock_writer_trylock (&locks[nr])) + { + if (g_test_verbose ()) + g_printerr ("thread %p going to block on lock %d\n", self, nr); + + g_rw_lock_writer_lock (&locks[nr]); + } + + g_assert (owners[nr] == NULL); /* hopefully nobody else is here */ + owners[nr] = self; + + /* let some other threads try to ruin our day */ + g_thread_yield (); + g_thread_yield (); + g_thread_yield (); + + g_assert (owners[nr] == self); /* hopefully this is still us... */ + owners[nr] = NULL; /* make way for the next guy */ + + g_rw_lock_writer_unlock (&locks[nr]); +} + +static gpointer +thread_func (gpointer data) +{ + gint i; + GRand *rand; + + rand = g_rand_new (); + + for (i = 0; i < ITERATIONS; i++) + acquire (g_rand_int_range (rand, 0, LOCKS)); + + g_rand_free (rand); + + return NULL; +} + +static void +test_rwlock7 (void) +{ + gint i; + GThread *threads[THREADS]; + + for (i = 0; i < LOCKS; i++) + g_rw_lock_init (&locks[i]); + + for (i = 0; i < THREADS; i++) + threads[i] = g_thread_new ("test", thread_func, NULL); + + for (i = 0; i < THREADS; i++) + g_thread_join (threads[i]); + + for (i = 0; i < LOCKS; i++) + g_rw_lock_clear (&locks[i]); + + for (i = 0; i < LOCKS; i++) + g_assert (owners[i] == NULL); +} + +static gint even; +static GRWLock even_lock; +GThread *writers[2]; +GThread *readers[10]; + +static void +change_even (gpointer data) +{ + g_rw_lock_writer_lock (&even_lock); + + g_assert (even % 2 == 0); + + even += 1; + + if (GPOINTER_TO_INT (data) == 0) + even += 1; + else + even -= 1; + + g_assert (even % 2 == 0); + + g_rw_lock_writer_unlock (&even_lock); +} + +static void +verify_even (gpointer data) +{ + g_rw_lock_reader_lock (&even_lock); + + g_assert (even % 2 == 0); + + g_rw_lock_reader_unlock (&even_lock); +} + +static gpointer +writer_func (gpointer data) +{ + gint i; + + for (i = 0; i < 100000; i++) + change_even (data); + + return NULL; +} + +static gpointer +reader_func (gpointer data) +{ + gint i; + + for (i = 0; i < 100000; i++) + verify_even (data); + + return NULL; +} + +/* This test has 2 writers and 10 readers. + * The writers modify an integer multiple times, + * but always leave it with an even value. + * The readers verify that they can only observe + * even values + */ +static void +test_rwlock8 (void) +{ + gint i; + + even = 0; + g_rw_lock_init (&even_lock); + + for (i = 0; i < 2; i++) + writers[i] = g_thread_new ("a", writer_func, GINT_TO_POINTER (i)); + + for (i = 0; i < 10; i++) + readers[i] = g_thread_new ("b", reader_func, NULL); + + for (i = 0; i < 2; i++) + g_thread_join (writers[i]); + + for (i = 0; i < 10; i++) + g_thread_join (readers[i]); + + g_assert (even % 2 == 0); + + g_rw_lock_clear (&even_lock); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/thread/rwlock1", test_rwlock1); + g_test_add_func ("/thread/rwlock2", test_rwlock2); + g_test_add_func ("/thread/rwlock3", test_rwlock3); + g_test_add_func ("/thread/rwlock4", test_rwlock4); + g_test_add_func ("/thread/rwlock5", test_rwlock5); + g_test_add_func ("/thread/rwlock6", test_rwlock6); + g_test_add_func ("/thread/rwlock7", test_rwlock7); + g_test_add_func ("/thread/rwlock8", test_rwlock8); + + return g_test_run (); +} diff --git a/glib/tests/scannerapi.c b/glib/tests/scannerapi.c new file mode 100644 index 0000000..6813184 --- /dev/null +++ b/glib/tests/scannerapi.c @@ -0,0 +1,142 @@ +/* Gtk+ object tests + * Copyright (C) 2007 Patrick Hulin + * Copyright (C) 2007 Imendio AB + * Authors: Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#include +#include +#include + + +/* GScanner fixture */ +typedef struct { + GScanner *scanner; +} ScannerFixture; +static void +scanner_fixture_setup (ScannerFixture *fix, + gconstpointer test_data) +{ + fix->scanner = g_scanner_new (NULL); + g_assert (fix->scanner != NULL); +} +static void +scanner_fixture_teardown (ScannerFixture *fix, + gconstpointer test_data) +{ + g_assert (fix->scanner != NULL); + g_scanner_destroy (fix->scanner); +} + +static void +scanner_msg_func (GScanner *scanner, + gchar *message, + gboolean error) +{ + g_assert_cmpstr (message, ==, "test"); +} + +static void +test_scanner_warn (ScannerFixture *fix, + gconstpointer test_data) +{ + fix->scanner->msg_handler = scanner_msg_func; + g_scanner_warn (fix->scanner, "test"); +} + +static void +test_scanner_error (ScannerFixture *fix, + gconstpointer test_data) +{ + if (g_test_subprocess ()) + { + int pe = fix->scanner->parse_errors; + g_scanner_error (fix->scanner, "scanner-error-message-test"); + g_assert_cmpint (fix->scanner->parse_errors, ==, pe + 1); + exit (0); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*scanner-error-message-test*"); +} + +static void +check_keys (gpointer key, + gpointer value, + gpointer user_data) +{ + g_assert_cmpint (GPOINTER_TO_INT (value), ==, g_ascii_strtoull (key, NULL, 0)); +} + +static void +test_scanner_symbols (ScannerFixture *fix, + gconstpointer test_data) +{ + gint i; + gchar buf[2]; + + g_scanner_set_scope (fix->scanner, 1); + + for (i = 0; i < 10; i++) + g_scanner_scope_add_symbol (fix->scanner, + 1, + g_ascii_dtostr (buf, 2, (gdouble)i), + GINT_TO_POINTER (i)); + g_scanner_scope_foreach_symbol (fix->scanner, 1, check_keys, NULL); + g_assert_cmpint (GPOINTER_TO_INT (g_scanner_lookup_symbol (fix->scanner, "5")), ==, 5); + g_scanner_scope_remove_symbol (fix->scanner, 1, "5"); + g_assert (g_scanner_lookup_symbol (fix->scanner, "5") == NULL); + + g_assert_cmpint (GPOINTER_TO_INT (g_scanner_scope_lookup_symbol (fix->scanner, 1, "4")), ==, 4); + g_assert_cmpint (GPOINTER_TO_INT (g_scanner_scope_lookup_symbol (fix->scanner, 1, "5")), ==, 0); +} + +static void +test_scanner_tokens (ScannerFixture *fix, + gconstpointer test_data) +{ + gchar buf[] = "(\t\n\r\\){}"; + const gint buflen = strlen (buf); + gchar tokbuf[] = "(\\){}"; + const gsize tokbuflen = strlen (tokbuf); + gsize i; + + g_scanner_input_text (fix->scanner, buf, buflen); + + g_assert_cmpint (g_scanner_cur_token (fix->scanner), ==, G_TOKEN_NONE); + g_scanner_get_next_token (fix->scanner); + g_assert_cmpint (g_scanner_cur_token (fix->scanner), ==, tokbuf[0]); + g_assert_cmpint (g_scanner_cur_line (fix->scanner), ==, 1); + + for (i = 1; i < tokbuflen; i++) + g_assert_cmpint (g_scanner_get_next_token (fix->scanner), ==, tokbuf[i]); + g_assert_cmpint (g_scanner_get_next_token (fix->scanner), ==, G_TOKEN_EOF); + return; +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add ("/scanner/warn", ScannerFixture, 0, scanner_fixture_setup, test_scanner_warn, scanner_fixture_teardown); + g_test_add ("/scanner/error", ScannerFixture, 0, scanner_fixture_setup, test_scanner_error, scanner_fixture_teardown); + g_test_add ("/scanner/symbols", ScannerFixture, 0, scanner_fixture_setup, test_scanner_symbols, scanner_fixture_teardown); + g_test_add ("/scanner/tokens", ScannerFixture, 0, scanner_fixture_setup, test_scanner_tokens, scanner_fixture_teardown); + + return g_test_run(); +} diff --git a/glib/tests/search-utils.c b/glib/tests/search-utils.c new file mode 100644 index 0000000..cbe5bed --- /dev/null +++ b/glib/tests/search-utils.c @@ -0,0 +1,126 @@ +#include "config.h" + +#include +#include + +typedef struct +{ + const gchar *string; + const gchar *prefix; + const gchar *locale; + gboolean should_match; +} SearchTest; + +/* Test word separators and case */ +SearchTest basic[] = { + { "Hello World", "he", "C", TRUE }, + { "Hello World", "wo", "C", TRUE }, + { "Hello World", "lo", "C", FALSE }, + { "Hello World", "ld", "C", FALSE }, + { "Hello-World", "wo", "C", TRUE }, + { "HelloWorld", "wo", "C", FALSE }, + { NULL, NULL, NULL, FALSE } +}; + +/* Test composed chars (accentued letters) */ +SearchTest composed[] = { + { "Jörgen", "jor", "sv_SE.UTF-8", TRUE }, + { "Gaëtan", "gaetan", "fr_FR.UTF-8", TRUE }, + { "élève", "ele", "fr_FR.UTF-8", TRUE }, + { "Azais", "AzaÃs", "fr_FR.UTF-8", FALSE }, + { "AzaÃs", "Azais", "fr_FR.UTF-8", TRUE }, + { NULL, NULL, NULL, FALSE } +}; + +/* Test decomposed chars, they looks the same, but are actually + * composed of multiple unicodes */ +SearchTest decomposed[] = { + { "Jorgen", "Jör", "sv_SE.UTF-8", FALSE }, + { "Jörgen", "jor", "sv_SE.UTF-8", TRUE }, + { NULL, NULL, NULL, FALSE } +}; + +/* Turkish special case */ +SearchTest turkish[] = { + { "İstanbul", "ist", "tr_TR.UTF-8", TRUE }, + { "Diyarbakır", "diyarbakir", "tr_TR.UTF-8", TRUE }, + { NULL, NULL, NULL, FALSE } +}; + +/* Test unicode chars when no locale is available */ +SearchTest c_locale_unicode[] = { + { "Jörgen", "jor", "C", TRUE }, + { "Jorgen", "Jör", "C", FALSE }, + { "Jörgen", "jor", "C", TRUE }, + { NULL, NULL, NULL, FALSE } +}; + +/* Multi words */ +SearchTest multi_words[] = { + { "Xavier Claessens", "Xav Cla", "C", TRUE }, + { "Xavier Claessens", "Cla Xav", "C", TRUE }, + { "Foo Bar Baz", " b ", "C", TRUE }, + { "Foo Bar Baz", "bar bazz", "C", FALSE }, + { NULL, NULL, NULL, FALSE } +}; + +static void +test_search (gconstpointer d) +{ + const SearchTest *tests = d; + guint i; + gboolean all_skipped = TRUE; + + g_debug ("Started"); + + for (i = 0; tests[i].string != NULL; i++) + { + gboolean match; + gboolean ok = FALSE; + gboolean skipped; + + if (setlocale (LC_ALL, tests[i].locale)) + { + skipped = FALSE; + all_skipped = FALSE; + match = g_str_match_string (tests[i].prefix, tests[i].string, TRUE); + ok = (match == tests[i].should_match); + } + else + { + skipped = TRUE; + g_test_message ("Locale '%s' is unavailable", tests[i].locale); + } + + g_debug ("'%s' - '%s' %s: %s", tests[i].prefix, tests[i].string, + tests[i].should_match ? "should match" : "should NOT match", + skipped ? "SKIPPED" : ok ? "OK" : "FAILED"); + + g_assert (skipped || ok); + } + + if (all_skipped) + g_test_skip ("No locales for the test set are available"); +} + +int +main (int argc, + char **argv) +{ + gchar *user_locale; + + g_test_init (&argc, &argv, NULL); + + setlocale (LC_ALL, ""); + user_locale = setlocale (LC_ALL, NULL); + g_debug ("Current user locale: %s", user_locale); + + g_test_add_data_func ("/search/basic", basic, test_search); + g_test_add_data_func ("/search/composed", composed, test_search); + g_test_add_data_func ("/search/decomposed", decomposed, test_search); + g_test_add_data_func ("/search/turkish", turkish, test_search); + g_test_add_data_func ("/search/c_locale_unicode", c_locale_unicode, test_search); + g_test_add_data_func ("/search/multi_words", multi_words, test_search); + + return g_test_run (); +} diff --git a/glib/tests/sequence.c b/glib/tests/sequence.c new file mode 100644 index 0000000..842bc54 --- /dev/null +++ b/glib/tests/sequence.c @@ -0,0 +1,1402 @@ +#include +#include +#include + +/* Keep this in sync with gsequence.c !!! */ +typedef struct _GSequenceNode GSequenceNode; + +struct _GSequence +{ + GSequenceNode * end_node; + GDestroyNotify data_destroy_notify; + gboolean access_prohibited; + GSequence * real_sequence; +}; + +struct _GSequenceNode +{ + gint n_nodes; + guint32 priority; + GSequenceNode * parent; + GSequenceNode * left; + GSequenceNode * right; + gpointer data; +}; + +static guint +get_priority (GSequenceNode *node) +{ + guint key = node->priority; + + /* We rely on 0 being less than all other priorities */ + return key? key : 1; +} + +static void +check_node (GSequenceNode *node) +{ + if (node) + { + g_assert (node->parent != node); + if (node->parent) + g_assert (node->parent->left == node || node->parent->right == node); + g_assert (node->n_nodes == 1 + (node->left ? node->left->n_nodes : 0) + (node->right ? node->right->n_nodes : 0)); + if (node->left) + g_assert (get_priority (node) >= get_priority (node->left)); + if (node->right) + g_assert (get_priority (node) >= get_priority (node->right)); + check_node (node->left); + check_node (node->right); + } +} + +static void +g_sequence_check (GSequence *seq) +{ + GSequenceNode *node = seq->end_node; + + while (node->parent) + node = node->parent; + + check_node (node); + + while (node->right) + node = node->right; + + g_assert (seq->end_node == node); + g_assert (node->data == seq); + +} + + +enum { + NEW, FREE, GET_LENGTH, FOREACH, FOREACH_RANGE, SORT, SORT_ITER, + + /* Getting iters */ + GET_BEGIN_ITER, GET_END_ITER, GET_ITER_AT_POS, APPEND, PREPEND, + INSERT_BEFORE, MOVE, SWAP, INSERT_SORTED, INSERT_SORTED_ITER, SORT_CHANGED, + SORT_CHANGED_ITER, REMOVE, REMOVE_RANGE, MOVE_RANGE, SEARCH, SEARCH_ITER, + LOOKUP, LOOKUP_ITER, + + /* dereferencing */ + GET, SET, + + /* operations on GSequenceIter * */ + ITER_IS_BEGIN, ITER_IS_END, ITER_NEXT, ITER_PREV, ITER_GET_POSITION, + ITER_MOVE, ITER_GET_SEQUENCE, + + /* search */ + ITER_COMPARE, RANGE_GET_MIDPOINT, + N_OPS +}; + +typedef struct SequenceInfo +{ + GQueue * queue; + GSequence * sequence; + guint n_items; +} SequenceInfo; + +typedef struct +{ + SequenceInfo *seq; + int number; +} Item; + +void g_sequence_check (GSequence *sequence); + +static Item * +fix_pointer (gconstpointer data) +{ + return (Item *)((char *)data - 1); +} + +static Item * +get_item (GSequenceIter *iter) +{ + return fix_pointer (g_sequence_get (iter)); +} + +static void +check_integrity (SequenceInfo *info) +{ + GList *list; + GSequenceIter *iter; + int i; + + g_sequence_check (info->sequence); + +#if 0 + if (g_sequence_get_length (info->sequence) != info->n_items) + g_printerr ("%d %d\n", + g_sequence_get_length (info->sequence), info->n_items); +#endif + g_assert (info->n_items == g_queue_get_length (info->queue)); + g_assert ((guint) g_sequence_get_length (info->sequence) == info->n_items); + + iter = g_sequence_get_begin_iter (info->sequence); + list = info->queue->head; + i = 0; + while (iter != g_sequence_get_end_iter (info->sequence)) + { + Item *item; + g_assert (list->data == iter); + item = get_item (list->data); + g_assert (item->seq == info); + + iter = g_sequence_iter_next (iter); + list = list->next; + i++; + } + + g_assert (info->n_items == g_queue_get_length (info->queue)); + g_assert ((guint) g_sequence_get_length (info->sequence) == info->n_items); +} + +static gpointer +new_item (SequenceInfo *seq) +{ + Item *item = g_new (Item, 1); + seq->n_items++; + item->seq = seq; + item->number = g_random_int (); + + /* There have been bugs in the past where the GSequence would + * dereference the user pointers. This will make sure such + * behavior causes crashes + */ + return ((char *)item + 1); +} + +static void +free_item (gpointer data) +{ + Item *item = fix_pointer (data); + item->seq->n_items--; + g_free (item); +} + +static void +seq_foreach (gpointer data, + gpointer user_data) +{ + Item *item = fix_pointer (data); + GList **link = user_data; + GSequenceIter *iter; + + g_assert (*link != NULL); + + iter = (*link)->data; + + g_assert (get_item (iter) == item); + + item->number = g_random_int(); + + *link = (*link)->next; +} + +static gint +simple_items_cmp (gconstpointer a, + gconstpointer b, + gpointer data) +{ + const Item *item_a = fix_pointer (a); + const Item *item_b = fix_pointer (b); + + if (item_a->number > item_b->number) + return +1; + else if (item_a->number < item_b->number) + return -1; + else + return 0; +} + +static gint +simple_iters_cmp (gconstpointer a, + gconstpointer b, + gpointer data) +{ + GSequence *seq = data; + GSequenceIter *iter_a = (GSequenceIter *)a; + GSequenceIter *iter_b = (GSequenceIter *)b; + gpointer item_a = g_sequence_get (iter_a); + gpointer item_b = g_sequence_get (iter_b); + + if (seq) + { + g_assert (g_sequence_iter_get_sequence (iter_a) == seq); + g_assert (g_sequence_iter_get_sequence (iter_b) == seq); + } + + return simple_items_cmp (item_a, item_b, data); +} + +static gint +compare_items (gconstpointer a, + gconstpointer b, + gpointer data) +{ + const Item *item_a = fix_pointer (a); + const Item *item_b = fix_pointer (b); + + if (item_a->number < item_b->number) + { + return -1; + } + else if (item_a->number == item_b->number) + { + /* Force an arbitrary order on the items + * We have to do this, since g_queue_insert_sorted() and + * g_sequence_insert_sorted() do not agree on the exact + * position the item is inserted if the new item is + * equal to an existing one. + */ + if (item_a < item_b) + return -1; + else if (item_a == item_b) + return 0; + else + return 1; + } + else + { + return 1; + } +} + +static void +check_sorted (SequenceInfo *info) +{ + GList *list; + int last; + GSequenceIter *last_iter; + + check_integrity (info); + + last = G_MININT; + last_iter = NULL; + for (list = info->queue->head; list != NULL; list = list->next) + { + GSequenceIter *iter = list->data; + Item *item = get_item (iter); + + g_assert (item->number >= last); + /* Check that the ordering is the same as that of the queue, + * ie. that the sort is stable + */ + if (last_iter) + g_assert (iter == g_sequence_iter_next (last_iter)); + + last = item->number; + last_iter = iter; + } +} + +static gint +compare_iters (gconstpointer a, + gconstpointer b, + gpointer data) +{ + GSequence *seq = data; + GSequenceIter *iter_a = (GSequenceIter *)a; + GSequenceIter *iter_b = (GSequenceIter *)b; + /* compare_items() will fix up the pointers */ + Item *item_a = g_sequence_get (iter_a); + Item *item_b = g_sequence_get (iter_b); + + if (seq) + { + g_assert (g_sequence_iter_get_sequence (iter_a) == seq); + g_assert (g_sequence_iter_get_sequence (iter_b) == seq); + } + + return compare_items (item_a, item_b, data); +} + +/* A version of g_queue_link_index() that treats NULL as just + * beyond the queue + */ +static int +queue_link_index (SequenceInfo *seq, GList *link) +{ + if (link) + return g_queue_link_index (seq->queue, link); + else + return g_queue_get_length (seq->queue); +} + +static void +get_random_range (SequenceInfo *seq, + GSequenceIter **begin_iter, + GSequenceIter **end_iter, + GList **begin_link, + GList **end_link) +{ + int length = g_queue_get_length (seq->queue); + int b = g_random_int_range (0, length + 1); + int e = g_random_int_range (b, length + 1); + + g_assert (length == g_sequence_get_length (seq->sequence)); + + if (begin_iter) + *begin_iter = g_sequence_get_iter_at_pos (seq->sequence, b); + if (end_iter) + *end_iter = g_sequence_get_iter_at_pos (seq->sequence, e); + if (begin_link) + *begin_link = g_queue_peek_nth_link (seq->queue, b); + if (end_link) + *end_link = g_queue_peek_nth_link (seq->queue, e); + if (begin_iter && begin_link) + { + g_assert ( + queue_link_index (seq, *begin_link) == + g_sequence_iter_get_position (*begin_iter)); + } + if (end_iter && end_link) + { + g_assert ( + queue_link_index (seq, *end_link) == + g_sequence_iter_get_position (*end_iter)); + } +} + +static gint +get_random_position (SequenceInfo *seq) +{ + int length = g_queue_get_length (seq->queue); + + g_assert (length == g_sequence_get_length (seq->sequence)); + + return g_random_int_range (-2, length + 5); +} + +static GSequenceIter * +get_random_iter (SequenceInfo *seq, + GList **link) +{ + GSequenceIter *iter; + int pos = get_random_position (seq); + if (link) + *link = g_queue_peek_nth_link (seq->queue, pos); + iter = g_sequence_get_iter_at_pos (seq->sequence, pos); + if (link) + g_assert (queue_link_index (seq, *link) == g_sequence_iter_get_position (iter)); + return iter; +} + +static void +dump_info (SequenceInfo *seq) +{ +#if 0 + GSequenceIter *iter; + GList *list; + + iter = g_sequence_get_begin_iter (seq->sequence); + list = seq->queue->head; + + while (iter != g_sequence_get_end_iter (seq->sequence)) + { + Item *item = get_item (iter); + g_printerr ("%p %p %d\n", list->data, iter, item->number); + + iter = g_sequence_iter_next (iter); + list = list->next; + } +#endif +} + +static void +run_random_tests (gconstpointer d) +{ + guint32 seed = GPOINTER_TO_UINT (d); +#define N_ITERATIONS 60000 +#define N_SEQUENCES 8 +#define N_TIMES 24 + + SequenceInfo sequences[N_SEQUENCES]; + int k; + +#if 0 + g_printerr (" seed: %u\n", seed); +#endif + + g_random_set_seed (seed); + + for (k = 0; k < N_SEQUENCES; ++k) + { + sequences[k].queue = g_queue_new (); + sequences[k].sequence = g_sequence_new (free_item); + sequences[k].n_items = 0; + } + +#define RANDOM_SEQUENCE() &(sequences[g_random_int_range (0, N_SEQUENCES)]) + + for (k = 0; k < N_ITERATIONS; ++k) + { + int i; + SequenceInfo *seq = RANDOM_SEQUENCE(); + int op = g_random_int_range (0, N_OPS); + +#if 0 + g_printerr ("%d on %p\n", op, seq); +#endif + + switch (op) + { + case NEW: + case FREE: + { + g_queue_free (seq->queue); + g_sequence_free (seq->sequence); + + g_assert (seq->n_items == 0); + + seq->queue = g_queue_new (); + seq->sequence = g_sequence_new (free_item); + + check_integrity (seq); + } + break; + case GET_LENGTH: + { + int slen = g_sequence_get_length (seq->sequence); + int qlen = g_queue_get_length (seq->queue); + + g_assert (slen == qlen); + } + break; + case FOREACH: + { + GList *link = seq->queue->head; + g_sequence_foreach (seq->sequence, seq_foreach, &link); + g_assert (link == NULL); + } + break; + case FOREACH_RANGE: + { + GSequenceIter *begin_iter, *end_iter; + GList *begin_link, *end_link; + + get_random_range (seq, &begin_iter, &end_iter, &begin_link, &end_link); + + check_integrity (seq); + + g_sequence_foreach_range (begin_iter, end_iter, seq_foreach, &begin_link); + + g_assert (begin_link == end_link); + } + break; + case SORT: + { + dump_info (seq); + + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + dump_info (seq); + } + break; + case SORT_ITER: + { + check_integrity (seq); + g_sequence_sort_iter (seq->sequence, + (GSequenceIterCompareFunc)compare_iters, seq->sequence); + g_queue_sort (seq->queue, compare_iters, NULL); + check_sorted (seq); + } + break; + + /* Getting iters */ + case GET_END_ITER: + case GET_BEGIN_ITER: + { + GSequenceIter *begin_iter; + GSequenceIter *end_iter; + GSequenceIter *penultimate_iter; + + begin_iter = g_sequence_get_begin_iter (seq->sequence); + check_integrity (seq); + + end_iter = g_sequence_get_end_iter (seq->sequence); + check_integrity (seq); + + penultimate_iter = g_sequence_iter_prev (end_iter); + check_integrity (seq); + + if (g_sequence_get_length (seq->sequence) > 0) + { + g_assert (seq->queue->head); + g_assert (seq->queue->head->data == begin_iter); + g_assert (seq->queue->tail); + g_assert (seq->queue->tail->data == penultimate_iter); + } + else + { + g_assert (penultimate_iter == end_iter); + g_assert (begin_iter == end_iter); + g_assert (penultimate_iter == begin_iter); + g_assert (seq->queue->head == NULL); + g_assert (seq->queue->tail == NULL); + } + } + break; + case GET_ITER_AT_POS: + { + g_assert (g_queue_get_length (seq->queue) == (guint) g_sequence_get_length (seq->sequence)); + + for (i = 0; i < 10; ++i) + { + int pos = get_random_position (seq); + GSequenceIter *iter = g_sequence_get_iter_at_pos (seq->sequence, pos); + GList *link = g_queue_peek_nth_link (seq->queue, pos); + check_integrity (seq); + if (pos >= g_sequence_get_length (seq->sequence) || pos < 0) + { + g_assert (iter == g_sequence_get_end_iter (seq->sequence)); + g_assert (link == NULL); + } + else + { + g_assert (link); + g_assert (link->data == iter); + } + } + } + break; + case APPEND: + { + for (i = 0; i < 10; ++i) + { + GSequenceIter *iter = g_sequence_append (seq->sequence, new_item (seq)); + g_queue_push_tail (seq->queue, iter); + } + } + break; + case PREPEND: + { + for (i = 0; i < 10; ++i) + { + GSequenceIter *iter = g_sequence_prepend (seq->sequence, new_item (seq)); + g_queue_push_head (seq->queue, iter); + } + } + break; + case INSERT_BEFORE: + { + for (i = 0; i < 10; ++i) + { + GList *link; + GSequenceIter *iter = get_random_iter (seq, &link); + GSequenceIter *new_iter; + check_integrity (seq); + + new_iter = g_sequence_insert_before (iter, new_item (seq)); + + g_queue_insert_before (seq->queue, link, new_iter); + } + } + break; + case MOVE: + { + GList *link1, *link2; + SequenceInfo *seq1 = RANDOM_SEQUENCE(); + SequenceInfo *seq2 = RANDOM_SEQUENCE(); + GSequenceIter *iter1 = get_random_iter (seq1, &link1); + GSequenceIter *iter2 = get_random_iter (seq2, &link2); + + if (!g_sequence_iter_is_end (iter1)) + { + g_sequence_move (iter1, iter2); + + if (!link2) + g_assert (g_sequence_iter_is_end (iter2)); + + g_queue_insert_before (seq2->queue, link2, link1->data); + + g_queue_delete_link (seq1->queue, link1); + + get_item (iter1)->seq = seq2; + + seq1->n_items--; + seq2->n_items++; + } + + check_integrity (seq); + + iter1 = get_random_iter (seq, NULL); + + /* Moving an iter to itself should have no effect */ + if (!g_sequence_iter_is_end (iter1)) + g_sequence_move (iter1, iter1); + } + break; + case SWAP: + { + GList *link1, *link2; + SequenceInfo *seq1 = RANDOM_SEQUENCE(); + SequenceInfo *seq2 = RANDOM_SEQUENCE(); + GSequenceIter *iter1 = get_random_iter (seq1, &link1); + GSequenceIter *iter2 = get_random_iter (seq2, &link2); + + if (!g_sequence_iter_is_end (iter1) && + !g_sequence_iter_is_end (iter2)) + { + gpointer tmp; + + g_sequence_swap (iter1, iter2); + + get_item (iter1)->seq = seq2; + get_item (iter2)->seq = seq1; + + tmp = link1->data; + link1->data = link2->data; + link2->data = tmp; + } + } + break; + case INSERT_SORTED: + { + dump_info (seq); + + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + for (i = 0; i < N_TIMES; ++i) + { + GSequenceIter *iter = + g_sequence_insert_sorted (seq->sequence, new_item(seq), compare_items, NULL); + + g_queue_insert_sorted (seq->queue, iter, compare_iters, NULL); + } + + check_sorted (seq); + + dump_info (seq); + } + break; + case INSERT_SORTED_ITER: + { + dump_info (seq); + + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + for (i = 0; i < N_TIMES; ++i) + { + GSequenceIter *iter; + + iter = g_sequence_insert_sorted_iter (seq->sequence, + new_item (seq), + (GSequenceIterCompareFunc)compare_iters, + seq->sequence); + + g_queue_insert_sorted (seq->queue, iter, compare_iters, NULL); + } + + check_sorted (seq); + + dump_info (seq); + } + break; + case SORT_CHANGED: + { + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + for (i = 0; i < N_TIMES; ++i) + { + GList *link; + GSequenceIter *iter = get_random_iter (seq, &link); + + if (!g_sequence_iter_is_end (iter)) + { + g_sequence_set (iter, new_item (seq)); + g_sequence_sort_changed (iter, compare_items, NULL); + + g_queue_delete_link (seq->queue, link); + g_queue_insert_sorted (seq->queue, iter, compare_iters, NULL); + } + + check_sorted (seq); + } + } + break; + case SORT_CHANGED_ITER: + { + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + for (i = 0; i < N_TIMES; ++i) + { + GList *link; + GSequenceIter *iter = get_random_iter (seq, &link); + + if (!g_sequence_iter_is_end (iter)) + { + g_sequence_set (iter, new_item (seq)); + g_sequence_sort_changed_iter (iter, + (GSequenceIterCompareFunc)compare_iters, seq->sequence); + + g_queue_delete_link (seq->queue, link); + g_queue_insert_sorted (seq->queue, iter, compare_iters, NULL); + } + + check_sorted (seq); + } + } + break; + case REMOVE: + { + for (i = 0; i < N_TIMES; ++i) + { + GList *link; + GSequenceIter *iter = get_random_iter (seq, &link); + + if (!g_sequence_iter_is_end (iter)) + { + g_sequence_remove (iter); + g_queue_delete_link (seq->queue, link); + } + } + } + break; + case REMOVE_RANGE: + { + GSequenceIter *begin_iter, *end_iter; + GList *begin_link, *end_link; + GList *list; + + get_random_range (seq, &begin_iter, &end_iter, &begin_link, &end_link); + + g_sequence_remove_range (begin_iter, end_iter); + + list = begin_link; + while (list != end_link) + { + GList *next = list->next; + + g_queue_delete_link (seq->queue, list); + + list = next; + } + } + break; + case MOVE_RANGE: + { + SequenceInfo *src = RANDOM_SEQUENCE(); + SequenceInfo *dst = RANDOM_SEQUENCE(); + + GSequenceIter *begin_iter, *end_iter; + GList *begin_link, *end_link; + + GSequenceIter *dst_iter; + GList *dst_link; + + GList *list; + + g_assert (src->queue); + g_assert (dst->queue); + + get_random_range (src, &begin_iter, &end_iter, &begin_link, &end_link); + dst_iter = get_random_iter (dst, &dst_link); + + g_sequence_move_range (dst_iter, begin_iter, end_iter); + + if (dst_link == begin_link || (src == dst && dst_link == end_link)) + { + check_integrity (src); + check_integrity (dst); + break; + } + + if (queue_link_index (src, begin_link) >= + queue_link_index (src, end_link)) + { + break; + } + + if (src == dst && + queue_link_index (src, dst_link) >= queue_link_index (src, begin_link) && + queue_link_index (src, dst_link) <= queue_link_index (src, end_link)) + { + break; + } + + list = begin_link; + while (list != end_link) + { + GList *next = list->next; + Item *item = get_item (list->data); + + g_assert (dst->queue); + g_queue_insert_before (dst->queue, dst_link, list->data); + g_queue_delete_link (src->queue, list); + + g_assert (item->seq == src); + + src->n_items--; + dst->n_items++; + item->seq = dst; + + list = next; + } + } + break; + case SEARCH: + { + Item *item; + GSequenceIter *search_iter; + GSequenceIter *insert_iter; + + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + item = new_item (seq); + search_iter = g_sequence_search (seq->sequence, item, compare_items, NULL); + + insert_iter = g_sequence_insert_sorted (seq->sequence, item, compare_items, NULL); + + g_assert (search_iter == g_sequence_iter_next (insert_iter)); + + g_queue_insert_sorted (seq->queue, insert_iter, compare_iters, NULL); + } + break; + case SEARCH_ITER: + { + Item *item; + GSequenceIter *search_iter; + GSequenceIter *insert_iter; + + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + item = new_item (seq); + search_iter = g_sequence_search_iter (seq->sequence, + item, + (GSequenceIterCompareFunc)compare_iters, seq->sequence); + + insert_iter = g_sequence_insert_sorted (seq->sequence, item, compare_items, NULL); + + g_assert (search_iter == g_sequence_iter_next (insert_iter)); + + g_queue_insert_sorted (seq->queue, insert_iter, compare_iters, NULL); + } + break; + case LOOKUP: + { + Item *item; + GSequenceIter *lookup_iter; + GSequenceIter *insert_iter; + + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + item = new_item (seq); + insert_iter = g_sequence_insert_sorted (seq->sequence, item, compare_items, NULL); + g_queue_insert_sorted (seq->queue, insert_iter, compare_iters, NULL); + + lookup_iter = g_sequence_lookup (seq->sequence, item, simple_items_cmp, NULL); + g_assert (simple_iters_cmp (insert_iter, lookup_iter, NULL) == 0); + } + break; + case LOOKUP_ITER: + { + Item *item; + GSequenceIter *lookup_iter; + GSequenceIter *insert_iter; + + g_sequence_sort (seq->sequence, compare_items, NULL); + g_queue_sort (seq->queue, compare_iters, NULL); + + check_sorted (seq); + + item = new_item (seq); + insert_iter = g_sequence_insert_sorted (seq->sequence, item, compare_items, NULL); + g_queue_insert_sorted (seq->queue, insert_iter, compare_iters, NULL); + + lookup_iter = g_sequence_lookup_iter (seq->sequence, item, + (GSequenceIterCompareFunc) simple_iters_cmp, NULL); + g_assert (simple_iters_cmp (insert_iter, lookup_iter, NULL) == 0); + } + break; + + /* dereferencing */ + case GET: + case SET: + { + GSequenceIter *iter; + GList *link; + + iter = get_random_iter (seq, &link); + + if (!g_sequence_iter_is_end (iter)) + { + Item *item; + + check_integrity (seq); + + /* Test basic functionality */ + item = new_item (seq); + g_sequence_set (iter, item); + g_assert (g_sequence_get (iter) == item); + + /* Make sure that existing items are freed */ + for (i = 0; i < N_TIMES; ++i) + g_sequence_set (iter, new_item (seq)); + + check_integrity (seq); + + g_sequence_set (iter, new_item (seq)); + } + } + break; + + /* operations on GSequenceIter * */ + case ITER_IS_BEGIN: + { + GSequenceIter *iter; + + iter = g_sequence_get_iter_at_pos (seq->sequence, 0); + + g_assert (g_sequence_iter_is_begin (iter)); + + check_integrity (seq); + + if (g_sequence_get_length (seq->sequence) > 0) + { + g_assert (!g_sequence_iter_is_begin (g_sequence_get_end_iter (seq->sequence))); + } + else + { + g_assert (g_sequence_iter_is_begin (g_sequence_get_end_iter (seq->sequence))); + } + + g_assert (g_sequence_iter_is_begin (g_sequence_get_begin_iter (seq->sequence))); + } + break; + case ITER_IS_END: + { + GSequenceIter *iter; + int len = g_sequence_get_length (seq->sequence); + + iter = g_sequence_get_iter_at_pos (seq->sequence, len); + + g_assert (g_sequence_iter_is_end (iter)); + + if (len > 0) + { + g_assert (!g_sequence_iter_is_end (g_sequence_get_begin_iter (seq->sequence))); + } + else + { + g_assert (g_sequence_iter_is_end (g_sequence_get_begin_iter (seq->sequence))); + } + + g_assert (g_sequence_iter_is_end (g_sequence_get_end_iter (seq->sequence))); + } + break; + case ITER_NEXT: + { + GSequenceIter *iter1, *iter2, *iter3, *end; + + iter1 = g_sequence_append (seq->sequence, new_item (seq)); + iter2 = g_sequence_append (seq->sequence, new_item (seq)); + iter3 = g_sequence_append (seq->sequence, new_item (seq)); + + end = g_sequence_get_end_iter (seq->sequence); + + g_assert (g_sequence_iter_next (iter1) == iter2); + g_assert (g_sequence_iter_next (iter2) == iter3); + g_assert (g_sequence_iter_next (iter3) == end); + g_assert (g_sequence_iter_next (end) == end); + + g_queue_push_tail (seq->queue, iter1); + g_queue_push_tail (seq->queue, iter2); + g_queue_push_tail (seq->queue, iter3); + } + break; + case ITER_PREV: + { + GSequenceIter *iter1, *iter2, *iter3, *begin; + + iter1 = g_sequence_prepend (seq->sequence, new_item (seq)); + iter2 = g_sequence_prepend (seq->sequence, new_item (seq)); + iter3 = g_sequence_prepend (seq->sequence, new_item (seq)); + + begin = g_sequence_get_begin_iter (seq->sequence); + + g_assert (g_sequence_iter_prev (iter1) == iter2); + g_assert (g_sequence_iter_prev (iter2) == iter3); + g_assert (iter3 == begin); + g_assert (g_sequence_iter_prev (iter3) == begin); + g_assert (g_sequence_iter_prev (begin) == begin); + + g_queue_push_head (seq->queue, iter1); + g_queue_push_head (seq->queue, iter2); + g_queue_push_head (seq->queue, iter3); + } + break; + case ITER_GET_POSITION: + { + GList *link; + GSequenceIter *iter = get_random_iter (seq, &link); + + g_assert (g_sequence_iter_get_position (iter) == + queue_link_index (seq, link)); + } + break; + case ITER_MOVE: + { + int len = g_sequence_get_length (seq->sequence); + GSequenceIter *iter; + int pos; + + iter = get_random_iter (seq, NULL); + pos = g_sequence_iter_get_position (iter); + iter = g_sequence_iter_move (iter, len - pos); + g_assert (g_sequence_iter_is_end (iter)); + + + iter = get_random_iter (seq, NULL); + pos = g_sequence_iter_get_position (iter); + while (pos < len) + { + g_assert (!g_sequence_iter_is_end (iter)); + pos++; + iter = g_sequence_iter_move (iter, 1); + } + g_assert (g_sequence_iter_is_end (iter)); + } + break; + case ITER_GET_SEQUENCE: + { + GSequenceIter *iter = get_random_iter (seq, NULL); + + g_assert (g_sequence_iter_get_sequence (iter) == seq->sequence); + } + break; + + /* search */ + case ITER_COMPARE: + { + GList *link1, *link2; + GSequenceIter *iter1 = get_random_iter (seq, &link1); + GSequenceIter *iter2 = get_random_iter (seq, &link2); + + int cmp = g_sequence_iter_compare (iter1, iter2); + int pos1 = queue_link_index (seq, link1); + int pos2 = queue_link_index (seq, link2); + + if (cmp == 0) + { + g_assert (pos1 == pos2); + } + else if (cmp < 0) + { + g_assert (pos1 < pos2); + } + else + { + g_assert (pos1 > pos2); + } + } + break; + case RANGE_GET_MIDPOINT: + { + GSequenceIter *iter1 = get_random_iter (seq, NULL); + GSequenceIter *iter2 = get_random_iter (seq, NULL); + GSequenceIter *iter3; + int cmp; + + cmp = g_sequence_iter_compare (iter1, iter2); + + if (cmp > 0) + { + GSequenceIter *tmp; + + tmp = iter1; + iter1 = iter2; + iter2 = tmp; + } + + iter3 = g_sequence_range_get_midpoint (iter1, iter2); + + if (cmp == 0) + { + g_assert (iter3 == iter1); + g_assert (iter3 == iter2); + } + + g_assert (g_sequence_iter_get_position (iter3) >= + g_sequence_iter_get_position (iter1)); + g_assert (g_sequence_iter_get_position (iter2) >= + g_sequence_iter_get_position (iter3)); + } + break; + + } + + check_integrity (seq); + } + + for (k = 0; k < N_SEQUENCES; ++k) + { + g_queue_free (sequences[k].queue); + g_sequence_free (sequences[k].sequence); + sequences[k].n_items = 0; + } +} + +/* Random seeds known to have failed at one point + */ +static gulong seeds[] = + { + 825541564u, + 801678400u, + 1477639090u, + 3369132895u, + 1192944867u, + 770458294u, + 1099575817u, + 590523467u, + 3583571454u, + 579241222u + }; + +/* Single, stand-alone tests */ + +static void +test_out_of_range_jump (void) +{ + GSequence *seq = g_sequence_new (NULL); + GSequenceIter *iter = g_sequence_get_begin_iter (seq); + + g_sequence_iter_move (iter, 5); + + g_assert (g_sequence_iter_is_begin (iter)); + g_assert (g_sequence_iter_is_end (iter)); + + g_sequence_free (seq); +} + +static void +test_iter_move (void) +{ + GSequence *seq = g_sequence_new (NULL); + GSequenceIter *iter; + gint i; + + for (i = 0; i < 10; ++i) + g_sequence_append (seq, GINT_TO_POINTER (i)); + + iter = g_sequence_get_begin_iter (seq); + iter = g_sequence_iter_move (iter, 5); + g_assert_cmpint (GPOINTER_TO_INT (g_sequence_get (iter)), ==, 5); + + iter = g_sequence_iter_move (iter, -10); + g_assert (g_sequence_iter_is_begin (iter)); + + iter = g_sequence_get_end_iter (seq); + iter = g_sequence_iter_move (iter, -5); + g_assert_cmpint (GPOINTER_TO_INT (g_sequence_get (iter)), ==, 5); + + iter = g_sequence_iter_move (iter, 10); + g_assert (g_sequence_iter_is_end (iter)); + + g_sequence_free (seq); +} + +static int +compare (gconstpointer a, gconstpointer b, gpointer userdata) +{ + int ai, bi; + + ai = GPOINTER_TO_INT (a); + bi = GPOINTER_TO_INT (b); + + if (ai < bi) + return -1; + else if (ai > bi) + return 1; + else + return 0; +} + +static int +compare_iter (GSequenceIter *a, + GSequenceIter *b, + gpointer data) +{ + return compare (g_sequence_get (a), + g_sequence_get (b), + data); +} + +static void +test_insert_sorted_non_pointer (void) +{ + int i; + + for (i = 0; i < 10; i++) + { + GSequence *seq = g_sequence_new (NULL); + int j; + + for (j = 0; j < 10000; j++) + { + g_sequence_insert_sorted (seq, GINT_TO_POINTER (g_random_int()), + compare, NULL); + + g_sequence_insert_sorted_iter (seq, GINT_TO_POINTER (g_random_int()), + compare_iter, NULL); + } + + g_sequence_check (seq); + + g_sequence_free (seq); + } +} + +static void +test_stable_sort (void) +{ + int i; + GSequence *seq = g_sequence_new (NULL); + +#define N_ITEMS 1000 + + GSequenceIter *iters[N_ITEMS]; + GSequenceIter *iter; + + for (i = 0; i < N_ITEMS; ++i) + { + iters[i] = g_sequence_append (seq, GINT_TO_POINTER (3000)); + g_sequence_check (seq); + g_assert (g_sequence_iter_get_sequence (iters[i]) == seq); + } + + i = 0; + iter = g_sequence_get_begin_iter (seq); + g_assert (g_sequence_iter_get_sequence (iter) == seq); + g_sequence_check (seq); + while (!g_sequence_iter_is_end (iter)) + { + g_assert (g_sequence_iter_get_sequence (iters[i]) == seq); + g_assert (iters[i++] == iter); + + iter = g_sequence_iter_next (iter); + g_sequence_check (seq); + } + + g_sequence_sort (seq, compare, NULL); + + i = 0; + iter = g_sequence_get_begin_iter (seq); + while (!g_sequence_iter_is_end (iter)) + { + g_assert (g_sequence_iter_get_sequence (iters[i]) == seq); + g_assert (iters[i] == iter); + + iter = g_sequence_iter_next (iter); + g_sequence_check (seq); + + i++; + } + + for (i = N_ITEMS - 1; i >= 0; --i) + { + g_sequence_check (seq); + g_assert (g_sequence_iter_get_sequence (iters[i]) == seq); + g_assert (g_sequence_get_end_iter (seq) != iters[i]); + g_sequence_sort_changed (iters[i], compare, NULL); + } + + i = 0; + iter = g_sequence_get_begin_iter (seq); + while (!g_sequence_iter_is_end (iter)) + { + g_assert (iters[i++] == iter); + + iter = g_sequence_iter_next (iter); + g_sequence_check (seq); + } + + g_sequence_free (seq); +} + +static void +test_empty (void) +{ + GSequence *seq; + int i; + + seq = g_sequence_new (NULL); + g_assert_true (g_sequence_is_empty (seq)); + + for (i = 0; i < 1000; i++) + { + g_sequence_append (seq, GINT_TO_POINTER (i)); + g_assert_false (g_sequence_is_empty (seq)); + } + + for (i = 0; i < 1000; i++) + { + GSequenceIter *end = g_sequence_get_end_iter (seq); + g_assert_false (g_sequence_is_empty (seq)); + g_sequence_remove (g_sequence_iter_prev (end)); + } + + g_assert_true (g_sequence_is_empty (seq)); + + g_sequence_free (seq); +} + +int +main (int argc, + char **argv) +{ + gsize i; + guint32 seed; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + /* Standalone tests */ + g_test_add_func ("/sequence/out-of-range-jump", test_out_of_range_jump); + g_test_add_func ("/sequence/iter-move", test_iter_move); + g_test_add_func ("/sequence/insert-sorted-non-pointer", test_insert_sorted_non_pointer); + g_test_add_func ("/sequence/stable-sort", test_stable_sort); + g_test_add_func ("/sequence/is_empty", test_empty); + + /* Regression tests */ + for (i = 0; i < G_N_ELEMENTS (seeds); ++i) + { + path = g_strdup_printf ("/sequence/random/seed:%lu", seeds[i]); + g_test_add_data_func (path, GUINT_TO_POINTER (seeds[i]), run_random_tests); + g_free (path); + } + + /* New random seed */ + seed = g_test_rand_int_range (0, G_MAXINT); + path = g_strdup_printf ("/sequence/random/seed:%u", seed); + g_test_add_data_func (path, GUINT_TO_POINTER (seed), run_random_tests); + g_free (path); + + return g_test_run (); +} diff --git a/glib/tests/shell.c b/glib/tests/shell.c new file mode 100644 index 0000000..5cde371 --- /dev/null +++ b/glib/tests/shell.c @@ -0,0 +1,216 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include +#include + + +typedef struct _CmdlineTest CmdlineTest; + +struct _CmdlineTest +{ + const gchar *cmdline; + gint argc; + const gchar *argv[10]; + gint error_code; +}; + +static CmdlineTest cmdline_tests[] = +{ + { "foo bar", 2, { "foo", "bar", NULL }, -1 }, + { "foo 'bar'", 2, { "foo", "bar", NULL }, -1 }, + { "foo \"bar\"", 2, { "foo", "bar", NULL }, -1 }, + { "foo '' 'bar'", 3, { "foo", "", "bar", NULL }, -1 }, + { "foo \"bar\"'baz'blah'foo'\\''blah'\"boo\"", 2, { "foo", "barbazblahfoo'blahboo", NULL }, -1 }, + { "foo \t \tblah\tfoo\t\tbar baz", 5, { "foo", "blah", "foo", "bar", "baz", NULL }, -1 }, + { "foo ' spaces more spaces lots of spaces in this ' \t", 2, { "foo", " spaces more spaces lots of spaces in this ", NULL }, -1 }, + { "foo \\\nbar", 2, { "foo", "bar", NULL }, -1 }, + { "foo '' ''", 3, { "foo", "", "", NULL }, -1 }, + { "foo \\\" la la la", 5, { "foo", "\"", "la", "la", "la", NULL }, -1 }, + { "foo \\ foo woo woo\\ ", 4, { "foo", " foo", "woo", "woo ", NULL }, -1 }, + { "foo \"yada yada \\$\\\"\"", 2, { "foo", "yada yada $\"", NULL }, -1 }, + { "foo \"c:\\\\\"", 2, { "foo", "c:\\", NULL }, -1 }, + { "foo # bla bla bla\n bar", 2, { "foo", "bar", NULL }, -1 }, + { "foo a#b", 2, { "foo", "a#b", NULL }, -1 }, + { "#foo", 0, { NULL }, G_SHELL_ERROR_EMPTY_STRING }, + { "foo bar \\", 0, { NULL }, G_SHELL_ERROR_BAD_QUOTING }, + { "foo 'bar baz", 0, { NULL }, G_SHELL_ERROR_BAD_QUOTING }, + { "foo '\"bar\" baz", 0, { NULL }, G_SHELL_ERROR_BAD_QUOTING }, + { "", 0, { NULL }, G_SHELL_ERROR_EMPTY_STRING }, + { " ", 0, { NULL }, G_SHELL_ERROR_EMPTY_STRING }, + { "# foo bar", 0, { NULL }, G_SHELL_ERROR_EMPTY_STRING }, + {"foo '/bar/summer'\\''09 tours.pdf'", 2, {"foo", "/bar/summer'09 tours.pdf", NULL}, -1} +}; + +static void +do_cmdline_test (gconstpointer d) +{ + const CmdlineTest *test = d; + gint argc; + gchar **argv; + GError *err; + gboolean res; + + err = NULL; + g_printerr ("test cmdline: %s\n", test->cmdline); + res = g_shell_parse_argv (test->cmdline, &argc, &argv, &err); + if (test->error_code == -1) + { + g_assert (res); + g_assert_cmpint (argc, ==, test->argc); + g_assert (g_strv_equal ((const gchar * const *) argv, (const gchar * const *) test->argv)); + g_assert_no_error (err); + } + else + { + g_assert (!res); + g_assert_error (err, G_SHELL_ERROR, test->error_code); + } + + if (err) + g_error_free (err); + if (res) + g_strfreev (argv); +} + +typedef struct _QuoteTest QuoteTest; + +struct _QuoteTest +{ + const gchar *in; + const gchar *out; +}; + +static QuoteTest quote_tests[] = +{ + { "", "''" }, + { "a", "'a'" }, + { "(", "'('" }, + { "'", "''\\'''" }, + { "'a", "''\\''a'" }, + { "a'", "'a'\\'''" }, + { "a'a", "'a'\\''a'" } +}; + +static void +do_quote_test (gconstpointer d) +{ + const QuoteTest *test = d; + gchar *out; + + out = g_shell_quote (test->in); + g_assert_cmpstr (out, ==, test->out); + g_free (out); +} + +typedef struct _UnquoteTest UnquoteTest; + +struct _UnquoteTest +{ + const gchar *in; + const gchar *out; + gint error_code; +}; + +static UnquoteTest unquote_tests[] = +{ + { "", "", -1 }, + { "a", "a", -1 }, + { "'a'", "a", -1 }, + { "'('", "(", -1 }, + { "''\\'''", "'", -1 }, + { "''\\''a'", "'a", -1 }, + { "'a'\\'''", "a'", -1 }, + { "'a'\\''a'", "a'a", -1 }, + { "\\\\", "\\", -1 }, + { "\\\n", "", -1 }, + { "'\\''", NULL, G_SHELL_ERROR_BAD_QUOTING }, + { "\"\\\"\"", "\"", -1 }, + { "\"", NULL, G_SHELL_ERROR_BAD_QUOTING }, + { "'", NULL, G_SHELL_ERROR_BAD_QUOTING }, + { "\x22\\\\\"", "\\", -1 }, + { "\x22\\`\"", "`", -1 }, + { "\x22\\$\"", "$", -1 }, + { "\x22\\\n\"", "\n", -1 }, + { "\"\\'\"", "\\'", -1 }, + { "\x22\\\r\"", "\\\r", -1 }, + { "\x22\\n\"", "\\n", -1 } +}; + +static void +do_unquote_test (gconstpointer d) +{ + const UnquoteTest *test = d; + gchar *out; + GError *error; + + error = NULL; + out = g_shell_unquote (test->in, &error); + g_assert_cmpstr (out, ==, test->out); + if (test->error_code == -1) + g_assert_no_error (error); + else + g_assert_error (error, G_SHELL_ERROR, test->error_code); + + g_free (out); + if (error) + g_error_free (error); +} + +int +main (int argc, char *argv[]) +{ + gsize i; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS (cmdline_tests); i++) + { + path = g_strdup_printf ("/shell/cmdline/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &cmdline_tests[i], do_cmdline_test); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (quote_tests); i++) + { + path = g_strdup_printf ("/shell/quote/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, "e_tests[i], do_quote_test); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (unquote_tests); i++) + { + path = g_strdup_printf ("/shell/unquote/%" G_GSIZE_FORMAT, i); + g_test_add_data_func (path, &unquote_tests[i], do_unquote_test); + g_free (path); + } + + return g_test_run (); +} diff --git a/glib/tests/slice-color.c b/glib/tests/slice-color.c new file mode 100644 index 0000000..733bfcc --- /dev/null +++ b/glib/tests/slice-color.c @@ -0,0 +1,133 @@ +/* GLIB sliced memory - fast threaded memory chunk allocator + * Copyright (C) 2005 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include + +#define ALIGN(size, base) \ + ((base) * (gsize) (((size) + (base) - 1) / (base))) + +static void +fill_memory (guint **mem, + guint n, + guint val) +{ + guint j; + + for (j = 0; j < n; j++) + mem[j][0] = val; +} + +static guint64 +access_memory3 (guint **mema, + guint **memb, + guint **memd, + guint n, + guint64 repeats) +{ + guint64 accu = 0, i, j; + + for (i = 0; i < repeats; i++) + { + for (j = 1; j < n; j += 2) + memd[j][0] = mema[j][0] + memb[j][0]; + } + + for (i = 0; i < repeats; i++) + for (j = 0; j < n; j++) + accu += memd[j][0]; + + return accu; +} + +static void +touch_mem (guint64 block_size, + guint64 n_blocks, + guint64 repeats) +{ + GTimer *timer; + guint **mema, **memb, **memc; + guint64 j, accu, n = n_blocks; + + mema = g_new (guint*, n); + for (j = 0; j < n; j++) + mema[j] = g_slice_alloc (block_size); + + memb = g_new (guint*, n); + for (j = 0; j < n; j++) + memb[j] = g_slice_alloc (block_size); + + memc = g_new (guint*, n); + for (j = 0; j < n; j++) + memc[j] = g_slice_alloc (block_size); + + timer = g_timer_new(); + + fill_memory (mema, n, 2); + fill_memory (memb, n, 3); + fill_memory (memc, n, 4); + + access_memory3 (mema, memb, memc, n, 3); + + g_timer_start (timer); + accu = access_memory3 (mema, memb, memc, n, repeats); + g_timer_stop (timer); + + g_test_message ("Access-time = %fs", g_timer_elapsed (timer, NULL)); + g_assert_cmpuint (accu / repeats, ==, (2 + 3) * n / 2 + 4 * n / 2); + + for (j = 0; j < n; j++) + { + g_slice_free1 (block_size, mema[j]); + g_slice_free1 (block_size, memb[j]); + g_slice_free1 (block_size, memc[j]); + } + + g_timer_destroy (timer); + g_free (mema); + g_free (memb); + g_free (memc); +} + +static void +test_slice_colors (void) +{ + guint64 block_size = 512; + guint64 area_size = 1024 * 1024; + guint64 n_blocks, repeats = 1000000; + + /* figure number of blocks from block and area size. + * divide area by 3 because touch_mem() allocates 3 areas */ + n_blocks = area_size / 3 / ALIGN (block_size, sizeof (gsize) * 2); + + g_test_message ("Allocate and touch %" G_GUINT64_FORMAT + " blocks of %" G_GUINT64_FORMAT " bytes" + " (= %" G_GUINT64_FORMAT " bytes) %" G_GUINT64_FORMAT + " times with color increment", + n_blocks, block_size, n_blocks * block_size, repeats); + + touch_mem (block_size, n_blocks, repeats); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/slice/colors", test_slice_colors); + + return g_test_run (); +} diff --git a/glib/tests/slice-concurrent.c b/glib/tests/slice-concurrent.c new file mode 100644 index 0000000..4551e20 --- /dev/null +++ b/glib/tests/slice-concurrent.c @@ -0,0 +1,130 @@ +/* test for gslice cross thread allocation/free + * Copyright (C) 2006 Stefan Westerfeld + * Copyright (C) 2007 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include + +#include + +#define N_THREADS 8 +#define N_ALLOCS 50000 +#define MAX_BLOCK_SIZE 64 + +struct ThreadData +{ + int thread_id; + GThread* gthread; + + GMutex to_free_mutex; + void* to_free [N_THREADS * N_ALLOCS]; + int bytes_to_free [N_THREADS * N_ALLOCS]; + int n_to_free; + int n_freed; +} tdata[N_THREADS]; + +static void * +thread_func (void *arg) +{ + int i; + struct ThreadData *td = arg; + + for (i = 0; i < N_ALLOCS; i++) + { + int bytes, f, t; + char *mem; + + if (rand() % (N_ALLOCS / 20) == 0) + g_test_message ("%c", 'a' - 1 + td->thread_id); + + /* allocate block of random size and randomly fill */ + bytes = rand() % MAX_BLOCK_SIZE + 1; + mem = g_slice_alloc (bytes); + + for (f = 0; f < bytes; f++) + mem[f] = rand(); + + /* associate block with random thread */ + t = rand() % N_THREADS; + g_mutex_lock (&tdata[t].to_free_mutex); + tdata[t].to_free[tdata[t].n_to_free] = mem; + tdata[t].bytes_to_free[tdata[t].n_to_free] = bytes; + tdata[t].n_to_free++; + g_mutex_unlock (&tdata[t].to_free_mutex); + + /* shuffle thread execution order every once in a while */ + if (rand() % 97 == 0) + { + if (rand() % 2) + g_thread_yield(); /* concurrent shuffling for single core */ + else + g_usleep (1000); /* concurrent shuffling for multi core */ + } + + /* free a block associated with this thread */ + g_mutex_lock (&td->to_free_mutex); + if (td->n_to_free > 0) + { + td->n_to_free--; + g_slice_free1 (td->bytes_to_free[td->n_to_free], + td->to_free[td->n_to_free]); + td->n_freed++; + } + g_mutex_unlock (&td->to_free_mutex); + } + + return NULL; +} + +static void +test_concurrent_slice (void) +{ + int t; + + for (t = 0; t < N_THREADS; t++) + { + tdata[t].thread_id = t + 1; + tdata[t].n_to_free = 0; + tdata[t].n_freed = 0; + } + + for (t = 0; t < N_THREADS; t++) + { + tdata[t].gthread = g_thread_new (NULL, thread_func, &tdata[t]); + g_assert_nonnull (tdata[t].gthread); + } + + for (t = 0; t < N_THREADS; t++) + { + g_thread_join (tdata[t].gthread); + } + + for (t = 0; t < N_THREADS; t++) + { + g_test_message ("Thread %d: %d blocks freed, %d blocks not freed", + tdata[t].thread_id, tdata[t].n_freed, tdata[t].n_to_free); + } +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/slice/concurrent", test_concurrent_slice); + + return g_test_run (); +} diff --git a/glib/tests/slice.c b/glib/tests/slice.c new file mode 100644 index 0000000..a566280 --- /dev/null +++ b/glib/tests/slice.c @@ -0,0 +1,167 @@ +#include +#include + +/* We test deprecated functionality here */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +#ifdef G_ENABLE_DEBUG +static void +test_slice_nodebug (void) +{ + const gchar *oldval; + + oldval = g_getenv ("G_SLICE"); + g_unsetenv ("G_SLICE"); + + if (g_test_subprocess ()) + { + gpointer p, q; + + p = g_slice_alloc (237); + q = g_slice_alloc (259); + g_slice_free1 (237, p); + g_slice_free1 (259, q); + + g_slice_debug_tree_statistics (); + return; + } + g_test_trap_subprocess (NULL, 1000000, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*GSlice: MemChecker: root=NULL*"); + + if (oldval) + g_setenv ("G_SLICE", oldval, TRUE); +} + +static void +test_slice_debug (void) +{ + const gchar *oldval; + + oldval = g_getenv ("G_SLICE"); + g_setenv ("G_SLICE", "debug-blocks:always-malloc", TRUE); + + if (g_test_subprocess ()) + { + gpointer p, q; + + p = g_slice_alloc (237); + q = g_slice_alloc (259); + g_slice_free1 (237, p); + g_slice_free1 (259, q); + + g_slice_debug_tree_statistics (); + return; + } + g_test_trap_subprocess (NULL, 1000000, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*GSlice: MemChecker: * trunks, * branches, * old branches*"); + + if (oldval) + g_setenv ("G_SLICE", oldval, TRUE); + else + g_unsetenv ("G_SLICE"); +} +#endif + +static void +test_slice_copy (void) +{ + const gchar *block = "0123456789ABCDEF"; + gpointer p; + + p = g_slice_copy (12, block); + g_assert (memcmp (p, block, 12) == 0); + g_slice_free1 (12, p); +} + +typedef struct { + gint int1; + gint int2; + gchar byte; + gpointer next; + gint64 more; +} TestStruct; + +static void +test_chain (void) +{ + TestStruct *ts, *head; + + head = ts = g_slice_new (TestStruct); + ts->next = g_slice_new (TestStruct); + ts = ts->next; + ts->next = g_slice_new (TestStruct); + ts = ts->next; + ts->next = NULL; + + g_slice_free_chain (TestStruct, head, next); +} + +static gpointer chunks[4096][30]; + +static gpointer +thread_allocate (gpointer data) +{ + gint i; + gint b; + gint size; + gpointer p; + gpointer *loc; /* (atomic) */ + + for (i = 0; i < 10000; i++) + { + b = g_random_int_range (0, 30); + size = g_random_int_range (0, 4096); + loc = &(chunks[size][b]); + + p = g_atomic_pointer_get (loc); + if (p == NULL) + { + p = g_slice_alloc (size + 1); + if (!g_atomic_pointer_compare_and_exchange (loc, NULL, p)) + g_slice_free1 (size + 1, p); + } + else + { + if (g_atomic_pointer_compare_and_exchange (loc, p, NULL)) + g_slice_free1 (size + 1, p); + } + } + + return NULL; +} + +static void +test_allocate (void) +{ + GThread *threads[30]; + gint size; + gsize i; + + for (i = 0; i < 30; i++) + for (size = 1; size <= 4096; size++) + chunks[size - 1][i] = NULL; + + for (i = 0; i < G_N_ELEMENTS(threads); i++) + threads[i] = g_thread_create (thread_allocate, NULL, TRUE, NULL); + + for (i = 0; i < G_N_ELEMENTS(threads); i++) + g_thread_join (threads[i]); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + +#ifdef G_ENABLE_DEBUG + g_test_add_func ("/slice/nodebug", test_slice_nodebug); + g_test_add_func ("/slice/debug", test_slice_debug); +#endif + g_test_add_func ("/slice/copy", test_slice_copy); + g_test_add_func ("/slice/chain", test_chain); + g_test_add_func ("/slice/allocate", test_allocate); + + return g_test_run (); +} diff --git a/glib/tests/slist.c b/glib/tests/slist.c new file mode 100644 index 0000000..7c17573 --- /dev/null +++ b/glib/tests/slist.c @@ -0,0 +1,463 @@ +#include + +#define SIZE 50 +#define NUMBER_MIN 0000 +#define NUMBER_MAX 9999 + + +static guint32 array[SIZE]; + + +static gint +sort (gconstpointer p1, gconstpointer p2) +{ + gint32 a, b; + + a = GPOINTER_TO_INT (p1); + b = GPOINTER_TO_INT (p2); + + return (a > b ? +1 : a == b ? 0 : -1); +} + +/* + * gslist sort tests + */ +static void +test_slist_sort (void) +{ + GSList *slist = NULL; + gint i; + + for (i = 0; i < SIZE; i++) + slist = g_slist_append (slist, GINT_TO_POINTER (array[i])); + + slist = g_slist_sort (slist, sort); + for (i = 0; i < SIZE - 1; i++) + { + gpointer p1, p2; + + p1 = g_slist_nth_data (slist, i); + p2 = g_slist_nth_data (slist, i+1); + + g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2)); + } + + g_slist_free (slist); +} + +static void +test_slist_sort_with_data (void) +{ + GSList *slist = NULL; + gint i; + + for (i = 0; i < SIZE; i++) + slist = g_slist_append (slist, GINT_TO_POINTER (array[i])); + + slist = g_slist_sort_with_data (slist, (GCompareDataFunc)sort, NULL); + for (i = 0; i < SIZE - 1; i++) + { + gpointer p1, p2; + + p1 = g_slist_nth_data (slist, i); + p2 = g_slist_nth_data (slist, i+1); + + g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2)); + } + + g_slist_free (slist); +} + +/* Test that the sort is stable. */ +static void +test_slist_sort_stable (void) +{ + GSList *list = NULL; /* (element-type utf8) */ + GSList *copy = NULL; /* (element-type utf8) */ + gsize i; + + /* Build a test list, already ordered. */ + for (i = 0; i < SIZE; i++) + list = g_slist_append (list, g_strdup_printf ("%" G_GSIZE_FORMAT, i / 5)); + + /* Take a copy and sort it. */ + copy = g_slist_copy (list); + copy = g_slist_sort (copy, (GCompareFunc) g_strcmp0); + + /* Compare the two lists, checking pointers are equal to ensure the elements + * have been kept stable. */ + for (i = 0; i < SIZE; i++) + { + gpointer p1, p2; + + p1 = g_slist_nth_data (list, i); + p2 = g_slist_nth_data (list, i); + + g_assert (p1 == p2); + } + + g_slist_free (copy); + g_slist_free_full (list, g_free); +} + +static void +test_slist_insert_sorted (void) +{ + GSList *slist = NULL; + gint i; + + for (i = 0; i < SIZE; i++) + slist = g_slist_insert_sorted (slist, GINT_TO_POINTER (array[i]), sort); + + for (i = 0; i < SIZE - 1; i++) + { + gpointer p1, p2; + + p1 = g_slist_nth_data (slist, i); + p2 = g_slist_nth_data (slist, i+1); + + g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2)); + } + + g_slist_free (slist); +} + +static void +test_slist_insert_sorted_with_data (void) +{ + GSList *slist = NULL; + gint i; + + for (i = 0; i < SIZE; i++) + slist = g_slist_insert_sorted_with_data (slist, + GINT_TO_POINTER (array[i]), + (GCompareDataFunc)sort, + NULL); + + for (i = 0; i < SIZE - 1; i++) + { + gpointer p1, p2; + + p1 = g_slist_nth_data (slist, i); + p2 = g_slist_nth_data (slist, i+1); + + g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2)); + } + + g_slist_free (slist); +} + +static void +test_slist_reverse (void) +{ + GSList *slist = NULL; + GSList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + slist = g_slist_append (slist, &nums[i]); + + slist = g_slist_reverse (slist); + + for (i = 0; i < 10; i++) + { + st = g_slist_nth (slist, i); + g_assert (*((gint*) st->data) == (9 - i)); + } + + g_slist_free (slist); +} + +static void +test_slist_nth (void) +{ + GSList *slist = NULL; + GSList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + slist = g_slist_append (slist, &nums[i]); + + for (i = 0; i < 10; i++) + { + st = g_slist_nth (slist, i); + g_assert (*((gint*) st->data) == i); + } + + g_slist_free (slist); +} + +static void +test_slist_remove (void) +{ + GSList *slist = NULL; + GSList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + { + slist = g_slist_append (slist, &nums[i]); + slist = g_slist_append (slist, &nums[i]); + } + + g_assert_cmpint (g_slist_length (slist), ==, 20); + + for (i = 0; i < 10; i++) + { + slist = g_slist_remove (slist, &nums[i]); + } + + g_assert_cmpint (g_slist_length (slist), ==, 10); + + for (i = 0; i < 10; i++) + { + st = g_slist_nth (slist, i); + g_assert (*((gint*) st->data) == i); + } + + g_slist_free (slist); +} + +static void +test_slist_remove_all (void) +{ + GSList *slist = NULL; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + { + slist = g_slist_append (slist, &nums[i]); + slist = g_slist_append (slist, &nums[i]); + } + + g_assert_cmpint (g_slist_length (slist), ==, 20); + + for (i = 0; i < 5; i++) + { + slist = g_slist_remove_all (slist, &nums[2 * i + 1]); + slist = g_slist_remove_all (slist, &nums[8 - 2 * i]); + } + + g_assert_cmpint (g_slist_length (slist), ==, 0); + g_assert (slist == NULL); +} + +static void +test_slist_insert (void) +{ + gpointer a = "a"; + gpointer b = "b"; + gpointer c = "c"; + GSList *slist = NULL; + GSList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + slist = g_slist_insert_before (NULL, NULL, &nums[1]); + slist = g_slist_insert (slist, &nums[3], 1); + slist = g_slist_insert (slist, &nums[4], -1); + slist = g_slist_insert (slist, &nums[0], 0); + slist = g_slist_insert (slist, &nums[5], 100); + slist = g_slist_insert_before (slist, NULL, &nums[6]); + slist = g_slist_insert_before (slist, slist->next->next, &nums[2]); + + slist = g_slist_insert (slist, &nums[9], 7); + slist = g_slist_insert (slist, &nums[8], 7); + slist = g_slist_insert (slist, &nums[7], 7); + + for (i = 0; i < 10; i++) + { + st = g_slist_nth (slist, i); + g_assert (*((gint*) st->data) == i); + } + + g_slist_free (slist); + + slist = g_slist_insert (NULL, a, 1); + g_assert (slist->data == a); + g_assert (slist->next == NULL); + g_slist_free (slist); + + slist = g_slist_append (NULL, a); + slist = g_slist_append (slist, b); + slist = g_slist_insert (slist, c, 5); + + g_assert (slist->next->next->data == c); + g_assert (slist->next->next->next == NULL); + g_slist_free (slist); + + slist = g_slist_append (NULL, a); + slist = g_slist_insert_before (slist, slist, b); + g_assert (slist->data == b); + g_assert (slist->next->data == a); + g_assert (slist->next->next == NULL); + g_slist_free (slist); +} + +static gint +find_num (gconstpointer l, gconstpointer data) +{ + return *(gint*)l - GPOINTER_TO_INT(data); +} + +static void +test_slist_position (void) +{ + GSList *slist = NULL; + GSList *st; + gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint i; + + for (i = 0; i < 10; i++) + { + slist = g_slist_append (slist, &nums[i]); + } + + g_assert_cmpint (g_slist_index (slist, NULL), ==, -1); + g_assert_cmpint (g_slist_position (slist, NULL), ==, -1); + + for (i = 0; i < 10; i++) + { + g_assert_cmpint (g_slist_index (slist, &nums[i]), ==, i); + st = g_slist_find_custom (slist, GINT_TO_POINTER(i), find_num); + g_assert (st != NULL); + g_assert_cmpint (g_slist_position (slist, st), ==, i); + } + + st = g_slist_find_custom (slist, GINT_TO_POINTER (1000), find_num); + g_assert (st == NULL); + + g_slist_free (slist); +} + +static void +test_slist_concat (void) +{ + gpointer a = "a"; + gpointer b = "b"; + GSList *s1, *s2, *s; + + s1 = g_slist_append (NULL, a); + s2 = g_slist_append (NULL, b); + s = g_slist_concat (s1, s2); + g_assert (s->data == a); + g_assert (s->next->data == b); + g_assert (s->next->next == NULL); + g_slist_free (s); + + s1 = g_slist_append (NULL, a); + + s = g_slist_concat (NULL, s1); + g_assert_cmpint (g_slist_length (s), ==, 1); + s = g_slist_concat (s1, NULL); + g_assert_cmpint (g_slist_length (s), ==, 1); + + g_slist_free (s); + + s = g_slist_concat (NULL, NULL); + g_assert (s == NULL); +} + +static void +test_slist_copy (void) +{ + GSList *slist = NULL, *copy; + GSList *s1, *s2; + guint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gsize i; + + /* Copy and test a many-element list. */ + for (i = 0; i < 10; i++) + slist = g_slist_append (slist, &nums[i]); + + copy = g_slist_copy (slist); + + g_assert_cmpuint (g_slist_length (copy), ==, g_slist_length (slist)); + + for (s1 = copy, s2 = slist; s1 != NULL && s2 != NULL; s1 = s1->next, s2 = s2->next) + g_assert (s1->data == s2->data); + + g_slist_free (copy); + g_slist_free (slist); + + /* Copy a NULL list. */ + copy = g_slist_copy (NULL); + g_assert_null (copy); +} + +static gpointer +copy_and_count_string (gconstpointer src, + gpointer data) +{ + const gchar *str = src; + gsize *count = data; + + *count = *count + 1; + return g_strdup (str); +} + +static void +test_slist_copy_deep (void) +{ + GSList *slist = NULL, *copy; + GSList *s1, *s2; + gsize count; + + /* Deep-copy a simple list. */ + slist = g_slist_append (slist, "a"); + slist = g_slist_append (slist, "b"); + slist = g_slist_append (slist, "c"); + + count = 0; + copy = g_slist_copy_deep (slist, copy_and_count_string, &count); + + g_assert_cmpuint (count, ==, g_slist_length (slist)); + g_assert_cmpuint (g_slist_length (copy), ==, count); + for (s1 = slist, s2 = copy; s1 != NULL && s2 != NULL; s1 = s1->next, s2 = s2->next) + { + g_assert_cmpstr (s1->data, ==, s2->data); + g_assert (s1->data != s2->data); + } + + g_slist_free_full (copy, g_free); + g_slist_free (slist); + + /* Try with an empty list. */ + count = 0; + copy = g_slist_copy_deep (NULL, copy_and_count_string, &count); + g_assert_cmpuint (count, ==, 0); + g_assert_null (copy); +} + +int +main (int argc, char *argv[]) +{ + gint i; + + g_test_init (&argc, &argv, NULL); + + /* Create an array of random numbers. */ + for (i = 0; i < SIZE; i++) + array[i] = g_test_rand_int_range (NUMBER_MIN, NUMBER_MAX); + + g_test_add_func ("/slist/sort", test_slist_sort); + g_test_add_func ("/slist/sort-with-data", test_slist_sort_with_data); + g_test_add_func ("/slist/sort/stable", test_slist_sort_stable); + g_test_add_func ("/slist/insert-sorted", test_slist_insert_sorted); + g_test_add_func ("/slist/insert-sorted-with-data", test_slist_insert_sorted_with_data); + g_test_add_func ("/slist/reverse", test_slist_reverse); + g_test_add_func ("/slist/nth", test_slist_nth); + g_test_add_func ("/slist/remove", test_slist_remove); + g_test_add_func ("/slist/remove-all", test_slist_remove_all); + g_test_add_func ("/slist/insert", test_slist_insert); + g_test_add_func ("/slist/position", test_slist_position); + g_test_add_func ("/slist/concat", test_slist_concat); + g_test_add_func ("/slist/copy", test_slist_copy); + g_test_add_func ("/slist/copy/deep", test_slist_copy_deep); + + return g_test_run (); +} diff --git a/glib/tests/sort.c b/glib/tests/sort.c new file mode 100644 index 0000000..eb748c5 --- /dev/null +++ b/glib/tests/sort.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include + +static int +int_compare_data (gconstpointer p1, gconstpointer p2, gpointer data) +{ + const gint *i1 = p1; + const gint *i2 = p2; + + return *i1 - *i2; +} + +static void +test_sort_basic (void) +{ + gint *data; + gint i; + + data = g_malloc (10000 * sizeof (int)); + for (i = 0; i < 10000; i++) + { + data[i] = g_random_int_range (0, 10000); + } + + g_qsort_with_data (data, 10000, sizeof (int), int_compare_data, NULL); + + for (i = 1; i < 10000; i++) + g_assert_cmpint (data[i -1], <=, data[i]); + + g_free (data); +} + +static void +test_sort_zero_elements (void) +{ + gint *data, *data_copy; + gsize i; + + data = g_malloc (100 * sizeof (int)); + data_copy = g_malloc (100 * sizeof (int)); + for (i = 0; i < 100; i++) + { + data[i] = g_random_int (); + data_copy[i] = data[i]; + } + + /* 0 elements is a valid case */ + g_qsort_with_data (data, 0, sizeof (int), int_compare_data, NULL); + + for (i = 0; i < 100; i++) + g_assert_cmpint (data[i], ==, data_copy[i]); + + g_free (data); + g_free (data_copy); +} + +typedef struct { + int val; + int i; +} SortItem; + +typedef struct { + int val; + int i; + int data[16]; +} BigItem; + +static int +item_compare_data (gconstpointer p1, gconstpointer p2, gpointer data) +{ + const SortItem *i1 = p1; + const SortItem *i2 = p2; + + return i1->val - i2->val; +} + +static void +test_sort_stable (void) +{ + SortItem *data; + gint i; + + data = g_malloc (10000 * sizeof (SortItem)); + for (i = 0; i < 10000; i++) + { + data[i].val = g_random_int_range (0, 10000); + data[i].i = i; + } + + g_qsort_with_data (data, 10000, sizeof (SortItem), item_compare_data, NULL); + + for (i = 1; i < 10000; i++) + { + g_assert_cmpint (data[i -1].val, <=, data[i].val); + if (data[i -1].val == data[i].val) + g_assert_cmpint (data[i -1].i, <, data[i].i); + } + g_free (data); +} + +static void +test_sort_big (void) +{ + BigItem *data; + gint i; + + data = g_malloc (10000 * sizeof (BigItem)); + for (i = 0; i < 10000; i++) + { + data[i].val = g_random_int_range (0, 10000); + data[i].i = i; + } + + g_qsort_with_data (data, 10000, sizeof (BigItem), item_compare_data, NULL); + + for (i = 1; i < 10000; i++) + { + g_assert_cmpint (data[i -1].val, <=, data[i].val); + if (data[i -1].val == data[i].val) + g_assert_cmpint (data[i -1].i, <, data[i].i); + } + g_free (data); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/sort/basic", test_sort_basic); + g_test_add_func ("/sort/zero-elements", test_sort_zero_elements); + g_test_add_func ("/sort/stable", test_sort_stable); + g_test_add_func ("/sort/big", test_sort_big); + + return g_test_run (); +} diff --git a/glib/tests/spawn-multithreaded.c b/glib/tests/spawn-multithreaded.c new file mode 100644 index 0000000..8dbc7bf --- /dev/null +++ b/glib/tests/spawn-multithreaded.c @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2011 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include + +#include +#include + +#include + +static char *echo_prog_path; +static char *sleep_prog_path; + +#ifdef G_OS_UNIX +#include +#endif + +#ifdef G_OS_WIN32 +#include +#endif + +typedef struct +{ + GMainLoop *main_loop; + gint *n_alive; /* (atomic) */ + gint ttl; /* seconds */ + GMainLoop *thread_main_loop; /* (nullable) */ +} SpawnChildsData; + +static GPid +get_a_child (gint ttl) +{ + GPid pid; + +#ifdef G_OS_WIN32 + STARTUPINFO si; + PROCESS_INFORMATION pi; + gchar *cmdline; + + memset (&si, 0, sizeof (si)); + si.cb = sizeof (&si); + memset (&pi, 0, sizeof (pi)); + + cmdline = g_strdup_printf ("%s %d", sleep_prog_path, ttl); + + if (!CreateProcess (NULL, cmdline, NULL, NULL, + FALSE, 0, NULL, NULL, &si, &pi)) + g_error ("CreateProcess failed: %s", + g_win32_error_message (GetLastError ())); + + g_free (cmdline); + + CloseHandle (pi.hThread); + pid = pi.hProcess; + + return pid; +#else + pid = fork (); + if (pid < 0) + exit (1); + + if (pid > 0) + return pid; + + sleep (ttl); + _exit (0); +#endif /* G_OS_WIN32 */ +} + +static void +child_watch_callback (GPid pid, gint status, gpointer user_data) +{ + SpawnChildsData *data = user_data; + + g_test_message ("Child %" G_PID_FORMAT " (ttl %d) exited, status %d", + pid, data->ttl, status); + + g_spawn_close_pid (pid); + + if (g_atomic_int_dec_and_test (data->n_alive)) + g_main_loop_quit (data->main_loop); + if (data->thread_main_loop != NULL) + g_main_loop_quit (data->thread_main_loop); +} + +static gpointer +start_thread (gpointer user_data) +{ + GMainLoop *new_main_loop; + GSource *source; + GPid pid; + SpawnChildsData *data = user_data; + gint ttl = data->ttl; + GMainContext *new_main_context = NULL; + + new_main_context = g_main_context_new (); + new_main_loop = g_main_loop_new (new_main_context, FALSE); + data->thread_main_loop = new_main_loop; + + pid = get_a_child (ttl); + source = g_child_watch_source_new (pid); + g_source_set_callback (source, + (GSourceFunc) child_watch_callback, data, NULL); + g_source_attach (source, g_main_loop_get_context (new_main_loop)); + g_source_unref (source); + + g_test_message ("Created pid: %" G_PID_FORMAT " (ttl %d)", pid, ttl); + + g_main_loop_run (new_main_loop); + g_main_loop_unref (new_main_loop); + g_main_context_unref (new_main_context); + + return NULL; +} + +static gboolean +quit_loop (gpointer data) +{ + GMainLoop *main_loop = data; + + g_main_loop_quit (main_loop); + + return TRUE; +} + +static void +test_spawn_childs (void) +{ + GPid pid; + GMainLoop *main_loop = NULL; + SpawnChildsData child1_data = { 0, }, child2_data = { 0, }; + gint n_alive; + guint timeout_id; + + main_loop = g_main_loop_new (NULL, FALSE); + +#ifdef G_OS_WIN32 + system ("cd ."); +#else + system ("true"); +#endif + + n_alive = 2; + timeout_id = g_timeout_add_seconds (30, quit_loop, main_loop); + + child1_data.main_loop = main_loop; + child1_data.ttl = 1; + child1_data.n_alive = &n_alive; + pid = get_a_child (child1_data.ttl); + g_child_watch_add (pid, + (GChildWatchFunc) child_watch_callback, + &child1_data); + + child2_data.main_loop = main_loop; + child2_data.ttl = 2; + child2_data.n_alive = &n_alive; + pid = get_a_child (child2_data.ttl); + g_child_watch_add (pid, + (GChildWatchFunc) child_watch_callback, + &child2_data); + + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + g_source_remove (timeout_id); + + g_assert_cmpint (g_atomic_int_get (&n_alive), ==, 0); +} + +static void +test_spawn_childs_threads (void) +{ + GMainLoop *main_loop = NULL; + SpawnChildsData thread1_data = { 0, }, thread2_data = { 0, }; + gint n_alive; + guint timeout_id; + GThread *thread1, *thread2; + + main_loop = g_main_loop_new (NULL, FALSE); + +#ifdef G_OS_WIN32 + system ("cd ."); +#else + system ("true"); +#endif + + n_alive = 2; + timeout_id = g_timeout_add_seconds (30, quit_loop, main_loop); + + thread1_data.main_loop = main_loop; + thread1_data.n_alive = &n_alive; + thread1_data.ttl = 1; /* seconds */ + thread1 = g_thread_new (NULL, start_thread, &thread1_data); + + thread2_data.main_loop = main_loop; + thread2_data.n_alive = &n_alive; + thread2_data.ttl = 2; /* seconds */ + thread2 = g_thread_new (NULL, start_thread, &thread2_data); + + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + g_source_remove (timeout_id); + + g_assert_cmpint (g_atomic_int_get (&n_alive), ==, 0); + + g_thread_join (g_steal_pointer (&thread2)); + g_thread_join (g_steal_pointer (&thread1)); +} + +static void +multithreaded_test_run (GThreadFunc function) +{ + guint i; + GPtrArray *threads = g_ptr_array_new (); + guint n_threads; + + /* Limit to 64, otherwise we may hit file descriptor limits and such */ + n_threads = MIN (g_get_num_processors () * 2, 64); + + for (i = 0; i < n_threads; i++) + { + GThread *thread; + + thread = g_thread_new ("test", function, GUINT_TO_POINTER (i)); + g_ptr_array_add (threads, thread); + } + + for (i = 0; i < n_threads; i++) + { + gpointer ret; + ret = g_thread_join (g_ptr_array_index (threads, i)); + g_assert_cmpint (GPOINTER_TO_UINT (ret), ==, i); + } + g_ptr_array_free (threads, TRUE); +} + +static gpointer +test_spawn_sync_multithreaded_instance (gpointer data) +{ + guint tnum = GPOINTER_TO_UINT (data); + GError *error = NULL; + GPtrArray *argv; + char *arg; + char *stdout_str; + int estatus; + + arg = g_strdup_printf ("thread %u", tnum); + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, echo_prog_path); + g_ptr_array_add (argv, arg); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char**)argv->pdata, NULL, G_SPAWN_DEFAULT, NULL, NULL, &stdout_str, NULL, &estatus, &error); + g_assert_no_error (error); + g_assert_cmpstr (arg, ==, stdout_str); + g_free (arg); + g_free (stdout_str); + g_ptr_array_free (argv, TRUE); + + return GUINT_TO_POINTER (tnum); +} + +static void +test_spawn_sync_multithreaded (void) +{ + multithreaded_test_run (test_spawn_sync_multithreaded_instance); +} + +typedef struct { + GMainLoop *loop; + gboolean child_exited; + gboolean stdout_done; + GString *stdout_buf; +} SpawnAsyncMultithreadedData; + +static gboolean +on_child_exited (GPid pid, + gint status, + gpointer datap) +{ + SpawnAsyncMultithreadedData *data = datap; + + data->child_exited = TRUE; + if (data->child_exited && data->stdout_done) + g_main_loop_quit (data->loop); + + return G_SOURCE_REMOVE; +} + +static gboolean +on_child_stdout (GIOChannel *channel, + GIOCondition condition, + gpointer datap) +{ + char buf[1024]; + GError *error = NULL; + gsize bytes_read; + GIOStatus status; + SpawnAsyncMultithreadedData *data = datap; + + read: + status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error); + if (status == G_IO_STATUS_NORMAL) + { + g_string_append_len (data->stdout_buf, buf, (gssize) bytes_read); + if (bytes_read == sizeof (buf)) + goto read; + } + else if (status == G_IO_STATUS_EOF) + { + g_string_append_len (data->stdout_buf, buf, (gssize) bytes_read); + data->stdout_done = TRUE; + } + else if (status == G_IO_STATUS_ERROR) + { + g_error ("Error reading from child stdin: %s", error->message); + } + + if (data->child_exited && data->stdout_done) + g_main_loop_quit (data->loop); + + return !data->stdout_done; +} + +static gpointer +test_spawn_async_multithreaded_instance (gpointer thread_data) +{ + guint tnum = GPOINTER_TO_UINT (thread_data); + GError *error = NULL; + GPtrArray *argv; + char *arg; + GPid pid; + GMainContext *context; + GMainLoop *loop; + GIOChannel *channel; + GSource *source; + int child_stdout_fd; + SpawnAsyncMultithreadedData data; + + context = g_main_context_new (); + loop = g_main_loop_new (context, TRUE); + + arg = g_strdup_printf ("thread %u", tnum); + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, echo_prog_path); + g_ptr_array_add (argv, arg); + g_ptr_array_add (argv, NULL); + + g_spawn_async_with_pipes (NULL, (char**)argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL, + &child_stdout_fd, NULL, &error); + g_assert_no_error (error); + g_ptr_array_free (argv, TRUE); + + data.loop = loop; + data.stdout_done = FALSE; + data.child_exited = FALSE; + data.stdout_buf = g_string_new (0); + + source = g_child_watch_source_new (pid); + g_source_set_callback (source, (GSourceFunc)on_child_exited, &data, NULL); + g_source_attach (source, context); + g_source_unref (source); + + channel = g_io_channel_unix_new (child_stdout_fd); + source = g_io_create_watch (channel, G_IO_IN | G_IO_HUP); + g_source_set_callback (source, (GSourceFunc)on_child_stdout, &data, NULL); + g_source_attach (source, context); + g_source_unref (source); + + g_main_loop_run (loop); + + g_assert_true (data.child_exited); + g_assert_true (data.stdout_done); + g_assert_cmpstr (data.stdout_buf->str, ==, arg); + g_string_free (data.stdout_buf, TRUE); + + g_io_channel_unref (channel); + g_main_context_unref (context); + g_main_loop_unref (loop); + + g_free (arg); + + return GUINT_TO_POINTER (tnum); +} + +static void +test_spawn_async_multithreaded (void) +{ + multithreaded_test_run (test_spawn_async_multithreaded_instance); +} + +int +main (int argc, + char *argv[]) +{ + char *dirname; + int ret; + + g_test_init (&argc, &argv, NULL); + + dirname = g_path_get_dirname (argv[0]); + echo_prog_path = g_build_filename (dirname, "test-spawn-echo" EXEEXT, NULL); + sleep_prog_path = g_build_filename (dirname, "test-spawn-sleep" EXEEXT, NULL); + g_free (dirname); + + g_assert (g_file_test (echo_prog_path, G_FILE_TEST_EXISTS)); +#ifdef G_OS_WIN32 + g_assert (g_file_test (sleep_prog_path, G_FILE_TEST_EXISTS)); +#endif + + g_test_add_func ("/gthread/spawn-childs", test_spawn_childs); + g_test_add_func ("/gthread/spawn-childs-threads", test_spawn_childs_threads); + g_test_add_func ("/gthread/spawn-sync", test_spawn_sync_multithreaded); + g_test_add_func ("/gthread/spawn-async", test_spawn_async_multithreaded); + + ret = g_test_run(); + + g_free (echo_prog_path); + g_free (sleep_prog_path); + + return ret; +} diff --git a/glib/tests/spawn-path-search-helper.c b/glib/tests/spawn-path-search-helper.c new file mode 100644 index 0000000..37be43b --- /dev/null +++ b/glib/tests/spawn-path-search-helper.c @@ -0,0 +1,171 @@ +/* + * Copyright 2021 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * . + */ + +#include +#include + +#include + +#ifdef G_OS_UNIX +#include +#include +#endif + +static void +child_setup (gpointer user_data) +{ +} + +typedef struct +{ + int wait_status; + gboolean done; +} ChildStatus; + +static ChildStatus child_status = { -1, FALSE }; + +static void +child_watch_cb (GPid pid, + gint status, + gpointer user_data) +{ + child_status.wait_status = status; + child_status.done = TRUE; +} + +int +main (int argc, + char **argv) +{ + gboolean search_path = FALSE; + gboolean search_path_from_envp = FALSE; + gboolean slow_path = FALSE; + gboolean unset_path_in_envp = FALSE; + gchar *chdir_child = NULL; + gchar *set_path_in_envp = NULL; + gchar **envp = NULL; + GOptionEntry entries[] = + { + { "chdir-child", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &chdir_child, + "Run PROGRAM in this working directory", NULL }, + { "search-path", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &search_path, + "Search PATH for PROGRAM", NULL }, + { "search-path-from-envp", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &search_path_from_envp, + "Search PATH from specified environment", NULL }, + { "set-path-in-envp", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &set_path_in_envp, + "Set PATH in specified environment to this value", "PATH", }, + { "unset-path-in-envp", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &unset_path_in_envp, + "Unset PATH in specified environment", NULL }, + { "slow-path", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &slow_path, + "Use a child-setup function to avoid the posix_spawn fast path", NULL }, + G_OPTION_ENTRY_NULL + }; + GError *error = NULL; + int ret = 1; + GSpawnFlags spawn_flags = G_SPAWN_DO_NOT_REAP_CHILD; + GPid pid; + GOptionContext *context = NULL; + + context = g_option_context_new ("PROGRAM [ARGS...]"); + g_option_context_add_main_entries (context, entries, NULL); + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + ret = 2; + goto out; + } + + if (argc < 2) + { + g_set_error (&error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, + "Usage: %s [OPTIONS] PROGRAM [ARGS...]", argv[0]); + ret = 2; + goto out; + } + + envp = g_get_environ (); + + if (set_path_in_envp != NULL && unset_path_in_envp) + { + g_set_error (&error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, + "Cannot both set PATH and unset it"); + ret = 2; + goto out; + } + + if (set_path_in_envp != NULL) + envp = g_environ_setenv (envp, "PATH", set_path_in_envp, TRUE); + + if (unset_path_in_envp) + envp = g_environ_unsetenv (envp, "PATH"); + + if (search_path) + spawn_flags |= G_SPAWN_SEARCH_PATH; + + if (search_path_from_envp) + spawn_flags |= G_SPAWN_SEARCH_PATH_FROM_ENVP; + + if (!g_spawn_async_with_pipes (chdir_child, + &argv[1], + envp, + spawn_flags, + slow_path ? child_setup : NULL, + NULL, /* user_data */ + &pid, + NULL, /* stdin */ + NULL, /* stdout */ + NULL, /* stderr */ + &error)) + { + ret = 1; + goto out; + } + + g_child_watch_add (pid, child_watch_cb, NULL); + + while (!child_status.done) + g_main_context_iteration (NULL, TRUE); + + g_spawn_close_pid (pid); + +#ifdef G_OS_UNIX + if (WIFEXITED (child_status.wait_status)) + ret = WEXITSTATUS (child_status.wait_status); + else + ret = 1; +#else + ret = child_status.wait_status; +#endif + +out: + if (error != NULL) + fprintf (stderr, "%s\n", error->message); + + g_free (set_path_in_envp); + g_free (chdir_child); + g_clear_error (&error); + g_strfreev (envp); + g_option_context_free (context); + return ret; +} diff --git a/glib/tests/spawn-path-search.c b/glib/tests/spawn-path-search.c new file mode 100644 index 0000000..221849d --- /dev/null +++ b/glib/tests/spawn-path-search.c @@ -0,0 +1,490 @@ +/* + * Copyright 2021 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * . + */ + +#include + +#ifdef G_OS_UNIX +#include +#include +#endif + +static gboolean +skip_win32 (void) +{ +#ifdef G_OS_WIN32 + g_test_skip ("The test manipulate PATH, and breaks DLL lookups."); + return TRUE; +#else + return FALSE; +#endif +} + +static void +test_do_not_search (void) +{ + GPtrArray *argv = g_ptr_array_new_with_free_func (g_free); + gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL); + gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL); + gchar **envp = g_get_environ (); + gchar *out = NULL; + gchar *err = NULL; + GError *error = NULL; + int wait_status = -1; + + g_test_summary ("Without G_SPAWN_SEARCH_PATH, spawn-test-helper " + "means ./spawn-test-helper."); + + if (skip_win32 ()) + return; + + envp = g_environ_setenv (envp, "PATH", subdir, TRUE); + + g_ptr_array_add (argv, + g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL)); + g_ptr_array_add (argv, g_strdup ("--")); + g_ptr_array_add (argv, g_strdup ("spawn-test-helper")); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (here, + (char **) argv->pdata, + envp, + G_SPAWN_DEFAULT, + NULL, /* child setup */ + NULL, /* user data */ + &out, + &err, + &wait_status, + &error); + g_assert_no_error (error); + + g_test_message ("%s", out); + g_test_message ("%s", err); + g_assert_nonnull (strstr (err, "this is spawn-test-helper from glib/tests")); + +#ifdef G_OS_UNIX + g_assert_true (WIFEXITED (wait_status)); + g_assert_cmpint (WEXITSTATUS (wait_status), ==, 0); +#endif + + g_strfreev (envp); + g_free (here); + g_free (subdir); + g_free (out); + g_free (err); + g_ptr_array_unref (argv); +} + +static void +test_search_path (void) +{ + GPtrArray *argv = g_ptr_array_new_with_free_func (g_free); + gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL); + gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL); + gchar **envp = g_get_environ (); + gchar *out = NULL; + gchar *err = NULL; + GError *error = NULL; + int wait_status = -1; + + g_test_summary ("With G_SPAWN_SEARCH_PATH, spawn-test-helper " + "means $PATH/spawn-test-helper."); + + if (skip_win32 ()) + return; + + envp = g_environ_setenv (envp, "PATH", subdir, TRUE); + + g_ptr_array_add (argv, + g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL)); + g_ptr_array_add (argv, g_strdup ("--search-path")); + g_ptr_array_add (argv, g_strdup ("--")); + g_ptr_array_add (argv, g_strdup ("spawn-test-helper")); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (here, + (char **) argv->pdata, + envp, + G_SPAWN_DEFAULT, + NULL, /* child setup */ + NULL, /* user data */ + &out, + &err, + &wait_status, + &error); + g_assert_no_error (error); + + g_test_message ("%s", out); + g_test_message ("%s", err); + g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir")); + +#ifdef G_OS_UNIX + g_assert_true (WIFEXITED (wait_status)); + g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5); +#endif + + g_strfreev (envp); + g_free (here); + g_free (subdir); + g_free (out); + g_free (err); + g_ptr_array_unref (argv); +} + +static void +test_search_path_from_envp (void) +{ + GPtrArray *argv = g_ptr_array_new_with_free_func (g_free); + gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL); + gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL); + gchar **envp = g_get_environ (); + gchar *out = NULL; + gchar *err = NULL; + GError *error = NULL; + int wait_status = -1; + + g_test_summary ("With G_SPAWN_SEARCH_PATH_FROM_ENVP, spawn-test-helper " + "means $PATH/spawn-test-helper with $PATH from envp."); + + if (skip_win32 ()) + return; + + envp = g_environ_setenv (envp, "PATH", here, TRUE); + + g_ptr_array_add (argv, + g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL)); + g_ptr_array_add (argv, g_strdup ("--search-path-from-envp")); + g_ptr_array_add (argv, g_strdup ("--set-path-in-envp")); + g_ptr_array_add (argv, g_strdup (subdir)); + g_ptr_array_add (argv, g_strdup ("--")); + g_ptr_array_add (argv, g_strdup ("spawn-test-helper")); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (here, + (char **) argv->pdata, + envp, + G_SPAWN_DEFAULT, + NULL, /* child setup */ + NULL, /* user data */ + &out, + &err, + &wait_status, + &error); + g_assert_no_error (error); + + g_test_message ("%s", out); + g_test_message ("%s", err); + g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir")); + +#ifdef G_OS_UNIX + g_assert_true (WIFEXITED (wait_status)); + g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5); +#endif + + g_strfreev (envp); + g_free (here); + g_free (subdir); + g_free (out); + g_free (err); + g_ptr_array_unref (argv); +} + +static void +test_search_path_ambiguous (void) +{ + GPtrArray *argv = g_ptr_array_new_with_free_func (g_free); + gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL); + gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL); + gchar **envp = g_get_environ (); + gchar *out = NULL; + gchar *err = NULL; + GError *error = NULL; + int wait_status = -1; + + g_test_summary ("With G_SPAWN_SEARCH_PATH and G_SPAWN_SEARCH_PATH_FROM_ENVP, " + "the latter wins."); + + if (skip_win32 ()) + return; + + envp = g_environ_setenv (envp, "PATH", here, TRUE); + + g_ptr_array_add (argv, + g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL)); + g_ptr_array_add (argv, g_strdup ("--search-path")); + g_ptr_array_add (argv, g_strdup ("--search-path-from-envp")); + g_ptr_array_add (argv, g_strdup ("--set-path-in-envp")); + g_ptr_array_add (argv, g_strdup (subdir)); + g_ptr_array_add (argv, g_strdup ("--")); + g_ptr_array_add (argv, g_strdup ("spawn-test-helper")); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (here, + (char **) argv->pdata, + envp, + G_SPAWN_DEFAULT, + NULL, /* child setup */ + NULL, /* user data */ + &out, + &err, + &wait_status, + &error); + g_assert_no_error (error); + + g_test_message ("%s", out); + g_test_message ("%s", err); + g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir")); + +#ifdef G_OS_UNIX + g_assert_true (WIFEXITED (wait_status)); + g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5); +#endif + + g_strfreev (envp); + g_free (here); + g_free (subdir); + g_free (out); + g_free (err); + g_ptr_array_unref (argv); +} + +static void +test_search_path_fallback_in_environ (void) +{ + GPtrArray *argv = g_ptr_array_new_with_free_func (g_free); + gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL); + gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL); + gchar **envp = g_get_environ (); + gchar *out = NULL; + gchar *err = NULL; + GError *error = NULL; + int wait_status = -1; + + g_test_summary ("With G_SPAWN_SEARCH_PATH but no PATH, a fallback is used."); + + if (skip_win32 ()) + return; + + /* We can't make a meaningful assertion about what the fallback *is*, + * but we can assert that it *includes* the current working directory. */ + + if (g_file_test ("/usr/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE) || + g_file_test ("/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE)) + { + g_test_skip ("Not testing fallback with unknown spawn-test-helper " + "executable in /usr/bin:/bin"); + return; + } + + envp = g_environ_unsetenv (envp, "PATH"); + + g_ptr_array_add (argv, + g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL)); + g_ptr_array_add (argv, g_strdup ("--search-path")); + g_ptr_array_add (argv, g_strdup ("--set-path-in-envp")); + g_ptr_array_add (argv, g_strdup (subdir)); + g_ptr_array_add (argv, g_strdup ("--")); + g_ptr_array_add (argv, g_strdup ("spawn-test-helper")); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (here, + (char **) argv->pdata, + envp, + G_SPAWN_DEFAULT, + NULL, /* child setup */ + NULL, /* user data */ + &out, + &err, + &wait_status, + &error); + g_assert_no_error (error); + + g_test_message ("%s", out); + g_test_message ("%s", err); + g_assert_nonnull (strstr (err, "this is spawn-test-helper from glib/tests")); + +#ifdef G_OS_UNIX + g_assert_true (WIFEXITED (wait_status)); + g_assert_cmpint (WEXITSTATUS (wait_status), ==, 0); +#endif + + g_strfreev (envp); + g_free (here); + g_free (subdir); + g_free (out); + g_free (err); + g_ptr_array_unref (argv); +} + +static void +test_search_path_fallback_in_envp (void) +{ + GPtrArray *argv = g_ptr_array_new_with_free_func (g_free); + gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL); + gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL); + gchar **envp = g_get_environ (); + gchar *out = NULL; + gchar *err = NULL; + GError *error = NULL; + int wait_status = -1; + + g_test_summary ("With G_SPAWN_SEARCH_PATH_FROM_ENVP but no PATH, a fallback is used."); + /* We can't make a meaningful assertion about what the fallback *is*, + * but we can assert that it *includes* the current working directory. */ + + if (skip_win32 ()) + return; + + if (g_file_test ("/usr/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE) || + g_file_test ("/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE)) + { + g_test_skip ("Not testing fallback with unknown spawn-test-helper " + "executable in /usr/bin:/bin"); + return; + } + + envp = g_environ_setenv (envp, "PATH", subdir, TRUE); + + g_ptr_array_add (argv, + g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL)); + g_ptr_array_add (argv, g_strdup ("--search-path-from-envp")); + g_ptr_array_add (argv, g_strdup ("--unset-path-in-envp")); + g_ptr_array_add (argv, g_strdup ("--")); + g_ptr_array_add (argv, g_strdup ("spawn-test-helper")); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (here, + (char **) argv->pdata, + envp, + G_SPAWN_DEFAULT, + NULL, /* child setup */ + NULL, /* user data */ + &out, + &err, + &wait_status, + &error); + g_assert_no_error (error); + + g_test_message ("%s", out); + g_test_message ("%s", err); + g_assert_nonnull (strstr (err, "this is spawn-test-helper from glib/tests")); + +#ifdef G_OS_UNIX + g_assert_true (WIFEXITED (wait_status)); + g_assert_cmpint (WEXITSTATUS (wait_status), ==, 0); +#endif + + g_strfreev (envp); + g_free (here); + g_free (subdir); + g_free (out); + g_free (err); + g_ptr_array_unref (argv); +} + +static void +test_search_path_heap_allocation (void) +{ + GPtrArray *argv = g_ptr_array_new_with_free_func (g_free); + /* Must be longer than the arbitrary 4000 byte limit for stack allocation + * in gspawn.c */ + char placeholder[4096]; + gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL); + gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL); + gchar *long_dir = NULL; + gchar *long_path = NULL; + gchar **envp = g_get_environ (); + gchar *out = NULL; + gchar *err = NULL; + GError *error = NULL; + int wait_status = -1; + gsize i; + + if (skip_win32 ()) + return; + + memset (placeholder, '_', sizeof (placeholder) - 1); + placeholder[sizeof (placeholder) - 1] = '\0'; + /* Force search_path_buffer to be heap-allocated */ + long_dir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", placeholder, NULL); + long_path = g_strjoin (G_SEARCHPATH_SEPARATOR_S, subdir, long_dir, NULL); + envp = g_environ_setenv (envp, "PATH", long_path, TRUE); + g_free (long_path); + g_free (long_dir); + + g_ptr_array_add (argv, + g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL)); + g_ptr_array_add (argv, g_strdup ("--search-path")); + g_ptr_array_add (argv, g_strdup ("--")); + g_ptr_array_add (argv, g_strdup ("spawn-test-helper")); + + /* Add enough arguments to make argv longer than the arbitrary 4000 byte + * limit for stack allocation in gspawn.c. + * This assumes sizeof (char *) >= 4. */ + for (i = 0; i < 1001; i++) + g_ptr_array_add (argv, g_strdup ("_")); + + g_ptr_array_add (argv, NULL); + + g_spawn_sync (here, + (char **) argv->pdata, + envp, + G_SPAWN_DEFAULT, + NULL, /* child setup */ + NULL, /* user data */ + &out, + &err, + &wait_status, + &error); + g_assert_no_error (error); + + g_test_message ("%s", out); + g_test_message ("%s", err); + g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir")); + +#ifdef G_OS_UNIX + g_assert_true (WIFEXITED (wait_status)); + g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5); +#endif + + g_strfreev (envp); + g_free (here); + g_free (subdir); + g_free (out); + g_free (err); + g_ptr_array_unref (argv); +} + +int +main (int argc, + char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/spawn/do-not-search", test_do_not_search); + g_test_add_func ("/spawn/search-path", test_search_path); + g_test_add_func ("/spawn/search-path-from-envp", test_search_path_from_envp); + g_test_add_func ("/spawn/search-path-ambiguous", test_search_path_ambiguous); + g_test_add_func ("/spawn/search-path-heap-allocation", + test_search_path_heap_allocation); + g_test_add_func ("/spawn/search-path-fallback-in-environ", + test_search_path_fallback_in_environ); + g_test_add_func ("/spawn/search-path-fallback-in-envp", + test_search_path_fallback_in_envp); + + return g_test_run (); +} diff --git a/glib/tests/spawn-singlethread.c b/glib/tests/spawn-singlethread.c new file mode 100644 index 0000000..b17b472 --- /dev/null +++ b/glib/tests/spawn-singlethread.c @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2011 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#ifdef G_OS_UNIX +#include +#include +#include +#include +#endif + +#ifdef G_OS_WIN32 +#include +#define LINEEND "\r\n" +#else +#define LINEEND "\n" +#endif + +/* MinGW builds are likely done using a BASH-style shell, so run the + * normal script there, as on non-Windows builds, as it is more likely + * that one will run 'make check' in such shells to test the code + */ +#if defined (G_OS_WIN32) && defined (_MSC_VER) +#define SCRIPT_EXT ".bat" +#else +#define SCRIPT_EXT +#endif + +static char *echo_prog_path; +static char *echo_script_path; + +typedef struct { + GMainLoop *loop; + gboolean child_exited; + gboolean stdout_done; + GString *stdout_buf; +} SpawnAsyncMultithreadedData; + +static gboolean +on_child_exited (GPid pid, + gint status, + gpointer datap) +{ + SpawnAsyncMultithreadedData *data = datap; + + data->child_exited = TRUE; + if (data->child_exited && data->stdout_done) + g_main_loop_quit (data->loop); + + return G_SOURCE_REMOVE; +} + +static gboolean +on_child_stdout (GIOChannel *channel, + GIOCondition condition, + gpointer datap) +{ + char buf[1024]; + GError *error = NULL; + gsize bytes_read; + SpawnAsyncMultithreadedData *data = datap; + + if (condition & G_IO_IN) + { + GIOStatus status; + status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error); + g_assert_no_error (error); + g_string_append_len (data->stdout_buf, buf, (gssize) bytes_read); + if (status == G_IO_STATUS_EOF) + data->stdout_done = TRUE; + } + if (condition & G_IO_HUP) + data->stdout_done = TRUE; + if (condition & G_IO_ERR) + g_error ("Error reading from child stdin"); + + if (data->child_exited && data->stdout_done) + g_main_loop_quit (data->loop); + + return !data->stdout_done; +} + +static void +test_spawn_async (void) +{ + int tnum = 1; + GError *error = NULL; + GPtrArray *argv; + char *arg; + GPid pid; + GMainContext *context; + GMainLoop *loop; + GIOChannel *channel; + GSource *source; + int child_stdout_fd; + SpawnAsyncMultithreadedData data; + + context = g_main_context_new (); + loop = g_main_loop_new (context, TRUE); + + arg = g_strdup_printf ("thread %d", tnum); + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, echo_prog_path); + g_ptr_array_add (argv, arg); + g_ptr_array_add (argv, NULL); + + g_spawn_async_with_pipes (NULL, (char**)argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL, + &child_stdout_fd, NULL, &error); + g_assert_no_error (error); + g_ptr_array_free (argv, TRUE); + + data.loop = loop; + data.stdout_done = FALSE; + data.child_exited = FALSE; + data.stdout_buf = g_string_new (0); + + source = g_child_watch_source_new (pid); + g_source_set_callback (source, (GSourceFunc)on_child_exited, &data, NULL); + g_source_attach (source, context); + g_source_unref (source); + + channel = g_io_channel_unix_new (child_stdout_fd); + source = g_io_create_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR); + g_source_set_callback (source, (GSourceFunc)on_child_stdout, &data, NULL); + g_source_attach (source, context); + g_source_unref (source); + + g_main_loop_run (loop); + + g_assert (data.child_exited); + g_assert (data.stdout_done); + g_assert_cmpstr (data.stdout_buf->str, ==, arg); + g_string_free (data.stdout_buf, TRUE); + + g_io_channel_unref (channel); + g_main_context_unref (context); + g_main_loop_unref (loop); + + g_free (arg); +} + +/* Windows close() causes failure through the Invalid Parameter Handler + * Routine if the file descriptor does not exist. + */ +static void +safe_close (int fd) +{ + if (fd >= 0) + close (fd); +} + +/* Test g_spawn_async_with_fds() with a variety of different inputs */ +static void +test_spawn_async_with_fds (void) +{ + int tnum = 1; + GPtrArray *argv; + char *arg; + gsize i; + + /* Each test has 3 variable parameters: stdin, stdout, stderr */ + enum fd_type { + NO_FD, /* pass fd -1 (unset) */ + FD_NEGATIVE, /* pass fd of negative value (equivalent to unset) */ + PIPE, /* pass fd of new/unique pipe */ + STDOUT_PIPE, /* pass the same pipe as stdout */ + } tests[][3] = { + { NO_FD, NO_FD, NO_FD }, /* Test with no fds passed */ + { NO_FD, FD_NEGATIVE, NO_FD }, /* Test another negative fd value */ + { PIPE, PIPE, PIPE }, /* Test with unique fds passed */ + { NO_FD, PIPE, STDOUT_PIPE }, /* Test the same fd for stdout + stderr */ + }; + + arg = g_strdup_printf ("thread %d", tnum); + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, echo_prog_path); + g_ptr_array_add (argv, arg); + g_ptr_array_add (argv, NULL); + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + GError *error = NULL; + GPid pid; + GMainContext *context; + GMainLoop *loop; + GIOChannel *channel = NULL; + GSource *source; + SpawnAsyncMultithreadedData data; + enum fd_type *fd_info = tests[i]; + gint test_pipe[3][2]; + int j; + + for (j = 0; j < 3; j++) + { + switch (fd_info[j]) + { + case NO_FD: + test_pipe[j][0] = -1; + test_pipe[j][1] = -1; + break; + case FD_NEGATIVE: + test_pipe[j][0] = -5; + test_pipe[j][1] = -5; + break; + case PIPE: +#ifdef G_OS_UNIX + g_unix_open_pipe (test_pipe[j], FD_CLOEXEC, &error); + g_assert_no_error (error); +#else + g_assert_cmpint (_pipe (test_pipe[j], 4096, _O_BINARY), >=, 0); +#endif + break; + case STDOUT_PIPE: + g_assert_cmpint (j, ==, 2); /* only works for stderr */ + test_pipe[j][0] = test_pipe[1][0]; + test_pipe[j][1] = test_pipe[1][1]; + break; + default: + g_assert_not_reached (); + } + } + + context = g_main_context_new (); + loop = g_main_loop_new (context, TRUE); + + g_spawn_async_with_fds (NULL, (char**)argv->pdata, NULL, + G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, + test_pipe[0][0], test_pipe[1][1], test_pipe[2][1], + &error); + g_assert_no_error (error); + safe_close (test_pipe[0][0]); + safe_close (test_pipe[1][1]); + if (fd_info[2] != STDOUT_PIPE) + safe_close (test_pipe[2][1]); + + data.loop = loop; + data.stdout_done = FALSE; + data.child_exited = FALSE; + data.stdout_buf = g_string_new (0); + + source = g_child_watch_source_new (pid); + g_source_set_callback (source, (GSourceFunc)on_child_exited, &data, NULL); + g_source_attach (source, context); + g_source_unref (source); + + if (test_pipe[1][0] >= 0) + { + channel = g_io_channel_unix_new (test_pipe[1][0]); + source = g_io_create_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR); + g_source_set_callback (source, (GSourceFunc)on_child_stdout, + &data, NULL); + g_source_attach (source, context); + g_source_unref (source); + } + else + { + /* Don't check stdout data if we didn't pass a fd */ + data.stdout_done = TRUE; + } + + g_main_loop_run (loop); + + g_assert_true (data.child_exited); + + if (test_pipe[1][0] >= 0) + { + /* Check for echo on stdout */ + g_assert_true (data.stdout_done); + g_assert_cmpstr (data.stdout_buf->str, ==, arg); + g_io_channel_unref (channel); + } + g_string_free (data.stdout_buf, TRUE); + + g_main_context_unref (context); + g_main_loop_unref (loop); + safe_close (test_pipe[0][1]); + safe_close (test_pipe[1][0]); + if (fd_info[2] != STDOUT_PIPE) + safe_close (test_pipe[2][0]); + } + + g_ptr_array_free (argv, TRUE); + g_free (arg); +} + +static void +test_spawn_sync (void) +{ + int tnum = 1; + GError *error = NULL; + char *arg = g_strdup_printf ("thread %d", tnum); + /* Include arguments with special symbols to test that they are correctly passed to child. + * This is tested on all platforms, but the most prone to failure is win32, + * where args are specially escaped during spawning. + */ + const char * const argv[] = { + echo_prog_path, + arg, + "doublequotes\\\"after\\\\\"\"backslashes", /* this would be special escaped on win32 */ + "\\\"\"doublequotes spaced after backslashes\\\\\"", /* this would be special escaped on win32 */ + "even$$dollars", + "even%%percents", + "even\"\"doublequotes", + "even''singlequotes", + "even\\\\backslashes", + "even//slashes", + "$odd spaced$dollars$", + "%odd spaced%spercents%", + "\"odd spaced\"doublequotes\"", + "'odd spaced'singlequotes'", + "\\odd spaced\\backslashes\\", /* this wasn't handled correctly on win32 in glib <=2.58 */ + "/odd spaced/slashes/", + NULL + }; + char *joined_args_str = g_strjoinv ("", (char**)argv + 1); + char *stdout_str; + int estatus; + + g_spawn_sync (NULL, (char**)argv, NULL, 0, NULL, NULL, &stdout_str, NULL, &estatus, &error); + g_assert_no_error (error); + g_assert_cmpstr (joined_args_str, ==, stdout_str); + g_free (arg); + g_free (stdout_str); + g_free (joined_args_str); +} + +/* Like test_spawn_sync but uses spawn flags that trigger the optimized + * posix_spawn codepath. + */ +static void +test_posix_spawn (void) +{ + int tnum = 1; + GError *error = NULL; + GPtrArray *argv; + char *arg; + char *stdout_str; + int estatus; + GSpawnFlags flags = G_SPAWN_CLOEXEC_PIPES | G_SPAWN_LEAVE_DESCRIPTORS_OPEN; + + arg = g_strdup_printf ("thread %d", tnum); + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, echo_prog_path); + g_ptr_array_add (argv, arg); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char**)argv->pdata, NULL, flags, NULL, NULL, &stdout_str, NULL, &estatus, &error); + g_assert_no_error (error); + g_assert_cmpstr (arg, ==, stdout_str); + g_free (arg); + g_free (stdout_str); + g_ptr_array_free (argv, TRUE); +} + +static void +test_spawn_script (void) +{ + GError *error = NULL; + GPtrArray *argv; + char *stdout_str; + int estatus; + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, echo_script_path); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char**)argv->pdata, NULL, 0, NULL, NULL, &stdout_str, NULL, &estatus, &error); + g_assert_no_error (error); + g_assert_cmpstr ("echo" LINEEND, ==, stdout_str); + g_free (stdout_str); + g_ptr_array_free (argv, TRUE); +} + +/* Test that spawning a non-existent executable returns %G_SPAWN_ERROR_NOENT. */ +static void +test_spawn_nonexistent (void) +{ + GError *error = NULL; + GPtrArray *argv = NULL; + gchar *stdout_str = NULL; + gint wait_status = -1; + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, "this does not exist"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char**) argv->pdata, NULL, 0, NULL, NULL, &stdout_str, + NULL, &wait_status, &error); + g_assert_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT); + g_assert_null (stdout_str); + g_assert_cmpint (wait_status, ==, -1); + + g_ptr_array_free (argv, TRUE); + + g_clear_error (&error); +} + +/* Test that FD assignments in a spawned process don’t overwrite and break the + * child_err_report_fd which is used to report error information back from the + * intermediate child process to the parent. + * + * https://gitlab.gnome.org/GNOME/glib/-/issues/2097 */ +static void +test_spawn_fd_assignment_clash (void) +{ + int tmp_fd; + guint i; +#define N_FDS 10 + gint source_fds[N_FDS]; + gint target_fds[N_FDS]; + const gchar *argv[] = { "/nonexistent", NULL }; + gboolean retval; + GError *local_error = NULL; + struct stat statbuf; + + /* Open a temporary file and duplicate its FD several times so we have several + * FDs to remap in the child process. */ + tmp_fd = g_file_open_tmp ("glib-spawn-test-XXXXXX", NULL, NULL); + g_assert_cmpint (tmp_fd, >=, 0); + + for (i = 0; i < (N_FDS - 1); ++i) + { + int source; +#ifdef F_DUPFD_CLOEXEC + source = fcntl (tmp_fd, F_DUPFD_CLOEXEC, 3); +#else + source = dup (tmp_fd); +#endif + g_assert_cmpint (source, >=, 0); + source_fds[i] = source; + target_fds[i] = source + N_FDS; + } + + source_fds[i] = tmp_fd; + target_fds[i] = tmp_fd + N_FDS; + + /* Print out the FD map. */ + g_test_message ("FD map:"); + for (i = 0; i < N_FDS; i++) + g_test_message (" • %d → %d", source_fds[i], target_fds[i]); + + /* Spawn the subprocess. This should fail because the executable doesn’t + * exist. */ + retval = g_spawn_async_with_pipes_and_fds (NULL, argv, NULL, G_SPAWN_DEFAULT, + NULL, NULL, -1, -1, -1, + source_fds, target_fds, N_FDS, + NULL, NULL, NULL, NULL, + &local_error); + g_assert_error (local_error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT); + g_assert_false (retval); + + g_clear_error (&local_error); + + /* Check nothing was written to the temporary file, as would happen if the FD + * mapping was messed up to conflict with the child process error reporting FD. + * See https://gitlab.gnome.org/GNOME/glib/-/issues/2097 */ + g_assert_no_errno (fstat (tmp_fd, &statbuf)); + g_assert_cmpuint (statbuf.st_size, ==, 0); + + /* Clean up. */ + for (i = 0; i < N_FDS; i++) + g_close (source_fds[i], NULL); +} + +int +main (int argc, + char *argv[]) +{ + char *dirname; + int ret; + + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + dirname = g_path_get_dirname (argv[0]); + echo_prog_path = g_build_filename (dirname, "test-spawn-echo" EXEEXT, NULL); + echo_script_path = g_build_filename (dirname, "echo-script" SCRIPT_EXT, NULL); + if (!g_file_test (echo_script_path, G_FILE_TEST_EXISTS)) + { + g_free (echo_script_path); + echo_script_path = g_test_build_filename (G_TEST_DIST, "echo-script" SCRIPT_EXT, NULL); + } + g_free (dirname); + + g_assert (g_file_test (echo_prog_path, G_FILE_TEST_EXISTS)); + g_assert (g_file_test (echo_script_path, G_FILE_TEST_EXISTS)); + + g_test_add_func ("/gthread/spawn-single-sync", test_spawn_sync); + g_test_add_func ("/gthread/spawn-single-async", test_spawn_async); + g_test_add_func ("/gthread/spawn-single-async-with-fds", test_spawn_async_with_fds); + g_test_add_func ("/gthread/spawn-script", test_spawn_script); + g_test_add_func ("/gthread/spawn/nonexistent", test_spawn_nonexistent); + g_test_add_func ("/gthread/spawn-posix-spawn", test_posix_spawn); + g_test_add_func ("/gthread/spawn/fd-assignment-clash", test_spawn_fd_assignment_clash); + + ret = g_test_run(); + + g_free (echo_script_path); + g_free (echo_prog_path); + + return ret; +} diff --git a/glib/tests/spawn-test-helper.c b/glib/tests/spawn-test-helper.c new file mode 100644 index 0000000..301f3f3 --- /dev/null +++ b/glib/tests/spawn-test-helper.c @@ -0,0 +1,7 @@ +#include + +int main (void) +{ + fprintf (stderr, "this is spawn-test-helper from glib/tests\n"); + return 0; +} diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c new file mode 100644 index 0000000..082eec0 --- /dev/null +++ b/glib/tests/strfuncs.c @@ -0,0 +1,2602 @@ +/* Unit tests for gstrfuncs + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#define _XOPEN_SOURCE 600 +#include +#include +#include +#include +#include +#include +#include +#include +#include "glib.h" + +#if defined (_MSC_VER) && (_MSC_VER <= 1800) +#define isnan(x) _isnan(x) + +#ifndef NAN +static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; +#define NAN (*(const float *) __nan) +#endif + +#ifndef INFINITY +#define INFINITY HUGE_VAL +#endif + +#endif + +#define GLIB_TEST_STRING "el dorado " + +#define FOR_ALL_CTYPE(macro) \ + macro(isalnum) \ + macro(isalpha) \ + macro(iscntrl) \ + macro(isdigit) \ + macro(isgraph) \ + macro(islower) \ + macro(isprint) \ + macro(ispunct) \ + macro(isspace) \ + macro(isupper) \ + macro(isxdigit) + +#define DEFINE_CALL_CTYPE(function) \ + static int \ + call_##function (int c) \ + { \ + return function (c); \ + } + +#define DEFINE_CALL_G_ASCII_CTYPE(function) \ + static gboolean \ + call_g_ascii_##function (gchar c) \ + { \ + return g_ascii_##function (c); \ + } + +FOR_ALL_CTYPE (DEFINE_CALL_CTYPE) +FOR_ALL_CTYPE (DEFINE_CALL_G_ASCII_CTYPE) + +static void +test_is_function (const char *name, + gboolean (* ascii_function) (gchar), + int (* c_library_function) (int), + gboolean (* unicode_function) (gunichar)) +{ + int c; + + for (c = 0; c <= 0x7F; c++) + { + gboolean ascii_result = ascii_function ((gchar)c); + gboolean c_library_result = c_library_function (c) != 0; + gboolean unicode_result = unicode_function ((gunichar) c); + if (ascii_result != c_library_result && c != '\v') + { + g_error ("g_ascii_%s returned %d and %s returned %d for 0x%X", + name, ascii_result, name, c_library_result, c); + } + if (ascii_result != unicode_result) + { + g_error ("g_ascii_%s returned %d and g_unichar_%s returned %d for 0x%X", + name, ascii_result, name, unicode_result, c); + } + } + for (c = 0x80; c <= 0xFF; c++) + { + gboolean ascii_result = ascii_function ((gchar)c); + if (ascii_result) + { + g_error ("g_ascii_%s returned TRUE for 0x%X", name, c); + } + } +} + +static void +test_to_function (const char *name, + gchar (* ascii_function) (gchar), + int (* c_library_function) (int), + gunichar (* unicode_function) (gunichar)) +{ + int c; + + for (c = 0; c <= 0x7F; c++) + { + int ascii_result = (guchar) ascii_function ((gchar) c); + int c_library_result = c_library_function (c); + int unicode_result = unicode_function ((gunichar) c); + if (ascii_result != c_library_result) + { + g_error ("g_ascii_%s returned 0x%X and %s returned 0x%X for 0x%X", + name, ascii_result, name, c_library_result, c); + } + if (ascii_result != unicode_result) + { + g_error ("g_ascii_%s returned 0x%X and g_unichar_%s returned 0x%X for 0x%X", + name, ascii_result, name, unicode_result, c); + } + } + for (c = 0x80; c <= 0xFF; c++) + { + int ascii_result = (guchar) ascii_function ((gchar) c); + if (ascii_result != c) + { + g_error ("g_ascii_%s returned 0x%X for 0x%X", + name, ascii_result, c); + } + } +} + +static void +test_digit_function (const char *name, + int (* ascii_function) (gchar), + int (* unicode_function) (gunichar)) +{ + int c; + + for (c = 0; c <= 0x7F; c++) + { + int ascii_result = ascii_function ((gchar) c); + int unicode_result = unicode_function ((gunichar) c); + if (ascii_result != unicode_result) + { + g_error ("g_ascii_%s_value returned %d and g_unichar_%s_value returned %d for 0x%X", + name, ascii_result, name, unicode_result, c); + } + } + for (c = 0x80; c <= 0xFF; c++) + { + int ascii_result = ascii_function ((gchar) c); + if (ascii_result != -1) + { + g_error ("g_ascii_%s_value returned %d for 0x%X", + name, ascii_result, c); + } + } +} + +static void +test_is_to_digit (void) +{ + #define TEST_IS(name) test_is_function (#name, call_g_ascii_##name, call_##name, g_unichar_##name); + + FOR_ALL_CTYPE(TEST_IS) + + #undef TEST_IS + + #define TEST_TO(name) test_to_function (#name, g_ascii_##name, name, g_unichar_##name) + + TEST_TO (tolower); + TEST_TO (toupper); + + #undef TEST_TO + + #define TEST_DIGIT(name) test_digit_function (#name, g_ascii_##name##_value, g_unichar_##name##_value) + + TEST_DIGIT (digit); + TEST_DIGIT (xdigit); + + #undef TEST_DIGIT +} + +/* Testing g_memdup() function with various positive and negative cases */ +static void +test_memdup (void) +{ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + + gchar *str_dup = NULL; + const gchar *str = "The quick brown fox jumps over the lazy dog"; + + /* Testing negative cases */ + g_assert_null (g_memdup (NULL, 1024)); + g_assert_null (g_memdup (str, 0)); + g_assert_null (g_memdup (NULL, 0)); + + /* Testing normal usage cases */ + str_dup = g_memdup (str, strlen (str) + 1); + g_assert_nonnull (str_dup); + g_assert_cmpstr (str, ==, str_dup); + + g_free (str_dup); + + G_GNUC_END_IGNORE_DEPRECATIONS +} + +/* Testing g_memdup2() function with various positive and negative cases */ +static void +test_memdup2 (void) +{ + gchar *str_dup = NULL; + const gchar *str = "The quick brown fox jumps over the lazy dog"; + + /* Testing negative cases */ + g_assert_null (g_memdup2 (NULL, 1024)); + g_assert_null (g_memdup2 (str, 0)); + g_assert_null (g_memdup2 (NULL, 0)); + + /* Testing normal usage cases */ + str_dup = g_memdup2 (str, strlen (str) + 1); + g_assert_nonnull (str_dup); + g_assert_cmpstr (str, ==, str_dup); + + g_free (str_dup); +} + +/* Testing g_strpcpy() function with various positive and negative cases */ +static void +test_stpcpy (void) +{ + gchar *str = "The quick brown fox jumps over the lazy dog"; + gchar str_cpy[45], *str_cpy_end = NULL; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_cpy_end = g_stpcpy (str_cpy, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_cpy_end = g_stpcpy (NULL, str); + g_test_assert_expected_messages (); + } + + /* Testing normal usage cases */ + str_cpy_end = g_stpcpy (str_cpy, str); + g_assert_nonnull (str_cpy); + g_assert_true (str_cpy + strlen (str) == str_cpy_end); + g_assert_cmpstr (str, ==, str_cpy); + g_assert_cmpstr (str, ==, str_cpy_end - strlen (str)); +} + +/* Testing g_strlcpy() function with various positive and negative cases */ +static void +test_strlcpy (void) +{ + gchar *str = "The quick brown fox jumps over the lazy dog"; + gchar str_cpy[45]; + gsize str_cpy_size = 0; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_cpy_size = g_strlcpy (str_cpy, NULL, 0); + g_test_assert_expected_messages (); + /* Returned 0 because g_strlcpy() failed */ + g_assert_cmpint (str_cpy_size, ==, 0); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_cpy_size = g_strlcpy (NULL, str, 0); + g_test_assert_expected_messages (); + /* Returned 0 because g_strlcpy() failed */ + g_assert_cmpint (str_cpy_size, ==, 0); + } + + str_cpy_size = g_strlcpy (str_cpy, "", 0); + g_assert_cmpint (str_cpy_size, ==, strlen ("")); + + /* Testing normal usage cases. + * Note that the @dest_size argument to g_strlcpy() is normally meant to be + * set to `sizeof (dest)`. We set it to various values `≤ sizeof (str_cpy)` + * for testing purposes. */ + str_cpy_size = g_strlcpy (str_cpy, str, strlen (str) + 1); + g_assert_nonnull (str_cpy); + g_assert_cmpstr (str, ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, strlen (str)); + + str_cpy_size = g_strlcpy (str_cpy, str, strlen (str)); + g_assert_nonnull (str_cpy); + g_assert_cmpstr ("The quick brown fox jumps over the lazy do", ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, strlen (str)); + + str_cpy_size = g_strlcpy (str_cpy, str, strlen (str) - 15); + g_assert_nonnull (str_cpy); + g_assert_cmpstr ("The quick brown fox jumps o", ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, strlen (str)); + + str_cpy_size = g_strlcpy (str_cpy, str, 0); + g_assert_nonnull (str_cpy); + g_assert_cmpstr ("The quick brown fox jumps o", ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, strlen (str)); + + str_cpy_size = g_strlcpy (str_cpy, str, strlen (str) + 15); + g_assert_nonnull (str_cpy); + g_assert_cmpstr (str, ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, strlen (str)); +} + +/* Testing g_strlcat() function with various positive and negative cases */ +static void +test_strlcat (void) +{ + gchar *str = "The quick brown fox jumps over the lazy dog"; + gchar str_cpy[60] = { 0 }; + gsize str_cpy_size = 0; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_cpy_size = g_strlcat (str_cpy, NULL, 0); + g_test_assert_expected_messages (); + /* Returned 0 because g_strlcpy() failed */ + g_assert_cmpint (str_cpy_size, ==, 0); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_cpy_size = g_strlcat (NULL, str, 0); + g_test_assert_expected_messages (); + /* Returned 0 because g_strlcpy() failed */ + g_assert_cmpint (str_cpy_size, ==, 0); + } + + str_cpy_size = g_strlcat (str_cpy, "", 0); + g_assert_cmpint (str_cpy_size, ==, strlen ("")); + + /* Testing normal usage cases. + * Note that the @dest_size argument to g_strlcat() is normally meant to be + * set to `sizeof (dest)`. We set it to various values `≤ sizeof (str_cpy)` + * for testing purposes. */ + g_assert_cmpuint (strlen (str) + 1, <=, sizeof (str_cpy)); + str_cpy_size = g_strlcat (str_cpy, str, strlen (str) + 1); + g_assert_cmpstr (str, ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, strlen (str)); + + g_assert_cmpuint (strlen (str), <=, sizeof (str_cpy)); + str_cpy_size = g_strlcat (str_cpy, str, strlen (str)); + g_assert_cmpstr (str, ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, 2 * strlen (str)); + + g_assert_cmpuint (strlen (str) - 15, <=, sizeof (str_cpy)); + str_cpy_size = g_strlcat (str_cpy, str, strlen (str) - 15); + g_assert_cmpstr (str, ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, 2 * strlen (str) - 15); + + g_assert_cmpuint (0, <=, sizeof (str_cpy)); + str_cpy_size = g_strlcat (str_cpy, str, 0); + g_assert_cmpstr (str, ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, strlen (str)); + + g_assert_cmpuint (strlen (str) + 15, <=, sizeof (str_cpy)); + str_cpy_size = g_strlcat (str_cpy, str, strlen (str) + 15); + g_assert_cmpstr ("The quick brown fox jumps over the lazy dogThe quick brow", + ==, str_cpy); + g_assert_cmpint (str_cpy_size, ==, 2 * strlen (str)); +} + +/* Testing g_ascii_strdown() function with various positive and negative cases */ +static void +test_ascii_strdown (void) +{ + const gchar *str_down = "the quick brown fox jumps over the lazy dog."; + const gchar *str_up = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG."; + gchar* str; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str = g_ascii_strdown (NULL, 0); + g_test_assert_expected_messages (); + } + + str = g_ascii_strdown ("", 0); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, ""); + g_free (str); + + str = g_ascii_strdown ("", -1); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, ""); + g_free (str); + + /* Testing normal usage cases */ + str = g_ascii_strdown (str_down, strlen (str_down)); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, str_down); + g_free (str); + + str = g_ascii_strdown (str_up, strlen (str_up)); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, str_down); + g_free (str); + + str = g_ascii_strdown (str_up, -1); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, str_down); + g_free (str); + + str = g_ascii_strdown (str_up, 0); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, ""); + g_free (str); +} + +/* Testing g_ascii_strup() function with various positive and negative cases */ +static void +test_ascii_strup (void) +{ + const gchar *str_down = "the quick brown fox jumps over the lazy dog."; + const gchar *str_up = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG."; + gchar* str; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str = g_ascii_strup (NULL, 0); + g_test_assert_expected_messages (); + } + + str = g_ascii_strup ("", 0); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, ""); + g_free (str); + + str = g_ascii_strup ("", -1); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, ""); + g_free (str); + + /* Testing normal usage cases */ + str = g_ascii_strup (str_up, strlen (str_up)); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, str_up); + g_free (str); + + str = g_ascii_strup (str_down, strlen (str_down)); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, str_up); + g_free (str); + + str = g_ascii_strup (str_down, -1); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, str_up); + g_free (str); + + str = g_ascii_strup (str_down, 0); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, ""); + g_free (str); +} + +/* Testing g_strdup() function with various positive and negative cases */ +static void +test_strdup (void) +{ + gchar *str; + + g_assert_null (g_strdup (NULL)); + + str = g_strdup (GLIB_TEST_STRING); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, GLIB_TEST_STRING); + g_free (str); +} + +/* Testing g_strndup() function with various positive and negative cases */ +static void +test_strndup (void) +{ + gchar *str; + + str = g_strndup (NULL, 3); + g_assert_null (str); + + str = g_strndup ("aaaa", 5); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "aaaa"); + g_free (str); + + str = g_strndup ("aaaa", 2); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "aa"); + g_free (str); +} + +/* Testing g_strdup_printf() function with various positive and negative cases */ +static void +test_strdup_printf (void) +{ + gchar *str; + + str = g_strdup_printf ("%05d %-5s", 21, "test"); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "00021 test "); + g_free (str); +} + +/* Testing g_strdupv() function with various positive and negative cases */ +static void +test_strdupv (void) +{ + gchar *vec[] = { "Foo", "Bar", NULL }; + gchar **copy; + + copy = g_strdupv (NULL); + g_assert_null (copy); + + copy = g_strdupv (vec); + g_assert_nonnull (copy); + g_assert_cmpstrv (copy, vec); + g_strfreev (copy); +} + +/* Testing g_strfill() function with various positive and negative cases */ +static void +test_strnfill (void) +{ + gchar *str; + + str = g_strnfill (0, 'a'); + g_assert_nonnull (str); + g_assert_true (*str == '\0'); + g_free (str); + + str = g_strnfill (5, 'a'); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "aaaaa"); + g_free (str); +} + +/* Testing g_strconcat() function with various positive and negative cases */ +static void +test_strconcat (void) +{ + gchar *str; + + str = g_strconcat (GLIB_TEST_STRING, NULL); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, GLIB_TEST_STRING); + g_free (str); + + str = g_strconcat (GLIB_TEST_STRING, + GLIB_TEST_STRING, + GLIB_TEST_STRING, + NULL); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, GLIB_TEST_STRING GLIB_TEST_STRING GLIB_TEST_STRING); + g_free (str); + + g_assert_null (g_strconcat (NULL, "bla", NULL)); +} + +/* Testing g_strjoinv() function with various positive and negative cases */ +static void +test_strjoinv (void) +{ + gchar *strings[] = { "string1", "string2", NULL }; + gchar *empty_strings[] = { NULL }; + gchar *str; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str = g_strjoinv (NULL, NULL); + g_test_assert_expected_messages (); + } + + str = g_strjoinv (":", strings); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "string1:string2"); + g_free (str); + + str = g_strjoinv (NULL, strings); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "string1string2"); + g_free (str); + + str = g_strjoinv (NULL, empty_strings); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, ""); + g_free (str); +} + +/* Testing g_strjoin() function with various positive and negative cases */ +static void +test_strjoin (void) +{ + gchar *str; + + str = g_strjoin (NULL, NULL); + g_assert_nonnull (str); + g_assert_true (*str == '\0'); + g_free (str); + + str = g_strjoin (":", NULL); + g_assert_nonnull (str); + g_assert_true (*str == '\0'); + g_free (str); + + str = g_strjoin (NULL, GLIB_TEST_STRING, NULL); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, GLIB_TEST_STRING); + g_free (str); + + str = g_strjoin (NULL, + GLIB_TEST_STRING, + GLIB_TEST_STRING, + GLIB_TEST_STRING, + NULL); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, GLIB_TEST_STRING GLIB_TEST_STRING GLIB_TEST_STRING); + g_free (str); + + str = g_strjoin (":", + GLIB_TEST_STRING, + GLIB_TEST_STRING, + GLIB_TEST_STRING, + NULL); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, GLIB_TEST_STRING ":" GLIB_TEST_STRING ":" GLIB_TEST_STRING); + g_free (str); +} + +/* Testing g_strcanon() function with various positive and negative cases */ +static void +test_strcanon (void) +{ + gchar *str; + + if (g_test_undefined ()) + { + gchar *ret; + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str = g_strcanon (NULL, "ab", 'y'); + g_test_assert_expected_messages (); + g_assert_null (str); + + str = g_strdup ("abxabxab"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + ret = g_strcanon (str, NULL, 'y'); + g_test_assert_expected_messages (); + g_assert_null (ret); + g_free (str); + } + + str = g_strdup ("abxabxab"); + str = g_strcanon (str, "ab", 'y'); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "abyabyab"); + g_free (str); +} + +/* Testing g_strcompress() and g_strescape() functions with various cases */ +static void +test_strcompress_strescape (void) +{ + gchar *str; + gchar *tmp; + + /* test compress */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str = g_strcompress (NULL); + g_test_assert_expected_messages (); + g_assert_null (str); + + /* trailing slashes are not allowed */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*trailing \\*"); + str = g_strcompress ("abc\\"); + g_test_assert_expected_messages (); + g_assert_cmpstr (str, ==, "abc"); + g_free (str); + } + + str = g_strcompress ("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313\\12345z"); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "abc\\\"\b\f\n\r\t\v\003\177\234\313\12345z"); + g_free (str); + + /* test escape */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str = g_strescape (NULL, NULL); + g_test_assert_expected_messages (); + g_assert_null (str); + } + + str = g_strescape ("abc\\\"\b\f\n\r\t\v\003\177\234\313", NULL); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"); + g_free (str); + + str = g_strescape ("abc\\\"\b\f\n\r\t\v\003\177\234\313", + "\b\f\001\002\003\004"); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "abc\\\\\\\"\b\f\\n\\r\\t\\v\003\\177\\234\\313"); + g_free (str); + + /* round trip */ + tmp = g_strescape ("abc\\\"\b\f\n\r\t\v\003\177\234\313", NULL); + str = g_strcompress (tmp); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "abc\\\"\b\f\n\r\t\v\003\177\234\313"); + g_free (str); + g_free (tmp); + + /* Unicode round trip */ + str = g_strescape ("héllø there⸘", NULL); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "h\\303\\251ll\\303\\270 there\\342\\270\\230"); + tmp = g_strcompress (str); + g_assert_nonnull (tmp); + g_assert_cmpstr (tmp, ==, "héllø there⸘"); + g_free (tmp); + g_free (str); + + /* Test expanding invalid escapes */ + str = g_strcompress ("\\11/ \\118 \\8aa \\19"); + g_assert_nonnull (str); + g_assert_cmpstr (str, ==, "\t/ \t8 8aa \0019"); + g_free (str); +} + +/* Testing g_ascii_strcasecmp() and g_ascii_strncasecmp() */ +static void +test_ascii_strcasecmp (void) +{ + gboolean res; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_ascii_strcasecmp ("foo", NULL); + g_test_assert_expected_messages (); + g_assert_false (res); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_ascii_strcasecmp (NULL, "foo"); + g_test_assert_expected_messages (); + g_assert_false (res); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_ascii_strncasecmp ("foo", NULL, 0); + g_test_assert_expected_messages (); + g_assert_false (res); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_ascii_strncasecmp (NULL, "foo", 0); + g_test_assert_expected_messages (); + g_assert_false (res); + } + + res = g_ascii_strcasecmp ("FroboZZ", "frobozz"); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strcasecmp ("frobozz", "frobozz"); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strcasecmp ("frobozz", "FROBOZZ"); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strcasecmp ("FROBOZZ", "froboz"); + g_assert_cmpint (res, !=, 0); + + res = g_ascii_strcasecmp ("", ""); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strcasecmp ("!#%&/()", "!#%&/()"); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strcasecmp ("a", "b"); + g_assert_cmpint (res, <, 0); + + res = g_ascii_strcasecmp ("a", "B"); + g_assert_cmpint (res, <, 0); + + res = g_ascii_strcasecmp ("A", "b"); + g_assert_cmpint (res, <, 0); + + res = g_ascii_strcasecmp ("A", "B"); + g_assert_cmpint (res, <, 0); + + res = g_ascii_strcasecmp ("b", "a"); + g_assert_cmpint (res, >, 0); + + res = g_ascii_strcasecmp ("b", "A"); + g_assert_cmpint (res, >, 0); + + res = g_ascii_strcasecmp ("B", "a"); + g_assert_cmpint (res, >, 0); + + res = g_ascii_strcasecmp ("B", "A"); + g_assert_cmpint (res, >, 0); + + /* g_ascii_strncasecmp() */ + res = g_ascii_strncasecmp ("", "", 10); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strncasecmp ("Frob0ZZ", "frob0zz", strlen ("frobozz")); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strncasecmp ("Frob0ZZ", "frobozz", strlen ("frobozz")); + g_assert_cmpint (res, !=, 0); + + res = g_ascii_strncasecmp ("frob0ZZ", "FroB0zz", strlen ("frobozz")); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strncasecmp ("Frob0ZZ", "froB0zz", strlen ("frobozz") - 5); + g_assert_cmpint (res, ==, 0); + + res = g_ascii_strncasecmp ("Frob0ZZ", "froB0zz", strlen ("frobozz") + 5); + g_assert_cmpint (res, ==, 0); +} + +static void +do_test_strchug (const gchar *str, const gchar *expected) +{ + gchar *tmp; + gboolean res; + + tmp = g_strdup (str); + + g_strchug (tmp); + res = (strcmp (tmp, expected) == 0); + g_free (tmp); + + g_assert_cmpint (res, ==, TRUE); +} + +/* Testing g_strchug() function with various positive and negative cases */ +static void +test_strchug (void) +{ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_strchug (NULL); + g_test_assert_expected_messages (); + } + + do_test_strchug ("", ""); + do_test_strchug (" ", ""); + do_test_strchug ("\t\r\n ", ""); + do_test_strchug (" a", "a"); + do_test_strchug (" a", "a"); + do_test_strchug ("a a", "a a"); + do_test_strchug (" a a", "a a"); +} + +static void +do_test_strchomp (const gchar *str, const gchar *expected) +{ + gchar *tmp; + gboolean res; + + tmp = g_strdup (str); + + g_strchomp (tmp); + res = (strcmp (tmp, expected) == 0); + g_free (tmp); + + g_assert_cmpint (res, ==, TRUE); +} + +/* Testing g_strchomp() function with various positive and negative cases */ +static void +test_strchomp (void) +{ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_strchomp (NULL); + g_test_assert_expected_messages (); + } + + do_test_strchomp ("", ""); + do_test_strchomp (" ", ""); + do_test_strchomp (" \t\r\n", ""); + do_test_strchomp ("a ", "a"); + do_test_strchomp ("a ", "a"); + do_test_strchomp ("a a", "a a"); + do_test_strchomp ("a a ", "a a"); +} + +/* Testing g_str_tokenize_and_fold() functions */ +static void +test_str_tokenize_and_fold (void) +{ + const gchar *local_str = "en_GB"; + const gchar *sample = "The quick brown fox¸ jumps over the lazy dog."; + const gchar *special_cases = "quıck QUİCK QUİı QUıİ İıck ıİCK àìøş"; + gchar **tokens, **alternates; + gchar + *expected_tokens[] = \ + {"the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog", NULL}, + *expected_tokens_alt[] = \ + { "quick", "quick", "quii", "quii", "iick", "iick", "àìøş", NULL}; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + tokens = g_str_tokenize_and_fold (NULL, local_str, NULL); + g_test_assert_expected_messages (); + } + + tokens = g_str_tokenize_and_fold (special_cases, local_str, &alternates); + g_assert_cmpint (g_strv_length (tokens), ==, + g_strv_length (expected_tokens_alt)); + g_assert_true (g_strv_equal ((const gchar * const *) tokens, + (const gchar * const *) expected_tokens_alt)); + g_strfreev (tokens); + g_strfreev (alternates); + + tokens = g_str_tokenize_and_fold (sample, local_str, &alternates); + g_assert_cmpint (g_strv_length (tokens), ==, g_strv_length (expected_tokens)); + g_assert_true (g_strv_equal ((const gchar * const *) tokens, + (const gchar * const *) expected_tokens)); + g_strfreev (tokens); + g_strfreev (alternates); + + tokens = g_str_tokenize_and_fold (sample, local_str, NULL); + g_assert_cmpint (g_strv_length (tokens), ==, g_strv_length (expected_tokens)); + g_assert_true (g_strv_equal ((const gchar * const *) tokens, + (const gchar * const *) expected_tokens)); + g_strfreev (tokens); + + tokens = g_str_tokenize_and_fold (sample, NULL, &alternates); + g_assert_cmpint (g_strv_length (tokens), ==, g_strv_length (expected_tokens)); + g_assert_true (g_strv_equal ((const gchar * const *) tokens, + (const gchar * const *) expected_tokens)); + g_strfreev (tokens); + g_strfreev (alternates); +} + +/* Testing g_strreverse() function with various positive and negative cases */ +static void +test_strreverse (void) +{ + gchar *str; + gchar *p; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str = g_strreverse (NULL); + g_test_assert_expected_messages (); + g_assert_null (str); + } + + str = p = g_strdup ("abcde"); + str = g_strreverse (str); + g_assert_nonnull (str); + g_assert_true (p == str); + g_assert_cmpstr (str, ==, "edcba"); + g_free (str); +} + +/* Testing g_strncasecmp() functions */ +static void +test_strncasecmp (void) +{ + g_assert_cmpint (g_strncasecmp ("abc1", "ABC2", 3), ==, 0); + g_assert_cmpint (g_strncasecmp ("abc1", "ABC2", 4), !=, 0); +} + +static void +test_strstr (void) +{ + gchar *haystack; + gchar *res; + + haystack = g_strdup ("FooBarFooBarFoo"); + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_strstr_len (NULL, 0, "xxx"); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_strstr_len ("xxx", 0, NULL); + g_test_assert_expected_messages (); + } + + /* strstr_len */ + res = g_strstr_len (haystack, 6, "xxx"); + g_assert_null (res); + + res = g_strstr_len (haystack, 6, "FooBarFooBarFooBar"); + g_assert_null (res); + + res = g_strstr_len (haystack, 3, "Bar"); + g_assert_null (res); + + res = g_strstr_len (haystack, 6, ""); + g_assert_true (res == haystack); + g_assert_cmpstr (res, ==, "FooBarFooBarFoo"); + + res = g_strstr_len (haystack, 6, "Bar"); + g_assert_true (res == haystack + 3); + g_assert_cmpstr (res, ==, "BarFooBarFoo"); + + res = g_strstr_len (haystack, -1, "Bar"); + g_assert_true (res == haystack + 3); + g_assert_cmpstr (res, ==, "BarFooBarFoo"); + + /* strrstr */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_strrstr (NULL, "xxx"); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_strrstr ("xxx", NULL); + g_test_assert_expected_messages (); + } + + res = g_strrstr (haystack, "xxx"); + g_assert_null (res); + + res = g_strrstr (haystack, "FooBarFooBarFooBar"); + g_assert_null (res); + + res = g_strrstr (haystack, ""); + g_assert_true (res == haystack); + g_assert_cmpstr (res, ==, "FooBarFooBarFoo"); + + res = g_strrstr (haystack, "Bar"); + g_assert_true (res == haystack + 9); + g_assert_cmpstr (res, ==, "BarFoo"); + + /* strrstr_len */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_strrstr_len (NULL, 14, "xxx"); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_strrstr_len ("xxx", 14, NULL); + g_test_assert_expected_messages (); + } + + res = g_strrstr_len (haystack, 14, "xxx"); + g_assert_null (res); + + res = g_strrstr_len (haystack, 14, "FooBarFooBarFooBar"); + g_assert_null (res); + + res = g_strrstr_len (haystack, 3, "Bar"); + g_assert_null (res); + + res = g_strrstr_len (haystack, 14, "BarFoo"); + g_assert_true (res == haystack + 3); + g_assert_cmpstr (res, ==, "BarFooBarFoo"); + + res = g_strrstr_len (haystack, 15, "BarFoo"); + g_assert_true (res == haystack + 9); + g_assert_cmpstr (res, ==, "BarFoo"); + + res = g_strrstr_len (haystack, -1, "BarFoo"); + g_assert_true (res == haystack + 9); + g_assert_cmpstr (res, ==, "BarFoo"); + + /* test case for strings with \0 in the middle */ + *(haystack + 7) = '\0'; + res = g_strstr_len (haystack, 15, "BarFoo"); + g_assert_null (res); + + g_free (haystack); +} + +/* Testing g_strtod() function with various positive and negative cases */ +static void +test_strtod (void) +{ + gchar *str_end = NULL; + double value = 0.0; + const double gold_ratio = 1.61803398874989484; + const gchar *gold_ratio_str = "1.61803398874989484"; + const gchar *minus_gold_ratio_str = "-1.61803398874989484"; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + value = g_strtod (NULL, NULL); + g_test_assert_expected_messages (); + g_assert_cmpfloat (value, ==, 0.0); + } + + g_assert_cmpfloat (g_strtod ("\x00\x00\x00\x00", NULL), ==, 0.0); + g_assert_cmpfloat (g_strtod ("\x00\x00\x00\x00", &str_end), ==, 0.0); + g_assert_cmpstr (str_end, ==, ""); + g_assert_cmpfloat (g_strtod ("\xff\xff\xff\xff", NULL), ==, 0.0); + g_assert_cmpfloat (g_strtod ("\xff\xff\xff\xff", &str_end), ==, 0.0); + g_assert_cmpstr (str_end, ==, "\xff\xff\xff\xff"); + + /* Testing normal usage cases */ + g_assert_cmpfloat (g_strtod (gold_ratio_str, NULL), ==, gold_ratio); + g_assert_cmpfloat (g_strtod (gold_ratio_str, &str_end), ==, gold_ratio); + g_assert_true (str_end == gold_ratio_str + strlen (gold_ratio_str)); + g_assert_cmpfloat (g_strtod (minus_gold_ratio_str, NULL), ==, -gold_ratio); + g_assert_cmpfloat (g_strtod (minus_gold_ratio_str, &str_end), ==, -gold_ratio); + g_assert_true (str_end == minus_gold_ratio_str + strlen (minus_gold_ratio_str)); +} + +/* Testing g_strdelimit() function */ +static void +test_strdelimit (void) +{ + const gchar *const_string = "ABCDE<*>Q"; + gchar *string; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + string = g_strdelimit (NULL, "ABCDE", 'N'); + g_test_assert_expected_messages (); + } + + string = g_strdelimit (g_strdup (const_string), "<>", '?'); + g_assert_cmpstr (string, ==, "ABCDE?*?Q"); + g_free (string); + + string = g_strdelimit (g_strdup (const_string), NULL, '?'); + g_assert_cmpstr (string, ==, "ABCDE?*?Q"); + g_free (string); +} + +/* Testing g_str_has_prefix() */ +static void +test_has_prefix (void) +{ + gboolean res; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_str_has_prefix ("foo", NULL); + g_test_assert_expected_messages (); + g_assert_false (res); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_str_has_prefix (NULL, "foo"); + g_test_assert_expected_messages (); + g_assert_false (res); + } + + res = g_str_has_prefix ("foo", "bar"); + g_assert_cmpint (res, ==, FALSE); + + res = g_str_has_prefix ("foo", "foobar"); + g_assert_cmpint (res, ==, FALSE); + + res = g_str_has_prefix ("foobar", "bar"); + g_assert_cmpint (res, ==, FALSE); + + res = g_str_has_prefix ("foobar", "foo"); + g_assert_cmpint (res, ==, TRUE); + + res = g_str_has_prefix ("foo", ""); + g_assert_cmpint (res, ==, TRUE); + + res = g_str_has_prefix ("foo", "foo"); + g_assert_cmpint (res, ==, TRUE); + + res = g_str_has_prefix ("", ""); + g_assert_cmpint (res, ==, TRUE); +} + +static void +test_has_suffix (void) +{ + gboolean res; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_str_has_suffix ("foo", NULL); + g_test_assert_expected_messages (); + g_assert_false (res); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + res = g_str_has_suffix (NULL, "foo"); + g_test_assert_expected_messages (); + g_assert_false (res); + } + + res = g_str_has_suffix ("foo", "bar"); + g_assert_false (res); + + res = g_str_has_suffix ("bar", "foobar"); + g_assert_false (res); + + res = g_str_has_suffix ("foobar", "foo"); + g_assert_false (res); + + res = g_str_has_suffix ("foobar", "bar"); + g_assert_true (res); + + res = g_str_has_suffix ("foo", ""); + g_assert_true (res); + + res = g_str_has_suffix ("foo", "foo"); + g_assert_true (res); + + res = g_str_has_suffix ("", ""); + g_assert_true (res); +} + +static void +strv_check (gchar **strv, ...) +{ + gboolean ok = TRUE; + gint i = 0; + va_list list; + + va_start (list, strv); + while (ok) + { + const gchar *str = va_arg (list, const char *); + if (strv[i] == NULL) + { + g_assert_null (str); + break; + } + if (str == NULL) + { + ok = FALSE; + } + else + { + g_assert_cmpstr (strv[i], ==, str); + } + i++; + } + va_end (list); + + g_strfreev (strv); +} + +/* Testing g_strsplit() function with various positive and negative cases */ +static void +test_strsplit (void) +{ + gchar **string = NULL; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + string = g_strsplit (NULL, ",", 0); + g_test_assert_expected_messages (); + g_assert_null (string); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + string = g_strsplit ("x", NULL, 0); + g_test_assert_expected_messages (); + g_assert_null (string); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion \'delimiter[0] != \'\\0\'*"); + string = g_strsplit ("x", "", 0); + g_test_assert_expected_messages (); + g_assert_null (string); + } + + strv_check (g_strsplit ("", ",", 0), NULL); + strv_check (g_strsplit ("x", ",", 0), "x", NULL); + strv_check (g_strsplit ("x,y", ",", 0), "x", "y", NULL); + strv_check (g_strsplit ("x,y,", ",", 0), "x", "y", "", NULL); + strv_check (g_strsplit (",x,y", ",", 0), "", "x", "y", NULL); + strv_check (g_strsplit (",x,y,", ",", 0), "", "x", "y", "", NULL); + strv_check (g_strsplit ("x,y,z", ",", 0), "x", "y", "z", NULL); + strv_check (g_strsplit ("x,y,z,", ",", 0), "x", "y", "z", "", NULL); + strv_check (g_strsplit (",x,y,z", ",", 0), "", "x", "y", "z", NULL); + strv_check (g_strsplit (",x,y,z,", ",", 0), "", "x", "y", "z", "", NULL); + strv_check (g_strsplit (",,x,,y,,z,,", ",", 0), "", "", "x", "", "y", "", "z", "", "", NULL); + strv_check (g_strsplit (",,x,,y,,z,,", ",,", 0), "", "x", "y", "z", "", NULL); + + strv_check (g_strsplit ("", ",", 1), NULL); + strv_check (g_strsplit ("x", ",", 1), "x", NULL); + strv_check (g_strsplit ("x,y", ",", 1), "x,y", NULL); + strv_check (g_strsplit ("x,y,", ",", 1), "x,y,", NULL); + strv_check (g_strsplit (",x,y", ",", 1), ",x,y", NULL); + strv_check (g_strsplit (",x,y,", ",", 1), ",x,y,", NULL); + strv_check (g_strsplit ("x,y,z", ",", 1), "x,y,z", NULL); + strv_check (g_strsplit ("x,y,z,", ",", 1), "x,y,z,", NULL); + strv_check (g_strsplit (",x,y,z", ",", 1), ",x,y,z", NULL); + strv_check (g_strsplit (",x,y,z,", ",", 1), ",x,y,z,", NULL); + strv_check (g_strsplit (",,x,,y,,z,,", ",", 1), ",,x,,y,,z,,", NULL); + strv_check (g_strsplit (",,x,,y,,z,,", ",,", 1), ",,x,,y,,z,,", NULL); + + strv_check (g_strsplit ("", ",", 2), NULL); + strv_check (g_strsplit ("x", ",", 2), "x", NULL); + strv_check (g_strsplit ("x,y", ",", 2), "x", "y", NULL); + strv_check (g_strsplit ("x,y,", ",", 2), "x", "y,", NULL); + strv_check (g_strsplit (",x,y", ",", 2), "", "x,y", NULL); + strv_check (g_strsplit (",x,y,", ",", 2), "", "x,y,", NULL); + strv_check (g_strsplit ("x,y,z", ",", 2), "x", "y,z", NULL); + strv_check (g_strsplit ("x,y,z,", ",", 2), "x", "y,z,", NULL); + strv_check (g_strsplit (",x,y,z", ",", 2), "", "x,y,z", NULL); + strv_check (g_strsplit (",x,y,z,", ",", 2), "", "x,y,z,", NULL); + strv_check (g_strsplit (",,x,,y,,z,,", ",", 2), "", ",x,,y,,z,,", NULL); + strv_check (g_strsplit (",,x,,y,,z,,", ",,", 2), "", "x,,y,,z,,", NULL); +} + +/* Testing function g_strsplit_set() */ +static void +test_strsplit_set (void) +{ + gchar **string = NULL; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + string = g_strsplit_set (NULL, ",/", 0); + g_test_assert_expected_messages (); + g_assert_null (string); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + string = g_strsplit_set ("", NULL, 0); + g_test_assert_expected_messages (); + g_assert_null (string); + } + + strv_check (g_strsplit_set ("", ",/", 0), NULL); + strv_check (g_strsplit_set (":def/ghi:", ":/", -1), "", "def", "ghi", "", NULL); + strv_check (g_strsplit_set ("abc:def/ghi", ":/", -1), "abc", "def", "ghi", NULL); + strv_check (g_strsplit_set (",;,;,;,;", ",;", -1), "", "", "", "", "", "", "", "", "", NULL); + strv_check (g_strsplit_set (",,abc.def", ".,", -1), "", "", "abc", "def", NULL); + + strv_check (g_strsplit_set (",x.y", ",.", 0), "", "x", "y", NULL); + strv_check (g_strsplit_set (".x,y,", ",.", 0), "", "x", "y", "", NULL); + strv_check (g_strsplit_set ("x,y.z", ",.", 0), "x", "y", "z", NULL); + strv_check (g_strsplit_set ("x.y,z,", ",.", 0), "x", "y", "z", "", NULL); + strv_check (g_strsplit_set (",x.y,z", ",.", 0), "", "x", "y", "z", NULL); + strv_check (g_strsplit_set (",x,y,z,", ",.", 0), "", "x", "y", "z", "", NULL); + strv_check (g_strsplit_set (",.x,,y,;z..", ".,;", 0), "", "", "x", "", "y", "", "z", "", "", NULL); + strv_check (g_strsplit_set (",,x,,y,,z,,", ",,", 0), "", "", "x", "", "y", "", "z", "", "", NULL); + + strv_check (g_strsplit_set ("x,y.z", ",.", 1), "x,y.z", NULL); + strv_check (g_strsplit_set ("x.y,z,", ",.", 1), "x.y,z,", NULL); + strv_check (g_strsplit_set (",x,y,z", ",.", 1), ",x,y,z", NULL); + strv_check (g_strsplit_set (",x,y.z,", ",.", 1), ",x,y.z,", NULL); + strv_check (g_strsplit_set (",,x,.y,,z,,", ",.", 1), ",,x,.y,,z,,", NULL); + strv_check (g_strsplit_set (",.x,,y,,z,,", ",,..", 1), ",.x,,y,,z,,", NULL); + + strv_check (g_strsplit_set ("", ",", 0), NULL); + strv_check (g_strsplit_set ("x", ",", 0), "x", NULL); + strv_check (g_strsplit_set ("x,y", ",", 0), "x", "y", NULL); + strv_check (g_strsplit_set ("x,y,", ",", 0), "x", "y", "", NULL); + strv_check (g_strsplit_set (",x,y", ",", 0), "", "x", "y", NULL); + strv_check (g_strsplit_set (",x,y,", ",", 0), "", "x", "y", "", NULL); + strv_check (g_strsplit_set ("x,y,z", ",", 0), "x", "y", "z", NULL); + strv_check (g_strsplit_set ("x,y,z,", ",", 0), "x", "y", "z", "", NULL); + strv_check (g_strsplit_set (",x,y,z", ",", 0), "", "x", "y", "z", NULL); + strv_check (g_strsplit_set (",x,y,z,", ",", 0), "", "x", "y", "z", "", NULL); + strv_check (g_strsplit_set (",,x,,y,,z,,", ",", 0), "", "", "x", "", "y", "", "z", "", "", NULL); + + strv_check (g_strsplit_set ("", ",", 1), NULL); + strv_check (g_strsplit_set ("x", ",", 1), "x", NULL); + strv_check (g_strsplit_set ("x,y", ",", 1), "x,y", NULL); + strv_check (g_strsplit_set ("x,y,", ",", 1), "x,y,", NULL); + strv_check (g_strsplit_set (",x,y", ",", 1), ",x,y", NULL); + strv_check (g_strsplit_set (",x,y,", ",", 1), ",x,y,", NULL); + strv_check (g_strsplit_set ("x,y,z", ",", 1), "x,y,z", NULL); + strv_check (g_strsplit_set ("x,y,z,", ",", 1), "x,y,z,", NULL); + strv_check (g_strsplit_set (",x,y,z", ",", 1), ",x,y,z", NULL); + strv_check (g_strsplit_set (",x,y,z,", ",", 1), ",x,y,z,", NULL); + strv_check (g_strsplit_set (",,x,,y,,z,,", ",", 1), ",,x,,y,,z,,", NULL); + strv_check (g_strsplit_set (",,x,,y,,z,,", ",,", 1), ",,x,,y,,z,,", NULL); + + strv_check (g_strsplit_set ("", ",", 2), NULL); + strv_check (g_strsplit_set ("x", ",", 2), "x", NULL); + strv_check (g_strsplit_set ("x,y", ",", 2), "x", "y", NULL); + strv_check (g_strsplit_set ("x,y,", ",", 2), "x", "y,", NULL); + strv_check (g_strsplit_set (",x,y", ",", 2), "", "x,y", NULL); + strv_check (g_strsplit_set (",x,y,", ",", 2), "", "x,y,", NULL); + strv_check (g_strsplit_set ("x,y,z", ",", 2), "x", "y,z", NULL); + strv_check (g_strsplit_set ("x,y,z,", ",", 2), "x", "y,z,", NULL); + strv_check (g_strsplit_set (",x,y,z", ",", 2), "", "x,y,z", NULL); + strv_check (g_strsplit_set (",x,y,z,", ",", 2), "", "x,y,z,", NULL); + strv_check (g_strsplit_set (",,x,,y,,z,,", ",", 2), "", ",x,,y,,z,,", NULL); + + strv_check (g_strsplit_set (",,x,.y,..z,,", ",.", 3), "", "", "x,.y,..z,,", NULL); +} + +/* Testing g_strv_length() function with various positive and negative cases */ +static void +test_strv_length (void) +{ + gchar **strv; + guint l; + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + l = g_strv_length (NULL); + g_test_assert_expected_messages (); + g_assert_cmpint (l, ==, 0); + } + + strv = g_strsplit ("1,2,3,4", ",", -1); + l = g_strv_length (strv); + g_assert_cmpuint (l, ==, 4); + g_strfreev (strv); +} + +static char *locales[] = {"sv_SE", "en_US", "fa_IR", "C", "ru_RU"}; + +static void +check_strtod_string (gchar *number, + double res, + gboolean check_end, + gsize correct_len) +{ + double d; + gsize l; + gchar *dummy; + + /* we try a copy of number, with some free space for malloc before that. + * This is supposed to smash the some wrong pointer calculations. */ + + dummy = g_malloc (100000); + number = g_strdup (number); + g_free (dummy); + + for (l = 0; l < G_N_ELEMENTS (locales); l++) + { + gchar *end = "(unset)"; + + setlocale (LC_NUMERIC, locales[l]); + d = g_ascii_strtod (number, &end); + g_assert_true (isnan (res) ? isnan (d) : (d == res)); + g_assert_true ((gsize) (end - number) == + (check_end ? correct_len : strlen (number))); + } + + g_free (number); +} + +static void +check_strtod_number (gdouble num, gchar *fmt, gchar *str) +{ + gsize l; + gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; + + for (l = 0; l < G_N_ELEMENTS (locales); l++) + { + setlocale (LC_ALL, locales[l]); + g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, fmt, num); + g_assert_cmpstr (buf, ==, str); + } +} + +/* Testing g_ascii_strtod() function with various positive and negative cases */ +static void +test_ascii_strtod (void) +{ + gdouble d, our_nan, our_inf; + char buffer[G_ASCII_DTOSTR_BUF_SIZE]; + +#ifdef NAN + our_nan = NAN; +#else + /* Do this before any call to setlocale. */ + our_nan = atof ("NaN"); +#endif + g_assert_true (isnan (our_nan)); + +#ifdef INFINITY + our_inf = INFINITY; +#else + our_inf = atof ("Infinity"); +#endif + g_assert_true (our_inf > 1 && our_inf == our_inf / 2); + + /* Testing degenerated cases */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + d = g_ascii_strtod (NULL, NULL); + g_test_assert_expected_messages (); + } + + /* Testing normal cases */ + check_strtod_string ("123.123", 123.123, FALSE, 0); + check_strtod_string ("123.123e2", 123.123e2, FALSE, 0); + check_strtod_string ("123.123e-2", 123.123e-2, FALSE, 0); + check_strtod_string ("-123.123", -123.123, FALSE, 0); + check_strtod_string ("-123.123e2", -123.123e2, FALSE, 0); + check_strtod_string ("-123.123e-2", -123.123e-2, FALSE, 0); + check_strtod_string ("5.4", 5.4, TRUE, 3); + check_strtod_string ("5.4,5.5", 5.4, TRUE, 3); + check_strtod_string ("5,4", 5.0, TRUE, 1); +#ifndef _MSC_VER + /* hex strings for strtod() is a C99 feature which Visual C++ does not support */ + check_strtod_string ("0xa.b", 10.6875, TRUE, 5); + check_strtod_string ("0xa.bP3", 85.5, TRUE, 7); + check_strtod_string ("0xa.bp+3", 85.5, TRUE, 8); + check_strtod_string ("0xa.bp-2", 2.671875, TRUE, 8); + check_strtod_string ("0xA.BG", 10.6875, TRUE, 5); +#endif + /* the following are for #156421 */ + check_strtod_string ("1e1", 1e1, FALSE, 0); +#ifndef _MSC_VER + /* NAN/-nan/INF/-infinity strings for strtod() are C99 features which Visual C++ does not support */ + check_strtod_string ("NAN", our_nan, FALSE, 0); + check_strtod_string ("-nan", -our_nan, FALSE, 0); + check_strtod_string ("INF", our_inf, FALSE, 0); + check_strtod_string ("-infinity", -our_inf, FALSE, 0); +#endif + check_strtod_string ("-.75,0", -0.75, TRUE, 4); + +#ifndef _MSC_VER + /* the values of d in the following 2 tests generate a C1064 compiler limit error */ + d = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0; + g_assert_true (d == g_ascii_strtod (g_ascii_dtostr (buffer, sizeof (buffer), d), NULL)); + + d = -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0; + g_assert_true (d == g_ascii_strtod (g_ascii_dtostr (buffer, sizeof (buffer), d), NULL)); +#endif + + d = pow (2.0, -1024.1); + g_assert_true (d == g_ascii_strtod (g_ascii_dtostr (buffer, sizeof (buffer), d), NULL)); + + d = -pow (2.0, -1024.1); + g_assert_true (d == g_ascii_strtod (g_ascii_dtostr (buffer, sizeof (buffer), d), NULL)); + + /* for #343899 */ + check_strtod_string (" 0.75", 0.75, FALSE, 0); + check_strtod_string (" +0.75", 0.75, FALSE, 0); + check_strtod_string (" -0.75", -0.75, FALSE, 0); + check_strtod_string ("\f0.75", 0.75, FALSE, 0); + check_strtod_string ("\n0.75", 0.75, FALSE, 0); + check_strtod_string ("\r0.75", 0.75, FALSE, 0); + check_strtod_string ("\t0.75", 0.75, FALSE, 0); + +#if 0 + /* g_ascii_isspace() returns FALSE for vertical tab, see #59388 */ + check_strtod_string ("\v0.75", 0.75, FALSE, 0); +#endif + + /* for #343899 */ + check_strtod_number (0.75, "%0.2f", "0.75"); + check_strtod_number (0.75, "%5.2f", " 0.75"); + check_strtod_number (-0.75, "%0.2f", "-0.75"); + check_strtod_number (-0.75, "%5.2f", "-0.75"); + check_strtod_number (1e99, "%.0e", "1e+99"); +} + +static void +check_uint64 (const gchar *str, + const gchar *end, + gint base, + guint64 result, + gint error) +{ + guint64 actual; + gchar *endptr = NULL; + gint err; + + errno = 0; + actual = g_ascii_strtoull (str, &endptr, base); + err = errno; + + g_assert_true (actual == result); + g_assert_cmpstr (end, ==, endptr); + g_assert_true (err == error); +} + +static void +check_int64 (const gchar *str, + const gchar *end, + gint base, + gint64 result, + gint error) +{ + gint64 actual; + gchar *endptr = NULL; + gint err; + + errno = 0; + actual = g_ascii_strtoll (str, &endptr, base); + err = errno; + + g_assert_true (actual == result); + g_assert_cmpstr (end, ==, endptr); + g_assert_true (err == error); +} + +static void +test_strtoll (void) +{ + check_uint64 ("0", "", 10, 0, 0); + check_uint64 ("+0", "", 10, 0, 0); + check_uint64 ("-0", "", 10, 0, 0); + check_uint64 ("18446744073709551615", "", 10, G_MAXUINT64, 0); + check_uint64 ("18446744073709551616", "", 10, G_MAXUINT64, ERANGE); + check_uint64 ("20xyz", "xyz", 10, 20, 0); + check_uint64 ("-1", "", 10, G_MAXUINT64, 0); + check_uint64 ("-FF4", "", 16, -((guint64) 0xFF4), 0); + + check_int64 ("0", "", 10, 0, 0); + check_int64 ("9223372036854775807", "", 10, G_MAXINT64, 0); + check_int64 ("9223372036854775808", "", 10, G_MAXINT64, ERANGE); + check_int64 ("-9223372036854775808", "", 10, G_MININT64, 0); + check_int64 ("-9223372036854775809", "", 10, G_MININT64, ERANGE); + check_int64 ("32768", "", 10, 32768, 0); + check_int64 ("-32768", "", 10, -32768, 0); + check_int64 ("001", "", 10, 1, 0); + check_int64 ("-001", "", 10, -1, 0); +} + +/* Testing g_str_match_string() function with various cases */ +static void +test_str_match_string (void) +{ + gboolean result = TRUE; + const gchar *str = "The quick brown fox¸ jumps over the lazy dog."; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_str_match_string (NULL, "AAA", TRUE); + g_test_assert_expected_messages (); + g_assert_false (result); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_str_match_string (str, NULL, TRUE); + g_test_assert_expected_messages (); + g_assert_false (result); + } + + g_assert_false (g_str_match_string (str, "AAA", TRUE)); + g_assert_false (g_str_match_string (str, "AAA", FALSE)); +} + +/* Testing functions bounds */ +static void +test_bounds (void) +{ + GMappedFile *file, *before, *after; + char buffer[4097]; + char *tmp, *tmp2; + char **array; + char *string; + const char * const strjoinv_0[] = { NULL }; + const char * const strjoinv_1[] = { "foo", NULL }; + + /* if we allocate the file between two others and then free those + * other two, then hopefully we end up with unmapped memory on either + * side. + */ + before = g_mapped_file_new ("4096-random-bytes", TRUE, NULL); + + /* quick workaround until #549783 can be fixed */ + if (before == NULL) + return; + + file = g_mapped_file_new ("4096-random-bytes", TRUE, NULL); + after = g_mapped_file_new ("4096-random-bytes", TRUE, NULL); + g_mapped_file_unref (before); + g_mapped_file_unref (after); + + g_assert_nonnull (file); + g_assert_cmpint (g_mapped_file_get_length (file), ==, 4096); + string = g_mapped_file_get_contents (file); + + /* ensure they're all non-nul */ + g_assert_null (memchr (string, '\0', 4096)); + + /* test set 1: ensure that nothing goes past its maximum length, even in + * light of a missing nul terminator. + * + * we try to test all of the 'n' functions here. + */ + tmp = g_strndup (string, 4096); + g_assert_cmpint (strlen (tmp), ==, 4096); + g_free (tmp); + + /* found no bugs in gnome, i hope :) */ + g_assert_null (g_strstr_len (string, 4096, "BUGS")); + g_strstr_len (string, 4096, "B"); + g_strstr_len (string, 4096, "."); + g_strstr_len (string, 4096, ""); + + g_strrstr_len (string, 4096, "BUGS"); + g_strrstr_len (string, 4096, "B"); + g_strrstr_len (string, 4096, "."); + g_strrstr_len (string, 4096, ""); + + tmp = g_ascii_strup (string, 4096); + tmp2 = g_ascii_strup (tmp, 4096); + g_assert_cmpint (g_ascii_strncasecmp (string, tmp, 4096), ==, 0); + g_assert_cmpint (g_ascii_strncasecmp (string, tmp2, 4096), ==, 0); + g_assert_cmpint (g_ascii_strncasecmp (tmp, tmp2, 4096), ==, 0); + g_free (tmp); + g_free (tmp2); + + tmp = g_ascii_strdown (string, 4096); + tmp2 = g_ascii_strdown (tmp, 4096); + g_assert_cmpint (g_ascii_strncasecmp (string, tmp, 4096), ==, 0); + g_assert_cmpint (g_ascii_strncasecmp (string, tmp2, 4096), ==, 0); + g_assert_cmpint (g_ascii_strncasecmp (tmp, tmp2, 4096), ==, 0); + g_free (tmp); + g_free (tmp2); + + tmp = g_markup_escape_text (string, 4096); + g_free (tmp); + + /* test set 2: ensure that nothing reads even one byte past a '\0'. + */ + g_assert_cmpint (string[4095], ==, '\n'); + string[4095] = '\0'; + + tmp = g_strdup (string); + g_assert_cmpint (strlen (tmp), ==, 4095); + g_free (tmp); + + tmp = g_strndup (string, 10000); + g_assert_cmpint (strlen (tmp), ==, 4095); + g_free (tmp); + + g_stpcpy (buffer, string); + g_assert_cmpint (strlen (buffer), ==, 4095); + + g_strstr_len (string, 10000, "BUGS"); + g_strstr_len (string, 10000, "B"); + g_strstr_len (string, 10000, "."); + g_strstr_len (string, 10000, ""); + + g_strrstr (string, "BUGS"); + g_strrstr (string, "B"); + g_strrstr (string, "."); + g_strrstr (string, ""); + + g_strrstr_len (string, 10000, "BUGS"); + g_strrstr_len (string, 10000, "B"); + g_strrstr_len (string, 10000, "."); + g_strrstr_len (string, 10000, ""); + + g_str_has_prefix (string, "this won't do very much..."); + g_str_has_suffix (string, "but maybe this will..."); + g_str_has_suffix (string, "HMMMM."); + g_str_has_suffix (string, "MMMM."); + g_str_has_suffix (string, "M."); + + g_strlcpy (buffer, string, sizeof buffer); + g_assert_cmpint (strlen (buffer), ==, 4095); + g_strlcpy (buffer, string, sizeof buffer); + buffer[0] = '\0'; + g_strlcat (buffer, string, sizeof buffer); + g_assert_cmpint (strlen (buffer), ==, 4095); + + tmp = g_strdup_printf ("<%s>", string); + g_assert_cmpint (strlen (tmp), ==, 4095 + 2); + g_free (tmp); + + tmp = g_ascii_strdown (string, -1); + tmp2 = g_ascii_strdown (tmp, -1); + g_assert_cmpint (strlen (tmp), ==, strlen (tmp2)); + g_assert_cmpint (strlen (string), ==, strlen (tmp)); + g_assert_cmpint (g_ascii_strncasecmp (string, tmp, -1), ==, 0); + g_assert_cmpint (g_ascii_strncasecmp (string, tmp2, -1), ==, 0); + g_assert_cmpint (g_ascii_strncasecmp (tmp, tmp2, -1), ==, 0); + g_free (tmp); + g_free (tmp2); + + tmp = g_ascii_strup (string, -1); + tmp2 = g_ascii_strup (string, -1); + g_assert_cmpint (strlen (tmp), ==, strlen (tmp2)); + g_assert_cmpint (strlen (string), ==, strlen (tmp)); + g_assert_cmpint (g_ascii_strncasecmp (string, tmp, -1), ==, 0); + g_assert_cmpint (g_ascii_strncasecmp (string, tmp2, -1), ==, 0); + g_assert_cmpint (g_ascii_strncasecmp (tmp, tmp2, -1), ==, 0); + g_free (tmp); + g_free (tmp2); + + g_ascii_strcasecmp (string, string); + g_ascii_strncasecmp (string, string, 10000); + + g_strreverse (string); + g_strreverse (string); + g_strchug (string); + g_strchomp (string); + g_strstrip (string); + g_assert_cmpint (strlen (string), ==, 4095); + + g_strdelimit (string, "M", 'N'); + g_strcanon (string, " N.", ':'); + g_assert_cmpint (strlen (string), ==, 4095); + + array = g_strsplit (string, ".", -1); + tmp = g_strjoinv (".", array); + g_strfreev (array); + + g_assert_cmpmem (tmp, strlen (tmp), string, 4095); + g_free (tmp); + + tmp = g_strjoinv ("/", (char **) strjoinv_0); + g_assert_cmpstr (tmp, ==, ""); + g_free (tmp); + + tmp = g_strjoinv ("/", (char **) strjoinv_1); + g_assert_cmpstr (tmp, ==, "foo"); + g_free (tmp); + + tmp = g_strconcat (string, string, string, NULL); + g_assert_cmpint (strlen (tmp), ==, 4095 * 3); + g_free (tmp); + + tmp = g_strjoin ("!", string, string, NULL); + g_assert_cmpint (strlen (tmp), ==, 4095 + 1 + 4095); + g_free (tmp); + + tmp = g_markup_escape_text (string, -1); + g_free (tmp); + + tmp = g_markup_printf_escaped ("%s", string); + g_free (tmp); + + tmp = g_strescape (string, NULL); + tmp2 = g_strcompress (tmp); + g_assert_cmpstr (string, ==, tmp2); + g_free (tmp2); + g_free (tmp); + + g_mapped_file_unref (file); +} + +/* Testing g_strip_context() function with various cases */ +static void +test_strip_context (void) +{ + const gchar *msgid; + const gchar *msgval; + const gchar *s; + + msgid = "blabla"; + msgval = "bla"; + s = g_strip_context (msgid, msgval); + g_assert_true (s == msgval); + + msgid = msgval = "blabla"; + s = g_strip_context (msgid, msgval); + g_assert_true (s == msgval); + + msgid = msgval = "blabla|foo"; + s = g_strip_context (msgid, msgval); + g_assert_true (s == msgval + 7); + + msgid = msgval = "blabla||bar"; + s = g_strip_context (msgid, msgval); + g_assert_true (s == msgval + 7); +} + +/* Test the strings returned by g_strerror() are valid and unique. On Windows, + * fewer than 200 error numbers are used, so we expect some strings to + * return a generic ‘unknown error code’ message. */ +static void +test_strerror (void) +{ + GHashTable *strs; + gint i; + const gchar *str, *unknown_str; + + setlocale (LC_ALL, "C"); + + unknown_str = g_strerror (-1); + strs = g_hash_table_new (g_str_hash, g_str_equal); + for (i = 1; i < 200; i++) + { + gboolean is_unknown; + str = g_strerror (i); + is_unknown = (strcmp (str, unknown_str) == 0); + g_assert_nonnull (str); + g_assert_true (g_utf8_validate (str, -1, NULL)); + g_assert_true (!g_hash_table_contains (strs, str) || is_unknown); + g_hash_table_add (strs, (gpointer) str); + } + + g_hash_table_unref (strs); +} + +/* Testing g_strsignal() function with various cases */ +static void +test_strsignal (void) +{ + gint i; + const gchar *str; + + for (i = 1; i < 20; i++) + { + str = g_strsignal (i); + g_assert_nonnull (str); + g_assert_true (g_utf8_validate (str, -1, NULL)); + } +} + +/* Testing g_strup(), g_strdown() and g_strcasecmp() */ +static void +test_strup (void) +{ + gchar *s = NULL; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + s = g_strup (NULL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + s = g_strdown (NULL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_strcasecmp (NULL, "ABCD"); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_strcasecmp ("abcd", NULL); + g_test_assert_expected_messages (); + } + + s = g_strdup ("lower UPPER"); + g_assert_cmpstr (g_strup (s), ==, "LOWER UPPER"); + g_assert_cmpstr (g_strdown (s), ==, "lower upper"); + g_assert_true (g_strcasecmp ("lower", "LOWER") == 0); + g_free (s); +} + +/* Testing g_str_to_ascii() function with various cases */ +static void +test_transliteration (void) +{ + gchar *out; + + /* ...to test the defaults */ + setlocale (LC_ALL, "C"); + + /* Test something trivial */ + out = g_str_to_ascii ("hello", NULL); + g_assert_cmpstr (out, ==, "hello"); + g_free (out); + + /* Test something above 0xffff */ + out = g_str_to_ascii ("ð€ð€ð€", NULL); + g_assert_cmpstr (out, ==, "AAA"); + g_free (out); + + /* Test something with no good match */ + out = g_str_to_ascii ("a ∧ ¬a", NULL); + g_assert_cmpstr (out, ==, "a ? ?a"); + g_free (out); + + /* Make sure 'ö' is handled differently per locale */ + out = g_str_to_ascii ("ö", NULL); + g_assert_cmpstr (out, ==, "o"); + g_free (out); + + out = g_str_to_ascii ("ö", "sv"); + g_assert_cmpstr (out, ==, "o"); + g_free (out); + + out = g_str_to_ascii ("ö", "de"); + g_assert_cmpstr (out, ==, "oe"); + g_free (out); + + /* Make sure we can find a locale by a wide range of names */ + out = g_str_to_ascii ("ö", "de_DE"); + g_assert_cmpstr (out, ==, "oe"); + g_free (out); + + out = g_str_to_ascii ("ö", "de_DE.UTF-8"); + g_assert_cmpstr (out, ==, "oe"); + g_free (out); + + out = g_str_to_ascii ("ö", "de_DE.UTF-8@euro"); + g_assert_cmpstr (out, ==, "oe"); + g_free (out); + + out = g_str_to_ascii ("ö", "de@euro"); + g_assert_cmpstr (out, ==, "oe"); + g_free (out); + + /* Test some invalid locale names */ + out = g_str_to_ascii ("ö", "de_DE@euro.UTF-8"); + g_assert_cmpstr (out, ==, "o"); + g_free (out); + + out = g_str_to_ascii ("ö", "de@DE@euro"); + g_assert_cmpstr (out, ==, "o"); + g_free (out); + + out = g_str_to_ascii ("ö", "doesnotexist"); + g_assert_cmpstr (out, ==, "o"); + g_free (out); + + out = g_str_to_ascii ("ö", "thislocalenameistoolong"); + g_assert_cmpstr (out, ==, "o"); + g_free (out); + + /* Try a lookup of a locale with a variant */ + out = g_str_to_ascii ("б", "sr_RS"); + g_assert_cmpstr (out, ==, "b"); + g_free (out); + + out = g_str_to_ascii ("б", "sr_RS@latin"); + g_assert_cmpstr (out, ==, "?"); + g_free (out); + + /* Ukrainian contains the only multi-character mappings. + * Try a string that contains one ('зг') along with a partial + * sequence ('з') at the end. + */ + out = g_str_to_ascii ("Зліва направо, згори вниз", "uk"); + g_assert_cmpstr (out, ==, "Zliva napravo, zghory vnyz"); + g_free (out); + + /* Try out the other combinations */ + out = g_str_to_ascii ("Зг", "uk"); + g_assert_cmpstr (out, ==, "Zgh"); + g_free (out); + + out = g_str_to_ascii ("зГ", "uk"); + g_assert_cmpstr (out, ==, "zGH"); + g_free (out); + + out = g_str_to_ascii ("ЗГ", "uk"); + g_assert_cmpstr (out, ==, "ZGH"); + g_free (out); + + /* And a non-combination */ + out = g_str_to_ascii ("зÑ", "uk"); + g_assert_cmpstr (out, ==, "zya"); + g_free (out); +} + +/* Testing g_strv_contains() function with various cases */ +static void +test_strv_contains (void) +{ + gboolean result = TRUE; + const gchar *strv_simple[] = { "hello", "there", NULL }; + const gchar *strv_dupe[] = { "dupe", "dupe", NULL }; + const gchar *strv_empty[] = { NULL }; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_strv_contains (NULL, "hello"); + g_test_assert_expected_messages (); + g_assert_false (result); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_strv_contains (strv_simple, NULL); + g_test_assert_expected_messages (); + g_assert_false (result); + } + + g_assert_true (g_strv_contains (strv_simple, "hello")); + g_assert_true (g_strv_contains (strv_simple, "there")); + g_assert_false (g_strv_contains (strv_simple, "non-existent")); + g_assert_false (g_strv_contains (strv_simple, "")); + + g_assert_true (g_strv_contains (strv_dupe, "dupe")); + + g_assert_false (g_strv_contains (strv_empty, "empty!")); + g_assert_false (g_strv_contains (strv_empty, "")); +} + +/* Test g_strv_equal() works for various inputs. */ +static void +test_strv_equal (void) +{ + gboolean result = TRUE; + const gchar *strv_empty[] = { NULL }; + const gchar *strv_empty2[] = { NULL }; + const gchar *strv_simple[] = { "hello", "you", NULL }; + const gchar *strv_simple2[] = { "hello", "you", NULL }; + const gchar *strv_simple_reordered[] = { "you", "hello", NULL }; + const gchar *strv_simple_superset[] = { "hello", "you", "again", NULL }; + const gchar *strv_another[] = { "not", "a", "coded", "message", NULL }; + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_strv_equal (NULL, strv_simple2); + g_test_assert_expected_messages (); + g_assert_false (result); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_strv_equal (strv_simple, NULL); + g_test_assert_expected_messages (); + g_assert_false (result); + } + + g_assert_true (g_strv_equal (strv_empty, strv_empty)); + g_assert_true (g_strv_equal (strv_empty, strv_empty2)); + g_assert_true (g_strv_equal (strv_empty2, strv_empty)); + g_assert_false (g_strv_equal (strv_empty, strv_simple)); + g_assert_false (g_strv_equal (strv_simple, strv_empty)); + g_assert_true (g_strv_equal (strv_simple, strv_simple)); + g_assert_true (g_strv_equal (strv_simple, strv_simple2)); + g_assert_true (g_strv_equal (strv_simple2, strv_simple)); + g_assert_false (g_strv_equal (strv_simple, strv_simple_reordered)); + g_assert_false (g_strv_equal (strv_simple_reordered, strv_simple)); + g_assert_false (g_strv_equal (strv_simple, strv_simple_superset)); + g_assert_false (g_strv_equal (strv_simple_superset, strv_simple)); + g_assert_false (g_strv_equal (strv_simple, strv_another)); + g_assert_false (g_strv_equal (strv_another, strv_simple)); +} + +typedef enum + { + SIGNED, + UNSIGNED + } SignType; + +typedef struct +{ + const gchar *str; + SignType sign_type; + guint base; + gint min; + gint max; + gint expected; + gboolean should_fail; + GNumberParserError error_code; +} TestData; + +const TestData test_data[] = { + /* typical cases for signed */ + { "0", SIGNED, 10, -2, 2, 0, FALSE, 0 }, + { "+0", SIGNED, 10, -2, 2, 0, FALSE, 0 }, + { "-0", SIGNED, 10, -2, 2, 0, FALSE, 0 }, + { "-2", SIGNED, 10, -2, 2, -2, FALSE, 0 }, + {"-02", SIGNED, 10, -2, 2, -2, FALSE, 0 }, + { "2", SIGNED, 10, -2, 2, 2, FALSE, 0 }, + { "02", SIGNED, 10, -2, 2, 2, FALSE, 0 }, + { "+2", SIGNED, 10, -2, 2, 2, FALSE, 0 }, + {"+02", SIGNED, 10, -2, 2, 2, FALSE, 0 }, + { "3", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS }, + { "+3", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS }, + { "-3", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS }, + + /* typical cases for unsigned */ + { "-1", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "1", UNSIGNED, 10, 0, 2, 1, FALSE, 0 }, + { "+1", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "0", UNSIGNED, 10, 0, 2, 0, FALSE, 0 }, + { "+0", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "-0", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "2", UNSIGNED, 10, 0, 2, 2, FALSE, 0 }, + { "+2", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "3", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS }, + { "+3", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + + /* min == max cases for signed */ + { "-2", SIGNED, 10, -2, -2, -2, FALSE, 0 }, + { "-1", SIGNED, 10, -2, -2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS }, + { "-3", SIGNED, 10, -2, -2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS }, + + /* min == max cases for unsigned */ + { "2", UNSIGNED, 10, 2, 2, 2, FALSE, 0 }, + { "3", UNSIGNED, 10, 2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS }, + { "1", UNSIGNED, 10, 2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS }, + + /* invalid inputs */ + { "", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "a", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "a", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "1a", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "1a", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "- 1", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + + /* leading/trailing whitespace */ + { " 1", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { " 1", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "1 ", SIGNED, 10, -2, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "1 ", UNSIGNED, 10, 0, 2, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + + /* hexadecimal numbers */ + { "a", SIGNED, 16, 0, 15, 10, FALSE, 0 }, + { "a", UNSIGNED, 16, 0, 15, 10, FALSE, 0 }, + { "0a", UNSIGNED, 16, 0, 15, 10, FALSE, 0 }, + { "0xa", SIGNED, 16, 0, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "0xa", UNSIGNED, 16, 0, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "-0xa", SIGNED, 16, -15, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "-0xa", UNSIGNED, 16, 0, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "+0xa", SIGNED, 16, 0, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "+0xa", UNSIGNED, 16, 0, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "- 0xa", SIGNED, 16, -15, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "- 0xa", UNSIGNED, 16, 0, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "+ 0xa", SIGNED, 16, -15, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, + { "+ 0xa", UNSIGNED, 16, 0, 15, 0, TRUE, G_NUMBER_PARSER_ERROR_INVALID }, +}; + +/* Testing g_ascii_string_to_signed() and g_ascii_string_to_unsigned() functions */ +static void +test_ascii_string_to_number_usual (void) +{ + gsize idx; + gboolean result; + GError *error = NULL; + const TestData *data; + gint value; + gint64 value64 = 0; + guint64 valueu64 = 0; + + /*** g_ascii_string_to_signed() ***/ + data = &test_data[0]; /* Setting data to signed data */ + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_ascii_string_to_signed (NULL, + data->base, + data->min, + data->max, + &value64, + &error); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion \'base >= 2 && base <= 36\'*"); + result = g_ascii_string_to_signed (data->str, + 1, + data->min, + data->max, + &value64, + &error); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion \'base >= 2 && base <= 36\'*"); + result = g_ascii_string_to_signed (data->str, + 40, + data->min, + data->max, + &value64, + &error); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion \'min <= max\'*"); + result = g_ascii_string_to_signed (data->str, + data->base, + data->max, + data->min, + &value64, + &error); + g_test_assert_expected_messages (); + } + + /* Catching first part of (error == NULL || *error == NULL) */ + result = g_ascii_string_to_signed (data->str, + data->base, + data->min, + data->max, + &value64, + NULL); + + /*** g_ascii_string_to_unsigned() ***/ + data = &test_data[12]; /* Setting data to unsigned data */ + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + result = g_ascii_string_to_unsigned (NULL, + data->base, + data->min, + data->max, + &valueu64, + &error); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion \'base >= 2 && base <= 36\'*"); + result = g_ascii_string_to_unsigned (data->str, + 1, + data->min, + data->max, + &valueu64, + &error); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion \'base >= 2 && base <= 36\'*"); + result = g_ascii_string_to_unsigned (data->str, + 40, + data->min, + data->max, + &valueu64, + &error); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion \'min <= max\'*"); + result = g_ascii_string_to_unsigned (data->str, + data->base, + data->max, + data->min, + &valueu64, + &error); + g_test_assert_expected_messages (); + } + + /* Catching first part of (error == NULL || *error == NULL) */ + result = g_ascii_string_to_unsigned (data->str, + data->base, + data->min, + data->max, + &valueu64, + NULL); + + /* Testing usual cases */ + for (idx = 0; idx < G_N_ELEMENTS (test_data); ++idx) + { + data = &test_data[idx]; + + switch (data->sign_type) + { + case SIGNED: + { + result = g_ascii_string_to_signed (data->str, + data->base, + data->min, + data->max, + &value64, + &error); + value = value64; + g_assert_cmpint (value, ==, value64); + break; + } + + case UNSIGNED: + { + result = g_ascii_string_to_unsigned (data->str, + data->base, + data->min, + data->max, + &valueu64, + &error); + value = valueu64; + g_assert_cmpint (value, ==, valueu64); + break; + } + + default: + g_assert_not_reached (); + } + + if (data->should_fail) + { + g_assert_false (result); + g_assert_error (error, G_NUMBER_PARSER_ERROR, (gint) data->error_code); + g_clear_error (&error); + } + else + { + g_assert_true (result); + g_assert_no_error (error); + g_assert_cmpint (value, ==, data->expected); + } + } +} + +/* Testing pathological cases for g_ascii_string_to_(un)signed() */ +static void +test_ascii_string_to_number_pathological (void) +{ + GError *error = NULL; + const gchar *crazy_high = "999999999999999999999999999999999999"; + const gchar *crazy_low = "-999999999999999999999999999999999999"; + const gchar *max_uint64 = "18446744073709551615"; + const gchar *max_int64 = "9223372036854775807"; + const gchar *min_int64 = "-9223372036854775808"; + guint64 uvalue = 0; + gint64 svalue = 0; + + g_assert_false (g_ascii_string_to_unsigned (crazy_high, + 10, + 0, + G_MAXUINT64, + NULL, + &error)); + g_assert_error (error, G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS); + g_clear_error (&error); + g_assert_false (g_ascii_string_to_unsigned (crazy_low, + 10, + 0, + G_MAXUINT64, + NULL, + &error)); + // crazy_low is a signed number so it is not a valid unsigned number + g_assert_error (error, G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_INVALID); + g_clear_error (&error); + + g_assert_false (g_ascii_string_to_signed (crazy_high, + 10, + G_MININT64, + G_MAXINT64, + NULL, + &error)); + g_assert_error (error, G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS); + g_clear_error (&error); + g_assert_false (g_ascii_string_to_signed (crazy_low, + 10, + G_MININT64, + G_MAXINT64, + NULL, + &error)); + g_assert_error (error, G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS); + g_clear_error (&error); + + g_assert_true (g_ascii_string_to_unsigned (max_uint64, + 10, + 0, + G_MAXUINT64, + &uvalue, + &error)); + g_assert_no_error (error); + g_assert_cmpint (uvalue, ==, G_MAXUINT64); + + g_assert_true (g_ascii_string_to_signed (max_int64, + 10, + G_MININT64, + G_MAXINT64, + &svalue, + &error)); + g_assert_no_error (error); + g_assert_cmpint (svalue, ==, G_MAXINT64); + + g_assert_true (g_ascii_string_to_signed (min_int64, + 10, + G_MININT64, + G_MAXINT64, + &svalue, + &error)); + g_assert_no_error (error); + g_assert_cmpint (svalue, ==, G_MININT64); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/strfuncs/ascii-strcasecmp", test_ascii_strcasecmp); + g_test_add_func ("/strfuncs/ascii-string-to-num/pathological", test_ascii_string_to_number_pathological); + g_test_add_func ("/strfuncs/ascii-string-to-num/usual", test_ascii_string_to_number_usual); + g_test_add_func ("/strfuncs/ascii_strdown", test_ascii_strdown); + g_test_add_func ("/strfuncs/ascii_strdup", test_ascii_strup); + g_test_add_func ("/strfuncs/ascii_strtod", test_ascii_strtod); + g_test_add_func ("/strfuncs/bounds-check", test_bounds); + g_test_add_func ("/strfuncs/has-prefix", test_has_prefix); + g_test_add_func ("/strfuncs/has-suffix", test_has_suffix); + g_test_add_func ("/strfuncs/memdup", test_memdup); + g_test_add_func ("/strfuncs/memdup2", test_memdup2); + g_test_add_func ("/strfuncs/stpcpy", test_stpcpy); + g_test_add_func ("/strfuncs/str_match_string", test_str_match_string); + g_test_add_func ("/strfuncs/str_tokenize_and_fold", test_str_tokenize_and_fold); + g_test_add_func ("/strfuncs/strcanon", test_strcanon); + g_test_add_func ("/strfuncs/strchomp", test_strchomp); + g_test_add_func ("/strfuncs/strchug", test_strchug); + g_test_add_func ("/strfuncs/strcompress-strescape", test_strcompress_strescape); + g_test_add_func ("/strfuncs/strconcat", test_strconcat); + g_test_add_func ("/strfuncs/strdelimit", test_strdelimit); + g_test_add_func ("/strfuncs/strdup", test_strdup); + g_test_add_func ("/strfuncs/strdup-printf", test_strdup_printf); + g_test_add_func ("/strfuncs/strdupv", test_strdupv); + g_test_add_func ("/strfuncs/strerror", test_strerror); + g_test_add_func ("/strfuncs/strip-context", test_strip_context); + g_test_add_func ("/strfuncs/strjoin", test_strjoin); + g_test_add_func ("/strfuncs/strjoinv", test_strjoinv); + g_test_add_func ("/strfuncs/strlcat", test_strlcat); + g_test_add_func ("/strfuncs/strlcpy", test_strlcpy); + g_test_add_func ("/strfuncs/strncasecmp", test_strncasecmp); + g_test_add_func ("/strfuncs/strndup", test_strndup); + g_test_add_func ("/strfuncs/strnfill", test_strnfill); + g_test_add_func ("/strfuncs/strreverse", test_strreverse); + g_test_add_func ("/strfuncs/strsignal", test_strsignal); + g_test_add_func ("/strfuncs/strsplit", test_strsplit); + g_test_add_func ("/strfuncs/strsplit-set", test_strsplit_set); + g_test_add_func ("/strfuncs/strstr", test_strstr); + g_test_add_func ("/strfuncs/strtod", test_strtod); + g_test_add_func ("/strfuncs/strtoull-strtoll", test_strtoll); + g_test_add_func ("/strfuncs/strup", test_strup); + g_test_add_func ("/strfuncs/strv-contains", test_strv_contains); + g_test_add_func ("/strfuncs/strv-equal", test_strv_equal); + g_test_add_func ("/strfuncs/strv-length", test_strv_length); + g_test_add_func ("/strfuncs/test-is-to-digit", test_is_to_digit); + g_test_add_func ("/strfuncs/transliteration", test_transliteration); + + return g_test_run(); +} diff --git a/glib/tests/string.c b/glib/tests/string.c new file mode 100644 index 0000000..0229099 --- /dev/null +++ b/glib/tests/string.c @@ -0,0 +1,627 @@ +/* Unit tests for gstring + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include +#include +#include "glib.h" + + +static void +test_string_chunks (void) +{ + GStringChunk *string_chunk; + gchar *tmp_string, *tmp_string_2; + gint i; + + string_chunk = g_string_chunk_new (1024); + + for (i = 0; i < 100000; i ++) + { + tmp_string = g_string_chunk_insert (string_chunk, "hi pete"); + g_assert_cmpstr ("hi pete", ==, tmp_string); + } + + tmp_string_2 = g_string_chunk_insert_const (string_chunk, tmp_string); + g_assert (tmp_string_2 != tmp_string); + g_assert_cmpstr (tmp_string_2, ==, tmp_string); + + tmp_string = g_string_chunk_insert_const (string_chunk, tmp_string); + g_assert_cmpstr (tmp_string_2, ==, tmp_string); + + g_string_chunk_clear (string_chunk); + g_string_chunk_free (string_chunk); +} + +static void +test_string_chunk_insert (void) +{ + const gchar s0[] = "Testing GStringChunk"; + const gchar s1[] = "a\0b\0c\0d\0"; + const gchar s2[] = "Hello, world"; + GStringChunk *chunk; + gchar *str[3]; + + chunk = g_string_chunk_new (512); + + str[0] = g_string_chunk_insert (chunk, s0); + str[1] = g_string_chunk_insert_len (chunk, s1, 8); + str[2] = g_string_chunk_insert (chunk, s2); + + g_assert (memcmp (s0, str[0], sizeof s0) == 0); + g_assert (memcmp (s1, str[1], sizeof s1) == 0); + g_assert (memcmp (s2, str[2], sizeof s2) == 0); + + g_string_chunk_free (chunk); +} + +static void +test_string_new (void) +{ + GString *string1, *string2; + + string1 = g_string_new ("hi pete!"); + string2 = g_string_new (NULL); + + g_assert (string1 != NULL); + g_assert (string2 != NULL); + g_assert (strlen (string1->str) == string1->len); + g_assert (strlen (string2->str) == string2->len); + g_assert (string2->len == 0); + g_assert_cmpstr ("hi pete!", ==, string1->str); + g_assert_cmpstr ("", ==, string2->str); + + g_string_free (string1, TRUE); + g_string_free (string2, TRUE); + + string1 = g_string_new_len ("foo", -1); + string2 = g_string_new_len ("foobar", 3); + + g_assert_cmpstr (string1->str, ==, "foo"); + g_assert_cmpint (string1->len, ==, 3); + g_assert_cmpstr (string2->str, ==, "foo"); + g_assert_cmpint (string2->len, ==, 3); + + g_string_free (string1, TRUE); + g_string_free (string2, TRUE); +} + +G_GNUC_PRINTF(2, 3) +static void +my_string_printf (GString *string, + const gchar *format, + ...) +{ + va_list args; + + va_start (args, format); + g_string_vprintf (string, format, args); + va_end (args); +} + +static void +test_string_printf (void) +{ + GString *string; + + string = g_string_new (NULL); + +#ifndef G_OS_WIN32 + /* MSVC and mingw32 use the same run-time C library, which doesn't like + the %10000.10000f format... */ + g_string_printf (string, "%s|%0100d|%s|%0*d|%*.*f|%10000.10000f", + "this pete guy sure is a wuss, like he's the number ", + 1, + " wuss. everyone agrees.\n", + 10, 666, 15, 15, 666.666666666, 666.666666666); +#else + g_string_printf (string, "%s|%0100d|%s|%0*d|%*.*f|%100.100f", + "this pete guy sure is a wuss, like he's the number ", + 1, + " wuss. everyone agrees.\n", + 10, 666, 15, 15, 666.666666666, 666.666666666); +#endif + + g_string_free (string, TRUE); + + string = g_string_new (NULL); + g_string_printf (string, "bla %s %d", "foo", 99); + g_assert_cmpstr (string->str, ==, "bla foo 99"); + my_string_printf (string, "%d,%s,%d", 1, "two", 3); + g_assert_cmpstr (string->str, ==, "1,two,3"); + + g_string_free (string, TRUE); +} + +static void +test_string_assign (void) +{ + GString *string; + + string = g_string_new (NULL); + g_string_assign (string, "boring text"); + g_assert_cmpstr (string->str, ==, "boring text"); + g_string_free (string, TRUE); + + /* assign with string overlap */ + string = g_string_new ("textbeforetextafter"); + g_string_assign (string, string->str + 10); + g_assert_cmpstr (string->str, ==, "textafter"); + g_string_free (string, TRUE); + + string = g_string_new ("boring text"); + g_string_assign (string, string->str); + g_assert_cmpstr (string->str, ==, "boring text"); + g_string_free (string, TRUE); +} + +static void +test_string_append_c (void) +{ + GString *string; + gint i; + + string = g_string_new ("hi pete!"); + + for (i = 0; i < 10000; i++) + if (i % 2) + g_string_append_c (string, 'a'+(i%26)); + else + (g_string_append_c) (string, 'a'+(i%26)); + + g_assert((strlen("hi pete!") + 10000) == string->len); + g_assert((strlen("hi pete!") + 10000) == strlen(string->str)); + + g_string_free (string, TRUE); +} + +static void +test_string_append (void) +{ + GString *string; + + /* append */ + string = g_string_new ("firsthalf"); + g_string_append (string, "lasthalf"); + g_assert_cmpstr (string->str, ==, "firsthalflasthalf"); + g_string_free (string, TRUE); + + /* append_len */ + string = g_string_new ("firsthalf"); + g_string_append_len (string, "lasthalfjunkjunk", strlen ("lasthalf")); + g_assert_cmpstr (string->str, ==, "firsthalflasthalf"); + g_string_free (string, TRUE); +} + +static void string_append_vprintf_va (GString *string, + const gchar *format, + ...) G_GNUC_PRINTF (2, 3); + +/* Wrapper around g_string_append_vprintf() which takes varargs */ +static void +string_append_vprintf_va (GString *string, + const gchar *format, + ...) +{ + va_list args; + + va_start (args, format); + g_string_append_vprintf (string, format, args); + va_end (args); +} + +static void +test_string_append_vprintf (void) +{ + GString *string; + + /* append */ + string = g_string_new ("firsthalf"); + + string_append_vprintf_va (string, "some %s placeholders", "format"); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-extra-args" + string_append_vprintf_va (string, "%l", "invalid"); +#pragma GCC diagnostic pop + + g_assert_cmpstr (string->str, ==, "firsthalfsome format placeholders"); + + g_string_free (string, TRUE); +} + +static void +test_string_prepend_c (void) +{ + GString *string; + gint i; + + string = g_string_new ("hi pete!"); + + for (i = 0; i < 10000; i++) + g_string_prepend_c (string, 'a'+(i%26)); + + g_assert((strlen("hi pete!") + 10000) == string->len); + g_assert((strlen("hi pete!") + 10000) == strlen(string->str)); + + g_string_free (string, TRUE); +} + +static void +test_string_prepend (void) +{ + GString *string; + + /* prepend */ + string = g_string_new ("lasthalf"); + g_string_prepend (string, "firsthalf"); + g_assert_cmpstr (string->str, ==, "firsthalflasthalf"); + g_string_free (string, TRUE); + + /* prepend_len */ + string = g_string_new ("lasthalf"); + g_string_prepend_len (string, "firsthalfjunkjunk", strlen ("firsthalf")); + g_assert_cmpstr (string->str, ==, "firsthalflasthalf"); + g_string_free (string, TRUE); +} + +static void +test_string_insert (void) +{ + GString *string; + + /* insert */ + string = g_string_new ("firstlast"); + g_string_insert (string, 5, "middle"); + g_assert_cmpstr (string->str, ==, "firstmiddlelast"); + g_string_free (string, TRUE); + + /* insert with pos == end of the string */ + string = g_string_new ("firstmiddle"); + g_string_insert (string, strlen ("firstmiddle"), "last"); + g_assert_cmpstr (string->str, ==, "firstmiddlelast"); + g_string_free (string, TRUE); + + /* insert_len */ + string = g_string_new ("firstlast"); + g_string_insert_len (string, 5, "middlejunkjunk", strlen ("middle")); + g_assert_cmpstr (string->str, ==, "firstmiddlelast"); + g_string_free (string, TRUE); + + /* insert_len with magic -1 pos for append */ + string = g_string_new ("first"); + g_string_insert_len (string, -1, "lastjunkjunk", strlen ("last")); + g_assert_cmpstr (string->str, ==, "firstlast"); + g_string_free (string, TRUE); + + /* insert_len with magic -1 len for strlen-the-string */ + string = g_string_new ("first"); + g_string_insert_len (string, 5, "last", -1); + g_assert_cmpstr (string->str, ==, "firstlast"); + g_string_free (string, TRUE); + + /* insert_len with string overlap */ + string = g_string_new ("textbeforetextafter"); + g_string_insert_len (string, 10, string->str + 8, 5); + g_assert_cmpstr (string->str, ==, "textbeforeretextextafter"); + g_string_free (string, TRUE); +} + +static void +test_string_insert_unichar (void) +{ + GString *string; + + /* insert_unichar with insertion in middle */ + string = g_string_new ("firsthalf"); + g_string_insert_unichar (string, 5, 0x0041); + g_assert_cmpstr (string->str, ==, "first\x41half"); + g_string_free (string, TRUE); + + string = g_string_new ("firsthalf"); + g_string_insert_unichar (string, 5, 0x0298); + g_assert_cmpstr (string->str, ==, "first\xCA\x98half"); + g_string_free (string, TRUE); + + string = g_string_new ("firsthalf"); + g_string_insert_unichar (string, 5, 0xFFFD); + g_assert_cmpstr (string->str, ==, "first\xEF\xBF\xBDhalf"); + g_string_free (string, TRUE); + + string = g_string_new ("firsthalf"); + g_string_insert_unichar (string, 5, 0x1D100); + g_assert_cmpstr (string->str, ==, "first\xF0\x9D\x84\x80half"); + g_string_free (string, TRUE); + + /* insert_unichar with insertion at end */ + string = g_string_new ("start"); + g_string_insert_unichar (string, -1, 0x0041); + g_assert_cmpstr (string->str, ==, "start\x41"); + g_string_free (string, TRUE); + + string = g_string_new ("start"); + g_string_insert_unichar (string, -1, 0x0298); + g_assert_cmpstr (string->str, ==, "start\xCA\x98"); + g_string_free (string, TRUE); + + string = g_string_new ("start"); + g_string_insert_unichar (string, -1, 0xFFFD); + g_assert_cmpstr (string->str, ==, "start\xEF\xBF\xBD"); + g_string_free (string, TRUE); + + string = g_string_new ("start"); + g_string_insert_unichar (string, -1, 0x1D100); + g_assert_cmpstr (string->str, ==, "start\xF0\x9D\x84\x80"); + g_string_free (string, TRUE); +} + +static void +test_string_equal (void) +{ + GString *string1, *string2; + + string1 = g_string_new ("test"); + string2 = g_string_new ("te"); + g_assert (!g_string_equal(string1, string2)); + g_string_append (string2, "st"); + g_assert (g_string_equal(string1, string2)); + g_string_free (string1, TRUE); + g_string_free (string2, TRUE); +} + +static void +test_string_truncate (void) +{ + GString *string; + + string = g_string_new ("testing"); + + g_string_truncate (string, 1000); + g_assert (string->len == strlen("testing")); + g_assert_cmpstr (string->str, ==, "testing"); + + g_string_truncate (string, 4); + g_assert (string->len == 4); + g_assert_cmpstr (string->str, ==, "test"); + + g_string_truncate (string, 0); + g_assert (string->len == 0); + g_assert_cmpstr (string->str, ==, ""); + + g_string_free (string, TRUE); +} + +static void +test_string_overwrite (void) +{ + GString *string; + + /* overwriting functions */ + string = g_string_new ("testing"); + + g_string_overwrite (string, 4, " and expand"); + g_assert (15 == string->len); + g_assert ('\0' == string->str[15]); + g_assert (g_str_equal ("test and expand", string->str)); + + g_string_overwrite (string, 5, "NOT-"); + g_assert (15 == string->len); + g_assert ('\0' == string->str[15]); + g_assert (g_str_equal ("test NOT-expand", string->str)); + + g_string_overwrite_len (string, 9, "blablabla", 6); + g_assert (15 == string->len); + g_assert ('\0' == string->str[15]); + g_assert (g_str_equal ("test NOT-blabla", string->str)); + + g_string_overwrite_len (string, 4, "BLABL", 0); + g_assert (g_str_equal ("test NOT-blabla", string->str)); + g_string_overwrite_len (string, 4, "BLABL", -1); + g_assert (g_str_equal ("testBLABLblabla", string->str)); + + g_string_free (string, TRUE); +} + +static void +test_string_nul_handling (void) +{ + GString *string1, *string2; + + /* Check handling of embedded ASCII 0 (NUL) characters in GString. */ + string1 = g_string_new ("fiddle"); + string2 = g_string_new ("fiddle"); + g_assert (g_string_equal (string1, string2)); + g_string_append_c (string1, '\0'); + g_assert (!g_string_equal (string1, string2)); + g_string_append_c (string2, '\0'); + g_assert (g_string_equal (string1, string2)); + g_string_append_c (string1, 'x'); + g_string_append_c (string2, 'y'); + g_assert (!g_string_equal (string1, string2)); + g_assert (string1->len == 8); + g_string_append (string1, "yzzy"); + g_assert_cmpmem (string1->str, string1->len + 1, "fiddle\0xyzzy", 13); + g_string_insert (string1, 1, "QED"); + g_assert_cmpmem (string1->str, string1->len + 1, "fQEDiddle\0xyzzy", 16); + g_string_printf (string1, "fiddle%cxyzzy", '\0'); + g_assert_cmpmem (string1->str, string1->len + 1, "fiddle\0xyzzy", 13); + + g_string_free (string1, TRUE); + g_string_free (string2, TRUE); +} + +static void +test_string_up_down (void) +{ + GString *s; + + s = g_string_new ("Mixed Case String !?"); + g_string_ascii_down (s); + g_assert_cmpstr (s->str, ==, "mixed case string !?"); + + g_string_assign (s, "Mixed Case String !?"); + g_string_down (s); + g_assert_cmpstr (s->str, ==, "mixed case string !?"); + + g_string_assign (s, "Mixed Case String !?"); + g_string_ascii_up (s); + g_assert_cmpstr (s->str, ==, "MIXED CASE STRING !?"); + + g_string_assign (s, "Mixed Case String !?"); + g_string_up (s); + g_assert_cmpstr (s->str, ==, "MIXED CASE STRING !?"); + + g_string_free (s, TRUE); +} + +static void +test_string_set_size (void) +{ + GString *s; + + s = g_string_new ("foo"); + g_string_set_size (s, 30); + + g_assert_cmpstr (s->str, ==, "foo"); + g_assert_cmpint (s->len, ==, 30); + + g_string_free (s, TRUE); +} + +static void +test_string_to_bytes (void) +{ + GString *s; + GBytes *bytes; + gconstpointer byte_data; + gsize byte_len; + + s = g_string_new ("foo"); + g_string_append (s, "-bar"); + + bytes = g_string_free_to_bytes (s); + + byte_data = g_bytes_get_data (bytes, &byte_len); + + g_assert_cmpint (byte_len, ==, 7); + + g_assert_cmpmem (byte_data, byte_len, "foo-bar", 7); + + g_bytes_unref (bytes); +} + +static void +test_string_replace (void) +{ + static const struct + { + const char *string; + const char *original; + const char *replacement; + guint limit; + const char *expected; + guint expected_n; + } + tests[] = + { + { "foo bar foo baz foo bar foobarbaz", "bar", "baz", 0, + "foo baz foo baz foo baz foobazbaz", 3 }, + { "foo baz foo baz foo baz foobazbaz", "baz", "bar", 3, + "foo bar foo bar foo bar foobazbaz", 3 }, + { "foo bar foo bar foo bar foobazbaz", "foobar", "bar", 1, + "foo bar foo bar foo bar foobazbaz", 0 }, + { "aaaaaaaa", "a", "abcdefghijkl", 0, + "abcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijkl", + 8 }, + { "/usr/$LIB/libMangoHud.so", "$LIB", "lib32", 0, + "/usr/lib32/libMangoHud.so", 1 }, + { "food for foals", "o", "", 0, + "fd fr fals", 4 }, + { "aaa", "a", "aaa", 0, + "aaaaaaaaa", 3 }, + { "aaa", "a", "", 0, + "", 3 }, + { "aaa", "aa", "bb", 0, + "bba", 1 }, + { "foo", "", "bar", 0, + "barfbarobarobar", 4 }, + { "", "", "x", 0, + "x", 1 }, + { "", "", "", 0, + "", 1 }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + GString *s; + guint n; + + s = g_string_new (tests[i].string); + g_test_message ("%" G_GSIZE_FORMAT ": Replacing \"%s\" with \"%s\" (limit %u) in \"%s\"", + i, tests[i].original, tests[i].replacement, + tests[i].limit, tests[i].string); + n = g_string_replace (s, tests[i].original, tests[i].replacement, + tests[i].limit); + g_test_message ("-> %u replacements, \"%s\"", + n, s->str); + g_assert_cmpstr (tests[i].expected, ==, s->str); + g_assert_cmpuint (strlen (tests[i].expected), ==, s->len); + g_assert_cmpuint (strlen (tests[i].expected) + 1, <=, s->allocated_len); + g_assert_cmpuint (tests[i].expected_n, ==, n); + g_string_free (s, TRUE); + } +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/string/test-string-chunks", test_string_chunks); + g_test_add_func ("/string/test-string-chunk-insert", test_string_chunk_insert); + g_test_add_func ("/string/test-string-new", test_string_new); + g_test_add_func ("/string/test-string-printf", test_string_printf); + g_test_add_func ("/string/test-string-assign", test_string_assign); + g_test_add_func ("/string/test-string-append-c", test_string_append_c); + g_test_add_func ("/string/test-string-append", test_string_append); + g_test_add_func ("/string/test-string-append-vprintf", test_string_append_vprintf); + g_test_add_func ("/string/test-string-prepend-c", test_string_prepend_c); + g_test_add_func ("/string/test-string-prepend", test_string_prepend); + g_test_add_func ("/string/test-string-insert", test_string_insert); + g_test_add_func ("/string/test-string-insert-unichar", test_string_insert_unichar); + g_test_add_func ("/string/test-string-equal", test_string_equal); + g_test_add_func ("/string/test-string-truncate", test_string_truncate); + g_test_add_func ("/string/test-string-overwrite", test_string_overwrite); + g_test_add_func ("/string/test-string-nul-handling", test_string_nul_handling); + g_test_add_func ("/string/test-string-up-down", test_string_up_down); + g_test_add_func ("/string/test-string-set-size", test_string_set_size); + g_test_add_func ("/string/test-string-to-bytes", test_string_to_bytes); + g_test_add_func ("/string/test-string-replace", test_string_replace); + + return g_test_run(); +} diff --git a/glib/tests/strvbuilder.c b/glib/tests/strvbuilder.c new file mode 100644 index 0000000..904af0e --- /dev/null +++ b/glib/tests/strvbuilder.c @@ -0,0 +1,117 @@ +/* + * Copyright © 2020 Canonical Ltd. + * Copyright © 2021 Alexandros Theodotou + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "glib.h" + +static void +test_strvbuilder_empty (void) +{ + GStrvBuilder *builder; + GStrv result; + + builder = g_strv_builder_new (); + result = g_strv_builder_end (builder); + g_assert_nonnull (result); + g_assert_cmpint (g_strv_length (result), ==, 0); + + g_strfreev (result); + g_strv_builder_unref (builder); +} + +static void +test_strvbuilder_add (void) +{ + GStrvBuilder *builder; + GStrv result; + const gchar *expected[] = { "one", "two", "three", NULL }; + + builder = g_strv_builder_new (); + g_strv_builder_add (builder, "one"); + g_strv_builder_add (builder, "two"); + g_strv_builder_add (builder, "three"); + result = g_strv_builder_end (builder); + g_assert_nonnull (result); + g_assert_true (g_strv_equal ((const gchar *const *) result, expected)); + + g_strfreev (result); + g_strv_builder_unref (builder); +} + +static void +test_strvbuilder_addv (void) +{ + GStrvBuilder *builder; + GStrv result; + const gchar *expected[] = { "one", "two", "three", NULL }; + + builder = g_strv_builder_new (); + g_strv_builder_addv (builder, expected); + result = g_strv_builder_end (builder); + g_assert_nonnull (result); + g_assert_cmpstrv ((const gchar *const *) result, expected); + + g_strfreev (result); + g_strv_builder_unref (builder); +} + +static void +test_strvbuilder_add_many (void) +{ + GStrvBuilder *builder; + GStrv result; + const gchar *expected[] = { "one", "two", "three", NULL }; + + builder = g_strv_builder_new (); + g_strv_builder_add_many (builder, "one", "two", "three", NULL); + result = g_strv_builder_end (builder); + g_assert_nonnull (result); + g_assert_cmpstrv ((const gchar *const *) result, expected); + + g_strfreev (result); + g_strv_builder_unref (builder); +} + +static void +test_strvbuilder_ref (void) +{ + GStrvBuilder *builder; + + builder = g_strv_builder_new (); + g_strv_builder_ref (builder); + g_strv_builder_unref (builder); + g_strv_builder_unref (builder); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/strvbuilder/empty", test_strvbuilder_empty); + g_test_add_func ("/strvbuilder/add", test_strvbuilder_add); + g_test_add_func ("/strvbuilder/addv", test_strvbuilder_addv); + g_test_add_func ("/strvbuilder/add_many", test_strvbuilder_add_many); + g_test_add_func ("/strvbuilder/ref", test_strvbuilder_ref); + + return g_test_run (); +} diff --git a/glib/tests/test-printf.c b/glib/tests/test-printf.c new file mode 100644 index 0000000..6eadf1e --- /dev/null +++ b/glib/tests/test-printf.c @@ -0,0 +1,987 @@ +/* Unit tests for gprintf + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include +#include +#include "glib.h" +#include "gstdio.h" +#ifdef G_OS_WIN32 +#include +#include +#endif + +static void +test_retval_and_trunc (void) +{ + gchar buf[128]; + gint res; + + res = g_snprintf (buf, 0, "abc"); + g_assert_cmpint (res, ==, 3); + + res = g_snprintf (NULL, 0, "abc"); + g_assert_cmpint (res, ==, 3); + + res = g_snprintf (buf, 5, "abc"); + g_assert_cmpint (res, ==, 3); + + res = g_snprintf (buf, 1, "abc"); + g_assert_cmpint (res, ==, 3); + g_assert (buf[0] == '\0'); + g_assert_cmpstr (buf, ==, ""); + + res = g_snprintf (buf, 2, "abc"); + g_assert_cmpint (res, ==, 3); + g_assert (buf[1] == '\0'); + g_assert_cmpstr (buf, ==, "a"); + + res = g_snprintf (buf, 3, "abc"); + g_assert_cmpint (res, ==, 3); + g_assert (buf[2] == '\0'); + g_assert_cmpstr (buf, ==, "ab"); + + res = g_snprintf (buf, 4, "abc"); + g_assert_cmpint (res, ==, 3); + g_assert (buf[3] == '\0'); + g_assert_cmpstr (buf, ==, "abc"); + + res = g_snprintf (buf, 5, "abc"); + g_assert_cmpint (res, ==, 3); + g_assert (buf[3] == '\0'); + g_assert_cmpstr (buf, ==, "abc"); +} + +static void +test_d (void) +{ + gchar buf[128]; + gint res; + + /* %d basic formatting */ + + res = g_snprintf (buf, 128, "%d", 5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%d", 0); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "0"); + + res = g_snprintf (buf, 128, "%.0d", 0); + g_assert_cmpint (res, ==, 0); + g_assert_cmpstr (buf, ==, ""); + + res = g_snprintf (buf, 128, "%.0d", 1); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "1"); + + res = g_snprintf (buf, 128, "%.d", 2); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "2"); + + res = g_snprintf (buf, 128, "%d", -1); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "-1"); + + res = g_snprintf (buf, 128, "%.3d", 5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "005"); + + res = g_snprintf (buf, 128, "%.3d", -5); + g_assert_cmpint (res, ==, 4); + g_assert_cmpstr (buf, ==, "-005"); + + res = g_snprintf (buf, 128, "%5.3d", 5); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " 005"); + + res = g_snprintf (buf, 128, "%-5.3d", -5); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, "-005 "); + + /* %d, length modifiers */ + + res = g_snprintf (buf, 128, "%" G_GINT16_FORMAT, (gint16)-5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "-5"); + + res = g_snprintf (buf, 128, "%" G_GUINT16_FORMAT, (guint16)5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%" G_GINT32_FORMAT, (gint32)-5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "-5"); + + res = g_snprintf (buf, 128, "%" G_GUINT32_FORMAT, (guint32)5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%" G_GINT64_FORMAT, (gint64)-5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "-5"); + + res = g_snprintf (buf, 128, "%" G_GUINT64_FORMAT, (guint64)5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%" G_GSSIZE_FORMAT, (gssize)-5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "-5"); + + res = g_snprintf (buf, 128, "%" G_GSIZE_FORMAT, (gsize)5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + /* %d, flags */ + + res = g_snprintf (buf, 128, "%-d", 5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%-+d", 5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "+5"); + + res = g_snprintf (buf, 128, "%+-d", 5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "+5"); + + res = g_snprintf (buf, 128, "%+d", -5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "-5"); + + res = g_snprintf (buf, 128, "% d", 5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, " 5"); + + res = g_snprintf (buf, 128, "% .0d", 0); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, " "); + + res = g_snprintf (buf, 128, "%03d", 5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "005"); + + res = g_snprintf (buf, 128, "%03d", -5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "-05"); +} + +/* gcc emits warnings for the following formats, since the C spec + * says some of the flags must be ignored. (The " " in "% +d" and + * the "0" in "%-03d".) But we need to test that our printf gets + * those rules right. So we fool gcc into not warning. + * + * These have to be in a separate function in order to use #pragma. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void +test_d_invalid (void) +{ + const gchar *fmt; + gchar buf[128]; + gint res; + + fmt = "% +d"; + res = g_snprintf (buf, 128, fmt, 5); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "+5"); + + fmt = "%-03d"; + res = g_snprintf (buf, 128, fmt, -5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "-5 "); +} +#pragma GCC diagnostic pop + +static void +test_o (void) +{ + gchar buf[128]; + gint res; + + /* %o basic formatting */ + + res = g_snprintf (buf, 128, "%o", 5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%o", 8); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "10"); + + res = g_snprintf (buf, 128, "%o", 0); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "0"); + + res = g_snprintf (buf, 128, "%.0o", 0); + g_assert_cmpint (res, ==, 0); + g_assert_cmpstr (buf, ==, ""); + + res = g_snprintf (buf, 128, "%.0o", 1); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "1"); + + res = g_snprintf (buf, 128, "%.3o", 5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "005"); + + res = g_snprintf (buf, 128, "%.3o", 8); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "010"); + + res = g_snprintf (buf, 128, "%5.3o", 5); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " 005"); +} + +static void +test_u (void) +{ + gchar buf[128]; + gint res; + + /* %u, basic formatting */ + + res = g_snprintf (buf, 128, "%u", 5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%u", 0); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "0"); + + res = g_snprintf (buf, 128, "%.0u", 0); + g_assert_cmpint (res, ==, 0); + g_assert_cmpstr (buf, ==, ""); + + res = g_snprintf (buf, 128, "%.0u", 1); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "1"); + + res = g_snprintf (buf, 128, "%.3u", 5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "005"); + + res = g_snprintf (buf, 128, "%5.3u", 5); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " 005"); +} + +static void +test_x (void) +{ + gchar buf[128]; + gint res; + + /* %x, basic formatting */ + + res = g_snprintf (buf, 128, "%x", 5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%x", 31); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "1f"); + + res = g_snprintf (buf, 128, "%x", 0); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "0"); + + res = g_snprintf (buf, 128, "%.0x", 0); + g_assert_cmpint (res, ==, 0); + g_assert_cmpstr (buf, ==, ""); + + res = g_snprintf (buf, 128, "%.0x", 1); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "1"); + + res = g_snprintf (buf, 128, "%.3x", 5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "005"); + + res = g_snprintf (buf, 128, "%.3x", 31); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "01f"); + + res = g_snprintf (buf, 128, "%5.3x", 5); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " 005"); + + /* %x, flags */ + + res = g_snprintf (buf, 128, "%-x", 5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%03x", 5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "005"); + + res = g_snprintf (buf, 128, "%#x", 31); + g_assert_cmpint (res, ==, 4); + g_assert_cmpstr (buf, ==, "0x1f"); + + res = g_snprintf (buf, 128, "%#x", 0); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "0"); +} + +static void +test_X (void) +{ + gchar buf[128]; + gint res; + + /* %X, basic formatting */ + + res = g_snprintf (buf, 128, "%X", 5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%X", 31); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "1F"); + + res = g_snprintf (buf, 128, "%X", 0); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "0"); + + res = g_snprintf (buf, 128, "%.0X", 0); + g_assert_cmpint (res, ==, 0); + g_assert_cmpstr (buf, ==, ""); + + res = g_snprintf (buf, 128, "%.0X", 1); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "1"); + + res = g_snprintf (buf, 128, "%.3X", 5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "005"); + + res = g_snprintf (buf, 128, "%.3X", 31); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "01F"); + + res = g_snprintf (buf, 128, "%5.3X", 5); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " 005"); + + /* %X, flags */ + + res = g_snprintf (buf, 128, "%-X", 5); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "5"); + + res = g_snprintf (buf, 128, "%03X", 5); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "005"); + + res = g_snprintf (buf, 128, "%#X", 31); + g_assert_cmpint (res, ==, 4); + g_assert_cmpstr (buf, ==, "0X1F"); + + res = g_snprintf (buf, 128, "%#X", 0); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "0"); +} + +static void +test_f (void) +{ + gchar buf[128]; + gint res; + + /* %f, basic formatting */ + + res = g_snprintf (buf, 128, "%f", G_PI); + g_assert_cmpint (res, ==, 8); + g_assert (0 == strncmp (buf, "3.14159", 7)); + + res = g_snprintf (buf, 128, "%.8f", G_PI); + g_assert_cmpint (res, ==, 10); + g_assert (0 == strncmp (buf, "3.1415926", 9)); + + res = g_snprintf (buf, 128, "%.0f", G_PI); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "3"); + + res = g_snprintf (buf, 128, "%1.f", G_PI); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "3"); + + res = g_snprintf (buf, 128, "%3.f", G_PI); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, " 3"); + + /* %f, flags */ + + res = g_snprintf (buf, 128, "%+f", G_PI); + g_assert_cmpint (res, ==, 9); + g_assert (0 == strncmp (buf, "+3.14159", 8)); + + res = g_snprintf (buf, 128, "% f", G_PI); + g_assert_cmpint (res, ==, 9); + g_assert (0 == strncmp (buf, " 3.14159", 8)); + + res = g_snprintf (buf, 128, "%#.0f", G_PI); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "3."); + + res = g_snprintf (buf, 128, "%05.2f", G_PI); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, "03.14"); +} + +static gboolean +same_value (const gchar *actual, + const gchar *expected) +{ + gdouble actual_value, expected_value; + + actual_value = g_ascii_strtod (actual, NULL); + expected_value = g_ascii_strtod (expected, NULL); + + return actual_value == expected_value; +} + +static void +test_e (void) +{ + gchar buf[128]; + gint res; + + /* %e, basic formatting */ + /* for %e we can't expect to reproduce exact strings and lengths, since SUS + * only guarantees that the exponent shall always contain at least two + * digits. On Windows, it seems to be at least three digits long. + * Therefore, we compare the results of parsing the expected result and the + * actual result. + */ + + res = g_snprintf (buf, 128, "%e", G_PI); + g_assert_cmpint (res, >=, 12); + g_assert (same_value (buf, "3.141593e+00")); + + res = g_snprintf (buf, 128, "%.8e", G_PI); + g_assert_cmpint (res, >=, 14); + g_assert (same_value (buf, "3.14159265e+00")); + + res = g_snprintf (buf, 128, "%.0e", G_PI); + g_assert_cmpint (res, >=, 5); + g_assert (same_value (buf, "3e+00")); + + res = g_snprintf (buf, 128, "%.1e", 0.0); + g_assert_cmpint (res, >=, 7); + g_assert (same_value (buf, "0.0e+00")); + + res = g_snprintf (buf, 128, "%.1e", 0.00001); + g_assert_cmpint (res, >=, 7); + g_assert (same_value (buf, "1.0e-05")); + + res = g_snprintf (buf, 128, "%.1e", 10000.0); + g_assert_cmpint (res, >=, 7); + g_assert (same_value (buf, "1.0e+04")); + + /* %e, flags */ + + res = g_snprintf (buf, 128, "%+e", G_PI); + g_assert_cmpint (res, >=, 13); + g_assert (same_value (buf, "+3.141593e+00")); + + res = g_snprintf (buf, 128, "% e", G_PI); + g_assert_cmpint (res, >=, 13); + g_assert (same_value (buf, " 3.141593e+00")); + + res = g_snprintf (buf, 128, "%#.0e", G_PI); + g_assert_cmpint (res, >=, 6); + g_assert (same_value (buf, "3.e+00")); + + res = g_snprintf (buf, 128, "%09.2e", G_PI); + g_assert_cmpint (res, >=, 9); + g_assert (same_value (buf, "03.14e+00")); +} + +static void +test_c (void) +{ + gchar buf[128]; + gint res; + + res = g_snprintf (buf, 128, "%c", 'a'); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "a"); +} + +static void +test_s (void) +{ + gchar buf[128]; + gint res; + + res = g_snprintf (buf, 128, "%.2s", "abc"); + g_assert_cmpint (res, ==, 2); + g_assert_cmpstr (buf, ==, "ab"); + + res = g_snprintf (buf, 128, "%.6s", "abc"); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "abc"); + + res = g_snprintf (buf, 128, "%5s", "abc"); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " abc"); + + res = g_snprintf (buf, 128, "%-5s", "abc"); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, "abc "); + + res = g_snprintf (buf, 128, "%5.2s", "abc"); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " ab"); + + res = g_snprintf (buf, 128, "%*s", 5, "abc"); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " abc"); + + res = g_snprintf (buf, 128, "%*s", -5, "abc"); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, "abc "); + + res = g_snprintf (buf, 128, "%*.*s", 5, 2, "abc"); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " ab"); +} + +static void +test_n (void) +{ + gchar buf[128]; + gint res; + gint i; + glong l; + + res = g_snprintf (buf, 128, "abc%n", &i); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "abc"); + g_assert_cmpint (i, ==, 3); + + res = g_snprintf (buf, 128, "abc%ln", &l); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "abc"); + g_assert_cmpint (l, ==, 3); +} + +static void +test_percent (void) +{ + gchar buf[128]; + gint res; + + res = g_snprintf (buf, 128, "%%"); + g_assert_cmpint (res, ==, 1); + g_assert_cmpstr (buf, ==, "%"); +} + +static void +test_positional_params (void) +{ + gchar buf[128]; + gint res; + + res = g_snprintf (buf, 128, "%2$c %1$c", 'b', 'a'); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "a b"); + + res = g_snprintf (buf, 128, "%1$*2$.*3$s", "abc", 5, 2); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " ab"); + + res = g_snprintf (buf, 128, "%1$s%1$s", "abc"); + g_assert_cmpint (res, ==, 6); + g_assert_cmpstr (buf, ==, "abcabc"); +} + +static void +test_positional_params2 (void) +{ + if (g_test_subprocess ()) + { + gint res; + + res = g_printf ("%2$c %1$c\n", 'b', 'a'); + g_assert_cmpint (res, ==, 4); + + res = g_printf ("%1$*2$.*3$s\n", "abc", 5, 2); + g_assert_cmpint (res, ==, 6); + + res = g_printf ("%1$s%1$s\n", "abc"); + g_assert_cmpint (res, ==, 7); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("a b\n ab\nabcabc\n"); +} + +static void +test_positional_params3 (void) +{ + gchar buf[128]; + gint res; + + res = g_sprintf (buf, "%2$c %1$c", 'b', 'a'); + g_assert_cmpint (res, ==, 3); + g_assert_cmpstr (buf, ==, "a b"); + + res = g_sprintf (buf, "%1$*2$.*3$s", "abc", 5, 2); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, " ab"); + + res = g_sprintf (buf, "%1$s%1$s", "abc"); + g_assert_cmpint (res, ==, 6); + g_assert_cmpstr (buf, ==, "abcabc"); +} + +static void +test_percent2 (void) +{ + if (g_test_subprocess ()) + { + gint res; + + res = g_printf ("%%"); + g_assert_cmpint (res, ==, 1); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*%*"); +} + +static void +test_64bit (void) +{ + gchar buf[128]; + gint res; + + res = g_snprintf (buf, 128, "%" G_GINT64_FORMAT, (gint64)123456); + g_assert_cmpint (res, ==, 6); + g_assert_cmpstr (buf, ==, "123456"); + + res = g_snprintf (buf, 128, "%" G_GINT64_FORMAT, (gint64)-123456); + g_assert_cmpint (res, ==, 7); + g_assert_cmpstr (buf, ==, "-123456"); + + res = g_snprintf (buf, 128, "%" G_GUINT64_FORMAT, (guint64)123456); + g_assert_cmpint (res, ==, 6); + g_assert_cmpstr (buf, ==, "123456"); + + res = g_snprintf (buf, 128, "%" G_GINT64_MODIFIER "o", (gint64)123456); + g_assert_cmpint (res, ==, 6); + g_assert_cmpstr (buf, ==, "361100"); + + res = g_snprintf (buf, 128, "%#" G_GINT64_MODIFIER "o", (gint64)123456); + g_assert_cmpint (res, ==, 7); + g_assert_cmpstr (buf, ==, "0361100"); + + res = g_snprintf (buf, 128, "%" G_GINT64_MODIFIER "x", (gint64)123456); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, "1e240"); + + res = g_snprintf (buf, 128, "%#" G_GINT64_MODIFIER "x", (gint64)123456); + g_assert_cmpint (res, ==, 7); + g_assert_cmpstr (buf, ==, "0x1e240"); + + res = g_snprintf (buf, 128, "%" G_GINT64_MODIFIER "X", (gint64)123456); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, "1E240"); + +#ifdef G_OS_WIN32 + /* On Win32, test that the "ll" modifier also works, for backward + * compatibility. One really should use the G_GINT64_MODIFIER (which + * on Win32 is the "I64" that the (msvcrt) C library's printf uses), + * but "ll" used to work with the "trio" g_printf implementation in + * GLib 2.2, so it's best if it continues to work. + */ + + /* However, gcc doesn't know about this, so we need to disable printf + * format warnings... + */ +#if G_GNUC_CHECK_VERSION(4, 6) +_Pragma ("GCC diagnostic push") +_Pragma ("GCC diagnostic ignored \"-Wformat\"") +_Pragma ("GCC diagnostic ignored \"-Wformat-extra-args\"") +#endif + + res = g_snprintf (buf, 128, "%" "lli", (gint64)123456); + g_assert_cmpint (res, ==, 6); + g_assert_cmpstr (buf, ==, "123456"); + + res = g_snprintf (buf, 128, "%" "lli", (gint64)-123456); + g_assert_cmpint (res, ==, 7); + g_assert_cmpstr (buf, ==, "-123456"); + + res = g_snprintf (buf, 128, "%" "llu", (guint64)123456); + g_assert_cmpint (res, ==, 6); + g_assert_cmpstr (buf, ==, "123456"); + + res = g_snprintf (buf, 128, "%" "ll" "o", (gint64)123456); + g_assert_cmpint (res, ==, 6); + g_assert_cmpstr (buf, ==, "361100"); + + res = g_snprintf (buf, 128, "%#" "ll" "o", (gint64)123456); + g_assert_cmpint (res, ==, 7); + g_assert_cmpstr (buf, ==, "0361100"); + + res = g_snprintf (buf, 128, "%" "ll" "x", (gint64)123456); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, "1e240"); + + res = g_snprintf (buf, 128, "%#" "ll" "x", (gint64)123456); + g_assert_cmpint (res, ==, 7); + g_assert_cmpstr (buf, ==, "0x1e240"); + + res = g_snprintf (buf, 128, "%" "ll" "X", (gint64)123456); + g_assert_cmpint (res, ==, 5); + g_assert_cmpstr (buf, ==, "1E240"); + +#if G_GNUC_CHECK_VERSION(4, 6) +_Pragma ("GCC diagnostic pop") +#endif + +#endif +} + +static void +test_64bit2_base (void) +{ + gint res; + + res = g_printf ("%" G_GINT64_FORMAT "\n", (gint64)123456); + g_assert_cmpint (res, ==, 7); + + res = g_printf ("%" G_GINT64_FORMAT "\n", (gint64)-123456); + g_assert_cmpint (res, ==, 8); + + res = g_printf ("%" G_GUINT64_FORMAT "\n", (guint64)123456); + g_assert_cmpint (res, ==, 7); + + res = g_printf ("%" G_GINT64_MODIFIER "o\n", (gint64)123456); + g_assert_cmpint (res, ==, 7); + + res = g_printf ("%#" G_GINT64_MODIFIER "o\n", (gint64)123456); + g_assert_cmpint (res, ==, 8); + + res = g_printf ("%" G_GINT64_MODIFIER "x\n", (gint64)123456); + g_assert_cmpint (res, ==, 6); + + res = g_printf ("%#" G_GINT64_MODIFIER "x\n", (gint64)123456); + g_assert_cmpint (res, ==, 8); + + res = g_printf ("%" G_GINT64_MODIFIER "X\n", (gint64)123456); + g_assert_cmpint (res, ==, 6); +} + +#ifdef G_OS_WIN32 +static void +test_64bit2_win32 (void) +{ + gint res; + + /* On Win32, test that the "ll" modifier also works, for backward + * compatibility. One really should use the G_GINT64_MODIFIER (which + * on Win32 is the "I64" that the (msvcrt) C library's printf uses), + * but "ll" used to work with the "trio" g_printf implementation in + * GLib 2.2, so it's best if it continues to work. + */ + + /* However, gcc doesn't know about this, so we need to disable printf + * format warnings... + */ +#if G_GNUC_CHECK_VERSION(4, 6) +_Pragma ("GCC diagnostic push") +_Pragma ("GCC diagnostic ignored \"-Wformat\"") +_Pragma ("GCC diagnostic ignored \"-Wformat-extra-args\"") +#endif + + res = g_printf ("%" "lli\n", (gint64)123456); + g_assert_cmpint (res, ==, 7); + + res = g_printf ("%" "lli\n", (gint64)-123456); + g_assert_cmpint (res, ==, 8); + + res = g_printf ("%" "llu\n", (guint64)123456); + g_assert_cmpint (res, ==, 7); + + res = g_printf ("%" "ll" "o\n", (gint64)123456); + g_assert_cmpint (res, ==, 7); + + res = g_printf ("%#" "ll" "o\n", (gint64)123456); + g_assert_cmpint (res, ==, 8); + + res = g_printf ("%" "ll" "x\n", (gint64)123456); + g_assert_cmpint (res, ==, 6); + + res = g_printf ("%#" "ll" "x\n", (gint64)123456); + g_assert_cmpint (res, ==, 8); + + res = g_printf ("%" "ll" "X\n", (gint64)123456); + g_assert_cmpint (res, ==, 6); + +#if G_GNUC_CHECK_VERSION(4, 6) +_Pragma ("GCC diagnostic pop") +#endif +} +#endif + +static void +test_64bit2 (void) +{ + g_test_trap_subprocess ("/printf/test-64bit/subprocess/base", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("123456\n-123456\n123456\n" + "361100\n0361100\n1e240\n" + "0x1e240\n1E240\n"); +#ifdef G_OS_WIN32 + g_test_trap_subprocess ("/printf/test-64bit/subprocess/win32", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("123456\n-123456\n123456\n" + "361100\n0361100\n1e240\n" + "0x1e240\n1E240\n"); +#endif +} + +G_GNUC_PRINTF(1, 2) +static gsize +upper_bound (const gchar *format, ...) +{ + va_list args; + gsize res; + + va_start (args, format); + res = g_printf_string_upper_bound (format, args); + va_end (args); + + return res; +} + +static void +test_upper_bound (void) +{ + gsize res; + + res = upper_bound ("bla %s %d: %g\n", "bla", 123, 0.123); + g_assert_cmpint (res, ==, 20); +} + +#if !defined(__APPLE__) && !defined(__FreeBSD__) +static gint test_vasprintf_va (gchar **string, + const gchar *format, + ...) G_GNUC_PRINTF (2, 3); + +/* Wrapper around g_vasprintf() which takes varargs */ +static gint +test_vasprintf_va (gchar **string, + const gchar *format, + ...) +{ + va_list args; + gint len; + + va_start (args, format); + len = g_vasprintf (string, format, args); + va_end (args); + + return len; +} +#endif /* !defined(__APPLE__) && !defined(__FreeBSD__) */ + +static void +test_vasprintf_invalid_format_placeholder (void) +{ +#if !defined(__APPLE__) && !defined(__FreeBSD__) + gint len = 0; + gchar *buf = "some non-null string"; +#endif + + g_test_summary ("Test error handling for invalid format placeholder in g_vasprintf()"); + +#if !defined(__APPLE__) && !defined(__FreeBSD__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-extra-args" + len = test_vasprintf_va (&buf, "%l", "nope"); +#pragma GCC diagnostic pop + + g_assert_cmpint (len, ==, -1); + g_assert_null (buf); +#else + g_test_skip ("vasprintf() placeholder checks on BSDs are less strict"); +#endif +} + +int +main (int argc, + char *argv[]) +{ +#ifdef G_OS_WIN32 + /* Ensure binary mode for stdout, this way + * tests produce \n line endings on Windows instead of the + * default \r\n. + */ + _setmode (fileno (stdout), _O_BINARY); +#endif + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/snprintf/retval-and-trunc", test_retval_and_trunc); + g_test_add_func ("/snprintf/%d", test_d); + g_test_add_func ("/snprintf/%d-invalid", test_d_invalid); + g_test_add_func ("/snprintf/%o", test_o); + g_test_add_func ("/snprintf/%u", test_u); + g_test_add_func ("/snprintf/%x", test_x); + g_test_add_func ("/snprintf/%X", test_X); + g_test_add_func ("/snprintf/%f", test_f); + g_test_add_func ("/snprintf/%e", test_e); + g_test_add_func ("/snprintf/%c", test_c); + g_test_add_func ("/snprintf/%s", test_s); + g_test_add_func ("/snprintf/%n", test_n); + g_test_add_func ("/snprintf/test-percent", test_percent); + g_test_add_func ("/snprintf/test-positional-params", test_positional_params); + g_test_add_func ("/snprintf/test-64bit", test_64bit); + + g_test_add_func ("/printf/test-percent", test_percent2); + g_test_add_func ("/printf/test-positional-params", test_positional_params2); + g_test_add_func ("/printf/test-64bit", test_64bit2); + g_test_add_func ("/printf/test-64bit/subprocess/base", test_64bit2_base); +#ifdef G_OS_WIN32 + g_test_add_func ("/printf/test-64bit/subprocess/win32", test_64bit2_win32); +#endif + + g_test_add_func ("/sprintf/test-positional-params", test_positional_params3); + g_test_add_func ("/sprintf/upper-bound", test_upper_bound); + + g_test_add_func ("/vasprintf/invalid-format-placeholder", test_vasprintf_invalid_format_placeholder); + + return g_test_run(); +} diff --git a/glib/tests/test-spawn-echo.c b/glib/tests/test-spawn-echo.c new file mode 100644 index 0000000..cb387ba --- /dev/null +++ b/glib/tests/test-spawn-echo.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include "glib.h" + +int +main (int argc, + char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) + { + g_print ("%s", argv[i]); + } + + return 0; +} diff --git a/glib/tests/test-spawn-sleep.c b/glib/tests/test-spawn-sleep.c new file mode 100644 index 0000000..34dfd5b --- /dev/null +++ b/glib/tests/test-spawn-sleep.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#include "config.h" + +#include +#include "glib.h" + +int +main (int argc, + char *argv[]) +{ + g_usleep (atoi (argv[1]) * G_USEC_PER_SEC); + return 0; +} diff --git a/glib/tests/testing-helper.c b/glib/tests/testing-helper.c new file mode 100644 index 0000000..7731538 --- /dev/null +++ b/glib/tests/testing-helper.c @@ -0,0 +1,192 @@ +/* + * Copyright 2018 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + */ + +#include +#include +#ifdef G_OS_WIN32 +#include +#include +#include +#endif + +static void +test_pass (void) +{ +} + +static void +test_skip (void) +{ + g_test_skip ("not enough tea"); +} + +static void +test_skip_printf (void) +{ + const char *beverage = "coffee"; + + g_test_skip_printf ("not enough %s", beverage); +} + +static void +test_fail (void) +{ + g_test_fail (); +} + +static void +test_fail_printf (void) +{ + g_test_fail_printf ("this test intentionally left failing"); +} + +static void +test_incomplete (void) +{ + g_test_incomplete ("mind reading not implemented yet"); +} + +static void +test_incomplete_printf (void) +{ + const char *operation = "telekinesis"; + + g_test_incomplete_printf ("%s not implemented yet", operation); +} + +static void +test_summary (void) +{ + g_test_summary ("Tests that g_test_summary() works with TAP, by outputting a " + "known summary message in testing-helper, and checking for " + "it in the TAP output later."); +} + +int +main (int argc, + char *argv[]) +{ + char *argv1; + + setlocale (LC_ALL, ""); + +#ifdef G_OS_WIN32 + /* Windows opens std streams in text mode, with \r\n EOLs. + * Sometimes it's easier to force a switch to binary mode than + * to account for extra \r in testcases. + */ + setmode (fileno (stdout), O_BINARY); +#endif + + g_return_val_if_fail (argc > 1, 1); + argv1 = argv[1]; + + if (argc > 2) + memmove (&argv[1], &argv[2], (argc - 2) * sizeof (char *)); + + argc -= 1; + argv[argc] = NULL; + + if (g_strcmp0 (argv1, "init-null-argv0") == 0) + { + int test_argc = 0; + char *test_argva[1] = { NULL }; + char **test_argv = test_argva; + + /* Test that `g_test_init()` can handle being called with an empty argv + * and argc == 0. While this isn’t recommended, it is possible for another + * process to use execve() to call a gtest process this way, so we’d + * better handle it gracefully. + * + * This test can’t be run after `g_test_init()` has been called normally, + * as it isn’t allowed to be called more than once in a process. */ + g_test_init (&test_argc, &test_argv, NULL); + + return 0; + } + + g_test_init (&argc, &argv, NULL); + g_test_set_nonfatal_assertions (); + + if (g_strcmp0 (argv1, "pass") == 0) + { + g_test_add_func ("/pass", test_pass); + } + else if (g_strcmp0 (argv1, "skip") == 0) + { + g_test_add_func ("/skip", test_skip); + } + else if (g_strcmp0 (argv1, "skip-printf") == 0) + { + g_test_add_func ("/skip-printf", test_skip_printf); + } + else if (g_strcmp0 (argv1, "incomplete") == 0) + { + g_test_add_func ("/incomplete", test_incomplete); + } + else if (g_strcmp0 (argv1, "incomplete-printf") == 0) + { + g_test_add_func ("/incomplete-printf", test_incomplete_printf); + } + else if (g_strcmp0 (argv1, "fail") == 0) + { + g_test_add_func ("/fail", test_fail); + } + else if (g_strcmp0 (argv1, "fail-printf") == 0) + { + g_test_add_func ("/fail-printf", test_fail_printf); + } + else if (g_strcmp0 (argv1, "all-non-failures") == 0) + { + g_test_add_func ("/pass", test_pass); + g_test_add_func ("/skip", test_skip); + g_test_add_func ("/incomplete", test_incomplete); + } + else if (g_strcmp0 (argv1, "all") == 0) + { + g_test_add_func ("/pass", test_pass); + g_test_add_func ("/skip", test_skip); + g_test_add_func ("/incomplete", test_incomplete); + g_test_add_func ("/fail", test_fail); + } + else if (g_strcmp0 (argv1, "skip-options") == 0) + { + /* The caller is expected to skip some of these with + * -p/-r, -s/-x and/or --GTestSkipCount */ + g_test_add_func ("/a", test_pass); + g_test_add_func ("/b", test_pass); + g_test_add_func ("/b/a", test_pass); + g_test_add_func ("/b/b", test_pass); + g_test_add_func ("/b/b/a", test_pass); + g_test_add_func ("/prefix/a", test_pass); + g_test_add_func ("/prefix/b/b", test_pass); + g_test_add_func ("/prefix-long/a", test_pass); + g_test_add_func ("/c/a", test_pass); + g_test_add_func ("/d/a", test_pass); + } + else if (g_strcmp0 (argv1, "summary") == 0) + { + g_test_add_func ("/summary", test_summary); + } + else + { + g_assert_not_reached (); + } + + return g_test_run (); +} diff --git a/glib/tests/testing.c b/glib/tests/testing.c new file mode 100644 index 0000000..accd5db --- /dev/null +++ b/glib/tests/testing.c @@ -0,0 +1,1733 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2007 Imendio AB + * Authors: Tim Janik + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "config.h" + +/* We want to distinguish between messages originating from libglib + * and messages originating from this program. + */ +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "testing" + +#include +#include +#include +#include + +/* test assertion variants */ +static void +test_assertions_bad_cmpvariant_types (void) +{ + GVariant *v1, *v2; + + v1 = g_variant_new_boolean (TRUE); + v2 = g_variant_new_string ("hello"); + + g_assert_cmpvariant (v1, v2); + + g_variant_unref (v2); + g_variant_unref (v1); + + exit (0); +} + +static void +test_assertions_bad_cmpvariant_values (void) +{ + GVariant *v1, *v2; + + v1 = g_variant_new_string ("goodbye"); + v2 = g_variant_new_string ("hello"); + + g_assert_cmpvariant (v1, v2); + + g_variant_unref (v2); + g_variant_unref (v1); + + exit (0); +} + +static void +test_assertions_bad_cmpstrv_null1 (void) +{ + const char *strv[] = { "one", "two", "three", NULL }; + g_assert_cmpstrv (strv, NULL); + exit (0); +} + +static void +test_assertions_bad_cmpstrv_null2 (void) +{ + const char *strv[] = { "one", "two", "three", NULL }; + g_assert_cmpstrv (NULL, strv); + exit (0); +} + +static void +test_assertions_bad_cmpstrv_length (void) +{ + const char *strv1[] = { "one", "two", "three", NULL }; + const char *strv2[] = { "one", "two", NULL }; + g_assert_cmpstrv (strv1, strv2); + exit (0); +} + +static void +test_assertions_bad_cmpstrv_values (void) +{ + const char *strv1[] = { "one", "two", "three", NULL }; + const char *strv2[] = { "one", "too", "three", NULL }; + g_assert_cmpstrv (strv1, strv2); + exit (0); +} + +static void +test_assertions_bad_cmpstr (void) +{ + g_assert_cmpstr ("fzz", !=, "fzz"); + exit (0); +} + +static void +test_assertions_bad_cmpint (void) +{ + g_assert_cmpint (4, !=, 4); + exit (0); +} + +static void +test_assertions_bad_cmpmem_len (void) +{ + g_assert_cmpmem ("foo", 3, "foot", 4); + exit (0); +} + +static void +test_assertions_bad_cmpmem_data (void) +{ + g_assert_cmpmem ("foo", 3, "fzz", 3); + exit (0); +} + +static void +test_assertions_bad_cmpmem_null (void) +{ + g_assert_cmpmem (NULL, 3, NULL, 3); + exit (0); +} + +static void +test_assertions_bad_cmpfloat_epsilon (void) +{ + g_assert_cmpfloat_with_epsilon (3.14, 3.15, 0.001); + exit (0); +} + +/* Emulates something like rmdir() failing. */ +static int +return_errno (void) +{ + errno = ERANGE; /* arbitrary non-zero value */ + return -1; +} + +/* Emulates something like rmdir() succeeding. */ +static int +return_no_errno (void) +{ + return 0; +} + +static void +test_assertions_bad_no_errno (void) +{ + g_assert_no_errno (return_errno ()); +} + +static void +test_assertions (void) +{ + const char *strv1[] = { "one", "two", "three", NULL }; + const char *strv2[] = { "one", "two", "three", NULL }; + GVariant *v1, *v2; + gchar *fuu; + + g_assert_cmpint (1, >, 0); + g_assert_cmphex (2, ==, 2); + g_assert_cmpfloat (3.3, !=, 7); + g_assert_cmpfloat (7, <=, 3 + 4); + g_assert_cmpfloat_with_epsilon (3.14, 3.15, 0.01); + g_assert_cmpfloat_with_epsilon (3.14159, 3.1416, 0.0001); + g_assert (TRUE); + g_assert_true (TRUE); + g_assert_cmpstr ("foo", !=, "faa"); + fuu = g_strdup_printf ("f%s", "uu"); + g_test_queue_free (fuu); + g_assert_cmpstr ("foo", !=, fuu); + g_assert_cmpstr ("fuu", ==, fuu); + g_assert_cmpstr (NULL, <, ""); + g_assert_cmpstr (NULL, ==, NULL); + g_assert_cmpstr ("", >, NULL); + g_assert_cmpstr ("foo", <, "fzz"); + g_assert_cmpstr ("fzz", >, "faa"); + g_assert_cmpstr ("fzz", ==, "fzz"); + g_assert_cmpmem ("foo", 3, "foot", 3); + g_assert_cmpmem (NULL, 0, NULL, 0); + g_assert_cmpmem (NULL, 0, "foot", 0); + g_assert_cmpmem ("foo", 0, NULL, 0); + g_assert_no_errno (return_no_errno ()); + + g_assert_cmpstrv (NULL, NULL); + g_assert_cmpstrv (strv1, strv2); + + v1 = g_variant_new_parsed ("['hello', 'there']"); + v2 = g_variant_new_parsed ("['hello', 'there']"); + + g_assert_cmpvariant (v1, v1); + g_assert_cmpvariant (v1, v2); + + g_variant_unref (v2); + g_variant_unref (v1); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpvariant_types", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpvariant_values", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstr", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_null1", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_null2", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_length", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_values", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpint", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_len", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*len*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_data", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + g_test_trap_assert_stderr_unmatched ("*assertion failed*len*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_null", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*NULL*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpfloat_epsilon", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + + g_test_trap_subprocess ("/misc/assertions/subprocess/bad_no_errno", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); +} + +/* test g_test_timer* API */ +static void +test_timer (void) +{ + double ttime; + g_test_timer_start(); + g_assert_cmpfloat (g_test_timer_last(), ==, 0); + g_usleep (25 * 1000); + ttime = g_test_timer_elapsed(); + g_assert_cmpfloat (ttime, >, 0); + g_assert_cmpfloat (g_test_timer_last(), ==, ttime); + g_test_minimized_result (ttime, "timer-test-time: %fsec", ttime); + g_test_maximized_result (5, "bogus-quantity: %ddummies", 5); /* simple API test */ +} + +#ifdef G_OS_UNIX +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +/* fork out for a failing test */ +static void +test_fork_fail (void) +{ + if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR)) + { + g_assert_not_reached(); + } + g_test_trap_assert_failed(); + g_test_trap_assert_stderr ("*ERROR*test_fork_fail*should not be reached*"); +} + +/* fork out to assert stdout and stderr patterns */ +static void +test_fork_patterns (void) +{ + if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR)) + { + g_print ("some stdout text: somagic17\n"); + g_printerr ("some stderr text: semagic43\n"); + exit (0); + } + g_test_trap_assert_passed(); + g_test_trap_assert_stdout ("*somagic17*"); + g_test_trap_assert_stderr ("*semagic43*"); +} + +/* fork out for a timeout test */ +static void +test_fork_timeout (void) +{ + /* allow child to run for only a fraction of a second */ + if (g_test_trap_fork (0.11 * 1000000, 0)) + { + /* loop and sleep forever */ + while (TRUE) + g_usleep (1000 * 1000); + } + g_test_trap_assert_failed(); + g_assert_true (g_test_trap_reached_timeout()); +} + +G_GNUC_END_IGNORE_DEPRECATIONS +#endif /* G_OS_UNIX */ + +static void +test_subprocess_fail (void) +{ + if (g_test_subprocess ()) + { + g_assert_not_reached (); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*ERROR*test_subprocess_fail*should not be reached*"); +} + +static void +test_subprocess_no_such_test (void) +{ + if (g_test_subprocess ()) + { + g_test_trap_subprocess ("/trap_subprocess/this-test-does-not-exist", 0, 0); + g_assert_not_reached (); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*test does not exist*"); + g_test_trap_assert_stderr_unmatched ("*should not be reached*"); +} + +static void +test_subprocess_patterns (void) +{ + if (g_test_subprocess ()) + { + g_print ("some stdout text: somagic17\n"); + g_printerr ("some stderr text: semagic43\n"); + exit (0); + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*somagic17*"); + g_test_trap_assert_stderr ("*semagic43*"); +} + +static void +test_subprocess_timeout (void) +{ + if (g_test_subprocess ()) + { + /* loop and sleep forever */ + while (TRUE) + g_usleep (1000 * 1000); + return; + } + /* allow child to run for only a fraction of a second */ + g_test_trap_subprocess (NULL, 0.11 * 1000000, 0); + g_test_trap_assert_failed (); + g_assert_true (g_test_trap_reached_timeout ()); +} + +/* run a test with fixture setup and teardown */ +typedef struct { + guint seed; + guint prime; + gchar *msg; +} Fixturetest; +static void +fixturetest_setup (Fixturetest *fix, + gconstpointer test_data) +{ + g_assert_true (test_data == (void*) 0xc0cac01a); + fix->seed = 18; + fix->prime = 19; + fix->msg = g_strdup_printf ("%d", fix->prime); +} +static void +fixturetest_test (Fixturetest *fix, + gconstpointer test_data) +{ + guint prime = g_spaced_primes_closest (fix->seed); + g_assert_cmpint (prime, ==, fix->prime); + prime = g_ascii_strtoull (fix->msg, NULL, 0); + g_assert_cmpint (prime, ==, fix->prime); + g_assert_true (test_data == (void*) 0xc0cac01a); +} +static void +fixturetest_teardown (Fixturetest *fix, + gconstpointer test_data) +{ + g_assert_true (test_data == (void*) 0xc0cac01a); + g_free (fix->msg); +} + +static struct { + int bit, vint1, vint2, irange; + long double vdouble, drange; +} shared_rand_state; + +static void +test_rand1 (void) +{ + shared_rand_state.bit = g_test_rand_bit(); + shared_rand_state.vint1 = g_test_rand_int(); + shared_rand_state.vint2 = g_test_rand_int(); + g_assert_cmpint (shared_rand_state.vint1, !=, shared_rand_state.vint2); + shared_rand_state.irange = g_test_rand_int_range (17, 35); + g_assert_cmpint (shared_rand_state.irange, >=, 17); + g_assert_cmpint (shared_rand_state.irange, <=, 35); + shared_rand_state.vdouble = g_test_rand_double(); + shared_rand_state.drange = g_test_rand_double_range (-999, +17); + g_assert_cmpfloat (shared_rand_state.drange, >=, -999); + g_assert_cmpfloat (shared_rand_state.drange, <=, +17); +} + +static void +test_rand2 (void) +{ + /* this test only works if run after test1. + * we do this to check that random number generators + * are reseeded upon fixture setup. + */ + g_assert_cmpint (shared_rand_state.bit, ==, g_test_rand_bit()); + g_assert_cmpint (shared_rand_state.vint1, ==, g_test_rand_int()); + g_assert_cmpint (shared_rand_state.vint2, ==, g_test_rand_int()); + g_assert_cmpint (shared_rand_state.irange, ==, g_test_rand_int_range (17, 35)); + g_assert_cmpfloat (shared_rand_state.vdouble, ==, g_test_rand_double()); + g_assert_cmpfloat (shared_rand_state.drange, ==, g_test_rand_double_range (-999, +17)); +} + +static void +test_data_test (gconstpointer test_data) +{ + g_assert_true (test_data == (void*) 0xc0c0baba); +} + +static void +test_random_conversions (void) +{ + /* very simple conversion test using random numbers */ + int vint = g_test_rand_int(); + char *err, *str = g_strdup_printf ("%d", vint); + gint64 vint64 = g_ascii_strtoll (str, &err, 10); + g_assert_cmphex (vint, ==, vint64); + g_assert_true (!err || *err == 0); + g_free (str); +} + +static gboolean +fatal_handler (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + return FALSE; +} + +static void +test_fatal_log_handler_critical_pass (void) +{ + g_test_log_set_fatal_handler (fatal_handler, NULL); + g_str_has_prefix (NULL, "file://"); + g_critical ("Test passing"); + exit (0); +} + +static void +test_fatal_log_handler_error_fail (void) +{ + g_error ("Test failing"); + exit (0); +} + +static void +test_fatal_log_handler_critical_fail (void) +{ + g_str_has_prefix (NULL, "file://"); + g_critical ("Test passing"); + exit (0); +} + +static void +test_fatal_log_handler (void) +{ + g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/critical-pass", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*CRITICAL*g_str_has_prefix*"); + g_test_trap_assert_stderr ("*CRITICAL*Test passing*"); + + g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/error-fail", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*ERROR*Test failing*"); + + g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/critical-fail", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*g_str_has_prefix*"); + g_test_trap_assert_stderr_unmatched ("*CRITICAL*Test passing*"); +} + +static void +test_expected_messages_warning (void) +{ + g_warning ("This is a %d warning", g_random_int ()); + g_return_if_reached (); +} + +static void +test_expected_messages_expect_warning (void) +{ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "This is a * warning"); + test_expected_messages_warning (); +} + +static void +test_expected_messages_wrong_warning (void) +{ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*should not be *"); + test_expected_messages_warning (); +} + +static void +test_expected_messages_expected (void) +{ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "This is a * warning"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*should not be reached"); + + test_expected_messages_warning (); + + g_test_assert_expected_messages (); + exit (0); +} + +static void +test_expected_messages_null_domain (void) +{ + g_test_expect_message (NULL, G_LOG_LEVEL_WARNING, "no domain"); + g_log (NULL, G_LOG_LEVEL_WARNING, "no domain"); + g_test_assert_expected_messages (); +} + +static void +test_expected_messages_expect_error (void) +{ + /* make sure we can't try to expect a g_error() */ + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "*G_LOG_LEVEL_ERROR*"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "this won't work"); + g_test_assert_expected_messages (); +} + +static void +test_expected_messages_extra_warning (void) +{ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "This is a * warning"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*should not be reached"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "nope"); + + test_expected_messages_warning (); + + /* If we don't assert, it won't notice the missing message */ + exit (0); +} + +static void +test_expected_messages_unexpected_extra_warning (void) +{ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "This is a * warning"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*should not be reached"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "nope"); + + test_expected_messages_warning (); + + g_test_assert_expected_messages (); + exit (0); +} + +static void +test_expected_messages (void) +{ + g_test_trap_subprocess ("/misc/expected-messages/subprocess/warning", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*This is a * warning*"); + g_test_trap_assert_stderr_unmatched ("*should not be reached*"); + + g_test_trap_subprocess ("/misc/expected-messages/subprocess/expect-warning", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr_unmatched ("*This is a * warning*"); + g_test_trap_assert_stderr ("*should not be reached*"); + + g_test_trap_subprocess ("/misc/expected-messages/subprocess/wrong-warning", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr_unmatched ("*should not be reached*"); + g_test_trap_assert_stderr ("*GLib-CRITICAL*Did not see expected message testing-CRITICAL*should not be *WARNING*This is a * warning*"); + + g_test_trap_subprocess ("/misc/expected-messages/subprocess/expected", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr (""); + + g_test_trap_subprocess ("/misc/expected-messages/subprocess/null-domain", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr (""); + + g_test_trap_subprocess ("/misc/expected-messages/subprocess/extra-warning", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr (""); + + g_test_trap_subprocess ("/misc/expected-messages/subprocess/unexpected-extra-warning", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib:ERROR*Did not see expected message testing-CRITICAL*nope*"); +} + +static void +test_expected_messages_debug (void) +{ + g_test_expect_message ("Test", G_LOG_LEVEL_WARNING, "warning message"); + g_log ("Test", G_LOG_LEVEL_DEBUG, "should be ignored"); + g_log ("Test", G_LOG_LEVEL_WARNING, "warning message"); + g_test_assert_expected_messages (); + + g_test_expect_message ("Test", G_LOG_LEVEL_DEBUG, "debug message"); + g_log ("Test", G_LOG_LEVEL_DEBUG, "debug message"); + g_test_assert_expected_messages (); +} + +static void +test_dash_p_hidden (void) +{ + if (!g_test_subprocess ()) + g_assert_not_reached (); + + g_print ("Test /misc/dash-p/subprocess/hidden ran\n"); +} + +static void +test_dash_p_hidden_sub (void) +{ + if (!g_test_subprocess ()) + g_assert_not_reached (); + + g_print ("Test /misc/dash-p/subprocess/hidden/sub ran\n"); +} + +/* The rest of the dash_p tests will get run by the toplevel test + * process, but they shouldn't do anything there. + */ + +static void +test_dash_p_child (void) +{ + if (!g_test_subprocess ()) + return; + + g_print ("Test /misc/dash-p/child ran\n"); +} + +static void +test_dash_p_child_sub (void) +{ + if (!g_test_subprocess ()) + return; + + g_print ("Test /misc/dash-p/child/sub ran\n"); +} + +static void +test_dash_p_child_sub2 (void) +{ + if (!g_test_subprocess ()) + return; + + g_print ("Test /misc/dash-p/child/sub2 ran\n"); +} + +static void +test_dash_p_child_sub_child (void) +{ + if (!g_test_subprocess ()) + return; + + g_print ("Test /misc/dash-p/child/subprocess ran\n"); +} + +static void +test_dash_p (void) +{ + g_test_trap_subprocess ("/misc/dash-p/subprocess/hidden", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Test /misc/dash-p/subprocess/hidden ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden/sub ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden/sub2 ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden/sub/subprocess ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child*"); + + g_test_trap_subprocess ("/misc/dash-p/subprocess/hidden/sub", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Test /misc/dash-p/subprocess/hidden/sub ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden/sub2 ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden/subprocess ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child*"); + + g_test_trap_subprocess ("/misc/dash-p/child", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Test /misc/dash-p/child ran*"); + g_test_trap_assert_stdout ("*Test /misc/dash-p/child/sub ran*"); + g_test_trap_assert_stdout ("*Test /misc/dash-p/child/sub2 ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child/subprocess ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden*"); + + g_test_trap_subprocess ("/misc/dash-p/child/sub", 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Test /misc/dash-p/child/sub ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child/sub2 ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child/subprocess ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden*"); +} + +static void +test_nonfatal (void) +{ + if (g_test_subprocess ()) + { + g_test_set_nonfatal_assertions (); + g_assert_cmpint (4, ==, 5); + g_print ("The End\n"); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*4 == 5*"); + g_test_trap_assert_stdout ("*The End*"); +} + +static void +test_skip (void) +{ + g_test_skip ("Skipped should count as passed, not failed"); + /* This function really means "the test concluded with a non-successful + * status" rather than "the test failed": it is documented to return + * true for skipped and incomplete tests, not just for failures. */ + g_assert_true (g_test_failed ()); +} + +static void +test_pass (void) +{ +} + +static void +subprocess_fail (void) +{ + /* Exit 1 instead of raising SIGABRT so that we can make assertions about + * how this combines with skipped/incomplete tests */ + g_test_set_nonfatal_assertions (); + g_test_fail (); + g_assert_true (g_test_failed ()); +} + +static void +test_fail (void) +{ + if (g_test_subprocess ()) + { + subprocess_fail (); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); +} + +static void +subprocess_incomplete (void) +{ + g_test_incomplete ("not done"); + /* This function really means "the test concluded with a non-successful + * status" rather than "the test failed": it is documented to return + * true for skipped and incomplete tests, not just for failures. */ + g_assert_true (g_test_failed ()); +} + +static void +test_incomplete (void) +{ + if (g_test_subprocess ()) + { + subprocess_incomplete (); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + /* An incomplete test represents functionality that is known not to be + * implemented yet (an expected failure), so it does not cause test + * failure; but it does count as the test having been skipped, which + * causes nonzero exit status 77, which is treated as failure by + * g_test_trap_subprocess(). */ + g_test_trap_assert_failed (); +} + +static void +test_subprocess_timed_out (void) +{ + if (g_test_subprocess ()) + { + g_usleep (1000000); + return; + } + g_test_trap_subprocess (NULL, 50000, 0); + g_assert_true (g_test_trap_reached_timeout ()); +} + +static void +test_path_first (void) +{ + g_assert_cmpstr (g_test_get_path (), ==, "/misc/path/first"); +} + +static void +test_path_second (void) +{ + g_assert_cmpstr (g_test_get_path (), ==, "/misc/path/second"); +} + +static const char *argv0; + +static void +test_combining (void) +{ + GPtrArray *argv; + GError *error = NULL; + int status; + + g_test_message ("single test case skipped -> overall status 77"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/skip"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 77); + g_clear_error (&error); + + g_test_message ("each test case skipped -> overall status 77"); + g_ptr_array_set_size (argv, 0); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/skip"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/skip1"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/skip2"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 77); + g_clear_error (&error); + + g_test_message ("single test case incomplete -> overall status 77"); + g_ptr_array_set_size (argv, 0); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/incomplete"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 77); + g_clear_error (&error); + + g_test_message ("one pass and some skipped -> overall status 0"); + g_ptr_array_set_size (argv, 0); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/skip"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/pass"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/skip1"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_test_message ("one pass and some incomplete -> overall status 0"); + g_ptr_array_set_size (argv, 0); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/pass"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/incomplete"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_test_message ("one pass and mix of skipped and incomplete -> overall status 0"); + g_ptr_array_set_size (argv, 0); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/pass"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/skip1"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/incomplete"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_test_message ("one fail and some skipped -> overall status fail"); + g_ptr_array_set_size (argv, 0); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/skip"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/fail"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/skip1"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (&error); + + g_test_message ("one fail and some incomplete -> overall status fail"); + g_ptr_array_set_size (argv, 0); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/fail"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/incomplete"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (&error); + + g_test_message ("one fail and mix of skipped and incomplete -> overall status fail"); + g_ptr_array_set_size (argv, 0); + g_ptr_array_add (argv, (char *) argv0); + g_ptr_array_add (argv, "--GTestSubprocess"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/fail"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/skip1"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/misc/combining/subprocess/incomplete"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (&error); + + g_ptr_array_unref (argv); +} + +/* Test the TAP output when a test suite is run with --tap. */ +static void +test_tap (void) +{ + const char *testing_helper; + GPtrArray *argv; + GError *error = NULL; + int status; + gchar *output; + + testing_helper = g_test_get_filename (G_TEST_BUILT, "testing-helper" EXEEXT, NULL); + + g_test_message ("pass"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "pass"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "\nok 1 /pass\n")); + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("skip"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "\nok 1 /skip # SKIP not enough tea\n")); + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("skip with printf format"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-printf"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "\nok 1 /skip-printf # SKIP not enough coffee\n")); + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("incomplete"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "incomplete"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "\nnot ok 1 /incomplete # TODO mind reading not implemented yet\n")); + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("incomplete with printf format"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "incomplete-printf"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "\nnot ok 1 /incomplete-printf # TODO telekinesis not implemented yet\n")); + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("fail"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "fail"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); + g_assert_nonnull (strstr (output, "\nnot ok 1 /fail\n")); + g_free (output); + g_clear_error (&error); + g_ptr_array_unref (argv); + + g_test_message ("fail with message"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "fail-printf"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); + g_assert_nonnull (strstr (output, "\nnot ok 1 /fail-printf - this test intentionally left failing\n")); + g_free (output); + g_clear_error (&error); + g_ptr_array_unref (argv); + + g_test_message ("all"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "all"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); + g_clear_error (&error); + g_ptr_array_unref (argv); + + g_test_message ("all-non-failures"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "all-non-failures"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_ptr_array_unref (argv); + + g_test_message ("--GTestSkipCount"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "--GTestSkipCount"); + g_ptr_array_add (argv, "2"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "1..10\n")); + g_assert_nonnull (strstr (output, "\nok 1 /a # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 2 /b # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 3 /b/a\n")); + g_assert_nonnull (strstr (output, "\nok 4 /b/b\n")); + g_assert_nonnull (strstr (output, "\nok 5 /b/b/a\n")); + g_assert_nonnull (strstr (output, "\nok 6 /prefix/a\n")); + g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b\n")); + g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a\n")); + g_assert_nonnull (strstr (output, "\nok 9 /c/a\n")); + g_assert_nonnull (strstr (output, "\nok 10 /d/a\n")); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("--GTestSkipCount=0 is the same as omitting it"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "--GTestSkipCount"); + g_ptr_array_add (argv, "0"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "1..10\n")); + g_assert_nonnull (strstr (output, "\nok 1 /a\n")); + g_assert_nonnull (strstr (output, "\nok 2 /b\n")); + g_assert_nonnull (strstr (output, "\nok 3 /b/a\n")); + g_assert_nonnull (strstr (output, "\nok 4 /b/b\n")); + g_assert_nonnull (strstr (output, "\nok 5 /b/b/a\n")); + g_assert_nonnull (strstr (output, "\nok 6 /prefix/a\n")); + g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b\n")); + g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a\n")); + g_assert_nonnull (strstr (output, "\nok 9 /c/a\n")); + g_assert_nonnull (strstr (output, "\nok 10 /d/a\n")); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("--GTestSkipCount > number of tests skips all"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "--GTestSkipCount"); + g_ptr_array_add (argv, "11"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "1..10\n")); + g_assert_nonnull (strstr (output, "\nok 1 /a # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 2 /b # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 3 /b/a # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 4 /b/b # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 5 /b/b/a # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 6 /prefix/a # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP\n")); + g_assert_nonnull (strstr (output, "\nok 10 /d/a # SKIP\n")); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("-p"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/b"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "\nok 1 /c/a\n")); + g_assert_nonnull (strstr (output, "\nok 2 /c/a\n")); + g_assert_nonnull (strstr (output, "\nok 3 /b\n")); + g_assert_nonnull (strstr (output, "\nok 4 /b/a\n")); + g_assert_nonnull (strstr (output, "\nok 5 /b/b\n")); + g_assert_nonnull (strstr (output, "\n1..5\n")); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("--run-prefix"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "-r"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, "-r"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, "--run-prefix"); + g_ptr_array_add (argv, "/b"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "\nok 1 /c/a\n")); + g_assert_nonnull (strstr (output, "\nok 2 /c/a\n")); + g_assert_nonnull (strstr (output, "\nok 3 /b\n")); + g_assert_nonnull (strstr (output, "\nok 4 /b/a\n")); + g_assert_nonnull (strstr (output, "\nok 5 /b/b\n")); + g_assert_nonnull (strstr (output, "\nok 6 /b/b/a\n")); + g_assert_nonnull (strstr (output, "\n1..6\n")); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("--run-prefix 2"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "-r"); + g_ptr_array_add (argv, "/pre"); + g_ptr_array_add (argv, "--run-prefix"); + g_ptr_array_add (argv, "/b/b"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "\nok 1 /b/b\n")); + g_assert_nonnull (strstr (output, "\nok 2 /b/b/a\n")); + g_assert_nonnull (strstr (output, "\n1..2\n")); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("--run-prefix conflict"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "-r"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, "-p"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, "--run-prefix"); + g_ptr_array_add (argv, "/b"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_spawn_check_wait_status (status, &error); + g_assert_nonnull (error); + g_assert_nonnull (strstr (output, "do not mix [-r | --run-prefix] with '-p'\n")); + g_clear_error (&error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("-s"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "-s"); + g_ptr_array_add (argv, "/a"); + g_ptr_array_add (argv, "-s"); + g_ptr_array_add (argv, "/b"); + g_ptr_array_add (argv, "-s"); + g_ptr_array_add (argv, "/pre"); + g_ptr_array_add (argv, "-s"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "1..10\n")); + g_assert_nonnull (strstr (output, "\nok 1 /a # SKIP by request")); + g_assert_nonnull (strstr (output, "\nok 2 /b # SKIP by request")); + /* "-s /b" would skip a test named exactly /b, but not a test named + * /b/anything */ + g_assert_nonnull (strstr (output, "\nok 3 /b/a\n")); + g_assert_nonnull (strstr (output, "\nok 4 /b/b\n")); + g_assert_nonnull (strstr (output, "\nok 5 /b/b/a\n")); + g_assert_nonnull (strstr (output, "\nok 6 /prefix/a\n")); + g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b\n")); + g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a\n")); + g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP by request")); + g_assert_nonnull (strstr (output, "\nok 10 /d/a\n")); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("--skip-prefix"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "-x"); + g_ptr_array_add (argv, "/a"); + g_ptr_array_add (argv, "--skip-prefix"); + g_ptr_array_add (argv, "/pre"); + g_ptr_array_add (argv, "-x"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "1..10\n")); + g_assert_nonnull (strstr (output, "\nok 1 /a # SKIP by request")); + g_assert_nonnull (strstr (output, "\nok 2 /b\n")); + g_assert_nonnull (strstr (output, "\nok 3 /b/a\n")); + g_assert_nonnull (strstr (output, "\nok 4 /b/b\n")); + g_assert_nonnull (strstr (output, "\nok 5 /b/b/a\n")); + /* "--skip-prefix /pre" will skip all test path which begins with /pre */ + g_assert_nonnull (strstr (output, "\nok 6 /prefix/a # SKIP by request")); + g_assert_nonnull (strstr (output, "\nok 7 /prefix/b/b # SKIP by request")); + g_assert_nonnull (strstr (output, "\nok 8 /prefix-long/a # SKIP by request")); + g_assert_nonnull (strstr (output, "\nok 9 /c/a # SKIP by request")); + g_assert_nonnull (strstr (output, "\nok 10 /d/a\n")); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + + g_free (output); + g_ptr_array_unref (argv); + + g_test_message ("--skip-prefix conflict"); + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "skip-options"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, "-s"); + g_ptr_array_add (argv, "/a"); + g_ptr_array_add (argv, "--skip-prefix"); + g_ptr_array_add (argv, "/pre"); + g_ptr_array_add (argv, "-x"); + g_ptr_array_add (argv, "/c/a"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + g_spawn_check_wait_status (status, &error); + g_assert_nonnull (error); + g_assert_nonnull (strstr (output, "do not mix [-x | --skip-prefix] with '-s'\n")); + g_clear_error (&error); + + g_free (output); + g_ptr_array_unref (argv); +} + +static void +test_tap_summary (void) +{ + const char *testing_helper; + GPtrArray *argv; + GError *error = NULL; + int status; + gchar *output; + + g_test_summary ("Test the output of g_test_summary() from the TAP output of a test."); + + testing_helper = g_test_get_filename (G_TEST_BUILT, "testing-helper" EXEEXT, NULL); + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "summary"); + g_ptr_array_add (argv, "--tap"); + g_ptr_array_add (argv, NULL); + + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + /* Note: The test path in the output is not `/tap/summary` because it’s the + * test path from testing-helper, not from this function. */ + g_assert_nonnull (strstr (output, "\n# /summary summary: Tests that g_test_summary() " + "works with TAP, by outputting a known " + "summary message in testing-helper, and " + "checking for it in the TAP output later.\n")); + g_free (output); + g_ptr_array_unref (argv); +} + +static void +test_init_no_argv0 (void) +{ + const char *testing_helper; + GPtrArray *argv; + GError *error = NULL; + int status; + gchar *output; + + g_test_summary ("Test that g_test_init() can be called safely with argc == 0."); + + testing_helper = g_test_get_filename (G_TEST_BUILT, "testing-helper" EXEEXT, NULL); + + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (char *) testing_helper); + g_ptr_array_add (argv, "init-null-argv0"); + g_ptr_array_add (argv, NULL); + + /* This has to be spawned manually and can’t be run with g_test_subprocess() + * because the test helper can’t be run after `g_test_init()` has been called + * in the process. */ + g_spawn_sync (NULL, (char **) argv->pdata, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, &output, NULL, &status, + &error); + g_assert_no_error (error); + + g_spawn_check_wait_status (status, &error); + g_assert_no_error (error); + g_assert_nonnull (strstr (output, "# random seed:")); + g_free (output); + g_ptr_array_unref (argv); +} + +int +main (int argc, + char *argv[]) +{ + int ret; + char *filename, *filename2; + + argv0 = argv[0]; + + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + /* Part of a test for + * https://gitlab.gnome.org/GNOME/glib/-/issues/2563, see below */ + filename = g_test_build_filename (G_TEST_BUILT, "nonexistent", NULL); + + g_test_add_func ("/random-generator/rand-1", test_rand1); + g_test_add_func ("/random-generator/rand-2", test_rand2); + g_test_add_func ("/random-generator/random-conversions", test_random_conversions); + g_test_add_func ("/misc/assertions", test_assertions); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpvariant_types", test_assertions_bad_cmpvariant_types); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpvariant_values", test_assertions_bad_cmpvariant_values); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpstr", test_assertions_bad_cmpstr); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpstrv_null1", test_assertions_bad_cmpstrv_null1); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpstrv_null2", test_assertions_bad_cmpstrv_null2); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpstrv_length", test_assertions_bad_cmpstrv_length); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpstrv_values", test_assertions_bad_cmpstrv_values); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpint", test_assertions_bad_cmpint); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_len", test_assertions_bad_cmpmem_len); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_data", test_assertions_bad_cmpmem_data); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_null", test_assertions_bad_cmpmem_null); + g_test_add_func ("/misc/assertions/subprocess/bad_cmpfloat_epsilon", test_assertions_bad_cmpfloat_epsilon); + g_test_add_func ("/misc/assertions/subprocess/bad_no_errno", test_assertions_bad_no_errno); + g_test_add_data_func ("/misc/test-data", (void*) 0xc0c0baba, test_data_test); + g_test_add ("/misc/primetoul", Fixturetest, (void*) 0xc0cac01a, fixturetest_setup, fixturetest_test, fixturetest_teardown); + if (g_test_perf()) + g_test_add_func ("/misc/timer", test_timer); + +#ifdef G_OS_UNIX + g_test_add_func ("/forking/fail assertion", test_fork_fail); + g_test_add_func ("/forking/patterns", test_fork_patterns); + if (g_test_slow()) + g_test_add_func ("/forking/timeout", test_fork_timeout); +#endif + + g_test_add_func ("/trap_subprocess/fail", test_subprocess_fail); + g_test_add_func ("/trap_subprocess/no-such-test", test_subprocess_no_such_test); + if (g_test_slow ()) + g_test_add_func ("/trap_subprocess/timeout", test_subprocess_timeout); + + g_test_add_func ("/trap_subprocess/patterns", test_subprocess_patterns); + + g_test_add_func ("/misc/fatal-log-handler", test_fatal_log_handler); + g_test_add_func ("/misc/fatal-log-handler/subprocess/critical-pass", test_fatal_log_handler_critical_pass); + g_test_add_func ("/misc/fatal-log-handler/subprocess/error-fail", test_fatal_log_handler_error_fail); + g_test_add_func ("/misc/fatal-log-handler/subprocess/critical-fail", test_fatal_log_handler_critical_fail); + + g_test_add_func ("/misc/expected-messages", test_expected_messages); + g_test_add_func ("/misc/expected-messages/subprocess/warning", test_expected_messages_warning); + g_test_add_func ("/misc/expected-messages/subprocess/expect-warning", test_expected_messages_expect_warning); + g_test_add_func ("/misc/expected-messages/subprocess/wrong-warning", test_expected_messages_wrong_warning); + g_test_add_func ("/misc/expected-messages/subprocess/expected", test_expected_messages_expected); + g_test_add_func ("/misc/expected-messages/subprocess/null-domain", test_expected_messages_null_domain); + g_test_add_func ("/misc/expected-messages/subprocess/extra-warning", test_expected_messages_extra_warning); + g_test_add_func ("/misc/expected-messages/subprocess/unexpected-extra-warning", test_expected_messages_unexpected_extra_warning); + g_test_add_func ("/misc/expected-messages/expect-error", test_expected_messages_expect_error); + g_test_add_func ("/misc/expected-messages/skip-debug", test_expected_messages_debug); + + g_test_add_func ("/misc/dash-p", test_dash_p); + g_test_add_func ("/misc/dash-p/child", test_dash_p_child); + g_test_add_func ("/misc/dash-p/child/sub", test_dash_p_child_sub); + g_test_add_func ("/misc/dash-p/child/sub/subprocess", test_dash_p_child_sub_child); + g_test_add_func ("/misc/dash-p/child/sub/subprocess/child", test_dash_p_child_sub_child); + g_test_add_func ("/misc/dash-p/child/sub2", test_dash_p_child_sub2); + g_test_add_func ("/misc/dash-p/subprocess/hidden", test_dash_p_hidden); + g_test_add_func ("/misc/dash-p/subprocess/hidden/sub", test_dash_p_hidden_sub); + + g_test_add_func ("/misc/nonfatal", test_nonfatal); + + g_test_add_func ("/misc/skip", test_skip); + g_test_add_func ("/misc/combining", test_combining); + g_test_add_func ("/misc/combining/subprocess/fail", subprocess_fail); + g_test_add_func ("/misc/combining/subprocess/skip1", test_skip); + g_test_add_func ("/misc/combining/subprocess/skip2", test_skip); + g_test_add_func ("/misc/combining/subprocess/incomplete", subprocess_incomplete); + g_test_add_func ("/misc/combining/subprocess/pass", test_pass); + g_test_add_func ("/misc/fail", test_fail); + g_test_add_func ("/misc/incomplete", test_incomplete); + g_test_add_func ("/misc/timeout", test_subprocess_timed_out); + + g_test_add_func ("/misc/path/first", test_path_first); + g_test_add_func ("/misc/path/second", test_path_second); + + g_test_add_func ("/tap", test_tap); + g_test_add_func ("/tap/summary", test_tap_summary); + + g_test_add_func ("/init/no_argv0", test_init_no_argv0); + + ret = g_test_run (); + + /* We can't test for https://gitlab.gnome.org/GNOME/glib/-/issues/2563 + * from a test-case, because the whole point of that issue is that it's + * about whether certain patterns are valid after g_test_run() has + * returned... so put an ad-hoc test here, and just crash if it fails. */ + filename2 = g_test_build_filename (G_TEST_BUILT, "nonexistent", NULL); + g_assert_cmpstr (filename, ==, filename2); + + g_free (filename); + g_free (filename2); + return ret; +} diff --git a/glib/tests/thread-pool.c b/glib/tests/thread-pool.c new file mode 100644 index 0000000..5c70815 --- /dev/null +++ b/glib/tests/thread-pool.c @@ -0,0 +1,268 @@ +/* Unit tests for GThreadPool + * Copyright (C) 2020 Sebastian Dröge + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include + +#include + +typedef struct { + GMutex mutex; + GCond cond; + gboolean signalled; +} MutexCond; + +static void +pool_func (gpointer data, gpointer user_data) +{ + MutexCond *m = user_data; + + g_mutex_lock (&m->mutex); + g_assert_false (m->signalled); + g_assert_true (data == GUINT_TO_POINTER (123)); + m->signalled = TRUE; + g_cond_signal (&m->cond); + g_mutex_unlock (&m->mutex); +} + +static void +test_simple (gconstpointer shared) +{ + GThreadPool *pool; + GError *err = NULL; + MutexCond m; + gboolean success; + + g_mutex_init (&m.mutex); + g_cond_init (&m.cond); + + if (GPOINTER_TO_INT (shared)) + { + g_test_summary ("Tests that a shared, non-exclusive thread pool " + "generally works."); + pool = g_thread_pool_new (pool_func, &m, -1, FALSE, &err); + } + else + { + g_test_summary ("Tests that an exclusive thread pool generally works."); + pool = g_thread_pool_new (pool_func, &m, 2, TRUE, &err); + } + g_assert_no_error (err); + g_assert_nonnull (pool); + + g_mutex_lock (&m.mutex); + m.signalled = FALSE; + + success = g_thread_pool_push (pool, GUINT_TO_POINTER (123), &err); + g_assert_no_error (err); + g_assert_true (success); + + while (!m.signalled) + g_cond_wait (&m.cond, &m.mutex); + g_mutex_unlock (&m.mutex); + + g_thread_pool_free (pool, TRUE, TRUE); +} + +static void +dummy_pool_func (gpointer data, gpointer user_data) +{ + g_assert_true (data == GUINT_TO_POINTER (123)); +} + +static void +test_create_first_pool (gconstpointer shared_first) +{ + GThreadPool *pool; + GError *err = NULL; + gboolean success; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/2012"); + if (GPOINTER_TO_INT (shared_first)) + { + g_test_summary ("Tests that creating an exclusive pool after a " + "shared one works."); + } + else + { + g_test_summary ("Tests that creating a shared pool after an " + "exclusive one works."); + } + + if (!g_test_subprocess ()) + { + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); + return; + } + + g_thread_pool_set_max_unused_threads (0); + + if (GPOINTER_TO_INT (shared_first)) + pool = g_thread_pool_new (dummy_pool_func, NULL, -1, FALSE, &err); + else + pool = g_thread_pool_new (dummy_pool_func, NULL, 2, TRUE, &err); + g_assert_no_error (err); + g_assert_nonnull (pool); + + success = g_thread_pool_push (pool, GUINT_TO_POINTER (123), &err); + g_assert_no_error (err); + g_assert_true (success); + + g_thread_pool_free (pool, TRUE, TRUE); + + if (GPOINTER_TO_INT (shared_first)) + pool = g_thread_pool_new (dummy_pool_func, NULL, 2, TRUE, &err); + else + pool = g_thread_pool_new (dummy_pool_func, NULL, -1, FALSE, &err); + g_assert_no_error (err); + g_assert_nonnull (pool); + + success = g_thread_pool_push (pool, GUINT_TO_POINTER (123), &err); + g_assert_no_error (err); + g_assert_true (success); + + g_thread_pool_free (pool, TRUE, TRUE); +} + +typedef struct +{ + GMutex mutex; /* (owned) */ + GCond cond; /* (owned) */ + gboolean threads_should_block; /* protected by mutex, cond */ + + guint n_jobs_started; /* (atomic) */ + guint n_jobs_completed; /* (atomic) */ + guint n_free_func_calls; /* (atomic) */ +} TestThreadPoolFullData; + +static void +full_thread_func (gpointer data, + gpointer user_data) +{ + TestThreadPoolFullData *test_data = data; + + g_atomic_int_inc (&test_data->n_jobs_started); + + /* Make the thread block until told to stop blocking. */ + g_mutex_lock (&test_data->mutex); + while (test_data->threads_should_block) + g_cond_wait (&test_data->cond, &test_data->mutex); + g_mutex_unlock (&test_data->mutex); + + g_atomic_int_inc (&test_data->n_jobs_completed); +} + +static void +free_func (gpointer user_data) +{ + TestThreadPoolFullData *test_data = user_data; + + g_atomic_int_inc (&test_data->n_free_func_calls); +} + +static void +test_thread_pool_full (gconstpointer shared_first) +{ + guint i; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/121"); + + g_thread_pool_set_max_unused_threads (0); + + /* Run the test twice, once with a shared pool and once with an exclusive one. */ + for (i = 0; i < 2; i++) + { + GThreadPool *pool; + TestThreadPoolFullData test_data; + GError *local_error = NULL; + gboolean success; + guint j; + + g_mutex_init (&test_data.mutex); + g_cond_init (&test_data.cond); + test_data.threads_should_block = TRUE; + test_data.n_jobs_started = 0; + test_data.n_jobs_completed = 0; + test_data.n_free_func_calls = 0; + + /* Create a thread pool with only one worker thread. The pool can be + * created in shared or exclusive mode. */ + pool = g_thread_pool_new_full (full_thread_func, &test_data, free_func, + 1, (i == 0), + &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (pool); + + /* Push two jobs into the pool. The first one will start executing and + * will block, the second one will wait in the queue as there’s only one + * worker thread. */ + for (j = 0; j < 2; j++) + { + success = g_thread_pool_push (pool, &test_data, &local_error); + g_assert_no_error (local_error); + g_assert_true (success); + } + + /* Wait for the first job to start. */ + while (g_atomic_int_get (&test_data.n_jobs_started) == 0); + + /* Free the pool. This won’t actually free the queued second job yet, as + * the thread pool hangs around until the executing first job has + * completed. The first job will complete only once @threads_should_block + * is unset. */ + g_thread_pool_free (pool, TRUE, FALSE); + + g_assert_cmpuint (g_atomic_int_get (&test_data.n_jobs_started), ==, 1); + g_assert_cmpuint (g_atomic_int_get (&test_data.n_jobs_completed), ==, 0); + g_assert_cmpuint (g_atomic_int_get (&test_data.n_free_func_calls), ==, 0); + + /* Unblock the job and allow the pool to be freed. */ + g_mutex_lock (&test_data.mutex); + test_data.threads_should_block = FALSE; + g_cond_signal (&test_data.cond); + g_mutex_unlock (&test_data.mutex); + + /* Wait for the first job to complete before freeing the mutex and cond. */ + while (g_atomic_int_get (&test_data.n_jobs_completed) != 1 || + g_atomic_int_get (&test_data.n_free_func_calls) != 1); + + g_assert_cmpuint (g_atomic_int_get (&test_data.n_jobs_started), ==, 1); + g_assert_cmpuint (g_atomic_int_get (&test_data.n_jobs_completed), ==, 1); + g_assert_cmpuint (g_atomic_int_get (&test_data.n_free_func_calls), ==, 1); + + g_cond_clear (&test_data.cond); + g_mutex_clear (&test_data.mutex); + } +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_data_func ("/thread_pool/shared", GINT_TO_POINTER (TRUE), test_simple); + g_test_add_data_func ("/thread_pool/exclusive", GINT_TO_POINTER (FALSE), test_simple); + g_test_add_data_func ("/thread_pool/create_shared_after_exclusive", GINT_TO_POINTER (FALSE), test_create_first_pool); + g_test_add_data_func ("/thread_pool/create_full", NULL, test_thread_pool_full); + g_test_add_data_func ("/thread_pool/create_exclusive_after_shared", GINT_TO_POINTER (TRUE), test_create_first_pool); + + return g_test_run (); +} diff --git a/glib/tests/thread.c b/glib/tests/thread.c new file mode 100644 index 0000000..2bae96c --- /dev/null +++ b/glib/tests/thread.c @@ -0,0 +1,226 @@ +/* Unit tests for GThread + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#include +#ifdef HAVE_SYS_PRCTL_H +#include +#endif + +#include + +#include "glib/glib-private.h" + +#ifdef G_OS_UNIX +#include +#include +#endif + +#ifdef THREADS_POSIX +#include +#endif + +static gpointer +thread1_func (gpointer data) +{ + g_thread_exit (GINT_TO_POINTER (1)); + + g_assert_not_reached (); + + return NULL; +} + +/* test that g_thread_exit() works */ +static void +test_thread1 (void) +{ + gpointer result; + GThread *thread; + GError *error = NULL; + + thread = g_thread_try_new ("test", thread1_func, NULL, &error); + g_assert_no_error (error); + + result = g_thread_join (thread); + + g_assert_cmpint (GPOINTER_TO_INT (result), ==, 1); +} + +static gpointer +thread2_func (gpointer data) +{ + return g_thread_self (); +} + +/* test that g_thread_self() works */ +static void +test_thread2 (void) +{ + gpointer result; + GThread *thread; + + thread = g_thread_new ("test", thread2_func, NULL); + + g_assert (g_thread_self () != thread); + + result = g_thread_join (thread); + + g_assert (result == thread); +} + +static gpointer +thread3_func (gpointer data) +{ + GThread *peer = data; + gint retval; + + retval = 3; + + if (peer) + { + gpointer result; + + result = g_thread_join (peer); + + retval += GPOINTER_TO_INT (result); + } + + return GINT_TO_POINTER (retval); +} + +/* test that g_thread_join() works across peers */ +static void +test_thread3 (void) +{ + gpointer result; + GThread *thread1, *thread2, *thread3; + + thread1 = g_thread_new ("a", thread3_func, NULL); + thread2 = g_thread_new ("b", thread3_func, thread1); + thread3 = g_thread_new ("c", thread3_func, thread2); + + result = g_thread_join (thread3); + + g_assert_cmpint (GPOINTER_TO_INT(result), ==, 9); +} + +/* test that thread creation fails as expected, + * by setting RLIMIT_NPROC ridiculously low + */ +static void +test_thread4 (void) +{ +#ifdef _GLIB_ADDRESS_SANITIZER + g_test_incomplete ("FIXME: Leaks a GSystemThread's name, see glib#2308"); +#elif defined(HAVE_PRLIMIT) + struct rlimit ol, nl; + GThread *thread; + GError *error; + gint ret; + + getrlimit (RLIMIT_NPROC, &nl); + nl.rlim_cur = 1; + + if ((ret = prlimit (getpid (), RLIMIT_NPROC, &nl, &ol)) != 0) + g_error ("prlimit failed: %s", g_strerror (errno)); + + error = NULL; + thread = g_thread_try_new ("a", thread1_func, NULL, &error); + + if (thread != NULL) + { + gpointer result; + + /* Privileged processes might be able to create new threads even + * though the rlimit is too low. There isn't much we can do about + * this; we just can't test this failure mode in this situation. */ + g_test_skip ("Unable to test g_thread_try_new() failing with EAGAIN " + "while privileged (CAP_SYS_RESOURCE, CAP_SYS_ADMIN or " + "euid 0?)"); + result = g_thread_join (thread); + g_assert_cmpint (GPOINTER_TO_INT (result), ==, 1); + } + else + { + g_assert (thread == NULL); + g_assert_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN); + g_error_free (error); + } + + if ((ret = prlimit (getpid (), RLIMIT_NPROC, &ol, NULL)) != 0) + g_error ("resetting RLIMIT_NPROC failed: %s", g_strerror (errno)); +#endif +} + +static void +test_thread5 (void) +{ + GThread *thread; + + thread = g_thread_new ("a", thread3_func, NULL); + g_thread_ref (thread); + g_thread_join (thread); + g_thread_unref (thread); +} + +static gpointer +thread6_func (gpointer data) +{ +#if defined (HAVE_PTHREAD_SETNAME_NP_WITH_TID) && defined (HAVE_PTHREAD_GETNAME_NP) + char name[16]; + + pthread_getname_np (pthread_self(), name, 16); + + g_assert_cmpstr (name, ==, data); +#endif + + return NULL; +} + +static void +test_thread6 (void) +{ + GThread *thread; + + thread = g_thread_new ("abc", thread6_func, "abc"); + g_thread_join (thread); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/thread/thread1", test_thread1); + g_test_add_func ("/thread/thread2", test_thread2); + g_test_add_func ("/thread/thread3", test_thread3); + g_test_add_func ("/thread/thread4", test_thread4); + g_test_add_func ("/thread/thread5", test_thread5); + g_test_add_func ("/thread/thread6", test_thread6); + + return g_test_run (); +} diff --git a/glib/tests/time-zones/Amsterdam-fat b/glib/tests/time-zones/Amsterdam-fat new file mode 100644 index 0000000000000000000000000000000000000000..c3ff07b436aedf662eae60f50668f5abcdb172b6 GIT binary patch literal 2910 zcmWHE%1kq2zyQ1q3=AL)lGp-eD>g7NFwExBdo%m$wU{|Kcks+zvY%((a#f!B)5Ule zOmOU3SoVWwQGs&L;;>shO9EJXmYVJ1S*9A@vt0dP&x*LmJuBH4_pE#u#k1;pYtI_> zM?7ner}wOVo5r(lxo6M%b2EE3v}^Zl+$h(xslbD0^Q0i2Edg3QTZ>zJwi)p7Y!BJV zvxEN~&rXMmo}KS6@a&c-?Ad+eP0ya6OL_M0IM=i9){UP1GdA=b*c;n(uwqirq2;H0 z4&8~3IUG?^aHRf7!BLB_f@2BaKO9#q`f$Q!Q^1+$-U4S=icdJV$XVe0Bol!PO{xMH zi^K#j`8iDBU6MS3uUkrhzr}TeK#AD|!4&lgLLm|pgneBEM2vq;5LJFXK}`701aaoG z6U0C7n;`Lc{RGL&3noY%o;X2z&t3tUHR}Xq=gb$7>zN=RU(+a{kW(a}7?UiZu1&gwit{j13Yji;&;G_Q(H&^pRKL3_)O2|7z&PSBllYl2?O z=?VHJdnOp9tes#OdsD!uXp4Zc?QQ{+plJf8vU3H@j4A}o{?-dvNKctyaW_%G@^{$; ztG&(w*0&=j*er{mV7uFDf?b>A1pC=C6CBc%CpflP3OKp3PH;|<7I0C0KEc)buYeot z$qDYt_XXVFJrnR`J}BUM?u3BXsAT)oY_CYx35RQZ_UC9{&{%<0X@wV0>ir| z1m&bo2sY1|5aQ!LAynLNLYR)`gs|@h6Cy<21R|~rO^E!eArQ6g%Y^8wTmmr*1O;NZ zyb*}2|11zc<(xo5{8fR(+E){j?6(Uf$DWyxB0p0g)pp&4G>)wk(q$)1NPjVXLdM^s z37ID7mf&2zPmZ0YQr*t>T|m%)XY3Ip?2Ne33ZiACe-)UPhetX zVrC%{va_&p<&229_zHOewU4kp;}=U|>LIvut4CVPFtCz$gSG`2-jw z7#L&}7-djNkhqU;2!mg62!o?<2!pnPfsp}&wt=CM0fVz^2!pe0a0tjIMn*fM`%b0-`~M35W(2C?FbCsDNlt!2+T|g$sxV z6)+$gRLFp6P(cHtL4^&71{F9U8dT_jXi&ieqCtfZn0^<<1EN8N5Qqj9L}2=OdJl*O z6-Xc&R49RHP{9PEL4^~D1{F{s8dOMuXiz}~qCtffhz1o{AR1I?foM>{1)@QP7l;NG zU|{dB4Jx=nv|;Q`0T2x;z(F*q5C_qqf*eGH3Ud$*D$v37-+HimP{9u3g9>*L4JzP4 zG^mgV(V&7JM1u-@5DhBuK{Tk)2hpH{A4G!+e-I6-06;XT5&+SliU34|DgzJ=st`al zs8RsYpo#%Zzk3FD52%6w@j;aYhz3;@AR1IzfM`&K0ir>b28ae#93UE0d4On81p=Z$ zl?aFiRU{x9RGENiP=x}bL6r)K230Iz`nv%*K0p-=h!3h{Ks2bL0nwn!21J7@91snv zbU-wy;sMd1$_GS)Dj*OIs)Rr^s3HQWe1``6&{ENReB&ARPljmP~``rK@}i~233L} jdbA>>up;Dgb`8-r1l5*0zQ%f{dImbah6W&7-ufap0l zckqDdxl8tg>3Pdl!Swv;Vqki~1jinb{KB#yVE&>4WiWqn*ex)BNdPODztn6Gn7>Rl z8q8m=eh^HrhQ+5(1@qUaKLYdD98U-H*S<{y^Vco+1oPLQn+c{j zv}=RujT_~_^riw2u)58Yg242a04*@RwHRXVHUl0oe|yMIFujBS9hlzfPyyDz^Zf-d zf44*-n7{kR8!)}+=Tflv-W}(_{C&4>fa(1+Hh}2^dt<@$!HP*>`q1*z5c*CmI6MzW zloWu%>qz|(Fn!b_3``$O`2GPTeq6B#OrLPs6aeC%dG0L$qR*}rp8%rIEpi6)&rdP| z(-)dl!Sux6{&|-qgK55QDFG0lzr_{I7br0U(}F4LU|J|d0!$10x`5S* z82`ehCM&cn0 zGYGP=k^~tTSf+p?Lud&j3z*Hpz`(MBfro)X=m4V-0|TD`g9HPEi~^&Kk8cQrUvLP6 zqi+a0fV-Ip^*WDvug;0vukh&1DCUFh^`@sspD&`XR2qQ<7;RDqV +#ifdef G_OS_UNIX +#include +#endif + +static GMainLoop *loop; + +static gboolean +stop_waiting (gpointer data) +{ + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static gboolean +unreachable_callback (gpointer data) +{ + g_assert_not_reached (); + + return G_SOURCE_REMOVE; +} + +static void +test_seconds (void) +{ + guint id; + + /* Bug 642052 mentions that g_timeout_add_seconds(21475) schedules a + * job that runs once per second. + * + * Test that that isn't true anymore by scheduling two jobs: + * - one, as above + * - another that runs in 2100ms + * + * If everything is working properly, the 2100ms one should run first + * (and exit the mainloop). If we ever see the 21475 second job run + * then we have trouble (since it ran in less than 2 seconds). + * + * We need a timeout of at least 2 seconds because + * g_timeout_add_seconds() can add as much as an additional second of + * latency. + */ + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642052"); + loop = g_main_loop_new (NULL, FALSE); + + g_timeout_add (2100, stop_waiting, NULL); + id = g_timeout_add_seconds (21475, unreachable_callback, NULL); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_source_remove (id); +} + +static void +test_weeks_overflow (void) +{ + guint id; + guint interval_seconds; + + /* Internally, the guint interval (in seconds) was converted to milliseconds + * then stored in a guint variable. This meant that any interval larger than + * G_MAXUINT / 1000 would overflow. + * + * On a system with 32-bit guint, the interval (G_MAXUINT / 1000) + 1 seconds + * (49.7 days) would end wrapping to 704 milliseconds. + * + * Test that that isn't true anymore by scheduling two jobs: + * - one, as above + * - another that runs in 2100ms + * + * If everything is working properly, the 2100ms one should run first + * (and exit the mainloop). If we ever see the other job run + * then we have trouble (since it ran in less than 2 seconds). + * + * We need a timeout of at least 2 seconds because + * g_timeout_add_seconds() can add as much as an additional second of + * latency. + */ + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1600"); + loop = g_main_loop_new (NULL, FALSE); + + g_timeout_add (2100, stop_waiting, NULL); + interval_seconds = 1 + G_MAXUINT / 1000; + id = g_timeout_add_seconds (interval_seconds, unreachable_callback, NULL); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_source_remove (id); +} + +/* The ready_time for a GSource is stored as a gint64, as an absolute monotonic + * time in microseconds. To call poll(), this must be converted to a relative + * timeout, in milliseconds, as a gint. If the ready_time is sufficiently far + * in the future, the timeout will not fit. Previously, it would be narrowed in + * an implementation-defined way; if this gave a negative result, poll() would + * block forever. + * + * This test creates a GSource with the largest possible ready_time (a little + * over 292 millennia, assuming g_get_monotonic_time() starts from near 0 when + * the system boots), adds it to a GMainContext, queries it for the parameters + * to pass to poll() -- essentially the first half of + * g_main_context_iteration() -- and checks that the timeout is a large + * positive number. + */ +static void +test_far_future_ready_time (void) +{ + GSourceFuncs source_funcs = { 0 }; + GMainContext *context = g_main_context_new (); + GSource *source = g_source_new (&source_funcs, sizeof (GSource)); + gboolean acquired, ready; + gint priority, timeout_, n_fds; + + g_source_set_ready_time (source, G_MAXINT64); + g_source_attach (source, context); + + acquired = g_main_context_acquire (context); + g_assert_true (acquired); + + ready = g_main_context_prepare (context, &priority); + g_assert_false (ready); + + n_fds = 0; + n_fds = g_main_context_query (context, priority, &timeout_, NULL, n_fds); + + g_assert_cmpint (n_fds, >=, 0); + + /* The true timeout in milliseconds doesn't fit into a gint. We definitely + * don't want poll() to block forever: + */ + g_assert_cmpint (timeout_, >=, 0); + /* Instead, we want it to block for as long as possible: */ + g_assert_cmpint (timeout_, ==, G_MAXINT); + + g_main_context_release (context); + g_main_context_unref (context); + g_source_unref (source); +} + +static gint64 last_time; +static gint count; + +static gboolean +test_func (gpointer data) +{ + gint64 current_time; + + current_time = g_get_monotonic_time (); + + /* We accept 2 on the first iteration because _add_seconds() can + * have an initial latency of 1 second, see its documentation. + * + * Allow up to 500ms leeway for rounding and scheduling. + */ + if (count == 0) + g_assert_cmpint (current_time / 1000 - last_time / 1000, <=, 2500); + else + g_assert_cmpint (current_time / 1000 - last_time / 1000, <=, 1500); + + last_time = current_time; + count++; + + /* Make the timeout take up to 0.1 seconds. + * We should still get scheduled for the next second. + */ + g_usleep (count * 10000); + + if (count < 10) + return TRUE; + + g_main_loop_quit (loop); + + return FALSE; +} + +static void +test_rounding (void) +{ + loop = g_main_loop_new (NULL, FALSE); + + last_time = g_get_monotonic_time (); + g_timeout_add_seconds (1, test_func, NULL); + + g_main_loop_run (loop); + g_main_loop_unref (loop); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/timeout/seconds", test_seconds); + g_test_add_func ("/timeout/weeks-overflow", test_weeks_overflow); + g_test_add_func ("/timeout/far-future-ready-time", test_far_future_ready_time); + g_test_add_func ("/timeout/rounding", test_rounding); + + return g_test_run (); +} diff --git a/glib/tests/timer.c b/glib/tests/timer.c new file mode 100644 index 0000000..42ed5a9 --- /dev/null +++ b/glib/tests/timer.c @@ -0,0 +1,363 @@ +/* Unit tests for GTimer + * Copyright (C) 2013 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Matthias Clasen + */ + +/* We test a few deprecated APIs here. */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS 1 + +#include "glib.h" + +static void +test_timer_basic (void) +{ + GTimer *timer; + gdouble elapsed; + gulong micros; + + timer = g_timer_new (); + + g_timer_start (timer); + elapsed = g_timer_elapsed (timer, NULL); + g_timer_stop (timer); + g_assert_cmpfloat (elapsed, <=, g_timer_elapsed (timer, NULL)); + + g_timer_destroy (timer); + + timer = g_timer_new (); + + g_timer_start (timer); + elapsed = g_timer_elapsed (timer, NULL); + g_timer_stop (timer); + g_assert_cmpfloat (elapsed, <=, g_timer_elapsed (timer, NULL)); + + g_timer_destroy (timer); + + timer = g_timer_new (); + + elapsed = g_timer_elapsed (timer, µs); + + g_assert_cmpfloat (elapsed, <, 1.0); + g_assert_cmpfloat_with_epsilon (elapsed, micros / 1e6, 0.001); + + g_timer_destroy (timer); +} + +static void +test_timer_stop (void) +{ + GTimer *timer; + gdouble elapsed, elapsed2; + + timer = g_timer_new (); + + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_usleep (100); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, ==, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timer_continue (void) +{ + GTimer *timer; + gdouble elapsed, elapsed2; + + timer = g_timer_new (); + + /* Continue on a running timer */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*== FALSE*"); + g_timer_continue (timer); + g_test_assert_expected_messages (); + } + + g_timer_reset (timer); + + /* Continue on a stopped timer */ + g_usleep (100); + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_timer_continue (timer); + g_usleep (100); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, <, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timer_reset (void) +{ + GTimer *timer; + gdouble elapsed, elapsed2; + + timer = g_timer_new (); + g_usleep (100); + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_timer_reset (timer); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, >, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timer_is_active (void) +{ + GTimer *timer; + gboolean is_active; + + timer = g_timer_new (); + is_active = g_timer_is_active (timer); + g_assert_true (is_active); + g_timer_stop (timer); + is_active = g_timer_is_active (timer); + g_assert_false (is_active); + + g_timer_destroy (timer); +} + +static void +test_timeval_add (void) +{ + GTimeVal time = { 1, 0 }; + + g_time_val_add (&time, 10); + + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 10); + + g_time_val_add (&time, -500); + g_assert_cmpint (time.tv_sec, ==, 0); + g_assert_cmpint (time.tv_usec, ==, G_USEC_PER_SEC - 490); + + g_time_val_add (&time, 1000); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 510); + + g_time_val_add (&time, 0); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 510); + + g_time_val_add (&time, -210); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 300); +} + +typedef struct { + gboolean success; + const gchar *in; + GTimeVal val; +} TimeValParseTest; + +static void +test_timeval_from_iso8601 (void) +{ + gchar *old_tz = g_strdup (g_getenv ("TZ")); + TimeValParseTest tests[] = { + { TRUE, "1990-11-01T10:21:17Z", { 657454877, 0 } }, + { TRUE, "19901101T102117Z", { 657454877, 0 } }, + { TRUE, "19901101T102117+5", { 657454577, 0 } }, + { TRUE, "19901101T102117+3:15", { 657443177, 0 } }, + { TRUE, " 1990-11-01T10:21:17Z ", { 657454877, 0 } }, + { TRUE, "1970-01-01T00:00:17.12Z", { 17, 120000 } }, + { TRUE, "1970-01-01T00:00:17.1234Z", { 17, 123400 } }, + { TRUE, "1970-01-01T00:00:17.123456Z", { 17, 123456 } }, + { TRUE, "1980-02-22T12:36:00+02:00", { 320063760, 0 } }, + { TRUE, "1980-02-22T10:36:00Z", { 320063760, 0 } }, + { TRUE, "1980-02-22T10:36:00", { 320063760, 0 } }, + { TRUE, "1980-02-22T12:36:00+02:00", { 320063760, 0 } }, + { TRUE, "19800222T053600-0500", { 320063760, 0 } }, + { TRUE, "1980-02-22T07:06:00-03:30", { 320063760, 0 } }, + { TRUE, "1980-02-22T10:36:00.050000Z", { 320063760, 50000 } }, + { TRUE, "1980-02-22T05:36:00,05-05:00", { 320063760, 50000 } }, + { TRUE, "19800222T123600.050000000+0200", { 320063760, 50000 } }, + { TRUE, "19800222T070600,0500-0330", { 320063760, 50000 } }, + { FALSE, " ", { 0, 0 } }, + { FALSE, "x", { 0, 0 } }, + { FALSE, "123x", { 0, 0 } }, + { FALSE, "2001-10+x", { 0, 0 } }, + { FALSE, "1980-02-22", { 0, 0 } }, + { FALSE, "1980-02-22T", { 0, 0 } }, + { FALSE, "2001-10-08Tx", { 0, 0 } }, + { FALSE, "2001-10-08T10:11x", { 0, 0 } }, + { FALSE, "Wed Dec 19 17:20:20 GMT 2007", { 0, 0 } }, + { FALSE, "1980-02-22T10:36:00Zulu", { 0, 0 } }, + { FALSE, "2T0+819855292164632335", { 0, 0 } }, + { FALSE, "1980-02-22", { 320063760, 50000 } }, + { TRUE, "2018-08-03T14:08:05.446178377+01:00", { 1533301685, 446178 } }, + { FALSE, "2147483648-08-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-13-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-00-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-00T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-32T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T24:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:60:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:63.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:05.446178377+100:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:05.446178377+01:60", { 0, 0 } }, + { TRUE, "20180803T140805.446178377+0100", { 1533301685, 446178 } }, + { FALSE, "21474836480803T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20181303T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180003T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180800T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180832T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T240805.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T146005.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T140863.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T140805.446178377+10000", { 0, 0 } }, + { FALSE, "20180803T140805.446178377+0160", { 0, 0 } }, + { TRUE, "+1980-02-22T12:36:00+02:00", { 320063760, 0 } }, + { FALSE, "-0005-01-01T00:00:00Z", { 0, 0 } }, + { FALSE, "2018-08-06", { 0, 0 } }, + { FALSE, "2018-08-06 13:51:00Z", { 0, 0 } }, + { TRUE, "20180803T140805,446178377+0100", { 1533301685, 446178 } }, + { TRUE, "2018-08-03T14:08:05.446178377-01:00", { 1533308885, 446178 } }, + { FALSE, "2018-08-03T14:08:05.446178377 01:00", { 0, 0 } }, + { TRUE, "1990-11-01T10:21:17", { 657454877, 0 } }, + { TRUE, "1990-11-01T10:21:17 ", { 657454877, 0 } }, + }; + GTimeVal out; + gboolean success; + gsize i; + + /* Always run in UTC so the comparisons of parsed values are valid. */ + if (!g_setenv ("TZ", "UTC", TRUE)) + { + g_test_skip ("Failed to set TZ=UTC"); + return; + } + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + out.tv_sec = 0; + out.tv_usec = 0; + success = g_time_val_from_iso8601 (tests[i].in, &out); + g_assert_cmpint (success, ==, tests[i].success); + if (tests[i].success) + { + g_assert_cmpint (out.tv_sec, ==, tests[i].val.tv_sec); + g_assert_cmpint (out.tv_usec, ==, tests[i].val.tv_usec); + } + } + + /* revert back user defined time zone */ + if (old_tz != NULL) + g_assert_true (g_setenv ("TZ", old_tz, TRUE)); + else + g_unsetenv ("TZ"); + tzset (); + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + out.tv_sec = 0; + out.tv_usec = 0; + success = g_time_val_from_iso8601 (tests[i].in, &out); + g_assert_cmpint (success, ==, tests[i].success); + } + + g_free (old_tz); +} + +typedef struct { + GTimeVal val; + const gchar *expected; +} TimeValFormatTest; + +static void +test_timeval_to_iso8601 (void) +{ + TimeValFormatTest tests[] = { + { { 657454877, 0 }, "1990-11-01T10:21:17Z" }, + { { 17, 123400 }, "1970-01-01T00:00:17.123400Z" } + }; + gsize i; + gchar *out; + GTimeVal val; + gboolean ret; + + g_unsetenv ("TZ"); + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + out = g_time_val_to_iso8601 (&(tests[i].val)); + g_assert_cmpstr (out, ==, tests[i].expected); + + ret = g_time_val_from_iso8601 (out, &val); + g_assert (ret); + g_assert_cmpint (val.tv_sec, ==, tests[i].val.tv_sec); + g_assert_cmpint (val.tv_usec, ==, tests[i].val.tv_usec); + g_free (out); + } +} + +/* Test error handling for g_time_val_to_iso8601() on dates which are too large. */ +static void +test_timeval_to_iso8601_overflow (void) +{ + GTimeVal val; + gchar *out = NULL; + + if ((glong) G_MAXINT == G_MAXLONG) + { + g_test_skip ("G_MAXINT == G_MAXLONG - we can't make g_time_val_to_iso8601() overflow."); + return; + } + + g_unsetenv ("TZ"); + + val.tv_sec = G_MAXLONG; + val.tv_usec = G_USEC_PER_SEC - 1; + + out = g_time_val_to_iso8601 (&val); + g_assert_null (out); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/timer/basic", test_timer_basic); + g_test_add_func ("/timer/stop", test_timer_stop); + g_test_add_func ("/timer/continue", test_timer_continue); + g_test_add_func ("/timer/reset", test_timer_reset); + g_test_add_func ("/timer/is_active", test_timer_is_active); + g_test_add_func ("/timeval/add", test_timeval_add); + g_test_add_func ("/timeval/from-iso8601", test_timeval_from_iso8601); + g_test_add_func ("/timeval/to-iso8601", test_timeval_to_iso8601); + g_test_add_func ("/timeval/to-iso8601/overflow", test_timeval_to_iso8601_overflow); + + return g_test_run (); +} diff --git a/glib/tests/tree.c b/glib/tests/tree.c new file mode 100644 index 0000000..e882926 --- /dev/null +++ b/glib/tests/tree.c @@ -0,0 +1,728 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include +#include +#include "glib.h" + + +static gint +my_compare (gconstpointer a, + gconstpointer b) +{ + const char *cha = a; + const char *chb = b; + + return *cha - *chb; +} + +static gint +my_compare_with_data (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + const char *cha = a; + const char *chb = b; + + /* just check that we got the right data */ + g_assert (GPOINTER_TO_INT(user_data) == 123); + + return *cha - *chb; +} + +static gint +my_search (gconstpointer a, + gconstpointer b) +{ + return my_compare (b, a); +} + +static gpointer destroyed_key = NULL; +static gpointer destroyed_value = NULL; +static guint destroyed_key_count = 0; +static guint destroyed_value_count = 0; + +static void +my_key_destroy (gpointer key) +{ + destroyed_key = key; + destroyed_key_count++; +} + +static void +my_value_destroy (gpointer value) +{ + destroyed_value = value; + destroyed_value_count++; +} + +static gint +my_traverse (gpointer key, + gpointer value, + gpointer data) +{ + char *ch = key; + + g_assert ((*ch) > 0); + + if (*ch == 'd') + return TRUE; + + return FALSE; +} + +char chars[] = + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + +char chars2[] = + "0123456789" + "abcdefghijklmnopqrstuvwxyz"; + +static gint +check_order (gpointer key, + gpointer value, + gpointer data) +{ + char **p = data; + char *ch = key; + + g_assert (**p == *ch); + + (*p)++; + + return FALSE; +} + +static void +test_tree_search (void) +{ + gint i; + GTree *tree; + gboolean removed; + gchar c; + gchar *p, *d; + + tree = g_tree_new_with_data (my_compare_with_data, GINT_TO_POINTER(123)); + + for (i = 0; chars[i]; i++) + g_tree_insert (tree, &chars[i], &chars[i]); + + g_tree_foreach (tree, my_traverse, NULL); + + g_assert_cmpint (g_tree_nnodes (tree), ==, strlen (chars)); + g_assert_cmpint (g_tree_height (tree), ==, 6); + + p = chars; + g_tree_foreach (tree, check_order, &p); + + for (i = 0; i < 26; i++) + { + removed = g_tree_remove (tree, &chars[i + 10]); + g_assert (removed); + } + + c = '\0'; + removed = g_tree_remove (tree, &c); + g_assert (!removed); + + g_tree_foreach (tree, my_traverse, NULL); + + g_assert_cmpint (g_tree_nnodes (tree), ==, strlen (chars2)); + g_assert_cmpint (g_tree_height (tree), ==, 6); + + p = chars2; + g_tree_foreach (tree, check_order, &p); + + for (i = 25; i >= 0; i--) + g_tree_insert (tree, &chars[i + 10], &chars[i + 10]); + + p = chars; + g_tree_foreach (tree, check_order, &p); + + c = '0'; + p = g_tree_lookup (tree, &c); + g_assert (p && *p == c); + g_assert (g_tree_lookup_extended (tree, &c, (gpointer *)&d, (gpointer *)&p)); + g_assert (c == *d && c == *p); + + c = 'A'; + p = g_tree_lookup (tree, &c); + g_assert (p && *p == c); + + c = 'a'; + p = g_tree_lookup (tree, &c); + g_assert (p && *p == c); + + c = 'z'; + p = g_tree_lookup (tree, &c); + g_assert (p && *p == c); + + c = '!'; + p = g_tree_lookup (tree, &c); + g_assert (p == NULL); + + c = '='; + p = g_tree_lookup (tree, &c); + g_assert (p == NULL); + + c = '|'; + p = g_tree_lookup (tree, &c); + g_assert (p == NULL); + + c = '0'; + p = g_tree_search (tree, my_search, &c); + g_assert (p && *p == c); + + c = 'A'; + p = g_tree_search (tree, my_search, &c); + g_assert (p && *p == c); + + c = 'a'; + p = g_tree_search (tree, my_search, &c); + g_assert (p &&*p == c); + + c = 'z'; + p = g_tree_search (tree, my_search, &c); + g_assert (p && *p == c); + + c = '!'; + p = g_tree_search (tree, my_search, &c); + g_assert (p == NULL); + + c = '='; + p = g_tree_search (tree, my_search, &c); + g_assert (p == NULL); + + c = '|'; + p = g_tree_search (tree, my_search, &c); + g_assert (p == NULL); + + g_tree_destroy (tree); +} + +static void +test_tree_remove (void) +{ + GTree *tree; + char c, d; + gint i; + gboolean removed; + gchar *remove; + + tree = g_tree_new_full ((GCompareDataFunc)my_compare, NULL, + my_key_destroy, + my_value_destroy); + + for (i = 0; chars[i]; i++) + g_tree_insert (tree, &chars[i], &chars[i]); + + c = '0'; + g_tree_insert (tree, &c, &c); + g_assert (destroyed_key == &c); + g_assert (destroyed_value == &chars[0]); + destroyed_key = NULL; + destroyed_value = NULL; + + d = '1'; + g_tree_replace (tree, &d, &d); + g_assert (destroyed_key == &chars[1]); + g_assert (destroyed_value == &chars[1]); + destroyed_key = NULL; + destroyed_value = NULL; + + c = '2'; + removed = g_tree_remove (tree, &c); + g_assert (removed); + g_assert (destroyed_key == &chars[2]); + g_assert (destroyed_value == &chars[2]); + destroyed_key = NULL; + destroyed_value = NULL; + + c = '3'; + removed = g_tree_steal (tree, &c); + g_assert (removed); + g_assert (destroyed_key == NULL); + g_assert (destroyed_value == NULL); + + remove = "omkjigfedba"; + for (i = 0; remove[i]; i++) + { + removed = g_tree_remove (tree, &remove[i]); + g_assert (removed); + } + + g_tree_destroy (tree); +} + +static void +test_tree_remove_all (void) +{ + GTree *tree; + gsize i; + + tree = g_tree_new_full ((GCompareDataFunc)my_compare, NULL, + my_key_destroy, + my_value_destroy); + + for (i = 0; chars[i]; i++) + g_tree_insert (tree, &chars[i], &chars[i]); + + destroyed_key_count = 0; + destroyed_value_count = 0; + + g_tree_remove_all (tree); + + g_assert_cmpuint (destroyed_key_count, ==, strlen (chars)); + g_assert_cmpuint (destroyed_value_count, ==, strlen (chars)); + g_assert_cmpint (g_tree_height (tree), ==, 0); + g_assert_cmpint (g_tree_nnodes (tree), ==, 0); + + g_tree_unref (tree); +} + +static void +test_tree_destroy (void) +{ + GTree *tree; + gint i; + + tree = g_tree_new (my_compare); + + for (i = 0; chars[i]; i++) + g_tree_insert (tree, &chars[i], &chars[i]); + + g_assert_cmpint (g_tree_nnodes (tree), ==, strlen (chars)); + + g_tree_ref (tree); + g_tree_destroy (tree); + + g_assert_cmpint (g_tree_nnodes (tree), ==, 0); + + g_tree_unref (tree); +} + +typedef struct { + GString *s; + gint count; +} CallbackData; + +static gboolean +traverse_func (gpointer key, gpointer value, gpointer data) +{ + CallbackData *d = data; + + gchar *c = value; + g_string_append_c (d->s, *c); + + d->count--; + + if (d->count == 0) + return TRUE; + + return FALSE; +} + +typedef struct { + GTraverseType traverse; + gint limit; + const gchar *expected; +} TraverseData; + +static void +test_tree_traverse (void) +{ + GTree *tree; + gsize i; + TraverseData orders[] = { + { G_IN_ORDER, -1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" }, + { G_IN_ORDER, 1, "0" }, + { G_IN_ORDER, 2, "01" }, + { G_IN_ORDER, 3, "012" }, + { G_IN_ORDER, 4, "0123" }, + { G_IN_ORDER, 5, "01234" }, + { G_IN_ORDER, 6, "012345" }, + { G_IN_ORDER, 7, "0123456" }, + { G_IN_ORDER, 8, "01234567" }, + { G_IN_ORDER, 9, "012345678" }, + { G_IN_ORDER, 10, "0123456789" }, + { G_IN_ORDER, 11, "0123456789A" }, + { G_IN_ORDER, 12, "0123456789AB" }, + { G_IN_ORDER, 13, "0123456789ABC" }, + { G_IN_ORDER, 14, "0123456789ABCD" }, + + { G_PRE_ORDER, -1, "VF73102546B98ADCENJHGILKMRPOQTSUldZXWYbachfegjiktpnmorqsxvuwyz" }, + { G_PRE_ORDER, 1, "V" }, + { G_PRE_ORDER, 2, "VF" }, + { G_PRE_ORDER, 3, "VF7" }, + { G_PRE_ORDER, 4, "VF73" }, + { G_PRE_ORDER, 5, "VF731" }, + { G_PRE_ORDER, 6, "VF7310" }, + { G_PRE_ORDER, 7, "VF73102" }, + { G_PRE_ORDER, 8, "VF731025" }, + { G_PRE_ORDER, 9, "VF7310254" }, + { G_PRE_ORDER, 10, "VF73102546" }, + { G_PRE_ORDER, 11, "VF73102546B" }, + { G_PRE_ORDER, 12, "VF73102546B9" }, + { G_PRE_ORDER, 13, "VF73102546B98" }, + { G_PRE_ORDER, 14, "VF73102546B98A" }, + + { G_POST_ORDER, -1, "02146538A9CEDB7GIHKMLJOQPSUTRNFWYXacbZegfikjhdmonqsrpuwvzyxtlV" }, + { G_POST_ORDER, 1, "0" }, + { G_POST_ORDER, 2, "02" }, + { G_POST_ORDER, 3, "021" }, + { G_POST_ORDER, 4, "0214" }, + { G_POST_ORDER, 5, "02146" }, + { G_POST_ORDER, 6, "021465" }, + { G_POST_ORDER, 7, "0214653" }, + { G_POST_ORDER, 8, "02146538" }, + { G_POST_ORDER, 9, "02146538A" }, + { G_POST_ORDER, 10, "02146538A9" }, + { G_POST_ORDER, 11, "02146538A9C" }, + { G_POST_ORDER, 12, "02146538A9CE" }, + { G_POST_ORDER, 13, "02146538A9CED" }, + { G_POST_ORDER, 14, "02146538A9CEDB" } + }; + CallbackData data; + + tree = g_tree_new (my_compare); + + for (i = 0; chars[i]; i++) + g_tree_insert (tree, &chars[i], &chars[i]); + + data.s = g_string_new (""); + for (i = 0; i < G_N_ELEMENTS (orders); i++) + { + g_string_set_size (data.s, 0); + data.count = orders[i].limit; + g_tree_traverse (tree, traverse_func, orders[i].traverse, &data); + g_assert_cmpstr (data.s->str, ==, orders[i].expected); + } + + g_tree_unref (tree); + g_string_free (data.s, TRUE); +} + +static void +test_tree_insert (void) +{ + GTree *tree; + gchar *p; + gint i; + gchar *scrambled; + + tree = g_tree_new (my_compare); + + for (i = 0; chars[i]; i++) + g_tree_insert (tree, &chars[i], &chars[i]); + p = chars; + g_tree_foreach (tree, check_order, &p); + + g_tree_unref (tree); + tree = g_tree_new (my_compare); + + for (i = strlen (chars) - 1; i >= 0; i--) + g_tree_insert (tree, &chars[i], &chars[i]); + p = chars; + g_tree_foreach (tree, check_order, &p); + + g_tree_unref (tree); + tree = g_tree_new (my_compare); + + scrambled = g_strdup (chars); + + for (i = 0; i < 30; i++) + { + gchar tmp; + gint a, b; + + a = g_random_int_range (0, strlen (scrambled)); + b = g_random_int_range (0, strlen (scrambled)); + tmp = scrambled[a]; + scrambled[a] = scrambled[b]; + scrambled[b] = tmp; + } + + for (i = 0; scrambled[i]; i++) + g_tree_insert (tree, &scrambled[i], &scrambled[i]); + p = chars; + g_tree_foreach (tree, check_order, &p); + + g_free (scrambled); + g_tree_unref (tree); +} + +static void +binary_tree_bound (GTree *tree, + char c, + char expected, + int lower) +{ + GTreeNode *node; + + if (lower) + node = g_tree_lower_bound (tree, &c); + else + node = g_tree_upper_bound (tree, &c); + + if (g_test_verbose ()) + g_test_message ("%c %s: ", c, lower ? "lower" : "upper"); + + if (!node) + { + if (!g_tree_nnodes (tree)) + { + if (g_test_verbose ()) + g_test_message ("empty tree"); + } + else + { + GTreeNode *last = g_tree_node_last (tree); + + g_assert (last); + if (g_test_verbose ()) + g_test_message ("past end last %c", + *(char *) g_tree_node_key (last)); + } + g_assert (expected == '\x00'); + } + else + { + GTreeNode *begin = g_tree_node_first (tree); + GTreeNode *last = g_tree_node_last (tree); + GTreeNode *prev = g_tree_node_previous (node); + GTreeNode *next = g_tree_node_next (node); + + g_assert (expected != '\x00'); + g_assert (expected == *(char *) g_tree_node_key (node)); + + if (g_test_verbose ()) + g_test_message ("%c", *(char *) g_tree_node_key (node)); + + if (node != begin) + { + g_assert (prev); + if (g_test_verbose ()) + g_test_message (" prev %c", *(char *) g_tree_node_key (prev)); + } + else + { + g_assert (!prev); + if (g_test_verbose ()) + g_test_message (" no prev, it's the first one"); + } + + if (node != last) + { + g_assert (next); + if (g_test_verbose ()) + g_test_message (" next %c", *(char *) g_tree_node_key (next)); + } + else + { + g_assert (!next); + if (g_test_verbose ()) + g_test_message (" no next, it's the last one"); + } + } + + if (g_test_verbose ()) + g_test_message ("\n"); +} + +static void +binary_tree_bounds (GTree *tree, + char c, + int mode) +{ + char expectedl, expectedu; + char first = mode == 0 ? '0' : mode == 1 ? 'A' : 'z'; + + g_assert (mode >= 0 && mode <= 3); + + if (c < first) + expectedl = first; + else if (c > 'z') + expectedl = '\x00'; + else + expectedl = c; + + if (c < first) + expectedu = first; + else if (c >= 'z') + expectedu = '\x00'; + else + expectedu = c == '9' ? 'A' : c == 'Z' ? 'a' : c + 1; + + if (mode == 3) + { + expectedl = '\x00'; + expectedu = '\x00'; + } + + binary_tree_bound (tree, c, expectedl, 1); + binary_tree_bound (tree, c, expectedu, 0); +} + +static void +binary_tree_bounds_test (GTree *tree, + int mode) +{ + binary_tree_bounds (tree, 'a', mode); + binary_tree_bounds (tree, 'A', mode); + binary_tree_bounds (tree, 'z', mode); + binary_tree_bounds (tree, 'Z', mode); + binary_tree_bounds (tree, 'Y', mode); + binary_tree_bounds (tree, '0', mode); + binary_tree_bounds (tree, '9', mode); + binary_tree_bounds (tree, '0' - 1, mode); + binary_tree_bounds (tree, 'z' + 1, mode); + binary_tree_bounds (tree, '0' - 2, mode); + binary_tree_bounds (tree, 'z' + 2, mode); +} + +static void +test_tree_bounds (void) +{ + GQueue queue = G_QUEUE_INIT; + GTree *tree; + char chars[62]; + guint i, j; + + tree = g_tree_new (my_compare); + + i = 0; + for (j = 0; j < 10; j++, i++) + { + chars[i] = '0' + j; + g_queue_push_tail (&queue, &chars[i]); + } + + for (j = 0; j < 26; j++, i++) + { + chars[i] = 'A' + j; + g_queue_push_tail (&queue, &chars[i]); + } + + for (j = 0; j < 26; j++, i++) + { + chars[i] = 'a' + j; + g_queue_push_tail (&queue, &chars[i]); + } + + if (g_test_verbose ()) + g_test_message ("tree insert: "); + + while (!g_queue_is_empty (&queue)) + { + gint32 which = g_random_int_range (0, g_queue_get_length (&queue)); + gpointer elem = g_queue_pop_nth (&queue, which); + GTreeNode *node; + + if (g_test_verbose ()) + g_test_message ("%c ", *(char *) elem); + + node = g_tree_insert_node (tree, elem, elem); + g_assert (g_tree_node_key (node) == elem); + g_assert (g_tree_node_value (node) == elem); + } + + if (g_test_verbose ()) + g_test_message ("\n"); + + g_assert_cmpint (g_tree_nnodes (tree), ==, 10 + 26 + 26); + g_assert_cmpint (g_tree_height (tree), >=, 6); + g_assert_cmpint (g_tree_height (tree), <=, 8); + + if (g_test_verbose ()) + { + g_test_message ("tree: "); + g_tree_foreach (tree, my_traverse, NULL); + g_test_message ("\n"); + } + + binary_tree_bounds_test (tree, 0); + + for (i = 0; i < 10; i++) + g_tree_remove (tree, &chars[i]); + + g_assert_cmpint (g_tree_nnodes (tree), ==, 26 + 26); + g_assert_cmpint (g_tree_height (tree), >=, 6); + g_assert_cmpint (g_tree_height (tree), <=, 8); + + if (g_test_verbose ()) + { + g_test_message ("tree: "); + g_tree_foreach (tree, my_traverse, NULL); + g_test_message ("\n"); + } + + binary_tree_bounds_test (tree, 1); + + for (i = 10; i < 10 + 26 + 26 - 1; i++) + g_tree_remove (tree, &chars[i]); + + if (g_test_verbose ()) + { + g_test_message ("tree: "); + g_tree_foreach (tree, my_traverse, NULL); + g_test_message ("\n"); + } + + binary_tree_bounds_test (tree, 2); + + g_tree_remove (tree, &chars[10 + 26 + 26 - 1]); + + if (g_test_verbose ()) + g_test_message ("empty tree\n"); + + binary_tree_bounds_test (tree, 3); + + g_tree_unref (tree); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/tree/search", test_tree_search); + g_test_add_func ("/tree/remove", test_tree_remove); + g_test_add_func ("/tree/destroy", test_tree_destroy); + g_test_add_func ("/tree/traverse", test_tree_traverse); + g_test_add_func ("/tree/insert", test_tree_insert); + g_test_add_func ("/tree/bounds", test_tree_bounds); + g_test_add_func ("/tree/remove-all", test_tree_remove_all); + + return g_test_run (); +} diff --git a/glib/tests/types.c b/glib/tests/types.c new file mode 100644 index 0000000..58eb748 --- /dev/null +++ b/glib/tests/types.c @@ -0,0 +1,154 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include + +#include + +static void +test_basic_types (void) +{ + gchar *string; + gushort gus; + guint gui; + gulong gul; + gsize gsz; + gshort gs; + gint gi; + glong gl; + gint16 gi16t1; + gint16 gi16t2; + gint32 gi32t1; + gint32 gi32t2; + guint16 gu16t1 = 0x44afU, gu16t2 = 0xaf44U; + guint32 gu32t1 = 0x02a7f109U, gu32t2 = 0x09f1a702U; + guint64 gu64t1 = G_GINT64_CONSTANT(0x1d636b02300a7aa7U), + gu64t2 = G_GINT64_CONSTANT(0xa77a0a30026b631dU); + gint64 gi64t1; + gint64 gi64t2; + gssize gsst1; + gssize gsst2; + gsize gst1; + gsize gst2; + + /* type sizes */ + g_assert_cmpint (sizeof (gint8), ==, 1); + g_assert_cmpint (sizeof (gint16), ==, 2); + g_assert_cmpint (sizeof (gint32), ==, 4); + g_assert_cmpint (sizeof (gint64), ==, 8); + + g_assert_cmpuint (GUINT16_SWAP_LE_BE (gu16t1), ==, gu16t2); + g_assert_cmpuint (GUINT32_SWAP_LE_BE (gu32t1), ==, gu32t2); + g_assert_cmpuint (GUINT64_SWAP_LE_BE (gu64t1), ==, gu64t2); + + /* Test the G_(MIN|MAX|MAXU)(SHORT|INT|LONG) macros */ + + gus = G_MAXUSHORT; + gus++; + g_assert_cmpuint (gus, ==, 0); + + gui = G_MAXUINT; + gui++; + g_assert_cmpuint (gui, ==, 0); + + gul = G_MAXULONG; + gul++; + g_assert_cmpuint (gul, ==, 0); + + gsz = G_MAXSIZE; + gsz++; + + g_assert_cmpuint (gsz, ==, 0); + + gs = G_MAXSHORT; + gs = (gshort) (1 + (gushort) gs); + g_assert_cmpint (gs, ==, G_MINSHORT); + + gi = G_MAXINT; + gi = (gint) (1 + (guint) gi); + g_assert_cmpint (gi, ==, G_MININT); + + gl = G_MAXLONG; + gl = (glong) (1 + (gulong) gl); + g_assert_cmpint (gl, ==, G_MINLONG); + + /* Test the G_G(U)?INT(16|32|64)_FORMAT macros */ + + gi16t1 = -0x3AFA; + gu16t1 = 0xFAFA; + gi32t1 = -0x3AFAFAFA; + gu32t1 = 0xFAFAFAFA; + +#define FORMAT "%" G_GINT16_FORMAT " %" G_GINT32_FORMAT \ + " %" G_GUINT16_FORMAT " %" G_GUINT32_FORMAT "\n" + string = g_strdup_printf (FORMAT, gi16t1, gi32t1, gu16t1, gu32t1); + sscanf (string, FORMAT, &gi16t2, &gi32t2, &gu16t2, &gu32t2); + g_free (string); + g_assert_cmpint (gi16t1, ==, gi16t2); + g_assert_cmpint (gi32t1, ==, gi32t2); + g_assert_cmpint (gu16t1, ==, gu16t2); + g_assert_cmpint (gu32t1, ==, gu32t2); + + gi64t1 = G_GINT64_CONSTANT (-0x3AFAFAFAFAFAFAFA); + gu64t1 = G_GINT64_CONSTANT (0xFAFAFAFAFAFAFAFA); + +#define FORMAT64 "%" G_GINT64_FORMAT " %" G_GUINT64_FORMAT "\n" +#ifndef G_OS_WIN32 +# define SCAN_FORMAT64 FORMAT64 +#else +# define sscanf sscanf_s +# define SCAN_FORMAT64 "%I64d %I64u\n" +#endif + string = g_strdup_printf (FORMAT64, gi64t1, gu64t1); + sscanf (string, SCAN_FORMAT64, &gi64t2, &gu64t2); + g_free (string); + g_assert_cmpint (gi64t1, ==, gi64t2); + g_assert_cmpint (gu64t1, ==, gu64t2); + + gsst1 = -0x3AFAFAFA; + gst1 = 0xFAFAFAFA; + +#define FORMATSIZE "%" G_GSSIZE_FORMAT " %" G_GSIZE_FORMAT "\n" +#ifndef G_OS_WIN32 +# define SCAN_FORMATSIZE FORMATSIZE +#else +# define sscanf sscanf_s +# define SCAN_FORMATSIZE "%Id %Iu\n" +#endif + string = g_strdup_printf (FORMATSIZE, gsst1, gst1); + sscanf (string, SCAN_FORMATSIZE, &gsst2, &gst2); + g_free (string); + g_assert_cmpint (gsst1, ==, gsst2); + g_assert_cmpint (gst1, ==, gst2); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/types/basic_types", test_basic_types); + + return g_test_run (); +} diff --git a/glib/tests/unicode.c b/glib/tests/unicode.c new file mode 100644 index 0000000..5ba167e --- /dev/null +++ b/glib/tests/unicode.c @@ -0,0 +1,1858 @@ +/* Unit tests for utilities + * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2011 Google, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Matthias Clasen, Behdad Esfahbod + */ + +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include +#include + +#include "glib.h" + +#include "glib/gunidecomp.h" + +/* Test that g_unichar_validate() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_unichar_validate (void) +{ + g_assert_true (g_unichar_validate ('j')); + g_assert_true (g_unichar_validate (8356)); + g_assert_true (g_unichar_validate (8356)); + g_assert_true (g_unichar_validate (0xFDD1)); + g_assert_true (g_unichar_validate (917760)); + g_assert_false (g_unichar_validate (0x110000)); +} + +/* Test that g_unichar_type() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_unichar_character_type (void) +{ + guint i; + struct { + GUnicodeType type; + gunichar c; + } examples[] = { + { G_UNICODE_CONTROL, 0x000D }, + { G_UNICODE_FORMAT, 0x200E }, + /* G_UNICODE_UNASSIGNED */ + { G_UNICODE_PRIVATE_USE, 0xE000 }, + { G_UNICODE_SURROGATE, 0xD800 }, + { G_UNICODE_LOWERCASE_LETTER, 0x0061 }, + { G_UNICODE_MODIFIER_LETTER, 0x02B0 }, + { G_UNICODE_OTHER_LETTER, 0x3400 }, + { G_UNICODE_TITLECASE_LETTER, 0x01C5 }, + { G_UNICODE_UPPERCASE_LETTER, 0xFF21 }, + { G_UNICODE_SPACING_MARK, 0x0903 }, + { G_UNICODE_ENCLOSING_MARK, 0x20DD }, + { G_UNICODE_NON_SPACING_MARK, 0xA806 }, + { G_UNICODE_DECIMAL_NUMBER, 0xFF10 }, + { G_UNICODE_LETTER_NUMBER, 0x16EE }, + { G_UNICODE_OTHER_NUMBER, 0x17F0 }, + { G_UNICODE_CONNECT_PUNCTUATION, 0x005F }, + { G_UNICODE_DASH_PUNCTUATION, 0x058A }, + { G_UNICODE_CLOSE_PUNCTUATION, 0x0F3B }, + { G_UNICODE_FINAL_PUNCTUATION, 0x2019 }, + { G_UNICODE_INITIAL_PUNCTUATION, 0x2018 }, + { G_UNICODE_OTHER_PUNCTUATION, 0x2016 }, + { G_UNICODE_OPEN_PUNCTUATION, 0x0F3A }, + { G_UNICODE_CURRENCY_SYMBOL, 0x20A0 }, + { G_UNICODE_MODIFIER_SYMBOL, 0x309B }, + { G_UNICODE_MATH_SYMBOL, 0xFB29 }, + { G_UNICODE_OTHER_SYMBOL, 0x00A6 }, + { G_UNICODE_LINE_SEPARATOR, 0x2028 }, + { G_UNICODE_PARAGRAPH_SEPARATOR, 0x2029 }, + { G_UNICODE_SPACE_SEPARATOR, 0x202F }, + }; + + for (i = 0; i < G_N_ELEMENTS (examples); i++) + { + g_assert_cmpint (g_unichar_type (examples[i].c), ==, examples[i].type); + } + + /*** Testing TYPE() border cases ***/ + g_assert_cmpint (g_unichar_type (0x3FF5), ==, 0x07); + /* U+FFEFF Plane 15 Private Use */ + g_assert_cmpint (g_unichar_type (0xFFEFF), ==, 0x03); + /* U+E0001 Language Tag */ + g_assert_cmpint (g_unichar_type (0xE0001), ==, 0x01); + g_assert_cmpint (g_unichar_type (G_UNICODE_LAST_CHAR), ==, 0x02); + g_assert_cmpint (g_unichar_type (G_UNICODE_LAST_CHAR + 1), ==, 0x02); + g_assert_cmpint (g_unichar_type (G_UNICODE_LAST_CHAR_PART1), ==, 0x02); + g_assert_cmpint (g_unichar_type (G_UNICODE_LAST_CHAR_PART1 + 1), ==, 0x02); +} + +/* Test that g_unichar_break_type() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_unichar_break_type (void) +{ + guint i; + struct { + GUnicodeBreakType type; + gunichar c; + } examples[] = { + { G_UNICODE_BREAK_MANDATORY, 0x2028 }, + { G_UNICODE_BREAK_CARRIAGE_RETURN, 0x000D }, + { G_UNICODE_BREAK_LINE_FEED, 0x000A }, + { G_UNICODE_BREAK_COMBINING_MARK, 0x0300 }, + { G_UNICODE_BREAK_SURROGATE, 0xD800 }, + { G_UNICODE_BREAK_ZERO_WIDTH_SPACE, 0x200B }, + { G_UNICODE_BREAK_INSEPARABLE, 0x2024 }, + { G_UNICODE_BREAK_NON_BREAKING_GLUE, 0x00A0 }, + { G_UNICODE_BREAK_CONTINGENT, 0xFFFC }, + { G_UNICODE_BREAK_SPACE, 0x0020 }, + { G_UNICODE_BREAK_AFTER, 0x05BE }, + { G_UNICODE_BREAK_BEFORE, 0x02C8 }, + { G_UNICODE_BREAK_BEFORE_AND_AFTER, 0x2014 }, + { G_UNICODE_BREAK_HYPHEN, 0x002D }, + { G_UNICODE_BREAK_NON_STARTER, 0x17D6 }, + { G_UNICODE_BREAK_OPEN_PUNCTUATION, 0x0028 }, + { G_UNICODE_BREAK_CLOSE_PARENTHESIS, 0x0029 }, + { G_UNICODE_BREAK_CLOSE_PUNCTUATION, 0x007D }, + { G_UNICODE_BREAK_QUOTATION, 0x0022 }, + { G_UNICODE_BREAK_EXCLAMATION, 0x0021 }, + { G_UNICODE_BREAK_IDEOGRAPHIC, 0x2E80 }, + { G_UNICODE_BREAK_NUMERIC, 0x0030 }, + { G_UNICODE_BREAK_INFIX_SEPARATOR, 0x002C }, + { G_UNICODE_BREAK_SYMBOL, 0x002F }, + { G_UNICODE_BREAK_ALPHABETIC, 0x0023 }, + { G_UNICODE_BREAK_PREFIX, 0x0024 }, + { G_UNICODE_BREAK_POSTFIX, 0x0025 }, + { G_UNICODE_BREAK_COMPLEX_CONTEXT, 0x0E01 }, + { G_UNICODE_BREAK_AMBIGUOUS, 0x00F7 }, + { G_UNICODE_BREAK_UNKNOWN, 0xE000 }, + { G_UNICODE_BREAK_NEXT_LINE, 0x0085 }, + { G_UNICODE_BREAK_WORD_JOINER, 0x2060 }, + { G_UNICODE_BREAK_HANGUL_L_JAMO, 0x1100 }, + { G_UNICODE_BREAK_HANGUL_V_JAMO, 0x1160 }, + { G_UNICODE_BREAK_HANGUL_T_JAMO, 0x11A8 }, + { G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, 0xAC00 }, + { G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 0xAC01 }, + { G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, 0x3041 }, + { G_UNICODE_BREAK_HEBREW_LETTER, 0x05D0 }, + { G_UNICODE_BREAK_REGIONAL_INDICATOR, 0x1F1F6 }, + { G_UNICODE_BREAK_EMOJI_BASE, 0x1F466 }, + { G_UNICODE_BREAK_EMOJI_MODIFIER, 0x1F3FB }, + { G_UNICODE_BREAK_ZERO_WIDTH_JOINER, 0x200D }, + }; + + for (i = 0; i < G_N_ELEMENTS (examples); i++) + { + g_assert_cmpint (g_unichar_break_type (examples[i].c), ==, examples[i].type); + } +} + +/* Test that g_unichar_get_script() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_unichar_script (void) +{ + guint i; + struct { + GUnicodeScript script; + gunichar c; + } examples[] = { + { G_UNICODE_SCRIPT_COMMON, 0x002A }, + { G_UNICODE_SCRIPT_INHERITED, 0x1CED }, + { G_UNICODE_SCRIPT_INHERITED, 0x0670 }, + { G_UNICODE_SCRIPT_ARABIC, 0x060D }, + { G_UNICODE_SCRIPT_ARMENIAN, 0x0559 }, + { G_UNICODE_SCRIPT_BENGALI, 0x09CD }, + { G_UNICODE_SCRIPT_BOPOMOFO, 0x31B6 }, + { G_UNICODE_SCRIPT_CHEROKEE, 0x13A2 }, + { G_UNICODE_SCRIPT_COPTIC, 0x2CFD }, + { G_UNICODE_SCRIPT_CYRILLIC, 0x0482 }, + { G_UNICODE_SCRIPT_DESERET, 0x10401 }, + { G_UNICODE_SCRIPT_DEVANAGARI, 0x094D }, + { G_UNICODE_SCRIPT_ETHIOPIC, 0x1258 }, + { G_UNICODE_SCRIPT_GEORGIAN, 0x10FC }, + { G_UNICODE_SCRIPT_GOTHIC, 0x10341 }, + { G_UNICODE_SCRIPT_GREEK, 0x0375 }, + { G_UNICODE_SCRIPT_GUJARATI, 0x0A83 }, + { G_UNICODE_SCRIPT_GURMUKHI, 0x0A3C }, + { G_UNICODE_SCRIPT_HAN, 0x3005 }, + { G_UNICODE_SCRIPT_HANGUL, 0x1100 }, + { G_UNICODE_SCRIPT_HEBREW, 0x05BF }, + { G_UNICODE_SCRIPT_HIRAGANA, 0x309F }, + { G_UNICODE_SCRIPT_KANNADA, 0x0CBC }, + { G_UNICODE_SCRIPT_KATAKANA, 0x30FF }, + { G_UNICODE_SCRIPT_KHMER, 0x17DD }, + { G_UNICODE_SCRIPT_LAO, 0x0EDD }, + { G_UNICODE_SCRIPT_LATIN, 0x0061 }, + { G_UNICODE_SCRIPT_MALAYALAM, 0x0D3D }, + { G_UNICODE_SCRIPT_MONGOLIAN, 0x1843 }, + { G_UNICODE_SCRIPT_MYANMAR, 0x1031 }, + { G_UNICODE_SCRIPT_OGHAM, 0x169C }, + { G_UNICODE_SCRIPT_OLD_ITALIC, 0x10322 }, + { G_UNICODE_SCRIPT_ORIYA, 0x0B3C }, + { G_UNICODE_SCRIPT_RUNIC, 0x16EF }, + { G_UNICODE_SCRIPT_SINHALA, 0x0DBD }, + { G_UNICODE_SCRIPT_SYRIAC, 0x0711 }, + { G_UNICODE_SCRIPT_TAMIL, 0x0B82 }, + { G_UNICODE_SCRIPT_TELUGU, 0x0C03 }, + { G_UNICODE_SCRIPT_THAANA, 0x07B1 }, + { G_UNICODE_SCRIPT_THAI, 0x0E31 }, + { G_UNICODE_SCRIPT_TIBETAN, 0x0FD4 }, + { G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, 0x1400 }, + { G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, 0x1401 }, + { G_UNICODE_SCRIPT_YI, 0xA015 }, + { G_UNICODE_SCRIPT_TAGALOG, 0x1700 }, + { G_UNICODE_SCRIPT_HANUNOO, 0x1720 }, + { G_UNICODE_SCRIPT_BUHID, 0x1740 }, + { G_UNICODE_SCRIPT_TAGBANWA, 0x1760 }, + { G_UNICODE_SCRIPT_BRAILLE, 0x2800 }, + { G_UNICODE_SCRIPT_CYPRIOT, 0x10808 }, + { G_UNICODE_SCRIPT_LIMBU, 0x1932 }, + { G_UNICODE_SCRIPT_OSMANYA, 0x10480 }, + { G_UNICODE_SCRIPT_SHAVIAN, 0x10450 }, + { G_UNICODE_SCRIPT_LINEAR_B, 0x10000 }, + { G_UNICODE_SCRIPT_TAI_LE, 0x1950 }, + { G_UNICODE_SCRIPT_UGARITIC, 0x1039F }, + { G_UNICODE_SCRIPT_NEW_TAI_LUE, 0x1980 }, + { G_UNICODE_SCRIPT_BUGINESE, 0x1A1F }, + { G_UNICODE_SCRIPT_GLAGOLITIC, 0x2C00 }, + { G_UNICODE_SCRIPT_TIFINAGH, 0x2D6F }, + { G_UNICODE_SCRIPT_SYLOTI_NAGRI, 0xA800 }, + { G_UNICODE_SCRIPT_OLD_PERSIAN, 0x103D0 }, + { G_UNICODE_SCRIPT_KHAROSHTHI, 0x10A3F }, + { G_UNICODE_SCRIPT_UNKNOWN, 0x1111111 }, + { G_UNICODE_SCRIPT_BALINESE, 0x1B04 }, + { G_UNICODE_SCRIPT_CUNEIFORM, 0x12000 }, + { G_UNICODE_SCRIPT_PHOENICIAN, 0x10900 }, + { G_UNICODE_SCRIPT_PHAGS_PA, 0xA840 }, + { G_UNICODE_SCRIPT_NKO, 0x07C0 }, + { G_UNICODE_SCRIPT_KAYAH_LI, 0xA900 }, + { G_UNICODE_SCRIPT_LEPCHA, 0x1C00 }, + { G_UNICODE_SCRIPT_REJANG, 0xA930 }, + { G_UNICODE_SCRIPT_SUNDANESE, 0x1B80 }, + { G_UNICODE_SCRIPT_SAURASHTRA, 0xA880 }, + { G_UNICODE_SCRIPT_CHAM, 0xAA00 }, + { G_UNICODE_SCRIPT_OL_CHIKI, 0x1C50 }, + { G_UNICODE_SCRIPT_VAI, 0xA500 }, + { G_UNICODE_SCRIPT_CARIAN, 0x102A0 }, + { G_UNICODE_SCRIPT_LYCIAN, 0x10280 }, + { G_UNICODE_SCRIPT_LYDIAN, 0x1093F }, + { G_UNICODE_SCRIPT_AVESTAN, 0x10B00 }, + { G_UNICODE_SCRIPT_BAMUM, 0xA6A0 }, + { G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS, 0x13000 }, + { G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC, 0x10840 }, + { G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI, 0x10B60 }, + { G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN, 0x10B40 }, + { G_UNICODE_SCRIPT_JAVANESE, 0xA980 }, + { G_UNICODE_SCRIPT_KAITHI, 0x11082 }, + { G_UNICODE_SCRIPT_LISU, 0xA4D0 }, + { G_UNICODE_SCRIPT_MEETEI_MAYEK, 0xABE5 }, + { G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN, 0x10A60 }, + { G_UNICODE_SCRIPT_OLD_TURKIC, 0x10C00 }, + { G_UNICODE_SCRIPT_SAMARITAN, 0x0800 }, + { G_UNICODE_SCRIPT_TAI_THAM, 0x1A20 }, + { G_UNICODE_SCRIPT_TAI_VIET, 0xAA80 }, + { G_UNICODE_SCRIPT_BATAK, 0x1BC0 }, + { G_UNICODE_SCRIPT_BRAHMI, 0x11000 }, + { G_UNICODE_SCRIPT_MANDAIC, 0x0840 }, + { G_UNICODE_SCRIPT_CHAKMA, 0x11100 }, + { G_UNICODE_SCRIPT_MEROITIC_CURSIVE, 0x109A0 }, + { G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS, 0x10980 }, + { G_UNICODE_SCRIPT_MIAO, 0x16F00 }, + { G_UNICODE_SCRIPT_SHARADA, 0x11180 }, + { G_UNICODE_SCRIPT_SORA_SOMPENG, 0x110D0 }, + { G_UNICODE_SCRIPT_TAKRI, 0x11680 }, + { G_UNICODE_SCRIPT_BASSA_VAH, 0x16AD0 }, + { G_UNICODE_SCRIPT_CAUCASIAN_ALBANIAN, 0x10530 }, + { G_UNICODE_SCRIPT_DUPLOYAN, 0x1BC00 }, + { G_UNICODE_SCRIPT_ELBASAN, 0x10500 }, + { G_UNICODE_SCRIPT_GRANTHA, 0x11301 }, + { G_UNICODE_SCRIPT_KHOJKI, 0x11200 }, + { G_UNICODE_SCRIPT_KHUDAWADI, 0x112B0 }, + { G_UNICODE_SCRIPT_LINEAR_A, 0x10600 }, + { G_UNICODE_SCRIPT_MAHAJANI, 0x11150 }, + { G_UNICODE_SCRIPT_MANICHAEAN, 0x10AC0 }, + { G_UNICODE_SCRIPT_MENDE_KIKAKUI, 0x1E800 }, + { G_UNICODE_SCRIPT_MODI, 0x11600 }, + { G_UNICODE_SCRIPT_MRO, 0x16A40 }, + { G_UNICODE_SCRIPT_NABATAEAN, 0x10880 }, + { G_UNICODE_SCRIPT_OLD_NORTH_ARABIAN, 0x10A80 }, + { G_UNICODE_SCRIPT_OLD_PERMIC, 0x10350 }, + { G_UNICODE_SCRIPT_PAHAWH_HMONG, 0x16B00 }, + { G_UNICODE_SCRIPT_PALMYRENE, 0x10860 }, + { G_UNICODE_SCRIPT_PAU_CIN_HAU, 0x11AC0 }, + { G_UNICODE_SCRIPT_PSALTER_PAHLAVI, 0x10B80 }, + { G_UNICODE_SCRIPT_SIDDHAM, 0x11580 }, + { G_UNICODE_SCRIPT_TIRHUTA, 0x11480 }, + { G_UNICODE_SCRIPT_WARANG_CITI, 0x118A0 }, + { G_UNICODE_SCRIPT_CHEROKEE, 0x0AB71 }, + { G_UNICODE_SCRIPT_HATRAN, 0x108E0 }, + { G_UNICODE_SCRIPT_OLD_HUNGARIAN, 0x10C80 }, + { G_UNICODE_SCRIPT_MULTANI, 0x11280 }, + { G_UNICODE_SCRIPT_AHOM, 0x11700 }, + { G_UNICODE_SCRIPT_CUNEIFORM, 0x12480 }, + { G_UNICODE_SCRIPT_ANATOLIAN_HIEROGLYPHS, 0x14400 }, + { G_UNICODE_SCRIPT_SIGNWRITING, 0x1D800 }, + { G_UNICODE_SCRIPT_ADLAM, 0x1E900 }, + { G_UNICODE_SCRIPT_BHAIKSUKI, 0x11C00 }, + { G_UNICODE_SCRIPT_MARCHEN, 0x11C70 }, + { G_UNICODE_SCRIPT_NEWA, 0x11400 }, + { G_UNICODE_SCRIPT_OSAGE, 0x104B0 }, + { G_UNICODE_SCRIPT_TANGUT, 0x16FE0 }, + { G_UNICODE_SCRIPT_MASARAM_GONDI, 0x11D00 }, + { G_UNICODE_SCRIPT_NUSHU, 0x1B170 }, + { G_UNICODE_SCRIPT_SOYOMBO, 0x11A50 }, + { G_UNICODE_SCRIPT_ZANABAZAR_SQUARE, 0x11A00 }, + { G_UNICODE_SCRIPT_DOGRA, 0x11800 }, + { G_UNICODE_SCRIPT_GUNJALA_GONDI, 0x11D60 }, + { G_UNICODE_SCRIPT_HANIFI_ROHINGYA, 0x10D00 }, + { G_UNICODE_SCRIPT_MAKASAR, 0x11EE0 }, + { G_UNICODE_SCRIPT_MEDEFAIDRIN, 0x16E40 }, + { G_UNICODE_SCRIPT_OLD_SOGDIAN, 0x10F00 }, + { G_UNICODE_SCRIPT_SOGDIAN, 0x10F30 }, + { G_UNICODE_SCRIPT_ELYMAIC, 0x10FE0 }, + { G_UNICODE_SCRIPT_NANDINAGARI, 0x119A0 }, + { G_UNICODE_SCRIPT_NYIAKENG_PUACHUE_HMONG, 0x1E100 }, + { G_UNICODE_SCRIPT_WANCHO, 0x1E2C0 }, + { G_UNICODE_SCRIPT_CHORASMIAN, 0x10FB0 }, + { G_UNICODE_SCRIPT_DIVES_AKURU, 0x11900 }, + { G_UNICODE_SCRIPT_KHITAN_SMALL_SCRIPT, 0x18B00 }, + { G_UNICODE_SCRIPT_YEZIDI, 0x10E80 }, + { G_UNICODE_SCRIPT_CYPRO_MINOAN, 0x12F90 }, + { G_UNICODE_SCRIPT_OLD_UYGHUR, 0x10F70 }, + { G_UNICODE_SCRIPT_TANGSA, 0x16A70 }, + { G_UNICODE_SCRIPT_TOTO, 0x1E290 }, + { G_UNICODE_SCRIPT_VITHKUQI, 0x10570 } + }; + for (i = 0; i < G_N_ELEMENTS (examples); i++) + g_assert_cmpint (g_unichar_get_script (examples[i].c), ==, examples[i].script); +} + +/* Test that g_unichar_combining_class() returns the correct value for + * various ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_combining_class (void) +{ + guint i; + struct { + gint class; + gunichar c; + } examples[] = { + { 0, 0x0020 }, + { 1, 0x0334 }, + { 7, 0x093C }, + { 8, 0x3099 }, + { 9, 0x094D }, + { 10, 0x05B0 }, + { 11, 0x05B1 }, + { 12, 0x05B2 }, + { 13, 0x05B3 }, + { 14, 0x05B4 }, + { 15, 0x05B5 }, + { 16, 0x05B6 }, + { 17, 0x05B7 }, + { 18, 0x05B8 }, + { 19, 0x05B9 }, + { 20, 0x05BB }, + { 21, 0x05BC }, + { 22, 0x05BD }, + { 23, 0x05BF }, + { 24, 0x05C1 }, + { 25, 0x05C2 }, + { 26, 0xFB1E }, + { 27, 0x064B }, + { 28, 0x064C }, + { 29, 0x064D }, + /* ... */ + { 228, 0x05AE }, + { 230, 0x0300 }, + { 232, 0x302C }, + { 233, 0x0362 }, + { 234, 0x0360 }, + { 234, 0x1DCD }, + { 240, 0x0345 } + }; + for (i = 0; i < G_N_ELEMENTS (examples); i++) + { + g_assert_cmpint (g_unichar_combining_class (examples[i].c), ==, examples[i].class); + } +} + +/* Test that g_unichar_get_mirror() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_mirror (void) +{ + gunichar mirror; + + g_assert_true (g_unichar_get_mirror_char ('(', &mirror)); + g_assert_cmpint (mirror, ==, ')'); + g_assert_true (g_unichar_get_mirror_char (')', &mirror)); + g_assert_cmpint (mirror, ==, '('); + g_assert_true (g_unichar_get_mirror_char ('{', &mirror)); + g_assert_cmpint (mirror, ==, '}'); + g_assert_true (g_unichar_get_mirror_char ('}', &mirror)); + g_assert_cmpint (mirror, ==, '{'); + g_assert_true (g_unichar_get_mirror_char (0x208D, &mirror)); + g_assert_cmpint (mirror, ==, 0x208E); + g_assert_true (g_unichar_get_mirror_char (0x208E, &mirror)); + g_assert_cmpint (mirror, ==, 0x208D); + g_assert_false (g_unichar_get_mirror_char ('a', &mirror)); +} + +/* Test that g_utf8_strup() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_strup (void) +{ + char *str_up = NULL; + const char *str = "AaZz09x;\x03\x45" + "\xEF\xBD\x81" /* Unichar 'A' (U+FF21) */ + "\xEF\xBC\xA1"; /* Unichar 'a' (U+FF41) */ + + /* Testing degenerated cases */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_up = g_utf8_strup (NULL, 0); + g_test_assert_expected_messages (); + } + + str_up = g_utf8_strup (str, strlen (str)); + /* Tricky, comparing two unicode strings with an ASCII function */ + g_assert_cmpstr (str_up, ==, "AAZZ09X;\003E\357\274\241\357\274\241"); + g_free (str_up); +} + +/* Test that g_utf8_strdown() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_strdown (void) +{ + char *str_down = NULL; + const char *str = "AaZz09x;\x03\x07" + "\xEF\xBD\x81" /* Unichar 'A' (U+FF21) */ + "\xEF\xBC\xA1"; /* Unichar 'a' (U+FF41) */ + + /* Testing degenerated cases */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_down = g_utf8_strdown (NULL, 0); + g_test_assert_expected_messages (); + } + + str_down = g_utf8_strdown (str, strlen (str)); + /* Tricky, comparing two unicode strings with an ASCII function */ + g_assert_cmpstr (str_down, ==, "aazz09x;\003\007\357\275\201\357\275\201"); + g_free (str_down); +} + +/* Test that g_utf8_strup() and g_utf8_strdown() return the correct + * value for Turkish 'i' with and without dot above. */ +static void +test_turkish_strupdown (void) +{ + char *str_up = NULL; + char *str_down = NULL; + const char *str = "iII" + "\xcc\x87" /* COMBINING DOT ABOVE (U+307) */ + "\xc4\xb1" /* LATIN SMALL LETTER DOTLESS I (U+131) */ + "\xc4\xb0"; /* LATIN CAPITAL LETTER I WITH DOT ABOVE (U+130) */ + + char *oldlocale = g_strdup (setlocale (LC_ALL, "tr_TR")); + + if (oldlocale == NULL) + { + g_test_skip ("locale tr_TR not available"); + return; + } + + str_up = g_utf8_strup (str, strlen (str)); + str_down = g_utf8_strdown (str, strlen (str)); + /* i => LATIN CAPITAL LETTER I WITH DOT ABOVE, + * I => I, + * I + COMBINING DOT ABOVE => I + COMBINING DOT ABOVE, + * LATIN SMALL LETTER DOTLESS I => I, + * LATIN CAPITAL LETTER I WITH DOT ABOVE => LATIN CAPITAL LETTER I WITH DOT ABOVE */ + g_assert_cmpstr (str_up, ==, "\xc4\xb0II\xcc\x87I\xc4\xb0"); + /* i => i, + * I => LATIN SMALL LETTER DOTLESS I, + * I + COMBINING DOT ABOVE => i, + * LATIN SMALL LETTER DOTLESS I => LATIN SMALL LETTER DOTLESS I, + * LATIN CAPITAL LETTER I WITH DOT ABOVE => i */ + g_assert_cmpstr (str_down, ==, "i\xc4\xb1i\xc4\xb1i"); + g_free (str_up); + g_free (str_down); + + setlocale (LC_ALL, oldlocale); + g_free (oldlocale); +} + +/* Test that g_utf8_casefold() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_casefold (void) +{ + char *str_casefold = NULL; + const char *str = "AaZz09x;" + "\xEF\xBD\x81" /* Unichar 'A' (U+FF21) */ + "\xEF\xBC\xA1"; /* Unichar 'a' (U+FF41) */ + + /* Testing degenerated cases */ + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + str_casefold = g_utf8_casefold (NULL, 0); + g_test_assert_expected_messages (); + } + + str_casefold = g_utf8_casefold (str, strlen (str)); + /* Tricky, comparing two unicode strings with an ASCII function */ + g_assert_cmpstr (str_casefold, ==, "aazz09x;\357\275\201\357\275\201"); + g_free (str_casefold); +} + +static void +test_casemap_and_casefold (void) +{ + FILE *infile; + char buffer[1024]; + char **strings; + char *filename; + const char *locale; + const char *test; + const char *expected; + char *convert; + char *current_locale = setlocale (LC_CTYPE, NULL); + + filename = g_test_build_filename (G_TEST_DIST, "casemap.txt", NULL); + infile = fopen (filename, "r"); + g_assert (infile != NULL); + + while (fgets (buffer, sizeof (buffer), infile)) + { + if (buffer[0] == '#') + continue; + + strings = g_strsplit (buffer, "\t", -1); + locale = strings[0]; + if (!locale[0]) + locale = "C"; + + if (strcmp (locale, current_locale) != 0) + { + setlocale (LC_CTYPE, locale); + current_locale = setlocale (LC_CTYPE, NULL); + + if (strncmp (current_locale, locale, 2) != 0) + { + g_test_message ("Cannot set locale to %s, skipping", locale); + goto next; + } + } + + test = strings[1]; + + /* gen-casemap-txt.py uses an empty string when a single + * character doesn't have an equivalent in a particular case; + * since that behavior is nonsense for multicharacter strings, + * it would make more sense to put the expected result ... the + * original character unchanged. But for now, we just work + * around it here and take the empty string to mean "same as + * original" + */ + + convert = g_utf8_strup (test, -1); + expected = strings[4][0] ? strings[4] : test; + g_assert_cmpstr (convert, ==, expected); + g_free (convert); + + convert = g_utf8_strdown (test, -1); + expected = strings[2][0] ? strings[2] : test; + g_assert_cmpstr (convert, ==, expected); + g_free (convert); + + next: + g_strfreev (strings); + } + + fclose (infile); + + g_free (filename); + filename = g_test_build_filename (G_TEST_DIST, "casefold.txt", NULL); + + infile = fopen (filename, "r"); + g_assert (infile != NULL); + + while (fgets (buffer, sizeof (buffer), infile)) + { + if (buffer[0] == '#') + continue; + + buffer[strlen (buffer) - 1] = '\0'; + strings = g_strsplit (buffer, "\t", -1); + + test = strings[0]; + + convert = g_utf8_casefold (test, -1); + g_assert_cmpstr (convert, ==, strings[1]); + g_free (convert); + + g_strfreev (strings); + } + + fclose (infile); + g_free (filename); +} + +/* Test that g_unichar_ismark() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_mark (void) +{ + g_assert_true (g_unichar_ismark (0x0903)); + g_assert_true (g_unichar_ismark (0x20DD)); + g_assert_true (g_unichar_ismark (0xA806)); + g_assert_false (g_unichar_ismark ('a')); + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_ismark (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_ismark (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_ismark (0xE0001)); + g_assert_false (g_unichar_ismark (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_ismark (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_ismark (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_ismark (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_isspace() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_space (void) +{ + g_assert_false (g_unichar_isspace ('a')); + g_assert_true (g_unichar_isspace (' ')); + g_assert_true (g_unichar_isspace ('\t')); + g_assert_true (g_unichar_isspace ('\n')); + g_assert_true (g_unichar_isspace ('\r')); + g_assert_true (g_unichar_isspace ('\f')); + g_assert_false (g_unichar_isspace (0xff41)); /* Unicode fullwidth 'a' */ + g_assert_true (g_unichar_isspace (0x202F)); /* Unicode space separator */ + g_assert_true (g_unichar_isspace (0x2028)); /* Unicode line separator */ + g_assert_true (g_unichar_isspace (0x2029)); /* Unicode paragraph separator */ + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_isspace (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_isspace (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_isspace (0xE0001)); + g_assert_false (g_unichar_isspace (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isspace (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isspace (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isspace (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_isalnum() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_alnum (void) +{ + g_assert_false (g_unichar_isalnum (' ')); + g_assert_true (g_unichar_isalnum ('a')); + g_assert_true (g_unichar_isalnum ('z')); + g_assert_true (g_unichar_isalnum ('0')); + g_assert_true (g_unichar_isalnum ('9')); + g_assert_true (g_unichar_isalnum ('A')); + g_assert_true (g_unichar_isalnum ('Z')); + g_assert_false (g_unichar_isalnum ('-')); + g_assert_false (g_unichar_isalnum ('*')); + g_assert_true (g_unichar_isalnum (0xFF21)); /* Unichar fullwidth 'A' */ + g_assert_true (g_unichar_isalnum (0xFF3A)); /* Unichar fullwidth 'Z' */ + g_assert_true (g_unichar_isalnum (0xFF41)); /* Unichar fullwidth 'a' */ + g_assert_true (g_unichar_isalnum (0xFF5A)); /* Unichar fullwidth 'z' */ + g_assert_true (g_unichar_isalnum (0xFF10)); /* Unichar fullwidth '0' */ + g_assert_true (g_unichar_isalnum (0xFF19)); /* Unichar fullwidth '9' */ + g_assert_false (g_unichar_isalnum (0xFF0A)); /* Unichar fullwidth '*' */ + + /*** Testing TYPE() border cases ***/ + g_assert_true (g_unichar_isalnum (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_isalnum (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_isalnum (0xE0001)); + g_assert_false (g_unichar_isalnum (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isalnum (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isalnum (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isalnum (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_isalpha() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_alpha (void) +{ + g_assert_false (g_unichar_isalpha (' ')); + g_assert_true (g_unichar_isalpha ('a')); + g_assert_true (g_unichar_isalpha ('z')); + g_assert_false (g_unichar_isalpha ('0')); + g_assert_false (g_unichar_isalpha ('9')); + g_assert_true (g_unichar_isalpha ('A')); + g_assert_true (g_unichar_isalpha ('Z')); + g_assert_false (g_unichar_isalpha ('-')); + g_assert_false (g_unichar_isalpha ('*')); + g_assert_true (g_unichar_isalpha (0xFF21)); /* Unichar fullwidth 'A' */ + g_assert_true (g_unichar_isalpha (0xFF3A)); /* Unichar fullwidth 'Z' */ + g_assert_true (g_unichar_isalpha (0xFF41)); /* Unichar fullwidth 'a' */ + g_assert_true (g_unichar_isalpha (0xFF5A)); /* Unichar fullwidth 'z' */ + g_assert_false (g_unichar_isalpha (0xFF10)); /* Unichar fullwidth '0' */ + g_assert_false (g_unichar_isalpha (0xFF19)); /* Unichar fullwidth '9' */ + g_assert_false (g_unichar_isalpha (0xFF0A)); /* Unichar fullwidth '*' */ + + /*** Testing TYPE() border cases ***/ + g_assert_true (g_unichar_isalpha (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_isalpha (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_isalpha (0xE0001)); + g_assert_false (g_unichar_isalpha (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isalpha (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isalpha (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isalpha (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_isdigit() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_digit (void) +{ + g_assert_false (g_unichar_isdigit (' ')); + g_assert_false (g_unichar_isdigit ('a')); + g_assert_true (g_unichar_isdigit ('0')); + g_assert_true (g_unichar_isdigit ('9')); + g_assert_false (g_unichar_isdigit ('A')); + g_assert_false (g_unichar_isdigit ('-')); + g_assert_false (g_unichar_isdigit ('*')); + g_assert_false (g_unichar_isdigit (0xFF21)); /* Unichar fullwidth 'A' */ + g_assert_false (g_unichar_isdigit (0xFF3A)); /* Unichar fullwidth 'Z' */ + g_assert_false (g_unichar_isdigit (0xFF41)); /* Unichar fullwidth 'a' */ + g_assert_false (g_unichar_isdigit (0xFF5A)); /* Unichar fullwidth 'z' */ + g_assert_true (g_unichar_isdigit (0xFF10)); /* Unichar fullwidth '0' */ + g_assert_true (g_unichar_isdigit (0xFF19)); /* Unichar fullwidth '9' */ + g_assert_false (g_unichar_isdigit (0xFF0A)); /* Unichar fullwidth '*' */ + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_isdigit (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_isdigit (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_isdigit (0xE0001)); + g_assert_false (g_unichar_isdigit (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isdigit (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isdigit (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isdigit (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_digit_value() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_digit_value (void) +{ + g_assert_cmpint (g_unichar_digit_value (' '), ==, -1); + g_assert_cmpint (g_unichar_digit_value ('a'), ==, -1); + g_assert_cmpint (g_unichar_digit_value ('0'), ==, 0); + g_assert_cmpint (g_unichar_digit_value ('9'), ==, 9); + g_assert_cmpint (g_unichar_digit_value ('A'), ==, -1); + g_assert_cmpint (g_unichar_digit_value ('-'), ==, -1); + g_assert_cmpint (g_unichar_digit_value (0xFF21), ==, -1); /* Unichar 'A' */ + g_assert_cmpint (g_unichar_digit_value (0xFF3A), ==, -1); /* Unichar 'Z' */ + g_assert_cmpint (g_unichar_digit_value (0xFF41), ==, -1); /* Unichar 'a' */ + g_assert_cmpint (g_unichar_digit_value (0xFF5A), ==, -1); /* Unichar 'z' */ + g_assert_cmpint (g_unichar_digit_value (0xFF10), ==, 0); /* Unichar '0' */ + g_assert_cmpint (g_unichar_digit_value (0xFF19), ==, 9); /* Unichar '9' */ + g_assert_cmpint (g_unichar_digit_value (0xFF0A), ==, -1); /* Unichar '*' */ + + /*** Testing TYPE() border cases ***/ + g_assert_cmpint (g_unichar_digit_value (0x3FF5), ==, -1); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_cmpint (g_unichar_digit_value (0xFFEFF), ==, -1); + /* U+E0001 Language Tag */ + g_assert_cmpint (g_unichar_digit_value (0xE0001), ==, -1); + g_assert_cmpint (g_unichar_digit_value (G_UNICODE_LAST_CHAR), ==, -1); + g_assert_cmpint (g_unichar_digit_value (G_UNICODE_LAST_CHAR + 1), ==, -1); + g_assert_cmpint (g_unichar_digit_value (G_UNICODE_LAST_CHAR_PART1), ==, -1); + g_assert_cmpint (g_unichar_digit_value (G_UNICODE_LAST_CHAR_PART1 + 1), ==, -1); +} + +/* Test that g_unichar_isxdigit() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_xdigit (void) +{ + g_assert_false (g_unichar_isxdigit (' ')); + g_assert_true (g_unichar_isxdigit ('a')); + g_assert_true (g_unichar_isxdigit ('f')); + g_assert_false (g_unichar_isxdigit ('g')); + g_assert_false (g_unichar_isxdigit ('z')); + g_assert_true (g_unichar_isxdigit ('0')); + g_assert_true (g_unichar_isxdigit ('9')); + g_assert_true (g_unichar_isxdigit ('A')); + g_assert_true (g_unichar_isxdigit ('F')); + g_assert_false (g_unichar_isxdigit ('G')); + g_assert_false (g_unichar_isxdigit ('Z')); + g_assert_false (g_unichar_isxdigit ('-')); + g_assert_false (g_unichar_isxdigit ('*')); + g_assert_true (g_unichar_isxdigit (0xFF21)); /* Unichar fullwidth 'A' */ + g_assert_true (g_unichar_isxdigit (0xFF26)); /* Unichar fullwidth 'F' */ + g_assert_false (g_unichar_isxdigit (0xFF27)); /* Unichar fullwidth 'G' */ + g_assert_false (g_unichar_isxdigit (0xFF3A)); /* Unichar fullwidth 'Z' */ + g_assert_true (g_unichar_isxdigit (0xFF41)); /* Unichar fullwidth 'a' */ + g_assert_true (g_unichar_isxdigit (0xFF46)); /* Unichar fullwidth 'f' */ + g_assert_false (g_unichar_isxdigit (0xFF47)); /* Unichar fullwidth 'g' */ + g_assert_false (g_unichar_isxdigit (0xFF5A)); /* Unichar fullwidth 'z' */ + g_assert_true (g_unichar_isxdigit (0xFF10)); /* Unichar fullwidth '0' */ + g_assert_true (g_unichar_isxdigit (0xFF19)); /* Unichar fullwidth '9' */ + g_assert_false (g_unichar_isxdigit (0xFF0A)); /* Unichar fullwidth '*' */ + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_isxdigit (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_isxdigit (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_isxdigit (0xE0001)); + g_assert_false (g_unichar_isxdigit (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isxdigit (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isxdigit (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isxdigit (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_xdigit_value() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_xdigit_value (void) +{ + g_assert_cmpint (g_unichar_xdigit_value (' '), ==, -1); + g_assert_cmpint (g_unichar_xdigit_value ('a'), ==, 10); + g_assert_cmpint (g_unichar_xdigit_value ('f'), ==, 15); + g_assert_cmpint (g_unichar_xdigit_value ('g'), ==, -1); + g_assert_cmpint (g_unichar_xdigit_value ('0'), ==, 0); + g_assert_cmpint (g_unichar_xdigit_value ('9'), ==, 9); + g_assert_cmpint (g_unichar_xdigit_value ('A'), ==, 10); + g_assert_cmpint (g_unichar_xdigit_value ('F'), ==, 15); + g_assert_cmpint (g_unichar_xdigit_value ('G'), ==, -1); + g_assert_cmpint (g_unichar_xdigit_value ('-'), ==, -1); + g_assert_cmpint (g_unichar_xdigit_value (0xFF21), ==, 10); /* Unichar 'A' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF26), ==, 15); /* Unichar 'F' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF27), ==, -1); /* Unichar 'G' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF3A), ==, -1); /* Unichar 'Z' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF41), ==, 10); /* Unichar 'a' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF46), ==, 15); /* Unichar 'f' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF47), ==, -1); /* Unichar 'g' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF5A), ==, -1); /* Unichar 'z' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF10), ==, 0); /* Unichar '0' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF19), ==, 9); /* Unichar '9' */ + g_assert_cmpint (g_unichar_xdigit_value (0xFF0A), ==, -1); /* Unichar '*' */ + + /*** Testing TYPE() border cases ***/ + g_assert_cmpint (g_unichar_xdigit_value (0x3FF5), ==, -1); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_cmpint (g_unichar_xdigit_value (0xFFEFF), ==, -1); + /* U+E0001 Language Tag */ + g_assert_cmpint (g_unichar_xdigit_value (0xE0001), ==, -1); + g_assert_cmpint (g_unichar_xdigit_value (G_UNICODE_LAST_CHAR), ==, -1); + g_assert_cmpint (g_unichar_xdigit_value (G_UNICODE_LAST_CHAR + 1), ==, -1); + g_assert_cmpint (g_unichar_xdigit_value (G_UNICODE_LAST_CHAR_PART1), ==, -1); + g_assert_cmpint (g_unichar_xdigit_value (G_UNICODE_LAST_CHAR_PART1 + 1), ==, -1); +} + +/* Test that g_unichar_ispunct() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_punctuation (void) +{ + g_assert_false (g_unichar_ispunct (' ')); + g_assert_false (g_unichar_ispunct ('a')); + g_assert_true (g_unichar_ispunct ('.')); + g_assert_true (g_unichar_ispunct (',')); + g_assert_true (g_unichar_ispunct (';')); + g_assert_true (g_unichar_ispunct (':')); + g_assert_true (g_unichar_ispunct ('-')); + + g_assert_false (g_unichar_ispunct (0xFF21)); /* Unichar fullwidth 'A' */ + g_assert_true (g_unichar_ispunct (0x005F)); /* Unichar fullwidth '.' */ + g_assert_true (g_unichar_ispunct (0x058A)); /* Unichar fullwidth '-' */ + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_ispunct (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_ispunct (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_ispunct (0xE0001)); + g_assert_false (g_unichar_ispunct (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_ispunct (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_ispunct (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_ispunct (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_iscntrl() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_cntrl (void) +{ + g_assert_true (g_unichar_iscntrl (0x08)); + g_assert_false (g_unichar_iscntrl ('a')); + g_assert_true (g_unichar_iscntrl (0x007F)); /* Unichar fullwidth */ + g_assert_true (g_unichar_iscntrl (0x009F)); /* Unichar fullwidth control */ + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_iscntrl (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_iscntrl (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_iscntrl (0xE0001)); + g_assert_false (g_unichar_iscntrl (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_iscntrl (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_iscntrl (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_iscntrl (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_isgraph() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_graph (void) +{ + g_assert_false (g_unichar_isgraph (0x08)); + g_assert_false (g_unichar_isgraph (' ')); + g_assert_true (g_unichar_isgraph ('a')); + g_assert_true (g_unichar_isgraph ('0')); + g_assert_true (g_unichar_isgraph ('9')); + g_assert_true (g_unichar_isgraph ('A')); + g_assert_true (g_unichar_isgraph ('-')); + g_assert_true (g_unichar_isgraph ('*')); + g_assert_true (g_unichar_isgraph (0xFF21)); /* Unichar fullwidth 'A' */ + g_assert_true (g_unichar_isgraph (0xFF3A)); /* Unichar fullwidth 'Z' */ + g_assert_true (g_unichar_isgraph (0xFF41)); /* Unichar fullwidth 'a' */ + g_assert_true (g_unichar_isgraph (0xFF5A)); /* Unichar fullwidth 'z' */ + g_assert_true (g_unichar_isgraph (0xFF10)); /* Unichar fullwidth '0' */ + g_assert_true (g_unichar_isgraph (0xFF19)); /* Unichar fullwidth '9' */ + g_assert_true (g_unichar_isgraph (0xFF0A)); /* Unichar fullwidth '*' */ + g_assert_false (g_unichar_isgraph (0x007F)); /* Unichar fullwidth */ + g_assert_false (g_unichar_isgraph (0x009F)); /* Unichar fullwidth control */ + + /*** Testing TYPE() border cases ***/ + g_assert_true (g_unichar_isgraph (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_true (g_unichar_isgraph (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_isgraph (0xE0001)); + g_assert_false (g_unichar_isgraph (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isgraph (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isgraph (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isgraph (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_iszerowidth() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_zerowidth (void) +{ + g_assert_false (g_unichar_iszerowidth (0x00AD)); + g_assert_false (g_unichar_iszerowidth (0x115F)); + g_assert_true (g_unichar_iszerowidth (0x1160)); + g_assert_true (g_unichar_iszerowidth (0x11AA)); + g_assert_true (g_unichar_iszerowidth (0x11FF)); + g_assert_false (g_unichar_iszerowidth (0x1200)); + g_assert_false (g_unichar_iszerowidth (0x200A)); + g_assert_true (g_unichar_iszerowidth (0x200B)); + g_assert_true (g_unichar_iszerowidth (0x200C)); + g_assert_true (g_unichar_iszerowidth (0x591)); + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_iszerowidth (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_iszerowidth (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_true (g_unichar_iszerowidth (0xE0001)); + g_assert_false (g_unichar_iszerowidth (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_iszerowidth (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_iszerowidth (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_iszerowidth (G_UNICODE_LAST_CHAR_PART1 + 1)); + + /* Hangul Jamo Extended-B block, containing jungseong and jongseong for + * Old Korean */ + g_assert_true (g_unichar_iszerowidth (0xD7B0)); + g_assert_true (g_unichar_iszerowidth (0xD7FB)); +} + +/* Test that g_unichar_istitle() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_title (void) +{ + g_assert_true (g_unichar_istitle (0x01c5)); + g_assert_true (g_unichar_istitle (0x1f88)); + g_assert_true (g_unichar_istitle (0x1fcc)); + g_assert_false (g_unichar_istitle ('a')); + g_assert_false (g_unichar_istitle ('A')); + g_assert_false (g_unichar_istitle (';')); + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_istitle (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_istitle (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_istitle (0xE0001)); + g_assert_false (g_unichar_istitle (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_istitle (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_istitle (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_istitle (G_UNICODE_LAST_CHAR_PART1 + 1)); + + g_assert_cmphex (g_unichar_totitle (0x0000), ==, 0x0000); + g_assert_cmphex (g_unichar_totitle (0x01c6), ==, 0x01c5); + g_assert_cmphex (g_unichar_totitle (0x01c4), ==, 0x01c5); + g_assert_cmphex (g_unichar_totitle (0x01c5), ==, 0x01c5); + g_assert_cmphex (g_unichar_totitle (0x1f80), ==, 0x1f88); + g_assert_cmphex (g_unichar_totitle (0x1f88), ==, 0x1f88); + g_assert_cmphex (g_unichar_totitle ('a'), ==, 'A'); + g_assert_cmphex (g_unichar_totitle ('A'), ==, 'A'); + + /*** Testing TYPE() border cases ***/ + g_assert_cmphex (g_unichar_totitle (0x3FF5), ==, 0x3FF5); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_cmphex (g_unichar_totitle (0xFFEFF), ==, 0xFFEFF); + g_assert_cmphex (g_unichar_totitle (0xDFFFF), ==, 0xDFFFF); + /* U+E0001 Language Tag */ + g_assert_cmphex (g_unichar_totitle (0xE0001), ==, 0xE0001); + g_assert_cmphex (g_unichar_totitle (G_UNICODE_LAST_CHAR), ==, + G_UNICODE_LAST_CHAR); + g_assert_cmphex (g_unichar_totitle (G_UNICODE_LAST_CHAR + 1), ==, + (G_UNICODE_LAST_CHAR + 1)); + g_assert_cmphex (g_unichar_totitle (G_UNICODE_LAST_CHAR_PART1), ==, + (G_UNICODE_LAST_CHAR_PART1)); + g_assert_cmphex (g_unichar_totitle (G_UNICODE_LAST_CHAR_PART1 + 1), ==, + (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_isupper() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_upper (void) +{ + g_assert_false (g_unichar_isupper (' ')); + g_assert_false (g_unichar_isupper ('0')); + g_assert_false (g_unichar_isupper ('a')); + g_assert_true (g_unichar_isupper ('A')); + g_assert_false (g_unichar_isupper (0xff41)); /* Unicode fullwidth 'a' */ + g_assert_true (g_unichar_isupper (0xff21)); /* Unicode fullwidth 'A' */ + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_isupper (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_isupper (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_isupper (0xE0001)); + g_assert_false (g_unichar_isupper (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isupper (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isupper (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isupper (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_islower() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_lower (void) +{ + g_assert_false (g_unichar_islower (' ')); + g_assert_false (g_unichar_islower ('0')); + g_assert_true (g_unichar_islower ('a')); + g_assert_false (g_unichar_islower ('A')); + g_assert_true (g_unichar_islower (0xff41)); /* Unicode fullwidth 'a' */ + g_assert_false (g_unichar_islower (0xff21)); /* Unicode fullwidth 'A' */ + + /*** Testing TYPE() border cases ***/ + g_assert_false (g_unichar_islower (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_false (g_unichar_islower (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_islower (0xE0001)); + g_assert_false (g_unichar_islower (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_islower (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_islower (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_islower (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_isprint() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_print (void) +{ + g_assert_true (g_unichar_isprint (' ')); + g_assert_true (g_unichar_isprint ('0')); + g_assert_true (g_unichar_isprint ('a')); + g_assert_true (g_unichar_isprint ('A')); + g_assert_true (g_unichar_isprint (0xff41)); /* Unicode fullwidth 'a' */ + g_assert_true (g_unichar_isprint (0xff21)); /* Unicode fullwidth 'A' */ + + /*** Testing TYPE() border cases ***/ + g_assert_true (g_unichar_isprint (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_true (g_unichar_isprint (0xFFEFF)); + /* U+E0001 Language Tag */ + g_assert_false (g_unichar_isprint (0xE0001)); + g_assert_false (g_unichar_isprint (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isprint (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isprint (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isprint (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_toupper() and g_unichar_tolower() return the + * correct values for various ASCII and Unicode alphabetic, numeric, + * and other, codepoints. */ +static void +test_cases (void) +{ + g_assert_cmphex (g_unichar_toupper (0x0), ==, 0x0); + g_assert_cmphex (g_unichar_tolower (0x0), ==, 0x0); + g_assert_cmphex (g_unichar_toupper ('a'), ==, 'A'); + g_assert_cmphex (g_unichar_toupper ('A'), ==, 'A'); + /* Unicode fullwidth 'a' == 'A' */ + g_assert_cmphex (g_unichar_toupper (0xff41), ==, 0xff21); + /* Unicode fullwidth 'A' == 'A' */ + g_assert_cmphex (g_unichar_toupper (0xff21), ==, 0xff21); + g_assert_cmphex (g_unichar_toupper (0x01C5), ==, 0x01C4); + g_assert_cmphex (g_unichar_toupper (0x01C6), ==, 0x01C4); + g_assert_cmphex (g_unichar_tolower ('A'), ==, 'a'); + g_assert_cmphex (g_unichar_tolower ('a'), ==, 'a'); + /* Unicode fullwidth 'A' == 'a' */ + g_assert_cmphex (g_unichar_tolower (0xff21), ==, 0xff41); + /* Unicode fullwidth 'a' == 'a' */ + g_assert_cmphex (g_unichar_tolower (0xff41), ==, 0xff41); + g_assert_cmphex (g_unichar_tolower (0x01C4), ==, 0x01C6); + g_assert_cmphex (g_unichar_tolower (0x01C5), ==, 0x01C6); + g_assert_cmphex (g_unichar_tolower (0x1F8A), ==, 0x1F82); + g_assert_cmphex (g_unichar_totitle (0x1F8A), ==, 0x1F8A); + g_assert_cmphex (g_unichar_toupper (0x1F8A), ==, 0x1F8A); + g_assert_cmphex (g_unichar_tolower (0x1FB2), ==, 0x1FB2); + g_assert_cmphex (g_unichar_toupper (0x1FB2), ==, 0x1FB2); + + /* U+130 is a special case, it's a 'I' with a dot on top */ + g_assert_cmphex (g_unichar_tolower (0x130), ==, 0x69); + + /* Testing ATTTABLE() border cases */ + g_assert_cmphex (g_unichar_toupper (0x1D6FE), ==, 0x1D6FE); + + /*** Testing TYPE() border cases ***/ + g_assert_cmphex (g_unichar_toupper (0x3FF5), ==, 0x3FF5); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_cmphex (g_unichar_toupper (0xFFEFF), ==, 0xFFEFF); + g_assert_cmphex (g_unichar_toupper (0xDFFFF), ==, 0xDFFFF); + /* U+E0001 Language Tag */ + g_assert_cmphex (g_unichar_toupper (0xE0001), ==, 0xE0001); + g_assert_cmphex (g_unichar_toupper (G_UNICODE_LAST_CHAR), ==, + G_UNICODE_LAST_CHAR); + g_assert_cmphex (g_unichar_toupper (G_UNICODE_LAST_CHAR + 1), ==, + (G_UNICODE_LAST_CHAR + 1)); + g_assert_cmphex (g_unichar_toupper (G_UNICODE_LAST_CHAR_PART1), ==, + (G_UNICODE_LAST_CHAR_PART1)); + g_assert_cmphex (g_unichar_toupper (G_UNICODE_LAST_CHAR_PART1 + 1), ==, + (G_UNICODE_LAST_CHAR_PART1 + 1)); + + /* Testing ATTTABLE() border cases */ + g_assert_cmphex (g_unichar_tolower (0x1D6FA), ==, 0x1D6FA); + + /*** Testing TYPE() border cases ***/ + g_assert_cmphex (g_unichar_tolower (0x3FF5), ==, 0x3FF5); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_cmphex (g_unichar_tolower (0xFFEFF), ==, 0xFFEFF); + g_assert_cmphex (g_unichar_tolower (0xDFFFF), ==, 0xDFFFF); + /* U+E0001 Language Tag */ + g_assert_cmphex (g_unichar_tolower (0xE0001), ==, 0xE0001); + g_assert_cmphex (g_unichar_tolower (G_UNICODE_LAST_CHAR), ==, + G_UNICODE_LAST_CHAR); + g_assert_cmphex (g_unichar_tolower (G_UNICODE_LAST_CHAR + 1), ==, + (G_UNICODE_LAST_CHAR + 1)); + g_assert_cmphex (g_unichar_tolower (G_UNICODE_LAST_CHAR_PART1), ==, + G_UNICODE_LAST_CHAR_PART1); + g_assert_cmphex (g_unichar_tolower (G_UNICODE_LAST_CHAR_PART1 + 1), ==, + (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_isdefined() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_defined (void) +{ + g_assert_true (g_unichar_isdefined (0x0903)); + g_assert_true (g_unichar_isdefined (0x20DD)); + g_assert_true (g_unichar_isdefined (0x20BA)); + g_assert_true (g_unichar_isdefined (0xA806)); + g_assert_true (g_unichar_isdefined ('a')); + g_assert_false (g_unichar_isdefined (0x10C49)); + g_assert_false (g_unichar_isdefined (0x169D)); + + /*** Testing TYPE() border cases ***/ + g_assert_true (g_unichar_isdefined (0x3FF5)); + /* U+FFEFF Plane 15 Private Use (needed to be > G_UNICODE_MAX_TABLE_INDEX) */ + g_assert_true (g_unichar_isdefined (0xFFEFF)); + g_assert_false (g_unichar_isdefined (0xDFFFF)); + /* U+E0001 Language Tag */ + g_assert_true (g_unichar_isdefined (0xE0001)); + g_assert_false (g_unichar_isdefined (G_UNICODE_LAST_CHAR)); + g_assert_false (g_unichar_isdefined (G_UNICODE_LAST_CHAR + 1)); + g_assert_false (g_unichar_isdefined (G_UNICODE_LAST_CHAR_PART1)); + g_assert_false (g_unichar_isdefined (G_UNICODE_LAST_CHAR_PART1 + 1)); +} + +/* Test that g_unichar_iswide() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_wide (void) +{ + guint i; + struct { + gunichar c; + enum { + NOT_WIDE, + WIDE_CJK, + WIDE + } wide; + } examples[] = { + /* Neutral */ + { 0x0000, NOT_WIDE }, + { 0x0483, NOT_WIDE }, + { 0x0641, NOT_WIDE }, + { 0xFFFC, NOT_WIDE }, + { 0x10000, NOT_WIDE }, + { 0xE0001, NOT_WIDE }, + { 0x2FFFE, NOT_WIDE }, + { 0x3FFFE, NOT_WIDE }, + + /* Narrow */ + { 0x0020, NOT_WIDE }, + { 0x0041, NOT_WIDE }, + { 0x27E6, NOT_WIDE }, + + /* Halfwidth */ + { 0x20A9, NOT_WIDE }, + { 0xFF61, NOT_WIDE }, + { 0xFF69, NOT_WIDE }, + { 0xFFEE, NOT_WIDE }, + + /* Ambiguous */ + { 0x00A1, WIDE_CJK }, + { 0x00BE, WIDE_CJK }, + { 0x02DD, WIDE_CJK }, + { 0x2020, WIDE_CJK }, + { 0xFFFD, WIDE_CJK }, + { 0x00A1, WIDE_CJK }, + { 0x1F100, WIDE_CJK }, + { 0xE0100, WIDE_CJK }, + { 0x100000, WIDE_CJK }, + { 0x10FFFD, WIDE_CJK }, + + /* Fullwidth */ + { 0x3000, WIDE }, + { 0xFF60, WIDE }, + + /* Wide */ + { 0x2329, WIDE }, + { 0x3001, WIDE }, + { 0xFE69, WIDE }, + { 0x30000, WIDE }, + { 0x3FFFD, WIDE }, + + /* Default Wide blocks */ + { 0x4DBF, WIDE }, + { 0x9FFF, WIDE }, + { 0xFAFF, WIDE }, + { 0x2A6DF, WIDE }, + { 0x2B73F, WIDE }, + { 0x2B81F, WIDE }, + { 0x2FA1F, WIDE }, + + /* Uniode-5.2 character additions */ + /* Wide */ + { 0x115F, WIDE }, + + /* Uniode-6.0 character additions */ + /* Wide */ + { 0x2B740, WIDE }, + { 0x1B000, WIDE }, + + { 0x111111, NOT_WIDE } + }; + + for (i = 0; i < G_N_ELEMENTS (examples); i++) + { + g_assert_cmpint (g_unichar_iswide (examples[i].c), ==, + (examples[i].wide == WIDE)); + g_assert_cmpint (g_unichar_iswide_cjk (examples[i].c), ==, + (examples[i].wide != NOT_WIDE)); + } +}; + +/* Test that g_unichar_compose() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_compose (void) +{ + gunichar ch; + + /* Not composable */ + g_assert_false (g_unichar_compose (0x0041, 0x0042, &ch) && ch == 0); + g_assert_false (g_unichar_compose (0x0041, 0, &ch) && ch == 0); + g_assert_false (g_unichar_compose (0x0066, 0x0069, &ch) && ch == 0); + + /* Tricky non-composable */ + g_assert_false (g_unichar_compose (0x0308, 0x0301, &ch) && ch == 0); /* !0x0344 */ + g_assert_false (g_unichar_compose (0x0F71, 0x0F72, &ch) && ch == 0); /* !0x0F73 */ + + /* Singletons should not compose */ + g_assert_false (g_unichar_compose (0x212B, 0, &ch) && ch == 0); + g_assert_false (g_unichar_compose (0x00C5, 0, &ch) && ch == 0); + g_assert_false (g_unichar_compose (0x2126, 0, &ch) && ch == 0); + g_assert_false (g_unichar_compose (0x03A9, 0, &ch) && ch == 0); + + /* Pairs */ + g_assert_true (g_unichar_compose (0x0041, 0x030A, &ch) && ch == 0x00C5); + g_assert_true (g_unichar_compose (0x006F, 0x0302, &ch) && ch == 0x00F4); + g_assert_true (g_unichar_compose (0x1E63, 0x0307, &ch) && ch == 0x1E69); + g_assert_true (g_unichar_compose (0x0073, 0x0323, &ch) && ch == 0x1E63); + g_assert_true (g_unichar_compose (0x0064, 0x0307, &ch) && ch == 0x1E0B); + g_assert_true (g_unichar_compose (0x0064, 0x0323, &ch) && ch == 0x1E0D); + + /* Hangul */ + g_assert_true (g_unichar_compose (0xD4CC, 0x11B6, &ch) && ch == 0xD4DB); + g_assert_true (g_unichar_compose (0x1111, 0x1171, &ch) && ch == 0xD4CC); + g_assert_true (g_unichar_compose (0xCE20, 0x11B8, &ch) && ch == 0xCE31); + g_assert_true (g_unichar_compose (0x110E, 0x1173, &ch) && ch == 0xCE20); +} + +/* Test that g_unichar_decompose() returns the correct value for various + * ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_decompose (void) +{ + gunichar a, b; + + /* Not decomposable */ + g_assert_false (g_unichar_decompose (0x0041, &a, &b) && a == 0x0041 && b == 0); + g_assert_false (g_unichar_decompose (0xFB01, &a, &b) && a == 0xFB01 && b == 0); + + /* Singletons */ + g_assert_true (g_unichar_decompose (0x212B, &a, &b) && a == 0x00C5 && b == 0); + g_assert_true (g_unichar_decompose (0x2126, &a, &b) && a == 0x03A9 && b == 0); + + /* Tricky pairs */ + g_assert_true (g_unichar_decompose (0x0344, &a, &b) && a == 0x0308 && b == 0x0301); + g_assert_true (g_unichar_decompose (0x0F73, &a, &b) && a == 0x0F71 && b == 0x0F72); + + /* Pairs */ + g_assert_true (g_unichar_decompose (0x00C5, &a, &b) && a == 0x0041 && b == 0x030A); + g_assert_true (g_unichar_decompose (0x00F4, &a, &b) && a == 0x006F && b == 0x0302); + g_assert_true (g_unichar_decompose (0x1E69, &a, &b) && a == 0x1E63 && b == 0x0307); + g_assert_true (g_unichar_decompose (0x1E63, &a, &b) && a == 0x0073 && b == 0x0323); + g_assert_true (g_unichar_decompose (0x1E0B, &a, &b) && a == 0x0064 && b == 0x0307); + g_assert_true (g_unichar_decompose (0x1E0D, &a, &b) && a == 0x0064 && b == 0x0323); + + /* Hangul */ + g_assert_true (g_unichar_decompose (0xD4DB, &a, &b) && a == 0xD4CC && b == 0x11B6); + g_assert_true (g_unichar_decompose (0xD4CC, &a, &b) && a == 0x1111 && b == 0x1171); + g_assert_true (g_unichar_decompose (0xCE31, &a, &b) && a == 0xCE20 && b == 0x11B8); + g_assert_true (g_unichar_decompose (0xCE20, &a, &b) && a == 0x110E && b == 0x1173); +} + +/* Test that g_unichar_fully_decompose() returns the correct value for + * various ASCII and Unicode alphabetic, numeric, and other, codepoints. */ +static void +test_fully_decompose_canonical (void) +{ + gunichar decomp[5]; + gsize len; + +#define TEST_DECOMP(ch, expected_len, a, b, c, d) \ + len = g_unichar_fully_decompose (ch, FALSE, decomp, G_N_ELEMENTS (decomp)); \ + g_assert_cmpint (expected_len, ==, len); \ + if (expected_len >= 1) g_assert_cmphex (decomp[0], ==, a); \ + if (expected_len >= 2) g_assert_cmphex (decomp[1], ==, b); \ + if (expected_len >= 3) g_assert_cmphex (decomp[2], ==, c); \ + if (expected_len >= 4) g_assert_cmphex (decomp[3], ==, d); \ + +#define TEST0(ch) TEST_DECOMP (ch, 1, ch, 0, 0, 0) +#define TEST1(ch, a) TEST_DECOMP (ch, 1, a, 0, 0, 0) +#define TEST2(ch, a, b) TEST_DECOMP (ch, 2, a, b, 0, 0) +#define TEST3(ch, a, b, c) TEST_DECOMP (ch, 3, a, b, c, 0) +#define TEST4(ch, a, b, c, d) TEST_DECOMP (ch, 4, a, b, c, d) + + /* Not decomposable */ + TEST0 (0x0041); + TEST0 (0xFB01); + + /* Singletons */ + TEST2 (0x212B, 0x0041, 0x030A); + TEST1 (0x2126, 0x03A9); + + /* Tricky pairs */ + TEST2 (0x0344, 0x0308, 0x0301); + TEST2 (0x0F73, 0x0F71, 0x0F72); + + /* General */ + TEST2 (0x00C5, 0x0041, 0x030A); + TEST2 (0x00F4, 0x006F, 0x0302); + TEST3 (0x1E69, 0x0073, 0x0323, 0x0307); + TEST2 (0x1E63, 0x0073, 0x0323); + TEST2 (0x1E0B, 0x0064, 0x0307); + TEST2 (0x1E0D, 0x0064, 0x0323); + + /* Hangul */ + TEST3 (0xD4DB, 0x1111, 0x1171, 0x11B6); + TEST2 (0xD4CC, 0x1111, 0x1171); + TEST3 (0xCE31, 0x110E, 0x1173, 0x11B8); + TEST2 (0xCE20, 0x110E, 0x1173); + +#undef TEST_DECOMP +} + +/* Test that g_unicode_canonical_decomposition() returns the correct + * value for various ASCII and Unicode alphabetic, numeric, and other, + * codepoints. */ +static void +test_canonical_decomposition (void) +{ + gunichar *decomp; + gsize len; + +#define TEST_DECOMP(ch, expected_len, a, b, c, d) \ + decomp = g_unicode_canonical_decomposition (ch, &len); \ + g_assert_cmpint (expected_len, ==, len); \ + if (expected_len >= 1) g_assert_cmphex (decomp[0], ==, a); \ + if (expected_len >= 2) g_assert_cmphex (decomp[1], ==, b); \ + if (expected_len >= 3) g_assert_cmphex (decomp[2], ==, c); \ + if (expected_len >= 4) g_assert_cmphex (decomp[3], ==, d); \ + g_free (decomp); + +#define TEST0(ch) TEST_DECOMP (ch, 1, ch, 0, 0, 0) +#define TEST1(ch, a) TEST_DECOMP (ch, 1, a, 0, 0, 0) +#define TEST2(ch, a, b) TEST_DECOMP (ch, 2, a, b, 0, 0) +#define TEST3(ch, a, b, c) TEST_DECOMP (ch, 3, a, b, c, 0) +#define TEST4(ch, a, b, c, d) TEST_DECOMP (ch, 4, a, b, c, d) + + /* Not decomposable */ + TEST0 (0x0041); + TEST0 (0xFB01); + + /* Singletons */ + TEST2 (0x212B, 0x0041, 0x030A); + TEST1 (0x2126, 0x03A9); + + /* Tricky pairs */ + TEST2 (0x0344, 0x0308, 0x0301); + TEST2 (0x0F73, 0x0F71, 0x0F72); + + /* General */ + TEST2 (0x00C5, 0x0041, 0x030A); + TEST2 (0x00F4, 0x006F, 0x0302); + TEST3 (0x1E69, 0x0073, 0x0323, 0x0307); + TEST2 (0x1E63, 0x0073, 0x0323); + TEST2 (0x1E0B, 0x0064, 0x0307); + TEST2 (0x1E0D, 0x0064, 0x0323); + + /* Hangul */ + TEST3 (0xD4DB, 0x1111, 0x1171, 0x11B6); + TEST2 (0xD4CC, 0x1111, 0x1171); + TEST3 (0xCE31, 0x110E, 0x1173, 0x11B8); + TEST2 (0xCE20, 0x110E, 0x1173); + +#undef TEST_DECOMP +} + +/* Test that g_unichar_decompose() whenever encouttering a char ch + * decomposes into a and b, b itself won't decompose any further. */ +static void +test_decompose_tail (void) +{ + gunichar ch, a, b, c, d; + + /* Test that whenever a char ch decomposes into a and b, b itself + * won't decompose any further. */ + + for (ch = 0; ch < 0x110000; ch++) + if (g_unichar_decompose (ch, &a, &b)) + g_assert_false (g_unichar_decompose (b, &c, &d)); + else + { + g_assert_cmpuint (a, ==, ch); + g_assert_cmpuint (b, ==, 0); + } +} + +/* Test that all canonical decompositions of g_unichar_fully_decompose() + * are at most 4 in length, and compatibility decompositions are + * at most 18 in length. */ +static void +test_fully_decompose_len (void) +{ + gunichar ch; + + /* Test that all canonical decompositions are at most 4 in length, + * and compatibility decompositions are at most 18 in length. + */ + + for (ch = 0; ch < 0x110000; ch++) { + g_assert_cmpint (g_unichar_fully_decompose (ch, FALSE, NULL, 0), <=, 4); + g_assert_cmpint (g_unichar_fully_decompose (ch, TRUE, NULL, 0), <=, 18); + } +} + +/* Check various examples from Unicode Annex #15 for NFD and NFC + * normalization. + */ +static void +test_normalization (void) +{ + const struct { + const char *source; + const char *nfd; + const char *nfc; + } tests[] = { + // Singletons + { "\xe2\x84\xab", "A\xcc\x8a", "Ã…" }, // U+212B ANGSTROM SIGN + { "\xe2\x84\xa6", "Ω", "Ω" }, // U+2126 OHM SIGN + // Canonical Composites + { "Ã…", "A\xcc\x8a", "Ã…" }, // U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE + { "ô", "o\xcc\x82", "ô" }, // U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX + // Multiple Combining Marks + { "\xe1\xb9\xa9", "s\xcc\xa3\xcc\x87", "ṩ" }, // U+1E69 LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE + { "\xe1\xb8\x8b\xcc\xa3", "d\xcc\xa3\xcc\x87", "á¸Ì‡" }, + { "q\xcc\x87\xcc\xa3", "q\xcc\xa3\xcc\x87", "q̣̇" }, + // Compatibility Composites + { "ï¬", "ï¬", "ï¬" }, // U+FB01 LATIN SMALL LIGATURE FI + { "2\xe2\x81\xb5", "2\xe2\x81\xb5", "2âµ" }, + { "\xe1\xba\x9b\xcc\xa3", "\xc5\xbf\xcc\xa3\xcc\x87", "ẛ̣" }, + + // Tests for behavior with reordered marks + { "s\xcc\x87\xcc\xa3", "s\xcc\xa3\xcc\x87", "ṩ" }, + { "α\xcc\x94\xcd\x82", "α\xcc\x94\xcd\x82", "ἇ" }, + { "α\xcd\x82\xcc\x94", "α\xcd\x82\xcc\x94", "á¾¶\xcc\x94" }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + char *nfd, *nfc; + + nfd = g_utf8_normalize (tests[i].source, -1, G_NORMALIZE_NFD); + g_assert_cmpstr (nfd, ==, tests[i].nfd); + + nfc = g_utf8_normalize (tests[i].nfd, -1, G_NORMALIZE_NFC); + g_assert_cmpstr (nfc, ==, tests[i].nfc); + + g_free (nfd); + g_free (nfc); + } +} + +static void +test_iso15924 (void) +{ + const struct { + GUnicodeScript script; + char four_letter_code[5]; + } data[] = { + { G_UNICODE_SCRIPT_COMMON, "Zyyy" }, + { G_UNICODE_SCRIPT_INHERITED, "Zinh" }, + { G_UNICODE_SCRIPT_MATH, "Zmth" }, + { G_UNICODE_SCRIPT_ARABIC, "Arab" }, + { G_UNICODE_SCRIPT_ARMENIAN, "Armn" }, + { G_UNICODE_SCRIPT_BENGALI, "Beng" }, + { G_UNICODE_SCRIPT_BOPOMOFO, "Bopo" }, + { G_UNICODE_SCRIPT_CHEROKEE, "Cher" }, + { G_UNICODE_SCRIPT_COPTIC, "Copt" }, + { G_UNICODE_SCRIPT_CYRILLIC, "Cyrl" }, + { G_UNICODE_SCRIPT_DESERET, "Dsrt" }, + { G_UNICODE_SCRIPT_DEVANAGARI, "Deva" }, + { G_UNICODE_SCRIPT_ETHIOPIC, "Ethi" }, + { G_UNICODE_SCRIPT_GEORGIAN, "Geor" }, + { G_UNICODE_SCRIPT_GOTHIC, "Goth" }, + { G_UNICODE_SCRIPT_GREEK, "Grek" }, + { G_UNICODE_SCRIPT_GUJARATI, "Gujr" }, + { G_UNICODE_SCRIPT_GURMUKHI, "Guru" }, + { G_UNICODE_SCRIPT_HAN, "Hani" }, + { G_UNICODE_SCRIPT_HANGUL, "Hang" }, + { G_UNICODE_SCRIPT_HEBREW, "Hebr" }, + { G_UNICODE_SCRIPT_HIRAGANA, "Hira" }, + { G_UNICODE_SCRIPT_KANNADA, "Knda" }, + { G_UNICODE_SCRIPT_KATAKANA, "Kana" }, + { G_UNICODE_SCRIPT_KHMER, "Khmr" }, + { G_UNICODE_SCRIPT_LAO, "Laoo" }, + { G_UNICODE_SCRIPT_LATIN, "Latn" }, + { G_UNICODE_SCRIPT_MALAYALAM, "Mlym" }, + { G_UNICODE_SCRIPT_MONGOLIAN, "Mong" }, + { G_UNICODE_SCRIPT_MYANMAR, "Mymr" }, + { G_UNICODE_SCRIPT_OGHAM, "Ogam" }, + { G_UNICODE_SCRIPT_OLD_ITALIC, "Ital" }, + { G_UNICODE_SCRIPT_ORIYA, "Orya" }, + { G_UNICODE_SCRIPT_RUNIC, "Runr" }, + { G_UNICODE_SCRIPT_SINHALA, "Sinh" }, + { G_UNICODE_SCRIPT_SYRIAC, "Syrc" }, + { G_UNICODE_SCRIPT_TAMIL, "Taml" }, + { G_UNICODE_SCRIPT_TELUGU, "Telu" }, + { G_UNICODE_SCRIPT_THAANA, "Thaa" }, + { G_UNICODE_SCRIPT_THAI, "Thai" }, + { G_UNICODE_SCRIPT_TIBETAN, "Tibt" }, + { G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, "Cans" }, + { G_UNICODE_SCRIPT_YI, "Yiii" }, + { G_UNICODE_SCRIPT_TAGALOG, "Tglg" }, + { G_UNICODE_SCRIPT_HANUNOO, "Hano" }, + { G_UNICODE_SCRIPT_BUHID, "Buhd" }, + { G_UNICODE_SCRIPT_TAGBANWA, "Tagb" }, + + /* Unicode-4.0 additions */ + { G_UNICODE_SCRIPT_BRAILLE, "Brai" }, + { G_UNICODE_SCRIPT_CYPRIOT, "Cprt" }, + { G_UNICODE_SCRIPT_LIMBU, "Limb" }, + { G_UNICODE_SCRIPT_OSMANYA, "Osma" }, + { G_UNICODE_SCRIPT_SHAVIAN, "Shaw" }, + { G_UNICODE_SCRIPT_LINEAR_B, "Linb" }, + { G_UNICODE_SCRIPT_TAI_LE, "Tale" }, + { G_UNICODE_SCRIPT_UGARITIC, "Ugar" }, + + /* Unicode-4.1 additions */ + { G_UNICODE_SCRIPT_NEW_TAI_LUE, "Talu" }, + { G_UNICODE_SCRIPT_BUGINESE, "Bugi" }, + { G_UNICODE_SCRIPT_GLAGOLITIC, "Glag" }, + { G_UNICODE_SCRIPT_TIFINAGH, "Tfng" }, + { G_UNICODE_SCRIPT_SYLOTI_NAGRI, "Sylo" }, + { G_UNICODE_SCRIPT_OLD_PERSIAN, "Xpeo" }, + { G_UNICODE_SCRIPT_KHAROSHTHI, "Khar" }, + + /* Unicode-5.0 additions */ + { G_UNICODE_SCRIPT_UNKNOWN, "Zzzz" }, + { G_UNICODE_SCRIPT_BALINESE, "Bali" }, + { G_UNICODE_SCRIPT_CUNEIFORM, "Xsux" }, + { G_UNICODE_SCRIPT_PHOENICIAN, "Phnx" }, + { G_UNICODE_SCRIPT_PHAGS_PA, "Phag" }, + { G_UNICODE_SCRIPT_NKO, "Nkoo" }, + + /* Unicode-5.1 additions */ + { G_UNICODE_SCRIPT_KAYAH_LI, "Kali" }, + { G_UNICODE_SCRIPT_LEPCHA, "Lepc" }, + { G_UNICODE_SCRIPT_REJANG, "Rjng" }, + { G_UNICODE_SCRIPT_SUNDANESE, "Sund" }, + { G_UNICODE_SCRIPT_SAURASHTRA, "Saur" }, + { G_UNICODE_SCRIPT_CHAM, "Cham" }, + { G_UNICODE_SCRIPT_OL_CHIKI, "Olck" }, + { G_UNICODE_SCRIPT_VAI, "Vaii" }, + { G_UNICODE_SCRIPT_CARIAN, "Cari" }, + { G_UNICODE_SCRIPT_LYCIAN, "Lyci" }, + { G_UNICODE_SCRIPT_LYDIAN, "Lydi" }, + + /* Unicode-5.2 additions */ + { G_UNICODE_SCRIPT_AVESTAN, "Avst" }, + { G_UNICODE_SCRIPT_BAMUM, "Bamu" }, + { G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS, "Egyp" }, + { G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC, "Armi" }, + { G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI, "Phli" }, + { G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN, "Prti" }, + { G_UNICODE_SCRIPT_JAVANESE, "Java" }, + { G_UNICODE_SCRIPT_KAITHI, "Kthi" }, + { G_UNICODE_SCRIPT_LISU, "Lisu" }, + { G_UNICODE_SCRIPT_MEETEI_MAYEK, "Mtei" }, + { G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN, "Sarb" }, + { G_UNICODE_SCRIPT_OLD_TURKIC, "Orkh" }, + { G_UNICODE_SCRIPT_SAMARITAN, "Samr" }, + { G_UNICODE_SCRIPT_TAI_THAM, "Lana" }, + { G_UNICODE_SCRIPT_TAI_VIET, "Tavt" }, + + /* Unicode-6.0 additions */ + { G_UNICODE_SCRIPT_BATAK, "Batk" }, + { G_UNICODE_SCRIPT_BRAHMI, "Brah" }, + { G_UNICODE_SCRIPT_MANDAIC, "Mand" }, + + /* Unicode-6.1 additions */ + { G_UNICODE_SCRIPT_CHAKMA, "Cakm" }, + { G_UNICODE_SCRIPT_MEROITIC_CURSIVE, "Merc" }, + { G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS, "Mero" }, + { G_UNICODE_SCRIPT_MIAO, "Plrd" }, + { G_UNICODE_SCRIPT_SHARADA, "Shrd" }, + { G_UNICODE_SCRIPT_SORA_SOMPENG, "Sora" }, + { G_UNICODE_SCRIPT_TAKRI, "Takr" }, + + /* Unicode 7.0 additions */ + { G_UNICODE_SCRIPT_BASSA_VAH, "Bass" }, + { G_UNICODE_SCRIPT_CAUCASIAN_ALBANIAN, "Aghb" }, + { G_UNICODE_SCRIPT_DUPLOYAN, "Dupl" }, + { G_UNICODE_SCRIPT_ELBASAN, "Elba" }, + { G_UNICODE_SCRIPT_GRANTHA, "Gran" }, + { G_UNICODE_SCRIPT_KHOJKI, "Khoj" }, + { G_UNICODE_SCRIPT_KHUDAWADI, "Sind" }, + { G_UNICODE_SCRIPT_LINEAR_A, "Lina" }, + { G_UNICODE_SCRIPT_MAHAJANI, "Mahj" }, + { G_UNICODE_SCRIPT_MANICHAEAN, "Mani" }, + { G_UNICODE_SCRIPT_MENDE_KIKAKUI, "Mend" }, + { G_UNICODE_SCRIPT_MODI, "Modi" }, + { G_UNICODE_SCRIPT_MRO, "Mroo" }, + { G_UNICODE_SCRIPT_NABATAEAN, "Nbat" }, + { G_UNICODE_SCRIPT_OLD_NORTH_ARABIAN, "Narb" }, + { G_UNICODE_SCRIPT_OLD_PERMIC, "Perm" }, + { G_UNICODE_SCRIPT_PAHAWH_HMONG, "Hmng" }, + { G_UNICODE_SCRIPT_PALMYRENE, "Palm" }, + { G_UNICODE_SCRIPT_PAU_CIN_HAU, "Pauc" }, + { G_UNICODE_SCRIPT_PSALTER_PAHLAVI, "Phlp" }, + { G_UNICODE_SCRIPT_SIDDHAM, "Sidd" }, + { G_UNICODE_SCRIPT_TIRHUTA, "Tirh" }, + { G_UNICODE_SCRIPT_WARANG_CITI, "Wara" }, + + /* Unicode 8.0 additions */ + { G_UNICODE_SCRIPT_AHOM, "Ahom" }, + { G_UNICODE_SCRIPT_ANATOLIAN_HIEROGLYPHS, "Hluw" }, + { G_UNICODE_SCRIPT_HATRAN, "Hatr" }, + { G_UNICODE_SCRIPT_MULTANI, "Mult" }, + { G_UNICODE_SCRIPT_OLD_HUNGARIAN, "Hung" }, + { G_UNICODE_SCRIPT_SIGNWRITING, "Sgnw" }, + + /* Unicode 9.0 additions */ + { G_UNICODE_SCRIPT_ADLAM, "Adlm" }, + { G_UNICODE_SCRIPT_BHAIKSUKI, "Bhks" }, + { G_UNICODE_SCRIPT_MARCHEN, "Marc" }, + { G_UNICODE_SCRIPT_NEWA, "Newa" }, + { G_UNICODE_SCRIPT_OSAGE, "Osge" }, + { G_UNICODE_SCRIPT_TANGUT, "Tang" }, + + /* Unicode 10.0 additions */ + { G_UNICODE_SCRIPT_MASARAM_GONDI, "Gonm" }, + { G_UNICODE_SCRIPT_NUSHU, "Nshu" }, + { G_UNICODE_SCRIPT_SOYOMBO, "Soyo" }, + { G_UNICODE_SCRIPT_ZANABAZAR_SQUARE, "Zanb" }, + + /* Unicode 11.0 additions */ + { G_UNICODE_SCRIPT_DOGRA, "Dogr" }, + { G_UNICODE_SCRIPT_GUNJALA_GONDI, "Gong" }, + { G_UNICODE_SCRIPT_HANIFI_ROHINGYA, "Rohg" }, + { G_UNICODE_SCRIPT_MAKASAR, "Maka" }, + { G_UNICODE_SCRIPT_MEDEFAIDRIN, "Medf" }, + { G_UNICODE_SCRIPT_OLD_SOGDIAN, "Sogo" }, + { G_UNICODE_SCRIPT_SOGDIAN, "Sogd" }, + + /* Unicode 12.0 additions */ + { G_UNICODE_SCRIPT_ELYMAIC, "Elym" }, + { G_UNICODE_SCRIPT_NANDINAGARI, "Nand" }, + { G_UNICODE_SCRIPT_NYIAKENG_PUACHUE_HMONG, "Hmnp" }, + { G_UNICODE_SCRIPT_WANCHO, "Wcho" }, + + /* Unicode 13.0 additions */ + { G_UNICODE_SCRIPT_CHORASMIAN, "Chrs" }, + { G_UNICODE_SCRIPT_DIVES_AKURU, "Diak" }, + { G_UNICODE_SCRIPT_KHITAN_SMALL_SCRIPT, "Kits" }, + { G_UNICODE_SCRIPT_YEZIDI, "Yezi" }, + + /* Unicode 14.0 additions */ + { G_UNICODE_SCRIPT_CYPRO_MINOAN, "Cpmn" }, + { G_UNICODE_SCRIPT_OLD_UYGHUR, "Ougr" }, + { G_UNICODE_SCRIPT_TANGSA, "Tnsa" }, + { G_UNICODE_SCRIPT_TOTO, "Toto" }, + { G_UNICODE_SCRIPT_VITHKUQI, "Vith" } + }; + guint i; + + g_assert_cmphex (0, ==, + g_unicode_script_to_iso15924 (G_UNICODE_SCRIPT_INVALID_CODE)); + g_assert_cmphex (0x5A7A7A7A, ==, g_unicode_script_to_iso15924 (1000)); + g_assert_cmphex (0x41726162, ==, + g_unicode_script_to_iso15924 (G_UNICODE_SCRIPT_ARABIC)); + + g_assert_cmphex (G_UNICODE_SCRIPT_INVALID_CODE, ==, + g_unicode_script_from_iso15924 (0)); + g_assert_cmphex (G_UNICODE_SCRIPT_UNKNOWN, ==, + g_unicode_script_from_iso15924 (0x12345678)); + +#define PACK(a,b,c,d) \ + ((guint32)((((guint8)(a))<<24)|(((guint8)(b))<<16)|(((guint8)(c))<<8)|((guint8)(d)))) + + for (i = 0; i < G_N_ELEMENTS (data); i++) + { + guint32 code = PACK (data[i].four_letter_code[0], + data[i].four_letter_code[1], + data[i].four_letter_code[2], + data[i].four_letter_code[3]); + + g_assert_cmphex (g_unicode_script_to_iso15924 (data[i].script), ==, code); + g_assert_cmpint (g_unicode_script_from_iso15924 (code), ==, data[i].script); + } + +#undef PACK +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/unicode/alnum", test_alnum); + g_test_add_func ("/unicode/alpha", test_alpha); + g_test_add_func ("/unicode/break-type", test_unichar_break_type); + g_test_add_func ("/unicode/canonical-decomposition", test_canonical_decomposition); + g_test_add_func ("/unicode/casefold", test_casefold); + g_test_add_func ("/unicode/casemap_and_casefold", test_casemap_and_casefold); + g_test_add_func ("/unicode/cases", test_cases); + g_test_add_func ("/unicode/character-type", test_unichar_character_type); + g_test_add_func ("/unicode/cntrl", test_cntrl); + g_test_add_func ("/unicode/combining-class", test_combining_class); + g_test_add_func ("/unicode/compose", test_compose); + g_test_add_func ("/unicode/decompose", test_decompose); + g_test_add_func ("/unicode/decompose-tail", test_decompose_tail); + g_test_add_func ("/unicode/defined", test_defined); + g_test_add_func ("/unicode/digit", test_digit); + g_test_add_func ("/unicode/digit-value", test_digit_value); + g_test_add_func ("/unicode/fully-decompose-canonical", test_fully_decompose_canonical); + g_test_add_func ("/unicode/fully-decompose-len", test_fully_decompose_len); + g_test_add_func ("/unicode/normalization", test_normalization); + g_test_add_func ("/unicode/graph", test_graph); + g_test_add_func ("/unicode/iso15924", test_iso15924); + g_test_add_func ("/unicode/lower", test_lower); + g_test_add_func ("/unicode/mark", test_mark); + g_test_add_func ("/unicode/mirror", test_mirror); + g_test_add_func ("/unicode/print", test_print); + g_test_add_func ("/unicode/punctuation", test_punctuation); + g_test_add_func ("/unicode/script", test_unichar_script); + g_test_add_func ("/unicode/space", test_space); + g_test_add_func ("/unicode/strdown", test_strdown); + g_test_add_func ("/unicode/strup", test_strup); + g_test_add_func ("/unicode/turkish-strupdown", test_turkish_strupdown); + g_test_add_func ("/unicode/title", test_title); + g_test_add_func ("/unicode/upper", test_upper); + g_test_add_func ("/unicode/validate", test_unichar_validate); + g_test_add_func ("/unicode/wide", test_wide); + g_test_add_func ("/unicode/xdigit", test_xdigit); + g_test_add_func ("/unicode/xdigit-value", test_xdigit_value); + g_test_add_func ("/unicode/zero-width", test_zerowidth); + + return g_test_run(); +} diff --git a/glib/tests/unix.c b/glib/tests/unix.c new file mode 100644 index 0000000..7639d06 --- /dev/null +++ b/glib/tests/unix.c @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2011 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include "glib-unix.h" +#include +#include + +static void +test_pipe (void) +{ + GError *error = NULL; + int pipefd[2]; + char buf[1024]; + gssize bytes_read; + gboolean res; + + res = g_unix_open_pipe (pipefd, FD_CLOEXEC, &error); + g_assert (res); + g_assert_no_error (error); + + write (pipefd[1], "hello", sizeof ("hello")); + memset (buf, 0, sizeof (buf)); + bytes_read = read (pipefd[0], buf, sizeof(buf) - 1); + g_assert_cmpint (bytes_read, >, 0); + buf[bytes_read] = '\0'; + + close (pipefd[0]); + close (pipefd[1]); + + g_assert (g_str_has_prefix (buf, "hello")); +} + +static void +test_error (void) +{ + GError *error = NULL; + gboolean res; + + res = g_unix_set_fd_nonblocking (123456, TRUE, &error); + g_assert_cmpint (errno, ==, EBADF); + g_assert (!res); + g_assert_error (error, G_UNIX_ERROR, 0); + g_clear_error (&error); +} + +static void +test_nonblocking (void) +{ + GError *error = NULL; + int pipefd[2]; + gboolean res; + int flags; + + res = g_unix_open_pipe (pipefd, FD_CLOEXEC, &error); + g_assert (res); + g_assert_no_error (error); + + res = g_unix_set_fd_nonblocking (pipefd[0], TRUE, &error); + g_assert (res); + g_assert_no_error (error); + + flags = fcntl (pipefd[0], F_GETFL); + g_assert_cmpint (flags, !=, -1); + g_assert (flags & O_NONBLOCK); + + res = g_unix_set_fd_nonblocking (pipefd[0], FALSE, &error); + g_assert (res); + g_assert_no_error (error); + + flags = fcntl (pipefd[0], F_GETFL); + g_assert_cmpint (flags, !=, -1); + g_assert (!(flags & O_NONBLOCK)); + + close (pipefd[0]); + close (pipefd[1]); +} + +static gboolean sig_received = FALSE; +static gboolean sig_timeout = FALSE; +static int sig_counter = 0; + +static gboolean +on_sig_received (gpointer user_data) +{ + GMainLoop *loop = user_data; + g_main_loop_quit (loop); + sig_received = TRUE; + sig_counter ++; + return G_SOURCE_REMOVE; +} + +static gboolean +on_sig_timeout (gpointer data) +{ + GMainLoop *loop = data; + g_main_loop_quit (loop); + sig_timeout = TRUE; + return G_SOURCE_REMOVE; +} + +static gboolean +exit_mainloop (gpointer data) +{ + GMainLoop *loop = data; + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; +} + +static gboolean +on_sig_received_2 (gpointer data) +{ + GMainLoop *loop = data; + + sig_counter ++; + if (sig_counter == 2) + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; +} + +static void +test_signal (int signum) +{ + GMainLoop *mainloop; + int id; + + mainloop = g_main_loop_new (NULL, FALSE); + + sig_received = FALSE; + sig_counter = 0; + g_unix_signal_add (signum, on_sig_received, mainloop); + kill (getpid (), signum); + g_assert (!sig_received); + id = g_timeout_add (5000, on_sig_timeout, mainloop); + g_main_loop_run (mainloop); + g_assert (sig_received); + sig_received = FALSE; + g_source_remove (id); + + /* Ensure we don't get double delivery */ + g_timeout_add (500, exit_mainloop, mainloop); + g_main_loop_run (mainloop); + g_assert (!sig_received); + + /* Ensure that two sources for the same signal get it */ + sig_counter = 0; + g_unix_signal_add (signum, on_sig_received_2, mainloop); + g_unix_signal_add (signum, on_sig_received_2, mainloop); + id = g_timeout_add (5000, on_sig_timeout, mainloop); + + kill (getpid (), signum); + g_main_loop_run (mainloop); + g_assert_cmpint (sig_counter, ==, 2); + g_source_remove (id); + + g_main_loop_unref (mainloop); +} + +static void +test_sighup (void) +{ + test_signal (SIGHUP); +} + +static void +test_sigterm (void) +{ + test_signal (SIGTERM); +} + +static void +test_sighup_add_remove (void) +{ + guint id; + struct sigaction action; + + sig_received = FALSE; + id = g_unix_signal_add (SIGHUP, on_sig_received, NULL); + g_source_remove (id); + + sigaction (SIGHUP, NULL, &action); + g_assert (action.sa_handler == SIG_DFL); +} + +static gboolean +nested_idle (gpointer data) +{ + GMainLoop *nested; + GMainContext *context; + GSource *source; + + context = g_main_context_new (); + nested = g_main_loop_new (context, FALSE); + + source = g_unix_signal_source_new (SIGHUP); + g_source_set_callback (source, on_sig_received, nested, NULL); + g_source_attach (source, context); + g_source_unref (source); + + kill (getpid (), SIGHUP); + g_main_loop_run (nested); + g_assert_cmpint (sig_counter, ==, 1); + + g_main_loop_unref (nested); + g_main_context_unref (context); + + return G_SOURCE_REMOVE; +} + +static void +test_sighup_nested (void) +{ + GMainLoop *mainloop; + + mainloop = g_main_loop_new (NULL, FALSE); + + sig_counter = 0; + sig_received = FALSE; + g_unix_signal_add (SIGHUP, on_sig_received, mainloop); + g_idle_add (nested_idle, mainloop); + + g_main_loop_run (mainloop); + g_assert_cmpint (sig_counter, ==, 2); + + g_main_loop_unref (mainloop); +} + +static gboolean +on_sigwinch_received (gpointer data) +{ + GMainLoop *loop = (GMainLoop *) data; + + sig_counter ++; + + if (sig_counter == 1) + kill (getpid (), SIGWINCH); + else if (sig_counter == 2) + g_main_loop_quit (loop); + else if (sig_counter > 2) + g_assert_not_reached (); + + /* Increase the time window in which an issue could happen. */ + g_usleep (G_USEC_PER_SEC); + + return G_SOURCE_CONTINUE; +} + +static void +test_callback_after_signal (void) +{ + /* Checks that user signal callback is invoked *after* receiving a signal. + * In other words a new signal is never merged with the one being currently + * dispatched or whose dispatch had already finished. */ + + GMainLoop *mainloop; + GMainContext *context; + GSource *source; + + sig_counter = 0; + + context = g_main_context_new (); + mainloop = g_main_loop_new (context, FALSE); + + source = g_unix_signal_source_new (SIGWINCH); + g_source_set_callback (source, on_sigwinch_received, mainloop, NULL); + g_source_attach (source, context); + g_source_unref (source); + + g_assert_cmpint (sig_counter, ==, 0); + kill (getpid (), SIGWINCH); + g_main_loop_run (mainloop); + g_assert_cmpint (sig_counter, ==, 2); + + g_main_loop_unref (mainloop); + g_main_context_unref (context); +} + +static void +test_get_passwd_entry_root (void) +{ + struct passwd *pwd; + GError *local_error = NULL; + + g_test_summary ("Tests that g_unix_get_passwd_entry() works for a " + "known-existing username."); + + pwd = g_unix_get_passwd_entry ("root", &local_error); + g_assert_no_error (local_error); + + g_assert_cmpstr (pwd->pw_name, ==, "root"); + g_assert_cmpuint (pwd->pw_uid, ==, 0); + + g_free (pwd); +} + +static void +test_get_passwd_entry_nonexistent (void) +{ + struct passwd *pwd; + GError *local_error = NULL; + + g_test_summary ("Tests that g_unix_get_passwd_entry() returns an error for a " + "nonexistent username."); + + pwd = g_unix_get_passwd_entry ("thisusernamedoesntexist", &local_error); + g_assert_error (local_error, G_UNIX_ERROR, 0); + g_assert_null (pwd); + + g_clear_error (&local_error); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/glib-unix/pipe", test_pipe); + g_test_add_func ("/glib-unix/error", test_error); + g_test_add_func ("/glib-unix/nonblocking", test_nonblocking); + g_test_add_func ("/glib-unix/sighup", test_sighup); + g_test_add_func ("/glib-unix/sigterm", test_sigterm); + g_test_add_func ("/glib-unix/sighup_again", test_sighup); + g_test_add_func ("/glib-unix/sighup_add_remove", test_sighup_add_remove); + g_test_add_func ("/glib-unix/sighup_nested", test_sighup_nested); + g_test_add_func ("/glib-unix/callback_after_signal", test_callback_after_signal); + g_test_add_func ("/glib-unix/get-passwd-entry/root", test_get_passwd_entry_root); + g_test_add_func ("/glib-unix/get-passwd-entry/nonexistent", test_get_passwd_entry_nonexistent); + + return g_test_run(); +} diff --git a/glib/tests/uri.c b/glib/tests/uri.c new file mode 100644 index 0000000..e1ad7cf --- /dev/null +++ b/glib/tests/uri.c @@ -0,0 +1,2057 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include +#include +#include +#include + +typedef struct +{ + char *filename; + char *hostname; + char *expected_result; + gint expected_error; /* If failed */ +} FileToUriTest; + +FileToUriTest +file_to_uri_tests[] = { + { "/etc", NULL, "file:///etc", 0 }, + { "/etc", "", "file:///etc", 0 }, + { "/etc", "otherhost", "file://otherhost/etc", 0 }, +#ifdef G_OS_WIN32 + { "/etc", "localhost", "file:///etc", 0 }, + { "c:\\windows", NULL, "file:///c:/windows", 0 }, + { "c:\\windows", "localhost", "file:///c:/windows", 0 }, + { "c:\\windows", "otherhost", "file://otherhost/c:/windows", 0 }, + { "\\\\server\\share\\dir", NULL, "file:////server/share/dir", 0 }, + { "\\\\server\\share\\dir", "localhost", "file:////server/share/dir", 0 }, +#else + { "/etc", "localhost", "file://localhost/etc", 0 }, + { "c:\\windows", NULL, NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, /* it's important to get this error on Unix */ + { "c:\\windows", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, + { "c:\\windows", "otherhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, +#endif + { "etc", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, +#ifndef G_PLATFORM_WIN32 + { "/etc/\xE5\xE4\xF6", NULL, "file:///etc/%E5%E4%F6", 0 }, + { "/etc/\xC3\xB6\xC3\xA4\xC3\xA5", NULL, "file:///etc/%C3%B6%C3%A4%C3%A5", 0 }, +#endif + { "/etc", "\xC3\xB6\xC3\xA4\xC3\xA5", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/etc", "\xE5\xE4\xF6", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/etc/file with #%", NULL, "file:///etc/file%20with%20%23%25", 0 }, + { "", NULL, NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, + { "", "", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, + { "", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, + { "", "otherhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, + { "/0123456789", NULL, "file:///0123456789", 0 }, + { "/ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL, "file:///ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 }, + { "/abcdefghijklmnopqrstuvwxyz", NULL, "file:///abcdefghijklmnopqrstuvwxyz", 0 }, + { "/-_.!~*'()", NULL, "file:///-_.!~*'()", 0 }, +#ifdef G_OS_WIN32 + /* As '\\' is a path separator on Win32, it gets turned into '/' in the URI */ + { "/\"#%<>[\\]^`{|}\x7F", NULL, "file:///%22%23%25%3C%3E%5B/%5D%5E%60%7B%7C%7D%7F", 0 }, +#else + /* On Unix, '\\' is a normal character in the file name */ + { "/\"#%<>[\\]^`{|}\x7F", NULL, "file:///%22%23%25%3C%3E%5B%5C%5D%5E%60%7B%7C%7D%7F", 0 }, +#endif + { "/;@+$,", NULL, "file:///%3B@+$,", 0 }, + /* This and some of the following are of course as such illegal file names on Windows, + * and would not occur in real life. + */ + { "/:", NULL, "file:///:", 0 }, + { "/?&=", NULL, "file:///%3F&=", 0 }, + { "/", "0123456789-", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "file://ABCDEFGHIJKLMNOPQRSTUVWXYZ/", 0 }, + { "/", "abcdefghijklmnopqrstuvwxyz", "file://abcdefghijklmnopqrstuvwxyz/", 0 }, + { "/", "_.!~*'()", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/", "\"#%<>[\\]^`{|}\x7F", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/", ";?&=+$,", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/", "/", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/", "@:", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/", "\x80\xFF", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, + { "/", "\xC3\x80\xC3\xBF", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE}, +}; + + +typedef struct +{ + char *uri; + char *expected_filename; + char *expected_hostname; + gint expected_error; /* If failed */ +} FileFromUriTest; + +FileFromUriTest +file_from_uri_tests[] = { + { "file:///etc", "/etc", NULL, 0 }, + { "FILE:///etc", "/etc", NULL, 0 }, + { "file:/etc", "/etc", NULL, 0 }, +#ifdef G_OS_WIN32 + /* On Win32 we don't return "localhost" hostames, just in case + * it isn't recognized anyway. + */ + { "file://localhost/etc", "/etc", NULL, 0 }, + { "file://localhost/etc/%23%25%20file", "/etc/#% file", NULL, 0 }, + { "file://localhost/\xE5\xE4\xF6", "/\xe5\xe4\xf6", NULL, 0 }, + { "file://localhost/%E5%E4%F6", "/\xe5\xe4\xf6", NULL, 0 }, +#else + { "file://localhost/etc", "/etc", "localhost", 0 }, + { "file://localhost/etc/%23%25%20file", "/etc/#% file", "localhost", 0 }, + { "file://localhost/\xE5\xE4\xF6", "/\xe5\xe4\xf6", "localhost", 0 }, + { "file://localhost/%E5%E4%F6", "/\xe5\xe4\xf6", "localhost", 0 }, +#endif + { "file://otherhost/etc", "/etc", "otherhost", 0 }, + { "file://otherhost/etc/%23%25%20file", "/etc/#% file", "otherhost", 0 }, + { "file://%C3%B6%C3%A4%C3%A5/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file:////etc/%C3%B6%C3%C3%C3%A5", "//etc/\xc3\xb6\xc3\xc3\xc3\xa5", NULL, 0 }, + { "file://\xE5\xE4\xF6/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://%E5%E4%F6/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file:///some/file#bad", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://some", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file:test", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "http://www.yahoo.com/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file:////etc", "//etc", NULL, 0 }, + { "file://///etc", "///etc", NULL, 0 }, +#ifdef G_OS_WIN32 + /* URIs with backslashes come from some nonstandard application, but accept them anyhow */ + { "file:///c:\\foo", "c:\\foo", NULL, 0 }, + { "file:///c:/foo\\bar", "c:\\foo\\bar", NULL, 0 }, + /* Accept also the old Netscape drive-letter-and-vertical bar convention */ + { "file:///c|/foo", "c:\\foo", NULL, 0 }, + { "file:////server/share/dir", "\\\\server\\share\\dir", NULL, 0 }, + { "file://localhost//server/share/foo", "\\\\server\\share\\foo", NULL, 0 }, + { "file://otherhost//server/share/foo", "\\\\server\\share\\foo", "otherhost", 0 }, +#else + { "file:///c:\\foo", "/c:\\foo", NULL, 0 }, + { "file:///c:/foo", "/c:/foo", NULL, 0 }, + { "file:////c:/foo", "//c:/foo", NULL, 0 }, +#endif + { "file://0123456789/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://ABCDEFGHIJKLMNOPQRSTUVWXYZ/", "/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 }, + { "file://abcdefghijklmnopqrstuvwxyz/", "/", "abcdefghijklmnopqrstuvwxyz", 0 }, + { "file://-_.!~*'()/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://\"<>[\\]^`{|}\x7F/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://;?&=+$,/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://%C3%80%C3%BF/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://@/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://:/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://#/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://%23/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, + { "file://%2F/", NULL, NULL, G_CONVERT_ERROR_BAD_URI}, +}; + +static void +run_file_to_uri_tests (void) +{ + gsize i; + gchar *res; + GError *error; + + for (i = 0; i < G_N_ELEMENTS (file_to_uri_tests); i++) + { + error = NULL; + res = g_filename_to_uri (file_to_uri_tests[i].filename, + file_to_uri_tests[i].hostname, + &error); + + if (res) + g_assert_cmpstr (res, ==, file_to_uri_tests[i].expected_result); + else + g_assert_error (error, G_CONVERT_ERROR, file_to_uri_tests[i].expected_error); + + g_free (res); + g_clear_error (&error); + } +} + +static void +run_file_from_uri_tests (void) +{ + gsize i; + gchar *res; + gchar *hostname; + GError *error; + + for (i = 0; i < G_N_ELEMENTS (file_from_uri_tests); i++) + { + error = NULL; + res = g_filename_from_uri (file_from_uri_tests[i].uri, + &hostname, + &error); + +#ifdef G_OS_WIN32 + if (file_from_uri_tests[i].expected_filename) + { + gchar *p, *slash; + p = file_from_uri_tests[i].expected_filename = + g_strdup (file_from_uri_tests[i].expected_filename); + while ((slash = strchr (p, '/')) != NULL) + { + *slash = '\\'; + p = slash + 1; + } + } +#endif + if (res) + g_assert_cmpstr (res, ==, file_from_uri_tests[i].expected_filename); + else + g_assert_error (error, G_CONVERT_ERROR, file_from_uri_tests[i].expected_error); + g_assert_cmpstr (hostname, ==, file_from_uri_tests[i].expected_hostname); + + g_free (res); + g_free (hostname); + g_clear_error (&error); + } +} + +static gint +safe_strcmp_filename (const gchar *a, const gchar *b) +{ +#ifndef G_OS_WIN32 + return g_strcmp0 (a, b); +#else + if (!a || !b) + return g_strcmp0 (a, b); + else + { + while (*a && *b) + { + if ((G_IS_DIR_SEPARATOR (*a) && G_IS_DIR_SEPARATOR (*b)) || + *a == *b) + a++, b++; + else + return (*a - *b); + } + return (*a - *b); + } +#endif +} + +static gint +safe_strcmp_hostname (const gchar *a, const gchar *b) +{ + if (a == NULL) + a = ""; + if (b == NULL) + b = ""; +#ifndef G_OS_WIN32 + return strcmp (a, b); +#else + if (strcmp (a, "localhost") == 0 && !*b) + return 0; + else + return strcmp (a, b); +#endif +} + +static void +run_file_roundtrip_tests (void) +{ + gsize i; + gchar *uri, *hostname, *res; + GError *error; + + for (i = 0; i < G_N_ELEMENTS (file_to_uri_tests); i++) + { + if (file_to_uri_tests[i].expected_error != 0) + continue; + + error = NULL; + uri = g_filename_to_uri (file_to_uri_tests[i].filename, + file_to_uri_tests[i].hostname, + &error); + g_assert_no_error (error); + + hostname = NULL; + res = g_filename_from_uri (uri, &hostname, &error); + g_assert_no_error (error); + + g_assert_cmpint (safe_strcmp_filename (file_to_uri_tests[i].filename, res), ==, 0); + g_assert_cmpint (safe_strcmp_hostname (file_to_uri_tests[i].hostname, hostname), ==, 0); + g_free (res); + g_free (uri); + g_free (hostname); + } +} + +static void +run_uri_list_tests (void) +{ + /* straight from the RFC */ + gchar *list = + "# urn:isbn:0-201-08372-8\r\n" + "http://www.huh.org/books/foo.html\r\n" + "http://www.huh.org/books/foo.pdf \r\n" + " ftp://ftp.foo.org/books/foo.txt\r\n"; + gchar *expected_uris[] = { + "http://www.huh.org/books/foo.html", + "http://www.huh.org/books/foo.pdf", + "ftp://ftp.foo.org/books/foo.txt" + }; + + gchar **uris; + gint j; + + uris = g_uri_list_extract_uris (list); + g_assert_cmpint (g_strv_length (uris), ==, 3); + + for (j = 0; j < 3; j++) + g_assert_cmpstr (uris[j], ==, expected_uris[j]); + + g_strfreev (uris); + + uris = g_uri_list_extract_uris ("# just hot air\r\n# more hot air"); + g_assert_cmpint (g_strv_length (uris), ==, 0); + g_strfreev (uris); +} + +static void +test_uri_unescape_string (void) +{ + const struct + { + /* Inputs */ + const gchar *escaped; /* (nullable) */ + const gchar *illegal_characters; /* (nullable) */ + /* Outputs */ + const gchar *expected_unescaped; /* (nullable) */ + } + tests[] = + { + { "%2Babc %4F", NULL, "+abc O" }, + { "%2Babc %4F", "+", NULL }, + { "%00abc %4F", "+/", NULL }, + { "/cursors/none.png", "/", "/cursors/none.png" }, + { "/cursors%2fbad-subdir/none.png", "/", NULL }, + { "%0", NULL, NULL }, + { "%ra", NULL, NULL }, + { "%2r", NULL, NULL }, + { "Timm B\344der", NULL, "Timm B\344der" }, + { NULL, NULL, NULL }, /* actually a valid test, not a delimiter */ + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + gchar *s = NULL; + + g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, tests[i].escaped); + + s = g_uri_unescape_string (tests[i].escaped, tests[i].illegal_characters); + g_assert_cmpstr (s, ==, tests[i].expected_unescaped); + g_free (s); + } +} + +static void +test_uri_unescape_bytes (gconstpointer test_data) +{ + GError *error = NULL; + gboolean use_nul_terminated = GPOINTER_TO_INT (test_data); + const struct + { + /* Inputs */ + const gchar *escaped; /* (nullable) */ + const gchar *illegal; + /* Outputs */ + gssize expected_unescaped_len; /* -1 => error expected */ + const guint8 *expected_unescaped; /* (nullable) */ + } + tests[] = + { + { "%00%00", NULL, 2, (const guint8 *) "\x00\x00" }, + { "/cursors/none.png", "/", 17, (const guint8 *) "/cursors/none.png" }, + { "/cursors%2fbad-subdir/none.png", "/", -1, NULL }, + { "%%", NULL, -1, NULL }, + { "%", NULL, -1, NULL }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + gssize escaped_len = 0; + gchar *escaped = NULL; + GBytes *bytes = NULL; + + g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, tests[i].escaped); + + /* The tests get run twice: once with the length unspecified, using a + * nul-terminated string; and once with the length specified and a copy of + * the string with the trailing nul explicitly removed (to help catch + * buffer overflows). */ + if (use_nul_terminated) + { + escaped_len = -1; + escaped = g_strdup (tests[i].escaped); + } + else + { + escaped_len = strlen (tests[i].escaped); /* no trailing nul */ + escaped = g_memdup2 (tests[i].escaped, escaped_len); + } + + bytes = g_uri_unescape_bytes (escaped, escaped_len, tests[i].illegal, &error); + + if (tests[i].expected_unescaped_len < 0) + { + g_assert_null (bytes); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_FAILED); + g_clear_error (&error); + } + else + { + g_assert_no_error (error); + g_assert_cmpmem (g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + tests[i].expected_unescaped, + tests[i].expected_unescaped_len); + } + + g_clear_pointer (&bytes, g_bytes_unref); + g_free (escaped); + } +} + +static void +test_uri_unescape_segment (void) +{ + const gchar *escaped_segment = "%2Babc %4F---"; + gchar *s = NULL; + + s = g_uri_unescape_segment (escaped_segment, escaped_segment + 10, NULL); + g_assert_cmpstr (s, ==, "+abc O"); + g_free (s); + + s = g_uri_unescape_segment ("%2Babc%00cde", NULL, NULL); + g_assert_null (s); +} + +static void +test_uri_escape_string (void) +{ + const struct + { + /* Inputs */ + const gchar *unescaped; + const gchar *reserved_chars_allowed; + gboolean allow_utf8; + /* Outputs */ + const gchar *expected_escaped; + } + tests[] = + { + { "abcdefgABCDEFG._~", NULL, FALSE, "abcdefgABCDEFG._~" }, + { ":+ \\?#", NULL, FALSE, "%3A%2B%20%5C%3F%23" }, + { "a+b:c", "+", FALSE, "a+b%3Ac" }, + { "a+b:c\303\234", "+", TRUE, "a+b%3Ac\303\234" }, + /* Incomplete UTF-8 sequence: */ + { "\xfc\x3b\xd2", NULL, TRUE, "%FC%3B%D2" }, + /* Invalid sequence: */ + { "\xc3\xb1\xc3\x28", NULL, TRUE, "ñ%C3%28" }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + gchar *s = NULL; + + g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, tests[i].unescaped); + + s = g_uri_escape_string (tests[i].unescaped, + tests[i].reserved_chars_allowed, + tests[i].allow_utf8); + g_assert_cmpstr (s, ==, tests[i].expected_escaped); + g_free (s); + } +} + +static void +test_uri_escape_bytes (void) +{ + gchar *s = NULL; + + s = g_uri_escape_bytes ((guchar*)"\0\0", 2, NULL); + g_assert_cmpstr (s, ==, "%00%00"); + g_free (s); +} + +static void +test_uri_scheme (void) +{ + const gchar *s1, *s2; + gchar *s; + + s = g_uri_parse_scheme ("ftp://ftp.gtk.org"); + g_assert_cmpstr (s, ==, "ftp"); + g_free (s); + + s = g_uri_parse_scheme ("good-scheme.but+weird:gtk.org"); + g_assert_cmpstr (s, ==, "good-scheme.but+weird"); + g_free (s); + + s = g_uri_parse_scheme ("1bad:"); + g_assert_null (s); + s = g_uri_parse_scheme ("bad"); + g_assert_null (s); + s = g_uri_parse_scheme ("99http://host/path"); + g_assert_null (s); + s = g_uri_parse_scheme (".http://host/path"); + g_assert_null (s); + s = g_uri_parse_scheme ("+http://host/path"); + g_assert_null (s); + + s1 = g_uri_peek_scheme ("ftp://ftp.gtk.org"); + g_assert_cmpstr (s1, ==, "ftp"); + s2 = g_uri_peek_scheme ("FTP://ftp.gtk.org"); + g_assert_cmpstr (s2, ==, "ftp"); + g_assert_true (s1 == s2); + s1 = g_uri_peek_scheme ("1bad:"); + g_assert_null (s1); + s1 = g_uri_peek_scheme ("bad"); + g_assert_null (s1); +} + +typedef struct { + const gchar *scheme; + const gchar *userinfo; + const gchar *host; + gint port; + const gchar *path; + const gchar *query; + const gchar *fragment; +} UriParts; + +typedef struct { + /* Inputs */ + const gchar *orig; + GUriFlags flags; + /* Outputs */ + gboolean expected_success; + gint expected_error_code; /* unused if @expected_success is true */ + const UriParts expected_parts; /* unused if @expected_success is false */ +} UriAbsoluteTest; + +static const UriAbsoluteTest absolute_tests[] = { + { "foo:", G_URI_FLAGS_NONE, TRUE, 0, + { "foo", NULL, NULL, -1, "", NULL, NULL } + }, + { "file:/dev/null", G_URI_FLAGS_NONE, TRUE, 0, + { "file", NULL, NULL, -1, "/dev/null", NULL, NULL } + }, + { "file:///dev/null", G_URI_FLAGS_NONE, TRUE, 0, + { "file", NULL, "", -1, "/dev/null", NULL, NULL } + }, + { "ftp://user@host/path", G_URI_FLAGS_NONE, TRUE, 0, + { "ftp", "user", "host", -1, "/path", NULL, NULL } + }, + { "ftp://user@host:9999/path", G_URI_FLAGS_NONE, TRUE, 0, + { "ftp", "user", "host", 9999, "/path", NULL, NULL } + }, + { "ftp://user:password@host/path", G_URI_FLAGS_NONE, TRUE, 0, + { "ftp", "user:password", "host", -1, "/path", NULL, NULL } + }, + { "ftp://user:password@host:9999/path", G_URI_FLAGS_NONE, TRUE, 0, + { "ftp", "user:password", "host", 9999, "/path", NULL, NULL } + }, + { "ftp://user:password@host", G_URI_FLAGS_NONE, TRUE, 0, + { "ftp", "user:password", "host", -1, "", NULL, NULL } + }, + { "http://us%65r@host", G_URI_FLAGS_NONE, TRUE, 0, + { "http", "user", "host", -1, "", NULL, NULL } + }, + { "http://us%40r@host", G_URI_FLAGS_NONE, TRUE, 0, + { "http", "us@r", "host", -1, "", NULL, NULL } + }, + { "http://us%3ar@host", G_URI_FLAGS_NONE, TRUE, 0, + { "http", "us:r", "host", -1, "", NULL, NULL } + }, + { "http://us%2fr@host", G_URI_FLAGS_NONE, TRUE, 0, + { "http", "us/r", "host", -1, "", NULL, NULL } + }, + { "http://us%3fr@host", G_URI_FLAGS_NONE, TRUE, 0, + { "http", "us?r", "host", -1, "", NULL, NULL } + }, + { "http://host?query", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "host", -1, "", "query", NULL } + }, + { "http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue¶m=value", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "host", -1, "/path", "query=http://host/path?childparam=childvalue¶m=value", NULL } + }, + { "http://control-chars/%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "control-chars", -1, "/\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F", NULL, NULL } + }, + { "http://space/%20", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "space", -1, "/ ", NULL, NULL } + }, + { "http://delims/%3C%3E%23%25%22", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "delims", -1, "/<>#%\"", NULL, NULL } + }, + { "http://unwise-chars/%7B%7D%7C%5C%5E%5B%5D%60", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "unwise-chars", -1, "/{}|\\^[]`", NULL, NULL } + }, + + /* From RFC 2732 */ + { "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 80, "/index.html", NULL, NULL } + }, + { "http://[1080:0:0:0:8:800:200C:417A]/index.html", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "1080:0:0:0:8:800:200C:417A", -1, "/index.html", NULL, NULL } + }, + { "http://[3ffe:2a00:100:7031::1]", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "3ffe:2a00:100:7031::1", -1, "", NULL, NULL } + }, + { "http://[1080::8:800:200C:417A]/foo", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "1080::8:800:200C:417A", -1, "/foo", NULL, NULL } + }, + { "http://[::192.9.5.5]/ipng", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "::192.9.5.5", -1, "/ipng", NULL, NULL } + }, + { "http://[::FFFF:129.144.52.38]:80/index.html", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "::FFFF:129.144.52.38", 80, "/index.html", NULL, NULL } + }, + { "http://[2010:836B:4179::836B:4179]", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "2010:836B:4179::836B:4179", -1, "", NULL, NULL } + }, + + /* some problematic URIs that are handled differently in libsoup */ + { "http://host/path with spaces", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path with spaces", NULL, NULL } + }, + { " http://host/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path", NULL, NULL } + }, + { "http://host/path ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path", NULL, NULL } + }, + { "http://host ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "", NULL, NULL } + }, + { "http://host:999 ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", 999, "", NULL, NULL } + }, + { "http://host/pa\nth", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path", NULL, NULL } + }, + { "http:\r\n//host/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path", NULL, NULL } + }, + { "http://\thost/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path", NULL, NULL } + }, + + /* Bug 594405; 0-length is different from not-present */ + { "http://host/path?", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "host", -1, "/path", "", NULL } + }, + { "http://host/path#", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "host", -1, "/path", NULL, "" }, + }, + + /* Bug 590524; ignore bad %-encoding */ + { "http://host/path%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path%", NULL, NULL } + }, + { "http://h%ost/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "h%ost", -1, "/path", NULL, NULL } + }, + { "http://host/path%%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path%%", NULL, NULL } + }, + { "http://host/path%%%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path%%%", NULL, NULL } + }, + { "http://host/path%/x/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path%/x/", NULL, NULL } + }, + { "http://host/path%0x/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path%0x/", NULL, NULL } + }, + { "http://host/path%ax", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "host", -1, "/path%ax", NULL, NULL } + }, + + /* GUri doesn't %-encode non-ASCII characters */ + { "http://host/p\xc3\xa4th/", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "host", -1, "/p\xc3\xa4th/", NULL, NULL } + }, + + { "HTTP:////////////////", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "", -1, "//////////////", NULL, NULL } + }, + + { "http://@host", G_URI_FLAGS_NONE, TRUE, 0, + { "http", "", "host", -1, "", NULL, NULL } + }, + { "http://:@host", G_URI_FLAGS_NONE, TRUE, 0, + { "http", ":", "host", -1, "", NULL, NULL } + }, + { "scheme://foo%3Abar._webdav._tcp.local", G_URI_FLAGS_NONE, TRUE, 0, + { "scheme", NULL, "foo:bar._webdav._tcp.local", -1, "", NULL, NULL} + }, + + /* ".." past top */ + { "http://example.com/..", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "example.com", -1, "/", NULL, NULL } + }, + + /* scheme parsing */ + { "foo0://host/path", G_URI_FLAGS_NONE, TRUE, 0, + { "foo0", NULL, "host", -1, "/path", NULL, NULL } }, + { "f0.o://host/path", G_URI_FLAGS_NONE, TRUE, 0, + { "f0.o", NULL, "host", -1, "/path", NULL, NULL } }, + { "http++://host/path", G_URI_FLAGS_NONE, TRUE, 0, + { "http++", NULL, "host", -1, "/path", NULL, NULL } }, + { "http-ish://host/path", G_URI_FLAGS_NONE, TRUE, 0, + { "http-ish", NULL, "host", -1, "/path", NULL, NULL } }, + + /* IPv6 scope ID parsing (both correct and incorrect) */ + { "http://[fe80::dead:beef%]/", G_URI_FLAGS_PARSE_RELAXED, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, + { "http://[fe80::dead:beef%em1]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%em1]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, + { "http://[fe80::dead:beef%25em1]/", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%25em1%20]/", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "fe80::dead:beef%em1 ", -1, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%25em%31]/", G_URI_FLAGS_NONE, TRUE, 0, + { "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%10]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "fe80::dead:beef%10", -1, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%10]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, + { "http://[fe80::dead:beef%25]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "fe80::dead:beef%25", -1, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%25]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, + { "http://[192.168.0.1%25em1]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, + { "http://[fe80::dead:beef%2em1]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0, + { "http", NULL, "fe80::dead:beef%2em1", -1, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%2em1]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, + { "http://[fe80::dead:beef%25em1%00]/", G_URI_FLAGS_PARSE_RELAXED, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, + { "http://[fe80::dead:beef%25em1%00]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, + + /* Invalid IDN hostname */ + { "http://xn--mixed-\xc3\xbcp/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST, + { NULL, NULL, NULL, -1, NULL, NULL, NULL } }, +}; + +static void +test_uri_parsing_absolute (void) +{ + gsize i; + + for (i = 0; i < G_N_ELEMENTS (absolute_tests); i++) + { + const UriAbsoluteTest *test = &absolute_tests[i]; + GError *error = NULL; + GUri *uri; + + g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, test->orig); + + uri = g_uri_parse (test->orig, test->flags, &error); + if (test->expected_success) + { + g_assert_no_error (error); + + g_assert_cmpstr (g_uri_get_scheme (uri), ==, test->expected_parts.scheme); + g_assert_cmpstr (g_uri_get_userinfo (uri), ==, test->expected_parts.userinfo); + g_assert_cmpstr (g_uri_get_host (uri), ==, test->expected_parts.host); + g_assert_cmpint (g_uri_get_port (uri), ==, test->expected_parts.port); + g_assert_cmpstr (g_uri_get_path (uri), ==, test->expected_parts.path); + g_assert_cmpstr (g_uri_get_query (uri), ==, test->expected_parts.query); + g_assert_cmpstr (g_uri_get_fragment (uri), ==, test->expected_parts.fragment); + } + else + { + g_assert_error (error, G_URI_ERROR, test->expected_error_code); + g_assert_null (uri); + } + + g_clear_pointer (&uri, g_uri_unref); + g_clear_error (&error); + } +} + +typedef struct { + const gchar *orig, *resolved; + UriParts parts; +} UriRelativeTest; + +/* This all comes from RFC 3986 */ +static const char *relative_test_base = "http://a/b/c/d;p?q"; +static const UriRelativeTest relative_tests[] = { + { "g:h", "g:h", + { "g", NULL, NULL, -1, "h", NULL, NULL } }, + { "g", "http://a/b/c/g", + { "http", NULL, "a", -1, "/b/c/g", NULL, NULL } }, + { "./g", "http://a/b/c/g", + { "http", NULL, "a", -1, "/b/c/g", NULL, NULL } }, + { "g/", "http://a/b/c/g/", + { "http", NULL, "a", -1, "/b/c/g/", NULL, NULL } }, + { "/g", "http://a/g", + { "http", NULL, "a", -1, "/g", NULL, NULL } }, + { "//g", "http://g", + { "http", NULL, "g", -1, "", NULL, NULL } }, + { "?y", "http://a/b/c/d;p?y", + { "http", NULL, "a", -1, "/b/c/d;p", "y", NULL } }, + { "g?y", "http://a/b/c/g?y", + { "http", NULL, "a", -1, "/b/c/g", "y", NULL } }, + { "#s", "http://a/b/c/d;p?q#s", + { "http", NULL, "a", -1, "/b/c/d;p", "q", "s" } }, + { "g#s", "http://a/b/c/g#s", + { "http", NULL, "a", -1, "/b/c/g", NULL, "s" } }, + { "g?y#s", "http://a/b/c/g?y#s", + { "http", NULL, "a", -1, "/b/c/g", "y", "s" } }, + { ";x", "http://a/b/c/;x", + { "http", NULL, "a", -1, "/b/c/;x", NULL, NULL } }, + { "g;x", "http://a/b/c/g;x", + { "http", NULL, "a", -1, "/b/c/g;x", NULL, NULL } }, + { "g;x?y#s", "http://a/b/c/g;x?y#s", + { "http", NULL, "a", -1, "/b/c/g;x", "y", "s" } }, + { ".", "http://a/b/c/", + { "http", NULL, "a", -1, "/b/c/", NULL, NULL } }, + { "./", "http://a/b/c/", + { "http", NULL, "a", -1, "/b/c/", NULL, NULL } }, + { "..", "http://a/b/", + { "http", NULL, "a", -1, "/b/", NULL, NULL } }, + { "../", "http://a/b/", + { "http", NULL, "a", -1, "/b/", NULL, NULL } }, + { "../g", "http://a/b/g", + { "http", NULL, "a", -1, "/b/g", NULL, NULL } }, + { "../..", "http://a/", + { "http", NULL, "a", -1, "/", NULL, NULL } }, + { "../../", "http://a/", + { "http", NULL, "a", -1, "/", NULL, NULL } }, + { "../../g", "http://a/g", + { "http", NULL, "a", -1, "/g", NULL, NULL } }, + { "", "http://a/b/c/d;p?q", + { "http", NULL, "a", -1, "/b/c/d;p", "q", NULL } }, + { "../../../g", "http://a/g", + { "http", NULL, "a", -1, "/g", NULL, NULL } }, + { "../../../../g", "http://a/g", + { "http", NULL, "a", -1, "/g", NULL, NULL } }, + { "/./g", "http://a/g", + { "http", NULL, "a", -1, "/g", NULL, NULL } }, + { "/../g", "http://a/g", + { "http", NULL, "a", -1, "/g", NULL, NULL } }, + { "g.", "http://a/b/c/g.", + { "http", NULL, "a", -1, "/b/c/g.", NULL, NULL } }, + { ".g", "http://a/b/c/.g", + { "http", NULL, "a", -1, "/b/c/.g", NULL, NULL } }, + { "g..", "http://a/b/c/g..", + { "http", NULL, "a", -1, "/b/c/g..", NULL, NULL } }, + { "..g", "http://a/b/c/..g", + { "http", NULL, "a", -1, "/b/c/..g", NULL, NULL } }, + { "./../g", "http://a/b/g", + { "http", NULL, "a", -1, "/b/g", NULL, NULL } }, + { "./g/.", "http://a/b/c/g/", + { "http", NULL, "a", -1, "/b/c/g/", NULL, NULL } }, + { "g/./h", "http://a/b/c/g/h", + { "http", NULL, "a", -1, "/b/c/g/h", NULL, NULL } }, + { "g/../h", "http://a/b/c/h", + { "http", NULL, "a", -1, "/b/c/h", NULL, NULL } }, + { "g;x=1/./y", "http://a/b/c/g;x=1/y", + { "http", NULL, "a", -1, "/b/c/g;x=1/y", NULL, NULL } }, + { "g;x=1/../y", "http://a/b/c/y", + { "http", NULL, "a", -1, "/b/c/y", NULL, NULL } }, + { "g?y/./x", "http://a/b/c/g?y/./x", + { "http", NULL, "a", -1, "/b/c/g", "y/./x", NULL } }, + { "g?y/../x", "http://a/b/c/g?y/../x", + { "http", NULL, "a", -1, "/b/c/g", "y/../x", NULL } }, + { "g#s/./x", "http://a/b/c/g#s/./x", + { "http", NULL, "a", -1, "/b/c/g", NULL, "s/./x" } }, + { "g#s/../x", "http://a/b/c/g#s/../x", + { "http", NULL, "a", -1, "/b/c/g", NULL, "s/../x" } }, + { "http:g", "http:g", + { "http", NULL, NULL, -1, "g", NULL, NULL } }, + { "http://a/../..", "http://a/", + { "http", NULL, "a", -1, "/", NULL, NULL } }, + { "ScHeMe://User:P%61ss@HOST.%63om:1234/path/./from/../to%7d/item%2dobj?qu%65ry=something#fr%61gment", + "scheme://User:Pass@HOST.com:1234/path/to%7D/item-obj?query=something#fragment", + { "scheme", "User:Pass", "HOST.com", 1234, "/path/to}/item-obj", "query=something", "fragment" } }, + /* Test corner cases of remove_dot_segments */ + { "http:..", "http:", + { "http", NULL, NULL, -1, "", NULL, NULL } }, + { "http:../", "http:", + { "http", NULL, NULL, -1, "", NULL, NULL } }, + { "http:.", "http:", + { "http", NULL, NULL, -1, "", NULL, NULL } }, + { "http:./", "http:", + { "http", NULL, NULL, -1, "", NULL, NULL } }, + { "http:a/..", "http:/", + { "http", NULL, NULL, -1, "/", NULL, NULL } }, + { "http:a/../", "http:/", + { "http", NULL, NULL, -1, "/", NULL, NULL } }, +}; +static int num_relative_tests = G_N_ELEMENTS (relative_tests); + +static void +test_uri_parsing_relative (void) +{ + int i; + GUri *base, *uri; + GError *error = NULL; + gchar *resolved; + + base = g_uri_parse (relative_test_base, G_URI_FLAGS_NONE, &error); + g_assert_no_error (error); + + for (i = 0; i < num_relative_tests; i++) + { + const UriRelativeTest *test = &relative_tests[i]; + gchar *tostring; + + uri = g_uri_parse_relative (base, test->orig, G_URI_FLAGS_NONE, &error); + g_assert_no_error (error); + + g_assert_cmpstr (g_uri_get_scheme (uri), ==, test->parts.scheme); + g_assert_cmpstr (g_uri_get_userinfo (uri), ==, test->parts.userinfo); + g_assert_cmpstr (g_uri_get_host (uri), ==, test->parts.host); + g_assert_cmpint (g_uri_get_port (uri), ==, test->parts.port); + g_assert_cmpstr (g_uri_get_path (uri), ==, test->parts.path); + g_assert_cmpstr (g_uri_get_query (uri), ==, test->parts.query); + g_assert_cmpstr (g_uri_get_fragment (uri), ==, test->parts.fragment); + + tostring = g_uri_to_string (uri); + g_assert_cmpstr (tostring, ==, test->resolved); + g_free (tostring); + + g_uri_unref (uri); + + resolved = g_uri_resolve_relative (relative_test_base, test->orig, G_URI_FLAGS_NONE, &error); + g_assert_no_error (error); + g_assert_cmpstr (resolved, ==, test->resolved); + g_free (resolved); + } + uri = g_uri_parse_relative (base, "%%", G_URI_FLAGS_NONE, &error); + g_assert_null (uri); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PATH); + g_clear_error (&error); + + g_uri_unref (base); + + resolved = g_uri_resolve_relative (NULL, "http://a", G_URI_FLAGS_NONE, &error); + g_assert_no_error (error); + g_assert_cmpstr (resolved, ==, "http://a"); + g_free (resolved); + + resolved = g_uri_resolve_relative ("http://a", "b", G_URI_FLAGS_NONE, &error); + g_assert_no_error (error); + g_assert_cmpstr (resolved, ==, "http://a/b"); + g_free (resolved); + + resolved = g_uri_resolve_relative (NULL, "a", G_URI_FLAGS_NONE, &error); + g_assert_null (resolved); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_FAILED); + g_clear_error (&error); + + resolved = g_uri_resolve_relative ("../b", "a", G_URI_FLAGS_NONE, &error); + g_assert_null (resolved); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_FAILED); + g_clear_error (&error); + + resolved = g_uri_resolve_relative ("%%", "a", G_URI_FLAGS_PARSE_RELAXED, &error); + g_assert_null (resolved); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_FAILED); + g_clear_error (&error); +} + +static void +test_uri_to_string (void) +{ + GUri *uri; + gchar *tostring; + + uri = g_uri_build (G_URI_FLAGS_NONE, "scheme", "userinfo", "host", 1234, + "/path", "query", "fragment"); + + tostring = g_uri_to_string (uri); + g_assert_cmpstr (tostring, ==, "scheme://userinfo@host:1234/path?query#fragment"); + g_free (tostring); + g_uri_unref (uri); + + uri = g_uri_build (G_URI_FLAGS_NONE, "scheme", NULL, "fe80::dead:beef%em1", -1, "", NULL, NULL); + tostring = g_uri_to_string (uri); + g_assert_cmpstr (tostring, ==, "scheme://[fe80::dead:beef%25em1]"); + g_free (tostring); + g_uri_unref (uri); + + uri = g_uri_build_with_user (G_URI_FLAGS_NONE, "scheme", "user", "pass", "auth", "host", 1234, + "/path", "query", "fragment"); + tostring = g_uri_to_string (uri); + g_assert_cmpstr (tostring, ==, "scheme://user:pass;auth@host:1234/path?query#fragment"); + g_free (tostring); + tostring = g_uri_to_string_partial (uri, G_URI_HIDE_USERINFO); + g_assert_cmpstr (tostring, ==, "scheme://host:1234/path?query#fragment"); + g_free (tostring); + tostring = g_uri_to_string_partial (uri, G_URI_HIDE_QUERY); + g_assert_cmpstr (tostring, ==, "scheme://user:pass;auth@host:1234/path#fragment"); + g_free (tostring); + tostring = g_uri_to_string_partial (uri, G_URI_HIDE_FRAGMENT); + g_assert_cmpstr (tostring, ==, "scheme://user:pass;auth@host:1234/path?query"); + g_free (tostring); + g_uri_unref (uri); + + uri = g_uri_build_with_user (G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS, + "scheme", "us:er", "pass", "auth", "host", 1234, + "/path", "query", "fragment"); + tostring = g_uri_to_string (uri); + g_assert_cmpstr (tostring, ==, "scheme://us%3Aer:pass;auth@host:1234/path?query#fragment"); + g_free (tostring); + tostring = g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD); + g_assert_cmpstr (tostring, ==, "scheme://us%3Aer;auth@host:1234/path?query#fragment"); + g_free (tostring); + tostring = g_uri_to_string_partial (uri, G_URI_HIDE_AUTH_PARAMS); + g_assert_cmpstr (tostring, ==, "scheme://us%3Aer:pass@host:1234/path?query#fragment"); + g_free (tostring); + tostring = g_uri_to_string_partial (uri, G_URI_HIDE_QUERY); + g_assert_cmpstr (tostring, ==, "scheme://us%3Aer:pass;auth@host:1234/path#fragment"); + g_free (tostring); + g_uri_unref (uri); +} + +static void +test_uri_build (void) +{ + GUri *uri; + + uri = g_uri_build (G_URI_FLAGS_NON_DNS, "scheme", "userinfo", "host", 1234, + "/path", "query", "fragment"); + + /* check ref/unref */ + g_uri_ref (uri); + g_uri_unref (uri); + + g_assert_cmpint (g_uri_get_flags (uri), ==, G_URI_FLAGS_NON_DNS); + g_assert_cmpstr (g_uri_get_scheme (uri), ==, "scheme"); + g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "userinfo"); + g_assert_cmpstr (g_uri_get_host (uri), ==, "host"); + g_assert_cmpint (g_uri_get_port (uri), ==, 1234); + g_assert_cmpstr (g_uri_get_path (uri), ==, "/path"); + g_assert_cmpstr (g_uri_get_query (uri), ==, "query"); + g_assert_cmpstr (g_uri_get_fragment (uri), ==, "fragment"); + g_assert_cmpstr (g_uri_get_user (uri), ==, NULL); + g_assert_cmpstr (g_uri_get_password (uri), ==, NULL); + g_uri_unref (uri); + + uri = g_uri_build_with_user (G_URI_FLAGS_NON_DNS, "scheme", "user", "password", + "authparams", "host", 1234, + "/path", "query", "fragment"); + + g_assert_cmpint (g_uri_get_flags (uri), ==, G_URI_FLAGS_NON_DNS | G_URI_FLAGS_HAS_PASSWORD); + g_assert_cmpstr (g_uri_get_scheme (uri), ==, "scheme"); + g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "user:password;authparams"); + g_assert_cmpstr (g_uri_get_host (uri), ==, "host"); + g_assert_cmpint (g_uri_get_port (uri), ==, 1234); + g_assert_cmpstr (g_uri_get_path (uri), ==, "/path"); + g_assert_cmpstr (g_uri_get_query (uri), ==, "query"); + g_assert_cmpstr (g_uri_get_fragment (uri), ==, "fragment"); + g_assert_cmpstr (g_uri_get_user (uri), ==, "user"); + g_assert_cmpstr (g_uri_get_password (uri), ==, "password"); + g_assert_cmpstr (g_uri_get_auth_params (uri), ==, "authparams"); + g_uri_unref (uri); + + uri = g_uri_build_with_user (G_URI_FLAGS_NONE, "scheme", "user\001", "password\002", + "authparams\003", "host", 1234, + "/path", "query", "fragment"); + g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "user\001:password\002;authparams\003"); + g_uri_unref (uri); + + uri = g_uri_build_with_user (G_URI_FLAGS_ENCODED, "scheme", "user%01", "password%02", + "authparams%03", "host", 1234, + "/path", "query", "fragment"); + g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "user%01:password%02;authparams%03"); + g_uri_unref (uri); + + uri = g_uri_build_with_user (G_URI_FLAGS_ENCODED, "scheme", NULL, NULL, + NULL, "host", 1234, + "/path", "query", "fragment"); + g_assert_null (g_uri_get_userinfo (uri)); + g_uri_unref (uri); + + uri = g_uri_build_with_user (G_URI_FLAGS_NONE, "scheme", "user", NULL, NULL, + "host", 1234, + "/path", "query", "fragment"); + g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "user"); + g_uri_unref (uri); +} + +static void +test_uri_split (void) +{ + gchar *scheme = NULL; + gchar *userinfo = NULL; + gchar *user = NULL; + gchar *pass = NULL; + gchar *authparams = NULL; + gchar *host = NULL; + gchar *path = NULL; + gchar *query = NULL; + gchar *fragment = NULL; + GError *error = NULL; + gint port; + + g_uri_split ("scheme://user%3Apass%3Bauth@host:1234/path?query#fragment", + G_URI_FLAGS_NONE, + &scheme, + &userinfo, + &host, + &port, + &path, + &query, + &fragment, + &error); + g_assert_no_error (error); + g_assert_cmpstr (scheme, ==, "scheme"); + g_assert_cmpstr (userinfo, ==, "user:pass;auth"); + g_assert_cmpstr (host, ==, "host"); + g_assert_cmpint (port, ==, 1234); + g_assert_cmpstr (path, ==, "/path"); + g_assert_cmpstr (query, ==, "query"); + g_assert_cmpstr (fragment, ==, "fragment"); + g_free (scheme); + g_free (userinfo); + g_free (host); + g_free (path); + g_free (query); + g_free (fragment); + + g_uri_split ("scheme://user%3Apass%3Bauth@h%01st:1234/path?query#fragment", + G_URI_FLAGS_ENCODED, + NULL, + NULL, + &host, + NULL, + NULL, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (host, ==, "h\001st"); + g_free (host); + + g_uri_split ("scheme://@@@host:1234/path?query#fragment", + G_URI_FLAGS_ENCODED | G_URI_FLAGS_PARSE_RELAXED, + NULL, + &userinfo, + NULL, + NULL, + NULL, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (userinfo, ==, "@@"); + g_free (userinfo); + + + g_uri_split ("http://f;oo/", + G_URI_FLAGS_NONE | G_URI_FLAGS_PARSE_RELAXED, + NULL, + NULL, + NULL, + NULL, + &path, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (path, ==, ";oo/"); + g_free (path); + + g_uri_split ("http://h%01st/path?saisons=%C3%89t%C3%A9%2Bhiver", + G_URI_FLAGS_NONE, + NULL, + NULL, + &host, + NULL, + NULL, + &query, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (host, ==, "h\001st"); + g_assert_cmpstr (query, ==, "saisons=Été+hiver"); + g_free (host); + g_free (query); + + g_uri_split ("http://h%01st/path?saisons=%C3%89t%C3%A9%2Bhiver", + G_URI_FLAGS_ENCODED_QUERY, + NULL, + NULL, + &host, + NULL, + NULL, + &query, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (host, ==, "h\001st"); + g_assert_cmpstr (query, ==, "saisons=%C3%89t%C3%A9%2Bhiver"); + g_free (host); + g_free (query); + + g_uri_split ("http://h%01st/%C3%89t%C3%A9%2Bhiver", + G_URI_FLAGS_ENCODED_PATH, + NULL, + NULL, + NULL, + NULL, + &path, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (path, ==, "/%C3%89t%C3%A9%2Bhiver"); + g_free (path); + + g_uri_split ("file:///path/to/some%20file", + G_URI_FLAGS_NONE, + NULL, + NULL, + NULL, + NULL, + &path, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (path, ==, "/path/to/some file"); + g_free (path); + + g_uri_split ("http://h%01st/path#%C3%89t%C3%A9%2Bhiver", + G_URI_FLAGS_ENCODED_FRAGMENT, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &fragment, + &error); + g_assert_no_error (error); + g_assert_cmpstr (fragment, ==, "%C3%89t%C3%A9%2Bhiver"); + g_free (fragment); + + g_uri_split_with_user ("scheme://user:pass;auth@host:1234/path?query#fragment", + G_URI_FLAGS_HAS_AUTH_PARAMS|G_URI_FLAGS_HAS_PASSWORD, + NULL, + &user, + &pass, + &authparams, + NULL, + NULL, + NULL, + NULL, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (user, ==, "user"); + g_assert_cmpstr (pass, ==, "pass"); + g_assert_cmpstr (authparams, ==, "auth"); + g_free (user); + g_free (pass); + g_free (authparams); + + g_uri_split_network ("scheme://user:pass;auth@host:1234/path?query#fragment", + G_URI_FLAGS_NONE, + NULL, + NULL, + NULL, + &error); + g_assert_no_error (error); + + g_uri_split_network ("scheme://user:pass;auth@host:1234/path?query#fragment", + G_URI_FLAGS_NONE, + &scheme, + &host, + &port, + &error); + g_assert_no_error (error); + g_assert_cmpstr (scheme, ==, "scheme"); + g_assert_cmpstr (host, ==, "host"); + g_assert_cmpint (port, ==, 1234); + g_free (scheme); + g_free (host); + + g_uri_split_network ("%00", + G_URI_FLAGS_NONE, NULL, NULL, NULL, &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PATH); + g_clear_error (&error); + + g_uri_split_network ("/a", + G_URI_FLAGS_NONE, + &scheme, + &host, + &port, + &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_SCHEME); + g_clear_error (&error); + + g_uri_split_network ("schme:#", + G_URI_FLAGS_NONE, + &scheme, + &host, + &port, + &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST); + g_clear_error (&error); + + g_uri_split_network ("scheme://[]/a", + G_URI_FLAGS_NONE, NULL, NULL, NULL, &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST); + g_clear_error (&error); + + g_uri_split_network ("scheme://user%00:pass;auth@host", + G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS, + NULL, NULL, NULL, &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_USER); + g_clear_error (&error); + + g_uri_split_network ("scheme://user:pass%00;auth@host", + G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS, + NULL, NULL, NULL, &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PASSWORD); + g_clear_error (&error); + + g_uri_split_network ("scheme://user:pass;auth@host:1234/path?quer%00y#fragment", + G_URI_FLAGS_NONE, + NULL, NULL, NULL, &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_QUERY); + g_clear_error (&error); + + g_uri_split_network ("scheme://use%00r:pass;auth@host:1234/path", + G_URI_FLAGS_NONE, + NULL, NULL, NULL, &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_USER); + g_clear_error (&error); + + g_uri_split ("scheme://user:pass;auth@host:1234/path?query#fragm%00ent", + G_URI_FLAGS_NONE, + &scheme, + &userinfo, + &host, + &port, + &path, + &query, + &fragment, + &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_FRAGMENT); + g_clear_error (&error); + + g_uri_split_with_user ("scheme://user:pa%x0s;auth@host:1234/path?query#fragment", + G_URI_FLAGS_HAS_PASSWORD, + &scheme, + &user, + &pass, + &authparams, + &host, + &port, + &path, + &query, + &fragment, + &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PASSWORD); + g_clear_error (&error); + + g_uri_split_with_user ("scheme://user:pass;auth%00@host", + G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS, + &scheme, + &user, + &pass, + &authparams, + &host, + &port, + &path, + &query, + &fragment, + &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_AUTH_PARAMS); + g_clear_error (&error); + + g_uri_split_network ("scheme://user:pass%00;auth@host", + G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS, + NULL, NULL, NULL, &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PASSWORD); + g_clear_error (&error); + + /* Path not started correctly */ + g_uri_split("scheme://hostname:123path?query#fragment", + G_URI_FLAGS_NONE, + &scheme, + &userinfo, + &host, + &port, + &path, + &query, + &fragment, + &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT); + g_clear_error (&error); + + /* Brackets that don't close */ + g_uri_split("scheme://[01:23:45:67:89:ab:cd:ef:123/path", + G_URI_FLAGS_NONE, + &scheme, + &userinfo, + &host, + &port, + &path, + &query, + &fragment, + &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST); + g_clear_error (&error); + + /* IPv6 hostname without brackets */ + g_uri_split("scheme://01:23:45:67:89:ab:cd:ef:123/path", + G_URI_FLAGS_NONE, + &scheme, + &userinfo, + &host, + &port, + &path, + &query, + &fragment, + &error); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT); + g_clear_error (&error); +} + +static void +test_uri_is_valid (void) +{ + GError *error = NULL; + + g_assert_true (g_uri_is_valid ("http://[::192.9.5.5]/ipng", G_URI_FLAGS_NONE, NULL)); + g_assert_true (g_uri_is_valid ("http://127.127.127.127/", G_URI_FLAGS_NONE, NULL)); + g_assert_true (g_uri_is_valid ("http://127.127.127.b/", G_URI_FLAGS_NONE, NULL)); + g_assert_true (g_uri_is_valid ("http://\xc3\x89XAMPLE.COM/", G_URI_FLAGS_NONE, NULL)); + + g_assert_true (g_uri_is_valid (" \r http\t://f oo \t\n ", G_URI_FLAGS_PARSE_RELAXED, NULL)); + g_assert_false (g_uri_is_valid (" \r http\t://f oo \t\n ", G_URI_FLAGS_NONE, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_SCHEME); + g_clear_error (&error); + + g_assert_false (g_uri_is_valid ("http://[::192.9.5.5/ipng", G_URI_FLAGS_NONE, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST); + g_clear_error (&error); + + g_assert_true (g_uri_is_valid ("http://[fe80::dead:beef%25wef]/", G_URI_FLAGS_NONE, NULL)); + g_assert_false (g_uri_is_valid ("http://[fe80::dead:beef%wef%]/", G_URI_FLAGS_NONE, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST); + g_clear_error (&error); + + g_assert_false (g_uri_is_valid ("http://%00/", G_URI_FLAGS_NON_DNS, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST); + g_clear_error (&error); + + g_assert_true (g_uri_is_valid ("http://foo/", G_URI_FLAGS_NON_DNS, &error)); + + g_assert_false (g_uri_is_valid ("http://%00/", G_URI_FLAGS_NONE, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST); + g_clear_error (&error); + + g_assert_false (g_uri_is_valid ("http://%30.%30.%30.%30/", G_URI_FLAGS_NONE, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST); + g_clear_error (&error); + + g_assert_false (g_uri_is_valid ("http://host:port", G_URI_FLAGS_NONE, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT); + g_clear_error (&error); + + g_assert_false (g_uri_is_valid ("http://host:65536", G_URI_FLAGS_NONE, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT); + g_clear_error (&error); + + g_assert_false (g_uri_is_valid ("http://host:6553l", G_URI_FLAGS_NONE, &error)); + g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT); + g_clear_error (&error); + + g_assert_true (g_uri_is_valid ("data:,Hello", G_URI_FLAGS_NONE, &error)); + + g_assert_true (g_uri_is_valid ("B:\\foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("B:/foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("B://foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("B:foo.txt", G_URI_FLAGS_NONE, &error)); + + g_assert_true (g_uri_is_valid ("fd://0", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("AB:\\foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("AB:/foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("AB://foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("AB:foo.txt", G_URI_FLAGS_NONE, &error)); + + g_assert_true (g_uri_is_valid ("ABC:/foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("ABC://foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("ABC:foo.txt", G_URI_FLAGS_NONE, &error)); + + g_assert_true (g_uri_is_valid ("ABCD:/foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("ABCD://foo.txt", G_URI_FLAGS_NONE, &error)); + g_assert_true (g_uri_is_valid ("ABCD:foo.txt", G_URI_FLAGS_NONE, &error)); +} + +static const struct +{ + /* Inputs */ + const gchar *uri; + gchar *separators; + GUriParamsFlags flags; + /* Outputs */ + /* key, value, key, value, …, limited to length 2*expected_n_params */ + gssize expected_n_iter; /* -1 => error expected */ + const gchar *expected_iter_key_values[6]; + gssize expected_n_params; /* -1 => error expected */ + const gchar *expected_param_key_values[6]; +} params_tests[] = + { + { "p1=foo&p2=bar;p3=baz", "&;", G_URI_PARAMS_NONE, + 3, { "p1", "foo", "p2", "bar", "p3", "baz" }, + 3, { "p1", "foo", "p2", "bar", "p3", "baz" }}, + { "p1=foo&p2=bar", "", G_URI_PARAMS_NONE, + 1, { "p1", "foo&p2=bar" }, + 1, { "p1", "foo&p2=bar" }}, + { "p1=foo&&P1=bar", "&", G_URI_PARAMS_NONE, + 1, { "p1", "foo" }, + -1, { NULL, }}, + { "%00=foo", "&", G_URI_PARAMS_NONE, + 0, { NULL, }, + -1, { NULL, }}, + { "p1=%00", "&", G_URI_PARAMS_NONE, + 0, { NULL, }, + -1, { NULL, }}, + { "p1=foo&p1=bar", "&", G_URI_PARAMS_NONE, + 2, { "p1", "foo", "p1", "bar" }, + 1, { "p1", "bar", NULL, }}, + { "p1=foo&P1=bar", "&", G_URI_PARAMS_CASE_INSENSITIVE, + 2, { "p1", "foo", "P1", "bar" }, + 1, { "p1", "bar", NULL, }}, + { "=%", "&", G_URI_PARAMS_PARSE_RELAXED, + 1, { "", "%", NULL, }, + 1, { "", "%", NULL, }}, + { "=", "&", G_URI_PARAMS_NONE, + 1, { "", "", NULL, }, + 1, { "", "", NULL, }}, + { "foo", "&", G_URI_PARAMS_NONE, + 0, { NULL, }, + -1, { NULL, }}, + { "foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver", "&", G_URI_PARAMS_WWW_FORM, + 2, { "foo", "bar & baz", "saisons", "Été+hiver", NULL, }, + 2, { "foo", "bar & baz", "saisons", "Été+hiver", NULL, }}, + { "foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver", "&", G_URI_PARAMS_NONE, + 2, { "foo", "bar+&+baz", "saisons", "Été+hiver", NULL, }, + 2, { "foo", "bar+&+baz", "saisons", "Été+hiver", NULL, }}, + { "token=exp=123~acl=/QualityLevels(*~hmac=0cb", "&", G_URI_PARAMS_NONE, + 1, { "token", "exp=123~acl=/QualityLevels(*~hmac=0cb", NULL, }, + 1, { "token", "exp=123~acl=/QualityLevels(*~hmac=0cb", NULL, }}, + }; + +static void +test_uri_iter_params (gconstpointer test_data) +{ + GError *err = NULL; + gboolean use_nul_terminated = GPOINTER_TO_INT (test_data); + gsize i, n; + + for (i = 0; i < G_N_ELEMENTS (params_tests); i++) + { + GUriParamsIter iter; + gchar *uri, *attr, *value; + gssize uri_len; + + g_test_message ("URI %" G_GSIZE_FORMAT ": %s", i, params_tests[i].uri); + + g_assert (params_tests[i].expected_n_params < 0 || + params_tests[i].expected_n_params <= (gssize) G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2); + + /* The tests get run twice: once with the length unspecified, using a + * nul-terminated string; and once with the length specified and a copy of + * the string with the trailing nul explicitly removed (to help catch + * buffer overflows). */ + if (use_nul_terminated) + { + uri_len = -1; + uri = g_strdup (params_tests[i].uri); + } + else + { + uri_len = strlen (params_tests[i].uri); /* no trailing nul */ + uri = g_memdup2 (params_tests[i].uri, uri_len); + } + + /* Run once without extracting the attr or value, just to check the numbers. */ + n = 0; + g_uri_params_iter_init (&iter, params_tests[i].uri, -1, params_tests[i].separators, params_tests[i].flags); + while (g_uri_params_iter_next (&iter, NULL, NULL, &err)) + n++; + g_assert_cmpint (n, ==, params_tests[i].expected_n_iter); + if (err) + { + g_assert_error (err, G_URI_ERROR, G_URI_ERROR_FAILED); + g_clear_error (&err); + } + + /* Run again and check the strings too. */ + n = 0; + g_uri_params_iter_init (&iter, params_tests[i].uri, -1, params_tests[i].separators, params_tests[i].flags); + while (g_uri_params_iter_next (&iter, &attr, &value, &err)) + { + g_assert_cmpstr (attr, ==, params_tests[i].expected_iter_key_values[n * 2]); + g_assert_cmpstr (value, ==, params_tests[i].expected_iter_key_values[n * 2 + 1]); + n++; + g_free (attr); + g_free (value); + } + g_assert_cmpint (n, ==, params_tests[i].expected_n_iter); + if (err) + { + g_assert_error (err, G_URI_ERROR, G_URI_ERROR_FAILED); + g_clear_error (&err); + } + + g_free (uri); + } +} + +static void +test_uri_parse_params (gconstpointer test_data) +{ + GError *err = NULL; + gboolean use_nul_terminated = GPOINTER_TO_INT (test_data); + gsize i; + + for (i = 0; i < G_N_ELEMENTS (params_tests); i++) + { + GHashTable *params; + gchar *uri = NULL; + gssize uri_len; + + g_test_message ("URI %" G_GSIZE_FORMAT ": %s", i, params_tests[i].uri); + + g_assert (params_tests[i].expected_n_params < 0 || + params_tests[i].expected_n_params <= (gssize) G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2); + + /* The tests get run twice: once with the length unspecified, using a + * nul-terminated string; and once with the length specified and a copy of + * the string with the trailing nul explicitly removed (to help catch + * buffer overflows). */ + if (use_nul_terminated) + { + uri_len = -1; + uri = g_strdup (params_tests[i].uri); + } + else + { + uri_len = strlen (params_tests[i].uri); /* no trailing nul */ + uri = g_memdup2 (params_tests[i].uri, uri_len); + } + + params = g_uri_parse_params (uri, uri_len, params_tests[i].separators, params_tests[i].flags, &err); + + if (params_tests[i].expected_n_params < 0) + { + g_assert_null (params); + g_assert_error (err, G_URI_ERROR, G_URI_ERROR_FAILED); + g_clear_error (&err); + } + else + { + gsize j; + + g_assert_no_error (err); + g_assert_cmpint (g_hash_table_size (params), ==, params_tests[i].expected_n_params); + + for (j = 0; j < (gsize) params_tests[i].expected_n_params; j += 2) + g_assert_cmpstr (g_hash_table_lookup (params, params_tests[i].expected_param_key_values[j]), ==, + params_tests[i].expected_param_key_values[j + 1]); + } + + g_clear_pointer (¶ms, g_hash_table_unref); + g_free (uri); + } +} + +static void +test_uri_join (void) +{ + gchar *uri = NULL; + + uri = g_uri_join (G_URI_FLAGS_NONE, "foo", "some:user@info", "bar", -1, "", NULL, NULL); + g_assert_cmpstr (uri, ==, "foo://some:user%40info@bar"); + g_free (uri); + + uri = g_uri_join (G_URI_FLAGS_NONE, NULL, NULL, NULL, -1, "/foo", "abc", NULL); + g_assert_cmpstr (uri, ==, "/foo?abc"); + g_free (uri); + + uri = g_uri_join (G_URI_FLAGS_NONE, NULL, NULL, "hostname", -1, "/foo", "abc", NULL); + g_assert_cmpstr (uri, ==, "//hostname/foo?abc"); + g_free (uri); + + uri = g_uri_join_with_user (G_URI_FLAGS_NONE, "scheme", "user\001", "pass\002", "authparams\003", + "host", 9876, "/path", "query", "fragment"); + g_assert_cmpstr (uri, ==, "scheme://user%01:pass%02;authparams%03@host:9876/path?query#fragment"); + g_free (uri); + + uri = g_uri_join_with_user (G_URI_FLAGS_NONE, "scheme", "user\001", "pass\002", "authparams\003", + "::192.9.5.5", 9876, "/path", "query", "fragment"); + g_assert_cmpstr (uri, ==, "scheme://user%01:pass%02;authparams%03@[::192.9.5.5]:9876/path?query#fragment"); + g_free (uri); + + uri = g_uri_join_with_user (G_URI_FLAGS_ENCODED, + "scheme", "user%01", "pass%02", "authparams%03", + "::192.9.5.5", 9876, "/path", "query", "fragment"); + g_assert_cmpstr (uri, ==, + "scheme://user%01:pass%02;authparams%03@[::192.9.5.5]:9876/path?query#fragment"); + g_free (uri); + + uri = g_uri_join (G_URI_FLAGS_NONE, "scheme", NULL, "foo:bar._webdav._tcp.local", -1, "", NULL, NULL); + g_assert_cmpstr (uri, ==, "scheme://foo%3Abar._webdav._tcp.local"); + g_free (uri); +} + +static void +test_uri_join_split_round_trip (void) +{ + GUriFlags flags = G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_HAS_AUTH_PARAMS; + guint i; + + g_test_summary ("Test that joining different URI components survives a round trip"); + + /* Each bit in @i indicates whether the corresponding URI field should be set + * or %NULL. */ + for (i = 0; i < (1 << 8); i++) + { + gchar *uri = NULL; + const gchar *scheme, *user, *password, *auth_params, *host, *path, *query, *fragment; + gint port; + gchar *scheme_out = NULL, *user_out = NULL, *password_out = NULL; + gchar *auth_params_out = NULL, *host_out = NULL, *path_out = NULL; + gchar *query_out = NULL, *fragment_out = NULL; + gint port_out = -1; + gboolean split_success; + GError *local_error = NULL; + + g_test_message ("Combination %u", i); + + scheme = (i & (1 << 8)) ? "scheme" : NULL; + host = (i & (1 << 4)) ? "host" : NULL; + user = (host != NULL && i & (1 << 7)) ? "user" : NULL; /* only supported if host is also set */ + password = (host != NULL && user != NULL && i & (1 << 6)) ? "password" : NULL; /* only supported if host and user are also set */ + auth_params = (host != NULL && user != NULL && i & (1 << 5)) ? "auth_params" : NULL; /* only supported if host and user are also set */ + port = (host != NULL && i & (1 << 3)) ? 123 : -1; /* only supported if host is also set */ + path = (i & (1 << 2)) ? "/path" : ""; /* the only mandatory component */ + query = (i & (1 << 1)) ? "query" : NULL; + fragment = (i & (1 << 0)) ? "fragment" : NULL; + + uri = g_uri_join_with_user (flags, scheme, user, password, auth_params, + host, port, path, query, fragment); + g_assert_nonnull (uri); + + split_success = g_uri_split_with_user (uri, flags, &scheme_out, &user_out, + &password_out, &auth_params_out, + &host_out, &port_out, &path_out, + &query_out, &fragment_out, + &local_error); + g_assert_no_error (local_error); + g_assert_true (split_success); + + g_assert_cmpstr (scheme, ==, scheme_out); + g_assert_cmpstr (user, ==, user_out); + g_assert_cmpstr (password, ==, password_out); + g_assert_cmpstr (auth_params, ==, auth_params_out); + g_assert_cmpstr (host, ==, host_out); + g_assert_cmpint (port, ==, port_out); + g_assert_cmpstr (path, ==, path_out); + g_assert_cmpstr (query, ==, query_out); + g_assert_cmpstr (fragment, ==, fragment_out); + + g_free (uri); + g_free (scheme_out); + g_free (user_out); + g_free (password_out); + g_free (auth_params_out); + g_free (host_out); + g_free (path_out); + g_free (query_out); + g_free (fragment_out); + } +} + +static const struct +{ + /* Inputs */ + const gchar *base; + const gchar *uri; + GUriFlags flags; + /* Outputs */ + const gchar *uri_string; + const gchar *path; + int port; +} normalize_parse_tests[] = + { + { NULL, "http://foo/path with spaces", G_URI_FLAGS_ENCODED, + "http://foo/path%20with%20spaces", "/path%20with%20spaces", -1 }, + { NULL, "http://foo/path with spaces 2", G_URI_FLAGS_ENCODED_PATH, + "http://foo/path%20with%20spaces%202", "/path%20with%20spaces%202", -1 }, + { NULL, "http://foo/%aa", G_URI_FLAGS_ENCODED, + "http://foo/%AA", "/%AA", -1 }, + { NULL, "http://foo/p\xc3\xa4th/", G_URI_FLAGS_ENCODED | G_URI_FLAGS_PARSE_RELAXED, + "http://foo/p%C3%A4th/", "/p%C3%A4th/", -1 }, + { NULL, "http://foo", G_URI_FLAGS_NONE, + "http://foo", "", -1 }, + { NULL, "http://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "http://foo/", "/", 80 }, + { NULL, "nothttp://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "nothttp://foo", "", -1 }, + { NULL, "http://foo:80", G_URI_FLAGS_NONE, + "http://foo:80", "", 80 }, + { NULL, "http://foo:80", G_URI_FLAGS_SCHEME_NORMALIZE, + "http://foo/", "/", 80 }, + { NULL, "http://foo:8080", G_URI_FLAGS_SCHEME_NORMALIZE, + "http://foo:8080/", "/", 8080 }, + { NULL, "https://foo:443", G_URI_FLAGS_SCHEME_NORMALIZE, + "https://foo/", "/", 443 }, + { NULL, "https://foo:943", G_URI_FLAGS_SCHEME_NORMALIZE, + "https://foo:943/", "/", 943 }, + { NULL, "ws://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "ws://foo/", "/", 80 }, + { NULL, "wss://foo:443", G_URI_FLAGS_SCHEME_NORMALIZE, + "wss://foo/", "/", 443 }, + { NULL, "ftp://foo", G_URI_FLAGS_NONE, + "ftp://foo", "", -1 }, + { NULL, "ftp://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "ftp://foo", "", 21 }, + { NULL, "ftp://foo:21", G_URI_FLAGS_SCHEME_NORMALIZE, + "ftp://foo", "", 21 }, + { NULL, "ftp://foo:2100", G_URI_FLAGS_SCHEME_NORMALIZE, + "ftp://foo:2100", "", 2100 }, + { NULL, "nothttp://foo:80", G_URI_FLAGS_SCHEME_NORMALIZE, + "nothttp://foo:80", "", 80 }, + { "http://foo", "//bar", G_URI_FLAGS_SCHEME_NORMALIZE, + "http://bar/", "/", 80 }, + { "http://foo", "//bar:80", G_URI_FLAGS_SCHEME_NORMALIZE, + "http://bar/", "/", 80 }, + { "nothttp://foo", "//bar:80", G_URI_FLAGS_SCHEME_NORMALIZE, + "nothttp://bar:80", "", 80 }, + { "http://foo", "//bar", G_URI_FLAGS_NONE, + "http://bar", "", -1 }, + { "ScHeMe://User:P%61ss@HOST.%63om:1234/path", + "ScHeMe://User:P%61ss@HOST.%63om:1234/path/./from/../to%7d/item%2dobj?qu%65ry=something#fr%61gment", + G_URI_FLAGS_SCHEME_NORMALIZE, + "scheme://User:Pass@HOST.com:1234/path/to%7D/item-obj?query=something#fragment", + "/path/to}/item-obj", 1234 }, + }; + +static const struct +{ + /* Inputs */ + const gchar *uri; + GUriFlags flags; + /* Outputs */ + const char *scheme; + const gchar *path; + int port; +} normalize_split_tests[] = + { + { "HTTP://foo", G_URI_FLAGS_ENCODED, + "http", "", -1 }, + { "HTTP://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "http", "/", 80 }, + { "http://foo:80/", G_URI_FLAGS_SCHEME_NORMALIZE, + "http", "/", 80 }, + { "http://foo:8080/bar", G_URI_FLAGS_SCHEME_NORMALIZE, + "http", "/bar", 8080 }, + { "ws://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "ws", "/", 80 }, + { "https://foo", G_URI_FLAGS_ENCODED, + "https", "", -1 }, + { "https://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "https", "/", 443 }, + { "https://foo:443/", G_URI_FLAGS_SCHEME_NORMALIZE, + "https", "/", 443 }, + { "wss://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "wss", "/", 443 }, + { "ftp://foo", G_URI_FLAGS_ENCODED, + "ftp", "", -1 }, + { "ftp://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "ftp", "", 21 }, + { "ftp://foo:21", G_URI_FLAGS_SCHEME_NORMALIZE, + "ftp", "", 21 }, + { "scheme://foo", G_URI_FLAGS_SCHEME_NORMALIZE, + "scheme", "", -1 }, + }; + +static const struct +{ + /* Inputs */ + GUriFlags flags; + const gchar *scheme; + const gchar *host; + int port; + const gchar *path; + /* Outputs */ + const gchar *uri; +} normalize_join_tests[] = + { + { G_URI_FLAGS_NONE, "http", "foo", -1, "", + "http://foo" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", -1, "", + "http://foo/" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", 80, "", + "http://foo/" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", 8080, "", + "http://foo:8080/" }, + { G_URI_FLAGS_NONE, "http", "foo", 80, "", + "http://foo:80" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "ws", "foo", 80, "", + "ws://foo/" }, + { G_URI_FLAGS_NONE, "https", "foo", -1, "", + "https://foo" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", -1, "", + "https://foo/" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", 443, "", + "https://foo/" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", 943, "", + "https://foo:943/" }, + { G_URI_FLAGS_NONE, "https", "foo", 443, "", + "https://foo:443" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "wss", "foo", 443, "", + "wss://foo/" }, + { G_URI_FLAGS_NONE, "ftp", "foo", -1, "", + "ftp://foo" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", -1, "", + "ftp://foo" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", 21, "", + "ftp://foo" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", 2020, "", + "ftp://foo:2020" }, + { G_URI_FLAGS_NONE, "ftp", "foo", 21, "", + "ftp://foo:21" }, + { G_URI_FLAGS_SCHEME_NORMALIZE, "scheme", "foo", 80, "", + "scheme://foo:80" }, + }; + +static void +test_uri_normalize (void) +{ + gsize i; + int port; + char *path; + char *uri_string; + + for (i = 0; i < G_N_ELEMENTS (normalize_parse_tests); ++i) + { + GUri *uri, *base = NULL; + + if (normalize_parse_tests[i].base) + base = g_uri_parse (normalize_parse_tests[i].base, normalize_parse_tests[i].flags, NULL); + + uri = g_uri_parse_relative (base, + normalize_parse_tests[i].uri, + normalize_parse_tests[i].flags, + NULL); + uri_string = g_uri_to_string (uri); + + g_assert_nonnull (uri); + g_assert_cmpstr (g_uri_get_path (uri), ==, normalize_parse_tests[i].path); + g_assert_cmpint (g_uri_get_port (uri), ==, normalize_parse_tests[i].port); + g_assert_cmpstr (uri_string, ==, normalize_parse_tests[i].uri_string); + + g_free (uri_string); + g_uri_unref (uri); + if (base) + g_uri_unref (base); + } + + for (i = 0; i < G_N_ELEMENTS (normalize_split_tests); ++i) + { + char *scheme; + + /* Testing a codepath where scheme is NULL but internally we still normalize it. */ + g_assert_true (g_uri_split (normalize_split_tests[i].uri, normalize_split_tests[i].flags, + NULL, NULL, NULL, &port, &path, NULL, NULL, NULL)); + g_assert_cmpstr (path, ==, normalize_split_tests[i].path); + g_assert_cmpint (port, ==, normalize_split_tests[i].port); + g_free (path); + + g_assert_true (g_uri_split (normalize_split_tests[i].uri, normalize_split_tests[i].flags, + &scheme, NULL, NULL, &port, &path, NULL, NULL, NULL)); + g_assert_cmpstr (scheme, ==, normalize_split_tests[i].scheme); + g_assert_cmpstr (path, ==, normalize_split_tests[i].path); + g_assert_cmpint (port, ==, normalize_split_tests[i].port); + g_free (scheme); + g_free (path); + } + + for (i = 0; i < G_N_ELEMENTS (normalize_join_tests); ++i) + { + uri_string = g_uri_join (normalize_join_tests[i].flags, normalize_join_tests[i].scheme, NULL, + normalize_join_tests[i].host, normalize_join_tests[i].port, + normalize_join_tests[i].path, NULL, NULL); + g_assert_cmpstr (uri_string, ==, normalize_join_tests[i].uri); + g_free (uri_string); + } +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/uri/file-to-uri", run_file_to_uri_tests); + g_test_add_func ("/uri/file-from-uri", run_file_from_uri_tests); + g_test_add_func ("/uri/file-roundtrip", run_file_roundtrip_tests); + g_test_add_func ("/uri/list", run_uri_list_tests); + g_test_add_func ("/uri/unescape-string", test_uri_unescape_string); + g_test_add_data_func ("/uri/unescape-bytes/nul-terminated", GINT_TO_POINTER (TRUE), test_uri_unescape_bytes); + g_test_add_data_func ("/uri/unescape-bytes/length", GINT_TO_POINTER (FALSE), test_uri_unescape_bytes); + g_test_add_func ("/uri/unescape-segment", test_uri_unescape_segment); + g_test_add_func ("/uri/escape-string", test_uri_escape_string); + g_test_add_func ("/uri/escape-bytes", test_uri_escape_bytes); + g_test_add_func ("/uri/scheme", test_uri_scheme); + g_test_add_func ("/uri/parsing/absolute", test_uri_parsing_absolute); + g_test_add_func ("/uri/parsing/relative", test_uri_parsing_relative); + g_test_add_func ("/uri/build", test_uri_build); + g_test_add_func ("/uri/split", test_uri_split); + g_test_add_func ("/uri/is_valid", test_uri_is_valid); + g_test_add_func ("/uri/to-string", test_uri_to_string); + g_test_add_func ("/uri/join", test_uri_join); + g_test_add_func ("/uri/join-split-round-trip", test_uri_join_split_round_trip); + g_test_add_func ("/uri/normalize", test_uri_normalize); + g_test_add_data_func ("/uri/iter-params/nul-terminated", GINT_TO_POINTER (TRUE), test_uri_iter_params); + g_test_add_data_func ("/uri/iter-params/length", GINT_TO_POINTER (FALSE), test_uri_iter_params); + g_test_add_data_func ("/uri/parse-params/nul-terminated", GINT_TO_POINTER (TRUE), test_uri_parse_params); + g_test_add_data_func ("/uri/parse-params/length", GINT_TO_POINTER (FALSE), test_uri_parse_params); + + return g_test_run (); +} diff --git a/glib/tests/utf8-misc.c b/glib/tests/utf8-misc.c new file mode 100644 index 0000000..c137294 --- /dev/null +++ b/glib/tests/utf8-misc.c @@ -0,0 +1,177 @@ +/* Unit tests for utilities + * Copyright (C) 2010 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Matthias Clasen + */ + +#include "glib.h" + +static void +test_utf8_strlen (void) +{ + const gchar *string = "\xe2\x82\xa0gh\xe2\x82\xa4jl"; + + g_assert_cmpint (g_utf8_strlen (string, -1), ==, 6); + g_assert_cmpint (g_utf8_strlen (string, 0), ==, 0); + g_assert_cmpint (g_utf8_strlen (string, 1), ==, 0); + g_assert_cmpint (g_utf8_strlen (string, 2), ==, 0); + g_assert_cmpint (g_utf8_strlen (string, 3), ==, 1); + g_assert_cmpint (g_utf8_strlen (string, 4), ==, 2); + g_assert_cmpint (g_utf8_strlen (string, 5), ==, 3); + g_assert_cmpint (g_utf8_strlen (string, 6), ==, 3); + g_assert_cmpint (g_utf8_strlen (string, 7), ==, 3); + g_assert_cmpint (g_utf8_strlen (string, 8), ==, 4); + g_assert_cmpint (g_utf8_strlen (string, 9), ==, 5); + g_assert_cmpint (g_utf8_strlen (string, 10), ==, 6); +} + +static void +test_utf8_strncpy (void) +{ + const gchar *string = "\xe2\x82\xa0gh\xe2\x82\xa4jl"; + gchar dest[20]; + + g_utf8_strncpy (dest, string, 0); + g_assert_cmpstr (dest, ==, ""); + + g_utf8_strncpy (dest, string, 1); + g_assert_cmpstr (dest, ==, "\xe2\x82\xa0"); + + g_utf8_strncpy (dest, string, 2); + g_assert_cmpstr (dest, ==, "\xe2\x82\xa0g"); + + g_utf8_strncpy (dest, string, 3); + g_assert_cmpstr (dest, ==, "\xe2\x82\xa0gh"); + + g_utf8_strncpy (dest, string, 4); + g_assert_cmpstr (dest, ==, "\xe2\x82\xa0gh\xe2\x82\xa4"); + + g_utf8_strncpy (dest, string, 5); + g_assert_cmpstr (dest, ==, "\xe2\x82\xa0gh\xe2\x82\xa4j"); + + g_utf8_strncpy (dest, string, 6); + g_assert_cmpstr (dest, ==, "\xe2\x82\xa0gh\xe2\x82\xa4jl"); + + g_utf8_strncpy (dest, string, 20); + g_assert_cmpstr (dest, ==, "\xe2\x82\xa0gh\xe2\x82\xa4jl"); +} + +static void +test_utf8_strrchr (void) +{ + const gchar *string = "\xe2\x82\xa0gh\xe2\x82\xa4jl\xe2\x82\xa4jl"; + + g_assert (g_utf8_strrchr (string, -1, 'j') == string + 13); + g_assert (g_utf8_strrchr (string, -1, 8356) == string + 10); + g_assert (g_utf8_strrchr (string, 9, 8356) == string + 5); + g_assert (g_utf8_strrchr (string, 3, 'j') == NULL); + g_assert (g_utf8_strrchr (string, -1, 'x') == NULL); +} + +static void +test_utf8_reverse (void) +{ + gchar *r; + + r = g_utf8_strreverse ("abcdef", -1); + g_assert_cmpstr (r, ==, "fedcba"); + g_free (r); + + r = g_utf8_strreverse ("abcdef", 4); + g_assert_cmpstr (r, ==, "dcba"); + g_free (r); + + /* U+0B0B Oriya Letter Vocalic R + * U+10900 Phoenician Letter Alf + * U+0041 Latin Capital Letter A + * U+1EB6 Latin Capital Letter A With Breve And Dot Below + */ + r = g_utf8_strreverse ("\340\254\213\360\220\244\200\101\341\272\266", -1); + g_assert_cmpstr (r, ==, "\341\272\266\101\360\220\244\200\340\254\213"); + g_free (r); +} + +static void +test_utf8_substring (void) +{ + gchar *r; + + r = g_utf8_substring ("abcd", 1, 3); + g_assert_cmpstr (r, ==, "bc"); + g_free (r); + + r = g_utf8_substring ("abcd", 0, 4); + g_assert_cmpstr (r, ==, "abcd"); + g_free (r); + + r = g_utf8_substring ("abcd", 2, 2); + g_assert_cmpstr (r, ==, ""); + g_free (r); + + r = g_utf8_substring ("abc\xe2\x82\xa0gh\xe2\x82\xa4", 2, 5); + g_assert_cmpstr (r, ==, "c\xe2\x82\xa0g"); + g_free (r); + + r = g_utf8_substring ("abcd", 1, -1); + g_assert_cmpstr (r, ==, "bcd"); + g_free (r); +} + +static void +test_utf8_make_valid (void) +{ + gchar *r; + + /* valid UTF8 */ + r = g_utf8_make_valid ("\xe2\x82\xa0gh\xe2\x82\xa4jl", -1); + g_assert_cmpstr (r, ==, "\xe2\x82\xa0gh\xe2\x82\xa4jl"); + g_free (r); + + /* invalid UTF8 */ + r = g_utf8_make_valid ("\xe2\x82\xa0gh\xe2\xffjl", -1); + g_assert_cmpstr (r, ==, "\xe2\x82\xa0gh\xef\xbf\xbd\xef\xbf\xbdjl"); + g_free (r); + + /* invalid UTF8 without nul terminator followed by something unfortunate */ + r = g_utf8_make_valid ("Bj\xc3\xb8", 3); + g_assert_cmpstr (r, ==, "Bj\xef\xbf\xbd"); + g_free (r); + + /* invalid UTF8 with embedded nul */ + r = g_utf8_make_valid ("\xe2\x82\xa0gh\xe2\x00jl", 9); + g_assert_cmpstr (r, ==, "\xe2\x82\xa0gh\xef\xbf\xbd\xef\xbf\xbdjl"); + g_free (r); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/utf8/strlen", test_utf8_strlen); + g_test_add_func ("/utf8/strncpy", test_utf8_strncpy); + g_test_add_func ("/utf8/strrchr", test_utf8_strrchr); + g_test_add_func ("/utf8/reverse", test_utf8_reverse); + g_test_add_func ("/utf8/substring", test_utf8_substring); + g_test_add_func ("/utf8/make-valid", test_utf8_make_valid); + + return g_test_run(); +} diff --git a/glib/tests/utf8-performance.c b/glib/tests/utf8-performance.c new file mode 100644 index 0000000..a9d06ea --- /dev/null +++ b/glib/tests/utf8-performance.c @@ -0,0 +1,247 @@ +/* GLIB - Library of useful routines for C programming + * + * Copyright (C) 2010 Mikhail Zabaluev + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include + +#include + +#define NUM_ITERATIONS 500000 + +static const char str_ascii[] = + "The quick brown fox jumps over the lazy dog"; + +static const gchar str_latin1[] = + "Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich"; + +/* Energizing GOELRO-talk in Russian, used by KDE */ +static const char str_cyrillic[] = + "Ð¨Ð¸Ñ€Ð¾ÐºÐ°Ñ ÑÐ»ÐµÐºÑ‚Ñ€Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ ÑŽÐ¶Ð½Ñ‹Ñ… губерний даÑÑ‚ мощный толчок подъёму " + "ÑельÑкого хозÑйÑтва."; + +/* First sentence from the Wikipedia article: + * http://zh.wikipedia.org/w/index.php?title=%E6%B1%89%E5%AD%97&oldid=13053137 */ +static const char str_han[] = + "漢字,亦稱中文字ã€ä¸­å›½å­—,在å°ç£åˆè¢«ç¨±ç‚ºåœ‹å­—ï¼Œæ˜¯æ¼¢å­—æ–‡åŒ–åœˆå»£æ³›ä½¿ç”¨çš„ä¸€ç¨®æ–‡å­—ï¼Œå±¬æ–¼è¡¨æ„æ–‡å­—的詞素音節文字"; + +typedef int (* GrindFunc) (const char *, gsize); + +#define GRIND_LOOP_BEGIN \ + { \ + int i; \ + for (i = 0; i < NUM_ITERATIONS; i++) + +#define GRIND_LOOP_END \ + } + +static int +grind_get_char (const char *str, gsize len) +{ + gunichar acc = 0; + GRIND_LOOP_BEGIN + { + const char *p = str; + while (*p) + { + acc += g_utf8_get_char (p); + p = g_utf8_next_char (p); + } + } + GRIND_LOOP_END; + return acc; +} + +static int +grind_get_char_validated (const char *str, gsize len) +{ + gunichar acc = 0; + GRIND_LOOP_BEGIN + { + const char *p = str; + while (*p) + { + acc += g_utf8_get_char_validated (p, -1); + p = g_utf8_next_char (p); + } + } + GRIND_LOOP_END; + return acc; +} + +static int +grind_utf8_to_ucs4 (const char *str, gsize len) +{ + GRIND_LOOP_BEGIN + { + gunichar *ustr; + ustr = g_utf8_to_ucs4 (str, -1, NULL, NULL, NULL); + g_free (ustr); + } + GRIND_LOOP_END; + return 0; +} + +static int +grind_get_char_backwards (const char *str, gsize len) +{ + gunichar acc = 0; + GRIND_LOOP_BEGIN + { + const char *p = str + len; + do + { + p = g_utf8_prev_char (p); + acc += g_utf8_get_char (p); + } + while (p != str); + } + GRIND_LOOP_END; + return acc; +} + +static int +grind_utf8_to_ucs4_sized (const char *str, gsize len) +{ + GRIND_LOOP_BEGIN + { + gunichar *ustr; + ustr = g_utf8_to_ucs4 (str, len, NULL, NULL, NULL); + g_free (ustr); + } + GRIND_LOOP_END; + return 0; +} + +static int +grind_utf8_to_ucs4_fast (const char *str, gsize len) +{ + GRIND_LOOP_BEGIN + { + gunichar *ustr; + ustr = g_utf8_to_ucs4_fast (str, -1, NULL); + g_free (ustr); + } + GRIND_LOOP_END; + return 0; +} + +static int +grind_utf8_to_ucs4_fast_sized (const char *str, gsize len) +{ + GRIND_LOOP_BEGIN + { + gunichar *ustr; + ustr = g_utf8_to_ucs4_fast (str, len, NULL); + g_free (ustr); + } + GRIND_LOOP_END; + return 0; +} + +static int +grind_utf8_validate (const char *str, gsize len) +{ + GRIND_LOOP_BEGIN + g_utf8_validate (str, -1, NULL); + GRIND_LOOP_END; + return 0; +} + +static int +grind_utf8_validate_sized (const char *str, gsize len) +{ + GRIND_LOOP_BEGIN + g_utf8_validate (str, len, NULL); + GRIND_LOOP_END; + return 0; +} + +typedef struct _GrindData { + GrindFunc func; + const char *str; +} GrindData; + +static void +perform (gconstpointer data) +{ + GrindData *gd = (GrindData *) data; + GrindFunc grind_func = gd->func; + const char *str = gd->str; + gsize len; + gulong bytes_ground; + gdouble time_elapsed; + gdouble result; + + len = strlen (str); + bytes_ground = (gulong) len * NUM_ITERATIONS; + + g_test_timer_start (); + + grind_func (str, len); + + time_elapsed = g_test_timer_elapsed (); + + result = ((gdouble) bytes_ground / time_elapsed) * 1.0e-6; + + g_test_maximized_result (result, "%7.1f MB/s", result); + + g_slice_free (GrindData, gd); +} + +static void +add_cases(const char *path, GrindFunc func) +{ +#define ADD_CASE(script) \ + G_STMT_START { \ + GrindData *gd; \ + gchar *full_path; \ + gd = g_slice_new0(GrindData); \ + gd->func = func; \ + gd->str = str_##script; \ + full_path = g_strdup_printf("%s/" #script, path); \ + g_test_add_data_func (full_path, gd, perform); \ + g_free (full_path); \ + } G_STMT_END + + ADD_CASE(ascii); + ADD_CASE(latin1); + ADD_CASE(cyrillic); + ADD_CASE(han); + +#undef ADD_CASE +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + if (g_test_perf ()) + { + add_cases ("/utf8/perf/get_char", grind_get_char); + add_cases ("/utf8/perf/get_char-backwards", grind_get_char_backwards); + add_cases ("/utf8/perf/get_char_validated", grind_get_char_validated); + add_cases ("/utf8/perf/utf8_to_ucs4", grind_utf8_to_ucs4); + add_cases ("/utf8/perf/utf8_to_ucs4-sized", grind_utf8_to_ucs4_sized); + add_cases ("/utf8/perf/utf8_to_ucs4_fast", grind_utf8_to_ucs4_fast); + add_cases ("/utf8/perf/utf8_to_ucs4_fast-sized", grind_utf8_to_ucs4_fast_sized); + add_cases ("/utf8/perf/utf8_validate", grind_utf8_validate); + add_cases ("/utf8/perf/utf8_validate-sized", grind_utf8_validate_sized); + } + + return g_test_run (); +} diff --git a/glib/tests/utf8-pointer.c b/glib/tests/utf8-pointer.c new file mode 100644 index 0000000..5835096 --- /dev/null +++ b/glib/tests/utf8-pointer.c @@ -0,0 +1,188 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include +#include + +/* Test conversions between offsets and pointers */ + +static void test_utf8 (gconstpointer d) +{ + gint num_chars; + const gchar **p; + gint i, j; + const gchar *string = d; + + g_assert (g_utf8_validate (string, -1, NULL)); + + num_chars = g_utf8_strlen (string, -1); + + p = (const gchar **) g_malloc (num_chars * sizeof (gchar *)); + + p[0] = string; + for (i = 1; i < num_chars; i++) + p[i] = g_utf8_next_char (p[i-1]); + + for (i = 0; i < num_chars; i++) + for (j = 0; j < num_chars; j++) + { + g_assert (g_utf8_offset_to_pointer (p[i], j - i) == p[j]); + g_assert (g_utf8_pointer_to_offset (p[i], p[j]) == j - i); + } + + g_free (p); +} + +gchar *longline = "asdasdas dsaf asfd as fdasdf asfd asdf as dfas dfasdf a" +"asd fasdf asdf asdf asd fasfd as fdasfd asdf as fdççççççççças ffsd asfd as fdASASASAs As" +"Asfdsf sdfg sdfg dsfg dfg sdfgsdfgsdfgsdfg sdfgsdfg sdfg sdfg sdf gsdfg sdfg sd" +"asd fasdf asdf asdf asd fasfd as fdaèèèèèèè òòòòòòòòòòòòsfd asdf as fdas ffsd asfd as fdASASASAs D" +"Asfdsf sdfg sdfg dsfg dfg sdfgsdfgsdfgsdfg sdfgsdfg sdfgùùùùùùùùùùùùùù sdfg sdf gsdfg sdfg sd" +"asd fasdf asdf asdf asd fasfd as fdasfd asd@@@@@@@f as fdas ffsd asfd as fdASASASAs D " +"Asfdsf sdfg sdfg dsfg dfg sdfgsdfgsdfgsdfg sdfgsdf€€€€€€€€€€€€€€€€€€g sdfg sdfg sdf gsdfg sdfg sd" +"asd fasdf asdf asdf asd fasfd as fdasfd asdf as fdas ffsd asfd as fdASASASAs D" +"Asfdsf sdfg sdfg dsfg dfg sdfgsdfgsdfgsdfg sdfgsdfg sdfg sdfg sdf gsdfg sdfg sd\n\nlalala\n"; + +static void +test_length (void) +{ + g_assert (g_utf8_strlen ("1234", -1) == 4); + g_assert (g_utf8_strlen ("1234", 0) == 0); + g_assert (g_utf8_strlen ("1234", 1) == 1); + g_assert (g_utf8_strlen ("1234", 2) == 2); + g_assert (g_utf8_strlen ("1234", 3) == 3); + g_assert (g_utf8_strlen ("1234", 4) == 4); + g_assert (g_utf8_strlen ("1234", 5) == 4); + + g_assert (g_utf8_strlen (longline, -1) == 762); + g_assert (g_utf8_strlen (longline, strlen (longline)) == 762); + g_assert (g_utf8_strlen (longline, 1024) == 762); + + g_assert (g_utf8_strlen (NULL, 0) == 0); + + g_assert (g_utf8_strlen ("a\340\250\201c", -1) == 3); + g_assert (g_utf8_strlen ("a\340\250\201c", 1) == 1); + g_assert (g_utf8_strlen ("a\340\250\201c", 2) == 1); + g_assert (g_utf8_strlen ("a\340\250\201c", 3) == 1); + g_assert (g_utf8_strlen ("a\340\250\201c", 4) == 2); + g_assert (g_utf8_strlen ("a\340\250\201c", 5) == 3); +} + +static void +test_find (void) +{ + /* U+0B0B Oriya Letter Vocalic R (\340\254\213) + * U+10900 Phoenician Letter Alf (\360\220\244\200) + * U+0041 Latin Capital Letter A (\101) + * U+1EB6 Latin Capital Letter A With Breve And Dot Below (\341\272\266) + */ +#define TEST_STR "\340\254\213\360\220\244\200\101\341\272\266\0\101" + const gsize str_size = sizeof TEST_STR; + const gchar *str = TEST_STR; + const gchar str_array[] = TEST_STR; + const gchar * volatile str_volatile = TEST_STR; +#undef TEST_STR + gchar *str_copy = g_malloc (str_size); + const gchar *p; + const gchar *q; + memcpy (str_copy, str, str_size); + +#define TEST_SET(STR) \ + G_STMT_START { \ + p = STR + (str_size - 1); \ + \ + q = g_utf8_find_prev_char (STR, p); \ + g_assert (q == STR + 12); \ + q = g_utf8_find_prev_char (STR, q); \ + g_assert (q == STR + 11); \ + q = g_utf8_find_prev_char (STR, q); \ + g_assert (q == STR + 8); \ + q = g_utf8_find_prev_char (STR, q); \ + g_assert (q == STR + 7); \ + q = g_utf8_find_prev_char (STR, q); \ + g_assert (q == STR + 3); \ + q = g_utf8_find_prev_char (STR, q); \ + g_assert (q == STR); \ + q = g_utf8_find_prev_char (STR, q); \ + g_assert_null (q); \ + \ + p = STR + 4; \ + q = g_utf8_find_prev_char (STR, p); \ + g_assert (q == STR + 3); \ + \ + p = STR + 2; \ + q = g_utf8_find_prev_char (STR, p); \ + g_assert (q == STR); \ + \ + p = STR + 2; \ + q = g_utf8_find_next_char (p, NULL); \ + g_assert (q == STR + 3); \ + q = g_utf8_find_next_char (q, NULL); \ + g_assert (q == STR + 7); \ + \ + q = g_utf8_find_next_char (p, STR + 6); \ + g_assert (q == STR + 3); \ + q = g_utf8_find_next_char (q, STR + 6); \ + g_assert_null (q); \ + \ + q = g_utf8_find_next_char (STR, STR); \ + g_assert_null (q); \ + \ + q = g_utf8_find_next_char (STR + strlen (STR), NULL); \ + g_assert (q == STR + strlen (STR) + 1); \ + \ + /* Check return values when reaching the end of the string, \ + * with @end set and unset. */ \ + q = g_utf8_find_next_char (STR + 10, NULL); \ + g_assert_nonnull (q); \ + g_assert (*q == '\0'); \ + \ + q = g_utf8_find_next_char (STR + 10, STR + 11); \ + g_assert_null (q); \ + } G_STMT_END + + TEST_SET(str_array); + TEST_SET(str_copy); + TEST_SET(str_volatile); + /* Starting with GCC 8 tests on @str with "-O2 -flto" in CFLAGS fail due to + * (incorrect?) constant propagation of @str into @g_utf8_find_prev_char. It + * doesn't happen if @TEST_STR doesn't contain \0 in the middle but the tests + * should cover all corner cases. + * For instance, see https://gitlab.gnome.org/GNOME/glib/issues/1917 */ + +#undef TEST_SET + + g_free (str_copy); +} + +int main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_data_func ("/utf8/offsets", longline, test_utf8); + g_test_add_func ("/utf8/lengths", test_length); + g_test_add_func ("/utf8/find", test_find); + + return g_test_run (); +} diff --git a/glib/tests/utf8-validate.c b/glib/tests/utf8-validate.c new file mode 100644 index 0000000..41d19ad --- /dev/null +++ b/glib/tests/utf8-validate.c @@ -0,0 +1,377 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2001 Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "glib.h" +#include + +#define UNICODE_VALID(Char) \ + ((Char) < 0x110000 && \ + (((Char) & 0xFFFFF800) != 0xD800) && \ + ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \ + ((Char) & 0xFFFE) != 0xFFFE) + + +typedef struct { + const gchar *text; + gint max_len; + gint offset; + gboolean valid; +} Test; + +static Test global_test[] = { + /* some tests to check max_len handling */ + /* length 1 */ + { "abcde", -1, 5, TRUE }, + { "abcde", 3, 3, TRUE }, + { "abcde", 5, 5, TRUE }, + { "abcde", 7, 5, FALSE }, + /* length 2 */ + { "\xc2\xa9\xc2\xa9\xc2\xa9", -1, 6, TRUE }, + { "\xc2\xa9\xc2\xa9\xc2\xa9", 1, 0, FALSE }, + { "\xc2\xa9\xc2\xa9\xc2\xa9", 2, 2, TRUE }, + { "\xc2\xa9\xc2\xa9\xc2\xa9", 3, 2, FALSE }, + { "\xc2\xa9\xc2\xa9\xc2\xa9", 4, 4, TRUE }, + { "\xc2\xa9\xc2\xa9\xc2\xa9", 5, 4, FALSE }, + { "\xc2\xa9\xc2\xa9\xc2\xa9", 6, 6, TRUE }, + { "\xc2\xa9\xc2\xa9\xc2\xa9", 7, 6, FALSE }, + /* length 3 */ + { "\xe2\x89\xa0\xe2\x89\xa0", -1, 6, TRUE }, + { "\xe2\x89\xa0\xe2\x89\xa0", 1, 0, FALSE }, + { "\xe2\x89\xa0\xe2\x89\xa0", 2, 0, FALSE }, + { "\xe2\x89\xa0\xe2\x89\xa0", 3, 3, TRUE }, + { "\xe2\x89\xa0\xe2\x89\xa0", 4, 3, FALSE }, + { "\xe2\x89\xa0\xe2\x89\xa0", 5, 3, FALSE }, + { "\xe2\x89\xa0\xe2\x89\xa0", 6, 6, TRUE }, + { "\xe2\x89\xa0\xe2\x89\xa0", 7, 6, FALSE }, + + /* examples from http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */ + /* greek 'kosme' */ + { "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5", -1, 11, TRUE }, + /* first sequence of each length */ + { "\x00", -1, 0, TRUE }, + { "\xc2\x80", -1, 2, TRUE }, + { "\xe0\xa0\x80", -1, 3, TRUE }, + { "\xf0\x90\x80\x80", -1, 4, TRUE }, + { "\xf8\x88\x80\x80\x80", -1, 0, FALSE }, + { "\xfc\x84\x80\x80\x80\x80", -1, 0, FALSE }, + /* last sequence of each length */ + { "\x7f", -1, 1, TRUE }, + { "\xdf\xbf", -1, 2, TRUE }, + { "\xef\xbf\xbf", -1, 3, TRUE }, + { "\xf7\xbf\xbf\xbf", -1, 0, FALSE }, + { "\xfb\xbf\xbf\xbf\xbf", -1, 0, FALSE }, + { "\xfd\xbf\xbf\xbf\xbf\xbf", -1, 0, FALSE }, + /* other boundary conditions */ + { "\xed\x9f\xbf", -1, 3, TRUE }, + { "\xee\x80\x80", -1, 3, TRUE }, + { "\xef\xbf\xbd", -1, 3, TRUE }, + { "\xf4\x8f\xbf\xbf", -1, 4, TRUE }, + { "\xf4\x90\x80\x80", -1, 0, FALSE }, + /* malformed sequences */ + /* continuation bytes */ + { "\x80", -1, 0, FALSE }, + { "\xbf", -1, 0, FALSE }, + { "\xbf\x80", -1, 0, FALSE }, + { "\x80\xbf", -1, 0, FALSE }, + { "\x80\xbf\x80", -1, 0, FALSE }, + { "\x80\xbf\x80\xbf", -1, 0, FALSE }, + { "\x80\xbf\x80\xbf\x80", -1, 0, FALSE }, + { "\x80\xbf\x80\xbf\x80\xbf", -1, 0, FALSE }, + { "\x80\xbf\x80\xbf\x80\xbf\x80", -1, 0, FALSE }, + + /* all possible continuation byte */ + { "\x80", -1, 0, FALSE }, + { "\x81", -1, 0, FALSE }, + { "\x82", -1, 0, FALSE }, + { "\x83", -1, 0, FALSE }, + { "\x84", -1, 0, FALSE }, + { "\x85", -1, 0, FALSE }, + { "\x86", -1, 0, FALSE }, + { "\x87", -1, 0, FALSE }, + { "\x88", -1, 0, FALSE }, + { "\x89", -1, 0, FALSE }, + { "\x8a", -1, 0, FALSE }, + { "\x8b", -1, 0, FALSE }, + { "\x8c", -1, 0, FALSE }, + { "\x8d", -1, 0, FALSE }, + { "\x8e", -1, 0, FALSE }, + { "\x8f", -1, 0, FALSE }, + { "\x90", -1, 0, FALSE }, + { "\x91", -1, 0, FALSE }, + { "\x92", -1, 0, FALSE }, + { "\x93", -1, 0, FALSE }, + { "\x94", -1, 0, FALSE }, + { "\x95", -1, 0, FALSE }, + { "\x96", -1, 0, FALSE }, + { "\x97", -1, 0, FALSE }, + { "\x98", -1, 0, FALSE }, + { "\x99", -1, 0, FALSE }, + { "\x9a", -1, 0, FALSE }, + { "\x9b", -1, 0, FALSE }, + { "\x9c", -1, 0, FALSE }, + { "\x9d", -1, 0, FALSE }, + { "\x9e", -1, 0, FALSE }, + { "\x9f", -1, 0, FALSE }, + { "\xa0", -1, 0, FALSE }, + { "\xa1", -1, 0, FALSE }, + { "\xa2", -1, 0, FALSE }, + { "\xa3", -1, 0, FALSE }, + { "\xa4", -1, 0, FALSE }, + { "\xa5", -1, 0, FALSE }, + { "\xa6", -1, 0, FALSE }, + { "\xa7", -1, 0, FALSE }, + { "\xa8", -1, 0, FALSE }, + { "\xa9", -1, 0, FALSE }, + { "\xaa", -1, 0, FALSE }, + { "\xab", -1, 0, FALSE }, + { "\xac", -1, 0, FALSE }, + { "\xad", -1, 0, FALSE }, + { "\xae", -1, 0, FALSE }, + { "\xaf", -1, 0, FALSE }, + { "\xb0", -1, 0, FALSE }, + { "\xb1", -1, 0, FALSE }, + { "\xb2", -1, 0, FALSE }, + { "\xb3", -1, 0, FALSE }, + { "\xb4", -1, 0, FALSE }, + { "\xb5", -1, 0, FALSE }, + { "\xb6", -1, 0, FALSE }, + { "\xb7", -1, 0, FALSE }, + { "\xb8", -1, 0, FALSE }, + { "\xb9", -1, 0, FALSE }, + { "\xba", -1, 0, FALSE }, + { "\xbb", -1, 0, FALSE }, + { "\xbc", -1, 0, FALSE }, + { "\xbd", -1, 0, FALSE }, + { "\xbe", -1, 0, FALSE }, + { "\xbf", -1, 0, FALSE }, + /* lone start characters */ + { "\xc0\x20", -1, 0, FALSE }, + { "\xc1\x20", -1, 0, FALSE }, + { "\xc2\x20", -1, 0, FALSE }, + { "\xc3\x20", -1, 0, FALSE }, + { "\xc4\x20", -1, 0, FALSE }, + { "\xc5\x20", -1, 0, FALSE }, + { "\xc6\x20", -1, 0, FALSE }, + { "\xc7\x20", -1, 0, FALSE }, + { "\xc8\x20", -1, 0, FALSE }, + { "\xc9\x20", -1, 0, FALSE }, + { "\xca\x20", -1, 0, FALSE }, + { "\xcb\x20", -1, 0, FALSE }, + { "\xcc\x20", -1, 0, FALSE }, + { "\xcd\x20", -1, 0, FALSE }, + { "\xce\x20", -1, 0, FALSE }, + { "\xcf\x20", -1, 0, FALSE }, + { "\xd0\x20", -1, 0, FALSE }, + { "\xd1\x20", -1, 0, FALSE }, + { "\xd2\x20", -1, 0, FALSE }, + { "\xd3\x20", -1, 0, FALSE }, + { "\xd4\x20", -1, 0, FALSE }, + { "\xd5\x20", -1, 0, FALSE }, + { "\xd6\x20", -1, 0, FALSE }, + { "\xd7\x20", -1, 0, FALSE }, + { "\xd8\x20", -1, 0, FALSE }, + { "\xd9\x20", -1, 0, FALSE }, + { "\xda\x20", -1, 0, FALSE }, + { "\xdb\x20", -1, 0, FALSE }, + { "\xdc\x20", -1, 0, FALSE }, + { "\xdd\x20", -1, 0, FALSE }, + { "\xde\x20", -1, 0, FALSE }, + { "\xdf\x20", -1, 0, FALSE }, + { "\xe0\x20", -1, 0, FALSE }, + { "\xe1\x20", -1, 0, FALSE }, + { "\xe2\x20", -1, 0, FALSE }, + { "\xe3\x20", -1, 0, FALSE }, + { "\xe4\x20", -1, 0, FALSE }, + { "\xe5\x20", -1, 0, FALSE }, + { "\xe6\x20", -1, 0, FALSE }, + { "\xe7\x20", -1, 0, FALSE }, + { "\xe8\x20", -1, 0, FALSE }, + { "\xe9\x20", -1, 0, FALSE }, + { "\xea\x20", -1, 0, FALSE }, + { "\xeb\x20", -1, 0, FALSE }, + { "\xec\x20", -1, 0, FALSE }, + { "\xed\x20", -1, 0, FALSE }, + { "\xee\x20", -1, 0, FALSE }, + { "\xef\x20", -1, 0, FALSE }, + { "\xf0\x20", -1, 0, FALSE }, + { "\xf1\x20", -1, 0, FALSE }, + { "\xf2\x20", -1, 0, FALSE }, + { "\xf3\x20", -1, 0, FALSE }, + { "\xf4\x20", -1, 0, FALSE }, + { "\xf5\x20", -1, 0, FALSE }, + { "\xf6\x20", -1, 0, FALSE }, + { "\xf7\x20", -1, 0, FALSE }, + { "\xf8\x20", -1, 0, FALSE }, + { "\xf9\x20", -1, 0, FALSE }, + { "\xfa\x20", -1, 0, FALSE }, + { "\xfb\x20", -1, 0, FALSE }, + { "\xfc\x20", -1, 0, FALSE }, + { "\xfd\x20", -1, 0, FALSE }, + /* missing continuation bytes */ + { "\x20\xc0", -1, 1, FALSE }, + { "\x20\xe0\x80", -1, 1, FALSE }, + { "\x20\xf0\x80\x80", -1, 1, FALSE }, + { "\x20\xf8\x80\x80\x80", -1, 1, FALSE }, + { "\x20\xfc\x80\x80\x80\x80", -1, 1, FALSE }, + { "\x20\xdf", -1, 1, FALSE }, + { "\x20\xef\xbf", -1, 1, FALSE }, + { "\x20\xf7\xbf\xbf", -1, 1, FALSE }, + { "\x20\xfb\xbf\xbf\xbf", -1, 1, FALSE }, + { "\x20\xfd\xbf\xbf\xbf\xbf", -1, 1, FALSE }, + /* impossible bytes */ + { "\x20\xfe\x20", -1, 1, FALSE }, + { "\x20\xff\x20", -1, 1, FALSE }, + /* overlong sequences */ + { "\x20\xc0\xaf\x20", -1, 1, FALSE }, + { "\x20\xe0\x80\xaf\x20", -1, 1, FALSE }, + { "\x20\xf0\x80\x80\xaf\x20", -1, 1, FALSE }, + { "\x20\xf8\x80\x80\x80\xaf\x20", -1, 1, FALSE }, + { "\x20\xfc\x80\x80\x80\x80\xaf\x20", -1, 1, FALSE }, + { "\x20\xc1\xbf\x20", -1, 1, FALSE }, + { "\x20\xe0\x9f\xbf\x20", -1, 1, FALSE }, + { "\x20\xf0\x8f\xbf\xbf\x20", -1, 1, FALSE }, + { "\x20\xf8\x87\xbf\xbf\xbf\x20", -1, 1, FALSE }, + { "\x20\xfc\x83\xbf\xbf\xbf\xbf\x20", -1, 1, FALSE }, + { "\x20\xc0\x80\x20", -1, 1, FALSE }, + { "\x20\xe0\x80\x80\x20", -1, 1, FALSE }, + { "\x20\xf0\x80\x80\x80\x20", -1, 1, FALSE }, + { "\x20\xf8\x80\x80\x80\x80\x20", -1, 1, FALSE }, + { "\x20\xfc\x80\x80\x80\x80\x80\x20", -1, 1, FALSE }, + /* illegal code positions */ + { "\x20\xed\xa0\x80\x20", -1, 1, FALSE }, + { "\x20\xed\xad\xbf\x20", -1, 1, FALSE }, + { "\x20\xed\xae\x80\x20", -1, 1, FALSE }, + { "\x20\xed\xaf\xbf\x20", -1, 1, FALSE }, + { "\x20\xed\xb0\x80\x20", -1, 1, FALSE }, + { "\x20\xed\xbe\x80\x20", -1, 1, FALSE }, + { "\x20\xed\xbf\xbf\x20", -1, 1, FALSE }, + { "\x20\xed\xa0\x80\xed\xb0\x80\x20", -1, 1, FALSE }, + { "\x20\xed\xa0\x80\xed\xbf\xbf\x20", -1, 1, FALSE }, + { "\x20\xed\xad\xbf\xed\xb0\x80\x20", -1, 1, FALSE }, + { "\x20\xed\xad\xbf\xed\xbf\xbf\x20", -1, 1, FALSE }, + { "\x20\xed\xae\x80\xed\xb0\x80\x20", -1, 1, FALSE }, + { "\x20\xed\xae\x80\xed\xbf\xbf\x20", -1, 1, FALSE }, + { "\x20\xed\xaf\xbf\xed\xb0\x80\x20", -1, 1, FALSE }, + { "\x20\xed\xaf\xbf\xed\xbf\xbf\x20", -1, 1, FALSE }, + + { NULL, 0, 0, 0 } +}; + +static void +do_test (gconstpointer d) +{ + const Test *test = d; + const gchar *end; + gboolean result; + + result = g_utf8_validate (test->text, test->max_len, &end); + + g_assert_true (result == test->valid); + g_assert_cmpint (end - test->text, ==, test->offset); + + if (test->max_len < 0) + { + result = g_utf8_validate (test->text, strlen (test->text), &end); + + g_assert_true (result == test->valid); + g_assert_cmpint (end - test->text, ==, test->offset); + } + else + { + result = g_utf8_validate_len (test->text, test->max_len, &end); + + g_assert_true (result == test->valid); + g_assert_cmpint (end - test->text, ==, test->offset); + } +} + +/* Test the behaviour of g_utf8_get_char_validated() with various inputs and + * length restrictions. */ +static void +test_utf8_get_char_validated (void) +{ + const struct { + const gchar *buf; + gssize max_len; + gunichar expected_result; + } test_vectors[] = { + /* Bug #780095: */ + { "\xC0\x00_45678", 8, (gunichar) -2 }, + { "\xC0\x00_45678", -1, (gunichar) -2 }, + /* It seems odd that the return value differs with the length input, but + * that’s how it’s documented: */ + { "", 0, (gunichar) -2 }, + { "", -1, (gunichar) 0 }, + { "\0", 1, (gunichar) -2 }, + { "AB\0", 3, 'A' }, + { "A\0B", 3, 'A' }, + { "\0AB", 3, (gunichar) -2 }, + { "\xD8\0", 2, (gunichar) -2 }, + /* Normal inputs: */ + { "hello", 5, (gunichar) 'h' }, + { "hello", -1, (gunichar) 'h' }, + { "\xD8\x9F", 2, 0x061F }, + { "\xD8\x9F", -1, 0x061F }, + { "\xD8\x9Fmore", 6, 0x061F }, + { "\xD8\x9Fmore", -1, 0x061F }, + { "\xD8\x9F\0", 3, 0x061F }, + { "\xE2\x96\xB3", 3, 0x25B3 }, + { "\xE2\x96\xB3", -1, 0x25B3 }, + { "\xE2\x96\xB3more", 7, 0x25B3 }, + { "\xE2\x96\xB3more", -1, 0x25B3 }, + { "\xF0\x9F\x92\xA9", 4, 0x1F4A9 }, + { "\xF0\x9F\x92\xA9", -1, 0x1F4A9 }, + { "\xF0\x9F\x92\xA9more", 8, 0x1F4A9 }, + { "\xF0\x9F\x92\xA9more", -1, 0x1F4A9 }, + /* Partial unichars: */ + { "\xD8", -1, (gunichar) -2 }, + { "\xD8\x9F", 1, (gunichar) -2 }, + { "\xCE", -1, (gunichar) -2 }, + { "\xCE", 1, (gunichar) -2 }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (test_vectors); i++) + { + gunichar actual_result; + + g_test_message ("Vector %" G_GSIZE_FORMAT, i); + actual_result = g_utf8_get_char_validated (test_vectors[i].buf, + test_vectors[i].max_len); + g_assert_cmpint (actual_result, ==, test_vectors[i].expected_result); + } +} + +int +main (int argc, char *argv[]) +{ + gint i; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + for (i = 0; global_test[i].text; i++) + { + path = g_strdup_printf ("/utf8/validate/%d", i); + g_test_add_data_func (path, &global_test[i], do_test); + g_free (path); + } + + g_test_add_func ("/utf8/get-char-validated", test_utf8_get_char_validated); + + return g_test_run (); +} diff --git a/glib/tests/utils.c b/glib/tests/utils.c new file mode 100644 index 0000000..11fed55 --- /dev/null +++ b/glib/tests/utils.c @@ -0,0 +1,1184 @@ +/* Unit tests for utilities + * Copyright (C) 2010 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Matthias Clasen + */ + +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "glib.h" +#include "glib-private.h" + +#include +#include +#include +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include +#endif + +static gboolean +strv_check (const gchar * const *strv, ...) +{ + va_list args; + gchar *s; + gint i; + + va_start (args, strv); + for (i = 0; strv[i]; i++) + { + s = va_arg (args, gchar*); + if (g_strcmp0 (strv[i], s) != 0) + { + va_end (args); + return FALSE; + } + } + + va_end (args); + + return TRUE; +} + +static void +test_language_names (void) +{ + const gchar * const *names; + + g_setenv ("LANGUAGE", "de:en_US", TRUE); + names = g_get_language_names (); + g_assert (strv_check (names, "de", "en_US", "en", "C", NULL)); + + g_setenv ("LANGUAGE", "tt_RU.UTF-8@iqtelif", TRUE); + names = g_get_language_names (); + g_assert (strv_check (names, + "tt_RU.UTF-8@iqtelif", + "tt_RU@iqtelif", + "tt.UTF-8@iqtelif", + "tt@iqtelif", + "tt_RU.UTF-8", + "tt_RU", + "tt.UTF-8", + "tt", + "C", + NULL)); +} + +static void +test_locale_variants (void) +{ + char **v; + + v = g_get_locale_variants ("fr_BE"); + g_assert (strv_check ((const gchar * const *) v, "fr_BE", "fr", NULL)); + g_strfreev (v); + + v = g_get_locale_variants ("sr_SR@latin"); + g_assert (strv_check ((const gchar * const *) v, "sr_SR@latin", "sr@latin", "sr_SR", "sr", NULL)); + g_strfreev (v); +} + +static void +test_version (void) +{ + if (g_test_verbose ()) + g_printerr ("(header %d.%d.%d library %d.%d.%d) ", + GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION, + glib_major_version, glib_minor_version, glib_micro_version); + + g_assert (glib_check_version (GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION, + GLIB_MICRO_VERSION) == NULL); + g_assert (glib_check_version (GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION, + 0) == NULL); + g_assert (glib_check_version (GLIB_MAJOR_VERSION - 1, + 0, + 0) != NULL); + g_assert (glib_check_version (GLIB_MAJOR_VERSION + 1, + 0, + 0) != NULL); + g_assert (glib_check_version (GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION + 1, + 0) != NULL); + /* don't use + 1 here, since a +/-1 difference can + * happen due to post-release version bumps in git + */ + g_assert (glib_check_version (GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION, + GLIB_MICRO_VERSION + 3) != NULL); +} + +static const gchar *argv0; + +static void +test_appname (void) +{ + const gchar *prgname; + const gchar *appname; + + prgname = g_get_prgname (); + appname = g_get_application_name (); + g_assert_cmpstr (prgname, ==, argv0); + g_assert_cmpstr (appname, ==, prgname); + + g_set_prgname ("prgname"); + + prgname = g_get_prgname (); + appname = g_get_application_name (); + g_assert_cmpstr (prgname, ==, "prgname"); + g_assert_cmpstr (appname, ==, "prgname"); + + g_set_application_name ("appname"); + + prgname = g_get_prgname (); + appname = g_get_application_name (); + g_assert_cmpstr (prgname, ==, "prgname"); + g_assert_cmpstr (appname, ==, "appname"); +} + +static gpointer +thread_prgname_check (gpointer data) +{ + gint *n_threads_got_prgname = (gint *) data; + const gchar *old_prgname; + + old_prgname = g_get_prgname (); + g_assert_cmpstr (old_prgname, ==, "prgname"); + + g_atomic_int_inc (n_threads_got_prgname); + + while (g_strcmp0 (g_get_prgname (), "prgname2") != 0); + + return NULL; +} + +static void +test_prgname_thread_safety (void) +{ + gsize i; + gint n_threads_got_prgname; + GThread *threads[4]; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/847"); + g_test_summary ("Test that threads racing to get and set the program name " + "always receive a valid program name."); + + g_set_prgname ("prgname"); + g_atomic_int_set (&n_threads_got_prgname, 0); + + for (i = 0; i < G_N_ELEMENTS (threads); i++) + threads[i] = g_thread_new (NULL, thread_prgname_check, &n_threads_got_prgname); + + while (g_atomic_int_get (&n_threads_got_prgname) != G_N_ELEMENTS (threads)) + g_usleep (50); + + g_set_prgname ("prgname2"); + + /* Wait for all the workers to exit. */ + for (i = 0; i < G_N_ELEMENTS (threads); i++) + g_thread_join (threads[i]); + + /* reset prgname */ + g_set_prgname ("prgname"); +} + +static void +test_tmpdir (void) +{ + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=627969"); + g_assert_cmpstr (g_get_tmp_dir (), !=, ""); +} + +#if defined(__GNUC__) && (__GNUC__ >= 4) +#define TEST_BUILTINS 1 +#else +#define TEST_BUILTINS 0 +#endif + +#if TEST_BUILTINS +static gint +builtin_bit_nth_lsf1 (gulong mask, gint nth_bit) +{ + if (nth_bit >= 0) + { + if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1)) + mask &= -(1UL << (nth_bit + 1)); + else + mask = 0; + } + return __builtin_ffsl (mask) - 1; +} + +static gint +builtin_bit_nth_lsf2 (gulong mask, gint nth_bit) +{ + if (nth_bit >= 0) + { + if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1)) + mask &= -(1UL << (nth_bit + 1)); + else + mask = 0; + } + return mask ? __builtin_ctzl (mask) : -1; +} + +static gint +builtin_bit_nth_msf (gulong mask, gint nth_bit) +{ + if (nth_bit >= 0 && nth_bit < GLIB_SIZEOF_LONG * 8) + mask &= (1UL << nth_bit) - 1; + return mask ? GLIB_SIZEOF_LONG * 8 - 1 - __builtin_clzl (mask) : -1; +} + +static guint +builtin_bit_storage (gulong number) +{ + return number ? GLIB_SIZEOF_LONG * 8 - __builtin_clzl (number) : 1; +} +#endif + +static gint +naive_bit_nth_lsf (gulong mask, gint nth_bit) +{ + if (G_UNLIKELY (nth_bit < -1)) + nth_bit = -1; + while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1)) + { + nth_bit++; + if (mask & (1UL << nth_bit)) + return nth_bit; + } + return -1; +} + +static gint +naive_bit_nth_msf (gulong mask, gint nth_bit) +{ + if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8)) + nth_bit = GLIB_SIZEOF_LONG * 8; + while (nth_bit > 0) + { + nth_bit--; + if (mask & (1UL << nth_bit)) + return nth_bit; + } + return -1; +} + +static guint +naive_bit_storage (gulong number) +{ + guint n_bits = 0; + + do + { + n_bits++; + number >>= 1; + } + while (number); + return n_bits; +} + +static void +test_basic_bits (void) +{ + gulong i; + gint nth_bit; + + /* we loop like this: 0, -1, 1, -2, 2, -3, 3, ... */ + for (i = 0; (glong) i < 1500; i = -(i + ((glong) i >= 0))) + { + guint naive_bit_storage_i = naive_bit_storage (i); + + /* Test the g_bit_*() implementations against the compiler builtins (if + * available), and against a slow-but-correct ‘naive’ implementation. + * They should all agree. + * + * The macro and function versions of the g_bit_*() functions are tested, + * hence one call with the function name in brackets (to avoid it being + * expanded as a macro). */ +#if TEST_BUILTINS + g_assert_cmpint (naive_bit_storage_i, ==, builtin_bit_storage (i)); +#endif + g_assert_cmpint (naive_bit_storage_i, ==, g_bit_storage (i)); + g_assert_cmpint (naive_bit_storage_i, ==, (g_bit_storage) (i)); + + for (nth_bit = -3; nth_bit <= 2 + GLIB_SIZEOF_LONG * 8; nth_bit++) + { + gint naive_bit_nth_lsf_i_nth_bit = naive_bit_nth_lsf (i, nth_bit); + gint naive_bit_nth_msf_i_nth_bit = naive_bit_nth_msf (i, nth_bit); + +#if TEST_BUILTINS + g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==, + builtin_bit_nth_lsf1 (i, nth_bit)); + g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==, + builtin_bit_nth_lsf2 (i, nth_bit)); +#endif + g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==, + g_bit_nth_lsf (i, nth_bit)); + g_assert_cmpint (naive_bit_nth_lsf_i_nth_bit, ==, + (g_bit_nth_lsf) (i, nth_bit)); + +#if TEST_BUILTINS + g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==, + builtin_bit_nth_msf (i, nth_bit)); +#endif + g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==, + g_bit_nth_msf (i, nth_bit)); + g_assert_cmpint (naive_bit_nth_msf_i_nth_bit, ==, + (g_bit_nth_msf) (i, nth_bit)); + } + } +} + +static void +test_bits (void) +{ + gulong mask; + gint max_bit; + gint i, pos; + + pos = g_bit_nth_lsf (0, -1); + g_assert_cmpint (pos, ==, -1); + + max_bit = sizeof (gulong) * 8; + for (i = 0; i < max_bit; i++) + { + mask = 1UL << i; + + pos = g_bit_nth_lsf (mask, -1); + g_assert_cmpint (pos, ==, i); + + pos = g_bit_nth_lsf (mask, i - 3); + g_assert_cmpint (pos , ==, i); + + pos = g_bit_nth_lsf (mask, i); + g_assert_cmpint (pos , ==, -1); + + pos = g_bit_nth_lsf (mask, i + 1); + g_assert_cmpint (pos , ==, -1); + } + + pos = g_bit_nth_msf (0, -1); + g_assert_cmpint (pos, ==, -1); + + for (i = 0; i < max_bit; i++) + { + mask = 1UL << i; + + pos = g_bit_nth_msf (mask, -1); + g_assert_cmpint (pos, ==, i); + + pos = g_bit_nth_msf (mask, i + 3); + g_assert_cmpint (pos , ==, i); + + pos = g_bit_nth_msf (mask, i); + g_assert_cmpint (pos , ==, -1); + + if (i > 0) + { + pos = g_bit_nth_msf (mask, i - 1); + g_assert_cmpint (pos , ==, -1); + } + } +} + +static void +test_swap (void) +{ + guint16 a16, b16; + guint32 a32, b32; + guint64 a64, b64; + + a16 = 0xaabb; + b16 = 0xbbaa; + + g_assert_cmpint (GUINT16_SWAP_LE_BE (a16), ==, b16); + + a32 = 0xaaaabbbb; + b32 = 0xbbbbaaaa; + + g_assert_cmpint (GUINT32_SWAP_LE_BE (a32), ==, b32); + + a64 = G_GUINT64_CONSTANT(0xaaaaaaaabbbbbbbb); + b64 = G_GUINT64_CONSTANT(0xbbbbbbbbaaaaaaaa); + + g_assert_cmpint (GUINT64_SWAP_LE_BE (a64), ==, b64); +} + +static void +test_find_program (void) +{ + gchar *res; + +#ifdef G_OS_UNIX + gchar *relative_path; + gchar *absolute_path; + gchar *cwd; + gsize i; + + res = g_find_program_in_path ("sh"); + g_assert (res != NULL); + g_free (res); + + res = g_find_program_in_path ("/bin/sh"); + g_assert (res != NULL); + g_free (res); + + cwd = g_get_current_dir (); + absolute_path = g_find_program_in_path ("sh"); + relative_path = g_strdup (absolute_path); + for (i = 0; cwd[i] != '\0'; i++) + { + if (cwd[i] == '/' && cwd[i + 1] != '\0') + { + gchar *relative_path_2 = g_strconcat ("../", relative_path, NULL); + g_free (relative_path); + relative_path = relative_path_2; + } + } + res = g_find_program_in_path (relative_path); + g_assert_nonnull (res); + g_assert_true (g_path_is_absolute (res)); + g_free (cwd); + g_free (absolute_path); + g_free (relative_path); + g_free (res); + +#else + /* There's not a lot we can search for that would reliably work both + * on real Windows and mingw. + */ +#endif + + res = g_find_program_in_path ("this_program_does_not_exit"); + g_assert (res == NULL); + + res = g_find_program_in_path ("/bin"); + g_assert (res == NULL); + + res = g_find_program_in_path ("/etc/passwd"); + g_assert (res == NULL); +} + +static void +test_debug (void) +{ + GDebugKey keys[] = { + { "key1", 1 }, + { "key2", 2 }, + { "key3", 4 }, + }; + guint res; + + res = g_parse_debug_string (NULL, keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 0); + + res = g_parse_debug_string ("foobabla;#!%!$%112 223", keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 0); + + res = g_parse_debug_string ("key1:key2", keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 3); + + res = g_parse_debug_string ("key1;key2", keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 3); + + res = g_parse_debug_string ("key1,key2", keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 3); + + res = g_parse_debug_string ("key1 key2", keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 3); + + res = g_parse_debug_string ("key1\tkey2", keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 3); + + res = g_parse_debug_string ("all", keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 7); + + if (g_test_subprocess ()) + { + res = g_parse_debug_string ("help", keys, G_N_ELEMENTS (keys)); + g_assert_cmpint (res, ==, 0); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*Supported debug values: key1 key2 key3 all help*"); +} + +static void +test_codeset (void) +{ + gchar *c; + const gchar *c2; + + c = g_get_codeset (); + g_get_charset (&c2); + + g_assert_cmpstr (c, ==, c2); + + g_free (c); +} + +static void +test_codeset2 (void) +{ + if (g_test_subprocess ()) + { + const gchar *c; + g_setenv ("CHARSET", "UTF-8", TRUE); + g_get_charset (&c); + g_assert_cmpstr (c, ==, "UTF-8"); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); +} + +static void +test_console_charset (void) +{ + const gchar *c1; + const gchar *c2; + +#ifdef G_OS_WIN32 + /* store current environment and unset $LANG to make sure it does not interfere */ + const unsigned int initial_cp = GetConsoleOutputCP (); + gchar *initial_lang = g_strdup (g_getenv ("LANG")); + g_unsetenv ("LANG"); + + /* set console output codepage to something specific (ISO-8859-1 aka CP28591) and query it */ + SetConsoleOutputCP (28591); + g_get_console_charset (&c1); + g_assert_cmpstr (c1, ==, "ISO-8859-1"); + + /* set $LANG to something specific (should override the console output codepage) and query it */ + g_setenv ("LANG", "de_DE.ISO-8859-15@euro", TRUE); + g_get_console_charset (&c2); + g_assert_cmpstr (c2, ==, "ISO-8859-15"); + + /* reset environment */ + if (initial_cp) + SetConsoleOutputCP (initial_cp); + if (initial_lang) + g_setenv ("LANG", initial_lang, TRUE); + g_free (initial_lang); +#else + g_get_charset (&c1); + g_get_console_charset (&c2); + + g_assert_cmpstr (c1, ==, c2); +#endif +} + +extern const gchar *glib_pgettext (const gchar *msgidctxt, gsize msgidoffset); + +static void +test_gettext (void) +{ + const gchar *am0, *am1, *am2, *am3; + + am0 = glib_pgettext ("GDateTime\004AM", strlen ("GDateTime") + 1); + am1 = g_dpgettext ("glib20", "GDateTime\004AM", strlen ("GDateTime") + 1); + am2 = g_dpgettext ("glib20", "GDateTime|AM", 0); + am3 = g_dpgettext2 ("glib20", "GDateTime", "AM"); + + g_assert_cmpstr (am0, ==, am1); + g_assert_cmpstr (am1, ==, am2); + g_assert_cmpstr (am2, ==, am3); +} + +static void +test_username (void) +{ + const gchar *name; + + name = g_get_user_name (); + + g_assert (name != NULL); +} + +static void +test_realname (void) +{ + const gchar *name; + + name = g_get_real_name (); + + g_assert (name != NULL); +} + +static void +test_hostname (void) +{ + const gchar *name; + + name = g_get_host_name (); + + g_assert (name != NULL); + g_assert_true (g_utf8_validate (name, -1, NULL)); +} + +#ifdef G_OS_UNIX +static void +test_xdg_dirs (void) +{ + gchar *xdg; + const gchar *dir; + const gchar * const *dirs; + gchar *s; + + xdg = g_strdup (g_getenv ("XDG_CONFIG_HOME")); + if (!xdg) + xdg = g_build_filename (g_get_home_dir (), ".config", NULL); + + dir = g_get_user_config_dir (); + + g_assert_cmpstr (dir, ==, xdg); + g_free (xdg); + + xdg = g_strdup (g_getenv ("XDG_DATA_HOME")); + if (!xdg) + xdg = g_build_filename (g_get_home_dir (), ".local", "share", NULL); + + dir = g_get_user_data_dir (); + + g_assert_cmpstr (dir, ==, xdg); + g_free (xdg); + + xdg = g_strdup (g_getenv ("XDG_CACHE_HOME")); + if (!xdg) + xdg = g_build_filename (g_get_home_dir (), ".cache", NULL); + + dir = g_get_user_cache_dir (); + + g_assert_cmpstr (dir, ==, xdg); + g_free (xdg); + + xdg = g_strdup (g_getenv ("XDG_STATE_HOME")); + if (!xdg) + xdg = g_build_filename (g_get_home_dir (), ".local/state", NULL); + + dir = g_get_user_state_dir (); + + g_assert_cmpstr (dir, ==, xdg); + g_free (xdg); + + xdg = g_strdup (g_getenv ("XDG_RUNTIME_DIR")); + if (!xdg) + xdg = g_strdup (g_get_user_cache_dir ()); + + dir = g_get_user_runtime_dir (); + + g_assert_cmpstr (dir, ==, xdg); + g_free (xdg); + + xdg = (gchar *)g_getenv ("XDG_CONFIG_DIRS"); + if (!xdg) + xdg = "/etc/xdg"; + + dirs = g_get_system_config_dirs (); + + s = g_strjoinv (":", (gchar **)dirs); + + g_assert_cmpstr (s, ==, xdg); + + g_free (s); +} +#endif + +static void +test_special_dir (void) +{ + const gchar *dir, *dir2; + + dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); + g_reload_user_special_dirs_cache (); + dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); + + g_assert_cmpstr (dir, ==, dir2); +} + +static void +test_desktop_special_dir (void) +{ + const gchar *dir, *dir2; + + dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); + g_assert (dir != NULL); + + g_reload_user_special_dirs_cache (); + dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); + g_assert (dir2 != NULL); +} + +static void +test_os_info (void) +{ + gchar *name; + gchar *contents = NULL; +#if defined (G_OS_UNIX) && !(defined (G_OS_WIN32) || defined (__APPLE__)) + struct utsname info; +#endif + + /* Whether this is implemented or not, it must not crash */ + name = g_get_os_info (G_OS_INFO_KEY_NAME); + g_test_message ("%s: %s", + G_OS_INFO_KEY_NAME, + name == NULL ? "(null)" : name); + +#if defined (G_OS_WIN32) || defined (__APPLE__) + /* These OSs have a special case so NAME should always succeed */ + g_assert_nonnull (name); +#elif defined (G_OS_UNIX) + if (g_file_get_contents ("/etc/os-release", &contents, NULL, NULL) || + g_file_get_contents ("/usr/lib/os-release", &contents, NULL, NULL) || + uname (&info) == 0) + g_assert_nonnull (name); + else + g_test_skip ("os-release(5) API not implemented on this platform"); +#else + g_test_skip ("g_get_os_info() not supported on this platform"); +#endif + + g_free (name); + g_free (contents); +} + +static gboolean +source_test (gpointer data) +{ + g_assert_not_reached (); + return G_SOURCE_REMOVE; +} + +static void +test_clear_source (void) +{ + guint id; + + id = g_idle_add (source_test, NULL); + g_assert_cmpuint (id, >, 0); + + g_clear_handle_id (&id, g_source_remove); + g_assert_cmpuint (id, ==, 0); + + id = g_timeout_add (100, source_test, NULL); + g_assert_cmpuint (id, >, 0); + + g_clear_handle_id (&id, g_source_remove); + g_assert_cmpuint (id, ==, 0); +} + +static void +test_clear_pointer (void) +{ + gpointer a; + + a = g_malloc (5); + g_clear_pointer (&a, g_free); + g_assert (a == NULL); + + a = g_malloc (5); + (g_clear_pointer) (&a, g_free); + g_assert (a == NULL); +} + +/* Test that g_clear_pointer() works with a GDestroyNotify which contains a cast. + * See https://gitlab.gnome.org/GNOME/glib/issues/1425 */ +static void +test_clear_pointer_cast (void) +{ + GHashTable *hash_table = NULL; + + hash_table = g_hash_table_new (g_str_hash, g_str_equal); + + g_assert_nonnull (hash_table); + + g_clear_pointer (&hash_table, (void (*) (GHashTable *)) g_hash_table_destroy); + + g_assert_null (hash_table); +} + +/* Test that the macro version of g_clear_pointer() only evaluates its argument + * once, just like the function version would. */ +static void +test_clear_pointer_side_effects (void) +{ + gchar **my_string_array, **i; + + my_string_array = g_new0 (gchar*, 3); + my_string_array[0] = g_strdup ("hello"); + my_string_array[1] = g_strdup ("there"); + my_string_array[2] = NULL; + + i = my_string_array; + + g_clear_pointer (i++, g_free); + + g_assert_true (i == &my_string_array[1]); + g_assert_null (my_string_array[0]); + g_assert_nonnull (my_string_array[1]); + g_assert_null (my_string_array[2]); + + g_free (my_string_array[1]); + g_free (my_string_array[2]); + g_free (my_string_array); +} + +static int obj_count; + +static void +get_obj (gpointer *obj_out) +{ + gpointer obj = g_malloc (5); + obj_count++; + + if (obj_out) + *obj_out = g_steal_pointer (&obj); + + if (obj) + { + g_free (obj); + obj_count--; + } +} + +static void +test_take_pointer (void) +{ + gpointer a; + gpointer b; + + get_obj (NULL); + + get_obj (&a); + g_assert (a); + + /* ensure that it works to skip the macro */ + b = (g_steal_pointer) (&a); + g_assert (!a); + obj_count--; + g_free (b); + + g_assert (!obj_count); +} + +static void +test_misc_mem (void) +{ + gpointer a; + + a = g_try_malloc (0); + g_assert (a == NULL); + + a = g_try_malloc0 (0); + g_assert (a == NULL); + + a = g_malloc (16); + a = g_try_realloc (a, 20); + a = g_try_realloc (a, 0); + + g_assert (a == NULL); +} + +static void +aligned_alloc_nz (void) +{ + gpointer a; + + /* Test an alignment that’s zero */ + a = g_aligned_alloc (16, sizeof(char), 0); + g_aligned_free (a); + exit (0); +} + +static void +aligned_alloc_npot (void) +{ + gpointer a; + + /* Test an alignment that’s not a power of two */ + a = g_aligned_alloc (16, sizeof(char), 15); + g_aligned_free (a); + exit (0); +} + +static void +aligned_alloc_nmov (void) +{ + gpointer a; + + /* Test an alignment that’s not a multiple of sizeof(void*) */ + a = g_aligned_alloc (16, sizeof(char), sizeof(void *) / 2); + g_aligned_free (a); + exit (0); +} + +static void +test_aligned_mem (void) +{ + gpointer a; + + g_test_summary ("Aligned memory allocator"); + + a = g_aligned_alloc (0, sizeof(int), 8); + g_assert_null (a); + + a = g_aligned_alloc0 (0, sizeof(int), 8); + g_assert_null (a); + + a = g_aligned_alloc (16, 0, 8); + g_assert_null (a); + +#define CHECK_SUBPROCESS_FAIL(name,msg) do { \ + if (g_test_undefined ()) \ + { \ + g_test_message (msg); \ + g_test_trap_subprocess ("/utils/aligned-mem/subprocess/" #name, 0, 0); \ + g_test_trap_assert_failed (); \ + } \ + } while (0) + + CHECK_SUBPROCESS_FAIL (aligned_alloc_nz, "Alignment must not be zero"); + CHECK_SUBPROCESS_FAIL (aligned_alloc_npot, "Alignment must be a power of two"); + CHECK_SUBPROCESS_FAIL (aligned_alloc_nmov, "Alignment must be a multiple of sizeof(void*)"); +} + +static void +test_aligned_mem_alignment (void) +{ + gchar *p; + + g_test_summary ("Check that g_aligned_alloc() returns a correctly aligned pointer"); + + p = g_aligned_alloc (5, sizeof (*p), 256); + g_assert_nonnull (p); + g_assert_cmpuint (((guintptr) p) % 256, ==, 0); + + g_aligned_free (p); +} + +static void +test_aligned_mem_zeroed (void) +{ + gsize n_blocks = 10; + guint *p; + gsize i; + + g_test_summary ("Check that g_aligned_alloc0() zeroes out its allocation"); + + p = g_aligned_alloc0 (n_blocks, sizeof (*p), 16); + g_assert_nonnull (p); + + for (i = 0; i < n_blocks; i++) + g_assert_cmpuint (p[i], ==, 0); + + g_aligned_free (p); +} + +static void +test_nullify (void) +{ + gpointer p = &test_nullify; + + g_assert (p != NULL); + + g_nullify_pointer (&p); + + g_assert (p == NULL); +} + +static void +atexit_func (void) +{ + g_print ("atexit called"); +} + +static void +test_atexit (void) +{ + if (g_test_subprocess ()) + { + g_atexit (atexit_func); + return; + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*atexit called*"); +} + +static void +test_check_setuid (void) +{ + gboolean res; + + res = GLIB_PRIVATE_CALL(g_check_setuid) (); + g_assert (!res); +} + +/* Test the defined integer limits are correct, as some compilers have had + * problems with signed/unsigned conversion in the past. These limits should not + * vary between platforms, compilers or architectures. + * + * Use string comparisons to avoid the same systematic problems with unary minus + * application in C++. See https://gitlab.gnome.org/GNOME/glib/issues/1663. */ +static void +test_int_limits (void) +{ + gchar *str = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1663"); + + str = g_strdup_printf ("%d %d %u\n" + "%" G_GINT16_FORMAT " %" G_GINT16_FORMAT " %" G_GUINT16_FORMAT "\n" + "%" G_GINT32_FORMAT " %" G_GINT32_FORMAT " %" G_GUINT32_FORMAT "\n" + "%" G_GINT64_FORMAT " %" G_GINT64_FORMAT " %" G_GUINT64_FORMAT "\n", + G_MININT8, G_MAXINT8, G_MAXUINT8, + G_MININT16, G_MAXINT16, G_MAXUINT16, + G_MININT32, G_MAXINT32, G_MAXUINT32, + G_MININT64, G_MAXINT64, G_MAXUINT64); + + g_assert_cmpstr (str, ==, + "-128 127 255\n" + "-32768 32767 65535\n" + "-2147483648 2147483647 4294967295\n" + "-9223372036854775808 9223372036854775807 18446744073709551615\n"); + g_free (str); +} + +static void +test_clear_list (void) +{ + GList *list = NULL; + + g_clear_list (&list, NULL); + g_assert_null (list); + + list = g_list_prepend (list, "test"); + g_assert_nonnull (list); + + g_clear_list (&list, NULL); + g_assert_null (list); + + g_clear_list (&list, g_free); + g_assert_null (list); + + list = g_list_prepend (list, g_malloc (16)); + g_assert_nonnull (list); + + g_clear_list (&list, g_free); + g_assert_null (list); +} + +static void +test_clear_slist (void) +{ + GSList *slist = NULL; + + g_clear_slist (&slist, NULL); + g_assert_null (slist); + + slist = g_slist_prepend (slist, "test"); + g_assert_nonnull (slist); + + g_clear_slist (&slist, NULL); + g_assert_null (slist); + + g_clear_slist (&slist, g_free); + g_assert_null (slist); + + slist = g_slist_prepend (slist, g_malloc (16)); + g_assert_nonnull (slist); + + g_clear_slist (&slist, g_free); + g_assert_null (slist); +} + +int +main (int argc, + char *argv[]) +{ + argv0 = argv[0]; + + /* for tmpdir test, need to do this early before g_get_any_init */ + g_setenv ("TMPDIR", "", TRUE); + g_unsetenv ("TMP"); + g_unsetenv ("TEMP"); + + /* g_test_init() only calls g_set_prgname() if g_get_prgname() + * returns %NULL, but g_get_prgname() on Windows never returns NULL. + * So we need to do this by hand to make test_appname() work on + * Windows. + */ + g_set_prgname (argv[0]); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/utils/language-names", test_language_names); + g_test_add_func ("/utils/locale-variants", test_locale_variants); + g_test_add_func ("/utils/version", test_version); + g_test_add_func ("/utils/appname", test_appname); + g_test_add_func ("/utils/prgname-thread-safety", test_prgname_thread_safety); + g_test_add_func ("/utils/tmpdir", test_tmpdir); + g_test_add_func ("/utils/basic_bits", test_basic_bits); + g_test_add_func ("/utils/bits", test_bits); + g_test_add_func ("/utils/swap", test_swap); + g_test_add_func ("/utils/find-program", test_find_program); + g_test_add_func ("/utils/debug", test_debug); + g_test_add_func ("/utils/codeset", test_codeset); + g_test_add_func ("/utils/codeset2", test_codeset2); + g_test_add_func ("/utils/console-charset", test_console_charset); + g_test_add_func ("/utils/gettext", test_gettext); + g_test_add_func ("/utils/username", test_username); + g_test_add_func ("/utils/realname", test_realname); + g_test_add_func ("/utils/hostname", test_hostname); +#ifdef G_OS_UNIX + g_test_add_func ("/utils/xdgdirs", test_xdg_dirs); +#endif + g_test_add_func ("/utils/specialdir", test_special_dir); + g_test_add_func ("/utils/specialdir/desktop", test_desktop_special_dir); + g_test_add_func ("/utils/os-info", test_os_info); + g_test_add_func ("/utils/clear-pointer", test_clear_pointer); + g_test_add_func ("/utils/clear-pointer-cast", test_clear_pointer_cast); + g_test_add_func ("/utils/clear-pointer/side-effects", test_clear_pointer_side_effects); + g_test_add_func ("/utils/take-pointer", test_take_pointer); + g_test_add_func ("/utils/clear-source", test_clear_source); + g_test_add_func ("/utils/misc-mem", test_misc_mem); + g_test_add_func ("/utils/aligned-mem", test_aligned_mem); + g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nz", aligned_alloc_nz); + g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_npot", aligned_alloc_npot); + g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nmov", aligned_alloc_nmov); + g_test_add_func ("/utils/aligned-mem/alignment", test_aligned_mem_alignment); + g_test_add_func ("/utils/aligned-mem/zeroed", test_aligned_mem_zeroed); + g_test_add_func ("/utils/nullify", test_nullify); + g_test_add_func ("/utils/atexit", test_atexit); + g_test_add_func ("/utils/check-setuid", test_check_setuid); + g_test_add_func ("/utils/int-limits", test_int_limits); + g_test_add_func ("/utils/clear-list", test_clear_list); + g_test_add_func ("/utils/clear-slist", test_clear_slist); + + return g_test_run (); +} diff --git a/glib/tests/win32.c b/glib/tests/win32.c new file mode 100644 index 0000000..1219973 --- /dev/null +++ b/glib/tests/win32.c @@ -0,0 +1,177 @@ +/* Unit test for VEH on Windows + * Copyright (C) 2019 РуÑлан Ижбулатов + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include "config.h" + +#include +#include +#include +#include + +static char *argv0 = NULL; + +#include "../gwin32-private.c" + +static void +test_subst_pid_and_event (void) +{ + const wchar_t not_enough[] = L"too long when %e and %p are substituted"; + wchar_t debugger_3[3]; + wchar_t debugger_not_enough[G_N_ELEMENTS (not_enough)]; + wchar_t debugger_enough[G_N_ELEMENTS (not_enough) + 1]; + char *debugger_enough_utf8; + wchar_t debugger_big[65535] = {0}; + char *debugger_big_utf8; + gchar *output; + guintptr be = (guintptr) 0xFFFFFFFF; + DWORD bp = G_MAXSIZE; + + /* %f is not valid */ + g_assert_false (_g_win32_subst_pid_and_event_w (debugger_3, G_N_ELEMENTS (debugger_3), + L"%f", 0, 0)); + + g_assert_false (_g_win32_subst_pid_and_event_w (debugger_3, G_N_ELEMENTS (debugger_3), + L"string longer than 10", 0, 0)); + /* 200 is longer than %e, so the string doesn't fit by 1 byte */ + g_assert_false (_g_win32_subst_pid_and_event_w (debugger_not_enough, G_N_ELEMENTS (debugger_not_enough), + not_enough, 10, 200)); + + /* This should fit */ + g_assert_true (_g_win32_subst_pid_and_event_w (debugger_enough, G_N_ELEMENTS (debugger_enough), + not_enough, 10, 200)); + debugger_enough_utf8 = g_utf16_to_utf8 (debugger_enough, -1, NULL, NULL, NULL); + g_assert_cmpstr (debugger_enough_utf8, ==, "too long when 200 and 10 are substituted"); + g_free (debugger_enough_utf8); + + g_assert_true (_g_win32_subst_pid_and_event_w (debugger_big, G_N_ELEMENTS (debugger_big), + L"multipl%e big %e %entries and %pids are %provided here", bp, be)); + debugger_big_utf8 = g_utf16_to_utf8 (debugger_big, -1, NULL, NULL, NULL); + output = g_strdup_printf ("multipl%llu big %llu %lluntries and %luids are %lurovided here", (guint64) be, (guint64) be, (guint64) be, bp, bp); + g_assert_cmpstr (debugger_big_utf8, ==, output); + g_free (debugger_big_utf8); + g_free (output); +} + +/* Crash with access violation */ +static void +test_access_violation (void) +{ + int *integer = NULL; + /* Use SEM_NOGPFAULTERRORBOX to prevent an error dialog + * from being shown. + */ + DWORD dwMode = SetErrorMode (SEM_NOGPFAULTERRORBOX); + SetErrorMode (dwMode | SEM_NOGPFAULTERRORBOX); + *integer = 1; + SetErrorMode (dwMode); +} + +/* Crash with illegal instruction */ +static void +test_illegal_instruction (void) +{ + DWORD dwMode = SetErrorMode (SEM_NOGPFAULTERRORBOX); + SetErrorMode (dwMode | SEM_NOGPFAULTERRORBOX); + RaiseException (EXCEPTION_ILLEGAL_INSTRUCTION, 0, 0, NULL); + SetErrorMode (dwMode); +} + +static void +test_veh_crash_access_violation (void) +{ + g_unsetenv ("G_DEBUGGER"); + /* Run a test that crashes */ + g_test_trap_subprocess ("/win32/subprocess/access_violation", 0, 0); + g_test_trap_assert_failed (); +} + +static void +test_veh_crash_illegal_instruction (void) +{ + g_unsetenv ("G_DEBUGGER"); + /* Run a test that crashes */ + g_test_trap_subprocess ("/win32/subprocess/illegal_instruction", 0, 0); + g_test_trap_assert_failed (); +} + +static void +test_veh_debug (void) +{ + /* Set up a debugger to be run on crash */ + gchar *command = g_strdup_printf ("%s %s", argv0, "%p %e"); + g_setenv ("G_DEBUGGER", command, TRUE); + /* Because the "debugger" here is not really a debugger, + * it can't write into stderr of this process, unless + * we allow it to inherit our stderr. + */ + g_setenv ("G_DEBUGGER_OLD_CONSOLE", "1", TRUE); + g_free (command); + /* Run a test that crashes and runs a debugger */ + g_test_trap_subprocess ("/win32/subprocess/debuggee", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("Debugger invoked, attaching to*"); +} + +static void +test_veh_debuggee (void) +{ + /* Crash */ + test_access_violation (); +} + +static void +veh_debugger (int argc, char *argv[]) +{ + char *end; + DWORD pid = strtoul (argv[1], &end, 10); + guintptr event = (guintptr) _strtoui64 (argv[2], &end, 10); + /* Unfreeze the debuggee and announce ourselves */ + SetEvent ((HANDLE) event); + CloseHandle ((HANDLE) event); + g_fprintf (stderr, "Debugger invoked, attaching to %lu and signalling %" G_GUINTPTR_FORMAT, pid, event); +} + +int +main (int argc, + char *argv[]) +{ + argv0 = argv[0]; + + g_test_init (&argc, &argv, NULL); + + if (argc > 2) + { + veh_debugger (argc, argv); + return 0; + } + + g_test_add_func ("/win32/substitute-pid-and-event", test_subst_pid_and_event); + + g_test_add_func ("/win32/veh/access_violation", test_veh_crash_access_violation); + g_test_add_func ("/win32/veh/illegal_instruction", test_veh_crash_illegal_instruction); + g_test_add_func ("/win32/veh/debug", test_veh_debug); + + g_test_add_func ("/win32/subprocess/debuggee", test_veh_debuggee); + g_test_add_func ("/win32/subprocess/access_violation", test_access_violation); + g_test_add_func ("/win32/subprocess/illegal_instruction", test_illegal_instruction); + + return g_test_run(); +} diff --git a/glib/update-gtranslit.py b/glib/update-gtranslit.py new file mode 100755 index 0000000..f2b4f9a --- /dev/null +++ b/glib/update-gtranslit.py @@ -0,0 +1,456 @@ +#!/usr/bin/env python3 + +# Run this script like so: +# +# ./update-gtranslit.py /path/to/glibc/localedata/locales > gtranslit-data.h + +import os +import sys + + +localedir = sys.argv[1] + + +# returns true if the name looks like a POSIX locale name +def looks_like_locale(name): + name, _, variant = name.partition("@") + + if "_" not in name: + return False + + lang, _, land = name.partition("_") + + return len(lang) == 2 or len(lang) == 3 and len(land) == 2 + + +# handles style escapes +def unescape(string): + chunks = [] + + n = len(string) + i = 0 + + while i < n: + start_escape = string.find("<", i) + + if start_escape == -1: + chunks.append(string[i:]) + break + + assert string[start_escape : (start_escape + 2)] == "", start_escape) + assert end_escape != -1 + + chunks.append(chr(int(string[start_escape:end_escape], 16))) + i = end_escape + 1 + + return "".join(chunks) + + +# Checks if a string is ascii +def is_ascii(string): + return all(ord(c) < 0x80 for c in string) + + +# A Mapping is a map from non-ascii strings to ascii strings. +# +# It corresponds to a sequence of one or more mapping lines: +# +# "";"" +# +# in a file. +class Mapping: + def __init__(self): + self.serialised = None + self.mapping = {} + + # Scans a string like + # + # "";"" % \ + # LATIN CAPITAL LETTER A WITH DIAERESIS. + # + # and adds the first all-ascii choice (or IGNORE) to the mapping + # dictionary, with the origin string as the key. In the case of + # IGNORE, stores the empty string. + def consider_mapping_line(self, line): + key, value, rest = (line + " % comment").split(maxsplit=2) + + key = unescape(key) + + for alternative in value.split(";"): + if alternative[0] == '"' and alternative[-1] == '"': + unescaped = unescape(alternative[1:-1]) + if is_ascii(unescaped): + self.mapping[key] = unescaped + break + + elif alternative[0] == "<" and alternative[-1] == ">": + unescaped = unescape(alternative) + if is_ascii(unescaped): + self.mapping[key] = unescaped + break + + elif alternative == "IGNORE": + self.mapping[key] = "" + break + + # Performs a normal dictionary merge, but ensures that there are no + # conflicting entries between the original dictionary and the requested + # changes + def merge_mapping(self, changes): + for key in changes.mapping: + if key in self.mapping: + assert self.mapping[key] == changes.mapping[key] + + self.mapping.update(changes.mapping) + + # Can't get much flatter... + def get_flattened(self): + return [self] + + def serialise(self, serialiser): + if self.serialised is None: + self.serialised = serialiser.add_mapping(self.mapping) + + return self.serialised + + +# A Chain is a sequence of mappings and chains. +# +# A chain contains another chain whenever "copy" or "include" is +# encountered in a source file. +# +# A chain contains a mapping whenever a sequence of mapping lines: +# +# "";"" +# +# is encountered in a file. +# +# The order of lookup is reverse: later entries override earlier ones. +class Chain: + def __init__(self, name): + self.serialised = None + self.name = name + self.chain = [] + self.links = 0 + + self.read_from_file(os.path.join(localedir, name)) + + def read_from_file(self, filename): + current_mapping = None + in_lc_ctype = False + in_translit = False + + fp = open(filename, encoding="ascii", errors="surrogateescape") + + for line in fp: + line = line.strip() + + if in_lc_ctype: + if line == "END LC_CTYPE": + break + + if line.startswith("copy") or line.startswith("include"): + if current_mapping: + self.chain.append(current_mapping) + + copyname = unescape(line.split('"', 3)[1]) + copyfile = get_chain(copyname) + self.chain.append(copyfile) + copyfile.links += 1 + + current_mapping = None + + elif line == "translit_start": + in_translit = True + + elif line == "translit_end": + in_translit = False + + elif in_translit and line.startswith("": + pass + + elif in_translit: + print("unknown line:", line) + assert False + + elif line == "LC_CTYPE": + in_lc_ctype = True + + if current_mapping: + self.chain.append(current_mapping) + + # If there is only one link to this chain, we may as well just + # return the contents of the chain so that they can be merged into + # our sole parent directly. Otherwise, return ourselves. + def get_flattened(self): + if self.links == 1: + return sum((item.get_flattened() for item in self.chain), []) + else: + return [self] + + def serialise(self, serialiser): + if self.serialised is None: + # Before we serialise, see if we can optimise a bit + self.chain = sum((item.get_flattened() for item in self.chain), []) + + i = 0 + while i < len(self.chain) - 1: + if isinstance(self.chain[i], Mapping) and isinstance( + self.chain[i + 1], Mapping + ): + # We have two mappings in a row. Try to merge them. + self.chain[i].merge_mapping(self.chain[i + 1]) + del self.chain[i + 1] + else: + i += 1 + + # If all that is left is one item, just serialise that directly + if len(self.chain) == 1: + self.serialised = self.chain[0].serialise(serialiser) + else: + ids = [item.serialise(serialiser) for item in self.chain] + self.serialised = serialiser.add_chain(ids) + + return self.serialised + + +# Chain cache -- allows sharing of common chains +chains = {} + + +def get_chain(name): + if name not in chains: + chains[name] = Chain(name) + + return chains[name] + + +# Remove the country name from a locale, preserving variant +# eg: 'sr_RS@latin' -> 'sr@latin' +def remove_country(string): + base, at, variant = string.partition("@") + lang, _, land = base.partition("_") + return lang + at + variant + + +def encode_range(start, end): + assert start <= end + length = end - start + + assert start < 0x1000 + assert length < 0x8 + + result = 0x8000 + (length << 12) + start + + assert result < 0x10000 + + return result + + +def c_pair_array(array): + return "{ " + ", ".join("{ %u, %u }" % pair for pair in array) + " };" + + +class Serialiser: + def __init__(self): + self.mappings = [] + self.chains = [] + self.locales = {} + + def add_mapping(self, mapping): + if mapping in self.mappings: + mapping_id = self.mappings.index(mapping) + else: + mapping_id = len(self.mappings) + self.mappings.append(mapping) + + assert mapping_id < 128 + return mapping_id + + def add_chain(self, chain): + if chain in self.chains: + chain_id = self.chains.index(chain) + else: + chain_id = len(self.chains) + self.chains.append(chain) + + assert chain_id < 128 + return 128 + chain_id + + def add_locale(self, name, item_id): + self.locales[name] = item_id + + def add_default(self, item_id): + self.default = item_id + + def optimise_locales(self): + # Check if all regions of a language/variant agree + languages = list(set(remove_country(locale) for locale in self.locales)) + + for language in languages: + locales = [ + locale for locale in self.locales if remove_country(locale) == language + ] + + item_id = self.locales[locales[0]] + if all(self.locales[locale] == item_id for locale in locales): + self.locales[language] = item_id + for locale in locales: + del self.locales[locale] + + # Check if a variant is the same as the non-variant form + # eg: 'de@euro' and 'de' + for variant in list(locale for locale in self.locales if "@" in locale): + base, _, _ = variant.partition("@") + if base in self.locales and self.locales[base] == self.locales[variant]: + del self.locales[variant] + + # Eliminate any entries that are just the same as the C locale + for locale in list(self.locales): + if self.locales[locale] == self.default: + del self.locales[locale] + + def to_c(self): + src_table = "" + ascii_table = "" + mappings_table = [] + mapping_ranges = [] + chains_table = [] + chain_starts = [] + locale_names = "" + locale_index = [] + max_lookup = 0 + max_localename = 0 + + for mapping in self.mappings: + mapping_ranges.append((len(mappings_table), len(mapping))) + + for key in sorted(mapping): + if len(key) == 1 and ord(key[0]) < 0x8000: + src_range = ord(key[0]) + else: + existing = src_table.find(key) + if existing == -1: + start = len(src_table) + assert all(ord(c) <= 0x10FFFF for c in key) + src_table += key + src_range = encode_range(start, len(src_table)) + max_lookup = max(max_lookup, len(key)) + else: + src_range = encode_range(existing, existing + len(key)) + + value = mapping[key] + if len(value) == 1 and ord(value[0]) < 0x80: + ascii_range = ord(value[0]) + else: + existing = ascii_table.find(value) + if existing == -1: + start = len(ascii_table) + assert all(ord(c) < 0x80 for c in value) + ascii_table += value + ascii_range = encode_range(start, len(ascii_table)) + else: + ascii_range = encode_range(existing, existing + len(value)) + + mappings_table.append((src_range, ascii_range)) + + for chain in self.chains: + chain_starts.append(len(chains_table)) + + for item_id in reversed(chain): + assert item_id < 0xFF + chains_table.append(item_id) + chains_table.append(0xFF) + + for locale in sorted(self.locales): + max_localename = max(max_localename, len(locale)) + name_offset = len(locale_names) + assert all(ord(c) <= 0x7F for c in locale) + locale_names += locale + "\0" + + item_id = self.locales[locale] + + assert name_offset < 256 + assert item_id < 256 + locale_index.append((name_offset, item_id)) + + print("/* Generated by update-gtranslit.py */") + print("#define MAX_KEY_SIZE", max_lookup) + print("#define MAX_LOCALE_NAME", max_localename) + print( + "static const gunichar src_table[] = {", + ", ".join(str(ord(c)) for c in src_table), + "};", + ) + # cannot do this in plain ascii because of trigraphs... :( + print( + "static const gchar ascii_table[] = {", + ", ".join(str(ord(c)) for c in ascii_table), + "};", + ) + print( + "static const struct mapping_entry mappings_table[] =", + c_pair_array(mappings_table), + ) + print( + "static const struct mapping_range mapping_ranges[] =", + c_pair_array(mapping_ranges), + ) + print( + "static const guint8 chains_table[] = {", + ", ".join(str(i) for i in chains_table), + "};", + ) + print( + "static const guint8 chain_starts[] = {", + ", ".join(str(i) for i in chain_starts), + "};", + ) + print( + 'static const gchar locale_names[] = "' + + locale_names.replace("\0", "\\0") + + '";' + ) + print( + "static const struct locale_entry locale_index[] = ", + c_pair_array(locale_index), + ) + print("static const guint8 default_item_id = %u;" % (self.default,)) + + def dump(self): + print(self.mappings) + print(self.chains) + print(self.locales) + + +locales = [] +for name in os.listdir(localedir): + if looks_like_locale(name): + chain = get_chain(name) + locales.append(chain) + chain.links += 1 + +serialiser = Serialiser() + +for locale in locales: + serialiser.add_locale(locale.name, locale.serialise(serialiser)) + +i18n = get_chain("i18n").serialise(serialiser) +combining = get_chain("translit_combining").serialise(serialiser) +serialiser.add_default(serialiser.add_chain([i18n, combining])) + +serialiser.optimise_locales() + +serialiser.to_c() diff --git a/glib/valgrind.h b/glib/valgrind.h new file mode 100644 index 0000000..a7f1f56 --- /dev/null +++ b/glib/valgrind.h @@ -0,0 +1,6648 @@ +/* -*- c -*- + ---------------------------------------------------------------- + + Notice that the following BSD-style license applies to this one + file (valgrind.h) only. The rest of Valgrind is licensed under the + terms of the GNU General Public License, version 2, unless + otherwise indicated. See the COPYING file in the source + distribution for details. + + ---------------------------------------------------------------- + + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2017 Julian Seward. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ---------------------------------------------------------------- + + Notice that the above BSD-style license applies to this one file + (valgrind.h) only. The entire rest of Valgrind is licensed under + the terms of the GNU General Public License, version 2. See the + COPYING file in the source distribution for details. + + ---------------------------------------------------------------- +*/ + + +/* This file is for inclusion into client (your!) code. + + You can use these macros to manipulate and query Valgrind's + execution inside your own programs. + + The resulting executables will still run without Valgrind, just a + little bit more slowly than they otherwise would, but otherwise + unchanged. When not running on valgrind, each client request + consumes very few (eg. 7) instructions, so the resulting performance + loss is negligible unless you plan to execute client requests + millions of times per second. Nevertheless, if that is still a + problem, you can compile with the NVALGRIND symbol defined (gcc + -DNVALGRIND) so that client requests are not even compiled in. */ + +#ifndef __VALGRIND_H +#define __VALGRIND_H + + +/* ------------------------------------------------------------------ */ +/* VERSION NUMBER OF VALGRIND */ +/* ------------------------------------------------------------------ */ + +/* Specify Valgrind's version number, so that user code can + conditionally compile based on our version number. Note that these + were introduced at version 3.6 and so do not exist in version 3.5 + or earlier. The recommended way to use them to check for "version + X.Y or later" is (eg) + +#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \ + && (__VALGRIND_MAJOR__ > 3 \ + || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) +*/ +#define __VALGRIND_MAJOR__ 3 +#define __VALGRIND_MINOR__ 15 + + +#include + +/* Nb: this file might be included in a file compiled with -ansi. So + we can't use C++ style "//" comments nor the "asm" keyword (instead + use "__asm__"). */ + +/* Derive some tags indicating what the target platform is. Note + that in this file we're using the compiler's CPP symbols for + identifying architectures, which are different to the ones we use + within the rest of Valgrind. Note, __powerpc__ is active for both + 32 and 64-bit PPC, whereas __powerpc64__ is only active for the + latter (on Linux, that is). + + Misc note: how to find out what's predefined in gcc by default: + gcc -Wp,-dM somefile.c +*/ +#undef PLAT_x86_darwin +#undef PLAT_amd64_darwin +#undef PLAT_x86_win32 +#undef PLAT_amd64_win64 +#undef PLAT_x86_linux +#undef PLAT_amd64_linux +#undef PLAT_ppc32_linux +#undef PLAT_ppc64be_linux +#undef PLAT_ppc64le_linux +#undef PLAT_arm_linux +#undef PLAT_arm64_linux +#undef PLAT_s390x_linux +#undef PLAT_mips32_linux +#undef PLAT_mips64_linux +#undef PLAT_x86_solaris +#undef PLAT_amd64_solaris + + +#if defined(__APPLE__) && defined(__i386__) +# define PLAT_x86_darwin 1 +#elif defined(__APPLE__) && defined(__x86_64__) +# define PLAT_amd64_darwin 1 +#elif (defined(__MINGW32__) && defined(__i386__)) \ + || defined(__CYGWIN32__) \ + || (defined(_WIN32) && defined(_M_IX86)) +# define PLAT_x86_win32 1 +#elif (defined(__MINGW32__) && defined(__x86_64__)) \ + || (defined(_WIN32) && defined(_M_X64)) +/* __MINGW32__ and _WIN32 are defined in 64 bit mode as well. */ +# define PLAT_amd64_win64 1 +#elif defined(__linux__) && defined(__i386__) +# define PLAT_x86_linux 1 +#elif defined(__linux__) && defined(__x86_64__) && !defined(__ILP32__) +# define PLAT_amd64_linux 1 +#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) +# define PLAT_ppc32_linux 1 +#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF != 2 +/* Big Endian uses ELF version 1 */ +# define PLAT_ppc64be_linux 1 +#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF == 2 +/* Little Endian uses ELF version 2 */ +# define PLAT_ppc64le_linux 1 +#elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__) +# define PLAT_arm_linux 1 +#elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__) +# define PLAT_arm64_linux 1 +#elif defined(__linux__) && defined(__s390__) && defined(__s390x__) +# define PLAT_s390x_linux 1 +#elif defined(__linux__) && defined(__mips__) && (__mips==64) +# define PLAT_mips64_linux 1 +#elif defined(__linux__) && defined(__mips__) && (__mips!=64) +# define PLAT_mips32_linux 1 +#elif defined(__sun) && defined(__i386__) +# define PLAT_x86_solaris 1 +#elif defined(__sun) && defined(__x86_64__) +# define PLAT_amd64_solaris 1 +#else +/* If we're not compiling for our target platform, don't generate + any inline asms. */ +# if !defined(NVALGRIND) +# define NVALGRIND 1 +# endif +#endif + + +/* ------------------------------------------------------------------ */ +/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ +/* in here of use to end-users -- skip to the next section. */ +/* ------------------------------------------------------------------ */ + +/* + * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client + * request. Accepts both pointers and integers as arguments. + * + * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind + * client request that does not return a value. + + * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind + * client request and whose value equals the client request result. Accepts + * both pointers and integers as arguments. Note that such calls are not + * necessarily pure functions -- they may have side effects. + */ + +#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \ + _zzq_request, _zzq_arg1, _zzq_arg2, \ + _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \ + (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ + (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) + +#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1, \ + _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ + (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) + +#if defined(NVALGRIND) + +/* Define NVALGRIND to completely remove the Valgrind magic sequence + from the compiled code (analogous to NDEBUG's effects on + assert()) */ +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + (_zzq_default) + +#else /* ! NVALGRIND */ + +/* The following defines the magic code sequences which the JITter + spots and handles magically. Don't look too closely at them as + they will rot your brain. + + The assembly code sequences for all architectures is in this one + file. This is because this file must be stand-alone, and we don't + want to have multiple files. + + For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default + value gets put in the return slot, so that everything works when + this is executed not under Valgrind. Args are passed in a memory + block, and so there's no intrinsic limit to the number that could + be passed, but it's currently five. + + The macro args are: + _zzq_rlval result lvalue + _zzq_default default value (result returned when running on real CPU) + _zzq_request request code + _zzq_arg1..5 request params + + The other two macros are used to support function wrapping, and are + a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the + guest's NRADDR pseudo-register and whatever other information is + needed to safely run the call original from the wrapper: on + ppc64-linux, the R2 value at the divert point is also needed. This + information is abstracted into a user-visible type, OrigFn. + + VALGRIND_CALL_NOREDIR_* behaves the same as the following on the + guest, but guarantees that the branch instruction will not be + redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: + branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a + complete inline asm, since it needs to be combined with more magic + inline asm stuff to be useful. +*/ + +/* ----------------- x86-{linux,darwin,solaris} ---------------- */ + +#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ + || (defined(PLAT_x86_win32) && defined(__GNUC__)) \ + || defined(PLAT_x86_solaris) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "roll $3, %%edi ; roll $13, %%edi\n\t" \ + "roll $29, %%edi ; roll $19, %%edi\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %EDX = client_request ( %EAX ) */ \ + "xchgl %%ebx,%%ebx" \ + : "=d" (_zzq_result) \ + : "a" (&_zzq_args[0]), "0" (_zzq_default) \ + : "cc", "memory" \ + ); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %EAX = guest_NRADDR */ \ + "xchgl %%ecx,%%ecx" \ + : "=a" (__addr) \ + : \ + : "cc", "memory" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_EAX \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir *%EAX */ \ + "xchgl %%edx,%%edx\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "xchgl %%edi,%%edi\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) + || PLAT_x86_solaris */ + +/* ------------------------- x86-Win32 ------------------------- */ + +#if defined(PLAT_x86_win32) && !defined(__GNUC__) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#if defined(_MSC_VER) + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + __asm rol edi, 3 __asm rol edi, 13 \ + __asm rol edi, 29 __asm rol edi, 19 + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \ + (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \ + (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \ + (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5)) + +static __inline uintptr_t +valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, + uintptr_t _zzq_arg1, uintptr_t _zzq_arg2, + uintptr_t _zzq_arg3, uintptr_t _zzq_arg4, + uintptr_t _zzq_arg5) +{ + volatile uintptr_t _zzq_args[6]; + volatile unsigned int _zzq_result; + _zzq_args[0] = (uintptr_t)(_zzq_request); + _zzq_args[1] = (uintptr_t)(_zzq_arg1); + _zzq_args[2] = (uintptr_t)(_zzq_arg2); + _zzq_args[3] = (uintptr_t)(_zzq_arg3); + _zzq_args[4] = (uintptr_t)(_zzq_arg4); + _zzq_args[5] = (uintptr_t)(_zzq_arg5); + __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default + __SPECIAL_INSTRUCTION_PREAMBLE + /* %EDX = client_request ( %EAX ) */ + __asm xchg ebx,ebx + __asm mov _zzq_result, edx + } + return _zzq_result; +} + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned int __addr; \ + __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %EAX = guest_NRADDR */ \ + __asm xchg ecx,ecx \ + __asm mov __addr, eax \ + } \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_EAX ERROR + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ + __asm xchg edi,edi \ + } \ + } while (0) + +#else +#error Unsupported compiler. +#endif + +#endif /* PLAT_x86_win32 */ + +/* ----------------- amd64-{linux,darwin,solaris} --------------- */ + +#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ + || defined(PLAT_amd64_solaris) \ + || (defined(PLAT_amd64_win64) && defined(__GNUC__)) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ + "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %RDX = client_request ( %RAX ) */ \ + "xchgq %%rbx,%%rbx" \ + : "=d" (_zzq_result) \ + : "a" (&_zzq_args[0]), "0" (_zzq_default) \ + : "cc", "memory" \ + ); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %RAX = guest_NRADDR */ \ + "xchgq %%rcx,%%rcx" \ + : "=a" (__addr) \ + : \ + : "cc", "memory" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_RAX \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir *%RAX */ \ + "xchgq %%rdx,%%rdx\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "xchgq %%rdi,%%rdi\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */ + +/* ------------------------- amd64-Win64 ------------------------- */ + +#if defined(PLAT_amd64_win64) && !defined(__GNUC__) + +#error Unsupported compiler. + +#endif /* PLAT_amd64_win64 */ + +/* ------------------------ ppc32-linux ------------------------ */ + +#if defined(PLAT_ppc32_linux) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rlwinm 0,0,3,0,31 ; rlwinm 0,0,13,0,31\n\t" \ + "rlwinm 0,0,29,0,31 ; rlwinm 0,0,19,0,31\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({ unsigned int _zzq_args[6]; \ + unsigned int _zzq_result; \ + unsigned int* _zzq_ptr; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + _zzq_ptr = _zzq_args; \ + __asm__ volatile("mr 3,%1\n\t" /*default*/ \ + "mr 4,%2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = client_request ( %R4 ) */ \ + "or 1,1,1\n\t" \ + "mr %0,3" /*result*/ \ + : "=b" (_zzq_result) \ + : "b" (_zzq_default), "b" (_zzq_ptr) \ + : "cc", "memory", "r3", "r4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR */ \ + "or 2,2,2\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir *%R11 */ \ + "or 3,3,3\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or 5,5,5\n\t" \ + ); \ + } while (0) + +#endif /* PLAT_ppc32_linux */ + +/* ------------------------ ppc64-linux ------------------------ */ + +#if defined(PLAT_ppc64be_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + unsigned long int r2; /* what tocptr do we need? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ + "rotldi 0,0,61 ; rotldi 0,0,51\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({ unsigned long int _zzq_args[6]; \ + unsigned long int _zzq_result; \ + unsigned long int* _zzq_ptr; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + _zzq_ptr = _zzq_args; \ + __asm__ volatile("mr 3,%1\n\t" /*default*/ \ + "mr 4,%2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = client_request ( %R4 ) */ \ + "or 1,1,1\n\t" \ + "mr %0,3" /*result*/ \ + : "=b" (_zzq_result) \ + : "b" (_zzq_default), "b" (_zzq_ptr) \ + : "cc", "memory", "r3", "r4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR */ \ + "or 2,2,2\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR_GPR2 */ \ + "or 4,4,4\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->r2 = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir *%R11 */ \ + "or 3,3,3\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or 5,5,5\n\t" \ + ); \ + } while (0) + +#endif /* PLAT_ppc64be_linux */ + +#if defined(PLAT_ppc64le_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + unsigned long int r2; /* what tocptr do we need? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ + "rotldi 0,0,61 ; rotldi 0,0,51\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({ unsigned long int _zzq_args[6]; \ + unsigned long int _zzq_result; \ + unsigned long int* _zzq_ptr; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + _zzq_ptr = _zzq_args; \ + __asm__ volatile("mr 3,%1\n\t" /*default*/ \ + "mr 4,%2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = client_request ( %R4 ) */ \ + "or 1,1,1\n\t" \ + "mr %0,3" /*result*/ \ + : "=b" (_zzq_result) \ + : "b" (_zzq_default), "b" (_zzq_ptr) \ + : "cc", "memory", "r3", "r4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR */ \ + "or 2,2,2\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR_GPR2 */ \ + "or 4,4,4\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->r2 = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir *%R12 */ \ + "or 3,3,3\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or 5,5,5\n\t" \ + ); \ + } while (0) + +#endif /* PLAT_ppc64le_linux */ + +/* ------------------------- arm-linux ------------------------- */ + +#if defined(PLAT_arm_linux) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \ + "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + __asm__ volatile("mov r3, %1\n\t" /*default*/ \ + "mov r4, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* R3 = client_request ( R4 ) */ \ + "orr r10, r10, r10\n\t" \ + "mov %0, r3" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "cc","memory", "r3", "r4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* R3 = guest_NRADDR */ \ + "orr r11, r11, r11\n\t" \ + "mov %0, r3" \ + : "=r" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir *%R4 */ \ + "orr r12, r12, r12\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "orr r9, r9, r9\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_arm_linux */ + +/* ------------------------ arm64-linux ------------------------- */ + +#if defined(PLAT_arm64_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "ror x12, x12, #3 ; ror x12, x12, #13 \n\t" \ + "ror x12, x12, #51 ; ror x12, x12, #61 \n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile("mov x3, %1\n\t" /*default*/ \ + "mov x4, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* X3 = client_request ( X4 ) */ \ + "orr x10, x10, x10\n\t" \ + "mov %0, x3" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" ((unsigned long int)(_zzq_default)), \ + "r" (&_zzq_args[0]) \ + : "cc","memory", "x3", "x4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* X3 = guest_NRADDR */ \ + "orr x11, x11, x11\n\t" \ + "mov %0, x3" \ + : "=r" (__addr) \ + : \ + : "cc", "memory", "x3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir X8 */ \ + "orr x12, x12, x12\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "orr x9, x9, x9\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_arm64_linux */ + +/* ------------------------ s390x-linux ------------------------ */ + +#if defined(PLAT_s390x_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + } + OrigFn; + +/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific + * code. This detection is implemented in platform specific toIR.c + * (e.g. VEX/priv/guest_s390_decoder.c). + */ +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "lr 15,15\n\t" \ + "lr 1,1\n\t" \ + "lr 2,2\n\t" \ + "lr 3,3\n\t" + +#define __CLIENT_REQUEST_CODE "lr 2,2\n\t" +#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t" +#define __CALL_NO_REDIR_CODE "lr 4,4\n\t" +#define __VEX_INJECT_IR_CODE "lr 5,5\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile(/* r2 = args */ \ + "lgr 2,%1\n\t" \ + /* r3 = default */ \ + "lgr 3,%2\n\t" \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + __CLIENT_REQUEST_CODE \ + /* results = r3 */ \ + "lgr %0, 3\n\t" \ + : "=d" (_zzq_result) \ + : "a" (&_zzq_args[0]), "0" (_zzq_default) \ + : "cc", "2", "3", "memory" \ + ); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + __GET_NR_CONTEXT_CODE \ + "lgr %0, 3\n\t" \ + : "=a" (__addr) \ + : \ + : "cc", "3", "memory" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_R1 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + __CALL_NO_REDIR_CODE + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + __VEX_INJECT_IR_CODE); \ + } while (0) + +#endif /* PLAT_s390x_linux */ + +/* ------------------------- mips32-linux ---------------- */ + +#if defined(PLAT_mips32_linux) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +/* .word 0x342 + * .word 0x742 + * .word 0xC2 + * .word 0x4C2*/ +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "srl $0, $0, 13\n\t" \ + "srl $0, $0, 29\n\t" \ + "srl $0, $0, 3\n\t" \ + "srl $0, $0, 19\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + __asm__ volatile("move $11, %1\n\t" /*default*/ \ + "move $12, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* T3 = client_request ( T4 ) */ \ + "or $13, $13, $13\n\t" \ + "move %0, $11\n\t" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "$11", "$12", "memory"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %t9 = guest_NRADDR */ \ + "or $14, $14, $14\n\t" \ + "move %0, $11" /*result*/ \ + : "=r" (__addr) \ + : \ + : "$11" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_T9 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir *%t9 */ \ + "or $15, $15, $15\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or $11, $11, $11\n\t" \ + ); \ + } while (0) + + +#endif /* PLAT_mips32_linux */ + +/* ------------------------- mips64-linux ---------------- */ + +#if defined(PLAT_mips64_linux) + +typedef + struct { + unsigned long nraddr; /* where's the code? */ + } + OrigFn; + +/* dsll $0,$0, 3 + * dsll $0,$0, 13 + * dsll $0,$0, 29 + * dsll $0,$0, 19*/ +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "dsll $0,$0, 3 ; dsll $0,$0,13\n\t" \ + "dsll $0,$0,29 ; dsll $0,$0,19\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile("move $11, %1\n\t" /*default*/ \ + "move $12, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* $11 = client_request ( $12 ) */ \ + "or $13, $13, $13\n\t" \ + "move %0, $11\n\t" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "$11", "$12", "memory"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* $11 = guest_NRADDR */ \ + "or $14, $14, $14\n\t" \ + "move %0, $11" /*result*/ \ + : "=r" (__addr) \ + : \ + : "$11"); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_T9 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir $25 */ \ + "or $15, $15, $15\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or $11, $11, $11\n\t" \ + ); \ + } while (0) + +#endif /* PLAT_mips64_linux */ + +/* Insert assembly code for other platforms here... */ + +#endif /* NVALGRIND */ + + +/* ------------------------------------------------------------------ */ +/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ +/* ugly. It's the least-worst tradeoff I can think of. */ +/* ------------------------------------------------------------------ */ + +/* This section defines magic (a.k.a appalling-hack) macros for doing + guaranteed-no-redirection macros, so as to get from function + wrappers to the functions they are wrapping. The whole point is to + construct standard call sequences, but to do the call itself with a + special no-redirect call pseudo-instruction that the JIT + understands and handles specially. This section is long and + repetitious, and I can't see a way to make it shorter. + + The naming scheme is as follows: + + CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} + + 'W' stands for "word" and 'v' for "void". Hence there are + different macros for calling arity 0, 1, 2, 3, 4, etc, functions, + and for each, the possibility of returning a word-typed result, or + no result. +*/ + +/* Use these to write the name of your wrapper. NOTE: duplicates + VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts + the default behaviour equivalance class tag "0000" into the name. + See pub_tool_redir.h for details -- normally you don't need to + think about this, though. */ + +/* Use an extra level of macroisation so as to ensure the soname/fnname + args are fully macro-expanded before pasting them together. */ +#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd + +#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ + VG_CONCAT4(_vgw00000ZU_,soname,_,fnname) + +#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ + VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname) + +/* Use this macro from within a wrapper function to collect the + context (address and possibly other info) of the original function. + Once you have that you can then use it in one of the CALL_FN_ + macros. The type of the argument _lval is OrigFn. */ +#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) + +/* Also provide end-user facilities for function replacement, rather + than wrapping. A replacement function differs from a wrapper in + that it has no way to get hold of the original function being + called, and hence no way to call onwards to it. In a replacement + function, VALGRIND_GET_ORIG_FN always returns zero. */ + +#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname) \ + VG_CONCAT4(_vgr00000ZU_,soname,_,fnname) + +#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname) \ + VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname) + +/* Derivatives of the main macros below, for calling functions + returning void. */ + +#define CALL_FN_v_v(fnptr) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_v(_junk,fnptr); } while (0) + +#define CALL_FN_v_W(fnptr, arg1) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_W(_junk,fnptr,arg1); } while (0) + +#define CALL_FN_v_WW(fnptr, arg1,arg2) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) + +#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) + +#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0) + +#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0) + +#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0) + +#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0) + +/* ----------------- x86-{linux,darwin,solaris} ---------------- */ + +#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ + || defined(PLAT_x86_solaris) + +/* These regs are trashed by the hidden call. No need to mention eax + as gcc can already see that, plus causes gcc to bomb. */ +#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "movl %%esp,%%edi\n\t" \ + "andl $0xfffffff0,%%esp\n\t" +#define VALGRIND_RESTORE_STACK \ + "movl %%edi,%%esp\n\t" + +/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned + long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ + "pushl 36(%%eax)\n\t" \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ + "pushl 40(%%eax)\n\t" \ + "pushl 36(%%eax)\n\t" \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ + "pushl 44(%%eax)\n\t" \ + "pushl 40(%%eax)\n\t" \ + "pushl 36(%%eax)\n\t" \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "pushl 48(%%eax)\n\t" \ + "pushl 44(%%eax)\n\t" \ + "pushl 40(%%eax)\n\t" \ + "pushl 36(%%eax)\n\t" \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_x86_linux || PLAT_x86_darwin || PLAT_x86_solaris */ + +/* ---------------- amd64-{linux,darwin,solaris} --------------- */ + +#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ + || defined(PLAT_amd64_solaris) + +/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ + "rdi", "r8", "r9", "r10", "r11" + +/* This is all pretty complex. It's so as to make stack unwinding + work reliably. See bug 243270. The basic problem is the sub and + add of 128 of %rsp in all of the following macros. If gcc believes + the CFA is in %rsp, then unwinding may fail, because what's at the + CFA is not what gcc "expected" when it constructs the CFIs for the + places where the macros are instantiated. + + But we can't just add a CFI annotation to increase the CFA offset + by 128, to match the sub of 128 from %rsp, because we don't know + whether gcc has chosen %rsp as the CFA at that point, or whether it + has chosen some other register (eg, %rbp). In the latter case, + adding a CFI annotation to change the CFA offset is simply wrong. + + So the solution is to get hold of the CFA using + __builtin_dwarf_cfa(), put it in a known register, and add a + CFI annotation to say what the register is. We choose %rbp for + this (perhaps perversely), because: + + (1) %rbp is already subject to unwinding. If a new register was + chosen then the unwinder would have to unwind it in all stack + traces, which is expensive, and + + (2) %rbp is already subject to precise exception updates in the + JIT. If a new register was chosen, we'd have to have precise + exceptions for it too, which reduces performance of the + generated code. + + However .. one extra complication. We can't just whack the result + of __builtin_dwarf_cfa() into %rbp and then add %rbp to the + list of trashed registers at the end of the inline assembly + fragments; gcc won't allow %rbp to appear in that list. Hence + instead we need to stash %rbp in %r15 for the duration of the asm, + and say that %r15 is trashed instead. gcc seems happy to go with + that. + + Oh .. and this all needs to be conditionalised so that it is + unchanged from before this commit, when compiled with older gccs + that don't support __builtin_dwarf_cfa. Furthermore, since + this header file is freestanding, it has to be independent of + config.h, and so the following conditionalisation cannot depend on + configure time checks. + + Although it's not clear from + 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)', + this expression excludes Darwin. + .cfi directives in Darwin assembly appear to be completely + different and I haven't investigated how they work. + + For even more entertainment value, note we have to use the + completely undocumented __builtin_dwarf_cfa(), which appears to + really compute the CFA, whereas __builtin_frame_address(0) claims + to but actually doesn't. See + https://bugs.kde.org/show_bug.cgi?id=243270#c47 +*/ +#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) +# define __FRAME_POINTER \ + ,"r"(__builtin_dwarf_cfa()) +# define VALGRIND_CFI_PROLOGUE \ + "movq %%rbp, %%r15\n\t" \ + "movq %2, %%rbp\n\t" \ + ".cfi_remember_state\n\t" \ + ".cfi_def_cfa rbp, 0\n\t" +# define VALGRIND_CFI_EPILOGUE \ + "movq %%r15, %%rbp\n\t" \ + ".cfi_restore_state\n\t" +#else +# define __FRAME_POINTER +# define VALGRIND_CFI_PROLOGUE +# define VALGRIND_CFI_EPILOGUE +#endif + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "movq %%rsp,%%r14\n\t" \ + "andq $0xfffffffffffffff0,%%rsp\n\t" +#define VALGRIND_RESTORE_STACK \ + "movq %%r14,%%rsp\n\t" + +/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned + long) == 8. */ + +/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ + macros. In order not to trash the stack redzone, we need to drop + %rsp by 128 before the hidden call, and restore afterwards. The + nastyness is that it is only by luck that the stack still appears + to be unwindable during the hidden call - since then the behaviour + of any routine using this macro does not match what the CFI data + says. Sigh. + + Why is this important? Imagine that a wrapper has a stack + allocated local, and passes to the hidden call, a pointer to it. + Because gcc does not know about the hidden call, it may allocate + that local in the redzone. Unfortunately the hidden call may then + trash it before it comes to use it. So we must step clear of the + redzone, for the duration of the hidden call, to make it safe. + + Probably the same problem afflicts the other redzone-style ABIs too + (ppc64-linux); but for those, the stack is + self describing (none of this CFI nonsense) so at least messing + with the stack pointer doesn't give a danger of non-unwindable + stack. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 88(%%rax)\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 96(%%rax)\n\t" \ + "pushq 88(%%rax)\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */ + +/* ------------------------ ppc32-linux ------------------------ */ + +#if defined(PLAT_ppc32_linux) + +/* This is useful for finding out about the on-stack stuff: + + extern int f9 ( int,int,int,int,int,int,int,int,int ); + extern int f10 ( int,int,int,int,int,int,int,int,int,int ); + extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); + extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); + + int g9 ( void ) { + return f9(11,22,33,44,55,66,77,88,99); + } + int g10 ( void ) { + return f10(11,22,33,44,55,66,77,88,99,110); + } + int g11 ( void ) { + return f11(11,22,33,44,55,66,77,88,99,110,121); + } + int g12 ( void ) { + return f12(11,22,33,44,55,66,77,88,99,110,121,132); + } +*/ + +/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "lr", "ctr", "xer", \ + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ + "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ + "r11", "r12", "r13" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "mr 28,1\n\t" \ + "rlwinm 1,1,0,0,27\n\t" +#define VALGRIND_RESTORE_STACK \ + "mr 1,28\n\t" + +/* These CALL_FN_ macros assume that on ppc32-linux, + sizeof(unsigned long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-16\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-16\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-32\n\t" \ + /* arg11 */ \ + "lwz 3,44(11)\n\t" \ + "stw 3,16(1)\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + _argvec[12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-32\n\t" \ + /* arg12 */ \ + "lwz 3,48(11)\n\t" \ + "stw 3,20(1)\n\t" \ + /* arg11 */ \ + "lwz 3,44(11)\n\t" \ + "stw 3,16(1)\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_ppc32_linux */ + +/* ------------------------ ppc64-linux ------------------------ */ + +#if defined(PLAT_ppc64be_linux) + +/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "lr", "ctr", "xer", \ + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ + "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ + "r11", "r12", "r13" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "mr 28,1\n\t" \ + "rldicr 1,1,0,59\n\t" +#define VALGRIND_RESTORE_STACK \ + "mr 1,28\n\t" + +/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned + long) == 8. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+0]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+1]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+2]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+3]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+4]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+5]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+6]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+7]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+8]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+9]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ + /* arg9 */ \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+10]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ + /* arg10 */ \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+11]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ + /* arg11 */ \ + "ld 3,88(11)\n\t" \ + "std 3,128(1)\n\t" \ + /* arg10 */ \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+12]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + _argvec[2+12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ + /* arg12 */ \ + "ld 3,96(11)\n\t" \ + "std 3,136(1)\n\t" \ + /* arg11 */ \ + "ld 3,88(11)\n\t" \ + "std 3,128(1)\n\t" \ + /* arg10 */ \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_ppc64be_linux */ + +/* ------------------------- ppc64le-linux ----------------------- */ +#if defined(PLAT_ppc64le_linux) + +/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "lr", "ctr", "xer", \ + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ + "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ + "r11", "r12", "r13" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "mr 28,1\n\t" \ + "rldicr 1,1,0,59\n\t" +#define VALGRIND_RESTORE_STACK \ + "mr 1,28\n\t" + +/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned + long) == 8. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+0]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+1]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+2]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+3]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+4]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+5]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+6]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+7]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+8]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+9]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ + /* arg9 */ \ + "ld 3,72(12)\n\t" \ + "std 3,96(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+10]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ + /* arg10 */ \ + "ld 3,80(12)\n\t" \ + "std 3,104(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(12)\n\t" \ + "std 3,96(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+11]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ + /* arg11 */ \ + "ld 3,88(12)\n\t" \ + "std 3,112(1)\n\t" \ + /* arg10 */ \ + "ld 3,80(12)\n\t" \ + "std 3,104(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(12)\n\t" \ + "std 3,96(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+12]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + _argvec[2+12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ + /* arg12 */ \ + "ld 3,96(12)\n\t" \ + "std 3,120(1)\n\t" \ + /* arg11 */ \ + "ld 3,88(12)\n\t" \ + "std 3,112(1)\n\t" \ + /* arg10 */ \ + "ld 3,80(12)\n\t" \ + "std 3,104(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(12)\n\t" \ + "std 3,96(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_ppc64le_linux */ + +/* ------------------------- arm-linux ------------------------- */ + +#if defined(PLAT_arm_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4", "r12", "r14" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +/* This is a bit tricky. We store the original stack pointer in r10 + as it is callee-saves. gcc doesn't allow the use of r11 for some + reason. Also, we can't directly "bic" the stack pointer in thumb + mode since r13 isn't an allowed register number in that context. + So use r4 as a temporary, since that is about to get trashed + anyway, just after each use of this macro. Side effect is we need + to be very careful about any future changes, since + VALGRIND_ALIGN_STACK simply assumes r4 is usable. */ +#define VALGRIND_ALIGN_STACK \ + "mov r10, sp\n\t" \ + "mov r4, sp\n\t" \ + "bic r4, r4, #7\n\t" \ + "mov sp, r4\n\t" +#define VALGRIND_RESTORE_STACK \ + "mov sp, r10\n\t" + +/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned + long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "push {r0} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "push {r0, r1} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "push {r0, r1, r2} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "push {r0, r1, r2, r3} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #40] \n\t" \ + "push {r0} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #40] \n\t" \ + "ldr r1, [%1, #44] \n\t" \ + "push {r0, r1} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #40] \n\t" \ + "ldr r1, [%1, #44] \n\t" \ + "ldr r2, [%1, #48] \n\t" \ + "push {r0, r1, r2} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_arm_linux */ + +/* ------------------------ arm64-linux ------------------------ */ + +#if defined(PLAT_arm64_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "x0", "x1", "x2", "x3","x4", "x5", "x6", "x7", "x8", "x9", \ + "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", \ + "x18", "x19", "x20", "x30", \ + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", \ + "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", \ + "v26", "v27", "v28", "v29", "v30", "v31" + +/* x21 is callee-saved, so we can use it to save and restore SP around + the hidden call. */ +#define VALGRIND_ALIGN_STACK \ + "mov x21, sp\n\t" \ + "bic sp, x21, #15\n\t" +#define VALGRIND_RESTORE_STACK \ + "mov sp, x21\n\t" + +/* These CALL_FN_ macros assume that on arm64-linux, + sizeof(unsigned long) == 8. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #0x20 \n\t" \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1, #72] \n\t" \ + "str x8, [sp, #0] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #0x20 \n\t" \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1, #72] \n\t" \ + "str x8, [sp, #0] \n\t" \ + "ldr x8, [%1, #80] \n\t" \ + "str x8, [sp, #8] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #0x30 \n\t" \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1, #72] \n\t" \ + "str x8, [sp, #0] \n\t" \ + "ldr x8, [%1, #80] \n\t" \ + "str x8, [sp, #8] \n\t" \ + "ldr x8, [%1, #88] \n\t" \ + "str x8, [sp, #16] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11, \ + arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #0x30 \n\t" \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1, #72] \n\t" \ + "str x8, [sp, #0] \n\t" \ + "ldr x8, [%1, #80] \n\t" \ + "str x8, [sp, #8] \n\t" \ + "ldr x8, [%1, #88] \n\t" \ + "str x8, [sp, #16] \n\t" \ + "ldr x8, [%1, #96] \n\t" \ + "str x8, [sp, #24] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_arm64_linux */ + +/* ------------------------- s390x-linux ------------------------- */ + +#if defined(PLAT_s390x_linux) + +/* Similar workaround as amd64 (see above), but we use r11 as frame + pointer and save the old r11 in r7. r11 might be used for + argvec, therefore we copy argvec in r1 since r1 is clobbered + after the call anyway. */ +#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) +# define __FRAME_POINTER \ + ,"d"(__builtin_dwarf_cfa()) +# define VALGRIND_CFI_PROLOGUE \ + ".cfi_remember_state\n\t" \ + "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ + "lgr 7,11\n\t" \ + "lgr 11,%2\n\t" \ + ".cfi_def_cfa r11, 0\n\t" +# define VALGRIND_CFI_EPILOGUE \ + "lgr 11, 7\n\t" \ + ".cfi_restore_state\n\t" +#else +# define __FRAME_POINTER +# define VALGRIND_CFI_PROLOGUE \ + "lgr 1,%1\n\t" +# define VALGRIND_CFI_EPILOGUE +#endif + +/* Nb: On s390 the stack pointer is properly aligned *at all times* + according to the s390 GCC maintainer. (The ABI specification is not + precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and + VALGRIND_RESTORE_STACK are not defined here. */ + +/* These regs are trashed by the hidden call. Note that we overwrite + r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the + function a proper return address. All others are ABI defined call + clobbers. */ +#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \ + "f0","f1","f2","f3","f4","f5","f6","f7" + +/* Nb: Although r11 is modified in the asm snippets below (inside + VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for + two reasons: + (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not + modified + (2) GCC will complain that r11 cannot appear inside a clobber section, + when compiled with -O -fno-omit-frame-pointer + */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 1, 0(1)\n\t" /* target->r1 */ \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +/* The call abi has the arguments in r2-r6 and stack */ +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1, arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-168\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,168\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-176\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,176\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-184\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,184\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-192\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,192\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-200\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,200\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10, arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-208\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "mvc 200(8,15), 88(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,208\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + _argvec[12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-216\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "mvc 200(8,15), 88(1)\n\t" \ + "mvc 208(8,15), 96(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,216\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + + +#endif /* PLAT_s390x_linux */ + +/* ------------------------- mips32-linux ----------------------- */ + +#if defined(PLAT_mips32_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ +"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ +"$25", "$31" + +/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned + long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16\n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $4, 4(%1) \n\t" /* arg1*/ \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 24\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 24 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 32\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "nop\n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 32 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 32\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 32 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 40\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 40 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 40\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 36(%1) \n\t" \ + "sw $4, 32($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 40 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 48\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 36(%1) \n\t" \ + "sw $4, 32($29) \n\t" \ + "lw $4, 40(%1) \n\t" \ + "sw $4, 36($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 48 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 48\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 36(%1) \n\t" \ + "sw $4, 32($29) \n\t" \ + "lw $4, 40(%1) \n\t" \ + "sw $4, 36($29) \n\t" \ + "lw $4, 44(%1) \n\t" \ + "sw $4, 40($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 48 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 56\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 36(%1) \n\t" \ + "sw $4, 32($29) \n\t" \ + "lw $4, 40(%1) \n\t" \ + "sw $4, 36($29) \n\t" \ + "lw $4, 44(%1) \n\t" \ + "sw $4, 40($29) \n\t" \ + "lw $4, 48(%1) \n\t" \ + "sw $4, 44($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 56 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_mips32_linux */ + +/* ------------------------- mips64-linux ------------------------- */ + +#if defined(PLAT_mips64_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ +"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ +"$25", "$31" + +/* These CALL_FN_ macros assume that on mips64-linux, + sizeof(long long) == 8. */ + +#define MIPS64_LONG2REG_CAST(x) ((long long)(long)x) + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[1]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + __asm__ volatile( \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[2]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" /* arg1*/ \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[3]; \ + volatile unsigned long long _res; \ + _argvec[0] = _orig.nraddr; \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[4]; \ + volatile unsigned long long _res; \ + _argvec[0] = _orig.nraddr; \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[5]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[6]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[7]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[8]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[9]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[10]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \ + __asm__ volatile( \ + "dsubu $29, $29, 8\n\t" \ + "ld $4, 72(%1)\n\t" \ + "sd $4, 0($29)\n\t" \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "daddu $29, $29, 8\n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[11]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \ + _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \ + __asm__ volatile( \ + "dsubu $29, $29, 16\n\t" \ + "ld $4, 72(%1)\n\t" \ + "sd $4, 0($29)\n\t" \ + "ld $4, 80(%1)\n\t" \ + "sd $4, 8($29)\n\t" \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "daddu $29, $29, 16\n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[12]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \ + _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \ + _argvec[11] = MIPS64_LONG2REG_CAST(arg11); \ + __asm__ volatile( \ + "dsubu $29, $29, 24\n\t" \ + "ld $4, 72(%1)\n\t" \ + "sd $4, 0($29)\n\t" \ + "ld $4, 80(%1)\n\t" \ + "sd $4, 8($29)\n\t" \ + "ld $4, 88(%1)\n\t" \ + "sd $4, 16($29)\n\t" \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "daddu $29, $29, 24\n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[13]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \ + _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \ + _argvec[11] = MIPS64_LONG2REG_CAST(arg11); \ + _argvec[12] = MIPS64_LONG2REG_CAST(arg12); \ + __asm__ volatile( \ + "dsubu $29, $29, 32\n\t" \ + "ld $4, 72(%1)\n\t" \ + "sd $4, 0($29)\n\t" \ + "ld $4, 80(%1)\n\t" \ + "sd $4, 8($29)\n\t" \ + "ld $4, 88(%1)\n\t" \ + "sd $4, 16($29)\n\t" \ + "ld $4, 96(%1)\n\t" \ + "sd $4, 24($29)\n\t" \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "daddu $29, $29, 32\n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#endif /* PLAT_mips64_linux */ + +/* ------------------------------------------------------------------ */ +/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ +/* */ +/* ------------------------------------------------------------------ */ + +/* Some request codes. There are many more of these, but most are not + exposed to end-user view. These are the public ones, all of the + form 0x1000 + small_number. + + Core ones are in the range 0x00000000--0x0000ffff. The non-public + ones start at 0x2000. +*/ + +/* These macros are used by tools -- they must be public, but don't + embed them into other programs. */ +#define VG_USERREQ_TOOL_BASE(a,b) \ + ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) +#define VG_IS_TOOL_USERREQ(a, b, v) \ + (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) + +/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! + This enum comprises an ABI exported by Valgrind to programs + which use client requests. DO NOT CHANGE THE NUMERIC VALUES OF THESE + ENTRIES, NOR DELETE ANY -- add new ones at the end of the most + relevant group. */ +typedef + enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, + VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, + + /* These allow any function to be called from the simulated + CPU but run on the real CPU. Nb: the first arg passed to + the function is always the ThreadId of the running + thread! So CLIENT_CALL0 actually requires a 1 arg + function, etc. */ + VG_USERREQ__CLIENT_CALL0 = 0x1101, + VG_USERREQ__CLIENT_CALL1 = 0x1102, + VG_USERREQ__CLIENT_CALL2 = 0x1103, + VG_USERREQ__CLIENT_CALL3 = 0x1104, + + /* Can be useful in regression testing suites -- eg. can + send Valgrind's output to /dev/null and still count + errors. */ + VG_USERREQ__COUNT_ERRORS = 0x1201, + + /* Allows the client program and/or gdbserver to execute a monitor + command. */ + VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202, + + /* These are useful and can be interpreted by any tool that + tracks malloc() et al, by using vg_replace_malloc.c. */ + VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, + VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b, + VG_USERREQ__FREELIKE_BLOCK = 0x1302, + /* Memory pool support. */ + VG_USERREQ__CREATE_MEMPOOL = 0x1303, + VG_USERREQ__DESTROY_MEMPOOL = 0x1304, + VG_USERREQ__MEMPOOL_ALLOC = 0x1305, + VG_USERREQ__MEMPOOL_FREE = 0x1306, + VG_USERREQ__MEMPOOL_TRIM = 0x1307, + VG_USERREQ__MOVE_MEMPOOL = 0x1308, + VG_USERREQ__MEMPOOL_CHANGE = 0x1309, + VG_USERREQ__MEMPOOL_EXISTS = 0x130a, + + /* Allow printfs to valgrind log. */ + /* The first two pass the va_list argument by value, which + assumes it is the same size as or smaller than a UWord, + which generally isn't the case. Hence are deprecated. + The second two pass the vargs by reference and so are + immune to this problem. */ + /* both :: char* fmt, va_list vargs (DEPRECATED) */ + VG_USERREQ__PRINTF = 0x1401, + VG_USERREQ__PRINTF_BACKTRACE = 0x1402, + /* both :: char* fmt, va_list* vargs */ + VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404, + + /* Stack support. */ + VG_USERREQ__STACK_REGISTER = 0x1501, + VG_USERREQ__STACK_DEREGISTER = 0x1502, + VG_USERREQ__STACK_CHANGE = 0x1503, + + /* Wine support */ + VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601, + + /* Querying of debug info. */ + VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701, + + /* Disable/enable error reporting level. Takes a single + Word arg which is the delta to this thread's error + disablement indicator. Hence 1 disables or further + disables errors, and -1 moves back towards enablement. + Other values are not allowed. */ + VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801, + + /* Some requests used for Valgrind internal, such as + self-test or self-hosting. */ + /* Initialise IR injection */ + VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901, + /* Used by Inner Valgrind to inform Outer Valgrind where to + find the list of inner guest threads */ + VG_USERREQ__INNER_THREADS = 0x1902 + } Vg_ClientRequest; + +#if !defined(__GNUC__) +# define __extension__ /* */ +#endif + + +/* Returns the number of Valgrinds this code is running under. That + is, 0 if running natively, 1 if running under Valgrind, 2 if + running under Valgrind which is running under another Valgrind, + etc. */ +#define RUNNING_ON_VALGRIND \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ + VG_USERREQ__RUNNING_ON_VALGRIND, \ + 0, 0, 0, 0, 0) \ + + +/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + + _qzz_len - 1]. Useful if you are debugging a JITter or some such, + since it provides a way to make sure valgrind will retranslate the + invalidated area. Returns no value. */ +#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \ + _qzz_addr, _qzz_len, 0, 0, 0) + +#define VALGRIND_INNER_THREADS(_qzz_addr) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__INNER_THREADS, \ + _qzz_addr, 0, 0, 0, 0) + + +/* These requests are for getting Valgrind itself to print something. + Possibly with a backtrace. This is a really ugly hack. The return value + is the number of characters printed, excluding the "**** " part at the + start and the backtrace (if present). */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) +/* Modern GCC will optimize the static routine out if unused, + and unused attribute will shut down warnings about it. */ +static int VALGRIND_PRINTF(const char *format, ...) + __attribute__((format(__printf__, 1, 2), __unused__)); +#endif +static int +#if defined(_MSC_VER) +__inline +#endif +VALGRIND_PRINTF(const char *format, ...) +{ +#if defined(NVALGRIND) + (void)format; + return 0; +#else /* NVALGRIND */ +#if defined(_MSC_VER) || defined(__MINGW64__) + uintptr_t _qzz_res; +#else + unsigned long _qzz_res; +#endif + va_list vargs; + va_start(vargs, format); +#if defined(_MSC_VER) || defined(__MINGW64__) + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_VALIST_BY_REF, + (uintptr_t)format, + (uintptr_t)&vargs, + 0, 0, 0); +#else + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_VALIST_BY_REF, + (unsigned long)format, + (unsigned long)&vargs, + 0, 0, 0); +#endif + va_end(vargs); + return (int)_qzz_res; +#endif /* NVALGRIND */ +} + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) +static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) + __attribute__((format(__printf__, 1, 2), __unused__)); +#endif +static int +#if defined(_MSC_VER) +__inline +#endif +VALGRIND_PRINTF_BACKTRACE(const char *format, ...) +{ +#if defined(NVALGRIND) + (void)format; + return 0; +#else /* NVALGRIND */ +#if defined(_MSC_VER) || defined(__MINGW64__) + uintptr_t _qzz_res; +#else + unsigned long _qzz_res; +#endif + va_list vargs; + va_start(vargs, format); +#if defined(_MSC_VER) || defined(__MINGW64__) + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, + (uintptr_t)format, + (uintptr_t)&vargs, + 0, 0, 0); +#else + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, + (unsigned long)format, + (unsigned long)&vargs, + 0, 0, 0); +#endif + va_end(vargs); + return (int)_qzz_res; +#endif /* NVALGRIND */ +} + + +/* These requests allow control to move from the simulated CPU to the + real CPU, calling an arbitrary function. + + Note that the current ThreadId is inserted as the first argument. + So this call: + + VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) + + requires f to have this signature: + + Word f(Word tid, Word arg1, Word arg2) + + where "Word" is a word-sized type. + + Note that these client requests are not entirely reliable. For example, + if you call a function with them that subsequently calls printf(), + there's a high chance Valgrind will crash. Generally, your prospects of + these working are made higher if the called function does not refer to + any global variables, and does not refer to any libc or other functions + (printf et al). Any kind of entanglement with libc or dynamic linking is + likely to have a bad outcome, for tricky reasons which we've grappled + with a lot in the past. +*/ +#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL0, \ + _qyy_fn, \ + 0, 0, 0, 0) + +#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL1, \ + _qyy_fn, \ + _qyy_arg1, 0, 0, 0) + +#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL2, \ + _qyy_fn, \ + _qyy_arg1, _qyy_arg2, 0, 0) + +#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL3, \ + _qyy_fn, \ + _qyy_arg1, _qyy_arg2, \ + _qyy_arg3, 0) + + +/* Counts the number of errors that have been recorded by a tool. Nb: + the tool must record the errors with VG_(maybe_record_error)() or + VG_(unique_error)() for them to be counted. */ +#define VALGRIND_COUNT_ERRORS \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + 0 /* default return */, \ + VG_USERREQ__COUNT_ERRORS, \ + 0, 0, 0, 0, 0) + +/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing + when heap blocks are allocated in order to give accurate results. This + happens automatically for the standard allocator functions such as + malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete, + delete[], etc. + + But if your program uses a custom allocator, this doesn't automatically + happen, and Valgrind will not do as well. For example, if you allocate + superblocks with mmap() and then allocates chunks of the superblocks, all + Valgrind's observations will be at the mmap() level and it won't know that + the chunks should be considered separate entities. In Memcheck's case, + that means you probably won't get heap block overrun detection (because + there won't be redzones marked as unaddressable) and you definitely won't + get any leak detection. + + The following client requests allow a custom allocator to be annotated so + that it can be handled accurately by Valgrind. + + VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated + by a malloc()-like function. For Memcheck (an illustrative case), this + does two things: + + - It records that the block has been allocated. This means any addresses + within the block mentioned in error messages will be + identified as belonging to the block. It also means that if the block + isn't freed it will be detected by the leak checker. + + - It marks the block as being addressable and undefined (if 'is_zeroed' is + not set), or addressable and defined (if 'is_zeroed' is set). This + controls how accesses to the block by the program are handled. + + 'addr' is the start of the usable block (ie. after any + redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator + can apply redzones -- these are blocks of padding at the start and end of + each block. Adding redzones is recommended as it makes it much more likely + Valgrind will spot block overruns. `is_zeroed' indicates if the memory is + zeroed (or filled with another predictable value), as is the case for + calloc(). + + VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a + heap block -- that will be used by the client program -- is allocated. + It's best to put it at the outermost level of the allocator if possible; + for example, if you have a function my_alloc() which calls + internal_alloc(), and the client request is put inside internal_alloc(), + stack traces relating to the heap block will contain entries for both + my_alloc() and internal_alloc(), which is probably not what you want. + + For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out + custom blocks from within a heap block, B, that has been allocated with + malloc/calloc/new/etc, then block B will be *ignored* during leak-checking + -- the custom blocks will take precedence. + + VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For + Memcheck, it does two things: + + - It records that the block has been deallocated. This assumes that the + block was annotated as having been allocated via + VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. + + - It marks the block as being unaddressable. + + VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a + heap block is deallocated. + + VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For + Memcheck, it does four things: + + - It records that the size of a block has been changed. This assumes that + the block was annotated as having been allocated via + VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. + + - If the block shrunk, it marks the freed memory as being unaddressable. + + - If the block grew, it marks the new area as undefined and defines a red + zone past the end of the new block. + + - The V-bits of the overlap between the old and the new block are preserved. + + VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block + and before deallocation of the old block. + + In many cases, these three client requests will not be enough to get your + allocator working well with Memcheck. More specifically, if your allocator + writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call + will be necessary to mark the memory as addressable just before the zeroing + occurs, otherwise you'll get a lot of invalid write errors. For example, + you'll need to do this if your allocator recycles freed blocks, but it + zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK). + Alternatively, if your allocator reuses freed blocks for allocator-internal + data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary. + + Really, what's happening is a blurring of the lines between the client + program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the + memory should be considered unaddressable to the client program, but the + allocator knows more than the rest of the client program and so may be able + to safely access it. Extra client requests are necessary for Valgrind to + understand the distinction between the allocator and the rest of the + program. + + Ignored if addr == 0. +*/ +#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \ + addr, sizeB, rzB, is_zeroed, 0) + +/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. + Ignored if addr == 0. +*/ +#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK, \ + addr, oldSizeB, newSizeB, rzB, 0) + +/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. + Ignored if addr == 0. +*/ +#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK, \ + addr, rzB, 0, 0, 0) + +/* Create a memory pool. */ +#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \ + pool, rzB, is_zeroed, 0, 0) + +/* Create a memory pool with some flags specifying extended behaviour. + When flags is zero, the behaviour is identical to VALGRIND_CREATE_MEMPOOL. + + The flag VALGRIND_MEMPOOL_METAPOOL specifies that the pieces of memory + associated with the pool using VALGRIND_MEMPOOL_ALLOC will be used + by the application as superblocks to dole out MALLOC_LIKE blocks using + VALGRIND_MALLOCLIKE_BLOCK. In other words, a meta pool is a "2 levels" + pool : first level is the blocks described by VALGRIND_MEMPOOL_ALLOC. + The second level blocks are described using VALGRIND_MALLOCLIKE_BLOCK. + Note that the association between the pool and the second level blocks + is implicit : second level blocks will be located inside first level + blocks. It is necessary to use the VALGRIND_MEMPOOL_METAPOOL flag + for such 2 levels pools, as otherwise valgrind will detect overlapping + memory blocks, and will abort execution (e.g. during leak search). + + Such a meta pool can also be marked as an 'auto free' pool using the flag + VALGRIND_MEMPOOL_AUTO_FREE, which must be OR-ed together with the + VALGRIND_MEMPOOL_METAPOOL. For an 'auto free' pool, VALGRIND_MEMPOOL_FREE + will automatically free the second level blocks that are contained + inside the first level block freed with VALGRIND_MEMPOOL_FREE. + In other words, calling VALGRIND_MEMPOOL_FREE will cause implicit calls + to VALGRIND_FREELIKE_BLOCK for all the second level blocks included + in the first level block. + Note: it is an error to use the VALGRIND_MEMPOOL_AUTO_FREE flag + without the VALGRIND_MEMPOOL_METAPOOL flag. +*/ +#define VALGRIND_MEMPOOL_AUTO_FREE 1 +#define VALGRIND_MEMPOOL_METAPOOL 2 +#define VALGRIND_CREATE_MEMPOOL_EXT(pool, rzB, is_zeroed, flags) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \ + pool, rzB, is_zeroed, flags, 0) + +/* Destroy a memory pool. */ +#define VALGRIND_DESTROY_MEMPOOL(pool) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL, \ + pool, 0, 0, 0, 0) + +/* Associate a piece of memory with a memory pool. */ +#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC, \ + pool, addr, size, 0, 0) + +/* Disassociate a piece of memory from a memory pool. */ +#define VALGRIND_MEMPOOL_FREE(pool, addr) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE, \ + pool, addr, 0, 0, 0) + +/* Disassociate any pieces outside a particular range. */ +#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM, \ + pool, addr, size, 0, 0) + +/* Resize and/or move a piece associated with a memory pool. */ +#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL, \ + poolA, poolB, 0, 0, 0) + +/* Resize and/or move a piece associated with a memory pool. */ +#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE, \ + pool, addrA, addrB, size, 0) + +/* Return 1 if a mempool exists, else 0. */ +#define VALGRIND_MEMPOOL_EXISTS(pool) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__MEMPOOL_EXISTS, \ + pool, 0, 0, 0, 0) + +/* Mark a piece of memory as being a stack. Returns a stack id. + start is the lowest addressable stack byte, end is the highest + addressable stack byte. */ +#define VALGRIND_STACK_REGISTER(start, end) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__STACK_REGISTER, \ + start, end, 0, 0, 0) + +/* Unmark the piece of memory associated with a stack id as being a + stack. */ +#define VALGRIND_STACK_DEREGISTER(id) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \ + id, 0, 0, 0, 0) + +/* Change the start and end address of the stack id. + start is the new lowest addressable stack byte, end is the new highest + addressable stack byte. */ +#define VALGRIND_STACK_CHANGE(id, start, end) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE, \ + id, start, end, 0, 0) + +/* Load PDB debug info for Wine PE image_map. */ +#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \ + fd, ptr, total_size, delta, 0) + +/* Map a code address to a source file name and line number. buf64 + must point to a 64-byte buffer in the caller's address space. The + result will be dumped in there and is guaranteed to be zero + terminated. If no info is found, the first byte is set to zero. */ +#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__MAP_IP_TO_SRCLOC, \ + addr, buf64, 0, 0, 0) + +/* Disable error reporting for this thread. Behaves in a stack like + way, so you can safely call this multiple times provided that + VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times + to re-enable reporting. The first call of this macro disables + reporting. Subsequent calls have no effect except to increase the + number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable + reporting. Child threads do not inherit this setting from their + parents -- they are always created with reporting enabled. */ +#define VALGRIND_DISABLE_ERROR_REPORTING \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ + 1, 0, 0, 0, 0) + +/* Re-enable error reporting, as per comments on + VALGRIND_DISABLE_ERROR_REPORTING. */ +#define VALGRIND_ENABLE_ERROR_REPORTING \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ + -1, 0, 0, 0, 0) + +/* Execute a monitor command from the client program. + If a connection is opened with GDB, the output will be sent + according to the output mode set for vgdb. + If no connection is opened, output will go to the log output. + Returns 1 if command not recognised, 0 otherwise. */ +#define VALGRIND_MONITOR_COMMAND(command) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \ + command, 0, 0, 0, 0) + + +#undef PLAT_x86_darwin +#undef PLAT_amd64_darwin +#undef PLAT_x86_win32 +#undef PLAT_amd64_win64 +#undef PLAT_x86_linux +#undef PLAT_amd64_linux +#undef PLAT_ppc32_linux +#undef PLAT_ppc64be_linux +#undef PLAT_ppc64le_linux +#undef PLAT_arm_linux +#undef PLAT_s390x_linux +#undef PLAT_mips32_linux +#undef PLAT_mips64_linux +#undef PLAT_x86_solaris +#undef PLAT_amd64_solaris + +#endif /* __VALGRIND_H */ diff --git a/glib/win_iconv.c b/glib/win_iconv.c new file mode 100644 index 0000000..7c78e78 --- /dev/null +++ b/glib/win_iconv.c @@ -0,0 +1,2098 @@ +/* + * iconv library implemented with Win32 API. + * + * This file is placed in the public domain. + * + * Maintainer: Yukihiro Nakadaira + * + * If $WINICONV_LIBICONV_DLL environment variable was defined, win_iconv + * loads the specified DLL dynamically and uses it. If loading the DLL + * or iconv_open() failed, falls back to internal conversion. + * $WINICONV_LIBICONV_DLL is a comma separated list. The first loadable + * DLL is used. The specified DLL should have iconv_open(), + * iconv_close() and iconv() functions. Or these functions can be + * libiconv_open(), libiconv_close() and libiconv(). + * + * Win32 API does not support strict encoding conversion for some + * codepage. And MLang function drop or replace invalid bytes and does + * not return useful error status as iconv. This implementation cannot + * be used for encoding validation purpose. + */ + +/* for WC_NO_BEST_FIT_CHARS */ +#ifndef WINVER +# define WINVER 0x0500 +#endif + +#define STRICT +#include +#include +#include +#include + +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + +/* WORKAROUND: */ +#ifndef UNDER_CE +#define GetProcAddressA GetProcAddress +#endif + +#if 0 +# define MAKE_EXE +# define MAKE_DLL +# define USE_LIBICONV_DLL +#endif + +#if !defined(DEFAULT_LIBICONV_DLL) +# define DEFAULT_LIBICONV_DLL "" +#endif + +#define MB_CHAR_MAX 16 + +#define UNICODE_MODE_BOM_DONE 1 +#define UNICODE_MODE_SWAPPED 2 + +#define FLAG_USE_BOM 1 +#define FLAG_TRANSLIT 2 /* //TRANSLIT */ +#define FLAG_IGNORE 4 /* //IGNORE */ + +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; + +typedef void* iconv_t; + +iconv_t iconv_open(const char *tocode, const char *fromcode); +int iconv_close(iconv_t cd); +size_t iconv(iconv_t cd, /* const */ char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); + +/* libiconv interface for vim */ +#if defined(MAKE_DLL) +int +iconvctl (iconv_t cd, int request, void* argument) +{ + /* not supported */ + return 0; +} +#endif + +typedef struct compat_t compat_t; +typedef struct csconv_t csconv_t; +typedef struct rec_iconv_t rec_iconv_t; + +typedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode); +typedef int (*f_iconv_close)(iconv_t cd); +typedef size_t (*f_iconv)(iconv_t cd, /* const */ char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); +typedef int* (*f_errno)(void); +typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize); +typedef int (*f_flush)(csconv_t *cv, uchar *buf, int bufsize); + +#define COMPAT_IN 1 +#define COMPAT_OUT 2 + +/* unicode mapping for compatibility with other conversion table. */ +struct compat_t { + uint in; + uint out; + uint flag; +}; + +struct csconv_t { + int codepage; + int flags; + f_mbtowc mbtowc; + f_wctomb wctomb; + f_mblen mblen; + f_flush flush; + DWORD mode; + compat_t *compat; +}; + +struct rec_iconv_t { + iconv_t cd; + f_iconv_close iconv_close; + f_iconv iconv; + f_errno _errno; + csconv_t from; + csconv_t to; +#if defined(USE_LIBICONV_DLL) + HMODULE hlibiconv; +#endif +}; + +static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); +static int win_iconv_close(iconv_t cd); +static size_t win_iconv(iconv_t cd, /* const */ char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); + +static int load_mlang(void); +static int make_csconv(const char *name, csconv_t *cv); +static int name_to_codepage(const char *name); +static uint utf16_to_ucs4(const ushort *wbuf); +static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize); +static int mbtowc_flags(int codepage); +static int must_use_null_useddefaultchar(int codepage); +static char *strrstr(const char *str, const char *token); +static char *xstrndup(const char *s, size_t n); +static int seterror(int err); + +#if defined(USE_LIBICONV_DLL) +static int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); +static PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size); +static FARPROC find_imported_function(HMODULE hModule, const char *funcname); + +static HMODULE hwiniconv; +#endif + +static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); +static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); +static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); +static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize); +static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize); + +static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize); + +static struct { + int codepage; + const char *name; +} codepage_alias[] = { + {65001, "CP65001"}, + {65001, "UTF8"}, + {65001, "UTF-8"}, + + {1200, "CP1200"}, + {1200, "UTF16LE"}, + {1200, "UTF-16LE"}, + {1200, "UCS2LE"}, + {1200, "UCS-2LE"}, + + {1201, "CP1201"}, + {1201, "UTF16BE"}, + {1201, "UTF-16BE"}, + {1201, "UCS2BE"}, + {1201, "UCS-2BE"}, + {1201, "unicodeFFFE"}, + + {12000, "CP12000"}, + {12000, "UTF32LE"}, + {12000, "UTF-32LE"}, + {12000, "UCS4LE"}, + {12000, "UCS-4LE"}, + + {12001, "CP12001"}, + {12001, "UTF32BE"}, + {12001, "UTF-32BE"}, + {12001, "UCS4BE"}, + {12001, "UCS-4BE"}, + +#ifndef GLIB_COMPILATION + /* + * Default is big endian. + * See rfc2781 4.3 Interpreting text labelled as UTF-16. + */ + {1201, "UTF16"}, + {1201, "UTF-16"}, + {1201, "UCS2"}, + {1201, "UCS-2"}, + {12001, "UTF32"}, + {12001, "UTF-32"}, + {12001, "UCS-4"}, + {12001, "UCS4"}, +#else + /* Default is little endian, because the platform is */ + {1200, "UTF16"}, + {1200, "UTF-16"}, + {1200, "UCS2"}, + {1200, "UCS-2"}, + {12000, "UTF32"}, + {12000, "UTF-32"}, + {12000, "UCS4"}, + {12000, "UCS-4"}, +#endif + + /* copy from libiconv `iconv -l` */ + /* !IsValidCodePage(367) */ + {20127, "ANSI_X3.4-1968"}, + {20127, "ANSI_X3.4-1986"}, + {20127, "ASCII"}, + {20127, "CP367"}, + {20127, "IBM367"}, + {20127, "ISO-IR-6"}, + {20127, "ISO646-US"}, + {20127, "ISO_646.IRV:1991"}, + {20127, "US"}, + {20127, "US-ASCII"}, + {20127, "CSASCII"}, + + /* !IsValidCodePage(819) */ + {1252, "CP819"}, + {1252, "IBM819"}, + {28591, "ISO-8859-1"}, + {28591, "ISO-IR-100"}, + {28591, "ISO8859-1"}, + {28591, "ISO_8859-1"}, + {28591, "ISO_8859-1:1987"}, + {28591, "L1"}, + {28591, "LATIN1"}, + {28591, "CSISOLATIN1"}, + + {1250, "CP1250"}, + {1250, "MS-EE"}, + {1250, "WINDOWS-1250"}, + + {1251, "CP1251"}, + {1251, "MS-CYRL"}, + {1251, "WINDOWS-1251"}, + + {1252, "CP1252"}, + {1252, "MS-ANSI"}, + {1252, "WINDOWS-1252"}, + + {1253, "CP1253"}, + {1253, "MS-GREEK"}, + {1253, "WINDOWS-1253"}, + + {1254, "CP1254"}, + {1254, "MS-TURK"}, + {1254, "WINDOWS-1254"}, + + {1255, "CP1255"}, + {1255, "MS-HEBR"}, + {1255, "WINDOWS-1255"}, + + {1256, "CP1256"}, + {1256, "MS-ARAB"}, + {1256, "WINDOWS-1256"}, + + {1257, "CP1257"}, + {1257, "WINBALTRIM"}, + {1257, "WINDOWS-1257"}, + + {1258, "CP1258"}, + {1258, "WINDOWS-1258"}, + + {850, "850"}, + {850, "CP850"}, + {850, "IBM850"}, + {850, "CSPC850MULTILINGUAL"}, + + /* !IsValidCodePage(862) */ + {862, "862"}, + {862, "CP862"}, + {862, "IBM862"}, + {862, "CSPC862LATINHEBREW"}, + + {866, "866"}, + {866, "CP866"}, + {866, "IBM866"}, + {866, "CSIBM866"}, + + /* !IsValidCodePage(154) */ + {154, "CP154"}, + {154, "CYRILLIC-ASIAN"}, + {154, "PT154"}, + {154, "PTCP154"}, + {154, "CSPTCP154"}, + + /* !IsValidCodePage(1133) */ + {1133, "CP1133"}, + {1133, "IBM-CP1133"}, + + {874, "CP874"}, + {874, "WINDOWS-874"}, + + /* !IsValidCodePage(51932) */ + {51932, "CP51932"}, + {51932, "MS51932"}, + {51932, "WINDOWS-51932"}, + {51932, "EUC-JP"}, + + {932, "CP932"}, + {932, "MS932"}, + {932, "SHIFFT_JIS"}, + {932, "SHIFFT_JIS-MS"}, + {932, "SJIS"}, + {932, "SJIS-MS"}, + {932, "SJIS-OPEN"}, + {932, "SJIS-WIN"}, + {932, "WINDOWS-31J"}, + {932, "WINDOWS-932"}, + {932, "CSWINDOWS31J"}, + + {50221, "CP50221"}, + {50221, "ISO-2022-JP"}, + {50221, "ISO-2022-JP-MS"}, + {50221, "ISO2022-JP"}, + {50221, "ISO2022-JP-MS"}, + {50221, "MS50221"}, + {50221, "WINDOWS-50221"}, + + {936, "CP936"}, + {936, "GBK"}, + {936, "MS936"}, + {936, "WINDOWS-936"}, + + {950, "CP950"}, + {950, "BIG5"}, + {950, "BIG5HKSCS"}, + {950, "BIG5-HKSCS"}, + + {949, "CP949"}, + {949, "UHC"}, + {949, "EUC-KR"}, + + {1361, "CP1361"}, + {1361, "JOHAB"}, + + {437, "437"}, + {437, "CP437"}, + {437, "IBM437"}, + {437, "CSPC8CODEPAGE437"}, + + {737, "CP737"}, + + {775, "CP775"}, + {775, "IBM775"}, + {775, "CSPC775BALTIC"}, + + {852, "852"}, + {852, "CP852"}, + {852, "IBM852"}, + {852, "CSPCP852"}, + + /* !IsValidCodePage(853) */ + {853, "CP853"}, + + {855, "855"}, + {855, "CP855"}, + {855, "IBM855"}, + {855, "CSIBM855"}, + + {857, "857"}, + {857, "CP857"}, + {857, "IBM857"}, + {857, "CSIBM857"}, + + /* !IsValidCodePage(858) */ + {858, "CP858"}, + + {860, "860"}, + {860, "CP860"}, + {860, "IBM860"}, + {860, "CSIBM860"}, + + {861, "861"}, + {861, "CP-IS"}, + {861, "CP861"}, + {861, "IBM861"}, + {861, "CSIBM861"}, + + {863, "863"}, + {863, "CP863"}, + {863, "IBM863"}, + {863, "CSIBM863"}, + + {864, "CP864"}, + {864, "IBM864"}, + {864, "CSIBM864"}, + + {865, "865"}, + {865, "CP865"}, + {865, "IBM865"}, + {865, "CSIBM865"}, + + {869, "869"}, + {869, "CP-GR"}, + {869, "CP869"}, + {869, "IBM869"}, + {869, "CSIBM869"}, + + /* !IsValidCodePage(1152) */ + {1125, "CP1125"}, + + /* + * Code Page Identifiers + * http://msdn2.microsoft.com/en-us/library/ms776446.aspx + */ + {37, "IBM037"}, /* IBM EBCDIC US-Canada */ + {437, "IBM437"}, /* OEM United States */ + {500, "IBM500"}, /* IBM EBCDIC International */ + {708, "ASMO-708"}, /* Arabic (ASMO 708) */ + /* 709 Arabic (ASMO-449+, BCON V4) */ + /* 710 Arabic - Transparent Arabic */ + {720, "DOS-720"}, /* Arabic (Transparent ASMO); Arabic (DOS) */ + {737, "ibm737"}, /* OEM Greek (formerly 437G); Greek (DOS) */ + {775, "ibm775"}, /* OEM Baltic; Baltic (DOS) */ + {850, "ibm850"}, /* OEM Multilingual Latin 1; Western European (DOS) */ + {852, "ibm852"}, /* OEM Latin 2; Central European (DOS) */ + {855, "IBM855"}, /* OEM Cyrillic (primarily Russian) */ + {857, "ibm857"}, /* OEM Turkish; Turkish (DOS) */ + {858, "IBM00858"}, /* OEM Multilingual Latin 1 + Euro symbol */ + {860, "IBM860"}, /* OEM Portuguese; Portuguese (DOS) */ + {861, "ibm861"}, /* OEM Icelandic; Icelandic (DOS) */ + {862, "DOS-862"}, /* OEM Hebrew; Hebrew (DOS) */ + {863, "IBM863"}, /* OEM French Canadian; French Canadian (DOS) */ + {864, "IBM864"}, /* OEM Arabic; Arabic (864) */ + {865, "IBM865"}, /* OEM Nordic; Nordic (DOS) */ + {866, "cp866"}, /* OEM Russian; Cyrillic (DOS) */ + {869, "ibm869"}, /* OEM Modern Greek; Greek, Modern (DOS) */ + {870, "IBM870"}, /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */ + {874, "windows-874"}, /* ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows) */ + {875, "cp875"}, /* IBM EBCDIC Greek Modern */ + {932, "shift_jis"}, /* ANSI/OEM Japanese; Japanese (Shift-JIS) */ + {932, "shift-jis"}, /* alternative name for it */ + {936, "gb2312"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */ + {949, "ks_c_5601-1987"}, /* ANSI/OEM Korean (Unified Hangul Code) */ + {950, "big5"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */ + {950, "big5hkscs"}, /* ANSI/OEM Traditional Chinese (Hong Kong SAR); Chinese Traditional (Big5-HKSCS) */ + {950, "big5-hkscs"}, /* alternative name for it */ + {1026, "IBM1026"}, /* IBM EBCDIC Turkish (Latin 5) */ + {1047, "IBM01047"}, /* IBM EBCDIC Latin 1/Open System */ + {1140, "IBM01140"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */ + {1141, "IBM01141"}, /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */ + {1142, "IBM01142"}, /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */ + {1143, "IBM01143"}, /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */ + {1144, "IBM01144"}, /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */ + {1145, "IBM01145"}, /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */ + {1146, "IBM01146"}, /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */ + {1147, "IBM01147"}, /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */ + {1148, "IBM01148"}, /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */ + {1149, "IBM01149"}, /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */ + {1250, "windows-1250"}, /* ANSI Central European; Central European (Windows) */ + {1251, "windows-1251"}, /* ANSI Cyrillic; Cyrillic (Windows) */ + {1252, "windows-1252"}, /* ANSI Latin 1; Western European (Windows) */ + {1253, "windows-1253"}, /* ANSI Greek; Greek (Windows) */ + {1254, "windows-1254"}, /* ANSI Turkish; Turkish (Windows) */ + {1255, "windows-1255"}, /* ANSI Hebrew; Hebrew (Windows) */ + {1256, "windows-1256"}, /* ANSI Arabic; Arabic (Windows) */ + {1257, "windows-1257"}, /* ANSI Baltic; Baltic (Windows) */ + {1258, "windows-1258"}, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */ + {1361, "Johab"}, /* Korean (Johab) */ + {10000, "macintosh"}, /* MAC Roman; Western European (Mac) */ + {10001, "x-mac-japanese"}, /* Japanese (Mac) */ + {10002, "x-mac-chinesetrad"}, /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */ + {10003, "x-mac-korean"}, /* Korean (Mac) */ + {10004, "x-mac-arabic"}, /* Arabic (Mac) */ + {10005, "x-mac-hebrew"}, /* Hebrew (Mac) */ + {10006, "x-mac-greek"}, /* Greek (Mac) */ + {10007, "x-mac-cyrillic"}, /* Cyrillic (Mac) */ + {10008, "x-mac-chinesesimp"}, /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */ + {10010, "x-mac-romanian"}, /* Romanian (Mac) */ + {10017, "x-mac-ukrainian"}, /* Ukrainian (Mac) */ + {10021, "x-mac-thai"}, /* Thai (Mac) */ + {10029, "x-mac-ce"}, /* MAC Latin 2; Central European (Mac) */ + {10079, "x-mac-icelandic"}, /* Icelandic (Mac) */ + {10081, "x-mac-turkish"}, /* Turkish (Mac) */ + {10082, "x-mac-croatian"}, /* Croatian (Mac) */ + {20000, "x-Chinese_CNS"}, /* CNS Taiwan; Chinese Traditional (CNS) */ + {20001, "x-cp20001"}, /* TCA Taiwan */ + {20002, "x_Chinese-Eten"}, /* Eten Taiwan; Chinese Traditional (Eten) */ + {20003, "x-cp20003"}, /* IBM5550 Taiwan */ + {20004, "x-cp20004"}, /* TeleText Taiwan */ + {20005, "x-cp20005"}, /* Wang Taiwan */ + {20105, "x-IA5"}, /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */ + {20106, "x-IA5-German"}, /* IA5 German (7-bit) */ + {20107, "x-IA5-Swedish"}, /* IA5 Swedish (7-bit) */ + {20108, "x-IA5-Norwegian"}, /* IA5 Norwegian (7-bit) */ + {20127, "us-ascii"}, /* US-ASCII (7-bit) */ + {20261, "x-cp20261"}, /* T.61 */ + {20269, "x-cp20269"}, /* ISO 6937 Non-Spacing Accent */ + {20273, "IBM273"}, /* IBM EBCDIC Germany */ + {20277, "IBM277"}, /* IBM EBCDIC Denmark-Norway */ + {20278, "IBM278"}, /* IBM EBCDIC Finland-Sweden */ + {20280, "IBM280"}, /* IBM EBCDIC Italy */ + {20284, "IBM284"}, /* IBM EBCDIC Latin America-Spain */ + {20285, "IBM285"}, /* IBM EBCDIC United Kingdom */ + {20290, "IBM290"}, /* IBM EBCDIC Japanese Katakana Extended */ + {20297, "IBM297"}, /* IBM EBCDIC France */ + {20420, "IBM420"}, /* IBM EBCDIC Arabic */ + {20423, "IBM423"}, /* IBM EBCDIC Greek */ + {20424, "IBM424"}, /* IBM EBCDIC Hebrew */ + {20833, "x-EBCDIC-KoreanExtended"}, /* IBM EBCDIC Korean Extended */ + {20838, "IBM-Thai"}, /* IBM EBCDIC Thai */ + {20866, "koi8-r"}, /* Russian (KOI8-R); Cyrillic (KOI8-R) */ + {20871, "IBM871"}, /* IBM EBCDIC Icelandic */ + {20880, "IBM880"}, /* IBM EBCDIC Cyrillic Russian */ + {20905, "IBM905"}, /* IBM EBCDIC Turkish */ + {20924, "IBM00924"}, /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */ + {20932, "EUC-JP"}, /* Japanese (JIS 0208-1990 and 0121-1990) */ + {20936, "x-cp20936"}, /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */ + {20949, "x-cp20949"}, /* Korean Wansung */ + {21025, "cp1025"}, /* IBM EBCDIC Cyrillic Serbian-Bulgarian */ + /* 21027 (deprecated) */ + {21866, "koi8-u"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */ + {28591, "iso-8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */ + {28591, "iso8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */ + {28591, "iso_8859-1"}, + {28591, "iso_8859_1"}, + {28592, "iso-8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */ + {28592, "iso8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */ + {28592, "iso_8859-2"}, + {28592, "iso_8859_2"}, + {28593, "iso-8859-3"}, /* ISO 8859-3 Latin 3 */ + {28593, "iso8859-3"}, /* ISO 8859-3 Latin 3 */ + {28593, "iso_8859-3"}, + {28593, "iso_8859_3"}, + {28594, "iso-8859-4"}, /* ISO 8859-4 Baltic */ + {28594, "iso8859-4"}, /* ISO 8859-4 Baltic */ + {28594, "iso_8859-4"}, + {28594, "iso_8859_4"}, + {28595, "iso-8859-5"}, /* ISO 8859-5 Cyrillic */ + {28595, "iso8859-5"}, /* ISO 8859-5 Cyrillic */ + {28595, "iso_8859-5"}, + {28595, "iso_8859_5"}, + {28596, "iso-8859-6"}, /* ISO 8859-6 Arabic */ + {28596, "iso8859-6"}, /* ISO 8859-6 Arabic */ + {28596, "iso_8859-6"}, + {28596, "iso_8859_6"}, + {28597, "iso-8859-7"}, /* ISO 8859-7 Greek */ + {28597, "iso8859-7"}, /* ISO 8859-7 Greek */ + {28597, "iso_8859-7"}, + {28597, "iso_8859_7"}, + {28598, "iso-8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */ + {28598, "iso8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */ + {28598, "iso_8859-8"}, + {28598, "iso_8859_8"}, + {28599, "iso-8859-9"}, /* ISO 8859-9 Turkish */ + {28599, "iso8859-9"}, /* ISO 8859-9 Turkish */ + {28599, "iso_8859-9"}, + {28599, "iso_8859_9"}, + {28603, "iso-8859-13"}, /* ISO 8859-13 Estonian */ + {28603, "iso8859-13"}, /* ISO 8859-13 Estonian */ + {28603, "iso_8859-13"}, + {28603, "iso_8859_13"}, + {28605, "iso-8859-15"}, /* ISO 8859-15 Latin 9 */ + {28605, "iso8859-15"}, /* ISO 8859-15 Latin 9 */ + {28605, "iso_8859-15"}, + {28605, "iso_8859_15"}, + {29001, "x-Europa"}, /* Europa 3 */ + {38598, "iso-8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */ + {38598, "iso8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */ + {38598, "iso_8859-8-i"}, + {38598, "iso_8859_8-i"}, + {50220, "iso-2022-jp"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */ + {50221, "csISO2022JP"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */ + {50222, "iso-2022-jp"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */ + {50225, "iso-2022-kr"}, /* ISO 2022 Korean */ + {50225, "iso2022-kr"}, /* ISO 2022 Korean */ + {50227, "x-cp50227"}, /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */ + /* 50229 ISO 2022 Traditional Chinese */ + /* 50930 EBCDIC Japanese (Katakana) Extended */ + /* 50931 EBCDIC US-Canada and Japanese */ + /* 50933 EBCDIC Korean Extended and Korean */ + /* 50935 EBCDIC Simplified Chinese Extended and Simplified Chinese */ + /* 50936 EBCDIC Simplified Chinese */ + /* 50937 EBCDIC US-Canada and Traditional Chinese */ + /* 50939 EBCDIC Japanese (Latin) Extended and Japanese */ + {51932, "euc-jp"}, /* EUC Japanese */ + {51936, "EUC-CN"}, /* EUC Simplified Chinese; Chinese Simplified (EUC) */ + {51949, "euc-kr"}, /* EUC Korean */ + /* 51950 EUC Traditional Chinese */ + {52936, "hz-gb-2312"}, /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */ + {54936, "GB18030"}, /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */ + {57002, "x-iscii-de"}, /* ISCII Devanagari */ + {57003, "x-iscii-be"}, /* ISCII Bengali */ + {57004, "x-iscii-ta"}, /* ISCII Tamil */ + {57005, "x-iscii-te"}, /* ISCII Telugu */ + {57006, "x-iscii-as"}, /* ISCII Assamese */ + {57007, "x-iscii-or"}, /* ISCII Oriya */ + {57008, "x-iscii-ka"}, /* ISCII Kannada */ + {57009, "x-iscii-ma"}, /* ISCII Malayalam */ + {57010, "x-iscii-gu"}, /* ISCII Gujarati */ + {57011, "x-iscii-pa"}, /* ISCII Punjabi */ + + {0, NULL} +}; + +/* + * SJIS SHIFTJIS table CP932 table + * ---- --------------------------- -------------------------------- + * 5C U+00A5 YEN SIGN U+005C REVERSE SOLIDUS + * 7E U+203E OVERLINE U+007E TILDE + * 815C U+2014 EM DASH U+2015 HORIZONTAL BAR + * 815F U+005C REVERSE SOLIDUS U+FF3C FULLWIDTH REVERSE SOLIDUS + * 8160 U+301C WAVE DASH U+FF5E FULLWIDTH TILDE + * 8161 U+2016 DOUBLE VERTICAL LINE U+2225 PARALLEL TO + * 817C U+2212 MINUS SIGN U+FF0D FULLWIDTH HYPHEN-MINUS + * 8191 U+00A2 CENT SIGN U+FFE0 FULLWIDTH CENT SIGN + * 8192 U+00A3 POUND SIGN U+FFE1 FULLWIDTH POUND SIGN + * 81CA U+00AC NOT SIGN U+FFE2 FULLWIDTH NOT SIGN + * + * EUC-JP and ISO-2022-JP should be compatible with CP932. + * + * Kernel and MLang have different Unicode mapping table. Make sure + * which API is used. + */ +static compat_t cp932_compat[] = { + {0x00A5, 0x005C, COMPAT_OUT}, + {0x203E, 0x007E, COMPAT_OUT}, + {0x2014, 0x2015, COMPAT_OUT}, + {0x301C, 0xFF5E, COMPAT_OUT}, + {0x2016, 0x2225, COMPAT_OUT}, + {0x2212, 0xFF0D, COMPAT_OUT}, + {0x00A2, 0xFFE0, COMPAT_OUT}, + {0x00A3, 0xFFE1, COMPAT_OUT}, + {0x00AC, 0xFFE2, COMPAT_OUT}, + {0, 0, 0} +}; + +static compat_t cp20932_compat[] = { + {0x00A5, 0x005C, COMPAT_OUT}, + {0x203E, 0x007E, COMPAT_OUT}, + {0x2014, 0x2015, COMPAT_OUT}, + {0xFF5E, 0x301C, COMPAT_OUT|COMPAT_IN}, + {0x2225, 0x2016, COMPAT_OUT|COMPAT_IN}, + {0xFF0D, 0x2212, COMPAT_OUT|COMPAT_IN}, + {0xFFE0, 0x00A2, COMPAT_OUT|COMPAT_IN}, + {0xFFE1, 0x00A3, COMPAT_OUT|COMPAT_IN}, + {0xFFE2, 0x00AC, COMPAT_OUT|COMPAT_IN}, + {0, 0, 0} +}; + +static compat_t *cp51932_compat = cp932_compat; + +/* cp20932_compat for kernel. cp932_compat for mlang. */ +static compat_t *cp5022x_compat = cp932_compat; + +typedef HRESULT (WINAPI *CONVERTINETSTRING)( + LPDWORD lpdwMode, + DWORD dwSrcEncoding, + DWORD dwDstEncoding, + LPCSTR lpSrcStr, + LPINT lpnSrcSize, + LPBYTE lpDstStr, + LPINT lpnDstSize +); +typedef HRESULT (WINAPI *CONVERTINETMULTIBYTETOUNICODE)( + LPDWORD lpdwMode, + DWORD dwSrcEncoding, + LPCSTR lpSrcStr, + LPINT lpnMultiCharCount, + LPWSTR lpDstStr, + LPINT lpnWideCharCount +); +typedef HRESULT (WINAPI *CONVERTINETUNICODETOMULTIBYTE)( + LPDWORD lpdwMode, + DWORD dwEncoding, + LPCWSTR lpSrcStr, + LPINT lpnWideCharCount, + LPSTR lpDstStr, + LPINT lpnMultiCharCount +); +typedef HRESULT (WINAPI *ISCONVERTINETSTRINGAVAILABLE)( + DWORD dwSrcEncoding, + DWORD dwDstEncoding +); +typedef HRESULT (WINAPI *LCIDTORFC1766A)( + LCID Locale, + LPSTR pszRfc1766, + int nChar +); +typedef HRESULT (WINAPI *LCIDTORFC1766W)( + LCID Locale, + LPWSTR pszRfc1766, + int nChar +); +typedef HRESULT (WINAPI *RFC1766TOLCIDA)( + LCID *pLocale, + LPSTR pszRfc1766 +); +typedef HRESULT (WINAPI *RFC1766TOLCIDW)( + LCID *pLocale, + LPWSTR pszRfc1766 +); +static CONVERTINETSTRING ConvertINetString; +static CONVERTINETMULTIBYTETOUNICODE ConvertINetMultiByteToUnicode; +static CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte; +static ISCONVERTINETSTRINGAVAILABLE IsConvertINetStringAvailable; +static LCIDTORFC1766A LcidToRfc1766A; +static RFC1766TOLCIDA Rfc1766ToLcidA; + +static int +load_mlang(void) +{ + HMODULE h; + if (ConvertINetString != NULL) + return TRUE; + h = LoadLibrary(TEXT("mlang.dll")); + if (!h) + return FALSE; + ConvertINetString = (CONVERTINETSTRING)GetProcAddressA(h, "ConvertINetString"); + ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddressA(h, "ConvertINetMultiByteToUnicode"); + ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddressA(h, "ConvertINetUnicodeToMultiByte"); + IsConvertINetStringAvailable = (ISCONVERTINETSTRINGAVAILABLE)GetProcAddressA(h, "IsConvertINetStringAvailable"); + LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddressA(h, "LcidToRfc1766A"); + Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddressA(h, "Rfc1766ToLcidA"); + return TRUE; +} + +iconv_t +iconv_open(const char *tocode, const char *fromcode) +{ + rec_iconv_t *cd; + + cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t)); + if (cd == NULL) + return (iconv_t)(-1); + +#if defined(USE_LIBICONV_DLL) + errno = 0; + if (libiconv_iconv_open(cd, tocode, fromcode)) + return (iconv_t)cd; +#endif + + /* reset the errno to prevent reporting wrong error code. + * 0 for unsorted error. */ + errno = 0; + if (win_iconv_open(cd, tocode, fromcode)) + return (iconv_t)cd; + + free(cd); + + return (iconv_t)(-1); +} + +int +iconv_close(iconv_t _cd) +{ + rec_iconv_t *cd = (rec_iconv_t *)_cd; + int r = cd->iconv_close(cd->cd); + int e = *(cd->_errno()); +#if defined(USE_LIBICONV_DLL) + if (cd->hlibiconv != NULL) + FreeLibrary(cd->hlibiconv); +#endif + free(cd); + errno = e; + return r; +} + +size_t +iconv(iconv_t _cd, /* const */ char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) +{ + rec_iconv_t *cd = (rec_iconv_t *)_cd; + size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft); + errno = *(cd->_errno()); + return r; +} + +static int +win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode) +{ + if (!make_csconv(fromcode, &cd->from) || !make_csconv(tocode, &cd->to)) + return FALSE; + cd->iconv_close = win_iconv_close; + cd->iconv = win_iconv; + cd->_errno = _errno; + cd->cd = (iconv_t)cd; + return TRUE; +} + +static int +win_iconv_close(iconv_t cd UNUSED) +{ + return 0; +} + +static size_t +win_iconv(iconv_t _cd, /* const */ char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) +{ + rec_iconv_t *cd = (rec_iconv_t *)_cd; + ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */ + int insize; + int outsize; + int wsize; + DWORD frommode; + DWORD tomode; + uint wc; + compat_t *cp; + int i; + + if (inbuf == NULL || *inbuf == NULL) + { + if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL) + { + tomode = cd->to.mode; + outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft); + if (outsize == -1) + { + if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG) + { + outsize = 0; + } + else + { + cd->to.mode = tomode; + return (size_t)(-1); + } + } + *outbuf += outsize; + *outbytesleft -= outsize; + } + cd->from.mode = 0; + cd->to.mode = 0; + return 0; + } + + while (*inbytesleft != 0) + { + frommode = cd->from.mode; + tomode = cd->to.mode; + wsize = MB_CHAR_MAX; + + insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize); + if (insize == -1) + { + if (cd->to.flags & FLAG_IGNORE) + { + cd->from.mode = frommode; + insize = 1; + wsize = 0; + } + else + { + cd->from.mode = frommode; + return (size_t)(-1); + } + } + + if (wsize == 0) + { + *inbuf += insize; + *inbytesleft -= insize; + continue; + } + + if (cd->from.compat != NULL) + { + wc = utf16_to_ucs4(wbuf); + cp = cd->from.compat; + for (i = 0; cp[i].in != 0; ++i) + { + if ((cp[i].flag & COMPAT_IN) && cp[i].out == wc) + { + ucs4_to_utf16(cp[i].in, wbuf, &wsize); + break; + } + } + } + + if (cd->to.compat != NULL) + { + wc = utf16_to_ucs4(wbuf); + cp = cd->to.compat; + for (i = 0; cp[i].in != 0; ++i) + { + if ((cp[i].flag & COMPAT_OUT) && cp[i].in == wc) + { + ucs4_to_utf16(cp[i].out, wbuf, &wsize); + break; + } + } + } + + outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft); + if (outsize == -1) + { + if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG) + { + cd->to.mode = tomode; + outsize = 0; + } + else + { + cd->from.mode = frommode; + cd->to.mode = tomode; + return (size_t)(-1); + } + } + + *inbuf += insize; + *outbuf += outsize; + *inbytesleft -= insize; + *outbytesleft -= outsize; + } + + return 0; +} + +static int +make_csconv(const char *_name, csconv_t *cv) +{ + CPINFO cpinfo; + int use_compat = TRUE; + int flag = 0; + char *name; + char *p; + + name = xstrndup(_name, strlen(_name)); + if (name == NULL) + return FALSE; + + /* check for option "enc_name//opt1//opt2" */ + while ((p = strrstr(name, "//")) != NULL) + { + if (_stricmp(p + 2, "nocompat") == 0) + use_compat = FALSE; + else if (_stricmp(p + 2, "translit") == 0) + flag |= FLAG_TRANSLIT; + else if (_stricmp(p + 2, "ignore") == 0) + flag |= FLAG_IGNORE; + *p = 0; + } + + cv->mode = 0; + cv->flags = flag; + cv->mblen = NULL; + cv->flush = NULL; + cv->compat = NULL; + cv->codepage = name_to_codepage(name); + if (cv->codepage == 1200 || cv->codepage == 1201) + { + cv->mbtowc = utf16_mbtowc; + cv->wctomb = utf16_wctomb; + if (_stricmp(name, "UTF-16") == 0 || _stricmp(name, "UTF16") == 0 || + _stricmp(name, "UCS-2") == 0 || _stricmp(name, "UCS2") == 0) + cv->flags |= FLAG_USE_BOM; + } + else if (cv->codepage == 12000 || cv->codepage == 12001) + { + cv->mbtowc = utf32_mbtowc; + cv->wctomb = utf32_wctomb; + if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0 || + _stricmp(name, "UCS-4") == 0 || _stricmp(name, "UCS4") == 0) + cv->flags |= FLAG_USE_BOM; + } + else if (cv->codepage == 65001) + { + cv->mbtowc = kernel_mbtowc; + cv->wctomb = kernel_wctomb; + cv->mblen = utf8_mblen; + } + else if ((cv->codepage == 50220 || cv->codepage == 50221 || cv->codepage == 50222) && load_mlang()) + { + cv->mbtowc = iso2022jp_mbtowc; + cv->wctomb = iso2022jp_wctomb; + cv->flush = iso2022jp_flush; + } + else if (cv->codepage == 51932 && load_mlang()) + { + cv->mbtowc = mlang_mbtowc; + cv->wctomb = mlang_wctomb; + cv->mblen = eucjp_mblen; + } + else if (IsValidCodePage(cv->codepage) + && GetCPInfo(cv->codepage, &cpinfo) != 0) + { + cv->mbtowc = kernel_mbtowc; + cv->wctomb = kernel_wctomb; + if (cpinfo.MaxCharSize == 1) + cv->mblen = sbcs_mblen; + else if (cpinfo.MaxCharSize == 2) + cv->mblen = dbcs_mblen; + else + cv->mblen = mbcs_mblen; + } + else + { + /* not supported */ + free(name); + errno = EINVAL; + return FALSE; + } + + if (use_compat) + { + switch (cv->codepage) + { + case 932: cv->compat = cp932_compat; break; + case 20932: cv->compat = cp20932_compat; break; + case 51932: cv->compat = cp51932_compat; break; + case 50220: case 50221: case 50222: cv->compat = cp5022x_compat; break; + } + } + + free(name); + + return TRUE; +} + +static int +name_to_codepage(const char *name) +{ + int i; + + if (*name == '\0' || + strcmp(name, "char") == 0) + return GetACP(); + else if (strcmp(name, "wchar_t") == 0) + return 1200; + else if (_strnicmp(name, "cp", 2) == 0) + return atoi(name + 2); /* CP123 */ + else if ('0' <= name[0] && name[0] <= '9') + return atoi(name); /* 123 */ + else if (_strnicmp(name, "xx", 2) == 0) + return atoi(name + 2); /* XX123 for debug */ + + for (i = 0; codepage_alias[i].name != NULL; ++i) + if (_stricmp(name, codepage_alias[i].name) == 0) + return codepage_alias[i].codepage; + return -1; +} + +/* + * http://www.faqs.org/rfcs/rfc2781.html + */ +static uint +utf16_to_ucs4(const ushort *wbuf) +{ + uint wc = wbuf[0]; + if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) + wc = ((wbuf[0] & 0x3FF) << 10) + (wbuf[1] & 0x3FF) + 0x10000; + return wc; +} + +static void +ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize) +{ + if (wc < 0x10000) + { + wbuf[0] = wc; + *wbufsize = 1; + } + else + { + wc -= 0x10000; + wbuf[0] = 0xD800 | ((wc >> 10) & 0x3FF); + wbuf[1] = 0xDC00 | (wc & 0x3FF); + *wbufsize = 2; + } +} + +/* + * Check if codepage is one of those for which the dwFlags parameter + * to MultiByteToWideChar() must be zero. Return zero or + * MB_ERR_INVALID_CHARS. The docs in Platform SDK for for Windows + * Server 2003 R2 claims that also codepage 65001 is one of these, but + * that doesn't seem to be the case. The MSDN docs for MSVS2008 leave + * out 65001 (UTF-8), and that indeed seems to be the case on XP, it + * works fine to pass MB_ERR_INVALID_CHARS in dwFlags when converting + * from UTF-8. + */ +static int +mbtowc_flags(int codepage) +{ + return (codepage == 50220 || codepage == 50221 || + codepage == 50222 || codepage == 50225 || + codepage == 50227 || codepage == 50229 || + codepage == 52936 || codepage == 54936 || + (codepage >= 57002 && codepage <= 57011) || + codepage == 65000 || codepage == 42) ? 0 : MB_ERR_INVALID_CHARS; +} + +/* + * Check if codepage is one those for which the lpUsedDefaultChar + * parameter to WideCharToMultiByte() must be NULL. The docs in + * Platform SDK for Windows Server 2003 R2 claims that this is the + * list below, while the MSDN docs for MSVS2008 claim that it is only + * for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform + * SDK seems to be correct, at least for XP. + */ +static int +must_use_null_useddefaultchar(int codepage) +{ + return (codepage == 65000 || codepage == 65001 || + codepage == 50220 || codepage == 50221 || + codepage == 50222 || codepage == 50225 || + codepage == 50227 || codepage == 50229 || + codepage == 52936 || codepage == 54936 || + (codepage >= 57002 && codepage <= 57011) || + codepage == 42); +} + +static char * +strrstr(const char *str, const char *token) +{ + int len = strlen(token); + const char *p = str + strlen(str); + + while (str <= --p) + if (p[0] == token[0] && strncmp(p, token, len) == 0) + return (char *)p; + return NULL; +} + +static char * +xstrndup(const char *s, size_t n) +{ + char *p; + + p = (char *)malloc(n + 1); + if (p == NULL) + return NULL; + memcpy(p, s, n); + p[n] = '\0'; + return p; +} + +static int +seterror(int err) +{ + errno = err; + return -1; +} + +#if defined(USE_LIBICONV_DLL) +static int +libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode) +{ + HMODULE hlibiconv = NULL; + char *dllname; + const char *p; + const char *e; + f_iconv_open _iconv_open; + + /* + * always try to load dll, so that we can switch dll in runtime. + */ + + /* XXX: getenv() can't get variable set by SetEnvironmentVariable() */ + p = getenv("WINICONV_LIBICONV_DLL"); + if (p == NULL) + p = DEFAULT_LIBICONV_DLL; + /* parse comma separated value */ + for ( ; *p != 0; p = (*e == ',') ? e + 1 : e) + { + e = strchr(p, ','); + if (p == e) + continue; + else if (e == NULL) + e = p + strlen(p); + dllname = xstrndup(p, e - p); + if (dllname == NULL) + return FALSE; + hlibiconv = LoadLibraryA(dllname); + free(dllname); + if (hlibiconv != NULL) + { + if (hlibiconv == hwiniconv) + { + FreeLibrary(hlibiconv); + hlibiconv = NULL; + continue; + } + break; + } + } + + if (hlibiconv == NULL) + goto failed; + + _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, "libiconv_open"); + if (_iconv_open == NULL) + _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, "iconv_open"); + cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, "libiconv_close"); + if (cd->iconv_close == NULL) + cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, "iconv_close"); + cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, "libiconv"); + if (cd->iconv == NULL) + cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, "iconv"); + cd->_errno = (f_errno)find_imported_function(hlibiconv, "_errno"); + if (_iconv_open == NULL || cd->iconv_close == NULL + || cd->iconv == NULL || cd->_errno == NULL) + goto failed; + + cd->cd = _iconv_open(tocode, fromcode); + if (cd->cd == (iconv_t)(-1)) + goto failed; + + cd->hlibiconv = hlibiconv; + return TRUE; + +failed: + if (hlibiconv != NULL) + FreeLibrary(hlibiconv); + return FALSE; +} + +/* + * Reference: + * http://forums.belution.com/ja/vc/000/234/78s.shtml + * http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html + * + * The formal way is + * imagehlp.h or dbghelp.h + * imagehlp.lib or dbghelp.lib + * ImageDirectoryEntryToData() + */ +#define TO_DOS_HEADER(base) ((PIMAGE_DOS_HEADER)(base)) +#define TO_NT_HEADERS(base) ((PIMAGE_NT_HEADERS)((LPBYTE)(base) + TO_DOS_HEADER(base)->e_lfanew)) +static PVOID +MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size) +{ + /* TODO: MappedAsImage? */ + PIMAGE_DATA_DIRECTORY p; + p = TO_NT_HEADERS(Base)->OptionalHeader.DataDirectory + DirectoryEntry; + if (p->VirtualAddress == 0) { + *Size = 0; + return NULL; + } + *Size = p->Size; + return (PVOID)((LPBYTE)Base + p->VirtualAddress); +} + +static FARPROC +find_imported_function(HMODULE hModule, const char *funcname) +{ + DWORD_PTR Base; + ULONG Size; + PIMAGE_IMPORT_DESCRIPTOR Imp; + PIMAGE_THUNK_DATA Address; /* Import Address Table */ + PIMAGE_THUNK_DATA Name; /* Import Name Table */ + PIMAGE_IMPORT_BY_NAME ImpName; + + Base = (DWORD_PTR)hModule; + Imp = (PIMAGE_IMPORT_DESCRIPTOR)MyImageDirectoryEntryToData( + (LPVOID)Base, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + if (Imp == NULL) + return NULL; + for ( ; Imp->OriginalFirstThunk != 0; ++Imp) + { + Address = (PIMAGE_THUNK_DATA)(Base + Imp->FirstThunk); + Name = (PIMAGE_THUNK_DATA)(Base + Imp->OriginalFirstThunk); + for ( ; Name->u1.Ordinal != 0; ++Name, ++Address) + { + if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal)) + { + ImpName = (PIMAGE_IMPORT_BY_NAME) + (Base + (DWORD_PTR)Name->u1.AddressOfData); + if (strcmp((char *)ImpName->Name, funcname) == 0) + return (FARPROC)Address->u1.Function; + } + } + } + return NULL; +} +#endif + +static int +sbcs_mblen(csconv_t *cv UNUSED, const uchar *buf UNUSED, int bufsize UNUSED) +{ + return 1; +} + +static int +dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) +{ + int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1; + if (bufsize < len) + return seterror(EINVAL); + return len; +} + +static int +mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) +{ + int len = 0; + + if (cv->codepage == 54936) { + if (buf[0] <= 0x7F) len = 1; + else if (buf[0] >= 0x81 && buf[0] <= 0xFE && + bufsize >= 2 && + ((buf[1] >= 0x40 && buf[1] <= 0x7E) || + (buf[1] >= 0x80 && buf[1] <= 0xFE))) len = 2; + else if (buf[0] >= 0x81 && buf[0] <= 0xFE && + bufsize >= 4 && + buf[1] >= 0x30 && buf[1] <= 0x39) len = 4; + else + return seterror(EINVAL); + return len; + } + else + return seterror(EINVAL); +} + +static int +utf8_mblen(csconv_t *cv UNUSED, const uchar *buf, int bufsize) +{ + int len = 0; + + if (buf[0] < 0x80) len = 1; + else if ((buf[0] & 0xE0) == 0xC0) len = 2; + else if ((buf[0] & 0xF0) == 0xE0) len = 3; + else if ((buf[0] & 0xF8) == 0xF0) len = 4; + else if ((buf[0] & 0xFC) == 0xF8) len = 5; + else if ((buf[0] & 0xFE) == 0xFC) len = 6; + + if (len == 0) + return seterror(EILSEQ); + else if (bufsize < len) + return seterror(EINVAL); + return len; +} + +static int +eucjp_mblen(csconv_t *cv UNUSED, const uchar *buf, int bufsize) +{ + if (buf[0] < 0x80) /* ASCII */ + return 1; + else if (buf[0] == 0x8E) /* JIS X 0201 */ + { + if (bufsize < 2) + return seterror(EINVAL); + else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF)) + return seterror(EILSEQ); + return 2; + } + else if (buf[0] == 0x8F) /* JIS X 0212 */ + { + if (bufsize < 3) + return seterror(EINVAL); + else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE) + || !(0xA1 <= buf[2] && buf[2] <= 0xFE)) + return seterror(EILSEQ); + return 3; + } + else /* JIS X 0208 */ + { + if (bufsize < 2) + return seterror(EINVAL); + else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE) + || !(0xA1 <= buf[1] && buf[1] <= 0xFE)) + return seterror(EILSEQ); + return 2; + } +} + +static int +kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + int len; + + len = cv->mblen(cv, buf, bufsize); + if (len == -1) + return -1; + /* If converting from ASCII, reject 8bit + * chars. MultiByteToWideChar() doesn't. Note that for ASCII we + * know that the mblen function is sbcs_mblen() so len is 1. + */ + if (cv->codepage == 20127 && buf[0] >= 0x80) + return seterror(EILSEQ); + *wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage), + (const char *)buf, len, (wchar_t *)wbuf, *wbufsize); + if (*wbufsize == 0) + return seterror(EILSEQ); + return len; +} + +static int +kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + BOOL usedDefaultChar = 0; + BOOL *p = NULL; + int flags = 0; + int len; + + if (bufsize == 0) + return seterror(E2BIG); + if (!must_use_null_useddefaultchar(cv->codepage)) + { + p = &usedDefaultChar; +#ifdef WC_NO_BEST_FIT_CHARS + if (!(cv->flags & FLAG_TRANSLIT)) + flags |= WC_NO_BEST_FIT_CHARS; +#endif + } + len = WideCharToMultiByte(cv->codepage, flags, + (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p); + if (len == 0) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + return seterror(E2BIG); + return seterror(EILSEQ); + } + else if (usedDefaultChar && !(cv->flags & FLAG_TRANSLIT)) + return seterror(EILSEQ); + else if (cv->mblen(cv, buf, len) != len) /* validate result */ + return seterror(EILSEQ); + return len; +} + +/* + * It seems that the mode (cv->mode) is fixnum. + * For example, when converting iso-2022-jp(cp50221) to unicode: + * in ascii sequence: mode=0xC42C0000 + * in jisx0208 sequence: mode=0xC42C0001 + * "C42C" is same for each convert session. + * It should be: ((codepage-1)<<16)|state + */ +static int +mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + int len; + int insize; + HRESULT hr; + + len = cv->mblen(cv, buf, bufsize); + if (len == -1) + return -1; + insize = len; + hr = ConvertINetMultiByteToUnicode(&cv->mode, cv->codepage, + (const char *)buf, &insize, (wchar_t *)wbuf, wbufsize); + if (hr != S_OK || insize != len) + return seterror(EILSEQ); + return len; +} + +static int +mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + char tmpbuf[MB_CHAR_MAX]; /* enough room for one character */ + int tmpsize = MB_CHAR_MAX; + int insize = wbufsize; + HRESULT hr; + + hr = ConvertINetUnicodeToMultiByte(&cv->mode, cv->codepage, + (const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize); + if (hr != S_OK || insize != wbufsize) + return seterror(EILSEQ); + else if (bufsize < tmpsize) + return seterror(E2BIG); + else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize) + return seterror(EILSEQ); + memcpy(buf, tmpbuf, tmpsize); + return tmpsize; +} + +static int +utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + int codepage = cv->codepage; + + /* swap endian: 1200 <-> 1201 */ + if (cv->mode & UNICODE_MODE_SWAPPED) + codepage ^= 1; + + if (bufsize < 2) + return seterror(EINVAL); + if (codepage == 1200) /* little endian */ + wbuf[0] = (buf[1] << 8) | buf[0]; + else if (codepage == 1201) /* big endian */ + wbuf[0] = (buf[0] << 8) | buf[1]; + + if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) + { + cv->mode |= UNICODE_MODE_BOM_DONE; + if (wbuf[0] == 0xFFFE) + { + cv->mode |= UNICODE_MODE_SWAPPED; + *wbufsize = 0; + return 2; + } + else if (wbuf[0] == 0xFEFF) + { + *wbufsize = 0; + return 2; + } + } + + if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF) + return seterror(EILSEQ); + if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) + { + if (bufsize < 4) + return seterror(EINVAL); + if (codepage == 1200) /* little endian */ + wbuf[1] = (buf[3] << 8) | buf[2]; + else if (codepage == 1201) /* big endian */ + wbuf[1] = (buf[2] << 8) | buf[3]; + if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF)) + return seterror(EILSEQ); + *wbufsize = 2; + return 4; + } + *wbufsize = 1; + return 2; +} + +static int +utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) + { + int r; + + cv->mode |= UNICODE_MODE_BOM_DONE; + if (bufsize < 2) + return seterror(E2BIG); + if (cv->codepage == 1200) /* little endian */ + memcpy(buf, "\xFF\xFE", 2); + else if (cv->codepage == 1201) /* big endian */ + memcpy(buf, "\xFE\xFF", 2); + + r = utf16_wctomb(cv, wbuf, wbufsize, buf + 2, bufsize - 2); + if (r == -1) + return -1; + return r + 2; + } + + if (bufsize < 2) + return seterror(E2BIG); + if (cv->codepage == 1200) /* little endian */ + { + buf[0] = (wbuf[0] & 0x00FF); + buf[1] = (wbuf[0] & 0xFF00) >> 8; + } + else if (cv->codepage == 1201) /* big endian */ + { + buf[0] = (wbuf[0] & 0xFF00) >> 8; + buf[1] = (wbuf[0] & 0x00FF); + } + if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) + { + if (bufsize < 4) + return seterror(E2BIG); + if (cv->codepage == 1200) /* little endian */ + { + buf[2] = (wbuf[1] & 0x00FF); + buf[3] = (wbuf[1] & 0xFF00) >> 8; + } + else if (cv->codepage == 1201) /* big endian */ + { + buf[2] = (wbuf[1] & 0xFF00) >> 8; + buf[3] = (wbuf[1] & 0x00FF); + } + return 4; + } + return 2; +} + +static int +utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + int codepage = cv->codepage; + uint wc = 0xD800; + + /* swap endian: 12000 <-> 12001 */ + if (cv->mode & UNICODE_MODE_SWAPPED) + codepage ^= 1; + + if (bufsize < 4) + return seterror(EINVAL); + if (codepage == 12000) /* little endian */ + wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; + else if (codepage == 12001) /* big endian */ + wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + + if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) + { + cv->mode |= UNICODE_MODE_BOM_DONE; + if (wc == 0xFFFE0000) + { + cv->mode |= UNICODE_MODE_SWAPPED; + *wbufsize = 0; + return 4; + } + else if (wc == 0x0000FEFF) + { + *wbufsize = 0; + return 4; + } + } + + if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc) + return seterror(EILSEQ); + ucs4_to_utf16(wc, wbuf, wbufsize); + return 4; +} + +static int +utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + uint wc; + + if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE)) + { + int r; + + cv->mode |= UNICODE_MODE_BOM_DONE; + if (bufsize < 4) + return seterror(E2BIG); + if (cv->codepage == 12000) /* little endian */ + memcpy(buf, "\xFF\xFE\x00\x00", 4); + else if (cv->codepage == 12001) /* big endian */ + memcpy(buf, "\x00\x00\xFE\xFF", 4); + + r = utf32_wctomb(cv, wbuf, wbufsize, buf + 4, bufsize - 4); + if (r == -1) + return -1; + return r + 4; + } + + if (bufsize < 4) + return seterror(E2BIG); + wc = utf16_to_ucs4(wbuf); + if (cv->codepage == 12000) /* little endian */ + { + buf[0] = wc & 0x000000FF; + buf[1] = (wc & 0x0000FF00) >> 8; + buf[2] = (wc & 0x00FF0000) >> 16; + buf[3] = (wc & 0xFF000000) >> 24; + } + else if (cv->codepage == 12001) /* big endian */ + { + buf[0] = (wc & 0xFF000000) >> 24; + buf[1] = (wc & 0x00FF0000) >> 16; + buf[2] = (wc & 0x0000FF00) >> 8; + buf[3] = wc & 0x000000FF; + } + return 4; +} + +/* + * 50220: ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) + * 50221: ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow + * 1 byte Kana) + * 50222: ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte + * Kana - SO/SI) + * + * MultiByteToWideChar() and WideCharToMultiByte() behave differently + * depending on Windows version. On XP, WideCharToMultiByte() doesn't + * terminate result sequence with ascii escape. But Vista does. + * Use MLang instead. + */ + +#define ISO2022_MODE(cs, shift) ((((DWORD) cs) << 8) | (shift)) +#define ISO2022_MODE_CS(mode) (((mode) >> 8) & 0xFF) +#define ISO2022_MODE_SHIFT(mode) ((mode) & 0xFF) + +#define ISO2022_SI 0 +#define ISO2022_SO 1 + +/* shift in */ +static const char iso2022_SI_seq[] = "\x0F"; +/* shift out */ +static const char iso2022_SO_seq[] = "\x0E"; + +typedef struct iso2022_esc_t iso2022_esc_t; +struct iso2022_esc_t { + const char *esc; + int esc_len; + int len; + int cs; +}; + +#define ISO2022JP_CS_ASCII 0 +#define ISO2022JP_CS_JISX0201_ROMAN 1 +#define ISO2022JP_CS_JISX0201_KANA 2 +#define ISO2022JP_CS_JISX0208_1978 3 +#define ISO2022JP_CS_JISX0208_1983 4 +#define ISO2022JP_CS_JISX0212 5 + +static iso2022_esc_t iso2022jp_esc[] = { + {"\x1B\x28\x42", 3, 1, ISO2022JP_CS_ASCII}, + {"\x1B\x28\x4A", 3, 1, ISO2022JP_CS_JISX0201_ROMAN}, + {"\x1B\x28\x49", 3, 1, ISO2022JP_CS_JISX0201_KANA}, + {"\x1B\x24\x40", 3, 2, ISO2022JP_CS_JISX0208_1983}, /* unify 1978 with 1983 */ + {"\x1B\x24\x42", 3, 2, ISO2022JP_CS_JISX0208_1983}, + {"\x1B\x24\x28\x44", 4, 2, ISO2022JP_CS_JISX0212}, + {NULL, 0, 0, 0} +}; + +static int +iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + iso2022_esc_t *iesc = iso2022jp_esc; + char tmp[MB_CHAR_MAX]; + int insize; + HRESULT hr; + DWORD dummy = 0; + int len; + int esc_len; + int cs; + int shift; + int i; + + if (buf[0] == 0x1B) + { + for (i = 0; iesc[i].esc != NULL; ++i) + { + esc_len = iesc[i].esc_len; + if (bufsize < esc_len) + { + if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0) + return seterror(EINVAL); + } + else + { + if (strncmp((char *)buf, iesc[i].esc, esc_len) == 0) + { + cv->mode = ISO2022_MODE(iesc[i].cs, ISO2022_SI); + *wbufsize = 0; + return esc_len; + } + } + } + /* not supported escape sequence */ + return seterror(EILSEQ); + } + else if (buf[0] == iso2022_SO_seq[0]) + { + cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SO); + *wbufsize = 0; + return 1; + } + else if (buf[0] == iso2022_SI_seq[0]) + { + cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SI); + *wbufsize = 0; + return 1; + } + + cs = ISO2022_MODE_CS(cv->mode); + shift = ISO2022_MODE_SHIFT(cv->mode); + + /* reset the mode for informal sequence */ + if (buf[0] < 0x20) + { + cs = ISO2022JP_CS_ASCII; + shift = ISO2022_SI; + } + + len = iesc[cs].len; + if (bufsize < len) + return seterror(EINVAL); + for (i = 0; i < len; ++i) + if (!(buf[i] < 0x80)) + return seterror(EILSEQ); + esc_len = iesc[cs].esc_len; + memcpy(tmp, iesc[cs].esc, esc_len); + if (shift == ISO2022_SO) + { + memcpy(tmp + esc_len, iso2022_SO_seq, 1); + esc_len += 1; + } + memcpy(tmp + esc_len, buf, len); + + if ((cv->codepage == 50220 || cv->codepage == 50221 + || cv->codepage == 50222) && shift == ISO2022_SO) + { + /* XXX: shift-out cannot be used for mbtowc (both kernel and + * mlang) */ + esc_len = iesc[ISO2022JP_CS_JISX0201_KANA].esc_len; + memcpy(tmp, iesc[ISO2022JP_CS_JISX0201_KANA].esc, esc_len); + memcpy(tmp + esc_len, buf, len); + } + + insize = len + esc_len; + hr = ConvertINetMultiByteToUnicode(&dummy, cv->codepage, + (const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize); + if (hr != S_OK || insize != len + esc_len) + return seterror(EILSEQ); + + /* Check for conversion error. Assuming defaultChar is 0x3F. */ + /* ascii should be converted from ascii */ + if (wbuf[0] == buf[0] + && cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI)) + return seterror(EILSEQ); + + /* reset the mode for informal sequence */ + if (cv->mode != ISO2022_MODE(cs, shift)) + cv->mode = ISO2022_MODE(cs, shift); + + return len; +} + +static int +iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + iso2022_esc_t *iesc = iso2022jp_esc; + char tmp[MB_CHAR_MAX]; + int tmpsize = MB_CHAR_MAX; + int insize = wbufsize; + HRESULT hr; + DWORD dummy = 0; + int len; + int esc_len; + int cs; + int shift; + int i; + + /* + * MultiByte = [escape sequence] + character + [escape sequence] + * + * Whether trailing escape sequence is added depends on which API is + * used (kernel or MLang, and its version). + */ + hr = ConvertINetUnicodeToMultiByte(&dummy, cv->codepage, + (const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize); + if (hr != S_OK || insize != wbufsize) + return seterror(EILSEQ); + else if (bufsize < tmpsize) + return seterror(E2BIG); + + if (tmpsize == 1) + { + cs = ISO2022JP_CS_ASCII; + esc_len = 0; + } + else + { + for (i = 1; iesc[i].esc != NULL; ++i) + { + esc_len = iesc[i].esc_len; + if (strncmp(tmp, iesc[i].esc, esc_len) == 0) + { + cs = iesc[i].cs; + break; + } + } + if (iesc[i].esc == NULL) + /* not supported escape sequence */ + return seterror(EILSEQ); + } + + shift = ISO2022_SI; + if (tmp[esc_len] == iso2022_SO_seq[0]) + { + shift = ISO2022_SO; + esc_len += 1; + } + + len = iesc[cs].len; + + /* Check for converting error. Assuming defaultChar is 0x3F. */ + /* ascii should be converted from ascii */ + if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80)) + return seterror(EILSEQ); + else if (tmpsize < esc_len + len) + return seterror(EILSEQ); + + if (cv->mode == ISO2022_MODE(cs, shift)) + { + /* remove escape sequence */ + if (esc_len != 0) + memmove(tmp, tmp + esc_len, len); + esc_len = 0; + } + else + { + if (cs == ISO2022JP_CS_ASCII) + { + esc_len = iesc[ISO2022JP_CS_ASCII].esc_len; + memmove(tmp + esc_len, tmp, len); + memcpy(tmp, iesc[ISO2022JP_CS_ASCII].esc, esc_len); + } + if (ISO2022_MODE_SHIFT(cv->mode) == ISO2022_SO) + { + /* shift-in before changing to other mode */ + memmove(tmp + 1, tmp, len + esc_len); + memcpy(tmp, iso2022_SI_seq, 1); + esc_len += 1; + } + } + + if (bufsize < len + esc_len) + return seterror(E2BIG); + memcpy(buf, tmp, len + esc_len); + cv->mode = ISO2022_MODE(cs, shift); + return len + esc_len; +} + +static int +iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize) +{ + iso2022_esc_t *iesc = iso2022jp_esc; + int esc_len; + + if (cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI)) + { + esc_len = 0; + if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI) + esc_len += 1; + if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII) + esc_len += iesc[ISO2022JP_CS_ASCII].esc_len; + if (bufsize < esc_len) + return seterror(E2BIG); + + esc_len = 0; + if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI) + { + memcpy(buf, iso2022_SI_seq, 1); + esc_len += 1; + } + if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII) + { + memcpy(buf + esc_len, iesc[ISO2022JP_CS_ASCII].esc, + iesc[ISO2022JP_CS_ASCII].esc_len); + esc_len += iesc[ISO2022JP_CS_ASCII].esc_len; + } + return esc_len; + } + return 0; +} + +#if defined(MAKE_DLL) && defined(USE_LIBICONV_DLL) +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + switch( fdwReason ) + { + case DLL_PROCESS_ATTACH: + hwiniconv = (HMODULE)hinstDLL; + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +#if defined(MAKE_EXE) +#include +#include +#include +int +main(int argc, char **argv) +{ + char *fromcode = NULL; + char *tocode = NULL; + int i; + char inbuf[BUFSIZ]; + char outbuf[BUFSIZ]; + const char *pin; + char *pout; + size_t inbytesleft; + size_t outbytesleft; + size_t rest = 0; + iconv_t cd; + size_t r; + FILE *in = stdin; + FILE *out = stdout; + FILE *in_allocated = NULL, *out_allocated = NULL; + int ignore = 0; + char *p; + + _setmode(_fileno(stdin), _O_BINARY); + _setmode(_fileno(stdout), _O_BINARY); + + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-l") == 0) + { + for (i = 0; codepage_alias[i].name != NULL; ++i) + printf("%s\n", codepage_alias[i].name); + return 0; + } + + if (strcmp(argv[i], "-f") == 0) + fromcode = argv[++i]; + else if (strcmp(argv[i], "-t") == 0) + tocode = argv[++i]; + else if (strcmp(argv[i], "-c") == 0) + ignore = 1; + else if (strcmp(argv[i], "--output") == 0) + { + out_allocated = out = fopen(argv[++i], "wb"); + if(out == NULL) + { + fprintf(stderr, "cannot open %s\n", argv[i]); + return 1; + } + } + else + { + in_allocated = in = fopen(argv[i], "rb"); + if (in == NULL) + { + fprintf(stderr, "cannot open %s\n", argv[i]); + return 1; + } + break; + } + } + + if (fromcode == NULL || tocode == NULL) + { + printf("usage: %s [-c] -f from-enc -t to-enc [file]\n", + (argc > 0) ? argv[0] : "win_iconv"); + return 0; + } + + if (ignore) + { + p = tocode; + tocode = (char *)malloc(strlen(p) + strlen("//IGNORE") + 1); + if (tocode == NULL) + { + perror("fatal error"); + return 1; + } + strcpy(tocode, p); + strcat(tocode, "//IGNORE"); + } + + cd = iconv_open(tocode, fromcode); + if (cd == (iconv_t)(-1)) + { + perror("iconv_open error"); + return 1; + } + + while ((inbytesleft = fread(inbuf + rest, 1, sizeof(inbuf) - rest, in)) != 0 + || rest != 0) + { + inbytesleft += rest; + pin = inbuf; + pout = outbuf; + outbytesleft = sizeof(outbuf); + r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft); + fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out); + if (r == (size_t)(-1) && errno != E2BIG && (errno != EINVAL || feof(in))) + { + perror("conversion error"); + return 1; + } + memmove(inbuf, pin, inbytesleft); + rest = inbytesleft; + } + pout = outbuf; + outbytesleft = sizeof(outbuf); + r = iconv(cd, NULL, NULL, &pout, &outbytesleft); + fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out); + if (r == (size_t)(-1)) + { + perror("conversion error"); + return 1; + } + + iconv_close(cd); + + if (in_allocated != NULL) + fclose (in_allocated); + if (out_allocated != NULL) + fclose (out_allocated); + + return 0; +} +#endif diff --git a/gmodule/AUTHORS b/gmodule/AUTHORS new file mode 100644 index 0000000..3282695 --- /dev/null +++ b/gmodule/AUTHORS @@ -0,0 +1 @@ +Tim Janik diff --git a/gmodule/COPYING b/gmodule/COPYING new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/gmodule/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/gmodule/gmodule-ar.c b/gmodule/gmodule-ar.c new file mode 100644 index 0000000..8c3f150 --- /dev/null +++ b/gmodule/gmodule-ar.c @@ -0,0 +1,182 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998, 2000 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * MT safe + */ + +/* because we are compatible with archive format only since AIX 4.3 */ + +#define __AR_BIG__ + +#include "config.h" + +#include +#include + +#include + +/* --- functions --- */ +static gchar* +fetch_dlerror (gboolean replace_null) +{ + gchar *msg = dlerror (); + + /* make sure we always return an error message != NULL, if + * expected to do so. */ + + if (!msg && replace_null) + return "unknown dl-error"; + + return msg; +} + +static gchar* _g_module_get_member(const gchar* file_name) +{ + gchar* member = NULL; + struct fl_hdr file_header; + struct ar_hdr ar_header; + long first_member; + long name_len; + int fd; + + fd = open(file_name, O_RDONLY); + if (fd == -1) + return NULL; + + if (read(fd, (void*)&file_header, FL_HSZ) != FL_HSZ) + goto exit; + + if (strncmp(file_header.fl_magic, AIAMAGBIG, SAIAMAG) != 0) + goto exit; + + /* read first archive file member header */ + + first_member = atol(file_header.fl_fstmoff); + + if (lseek(fd, first_member, SEEK_SET) != first_member) + goto exit; + + if (read(fd, (void*)&ar_header, AR_HSZ - 2) != AR_HSZ - 2) + goto exit; + + /* read member name */ + + name_len = atol(ar_header.ar_namlen); + + member = g_malloc(name_len+1); + if (!member) + goto exit; + + if (read(fd, (void*)member, name_len) != name_len) + { + g_free(member); + member = NULL; + goto exit; + } + + member[name_len] = 0; + +exit: + close(fd); + + return member; +} + +static gpointer +_g_module_open (const gchar *file_name, + gboolean bind_lazy, + gboolean bind_local, + GError **error) +{ + gpointer handle; + gchar* member; + gchar* full_name; + + /* extract name of first member of archive */ + + member = _g_module_get_member (file_name); + if (member != NULL) + { + full_name = g_strconcat (file_name, "(", member, ")", NULL); + g_free (member); + } + else + full_name = g_strdup (file_name); + + handle = dlopen (full_name, + (bind_local ? RTLD_LOCAL : RTLD_GLOBAL) | RTLD_MEMBER | (bind_lazy ? RTLD_LAZY : RTLD_NOW)); + + g_free (full_name); + + if (!handle) + { + const gchar *message = fetch_dlerror (TRUE); + + g_module_set_error (message); + g_set_error_literal (error, G_MODULE_ERROR, G_MODULE_ERROR_FAILED, message); + } + + return handle; +} + +static gpointer +_g_module_self (void) +{ + gpointer handle; + + handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY); + if (!handle) + g_module_set_error (fetch_dlerror (TRUE)); + + return handle; +} + +static void +_g_module_close (gpointer handle) +{ + if (dlclose (handle) != 0) + g_module_set_error (fetch_dlerror (TRUE)); +} + +static gpointer +_g_module_symbol (gpointer handle, + const gchar *symbol_name) +{ + gpointer p; + + p = dlsym (handle, symbol_name); + if (!p) + g_module_set_error (fetch_dlerror (FALSE)); + + return p; +} + +static gchar* +_g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + if (directory && *directory) { + if (strncmp (module_name, "lib", 3) == 0) + return g_strconcat (directory, "/", module_name, NULL); + else + return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL); + } else if (strncmp (module_name, "lib", 3) == 0) + return g_strdup (module_name); + else + return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL); +} diff --git a/gmodule/gmodule-dl.c b/gmodule/gmodule-dl.c new file mode 100644 index 0000000..26f6ba0 --- /dev/null +++ b/gmodule/gmodule-dl.c @@ -0,0 +1,225 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998, 2000 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ +#include "config.h" + +#include +#include + +/* Perl includes and instead of on some systems? */ + + +/* dlerror() is not implemented on all systems + */ +#ifndef G_MODULE_HAVE_DLERROR +# ifdef __NetBSD__ +# define dlerror() g_strerror (errno) +# else /* !__NetBSD__ */ +/* could we rely on errno's state here? */ +# define dlerror() "unknown dl-error" +# endif /* !__NetBSD__ */ +#endif /* G_MODULE_HAVE_DLERROR */ + +/* some flags are missing on some systems, so we provide + * harmless defaults. + * The Perl sources say, RTLD_LAZY needs to be defined as (1), + * at least for Solaris 1. + * + * Mandatory: + * RTLD_LAZY - resolve undefined symbols as code from the dynamic library + * is executed. + * RTLD_NOW - resolve all undefined symbols before dlopen returns, and fail + * if this cannot be done. + * Optionally: + * RTLD_GLOBAL - the external symbols defined in the library will be made + * available to subsequently loaded libraries. + */ +#ifndef HAVE_RTLD_LAZY +#define RTLD_LAZY 1 +#endif /* RTLD_LAZY */ +#ifndef HAVE_RTLD_NOW +#define RTLD_NOW 0 +#endif /* RTLD_NOW */ +/* some systems (OSF1 V5.0) have broken RTLD_GLOBAL linkage */ +#ifdef G_MODULE_BROKEN_RTLD_GLOBAL +#undef RTLD_GLOBAL +#undef HAVE_RTLD_GLOBAL +#endif /* G_MODULE_BROKEN_RTLD_GLOBAL */ +#ifndef HAVE_RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif /* RTLD_GLOBAL */ + + +/* According to POSIX.1-2001, dlerror() is not necessarily thread-safe + * (see https://pubs.opengroup.org/onlinepubs/009695399/), and so must be + * called within the same locked section as the dlopen()/dlsym() call which + * may have caused an error. + * + * However, some libc implementations, such as glibc, implement dlerror() using + * thread-local storage, so are thread-safe. As of early 2021: + * - glibc is thread-safe: https://github.com/bminor/glibc/blob/HEAD/dlfcn/libc_dlerror_result.c + * - uclibc-ng is not thread-safe: https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/ldso/libdl/libdl.c?id=132decd2a043d0ccf799f42bf89f3ae0c11e95d5#n1075 + * - Other libc implementations have not been checked, and no problems have + * been reported with them in 10 years, so default to assuming that they + * don’t need additional thread-safety from GLib + */ +#if defined(__UCLIBC__) +G_LOCK_DEFINE_STATIC (errors); +#else +#define DLERROR_IS_THREADSAFE 1 +#endif + +static void +lock_dlerror (void) +{ +#ifndef DLERROR_IS_THREADSAFE + G_LOCK (errors); +#endif +} + +static void +unlock_dlerror (void) +{ +#ifndef DLERROR_IS_THREADSAFE + G_UNLOCK (errors); +#endif +} + +/* This should be called with lock_dlerror() held */ +static const gchar * +fetch_dlerror (gboolean replace_null) +{ + const gchar *msg = dlerror (); + + /* make sure we always return an error message != NULL, if + * expected to do so. */ + + if (!msg && replace_null) + return "unknown dl-error"; + + return msg; +} + +static gpointer +_g_module_open (const gchar *file_name, + gboolean bind_lazy, + gboolean bind_local, + GError **error) +{ + gpointer handle; + + lock_dlerror (); + handle = dlopen (file_name, + (bind_local ? 0 : RTLD_GLOBAL) | (bind_lazy ? RTLD_LAZY : RTLD_NOW)); + if (!handle) + { + const gchar *message = fetch_dlerror (TRUE); + + g_module_set_error (message); + g_set_error_literal (error, G_MODULE_ERROR, G_MODULE_ERROR_FAILED, message); + } + + unlock_dlerror (); + + return handle; +} + +static gpointer +_g_module_self (void) +{ + gpointer handle; + + /* to query symbols from the program itself, special link options + * are required on some systems. + */ + + /* On Android 32 bit (i.e. not __LP64__), dlopen(NULL) + * does not work reliable and generally no symbols are found + * at all. RTLD_DEFAULT works though. + * On Android 64 bit, dlopen(NULL) seems to work but dlsym(handle) + * always returns 'undefined symbol'. Only if RTLD_DEFAULT or + * NULL is given, dlsym returns an appropriate pointer. + */ + lock_dlerror (); +#if defined(__BIONIC__) + handle = RTLD_DEFAULT; +#else + handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY); +#endif + if (!handle) + g_module_set_error (fetch_dlerror (TRUE)); + unlock_dlerror (); + + return handle; +} + +static void +_g_module_close (gpointer handle) +{ +#if defined(__BIONIC__) + if (handle != RTLD_DEFAULT) +#endif + { + lock_dlerror (); + if (dlclose (handle) != 0) + g_module_set_error (fetch_dlerror (TRUE)); + unlock_dlerror (); + } +} + +static gpointer +_g_module_symbol (gpointer handle, + const gchar *symbol_name) +{ + gpointer p; + const gchar *msg; + + lock_dlerror (); + fetch_dlerror (FALSE); + p = dlsym (handle, symbol_name); + msg = fetch_dlerror (FALSE); + if (msg) + g_module_set_error (msg); + unlock_dlerror (); + + return p; +} + +static gchar* +_g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + if (directory && *directory) { + if (strncmp (module_name, "lib", 3) == 0) + return g_strconcat (directory, "/", module_name, NULL); + else + return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL); + } else if (strncmp (module_name, "lib", 3) == 0) + return g_strdup (module_name); + else + return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL); +} diff --git a/gmodule/gmodule-win32.c b/gmodule/gmodule-win32.c new file mode 100644 index 0000000..cb51949 --- /dev/null +++ b/gmodule/gmodule-win32.c @@ -0,0 +1,237 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998, 2000 Tim Janik + * + * Win32 GMODULE implementation + * Copyright (C) 1998 Tor Lillqvist + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ +#include "config.h" + +#include +#include +#include + +#include + +#ifdef G_WITH_CYGWIN +#include +#endif + +static void G_GNUC_PRINTF (2, 3) +set_error (GError **error, + const gchar *format, + ...) +{ + gchar *win32_error; + gchar *detail; + gchar *message; + va_list args; + + win32_error = g_win32_error_message (GetLastError ()); + + va_start (args, format); + detail = g_strdup_vprintf (format, args); + va_end (args); + + message = g_strconcat (detail, win32_error, NULL); + + g_module_set_error (message); + g_set_error_literal (error, G_MODULE_ERROR, G_MODULE_ERROR_FAILED, message); + + g_free (message); + g_free (detail); + g_free (win32_error); +} + +/* --- functions --- */ +static gpointer +_g_module_open (const gchar *file_name, + gboolean bind_lazy, + gboolean bind_local, + GError **error) +{ + HINSTANCE handle; + wchar_t *wfilename; + DWORD old_mode; + BOOL success; +#ifdef G_WITH_CYGWIN + gchar tmp[MAX_PATH]; + + cygwin_conv_to_win32_path(file_name, tmp); + file_name = tmp; +#endif + wfilename = g_utf8_to_utf16 (file_name, -1, NULL, NULL, NULL); + + /* suppress error dialog */ + success = SetThreadErrorMode (SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS, &old_mode); + if (!success) + set_error (error, ""); + + /* When building for UWP, load app asset DLLs instead of filesystem DLLs. + * Needs MSVC, Windows 8 and newer, and is only usable from apps. */ +#if _WIN32_WINNT >= 0x0602 && defined(G_WINAPI_ONLY_APP) + handle = LoadPackagedLibrary (wfilename, 0); +#else + handle = LoadLibraryW (wfilename); +#endif + + if (success) + SetThreadErrorMode (old_mode, NULL); + g_free (wfilename); + + if (!handle) + set_error (error, "'%s': ", file_name); + + return handle; +} + +static gint dummy; +static gpointer null_module_handle = &dummy; + +static gpointer +_g_module_self (void) +{ + return null_module_handle; +} + +static void +_g_module_close (gpointer handle) +{ + if (handle != null_module_handle) + if (!FreeLibrary (handle)) + set_error (NULL, ""); +} + +static gpointer +find_in_any_module_using_toolhelp (const gchar *symbol_name) +{ + HANDLE snapshot; + MODULEENTRY32 me32; + + gpointer p = NULL; + + /* Under UWP, Module32Next and Module32First are not available since we're + * not allowed to search in the address space of arbitrary loaded DLLs */ +#if !defined(G_WINAPI_ONLY_APP) + /* https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot#remarks + * If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds. */ + while (TRUE) + { + snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); + if (snapshot == INVALID_HANDLE_VALUE && GetLastError () == ERROR_BAD_LENGTH) + { + g_thread_yield (); + continue; + } + break; + } + + if (snapshot == INVALID_HANDLE_VALUE) + return NULL; + + me32.dwSize = sizeof (me32); + p = NULL; + if (Module32First (snapshot, &me32)) + { + do { + if ((p = GetProcAddress (me32.hModule, symbol_name)) != NULL) + break; + } while (Module32Next (snapshot, &me32)); + } + + CloseHandle (snapshot); +#endif + + return p; +} + +static gpointer +find_in_any_module (const gchar *symbol_name) +{ + gpointer result; + + if ((result = find_in_any_module_using_toolhelp (symbol_name)) == NULL) + return NULL; + else + return result; +} + +static gpointer +_g_module_symbol (gpointer handle, + const gchar *symbol_name) +{ + gpointer p; + + if (handle == null_module_handle) + { + if ((p = GetProcAddress (GetModuleHandle (NULL), symbol_name)) == NULL) + p = find_in_any_module (symbol_name); + } + else + p = GetProcAddress (handle, symbol_name); + + if (!p) + set_error (NULL, ""); + + return p; +} + +static gchar* +_g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + gint k; + + k = strlen (module_name); + + if (directory && *directory) + if (k > 4 && g_ascii_strcasecmp (module_name + k - 4, ".dll") == 0) + return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, NULL); +#ifdef G_WITH_CYGWIN + else if (strncmp (module_name, "lib", 3) == 0 || strncmp (module_name, "cyg", 3) == 0) + return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, ".dll", NULL); + else + return g_strconcat (directory, G_DIR_SEPARATOR_S, "cyg", module_name, ".dll", NULL); +#else + else if (strncmp (module_name, "lib", 3) == 0) + return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, ".dll", NULL); + else + return g_strconcat (directory, G_DIR_SEPARATOR_S, "lib", module_name, ".dll", NULL); +#endif + else if (k > 4 && g_ascii_strcasecmp (module_name + k - 4, ".dll") == 0) + return g_strdup (module_name); +#ifdef G_WITH_CYGWIN + else if (strncmp (module_name, "lib", 3) == 0 || strncmp (module_name, "cyg", 3) == 0) + return g_strconcat (module_name, ".dll", NULL); + else + return g_strconcat ("cyg", module_name, ".dll", NULL); +#else + else if (strncmp (module_name, "lib", 3) == 0) + return g_strconcat (module_name, ".dll", NULL); + else + return g_strconcat ("lib", module_name, ".dll", NULL); +#endif +} diff --git a/gmodule/gmodule.c b/gmodule/gmodule.c new file mode 100644 index 0000000..c722c44 --- /dev/null +++ b/gmodule/gmodule.c @@ -0,0 +1,910 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "glib.h" +#include "gmodule.h" + +#include +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include /* For open() and close() prototypes. */ +#endif + +#include "gmoduleconf.h" +#include "gstdio.h" + +/** + * SECTION:modules + * @title: Dynamic Loading of Modules + * @short_description: portable method for dynamically loading 'plug-ins' + * + * These functions provide a portable way to dynamically load object files + * (commonly known as 'plug-ins'). The current implementation supports all + * systems that provide an implementation of dlopen() (e.g. Linux/Sun), as + * well as Windows platforms via DLLs. + * + * A program which wants to use these functions must be linked to the + * libraries output by the command `pkg-config --libs gmodule-2.0`. + * + * To use them you must first determine whether dynamic loading + * is supported on the platform by calling g_module_supported(). + * If it is, you can open a module with g_module_open(), + * find the module's symbols (e.g. function names) with g_module_symbol(), + * and later close the module with g_module_close(). + * g_module_name() will return the file name of a currently opened module. + * + * If any of the above functions fail, the error status can be found with + * g_module_error(). + * + * The #GModule implementation features reference counting for opened modules, + * and supports hook functions within a module which are called when the + * module is loaded and unloaded (see #GModuleCheckInit and #GModuleUnload). + * + * If your module introduces static data to common subsystems in the running + * program, e.g. through calling + * `g_quark_from_static_string ("my-module-stuff")`, + * it must ensure that it is never unloaded, by calling g_module_make_resident(). + * + * Example: Calling a function defined in a GModule + * |[ + * // the function signature for 'say_hello' + * typedef void (* SayHelloFunc) (const char *message); + * + * gboolean + * just_say_hello (const char *filename, GError **error) + * { + * SayHelloFunc say_hello; + * GModule *module; + * + * module = g_module_open (filename, G_MODULE_BIND_LAZY); + * if (!module) + * { + * g_set_error (error, FOO_ERROR, FOO_ERROR_BLAH, + * "%s", g_module_error ()); + * return FALSE; + * } + * + * if (!g_module_symbol (module, "say_hello", (gpointer *)&say_hello)) + * { + * g_set_error (error, SAY_ERROR, SAY_ERROR_OPEN, + * "%s: %s", filename, g_module_error ()); + * if (!g_module_close (module)) + * g_warning ("%s: %s", filename, g_module_error ()); + * return FALSE; + * } + * + * if (say_hello == NULL) + * { + * g_set_error (error, SAY_ERROR, SAY_ERROR_OPEN, + * "symbol say_hello is NULL"); + * if (!g_module_close (module)) + * g_warning ("%s: %s", filename, g_module_error ()); + * return FALSE; + * } + * + * // call our function in the module + * say_hello ("Hello world!"); + * + * if (!g_module_close (module)) + * g_warning ("%s: %s", filename, g_module_error ()); + * return TRUE; + * } + * ]| + */ + +/** + * GModule: + * + * The #GModule struct is an opaque data structure to represent a + * [dynamically-loaded module][glib-Dynamic-Loading-of-Modules]. + * It should only be accessed via the following functions. + */ + +/** + * GModuleCheckInit: + * @module: the #GModule corresponding to the module which has just been loaded + * + * Specifies the type of the module initialization function. + * If a module contains a function named g_module_check_init() it is called + * automatically when the module is loaded. It is passed the #GModule structure + * and should return %NULL on success or a string describing the initialization + * error. + * + * Returns: %NULL on success, or a string describing the initialization error + */ + +/** + * GModuleUnload: + * @module: the #GModule about to be unloaded + * + * Specifies the type of the module function called when it is unloaded. + * If a module contains a function named g_module_unload() it is called + * automatically when the module is unloaded. + * It is passed the #GModule structure. + */ + +/** + * G_MODULE_SUFFIX: + * + * Expands to the proper shared library suffix for the current platform + * without the leading dot. For most Unices and Linux this is "so", and + * for Windows this is "dll". + */ + +/** + * G_MODULE_EXPORT: + * + * Used to declare functions exported by libraries or modules. + * + * When compiling for Windows, it marks the symbol as `dllexport`. + * + * When compiling for Linux and Unices, it marks the symbol as having `default` + * visibility. This is no-op unless the code is being compiled with a + * non-default + * [visibility flag](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fvisibility-1260) + * such as `hidden`. + */ + +/** + * G_MODULE_IMPORT: + * + * Used to declare functions imported from modules. + */ + +/* We maintain a list of modules, so we can reference count them. + * That's needed because some platforms don't support references counts on + * modules. Also, the module for the program itself is kept separately for + * faster access and because it has special semantics. + */ + + +/* --- structures --- */ +struct _GModule +{ + gchar *file_name; + gpointer handle; + guint ref_count : 31; + guint is_resident : 1; + GModuleUnload unload; + GModule *next; +}; + + +/* --- prototypes --- */ +static gpointer _g_module_open (const gchar *file_name, + gboolean bind_lazy, + gboolean bind_local, + GError **error); +static void _g_module_close (gpointer handle); +static gpointer _g_module_self (void); +static gpointer _g_module_symbol (gpointer handle, + const gchar *symbol_name); +static gchar* _g_module_build_path (const gchar *directory, + const gchar *module_name); +static inline void g_module_set_error (const gchar *error); +static inline GModule* g_module_find_by_handle (gpointer handle); +static inline GModule* g_module_find_by_name (const gchar *name); + + +/* --- variables --- */ +static GModule *modules = NULL; +static GModule *main_module = NULL; +static GPrivate module_error_private = G_PRIVATE_INIT (g_free); +static gboolean module_debug_initialized = FALSE; +static guint module_debug_flags = 0; + + +/* --- inline functions --- */ +static inline GModule* +g_module_find_by_handle (gpointer handle) +{ + GModule *module; + GModule *retval = NULL; + + if (main_module && main_module->handle == handle) + retval = main_module; + else + for (module = modules; module; module = module->next) + if (handle == module->handle) + { + retval = module; + break; + } + + return retval; +} + +static inline GModule* +g_module_find_by_name (const gchar *name) +{ + GModule *module; + GModule *retval = NULL; + + for (module = modules; module; module = module->next) + if (strcmp (name, module->file_name) == 0) + { + retval = module; + break; + } + + return retval; +} + +static inline void +g_module_set_error_unduped (gchar *error) +{ + g_private_replace (&module_error_private, error); + errno = 0; +} + +static inline void +g_module_set_error (const gchar *error) +{ + g_module_set_error_unduped (g_strdup (error)); +} + + +/* --- include platform specific code --- */ +#define SUPPORT_OR_RETURN(rv) { g_module_set_error (NULL); } +#if (G_MODULE_IMPL == G_MODULE_IMPL_DL) +#include "gmodule-dl.c" +#elif (G_MODULE_IMPL == G_MODULE_IMPL_WIN32) +#include "gmodule-win32.c" +#elif (G_MODULE_IMPL == G_MODULE_IMPL_AR) +#include "gmodule-ar.c" +#else +#undef SUPPORT_OR_RETURN +#define SUPPORT_OR_RETURN(rv) { g_module_set_error ("dynamic modules are " \ + "not supported by this system"); return rv; } +static gpointer +_g_module_open (const gchar *file_name, + gboolean bind_lazy, + gboolean bind_local, + GError **error) +{ + g_module_set_error (NULL); + return NULL; +} +static void +_g_module_close (gpointer handle) +{ +} +static gpointer +_g_module_self (void) +{ + return NULL; +} +static gpointer +_g_module_symbol (gpointer handle, + const gchar *symbol_name) +{ + return NULL; +} +static gchar* +_g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + return NULL; +} +#endif /* no implementation */ + +/** + * G_MODULE_ERROR: + * + * The error domain of the #GModule API. + * + * Since: 2.70 + */ +G_DEFINE_QUARK (g-module-error-quark, g_module_error) + +/* --- functions --- */ + +/** + * g_module_supported: + * + * Checks if modules are supported on the current platform. + * + * Returns: %TRUE if modules are supported + */ +gboolean +g_module_supported (void) +{ + SUPPORT_OR_RETURN (FALSE); + + return TRUE; +} + +static gchar* +parse_libtool_archive (const gchar* libtool_name) +{ + const guint TOKEN_DLNAME = G_TOKEN_LAST + 1; + const guint TOKEN_INSTALLED = G_TOKEN_LAST + 2; + const guint TOKEN_LIBDIR = G_TOKEN_LAST + 3; + gchar *lt_dlname = NULL; + gboolean lt_installed = TRUE; + gchar *lt_libdir = NULL; + gchar *name; + GTokenType token; + GScanner *scanner; + + int fd = g_open (libtool_name, O_RDONLY, 0); + if (fd < 0) + { + gchar *display_libtool_name = g_filename_display_name (libtool_name); + g_module_set_error_unduped (g_strdup_printf ("failed to open libtool archive \"%s\"", display_libtool_name)); + g_free (display_libtool_name); + return NULL; + } + /* search libtool's dlname specification */ + scanner = g_scanner_new (NULL); + g_scanner_input_file (scanner, fd); + scanner->config->symbol_2_token = TRUE; + g_scanner_scope_add_symbol (scanner, 0, "dlname", + GUINT_TO_POINTER (TOKEN_DLNAME)); + g_scanner_scope_add_symbol (scanner, 0, "installed", + GUINT_TO_POINTER (TOKEN_INSTALLED)); + g_scanner_scope_add_symbol (scanner, 0, "libdir", + GUINT_TO_POINTER (TOKEN_LIBDIR)); + while (!g_scanner_eof (scanner)) + { + token = g_scanner_get_next_token (scanner); + if (token == TOKEN_DLNAME || token == TOKEN_INSTALLED || + token == TOKEN_LIBDIR) + { + if (g_scanner_get_next_token (scanner) != '=' || + g_scanner_get_next_token (scanner) != + (token == TOKEN_INSTALLED ? + G_TOKEN_IDENTIFIER : G_TOKEN_STRING)) + { + gchar *display_libtool_name = g_filename_display_name (libtool_name); + g_module_set_error_unduped (g_strdup_printf ("unable to parse libtool archive \"%s\"", display_libtool_name)); + g_free (display_libtool_name); + + g_free (lt_dlname); + g_free (lt_libdir); + g_scanner_destroy (scanner); + close (fd); + + return NULL; + } + else + { + if (token == TOKEN_DLNAME) + { + g_free (lt_dlname); + lt_dlname = g_strdup (scanner->value.v_string); + } + else if (token == TOKEN_INSTALLED) + lt_installed = + strcmp (scanner->value.v_identifier, "yes") == 0; + else /* token == TOKEN_LIBDIR */ + { + g_free (lt_libdir); + lt_libdir = g_strdup (scanner->value.v_string); + } + } + } + } + + if (!lt_installed) + { + gchar *dir = g_path_get_dirname (libtool_name); + g_free (lt_libdir); + lt_libdir = g_strconcat (dir, G_DIR_SEPARATOR_S ".libs", NULL); + g_free (dir); + } + + name = g_strconcat (lt_libdir, G_DIR_SEPARATOR_S, lt_dlname, NULL); + + g_free (lt_dlname); + g_free (lt_libdir); + g_scanner_destroy (scanner); + close (fd); + + return name; +} + +enum +{ + G_MODULE_DEBUG_RESIDENT_MODULES = 1 << 0, + G_MODULE_DEBUG_BIND_NOW_MODULES = 1 << 1 +}; + +static void +_g_module_debug_init (void) +{ + const GDebugKey keys[] = { + { "resident-modules", G_MODULE_DEBUG_RESIDENT_MODULES }, + { "bind-now-modules", G_MODULE_DEBUG_BIND_NOW_MODULES } + }; + const gchar *env; + + env = g_getenv ("G_DEBUG"); + + module_debug_flags = + !env ? 0 : g_parse_debug_string (env, keys, G_N_ELEMENTS (keys)); + + module_debug_initialized = TRUE; +} + +static GRecMutex g_module_global_lock; + +/** + * g_module_open_full: + * @file_name: (nullable): the name of the file containing the module, or %NULL + * to obtain a #GModule representing the main program itself + * @flags: the flags used for opening the module. This can be the + * logical OR of any of the #GModuleFlags + * @error: #GError. + * + * Opens a module. If the module has already been opened, + * its reference count is incremented. + * + * First of all g_module_open_full() tries to open @file_name as a module. + * If that fails and @file_name has the ".la"-suffix (and is a libtool + * archive) it tries to open the corresponding module. If that fails + * and it doesn't have the proper module suffix for the platform + * (%G_MODULE_SUFFIX), this suffix will be appended and the corresponding + * module will be opened. If that fails and @file_name doesn't have the + * ".la"-suffix, this suffix is appended and g_module_open_full() tries to open + * the corresponding module. If eventually that fails as well, %NULL is + * returned. + * + * Returns: a #GModule on success, or %NULL on failure + * + * Since: 2.70 + */ +GModule* +g_module_open_full (const gchar *file_name, + GModuleFlags flags, + GError **error) +{ + GModule *module; + gpointer handle = NULL; + gchar *name = NULL; + + SUPPORT_OR_RETURN (NULL); + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + g_rec_mutex_lock (&g_module_global_lock); + + if (G_UNLIKELY (!module_debug_initialized)) + _g_module_debug_init (); + + if (module_debug_flags & G_MODULE_DEBUG_BIND_NOW_MODULES) + flags &= ~G_MODULE_BIND_LAZY; + + if (!file_name) + { + if (!main_module) + { + handle = _g_module_self (); +/* On Android 64 bit, RTLD_DEFAULT is (void *)0x0 + * so it always fails to create main_module if file_name is NULL */ +#if !defined(__BIONIC__) || !defined(__LP64__) + if (handle) +#endif + { + main_module = g_new (GModule, 1); + main_module->file_name = NULL; + main_module->handle = handle; + main_module->ref_count = 1; + main_module->is_resident = TRUE; + main_module->unload = NULL; + main_module->next = NULL; + } + } + else + main_module->ref_count++; + + g_rec_mutex_unlock (&g_module_global_lock); + return main_module; + } + + /* we first search the module list by name */ + module = g_module_find_by_name (file_name); + if (module) + { + module->ref_count++; + + g_rec_mutex_unlock (&g_module_global_lock); + return module; + } + + /* check whether we have a readable file right away */ + if (g_file_test (file_name, G_FILE_TEST_IS_REGULAR)) + name = g_strdup (file_name); + /* try completing file name with standard library suffix */ + if (!name) + { + name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL); + if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) + { + g_free (name); + name = NULL; + } + } + /* try completing by appending libtool suffix */ + if (!name) + { + name = g_strconcat (file_name, ".la", NULL); + if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) + { + g_free (name); + name = NULL; + } + } + /* we can't access() the file, lets hope the platform backends finds + * it via library paths + */ + if (!name) + { + gchar *dot = strrchr (file_name, '.'); + gchar *slash = strrchr (file_name, G_DIR_SEPARATOR); + + /* make sure the name has a suffix */ + if (!dot || dot < slash) + name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL); + else + name = g_strdup (file_name); + } + + /* ok, try loading the module */ + g_assert (name != NULL); + + /* if it's a libtool archive, figure library file to load */ + if (g_str_has_suffix (name, ".la")) /* libtool archive? */ + { + gchar *real_name = parse_libtool_archive (name); + + /* real_name might be NULL, but then module error is already set */ + if (real_name) + { + g_free (name); + name = real_name; + } + } + + handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0, + (flags & G_MODULE_BIND_LOCAL) != 0, error); + g_free (name); + + if (handle) + { + gchar *saved_error; + GModuleCheckInit check_init; + const gchar *check_failed = NULL; + + /* search the module list by handle, since file names are not unique */ + module = g_module_find_by_handle (handle); + if (module) + { + _g_module_close (module->handle); + module->ref_count++; + g_module_set_error (NULL); + + g_rec_mutex_unlock (&g_module_global_lock); + return module; + } + + saved_error = g_strdup (g_module_error ()); + g_module_set_error (NULL); + + module = g_new (GModule, 1); + module->file_name = g_strdup (file_name); + module->handle = handle; + module->ref_count = 1; + module->is_resident = FALSE; + module->unload = NULL; + module->next = modules; + modules = module; + + /* check initialization */ + if (g_module_symbol (module, "g_module_check_init", (gpointer) &check_init) && check_init != NULL) + check_failed = check_init (module); + + /* we don't call unload() if the initialization check failed. */ + if (!check_failed) + g_module_symbol (module, "g_module_unload", (gpointer) &module->unload); + + if (check_failed) + { + gchar *temp_error; + + temp_error = g_strconcat ("GModule (", file_name, ") ", + "initialization check failed: ", + check_failed, NULL); + g_module_close (module); + module = NULL; + g_module_set_error (temp_error); + g_set_error_literal (error, G_MODULE_ERROR, G_MODULE_ERROR_CHECK_FAILED, temp_error); + g_free (temp_error); + } + else + g_module_set_error (saved_error); + + g_free (saved_error); + } + + if (module != NULL && + (module_debug_flags & G_MODULE_DEBUG_RESIDENT_MODULES)) + g_module_make_resident (module); + + g_rec_mutex_unlock (&g_module_global_lock); + return module; +} + +/** + * g_module_open: + * @file_name: (nullable): the name of the file containing the module, or %NULL + * to obtain a #GModule representing the main program itself + * @flags: the flags used for opening the module. This can be the + * logical OR of any of the #GModuleFlags. + * + * A thin wrapper function around g_module_open_full() + * + * Returns: a #GModule on success, or %NULL on failure + */ +GModule * +g_module_open (const gchar *file_name, + GModuleFlags flags) +{ + return g_module_open_full (file_name, flags, NULL); +} + +/** + * g_module_close: + * @module: a #GModule to close + * + * Closes a module. + * + * Returns: %TRUE on success + */ +gboolean +g_module_close (GModule *module) +{ + SUPPORT_OR_RETURN (FALSE); + + g_return_val_if_fail (module != NULL, FALSE); + g_return_val_if_fail (module->ref_count > 0, FALSE); + + g_rec_mutex_lock (&g_module_global_lock); + + module->ref_count--; + + if (!module->ref_count && !module->is_resident && module->unload) + { + GModuleUnload unload; + + unload = module->unload; + module->unload = NULL; + unload (module); + } + + if (!module->ref_count && !module->is_resident) + { + GModule *last; + GModule *node; + + last = NULL; + + node = modules; + while (node) + { + if (node == module) + { + if (last) + last->next = node->next; + else + modules = node->next; + break; + } + last = node; + node = last->next; + } + module->next = NULL; + + _g_module_close (module->handle); + g_free (module->file_name); + g_free (module); + } + + g_rec_mutex_unlock (&g_module_global_lock); + return g_module_error() == NULL; +} + +/** + * g_module_make_resident: + * @module: a #GModule to make permanently resident + * + * Ensures that a module will never be unloaded. + * Any future g_module_close() calls on the module will be ignored. + */ +void +g_module_make_resident (GModule *module) +{ + g_return_if_fail (module != NULL); + + module->is_resident = TRUE; +} + +/** + * g_module_error: + * + * Gets a string describing the last module error. + * + * Returns: a string describing the last module error + */ +const gchar * +g_module_error (void) +{ + return g_private_get (&module_error_private); +} + +/** + * g_module_symbol: + * @module: a #GModule + * @symbol_name: the name of the symbol to find + * @symbol: (out): returns the pointer to the symbol value + * + * Gets a symbol pointer from a module, such as one exported + * by %G_MODULE_EXPORT. Note that a valid symbol can be %NULL. + * + * Returns: %TRUE on success + */ +gboolean +g_module_symbol (GModule *module, + const gchar *symbol_name, + gpointer *symbol) +{ + const gchar *module_error; + + if (symbol) + *symbol = NULL; + SUPPORT_OR_RETURN (FALSE); + + g_return_val_if_fail (module != NULL, FALSE); + g_return_val_if_fail (symbol_name != NULL, FALSE); + g_return_val_if_fail (symbol != NULL, FALSE); + + g_rec_mutex_lock (&g_module_global_lock); + +#ifdef G_MODULE_NEED_USCORE + { + gchar *name; + + name = g_strconcat ("_", symbol_name, NULL); + *symbol = _g_module_symbol (module->handle, name); + g_free (name); + } +#else /* !G_MODULE_NEED_USCORE */ + *symbol = _g_module_symbol (module->handle, symbol_name); +#endif /* !G_MODULE_NEED_USCORE */ + + module_error = g_module_error (); + if (module_error) + { + gchar *error; + + error = g_strconcat ("'", symbol_name, "': ", module_error, NULL); + g_module_set_error (error); + g_free (error); + *symbol = NULL; + } + + g_rec_mutex_unlock (&g_module_global_lock); + return !module_error; +} + +/** + * g_module_name: + * @module: a #GModule + * + * Returns the filename that the module was opened with. + * + * If @module refers to the application itself, "main" is returned. + * + * Returns: (transfer none): the filename of the module + */ +const gchar * +g_module_name (GModule *module) +{ + g_return_val_if_fail (module != NULL, NULL); + + if (module == main_module) + return "main"; + + return module->file_name; +} + +/** + * g_module_build_path: + * @directory: (nullable): the directory where the module is. This can be + * %NULL or the empty string to indicate that the standard platform-specific + * directories will be used, though that is not recommended + * @module_name: the name of the module + * + * A portable way to build the filename of a module. The platform-specific + * prefix and suffix are added to the filename, if needed, and the result + * is added to the directory, using the correct separator character. + * + * The directory should specify the directory where the module can be found. + * It can be %NULL or an empty string to indicate that the module is in a + * standard platform-specific directory, though this is not recommended + * since the wrong module may be found. + * + * For example, calling g_module_build_path() on a Linux system with a + * @directory of `/lib` and a @module_name of "mylibrary" will return + * `/lib/libmylibrary.so`. On a Windows system, using `\Windows` as the + * directory it will return `\Windows\mylibrary.dll`. + * + * Returns: the complete path of the module, including the standard library + * prefix and suffix. This should be freed when no longer needed + */ +gchar * +g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + g_return_val_if_fail (module_name != NULL, NULL); + + return _g_module_build_path (directory, module_name); +} + + +#ifdef G_OS_WIN32 + +/* Binary compatibility versions. Not for newly compiled code. */ + +_GLIB_EXTERN GModule * g_module_open_utf8 (const gchar *file_name, + GModuleFlags flags); + +_GLIB_EXTERN const gchar *g_module_name_utf8 (GModule *module); + +GModule* +g_module_open_utf8 (const gchar *file_name, + GModuleFlags flags) +{ + return g_module_open (file_name, flags); +} + +const gchar * +g_module_name_utf8 (GModule *module) +{ + return g_module_name (module); +} + +#endif diff --git a/gmodule/gmodule.h b/gmodule/gmodule.h new file mode 100644 index 0000000..c5fd033 --- /dev/null +++ b/gmodule/gmodule.h @@ -0,0 +1,142 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GMODULE_H__ +#define __GMODULE_H__ + +#include + +G_BEGIN_DECLS + +/* exporting and importing functions, this is special cased + * to feature Windows dll stubs. + */ +#define G_MODULE_IMPORT extern +#ifdef G_PLATFORM_WIN32 +# define G_MODULE_EXPORT __declspec(dllexport) +#elif __GNUC__ >= 4 +# define G_MODULE_EXPORT __attribute__((visibility("default"))) +#else /* !G_PLATFORM_WIN32 && __GNUC__ < 4 */ +# define G_MODULE_EXPORT +#endif /* !G_PLATFORM_WIN32 */ + +/** + * GModuleFlags: + * @G_MODULE_BIND_LAZY: specifies that symbols are only resolved when + * needed. The default action is to bind all symbols when the module + * is loaded. + * @G_MODULE_BIND_LOCAL: specifies that symbols in the module should + * not be added to the global name space. The default action on most + * platforms is to place symbols in the module in the global name space, + * which may cause conflicts with existing symbols. + * @G_MODULE_BIND_MASK: mask for all flags. + * + * Flags passed to g_module_open(). + * Note that these flags are not supported on all platforms. + */ +typedef enum +{ + G_MODULE_BIND_LAZY = 1 << 0, + G_MODULE_BIND_LOCAL = 1 << 1, + G_MODULE_BIND_MASK = 0x03 +} GModuleFlags; + +typedef struct _GModule GModule; +typedef const gchar* (*GModuleCheckInit) (GModule *module); +typedef void (*GModuleUnload) (GModule *module); + +#define G_MODULE_ERROR g_module_error_quark () GLIB_AVAILABLE_MACRO_IN_2_70 +GLIB_AVAILABLE_IN_2_70 +GQuark g_module_error_quark (void); + +/** + * GModuleError: + * @G_MODULE_ERROR_FAILED: there was an error loading or opening a module file + * @G_MODULE_ERROR_CHECK_FAILED: a module returned an error from its `g_module_check_init()` function + * + * Errors returned by g_module_open_full(). + * + * Since: 2.70 + */ +typedef enum +{ + G_MODULE_ERROR_FAILED, + G_MODULE_ERROR_CHECK_FAILED, +} GModuleError +GLIB_AVAILABLE_ENUMERATOR_IN_2_70; + +/* return TRUE if dynamic module loading is supported */ +GLIB_AVAILABLE_IN_ALL +gboolean g_module_supported (void) G_GNUC_CONST; + +/* open a module 'file_name' and return handle, which is NULL on error */ +GLIB_AVAILABLE_IN_ALL +GModule* g_module_open (const gchar *file_name, + GModuleFlags flags); + +GLIB_AVAILABLE_IN_2_70 +GModule *g_module_open_full (const gchar *file_name, + GModuleFlags flags, + GError **error); + +/* close a previously opened module, returns TRUE on success */ +GLIB_AVAILABLE_IN_ALL +gboolean g_module_close (GModule *module); + +/* make a module resident so g_module_close on it will be ignored */ +GLIB_AVAILABLE_IN_ALL +void g_module_make_resident (GModule *module); + +/* query the last module error as a string */ +GLIB_AVAILABLE_IN_ALL +const gchar * g_module_error (void); + +/* retrieve a symbol pointer from 'module', returns TRUE on success */ +GLIB_AVAILABLE_IN_ALL +gboolean g_module_symbol (GModule *module, + const gchar *symbol_name, + gpointer *symbol); + +/* retrieve the file name from an existing module */ +GLIB_AVAILABLE_IN_ALL +const gchar * g_module_name (GModule *module); + +/* Build the actual file name containing a module. 'directory' is the + * directory where the module file is supposed to be, or NULL or empty + * in which case it should either be in the current directory or, on + * some operating systems, in some standard place, for instance on the + * PATH. Hence, to be absolutely sure to get the correct module, + * always pass in a directory. The file name consists of the directory, + * if supplied, and 'module_name' suitably decorated according to + * the operating system's conventions (for instance lib*.so or *.dll). + * + * No checks are made that the file exists, or is of correct type. + */ +GLIB_AVAILABLE_IN_ALL +gchar* g_module_build_path (const gchar *directory, + const gchar *module_name); + +G_END_DECLS + +#endif /* __GMODULE_H__ */ diff --git a/gmodule/gmodule.rc.in b/gmodule/gmodule.rc.in new file mode 100644 index 0000000..c3d762d --- /dev/null +++ b/gmodule/gmodule.rc.in @@ -0,0 +1,30 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + FILEFLAGSMASK 0 + FILEFLAGS 0 + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "The GLib developer community" + VALUE "FileDescription", "GModule" + VALUE "FileVersion", "@GLIB_VERSION@.0" + VALUE "InternalName", "libgmodule-2.0-@LT_CURRENT_MINUS_AGE@" + VALUE "LegalCopyright", "Copyright 1998-2011 Tim Janik and others." + VALUE "OriginalFilename", "libgmodule-2.0-@LT_CURRENT_MINUS_AGE@.dll" + VALUE "ProductName", "GLib" + VALUE "ProductVersion", "@GLIB_VERSION@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END + END diff --git a/gmodule/gmoduleconf.h.in b/gmodule/gmoduleconf.h.in new file mode 100644 index 0000000..39d6707 --- /dev/null +++ b/gmodule/gmoduleconf.h.in @@ -0,0 +1,48 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#ifndef __G_MODULE_CONF_H__ +#define __G_MODULE_CONF_H__ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define G_MODULE_IMPL_NONE 0 +#define G_MODULE_IMPL_DL 1 +#define G_MODULE_IMPL_WIN32 3 +#define G_MODULE_IMPL_AR 7 + +#define G_MODULE_IMPL @G_MODULE_IMPL@ +#undef G_MODULE_HAVE_DLERROR +#if (@G_MODULE_HAVE_DLERROR@) +#define G_MODULE_HAVE_DLERROR +#endif +#if (@G_MODULE_NEED_USCORE@) +#define G_MODULE_NEED_USCORE +#endif +#if (@G_MODULE_BROKEN_RTLD_GLOBAL@) +#define G_MODULE_BROKEN_RTLD_GLOBAL +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __G_MODULE_CONF_H__ */ diff --git a/gmodule/meson.build b/gmodule/meson.build new file mode 100644 index 0000000..e4c1023 --- /dev/null +++ b/gmodule/meson.build @@ -0,0 +1,137 @@ +gmoduleconf_conf = configuration_data() + +g_module_need_uscore = 0 +g_module_broken_rtld_global = 0 +g_module_have_dlerror = 0 + +g_module_impl = '' + +# On Windows force native WIN32 shared lib loader +if host_system == 'windows' + g_module_impl = 'G_MODULE_IMPL_WIN32' +# Force native AIX library loader +# dlopen() filepath must be of the form /path/libname.a(libname.so) +elif host_system == 'aix' + g_module_impl = 'G_MODULE_IMPL_AR' +elif have_dlopen_dlsym + g_module_impl = 'G_MODULE_IMPL_DL' +endif + +# additional checks for G_MODULE_IMPL_DL +if g_module_impl == 'G_MODULE_IMPL_DL' + # FIXME: check for OSF1/5.0 RTLD_GLOBAL brokenness (is this still relevant?) + + # Check whether we need preceding underscores + if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' + message('Building for MSVC: assuming that symbols are prefixed with underscore') + g_module_need_uscore = 1 + elif meson.has_exe_wrapper() + # FIXME: communicate result via stdout instead of return value, so non-0 return is not printed in bold red + rres = cc.run(dlopen_dlsym_test_code, + dependencies : libdl_dep, + name : 'dlsym() preceding underscores') + if host_system == 'windows' or (rres.compiled() and rres.returncode() == 0) + g_module_need_uscore = 1 + endif + else + message('Cross-compiling: assuming that symbols aren\'t prefixed with underscore') + g_module_need_uscore = 0 + endif + + if cc.has_function('dlerror', dependencies : libdl_dep) + g_module_have_dlerror = 1 + endif +endif + +# Done, have we got an implementation? +if g_module_impl == '' + g_module_impl = '0' + message('WARNING: No suitable GModule implementation found!') +endif + +gmoduleconf_conf.set('G_MODULE_IMPL', g_module_impl) +gmoduleconf_conf.set('G_MODULE_SUPPORTED', g_module_impl != '0') +gmoduleconf_conf.set('G_MODULE_HAVE_DLERROR', g_module_have_dlerror) +gmoduleconf_conf.set('G_MODULE_NEED_USCORE', g_module_need_uscore) +gmoduleconf_conf.set('G_MODULE_BROKEN_RTLD_GLOBAL', g_module_broken_rtld_global) + +gmoduleconf_h = configure_file(input : 'gmoduleconf.h.in', + output : 'gmoduleconf.h', + configuration : gmoduleconf_conf) + +# Expose as variable to be used by gobject-introspection +# when it includes GLib as a subproject +gmodule_h = files('gmodule.h') +gmodule_c = files('gmodule.c') + +install_headers([gmodule_h], subdir : 'glib-2.0') + +gmodule_sources = [gmodule_c] +if host_system == 'windows' + gmodule_win_rc = configure_file( + input: 'gmodule.rc.in', + output: 'gmodule.rc', + configuration: glibconfig_conf, + ) + gmodule_win_res = windows.compile_resources(gmodule_win_rc) + gmodule_sources += [gmodule_win_res] +endif + +libgmodule = library('gmodule-2.0', + sources : gmodule_sources, + version : library_version, + soversion : soversion, + darwin_versions : darwin_versions, + install : true, + include_directories : [configinc, gmoduleinc], + dependencies : [libdl_dep, libglib_dep], + c_args : ['-DG_LOG_DOMAIN="GModule"'] + glib_hidden_visibility_args, + link_args : [glib_link_flags], +) + +supported_var = 'gmodule_supported=@0@'.format(g_module_impl != '0') + +pkg.generate(libgmodule, + libraries : [thread_dep], + requires : ['glib-2.0'], + version : glib_version, + variables : [supported_var], + install_dir : glib_pkgconfigreldir, + filebase : 'gmodule-no-export-2.0', + name : 'GModule', + description : 'Dynamic module loader for GLib', +) + +pkg.generate(libraries : [libgmodule, export_dynamic_ldflags], + requires : ['glib-2.0'], + version : glib_version, + variables : [supported_var], + install_dir : glib_pkgconfigreldir, + filebase : 'gmodule-export-2.0', + name : 'GModule', + description : 'Dynamic module loader for GLib', +) + +pkg.generate(libraries : [libgmodule, export_dynamic_ldflags], + requires : ['glib-2.0'], + version : glib_version, + variables : [supported_var], + install_dir : glib_pkgconfigreldir, + filebase : 'gmodule-2.0', + name : 'GModule', + description : 'Dynamic module loader for GLib', +) + +libgmodule_dep = declare_dependency(link_with : libgmodule, + include_directories : [gmoduleinc], + dependencies : [libglib_dep]) + +if meson.version().version_compare('>=0.54.0') + meson.override_dependency('gmodule-no-export-2.0', libgmodule_dep) + meson.override_dependency('gmodule-export-2.0', libgmodule_dep) + meson.override_dependency('gmodule-2.0', libgmodule_dep) +endif + +if build_tests + subdir('tests') +endif diff --git a/gmodule/tests/cxx.cpp b/gmodule/tests/cxx.cpp new file mode 100644 index 0000000..85242c5 --- /dev/null +++ b/gmodule/tests/cxx.cpp @@ -0,0 +1,26 @@ +/* Copyright (C) 2001 Sebastian Wilhelmi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +/* A trivial C++ program to be compiled in C++ mode, which + * smoketests that the GModule headers are valid C++ headers. */ + +#include + +int +main () +{ + return 0; +} diff --git a/gmodule/tests/meson.build b/gmodule/tests/meson.build new file mode 100644 index 0000000..b6f1cca --- /dev/null +++ b/gmodule/tests/meson.build @@ -0,0 +1,47 @@ +if have_cxx + gmodule_tests = { + 'cxx' : { + 'source' : ['cxx.cpp'], + }, + } +endif + +test_env = environment() +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +test_env.set('G_DEBUG', 'gc-friendly') +test_env.set('MALLOC_CHECK_', '2') +test_env.set('MALLOC_PERTURB_', '@0@'.format(random_number % 256)) + +test_deps = [libm, thread_dep, libglib_dep, libgmodule_dep] +test_cargs = ['-DG_LOG_DOMAIN="GModule"', '-UG_DISABLE_ASSERT'] + +foreach test_name, extra_args : gmodule_tests + source = extra_args.get('source', test_name + '.c') + install = installed_tests_enabled and extra_args.get('install', true) + + if install + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_conf.set('env', '') + configure_file( + input: installed_tests_template_tap, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf + ) + endif + + exe = executable(test_name, source, + c_args : test_cargs + extra_args.get('c_args', []), + link_args : extra_args.get('link_args', []), + dependencies : test_deps + extra_args.get('dependencies', []), + install_dir: installed_tests_execdir, + install: install, + ) + + suite = ['gmodule'] + extra_args.get('suite', []) + timeout = suite.contains('slow') ? test_timeout_slow : test_timeout + test(test_name, exe, env : test_env, timeout : timeout, suite : suite) +endforeach diff --git a/gobject/gatomicarray.c b/gobject/gatomicarray.c new file mode 100644 index 0000000..43111e8 --- /dev/null +++ b/gobject/gatomicarray.c @@ -0,0 +1,172 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2009 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "../glib/gvalgrind.h" +#include + +#include "gatomicarray.h" + +/* A GAtomicArray is a growable, mutable array of data + * generally of the form of a header of a specific size and + * then an array of items of a fixed size. + * + * It is possible to do lock-less read transactions from the + * array without any protection against other reads or writes, + * but such read operation must be aware that the data in the + * atomic array can change at any time during the transaction, + * and only at the end can we verify if the transaction succeeded + * or not. Thus the reading transaction cannot for instance + * dereference a pointer in the array inside the transaction. + * + * The size of an array however cannot change during a read + * transaction. + * + * Writes to the array is done in a copy-update style, but there + * is no real protection against multiple writers overwriting each + * others updates, so writes must be protected by an external lock. + */ + +G_LOCK_DEFINE_STATIC (array); + +typedef struct _FreeListNode FreeListNode; +struct _FreeListNode { + FreeListNode *next; +}; + +/* This is really a list of array memory blocks, using the + * first item as the next pointer to chain them together. + * Protected by array lock */ +static FreeListNode *freelist = NULL; + +/* must hold array lock */ +static gpointer +freelist_alloc (gsize size, gboolean reuse) +{ + gpointer mem; + FreeListNode *free, **prev; + gsize real_size; + + if (reuse) + { + for (free = freelist, prev = &freelist; free != NULL; prev = &free->next, free = free->next) + { + if (G_ATOMIC_ARRAY_DATA_SIZE (free) == size) + { + *prev = free->next; + return (gpointer)free; + } + } + } + + real_size = sizeof (gsize) + MAX (size, sizeof (FreeListNode)); + mem = g_slice_alloc (real_size); + mem = ((char *) mem) + sizeof (gsize); + G_ATOMIC_ARRAY_DATA_SIZE (mem) = size; + +#if ENABLE_VALGRIND + VALGRIND_MALLOCLIKE_BLOCK (mem, real_size - sizeof (gsize), FALSE, FALSE); +#endif + + return mem; +} + +/* must hold array lock */ +static void +freelist_free (gpointer mem) +{ + FreeListNode *free; + + free = mem; + free->next = freelist; + freelist = free; +} + +void +_g_atomic_array_init (GAtomicArray *array) +{ + array->data = NULL; +} + +/* Get a copy of the data (if non-NULL) that + * can be changed and then re-applied with + * g_atomic_array_update(). + * + * If additional_element_size is > 0 then + * then the new memory chunk is that much + * larger, or there were no data we return + * a chunk of header_size + additional_element_size. + * This means you can use this to grow the + * array part and it handles the first element + * being added automatically. + * + * We don't support shrinking arrays, as if + * we then re-grow we may reuse an old pointer + * value and confuse the transaction check. + */ +gpointer +_g_atomic_array_copy (GAtomicArray *array, + gsize header_size, + gsize additional_element_size) +{ + guint8 *new, *old; + gsize old_size, new_size; + + G_LOCK (array); + old = g_atomic_pointer_get (&array->data); + if (old) + { + old_size = G_ATOMIC_ARRAY_DATA_SIZE (old); + new_size = old_size + additional_element_size; + /* Don't reuse if copying to same size, as this may end + up reusing the same pointer for the same array thus + confusing the transaction check */ + new = freelist_alloc (new_size, additional_element_size != 0); + memcpy (new, old, old_size); + } + else if (additional_element_size != 0) + { + new_size = header_size + additional_element_size; + new = freelist_alloc (new_size, TRUE); + } + else + new = NULL; + G_UNLOCK (array); + return new; +} + +/* Replace the data in the array with the new data, + * freeing the old data (for reuse). The new data may + * not be smaller than the current data. + */ +void +_g_atomic_array_update (GAtomicArray *array, + gpointer new_data) +{ + guint8 *old; + + G_LOCK (array); + old = g_atomic_pointer_get (&array->data); + + g_assert (old == NULL || G_ATOMIC_ARRAY_DATA_SIZE (old) <= G_ATOMIC_ARRAY_DATA_SIZE (new_data)); + + g_atomic_pointer_set (&array->data, new_data); + if (old) + freelist_free (old); + G_UNLOCK (array); +} diff --git a/gobject/gatomicarray.h b/gobject/gatomicarray.h new file mode 100644 index 0000000..89043c5 --- /dev/null +++ b/gobject/gatomicarray.h @@ -0,0 +1,58 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2009 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_ATOMIC_ARRAY_H__ +#define __G_ATOMIC_ARRAY_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_ATOMIC_ARRAY_DATA_SIZE(mem) (*((gsize *) (mem) - 1)) + +typedef struct _GAtomicArray GAtomicArray; +struct _GAtomicArray { + gpointer data; /* elements - atomic */ +}; + +void _g_atomic_array_init (GAtomicArray *array); +gpointer _g_atomic_array_copy (GAtomicArray *array, + gsize header_size, + gsize additional_element_size); +void _g_atomic_array_update (GAtomicArray *array, + gpointer new_data); + +#define G_ATOMIC_ARRAY_GET_LOCKED(_array, _type) ((_type *)((_array)->data)) + +#define G_ATOMIC_ARRAY_DO_TRANSACTION(_array, _type, _C_) G_STMT_START { \ + gpointer *_datap = &(_array)->data; \ + _type *transaction_data, *__check; \ + \ + __check = g_atomic_pointer_get (_datap); \ + do { \ + transaction_data = __check; \ + {_C_;} \ + __check = g_atomic_pointer_get (_datap); \ + } while (transaction_data != __check); \ + } G_STMT_END + +G_END_DECLS + +#endif /* __G_ATOMIC_ARRAY_H__ */ diff --git a/gobject/gbinding.c b/gobject/gbinding.c new file mode 100644 index 0000000..a0b5de1 --- /dev/null +++ b/gobject/gbinding.c @@ -0,0 +1,1637 @@ +/* gbinding.c: Binding for object properties + * + * Copyright (C) 2010 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Emmanuele Bassi + */ + +/** + * SECTION:gbinding + * @Title: GBinding + * @Short_Description: Bind two object properties + * + * #GBinding is the representation of a binding between a property on a + * #GObject instance (or source) and another property on another #GObject + * instance (or target). + * + * Whenever the source property changes, the same value is applied to the + * target property; for instance, the following binding: + * + * |[ + * g_object_bind_property (object1, "property-a", + * object2, "property-b", + * G_BINDING_DEFAULT); + * ]| + * + * will cause the property named "property-b" of @object2 to be updated + * every time g_object_set() or the specific accessor changes the value of + * the property "property-a" of @object1. + * + * It is possible to create a bidirectional binding between two properties + * of two #GObject instances, so that if either property changes, the + * other is updated as well, for instance: + * + * |[ + * g_object_bind_property (object1, "property-a", + * object2, "property-b", + * G_BINDING_BIDIRECTIONAL); + * ]| + * + * will keep the two properties in sync. + * + * It is also possible to set a custom transformation function (in both + * directions, in case of a bidirectional binding) to apply a custom + * transformation from the source value to the target value before + * applying it; for instance, the following binding: + * + * |[ + * g_object_bind_property_full (adjustment1, "value", + * adjustment2, "value", + * G_BINDING_BIDIRECTIONAL, + * celsius_to_fahrenheit, + * fahrenheit_to_celsius, + * NULL, NULL); + * ]| + * + * will keep the "value" property of the two adjustments in sync; the + * @celsius_to_fahrenheit function will be called whenever the "value" + * property of @adjustment1 changes and will transform the current value + * of the property before applying it to the "value" property of @adjustment2. + * + * Vice versa, the @fahrenheit_to_celsius function will be called whenever + * the "value" property of @adjustment2 changes, and will transform the + * current value of the property before applying it to the "value" property + * of @adjustment1. + * + * Note that #GBinding does not resolve cycles by itself; a cycle like + * + * |[ + * object1:propertyA -> object2:propertyB + * object2:propertyB -> object3:propertyC + * object3:propertyC -> object1:propertyA + * ]| + * + * might lead to an infinite loop. The loop, in this particular case, + * can be avoided if the objects emit the #GObject::notify signal only + * if the value has effectively been changed. A binding is implemented + * using the #GObject::notify signal, so it is susceptible to all the + * various ways of blocking a signal emission, like g_signal_stop_emission() + * or g_signal_handler_block(). + * + * A binding will be severed, and the resources it allocates freed, whenever + * either one of the #GObject instances it refers to are finalized, or when + * the #GBinding instance loses its last reference. + * + * Bindings for languages with garbage collection can use + * g_binding_unbind() to explicitly release a binding between the source + * and target properties, instead of relying on the last reference on the + * binding, source, and target instances to drop. + * + * #GBinding is available since GObject 2.26 + */ + +#include "config.h" + +#include + +#include "gbinding.h" +#include "genums.h" +#include "gmarshal.h" +#include "gobject.h" +#include "gsignal.h" +#include "gparamspecs.h" +#include "gvaluetypes.h" + +#include "glibintl.h" + + +GType +g_binding_flags_get_type (void) +{ + static gsize static_g_define_type_id = 0; + + if (g_once_init_enter (&static_g_define_type_id)) + { + static const GFlagsValue values[] = { + { G_BINDING_DEFAULT, "G_BINDING_DEFAULT", "default" }, + { G_BINDING_BIDIRECTIONAL, "G_BINDING_BIDIRECTIONAL", "bidirectional" }, + { G_BINDING_SYNC_CREATE, "G_BINDING_SYNC_CREATE", "sync-create" }, + { G_BINDING_INVERT_BOOLEAN, "G_BINDING_INVERT_BOOLEAN", "invert-boolean" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("GBindingFlags"), values); + g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + + return static_g_define_type_id; +} + +/* Reference counted helper struct that is passed to all callbacks to ensure + * that they never work with already freed objects without having to store + * strong references for them. + * + * Using strong references anywhere is not possible because of the API + * requirements of GBinding, specifically that the initial reference of the + * GBinding is owned by the source/target and the caller and can be released + * either by the source/target being finalized or calling g_binding_unbind(). + * + * As such, the only strong reference has to be owned by both weak notifies of + * the source and target and the first to be called has to release it. + */ +typedef struct { + GWeakRef binding; + GWeakRef source; + GWeakRef target; + gboolean binding_removed; +} BindingContext; + +static BindingContext * +binding_context_ref (BindingContext *context) +{ + return g_atomic_rc_box_acquire (context); +} + +static void +binding_context_clear (BindingContext *context) +{ + g_weak_ref_clear (&context->binding); + g_weak_ref_clear (&context->source); + g_weak_ref_clear (&context->target); +} + +static void +binding_context_unref (BindingContext *context) +{ + g_atomic_rc_box_release_full (context, (GDestroyNotify) binding_context_clear); +} + +/* Reference counting for the transform functions to ensure that they're always + * valid while making use of them in the property notify callbacks. + * + * The transform functions are released when unbinding but unbinding can happen + * while the transform functions are currently in use inside the notify callbacks. + */ +typedef struct { + GBindingTransformFunc transform_s2t; + GBindingTransformFunc transform_t2s; + + gpointer transform_data; + GDestroyNotify destroy_notify; +} TransformFunc; + +static TransformFunc * +transform_func_new (GBindingTransformFunc transform_s2t, + GBindingTransformFunc transform_t2s, + gpointer transform_data, + GDestroyNotify destroy_notify) +{ + TransformFunc *func = g_atomic_rc_box_new0 (TransformFunc); + + func->transform_s2t = transform_s2t; + func->transform_t2s = transform_t2s; + func->transform_data = transform_data; + func->destroy_notify = destroy_notify; + + return func; +} + +static TransformFunc * +transform_func_ref (TransformFunc *func) +{ + return g_atomic_rc_box_acquire (func); +} + +static void +transform_func_clear (TransformFunc *func) +{ + if (func->destroy_notify) + func->destroy_notify (func->transform_data); +} + +static void +transform_func_unref (TransformFunc *func) +{ + g_atomic_rc_box_release_full (func, (GDestroyNotify) transform_func_clear); +} + +#define G_BINDING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_BINDING, GBindingClass)) +#define G_IS_BINDING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_BINDING)) +#define G_BINDING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_BINDING, GBindingClass)) + +typedef struct _GBindingClass GBindingClass; + +struct _GBinding +{ + GObject parent_instance; + + /* no reference is held on the objects, to avoid cycles */ + BindingContext *context; + + /* protects transform_func, source, target property notify and + * target_weak_notify_installed for unbinding */ + GMutex unbind_lock; + + /* transform functions, only NULL after unbinding */ + TransformFunc *transform_func; /* LOCK: unbind_lock */ + + /* the property names are interned, so they should not be freed */ + const gchar *source_property; + const gchar *target_property; + + GParamSpec *source_pspec; + GParamSpec *target_pspec; + + GBindingFlags flags; + + guint source_notify; /* LOCK: unbind_lock */ + guint target_notify; /* LOCK: unbind_lock */ + gboolean target_weak_notify_installed; /* LOCK: unbind_lock */ + + /* a guard, to avoid loops */ + guint is_frozen : 1; +}; + +struct _GBindingClass +{ + GObjectClass parent_class; +}; + +enum +{ + PROP_0, + + PROP_SOURCE, + PROP_TARGET, + PROP_SOURCE_PROPERTY, + PROP_TARGET_PROPERTY, + PROP_FLAGS +}; + +static guint gobject_notify_signal_id; + +G_DEFINE_TYPE (GBinding, g_binding, G_TYPE_OBJECT) + +static void weak_unbind (gpointer user_data, GObject *where_the_object_was); + +/* Must be called with the unbind lock held, context/binding != NULL and strong + * references to source/target or NULL. + * Return TRUE if the binding was actually removed and FALSE if it was already + * removed before. */ +static gboolean +unbind_internal_locked (BindingContext *context, GBinding *binding, GObject *source, GObject *target) +{ + gboolean binding_was_removed = FALSE; + + g_assert (context != NULL); + g_assert (binding != NULL); + + /* If the target went away we still have a strong reference to the source + * here and can clear it from the binding. Otherwise if the source went away + * we can clear the target from the binding. Finalizing an object clears its + * signal handlers and all weak references pointing to it before calling + * weak notify callbacks. + * + * If both still exist we clean up everything set up by the binding. + */ + if (source) + { + /* We always add/remove the source property notify and the weak notify + * of the source at the same time, and should only ever do that once. */ + if (binding->source_notify != 0) + { + g_signal_handler_disconnect (source, binding->source_notify); + + g_object_weak_unref (source, weak_unbind, context); + binding_context_unref (context); + + binding->source_notify = 0; + } + g_weak_ref_set (&context->source, NULL); + } + + /* As above, but with the target. If source==target then no weak notify was + * installed for the target, which is why that is stored as a separate + * boolean inside the binding. */ + if (target) + { + /* There might be a target property notify without a weak notify on the + * target or the other way around, so these have to be handled + * independently here unlike for the source. */ + if (binding->target_notify != 0) + { + g_signal_handler_disconnect (target, binding->target_notify); + + binding->target_notify = 0; + } + g_weak_ref_set (&context->target, NULL); + + /* Remove the weak notify from the target, at most once */ + if (binding->target_weak_notify_installed) + { + g_object_weak_unref (target, weak_unbind, context); + binding_context_unref (context); + binding->target_weak_notify_installed = FALSE; + } + } + + /* Make sure to remove the binding only once and return to the caller that + * this was the call that actually removed it. */ + if (!context->binding_removed) + { + context->binding_removed = TRUE; + binding_was_removed = TRUE; + } + + return binding_was_removed; +} + +/* the basic assumption is that if either the source or the target + * goes away then the binding does not exist any more and it should + * be reaped as well. Each weak notify owns a strong reference to the + * binding that should be dropped here. */ +static void +weak_unbind (gpointer user_data, + GObject *where_the_object_was) +{ + BindingContext *context = user_data; + GBinding *binding; + GObject *source, *target; + gboolean binding_was_removed = FALSE; + TransformFunc *transform_func; + + binding = g_weak_ref_get (&context->binding); + if (!binding) + { + /* The binding was already destroyed before so there's nothing to do */ + binding_context_unref (context); + return; + } + + g_mutex_lock (&binding->unbind_lock); + + transform_func = g_steal_pointer (&binding->transform_func); + + source = g_weak_ref_get (&context->source); + target = g_weak_ref_get (&context->target); + + /* If this is called then either the source or target or both must be in the + * process of being disposed. If this happens as part of g_object_unref() + * then the weak references are actually cleared, otherwise if disposing + * happens as part of g_object_run_dispose() then they would still point to + * the disposed object. + * + * If the object this is being called for is either the source or the target + * and we actually got a strong reference to it nonetheless (see above), + * then signal handlers and weak notifies for it are already disconnected + * and they must not be disconnected a second time. Instead simply clear the + * weak reference and be done with it. + * + * See https://gitlab.gnome.org/GNOME/glib/-/issues/2266 */ + + if (source == where_the_object_was) + { + g_weak_ref_set (&context->source, NULL); + g_clear_object (&source); + } + + if (target == where_the_object_was) + { + g_weak_ref_set (&context->target, NULL); + g_clear_object (&target); + } + + binding_was_removed = unbind_internal_locked (context, binding, source, target); + + g_mutex_unlock (&binding->unbind_lock); + + /* Unref source, target and transform_func after the mutex is unlocked as it + * might release the last reference, which then accesses the mutex again */ + g_clear_object (&target); + g_clear_object (&source); + + g_clear_pointer (&transform_func, transform_func_unref); + + /* This releases the strong reference we got from the weak ref above */ + g_object_unref (binding); + + /* This will take care of the binding itself. */ + if (binding_was_removed) + g_object_unref (binding); + + /* Each weak notify owns a reference to the binding context. */ + binding_context_unref (context); +} + +static gboolean +default_transform (GBinding *binding, + const GValue *value_a, + GValue *value_b, + gpointer user_data G_GNUC_UNUSED) +{ + /* if it's not the same type, try to convert it using the GValue + * transformation API; otherwise just copy it + */ + if (!g_type_is_a (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b))) + { + /* are these two types compatible (can be directly copied)? */ + if (g_value_type_compatible (G_VALUE_TYPE (value_a), + G_VALUE_TYPE (value_b))) + { + g_value_copy (value_a, value_b); + return TRUE; + } + + if (g_value_type_transformable (G_VALUE_TYPE (value_a), + G_VALUE_TYPE (value_b))) + { + if (g_value_transform (value_a, value_b)) + return TRUE; + } + + g_warning ("%s: Unable to convert a value of type %s to a " + "value of type %s", + G_STRLOC, + g_type_name (G_VALUE_TYPE (value_a)), + g_type_name (G_VALUE_TYPE (value_b))); + + return FALSE; + } + + g_value_copy (value_a, value_b); + return TRUE; +} + +static gboolean +default_invert_boolean_transform (GBinding *binding, + const GValue *value_a, + GValue *value_b, + gpointer user_data G_GNUC_UNUSED) +{ + gboolean value; + + g_assert (G_VALUE_HOLDS_BOOLEAN (value_a)); + g_assert (G_VALUE_HOLDS_BOOLEAN (value_b)); + + value = g_value_get_boolean (value_a); + value = !value; + + g_value_set_boolean (value_b, value); + + return TRUE; +} + +static void +on_source_notify (GObject *source, + GParamSpec *pspec, + BindingContext *context) +{ + GBinding *binding; + GObject *target; + TransformFunc *transform_func; + GValue from_value = G_VALUE_INIT; + GValue to_value = G_VALUE_INIT; + gboolean res; + + binding = g_weak_ref_get (&context->binding); + if (!binding) + return; + + if (binding->is_frozen) + { + g_object_unref (binding); + return; + } + + target = g_weak_ref_get (&context->target); + if (!target) + { + g_object_unref (binding); + return; + } + + /* Get the transform function safely */ + g_mutex_lock (&binding->unbind_lock); + if (!binding->transform_func) + { + /* it was released already during unbinding, nothing to do here */ + g_mutex_unlock (&binding->unbind_lock); + return; + } + transform_func = transform_func_ref (binding->transform_func); + g_mutex_unlock (&binding->unbind_lock); + + g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec)); + g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec)); + + g_object_get_property (source, binding->source_pspec->name, &from_value); + + res = transform_func->transform_s2t (binding, + &from_value, + &to_value, + transform_func->transform_data); + + transform_func_unref (transform_func); + + if (res) + { + binding->is_frozen = TRUE; + + g_param_value_validate (binding->target_pspec, &to_value); + g_object_set_property (target, binding->target_pspec->name, &to_value); + + binding->is_frozen = FALSE; + } + + g_value_unset (&from_value); + g_value_unset (&to_value); + + g_object_unref (target); + g_object_unref (binding); +} + +static void +on_target_notify (GObject *target, + GParamSpec *pspec, + BindingContext *context) +{ + GBinding *binding; + GObject *source; + TransformFunc *transform_func; + GValue from_value = G_VALUE_INIT; + GValue to_value = G_VALUE_INIT; + gboolean res; + + binding = g_weak_ref_get (&context->binding); + if (!binding) + return; + + if (binding->is_frozen) + { + g_object_unref (binding); + return; + } + + source = g_weak_ref_get (&context->source); + if (!source) + { + g_object_unref (binding); + return; + } + + /* Get the transform function safely */ + g_mutex_lock (&binding->unbind_lock); + if (!binding->transform_func) + { + /* it was released already during unbinding, nothing to do here */ + g_mutex_unlock (&binding->unbind_lock); + return; + } + transform_func = transform_func_ref (binding->transform_func); + g_mutex_unlock (&binding->unbind_lock); + + g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec)); + g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec)); + + g_object_get_property (target, binding->target_pspec->name, &from_value); + + res = transform_func->transform_t2s (binding, + &from_value, + &to_value, + transform_func->transform_data); + transform_func_unref (transform_func); + + if (res) + { + binding->is_frozen = TRUE; + + g_param_value_validate (binding->source_pspec, &to_value); + g_object_set_property (source, binding->source_pspec->name, &to_value); + + binding->is_frozen = FALSE; + } + + g_value_unset (&from_value); + g_value_unset (&to_value); + + g_object_unref (source); + g_object_unref (binding); +} + +static inline void +g_binding_unbind_internal (GBinding *binding, + gboolean unref_binding) +{ + BindingContext *context = binding->context; + GObject *source, *target; + gboolean binding_was_removed = FALSE; + TransformFunc *transform_func; + + g_mutex_lock (&binding->unbind_lock); + + transform_func = g_steal_pointer (&binding->transform_func); + + source = g_weak_ref_get (&context->source); + target = g_weak_ref_get (&context->target); + + binding_was_removed = unbind_internal_locked (context, binding, source, target); + + g_mutex_unlock (&binding->unbind_lock); + + /* Unref source, target and transform_func after the mutex is unlocked as it + * might release the last reference, which then accesses the mutex again */ + g_clear_object (&target); + g_clear_object (&source); + + g_clear_pointer (&transform_func, transform_func_unref); + + if (binding_was_removed && unref_binding) + g_object_unref (binding); +} + +static void +g_binding_finalize (GObject *gobject) +{ + GBinding *binding = G_BINDING (gobject); + + g_binding_unbind_internal (binding, FALSE); + + binding_context_unref (binding->context); + + g_mutex_clear (&binding->unbind_lock); + + G_OBJECT_CLASS (g_binding_parent_class)->finalize (gobject); +} + +/* @key must have already been validated with is_valid() + * Modifies @key in place. */ +static void +canonicalize_key (gchar *key) +{ + gchar *p; + + for (p = key; *p != 0; p++) + { + gchar c = *p; + + if (c == '_') + *p = '-'; + } +} + +/* @key must have already been validated with is_valid() */ +static gboolean +is_canonical (const gchar *key) +{ + return (strchr (key, '_') == NULL); +} + +static gboolean +is_valid_property_name (const gchar *key) +{ + const gchar *p; + + /* First character must be a letter. */ + if ((key[0] < 'A' || key[0] > 'Z') && + (key[0] < 'a' || key[0] > 'z')) + return FALSE; + + for (p = key; *p != 0; p++) + { + const gchar c = *p; + + if (c != '-' && c != '_' && + (c < '0' || c > '9') && + (c < 'A' || c > 'Z') && + (c < 'a' || c > 'z')) + return FALSE; + } + + return TRUE; +} + +static void +g_binding_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GBinding *binding = G_BINDING (gobject); + + switch (prop_id) + { + case PROP_SOURCE: + g_weak_ref_set (&binding->context->source, g_value_get_object (value)); + break; + + case PROP_TARGET: + g_weak_ref_set (&binding->context->target, g_value_get_object (value)); + break; + + case PROP_SOURCE_PROPERTY: + case PROP_TARGET_PROPERTY: + { + gchar *name_copy = NULL; + const gchar *name = g_value_get_string (value); + const gchar **dest; + + /* Ensure the name we intern is canonical. */ + if (!is_canonical (name)) + { + name_copy = g_value_dup_string (value); + canonicalize_key (name_copy); + name = name_copy; + } + + if (prop_id == PROP_SOURCE_PROPERTY) + dest = &binding->source_property; + else + dest = &binding->target_property; + + *dest = g_intern_string (name); + + g_free (name_copy); + break; + } + + case PROP_FLAGS: + binding->flags = g_value_get_flags (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +g_binding_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GBinding *binding = G_BINDING (gobject); + + switch (prop_id) + { + case PROP_SOURCE: + g_value_take_object (value, g_weak_ref_get (&binding->context->source)); + break; + + case PROP_SOURCE_PROPERTY: + /* @source_property is interned, so we don’t need to take a copy */ + g_value_set_interned_string (value, binding->source_property); + break; + + case PROP_TARGET: + g_value_take_object (value, g_weak_ref_get (&binding->context->target)); + break; + + case PROP_TARGET_PROPERTY: + /* @target_property is interned, so we don’t need to take a copy */ + g_value_set_interned_string (value, binding->target_property); + break; + + case PROP_FLAGS: + g_value_set_flags (value, binding->flags); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +g_binding_constructed (GObject *gobject) +{ + GBinding *binding = G_BINDING (gobject); + GBindingTransformFunc transform_func = default_transform; + GObject *source, *target; + GQuark source_property_detail; + GClosure *source_notify_closure; + + /* assert that we were constructed correctly */ + source = g_weak_ref_get (&binding->context->source); + target = g_weak_ref_get (&binding->context->target); + g_assert (source != NULL); + g_assert (target != NULL); + g_assert (binding->source_property != NULL); + g_assert (binding->target_property != NULL); + + /* we assume a check was performed prior to construction - since + * g_object_bind_property_full() does it; we cannot fail construction + * anyway, so it would be hard for use to properly warn here + */ + binding->source_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), binding->source_property); + binding->target_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), binding->target_property); + g_assert (binding->source_pspec != NULL); + g_assert (binding->target_pspec != NULL); + + /* switch to the invert boolean transform if needed */ + if (binding->flags & G_BINDING_INVERT_BOOLEAN) + transform_func = default_invert_boolean_transform; + + /* set the default transformation functions here */ + binding->transform_func = transform_func_new (transform_func, transform_func, NULL, NULL); + + source_property_detail = g_quark_from_string (binding->source_property); + source_notify_closure = g_cclosure_new (G_CALLBACK (on_source_notify), + binding_context_ref (binding->context), + (GClosureNotify) binding_context_unref); + binding->source_notify = g_signal_connect_closure_by_id (source, + gobject_notify_signal_id, + source_property_detail, + source_notify_closure, + FALSE); + + g_object_weak_ref (source, weak_unbind, binding_context_ref (binding->context)); + + if (binding->flags & G_BINDING_BIDIRECTIONAL) + { + GQuark target_property_detail; + GClosure *target_notify_closure; + + target_property_detail = g_quark_from_string (binding->target_property); + target_notify_closure = g_cclosure_new (G_CALLBACK (on_target_notify), + binding_context_ref (binding->context), + (GClosureNotify) binding_context_unref); + binding->target_notify = g_signal_connect_closure_by_id (target, + gobject_notify_signal_id, + target_property_detail, + target_notify_closure, + FALSE); + } + + if (target != source) + { + g_object_weak_ref (target, weak_unbind, binding_context_ref (binding->context)); + + /* Need to remember separately if a target weak notify was installed as + * unlike for the source it can exist independently of the property + * notification callback */ + binding->target_weak_notify_installed = TRUE; + } + + g_object_unref (source); + g_object_unref (target); +} + +static void +g_binding_class_init (GBindingClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_notify_signal_id = g_signal_lookup ("notify", G_TYPE_OBJECT); + g_assert (gobject_notify_signal_id != 0); + + gobject_class->constructed = g_binding_constructed; + gobject_class->set_property = g_binding_set_property; + gobject_class->get_property = g_binding_get_property; + gobject_class->finalize = g_binding_finalize; + + /** + * GBinding:source: + * + * The #GObject that should be used as the source of the binding + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, PROP_SOURCE, + g_param_spec_object ("source", + P_("Source"), + P_("The source of the binding"), + G_TYPE_OBJECT, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GBinding:target: + * + * The #GObject that should be used as the target of the binding + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, PROP_TARGET, + g_param_spec_object ("target", + P_("Target"), + P_("The target of the binding"), + G_TYPE_OBJECT, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GBinding:source-property: + * + * The name of the property of #GBinding:source that should be used + * as the source of the binding. + * + * This should be in [canonical form][canonical-parameter-names] to get the + * best performance. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, PROP_SOURCE_PROPERTY, + g_param_spec_string ("source-property", + P_("Source Property"), + P_("The property on the source to bind"), + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GBinding:target-property: + * + * The name of the property of #GBinding:target that should be used + * as the target of the binding. + * + * This should be in [canonical form][canonical-parameter-names] to get the + * best performance. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, PROP_TARGET_PROPERTY, + g_param_spec_string ("target-property", + P_("Target Property"), + P_("The property on the target to bind"), + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * GBinding:flags: + * + * Flags to be used to control the #GBinding + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, PROP_FLAGS, + g_param_spec_flags ("flags", + P_("Flags"), + P_("The binding flags"), + G_TYPE_BINDING_FLAGS, + G_BINDING_DEFAULT, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +g_binding_init (GBinding *binding) +{ + g_mutex_init (&binding->unbind_lock); + + binding->context = g_atomic_rc_box_new0 (BindingContext); + g_weak_ref_init (&binding->context->binding, binding); + g_weak_ref_init (&binding->context->source, NULL); + g_weak_ref_init (&binding->context->target, NULL); +} + +/** + * g_binding_get_flags: + * @binding: a #GBinding + * + * Retrieves the flags passed when constructing the #GBinding. + * + * Returns: the #GBindingFlags used by the #GBinding + * + * Since: 2.26 + */ +GBindingFlags +g_binding_get_flags (GBinding *binding) +{ + g_return_val_if_fail (G_IS_BINDING (binding), G_BINDING_DEFAULT); + + return binding->flags; +} + +/** + * g_binding_get_source: + * @binding: a #GBinding + * + * Retrieves the #GObject instance used as the source of the binding. + * + * A #GBinding can outlive the source #GObject as the binding does not hold a + * strong reference to the source. If the source is destroyed before the + * binding then this function will return %NULL. + * + * Use g_binding_dup_source() if the source or binding are used from different + * threads as otherwise the pointer returned from this function might become + * invalid if the source is finalized from another thread in the meantime. + * + * Returns: (transfer none) (nullable): the source #GObject, or %NULL if the + * source does not exist any more. + * + * Deprecated: 2.68: Use g_binding_dup_source() for a safer version of this + * function. + * + * Since: 2.26 + */ +GObject * +g_binding_get_source (GBinding *binding) +{ + GObject *source; + + g_return_val_if_fail (G_IS_BINDING (binding), NULL); + + source = g_weak_ref_get (&binding->context->source); + /* Unref here, this API is not thread-safe + * FIXME: Remove this API when we next break API */ + if (source) + g_object_unref (source); + + return source; +} + +/** + * g_binding_dup_source: + * @binding: a #GBinding + * + * Retrieves the #GObject instance used as the source of the binding. + * + * A #GBinding can outlive the source #GObject as the binding does not hold a + * strong reference to the source. If the source is destroyed before the + * binding then this function will return %NULL. + * + * Returns: (transfer full) (nullable): the source #GObject, or %NULL if the + * source does not exist any more. + * + * Since: 2.68 + */ +GObject * +g_binding_dup_source (GBinding *binding) +{ + g_return_val_if_fail (G_IS_BINDING (binding), NULL); + + return g_weak_ref_get (&binding->context->source); +} + +/** + * g_binding_get_target: + * @binding: a #GBinding + * + * Retrieves the #GObject instance used as the target of the binding. + * + * A #GBinding can outlive the target #GObject as the binding does not hold a + * strong reference to the target. If the target is destroyed before the + * binding then this function will return %NULL. + * + * Use g_binding_dup_target() if the target or binding are used from different + * threads as otherwise the pointer returned from this function might become + * invalid if the target is finalized from another thread in the meantime. + * + * Returns: (transfer none) (nullable): the target #GObject, or %NULL if the + * target does not exist any more. + * + * Deprecated: 2.68: Use g_binding_dup_target() for a safer version of this + * function. + * + * Since: 2.26 + */ +GObject * +g_binding_get_target (GBinding *binding) +{ + GObject *target; + + g_return_val_if_fail (G_IS_BINDING (binding), NULL); + + target = g_weak_ref_get (&binding->context->target); + /* Unref here, this API is not thread-safe + * FIXME: Remove this API when we next break API */ + if (target) + g_object_unref (target); + + return target; +} + +/** + * g_binding_dup_target: + * @binding: a #GBinding + * + * Retrieves the #GObject instance used as the target of the binding. + * + * A #GBinding can outlive the target #GObject as the binding does not hold a + * strong reference to the target. If the target is destroyed before the + * binding then this function will return %NULL. + * + * Returns: (transfer full) (nullable): the target #GObject, or %NULL if the + * target does not exist any more. + * + * Since: 2.68 + */ +GObject * +g_binding_dup_target (GBinding *binding) +{ + g_return_val_if_fail (G_IS_BINDING (binding), NULL); + + return g_weak_ref_get (&binding->context->target); +} + +/** + * g_binding_get_source_property: + * @binding: a #GBinding + * + * Retrieves the name of the property of #GBinding:source used as the source + * of the binding. + * + * Returns: the name of the source property + * + * Since: 2.26 + */ +const gchar * +g_binding_get_source_property (GBinding *binding) +{ + g_return_val_if_fail (G_IS_BINDING (binding), NULL); + + return binding->source_property; +} + +/** + * g_binding_get_target_property: + * @binding: a #GBinding + * + * Retrieves the name of the property of #GBinding:target used as the target + * of the binding. + * + * Returns: the name of the target property + * + * Since: 2.26 + */ +const gchar * +g_binding_get_target_property (GBinding *binding) +{ + g_return_val_if_fail (G_IS_BINDING (binding), NULL); + + return binding->target_property; +} + +/** + * g_binding_unbind: + * @binding: a #GBinding + * + * Explicitly releases the binding between the source and the target + * property expressed by @binding. + * + * This function will release the reference that is being held on + * the @binding instance if the binding is still bound; if you want to hold on + * to the #GBinding instance after calling g_binding_unbind(), you will need + * to hold a reference to it. + * + * Note however that this function does not take ownership of @binding, it + * only unrefs the reference that was initially created by + * g_object_bind_property() and is owned by the binding. + * + * Since: 2.38 + */ +void +g_binding_unbind (GBinding *binding) +{ + g_return_if_fail (G_IS_BINDING (binding)); + + g_binding_unbind_internal (binding, TRUE); +} + +/** + * g_object_bind_property_full: + * @source: (type GObject.Object): the source #GObject + * @source_property: the property on @source to bind + * @target: (type GObject.Object): the target #GObject + * @target_property: the property on @target to bind + * @flags: flags to pass to #GBinding + * @transform_to: (scope notified) (nullable): the transformation function + * from the @source to the @target, or %NULL to use the default + * @transform_from: (scope notified) (nullable): the transformation function + * from the @target to the @source, or %NULL to use the default + * @user_data: custom data to be passed to the transformation functions, + * or %NULL + * @notify: (nullable): a function to call when disposing the binding, to free + * resources used by the transformation functions, or %NULL if not required + * + * Complete version of g_object_bind_property(). + * + * Creates a binding between @source_property on @source and @target_property + * on @target, allowing you to set the transformation functions to be used by + * the binding. + * + * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual: + * if @target_property on @target changes then the @source_property on @source + * will be updated as well. The @transform_from function is only used in case + * of bidirectional bindings, otherwise it will be ignored + * + * The binding will automatically be removed when either the @source or the + * @target instances are finalized. This will release the reference that is + * being held on the #GBinding instance; if you want to hold on to the + * #GBinding instance, you will need to hold a reference to it. + * + * To remove the binding, call g_binding_unbind(). + * + * A #GObject can have multiple bindings. + * + * The same @user_data parameter will be used for both @transform_to + * and @transform_from transformation functions; the @notify function will + * be called once, when the binding is removed. If you need different data + * for each transformation function, please use + * g_object_bind_property_with_closures() instead. + * + * Returns: (transfer none): the #GBinding instance representing the + * binding between the two #GObject instances. The binding is released + * whenever the #GBinding reference count reaches zero. + * + * Since: 2.26 + */ +GBinding * +g_object_bind_property_full (gpointer source, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + GBindingTransformFunc transform_to, + GBindingTransformFunc transform_from, + gpointer user_data, + GDestroyNotify notify) +{ + GParamSpec *pspec; + GBinding *binding; + + g_return_val_if_fail (G_IS_OBJECT (source), NULL); + g_return_val_if_fail (source_property != NULL, NULL); + g_return_val_if_fail (is_valid_property_name (source_property), NULL); + g_return_val_if_fail (G_IS_OBJECT (target), NULL); + g_return_val_if_fail (target_property != NULL, NULL); + g_return_val_if_fail (is_valid_property_name (target_property), NULL); + + if (source == target && g_strcmp0 (source_property, target_property) == 0) + { + g_warning ("Unable to bind the same property on the same instance"); + return NULL; + } + + /* remove the G_BINDING_INVERT_BOOLEAN flag in case we have + * custom transformation functions + */ + if ((flags & G_BINDING_INVERT_BOOLEAN) && + (transform_to != NULL || transform_from != NULL)) + { + flags &= ~G_BINDING_INVERT_BOOLEAN; + } + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), source_property); + if (pspec == NULL) + { + g_warning ("%s: The source object of type %s has no property called '%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (source), + source_property); + return NULL; + } + + if (!(pspec->flags & G_PARAM_READABLE)) + { + g_warning ("%s: The source object of type %s has no readable property called '%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (source), + source_property); + return NULL; + } + + if ((flags & G_BINDING_BIDIRECTIONAL) && + ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE))) + { + g_warning ("%s: The source object of type %s has no writable property called '%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (source), + source_property); + return NULL; + } + + if ((flags & G_BINDING_INVERT_BOOLEAN) && + !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)) + { + g_warning ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used " + "when binding boolean properties; the source property '%s' " + "is of type '%s'", + G_STRLOC, + source_property, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); + return NULL; + } + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), target_property); + if (pspec == NULL) + { + g_warning ("%s: The target object of type %s has no property called '%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (target), + target_property); + return NULL; + } + + if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE)) + { + g_warning ("%s: The target object of type %s has no writable property called '%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (target), + target_property); + return NULL; + } + + if ((flags & G_BINDING_BIDIRECTIONAL) && + !(pspec->flags & G_PARAM_READABLE)) + { + g_warning ("%s: The target object of type %s has no readable property called '%s'", + G_STRLOC, + G_OBJECT_TYPE_NAME (target), + target_property); + return NULL; + } + + if ((flags & G_BINDING_INVERT_BOOLEAN) && + !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)) + { + g_warning ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used " + "when binding boolean properties; the target property '%s' " + "is of type '%s'", + G_STRLOC, + target_property, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); + return NULL; + } + + binding = g_object_new (G_TYPE_BINDING, + "source", source, + "source-property", source_property, + "target", target, + "target-property", target_property, + "flags", flags, + NULL); + + g_assert (binding->transform_func != NULL); + + /* Use default functions if not provided here */ + if (transform_to == NULL) + transform_to = binding->transform_func->transform_s2t; + + if (transform_from == NULL) + transform_from = binding->transform_func->transform_t2s; + + g_clear_pointer (&binding->transform_func, transform_func_unref); + binding->transform_func = transform_func_new (transform_to, transform_from, user_data, notify); + + /* synchronize the target with the source by faking an emission of + * the ::notify signal for the source property; this will also take + * care of the bidirectional binding case because the eventual change + * will emit a notification on the target + */ + if (flags & G_BINDING_SYNC_CREATE) + on_source_notify (source, binding->source_pspec, binding->context); + + return binding; +} + +/** + * g_object_bind_property: + * @source: (type GObject.Object): the source #GObject + * @source_property: the property on @source to bind + * @target: (type GObject.Object): the target #GObject + * @target_property: the property on @target to bind + * @flags: flags to pass to #GBinding + * + * Creates a binding between @source_property on @source and @target_property + * on @target. + * + * Whenever the @source_property is changed the @target_property is + * updated using the same value. For instance: + * + * |[ + * g_object_bind_property (action, "active", widget, "sensitive", 0); + * ]| + * + * Will result in the "sensitive" property of the widget #GObject instance to be + * updated with the same value of the "active" property of the action #GObject + * instance. + * + * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual: + * if @target_property on @target changes then the @source_property on @source + * will be updated as well. + * + * The binding will automatically be removed when either the @source or the + * @target instances are finalized. To remove the binding without affecting the + * @source and the @target you can just call g_object_unref() on the returned + * #GBinding instance. + * + * Removing the binding by calling g_object_unref() on it must only be done if + * the binding, @source and @target are only used from a single thread and it + * is clear that both @source and @target outlive the binding. Especially it + * is not safe to rely on this if the binding, @source or @target can be + * finalized from different threads. Keep another reference to the binding and + * use g_binding_unbind() instead to be on the safe side. + * + * A #GObject can have multiple bindings. + * + * Returns: (transfer none): the #GBinding instance representing the + * binding between the two #GObject instances. The binding is released + * whenever the #GBinding reference count reaches zero. + * + * Since: 2.26 + */ +GBinding * +g_object_bind_property (gpointer source, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags) +{ + /* type checking is done in g_object_bind_property_full() */ + + return g_object_bind_property_full (source, source_property, + target, target_property, + flags, + NULL, + NULL, + NULL, NULL); +} + +typedef struct _TransformData +{ + GClosure *transform_to_closure; + GClosure *transform_from_closure; +} TransformData; + +static gboolean +bind_with_closures_transform_to (GBinding *binding, + const GValue *source, + GValue *target, + gpointer data) +{ + TransformData *t_data = data; + GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT }; + GValue retval = G_VALUE_INIT; + gboolean res; + + g_value_init (¶ms[0], G_TYPE_BINDING); + g_value_set_object (¶ms[0], binding); + + g_value_init (¶ms[1], G_TYPE_VALUE); + g_value_set_boxed (¶ms[1], source); + + g_value_init (¶ms[2], G_TYPE_VALUE); + g_value_set_boxed (¶ms[2], target); + + g_value_init (&retval, G_TYPE_BOOLEAN); + g_value_set_boolean (&retval, FALSE); + + g_closure_invoke (t_data->transform_to_closure, &retval, 3, params, NULL); + + res = g_value_get_boolean (&retval); + if (res) + { + const GValue *out_value = g_value_get_boxed (¶ms[2]); + + g_assert (out_value != NULL); + + g_value_copy (out_value, target); + } + + g_value_unset (¶ms[0]); + g_value_unset (¶ms[1]); + g_value_unset (¶ms[2]); + g_value_unset (&retval); + + return res; +} + +static gboolean +bind_with_closures_transform_from (GBinding *binding, + const GValue *source, + GValue *target, + gpointer data) +{ + TransformData *t_data = data; + GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT }; + GValue retval = G_VALUE_INIT; + gboolean res; + + g_value_init (¶ms[0], G_TYPE_BINDING); + g_value_set_object (¶ms[0], binding); + + g_value_init (¶ms[1], G_TYPE_VALUE); + g_value_set_boxed (¶ms[1], source); + + g_value_init (¶ms[2], G_TYPE_VALUE); + g_value_set_boxed (¶ms[2], target); + + g_value_init (&retval, G_TYPE_BOOLEAN); + g_value_set_boolean (&retval, FALSE); + + g_closure_invoke (t_data->transform_from_closure, &retval, 3, params, NULL); + + res = g_value_get_boolean (&retval); + if (res) + { + const GValue *out_value = g_value_get_boxed (¶ms[2]); + + g_assert (out_value != NULL); + + g_value_copy (out_value, target); + } + + g_value_unset (¶ms[0]); + g_value_unset (¶ms[1]); + g_value_unset (¶ms[2]); + g_value_unset (&retval); + + return res; +} + +static void +bind_with_closures_free_func (gpointer data) +{ + TransformData *t_data = data; + + if (t_data->transform_to_closure != NULL) + g_closure_unref (t_data->transform_to_closure); + + if (t_data->transform_from_closure != NULL) + g_closure_unref (t_data->transform_from_closure); + + g_slice_free (TransformData, t_data); +} + +/** + * g_object_bind_property_with_closures: (rename-to g_object_bind_property_full) + * @source: (type GObject.Object): the source #GObject + * @source_property: the property on @source to bind + * @target: (type GObject.Object): the target #GObject + * @target_property: the property on @target to bind + * @flags: flags to pass to #GBinding + * @transform_to: a #GClosure wrapping the transformation function + * from the @source to the @target, or %NULL to use the default + * @transform_from: a #GClosure wrapping the transformation function + * from the @target to the @source, or %NULL to use the default + * + * Creates a binding between @source_property on @source and @target_property + * on @target, allowing you to set the transformation functions to be used by + * the binding. + * + * This function is the language bindings friendly version of + * g_object_bind_property_full(), using #GClosures instead of + * function pointers. + * + * Returns: (transfer none): the #GBinding instance representing the + * binding between the two #GObject instances. The binding is released + * whenever the #GBinding reference count reaches zero. + * + * Since: 2.26 + */ +GBinding * +g_object_bind_property_with_closures (gpointer source, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + GClosure *transform_to, + GClosure *transform_from) +{ + TransformData *data; + + data = g_slice_new0 (TransformData); + + if (transform_to != NULL) + { + if (G_CLOSURE_NEEDS_MARSHAL (transform_to)) + g_closure_set_marshal (transform_to, g_cclosure_marshal_BOOLEAN__BOXED_BOXED); + + data->transform_to_closure = g_closure_ref (transform_to); + g_closure_sink (data->transform_to_closure); + } + + if (transform_from != NULL) + { + if (G_CLOSURE_NEEDS_MARSHAL (transform_from)) + g_closure_set_marshal (transform_from, g_cclosure_marshal_BOOLEAN__BOXED_BOXED); + + data->transform_from_closure = g_closure_ref (transform_from); + g_closure_sink (data->transform_from_closure); + } + + return g_object_bind_property_full (source, source_property, + target, target_property, + flags, + transform_to != NULL ? bind_with_closures_transform_to : NULL, + transform_from != NULL ? bind_with_closures_transform_from : NULL, + data, + bind_with_closures_free_func); +} diff --git a/gobject/gbinding.h b/gobject/gbinding.h new file mode 100644 index 0000000..2b25214 --- /dev/null +++ b/gobject/gbinding.h @@ -0,0 +1,154 @@ +/* gbinding.h: Binding for object properties + * + * Copyright (C) 2010 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Emmanuele Bassi + */ + +#ifndef __G_BINDING_H__ +#define __G_BINDING_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_BINDING_FLAGS (g_binding_flags_get_type ()) + +#define G_TYPE_BINDING (g_binding_get_type ()) +#define G_BINDING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_BINDING, GBinding)) +#define G_IS_BINDING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_BINDING)) + +/** + * GBinding: + * + * GBinding is an opaque structure whose members + * cannot be accessed directly. + * + * Since: 2.26 + */ +typedef struct _GBinding GBinding; + +/** + * GBindingTransformFunc: + * @binding: a #GBinding + * @from_value: the #GValue containing the value to transform + * @to_value: the #GValue in which to store the transformed value + * @user_data: data passed to the transform function + * + * A function to be called to transform @from_value to @to_value. + * + * If this is the @transform_to function of a binding, then @from_value + * is the @source_property on the @source object, and @to_value is the + * @target_property on the @target object. If this is the + * @transform_from function of a %G_BINDING_BIDIRECTIONAL binding, + * then those roles are reversed. + * + * Returns: %TRUE if the transformation was successful, and %FALSE + * otherwise + * + * Since: 2.26 + */ +typedef gboolean (* GBindingTransformFunc) (GBinding *binding, + const GValue *from_value, + GValue *to_value, + gpointer user_data); + +/** + * GBindingFlags: + * @G_BINDING_DEFAULT: The default binding; if the source property + * changes, the target property is updated with its value. + * @G_BINDING_BIDIRECTIONAL: Bidirectional binding; if either the + * property of the source or the property of the target changes, + * the other is updated. + * @G_BINDING_SYNC_CREATE: Synchronize the values of the source and + * target properties when creating the binding; the direction of + * the synchronization is always from the source to the target. + * @G_BINDING_INVERT_BOOLEAN: If the two properties being bound are + * booleans, setting one to %TRUE will result in the other being + * set to %FALSE and vice versa. This flag will only work for + * boolean properties, and cannot be used when passing custom + * transformation functions to g_object_bind_property_full(). + * + * Flags to be passed to g_object_bind_property() or + * g_object_bind_property_full(). + * + * This enumeration can be extended at later date. + * + * Since: 2.26 + */ +typedef enum { /*< prefix=G_BINDING >*/ + G_BINDING_DEFAULT = 0, + + G_BINDING_BIDIRECTIONAL = 1 << 0, + G_BINDING_SYNC_CREATE = 1 << 1, + G_BINDING_INVERT_BOOLEAN = 1 << 2 +} GBindingFlags; + +GLIB_AVAILABLE_IN_ALL +GType g_binding_flags_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_binding_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL +GBindingFlags g_binding_get_flags (GBinding *binding); +GLIB_DEPRECATED_IN_2_68_FOR(g_binding_dup_source) +GObject * g_binding_get_source (GBinding *binding); +GLIB_AVAILABLE_IN_2_68 +GObject * g_binding_dup_source (GBinding *binding); +GLIB_DEPRECATED_IN_2_68_FOR(g_binding_dup_target) +GObject * g_binding_get_target (GBinding *binding); +GLIB_AVAILABLE_IN_2_68 +GObject * g_binding_dup_target (GBinding *binding); +GLIB_AVAILABLE_IN_ALL +const gchar * g_binding_get_source_property (GBinding *binding); +GLIB_AVAILABLE_IN_ALL +const gchar * g_binding_get_target_property (GBinding *binding); +GLIB_AVAILABLE_IN_2_38 +void g_binding_unbind (GBinding *binding); + +GLIB_AVAILABLE_IN_ALL +GBinding *g_object_bind_property (gpointer source, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags); +GLIB_AVAILABLE_IN_ALL +GBinding *g_object_bind_property_full (gpointer source, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + GBindingTransformFunc transform_to, + GBindingTransformFunc transform_from, + gpointer user_data, + GDestroyNotify notify); +GLIB_AVAILABLE_IN_ALL +GBinding *g_object_bind_property_with_closures (gpointer source, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + GClosure *transform_to, + GClosure *transform_from); + +G_END_DECLS + +#endif /* __G_BINDING_H__ */ diff --git a/gobject/gbindinggroup.c b/gobject/gbindinggroup.c new file mode 100644 index 0000000..e5c8980 --- /dev/null +++ b/gobject/gbindinggroup.c @@ -0,0 +1,679 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * Copyright (C) 2015-2022 Christian Hergert + * Copyright (C) 2015 Garrett Regier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" +#include "glib.h" +#include "glibintl.h" + +#include "gbindinggroup.h" +#include "gparamspecs.h" + +/** + * SECTION:gbindinggroup + * @Title: GBindingGroup + * @Short_description: Binding multiple properties as a group + * @include: glib-object.h + * + * The #GBindingGroup can be used to bind multiple properties + * from an object collectively. + * + * Use the various methods to bind properties from a single source + * object to multiple destination objects. Properties can be bound + * bidirectionally and are connected when the source object is set + * with g_binding_group_set_source(). + * + * Since: 2.72 + */ + +#if 0 +# define DEBUG_BINDINGS +#endif + +struct _GBindingGroup +{ + GObject parent_instance; + GMutex mutex; + GObject *source; /* (owned weak) */ + GPtrArray *lazy_bindings; /* (owned) (element-type LazyBinding) */ +}; + +typedef struct _GBindingGroupClass +{ + GObjectClass parent_class; +} GBindingGroupClass; + +typedef struct +{ + GBindingGroup *group; /* (unowned) */ + const char *source_property; /* (interned) */ + const char *target_property; /* (interned) */ + GObject *target; /* (owned weak) */ + GBinding *binding; /* (unowned) */ + gpointer user_data; + GDestroyNotify user_data_destroy; + gpointer transform_to; /* (nullable) (owned) */ + gpointer transform_from; /* (nullable) (owned) */ + GBindingFlags binding_flags; + guint using_closures : 1; +} LazyBinding; + +G_DEFINE_TYPE (GBindingGroup, g_binding_group, G_TYPE_OBJECT) + +typedef enum +{ + PROP_SOURCE = 1, + N_PROPS +} GBindingGroupProperty; + +static void lazy_binding_free (gpointer data); + +static GParamSpec *properties[N_PROPS]; + +static void +g_binding_group_connect (GBindingGroup *self, + LazyBinding *lazy_binding) +{ + GBinding *binding; + + g_assert (G_IS_BINDING_GROUP (self)); + g_assert (self->source != NULL); + g_assert (lazy_binding != NULL); + g_assert (lazy_binding->binding == NULL); + g_assert (lazy_binding->target != NULL); + g_assert (lazy_binding->target_property != NULL); + g_assert (lazy_binding->source_property != NULL); + +#ifdef DEBUG_BINDINGS + { + GFlagsClass *flags_class; + g_autofree gchar *flags_str = NULL; + + flags_class = g_type_class_ref (G_TYPE_BINDING_FLAGS); + flags_str = g_flags_to_string (flags_class, lazy_binding->binding_flags); + + g_print ("Binding %s(%p):%s to %s(%p):%s (flags=%s)\n", + G_OBJECT_TYPE_NAME (self->source), + self->source, + lazy_binding->source_property, + G_OBJECT_TYPE_NAME (lazy_binding->target), + lazy_binding->target, + lazy_binding->target_property, + flags_str); + + g_type_class_unref (flags_class); + } +#endif + + if (!lazy_binding->using_closures) + binding = g_object_bind_property_full (self->source, + lazy_binding->source_property, + lazy_binding->target, + lazy_binding->target_property, + lazy_binding->binding_flags, + lazy_binding->transform_to, + lazy_binding->transform_from, + lazy_binding->user_data, + NULL); + else + binding = g_object_bind_property_with_closures (self->source, + lazy_binding->source_property, + lazy_binding->target, + lazy_binding->target_property, + lazy_binding->binding_flags, + lazy_binding->transform_to, + lazy_binding->transform_from); + + lazy_binding->binding = binding; +} + +static void +g_binding_group_disconnect (LazyBinding *lazy_binding) +{ + g_assert (lazy_binding != NULL); + + if (lazy_binding->binding != NULL) + { + g_binding_unbind (lazy_binding->binding); + lazy_binding->binding = NULL; + } +} + +static void +g_binding_group__source_weak_notify (gpointer data, + GObject *where_object_was) +{ + GBindingGroup *self = data; + guint i; + + g_assert (G_IS_BINDING_GROUP (self)); + + g_mutex_lock (&self->mutex); + + self->source = NULL; + + for (i = 0; i < self->lazy_bindings->len; i++) + { + LazyBinding *lazy_binding = g_ptr_array_index (self->lazy_bindings, i); + + lazy_binding->binding = NULL; + } + + g_mutex_unlock (&self->mutex); +} + +static void +g_binding_group__target_weak_notify (gpointer data, + GObject *where_object_was) +{ + GBindingGroup *self = data; + LazyBinding *to_free = NULL; + guint i; + + g_assert (G_IS_BINDING_GROUP (self)); + + g_mutex_lock (&self->mutex); + + for (i = 0; i < self->lazy_bindings->len; i++) + { + LazyBinding *lazy_binding = g_ptr_array_index (self->lazy_bindings, i); + + if (lazy_binding->target == where_object_was) + { + lazy_binding->target = NULL; + lazy_binding->binding = NULL; + + to_free = g_ptr_array_steal_index_fast (self->lazy_bindings, i); + break; + } + } + + g_mutex_unlock (&self->mutex); + + if (to_free != NULL) + lazy_binding_free (to_free); +} + +static void +lazy_binding_free (gpointer data) +{ + LazyBinding *lazy_binding = data; + + if (lazy_binding->target != NULL) + { + g_object_weak_unref (lazy_binding->target, + g_binding_group__target_weak_notify, + lazy_binding->group); + lazy_binding->target = NULL; + } + + g_binding_group_disconnect (lazy_binding); + + lazy_binding->group = NULL; + lazy_binding->source_property = NULL; + lazy_binding->target_property = NULL; + + if (lazy_binding->user_data_destroy) + lazy_binding->user_data_destroy (lazy_binding->user_data); + + if (lazy_binding->using_closures) + { + g_clear_pointer (&lazy_binding->transform_to, g_closure_unref); + g_clear_pointer (&lazy_binding->transform_from, g_closure_unref); + } + + g_slice_free (LazyBinding, lazy_binding); +} + +static void +g_binding_group_dispose (GObject *object) +{ + GBindingGroup *self = (GBindingGroup *)object; + LazyBinding **lazy_bindings = NULL; + gsize len = 0; + gsize i; + + g_assert (G_IS_BINDING_GROUP (self)); + + g_mutex_lock (&self->mutex); + + if (self->source != NULL) + { + g_object_weak_unref (self->source, + g_binding_group__source_weak_notify, + self); + self->source = NULL; + } + + if (self->lazy_bindings->len > 0) + lazy_bindings = (LazyBinding **)g_ptr_array_steal (self->lazy_bindings, &len); + + g_mutex_unlock (&self->mutex); + + /* Free bindings without holding self->mutex to avoid re-entrancy + * from collateral damage through release of binding closure data, + * GDataList, etc. + */ + for (i = 0; i < len; i++) + lazy_binding_free (lazy_bindings[i]); + g_free (lazy_bindings); + + G_OBJECT_CLASS (g_binding_group_parent_class)->dispose (object); +} + +static void +g_binding_group_finalize (GObject *object) +{ + GBindingGroup *self = (GBindingGroup *)object; + + g_assert (self->lazy_bindings != NULL); + g_assert (self->lazy_bindings->len == 0); + + g_clear_pointer (&self->lazy_bindings, g_ptr_array_unref); + g_mutex_clear (&self->mutex); + + G_OBJECT_CLASS (g_binding_group_parent_class)->finalize (object); +} + +static void +g_binding_group_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GBindingGroup *self = G_BINDING_GROUP (object); + + switch ((GBindingGroupProperty) prop_id) + { + case PROP_SOURCE: + g_value_take_object (value, g_binding_group_dup_source (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_binding_group_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GBindingGroup *self = G_BINDING_GROUP (object); + + switch ((GBindingGroupProperty) prop_id) + { + case PROP_SOURCE: + g_binding_group_set_source (self, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_binding_group_class_init (GBindingGroupClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = g_binding_group_dispose; + object_class->finalize = g_binding_group_finalize; + object_class->get_property = g_binding_group_get_property; + object_class->set_property = g_binding_group_set_property; + + /** + * GBindingGroup:source: (nullable) + * + * The source object used for binding properties. + * + * Since: 2.72 + */ + properties[PROP_SOURCE] = + g_param_spec_object ("source", + "Source", + "The source GObject used for binding properties.", + G_TYPE_OBJECT, + (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, N_PROPS, properties); +} + +static void +g_binding_group_init (GBindingGroup *self) +{ + g_mutex_init (&self->mutex); + self->lazy_bindings = g_ptr_array_new_with_free_func (lazy_binding_free); +} + +/** + * g_binding_group_new: + * + * Creates a new #GBindingGroup. + * + * Returns: (transfer full): a new #GBindingGroup + * + * Since: 2.72 + */ +GBindingGroup * +g_binding_group_new (void) +{ + return g_object_new (G_TYPE_BINDING_GROUP, NULL); +} + +/** + * g_binding_group_dup_source: + * @self: the #GBindingGroup + * + * Gets the source object used for binding properties. + * + * Returns: (transfer none) (nullable) (type GObject): a #GObject or %NULL. + * + * Since: 2.72 + */ +gpointer +g_binding_group_dup_source (GBindingGroup *self) +{ + GObject *source; + + g_return_val_if_fail (G_IS_BINDING_GROUP (self), NULL); + + g_mutex_lock (&self->mutex); + source = self->source ? g_object_ref (self->source) : NULL; + g_mutex_unlock (&self->mutex); + + return source; +} + +static gboolean +g_binding_group_check_source (GBindingGroup *self, + gpointer source) +{ + guint i; + + g_assert (G_IS_BINDING_GROUP (self)); + g_assert (!source || G_IS_OBJECT (source)); + + for (i = 0; i < self->lazy_bindings->len; i++) + { + LazyBinding *lazy_binding = g_ptr_array_index (self->lazy_bindings, i); + + g_return_val_if_fail (g_object_class_find_property (G_OBJECT_GET_CLASS (source), + lazy_binding->source_property) != NULL, + FALSE); + } + + return TRUE; +} + +/** + * g_binding_group_set_source: + * @self: the #GBindingGroup + * @source: (type GObject) (nullable) (transfer none): the source #GObject, + * or %NULL to clear it + * + * Sets @source as the source object used for creating property + * bindings. If there is already a source object all bindings from it + * will be removed. + * + * Note that all properties that have been bound must exist on @source. + * + * Since: 2.72 + */ +void +g_binding_group_set_source (GBindingGroup *self, + gpointer source) +{ + gboolean notify = FALSE; + + g_return_if_fail (G_IS_BINDING_GROUP (self)); + g_return_if_fail (!source || G_IS_OBJECT (source)); + g_return_if_fail (source != (gpointer) self); + + g_mutex_lock (&self->mutex); + + if (source == (gpointer) self->source) + goto unlock; + + if (self->source != NULL) + { + guint i; + + g_object_weak_unref (self->source, + g_binding_group__source_weak_notify, + self); + self->source = NULL; + + for (i = 0; i < self->lazy_bindings->len; i++) + { + LazyBinding *lazy_binding = g_ptr_array_index (self->lazy_bindings, i); + + g_binding_group_disconnect (lazy_binding); + } + } + + if (source != NULL && g_binding_group_check_source (self, source)) + { + guint i; + + self->source = source; + g_object_weak_ref (self->source, + g_binding_group__source_weak_notify, + self); + + for (i = 0; i < self->lazy_bindings->len; i++) + { + LazyBinding *lazy_binding; + + lazy_binding = g_ptr_array_index (self->lazy_bindings, i); + g_binding_group_connect (self, lazy_binding); + } + } + + notify = TRUE; + +unlock: + g_mutex_unlock (&self->mutex); + + if (notify) + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SOURCE]); +} + +static void +g_binding_group_bind_helper (GBindingGroup *self, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + gpointer transform_to, + gpointer transform_from, + gpointer user_data, + GDestroyNotify user_data_destroy, + gboolean using_closures) +{ + LazyBinding *lazy_binding; + + g_return_if_fail (G_IS_BINDING_GROUP (self)); + g_return_if_fail (source_property != NULL); + g_return_if_fail (self->source == NULL || + g_object_class_find_property (G_OBJECT_GET_CLASS (self->source), + source_property) != NULL); + g_return_if_fail (G_IS_OBJECT (target)); + g_return_if_fail (target_property != NULL); + g_return_if_fail (g_object_class_find_property (G_OBJECT_GET_CLASS (target), + target_property) != NULL); + g_return_if_fail (target != (gpointer) self || + strcmp (source_property, target_property) != 0); + + g_mutex_lock (&self->mutex); + + lazy_binding = g_slice_new0 (LazyBinding); + lazy_binding->group = self; + lazy_binding->source_property = g_intern_string (source_property); + lazy_binding->target_property = g_intern_string (target_property); + lazy_binding->target = target; + lazy_binding->binding_flags = flags | G_BINDING_SYNC_CREATE; + lazy_binding->user_data = user_data; + lazy_binding->user_data_destroy = user_data_destroy; + lazy_binding->transform_to = transform_to; + lazy_binding->transform_from = transform_from; + + if (using_closures) + { + lazy_binding->using_closures = TRUE; + + if (transform_to != NULL) + g_closure_sink (g_closure_ref (transform_to)); + + if (transform_from != NULL) + g_closure_sink (g_closure_ref (transform_from)); + } + + g_object_weak_ref (target, + g_binding_group__target_weak_notify, + self); + + g_ptr_array_add (self->lazy_bindings, lazy_binding); + + if (self->source != NULL) + g_binding_group_connect (self, lazy_binding); + + g_mutex_unlock (&self->mutex); +} + +/** + * g_binding_group_bind: + * @self: the #GBindingGroup + * @source_property: the property on the source to bind + * @target: (type GObject) (transfer none) (not nullable): the target #GObject + * @target_property: the property on @target to bind + * @flags: the flags used to create the #GBinding + * + * Creates a binding between @source_property on the source object + * and @target_property on @target. Whenever the @source_property + * is changed the @target_property is updated using the same value. + * The binding flag %G_BINDING_SYNC_CREATE is automatically specified. + * + * See g_object_bind_property() for more information. + * + * Since: 2.72 + */ +void +g_binding_group_bind (GBindingGroup *self, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags) +{ + g_binding_group_bind_full (self, source_property, + target, target_property, + flags, + NULL, NULL, + NULL, NULL); +} + +/** + * g_binding_group_bind_full: + * @self: the #GBindingGroup + * @source_property: the property on the source to bind + * @target: (type GObject) (transfer none) (not nullable): the target #GObject + * @target_property: the property on @target to bind + * @flags: the flags used to create the #GBinding + * @transform_to: (scope notified) (nullable): the transformation function + * from the source object to the @target, or %NULL to use the default + * @transform_from: (scope notified) (nullable): the transformation function + * from the @target to the source object, or %NULL to use the default + * @user_data: custom data to be passed to the transformation + * functions, or %NULL + * @user_data_destroy: function to be called when disposing the binding, + * to free the resources used by the transformation functions + * + * Creates a binding between @source_property on the source object and + * @target_property on @target, allowing you to set the transformation + * functions to be used by the binding. The binding flag + * %G_BINDING_SYNC_CREATE is automatically specified. + * + * See g_object_bind_property_full() for more information. + * + * Since: 2.72 + */ +void +g_binding_group_bind_full (GBindingGroup *self, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + GBindingTransformFunc transform_to, + GBindingTransformFunc transform_from, + gpointer user_data, + GDestroyNotify user_data_destroy) +{ + g_binding_group_bind_helper (self, source_property, + target, target_property, + flags, + transform_to, transform_from, + user_data, user_data_destroy, + FALSE); +} + +/** + * g_binding_group_bind_with_closures: (rename-to g_binding_group_bind_full) + * @self: the #GBindingGroup + * @source_property: the property on the source to bind + * @target: (type GObject) (transfer none) (not nullable): the target #GObject + * @target_property: the property on @target to bind + * @flags: the flags used to create the #GBinding + * @transform_to: (nullable) (transfer none): a #GClosure wrapping the + * transformation function from the source object to the @target, + * or %NULL to use the default + * @transform_from: (nullable) (transfer none): a #GClosure wrapping the + * transformation function from the @target to the source object, + * or %NULL to use the default + * + * Creates a binding between @source_property on the source object and + * @target_property on @target, allowing you to set the transformation + * functions to be used by the binding. The binding flag + * %G_BINDING_SYNC_CREATE is automatically specified. + * + * This function is the language bindings friendly version of + * g_binding_group_bind_property_full(), using #GClosures + * instead of function pointers. + * + * See g_object_bind_property_with_closures() for more information. + * + * Since: 2.72 + */ +void +g_binding_group_bind_with_closures (GBindingGroup *self, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + GClosure *transform_to, + GClosure *transform_from) +{ + g_binding_group_bind_helper (self, source_property, + target, target_property, + flags, + transform_to, transform_from, + NULL, NULL, + TRUE); +} diff --git a/gobject/gbindinggroup.h b/gobject/gbindinggroup.h new file mode 100644 index 0000000..472ebc5 --- /dev/null +++ b/gobject/gbindinggroup.h @@ -0,0 +1,85 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * Copyright (C) 2015-2022 Christian Hergert + * Copyright (C) 2015 Garrett Regier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef __G_BINDING_GROUP_H__ +#define __G_BINDING_GROUP_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +#define G_BINDING_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_BINDING_GROUP, GBindingGroup)) +#define G_IS_BINDING_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_BINDING_GROUP)) +#define G_TYPE_BINDING_GROUP (g_binding_group_get_type()) + +/** + * GBindingGroup: + * + * GBindingGroup is an opaque structure whose members + * cannot be accessed directly. + * + * Since: 2.72 + */ +typedef struct _GBindingGroup GBindingGroup; + +GLIB_AVAILABLE_IN_2_72 +GType g_binding_group_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_72 +GBindingGroup *g_binding_group_new (void); +GLIB_AVAILABLE_IN_2_72 +gpointer g_binding_group_dup_source (GBindingGroup *self); +GLIB_AVAILABLE_IN_2_72 +void g_binding_group_set_source (GBindingGroup *self, + gpointer source); +GLIB_AVAILABLE_IN_2_72 +void g_binding_group_bind (GBindingGroup *self, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags); +GLIB_AVAILABLE_IN_2_72 +void g_binding_group_bind_full (GBindingGroup *self, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + GBindingTransformFunc transform_to, + GBindingTransformFunc transform_from, + gpointer user_data, + GDestroyNotify user_data_destroy); +GLIB_AVAILABLE_IN_2_72 +void g_binding_group_bind_with_closures (GBindingGroup *self, + const gchar *source_property, + gpointer target, + const gchar *target_property, + GBindingFlags flags, + GClosure *transform_to, + GClosure *transform_from); + +G_END_DECLS + +#endif /* __G_BINDING_GROUP_H__ */ diff --git a/gobject/gboxed.c b/gobject/gboxed.c new file mode 100644 index 0000000..4a26992 --- /dev/null +++ b/gobject/gboxed.c @@ -0,0 +1,565 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000-2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include + +/* for GValueArray */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "gboxed.h" +#include "gclosure.h" +#include "gtype-private.h" +#include "gvalue.h" +#include "gvaluearray.h" +#include "gvaluecollector.h" + + +/** + * SECTION:gboxed + * @short_description: A mechanism to wrap opaque C structures registered + * by the type system + * @see_also: #GParamSpecBoxed, g_param_spec_boxed() + * @title: Boxed Types + * + * #GBoxed is a generic wrapper mechanism for arbitrary C structures. + * + * The only thing the type system needs to know about the structures is how to + * copy them (a #GBoxedCopyFunc) and how to free them (a #GBoxedFreeFunc); + * beyond that, they are treated as opaque chunks of memory. + * + * Boxed types are useful for simple value-holder structures like rectangles or + * points. They can also be used for wrapping structures defined in non-#GObject + * based libraries. They allow arbitrary structures to be handled in a uniform + * way, allowing uniform copying (or referencing) and freeing (or unreferencing) + * of them, and uniform representation of the type of the contained structure. + * In turn, this allows any type which can be boxed to be set as the data in a + * #GValue, which allows for polymorphic handling of a much wider range of data + * types, and hence usage of such types as #GObject property values. + * + * #GBoxed is designed so that reference counted types can be boxed. Use the + * type’s ‘ref’ function as the #GBoxedCopyFunc, and its ‘unref’ function as the + * #GBoxedFreeFunc. For example, for #GBytes, the #GBoxedCopyFunc is + * g_bytes_ref(), and the #GBoxedFreeFunc is g_bytes_unref(). + */ + +static inline void /* keep this function in sync with gvalue.c */ +value_meminit (GValue *value, + GType value_type) +{ + value->g_type = value_type; + memset (value->data, 0, sizeof (value->data)); +} + +static GValue * +value_copy (GValue *src_value) +{ + GValue *dest_value = g_new0 (GValue, 1); + + if (G_VALUE_TYPE (src_value)) + { + g_value_init (dest_value, G_VALUE_TYPE (src_value)); + g_value_copy (src_value, dest_value); + } + return dest_value; +} + +static void +value_free (GValue *value) +{ + if (G_VALUE_TYPE (value)) + g_value_unset (value); + g_free (value); +} + +static GPollFD * +pollfd_copy (GPollFD *src) +{ + GPollFD *dest = g_new0 (GPollFD, 1); + /* just a couple of integers */ + memcpy (dest, src, sizeof (GPollFD)); + return dest; +} + +void +_g_boxed_type_init (void) +{ + const GTypeInfo info = { + 0, /* class_size */ + NULL, /* base_init */ + NULL, /* base_destroy */ + NULL, /* class_init */ + NULL, /* class_destroy */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, }; + GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + /* G_TYPE_BOXED + */ + type = g_type_register_fundamental (G_TYPE_BOXED, g_intern_static_string ("GBoxed"), &info, &finfo, + G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); + g_assert (type == G_TYPE_BOXED); +} + +static GString * +gstring_copy (GString *src_gstring) +{ + return g_string_new_len (src_gstring->str, src_gstring->len); +} + +static void +gstring_free (GString *gstring) +{ + g_string_free (gstring, TRUE); +} + +G_DEFINE_BOXED_TYPE (GClosure, g_closure, g_closure_ref, g_closure_unref) +G_DEFINE_BOXED_TYPE (GValue, g_value, value_copy, value_free) +G_DEFINE_BOXED_TYPE (GValueArray, g_value_array, g_value_array_copy, g_value_array_free) +G_DEFINE_BOXED_TYPE (GDate, g_date, g_date_copy, g_date_free) +/* the naming is a bit odd, but GString is obviously not G_TYPE_STRING */ +G_DEFINE_BOXED_TYPE (GString, g_gstring, gstring_copy, gstring_free) +G_DEFINE_BOXED_TYPE (GHashTable, g_hash_table, g_hash_table_ref, g_hash_table_unref) +G_DEFINE_BOXED_TYPE (GArray, g_array, g_array_ref, g_array_unref) +G_DEFINE_BOXED_TYPE (GPtrArray, g_ptr_array,g_ptr_array_ref, g_ptr_array_unref) +G_DEFINE_BOXED_TYPE (GByteArray, g_byte_array, g_byte_array_ref, g_byte_array_unref) +G_DEFINE_BOXED_TYPE (GBytes, g_bytes, g_bytes_ref, g_bytes_unref) +G_DEFINE_BOXED_TYPE (GTree, g_tree, g_tree_ref, g_tree_unref) + +G_DEFINE_BOXED_TYPE (GRegex, g_regex, g_regex_ref, g_regex_unref) +G_DEFINE_BOXED_TYPE (GMatchInfo, g_match_info, g_match_info_ref, g_match_info_unref) + +#define g_variant_type_get_type g_variant_type_get_gtype +G_DEFINE_BOXED_TYPE (GVariantType, g_variant_type, g_variant_type_copy, g_variant_type_free) +#undef g_variant_type_get_type + +G_DEFINE_BOXED_TYPE (GVariantBuilder, g_variant_builder, g_variant_builder_ref, g_variant_builder_unref) +G_DEFINE_BOXED_TYPE (GVariantDict, g_variant_dict, g_variant_dict_ref, g_variant_dict_unref) + +G_DEFINE_BOXED_TYPE (GError, g_error, g_error_copy, g_error_free) + +G_DEFINE_BOXED_TYPE (GDateTime, g_date_time, g_date_time_ref, g_date_time_unref) +G_DEFINE_BOXED_TYPE (GTimeZone, g_time_zone, g_time_zone_ref, g_time_zone_unref) +G_DEFINE_BOXED_TYPE (GKeyFile, g_key_file, g_key_file_ref, g_key_file_unref) +G_DEFINE_BOXED_TYPE (GMappedFile, g_mapped_file, g_mapped_file_ref, g_mapped_file_unref) + +G_DEFINE_BOXED_TYPE (GMainLoop, g_main_loop, g_main_loop_ref, g_main_loop_unref) +G_DEFINE_BOXED_TYPE (GMainContext, g_main_context, g_main_context_ref, g_main_context_unref) +G_DEFINE_BOXED_TYPE (GSource, g_source, g_source_ref, g_source_unref) +G_DEFINE_BOXED_TYPE (GPollFD, g_pollfd, pollfd_copy, g_free) +G_DEFINE_BOXED_TYPE (GMarkupParseContext, g_markup_parse_context, g_markup_parse_context_ref, g_markup_parse_context_unref) + +G_DEFINE_BOXED_TYPE (GThread, g_thread, g_thread_ref, g_thread_unref) +G_DEFINE_BOXED_TYPE (GChecksum, g_checksum, g_checksum_copy, g_checksum_free) +G_DEFINE_BOXED_TYPE (GUri, g_uri, g_uri_ref, g_uri_unref) + +G_DEFINE_BOXED_TYPE (GOptionGroup, g_option_group, g_option_group_ref, g_option_group_unref) +G_DEFINE_BOXED_TYPE (GPatternSpec, g_pattern_spec, g_pattern_spec_copy, g_pattern_spec_free); + +/* This one can't use G_DEFINE_BOXED_TYPE (GStrv, g_strv, g_strdupv, g_strfreev) */ +GType +g_strv_get_type (void) +{ + static gsize static_g_define_type_id = 0; + + if (g_once_init_enter (&static_g_define_type_id)) + { + GType g_define_type_id = + g_boxed_type_register_static (g_intern_static_string ("GStrv"), + (GBoxedCopyFunc) g_strdupv, + (GBoxedFreeFunc) g_strfreev); + + g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + + return static_g_define_type_id; +} + +GType +g_variant_get_gtype (void) +{ + return G_TYPE_VARIANT; +} + +static void +boxed_proxy_value_init (GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static void +boxed_proxy_value_free (GValue *value) +{ + if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) + _g_type_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer); +} + +static void +boxed_proxy_value_copy (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[0].v_pointer) + dest_value->data[0].v_pointer = _g_type_boxed_copy (G_VALUE_TYPE (src_value), src_value->data[0].v_pointer); + else + dest_value->data[0].v_pointer = src_value->data[0].v_pointer; +} + +static gpointer +boxed_proxy_value_peek_pointer (const GValue *value) +{ + return value->data[0].v_pointer; +} + +static gchar* +boxed_proxy_collect_value (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + if (!collect_values[0].v_pointer) + value->data[0].v_pointer = NULL; + else + { + if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + { + value->data[0].v_pointer = collect_values[0].v_pointer; + value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; + } + else + value->data[0].v_pointer = _g_type_boxed_copy (G_VALUE_TYPE (value), collect_values[0].v_pointer); + } + + return NULL; +} + +static gchar* +boxed_proxy_lcopy_value (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gpointer *boxed_p = collect_values[0].v_pointer; + + g_return_val_if_fail (boxed_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + if (!value->data[0].v_pointer) + *boxed_p = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + *boxed_p = value->data[0].v_pointer; + else + *boxed_p = _g_type_boxed_copy (G_VALUE_TYPE (value), value->data[0].v_pointer); + + return NULL; +} + +/** + * g_boxed_type_register_static: + * @name: Name of the new boxed type. + * @boxed_copy: Boxed structure copy function. + * @boxed_free: Boxed structure free function. + * + * This function creates a new %G_TYPE_BOXED derived type id for a new + * boxed type with name @name. + * + * Boxed type handling functions have to be provided to copy and free + * opaque boxed structures of this type. + * + * For the general case, it is recommended to use G_DEFINE_BOXED_TYPE() + * instead of calling g_boxed_type_register_static() directly. The macro + * will create the appropriate `*_get_type()` function for the boxed type. + * + * Returns: New %G_TYPE_BOXED derived type id for @name. + */ +GType +g_boxed_type_register_static (const gchar *name, + GBoxedCopyFunc boxed_copy, + GBoxedFreeFunc boxed_free) +{ + static const GTypeValueTable vtable = { + boxed_proxy_value_init, + boxed_proxy_value_free, + boxed_proxy_value_copy, + boxed_proxy_value_peek_pointer, + "p", + boxed_proxy_collect_value, + "p", + boxed_proxy_lcopy_value, + }; + GTypeInfo type_info = { + 0, /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + &vtable, /* value_table */ + }; + GType type; + + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (boxed_copy != NULL, 0); + g_return_val_if_fail (boxed_free != NULL, 0); + g_return_val_if_fail (g_type_from_name (name) == 0, 0); + + type = g_type_register_static (G_TYPE_BOXED, name, &type_info, 0); + + /* install proxy functions upon successful registration */ + if (type) + _g_type_boxed_init (type, boxed_copy, boxed_free); + + return type; +} + +/** + * g_boxed_copy: + * @boxed_type: The type of @src_boxed. + * @src_boxed: (not nullable): The boxed structure to be copied. + * + * Provide a copy of a boxed structure @src_boxed which is of type @boxed_type. + * + * Returns: (transfer full) (not nullable): The newly created copy of the boxed + * structure. + */ +gpointer +g_boxed_copy (GType boxed_type, + gconstpointer src_boxed) +{ + GTypeValueTable *value_table; + gpointer dest_boxed; + + g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL); + g_return_val_if_fail (G_TYPE_IS_ABSTRACT (boxed_type) == FALSE, NULL); + g_return_val_if_fail (src_boxed != NULL, NULL); + + value_table = g_type_value_table_peek (boxed_type); + g_assert (value_table != NULL); + + /* check if our proxying implementation is used, we can short-cut here */ + if (value_table->value_copy == boxed_proxy_value_copy) + dest_boxed = _g_type_boxed_copy (boxed_type, (gpointer) src_boxed); + else + { + GValue src_value, dest_value; + + /* we heavily rely on third-party boxed type value vtable + * implementations to follow normal boxed value storage + * (data[0].v_pointer is the boxed struct, and + * data[1].v_uint holds the G_VALUE_NOCOPY_CONTENTS flag, + * rest zero). + * but then, we can expect that since we laid out the + * g_boxed_*() API. + * data[1].v_uint&G_VALUE_NOCOPY_CONTENTS shouldn't be set + * after a copy. + */ + /* equiv. to g_value_set_static_boxed() */ + value_meminit (&src_value, boxed_type); + src_value.data[0].v_pointer = (gpointer) src_boxed; + src_value.data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; + + /* call third-party code copy function, fingers-crossed */ + value_meminit (&dest_value, boxed_type); + value_table->value_copy (&src_value, &dest_value); + + /* double check and grouse if things went wrong */ + if (dest_value.data[1].v_ulong) + g_warning ("the copy_value() implementation of type '%s' seems to make use of reserved GValue fields", + g_type_name (boxed_type)); + + dest_boxed = dest_value.data[0].v_pointer; + } + + return dest_boxed; +} + +/** + * g_boxed_free: + * @boxed_type: The type of @boxed. + * @boxed: (not nullable): The boxed structure to be freed. + * + * Free the boxed structure @boxed which is of type @boxed_type. + */ +void +g_boxed_free (GType boxed_type, + gpointer boxed) +{ + GTypeValueTable *value_table; + + g_return_if_fail (G_TYPE_IS_BOXED (boxed_type)); + g_return_if_fail (G_TYPE_IS_ABSTRACT (boxed_type) == FALSE); + g_return_if_fail (boxed != NULL); + + value_table = g_type_value_table_peek (boxed_type); + g_assert (value_table != NULL); + + /* check if our proxying implementation is used, we can short-cut here */ + if (value_table->value_free == boxed_proxy_value_free) + _g_type_boxed_free (boxed_type, boxed); + else + { + GValue value; + + /* see g_boxed_copy() on why we think we can do this */ + value_meminit (&value, boxed_type); + value.data[0].v_pointer = boxed; + value_table->value_free (&value); + } +} + +/** + * g_value_get_boxed: + * @value: a valid #GValue of %G_TYPE_BOXED derived type + * + * Get the contents of a %G_TYPE_BOXED derived #GValue. + * + * Returns: (transfer none): boxed contents of @value + */ +gpointer +g_value_get_boxed (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), NULL); + g_return_val_if_fail (G_TYPE_IS_VALUE (G_VALUE_TYPE (value)), NULL); + + return value->data[0].v_pointer; +} + +/** + * g_value_dup_boxed: (skip) + * @value: a valid #GValue of %G_TYPE_BOXED derived type + * + * Get the contents of a %G_TYPE_BOXED derived #GValue. Upon getting, + * the boxed value is duplicated and needs to be later freed with + * g_boxed_free(), e.g. like: g_boxed_free (G_VALUE_TYPE (@value), + * return_value); + * + * Returns: boxed contents of @value + */ +gpointer +g_value_dup_boxed (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), NULL); + g_return_val_if_fail (G_TYPE_IS_VALUE (G_VALUE_TYPE (value)), NULL); + + return value->data[0].v_pointer ? g_boxed_copy (G_VALUE_TYPE (value), value->data[0].v_pointer) : NULL; +} + +static inline void +value_set_boxed_internal (GValue *value, + gconstpointer boxed, + gboolean need_copy, + gboolean need_free) +{ + if (!boxed) + { + /* just resetting to NULL might not be desired, need to + * have value reinitialized also (for values defaulting + * to other default value states than a NULL data pointer), + * g_value_reset() will handle this + */ + g_value_reset (value); + return; + } + + if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) + g_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer); + value->data[1].v_uint = need_free ? 0 : G_VALUE_NOCOPY_CONTENTS; + value->data[0].v_pointer = need_copy ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : (gpointer) boxed; +} + +/** + * g_value_set_boxed: + * @value: a valid #GValue of %G_TYPE_BOXED derived type + * @v_boxed: (nullable): boxed value to be set + * + * Set the contents of a %G_TYPE_BOXED derived #GValue to @v_boxed. + */ +void +g_value_set_boxed (GValue *value, + gconstpointer boxed) +{ + g_return_if_fail (G_VALUE_HOLDS_BOXED (value)); + g_return_if_fail (G_TYPE_IS_VALUE (G_VALUE_TYPE (value))); + + value_set_boxed_internal (value, boxed, TRUE, TRUE); +} + +/** + * g_value_set_static_boxed: + * @value: a valid #GValue of %G_TYPE_BOXED derived type + * @v_boxed: (nullable): static boxed value to be set + * + * Set the contents of a %G_TYPE_BOXED derived #GValue to @v_boxed. + * + * The boxed value is assumed to be static, and is thus not duplicated + * when setting the #GValue. + */ +void +g_value_set_static_boxed (GValue *value, + gconstpointer boxed) +{ + g_return_if_fail (G_VALUE_HOLDS_BOXED (value)); + g_return_if_fail (G_TYPE_IS_VALUE (G_VALUE_TYPE (value))); + + value_set_boxed_internal (value, boxed, FALSE, FALSE); +} + +/** + * g_value_set_boxed_take_ownership: + * @value: a valid #GValue of %G_TYPE_BOXED derived type + * @v_boxed: (nullable): duplicated unowned boxed value to be set + * + * This is an internal function introduced mainly for C marshallers. + * + * Deprecated: 2.4: Use g_value_take_boxed() instead. + */ +void +g_value_set_boxed_take_ownership (GValue *value, + gconstpointer boxed) +{ + g_value_take_boxed (value, boxed); +} + +/** + * g_value_take_boxed: + * @value: a valid #GValue of %G_TYPE_BOXED derived type + * @v_boxed: (nullable): duplicated unowned boxed value to be set + * + * Sets the contents of a %G_TYPE_BOXED derived #GValue to @v_boxed + * and takes over the ownership of the caller’s reference to @v_boxed; + * the caller doesn’t have to unref it any more. + * + * Since: 2.4 + */ +void +g_value_take_boxed (GValue *value, + gconstpointer boxed) +{ + g_return_if_fail (G_VALUE_HOLDS_BOXED (value)); + g_return_if_fail (G_TYPE_IS_VALUE (G_VALUE_TYPE (value))); + + value_set_boxed_internal (value, boxed, FALSE, TRUE); +} diff --git a/gobject/gboxed.h b/gobject/gboxed.h new file mode 100644 index 0000000..bcaf0b0 --- /dev/null +++ b/gobject/gboxed.h @@ -0,0 +1,122 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000-2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_BOXED_H__ +#define __G_BOXED_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +#ifndef __GI_SCANNER__ +#include +#endif + +G_BEGIN_DECLS + +/* --- type macros --- */ +#define G_TYPE_IS_BOXED(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_BOXED) +/** + * G_VALUE_HOLDS_BOXED: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values derived + * from type %G_TYPE_BOXED. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_BOXED(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_BOXED)) + + +/* --- typedefs --- */ +/** + * GBoxedCopyFunc: + * @boxed: (not nullable): The boxed structure to be copied. + * + * This function is provided by the user and should produce a copy + * of the passed in boxed structure. + * + * Returns: (not nullable): The newly created copy of the boxed structure. + */ +typedef gpointer (*GBoxedCopyFunc) (gpointer boxed); + +/** + * GBoxedFreeFunc: + * @boxed: (not nullable): The boxed structure to be freed. + * + * This function is provided by the user and should free the boxed + * structure passed. + */ +typedef void (*GBoxedFreeFunc) (gpointer boxed); + + +/* --- prototypes --- */ +GLIB_AVAILABLE_IN_ALL +gpointer g_boxed_copy (GType boxed_type, + gconstpointer src_boxed); +GLIB_AVAILABLE_IN_ALL +void g_boxed_free (GType boxed_type, + gpointer boxed); +GLIB_AVAILABLE_IN_ALL +void g_value_set_boxed (GValue *value, + gconstpointer v_boxed); +GLIB_AVAILABLE_IN_ALL +void g_value_set_static_boxed (GValue *value, + gconstpointer v_boxed); +GLIB_AVAILABLE_IN_ALL +void g_value_take_boxed (GValue *value, + gconstpointer v_boxed); +GLIB_DEPRECATED_FOR(g_value_take_boxed) +void g_value_set_boxed_take_ownership (GValue *value, + gconstpointer v_boxed); +GLIB_AVAILABLE_IN_ALL +gpointer g_value_get_boxed (const GValue *value); +GLIB_AVAILABLE_IN_ALL +gpointer g_value_dup_boxed (const GValue *value); + + +/* --- convenience --- */ +GLIB_AVAILABLE_IN_ALL +GType g_boxed_type_register_static (const gchar *name, + GBoxedCopyFunc boxed_copy, + GBoxedFreeFunc boxed_free); + +/* --- GObject boxed types --- */ +/** + * G_TYPE_CLOSURE: + * + * The #GType for #GClosure. + */ +#define G_TYPE_CLOSURE (g_closure_get_type ()) + +/** + * G_TYPE_VALUE: + * + * The type ID of the "GValue" type which is a boxed type, + * used to pass around pointers to GValues. + */ +#define G_TYPE_VALUE (g_value_get_type ()) + +GLIB_AVAILABLE_IN_ALL +GType g_closure_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_value_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __G_BOXED_H__ */ diff --git a/gobject/gclosure.c b/gobject/gclosure.c new file mode 100644 index 0000000..85002a2 --- /dev/null +++ b/gobject/gclosure.c @@ -0,0 +1,1990 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000-2001 Red Hat, Inc. + * Copyright (C) 2005 Imendio AB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * MT safe with regards to reference counting. + */ + +#include "config.h" + +#include "../glib/gvalgrind.h" +#include + +#include + +#include "gclosure.h" +#include "gboxed.h" +#include "gobject.h" +#include "genums.h" +#include "gvalue.h" +#include "gvaluetypes.h" +#include "gtype-private.h" + + +/** + * SECTION:gclosure + * @short_description: Functions as first-class objects + * @title: Closures + * + * A #GClosure represents a callback supplied by the programmer. + * + * It will generally comprise a function of some kind and a marshaller + * used to call it. It is the responsibility of the marshaller to + * convert the arguments for the invocation from #GValues into + * a suitable form, perform the callback on the converted arguments, + * and transform the return value back into a #GValue. + * + * In the case of C programs, a closure usually just holds a pointer + * to a function and maybe a data argument, and the marshaller + * converts between #GValue and native C types. The GObject + * library provides the #GCClosure type for this purpose. Bindings for + * other languages need marshallers which convert between #GValues + * and suitable representations in the runtime of the language in + * order to use functions written in that language as callbacks. Use + * g_closure_set_marshal() to set the marshaller on such a custom + * closure implementation. + * + * Within GObject, closures play an important role in the + * implementation of signals. When a signal is registered, the + * @c_marshaller argument to g_signal_new() specifies the default C + * marshaller for any closure which is connected to this + * signal. GObject provides a number of C marshallers for this + * purpose, see the g_cclosure_marshal_*() functions. Additional C + * marshallers can be generated with the [glib-genmarshal][glib-genmarshal] + * utility. Closures can be explicitly connected to signals with + * g_signal_connect_closure(), but it usually more convenient to let + * GObject create a closure automatically by using one of the + * g_signal_connect_*() functions which take a callback function/user + * data pair. + * + * Using closures has a number of important advantages over a simple + * callback function/data pointer combination: + * + * - Closures allow the callee to get the types of the callback parameters, + * which means that language bindings don't have to write individual glue + * for each callback type. + * + * - The reference counting of #GClosure makes it easy to handle reentrancy + * right; if a callback is removed while it is being invoked, the closure + * and its parameters won't be freed until the invocation finishes. + * + * - g_closure_invalidate() and invalidation notifiers allow callbacks to be + * automatically removed when the objects they point to go away. + */ + +#define CLOSURE_MAX_REF_COUNT ((1 << 15) - 1) +#define CLOSURE_MAX_N_GUARDS ((1 << 1) - 1) +#define CLOSURE_MAX_N_FNOTIFIERS ((1 << 2) - 1) +#define CLOSURE_MAX_N_INOTIFIERS ((1 << 8) - 1) +#define CLOSURE_N_MFUNCS(cl) (((cl)->n_guards << 1L)) +/* same as G_CLOSURE_N_NOTIFIERS() (keep in sync) */ +#define CLOSURE_N_NOTIFIERS(cl) (CLOSURE_N_MFUNCS (cl) + \ + (cl)->n_fnotifiers + \ + (cl)->n_inotifiers) + +typedef union { + GClosure closure; + gint vint; +} ClosureInt; + +#define CHANGE_FIELD(_closure, _field, _OP, _value, _must_set, _SET_OLD, _SET_NEW) \ +G_STMT_START { \ + ClosureInt *cunion = (ClosureInt*) _closure; \ + gint new_int, old_int, success; \ + do \ + { \ + ClosureInt tmp; \ + tmp.vint = old_int = cunion->vint; \ + _SET_OLD tmp.closure._field; \ + tmp.closure._field _OP _value; \ + _SET_NEW tmp.closure._field; \ + new_int = tmp.vint; \ + success = g_atomic_int_compare_and_exchange (&cunion->vint, old_int, new_int); \ + } \ + while (!success && _must_set); \ +} G_STMT_END + +#define SWAP(_closure, _field, _value, _oldv) CHANGE_FIELD (_closure, _field, =, _value, TRUE, *(_oldv) =, (void) ) +#define SET(_closure, _field, _value) CHANGE_FIELD (_closure, _field, =, _value, TRUE, (void), (void) ) +#define INC(_closure, _field) CHANGE_FIELD (_closure, _field, +=, 1, TRUE, (void), (void) ) +#define INC_ASSIGN(_closure, _field, _newv) CHANGE_FIELD (_closure, _field, +=, 1, TRUE, (void), *(_newv) = ) +#define DEC(_closure, _field) CHANGE_FIELD (_closure, _field, -=, 1, TRUE, (void), (void) ) +#define DEC_ASSIGN(_closure, _field, _newv) CHANGE_FIELD (_closure, _field, -=, 1, TRUE, (void), *(_newv) = ) + +#if 0 /* for non-thread-safe closures */ +#define SWAP(cl,f,v,o) (void) (*(o) = cl->f, cl->f = v) +#define SET(cl,f,v) (void) (cl->f = v) +#define INC(cl,f) (void) (cl->f += 1) +#define INC_ASSIGN(cl,f,n) (void) (cl->f += 1, *(n) = cl->f) +#define DEC(cl,f) (void) (cl->f -= 1) +#define DEC_ASSIGN(cl,f,n) (void) (cl->f -= 1, *(n) = cl->f) +#endif + +enum { + FNOTIFY, + INOTIFY, + PRE_NOTIFY, + POST_NOTIFY +}; + + +/* --- functions --- */ +/** + * g_closure_new_simple: + * @sizeof_closure: the size of the structure to allocate, must be at least + * `sizeof (GClosure)` + * @data: data to store in the @data field of the newly allocated #GClosure + * + * Allocates a struct of the given size and initializes the initial + * part as a #GClosure. + * + * This function is mainly useful when implementing new types of closures: + * + * |[ + * typedef struct _MyClosure MyClosure; + * struct _MyClosure + * { + * GClosure closure; + * // extra data goes here + * }; + * + * static void + * my_closure_finalize (gpointer notify_data, + * GClosure *closure) + * { + * MyClosure *my_closure = (MyClosure *)closure; + * + * // free extra data here + * } + * + * MyClosure *my_closure_new (gpointer data) + * { + * GClosure *closure; + * MyClosure *my_closure; + * + * closure = g_closure_new_simple (sizeof (MyClosure), data); + * my_closure = (MyClosure *) closure; + * + * // initialize extra data here + * + * g_closure_add_finalize_notifier (closure, notify_data, + * my_closure_finalize); + * return my_closure; + * } + * ]| + * + * Returns: (transfer none): a floating reference to a new #GClosure + */ +GClosure* +g_closure_new_simple (guint sizeof_closure, + gpointer data) +{ + GClosure *closure; + gint private_size; + gchar *allocated; + + g_return_val_if_fail (sizeof_closure >= sizeof (GClosure), NULL); + + private_size = sizeof (GRealClosure) - sizeof (GClosure); + +#ifdef ENABLE_VALGRIND + /* See comments in gtype.c about what's going on here... */ + if (RUNNING_ON_VALGRIND) + { + private_size += sizeof (gpointer); + + allocated = g_malloc0 (private_size + sizeof_closure + sizeof (gpointer)); + + *(gpointer *) (allocated + private_size + sizeof_closure) = allocated + sizeof (gpointer); + + VALGRIND_MALLOCLIKE_BLOCK (allocated + private_size, sizeof_closure + sizeof (gpointer), 0, TRUE); + VALGRIND_MALLOCLIKE_BLOCK (allocated + sizeof (gpointer), private_size - sizeof (gpointer), 0, TRUE); + } + else +#endif + allocated = g_malloc0 (private_size + sizeof_closure); + + closure = (GClosure *) (allocated + private_size); + + SET (closure, ref_count, 1); + SET (closure, floating, TRUE); + closure->data = data; + + return closure; +} + +static inline void +closure_invoke_notifiers (GClosure *closure, + guint notify_type) +{ + /* notifier layout: + * n_guards n_guards n_fnotif. n_inotifiers + * ->[[pre_guards][post_guards][fnotifiers][inotifiers]] + * + * CLOSURE_N_MFUNCS(cl) = n_guards + n_guards; + * CLOSURE_N_NOTIFIERS(cl) = CLOSURE_N_MFUNCS(cl) + n_fnotifiers + n_inotifiers + * + * constrains/catches: + * - closure->notifiers may be reloacted during callback + * - closure->n_fnotifiers and closure->n_inotifiers may change during callback + * - i.e. callbacks can be removed/added during invocation + * - must prepare for callback removal during FNOTIFY and INOTIFY (done via ->marshal= & ->data=) + * - must distinguish (->marshal= & ->data=) for INOTIFY vs. FNOTIFY (via ->in_inotify) + * + closure->n_guards is const during PRE_NOTIFY & POST_NOTIFY + * + none of the callbacks can cause recursion + * + closure->n_inotifiers is const 0 during FNOTIFY + */ + switch (notify_type) + { + GClosureNotifyData *ndata; + guint i, offs; + case FNOTIFY: + while (closure->n_fnotifiers) + { + guint n; + DEC_ASSIGN (closure, n_fnotifiers, &n); + + ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + n; + closure->marshal = (GClosureMarshal) ndata->notify; + closure->data = ndata->data; + ndata->notify (ndata->data, closure); + } + closure->marshal = NULL; + closure->data = NULL; + break; + case INOTIFY: + SET (closure, in_inotify, TRUE); + while (closure->n_inotifiers) + { + guint n; + DEC_ASSIGN (closure, n_inotifiers, &n); + + ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + n; + closure->marshal = (GClosureMarshal) ndata->notify; + closure->data = ndata->data; + ndata->notify (ndata->data, closure); + } + closure->marshal = NULL; + closure->data = NULL; + SET (closure, in_inotify, FALSE); + break; + case PRE_NOTIFY: + i = closure->n_guards; + offs = 0; + while (i--) + { + ndata = closure->notifiers + offs + i; + ndata->notify (ndata->data, closure); + } + break; + case POST_NOTIFY: + i = closure->n_guards; + offs = i; + while (i--) + { + ndata = closure->notifiers + offs + i; + ndata->notify (ndata->data, closure); + } + break; + } +} + +static void +g_closure_set_meta_va_marshal (GClosure *closure, + GVaClosureMarshal va_meta_marshal) +{ + GRealClosure *real_closure; + + g_return_if_fail (closure != NULL); + g_return_if_fail (va_meta_marshal != NULL); + g_return_if_fail (closure->is_invalid == FALSE); + g_return_if_fail (closure->in_marshal == FALSE); + + real_closure = G_REAL_CLOSURE (closure); + + g_return_if_fail (real_closure->meta_marshal != NULL); + + real_closure->va_meta_marshal = va_meta_marshal; +} + +/** + * g_closure_set_meta_marshal: (skip) + * @closure: a #GClosure + * @marshal_data: (closure meta_marshal): context-dependent data to pass + * to @meta_marshal + * @meta_marshal: a #GClosureMarshal function + * + * Sets the meta marshaller of @closure. + * + * A meta marshaller wraps the @closure's marshal and modifies the way + * it is called in some fashion. The most common use of this facility + * is for C callbacks. + * + * The same marshallers (generated by [glib-genmarshal][glib-genmarshal]), + * are used everywhere, but the way that we get the callback function + * differs. In most cases we want to use the @closure's callback, but in + * other cases we want to use some different technique to retrieve the + * callback function. + * + * For example, class closures for signals (see + * g_signal_type_cclosure_new()) retrieve the callback function from a + * fixed offset in the class structure. The meta marshaller retrieves + * the right callback and passes it to the marshaller as the + * @marshal_data argument. + */ +void +g_closure_set_meta_marshal (GClosure *closure, + gpointer marshal_data, + GClosureMarshal meta_marshal) +{ + GRealClosure *real_closure; + + g_return_if_fail (closure != NULL); + g_return_if_fail (meta_marshal != NULL); + g_return_if_fail (closure->is_invalid == FALSE); + g_return_if_fail (closure->in_marshal == FALSE); + + real_closure = G_REAL_CLOSURE (closure); + + g_return_if_fail (real_closure->meta_marshal == NULL); + + real_closure->meta_marshal = meta_marshal; + real_closure->meta_marshal_data = marshal_data; +} + +/** + * g_closure_add_marshal_guards: (skip) + * @closure: a #GClosure + * @pre_marshal_data: (closure pre_marshal_notify): data to pass + * to @pre_marshal_notify + * @pre_marshal_notify: a function to call before the closure callback + * @post_marshal_data: (closure post_marshal_notify): data to pass + * to @post_marshal_notify + * @post_marshal_notify: a function to call after the closure callback + * + * Adds a pair of notifiers which get invoked before and after the + * closure callback, respectively. + * + * This is typically used to protect the extra arguments for the + * duration of the callback. See g_object_watch_closure() for an + * example of marshal guards. + */ +void +g_closure_add_marshal_guards (GClosure *closure, + gpointer pre_marshal_data, + GClosureNotify pre_marshal_notify, + gpointer post_marshal_data, + GClosureNotify post_marshal_notify) +{ + guint i; + + g_return_if_fail (closure != NULL); + g_return_if_fail (pre_marshal_notify != NULL); + g_return_if_fail (post_marshal_notify != NULL); + g_return_if_fail (closure->is_invalid == FALSE); + g_return_if_fail (closure->in_marshal == FALSE); + g_return_if_fail (closure->n_guards < CLOSURE_MAX_N_GUARDS); + + closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 2); + if (closure->n_inotifiers) + closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers + + closure->n_inotifiers + 1)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers + 0)]; + if (closure->n_inotifiers > 1) + closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers + + closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers + 1)]; + if (closure->n_fnotifiers) + closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers + 1)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 0]; + if (closure->n_fnotifiers > 1) + closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 1]; + if (closure->n_guards) + closure->notifiers[(closure->n_guards + + closure->n_guards + 1)] = closure->notifiers[closure->n_guards]; + i = closure->n_guards; + closure->notifiers[i].data = pre_marshal_data; + closure->notifiers[i].notify = pre_marshal_notify; + closure->notifiers[i + 1].data = post_marshal_data; + closure->notifiers[i + 1].notify = post_marshal_notify; + INC (closure, n_guards); +} + +/** + * g_closure_add_finalize_notifier: (skip) + * @closure: a #GClosure + * @notify_data: (closure notify_func): data to pass to @notify_func + * @notify_func: the callback function to register + * + * Registers a finalization notifier which will be called when the + * reference count of @closure goes down to 0. + * + * Multiple finalization notifiers on a single closure are invoked in + * unspecified order. If a single call to g_closure_unref() results in + * the closure being both invalidated and finalized, then the invalidate + * notifiers will be run before the finalize notifiers. + */ +void +g_closure_add_finalize_notifier (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func) +{ + guint i; + + g_return_if_fail (closure != NULL); + g_return_if_fail (notify_func != NULL); + g_return_if_fail (closure->n_fnotifiers < CLOSURE_MAX_N_FNOTIFIERS); + + closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1); + if (closure->n_inotifiers) + closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers + + closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers + 0)]; + i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers; + closure->notifiers[i].data = notify_data; + closure->notifiers[i].notify = notify_func; + INC (closure, n_fnotifiers); +} + +/** + * g_closure_add_invalidate_notifier: (skip) + * @closure: a #GClosure + * @notify_data: (closure notify_func): data to pass to @notify_func + * @notify_func: the callback function to register + * + * Registers an invalidation notifier which will be called when the + * @closure is invalidated with g_closure_invalidate(). + * + * Invalidation notifiers are invoked before finalization notifiers, + * in an unspecified order. + */ +void +g_closure_add_invalidate_notifier (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func) +{ + guint i; + + g_return_if_fail (closure != NULL); + g_return_if_fail (notify_func != NULL); + g_return_if_fail (closure->is_invalid == FALSE); + g_return_if_fail (closure->n_inotifiers < CLOSURE_MAX_N_INOTIFIERS); + + closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1); + i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers; + closure->notifiers[i].data = notify_data; + closure->notifiers[i].notify = notify_func; + INC (closure, n_inotifiers); +} + +static inline gboolean +closure_try_remove_inotify (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func) +{ + GClosureNotifyData *ndata, *nlast; + + nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - 1; + for (ndata = nlast + 1 - closure->n_inotifiers; ndata <= nlast; ndata++) + if (ndata->notify == notify_func && ndata->data == notify_data) + { + DEC (closure, n_inotifiers); + if (ndata < nlast) + *ndata = *nlast; + + return TRUE; + } + return FALSE; +} + +static inline gboolean +closure_try_remove_fnotify (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func) +{ + GClosureNotifyData *ndata, *nlast; + + nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - closure->n_inotifiers - 1; + for (ndata = nlast + 1 - closure->n_fnotifiers; ndata <= nlast; ndata++) + if (ndata->notify == notify_func && ndata->data == notify_data) + { + DEC (closure, n_fnotifiers); + if (ndata < nlast) + *ndata = *nlast; + if (closure->n_inotifiers) + closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + + closure->n_fnotifiers + + closure->n_inotifiers)]; + return TRUE; + } + return FALSE; +} + +/** + * g_closure_ref: + * @closure: #GClosure to increment the reference count on + * + * Increments the reference count on a closure to force it staying + * alive while the caller holds a pointer to it. + * + * Returns: (transfer none): The @closure passed in, for convenience + */ +GClosure* +g_closure_ref (GClosure *closure) +{ + guint new_ref_count; + g_return_val_if_fail (closure != NULL, NULL); + g_return_val_if_fail (closure->ref_count > 0, NULL); + g_return_val_if_fail (closure->ref_count < CLOSURE_MAX_REF_COUNT, NULL); + + INC_ASSIGN (closure, ref_count, &new_ref_count); + g_return_val_if_fail (new_ref_count > 1, NULL); + + return closure; +} + +/** + * g_closure_invalidate: + * @closure: #GClosure to invalidate + * + * Sets a flag on the closure to indicate that its calling + * environment has become invalid, and thus causes any future + * invocations of g_closure_invoke() on this @closure to be + * ignored. + * + * Also, invalidation notifiers installed on the closure will + * be called at this point. Note that unless you are holding a + * reference to the closure yourself, the invalidation notifiers may + * unref the closure and cause it to be destroyed, so if you need to + * access the closure after calling g_closure_invalidate(), make sure + * that you've previously called g_closure_ref(). + * + * Note that g_closure_invalidate() will also be called when the + * reference count of a closure drops to zero (unless it has already + * been invalidated before). + */ +void +g_closure_invalidate (GClosure *closure) +{ + g_return_if_fail (closure != NULL); + + if (!closure->is_invalid) + { + gboolean was_invalid; + g_closure_ref (closure); /* preserve floating flag */ + SWAP (closure, is_invalid, TRUE, &was_invalid); + /* invalidate only once */ + if (!was_invalid) + closure_invoke_notifiers (closure, INOTIFY); + g_closure_unref (closure); + } +} + +/** + * g_closure_unref: + * @closure: #GClosure to decrement the reference count on + * + * Decrements the reference count of a closure after it was previously + * incremented by the same caller. + * + * If no other callers are using the closure, then the closure will be + * destroyed and freed. + */ +void +g_closure_unref (GClosure *closure) +{ + guint new_ref_count; + + g_return_if_fail (closure != NULL); + g_return_if_fail (closure->ref_count > 0); + + if (closure->ref_count == 1) /* last unref, invalidate first */ + g_closure_invalidate (closure); + + DEC_ASSIGN (closure, ref_count, &new_ref_count); + + if (new_ref_count == 0) + { + closure_invoke_notifiers (closure, FNOTIFY); + g_free (closure->notifiers); + +#ifdef ENABLE_VALGRIND + /* See comments in gtype.c about what's going on here... */ + if (RUNNING_ON_VALGRIND) + { + gchar *allocated; + + allocated = (gchar *) G_REAL_CLOSURE (closure); + allocated -= sizeof (gpointer); + + g_free (allocated); + + VALGRIND_FREELIKE_BLOCK (allocated + sizeof (gpointer), 0); + VALGRIND_FREELIKE_BLOCK (closure, 0); + } + else +#endif + g_free (G_REAL_CLOSURE (closure)); + } +} + +/** + * g_closure_sink: + * @closure: #GClosure to decrement the initial reference count on, if it's + * still being held + * + * Takes over the initial ownership of a closure. + * + * Each closure is initially created in a "floating" state, which means + * that the initial reference count is not owned by any caller. + * + * This function checks to see if the object is still floating, and if so, + * unsets the floating state and decreases the reference count. If the + * closure is not floating, g_closure_sink() does nothing. + * + * The reason for the existence of the floating state is to prevent + * cumbersome code sequences like: + * + * |[ + * closure = g_cclosure_new (cb_func, cb_data); + * g_source_set_closure (source, closure); + * g_closure_unref (closure); // GObject doesn't really need this + * ]| + * + * Because g_source_set_closure() (and similar functions) take ownership of the + * initial reference count, if it is unowned, we instead can write: + * + * |[ + * g_source_set_closure (source, g_cclosure_new (cb_func, cb_data)); + * ]| + * + * Generally, this function is used together with g_closure_ref(). An example + * of storing a closure for later notification looks like: + * + * |[ + * static GClosure *notify_closure = NULL; + * void + * foo_notify_set_closure (GClosure *closure) + * { + * if (notify_closure) + * g_closure_unref (notify_closure); + * notify_closure = closure; + * if (notify_closure) + * { + * g_closure_ref (notify_closure); + * g_closure_sink (notify_closure); + * } + * } + * ]| + * + * Because g_closure_sink() may decrement the reference count of a closure + * (if it hasn't been called on @closure yet) just like g_closure_unref(), + * g_closure_ref() should be called prior to this function. + */ +void +g_closure_sink (GClosure *closure) +{ + g_return_if_fail (closure != NULL); + g_return_if_fail (closure->ref_count > 0); + + /* floating is basically a kludge to avoid creating closures + * with a ref_count of 0. so the initial ref_count a closure has + * is unowned. with invoking g_closure_sink() code may + * indicate that it takes over that initial ref_count. + */ + if (closure->floating) + { + gboolean was_floating; + SWAP (closure, floating, FALSE, &was_floating); + /* unref floating flag only once */ + if (was_floating) + g_closure_unref (closure); + } +} + +/** + * g_closure_remove_invalidate_notifier: (skip) + * @closure: a #GClosure + * @notify_data: data which was passed to g_closure_add_invalidate_notifier() + * when registering @notify_func + * @notify_func: the callback function to remove + * + * Removes an invalidation notifier. + * + * Notice that notifiers are automatically removed after they are run. + */ +void +g_closure_remove_invalidate_notifier (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func) +{ + g_return_if_fail (closure != NULL); + g_return_if_fail (notify_func != NULL); + + if (closure->is_invalid && closure->in_inotify && /* account removal of notify_func() while it's called */ + ((gpointer) closure->marshal) == ((gpointer) notify_func) && + closure->data == notify_data) + closure->marshal = NULL; + else if (!closure_try_remove_inotify (closure, notify_data, notify_func)) + g_warning (G_STRLOC ": unable to remove uninstalled invalidation notifier: %p (%p)", + notify_func, notify_data); +} + +/** + * g_closure_remove_finalize_notifier: (skip) + * @closure: a #GClosure + * @notify_data: data which was passed to g_closure_add_finalize_notifier() + * when registering @notify_func + * @notify_func: the callback function to remove + * + * Removes a finalization notifier. + * + * Notice that notifiers are automatically removed after they are run. + */ +void +g_closure_remove_finalize_notifier (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func) +{ + g_return_if_fail (closure != NULL); + g_return_if_fail (notify_func != NULL); + + if (closure->is_invalid && !closure->in_inotify && /* account removal of notify_func() while it's called */ + ((gpointer) closure->marshal) == ((gpointer) notify_func) && + closure->data == notify_data) + closure->marshal = NULL; + else if (!closure_try_remove_fnotify (closure, notify_data, notify_func)) + g_warning (G_STRLOC ": unable to remove uninstalled finalization notifier: %p (%p)", + notify_func, notify_data); +} + +/** + * g_closure_invoke: + * @closure: a #GClosure + * @return_value: (optional) (out): a #GValue to store the return + * value. May be %NULL if the callback of @closure + * doesn't return a value. + * @n_param_values: the length of the @param_values array + * @param_values: (array length=n_param_values): an array of + * #GValues holding the arguments on which to + * invoke the callback of @closure + * @invocation_hint: (nullable): a context-dependent invocation hint + * + * Invokes the closure, i.e. executes the callback represented by the @closure. + */ +void +g_closure_invoke (GClosure *closure, + GValue /*out*/ *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint) +{ + GRealClosure *real_closure; + + g_return_if_fail (closure != NULL); + + real_closure = G_REAL_CLOSURE (closure); + + g_closure_ref (closure); /* preserve floating flag */ + if (!closure->is_invalid) + { + GClosureMarshal marshal; + gpointer marshal_data; + gboolean in_marshal = closure->in_marshal; + + g_return_if_fail (closure->marshal || real_closure->meta_marshal); + + SET (closure, in_marshal, TRUE); + if (real_closure->meta_marshal) + { + marshal_data = real_closure->meta_marshal_data; + marshal = real_closure->meta_marshal; + } + else + { + marshal_data = NULL; + marshal = closure->marshal; + } + if (!in_marshal) + closure_invoke_notifiers (closure, PRE_NOTIFY); + marshal (closure, + return_value, + n_param_values, param_values, + invocation_hint, + marshal_data); + if (!in_marshal) + closure_invoke_notifiers (closure, POST_NOTIFY); + SET (closure, in_marshal, in_marshal); + } + g_closure_unref (closure); +} + +gboolean +_g_closure_supports_invoke_va (GClosure *closure) +{ + GRealClosure *real_closure; + + g_return_val_if_fail (closure != NULL, FALSE); + + real_closure = G_REAL_CLOSURE (closure); + + return + real_closure->va_marshal != NULL && + (real_closure->meta_marshal == NULL || + real_closure->va_meta_marshal != NULL); +} + +void +_g_closure_invoke_va (GClosure *closure, + GValue /*out*/ *return_value, + gpointer instance, + va_list args, + int n_params, + GType *param_types) +{ + GRealClosure *real_closure; + + g_return_if_fail (closure != NULL); + + real_closure = G_REAL_CLOSURE (closure); + + g_closure_ref (closure); /* preserve floating flag */ + if (!closure->is_invalid) + { + GVaClosureMarshal marshal; + gpointer marshal_data; + gboolean in_marshal = closure->in_marshal; + + g_return_if_fail (closure->marshal || real_closure->meta_marshal); + + SET (closure, in_marshal, TRUE); + if (real_closure->va_meta_marshal) + { + marshal_data = real_closure->meta_marshal_data; + marshal = real_closure->va_meta_marshal; + } + else + { + marshal_data = NULL; + marshal = real_closure->va_marshal; + } + if (!in_marshal) + closure_invoke_notifiers (closure, PRE_NOTIFY); + marshal (closure, + return_value, + instance, args, + marshal_data, + n_params, param_types); + if (!in_marshal) + closure_invoke_notifiers (closure, POST_NOTIFY); + SET (closure, in_marshal, in_marshal); + } + g_closure_unref (closure); +} + + +/** + * g_closure_set_marshal: (skip) + * @closure: a #GClosure + * @marshal: a #GClosureMarshal function + * + * Sets the marshaller of @closure. + * + * The `marshal_data` of @marshal provides a way for a meta marshaller to + * provide additional information to the marshaller. + * + * For GObject's C predefined marshallers (the `g_cclosure_marshal_*()` + * functions), what it provides is a callback function to use instead of + * @closure->callback. + * + * See also: g_closure_set_meta_marshal() + */ +void +g_closure_set_marshal (GClosure *closure, + GClosureMarshal marshal) +{ + g_return_if_fail (closure != NULL); + g_return_if_fail (marshal != NULL); + + if (closure->marshal && closure->marshal != marshal) + g_warning ("attempt to override closure->marshal (%p) with new marshal (%p)", + closure->marshal, marshal); + else + closure->marshal = marshal; +} + +void +_g_closure_set_va_marshal (GClosure *closure, + GVaClosureMarshal marshal) +{ + GRealClosure *real_closure; + + g_return_if_fail (closure != NULL); + g_return_if_fail (marshal != NULL); + + real_closure = G_REAL_CLOSURE (closure); + + if (real_closure->va_marshal && real_closure->va_marshal != marshal) + g_warning ("attempt to override closure->va_marshal (%p) with new marshal (%p)", + real_closure->va_marshal, marshal); + else + real_closure->va_marshal = marshal; +} + +/** + * g_cclosure_new: (skip) + * @callback_func: the function to invoke + * @user_data: (closure callback_func): user data to pass to @callback_func + * @destroy_data: destroy notify to be called when @user_data is no longer used + * + * Creates a new closure which invokes @callback_func with @user_data as + * the last parameter. + * + * @destroy_data will be called as a finalize notifier on the #GClosure. + * + * Returns: (transfer none): a floating reference to a new #GCClosure + */ +GClosure* +g_cclosure_new (GCallback callback_func, + gpointer user_data, + GClosureNotify destroy_data) +{ + GClosure *closure; + + g_return_val_if_fail (callback_func != NULL, NULL); + + closure = g_closure_new_simple (sizeof (GCClosure), user_data); + if (destroy_data) + g_closure_add_finalize_notifier (closure, user_data, destroy_data); + ((GCClosure*) closure)->callback = (gpointer) callback_func; + + return closure; +} + +/** + * g_cclosure_new_swap: (skip) + * @callback_func: the function to invoke + * @user_data: (closure callback_func): user data to pass to @callback_func + * @destroy_data: destroy notify to be called when @user_data is no longer used + * + * Creates a new closure which invokes @callback_func with @user_data as + * the first parameter. + * + * @destroy_data will be called as a finalize notifier on the #GClosure. + * + * Returns: (transfer none): a floating reference to a new #GCClosure + */ +GClosure* +g_cclosure_new_swap (GCallback callback_func, + gpointer user_data, + GClosureNotify destroy_data) +{ + GClosure *closure; + + g_return_val_if_fail (callback_func != NULL, NULL); + + closure = g_closure_new_simple (sizeof (GCClosure), user_data); + if (destroy_data) + g_closure_add_finalize_notifier (closure, user_data, destroy_data); + ((GCClosure*) closure)->callback = (gpointer) callback_func; + SET (closure, derivative_flag, TRUE); + + return closure; +} + +static void +g_type_class_meta_marshal (GClosure *closure, + GValue /*out*/ *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + GTypeClass *class; + gpointer callback; + /* GType itype = (GType) closure->data; */ + guint offset = GPOINTER_TO_UINT (marshal_data); + + class = G_TYPE_INSTANCE_GET_CLASS (g_value_peek_pointer (param_values + 0), itype, GTypeClass); + callback = G_STRUCT_MEMBER (gpointer, class, offset); + if (callback) + closure->marshal (closure, + return_value, + n_param_values, param_values, + invocation_hint, + callback); +} + +static void +g_type_class_meta_marshalv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + GRealClosure *real_closure; + GTypeClass *class; + gpointer callback; + /* GType itype = (GType) closure->data; */ + guint offset = GPOINTER_TO_UINT (marshal_data); + + real_closure = G_REAL_CLOSURE (closure); + + class = G_TYPE_INSTANCE_GET_CLASS (instance, itype, GTypeClass); + callback = G_STRUCT_MEMBER (gpointer, class, offset); + if (callback) + real_closure->va_marshal (closure, + return_value, + instance, args, + callback, + n_params, + param_types); +} + +static void +g_type_iface_meta_marshal (GClosure *closure, + GValue /*out*/ *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + GTypeClass *class; + gpointer callback; + GType itype = (GType) closure->data; + guint offset = GPOINTER_TO_UINT (marshal_data); + + class = G_TYPE_INSTANCE_GET_INTERFACE (g_value_peek_pointer (param_values + 0), itype, GTypeClass); + callback = G_STRUCT_MEMBER (gpointer, class, offset); + if (callback) + closure->marshal (closure, + return_value, + n_param_values, param_values, + invocation_hint, + callback); +} + +gboolean +_g_closure_is_void (GClosure *closure, + gpointer instance) +{ + GRealClosure *real_closure; + GTypeClass *class; + gpointer callback; + GType itype; + guint offset; + + if (closure->is_invalid) + return TRUE; + + real_closure = G_REAL_CLOSURE (closure); + + if (real_closure->meta_marshal == g_type_iface_meta_marshal) + { + itype = (GType) closure->data; + offset = GPOINTER_TO_UINT (real_closure->meta_marshal_data); + + class = G_TYPE_INSTANCE_GET_INTERFACE (instance, itype, GTypeClass); + callback = G_STRUCT_MEMBER (gpointer, class, offset); + return callback == NULL; + } + else if (real_closure->meta_marshal == g_type_class_meta_marshal) + { + offset = GPOINTER_TO_UINT (real_closure->meta_marshal_data); + + class = G_TYPE_INSTANCE_GET_CLASS (instance, itype, GTypeClass); + callback = G_STRUCT_MEMBER (gpointer, class, offset); + return callback == NULL; + } + + return FALSE; +} + +static void +g_type_iface_meta_marshalv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + GRealClosure *real_closure; + GTypeClass *class; + gpointer callback; + GType itype = (GType) closure->data; + guint offset = GPOINTER_TO_UINT (marshal_data); + + real_closure = G_REAL_CLOSURE (closure); + + class = G_TYPE_INSTANCE_GET_INTERFACE (instance, itype, GTypeClass); + callback = G_STRUCT_MEMBER (gpointer, class, offset); + if (callback) + real_closure->va_marshal (closure, + return_value, + instance, args, + callback, + n_params, + param_types); +} + +/** + * g_signal_type_cclosure_new: + * @itype: the #GType identifier of an interface or classed type + * @struct_offset: the offset of the member function of @itype's class + * structure which is to be invoked by the new closure + * + * Creates a new closure which invokes the function found at the offset + * @struct_offset in the class structure of the interface or classed type + * identified by @itype. + * + * Returns: (transfer none): a floating reference to a new #GCClosure + */ +GClosure* +g_signal_type_cclosure_new (GType itype, + guint struct_offset) +{ + GClosure *closure; + + g_return_val_if_fail (G_TYPE_IS_CLASSED (itype) || G_TYPE_IS_INTERFACE (itype), NULL); + g_return_val_if_fail (struct_offset >= sizeof (GTypeClass), NULL); + + closure = g_closure_new_simple (sizeof (GClosure), (gpointer) itype); + if (G_TYPE_IS_INTERFACE (itype)) + { + g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_iface_meta_marshal); + g_closure_set_meta_va_marshal (closure, g_type_iface_meta_marshalv); + } + else + { + g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_class_meta_marshal); + g_closure_set_meta_va_marshal (closure, g_type_class_meta_marshalv); + } + return closure; +} + +#include +static ffi_type * +value_to_ffi_type (const GValue *gvalue, + gpointer *value, + gint *enum_tmpval, + gboolean *tmpval_used) +{ + ffi_type *rettype = NULL; + GType type = g_type_fundamental (G_VALUE_TYPE (gvalue)); + g_assert (type != G_TYPE_INVALID); + + if (enum_tmpval) + { + g_assert (tmpval_used != NULL); + *tmpval_used = FALSE; + } + + switch (type) + { + case G_TYPE_BOOLEAN: + case G_TYPE_CHAR: + case G_TYPE_INT: + rettype = &ffi_type_sint; + *value = (gpointer)&(gvalue->data[0].v_int); + break; + case G_TYPE_ENUM: + /* enums are stored in v_long even though they are integers, which makes + * marshalling through libffi somewhat complicated. They need to be + * marshalled as signed ints, but we need to use a temporary int sized + * value to pass to libffi otherwise it'll pull the wrong value on + * BE machines with 32-bit integers when treating v_long as 32-bit int. + */ + g_assert (enum_tmpval != NULL); + rettype = &ffi_type_sint; + *enum_tmpval = g_value_get_enum (gvalue); + *value = enum_tmpval; + *tmpval_used = TRUE; + break; + case G_TYPE_FLAGS: + g_assert (enum_tmpval != NULL); + rettype = &ffi_type_uint; + *enum_tmpval = g_value_get_flags (gvalue); + *value = enum_tmpval; + *tmpval_used = TRUE; + break; + case G_TYPE_UCHAR: + case G_TYPE_UINT: + rettype = &ffi_type_uint; + *value = (gpointer)&(gvalue->data[0].v_uint); + break; + case G_TYPE_STRING: + case G_TYPE_OBJECT: + case G_TYPE_BOXED: + case G_TYPE_PARAM: + case G_TYPE_POINTER: + case G_TYPE_INTERFACE: + case G_TYPE_VARIANT: + rettype = &ffi_type_pointer; + *value = (gpointer)&(gvalue->data[0].v_pointer); + break; + case G_TYPE_FLOAT: + rettype = &ffi_type_float; + *value = (gpointer)&(gvalue->data[0].v_float); + break; + case G_TYPE_DOUBLE: + rettype = &ffi_type_double; + *value = (gpointer)&(gvalue->data[0].v_double); + break; + case G_TYPE_LONG: + rettype = &ffi_type_slong; + *value = (gpointer)&(gvalue->data[0].v_long); + break; + case G_TYPE_ULONG: + rettype = &ffi_type_ulong; + *value = (gpointer)&(gvalue->data[0].v_ulong); + break; + case G_TYPE_INT64: + rettype = &ffi_type_sint64; + *value = (gpointer)&(gvalue->data[0].v_int64); + break; + case G_TYPE_UINT64: + rettype = &ffi_type_uint64; + *value = (gpointer)&(gvalue->data[0].v_uint64); + break; + default: + rettype = &ffi_type_pointer; + *value = NULL; + g_warning ("value_to_ffi_type: Unsupported fundamental type: %s", g_type_name (type)); + break; + } + return rettype; +} + +static void +value_from_ffi_type (GValue *gvalue, gpointer *value) +{ + ffi_arg *int_val = (ffi_arg*) value; + GType type; + + type = G_VALUE_TYPE (gvalue); + +restart: + switch (g_type_fundamental (type)) + { + case G_TYPE_INT: + g_value_set_int (gvalue, (gint) *int_val); + break; + case G_TYPE_FLOAT: + g_value_set_float (gvalue, *(gfloat*)value); + break; + case G_TYPE_DOUBLE: + g_value_set_double (gvalue, *(gdouble*)value); + break; + case G_TYPE_BOOLEAN: + g_value_set_boolean (gvalue, (gboolean) *int_val); + break; + case G_TYPE_STRING: + g_value_take_string (gvalue, *(gchar**)value); + break; + case G_TYPE_CHAR: + g_value_set_schar (gvalue, (gint8) *int_val); + break; + case G_TYPE_UCHAR: + g_value_set_uchar (gvalue, (guchar) *int_val); + break; + case G_TYPE_UINT: + g_value_set_uint (gvalue, (guint) *int_val); + break; + case G_TYPE_POINTER: + g_value_set_pointer (gvalue, *(gpointer*)value); + break; + case G_TYPE_LONG: + g_value_set_long (gvalue, (glong) *int_val); + break; + case G_TYPE_ULONG: + g_value_set_ulong (gvalue, (gulong) *int_val); + break; + case G_TYPE_INT64: + g_value_set_int64 (gvalue, (gint64) *int_val); + break; + case G_TYPE_UINT64: + g_value_set_uint64 (gvalue, (guint64) *int_val); + break; + case G_TYPE_BOXED: + g_value_take_boxed (gvalue, *(gpointer*)value); + break; + case G_TYPE_ENUM: + g_value_set_enum (gvalue, (gint) *int_val); + break; + case G_TYPE_FLAGS: + g_value_set_flags (gvalue, (guint) *int_val); + break; + case G_TYPE_PARAM: + g_value_take_param (gvalue, *(gpointer*)value); + break; + case G_TYPE_OBJECT: + g_value_take_object (gvalue, *(gpointer*)value); + break; + case G_TYPE_VARIANT: + g_value_take_variant (gvalue, *(gpointer*)value); + break; + case G_TYPE_INTERFACE: + type = g_type_interface_instantiatable_prerequisite (type); + if (type) + goto restart; + G_GNUC_FALLTHROUGH; + default: + g_warning ("value_from_ffi_type: Unsupported fundamental type %s for type %s", + g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))), + g_type_name (G_VALUE_TYPE (gvalue))); + } +} + +typedef union { + gpointer _gpointer; + float _float; + double _double; + gint _gint; + guint _guint; + glong _glong; + gulong _gulong; + gint64 _gint64; + guint64 _guint64; +} va_arg_storage; + +static ffi_type * +va_to_ffi_type (GType gtype, + va_list *va, + va_arg_storage *storage) +{ + ffi_type *rettype = NULL; + GType type = g_type_fundamental (gtype); + g_assert (type != G_TYPE_INVALID); + + switch (type) + { + case G_TYPE_BOOLEAN: + case G_TYPE_CHAR: + case G_TYPE_INT: + case G_TYPE_ENUM: + rettype = &ffi_type_sint; + storage->_gint = va_arg (*va, gint); + break; + case G_TYPE_UCHAR: + case G_TYPE_UINT: + case G_TYPE_FLAGS: + rettype = &ffi_type_uint; + storage->_guint = va_arg (*va, guint); + break; + case G_TYPE_STRING: + case G_TYPE_OBJECT: + case G_TYPE_BOXED: + case G_TYPE_PARAM: + case G_TYPE_POINTER: + case G_TYPE_INTERFACE: + case G_TYPE_VARIANT: + rettype = &ffi_type_pointer; + storage->_gpointer = va_arg (*va, gpointer); + break; + case G_TYPE_FLOAT: + /* Float args are passed as doubles in varargs */ + rettype = &ffi_type_float; + storage->_float = (float)va_arg (*va, double); + break; + case G_TYPE_DOUBLE: + rettype = &ffi_type_double; + storage->_double = va_arg (*va, double); + break; + case G_TYPE_LONG: + rettype = &ffi_type_slong; + storage->_glong = va_arg (*va, glong); + break; + case G_TYPE_ULONG: + rettype = &ffi_type_ulong; + storage->_gulong = va_arg (*va, gulong); + break; + case G_TYPE_INT64: + rettype = &ffi_type_sint64; + storage->_gint64 = va_arg (*va, gint64); + break; + case G_TYPE_UINT64: + rettype = &ffi_type_uint64; + storage->_guint64 = va_arg (*va, guint64); + break; + default: + rettype = &ffi_type_pointer; + storage->_guint64 = 0; + g_warning ("va_to_ffi_type: Unsupported fundamental type: %s", g_type_name (type)); + break; + } + return rettype; +} + +/** + * g_cclosure_marshal_generic: + * @closure: A #GClosure. + * @return_gvalue: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A generic marshaller function implemented via + * [libffi](http://sourceware.org/libffi/). + * + * Normally this function is not passed explicitly to g_signal_new(), + * but used automatically by GLib when specifying a %NULL marshaller. + * + * Since: 2.30 + */ +void +g_cclosure_marshal_generic (GClosure *closure, + GValue *return_gvalue, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + ffi_type *rtype; + void *rvalue; + int n_args; + ffi_type **atypes; + void **args; + int i; + ffi_cif cif; + GCClosure *cc = (GCClosure*) closure; + gint *enum_tmpval; + gboolean tmpval_used = FALSE; + + enum_tmpval = g_alloca (sizeof (gint)); + if (return_gvalue && G_VALUE_TYPE (return_gvalue)) + { + rtype = value_to_ffi_type (return_gvalue, &rvalue, enum_tmpval, &tmpval_used); + } + else + { + rtype = &ffi_type_void; + } + + rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg))); + + n_args = n_param_values + 1; + atypes = g_alloca (sizeof (ffi_type *) * n_args); + args = g_alloca (sizeof (gpointer) * n_args); + + if (tmpval_used) + enum_tmpval = g_alloca (sizeof (gint)); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + atypes[n_args-1] = value_to_ffi_type (param_values + 0, + &args[n_args-1], + enum_tmpval, + &tmpval_used); + atypes[0] = &ffi_type_pointer; + args[0] = &closure->data; + } + else + { + atypes[0] = value_to_ffi_type (param_values + 0, + &args[0], + enum_tmpval, + &tmpval_used); + atypes[n_args-1] = &ffi_type_pointer; + args[n_args-1] = &closure->data; + } + + for (i = 1; i < n_args - 1; i++) + { + if (tmpval_used) + enum_tmpval = g_alloca (sizeof (gint)); + + atypes[i] = value_to_ffi_type (param_values + i, + &args[i], + enum_tmpval, + &tmpval_used); + } + + if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) + return; + + ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); + + if (return_gvalue && G_VALUE_TYPE (return_gvalue)) + value_from_ffi_type (return_gvalue, rvalue); +} + +/** + * g_cclosure_marshal_generic_va: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is + * invoked. + * @args_list: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args_list. + * + * A generic #GVaClosureMarshal function implemented via + * [libffi](http://sourceware.org/libffi/). + * + * Since: 2.30 + */ +void +g_cclosure_marshal_generic_va (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args_list, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + ffi_type *rtype; + void *rvalue; + int n_args; + ffi_type **atypes; + void **args; + va_arg_storage *storage; + int i; + ffi_cif cif; + GCClosure *cc = (GCClosure*) closure; + gint *enum_tmpval; + gboolean tmpval_used = FALSE; + va_list args_copy; + + enum_tmpval = g_alloca (sizeof (gint)); + if (return_value && G_VALUE_TYPE (return_value)) + { + rtype = value_to_ffi_type (return_value, &rvalue, enum_tmpval, &tmpval_used); + } + else + { + rtype = &ffi_type_void; + } + + rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg))); + + n_args = n_params + 2; + atypes = g_alloca (sizeof (ffi_type *) * n_args); + args = g_alloca (sizeof (gpointer) * n_args); + storage = g_alloca (sizeof (va_arg_storage) * n_params); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + atypes[n_args-1] = &ffi_type_pointer; + args[n_args-1] = &instance; + atypes[0] = &ffi_type_pointer; + args[0] = &closure->data; + } + else + { + atypes[0] = &ffi_type_pointer; + args[0] = &instance; + atypes[n_args-1] = &ffi_type_pointer; + args[n_args-1] = &closure->data; + } + + G_VA_COPY (args_copy, args_list); + + /* Box non-primitive arguments */ + for (i = 0; i < n_params; i++) + { + GType type = param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; + GType fundamental = G_TYPE_FUNDAMENTAL (type); + + atypes[i+1] = va_to_ffi_type (type, + &args_copy, + &storage[i]); + args[i+1] = &storage[i]; + + if ((param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0) + { + if (fundamental == G_TYPE_STRING && storage[i]._gpointer != NULL) + storage[i]._gpointer = g_strdup (storage[i]._gpointer); + else if (fundamental == G_TYPE_PARAM && storage[i]._gpointer != NULL) + storage[i]._gpointer = g_param_spec_ref (storage[i]._gpointer); + else if (fundamental == G_TYPE_BOXED && storage[i]._gpointer != NULL) + storage[i]._gpointer = g_boxed_copy (type, storage[i]._gpointer); + else if (fundamental == G_TYPE_VARIANT && storage[i]._gpointer != NULL) + storage[i]._gpointer = g_variant_ref_sink (storage[i]._gpointer); + } + if (fundamental == G_TYPE_OBJECT && storage[i]._gpointer != NULL) + storage[i]._gpointer = g_object_ref (storage[i]._gpointer); + } + + va_end (args_copy); + + if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) + return; + + ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); + + /* Unbox non-primitive arguments */ + for (i = 0; i < n_params; i++) + { + GType type = param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; + GType fundamental = G_TYPE_FUNDAMENTAL (type); + + if ((param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0) + { + if (fundamental == G_TYPE_STRING && storage[i]._gpointer != NULL) + g_free (storage[i]._gpointer); + else if (fundamental == G_TYPE_PARAM && storage[i]._gpointer != NULL) + g_param_spec_unref (storage[i]._gpointer); + else if (fundamental == G_TYPE_BOXED && storage[i]._gpointer != NULL) + g_boxed_free (type, storage[i]._gpointer); + else if (fundamental == G_TYPE_VARIANT && storage[i]._gpointer != NULL) + g_variant_unref (storage[i]._gpointer); + } + if (fundamental == G_TYPE_OBJECT && storage[i]._gpointer != NULL) + g_object_unref (storage[i]._gpointer); + } + + if (return_value && G_VALUE_TYPE (return_value)) + value_from_ffi_type (return_value, rvalue); +} + +/** + * g_cclosure_marshal_VOID__VOID: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 1 + * @param_values: a #GValue array holding only the instance + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__BOOLEAN: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #gboolean parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gboolean arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__CHAR: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #gchar parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gchar arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__UCHAR: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #guchar parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, guchar arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__INT: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #gint parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__UINT: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #guint parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, guint arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__LONG: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #glong parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, glong arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__ULONG: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #gulong parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gulong arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__ENUM: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the enumeration parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter denotes an enumeration type.. + */ + +/** + * g_cclosure_marshal_VOID__FLAGS: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the flags parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter denotes a flags type. + */ + +/** + * g_cclosure_marshal_VOID__FLOAT: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #gfloat parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gfloat arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__DOUBLE: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #gdouble parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gdouble arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__STRING: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #gchar* parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, const gchar *arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__PARAM: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #GParamSpec* parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, GParamSpec *arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__BOXED: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #GBoxed* parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, GBoxed *arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__POINTER: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #gpointer parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, gpointer arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__OBJECT: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #GObject* parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, GObject *arg1, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_VOID__VARIANT: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 2 + * @param_values: a #GValue array holding the instance and the #GVariant* parameter + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, GVariant *arg1, gpointer user_data)`. + * + * Since: 2.26 + */ + +/** + * g_cclosure_marshal_VOID__UINT_POINTER: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: ignored + * @n_param_values: 3 + * @param_values: a #GValue array holding instance, arg1 and arg2 + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `void (*callback) (gpointer instance, guint arg1, gpointer arg2, gpointer user_data)`. + */ + +/** + * g_cclosure_marshal_BOOLEAN__FLAGS: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: a #GValue which can store the returned #gboolean + * @n_param_values: 2 + * @param_values: a #GValue array holding instance and arg1 + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `gboolean (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter + * denotes a flags type. + */ + +/** + * g_cclosure_marshal_BOOL__FLAGS: + * + * Another name for g_cclosure_marshal_BOOLEAN__FLAGS(). + */ +/** + * g_cclosure_marshal_STRING__OBJECT_POINTER: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: a #GValue, which can store the returned string + * @n_param_values: 3 + * @param_values: a #GValue array holding instance, arg1 and arg2 + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `gchar* (*callback) (gpointer instance, GObject *arg1, gpointer arg2, gpointer user_data)`. + */ +/** + * g_cclosure_marshal_BOOLEAN__OBJECT_BOXED_BOXED: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: a #GValue, which can store the returned string + * @n_param_values: 3 + * @param_values: a #GValue array holding instance, arg1 and arg2 + * @invocation_hint: the invocation hint given as the last argument + * to g_closure_invoke() + * @marshal_data: additional data specified when registering the marshaller + * + * A marshaller for a #GCClosure with a callback of type + * `gboolean (*callback) (gpointer instance, GBoxed *arg1, GBoxed *arg2, gpointer user_data)`. + * + * Since: 2.26 + */ diff --git a/gobject/gclosure.h b/gobject/gclosure.h new file mode 100644 index 0000000..f30499e --- /dev/null +++ b/gobject/gclosure.h @@ -0,0 +1,321 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000-2001 Red Hat, Inc. + * Copyright (C) 2005 Imendio AB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_CLOSURE_H__ +#define __G_CLOSURE_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* --- defines --- */ +/** + * G_CLOSURE_NEEDS_MARSHAL: + * @closure: a #GClosure + * + * Check if the closure still needs a marshaller. See g_closure_set_marshal(). + * + * Returns: %TRUE if a #GClosureMarshal marshaller has not yet been set on + * @closure. + */ +#define G_CLOSURE_NEEDS_MARSHAL(closure) (((GClosure*) (closure))->marshal == NULL) +/** + * G_CLOSURE_N_NOTIFIERS: + * @cl: a #GClosure + * + * Get the total number of notifiers connected with the closure @cl. + * + * The count includes the meta marshaller, the finalize and invalidate notifiers + * and the marshal guards. Note that each guard counts as two notifiers. + * See g_closure_set_meta_marshal(), g_closure_add_finalize_notifier(), + * g_closure_add_invalidate_notifier() and g_closure_add_marshal_guards(). + * + * Returns: number of notifiers + */ +#define G_CLOSURE_N_NOTIFIERS(cl) (((cl)->n_guards << 1L) + \ + (cl)->n_fnotifiers + (cl)->n_inotifiers) +/** + * G_CCLOSURE_SWAP_DATA: + * @cclosure: a #GCClosure + * + * Checks whether the user data of the #GCClosure should be passed as the + * first parameter to the callback. See g_cclosure_new_swap(). + * + * Returns: %TRUE if data has to be swapped. + */ +#define G_CCLOSURE_SWAP_DATA(cclosure) (((GClosure*) (cclosure))->derivative_flag) +/** + * G_CALLBACK: + * @f: a function pointer. + * + * Cast a function pointer to a #GCallback. + */ +#define G_CALLBACK(f) ((GCallback) (f)) + + +/* -- typedefs --- */ +typedef struct _GClosure GClosure; +typedef struct _GClosureNotifyData GClosureNotifyData; + +/** + * GCallback: + * + * The type used for callback functions in structure definitions and function + * signatures. + * + * This doesn't mean that all callback functions must take no parameters and + * return void. The required signature of a callback function is determined by + * the context in which is used (e.g. the signal to which it is connected). + * + * Use G_CALLBACK() to cast the callback function to a #GCallback. + */ +typedef void (*GCallback) (void); +/** + * GClosureNotify: + * @data: data specified when registering the notification callback + * @closure: the #GClosure on which the notification is emitted + * + * The type used for the various notification callbacks which can be registered + * on closures. + */ +typedef void (*GClosureNotify) (gpointer data, + GClosure *closure); +/** + * GClosureMarshal: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @n_param_values: the length of the @param_values array + * @param_values: (array length=n_param_values): an array of + * #GValues holding the arguments on which to invoke the + * callback of @closure + * @invocation_hint: (nullable): the invocation hint given as the + * last argument to g_closure_invoke() + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * The type used for marshaller functions. + */ +typedef void (*GClosureMarshal) (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/** + * GVaClosureMarshal: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is + * invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * This is the signature of va_list marshaller functions, an optional + * marshaller that can be used in some situations to avoid + * marshalling the signal argument into GValues. + */ +typedef void (* GVaClosureMarshal) (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/** + * GCClosure: + * @closure: the #GClosure + * @callback: the callback function + * + * A #GCClosure is a specialization of #GClosure for C function callbacks. + */ +typedef struct _GCClosure GCClosure; + + +/* --- structures --- */ +struct _GClosureNotifyData +{ + gpointer data; + GClosureNotify notify; +}; +/** + * GClosure: + * @in_marshal: Indicates whether the closure is currently being invoked with + * g_closure_invoke() + * @is_invalid: Indicates whether the closure has been invalidated by + * g_closure_invalidate() + * + * A #GClosure represents a callback supplied by the programmer. + */ +struct _GClosure +{ + /*< private >*/ + guint ref_count : 15; /* (atomic) */ + /* meta_marshal is not used anymore but must be zero for historical reasons + as it was exposed in the G_CLOSURE_N_NOTIFIERS macro */ + guint meta_marshal_nouse : 1; /* (atomic) */ + guint n_guards : 1; /* (atomic) */ + guint n_fnotifiers : 2; /* finalization notifiers (atomic) */ + guint n_inotifiers : 8; /* invalidation notifiers (atomic) */ + guint in_inotify : 1; /* (atomic) */ + guint floating : 1; /* (atomic) */ + /*< protected >*/ + guint derivative_flag : 1; /* (atomic) */ + /*< public >*/ + guint in_marshal : 1; /* (atomic) */ + guint is_invalid : 1; /* (atomic) */ + + /*< private >*/ void (*marshal) (GClosure *closure, + GValue /*out*/ *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + /*< protected >*/ gpointer data; + + /*< private >*/ GClosureNotifyData *notifiers; + + /* invariants/constraints: + * - ->marshal and ->data are _invalid_ as soon as ->is_invalid==TRUE + * - invocation of all inotifiers occurs prior to fnotifiers + * - order of inotifiers is random + * inotifiers may _not_ free/invalidate parameter values (e.g. ->data) + * - order of fnotifiers is random + * - each notifier may only be removed before or during its invocation + * - reference counting may only happen prior to fnotify invocation + * (in that sense, fnotifiers are really finalization handlers) + */ +}; +/* closure for C function calls, callback() is the user function + */ +struct _GCClosure +{ + GClosure closure; + gpointer callback; +}; + + +/* --- prototypes --- */ +GLIB_AVAILABLE_IN_ALL +GClosure* g_cclosure_new (GCallback callback_func, + gpointer user_data, + GClosureNotify destroy_data); +GLIB_AVAILABLE_IN_ALL +GClosure* g_cclosure_new_swap (GCallback callback_func, + gpointer user_data, + GClosureNotify destroy_data); +GLIB_AVAILABLE_IN_ALL +GClosure* g_signal_type_cclosure_new (GType itype, + guint struct_offset); + + +/* --- prototypes --- */ +GLIB_AVAILABLE_IN_ALL +GClosure* g_closure_ref (GClosure *closure); +GLIB_AVAILABLE_IN_ALL +void g_closure_sink (GClosure *closure); +GLIB_AVAILABLE_IN_ALL +void g_closure_unref (GClosure *closure); +/* intimidating */ +GLIB_AVAILABLE_IN_ALL +GClosure* g_closure_new_simple (guint sizeof_closure, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_closure_add_finalize_notifier (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func); +GLIB_AVAILABLE_IN_ALL +void g_closure_remove_finalize_notifier (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func); +GLIB_AVAILABLE_IN_ALL +void g_closure_add_invalidate_notifier (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func); +GLIB_AVAILABLE_IN_ALL +void g_closure_remove_invalidate_notifier (GClosure *closure, + gpointer notify_data, + GClosureNotify notify_func); +GLIB_AVAILABLE_IN_ALL +void g_closure_add_marshal_guards (GClosure *closure, + gpointer pre_marshal_data, + GClosureNotify pre_marshal_notify, + gpointer post_marshal_data, + GClosureNotify post_marshal_notify); +GLIB_AVAILABLE_IN_ALL +void g_closure_set_marshal (GClosure *closure, + GClosureMarshal marshal); +GLIB_AVAILABLE_IN_ALL +void g_closure_set_meta_marshal (GClosure *closure, + gpointer marshal_data, + GClosureMarshal meta_marshal); +GLIB_AVAILABLE_IN_ALL +void g_closure_invalidate (GClosure *closure); +GLIB_AVAILABLE_IN_ALL +void g_closure_invoke (GClosure *closure, + GValue /*out*/ *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint); + +/* FIXME: + OK: data_object::destroy -> closure_invalidate(); + MIS: closure_invalidate() -> disconnect(closure); + MIS: disconnect(closure) -> (unlink) closure_unref(); + OK: closure_finalize() -> g_free (data_string); + + random remarks: + - need marshaller repo with decent aliasing to base types + - provide marshaller collection, virtually covering anything out there +*/ + +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_generic (GClosure *closure, + GValue *return_gvalue, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_generic_va (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args_list, + gpointer marshal_data, + int n_params, + GType *param_types); + + +G_END_DECLS + +#endif /* __G_CLOSURE_H__ */ diff --git a/gobject/genums.c b/gobject/genums.c new file mode 100644 index 0000000..86a8b73 --- /dev/null +++ b/gobject/genums.c @@ -0,0 +1,760 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * MT safe + */ + +#include "config.h" + +#include + +#include "genums.h" +#include "gtype-private.h" +#include "gvalue.h" +#include "gvaluecollector.h" + + +/** + * SECTION:enumerations_flags + * @short_description: Enumeration and flags types + * @title: Enumeration and Flag Types + * @see_also:#GParamSpecEnum, #GParamSpecFlags, g_param_spec_enum(), + * g_param_spec_flags() + * + * The GLib type system provides fundamental types for enumeration and + * flags types. (Flags types are like enumerations, but allow their + * values to be combined by bitwise or). A registered enumeration or + * flags type associates a name and a nickname with each allowed + * value, and the methods g_enum_get_value_by_name(), + * g_enum_get_value_by_nick(), g_flags_get_value_by_name() and + * g_flags_get_value_by_nick() can look up values by their name or + * nickname. When an enumeration or flags type is registered with the + * GLib type system, it can be used as value type for object + * properties, using g_param_spec_enum() or g_param_spec_flags(). + * + * GObject ships with a utility called [glib-mkenums][glib-mkenums], + * that can construct suitable type registration functions from C enumeration + * definitions. + * + * Example of how to get a string representation of an enum value: + * |[ + * GEnumClass *enum_class; + * GEnumValue *enum_value; + * + * enum_class = g_type_class_ref (MAMAN_TYPE_MY_ENUM); + * enum_value = g_enum_get_value (enum_class, MAMAN_MY_ENUM_FOO); + * + * g_print ("Name: %s\n", enum_value->value_name); + * + * g_type_class_unref (enum_class); + * ]| + */ + + +/* --- prototypes --- */ +static void g_enum_class_init (GEnumClass *class, + gpointer class_data); +static void g_flags_class_init (GFlagsClass *class, + gpointer class_data); +static void value_flags_enum_init (GValue *value); +static void value_flags_enum_copy_value (const GValue *src_value, + GValue *dest_value); +static gchar* value_flags_enum_collect_value (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags); +static gchar* value_flags_enum_lcopy_value (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags); + +/* --- functions --- */ +void +_g_enum_types_init (void) +{ + static gboolean initialized = FALSE; + static const GTypeValueTable flags_enum_value_table = { + value_flags_enum_init, /* value_init */ + NULL, /* value_free */ + value_flags_enum_copy_value, /* value_copy */ + NULL, /* value_peek_pointer */ + "i", /* collect_format */ + value_flags_enum_collect_value, /* collect_value */ + "p", /* lcopy_format */ + value_flags_enum_lcopy_value, /* lcopy_value */ + }; + GTypeInfo info = { + 0, /* class_size */ + NULL, /* base_init */ + NULL, /* base_destroy */ + NULL, /* class_init */ + NULL, /* class_destroy */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + &flags_enum_value_table, /* value_table */ + }; + static const GTypeFundamentalInfo finfo = { + G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE, + }; + GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + g_return_if_fail (initialized == FALSE); + initialized = TRUE; + + /* G_TYPE_ENUM + */ + info.class_size = sizeof (GEnumClass); + type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo, + G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); + g_assert (type == G_TYPE_ENUM); + + /* G_TYPE_FLAGS + */ + info.class_size = sizeof (GFlagsClass); + type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo, + G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); + g_assert (type == G_TYPE_FLAGS); +} + +static void +value_flags_enum_init (GValue *value) +{ + value->data[0].v_long = 0; +} + +static void +value_flags_enum_copy_value (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_long = src_value->data[0].v_long; +} + +static gchar* +value_flags_enum_collect_value (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + if (G_VALUE_HOLDS_ENUM (value)) + value->data[0].v_long = collect_values[0].v_int; + else + value->data[0].v_ulong = (guint) collect_values[0].v_int; + + return NULL; +} + +static gchar* +value_flags_enum_lcopy_value (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gint *int_p = collect_values[0].v_pointer; + + g_return_val_if_fail (int_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *int_p = value->data[0].v_long; + + return NULL; +} + +/** + * g_enum_register_static: + * @name: A nul-terminated string used as the name of the new type. + * @const_static_values: An array of #GEnumValue structs for the possible + * enumeration values. The array is terminated by a struct with all + * members being 0. GObject keeps a reference to the data, so it cannot + * be stack-allocated. + * + * Registers a new static enumeration type with the name @name. + * + * It is normally more convenient to let [glib-mkenums][glib-mkenums], + * generate a my_enum_get_type() function from a usual C enumeration + * definition than to write one yourself using g_enum_register_static(). + * + * Returns: The new type identifier. + */ +GType +g_enum_register_static (const gchar *name, + const GEnumValue *const_static_values) +{ + GTypeInfo enum_type_info = { + sizeof (GEnumClass), /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) g_enum_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + GType type; + + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (const_static_values != NULL, 0); + + enum_type_info.class_data = const_static_values; + + type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0); + + return type; +} + +/** + * g_flags_register_static: + * @name: A nul-terminated string used as the name of the new type. + * @const_static_values: An array of #GFlagsValue structs for the possible + * flags values. The array is terminated by a struct with all members being 0. + * GObject keeps a reference to the data, so it cannot be stack-allocated. + * + * Registers a new static flags type with the name @name. + * + * It is normally more convenient to let [glib-mkenums][glib-mkenums] + * generate a my_flags_get_type() function from a usual C enumeration + * definition than to write one yourself using g_flags_register_static(). + * + * Returns: The new type identifier. + */ +GType +g_flags_register_static (const gchar *name, + const GFlagsValue *const_static_values) +{ + GTypeInfo flags_type_info = { + sizeof (GFlagsClass), /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) g_flags_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + GType type; + + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (const_static_values != NULL, 0); + + flags_type_info.class_data = const_static_values; + + type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0); + + return type; +} + +/** + * g_enum_complete_type_info: + * @g_enum_type: the type identifier of the type being completed + * @info: (out callee-allocates): the #GTypeInfo struct to be filled in + * @const_values: An array of #GEnumValue structs for the possible + * enumeration values. The array is terminated by a struct with all + * members being 0. + * + * This function is meant to be called from the `complete_type_info` + * function of a #GTypePlugin implementation, as in the following + * example: + * + * |[ + * static void + * my_enum_complete_type_info (GTypePlugin *plugin, + * GType g_type, + * GTypeInfo *info, + * GTypeValueTable *value_table) + * { + * static const GEnumValue values[] = { + * { MY_ENUM_FOO, "MY_ENUM_FOO", "foo" }, + * { MY_ENUM_BAR, "MY_ENUM_BAR", "bar" }, + * { 0, NULL, NULL } + * }; + * + * g_enum_complete_type_info (type, info, values); + * } + * ]| + */ +void +g_enum_complete_type_info (GType g_enum_type, + GTypeInfo *info, + const GEnumValue *const_values) +{ + g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type)); + g_return_if_fail (info != NULL); + g_return_if_fail (const_values != NULL); + + info->class_size = sizeof (GEnumClass); + info->base_init = NULL; + info->base_finalize = NULL; + info->class_init = (GClassInitFunc) g_enum_class_init; + info->class_finalize = NULL; + info->class_data = const_values; +} + +/** + * g_flags_complete_type_info: + * @g_flags_type: the type identifier of the type being completed + * @info: (out callee-allocates): the #GTypeInfo struct to be filled in + * @const_values: An array of #GFlagsValue structs for the possible + * enumeration values. The array is terminated by a struct with all + * members being 0. + * + * This function is meant to be called from the complete_type_info() + * function of a #GTypePlugin implementation, see the example for + * g_enum_complete_type_info() above. + */ +void +g_flags_complete_type_info (GType g_flags_type, + GTypeInfo *info, + const GFlagsValue *const_values) +{ + g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type)); + g_return_if_fail (info != NULL); + g_return_if_fail (const_values != NULL); + + info->class_size = sizeof (GFlagsClass); + info->base_init = NULL; + info->base_finalize = NULL; + info->class_init = (GClassInitFunc) g_flags_class_init; + info->class_finalize = NULL; + info->class_data = const_values; +} + +static void +g_enum_class_init (GEnumClass *class, + gpointer class_data) +{ + g_return_if_fail (G_IS_ENUM_CLASS (class)); + + class->minimum = 0; + class->maximum = 0; + class->n_values = 0; + class->values = class_data; + + if (class->values) + { + GEnumValue *values; + + class->minimum = class->values->value; + class->maximum = class->values->value; + for (values = class->values; values->value_name; values++) + { + class->minimum = MIN (class->minimum, values->value); + class->maximum = MAX (class->maximum, values->value); + class->n_values++; + } + } +} + +static void +g_flags_class_init (GFlagsClass *class, + gpointer class_data) +{ + g_return_if_fail (G_IS_FLAGS_CLASS (class)); + + class->mask = 0; + class->n_values = 0; + class->values = class_data; + + if (class->values) + { + GFlagsValue *values; + + for (values = class->values; values->value_name; values++) + { + class->mask |= values->value; + class->n_values++; + } + } +} + +/** + * g_enum_get_value_by_name: + * @enum_class: a #GEnumClass + * @name: the name to look up + * + * Looks up a #GEnumValue by name. + * + * Returns: (transfer none) (nullable): the #GEnumValue with name @name, + * or %NULL if the enumeration doesn't have a member + * with that name + */ +GEnumValue* +g_enum_get_value_by_name (GEnumClass *enum_class, + const gchar *name) +{ + g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); + g_return_val_if_fail (name != NULL, NULL); + + if (enum_class->n_values) + { + GEnumValue *enum_value; + + for (enum_value = enum_class->values; enum_value->value_name; enum_value++) + if (strcmp (name, enum_value->value_name) == 0) + return enum_value; + } + + return NULL; +} + +/** + * g_flags_get_value_by_name: + * @flags_class: a #GFlagsClass + * @name: the name to look up + * + * Looks up a #GFlagsValue by name. + * + * Returns: (transfer none) (nullable): the #GFlagsValue with name @name, + * or %NULL if there is no flag with that name + */ +GFlagsValue* +g_flags_get_value_by_name (GFlagsClass *flags_class, + const gchar *name) +{ + g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); + g_return_val_if_fail (name != NULL, NULL); + + if (flags_class->n_values) + { + GFlagsValue *flags_value; + + for (flags_value = flags_class->values; flags_value->value_name; flags_value++) + if (strcmp (name, flags_value->value_name) == 0) + return flags_value; + } + + return NULL; +} + +/** + * g_enum_get_value_by_nick: + * @enum_class: a #GEnumClass + * @nick: the nickname to look up + * + * Looks up a #GEnumValue by nickname. + * + * Returns: (transfer none) (nullable): the #GEnumValue with nickname @nick, + * or %NULL if the enumeration doesn't have a member + * with that nickname + */ +GEnumValue* +g_enum_get_value_by_nick (GEnumClass *enum_class, + const gchar *nick) +{ + g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); + g_return_val_if_fail (nick != NULL, NULL); + + if (enum_class->n_values) + { + GEnumValue *enum_value; + + for (enum_value = enum_class->values; enum_value->value_name; enum_value++) + if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0) + return enum_value; + } + + return NULL; +} + +/** + * g_flags_get_value_by_nick: + * @flags_class: a #GFlagsClass + * @nick: the nickname to look up + * + * Looks up a #GFlagsValue by nickname. + * + * Returns: (transfer none) (nullable): the #GFlagsValue with nickname @nick, + * or %NULL if there is no flag with that nickname + */ +GFlagsValue* +g_flags_get_value_by_nick (GFlagsClass *flags_class, + const gchar *nick) +{ + g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); + g_return_val_if_fail (nick != NULL, NULL); + + if (flags_class->n_values) + { + GFlagsValue *flags_value; + + for (flags_value = flags_class->values; flags_value->value_nick; flags_value++) + if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0) + return flags_value; + } + + return NULL; +} + +/** + * g_enum_get_value: + * @enum_class: a #GEnumClass + * @value: the value to look up + * + * Returns the #GEnumValue for a value. + * + * Returns: (transfer none) (nullable): the #GEnumValue for @value, or %NULL + * if @value is not a member of the enumeration + */ +GEnumValue* +g_enum_get_value (GEnumClass *enum_class, + gint value) +{ + g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); + + if (enum_class->n_values) + { + GEnumValue *enum_value; + + for (enum_value = enum_class->values; enum_value->value_name; enum_value++) + if (enum_value->value == value) + return enum_value; + } + + return NULL; +} + +/** + * g_flags_get_first_value: + * @flags_class: a #GFlagsClass + * @value: the value + * + * Returns the first #GFlagsValue which is set in @value. + * + * Returns: (transfer none) (nullable): the first #GFlagsValue which is set in + * @value, or %NULL if none is set + */ +GFlagsValue* +g_flags_get_first_value (GFlagsClass *flags_class, + guint value) +{ + g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); + + if (flags_class->n_values) + { + GFlagsValue *flags_value; + + if (value == 0) + { + for (flags_value = flags_class->values; flags_value->value_name; flags_value++) + if (flags_value->value == 0) + return flags_value; + } + else + { + for (flags_value = flags_class->values; flags_value->value_name; flags_value++) + if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value) + return flags_value; + } + } + + return NULL; +} + +/** + * g_enum_to_string: + * @g_enum_type: the type identifier of a #GEnumClass type + * @value: the value + * + * Pretty-prints @value in the form of the enum’s name. + * + * This is intended to be used for debugging purposes. The format of the output + * may change in the future. + * + * Returns: (transfer full): a newly-allocated text string + * + * Since: 2.54 + */ +gchar * +g_enum_to_string (GType g_enum_type, + gint value) +{ + gchar *result; + GEnumClass *enum_class; + GEnumValue *enum_value; + + g_return_val_if_fail (G_TYPE_IS_ENUM (g_enum_type), NULL); + + enum_class = g_type_class_ref (g_enum_type); + + /* Already warned */ + if (enum_class == NULL) + return g_strdup_printf ("%d", value); + + enum_value = g_enum_get_value (enum_class, value); + + if (enum_value == NULL) + result = g_strdup_printf ("%d", value); + else + result = g_strdup (enum_value->value_name); + + g_type_class_unref (enum_class); + return result; +} + +/* + * g_flags_get_value_string: + * @flags_class: a #GFlagsClass + * @value: the value + * + * Pretty-prints @value in the form of the flag names separated by ` | ` and + * sorted. Any extra bits will be shown at the end as a hexadecimal number. + * + * This is intended to be used for debugging purposes. The format of the output + * may change in the future. + * + * Returns: (transfer full): a newly-allocated text string + * + * Since: 2.54 + */ +static gchar * +g_flags_get_value_string (GFlagsClass *flags_class, + guint value) +{ + GString *str; + GFlagsValue *flags_value; + + g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); + + str = g_string_new (NULL); + + while ((str->len == 0 || value != 0) && + (flags_value = g_flags_get_first_value (flags_class, value)) != NULL) + { + if (str->len > 0) + g_string_append (str, " | "); + + g_string_append (str, flags_value->value_name); + + value &= ~flags_value->value; + } + + /* Show the extra bits */ + if (value != 0 || str->len == 0) + { + if (str->len > 0) + g_string_append (str, " | "); + + g_string_append_printf (str, "0x%x", value); + } + + return g_string_free (str, FALSE); +} + +/** + * g_flags_to_string: + * @flags_type: the type identifier of a #GFlagsClass type + * @value: the value + * + * Pretty-prints @value in the form of the flag names separated by ` | ` and + * sorted. Any extra bits will be shown at the end as a hexadecimal number. + * + * This is intended to be used for debugging purposes. The format of the output + * may change in the future. + * + * Returns: (transfer full): a newly-allocated text string + * + * Since: 2.54 + */ +gchar * +g_flags_to_string (GType flags_type, + guint value) +{ + gchar *result; + GFlagsClass *flags_class; + + g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL); + + flags_class = g_type_class_ref (flags_type); + + /* Already warned */ + if (flags_class == NULL) + return NULL; + + result = g_flags_get_value_string (flags_class, value); + + g_type_class_unref (flags_class); + return result; +} + + +/** + * g_value_set_enum: + * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM + * @v_enum: enum value to be set + * + * Set the contents of a %G_TYPE_ENUM #GValue to @v_enum. + */ +void +g_value_set_enum (GValue *value, + gint v_enum) +{ + g_return_if_fail (G_VALUE_HOLDS_ENUM (value)); + + value->data[0].v_long = v_enum; +} + +/** + * g_value_get_enum: + * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM + * + * Get the contents of a %G_TYPE_ENUM #GValue. + * + * Returns: enum contents of @value + */ +gint +g_value_get_enum (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0); + + return value->data[0].v_long; +} + +/** + * g_value_set_flags: + * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS + * @v_flags: flags value to be set + * + * Set the contents of a %G_TYPE_FLAGS #GValue to @v_flags. + */ +void +g_value_set_flags (GValue *value, + guint v_flags) +{ + g_return_if_fail (G_VALUE_HOLDS_FLAGS (value)); + + value->data[0].v_ulong = v_flags; +} + +/** + * g_value_get_flags: + * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS + * + * Get the contents of a %G_TYPE_FLAGS #GValue. + * + * Returns: flags contents of @value + */ +guint +g_value_get_flags (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0); + + return value->data[0].v_ulong; +} diff --git a/gobject/genums.h b/gobject/genums.h new file mode 100644 index 0000000..c66ce45 --- /dev/null +++ b/gobject/genums.h @@ -0,0 +1,279 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_ENUMS_H__ +#define __G_ENUMS_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* --- type macros --- */ +/** + * G_TYPE_IS_ENUM: + * @type: a #GType ID. + * + * Checks whether @type "is a" %G_TYPE_ENUM. + * + * Returns: %TRUE if @type "is a" %G_TYPE_ENUM. + */ +#define G_TYPE_IS_ENUM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM) +/** + * G_ENUM_CLASS: + * @class: a valid #GEnumClass + * + * Casts a derived #GEnumClass structure into a #GEnumClass structure. + */ +#define G_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_ENUM, GEnumClass)) +/** + * G_IS_ENUM_CLASS: + * @class: a #GEnumClass + * + * Checks whether @class "is a" valid #GEnumClass structure of type %G_TYPE_ENUM + * or derived. + */ +#define G_IS_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_ENUM)) +/** + * G_ENUM_CLASS_TYPE: + * @class: a #GEnumClass + * + * Get the type identifier from a given #GEnumClass structure. + * + * Returns: the #GType + */ +#define G_ENUM_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +/** + * G_ENUM_CLASS_TYPE_NAME: + * @class: a #GEnumClass + * + * Get the static type name from a given #GEnumClass structure. + * + * Returns: the type name. + */ +#define G_ENUM_CLASS_TYPE_NAME(class) (g_type_name (G_ENUM_CLASS_TYPE (class))) + + +/** + * G_TYPE_IS_FLAGS: + * @type: a #GType ID. + * + * Checks whether @type "is a" %G_TYPE_FLAGS. + * + * Returns: %TRUE if @type "is a" %G_TYPE_FLAGS. + */ +#define G_TYPE_IS_FLAGS(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_FLAGS) +/** + * G_FLAGS_CLASS: + * @class: a valid #GFlagsClass + * + * Casts a derived #GFlagsClass structure into a #GFlagsClass structure. + */ +#define G_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_FLAGS, GFlagsClass)) +/** + * G_IS_FLAGS_CLASS: + * @class: a #GFlagsClass + * + * Checks whether @class "is a" valid #GFlagsClass structure of type %G_TYPE_FLAGS + * or derived. + */ +#define G_IS_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_FLAGS)) +/** + * G_FLAGS_CLASS_TYPE: + * @class: a #GFlagsClass + * + * Get the type identifier from a given #GFlagsClass structure. + * + * Returns: the #GType + */ +#define G_FLAGS_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +/** + * G_FLAGS_CLASS_TYPE_NAME: + * @class: a #GFlagsClass + * + * Get the static type name from a given #GFlagsClass structure. + * + * Returns: the type name. + */ +#define G_FLAGS_CLASS_TYPE_NAME(class) (g_type_name (G_FLAGS_CLASS_TYPE (class))) + + +/** + * G_VALUE_HOLDS_ENUM: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values derived from type %G_TYPE_ENUM. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_ENUM(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_ENUM)) +/** + * G_VALUE_HOLDS_FLAGS: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values derived from type %G_TYPE_FLAGS. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_FLAGS(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_FLAGS)) + + +/* --- enum/flag values & classes --- */ +typedef struct _GEnumClass GEnumClass; +typedef struct _GFlagsClass GFlagsClass; +typedef struct _GEnumValue GEnumValue; +typedef struct _GFlagsValue GFlagsValue; + +/** + * GEnumClass: + * @g_type_class: the parent class + * @minimum: the smallest possible value. + * @maximum: the largest possible value. + * @n_values: the number of possible values. + * @values: an array of #GEnumValue structs describing the + * individual values. + * + * The class of an enumeration type holds information about its + * possible values. + */ +struct _GEnumClass +{ + GTypeClass g_type_class; + + /*< public >*/ + gint minimum; + gint maximum; + guint n_values; + GEnumValue *values; +}; +/** + * GFlagsClass: + * @g_type_class: the parent class + * @mask: a mask covering all possible values. + * @n_values: the number of possible values. + * @values: an array of #GFlagsValue structs describing the + * individual values. + * + * The class of a flags type holds information about its + * possible values. + */ +struct _GFlagsClass +{ + GTypeClass g_type_class; + + /*< public >*/ + guint mask; + guint n_values; + GFlagsValue *values; +}; +/** + * GEnumValue: + * @value: the enum value + * @value_name: the name of the value + * @value_nick: the nickname of the value + * + * A structure which contains a single enum value, its name, and its + * nickname. + */ +struct _GEnumValue +{ + gint value; + const gchar *value_name; + const gchar *value_nick; +}; +/** + * GFlagsValue: + * @value: the flags value + * @value_name: the name of the value + * @value_nick: the nickname of the value + * + * A structure which contains a single flags value, its name, and its + * nickname. + */ +struct _GFlagsValue +{ + guint value; + const gchar *value_name; + const gchar *value_nick; +}; + + +/* --- prototypes --- */ +GLIB_AVAILABLE_IN_ALL +GEnumValue* g_enum_get_value (GEnumClass *enum_class, + gint value); +GLIB_AVAILABLE_IN_ALL +GEnumValue* g_enum_get_value_by_name (GEnumClass *enum_class, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +GEnumValue* g_enum_get_value_by_nick (GEnumClass *enum_class, + const gchar *nick); +GLIB_AVAILABLE_IN_ALL +GFlagsValue* g_flags_get_first_value (GFlagsClass *flags_class, + guint value); +GLIB_AVAILABLE_IN_ALL +GFlagsValue* g_flags_get_value_by_name (GFlagsClass *flags_class, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +GFlagsValue* g_flags_get_value_by_nick (GFlagsClass *flags_class, + const gchar *nick); +GLIB_AVAILABLE_IN_2_54 +gchar *g_enum_to_string (GType g_enum_type, + gint value); +GLIB_AVAILABLE_IN_2_54 +gchar *g_flags_to_string (GType flags_type, + guint value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_enum (GValue *value, + gint v_enum); +GLIB_AVAILABLE_IN_ALL +gint g_value_get_enum (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_flags (GValue *value, + guint v_flags); +GLIB_AVAILABLE_IN_ALL +guint g_value_get_flags (const GValue *value); + + + +/* --- registration functions --- */ +/* const_static_values is a NULL terminated array of enum/flags + * values that is taken over! + */ +GLIB_AVAILABLE_IN_ALL +GType g_enum_register_static (const gchar *name, + const GEnumValue *const_static_values); +GLIB_AVAILABLE_IN_ALL +GType g_flags_register_static (const gchar *name, + const GFlagsValue *const_static_values); +/* functions to complete the type information + * for enums/flags implemented by plugins + */ +GLIB_AVAILABLE_IN_ALL +void g_enum_complete_type_info (GType g_enum_type, + GTypeInfo *info, + const GEnumValue *const_values); +GLIB_AVAILABLE_IN_ALL +void g_flags_complete_type_info (GType g_flags_type, + GTypeInfo *info, + const GFlagsValue *const_values); + +G_END_DECLS + +#endif /* __G_ENUMS_H__ */ diff --git a/gobject/glib-enumtypes.c.template b/gobject/glib-enumtypes.c.template new file mode 100644 index 0000000..42f9c34 --- /dev/null +++ b/gobject/glib-enumtypes.c.template @@ -0,0 +1,47 @@ +/*** BEGIN file-header ***/ +#include "config.h" +#include "glib-enumtypes.h" +#include + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +/*** END file-header ***/ + +/*** BEGIN file-tail ***/ + +G_GNUC_END_IGNORE_DEPRECATIONS + +/*** END file-tail ***/ + +/*** BEGIN file-production ***/ +/* enumerations from "@filename@" */ + +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static gsize static_g_define_type_id = 0; + + if (g_once_init_enter (&static_g_define_type_id)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + + return static_g_define_type_id; +} + +/*** END value-tail ***/ diff --git a/gobject/glib-enumtypes.h.template b/gobject/glib-enumtypes.h.template new file mode 100644 index 0000000..2a4b0e4 --- /dev/null +++ b/gobject/glib-enumtypes.h.template @@ -0,0 +1,24 @@ +/*** BEGIN file-header ***/ +#ifndef __GOBJECT_ENUM_TYPES_H__ +#define __GOBJECT_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS +/*** END file-header ***/ + +/*** BEGIN file-production ***/ + +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GLIB_AVAILABLE_IN_2_60 GType @enum_name@_get_type (void) G_GNUC_CONST; +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) +/*** END value-header ***/ + +/*** BEGIN file-tail ***/ +G_END_DECLS + +#endif /* __GOBJECT_ENUM_TYPES_H__ */ +/*** END file-tail ***/ diff --git a/gobject/glib-genmarshal.in b/gobject/glib-genmarshal.in new file mode 100755 index 0000000..20e08e4 --- /dev/null +++ b/gobject/glib-genmarshal.in @@ -0,0 +1,1080 @@ +#!/usr/bin/env @PYTHON@ + +# pylint: disable=too-many-lines, missing-docstring, invalid-name + +# This file is part of GLib +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . + +import argparse +import os +import re +import sys + +VERSION_STR = '''glib-genmarshal version @VERSION@ +glib-genmarshal comes with ABSOLUTELY NO WARRANTY. +You may redistribute copies of glib-genmarshal under the terms of +the GNU General Public License which can be found in the +GLib source package. Sources, examples and contact +information are available at http://www.gtk.org''' + +GETTERS_STR = '''#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */''' + +DEPRECATED_MSG_STR = 'The token "{}" is deprecated; use "{}" instead' + +VA_ARG_STR = \ + ' arg{:d} = ({:s}) va_arg (args_copy, {:s});' +STATIC_CHECK_STR = \ + '(param_types[{:d}] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && ' +BOX_TYPED_STR = \ + ' arg{idx:d} = {box_func} (param_types[{idx:d}] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg{idx:d});' +BOX_UNTYPED_STR = \ + ' arg{idx:d} = {box_func} (arg{idx:d});' +UNBOX_TYPED_STR = \ + ' {unbox_func} (param_types[{idx:d}] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg{idx:d});' +UNBOX_UNTYPED_STR = \ + ' {unbox_func} (arg{idx:d});' + +STD_PREFIX = 'g_cclosure_marshal' + +# These are part of our ABI; keep this in sync with gmarshal.h +GOBJECT_MARSHALLERS = { + 'g_cclosure_marshal_VOID__VOID', + 'g_cclosure_marshal_VOID__BOOLEAN', + 'g_cclosure_marshal_VOID__CHAR', + 'g_cclosure_marshal_VOID__UCHAR', + 'g_cclosure_marshal_VOID__INT', + 'g_cclosure_marshal_VOID__UINT', + 'g_cclosure_marshal_VOID__LONG', + 'g_cclosure_marshal_VOID__ULONG', + 'g_cclosure_marshal_VOID__ENUM', + 'g_cclosure_marshal_VOID__FLAGS', + 'g_cclosure_marshal_VOID__FLOAT', + 'g_cclosure_marshal_VOID__DOUBLE', + 'g_cclosure_marshal_VOID__STRING', + 'g_cclosure_marshal_VOID__PARAM', + 'g_cclosure_marshal_VOID__BOXED', + 'g_cclosure_marshal_VOID__POINTER', + 'g_cclosure_marshal_VOID__OBJECT', + 'g_cclosure_marshal_VOID__VARIANT', + 'g_cclosure_marshal_VOID__UINT_POINTER', + 'g_cclosure_marshal_BOOLEAN__FLAGS', + 'g_cclosure_marshal_STRING__OBJECT_POINTER', + 'g_cclosure_marshal_BOOLEAN__BOXED_BOXED', +} + + +# pylint: disable=too-few-public-methods +class Color: + '''ANSI Terminal colors''' + GREEN = '\033[1;32m' + BLUE = '\033[1;34m' + YELLOW = '\033[1;33m' + RED = '\033[1;31m' + END = '\033[0m' + + +def print_color(msg, color=Color.END, prefix='MESSAGE'): + '''Print a string with a color prefix''' + if os.isatty(sys.stderr.fileno()): + real_prefix = '{start}{prefix}{end}'.format(start=color, prefix=prefix, end=Color.END) + else: + real_prefix = prefix + sys.stderr.write('{prefix}: {msg}\n'.format(prefix=real_prefix, msg=msg)) + + +def print_error(msg): + '''Print an error, and terminate''' + print_color(msg, color=Color.RED, prefix='ERROR') + sys.exit(1) + + +def print_warning(msg, fatal=False): + '''Print a warning, and optionally terminate''' + if fatal: + color = Color.RED + prefix = 'ERROR' + else: + color = Color.YELLOW + prefix = 'WARNING' + print_color(msg, color, prefix) + if fatal: + sys.exit(1) + + +def print_info(msg): + '''Print a message''' + print_color(msg, color=Color.GREEN, prefix='INFO') + + +def generate_licensing_comment(outfile): + outfile.write('/* This file is generated by glib-genmarshal, do not ' + 'modify it. This code is licensed under the same license as ' + 'the containing project. Note that it links to GLib, so ' + 'must comply with the LGPL linking clauses. */\n') + + +def generate_header_preamble(outfile, prefix='', std_includes=True, use_pragma=False): + '''Generate the preamble for the marshallers header file''' + generate_licensing_comment(outfile) + + if use_pragma: + outfile.write('#pragma once\n') + outfile.write('\n') + else: + outfile.write('#ifndef __{}_MARSHAL_H__\n'.format(prefix.upper())) + outfile.write('#define __{}_MARSHAL_H__\n'.format(prefix.upper())) + outfile.write('\n') + # Maintain compatibility with the old C-based tool + if std_includes: + outfile.write('#include \n') + outfile.write('\n') + + outfile.write('G_BEGIN_DECLS\n') + outfile.write('\n') + + +def generate_header_postamble(outfile, prefix='', use_pragma=False): + '''Generate the postamble for the marshallers header file''' + outfile.write('\n') + outfile.write('G_END_DECLS\n') + + if not use_pragma: + outfile.write('\n') + outfile.write('#endif /* __{}_MARSHAL_H__ */\n'.format(prefix.upper())) + + +def generate_body_preamble(outfile, std_includes=True, include_headers=None, cpp_defines=None, cpp_undefines=None): + '''Generate the preamble for the marshallers source file''' + generate_licensing_comment(outfile) + + for header in (include_headers or []): + outfile.write('#include "{}"\n'.format(header)) + if include_headers: + outfile.write('\n') + + for define in (cpp_defines or []): + s = define.split('=') + symbol = s[0] + value = s[1] if len(s) > 1 else '1' + outfile.write('#define {} {}\n'.format(symbol, value)) + if cpp_defines: + outfile.write('\n') + + for undefine in (cpp_undefines or []): + outfile.write('#undef {}\n'.format(undefine)) + if cpp_undefines: + outfile.write('\n') + + if std_includes: + outfile.write('#include \n') + outfile.write('\n') + + outfile.write(GETTERS_STR) + outfile.write('\n\n') + + +# Marshaller arguments, as a dictionary where the key is the token used in +# the source file, and the value is another dictionary with the following +# keys: +# +# - signal: the token used in the marshaller prototype (mandatory) +# - ctype: the C type for the marshaller argument (mandatory) +# - getter: the function used to retrieve the argument from the GValue +# array when invoking the callback (optional) +# - promoted: the C type used by va_arg() to retrieve the argument from +# the va_list when invoking the callback (optional, only used when +# generating va_list marshallers) +# - box: an array of two elements, containing the boxing and unboxing +# functions for the given type (optional, only used when generating +# va_list marshallers) +# - static-check: a boolean value, if the given type should perform +# a static type check before boxing or unboxing the argument (optional, +# only used when generating va_list marshallers) +# - takes-type: a boolean value, if the boxing and unboxing functions +# for the given type require the type (optional, only used when +# generating va_list marshallers) +# - deprecated: whether the token has been deprecated (optional) +# - replaced-by: the token used to replace a deprecated token (optional, +# only used if deprecated is True) +IN_ARGS = { + 'VOID': { + 'signal': 'VOID', + 'ctype': 'void', + }, + 'BOOLEAN': { + 'signal': 'BOOLEAN', + 'ctype': 'gboolean', + 'getter': 'g_marshal_value_peek_boolean', + }, + 'CHAR': { + 'signal': 'CHAR', + 'ctype': 'gchar', + 'promoted': 'gint', + 'getter': 'g_marshal_value_peek_char', + }, + 'UCHAR': { + 'signal': 'UCHAR', + 'ctype': 'guchar', + 'promoted': 'guint', + 'getter': 'g_marshal_value_peek_uchar', + }, + 'INT': { + 'signal': 'INT', + 'ctype': 'gint', + 'getter': 'g_marshal_value_peek_int', + }, + 'UINT': { + 'signal': 'UINT', + 'ctype': 'guint', + 'getter': 'g_marshal_value_peek_uint', + }, + 'LONG': { + 'signal': 'LONG', + 'ctype': 'glong', + 'getter': 'g_marshal_value_peek_long', + }, + 'ULONG': { + 'signal': 'ULONG', + 'ctype': 'gulong', + 'getter': 'g_marshal_value_peek_ulong', + }, + 'INT64': { + 'signal': 'INT64', + 'ctype': 'gint64', + 'getter': 'g_marshal_value_peek_int64', + }, + 'UINT64': { + 'signal': 'UINT64', + 'ctype': 'guint64', + 'getter': 'g_marshal_value_peek_uint64', + }, + 'ENUM': { + 'signal': 'ENUM', + 'ctype': 'gint', + 'getter': 'g_marshal_value_peek_enum', + }, + 'FLAGS': { + 'signal': 'FLAGS', + 'ctype': 'guint', + 'getter': 'g_marshal_value_peek_flags', + }, + 'FLOAT': { + 'signal': 'FLOAT', + 'ctype': 'gfloat', + 'promoted': 'gdouble', + 'getter': 'g_marshal_value_peek_float', + }, + 'DOUBLE': { + 'signal': 'DOUBLE', + 'ctype': 'gdouble', + 'getter': 'g_marshal_value_peek_double', + }, + 'STRING': { + 'signal': 'STRING', + 'ctype': 'gpointer', + 'getter': 'g_marshal_value_peek_string', + 'box': ['g_strdup', 'g_free'], + 'static-check': True, + }, + 'PARAM': { + 'signal': 'PARAM', + 'ctype': 'gpointer', + 'getter': 'g_marshal_value_peek_param', + 'box': ['g_param_spec_ref', 'g_param_spec_unref'], + 'static-check': True, + }, + 'BOXED': { + 'signal': 'BOXED', + 'ctype': 'gpointer', + 'getter': 'g_marshal_value_peek_boxed', + 'box': ['g_boxed_copy', 'g_boxed_free'], + 'static-check': True, + 'takes-type': True, + }, + 'POINTER': { + 'signal': 'POINTER', + 'ctype': 'gpointer', + 'getter': 'g_marshal_value_peek_pointer', + }, + 'OBJECT': { + 'signal': 'OBJECT', + 'ctype': 'gpointer', + 'getter': 'g_marshal_value_peek_object', + 'box': ['g_object_ref', 'g_object_unref'], + }, + 'VARIANT': { + 'signal': 'VARIANT', + 'ctype': 'gpointer', + 'getter': 'g_marshal_value_peek_variant', + 'box': ['g_variant_ref_sink', 'g_variant_unref'], + 'static-check': True, + 'takes-type': False, + }, + + # Deprecated tokens + 'NONE': { + 'signal': 'VOID', + 'ctype': 'void', + 'deprecated': True, + 'replaced_by': 'VOID' + }, + 'BOOL': { + 'signal': 'BOOLEAN', + 'ctype': 'gboolean', + 'getter': 'g_marshal_value_peek_boolean', + 'deprecated': True, + 'replaced_by': 'BOOLEAN' + } +} + + +# Marshaller return values, as a dictionary where the key is the token used +# in the source file, and the value is another dictionary with the following +# keys: +# +# - signal: the token used in the marshaller prototype (mandatory) +# - ctype: the C type for the marshaller argument (mandatory) +# - setter: the function used to set the return value of the callback +# into a GValue (optional) +# - deprecated: whether the token has been deprecated (optional) +# - replaced-by: the token used to replace a deprecated token (optional, +# only used if deprecated is True) +OUT_ARGS = { + 'VOID': { + 'signal': 'VOID', + 'ctype': 'void', + }, + 'BOOLEAN': { + 'signal': 'BOOLEAN', + 'ctype': 'gboolean', + 'setter': 'g_value_set_boolean', + }, + 'CHAR': { + 'signal': 'CHAR', + 'ctype': 'gchar', + 'setter': 'g_value_set_char', + }, + 'UCHAR': { + 'signal': 'UCHAR', + 'ctype': 'guchar', + 'setter': 'g_value_set_uchar', + }, + 'INT': { + 'signal': 'INT', + 'ctype': 'gint', + 'setter': 'g_value_set_int', + }, + 'UINT': { + 'signal': 'UINT', + 'ctype': 'guint', + 'setter': 'g_value_set_uint', + }, + 'LONG': { + 'signal': 'LONG', + 'ctype': 'glong', + 'setter': 'g_value_set_long', + }, + 'ULONG': { + 'signal': 'ULONG', + 'ctype': 'gulong', + 'setter': 'g_value_set_ulong', + }, + 'INT64': { + 'signal': 'INT64', + 'ctype': 'gint64', + 'setter': 'g_value_set_int64', + }, + 'UINT64': { + 'signal': 'UINT64', + 'ctype': 'guint64', + 'setter': 'g_value_set_uint64', + }, + 'ENUM': { + 'signal': 'ENUM', + 'ctype': 'gint', + 'setter': 'g_value_set_enum', + }, + 'FLAGS': { + 'signal': 'FLAGS', + 'ctype': 'guint', + 'setter': 'g_value_set_flags', + }, + 'FLOAT': { + 'signal': 'FLOAT', + 'ctype': 'gfloat', + 'setter': 'g_value_set_float', + }, + 'DOUBLE': { + 'signal': 'DOUBLE', + 'ctype': 'gdouble', + 'setter': 'g_value_set_double', + }, + 'STRING': { + 'signal': 'STRING', + 'ctype': 'gchar*', + 'setter': 'g_value_take_string', + }, + 'PARAM': { + 'signal': 'PARAM', + 'ctype': 'GParamSpec*', + 'setter': 'g_value_take_param', + }, + 'BOXED': { + 'signal': 'BOXED', + 'ctype': 'gpointer', + 'setter': 'g_value_take_boxed', + }, + 'POINTER': { + 'signal': 'POINTER', + 'ctype': 'gpointer', + 'setter': 'g_value_set_pointer', + }, + 'OBJECT': { + 'signal': 'OBJECT', + 'ctype': 'GObject*', + 'setter': 'g_value_take_object', + }, + 'VARIANT': { + 'signal': 'VARIANT', + 'ctype': 'GVariant*', + 'setter': 'g_value_take_variant', + }, + + # Deprecated tokens + 'NONE': { + 'signal': 'VOID', + 'ctype': 'void', + 'setter': None, + 'deprecated': True, + 'replaced_by': 'VOID', + }, + 'BOOL': { + 'signal': 'BOOLEAN', + 'ctype': 'gboolean', + 'setter': 'g_value_set_boolean', + 'deprecated': True, + 'replaced_by': 'BOOLEAN', + }, +} + + +def check_args(retval, params, fatal_warnings=False): + '''Check the @retval and @params tokens for invalid and deprecated symbols.''' + if retval not in OUT_ARGS: + print_error('Unknown return value type "{}"'.format(retval)) + + if OUT_ARGS[retval].get('deprecated', False): + replaced_by = OUT_ARGS[retval]['replaced_by'] + print_warning(DEPRECATED_MSG_STR.format(retval, replaced_by), fatal_warnings) + + for param in params: + if param not in IN_ARGS: + print_error('Unknown parameter type "{}"'.format(param)) + else: + if IN_ARGS[param].get('deprecated', False): + replaced_by = IN_ARGS[param]['replaced_by'] + print_warning(DEPRECATED_MSG_STR.format(param, replaced_by), fatal_warnings) + + +def indent(text, level=0, fill=' '): + '''Indent @text by @level columns, using the @fill character''' + return ''.join([fill for x in range(level)]) + text + + +# pylint: disable=too-few-public-methods +class Visibility: + '''Symbol visibility options''' + NONE = 0 + INTERNAL = 1 + EXTERN = 2 + + +def generate_marshaller_name(prefix, retval, params, replace_deprecated=True): + '''Generate a marshaller name for the given @prefix, @retval, and @params. + If @replace_deprecated is True, the generated name will replace deprecated + tokens.''' + if replace_deprecated: + real_retval = OUT_ARGS[retval]['signal'] + real_params = [] + for param in params: + real_params.append(IN_ARGS[param]['signal']) + else: + real_retval = retval + real_params = params + return '{prefix}_{retval}__{args}'.format(prefix=prefix, + retval=real_retval, + args='_'.join(real_params)) + + +def generate_prototype(retval, params, + prefix='g_cclosure_user_marshal', + visibility=Visibility.NONE, + va_marshal=False): + '''Generate a marshaller declaration with the given @visibility. If @va_marshal + is True, the marshaller will use variadic arguments in place of a GValue array.''' + signature = [] + + if visibility == Visibility.INTERNAL: + signature += ['G_GNUC_INTERNAL'] + elif visibility == Visibility.EXTERN: + signature += ['extern'] + + function_name = generate_marshaller_name(prefix, retval, params) + + if not va_marshal: + signature += ['void ' + function_name + ' (GClosure *closure,'] + width = len('void ') + len(function_name) + 2 + + signature += [indent('GValue *return_value,', level=width, fill=' ')] + signature += [indent('guint n_param_values,', level=width, fill=' ')] + signature += [indent('const GValue *param_values,', level=width, fill=' ')] + signature += [indent('gpointer invocation_hint,', level=width, fill=' ')] + signature += [indent('gpointer marshal_data);', level=width, fill=' ')] + else: + signature += ['void ' + function_name + 'v (GClosure *closure,'] + width = len('void ') + len(function_name) + 3 + + signature += [indent('GValue *return_value,', level=width, fill=' ')] + signature += [indent('gpointer instance,', level=width, fill=' ')] + signature += [indent('va_list args,', level=width, fill=' ')] + signature += [indent('gpointer marshal_data,', level=width, fill=' ')] + signature += [indent('int n_params,', level=width, fill=' ')] + signature += [indent('GType *param_types);', level=width, fill=' ')] + + return signature + + +# pylint: disable=too-many-statements, too-many-locals, too-many-branches +def generate_body(retval, params, prefix, va_marshal=False): + '''Generate a marshaller definition. If @va_marshal is True, the marshaller + will use va_list and variadic arguments in place of a GValue array.''' + retval_setter = OUT_ARGS[retval].get('setter', None) + # If there's no return value then we can mark the retval argument as unused + # and get a minor optimisation, as well as avoid a compiler warning + if not retval_setter: + unused = ' G_GNUC_UNUSED' + else: + unused = '' + + body = ['void'] + + function_name = generate_marshaller_name(prefix, retval, params) + + if not va_marshal: + body += [function_name + ' (GClosure *closure,'] + width = len(function_name) + 2 + + body += [indent('GValue *return_value{},'.format(unused), level=width, fill=' ')] + body += [indent('guint n_param_values,', level=width, fill=' ')] + body += [indent('const GValue *param_values,', level=width, fill=' ')] + body += [indent('gpointer invocation_hint G_GNUC_UNUSED,', level=width, fill=' ')] + body += [indent('gpointer marshal_data)', level=width, fill=' ')] + else: + body += [function_name + 'v (GClosure *closure,'] + width = len(function_name) + 3 + + body += [indent('GValue *return_value{},'.format(unused), level=width, fill=' ')] + body += [indent('gpointer instance,', level=width, fill=' ')] + body += [indent('va_list args,', level=width, fill=' ')] + body += [indent('gpointer marshal_data,', level=width, fill=' ')] + body += [indent('int n_params,', level=width, fill=' ')] + body += [indent('GType *param_types)', level=width, fill=' ')] + + # Filter the arguments that have a getter + get_args = [x for x in params if IN_ARGS[x].get('getter', None) is not None] + + body += ['{'] + + # Generate the type of the marshaller function + typedef_marshal = generate_marshaller_name('GMarshalFunc', retval, params) + + typedef = ' typedef {ctype} (*{func_name}) ('.format(ctype=OUT_ARGS[retval]['ctype'], + func_name=typedef_marshal) + pad = len(typedef) + typedef += 'gpointer data1,' + body += [typedef] + + for idx, in_arg in enumerate(get_args): + body += [indent('{} arg{:d},'.format(IN_ARGS[in_arg]['ctype'], idx + 1), level=pad)] + + body += [indent('gpointer data2);', level=pad)] + + # Variable declarations + body += [' GCClosure *cc = (GCClosure *) closure;'] + body += [' gpointer data1, data2;'] + body += [' {} callback;'.format(typedef_marshal)] + + if retval_setter: + body += [' {} v_return;'.format(OUT_ARGS[retval]['ctype'])] + + if va_marshal: + for idx, arg in enumerate(get_args): + body += [' {} arg{:d};'.format(IN_ARGS[arg]['ctype'], idx)] + + if get_args: + body += [' va_list args_copy;'] + body += [''] + + body += [' G_VA_COPY (args_copy, args);'] + + for idx, arg in enumerate(get_args): + ctype = IN_ARGS[arg]['ctype'] + promoted_ctype = IN_ARGS[arg].get('promoted', ctype) + body += [VA_ARG_STR.format(idx, ctype, promoted_ctype)] + if IN_ARGS[arg].get('box', None): + box_func = IN_ARGS[arg]['box'][0] + if IN_ARGS[arg].get('static-check', False): + static_check = STATIC_CHECK_STR.format(idx) + else: + static_check = '' + arg_check = 'arg{:d} != NULL'.format(idx) + body += [' if ({}{})'.format(static_check, arg_check)] + if IN_ARGS[arg].get('takes-type', False): + body += [BOX_TYPED_STR.format(idx=idx, box_func=box_func)] + else: + body += [BOX_UNTYPED_STR.format(idx=idx, box_func=box_func)] + + body += [' va_end (args_copy);'] + + body += [''] + + # Preconditions check + if retval_setter: + body += [' g_return_if_fail (return_value != NULL);'] + + if not va_marshal: + body += [' g_return_if_fail (n_param_values == {:d});'.format(len(get_args) + 1)] + + body += [''] + + # Marshal instance, data, and callback set up + body += [' if (G_CCLOSURE_SWAP_DATA (closure))'] + body += [' {'] + body += [' data1 = closure->data;'] + if va_marshal: + body += [' data2 = instance;'] + else: + body += [' data2 = g_value_peek_pointer (param_values + 0);'] + body += [' }'] + body += [' else'] + body += [' {'] + if va_marshal: + body += [' data1 = instance;'] + else: + body += [' data1 = g_value_peek_pointer (param_values + 0);'] + body += [' data2 = closure->data;'] + body += [' }'] + # pylint: disable=line-too-long + body += [' callback = ({}) (marshal_data ? marshal_data : cc->callback);'.format(typedef_marshal)] + body += [''] + + # Marshal callback action + if retval_setter: + callback = ' {} callback ('.format(' v_return =') + else: + callback = ' callback (' + + pad = len(callback) + body += [callback + 'data1,'] + + if va_marshal: + for idx, arg in enumerate(get_args): + body += [indent('arg{:d},'.format(idx), level=pad)] + else: + for idx, arg in enumerate(get_args): + arg_getter = IN_ARGS[arg]['getter'] + body += [indent('{} (param_values + {:d}),'.format(arg_getter, idx + 1), level=pad)] + + body += [indent('data2);', level=pad)] + + if va_marshal: + boxed_args = [x for x in get_args if IN_ARGS[x].get('box', None) is not None] + if not boxed_args: + body += [''] + else: + for idx, arg in enumerate(get_args): + if not IN_ARGS[arg].get('box', None): + continue + unbox_func = IN_ARGS[arg]['box'][1] + if IN_ARGS[arg].get('static-check', False): + static_check = STATIC_CHECK_STR.format(idx) + else: + static_check = '' + arg_check = 'arg{:d} != NULL'.format(idx) + body += [' if ({}{})'.format(static_check, arg_check)] + if IN_ARGS[arg].get('takes-type', False): + body += [UNBOX_TYPED_STR.format(idx=idx, unbox_func=unbox_func)] + else: + body += [UNBOX_UNTYPED_STR.format(idx=idx, unbox_func=unbox_func)] + + if retval_setter: + body += [''] + body += [' {} (return_value, v_return);'.format(retval_setter)] + + body += ['}'] + + return body + + +def generate_marshaller_alias(outfile, marshaller, real_marshaller, + include_va=False, + source_location=None): + '''Generate an alias between @marshaller and @real_marshaller, including + an optional alias for va_list marshallers''' + if source_location: + outfile.write('/* {} */\n'.format(source_location)) + + outfile.write('#define {}\t{}\n'.format(marshaller, real_marshaller)) + + if include_va: + outfile.write('#define {}v\t{}v\n'.format(marshaller, real_marshaller)) + + outfile.write('\n') + + +def generate_marshallers_header(outfile, retval, params, + prefix='g_cclosure_user_marshal', + internal=False, + include_va=False, source_location=None): + '''Generate a declaration for a marshaller function, to be used in the header, + with the given @retval, @params, and @prefix. An optional va_list marshaller + for the same arguments is also generated. The generated buffer is written to + the @outfile stream object.''' + if source_location: + outfile.write('/* {} */\n'.format(source_location)) + + if internal: + visibility = Visibility.INTERNAL + else: + visibility = Visibility.EXTERN + + signature = generate_prototype(retval, params, prefix, visibility, False) + if include_va: + signature += generate_prototype(retval, params, prefix, visibility, True) + signature += [''] + + outfile.write('\n'.join(signature)) + outfile.write('\n') + + +def generate_marshallers_body(outfile, retval, params, + prefix='g_cclosure_user_marshal', + include_prototype=True, + internal=False, + include_va=False, source_location=None): + '''Generate a definition for a marshaller function, to be used in the source, + with the given @retval, @params, and @prefix. An optional va_list marshaller + for the same arguments is also generated. The generated buffer is written to + the @outfile stream object.''' + if source_location: + outfile.write('/* {} */\n'.format(source_location)) + + if include_prototype: + # Declaration visibility + if internal: + decl_visibility = Visibility.INTERNAL + else: + decl_visibility = Visibility.EXTERN + proto = ['/* Prototype for -Wmissing-prototypes */'] + # Add C++ guards in case somebody compiles the generated code + # with a C++ compiler + proto += ['G_BEGIN_DECLS'] + proto += generate_prototype(retval, params, prefix, decl_visibility, False) + proto += ['G_END_DECLS'] + outfile.write('\n'.join(proto)) + outfile.write('\n') + + body = generate_body(retval, params, prefix, False) + outfile.write('\n'.join(body)) + outfile.write('\n\n') + + if include_va: + if include_prototype: + # Declaration visibility + if internal: + decl_visibility = Visibility.INTERNAL + else: + decl_visibility = Visibility.EXTERN + proto = ['/* Prototype for -Wmissing-prototypes */'] + # Add C++ guards here as well + proto += ['G_BEGIN_DECLS'] + proto += generate_prototype(retval, params, prefix, decl_visibility, True) + proto += ['G_END_DECLS'] + outfile.write('\n'.join(proto)) + outfile.write('\n') + + body = generate_body(retval, params, prefix, True) + outfile.write('\n'.join(body)) + outfile.write('\n\n') + + +def parse_args(): + arg_parser = argparse.ArgumentParser(description='Generate signal marshallers for GObject') + arg_parser.add_argument('--prefix', metavar='STRING', + default='g_cclosure_user_marshal', + help='Specify marshaller prefix') + arg_parser.add_argument('--output', metavar='FILE', + type=argparse.FileType('w'), + default=sys.stdout, + help='Write output into the specified file') + arg_parser.add_argument('--skip-source', + action='store_true', + help='Skip source location comments') + arg_parser.add_argument('--internal', + action='store_true', + help='Mark generated functions as internal') + arg_parser.add_argument('--valist-marshallers', + action='store_true', + help='Generate va_list marshallers') + arg_parser.add_argument('-v', '--version', + action='store_true', + dest='show_version', + help='Print version information, and exit') + arg_parser.add_argument('--g-fatal-warnings', + action='store_true', + dest='fatal_warnings', + help='Make warnings fatal') + arg_parser.add_argument('--include-header', metavar='HEADER', nargs='?', + action='append', + dest='include_headers', + help='Include the specified header in the body') + arg_parser.add_argument('--pragma-once', + action='store_true', + help='Use "pragma once" as the inclusion guard') + arg_parser.add_argument('-D', + action='append', + dest='cpp_defines', + default=[], + help='Pre-processor define') + arg_parser.add_argument('-U', + action='append', + dest='cpp_undefines', + default=[], + help='Pre-processor undefine') + arg_parser.add_argument('files', metavar='FILE', nargs='*', + type=argparse.FileType('r'), + help='Files with lists of marshallers to generate, ' + + 'or "-" for standard input') + arg_parser.add_argument('--prototypes', + action='store_true', + help='Generate the marshallers prototype in the C code') + arg_parser.add_argument('--header', + action='store_true', + help='Generate C headers') + arg_parser.add_argument('--body', + action='store_true', + help='Generate C code') + + group = arg_parser.add_mutually_exclusive_group() + group.add_argument('--stdinc', + action='store_true', + dest='stdinc', default=True, + help='Include standard marshallers') + group.add_argument('--nostdinc', + action='store_false', + dest='stdinc', default=True, + help='Use standard marshallers') + + group = arg_parser.add_mutually_exclusive_group() + group.add_argument('--quiet', + action='store_true', + help='Only print warnings and errors') + group.add_argument('--verbose', + action='store_true', + help='Be verbose, and include debugging information') + + args = arg_parser.parse_args() + + if args.show_version: + print(VERSION_STR) + sys.exit(0) + + return args + + +def generate(args): + # Backward compatibility hack; some projects use both arguments to + # generate the marshallers prototype in the C source, even though + # it's not really a supported use case. We keep this behaviour by + # forcing the --prototypes and --body arguments instead. We make this + # warning non-fatal even with --g-fatal-warnings, as it's a deprecation + compatibility_mode = False + if args.header and args.body: + print_warning('Using --header and --body at the same time is deprecated; ' + + 'use --body --prototypes instead', False) + args.prototypes = True + args.header = False + compatibility_mode = True + + if args.header: + generate_header_preamble(args.output, + prefix=args.prefix, + std_includes=args.stdinc, + use_pragma=args.pragma_once) + elif args.body: + generate_body_preamble(args.output, + std_includes=args.stdinc, + include_headers=args.include_headers, + cpp_defines=args.cpp_defines, + cpp_undefines=args.cpp_undefines) + + seen_marshallers = set() + + for infile in args.files: + if not args.quiet: + print_info('Reading {}...'.format(infile.name)) + + line_count = 0 + for line in infile: + line_count += 1 + + if line == '\n' or line.startswith('#'): + continue + + matches = re.match(r'^([A-Z0-9]+)\s?:\s?([A-Z0-9,\s]+)$', line.strip()) + if not matches or len(matches.groups()) != 2: + print_warning('Invalid entry: "{}"'.format(line.strip()), args.fatal_warnings) + continue + + if not args.skip_source: + location = '{} ({}:{:d})'.format(line.strip(), infile.name, line_count) + else: + location = None + + retval = matches.group(1).strip() + params = [x.strip() for x in matches.group(2).split(',')] + check_args(retval, params, args.fatal_warnings) + + raw_marshaller = generate_marshaller_name(args.prefix, retval, params, False) + if raw_marshaller in seen_marshallers: + if args.verbose: + print_info('Skipping repeated marshaller {}'.format(line.strip())) + continue + + if args.header: + if args.verbose: + print_info('Generating declaration for {}'.format(line.strip())) + generate_std_alias = False + if args.stdinc: + std_marshaller = generate_marshaller_name(STD_PREFIX, retval, params) + if std_marshaller in GOBJECT_MARSHALLERS: + if args.verbose: + print_info('Skipping default marshaller {}'.format(line.strip())) + generate_std_alias = True + + marshaller = generate_marshaller_name(args.prefix, retval, params) + if generate_std_alias: + generate_marshaller_alias(args.output, marshaller, std_marshaller, + source_location=location, + include_va=args.valist_marshallers) + else: + generate_marshallers_header(args.output, retval, params, + prefix=args.prefix, + internal=args.internal, + include_va=args.valist_marshallers, + source_location=location) + # If the marshaller is defined using a deprecated token, we want to maintain + # compatibility and generate an alias for the old name pointing to the new + # one + if marshaller != raw_marshaller: + if args.verbose: + print_info('Generating alias for deprecated tokens') + generate_marshaller_alias(args.output, raw_marshaller, marshaller, + include_va=args.valist_marshallers) + elif args.body: + if args.verbose: + print_info('Generating definition for {}'.format(line.strip())) + generate_std_alias = False + if args.stdinc: + std_marshaller = generate_marshaller_name(STD_PREFIX, retval, params) + if std_marshaller in GOBJECT_MARSHALLERS: + if args.verbose: + print_info('Skipping default marshaller {}'.format(line.strip())) + generate_std_alias = True + marshaller = generate_marshaller_name(args.prefix, retval, params) + if generate_std_alias: + # We need to generate the alias if we are in compatibility mode + if compatibility_mode: + generate_marshaller_alias(args.output, marshaller, std_marshaller, + source_location=location, + include_va=args.valist_marshallers) + else: + generate_marshallers_body(args.output, retval, params, + prefix=args.prefix, + internal=args.internal, + include_prototype=args.prototypes, + include_va=args.valist_marshallers, + source_location=location) + if compatibility_mode and marshaller != raw_marshaller: + if args.verbose: + print_info('Generating alias for deprecated tokens') + generate_marshaller_alias(args.output, raw_marshaller, marshaller, + include_va=args.valist_marshallers) + + seen_marshallers.add(raw_marshaller) + + if args.header: + generate_header_postamble(args.output, prefix=args.prefix, use_pragma=args.pragma_once) + + +if __name__ == '__main__': + args = parse_args() + + with args.output: + generate(args) diff --git a/gobject/glib-mkenums.in b/gobject/glib-mkenums.in new file mode 100755 index 0000000..b996a73 --- /dev/null +++ b/gobject/glib-mkenums.in @@ -0,0 +1,806 @@ +#!/usr/bin/env @PYTHON@ + +# If the code below looks horrible and unpythonic, do not panic. +# +# It is. +# +# This is a manual conversion from the original Perl script to +# Python. Improvements are welcome. +# +from __future__ import print_function, unicode_literals + +import argparse +import os +import re +import sys +import tempfile +import io +import errno +import codecs +import locale + +VERSION_STR = '''glib-mkenums version @VERSION@ +glib-mkenums comes with ABSOLUTELY NO WARRANTY. +You may redistribute copies of glib-mkenums under the terms of +the GNU General Public License which can be found in the +GLib source package. Sources, examples and contact +information are available at http://www.gtk.org''' + +# pylint: disable=too-few-public-methods +class Color: + '''ANSI Terminal colors''' + GREEN = '\033[1;32m' + BLUE = '\033[1;34m' + YELLOW = '\033[1;33m' + RED = '\033[1;31m' + END = '\033[0m' + + +def print_color(msg, color=Color.END, prefix='MESSAGE'): + '''Print a string with a color prefix''' + if os.isatty(sys.stderr.fileno()): + real_prefix = '{start}{prefix}{end}'.format(start=color, prefix=prefix, end=Color.END) + else: + real_prefix = prefix + print('{prefix}: {msg}'.format(prefix=real_prefix, msg=msg), file=sys.stderr) + + +def print_error(msg): + '''Print an error, and terminate''' + print_color(msg, color=Color.RED, prefix='ERROR') + sys.exit(1) + + +def print_warning(msg, fatal=False): + '''Print a warning, and optionally terminate''' + if fatal: + color = Color.RED + prefix = 'ERROR' + else: + color = Color.YELLOW + prefix = 'WARNING' + print_color(msg, color, prefix) + if fatal: + sys.exit(1) + + +def print_info(msg): + '''Print a message''' + print_color(msg, color=Color.GREEN, prefix='INFO') + + +def get_rspfile_args(rspfile): + ''' + Response files are useful on Windows where there is a command-line character + limit of 8191 because when passing sources as arguments to glib-mkenums this + limit can be exceeded in large codebases. + + There is no specification for response files and each tool that supports it + generally writes them out in slightly different ways, but some sources are: + https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-response-files + https://docs.microsoft.com/en-us/windows/desktop/midl/the-response-file-command + ''' + import shlex + if not os.path.isfile(rspfile): + sys.exit('Response file {!r} does not exist'.format(rspfile)) + try: + with open(rspfile, 'r') as f: + cmdline = f.read() + except OSError as e: + sys.exit('Response file {!r} could not be read: {}' + .format(rspfile, e.strerror)) + return shlex.split(cmdline) + + +def write_output(output): + global output_stream + print(output, file=output_stream) + + +# Python 2 defaults to ASCII in case stdout is redirected. +# This should make it match Python 3, which uses the locale encoding. +if sys.stdout.encoding is None: + output_stream = codecs.getwriter( + locale.getpreferredencoding())(sys.stdout) +else: + output_stream = sys.stdout + + +# Some source files aren't UTF-8 and the old perl version didn't care. +# Replace invalid data with a replacement character to keep things working. +# https://bugzilla.gnome.org/show_bug.cgi?id=785113#c20 +def replace_and_warn(err): + # 7 characters of context either side of the offending character + print_warning('UnicodeWarning: {} at {} ({})'.format( + err.reason, err.start, + err.object[err.start - 7:err.end + 7])) + return ('?', err.end) + +codecs.register_error('replace_and_warn', replace_and_warn) + + +# glib-mkenums.py +# Information about the current enumeration +flags = None # Is enumeration a bitmask? +option_underscore_name = '' # Overridden underscore variant of the enum name + # for example to fix the cases we don't get the + # mixed-case -> underscorized transform right. +option_lowercase_name = '' # DEPRECATED. A lower case name to use as part + # of the *_get_type() function, instead of the + # one that we guess. For instance, when an enum + # uses abnormal capitalization and we can not + # guess where to put the underscores. +option_since = '' # User provided version info for the enum. +seenbitshift = 0 # Have we seen bitshift operators? +seenprivate = False # Have we seen a private option? +enum_prefix = None # Prefix for this enumeration +enumname = '' # Name for this enumeration +enumshort = '' # $enumname without prefix +enumname_prefix = '' # prefix of $enumname +enumindex = 0 # Global enum counter +firstenum = 1 # Is this the first enumeration per file? +entries = [] # [ name, val ] for each entry +sandbox = None # sandbox for safe evaluation of expressions + +output = '' # Filename to write result into + +def parse_trigraph(opts): + result = {} + + for opt in re.split(r'\s*,\s*', opts): + opt = re.sub(r'^\s*', '', opt) + opt = re.sub(r'\s*$', '', opt) + m = re.search(r'(\w+)(?:=(.+))?', opt) + assert m is not None + groups = m.groups() + key = groups[0] + if len(groups) > 1: + val = groups[1] + else: + val = 1 + result[key] = val + return result + +def parse_entries(file, file_name): + global entries, enumindex, enumname, seenbitshift, seenprivate, flags + looking_for_name = False + + while True: + line = file.readline() + if not line: + break + + line = line.strip() + + # read lines until we have no open comments + while re.search(r'/\*([^*]|\*(?!/))*$', line): + line += file.readline() + + # strip comments w/o options + line = re.sub(r'''/\*(?!<) + ([^*]+|\*(?!/))* + \*/''', '', line, flags=re.X) + + line = line.rstrip() + + # skip empty lines + if len(line.strip()) == 0: + continue + + if looking_for_name: + m = re.match(r'\s*(\w+)', line) + if m: + enumname = m.group(1) + return True + + # Handle include files + m = re.match(r'\#include\s*<([^>]*)>', line) + if m: + newfilename = os.path.join("..", m.group(1)) + newfile = io.open(newfilename, encoding="utf-8", + errors="replace_and_warn") + + if not parse_entries(newfile, newfilename): + return False + else: + continue + + m = re.match(r'\s*\}\s*(\w+)', line) + if m: + enumname = m.group(1) + enumindex += 1 + return 1 + + m = re.match(r'\s*\}', line) + if m: + enumindex += 1 + looking_for_name = True + continue + + m = re.match(r'''\s* + (\w+)\s* # name + (\s+[A-Z]+_(?:AVAILABLE|DEPRECATED)_ENUMERATOR_IN_[0-9_]+(?:_FOR\s*\(\s*\w+\s*\))?\s*)? # availability + (?:=( # value + \s*\w+\s*\(.*\)\s* # macro with multiple args + | # OR + (?:[^,/]|/(?!\*))* # anything but a comma or comment + ))?,?\s* + (?:/\*< # options + (([^*]|\*(?!/))*) + >\s*\*/)?,? + \s*$''', line, flags=re.X) + if m: + groups = m.groups() + name = groups[0] + availability = None + value = None + options = None + if len(groups) > 1: + availability = groups[1] + if len(groups) > 2: + value = groups[2] + if len(groups) > 3: + options = groups[3] + if flags is None and value is not None and '<<' in value: + seenbitshift = 1 + + if seenprivate: + continue + + if options is not None: + options = parse_trigraph(options) + if 'skip' not in options: + entries.append((name, value, options.get('nick'))) + else: + entries.append((name, value)) + else: + m = re.match(r'''\s* + /\*< (([^*]|\*(?!/))*) >\s*\*/ + \s*$''', line, flags=re.X) + if m: + options = m.groups()[0] + if options is not None: + options = parse_trigraph(options) + if 'private' in options: + seenprivate = True + continue + if 'public' in options: + seenprivate = False + continue + if re.match(r's*\#', line): + pass + else: + print_warning('Failed to parse "{}" in {}'.format(line, file_name)) + return False + +help_epilog = '''Production text substitutions: + \u0040EnumName\u0040 PrefixTheXEnum + \u0040enum_name\u0040 prefix_the_xenum + \u0040ENUMNAME\u0040 PREFIX_THE_XENUM + \u0040ENUMSHORT\u0040 THE_XENUM + \u0040ENUMPREFIX\u0040 PREFIX + \u0040enumsince\u0040 the user-provided since value given + \u0040VALUENAME\u0040 PREFIX_THE_XVALUE + \u0040valuenick\u0040 the-xvalue + \u0040valuenum\u0040 the integer value (limited support, Since: 2.26) + \u0040type\u0040 either enum or flags + \u0040Type\u0040 either Enum or Flags + \u0040TYPE\u0040 either ENUM or FLAGS + \u0040filename\u0040 name of current input file + \u0040basename\u0040 base name of the current input file (Since: 2.22) +''' + + +# production variables: +idprefix = "" # "G", "Gtk", etc +symprefix = "" # "g", "gtk", etc, if not just lc($idprefix) +fhead = "" # output file header +fprod = "" # per input file production +ftail = "" # output file trailer +eprod = "" # per enum text (produced prior to value itarations) +vhead = "" # value header, produced before iterating over enum values +vprod = "" # value text, produced for each enum value +vtail = "" # value tail, produced after iterating over enum values +comment_tmpl = "" # comment template + +def read_template_file(file): + global idprefix, symprefix, fhead, fprod, ftail, eprod, vhead, vprod, vtail, comment_tmpl + tmpl = {'file-header': fhead, + 'file-production': fprod, + 'file-tail': ftail, + 'enumeration-production': eprod, + 'value-header': vhead, + 'value-production': vprod, + 'value-tail': vtail, + 'comment': comment_tmpl, + } + in_ = 'junk' + + ifile = io.open(file, encoding="utf-8", errors="replace_and_warn") + for line in ifile: + m = re.match(r'\/\*\*\*\s+(BEGIN|END)\s+([\w-]+)\s+\*\*\*\/', line) + if m: + if in_ == 'junk' and m.group(1) == 'BEGIN' and m.group(2) in tmpl: + in_ = m.group(2) + continue + elif in_ == m.group(2) and m.group(1) == 'END' and m.group(2) in tmpl: + in_ = 'junk' + continue + else: + sys.exit("Malformed template file " + file) + + if in_ != 'junk': + tmpl[in_] += line + + if in_ != 'junk': + sys.exit("Malformed template file " + file) + + fhead = tmpl['file-header'] + fprod = tmpl['file-production'] + ftail = tmpl['file-tail'] + eprod = tmpl['enumeration-production'] + vhead = tmpl['value-header'] + vprod = tmpl['value-production'] + vtail = tmpl['value-tail'] + comment_tmpl = tmpl['comment'] + +parser = argparse.ArgumentParser(epilog=help_epilog, + formatter_class=argparse.RawDescriptionHelpFormatter) + +parser.add_argument('--identifier-prefix', default='', dest='idprefix', + help='Identifier prefix') +parser.add_argument('--symbol-prefix', default='', dest='symprefix', + help='Symbol prefix') +parser.add_argument('--fhead', default=[], dest='fhead', action='append', + help='Output file header') +parser.add_argument('--ftail', default=[], dest='ftail', action='append', + help='Output file footer') +parser.add_argument('--fprod', default=[], dest='fprod', action='append', + help='Put out TEXT every time a new input file is being processed.') +parser.add_argument('--eprod', default=[], dest='eprod', action='append', + help='Per enum text, produced prior to value iterations') +parser.add_argument('--vhead', default=[], dest='vhead', action='append', + help='Value header, produced before iterating over enum values') +parser.add_argument('--vprod', default=[], dest='vprod', action='append', + help='Value text, produced for each enum value.') +parser.add_argument('--vtail', default=[], dest='vtail', action='append', + help='Value tail, produced after iterating over enum values') +parser.add_argument('--comments', default='', dest='comment_tmpl', + help='Comment structure') +parser.add_argument('--template', default='', dest='template', + help='Template file') +parser.add_argument('--output', default=None, dest='output') +parser.add_argument('--version', '-v', default=False, action='store_true', dest='version', + help='Print version information') +parser.add_argument('args', nargs='*', + help='One or more input files, or a single argument @rspfile_path ' + 'pointing to a file that contains the actual arguments') + +# Support reading an rspfile of the form @filename which contains the args +# to be parsed +if len(sys.argv) == 2 and sys.argv[1].startswith('@'): + args = get_rspfile_args(sys.argv[1][1:]) +else: + args = sys.argv[1:] + +options = parser.parse_args(args) + +if options.version: + print(VERSION_STR) + sys.exit(0) + +def unescape_cmdline_args(arg): + arg = arg.replace('\\n', '\n') + arg = arg.replace('\\r', '\r') + return arg.replace('\\t', '\t') + +if options.template != '': + read_template_file(options.template) + +idprefix += options.idprefix +symprefix += options.symprefix + +# This is a hack to maintain some semblance of backward compatibility with +# the old, Perl-based glib-mkenums. The old tool had an implicit ordering +# on the arguments and templates; each argument was parsed in order, and +# all the strings appended. This allowed developers to write: +# +# glib-mkenums \ +# --fhead ... \ +# --template a-template-file.c.in \ +# --ftail ... +# +# And have the fhead be prepended to the file-head stanza in the template, +# as well as the ftail be appended to the file-tail stanza in the template. +# Short of throwing away ArgumentParser and going over sys.argv[] element +# by element, we can simulate that behaviour by ensuring some ordering in +# how we build the template strings: +# +# - the head stanzas are always prepended to the template +# - the prod stanzas are always appended to the template +# - the tail stanzas are always appended to the template +# +# Within each instance of the command line argument, we append each value +# to the array in the order in which it appears on the command line. +fhead = ''.join([unescape_cmdline_args(x) for x in options.fhead]) + fhead +vhead = ''.join([unescape_cmdline_args(x) for x in options.vhead]) + vhead + +fprod += ''.join([unescape_cmdline_args(x) for x in options.fprod]) +eprod += ''.join([unescape_cmdline_args(x) for x in options.eprod]) +vprod += ''.join([unescape_cmdline_args(x) for x in options.vprod]) + +ftail = ftail + ''.join([unescape_cmdline_args(x) for x in options.ftail]) +vtail = vtail + ''.join([unescape_cmdline_args(x) for x in options.vtail]) + +if options.comment_tmpl != '': + comment_tmpl = unescape_cmdline_args(options.comment_tmpl) +elif comment_tmpl == "": + # default to C-style comments + comment_tmpl = "/* \u0040comment\u0040 */" + +output = options.output + +if output is not None: + (out_dir, out_fn) = os.path.split(options.output) + out_suffix = '_' + os.path.splitext(out_fn)[1] + if out_dir == '': + out_dir = '.' + fd, filename = tempfile.mkstemp(dir=out_dir) + os.close(fd) + tmpfile = io.open(filename, "w", encoding="utf-8") + output_stream = tmpfile +else: + tmpfile = None + +# put auto-generation comment +comment = comment_tmpl.replace('\u0040comment\u0040', + 'This file is generated by glib-mkenums, do ' + 'not modify it. This code is licensed under ' + 'the same license as the containing project. ' + 'Note that it links to GLib, so must comply ' + 'with the LGPL linking clauses.') +write_output("\n" + comment + '\n') + +def replace_specials(prod): + prod = prod.replace(r'\\a', r'\a') + prod = prod.replace(r'\\b', r'\b') + prod = prod.replace(r'\\t', r'\t') + prod = prod.replace(r'\\n', r'\n') + prod = prod.replace(r'\\f', r'\f') + prod = prod.replace(r'\\r', r'\r') + prod = prod.rstrip() + return prod + + +def warn_if_filename_basename_used(section, prod): + for substitution in ('\u0040filename\u0040', + '\u0040basename\u0040'): + if substitution in prod: + print_warning('{} used in {} section.'.format(substitution, + section)) + +if len(fhead) > 0: + prod = fhead + warn_if_filename_basename_used('file-header', prod) + prod = replace_specials(prod) + write_output(prod) + +def process_file(curfilename): + global entries, flags, seenbitshift, seenprivate, enum_prefix + firstenum = True + + try: + curfile = io.open(curfilename, encoding="utf-8", + errors="replace_and_warn") + except IOError as e: + if e.errno == errno.ENOENT: + print_warning('No file "{}" found.'.format(curfilename)) + return + raise + + while True: + line = curfile.readline() + if not line: + break + + line = line.strip() + + # read lines until we have no open comments + while re.search(r'/\*([^*]|\*(?!/))*$', line): + line += curfile.readline() + + # strip comments w/o options + line = re.sub(r'''/\*(?!<) + ([^*]+|\*(?!/))* + \*/''', '', line) + + # ignore forward declarations + if re.match(r'\s*typedef\s+enum.*;', line): + continue + + m = re.match(r'''\s*typedef\s+enum\s*[_A-Za-z]*[_A-Za-z0-9]*\s* + ({)?\s* + (?:/\*< + (([^*]|\*(?!/))*) + >\s*\*/)? + \s*({)?''', line, flags=re.X) + if m: + groups = m.groups() + if len(groups) >= 2 and groups[1] is not None: + options = parse_trigraph(groups[1]) + if 'skip' in options: + continue + enum_prefix = options.get('prefix', None) + flags = options.get('flags', None) + if 'flags' in options: + if flags is None: + flags = 1 + else: + flags = int(flags) + option_lowercase_name = options.get('lowercase_name', None) + option_underscore_name = options.get('underscore_name', None) + option_since = options.get('since', None) + else: + enum_prefix = None + flags = None + option_lowercase_name = None + option_underscore_name = None + option_since = None + + if option_lowercase_name is not None: + if option_underscore_name is not None: + print_warning("lowercase_name overridden with underscore_name") + option_lowercase_name = None + else: + print_warning("lowercase_name is deprecated, use underscore_name") + + # Didn't have trailing '{' look on next lines + if groups[0] is None and (len(groups) < 4 or groups[3] is None): + while True: + line = curfile.readline() + if not line: + print_error("Syntax error when looking for opening { in enum") + if re.match(r'\s*\{', line): + break + + seenbitshift = 0 + seenprivate = False + entries = [] + + # Now parse the entries + parse_entries(curfile, curfilename) + + # figure out if this was a flags or enums enumeration + if flags is None: + flags = seenbitshift + + # Autogenerate a prefix + if enum_prefix is None: + for entry in entries: + if len(entry) < 3 or entry[2] is None: + name = entry[0] + if enum_prefix is not None: + enum_prefix = os.path.commonprefix([name, enum_prefix]) + else: + enum_prefix = name + if enum_prefix is None: + enum_prefix = "" + else: + # Trim so that it ends in an underscore + enum_prefix = re.sub(r'_[^_]*$', '_', enum_prefix) + else: + # canonicalize user defined prefixes + enum_prefix = enum_prefix.upper() + enum_prefix = enum_prefix.replace('-', '_') + enum_prefix = re.sub(r'(.*)([^_])$', r'\1\2_', enum_prefix) + + fixed_entries = [] + for e in entries: + name = e[0] + num = e[1] + if len(e) < 3 or e[2] is None: + nick = re.sub(r'^' + enum_prefix, '', name) + nick = nick.replace('_', '-').lower() + e = (name, num, nick) + fixed_entries.append(e) + entries = fixed_entries + + # Spit out the output + if option_underscore_name is not None: + enumlong = option_underscore_name.upper() + enumsym = option_underscore_name.lower() + enumshort = re.sub(r'^[A-Z][A-Z0-9]*_', '', enumlong) + + enumname_prefix = re.sub('_' + enumshort + '$', '', enumlong) + elif symprefix == '' and idprefix == '': + # enumname is e.g. GMatchType + enspace = re.sub(r'^([A-Z][a-z]*).*$', r'\1', enumname) + + enumshort = re.sub(r'^[A-Z][a-z]*', '', enumname) + enumshort = re.sub(r'([^A-Z])([A-Z])', r'\1_\2', enumshort) + enumshort = re.sub(r'([A-Z][A-Z])([A-Z][0-9a-z])', r'\1_\2', enumshort) + enumshort = enumshort.upper() + + enumname_prefix = re.sub(r'^([A-Z][a-z]*).*$', r'\1', enumname).upper() + + enumlong = enspace.upper() + "_" + enumshort + enumsym = enspace.lower() + "_" + enumshort.lower() + + if option_lowercase_name is not None: + enumsym = option_lowercase_name + else: + enumshort = enumname + if idprefix: + enumshort = re.sub(r'^' + idprefix, '', enumshort) + else: + enumshort = re.sub(r'/^[A-Z][a-z]*', '', enumshort) + + enumshort = re.sub(r'([^A-Z])([A-Z])', r'\1_\2', enumshort) + enumshort = re.sub(r'([A-Z][A-Z])([A-Z][0-9a-z])', r'\1_\2', enumshort) + enumshort = enumshort.upper() + + if symprefix: + enumname_prefix = symprefix.upper() + else: + enumname_prefix = idprefix.upper() + + enumlong = enumname_prefix + "_" + enumshort + enumsym = enumlong.lower() + + if option_since is not None: + enumsince = option_since + else: + enumsince = "" + + if firstenum: + firstenum = False + + if len(fprod) > 0: + prod = fprod + base = os.path.basename(curfilename) + + prod = prod.replace('\u0040filename\u0040', curfilename) + prod = prod.replace('\u0040basename\u0040', base) + prod = replace_specials(prod) + + write_output(prod) + + if len(eprod) > 0: + prod = eprod + + prod = prod.replace('\u0040enum_name\u0040', enumsym) + prod = prod.replace('\u0040EnumName\u0040', enumname) + prod = prod.replace('\u0040ENUMSHORT\u0040', enumshort) + prod = prod.replace('\u0040ENUMNAME\u0040', enumlong) + prod = prod.replace('\u0040ENUMPREFIX\u0040', enumname_prefix) + prod = prod.replace('\u0040enumsince\u0040', enumsince) + if flags: + prod = prod.replace('\u0040type\u0040', 'flags') + else: + prod = prod.replace('\u0040type\u0040', 'enum') + if flags: + prod = prod.replace('\u0040Type\u0040', 'Flags') + else: + prod = prod.replace('\u0040Type\u0040', 'Enum') + if flags: + prod = prod.replace('\u0040TYPE\u0040', 'FLAGS') + else: + prod = prod.replace('\u0040TYPE\u0040', 'ENUM') + prod = replace_specials(prod) + write_output(prod) + + if len(vhead) > 0: + prod = vhead + prod = prod.replace('\u0040enum_name\u0040', enumsym) + prod = prod.replace('\u0040EnumName\u0040', enumname) + prod = prod.replace('\u0040ENUMSHORT\u0040', enumshort) + prod = prod.replace('\u0040ENUMNAME\u0040', enumlong) + prod = prod.replace('\u0040ENUMPREFIX\u0040', enumname_prefix) + prod = prod.replace('\u0040enumsince\u0040', enumsince) + if flags: + prod = prod.replace('\u0040type\u0040', 'flags') + else: + prod = prod.replace('\u0040type\u0040', 'enum') + if flags: + prod = prod.replace('\u0040Type\u0040', 'Flags') + else: + prod = prod.replace('\u0040Type\u0040', 'Enum') + if flags: + prod = prod.replace('\u0040TYPE\u0040', 'FLAGS') + else: + prod = prod.replace('\u0040TYPE\u0040', 'ENUM') + prod = replace_specials(prod) + write_output(prod) + + if len(vprod) > 0: + prod = vprod + next_num = 0 + + prod = replace_specials(prod) + for name, num, nick in entries: + tmp_prod = prod + + if '\u0040valuenum\u0040' in prod: + # only attempt to eval the value if it is requested + # this prevents us from throwing errors otherwise + if num is not None: + # use sandboxed evaluation as a reasonable + # approximation to C constant folding + inum = eval(num, {}, {}) + + # make sure it parsed to an integer + if not isinstance(inum, int): + sys.exit("Unable to parse enum value '%s'" % num) + num = inum + else: + num = next_num + + tmp_prod = tmp_prod.replace('\u0040valuenum\u0040', str(num)) + next_num = int(num) + 1 + + tmp_prod = tmp_prod.replace('\u0040VALUENAME\u0040', name) + tmp_prod = tmp_prod.replace('\u0040valuenick\u0040', nick) + if flags: + tmp_prod = tmp_prod.replace('\u0040type\u0040', 'flags') + else: + tmp_prod = tmp_prod.replace('\u0040type\u0040', 'enum') + if flags: + tmp_prod = tmp_prod.replace('\u0040Type\u0040', 'Flags') + else: + tmp_prod = tmp_prod.replace('\u0040Type\u0040', 'Enum') + if flags: + tmp_prod = tmp_prod.replace('\u0040TYPE\u0040', 'FLAGS') + else: + tmp_prod = tmp_prod.replace('\u0040TYPE\u0040', 'ENUM') + tmp_prod = tmp_prod.rstrip() + + write_output(tmp_prod) + + if len(vtail) > 0: + prod = vtail + prod = prod.replace('\u0040enum_name\u0040', enumsym) + prod = prod.replace('\u0040EnumName\u0040', enumname) + prod = prod.replace('\u0040ENUMSHORT\u0040', enumshort) + prod = prod.replace('\u0040ENUMNAME\u0040', enumlong) + prod = prod.replace('\u0040ENUMPREFIX\u0040', enumname_prefix) + prod = prod.replace('\u0040enumsince\u0040', enumsince) + if flags: + prod = prod.replace('\u0040type\u0040', 'flags') + else: + prod = prod.replace('\u0040type\u0040', 'enum') + if flags: + prod = prod.replace('\u0040Type\u0040', 'Flags') + else: + prod = prod.replace('\u0040Type\u0040', 'Enum') + if flags: + prod = prod.replace('\u0040TYPE\u0040', 'FLAGS') + else: + prod = prod.replace('\u0040TYPE\u0040', 'ENUM') + prod = replace_specials(prod) + write_output(prod) + +for fname in sorted(options.args): + process_file(fname) + +if len(ftail) > 0: + prod = ftail + warn_if_filename_basename_used('file-tail', prod) + prod = replace_specials(prod) + write_output(prod) + +# put auto-generation comment +comment = comment_tmpl +comment = comment.replace('\u0040comment\u0040', 'Generated data ends here') +write_output("\n" + comment + "\n") + +if tmpfile is not None: + tmpfilename = tmpfile.name + tmpfile.close() + + try: + os.unlink(options.output) + except OSError as error: + if error.errno != errno.ENOENT: + raise error + + os.rename(tmpfilename, options.output) diff --git a/gobject/glib-types.h b/gobject/glib-types.h new file mode 100644 index 0000000..f0d3323 --- /dev/null +++ b/gobject/glib-types.h @@ -0,0 +1,395 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000-2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __GLIB_TYPES_H__ +#define __GLIB_TYPES_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) && !defined(GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* A hack necesssary to preprocess this file with g-ir-scanner */ +#ifdef __GI_SCANNER__ +typedef gsize GType; +#endif + +/* --- GLib boxed types --- */ +/** + * G_TYPE_DATE: + * + * The #GType for #GDate. + */ +#define G_TYPE_DATE (g_date_get_type ()) + +/** + * G_TYPE_STRV: + * + * The #GType for a boxed type holding a %NULL-terminated array of strings. + * + * The code fragments in the following example show the use of a property of + * type %G_TYPE_STRV with g_object_class_install_property(), g_object_set() + * and g_object_get(). + * + * |[ + * g_object_class_install_property (object_class, + * PROP_AUTHORS, + * g_param_spec_boxed ("authors", + * _("Authors"), + * _("List of authors"), + * G_TYPE_STRV, + * G_PARAM_READWRITE)); + * + * gchar *authors[] = { "Owen", "Tim", NULL }; + * g_object_set (obj, "authors", authors, NULL); + * + * gchar *writers[]; + * g_object_get (obj, "authors", &writers, NULL); + * /* do something with writers */ + * g_strfreev (writers); + * ]| + * + * Since: 2.4 + */ +#define G_TYPE_STRV (g_strv_get_type ()) + +/** + * G_TYPE_GSTRING: + * + * The #GType for #GString. + */ +#define G_TYPE_GSTRING (g_gstring_get_type ()) + +/** + * G_TYPE_HASH_TABLE: + * + * The #GType for a boxed type holding a #GHashTable reference. + * + * Since: 2.10 + */ +#define G_TYPE_HASH_TABLE (g_hash_table_get_type ()) + +/** + * G_TYPE_REGEX: + * + * The #GType for a boxed type holding a #GRegex reference. + * + * Since: 2.14 + */ +#define G_TYPE_REGEX (g_regex_get_type ()) + +/** + * G_TYPE_MATCH_INFO: + * + * The #GType for a boxed type holding a #GMatchInfo reference. + * + * Since: 2.30 + */ +#define G_TYPE_MATCH_INFO (g_match_info_get_type ()) + +/** + * G_TYPE_ARRAY: + * + * The #GType for a boxed type holding a #GArray reference. + * + * Since: 2.22 + */ +#define G_TYPE_ARRAY (g_array_get_type ()) + +/** + * G_TYPE_BYTE_ARRAY: + * + * The #GType for a boxed type holding a #GByteArray reference. + * + * Since: 2.22 + */ +#define G_TYPE_BYTE_ARRAY (g_byte_array_get_type ()) + +/** + * G_TYPE_PTR_ARRAY: + * + * The #GType for a boxed type holding a #GPtrArray reference. + * + * Since: 2.22 + */ +#define G_TYPE_PTR_ARRAY (g_ptr_array_get_type ()) + +/** + * G_TYPE_BYTES: + * + * The #GType for #GBytes. + * + * Since: 2.32 + */ +#define G_TYPE_BYTES (g_bytes_get_type ()) + +/** + * G_TYPE_VARIANT_TYPE: + * + * The #GType for a boxed type holding a #GVariantType. + * + * Since: 2.24 + */ +#define G_TYPE_VARIANT_TYPE (g_variant_type_get_gtype ()) + +/** + * G_TYPE_ERROR: + * + * The #GType for a boxed type holding a #GError. + * + * Since: 2.26 + */ +#define G_TYPE_ERROR (g_error_get_type ()) + +/** + * G_TYPE_DATE_TIME: + * + * The #GType for a boxed type holding a #GDateTime. + * + * Since: 2.26 + */ +#define G_TYPE_DATE_TIME (g_date_time_get_type ()) + +/** + * G_TYPE_TIME_ZONE: + * + * The #GType for a boxed type holding a #GTimeZone. + * + * Since: 2.34 + */ +#define G_TYPE_TIME_ZONE (g_time_zone_get_type ()) + +/** + * G_TYPE_IO_CHANNEL: + * + * The #GType for #GIOChannel. + */ +#define G_TYPE_IO_CHANNEL (g_io_channel_get_type ()) + +/** + * G_TYPE_IO_CONDITION: + * + * The #GType for #GIOCondition. + */ +#define G_TYPE_IO_CONDITION (g_io_condition_get_type ()) + +/** + * G_TYPE_VARIANT_BUILDER: + * + * The #GType for a boxed type holding a #GVariantBuilder. + * + * Since: 2.30 + */ +#define G_TYPE_VARIANT_BUILDER (g_variant_builder_get_type ()) + +/** + * G_TYPE_VARIANT_DICT: + * + * The #GType for a boxed type holding a #GVariantDict. + * + * Since: 2.40 + */ +#define G_TYPE_VARIANT_DICT (g_variant_dict_get_type ()) + +/** + * G_TYPE_MAIN_LOOP: + * + * The #GType for a boxed type holding a #GMainLoop. + * + * Since: 2.30 + */ +#define G_TYPE_MAIN_LOOP (g_main_loop_get_type ()) + +/** + * G_TYPE_MAIN_CONTEXT: + * + * The #GType for a boxed type holding a #GMainContext. + * + * Since: 2.30 + */ +#define G_TYPE_MAIN_CONTEXT (g_main_context_get_type ()) + +/** + * G_TYPE_SOURCE: + * + * The #GType for a boxed type holding a #GSource. + * + * Since: 2.30 + */ +#define G_TYPE_SOURCE (g_source_get_type ()) + +/** + * G_TYPE_POLLFD: + * + * The #GType for a boxed type holding a #GPollFD. + * + * Since: 2.36 + */ +#define G_TYPE_POLLFD (g_pollfd_get_type ()) + +/** + * G_TYPE_MARKUP_PARSE_CONTEXT: + * + * The #GType for a boxed type holding a #GMarkupParseContext. + * + * Since: 2.36 + */ +#define G_TYPE_MARKUP_PARSE_CONTEXT (g_markup_parse_context_get_type ()) + +/** + * G_TYPE_KEY_FILE: + * + * The #GType for a boxed type holding a #GKeyFile. + * + * Since: 2.32 + */ +#define G_TYPE_KEY_FILE (g_key_file_get_type ()) + +/** + * G_TYPE_MAPPED_FILE: + * + * The #GType for a boxed type holding a #GMappedFile. + * + * Since: 2.40 + */ +#define G_TYPE_MAPPED_FILE (g_mapped_file_get_type ()) + +/** + * G_TYPE_THREAD: + * + * The #GType for a boxed type holding a #GThread. + * + * Since: 2.36 + */ +#define G_TYPE_THREAD (g_thread_get_type ()) + +/** + * G_TYPE_CHECKSUM: + * + * The #GType for a boxed type holding a #GChecksum. + * + * Since: 2.36 + */ +#define G_TYPE_CHECKSUM (g_checksum_get_type ()) + +/** + * G_TYPE_OPTION_GROUP: + * + * The #GType for a boxed type holding a #GOptionGroup. + * + * Since: 2.44 + */ +#define G_TYPE_OPTION_GROUP (g_option_group_get_type ()) + +/** + * G_TYPE_URI: + * + * The #GType for a boxed type holding a #GUri. + * + * Since: 2.66 + */ +#define G_TYPE_URI (g_uri_get_type ()) + +/** + * G_TYPE_TREE: + * + * The #GType for #GTree. + * + * Since: 2.68 + */ +#define G_TYPE_TREE (g_tree_get_type ()) + +/** + * G_TYPE_PATTERN_SPEC: + * + * The #GType for #GPatternSpec. + * + * Since: 2.70 + */ +#define G_TYPE_PATTERN_SPEC (g_pattern_spec_get_type ()) + +GLIB_AVAILABLE_IN_ALL +GType g_date_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_strv_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_gstring_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_hash_table_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_array_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_byte_array_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_ptr_array_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_bytes_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_variant_type_get_gtype (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_regex_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_30 +GType g_match_info_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_error_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_date_time_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_time_zone_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_io_channel_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_io_condition_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_variant_builder_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_40 +GType g_variant_dict_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +GType g_key_file_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_30 +GType g_main_loop_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_30 +GType g_main_context_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_30 +GType g_source_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_36 +GType g_pollfd_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_36 +GType g_thread_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_36 +GType g_checksum_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_36 +GType g_markup_parse_context_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_40 +GType g_mapped_file_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_44 +GType g_option_group_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_66 +GType g_uri_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_68 +GType g_tree_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_70 +GType g_pattern_spec_get_type (void) G_GNUC_CONST; + +GLIB_DEPRECATED_FOR('G_TYPE_VARIANT') +GType g_variant_get_gtype (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GLIB_TYPES_H__ */ diff --git a/gobject/gmarshal.c b/gobject/gmarshal.c new file mode 100644 index 0000000..0c729b4 --- /dev/null +++ b/gobject/gmarshal.c @@ -0,0 +1,2521 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gobject.h" +#include "genums.h" +#include "gboxed.h" +#include "gvaluetypes.h" + + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/** + * g_cclosure_marshal_VOID__VOID: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with no arguments. + */ +/* VOID:VOID */ +void +g_cclosure_marshal_VOID__VOID (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__VOID) (gpointer data1, + gpointer data2); + GMarshalFunc_VOID__VOID callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 1); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__VOID) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + data2); +} + +/** + * g_cclosure_marshal_VOID__VOIDv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__VOID(). + */ +void +g_cclosure_marshal_VOID__VOIDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__VOID) (gpointer instance, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__VOID callback; + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__VOID) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + data2); +} + +/** + * g_cclosure_marshal_VOID__BOOLEAN: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * boolean argument. + */ +/* VOID:BOOLEAN */ +void +g_cclosure_marshal_VOID__BOOLEAN (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__BOOLEAN) (gpointer data1, + gboolean arg_1, + gpointer data2); + GMarshalFunc_VOID__BOOLEAN callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__BOOLEAN) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_boolean (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__BOOLEANv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__BOOLEAN(). + */ +void +g_cclosure_marshal_VOID__BOOLEANv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__BOOLEAN) (gpointer instance, + gboolean arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__BOOLEAN callback; + gboolean arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gboolean) va_arg (args_copy, gboolean); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__BOOLEAN) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__CHAR: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * character argument. + */ +/* VOID:CHAR */ +void +g_cclosure_marshal_VOID__CHAR (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__CHAR) (gpointer data1, + gchar arg_1, + gpointer data2); + GMarshalFunc_VOID__CHAR callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__CHAR) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_char (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__CHARv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__CHAR(). + */ +void +g_cclosure_marshal_VOID__CHARv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__CHAR) (gpointer instance, + gchar arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__CHAR callback; + gchar arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gchar) va_arg (args_copy, gint); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__CHAR) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__UCHAR: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * unsigned character argument. + */ +/* VOID:UCHAR */ +void +g_cclosure_marshal_VOID__UCHAR (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__UCHAR) (gpointer data1, + guchar arg_1, + gpointer data2); + GMarshalFunc_VOID__UCHAR callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UCHAR) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_uchar (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__UCHARv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__UCHAR(). + */ +void +g_cclosure_marshal_VOID__UCHARv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__UCHAR) (gpointer instance, + guchar arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__UCHAR callback; + guchar arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (guchar) va_arg (args_copy, guint); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UCHAR) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__INT: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * integer argument. + */ +/* VOID:INT */ +void +g_cclosure_marshal_VOID__INT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INT) (gpointer data1, + gint arg_1, + gpointer data2); + GMarshalFunc_VOID__INT callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_int (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__INTv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__INT(). + */ +void +g_cclosure_marshal_VOID__INTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__INT) (gpointer instance, + gint arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__INT callback; + gint arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gint) va_arg (args_copy, gint); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__UINT: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with with a single + * unsigned integer argument. + */ +/* VOID:UINT */ +void +g_cclosure_marshal_VOID__UINT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__UINT) (gpointer data1, + guint arg_1, + gpointer data2); + GMarshalFunc_VOID__UINT callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_uint (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__UINTv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__UINT(). + */ +void +g_cclosure_marshal_VOID__UINTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__UINT) (gpointer instance, + guint arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__UINT callback; + guint arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (guint) va_arg (args_copy, guint); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__LONG: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with with a single + * long integer argument. + */ +/* VOID:LONG */ +void +g_cclosure_marshal_VOID__LONG (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__LONG) (gpointer data1, + glong arg_1, + gpointer data2); + GMarshalFunc_VOID__LONG callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__LONG) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_long (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__LONGv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__LONG(). + */ +void +g_cclosure_marshal_VOID__LONGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__LONG) (gpointer instance, + glong arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__LONG callback; + glong arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (glong) va_arg (args_copy, glong); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__LONG) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__ULONG: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * unsigned long integer argument. + */ +/* VOID:ULONG */ +void +g_cclosure_marshal_VOID__ULONG (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__ULONG) (gpointer data1, + gulong arg_1, + gpointer data2); + GMarshalFunc_VOID__ULONG callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__ULONG) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_ulong (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__ULONGv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__ULONG(). + */ +void +g_cclosure_marshal_VOID__ULONGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__ULONG) (gpointer instance, + gulong arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__ULONG callback; + gulong arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gulong) va_arg (args_copy, gulong); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__ULONG) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__ENUM: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * argument with an enumerated type. + */ +/* VOID:ENUM */ +void +g_cclosure_marshal_VOID__ENUM (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__ENUM) (gpointer data1, + gint arg_1, + gpointer data2); + GMarshalFunc_VOID__ENUM callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__ENUM) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_enum (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__ENUMv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__ENUM(). + */ +void +g_cclosure_marshal_VOID__ENUMv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__ENUM) (gpointer instance, + gint arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__ENUM callback; + gint arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gint) va_arg (args_copy, gint); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__ENUM) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__FLAGS: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * argument with a flags types. + */ +/* VOID:FLAGS */ +void +g_cclosure_marshal_VOID__FLAGS (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__FLAGS) (gpointer data1, + guint arg_1, + gpointer data2); + GMarshalFunc_VOID__FLAGS callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__FLAGS) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_flags (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__FLAGSv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__FLAGS(). + */ +void +g_cclosure_marshal_VOID__FLAGSv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__FLAGS) (gpointer instance, + guint arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__FLAGS callback; + guint arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (guint) va_arg (args_copy, guint); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__FLAGS) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__FLOAT: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with one + * single-precision floating point argument. + */ +/* VOID:FLOAT */ +void +g_cclosure_marshal_VOID__FLOAT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__FLOAT) (gpointer data1, + gfloat arg_1, + gpointer data2); + GMarshalFunc_VOID__FLOAT callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__FLOAT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_float (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__FLOATv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__FLOAT(). + */ +void +g_cclosure_marshal_VOID__FLOATv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__FLOAT) (gpointer instance, + gfloat arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__FLOAT callback; + gfloat arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gfloat) va_arg (args_copy, gdouble); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__FLOAT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__DOUBLE: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with one + * double-precision floating point argument. + */ +/* VOID:DOUBLE */ +void +g_cclosure_marshal_VOID__DOUBLE (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__DOUBLE) (gpointer data1, + gdouble arg_1, + gpointer data2); + GMarshalFunc_VOID__DOUBLE callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__DOUBLE) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_double (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__DOUBLEv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__DOUBLE(). + */ +void +g_cclosure_marshal_VOID__DOUBLEv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__DOUBLE) (gpointer instance, + gdouble arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__DOUBLE callback; + gdouble arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gdouble) va_arg (args_copy, gdouble); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__DOUBLE) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__STRING: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single string + * argument. + */ +/* VOID:STRING */ +void +g_cclosure_marshal_VOID__STRING (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING) (gpointer data1, + gpointer arg_1, + gpointer data2); + GMarshalFunc_VOID__STRING callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__STRINGv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__STRING(). + */ +void +g_cclosure_marshal_VOID__STRINGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__STRING) (gpointer instance, + gpointer arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); +} + +/** + * g_cclosure_marshal_VOID__PARAM: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * argument of type #GParamSpec. + */ +/* VOID:PARAM */ +void +g_cclosure_marshal_VOID__PARAM (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__PARAM) (gpointer data1, + gpointer arg_1, + gpointer data2); + GMarshalFunc_VOID__PARAM callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__PARAM) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_param (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__PARAMv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__PARAM(). + */ +void +g_cclosure_marshal_VOID__PARAMv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__PARAM) (gpointer instance, + gpointer arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__PARAM callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_param_spec_ref (arg0); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__PARAM) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_param_spec_unref (arg0); +} + +/** + * g_cclosure_marshal_VOID__BOXED: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * argument which is any boxed pointer type. + */ +/* VOID:BOXED */ +void +g_cclosure_marshal_VOID__BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__BOXED) (gpointer data1, + gpointer arg_1, + gpointer data2); + GMarshalFunc_VOID__BOXED callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_boxed (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__BOXEDv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__BOXED(). + */ +void +g_cclosure_marshal_VOID__BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__BOXED) (gpointer instance, + gpointer arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__BOXED callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_boxed_copy (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg0); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__BOXED) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_boxed_free (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg0); +} + +/** + * g_cclosure_marshal_VOID__POINTER: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single raw + * pointer argument type. + * + * If it is possible, it is better to use one of the more specific + * functions such as g_cclosure_marshal_VOID__OBJECT() or + * g_cclosure_marshal_VOID__OBJECT(). + */ +/* VOID:POINTER */ +void +g_cclosure_marshal_VOID__POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER) (gpointer data1, + gpointer arg_1, + gpointer data2); + GMarshalFunc_VOID__POINTER callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__POINTERv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__POINTER(). + */ +void +g_cclosure_marshal_VOID__POINTERv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__POINTER) (gpointer instance, + gpointer arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__POINTER callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); +} + +/** + * g_cclosure_marshal_VOID__OBJECT: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * #GObject argument. + */ +/* VOID:OBJECT */ +void +g_cclosure_marshal_VOID__OBJECT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT) (gpointer data1, + gpointer arg_1, + gpointer data2); + GMarshalFunc_VOID__OBJECT callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_object (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__OBJECTv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__OBJECT(). + */ +void +g_cclosure_marshal_VOID__OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__OBJECT) (gpointer instance, + gpointer arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__OBJECT callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__OBJECT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); + if (arg0 != NULL) + g_object_unref (arg0); +} + +/** + * g_cclosure_marshal_VOID__VARIANT: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with a single + * #GVariant argument. + */ +/* VOID:VARIANT */ +void +g_cclosure_marshal_VOID__VARIANT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__VARIANT) (gpointer data1, + gpointer arg_1, + gpointer data2); + GMarshalFunc_VOID__VARIANT callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_variant (param_values + 1), + data2); +} + +/** + * g_cclosure_marshal_VOID__VARIANTv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__VARIANT(). + */ +void +g_cclosure_marshal_VOID__VARIANTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__VARIANT) (gpointer instance, + gpointer arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__VARIANT callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_variant_ref_sink (arg0); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_variant_unref (arg0); +} + +/** + * g_cclosure_marshal_VOID__UINT_POINTER: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with an unsigned int + * and a pointer as arguments. + */ +/* VOID:UINT,POINTER */ +void +g_cclosure_marshal_VOID__UINT_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__UINT_POINTER) (gpointer data1, + guint arg_1, + gpointer arg_2, + gpointer data2); + GMarshalFunc_VOID__UINT_POINTER callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UINT_POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_uint (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); +} + +/** + * g_cclosure_marshal_VOID__UINT_POINTERv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_VOID__UINT_POINTER(). + */ +void +g_cclosure_marshal_VOID__UINT_POINTERv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef void (*GMarshalFunc_VOID__UINT_POINTER) (gpointer instance, + guint arg_0, + gpointer arg_1, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_VOID__UINT_POINTER callback; + guint arg0; + gpointer arg1; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (guint) va_arg (args_copy, guint); + arg1 = (gpointer) va_arg (args_copy, gpointer); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__UINT_POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + arg1, + data2); +} + +/** + * g_cclosure_marshal_BOOLEAN__FLAGS: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with handlers that + * take a flags type as an argument and return a boolean. If you have + * such a signal, you will probably also need to use an accumulator, + * such as g_signal_accumulator_true_handled(). + */ +/* BOOL:FLAGS */ +void +g_cclosure_marshal_BOOLEAN__FLAGS (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__FLAGS) (gpointer data1, + guint arg_1, + gpointer data2); + GMarshalFunc_BOOLEAN__FLAGS callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__FLAGS) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_flags (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/** + * g_cclosure_marshal_BOOLEAN__FLAGSv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_BOOLEAN__FLAGS(). + */ +void +g_cclosure_marshal_BOOLEAN__FLAGSv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__FLAGS) (gpointer instance, + guint arg_0, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__FLAGS callback; + guint arg0; + va_list args_copy; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + + G_VA_COPY (args_copy, args); + arg0 = (guint) va_arg (args_copy, guint); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__FLAGS) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + data2); + + g_value_set_boolean (return_value, v_return); +} + +/** + * g_cclosure_marshal_STRING__OBJECT_POINTER: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with handlers that + * take a #GObject and a pointer and produce a string. It is highly + * unlikely that your signal handler fits this description. + */ +/* STRING:OBJECT,POINTER */ +void +g_cclosure_marshal_STRING__OBJECT_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gchar* (*GMarshalFunc_STRING__OBJECT_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + GMarshalFunc_STRING__OBJECT_POINTER callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + gchar* v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_STRING__OBJECT_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); + + g_value_take_string (return_value, v_return); +} + +/** + * g_cclosure_marshal_STRING__OBJECT_POINTERv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_STRING__OBJECT_POINTER(). + */ +void +g_cclosure_marshal_STRING__OBJECT_POINTERv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gchar* (*GMarshalFunc_STRING__OBJECT_POINTER) (gpointer instance, + gpointer arg_0, + gpointer arg_1, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_STRING__OBJECT_POINTER callback; + gpointer arg0; + gpointer arg1; + va_list args_copy; + gchar* v_return; + + g_return_if_fail (return_value != NULL); + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if (arg0 != NULL) + arg0 = g_object_ref (arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_STRING__OBJECT_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + arg1, + data2); + if (arg0 != NULL) + g_object_unref (arg0); + + g_value_take_string (return_value, v_return); +} + +/** + * g_cclosure_marshal_BOOLEAN__BOXED_BOXED: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * A #GClosureMarshal function for use with signals with handlers that + * take two boxed pointers as arguments and return a boolean. If you + * have such a signal, you will probably also need to use an + * accumulator, such as g_signal_accumulator_true_handled(). + */ +/* BOOL:BOXED,BOXED */ +void +g_cclosure_marshal_BOOLEAN__BOXED_BOXED (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_BOXED) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + GMarshalFunc_BOOLEAN__BOXED_BOXED callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__BOXED_BOXED) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_boxed (param_values + 1), + g_marshal_value_peek_boxed (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/** + * g_cclosure_marshal_BOOLEAN__BOXED_BOXEDv: + * @closure: the #GClosure to which the marshaller belongs + * @return_value: (nullable): a #GValue to store the return + * value. May be %NULL if the callback of @closure doesn't return a + * value. + * @instance: (type GObject.TypeInstance): the instance on which the closure is invoked. + * @args: va_list of arguments to be passed to the closure. + * @marshal_data: (nullable): additional data specified when + * registering the marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * @n_params: the length of the @param_types array + * @param_types: (array length=n_params): the #GType of each argument from + * @args. + * + * The #GVaClosureMarshal equivalent to g_cclosure_marshal_BOOLEAN__BOXED_BOXED(). + */ +void +g_cclosure_marshal_BOOLEAN__BOXED_BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_BOXED) (gpointer instance, + gpointer arg_0, + gpointer arg_1, + gpointer data); + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + GMarshalFunc_BOOLEAN__BOXED_BOXED callback; + gpointer arg0; + gpointer arg1; + va_list args_copy; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_boxed_copy (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg0); + arg1 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + arg1 = g_boxed_copy (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); + va_end (args_copy); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = instance; + } + else + { + data1 = instance; + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__BOXED_BOXED) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + arg0, + arg1, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_boxed_free (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg0); + if ((param_types[1] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg1 != NULL) + g_boxed_free (param_types[1] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg1); + + g_value_set_boolean (return_value, v_return); +} diff --git a/gobject/gmarshal.h b/gobject/gmarshal.h new file mode 100644 index 0000000..fdd6c04 --- /dev/null +++ b/gobject/gmarshal.h @@ -0,0 +1,434 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __G_MARSHAL_H__ +#define __G_MARSHAL_H__ + +G_BEGIN_DECLS + +/* VOID:VOID */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__VOIDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:BOOLEAN */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__BOOLEAN (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__BOOLEANv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:CHAR */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__CHAR (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__CHARv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:UCHAR */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__UCHAR (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__UCHARv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:INT */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__INTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:UINT */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__UINTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:LONG */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__LONG (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__LONGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:ULONG */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__ULONG (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__ULONGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:ENUM */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__ENUM (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__ENUMv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:FLAGS */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__FLAGS (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__FLAGSv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:FLOAT */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__FLOAT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__FLOATv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:DOUBLE */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__DOUBLE (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__DOUBLEv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:STRING */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__STRINGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:PARAM */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__PARAM (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__PARAMv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:BOXED */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:POINTER */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__POINTERv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:OBJECT */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__OBJECT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__OBJECTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:VARIANT */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__VARIANT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__VARIANTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* VOID:UINT,POINTER */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__UINT_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_VOID__UINT_POINTERv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* BOOL:FLAGS */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_BOOLEAN__FLAGS (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_BOOLEAN__FLAGSv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/** + * g_cclosure_marshal_BOOL__FLAGS: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * An old alias for g_cclosure_marshal_BOOLEAN__FLAGS(). + */ +#define g_cclosure_marshal_BOOL__FLAGS g_cclosure_marshal_BOOLEAN__FLAGS + +/* STRING:OBJECT,POINTER */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_STRING__OBJECT_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_STRING__OBJECT_POINTERv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/* BOOL:BOXED,BOXED */ +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_BOOLEAN__BOXED_BOXED (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +GLIB_AVAILABLE_IN_ALL +void g_cclosure_marshal_BOOLEAN__BOXED_BOXEDv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + +/** + * g_cclosure_marshal_BOOL__BOXED_BOXED: + * @closure: A #GClosure. + * @return_value: A #GValue to store the return value. May be %NULL + * if the callback of closure doesn't return a value. + * @n_param_values: The length of the @param_values array. + * @param_values: An array of #GValues holding the arguments + * on which to invoke the callback of closure. + * @invocation_hint: The invocation hint given as the last argument to + * g_closure_invoke(). + * @marshal_data: Additional data specified when registering the + * marshaller, see g_closure_set_marshal() and + * g_closure_set_meta_marshal() + * + * An old alias for g_cclosure_marshal_BOOLEAN__BOXED_BOXED(). + */ +#define g_cclosure_marshal_BOOL__BOXED_BOXED g_cclosure_marshal_BOOLEAN__BOXED_BOXED + +G_END_DECLS + +#endif /* __G_MARSHAL_H__ */ diff --git a/gobject/gobject-autocleanups.h b/gobject/gobject-autocleanups.h new file mode 100644 index 0000000..1613857 --- /dev/null +++ b/gobject/gobject-autocleanups.h @@ -0,0 +1,31 @@ +/* + * Copyright © 2015 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GClosure, g_closure_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GEnumClass, g_type_class_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GFlagsClass, g_type_class_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GObject, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GInitiallyUnowned, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GParamSpec, g_param_spec_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTypeClass, g_type_class_unref) +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GValue, g_value_unset) diff --git a/gobject/gobject-query.c b/gobject/gobject-query.c new file mode 100644 index 0000000..5c3c7dc --- /dev/null +++ b/gobject/gobject-query.c @@ -0,0 +1,223 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include + + +static gchar *indent_inc = NULL; +static guint spacing = 1; +static FILE *f_out = NULL; +static GType root = 0; +static gboolean recursion = TRUE; + +#if 0 +# define O_SPACE "\\as" +# define O_ESPACE " " +# define O_BRANCH "\\aE" +# define O_VLINE "\\al" +# define O_LLEAF "\\aL" +# define O_KEY_FILL "_" +#else +# define O_SPACE " " +# define O_ESPACE "" +# define O_BRANCH "+" +# define O_VLINE "|" +# define O_LLEAF "`" +# define O_KEY_FILL "_" +#endif + +static void +show_nodes (GType type, + GType sibling, + const gchar *indent) +{ + GType *children; + guint i; + + if (!type) + return; + + children = g_type_children (type, NULL); + + if (type != root) + for (i = 0; i < spacing; i++) + g_fprintf (f_out, "%s%s\n", indent, O_VLINE); + + g_fprintf (f_out, "%s%s%s%s", + indent, + sibling ? O_BRANCH : (type != root ? O_LLEAF : O_SPACE), + O_ESPACE, + g_type_name (type)); + + for (i = strlen (g_type_name (type)); i <= strlen (indent_inc); i++) + fputs (O_KEY_FILL, f_out); + + fputc ('\n', f_out); + + if (children && recursion) + { + gchar *new_indent; + GType *child; + + if (sibling) + new_indent = g_strconcat (indent, O_VLINE, indent_inc, NULL); + else + new_indent = g_strconcat (indent, O_SPACE, indent_inc, NULL); + + for (child = children; *child; child++) + show_nodes (child[0], child[1], new_indent); + + g_free (new_indent); + } + + g_free (children); +} + +static gint +help (gchar *arg) +{ + g_fprintf (stderr, "usage: gobject-query [-r ] [-{i|b} \"\"] [-s #] [-{h|x|y}]\n"); + g_fprintf (stderr, " -r specify root type\n"); + g_fprintf (stderr, " -n don't descend type tree\n"); + g_fprintf (stderr, " -h guess what ;)\n"); + g_fprintf (stderr, " -b specify indent string\n"); + g_fprintf (stderr, " -i specify incremental indent string\n"); + g_fprintf (stderr, " -s specify line spacing\n"); + g_fprintf (stderr, "qualifiers:\n"); + g_fprintf (stderr, " froots iterate over fundamental roots\n"); + g_fprintf (stderr, " tree print type tree\n"); + + return arg != NULL; +} + +int +main (gint argc, + gchar *argv[]) +{ + GLogLevelFlags fatal_mask; + gboolean gen_froots = 0; + gboolean gen_tree = 0; + gint i; + const gchar *iindent = ""; + + f_out = stdout; + + fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); + fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; + g_log_set_always_fatal (fatal_mask); + + root = G_TYPE_OBJECT; + + for (i = 1; i < argc; i++) + { + if (strcmp ("-s", argv[i]) == 0) + { + i++; + if (i < argc) + spacing = atoi (argv[i]); + } + else if (strcmp ("-i", argv[i]) == 0) + { + i++; + if (i < argc) + { + char *p; + guint n; + + p = argv[i]; + while (*p) + p++; + n = p - argv[i]; + indent_inc = g_new (gchar, n * strlen (O_SPACE) + 1); + *indent_inc = 0; + while (n) + { + n--; + strcpy (indent_inc, O_SPACE); + } + } + } + else if (strcmp ("-b", argv[i]) == 0) + { + i++; + if (i < argc) + iindent = argv[i]; + } + else if (strcmp ("-r", argv[i]) == 0) + { + i++; + if (i < argc) + root = g_type_from_name (argv[i]); + } + else if (strcmp ("-n", argv[i]) == 0) + { + recursion = FALSE; + } + else if (strcmp ("froots", argv[i]) == 0) + { + gen_froots = 1; + } + else if (strcmp ("tree", argv[i]) == 0) + { + gen_tree = 1; + } + else if (strcmp ("-h", argv[i]) == 0) + { + return help (NULL); + } + else if (strcmp ("--help", argv[i]) == 0) + { + return help (NULL); + } + else + return help (argv[i]); + } + + if (!gen_froots && !gen_tree) + return help ((argc > 0) ? argv[i-1] : NULL); + + if (!indent_inc) + { + indent_inc = g_new (gchar, strlen (O_SPACE) + 1); + *indent_inc = 0; + strcpy (indent_inc, O_SPACE); + } + + if (gen_tree) + show_nodes (root, 0, iindent); + if (gen_froots) + { + root = ~0; + for (i = 0; i <= G_TYPE_FUNDAMENTAL_MAX; i += G_TYPE_MAKE_FUNDAMENTAL (1)) + { + const gchar *name = g_type_name (i); + + if (name) + show_nodes (i, 0, iindent); + } + } + + return 0; +} diff --git a/gobject/gobject.c b/gobject/gobject.c new file mode 100644 index 0000000..c33ee35 --- /dev/null +++ b/gobject/gobject.c @@ -0,0 +1,4871 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * MT safe with regards to reference counting. + */ + +#include "config.h" + +#include +#include + +#include "../glib/glib-private.h" + +#include "gobject.h" +#include "gtype-private.h" +#include "gvaluecollector.h" +#include "gsignal.h" +#include "gparamspecs.h" +#include "gvaluetypes.h" +#include "gobject_trace.h" +#include "gconstructor.h" + +/** + * SECTION:objects + * @title: GObject + * @short_description: The base object type + * @see_also: #GParamSpecObject, g_param_spec_object() + * + * GObject is the fundamental type providing the common attributes and + * methods for all object types in GTK+, Pango and other libraries + * based on GObject. The GObject class provides methods for object + * construction and destruction, property access methods, and signal + * support. Signals are described in detail [here][gobject-Signals]. + * + * For a tutorial on implementing a new GObject class, see [How to define and + * implement a new GObject][howto-gobject]. For a list of naming conventions for + * GObjects and their methods, see the [GType conventions][gtype-conventions]. + * For the high-level concepts behind GObject, read [Instantiatable classed types: + * Objects][gtype-instantiatable-classed]. + * + * ## Floating references # {#floating-ref} + * + * **Note**: Floating references are a C convenience API and should not be + * used in modern GObject code. Language bindings in particular find the + * concept highly problematic, as floating references are not identifiable + * through annotations, and neither are deviations from the floating reference + * behavior, like types that inherit from #GInitiallyUnowned and still return + * a full reference from g_object_new(). + * + * GInitiallyUnowned is derived from GObject. The only difference between + * the two is that the initial reference of a GInitiallyUnowned is flagged + * as a "floating" reference. This means that it is not specifically + * claimed to be "owned" by any code portion. The main motivation for + * providing floating references is C convenience. In particular, it + * allows code to be written as: + * + * |[ + * container = create_container (); + * container_add_child (container, create_child()); + * ]| + * + * If container_add_child() calls g_object_ref_sink() on the passed-in child, + * no reference of the newly created child is leaked. Without floating + * references, container_add_child() can only g_object_ref() the new child, + * so to implement this code without reference leaks, it would have to be + * written as: + * + * |[ + * Child *child; + * container = create_container (); + * child = create_child (); + * container_add_child (container, child); + * g_object_unref (child); + * ]| + * + * The floating reference can be converted into an ordinary reference by + * calling g_object_ref_sink(). For already sunken objects (objects that + * don't have a floating reference anymore), g_object_ref_sink() is equivalent + * to g_object_ref() and returns a new reference. + * + * Since floating references are useful almost exclusively for C convenience, + * language bindings that provide automated reference and memory ownership + * maintenance (such as smart pointers or garbage collection) should not + * expose floating references in their API. The best practice for handling + * types that have initially floating references is to immediately sink those + * references after g_object_new() returns, by checking if the #GType + * inherits from #GInitiallyUnowned. For instance: + * + * |[ + * GObject *res = g_object_new_with_properties (gtype, + * n_props, + * prop_names, + * prop_values); + * + * // or: if (g_type_is_a (gtype, G_TYPE_INITIALLY_UNOWNED)) + * if (G_IS_INITIALLY_UNOWNED (res)) + * g_object_ref_sink (res); + * + * return res; + * ]| + * + * Some object implementations may need to save an objects floating state + * across certain code portions (an example is #GtkMenu), to achieve this, + * the following sequence can be used: + * + * |[ + * // save floating state + * gboolean was_floating = g_object_is_floating (object); + * g_object_ref_sink (object); + * // protected code portion + * + * ... + * + * // restore floating state + * if (was_floating) + * g_object_force_floating (object); + * else + * g_object_unref (object); // release previously acquired reference + * ]| + */ + + +/* --- macros --- */ +#define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id) +#define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id)) + +#define OBJECT_HAS_TOGGLE_REF_FLAG 0x1 +#define OBJECT_HAS_TOGGLE_REF(object) \ + ((g_datalist_get_flags (&(object)->qdata) & OBJECT_HAS_TOGGLE_REF_FLAG) != 0) +#define OBJECT_FLOATING_FLAG 0x2 + +#define CLASS_HAS_PROPS_FLAG 0x1 +#define CLASS_HAS_PROPS(class) \ + ((class)->flags & CLASS_HAS_PROPS_FLAG) +#define CLASS_HAS_CUSTOM_CONSTRUCTOR(class) \ + ((class)->constructor != g_object_constructor) +#define CLASS_HAS_CUSTOM_CONSTRUCTED(class) \ + ((class)->constructed != g_object_constructed) + +#define CLASS_HAS_DERIVED_CLASS_FLAG 0x2 +#define CLASS_HAS_DERIVED_CLASS(class) \ + ((class)->flags & CLASS_HAS_DERIVED_CLASS_FLAG) + +/* --- signals --- */ +enum { + NOTIFY, + LAST_SIGNAL +}; + + +/* --- properties --- */ +enum { + PROP_NONE +}; + +#define OPTIONAL_FLAG_IN_CONSTRUCTION 1<<0 +#define OPTIONAL_FLAG_HAS_SIGNAL_HANDLER 1<<1 /* Set if object ever had a signal handler */ + +#if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P == 8 +#define HAVE_OPTIONAL_FLAGS +#endif + +typedef struct +{ + GTypeInstance g_type_instance; + + /*< private >*/ + guint ref_count; /* (atomic) */ +#ifdef HAVE_OPTIONAL_FLAGS + guint optional_flags; /* (atomic) */ +#endif + GData *qdata; +} GObjectReal; + +G_STATIC_ASSERT(sizeof(GObject) == sizeof(GObjectReal)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, ref_count) == G_STRUCT_OFFSET(GObjectReal, ref_count)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, qdata) == G_STRUCT_OFFSET(GObjectReal, qdata)); + + +/* --- prototypes --- */ +static void g_object_base_class_init (GObjectClass *class); +static void g_object_base_class_finalize (GObjectClass *class); +static void g_object_do_class_init (GObjectClass *class); +static void g_object_init (GObject *object, + GObjectClass *class); +static GObject* g_object_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params); +static void g_object_constructed (GObject *object); +static void g_object_real_dispose (GObject *object); +static void g_object_finalize (GObject *object); +static void g_object_do_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void g_object_do_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void g_value_object_init (GValue *value); +static void g_value_object_free_value (GValue *value); +static void g_value_object_copy_value (const GValue *src_value, + GValue *dest_value); +static void g_value_object_transform_value (const GValue *src_value, + GValue *dest_value); +static gpointer g_value_object_peek_pointer (const GValue *value); +static gchar* g_value_object_collect_value (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags); +static gchar* g_value_object_lcopy_value (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags); +static void g_object_dispatch_properties_changed (GObject *object, + guint n_pspecs, + GParamSpec **pspecs); +static guint object_floating_flag_handler (GObject *object, + gint job); + +static void object_interface_check_properties (gpointer check_data, + gpointer g_iface); +static void weak_locations_free_unlocked (GSList **weak_locations); + +/* --- typedefs --- */ +typedef struct _GObjectNotifyQueue GObjectNotifyQueue; + +struct _GObjectNotifyQueue +{ + GSList *pspecs; + guint16 n_pspecs; + guint16 freeze_count; +}; + +/* --- variables --- */ +G_LOCK_DEFINE_STATIC (closure_array_mutex); +G_LOCK_DEFINE_STATIC (weak_refs_mutex); +G_LOCK_DEFINE_STATIC (toggle_refs_mutex); +static GQuark quark_closure_array = 0; +static GQuark quark_weak_refs = 0; +static GQuark quark_toggle_refs = 0; +static GQuark quark_notify_queue; +static GQuark quark_in_construction; +static GParamSpecPool *pspec_pool = NULL; +static gulong gobject_signals[LAST_SIGNAL] = { 0, }; +static guint (*floating_flag_handler) (GObject*, gint) = object_floating_flag_handler; +/* qdata pointing to GSList, protected by weak_locations_lock */ +static GQuark quark_weak_locations = 0; +static GRWLock weak_locations_lock; + +G_LOCK_DEFINE_STATIC(notify_lock); + +/* --- functions --- */ +static void +g_object_notify_queue_free (gpointer data) +{ + GObjectNotifyQueue *nqueue = data; + + g_slist_free (nqueue->pspecs); + g_slice_free (GObjectNotifyQueue, nqueue); +} + +static GObjectNotifyQueue* +g_object_notify_queue_freeze (GObject *object, + gboolean conditional) +{ + GObjectNotifyQueue *nqueue; + + G_LOCK(notify_lock); + nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue); + if (!nqueue) + { + if (conditional) + { + G_UNLOCK(notify_lock); + return NULL; + } + + nqueue = g_slice_new0 (GObjectNotifyQueue); + g_datalist_id_set_data_full (&object->qdata, quark_notify_queue, + nqueue, g_object_notify_queue_free); + } + + if (nqueue->freeze_count >= 65535) + g_critical("Free queue for %s (%p) is larger than 65535," + " called g_object_freeze_notify() too often." + " Forgot to call g_object_thaw_notify() or infinite loop", + G_OBJECT_TYPE_NAME (object), object); + else + nqueue->freeze_count++; + + G_UNLOCK(notify_lock); + + return nqueue; +} + +static void +g_object_notify_queue_thaw (GObject *object, + GObjectNotifyQueue *nqueue) +{ + GParamSpec *pspecs_mem[16], **pspecs, **free_me = NULL; + GSList *slist; + guint n_pspecs = 0; + + g_return_if_fail (g_atomic_int_get(&object->ref_count) > 0); + + G_LOCK(notify_lock); + + /* Just make sure we never get into some nasty race condition */ + if (G_UNLIKELY(nqueue->freeze_count == 0)) { + G_UNLOCK(notify_lock); + g_warning ("%s: property-changed notification for %s(%p) is not frozen", + G_STRFUNC, G_OBJECT_TYPE_NAME (object), object); + return; + } + + nqueue->freeze_count--; + if (nqueue->freeze_count) { + G_UNLOCK(notify_lock); + return; + } + + pspecs = nqueue->n_pspecs > 16 ? free_me = g_new (GParamSpec*, nqueue->n_pspecs) : pspecs_mem; + + for (slist = nqueue->pspecs; slist; slist = slist->next) + { + pspecs[n_pspecs++] = slist->data; + } + g_datalist_id_set_data (&object->qdata, quark_notify_queue, NULL); + + G_UNLOCK(notify_lock); + + if (n_pspecs) + G_OBJECT_GET_CLASS (object)->dispatch_properties_changed (object, n_pspecs, pspecs); + g_free (free_me); +} + +static void +g_object_notify_queue_add (GObject *object, + GObjectNotifyQueue *nqueue, + GParamSpec *pspec) +{ + G_LOCK(notify_lock); + + g_assert (nqueue->n_pspecs < 65535); + + if (g_slist_find (nqueue->pspecs, pspec) == NULL) + { + nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec); + nqueue->n_pspecs++; + } + + G_UNLOCK(notify_lock); +} + +#ifdef G_ENABLE_DEBUG +G_LOCK_DEFINE_STATIC (debug_objects); +static guint debug_objects_count = 0; +static GHashTable *debug_objects_ht = NULL; + +static void +debug_objects_foreach (gpointer key, + gpointer value, + gpointer user_data) +{ + GObject *object = value; + + g_message ("[%p] stale %s\tref_count=%u", + object, + G_OBJECT_TYPE_NAME (object), + object->ref_count); +} + +#ifdef G_HAS_CONSTRUCTORS +#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(debug_objects_atexit) +#endif +G_DEFINE_DESTRUCTOR(debug_objects_atexit) +#endif /* G_HAS_CONSTRUCTORS */ + +static void +debug_objects_atexit (void) +{ + GOBJECT_IF_DEBUG (OBJECTS, + { + G_LOCK (debug_objects); + g_message ("stale GObjects: %u", debug_objects_count); + g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL); + G_UNLOCK (debug_objects); + }); +} +#endif /* G_ENABLE_DEBUG */ + +void +_g_object_type_init (void) +{ + static gboolean initialized = FALSE; + static const GTypeFundamentalInfo finfo = { + G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE, + }; + GTypeInfo info = { + sizeof (GObjectClass), + (GBaseInitFunc) g_object_base_class_init, + (GBaseFinalizeFunc) g_object_base_class_finalize, + (GClassInitFunc) g_object_do_class_init, + NULL /* class_destroy */, + NULL /* class_data */, + sizeof (GObject), + 0 /* n_preallocs */, + (GInstanceInitFunc) g_object_init, + NULL, /* value_table */ + }; + static const GTypeValueTable value_table = { + g_value_object_init, /* value_init */ + g_value_object_free_value, /* value_free */ + g_value_object_copy_value, /* value_copy */ + g_value_object_peek_pointer, /* value_peek_pointer */ + "p", /* collect_format */ + g_value_object_collect_value, /* collect_value */ + "p", /* lcopy_format */ + g_value_object_lcopy_value, /* lcopy_value */ + }; + GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + g_return_if_fail (initialized == FALSE); + initialized = TRUE; + + /* G_TYPE_OBJECT + */ + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_OBJECT, g_intern_static_string ("GObject"), &info, &finfo, 0); + g_assert (type == G_TYPE_OBJECT); + g_value_register_transform_func (G_TYPE_OBJECT, G_TYPE_OBJECT, g_value_object_transform_value); + +#if G_ENABLE_DEBUG + /* We cannot use GOBJECT_IF_DEBUG here because of the G_HAS_CONSTRUCTORS + * conditional in between, as the C spec leaves conditionals inside macro + * expansions as undefined behavior. Only GCC and Clang are known to work + * but compilation breaks on MSVC. + * + * See: https://bugzilla.gnome.org/show_bug.cgi?id=769504 + */ + if (_g_type_debug_flags & G_TYPE_DEBUG_OBJECTS) \ + { + debug_objects_ht = g_hash_table_new (g_direct_hash, NULL); +# ifndef G_HAS_CONSTRUCTORS + g_atexit (debug_objects_atexit); +# endif /* G_HAS_CONSTRUCTORS */ + } +#endif /* G_ENABLE_DEBUG */ +} + +static void +g_object_base_class_init (GObjectClass *class) +{ + GObjectClass *pclass = g_type_class_peek_parent (class); + + /* Don't inherit HAS_DERIVED_CLASS flag from parent class */ + class->flags &= ~CLASS_HAS_DERIVED_CLASS_FLAG; + + if (pclass) + pclass->flags |= CLASS_HAS_DERIVED_CLASS_FLAG; + + /* reset instance specific fields and methods that don't get inherited */ + class->construct_properties = pclass ? g_slist_copy (pclass->construct_properties) : NULL; + class->get_property = NULL; + class->set_property = NULL; +} + +static void +g_object_base_class_finalize (GObjectClass *class) +{ + GList *list, *node; + + _g_signals_destroy (G_OBJECT_CLASS_TYPE (class)); + + g_slist_free (class->construct_properties); + class->construct_properties = NULL; + list = g_param_spec_pool_list_owned (pspec_pool, G_OBJECT_CLASS_TYPE (class)); + for (node = list; node; node = node->next) + { + GParamSpec *pspec = node->data; + + g_param_spec_pool_remove (pspec_pool, pspec); + PARAM_SPEC_SET_PARAM_ID (pspec, 0); + g_param_spec_unref (pspec); + } + g_list_free (list); +} + +static void +g_object_do_class_init (GObjectClass *class) +{ + /* read the comment about typedef struct CArray; on why not to change this quark */ + quark_closure_array = g_quark_from_static_string ("GObject-closure-array"); + + quark_weak_refs = g_quark_from_static_string ("GObject-weak-references"); + quark_weak_locations = g_quark_from_static_string ("GObject-weak-locations"); + quark_toggle_refs = g_quark_from_static_string ("GObject-toggle-references"); + quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue"); + quark_in_construction = g_quark_from_static_string ("GObject-in-construction"); + pspec_pool = g_param_spec_pool_new (TRUE); + + class->constructor = g_object_constructor; + class->constructed = g_object_constructed; + class->set_property = g_object_do_set_property; + class->get_property = g_object_do_get_property; + class->dispose = g_object_real_dispose; + class->finalize = g_object_finalize; + class->dispatch_properties_changed = g_object_dispatch_properties_changed; + class->notify = NULL; + + /** + * GObject::notify: + * @gobject: the object which received the signal. + * @pspec: the #GParamSpec of the property which changed. + * + * The notify signal is emitted on an object when one of its properties has + * its value set through g_object_set_property(), g_object_set(), et al. + * + * Note that getting this signal doesn’t itself guarantee that the value of + * the property has actually changed. When it is emitted is determined by the + * derived GObject class. If the implementor did not create the property with + * %G_PARAM_EXPLICIT_NOTIFY, then any call to g_object_set_property() results + * in ::notify being emitted, even if the new value is the same as the old. + * If they did pass %G_PARAM_EXPLICIT_NOTIFY, then this signal is emitted only + * when they explicitly call g_object_notify() or g_object_notify_by_pspec(), + * and common practice is to do that only when the value has actually changed. + * + * This signal is typically used to obtain change notification for a + * single property, by specifying the property name as a detail in the + * g_signal_connect() call, like this: + * + * |[ + * g_signal_connect (text_view->buffer, "notify::paste-target-list", + * G_CALLBACK (gtk_text_view_target_list_notify), + * text_view) + * ]| + * + * It is important to note that you must use + * [canonical parameter names][canonical-parameter-names] as + * detail strings for the notify signal. + */ + gobject_signals[NOTIFY] = + g_signal_new (g_intern_static_string ("notify"), + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GObjectClass, notify), + NULL, NULL, + NULL, + G_TYPE_NONE, + 1, G_TYPE_PARAM); + + /* Install a check function that we'll use to verify that classes that + * implement an interface implement all properties for that interface + */ + g_type_add_interface_check (NULL, object_interface_check_properties); +} + +/* Sinks @pspec if it’s a floating ref. */ +static inline gboolean +install_property_internal (GType g_type, + guint property_id, + GParamSpec *pspec) +{ + g_param_spec_ref_sink (pspec); + + if (g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type, FALSE)) + { + g_warning ("When installing property: type '%s' already has a property named '%s'", + g_type_name (g_type), + pspec->name); + g_param_spec_unref (pspec); + return FALSE; + } + + PARAM_SPEC_SET_PARAM_ID (pspec, property_id); + g_param_spec_pool_insert (pspec_pool, g_steal_pointer (&pspec), g_type); + return TRUE; +} + +static gboolean +validate_pspec_to_install (GParamSpec *pspec) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); + g_return_val_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0, FALSE); /* paranoid */ + + g_return_val_if_fail (pspec->flags & (G_PARAM_READABLE | G_PARAM_WRITABLE), FALSE); + + if (pspec->flags & G_PARAM_CONSTRUCT) + g_return_val_if_fail ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0, FALSE); + + if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) + g_return_val_if_fail (pspec->flags & G_PARAM_WRITABLE, FALSE); + + return TRUE; +} + +/* Sinks @pspec if it’s a floating ref. */ +static gboolean +validate_and_install_class_property (GObjectClass *class, + GType oclass_type, + GType parent_type, + guint property_id, + GParamSpec *pspec) +{ + if (!validate_pspec_to_install (pspec)) + { + g_param_spec_ref_sink (pspec); + g_param_spec_unref (pspec); + return FALSE; + } + + if (pspec->flags & G_PARAM_WRITABLE) + g_return_val_if_fail (class->set_property != NULL, FALSE); + if (pspec->flags & G_PARAM_READABLE) + g_return_val_if_fail (class->get_property != NULL, FALSE); + + class->flags |= CLASS_HAS_PROPS_FLAG; + if (install_property_internal (oclass_type, property_id, pspec)) + { + if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) + class->construct_properties = g_slist_append (class->construct_properties, pspec); + + /* for property overrides of construct properties, we have to get rid + * of the overridden inherited construct property + */ + pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, parent_type, TRUE); + if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) + class->construct_properties = g_slist_remove (class->construct_properties, pspec); + + return TRUE; + } + else + return FALSE; +} + +/** + * g_object_class_install_property: + * @oclass: a #GObjectClass + * @property_id: the id for the new property + * @pspec: the #GParamSpec for the new property + * + * Installs a new property. + * + * All properties should be installed during the class initializer. It + * is possible to install properties after that, but doing so is not + * recommend, and specifically, is not guaranteed to be thread-safe vs. + * use of properties on the same type on other threads. + * + * Note that it is possible to redefine a property in a derived class, + * by installing a property with the same name. This can be useful at times, + * e.g. to change the range of allowed values or the default value. + */ +void +g_object_class_install_property (GObjectClass *class, + guint property_id, + GParamSpec *pspec) +{ + GType oclass_type, parent_type; + + g_return_if_fail (G_IS_OBJECT_CLASS (class)); + g_return_if_fail (property_id > 0); + + oclass_type = G_OBJECT_CLASS_TYPE (class); + parent_type = g_type_parent (oclass_type); + + if (CLASS_HAS_DERIVED_CLASS (class)) + g_error ("Attempt to add property %s::%s to class after it was derived", G_OBJECT_CLASS_NAME (class), pspec->name); + + (void) validate_and_install_class_property (class, + oclass_type, + parent_type, + property_id, + pspec); +} + +/** + * g_object_class_install_properties: + * @oclass: a #GObjectClass + * @n_pspecs: the length of the #GParamSpecs array + * @pspecs: (array length=n_pspecs): the #GParamSpecs array + * defining the new properties + * + * Installs new properties from an array of #GParamSpecs. + * + * All properties should be installed during the class initializer. It + * is possible to install properties after that, but doing so is not + * recommend, and specifically, is not guaranteed to be thread-safe vs. + * use of properties on the same type on other threads. + * + * The property id of each property is the index of each #GParamSpec in + * the @pspecs array. + * + * The property id of 0 is treated specially by #GObject and it should not + * be used to store a #GParamSpec. + * + * This function should be used if you plan to use a static array of + * #GParamSpecs and g_object_notify_by_pspec(). For instance, this + * class initialization: + * + * |[ + * enum { + * PROP_0, PROP_FOO, PROP_BAR, N_PROPERTIES + * }; + * + * static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + * + * static void + * my_object_class_init (MyObjectClass *klass) + * { + * GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + * + * obj_properties[PROP_FOO] = + * g_param_spec_int ("foo", "Foo", "Foo", + * -1, G_MAXINT, + * 0, + * G_PARAM_READWRITE); + * + * obj_properties[PROP_BAR] = + * g_param_spec_string ("bar", "Bar", "Bar", + * NULL, + * G_PARAM_READWRITE); + * + * gobject_class->set_property = my_object_set_property; + * gobject_class->get_property = my_object_get_property; + * g_object_class_install_properties (gobject_class, + * N_PROPERTIES, + * obj_properties); + * } + * ]| + * + * allows calling g_object_notify_by_pspec() to notify of property changes: + * + * |[ + * void + * my_object_set_foo (MyObject *self, gint foo) + * { + * if (self->foo != foo) + * { + * self->foo = foo; + * g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_FOO]); + * } + * } + * ]| + * + * Since: 2.26 + */ +void +g_object_class_install_properties (GObjectClass *oclass, + guint n_pspecs, + GParamSpec **pspecs) +{ + GType oclass_type, parent_type; + guint i; + + g_return_if_fail (G_IS_OBJECT_CLASS (oclass)); + g_return_if_fail (n_pspecs > 1); + g_return_if_fail (pspecs[0] == NULL); + + if (CLASS_HAS_DERIVED_CLASS (oclass)) + g_error ("Attempt to add properties to %s after it was derived", + G_OBJECT_CLASS_NAME (oclass)); + + oclass_type = G_OBJECT_CLASS_TYPE (oclass); + parent_type = g_type_parent (oclass_type); + + /* we skip the first element of the array as it would have a 0 prop_id */ + for (i = 1; i < n_pspecs; i++) + { + GParamSpec *pspec = pspecs[i]; + + if (!validate_and_install_class_property (oclass, + oclass_type, + parent_type, + i, + pspec)) + { + break; + } + } +} + +/** + * g_object_interface_install_property: + * @g_iface: (type GObject.TypeInterface): any interface vtable for the + * interface, or the default + * vtable for the interface. + * @pspec: the #GParamSpec for the new property + * + * Add a property to an interface; this is only useful for interfaces + * that are added to GObject-derived types. Adding a property to an + * interface forces all objects classes with that interface to have a + * compatible property. The compatible property could be a newly + * created #GParamSpec, but normally + * g_object_class_override_property() will be used so that the object + * class only needs to provide an implementation and inherits the + * property description, default value, bounds, and so forth from the + * interface property. + * + * This function is meant to be called from the interface's default + * vtable initialization function (the @class_init member of + * #GTypeInfo.) It must not be called after after @class_init has + * been called for any object types implementing this interface. + * + * If @pspec is a floating reference, it will be consumed. + * + * Since: 2.4 + */ +void +g_object_interface_install_property (gpointer g_iface, + GParamSpec *pspec) +{ + GTypeInterface *iface_class = g_iface; + + g_return_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type)); + g_return_if_fail (!G_IS_PARAM_SPEC_OVERRIDE (pspec)); /* paranoid */ + + if (!validate_pspec_to_install (pspec)) + { + g_param_spec_ref_sink (pspec); + g_param_spec_unref (pspec); + return; + } + + (void) install_property_internal (iface_class->g_type, 0, pspec); +} + +/** + * g_object_class_find_property: + * @oclass: a #GObjectClass + * @property_name: the name of the property to look up + * + * Looks up the #GParamSpec for a property of a class. + * + * Returns: (transfer none): the #GParamSpec for the property, or + * %NULL if the class doesn't have a property of that name + */ +GParamSpec* +g_object_class_find_property (GObjectClass *class, + const gchar *property_name) +{ + GParamSpec *pspec; + GParamSpec *redirect; + + g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + + pspec = g_param_spec_pool_lookup (pspec_pool, + property_name, + G_OBJECT_CLASS_TYPE (class), + TRUE); + if (pspec) + { + redirect = g_param_spec_get_redirect_target (pspec); + if (redirect) + return redirect; + else + return pspec; + } + else + return NULL; +} + +/** + * g_object_interface_find_property: + * @g_iface: (type GObject.TypeInterface): any interface vtable for the + * interface, or the default vtable for the interface + * @property_name: name of a property to look up. + * + * Find the #GParamSpec with the given name for an + * interface. Generally, the interface vtable passed in as @g_iface + * will be the default vtable from g_type_default_interface_ref(), or, + * if you know the interface has already been loaded, + * g_type_default_interface_peek(). + * + * Since: 2.4 + * + * Returns: (transfer none): the #GParamSpec for the property of the + * interface with the name @property_name, or %NULL if no + * such property exists. + */ +GParamSpec* +g_object_interface_find_property (gpointer g_iface, + const gchar *property_name) +{ + GTypeInterface *iface_class = g_iface; + + g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + + return g_param_spec_pool_lookup (pspec_pool, + property_name, + iface_class->g_type, + FALSE); +} + +/** + * g_object_class_override_property: + * @oclass: a #GObjectClass + * @property_id: the new property ID + * @name: the name of a property registered in a parent class or + * in an interface of this class. + * + * Registers @property_id as referring to a property with the name + * @name in a parent class or in an interface implemented by @oclass. + * This allows this class to "override" a property implementation in + * a parent class or to provide the implementation of a property from + * an interface. + * + * Internally, overriding is implemented by creating a property of type + * #GParamSpecOverride; generally operations that query the properties of + * the object class, such as g_object_class_find_property() or + * g_object_class_list_properties() will return the overridden + * property. However, in one case, the @construct_properties argument of + * the @constructor virtual function, the #GParamSpecOverride is passed + * instead, so that the @param_id field of the #GParamSpec will be + * correct. For virtually all uses, this makes no difference. If you + * need to get the overridden property, you can call + * g_param_spec_get_redirect_target(). + * + * Since: 2.4 + */ +void +g_object_class_override_property (GObjectClass *oclass, + guint property_id, + const gchar *name) +{ + GParamSpec *overridden = NULL; + GParamSpec *new; + GType parent_type; + + g_return_if_fail (G_IS_OBJECT_CLASS (oclass)); + g_return_if_fail (property_id > 0); + g_return_if_fail (name != NULL); + + /* Find the overridden property; first check parent types + */ + parent_type = g_type_parent (G_OBJECT_CLASS_TYPE (oclass)); + if (parent_type != G_TYPE_NONE) + overridden = g_param_spec_pool_lookup (pspec_pool, + name, + parent_type, + TRUE); + if (!overridden) + { + GType *ifaces; + guint n_ifaces; + + /* Now check interfaces + */ + ifaces = g_type_interfaces (G_OBJECT_CLASS_TYPE (oclass), &n_ifaces); + while (n_ifaces-- && !overridden) + { + overridden = g_param_spec_pool_lookup (pspec_pool, + name, + ifaces[n_ifaces], + FALSE); + } + + g_free (ifaces); + } + + if (!overridden) + { + g_warning ("%s: Can't find property to override for '%s::%s'", + G_STRFUNC, G_OBJECT_CLASS_NAME (oclass), name); + return; + } + + new = g_param_spec_override (name, overridden); + g_object_class_install_property (oclass, property_id, new); +} + +/** + * g_object_class_list_properties: + * @oclass: a #GObjectClass + * @n_properties: (out): return location for the length of the returned array + * + * Get an array of #GParamSpec* for all properties of a class. + * + * Returns: (array length=n_properties) (transfer container): an array of + * #GParamSpec* which should be freed after use + */ +GParamSpec** /* free result */ +g_object_class_list_properties (GObjectClass *class, + guint *n_properties_p) +{ + GParamSpec **pspecs; + guint n; + + g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL); + + pspecs = g_param_spec_pool_list (pspec_pool, + G_OBJECT_CLASS_TYPE (class), + &n); + if (n_properties_p) + *n_properties_p = n; + + return pspecs; +} + +/** + * g_object_interface_list_properties: + * @g_iface: (type GObject.TypeInterface): any interface vtable for the + * interface, or the default vtable for the interface + * @n_properties_p: (out): location to store number of properties returned. + * + * Lists the properties of an interface.Generally, the interface + * vtable passed in as @g_iface will be the default vtable from + * g_type_default_interface_ref(), or, if you know the interface has + * already been loaded, g_type_default_interface_peek(). + * + * Since: 2.4 + * + * Returns: (array length=n_properties_p) (transfer container): a + * pointer to an array of pointers to #GParamSpec + * structures. The paramspecs are owned by GLib, but the + * array should be freed with g_free() when you are done with + * it. + */ +GParamSpec** +g_object_interface_list_properties (gpointer g_iface, + guint *n_properties_p) +{ + GTypeInterface *iface_class = g_iface; + GParamSpec **pspecs; + guint n; + + g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type), NULL); + + pspecs = g_param_spec_pool_list (pspec_pool, + iface_class->g_type, + &n); + if (n_properties_p) + *n_properties_p = n; + + return pspecs; +} + +static inline guint +object_get_optional_flags (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + GObjectReal *real = (GObjectReal *)object; + return (guint)g_atomic_int_get (&real->optional_flags); +#else + return 0; +#endif +} + +static inline void +object_set_optional_flags (GObject *object, + guint flags) +{ +#ifdef HAVE_OPTIONAL_FLAGS + GObjectReal *real = (GObjectReal *)object; + g_atomic_int_or (&real->optional_flags, flags); +#endif +} + +static inline void +object_unset_optional_flags (GObject *object, + guint flags) +{ +#ifdef HAVE_OPTIONAL_FLAGS + GObjectReal *real = (GObjectReal *)object; + g_atomic_int_and (&real->optional_flags, ~flags); +#endif +} + +gboolean +_g_object_has_signal_handler (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + return (object_get_optional_flags (object) & OPTIONAL_FLAG_HAS_SIGNAL_HANDLER) != 0; +#else + return TRUE; +#endif +} + +void +_g_object_set_has_signal_handler (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + object_set_optional_flags (object, OPTIONAL_FLAG_HAS_SIGNAL_HANDLER); +#endif +} + +static inline gboolean +object_in_construction (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + return (object_get_optional_flags (object) & OPTIONAL_FLAG_IN_CONSTRUCTION) != 0; +#else + return g_datalist_id_get_data (&object->qdata, quark_in_construction) != NULL; +#endif +} + +static inline void +set_object_in_construction (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + object_set_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION); +#else + g_datalist_id_set_data (&object->qdata, quark_in_construction, object); +#endif +} + +static inline void +unset_object_in_construction (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + object_unset_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION); +#else + g_datalist_id_set_data (&object->qdata, quark_in_construction, NULL); +#endif +} + +static void +g_object_init (GObject *object, + GObjectClass *class) +{ + object->ref_count = 1; + object->qdata = NULL; + + if (CLASS_HAS_PROPS (class)) + { + /* freeze object's notification queue, g_object_newv() preserves pairedness */ + g_object_notify_queue_freeze (object, FALSE); + } + + if (CLASS_HAS_CUSTOM_CONSTRUCTOR (class)) + { + /* mark object in-construction for notify_queue_thaw() and to allow construct-only properties */ + set_object_in_construction (object); + } + + GOBJECT_IF_DEBUG (OBJECTS, + { + G_LOCK (debug_objects); + debug_objects_count++; + g_hash_table_add (debug_objects_ht, object); + G_UNLOCK (debug_objects); + }); +} + +static void +g_object_do_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +g_object_do_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +g_object_real_dispose (GObject *object) +{ + g_signal_handlers_destroy (object); + g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL); + g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL); + g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL); +} + +#ifdef G_ENABLE_DEBUG +static gboolean +floating_check (GObject *object) +{ + static const char *g_enable_diagnostic = NULL; + + if (G_UNLIKELY (g_enable_diagnostic == NULL)) + { + g_enable_diagnostic = g_getenv ("G_ENABLE_DIAGNOSTIC"); + if (g_enable_diagnostic == NULL) + g_enable_diagnostic = "0"; + } + + if (g_enable_diagnostic[0] == '1') + return g_object_is_floating (object); + + return FALSE; +} +#endif + +static void +g_object_finalize (GObject *object) +{ + if (object_in_construction (object)) + { + g_critical ("object %s %p finalized while still in-construction", + G_OBJECT_TYPE_NAME (object), object); + } + +#ifdef G_ENABLE_DEBUG + if (floating_check (object)) + { + g_critical ("A floating object %s %p was finalized. This means that someone\n" + "called g_object_unref() on an object that had only a floating\n" + "reference; the initial floating reference is not owned by anyone\n" + "and must be removed with g_object_ref_sink().", + G_OBJECT_TYPE_NAME (object), object); + } +#endif + + g_datalist_clear (&object->qdata); + + GOBJECT_IF_DEBUG (OBJECTS, + { + G_LOCK (debug_objects); + g_assert (g_hash_table_contains (debug_objects_ht, object)); + g_hash_table_remove (debug_objects_ht, object); + debug_objects_count--; + G_UNLOCK (debug_objects); + }); +} + +static void +g_object_dispatch_properties_changed (GObject *object, + guint n_pspecs, + GParamSpec **pspecs) +{ + guint i; + + for (i = 0; i < n_pspecs; i++) + g_signal_emit (object, gobject_signals[NOTIFY], g_param_spec_get_name_quark (pspecs[i]), pspecs[i]); +} + +/** + * g_object_run_dispose: + * @object: a #GObject + * + * Releases all references to other objects. This can be used to break + * reference cycles. + * + * This function should only be called from object system implementations. + */ +void +g_object_run_dispose (GObject *object) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0); + + g_object_ref (object); + TRACE (GOBJECT_OBJECT_DISPOSE(object,G_TYPE_FROM_INSTANCE(object), 0)); + G_OBJECT_GET_CLASS (object)->dispose (object); + TRACE (GOBJECT_OBJECT_DISPOSE_END(object,G_TYPE_FROM_INSTANCE(object), 0)); + g_object_unref (object); +} + +/** + * g_object_freeze_notify: + * @object: a #GObject + * + * Increases the freeze count on @object. If the freeze count is + * non-zero, the emission of "notify" signals on @object is + * stopped. The signals are queued until the freeze count is decreased + * to zero. Duplicate notifications are squashed so that at most one + * #GObject::notify signal is emitted for each property modified while the + * object is frozen. + * + * This is necessary for accessors that modify multiple properties to prevent + * premature notification while the object is still being modified. + */ +void +g_object_freeze_notify (GObject *object) +{ + g_return_if_fail (G_IS_OBJECT (object)); + + if (g_atomic_int_get (&object->ref_count) == 0) + return; + + g_object_ref (object); + g_object_notify_queue_freeze (object, FALSE); + g_object_unref (object); +} + +static GParamSpec * +get_notify_pspec (GParamSpec *pspec) +{ + GParamSpec *redirected; + + /* we don't notify on non-READABLE parameters */ + if (~pspec->flags & G_PARAM_READABLE) + return NULL; + + /* if the paramspec is redirected, notify on the target */ + redirected = g_param_spec_get_redirect_target (pspec); + if (redirected != NULL) + return redirected; + + /* else, notify normally */ + return pspec; +} + +static inline void +g_object_notify_by_spec_internal (GObject *object, + GParamSpec *pspec) +{ + GParamSpec *notify_pspec; + + notify_pspec = get_notify_pspec (pspec); + + if (notify_pspec != NULL) + { + GObjectNotifyQueue *nqueue; + + /* conditional freeze: only increase freeze count if already frozen */ + nqueue = g_object_notify_queue_freeze (object, TRUE); + + if (nqueue != NULL) + { + /* we're frozen, so add to the queue and release our freeze */ + g_object_notify_queue_add (object, nqueue, notify_pspec); + g_object_notify_queue_thaw (object, nqueue); + } + else + /* not frozen, so just dispatch the notification directly */ + G_OBJECT_GET_CLASS (object) + ->dispatch_properties_changed (object, 1, ¬ify_pspec); + } +} + +/** + * g_object_notify: + * @object: a #GObject + * @property_name: the name of a property installed on the class of @object. + * + * Emits a "notify" signal for the property @property_name on @object. + * + * When possible, eg. when signaling a property change from within the class + * that registered the property, you should use g_object_notify_by_pspec() + * instead. + * + * Note that emission of the notify signal may be blocked with + * g_object_freeze_notify(). In this case, the signal emissions are queued + * and will be emitted (in reverse order) when g_object_thaw_notify() is + * called. + */ +void +g_object_notify (GObject *object, + const gchar *property_name) +{ + GParamSpec *pspec; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (property_name != NULL); + if (g_atomic_int_get (&object->ref_count) == 0) + return; + + g_object_ref (object); + /* We don't need to get the redirect target + * (by, e.g. calling g_object_class_find_property()) + * because g_object_notify_queue_add() does that + */ + pspec = g_param_spec_pool_lookup (pspec_pool, + property_name, + G_OBJECT_TYPE (object), + TRUE); + + if (!pspec) + g_warning ("%s: object class '%s' has no property named '%s'", + G_STRFUNC, + G_OBJECT_TYPE_NAME (object), + property_name); + else + g_object_notify_by_spec_internal (object, pspec); + g_object_unref (object); +} + +/** + * g_object_notify_by_pspec: + * @object: a #GObject + * @pspec: the #GParamSpec of a property installed on the class of @object. + * + * Emits a "notify" signal for the property specified by @pspec on @object. + * + * This function omits the property name lookup, hence it is faster than + * g_object_notify(). + * + * One way to avoid using g_object_notify() from within the + * class that registered the properties, and using g_object_notify_by_pspec() + * instead, is to store the GParamSpec used with + * g_object_class_install_property() inside a static array, e.g.: + * + *|[ + * enum + * { + * PROP_0, + * PROP_FOO, + * PROP_LAST + * }; + * + * static GParamSpec *properties[PROP_LAST]; + * + * static void + * my_object_class_init (MyObjectClass *klass) + * { + * properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "The foo", + * 0, 100, + * 50, + * G_PARAM_READWRITE); + * g_object_class_install_property (gobject_class, + * PROP_FOO, + * properties[PROP_FOO]); + * } + * ]| + * + * and then notify a change on the "foo" property with: + * + * |[ + * g_object_notify_by_pspec (self, properties[PROP_FOO]); + * ]| + * + * Since: 2.26 + */ +void +g_object_notify_by_pspec (GObject *object, + GParamSpec *pspec) +{ + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + + if (g_atomic_int_get (&object->ref_count) == 0) + return; + + g_object_ref (object); + g_object_notify_by_spec_internal (object, pspec); + g_object_unref (object); +} + +/** + * g_object_thaw_notify: + * @object: a #GObject + * + * Reverts the effect of a previous call to + * g_object_freeze_notify(). The freeze count is decreased on @object + * and when it reaches zero, queued "notify" signals are emitted. + * + * Duplicate notifications for each property are squashed so that at most one + * #GObject::notify signal is emitted for each property, in the reverse order + * in which they have been queued. + * + * It is an error to call this function when the freeze count is zero. + */ +void +g_object_thaw_notify (GObject *object) +{ + GObjectNotifyQueue *nqueue; + + g_return_if_fail (G_IS_OBJECT (object)); + if (g_atomic_int_get (&object->ref_count) == 0) + return; + + g_object_ref (object); + + /* FIXME: Freezing is the only way to get at the notify queue. + * So we freeze once and then thaw twice. + */ + nqueue = g_object_notify_queue_freeze (object, FALSE); + g_object_notify_queue_thaw (object, nqueue); + g_object_notify_queue_thaw (object, nqueue); + + g_object_unref (object); +} + +static void +consider_issuing_property_deprecation_warning (const GParamSpec *pspec) +{ + static GHashTable *already_warned_table; + static const gchar *enable_diagnostic; + static GMutex already_warned_lock; + gboolean already; + + if (!(pspec->flags & G_PARAM_DEPRECATED)) + return; + + if (g_once_init_enter (&enable_diagnostic)) + { + const gchar *value = g_getenv ("G_ENABLE_DIAGNOSTIC"); + + if (!value) + value = "0"; + + g_once_init_leave (&enable_diagnostic, value); + } + + if (enable_diagnostic[0] == '0') + return; + + /* We hash only on property names: this means that we could end up in + * a situation where we fail to emit a warning about a pair of + * same-named deprecated properties used on two separate types. + * That's pretty unlikely to occur, and even if it does, you'll still + * have seen the warning for the first one... + * + * Doing it this way lets us hash directly on the (interned) property + * name pointers. + */ + g_mutex_lock (&already_warned_lock); + + if (already_warned_table == NULL) + already_warned_table = g_hash_table_new (NULL, NULL); + + already = g_hash_table_contains (already_warned_table, (gpointer) pspec->name); + if (!already) + g_hash_table_add (already_warned_table, (gpointer) pspec->name); + + g_mutex_unlock (&already_warned_lock); + + if (!already) + g_warning ("The property %s:%s is deprecated and shouldn't be used " + "anymore. It will be removed in a future version.", + g_type_name (pspec->owner_type), pspec->name); +} + +static inline void +object_get_property (GObject *object, + GParamSpec *pspec, + GValue *value) +{ + GObjectClass *class = g_type_class_peek (pspec->owner_type); + guint param_id = PARAM_SPEC_PARAM_ID (pspec); + GParamSpec *redirect; + + if (class == NULL) + { + g_warning ("'%s::%s' is not a valid property name; '%s' is not a GObject subtype", + g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->owner_type)); + return; + } + + redirect = g_param_spec_get_redirect_target (pspec); + if (redirect) + pspec = redirect; + + consider_issuing_property_deprecation_warning (pspec); + + class->get_property (object, param_id, value, pspec); +} + +static inline void +object_set_property (GObject *object, + GParamSpec *pspec, + const GValue *value, + GObjectNotifyQueue *nqueue) +{ + GValue tmp_value = G_VALUE_INIT; + GObjectClass *class = g_type_class_peek (pspec->owner_type); + guint param_id = PARAM_SPEC_PARAM_ID (pspec); + GParamSpec *redirect; + + if (class == NULL) + { + g_warning ("'%s::%s' is not a valid property name; '%s' is not a GObject subtype", + g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->owner_type)); + return; + } + + redirect = g_param_spec_get_redirect_target (pspec); + if (redirect) + pspec = redirect; + + /* provide a copy to work from, convert (if necessary) and validate */ + g_value_init (&tmp_value, pspec->value_type); + if (!g_value_transform (value, &tmp_value)) + g_warning ("unable to set property '%s' of type '%s' from value of type '%s'", + pspec->name, + g_type_name (pspec->value_type), + G_VALUE_TYPE_NAME (value)); + else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION)) + { + gchar *contents = g_strdup_value_contents (value); + + g_warning ("value \"%s\" of type '%s' is invalid or out of range for property '%s' of type '%s'", + contents, + G_VALUE_TYPE_NAME (value), + pspec->name, + g_type_name (pspec->value_type)); + g_free (contents); + } + else + { + class->set_property (object, param_id, &tmp_value, pspec); + + if (~pspec->flags & G_PARAM_EXPLICIT_NOTIFY && + pspec->flags & G_PARAM_READABLE) + g_object_notify_queue_add (object, nqueue, pspec); + } + g_value_unset (&tmp_value); +} + +static void +object_interface_check_properties (gpointer check_data, + gpointer g_iface) +{ + GTypeInterface *iface_class = g_iface; + GObjectClass *class; + GType iface_type = iface_class->g_type; + GParamSpec **pspecs; + guint n; + + class = g_type_class_ref (iface_class->g_instance_type); + + if (class == NULL) + return; + + if (!G_IS_OBJECT_CLASS (class)) + goto out; + + pspecs = g_param_spec_pool_list (pspec_pool, iface_type, &n); + + while (n--) + { + GParamSpec *class_pspec = g_param_spec_pool_lookup (pspec_pool, + pspecs[n]->name, + G_OBJECT_CLASS_TYPE (class), + TRUE); + + if (!class_pspec) + { + g_critical ("Object class %s doesn't implement property " + "'%s' from interface '%s'", + g_type_name (G_OBJECT_CLASS_TYPE (class)), + pspecs[n]->name, + g_type_name (iface_type)); + + continue; + } + + /* We do a number of checks on the properties of an interface to + * make sure that all classes implementing the interface are + * overriding the properties correctly. + * + * We do the checks in order of importance so that we can give + * more useful error messages first. + * + * First, we check that the implementation doesn't remove the + * basic functionality (readability, writability) advertised by + * the interface. Next, we check that it doesn't introduce + * additional restrictions (such as construct-only). Finally, we + * make sure the types are compatible. + */ + +#define SUBSET(a,b,mask) (((a) & ~(b) & (mask)) == 0) + /* If the property on the interface is readable then the + * implementation must be readable. If the interface is writable + * then the implementation must be writable. + */ + if (!SUBSET (pspecs[n]->flags, class_pspec->flags, G_PARAM_READABLE | G_PARAM_WRITABLE)) + { + g_critical ("Flags for property '%s' on class '%s' remove functionality compared with the " + "property on interface '%s'\n", pspecs[n]->name, + g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (iface_type)); + continue; + } + + /* If the property on the interface is writable then we need to + * make sure the implementation doesn't introduce new restrictions + * on that writability (ie: construct-only). + * + * If the interface was not writable to begin with then we don't + * really have any problems here because "writable at construct + * time only" is still more permissive than "read only". + */ + if (pspecs[n]->flags & G_PARAM_WRITABLE) + { + if (!SUBSET (class_pspec->flags, pspecs[n]->flags, G_PARAM_CONSTRUCT_ONLY)) + { + g_critical ("Flags for property '%s' on class '%s' introduce additional restrictions on " + "writability compared with the property on interface '%s'\n", pspecs[n]->name, + g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (iface_type)); + continue; + } + } +#undef SUBSET + + /* If the property on the interface is readable then we are + * effectively advertising that reading the property will return a + * value of a specific type. All implementations of the interface + * need to return items of this type -- but may be more + * restrictive. For example, it is legal to have: + * + * GtkWidget *get_item(); + * + * that is implemented by a function that always returns a + * GtkEntry. In short: readability implies that the + * implementation value type must be equal or more restrictive. + * + * Similarly, if the property on the interface is writable then + * must be able to accept the property being set to any value of + * that type, including subclasses. In this case, we may also be + * less restrictive. For example, it is legal to have: + * + * set_item (GtkEntry *); + * + * that is implemented by a function that will actually work with + * any GtkWidget. In short: writability implies that the + * implementation value type must be equal or less restrictive. + * + * In the case that the property is both readable and writable + * then the only way that both of the above can be satisfied is + * with a type that is exactly equal. + */ + switch (pspecs[n]->flags & (G_PARAM_READABLE | G_PARAM_WRITABLE)) + { + case G_PARAM_READABLE | G_PARAM_WRITABLE: + /* class pspec value type must have exact equality with interface */ + if (pspecs[n]->value_type != class_pspec->value_type) + g_critical ("Read/writable property '%s' on class '%s' has type '%s' which is not exactly equal to the " + "type '%s' of the property on the interface '%s'\n", pspecs[n]->name, + g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (G_PARAM_SPEC_VALUE_TYPE (class_pspec)), + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspecs[n])), g_type_name (iface_type)); + break; + + case G_PARAM_READABLE: + /* class pspec value type equal or more restrictive than interface */ + if (!g_type_is_a (class_pspec->value_type, pspecs[n]->value_type)) + g_critical ("Read-only property '%s' on class '%s' has type '%s' which is not equal to or more " + "restrictive than the type '%s' of the property on the interface '%s'\n", pspecs[n]->name, + g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (G_PARAM_SPEC_VALUE_TYPE (class_pspec)), + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspecs[n])), g_type_name (iface_type)); + break; + + case G_PARAM_WRITABLE: + /* class pspec value type equal or less restrictive than interface */ + if (!g_type_is_a (pspecs[n]->value_type, class_pspec->value_type)) + g_critical ("Write-only property '%s' on class '%s' has type '%s' which is not equal to or less " + "restrictive than the type '%s' of the property on the interface '%s' \n", pspecs[n]->name, + g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (G_PARAM_SPEC_VALUE_TYPE (class_pspec)), + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspecs[n])), g_type_name (iface_type)); + break; + + default: + g_assert_not_reached (); + } + } + + g_free (pspecs); + + out: + g_type_class_unref (class); +} + +GType +g_object_get_type (void) +{ + return G_TYPE_OBJECT; +} + +/** + * g_object_new: (skip) + * @object_type: the type id of the #GObject subtype to instantiate + * @first_property_name: the name of the first property + * @...: the value of the first property, followed optionally by more + * name/value pairs, followed by %NULL + * + * Creates a new instance of a #GObject subtype and sets its properties. + * + * Construction parameters (see %G_PARAM_CONSTRUCT, %G_PARAM_CONSTRUCT_ONLY) + * which are not explicitly specified are set to their default values. Any + * private data for the object is guaranteed to be initialized with zeros, as + * per g_type_create_instance(). + * + * Note that in C, small integer types in variable argument lists are promoted + * up to #gint or #guint as appropriate, and read back accordingly. #gint is 32 + * bits on every platform on which GLib is currently supported. This means that + * you can use C expressions of type #gint with g_object_new() and properties of + * type #gint or #guint or smaller. Specifically, you can use integer literals + * with these property types. + * + * When using property types of #gint64 or #guint64, you must ensure that the + * value that you provide is 64 bit. This means that you should use a cast or + * make use of the %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros. + * + * Similarly, #gfloat is promoted to #gdouble, so you must ensure that the value + * you provide is a #gdouble, even for a property of type #gfloat. + * + * Since GLib 2.72, all #GObjects are guaranteed to be aligned to at least the + * alignment of the largest basic GLib type (typically this is #guint64 or + * #gdouble). If you need larger alignment for an element in a #GObject, you + * should allocate it on the heap (aligned), or arrange for your #GObject to be + * appropriately padded. + * + * Returns: (transfer full) (type GObject.Object): a new instance of + * @object_type + */ +gpointer +g_object_new (GType object_type, + const gchar *first_property_name, + ...) +{ + GObject *object; + va_list var_args; + + /* short circuit for calls supplying no properties */ + if (!first_property_name) + return g_object_new_with_properties (object_type, 0, NULL, NULL); + + va_start (var_args, first_property_name); + object = g_object_new_valist (object_type, first_property_name, var_args); + va_end (var_args); + + return object; +} + +/* Check alignment. (See https://gitlab.gnome.org/GNOME/glib/-/issues/1231.) + * This should never fail, since g_type_create_instance() uses g_slice_alloc0(). + * The GSlice allocator always aligns to the next power of 2 greater than the + * allocation size. The allocation size for a GObject is + * sizeof(GTypeInstance) + sizeof(guint) + sizeof(GData*) + * which is 12B on 32-bit platforms, and larger on 64-bit systems. In both + * cases, that’s larger than the 8B needed for a guint64 or gdouble. + * + * If GSlice falls back to malloc(), it’s documented to return something + * suitably aligned for any basic type. */ +static inline gboolean +g_object_is_aligned (GObject *object) +{ + return ((((guintptr) (void *) object) % + MAX (G_ALIGNOF (gdouble), + MAX (G_ALIGNOF (guint64), + MAX (G_ALIGNOF (gint), + G_ALIGNOF (glong))))) == 0); +} + +static gpointer +g_object_new_with_custom_constructor (GObjectClass *class, + GObjectConstructParam *params, + guint n_params) +{ + GObjectNotifyQueue *nqueue = NULL; + gboolean newly_constructed; + GObjectConstructParam *cparams; + GObject *object; + GValue *cvalues; + gint n_cparams; + gint cvals_used; + GSList *node; + guint i; + + /* If we have ->constructed() then we have to do a lot more work. + * It's possible that this is a singleton and it's also possible + * that the user's constructor() will attempt to modify the values + * that we pass in, so we'll need to allocate copies of them. + * It's also possible that the user may attempt to call + * g_object_set() from inside of their constructor, so we need to + * add ourselves to a list of objects for which that is allowed + * while their constructor() is running. + */ + + /* Create the array of GObjectConstructParams for constructor() */ + n_cparams = g_slist_length (class->construct_properties); + cparams = g_new (GObjectConstructParam, n_cparams); + cvalues = g_new0 (GValue, n_cparams); + cvals_used = 0; + i = 0; + + /* As above, we may find the value in the passed-in params list. + * + * If we have the value passed in then we can use the GValue from + * it directly because it is safe to modify. If we use the + * default value from the class, we had better not pass that in + * and risk it being modified, so we create a new one. + * */ + for (node = class->construct_properties; node; node = node->next) + { + GParamSpec *pspec; + GValue *value; + guint j; + + pspec = node->data; + value = NULL; /* to silence gcc... */ + + for (j = 0; j < n_params; j++) + if (params[j].pspec == pspec) + { + consider_issuing_property_deprecation_warning (pspec); + value = params[j].value; + break; + } + + if (value == NULL) + { + value = &cvalues[cvals_used++]; + g_value_init (value, pspec->value_type); + g_param_value_set_default (pspec, value); + } + + cparams[i].pspec = pspec; + cparams[i].value = value; + i++; + } + + /* construct object from construction parameters */ + object = class->constructor (class->g_type_class.g_type, n_cparams, cparams); + /* free construction values */ + g_free (cparams); + while (cvals_used--) + g_value_unset (&cvalues[cvals_used]); + g_free (cvalues); + + /* There is code in the wild that relies on being able to return NULL + * from its custom constructor. This was never a supported operation, + * but since the code is already out there... + */ + if (object == NULL) + { + g_critical ("Custom constructor for class %s returned NULL (which is invalid). " + "Please use GInitable instead.", G_OBJECT_CLASS_NAME (class)); + return NULL; + } + + if (!g_object_is_aligned (object)) + { + g_critical ("Custom constructor for class %s returned a non-aligned " + "GObject (which is invalid since GLib 2.72). Assuming any " + "code using this object doesn’t require it to be aligned. " + "Please fix your constructor to align to the largest GLib " + "basic type (typically gdouble or guint64).", + G_OBJECT_CLASS_NAME (class)); + } + + /* g_object_init() will have marked the object as being in-construction. + * Check if the returned object still is so marked, or if this is an + * already-existing singleton (in which case we should not do 'constructed'). + */ + newly_constructed = object_in_construction (object); + if (newly_constructed) + unset_object_in_construction (object); + + if (CLASS_HAS_PROPS (class)) + { + /* If this object was newly_constructed then g_object_init() + * froze the queue. We need to freeze it here in order to get + * the handle so that we can thaw it below (otherwise it will + * be frozen forever). + * + * We also want to do a freeze if we have any params to set, + * even on a non-newly_constructed object. + * + * It's possible that we have the case of non-newly created + * singleton and all of the passed-in params were construct + * properties so n_params > 0 but we will actually set no + * properties. This is a pretty lame case to optimise, so + * just ignore it and freeze anyway. + */ + if (newly_constructed || n_params) + nqueue = g_object_notify_queue_freeze (object, FALSE); + + /* Remember: if it was newly_constructed then g_object_init() + * already did a freeze, so we now have two. Release one. + */ + if (newly_constructed) + g_object_notify_queue_thaw (object, nqueue); + } + + /* run 'constructed' handler if there is a custom one */ + if (newly_constructed && CLASS_HAS_CUSTOM_CONSTRUCTED (class)) + class->constructed (object); + + /* set remaining properties */ + for (i = 0; i < n_params; i++) + if (!(params[i].pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))) + { + consider_issuing_property_deprecation_warning (params[i].pspec); + object_set_property (object, params[i].pspec, params[i].value, nqueue); + } + + /* If nqueue is non-NULL then we are frozen. Thaw it. */ + if (nqueue) + g_object_notify_queue_thaw (object, nqueue); + + return object; +} + +static gpointer +g_object_new_internal (GObjectClass *class, + GObjectConstructParam *params, + guint n_params) +{ + GObjectNotifyQueue *nqueue = NULL; + GObject *object; + + if G_UNLIKELY (CLASS_HAS_CUSTOM_CONSTRUCTOR (class)) + return g_object_new_with_custom_constructor (class, params, n_params); + + object = (GObject *) g_type_create_instance (class->g_type_class.g_type); + + g_assert (g_object_is_aligned (object)); + + if (CLASS_HAS_PROPS (class)) + { + GSList *node; + + /* This will have been setup in g_object_init() */ + nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue); + g_assert (nqueue != NULL); + + /* We will set exactly n_construct_properties construct + * properties, but they may come from either the class default + * values or the passed-in parameter list. + */ + for (node = class->construct_properties; node; node = node->next) + { + const GValue *value; + GParamSpec *pspec; + guint j; + + pspec = node->data; + value = NULL; /* to silence gcc... */ + + for (j = 0; j < n_params; j++) + if (params[j].pspec == pspec) + { + consider_issuing_property_deprecation_warning (pspec); + value = params[j].value; + break; + } + + if (value == NULL) + value = g_param_spec_get_default_value (pspec); + + object_set_property (object, pspec, value, nqueue); + } + } + + /* run 'constructed' handler if there is a custom one */ + if (CLASS_HAS_CUSTOM_CONSTRUCTED (class)) + class->constructed (object); + + if (nqueue) + { + guint i; + + /* Set remaining properties. The construct properties will + * already have been taken, so set only the non-construct + * ones. + */ + for (i = 0; i < n_params; i++) + if (!(params[i].pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))) + { + consider_issuing_property_deprecation_warning (params[i].pspec); + object_set_property (object, params[i].pspec, params[i].value, nqueue); + } + + g_object_notify_queue_thaw (object, nqueue); + } + + return object; +} + + +static inline gboolean +g_object_new_is_valid_property (GType object_type, + GParamSpec *pspec, + const char *name, + GObjectConstructParam *params, + guint n_params) +{ + guint i; + + if (G_UNLIKELY (pspec == NULL)) + { + g_critical ("%s: object class '%s' has no property named '%s'", + G_STRFUNC, g_type_name (object_type), name); + return FALSE; + } + + if (G_UNLIKELY (~pspec->flags & G_PARAM_WRITABLE)) + { + g_critical ("%s: property '%s' of object class '%s' is not writable", + G_STRFUNC, pspec->name, g_type_name (object_type)); + return FALSE; + } + + if (G_UNLIKELY (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))) + { + for (i = 0; i < n_params; i++) + if (params[i].pspec == pspec) + break; + if (G_UNLIKELY (i != n_params)) + { + g_critical ("%s: property '%s' for type '%s' cannot be set twice", + G_STRFUNC, name, g_type_name (object_type)); + return FALSE; + } + } + return TRUE; +} + + +/** + * g_object_new_with_properties: (skip) + * @object_type: the object type to instantiate + * @n_properties: the number of properties + * @names: (array length=n_properties): the names of each property to be set + * @values: (array length=n_properties): the values of each property to be set + * + * Creates a new instance of a #GObject subtype and sets its properties using + * the provided arrays. Both arrays must have exactly @n_properties elements, + * and the names and values correspond by index. + * + * Construction parameters (see %G_PARAM_CONSTRUCT, %G_PARAM_CONSTRUCT_ONLY) + * which are not explicitly specified are set to their default values. + * + * Returns: (type GObject.Object) (transfer full): a new instance of + * @object_type + * + * Since: 2.54 + */ +GObject * +g_object_new_with_properties (GType object_type, + guint n_properties, + const char *names[], + const GValue values[]) +{ + GObjectClass *class, *unref_class = NULL; + GObject *object; + + g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL); + + /* Try to avoid thrashing the ref_count if we don't need to (since + * it's a locked operation). + */ + class = g_type_class_peek_static (object_type); + + if (class == NULL) + class = unref_class = g_type_class_ref (object_type); + + if (n_properties > 0) + { + guint i, count = 0; + GObjectConstructParam *params; + + params = g_newa (GObjectConstructParam, n_properties); + for (i = 0; i < n_properties; i++) + { + GParamSpec *pspec; + pspec = g_param_spec_pool_lookup (pspec_pool, names[i], object_type, TRUE); + if (!g_object_new_is_valid_property (object_type, pspec, names[i], params, count)) + continue; + params[count].pspec = pspec; + + /* Init GValue */ + params[count].value = g_newa0 (GValue, 1); + g_value_init (params[count].value, G_VALUE_TYPE (&values[i])); + + g_value_copy (&values[i], params[count].value); + count++; + } + object = g_object_new_internal (class, params, count); + + while (count--) + g_value_unset (params[count].value); + } + else + object = g_object_new_internal (class, NULL, 0); + + if (unref_class != NULL) + g_type_class_unref (unref_class); + + return object; +} + +/** + * g_object_newv: + * @object_type: the type id of the #GObject subtype to instantiate + * @n_parameters: the length of the @parameters array + * @parameters: (array length=n_parameters): an array of #GParameter + * + * Creates a new instance of a #GObject subtype and sets its properties. + * + * Construction parameters (see %G_PARAM_CONSTRUCT, %G_PARAM_CONSTRUCT_ONLY) + * which are not explicitly specified are set to their default values. + * + * Returns: (type GObject.Object) (transfer full): a new instance of + * @object_type + * + * Deprecated: 2.54: Use g_object_new_with_properties() instead. + * deprecated. See #GParameter for more information. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +gpointer +g_object_newv (GType object_type, + guint n_parameters, + GParameter *parameters) +{ + GObjectClass *class, *unref_class = NULL; + GObject *object; + + g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL); + g_return_val_if_fail (n_parameters == 0 || parameters != NULL, NULL); + + /* Try to avoid thrashing the ref_count if we don't need to (since + * it's a locked operation). + */ + class = g_type_class_peek_static (object_type); + + if (!class) + class = unref_class = g_type_class_ref (object_type); + + if (n_parameters) + { + GObjectConstructParam *cparams; + guint i, j; + + cparams = g_newa (GObjectConstructParam, n_parameters); + j = 0; + + for (i = 0; i < n_parameters; i++) + { + GParamSpec *pspec; + + pspec = g_param_spec_pool_lookup (pspec_pool, parameters[i].name, object_type, TRUE); + if (!g_object_new_is_valid_property (object_type, pspec, parameters[i].name, cparams, j)) + continue; + + cparams[j].pspec = pspec; + cparams[j].value = ¶meters[i].value; + j++; + } + + object = g_object_new_internal (class, cparams, j); + } + else + /* Fast case: no properties passed in. */ + object = g_object_new_internal (class, NULL, 0); + + if (unref_class) + g_type_class_unref (unref_class); + + return object; +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_object_new_valist: (skip) + * @object_type: the type id of the #GObject subtype to instantiate + * @first_property_name: the name of the first property + * @var_args: the value of the first property, followed optionally by more + * name/value pairs, followed by %NULL + * + * Creates a new instance of a #GObject subtype and sets its properties. + * + * Construction parameters (see %G_PARAM_CONSTRUCT, %G_PARAM_CONSTRUCT_ONLY) + * which are not explicitly specified are set to their default values. + * + * Returns: a new instance of @object_type + */ +GObject* +g_object_new_valist (GType object_type, + const gchar *first_property_name, + va_list var_args) +{ + GObjectClass *class, *unref_class = NULL; + GObject *object; + + g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL); + + /* Try to avoid thrashing the ref_count if we don't need to (since + * it's a locked operation). + */ + class = g_type_class_peek_static (object_type); + + if (!class) + class = unref_class = g_type_class_ref (object_type); + + if (first_property_name) + { + GObjectConstructParam params_stack[16]; + GValue values_stack[G_N_ELEMENTS (params_stack)]; + const gchar *name; + GObjectConstructParam *params = params_stack; + GValue *values = values_stack; + guint n_params = 0; + guint n_params_alloc = G_N_ELEMENTS (params_stack); + + name = first_property_name; + + do + { + gchar *error = NULL; + GParamSpec *pspec; + + pspec = g_param_spec_pool_lookup (pspec_pool, name, object_type, TRUE); + + if (!g_object_new_is_valid_property (object_type, pspec, name, params, n_params)) + break; + + if (G_UNLIKELY (n_params == n_params_alloc)) + { + guint i; + + if (n_params_alloc == G_N_ELEMENTS (params_stack)) + { + n_params_alloc = G_N_ELEMENTS (params_stack) * 2u; + params = g_new (GObjectConstructParam, n_params_alloc); + values = g_new (GValue, n_params_alloc); + memcpy (params, params_stack, sizeof (GObjectConstructParam) * n_params); + memcpy (values, values_stack, sizeof (GValue) * n_params); + } + else + { + n_params_alloc *= 2u; + params = g_realloc (params, sizeof (GObjectConstructParam) * n_params_alloc); + values = g_realloc (values, sizeof (GValue) * n_params_alloc); + } + + for (i = 0; i < n_params; i++) + params[i].value = &values[i]; + } + + params[n_params].pspec = pspec; + params[n_params].value = &values[n_params]; + memset (&values[n_params], 0, sizeof (GValue)); + + G_VALUE_COLLECT_INIT (&values[n_params], pspec->value_type, var_args, 0, &error); + + if (error) + { + g_critical ("%s: %s", G_STRFUNC, error); + g_value_unset (&values[n_params]); + g_free (error); + break; + } + + n_params++; + } + while ((name = va_arg (var_args, const gchar *))); + + object = g_object_new_internal (class, params, n_params); + + while (n_params--) + g_value_unset (params[n_params].value); + + if (G_UNLIKELY (n_params_alloc != G_N_ELEMENTS (params_stack))) + { + g_free (params); + g_free (values); + } + } + else + /* Fast case: no properties passed in. */ + object = g_object_new_internal (class, NULL, 0); + + if (unref_class) + g_type_class_unref (unref_class); + + return object; +} + +static GObject* +g_object_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + + /* create object */ + object = (GObject*) g_type_create_instance (type); + + /* set construction parameters */ + if (n_construct_properties) + { + GObjectNotifyQueue *nqueue = g_object_notify_queue_freeze (object, FALSE); + + /* set construct properties */ + while (n_construct_properties--) + { + GValue *value = construct_params->value; + GParamSpec *pspec = construct_params->pspec; + + construct_params++; + object_set_property (object, pspec, value, nqueue); + } + g_object_notify_queue_thaw (object, nqueue); + /* the notification queue is still frozen from g_object_init(), so + * we don't need to handle it here, g_object_newv() takes + * care of that + */ + } + + return object; +} + +static void +g_object_constructed (GObject *object) +{ + /* empty default impl to allow unconditional upchaining */ +} + +static inline gboolean +g_object_set_is_valid_property (GObject *object, + GParamSpec *pspec, + const char *property_name) +{ + if (G_UNLIKELY (pspec == NULL)) + { + g_warning ("%s: object class '%s' has no property named '%s'", + G_STRFUNC, G_OBJECT_TYPE_NAME (object), property_name); + return FALSE; + } + if (G_UNLIKELY (!(pspec->flags & G_PARAM_WRITABLE))) + { + g_warning ("%s: property '%s' of object class '%s' is not writable", + G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object)); + return FALSE; + } + if (G_UNLIKELY (((pspec->flags & G_PARAM_CONSTRUCT_ONLY) && !object_in_construction (object)))) + { + g_warning ("%s: construct property \"%s\" for object '%s' can't be set after construction", + G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object)); + return FALSE; + } + return TRUE; +} + +/** + * g_object_setv: (skip) + * @object: a #GObject + * @n_properties: the number of properties + * @names: (array length=n_properties): the names of each property to be set + * @values: (array length=n_properties): the values of each property to be set + * + * Sets @n_properties properties for an @object. + * Properties to be set will be taken from @values. All properties must be + * valid. Warnings will be emitted and undefined behaviour may result if invalid + * properties are passed in. + * + * Since: 2.54 + */ +void +g_object_setv (GObject *object, + guint n_properties, + const gchar *names[], + const GValue values[]) +{ + guint i; + GObjectNotifyQueue *nqueue; + GParamSpec *pspec; + GType obj_type; + + g_return_if_fail (G_IS_OBJECT (object)); + + if (n_properties == 0) + return; + + g_object_ref (object); + obj_type = G_OBJECT_TYPE (object); + nqueue = g_object_notify_queue_freeze (object, FALSE); + for (i = 0; i < n_properties; i++) + { + pspec = g_param_spec_pool_lookup (pspec_pool, names[i], obj_type, TRUE); + + if (!g_object_set_is_valid_property (object, pspec, names[i])) + break; + + consider_issuing_property_deprecation_warning (pspec); + object_set_property (object, pspec, &values[i], nqueue); + } + + g_object_notify_queue_thaw (object, nqueue); + g_object_unref (object); +} + +/** + * g_object_set_valist: (skip) + * @object: a #GObject + * @first_property_name: name of the first property to set + * @var_args: value for the first property, followed optionally by more + * name/value pairs, followed by %NULL + * + * Sets properties on an object. + */ +void +g_object_set_valist (GObject *object, + const gchar *first_property_name, + va_list var_args) +{ + GObjectNotifyQueue *nqueue; + const gchar *name; + + g_return_if_fail (G_IS_OBJECT (object)); + + g_object_ref (object); + nqueue = g_object_notify_queue_freeze (object, FALSE); + + name = first_property_name; + while (name) + { + GValue value = G_VALUE_INIT; + GParamSpec *pspec; + gchar *error = NULL; + + pspec = g_param_spec_pool_lookup (pspec_pool, + name, + G_OBJECT_TYPE (object), + TRUE); + + if (!g_object_set_is_valid_property (object, pspec, name)) + break; + + G_VALUE_COLLECT_INIT (&value, pspec->value_type, var_args, + 0, &error); + if (error) + { + g_warning ("%s: %s", G_STRFUNC, error); + g_free (error); + g_value_unset (&value); + break; + } + + consider_issuing_property_deprecation_warning (pspec); + object_set_property (object, pspec, &value, nqueue); + g_value_unset (&value); + + name = va_arg (var_args, gchar*); + } + + g_object_notify_queue_thaw (object, nqueue); + g_object_unref (object); +} + +static inline gboolean +g_object_get_is_valid_property (GObject *object, + GParamSpec *pspec, + const char *property_name) +{ + if (G_UNLIKELY (pspec == NULL)) + { + g_warning ("%s: object class '%s' has no property named '%s'", + G_STRFUNC, G_OBJECT_TYPE_NAME (object), property_name); + return FALSE; + } + if (G_UNLIKELY (!(pspec->flags & G_PARAM_READABLE))) + { + g_warning ("%s: property '%s' of object class '%s' is not readable", + G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object)); + return FALSE; + } + return TRUE; +} + +/** + * g_object_getv: + * @object: a #GObject + * @n_properties: the number of properties + * @names: (array length=n_properties): the names of each property to get + * @values: (array length=n_properties): the values of each property to get + * + * Gets @n_properties properties for an @object. + * Obtained properties will be set to @values. All properties must be valid. + * Warnings will be emitted and undefined behaviour may result if invalid + * properties are passed in. + * + * Since: 2.54 + */ +void +g_object_getv (GObject *object, + guint n_properties, + const gchar *names[], + GValue values[]) +{ + guint i; + GParamSpec *pspec; + GType obj_type; + + g_return_if_fail (G_IS_OBJECT (object)); + + if (n_properties == 0) + return; + + g_object_ref (object); + + memset (values, 0, n_properties * sizeof (GValue)); + + obj_type = G_OBJECT_TYPE (object); + for (i = 0; i < n_properties; i++) + { + pspec = g_param_spec_pool_lookup (pspec_pool, names[i], obj_type, TRUE); + if (!g_object_get_is_valid_property (object, pspec, names[i])) + break; + g_value_init (&values[i], pspec->value_type); + object_get_property (object, pspec, &values[i]); + } + g_object_unref (object); +} + +/** + * g_object_get_valist: (skip) + * @object: a #GObject + * @first_property_name: name of the first property to get + * @var_args: return location for the first property, followed optionally by more + * name/return location pairs, followed by %NULL + * + * Gets properties of an object. + * + * In general, a copy is made of the property contents and the caller + * is responsible for freeing the memory in the appropriate manner for + * the type, for instance by calling g_free() or g_object_unref(). + * + * See g_object_get(). + */ +void +g_object_get_valist (GObject *object, + const gchar *first_property_name, + va_list var_args) +{ + const gchar *name; + + g_return_if_fail (G_IS_OBJECT (object)); + + g_object_ref (object); + + name = first_property_name; + + while (name) + { + GValue value = G_VALUE_INIT; + GParamSpec *pspec; + gchar *error; + + pspec = g_param_spec_pool_lookup (pspec_pool, + name, + G_OBJECT_TYPE (object), + TRUE); + + if (!g_object_get_is_valid_property (object, pspec, name)) + break; + + g_value_init (&value, pspec->value_type); + + object_get_property (object, pspec, &value); + + G_VALUE_LCOPY (&value, var_args, 0, &error); + if (error) + { + g_warning ("%s: %s", G_STRFUNC, error); + g_free (error); + g_value_unset (&value); + break; + } + + g_value_unset (&value); + + name = va_arg (var_args, gchar*); + } + + g_object_unref (object); +} + +/** + * g_object_set: (skip) + * @object: (type GObject.Object): a #GObject + * @first_property_name: name of the first property to set + * @...: value for the first property, followed optionally by more + * name/value pairs, followed by %NULL + * + * Sets properties on an object. + * + * The same caveats about passing integer literals as varargs apply as with + * g_object_new(). In particular, any integer literals set as the values for + * properties of type #gint64 or #guint64 must be 64 bits wide, using the + * %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros. + * + * Note that the "notify" signals are queued and only emitted (in + * reverse order) after all properties have been set. See + * g_object_freeze_notify(). + */ +void +g_object_set (gpointer _object, + const gchar *first_property_name, + ...) +{ + GObject *object = _object; + va_list var_args; + + g_return_if_fail (G_IS_OBJECT (object)); + + va_start (var_args, first_property_name); + g_object_set_valist (object, first_property_name, var_args); + va_end (var_args); +} + +/** + * g_object_get: (skip) + * @object: (type GObject.Object): a #GObject + * @first_property_name: name of the first property to get + * @...: return location for the first property, followed optionally by more + * name/return location pairs, followed by %NULL + * + * Gets properties of an object. + * + * In general, a copy is made of the property contents and the caller + * is responsible for freeing the memory in the appropriate manner for + * the type, for instance by calling g_free() or g_object_unref(). + * + * Here is an example of using g_object_get() to get the contents + * of three properties: an integer, a string and an object: + * |[ + * gint intval; + * guint64 uint64val; + * gchar *strval; + * GObject *objval; + * + * g_object_get (my_object, + * "int-property", &intval, + * "uint64-property", &uint64val, + * "str-property", &strval, + * "obj-property", &objval, + * NULL); + * + * // Do something with intval, uint64val, strval, objval + * + * g_free (strval); + * g_object_unref (objval); + * ]| + */ +void +g_object_get (gpointer _object, + const gchar *first_property_name, + ...) +{ + GObject *object = _object; + va_list var_args; + + g_return_if_fail (G_IS_OBJECT (object)); + + va_start (var_args, first_property_name); + g_object_get_valist (object, first_property_name, var_args); + va_end (var_args); +} + +/** + * g_object_set_property: + * @object: a #GObject + * @property_name: the name of the property to set + * @value: the value + * + * Sets a property on an object. + */ +void +g_object_set_property (GObject *object, + const gchar *property_name, + const GValue *value) +{ + g_object_setv (object, 1, &property_name, value); +} + +/** + * g_object_get_property: + * @object: a #GObject + * @property_name: the name of the property to get + * @value: return location for the property value + * + * Gets a property of an object. + * + * The @value can be: + * + * - an empty #GValue initialized by %G_VALUE_INIT, which will be + * automatically initialized with the expected type of the property + * (since GLib 2.60) + * - a #GValue initialized with the expected type of the property + * - a #GValue initialized with a type to which the expected type + * of the property can be transformed + * + * In general, a copy is made of the property contents and the caller is + * responsible for freeing the memory by calling g_value_unset(). + * + * Note that g_object_get_property() is really intended for language + * bindings, g_object_get() is much more convenient for C programming. + */ +void +g_object_get_property (GObject *object, + const gchar *property_name, + GValue *value) +{ + GParamSpec *pspec; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (property_name != NULL); + g_return_if_fail (value != NULL); + + g_object_ref (object); + + pspec = g_param_spec_pool_lookup (pspec_pool, + property_name, + G_OBJECT_TYPE (object), + TRUE); + + if (g_object_get_is_valid_property (object, pspec, property_name)) + { + GValue *prop_value, tmp_value = G_VALUE_INIT; + + if (G_VALUE_TYPE (value) == G_TYPE_INVALID) + { + /* zero-initialized value */ + g_value_init (value, pspec->value_type); + prop_value = value; + } + else if (G_VALUE_TYPE (value) == pspec->value_type) + { + /* auto-conversion of the callers value type */ + g_value_reset (value); + prop_value = value; + } + else if (!g_value_type_transformable (pspec->value_type, G_VALUE_TYPE (value))) + { + g_warning ("%s: can't retrieve property '%s' of type '%s' as value of type '%s'", + G_STRFUNC, pspec->name, + g_type_name (pspec->value_type), + G_VALUE_TYPE_NAME (value)); + g_object_unref (object); + return; + } + else + { + g_value_init (&tmp_value, pspec->value_type); + prop_value = &tmp_value; + } + object_get_property (object, pspec, prop_value); + if (prop_value != value) + { + g_value_transform (prop_value, value); + g_value_unset (&tmp_value); + } + } + + g_object_unref (object); +} + +/** + * g_object_connect: (skip) + * @object: (type GObject.Object): a #GObject + * @signal_spec: the spec for the first signal + * @...: #GCallback for the first signal, followed by data for the + * first signal, followed optionally by more signal + * spec/callback/data triples, followed by %NULL + * + * A convenience function to connect multiple signals at once. + * + * The signal specs expected by this function have the form + * "modifier::signal_name", where modifier can be one of the following: + * - signal: equivalent to g_signal_connect_data (..., NULL, 0) + * - object-signal, object_signal: equivalent to g_signal_connect_object (..., 0) + * - swapped-signal, swapped_signal: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_SWAPPED) + * - swapped_object_signal, swapped-object-signal: equivalent to g_signal_connect_object (..., G_CONNECT_SWAPPED) + * - signal_after, signal-after: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_AFTER) + * - object_signal_after, object-signal-after: equivalent to g_signal_connect_object (..., G_CONNECT_AFTER) + * - swapped_signal_after, swapped-signal-after: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_SWAPPED | G_CONNECT_AFTER) + * - swapped_object_signal_after, swapped-object-signal-after: equivalent to g_signal_connect_object (..., G_CONNECT_SWAPPED | G_CONNECT_AFTER) + * + * |[ + * menu->toplevel = g_object_connect (g_object_new (GTK_TYPE_WINDOW, + * "type", GTK_WINDOW_POPUP, + * "child", menu, + * NULL), + * "signal::event", gtk_menu_window_event, menu, + * "signal::size_request", gtk_menu_window_size_request, menu, + * "signal::destroy", gtk_widget_destroyed, &menu->toplevel, + * NULL); + * ]| + * + * Returns: (transfer none) (type GObject.Object): @object + */ +gpointer +g_object_connect (gpointer _object, + const gchar *signal_spec, + ...) +{ + GObject *object = _object; + va_list var_args; + + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (object->ref_count > 0, object); + + va_start (var_args, signal_spec); + while (signal_spec) + { + GCallback callback = va_arg (var_args, GCallback); + gpointer data = va_arg (var_args, gpointer); + + if (strncmp (signal_spec, "signal::", 8) == 0) + g_signal_connect_data (object, signal_spec + 8, + callback, data, NULL, + 0); + else if (strncmp (signal_spec, "object_signal::", 15) == 0 || + strncmp (signal_spec, "object-signal::", 15) == 0) + g_signal_connect_object (object, signal_spec + 15, + callback, data, + 0); + else if (strncmp (signal_spec, "swapped_signal::", 16) == 0 || + strncmp (signal_spec, "swapped-signal::", 16) == 0) + g_signal_connect_data (object, signal_spec + 16, + callback, data, NULL, + G_CONNECT_SWAPPED); + else if (strncmp (signal_spec, "swapped_object_signal::", 23) == 0 || + strncmp (signal_spec, "swapped-object-signal::", 23) == 0) + g_signal_connect_object (object, signal_spec + 23, + callback, data, + G_CONNECT_SWAPPED); + else if (strncmp (signal_spec, "signal_after::", 14) == 0 || + strncmp (signal_spec, "signal-after::", 14) == 0) + g_signal_connect_data (object, signal_spec + 14, + callback, data, NULL, + G_CONNECT_AFTER); + else if (strncmp (signal_spec, "object_signal_after::", 21) == 0 || + strncmp (signal_spec, "object-signal-after::", 21) == 0) + g_signal_connect_object (object, signal_spec + 21, + callback, data, + G_CONNECT_AFTER); + else if (strncmp (signal_spec, "swapped_signal_after::", 22) == 0 || + strncmp (signal_spec, "swapped-signal-after::", 22) == 0) + g_signal_connect_data (object, signal_spec + 22, + callback, data, NULL, + G_CONNECT_SWAPPED | G_CONNECT_AFTER); + else if (strncmp (signal_spec, "swapped_object_signal_after::", 29) == 0 || + strncmp (signal_spec, "swapped-object-signal-after::", 29) == 0) + g_signal_connect_object (object, signal_spec + 29, + callback, data, + G_CONNECT_SWAPPED | G_CONNECT_AFTER); + else + { + g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC, signal_spec); + break; + } + signal_spec = va_arg (var_args, gchar*); + } + va_end (var_args); + + return object; +} + +/** + * g_object_disconnect: (skip) + * @object: (type GObject.Object): a #GObject + * @signal_spec: the spec for the first signal + * @...: #GCallback for the first signal, followed by data for the first signal, + * followed optionally by more signal spec/callback/data triples, + * followed by %NULL + * + * A convenience function to disconnect multiple signals at once. + * + * The signal specs expected by this function have the form + * "any_signal", which means to disconnect any signal with matching + * callback and data, or "any_signal::signal_name", which only + * disconnects the signal named "signal_name". + */ +void +g_object_disconnect (gpointer _object, + const gchar *signal_spec, + ...) +{ + GObject *object = _object; + va_list var_args; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (object->ref_count > 0); + + va_start (var_args, signal_spec); + while (signal_spec) + { + GCallback callback = va_arg (var_args, GCallback); + gpointer data = va_arg (var_args, gpointer); + guint sid = 0, detail = 0, mask = 0; + + if (strncmp (signal_spec, "any_signal::", 12) == 0 || + strncmp (signal_spec, "any-signal::", 12) == 0) + { + signal_spec += 12; + mask = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA; + } + else if (strcmp (signal_spec, "any_signal") == 0 || + strcmp (signal_spec, "any-signal") == 0) + { + signal_spec += 10; + mask = G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA; + } + else + { + g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC, signal_spec); + break; + } + + if ((mask & G_SIGNAL_MATCH_ID) && + !g_signal_parse_name (signal_spec, G_OBJECT_TYPE (object), &sid, &detail, FALSE)) + g_warning ("%s: invalid signal name \"%s\"", G_STRFUNC, signal_spec); + else if (!g_signal_handlers_disconnect_matched (object, mask | (detail ? G_SIGNAL_MATCH_DETAIL : 0), + sid, detail, + NULL, (gpointer)callback, data)) + g_warning ("%s: signal handler %p(%p) is not connected", G_STRFUNC, callback, data); + signal_spec = va_arg (var_args, gchar*); + } + va_end (var_args); +} + +typedef struct { + GObject *object; + guint n_weak_refs; + struct { + GWeakNotify notify; + gpointer data; + } weak_refs[1]; /* flexible array */ +} WeakRefStack; + +static void +weak_refs_notify (gpointer data) +{ + WeakRefStack *wstack = data; + guint i; + + for (i = 0; i < wstack->n_weak_refs; i++) + wstack->weak_refs[i].notify (wstack->weak_refs[i].data, wstack->object); + g_free (wstack); +} + +/** + * g_object_weak_ref: (skip) + * @object: #GObject to reference weakly + * @notify: callback to invoke before the object is freed + * @data: extra data to pass to notify + * + * Adds a weak reference callback to an object. Weak references are + * used for notification when an object is disposed. They are called + * "weak references" because they allow you to safely hold a pointer + * to an object without calling g_object_ref() (g_object_ref() adds a + * strong reference, that is, forces the object to stay alive). + * + * Note that the weak references created by this method are not + * thread-safe: they cannot safely be used in one thread if the + * object's last g_object_unref() might happen in another thread. + * Use #GWeakRef if thread-safety is required. + */ +void +g_object_weak_ref (GObject *object, + GWeakNotify notify, + gpointer data) +{ + WeakRefStack *wstack; + guint i; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (notify != NULL); + g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1); + + G_LOCK (weak_refs_mutex); + wstack = g_datalist_id_remove_no_notify (&object->qdata, quark_weak_refs); + if (wstack) + { + i = wstack->n_weak_refs++; + wstack = g_realloc (wstack, sizeof (*wstack) + sizeof (wstack->weak_refs[0]) * i); + } + else + { + wstack = g_renew (WeakRefStack, NULL, 1); + wstack->object = object; + wstack->n_weak_refs = 1; + i = 0; + } + wstack->weak_refs[i].notify = notify; + wstack->weak_refs[i].data = data; + g_datalist_id_set_data_full (&object->qdata, quark_weak_refs, wstack, weak_refs_notify); + G_UNLOCK (weak_refs_mutex); +} + +/** + * g_object_weak_unref: (skip) + * @object: #GObject to remove a weak reference from + * @notify: callback to search for + * @data: data to search for + * + * Removes a weak reference callback to an object. + */ +void +g_object_weak_unref (GObject *object, + GWeakNotify notify, + gpointer data) +{ + WeakRefStack *wstack; + gboolean found_one = FALSE; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (notify != NULL); + + G_LOCK (weak_refs_mutex); + wstack = g_datalist_id_get_data (&object->qdata, quark_weak_refs); + if (wstack) + { + guint i; + + for (i = 0; i < wstack->n_weak_refs; i++) + if (wstack->weak_refs[i].notify == notify && + wstack->weak_refs[i].data == data) + { + found_one = TRUE; + wstack->n_weak_refs -= 1; + if (i != wstack->n_weak_refs) + wstack->weak_refs[i] = wstack->weak_refs[wstack->n_weak_refs]; + + break; + } + } + G_UNLOCK (weak_refs_mutex); + if (!found_one) + g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data); +} + +/** + * g_object_add_weak_pointer: (skip) + * @object: The object that should be weak referenced. + * @weak_pointer_location: (inout) (not optional): The memory address + * of a pointer. + * + * Adds a weak reference from weak_pointer to @object to indicate that + * the pointer located at @weak_pointer_location is only valid during + * the lifetime of @object. When the @object is finalized, + * @weak_pointer will be set to %NULL. + * + * Note that as with g_object_weak_ref(), the weak references created by + * this method are not thread-safe: they cannot safely be used in one + * thread if the object's last g_object_unref() might happen in another + * thread. Use #GWeakRef if thread-safety is required. + */ +void +g_object_add_weak_pointer (GObject *object, + gpointer *weak_pointer_location) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (weak_pointer_location != NULL); + + g_object_weak_ref (object, + (GWeakNotify) g_nullify_pointer, + weak_pointer_location); +} + +/** + * g_object_remove_weak_pointer: (skip) + * @object: The object that is weak referenced. + * @weak_pointer_location: (inout) (not optional): The memory address + * of a pointer. + * + * Removes a weak reference from @object that was previously added + * using g_object_add_weak_pointer(). The @weak_pointer_location has + * to match the one used with g_object_add_weak_pointer(). + */ +void +g_object_remove_weak_pointer (GObject *object, + gpointer *weak_pointer_location) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (weak_pointer_location != NULL); + + g_object_weak_unref (object, + (GWeakNotify) g_nullify_pointer, + weak_pointer_location); +} + +static guint +object_floating_flag_handler (GObject *object, + gint job) +{ + switch (job) + { + gpointer oldvalue; + case +1: /* force floating if possible */ + do + oldvalue = g_atomic_pointer_get (&object->qdata); + while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue, + (gpointer) ((gsize) oldvalue | OBJECT_FLOATING_FLAG))); + return (gsize) oldvalue & OBJECT_FLOATING_FLAG; + case -1: /* sink if possible */ + do + oldvalue = g_atomic_pointer_get (&object->qdata); + while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue, + (gpointer) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG))); + return (gsize) oldvalue & OBJECT_FLOATING_FLAG; + default: /* check floating */ + return 0 != ((gsize) g_atomic_pointer_get (&object->qdata) & OBJECT_FLOATING_FLAG); + } +} + +/** + * g_object_is_floating: + * @object: (type GObject.Object): a #GObject + * + * Checks whether @object has a [floating][floating-ref] reference. + * + * Since: 2.10 + * + * Returns: %TRUE if @object has a floating reference + */ +gboolean +g_object_is_floating (gpointer _object) +{ + GObject *object = _object; + g_return_val_if_fail (G_IS_OBJECT (object), FALSE); + return floating_flag_handler (object, 0); +} + +/** + * g_object_ref_sink: + * @object: (type GObject.Object): a #GObject + * + * Increase the reference count of @object, and possibly remove the + * [floating][floating-ref] reference, if @object has a floating reference. + * + * In other words, if the object is floating, then this call "assumes + * ownership" of the floating reference, converting it to a normal + * reference by clearing the floating flag while leaving the reference + * count unchanged. If the object is not floating, then this call + * adds a new normal reference increasing the reference count by one. + * + * Since GLib 2.56, the type of @object will be propagated to the return type + * under the same conditions as for g_object_ref(). + * + * Since: 2.10 + * + * Returns: (type GObject.Object) (transfer none): @object + */ +gpointer +(g_object_ref_sink) (gpointer _object) +{ + GObject *object = _object; + gboolean was_floating; + g_return_val_if_fail (G_IS_OBJECT (object), object); + g_return_val_if_fail (g_atomic_int_get (&object->ref_count) >= 1, object); + g_object_ref (object); + was_floating = floating_flag_handler (object, -1); + if (was_floating) + g_object_unref (object); + return object; +} + +/** + * g_object_take_ref: (skip) + * @object: (type GObject.Object): a #GObject + * + * If @object is floating, sink it. Otherwise, do nothing. + * + * In other words, this function will convert a floating reference (if + * present) into a full reference. + * + * Typically you want to use g_object_ref_sink() in order to + * automatically do the correct thing with respect to floating or + * non-floating references, but there is one specific scenario where + * this function is helpful. + * + * The situation where this function is helpful is when creating an API + * that allows the user to provide a callback function that returns a + * GObject. We certainly want to allow the user the flexibility to + * return a non-floating reference from this callback (for the case + * where the object that is being returned already exists). + * + * At the same time, the API style of some popular GObject-based + * libraries (such as Gtk) make it likely that for newly-created GObject + * instances, the user can be saved some typing if they are allowed to + * return a floating reference. + * + * Using this function on the return value of the user's callback allows + * the user to do whichever is more convenient for them. The caller will + * alway receives exactly one full reference to the value: either the + * one that was returned in the first place, or a floating reference + * that has been converted to a full reference. + * + * This function has an odd interaction when combined with + * g_object_ref_sink() running at the same time in another thread on + * the same #GObject instance. If g_object_ref_sink() runs first then + * the result will be that the floating reference is converted to a hard + * reference. If g_object_take_ref() runs first then the result will be + * that the floating reference is converted to a hard reference and an + * additional reference on top of that one is added. It is best to avoid + * this situation. + * + * Since: 2.70 + * + * Returns: (type GObject.Object) (transfer full): @object + */ +gpointer +g_object_take_ref (gpointer _object) +{ + GObject *object = _object; + g_return_val_if_fail (G_IS_OBJECT (object), object); + g_return_val_if_fail (g_atomic_int_get (&object->ref_count) >= 1, object); + + floating_flag_handler (object, -1); + + return object; +} + +/** + * g_object_force_floating: + * @object: a #GObject + * + * This function is intended for #GObject implementations to re-enforce + * a [floating][floating-ref] object reference. Doing this is seldom + * required: all #GInitiallyUnowneds are created with a floating reference + * which usually just needs to be sunken by calling g_object_ref_sink(). + * + * Since: 2.10 + */ +void +g_object_force_floating (GObject *object) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1); + + floating_flag_handler (object, +1); +} + +typedef struct { + GObject *object; + guint n_toggle_refs; + struct { + GToggleNotify notify; + gpointer data; + } toggle_refs[1]; /* flexible array */ +} ToggleRefStack; + +static void +toggle_refs_notify (GObject *object, + gboolean is_last_ref) +{ + ToggleRefStack tstack, *tstackptr; + + G_LOCK (toggle_refs_mutex); + /* If another thread removed the toggle reference on the object, while + * we were waiting here, there's nothing to notify. + * So let's check again if the object has toggle reference and in case return. + */ + if (!OBJECT_HAS_TOGGLE_REF (object)) + { + G_UNLOCK (toggle_refs_mutex); + return; + } + + tstackptr = g_datalist_id_get_data (&object->qdata, quark_toggle_refs); + tstack = *tstackptr; + G_UNLOCK (toggle_refs_mutex); + + /* Reentrancy here is not as tricky as it seems, because a toggle reference + * will only be notified when there is exactly one of them. + */ + g_assert (tstack.n_toggle_refs == 1); + tstack.toggle_refs[0].notify (tstack.toggle_refs[0].data, tstack.object, is_last_ref); +} + +/** + * g_object_add_toggle_ref: (skip) + * @object: a #GObject + * @notify: a function to call when this reference is the + * last reference to the object, or is no longer + * the last reference. + * @data: data to pass to @notify + * + * Increases the reference count of the object by one and sets a + * callback to be called when all other references to the object are + * dropped, or when this is already the last reference to the object + * and another reference is established. + * + * This functionality is intended for binding @object to a proxy + * object managed by another memory manager. This is done with two + * paired references: the strong reference added by + * g_object_add_toggle_ref() and a reverse reference to the proxy + * object which is either a strong reference or weak reference. + * + * The setup is that when there are no other references to @object, + * only a weak reference is held in the reverse direction from @object + * to the proxy object, but when there are other references held to + * @object, a strong reference is held. The @notify callback is called + * when the reference from @object to the proxy object should be + * "toggled" from strong to weak (@is_last_ref true) or weak to strong + * (@is_last_ref false). + * + * Since a (normal) reference must be held to the object before + * calling g_object_add_toggle_ref(), the initial state of the reverse + * link is always strong. + * + * Multiple toggle references may be added to the same gobject, + * however if there are multiple toggle references to an object, none + * of them will ever be notified until all but one are removed. For + * this reason, you should only ever use a toggle reference if there + * is important state in the proxy object. + * + * Since: 2.8 + */ +void +g_object_add_toggle_ref (GObject *object, + GToggleNotify notify, + gpointer data) +{ + ToggleRefStack *tstack; + guint i; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (notify != NULL); + g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1); + + g_object_ref (object); + + G_LOCK (toggle_refs_mutex); + tstack = g_datalist_id_remove_no_notify (&object->qdata, quark_toggle_refs); + if (tstack) + { + i = tstack->n_toggle_refs++; + /* allocate i = tstate->n_toggle_refs - 1 positions beyond the 1 declared + * in tstate->toggle_refs */ + tstack = g_realloc (tstack, sizeof (*tstack) + sizeof (tstack->toggle_refs[0]) * i); + } + else + { + tstack = g_renew (ToggleRefStack, NULL, 1); + tstack->object = object; + tstack->n_toggle_refs = 1; + i = 0; + } + + /* Set a flag for fast lookup after adding the first toggle reference */ + if (tstack->n_toggle_refs == 1) + g_datalist_set_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG); + + tstack->toggle_refs[i].notify = notify; + tstack->toggle_refs[i].data = data; + g_datalist_id_set_data_full (&object->qdata, quark_toggle_refs, tstack, + (GDestroyNotify)g_free); + G_UNLOCK (toggle_refs_mutex); +} + +/** + * g_object_remove_toggle_ref: (skip) + * @object: a #GObject + * @notify: a function to call when this reference is the + * last reference to the object, or is no longer + * the last reference. + * @data: (nullable): data to pass to @notify, or %NULL to + * match any toggle refs with the @notify argument. + * + * Removes a reference added with g_object_add_toggle_ref(). The + * reference count of the object is decreased by one. + * + * Since: 2.8 + */ +void +g_object_remove_toggle_ref (GObject *object, + GToggleNotify notify, + gpointer data) +{ + ToggleRefStack *tstack; + gboolean found_one = FALSE; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (notify != NULL); + + G_LOCK (toggle_refs_mutex); + tstack = g_datalist_id_get_data (&object->qdata, quark_toggle_refs); + if (tstack) + { + guint i; + + for (i = 0; i < tstack->n_toggle_refs; i++) + if (tstack->toggle_refs[i].notify == notify && + (tstack->toggle_refs[i].data == data || data == NULL)) + { + found_one = TRUE; + tstack->n_toggle_refs -= 1; + if (i != tstack->n_toggle_refs) + tstack->toggle_refs[i] = tstack->toggle_refs[tstack->n_toggle_refs]; + + if (tstack->n_toggle_refs == 0) + g_datalist_unset_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG); + + break; + } + } + G_UNLOCK (toggle_refs_mutex); + + if (found_one) + g_object_unref (object); + else + g_warning ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC, notify, data); +} + +/** + * g_object_ref: + * @object: (type GObject.Object): a #GObject + * + * Increases the reference count of @object. + * + * Since GLib 2.56, if `GLIB_VERSION_MAX_ALLOWED` is 2.56 or greater, the type + * of @object will be propagated to the return type (using the GCC typeof() + * extension), so any casting the caller needs to do on the return type must be + * explicit. + * + * Returns: (type GObject.Object) (transfer none): the same @object + */ +gpointer +(g_object_ref) (gpointer _object) +{ + GObject *object = _object; + gint old_val; + gboolean object_already_finalized; + + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + + old_val = g_atomic_int_add (&object->ref_count, 1); + object_already_finalized = (old_val <= 0); + g_return_val_if_fail (!object_already_finalized, NULL); + + if (old_val == 1 && OBJECT_HAS_TOGGLE_REF (object)) + toggle_refs_notify (object, FALSE); + + TRACE (GOBJECT_OBJECT_REF(object,G_TYPE_FROM_INSTANCE(object),old_val)); + + return object; +} + +/** + * g_object_unref: + * @object: (type GObject.Object): a #GObject + * + * Decreases the reference count of @object. When its reference count + * drops to 0, the object is finalized (i.e. its memory is freed). + * + * If the pointer to the #GObject may be reused in future (for example, if it is + * an instance variable of another object), it is recommended to clear the + * pointer to %NULL rather than retain a dangling pointer to a potentially + * invalid #GObject instance. Use g_clear_object() for this. + */ +void +g_object_unref (gpointer _object) +{ + GObject *object = _object; + gint old_ref; + + g_return_if_fail (G_IS_OBJECT (object)); + + /* here we want to atomically do: if (ref_count>1) { ref_count--; return; } */ + retry_atomic_decrement1: + old_ref = g_atomic_int_get (&object->ref_count); + if (old_ref > 1) + { + /* valid if last 2 refs are owned by this call to unref and the toggle_ref */ + gboolean has_toggle_ref = OBJECT_HAS_TOGGLE_REF (object); + + if (!g_atomic_int_compare_and_exchange ((int *)&object->ref_count, old_ref, old_ref - 1)) + goto retry_atomic_decrement1; + + TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref)); + + /* if we went from 2->1 we need to notify toggle refs if any */ + if (old_ref == 2 && has_toggle_ref) /* The last ref being held in this case is owned by the toggle_ref */ + toggle_refs_notify (object, TRUE); + } + else + { + GSList **weak_locations; + GObjectNotifyQueue *nqueue; + + /* The only way that this object can live at this point is if + * there are outstanding weak references already established + * before we got here. + * + * If there were not already weak references then no more can be + * established at this time, because the other thread would have + * to hold a strong ref in order to call + * g_object_add_weak_pointer() and then we wouldn't be here. + * + * Other GWeakRef's (weak locations) instead may still be added + * before the object is finalized, but in such case we'll unset + * them as part of the qdata removal. + */ + weak_locations = g_datalist_id_get_data (&object->qdata, quark_weak_locations); + + if (weak_locations != NULL) + { + g_rw_lock_writer_lock (&weak_locations_lock); + + /* It is possible that one of the weak references beat us to + * the lock. Make sure the refcount is still what we expected + * it to be. + */ + old_ref = g_atomic_int_get (&object->ref_count); + if (old_ref != 1) + { + g_rw_lock_writer_unlock (&weak_locations_lock); + goto retry_atomic_decrement1; + } + + /* We got the lock first, so the object will definitely die + * now. Clear out all the weak references, if they're still set. + */ + weak_locations = g_datalist_id_remove_no_notify (&object->qdata, + quark_weak_locations); + g_clear_pointer (&weak_locations, weak_locations_free_unlocked); + + g_rw_lock_writer_unlock (&weak_locations_lock); + } + + /* freeze the notification queue, so we don't accidentally emit + * notifications during dispose() and finalize(). + * + * The notification queue stays frozen unless the instance acquires + * a reference during dispose(), in which case we thaw it and + * dispatch all the notifications. If the instance gets through + * to finalize(), the notification queue gets automatically + * drained when g_object_finalize() is reached and + * the qdata is cleared. + */ + nqueue = g_object_notify_queue_freeze (object, FALSE); + + /* we are about to remove the last reference */ + TRACE (GOBJECT_OBJECT_DISPOSE(object,G_TYPE_FROM_INSTANCE(object), 1)); + G_OBJECT_GET_CLASS (object)->dispose (object); + TRACE (GOBJECT_OBJECT_DISPOSE_END(object,G_TYPE_FROM_INSTANCE(object), 1)); + + /* may have been re-referenced meanwhile */ + retry_atomic_decrement2: + old_ref = g_atomic_int_get ((int *)&object->ref_count); + if (old_ref > 1) + { + /* valid if last 2 refs are owned by this call to unref and the toggle_ref */ + gboolean has_toggle_ref = OBJECT_HAS_TOGGLE_REF (object); + + if (!g_atomic_int_compare_and_exchange ((int *)&object->ref_count, old_ref, old_ref - 1)) + goto retry_atomic_decrement2; + + /* emit all notifications that have been queued during dispose() */ + g_object_notify_queue_thaw (object, nqueue); + + TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref)); + + /* if we went from 2->1 we need to notify toggle refs if any */ + if (old_ref == 2 && has_toggle_ref) /* The last ref being held in this case is owned by the toggle_ref */ + toggle_refs_notify (object, TRUE); + + return; + } + + /* we are still in the process of taking away the last ref */ + g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL); + g_signal_handlers_destroy (object); + g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL); + g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL); + + /* decrement the last reference */ + old_ref = g_atomic_int_add (&object->ref_count, -1); + g_return_if_fail (old_ref > 0); + + TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref)); + + /* may have been re-referenced meanwhile */ + if (G_LIKELY (old_ref == 1)) + { + TRACE (GOBJECT_OBJECT_FINALIZE(object,G_TYPE_FROM_INSTANCE(object))); + G_OBJECT_GET_CLASS (object)->finalize (object); + TRACE (GOBJECT_OBJECT_FINALIZE_END(object,G_TYPE_FROM_INSTANCE(object))); + + GOBJECT_IF_DEBUG (OBJECTS, + { + gboolean was_present; + + /* catch objects not chaining finalize handlers */ + G_LOCK (debug_objects); + was_present = g_hash_table_remove (debug_objects_ht, object); + G_UNLOCK (debug_objects); + + if (was_present) + g_critical ("Object %p of type %s not finalized correctly.", + object, G_OBJECT_TYPE_NAME (object)); + }); + g_type_free_instance ((GTypeInstance*) object); + } + else + { + /* The instance acquired a reference between dispose() and + * finalize(), so we need to thaw the notification queue + */ + g_object_notify_queue_thaw (object, nqueue); + } + } +} + +/** + * g_clear_object: (skip) + * @object_ptr: a pointer to a #GObject reference + * + * Clears a reference to a #GObject. + * + * @object_ptr must not be %NULL. + * + * If the reference is %NULL then this function does nothing. + * Otherwise, the reference count of the object is decreased and the + * pointer is set to %NULL. + * + * A macro is also included that allows this function to be used without + * pointer casts. + * + * Since: 2.28 + **/ +#undef g_clear_object +void +g_clear_object (GObject **object_ptr) +{ + g_clear_pointer (object_ptr, g_object_unref); +} + +/** + * g_object_get_qdata: + * @object: The GObject to get a stored user data pointer from + * @quark: A #GQuark, naming the user data pointer + * + * This function gets back user data pointers stored via + * g_object_set_qdata(). + * + * Returns: (transfer none) (nullable): The user data pointer set, or %NULL + */ +gpointer +g_object_get_qdata (GObject *object, + GQuark quark) +{ + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + + return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL; +} + +/** + * g_object_set_qdata: (skip) + * @object: The GObject to set store a user data pointer + * @quark: A #GQuark, naming the user data pointer + * @data: (nullable): An opaque user data pointer + * + * This sets an opaque, named pointer on an object. + * The name is specified through a #GQuark (retrieved e.g. via + * g_quark_from_static_string()), and the pointer + * can be gotten back from the @object with g_object_get_qdata() + * until the @object is finalized. + * Setting a previously set user data pointer, overrides (frees) + * the old pointer set, using #NULL as pointer essentially + * removes the data stored. + */ +void +g_object_set_qdata (GObject *object, + GQuark quark, + gpointer data) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (quark > 0); + + g_datalist_id_set_data (&object->qdata, quark, data); +} + +/** + * g_object_dup_qdata: (skip) + * @object: the #GObject to store user data on + * @quark: a #GQuark, naming the user data pointer + * @dup_func: (nullable): function to dup the value + * @user_data: (nullable): passed as user_data to @dup_func + * + * This is a variant of g_object_get_qdata() which returns + * a 'duplicate' of the value. @dup_func defines the + * meaning of 'duplicate' in this context, it could e.g. + * take a reference on a ref-counted object. + * + * If the @quark is not set on the object then @dup_func + * will be called with a %NULL argument. + * + * Note that @dup_func is called while user data of @object + * is locked. + * + * This function can be useful to avoid races when multiple + * threads are using object data on the same key on the same + * object. + * + * Returns: the result of calling @dup_func on the value + * associated with @quark on @object, or %NULL if not set. + * If @dup_func is %NULL, the value is returned + * unmodified. + * + * Since: 2.34 + */ +gpointer +g_object_dup_qdata (GObject *object, + GQuark quark, + GDuplicateFunc dup_func, + gpointer user_data) +{ + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (quark > 0, NULL); + + return g_datalist_id_dup_data (&object->qdata, quark, dup_func, user_data); +} + +/** + * g_object_replace_qdata: (skip) + * @object: the #GObject to store user data on + * @quark: a #GQuark, naming the user data pointer + * @oldval: (nullable): the old value to compare against + * @newval: (nullable): the new value + * @destroy: (nullable): a destroy notify for the new value + * @old_destroy: (out) (optional): destroy notify for the existing value + * + * Compares the user data for the key @quark on @object with + * @oldval, and if they are the same, replaces @oldval with + * @newval. + * + * This is like a typical atomic compare-and-exchange + * operation, for user data on an object. + * + * If the previous value was replaced then ownership of the + * old value (@oldval) is passed to the caller, including + * the registered destroy notify for it (passed out in @old_destroy). + * It’s up to the caller to free this as needed, which may + * or may not include using @old_destroy as sometimes replacement + * should not destroy the object in the normal way. + * + * Returns: %TRUE if the existing value for @quark was replaced + * by @newval, %FALSE otherwise. + * + * Since: 2.34 + */ +gboolean +g_object_replace_qdata (GObject *object, + GQuark quark, + gpointer oldval, + gpointer newval, + GDestroyNotify destroy, + GDestroyNotify *old_destroy) +{ + g_return_val_if_fail (G_IS_OBJECT (object), FALSE); + g_return_val_if_fail (quark > 0, FALSE); + + return g_datalist_id_replace_data (&object->qdata, quark, + oldval, newval, destroy, + old_destroy); +} + +/** + * g_object_set_qdata_full: (skip) + * @object: The GObject to set store a user data pointer + * @quark: A #GQuark, naming the user data pointer + * @data: (nullable): An opaque user data pointer + * @destroy: (nullable): Function to invoke with @data as argument, when @data + * needs to be freed + * + * This function works like g_object_set_qdata(), but in addition, + * a void (*destroy) (gpointer) function may be specified which is + * called with @data as argument when the @object is finalized, or + * the data is being overwritten by a call to g_object_set_qdata() + * with the same @quark. + */ +void +g_object_set_qdata_full (GObject *object, + GQuark quark, + gpointer data, + GDestroyNotify destroy) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (quark > 0); + + g_datalist_id_set_data_full (&object->qdata, quark, data, + data ? destroy : (GDestroyNotify) NULL); +} + +/** + * g_object_steal_qdata: + * @object: The GObject to get a stored user data pointer from + * @quark: A #GQuark, naming the user data pointer + * + * This function gets back user data pointers stored via + * g_object_set_qdata() and removes the @data from object + * without invoking its destroy() function (if any was + * set). + * Usually, calling this function is only required to update + * user data pointers with a destroy notifier, for example: + * |[ + * void + * object_add_to_user_list (GObject *object, + * const gchar *new_string) + * { + * // the quark, naming the object data + * GQuark quark_string_list = g_quark_from_static_string ("my-string-list"); + * // retrieve the old string list + * GList *list = g_object_steal_qdata (object, quark_string_list); + * + * // prepend new string + * list = g_list_prepend (list, g_strdup (new_string)); + * // this changed 'list', so we need to set it again + * g_object_set_qdata_full (object, quark_string_list, list, free_string_list); + * } + * static void + * free_string_list (gpointer data) + * { + * GList *node, *list = data; + * + * for (node = list; node; node = node->next) + * g_free (node->data); + * g_list_free (list); + * } + * ]| + * Using g_object_get_qdata() in the above example, instead of + * g_object_steal_qdata() would have left the destroy function set, + * and thus the partial string list would have been freed upon + * g_object_set_qdata_full(). + * + * Returns: (transfer full) (nullable): The user data pointer set, or %NULL + */ +gpointer +g_object_steal_qdata (GObject *object, + GQuark quark) +{ + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (quark > 0, NULL); + + return g_datalist_id_remove_no_notify (&object->qdata, quark); +} + +/** + * g_object_get_data: + * @object: #GObject containing the associations + * @key: name of the key for that association + * + * Gets a named field from the objects table of associations (see g_object_set_data()). + * + * Returns: (transfer none) (nullable): the data if found, + * or %NULL if no such data exists. + */ +gpointer +g_object_get_data (GObject *object, + const gchar *key) +{ + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (key != NULL, NULL); + + return g_datalist_get_data (&object->qdata, key); +} + +/** + * g_object_set_data: + * @object: #GObject containing the associations. + * @key: name of the key + * @data: (nullable): data to associate with that key + * + * Each object carries around a table of associations from + * strings to pointers. This function lets you set an association. + * + * If the object already had an association with that name, + * the old association will be destroyed. + * + * Internally, the @key is converted to a #GQuark using g_quark_from_string(). + * This means a copy of @key is kept permanently (even after @object has been + * finalized) — so it is recommended to only use a small, bounded set of values + * for @key in your program, to avoid the #GQuark storage growing unbounded. + */ +void +g_object_set_data (GObject *object, + const gchar *key, + gpointer data) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (key != NULL); + + g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data); +} + +/** + * g_object_dup_data: (skip) + * @object: the #GObject to store user data on + * @key: a string, naming the user data pointer + * @dup_func: (nullable): function to dup the value + * @user_data: (nullable): passed as user_data to @dup_func + * + * This is a variant of g_object_get_data() which returns + * a 'duplicate' of the value. @dup_func defines the + * meaning of 'duplicate' in this context, it could e.g. + * take a reference on a ref-counted object. + * + * If the @key is not set on the object then @dup_func + * will be called with a %NULL argument. + * + * Note that @dup_func is called while user data of @object + * is locked. + * + * This function can be useful to avoid races when multiple + * threads are using object data on the same key on the same + * object. + * + * Returns: the result of calling @dup_func on the value + * associated with @key on @object, or %NULL if not set. + * If @dup_func is %NULL, the value is returned + * unmodified. + * + * Since: 2.34 + */ +gpointer +g_object_dup_data (GObject *object, + const gchar *key, + GDuplicateFunc dup_func, + gpointer user_data) +{ + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (key != NULL, NULL); + + return g_datalist_id_dup_data (&object->qdata, + g_quark_from_string (key), + dup_func, user_data); +} + +/** + * g_object_replace_data: (skip) + * @object: the #GObject to store user data on + * @key: a string, naming the user data pointer + * @oldval: (nullable): the old value to compare against + * @newval: (nullable): the new value + * @destroy: (nullable): a destroy notify for the new value + * @old_destroy: (out) (optional): destroy notify for the existing value + * + * Compares the user data for the key @key on @object with + * @oldval, and if they are the same, replaces @oldval with + * @newval. + * + * This is like a typical atomic compare-and-exchange + * operation, for user data on an object. + * + * If the previous value was replaced then ownership of the + * old value (@oldval) is passed to the caller, including + * the registered destroy notify for it (passed out in @old_destroy). + * It’s up to the caller to free this as needed, which may + * or may not include using @old_destroy as sometimes replacement + * should not destroy the object in the normal way. + * + * See g_object_set_data() for guidance on using a small, bounded set of values + * for @key. + * + * Returns: %TRUE if the existing value for @key was replaced + * by @newval, %FALSE otherwise. + * + * Since: 2.34 + */ +gboolean +g_object_replace_data (GObject *object, + const gchar *key, + gpointer oldval, + gpointer newval, + GDestroyNotify destroy, + GDestroyNotify *old_destroy) +{ + g_return_val_if_fail (G_IS_OBJECT (object), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + return g_datalist_id_replace_data (&object->qdata, + g_quark_from_string (key), + oldval, newval, destroy, + old_destroy); +} + +/** + * g_object_set_data_full: (skip) + * @object: #GObject containing the associations + * @key: name of the key + * @data: (nullable): data to associate with that key + * @destroy: (nullable): function to call when the association is destroyed + * + * Like g_object_set_data() except it adds notification + * for when the association is destroyed, either by setting it + * to a different value or when the object is destroyed. + * + * Note that the @destroy callback is not called if @data is %NULL. + */ +void +g_object_set_data_full (GObject *object, + const gchar *key, + gpointer data, + GDestroyNotify destroy) +{ + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (key != NULL); + + g_datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data, + data ? destroy : (GDestroyNotify) NULL); +} + +/** + * g_object_steal_data: + * @object: #GObject containing the associations + * @key: name of the key + * + * Remove a specified datum from the object's data associations, + * without invoking the association's destroy handler. + * + * Returns: (transfer full) (nullable): the data if found, or %NULL + * if no such data exists. + */ +gpointer +g_object_steal_data (GObject *object, + const gchar *key) +{ + GQuark quark; + + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (key != NULL, NULL); + + quark = g_quark_try_string (key); + + return quark ? g_datalist_id_remove_no_notify (&object->qdata, quark) : NULL; +} + +static void +g_value_object_init (GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static void +g_value_object_free_value (GValue *value) +{ + if (value->data[0].v_pointer) + g_object_unref (value->data[0].v_pointer); +} + +static void +g_value_object_copy_value (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[0].v_pointer) + dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer); + else + dest_value->data[0].v_pointer = NULL; +} + +static void +g_value_object_transform_value (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[0].v_pointer && g_type_is_a (G_OBJECT_TYPE (src_value->data[0].v_pointer), G_VALUE_TYPE (dest_value))) + dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer); + else + dest_value->data[0].v_pointer = NULL; +} + +static gpointer +g_value_object_peek_pointer (const GValue *value) +{ + return value->data[0].v_pointer; +} + +static gchar* +g_value_object_collect_value (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + if (collect_values[0].v_pointer) + { + GObject *object = collect_values[0].v_pointer; + + if (object->g_type_instance.g_class == NULL) + return g_strconcat ("invalid unclassed object pointer for value type '", + G_VALUE_TYPE_NAME (value), + "'", + NULL); + else if (!g_value_type_compatible (G_OBJECT_TYPE (object), G_VALUE_TYPE (value))) + return g_strconcat ("invalid object type '", + G_OBJECT_TYPE_NAME (object), + "' for value type '", + G_VALUE_TYPE_NAME (value), + "'", + NULL); + /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */ + value->data[0].v_pointer = g_object_ref (object); + } + else + value->data[0].v_pointer = NULL; + + return NULL; +} + +static gchar* +g_value_object_lcopy_value (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + GObject **object_p = collect_values[0].v_pointer; + + g_return_val_if_fail (object_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + if (!value->data[0].v_pointer) + *object_p = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + *object_p = value->data[0].v_pointer; + else + *object_p = g_object_ref (value->data[0].v_pointer); + + return NULL; +} + +/** + * g_value_set_object: + * @value: a valid #GValue of %G_TYPE_OBJECT derived type + * @v_object: (type GObject.Object) (nullable): object value to be set + * + * Set the contents of a %G_TYPE_OBJECT derived #GValue to @v_object. + * + * g_value_set_object() increases the reference count of @v_object + * (the #GValue holds a reference to @v_object). If you do not wish + * to increase the reference count of the object (i.e. you wish to + * pass your current reference to the #GValue because you no longer + * need it), use g_value_take_object() instead. + * + * It is important that your #GValue holds a reference to @v_object (either its + * own, or one it has taken) to ensure that the object won't be destroyed while + * the #GValue still exists). + */ +void +g_value_set_object (GValue *value, + gpointer v_object) +{ + GObject *old; + + g_return_if_fail (G_VALUE_HOLDS_OBJECT (value)); + + old = value->data[0].v_pointer; + + if (v_object) + { + g_return_if_fail (G_IS_OBJECT (v_object)); + g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value))); + + value->data[0].v_pointer = v_object; + g_object_ref (value->data[0].v_pointer); + } + else + value->data[0].v_pointer = NULL; + + if (old) + g_object_unref (old); +} + +/** + * g_value_set_object_take_ownership: (skip) + * @value: a valid #GValue of %G_TYPE_OBJECT derived type + * @v_object: (nullable): object value to be set + * + * This is an internal function introduced mainly for C marshallers. + * + * Deprecated: 2.4: Use g_value_take_object() instead. + */ +void +g_value_set_object_take_ownership (GValue *value, + gpointer v_object) +{ + g_value_take_object (value, v_object); +} + +/** + * g_value_take_object: (skip) + * @value: a valid #GValue of %G_TYPE_OBJECT derived type + * @v_object: (nullable): object value to be set + * + * Sets the contents of a %G_TYPE_OBJECT derived #GValue to @v_object + * and takes over the ownership of the caller’s reference to @v_object; + * the caller doesn’t have to unref it any more (i.e. the reference + * count of the object is not increased). + * + * If you want the #GValue to hold its own reference to @v_object, use + * g_value_set_object() instead. + * + * Since: 2.4 + */ +void +g_value_take_object (GValue *value, + gpointer v_object) +{ + g_return_if_fail (G_VALUE_HOLDS_OBJECT (value)); + + if (value->data[0].v_pointer) + { + g_object_unref (value->data[0].v_pointer); + value->data[0].v_pointer = NULL; + } + + if (v_object) + { + g_return_if_fail (G_IS_OBJECT (v_object)); + g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value))); + + value->data[0].v_pointer = v_object; /* we take over the reference count */ + } +} + +/** + * g_value_get_object: + * @value: a valid #GValue of %G_TYPE_OBJECT derived type + * + * Get the contents of a %G_TYPE_OBJECT derived #GValue. + * + * Returns: (type GObject.Object) (transfer none): object contents of @value + */ +gpointer +g_value_get_object (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL); + + return value->data[0].v_pointer; +} + +/** + * g_value_dup_object: + * @value: a valid #GValue whose type is derived from %G_TYPE_OBJECT + * + * Get the contents of a %G_TYPE_OBJECT derived #GValue, increasing + * its reference count. If the contents of the #GValue are %NULL, then + * %NULL will be returned. + * + * Returns: (type GObject.Object) (transfer full): object content of @value, + * should be unreferenced when no longer needed. + */ +gpointer +g_value_dup_object (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL); + + return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL; +} + +/** + * g_signal_connect_object: (skip) + * @instance: (type GObject.TypeInstance): the instance to connect to. + * @detailed_signal: a string of the form "signal-name::detail". + * @c_handler: the #GCallback to connect. + * @gobject: (type GObject.Object) (nullable): the object to pass as data + * to @c_handler. + * @connect_flags: a combination of #GConnectFlags. + * + * This is similar to g_signal_connect_data(), but uses a closure which + * ensures that the @gobject stays alive during the call to @c_handler + * by temporarily adding a reference count to @gobject. + * + * When the @gobject is destroyed the signal handler will be automatically + * disconnected. Note that this is not currently threadsafe (ie: + * emitting a signal while @gobject is being destroyed in another thread + * is not safe). + * + * Returns: the handler id. + */ +gulong +g_signal_connect_object (gpointer instance, + const gchar *detailed_signal, + GCallback c_handler, + gpointer gobject, + GConnectFlags connect_flags) +{ + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail (detailed_signal != NULL, 0); + g_return_val_if_fail (c_handler != NULL, 0); + + if (gobject) + { + GClosure *closure; + + g_return_val_if_fail (G_IS_OBJECT (gobject), 0); + + closure = ((connect_flags & G_CONNECT_SWAPPED) ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, gobject); + + return g_signal_connect_closure (instance, detailed_signal, closure, connect_flags & G_CONNECT_AFTER); + } + else + return g_signal_connect_data (instance, detailed_signal, c_handler, NULL, NULL, connect_flags); +} + +typedef struct { + GObject *object; + guint n_closures; + GClosure *closures[1]; /* flexible array */ +} CArray; +/* don't change this structure without supplying an accessor for + * watched closures, e.g.: + * GSList* g_object_list_watched_closures (GObject *object) + * { + * CArray *carray; + * g_return_val_if_fail (G_IS_OBJECT (object), NULL); + * carray = g_object_get_data (object, "GObject-closure-array"); + * if (carray) + * { + * GSList *slist = NULL; + * guint i; + * for (i = 0; i < carray->n_closures; i++) + * slist = g_slist_prepend (slist, carray->closures[i]); + * return slist; + * } + * return NULL; + * } + */ + +static void +object_remove_closure (gpointer data, + GClosure *closure) +{ + GObject *object = data; + CArray *carray; + guint i; + + G_LOCK (closure_array_mutex); + carray = g_object_get_qdata (object, quark_closure_array); + for (i = 0; i < carray->n_closures; i++) + if (carray->closures[i] == closure) + { + carray->n_closures--; + if (i < carray->n_closures) + carray->closures[i] = carray->closures[carray->n_closures]; + G_UNLOCK (closure_array_mutex); + return; + } + G_UNLOCK (closure_array_mutex); + g_assert_not_reached (); +} + +static void +destroy_closure_array (gpointer data) +{ + CArray *carray = data; + GObject *object = carray->object; + guint i, n = carray->n_closures; + + for (i = 0; i < n; i++) + { + GClosure *closure = carray->closures[i]; + + /* removing object_remove_closure() upfront is probably faster than + * letting it fiddle with quark_closure_array which is empty anyways + */ + g_closure_remove_invalidate_notifier (closure, object, object_remove_closure); + g_closure_invalidate (closure); + } + g_free (carray); +} + +/** + * g_object_watch_closure: + * @object: #GObject restricting lifetime of @closure + * @closure: #GClosure to watch + * + * This function essentially limits the life time of the @closure to + * the life time of the object. That is, when the object is finalized, + * the @closure is invalidated by calling g_closure_invalidate() on + * it, in order to prevent invocations of the closure with a finalized + * (nonexisting) object. Also, g_object_ref() and g_object_unref() are + * added as marshal guards to the @closure, to ensure that an extra + * reference count is held on @object during invocation of the + * @closure. Usually, this function will be called on closures that + * use this @object as closure data. + */ +void +g_object_watch_closure (GObject *object, + GClosure *closure) +{ + CArray *carray; + guint i; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (closure != NULL); + g_return_if_fail (closure->is_invalid == FALSE); + g_return_if_fail (closure->in_marshal == FALSE); + g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0); /* this doesn't work on finalizing objects */ + + g_closure_add_invalidate_notifier (closure, object, object_remove_closure); + g_closure_add_marshal_guards (closure, + object, (GClosureNotify) g_object_ref, + object, (GClosureNotify) g_object_unref); + G_LOCK (closure_array_mutex); + carray = g_datalist_id_remove_no_notify (&object->qdata, quark_closure_array); + if (!carray) + { + carray = g_renew (CArray, NULL, 1); + carray->object = object; + carray->n_closures = 1; + i = 0; + } + else + { + i = carray->n_closures++; + carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i); + } + carray->closures[i] = closure; + g_datalist_id_set_data_full (&object->qdata, quark_closure_array, carray, destroy_closure_array); + G_UNLOCK (closure_array_mutex); +} + +/** + * g_closure_new_object: + * @sizeof_closure: the size of the structure to allocate, must be at least + * `sizeof (GClosure)` + * @object: a #GObject pointer to store in the @data field of the newly + * allocated #GClosure + * + * A variant of g_closure_new_simple() which stores @object in the + * @data field of the closure and calls g_object_watch_closure() on + * @object and the created closure. This function is mainly useful + * when implementing new types of closures. + * + * Returns: (transfer floating): a newly allocated #GClosure + */ +GClosure * +g_closure_new_object (guint sizeof_closure, + GObject *object) +{ + GClosure *closure; + + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */ + + closure = g_closure_new_simple (sizeof_closure, object); + g_object_watch_closure (object, closure); + + return closure; +} + +/** + * g_cclosure_new_object: (skip) + * @callback_func: the function to invoke + * @object: a #GObject pointer to pass to @callback_func + * + * A variant of g_cclosure_new() which uses @object as @user_data and + * calls g_object_watch_closure() on @object and the created + * closure. This function is useful when you have a callback closely + * associated with a #GObject, and want the callback to no longer run + * after the object is is freed. + * + * Returns: (transfer floating): a new #GCClosure + */ +GClosure * +g_cclosure_new_object (GCallback callback_func, + GObject *object) +{ + GClosure *closure; + + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */ + g_return_val_if_fail (callback_func != NULL, NULL); + + closure = g_cclosure_new (callback_func, object, NULL); + g_object_watch_closure (object, closure); + + return closure; +} + +/** + * g_cclosure_new_object_swap: (skip) + * @callback_func: the function to invoke + * @object: a #GObject pointer to pass to @callback_func + * + * A variant of g_cclosure_new_swap() which uses @object as @user_data + * and calls g_object_watch_closure() on @object and the created + * closure. This function is useful when you have a callback closely + * associated with a #GObject, and want the callback to no longer run + * after the object is is freed. + * + * Returns: (transfer floating): a new #GCClosure + */ +GClosure * +g_cclosure_new_object_swap (GCallback callback_func, + GObject *object) +{ + GClosure *closure; + + g_return_val_if_fail (G_IS_OBJECT (object), NULL); + g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */ + g_return_val_if_fail (callback_func != NULL, NULL); + + closure = g_cclosure_new_swap (callback_func, object, NULL); + g_object_watch_closure (object, closure); + + return closure; +} + +gsize +g_object_compat_control (gsize what, + gpointer data) +{ + switch (what) + { + gpointer *pp; + case 1: /* floating base type */ + return G_TYPE_INITIALLY_UNOWNED; + case 2: /* FIXME: remove this once GLib/Gtk+ break ABI again */ + floating_flag_handler = (guint(*)(GObject*,gint)) data; + return 1; + case 3: /* FIXME: remove this once GLib/Gtk+ break ABI again */ + pp = data; + *pp = floating_flag_handler; + return 1; + default: + return 0; + } +} + +G_DEFINE_TYPE (GInitiallyUnowned, g_initially_unowned, G_TYPE_OBJECT) + +static void +g_initially_unowned_init (GInitiallyUnowned *object) +{ + g_object_force_floating (object); +} + +static void +g_initially_unowned_class_init (GInitiallyUnownedClass *klass) +{ +} + +/** + * GWeakRef: + * + * A structure containing a weak reference to a #GObject. + * + * A `GWeakRef` can either be empty (i.e. point to %NULL), or point to an + * object for as long as at least one "strong" reference to that object + * exists. Before the object's #GObjectClass.dispose method is called, + * every #GWeakRef associated with becomes empty (i.e. points to %NULL). + * + * Like #GValue, #GWeakRef can be statically allocated, stack- or + * heap-allocated, or embedded in larger structures. + * + * Unlike g_object_weak_ref() and g_object_add_weak_pointer(), this weak + * reference is thread-safe: converting a weak pointer to a reference is + * atomic with respect to invalidation of weak pointers to destroyed + * objects. + * + * If the object's #GObjectClass.dispose method results in additional + * references to the object being held (‘re-referencing’), any #GWeakRefs taken + * before it was disposed will continue to point to %NULL. Any #GWeakRefs taken + * during disposal and after re-referencing, or after disposal has returned due + * to the re-referencing, will continue to point to the object until its refcount + * goes back to zero, at which point they too will be invalidated. + * + * It is invalid to take a #GWeakRef on an object during #GObjectClass.dispose + * without first having or creating a strong reference to the object. + */ + +/** + * g_weak_ref_init: (skip) + * @weak_ref: (inout): uninitialized or empty location for a weak + * reference + * @object: (type GObject.Object) (nullable): a #GObject or %NULL + * + * Initialise a non-statically-allocated #GWeakRef. + * + * This function also calls g_weak_ref_set() with @object on the + * freshly-initialised weak reference. + * + * This function should always be matched with a call to + * g_weak_ref_clear(). It is not necessary to use this function for a + * #GWeakRef in static storage because it will already be + * properly initialised. Just use g_weak_ref_set() directly. + * + * Since: 2.32 + */ +void +g_weak_ref_init (GWeakRef *weak_ref, + gpointer object) +{ + weak_ref->priv.p = NULL; + + g_weak_ref_set (weak_ref, object); +} + +/** + * g_weak_ref_clear: (skip) + * @weak_ref: (inout): location of a weak reference, which + * may be empty + * + * Frees resources associated with a non-statically-allocated #GWeakRef. + * After this call, the #GWeakRef is left in an undefined state. + * + * You should only call this on a #GWeakRef that previously had + * g_weak_ref_init() called on it. + * + * Since: 2.32 + */ +void +g_weak_ref_clear (GWeakRef *weak_ref) +{ + g_weak_ref_set (weak_ref, NULL); + + /* be unkind */ + weak_ref->priv.p = (void *) 0xccccccccu; +} + +/** + * g_weak_ref_get: (skip) + * @weak_ref: (inout): location of a weak reference to a #GObject + * + * If @weak_ref is not empty, atomically acquire a strong + * reference to the object it points to, and return that reference. + * + * This function is needed because of the potential race between taking + * the pointer value and g_object_ref() on it, if the object was losing + * its last reference at the same time in a different thread. + * + * The caller should release the resulting reference in the usual way, + * by using g_object_unref(). + * + * Returns: (transfer full) (type GObject.Object): the object pointed to + * by @weak_ref, or %NULL if it was empty + * + * Since: 2.32 + */ +gpointer +g_weak_ref_get (GWeakRef *weak_ref) +{ + gpointer object_or_null; + + g_return_val_if_fail (weak_ref!= NULL, NULL); + + g_rw_lock_reader_lock (&weak_locations_lock); + + object_or_null = weak_ref->priv.p; + + if (object_or_null != NULL) + g_object_ref (object_or_null); + + g_rw_lock_reader_unlock (&weak_locations_lock); + + return object_or_null; +} + +static void +weak_locations_free_unlocked (GSList **weak_locations) +{ + if (*weak_locations) + { + GSList *weak_location; + + for (weak_location = *weak_locations; weak_location;) + { + GWeakRef *weak_ref_location = weak_location->data; + + weak_ref_location->priv.p = NULL; + weak_location = g_slist_delete_link (weak_location, weak_location); + } + } + + g_free (weak_locations); +} + +static void +weak_locations_free (gpointer data) +{ + GSList **weak_locations = data; + + g_rw_lock_writer_lock (&weak_locations_lock); + weak_locations_free_unlocked (weak_locations); + g_rw_lock_writer_unlock (&weak_locations_lock); +} + +/** + * g_weak_ref_set: (skip) + * @weak_ref: location for a weak reference + * @object: (type GObject.Object) (nullable): a #GObject or %NULL + * + * Change the object to which @weak_ref points, or set it to + * %NULL. + * + * You must own a strong reference on @object while calling this + * function. + * + * Since: 2.32 + */ +void +g_weak_ref_set (GWeakRef *weak_ref, + gpointer object) +{ + GSList **weak_locations; + GObject *new_object; + GObject *old_object; + + g_return_if_fail (weak_ref != NULL); + g_return_if_fail (object == NULL || G_IS_OBJECT (object)); + + new_object = object; + + g_rw_lock_writer_lock (&weak_locations_lock); + + /* We use the extra level of indirection here so that if we have ever + * had a weak pointer installed at any point in time on this object, + * we can see that there is a non-NULL value associated with the + * weak-pointer quark and know that this value will not change at any + * point in the object's lifetime. + * + * Both properties are important for reducing the amount of times we + * need to acquire locks and for decreasing the duration of time the + * lock is held while avoiding some rather tricky races. + * + * Specifically: we can avoid having to do an extra unconditional lock + * in g_object_unref() without worrying about some extremely tricky + * races. + */ + + old_object = weak_ref->priv.p; + if (new_object != old_object) + { + weak_ref->priv.p = new_object; + + /* Remove the weak ref from the old object */ + if (old_object != NULL) + { + weak_locations = g_datalist_id_get_data (&old_object->qdata, quark_weak_locations); + /* for it to point to an object, the object must have had it added once */ + g_assert (weak_locations != NULL); + + *weak_locations = g_slist_remove (*weak_locations, weak_ref); + + if (!*weak_locations) + { + weak_locations_free_unlocked (weak_locations); + g_datalist_id_remove_no_notify (&old_object->qdata, quark_weak_locations); + } + } + + /* Add the weak ref to the new object */ + if (new_object != NULL) + { + weak_locations = g_datalist_id_get_data (&new_object->qdata, quark_weak_locations); + + if (weak_locations == NULL) + { + weak_locations = g_new0 (GSList *, 1); + g_datalist_id_set_data_full (&new_object->qdata, quark_weak_locations, + weak_locations, weak_locations_free); + } + + *weak_locations = g_slist_prepend (*weak_locations, weak_ref); + } + } + + g_rw_lock_writer_unlock (&weak_locations_lock); +} diff --git a/gobject/gobject.h b/gobject/gobject.h new file mode 100644 index 0000000..3dc4f7f --- /dev/null +++ b/gobject/gobject.h @@ -0,0 +1,946 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_OBJECT_H__ +#define __G_OBJECT_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +/* --- type macros --- */ +/** + * G_TYPE_IS_OBJECT: + * @type: Type id to check + * + * Check if the passed in type id is a %G_TYPE_OBJECT or derived from it. + * + * Returns: %FALSE or %TRUE, indicating whether @type is a %G_TYPE_OBJECT. + */ +#define G_TYPE_IS_OBJECT(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_OBJECT) +/** + * G_OBJECT: + * @object: Object which is subject to casting. + * + * Casts a #GObject or derived pointer into a (GObject*) pointer. + * + * Depending on the current debugging level, this function may invoke + * certain runtime checks to identify invalid casts. + */ +#define G_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_OBJECT, GObject)) +/** + * G_OBJECT_CLASS: + * @class: a valid #GObjectClass + * + * Casts a derived #GObjectClass structure into a #GObjectClass structure. + */ +#define G_OBJECT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_OBJECT, GObjectClass)) +/** + * G_IS_OBJECT: + * @object: Instance to check for being a %G_TYPE_OBJECT. + * + * Checks whether a valid #GTypeInstance pointer is of type %G_TYPE_OBJECT. + */ +#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_42 +#define G_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE ((object), G_TYPE_OBJECT)) +#else +#define G_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_OBJECT)) +#endif +/** + * G_IS_OBJECT_CLASS: + * @class: a #GObjectClass + * + * Checks whether @class "is a" valid #GObjectClass structure of type + * %G_TYPE_OBJECT or derived. + */ +#define G_IS_OBJECT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_OBJECT)) +/** + * G_OBJECT_GET_CLASS: + * @object: a #GObject instance. + * + * Get the class structure associated to a #GObject instance. + * + * Returns: pointer to object class structure. + */ +#define G_OBJECT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), G_TYPE_OBJECT, GObjectClass)) +/** + * G_OBJECT_TYPE: + * @object: Object to return the type id for. + * + * Get the type id of an object. + * + * Returns: Type id of @object. + */ +#define G_OBJECT_TYPE(object) (G_TYPE_FROM_INSTANCE (object)) +/** + * G_OBJECT_TYPE_NAME: + * @object: Object to return the type name for. + * + * Get the name of an object's type. + * + * Returns: Type name of @object. The string is owned by the type system and + * should not be freed. + */ +#define G_OBJECT_TYPE_NAME(object) (g_type_name (G_OBJECT_TYPE (object))) +/** + * G_OBJECT_CLASS_TYPE: + * @class: a valid #GObjectClass + * + * Get the type id of a class structure. + * + * Returns: Type id of @class. + */ +#define G_OBJECT_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +/** + * G_OBJECT_CLASS_NAME: + * @class: a valid #GObjectClass + * + * Return the name of a class structure's type. + * + * Returns: Type name of @class. The string is owned by the type system and + * should not be freed. + */ +#define G_OBJECT_CLASS_NAME(class) (g_type_name (G_OBJECT_CLASS_TYPE (class))) +/** + * G_VALUE_HOLDS_OBJECT: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values derived from type %G_TYPE_OBJECT. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_OBJECT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_OBJECT)) + +/* --- type macros --- */ +/** + * G_TYPE_INITIALLY_UNOWNED: + * + * The type for #GInitiallyUnowned. + */ +#define G_TYPE_INITIALLY_UNOWNED (g_initially_unowned_get_type()) +/** + * G_INITIALLY_UNOWNED: + * @object: Object which is subject to casting. + * + * Casts a #GInitiallyUnowned or derived pointer into a (GInitiallyUnowned*) + * pointer. + * + * Depending on the current debugging level, this function may invoke + * certain runtime checks to identify invalid casts. + */ +#define G_INITIALLY_UNOWNED(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_INITIALLY_UNOWNED, GInitiallyUnowned)) +/** + * G_INITIALLY_UNOWNED_CLASS: + * @class: a valid #GInitiallyUnownedClass + * + * Casts a derived #GInitiallyUnownedClass structure into a + * #GInitiallyUnownedClass structure. + */ +#define G_INITIALLY_UNOWNED_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_INITIALLY_UNOWNED, GInitiallyUnownedClass)) +/** + * G_IS_INITIALLY_UNOWNED: + * @object: Instance to check for being a %G_TYPE_INITIALLY_UNOWNED. + * + * Checks whether a valid #GTypeInstance pointer is of type %G_TYPE_INITIALLY_UNOWNED. + */ +#define G_IS_INITIALLY_UNOWNED(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_INITIALLY_UNOWNED)) +/** + * G_IS_INITIALLY_UNOWNED_CLASS: + * @class: a #GInitiallyUnownedClass + * + * Checks whether @class "is a" valid #GInitiallyUnownedClass structure of type + * %G_TYPE_INITIALLY_UNOWNED or derived. + */ +#define G_IS_INITIALLY_UNOWNED_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_INITIALLY_UNOWNED)) +/** + * G_INITIALLY_UNOWNED_GET_CLASS: + * @object: a #GInitiallyUnowned instance. + * + * Get the class structure associated to a #GInitiallyUnowned instance. + * + * Returns: pointer to object class structure. + */ +#define G_INITIALLY_UNOWNED_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), G_TYPE_INITIALLY_UNOWNED, GInitiallyUnownedClass)) +/* GInitiallyUnowned ia a GObject with initially floating reference count */ + + +/* --- typedefs & structures --- */ +typedef struct _GObject GObject; +typedef struct _GObjectClass GObjectClass; +typedef struct _GObject GInitiallyUnowned; +typedef struct _GObjectClass GInitiallyUnownedClass; +typedef struct _GObjectConstructParam GObjectConstructParam; +/** + * GObjectGetPropertyFunc: + * @object: a #GObject + * @property_id: the numeric id under which the property was registered with + * g_object_class_install_property(). + * @value: a #GValue to return the property value in + * @pspec: the #GParamSpec describing the property + * + * The type of the @get_property function of #GObjectClass. + */ +typedef void (*GObjectGetPropertyFunc) (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +/** + * GObjectSetPropertyFunc: + * @object: a #GObject + * @property_id: the numeric id under which the property was registered with + * g_object_class_install_property(). + * @value: the new value for the property + * @pspec: the #GParamSpec describing the property + * + * The type of the @set_property function of #GObjectClass. + */ +typedef void (*GObjectSetPropertyFunc) (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +/** + * GObjectFinalizeFunc: + * @object: the #GObject being finalized + * + * The type of the @finalize function of #GObjectClass. + */ +typedef void (*GObjectFinalizeFunc) (GObject *object); +/** + * GWeakNotify: + * @data: data that was provided when the weak reference was established + * @where_the_object_was: the object being disposed + * + * A #GWeakNotify function can be added to an object as a callback that gets + * triggered when the object is finalized. + * + * Since the object is already being disposed when the #GWeakNotify is called, + * there's not much you could do with the object, apart from e.g. using its + * address as hash-index or the like. + * + * In particular, this means it’s invalid to call g_object_ref(), + * g_weak_ref_init(), g_weak_ref_set(), g_object_add_toggle_ref(), + * g_object_weak_ref(), g_object_add_weak_pointer() or any function which calls + * them on the object from this callback. + */ +typedef void (*GWeakNotify) (gpointer data, + GObject *where_the_object_was); +/** + * GObject: + * + * The base object type. + * + * All the fields in the `GObject` structure are private to the implementation + * and should never be accessed directly. + * + * Since GLib 2.72, all #GObjects are guaranteed to be aligned to at least the + * alignment of the largest basic GLib type (typically this is #guint64 or + * #gdouble). If you need larger alignment for an element in a #GObject, you + * should allocate it on the heap (aligned), or arrange for your #GObject to be + * appropriately padded. This guarantee applies to the #GObject (or derived) + * struct, the #GObjectClass (or derived) struct, and any private data allocated + * by G_ADD_PRIVATE(). + */ +struct _GObject +{ + GTypeInstance g_type_instance; + + /*< private >*/ + guint ref_count; /* (atomic) */ + GData *qdata; +}; +/** + * GObjectClass: + * @g_type_class: the parent class + * @constructor: the @constructor function is called by g_object_new () to + * complete the object initialization after all the construction properties are + * set. The first thing a @constructor implementation must do is chain up to the + * @constructor of the parent class. Overriding @constructor should be rarely + * needed, e.g. to handle construct properties, or to implement singletons. + * @set_property: the generic setter for all properties of this type. Should be + * overridden for every type with properties. If implementations of + * @set_property don't emit property change notification explicitly, this will + * be done implicitly by the type system. However, if the notify signal is + * emitted explicitly, the type system will not emit it a second time. + * @get_property: the generic getter for all properties of this type. Should be + * overridden for every type with properties. + * @dispose: the @dispose function is supposed to drop all references to other + * objects, but keep the instance otherwise intact, so that client method + * invocations still work. It may be run multiple times (due to reference + * loops). Before returning, @dispose should chain up to the @dispose method + * of the parent class. + * @finalize: instance finalization function, should finish the finalization of + * the instance begun in @dispose and chain up to the @finalize method of the + * parent class. + * @dispatch_properties_changed: emits property change notification for a bunch + * of properties. Overriding @dispatch_properties_changed should be rarely + * needed. + * @notify: the class closure for the notify signal + * @constructed: the @constructed function is called by g_object_new() as the + * final step of the object creation process. At the point of the call, all + * construction properties have been set on the object. The purpose of this + * call is to allow for object initialisation steps that can only be performed + * after construction properties have been set. @constructed implementors + * should chain up to the @constructed call of their parent class to allow it + * to complete its initialisation. + * + * The class structure for the GObject type. + * + * |[ + * // Example of implementing a singleton using a constructor. + * static MySingleton *the_singleton = NULL; + * + * static GObject* + * my_singleton_constructor (GType type, + * guint n_construct_params, + * GObjectConstructParam *construct_params) + * { + * GObject *object; + * + * if (!the_singleton) + * { + * object = G_OBJECT_CLASS (parent_class)->constructor (type, + * n_construct_params, + * construct_params); + * the_singleton = MY_SINGLETON (object); + * } + * else + * object = g_object_ref (G_OBJECT (the_singleton)); + * + * return object; + * } + * ]| + */ +struct _GObjectClass +{ + GTypeClass g_type_class; + + /*< private >*/ + GSList *construct_properties; + + /*< public >*/ + /* seldom overridden */ + GObject* (*constructor) (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties); + /* overridable methods */ + void (*set_property) (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); + void (*get_property) (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + void (*dispose) (GObject *object); + void (*finalize) (GObject *object); + /* seldom overridden */ + void (*dispatch_properties_changed) (GObject *object, + guint n_pspecs, + GParamSpec **pspecs); + /* signals */ + void (*notify) (GObject *object, + GParamSpec *pspec); + + /* called when done constructing */ + void (*constructed) (GObject *object); + + /*< private >*/ + gsize flags; + + /* padding */ + gpointer pdummy[6]; +}; + +/** + * GObjectConstructParam: + * @pspec: the #GParamSpec of the construct parameter + * @value: the value to set the parameter to + * + * The GObjectConstructParam struct is an auxiliary structure used to hand + * #GParamSpec/#GValue pairs to the @constructor of a #GObjectClass. + */ +struct _GObjectConstructParam +{ + GParamSpec *pspec; + GValue *value; +}; + +/** + * GInitiallyUnowned: + * + * A type for objects that have an initially floating reference. + * + * All the fields in the `GInitiallyUnowned` structure are private to the + * implementation and should never be accessed directly. + */ +/** + * GInitiallyUnownedClass: + * + * The class structure for the GInitiallyUnowned type. + */ + + +/* --- prototypes --- */ +GLIB_AVAILABLE_IN_ALL +GType g_initially_unowned_get_type (void); +GLIB_AVAILABLE_IN_ALL +void g_object_class_install_property (GObjectClass *oclass, + guint property_id, + GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_object_class_find_property (GObjectClass *oclass, + const gchar *property_name); +GLIB_AVAILABLE_IN_ALL +GParamSpec**g_object_class_list_properties (GObjectClass *oclass, + guint *n_properties); +GLIB_AVAILABLE_IN_ALL +void g_object_class_override_property (GObjectClass *oclass, + guint property_id, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +void g_object_class_install_properties (GObjectClass *oclass, + guint n_pspecs, + GParamSpec **pspecs); + +GLIB_AVAILABLE_IN_ALL +void g_object_interface_install_property (gpointer g_iface, + GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_object_interface_find_property (gpointer g_iface, + const gchar *property_name); +GLIB_AVAILABLE_IN_ALL +GParamSpec**g_object_interface_list_properties (gpointer g_iface, + guint *n_properties_p); + +GLIB_AVAILABLE_IN_ALL +GType g_object_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gpointer g_object_new (GType object_type, + const gchar *first_property_name, + ...); +GLIB_AVAILABLE_IN_2_54 +GObject* g_object_new_with_properties (GType object_type, + guint n_properties, + const char *names[], + const GValue values[]); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +GLIB_DEPRECATED_IN_2_54_FOR(g_object_new_with_properties) +gpointer g_object_newv (GType object_type, + guint n_parameters, + GParameter *parameters); + +G_GNUC_END_IGNORE_DEPRECATIONS + +GLIB_AVAILABLE_IN_ALL +GObject* g_object_new_valist (GType object_type, + const gchar *first_property_name, + va_list var_args); +GLIB_AVAILABLE_IN_ALL +void g_object_set (gpointer object, + const gchar *first_property_name, + ...) G_GNUC_NULL_TERMINATED; +GLIB_AVAILABLE_IN_ALL +void g_object_get (gpointer object, + const gchar *first_property_name, + ...) G_GNUC_NULL_TERMINATED; +GLIB_AVAILABLE_IN_ALL +gpointer g_object_connect (gpointer object, + const gchar *signal_spec, + ...) G_GNUC_NULL_TERMINATED; +GLIB_AVAILABLE_IN_ALL +void g_object_disconnect (gpointer object, + const gchar *signal_spec, + ...) G_GNUC_NULL_TERMINATED; +GLIB_AVAILABLE_IN_2_54 +void g_object_setv (GObject *object, + guint n_properties, + const gchar *names[], + const GValue values[]); +GLIB_AVAILABLE_IN_ALL +void g_object_set_valist (GObject *object, + const gchar *first_property_name, + va_list var_args); +GLIB_AVAILABLE_IN_2_54 +void g_object_getv (GObject *object, + guint n_properties, + const gchar *names[], + GValue values[]); +GLIB_AVAILABLE_IN_ALL +void g_object_get_valist (GObject *object, + const gchar *first_property_name, + va_list var_args); +GLIB_AVAILABLE_IN_ALL +void g_object_set_property (GObject *object, + const gchar *property_name, + const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_object_get_property (GObject *object, + const gchar *property_name, + GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_object_freeze_notify (GObject *object); +GLIB_AVAILABLE_IN_ALL +void g_object_notify (GObject *object, + const gchar *property_name); +GLIB_AVAILABLE_IN_ALL +void g_object_notify_by_pspec (GObject *object, + GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +void g_object_thaw_notify (GObject *object); +GLIB_AVAILABLE_IN_ALL +gboolean g_object_is_floating (gpointer object); +GLIB_AVAILABLE_IN_ALL +gpointer g_object_ref_sink (gpointer object); +GLIB_AVAILABLE_IN_2_70 +gpointer g_object_take_ref (gpointer object); +GLIB_AVAILABLE_IN_ALL +gpointer g_object_ref (gpointer object); +GLIB_AVAILABLE_IN_ALL +void g_object_unref (gpointer object); +GLIB_AVAILABLE_IN_ALL +void g_object_weak_ref (GObject *object, + GWeakNotify notify, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_object_weak_unref (GObject *object, + GWeakNotify notify, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_object_add_weak_pointer (GObject *object, + gpointer *weak_pointer_location); +GLIB_AVAILABLE_IN_ALL +void g_object_remove_weak_pointer (GObject *object, + gpointer *weak_pointer_location); + +#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_56 +/* Make reference APIs type safe with macros */ +#define g_object_ref(Obj) ((glib_typeof (Obj)) (g_object_ref) (Obj)) +#define g_object_ref_sink(Obj) ((glib_typeof (Obj)) (g_object_ref_sink) (Obj)) +#endif + +/** + * GToggleNotify: + * @data: Callback data passed to g_object_add_toggle_ref() + * @object: The object on which g_object_add_toggle_ref() was called. + * @is_last_ref: %TRUE if the toggle reference is now the + * last reference to the object. %FALSE if the toggle + * reference was the last reference and there are now other + * references. + * + * A callback function used for notification when the state + * of a toggle reference changes. + * + * See also: g_object_add_toggle_ref() + */ +typedef void (*GToggleNotify) (gpointer data, + GObject *object, + gboolean is_last_ref); + +GLIB_AVAILABLE_IN_ALL +void g_object_add_toggle_ref (GObject *object, + GToggleNotify notify, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_object_remove_toggle_ref (GObject *object, + GToggleNotify notify, + gpointer data); + +GLIB_AVAILABLE_IN_ALL +gpointer g_object_get_qdata (GObject *object, + GQuark quark); +GLIB_AVAILABLE_IN_ALL +void g_object_set_qdata (GObject *object, + GQuark quark, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_object_set_qdata_full (GObject *object, + GQuark quark, + gpointer data, + GDestroyNotify destroy); +GLIB_AVAILABLE_IN_ALL +gpointer g_object_steal_qdata (GObject *object, + GQuark quark); + +GLIB_AVAILABLE_IN_2_34 +gpointer g_object_dup_qdata (GObject *object, + GQuark quark, + GDuplicateFunc dup_func, + gpointer user_data); +GLIB_AVAILABLE_IN_2_34 +gboolean g_object_replace_qdata (GObject *object, + GQuark quark, + gpointer oldval, + gpointer newval, + GDestroyNotify destroy, + GDestroyNotify *old_destroy); + +GLIB_AVAILABLE_IN_ALL +gpointer g_object_get_data (GObject *object, + const gchar *key); +GLIB_AVAILABLE_IN_ALL +void g_object_set_data (GObject *object, + const gchar *key, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_object_set_data_full (GObject *object, + const gchar *key, + gpointer data, + GDestroyNotify destroy); +GLIB_AVAILABLE_IN_ALL +gpointer g_object_steal_data (GObject *object, + const gchar *key); + +GLIB_AVAILABLE_IN_2_34 +gpointer g_object_dup_data (GObject *object, + const gchar *key, + GDuplicateFunc dup_func, + gpointer user_data); +GLIB_AVAILABLE_IN_2_34 +gboolean g_object_replace_data (GObject *object, + const gchar *key, + gpointer oldval, + gpointer newval, + GDestroyNotify destroy, + GDestroyNotify *old_destroy); + + +GLIB_AVAILABLE_IN_ALL +void g_object_watch_closure (GObject *object, + GClosure *closure); +GLIB_AVAILABLE_IN_ALL +GClosure* g_cclosure_new_object (GCallback callback_func, + GObject *object); +GLIB_AVAILABLE_IN_ALL +GClosure* g_cclosure_new_object_swap (GCallback callback_func, + GObject *object); +GLIB_AVAILABLE_IN_ALL +GClosure* g_closure_new_object (guint sizeof_closure, + GObject *object); +GLIB_AVAILABLE_IN_ALL +void g_value_set_object (GValue *value, + gpointer v_object); +GLIB_AVAILABLE_IN_ALL +gpointer g_value_get_object (const GValue *value); +GLIB_AVAILABLE_IN_ALL +gpointer g_value_dup_object (const GValue *value); +GLIB_AVAILABLE_IN_ALL +gulong g_signal_connect_object (gpointer instance, + const gchar *detailed_signal, + GCallback c_handler, + gpointer gobject, + GConnectFlags connect_flags); + +/*< protected >*/ +GLIB_AVAILABLE_IN_ALL +void g_object_force_floating (GObject *object); +GLIB_AVAILABLE_IN_ALL +void g_object_run_dispose (GObject *object); + + +GLIB_AVAILABLE_IN_ALL +void g_value_take_object (GValue *value, + gpointer v_object); +GLIB_DEPRECATED_FOR(g_value_take_object) +void g_value_set_object_take_ownership (GValue *value, + gpointer v_object); + +GLIB_DEPRECATED +gsize g_object_compat_control (gsize what, + gpointer data); + +/* --- implementation macros --- */ +#define G_OBJECT_WARN_INVALID_PSPEC(object, pname, property_id, pspec) \ +G_STMT_START { \ + GObject *_glib__object = (GObject*) (object); \ + GParamSpec *_glib__pspec = (GParamSpec*) (pspec); \ + guint _glib__property_id = (property_id); \ + g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'", \ + __FILE__, __LINE__, \ + (pname), \ + _glib__property_id, \ + _glib__pspec->name, \ + g_type_name (G_PARAM_SPEC_TYPE (_glib__pspec)), \ + G_OBJECT_TYPE_NAME (_glib__object)); \ +} G_STMT_END +/** + * G_OBJECT_WARN_INVALID_PROPERTY_ID: + * @object: the #GObject on which set_property() or get_property() was called + * @property_id: the numeric id of the property + * @pspec: the #GParamSpec of the property + * + * This macro should be used to emit a standard warning about unexpected + * properties in set_property() and get_property() implementations. + */ +#define G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec) \ + G_OBJECT_WARN_INVALID_PSPEC ((object), "property", (property_id), (pspec)) + +GLIB_AVAILABLE_IN_ALL +void g_clear_object (GObject **object_ptr); +#define g_clear_object(object_ptr) g_clear_pointer ((object_ptr), g_object_unref) + +/** + * g_set_object: (skip) + * @object_ptr: (inout) (not optional) (nullable): a pointer to a #GObject reference + * @new_object: (nullable) (transfer none): a pointer to the new #GObject to + * assign to @object_ptr, or %NULL to clear the pointer + * + * Updates a #GObject pointer to refer to @new_object. + * + * It increments the reference count of @new_object (if non-%NULL), decrements + * the reference count of the current value of @object_ptr (if non-%NULL), and + * assigns @new_object to @object_ptr. The assignment is not atomic. + * + * @object_ptr must not be %NULL, but can point to a %NULL value. + * + * A macro is also included that allows this function to be used without + * pointer casts. The function itself is static inline, so its address may vary + * between compilation units. + * + * One convenient usage of this function is in implementing property setters: + * |[ + * void + * foo_set_bar (Foo *foo, + * Bar *new_bar) + * { + * g_return_if_fail (IS_FOO (foo)); + * g_return_if_fail (new_bar == NULL || IS_BAR (new_bar)); + * + * if (g_set_object (&foo->bar, new_bar)) + * g_object_notify (foo, "bar"); + * } + * ]| + * + * Returns: %TRUE if the value of @object_ptr changed, %FALSE otherwise + * + * Since: 2.44 + */ +static inline gboolean +(g_set_object) (GObject **object_ptr, + GObject *new_object) +{ + GObject *old_object = *object_ptr; + + /* rely on g_object_[un]ref() to check the pointers are actually GObjects; + * elide a (object_ptr != NULL) check because most of the time we will be + * operating on struct members with a constant offset, so a NULL check would + * not catch bugs + */ + + if (old_object == new_object) + return FALSE; + + if (new_object != NULL) + g_object_ref (new_object); + + *object_ptr = new_object; + + if (old_object != NULL) + g_object_unref (old_object); + + return TRUE; +} + +/* We need GCC for __extension__, which we need to sort out strict aliasing of @object_ptr */ +#if defined(__GNUC__) + +#define g_set_object(object_ptr, new_object) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(object_ptr) == sizeof (new_object)); \ + /* Only one access, please; work around type aliasing */ \ + union { char *in; GObject **out; } _object_ptr; \ + _object_ptr.in = (char *) (object_ptr); \ + /* Check types match */ \ + (void) (0 ? *(object_ptr) = (new_object), FALSE : FALSE); \ + (g_set_object) (_object_ptr.out, (GObject *) new_object); \ + })) \ + GLIB_AVAILABLE_MACRO_IN_2_44 + +#else /* if !defined(__GNUC__) */ + +#define g_set_object(object_ptr, new_object) \ + (/* Check types match. */ \ + 0 ? *(object_ptr) = (new_object), FALSE : \ + (g_set_object) ((GObject **) (object_ptr), (GObject *) (new_object)) \ + ) + +#endif /* !defined(__GNUC__) */ + +/** + * g_assert_finalize_object: (skip) + * @object: (transfer full) (type GObject.Object): an object + * + * Assert that @object is non-%NULL, then release one reference to it with + * g_object_unref() and assert that it has been finalized (i.e. that there + * are no more references). + * + * If assertions are disabled via `G_DISABLE_ASSERT`, + * this macro just calls g_object_unref() without any further checks. + * + * This macro should only be used in regression tests. + * + * Since: 2.62 + */ +static inline void +(g_assert_finalize_object) (GObject *object) +{ + gpointer weak_pointer = object; + + g_assert_true (G_IS_OBJECT (weak_pointer)); + g_object_add_weak_pointer (object, &weak_pointer); + g_object_unref (weak_pointer); + g_assert_null (weak_pointer); +} + +#ifdef G_DISABLE_ASSERT +#define g_assert_finalize_object(object) g_object_unref (object) +#else +#define g_assert_finalize_object(object) (g_assert_finalize_object ((GObject *) object)) +#endif + +/** + * g_clear_weak_pointer: (skip) + * @weak_pointer_location: The memory address of a pointer + * + * Clears a weak reference to a #GObject. + * + * @weak_pointer_location must not be %NULL. + * + * If the weak reference is %NULL then this function does nothing. + * Otherwise, the weak reference to the object is removed for that location + * and the pointer is set to %NULL. + * + * A macro is also included that allows this function to be used without + * pointer casts. The function itself is static inline, so its address may vary + * between compilation units. + * + * Since: 2.56 + */ +static inline void +(g_clear_weak_pointer) (gpointer *weak_pointer_location) +{ + GObject *object = (GObject *) *weak_pointer_location; + + if (object != NULL) + { + g_object_remove_weak_pointer (object, weak_pointer_location); + *weak_pointer_location = NULL; + } +} + +#define g_clear_weak_pointer(weak_pointer_location) \ + (/* Check types match. */ \ + (g_clear_weak_pointer) ((gpointer *) (weak_pointer_location)) \ + ) + +/** + * g_set_weak_pointer: (skip) + * @weak_pointer_location: the memory address of a pointer + * @new_object: (nullable) (transfer none): a pointer to the new #GObject to + * assign to it, or %NULL to clear the pointer + * + * Updates a pointer to weakly refer to @new_object. + * + * It assigns @new_object to @weak_pointer_location and ensures + * that @weak_pointer_location will automatically be set to %NULL + * if @new_object gets destroyed. The assignment is not atomic. + * The weak reference is not thread-safe, see g_object_add_weak_pointer() + * for details. + * + * The @weak_pointer_location argument must not be %NULL. + * + * A macro is also included that allows this function to be used without + * pointer casts. The function itself is static inline, so its address may vary + * between compilation units. + * + * One convenient usage of this function is in implementing property setters: + * |[ + * void + * foo_set_bar (Foo *foo, + * Bar *new_bar) + * { + * g_return_if_fail (IS_FOO (foo)); + * g_return_if_fail (new_bar == NULL || IS_BAR (new_bar)); + * + * if (g_set_weak_pointer (&foo->bar, new_bar)) + * g_object_notify (foo, "bar"); + * } + * ]| + * + * Returns: %TRUE if the value of @weak_pointer_location changed, %FALSE otherwise + * + * Since: 2.56 + */ +static inline gboolean +(g_set_weak_pointer) (gpointer *weak_pointer_location, + GObject *new_object) +{ + GObject *old_object = (GObject *) *weak_pointer_location; + + /* elide a (weak_pointer_location != NULL) check because most of the time we + * will be operating on struct members with a constant offset, so a NULL + * check would not catch bugs + */ + + if (old_object == new_object) + return FALSE; + + if (old_object != NULL) + g_object_remove_weak_pointer (old_object, weak_pointer_location); + + *weak_pointer_location = new_object; + + if (new_object != NULL) + g_object_add_weak_pointer (new_object, weak_pointer_location); + + return TRUE; +} + +#define g_set_weak_pointer(weak_pointer_location, new_object) \ + (/* Check types match. */ \ + 0 ? *(weak_pointer_location) = (new_object), FALSE : \ + (g_set_weak_pointer) ((gpointer *) (weak_pointer_location), (GObject *) (new_object)) \ + ) + +typedef struct { + /**/ + union { gpointer p; } priv; +} GWeakRef; + +GLIB_AVAILABLE_IN_ALL +void g_weak_ref_init (GWeakRef *weak_ref, + gpointer object); +GLIB_AVAILABLE_IN_ALL +void g_weak_ref_clear (GWeakRef *weak_ref); +GLIB_AVAILABLE_IN_ALL +gpointer g_weak_ref_get (GWeakRef *weak_ref); +GLIB_AVAILABLE_IN_ALL +void g_weak_ref_set (GWeakRef *weak_ref, + gpointer object); + +G_END_DECLS + +#endif /* __G_OBJECT_H__ */ diff --git a/gobject/gobject.rc.in b/gobject/gobject.rc.in new file mode 100644 index 0000000..1c73e93 --- /dev/null +++ b/gobject/gobject.rc.in @@ -0,0 +1,30 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + FILEFLAGSMASK 0 + FILEFLAGS 0 + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "The GLib developer community" + VALUE "FileDescription", "GObject" + VALUE "FileVersion", "@GLIB_VERSION@.0" + VALUE "InternalName", "libgobject-2.0-@LT_CURRENT_MINUS_AGE@" + VALUE "LegalCopyright", "Copyright 1998-2011 Tim Janik, Red Hat, Inc. and others" + VALUE "OriginalFilename", "libgobject-2.0-@LT_CURRENT_MINUS_AGE@.dll" + VALUE "ProductName", "GLib" + VALUE "ProductVersion", "@GLIB_VERSION@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END + END diff --git a/gobject/gobject.stp.in b/gobject/gobject.stp.in new file mode 100644 index 0000000..67a4520 --- /dev/null +++ b/gobject/gobject.stp.in @@ -0,0 +1,199 @@ +global gobject_types_2_0_@LT_CURRENT@_@LT_REVISION@ +global gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@ +global gobject_signal_names_2_0_@LT_CURRENT@_@LT_REVISION@ + +/* These are needed to keep track of gtype and signal names for the below + * probes. + */ +probe process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("type__new") +{ + gobject_types_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),user_string($arg1)] = $arg3; + gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg3] = user_string($arg1); +} +probe process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("signal__new") +{ + gobject_signal_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg1] = user_string($arg2); +} + +/** + * probe gobject.type_new - Called when any entity registered with the #GType system is created + * @name: String name of type + * @parent_gtype: The parent #GType of this type + * @gtype: The #GType for this type + */ +probe gobject.type_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("type__new") +{ + name = user_string($arg1); + parent_gtype = $arg2; + gtype = $arg3; + probestr = sprintf("gobject.type_new(%s, %d) -> %d", name, parent_gtype, gtype); +} + +/** + * probe gobject.object_new - Called when a #GObject is created + * @object: Raw pointer to object + * @gtype: #GType for this object + * @type: String name of object type + */ +probe gobject.object_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("object__new") +{ + object = $arg1; + gtype = $arg2; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg2]; + probestr = sprintf("gobject.object_new(%s) -> %p", type, object); +} + +/** + * probe gobject.object_ref - Called when a new reference is added to a #GObject + * @object: Raw pointer to object + * @gtype: #GType for this object + * @type: String name of object type + * @old_refcount: Original value of the reference count + * @refcount: New value of the reference count + */ +probe gobject.object_ref = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("object__ref") +{ + object = $arg1; + gtype = $arg2; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),gtype]; + old_refcount = $arg3; + refcount = old_refcount+1; + probestr = sprintf("gobject.object_ref(%p[%s]) -> %d", object, type, refcount); +} + +/** + * probe gobject.object_unref - Called when a reference is removed from a #GObject + * @object: Raw pointer to object + * @gtype: #GType for this object + * @type: String name of object type + * @old_refcount: Original value of the reference count + */ +probe gobject.object_unref = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("object__unref") +{ + object = $arg1; + gtype = $arg2; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),gtype]; + old_refcount = $arg3; + refcount = old_refcount-1; + probestr = sprintf("gobject.object_unref(%p [%s]) -> %d", object, type, refcount); +} + +/** + * probe gobject.object_dispose - Called when a g_object_dispose() run for a #GObject is initiated + * @object: Raw pointer to object + * @gtype: #GType for this object + * @type: String name of object type + * @last_unref: FIXME + */ +probe gobject.object_dispose = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("object__dispose") +{ + object = $arg1; + gtype = $arg2; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg2]; + last_unref = $arg3; + probestr = sprintf("gobject.object_dispose(%p[%s])", object, type); +} + +/** + * probe gobject.object_dispose_end - Called when a g_object_dispose() run for a #GObject is completed + * @object: Raw pointer to object + * @gtype: #GType for this object + * @type: String name of object type + * @last_unref: FIXME + */ +probe gobject.object_dispose_end = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("object__dispose__end") +{ + object = $arg1; + gtype = $arg2; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg2]; + last_unref = $arg3; + probestr = sprintf("gobject.object_dispose_end(%p[%s])", object, type); +} + +/** + * probe gobject.object_finalize - Called when finalization for a #GObject is started + * @object: Raw pointer to object + * @gtype: #GType for this object + * @type: String name of object type + */ +probe gobject.object_finalize = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("object__finalize") +{ + object = $arg1; + gtype = $arg2; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg2]; + probestr = sprintf("gobject.object_finalize(%p[%s])", object, type); +} + +/** + * probe gobject.object_finalize - Called when finalization for a #GObject is completed + * @object: Raw pointer to object + * @gtype: #GType for this object + * @type: String name of object type + */ +probe gobject.object_finalize_end = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("object__finalize__end") +{ + object = $arg1; + gtype = $arg2; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg2]; + probestr = sprintf("gobject.object_finalize_end(%p[%s])", object, type); +} + +/** + * probe gobject.signal_new - Called when a new signal is registered for a #GObject + * @gsignal: Integer value for this signal + * @name: String name for this signal + * @gtype: #GType for the type which will gain the new signal + * @type: String name of the type which will gain the new signal + */ +probe gobject.signal_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("signal__new") +{ + gsignal = $arg1; + name = user_string($arg2); + gtype = $arg3; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg3]; + probestr = sprintf("gobject.signal_new(%s, %s) -> %d", name, type, gsignal); +} + +/** + * probe gobject.signal_emit - Called when a signal emission for a #GObject is started + * @gsignal: Integer value for this signal + * @detail: String containing signal "detail" + * @signal: String name of the signal + * @object: Raw pointer for object emitting signal + * @gtype: #GType for the type emitting the signal + * @type: String name of the type emitting the signal + */ +probe gobject.signal_emit = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("signal__emit") +{ + gsignal = $arg1; + detail = $arg2; + signal = gobject_signal_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg1]; + if (detail != 0) + signal = signal . "::" . gquarks[pid(), detail] + object = $arg3; + gtype = $arg4; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg4]; + probestr = sprintf("gobject.signal_emit(%p[%s], %s)", object, type, signal); +} + +/** + * probe gobject.signal_emit_end - Called when a signal emission for a #GObject is completed + * @gsignal: Integer value for this signal + * @detail: String containing signal "detail" + * @signal: String name of the signal + * @object: Raw pointer for object emitting signal + * @gtype: #GType for the type emitting the signal + * @type: String name of the type emitting the signal + */ +probe gobject.signal_emit_end = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgobject-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("signal__emit__end") +{ + gsignal = $arg1; + detail = $arg2; + signal = gobject_signal_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg1]; + if (detail != 0) + signal = signal . "::" . gquarks[pid(), detail] + object = $arg3; + gtype = $arg4; + type = gobject_type_names_2_0_@LT_CURRENT@_@LT_REVISION@[pid(),$arg4]; + probestr = sprintf("gobject.signal_emit_end(%p[%s], %s)", object, type, signal); +} diff --git a/gobject/gobject_gdb.py b/gobject/gobject_gdb.py new file mode 100644 index 0000000..ac9fd4e --- /dev/null +++ b/gobject/gobject_gdb.py @@ -0,0 +1,352 @@ +import gdb +import glib_gdb +import sys + +if sys.version_info[0] >= 3: + long = int +else: + import itertools + + map = itertools.imap + +# FrameDecorator is new in gdb 7.7, so we adapt to its absence. +try: + import gdb.FrameDecorator + + HAVE_GDB_FRAMEDECORATOR = True + FrameDecorator = gdb.FrameDecorator.FrameDecorator +except ImportError: + HAVE_GDB_FRAMEDECORATOR = False + + +# This is not quite right, as local vars may override symname +def read_global_var(symname): + return gdb.selected_frame().read_var(symname) + + +def g_type_to_typenode(gtype): + def lookup_fundamental_type(typenode): + if typenode == 0: + return None + val = read_global_var("static_fundamental_type_nodes") + if val is None: + return None + return val[typenode >> 2].address + + gtype = long(gtype) + typenode = gtype - gtype % 4 + if typenode > (255 << 2): + typenode = gdb.Value(typenode).cast(gdb.lookup_type("TypeNode").pointer()) + else: + typenode = lookup_fundamental_type(typenode) + return typenode + + +def g_type_to_name(gtype): + typenode = g_type_to_typenode(gtype) + if typenode is not None: + return glib_gdb.g_quark_to_string(typenode["qname"]) + return None + + +def is_g_type_instance(val): + def is_g_type_instance_helper(type): + if str(type) == "GTypeInstance": + return True + + while type.code == gdb.TYPE_CODE_TYPEDEF: + type = type.target() + + if type.code != gdb.TYPE_CODE_STRUCT: + return False + + fields = type.fields() + if len(fields) < 1: + return False + + first_field = fields[0] + return is_g_type_instance_helper(first_field.type) + + type = val.type + if type.code != gdb.TYPE_CODE_PTR: + return False + type = type.target() + return is_g_type_instance_helper(type) + + +def g_type_name_from_instance(instance): + if long(instance) != 0: + try: + inst = instance.cast(gdb.lookup_type("GTypeInstance").pointer()) + klass = inst["g_class"] + gtype = klass["g_type"] + name = g_type_to_name(gtype) + return name + except RuntimeError: + pass + return None + + +class GTypePrettyPrinter: + "Prints a GType instance pointer" + + def __init__(self, val): + self.val = val + + def to_string(self): + name = g_type_name_from_instance(self.val) + if name: + return ("0x%x [%s]") % (long(self.val), name) + return ("0x%x") % (long(self.val)) + + +def is_g_type_class_instance(val): + type = val.type + if type.code != gdb.TYPE_CODE_PTR: + return False + return str(type.target()) == "GTypeClass" + + +class GTypeHandlePrettyPrinter: + "Prints a GType instance" + + def __init__(self, val, hint=""): + self.val = val + self.hint = hint + + def to_string(self): + typenode = g_type_to_typenode(self.val) + if typenode is not None: + name = glib_gdb.g_quark_to_string(typenode["qname"]) + s = ("0x%x [%s%s") % (long(self.val), self.hint, name) + for i in range(1, int(typenode["n_supers"])): + node = g_type_to_typenode(typenode["supers"][i]) + if node: + name = glib_gdb.g_quark_to_string(node["qname"]) + else: + name = "???" + s += "/" + name + return s + "]" + else: + return ("0x%x") % (long(self.val)) + + +def pretty_printer_lookup(val): + if is_g_type_instance(val): + return GTypePrettyPrinter(val) + if str(val.type) == "GType": + return GTypeHandlePrettyPrinter(val) + if is_g_type_class_instance(val): + return GTypeHandlePrettyPrinter(val["g_type"], "g_type: ") + + return None + + +def get_signal_name(id): + if id is None: + return None + id = long(id) + if id == 0: + return None + val = read_global_var("g_signal_nodes") + max_s = read_global_var("g_n_signal_nodes") + max_s = long(max_s) + if id < max_s: + return val[id]["name"].string() + return None + + +def frame_name(frame): + return str(frame.function()) + + +def frame_var(frame, var): + return frame.inferior_frame().read_var(var) + + +class SignalFrame(FrameDecorator): + def __init__(self, frames): + FrameDecorator.__init__(self, frames[-1]) + self.frame = frames[-1] + self.frames = frames + + def name(self): + return "signal-emission" + + def read_var(self, frame, name, array=None): + try: + v = frame_var(frame, name) + if v is None or v.is_optimized_out: + return None + if array is not None: + array.append(v) + return v + except ValueError: + return None + + def read_object(self, frame, name, array=None): + try: + v = frame_var(frame, name) + if v is None or v.is_optimized_out: + return None + v = v.cast(gdb.lookup_type("GObject").pointer()) + # Ensure this is a somewhat correct object pointer + if v is not None and g_type_name_from_instance(v): + if array is not None: + array.append(v) + return v + return None + except ValueError: + return None + + def append(self, array, obj): + if obj is not None: + array.append(obj) + + def or_join_array(self, array): + if len(array) == 0: + return "???" + else: + return " or ".join(set(map(str, array))) + + def get_detailed_signal_from_frame(self, frame, signal): + detail = self.read_var(frame, "detail") + detail = glib_gdb.g_quark_to_string(detail) + if detail is not None: + return signal + ":" + detail + else: + return detail + + def function(self): + instances = [] + signals = [] + + for frame in self.frames: + name = frame_name(frame) + if name == "signal_emit_unlocked_R": + self.read_object(frame, "instance", instances) + node = self.read_var(frame, "node") + if node: + signal = node["name"].string() + signal = self.get_detailed_signal_from_frame(frame, signal) + self.append(signals, signal) + + if name == "g_signal_emitv": + instance_and_params = self.read_var(frame, "instance_and_params") + if instance_and_params: + instance = instance_and_params[0]["v_pointer"].cast( + gdb.Type("GObject").pointer() + ) + self.append(instances, instance) + id = self.read_var(frame, "signal_id") + signal = get_signal_name(id) + if signal: + signal = self.get_detailed_signal_from_frame(frame, signal) + self.append(signals, signal) + + if name == "g_signal_emit_valist" or name == "g_signal_emit": + self.read_object(frame, "instance", instances) + id = self.read_var(frame, "signal_id") + signal = get_signal_name(id) + if signal: + signal = self.get_detailed_signal_from_frame(frame, signal) + self.append(signals, signal) + + if name == "g_signal_emit_by_name": + self.read_object(frame, "instance", instances) + self.read_var(frame, "detailed_signal", signals) + break + + instance = self.or_join_array(instances) + signal = self.or_join_array(signals) + + return "" % (signal, instance) + + def elided(self): + return self.frames[0:-1] + + def describe(self, stream, full): + stream.write(" " + self.function() + "\n") + + +class GFrameDecorator: + def __init__(self, iter): + self.queue = [] + self.iter = iter + + def __iter__(self): + return self + + def fill(self): + while len(self.queue) <= 8: + try: + f = next(self.iter) + self.queue.append(f) + except StopIteration: + return + + def find_signal_emission(self): + for i in range(min(len(self.queue), 3)): + if frame_name(self.queue[i]) == "signal_emit_unlocked_R": + return i + return -1 + + def next(self): + # Ensure we have enough frames for a full signal emission + self.fill() + + # Are we at the end? + if len(self.queue) == 0: + raise StopIteration + + emission = self.find_signal_emission() + if emission > 0: + start = emission + while True: + if start == 0: + break + prev_name = frame_name(self.queue[start - 1]) + if prev_name.find("_marshal_") >= 0 or prev_name == "g_closure_invoke": + start = start - 1 + else: + break + end = emission + 1 + while end < len(self.queue): + if frame_name(self.queue[end]) in [ + "g_signal_emitv", + "g_signal_emit_valist", + "g_signal_emit", + "g_signal_emit_by_name", + "_g_closure_invoke_va", + ]: + end = end + 1 + else: + break + + signal_frames = self.queue[start:end] + new_frames = [SignalFrame(signal_frames)] + self.queue[start:end] = new_frames + + return self.queue.pop(0) + + def __next__(self): + return self.next() + + +class GFrameFilter(object): + name = "glib" + enabled = True + priority = 100 + + def filter(self, iterator): + return GFrameDecorator(iterator) + + +def register(obj): + if obj is None: + obj = gdb + + if HAVE_GDB_FRAMEDECORATOR: + filter = GFrameFilter() + obj.frame_filters[filter.name] = filter + obj.pretty_printers.append(pretty_printer_lookup) diff --git a/gobject/gobject_probes.d b/gobject/gobject_probes.d new file mode 100644 index 0000000..bddbfae --- /dev/null +++ b/gobject/gobject_probes.d @@ -0,0 +1,13 @@ +provider gobject { + probe type__new(char *, unsigned long, unsigned long); + probe object__new(void*, unsigned long); + probe object__ref(void*, unsigned long, unsigned int); + probe object__unref(void*, unsigned long, unsigned int); + probe object__dispose(void*, unsigned long, unsigned int); + probe object__dispose__end(void*, unsigned long, unsigned int); + probe object__finalize(void*, unsigned long); + probe object__finalize__end(void*, unsigned long); + probe signal__new(unsigned int, char *, unsigned long); + probe signal__emit(unsigned int, unsigned int, void *, unsigned long); + probe signal__emit__end(unsigned int, unsigned int, void *, unsigned long); +}; diff --git a/gobject/gobject_trace.h b/gobject/gobject_trace.h new file mode 100644 index 0000000..261fdac --- /dev/null +++ b/gobject/gobject_trace.h @@ -0,0 +1,43 @@ +/* GLIB - Library of useful routines for C programming + * + * Copyright (C) 2009,2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Alexander Larsson + */ + +#ifndef __GOBJECTTRACE_H__ +#define __GOBJECTTRACE_H__ + +#ifndef SIZEOF_CHAR +#error "config.h must be included prior to gobject_trace.h" +#endif + +/* Ignore probes when doing static analysis, as they do weird things which + * confuses the analyser. */ +#if defined(HAVE_DTRACE) && !defined(__clang_analyzer__) + +/* include the generated probes header and put markers in code */ +#include "gobject_probes.h" +#define TRACE(probe) probe + +#else + +/* Wrap the probe to allow it to be removed when no systemtap available */ +#define TRACE(probe) + +#endif + +#endif /* __GOBJECTTRACE_H__ */ diff --git a/gobject/gobjectnotifyqueue.c b/gobject/gobjectnotifyqueue.c new file mode 100644 index 0000000..1a7d23f --- /dev/null +++ b/gobject/gobjectnotifyqueue.c @@ -0,0 +1,197 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* WARNING: + * + * This file is INSTALLED and other projects (outside of glib) + * #include its contents. + */ + +#ifndef __G_OBJECT_NOTIFY_QUEUE_H__ +#define __G_OBJECT_NOTIFY_QUEUE_H__ + +#include /* memset */ + +#include + +G_BEGIN_DECLS + + +/* --- typedefs --- */ +typedef struct _GObjectNotifyContext GObjectNotifyContext; +typedef struct _GObjectNotifyQueue GObjectNotifyQueue; +typedef void (*GObjectNotifyQueueDispatcher) (GObject *object, + guint n_pspecs, + GParamSpec **pspecs); + + +/* --- structures --- */ +struct _GObjectNotifyContext +{ + GQuark quark_notify_queue; + GObjectNotifyQueueDispatcher dispatcher; + GTrashStack *_nqueue_trash; /* unused */ +}; +struct _GObjectNotifyQueue +{ + GObjectNotifyContext *context; + GSList *pspecs; + guint16 n_pspecs; + guint16 freeze_count; +}; + +G_LOCK_DEFINE_STATIC(notify_lock); + +/* --- functions --- */ +static void +g_object_notify_queue_free (gpointer data) +{ + GObjectNotifyQueue *nqueue = data; + + g_slist_free (nqueue->pspecs); + g_slice_free (GObjectNotifyQueue, nqueue); +} + +static inline GObjectNotifyQueue* +g_object_notify_queue_freeze (GObject *object, + GObjectNotifyContext *context) +{ + GObjectNotifyQueue *nqueue; + + G_LOCK(notify_lock); + nqueue = g_datalist_id_get_data (&object->qdata, context->quark_notify_queue); + if (!nqueue) + { + nqueue = g_slice_new0 (GObjectNotifyQueue); + nqueue->context = context; + g_datalist_id_set_data_full (&object->qdata, context->quark_notify_queue, + nqueue, g_object_notify_queue_free); + } + + if (nqueue->freeze_count >= 65535) + g_critical("Free queue for %s (%p) is larger than 65535," + " called g_object_freeze_notify() too often." + " Forgot to call g_object_thaw_notify() or infinite loop", + G_OBJECT_TYPE_NAME (object), object); + else + nqueue->freeze_count++; + G_UNLOCK(notify_lock); + + return nqueue; +} + +static inline void +g_object_notify_queue_thaw (GObject *object, + GObjectNotifyQueue *nqueue) +{ + GObjectNotifyContext *context = nqueue->context; + GParamSpec *pspecs_mem[16], **pspecs, **free_me = NULL; + GSList *slist; + guint n_pspecs = 0; + + g_return_if_fail (nqueue->freeze_count > 0); + g_return_if_fail (g_atomic_int_get(&object->ref_count) > 0); + + G_LOCK(notify_lock); + + /* Just make sure we never get into some nasty race condition */ + if (G_UNLIKELY(nqueue->freeze_count == 0)) { + G_UNLOCK(notify_lock); + g_warning ("%s: property-changed notification for %s(%p) is not frozen", + G_STRFUNC, G_OBJECT_TYPE_NAME (object), object); + return; + } + + nqueue->freeze_count--; + if (nqueue->freeze_count) { + G_UNLOCK(notify_lock); + return; + } + + pspecs = nqueue->n_pspecs > 16 ? free_me = g_new (GParamSpec*, nqueue->n_pspecs) : pspecs_mem; + + for (slist = nqueue->pspecs; slist; slist = slist->next) + { + pspecs[n_pspecs++] = slist->data; + } + g_datalist_id_set_data (&object->qdata, context->quark_notify_queue, NULL); + + G_UNLOCK(notify_lock); + + if (n_pspecs) + context->dispatcher (object, n_pspecs, pspecs); + g_free (free_me); +} + +static inline void +g_object_notify_queue_clear (GObject *object, + GObjectNotifyQueue *nqueue) +{ + g_return_if_fail (nqueue->freeze_count > 0); + + G_LOCK(notify_lock); + + g_slist_free (nqueue->pspecs); + nqueue->pspecs = NULL; + nqueue->n_pspecs = 0; + + G_UNLOCK(notify_lock); +} + +static inline void +g_object_notify_queue_add (GObject *object, + GObjectNotifyQueue *nqueue, + GParamSpec *pspec) +{ + if (pspec->flags & G_PARAM_READABLE) + { + GParamSpec *redirect; + + G_LOCK(notify_lock); + + g_return_if_fail (nqueue->n_pspecs < 65535); + + redirect = g_param_spec_get_redirect_target (pspec); + if (redirect) + pspec = redirect; + + /* we do the deduping in _thaw */ + if (g_slist_find (nqueue->pspecs, pspec) == NULL) + { + nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec); + nqueue->n_pspecs++; + } + + G_UNLOCK(notify_lock); + } +} + +/* NB: This function is not threadsafe, do not ever use it if + * you need a threadsafe notify queue. + * Use g_object_notify_queue_freeze() to acquire the queue and + * g_object_notify_queue_thaw() after you are done instead. + */ +static inline GObjectNotifyQueue* +g_object_notify_queue_from_object (GObject *object, + GObjectNotifyContext *context) +{ + return g_datalist_id_get_data (&object->qdata, context->quark_notify_queue); +} + +G_END_DECLS + +#endif /* __G_OBJECT_NOTIFY_QUEUE_H__ */ diff --git a/gobject/gparam.c b/gobject/gparam.c new file mode 100644 index 0000000..d761d92 --- /dev/null +++ b/gobject/gparam.c @@ -0,0 +1,1619 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * MT safe + */ + +#include "config.h" + +#include + +#include "gparam.h" +#include "gparamspecs.h" +#include "gvaluecollector.h" +#include "gtype-private.h" + +/** + * SECTION:gparamspec + * @short_description: Metadata for parameter specifications + * @see_also: g_object_class_install_property(), g_object_set(), + * g_object_get(), g_object_set_property(), g_object_get_property(), + * g_value_register_transform_func() + * @title: GParamSpec + * + * #GParamSpec is an object structure that encapsulates the metadata + * required to specify parameters, such as e.g. #GObject properties. + * + * ## Parameter names # {#canonical-parameter-names} + * + * A property name consists of one or more segments consisting of ASCII letters + * and digits, separated by either the `-` or `_` character. The first + * character of a property name must be a letter. These are the same rules as + * for signal naming (see g_signal_new()). + * + * When creating and looking up a #GParamSpec, either separator can be + * used, but they cannot be mixed. Using `-` is considerably more + * efficient, and is the ‘canonical form’. Using `_` is discouraged. + */ + + +/* --- defines --- */ +#define PARAM_FLOATING_FLAG 0x2 +#define G_PARAM_USER_MASK (~0U << G_PARAM_USER_SHIFT) +#define PSPEC_APPLIES_TO_VALUE(pspec, value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_PARAM_SPEC_VALUE_TYPE (pspec))) + +/* --- prototypes --- */ +static void g_param_spec_class_base_init (GParamSpecClass *class); +static void g_param_spec_class_base_finalize (GParamSpecClass *class); +static void g_param_spec_class_init (GParamSpecClass *class, + gpointer class_data); +static void g_param_spec_init (GParamSpec *pspec, + GParamSpecClass *class); +static void g_param_spec_finalize (GParamSpec *pspec); +static void value_param_init (GValue *value); +static void value_param_free_value (GValue *value); +static void value_param_copy_value (const GValue *src_value, + GValue *dest_value); +static void value_param_transform_value (const GValue *src_value, + GValue *dest_value); +static gpointer value_param_peek_pointer (const GValue *value); +static gchar* value_param_collect_value (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags); +static gchar* value_param_lcopy_value (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags); + +typedef struct +{ + GValue default_value; + GQuark name_quark; +} GParamSpecPrivate; + +static gint g_param_private_offset; + +/* --- functions --- */ +static inline GParamSpecPrivate * +g_param_spec_get_private (GParamSpec *pspec) +{ + return &G_STRUCT_MEMBER (GParamSpecPrivate, pspec, g_param_private_offset); +} + +void +_g_param_type_init (void) +{ + static const GTypeFundamentalInfo finfo = { + (G_TYPE_FLAG_CLASSED | + G_TYPE_FLAG_INSTANTIATABLE | + G_TYPE_FLAG_DERIVABLE | + G_TYPE_FLAG_DEEP_DERIVABLE), + }; + static const GTypeValueTable param_value_table = { + value_param_init, /* value_init */ + value_param_free_value, /* value_free */ + value_param_copy_value, /* value_copy */ + value_param_peek_pointer, /* value_peek_pointer */ + "p", /* collect_format */ + value_param_collect_value, /* collect_value */ + "p", /* lcopy_format */ + value_param_lcopy_value, /* lcopy_value */ + }; + const GTypeInfo param_spec_info = { + sizeof (GParamSpecClass), + + (GBaseInitFunc) g_param_spec_class_base_init, + (GBaseFinalizeFunc) g_param_spec_class_base_finalize, + (GClassInitFunc) g_param_spec_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + + sizeof (GParamSpec), + 0, /* n_preallocs */ + (GInstanceInitFunc) g_param_spec_init, + + ¶m_value_table, + }; + GType type; + + /* This should be registered as GParamSpec instead of GParam, for + * consistency sake, so that type name can be mapped to struct name, + * However, some language bindings, most noticeable the python ones + * depends on the "GParam" identifier, see #548689 + */ + type = g_type_register_fundamental (G_TYPE_PARAM, g_intern_static_string ("GParam"), ¶m_spec_info, &finfo, G_TYPE_FLAG_ABSTRACT); + g_assert (type == G_TYPE_PARAM); + g_param_private_offset = g_type_add_instance_private (type, sizeof (GParamSpecPrivate)); + g_value_register_transform_func (G_TYPE_PARAM, G_TYPE_PARAM, value_param_transform_value); +} + +static void +g_param_spec_class_base_init (GParamSpecClass *class) +{ +} + +static void +g_param_spec_class_base_finalize (GParamSpecClass *class) +{ +} + +static void +g_param_spec_class_init (GParamSpecClass *class, + gpointer class_data) +{ + class->value_type = G_TYPE_NONE; + class->finalize = g_param_spec_finalize; + class->value_set_default = NULL; + class->value_validate = NULL; + class->values_cmp = NULL; + + g_type_class_adjust_private_offset (class, &g_param_private_offset); +} + +static void +g_param_spec_init (GParamSpec *pspec, + GParamSpecClass *class) +{ + pspec->name = NULL; + pspec->_nick = NULL; + pspec->_blurb = NULL; + pspec->flags = 0; + pspec->value_type = class->value_type; + pspec->owner_type = 0; + pspec->qdata = NULL; + g_datalist_set_flags (&pspec->qdata, PARAM_FLOATING_FLAG); + pspec->ref_count = 1; + pspec->param_id = 0; +} + +static void +g_param_spec_finalize (GParamSpec *pspec) +{ + GParamSpecPrivate *priv = g_param_spec_get_private (pspec); + + if (priv->default_value.g_type) + g_value_reset (&priv->default_value); + + g_datalist_clear (&pspec->qdata); + + if (!(pspec->flags & G_PARAM_STATIC_NICK)) + g_free (pspec->_nick); + + if (!(pspec->flags & G_PARAM_STATIC_BLURB)) + g_free (pspec->_blurb); + + g_type_free_instance ((GTypeInstance*) pspec); +} + +/** + * g_param_spec_ref: (skip) + * @pspec: (transfer none) (not nullable): a valid #GParamSpec + * + * Increments the reference count of @pspec. + * + * Returns: (transfer full) (not nullable): the #GParamSpec that was passed into this function + */ +GParamSpec* +g_param_spec_ref (GParamSpec *pspec) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + g_atomic_int_inc ((int *)&pspec->ref_count); + + return pspec; +} + +/** + * g_param_spec_unref: (skip) + * @pspec: a valid #GParamSpec + * + * Decrements the reference count of a @pspec. + */ +void +g_param_spec_unref (GParamSpec *pspec) +{ + gboolean is_zero; + + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + + is_zero = g_atomic_int_dec_and_test ((int *)&pspec->ref_count); + + if (G_UNLIKELY (is_zero)) + { + G_PARAM_SPEC_GET_CLASS (pspec)->finalize (pspec); + } +} + +/** + * g_param_spec_sink: + * @pspec: a valid #GParamSpec + * + * The initial reference count of a newly created #GParamSpec is 1, + * even though no one has explicitly called g_param_spec_ref() on it + * yet. So the initial reference count is flagged as "floating", until + * someone calls `g_param_spec_ref (pspec); g_param_spec_sink + * (pspec);` in sequence on it, taking over the initial + * reference count (thus ending up with a @pspec that has a reference + * count of 1 still, but is not flagged "floating" anymore). + */ +void +g_param_spec_sink (GParamSpec *pspec) +{ + gsize oldvalue; + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + + oldvalue = g_atomic_pointer_and (&pspec->qdata, ~(gsize)PARAM_FLOATING_FLAG); + if (oldvalue & PARAM_FLOATING_FLAG) + g_param_spec_unref (pspec); +} + +/** + * g_param_spec_ref_sink: (skip) + * @pspec: a valid #GParamSpec + * + * Convenience function to ref and sink a #GParamSpec. + * + * Since: 2.10 + * Returns: (transfer full) (not nullable): the #GParamSpec that was passed into this function + */ +GParamSpec* +g_param_spec_ref_sink (GParamSpec *pspec) +{ + gsize oldvalue; + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + oldvalue = g_atomic_pointer_and (&pspec->qdata, ~(gsize)PARAM_FLOATING_FLAG); + if (!(oldvalue & PARAM_FLOATING_FLAG)) + g_param_spec_ref (pspec); + + return pspec; +} + +/** + * g_param_spec_get_name: + * @pspec: a valid #GParamSpec + * + * Get the name of a #GParamSpec. + * + * The name is always an "interned" string (as per g_intern_string()). + * This allows for pointer-value comparisons. + * + * Returns: the name of @pspec. + */ +const gchar * +g_param_spec_get_name (GParamSpec *pspec) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + return pspec->name; +} + +/** + * g_param_spec_get_nick: + * @pspec: a valid #GParamSpec + * + * Get the nickname of a #GParamSpec. + * + * Returns: the nickname of @pspec. + */ +const gchar * +g_param_spec_get_nick (GParamSpec *pspec) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + if (pspec->_nick) + return pspec->_nick; + else + { + GParamSpec *redirect_target; + + redirect_target = g_param_spec_get_redirect_target (pspec); + if (redirect_target && redirect_target->_nick) + return redirect_target->_nick; + } + + return pspec->name; +} + +/** + * g_param_spec_get_blurb: + * @pspec: a valid #GParamSpec + * + * Get the short description of a #GParamSpec. + * + * Returns: (nullable): the short description of @pspec. + */ +const gchar * +g_param_spec_get_blurb (GParamSpec *pspec) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + if (pspec->_blurb) + return pspec->_blurb; + else + { + GParamSpec *redirect_target; + + redirect_target = g_param_spec_get_redirect_target (pspec); + if (redirect_target && redirect_target->_blurb) + return redirect_target->_blurb; + } + + return NULL; +} + +/* @key must have already been validated with is_valid() + * Modifies @key in place. */ +static void +canonicalize_key (gchar *key) +{ + gchar *p; + + for (p = key; *p != 0; p++) + { + gchar c = *p; + + if (c == '_') + *p = '-'; + } +} + +/* @key must have already been validated with is_valid() */ +static gboolean +is_canonical (const gchar *key) +{ + return (strchr (key, '_') == NULL); +} + +/** + * g_param_spec_is_valid_name: + * @name: the canonical name of the property + * + * Validate a property name for a #GParamSpec. This can be useful for + * dynamically-generated properties which need to be validated at run-time + * before actually trying to create them. + * + * See [canonical parameter names][canonical-parameter-names] for details of + * the rules for valid names. + * + * Returns: %TRUE if @name is a valid property name, %FALSE otherwise. + * Since: 2.66 + */ +gboolean +g_param_spec_is_valid_name (const gchar *name) +{ + const gchar *p; + + /* First character must be a letter. */ + if ((name[0] < 'A' || name[0] > 'Z') && + (name[0] < 'a' || name[0] > 'z')) + return FALSE; + + for (p = name; *p != 0; p++) + { + const gchar c = *p; + + if (c != '-' && c != '_' && + (c < '0' || c > '9') && + (c < 'A' || c > 'Z') && + (c < 'a' || c > 'z')) + return FALSE; + } + + return TRUE; +} + +/** + * g_param_spec_internal: (skip) + * @param_type: the #GType for the property; must be derived from %G_TYPE_PARAM + * @name: the canonical name of the property + * @nick: (nullable): the nickname of the property + * @blurb: (nullable): a short description of the property + * @flags: a combination of #GParamFlags + * + * Creates a new #GParamSpec instance. + * + * See [canonical parameter names][canonical-parameter-names] for details of + * the rules for @name. Names which violate these rules lead to undefined + * behaviour. + * + * Beyond the name, #GParamSpecs have two more descriptive strings, the + * @nick and @blurb, which may be used as a localized label and description. + * For GTK and related libraries these are considered deprecated and may be + * omitted, while for other libraries such as GStreamer and its plugins they + * are essential. When in doubt, follow the conventions used in the + * surrounding code and supporting libraries. + * + * Returns: (type GObject.ParamSpec): (transfer floating): a newly allocated + * #GParamSpec instance, which is initially floating + */ +gpointer +g_param_spec_internal (GType param_type, + const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamFlags flags) +{ + GParamSpec *pspec; + GParamSpecPrivate *priv; + + g_return_val_if_fail (G_TYPE_IS_PARAM (param_type) && param_type != G_TYPE_PARAM, NULL); + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (g_param_spec_is_valid_name (name), NULL); + g_return_val_if_fail (!(flags & G_PARAM_STATIC_NAME) || is_canonical (name), NULL); + + pspec = (gpointer) g_type_create_instance (param_type); + + if (flags & G_PARAM_STATIC_NAME) + { + /* pspec->name is not freed if (flags & G_PARAM_STATIC_NAME) */ + pspec->name = (gchar *) g_intern_static_string (name); + if (!is_canonical (pspec->name)) + g_warning ("G_PARAM_STATIC_NAME used with non-canonical pspec name: %s", pspec->name); + } + else + { + if (is_canonical (name)) + pspec->name = (gchar *) g_intern_string (name); + else + { + gchar *tmp = g_strdup (name); + canonicalize_key (tmp); + pspec->name = (gchar *) g_intern_string (tmp); + g_free (tmp); + } + } + + priv = g_param_spec_get_private (pspec); + priv->name_quark = g_quark_from_string (pspec->name); + + if (flags & G_PARAM_STATIC_NICK) + pspec->_nick = (gchar*) nick; + else + pspec->_nick = g_strdup (nick); + + if (flags & G_PARAM_STATIC_BLURB) + pspec->_blurb = (gchar*) blurb; + else + pspec->_blurb = g_strdup (blurb); + + pspec->flags = (flags & G_PARAM_USER_MASK) | (flags & G_PARAM_MASK); + + return pspec; +} + +/** + * g_param_spec_get_qdata: + * @pspec: a valid #GParamSpec + * @quark: a #GQuark, naming the user data pointer + * + * Gets back user data pointers stored via g_param_spec_set_qdata(). + * + * Returns: (transfer none) (nullable): the user data pointer set, or %NULL + */ +gpointer +g_param_spec_get_qdata (GParamSpec *pspec, + GQuark quark) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + + return quark ? g_datalist_id_get_data (&pspec->qdata, quark) : NULL; +} + +/** + * g_param_spec_set_qdata: + * @pspec: the #GParamSpec to set store a user data pointer + * @quark: a #GQuark, naming the user data pointer + * @data: (nullable): an opaque user data pointer + * + * Sets an opaque, named pointer on a #GParamSpec. The name is + * specified through a #GQuark (retrieved e.g. via + * g_quark_from_static_string()), and the pointer can be gotten back + * from the @pspec with g_param_spec_get_qdata(). Setting a + * previously set user data pointer, overrides (frees) the old pointer + * set, using %NULL as pointer essentially removes the data stored. + */ +void +g_param_spec_set_qdata (GParamSpec *pspec, + GQuark quark, + gpointer data) +{ + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + g_return_if_fail (quark > 0); + + g_datalist_id_set_data (&pspec->qdata, quark, data); +} + +/** + * g_param_spec_set_qdata_full: (skip) + * @pspec: the #GParamSpec to set store a user data pointer + * @quark: a #GQuark, naming the user data pointer + * @data: (nullable): an opaque user data pointer + * @destroy: (nullable): function to invoke with @data as argument, when @data needs to + * be freed + * + * This function works like g_param_spec_set_qdata(), but in addition, + * a `void (*destroy) (gpointer)` function may be + * specified which is called with @data as argument when the @pspec is + * finalized, or the data is being overwritten by a call to + * g_param_spec_set_qdata() with the same @quark. + */ +void +g_param_spec_set_qdata_full (GParamSpec *pspec, + GQuark quark, + gpointer data, + GDestroyNotify destroy) +{ + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + g_return_if_fail (quark > 0); + + g_datalist_id_set_data_full (&pspec->qdata, quark, data, data ? destroy : (GDestroyNotify) NULL); +} + +/** + * g_param_spec_steal_qdata: + * @pspec: the #GParamSpec to get a stored user data pointer from + * @quark: a #GQuark, naming the user data pointer + * + * Gets back user data pointers stored via g_param_spec_set_qdata() + * and removes the @data from @pspec without invoking its destroy() + * function (if any was set). Usually, calling this function is only + * required to update user data pointers with a destroy notifier. + * + * Returns: (transfer none) (nullable): the user data pointer set, or %NULL + */ +gpointer +g_param_spec_steal_qdata (GParamSpec *pspec, + GQuark quark) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); + g_return_val_if_fail (quark > 0, NULL); + + return g_datalist_id_remove_no_notify (&pspec->qdata, quark); +} + +/** + * g_param_spec_get_redirect_target: + * @pspec: a #GParamSpec + * + * If the paramspec redirects operations to another paramspec, + * returns that paramspec. Redirect is used typically for + * providing a new implementation of a property in a derived + * type while preserving all the properties from the parent + * type. Redirection is established by creating a property + * of type #GParamSpecOverride. See g_object_class_override_property() + * for an example of the use of this capability. + * + * Since: 2.4 + * + * Returns: (transfer none) (nullable): paramspec to which requests on this + * paramspec should be redirected, or %NULL if none. + */ +GParamSpec* +g_param_spec_get_redirect_target (GParamSpec *pspec) +{ + GTypeInstance *inst = (GTypeInstance *)pspec; + + if (inst && inst->g_class && inst->g_class->g_type == G_TYPE_PARAM_OVERRIDE) + return ((GParamSpecOverride*)pspec)->overridden; + else + return NULL; +} + +/** + * g_param_value_set_default: + * @pspec: a valid #GParamSpec + * @value: a #GValue of correct type for @pspec; since 2.64, you + * can also pass an empty #GValue, initialized with %G_VALUE_INIT + * + * Sets @value to its default value as specified in @pspec. + */ +void +g_param_value_set_default (GParamSpec *pspec, + GValue *value) +{ + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + + if (G_VALUE_TYPE (value) == G_TYPE_INVALID) + { + g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + } + else + { + g_return_if_fail (G_IS_VALUE (value)); + g_return_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value)); + g_value_reset (value); + } + + G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, value); +} + +/** + * g_param_value_defaults: + * @pspec: a valid #GParamSpec + * @value: a #GValue of correct type for @pspec + * + * Checks whether @value contains the default value as specified in @pspec. + * + * Returns: whether @value contains the canonical default for this @pspec + */ +gboolean +g_param_value_defaults (GParamSpec *pspec, + const GValue *value) +{ + GValue dflt_value = G_VALUE_INIT; + gboolean defaults; + + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); + g_return_val_if_fail (G_IS_VALUE (value), FALSE); + g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value), FALSE); + + g_value_init (&dflt_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, &dflt_value); + defaults = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value, &dflt_value) == 0; + g_value_unset (&dflt_value); + + return defaults; +} + +/** + * g_param_value_validate: + * @pspec: a valid #GParamSpec + * @value: a #GValue of correct type for @pspec + * + * Ensures that the contents of @value comply with the specifications + * set out by @pspec. For example, a #GParamSpecInt might require + * that integers stored in @value may not be smaller than -42 and not be + * greater than +42. If @value contains an integer outside of this range, + * it is modified accordingly, so the resulting value will fit into the + * range -42 .. +42. + * + * Returns: whether modifying @value was necessary to ensure validity + */ +gboolean +g_param_value_validate (GParamSpec *pspec, + GValue *value) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); + g_return_val_if_fail (G_IS_VALUE (value), FALSE); + g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value), FALSE); + + if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate) + { + GValue oval = *value; + + if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate (pspec, value) || + memcmp (&oval.data, &value->data, sizeof (oval.data))) + return TRUE; + } + + return FALSE; +} + +/** + * g_param_value_convert: + * @pspec: a valid #GParamSpec + * @src_value: source #GValue + * @dest_value: destination #GValue of correct type for @pspec + * @strict_validation: %TRUE requires @dest_value to conform to @pspec + * without modifications + * + * Transforms @src_value into @dest_value if possible, and then + * validates @dest_value, in order for it to conform to @pspec. If + * @strict_validation is %TRUE this function will only succeed if the + * transformed @dest_value complied to @pspec without modifications. + * + * See also g_value_type_transformable(), g_value_transform() and + * g_param_value_validate(). + * + * Returns: %TRUE if transformation and validation were successful, + * %FALSE otherwise and @dest_value is left untouched. + */ +gboolean +g_param_value_convert (GParamSpec *pspec, + const GValue *src_value, + GValue *dest_value, + gboolean strict_validation) +{ + GValue tmp_value = G_VALUE_INIT; + + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); + g_return_val_if_fail (G_IS_VALUE (src_value), FALSE); + g_return_val_if_fail (G_IS_VALUE (dest_value), FALSE); + g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, dest_value), FALSE); + + /* better leave dest_value untouched when returning FALSE */ + + g_value_init (&tmp_value, G_VALUE_TYPE (dest_value)); + if (g_value_transform (src_value, &tmp_value) && + (!g_param_value_validate (pspec, &tmp_value) || !strict_validation)) + { + g_value_unset (dest_value); + + /* values are relocatable */ + memcpy (dest_value, &tmp_value, sizeof (tmp_value)); + + return TRUE; + } + else + { + g_value_unset (&tmp_value); + + return FALSE; + } +} + +/** + * g_param_values_cmp: + * @pspec: a valid #GParamSpec + * @value1: a #GValue of correct type for @pspec + * @value2: a #GValue of correct type for @pspec + * + * Compares @value1 with @value2 according to @pspec, and return -1, 0 or +1, + * if @value1 is found to be less than, equal to or greater than @value2, + * respectively. + * + * Returns: -1, 0 or +1, for a less than, equal to or greater than result + */ +gint +g_param_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + gint cmp; + + /* param_values_cmp() effectively does: value1 - value2 + * so the return values are: + * -1) value1 < value2 + * 0) value1 == value2 + * 1) value1 > value2 + */ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0); + g_return_val_if_fail (G_IS_VALUE (value1), 0); + g_return_val_if_fail (G_IS_VALUE (value2), 0); + g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value1), 0); + g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value2), 0); + + cmp = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value1, value2); + + return CLAMP (cmp, -1, 1); +} + +static void +value_param_init (GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static void +value_param_free_value (GValue *value) +{ + if (value->data[0].v_pointer) + g_param_spec_unref (value->data[0].v_pointer); +} + +static void +value_param_copy_value (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[0].v_pointer) + dest_value->data[0].v_pointer = g_param_spec_ref (src_value->data[0].v_pointer); + else + dest_value->data[0].v_pointer = NULL; +} + +static void +value_param_transform_value (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[0].v_pointer && + g_type_is_a (G_PARAM_SPEC_TYPE (dest_value->data[0].v_pointer), G_VALUE_TYPE (dest_value))) + dest_value->data[0].v_pointer = g_param_spec_ref (src_value->data[0].v_pointer); + else + dest_value->data[0].v_pointer = NULL; +} + +static gpointer +value_param_peek_pointer (const GValue *value) +{ + return value->data[0].v_pointer; +} + +static gchar* +value_param_collect_value (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + if (collect_values[0].v_pointer) + { + GParamSpec *param = collect_values[0].v_pointer; + + if (param->g_type_instance.g_class == NULL) + return g_strconcat ("invalid unclassed param spec pointer for value type '", + G_VALUE_TYPE_NAME (value), + "'", + NULL); + else if (!g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_VALUE_TYPE (value))) + return g_strconcat ("invalid param spec type '", + G_PARAM_SPEC_TYPE_NAME (param), + "' for value type '", + G_VALUE_TYPE_NAME (value), + "'", + NULL); + value->data[0].v_pointer = g_param_spec_ref (param); + } + else + value->data[0].v_pointer = NULL; + + return NULL; +} + +static gchar* +value_param_lcopy_value (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + GParamSpec **param_p = collect_values[0].v_pointer; + + g_return_val_if_fail (param_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + if (!value->data[0].v_pointer) + *param_p = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + *param_p = value->data[0].v_pointer; + else + *param_p = g_param_spec_ref (value->data[0].v_pointer); + + return NULL; +} + + +/* --- param spec pool --- */ +/** + * GParamSpecPool: + * + * A #GParamSpecPool maintains a collection of #GParamSpecs which can be + * quickly accessed by owner and name. + * + * The implementation of the #GObject property system uses such a pool to + * store the #GParamSpecs of the properties all object types. + */ +struct _GParamSpecPool +{ + GMutex mutex; + gboolean type_prefixing; + GHashTable *hash_table; +}; + +static guint +param_spec_pool_hash (gconstpointer key_spec) +{ + const GParamSpec *key = key_spec; + const gchar *p; + guint h = key->owner_type; + + for (p = key->name; *p; p++) + h = (h << 5) - h + *p; + + return h; +} + +static gboolean +param_spec_pool_equals (gconstpointer key_spec_1, + gconstpointer key_spec_2) +{ + const GParamSpec *key1 = key_spec_1; + const GParamSpec *key2 = key_spec_2; + + return (key1->owner_type == key2->owner_type && + strcmp (key1->name, key2->name) == 0); +} + +/** + * g_param_spec_pool_new: + * @type_prefixing: Whether the pool will support type-prefixed property names. + * + * Creates a new #GParamSpecPool. + * + * If @type_prefixing is %TRUE, lookups in the newly created pool will + * allow to specify the owner as a colon-separated prefix of the + * property name, like "GtkContainer:border-width". This feature is + * deprecated, so you should always set @type_prefixing to %FALSE. + * + * Returns: (transfer full): a newly allocated #GParamSpecPool. + */ +GParamSpecPool* +g_param_spec_pool_new (gboolean type_prefixing) +{ + static GMutex init_mutex; + GParamSpecPool *pool = g_new (GParamSpecPool, 1); + + memcpy (&pool->mutex, &init_mutex, sizeof (init_mutex)); + pool->type_prefixing = type_prefixing != FALSE; + pool->hash_table = g_hash_table_new (param_spec_pool_hash, param_spec_pool_equals); + + return pool; +} + +/** + * g_param_spec_pool_insert: + * @pool: a #GParamSpecPool. + * @pspec: (transfer none) (not nullable): the #GParamSpec to insert + * @owner_type: a #GType identifying the owner of @pspec + * + * Inserts a #GParamSpec in the pool. + */ +void +g_param_spec_pool_insert (GParamSpecPool *pool, + GParamSpec *pspec, + GType owner_type) +{ + const gchar *p; + + if (pool && pspec && owner_type > 0 && pspec->owner_type == 0) + { + for (p = pspec->name; *p; p++) + { + if (!strchr (G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_", *p)) + { + g_warning (G_STRLOC ": pspec name \"%s\" contains invalid characters", pspec->name); + return; + } + } + g_mutex_lock (&pool->mutex); + pspec->owner_type = owner_type; + g_param_spec_ref (pspec); + g_hash_table_add (pool->hash_table, pspec); + g_mutex_unlock (&pool->mutex); + } + else + { + g_return_if_fail (pool != NULL); + g_return_if_fail (pspec); + g_return_if_fail (owner_type > 0); + g_return_if_fail (pspec->owner_type == 0); + } +} + +/** + * g_param_spec_pool_remove: + * @pool: a #GParamSpecPool + * @pspec: (transfer none) (not nullable): the #GParamSpec to remove + * + * Removes a #GParamSpec from the pool. + */ +void +g_param_spec_pool_remove (GParamSpecPool *pool, + GParamSpec *pspec) +{ + if (pool && pspec) + { + g_mutex_lock (&pool->mutex); + if (g_hash_table_remove (pool->hash_table, pspec)) + g_param_spec_unref (pspec); + else + g_warning (G_STRLOC ": attempt to remove unknown pspec '%s' from pool", pspec->name); + g_mutex_unlock (&pool->mutex); + } + else + { + g_return_if_fail (pool != NULL); + g_return_if_fail (pspec); + } +} + +static inline GParamSpec* +param_spec_ht_lookup (GHashTable *hash_table, + const gchar *param_name, + GType owner_type, + gboolean walk_ancestors) +{ + GParamSpec key, *pspec; + + key.owner_type = owner_type; + key.name = (gchar*) param_name; + if (walk_ancestors) + do + { + pspec = g_hash_table_lookup (hash_table, &key); + if (pspec) + return pspec; + key.owner_type = g_type_parent (key.owner_type); + } + while (key.owner_type); + else + pspec = g_hash_table_lookup (hash_table, &key); + + if (!pspec && !is_canonical (param_name)) + { + gchar *canonical; + + canonical = g_strdup (key.name); + canonicalize_key (canonical); + + /* try canonicalized form */ + key.name = canonical; + key.owner_type = owner_type; + + if (walk_ancestors) + do + { + pspec = g_hash_table_lookup (hash_table, &key); + if (pspec) + { + g_free (canonical); + return pspec; + } + key.owner_type = g_type_parent (key.owner_type); + } + while (key.owner_type); + else + pspec = g_hash_table_lookup (hash_table, &key); + + g_free (canonical); + } + + return pspec; +} + +/** + * g_param_spec_pool_lookup: + * @pool: a #GParamSpecPool + * @param_name: the name to look for + * @owner_type: the owner to look for + * @walk_ancestors: If %TRUE, also try to find a #GParamSpec with @param_name + * owned by an ancestor of @owner_type. + * + * Looks up a #GParamSpec in the pool. + * + * Returns: (transfer none) (nullable): The found #GParamSpec, or %NULL if no + * matching #GParamSpec was found. + */ +GParamSpec* +g_param_spec_pool_lookup (GParamSpecPool *pool, + const gchar *param_name, + GType owner_type, + gboolean walk_ancestors) +{ + GParamSpec *pspec; + gchar *delim; + + g_return_val_if_fail (pool != NULL, NULL); + g_return_val_if_fail (param_name != NULL, NULL); + + g_mutex_lock (&pool->mutex); + + delim = pool->type_prefixing ? strchr (param_name, ':') : NULL; + + /* try quick and away, i.e. without prefix */ + if (!delim) + { + pspec = param_spec_ht_lookup (pool->hash_table, param_name, owner_type, walk_ancestors); + g_mutex_unlock (&pool->mutex); + + return pspec; + } + + /* strip type prefix */ + if (pool->type_prefixing && delim[1] == ':') + { + guint l = delim - param_name; + gchar stack_buffer[32], *buffer = l < 32 ? stack_buffer : g_new (gchar, l + 1); + GType type; + + strncpy (buffer, param_name, delim - param_name); + buffer[l] = 0; + type = g_type_from_name (buffer); + if (l >= 32) + g_free (buffer); + if (type) /* type==0 isn't a valid type pefix */ + { + /* sanity check, these cases don't make a whole lot of sense */ + if ((!walk_ancestors && type != owner_type) || !g_type_is_a (owner_type, type)) + { + g_mutex_unlock (&pool->mutex); + + return NULL; + } + owner_type = type; + param_name += l + 2; + pspec = param_spec_ht_lookup (pool->hash_table, param_name, owner_type, walk_ancestors); + g_mutex_unlock (&pool->mutex); + + return pspec; + } + } + /* malformed param_name */ + + g_mutex_unlock (&pool->mutex); + + return NULL; +} + +static void +pool_list (gpointer key, + gpointer value, + gpointer user_data) +{ + GParamSpec *pspec = value; + gpointer *data = user_data; + GType owner_type = (GType) data[1]; + + if (owner_type == pspec->owner_type) + data[0] = g_list_prepend (data[0], pspec); +} + +/** + * g_param_spec_pool_list_owned: + * @pool: a #GParamSpecPool + * @owner_type: the owner to look for + * + * Gets an #GList of all #GParamSpecs owned by @owner_type in + * the pool. + * + * Returns: (transfer container) (element-type GObject.ParamSpec): a + * #GList of all #GParamSpecs owned by @owner_type in + * the pool#GParamSpecs. + */ +GList* +g_param_spec_pool_list_owned (GParamSpecPool *pool, + GType owner_type) +{ + gpointer data[2]; + + g_return_val_if_fail (pool != NULL, NULL); + g_return_val_if_fail (owner_type > 0, NULL); + + g_mutex_lock (&pool->mutex); + data[0] = NULL; + data[1] = (gpointer) owner_type; + g_hash_table_foreach (pool->hash_table, pool_list, &data); + g_mutex_unlock (&pool->mutex); + + return data[0]; +} + +static gint +pspec_compare_id (gconstpointer a, + gconstpointer b) +{ + const GParamSpec *pspec1 = a, *pspec2 = b; + + if (pspec1->param_id < pspec2->param_id) + return -1; + + if (pspec1->param_id > pspec2->param_id) + return 1; + + return strcmp (pspec1->name, pspec2->name); +} + +static inline gboolean +should_list_pspec (GParamSpec *pspec, + GType owner_type, + GHashTable *ht) +{ + GParamSpec *found; + + /* Remove paramspecs that are redirected, and also paramspecs + * that have are overridden by non-redirected properties. + * The idea is to get the single paramspec for each name that + * best corresponds to what the application sees. + */ + if (g_param_spec_get_redirect_target (pspec)) + return FALSE; + + found = param_spec_ht_lookup (ht, pspec->name, owner_type, TRUE); + if (found != pspec) + { + GParamSpec *redirect = g_param_spec_get_redirect_target (found); + if (redirect != pspec) + return FALSE; + } + + return TRUE; +} + +static void +pool_depth_list (gpointer key, + gpointer value, + gpointer user_data) +{ + GParamSpec *pspec = value; + gpointer *data = user_data; + GSList **slists = data[0]; + GType owner_type = (GType) data[1]; + GHashTable *ht = data[2]; + int *count = data[3]; + + if (g_type_is_a (owner_type, pspec->owner_type) && + should_list_pspec (pspec, owner_type, ht)) + { + if (G_TYPE_IS_INTERFACE (pspec->owner_type)) + { + slists[0] = g_slist_prepend (slists[0], pspec); + *count = *count + 1; + } + else + { + guint d = g_type_depth (pspec->owner_type); + + slists[d - 1] = g_slist_prepend (slists[d - 1], pspec); + *count = *count + 1; + } + } +} + +/* We handle interfaces specially since we don't want to + * count interface prerequisites like normal inheritance; + * the property comes from the direct inheritance from + * the prerequisite class, not from the interface that + * prerequires it. + * + * also 'depth' isn't a meaningful concept for interface + * prerequites. + */ +static void +pool_depth_list_for_interface (gpointer key, + gpointer value, + gpointer user_data) +{ + GParamSpec *pspec = value; + gpointer *data = user_data; + GSList **slists = data[0]; + GType owner_type = (GType) data[1]; + GHashTable *ht = data[2]; + int *count = data[3]; + + if (pspec->owner_type == owner_type && + should_list_pspec (pspec, owner_type, ht)) + { + slists[0] = g_slist_prepend (slists[0], pspec); + *count = *count + 1; + } +} + +/** + * g_param_spec_pool_list: + * @pool: a #GParamSpecPool + * @owner_type: the owner to look for + * @n_pspecs_p: (out): return location for the length of the returned array + * + * Gets an array of all #GParamSpecs owned by @owner_type in + * the pool. + * + * Returns: (array length=n_pspecs_p) (transfer container): a newly + * allocated array containing pointers to all #GParamSpecs + * owned by @owner_type in the pool + */ +GParamSpec** +g_param_spec_pool_list (GParamSpecPool *pool, + GType owner_type, + guint *n_pspecs_p) +{ + GParamSpec **pspecs, **p; + GSList **slists, *node; + gpointer data[4]; + guint d, i; + int n_pspecs = 0; + + g_return_val_if_fail (pool != NULL, NULL); + g_return_val_if_fail (owner_type > 0, NULL); + g_return_val_if_fail (n_pspecs_p != NULL, NULL); + + g_mutex_lock (&pool->mutex); + d = g_type_depth (owner_type); + slists = g_new0 (GSList*, d); + data[0] = slists; + data[1] = (gpointer) owner_type; + data[2] = pool->hash_table; + data[3] = &n_pspecs; + + g_hash_table_foreach (pool->hash_table, + G_TYPE_IS_INTERFACE (owner_type) ? + pool_depth_list_for_interface : + pool_depth_list, + &data); + + pspecs = g_new (GParamSpec*, n_pspecs + 1); + p = pspecs; + for (i = 0; i < d; i++) + { + slists[i] = g_slist_sort (slists[i], pspec_compare_id); + for (node = slists[i]; node; node = node->next) + *p++ = node->data; + g_slist_free (slists[i]); + } + *p++ = NULL; + g_free (slists); + g_mutex_unlock (&pool->mutex); + + *n_pspecs_p = n_pspecs; + + return pspecs; +} + +/* --- auxiliary functions --- */ +typedef struct +{ + /* class portion */ + GType value_type; + void (*finalize) (GParamSpec *pspec); + void (*value_set_default) (GParamSpec *pspec, + GValue *value); + gboolean (*value_validate) (GParamSpec *pspec, + GValue *value); + gint (*values_cmp) (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); +} ParamSpecClassInfo; + +static void +param_spec_generic_class_init (gpointer g_class, + gpointer class_data) +{ + GParamSpecClass *class = g_class; + ParamSpecClassInfo *info = class_data; + + class->value_type = info->value_type; + if (info->finalize) + class->finalize = info->finalize; /* optional */ + class->value_set_default = info->value_set_default; + if (info->value_validate) + class->value_validate = info->value_validate; /* optional */ + class->values_cmp = info->values_cmp; + g_free (class_data); +} + +static void +default_value_set_default (GParamSpec *pspec, + GValue *value) +{ + /* value is already zero initialized */ +} + +static gint +default_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + return memcmp (&value1->data, &value2->data, sizeof (value1->data)); +} + +/** + * g_param_type_register_static: + * @name: 0-terminated string used as the name of the new #GParamSpec type. + * @pspec_info: The #GParamSpecTypeInfo for this #GParamSpec type. + * + * Registers @name as the name of a new static type derived + * from %G_TYPE_PARAM. + * + * The type system uses the information contained in the #GParamSpecTypeInfo + * structure pointed to by @info to manage the #GParamSpec type and its + * instances. + * + * Returns: The new type identifier. + */ +GType +g_param_type_register_static (const gchar *name, + const GParamSpecTypeInfo *pspec_info) +{ + GTypeInfo info = { + sizeof (GParamSpecClass), /* class_size */ + NULL, /* base_init */ + NULL, /* base_destroy */ + param_spec_generic_class_init, /* class_init */ + NULL, /* class_destroy */ + NULL, /* class_data */ + 0, /* instance_size */ + 16, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + ParamSpecClassInfo *cinfo; + + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (pspec_info != NULL, 0); + g_return_val_if_fail (g_type_from_name (name) == 0, 0); + g_return_val_if_fail (pspec_info->instance_size >= sizeof (GParamSpec), 0); + g_return_val_if_fail (g_type_name (pspec_info->value_type) != NULL, 0); + /* default: g_return_val_if_fail (pspec_info->value_set_default != NULL, 0); */ + /* optional: g_return_val_if_fail (pspec_info->value_validate != NULL, 0); */ + /* default: g_return_val_if_fail (pspec_info->values_cmp != NULL, 0); */ + + info.instance_size = pspec_info->instance_size; + info.n_preallocs = pspec_info->n_preallocs; + info.instance_init = (GInstanceInitFunc) pspec_info->instance_init; + cinfo = g_new (ParamSpecClassInfo, 1); + cinfo->value_type = pspec_info->value_type; + cinfo->finalize = pspec_info->finalize; + cinfo->value_set_default = pspec_info->value_set_default ? pspec_info->value_set_default : default_value_set_default; + cinfo->value_validate = pspec_info->value_validate; + cinfo->values_cmp = pspec_info->values_cmp ? pspec_info->values_cmp : default_values_cmp; + info.class_data = cinfo; + + return g_type_register_static (G_TYPE_PARAM, name, &info, 0); +} + +/** + * g_value_set_param: + * @value: a valid #GValue of type %G_TYPE_PARAM + * @param: (nullable): the #GParamSpec to be set + * + * Set the contents of a %G_TYPE_PARAM #GValue to @param. + */ +void +g_value_set_param (GValue *value, + GParamSpec *param) +{ + g_return_if_fail (G_VALUE_HOLDS_PARAM (value)); + if (param) + g_return_if_fail (G_IS_PARAM_SPEC (param)); + + if (value->data[0].v_pointer) + g_param_spec_unref (value->data[0].v_pointer); + value->data[0].v_pointer = param; + if (value->data[0].v_pointer) + g_param_spec_ref (value->data[0].v_pointer); +} + +/** + * g_value_set_param_take_ownership: (skip) + * @value: a valid #GValue of type %G_TYPE_PARAM + * @param: (nullable): the #GParamSpec to be set + * + * This is an internal function introduced mainly for C marshallers. + * + * Deprecated: 2.4: Use g_value_take_param() instead. + */ +void +g_value_set_param_take_ownership (GValue *value, + GParamSpec *param) +{ + g_value_take_param (value, param); +} + +/** + * g_value_take_param: (skip) + * @value: a valid #GValue of type %G_TYPE_PARAM + * @param: (nullable): the #GParamSpec to be set + * + * Sets the contents of a %G_TYPE_PARAM #GValue to @param and takes + * over the ownership of the caller’s reference to @param; the caller + * doesn’t have to unref it any more. + * + * Since: 2.4 + */ +void +g_value_take_param (GValue *value, + GParamSpec *param) +{ + g_return_if_fail (G_VALUE_HOLDS_PARAM (value)); + if (param) + g_return_if_fail (G_IS_PARAM_SPEC (param)); + + if (value->data[0].v_pointer) + g_param_spec_unref (value->data[0].v_pointer); + value->data[0].v_pointer = param; /* we take over the reference count */ +} + +/** + * g_value_get_param: + * @value: a valid #GValue whose type is derived from %G_TYPE_PARAM + * + * Get the contents of a %G_TYPE_PARAM #GValue. + * + * Returns: (transfer none): #GParamSpec content of @value + */ +GParamSpec* +g_value_get_param (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_PARAM (value), NULL); + + return value->data[0].v_pointer; +} + +/** + * g_value_dup_param: (skip) + * @value: a valid #GValue whose type is derived from %G_TYPE_PARAM + * + * Get the contents of a %G_TYPE_PARAM #GValue, increasing its + * reference count. + * + * Returns: (transfer full): #GParamSpec content of @value, should be + * unreferenced when no longer needed. + */ +GParamSpec* +g_value_dup_param (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_PARAM (value), NULL); + + return value->data[0].v_pointer ? g_param_spec_ref (value->data[0].v_pointer) : NULL; +} + +/** + * g_param_spec_get_default_value: + * @pspec: a #GParamSpec + * + * Gets the default value of @pspec as a pointer to a #GValue. + * + * The #GValue will remain valid for the life of @pspec. + * + * Returns: a pointer to a #GValue which must not be modified + * + * Since: 2.38 + **/ +const GValue * +g_param_spec_get_default_value (GParamSpec *pspec) +{ + GParamSpecPrivate *priv = g_param_spec_get_private (pspec); + + /* We use the type field of the GValue as the key for the once because + * it will be zero before it is initialised and non-zero after. We + * have to take care that we don't write a non-zero value to the type + * field before we are completely done, however, because then another + * thread could come along and find the value partially-initialised. + * + * In order to accomplish this we store the default value in a + * stack-allocated GValue. We then set the type field in that value + * to zero and copy the contents into place. We then end by storing + * the type as the last step in order to ensure that we're completely + * done before a g_once_init_enter() could take the fast path in + * another thread. + */ + if (g_once_init_enter (&priv->default_value.g_type)) + { + GValue default_value = G_VALUE_INIT; + + g_value_init (&default_value, pspec->value_type); + g_param_value_set_default (pspec, &default_value); + + /* store all but the type */ + memcpy (priv->default_value.data, default_value.data, sizeof (default_value.data)); + + g_once_init_leave (&priv->default_value.g_type, pspec->value_type); + } + + return &priv->default_value; +} + +/** + * g_param_spec_get_name_quark: + * @pspec: a #GParamSpec + * + * Gets the GQuark for the name. + * + * Returns: the GQuark for @pspec->name. + * + * Since: 2.46 + */ +GQuark +g_param_spec_get_name_quark (GParamSpec *pspec) +{ + GParamSpecPrivate *priv = g_param_spec_get_private (pspec); + + /* Return the quark that we've stashed away at creation time. + * This lets us avoid a lock and a hash table lookup when + * dispatching property change notification. + */ + + return priv->name_quark; +} diff --git a/gobject/gparam.h b/gobject/gparam.h new file mode 100644 index 0000000..e0f3166 --- /dev/null +++ b/gobject/gparam.h @@ -0,0 +1,458 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * gparam.h: GParamSpec base class implementation + */ +#ifndef __G_PARAM_H__ +#define __G_PARAM_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* --- standard type macros --- */ +/** + * G_TYPE_IS_PARAM: + * @type: a #GType ID + * + * Checks whether @type "is a" %G_TYPE_PARAM. + */ +#define G_TYPE_IS_PARAM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_PARAM) +/** + * G_PARAM_SPEC: + * @pspec: a valid #GParamSpec + * + * Casts a derived #GParamSpec object (e.g. of type #GParamSpecInt) into + * a #GParamSpec object. + */ +#define G_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM, GParamSpec)) +/** + * G_IS_PARAM_SPEC: + * @pspec: a #GParamSpec + * + * Checks whether @pspec "is a" valid #GParamSpec structure of type %G_TYPE_PARAM + * or derived. + */ +#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_42 +#define G_IS_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE ((pspec), G_TYPE_PARAM)) +#else +#define G_IS_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM)) +#endif +/** + * G_PARAM_SPEC_CLASS: + * @pclass: a valid #GParamSpecClass + * + * Casts a derived #GParamSpecClass structure into a #GParamSpecClass structure. + */ +#define G_PARAM_SPEC_CLASS(pclass) (G_TYPE_CHECK_CLASS_CAST ((pclass), G_TYPE_PARAM, GParamSpecClass)) +/** + * G_IS_PARAM_SPEC_CLASS: + * @pclass: a #GParamSpecClass + * + * Checks whether @pclass "is a" valid #GParamSpecClass structure of type + * %G_TYPE_PARAM or derived. + */ +#define G_IS_PARAM_SPEC_CLASS(pclass) (G_TYPE_CHECK_CLASS_TYPE ((pclass), G_TYPE_PARAM)) +/** + * G_PARAM_SPEC_GET_CLASS: + * @pspec: a valid #GParamSpec + * + * Retrieves the #GParamSpecClass of a #GParamSpec. + */ +#define G_PARAM_SPEC_GET_CLASS(pspec) (G_TYPE_INSTANCE_GET_CLASS ((pspec), G_TYPE_PARAM, GParamSpecClass)) + + +/* --- convenience macros --- */ +/** + * G_PARAM_SPEC_TYPE: + * @pspec: a valid #GParamSpec + * + * Retrieves the #GType of this @pspec. + */ +#define G_PARAM_SPEC_TYPE(pspec) (G_TYPE_FROM_INSTANCE (pspec)) +/** + * G_PARAM_SPEC_TYPE_NAME: + * @pspec: a valid #GParamSpec + * + * Retrieves the #GType name of this @pspec. + */ +#define G_PARAM_SPEC_TYPE_NAME(pspec) (g_type_name (G_PARAM_SPEC_TYPE (pspec))) +/** + * G_PARAM_SPEC_VALUE_TYPE: + * @pspec: a valid #GParamSpec + * + * Retrieves the #GType to initialize a #GValue for this parameter. + */ +#define G_PARAM_SPEC_VALUE_TYPE(pspec) (G_PARAM_SPEC (pspec)->value_type) +/** + * G_VALUE_HOLDS_PARAM: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values derived from type %G_TYPE_PARAM. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_PARAM(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_PARAM)) + + +/* --- flags --- */ +/** + * GParamFlags: + * @G_PARAM_READABLE: the parameter is readable + * @G_PARAM_WRITABLE: the parameter is writable + * @G_PARAM_READWRITE: alias for %G_PARAM_READABLE | %G_PARAM_WRITABLE + * @G_PARAM_CONSTRUCT: the parameter will be set upon object construction + * @G_PARAM_CONSTRUCT_ONLY: the parameter can only be set upon object construction + * @G_PARAM_LAX_VALIDATION: upon parameter conversion (see g_param_value_convert()) + * strict validation is not required + * @G_PARAM_STATIC_NAME: the string used as name when constructing the + * parameter is guaranteed to remain valid and + * unmodified for the lifetime of the parameter. + * Since 2.8 + * @G_PARAM_STATIC_NICK: the string used as nick when constructing the + * parameter is guaranteed to remain valid and + * unmmodified for the lifetime of the parameter. + * Since 2.8 + * @G_PARAM_STATIC_BLURB: the string used as blurb when constructing the + * parameter is guaranteed to remain valid and + * unmodified for the lifetime of the parameter. + * Since 2.8 + * @G_PARAM_EXPLICIT_NOTIFY: calls to g_object_set_property() for this + * property will not automatically result in a "notify" signal being + * emitted: the implementation must call g_object_notify() themselves + * in case the property actually changes. Since: 2.42. + * @G_PARAM_PRIVATE: internal + * @G_PARAM_DEPRECATED: the parameter is deprecated and will be removed + * in a future version. A warning will be generated if it is used + * while running with G_ENABLE_DIAGNOSTIC=1. + * Since 2.26 + * + * Through the #GParamFlags flag values, certain aspects of parameters + * can be configured. + * + * See also: %G_PARAM_STATIC_STRINGS + */ +typedef enum +{ + G_PARAM_READABLE = 1 << 0, + G_PARAM_WRITABLE = 1 << 1, + G_PARAM_READWRITE = (G_PARAM_READABLE | G_PARAM_WRITABLE), + G_PARAM_CONSTRUCT = 1 << 2, + G_PARAM_CONSTRUCT_ONLY = 1 << 3, + G_PARAM_LAX_VALIDATION = 1 << 4, + G_PARAM_STATIC_NAME = 1 << 5, + G_PARAM_PRIVATE GLIB_DEPRECATED_ENUMERATOR_IN_2_26 = G_PARAM_STATIC_NAME, + G_PARAM_STATIC_NICK = 1 << 6, + G_PARAM_STATIC_BLURB = 1 << 7, + /* User defined flags go here */ + G_PARAM_EXPLICIT_NOTIFY = 1 << 30, + /* Avoid warning with -Wpedantic for gcc6 */ + G_PARAM_DEPRECATED = (gint)(1u << 31) +} GParamFlags; + +/** + * G_PARAM_STATIC_STRINGS: + * + * #GParamFlags value alias for %G_PARAM_STATIC_NAME | %G_PARAM_STATIC_NICK | %G_PARAM_STATIC_BLURB. + * + * Since 2.13.0 + */ +#define G_PARAM_STATIC_STRINGS (G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB) +/* bits in the range 0xffffff00 are reserved for 3rd party usage */ +/** + * G_PARAM_MASK: + * + * Mask containing the bits of #GParamSpec.flags which are reserved for GLib. + */ +#define G_PARAM_MASK (0x000000ff) +/** + * G_PARAM_USER_SHIFT: + * + * Minimum shift count to be used for user defined flags, to be stored in + * #GParamSpec.flags. The maximum allowed is 10. + */ +#define G_PARAM_USER_SHIFT (8) + +/* --- typedefs & structures --- */ +typedef struct _GParamSpec GParamSpec; +typedef struct _GParamSpecClass GParamSpecClass; +typedef struct _GParameter GParameter GLIB_DEPRECATED_TYPE_IN_2_54; +typedef struct _GParamSpecPool GParamSpecPool; +/** + * GParamSpec: (ref-func g_param_spec_ref_sink) (unref-func g_param_spec_unref) (set-value-func g_value_set_param) (get-value-func g_value_get_param) + * @g_type_instance: private #GTypeInstance portion + * @name: name of this parameter: always an interned string + * @flags: #GParamFlags flags for this parameter + * @value_type: the #GValue type for this parameter + * @owner_type: #GType type that uses (introduces) this parameter + * + * All other fields of the GParamSpec struct are private and + * should not be used directly. + */ +struct _GParamSpec +{ + GTypeInstance g_type_instance; + + const gchar *name; /* interned string */ + GParamFlags flags; + GType value_type; + GType owner_type; /* class or interface using this property */ + + /*< private >*/ + gchar *_nick; + gchar *_blurb; + GData *qdata; + guint ref_count; + guint param_id; /* sort-criteria */ +}; +/** + * GParamSpecClass: + * @g_type_class: the parent class + * @value_type: the #GValue type for this parameter + * @finalize: The instance finalization function (optional), should chain + * up to the finalize method of the parent class. + * @value_set_default: Resets a @value to the default value for this type + * (recommended, the default is g_value_reset()), see + * g_param_value_set_default(). + * @value_validate: Ensures that the contents of @value comply with the + * specifications set out by this type (optional), see + * g_param_value_validate(). + * @values_cmp: Compares @value1 with @value2 according to this type + * (recommended, the default is memcmp()), see g_param_values_cmp(). + * + * The class structure for the GParamSpec type. + * Normally, GParamSpec classes are filled by + * g_param_type_register_static(). + */ +struct _GParamSpecClass +{ + GTypeClass g_type_class; + + GType value_type; + + void (*finalize) (GParamSpec *pspec); + + /* GParam methods */ + void (*value_set_default) (GParamSpec *pspec, + GValue *value); + gboolean (*value_validate) (GParamSpec *pspec, + GValue *value); + gint (*values_cmp) (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); + /*< private >*/ + gpointer dummy[4]; +}; +/** + * GParameter: + * @name: the parameter name + * @value: the parameter value + * + * The GParameter struct is an auxiliary structure used + * to hand parameter name/value pairs to g_object_newv(). + * + * Deprecated: 2.54: This type is not introspectable. + */ +struct _GParameter /* auxiliary structure for _setv() variants */ +{ + const gchar *name; + GValue value; +} GLIB_DEPRECATED_TYPE_IN_2_54; + + +/* --- prototypes --- */ +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_ref (GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +void g_param_spec_unref (GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +void g_param_spec_sink (GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_ref_sink (GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +gpointer g_param_spec_get_qdata (GParamSpec *pspec, + GQuark quark); +GLIB_AVAILABLE_IN_ALL +void g_param_spec_set_qdata (GParamSpec *pspec, + GQuark quark, + gpointer data); +GLIB_AVAILABLE_IN_ALL +void g_param_spec_set_qdata_full (GParamSpec *pspec, + GQuark quark, + gpointer data, + GDestroyNotify destroy); +GLIB_AVAILABLE_IN_ALL +gpointer g_param_spec_steal_qdata (GParamSpec *pspec, + GQuark quark); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_get_redirect_target (GParamSpec *pspec); + +GLIB_AVAILABLE_IN_ALL +void g_param_value_set_default (GParamSpec *pspec, + GValue *value); +GLIB_AVAILABLE_IN_ALL +gboolean g_param_value_defaults (GParamSpec *pspec, + const GValue *value); +GLIB_AVAILABLE_IN_ALL +gboolean g_param_value_validate (GParamSpec *pspec, + GValue *value); +GLIB_AVAILABLE_IN_ALL +gboolean g_param_value_convert (GParamSpec *pspec, + const GValue *src_value, + GValue *dest_value, + gboolean strict_validation); +GLIB_AVAILABLE_IN_ALL +gint g_param_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); +GLIB_AVAILABLE_IN_ALL +const gchar * g_param_spec_get_name (GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +const gchar * g_param_spec_get_nick (GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +const gchar * g_param_spec_get_blurb (GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +void g_value_set_param (GValue *value, + GParamSpec *param); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_value_get_param (const GValue *value); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_value_dup_param (const GValue *value); + + +GLIB_AVAILABLE_IN_ALL +void g_value_take_param (GValue *value, + GParamSpec *param); +GLIB_DEPRECATED_FOR(g_value_take_param) +void g_value_set_param_take_ownership (GValue *value, + GParamSpec *param); +GLIB_AVAILABLE_IN_2_36 +const GValue * g_param_spec_get_default_value (GParamSpec *pspec); + +GLIB_AVAILABLE_IN_2_46 +GQuark g_param_spec_get_name_quark (GParamSpec *pspec); + +/* --- convenience functions --- */ +typedef struct _GParamSpecTypeInfo GParamSpecTypeInfo; +/** + * GParamSpecTypeInfo: + * @instance_size: Size of the instance (object) structure. + * @n_preallocs: Prior to GLib 2.10, it specified the number of pre-allocated (cached) instances to reserve memory for (0 indicates no caching). Since GLib 2.10, it is ignored, since instances are allocated with the [slice allocator][glib-Memory-Slices] now. + * @instance_init: Location of the instance initialization function (optional). + * @value_type: The #GType of values conforming to this #GParamSpec + * @finalize: The instance finalization function (optional). + * @value_set_default: Resets a @value to the default value for @pspec + * (recommended, the default is g_value_reset()), see + * g_param_value_set_default(). + * @value_validate: Ensures that the contents of @value comply with the + * specifications set out by @pspec (optional), see + * g_param_value_validate(). + * @values_cmp: Compares @value1 with @value2 according to @pspec + * (recommended, the default is memcmp()), see g_param_values_cmp(). + * + * This structure is used to provide the type system with the information + * required to initialize and destruct (finalize) a parameter's class and + * instances thereof. + * + * The initialized structure is passed to the g_param_type_register_static() + * The type system will perform a deep copy of this structure, so its memory + * does not need to be persistent across invocation of + * g_param_type_register_static(). + */ +struct _GParamSpecTypeInfo +{ + /* type system portion */ + guint16 instance_size; /* obligatory */ + guint16 n_preallocs; /* optional */ + void (*instance_init) (GParamSpec *pspec); /* optional */ + + /* class portion */ + GType value_type; /* obligatory */ + void (*finalize) (GParamSpec *pspec); /* optional */ + void (*value_set_default) (GParamSpec *pspec, /* recommended */ + GValue *value); + gboolean (*value_validate) (GParamSpec *pspec, /* optional */ + GValue *value); + gint (*values_cmp) (GParamSpec *pspec, /* recommended */ + const GValue *value1, + const GValue *value2); +}; +GLIB_AVAILABLE_IN_ALL +GType g_param_type_register_static (const gchar *name, + const GParamSpecTypeInfo *pspec_info); + +GLIB_AVAILABLE_IN_2_66 +gboolean g_param_spec_is_valid_name (const gchar *name); + +/* For registering builting types */ +GType _g_param_type_register_static_constant (const gchar *name, + const GParamSpecTypeInfo *pspec_info, + GType opt_type); + + +/* --- protected --- */ +GLIB_AVAILABLE_IN_ALL +gpointer g_param_spec_internal (GType param_type, + const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpecPool* g_param_spec_pool_new (gboolean type_prefixing); +GLIB_AVAILABLE_IN_ALL +void g_param_spec_pool_insert (GParamSpecPool *pool, + GParamSpec *pspec, + GType owner_type); +GLIB_AVAILABLE_IN_ALL +void g_param_spec_pool_remove (GParamSpecPool *pool, + GParamSpec *pspec); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_pool_lookup (GParamSpecPool *pool, + const gchar *param_name, + GType owner_type, + gboolean walk_ancestors); +GLIB_AVAILABLE_IN_ALL +GList* g_param_spec_pool_list_owned (GParamSpecPool *pool, + GType owner_type); +GLIB_AVAILABLE_IN_ALL +GParamSpec** g_param_spec_pool_list (GParamSpecPool *pool, + GType owner_type, + guint *n_pspecs_p); + + +/* contracts: + * + * gboolean value_validate (GParamSpec *pspec, + * GValue *value): + * modify value contents in the least destructive way, so + * that it complies with pspec's requirements (i.e. + * according to minimum/maximum ranges etc...). return + * whether modification was necessary. + * + * gint values_cmp (GParamSpec *pspec, + * const GValue *value1, + * const GValue *value2): + * return value1 - value2, i.e. (-1) if value1 < value2, + * (+1) if value1 > value2, and (0) otherwise (equality) + */ + +G_END_DECLS + +#endif /* __G_PARAM_H__ */ diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c new file mode 100644 index 0000000..c937a6a --- /dev/null +++ b/gobject/gparamspecs.c @@ -0,0 +1,2622 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * Copyright (C) 2010 Christian Persch + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * MT safe + */ + +#include "config.h" + +#include + +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include "gparamspecs.h" +#include "gtype-private.h" +#include "gvaluecollector.h" + +#include "gvaluearray.h" + + +/** + * SECTION:param_value_types + * @short_description: Standard Parameter and Value Types + * @see_also: #GParamSpec, #GValue, g_object_class_install_property(). + * @title: Parameters and Values + * + * #GValue provides an abstract container structure which can be + * copied, transformed and compared while holding a value of any + * (derived) type, which is registered as a #GType with a + * #GTypeValueTable in its #GTypeInfo structure. Parameter + * specifications for most value types can be created as #GParamSpec + * derived instances, to implement e.g. #GObject properties which + * operate on #GValue containers. + * + * Parameter names need to start with a letter (a-z or A-Z). Subsequent + * characters can be letters, numbers or a '-'. + * All other characters are replaced by a '-' during construction. + * + * See also #GValue for more information. + * + */ + + +#define G_FLOAT_EPSILON (1e-30) +#define G_DOUBLE_EPSILON (1e-90) + + +/* --- param spec functions --- */ +static void +param_char_init (GParamSpec *pspec) +{ + GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec); + + cspec->minimum = 0x7f; + cspec->maximum = 0x80; + cspec->default_value = 0; +} + +static void +param_char_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value; +} + +static gboolean +param_char_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec); + gint oval = value->data[0].v_int; + + value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum); + + return value->data[0].v_int != oval; +} + +static void +param_uchar_init (GParamSpec *pspec) +{ + GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec); + + uspec->minimum = 0; + uspec->maximum = 0xff; + uspec->default_value = 0; +} + +static void +param_uchar_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value; +} + +static gboolean +param_uchar_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec); + guint oval = value->data[0].v_uint; + + value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum); + + return value->data[0].v_uint != oval; +} + +static void +param_boolean_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value; +} + +static gboolean +param_boolean_validate (GParamSpec *pspec, + GValue *value) +{ + gint oval = value->data[0].v_int; + + value->data[0].v_int = value->data[0].v_int != FALSE; + + return value->data[0].v_int != oval; +} + +static void +param_int_init (GParamSpec *pspec) +{ + GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec); + + ispec->minimum = 0x7fffffff; + ispec->maximum = 0x80000000; + ispec->default_value = 0; +} + +static void +param_int_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value; +} + +static gboolean +param_int_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec); + gint oval = value->data[0].v_int; + + value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum); + + return value->data[0].v_int != oval; +} + +static gint +param_int_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + if (value1->data[0].v_int < value2->data[0].v_int) + return -1; + else + return value1->data[0].v_int > value2->data[0].v_int; +} + +static void +param_uint_init (GParamSpec *pspec) +{ + GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec); + + uspec->minimum = 0; + uspec->maximum = 0xffffffff; + uspec->default_value = 0; +} + +static void +param_uint_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value; +} + +static gboolean +param_uint_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec); + guint oval = value->data[0].v_uint; + + value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum); + + return value->data[0].v_uint != oval; +} + +static gint +param_uint_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + if (value1->data[0].v_uint < value2->data[0].v_uint) + return -1; + else + return value1->data[0].v_uint > value2->data[0].v_uint; +} + +static void +param_long_init (GParamSpec *pspec) +{ + GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec); + +#if SIZEOF_LONG == 4 + lspec->minimum = 0x7fffffff; + lspec->maximum = 0x80000000; +#else /* SIZEOF_LONG != 4 (8) */ + lspec->minimum = 0x7fffffffffffffff; + lspec->maximum = 0x8000000000000000; +#endif + lspec->default_value = 0; +} + +static void +param_long_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value; +} + +static gboolean +param_long_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec); + glong oval = value->data[0].v_long; + + value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum); + + return value->data[0].v_long != oval; +} + +static gint +param_long_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + if (value1->data[0].v_long < value2->data[0].v_long) + return -1; + else + return value1->data[0].v_long > value2->data[0].v_long; +} + +static void +param_ulong_init (GParamSpec *pspec) +{ + GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec); + + uspec->minimum = 0; +#if SIZEOF_LONG == 4 + uspec->maximum = 0xffffffff; +#else /* SIZEOF_LONG != 4 (8) */ + uspec->maximum = 0xffffffffffffffff; +#endif + uspec->default_value = 0; +} + +static void +param_ulong_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value; +} + +static gboolean +param_ulong_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec); + gulong oval = value->data[0].v_ulong; + + value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum); + + return value->data[0].v_ulong != oval; +} + +static gint +param_ulong_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + if (value1->data[0].v_ulong < value2->data[0].v_ulong) + return -1; + else + return value1->data[0].v_ulong > value2->data[0].v_ulong; +} + +static void +param_int64_init (GParamSpec *pspec) +{ + GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec); + + lspec->minimum = G_MININT64; + lspec->maximum = G_MAXINT64; + lspec->default_value = 0; +} + +static void +param_int64_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_int64 = G_PARAM_SPEC_INT64 (pspec)->default_value; +} + +static gboolean +param_int64_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec); + gint64 oval = value->data[0].v_int64; + + value->data[0].v_int64 = CLAMP (value->data[0].v_int64, lspec->minimum, lspec->maximum); + + return value->data[0].v_int64 != oval; +} + +static gint +param_int64_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + if (value1->data[0].v_int64 < value2->data[0].v_int64) + return -1; + else + return value1->data[0].v_int64 > value2->data[0].v_int64; +} + +static void +param_uint64_init (GParamSpec *pspec) +{ + GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec); + + uspec->minimum = 0; + uspec->maximum = G_MAXUINT64; + uspec->default_value = 0; +} + +static void +param_uint64_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_uint64 = G_PARAM_SPEC_UINT64 (pspec)->default_value; +} + +static gboolean +param_uint64_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec); + guint64 oval = value->data[0].v_uint64; + + value->data[0].v_uint64 = CLAMP (value->data[0].v_uint64, uspec->minimum, uspec->maximum); + + return value->data[0].v_uint64 != oval; +} + +static gint +param_uint64_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + if (value1->data[0].v_uint64 < value2->data[0].v_uint64) + return -1; + else + return value1->data[0].v_uint64 > value2->data[0].v_uint64; +} + +static void +param_unichar_init (GParamSpec *pspec) +{ + GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec); + + uspec->default_value = 0; +} + +static void +param_unichar_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_uint = G_PARAM_SPEC_UNICHAR (pspec)->default_value; +} + +static gboolean +param_unichar_validate (GParamSpec *pspec, + GValue *value) +{ + gunichar oval = value->data[0].v_uint; + gboolean changed = FALSE; + + if (!g_unichar_validate (oval)) + { + value->data[0].v_uint = 0; + changed = TRUE; + } + + return changed; +} + +static gint +param_unichar_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + if (value1->data[0].v_uint < value2->data[0].v_uint) + return -1; + else + return value1->data[0].v_uint > value2->data[0].v_uint; +} + +static void +param_enum_init (GParamSpec *pspec) +{ + GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); + + espec->enum_class = NULL; + espec->default_value = 0; +} + +static void +param_enum_finalize (GParamSpec *pspec) +{ + GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); + GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM)); + + if (espec->enum_class) + { + g_type_class_unref (espec->enum_class); + espec->enum_class = NULL; + } + + parent_class->finalize (pspec); +} + +static void +param_enum_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value; +} + +static gboolean +param_enum_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); + glong oval = value->data[0].v_long; + + if (!espec->enum_class || + !g_enum_get_value (espec->enum_class, value->data[0].v_long)) + value->data[0].v_long = espec->default_value; + + return value->data[0].v_long != oval; +} + +static void +param_flags_init (GParamSpec *pspec) +{ + GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); + + fspec->flags_class = NULL; + fspec->default_value = 0; +} + +static void +param_flags_finalize (GParamSpec *pspec) +{ + GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); + GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS)); + + if (fspec->flags_class) + { + g_type_class_unref (fspec->flags_class); + fspec->flags_class = NULL; + } + + parent_class->finalize (pspec); +} + +static void +param_flags_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value; +} + +static gboolean +param_flags_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); + gulong oval = value->data[0].v_ulong; + + if (fspec->flags_class) + value->data[0].v_ulong &= fspec->flags_class->mask; + else + value->data[0].v_ulong = fspec->default_value; + + return value->data[0].v_ulong != oval; +} + +static void +param_float_init (GParamSpec *pspec) +{ + GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec); + + fspec->minimum = -G_MAXFLOAT; + fspec->maximum = G_MAXFLOAT; + fspec->default_value = 0; + fspec->epsilon = G_FLOAT_EPSILON; +} + +static void +param_float_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value; +} + +static gboolean +param_float_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec); + gfloat oval = value->data[0].v_float; + + value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum); + + return value->data[0].v_float != oval; +} + +static gint +param_float_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon; + + if (value1->data[0].v_float < value2->data[0].v_float) + return - (value2->data[0].v_float - value1->data[0].v_float > epsilon); + else + return value1->data[0].v_float - value2->data[0].v_float > epsilon; +} + +static void +param_double_init (GParamSpec *pspec) +{ + GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec); + + dspec->minimum = -G_MAXDOUBLE; + dspec->maximum = G_MAXDOUBLE; + dspec->default_value = 0; + dspec->epsilon = G_DOUBLE_EPSILON; +} + +static void +param_double_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value; +} + +static gboolean +param_double_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec); + gdouble oval = value->data[0].v_double; + + value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum); + + return value->data[0].v_double != oval; +} + +static gint +param_double_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon; + + if (value1->data[0].v_double < value2->data[0].v_double) + return - (value2->data[0].v_double - value1->data[0].v_double > epsilon); + else + return value1->data[0].v_double - value2->data[0].v_double > epsilon; +} + +static void +param_string_init (GParamSpec *pspec) +{ + GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); + + sspec->default_value = NULL; + sspec->cset_first = NULL; + sspec->cset_nth = NULL; + sspec->substitutor = '_'; + sspec->null_fold_if_empty = FALSE; + sspec->ensure_non_null = FALSE; +} + +static void +param_string_finalize (GParamSpec *pspec) +{ + GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); + GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING)); + + g_free (sspec->default_value); + g_free (sspec->cset_first); + g_free (sspec->cset_nth); + sspec->default_value = NULL; + sspec->cset_first = NULL; + sspec->cset_nth = NULL; + + parent_class->finalize (pspec); +} + +static void +param_string_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value); +} + +static gboolean +param_string_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); + gchar *string = value->data[0].v_pointer; + guint changed = 0; + + if (string && string[0]) + { + gchar *s; + + if (sspec->cset_first && !strchr (sspec->cset_first, string[0])) + { + if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) + { + value->data[0].v_pointer = g_strdup (string); + string = value->data[0].v_pointer; + value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS; + } + string[0] = sspec->substitutor; + changed++; + } + if (sspec->cset_nth) + for (s = string + 1; *s; s++) + if (!strchr (sspec->cset_nth, *s)) + { + if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) + { + value->data[0].v_pointer = g_strdup (string); + s = (gchar*) value->data[0].v_pointer + (s - string); + string = value->data[0].v_pointer; + value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS; + } + *s = sspec->substitutor; + changed++; + } + } + if (sspec->null_fold_if_empty && string && string[0] == 0) + { + if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) + g_free (value->data[0].v_pointer); + else + value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS; + value->data[0].v_pointer = NULL; + changed++; + string = value->data[0].v_pointer; + } + if (sspec->ensure_non_null && !string) + { + value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS; + value->data[0].v_pointer = g_strdup (""); + changed++; + string = value->data[0].v_pointer; + } + + return changed; +} + +static gint +param_string_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + if (!value1->data[0].v_pointer) + return value2->data[0].v_pointer != NULL ? -1 : 0; + else if (!value2->data[0].v_pointer) + return value1->data[0].v_pointer != NULL; + else + return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer); +} + +static void +param_param_init (GParamSpec *pspec) +{ + /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */ +} + +static void +param_param_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static gboolean +param_param_validate (GParamSpec *pspec, + GValue *value) +{ + /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */ + GParamSpec *param = value->data[0].v_pointer; + guint changed = 0; + + if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec))) + { + g_param_spec_unref (param); + value->data[0].v_pointer = NULL; + changed++; + } + + return changed; +} + +static void +param_boxed_init (GParamSpec *pspec) +{ + /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */ +} + +static void +param_boxed_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static gboolean +param_boxed_validate (GParamSpec *pspec, + GValue *value) +{ + /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */ + guint changed = 0; + + /* can't do a whole lot here since we haven't even G_BOXED_TYPE() */ + + return changed; +} + +static gint +param_boxed_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + guint8 *p1 = value1->data[0].v_pointer; + guint8 *p2 = value2->data[0].v_pointer; + + /* not much to compare here, try to at least provide stable lesser/greater result */ + + return p1 < p2 ? -1 : p1 > p2; +} + +static void +param_pointer_init (GParamSpec *pspec) +{ + /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */ +} + +static void +param_pointer_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static gboolean +param_pointer_validate (GParamSpec *pspec, + GValue *value) +{ + /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */ + guint changed = 0; + + return changed; +} + +static gint +param_pointer_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + guint8 *p1 = value1->data[0].v_pointer; + guint8 *p2 = value2->data[0].v_pointer; + + /* not much to compare here, try to at least provide stable lesser/greater result */ + + return p1 < p2 ? -1 : p1 > p2; +} + +static void +param_value_array_init (GParamSpec *pspec) +{ + GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); + + aspec->element_spec = NULL; + aspec->fixed_n_elements = 0; /* disable */ +} + +static inline guint +value_array_ensure_size (GValueArray *value_array, + guint fixed_n_elements) +{ + guint changed = 0; + + if (fixed_n_elements) + { + while (value_array->n_values < fixed_n_elements) + { + g_value_array_append (value_array, NULL); + changed++; + } + while (value_array->n_values > fixed_n_elements) + { + g_value_array_remove (value_array, value_array->n_values - 1); + changed++; + } + } + return changed; +} + +static void +param_value_array_finalize (GParamSpec *pspec) +{ + GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); + GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY)); + + if (aspec->element_spec) + { + g_param_spec_unref (aspec->element_spec); + aspec->element_spec = NULL; + } + + parent_class->finalize (pspec); +} + +static void +param_value_array_set_default (GParamSpec *pspec, + GValue *value) +{ + GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); + + if (!value->data[0].v_pointer && aspec->fixed_n_elements) + value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements); + + if (value->data[0].v_pointer) + { + /* g_value_reset (value); already done */ + value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements); + } +} + +static gboolean +param_value_array_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); + GValueArray *value_array = value->data[0].v_pointer; + guint changed = 0; + + if (!value->data[0].v_pointer && aspec->fixed_n_elements) + value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements); + + if (value->data[0].v_pointer) + { + /* ensure array size validity */ + changed += value_array_ensure_size (value_array, aspec->fixed_n_elements); + + /* ensure array values validity against a present element spec */ + if (aspec->element_spec) + { + GParamSpec *element_spec = aspec->element_spec; + guint i; + + for (i = 0; i < value_array->n_values; i++) + { + GValue *element = value_array->values + i; + + /* need to fixup value type, or ensure that the array value is initialized at all */ + if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec))) + { + if (G_VALUE_TYPE (element) != 0) + g_value_unset (element); + g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec)); + g_param_value_set_default (element_spec, element); + changed++; + } + else + { + /* validate array value against element_spec */ + changed += g_param_value_validate (element_spec, element); + } + } + } + } + + return changed; +} + +static gint +param_value_array_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); + GValueArray *value_array1 = value1->data[0].v_pointer; + GValueArray *value_array2 = value2->data[0].v_pointer; + + if (!value_array1 || !value_array2) + return value_array2 ? -1 : value_array1 != value_array2; + + if (value_array1->n_values != value_array2->n_values) + return value_array1->n_values < value_array2->n_values ? -1 : 1; + else if (!aspec->element_spec) + { + /* we need an element specification for comparisons, so there's not much + * to compare here, try to at least provide stable lesser/greater result + */ + return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values; + } + else /* value_array1->n_values == value_array2->n_values */ + { + guint i; + + for (i = 0; i < value_array1->n_values; i++) + { + GValue *element1 = value_array1->values + i; + GValue *element2 = value_array2->values + i; + gint cmp; + + /* need corresponding element types, provide stable result otherwise */ + if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2)) + return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1; + cmp = g_param_values_cmp (aspec->element_spec, element1, element2); + if (cmp) + return cmp; + } + return 0; + } +} + +static void +param_object_init (GParamSpec *pspec) +{ + /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */ +} + +static void +param_object_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static gboolean +param_object_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); + GObject *object = value->data[0].v_pointer; + guint changed = 0; + + if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec))) + { + g_object_unref (object); + value->data[0].v_pointer = NULL; + changed++; + } + + return changed; +} + +static gint +param_object_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + guint8 *p1 = value1->data[0].v_pointer; + guint8 *p2 = value2->data[0].v_pointer; + + /* not much to compare here, try to at least provide stable lesser/greater result */ + + return p1 < p2 ? -1 : p1 > p2; +} + +static void +param_override_init (GParamSpec *pspec) +{ + /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */ +} + +static void +param_override_finalize (GParamSpec *pspec) +{ + GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); + GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_OVERRIDE)); + + if (ospec->overridden) + { + g_param_spec_unref (ospec->overridden); + ospec->overridden = NULL; + } + + parent_class->finalize (pspec); +} + +static void +param_override_set_default (GParamSpec *pspec, + GValue *value) +{ + GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); + + g_param_value_set_default (ospec->overridden, value); +} + +static gboolean +param_override_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); + + return g_param_value_validate (ospec->overridden, value); +} + +static gint +param_override_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); + + return g_param_values_cmp (ospec->overridden, value1, value2); +} + +static void +param_gtype_init (GParamSpec *pspec) +{ +} + +static void +param_gtype_set_default (GParamSpec *pspec, + GValue *value) +{ + GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec); + + value->data[0].v_pointer = GSIZE_TO_POINTER (tspec->is_a_type); +} + +static gboolean +param_gtype_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec); + GType gtype = GPOINTER_TO_SIZE (value->data[0].v_pointer); + guint changed = 0; + + if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type)) + { + value->data[0].v_pointer = GSIZE_TO_POINTER (tspec->is_a_type); + changed++; + } + + return changed; +} + +static gint +param_gtype_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GType p1 = GPOINTER_TO_SIZE (value1->data[0].v_pointer); + GType p2 = GPOINTER_TO_SIZE (value2->data[0].v_pointer); + + /* not much to compare here, try to at least provide stable lesser/greater result */ + + return p1 < p2 ? -1 : p1 > p2; +} + +static void +param_variant_init (GParamSpec *pspec) +{ + GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec); + + vspec->type = NULL; + vspec->default_value = NULL; +} + +static void +param_variant_finalize (GParamSpec *pspec) +{ + GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec); + GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT)); + + if (vspec->default_value) + g_variant_unref (vspec->default_value); + g_variant_type_free (vspec->type); + + parent_class->finalize (pspec); +} + +static void +param_variant_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_pointer = G_PARAM_SPEC_VARIANT (pspec)->default_value; + value->data[1].v_uint |= G_VALUE_NOCOPY_CONTENTS; +} + +static gboolean +param_variant_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec); + GVariant *variant = value->data[0].v_pointer; + + if ((variant == NULL && vspec->default_value != NULL) || + (variant != NULL && !g_variant_is_of_type (variant, vspec->type))) + { + g_param_value_set_default (pspec, value); + return TRUE; + } + + return FALSE; +} + +/* g_variant_compare() can only be used with scalar types. */ +static gboolean +variant_is_incomparable (GVariant *v) +{ + GVariantClass v_class = g_variant_classify (v); + + return (v_class == G_VARIANT_CLASS_HANDLE || + v_class == G_VARIANT_CLASS_VARIANT || + v_class == G_VARIANT_CLASS_MAYBE|| + v_class == G_VARIANT_CLASS_ARRAY || + v_class == G_VARIANT_CLASS_TUPLE || + v_class == G_VARIANT_CLASS_DICT_ENTRY); +} + +static gint +param_variant_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GVariant *v1 = value1->data[0].v_pointer; + GVariant *v2 = value2->data[0].v_pointer; + + if (v1 == NULL && v2 == NULL) + return 0; + else if (v1 == NULL && v2 != NULL) + return -1; + else if (v1 != NULL && v2 == NULL) + return 1; + + if (!g_variant_type_equal (g_variant_get_type (v1), g_variant_get_type (v2)) || + variant_is_incomparable (v1) || + variant_is_incomparable (v2)) + return g_variant_equal (v1, v2) ? 0 : (v1 < v2 ? -1 : 1); + + return g_variant_compare (v1, v2); +} + +/* --- type initialization --- */ +GType *g_param_spec_types = NULL; + +void +_g_param_spec_types_init (void) +{ + const guint n_types = 23; + GType type, *spec_types; +#ifndef G_DISABLE_ASSERT + GType *spec_types_bound; +#endif + + g_param_spec_types = g_new0 (GType, n_types); + spec_types = g_param_spec_types; +#ifndef G_DISABLE_ASSERT + spec_types_bound = g_param_spec_types + n_types; +#endif + + /* G_TYPE_PARAM_CHAR + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecChar), /* instance_size */ + 16, /* n_preallocs */ + param_char_init, /* instance_init */ + G_TYPE_CHAR, /* value_type */ + NULL, /* finalize */ + param_char_set_default, /* value_set_default */ + param_char_validate, /* value_validate */ + param_int_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamChar"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_CHAR); + } + + /* G_TYPE_PARAM_UCHAR + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecUChar), /* instance_size */ + 16, /* n_preallocs */ + param_uchar_init, /* instance_init */ + G_TYPE_UCHAR, /* value_type */ + NULL, /* finalize */ + param_uchar_set_default, /* value_set_default */ + param_uchar_validate, /* value_validate */ + param_uint_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamUChar"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_UCHAR); + } + + /* G_TYPE_PARAM_BOOLEAN + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecBoolean), /* instance_size */ + 16, /* n_preallocs */ + NULL, /* instance_init */ + G_TYPE_BOOLEAN, /* value_type */ + NULL, /* finalize */ + param_boolean_set_default, /* value_set_default */ + param_boolean_validate, /* value_validate */ + param_int_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamBoolean"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_BOOLEAN); + } + + /* G_TYPE_PARAM_INT + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecInt), /* instance_size */ + 16, /* n_preallocs */ + param_int_init, /* instance_init */ + G_TYPE_INT, /* value_type */ + NULL, /* finalize */ + param_int_set_default, /* value_set_default */ + param_int_validate, /* value_validate */ + param_int_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamInt"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_INT); + } + + /* G_TYPE_PARAM_UINT + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecUInt), /* instance_size */ + 16, /* n_preallocs */ + param_uint_init, /* instance_init */ + G_TYPE_UINT, /* value_type */ + NULL, /* finalize */ + param_uint_set_default, /* value_set_default */ + param_uint_validate, /* value_validate */ + param_uint_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamUInt"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_UINT); + } + + /* G_TYPE_PARAM_LONG + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecLong), /* instance_size */ + 16, /* n_preallocs */ + param_long_init, /* instance_init */ + G_TYPE_LONG, /* value_type */ + NULL, /* finalize */ + param_long_set_default, /* value_set_default */ + param_long_validate, /* value_validate */ + param_long_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamLong"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_LONG); + } + + /* G_TYPE_PARAM_ULONG + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecULong), /* instance_size */ + 16, /* n_preallocs */ + param_ulong_init, /* instance_init */ + G_TYPE_ULONG, /* value_type */ + NULL, /* finalize */ + param_ulong_set_default, /* value_set_default */ + param_ulong_validate, /* value_validate */ + param_ulong_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamULong"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_ULONG); + } + + /* G_TYPE_PARAM_INT64 + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecInt64), /* instance_size */ + 16, /* n_preallocs */ + param_int64_init, /* instance_init */ + G_TYPE_INT64, /* value_type */ + NULL, /* finalize */ + param_int64_set_default, /* value_set_default */ + param_int64_validate, /* value_validate */ + param_int64_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamInt64"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_INT64); + } + + /* G_TYPE_PARAM_UINT64 + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecUInt64), /* instance_size */ + 16, /* n_preallocs */ + param_uint64_init, /* instance_init */ + G_TYPE_UINT64, /* value_type */ + NULL, /* finalize */ + param_uint64_set_default, /* value_set_default */ + param_uint64_validate, /* value_validate */ + param_uint64_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamUInt64"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_UINT64); + } + + /* G_TYPE_PARAM_UNICHAR + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecUnichar), /* instance_size */ + 16, /* n_preallocs */ + param_unichar_init, /* instance_init */ + G_TYPE_UINT, /* value_type */ + NULL, /* finalize */ + param_unichar_set_default, /* value_set_default */ + param_unichar_validate, /* value_validate */ + param_unichar_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamUnichar"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_UNICHAR); + } + + /* G_TYPE_PARAM_ENUM + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecEnum), /* instance_size */ + 16, /* n_preallocs */ + param_enum_init, /* instance_init */ + G_TYPE_ENUM, /* value_type */ + param_enum_finalize, /* finalize */ + param_enum_set_default, /* value_set_default */ + param_enum_validate, /* value_validate */ + param_long_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamEnum"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_ENUM); + } + + /* G_TYPE_PARAM_FLAGS + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecFlags), /* instance_size */ + 16, /* n_preallocs */ + param_flags_init, /* instance_init */ + G_TYPE_FLAGS, /* value_type */ + param_flags_finalize, /* finalize */ + param_flags_set_default, /* value_set_default */ + param_flags_validate, /* value_validate */ + param_ulong_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamFlags"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_FLAGS); + } + + /* G_TYPE_PARAM_FLOAT + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecFloat), /* instance_size */ + 16, /* n_preallocs */ + param_float_init, /* instance_init */ + G_TYPE_FLOAT, /* value_type */ + NULL, /* finalize */ + param_float_set_default, /* value_set_default */ + param_float_validate, /* value_validate */ + param_float_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamFloat"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_FLOAT); + } + + /* G_TYPE_PARAM_DOUBLE + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecDouble), /* instance_size */ + 16, /* n_preallocs */ + param_double_init, /* instance_init */ + G_TYPE_DOUBLE, /* value_type */ + NULL, /* finalize */ + param_double_set_default, /* value_set_default */ + param_double_validate, /* value_validate */ + param_double_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamDouble"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_DOUBLE); + } + + /* G_TYPE_PARAM_STRING + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecString), /* instance_size */ + 16, /* n_preallocs */ + param_string_init, /* instance_init */ + G_TYPE_STRING, /* value_type */ + param_string_finalize, /* finalize */ + param_string_set_default, /* value_set_default */ + param_string_validate, /* value_validate */ + param_string_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamString"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_STRING); + } + + /* G_TYPE_PARAM_PARAM + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecParam), /* instance_size */ + 16, /* n_preallocs */ + param_param_init, /* instance_init */ + G_TYPE_PARAM, /* value_type */ + NULL, /* finalize */ + param_param_set_default, /* value_set_default */ + param_param_validate, /* value_validate */ + param_pointer_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamParam"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_PARAM); + } + + /* G_TYPE_PARAM_BOXED + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecBoxed), /* instance_size */ + 4, /* n_preallocs */ + param_boxed_init, /* instance_init */ + G_TYPE_BOXED, /* value_type */ + NULL, /* finalize */ + param_boxed_set_default, /* value_set_default */ + param_boxed_validate, /* value_validate */ + param_boxed_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamBoxed"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_BOXED); + } + + /* G_TYPE_PARAM_POINTER + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecPointer), /* instance_size */ + 0, /* n_preallocs */ + param_pointer_init, /* instance_init */ + G_TYPE_POINTER, /* value_type */ + NULL, /* finalize */ + param_pointer_set_default, /* value_set_default */ + param_pointer_validate, /* value_validate */ + param_pointer_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamPointer"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_POINTER); + } + + /* G_TYPE_PARAM_VALUE_ARRAY + */ + { + /* const */ GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecValueArray), /* instance_size */ + 0, /* n_preallocs */ + param_value_array_init, /* instance_init */ + 0xdeadbeef, /* value_type, assigned further down */ + param_value_array_finalize, /* finalize */ + param_value_array_set_default, /* value_set_default */ + param_value_array_validate, /* value_validate */ + param_value_array_values_cmp, /* values_cmp */ + }; + pspec_info.value_type = G_TYPE_VALUE_ARRAY; + type = g_param_type_register_static (g_intern_static_string ("GParamValueArray"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_VALUE_ARRAY); + } + + /* G_TYPE_PARAM_OBJECT + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecObject), /* instance_size */ + 16, /* n_preallocs */ + param_object_init, /* instance_init */ + G_TYPE_OBJECT, /* value_type */ + NULL, /* finalize */ + param_object_set_default, /* value_set_default */ + param_object_validate, /* value_validate */ + param_object_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamObject"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_OBJECT); + } + + /* G_TYPE_PARAM_OVERRIDE + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecOverride), /* instance_size */ + 16, /* n_preallocs */ + param_override_init, /* instance_init */ + G_TYPE_NONE, /* value_type */ + param_override_finalize, /* finalize */ + param_override_set_default, /* value_set_default */ + param_override_validate, /* value_validate */ + param_override_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamOverride"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_OVERRIDE); + } + + /* G_TYPE_PARAM_GTYPE + */ + { + GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecGType), /* instance_size */ + 0, /* n_preallocs */ + param_gtype_init, /* instance_init */ + 0xdeadbeef, /* value_type, assigned further down */ + NULL, /* finalize */ + param_gtype_set_default, /* value_set_default */ + param_gtype_validate, /* value_validate */ + param_gtype_values_cmp, /* values_cmp */ + }; + pspec_info.value_type = G_TYPE_GTYPE; + type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_GTYPE); + } + + /* G_TYPE_PARAM_VARIANT + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecVariant), /* instance_size */ + 0, /* n_preallocs */ + param_variant_init, /* instance_init */ + G_TYPE_VARIANT, /* value_type */ + param_variant_finalize, /* finalize */ + param_variant_set_default, /* value_set_default */ + param_variant_validate, /* value_validate */ + param_variant_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamVariant"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_VARIANT); + } + + g_assert (spec_types == spec_types_bound); +} + +/* --- GParamSpec initialization --- */ + +/** + * g_param_spec_char: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecChar instance specifying a %G_TYPE_CHAR property. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_char (const gchar *name, + const gchar *nick, + const gchar *blurb, + gint8 minimum, + gint8 maximum, + gint8 default_value, + GParamFlags flags) +{ + GParamSpecChar *cspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR, + name, + nick, + blurb, + flags); + if (cspec == NULL) + return NULL; + + cspec->minimum = minimum; + cspec->maximum = maximum; + cspec->default_value = default_value; + + return G_PARAM_SPEC (cspec); +} + +/** + * g_param_spec_uchar: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecUChar instance specifying a %G_TYPE_UCHAR property. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_uchar (const gchar *name, + const gchar *nick, + const gchar *blurb, + guint8 minimum, + guint8 maximum, + guint8 default_value, + GParamFlags flags) +{ + GParamSpecUChar *uspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR, + name, + nick, + blurb, + flags); + if (uspec == NULL) + return NULL; + + uspec->minimum = minimum; + uspec->maximum = maximum; + uspec->default_value = default_value; + + return G_PARAM_SPEC (uspec); +} + +/** + * g_param_spec_boolean: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecBoolean instance specifying a %G_TYPE_BOOLEAN + * property. In many cases, it may be more appropriate to use an enum with + * g_param_spec_enum(), both to improve code clarity by using explicitly named + * values, and to allow for more values to be added in future without breaking + * API. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_boolean (const gchar *name, + const gchar *nick, + const gchar *blurb, + gboolean default_value, + GParamFlags flags) +{ + GParamSpecBoolean *bspec; + + g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL); + + bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN, + name, + nick, + blurb, + flags); + if (bspec == NULL) + return NULL; + + bspec->default_value = default_value; + + return G_PARAM_SPEC (bspec); +} + +/** + * g_param_spec_int: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecInt instance specifying a %G_TYPE_INT property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_int (const gchar *name, + const gchar *nick, + const gchar *blurb, + gint minimum, + gint maximum, + gint default_value, + GParamFlags flags) +{ + GParamSpecInt *ispec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + ispec = g_param_spec_internal (G_TYPE_PARAM_INT, + name, + nick, + blurb, + flags); + if (ispec == NULL) + return NULL; + + ispec->minimum = minimum; + ispec->maximum = maximum; + ispec->default_value = default_value; + + return G_PARAM_SPEC (ispec); +} + +/** + * g_param_spec_uint: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecUInt instance specifying a %G_TYPE_UINT property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_uint (const gchar *name, + const gchar *nick, + const gchar *blurb, + guint minimum, + guint maximum, + guint default_value, + GParamFlags flags) +{ + GParamSpecUInt *uspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + uspec = g_param_spec_internal (G_TYPE_PARAM_UINT, + name, + nick, + blurb, + flags); + if (uspec == NULL) + return NULL; + + uspec->minimum = minimum; + uspec->maximum = maximum; + uspec->default_value = default_value; + + return G_PARAM_SPEC (uspec); +} + +/** + * g_param_spec_long: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecLong instance specifying a %G_TYPE_LONG property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_long (const gchar *name, + const gchar *nick, + const gchar *blurb, + glong minimum, + glong maximum, + glong default_value, + GParamFlags flags) +{ + GParamSpecLong *lspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + lspec = g_param_spec_internal (G_TYPE_PARAM_LONG, + name, + nick, + blurb, + flags); + if (lspec == NULL) + return NULL; + + lspec->minimum = minimum; + lspec->maximum = maximum; + lspec->default_value = default_value; + + return G_PARAM_SPEC (lspec); +} + +/** + * g_param_spec_ulong: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecULong instance specifying a %G_TYPE_ULONG + * property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_ulong (const gchar *name, + const gchar *nick, + const gchar *blurb, + gulong minimum, + gulong maximum, + gulong default_value, + GParamFlags flags) +{ + GParamSpecULong *uspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG, + name, + nick, + blurb, + flags); + if (uspec == NULL) + return NULL; + + uspec->minimum = minimum; + uspec->maximum = maximum; + uspec->default_value = default_value; + + return G_PARAM_SPEC (uspec); +} + +/** + * g_param_spec_int64: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecInt64 instance specifying a %G_TYPE_INT64 property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_int64 (const gchar *name, + const gchar *nick, + const gchar *blurb, + gint64 minimum, + gint64 maximum, + gint64 default_value, + GParamFlags flags) +{ + GParamSpecInt64 *lspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + lspec = g_param_spec_internal (G_TYPE_PARAM_INT64, + name, + nick, + blurb, + flags); + if (lspec == NULL) + return NULL; + + lspec->minimum = minimum; + lspec->maximum = maximum; + lspec->default_value = default_value; + + return G_PARAM_SPEC (lspec); +} + +/** + * g_param_spec_uint64: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecUInt64 instance specifying a %G_TYPE_UINT64 + * property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_uint64 (const gchar *name, + const gchar *nick, + const gchar *blurb, + guint64 minimum, + guint64 maximum, + guint64 default_value, + GParamFlags flags) +{ + GParamSpecUInt64 *uspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64, + name, + nick, + blurb, + flags); + if (uspec == NULL) + return NULL; + + uspec->minimum = minimum; + uspec->maximum = maximum; + uspec->default_value = default_value; + + return G_PARAM_SPEC (uspec); +} + +/** + * g_param_spec_unichar: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecUnichar instance specifying a %G_TYPE_UINT + * property. #GValue structures for this property can be accessed with + * g_value_set_uint() and g_value_get_uint(). + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_unichar (const gchar *name, + const gchar *nick, + const gchar *blurb, + gunichar default_value, + GParamFlags flags) +{ + GParamSpecUnichar *uspec; + + uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR, + name, + nick, + blurb, + flags); + if (uspec == NULL) + return NULL; + + uspec->default_value = default_value; + + return G_PARAM_SPEC (uspec); +} + +/** + * g_param_spec_enum: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @enum_type: a #GType derived from %G_TYPE_ENUM + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecEnum instance specifying a %G_TYPE_ENUM + * property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_enum (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType enum_type, + gint default_value, + GParamFlags flags) +{ + GParamSpecEnum *espec; + GEnumClass *enum_class; + + g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL); + + enum_class = g_type_class_ref (enum_type); + + g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL); + + espec = g_param_spec_internal (G_TYPE_PARAM_ENUM, + name, + nick, + blurb, + flags); + if (espec == NULL) + { + g_type_class_unref (enum_class); + return NULL; + } + + espec->enum_class = enum_class; + espec->default_value = default_value; + G_PARAM_SPEC (espec)->value_type = enum_type; + + return G_PARAM_SPEC (espec); +} + +/** + * g_param_spec_flags: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @flags_type: a #GType derived from %G_TYPE_FLAGS + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecFlags instance specifying a %G_TYPE_FLAGS + * property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_flags (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType flags_type, + guint default_value, + GParamFlags flags) +{ + GParamSpecFlags *fspec; + GFlagsClass *flags_class; + + g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL); + + flags_class = g_type_class_ref (flags_type); + + g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL); + + fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS, + name, + nick, + blurb, + flags); + if (fspec == NULL) + { + g_type_class_unref (flags_class); + return NULL; + } + + fspec->flags_class = flags_class; + fspec->default_value = default_value; + G_PARAM_SPEC (fspec)->value_type = flags_type; + + return G_PARAM_SPEC (fspec); +} + +/** + * g_param_spec_float: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecFloat instance specifying a %G_TYPE_FLOAT property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_float (const gchar *name, + const gchar *nick, + const gchar *blurb, + gfloat minimum, + gfloat maximum, + gfloat default_value, + GParamFlags flags) +{ + GParamSpecFloat *fspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT, + name, + nick, + blurb, + flags); + if (fspec == NULL) + return NULL; + + fspec->minimum = minimum; + fspec->maximum = maximum; + fspec->default_value = default_value; + + return G_PARAM_SPEC (fspec); +} + +/** + * g_param_spec_double: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecDouble instance specifying a %G_TYPE_DOUBLE + * property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_double (const gchar *name, + const gchar *nick, + const gchar *blurb, + gdouble minimum, + gdouble maximum, + gdouble default_value, + GParamFlags flags) +{ + GParamSpecDouble *dspec; + + g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); + + dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE, + name, + nick, + blurb, + flags); + if (dspec == NULL) + return NULL; + + dspec->minimum = minimum; + dspec->maximum = maximum; + dspec->default_value = default_value; + + return G_PARAM_SPEC (dspec); +} + +/** + * g_param_spec_string: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @default_value: (nullable): default value for the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecString instance. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_string (const gchar *name, + const gchar *nick, + const gchar *blurb, + const gchar *default_value, + GParamFlags flags) +{ + GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING, + name, + nick, + blurb, + flags); + if (sspec == NULL) + return NULL; + + g_free (sspec->default_value); + sspec->default_value = g_strdup (default_value); + + return G_PARAM_SPEC (sspec); +} + +/** + * g_param_spec_param: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @param_type: a #GType derived from %G_TYPE_PARAM + * @flags: flags for the property specified + * + * Creates a new #GParamSpecParam instance specifying a %G_TYPE_PARAM + * property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_param (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType param_type, + GParamFlags flags) +{ + GParamSpecParam *pspec; + + g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL); + + pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM, + name, + nick, + blurb, + flags); + if (pspec == NULL) + return NULL; + + G_PARAM_SPEC (pspec)->value_type = param_type; + + return G_PARAM_SPEC (pspec); +} + +/** + * g_param_spec_boxed: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @boxed_type: %G_TYPE_BOXED derived type of this property + * @flags: flags for the property specified + * + * Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_BOXED + * derived property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_boxed (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType boxed_type, + GParamFlags flags) +{ + GParamSpecBoxed *bspec; + + g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL); + g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL); + + bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED, + name, + nick, + blurb, + flags); + if (bspec == NULL) + return NULL; + + G_PARAM_SPEC (bspec)->value_type = boxed_type; + + return G_PARAM_SPEC (bspec); +} + +/** + * g_param_spec_pointer: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @flags: flags for the property specified + * + * Creates a new #GParamSpecPointer instance specifying a pointer property. + * Where possible, it is better to use g_param_spec_object() or + * g_param_spec_boxed() to expose memory management information. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_pointer (const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamFlags flags) +{ + GParamSpecPointer *pspec; + + pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER, + name, + nick, + blurb, + flags); + if (pspec == NULL) + return NULL; + + return G_PARAM_SPEC (pspec); +} + +/** + * g_param_spec_gtype: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @is_a_type: a #GType whose subtypes are allowed as values + * of the property (use %G_TYPE_NONE for any type) + * @flags: flags for the property specified + * + * Creates a new #GParamSpecGType instance specifying a + * %G_TYPE_GTYPE property. + * + * See g_param_spec_internal() for details on property names. + * + * Since: 2.10 + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_gtype (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType is_a_type, + GParamFlags flags) +{ + GParamSpecGType *tspec; + + tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE, + name, + nick, + blurb, + flags); + if (tspec == NULL) + return NULL; + + tspec->is_a_type = is_a_type; + + return G_PARAM_SPEC (tspec); +} + +/** + * g_param_spec_value_array: (skip) + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @element_spec: a #GParamSpec describing the elements contained in + * arrays of this property, may be %NULL + * @flags: flags for the property specified + * + * Creates a new #GParamSpecValueArray instance specifying a + * %G_TYPE_VALUE_ARRAY property. %G_TYPE_VALUE_ARRAY is a + * %G_TYPE_BOXED type, as such, #GValue structures for this property + * can be accessed with g_value_set_boxed() and g_value_get_boxed(). + * + * See g_param_spec_internal() for details on property names. + * + * Returns: a newly created parameter specification + */ +GParamSpec* +g_param_spec_value_array (const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamSpec *element_spec, + GParamFlags flags) +{ + GParamSpecValueArray *aspec; + + if (element_spec) + g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL); + + aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY, + name, + nick, + blurb, + flags); + if (aspec == NULL) + return NULL; + + if (element_spec) + { + aspec->element_spec = g_param_spec_ref (element_spec); + g_param_spec_sink (element_spec); + } + + return G_PARAM_SPEC (aspec); +} + +/** + * g_param_spec_object: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @object_type: %G_TYPE_OBJECT derived type of this property + * @flags: flags for the property specified + * + * Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_OBJECT + * derived property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): a newly created parameter specification + */ +GParamSpec* +g_param_spec_object (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType object_type, + GParamFlags flags) +{ + GParamSpecObject *ospec; + + g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL); + + ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, + name, + nick, + blurb, + flags); + if (ospec == NULL) + return NULL; + + G_PARAM_SPEC (ospec)->value_type = object_type; + + return G_PARAM_SPEC (ospec); +} + +/** + * g_param_spec_override: (skip) + * @name: the name of the property. + * @overridden: The property that is being overridden + * + * Creates a new property of type #GParamSpecOverride. This is used + * to direct operations to another paramspec, and will not be directly + * useful unless you are implementing a new base type similar to GObject. + * + * Since: 2.4 + * + * Returns: the newly created #GParamSpec + */ +GParamSpec* +g_param_spec_override (const gchar *name, + GParamSpec *overridden) +{ + GParamSpec *pspec; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (G_IS_PARAM_SPEC (overridden), NULL); + + /* Dereference further redirections for property that was passed in + */ + while (TRUE) + { + GParamSpec *indirect = g_param_spec_get_redirect_target (overridden); + if (indirect) + overridden = indirect; + else + break; + } + + pspec = g_param_spec_internal (G_TYPE_PARAM_OVERRIDE, + name, NULL, NULL, + overridden->flags); + if (pspec == NULL) + return NULL; + + pspec->value_type = G_PARAM_SPEC_VALUE_TYPE (overridden); + G_PARAM_SPEC_OVERRIDE (pspec)->overridden = g_param_spec_ref (overridden); + + return pspec; +} + +/** + * g_param_spec_variant: + * @name: canonical name of the property specified + * @nick: (nullable): nick name for the property specified + * @blurb: (nullable): description of the property specified + * @type: a #GVariantType + * @default_value: (nullable) (transfer full): a #GVariant of type @type to + * use as the default value, or %NULL + * @flags: flags for the property specified + * + * Creates a new #GParamSpecVariant instance specifying a #GVariant + * property. + * + * If @default_value is floating, it is consumed. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer full): the newly created #GParamSpec + * + * Since: 2.26 + */ +GParamSpec* +g_param_spec_variant (const gchar *name, + const gchar *nick, + const gchar *blurb, + const GVariantType *type, + GVariant *default_value, + GParamFlags flags) +{ + GParamSpecVariant *vspec; + + g_return_val_if_fail (type != NULL, NULL); + g_return_val_if_fail (default_value == NULL || + g_variant_is_of_type (default_value, type), NULL); + + vspec = g_param_spec_internal (G_TYPE_PARAM_VARIANT, + name, + nick, + blurb, + flags); + if (vspec == NULL) + return NULL; + + vspec->type = g_variant_type_copy (type); + if (default_value) + vspec->default_value = g_variant_ref_sink (default_value); + + return G_PARAM_SPEC (vspec); +} diff --git a/gobject/gparamspecs.h b/gobject/gparamspecs.h new file mode 100644 index 0000000..78bf6b8 --- /dev/null +++ b/gobject/gparamspecs.h @@ -0,0 +1,1173 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * gparamspecs.h: GLib default param specs + */ +#ifndef __G_PARAMSPECS_H__ +#define __G_PARAMSPECS_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include +#include + +G_BEGIN_DECLS + +/* --- type macros --- */ +/** + * G_TYPE_PARAM_CHAR: + * + * The #GType of #GParamSpecChar. + */ +#define G_TYPE_PARAM_CHAR (g_param_spec_types[0]) +/** + * G_IS_PARAM_SPEC_CHAR: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_CHAR. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_CHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_CHAR)) +/** + * G_PARAM_SPEC_CHAR: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecChar. + */ +#define G_PARAM_SPEC_CHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_CHAR, GParamSpecChar)) + +/** + * G_TYPE_PARAM_UCHAR: + * + * The #GType of #GParamSpecUChar. + */ +#define G_TYPE_PARAM_UCHAR (g_param_spec_types[1]) +/** + * G_IS_PARAM_SPEC_UCHAR: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_UCHAR. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_UCHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UCHAR)) +/** + * G_PARAM_SPEC_UCHAR: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecUChar. + */ +#define G_PARAM_SPEC_UCHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UCHAR, GParamSpecUChar)) + +/** + * G_TYPE_PARAM_BOOLEAN: + * + * The #GType of #GParamSpecBoolean. + */ +#define G_TYPE_PARAM_BOOLEAN (g_param_spec_types[2]) +/** + * G_IS_PARAM_SPEC_BOOLEAN: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_BOOLEAN. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_BOOLEAN(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_BOOLEAN)) +/** + * G_PARAM_SPEC_BOOLEAN: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecBoolean. + */ +#define G_PARAM_SPEC_BOOLEAN(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_BOOLEAN, GParamSpecBoolean)) + +/** + * G_TYPE_PARAM_INT: + * + * The #GType of #GParamSpecInt. + */ +#define G_TYPE_PARAM_INT (g_param_spec_types[3]) +/** + * G_IS_PARAM_SPEC_INT: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_INT. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_INT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_INT)) +/** + * G_PARAM_SPEC_INT: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecInt. + */ +#define G_PARAM_SPEC_INT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_INT, GParamSpecInt)) + +/** + * G_TYPE_PARAM_UINT: + * + * The #GType of #GParamSpecUInt. + */ +#define G_TYPE_PARAM_UINT (g_param_spec_types[4]) +/** + * G_IS_PARAM_SPEC_UINT: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_UINT. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_UINT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UINT)) +/** + * G_PARAM_SPEC_UINT: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecUInt. + */ +#define G_PARAM_SPEC_UINT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UINT, GParamSpecUInt)) + +/** + * G_TYPE_PARAM_LONG: + * + * The #GType of #GParamSpecLong. + */ +#define G_TYPE_PARAM_LONG (g_param_spec_types[5]) +/** + * G_IS_PARAM_SPEC_LONG: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_LONG. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_LONG(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_LONG)) +/** + * G_PARAM_SPEC_LONG: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecLong. + */ +#define G_PARAM_SPEC_LONG(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_LONG, GParamSpecLong)) + +/** + * G_TYPE_PARAM_ULONG: + * + * The #GType of #GParamSpecULong. + */ +#define G_TYPE_PARAM_ULONG (g_param_spec_types[6]) +/** + * G_IS_PARAM_SPEC_ULONG: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_ULONG. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_ULONG(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_ULONG)) +/** + * G_PARAM_SPEC_ULONG: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecULong. + */ +#define G_PARAM_SPEC_ULONG(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_ULONG, GParamSpecULong)) + +/** + * G_TYPE_PARAM_INT64: + * + * The #GType of #GParamSpecInt64. + */ +#define G_TYPE_PARAM_INT64 (g_param_spec_types[7]) +/** + * G_IS_PARAM_SPEC_INT64: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_INT64. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_INT64(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_INT64)) +/** + * G_PARAM_SPEC_INT64: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecInt64. + */ +#define G_PARAM_SPEC_INT64(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_INT64, GParamSpecInt64)) + +/** + * G_TYPE_PARAM_UINT64: + * + * The #GType of #GParamSpecUInt64. + */ +#define G_TYPE_PARAM_UINT64 (g_param_spec_types[8]) +/** + * G_IS_PARAM_SPEC_UINT64: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_UINT64. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_UINT64(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UINT64)) +/** + * G_PARAM_SPEC_UINT64: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecUInt64. + */ +#define G_PARAM_SPEC_UINT64(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UINT64, GParamSpecUInt64)) + +/** + * G_TYPE_PARAM_UNICHAR: + * + * The #GType of #GParamSpecUnichar. + */ +#define G_TYPE_PARAM_UNICHAR (g_param_spec_types[9]) +/** + * G_PARAM_SPEC_UNICHAR: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecUnichar. + */ +#define G_PARAM_SPEC_UNICHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UNICHAR, GParamSpecUnichar)) +/** + * G_IS_PARAM_SPEC_UNICHAR: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_UNICHAR. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_UNICHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UNICHAR)) + +/** + * G_TYPE_PARAM_ENUM: + * + * The #GType of #GParamSpecEnum. + */ +#define G_TYPE_PARAM_ENUM (g_param_spec_types[10]) +/** + * G_IS_PARAM_SPEC_ENUM: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_ENUM. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_ENUM(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_ENUM)) +/** + * G_PARAM_SPEC_ENUM: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecEnum. + */ +#define G_PARAM_SPEC_ENUM(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_ENUM, GParamSpecEnum)) + +/** + * G_TYPE_PARAM_FLAGS: + * + * The #GType of #GParamSpecFlags. + */ +#define G_TYPE_PARAM_FLAGS (g_param_spec_types[11]) +/** + * G_IS_PARAM_SPEC_FLAGS: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_FLAGS. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_FLAGS(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_FLAGS)) +/** + * G_PARAM_SPEC_FLAGS: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecFlags. + */ +#define G_PARAM_SPEC_FLAGS(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_FLAGS, GParamSpecFlags)) + +/** + * G_TYPE_PARAM_FLOAT: + * + * The #GType of #GParamSpecFloat. + */ +#define G_TYPE_PARAM_FLOAT (g_param_spec_types[12]) +/** + * G_IS_PARAM_SPEC_FLOAT: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_FLOAT. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_FLOAT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_FLOAT)) +/** + * G_PARAM_SPEC_FLOAT: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecFloat. + */ +#define G_PARAM_SPEC_FLOAT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_FLOAT, GParamSpecFloat)) + +/** + * G_TYPE_PARAM_DOUBLE: + * + * The #GType of #GParamSpecDouble. + */ +#define G_TYPE_PARAM_DOUBLE (g_param_spec_types[13]) +/** + * G_IS_PARAM_SPEC_DOUBLE: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_DOUBLE. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_DOUBLE)) +/** + * G_PARAM_SPEC_DOUBLE: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecDouble. + */ +#define G_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_DOUBLE, GParamSpecDouble)) + +/** + * G_TYPE_PARAM_STRING: + * + * The #GType of #GParamSpecString. + */ +#define G_TYPE_PARAM_STRING (g_param_spec_types[14]) +/** + * G_IS_PARAM_SPEC_STRING: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_STRING. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_STRING)) +/** + * G_PARAM_SPEC_STRING: + * @pspec: a valid #GParamSpec instance + * + * Casts a #GParamSpec instance into a #GParamSpecString. + */ +#define G_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_STRING, GParamSpecString)) + +/** + * G_TYPE_PARAM_PARAM: + * + * The #GType of #GParamSpecParam. + */ +#define G_TYPE_PARAM_PARAM (g_param_spec_types[15]) +/** + * G_IS_PARAM_SPEC_PARAM: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_PARAM. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_PARAM(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_PARAM)) +/** + * G_PARAM_SPEC_PARAM: + * @pspec: a valid #GParamSpec instance + * + * Casts a #GParamSpec instance into a #GParamSpecParam. + */ +#define G_PARAM_SPEC_PARAM(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_PARAM, GParamSpecParam)) + +/** + * G_TYPE_PARAM_BOXED: + * + * The #GType of #GParamSpecBoxed. + */ +#define G_TYPE_PARAM_BOXED (g_param_spec_types[16]) +/** + * G_IS_PARAM_SPEC_BOXED: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_BOXED. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_BOXED(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_BOXED)) +/** + * G_PARAM_SPEC_BOXED: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecBoxed. + */ +#define G_PARAM_SPEC_BOXED(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_BOXED, GParamSpecBoxed)) + +/** + * G_TYPE_PARAM_POINTER: + * + * The #GType of #GParamSpecPointer. + */ +#define G_TYPE_PARAM_POINTER (g_param_spec_types[17]) +/** + * G_IS_PARAM_SPEC_POINTER: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_POINTER. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_POINTER(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_POINTER)) +/** + * G_PARAM_SPEC_POINTER: + * @pspec: a valid #GParamSpec instance + * + * Casts a #GParamSpec instance into a #GParamSpecPointer. + */ +#define G_PARAM_SPEC_POINTER(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_POINTER, GParamSpecPointer)) + +/** + * G_TYPE_PARAM_VALUE_ARRAY: + * + * The #GType of #GParamSpecValueArray. + * + * Deprecated: 2.32: Use #GArray instead of #GValueArray + */ +#define G_TYPE_PARAM_VALUE_ARRAY (g_param_spec_types[18]) GLIB_DEPRECATED_MACRO_IN_2_32 +/** + * G_IS_PARAM_SPEC_VALUE_ARRAY: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_VALUE_ARRAY. + * + * Returns: %TRUE on success. + * + * Deprecated: 2.32: Use #GArray instead of #GValueArray + */ +#define G_IS_PARAM_SPEC_VALUE_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_VALUE_ARRAY)) GLIB_DEPRECATED_MACRO_IN_2_32 +/** + * G_PARAM_SPEC_VALUE_ARRAY: + * @pspec: a valid #GParamSpec instance + * + * Cast a #GParamSpec instance into a #GParamSpecValueArray. + * + * Deprecated: 2.32: Use #GArray instead of #GValueArray + */ +#define G_PARAM_SPEC_VALUE_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_VALUE_ARRAY, GParamSpecValueArray)) GLIB_DEPRECATED_MACRO_IN_2_32 + +/** + * G_TYPE_PARAM_OBJECT: + * + * The #GType of #GParamSpecObject. + */ +#define G_TYPE_PARAM_OBJECT (g_param_spec_types[19]) +/** + * G_IS_PARAM_SPEC_OBJECT: + * @pspec: a valid #GParamSpec instance + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_OBJECT. + * + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_OBJECT)) +/** + * G_PARAM_SPEC_OBJECT: + * @pspec: a valid #GParamSpec instance + * + * Casts a #GParamSpec instance into a #GParamSpecObject. + */ +#define G_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_OBJECT, GParamSpecObject)) + +/** + * G_TYPE_PARAM_OVERRIDE: + * + * The #GType of #GParamSpecOverride. + * + * Since: 2.4 + */ +#define G_TYPE_PARAM_OVERRIDE (g_param_spec_types[20]) +/** + * G_IS_PARAM_SPEC_OVERRIDE: + * @pspec: a #GParamSpec + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_OVERRIDE. + * + * Since: 2.4 + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_OVERRIDE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_OVERRIDE)) +/** + * G_PARAM_SPEC_OVERRIDE: + * @pspec: a #GParamSpec + * + * Casts a #GParamSpec into a #GParamSpecOverride. + * + * Since: 2.4 + */ +#define G_PARAM_SPEC_OVERRIDE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_OVERRIDE, GParamSpecOverride)) + +/** + * G_TYPE_PARAM_GTYPE: + * + * The #GType of #GParamSpecGType. + * + * Since: 2.10 + */ +#define G_TYPE_PARAM_GTYPE (g_param_spec_types[21]) +/** + * G_IS_PARAM_SPEC_GTYPE: + * @pspec: a #GParamSpec + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_GTYPE. + * + * Since: 2.10 + * Returns: %TRUE on success. + */ +#define G_IS_PARAM_SPEC_GTYPE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_GTYPE)) +/** + * G_PARAM_SPEC_GTYPE: + * @pspec: a #GParamSpec + * + * Casts a #GParamSpec into a #GParamSpecGType. + * + * Since: 2.10 + */ +#define G_PARAM_SPEC_GTYPE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_GTYPE, GParamSpecGType)) + +/** + * G_TYPE_PARAM_VARIANT: + * + * The #GType of #GParamSpecVariant. + * + * Since: 2.26 + */ +#define G_TYPE_PARAM_VARIANT (g_param_spec_types[22]) +/** + * G_IS_PARAM_SPEC_VARIANT: + * @pspec: a #GParamSpec + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_VARIANT. + * + * Returns: %TRUE on success + * + * Since: 2.26 + */ +#define G_IS_PARAM_SPEC_VARIANT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_VARIANT)) +/** + * G_PARAM_SPEC_VARIANT: + * @pspec: a #GParamSpec + * + * Casts a #GParamSpec into a #GParamSpecVariant. + * + * Since: 2.26 + */ +#define G_PARAM_SPEC_VARIANT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_VARIANT, GParamSpecVariant)) + +/* --- typedefs & structures --- */ +typedef struct _GParamSpecChar GParamSpecChar; +typedef struct _GParamSpecUChar GParamSpecUChar; +typedef struct _GParamSpecBoolean GParamSpecBoolean; +typedef struct _GParamSpecInt GParamSpecInt; +typedef struct _GParamSpecUInt GParamSpecUInt; +typedef struct _GParamSpecLong GParamSpecLong; +typedef struct _GParamSpecULong GParamSpecULong; +typedef struct _GParamSpecInt64 GParamSpecInt64; +typedef struct _GParamSpecUInt64 GParamSpecUInt64; +typedef struct _GParamSpecUnichar GParamSpecUnichar; +typedef struct _GParamSpecEnum GParamSpecEnum; +typedef struct _GParamSpecFlags GParamSpecFlags; +typedef struct _GParamSpecFloat GParamSpecFloat; +typedef struct _GParamSpecDouble GParamSpecDouble; +typedef struct _GParamSpecString GParamSpecString; +typedef struct _GParamSpecParam GParamSpecParam; +typedef struct _GParamSpecBoxed GParamSpecBoxed; +typedef struct _GParamSpecPointer GParamSpecPointer; +typedef struct _GParamSpecValueArray GParamSpecValueArray; +typedef struct _GParamSpecObject GParamSpecObject; +typedef struct _GParamSpecOverride GParamSpecOverride; +typedef struct _GParamSpecGType GParamSpecGType; +typedef struct _GParamSpecVariant GParamSpecVariant; + +/** + * GParamSpecChar: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for character properties. + */ +struct _GParamSpecChar +{ + GParamSpec parent_instance; + + gint8 minimum; + gint8 maximum; + gint8 default_value; +}; +/** + * GParamSpecUChar: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for unsigned character properties. + */ +struct _GParamSpecUChar +{ + GParamSpec parent_instance; + + guint8 minimum; + guint8 maximum; + guint8 default_value; +}; +/** + * GParamSpecBoolean: + * @parent_instance: private #GParamSpec portion + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for boolean properties. + */ +struct _GParamSpecBoolean +{ + GParamSpec parent_instance; + + gboolean default_value; +}; +/** + * GParamSpecInt: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for integer properties. + */ +struct _GParamSpecInt +{ + GParamSpec parent_instance; + + gint minimum; + gint maximum; + gint default_value; +}; +/** + * GParamSpecUInt: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for unsigned integer properties. + */ +struct _GParamSpecUInt +{ + GParamSpec parent_instance; + + guint minimum; + guint maximum; + guint default_value; +}; +/** + * GParamSpecLong: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for long integer properties. + */ +struct _GParamSpecLong +{ + GParamSpec parent_instance; + + glong minimum; + glong maximum; + glong default_value; +}; +/** + * GParamSpecULong: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for unsigned long integer properties. + */ +struct _GParamSpecULong +{ + GParamSpec parent_instance; + + gulong minimum; + gulong maximum; + gulong default_value; +}; +/** + * GParamSpecInt64: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for 64bit integer properties. + */ +struct _GParamSpecInt64 +{ + GParamSpec parent_instance; + + gint64 minimum; + gint64 maximum; + gint64 default_value; +}; +/** + * GParamSpecUInt64: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for unsigned 64bit integer properties. + */ +struct _GParamSpecUInt64 +{ + GParamSpec parent_instance; + + guint64 minimum; + guint64 maximum; + guint64 default_value; +}; +/** + * GParamSpecUnichar: + * @parent_instance: private #GParamSpec portion + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for unichar (unsigned integer) properties. + */ +struct _GParamSpecUnichar +{ + GParamSpec parent_instance; + + gunichar default_value; +}; +/** + * GParamSpecEnum: + * @parent_instance: private #GParamSpec portion + * @enum_class: the #GEnumClass for the enum + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for enum + * properties. + */ +struct _GParamSpecEnum +{ + GParamSpec parent_instance; + + GEnumClass *enum_class; + gint default_value; +}; +/** + * GParamSpecFlags: + * @parent_instance: private #GParamSpec portion + * @flags_class: the #GFlagsClass for the flags + * @default_value: default value for the property specified + * + * A #GParamSpec derived structure that contains the meta data for flags + * properties. + */ +struct _GParamSpecFlags +{ + GParamSpec parent_instance; + + GFlagsClass *flags_class; + guint default_value; +}; +/** + * GParamSpecFloat: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @epsilon: values closer than @epsilon will be considered identical + * by g_param_values_cmp(); the default value is 1e-30. + * + * A #GParamSpec derived structure that contains the meta data for float properties. + */ +struct _GParamSpecFloat +{ + GParamSpec parent_instance; + + gfloat minimum; + gfloat maximum; + gfloat default_value; + gfloat epsilon; +}; +/** + * GParamSpecDouble: + * @parent_instance: private #GParamSpec portion + * @minimum: minimum value for the property specified + * @maximum: maximum value for the property specified + * @default_value: default value for the property specified + * @epsilon: values closer than @epsilon will be considered identical + * by g_param_values_cmp(); the default value is 1e-90. + * + * A #GParamSpec derived structure that contains the meta data for double properties. + */ +struct _GParamSpecDouble +{ + GParamSpec parent_instance; + + gdouble minimum; + gdouble maximum; + gdouble default_value; + gdouble epsilon; +}; +/** + * GParamSpecString: + * @parent_instance: private #GParamSpec portion + * @default_value: default value for the property specified + * @cset_first: a string containing the allowed values for the first byte + * @cset_nth: a string containing the allowed values for the subsequent bytes + * @substitutor: the replacement byte for bytes which don't match @cset_first or @cset_nth. + * @null_fold_if_empty: replace empty string by %NULL + * @ensure_non_null: replace %NULL strings by an empty string + * + * A #GParamSpec derived structure that contains the meta data for string + * properties. + */ +struct _GParamSpecString +{ + GParamSpec parent_instance; + + gchar *default_value; + gchar *cset_first; + gchar *cset_nth; + gchar substitutor; + guint null_fold_if_empty : 1; + guint ensure_non_null : 1; +}; +/** + * GParamSpecParam: + * @parent_instance: private #GParamSpec portion + * + * A #GParamSpec derived structure that contains the meta data for %G_TYPE_PARAM + * properties. + */ +struct _GParamSpecParam +{ + GParamSpec parent_instance; +}; +/** + * GParamSpecBoxed: + * @parent_instance: private #GParamSpec portion + * + * A #GParamSpec derived structure that contains the meta data for boxed properties. + */ +struct _GParamSpecBoxed +{ + GParamSpec parent_instance; +}; +/** + * GParamSpecPointer: + * @parent_instance: private #GParamSpec portion + * + * A #GParamSpec derived structure that contains the meta data for pointer properties. + */ +struct _GParamSpecPointer +{ + GParamSpec parent_instance; +}; +/** + * GParamSpecValueArray: + * @parent_instance: private #GParamSpec portion + * @element_spec: a #GParamSpec describing the elements contained in arrays of this property, may be %NULL + * @fixed_n_elements: if greater than 0, arrays of this property will always have this many elements + * + * A #GParamSpec derived structure that contains the meta data for #GValueArray properties. + */ +struct _GParamSpecValueArray +{ + GParamSpec parent_instance; + GParamSpec *element_spec; + guint fixed_n_elements; +}; +/** + * GParamSpecObject: + * @parent_instance: private #GParamSpec portion + * + * A #GParamSpec derived structure that contains the meta data for object properties. + */ +struct _GParamSpecObject +{ + GParamSpec parent_instance; +}; +/** + * GParamSpecOverride: + * + * A #GParamSpec derived structure that redirects operations to + * other types of #GParamSpec. + * + * All operations other than getting or setting the value are redirected, + * including accessing the nick and blurb, validating a value, and so + * forth. + * + * See g_param_spec_get_redirect_target() for retrieving the overridden + * property. #GParamSpecOverride is used in implementing + * g_object_class_override_property(), and will not be directly useful + * unless you are implementing a new base type similar to GObject. + * + * Since: 2.4 + */ +struct _GParamSpecOverride +{ + /*< private >*/ + GParamSpec parent_instance; + GParamSpec *overridden; +}; +/** + * GParamSpecGType: + * @parent_instance: private #GParamSpec portion + * @is_a_type: a #GType whose subtypes can occur as values + * + * A #GParamSpec derived structure that contains the meta data for #GType properties. + * + * Since: 2.10 + */ +struct _GParamSpecGType +{ + GParamSpec parent_instance; + GType is_a_type; +}; +/** + * GParamSpecVariant: + * @parent_instance: private #GParamSpec portion + * @type: a #GVariantType, or %NULL + * @default_value: a #GVariant, or %NULL + * + * A #GParamSpec derived structure that contains the meta data for #GVariant properties. + * + * When comparing values with g_param_values_cmp(), scalar values with the same + * type will be compared with g_variant_compare(). Other non-%NULL variants will + * be checked for equality with g_variant_equal(), and their sort order is + * otherwise undefined. %NULL is ordered before non-%NULL variants. Two %NULL + * values compare equal. + * + * Since: 2.26 + */ +struct _GParamSpecVariant +{ + GParamSpec parent_instance; + GVariantType *type; + GVariant *default_value; + + /*< private >*/ + gpointer padding[4]; +}; + +/* --- GParamSpec prototypes --- */ +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_char (const gchar *name, + const gchar *nick, + const gchar *blurb, + gint8 minimum, + gint8 maximum, + gint8 default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_uchar (const gchar *name, + const gchar *nick, + const gchar *blurb, + guint8 minimum, + guint8 maximum, + guint8 default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_boolean (const gchar *name, + const gchar *nick, + const gchar *blurb, + gboolean default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_int (const gchar *name, + const gchar *nick, + const gchar *blurb, + gint minimum, + gint maximum, + gint default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_uint (const gchar *name, + const gchar *nick, + const gchar *blurb, + guint minimum, + guint maximum, + guint default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_long (const gchar *name, + const gchar *nick, + const gchar *blurb, + glong minimum, + glong maximum, + glong default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_ulong (const gchar *name, + const gchar *nick, + const gchar *blurb, + gulong minimum, + gulong maximum, + gulong default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_int64 (const gchar *name, + const gchar *nick, + const gchar *blurb, + gint64 minimum, + gint64 maximum, + gint64 default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_uint64 (const gchar *name, + const gchar *nick, + const gchar *blurb, + guint64 minimum, + guint64 maximum, + guint64 default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_unichar (const gchar *name, + const gchar *nick, + const gchar *blurb, + gunichar default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_enum (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType enum_type, + gint default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_flags (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType flags_type, + guint default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_float (const gchar *name, + const gchar *nick, + const gchar *blurb, + gfloat minimum, + gfloat maximum, + gfloat default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_double (const gchar *name, + const gchar *nick, + const gchar *blurb, + gdouble minimum, + gdouble maximum, + gdouble default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_string (const gchar *name, + const gchar *nick, + const gchar *blurb, + const gchar *default_value, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_param (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType param_type, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_boxed (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType boxed_type, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_pointer (const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_value_array (const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamSpec *element_spec, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_object (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType object_type, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_override (const gchar *name, + GParamSpec *overridden); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_gtype (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType is_a_type, + GParamFlags flags); +GLIB_AVAILABLE_IN_ALL +GParamSpec* g_param_spec_variant (const gchar *name, + const gchar *nick, + const gchar *blurb, + const GVariantType *type, + GVariant *default_value, + GParamFlags flags); + +/* --- internal --- */ +/* We prefix variable declarations so they can + * properly get exported in windows dlls. + */ +#ifndef GOBJECT_VAR +# ifdef G_PLATFORM_WIN32 +# ifdef GOBJECT_STATIC_COMPILATION +# define GOBJECT_VAR extern +# else /* !GOBJECT_STATIC_COMPILATION */ +# ifdef GOBJECT_COMPILATION +# ifdef DLL_EXPORT +# define GOBJECT_VAR extern __declspec(dllexport) +# else /* !DLL_EXPORT */ +# define GOBJECT_VAR extern +# endif /* !DLL_EXPORT */ +# else /* !GOBJECT_COMPILATION */ +# define GOBJECT_VAR extern __declspec(dllimport) +# endif /* !GOBJECT_COMPILATION */ +# endif /* !GOBJECT_STATIC_COMPILATION */ +# else /* !G_PLATFORM_WIN32 */ +# define GOBJECT_VAR _GLIB_EXTERN +# endif /* !G_PLATFORM_WIN32 */ +#endif /* GOBJECT_VAR */ + +GOBJECT_VAR GType *g_param_spec_types; + +G_END_DECLS + +#endif /* __G_PARAMSPECS_H__ */ diff --git a/gobject/gsignal.c b/gobject/gsignal.c new file mode 100644 index 0000000..aeaf244 --- /dev/null +++ b/gobject/gsignal.c @@ -0,0 +1,4075 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000-2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * this code is based on the original GtkSignal implementation + * for the Gtk+ library by Peter Mattis + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include + +#include "gsignal.h" +#include "gtype-private.h" +#include "gbsearcharray.h" +#include "gvaluecollector.h" +#include "gvaluetypes.h" +#include "gobject.h" +#include "genums.h" +#include "gobject_trace.h" + + +/** + * SECTION:signals + * @short_description: A means for customization of object behaviour + * and a general purpose notification mechanism + * @title: Signals + * + * The basic concept of the signal system is that of the emission + * of a signal. Signals are introduced per-type and are identified + * through strings. Signals introduced for a parent type are available + * in derived types as well, so basically they are a per-type facility + * that is inherited. + * + * A signal emission mainly involves invocation of a certain set of + * callbacks in precisely defined manner. There are two main categories + * of such callbacks, per-object ones and user provided ones. + * (Although signals can deal with any kind of instantiatable type, I'm + * referring to those types as "object types" in the following, simply + * because that is the context most users will encounter signals in.) + * The per-object callbacks are most often referred to as "object method + * handler" or "default (signal) handler", while user provided callbacks are + * usually just called "signal handler". + * + * The object method handler is provided at signal creation time (this most + * frequently happens at the end of an object class' creation), while user + * provided handlers are frequently connected and disconnected to/from a + * certain signal on certain object instances. + * + * A signal emission consists of five stages, unless prematurely stopped: + * + * 1. Invocation of the object method handler for %G_SIGNAL_RUN_FIRST signals + * + * 2. Invocation of normal user-provided signal handlers (where the @after + * flag is not set) + * + * 3. Invocation of the object method handler for %G_SIGNAL_RUN_LAST signals + * + * 4. Invocation of user provided signal handlers (where the @after flag is set) + * + * 5. Invocation of the object method handler for %G_SIGNAL_RUN_CLEANUP signals + * + * The user-provided signal handlers are called in the order they were + * connected in. + * + * All handlers may prematurely stop a signal emission, and any number of + * handlers may be connected, disconnected, blocked or unblocked during + * a signal emission. + * + * There are certain criteria for skipping user handlers in stages 2 and 4 + * of a signal emission. + * + * First, user handlers may be blocked. Blocked handlers are omitted during + * callback invocation, to return from the blocked state, a handler has to + * get unblocked exactly the same amount of times it has been blocked before. + * + * Second, upon emission of a %G_SIGNAL_DETAILED signal, an additional + * @detail argument passed in to g_signal_emit() has to match the detail + * argument of the signal handler currently subject to invocation. + * Specification of no detail argument for signal handlers (omission of the + * detail part of the signal specification upon connection) serves as a + * wildcard and matches any detail argument passed in to emission. + * + * While the @detail argument is typically used to pass an object property name + * (as with #GObject::notify), no specific format is mandated for the detail + * string, other than that it must be non-empty. + * + * ## Memory management of signal handlers # {#signal-memory-management} + * + * If you are connecting handlers to signals and using a #GObject instance as + * your signal handler user data, you should remember to pair calls to + * g_signal_connect() with calls to g_signal_handler_disconnect() or + * g_signal_handlers_disconnect_by_func(). While signal handlers are + * automatically disconnected when the object emitting the signal is finalised, + * they are not automatically disconnected when the signal handler user data is + * destroyed. If this user data is a #GObject instance, using it from a + * signal handler after it has been finalised is an error. + * + * There are two strategies for managing such user data. The first is to + * disconnect the signal handler (using g_signal_handler_disconnect() or + * g_signal_handlers_disconnect_by_func()) when the user data (object) is + * finalised; this has to be implemented manually. For non-threaded programs, + * g_signal_connect_object() can be used to implement this automatically. + * Currently, however, it is unsafe to use in threaded programs. + * + * The second is to hold a strong reference on the user data until after the + * signal is disconnected for other reasons. This can be implemented + * automatically using g_signal_connect_data(). + * + * The first approach is recommended, as the second approach can result in + * effective memory leaks of the user data if the signal handler is never + * disconnected for some reason. + */ + + +#define REPORT_BUG "please report occurrence circumstances to https://gitlab.gnome.org/GNOME/glib/issues/new" + +/* --- typedefs --- */ +typedef struct _SignalNode SignalNode; +typedef struct _SignalKey SignalKey; +typedef struct _Emission Emission; +typedef struct _Handler Handler; +typedef struct _HandlerList HandlerList; +typedef struct _HandlerMatch HandlerMatch; +typedef enum +{ + EMISSION_STOP, + EMISSION_RUN, + EMISSION_HOOK, + EMISSION_RESTART +} EmissionState; + + +/* --- prototypes --- */ +static inline guint signal_id_lookup (const gchar *name, + GType itype); +static void signal_destroy_R (SignalNode *signal_node); +static inline HandlerList* handler_list_ensure (guint signal_id, + gpointer instance); +static inline HandlerList* handler_list_lookup (guint signal_id, + gpointer instance); +static inline Handler* handler_new (guint signal_id, + gpointer instance, + gboolean after); +static void handler_insert (guint signal_id, + gpointer instance, + Handler *handler); +static Handler* handler_lookup (gpointer instance, + gulong handler_id, + GClosure *closure, + guint *signal_id_p); +static inline HandlerMatch* handler_match_prepend (HandlerMatch *list, + Handler *handler, + guint signal_id); +static inline HandlerMatch* handler_match_free1_R (HandlerMatch *node, + gpointer instance); +static HandlerMatch* handlers_find (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data, + gboolean one_and_only); +static inline void handler_ref (Handler *handler); +static inline void handler_unref_R (guint signal_id, + gpointer instance, + Handler *handler); +static gint handler_lists_cmp (gconstpointer node1, + gconstpointer node2); +static inline void emission_push (Emission *emission); +static inline void emission_pop (Emission *emission); +static inline Emission* emission_find (guint signal_id, + GQuark detail, + gpointer instance); +static gint class_closures_cmp (gconstpointer node1, + gconstpointer node2); +static gint signal_key_cmp (gconstpointer node1, + gconstpointer node2); +static gboolean signal_emit_unlocked_R (SignalNode *node, + GQuark detail, + gpointer instance, + GValue *return_value, + const GValue *instance_and_params); +static void add_invalid_closure_notify (Handler *handler, + gpointer instance); +static void remove_invalid_closure_notify (Handler *handler, + gpointer instance); +static void invalid_closure_notify (gpointer data, + GClosure *closure); +static const gchar * type_debug_name (GType type); +static void node_check_deprecated (const SignalNode *node); +static void node_update_single_va_closure (SignalNode *node); + + +/* --- structures --- */ +typedef struct +{ + GSignalAccumulator func; + gpointer data; +} SignalAccumulator; +typedef struct +{ + GHook hook; + GQuark detail; +} SignalHook; +#define SIGNAL_HOOK(hook) ((SignalHook*) (hook)) + +struct _SignalNode +{ + /* permanent portion */ + guint signal_id; + GType itype; + const gchar *name; + guint destroyed : 1; + + /* reinitializable portion */ + guint flags : 9; + guint n_params : 8; + guint single_va_closure_is_valid : 1; + guint single_va_closure_is_after : 1; + GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ + GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ + GBSearchArray *class_closure_bsa; + SignalAccumulator *accumulator; + GSignalCMarshaller c_marshaller; + GSignalCVaMarshaller va_marshaller; + GHookList *emission_hooks; + + GClosure *single_va_closure; +}; + +#define SINGLE_VA_CLOSURE_EMPTY_MAGIC GINT_TO_POINTER(1) /* indicates single_va_closure is valid but empty */ + +struct _SignalKey +{ + GType itype; + GQuark quark; + guint signal_id; +}; + +struct _Emission +{ + Emission *next; + gpointer instance; + GSignalInvocationHint ihint; + EmissionState state; + GType chain_type; +}; + +struct _HandlerList +{ + guint signal_id; + Handler *handlers; + Handler *tail_before; /* normal signal handlers are appended here */ + Handler *tail_after; /* CONNECT_AFTER handlers are appended here */ +}; + +struct _Handler +{ + gulong sequential_number; + Handler *next; + Handler *prev; + GQuark detail; + guint signal_id; + guint ref_count; + guint block_count : 16; +#define HANDLER_MAX_BLOCK_COUNT (1 << 16) + guint after : 1; + guint has_invalid_closure_notify : 1; + GClosure *closure; + gpointer instance; +}; +struct _HandlerMatch +{ + Handler *handler; + HandlerMatch *next; + guint signal_id; +}; + +typedef struct +{ + GType instance_type; /* 0 for default closure */ + GClosure *closure; +} ClassClosure; + + +/* --- variables --- */ +static GBSearchArray *g_signal_key_bsa = NULL; +static const GBSearchConfig g_signal_key_bconfig = { + sizeof (SignalKey), + signal_key_cmp, + G_BSEARCH_ARRAY_ALIGN_POWER2, +}; +static GBSearchConfig g_signal_hlbsa_bconfig = { + sizeof (HandlerList), + handler_lists_cmp, + 0, +}; +static GBSearchConfig g_class_closure_bconfig = { + sizeof (ClassClosure), + class_closures_cmp, + 0, +}; +static GHashTable *g_handler_list_bsa_ht = NULL; +static Emission *g_emissions = NULL; +static gulong g_handler_sequential_number = 1; +static GHashTable *g_handlers = NULL; + +G_LOCK_DEFINE_STATIC (g_signal_mutex); +#define SIGNAL_LOCK() G_LOCK (g_signal_mutex) +#define SIGNAL_UNLOCK() G_UNLOCK (g_signal_mutex) + + +/* --- signal nodes --- */ +static guint g_n_signal_nodes = 0; +static SignalNode **g_signal_nodes = NULL; + +static inline SignalNode* +LOOKUP_SIGNAL_NODE (guint signal_id) +{ + if (signal_id < g_n_signal_nodes) + return g_signal_nodes[signal_id]; + else + return NULL; +} + + +/* --- functions --- */ +/* @key must have already been validated with is_valid() + * Modifies @key in place. */ +static void +canonicalize_key (gchar *key) +{ + gchar *p; + + for (p = key; *p != 0; p++) + { + gchar c = *p; + + if (c == '_') + *p = '-'; + } +} + +/* @key must have already been validated with is_valid() */ +static gboolean +is_canonical (const gchar *key) +{ + return (strchr (key, '_') == NULL); +} + +/** + * g_signal_is_valid_name: + * @name: the canonical name of the signal + * + * Validate a signal name. This can be useful for dynamically-generated signals + * which need to be validated at run-time before actually trying to create them. + * + * See [canonical parameter names][canonical-parameter-names] for details of + * the rules for valid names. The rules for signal names are the same as those + * for property names. + * + * Returns: %TRUE if @name is a valid signal name, %FALSE otherwise. + * Since: 2.66 + */ +gboolean +g_signal_is_valid_name (const gchar *name) +{ + /* FIXME: We allow this, against our own documentation (the leading `-` is + * invalid), because GTK has historically used this. */ + if (g_str_equal (name, "-gtk-private-changed")) + return TRUE; + + return g_param_spec_is_valid_name (name); +} + +static inline guint +signal_id_lookup (const gchar *name, + GType itype) +{ + GQuark quark; + GType *ifaces, type = itype; + SignalKey key; + guint n_ifaces; + + quark = g_quark_try_string (name); + key.quark = quark; + + /* try looking up signals for this type and its ancestors */ + do + { + SignalKey *signal_key; + + key.itype = type; + signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key); + + if (signal_key) + return signal_key->signal_id; + + type = g_type_parent (type); + } + while (type); + + /* no luck, try interfaces it exports */ + ifaces = g_type_interfaces (itype, &n_ifaces); + while (n_ifaces--) + { + SignalKey *signal_key; + + key.itype = ifaces[n_ifaces]; + signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key); + + if (signal_key) + { + g_free (ifaces); + return signal_key->signal_id; + } + } + g_free (ifaces); + + /* If the @name is non-canonical, try again. This is the slow path — people + * should use canonical names in their queries if they want performance. */ + if (!is_canonical (name)) + { + guint signal_id; + gchar *name_copy = g_strdup (name); + canonicalize_key (name_copy); + + signal_id = signal_id_lookup (name_copy, itype); + + g_free (name_copy); + + return signal_id; + } + + return 0; +} + +static gint +class_closures_cmp (gconstpointer node1, + gconstpointer node2) +{ + const ClassClosure *c1 = node1, *c2 = node2; + + return G_BSEARCH_ARRAY_CMP (c1->instance_type, c2->instance_type); +} + +static gint +handler_lists_cmp (gconstpointer node1, + gconstpointer node2) +{ + const HandlerList *hlist1 = node1, *hlist2 = node2; + + return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id); +} + +static inline HandlerList* +handler_list_ensure (guint signal_id, + gpointer instance) +{ + GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); + HandlerList key; + + key.signal_id = signal_id; + key.handlers = NULL; + key.tail_before = NULL; + key.tail_after = NULL; + if (!hlbsa) + { + hlbsa = g_bsearch_array_create (&g_signal_hlbsa_bconfig); + hlbsa = g_bsearch_array_insert (hlbsa, &g_signal_hlbsa_bconfig, &key); + g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa); + } + else + { + GBSearchArray *o = hlbsa; + + hlbsa = g_bsearch_array_insert (o, &g_signal_hlbsa_bconfig, &key); + if (hlbsa != o) + g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa); + } + return g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key); +} + +static inline HandlerList* +handler_list_lookup (guint signal_id, + gpointer instance) +{ + GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); + HandlerList key; + + key.signal_id = signal_id; + + return hlbsa ? g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key) : NULL; +} + +static guint +handler_hash (gconstpointer key) +{ + return (guint)((Handler*)key)->sequential_number; +} + +static gboolean +handler_equal (gconstpointer a, gconstpointer b) +{ + Handler *ha = (Handler *)a; + Handler *hb = (Handler *)b; + return (ha->sequential_number == hb->sequential_number) && + (ha->instance == hb->instance); +} + +static Handler* +handler_lookup (gpointer instance, + gulong handler_id, + GClosure *closure, + guint *signal_id_p) +{ + GBSearchArray *hlbsa; + + if (handler_id) + { + Handler key; + key.sequential_number = handler_id; + key.instance = instance; + return g_hash_table_lookup (g_handlers, &key); + + } + + hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); + + if (hlbsa) + { + guint i; + + for (i = 0; i < hlbsa->n_nodes; i++) + { + HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i); + Handler *handler; + + for (handler = hlist->handlers; handler; handler = handler->next) + if (closure ? (handler->closure == closure) : (handler->sequential_number == handler_id)) + { + if (signal_id_p) + *signal_id_p = hlist->signal_id; + + return handler; + } + } + } + + return NULL; +} + +static inline HandlerMatch* +handler_match_prepend (HandlerMatch *list, + Handler *handler, + guint signal_id) +{ + HandlerMatch *node; + + node = g_slice_new (HandlerMatch); + node->handler = handler; + node->next = list; + node->signal_id = signal_id; + handler_ref (handler); + + return node; +} +static inline HandlerMatch* +handler_match_free1_R (HandlerMatch *node, + gpointer instance) +{ + HandlerMatch *next = node->next; + + handler_unref_R (node->signal_id, instance, node->handler); + g_slice_free (HandlerMatch, node); + + return next; +} + +static HandlerMatch* +handlers_find (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data, + gboolean one_and_only) +{ + HandlerMatch *mlist = NULL; + + if (mask & G_SIGNAL_MATCH_ID) + { + HandlerList *hlist = handler_list_lookup (signal_id, instance); + Handler *handler; + SignalNode *node = NULL; + + if (mask & G_SIGNAL_MATCH_FUNC) + { + node = LOOKUP_SIGNAL_NODE (signal_id); + if (!node || !node->c_marshaller) + return NULL; + } + + mask = ~mask; + for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next) + if (handler->sequential_number && + ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && + ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && + ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && + ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && + ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && + G_REAL_CLOSURE (handler->closure)->meta_marshal == NULL && + ((GCClosure*) handler->closure)->callback == func))) + { + mlist = handler_match_prepend (mlist, handler, signal_id); + if (one_and_only) + return mlist; + } + } + else + { + GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); + + mask = ~mask; + if (hlbsa) + { + guint i; + + for (i = 0; i < hlbsa->n_nodes; i++) + { + HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i); + SignalNode *node = NULL; + Handler *handler; + + if (!(mask & G_SIGNAL_MATCH_FUNC)) + { + node = LOOKUP_SIGNAL_NODE (hlist->signal_id); + if (!node->c_marshaller) + continue; + } + + for (handler = hlist->handlers; handler; handler = handler->next) + if (handler->sequential_number && + ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && + ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && + ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && + ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && + ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && + G_REAL_CLOSURE (handler->closure)->meta_marshal == NULL && + ((GCClosure*) handler->closure)->callback == func))) + { + mlist = handler_match_prepend (mlist, handler, hlist->signal_id); + if (one_and_only) + return mlist; + } + } + } + } + + return mlist; +} + +static inline Handler* +handler_new (guint signal_id, gpointer instance, gboolean after) +{ + Handler *handler = g_slice_new (Handler); +#ifndef G_DISABLE_CHECKS + if (g_handler_sequential_number < 1) + g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG); +#endif + + handler->sequential_number = g_handler_sequential_number++; + handler->prev = NULL; + handler->next = NULL; + handler->detail = 0; + handler->signal_id = signal_id; + handler->instance = instance; + handler->ref_count = 1; + handler->block_count = 0; + handler->after = after != FALSE; + handler->closure = NULL; + handler->has_invalid_closure_notify = 0; + + g_hash_table_add (g_handlers, handler); + + return handler; +} + +static inline void +handler_ref (Handler *handler) +{ + g_return_if_fail (handler->ref_count > 0); + + handler->ref_count++; +} + +static inline void +handler_unref_R (guint signal_id, + gpointer instance, + Handler *handler) +{ + g_return_if_fail (handler->ref_count > 0); + + handler->ref_count--; + + if (G_UNLIKELY (handler->ref_count == 0)) + { + HandlerList *hlist = NULL; + + if (handler->next) + handler->next->prev = handler->prev; + if (handler->prev) /* watch out for g_signal_handlers_destroy()! */ + handler->prev->next = handler->next; + else + { + hlist = handler_list_lookup (signal_id, instance); + g_assert (hlist != NULL); + hlist->handlers = handler->next; + } + + if (instance) + { + /* check if we are removing the handler pointed to by tail_before */ + if (!handler->after && (!handler->next || handler->next->after)) + { + if (!hlist) + hlist = handler_list_lookup (signal_id, instance); + if (hlist) + { + g_assert (hlist->tail_before == handler); /* paranoid */ + hlist->tail_before = handler->prev; + } + } + + /* check if we are removing the handler pointed to by tail_after */ + if (!handler->next) + { + if (!hlist) + hlist = handler_list_lookup (signal_id, instance); + if (hlist) + { + g_assert (hlist->tail_after == handler); /* paranoid */ + hlist->tail_after = handler->prev; + } + } + } + + SIGNAL_UNLOCK (); + g_closure_unref (handler->closure); + SIGNAL_LOCK (); + g_slice_free (Handler, handler); + } +} + +static void +handler_insert (guint signal_id, + gpointer instance, + Handler *handler) +{ + HandlerList *hlist; + + g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */ + + hlist = handler_list_ensure (signal_id, instance); + if (!hlist->handlers) + { + hlist->handlers = handler; + if (!handler->after) + hlist->tail_before = handler; + } + else if (handler->after) + { + handler->prev = hlist->tail_after; + hlist->tail_after->next = handler; + } + else + { + if (hlist->tail_before) + { + handler->next = hlist->tail_before->next; + if (handler->next) + handler->next->prev = handler; + handler->prev = hlist->tail_before; + hlist->tail_before->next = handler; + } + else /* insert !after handler into a list of only after handlers */ + { + handler->next = hlist->handlers; + if (handler->next) + handler->next->prev = handler; + hlist->handlers = handler; + } + hlist->tail_before = handler; + } + + if (!handler->next) + hlist->tail_after = handler; +} + +static void +node_update_single_va_closure (SignalNode *node) +{ + GClosure *closure = NULL; + gboolean is_after = FALSE; + + /* Fast path single-handler without boxing the arguments in GValues */ + if (G_TYPE_IS_OBJECT (node->itype) && + (node->flags & (G_SIGNAL_MUST_COLLECT)) == 0 && + (node->emission_hooks == NULL || node->emission_hooks->hooks == NULL)) + { + GSignalFlags run_type; + ClassClosure * cc; + GBSearchArray *bsa = node->class_closure_bsa; + + if (bsa == NULL || bsa->n_nodes == 0) + closure = SINGLE_VA_CLOSURE_EMPTY_MAGIC; + else if (bsa->n_nodes == 1) + { + /* Look for default class closure (can't support non-default as it + chains up using GValues */ + cc = g_bsearch_array_get_nth (bsa, &g_class_closure_bconfig, 0); + if (cc->instance_type == 0) + { + run_type = node->flags & (G_SIGNAL_RUN_FIRST|G_SIGNAL_RUN_LAST|G_SIGNAL_RUN_CLEANUP); + /* Only support *one* of run-first or run-last, not multiple or cleanup */ + if (run_type == G_SIGNAL_RUN_FIRST || + run_type == G_SIGNAL_RUN_LAST) + { + closure = cc->closure; + is_after = (run_type == G_SIGNAL_RUN_LAST); + } + } + } + } + + node->single_va_closure_is_valid = TRUE; + node->single_va_closure = closure; + node->single_va_closure_is_after = is_after; +} + +static inline void +emission_push (Emission *emission) +{ + emission->next = g_emissions; + g_emissions = emission; +} + +static inline void +emission_pop (Emission *emission) +{ + Emission *node, *last = NULL; + + for (node = g_emissions; node; last = node, node = last->next) + if (node == emission) + { + if (last) + last->next = node->next; + else + g_emissions = node->next; + return; + } + g_assert_not_reached (); +} + +static inline Emission* +emission_find (guint signal_id, + GQuark detail, + gpointer instance) +{ + Emission *emission; + + for (emission = g_emissions; emission; emission = emission->next) + if (emission->instance == instance && + emission->ihint.signal_id == signal_id && + emission->ihint.detail == detail) + return emission; + return NULL; +} + +static inline Emission* +emission_find_innermost (gpointer instance) +{ + Emission *emission; + + for (emission = g_emissions; emission; emission = emission->next) + if (emission->instance == instance) + return emission; + + return NULL; +} + +static gint +signal_key_cmp (gconstpointer node1, + gconstpointer node2) +{ + const SignalKey *key1 = node1, *key2 = node2; + + if (key1->itype == key2->itype) + return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark); + else + return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype); +} + +void +_g_signal_init (void) +{ + SIGNAL_LOCK (); + if (!g_n_signal_nodes) + { + /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */ + g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL); + g_signal_key_bsa = g_bsearch_array_create (&g_signal_key_bconfig); + + /* invalid (0) signal_id */ + g_n_signal_nodes = 1; + g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); + g_signal_nodes[0] = NULL; + g_handlers = g_hash_table_new (handler_hash, handler_equal); + } + SIGNAL_UNLOCK (); +} + +void +_g_signals_destroy (GType itype) +{ + guint i; + + SIGNAL_LOCK (); + for (i = 1; i < g_n_signal_nodes; i++) + { + SignalNode *node = g_signal_nodes[i]; + + if (node->itype == itype) + { + if (node->destroyed) + g_warning (G_STRLOC ": signal \"%s\" of type '%s' already destroyed", + node->name, + type_debug_name (node->itype)); + else + signal_destroy_R (node); + } + } + SIGNAL_UNLOCK (); +} + +/** + * g_signal_stop_emission: + * @instance: (type GObject.Object): the object whose signal handlers you wish to stop. + * @signal_id: the signal identifier, as returned by g_signal_lookup(). + * @detail: the detail which the signal was emitted with. + * + * Stops a signal's current emission. + * + * This will prevent the default method from running, if the signal was + * %G_SIGNAL_RUN_LAST and you connected normally (i.e. without the "after" + * flag). + * + * Prints a warning if used on a signal which isn't being emitted. + */ +void +g_signal_stop_emission (gpointer instance, + guint signal_id, + GQuark detail) +{ + SignalNode *node; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (signal_id > 0); + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (node && detail && !(node->flags & G_SIGNAL_DETAILED)) + { + g_warning ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail); + SIGNAL_UNLOCK (); + return; + } + if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) + { + Emission *emission = emission_find (signal_id, detail, instance); + + if (emission) + { + if (emission->state == EMISSION_HOOK) + g_warning (G_STRLOC ": emission of signal \"%s\" for instance '%p' cannot be stopped from emission hook", + node->name, instance); + else if (emission->state == EMISSION_RUN) + emission->state = EMISSION_STOP; + } + else + g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance '%p'", + node->name, instance); + } + else + g_warning ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance); + SIGNAL_UNLOCK (); +} + +static void +signal_finalize_hook (GHookList *hook_list, + GHook *hook) +{ + GDestroyNotify destroy = hook->destroy; + + if (destroy) + { + hook->destroy = NULL; + SIGNAL_UNLOCK (); + destroy (hook->data); + SIGNAL_LOCK (); + } +} + +/** + * g_signal_add_emission_hook: + * @signal_id: the signal identifier, as returned by g_signal_lookup(). + * @detail: the detail on which to call the hook. + * @hook_func: (not nullable): a #GSignalEmissionHook function. + * @hook_data: (nullable) (closure hook_func): user data for @hook_func. + * @data_destroy: (nullable) (destroy hook_data): a #GDestroyNotify for @hook_data. + * + * Adds an emission hook for a signal, which will get called for any emission + * of that signal, independent of the instance. This is possible only + * for signals which don't have %G_SIGNAL_NO_HOOKS flag set. + * + * Returns: the hook id, for later use with g_signal_remove_emission_hook(). + */ +gulong +g_signal_add_emission_hook (guint signal_id, + GQuark detail, + GSignalEmissionHook hook_func, + gpointer hook_data, + GDestroyNotify data_destroy) +{ + static gulong seq_hook_id = 1; + SignalNode *node; + GHook *hook; + SignalHook *signal_hook; + + g_return_val_if_fail (signal_id > 0, 0); + g_return_val_if_fail (hook_func != NULL, 0); + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (!node || node->destroyed) + { + g_warning ("%s: invalid signal id '%u'", G_STRLOC, signal_id); + SIGNAL_UNLOCK (); + return 0; + } + if (node->flags & G_SIGNAL_NO_HOOKS) + { + g_warning ("%s: signal id '%u' does not support emission hooks (G_SIGNAL_NO_HOOKS flag set)", G_STRLOC, signal_id); + SIGNAL_UNLOCK (); + return 0; + } + if (detail && !(node->flags & G_SIGNAL_DETAILED)) + { + g_warning ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail); + SIGNAL_UNLOCK (); + return 0; + } + node->single_va_closure_is_valid = FALSE; + if (!node->emission_hooks) + { + node->emission_hooks = g_new (GHookList, 1); + g_hook_list_init (node->emission_hooks, sizeof (SignalHook)); + node->emission_hooks->finalize_hook = signal_finalize_hook; + } + + node_check_deprecated (node); + + hook = g_hook_alloc (node->emission_hooks); + hook->data = hook_data; + hook->func = (gpointer) hook_func; + hook->destroy = data_destroy; + signal_hook = SIGNAL_HOOK (hook); + signal_hook->detail = detail; + node->emission_hooks->seq_id = seq_hook_id; + g_hook_append (node->emission_hooks, hook); + seq_hook_id = node->emission_hooks->seq_id; + + SIGNAL_UNLOCK (); + + return hook->hook_id; +} + +/** + * g_signal_remove_emission_hook: + * @signal_id: the id of the signal + * @hook_id: the id of the emission hook, as returned by + * g_signal_add_emission_hook() + * + * Deletes an emission hook. + */ +void +g_signal_remove_emission_hook (guint signal_id, + gulong hook_id) +{ + SignalNode *node; + + g_return_if_fail (signal_id > 0); + g_return_if_fail (hook_id > 0); + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (!node || node->destroyed) + { + g_warning ("%s: invalid signal id '%u'", G_STRLOC, signal_id); + goto out; + } + else if (!node->emission_hooks || !g_hook_destroy (node->emission_hooks, hook_id)) + g_warning ("%s: signal \"%s\" had no hook (%lu) to remove", G_STRLOC, node->name, hook_id); + + node->single_va_closure_is_valid = FALSE; + + out: + SIGNAL_UNLOCK (); +} + +static inline guint +signal_parse_name (const gchar *name, + GType itype, + GQuark *detail_p, + gboolean force_quark) +{ + const gchar *colon = strchr (name, ':'); + guint signal_id; + + if (!colon) + { + signal_id = signal_id_lookup (name, itype); + if (signal_id && detail_p) + *detail_p = 0; + } + else if (colon[1] == ':') + { + gchar buffer[32]; + guint l = colon - name; + + if (colon[2] == '\0') + return 0; + + if (l < 32) + { + memcpy (buffer, name, l); + buffer[l] = 0; + signal_id = signal_id_lookup (buffer, itype); + } + else + { + gchar *signal = g_new (gchar, l + 1); + + memcpy (signal, name, l); + signal[l] = 0; + signal_id = signal_id_lookup (signal, itype); + g_free (signal); + } + + if (signal_id && detail_p) + *detail_p = (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2); + } + else + signal_id = 0; + return signal_id; +} + +/** + * g_signal_parse_name: + * @detailed_signal: a string of the form "signal-name::detail". + * @itype: The interface/instance type that introduced "signal-name". + * @signal_id_p: (out): Location to store the signal id. + * @detail_p: (out): Location to store the detail quark. + * @force_detail_quark: %TRUE forces creation of a #GQuark for the detail. + * + * Internal function to parse a signal name into its @signal_id + * and @detail quark. + * + * Returns: Whether the signal name could successfully be parsed and @signal_id_p and @detail_p contain valid return values. + */ +gboolean +g_signal_parse_name (const gchar *detailed_signal, + GType itype, + guint *signal_id_p, + GQuark *detail_p, + gboolean force_detail_quark) +{ + SignalNode *node; + GQuark detail = 0; + guint signal_id; + + g_return_val_if_fail (detailed_signal != NULL, FALSE); + g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE); + + SIGNAL_LOCK (); + signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark); + SIGNAL_UNLOCK (); + + node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL; + if (!node || node->destroyed || + (detail && !(node->flags & G_SIGNAL_DETAILED))) + return FALSE; + + if (signal_id_p) + *signal_id_p = signal_id; + if (detail_p) + *detail_p = detail; + + return TRUE; +} + +/** + * g_signal_stop_emission_by_name: + * @instance: (type GObject.Object): the object whose signal handlers you wish to stop. + * @detailed_signal: a string of the form "signal-name::detail". + * + * Stops a signal's current emission. + * + * This is just like g_signal_stop_emission() except it will look up the + * signal id for you. + */ +void +g_signal_stop_emission_by_name (gpointer instance, + const gchar *detailed_signal) +{ + guint signal_id; + GQuark detail = 0; + GType itype; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (detailed_signal != NULL); + + SIGNAL_LOCK (); + itype = G_TYPE_FROM_INSTANCE (instance); + signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); + if (signal_id) + { + SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); + + if (detail && !(node->flags & G_SIGNAL_DETAILED)) + g_warning ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal); + else if (!g_type_is_a (itype, node->itype)) + g_warning ("%s: signal '%s' is invalid for instance '%p' of type '%s'", + G_STRLOC, detailed_signal, instance, g_type_name (itype)); + else + { + Emission *emission = emission_find (signal_id, detail, instance); + + if (emission) + { + if (emission->state == EMISSION_HOOK) + g_warning (G_STRLOC ": emission of signal \"%s\" for instance '%p' cannot be stopped from emission hook", + node->name, instance); + else if (emission->state == EMISSION_RUN) + emission->state = EMISSION_STOP; + } + else + g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance '%p'", + node->name, instance); + } + } + else + g_warning ("%s: signal '%s' is invalid for instance '%p' of type '%s'", + G_STRLOC, detailed_signal, instance, g_type_name (itype)); + SIGNAL_UNLOCK (); +} + +/** + * g_signal_lookup: + * @name: the signal's name. + * @itype: the type that the signal operates on. + * + * Given the name of the signal and the type of object it connects to, gets + * the signal's identifying integer. Emitting the signal by number is + * somewhat faster than using the name each time. + * + * Also tries the ancestors of the given type. + * + * The type class passed as @itype must already have been instantiated (for + * example, using g_type_class_ref()) for this function to work, as signals are + * always installed during class initialization. + * + * See g_signal_new() for details on allowed signal names. + * + * Returns: the signal's identifying number, or 0 if no signal was found. + */ +guint +g_signal_lookup (const gchar *name, + GType itype) +{ + guint signal_id; + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); + + SIGNAL_LOCK (); + signal_id = signal_id_lookup (name, itype); + SIGNAL_UNLOCK (); + if (!signal_id) + { + /* give elaborate warnings */ + if (!g_type_name (itype)) + g_warning (G_STRLOC ": unable to look up signal \"%s\" for invalid type id '%"G_GSIZE_FORMAT"'", + name, itype); + else if (!g_signal_is_valid_name (name)) + g_warning (G_STRLOC ": unable to look up invalid signal name \"%s\" on type '%s'", + name, g_type_name (itype)); + } + + return signal_id; +} + +/** + * g_signal_list_ids: + * @itype: Instance or interface type. + * @n_ids: Location to store the number of signal ids for @itype. + * + * Lists the signals by id that a certain instance or interface type + * created. Further information about the signals can be acquired through + * g_signal_query(). + * + * Returns: (array length=n_ids) (transfer full): Newly allocated array of signal IDs. + */ +guint* +g_signal_list_ids (GType itype, + guint *n_ids) +{ + SignalKey *keys; + GArray *result; + guint n_nodes; + guint i; + + g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL); + g_return_val_if_fail (n_ids != NULL, NULL); + + SIGNAL_LOCK (); + keys = g_bsearch_array_get_nth (g_signal_key_bsa, &g_signal_key_bconfig, 0); + n_nodes = g_bsearch_array_get_n_nodes (g_signal_key_bsa); + result = g_array_new (FALSE, FALSE, sizeof (guint)); + + for (i = 0; i < n_nodes; i++) + if (keys[i].itype == itype) + { + g_array_append_val (result, keys[i].signal_id); + } + *n_ids = result->len; + SIGNAL_UNLOCK (); + if (!n_nodes) + { + /* give elaborate warnings */ + if (!g_type_name (itype)) + g_warning (G_STRLOC ": unable to list signals for invalid type id '%"G_GSIZE_FORMAT"'", + itype); + else if (!G_TYPE_IS_INSTANTIATABLE (itype) && !G_TYPE_IS_INTERFACE (itype)) + g_warning (G_STRLOC ": unable to list signals of non instantiatable type '%s'", + g_type_name (itype)); + else if (!g_type_class_peek (itype) && !G_TYPE_IS_INTERFACE (itype)) + g_warning (G_STRLOC ": unable to list signals of unloaded type '%s'", + g_type_name (itype)); + } + + return (guint*) g_array_free (result, FALSE); +} + +/** + * g_signal_name: + * @signal_id: the signal's identifying number. + * + * Given the signal's identifier, finds its name. + * + * Two different signals may have the same name, if they have differing types. + * + * Returns: (nullable): the signal name, or %NULL if the signal number was invalid. + */ +const gchar * +g_signal_name (guint signal_id) +{ + SignalNode *node; + const gchar *name; + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + name = node ? node->name : NULL; + SIGNAL_UNLOCK (); + + return (char*) name; +} + +/** + * g_signal_query: + * @signal_id: The signal id of the signal to query information for. + * @query: (out caller-allocates) (not optional): A user provided structure that is + * filled in with constant values upon success. + * + * Queries the signal system for in-depth information about a + * specific signal. This function will fill in a user-provided + * structure to hold signal-specific information. If an invalid + * signal id is passed in, the @signal_id member of the #GSignalQuery + * is 0. All members filled into the #GSignalQuery structure should + * be considered constant and have to be left untouched. + */ +void +g_signal_query (guint signal_id, + GSignalQuery *query) +{ + SignalNode *node; + + g_return_if_fail (query != NULL); + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (!node || node->destroyed) + query->signal_id = 0; + else + { + query->signal_id = node->signal_id; + query->signal_name = node->name; + query->itype = node->itype; + query->signal_flags = node->flags; + query->return_type = node->return_type; + query->n_params = node->n_params; + query->param_types = node->param_types; + } + SIGNAL_UNLOCK (); +} + +/** + * g_signal_new: + * @signal_name: the name for the signal + * @itype: the type this signal pertains to. It will also pertain to + * types which are derived from this type. + * @signal_flags: a combination of #GSignalFlags specifying detail of when + * the default handler is to be invoked. You should at least specify + * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST. + * @class_offset: The offset of the function pointer in the class structure + * for this type. Used to invoke a class method generically. Pass 0 to + * not associate a class method slot with this signal. + * @accumulator: (nullable): the accumulator for this signal; may be %NULL. + * @accu_data: (nullable) (closure accumulator): user data for the @accumulator. + * @c_marshaller: (nullable): the function to translate arrays of parameter + * values to signal emissions into C language callback invocations or %NULL. + * @return_type: the type of return value, or %G_TYPE_NONE for a signal + * without a return value. + * @n_params: the number of parameter types to follow. + * @...: a list of types, one for each parameter. + * + * Creates a new signal. (This is usually done in the class initializer.) + * + * A signal name consists of segments consisting of ASCII letters and + * digits, separated by either the `-` or `_` character. The first + * character of a signal name must be a letter. Names which violate these + * rules lead to undefined behaviour. These are the same rules as for property + * naming (see g_param_spec_internal()). + * + * When registering a signal and looking up a signal, either separator can + * be used, but they cannot be mixed. Using `-` is considerably more efficient. + * Using `_` is discouraged. + * + * If 0 is used for @class_offset subclasses cannot override the class handler + * in their class_init method by doing super_class->signal_handler = my_signal_handler. + * Instead they will have to use g_signal_override_class_handler(). + * + * If @c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as + * the marshaller for this signal. In some simple cases, g_signal_new() + * will use a more optimized c_marshaller and va_marshaller for the signal + * instead of g_cclosure_marshal_generic(). + * + * If @c_marshaller is non-%NULL, you need to also specify a va_marshaller + * using g_signal_set_va_marshaller() or the generic va_marshaller will + * be used. + * + * Returns: the signal id + */ +guint +g_signal_new (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + guint class_offset, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + ...) +{ + va_list args; + guint signal_id; + + g_return_val_if_fail (signal_name != NULL, 0); + + va_start (args, n_params); + + signal_id = g_signal_new_valist (signal_name, itype, signal_flags, + class_offset ? g_signal_type_cclosure_new (itype, class_offset) : NULL, + accumulator, accu_data, c_marshaller, + return_type, n_params, args); + + va_end (args); + + return signal_id; +} + +/** + * g_signal_new_class_handler: + * @signal_name: the name for the signal + * @itype: the type this signal pertains to. It will also pertain to + * types which are derived from this type. + * @signal_flags: a combination of #GSignalFlags specifying detail of when + * the default handler is to be invoked. You should at least specify + * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST. + * @class_handler: (nullable): a #GCallback which acts as class implementation of + * this signal. Used to invoke a class method generically. Pass %NULL to + * not associate a class method with this signal. + * @accumulator: (nullable): the accumulator for this signal; may be %NULL. + * @accu_data: (nullable) (closure accumulator): user data for the @accumulator. + * @c_marshaller: (nullable): the function to translate arrays of parameter + * values to signal emissions into C language callback invocations or %NULL. + * @return_type: the type of return value, or %G_TYPE_NONE for a signal + * without a return value. + * @n_params: the number of parameter types to follow. + * @...: a list of types, one for each parameter. + * + * Creates a new signal. (This is usually done in the class initializer.) + * + * This is a variant of g_signal_new() that takes a C callback instead + * of a class offset for the signal's class handler. This function + * doesn't need a function pointer exposed in the class structure of + * an object definition, instead the function pointer is passed + * directly and can be overridden by derived classes with + * g_signal_override_class_closure() or + * g_signal_override_class_handler() and chained to with + * g_signal_chain_from_overridden() or + * g_signal_chain_from_overridden_handler(). + * + * See g_signal_new() for information about signal names. + * + * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as + * the marshaller for this signal. + * + * Returns: the signal id + * + * Since: 2.18 + */ +guint +g_signal_new_class_handler (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + GCallback class_handler, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + ...) +{ + va_list args; + guint signal_id; + + g_return_val_if_fail (signal_name != NULL, 0); + + va_start (args, n_params); + + signal_id = g_signal_new_valist (signal_name, itype, signal_flags, + class_handler ? g_cclosure_new (class_handler, NULL, NULL) : NULL, + accumulator, accu_data, c_marshaller, + return_type, n_params, args); + + va_end (args); + + return signal_id; +} + +static inline ClassClosure* +signal_find_class_closure (SignalNode *node, + GType itype) +{ + GBSearchArray *bsa = node->class_closure_bsa; + ClassClosure *cc; + + if (bsa) + { + ClassClosure key; + + /* cc->instance_type is 0 for default closure */ + + if (g_bsearch_array_get_n_nodes (bsa) == 1) + { + cc = g_bsearch_array_get_nth (bsa, &g_class_closure_bconfig, 0); + if (cc && cc->instance_type == 0) /* check for default closure */ + return cc; + } + + key.instance_type = itype; + cc = g_bsearch_array_lookup (bsa, &g_class_closure_bconfig, &key); + while (!cc && key.instance_type) + { + key.instance_type = g_type_parent (key.instance_type); + cc = g_bsearch_array_lookup (bsa, &g_class_closure_bconfig, &key); + } + } + else + cc = NULL; + return cc; +} + +static inline GClosure* +signal_lookup_closure (SignalNode *node, + GTypeInstance *instance) +{ + ClassClosure *cc; + + cc = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance)); + return cc ? cc->closure : NULL; +} + +static void +signal_add_class_closure (SignalNode *node, + GType itype, + GClosure *closure) +{ + ClassClosure key; + + node->single_va_closure_is_valid = FALSE; + + if (!node->class_closure_bsa) + node->class_closure_bsa = g_bsearch_array_create (&g_class_closure_bconfig); + key.instance_type = itype; + key.closure = g_closure_ref (closure); + node->class_closure_bsa = g_bsearch_array_insert (node->class_closure_bsa, + &g_class_closure_bconfig, + &key); + g_closure_sink (closure); + if (node->c_marshaller && closure && G_CLOSURE_NEEDS_MARSHAL (closure)) + { + g_closure_set_marshal (closure, node->c_marshaller); + if (node->va_marshaller) + _g_closure_set_va_marshal (closure, node->va_marshaller); + } +} + +/** + * g_signal_newv: + * @signal_name: the name for the signal + * @itype: the type this signal pertains to. It will also pertain to + * types which are derived from this type + * @signal_flags: a combination of #GSignalFlags specifying detail of when + * the default handler is to be invoked. You should at least specify + * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST + * @class_closure: (nullable): The closure to invoke on signal emission; + * may be %NULL + * @accumulator: (nullable): the accumulator for this signal; may be %NULL + * @accu_data: (nullable) (closure accumulator): user data for the @accumulator + * @c_marshaller: (nullable): the function to translate arrays of + * parameter values to signal emissions into C language callback + * invocations or %NULL + * @return_type: the type of return value, or %G_TYPE_NONE for a signal + * without a return value + * @n_params: the length of @param_types + * @param_types: (array length=n_params) (nullable): an array of types, one for + * each parameter (may be %NULL if @n_params is zero) + * + * Creates a new signal. (This is usually done in the class initializer.) + * + * See g_signal_new() for details on allowed signal names. + * + * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as + * the marshaller for this signal. + * + * Returns: the signal id + */ +guint +g_signal_newv (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + GClosure *class_closure, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + GType *param_types) +{ + const gchar *name; + gchar *signal_name_copy = NULL; + guint signal_id, i; + SignalNode *node; + GSignalCMarshaller builtin_c_marshaller; + GSignalCVaMarshaller builtin_va_marshaller; + GSignalCVaMarshaller va_marshaller; + + g_return_val_if_fail (signal_name != NULL, 0); + g_return_val_if_fail (g_signal_is_valid_name (signal_name), 0); + g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); + if (n_params) + g_return_val_if_fail (param_types != NULL, 0); + g_return_val_if_fail ((return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == 0, 0); + if (return_type == (G_TYPE_NONE & ~G_SIGNAL_TYPE_STATIC_SCOPE)) + g_return_val_if_fail (accumulator == NULL, 0); + if (!accumulator) + g_return_val_if_fail (accu_data == NULL, 0); + g_return_val_if_fail ((signal_flags & G_SIGNAL_ACCUMULATOR_FIRST_RUN) == 0, 0); + + if (!is_canonical (signal_name)) + { + signal_name_copy = g_strdup (signal_name); + canonicalize_key (signal_name_copy); + name = signal_name_copy; + } + else + { + name = signal_name; + } + + SIGNAL_LOCK (); + + signal_id = signal_id_lookup (name, itype); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (node && !node->destroyed) + { + g_warning (G_STRLOC ": signal \"%s\" already exists in the '%s' %s", + name, + type_debug_name (node->itype), + G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry"); + g_free (signal_name_copy); + SIGNAL_UNLOCK (); + return 0; + } + if (node && node->itype != itype) + { + g_warning (G_STRLOC ": signal \"%s\" for type '%s' was previously created for type '%s'", + name, + type_debug_name (itype), + type_debug_name (node->itype)); + g_free (signal_name_copy); + SIGNAL_UNLOCK (); + return 0; + } + for (i = 0; i < n_params; i++) + if (!G_TYPE_IS_VALUE (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE)) + { + g_warning (G_STRLOC ": parameter %d of type '%s' for signal \"%s::%s\" is not a value type", + i + 1, type_debug_name (param_types[i]), type_debug_name (itype), name); + g_free (signal_name_copy); + SIGNAL_UNLOCK (); + return 0; + } + if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE)) + { + g_warning (G_STRLOC ": return value of type '%s' for signal \"%s::%s\" is not a value type", + type_debug_name (return_type), type_debug_name (itype), name); + g_free (signal_name_copy); + SIGNAL_UNLOCK (); + return 0; + } + + /* setup permanent portion of signal node */ + if (!node) + { + SignalKey key; + + signal_id = g_n_signal_nodes++; + node = g_new (SignalNode, 1); + node->signal_id = signal_id; + g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); + g_signal_nodes[signal_id] = node; + node->itype = itype; + key.itype = itype; + key.signal_id = signal_id; + node->name = g_intern_string (name); + key.quark = g_quark_from_string (name); + g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key); + + TRACE(GOBJECT_SIGNAL_NEW(signal_id, name, itype)); + } + node->destroyed = FALSE; + + /* setup reinitializable portion */ + node->single_va_closure_is_valid = FALSE; + node->flags = signal_flags & G_SIGNAL_FLAGS_MASK; + node->n_params = n_params; + node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params); + node->return_type = return_type; + node->class_closure_bsa = NULL; + if (accumulator) + { + node->accumulator = g_new (SignalAccumulator, 1); + node->accumulator->func = accumulator; + node->accumulator->data = accu_data; + } + else + node->accumulator = NULL; + + builtin_c_marshaller = NULL; + builtin_va_marshaller = NULL; + + /* Pick up built-in va marshallers for standard types, and + instead of generic marshaller if no marshaller specified */ + if (n_params == 0 && return_type == G_TYPE_NONE) + { + builtin_c_marshaller = g_cclosure_marshal_VOID__VOID; + builtin_va_marshaller = g_cclosure_marshal_VOID__VOIDv; + } + else if (n_params == 1 && return_type == G_TYPE_NONE) + { +#define ADD_CHECK(__type__) \ + else if (g_type_is_a (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_ ##__type__)) \ + { \ + builtin_c_marshaller = g_cclosure_marshal_VOID__ ## __type__; \ + builtin_va_marshaller = g_cclosure_marshal_VOID__ ## __type__ ##v; \ + } + + if (0) {} + ADD_CHECK (BOOLEAN) + ADD_CHECK (CHAR) + ADD_CHECK (UCHAR) + ADD_CHECK (INT) + ADD_CHECK (UINT) + ADD_CHECK (LONG) + ADD_CHECK (ULONG) + ADD_CHECK (ENUM) + ADD_CHECK (FLAGS) + ADD_CHECK (FLOAT) + ADD_CHECK (DOUBLE) + ADD_CHECK (STRING) + ADD_CHECK (PARAM) + ADD_CHECK (BOXED) + ADD_CHECK (POINTER) + ADD_CHECK (OBJECT) + ADD_CHECK (VARIANT) + } + + if (c_marshaller == NULL) + { + if (builtin_c_marshaller) + { + c_marshaller = builtin_c_marshaller; + va_marshaller = builtin_va_marshaller; + } + else + { + c_marshaller = g_cclosure_marshal_generic; + va_marshaller = g_cclosure_marshal_generic_va; + } + } + else + va_marshaller = NULL; + + node->c_marshaller = c_marshaller; + node->va_marshaller = va_marshaller; + node->emission_hooks = NULL; + if (class_closure) + signal_add_class_closure (node, 0, class_closure); + + SIGNAL_UNLOCK (); + + g_free (signal_name_copy); + + return signal_id; +} + +/** + * g_signal_set_va_marshaller: + * @signal_id: the signal id + * @instance_type: the instance type on which to set the marshaller. + * @va_marshaller: the marshaller to set. + * + * Change the #GSignalCVaMarshaller used for a given signal. This is a + * specialised form of the marshaller that can often be used for the + * common case of a single connected signal handler and avoids the + * overhead of #GValue. Its use is optional. + * + * Since: 2.32 + */ +void +g_signal_set_va_marshaller (guint signal_id, + GType instance_type, + GSignalCVaMarshaller va_marshaller) +{ + SignalNode *node; + + g_return_if_fail (signal_id > 0); + g_return_if_fail (va_marshaller != NULL); + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (node) + { + node->va_marshaller = va_marshaller; + if (node->class_closure_bsa) + { + ClassClosure *cc = g_bsearch_array_get_nth (node->class_closure_bsa, &g_class_closure_bconfig, 0); + if (cc->closure->marshal == node->c_marshaller) + _g_closure_set_va_marshal (cc->closure, va_marshaller); + } + + node->single_va_closure_is_valid = FALSE; + } + + SIGNAL_UNLOCK (); +} + + +/** + * g_signal_new_valist: + * @signal_name: the name for the signal + * @itype: the type this signal pertains to. It will also pertain to + * types which are derived from this type. + * @signal_flags: a combination of #GSignalFlags specifying detail of when + * the default handler is to be invoked. You should at least specify + * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST. + * @class_closure: (nullable): The closure to invoke on signal emission; may be %NULL. + * @accumulator: (nullable): the accumulator for this signal; may be %NULL. + * @accu_data: (nullable) (closure accumulator): user data for the @accumulator. + * @c_marshaller: (nullable): the function to translate arrays of parameter + * values to signal emissions into C language callback invocations or %NULL. + * @return_type: the type of return value, or %G_TYPE_NONE for a signal + * without a return value. + * @n_params: the number of parameter types in @args. + * @args: va_list of #GType, one for each parameter. + * + * Creates a new signal. (This is usually done in the class initializer.) + * + * See g_signal_new() for details on allowed signal names. + * + * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as + * the marshaller for this signal. + * + * Returns: the signal id + */ +guint +g_signal_new_valist (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + GClosure *class_closure, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + va_list args) +{ + /* Somewhat arbitrarily reserve 200 bytes. That should cover the majority + * of cases where n_params is small and still be small enough for what we + * want to put on the stack. */ + GType param_types_stack[200 / sizeof (GType)]; + GType *param_types_heap = NULL; + GType *param_types; + guint i; + guint signal_id; + + param_types = param_types_stack; + if (n_params > 0) + { + if (G_UNLIKELY (n_params > G_N_ELEMENTS (param_types_stack))) + { + param_types_heap = g_new (GType, n_params); + param_types = param_types_heap; + } + + for (i = 0; i < n_params; i++) + param_types[i] = va_arg (args, GType); + } + + signal_id = g_signal_newv (signal_name, itype, signal_flags, + class_closure, accumulator, accu_data, c_marshaller, + return_type, n_params, param_types); + g_free (param_types_heap); + + return signal_id; +} + +static void +signal_destroy_R (SignalNode *signal_node) +{ + SignalNode node = *signal_node; + + signal_node->destroyed = TRUE; + + /* reentrancy caution, zero out real contents first */ + signal_node->single_va_closure_is_valid = FALSE; + signal_node->n_params = 0; + signal_node->param_types = NULL; + signal_node->return_type = 0; + signal_node->class_closure_bsa = NULL; + signal_node->accumulator = NULL; + signal_node->c_marshaller = NULL; + signal_node->va_marshaller = NULL; + signal_node->emission_hooks = NULL; + +#ifdef G_ENABLE_DEBUG + /* check current emissions */ + { + Emission *emission; + + for (emission = g_emissions; emission; emission = emission->next) + if (emission->ihint.signal_id == node.signal_id) + g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance '%p')", + node.name, emission->instance); + } +#endif + + /* free contents that need to + */ + SIGNAL_UNLOCK (); + g_free (node.param_types); + if (node.class_closure_bsa) + { + guint i; + + for (i = 0; i < node.class_closure_bsa->n_nodes; i++) + { + ClassClosure *cc = g_bsearch_array_get_nth (node.class_closure_bsa, &g_class_closure_bconfig, i); + + g_closure_unref (cc->closure); + } + g_bsearch_array_free (node.class_closure_bsa, &g_class_closure_bconfig); + } + g_free (node.accumulator); + if (node.emission_hooks) + { + g_hook_list_clear (node.emission_hooks); + g_free (node.emission_hooks); + } + SIGNAL_LOCK (); +} + +/** + * g_signal_override_class_closure: + * @signal_id: the signal id + * @instance_type: the instance type on which to override the class closure + * for the signal. + * @class_closure: the closure. + * + * Overrides the class closure (i.e. the default handler) for the given signal + * for emissions on instances of @instance_type. @instance_type must be derived + * from the type to which the signal belongs. + * + * See g_signal_chain_from_overridden() and + * g_signal_chain_from_overridden_handler() for how to chain up to the + * parent class closure from inside the overridden one. + */ +void +g_signal_override_class_closure (guint signal_id, + GType instance_type, + GClosure *class_closure) +{ + SignalNode *node; + + g_return_if_fail (signal_id > 0); + g_return_if_fail (class_closure != NULL); + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + node_check_deprecated (node); + if (!g_type_is_a (instance_type, node->itype)) + g_warning ("%s: type '%s' cannot be overridden for signal id '%u'", G_STRLOC, type_debug_name (instance_type), signal_id); + else + { + ClassClosure *cc = signal_find_class_closure (node, instance_type); + + if (cc && cc->instance_type == instance_type) + g_warning ("%s: type '%s' is already overridden for signal id '%u'", G_STRLOC, type_debug_name (instance_type), signal_id); + else + signal_add_class_closure (node, instance_type, class_closure); + } + SIGNAL_UNLOCK (); +} + +/** + * g_signal_override_class_handler: + * @signal_name: the name for the signal + * @instance_type: the instance type on which to override the class handler + * for the signal. + * @class_handler: the handler. + * + * Overrides the class closure (i.e. the default handler) for the + * given signal for emissions on instances of @instance_type with + * callback @class_handler. @instance_type must be derived from the + * type to which the signal belongs. + * + * See g_signal_chain_from_overridden() and + * g_signal_chain_from_overridden_handler() for how to chain up to the + * parent class closure from inside the overridden one. + * + * Since: 2.18 + */ +void +g_signal_override_class_handler (const gchar *signal_name, + GType instance_type, + GCallback class_handler) +{ + guint signal_id; + + g_return_if_fail (signal_name != NULL); + g_return_if_fail (instance_type != G_TYPE_NONE); + g_return_if_fail (class_handler != NULL); + + signal_id = g_signal_lookup (signal_name, instance_type); + + if (signal_id) + g_signal_override_class_closure (signal_id, instance_type, + g_cclosure_new (class_handler, NULL, NULL)); + else + g_warning ("%s: signal name '%s' is invalid for type id '%"G_GSIZE_FORMAT"'", + G_STRLOC, signal_name, instance_type); + +} + +/** + * g_signal_chain_from_overridden: + * @instance_and_params: (array) the argument list of the signal emission. + * The first element in the array is a #GValue for the instance the signal + * is being emitted on. The rest are any arguments to be passed to the signal. + * @return_value: Location for the return value. + * + * Calls the original class closure of a signal. This function should only + * be called from an overridden class closure; see + * g_signal_override_class_closure() and + * g_signal_override_class_handler(). + */ +void +g_signal_chain_from_overridden (const GValue *instance_and_params, + GValue *return_value) +{ + GType chain_type = 0, restore_type = 0; + Emission *emission = NULL; + GClosure *closure = NULL; + guint n_params = 0; + gpointer instance; + + g_return_if_fail (instance_and_params != NULL); + instance = g_value_peek_pointer (instance_and_params); + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + + SIGNAL_LOCK (); + emission = emission_find_innermost (instance); + if (emission) + { + SignalNode *node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id); + + g_assert (node != NULL); /* paranoid */ + + /* we should probably do the same parameter checks as g_signal_emit() here. + */ + if (emission->chain_type != G_TYPE_NONE) + { + ClassClosure *cc = signal_find_class_closure (node, emission->chain_type); + + g_assert (cc != NULL); /* closure currently in call stack */ + + n_params = node->n_params; + restore_type = cc->instance_type; + cc = signal_find_class_closure (node, g_type_parent (cc->instance_type)); + if (cc && cc->instance_type != restore_type) + { + closure = cc->closure; + chain_type = cc->instance_type; + } + } + else + g_warning ("%s: signal id '%u' cannot be chained from current emission stage for instance '%p'", G_STRLOC, node->signal_id, instance); + } + else + g_warning ("%s: no signal is currently being emitted for instance '%p'", G_STRLOC, instance); + + if (closure) + { + emission->chain_type = chain_type; + SIGNAL_UNLOCK (); + g_closure_invoke (closure, + return_value, + n_params + 1, + instance_and_params, + &emission->ihint); + SIGNAL_LOCK (); + emission->chain_type = restore_type; + } + SIGNAL_UNLOCK (); +} + +/** + * g_signal_chain_from_overridden_handler: (skip) + * @instance: (type GObject.TypeInstance): the instance the signal is being + * emitted on. + * @...: parameters to be passed to the parent class closure, followed by a + * location for the return value. If the return type of the signal + * is %G_TYPE_NONE, the return value location can be omitted. + * + * Calls the original class closure of a signal. This function should + * only be called from an overridden class closure; see + * g_signal_override_class_closure() and + * g_signal_override_class_handler(). + * + * Since: 2.18 + */ +void +g_signal_chain_from_overridden_handler (gpointer instance, + ...) +{ + GType chain_type = 0, restore_type = 0; + Emission *emission = NULL; + GClosure *closure = NULL; + SignalNode *node = NULL; + guint n_params = 0; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + + SIGNAL_LOCK (); + emission = emission_find_innermost (instance); + if (emission) + { + node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id); + + g_assert (node != NULL); /* paranoid */ + + /* we should probably do the same parameter checks as g_signal_emit() here. + */ + if (emission->chain_type != G_TYPE_NONE) + { + ClassClosure *cc = signal_find_class_closure (node, emission->chain_type); + + g_assert (cc != NULL); /* closure currently in call stack */ + + n_params = node->n_params; + restore_type = cc->instance_type; + cc = signal_find_class_closure (node, g_type_parent (cc->instance_type)); + if (cc && cc->instance_type != restore_type) + { + closure = cc->closure; + chain_type = cc->instance_type; + } + } + else + g_warning ("%s: signal id '%u' cannot be chained from current emission stage for instance '%p'", G_STRLOC, node->signal_id, instance); + } + else + g_warning ("%s: no signal is currently being emitted for instance '%p'", G_STRLOC, instance); + + if (closure) + { + GValue *instance_and_params; + GType signal_return_type; + GValue *param_values; + va_list var_args; + guint i; + + va_start (var_args, instance); + + signal_return_type = node->return_type; + instance_and_params = g_newa0 (GValue, n_params + 1); + param_values = instance_and_params + 1; + + for (i = 0; i < node->n_params; i++) + { + gchar *error; + GType ptype = node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; + gboolean static_scope = node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE; + + SIGNAL_UNLOCK (); + G_VALUE_COLLECT_INIT (param_values + i, ptype, + var_args, + static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, + &error); + if (error) + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + + /* we purposely leak the value here, it might not be + * in a correct state if an error condition occurred + */ + while (i--) + g_value_unset (param_values + i); + + va_end (var_args); + return; + } + SIGNAL_LOCK (); + } + + SIGNAL_UNLOCK (); + instance_and_params->g_type = 0; + g_value_init_from_instance (instance_and_params, instance); + SIGNAL_LOCK (); + + emission->chain_type = chain_type; + SIGNAL_UNLOCK (); + + if (signal_return_type == G_TYPE_NONE) + { + g_closure_invoke (closure, + NULL, + n_params + 1, + instance_and_params, + &emission->ihint); + } + else + { + GValue return_value = G_VALUE_INIT; + gchar *error = NULL; + GType rtype = signal_return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE; + gboolean static_scope = signal_return_type & G_SIGNAL_TYPE_STATIC_SCOPE; + + g_value_init (&return_value, rtype); + + g_closure_invoke (closure, + &return_value, + n_params + 1, + instance_and_params, + &emission->ihint); + + G_VALUE_LCOPY (&return_value, + var_args, + static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, + &error); + if (!error) + { + g_value_unset (&return_value); + } + else + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + + /* we purposely leak the value here, it might not be + * in a correct state if an error condition occurred + */ + } + } + + for (i = 0; i < n_params; i++) + g_value_unset (param_values + i); + g_value_unset (instance_and_params); + + va_end (var_args); + + SIGNAL_LOCK (); + emission->chain_type = restore_type; + } + SIGNAL_UNLOCK (); +} + +/** + * g_signal_get_invocation_hint: + * @instance: (type GObject.Object): the instance to query + * + * Returns the invocation hint of the innermost signal emission of instance. + * + * Returns: (transfer none) (nullable): the invocation hint of the innermost + * signal emission, or %NULL if not found. + */ +GSignalInvocationHint* +g_signal_get_invocation_hint (gpointer instance) +{ + Emission *emission = NULL; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), NULL); + + SIGNAL_LOCK (); + emission = emission_find_innermost (instance); + SIGNAL_UNLOCK (); + + return emission ? &emission->ihint : NULL; +} + +/** + * g_signal_connect_closure_by_id: + * @instance: (type GObject.Object): the instance to connect to. + * @signal_id: the id of the signal. + * @detail: the detail. + * @closure: (not nullable): the closure to connect. + * @after: whether the handler should be called before or after the + * default handler of the signal. + * + * Connects a closure to a signal for a particular object. + * + * Returns: the handler ID (always greater than 0 for successful connections) + */ +gulong +g_signal_connect_closure_by_id (gpointer instance, + guint signal_id, + GQuark detail, + GClosure *closure, + gboolean after) +{ + SignalNode *node; + gulong handler_seq_no = 0; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail (signal_id > 0, 0); + g_return_val_if_fail (closure != NULL, 0); + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (node) + { + if (detail && !(node->flags & G_SIGNAL_DETAILED)) + g_warning ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail); + else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) + g_warning ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance); + else + { + Handler *handler = handler_new (signal_id, instance, after); + + if (G_TYPE_IS_OBJECT (node->itype)) + _g_object_set_has_signal_handler ((GObject *)instance); + + handler_seq_no = handler->sequential_number; + handler->detail = detail; + handler->closure = g_closure_ref (closure); + g_closure_sink (closure); + add_invalid_closure_notify (handler, instance); + handler_insert (signal_id, instance, handler); + if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure)) + { + g_closure_set_marshal (closure, node->c_marshaller); + if (node->va_marshaller) + _g_closure_set_va_marshal (closure, node->va_marshaller); + } + } + } + else + g_warning ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance); + SIGNAL_UNLOCK (); + + return handler_seq_no; +} + +/** + * g_signal_connect_closure: + * @instance: (type GObject.Object): the instance to connect to. + * @detailed_signal: a string of the form "signal-name::detail". + * @closure: (not nullable): the closure to connect. + * @after: whether the handler should be called before or after the + * default handler of the signal. + * + * Connects a closure to a signal for a particular object. + * + * Returns: the handler ID (always greater than 0 for successful connections) + */ +gulong +g_signal_connect_closure (gpointer instance, + const gchar *detailed_signal, + GClosure *closure, + gboolean after) +{ + guint signal_id; + gulong handler_seq_no = 0; + GQuark detail = 0; + GType itype; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail (detailed_signal != NULL, 0); + g_return_val_if_fail (closure != NULL, 0); + + SIGNAL_LOCK (); + itype = G_TYPE_FROM_INSTANCE (instance); + signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); + if (signal_id) + { + SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); + + if (detail && !(node->flags & G_SIGNAL_DETAILED)) + g_warning ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal); + else if (!g_type_is_a (itype, node->itype)) + g_warning ("%s: signal '%s' is invalid for instance '%p' of type '%s'", + G_STRLOC, detailed_signal, instance, g_type_name (itype)); + else + { + Handler *handler = handler_new (signal_id, instance, after); + + if (G_TYPE_IS_OBJECT (node->itype)) + _g_object_set_has_signal_handler ((GObject *)instance); + + handler_seq_no = handler->sequential_number; + handler->detail = detail; + handler->closure = g_closure_ref (closure); + g_closure_sink (closure); + add_invalid_closure_notify (handler, instance); + handler_insert (signal_id, instance, handler); + if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) + { + g_closure_set_marshal (handler->closure, node->c_marshaller); + if (node->va_marshaller) + _g_closure_set_va_marshal (handler->closure, node->va_marshaller); + } + } + } + else + g_warning ("%s: signal '%s' is invalid for instance '%p' of type '%s'", + G_STRLOC, detailed_signal, instance, g_type_name (itype)); + SIGNAL_UNLOCK (); + + return handler_seq_no; +} + +static void +node_check_deprecated (const SignalNode *node) +{ + static const gchar * g_enable_diagnostic = NULL; + + if (G_UNLIKELY (!g_enable_diagnostic)) + { + g_enable_diagnostic = g_getenv ("G_ENABLE_DIAGNOSTIC"); + if (!g_enable_diagnostic) + g_enable_diagnostic = "0"; + } + + if (g_enable_diagnostic[0] == '1') + { + if (node->flags & G_SIGNAL_DEPRECATED) + { + g_warning ("The signal %s::%s is deprecated and shouldn't be used " + "anymore. It will be removed in a future version.", + type_debug_name (node->itype), node->name); + } + } +} + +/** + * g_signal_connect_data: + * @instance: (type GObject.Object): the instance to connect to. + * @detailed_signal: a string of the form "signal-name::detail". + * @c_handler: (not nullable): the #GCallback to connect. + * @data: (nullable) (closure c_handler): data to pass to @c_handler calls. + * @destroy_data: (nullable) (destroy data): a #GClosureNotify for @data. + * @connect_flags: a combination of #GConnectFlags. + * + * Connects a #GCallback function to a signal for a particular object. Similar + * to g_signal_connect(), but allows to provide a #GClosureNotify for the data + * which will be called when the signal handler is disconnected and no longer + * used. Specify @connect_flags if you need `..._after()` or + * `..._swapped()` variants of this function. + * + * Returns: the handler ID (always greater than 0 for successful connections) + */ +gulong +g_signal_connect_data (gpointer instance, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data, + GClosureNotify destroy_data, + GConnectFlags connect_flags) +{ + guint signal_id; + gulong handler_seq_no = 0; + GQuark detail = 0; + GType itype; + gboolean swapped, after; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail (detailed_signal != NULL, 0); + g_return_val_if_fail (c_handler != NULL, 0); + + swapped = (connect_flags & G_CONNECT_SWAPPED) != FALSE; + after = (connect_flags & G_CONNECT_AFTER) != FALSE; + + SIGNAL_LOCK (); + itype = G_TYPE_FROM_INSTANCE (instance); + signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); + if (signal_id) + { + SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); + + node_check_deprecated (node); + + if (detail && !(node->flags & G_SIGNAL_DETAILED)) + g_warning ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal); + else if (!g_type_is_a (itype, node->itype)) + g_warning ("%s: signal '%s' is invalid for instance '%p' of type '%s'", + G_STRLOC, detailed_signal, instance, g_type_name (itype)); + else + { + Handler *handler = handler_new (signal_id, instance, after); + + if (G_TYPE_IS_OBJECT (node->itype)) + _g_object_set_has_signal_handler ((GObject *)instance); + + handler_seq_no = handler->sequential_number; + handler->detail = detail; + handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data)); + g_closure_sink (handler->closure); + handler_insert (signal_id, instance, handler); + if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) + { + g_closure_set_marshal (handler->closure, node->c_marshaller); + if (node->va_marshaller) + _g_closure_set_va_marshal (handler->closure, node->va_marshaller); + } + } + } + else + g_warning ("%s: signal '%s' is invalid for instance '%p' of type '%s'", + G_STRLOC, detailed_signal, instance, g_type_name (itype)); + SIGNAL_UNLOCK (); + + return handler_seq_no; +} + +static void +signal_handler_block_unlocked (gpointer instance, + gulong handler_id); + +/** + * g_signal_handler_block: + * @instance: (type GObject.Object): The instance to block the signal handler of. + * @handler_id: Handler id of the handler to be blocked. + * + * Blocks a handler of an instance so it will not be called during any + * signal emissions unless it is unblocked again. Thus "blocking" a + * signal handler means to temporarily deactivate it, a signal handler + * has to be unblocked exactly the same amount of times it has been + * blocked before to become active again. + * + * The @handler_id has to be a valid signal handler id, connected to a + * signal of @instance. + */ +void +g_signal_handler_block (gpointer instance, + gulong handler_id) +{ + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (handler_id > 0); + + SIGNAL_LOCK (); + signal_handler_block_unlocked (instance, handler_id); + SIGNAL_UNLOCK (); +} + +static void +signal_handler_block_unlocked (gpointer instance, + gulong handler_id) +{ + Handler *handler; + + handler = handler_lookup (instance, handler_id, NULL, NULL); + if (handler) + { +#ifndef G_DISABLE_CHECKS + if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1) + g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG); +#endif + handler->block_count += 1; + } + else + g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id); +} + +static void +signal_handler_unblock_unlocked (gpointer instance, + gulong handler_id); + +/** + * g_signal_handler_unblock: + * @instance: (type GObject.Object): The instance to unblock the signal handler of. + * @handler_id: Handler id of the handler to be unblocked. + * + * Undoes the effect of a previous g_signal_handler_block() call. A + * blocked handler is skipped during signal emissions and will not be + * invoked, unblocking it (for exactly the amount of times it has been + * blocked before) reverts its "blocked" state, so the handler will be + * recognized by the signal system and is called upon future or + * currently ongoing signal emissions (since the order in which + * handlers are called during signal emissions is deterministic, + * whether the unblocked handler in question is called as part of a + * currently ongoing emission depends on how far that emission has + * proceeded yet). + * + * The @handler_id has to be a valid id of a signal handler that is + * connected to a signal of @instance and is currently blocked. + */ +void +g_signal_handler_unblock (gpointer instance, + gulong handler_id) +{ + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (handler_id > 0); + + SIGNAL_LOCK (); + signal_handler_unblock_unlocked (instance, handler_id); + SIGNAL_UNLOCK (); +} + +static void +signal_handler_unblock_unlocked (gpointer instance, + gulong handler_id) +{ + Handler *handler; + + handler = handler_lookup (instance, handler_id, NULL, NULL); + if (handler) + { + if (handler->block_count) + handler->block_count -= 1; + else + g_warning (G_STRLOC ": handler '%lu' of instance '%p' is not blocked", handler_id, instance); + } + else + g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id); +} + +static void +signal_handler_disconnect_unlocked (gpointer instance, + gulong handler_id); + +/** + * g_signal_handler_disconnect: + * @instance: (type GObject.Object): The instance to remove the signal handler from. + * @handler_id: Handler id of the handler to be disconnected. + * + * Disconnects a handler from an instance so it will not be called during + * any future or currently ongoing emissions of the signal it has been + * connected to. The @handler_id becomes invalid and may be reused. + * + * The @handler_id has to be a valid signal handler id, connected to a + * signal of @instance. + */ +void +g_signal_handler_disconnect (gpointer instance, + gulong handler_id) +{ + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (handler_id > 0); + + SIGNAL_LOCK (); + signal_handler_disconnect_unlocked (instance, handler_id); + SIGNAL_UNLOCK (); +} + +static void +signal_handler_disconnect_unlocked (gpointer instance, + gulong handler_id) +{ + Handler *handler; + + handler = handler_lookup (instance, handler_id, 0, 0); + if (handler) + { + g_hash_table_remove (g_handlers, handler); + handler->sequential_number = 0; + handler->block_count = 1; + remove_invalid_closure_notify (handler, instance); + handler_unref_R (handler->signal_id, instance, handler); + } + else + g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id); +} + +/** + * g_signal_handler_is_connected: + * @instance: (type GObject.Object): The instance where a signal handler is sought. + * @handler_id: the handler ID. + * + * Returns whether @handler_id is the ID of a handler connected to @instance. + * + * Returns: whether @handler_id identifies a handler connected to @instance. + */ +gboolean +g_signal_handler_is_connected (gpointer instance, + gulong handler_id) +{ + Handler *handler; + gboolean connected; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); + + SIGNAL_LOCK (); + handler = handler_lookup (instance, handler_id, NULL, NULL); + connected = handler != NULL; + SIGNAL_UNLOCK (); + + return connected; +} + +/** + * g_signal_handlers_destroy: + * @instance: (type GObject.Object): The instance whose signal handlers are destroyed + * + * Destroy all signal handlers of a type instance. This function is + * an implementation detail of the #GObject dispose implementation, + * and should not be used outside of the type system. + */ +void +g_signal_handlers_destroy (gpointer instance) +{ + GBSearchArray *hlbsa; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + + SIGNAL_LOCK (); + hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); + if (hlbsa) + { + guint i; + + /* reentrancy caution, delete instance trace first */ + g_hash_table_remove (g_handler_list_bsa_ht, instance); + + for (i = 0; i < hlbsa->n_nodes; i++) + { + HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i); + Handler *handler = hlist->handlers; + + while (handler) + { + Handler *tmp = handler; + + handler = tmp->next; + tmp->block_count = 1; + /* cruel unlink, this works because _all_ handlers vanish */ + tmp->next = NULL; + tmp->prev = tmp; + if (tmp->sequential_number) + { + g_hash_table_remove (g_handlers, tmp); + remove_invalid_closure_notify (tmp, instance); + tmp->sequential_number = 0; + handler_unref_R (0, NULL, tmp); + } + } + } + g_bsearch_array_free (hlbsa, &g_signal_hlbsa_bconfig); + } + SIGNAL_UNLOCK (); +} + +/** + * g_signal_handler_find: + * @instance: (type GObject.Object): The instance owning the signal handler to be found. + * @mask: Mask indicating which of @signal_id, @detail, @closure, @func + * and/or @data the handler has to match. + * @signal_id: Signal the handler has to be connected to. + * @detail: Signal detail the handler has to be connected to. + * @closure: (nullable): The closure the handler will invoke. + * @func: The C closure callback of the handler (useless for non-C closures). + * @data: (nullable) (closure closure): The closure data of the handler's closure. + * + * Finds the first signal handler that matches certain selection criteria. + * The criteria mask is passed as an OR-ed combination of #GSignalMatchType + * flags, and the criteria values are passed as arguments. + * The match @mask has to be non-0 for successful matches. + * If no handler was found, 0 is returned. + * + * Returns: A valid non-0 signal handler id for a successful match. + */ +gulong +g_signal_handler_find (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data) +{ + gulong handler_seq_no = 0; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); + + if (mask & G_SIGNAL_MATCH_MASK) + { + HandlerMatch *mlist; + + SIGNAL_LOCK (); + mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE); + if (mlist) + { + handler_seq_no = mlist->handler->sequential_number; + handler_match_free1_R (mlist, instance); + } + SIGNAL_UNLOCK (); + } + + return handler_seq_no; +} + +typedef void (*CallbackHandlerFunc) (gpointer instance, gulong handler_seq_no); + +static guint +signal_handlers_foreach_matched_unlocked_R (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data, + CallbackHandlerFunc callback) +{ + HandlerMatch *mlist; + guint n_handlers = 0; + + mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE); + while (mlist) + { + n_handlers++; + if (mlist->handler->sequential_number) + callback (instance, mlist->handler->sequential_number); + + mlist = handler_match_free1_R (mlist, instance); + } + + return n_handlers; +} + +/** + * g_signal_handlers_block_matched: + * @instance: (type GObject.Object): The instance to block handlers from. + * @mask: Mask indicating which of @signal_id, @detail, @closure, @func + * and/or @data the handlers have to match. + * @signal_id: Signal the handlers have to be connected to. + * @detail: Signal detail the handlers have to be connected to. + * @closure: (nullable): The closure the handlers will invoke. + * @func: The C closure callback of the handlers (useless for non-C closures). + * @data: (nullable) (closure closure): The closure data of the handlers' closures. + * + * Blocks all handlers on an instance that match a certain selection criteria. + * The criteria mask is passed as an OR-ed combination of #GSignalMatchType + * flags, and the criteria values are passed as arguments. + * Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC + * or %G_SIGNAL_MATCH_DATA match flags is required for successful matches. + * If no handlers were found, 0 is returned, the number of blocked handlers + * otherwise. + * + * Returns: The number of handlers that matched. + */ +guint +g_signal_handlers_block_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data) +{ + guint n_handlers = 0; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); + + if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) + { + SIGNAL_LOCK (); + n_handlers = + signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail, + closure, func, data, + signal_handler_block_unlocked); + SIGNAL_UNLOCK (); + } + + return n_handlers; +} + +/** + * g_signal_handlers_unblock_matched: + * @instance: (type GObject.Object): The instance to unblock handlers from. + * @mask: Mask indicating which of @signal_id, @detail, @closure, @func + * and/or @data the handlers have to match. + * @signal_id: Signal the handlers have to be connected to. + * @detail: Signal detail the handlers have to be connected to. + * @closure: (nullable): The closure the handlers will invoke. + * @func: The C closure callback of the handlers (useless for non-C closures). + * @data: (nullable) (closure closure): The closure data of the handlers' closures. + * + * Unblocks all handlers on an instance that match a certain selection + * criteria. The criteria mask is passed as an OR-ed combination of + * #GSignalMatchType flags, and the criteria values are passed as arguments. + * Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC + * or %G_SIGNAL_MATCH_DATA match flags is required for successful matches. + * If no handlers were found, 0 is returned, the number of unblocked handlers + * otherwise. The match criteria should not apply to any handlers that are + * not currently blocked. + * + * Returns: The number of handlers that matched. + */ +guint +g_signal_handlers_unblock_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data) +{ + guint n_handlers = 0; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); + + if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) + { + SIGNAL_LOCK (); + n_handlers = + signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail, + closure, func, data, + signal_handler_unblock_unlocked); + SIGNAL_UNLOCK (); + } + + return n_handlers; +} + +/** + * g_signal_handlers_disconnect_matched: + * @instance: (type GObject.Object): The instance to remove handlers from. + * @mask: Mask indicating which of @signal_id, @detail, @closure, @func + * and/or @data the handlers have to match. + * @signal_id: Signal the handlers have to be connected to. + * @detail: Signal detail the handlers have to be connected to. + * @closure: (nullable): The closure the handlers will invoke. + * @func: The C closure callback of the handlers (useless for non-C closures). + * @data: (nullable) (closure closure): The closure data of the handlers' closures. + * + * Disconnects all handlers on an instance that match a certain + * selection criteria. The criteria mask is passed as an OR-ed + * combination of #GSignalMatchType flags, and the criteria values are + * passed as arguments. Passing at least one of the + * %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC or + * %G_SIGNAL_MATCH_DATA match flags is required for successful + * matches. If no handlers were found, 0 is returned, the number of + * disconnected handlers otherwise. + * + * Returns: The number of handlers that matched. + */ +guint +g_signal_handlers_disconnect_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data) +{ + guint n_handlers = 0; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); + g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); + + if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) + { + SIGNAL_LOCK (); + n_handlers = + signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail, + closure, func, data, + signal_handler_disconnect_unlocked); + SIGNAL_UNLOCK (); + } + + return n_handlers; +} + +/** + * g_signal_has_handler_pending: + * @instance: (type GObject.Object): the object whose signal handlers are sought. + * @signal_id: the signal id. + * @detail: the detail. + * @may_be_blocked: whether blocked handlers should count as match. + * + * Returns whether there are any handlers connected to @instance for the + * given signal id and detail. + * + * If @detail is 0 then it will only match handlers that were connected + * without detail. If @detail is non-zero then it will match handlers + * connected both without detail and with the given detail. This is + * consistent with how a signal emitted with @detail would be delivered + * to those handlers. + * + * Since 2.46 this also checks for a non-default class closure being + * installed, as this is basically always what you want. + * + * One example of when you might use this is when the arguments to the + * signal are difficult to compute. A class implementor may opt to not + * emit the signal if no one is attached anyway, thus saving the cost + * of building the arguments. + * + * Returns: %TRUE if a handler is connected to the signal, %FALSE + * otherwise. + */ +gboolean +g_signal_has_handler_pending (gpointer instance, + guint signal_id, + GQuark detail, + gboolean may_be_blocked) +{ + HandlerMatch *mlist; + gboolean has_pending; + SignalNode *node; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); + g_return_val_if_fail (signal_id > 0, FALSE); + + SIGNAL_LOCK (); + + node = LOOKUP_SIGNAL_NODE (signal_id); + if (detail) + { + if (!(node->flags & G_SIGNAL_DETAILED)) + { + g_warning ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail); + SIGNAL_UNLOCK (); + return FALSE; + } + } + mlist = handlers_find (instance, + (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)), + signal_id, detail, NULL, NULL, NULL, TRUE); + if (mlist) + { + has_pending = TRUE; + handler_match_free1_R (mlist, instance); + } + else + { + ClassClosure *class_closure = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance)); + if (class_closure != NULL && class_closure->instance_type != 0) + has_pending = TRUE; + else + has_pending = FALSE; + } + SIGNAL_UNLOCK (); + + return has_pending; +} + +/** + * g_signal_emitv: + * @instance_and_params: (array): argument list for the signal emission. + * The first element in the array is a #GValue for the instance the signal + * is being emitted on. The rest are any arguments to be passed to the signal. + * @signal_id: the signal id + * @detail: the detail + * @return_value: (inout) (optional): Location to + * store the return value of the signal emission. This must be provided if the + * specified signal returns a value, but may be ignored otherwise. + * + * Emits a signal. Signal emission is done synchronously. + * The method will only return control after all handlers are called or signal emission was stopped. + * + * Note that g_signal_emitv() doesn't change @return_value if no handlers are + * connected, in contrast to g_signal_emit() and g_signal_emit_valist(). + */ +void +g_signal_emitv (const GValue *instance_and_params, + guint signal_id, + GQuark detail, + GValue *return_value) +{ + gpointer instance; + SignalNode *node; +#ifdef G_ENABLE_DEBUG + const GValue *param_values; + guint i; +#endif + + g_return_if_fail (instance_and_params != NULL); + instance = g_value_peek_pointer (instance_and_params); + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (signal_id > 0); + +#ifdef G_ENABLE_DEBUG + param_values = instance_and_params + 1; +#endif + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) + { + g_warning ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance); + SIGNAL_UNLOCK (); + return; + } +#ifdef G_ENABLE_DEBUG + if (detail && !(node->flags & G_SIGNAL_DETAILED)) + { + g_warning ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail); + SIGNAL_UNLOCK (); + return; + } + for (i = 0; i < node->n_params; i++) + if (!G_TYPE_CHECK_VALUE_TYPE (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE)) + { + g_critical ("%s: value for '%s' parameter %u for signal \"%s\" is of type '%s'", + G_STRLOC, + type_debug_name (node->param_types[i]), + i, + node->name, + G_VALUE_TYPE_NAME (param_values + i)); + SIGNAL_UNLOCK (); + return; + } + if (node->return_type != G_TYPE_NONE) + { + if (!return_value) + { + g_critical ("%s: return value '%s' for signal \"%s\" is (NULL)", + G_STRLOC, + type_debug_name (node->return_type), + node->name); + SIGNAL_UNLOCK (); + return; + } + else if (!node->accumulator && !G_TYPE_CHECK_VALUE_TYPE (return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE)) + { + g_critical ("%s: return value '%s' for signal \"%s\" is of type '%s'", + G_STRLOC, + type_debug_name (node->return_type), + node->name, + G_VALUE_TYPE_NAME (return_value)); + SIGNAL_UNLOCK (); + return; + } + } + else + return_value = NULL; +#endif /* G_ENABLE_DEBUG */ + + /* optimize NOP emissions */ + if (!node->single_va_closure_is_valid) + node_update_single_va_closure (node); + + if (node->single_va_closure != NULL && + (node->single_va_closure == SINGLE_VA_CLOSURE_EMPTY_MAGIC || + _g_closure_is_void (node->single_va_closure, instance))) + { + HandlerList* hlist; + + /* single_va_closure is only true for GObjects, so fast path if no handler ever connected to the signal */ + if (_g_object_has_signal_handler ((GObject *)instance)) + hlist = handler_list_lookup (node->signal_id, instance); + else + hlist = NULL; + + if (hlist == NULL || hlist->handlers == NULL) + { + /* nothing to do to emit this signal */ + SIGNAL_UNLOCK (); + /* g_printerr ("omitting emission of \"%s\"\n", node->name); */ + return; + } + } + + SIGNAL_UNLOCK (); + signal_emit_unlocked_R (node, detail, instance, return_value, instance_and_params); +} + +static inline gboolean +accumulate (GSignalInvocationHint *ihint, + GValue *return_accu, + GValue *handler_return, + SignalAccumulator *accumulator) +{ + gboolean continue_emission; + + if (!accumulator) + return TRUE; + + continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data); + g_value_reset (handler_return); + + ihint->run_type &= ~G_SIGNAL_ACCUMULATOR_FIRST_RUN; + + return continue_emission; +} + +/** + * g_signal_emit_valist: (skip) + * @instance: (type GObject.TypeInstance): the instance the signal is being + * emitted on. + * @signal_id: the signal id + * @detail: the detail + * @var_args: a list of parameters to be passed to the signal, followed by a + * location for the return value. If the return type of the signal + * is %G_TYPE_NONE, the return value location can be omitted. + * + * Emits a signal. Signal emission is done synchronously. + * The method will only return control after all handlers are called or signal emission was stopped. + * + * Note that g_signal_emit_valist() resets the return value to the default + * if no handlers are connected, in contrast to g_signal_emitv(). + */ +void +g_signal_emit_valist (gpointer instance, + guint signal_id, + GQuark detail, + va_list var_args) +{ + GValue *instance_and_params; + GType signal_return_type; + GValue *param_values; + SignalNode *node; + guint i, n_params; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (signal_id > 0); + + SIGNAL_LOCK (); + node = LOOKUP_SIGNAL_NODE (signal_id); + if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) + { + g_warning ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance); + SIGNAL_UNLOCK (); + return; + } +#ifndef G_DISABLE_CHECKS + if (detail && !(node->flags & G_SIGNAL_DETAILED)) + { + g_warning ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail); + SIGNAL_UNLOCK (); + return; + } +#endif /* !G_DISABLE_CHECKS */ + + if (!node->single_va_closure_is_valid) + node_update_single_va_closure (node); + + if (node->single_va_closure != NULL) + { + HandlerList* hlist; + Handler *fastpath_handler = NULL; + Handler *l; + GClosure *closure = NULL; + gboolean fastpath = TRUE; + GSignalFlags run_type = G_SIGNAL_RUN_FIRST; + + if (node->single_va_closure != SINGLE_VA_CLOSURE_EMPTY_MAGIC && + !_g_closure_is_void (node->single_va_closure, instance)) + { + if (_g_closure_supports_invoke_va (node->single_va_closure)) + { + closure = node->single_va_closure; + if (node->single_va_closure_is_after) + run_type = G_SIGNAL_RUN_LAST; + else + run_type = G_SIGNAL_RUN_FIRST; + } + else + fastpath = FALSE; + } + + /* single_va_closure is only true for GObjects, so fast path if no handler ever connected to the signal */ + if (_g_object_has_signal_handler ((GObject *)instance)) + hlist = handler_list_lookup (node->signal_id, instance); + else + hlist = NULL; + + for (l = hlist ? hlist->handlers : NULL; fastpath && l != NULL; l = l->next) + { + if (!l->block_count && + (!l->detail || l->detail == detail)) + { + if (closure != NULL || !_g_closure_supports_invoke_va (l->closure)) + { + fastpath = FALSE; + break; + } + else + { + fastpath_handler = l; + closure = l->closure; + if (l->after) + run_type = G_SIGNAL_RUN_LAST; + else + run_type = G_SIGNAL_RUN_FIRST; + } + } + } + + if (fastpath && closure == NULL && node->return_type == G_TYPE_NONE) + { + SIGNAL_UNLOCK (); + return; + } + + /* Don't allow no-recurse emission as we might have to restart, which means + we will run multiple handlers and thus must ref all arguments */ + if (closure != NULL && (node->flags & (G_SIGNAL_NO_RECURSE)) != 0) + fastpath = FALSE; + + if (fastpath) + { + SignalAccumulator *accumulator; + Emission emission; + GValue *return_accu, accu = G_VALUE_INIT; + GType instance_type = G_TYPE_FROM_INSTANCE (instance); + GValue emission_return = G_VALUE_INIT; + GType rtype = node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE; + gboolean static_scope = node->return_type & G_SIGNAL_TYPE_STATIC_SCOPE; + + signal_id = node->signal_id; + accumulator = node->accumulator; + if (rtype == G_TYPE_NONE) + return_accu = NULL; + else if (accumulator) + return_accu = &accu; + else + return_accu = &emission_return; + + emission.instance = instance; + emission.ihint.signal_id = signal_id; + emission.ihint.detail = detail; + emission.ihint.run_type = run_type | G_SIGNAL_ACCUMULATOR_FIRST_RUN; + emission.state = EMISSION_RUN; + emission.chain_type = instance_type; + emission_push (&emission); + + if (fastpath_handler) + handler_ref (fastpath_handler); + + SIGNAL_UNLOCK (); + + TRACE(GOBJECT_SIGNAL_EMIT(signal_id, detail, instance, instance_type)); + + if (rtype != G_TYPE_NONE) + g_value_init (&emission_return, rtype); + + if (accumulator) + g_value_init (&accu, rtype); + + if (closure != NULL) + { + g_object_ref (instance); + _g_closure_invoke_va (closure, + return_accu, + instance, + var_args, + node->n_params, + node->param_types); + accumulate (&emission.ihint, &emission_return, &accu, accumulator); + } + + SIGNAL_LOCK (); + + emission.chain_type = G_TYPE_NONE; + emission_pop (&emission); + + if (fastpath_handler) + handler_unref_R (signal_id, instance, fastpath_handler); + + SIGNAL_UNLOCK (); + + if (accumulator) + g_value_unset (&accu); + + if (rtype != G_TYPE_NONE) + { + gchar *error = NULL; + for (i = 0; i < node->n_params; i++) + { + GType ptype = node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; + G_VALUE_COLLECT_SKIP (ptype, var_args); + } + + G_VALUE_LCOPY (&emission_return, + var_args, + static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, + &error); + if (!error) + g_value_unset (&emission_return); + else + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + /* we purposely leak the value here, it might not be + * in a correct state if an error condition occurred + */ + } + } + + TRACE(GOBJECT_SIGNAL_EMIT_END(signal_id, detail, instance, instance_type)); + + if (closure != NULL) + g_object_unref (instance); + + return; + } + } + SIGNAL_UNLOCK (); + + n_params = node->n_params; + signal_return_type = node->return_type; + instance_and_params = g_newa0 (GValue, n_params + 1); + param_values = instance_and_params + 1; + + for (i = 0; i < node->n_params; i++) + { + gchar *error; + GType ptype = node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; + gboolean static_scope = node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE; + + G_VALUE_COLLECT_INIT (param_values + i, ptype, + var_args, + static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, + &error); + if (error) + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + + /* we purposely leak the value here, it might not be + * in a correct state if an error condition occurred + */ + while (i--) + g_value_unset (param_values + i); + + return; + } + } + + instance_and_params->g_type = 0; + g_value_init_from_instance (instance_and_params, instance); + if (signal_return_type == G_TYPE_NONE) + signal_emit_unlocked_R (node, detail, instance, NULL, instance_and_params); + else + { + GValue return_value = G_VALUE_INIT; + gchar *error = NULL; + GType rtype = signal_return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE; + gboolean static_scope = signal_return_type & G_SIGNAL_TYPE_STATIC_SCOPE; + + g_value_init (&return_value, rtype); + + signal_emit_unlocked_R (node, detail, instance, &return_value, instance_and_params); + + G_VALUE_LCOPY (&return_value, + var_args, + static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, + &error); + if (!error) + g_value_unset (&return_value); + else + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + + /* we purposely leak the value here, it might not be + * in a correct state if an error condition occurred + */ + } + } + for (i = 0; i < n_params; i++) + g_value_unset (param_values + i); + g_value_unset (instance_and_params); +} + +/** + * g_signal_emit: + * @instance: (type GObject.Object): the instance the signal is being emitted on. + * @signal_id: the signal id + * @detail: the detail + * @...: parameters to be passed to the signal, followed by a + * location for the return value. If the return type of the signal + * is %G_TYPE_NONE, the return value location can be omitted. + * + * Emits a signal. Signal emission is done synchronously. + * The method will only return control after all handlers are called or signal emission was stopped. + * + * Note that g_signal_emit() resets the return value to the default + * if no handlers are connected, in contrast to g_signal_emitv(). + */ +void +g_signal_emit (gpointer instance, + guint signal_id, + GQuark detail, + ...) +{ + va_list var_args; + + va_start (var_args, detail); + g_signal_emit_valist (instance, signal_id, detail, var_args); + va_end (var_args); +} + +/** + * g_signal_emit_by_name: + * @instance: (type GObject.Object): the instance the signal is being emitted on. + * @detailed_signal: a string of the form "signal-name::detail". + * @...: parameters to be passed to the signal, followed by a + * location for the return value. If the return type of the signal + * is %G_TYPE_NONE, the return value location can be omitted. The + * number of parameters to pass to this function is defined when creating the signal. + * + * Emits a signal. Signal emission is done synchronously. + * The method will only return control after all handlers are called or signal emission was stopped. + * + * Note that g_signal_emit_by_name() resets the return value to the default + * if no handlers are connected, in contrast to g_signal_emitv(). + */ +void +g_signal_emit_by_name (gpointer instance, + const gchar *detailed_signal, + ...) +{ + GQuark detail = 0; + guint signal_id; + GType itype; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (detailed_signal != NULL); + + itype = G_TYPE_FROM_INSTANCE (instance); + + SIGNAL_LOCK (); + signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); + SIGNAL_UNLOCK (); + + if (signal_id) + { + va_list var_args; + + va_start (var_args, detailed_signal); + g_signal_emit_valist (instance, signal_id, detail, var_args); + va_end (var_args); + } + else + g_warning ("%s: signal name '%s' is invalid for instance '%p' of type '%s'", + G_STRLOC, detailed_signal, instance, g_type_name (itype)); +} + +static gboolean +signal_emit_unlocked_R (SignalNode *node, + GQuark detail, + gpointer instance, + GValue *emission_return, + const GValue *instance_and_params) +{ + SignalAccumulator *accumulator; + Emission emission; + GClosure *class_closure; + HandlerList *hlist; + Handler *handler_list = NULL; + GValue *return_accu, accu = G_VALUE_INIT; + guint signal_id; + gulong max_sequential_handler_number; + gboolean return_value_altered = FALSE; + + TRACE(GOBJECT_SIGNAL_EMIT(node->signal_id, detail, instance, G_TYPE_FROM_INSTANCE (instance))); + + SIGNAL_LOCK (); + signal_id = node->signal_id; + + if (node->flags & G_SIGNAL_NO_RECURSE) + { + Emission *emission_node = emission_find (signal_id, detail, instance); + + if (emission_node) + { + emission_node->state = EMISSION_RESTART; + SIGNAL_UNLOCK (); + return return_value_altered; + } + } + accumulator = node->accumulator; + if (accumulator) + { + SIGNAL_UNLOCK (); + g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); + return_accu = &accu; + SIGNAL_LOCK (); + } + else + return_accu = emission_return; + emission.instance = instance; + emission.ihint.signal_id = node->signal_id; + emission.ihint.detail = detail; + emission.ihint.run_type = 0; + emission.state = 0; + emission.chain_type = G_TYPE_NONE; + emission_push (&emission); + class_closure = signal_lookup_closure (node, instance); + + EMIT_RESTART: + + if (handler_list) + handler_unref_R (signal_id, instance, handler_list); + max_sequential_handler_number = g_handler_sequential_number; + hlist = handler_list_lookup (signal_id, instance); + handler_list = hlist ? hlist->handlers : NULL; + if (handler_list) + handler_ref (handler_list); + + emission.ihint.run_type = G_SIGNAL_RUN_FIRST | G_SIGNAL_ACCUMULATOR_FIRST_RUN; + + if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure) + { + emission.state = EMISSION_RUN; + + emission.chain_type = G_TYPE_FROM_INSTANCE (instance); + SIGNAL_UNLOCK (); + g_closure_invoke (class_closure, + return_accu, + node->n_params + 1, + instance_and_params, + &emission.ihint); + if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && + emission.state == EMISSION_RUN) + emission.state = EMISSION_STOP; + SIGNAL_LOCK (); + emission.chain_type = G_TYPE_NONE; + return_value_altered = TRUE; + + if (emission.state == EMISSION_STOP) + goto EMIT_CLEANUP; + else if (emission.state == EMISSION_RESTART) + goto EMIT_RESTART; + } + + if (node->emission_hooks) + { + gboolean need_destroy, was_in_call, may_recurse = TRUE; + GHook *hook; + + emission.state = EMISSION_HOOK; + hook = g_hook_first_valid (node->emission_hooks, may_recurse); + while (hook) + { + SignalHook *signal_hook = SIGNAL_HOOK (hook); + + if (!signal_hook->detail || signal_hook->detail == detail) + { + GSignalEmissionHook hook_func = (GSignalEmissionHook) hook->func; + + was_in_call = G_HOOK_IN_CALL (hook); + hook->flags |= G_HOOK_FLAG_IN_CALL; + SIGNAL_UNLOCK (); + need_destroy = !hook_func (&emission.ihint, node->n_params + 1, instance_and_params, hook->data); + SIGNAL_LOCK (); + if (!was_in_call) + hook->flags &= ~G_HOOK_FLAG_IN_CALL; + if (need_destroy) + g_hook_destroy_link (node->emission_hooks, hook); + } + hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse); + } + + if (emission.state == EMISSION_RESTART) + goto EMIT_RESTART; + } + + if (handler_list) + { + Handler *handler = handler_list; + + emission.state = EMISSION_RUN; + handler_ref (handler); + do + { + Handler *tmp; + + if (handler->after) + { + handler_unref_R (signal_id, instance, handler_list); + handler_list = handler; + break; + } + else if (!handler->block_count && (!handler->detail || handler->detail == detail) && + handler->sequential_number < max_sequential_handler_number) + { + SIGNAL_UNLOCK (); + g_closure_invoke (handler->closure, + return_accu, + node->n_params + 1, + instance_and_params, + &emission.ihint); + if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && + emission.state == EMISSION_RUN) + emission.state = EMISSION_STOP; + SIGNAL_LOCK (); + return_value_altered = TRUE; + + tmp = emission.state == EMISSION_RUN ? handler->next : NULL; + } + else + tmp = handler->next; + + if (tmp) + handler_ref (tmp); + handler_unref_R (signal_id, instance, handler_list); + handler_list = handler; + handler = tmp; + } + while (handler); + + if (emission.state == EMISSION_STOP) + goto EMIT_CLEANUP; + else if (emission.state == EMISSION_RESTART) + goto EMIT_RESTART; + } + + emission.ihint.run_type &= ~G_SIGNAL_RUN_FIRST; + emission.ihint.run_type |= G_SIGNAL_RUN_LAST; + + if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure) + { + emission.state = EMISSION_RUN; + + emission.chain_type = G_TYPE_FROM_INSTANCE (instance); + SIGNAL_UNLOCK (); + g_closure_invoke (class_closure, + return_accu, + node->n_params + 1, + instance_and_params, + &emission.ihint); + if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && + emission.state == EMISSION_RUN) + emission.state = EMISSION_STOP; + SIGNAL_LOCK (); + emission.chain_type = G_TYPE_NONE; + return_value_altered = TRUE; + + if (emission.state == EMISSION_STOP) + goto EMIT_CLEANUP; + else if (emission.state == EMISSION_RESTART) + goto EMIT_RESTART; + } + + if (handler_list) + { + Handler *handler = handler_list; + + emission.state = EMISSION_RUN; + handler_ref (handler); + do + { + Handler *tmp; + + if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail) && + handler->sequential_number < max_sequential_handler_number) + { + SIGNAL_UNLOCK (); + g_closure_invoke (handler->closure, + return_accu, + node->n_params + 1, + instance_and_params, + &emission.ihint); + if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && + emission.state == EMISSION_RUN) + emission.state = EMISSION_STOP; + SIGNAL_LOCK (); + return_value_altered = TRUE; + + tmp = emission.state == EMISSION_RUN ? handler->next : NULL; + } + else + tmp = handler->next; + + if (tmp) + handler_ref (tmp); + handler_unref_R (signal_id, instance, handler); + handler = tmp; + } + while (handler); + + if (emission.state == EMISSION_STOP) + goto EMIT_CLEANUP; + else if (emission.state == EMISSION_RESTART) + goto EMIT_RESTART; + } + + EMIT_CLEANUP: + + emission.ihint.run_type &= ~G_SIGNAL_RUN_LAST; + emission.ihint.run_type |= G_SIGNAL_RUN_CLEANUP; + + if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure) + { + gboolean need_unset = FALSE; + + emission.state = EMISSION_STOP; + + emission.chain_type = G_TYPE_FROM_INSTANCE (instance); + SIGNAL_UNLOCK (); + if (node->return_type != G_TYPE_NONE && !accumulator) + { + g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); + need_unset = TRUE; + } + g_closure_invoke (class_closure, + node->return_type != G_TYPE_NONE ? &accu : NULL, + node->n_params + 1, + instance_and_params, + &emission.ihint); + if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && + emission.state == EMISSION_RUN) + emission.state = EMISSION_STOP; + if (need_unset) + g_value_unset (&accu); + SIGNAL_LOCK (); + return_value_altered = TRUE; + + emission.chain_type = G_TYPE_NONE; + + if (emission.state == EMISSION_RESTART) + goto EMIT_RESTART; + } + + if (handler_list) + handler_unref_R (signal_id, instance, handler_list); + + emission_pop (&emission); + SIGNAL_UNLOCK (); + if (accumulator) + g_value_unset (&accu); + + TRACE(GOBJECT_SIGNAL_EMIT_END(node->signal_id, detail, instance, G_TYPE_FROM_INSTANCE (instance))); + + return return_value_altered; +} + +static void +add_invalid_closure_notify (Handler *handler, + gpointer instance) +{ + g_closure_add_invalidate_notifier (handler->closure, instance, invalid_closure_notify); + handler->has_invalid_closure_notify = 1; +} + +static void +remove_invalid_closure_notify (Handler *handler, + gpointer instance) +{ + if (handler->has_invalid_closure_notify) + { + g_closure_remove_invalidate_notifier (handler->closure, instance, invalid_closure_notify); + handler->has_invalid_closure_notify = 0; + } +} + +static void +invalid_closure_notify (gpointer instance, + GClosure *closure) +{ + Handler *handler; + guint signal_id; + + SIGNAL_LOCK (); + + handler = handler_lookup (instance, 0, closure, &signal_id); + /* See https://bugzilla.gnome.org/show_bug.cgi?id=730296 for discussion about this... */ + g_assert (handler != NULL); + g_assert (handler->closure == closure); + + g_hash_table_remove (g_handlers, handler); + handler->sequential_number = 0; + handler->block_count = 1; + handler_unref_R (signal_id, instance, handler); + + SIGNAL_UNLOCK (); +} + +static const gchar* +type_debug_name (GType type) +{ + if (type) + { + const char *name = g_type_name (type & ~G_SIGNAL_TYPE_STATIC_SCOPE); + return name ? name : ""; + } + else + return ""; +} + +/** + * g_signal_accumulator_true_handled: + * @ihint: standard #GSignalAccumulator parameter + * @return_accu: standard #GSignalAccumulator parameter + * @handler_return: standard #GSignalAccumulator parameter + * @dummy: standard #GSignalAccumulator parameter + * + * A predefined #GSignalAccumulator for signals that return a + * boolean values. The behavior that this accumulator gives is + * that a return of %TRUE stops the signal emission: no further + * callbacks will be invoked, while a return of %FALSE allows + * the emission to continue. The idea here is that a %TRUE return + * indicates that the callback handled the signal, and no further + * handling is needed. + * + * Since: 2.4 + * + * Returns: standard #GSignalAccumulator result + */ +gboolean +g_signal_accumulator_true_handled (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + gboolean continue_emission; + gboolean signal_handled; + + signal_handled = g_value_get_boolean (handler_return); + g_value_set_boolean (return_accu, signal_handled); + continue_emission = !signal_handled; + + return continue_emission; +} + +/** + * g_signal_accumulator_first_wins: + * @ihint: standard #GSignalAccumulator parameter + * @return_accu: standard #GSignalAccumulator parameter + * @handler_return: standard #GSignalAccumulator parameter + * @dummy: standard #GSignalAccumulator parameter + * + * A predefined #GSignalAccumulator for signals intended to be used as a + * hook for application code to provide a particular value. Usually + * only one such value is desired and multiple handlers for the same + * signal don't make much sense (except for the case of the default + * handler defined in the class structure, in which case you will + * usually want the signal connection to override the class handler). + * + * This accumulator will use the return value from the first signal + * handler that is run as the return value for the signal and not run + * any further handlers (ie: the first handler "wins"). + * + * Returns: standard #GSignalAccumulator result + * + * Since: 2.28 + **/ +gboolean +g_signal_accumulator_first_wins (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + g_value_copy (handler_return, return_accu); + return FALSE; +} + +/** + * g_clear_signal_handler: + * @handler_id_ptr: A pointer to a handler ID (of type #gulong) of the handler to be disconnected. + * @instance: (type GObject.Object): The instance to remove the signal handler from. + * This pointer may be %NULL or invalid, if the handler ID is zero. + * + * Disconnects a handler from @instance so it will not be called during + * any future or currently ongoing emissions of the signal it has been + * connected to. The @handler_id_ptr is then set to zero, which is never a valid handler ID value (see g_signal_connect()). + * + * If the handler ID is 0 then this function does nothing. + * + * There is also a macro version of this function so that the code + * will be inlined. + * + * Since: 2.62 + */ +void +(g_clear_signal_handler) (gulong *handler_id_ptr, + gpointer instance) +{ + g_return_if_fail (handler_id_ptr != NULL); + +#ifndef g_clear_signal_handler +#error g_clear_signal_handler() macro is not defined +#endif + + g_clear_signal_handler (handler_id_ptr, instance); +} diff --git a/gobject/gsignal.h b/gobject/gsignal.h new file mode 100644 index 0000000..04f1344 --- /dev/null +++ b/gobject/gsignal.h @@ -0,0 +1,640 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000-2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_SIGNAL_H__ +#define __G_SIGNAL_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include +#include + +G_BEGIN_DECLS + +/* --- typedefs --- */ +typedef struct _GSignalQuery GSignalQuery; +typedef struct _GSignalInvocationHint GSignalInvocationHint; +/** + * GSignalCMarshaller: + * + * This is the signature of marshaller functions, required to marshall + * arrays of parameter values to signal emissions into C language callback + * invocations. + * + * It is merely an alias to #GClosureMarshal since the #GClosure mechanism + * takes over responsibility of actual function invocation for the signal + * system. + */ +typedef GClosureMarshal GSignalCMarshaller; +/** + * GSignalCVaMarshaller: + * + * This is the signature of va_list marshaller functions, an optional + * marshaller that can be used in some situations to avoid + * marshalling the signal argument into GValues. + */ +typedef GVaClosureMarshal GSignalCVaMarshaller; +/** + * GSignalEmissionHook: + * @ihint: Signal invocation hint, see #GSignalInvocationHint. + * @n_param_values: the number of parameters to the function, including + * the instance on which the signal was emitted. + * @param_values: (array length=n_param_values): the instance on which + * the signal was emitted, followed by the parameters of the emission. + * @data: user data associated with the hook. + * + * A simple function pointer to get invoked when the signal is emitted. + * + * Emission hooks allow you to tie a hook to the signal type, so that it will + * trap all emissions of that signal, from any object. + * + * You may not attach these to signals created with the %G_SIGNAL_NO_HOOKS flag. + * + * Returns: whether it wants to stay connected. If it returns %FALSE, the signal + * hook is disconnected (and destroyed). + */ +typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint, + guint n_param_values, + const GValue *param_values, + gpointer data); +/** + * GSignalAccumulator: + * @ihint: Signal invocation hint, see #GSignalInvocationHint. + * @return_accu: Accumulator to collect callback return values in, this + * is the return value of the current signal emission. + * @handler_return: A #GValue holding the return value of the signal handler. + * @data: Callback data that was specified when creating the signal. + * + * The signal accumulator is a special callback function that can be used + * to collect return values of the various callbacks that are called + * during a signal emission. + * + * The signal accumulator is specified at signal creation time, if it is + * left %NULL, no accumulation of callback return values is performed. + * The return value of signal emissions is then the value returned by the + * last callback. + * + * Returns: The accumulator function returns whether the signal emission + * should be aborted. Returning %TRUE will continue with + * the signal emission. Returning %FALSE will abort the current emission. + * Since 2.62, returning %FALSE will skip to the CLEANUP stage. In this case, + * emission will occur as normal in the CLEANUP stage and the handler's + * return value will be accumulated. + */ +typedef gboolean (*GSignalAccumulator) (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data); + + +/* --- run, match and connect types --- */ +/** + * GSignalFlags: + * @G_SIGNAL_RUN_FIRST: Invoke the object method handler in the first emission stage. + * @G_SIGNAL_RUN_LAST: Invoke the object method handler in the third emission stage. + * @G_SIGNAL_RUN_CLEANUP: Invoke the object method handler in the last emission stage. + * @G_SIGNAL_NO_RECURSE: Signals being emitted for an object while currently being in + * emission for this very object will not be emitted recursively, + * but instead cause the first emission to be restarted. + * @G_SIGNAL_DETAILED: This signal supports "::detail" appendices to the signal name + * upon handler connections and emissions. + * @G_SIGNAL_ACTION: Action signals are signals that may freely be emitted on alive + * objects from user code via g_signal_emit() and friends, without + * the need of being embedded into extra code that performs pre or + * post emission adjustments on the object. They can also be thought + * of as object methods which can be called generically by + * third-party code. + * @G_SIGNAL_NO_HOOKS: No emissions hooks are supported for this signal. + * @G_SIGNAL_MUST_COLLECT: Varargs signal emission will always collect the + * arguments, even if there are no signal handlers connected. Since 2.30. + * @G_SIGNAL_DEPRECATED: The signal is deprecated and will be removed + * in a future version. A warning will be generated if it is connected while + * running with G_ENABLE_DIAGNOSTIC=1. Since 2.32. + * @G_SIGNAL_ACCUMULATOR_FIRST_RUN: Only used in #GSignalAccumulator accumulator + * functions for the #GSignalInvocationHint::run_type field to mark the first + * call to the accumulator function for a signal emission. Since 2.68. + * + * The signal flags are used to specify a signal's behaviour. + */ +typedef enum +{ + G_SIGNAL_RUN_FIRST = 1 << 0, + G_SIGNAL_RUN_LAST = 1 << 1, + G_SIGNAL_RUN_CLEANUP = 1 << 2, + G_SIGNAL_NO_RECURSE = 1 << 3, + G_SIGNAL_DETAILED = 1 << 4, + G_SIGNAL_ACTION = 1 << 5, + G_SIGNAL_NO_HOOKS = 1 << 6, + G_SIGNAL_MUST_COLLECT = 1 << 7, + G_SIGNAL_DEPRECATED = 1 << 8, + /* normal signal flags until 1 << 16 */ + G_SIGNAL_ACCUMULATOR_FIRST_RUN = 1 << 17, +} GSignalFlags; +/** + * G_SIGNAL_FLAGS_MASK: + * + * A mask for all #GSignalFlags bits. + */ +#define G_SIGNAL_FLAGS_MASK 0x1ff +/** + * GConnectFlags: + * @G_CONNECT_AFTER: whether the handler should be called before or after the + * default handler of the signal. + * @G_CONNECT_SWAPPED: whether the instance and data should be swapped when + * calling the handler; see g_signal_connect_swapped() for an example. + * + * The connection flags are used to specify the behaviour of a signal's + * connection. + */ +typedef enum +{ + G_CONNECT_AFTER = 1 << 0, + G_CONNECT_SWAPPED = 1 << 1 +} GConnectFlags; +/** + * GSignalMatchType: + * @G_SIGNAL_MATCH_ID: The signal id must be equal. + * @G_SIGNAL_MATCH_DETAIL: The signal detail must be equal. + * @G_SIGNAL_MATCH_CLOSURE: The closure must be the same. + * @G_SIGNAL_MATCH_FUNC: The C closure callback must be the same. + * @G_SIGNAL_MATCH_DATA: The closure data must be the same. + * @G_SIGNAL_MATCH_UNBLOCKED: Only unblocked signals may be matched. + * + * The match types specify what g_signal_handlers_block_matched(), + * g_signal_handlers_unblock_matched() and g_signal_handlers_disconnect_matched() + * match signals by. + */ +typedef enum +{ + G_SIGNAL_MATCH_ID = 1 << 0, + G_SIGNAL_MATCH_DETAIL = 1 << 1, + G_SIGNAL_MATCH_CLOSURE = 1 << 2, + G_SIGNAL_MATCH_FUNC = 1 << 3, + G_SIGNAL_MATCH_DATA = 1 << 4, + G_SIGNAL_MATCH_UNBLOCKED = 1 << 5 +} GSignalMatchType; +/** + * G_SIGNAL_MATCH_MASK: + * + * A mask for all #GSignalMatchType bits. + */ +#define G_SIGNAL_MATCH_MASK 0x3f +/** + * G_SIGNAL_TYPE_STATIC_SCOPE: + * + * This macro flags signal argument types for which the signal system may + * assume that instances thereof remain persistent across all signal emissions + * they are used in. This is only useful for non ref-counted, value-copy types. + * + * To flag a signal argument in this way, add `| G_SIGNAL_TYPE_STATIC_SCOPE` + * to the corresponding argument of g_signal_new(). + * |[ + * g_signal_new ("size_request", + * G_TYPE_FROM_CLASS (gobject_class), + * G_SIGNAL_RUN_FIRST, + * G_STRUCT_OFFSET (GtkWidgetClass, size_request), + * NULL, NULL, + * _gtk_marshal_VOID__BOXED, + * G_TYPE_NONE, 1, + * GTK_TYPE_REQUISITION | G_SIGNAL_TYPE_STATIC_SCOPE); + * ]| + */ +#define G_SIGNAL_TYPE_STATIC_SCOPE (G_TYPE_FLAG_RESERVED_ID_BIT) + + +/* --- signal information --- */ +/** + * GSignalInvocationHint: + * @signal_id: The signal id of the signal invoking the callback + * @detail: The detail passed on for this emission + * @run_type: The stage the signal emission is currently in, this + * field will contain one of %G_SIGNAL_RUN_FIRST, + * %G_SIGNAL_RUN_LAST or %G_SIGNAL_RUN_CLEANUP and %G_SIGNAL_ACCUMULATOR_FIRST_RUN. + * %G_SIGNAL_ACCUMULATOR_FIRST_RUN is only set for the first run of the accumulator + * function for a signal emission. + * + * The #GSignalInvocationHint structure is used to pass on additional information + * to callbacks during a signal emission. + */ +struct _GSignalInvocationHint +{ + guint signal_id; + GQuark detail; + GSignalFlags run_type; +}; +/** + * GSignalQuery: + * @signal_id: The signal id of the signal being queried, or 0 if the + * signal to be queried was unknown. + * @signal_name: The signal name. + * @itype: The interface/instance type that this signal can be emitted for. + * @signal_flags: The signal flags as passed in to g_signal_new(). + * @return_type: The return type for user callbacks. + * @n_params: The number of parameters that user callbacks take. + * @param_types: (array length=n_params): The individual parameter types for + * user callbacks, note that the effective callback signature is: + * |[ + * @return_type callback (#gpointer data1, + * [param_types param_names,] + * gpointer data2); + * ]| + * + * A structure holding in-depth information for a specific signal. + * + * See also: g_signal_query() + */ +struct _GSignalQuery +{ + guint signal_id; + const gchar *signal_name; + GType itype; + GSignalFlags signal_flags; + GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ + guint n_params; + const GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ +}; + + +/* --- signals --- */ +GLIB_AVAILABLE_IN_ALL +guint g_signal_newv (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + GClosure *class_closure, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + GType *param_types); +GLIB_AVAILABLE_IN_ALL +guint g_signal_new_valist (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + GClosure *class_closure, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + va_list args); +GLIB_AVAILABLE_IN_ALL +guint g_signal_new (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + guint class_offset, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + ...); +GLIB_AVAILABLE_IN_ALL +guint g_signal_new_class_handler (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + GCallback class_handler, + GSignalAccumulator accumulator, + gpointer accu_data, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + ...); +GLIB_AVAILABLE_IN_ALL +void g_signal_set_va_marshaller (guint signal_id, + GType instance_type, + GSignalCVaMarshaller va_marshaller); + +GLIB_AVAILABLE_IN_ALL +void g_signal_emitv (const GValue *instance_and_params, + guint signal_id, + GQuark detail, + GValue *return_value); +GLIB_AVAILABLE_IN_ALL +void g_signal_emit_valist (gpointer instance, + guint signal_id, + GQuark detail, + va_list var_args); +GLIB_AVAILABLE_IN_ALL +void g_signal_emit (gpointer instance, + guint signal_id, + GQuark detail, + ...); +GLIB_AVAILABLE_IN_ALL +void g_signal_emit_by_name (gpointer instance, + const gchar *detailed_signal, + ...); +GLIB_AVAILABLE_IN_ALL +guint g_signal_lookup (const gchar *name, + GType itype); +GLIB_AVAILABLE_IN_ALL +const gchar * g_signal_name (guint signal_id); +GLIB_AVAILABLE_IN_ALL +void g_signal_query (guint signal_id, + GSignalQuery *query); +GLIB_AVAILABLE_IN_ALL +guint* g_signal_list_ids (GType itype, + guint *n_ids); +GLIB_AVAILABLE_IN_2_66 +gboolean g_signal_is_valid_name (const gchar *name); +GLIB_AVAILABLE_IN_ALL +gboolean g_signal_parse_name (const gchar *detailed_signal, + GType itype, + guint *signal_id_p, + GQuark *detail_p, + gboolean force_detail_quark); +GLIB_AVAILABLE_IN_ALL +GSignalInvocationHint* g_signal_get_invocation_hint (gpointer instance); + + +/* --- signal emissions --- */ +GLIB_AVAILABLE_IN_ALL +void g_signal_stop_emission (gpointer instance, + guint signal_id, + GQuark detail); +GLIB_AVAILABLE_IN_ALL +void g_signal_stop_emission_by_name (gpointer instance, + const gchar *detailed_signal); +GLIB_AVAILABLE_IN_ALL +gulong g_signal_add_emission_hook (guint signal_id, + GQuark detail, + GSignalEmissionHook hook_func, + gpointer hook_data, + GDestroyNotify data_destroy); +GLIB_AVAILABLE_IN_ALL +void g_signal_remove_emission_hook (guint signal_id, + gulong hook_id); + + +/* --- signal handlers --- */ +GLIB_AVAILABLE_IN_ALL +gboolean g_signal_has_handler_pending (gpointer instance, + guint signal_id, + GQuark detail, + gboolean may_be_blocked); +GLIB_AVAILABLE_IN_ALL +gulong g_signal_connect_closure_by_id (gpointer instance, + guint signal_id, + GQuark detail, + GClosure *closure, + gboolean after); +GLIB_AVAILABLE_IN_ALL +gulong g_signal_connect_closure (gpointer instance, + const gchar *detailed_signal, + GClosure *closure, + gboolean after); +GLIB_AVAILABLE_IN_ALL +gulong g_signal_connect_data (gpointer instance, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data, + GClosureNotify destroy_data, + GConnectFlags connect_flags); +GLIB_AVAILABLE_IN_ALL +void g_signal_handler_block (gpointer instance, + gulong handler_id); +GLIB_AVAILABLE_IN_ALL +void g_signal_handler_unblock (gpointer instance, + gulong handler_id); +GLIB_AVAILABLE_IN_ALL +void g_signal_handler_disconnect (gpointer instance, + gulong handler_id); +GLIB_AVAILABLE_IN_ALL +gboolean g_signal_handler_is_connected (gpointer instance, + gulong handler_id); +GLIB_AVAILABLE_IN_ALL +gulong g_signal_handler_find (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +GLIB_AVAILABLE_IN_ALL +guint g_signal_handlers_block_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +GLIB_AVAILABLE_IN_ALL +guint g_signal_handlers_unblock_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +GLIB_AVAILABLE_IN_ALL +guint g_signal_handlers_disconnect_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); + +GLIB_AVAILABLE_IN_2_62 +void g_clear_signal_handler (gulong *handler_id_ptr, + gpointer instance); + +#define g_clear_signal_handler(handler_id_ptr, instance) \ + G_STMT_START { \ + gpointer const _instance = (instance); \ + gulong *const _handler_id_ptr = (handler_id_ptr); \ + const gulong _handler_id = *_handler_id_ptr; \ + \ + if (_handler_id > 0) \ + { \ + *_handler_id_ptr = 0; \ + g_signal_handler_disconnect (_instance, _handler_id); \ + } \ + } G_STMT_END \ + GLIB_AVAILABLE_MACRO_IN_2_62 + +/* --- overriding and chaining --- */ +GLIB_AVAILABLE_IN_ALL +void g_signal_override_class_closure (guint signal_id, + GType instance_type, + GClosure *class_closure); +GLIB_AVAILABLE_IN_ALL +void g_signal_override_class_handler (const gchar *signal_name, + GType instance_type, + GCallback class_handler); +GLIB_AVAILABLE_IN_ALL +void g_signal_chain_from_overridden (const GValue *instance_and_params, + GValue *return_value); +GLIB_AVAILABLE_IN_ALL +void g_signal_chain_from_overridden_handler (gpointer instance, + ...); + + +/* --- convenience --- */ +/** + * g_signal_connect: + * @instance: the instance to connect to. + * @detailed_signal: a string of the form "signal-name::detail". + * @c_handler: the #GCallback to connect. + * @data: data to pass to @c_handler calls. + * + * Connects a #GCallback function to a signal for a particular object. + * + * The handler will be called synchronously, before the default handler of the signal. g_signal_emit() will not return control until all handlers are called. + * + * See [memory management of signal handlers][signal-memory-management] for + * details on how to handle the return value and memory management of @data. + * + * Returns: the handler ID, of type #gulong (always greater than 0 for successful connections) + */ +#define g_signal_connect(instance, detailed_signal, c_handler, data) \ + g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) +/** + * g_signal_connect_after: + * @instance: the instance to connect to. + * @detailed_signal: a string of the form "signal-name::detail". + * @c_handler: the #GCallback to connect. + * @data: data to pass to @c_handler calls. + * + * Connects a #GCallback function to a signal for a particular object. + * + * The handler will be called synchronously, after the default handler of the signal. + * + * Returns: the handler ID, of type #gulong (always greater than 0 for successful connections) + */ +#define g_signal_connect_after(instance, detailed_signal, c_handler, data) \ + g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, G_CONNECT_AFTER) +/** + * g_signal_connect_swapped: + * @instance: the instance to connect to. + * @detailed_signal: a string of the form "signal-name::detail". + * @c_handler: the #GCallback to connect. + * @data: data to pass to @c_handler calls. + * + * Connects a #GCallback function to a signal for a particular object. + * + * The instance on which the signal is emitted and @data will be swapped when + * calling the handler. This is useful when calling pre-existing functions to + * operate purely on the @data, rather than the @instance: swapping the + * parameters avoids the need to write a wrapper function. + * + * For example, this allows the shorter code: + * |[ + * g_signal_connect_swapped (button, "clicked", + * (GCallback) gtk_widget_hide, other_widget); + * ]| + * + * Rather than the cumbersome: + * |[ + * static void + * button_clicked_cb (GtkButton *button, GtkWidget *other_widget) + * { + * gtk_widget_hide (other_widget); + * } + * + * ... + * + * g_signal_connect (button, "clicked", + * (GCallback) button_clicked_cb, other_widget); + * ]| + * + * Returns: the handler ID, of type #gulong (always greater than 0 for successful connections) + */ +#define g_signal_connect_swapped(instance, detailed_signal, c_handler, data) \ + g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, G_CONNECT_SWAPPED) +/** + * g_signal_handlers_disconnect_by_func: + * @instance: The instance to remove handlers from. + * @func: The C closure callback of the handlers (useless for non-C closures). + * @data: The closure data of the handlers' closures. + * + * Disconnects all handlers on an instance that match @func and @data. + * + * Returns: The number of handlers that matched. + */ +#define g_signal_handlers_disconnect_by_func(instance, func, data) \ + g_signal_handlers_disconnect_matched ((instance), \ + (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), \ + 0, 0, NULL, (func), (data)) + +/** + * g_signal_handlers_disconnect_by_data: + * @instance: The instance to remove handlers from + * @data: the closure data of the handlers' closures + * + * Disconnects all handlers on an instance that match @data. + * + * Returns: The number of handlers that matched. + * + * Since: 2.32 + */ +#define g_signal_handlers_disconnect_by_data(instance, data) \ + g_signal_handlers_disconnect_matched ((instance), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, (data)) + +/** + * g_signal_handlers_block_by_func: + * @instance: The instance to block handlers from. + * @func: The C closure callback of the handlers (useless for non-C closures). + * @data: The closure data of the handlers' closures. + * + * Blocks all handlers on an instance that match @func and @data. + * + * Returns: The number of handlers that matched. + */ +#define g_signal_handlers_block_by_func(instance, func, data) \ + g_signal_handlers_block_matched ((instance), \ + (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), \ + 0, 0, NULL, (func), (data)) +/** + * g_signal_handlers_unblock_by_func: + * @instance: The instance to unblock handlers from. + * @func: The C closure callback of the handlers (useless for non-C closures). + * @data: The closure data of the handlers' closures. + * + * Unblocks all handlers on an instance that match @func and @data. + * + * Returns: The number of handlers that matched. + */ +#define g_signal_handlers_unblock_by_func(instance, func, data) \ + g_signal_handlers_unblock_matched ((instance), \ + (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), \ + 0, 0, NULL, (func), (data)) + + +GLIB_AVAILABLE_IN_ALL +gboolean g_signal_accumulator_true_handled (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy); + +GLIB_AVAILABLE_IN_ALL +gboolean g_signal_accumulator_first_wins (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy); + +/*< private >*/ +GLIB_AVAILABLE_IN_ALL +void g_signal_handlers_destroy (gpointer instance); +void _g_signals_destroy (GType itype); + +G_END_DECLS + +#endif /* __G_SIGNAL_H__ */ diff --git a/gobject/gsignalgroup.c b/gobject/gsignalgroup.c new file mode 100644 index 0000000..8feba54 --- /dev/null +++ b/gobject/gsignalgroup.c @@ -0,0 +1,912 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * Copyright (C) 2015-2022 Christian Hergert + * Copyright (C) 2015 Garrett Regier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" +#include "glib.h" +#include "glibintl.h" + +#include "gparamspecs.h" +#include "gsignalgroup.h" +#include "gvaluetypes.h" + +/** + * SECTION:gsignalgroup + * @Title: GSignalGroup + * @Short_description: Manage a collection of signals on a GObject + * + * #GSignalGroup manages to simplify the process of connecting + * many signals to a #GObject as a group. As such there is no API + * to disconnect a signal from the group. + * + * In particular, this allows you to: + * + * - Change the target instance, which automatically causes disconnection + * of the signals from the old instance and connecting to the new instance. + * - Block and unblock signals as a group + * - Ensuring that blocked state transfers across target instances. + * + * One place you might want to use such a structure is with #GtkTextView and + * #GtkTextBuffer. Often times, you'll need to connect to many signals on + * #GtkTextBuffer from a #GtkTextView subclass. This allows you to create a + * signal group during instance construction, simply bind the + * #GtkTextView:buffer property to #GSignalGroup:target and connect + * all the signals you need. When the #GtkTextView:buffer property changes + * all of the signals will be transitioned correctly. + * + * Since: 2.72 + */ + +struct _GSignalGroup +{ + GObject parent_instance; + + GWeakRef target_ref; + GRecMutex mutex; + GPtrArray *handlers; + GType target_type; + gssize block_count; + + guint has_bound_at_least_once : 1; +}; + +typedef struct _GSignalGroupClass +{ + GObjectClass parent_class; + + void (*bind) (GSignalGroup *self, + GObject *target); +} GSignalGroupClass; + +typedef struct +{ + GSignalGroup *group; + gulong handler_id; + GClosure *closure; + guint signal_id; + GQuark signal_detail; + guint connect_after : 1; +} SignalHandler; + +G_DEFINE_TYPE (GSignalGroup, g_signal_group, G_TYPE_OBJECT) + +typedef enum +{ + PROP_TARGET = 1, + PROP_TARGET_TYPE, + LAST_PROP +} GSignalGroupProperty; + +enum +{ + BIND, + UNBIND, + LAST_SIGNAL +}; + +static GParamSpec *properties[LAST_PROP]; +static guint signals[LAST_SIGNAL]; + +static void +g_signal_group_set_target_type (GSignalGroup *self, + GType target_type) +{ + g_assert (G_IS_SIGNAL_GROUP (self)); + g_assert (g_type_is_a (target_type, G_TYPE_OBJECT)); + + self->target_type = target_type; + + /* The class must be created at least once for the signals + * to be registered, otherwise g_signal_parse_name() will fail + */ + if (G_TYPE_IS_INTERFACE (target_type)) + { + if (g_type_default_interface_peek (target_type) == NULL) + g_type_default_interface_unref (g_type_default_interface_ref (target_type)); + } + else + { + if (g_type_class_peek (target_type) == NULL) + g_type_class_unref (g_type_class_ref (target_type)); + } +} + +static void +g_signal_group_gc_handlers (GSignalGroup *self) +{ + guint i; + + g_assert (G_IS_SIGNAL_GROUP (self)); + + /* + * Remove any handlers for which the closures have become invalid. We do + * this cleanup lazily to avoid situations where we could have disposal + * active on both the signal group and the peer object. + */ + + for (i = self->handlers->len; i > 0; i--) + { + const SignalHandler *handler = g_ptr_array_index (self->handlers, i - 1); + + g_assert (handler != NULL); + g_assert (handler->closure != NULL); + + if (handler->closure->is_invalid) + g_ptr_array_remove_index (self->handlers, i - 1); + } +} + +static void +g_signal_group__target_weak_notify (gpointer data, + GObject *where_object_was) +{ + GSignalGroup *self = data; + guint i; + + g_assert (G_IS_SIGNAL_GROUP (self)); + g_assert (where_object_was != NULL); + + g_rec_mutex_lock (&self->mutex); + + g_weak_ref_set (&self->target_ref, NULL); + + for (i = 0; i < self->handlers->len; i++) + { + SignalHandler *handler = g_ptr_array_index (self->handlers, i); + + handler->handler_id = 0; + } + + g_signal_emit (self, signals[UNBIND], 0); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TARGET]); + + g_rec_mutex_unlock (&self->mutex); +} + +static void +g_signal_group_bind_handler (GSignalGroup *self, + SignalHandler *handler, + GObject *target) +{ + gssize i; + + g_assert (self != NULL); + g_assert (G_IS_OBJECT (target)); + g_assert (handler != NULL); + g_assert (handler->signal_id != 0); + g_assert (handler->closure != NULL); + g_assert (handler->closure->is_invalid == 0); + g_assert (handler->handler_id == 0); + + handler->handler_id = g_signal_connect_closure_by_id (target, + handler->signal_id, + handler->signal_detail, + handler->closure, + handler->connect_after); + + g_assert (handler->handler_id != 0); + + for (i = 0; i < self->block_count; i++) + g_signal_handler_block (target, handler->handler_id); +} + +static void +g_signal_group_bind (GSignalGroup *self, + GObject *target) +{ + GObject *hold; + guint i; + + g_assert (G_IS_SIGNAL_GROUP (self)); + g_assert (!target || G_IS_OBJECT (target)); + + if (target == NULL) + return; + + self->has_bound_at_least_once = TRUE; + + hold = g_object_ref (target); + + g_weak_ref_set (&self->target_ref, hold); + g_object_weak_ref (hold, g_signal_group__target_weak_notify, self); + + g_signal_group_gc_handlers (self); + + for (i = 0; i < self->handlers->len; i++) + { + SignalHandler *handler = g_ptr_array_index (self->handlers, i); + + g_signal_group_bind_handler (self, handler, hold); + } + + g_signal_emit (self, signals [BIND], 0, hold); + + g_object_unref (hold); +} + +static void +g_signal_group_unbind (GSignalGroup *self) +{ + GObject *target; + guint i; + + g_return_if_fail (G_IS_SIGNAL_GROUP (self)); + + target = g_weak_ref_get (&self->target_ref); + + /* + * Target may be NULL by this point, as we got notified of its destruction. + * However, if we're early enough, we may get a full reference back and can + * cleanly disconnect our connections. + */ + + if (target != NULL) + { + g_weak_ref_set (&self->target_ref, NULL); + + /* + * Let go of our weak reference now that we have a full reference + * for the life of this function. + */ + g_object_weak_unref (target, + g_signal_group__target_weak_notify, + self); + } + + g_signal_group_gc_handlers (self); + + for (i = 0; i < self->handlers->len; i++) + { + SignalHandler *handler; + gulong handler_id; + + handler = g_ptr_array_index (self->handlers, i); + + g_assert (handler != NULL); + g_assert (handler->signal_id != 0); + g_assert (handler->closure != NULL); + + handler_id = handler->handler_id; + handler->handler_id = 0; + + /* + * If @target is NULL, we lost a race to cleanup the weak + * instance and the signal connections have already been + * finalized and therefore nothing to do. + */ + + if (target != NULL && handler_id != 0) + g_signal_handler_disconnect (target, handler_id); + } + + g_signal_emit (self, signals [UNBIND], 0); + + g_clear_object (&target); +} + +static gboolean +g_signal_group_check_target_type (GSignalGroup *self, + gpointer target) +{ + if ((target != NULL) && + !g_type_is_a (G_OBJECT_TYPE (target), self->target_type)) + { + g_critical ("Failed to set GSignalGroup of target type %s " + "using target %p of type %s", + g_type_name (self->target_type), + target, G_OBJECT_TYPE_NAME (target)); + return FALSE; + } + + return TRUE; +} + +/** + * g_signal_group_block: + * @self: the #GSignalGroup + * + * Blocks all signal handlers managed by @self so they will not + * be called during any signal emissions. Must be unblocked exactly + * the same number of times it has been blocked to become active again. + * + * This blocked state will be kept across changes of the target instance. + * + * Since: 2.72 + */ +void +g_signal_group_block (GSignalGroup *self) +{ + GObject *target; + guint i; + + g_return_if_fail (G_IS_SIGNAL_GROUP (self)); + g_return_if_fail (self->block_count >= 0); + + g_rec_mutex_lock (&self->mutex); + + self->block_count++; + + target = g_weak_ref_get (&self->target_ref); + + if (target == NULL) + goto unlock; + + for (i = 0; i < self->handlers->len; i++) + { + const SignalHandler *handler = g_ptr_array_index (self->handlers, i); + + g_assert (handler != NULL); + g_assert (handler->signal_id != 0); + g_assert (handler->closure != NULL); + g_assert (handler->handler_id != 0); + + g_signal_handler_block (target, handler->handler_id); + } + + g_object_unref (target); + +unlock: + g_rec_mutex_unlock (&self->mutex); +} + +/** + * g_signal_group_unblock: + * @self: the #GSignalGroup + * + * Unblocks all signal handlers managed by @self so they will be + * called again during any signal emissions unless it is blocked + * again. Must be unblocked exactly the same number of times it + * has been blocked to become active again. + * + * Since: 2.72 + */ +void +g_signal_group_unblock (GSignalGroup *self) +{ + GObject *target; + guint i; + + g_return_if_fail (G_IS_SIGNAL_GROUP (self)); + g_return_if_fail (self->block_count > 0); + + g_rec_mutex_lock (&self->mutex); + + self->block_count--; + + target = g_weak_ref_get (&self->target_ref); + if (target == NULL) + goto unlock; + + for (i = 0; i < self->handlers->len; i++) + { + const SignalHandler *handler = g_ptr_array_index (self->handlers, i); + + g_assert (handler != NULL); + g_assert (handler->signal_id != 0); + g_assert (handler->closure != NULL); + g_assert (handler->handler_id != 0); + + g_signal_handler_unblock (target, handler->handler_id); + } + + g_object_unref (target); + +unlock: + g_rec_mutex_unlock (&self->mutex); +} + +/** + * g_signal_group_dup_target: + * @self: the #GSignalGroup + * + * Gets the target instance used when connecting signals. + * + * Returns: (nullable) (transfer full) (type GObject): The target instance + * + * Since: 2.72 + */ +gpointer +g_signal_group_dup_target (GSignalGroup *self) +{ + GObject *target; + + g_return_val_if_fail (G_IS_SIGNAL_GROUP (self), NULL); + + g_rec_mutex_lock (&self->mutex); + target = g_weak_ref_get (&self->target_ref); + g_rec_mutex_unlock (&self->mutex); + + return target; +} + +/** + * g_signal_group_set_target: + * @self: the #GSignalGroup. + * @target: (nullable) (type GObject) (transfer none): The target instance used + * when connecting signals. + * + * Sets the target instance used when connecting signals. Any signal + * that has been registered with g_signal_group_connect_object() or + * similar functions will be connected to this object. + * + * If the target instance was previously set, signals will be + * disconnected from that object prior to connecting to @target. + * + * Since: 2.72 + */ +void +g_signal_group_set_target (GSignalGroup *self, + gpointer target) +{ + GObject *object; + + g_return_if_fail (G_IS_SIGNAL_GROUP (self)); + + g_rec_mutex_lock (&self->mutex); + + object = g_weak_ref_get (&self->target_ref); + + if (object == (GObject *)target) + goto cleanup; + + if (!g_signal_group_check_target_type (self, target)) + goto cleanup; + + /* Only emit unbind if we've ever called bind */ + if (self->has_bound_at_least_once) + g_signal_group_unbind (self); + + g_signal_group_bind (self, target); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TARGET]); + +cleanup: + g_clear_object (&object); + g_rec_mutex_unlock (&self->mutex); +} + +static void +signal_handler_free (gpointer data) +{ + SignalHandler *handler = data; + + if (handler->closure != NULL) + g_closure_invalidate (handler->closure); + + handler->handler_id = 0; + handler->signal_id = 0; + handler->signal_detail = 0; + g_clear_pointer (&handler->closure, g_closure_unref); + g_slice_free (SignalHandler, handler); +} + +static void +g_signal_group_constructed (GObject *object) +{ + GSignalGroup *self = (GSignalGroup *)object; + GObject *target; + + g_rec_mutex_lock (&self->mutex); + + target = g_weak_ref_get (&self->target_ref); + if (!g_signal_group_check_target_type (self, target)) + g_signal_group_set_target (self, NULL); + + G_OBJECT_CLASS (g_signal_group_parent_class)->constructed (object); + + g_clear_object (&target); + + g_rec_mutex_unlock (&self->mutex); +} + +static void +g_signal_group_dispose (GObject *object) +{ + GSignalGroup *self = (GSignalGroup *)object; + + g_rec_mutex_lock (&self->mutex); + + g_signal_group_gc_handlers (self); + + if (self->has_bound_at_least_once) + g_signal_group_unbind (self); + + g_clear_pointer (&self->handlers, g_ptr_array_unref); + + g_rec_mutex_unlock (&self->mutex); + + G_OBJECT_CLASS (g_signal_group_parent_class)->dispose (object); +} + +static void +g_signal_group_finalize (GObject *object) +{ + GSignalGroup *self = (GSignalGroup *)object; + + g_weak_ref_clear (&self->target_ref); + g_rec_mutex_clear (&self->mutex); + + G_OBJECT_CLASS (g_signal_group_parent_class)->finalize (object); +} + +static void +g_signal_group_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GSignalGroup *self = G_SIGNAL_GROUP (object); + + switch ((GSignalGroupProperty) prop_id) + { + case PROP_TARGET: + g_value_take_object (value, g_signal_group_dup_target (self)); + break; + + case PROP_TARGET_TYPE: + g_value_set_gtype (value, self->target_type); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_signal_group_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GSignalGroup *self = G_SIGNAL_GROUP (object); + + switch ((GSignalGroupProperty) prop_id) + { + case PROP_TARGET: + g_signal_group_set_target (self, g_value_get_object (value)); + break; + + case PROP_TARGET_TYPE: + g_signal_group_set_target_type (self, g_value_get_gtype (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +g_signal_group_class_init (GSignalGroupClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = g_signal_group_constructed; + object_class->dispose = g_signal_group_dispose; + object_class->finalize = g_signal_group_finalize; + object_class->get_property = g_signal_group_get_property; + object_class->set_property = g_signal_group_set_property; + + /** + * GSignalGroup:target + * + * The target instance used when connecting signals. + * + * Since: 2.72 + */ + properties[PROP_TARGET] = + g_param_spec_object ("target", + "Target", + "The target instance used when connecting signals.", + G_TYPE_OBJECT, + (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); + + /** + * GSignalGroup:target-type + * + * The #GType of the target property. + * + * Since: 2.72 + */ + properties[PROP_TARGET_TYPE] = + g_param_spec_gtype ("target-type", + "Target Type", + "The GType of the target property.", + G_TYPE_OBJECT, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, properties); + + /** + * GSignalGroup::bind: + * @self: the #GSignalGroup + * @instance: a #GObject containing the new value for #GSignalGroup:target + * + * This signal is emitted when #GSignalGroup:target is set to a new value + * other than %NULL. It is similar to #GObject::notify on `target` except it + * will not emit when #GSignalGroup:target is %NULL and also allows for + * receiving the #GObject without a data-race. + * + * Since: 2.72 + */ + signals[BIND] = + g_signal_new ("bind", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + /** + * GSignalGroup::unbind: + * @self: a #GSignalGroup + * + * This signal is emitted when the target instance of @self is set to a + * new #GObject. + * + * This signal will only be emitted if the previous target of @self is + * non-%NULL. + * + * Since: 2.72 + */ + signals[UNBIND] = + g_signal_new ("unbind", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 0); +} + +static void +g_signal_group_init (GSignalGroup *self) +{ + g_rec_mutex_init (&self->mutex); + self->handlers = g_ptr_array_new_with_free_func (signal_handler_free); + self->target_type = G_TYPE_OBJECT; +} + +/** + * g_signal_group_new: + * @target_type: the #GType of the target instance. + * + * Creates a new #GSignalGroup for target instances of @target_type. + * + * Returns: (transfer full): a new #GSignalGroup + * + * Since: 2.72 + */ +GSignalGroup * +g_signal_group_new (GType target_type) +{ + g_return_val_if_fail (g_type_is_a (target_type, G_TYPE_OBJECT), NULL); + + return g_object_new (G_TYPE_SIGNAL_GROUP, + "target-type", target_type, + NULL); +} + +static void +g_signal_group_connect_full (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data, + GClosureNotify notify, + GConnectFlags flags, + gboolean is_object) +{ + GObject *target; + SignalHandler *handler; + GClosure *closure; + guint signal_id; + GQuark signal_detail; + + g_return_if_fail (G_IS_SIGNAL_GROUP (self)); + g_return_if_fail (detailed_signal != NULL); + g_return_if_fail (g_signal_parse_name (detailed_signal, self->target_type, + &signal_id, &signal_detail, TRUE) != 0); + g_return_if_fail (c_handler != NULL); + g_return_if_fail (!is_object || G_IS_OBJECT (data)); + + g_rec_mutex_lock (&self->mutex); + + if (self->has_bound_at_least_once) + { + g_critical ("Cannot add signals after setting target"); + g_rec_mutex_unlock (&self->mutex); + return; + } + + if ((flags & G_CONNECT_SWAPPED) != 0) + closure = g_cclosure_new_swap (c_handler, data, notify); + else + closure = g_cclosure_new (c_handler, data, notify); + + handler = g_slice_new0 (SignalHandler); + handler->group = self; + handler->signal_id = signal_id; + handler->signal_detail = signal_detail; + handler->closure = g_closure_ref (closure); + handler->connect_after = ((flags & G_CONNECT_AFTER) != 0); + + g_closure_sink (closure); + + if (is_object) + { + /* Set closure->is_invalid when data is disposed. We only track this to avoid + * reconnecting in the future. However, we do a round of cleanup when ever we + * connect a new object or the target changes to GC the old handlers. + */ + g_object_watch_closure (data, closure); + } + + g_ptr_array_add (self->handlers, handler); + + target = g_weak_ref_get (&self->target_ref); + + if (target != NULL) + { + g_signal_group_bind_handler (self, handler, target); + g_object_unref (target); + } + + /* Lazily remove any old handlers on connect */ + g_signal_group_gc_handlers (self); + + g_rec_mutex_unlock (&self->mutex); +} + +/** + * g_signal_group_connect_object: (skip) + * @self: a #GSignalGroup + * @detailed_signal: a string of the form `signal-name` with optional `::signal-detail` + * @c_handler: (scope notified): the #GCallback to connect + * @object: (not nullable) (transfer none): the #GObject to pass as data to @c_handler calls + * @flags: #GConnectFlags for the signal connection + * + * Connects @c_handler to the signal @detailed_signal on #GSignalGroup:target. + * + * Ensures that the @object stays alive during the call to @c_handler + * by temporarily adding a reference count. When the @object is destroyed + * the signal handler will automatically be removed. + * + * You cannot connect a signal handler after #GSignalGroup:target has been set. + * + * Since: 2.72 + */ +void +g_signal_group_connect_object (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer object, + GConnectFlags flags) +{ + g_return_if_fail (G_IS_OBJECT (object)); + + g_signal_group_connect_full (self, detailed_signal, c_handler, object, NULL, + flags, TRUE); +} + +/** + * g_signal_group_connect_data: + * @self: a #GSignalGroup + * @detailed_signal: a string of the form "signal-name::detail" + * @c_handler: (scope notified) (closure data) (destroy notify): the #GCallback to connect + * @data: the data to pass to @c_handler calls + * @notify: function to be called when disposing of @self + * @flags: the flags used to create the signal connection + * + * Connects @c_handler to the signal @detailed_signal + * on the target instance of @self. + * + * You cannot connect a signal handler after #GSignalGroup:target has been set. + * + * Since: 2.72 + */ +void +g_signal_group_connect_data (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data, + GClosureNotify notify, + GConnectFlags flags) +{ + g_signal_group_connect_full (self, detailed_signal, c_handler, data, notify, + flags, FALSE); +} + +/** + * g_signal_group_connect: (skip) + * @self: a #GSignalGroup + * @detailed_signal: a string of the form "signal-name::detail" + * @c_handler: (scope notified): the #GCallback to connect + * @data: the data to pass to @c_handler calls + * + * Connects @c_handler to the signal @detailed_signal + * on the target instance of @self. + * + * You cannot connect a signal handler after #GSignalGroup:target has been set. + * + * Since: 2.72 + */ +void +g_signal_group_connect (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data) +{ + g_signal_group_connect_full (self, detailed_signal, c_handler, data, NULL, + 0, FALSE); +} + +/** + * g_signal_group_connect_after: (skip) + * @self: a #GSignalGroup + * @detailed_signal: a string of the form "signal-name::detail" + * @c_handler: (scope notified): the #GCallback to connect + * @data: the data to pass to @c_handler calls + * + * Connects @c_handler to the signal @detailed_signal + * on the target instance of @self. + * + * The @c_handler will be called after the default handler of the signal. + * + * You cannot connect a signal handler after #GSignalGroup:target has been set. + * + * Since: 2.72 + */ +void +g_signal_group_connect_after (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data) +{ + g_signal_group_connect_full (self, detailed_signal, c_handler, + data, NULL, G_CONNECT_AFTER, FALSE); +} + +/** + * g_signal_group_connect_swapped: + * @self: a #GSignalGroup + * @detailed_signal: a string of the form "signal-name::detail" + * @c_handler: (scope async): the #GCallback to connect + * @data: the data to pass to @c_handler calls + * + * Connects @c_handler to the signal @detailed_signal + * on the target instance of @self. + * + * The instance on which the signal is emitted and @data + * will be swapped when calling @c_handler. + * + * You cannot connect a signal handler after #GSignalGroup:target has been set. + * + * Since: 2.72 + */ +void +g_signal_group_connect_swapped (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data) +{ + g_signal_group_connect_full (self, detailed_signal, c_handler, data, NULL, + G_CONNECT_SWAPPED, FALSE); +} diff --git a/gobject/gsignalgroup.h b/gobject/gsignalgroup.h new file mode 100644 index 0000000..c82a5cd --- /dev/null +++ b/gobject/gsignalgroup.h @@ -0,0 +1,93 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * Copyright (C) 2015-2022 Christian Hergert + * Copyright (C) 2015 Garrett Regier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef __G_SIGNAL_GROUP_H__ +#define __G_SIGNAL_GROUP_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +#define G_SIGNAL_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_SIGNAL_GROUP, GSignalGroup)) +#define G_IS_SIGNAL_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_SIGNAL_GROUP)) +#define G_TYPE_SIGNAL_GROUP (g_signal_group_get_type()) + +/** + * GSignalGroup: + * + * #GSignalGroup is an opaque structure whose members + * cannot be accessed directly. + * + * Since: 2.72 + */ +typedef struct _GSignalGroup GSignalGroup; + +GLIB_AVAILABLE_IN_2_72 +GType g_signal_group_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_2_72 +GSignalGroup *g_signal_group_new (GType target_type); +GLIB_AVAILABLE_IN_2_72 +void g_signal_group_set_target (GSignalGroup *self, + gpointer target); +GLIB_AVAILABLE_IN_2_72 +gpointer g_signal_group_dup_target (GSignalGroup *self); +GLIB_AVAILABLE_IN_2_72 +void g_signal_group_block (GSignalGroup *self); +GLIB_AVAILABLE_IN_2_72 +void g_signal_group_unblock (GSignalGroup *self); +GLIB_AVAILABLE_IN_2_72 +void g_signal_group_connect_object (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer object, + GConnectFlags flags); +GLIB_AVAILABLE_IN_2_72 +void g_signal_group_connect_data (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data, + GClosureNotify notify, + GConnectFlags flags); +GLIB_AVAILABLE_IN_2_72 +void g_signal_group_connect (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data); +GLIB_AVAILABLE_IN_2_72 +void g_signal_group_connect_after (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data); +GLIB_AVAILABLE_IN_2_72 +void g_signal_group_connect_swapped (GSignalGroup *self, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data); + +G_END_DECLS + +#endif /* __G_SIGNAL_GROUP_H__ */ diff --git a/gobject/gsourceclosure.c b/gobject/gsourceclosure.c new file mode 100644 index 0000000..d1b1ee4 --- /dev/null +++ b/gobject/gsourceclosure.c @@ -0,0 +1,322 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gsourceclosure.h" +#include "gboxed.h" +#include "genums.h" +#include "gmarshal.h" +#include "gvalue.h" +#include "gvaluetypes.h" +#ifdef G_OS_UNIX +#include "glib-unix.h" +#endif + +G_DEFINE_BOXED_TYPE (GIOChannel, g_io_channel, g_io_channel_ref, g_io_channel_unref) + +GType +g_io_condition_get_type (void) +{ + static GType etype = 0; + + if (g_once_init_enter (&etype)) + { + static const GFlagsValue values[] = { + { G_IO_IN, "G_IO_IN", "in" }, + { G_IO_OUT, "G_IO_OUT", "out" }, + { G_IO_PRI, "G_IO_PRI", "pri" }, + { G_IO_ERR, "G_IO_ERR", "err" }, + { G_IO_HUP, "G_IO_HUP", "hup" }, + { G_IO_NVAL, "G_IO_NVAL", "nval" }, + { 0, NULL, NULL } + }; + GType type_id = g_flags_register_static ("GIOCondition", values); + g_once_init_leave (&etype, type_id); + } + return etype; +} + +/* We need to hand-write this marshaler, since it doesn't have an + * instance object. + */ +static void +source_closure_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + GSourceFunc callback; + GCClosure *cc = (GCClosure*) closure; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 0); + + callback = (GSourceFunc) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (closure->data); + + g_value_set_boolean (return_value, v_return); +} + +static gboolean +io_watch_closure_callback (GIOChannel *channel, + GIOCondition condition, + gpointer data) +{ + GClosure *closure = data; + + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + g_value_init (¶ms[0], G_TYPE_IO_CHANNEL); + g_value_set_boxed (¶ms[0], channel); + + g_value_init (¶ms[1], G_TYPE_IO_CONDITION); + g_value_set_flags (¶ms[1], condition); + + g_closure_invoke (closure, &result_value, 2, params, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + g_value_unset (¶ms[0]); + g_value_unset (¶ms[1]); + + return result; +} + +static gboolean +g_child_watch_closure_callback (GPid pid, + gint status, + gpointer data) +{ + GClosure *closure = data; + + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + +#ifdef G_OS_UNIX + g_value_init (¶ms[0], G_TYPE_ULONG); + g_value_set_ulong (¶ms[0], pid); +#endif +#ifdef G_OS_WIN32 + g_value_init (¶ms[0], G_TYPE_POINTER); + g_value_set_pointer (¶ms[0], pid); +#endif + + g_value_init (¶ms[1], G_TYPE_INT); + g_value_set_int (¶ms[1], status); + + g_closure_invoke (closure, &result_value, 2, params, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + g_value_unset (¶ms[0]); + g_value_unset (¶ms[1]); + + return result; +} + +#ifdef G_OS_UNIX +static gboolean +g_unix_fd_source_closure_callback (int fd, + GIOCondition condition, + gpointer data) +{ + GClosure *closure = data; + + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_value_init (¶ms[0], G_TYPE_INT); + g_value_set_int (¶ms[0], fd); + + g_value_init (¶ms[1], G_TYPE_IO_CONDITION); + g_value_set_flags (¶ms[1], condition); + + g_closure_invoke (closure, &result_value, 2, params, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + g_value_unset (¶ms[0]); + g_value_unset (¶ms[1]); + + return result; +} +#endif + +static gboolean +source_closure_callback (gpointer data) +{ + GClosure *closure = data; + GValue result_value = G_VALUE_INIT; + gboolean result; + + g_value_init (&result_value, G_TYPE_BOOLEAN); + + g_closure_invoke (closure, &result_value, 0, NULL, NULL); + + result = g_value_get_boolean (&result_value); + g_value_unset (&result_value); + + return result; +} + +static void +closure_callback_get (gpointer cb_data, + GSource *source, + GSourceFunc *func, + gpointer *data) +{ + GSourceFunc closure_callback = source->source_funcs->closure_callback; + + if (!closure_callback) + { + if (source->source_funcs == &g_io_watch_funcs) + closure_callback = (GSourceFunc)io_watch_closure_callback; + else if (source->source_funcs == &g_child_watch_funcs) + closure_callback = (GSourceFunc)g_child_watch_closure_callback; +#ifdef G_OS_UNIX + else if (source->source_funcs == &g_unix_fd_source_funcs) + closure_callback = (GSourceFunc)g_unix_fd_source_closure_callback; +#endif + else if (source->source_funcs == &g_timeout_funcs || +#ifdef G_OS_UNIX + source->source_funcs == &g_unix_signal_funcs || +#endif + source->source_funcs == &g_idle_funcs) + closure_callback = source_closure_callback; + } + + *func = closure_callback; + *data = cb_data; +} + +static GSourceCallbackFuncs closure_callback_funcs = { + (void (*) (gpointer)) g_closure_ref, + (void (*) (gpointer)) g_closure_unref, + closure_callback_get +}; + +static void +closure_invalidated (gpointer user_data, + GClosure *closure) +{ + g_source_destroy (user_data); +} + +/** + * g_source_set_closure: + * @source: the source + * @closure: a #GClosure + * + * Set the callback for a source as a #GClosure. + * + * If the source is not one of the standard GLib types, the @closure_callback + * and @closure_marshal fields of the #GSourceFuncs structure must have been + * filled in with pointers to appropriate functions. + */ +void +g_source_set_closure (GSource *source, + GClosure *closure) +{ + g_return_if_fail (source != NULL); + g_return_if_fail (closure != NULL); + + if (!source->source_funcs->closure_callback && +#ifdef G_OS_UNIX + source->source_funcs != &g_unix_fd_source_funcs && + source->source_funcs != &g_unix_signal_funcs && +#endif + source->source_funcs != &g_child_watch_funcs && + source->source_funcs != &g_io_watch_funcs && + source->source_funcs != &g_timeout_funcs && + source->source_funcs != &g_idle_funcs) + { + g_critical (G_STRLOC ": closure cannot be set on GSource without GSourceFuncs::closure_callback"); + return; + } + + g_closure_ref (closure); + g_closure_sink (closure); + g_source_set_callback_indirect (source, closure, &closure_callback_funcs); + + g_closure_add_invalidate_notifier (closure, source, closure_invalidated); + + if (G_CLOSURE_NEEDS_MARSHAL (closure)) + { + GClosureMarshal marshal = (GClosureMarshal)source->source_funcs->closure_marshal; + if (marshal) + g_closure_set_marshal (closure, marshal); + else if (source->source_funcs == &g_idle_funcs || +#ifdef G_OS_UNIX + source->source_funcs == &g_unix_signal_funcs || +#endif + source->source_funcs == &g_timeout_funcs) + g_closure_set_marshal (closure, source_closure_marshal_BOOLEAN__VOID); + else + g_closure_set_marshal (closure, g_cclosure_marshal_generic); + } +} + +static void +dummy_closure_marshal (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + if (G_VALUE_HOLDS_BOOLEAN (return_value)) + g_value_set_boolean (return_value, TRUE); +} + +/** + * g_source_set_dummy_callback: + * @source: the source + * + * Sets a dummy callback for @source. The callback will do nothing, and + * if the source expects a #gboolean return value, it will return %TRUE. + * (If the source expects any other type of return value, it will return + * a 0/%NULL value; whatever g_value_init() initializes a #GValue to for + * that type.) + * + * If the source is not one of the standard GLib types, the + * @closure_callback and @closure_marshal fields of the #GSourceFuncs + * structure must have been filled in with pointers to appropriate + * functions. + */ +void +g_source_set_dummy_callback (GSource *source) +{ + GClosure *closure; + + closure = g_closure_new_simple (sizeof (GClosure), NULL); + g_closure_set_meta_marshal (closure, NULL, dummy_closure_marshal); + g_source_set_closure (source, closure); +} diff --git a/gobject/gsourceclosure.h b/gobject/gsourceclosure.h new file mode 100644 index 0000000..4847677 --- /dev/null +++ b/gobject/gsourceclosure.h @@ -0,0 +1,38 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_SOURCECLOSURE_H__ +#define __G_SOURCECLOSURE_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +GLIB_AVAILABLE_IN_ALL +void g_source_set_closure (GSource *source, + GClosure *closure); + +GLIB_AVAILABLE_IN_ALL +void g_source_set_dummy_callback (GSource *source); + +G_END_DECLS + +#endif /* __G_SOURCECLOSURE_H__ */ diff --git a/gobject/gtype-private.h b/gobject/gtype-private.h new file mode 100644 index 0000000..2e0afdd --- /dev/null +++ b/gobject/gtype-private.h @@ -0,0 +1,113 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_TYPE_PRIVATE_H__ +#define __G_TYPE_PRIVATE_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include "gboxed.h" +#include "gclosure.h" +#include "gobject.h" + +/*< private > + * GOBJECT_IF_DEBUG: + * @debug_type: Currently only OBJECTS and SIGNALS are supported. + * @code_block: Custom debug code. + * + * A convenience macro for debugging GObject. + * This macro is only used internally. + */ +#ifdef G_ENABLE_DEBUG +#define GOBJECT_IF_DEBUG(debug_type, code_block) \ +G_STMT_START { \ + if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) \ + { code_block; } \ +} G_STMT_END +#else /* !G_ENABLE_DEBUG */ +#define GOBJECT_IF_DEBUG(debug_type, code_block) +#endif /* G_ENABLE_DEBUG */ + +G_BEGIN_DECLS + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +extern GTypeDebugFlags _g_type_debug_flags; +G_GNUC_END_IGNORE_DEPRECATIONS + +typedef struct _GRealClosure GRealClosure; +struct _GRealClosure +{ + GClosureMarshal meta_marshal; + gpointer meta_marshal_data; + GVaClosureMarshal va_meta_marshal; + GVaClosureMarshal va_marshal; + GClosure closure; +}; + +#define G_REAL_CLOSURE(_c) \ + ((GRealClosure *)G_STRUCT_MEMBER_P ((_c), -G_STRUCT_OFFSET (GRealClosure, closure))) + +void _g_value_c_init (void); /* sync with gvalue.c */ +void _g_value_types_init (void); /* sync with gvaluetypes.c */ +void _g_enum_types_init (void); /* sync with genums.c */ +void _g_param_type_init (void); /* sync with gparam.c */ +void _g_boxed_type_init (void); /* sync with gboxed.c */ +void _g_object_type_init (void); /* sync with gobject.c */ +void _g_param_spec_types_init (void); /* sync with gparamspecs.c */ +void _g_value_transforms_init (void); /* sync with gvaluetransform.c */ +void _g_signal_init (void); /* sync with gsignal.c */ + +/* for gboxed.c */ +gpointer _g_type_boxed_copy (GType type, + gpointer value); +void _g_type_boxed_free (GType type, + gpointer value); +void _g_type_boxed_init (GType type, + GBoxedCopyFunc copy_func, + GBoxedFreeFunc free_func); + +gboolean _g_closure_is_void (GClosure *closure, + gpointer instance); +gboolean _g_closure_supports_invoke_va (GClosure *closure); +void _g_closure_set_va_marshal (GClosure *closure, + GVaClosureMarshal marshal); +void _g_closure_invoke_va (GClosure *closure, + GValue /*out*/ *return_value, + gpointer instance, + va_list args, + int n_params, + GType *param_types); + +gboolean _g_object_has_signal_handler (GObject *object); +void _g_object_set_has_signal_handler (GObject *object); + +/** + * _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE: + * + * See also G_DEFINE_TYPE_EXTENDED(). This macro is generally only + * necessary as a workaround for classes which have properties of + * object types that may be initialized in distinct threads. See: + * https://bugzilla.gnome.org/show_bug.cgi?id=674885 + * + * Currently private. + */ +#define _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE(TN, t_n, T_P, _f_, _P_, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE (TN, t_n, T_P) {_P_;} _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER (TN, t_n, T_P, _f_){_C_;} _G_DEFINE_TYPE_EXTENDED_END() + +G_END_DECLS + +#endif /* __G_TYPE_PRIVATE_H__ */ diff --git a/gobject/gtype.c b/gobject/gtype.c new file mode 100644 index 0000000..cf213b7 --- /dev/null +++ b/gobject/gtype.c @@ -0,0 +1,5024 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "../glib/gvalgrind.h" +#include + +#include "gtype.h" +#include "gtype-private.h" +#include "gtypeplugin.h" +#include "gvaluecollector.h" +#include "gatomicarray.h" +#include "gobject_trace.h" + +#include "glib-private.h" +#include "gconstructor.h" + +#ifdef G_OS_WIN32 +#include +#endif + +#ifdef G_ENABLE_DEBUG +#define IF_DEBUG(debug_type) if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) +#endif + +/** + * SECTION:gtype + * @short_description: The GLib Runtime type identification and + * management system + * @title:Type Information + * + * The GType API is the foundation of the GObject system. It provides the + * facilities for registering and managing all fundamental data types, + * user-defined object and interface types. + * + * For type creation and registration purposes, all types fall into one of + * two categories: static or dynamic. Static types are never loaded or + * unloaded at run-time as dynamic types may be. Static types are created + * with g_type_register_static() that gets type specific information passed + * in via a #GTypeInfo structure. + * + * Dynamic types are created with g_type_register_dynamic() which takes a + * #GTypePlugin structure instead. The remaining type information (the + * #GTypeInfo structure) is retrieved during runtime through #GTypePlugin + * and the g_type_plugin_*() API. + * + * These registration functions are usually called only once from a + * function whose only purpose is to return the type identifier for a + * specific class. Once the type (or class or interface) is registered, + * it may be instantiated, inherited, or implemented depending on exactly + * what sort of type it is. + * + * There is also a third registration function for registering fundamental + * types called g_type_register_fundamental() which requires both a #GTypeInfo + * structure and a #GTypeFundamentalInfo structure but it is seldom used + * since most fundamental types are predefined rather than user-defined. + * + * Type instance and class structs are limited to a total of 64 KiB, + * including all parent types. Similarly, type instances' private data + * (as created by G_ADD_PRIVATE()) are limited to a total of + * 64 KiB. If a type instance needs a large static buffer, allocate it + * separately (typically by using #GArray or #GPtrArray) and put a pointer + * to the buffer in the structure. + * + * As mentioned in the [GType conventions][gtype-conventions], type names must + * be at least three characters long. There is no upper length limit. The first + * character must be a letter (a–z or A–Z) or an underscore (‘_’). Subsequent + * characters can be letters, numbers or any of ‘-_+’. + */ + + +/* NOTE: some functions (some internal variants and exported ones) + * invalidate data portions of the TypeNodes. if external functions/callbacks + * are called, pointers to memory maintained by TypeNodes have to be looked up + * again. this affects most of the struct TypeNode fields, e.g. ->children or + * CLASSED_NODE_IFACES_ENTRIES() respectively IFACE_NODE_PREREQUISITES() (but + * not ->supers[]), as all those memory portions can get realloc()ed during + * callback invocation. + * + * LOCKING: + * lock handling issues when calling static functions are indicated by + * uppercase letter postfixes, all static functions have to have + * one of the below postfixes: + * - _I: [Indifferent about locking] + * function doesn't care about locks at all + * - _U: [Unlocked invocation] + * no read or write lock has to be held across function invocation + * (locks may be acquired and released during invocation though) + * - _L: [Locked invocation] + * a write lock or more than 0 read locks have to be held across + * function invocation + * - _W: [Write-locked invocation] + * a write lock has to be held across function invocation + * - _Wm: [Write-locked invocation, mutatable] + * like _W, but the write lock might be released and reacquired + * during invocation, watch your pointers + * - _WmREC: [Write-locked invocation, mutatable, recursive] + * like _Wm, but also acquires recursive mutex class_init_rec_mutex + */ + +#ifdef LOCK_DEBUG +#define G_READ_LOCK(rw_lock) do { g_printerr (G_STRLOC ": readL++\n"); g_rw_lock_reader_lock (rw_lock); } while (0) +#define G_READ_UNLOCK(rw_lock) do { g_printerr (G_STRLOC ": readL--\n"); g_rw_lock_reader_unlock (rw_lock); } while (0) +#define G_WRITE_LOCK(rw_lock) do { g_printerr (G_STRLOC ": writeL++\n"); g_rw_lock_writer_lock (rw_lock); } while (0) +#define G_WRITE_UNLOCK(rw_lock) do { g_printerr (G_STRLOC ": writeL--\n"); g_rw_lock_writer_unlock (rw_lock); } while (0) +#else +#define G_READ_LOCK(rw_lock) g_rw_lock_reader_lock (rw_lock) +#define G_READ_UNLOCK(rw_lock) g_rw_lock_reader_unlock (rw_lock) +#define G_WRITE_LOCK(rw_lock) g_rw_lock_writer_lock (rw_lock) +#define G_WRITE_UNLOCK(rw_lock) g_rw_lock_writer_unlock (rw_lock) +#endif +#define INVALID_RECURSION(func, arg, type_name) G_STMT_START{ \ + static const gchar _action[] = " invalidly modified type "; \ + gpointer _arg = (gpointer) (arg); const gchar *_tname = (type_name), *_fname = (func); \ + if (_arg) \ + g_error ("%s(%p)%s'%s'", _fname, _arg, _action, _tname); \ + else \ + g_error ("%s()%s'%s'", _fname, _action, _tname); \ +}G_STMT_END +#define g_assert_type_system_initialized() \ + g_assert (static_quark_type_flags) + +#define TYPE_FUNDAMENTAL_FLAG_MASK (G_TYPE_FLAG_CLASSED | \ + G_TYPE_FLAG_INSTANTIATABLE | \ + G_TYPE_FLAG_DERIVABLE | \ + G_TYPE_FLAG_DEEP_DERIVABLE) +#define TYPE_FLAG_MASK (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_FINAL) +#define SIZEOF_FUNDAMENTAL_INFO ((gssize) MAX (MAX (sizeof (GTypeFundamentalInfo), \ + sizeof (gpointer)), \ + sizeof (glong))) + +/* The 2*sizeof(size_t) alignment here is borrowed from + * GNU libc, so it should be good most everywhere. + * It is more conservative than is needed on some 64-bit + * platforms, but ia64 does require a 16-byte alignment. + * The SIMD extensions for x86 and ppc32 would want a + * larger alignment than this, but we don't need to + * do better than malloc. + */ +#define STRUCT_ALIGNMENT (2 * sizeof (gsize)) +#define ALIGN_STRUCT(offset) \ + ((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT) + + +/* --- typedefs --- */ +typedef struct _TypeNode TypeNode; +typedef struct _CommonData CommonData; +typedef struct _BoxedData BoxedData; +typedef struct _IFaceData IFaceData; +typedef struct _ClassData ClassData; +typedef struct _InstanceData InstanceData; +typedef union _TypeData TypeData; +typedef struct _IFaceEntries IFaceEntries; +typedef struct _IFaceEntry IFaceEntry; +typedef struct _IFaceHolder IFaceHolder; + + +/* --- prototypes --- */ +static inline GTypeFundamentalInfo* type_node_fundamental_info_I (TypeNode *node); +static void type_add_flags_W (TypeNode *node, + GTypeFlags flags); +static void type_data_make_W (TypeNode *node, + const GTypeInfo *info, + const GTypeValueTable *value_table); +static inline void type_data_ref_Wm (TypeNode *node); +static inline void type_data_unref_U (TypeNode *node, + gboolean uncached); +static void type_data_last_unref_Wm (TypeNode * node, + gboolean uncached); +static inline gpointer type_get_qdata_L (TypeNode *node, + GQuark quark); +static inline void type_set_qdata_W (TypeNode *node, + GQuark quark, + gpointer data); +static IFaceHolder* type_iface_peek_holder_L (TypeNode *iface, + GType instance_type); +static gboolean type_iface_vtable_base_init_Wm (TypeNode *iface, + TypeNode *node); +static void type_iface_vtable_iface_init_Wm (TypeNode *iface, + TypeNode *node); +static gboolean type_node_is_a_L (TypeNode *node, + TypeNode *iface_node); + + +/* --- enumeration --- */ + +/* The InitState enumeration is used to track the progress of initializing + * both classes and interface vtables. Keeping the state of initialization + * is necessary to handle new interfaces being added while we are initializing + * the class or other interfaces. + */ +typedef enum +{ + UNINITIALIZED, + BASE_CLASS_INIT, + BASE_IFACE_INIT, + CLASS_INIT, + IFACE_INIT, + INITIALIZED +} InitState; + +/* --- structures --- */ +struct _TypeNode +{ + guint ref_count; /* (atomic) */ +#ifdef G_ENABLE_DEBUG + guint instance_count; /* (atomic) */ +#endif + GTypePlugin *plugin; + guint n_children; /* writable with lock */ + guint n_supers : 8; + guint n_prerequisites : 9; + guint is_classed : 1; + guint is_instantiatable : 1; + guint mutatable_check_cache : 1; /* combines some common path checks */ + GType *children; /* writable with lock */ + TypeData *data; + GQuark qname; + GData *global_gdata; + union { + GAtomicArray iface_entries; /* for !iface types */ + GAtomicArray offsets; + } _prot; + GType *prerequisites; + GType supers[1]; /* flexible array */ +}; + +#define SIZEOF_BASE_TYPE_NODE() (G_STRUCT_OFFSET (TypeNode, supers)) +#define MAX_N_SUPERS (255) +#define MAX_N_CHILDREN (G_MAXUINT) +#define MAX_N_INTERFACES (255) /* Limited by offsets being 8 bits */ +#define MAX_N_PREREQUISITES (511) +#define NODE_TYPE(node) (node->supers[0]) +#define NODE_PARENT_TYPE(node) (node->supers[1]) +#define NODE_FUNDAMENTAL_TYPE(node) (node->supers[node->n_supers]) +#define NODE_NAME(node) (g_quark_to_string (node->qname)) +#define NODE_REFCOUNT(node) ((guint) g_atomic_int_get ((int *) &(node)->ref_count)) +#define NODE_IS_BOXED(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_BOXED) +#define NODE_IS_IFACE(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_INTERFACE) +#define CLASSED_NODE_IFACES_ENTRIES(node) (&(node)->_prot.iface_entries) +#define CLASSED_NODE_IFACES_ENTRIES_LOCKED(node)(G_ATOMIC_ARRAY_GET_LOCKED(CLASSED_NODE_IFACES_ENTRIES((node)), IFaceEntries)) +#define IFACE_NODE_N_PREREQUISITES(node) ((node)->n_prerequisites) +#define IFACE_NODE_PREREQUISITES(node) ((node)->prerequisites) +#define iface_node_get_holders_L(node) ((IFaceHolder*) type_get_qdata_L ((node), static_quark_iface_holder)) +#define iface_node_set_holders_W(node, holders) (type_set_qdata_W ((node), static_quark_iface_holder, (holders))) +#define iface_node_get_dependants_array_L(n) ((GType*) type_get_qdata_L ((n), static_quark_dependants_array)) +#define iface_node_set_dependants_array_W(n,d) (type_set_qdata_W ((n), static_quark_dependants_array, (d))) +#define TYPE_ID_MASK ((GType) ((1 << G_TYPE_FUNDAMENTAL_SHIFT) - 1)) + +#define NODE_IS_ANCESTOR(ancestor, node) \ + ((ancestor)->n_supers <= (node)->n_supers && \ + (node)->supers[(node)->n_supers - (ancestor)->n_supers] == NODE_TYPE (ancestor)) + +struct _IFaceHolder +{ + GType instance_type; + GInterfaceInfo *info; + GTypePlugin *plugin; + IFaceHolder *next; +}; + +struct _IFaceEntry +{ + GType iface_type; + GTypeInterface *vtable; + InitState init_state; +}; + +struct _IFaceEntries { + gsize offset_index; + IFaceEntry entry[1]; +}; + +#define IFACE_ENTRIES_HEADER_SIZE (sizeof(IFaceEntries) - sizeof(IFaceEntry)) +#define IFACE_ENTRIES_N_ENTRIES(_entries) ( (G_ATOMIC_ARRAY_DATA_SIZE((_entries)) - IFACE_ENTRIES_HEADER_SIZE) / sizeof(IFaceEntry) ) + +struct _CommonData +{ + GTypeValueTable *value_table; +}; + +struct _BoxedData +{ + CommonData data; + GBoxedCopyFunc copy_func; + GBoxedFreeFunc free_func; +}; + +struct _IFaceData +{ + CommonData common; + guint16 vtable_size; + GBaseInitFunc vtable_init_base; + GBaseFinalizeFunc vtable_finalize_base; + GClassInitFunc dflt_init; + GClassFinalizeFunc dflt_finalize; + gconstpointer dflt_data; + gpointer dflt_vtable; +}; + +struct _ClassData +{ + CommonData common; + guint16 class_size; + guint16 class_private_size; + int init_state; /* (atomic) - g_type_class_ref reads it unlocked */ + GBaseInitFunc class_init_base; + GBaseFinalizeFunc class_finalize_base; + GClassInitFunc class_init; + GClassFinalizeFunc class_finalize; + gconstpointer class_data; + gpointer class; +}; + +struct _InstanceData +{ + CommonData common; + guint16 class_size; + guint16 class_private_size; + int init_state; /* (atomic) - g_type_class_ref reads it unlocked */ + GBaseInitFunc class_init_base; + GBaseFinalizeFunc class_finalize_base; + GClassInitFunc class_init; + GClassFinalizeFunc class_finalize; + gconstpointer class_data; + gpointer class; + guint16 instance_size; + guint16 private_size; + guint16 n_preallocs; + GInstanceInitFunc instance_init; +}; + +union _TypeData +{ + CommonData common; + BoxedData boxed; + IFaceData iface; + ClassData class; + InstanceData instance; +}; + +typedef struct { + gpointer cache_data; + GTypeClassCacheFunc cache_func; +} ClassCacheFunc; + +typedef struct { + gpointer check_data; + GTypeInterfaceCheckFunc check_func; +} IFaceCheckFunc; + + +/* --- variables --- */ +static GRWLock type_rw_lock; +static GRecMutex class_init_rec_mutex; +static guint static_n_class_cache_funcs = 0; +static ClassCacheFunc *static_class_cache_funcs = NULL; +static guint static_n_iface_check_funcs = 0; +static IFaceCheckFunc *static_iface_check_funcs = NULL; +static GQuark static_quark_type_flags = 0; +static GQuark static_quark_iface_holder = 0; +static GQuark static_quark_dependants_array = 0; +static guint type_registration_serial = 0; + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GTypeDebugFlags _g_type_debug_flags = 0; +G_GNUC_END_IGNORE_DEPRECATIONS + +/* --- type nodes --- */ +static GHashTable *static_type_nodes_ht = NULL; +static TypeNode *static_fundamental_type_nodes[(G_TYPE_FUNDAMENTAL_MAX >> G_TYPE_FUNDAMENTAL_SHIFT) + 1] = { NULL, }; +static GType static_fundamental_next = G_TYPE_RESERVED_USER_FIRST; + +static inline TypeNode* +lookup_type_node_I (GType utype) +{ + if (utype > G_TYPE_FUNDAMENTAL_MAX) + return (TypeNode*) (utype & ~TYPE_ID_MASK); + else + return static_fundamental_type_nodes[utype >> G_TYPE_FUNDAMENTAL_SHIFT]; +} + +/** + * g_type_get_type_registration_serial: + * + * Returns an opaque serial number that represents the state of the set + * of registered types. Any time a type is registered this serial changes, + * which means you can cache information based on type lookups (such as + * g_type_from_name()) and know if the cache is still valid at a later + * time by comparing the current serial with the one at the type lookup. + * + * Since: 2.36 + * + * Returns: An unsigned int, representing the state of type registrations + */ +guint +g_type_get_type_registration_serial (void) +{ + return (guint)g_atomic_int_get ((gint *)&type_registration_serial); +} + +static TypeNode* +type_node_any_new_W (TypeNode *pnode, + GType ftype, + const gchar *name, + GTypePlugin *plugin, + GTypeFundamentalFlags type_flags) +{ + guint n_supers; + GType type; + TypeNode *node; + guint i, node_size = 0; + + n_supers = pnode ? pnode->n_supers + 1 : 0; + + if (!pnode) + node_size += SIZEOF_FUNDAMENTAL_INFO; /* fundamental type info */ + node_size += SIZEOF_BASE_TYPE_NODE (); /* TypeNode structure */ + node_size += (sizeof (GType) * (1 + n_supers + 1)); /* self + ancestors + (0) for ->supers[] */ + node = g_malloc0 (node_size); + if (!pnode) /* offset fundamental types */ + { + node = G_STRUCT_MEMBER_P (node, SIZEOF_FUNDAMENTAL_INFO); + static_fundamental_type_nodes[ftype >> G_TYPE_FUNDAMENTAL_SHIFT] = node; + type = ftype; + +#if ENABLE_VALGRIND + VALGRIND_MALLOCLIKE_BLOCK (node, node_size - SIZEOF_FUNDAMENTAL_INFO, FALSE, TRUE); +#endif + } + else + type = (GType) node; + + g_assert ((type & TYPE_ID_MASK) == 0); + + node->n_supers = n_supers; + if (!pnode) + { + node->supers[0] = type; + node->supers[1] = 0; + + node->is_classed = (type_flags & G_TYPE_FLAG_CLASSED) != 0; + node->is_instantiatable = (type_flags & G_TYPE_FLAG_INSTANTIATABLE) != 0; + + if (NODE_IS_IFACE (node)) + { + IFACE_NODE_N_PREREQUISITES (node) = 0; + IFACE_NODE_PREREQUISITES (node) = NULL; + } + else + _g_atomic_array_init (CLASSED_NODE_IFACES_ENTRIES (node)); + } + else + { + node->supers[0] = type; + memcpy (node->supers + 1, pnode->supers, sizeof (GType) * (1 + pnode->n_supers + 1)); + + node->is_classed = pnode->is_classed; + node->is_instantiatable = pnode->is_instantiatable; + + if (NODE_IS_IFACE (node)) + { + IFACE_NODE_N_PREREQUISITES (node) = 0; + IFACE_NODE_PREREQUISITES (node) = NULL; + } + else + { + guint j; + IFaceEntries *entries; + + entries = _g_atomic_array_copy (CLASSED_NODE_IFACES_ENTRIES (pnode), + IFACE_ENTRIES_HEADER_SIZE, + 0); + if (entries) + { + for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (entries); j++) + { + entries->entry[j].vtable = NULL; + entries->entry[j].init_state = UNINITIALIZED; + } + _g_atomic_array_update (CLASSED_NODE_IFACES_ENTRIES (node), + entries); + } + } + + i = pnode->n_children++; + pnode->children = g_renew (GType, pnode->children, pnode->n_children); + pnode->children[i] = type; + } + + TRACE(GOBJECT_TYPE_NEW(name, node->supers[1], type)); + + node->plugin = plugin; + node->n_children = 0; + node->children = NULL; + node->data = NULL; + node->qname = g_quark_from_string (name); + node->global_gdata = NULL; + g_hash_table_insert (static_type_nodes_ht, + (gpointer) g_quark_to_string (node->qname), + (gpointer) type); + + g_atomic_int_inc ((gint *)&type_registration_serial); + + return node; +} + +static inline GTypeFundamentalInfo* +type_node_fundamental_info_I (TypeNode *node) +{ + GType ftype = NODE_FUNDAMENTAL_TYPE (node); + + if (ftype != NODE_TYPE (node)) + node = lookup_type_node_I (ftype); + + return node ? G_STRUCT_MEMBER_P (node, -SIZEOF_FUNDAMENTAL_INFO) : NULL; +} + +static TypeNode* +type_node_fundamental_new_W (GType ftype, + const gchar *name, + GTypeFundamentalFlags type_flags) +{ + GTypeFundamentalInfo *finfo; + TypeNode *node; + + g_assert ((ftype & TYPE_ID_MASK) == 0); + g_assert (ftype <= G_TYPE_FUNDAMENTAL_MAX); + + if (ftype >> G_TYPE_FUNDAMENTAL_SHIFT == static_fundamental_next) + static_fundamental_next++; + + type_flags &= TYPE_FUNDAMENTAL_FLAG_MASK; + + node = type_node_any_new_W (NULL, ftype, name, NULL, type_flags); + + finfo = type_node_fundamental_info_I (node); + finfo->type_flags = type_flags; + + return node; +} + +static TypeNode* +type_node_new_W (TypeNode *pnode, + const gchar *name, + GTypePlugin *plugin) + +{ + g_assert (pnode); + g_assert (pnode->n_supers < MAX_N_SUPERS); + g_assert (pnode->n_children < MAX_N_CHILDREN); + + return type_node_any_new_W (pnode, NODE_FUNDAMENTAL_TYPE (pnode), name, plugin, 0); +} + +static inline IFaceEntry* +lookup_iface_entry_I (IFaceEntries *entries, + TypeNode *iface_node) +{ + guint8 *offsets; + gsize offset_index; + IFaceEntry *check; + gsize index; + IFaceEntry *entry; + + if (entries == NULL) + return NULL; + + G_ATOMIC_ARRAY_DO_TRANSACTION + (&iface_node->_prot.offsets, guint8, + + entry = NULL; + offsets = transaction_data; + offset_index = entries->offset_index; + if (offsets != NULL && + offset_index < G_ATOMIC_ARRAY_DATA_SIZE(offsets)) + { + index = offsets[offset_index]; + if (index > 0) + { + /* zero means unset, subtract one to get real index */ + index -= 1; + + if (index < IFACE_ENTRIES_N_ENTRIES (entries)) + { + check = (IFaceEntry *)&entries->entry[index]; + if (check->iface_type == NODE_TYPE (iface_node)) + entry = check; + } + } + } + ); + + return entry; +} + +static inline IFaceEntry* +type_lookup_iface_entry_L (TypeNode *node, + TypeNode *iface_node) +{ + if (!NODE_IS_IFACE (iface_node)) + return NULL; + + return lookup_iface_entry_I (CLASSED_NODE_IFACES_ENTRIES_LOCKED (node), + iface_node); +} + + +static inline gboolean +type_lookup_iface_vtable_I (TypeNode *node, + TypeNode *iface_node, + gpointer *vtable_ptr) +{ + IFaceEntry *entry; + gboolean res; + + if (!NODE_IS_IFACE (iface_node)) + { + if (vtable_ptr) + *vtable_ptr = NULL; + return FALSE; + } + + G_ATOMIC_ARRAY_DO_TRANSACTION + (CLASSED_NODE_IFACES_ENTRIES (node), IFaceEntries, + + entry = lookup_iface_entry_I (transaction_data, iface_node); + res = entry != NULL; + if (vtable_ptr) + { + if (entry) + *vtable_ptr = entry->vtable; + else + *vtable_ptr = NULL; + } + ); + + return res; +} + +static inline gboolean +type_lookup_prerequisite_L (TypeNode *iface, + GType prerequisite_type) +{ + if (NODE_IS_IFACE (iface) && IFACE_NODE_N_PREREQUISITES (iface)) + { + GType *prerequisites = IFACE_NODE_PREREQUISITES (iface) - 1; + guint n_prerequisites = IFACE_NODE_N_PREREQUISITES (iface); + + do + { + guint i; + GType *check; + + i = (n_prerequisites + 1) >> 1; + check = prerequisites + i; + if (prerequisite_type == *check) + return TRUE; + else if (prerequisite_type > *check) + { + n_prerequisites -= i; + prerequisites = check; + } + else /* if (prerequisite_type < *check) */ + n_prerequisites = i - 1; + } + while (n_prerequisites); + } + return FALSE; +} + +static const gchar* +type_descriptive_name_I (GType type) +{ + if (type) + { + TypeNode *node = lookup_type_node_I (type); + + return node ? NODE_NAME (node) : ""; + } + else + return ""; +} + + +/* --- type consistency checks --- */ +static gboolean +check_plugin_U (GTypePlugin *plugin, + gboolean need_complete_type_info, + gboolean need_complete_interface_info, + const gchar *type_name) +{ + /* G_IS_TYPE_PLUGIN() and G_TYPE_PLUGIN_GET_CLASS() are external calls: _U + */ + if (!plugin) + { + g_warning ("plugin handle for type '%s' is NULL", + type_name); + return FALSE; + } + if (!G_IS_TYPE_PLUGIN (plugin)) + { + g_warning ("plugin pointer (%p) for type '%s' is invalid", + plugin, type_name); + return FALSE; + } + if (need_complete_type_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_type_info) + { + g_warning ("plugin for type '%s' has no complete_type_info() implementation", + type_name); + return FALSE; + } + if (need_complete_interface_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_interface_info) + { + g_warning ("plugin for type '%s' has no complete_interface_info() implementation", + type_name); + return FALSE; + } + return TRUE; +} + +static gboolean +check_type_name_I (const gchar *type_name) +{ + static const gchar extra_chars[] = "-_+"; + const gchar *p = type_name; + gboolean name_valid; + + if (!type_name[0] || !type_name[1] || !type_name[2]) + { + g_warning ("type name '%s' is too short", type_name); + return FALSE; + } + /* check the first letter */ + name_valid = (p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z') || p[0] == '_'; + for (p = type_name + 1; *p; p++) + name_valid &= ((p[0] >= 'A' && p[0] <= 'Z') || + (p[0] >= 'a' && p[0] <= 'z') || + (p[0] >= '0' && p[0] <= '9') || + strchr (extra_chars, p[0])); + if (!name_valid) + { + g_warning ("type name '%s' contains invalid characters", type_name); + return FALSE; + } + if (g_type_from_name (type_name)) + { + g_warning ("cannot register existing type '%s'", type_name); + return FALSE; + } + + return TRUE; +} + +static gboolean +check_derivation_I (GType parent_type, + const gchar *type_name) +{ + TypeNode *pnode; + GTypeFundamentalInfo* finfo; + + pnode = lookup_type_node_I (parent_type); + if (!pnode) + { + g_warning ("cannot derive type '%s' from invalid parent type '%s'", + type_name, + type_descriptive_name_I (parent_type)); + return FALSE; + } + finfo = type_node_fundamental_info_I (pnode); + /* ensure flat derivability */ + if (!(finfo->type_flags & G_TYPE_FLAG_DERIVABLE)) + { + g_warning ("cannot derive '%s' from non-derivable parent type '%s'", + type_name, + NODE_NAME (pnode)); + return FALSE; + } + /* ensure deep derivability */ + if (parent_type != NODE_FUNDAMENTAL_TYPE (pnode) && + !(finfo->type_flags & G_TYPE_FLAG_DEEP_DERIVABLE)) + { + g_warning ("cannot derive '%s' from non-fundamental parent type '%s'", + type_name, + NODE_NAME (pnode)); + return FALSE; + } + if ((G_TYPE_FLAG_FINAL & GPOINTER_TO_UINT (type_get_qdata_L (pnode, static_quark_type_flags))) == G_TYPE_FLAG_FINAL) + { + g_warning ("cannot derive '%s' from final parent type '%s'", + type_name, + NODE_NAME (pnode)); + return FALSE; + } + + return TRUE; +} + +static gboolean +check_collect_format_I (const gchar *collect_format) +{ + const gchar *p = collect_format; + gchar valid_format[] = { G_VALUE_COLLECT_INT, G_VALUE_COLLECT_LONG, + G_VALUE_COLLECT_INT64, G_VALUE_COLLECT_DOUBLE, + G_VALUE_COLLECT_POINTER, 0 }; + + while (*p) + if (!strchr (valid_format, *p++)) + return FALSE; + return p - collect_format <= G_VALUE_COLLECT_FORMAT_MAX_LENGTH; +} + +static gboolean +check_value_table_I (const gchar *type_name, + const GTypeValueTable *value_table) +{ + if (!value_table) + return FALSE; + else if (value_table->value_init == NULL) + { + if (value_table->value_free || value_table->value_copy || + value_table->value_peek_pointer || + value_table->collect_format || value_table->collect_value || + value_table->lcopy_format || value_table->lcopy_value) + g_warning ("cannot handle uninitializable values of type '%s'", + type_name); + return FALSE; + } + else /* value_table->value_init != NULL */ + { + if (!value_table->value_free) + { + /* +++ optional +++ + * g_warning ("missing 'value_free()' for type '%s'", type_name); + * return FALSE; + */ + } + if (!value_table->value_copy) + { + g_warning ("missing 'value_copy()' for type '%s'", type_name); + return FALSE; + } + if ((value_table->collect_format || value_table->collect_value) && + (!value_table->collect_format || !value_table->collect_value)) + { + g_warning ("one of 'collect_format' and 'collect_value()' is unspecified for type '%s'", + type_name); + return FALSE; + } + if (value_table->collect_format && !check_collect_format_I (value_table->collect_format)) + { + g_warning ("the '%s' specification for type '%s' is too long or invalid", + "collect_format", + type_name); + return FALSE; + } + if ((value_table->lcopy_format || value_table->lcopy_value) && + (!value_table->lcopy_format || !value_table->lcopy_value)) + { + g_warning ("one of 'lcopy_format' and 'lcopy_value()' is unspecified for type '%s'", + type_name); + return FALSE; + } + if (value_table->lcopy_format && !check_collect_format_I (value_table->lcopy_format)) + { + g_warning ("the '%s' specification for type '%s' is too long or invalid", + "lcopy_format", + type_name); + return FALSE; + } + } + return TRUE; +} + +static gboolean +check_type_info_I (TypeNode *pnode, + GType ftype, + const gchar *type_name, + const GTypeInfo *info) +{ + GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (lookup_type_node_I (ftype)); + gboolean is_interface = ftype == G_TYPE_INTERFACE; + + g_assert (ftype <= G_TYPE_FUNDAMENTAL_MAX && !(ftype & TYPE_ID_MASK)); + + /* check instance members */ + if (!(finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) && + (info->instance_size || info->n_preallocs || info->instance_init)) + { + if (pnode) + g_warning ("cannot instantiate '%s', derived from non-instantiatable parent type '%s'", + type_name, + NODE_NAME (pnode)); + else + g_warning ("cannot instantiate '%s' as non-instantiatable fundamental", + type_name); + return FALSE; + } + /* check class & interface members */ + if (!((finfo->type_flags & G_TYPE_FLAG_CLASSED) || is_interface) && + (info->class_init || info->class_finalize || info->class_data || + info->class_size || info->base_init || info->base_finalize)) + { + if (pnode) + g_warning ("cannot create class for '%s', derived from non-classed parent type '%s'", + type_name, + NODE_NAME (pnode)); + else + g_warning ("cannot create class for '%s' as non-classed fundamental", + type_name); + return FALSE; + } + /* check interface size */ + if (is_interface && info->class_size < sizeof (GTypeInterface)) + { + g_warning ("specified interface size for type '%s' is smaller than 'GTypeInterface' size", + type_name); + return FALSE; + } + /* check class size */ + if (finfo->type_flags & G_TYPE_FLAG_CLASSED) + { + if (info->class_size < sizeof (GTypeClass)) + { + g_warning ("specified class size for type '%s' is smaller than 'GTypeClass' size", + type_name); + return FALSE; + } + if (pnode && info->class_size < pnode->data->class.class_size) + { + g_warning ("specified class size for type '%s' is smaller " + "than the parent type's '%s' class size", + type_name, + NODE_NAME (pnode)); + return FALSE; + } + } + /* check instance size */ + if (finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) + { + if (info->instance_size < sizeof (GTypeInstance)) + { + g_warning ("specified instance size for type '%s' is smaller than 'GTypeInstance' size", + type_name); + return FALSE; + } + if (pnode && info->instance_size < pnode->data->instance.instance_size) + { + g_warning ("specified instance size for type '%s' is smaller " + "than the parent type's '%s' instance size", + type_name, + NODE_NAME (pnode)); + return FALSE; + } + } + + return TRUE; +} + +static TypeNode* +find_conforming_child_type_L (TypeNode *pnode, + TypeNode *iface) +{ + TypeNode *node = NULL; + guint i; + + if (type_lookup_iface_entry_L (pnode, iface)) + return pnode; + + for (i = 0; i < pnode->n_children && !node; i++) + node = find_conforming_child_type_L (lookup_type_node_I (pnode->children[i]), iface); + + return node; +} + +static gboolean +check_add_interface_L (GType instance_type, + GType iface_type) +{ + TypeNode *node = lookup_type_node_I (instance_type); + TypeNode *iface = lookup_type_node_I (iface_type); + IFaceEntry *entry; + TypeNode *tnode; + GType *prerequisites; + guint i; + + + if (!node || !node->is_instantiatable) + { + g_warning ("cannot add interfaces to invalid (non-instantiatable) type '%s'", + type_descriptive_name_I (instance_type)); + return FALSE; + } + if (!iface || !NODE_IS_IFACE (iface)) + { + g_warning ("cannot add invalid (non-interface) type '%s' to type '%s'", + type_descriptive_name_I (iface_type), + NODE_NAME (node)); + return FALSE; + } + if (node->data && node->data->class.class) + { + g_warning ("attempting to add an interface (%s) to class (%s) after class_init", + NODE_NAME (iface), NODE_NAME (node)); + return FALSE; + } + tnode = lookup_type_node_I (NODE_PARENT_TYPE (iface)); + if (NODE_PARENT_TYPE (tnode) && !type_lookup_iface_entry_L (node, tnode)) + { + /* 2001/7/31:timj: erk, i guess this warning is junk as interface derivation is flat */ + g_warning ("cannot add sub-interface '%s' to type '%s' which does not conform to super-interface '%s'", + NODE_NAME (iface), + NODE_NAME (node), + NODE_NAME (tnode)); + return FALSE; + } + /* allow overriding of interface type introduced for parent type */ + entry = type_lookup_iface_entry_L (node, iface); + if (entry && entry->vtable == NULL && !type_iface_peek_holder_L (iface, NODE_TYPE (node))) + { + /* ok, we do conform to this interface already, but the interface vtable was not + * yet initialized, and we just conform to the interface because it got added to + * one of our parents. so we allow overriding of holder info here. + */ + return TRUE; + } + /* check whether one of our children already conforms (or whether the interface + * got added to this node already) + */ + tnode = find_conforming_child_type_L (node, iface); /* tnode is_a node */ + if (tnode) + { + g_warning ("cannot add interface type '%s' to type '%s', since type '%s' already conforms to interface", + NODE_NAME (iface), + NODE_NAME (node), + NODE_NAME (tnode)); + return FALSE; + } + prerequisites = IFACE_NODE_PREREQUISITES (iface); + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++) + { + tnode = lookup_type_node_I (prerequisites[i]); + if (!type_node_is_a_L (node, tnode)) + { + g_warning ("cannot add interface type '%s' to type '%s' which does not conform to prerequisite '%s'", + NODE_NAME (iface), + NODE_NAME (node), + NODE_NAME (tnode)); + return FALSE; + } + } + return TRUE; +} + +static gboolean +check_interface_info_I (TypeNode *iface, + GType instance_type, + const GInterfaceInfo *info) +{ + if ((info->interface_finalize || info->interface_data) && !info->interface_init) + { + g_warning ("interface type '%s' for type '%s' comes without initializer", + NODE_NAME (iface), + type_descriptive_name_I (instance_type)); + return FALSE; + } + + return TRUE; +} + +/* --- type info (type node data) --- */ +static void +type_data_make_W (TypeNode *node, + const GTypeInfo *info, + const GTypeValueTable *value_table) +{ + TypeData *data; + GTypeValueTable *vtable = NULL; + guint vtable_size = 0; + + g_assert (node->data == NULL && info != NULL); + + if (!value_table) + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + + if (pnode) + vtable = pnode->data->common.value_table; + else + { + static const GTypeValueTable zero_vtable = + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + + value_table = &zero_vtable; + } + } + if (value_table) + { + /* need to setup vtable_size since we have to allocate it with data in one chunk */ + vtable_size = sizeof (GTypeValueTable); + if (value_table->collect_format) + vtable_size += strlen (value_table->collect_format); + if (value_table->lcopy_format) + vtable_size += strlen (value_table->lcopy_format); + vtable_size += 2; + } + + if (node->is_instantiatable) /* careful, is_instantiatable is also is_classed */ + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + + data = g_malloc0 (sizeof (InstanceData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (InstanceData)); + data->instance.class_size = info->class_size; + data->instance.class_init_base = info->base_init; + data->instance.class_finalize_base = info->base_finalize; + data->instance.class_init = info->class_init; + data->instance.class_finalize = info->class_finalize; + data->instance.class_data = info->class_data; + data->instance.class = NULL; + data->instance.init_state = UNINITIALIZED; + data->instance.instance_size = info->instance_size; + /* We'll set the final value for data->instance.private size + * after the parent class has been initialized + */ + data->instance.private_size = 0; + data->instance.class_private_size = 0; + if (pnode) + data->instance.class_private_size = pnode->data->instance.class_private_size; + data->instance.n_preallocs = MIN (info->n_preallocs, 1024); + data->instance.instance_init = info->instance_init; + } + else if (node->is_classed) /* only classed */ + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + + data = g_malloc0 (sizeof (ClassData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (ClassData)); + data->class.class_size = info->class_size; + data->class.class_init_base = info->base_init; + data->class.class_finalize_base = info->base_finalize; + data->class.class_init = info->class_init; + data->class.class_finalize = info->class_finalize; + data->class.class_data = info->class_data; + data->class.class = NULL; + data->class.class_private_size = 0; + if (pnode) + data->class.class_private_size = pnode->data->class.class_private_size; + data->class.init_state = UNINITIALIZED; + } + else if (NODE_IS_IFACE (node)) + { + data = g_malloc0 (sizeof (IFaceData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (IFaceData)); + data->iface.vtable_size = info->class_size; + data->iface.vtable_init_base = info->base_init; + data->iface.vtable_finalize_base = info->base_finalize; + data->iface.dflt_init = info->class_init; + data->iface.dflt_finalize = info->class_finalize; + data->iface.dflt_data = info->class_data; + data->iface.dflt_vtable = NULL; + } + else if (NODE_IS_BOXED (node)) + { + data = g_malloc0 (sizeof (BoxedData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (BoxedData)); + } + else + { + data = g_malloc0 (sizeof (CommonData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (CommonData)); + } + + node->data = data; + + if (vtable_size) + { + gchar *p; + + /* we allocate the vtable and its strings together with the type data, so + * children can take over their parent's vtable pointer, and we don't + * need to worry freeing it or not when the child data is destroyed + */ + *vtable = *value_table; + p = G_STRUCT_MEMBER_P (vtable, sizeof (*vtable)); + p[0] = 0; + vtable->collect_format = p; + if (value_table->collect_format) + { + strcat (p, value_table->collect_format); + p += strlen (value_table->collect_format); + } + p++; + p[0] = 0; + vtable->lcopy_format = p; + if (value_table->lcopy_format) + strcat (p, value_table->lcopy_format); + } + node->data->common.value_table = vtable; + node->mutatable_check_cache = (node->data->common.value_table->value_init != NULL && + !((G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_ABSTRACT) & + GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags)))); + + g_assert (node->data->common.value_table != NULL); /* paranoid */ + + g_atomic_int_set ((int *) &node->ref_count, 1); +} + +static inline void +type_data_ref_Wm (TypeNode *node) +{ + if (!node->data) + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + GTypeInfo tmp_info; + GTypeValueTable tmp_value_table; + + g_assert (node->plugin != NULL); + + if (pnode) + { + type_data_ref_Wm (pnode); + if (node->data) + INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node)); + } + + memset (&tmp_info, 0, sizeof (tmp_info)); + memset (&tmp_value_table, 0, sizeof (tmp_value_table)); + + G_WRITE_UNLOCK (&type_rw_lock); + g_type_plugin_use (node->plugin); + g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmp_info, &tmp_value_table); + G_WRITE_LOCK (&type_rw_lock); + if (node->data) + INVALID_RECURSION ("g_type_plugin_*", node->plugin, NODE_NAME (node)); + + check_type_info_I (pnode, NODE_FUNDAMENTAL_TYPE (node), NODE_NAME (node), &tmp_info); + type_data_make_W (node, &tmp_info, + check_value_table_I (NODE_NAME (node), + &tmp_value_table) ? &tmp_value_table : NULL); + } + else + { + g_assert (NODE_REFCOUNT (node) > 0); + + g_atomic_int_inc ((int *) &node->ref_count); + } +} + +static inline gboolean +type_data_ref_U (TypeNode *node) +{ + guint current; + + do { + current = NODE_REFCOUNT (node); + + if (current < 1) + return FALSE; + } while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current + 1)); + + return TRUE; +} + +static gboolean +iface_node_has_available_offset_L (TypeNode *iface_node, + gsize offset, + int for_index) +{ + guint8 *offsets; + + offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->_prot.offsets, guint8); + if (offsets == NULL) + return TRUE; + + if (G_ATOMIC_ARRAY_DATA_SIZE (offsets) <= offset) + return TRUE; + + if (offsets[offset] == 0 || + offsets[offset] == for_index+1) + return TRUE; + + return FALSE; +} + +static gsize +find_free_iface_offset_L (IFaceEntries *entries) +{ + IFaceEntry *entry; + TypeNode *iface_node; + gsize offset; + int i; + int n_entries; + + n_entries = IFACE_ENTRIES_N_ENTRIES (entries); + offset = 0; + do + { + for (i = 0; i < n_entries; i++) + { + entry = &entries->entry[i]; + iface_node = lookup_type_node_I (entry->iface_type); + + if (!iface_node_has_available_offset_L (iface_node, offset, i)) + { + offset++; + break; + } + } + } + while (i != n_entries); + + return offset; +} + +static void +iface_node_set_offset_L (TypeNode *iface_node, + gsize offset, + int index) +{ + guint8 *offsets, *old_offsets; + gsize new_size, old_size; + gsize i; + + old_offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->_prot.offsets, guint8); + if (old_offsets == NULL) + old_size = 0; + else + { + old_size = G_ATOMIC_ARRAY_DATA_SIZE (old_offsets); + if (offset < old_size && + old_offsets[offset] == index + 1) + return; /* Already set to this index, return */ + } + new_size = MAX (old_size, offset + 1); + + offsets = _g_atomic_array_copy (&iface_node->_prot.offsets, + 0, new_size - old_size); + + /* Mark new area as unused */ + for (i = old_size; i < new_size; i++) + offsets[i] = 0; + + offsets[offset] = index + 1; + + _g_atomic_array_update (&iface_node->_prot.offsets, offsets); +} + +static void +type_node_add_iface_entry_W (TypeNode *node, + GType iface_type, + IFaceEntry *parent_entry) +{ + IFaceEntries *entries; + IFaceEntry *entry; + TypeNode *iface_node; + guint i, j; + guint num_entries; + + g_assert (node->is_instantiatable); + + entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node); + if (entries != NULL) + { + num_entries = IFACE_ENTRIES_N_ENTRIES (entries); + + g_assert (num_entries < MAX_N_INTERFACES); + + for (i = 0; i < num_entries; i++) + { + entry = &entries->entry[i]; + if (entry->iface_type == iface_type) + { + /* this can happen in two cases: + * - our parent type already conformed to iface_type and node + * got its own holder info. here, our children already have + * entries and NULL vtables, since this will only work for + * uninitialized classes. + * - an interface type is added to an ancestor after it was + * added to a child type. + */ + if (!parent_entry) + g_assert (entry->vtable == NULL && entry->init_state == UNINITIALIZED); + else + { + /* sick, interface is added to ancestor *after* child type; + * nothing todo, the entry and our children were already setup correctly + */ + } + return; + } + } + } + + entries = _g_atomic_array_copy (CLASSED_NODE_IFACES_ENTRIES (node), + IFACE_ENTRIES_HEADER_SIZE, + sizeof (IFaceEntry)); + num_entries = IFACE_ENTRIES_N_ENTRIES (entries); + i = num_entries - 1; + if (i == 0) + entries->offset_index = 0; + entries->entry[i].iface_type = iface_type; + entries->entry[i].vtable = NULL; + entries->entry[i].init_state = UNINITIALIZED; + + if (parent_entry) + { + if (node->data && g_atomic_int_get (&node->data->class.init_state) >= BASE_IFACE_INIT) + { + entries->entry[i].init_state = INITIALIZED; + entries->entry[i].vtable = parent_entry->vtable; + } + } + + /* Update offsets in iface */ + iface_node = lookup_type_node_I (iface_type); + + if (iface_node_has_available_offset_L (iface_node, + entries->offset_index, + i)) + { + iface_node_set_offset_L (iface_node, + entries->offset_index, i); + } + else + { + entries->offset_index = + find_free_iface_offset_L (entries); + for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (entries); j++) + { + entry = &entries->entry[j]; + iface_node = + lookup_type_node_I (entry->iface_type); + iface_node_set_offset_L (iface_node, + entries->offset_index, j); + } + } + + _g_atomic_array_update (CLASSED_NODE_IFACES_ENTRIES (node), entries); + + if (parent_entry) + { + for (i = 0; i < node->n_children; i++) + type_node_add_iface_entry_W (lookup_type_node_I (node->children[i]), iface_type, &entries->entry[i]); + } +} + +static void +type_add_interface_Wm (TypeNode *node, + TypeNode *iface, + const GInterfaceInfo *info, + GTypePlugin *plugin) +{ + IFaceHolder *iholder = g_new0 (IFaceHolder, 1); + IFaceEntry *entry; + guint i; + + g_assert (node->is_instantiatable && NODE_IS_IFACE (iface) && ((info && !plugin) || (!info && plugin))); + + iholder->next = iface_node_get_holders_L (iface); + iface_node_set_holders_W (iface, iholder); + iholder->instance_type = NODE_TYPE (node); + iholder->info = info ? g_memdup2 (info, sizeof (*info)) : NULL; + iholder->plugin = plugin; + + /* create an iface entry for this type */ + type_node_add_iface_entry_W (node, NODE_TYPE (iface), NULL); + + /* if the class is already (partly) initialized, we may need to base + * initialize and/or initialize the new interface. + */ + if (node->data) + { + InitState class_state = g_atomic_int_get (&node->data->class.init_state); + + if (class_state >= BASE_IFACE_INIT) + type_iface_vtable_base_init_Wm (iface, node); + + if (class_state >= IFACE_INIT) + type_iface_vtable_iface_init_Wm (iface, node); + } + + /* create iface entries for children of this type */ + entry = type_lookup_iface_entry_L (node, iface); + for (i = 0; i < node->n_children; i++) + type_node_add_iface_entry_W (lookup_type_node_I (node->children[i]), NODE_TYPE (iface), entry); +} + +static void +type_iface_add_prerequisite_W (TypeNode *iface, + TypeNode *prerequisite_node) +{ + GType prerequisite_type = NODE_TYPE (prerequisite_node); + GType *prerequisites, *dependants; + guint n_dependants, i; + + g_assert (NODE_IS_IFACE (iface) && + IFACE_NODE_N_PREREQUISITES (iface) < MAX_N_PREREQUISITES && + (prerequisite_node->is_instantiatable || NODE_IS_IFACE (prerequisite_node))); + + prerequisites = IFACE_NODE_PREREQUISITES (iface); + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++) + if (prerequisites[i] == prerequisite_type) + return; /* we already have that prerequisiste */ + else if (prerequisites[i] > prerequisite_type) + break; + IFACE_NODE_N_PREREQUISITES (iface) += 1; + IFACE_NODE_PREREQUISITES (iface) = g_renew (GType, + IFACE_NODE_PREREQUISITES (iface), + IFACE_NODE_N_PREREQUISITES (iface)); + prerequisites = IFACE_NODE_PREREQUISITES (iface); + memmove (prerequisites + i + 1, prerequisites + i, + sizeof (prerequisites[0]) * (IFACE_NODE_N_PREREQUISITES (iface) - i - 1)); + prerequisites[i] = prerequisite_type; + + /* we want to get notified when prerequisites get added to prerequisite_node */ + if (NODE_IS_IFACE (prerequisite_node)) + { + dependants = iface_node_get_dependants_array_L (prerequisite_node); + n_dependants = dependants ? dependants[0] : 0; + n_dependants += 1; + dependants = g_renew (GType, dependants, n_dependants + 1); + dependants[n_dependants] = NODE_TYPE (iface); + dependants[0] = n_dependants; + iface_node_set_dependants_array_W (prerequisite_node, dependants); + } + + /* we need to notify all dependants */ + dependants = iface_node_get_dependants_array_L (iface); + n_dependants = dependants ? dependants[0] : 0; + for (i = 1; i <= n_dependants; i++) + type_iface_add_prerequisite_W (lookup_type_node_I (dependants[i]), prerequisite_node); +} + +/** + * g_type_interface_add_prerequisite: + * @interface_type: #GType value of an interface type + * @prerequisite_type: #GType value of an interface or instantiatable type + * + * Adds @prerequisite_type to the list of prerequisites of @interface_type. + * This means that any type implementing @interface_type must also implement + * @prerequisite_type. Prerequisites can be thought of as an alternative to + * interface derivation (which GType doesn't support). An interface can have + * at most one instantiatable prerequisite type. + */ +void +g_type_interface_add_prerequisite (GType interface_type, + GType prerequisite_type) +{ + TypeNode *iface, *prerequisite_node; + IFaceHolder *holders; + + g_return_if_fail (G_TYPE_IS_INTERFACE (interface_type)); /* G_TYPE_IS_INTERFACE() is an external call: _U */ + g_return_if_fail (!g_type_is_a (interface_type, prerequisite_type)); + g_return_if_fail (!g_type_is_a (prerequisite_type, interface_type)); + + iface = lookup_type_node_I (interface_type); + prerequisite_node = lookup_type_node_I (prerequisite_type); + if (!iface || !prerequisite_node || !NODE_IS_IFACE (iface)) + { + g_warning ("interface type '%s' or prerequisite type '%s' invalid", + type_descriptive_name_I (interface_type), + type_descriptive_name_I (prerequisite_type)); + return; + } + G_WRITE_LOCK (&type_rw_lock); + holders = iface_node_get_holders_L (iface); + if (holders) + { + G_WRITE_UNLOCK (&type_rw_lock); + g_warning ("unable to add prerequisite '%s' to interface '%s' which is already in use for '%s'", + type_descriptive_name_I (prerequisite_type), + type_descriptive_name_I (interface_type), + type_descriptive_name_I (holders->instance_type)); + return; + } + if (prerequisite_node->is_instantiatable) + { + guint i; + + /* can have at most one publicly installable instantiatable prerequisite */ + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++) + { + TypeNode *prnode = lookup_type_node_I (IFACE_NODE_PREREQUISITES (iface)[i]); + + if (prnode->is_instantiatable) + { + G_WRITE_UNLOCK (&type_rw_lock); + g_warning ("adding prerequisite '%s' to interface '%s' conflicts with existing prerequisite '%s'", + type_descriptive_name_I (prerequisite_type), + type_descriptive_name_I (interface_type), + type_descriptive_name_I (NODE_TYPE (prnode))); + return; + } + } + + for (i = 0; i < prerequisite_node->n_supers + 1u; i++) + type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisite_node->supers[i])); + G_WRITE_UNLOCK (&type_rw_lock); + } + else if (NODE_IS_IFACE (prerequisite_node)) + { + GType *prerequisites; + guint i; + + prerequisites = IFACE_NODE_PREREQUISITES (prerequisite_node); + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (prerequisite_node); i++) + type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisites[i])); + type_iface_add_prerequisite_W (iface, prerequisite_node); + G_WRITE_UNLOCK (&type_rw_lock); + } + else + { + G_WRITE_UNLOCK (&type_rw_lock); + g_warning ("prerequisite '%s' for interface '%s' is neither instantiatable nor interface", + type_descriptive_name_I (prerequisite_type), + type_descriptive_name_I (interface_type)); + } +} + +/** + * g_type_interface_prerequisites: + * @interface_type: an interface type + * @n_prerequisites: (out) (optional): location to return the number + * of prerequisites, or %NULL + * + * Returns the prerequisites of an interfaces type. + * + * Since: 2.2 + * + * Returns: (array length=n_prerequisites) (transfer full): a + * newly-allocated zero-terminated array of #GType containing + * the prerequisites of @interface_type + */ +GType* +g_type_interface_prerequisites (GType interface_type, + guint *n_prerequisites) +{ + TypeNode *iface; + + g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL); + + iface = lookup_type_node_I (interface_type); + if (iface) + { + GType *types; + TypeNode *inode = NULL; + guint i, n = 0; + + G_READ_LOCK (&type_rw_lock); + types = g_new0 (GType, IFACE_NODE_N_PREREQUISITES (iface) + 1); + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++) + { + GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i]; + TypeNode *node = lookup_type_node_I (prerequisite); + if (node->is_instantiatable) + { + if (!inode || type_node_is_a_L (node, inode)) + inode = node; + } + else + types[n++] = NODE_TYPE (node); + } + if (inode) + types[n++] = NODE_TYPE (inode); + + if (n_prerequisites) + *n_prerequisites = n; + G_READ_UNLOCK (&type_rw_lock); + + return types; + } + else + { + if (n_prerequisites) + *n_prerequisites = 0; + + return NULL; + } +} + +/** + * g_type_interface_instantiatable_prerequisite: + * @interface_type: an interface type + * + * Returns the most specific instantiatable prerequisite of an + * interface type. If the interface type has no instantiatable + * prerequisite, %G_TYPE_INVALID is returned. + * + * See g_type_interface_add_prerequisite() for more information + * about prerequisites. + * + * Returns: the instantiatable prerequisite type or %G_TYPE_INVALID if none + * + * Since: 2.68 + **/ +GType +g_type_interface_instantiatable_prerequisite (GType interface_type) +{ + TypeNode *inode = NULL; + TypeNode *iface; + guint i; + + g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), G_TYPE_INVALID); + + iface = lookup_type_node_I (interface_type); + if (iface == NULL) + return G_TYPE_INVALID; + + G_READ_LOCK (&type_rw_lock); + + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++) + { + GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i]; + TypeNode *node = lookup_type_node_I (prerequisite); + if (node->is_instantiatable) + { + if (!inode || type_node_is_a_L (node, inode)) + inode = node; + } + } + + G_READ_UNLOCK (&type_rw_lock); + + if (inode) + return NODE_TYPE (inode); + else + return G_TYPE_INVALID; +} + +static IFaceHolder* +type_iface_peek_holder_L (TypeNode *iface, + GType instance_type) +{ + IFaceHolder *iholder; + + g_assert (NODE_IS_IFACE (iface)); + + iholder = iface_node_get_holders_L (iface); + while (iholder && iholder->instance_type != instance_type) + iholder = iholder->next; + return iholder; +} + +static IFaceHolder* +type_iface_retrieve_holder_info_Wm (TypeNode *iface, + GType instance_type, + gboolean need_info) +{ + IFaceHolder *iholder = type_iface_peek_holder_L (iface, instance_type); + + if (iholder && !iholder->info && need_info) + { + GInterfaceInfo tmp_info; + + g_assert (iholder->plugin != NULL); + + type_data_ref_Wm (iface); + if (iholder->info) + INVALID_RECURSION ("g_type_plugin_*", iface->plugin, NODE_NAME (iface)); + + memset (&tmp_info, 0, sizeof (tmp_info)); + + G_WRITE_UNLOCK (&type_rw_lock); + g_type_plugin_use (iholder->plugin); + g_type_plugin_complete_interface_info (iholder->plugin, instance_type, NODE_TYPE (iface), &tmp_info); + G_WRITE_LOCK (&type_rw_lock); + if (iholder->info) + INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface)); + + check_interface_info_I (iface, instance_type, &tmp_info); + iholder->info = g_memdup2 (&tmp_info, sizeof (tmp_info)); + } + + return iholder; /* we don't modify write lock upon returning NULL */ +} + +static void +type_iface_blow_holder_info_Wm (TypeNode *iface, + GType instance_type) +{ + IFaceHolder *iholder = iface_node_get_holders_L (iface); + + g_assert (NODE_IS_IFACE (iface)); + + while (iholder->instance_type != instance_type) + iholder = iholder->next; + + if (iholder->info && iholder->plugin) + { + g_free (iholder->info); + iholder->info = NULL; + + G_WRITE_UNLOCK (&type_rw_lock); + g_type_plugin_unuse (iholder->plugin); + type_data_unref_U (iface, FALSE); + G_WRITE_LOCK (&type_rw_lock); + } +} + +/** + * g_type_create_instance: (skip) + * @type: an instantiatable type to create an instance for + * + * Creates and initializes an instance of @type if @type is valid and + * can be instantiated. The type system only performs basic allocation + * and structure setups for instances: actual instance creation should + * happen through functions supplied by the type's fundamental type + * implementation. So use of g_type_create_instance() is reserved for + * implementers of fundamental types only. E.g. instances of the + * #GObject hierarchy should be created via g_object_new() and never + * directly through g_type_create_instance() which doesn't handle things + * like singleton objects or object construction. + * + * The extended members of the returned instance are guaranteed to be filled + * with zeros. + * + * Note: Do not use this function, unless you're implementing a + * fundamental type. Also language bindings should not use this + * function, but g_object_new() instead. + * + * Returns: an allocated and initialized instance, subject to further + * treatment by the fundamental type implementation + */ +GTypeInstance* +g_type_create_instance (GType type) +{ + TypeNode *node; + GTypeInstance *instance; + GTypeClass *class; + gchar *allocated; + gint private_size; + gint ivar_size; + guint i; + + node = lookup_type_node_I (type); + if (!node || !node->is_instantiatable) + { + g_error ("cannot create new instance of invalid (non-instantiatable) type '%s'", + type_descriptive_name_I (type)); + } + /* G_TYPE_IS_ABSTRACT() is an external call: _U */ + if (!node->mutatable_check_cache && G_TYPE_IS_ABSTRACT (type)) + { + g_error ("cannot create instance of abstract (non-instantiatable) type '%s'", + type_descriptive_name_I (type)); + } + + class = g_type_class_ref (type); + + /* We allocate the 'private' areas before the normal instance data, in + * reverse order. This allows the private area of a particular class + * to always be at a constant relative address to the instance data. + * If we stored the private data after the instance data this would + * not be the case (since a subclass that added more instance + * variables would push the private data further along). + * + * This presents problems for valgrindability, of course, so we do a + * workaround for that case. We identify the start of the object to + * valgrind as an allocated block (so that pointers to objects show up + * as 'reachable' instead of 'possibly lost'). We then add an extra + * pointer at the end of the object, after all instance data, back to + * the start of the private area so that it is also recorded as + * reachable. We also add extra private space at the start because + * valgrind doesn't seem to like us claiming to have allocated an + * address that it saw allocated by malloc(). + */ + private_size = node->data->instance.private_size; + ivar_size = node->data->instance.instance_size; + +#ifdef ENABLE_VALGRIND + if (private_size && RUNNING_ON_VALGRIND) + { + private_size += ALIGN_STRUCT (1); + + /* Allocate one extra pointer size... */ + allocated = g_slice_alloc0 (private_size + ivar_size + sizeof (gpointer)); + /* ... and point it back to the start of the private data. */ + *(gpointer *) (allocated + private_size + ivar_size) = allocated + ALIGN_STRUCT (1); + + /* Tell valgrind that it should treat the object itself as such */ + VALGRIND_MALLOCLIKE_BLOCK (allocated + private_size, ivar_size + sizeof (gpointer), 0, TRUE); + VALGRIND_MALLOCLIKE_BLOCK (allocated + ALIGN_STRUCT (1), private_size - ALIGN_STRUCT (1), 0, TRUE); + } + else +#endif + allocated = g_slice_alloc0 (private_size + ivar_size); + + instance = (GTypeInstance *) (allocated + private_size); + + for (i = node->n_supers; i > 0; i--) + { + TypeNode *pnode; + + pnode = lookup_type_node_I (node->supers[i]); + if (pnode->data->instance.instance_init) + { + instance->g_class = pnode->data->instance.class; + pnode->data->instance.instance_init (instance, class); + } + } + + instance->g_class = class; + if (node->data->instance.instance_init) + node->data->instance.instance_init (instance, class); + +#ifdef G_ENABLE_DEBUG + IF_DEBUG (INSTANCE_COUNT) + { + g_atomic_int_inc ((int *) &node->instance_count); + } +#endif + + TRACE(GOBJECT_OBJECT_NEW(instance, type)); + + return instance; +} + +/** + * g_type_free_instance: + * @instance: an instance of a type + * + * Frees an instance of a type, returning it to the instance pool for + * the type, if there is one. + * + * Like g_type_create_instance(), this function is reserved for + * implementors of fundamental types. + */ +void +g_type_free_instance (GTypeInstance *instance) +{ + TypeNode *node; + GTypeClass *class; + gchar *allocated; + gint private_size; + gint ivar_size; + + g_return_if_fail (instance != NULL && instance->g_class != NULL); + + class = instance->g_class; + node = lookup_type_node_I (class->g_type); + if (!node || !node->is_instantiatable || !node->data || node->data->class.class != (gpointer) class) + { + g_warning ("cannot free instance of invalid (non-instantiatable) type '%s'", + type_descriptive_name_I (class->g_type)); + return; + } + /* G_TYPE_IS_ABSTRACT() is an external call: _U */ + if (!node->mutatable_check_cache && G_TYPE_IS_ABSTRACT (NODE_TYPE (node))) + { + g_warning ("cannot free instance of abstract (non-instantiatable) type '%s'", + NODE_NAME (node)); + return; + } + + instance->g_class = NULL; + private_size = node->data->instance.private_size; + ivar_size = node->data->instance.instance_size; + allocated = ((gchar *) instance) - private_size; + +#ifdef G_ENABLE_DEBUG + memset (allocated, 0xaa, ivar_size + private_size); +#endif + +#ifdef ENABLE_VALGRIND + /* See comment in g_type_create_instance() about what's going on here. + * We're basically unwinding what we put into motion there. + */ + if (private_size && RUNNING_ON_VALGRIND) + { + private_size += ALIGN_STRUCT (1); + allocated -= ALIGN_STRUCT (1); + + /* Clear out the extra pointer... */ + *(gpointer *) (allocated + private_size + ivar_size) = NULL; + /* ... and ensure we include it in the size we free. */ + g_slice_free1 (private_size + ivar_size + sizeof (gpointer), allocated); + + VALGRIND_FREELIKE_BLOCK (allocated + ALIGN_STRUCT (1), 0); + VALGRIND_FREELIKE_BLOCK (instance, 0); + } + else +#endif + g_slice_free1 (private_size + ivar_size, allocated); + +#ifdef G_ENABLE_DEBUG + IF_DEBUG (INSTANCE_COUNT) + { + g_atomic_int_add ((int *) &node->instance_count, -1); + } +#endif + + g_type_class_unref (class); +} + +static void +type_iface_ensure_dflt_vtable_Wm (TypeNode *iface) +{ + g_assert (iface->data); + + if (!iface->data->iface.dflt_vtable) + { + GTypeInterface *vtable = g_malloc0 (iface->data->iface.vtable_size); + iface->data->iface.dflt_vtable = vtable; + vtable->g_type = NODE_TYPE (iface); + vtable->g_instance_type = 0; + if (iface->data->iface.vtable_init_base || + iface->data->iface.dflt_init) + { + G_WRITE_UNLOCK (&type_rw_lock); + if (iface->data->iface.vtable_init_base) + iface->data->iface.vtable_init_base (vtable); + if (iface->data->iface.dflt_init) + iface->data->iface.dflt_init (vtable, (gpointer) iface->data->iface.dflt_data); + G_WRITE_LOCK (&type_rw_lock); + } + } +} + + +/* This is called to allocate and do the first part of initializing + * the interface vtable; type_iface_vtable_iface_init_Wm() does the remainder. + * + * A FALSE return indicates that we didn't find an init function for + * this type/iface pair, so the vtable from the parent type should + * be used. Note that the write lock is not modified upon a FALSE + * return. + */ +static gboolean +type_iface_vtable_base_init_Wm (TypeNode *iface, + TypeNode *node) +{ + IFaceEntry *entry; + IFaceHolder *iholder; + GTypeInterface *vtable = NULL; + TypeNode *pnode; + + /* type_iface_retrieve_holder_info_Wm() doesn't modify write lock for returning NULL */ + iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), TRUE); + if (!iholder) + return FALSE; /* we don't modify write lock upon FALSE */ + + type_iface_ensure_dflt_vtable_Wm (iface); + + entry = type_lookup_iface_entry_L (node, iface); + + g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info); + + entry->init_state = IFACE_INIT; + + pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + if (pnode) /* want to copy over parent iface contents */ + { + IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface); + + if (pentry) + vtable = g_memdup2 (pentry->vtable, iface->data->iface.vtable_size); + } + if (!vtable) + vtable = g_memdup2 (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size); + entry->vtable = vtable; + vtable->g_type = NODE_TYPE (iface); + vtable->g_instance_type = NODE_TYPE (node); + + if (iface->data->iface.vtable_init_base) + { + G_WRITE_UNLOCK (&type_rw_lock); + iface->data->iface.vtable_init_base (vtable); + G_WRITE_LOCK (&type_rw_lock); + } + return TRUE; /* initialized the vtable */ +} + +/* Finishes what type_iface_vtable_base_init_Wm started by + * calling the interface init function. + * this function may only be called for types with their + * own interface holder info, i.e. types for which + * g_type_add_interface*() was called and not children thereof. + */ +static void +type_iface_vtable_iface_init_Wm (TypeNode *iface, + TypeNode *node) +{ + IFaceEntry *entry = type_lookup_iface_entry_L (node, iface); + IFaceHolder *iholder = type_iface_peek_holder_L (iface, NODE_TYPE (node)); + GTypeInterface *vtable = NULL; + guint i; + + /* iholder->info should have been filled in by type_iface_vtable_base_init_Wm() */ + g_assert (iface->data && entry && iholder && iholder->info); + g_assert (entry->init_state == IFACE_INIT); /* assert prior base_init() */ + + entry->init_state = INITIALIZED; + + vtable = entry->vtable; + + if (iholder->info->interface_init) + { + G_WRITE_UNLOCK (&type_rw_lock); + if (iholder->info->interface_init) + iholder->info->interface_init (vtable, iholder->info->interface_data); + G_WRITE_LOCK (&type_rw_lock); + } + + for (i = 0; i < static_n_iface_check_funcs; i++) + { + GTypeInterfaceCheckFunc check_func = static_iface_check_funcs[i].check_func; + gpointer check_data = static_iface_check_funcs[i].check_data; + + G_WRITE_UNLOCK (&type_rw_lock); + check_func (check_data, (gpointer)vtable); + G_WRITE_LOCK (&type_rw_lock); + } +} + +static gboolean +type_iface_vtable_finalize_Wm (TypeNode *iface, + TypeNode *node, + GTypeInterface *vtable) +{ + IFaceEntry *entry = type_lookup_iface_entry_L (node, iface); + IFaceHolder *iholder; + + /* type_iface_retrieve_holder_info_Wm() doesn't modify write lock for returning NULL */ + iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), FALSE); + if (!iholder) + return FALSE; /* we don't modify write lock upon FALSE */ + + g_assert (entry && entry->vtable == vtable && iholder->info); + + entry->vtable = NULL; + entry->init_state = UNINITIALIZED; + if (iholder->info->interface_finalize || iface->data->iface.vtable_finalize_base) + { + G_WRITE_UNLOCK (&type_rw_lock); + if (iholder->info->interface_finalize) + iholder->info->interface_finalize (vtable, iholder->info->interface_data); + if (iface->data->iface.vtable_finalize_base) + iface->data->iface.vtable_finalize_base (vtable); + G_WRITE_LOCK (&type_rw_lock); + } + vtable->g_type = 0; + vtable->g_instance_type = 0; + g_free (vtable); + + type_iface_blow_holder_info_Wm (iface, NODE_TYPE (node)); + + return TRUE; /* write lock modified */ +} + +static void +type_class_init_Wm (TypeNode *node, + GTypeClass *pclass) +{ + GSList *slist, *init_slist = NULL; + GTypeClass *class; + IFaceEntries *entries; + IFaceEntry *entry; + TypeNode *bnode, *pnode; + guint i; + + /* Accessing data->class will work for instantiatable types + * too because ClassData is a subset of InstanceData + */ + g_assert (node->is_classed && node->data && + node->data->class.class_size && + !node->data->class.class && + g_atomic_int_get (&node->data->class.init_state) == UNINITIALIZED); + if (node->data->class.class_private_size) + class = g_malloc0 (ALIGN_STRUCT (node->data->class.class_size) + node->data->class.class_private_size); + else + class = g_malloc0 (node->data->class.class_size); + node->data->class.class = class; + g_atomic_int_set (&node->data->class.init_state, BASE_CLASS_INIT); + + if (pclass) + { + pnode = lookup_type_node_I (pclass->g_type); + + memcpy (class, pclass, pnode->data->class.class_size); + memcpy (G_STRUCT_MEMBER_P (class, ALIGN_STRUCT (node->data->class.class_size)), G_STRUCT_MEMBER_P (pclass, ALIGN_STRUCT (pnode->data->class.class_size)), pnode->data->class.class_private_size); + + if (node->is_instantiatable) + { + /* We need to initialize the private_size here rather than in + * type_data_make_W() since the class init for the parent + * class may have changed pnode->data->instance.private_size. + */ + node->data->instance.private_size = pnode->data->instance.private_size; + } + } + class->g_type = NODE_TYPE (node); + + G_WRITE_UNLOCK (&type_rw_lock); + + /* stack all base class initialization functions, so we + * call them in ascending order. + */ + for (bnode = node; bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode))) + if (bnode->data->class.class_init_base) + init_slist = g_slist_prepend (init_slist, (gpointer) bnode->data->class.class_init_base); + for (slist = init_slist; slist; slist = slist->next) + { + GBaseInitFunc class_init_base = (GBaseInitFunc) slist->data; + + class_init_base (class); + } + g_slist_free (init_slist); + + G_WRITE_LOCK (&type_rw_lock); + + g_atomic_int_set (&node->data->class.init_state, BASE_IFACE_INIT); + + /* Before we initialize the class, base initialize all interfaces, either + * from parent, or through our holder info + */ + pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + + i = 0; + while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL && + i < IFACE_ENTRIES_N_ENTRIES (entries)) + { + entry = &entries->entry[i]; + while (i < IFACE_ENTRIES_N_ENTRIES (entries) && + entry->init_state == IFACE_INIT) + { + entry++; + i++; + } + + if (i == IFACE_ENTRIES_N_ENTRIES (entries)) + break; + + if (!type_iface_vtable_base_init_Wm (lookup_type_node_I (entry->iface_type), node)) + { + guint j; + IFaceEntries *pentries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (pnode); + + /* need to get this interface from parent, type_iface_vtable_base_init_Wm() + * doesn't modify write lock upon FALSE, so entry is still valid; + */ + g_assert (pnode != NULL); + + if (pentries) + for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (pentries); j++) + { + IFaceEntry *pentry = &pentries->entry[j]; + + if (pentry->iface_type == entry->iface_type) + { + entry->vtable = pentry->vtable; + entry->init_state = INITIALIZED; + break; + } + } + g_assert (entry->vtable != NULL); + } + + /* If the write lock was released, additional interface entries might + * have been inserted into CLASSED_NODE_IFACES_ENTRIES (node); they'll + * be base-initialized when inserted, so we don't have to worry that + * we might miss them. Uninitialized entries can only be moved higher + * when new ones are inserted. + */ + i++; + } + + g_atomic_int_set (&node->data->class.init_state, CLASS_INIT); + + G_WRITE_UNLOCK (&type_rw_lock); + + if (node->data->class.class_init) + node->data->class.class_init (class, (gpointer) node->data->class.class_data); + + G_WRITE_LOCK (&type_rw_lock); + + g_atomic_int_set (&node->data->class.init_state, IFACE_INIT); + + /* finish initializing the interfaces through our holder info. + * inherited interfaces are already init_state == INITIALIZED, because + * they either got setup in the above base_init loop, or during + * class_init from within type_add_interface_Wm() for this or + * an ancestor type. + */ + i = 0; + while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL) + { + entry = &entries->entry[i]; + while (i < IFACE_ENTRIES_N_ENTRIES (entries) && + entry->init_state == INITIALIZED) + { + entry++; + i++; + } + + if (i == IFACE_ENTRIES_N_ENTRIES (entries)) + break; + + type_iface_vtable_iface_init_Wm (lookup_type_node_I (entry->iface_type), node); + + /* As in the loop above, additional initialized entries might be inserted + * if the write lock is released, but that's harmless because the entries + * we need to initialize only move higher in the list. + */ + i++; + } + + g_atomic_int_set (&node->data->class.init_state, INITIALIZED); +} + +static void +type_data_finalize_class_ifaces_Wm (TypeNode *node) +{ + guint i; + IFaceEntries *entries; + + g_assert (node->is_instantiatable && node->data && node->data->class.class && NODE_REFCOUNT (node) == 0); + + reiterate: + entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node); + for (i = 0; entries != NULL && i < IFACE_ENTRIES_N_ENTRIES (entries); i++) + { + IFaceEntry *entry = &entries->entry[i]; + if (entry->vtable) + { + if (type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable)) + { + /* refetch entries, IFACES_ENTRIES might be modified */ + goto reiterate; + } + else + { + /* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE, + * iface vtable came from parent + */ + entry->vtable = NULL; + entry->init_state = UNINITIALIZED; + } + } + } +} + +static void +type_data_finalize_class_U (TypeNode *node, + ClassData *cdata) +{ + GTypeClass *class = cdata->class; + TypeNode *bnode; + + g_assert (cdata->class && NODE_REFCOUNT (node) == 0); + + if (cdata->class_finalize) + cdata->class_finalize (class, (gpointer) cdata->class_data); + + /* call all base class destruction functions in descending order + */ + if (cdata->class_finalize_base) + cdata->class_finalize_base (class); + for (bnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode))) + if (bnode->data->class.class_finalize_base) + bnode->data->class.class_finalize_base (class); + + g_free (cdata->class); +} + +static void +type_data_last_unref_Wm (TypeNode *node, + gboolean uncached) +{ + g_return_if_fail (node != NULL && node->plugin != NULL); + + if (!node->data || NODE_REFCOUNT (node) == 0) + { + g_warning ("cannot drop last reference to unreferenced type '%s'", + NODE_NAME (node)); + return; + } + + /* call class cache hooks */ + if (node->is_classed && node->data && node->data->class.class && static_n_class_cache_funcs && !uncached) + { + guint i; + + G_WRITE_UNLOCK (&type_rw_lock); + G_READ_LOCK (&type_rw_lock); + for (i = 0; i < static_n_class_cache_funcs; i++) + { + GTypeClassCacheFunc cache_func = static_class_cache_funcs[i].cache_func; + gpointer cache_data = static_class_cache_funcs[i].cache_data; + gboolean need_break; + + G_READ_UNLOCK (&type_rw_lock); + need_break = cache_func (cache_data, node->data->class.class); + G_READ_LOCK (&type_rw_lock); + if (!node->data || NODE_REFCOUNT (node) == 0) + INVALID_RECURSION ("GType class cache function ", cache_func, NODE_NAME (node)); + if (need_break) + break; + } + G_READ_UNLOCK (&type_rw_lock); + G_WRITE_LOCK (&type_rw_lock); + } + + /* may have been re-referenced meanwhile */ + if (g_atomic_int_dec_and_test ((int *) &node->ref_count)) + { + GType ptype = NODE_PARENT_TYPE (node); + TypeData *tdata; + + if (node->is_instantiatable) + { + /* destroy node->data->instance.mem_chunk */ + } + + tdata = node->data; + if (node->is_classed && tdata->class.class) + { + if (CLASSED_NODE_IFACES_ENTRIES_LOCKED (node) != NULL) + type_data_finalize_class_ifaces_Wm (node); + node->mutatable_check_cache = FALSE; + node->data = NULL; + G_WRITE_UNLOCK (&type_rw_lock); + type_data_finalize_class_U (node, &tdata->class); + G_WRITE_LOCK (&type_rw_lock); + } + else if (NODE_IS_IFACE (node) && tdata->iface.dflt_vtable) + { + node->mutatable_check_cache = FALSE; + node->data = NULL; + if (tdata->iface.dflt_finalize || tdata->iface.vtable_finalize_base) + { + G_WRITE_UNLOCK (&type_rw_lock); + if (tdata->iface.dflt_finalize) + tdata->iface.dflt_finalize (tdata->iface.dflt_vtable, (gpointer) tdata->iface.dflt_data); + if (tdata->iface.vtable_finalize_base) + tdata->iface.vtable_finalize_base (tdata->iface.dflt_vtable); + G_WRITE_LOCK (&type_rw_lock); + } + g_free (tdata->iface.dflt_vtable); + } + else + { + node->mutatable_check_cache = FALSE; + node->data = NULL; + } + + /* freeing tdata->common.value_table and its contents is taken care of + * by allocating it in one chunk with tdata + */ + g_free (tdata); + + G_WRITE_UNLOCK (&type_rw_lock); + g_type_plugin_unuse (node->plugin); + if (ptype) + type_data_unref_U (lookup_type_node_I (ptype), FALSE); + G_WRITE_LOCK (&type_rw_lock); + } +} + +static inline void +type_data_unref_U (TypeNode *node, + gboolean uncached) +{ + guint current; + + do { + current = NODE_REFCOUNT (node); + + if (current <= 1) + { + if (!node->plugin) + { + g_warning ("static type '%s' unreferenced too often", + NODE_NAME (node)); + return; + } + else + { + /* This is the last reference of a type from a plugin. We are + * experimentally disabling support for unloading type + * plugins, so don't allow the last ref to drop. + */ + return; + } + + g_assert (current > 0); + + g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ + G_WRITE_LOCK (&type_rw_lock); + type_data_last_unref_Wm (node, uncached); + G_WRITE_UNLOCK (&type_rw_lock); + g_rec_mutex_unlock (&class_init_rec_mutex); + return; + } + } while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current - 1)); +} + +/** + * g_type_add_class_cache_func: (skip) + * @cache_data: data to be passed to @cache_func + * @cache_func: a #GTypeClassCacheFunc + * + * Adds a #GTypeClassCacheFunc to be called before the reference count of a + * class goes from one to zero. This can be used to prevent premature class + * destruction. All installed #GTypeClassCacheFunc functions will be chained + * until one of them returns %TRUE. The functions have to check the class id + * passed in to figure whether they actually want to cache the class of this + * type, since all classes are routed through the same #GTypeClassCacheFunc + * chain. + */ +void +g_type_add_class_cache_func (gpointer cache_data, + GTypeClassCacheFunc cache_func) +{ + guint i; + + g_return_if_fail (cache_func != NULL); + + G_WRITE_LOCK (&type_rw_lock); + i = static_n_class_cache_funcs++; + static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs); + static_class_cache_funcs[i].cache_data = cache_data; + static_class_cache_funcs[i].cache_func = cache_func; + G_WRITE_UNLOCK (&type_rw_lock); +} + +/** + * g_type_remove_class_cache_func: (skip) + * @cache_data: data that was given when adding @cache_func + * @cache_func: a #GTypeClassCacheFunc + * + * Removes a previously installed #GTypeClassCacheFunc. The cache + * maintained by @cache_func has to be empty when calling + * g_type_remove_class_cache_func() to avoid leaks. + */ +void +g_type_remove_class_cache_func (gpointer cache_data, + GTypeClassCacheFunc cache_func) +{ + gboolean found_it = FALSE; + guint i; + + g_return_if_fail (cache_func != NULL); + + G_WRITE_LOCK (&type_rw_lock); + for (i = 0; i < static_n_class_cache_funcs; i++) + if (static_class_cache_funcs[i].cache_data == cache_data && + static_class_cache_funcs[i].cache_func == cache_func) + { + static_n_class_cache_funcs--; + memmove (static_class_cache_funcs + i, + static_class_cache_funcs + i + 1, + sizeof (static_class_cache_funcs[0]) * (static_n_class_cache_funcs - i)); + static_class_cache_funcs = g_renew (ClassCacheFunc, static_class_cache_funcs, static_n_class_cache_funcs); + found_it = TRUE; + break; + } + G_WRITE_UNLOCK (&type_rw_lock); + + if (!found_it) + g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p", + cache_func, cache_data); +} + + +/** + * g_type_add_interface_check: (skip) + * @check_data: data to pass to @check_func + * @check_func: function to be called after each interface + * is initialized + * + * Adds a function to be called after an interface vtable is + * initialized for any class (i.e. after the @interface_init + * member of #GInterfaceInfo has been called). + * + * This function is useful when you want to check an invariant + * that depends on the interfaces of a class. For instance, the + * implementation of #GObject uses this facility to check that an + * object implements all of the properties that are defined on its + * interfaces. + * + * Since: 2.4 + */ +void +g_type_add_interface_check (gpointer check_data, + GTypeInterfaceCheckFunc check_func) +{ + guint i; + + g_return_if_fail (check_func != NULL); + + G_WRITE_LOCK (&type_rw_lock); + i = static_n_iface_check_funcs++; + static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs); + static_iface_check_funcs[i].check_data = check_data; + static_iface_check_funcs[i].check_func = check_func; + G_WRITE_UNLOCK (&type_rw_lock); +} + +/** + * g_type_remove_interface_check: (skip) + * @check_data: callback data passed to g_type_add_interface_check() + * @check_func: callback function passed to g_type_add_interface_check() + * + * Removes an interface check function added with + * g_type_add_interface_check(). + * + * Since: 2.4 + */ +void +g_type_remove_interface_check (gpointer check_data, + GTypeInterfaceCheckFunc check_func) +{ + gboolean found_it = FALSE; + guint i; + + g_return_if_fail (check_func != NULL); + + G_WRITE_LOCK (&type_rw_lock); + for (i = 0; i < static_n_iface_check_funcs; i++) + if (static_iface_check_funcs[i].check_data == check_data && + static_iface_check_funcs[i].check_func == check_func) + { + static_n_iface_check_funcs--; + memmove (static_iface_check_funcs + i, + static_iface_check_funcs + i + 1, + sizeof (static_iface_check_funcs[0]) * (static_n_iface_check_funcs - i)); + static_iface_check_funcs = g_renew (IFaceCheckFunc, static_iface_check_funcs, static_n_iface_check_funcs); + found_it = TRUE; + break; + } + G_WRITE_UNLOCK (&type_rw_lock); + + if (!found_it) + g_warning (G_STRLOC ": cannot remove unregistered class check func %p with data %p", + check_func, check_data); +} + +/* --- type registration --- */ +/** + * g_type_register_fundamental: + * @type_id: a predefined type identifier + * @type_name: 0-terminated string used as the name of the new type + * @info: #GTypeInfo structure for this type + * @finfo: #GTypeFundamentalInfo structure for this type + * @flags: bitwise combination of #GTypeFlags values + * + * Registers @type_id as the predefined identifier and @type_name as the + * name of a fundamental type. If @type_id is already registered, or a + * type named @type_name is already registered, the behaviour is undefined. + * The type system uses the information contained in the #GTypeInfo structure + * pointed to by @info and the #GTypeFundamentalInfo structure pointed to by + * @finfo to manage the type and its instances. The value of @flags determines + * additional characteristics of the fundamental type. + * + * Returns: the predefined type identifier + */ +GType +g_type_register_fundamental (GType type_id, + const gchar *type_name, + const GTypeInfo *info, + const GTypeFundamentalInfo *finfo, + GTypeFlags flags) +{ + TypeNode *node; + + g_assert_type_system_initialized (); + g_return_val_if_fail (type_id > 0, 0); + g_return_val_if_fail (type_name != NULL, 0); + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (finfo != NULL, 0); + + if (!check_type_name_I (type_name)) + return 0; + if ((type_id & TYPE_ID_MASK) || + type_id > G_TYPE_FUNDAMENTAL_MAX) + { + g_warning ("attempt to register fundamental type '%s' with invalid type id (%" G_GSIZE_FORMAT ")", + type_name, + type_id); + return 0; + } + if ((finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) && + !(finfo->type_flags & G_TYPE_FLAG_CLASSED)) + { + g_warning ("cannot register instantiatable fundamental type '%s' as non-classed", + type_name); + return 0; + } + if (lookup_type_node_I (type_id)) + { + g_warning ("cannot register existing fundamental type '%s' (as '%s')", + type_descriptive_name_I (type_id), + type_name); + return 0; + } + + G_WRITE_LOCK (&type_rw_lock); + node = type_node_fundamental_new_W (type_id, type_name, finfo->type_flags); + type_add_flags_W (node, flags); + + if (check_type_info_I (NULL, NODE_FUNDAMENTAL_TYPE (node), type_name, info)) + type_data_make_W (node, info, + check_value_table_I (type_name, info->value_table) ? info->value_table : NULL); + G_WRITE_UNLOCK (&type_rw_lock); + + return NODE_TYPE (node); +} + +/** + * g_type_register_static_simple: (skip) + * @parent_type: type from which this type will be derived + * @type_name: 0-terminated string used as the name of the new type + * @class_size: size of the class structure (see #GTypeInfo) + * @class_init: location of the class initialization function (see #GTypeInfo) + * @instance_size: size of the instance structure (see #GTypeInfo) + * @instance_init: location of the instance initialization function (see #GTypeInfo) + * @flags: bitwise combination of #GTypeFlags values + * + * Registers @type_name as the name of a new static type derived from + * @parent_type. The value of @flags determines the nature (e.g. + * abstract or not) of the type. It works by filling a #GTypeInfo + * struct and calling g_type_register_static(). + * + * Since: 2.12 + * + * Returns: the new type identifier + */ +GType +g_type_register_static_simple (GType parent_type, + const gchar *type_name, + guint class_size, + GClassInitFunc class_init, + guint instance_size, + GInstanceInitFunc instance_init, + GTypeFlags flags) +{ + GTypeInfo info; + + /* Instances are not allowed to be larger than this. If you have a big + * fixed-length array or something, point to it instead. + */ + g_return_val_if_fail (class_size <= G_MAXUINT16, G_TYPE_INVALID); + g_return_val_if_fail (instance_size <= G_MAXUINT16, G_TYPE_INVALID); + + info.class_size = class_size; + info.base_init = NULL; + info.base_finalize = NULL; + info.class_init = class_init; + info.class_finalize = NULL; + info.class_data = NULL; + info.instance_size = instance_size; + info.n_preallocs = 0; + info.instance_init = instance_init; + info.value_table = NULL; + + return g_type_register_static (parent_type, type_name, &info, flags); +} + +/** + * g_type_register_static: + * @parent_type: type from which this type will be derived + * @type_name: 0-terminated string used as the name of the new type + * @info: #GTypeInfo structure for this type + * @flags: bitwise combination of #GTypeFlags values + * + * Registers @type_name as the name of a new static type derived from + * @parent_type. The type system uses the information contained in the + * #GTypeInfo structure pointed to by @info to manage the type and its + * instances (if not abstract). The value of @flags determines the nature + * (e.g. abstract or not) of the type. + * + * Returns: the new type identifier + */ +GType +g_type_register_static (GType parent_type, + const gchar *type_name, + const GTypeInfo *info, + GTypeFlags flags) +{ + TypeNode *pnode, *node; + GType type = 0; + + g_assert_type_system_initialized (); + g_return_val_if_fail (parent_type > 0, 0); + g_return_val_if_fail (type_name != NULL, 0); + g_return_val_if_fail (info != NULL, 0); + + if (!check_type_name_I (type_name) || + !check_derivation_I (parent_type, type_name)) + return 0; + if (info->class_finalize) + { + g_warning ("class finalizer specified for static type '%s'", + type_name); + return 0; + } + + pnode = lookup_type_node_I (parent_type); + G_WRITE_LOCK (&type_rw_lock); + type_data_ref_Wm (pnode); + if (check_type_info_I (pnode, NODE_FUNDAMENTAL_TYPE (pnode), type_name, info)) + { + node = type_node_new_W (pnode, type_name, NULL); + type_add_flags_W (node, flags); + type = NODE_TYPE (node); + type_data_make_W (node, info, + check_value_table_I (type_name, info->value_table) ? info->value_table : NULL); + } + G_WRITE_UNLOCK (&type_rw_lock); + + return type; +} + +/** + * g_type_register_dynamic: + * @parent_type: type from which this type will be derived + * @type_name: 0-terminated string used as the name of the new type + * @plugin: #GTypePlugin structure to retrieve the #GTypeInfo from + * @flags: bitwise combination of #GTypeFlags values + * + * Registers @type_name as the name of a new dynamic type derived from + * @parent_type. The type system uses the information contained in the + * #GTypePlugin structure pointed to by @plugin to manage the type and its + * instances (if not abstract). The value of @flags determines the nature + * (e.g. abstract or not) of the type. + * + * Returns: the new type identifier or %G_TYPE_INVALID if registration failed + */ +GType +g_type_register_dynamic (GType parent_type, + const gchar *type_name, + GTypePlugin *plugin, + GTypeFlags flags) +{ + TypeNode *pnode, *node; + GType type; + + g_assert_type_system_initialized (); + g_return_val_if_fail (parent_type > 0, 0); + g_return_val_if_fail (type_name != NULL, 0); + g_return_val_if_fail (plugin != NULL, 0); + + if (!check_type_name_I (type_name) || + !check_derivation_I (parent_type, type_name) || + !check_plugin_U (plugin, TRUE, FALSE, type_name)) + return 0; + + G_WRITE_LOCK (&type_rw_lock); + pnode = lookup_type_node_I (parent_type); + node = type_node_new_W (pnode, type_name, plugin); + type_add_flags_W (node, flags); + type = NODE_TYPE (node); + G_WRITE_UNLOCK (&type_rw_lock); + + return type; +} + +/** + * g_type_add_interface_static: + * @instance_type: #GType value of an instantiatable type + * @interface_type: #GType value of an interface type + * @info: #GInterfaceInfo structure for this + * (@instance_type, @interface_type) combination + * + * Adds @interface_type to the static @instance_type. + * The information contained in the #GInterfaceInfo structure + * pointed to by @info is used to manage the relationship. + */ +void +g_type_add_interface_static (GType instance_type, + GType interface_type, + const GInterfaceInfo *info) +{ + /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */ + g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type)); + g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE); + + /* we only need to lock class_init_rec_mutex if instance_type already has its + * class initialized, however this function is rarely enough called to take + * the simple route and always acquire class_init_rec_mutex. + */ + g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ + G_WRITE_LOCK (&type_rw_lock); + if (check_add_interface_L (instance_type, interface_type)) + { + TypeNode *node = lookup_type_node_I (instance_type); + TypeNode *iface = lookup_type_node_I (interface_type); + if (check_interface_info_I (iface, NODE_TYPE (node), info)) + type_add_interface_Wm (node, iface, info, NULL); + } + G_WRITE_UNLOCK (&type_rw_lock); + g_rec_mutex_unlock (&class_init_rec_mutex); +} + +/** + * g_type_add_interface_dynamic: + * @instance_type: #GType value of an instantiatable type + * @interface_type: #GType value of an interface type + * @plugin: #GTypePlugin structure to retrieve the #GInterfaceInfo from + * + * Adds @interface_type to the dynamic @instance_type. The information + * contained in the #GTypePlugin structure pointed to by @plugin + * is used to manage the relationship. + */ +void +g_type_add_interface_dynamic (GType instance_type, + GType interface_type, + GTypePlugin *plugin) +{ + TypeNode *node; + /* G_TYPE_IS_INSTANTIATABLE() is an external call: _U */ + g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type)); + g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE); + + node = lookup_type_node_I (instance_type); + if (!check_plugin_U (plugin, FALSE, TRUE, NODE_NAME (node))) + return; + + /* see comment in g_type_add_interface_static() about class_init_rec_mutex */ + g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ + G_WRITE_LOCK (&type_rw_lock); + if (check_add_interface_L (instance_type, interface_type)) + { + TypeNode *iface = lookup_type_node_I (interface_type); + type_add_interface_Wm (node, iface, NULL, plugin); + } + G_WRITE_UNLOCK (&type_rw_lock); + g_rec_mutex_unlock (&class_init_rec_mutex); +} + + +/* --- public API functions --- */ +/** + * g_type_class_ref: + * @type: type ID of a classed type + * + * Increments the reference count of the class structure belonging to + * @type. This function will demand-create the class if it doesn't + * exist already. + * + * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass + * structure for the given type ID + */ +gpointer +g_type_class_ref (GType type) +{ + TypeNode *node; + GType ptype; + gboolean holds_ref; + GTypeClass *pclass; + + /* optimize for common code path */ + node = lookup_type_node_I (type); + if (!node || !node->is_classed) + { + g_warning ("cannot retrieve class for invalid (unclassed) type '%s'", + type_descriptive_name_I (type)); + return NULL; + } + + if (G_LIKELY (type_data_ref_U (node))) + { + if (G_LIKELY (g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)) + return node->data->class.class; + holds_ref = TRUE; + } + else + holds_ref = FALSE; + + /* here, we either have node->data->class.class == NULL, or a recursive + * call to g_type_class_ref() with a partly initialized class, or + * node->data->class.init_state == INITIALIZED, because any + * concurrently running initialization was guarded by class_init_rec_mutex. + */ + g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ + + /* we need an initialized parent class for initializing derived classes */ + ptype = NODE_PARENT_TYPE (node); + pclass = ptype ? g_type_class_ref (ptype) : NULL; + + G_WRITE_LOCK (&type_rw_lock); + + if (!holds_ref) + type_data_ref_Wm (node); + + if (!node->data->class.class) /* class uninitialized */ + type_class_init_Wm (node, pclass); + + G_WRITE_UNLOCK (&type_rw_lock); + + if (pclass) + g_type_class_unref (pclass); + + g_rec_mutex_unlock (&class_init_rec_mutex); + + return node->data->class.class; +} + +/** + * g_type_class_unref: + * @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref + * + * Decrements the reference count of the class structure being passed in. + * Once the last reference count of a class has been released, classes + * may be finalized by the type system, so further dereferencing of a + * class pointer after g_type_class_unref() are invalid. + */ +void +g_type_class_unref (gpointer g_class) +{ + TypeNode *node; + GTypeClass *class = g_class; + + g_return_if_fail (g_class != NULL); + + node = lookup_type_node_I (class->g_type); + if (node && node->is_classed && NODE_REFCOUNT (node)) + type_data_unref_U (node, FALSE); + else + g_warning ("cannot unreference class of invalid (unclassed) type '%s'", + type_descriptive_name_I (class->g_type)); +} + +/** + * g_type_class_unref_uncached: (skip) + * @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref + * + * A variant of g_type_class_unref() for use in #GTypeClassCacheFunc + * implementations. It unreferences a class without consulting the chain + * of #GTypeClassCacheFuncs, avoiding the recursion which would occur + * otherwise. + */ +void +g_type_class_unref_uncached (gpointer g_class) +{ + TypeNode *node; + GTypeClass *class = g_class; + + g_return_if_fail (g_class != NULL); + + node = lookup_type_node_I (class->g_type); + if (node && node->is_classed && NODE_REFCOUNT (node)) + type_data_unref_U (node, TRUE); + else + g_warning ("cannot unreference class of invalid (unclassed) type '%s'", + type_descriptive_name_I (class->g_type)); +} + +/** + * g_type_class_peek: + * @type: type ID of a classed type + * + * This function is essentially the same as g_type_class_ref(), + * except that the classes reference count isn't incremented. + * As a consequence, this function may return %NULL if the class + * of the type passed in does not currently exist (hasn't been + * referenced before). + * + * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass + * structure for the given type ID or %NULL if the class does not + * currently exist + */ +gpointer +g_type_class_peek (GType type) +{ + TypeNode *node; + gpointer class; + + node = lookup_type_node_I (type); + if (node && node->is_classed && NODE_REFCOUNT (node) && + g_atomic_int_get (&node->data->class.init_state) == INITIALIZED) + /* ref_count _may_ be 0 */ + class = node->data->class.class; + else + class = NULL; + + return class; +} + +/** + * g_type_class_peek_static: + * @type: type ID of a classed type + * + * A more efficient version of g_type_class_peek() which works only for + * static types. + * + * Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass + * structure for the given type ID or %NULL if the class does not + * currently exist or is dynamically loaded + * + * Since: 2.4 + */ +gpointer +g_type_class_peek_static (GType type) +{ + TypeNode *node; + gpointer class; + + node = lookup_type_node_I (type); + if (node && node->is_classed && NODE_REFCOUNT (node) && + /* peek only static types: */ node->plugin == NULL && + g_atomic_int_get (&node->data->class.init_state) == INITIALIZED) + /* ref_count _may_ be 0 */ + class = node->data->class.class; + else + class = NULL; + + return class; +} + +/** + * g_type_class_peek_parent: + * @g_class: (type GObject.TypeClass): the #GTypeClass structure to + * retrieve the parent class for + * + * This is a convenience function often needed in class initializers. + * It returns the class structure of the immediate parent type of the + * class passed in. Since derived classes hold a reference count on + * their parent classes as long as they are instantiated, the returned + * class will always exist. + * + * This function is essentially equivalent to: + * g_type_class_peek (g_type_parent (G_TYPE_FROM_CLASS (g_class))) + * + * Returns: (type GObject.TypeClass) (transfer none): the parent class + * of @g_class + */ +gpointer +g_type_class_peek_parent (gpointer g_class) +{ + TypeNode *node; + gpointer class = NULL; + + g_return_val_if_fail (g_class != NULL, NULL); + + node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class)); + + g_return_val_if_fail (node != NULL, NULL); + + /* We used to acquire a read lock here. That is not necessary, since + * parent->data->class.class is constant as long as the derived class + * exists. + */ + if (node->is_classed && node->data && NODE_PARENT_TYPE (node)) + { + node = lookup_type_node_I (NODE_PARENT_TYPE (node)); + class = node->data->class.class; + } + else if (NODE_PARENT_TYPE (node)) + g_warning (G_STRLOC ": invalid class pointer '%p'", g_class); + + return class; +} + +/** + * g_type_interface_peek: + * @instance_class: (type GObject.TypeClass): a #GTypeClass structure + * @iface_type: an interface ID which this class conforms to + * + * Returns the #GTypeInterface structure of an interface to which the + * passed in class conforms. + * + * Returns: (type GObject.TypeInterface) (transfer none): the #GTypeInterface + * structure of @iface_type if implemented by @instance_class, %NULL + * otherwise + */ +gpointer +g_type_interface_peek (gpointer instance_class, + GType iface_type) +{ + TypeNode *node; + TypeNode *iface; + gpointer vtable = NULL; + GTypeClass *class = instance_class; + + g_return_val_if_fail (instance_class != NULL, NULL); + + node = lookup_type_node_I (class->g_type); + iface = lookup_type_node_I (iface_type); + if (node && node->is_instantiatable && iface) + type_lookup_iface_vtable_I (node, iface, &vtable); + else + g_warning (G_STRLOC ": invalid class pointer '%p'", class); + + return vtable; +} + +/** + * g_type_interface_peek_parent: + * @g_iface: (type GObject.TypeInterface): a #GTypeInterface structure + * + * Returns the corresponding #GTypeInterface structure of the parent type + * of the instance type to which @g_iface belongs. This is useful when + * deriving the implementation of an interface from the parent type and + * then possibly overriding some methods. + * + * Returns: (transfer none) (type GObject.TypeInterface): the + * corresponding #GTypeInterface structure of the parent type of the + * instance type to which @g_iface belongs, or %NULL if the parent + * type doesn't conform to the interface + */ +gpointer +g_type_interface_peek_parent (gpointer g_iface) +{ + TypeNode *node; + TypeNode *iface; + gpointer vtable = NULL; + GTypeInterface *iface_class = g_iface; + + g_return_val_if_fail (g_iface != NULL, NULL); + + iface = lookup_type_node_I (iface_class->g_type); + node = lookup_type_node_I (iface_class->g_instance_type); + if (node) + node = lookup_type_node_I (NODE_PARENT_TYPE (node)); + if (node && node->is_instantiatable && iface) + type_lookup_iface_vtable_I (node, iface, &vtable); + else if (node) + g_warning (G_STRLOC ": invalid interface pointer '%p'", g_iface); + + return vtable; +} + +/** + * g_type_default_interface_ref: + * @g_type: an interface type + * + * Increments the reference count for the interface type @g_type, + * and returns the default interface vtable for the type. + * + * If the type is not currently in use, then the default vtable + * for the type will be created and initialized by calling + * the base interface init and default vtable init functions for + * the type (the @base_init and @class_init members of #GTypeInfo). + * Calling g_type_default_interface_ref() is useful when you + * want to make sure that signals and properties for an interface + * have been installed. + * + * Since: 2.4 + * + * Returns: (type GObject.TypeInterface) (transfer none): the default + * vtable for the interface; call g_type_default_interface_unref() + * when you are done using the interface. + */ +gpointer +g_type_default_interface_ref (GType g_type) +{ + TypeNode *node; + gpointer dflt_vtable; + + G_WRITE_LOCK (&type_rw_lock); + + node = lookup_type_node_I (g_type); + if (!node || !NODE_IS_IFACE (node) || + (node->data && NODE_REFCOUNT (node) == 0)) + { + G_WRITE_UNLOCK (&type_rw_lock); + g_warning ("cannot retrieve default vtable for invalid or non-interface type '%s'", + type_descriptive_name_I (g_type)); + return NULL; + } + + if (!node->data || !node->data->iface.dflt_vtable) + { + G_WRITE_UNLOCK (&type_rw_lock); + g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */ + G_WRITE_LOCK (&type_rw_lock); + node = lookup_type_node_I (g_type); + type_data_ref_Wm (node); + type_iface_ensure_dflt_vtable_Wm (node); + g_rec_mutex_unlock (&class_init_rec_mutex); + } + else + type_data_ref_Wm (node); /* ref_count >= 1 already */ + + dflt_vtable = node->data->iface.dflt_vtable; + G_WRITE_UNLOCK (&type_rw_lock); + + return dflt_vtable; +} + +/** + * g_type_default_interface_peek: + * @g_type: an interface type + * + * If the interface type @g_type is currently in use, returns its + * default interface vtable. + * + * Since: 2.4 + * + * Returns: (type GObject.TypeInterface) (transfer none): the default + * vtable for the interface, or %NULL if the type is not currently + * in use + */ +gpointer +g_type_default_interface_peek (GType g_type) +{ + TypeNode *node; + gpointer vtable; + + node = lookup_type_node_I (g_type); + if (node && NODE_IS_IFACE (node) && NODE_REFCOUNT (node)) + vtable = node->data->iface.dflt_vtable; + else + vtable = NULL; + + return vtable; +} + +/** + * g_type_default_interface_unref: + * @g_iface: (type GObject.TypeInterface): the default vtable + * structure for an interface, as returned by g_type_default_interface_ref() + * + * Decrements the reference count for the type corresponding to the + * interface default vtable @g_iface. If the type is dynamic, then + * when no one is using the interface and all references have + * been released, the finalize function for the interface's default + * vtable (the @class_finalize member of #GTypeInfo) will be called. + * + * Since: 2.4 + */ +void +g_type_default_interface_unref (gpointer g_iface) +{ + TypeNode *node; + GTypeInterface *vtable = g_iface; + + g_return_if_fail (g_iface != NULL); + + node = lookup_type_node_I (vtable->g_type); + if (node && NODE_IS_IFACE (node)) + type_data_unref_U (node, FALSE); + else + g_warning ("cannot unreference invalid interface default vtable for '%s'", + type_descriptive_name_I (vtable->g_type)); +} + +/** + * g_type_name: + * @type: type to return name for + * + * Get the unique name that is assigned to a type ID. Note that this + * function (like all other GType API) cannot cope with invalid type + * IDs. %G_TYPE_INVALID may be passed to this function, as may be any + * other validly registered type ID, but randomized type IDs should + * not be passed in and will most likely lead to a crash. + * + * Returns: static type name or %NULL + */ +const gchar * +g_type_name (GType type) +{ + TypeNode *node; + + g_assert_type_system_initialized (); + + node = lookup_type_node_I (type); + + return node ? NODE_NAME (node) : NULL; +} + +/** + * g_type_qname: + * @type: type to return quark of type name for + * + * Get the corresponding quark of the type IDs name. + * + * Returns: the type names quark or 0 + */ +GQuark +g_type_qname (GType type) +{ + TypeNode *node; + + node = lookup_type_node_I (type); + + return node ? node->qname : 0; +} + +/** + * g_type_from_name: + * @name: type name to look up + * + * Look up the type ID from a given type name, returning 0 if no type + * has been registered under this name (this is the preferred method + * to find out by name whether a specific type has been registered + * yet). + * + * Returns: corresponding type ID or 0 + */ +GType +g_type_from_name (const gchar *name) +{ + GType type = 0; + + g_return_val_if_fail (name != NULL, 0); + + G_READ_LOCK (&type_rw_lock); + type = (GType) g_hash_table_lookup (static_type_nodes_ht, name); + G_READ_UNLOCK (&type_rw_lock); + + return type; +} + +/** + * g_type_parent: + * @type: the derived type + * + * Return the direct parent type of the passed in type. If the passed + * in type has no parent, i.e. is a fundamental type, 0 is returned. + * + * Returns: the parent type + */ +GType +g_type_parent (GType type) +{ + TypeNode *node; + + node = lookup_type_node_I (type); + + return node ? NODE_PARENT_TYPE (node) : 0; +} + +/** + * g_type_depth: + * @type: a #GType + * + * Returns the length of the ancestry of the passed in type. This + * includes the type itself, so that e.g. a fundamental type has depth 1. + * + * Returns: the depth of @type + */ +guint +g_type_depth (GType type) +{ + TypeNode *node; + + node = lookup_type_node_I (type); + + return node ? node->n_supers + 1 : 0; +} + +/** + * g_type_next_base: + * @leaf_type: descendant of @root_type and the type to be returned + * @root_type: immediate parent of the returned type + * + * Given a @leaf_type and a @root_type which is contained in its + * ancestry, return the type that @root_type is the immediate parent + * of. In other words, this function determines the type that is + * derived directly from @root_type which is also a base class of + * @leaf_type. Given a root type and a leaf type, this function can + * be used to determine the types and order in which the leaf type is + * descended from the root type. + * + * Returns: immediate child of @root_type and ancestor of @leaf_type + */ +GType +g_type_next_base (GType type, + GType base_type) +{ + GType atype = 0; + TypeNode *node; + + node = lookup_type_node_I (type); + if (node) + { + TypeNode *base_node = lookup_type_node_I (base_type); + + if (base_node && base_node->n_supers < node->n_supers) + { + guint n = node->n_supers - base_node->n_supers; + + if (node->supers[n] == base_type) + atype = node->supers[n - 1]; + } + } + + return atype; +} + +static inline gboolean +type_node_check_conformities_UorL (TypeNode *node, + TypeNode *iface_node, + /* support_inheritance */ + gboolean support_interfaces, + gboolean support_prerequisites, + gboolean have_lock) +{ + gboolean match; + + if (/* support_inheritance && */ + NODE_IS_ANCESTOR (iface_node, node)) + return TRUE; + + support_interfaces = support_interfaces && node->is_instantiatable && NODE_IS_IFACE (iface_node); + support_prerequisites = support_prerequisites && NODE_IS_IFACE (node); + match = FALSE; + if (support_interfaces) + { + if (have_lock) + { + if (type_lookup_iface_entry_L (node, iface_node)) + match = TRUE; + } + else + { + if (type_lookup_iface_vtable_I (node, iface_node, NULL)) + match = TRUE; + } + } + if (!match && + support_prerequisites) + { + if (!have_lock) + G_READ_LOCK (&type_rw_lock); + if (support_prerequisites && type_lookup_prerequisite_L (node, NODE_TYPE (iface_node))) + match = TRUE; + if (!have_lock) + G_READ_UNLOCK (&type_rw_lock); + } + return match; +} + +static gboolean +type_node_is_a_L (TypeNode *node, + TypeNode *iface_node) +{ + return type_node_check_conformities_UorL (node, iface_node, TRUE, TRUE, TRUE); +} + +static inline gboolean +type_node_conforms_to_U (TypeNode *node, + TypeNode *iface_node, + gboolean support_interfaces, + gboolean support_prerequisites) +{ + return type_node_check_conformities_UorL (node, iface_node, support_interfaces, support_prerequisites, FALSE); +} + +/** + * g_type_is_a: + * @type: type to check ancestry for + * @is_a_type: possible ancestor of @type or interface that @type + * could conform to + * + * If @is_a_type is a derivable type, check whether @type is a + * descendant of @is_a_type. If @is_a_type is an interface, check + * whether @type conforms to it. + * + * Returns: %TRUE if @type is a @is_a_type + */ +gboolean +g_type_is_a (GType type, + GType iface_type) +{ + TypeNode *node, *iface_node; + gboolean is_a; + + if (type == iface_type) + return TRUE; + + node = lookup_type_node_I (type); + iface_node = lookup_type_node_I (iface_type); + is_a = node && iface_node && type_node_conforms_to_U (node, iface_node, TRUE, TRUE); + + return is_a; +} + +/** + * g_type_children: + * @type: the parent type + * @n_children: (out) (optional): location to store the length of + * the returned array, or %NULL + * + * Return a newly allocated and 0-terminated array of type IDs, listing + * the child types of @type. + * + * Returns: (array length=n_children) (transfer full): Newly allocated + * and 0-terminated array of child types, free with g_free() + */ +GType* +g_type_children (GType type, + guint *n_children) +{ + TypeNode *node; + + node = lookup_type_node_I (type); + if (node) + { + GType *children; + + G_READ_LOCK (&type_rw_lock); /* ->children is relocatable */ + children = g_new (GType, node->n_children + 1); + if (node->n_children != 0) + memcpy (children, node->children, sizeof (GType) * node->n_children); + children[node->n_children] = 0; + + if (n_children) + *n_children = node->n_children; + G_READ_UNLOCK (&type_rw_lock); + + return children; + } + else + { + if (n_children) + *n_children = 0; + + return NULL; + } +} + +/** + * g_type_interfaces: + * @type: the type to list interface types for + * @n_interfaces: (out) (optional): location to store the length of + * the returned array, or %NULL + * + * Return a newly allocated and 0-terminated array of type IDs, listing + * the interface types that @type conforms to. + * + * Returns: (array length=n_interfaces) (transfer full): Newly allocated + * and 0-terminated array of interface types, free with g_free() + */ +GType* +g_type_interfaces (GType type, + guint *n_interfaces) +{ + TypeNode *node; + + node = lookup_type_node_I (type); + if (node && node->is_instantiatable) + { + IFaceEntries *entries; + GType *ifaces; + guint i; + + G_READ_LOCK (&type_rw_lock); + entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node); + if (entries) + { + ifaces = g_new (GType, IFACE_ENTRIES_N_ENTRIES (entries) + 1); + for (i = 0; i < IFACE_ENTRIES_N_ENTRIES (entries); i++) + ifaces[i] = entries->entry[i].iface_type; + } + else + { + ifaces = g_new (GType, 1); + i = 0; + } + ifaces[i] = 0; + + if (n_interfaces) + *n_interfaces = i; + G_READ_UNLOCK (&type_rw_lock); + + return ifaces; + } + else + { + if (n_interfaces) + *n_interfaces = 0; + + return NULL; + } +} + +typedef struct _QData QData; +struct _GData +{ + guint n_qdatas; + QData *qdatas; +}; +struct _QData +{ + GQuark quark; + gpointer data; +}; + +static inline gpointer +type_get_qdata_L (TypeNode *node, + GQuark quark) +{ + GData *gdata = node->global_gdata; + + if (quark && gdata && gdata->n_qdatas) + { + QData *qdatas = gdata->qdatas - 1; + guint n_qdatas = gdata->n_qdatas; + + do + { + guint i; + QData *check; + + i = (n_qdatas + 1) / 2; + check = qdatas + i; + if (quark == check->quark) + return check->data; + else if (quark > check->quark) + { + n_qdatas -= i; + qdatas = check; + } + else /* if (quark < check->quark) */ + n_qdatas = i - 1; + } + while (n_qdatas); + } + return NULL; +} + +/** + * g_type_get_qdata: + * @type: a #GType + * @quark: a #GQuark id to identify the data + * + * Obtains data which has previously been attached to @type + * with g_type_set_qdata(). + * + * Note that this does not take subtyping into account; data + * attached to one type with g_type_set_qdata() cannot + * be retrieved from a subtype using g_type_get_qdata(). + * + * Returns: (transfer none): the data, or %NULL if no data was found + */ +gpointer +g_type_get_qdata (GType type, + GQuark quark) +{ + TypeNode *node; + gpointer data; + + node = lookup_type_node_I (type); + if (node) + { + G_READ_LOCK (&type_rw_lock); + data = type_get_qdata_L (node, quark); + G_READ_UNLOCK (&type_rw_lock); + } + else + { + g_return_val_if_fail (node != NULL, NULL); + data = NULL; + } + return data; +} + +static inline void +type_set_qdata_W (TypeNode *node, + GQuark quark, + gpointer data) +{ + GData *gdata; + QData *qdata; + guint i; + + /* setup qdata list if necessary */ + if (!node->global_gdata) + node->global_gdata = g_new0 (GData, 1); + gdata = node->global_gdata; + + /* try resetting old data */ + qdata = gdata->qdatas; + for (i = 0; i < gdata->n_qdatas; i++) + if (qdata[i].quark == quark) + { + qdata[i].data = data; + return; + } + + /* add new entry */ + gdata->n_qdatas++; + gdata->qdatas = g_renew (QData, gdata->qdatas, gdata->n_qdatas); + qdata = gdata->qdatas; + for (i = 0; i < gdata->n_qdatas - 1; i++) + if (qdata[i].quark > quark) + break; + memmove (qdata + i + 1, qdata + i, sizeof (qdata[0]) * (gdata->n_qdatas - i - 1)); + qdata[i].quark = quark; + qdata[i].data = data; +} + +/** + * g_type_set_qdata: + * @type: a #GType + * @quark: a #GQuark id to identify the data + * @data: the data + * + * Attaches arbitrary data to a type. + */ +void +g_type_set_qdata (GType type, + GQuark quark, + gpointer data) +{ + TypeNode *node; + + g_return_if_fail (quark != 0); + + node = lookup_type_node_I (type); + if (node) + { + G_WRITE_LOCK (&type_rw_lock); + type_set_qdata_W (node, quark, data); + G_WRITE_UNLOCK (&type_rw_lock); + } + else + g_return_if_fail (node != NULL); +} + +static void +type_add_flags_W (TypeNode *node, + GTypeFlags flags) +{ + guint dflags; + + g_return_if_fail ((flags & ~TYPE_FLAG_MASK) == 0); + g_return_if_fail (node != NULL); + + if ((flags & TYPE_FLAG_MASK) && node->is_classed && node->data && node->data->class.class) + g_warning ("tagging type '%s' as abstract after class initialization", NODE_NAME (node)); + dflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags)); + dflags |= flags; + type_set_qdata_W (node, static_quark_type_flags, GUINT_TO_POINTER (dflags)); +} + +/** + * g_type_query: + * @type: #GType of a static, classed type + * @query: (out caller-allocates): a user provided structure that is + * filled in with constant values upon success + * + * Queries the type system for information about a specific type. + * This function will fill in a user-provided structure to hold + * type-specific information. If an invalid #GType is passed in, the + * @type member of the #GTypeQuery is 0. All members filled into the + * #GTypeQuery structure should be considered constant and have to be + * left untouched. + */ +void +g_type_query (GType type, + GTypeQuery *query) +{ + TypeNode *node; + + g_return_if_fail (query != NULL); + + /* if node is not static and classed, we won't allow query */ + query->type = 0; + node = lookup_type_node_I (type); + if (node && node->is_classed && !node->plugin) + { + /* type is classed and probably even instantiatable */ + G_READ_LOCK (&type_rw_lock); + if (node->data) /* type is static or referenced */ + { + query->type = NODE_TYPE (node); + query->type_name = NODE_NAME (node); + query->class_size = node->data->class.class_size; + query->instance_size = node->is_instantiatable ? node->data->instance.instance_size : 0; + } + G_READ_UNLOCK (&type_rw_lock); + } +} + +/** + * g_type_get_instance_count: + * @type: a #GType + * + * Returns the number of instances allocated of the particular type; + * this is only available if GLib is built with debugging support and + * the instance_count debug flag is set (by setting the GOBJECT_DEBUG + * variable to include instance-count). + * + * Returns: the number of instances allocated of the given type; + * if instance counts are not available, returns 0. + * + * Since: 2.44 + */ +int +g_type_get_instance_count (GType type) +{ +#ifdef G_ENABLE_DEBUG + TypeNode *node; + + node = lookup_type_node_I (type); + g_return_val_if_fail (node != NULL, 0); + + return g_atomic_int_get (&node->instance_count); +#else + return 0; +#endif +} + +/* --- implementation details --- */ +gboolean +g_type_test_flags (GType type, + guint flags) +{ + TypeNode *node; + gboolean result = FALSE; + + node = lookup_type_node_I (type); + if (node) + { + guint fflags = flags & TYPE_FUNDAMENTAL_FLAG_MASK; + guint tflags = flags & TYPE_FLAG_MASK; + + if (fflags) + { + GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (node); + + fflags = (finfo->type_flags & fflags) == fflags; + } + else + fflags = TRUE; + + if (tflags) + { + G_READ_LOCK (&type_rw_lock); + tflags = (tflags & GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))) == tflags; + G_READ_UNLOCK (&type_rw_lock); + } + else + tflags = TRUE; + + result = tflags && fflags; + } + + return result; +} + +/** + * g_type_get_plugin: + * @type: #GType to retrieve the plugin for + * + * Returns the #GTypePlugin structure for @type. + * + * Returns: (transfer none): the corresponding plugin + * if @type is a dynamic type, %NULL otherwise + */ +GTypePlugin* +g_type_get_plugin (GType type) +{ + TypeNode *node; + + node = lookup_type_node_I (type); + + return node ? node->plugin : NULL; +} + +/** + * g_type_interface_get_plugin: + * @instance_type: #GType of an instantiatable type + * @interface_type: #GType of an interface type + * + * Returns the #GTypePlugin structure for the dynamic interface + * @interface_type which has been added to @instance_type, or %NULL + * if @interface_type has not been added to @instance_type or does + * not have a #GTypePlugin structure. See g_type_add_interface_dynamic(). + * + * Returns: (transfer none): the #GTypePlugin for the dynamic + * interface @interface_type of @instance_type + */ +GTypePlugin* +g_type_interface_get_plugin (GType instance_type, + GType interface_type) +{ + TypeNode *node; + TypeNode *iface; + + g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL); /* G_TYPE_IS_INTERFACE() is an external call: _U */ + + node = lookup_type_node_I (instance_type); + iface = lookup_type_node_I (interface_type); + if (node && iface) + { + IFaceHolder *iholder; + GTypePlugin *plugin; + + G_READ_LOCK (&type_rw_lock); + + iholder = iface_node_get_holders_L (iface); + while (iholder && iholder->instance_type != instance_type) + iholder = iholder->next; + plugin = iholder ? iholder->plugin : NULL; + + G_READ_UNLOCK (&type_rw_lock); + + return plugin; + } + + g_return_val_if_fail (node == NULL, NULL); + g_return_val_if_fail (iface == NULL, NULL); + + g_warning (G_STRLOC ": attempt to look up plugin for invalid instance/interface type pair."); + + return NULL; +} + +/** + * g_type_fundamental_next: + * + * Returns the next free fundamental type id which can be used to + * register a new fundamental type with g_type_register_fundamental(). + * The returned type ID represents the highest currently registered + * fundamental type identifier. + * + * Returns: the next available fundamental type ID to be registered, + * or 0 if the type system ran out of fundamental type IDs + */ +GType +g_type_fundamental_next (void) +{ + GType type; + + G_READ_LOCK (&type_rw_lock); + type = static_fundamental_next; + G_READ_UNLOCK (&type_rw_lock); + type = G_TYPE_MAKE_FUNDAMENTAL (type); + return type <= G_TYPE_FUNDAMENTAL_MAX ? type : 0; +} + +/** + * g_type_fundamental: + * @type_id: valid type ID + * + * Internal function, used to extract the fundamental type ID portion. + * Use G_TYPE_FUNDAMENTAL() instead. + * + * Returns: fundamental type ID + */ +GType +g_type_fundamental (GType type_id) +{ + TypeNode *node = lookup_type_node_I (type_id); + + return node ? NODE_FUNDAMENTAL_TYPE (node) : 0; +} + +gboolean +g_type_check_instance_is_a (GTypeInstance *type_instance, + GType iface_type) +{ + TypeNode *node, *iface; + gboolean check; + + if (!type_instance || !type_instance->g_class) + return FALSE; + + node = lookup_type_node_I (type_instance->g_class->g_type); + iface = lookup_type_node_I (iface_type); + check = node && node->is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE); + + return check; +} + +gboolean +g_type_check_instance_is_fundamentally_a (GTypeInstance *type_instance, + GType fundamental_type) +{ + TypeNode *node; + if (!type_instance || !type_instance->g_class) + return FALSE; + node = lookup_type_node_I (type_instance->g_class->g_type); + return node && (NODE_FUNDAMENTAL_TYPE(node) == fundamental_type); +} + +gboolean +g_type_check_class_is_a (GTypeClass *type_class, + GType is_a_type) +{ + TypeNode *node, *iface; + gboolean check; + + if (!type_class) + return FALSE; + + node = lookup_type_node_I (type_class->g_type); + iface = lookup_type_node_I (is_a_type); + check = node && node->is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE); + + return check; +} + +GTypeInstance* +g_type_check_instance_cast (GTypeInstance *type_instance, + GType iface_type) +{ + if (type_instance) + { + if (type_instance->g_class) + { + TypeNode *node, *iface; + gboolean is_instantiatable, check; + + node = lookup_type_node_I (type_instance->g_class->g_type); + is_instantiatable = node && node->is_instantiatable; + iface = lookup_type_node_I (iface_type); + check = is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE); + if (check) + return type_instance; + + if (is_instantiatable) + g_warning ("invalid cast from '%s' to '%s'", + type_descriptive_name_I (type_instance->g_class->g_type), + type_descriptive_name_I (iface_type)); + else + g_warning ("invalid uninstantiatable type '%s' in cast to '%s'", + type_descriptive_name_I (type_instance->g_class->g_type), + type_descriptive_name_I (iface_type)); + } + else + g_warning ("invalid unclassed pointer in cast to '%s'", + type_descriptive_name_I (iface_type)); + } + + return type_instance; +} + +GTypeClass* +g_type_check_class_cast (GTypeClass *type_class, + GType is_a_type) +{ + if (type_class) + { + TypeNode *node, *iface; + gboolean is_classed, check; + + node = lookup_type_node_I (type_class->g_type); + is_classed = node && node->is_classed; + iface = lookup_type_node_I (is_a_type); + check = is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE); + if (check) + return type_class; + + if (is_classed) + g_warning ("invalid class cast from '%s' to '%s'", + type_descriptive_name_I (type_class->g_type), + type_descriptive_name_I (is_a_type)); + else + g_warning ("invalid unclassed type '%s' in class cast to '%s'", + type_descriptive_name_I (type_class->g_type), + type_descriptive_name_I (is_a_type)); + } + else + g_warning ("invalid class cast from (NULL) pointer to '%s'", + type_descriptive_name_I (is_a_type)); + return type_class; +} + +/** + * g_type_check_instance: + * @instance: a valid #GTypeInstance structure + * + * Private helper function to aid implementation of the + * G_TYPE_CHECK_INSTANCE() macro. + * + * Returns: %TRUE if @instance is valid, %FALSE otherwise + */ +gboolean +g_type_check_instance (GTypeInstance *type_instance) +{ + /* this function is just here to make the signal system + * conveniently elaborated on instance checks + */ + if (type_instance) + { + if (type_instance->g_class) + { + TypeNode *node = lookup_type_node_I (type_instance->g_class->g_type); + + if (node && node->is_instantiatable) + return TRUE; + + g_warning ("instance of invalid non-instantiatable type '%s'", + type_descriptive_name_I (type_instance->g_class->g_type)); + } + else + g_warning ("instance with invalid (NULL) class pointer"); + } + else + g_warning ("invalid (NULL) pointer instance"); + + return FALSE; +} + +static inline gboolean +type_check_is_value_type_U (GType type) +{ + GTypeFlags tflags = G_TYPE_FLAG_VALUE_ABSTRACT; + TypeNode *node; + + /* common path speed up */ + node = lookup_type_node_I (type); + if (node && node->mutatable_check_cache) + return TRUE; + + G_READ_LOCK (&type_rw_lock); + restart_check: + if (node) + { + if (node->data && NODE_REFCOUNT (node) > 0 && + node->data->common.value_table->value_init) + tflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags)); + else if (NODE_IS_IFACE (node)) + { + guint i; + + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++) + { + GType prtype = IFACE_NODE_PREREQUISITES (node)[i]; + TypeNode *prnode = lookup_type_node_I (prtype); + + if (prnode->is_instantiatable) + { + type = prtype; + node = lookup_type_node_I (type); + goto restart_check; + } + } + } + } + G_READ_UNLOCK (&type_rw_lock); + + return !(tflags & G_TYPE_FLAG_VALUE_ABSTRACT); +} + +gboolean +g_type_check_is_value_type (GType type) +{ + return type_check_is_value_type_U (type); +} + +gboolean +g_type_check_value (const GValue *value) +{ + return value && type_check_is_value_type_U (value->g_type); +} + +gboolean +g_type_check_value_holds (const GValue *value, + GType type) +{ + return value && type_check_is_value_type_U (value->g_type) && g_type_is_a (value->g_type, type); +} + +/** + * g_type_value_table_peek: (skip) + * @type: a #GType + * + * Returns the location of the #GTypeValueTable associated with @type. + * + * Note that this function should only be used from source code + * that implements or has internal knowledge of the implementation of + * @type. + * + * Returns: location of the #GTypeValueTable associated with @type or + * %NULL if there is no #GTypeValueTable associated with @type + */ +GTypeValueTable* +g_type_value_table_peek (GType type) +{ + GTypeValueTable *vtable = NULL; + TypeNode *node = lookup_type_node_I (type); + gboolean has_refed_data, has_table; + + if (node && NODE_REFCOUNT (node) && node->mutatable_check_cache) + return node->data->common.value_table; + + G_READ_LOCK (&type_rw_lock); + + restart_table_peek: + has_refed_data = node && node->data && NODE_REFCOUNT (node) > 0; + has_table = has_refed_data && node->data->common.value_table->value_init; + if (has_refed_data) + { + if (has_table) + vtable = node->data->common.value_table; + else if (NODE_IS_IFACE (node)) + { + guint i; + + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (node); i++) + { + GType prtype = IFACE_NODE_PREREQUISITES (node)[i]; + TypeNode *prnode = lookup_type_node_I (prtype); + + if (prnode->is_instantiatable) + { + type = prtype; + node = lookup_type_node_I (type); + goto restart_table_peek; + } + } + } + } + + G_READ_UNLOCK (&type_rw_lock); + + if (vtable) + return vtable; + + if (!node) + g_warning (G_STRLOC ": type id '%" G_GSIZE_FORMAT "' is invalid", type); + if (!has_refed_data) + g_warning ("can't peek value table for type '%s' which is not currently referenced", + type_descriptive_name_I (type)); + + return NULL; +} + +const gchar * +g_type_name_from_instance (GTypeInstance *instance) +{ + if (!instance) + return ""; + else + return g_type_name_from_class (instance->g_class); +} + +const gchar * +g_type_name_from_class (GTypeClass *g_class) +{ + if (!g_class) + return ""; + else + return g_type_name (g_class->g_type); +} + + +/* --- private api for gboxed.c --- */ +gpointer +_g_type_boxed_copy (GType type, gpointer value) +{ + TypeNode *node = lookup_type_node_I (type); + + return node->data->boxed.copy_func (value); +} + +void +_g_type_boxed_free (GType type, gpointer value) +{ + TypeNode *node = lookup_type_node_I (type); + + node->data->boxed.free_func (value); +} + +void +_g_type_boxed_init (GType type, + GBoxedCopyFunc copy_func, + GBoxedFreeFunc free_func) +{ + TypeNode *node = lookup_type_node_I (type); + + node->data->boxed.copy_func = copy_func; + node->data->boxed.free_func = free_func; +} + +/* --- initialization --- */ +/** + * g_type_init_with_debug_flags: + * @debug_flags: bitwise combination of #GTypeDebugFlags values for + * debugging purposes + * + * This function used to initialise the type system with debugging + * flags. Since GLib 2.36, the type system is initialised automatically + * and this function does nothing. + * + * If you need to enable debugging features, use the GOBJECT_DEBUG + * environment variable. + * + * Deprecated: 2.36: the type system is now initialised automatically + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +void +g_type_init_with_debug_flags (GTypeDebugFlags debug_flags) +{ + g_assert_type_system_initialized (); + + if (debug_flags) + g_message ("g_type_init_with_debug_flags() is no longer supported. Use the GOBJECT_DEBUG environment variable."); +} +G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * g_type_init: + * + * This function used to initialise the type system. Since GLib 2.36, + * the type system is initialised automatically and this function does + * nothing. + * + * Deprecated: 2.36: the type system is now initialised automatically + */ +void +g_type_init (void) +{ + g_assert_type_system_initialized (); +} + +static void +gobject_init (void) +{ + const gchar *env_string; + GTypeInfo info; + TypeNode *node; + GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + /* Ensure GLib is initialized first, see + * https://bugzilla.gnome.org/show_bug.cgi?id=756139 + */ + GLIB_PRIVATE_CALL (glib_init) (); + + G_WRITE_LOCK (&type_rw_lock); + + /* setup GObject library wide debugging flags */ + env_string = g_getenv ("GOBJECT_DEBUG"); + if (env_string != NULL) + { + GDebugKey debug_keys[] = { + { "objects", G_TYPE_DEBUG_OBJECTS }, + { "instance-count", G_TYPE_DEBUG_INSTANCE_COUNT }, + { "signals", G_TYPE_DEBUG_SIGNALS }, + }; + + _g_type_debug_flags = g_parse_debug_string (env_string, debug_keys, G_N_ELEMENTS (debug_keys)); + } + + /* quarks */ + static_quark_type_flags = g_quark_from_static_string ("-g-type-private--GTypeFlags"); + static_quark_iface_holder = g_quark_from_static_string ("-g-type-private--IFaceHolder"); + static_quark_dependants_array = g_quark_from_static_string ("-g-type-private--dependants-array"); + + /* type qname hash table */ + static_type_nodes_ht = g_hash_table_new (g_str_hash, g_str_equal); + + /* invalid type G_TYPE_INVALID (0) + */ + static_fundamental_type_nodes[0] = NULL; + + /* void type G_TYPE_NONE + */ + node = type_node_fundamental_new_W (G_TYPE_NONE, g_intern_static_string ("void"), 0); + type = NODE_TYPE (node); + g_assert (type == G_TYPE_NONE); + + /* interface fundamental type G_TYPE_INTERFACE (!classed) + */ + memset (&info, 0, sizeof (info)); + node = type_node_fundamental_new_W (G_TYPE_INTERFACE, g_intern_static_string ("GInterface"), G_TYPE_FLAG_DERIVABLE); + type = NODE_TYPE (node); + type_data_make_W (node, &info, NULL); + g_assert (type == G_TYPE_INTERFACE); + + G_WRITE_UNLOCK (&type_rw_lock); + + _g_value_c_init (); + + /* G_TYPE_TYPE_PLUGIN + */ + g_type_ensure (g_type_plugin_get_type ()); + + /* G_TYPE_* value types + */ + _g_value_types_init (); + + /* G_TYPE_ENUM & G_TYPE_FLAGS + */ + _g_enum_types_init (); + + /* G_TYPE_BOXED + */ + _g_boxed_type_init (); + + /* G_TYPE_PARAM + */ + _g_param_type_init (); + + /* G_TYPE_OBJECT + */ + _g_object_type_init (); + + /* G_TYPE_PARAM_* pspec types + */ + _g_param_spec_types_init (); + + /* Value Transformations + */ + _g_value_transforms_init (); + + /* Signal system + */ + _g_signal_init (); +} + +#ifdef G_PLATFORM_WIN32 + +void gobject_win32_init (void); + +void +gobject_win32_init (void) +{ + /* May be called more than once in static compilation mode */ + static gboolean win32_already_init = FALSE; + if (!win32_already_init) + { + win32_already_init = TRUE; + gobject_init (); + } +} + +#ifndef GLIB_STATIC_COMPILATION + +BOOL WINAPI DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved); + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + gobject_win32_init (); + break; + + default: + /* do nothing */ + ; + } + + return TRUE; +} + +#elif defined(G_HAS_CONSTRUCTORS) /* && G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION */ +extern void glib_win32_init (void); + +#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor) +#endif + +G_DEFINE_CONSTRUCTOR(gobject_init_ctor) + +static void +gobject_init_ctor (void) +{ + /* When built dynamically, module initialization is done through DllMain + * function which is called when the dynamic library is loaded by the glib + * module. So, in dynamic configuration glib is always initialized BEFORE + * gobject. + * + * When built statically, initialization mechanism relies on hooking + * functions to the CRT section directly at compilation time. As we don't + * control how each compilation unit will be built and in which order, we + * obtain the same kind of issue as the "static initialization order fiasco". + * In this case, we must ensure explicitly that glib is always well + * initialized BEFORE gobject. + */ + glib_win32_init (); + gobject_win32_init (); +} + +#else /* G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION && !G_HAS_CONSTRUCTORS */ +# error Your platform/compiler is missing constructor support +#endif /* GLIB_STATIC_COMPILATION */ + +#elif defined(G_HAS_CONSTRUCTORS) /* && !G_PLATFORM_WIN32 */ + +#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor) +#endif + +G_DEFINE_CONSTRUCTOR (gobject_init_ctor) + +static void +gobject_init_ctor (void) +{ + gobject_init (); +} + +#else /* !G_PLATFORM_WIN32 && !G_HAS_CONSTRUCTORS */ +#error Your platform/compiler is missing constructor support +#endif /* G_PLATFORM_WIN32 */ + +/** + * g_type_class_add_private: + * @g_class: (type GObject.TypeClass): class structure for an instantiatable + * type + * @private_size: size of private structure + * + * Registers a private structure for an instantiatable type. + * + * When an object is allocated, the private structures for + * the type and all of its parent types are allocated + * sequentially in the same memory block as the public + * structures, and are zero-filled. + * + * Note that the accumulated size of the private structures of + * a type and all its parent types cannot exceed 64 KiB. + * + * This function should be called in the type's class_init() function. + * The private structure can be retrieved using the + * G_TYPE_INSTANCE_GET_PRIVATE() macro. + * + * The following example shows attaching a private structure + * MyObjectPrivate to an object MyObject defined in the standard + * GObject fashion in the type's class_init() function. + * + * Note the use of a structure member "priv" to avoid the overhead + * of repeatedly calling MY_OBJECT_GET_PRIVATE(). + * + * |[ + * typedef struct _MyObject MyObject; + * typedef struct _MyObjectPrivate MyObjectPrivate; + * + * struct _MyObject { + * GObject parent; + * + * MyObjectPrivate *priv; + * }; + * + * struct _MyObjectPrivate { + * int some_field; + * }; + * + * static void + * my_object_class_init (MyObjectClass *klass) + * { + * g_type_class_add_private (klass, sizeof (MyObjectPrivate)); + * } + * + * static void + * my_object_init (MyObject *my_object) + * { + * my_object->priv = G_TYPE_INSTANCE_GET_PRIVATE (my_object, + * MY_TYPE_OBJECT, + * MyObjectPrivate); + * // my_object->priv->some_field will be automatically initialised to 0 + * } + * + * static int + * my_object_get_some_field (MyObject *my_object) + * { + * MyObjectPrivate *priv; + * + * g_return_val_if_fail (MY_IS_OBJECT (my_object), 0); + * + * priv = my_object->priv; + * + * return priv->some_field; + * } + * ]| + * + * Since: 2.4 + * Deprecated: 2.58: Use the G_ADD_PRIVATE() macro with the `G_DEFINE_*` + * family of macros to add instance private data to a type + */ +void +g_type_class_add_private (gpointer g_class, + gsize private_size) +{ + GType instance_type = ((GTypeClass *)g_class)->g_type; + TypeNode *node = lookup_type_node_I (instance_type); + + g_return_if_fail (private_size > 0); + g_return_if_fail (private_size <= 0xffff); + + if (!node || !node->is_instantiatable || !node->data || node->data->class.class != g_class) + { + g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'", + type_descriptive_name_I (instance_type)); + return; + } + + if (NODE_PARENT_TYPE (node)) + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + if (node->data->instance.private_size != pnode->data->instance.private_size) + { + g_warning ("g_type_class_add_private() called multiple times for the same type"); + return; + } + } + + G_WRITE_LOCK (&type_rw_lock); + + private_size = ALIGN_STRUCT (node->data->instance.private_size + private_size); + g_assert (private_size <= 0xffff); + node->data->instance.private_size = private_size; + + G_WRITE_UNLOCK (&type_rw_lock); +} + +/* semi-private, called only by the G_ADD_PRIVATE macro */ +gint +g_type_add_instance_private (GType class_gtype, + gsize private_size) +{ + TypeNode *node = lookup_type_node_I (class_gtype); + + g_return_val_if_fail (private_size > 0, 0); + g_return_val_if_fail (private_size <= 0xffff, 0); + + if (!node || !node->is_classed || !node->is_instantiatable || !node->data) + { + g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'", + type_descriptive_name_I (class_gtype)); + return 0; + } + + if (node->plugin != NULL) + { + g_warning ("cannot use g_type_add_instance_private() with dynamic type '%s'", + type_descriptive_name_I (class_gtype)); + return 0; + } + + /* in the future, we want to register the private data size of a type + * directly from the get_type() implementation so that we can take full + * advantage of the type definition macros that we already have. + * + * unfortunately, this does not behave correctly if a class in the middle + * of the type hierarchy uses the "old style" of private data registration + * from the class_init() implementation, as the private data offset is not + * going to be known until the full class hierarchy is initialized. + * + * in order to transition our code to the Glorious New Futureâ„¢, we proceed + * with a two-step implementation: first, we provide this new function to + * register the private data size in the get_type() implementation and we + * hide it behind a macro. the function will return the private size, instead + * of the offset, which will be stored inside a static variable defined by + * the G_DEFINE_TYPE_EXTENDED() macro. the G_DEFINE_TYPE_EXTENDED() macro will + * check the variable and call g_type_class_add_instance_private(), which + * will use the data size and actually register the private data, then + * return the computed offset of the private data, which will be stored + * inside the static variable, so we can use it to retrieve the pointer + * to the private data structure. + * + * once all our code has been migrated to the new idiomatic form of private + * data registration, we will change the g_type_add_instance_private() + * function to actually perform the registration and return the offset + * of the private data; g_type_class_add_instance_private() already checks + * if the passed argument is negative (meaning that it's an offset in the + * GTypeInstance allocation) and becomes a no-op if that's the case. this + * should make the migration fully transparent even if we're effectively + * copying this macro into everybody's code. + */ + return private_size; +} + +/* semi-private function, should only be used by G_DEFINE_TYPE_EXTENDED */ +void +g_type_class_adjust_private_offset (gpointer g_class, + gint *private_size_or_offset) +{ + GType class_gtype = ((GTypeClass *) g_class)->g_type; + TypeNode *node = lookup_type_node_I (class_gtype); + gssize private_size; + + g_return_if_fail (private_size_or_offset != NULL); + + /* if we have been passed the offset instead of the private data size, + * then we consider this as a no-op, and just return the value. see the + * comment in g_type_add_instance_private() for the full explanation. + */ + if (*private_size_or_offset > 0) + g_return_if_fail (*private_size_or_offset <= 0xffff); + else + return; + + if (!node || !node->is_classed || !node->is_instantiatable || !node->data) + { + g_warning ("cannot add private field to invalid (non-instantiatable) type '%s'", + type_descriptive_name_I (class_gtype)); + *private_size_or_offset = 0; + return; + } + + if (NODE_PARENT_TYPE (node)) + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + if (node->data->instance.private_size != pnode->data->instance.private_size) + { + g_warning ("g_type_add_instance_private() called multiple times for the same type"); + *private_size_or_offset = 0; + return; + } + } + + G_WRITE_LOCK (&type_rw_lock); + + private_size = ALIGN_STRUCT (node->data->instance.private_size + *private_size_or_offset); + g_assert (private_size <= 0xffff); + node->data->instance.private_size = private_size; + + *private_size_or_offset = -(gint) node->data->instance.private_size; + + G_WRITE_UNLOCK (&type_rw_lock); +} + +gpointer +g_type_instance_get_private (GTypeInstance *instance, + GType private_type) +{ + TypeNode *node; + + g_return_val_if_fail (instance != NULL && instance->g_class != NULL, NULL); + + node = lookup_type_node_I (private_type); + if (G_UNLIKELY (!node || !node->is_instantiatable)) + { + g_warning ("instance of invalid non-instantiatable type '%s'", + type_descriptive_name_I (instance->g_class->g_type)); + return NULL; + } + + return ((gchar *) instance) - node->data->instance.private_size; +} + +/** + * g_type_class_get_instance_private_offset: (skip) + * @g_class: (type GObject.TypeClass): a #GTypeClass + * + * Gets the offset of the private data for instances of @g_class. + * + * This is how many bytes you should add to the instance pointer of a + * class in order to get the private data for the type represented by + * @g_class. + * + * You can only call this function after you have registered a private + * data area for @g_class using g_type_class_add_private(). + * + * Returns: the offset, in bytes + * + * Since: 2.38 + **/ +gint +g_type_class_get_instance_private_offset (gpointer g_class) +{ + GType instance_type; + guint16 parent_size; + TypeNode *node; + + g_assert (g_class != NULL); + + instance_type = ((GTypeClass *) g_class)->g_type; + node = lookup_type_node_I (instance_type); + + g_assert (node != NULL); + g_assert (node->is_instantiatable); + + if (NODE_PARENT_TYPE (node)) + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + + parent_size = pnode->data->instance.private_size; + } + else + parent_size = 0; + + if (node->data->instance.private_size == parent_size) + g_error ("g_type_class_get_instance_private_offset() called on class %s but it has no private data", + g_type_name (instance_type)); + + return -(gint) node->data->instance.private_size; +} + +/** + * g_type_add_class_private: + * @class_type: GType of a classed type + * @private_size: size of private structure + * + * Registers a private class structure for a classed type; + * when the class is allocated, the private structures for + * the class and all of its parent types are allocated + * sequentially in the same memory block as the public + * structures, and are zero-filled. + * + * This function should be called in the + * type's get_type() function after the type is registered. + * The private structure can be retrieved using the + * G_TYPE_CLASS_GET_PRIVATE() macro. + * + * Since: 2.24 + */ +void +g_type_add_class_private (GType class_type, + gsize private_size) +{ + TypeNode *node = lookup_type_node_I (class_type); + gsize offset; + + g_return_if_fail (private_size > 0); + + if (!node || !node->is_classed || !node->data) + { + g_warning ("cannot add class private field to invalid type '%s'", + type_descriptive_name_I (class_type)); + return; + } + + if (NODE_PARENT_TYPE (node)) + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + if (node->data->class.class_private_size != pnode->data->class.class_private_size) + { + g_warning ("g_type_add_class_private() called multiple times for the same type"); + return; + } + } + + G_WRITE_LOCK (&type_rw_lock); + + offset = ALIGN_STRUCT (node->data->class.class_private_size); + node->data->class.class_private_size = offset + private_size; + + G_WRITE_UNLOCK (&type_rw_lock); +} + +gpointer +g_type_class_get_private (GTypeClass *klass, + GType private_type) +{ + TypeNode *class_node; + TypeNode *private_node; + TypeNode *parent_node; + gsize offset; + + g_return_val_if_fail (klass != NULL, NULL); + + class_node = lookup_type_node_I (klass->g_type); + if (G_UNLIKELY (!class_node || !class_node->is_classed)) + { + g_warning ("class of invalid type '%s'", + type_descriptive_name_I (klass->g_type)); + return NULL; + } + + private_node = lookup_type_node_I (private_type); + if (G_UNLIKELY (!private_node || !NODE_IS_ANCESTOR (private_node, class_node))) + { + g_warning ("attempt to retrieve private data for invalid type '%s'", + type_descriptive_name_I (private_type)); + return NULL; + } + + offset = ALIGN_STRUCT (class_node->data->class.class_size); + + if (NODE_PARENT_TYPE (private_node)) + { + parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node)); + g_assert (parent_node->data && NODE_REFCOUNT (parent_node) > 0); + + if (G_UNLIKELY (private_node->data->class.class_private_size == parent_node->data->class.class_private_size)) + { + g_warning ("g_type_instance_get_class_private() requires a prior call to g_type_add_class_private()"); + return NULL; + } + + offset += ALIGN_STRUCT (parent_node->data->class.class_private_size); + } + + return G_STRUCT_MEMBER_P (klass, offset); +} + +/** + * g_type_ensure: + * @type: a #GType + * + * Ensures that the indicated @type has been registered with the + * type system, and its _class_init() method has been run. + * + * In theory, simply calling the type's _get_type() method (or using + * the corresponding macro) is supposed take care of this. However, + * _get_type() methods are often marked %G_GNUC_CONST for performance + * reasons, even though this is technically incorrect (since + * %G_GNUC_CONST requires that the function not have side effects, + * which _get_type() methods do on the first call). As a result, if + * you write a bare call to a _get_type() macro, it may get optimized + * out by the compiler. Using g_type_ensure() guarantees that the + * type's _get_type() method is called. + * + * Since: 2.34 + */ +void +g_type_ensure (GType type) +{ + /* In theory, @type has already been resolved and so there's nothing + * to do here. But this protects us in the case where the function + * gets inlined (as it might in gobject_init_ctor() above). + */ + if (G_UNLIKELY (type == (GType)-1)) + g_error ("can't happen"); +} diff --git a/gobject/gtype.h b/gobject/gtype.h new file mode 100644 index 0000000..2aa5e13 --- /dev/null +++ b/gobject/gtype.h @@ -0,0 +1,2515 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_TYPE_H__ +#define __G_TYPE_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* Basic Type Macros + */ +/** + * G_TYPE_FUNDAMENTAL: + * @type: A #GType value. + * + * The fundamental type which is the ancestor of @type. + * + * Fundamental types are types that serve as ultimate bases for the derived types, + * thus they are the roots of distinct inheritance hierarchies. + */ +#define G_TYPE_FUNDAMENTAL(type) (g_type_fundamental (type)) +/** + * G_TYPE_FUNDAMENTAL_MAX: + * + * An integer constant that represents the number of identifiers reserved + * for types that are assigned at compile-time. + */ +#define G_TYPE_FUNDAMENTAL_MAX (255 << G_TYPE_FUNDAMENTAL_SHIFT) + +/* Constant fundamental types, + */ +/** + * G_TYPE_INVALID: + * + * An invalid #GType used as error return value in some functions which return + * a #GType. + */ +#define G_TYPE_INVALID G_TYPE_MAKE_FUNDAMENTAL (0) +/** + * G_TYPE_NONE: + * + * A fundamental type which is used as a replacement for the C + * void return type. + */ +#define G_TYPE_NONE G_TYPE_MAKE_FUNDAMENTAL (1) +/** + * G_TYPE_INTERFACE: + * + * The fundamental type from which all interfaces are derived. + */ +#define G_TYPE_INTERFACE G_TYPE_MAKE_FUNDAMENTAL (2) +/** + * G_TYPE_CHAR: + * + * The fundamental type corresponding to #gchar. + * + * The type designated by %G_TYPE_CHAR is unconditionally an 8-bit signed integer. + * This may or may not be the same type a the C type "gchar". + */ +#define G_TYPE_CHAR G_TYPE_MAKE_FUNDAMENTAL (3) +/** + * G_TYPE_UCHAR: + * + * The fundamental type corresponding to #guchar. + */ +#define G_TYPE_UCHAR G_TYPE_MAKE_FUNDAMENTAL (4) +/** + * G_TYPE_BOOLEAN: + * + * The fundamental type corresponding to #gboolean. + */ +#define G_TYPE_BOOLEAN G_TYPE_MAKE_FUNDAMENTAL (5) +/** + * G_TYPE_INT: + * + * The fundamental type corresponding to #gint. + */ +#define G_TYPE_INT G_TYPE_MAKE_FUNDAMENTAL (6) +/** + * G_TYPE_UINT: + * + * The fundamental type corresponding to #guint. + */ +#define G_TYPE_UINT G_TYPE_MAKE_FUNDAMENTAL (7) +/** + * G_TYPE_LONG: + * + * The fundamental type corresponding to #glong. + */ +#define G_TYPE_LONG G_TYPE_MAKE_FUNDAMENTAL (8) +/** + * G_TYPE_ULONG: + * + * The fundamental type corresponding to #gulong. + */ +#define G_TYPE_ULONG G_TYPE_MAKE_FUNDAMENTAL (9) +/** + * G_TYPE_INT64: + * + * The fundamental type corresponding to #gint64. + */ +#define G_TYPE_INT64 G_TYPE_MAKE_FUNDAMENTAL (10) +/** + * G_TYPE_UINT64: + * + * The fundamental type corresponding to #guint64. + */ +#define G_TYPE_UINT64 G_TYPE_MAKE_FUNDAMENTAL (11) +/** + * G_TYPE_ENUM: + * + * The fundamental type from which all enumeration types are derived. + */ +#define G_TYPE_ENUM G_TYPE_MAKE_FUNDAMENTAL (12) +/** + * G_TYPE_FLAGS: + * + * The fundamental type from which all flags types are derived. + */ +#define G_TYPE_FLAGS G_TYPE_MAKE_FUNDAMENTAL (13) +/** + * G_TYPE_FLOAT: + * + * The fundamental type corresponding to #gfloat. + */ +#define G_TYPE_FLOAT G_TYPE_MAKE_FUNDAMENTAL (14) +/** + * G_TYPE_DOUBLE: + * + * The fundamental type corresponding to #gdouble. + */ +#define G_TYPE_DOUBLE G_TYPE_MAKE_FUNDAMENTAL (15) +/** + * G_TYPE_STRING: + * + * The fundamental type corresponding to nul-terminated C strings. + */ +#define G_TYPE_STRING G_TYPE_MAKE_FUNDAMENTAL (16) +/** + * G_TYPE_POINTER: + * + * The fundamental type corresponding to #gpointer. + */ +#define G_TYPE_POINTER G_TYPE_MAKE_FUNDAMENTAL (17) +/** + * G_TYPE_BOXED: + * + * The fundamental type from which all boxed types are derived. + */ +#define G_TYPE_BOXED G_TYPE_MAKE_FUNDAMENTAL (18) +/** + * G_TYPE_PARAM: + * + * The fundamental type from which all #GParamSpec types are derived. + */ +#define G_TYPE_PARAM G_TYPE_MAKE_FUNDAMENTAL (19) +/** + * G_TYPE_OBJECT: + * + * The fundamental type for #GObject. + */ +#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20) +/** + * G_TYPE_VARIANT: + * + * The fundamental type corresponding to #GVariant. + * + * All floating #GVariant instances passed through the #GType system are + * consumed. + * + * Note that callbacks in closures, and signal handlers + * for signals of return type %G_TYPE_VARIANT, must never return floating + * variants. + * + * Note: GLib 2.24 did include a boxed type with this name. It was replaced + * with this fundamental type in 2.26. + * + * Since: 2.26 + */ +#define G_TYPE_VARIANT G_TYPE_MAKE_FUNDAMENTAL (21) + + +/* Reserved fundamental type numbers to create new fundamental + * type IDs with G_TYPE_MAKE_FUNDAMENTAL(). + * + * Open an issue on https://gitlab.gnome.org/GNOME/glib/issues/new for + * reservations. + */ +/** + * G_TYPE_FUNDAMENTAL_SHIFT: + * + * Shift value used in converting numbers to type IDs. + */ +#define G_TYPE_FUNDAMENTAL_SHIFT (2) +/** + * G_TYPE_MAKE_FUNDAMENTAL: + * @x: the fundamental type number. + * + * Get the type ID for the fundamental type number @x. + * + * Use g_type_fundamental_next() instead of this macro to create new fundamental + * types. + * + * Returns: the GType + */ +#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT)) +/** + * G_TYPE_RESERVED_GLIB_FIRST: + * + * First fundamental type number to create a new fundamental type id with + * G_TYPE_MAKE_FUNDAMENTAL() reserved for GLib. + */ +#define G_TYPE_RESERVED_GLIB_FIRST (22) +/** + * G_TYPE_RESERVED_GLIB_LAST: + * + * Last fundamental type number reserved for GLib. + */ +#define G_TYPE_RESERVED_GLIB_LAST (31) +/** + * G_TYPE_RESERVED_BSE_FIRST: + * + * First fundamental type number to create a new fundamental type id with + * G_TYPE_MAKE_FUNDAMENTAL() reserved for BSE. + */ +#define G_TYPE_RESERVED_BSE_FIRST (32) +/** + * G_TYPE_RESERVED_BSE_LAST: + * + * Last fundamental type number reserved for BSE. + */ +#define G_TYPE_RESERVED_BSE_LAST (48) +/** + * G_TYPE_RESERVED_USER_FIRST: + * + * First available fundamental type number to create new fundamental + * type id with G_TYPE_MAKE_FUNDAMENTAL(). + */ +#define G_TYPE_RESERVED_USER_FIRST (49) + + +/* Type Checking Macros + */ +/** + * G_TYPE_IS_FUNDAMENTAL: + * @type: A #GType value + * + * Checks if @type is a fundamental type. + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_FUNDAMENTAL(type) ((type) <= G_TYPE_FUNDAMENTAL_MAX) +/** + * G_TYPE_IS_DERIVED: + * @type: A #GType value + * + * Checks if @type is derived (or in object-oriented terminology: + * inherited) from another type (this holds true for all non-fundamental + * types). + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_DERIVED(type) ((type) > G_TYPE_FUNDAMENTAL_MAX) +/** + * G_TYPE_IS_INTERFACE: + * @type: A #GType value + * + * Checks if @type is an interface type. + * + * An interface type provides a pure API, the implementation + * of which is provided by another type (which is then said to conform + * to the interface). GLib interfaces are somewhat analogous to Java + * interfaces and C++ classes containing only pure virtual functions, + * with the difference that GType interfaces are not derivable (but see + * g_type_interface_add_prerequisite() for an alternative). + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_INTERFACE(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_INTERFACE) +/** + * G_TYPE_IS_CLASSED: + * @type: A #GType value + * + * Checks if @type is a classed type. + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_CLASSED(type) (g_type_test_flags ((type), G_TYPE_FLAG_CLASSED)) +/** + * G_TYPE_IS_INSTANTIATABLE: + * @type: A #GType value + * + * Checks if @type can be instantiated. Instantiation is the + * process of creating an instance (object) of this type. + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_INSTANTIATABLE(type) (g_type_test_flags ((type), G_TYPE_FLAG_INSTANTIATABLE)) +/** + * G_TYPE_IS_DERIVABLE: + * @type: A #GType value + * + * Checks if @type is a derivable type. A derivable type can + * be used as the base class of a flat (single-level) class hierarchy. + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_DERIVABLE(type) (g_type_test_flags ((type), G_TYPE_FLAG_DERIVABLE)) +/** + * G_TYPE_IS_DEEP_DERIVABLE: + * @type: A #GType value + * + * Checks if @type is a deep derivable type. A deep derivable type + * can be used as the base class of a deep (multi-level) class hierarchy. + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_DEEP_DERIVABLE(type) (g_type_test_flags ((type), G_TYPE_FLAG_DEEP_DERIVABLE)) +/** + * G_TYPE_IS_ABSTRACT: + * @type: A #GType value + * + * Checks if @type is an abstract type. An abstract type cannot be + * instantiated and is normally used as an abstract base class for + * derived classes. + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_ABSTRACT(type) (g_type_test_flags ((type), G_TYPE_FLAG_ABSTRACT)) +/** + * G_TYPE_IS_VALUE_ABSTRACT: + * @type: A #GType value + * + * Checks if @type is an abstract value type. An abstract value type introduces + * a value table, but can't be used for g_value_init() and is normally used as + * an abstract base type for derived value types. + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_VALUE_ABSTRACT(type) (g_type_test_flags ((type), G_TYPE_FLAG_VALUE_ABSTRACT)) +/** + * G_TYPE_IS_VALUE_TYPE: + * @type: A #GType value + * + * Checks if @type is a value type and can be used with g_value_init(). + * + * Returns: %TRUE on success + */ +#define G_TYPE_IS_VALUE_TYPE(type) (g_type_check_is_value_type (type)) +/** + * G_TYPE_HAS_VALUE_TABLE: + * @type: A #GType value + * + * Checks if @type has a #GTypeValueTable. + * + * Returns: %TRUE on success + */ +#define G_TYPE_HAS_VALUE_TABLE(type) (g_type_value_table_peek (type) != NULL) +/** + * G_TYPE_IS_FINAL: + * @type: a #GType value + * + * Checks if @type is a final type. A final type cannot be derived any + * further. + * + * Returns: %TRUE on success + * + * Since: 2.70 + */ +#define G_TYPE_IS_FINAL(type) (g_type_test_flags ((type), G_TYPE_FLAG_FINAL)) GLIB_AVAILABLE_MACRO_IN_2_70 + + +/* Typedefs + */ +/** + * GType: + * + * A numerical value which represents the unique identifier of a registered + * type. + */ +#if GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG || !defined __cplusplus +typedef gsize GType; +#else /* for historic reasons, C++ links against gulong GTypes */ +typedef gulong GType; +#endif +typedef struct _GValue GValue; +typedef union _GTypeCValue GTypeCValue; +typedef struct _GTypePlugin GTypePlugin; +typedef struct _GTypeClass GTypeClass; +typedef struct _GTypeInterface GTypeInterface; +typedef struct _GTypeInstance GTypeInstance; +typedef struct _GTypeInfo GTypeInfo; +typedef struct _GTypeFundamentalInfo GTypeFundamentalInfo; +typedef struct _GInterfaceInfo GInterfaceInfo; +typedef struct _GTypeValueTable GTypeValueTable; +typedef struct _GTypeQuery GTypeQuery; + + +/* Basic Type Structures + */ +/** + * GTypeClass: + * + * An opaque structure used as the base of all classes. + */ +struct _GTypeClass +{ + /*< private >*/ + GType g_type; +}; +/** + * GTypeInstance: + * + * An opaque structure used as the base of all type instances. + */ +struct _GTypeInstance +{ + /*< private >*/ + GTypeClass *g_class; +}; +/** + * GTypeInterface: + * + * An opaque structure used as the base of all interface types. + */ +struct _GTypeInterface +{ + /*< private >*/ + GType g_type; /* iface type */ + GType g_instance_type; +}; +/** + * GTypeQuery: + * @type: the #GType value of the type + * @type_name: the name of the type + * @class_size: the size of the class structure + * @instance_size: the size of the instance structure + * + * A structure holding information for a specific type. + * + * See also: g_type_query() + */ +struct _GTypeQuery +{ + GType type; + const gchar *type_name; + guint class_size; + guint instance_size; +}; + + +/* Casts, checks and accessors for structured types + * usage of these macros is reserved to type implementations only + */ +/*< protected >*/ +/** + * G_TYPE_CHECK_INSTANCE: + * @instance: Location of a #GTypeInstance structure + * + * Checks if @instance is a valid #GTypeInstance structure, + * otherwise issues a warning and returns %FALSE. %NULL is not a valid + * #GTypeInstance. + * + * This macro should only be used in type implementations. + * + * Returns: %TRUE on success + */ +#define G_TYPE_CHECK_INSTANCE(instance) (_G_TYPE_CHI ((GTypeInstance*) (instance))) +/** + * G_TYPE_CHECK_INSTANCE_CAST: + * @instance: (nullable): Location of a #GTypeInstance structure + * @g_type: The type to be returned + * @c_type: The corresponding C type of @g_type + * + * Checks that @instance is an instance of the type identified by @g_type + * and issues a warning if this is not the case. Returns @instance casted + * to a pointer to @c_type. + * + * No warning will be issued if @instance is %NULL, and %NULL will be returned. + * + * This macro should only be used in type implementations. + */ +#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type)) +/** + * G_TYPE_CHECK_INSTANCE_TYPE: + * @instance: (nullable): Location of a #GTypeInstance structure. + * @g_type: The type to be checked + * + * Checks if @instance is an instance of the type identified by @g_type. If + * @instance is %NULL, %FALSE will be returned. + * + * This macro should only be used in type implementations. + * + * Returns: %TRUE on success + */ +#define G_TYPE_CHECK_INSTANCE_TYPE(instance, g_type) (_G_TYPE_CIT ((instance), (g_type))) +/** + * G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE: + * @instance: (nullable): Location of a #GTypeInstance structure. + * @g_type: The fundamental type to be checked + * + * Checks if @instance is an instance of the fundamental type identified by @g_type. + * If @instance is %NULL, %FALSE will be returned. + * + * This macro should only be used in type implementations. + * + * Returns: %TRUE on success + */ +#define G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE(instance, g_type) (_G_TYPE_CIFT ((instance), (g_type))) +/** + * G_TYPE_INSTANCE_GET_CLASS: + * @instance: Location of the #GTypeInstance structure + * @g_type: The #GType of the class to be returned + * @c_type: The C type of the class structure + * + * Get the class structure of a given @instance, casted + * to a specified ancestor type @g_type of the instance. + * + * Note that while calling a GInstanceInitFunc(), the class pointer + * gets modified, so it might not always return the expected pointer. + * + * This macro should only be used in type implementations. + * + * Returns: a pointer to the class structure + */ +#define G_TYPE_INSTANCE_GET_CLASS(instance, g_type, c_type) (_G_TYPE_IGC ((instance), (g_type), c_type)) +/** + * G_TYPE_INSTANCE_GET_INTERFACE: + * @instance: Location of the #GTypeInstance structure + * @g_type: The #GType of the interface to be returned + * @c_type: The C type of the interface structure + * + * Get the interface structure for interface @g_type of a given @instance. + * + * This macro should only be used in type implementations. + * + * Returns: a pointer to the interface structure + */ +#define G_TYPE_INSTANCE_GET_INTERFACE(instance, g_type, c_type) (_G_TYPE_IGI ((instance), (g_type), c_type)) +/** + * G_TYPE_CHECK_CLASS_CAST: + * @g_class: Location of a #GTypeClass structure + * @g_type: The type to be returned + * @c_type: The corresponding C type of class structure of @g_type + * + * Checks that @g_class is a class structure of the type identified by @g_type + * and issues a warning if this is not the case. Returns @g_class casted + * to a pointer to @c_type. %NULL is not a valid class structure. + * + * This macro should only be used in type implementations. + */ +#define G_TYPE_CHECK_CLASS_CAST(g_class, g_type, c_type) (_G_TYPE_CCC ((g_class), (g_type), c_type)) +/** + * G_TYPE_CHECK_CLASS_TYPE: + * @g_class: (nullable): Location of a #GTypeClass structure + * @g_type: The type to be checked + * + * Checks if @g_class is a class structure of the type identified by + * @g_type. If @g_class is %NULL, %FALSE will be returned. + * + * This macro should only be used in type implementations. + * + * Returns: %TRUE on success + */ +#define G_TYPE_CHECK_CLASS_TYPE(g_class, g_type) (_G_TYPE_CCT ((g_class), (g_type))) +/** + * G_TYPE_CHECK_VALUE: + * @value: a #GValue + * + * Checks if @value has been initialized to hold values + * of a value type. + * + * This macro should only be used in type implementations. + * + * Returns: %TRUE on success + */ +#define G_TYPE_CHECK_VALUE(value) (_G_TYPE_CHV ((value))) +/** + * G_TYPE_CHECK_VALUE_TYPE: + * @value: a #GValue + * @g_type: The type to be checked + * + * Checks if @value has been initialized to hold values + * of type @g_type. + * + * This macro should only be used in type implementations. + * + * Returns: %TRUE on success + */ +#define G_TYPE_CHECK_VALUE_TYPE(value, g_type) (_G_TYPE_CVH ((value), (g_type))) +/** + * G_TYPE_FROM_INSTANCE: + * @instance: Location of a valid #GTypeInstance structure + * + * Get the type identifier from a given @instance structure. + * + * This macro should only be used in type implementations. + * + * Returns: the #GType + */ +#define G_TYPE_FROM_INSTANCE(instance) (G_TYPE_FROM_CLASS (((GTypeInstance*) (instance))->g_class)) +/** + * G_TYPE_FROM_CLASS: + * @g_class: Location of a valid #GTypeClass structure + * + * Get the type identifier from a given @class structure. + * + * This macro should only be used in type implementations. + * + * Returns: the #GType + */ +#define G_TYPE_FROM_CLASS(g_class) (((GTypeClass*) (g_class))->g_type) +/** + * G_TYPE_FROM_INTERFACE: + * @g_iface: Location of a valid #GTypeInterface structure + * + * Get the type identifier from a given @interface structure. + * + * This macro should only be used in type implementations. + * + * Returns: the #GType + */ +#define G_TYPE_FROM_INTERFACE(g_iface) (((GTypeInterface*) (g_iface))->g_type) + +/** + * G_TYPE_INSTANCE_GET_PRIVATE: + * @instance: the instance of a type deriving from @private_type + * @g_type: the type identifying which private data to retrieve + * @c_type: The C type for the private structure + * + * Gets the private structure for a particular type. + * + * The private structure must have been registered in the + * class_init function with g_type_class_add_private(). + * + * This macro should only be used in type implementations. + * + * Since: 2.4 + * Deprecated: 2.58: Use G_ADD_PRIVATE() and the generated + * `your_type_get_instance_private()` function instead + * Returns: (not nullable): a pointer to the private data structure + */ +#define G_TYPE_INSTANCE_GET_PRIVATE(instance, g_type, c_type) ((c_type*) g_type_instance_get_private ((GTypeInstance*) (instance), (g_type))) GLIB_DEPRECATED_MACRO_IN_2_58_FOR(G_ADD_PRIVATE) + +/** + * G_TYPE_CLASS_GET_PRIVATE: + * @klass: the class of a type deriving from @private_type + * @g_type: the type identifying which private data to retrieve + * @c_type: The C type for the private structure + * + * Gets the private class structure for a particular type. + * + * The private structure must have been registered in the + * get_type() function with g_type_add_class_private(). + * + * This macro should only be used in type implementations. + * + * Since: 2.24 + * Returns: (not nullable): a pointer to the private data structure + */ +#define G_TYPE_CLASS_GET_PRIVATE(klass, g_type, c_type) ((c_type*) g_type_class_get_private ((GTypeClass*) (klass), (g_type))) + +/** + * GTypeDebugFlags: + * @G_TYPE_DEBUG_NONE: Print no messages + * @G_TYPE_DEBUG_OBJECTS: Print messages about object bookkeeping + * @G_TYPE_DEBUG_SIGNALS: Print messages about signal emissions + * @G_TYPE_DEBUG_MASK: Mask covering all debug flags + * @G_TYPE_DEBUG_INSTANCE_COUNT: Keep a count of instances of each type + * + * These flags used to be passed to g_type_init_with_debug_flags() which + * is now deprecated. + * + * If you need to enable debugging features, use the GOBJECT_DEBUG + * environment variable. + * + * Deprecated: 2.36: g_type_init() is now done automatically + */ +typedef enum /*< skip >*/ +{ + G_TYPE_DEBUG_NONE = 0, + G_TYPE_DEBUG_OBJECTS = 1 << 0, + G_TYPE_DEBUG_SIGNALS = 1 << 1, + G_TYPE_DEBUG_INSTANCE_COUNT = 1 << 2, + G_TYPE_DEBUG_MASK = 0x07 +} GTypeDebugFlags GLIB_DEPRECATED_TYPE_IN_2_36; + + +/* --- prototypes --- */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +GLIB_DEPRECATED_IN_2_36 +void g_type_init (void); +GLIB_DEPRECATED_IN_2_36 +void g_type_init_with_debug_flags (GTypeDebugFlags debug_flags); +G_GNUC_END_IGNORE_DEPRECATIONS + +GLIB_AVAILABLE_IN_ALL +const gchar * g_type_name (GType type); +GLIB_AVAILABLE_IN_ALL +GQuark g_type_qname (GType type); +GLIB_AVAILABLE_IN_ALL +GType g_type_from_name (const gchar *name); +GLIB_AVAILABLE_IN_ALL +GType g_type_parent (GType type); +GLIB_AVAILABLE_IN_ALL +guint g_type_depth (GType type); +GLIB_AVAILABLE_IN_ALL +GType g_type_next_base (GType leaf_type, + GType root_type); +GLIB_AVAILABLE_IN_ALL +gboolean g_type_is_a (GType type, + GType is_a_type); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_class_ref (GType type); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_class_peek (GType type); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_class_peek_static (GType type); +GLIB_AVAILABLE_IN_ALL +void g_type_class_unref (gpointer g_class); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_class_peek_parent (gpointer g_class); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_interface_peek (gpointer instance_class, + GType iface_type); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_interface_peek_parent (gpointer g_iface); + +GLIB_AVAILABLE_IN_ALL +gpointer g_type_default_interface_ref (GType g_type); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_default_interface_peek (GType g_type); +GLIB_AVAILABLE_IN_ALL +void g_type_default_interface_unref (gpointer g_iface); + +/* g_free() the returned arrays */ +GLIB_AVAILABLE_IN_ALL +GType* g_type_children (GType type, + guint *n_children); +GLIB_AVAILABLE_IN_ALL +GType* g_type_interfaces (GType type, + guint *n_interfaces); + +/* per-type _static_ data */ +GLIB_AVAILABLE_IN_ALL +void g_type_set_qdata (GType type, + GQuark quark, + gpointer data); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_get_qdata (GType type, + GQuark quark); +GLIB_AVAILABLE_IN_ALL +void g_type_query (GType type, + GTypeQuery *query); + +GLIB_AVAILABLE_IN_2_44 +int g_type_get_instance_count (GType type); + +/* --- type registration --- */ +/** + * GBaseInitFunc: + * @g_class: (type GObject.TypeClass): The #GTypeClass structure to initialize + * + * A callback function used by the type system to do base initialization + * of the class structures of derived types. + * + * This function is called as part of the initialization process of all derived + * classes and should reallocate or reset all dynamic class members copied over + * from the parent class. + * + * For example, class members (such as strings) that are not sufficiently + * handled by a plain memory copy of the parent class into the derived class + * have to be altered. See GClassInitFunc() for a discussion of the class + * initialization process. + */ +typedef void (*GBaseInitFunc) (gpointer g_class); +/** + * GBaseFinalizeFunc: + * @g_class: (type GObject.TypeClass): The #GTypeClass structure to finalize + * + * A callback function used by the type system to finalize those portions + * of a derived types class structure that were setup from the corresponding + * GBaseInitFunc() function. + * + * Class finalization basically works the inverse way in which class + * initialization is performed. + * + * See GClassInitFunc() for a discussion of the class initialization process. + */ +typedef void (*GBaseFinalizeFunc) (gpointer g_class); +/** + * GClassInitFunc: + * @g_class: (type GObject.TypeClass): The #GTypeClass structure to initialize. + * @class_data: The @class_data member supplied via the #GTypeInfo structure. + * + * A callback function used by the type system to initialize the class + * of a specific type. + * + * This function should initialize all static class members. + * + * The initialization process of a class involves: + * + * - Copying common members from the parent class over to the + * derived class structure. + * - Zero initialization of the remaining members not copied + * over from the parent class. + * - Invocation of the GBaseInitFunc() initializers of all parent + * types and the class' type. + * - Invocation of the class' GClassInitFunc() initializer. + * + * Since derived classes are partially initialized through a memory copy + * of the parent class, the general rule is that GBaseInitFunc() and + * GBaseFinalizeFunc() should take care of necessary reinitialization + * and release of those class members that were introduced by the type + * that specified these GBaseInitFunc()/GBaseFinalizeFunc(). + * GClassInitFunc() should only care about initializing static + * class members, while dynamic class members (such as allocated strings + * or reference counted resources) are better handled by a GBaseInitFunc() + * for this type, so proper initialization of the dynamic class members + * is performed for class initialization of derived types as well. + * + * An example may help to correspond the intend of the different class + * initializers: + * + * |[ + * typedef struct { + * GObjectClass parent_class; + * gint static_integer; + * gchar *dynamic_string; + * } TypeAClass; + * static void + * type_a_base_class_init (TypeAClass *class) + * { + * class->dynamic_string = g_strdup ("some string"); + * } + * static void + * type_a_base_class_finalize (TypeAClass *class) + * { + * g_free (class->dynamic_string); + * } + * static void + * type_a_class_init (TypeAClass *class) + * { + * class->static_integer = 42; + * } + * + * typedef struct { + * TypeAClass parent_class; + * gfloat static_float; + * GString *dynamic_gstring; + * } TypeBClass; + * static void + * type_b_base_class_init (TypeBClass *class) + * { + * class->dynamic_gstring = g_string_new ("some other string"); + * } + * static void + * type_b_base_class_finalize (TypeBClass *class) + * { + * g_string_free (class->dynamic_gstring); + * } + * static void + * type_b_class_init (TypeBClass *class) + * { + * class->static_float = 3.14159265358979323846; + * } + * ]| + * + * Initialization of TypeBClass will first cause initialization of + * TypeAClass (derived classes reference their parent classes, see + * g_type_class_ref() on this). + * + * Initialization of TypeAClass roughly involves zero-initializing its fields, + * then calling its GBaseInitFunc() type_a_base_class_init() to allocate + * its dynamic members (dynamic_string), and finally calling its GClassInitFunc() + * type_a_class_init() to initialize its static members (static_integer). + * The first step in the initialization process of TypeBClass is then + * a plain memory copy of the contents of TypeAClass into TypeBClass and + * zero-initialization of the remaining fields in TypeBClass. + * The dynamic members of TypeAClass within TypeBClass now need + * reinitialization which is performed by calling type_a_base_class_init() + * with an argument of TypeBClass. + * + * After that, the GBaseInitFunc() of TypeBClass, type_b_base_class_init() + * is called to allocate the dynamic members of TypeBClass (dynamic_gstring), + * and finally the GClassInitFunc() of TypeBClass, type_b_class_init(), + * is called to complete the initialization process with the static members + * (static_float). + * + * Corresponding finalization counter parts to the GBaseInitFunc() functions + * have to be provided to release allocated resources at class finalization + * time. + */ +typedef void (*GClassInitFunc) (gpointer g_class, + gpointer class_data); +/** + * GClassFinalizeFunc: + * @g_class: (type GObject.TypeClass): The #GTypeClass structure to finalize + * @class_data: The @class_data member supplied via the #GTypeInfo structure + * + * A callback function used by the type system to finalize a class. + * + * This function is rarely needed, as dynamically allocated class resources + * should be handled by GBaseInitFunc() and GBaseFinalizeFunc(). + * + * Also, specification of a GClassFinalizeFunc() in the #GTypeInfo + * structure of a static type is invalid, because classes of static types + * will never be finalized (they are artificially kept alive when their + * reference count drops to zero). + */ +typedef void (*GClassFinalizeFunc) (gpointer g_class, + gpointer class_data); +/** + * GInstanceInitFunc: + * @instance: The instance to initialize + * @g_class: (type GObject.TypeClass): The class of the type the instance is + * created for + * + * A callback function used by the type system to initialize a new + * instance of a type. + * + * This function initializes all instance members and allocates any resources + * required by it. + * + * Initialization of a derived instance involves calling all its parent + * types instance initializers, so the class member of the instance + * is altered during its initialization to always point to the class that + * belongs to the type the current initializer was introduced for. + * + * The extended members of @instance are guaranteed to have been filled with + * zeros before this function is called. + */ +typedef void (*GInstanceInitFunc) (GTypeInstance *instance, + gpointer g_class); +/** + * GInterfaceInitFunc: + * @g_iface: (type GObject.TypeInterface): The interface structure to initialize + * @iface_data: The @interface_data supplied via the #GInterfaceInfo structure + * + * A callback function used by the type system to initialize a new + * interface. + * + * This function should initialize all internal data and* allocate any + * resources required by the interface. + * + * The members of @iface_data are guaranteed to have been filled with + * zeros before this function is called. + */ +typedef void (*GInterfaceInitFunc) (gpointer g_iface, + gpointer iface_data); +/** + * GInterfaceFinalizeFunc: + * @g_iface: (type GObject.TypeInterface): The interface structure to finalize + * @iface_data: The @interface_data supplied via the #GInterfaceInfo structure + * + * A callback function used by the type system to finalize an interface. + * + * This function should destroy any internal data and release any resources + * allocated by the corresponding GInterfaceInitFunc() function. + */ +typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface, + gpointer iface_data); +/** + * GTypeClassCacheFunc: + * @cache_data: data that was given to the g_type_add_class_cache_func() call + * @g_class: (type GObject.TypeClass): The #GTypeClass structure which is + * unreferenced + * + * A callback function which is called when the reference count of a class + * drops to zero. + * + * It may use g_type_class_ref() to prevent the class from being freed. You + * should not call g_type_class_unref() from a #GTypeClassCacheFunc function + * to prevent infinite recursion, use g_type_class_unref_uncached() instead. + * + * The functions have to check the class id passed in to figure + * whether they actually want to cache the class of this type, since all + * classes are routed through the same #GTypeClassCacheFunc chain. + * + * Returns: %TRUE to stop further #GTypeClassCacheFuncs from being + * called, %FALSE to continue + */ +typedef gboolean (*GTypeClassCacheFunc) (gpointer cache_data, + GTypeClass *g_class); +/** + * GTypeInterfaceCheckFunc: + * @check_data: data passed to g_type_add_interface_check() + * @g_iface: (type GObject.TypeInterface): the interface that has been + * initialized + * + * A callback called after an interface vtable is initialized. + * + * See g_type_add_interface_check(). + * + * Since: 2.4 + */ +typedef void (*GTypeInterfaceCheckFunc) (gpointer check_data, + gpointer g_iface); +/** + * GTypeFundamentalFlags: + * @G_TYPE_FLAG_CLASSED: Indicates a classed type + * @G_TYPE_FLAG_INSTANTIATABLE: Indicates an instantiatable type (implies classed) + * @G_TYPE_FLAG_DERIVABLE: Indicates a flat derivable type + * @G_TYPE_FLAG_DEEP_DERIVABLE: Indicates a deep derivable type (implies derivable) + * + * Bit masks used to check or determine specific characteristics of a + * fundamental type. + */ +typedef enum /*< skip >*/ +{ + G_TYPE_FLAG_CLASSED = (1 << 0), + G_TYPE_FLAG_INSTANTIATABLE = (1 << 1), + G_TYPE_FLAG_DERIVABLE = (1 << 2), + G_TYPE_FLAG_DEEP_DERIVABLE = (1 << 3) +} GTypeFundamentalFlags; +/** + * GTypeFlags: + * @G_TYPE_FLAG_ABSTRACT: Indicates an abstract type. No instances can be + * created for an abstract type + * @G_TYPE_FLAG_VALUE_ABSTRACT: Indicates an abstract value type, i.e. a type + * that introduces a value table, but can't be used for + * g_value_init() + * @G_TYPE_FLAG_FINAL: Indicates a final type. A final type is a non-derivable + * leaf node in a deep derivable type hierarchy tree. Since: 2.70 + * + * Bit masks used to check or determine characteristics of a type. + */ +typedef enum /*< skip >*/ +{ + G_TYPE_FLAG_ABSTRACT = (1 << 4), + G_TYPE_FLAG_VALUE_ABSTRACT = (1 << 5), + G_TYPE_FLAG_FINAL GLIB_AVAILABLE_ENUMERATOR_IN_2_70 = (1 << 6) +} GTypeFlags; +/** + * GTypeInfo: + * @class_size: Size of the class structure (required for interface, classed and instantiatable types) + * @base_init: Location of the base initialization function (optional) + * @base_finalize: Location of the base finalization function (optional) + * @class_init: Location of the class initialization function for + * classed and instantiatable types. Location of the default vtable + * inititalization function for interface types. (optional) This function + * is used both to fill in virtual functions in the class or default vtable, + * and to do type-specific setup such as registering signals and object + * properties. + * @class_finalize: Location of the class finalization function for + * classed and instantiatable types. Location of the default vtable + * finalization function for interface types. (optional) + * @class_data: User-supplied data passed to the class init/finalize functions + * @instance_size: Size of the instance (object) structure (required for instantiatable types only) + * @n_preallocs: Prior to GLib 2.10, it specified the number of pre-allocated (cached) instances to reserve memory for (0 indicates no caching). Since GLib 2.10, it is ignored, since instances are allocated with the [slice allocator][glib-Memory-Slices] now. + * @instance_init: Location of the instance initialization function (optional, for instantiatable types only) + * @value_table: A #GTypeValueTable function table for generic handling of GValues + * of this type (usually only useful for fundamental types) + * + * This structure is used to provide the type system with the information + * required to initialize and destruct (finalize) a type's class and + * its instances. + * + * The initialized structure is passed to the g_type_register_static() function + * (or is copied into the provided #GTypeInfo structure in the + * g_type_plugin_complete_type_info()). The type system will perform a deep + * copy of this structure, so its memory does not need to be persistent + * across invocation of g_type_register_static(). + */ +struct _GTypeInfo +{ + /* interface types, classed types, instantiated types */ + guint16 class_size; + + GBaseInitFunc base_init; + GBaseFinalizeFunc base_finalize; + + /* interface types, classed types, instantiated types */ + GClassInitFunc class_init; + GClassFinalizeFunc class_finalize; + gconstpointer class_data; + + /* instantiated types */ + guint16 instance_size; + guint16 n_preallocs; + GInstanceInitFunc instance_init; + + /* value handling */ + const GTypeValueTable *value_table; +}; +/** + * GTypeFundamentalInfo: + * @type_flags: #GTypeFundamentalFlags describing the characteristics of the fundamental type + * + * A structure that provides information to the type system which is + * used specifically for managing fundamental types. + */ +struct _GTypeFundamentalInfo +{ + GTypeFundamentalFlags type_flags; +}; +/** + * GInterfaceInfo: + * @interface_init: location of the interface initialization function + * @interface_finalize: location of the interface finalization function + * @interface_data: user-supplied data passed to the interface init/finalize functions + * + * A structure that provides information to the type system which is + * used specifically for managing interface types. + */ +struct _GInterfaceInfo +{ + GInterfaceInitFunc interface_init; + GInterfaceFinalizeFunc interface_finalize; + gpointer interface_data; +}; +/** + * GTypeValueTable: + * @value_init: Default initialize @values contents by poking values + * directly into the value->data array. The data array of + * the #GValue passed into this function was zero-filled + * with `memset()`, so no care has to be taken to free any + * old contents. E.g. for the implementation of a string + * value that may never be %NULL, the implementation might + * look like: + * |[ + * value->data[0].v_pointer = g_strdup (""); + * ]| + * @value_free: Free any old contents that might be left in the + * data array of the passed in @value. No resources may + * remain allocated through the #GValue contents after + * this function returns. E.g. for our above string type: + * |[ + * // only free strings without a specific flag for static storage + * if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) + * g_free (value->data[0].v_pointer); + * ]| + * @value_copy: @dest_value is a #GValue with zero-filled data section + * and @src_value is a properly setup #GValue of same or + * derived type. + * The purpose of this function is to copy the contents of + * @src_value into @dest_value in a way, that even after + * @src_value has been freed, the contents of @dest_value + * remain valid. String type example: + * |[ + * dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer); + * ]| + * @value_peek_pointer: If the value contents fit into a pointer, such as objects + * or strings, return this pointer, so the caller can peek at + * the current contents. To extend on our above string example: + * |[ + * return value->data[0].v_pointer; + * ]| + * @collect_format: A string format describing how to collect the contents of + * this value bit-by-bit. Each character in the format represents + * an argument to be collected, and the characters themselves indicate + * the type of the argument. Currently supported arguments are: + * - 'i' - Integers. passed as collect_values[].v_int. + * - 'l' - Longs. passed as collect_values[].v_long. + * - 'd' - Doubles. passed as collect_values[].v_double. + * - 'p' - Pointers. passed as collect_values[].v_pointer. + * It should be noted that for variable argument list construction, + * ANSI C promotes every type smaller than an integer to an int, and + * floats to doubles. So for collection of short int or char, 'i' + * needs to be used, and for collection of floats 'd'. + * @collect_value: The collect_value() function is responsible for converting the + * values collected from a variable argument list into contents + * suitable for storage in a GValue. This function should setup + * @value similar to value_init(); e.g. for a string value that + * does not allow %NULL pointers, it needs to either spew an error, + * or do an implicit conversion by storing an empty string. + * The @value passed in to this function has a zero-filled data + * array, so just like for value_init() it is guaranteed to not + * contain any old contents that might need freeing. + * @n_collect_values is exactly the string length of @collect_format, + * and @collect_values is an array of unions #GTypeCValue with + * length @n_collect_values, containing the collected values + * according to @collect_format. + * @collect_flags is an argument provided as a hint by the caller. + * It may contain the flag %G_VALUE_NOCOPY_CONTENTS indicating, + * that the collected value contents may be considered "static" + * for the duration of the @value lifetime. + * Thus an extra copy of the contents stored in @collect_values is + * not required for assignment to @value. + * For our above string example, we continue with: + * |[ + * if (!collect_values[0].v_pointer) + * value->data[0].v_pointer = g_strdup (""); + * else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + * { + * value->data[0].v_pointer = collect_values[0].v_pointer; + * // keep a flag for the value_free() implementation to not free this string + * value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; + * } + * else + * value->data[0].v_pointer = g_strdup (collect_values[0].v_pointer); + * return NULL; + * ]| + * It should be noted, that it is generally a bad idea to follow the + * %G_VALUE_NOCOPY_CONTENTS hint for reference counted types. Due to + * reentrancy requirements and reference count assertions performed + * by the signal emission code, reference counts should always be + * incremented for reference counted contents stored in the value->data + * array. To deviate from our string example for a moment, and taking + * a look at an exemplary implementation for collect_value() of + * #GObject: + * |[ + * GObject *object = G_OBJECT (collect_values[0].v_pointer); + * g_return_val_if_fail (object != NULL, + * g_strdup_printf ("Object passed as invalid NULL pointer")); + * // never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types + * value->data[0].v_pointer = g_object_ref (object); + * return NULL; + * ]| + * The reference count for valid objects is always incremented, + * regardless of @collect_flags. For invalid objects, the example + * returns a newly allocated string without altering @value. + * Upon success, collect_value() needs to return %NULL. If, however, + * an error condition occurred, collect_value() may spew an + * error by returning a newly allocated non-%NULL string, giving + * a suitable description of the error condition. + * The calling code makes no assumptions about the @value + * contents being valid upon error returns, @value + * is simply thrown away without further freeing. As such, it is + * a good idea to not allocate #GValue contents, prior to returning + * an error, however, collect_values() is not obliged to return + * a correctly setup @value for error returns, simply because + * any non-%NULL return is considered a fatal condition so further + * program behaviour is undefined. + * @lcopy_format: Format description of the arguments to collect for @lcopy_value, + * analogous to @collect_format. Usually, @lcopy_format string consists + * only of 'p's to provide lcopy_value() with pointers to storage locations. + * @lcopy_value: This function is responsible for storing the @value contents into + * arguments passed through a variable argument list which got + * collected into @collect_values according to @lcopy_format. + * @n_collect_values equals the string length of @lcopy_format, + * and @collect_flags may contain %G_VALUE_NOCOPY_CONTENTS. + * In contrast to collect_value(), lcopy_value() is obliged to + * always properly support %G_VALUE_NOCOPY_CONTENTS. + * Similar to collect_value() the function may prematurely abort + * by returning a newly allocated string describing an error condition. + * To complete the string example: + * |[ + * gchar **string_p = collect_values[0].v_pointer; + * g_return_val_if_fail (string_p != NULL, + * g_strdup_printf ("string location passed as NULL")); + * if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + * *string_p = value->data[0].v_pointer; + * else + * *string_p = g_strdup (value->data[0].v_pointer); + * ]| + * And an illustrative version of lcopy_value() for + * reference-counted types: + * |[ + * GObject **object_p = collect_values[0].v_pointer; + * g_return_val_if_fail (object_p != NULL, + * g_strdup_printf ("object location passed as NULL")); + * if (!value->data[0].v_pointer) + * *object_p = NULL; + * else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) // always honour + * *object_p = value->data[0].v_pointer; + * else + * *object_p = g_object_ref (value->data[0].v_pointer); + * return NULL; + * ]| + * + * The #GTypeValueTable provides the functions required by the #GValue + * implementation, to serve as a container for values of a type. + */ + +struct _GTypeValueTable +{ + void (*value_init) (GValue *value); + void (*value_free) (GValue *value); + void (*value_copy) (const GValue *src_value, + GValue *dest_value); + /* varargs functionality (optional) */ + gpointer (*value_peek_pointer) (const GValue *value); + const gchar *collect_format; + gchar* (*collect_value) (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags); + const gchar *lcopy_format; + gchar* (*lcopy_value) (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags); +}; +GLIB_AVAILABLE_IN_ALL +GType g_type_register_static (GType parent_type, + const gchar *type_name, + const GTypeInfo *info, + GTypeFlags flags); +GLIB_AVAILABLE_IN_ALL +GType g_type_register_static_simple (GType parent_type, + const gchar *type_name, + guint class_size, + GClassInitFunc class_init, + guint instance_size, + GInstanceInitFunc instance_init, + GTypeFlags flags); + +GLIB_AVAILABLE_IN_ALL +GType g_type_register_dynamic (GType parent_type, + const gchar *type_name, + GTypePlugin *plugin, + GTypeFlags flags); +GLIB_AVAILABLE_IN_ALL +GType g_type_register_fundamental (GType type_id, + const gchar *type_name, + const GTypeInfo *info, + const GTypeFundamentalInfo *finfo, + GTypeFlags flags); +GLIB_AVAILABLE_IN_ALL +void g_type_add_interface_static (GType instance_type, + GType interface_type, + const GInterfaceInfo *info); +GLIB_AVAILABLE_IN_ALL +void g_type_add_interface_dynamic (GType instance_type, + GType interface_type, + GTypePlugin *plugin); +GLIB_AVAILABLE_IN_ALL +void g_type_interface_add_prerequisite (GType interface_type, + GType prerequisite_type); +GLIB_AVAILABLE_IN_ALL +GType*g_type_interface_prerequisites (GType interface_type, + guint *n_prerequisites); +GLIB_AVAILABLE_IN_2_68 +GType g_type_interface_instantiatable_prerequisite + (GType interface_type); +GLIB_DEPRECATED_IN_2_58 +void g_type_class_add_private (gpointer g_class, + gsize private_size); +GLIB_AVAILABLE_IN_2_38 +gint g_type_add_instance_private (GType class_type, + gsize private_size); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_instance_get_private (GTypeInstance *instance, + GType private_type); +GLIB_AVAILABLE_IN_2_38 +void g_type_class_adjust_private_offset (gpointer g_class, + gint *private_size_or_offset); + +GLIB_AVAILABLE_IN_ALL +void g_type_add_class_private (GType class_type, + gsize private_size); +GLIB_AVAILABLE_IN_ALL +gpointer g_type_class_get_private (GTypeClass *klass, + GType private_type); +GLIB_AVAILABLE_IN_2_38 +gint g_type_class_get_instance_private_offset (gpointer g_class); + +GLIB_AVAILABLE_IN_2_34 +void g_type_ensure (GType type); +GLIB_AVAILABLE_IN_2_36 +guint g_type_get_type_registration_serial (void); + + +/* --- GType boilerplate --- */ +/** + * G_DECLARE_FINAL_TYPE: + * @ModuleObjName: The name of the new type, in camel case (like `GtkWidget`) + * @module_obj_name: The name of the new type in lowercase, with words + * separated by `_` (like `gtk_widget`) + * @MODULE: The name of the module, in all caps (like `GTK`) + * @OBJ_NAME: The bare name of the type, in all caps (like `WIDGET`) + * @ParentName: the name of the parent type, in camel case (like `GtkWidget`) + * + * A convenience macro for emitting the usual declarations in the header file + * for a type which is not (at the present time) intended to be subclassed. + * + * You might use it in a header as follows: + * + * |[ + * #ifndef _myapp_window_h_ + * #define _myapp_window_h_ + * + * #include + * + * #define MY_APP_TYPE_WINDOW my_app_window_get_type () + * G_DECLARE_FINAL_TYPE (MyAppWindow, my_app_window, MY_APP, WINDOW, GtkWindow) + * + * MyAppWindow * my_app_window_new (void); + * + * ... + * + * #endif + * ]| + * + * And use it as follow in your C file: + * + * |[ + * struct _MyAppWindow + * { + * GtkWindow parent; + * ... + * }; + * G_DEFINE_TYPE (MyAppWindow, my_app_window, GTK_TYPE_WINDOW) + * ]| + * + * This results in the following things happening: + * + * - the usual `my_app_window_get_type()` function is declared with a return type of #GType + * + * - the `MyAppWindow` type is defined as a `typedef` of `struct _MyAppWindow`. The struct itself is not + * defined and should be defined from the .c file before G_DEFINE_TYPE() is used. + * + * - the `MY_APP_WINDOW()` cast is emitted as `static inline` function along with the `MY_APP_IS_WINDOW()` type + * checking function + * + * - the `MyAppWindowClass` type is defined as a struct containing `GtkWindowClass`. This is done for the + * convenience of the person defining the type and should not be considered to be part of the ABI. In + * particular, without a firm declaration of the instance structure, it is not possible to subclass the type + * and therefore the fact that the size of the class structure is exposed is not a concern and it can be + * freely changed at any point in the future. + * + * - g_autoptr() support being added for your type, based on the type of your parent class + * + * You can only use this function if your parent type also supports g_autoptr(). + * + * Because the type macro (`MY_APP_TYPE_WINDOW` in the above example) is not a callable, you must continue to + * manually define this as a macro for yourself. + * + * The declaration of the `_get_type()` function is the first thing emitted by the macro. This allows this macro + * to be used in the usual way with export control and API versioning macros. + * + * If you want to declare your own class structure, use G_DECLARE_DERIVABLE_TYPE(). + * + * If you are writing a library, it is important to note that it is possible to convert a type from using + * G_DECLARE_FINAL_TYPE() to G_DECLARE_DERIVABLE_TYPE() without breaking API or ABI. As a precaution, you + * should therefore use G_DECLARE_FINAL_TYPE() until you are sure that it makes sense for your class to be + * subclassed. Once a class structure has been exposed it is not possible to change its size or remove or + * reorder items without breaking the API and/or ABI. + * + * Since: 2.44 + **/ +#define G_DECLARE_FINAL_TYPE(ModuleObjName, module_obj_name, MODULE, OBJ_NAME, ParentName) \ + GType module_obj_name##_get_type (void); \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + typedef struct _##ModuleObjName ModuleObjName; \ + typedef struct { ParentName##Class parent_class; } ModuleObjName##Class; \ + \ + _GLIB_DEFINE_AUTOPTR_CHAINUP (ModuleObjName, ParentName) \ + G_DEFINE_AUTOPTR_CLEANUP_FUNC (ModuleObjName##Class, g_type_class_unref) \ + \ + G_GNUC_UNUSED static inline ModuleObjName * MODULE##_##OBJ_NAME (gpointer ptr) { \ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, module_obj_name##_get_type (), ModuleObjName); } \ + G_GNUC_UNUSED static inline gboolean MODULE##_IS_##OBJ_NAME (gpointer ptr) { \ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, module_obj_name##_get_type ()); } \ + G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * G_DECLARE_DERIVABLE_TYPE: + * @ModuleObjName: The name of the new type, in camel case (like `GtkWidget`) + * @module_obj_name: The name of the new type in lowercase, with words + * separated by `_` (like `gtk_widget`) + * @MODULE: The name of the module, in all caps (like `GTK`) + * @OBJ_NAME: The bare name of the type, in all caps (like `WIDGET`) + * @ParentName: the name of the parent type, in camel case (like `GtkWidget`) + * + * A convenience macro for emitting the usual declarations in the + * header file for a type which is intended to be subclassed. + * + * You might use it in a header as follows: + * + * |[ + * #ifndef _gtk_frobber_h_ + * #define _gtk_frobber_h_ + * + * #define GTK_TYPE_FROBBER gtk_frobber_get_type () + * GDK_AVAILABLE_IN_3_12 + * G_DECLARE_DERIVABLE_TYPE (GtkFrobber, gtk_frobber, GTK, FROBBER, GtkWidget) + * + * struct _GtkFrobberClass + * { + * GtkWidgetClass parent_class; + * + * void (* handle_frob) (GtkFrobber *frobber, + * guint n_frobs); + * + * gpointer padding[12]; + * }; + * + * GtkWidget * gtk_frobber_new (void); + * + * ... + * + * #endif + * ]| + * + * Since the instance structure is public it is often needed to declare a + * private struct as follow in your C file: + * + * |[ + * typedef struct _GtkFrobberPrivate GtkFrobberPrivate; + * struct _GtkFrobberPrivate + * { + * ... + * }; + * G_DEFINE_TYPE_WITH_PRIVATE (GtkFrobber, gtk_frobber, GTK_TYPE_WIDGET) + * ]| + * + * This results in the following things happening: + * + * - the usual `gtk_frobber_get_type()` function is declared with a return type of #GType + * + * - the `GtkFrobber` struct is created with `GtkWidget` as the first and only item. You are expected to use + * a private structure from your .c file to store your instance variables. + * + * - the `GtkFrobberClass` type is defined as a typedef to `struct _GtkFrobberClass`, which is left undefined. + * You should do this from the header file directly after you use the macro. + * + * - the `GTK_FROBBER()` and `GTK_FROBBER_CLASS()` casts are emitted as `static inline` functions along with + * the `GTK_IS_FROBBER()` and `GTK_IS_FROBBER_CLASS()` type checking functions and `GTK_FROBBER_GET_CLASS()` + * function. + * + * - g_autoptr() support being added for your type, based on the type of your parent class + * + * You can only use this function if your parent type also supports g_autoptr(). + * + * Because the type macro (`GTK_TYPE_FROBBER` in the above example) is not a callable, you must continue to + * manually define this as a macro for yourself. + * + * The declaration of the `_get_type()` function is the first thing emitted by the macro. This allows this macro + * to be used in the usual way with export control and API versioning macros. + * + * If you are writing a library, it is important to note that it is possible to convert a type from using + * G_DECLARE_FINAL_TYPE() to G_DECLARE_DERIVABLE_TYPE() without breaking API or ABI. As a precaution, you + * should therefore use G_DECLARE_FINAL_TYPE() until you are sure that it makes sense for your class to be + * subclassed. Once a class structure has been exposed it is not possible to change its size or remove or + * reorder items without breaking the API and/or ABI. If you want to declare your own class structure, use + * G_DECLARE_DERIVABLE_TYPE(). If you want to declare a class without exposing the class or instance + * structures, use G_DECLARE_FINAL_TYPE(). + * + * If you must use G_DECLARE_DERIVABLE_TYPE() you should be sure to include some padding at the bottom of your + * class structure to leave space for the addition of future virtual functions. + * + * Since: 2.44 + **/ +#define G_DECLARE_DERIVABLE_TYPE(ModuleObjName, module_obj_name, MODULE, OBJ_NAME, ParentName) \ + GType module_obj_name##_get_type (void); \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + typedef struct _##ModuleObjName ModuleObjName; \ + typedef struct _##ModuleObjName##Class ModuleObjName##Class; \ + struct _##ModuleObjName { ParentName parent_instance; }; \ + \ + _GLIB_DEFINE_AUTOPTR_CHAINUP (ModuleObjName, ParentName) \ + G_DEFINE_AUTOPTR_CLEANUP_FUNC (ModuleObjName##Class, g_type_class_unref) \ + \ + G_GNUC_UNUSED static inline ModuleObjName * MODULE##_##OBJ_NAME (gpointer ptr) { \ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, module_obj_name##_get_type (), ModuleObjName); } \ + G_GNUC_UNUSED static inline ModuleObjName##Class * MODULE##_##OBJ_NAME##_CLASS (gpointer ptr) { \ + return G_TYPE_CHECK_CLASS_CAST (ptr, module_obj_name##_get_type (), ModuleObjName##Class); } \ + G_GNUC_UNUSED static inline gboolean MODULE##_IS_##OBJ_NAME (gpointer ptr) { \ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, module_obj_name##_get_type ()); } \ + G_GNUC_UNUSED static inline gboolean MODULE##_IS_##OBJ_NAME##_CLASS (gpointer ptr) { \ + return G_TYPE_CHECK_CLASS_TYPE (ptr, module_obj_name##_get_type ()); } \ + G_GNUC_UNUSED static inline ModuleObjName##Class * MODULE##_##OBJ_NAME##_GET_CLASS (gpointer ptr) { \ + return G_TYPE_INSTANCE_GET_CLASS (ptr, module_obj_name##_get_type (), ModuleObjName##Class); } \ + G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * G_DECLARE_INTERFACE: + * @ModuleObjName: The name of the new type, in camel case (like `GtkWidget`) + * @module_obj_name: The name of the new type in lowercase, with words + * separated by `_` (like `gtk_widget`) + * @MODULE: The name of the module, in all caps (like `GTK`) + * @OBJ_NAME: The bare name of the type, in all caps (like `WIDGET`) + * @PrerequisiteName: the name of the prerequisite type, in camel case (like `GtkWidget`) + * + * A convenience macro for emitting the usual declarations in the header file for a #GInterface type. + * + * You might use it in a header as follows: + * + * |[ + * #ifndef _my_model_h_ + * #define _my_model_h_ + * + * #define MY_TYPE_MODEL my_model_get_type () + * GDK_AVAILABLE_IN_3_12 + * G_DECLARE_INTERFACE (MyModel, my_model, MY, MODEL, GObject) + * + * struct _MyModelInterface + * { + * GTypeInterface g_iface; + * + * gpointer (* get_item) (MyModel *model); + * }; + * + * gpointer my_model_get_item (MyModel *model); + * + * ... + * + * #endif + * ]| + * + * And use it as follow in your C file: + * + * |[ + * G_DEFINE_INTERFACE (MyModel, my_model, G_TYPE_OBJECT); + * + * static void + * my_model_default_init (MyModelInterface *iface) + * { + * ... + * } + * ]| + * + * This results in the following things happening: + * + * - the usual `my_model_get_type()` function is declared with a return type of #GType + * + * - the `MyModelInterface` type is defined as a typedef to `struct _MyModelInterface`, + * which is left undefined. You should do this from the header file directly after + * you use the macro. + * + * - the `MY_MODEL()` cast is emitted as `static inline` functions along with + * the `MY_IS_MODEL()` type checking function and `MY_MODEL_GET_IFACE()` function. + * + * - g_autoptr() support being added for your type, based on your prerequisite type. + * + * You can only use this function if your prerequisite type also supports g_autoptr(). + * + * Because the type macro (`MY_TYPE_MODEL` in the above example) is not a callable, you must continue to + * manually define this as a macro for yourself. + * + * The declaration of the `_get_type()` function is the first thing emitted by the macro. This allows this macro + * to be used in the usual way with export control and API versioning macros. + * + * Since: 2.44 + **/ +#define G_DECLARE_INTERFACE(ModuleObjName, module_obj_name, MODULE, OBJ_NAME, PrerequisiteName) \ + GType module_obj_name##_get_type (void); \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + typedef struct _##ModuleObjName ModuleObjName; \ + typedef struct _##ModuleObjName##Interface ModuleObjName##Interface; \ + \ + _GLIB_DEFINE_AUTOPTR_CHAINUP (ModuleObjName, PrerequisiteName) \ + \ + G_GNUC_UNUSED static inline ModuleObjName * MODULE##_##OBJ_NAME (gpointer ptr) { \ + return G_TYPE_CHECK_INSTANCE_CAST (ptr, module_obj_name##_get_type (), ModuleObjName); } \ + G_GNUC_UNUSED static inline gboolean MODULE##_IS_##OBJ_NAME (gpointer ptr) { \ + return G_TYPE_CHECK_INSTANCE_TYPE (ptr, module_obj_name##_get_type ()); } \ + G_GNUC_UNUSED static inline ModuleObjName##Interface * MODULE##_##OBJ_NAME##_GET_IFACE (gpointer ptr) { \ + return G_TYPE_INSTANCE_GET_INTERFACE (ptr, module_obj_name##_get_type (), ModuleObjName##Interface); } \ + G_GNUC_END_IGNORE_DEPRECATIONS + +/** + * G_DEFINE_TYPE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words + * separated by `_`. + * @T_P: The #GType of the parent type. + * + * A convenience macro for type implementations, which declares a class + * initialization function, an instance initialization function (see #GTypeInfo + * for information about these) and a static variable named `t_n_parent_class` + * pointing to the parent class. Furthermore, it defines a `*_get_type()` function. + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Since: 2.4 + */ +#define G_DEFINE_TYPE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, {}) +/** + * G_DEFINE_TYPE_WITH_CODE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type in lowercase, with words separated by `_`. + * @T_P: The #GType of the parent type. + * @_C_: Custom code that gets inserted in the `*_get_type()` function. + * + * A convenience macro for type implementations. + * + * Similar to G_DEFINE_TYPE(), but allows you to insert custom code into the + * `*_get_type()` function, e.g. interface implementations via G_IMPLEMENT_INTERFACE(). + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Since: 2.4 + */ +#define G_DEFINE_TYPE_WITH_CODE(TN, t_n, T_P, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, 0) {_C_;} _G_DEFINE_TYPE_EXTENDED_END() +/** + * G_DEFINE_TYPE_WITH_PRIVATE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words + * separated by `_`. + * @T_P: The #GType of the parent type. + * + * A convenience macro for type implementations, which declares a class + * initialization function, an instance initialization function (see #GTypeInfo + * for information about these), a static variable named `t_n_parent_class` + * pointing to the parent class, and adds private instance data to the type. + * + * Furthermore, it defines a `*_get_type()` function. See G_DEFINE_TYPE_EXTENDED() + * for an example. + * + * Note that private structs added with this macros must have a struct + * name of the form `TN ## Private`. + * + * The private instance data can be retrieved using the automatically generated + * getter function `t_n_get_instance_private()`. + * + * See also: G_ADD_PRIVATE() + * + * Since: 2.38 + */ +#define G_DEFINE_TYPE_WITH_PRIVATE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, G_ADD_PRIVATE (TN)) +/** + * G_DEFINE_ABSTRACT_TYPE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words + * separated by `_`. + * @T_P: The #GType of the parent type. + * + * A convenience macro for type implementations. + * + * Similar to G_DEFINE_TYPE(), but defines an abstract type. + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Since: 2.4 + */ +#define G_DEFINE_ABSTRACT_TYPE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_ABSTRACT, {}) +/** + * G_DEFINE_ABSTRACT_TYPE_WITH_CODE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words + * separated by `_`. + * @T_P: The #GType of the parent type. + * @_C_: Custom code that gets inserted in the `type_name_get_type()` function. + * + * A convenience macro for type implementations. + * + * Similar to G_DEFINE_TYPE_WITH_CODE(), but defines an abstract type and + * allows you to insert custom code into the `*_get_type()` function, e.g. + * interface implementations via G_IMPLEMENT_INTERFACE(). + * + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Since: 2.4 + */ +#define G_DEFINE_ABSTRACT_TYPE_WITH_CODE(TN, t_n, T_P, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, G_TYPE_FLAG_ABSTRACT) {_C_;} _G_DEFINE_TYPE_EXTENDED_END() +/** + * G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words + * separated by `_`. + * @T_P: The #GType of the parent type. + * + * Similar to G_DEFINE_TYPE_WITH_PRIVATE(), but defines an abstract type. + * + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Since: 2.38 + */ +#define G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_ABSTRACT, G_ADD_PRIVATE (TN)) +/** + * G_DEFINE_FINAL_TYPE: + * @TN: the name of the new type, in Camel case + * @t_n: the name of the new type, in lower case, with words + * separated by `_` (snake case) + * @T_P: the #GType of the parent type + * + * A convenience macro for type implementations. + * + * Similar to G_DEFINE_TYPE(), but defines a final type. + * + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Since: 2.70 + */ +#define G_DEFINE_FINAL_TYPE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_FINAL, {}) GLIB_AVAILABLE_MACRO_IN_2_70 +/** + * G_DEFINE_FINAL_TYPE_WITH_CODE: + * @TN: the name of the new type, in Camel case + * @t_n: the name of the new type, in lower case, with words + * separated by `_` (snake case) + * @T_P: the #GType of the parent type + * @_C_: Custom code that gets inserted in the `type_name_get_type()` function. + * + * A convenience macro for type implementations. + * + * Similar to G_DEFINE_TYPE_WITH_CODE(), but defines a final type and + * allows you to insert custom code into the `*_get_type()` function, e.g. + * interface implementations via G_IMPLEMENT_INTERFACE(). + * + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Since: 2.70 + */ +#define G_DEFINE_FINAL_TYPE_WITH_CODE(TN, t_n, T_P, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, G_TYPE_FLAG_FINAL) {_C_;} _G_DEFINE_TYPE_EXTENDED_END() GLIB_AVAILABLE_MACRO_IN_2_70 +/** + * G_DEFINE_FINAL_TYPE_WITH_PRIVATE: + * @TN: the name of the new type, in Camel case + * @t_n: the name of the new type, in lower case, with words + * separated by `_` (snake case) + * @T_P: the #GType of the parent type + * + * A convenience macro for type implementations. + * + * Similar to G_DEFINE_TYPE_WITH_PRIVATE(), but defines a final type. + * + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Since: 2.70 + */ +#define G_DEFINE_FINAL_TYPE_WITH_PRIVATE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_FINAL, G_ADD_PRIVATE (TN)) GLIB_AVAILABLE_MACRO_IN_2_70 +/** + * G_DEFINE_TYPE_EXTENDED: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words + * separated by `_`. + * @T_P: The #GType of the parent type. + * @_f_: #GTypeFlags to pass to g_type_register_static() + * @_C_: Custom code that gets inserted in the `*_get_type()` function. + * + * The most general convenience macro for type implementations, on which + * G_DEFINE_TYPE(), etc are based. + * + * |[ + * G_DEFINE_TYPE_EXTENDED (GtkGadget, + * gtk_gadget, + * GTK_TYPE_WIDGET, + * 0, + * G_ADD_PRIVATE (GtkGadget) + * G_IMPLEMENT_INTERFACE (TYPE_GIZMO, + * gtk_gadget_gizmo_init)); + * ]| + * + * expands to + * + * |[ + * static void gtk_gadget_init (GtkGadget *self); + * static void gtk_gadget_class_init (GtkGadgetClass *klass); + * static gpointer gtk_gadget_parent_class = NULL; + * static gint GtkGadget_private_offset; + * static void gtk_gadget_class_intern_init (gpointer klass) + * { + * gtk_gadget_parent_class = g_type_class_peek_parent (klass); + * if (GtkGadget_private_offset != 0) + * g_type_class_adjust_private_offset (klass, &GtkGadget_private_offset); + * gtk_gadget_class_init ((GtkGadgetClass*) klass); + * } + * static inline gpointer gtk_gadget_get_instance_private (GtkGadget *self) + * { + * return (G_STRUCT_MEMBER_P (self, GtkGadget_private_offset)); + * } + * + * GType + * gtk_gadget_get_type (void) + * { + * static gsize static_g_define_type_id = 0; + * if (g_once_init_enter (&static_g_define_type_id)) + * { + * GType g_define_type_id = + * g_type_register_static_simple (GTK_TYPE_WIDGET, + * g_intern_static_string ("GtkGadget"), + * sizeof (GtkGadgetClass), + * (GClassInitFunc) gtk_gadget_class_intern_init, + * sizeof (GtkGadget), + * (GInstanceInitFunc) gtk_gadget_init, + * 0); + * { + * GtkGadget_private_offset = + * g_type_add_instance_private (g_define_type_id, sizeof (GtkGadgetPrivate)); + * } + * { + * const GInterfaceInfo g_implement_interface_info = { + * (GInterfaceInitFunc) gtk_gadget_gizmo_init + * }; + * g_type_add_interface_static (g_define_type_id, TYPE_GIZMO, &g_implement_interface_info); + * } + * g_once_init_leave (&static_g_define_type_id, g_define_type_id); + * } + * return static_g_define_type_id; + * } + * ]| + * + * The only pieces which have to be manually provided are the definitions of + * the instance and class structure and the definitions of the instance and + * class init functions. + * + * Since: 2.4 + */ +#define G_DEFINE_TYPE_EXTENDED(TN, t_n, T_P, _f_, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, _f_) {_C_;} _G_DEFINE_TYPE_EXTENDED_END() + +/** + * G_DEFINE_INTERFACE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words separated by `_`. + * @T_P: The #GType of the prerequisite type for the interface, or %G_TYPE_INVALID + * for no prerequisite type. + * + * A convenience macro for #GTypeInterface definitions, which declares + * a default vtable initialization function and defines a `*_get_type()` + * function. + * + * The macro expects the interface initialization function to have the + * name `t_n ## _default_init`, and the interface structure to have the + * name `TN ## Interface`. + * + * The initialization function has signature + * `static void t_n ## _default_init (TypeName##Interface *klass);`, rather than + * the full #GInterfaceInitFunc signature, for brevity and convenience. If you + * need to use an initialization function with an `iface_data` argument, you + * must write the #GTypeInterface definitions manually. + * + * Since: 2.24 + */ +#define G_DEFINE_INTERFACE(TN, t_n, T_P) G_DEFINE_INTERFACE_WITH_CODE(TN, t_n, T_P, ;) + +/** + * G_DEFINE_INTERFACE_WITH_CODE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words separated by `_`. + * @T_P: The #GType of the prerequisite type for the interface, or %G_TYPE_INVALID + * for no prerequisite type. + * @_C_: Custom code that gets inserted in the `*_get_type()` function. + * + * A convenience macro for #GTypeInterface definitions. + * + * Similar to G_DEFINE_INTERFACE(), but allows you to insert custom code + * into the `*_get_type()` function, e.g. additional interface implementations + * via G_IMPLEMENT_INTERFACE(), or additional prerequisite types. + * + * See G_DEFINE_TYPE_EXTENDED() for a similar example using + * G_DEFINE_TYPE_WITH_CODE(). + * + * Since: 2.24 + */ +#define G_DEFINE_INTERFACE_WITH_CODE(TN, t_n, T_P, _C_) _G_DEFINE_INTERFACE_EXTENDED_BEGIN(TN, t_n, T_P) {_C_;} _G_DEFINE_INTERFACE_EXTENDED_END() + +/** + * G_IMPLEMENT_INTERFACE: + * @TYPE_IFACE: The #GType of the interface to add + * @iface_init: (type GInterfaceInitFunc): The interface init function, of type #GInterfaceInitFunc + * + * A convenience macro to ease interface addition in the `_C_` section + * of G_DEFINE_TYPE_WITH_CODE() or G_DEFINE_ABSTRACT_TYPE_WITH_CODE(). + * See G_DEFINE_TYPE_EXTENDED() for an example. + * + * Note that this macro can only be used together with the `G_DEFINE_TYPE_*` + * macros, since it depends on variable names from those macros. + * + * Since: 2.4 + */ +#define G_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) { \ + const GInterfaceInfo g_implement_interface_info = { \ + (GInterfaceInitFunc)(void (*)(void)) iface_init, NULL, NULL \ + }; \ + g_type_add_interface_static (g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \ +} + +/** + * G_ADD_PRIVATE: + * @TypeName: the name of the type in CamelCase + * + * A convenience macro to ease adding private data to instances of a new type + * in the @_C_ section of G_DEFINE_TYPE_WITH_CODE() or + * G_DEFINE_ABSTRACT_TYPE_WITH_CODE(). + * + * For instance: + * + * |[ + * typedef struct _MyObject MyObject; + * typedef struct _MyObjectClass MyObjectClass; + * + * typedef struct { + * gint foo; + * gint bar; + * } MyObjectPrivate; + * + * G_DEFINE_TYPE_WITH_CODE (MyObject, my_object, G_TYPE_OBJECT, + * G_ADD_PRIVATE (MyObject)) + * ]| + * + * Will add `MyObjectPrivate` as the private data to any instance of the + * `MyObject` type. + * + * `G_DEFINE_TYPE_*` macros will automatically create a private function + * based on the arguments to this macro, which can be used to safely + * retrieve the private data from an instance of the type; for instance: + * + * |[ + * gint + * my_object_get_foo (MyObject *obj) + * { + * MyObjectPrivate *priv = my_object_get_instance_private (obj); + * + * g_return_val_if_fail (MY_IS_OBJECT (obj), 0); + * + * return priv->foo; + * } + * + * void + * my_object_set_bar (MyObject *obj, + * gint bar) + * { + * MyObjectPrivate *priv = my_object_get_instance_private (obj); + * + * g_return_if_fail (MY_IS_OBJECT (obj)); + * + * if (priv->bar != bar) + * priv->bar = bar; + * } + * ]| + * + * Since GLib 2.72, the returned `MyObjectPrivate` pointer is guaranteed to be + * aligned to at least the alignment of the largest basic GLib type (typically + * this is #guint64 or #gdouble). If you need larger alignment for an element in + * the struct, you should allocate it on the heap (aligned), or arrange for your + * `MyObjectPrivate` struct to be appropriately padded. + * + * Note that this macro can only be used together with the `G_DEFINE_TYPE_*` + * macros, since it depends on variable names from those macros. + * + * Also note that private structs added with these macros must have a struct + * name of the form `TypeNamePrivate`. + * + * It is safe to call the `_get_instance_private` function on %NULL or invalid + * objects since it's only adding an offset to the instance pointer. In that + * case the returned pointer must not be dereferenced. + * + * Since: 2.38 + */ +#define G_ADD_PRIVATE(TypeName) { \ + TypeName##_private_offset = \ + g_type_add_instance_private (g_define_type_id, sizeof (TypeName##Private)); \ +} + +/** + * G_PRIVATE_OFFSET: + * @TypeName: the name of the type in CamelCase + * @field: the name of the field in the private data structure + * + * Evaluates to the offset of the @field inside the instance private data + * structure for @TypeName. + * + * Note that this macro can only be used together with the `G_DEFINE_TYPE_*` + * and G_ADD_PRIVATE() macros, since it depends on variable names from + * those macros. + * + * Since: 2.38 + */ +#define G_PRIVATE_OFFSET(TypeName, field) \ + (TypeName##_private_offset + (G_STRUCT_OFFSET (TypeName##Private, field))) + +/** + * G_PRIVATE_FIELD_P: + * @TypeName: the name of the type in CamelCase + * @inst: the instance of @TypeName you wish to access + * @field_name: the name of the field in the private data structure + * + * Evaluates to a pointer to the @field_name inside the @inst private data + * structure for @TypeName. + * + * Note that this macro can only be used together with the `G_DEFINE_TYPE_*` + * and G_ADD_PRIVATE() macros, since it depends on variable names from + * those macros. + * + * Since: 2.38 + */ +#define G_PRIVATE_FIELD_P(TypeName, inst, field_name) \ + G_STRUCT_MEMBER_P (inst, G_PRIVATE_OFFSET (TypeName, field_name)) + +/** + * G_PRIVATE_FIELD: + * @TypeName: the name of the type in CamelCase + * @inst: the instance of @TypeName you wish to access + * @field_type: the type of the field in the private data structure + * @field_name: the name of the field in the private data structure + * + * Evaluates to the @field_name inside the @inst private data + * structure for @TypeName. + * + * Note that this macro can only be used together with the `G_DEFINE_TYPE_*` + * and G_ADD_PRIVATE() macros, since it depends on variable names from + * those macros. + * + * Since: 2.38 + */ +#define G_PRIVATE_FIELD(TypeName, inst, field_type, field_name) \ + G_STRUCT_MEMBER (field_type, inst, G_PRIVATE_OFFSET (TypeName, field_name)) + +/* we need to have this macro under conditional expansion, as it references + * a function that has been added in 2.38. see bug: + * https://bugzilla.gnome.org/show_bug.cgi?id=703191 + */ +#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 +#define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \ +static void type_name##_class_intern_init (gpointer klass) \ +{ \ + type_name##_parent_class = g_type_class_peek_parent (klass); \ + if (TypeName##_private_offset != 0) \ + g_type_class_adjust_private_offset (klass, &TypeName##_private_offset); \ + type_name##_class_init ((TypeName##Class*) klass); \ +} + +#else +#define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \ +static void type_name##_class_intern_init (gpointer klass) \ +{ \ + type_name##_parent_class = g_type_class_peek_parent (klass); \ + type_name##_class_init ((TypeName##Class*) klass); \ +} +#endif /* GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 */ + +/* Added for _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE */ +#define _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE(TypeName, type_name, TYPE_PARENT) \ +\ +static void type_name##_init (TypeName *self); \ +static void type_name##_class_init (TypeName##Class *klass); \ +static GType type_name##_get_type_once (void); \ +static gpointer type_name##_parent_class = NULL; \ +static gint TypeName##_private_offset; \ +\ +_G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \ +\ +G_GNUC_UNUSED \ +static inline gpointer \ +type_name##_get_instance_private (TypeName *self) \ +{ \ + return (G_STRUCT_MEMBER_P (self, TypeName##_private_offset)); \ +} \ +\ +GType \ +type_name##_get_type (void) \ +{ \ + static gsize static_g_define_type_id = 0; + /* Prelude goes here */ + +/* Added for _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE */ +#define _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \ + if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = type_name##_get_type_once (); \ + g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ + return static_g_define_type_id; \ +} /* closes type_name##_get_type() */ \ +\ +G_GNUC_NO_INLINE \ +static GType \ +type_name##_get_type_once (void) \ +{ \ + GType g_define_type_id = \ + g_type_register_static_simple (TYPE_PARENT, \ + g_intern_static_string (#TypeName), \ + sizeof (TypeName##Class), \ + (GClassInitFunc)(void (*)(void)) type_name##_class_intern_init, \ + sizeof (TypeName), \ + (GInstanceInitFunc)(void (*)(void)) type_name##_init, \ + (GTypeFlags) flags); \ + { /* custom code follows */ +#define _G_DEFINE_TYPE_EXTENDED_END() \ + /* following custom code */ \ + } \ + return g_define_type_id; \ +} /* closes type_name##_get_type_once() */ + +/* This was defined before we had G_DEFINE_TYPE_WITH_CODE_AND_PRELUDE, it's simplest + * to keep it. + */ +#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \ + _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE(TypeName, type_name, TYPE_PARENT) \ + _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \ + +#define _G_DEFINE_INTERFACE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PREREQ) \ +\ +static void type_name##_default_init (TypeName##Interface *klass); \ +\ +GType \ +type_name##_get_type (void) \ +{ \ + static gsize static_g_define_type_id = 0; \ + if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = \ + g_type_register_static_simple (G_TYPE_INTERFACE, \ + g_intern_static_string (#TypeName), \ + sizeof (TypeName##Interface), \ + (GClassInitFunc)(void (*)(void)) type_name##_default_init, \ + 0, \ + (GInstanceInitFunc)NULL, \ + (GTypeFlags) 0); \ + if (TYPE_PREREQ != G_TYPE_INVALID) \ + g_type_interface_add_prerequisite (g_define_type_id, TYPE_PREREQ); \ + { /* custom code follows */ +#define _G_DEFINE_INTERFACE_EXTENDED_END() \ + /* following custom code */ \ + } \ + g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ + return static_g_define_type_id; \ +} /* closes type_name##_get_type() */ + +/** + * G_DEFINE_BOXED_TYPE: + * @TypeName: The name of the new type, in Camel case + * @type_name: The name of the new type, in lowercase, with words + * separated by `_` + * @copy_func: the #GBoxedCopyFunc for the new type + * @free_func: the #GBoxedFreeFunc for the new type + * + * A convenience macro for defining a new custom boxed type. + * + * Using this macro is the recommended way of defining new custom boxed + * types, over calling g_boxed_type_register_static() directly. It defines + * a `type_name_get_type()` function which will return the newly defined + * #GType, enabling lazy instantiation. + * + * |[ + * G_DEFINE_BOXED_TYPE (MyStruct, my_struct, my_struct_copy, my_struct_free) + * + * void + * foo () + * { + * GType type = my_struct_get_type (); + * // ... your code ... + * } + * ]| + * + * Since: 2.26 + */ +#define G_DEFINE_BOXED_TYPE(TypeName, type_name, copy_func, free_func) G_DEFINE_BOXED_TYPE_WITH_CODE (TypeName, type_name, copy_func, free_func, {}) +/** + * G_DEFINE_BOXED_TYPE_WITH_CODE: + * @TypeName: The name of the new type, in Camel case + * @type_name: The name of the new type, in lowercase, with words + * separated by `_` + * @copy_func: the #GBoxedCopyFunc for the new type + * @free_func: the #GBoxedFreeFunc for the new type + * @_C_: Custom code that gets inserted in the `*_get_type()` function + * + * A convenience macro for boxed type implementations. + * + * Similar to G_DEFINE_BOXED_TYPE(), but allows to insert custom code into the + * `type_name_get_type()` function, e.g. to register value transformations with + * g_value_register_transform_func(), for instance: + * + * |[ + * G_DEFINE_BOXED_TYPE_WITH_CODE (GdkRectangle, gdk_rectangle, + * gdk_rectangle_copy, + * gdk_rectangle_free, + * register_rectangle_transform_funcs (g_define_type_id)) + * ]| + * + * Similarly to the `G_DEFINE_TYPE_*` family of macros, the #GType of the newly + * defined boxed type is exposed in the `g_define_type_id` variable. + * + * Since: 2.26 + */ +#define G_DEFINE_BOXED_TYPE_WITH_CODE(TypeName, type_name, copy_func, free_func, _C_) _G_DEFINE_BOXED_TYPE_BEGIN (TypeName, type_name, copy_func, free_func) {_C_;} _G_DEFINE_TYPE_EXTENDED_END() + +/* Only use this in non-C++ on GCC >= 2.7, except for Darwin/ppc64. + * See https://bugzilla.gnome.org/show_bug.cgi?id=647145 + */ +#if !defined (__cplusplus) && (G_GNUC_CHECK_VERSION(2, 7)) && !(defined (__APPLE__) && defined (__ppc64__)) +#define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \ +static GType type_name##_get_type_once (void); \ +\ +GType \ +type_name##_get_type (void) \ +{ \ + static gsize static_g_define_type_id = 0; \ + if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = type_name##_get_type_once (); \ + g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ + return static_g_define_type_id; \ +} \ +\ +G_GNUC_NO_INLINE \ +static GType \ +type_name##_get_type_once (void) \ +{ \ + GType (* _g_register_boxed) \ + (const gchar *, \ + union \ + { \ + TypeName * (*do_copy_type) (TypeName *); \ + TypeName * (*do_const_copy_type) (const TypeName *); \ + GBoxedCopyFunc do_copy_boxed; \ + } __attribute__((__transparent_union__)), \ + union \ + { \ + void (* do_free_type) (TypeName *); \ + GBoxedFreeFunc do_free_boxed; \ + } __attribute__((__transparent_union__)) \ + ) = g_boxed_type_register_static; \ + GType g_define_type_id = \ + _g_register_boxed (g_intern_static_string (#TypeName), copy_func, free_func); \ + { /* custom code follows */ +#else +#define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \ +static GType type_name##_get_type_once (void); \ +\ +GType \ +type_name##_get_type (void) \ +{ \ + static gsize static_g_define_type_id = 0; \ + if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = type_name##_get_type_once (); \ + g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ + return static_g_define_type_id; \ +} \ +\ +G_GNUC_NO_INLINE \ +static GType \ +type_name##_get_type_once (void) \ +{ \ + GType g_define_type_id = \ + g_boxed_type_register_static (g_intern_static_string (#TypeName), \ + (GBoxedCopyFunc) copy_func, \ + (GBoxedFreeFunc) free_func); \ + { /* custom code follows */ +#endif /* __GNUC__ */ + +/** + * G_DEFINE_POINTER_TYPE: + * @TypeName: The name of the new type, in Camel case + * @type_name: The name of the new type, in lowercase, with words + * separated by `_` + * + * A convenience macro for pointer type implementations, which defines a + * `type_name_get_type()` function registering the pointer type. + * + * Since: 2.26 + */ +#define G_DEFINE_POINTER_TYPE(TypeName, type_name) G_DEFINE_POINTER_TYPE_WITH_CODE (TypeName, type_name, {}) +/** + * G_DEFINE_POINTER_TYPE_WITH_CODE: + * @TypeName: The name of the new type, in Camel case + * @type_name: The name of the new type, in lowercase, with words + * separated by `_` + * @_C_: Custom code that gets inserted in the `*_get_type()` function + * + * A convenience macro for pointer type implementations. + * Similar to G_DEFINE_POINTER_TYPE(), but allows to insert + * custom code into the `type_name_get_type()` function. + * + * Since: 2.26 + */ +#define G_DEFINE_POINTER_TYPE_WITH_CODE(TypeName, type_name, _C_) _G_DEFINE_POINTER_TYPE_BEGIN (TypeName, type_name) {_C_;} _G_DEFINE_TYPE_EXTENDED_END() + +#define _G_DEFINE_POINTER_TYPE_BEGIN(TypeName, type_name) \ +static GType type_name##_get_type_once (void); \ +\ +GType \ +type_name##_get_type (void) \ +{ \ + static gsize static_g_define_type_id = 0; \ + if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = type_name##_get_type_once (); \ + g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ + return static_g_define_type_id; \ +} \ +\ +G_GNUC_NO_INLINE \ +static GType \ +type_name##_get_type_once (void) \ +{ \ + GType g_define_type_id = \ + g_pointer_type_register_static (g_intern_static_string (#TypeName)); \ + { /* custom code follows */ + +/* --- protected (for fundamental type implementations) --- */ +GLIB_AVAILABLE_IN_ALL +GTypePlugin* g_type_get_plugin (GType type); +GLIB_AVAILABLE_IN_ALL +GTypePlugin* g_type_interface_get_plugin (GType instance_type, + GType interface_type); +GLIB_AVAILABLE_IN_ALL +GType g_type_fundamental_next (void); +GLIB_AVAILABLE_IN_ALL +GType g_type_fundamental (GType type_id); +GLIB_AVAILABLE_IN_ALL +GTypeInstance* g_type_create_instance (GType type); +GLIB_AVAILABLE_IN_ALL +void g_type_free_instance (GTypeInstance *instance); + +GLIB_AVAILABLE_IN_ALL +void g_type_add_class_cache_func (gpointer cache_data, + GTypeClassCacheFunc cache_func); +GLIB_AVAILABLE_IN_ALL +void g_type_remove_class_cache_func (gpointer cache_data, + GTypeClassCacheFunc cache_func); +GLIB_AVAILABLE_IN_ALL +void g_type_class_unref_uncached (gpointer g_class); + +GLIB_AVAILABLE_IN_ALL +void g_type_add_interface_check (gpointer check_data, + GTypeInterfaceCheckFunc check_func); +GLIB_AVAILABLE_IN_ALL +void g_type_remove_interface_check (gpointer check_data, + GTypeInterfaceCheckFunc check_func); + +GLIB_AVAILABLE_IN_ALL +GTypeValueTable* g_type_value_table_peek (GType type); + + +/*< private >*/ +GLIB_AVAILABLE_IN_ALL +gboolean g_type_check_instance (GTypeInstance *instance) G_GNUC_PURE; +GLIB_AVAILABLE_IN_ALL +GTypeInstance* g_type_check_instance_cast (GTypeInstance *instance, + GType iface_type); +GLIB_AVAILABLE_IN_ALL +gboolean g_type_check_instance_is_a (GTypeInstance *instance, + GType iface_type) G_GNUC_PURE; +GLIB_AVAILABLE_IN_2_42 +gboolean g_type_check_instance_is_fundamentally_a (GTypeInstance *instance, + GType fundamental_type) G_GNUC_PURE; +GLIB_AVAILABLE_IN_ALL +GTypeClass* g_type_check_class_cast (GTypeClass *g_class, + GType is_a_type); +GLIB_AVAILABLE_IN_ALL +gboolean g_type_check_class_is_a (GTypeClass *g_class, + GType is_a_type) G_GNUC_PURE; +GLIB_AVAILABLE_IN_ALL +gboolean g_type_check_is_value_type (GType type) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gboolean g_type_check_value (const GValue *value) G_GNUC_PURE; +GLIB_AVAILABLE_IN_ALL +gboolean g_type_check_value_holds (const GValue *value, + GType type) G_GNUC_PURE; +GLIB_AVAILABLE_IN_ALL +gboolean g_type_test_flags (GType type, + guint flags) G_GNUC_CONST; + + +/* --- debugging functions --- */ +GLIB_AVAILABLE_IN_ALL +const gchar * g_type_name_from_instance (GTypeInstance *instance); +GLIB_AVAILABLE_IN_ALL +const gchar * g_type_name_from_class (GTypeClass *g_class); + + +/* --- implementation bits --- */ +#ifndef G_DISABLE_CAST_CHECKS +# define _G_TYPE_CIC(ip, gt, ct) \ + ((ct*) (void *) g_type_check_instance_cast ((GTypeInstance*) ip, gt)) +# define _G_TYPE_CCC(cp, gt, ct) \ + ((ct*) (void *) g_type_check_class_cast ((GTypeClass*) cp, gt)) +#else /* G_DISABLE_CAST_CHECKS */ +# define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip) +# define _G_TYPE_CCC(cp, gt, ct) ((ct*) cp) +#endif /* G_DISABLE_CAST_CHECKS */ +#define _G_TYPE_CHI(ip) (g_type_check_instance ((GTypeInstance*) ip)) +#define _G_TYPE_CHV(vl) (g_type_check_value ((GValue*) vl)) +#define _G_TYPE_IGC(ip, gt, ct) ((ct*) (((GTypeInstance*) ip)->g_class)) +#define _G_TYPE_IGI(ip, gt, ct) ((ct*) g_type_interface_peek (((GTypeInstance*) ip)->g_class, gt)) +#define _G_TYPE_CIFT(ip, ft) (g_type_check_instance_is_fundamentally_a ((GTypeInstance*) ip, ft)) +#ifdef __GNUC__ +# define _G_TYPE_CIT(ip, gt) (G_GNUC_EXTENSION ({ \ + GTypeInstance *__inst = (GTypeInstance*) ip; GType __t = gt; gboolean __r; \ + if (!__inst) \ + __r = FALSE; \ + else if (__inst->g_class && __inst->g_class->g_type == __t) \ + __r = TRUE; \ + else \ + __r = g_type_check_instance_is_a (__inst, __t); \ + __r; \ +})) +# define _G_TYPE_CCT(cp, gt) (G_GNUC_EXTENSION ({ \ + GTypeClass *__class = (GTypeClass*) cp; GType __t = gt; gboolean __r; \ + if (!__class) \ + __r = FALSE; \ + else if (__class->g_type == __t) \ + __r = TRUE; \ + else \ + __r = g_type_check_class_is_a (__class, __t); \ + __r; \ +})) +# define _G_TYPE_CVH(vl, gt) (G_GNUC_EXTENSION ({ \ + const GValue *__val = (const GValue*) vl; GType __t = gt; gboolean __r; \ + if (!__val) \ + __r = FALSE; \ + else if (__val->g_type == __t) \ + __r = TRUE; \ + else \ + __r = g_type_check_value_holds (__val, __t); \ + __r; \ +})) +#else /* !__GNUC__ */ +# define _G_TYPE_CIT(ip, gt) (g_type_check_instance_is_a ((GTypeInstance*) ip, gt)) +# define _G_TYPE_CCT(cp, gt) (g_type_check_class_is_a ((GTypeClass*) cp, gt)) +# define _G_TYPE_CVH(vl, gt) (g_type_check_value_holds ((const GValue*) vl, gt)) +#endif /* !__GNUC__ */ +/** + * G_TYPE_FLAG_RESERVED_ID_BIT: + * + * A bit in the type number that's supposed to be left untouched. + */ +#define G_TYPE_FLAG_RESERVED_ID_BIT ((GType) (1 << 0)) + +G_END_DECLS + +#endif /* __G_TYPE_H__ */ diff --git a/gobject/gtypemodule.c b/gobject/gtypemodule.c new file mode 100644 index 0000000..1c2ab43 --- /dev/null +++ b/gobject/gtypemodule.c @@ -0,0 +1,602 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" + +#include + +#include "gtypeplugin.h" +#include "gtypemodule.h" + + +/** + * SECTION:gtypemodule + * @short_description: Type loading modules + * @see_also: #GTypePlugin, #GModule + * @title: GTypeModule + * + * #GTypeModule provides a simple implementation of the #GTypePlugin + * interface. + * + * The model of #GTypeModule is a dynamically loaded module which + * implements some number of types and interface implementations. + * + * When the module is loaded, it registers its types and interfaces + * using g_type_module_register_type() and g_type_module_add_interface(). + * As long as any instances of these types and interface implementations + * are in use, the module is kept loaded. When the types and interfaces + * are gone, the module may be unloaded. If the types and interfaces + * become used again, the module will be reloaded. Note that the last + * reference cannot be released from within the module code, since that + * would lead to the caller's code being unloaded before g_object_unref() + * returns to it. + * + * Keeping track of whether the module should be loaded or not is done by + * using a use count - it starts at zero, and whenever it is greater than + * zero, the module is loaded. The use count is maintained internally by + * the type system, but also can be explicitly controlled by + * g_type_module_use() and g_type_module_unuse(). Typically, when loading + * a module for the first type, g_type_module_use() will be used to load + * it so that it can initialize its types. At some later point, when the + * module no longer needs to be loaded except for the type + * implementations it contains, g_type_module_unuse() is called. + * + * #GTypeModule does not actually provide any implementation of module + * loading and unloading. To create a particular module type you must + * derive from #GTypeModule and implement the load and unload functions + * in #GTypeModuleClass. + */ + +typedef struct _ModuleTypeInfo ModuleTypeInfo; +typedef struct _ModuleInterfaceInfo ModuleInterfaceInfo; + +struct _ModuleTypeInfo +{ + gboolean loaded; + GType type; + GType parent_type; + GTypeInfo info; +}; + +struct _ModuleInterfaceInfo +{ + gboolean loaded; + GType instance_type; + GType interface_type; + GInterfaceInfo info; +}; + +static void g_type_module_use_plugin (GTypePlugin *plugin); +static void g_type_module_complete_type_info (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table); +static void g_type_module_complete_interface_info (GTypePlugin *plugin, + GType instance_type, + GType interface_type, + GInterfaceInfo *info); + +static gpointer parent_class = NULL; + +static void +g_type_module_dispose (GObject *object) +{ + GTypeModule *module = G_TYPE_MODULE (object); + + if (module->type_infos || module->interface_infos) + { + g_warning (G_STRLOC ": unsolicitated invocation of g_object_run_dispose() on GTypeModule"); + + g_object_ref (object); + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +g_type_module_finalize (GObject *object) +{ + GTypeModule *module = G_TYPE_MODULE (object); + + g_free (module->name); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +g_type_module_class_init (GTypeModuleClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class)); + + gobject_class->dispose = g_type_module_dispose; + gobject_class->finalize = g_type_module_finalize; +} + +static void +g_type_module_iface_init (GTypePluginClass *iface) +{ + iface->use_plugin = g_type_module_use_plugin; + iface->unuse_plugin = (void (*) (GTypePlugin *))g_type_module_unuse; + iface->complete_type_info = g_type_module_complete_type_info; + iface->complete_interface_info = g_type_module_complete_interface_info; +} + +GType +g_type_module_get_type (void) +{ + static GType type_module_type = 0; + + if (!type_module_type) + { + const GTypeInfo type_module_info = { + sizeof (GTypeModuleClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) g_type_module_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GTypeModule), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) g_type_module_iface_init, + NULL, /* interface_finalize */ + NULL, /* interface_data */ + }; + + type_module_type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("GTypeModule"), &type_module_info, G_TYPE_FLAG_ABSTRACT); + + g_type_add_interface_static (type_module_type, G_TYPE_TYPE_PLUGIN, &iface_info); + } + + return type_module_type; +} + +/** + * g_type_module_set_name: + * @module: a #GTypeModule. + * @name: a human-readable name to use in error messages. + * + * Sets the name for a #GTypeModule + */ +void +g_type_module_set_name (GTypeModule *module, + const gchar *name) +{ + g_return_if_fail (G_IS_TYPE_MODULE (module)); + + g_free (module->name); + module->name = g_strdup (name); +} + +static ModuleTypeInfo * +g_type_module_find_type_info (GTypeModule *module, + GType type) +{ + GSList *tmp_list = module->type_infos; + while (tmp_list) + { + ModuleTypeInfo *type_info = tmp_list->data; + if (type_info->type == type) + return type_info; + + tmp_list = tmp_list->next; + } + + return NULL; +} + +static ModuleInterfaceInfo * +g_type_module_find_interface_info (GTypeModule *module, + GType instance_type, + GType interface_type) +{ + GSList *tmp_list = module->interface_infos; + while (tmp_list) + { + ModuleInterfaceInfo *interface_info = tmp_list->data; + if (interface_info->instance_type == instance_type && + interface_info->interface_type == interface_type) + return interface_info; + + tmp_list = tmp_list->next; + } + + return NULL; +} + +/** + * g_type_module_use: + * @module: a #GTypeModule + * + * Increases the use count of a #GTypeModule by one. If the + * use count was zero before, the plugin will be loaded. + * If loading the plugin fails, the use count is reset to + * its prior value. + * + * Returns: %FALSE if the plugin needed to be loaded and + * loading the plugin failed. + */ +gboolean +g_type_module_use (GTypeModule *module) +{ + g_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE); + + module->use_count++; + if (module->use_count == 1) + { + GSList *tmp_list; + + if (!G_TYPE_MODULE_GET_CLASS (module)->load (module)) + { + module->use_count--; + return FALSE; + } + + tmp_list = module->type_infos; + while (tmp_list) + { + ModuleTypeInfo *type_info = tmp_list->data; + if (!type_info->loaded) + { + g_warning ("plugin '%s' failed to register type '%s'", + module->name ? module->name : "(unknown)", + g_type_name (type_info->type)); + module->use_count--; + return FALSE; + } + + tmp_list = tmp_list->next; + } + } + + return TRUE; +} + +/** + * g_type_module_unuse: + * @module: a #GTypeModule + * + * Decreases the use count of a #GTypeModule by one. If the + * result is zero, the module will be unloaded. (However, the + * #GTypeModule will not be freed, and types associated with the + * #GTypeModule are not unregistered. Once a #GTypeModule is + * initialized, it must exist forever.) + */ +void +g_type_module_unuse (GTypeModule *module) +{ + g_return_if_fail (G_IS_TYPE_MODULE (module)); + g_return_if_fail (module->use_count > 0); + + module->use_count--; + + if (module->use_count == 0) + { + GSList *tmp_list; + + G_TYPE_MODULE_GET_CLASS (module)->unload (module); + + tmp_list = module->type_infos; + while (tmp_list) + { + ModuleTypeInfo *type_info = tmp_list->data; + type_info->loaded = FALSE; + + tmp_list = tmp_list->next; + } + } +} + +static void +g_type_module_use_plugin (GTypePlugin *plugin) +{ + GTypeModule *module = G_TYPE_MODULE (plugin); + + if (!g_type_module_use (module)) + { + g_warning ("Fatal error - Could not reload previously loaded plugin '%s'", + module->name ? module->name : "(unknown)"); + exit (1); + } +} + +static void +g_type_module_complete_type_info (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table) +{ + GTypeModule *module = G_TYPE_MODULE (plugin); + ModuleTypeInfo *module_type_info = g_type_module_find_type_info (module, g_type); + + *info = module_type_info->info; + + if (module_type_info->info.value_table) + *value_table = *module_type_info->info.value_table; +} + +static void +g_type_module_complete_interface_info (GTypePlugin *plugin, + GType instance_type, + GType interface_type, + GInterfaceInfo *info) +{ + GTypeModule *module = G_TYPE_MODULE (plugin); + ModuleInterfaceInfo *module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type); + + *info = module_interface_info->info; +} + +/** + * g_type_module_register_type: + * @module: (nullable): a #GTypeModule + * @parent_type: the type for the parent class + * @type_name: name for the type + * @type_info: type information structure + * @flags: flags field providing details about the type + * + * Looks up or registers a type that is implemented with a particular + * type plugin. If a type with name @type_name was previously registered, + * the #GType identifier for the type is returned, otherwise the type + * is newly registered, and the resulting #GType identifier returned. + * + * When reregistering a type (typically because a module is unloaded + * then reloaded, and reinitialized), @module and @parent_type must + * be the same as they were previously. + * + * As long as any instances of the type exist, the type plugin will + * not be unloaded. + * + * Since 2.56 if @module is %NULL this will call g_type_register_static() + * instead. This can be used when making a static build of the module. + * + * Returns: the new or existing type ID + */ +GType +g_type_module_register_type (GTypeModule *module, + GType parent_type, + const gchar *type_name, + const GTypeInfo *type_info, + GTypeFlags flags) +{ + ModuleTypeInfo *module_type_info = NULL; + GType type; + + g_return_val_if_fail (type_name != NULL, 0); + g_return_val_if_fail (type_info != NULL, 0); + + if (module == NULL) + { + /* Cannot pass type_info directly to g_type_register_static() here because + * it has class_finalize != NULL and that's forbidden for static types */ + return g_type_register_static_simple (parent_type, + type_name, + type_info->class_size, + type_info->class_init, + type_info->instance_size, + type_info->instance_init, + flags); + } + + type = g_type_from_name (type_name); + if (type) + { + GTypePlugin *old_plugin = g_type_get_plugin (type); + + if (old_plugin != G_TYPE_PLUGIN (module)) + { + g_warning ("Two different plugins tried to register '%s'.", type_name); + return 0; + } + } + + if (type) + { + module_type_info = g_type_module_find_type_info (module, type); + + if (module_type_info->parent_type != parent_type) + { + const gchar *parent_type_name = g_type_name (parent_type); + + g_warning ("Type '%s' recreated with different parent type." + "(was '%s', now '%s')", type_name, + g_type_name (module_type_info->parent_type), + parent_type_name ? parent_type_name : "(unknown)"); + return 0; + } + + if (module_type_info->info.value_table) + g_free ((GTypeValueTable *) module_type_info->info.value_table); + } + else + { + module_type_info = g_new (ModuleTypeInfo, 1); + + module_type_info->parent_type = parent_type; + module_type_info->type = g_type_register_dynamic (parent_type, type_name, G_TYPE_PLUGIN (module), flags); + + module->type_infos = g_slist_prepend (module->type_infos, module_type_info); + } + + module_type_info->loaded = TRUE; + module_type_info->info = *type_info; + if (type_info->value_table) + module_type_info->info.value_table = g_memdup2 (type_info->value_table, + sizeof (GTypeValueTable)); + + return module_type_info->type; +} + +/** + * g_type_module_add_interface: + * @module: (nullable): a #GTypeModule + * @instance_type: type to which to add the interface. + * @interface_type: interface type to add + * @interface_info: type information structure + * + * Registers an additional interface for a type, whose interface lives + * in the given type plugin. If the interface was already registered + * for the type in this plugin, nothing will be done. + * + * As long as any instances of the type exist, the type plugin will + * not be unloaded. + * + * Since 2.56 if @module is %NULL this will call g_type_add_interface_static() + * instead. This can be used when making a static build of the module. + */ +void +g_type_module_add_interface (GTypeModule *module, + GType instance_type, + GType interface_type, + const GInterfaceInfo *interface_info) +{ + ModuleInterfaceInfo *module_interface_info = NULL; + + g_return_if_fail (interface_info != NULL); + + if (module == NULL) + { + g_type_add_interface_static (instance_type, interface_type, interface_info); + return; + } + + if (g_type_is_a (instance_type, interface_type)) + { + GTypePlugin *old_plugin = g_type_interface_get_plugin (instance_type, + interface_type); + + if (!old_plugin) + { + g_warning ("Interface '%s' for '%s' was previously registered statically or for a parent type.", + g_type_name (interface_type), g_type_name (instance_type)); + return; + } + else if (old_plugin != G_TYPE_PLUGIN (module)) + { + g_warning ("Two different plugins tried to register interface '%s' for '%s'.", + g_type_name (interface_type), g_type_name (instance_type)); + return; + } + + module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type); + + g_assert (module_interface_info); + } + else + { + module_interface_info = g_new (ModuleInterfaceInfo, 1); + + module_interface_info->instance_type = instance_type; + module_interface_info->interface_type = interface_type; + + g_type_add_interface_dynamic (instance_type, interface_type, G_TYPE_PLUGIN (module)); + + module->interface_infos = g_slist_prepend (module->interface_infos, module_interface_info); + } + + module_interface_info->loaded = TRUE; + module_interface_info->info = *interface_info; +} + +/** + * g_type_module_register_enum: + * @module: (nullable): a #GTypeModule + * @name: name for the type + * @const_static_values: an array of #GEnumValue structs for the + * possible enumeration values. The array is + * terminated by a struct with all members being + * 0. + * + * Looks up or registers an enumeration that is implemented with a particular + * type plugin. If a type with name @type_name was previously registered, + * the #GType identifier for the type is returned, otherwise the type + * is newly registered, and the resulting #GType identifier returned. + * + * As long as any instances of the type exist, the type plugin will + * not be unloaded. + * + * Since 2.56 if @module is %NULL this will call g_type_register_static() + * instead. This can be used when making a static build of the module. + * + * Since: 2.6 + * + * Returns: the new or existing type ID + */ +GType +g_type_module_register_enum (GTypeModule *module, + const gchar *name, + const GEnumValue *const_static_values) +{ + GTypeInfo enum_type_info = { 0, }; + + g_return_val_if_fail (module == NULL || G_IS_TYPE_MODULE (module), 0); + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (const_static_values != NULL, 0); + + g_enum_complete_type_info (G_TYPE_ENUM, + &enum_type_info, const_static_values); + + return g_type_module_register_type (G_TYPE_MODULE (module), + G_TYPE_ENUM, name, &enum_type_info, 0); +} + +/** + * g_type_module_register_flags: + * @module: (nullable): a #GTypeModule + * @name: name for the type + * @const_static_values: an array of #GFlagsValue structs for the + * possible flags values. The array is + * terminated by a struct with all members being + * 0. + * + * Looks up or registers a flags type that is implemented with a particular + * type plugin. If a type with name @type_name was previously registered, + * the #GType identifier for the type is returned, otherwise the type + * is newly registered, and the resulting #GType identifier returned. + * + * As long as any instances of the type exist, the type plugin will + * not be unloaded. + * + * Since 2.56 if @module is %NULL this will call g_type_register_static() + * instead. This can be used when making a static build of the module. + * + * Since: 2.6 + * + * Returns: the new or existing type ID + */ +GType +g_type_module_register_flags (GTypeModule *module, + const gchar *name, + const GFlagsValue *const_static_values) +{ + GTypeInfo flags_type_info = { 0, }; + + g_return_val_if_fail (module == NULL || G_IS_TYPE_MODULE (module), 0); + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (const_static_values != NULL, 0); + + g_flags_complete_type_info (G_TYPE_FLAGS, + &flags_type_info, const_static_values); + + return g_type_module_register_type (G_TYPE_MODULE (module), + G_TYPE_FLAGS, name, &flags_type_info, 0); +} diff --git a/gobject/gtypemodule.h b/gobject/gtypemodule.h new file mode 100644 index 0000000..400d7f1 --- /dev/null +++ b/gobject/gtypemodule.h @@ -0,0 +1,300 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#ifndef __G_TYPE_MODULE_H__ +#define __G_TYPE_MODULE_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GTypeModule GTypeModule; +typedef struct _GTypeModuleClass GTypeModuleClass; + +#define G_TYPE_TYPE_MODULE (g_type_module_get_type ()) +#define G_TYPE_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), G_TYPE_TYPE_MODULE, GTypeModule)) +#define G_TYPE_MODULE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_TYPE_MODULE, GTypeModuleClass)) +#define G_IS_TYPE_MODULE(module) (G_TYPE_CHECK_INSTANCE_TYPE ((module), G_TYPE_TYPE_MODULE)) +#define G_IS_TYPE_MODULE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_TYPE_MODULE)) +#define G_TYPE_MODULE_GET_CLASS(module) (G_TYPE_INSTANCE_GET_CLASS ((module), G_TYPE_TYPE_MODULE, GTypeModuleClass)) + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GTypeModule, g_object_unref) + +/** + * GTypeModule: + * @name: the name of the module + * + * The members of the GTypeModule structure should not + * be accessed directly, except for the @name field. + */ +struct _GTypeModule +{ + GObject parent_instance; + + guint use_count; + GSList *type_infos; + GSList *interface_infos; + + /*< public >*/ + gchar *name; +}; + +/** + * GTypeModuleClass: + * @parent_class: the parent class + * @load: loads the module and registers one or more types using + * g_type_module_register_type(). + * @unload: unloads the module + * + * In order to implement dynamic loading of types based on #GTypeModule, + * the @load and @unload functions in #GTypeModuleClass must be implemented. + */ +struct _GTypeModuleClass +{ + GObjectClass parent_class; + + /*< public >*/ + gboolean (* load) (GTypeModule *module); + void (* unload) (GTypeModule *module); + + /*< private >*/ + /* Padding for future expansion */ + void (*reserved1) (void); + void (*reserved2) (void); + void (*reserved3) (void); + void (*reserved4) (void); +}; + +/** + * G_DEFINE_DYNAMIC_TYPE: + * @TN: The name of the new type, in Camel case. + * @t_n: The name of the new type, in lowercase, with words + * separated by '_'. + * @T_P: The #GType of the parent type. + * + * A convenience macro for dynamic type implementations, which declares a + * class initialization function, an instance initialization function (see + * #GTypeInfo for information about these) and a static variable named + * `t_n`_parent_class pointing to the parent class. + * + * Furthermore, it defines a `*_get_type()` and a static `*_register_type()` + * functions for use in your `module_init()`. + * + * See G_DEFINE_DYNAMIC_TYPE_EXTENDED() for an example. + * + * Since: 2.14 + */ +#define G_DEFINE_DYNAMIC_TYPE(TN, t_n, T_P) G_DEFINE_DYNAMIC_TYPE_EXTENDED (TN, t_n, T_P, 0, {}) +/** + * G_DEFINE_DYNAMIC_TYPE_EXTENDED: + * @TypeName: The name of the new type, in Camel case. + * @type_name: The name of the new type, in lowercase, with words + * separated by '_'. + * @TYPE_PARENT: The #GType of the parent type. + * @flags: #GTypeFlags to pass to g_type_module_register_type() + * @CODE: Custom code that gets inserted in the *_get_type() function. + * + * A more general version of G_DEFINE_DYNAMIC_TYPE() which + * allows to specify #GTypeFlags and custom code. + * + * |[ + * G_DEFINE_DYNAMIC_TYPE_EXTENDED (GtkGadget, + * gtk_gadget, + * GTK_TYPE_THING, + * 0, + * G_IMPLEMENT_INTERFACE_DYNAMIC (TYPE_GIZMO, + * gtk_gadget_gizmo_init)); + * ]| + * + * expands to + * + * |[ + * static void gtk_gadget_init (GtkGadget *self); + * static void gtk_gadget_class_init (GtkGadgetClass *klass); + * static void gtk_gadget_class_finalize (GtkGadgetClass *klass); + * + * static gpointer gtk_gadget_parent_class = NULL; + * static GType gtk_gadget_type_id = 0; + * + * static void gtk_gadget_class_intern_init (gpointer klass) + * { + * gtk_gadget_parent_class = g_type_class_peek_parent (klass); + * gtk_gadget_class_init ((GtkGadgetClass*) klass); + * } + * + * GType + * gtk_gadget_get_type (void) + * { + * return gtk_gadget_type_id; + * } + * + * static void + * gtk_gadget_register_type (GTypeModule *type_module) + * { + * const GTypeInfo g_define_type_info = { + * sizeof (GtkGadgetClass), + * (GBaseInitFunc) NULL, + * (GBaseFinalizeFunc) NULL, + * (GClassInitFunc) gtk_gadget_class_intern_init, + * (GClassFinalizeFunc) gtk_gadget_class_finalize, + * NULL, // class_data + * sizeof (GtkGadget), + * 0, // n_preallocs + * (GInstanceInitFunc) gtk_gadget_init, + * NULL // value_table + * }; + * gtk_gadget_type_id = g_type_module_register_type (type_module, + * GTK_TYPE_THING, + * "GtkGadget", + * &g_define_type_info, + * (GTypeFlags) flags); + * { + * const GInterfaceInfo g_implement_interface_info = { + * (GInterfaceInitFunc) gtk_gadget_gizmo_init + * }; + * g_type_module_add_interface (type_module, g_define_type_id, TYPE_GIZMO, &g_implement_interface_info); + * } + * } + * ]| + * + * Since: 2.14 + */ +#define G_DEFINE_DYNAMIC_TYPE_EXTENDED(TypeName, type_name, TYPE_PARENT, flags, CODE) \ +static void type_name##_init (TypeName *self); \ +static void type_name##_class_init (TypeName##Class *klass); \ +static void type_name##_class_finalize (TypeName##Class *klass); \ +static gpointer type_name##_parent_class = NULL; \ +static GType type_name##_type_id = 0; \ +static gint TypeName##_private_offset; \ +\ +_G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \ +\ +G_GNUC_UNUSED \ +static inline gpointer \ +type_name##_get_instance_private (TypeName *self) \ +{ \ + return (G_STRUCT_MEMBER_P (self, TypeName##_private_offset)); \ +} \ +\ +GType \ +type_name##_get_type (void) \ +{ \ + return type_name##_type_id; \ +} \ +static void \ +type_name##_register_type (GTypeModule *type_module) \ +{ \ + GType g_define_type_id G_GNUC_UNUSED; \ + const GTypeInfo g_define_type_info = { \ + sizeof (TypeName##Class), \ + (GBaseInitFunc) NULL, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc)(void (*)(void)) type_name##_class_intern_init, \ + (GClassFinalizeFunc)(void (*)(void)) type_name##_class_finalize, \ + NULL, /* class_data */ \ + sizeof (TypeName), \ + 0, /* n_preallocs */ \ + (GInstanceInitFunc)(void (*)(void)) type_name##_init, \ + NULL /* value_table */ \ + }; \ + type_name##_type_id = g_type_module_register_type (type_module, \ + TYPE_PARENT, \ + #TypeName, \ + &g_define_type_info, \ + (GTypeFlags) flags); \ + g_define_type_id = type_name##_type_id; \ + { CODE ; } \ +} + +/** + * G_IMPLEMENT_INTERFACE_DYNAMIC: + * @TYPE_IFACE: The #GType of the interface to add + * @iface_init: The interface init function + * + * A convenience macro to ease interface addition in the @_C_ section + * of G_DEFINE_DYNAMIC_TYPE_EXTENDED(). + * + * See G_DEFINE_DYNAMIC_TYPE_EXTENDED() for an example. + * + * Note that this macro can only be used together with the + * G_DEFINE_DYNAMIC_TYPE_EXTENDED macros, since it depends on variable + * names from that macro. + * + * Since: 2.24 + */ +#define G_IMPLEMENT_INTERFACE_DYNAMIC(TYPE_IFACE, iface_init) { \ + const GInterfaceInfo g_implement_interface_info = { \ + (GInterfaceInitFunc)(void (*)(void)) iface_init, NULL, NULL \ + }; \ + g_type_module_add_interface (type_module, g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \ +} + +/** + * G_ADD_PRIVATE_DYNAMIC: + * @TypeName: the name of the type in CamelCase + * + * A convenience macro to ease adding private data to instances of a new dynamic + * type in the @_C_ section of G_DEFINE_DYNAMIC_TYPE_EXTENDED(). + * + * See G_ADD_PRIVATE() for details, it is similar but for static types. + * + * Note that this macro can only be used together with the + * G_DEFINE_DYNAMIC_TYPE_EXTENDED macros, since it depends on variable + * names from that macro. + * + * Since: 2.38 + */ +#define G_ADD_PRIVATE_DYNAMIC(TypeName) { \ + TypeName##_private_offset = sizeof (TypeName##Private); \ +} + +GLIB_AVAILABLE_IN_ALL +GType g_type_module_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +gboolean g_type_module_use (GTypeModule *module); +GLIB_AVAILABLE_IN_ALL +void g_type_module_unuse (GTypeModule *module); +GLIB_AVAILABLE_IN_ALL +void g_type_module_set_name (GTypeModule *module, + const gchar *name); +GLIB_AVAILABLE_IN_ALL +GType g_type_module_register_type (GTypeModule *module, + GType parent_type, + const gchar *type_name, + const GTypeInfo *type_info, + GTypeFlags flags); +GLIB_AVAILABLE_IN_ALL +void g_type_module_add_interface (GTypeModule *module, + GType instance_type, + GType interface_type, + const GInterfaceInfo *interface_info); +GLIB_AVAILABLE_IN_ALL +GType g_type_module_register_enum (GTypeModule *module, + const gchar *name, + const GEnumValue *const_static_values); +GLIB_AVAILABLE_IN_ALL +GType g_type_module_register_flags (GTypeModule *module, + const gchar *name, + const GFlagsValue *const_static_values); + +G_END_DECLS + +#endif /* __G_TYPE_MODULE_H__ */ diff --git a/gobject/gtypeplugin.c b/gobject/gtypeplugin.c new file mode 100644 index 0000000..30e38c1 --- /dev/null +++ b/gobject/gtypeplugin.c @@ -0,0 +1,203 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include "gtypeplugin.h" + + +/** + * SECTION:gtypeplugin + * @short_description: An interface for dynamically loadable types + * @see_also: #GTypeModule and g_type_register_dynamic(). + * @title: GTypePlugin + * + * An interface that handles the lifecycle of dynamically loaded types. + * + * The GObject type system supports dynamic loading of types. + * It goes as follows: + * + * 1. The type is initially introduced (usually upon loading the module + * the first time, or by your main application that knows what modules + * introduces what types), like this: + * |[ + * new_type_id = g_type_register_dynamic (parent_type_id, + * "TypeName", + * new_type_plugin, + * type_flags); + * ]| + * where @new_type_plugin is an implementation of the + * #GTypePlugin interface. + * + * 2. The type's implementation is referenced, e.g. through + * g_type_class_ref() or through g_type_create_instance() (this is + * being called by g_object_new()) or through one of the above done on + * a type derived from @new_type_id. + * + * 3. This causes the type system to load the type's implementation by + * calling g_type_plugin_use() and g_type_plugin_complete_type_info() + * on @new_type_plugin. + * + * 4. At some point the type's implementation isn't required anymore, + * e.g. after g_type_class_unref() or g_type_free_instance() (called + * when the reference count of an instance drops to zero). + * + * 5. This causes the type system to throw away the information retrieved + * from g_type_plugin_complete_type_info() and then it calls + * g_type_plugin_unuse() on @new_type_plugin. + * + * 6. Things may repeat from the second step. + * + * So basically, you need to implement a #GTypePlugin type that + * carries a use_count, once use_count goes from zero to one, you need + * to load the implementation to successfully handle the upcoming + * g_type_plugin_complete_type_info() call. Later, maybe after + * succeeding use/unuse calls, once use_count drops to zero, you can + * unload the implementation again. The type system makes sure to call + * g_type_plugin_use() and g_type_plugin_complete_type_info() again + * when the type is needed again. + * + * #GTypeModule is an implementation of #GTypePlugin that already + * implements most of this except for the actual module loading and + * unloading. It even handles multiple registered types per module. + */ + + +/* --- functions --- */ +GType +g_type_plugin_get_type (void) +{ + static GType type_plugin_type = 0; + + if (!type_plugin_type) + { + const GTypeInfo type_plugin_info = { + sizeof (GTypePluginClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + 0, /* class_init */ + NULL, /* class_destroy */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + + type_plugin_type = g_type_register_static (G_TYPE_INTERFACE, g_intern_static_string ("GTypePlugin"), &type_plugin_info, 0); + } + + return type_plugin_type; +} + +/** + * g_type_plugin_use: + * @plugin: a #GTypePlugin + * + * Calls the @use_plugin function from the #GTypePluginClass of + * @plugin. There should be no need to use this function outside of + * the GObject type system itself. + */ +void +g_type_plugin_use (GTypePlugin *plugin) +{ + GTypePluginClass *iface; + + g_return_if_fail (G_IS_TYPE_PLUGIN (plugin)); + + iface = G_TYPE_PLUGIN_GET_CLASS (plugin); + iface->use_plugin (plugin); +} + +/** + * g_type_plugin_unuse: + * @plugin: a #GTypePlugin + * + * Calls the @unuse_plugin function from the #GTypePluginClass of + * @plugin. There should be no need to use this function outside of + * the GObject type system itself. + */ +void +g_type_plugin_unuse (GTypePlugin *plugin) +{ + GTypePluginClass *iface; + + g_return_if_fail (G_IS_TYPE_PLUGIN (plugin)); + + iface = G_TYPE_PLUGIN_GET_CLASS (plugin); + iface->unuse_plugin (plugin); +} + +/** + * g_type_plugin_complete_type_info: + * @plugin: a #GTypePlugin + * @g_type: the #GType whose info is completed + * @info: the #GTypeInfo struct to fill in + * @value_table: the #GTypeValueTable to fill in + * + * Calls the @complete_type_info function from the #GTypePluginClass of @plugin. + * There should be no need to use this function outside of the GObject + * type system itself. + */ +void +g_type_plugin_complete_type_info (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table) +{ + GTypePluginClass *iface; + + g_return_if_fail (G_IS_TYPE_PLUGIN (plugin)); + g_return_if_fail (info != NULL); + g_return_if_fail (value_table != NULL); + + iface = G_TYPE_PLUGIN_GET_CLASS (plugin); + iface->complete_type_info (plugin, + g_type, + info, + value_table); +} + +/** + * g_type_plugin_complete_interface_info: + * @plugin: the #GTypePlugin + * @instance_type: the #GType of an instantiatable type to which the interface + * is added + * @interface_type: the #GType of the interface whose info is completed + * @info: the #GInterfaceInfo to fill in + * + * Calls the @complete_interface_info function from the + * #GTypePluginClass of @plugin. There should be no need to use this + * function outside of the GObject type system itself. + */ +void +g_type_plugin_complete_interface_info (GTypePlugin *plugin, + GType instance_type, + GType interface_type, + GInterfaceInfo *info) +{ + GTypePluginClass *iface; + + g_return_if_fail (G_IS_TYPE_PLUGIN (plugin)); + g_return_if_fail (info != NULL); + + iface = G_TYPE_PLUGIN_GET_CLASS (plugin); + iface->complete_interface_info (plugin, + instance_type, + interface_type, + info); +} diff --git a/gobject/gtypeplugin.h b/gobject/gtypeplugin.h new file mode 100644 index 0000000..de114fe --- /dev/null +++ b/gobject/gtypeplugin.h @@ -0,0 +1,134 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#ifndef __G_TYPE_PLUGIN_H__ +#define __G_TYPE_PLUGIN_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* --- type macros --- */ +#define G_TYPE_TYPE_PLUGIN (g_type_plugin_get_type ()) +#define G_TYPE_PLUGIN(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TYPE_PLUGIN, GTypePlugin)) +#define G_TYPE_PLUGIN_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), G_TYPE_TYPE_PLUGIN, GTypePluginClass)) +#define G_IS_TYPE_PLUGIN(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TYPE_PLUGIN)) +#define G_IS_TYPE_PLUGIN_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), G_TYPE_TYPE_PLUGIN)) +#define G_TYPE_PLUGIN_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_TYPE_PLUGIN, GTypePluginClass)) + + +/* --- typedefs & structures --- */ +typedef struct _GTypePluginClass GTypePluginClass; +/** + * GTypePluginUse: + * @plugin: the #GTypePlugin whose use count should be increased + * + * The type of the @use_plugin function of #GTypePluginClass, which gets called + * to increase the use count of @plugin. + */ +typedef void (*GTypePluginUse) (GTypePlugin *plugin); +/** + * GTypePluginUnuse: + * @plugin: the #GTypePlugin whose use count should be decreased + * + * The type of the @unuse_plugin function of #GTypePluginClass. + */ +typedef void (*GTypePluginUnuse) (GTypePlugin *plugin); +/** + * GTypePluginCompleteTypeInfo: + * @plugin: the #GTypePlugin + * @g_type: the #GType whose info is completed + * @info: the #GTypeInfo struct to fill in + * @value_table: the #GTypeValueTable to fill in + * + * The type of the @complete_type_info function of #GTypePluginClass. + */ +typedef void (*GTypePluginCompleteTypeInfo) (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table); +/** + * GTypePluginCompleteInterfaceInfo: + * @plugin: the #GTypePlugin + * @instance_type: the #GType of an instantiatable type to which the interface + * is added + * @interface_type: the #GType of the interface whose info is completed + * @info: the #GInterfaceInfo to fill in + * + * The type of the @complete_interface_info function of #GTypePluginClass. + */ +typedef void (*GTypePluginCompleteInterfaceInfo) (GTypePlugin *plugin, + GType instance_type, + GType interface_type, + GInterfaceInfo *info); +/** + * GTypePlugin: + * + * The GTypePlugin typedef is used as a placeholder + * for objects that implement the GTypePlugin interface. + */ +/** + * GTypePluginClass: + * @use_plugin: Increases the use count of the plugin. + * @unuse_plugin: Decreases the use count of the plugin. + * @complete_type_info: Fills in the #GTypeInfo and + * #GTypeValueTable structs for the type. The structs are initialized + * with `memset(s, 0, sizeof (s))` before calling this function. + * @complete_interface_info: Fills in missing parts of the #GInterfaceInfo + * for the interface. The structs is initialized with + * `memset(s, 0, sizeof (s))` before calling this function. + * + * The #GTypePlugin interface is used by the type system in order to handle + * the lifecycle of dynamically loaded types. + */ +struct _GTypePluginClass +{ + /*< private >*/ + GTypeInterface base_iface; + + /*< public >*/ + GTypePluginUse use_plugin; + GTypePluginUnuse unuse_plugin; + GTypePluginCompleteTypeInfo complete_type_info; + GTypePluginCompleteInterfaceInfo complete_interface_info; +}; + + +/* --- prototypes --- */ +GLIB_AVAILABLE_IN_ALL +GType g_type_plugin_get_type (void) G_GNUC_CONST; +GLIB_AVAILABLE_IN_ALL +void g_type_plugin_use (GTypePlugin *plugin); +GLIB_AVAILABLE_IN_ALL +void g_type_plugin_unuse (GTypePlugin *plugin); +GLIB_AVAILABLE_IN_ALL +void g_type_plugin_complete_type_info (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table); +GLIB_AVAILABLE_IN_ALL +void g_type_plugin_complete_interface_info (GTypePlugin *plugin, + GType instance_type, + GType interface_type, + GInterfaceInfo *info); + +G_END_DECLS + +#endif /* __G_TYPE_PLUGIN_H__ */ diff --git a/gobject/gvalue.c b/gobject/gvalue.c new file mode 100644 index 0000000..0977550 --- /dev/null +++ b/gobject/gvalue.c @@ -0,0 +1,675 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * FIXME: MT-safety + */ + +#include "config.h" + +#include + +#include "gvalue.h" +#include "gvaluecollector.h" +#include "gbsearcharray.h" +#include "gtype-private.h" + + +/** + * SECTION:generic_values + * @short_description: A polymorphic type that can hold values of any + * other type + * @see_also: The fundamental types which all support #GValue + * operations and thus can be used as a type initializer for + * g_value_init() are defined by a separate interface. See the + * [standard values API][gobject-Standard-Parameter-and-Value-Types] + * for details + * @title: Generic values + * + * The #GValue structure is basically a variable container that consists + * of a type identifier and a specific value of that type. + * + * The type identifier within a #GValue structure always determines the + * type of the associated value. + * + * To create an undefined #GValue structure, simply create a zero-filled + * #GValue structure. To initialize the #GValue, use the g_value_init() + * function. A #GValue cannot be used until it is initialized. Before + * destruction you must always use g_value_unset() to make sure allocated + * memory is freed. + * + * The basic type operations (such as freeing and copying) are determined + * by the #GTypeValueTable associated with the type ID stored in the #GValue. + * Other #GValue operations (such as converting values between types) are + * provided by this interface. + * + * The code in the example program below demonstrates #GValue's + * features. + * + * |[ + * #include + * + * static void + * int2string (const GValue *src_value, + * GValue *dest_value) + * { + * if (g_value_get_int (src_value) == 42) + * g_value_set_static_string (dest_value, "An important number"); + * else + * g_value_set_static_string (dest_value, "What's that?"); + * } + * + * int + * main (int argc, + * char *argv[]) + * { + * // GValues must be initialized + * GValue a = G_VALUE_INIT; + * GValue b = G_VALUE_INIT; + * const gchar *message; + * + * // The GValue starts empty + * g_assert (!G_VALUE_HOLDS_STRING (&a)); + * + * // Put a string in it + * g_value_init (&a, G_TYPE_STRING); + * g_assert (G_VALUE_HOLDS_STRING (&a)); + * g_value_set_static_string (&a, "Hello, world!"); + * g_printf ("%s\n", g_value_get_string (&a)); + * + * // Reset it to its pristine state + * g_value_unset (&a); + * + * // It can then be reused for another type + * g_value_init (&a, G_TYPE_INT); + * g_value_set_int (&a, 42); + * + * // Attempt to transform it into a GValue of type STRING + * g_value_init (&b, G_TYPE_STRING); + * + * // An INT is transformable to a STRING + * g_assert (g_value_type_transformable (G_TYPE_INT, G_TYPE_STRING)); + * + * g_value_transform (&a, &b); + * g_printf ("%s\n", g_value_get_string (&b)); + * + * // Attempt to transform it again using a custom transform function + * g_value_register_transform_func (G_TYPE_INT, G_TYPE_STRING, int2string); + * g_value_transform (&a, &b); + * g_printf ("%s\n", g_value_get_string (&b)); + * return 0; + * } + * ]| + * + * See also [gobject-Standard-Parameter-and-Value-Types] for more information on + * validation of #GValue. + * + * For letting a #GValue own (and memory manage) arbitrary types or pointers, + * they need to become a [boxed type][gboxed]. The example below shows how + * the pointer `mystruct` of type `MyStruct` is used as a [boxed type][gboxed]. + * + * |[ + * typedef struct { ... } MyStruct; + * G_DEFINE_BOXED_TYPE (MyStruct, my_struct, my_struct_copy, my_struct_free) + * + * // These two lines normally go in a public header. By GObject convention, + * // the naming scheme is NAMESPACE_TYPE_NAME: + * #define MY_TYPE_STRUCT (my_struct_get_type ()) + * GType my_struct_get_type (void); + * + * void + * foo () + * { + * GValue *value = g_new0 (GValue, 1); + * g_value_init (value, MY_TYPE_STRUCT); + * g_value_set_boxed (value, mystruct); + * // [... your code ....] + * g_value_unset (value); + * g_value_free (value); + * } + * ]| + */ + + +/* --- typedefs & structures --- */ +typedef struct { + GType src_type; + GType dest_type; + GValueTransform func; +} TransformEntry; + + +/* --- prototypes --- */ +static gint transform_entries_cmp (gconstpointer bsearch_node1, + gconstpointer bsearch_node2); + + +/* --- variables --- */ +static GBSearchArray *transform_array = NULL; +static GBSearchConfig transform_bconfig = { + sizeof (TransformEntry), + transform_entries_cmp, + G_BSEARCH_ARRAY_ALIGN_POWER2, +}; + + +/* --- functions --- */ +void +_g_value_c_init (void) +{ + transform_array = g_bsearch_array_create (&transform_bconfig); +} + +static inline void /* keep this function in sync with gvaluecollector.h and gboxed.c */ +value_meminit (GValue *value, + GType value_type) +{ + value->g_type = value_type; + memset (value->data, 0, sizeof (value->data)); +} + +/** + * g_value_init: + * @value: A zero-filled (uninitialized) #GValue structure. + * @g_type: Type the #GValue should hold values of. + * + * Initializes @value with the default value of @type. + * + * Returns: (transfer none): the #GValue structure that has been passed in + */ +GValue* +g_value_init (GValue *value, + GType g_type) +{ + GTypeValueTable *value_table; + /* g_return_val_if_fail (G_TYPE_IS_VALUE (g_type), NULL); be more elaborate below */ + g_return_val_if_fail (value != NULL, NULL); + /* g_return_val_if_fail (G_VALUE_TYPE (value) == 0, NULL); be more elaborate below */ + + value_table = g_type_value_table_peek (g_type); + + if (value_table && G_VALUE_TYPE (value) == 0) + { + /* setup and init */ + value_meminit (value, g_type); + value_table->value_init (value); + } + else if (G_VALUE_TYPE (value)) + g_warning ("%s: cannot initialize GValue with type '%s', the value has already been initialized as '%s'", + G_STRLOC, + g_type_name (g_type), + g_type_name (G_VALUE_TYPE (value))); + else /* !G_TYPE_IS_VALUE (g_type) */ + g_warning ("%s: cannot initialize GValue with type '%s', %s", + G_STRLOC, + g_type_name (g_type), + value_table ? "this type is abstract with regards to GValue use, use a more specific (derived) type" : "this type has no GTypeValueTable implementation"); + return value; +} + +/** + * g_value_copy: + * @src_value: An initialized #GValue structure. + * @dest_value: An initialized #GValue structure of the same type as @src_value. + * + * Copies the value of @src_value into @dest_value. + */ +void +g_value_copy (const GValue *src_value, + GValue *dest_value) +{ + g_return_if_fail (src_value); + g_return_if_fail (dest_value); + g_return_if_fail (g_value_type_compatible (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value))); + + if (src_value != dest_value) + { + GType dest_type = G_VALUE_TYPE (dest_value); + GTypeValueTable *value_table = g_type_value_table_peek (dest_type); + + g_return_if_fail (value_table); + + /* make sure dest_value's value is free()d */ + if (value_table->value_free) + value_table->value_free (dest_value); + + /* setup and copy */ + value_meminit (dest_value, dest_type); + value_table->value_copy (src_value, dest_value); + } +} + +/** + * g_value_reset: + * @value: An initialized #GValue structure. + * + * Clears the current value in @value and resets it to the default value + * (as if the value had just been initialized). + * + * Returns: the #GValue structure that has been passed in + */ +GValue* +g_value_reset (GValue *value) +{ + GTypeValueTable *value_table; + GType g_type; + + g_return_val_if_fail (value, NULL); + g_type = G_VALUE_TYPE (value); + + value_table = g_type_value_table_peek (g_type); + g_return_val_if_fail (value_table, NULL); + + /* make sure value's value is free()d */ + if (value_table->value_free) + value_table->value_free (value); + + /* setup and init */ + value_meminit (value, g_type); + value_table->value_init (value); + + return value; +} + +/** + * g_value_unset: + * @value: An initialized #GValue structure. + * + * Clears the current value in @value (if any) and "unsets" the type, + * this releases all resources associated with this GValue. An unset + * value is the same as an uninitialized (zero-filled) #GValue + * structure. + */ +void +g_value_unset (GValue *value) +{ + GTypeValueTable *value_table; + + if (value->g_type == 0) + return; + + g_return_if_fail (value); + + value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); + g_return_if_fail (value_table); + + if (value_table->value_free) + value_table->value_free (value); + memset (value, 0, sizeof (*value)); +} + +/** + * g_value_fits_pointer: + * @value: An initialized #GValue structure. + * + * Determines if @value will fit inside the size of a pointer value. + * This is an internal function introduced mainly for C marshallers. + * + * Returns: %TRUE if @value will fit inside a pointer value. + */ +gboolean +g_value_fits_pointer (const GValue *value) +{ + GTypeValueTable *value_table; + + g_return_val_if_fail (value, FALSE); + + value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); + g_return_val_if_fail (value_table, FALSE); + + return value_table->value_peek_pointer != NULL; +} + +/** + * g_value_peek_pointer: + * @value: An initialized #GValue structure + * + * Returns the value contents as pointer. This function asserts that + * g_value_fits_pointer() returned %TRUE for the passed in value. + * This is an internal function introduced mainly for C marshallers. + * + * Returns: (transfer none): the value contents as pointer + */ +gpointer +g_value_peek_pointer (const GValue *value) +{ + GTypeValueTable *value_table; + + g_return_val_if_fail (value, NULL); + + value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); + g_return_val_if_fail (value_table, NULL); + + if (!value_table->value_peek_pointer) + { + g_return_val_if_fail (g_value_fits_pointer (value) == TRUE, NULL); + return NULL; + } + + return value_table->value_peek_pointer (value); +} + +/** + * g_value_set_instance: + * @value: An initialized #GValue structure. + * @instance: (nullable): the instance + * + * Sets @value from an instantiatable type via the + * value_table's collect_value() function. + */ +void +g_value_set_instance (GValue *value, + gpointer instance) +{ + GType g_type; + GTypeValueTable *value_table; + GTypeCValue cvalue; + gchar *error_msg; + + g_return_if_fail (value); + g_type = G_VALUE_TYPE (value); + value_table = g_type_value_table_peek (g_type); + g_return_if_fail (value_table); + + if (instance) + { + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (instance), G_VALUE_TYPE (value))); + } + + g_return_if_fail (strcmp (value_table->collect_format, "p") == 0); + + memset (&cvalue, 0, sizeof (cvalue)); + cvalue.v_pointer = instance; + + /* make sure value's value is free()d */ + if (value_table->value_free) + value_table->value_free (value); + + /* setup and collect */ + value_meminit (value, g_type); + error_msg = value_table->collect_value (value, 1, &cvalue, 0); + if (error_msg) + { + g_warning ("%s: %s", G_STRLOC, error_msg); + g_free (error_msg); + + /* we purposely leak the value here, it might not be + * in a correct state if an error condition occurred + */ + value_meminit (value, g_type); + value_table->value_init (value); + } +} + +/** + * g_value_init_from_instance: + * @value: An uninitialized #GValue structure. + * @instance: (type GObject.TypeInstance): the instance + * + * Initializes and sets @value from an instantiatable type via the + * value_table's collect_value() function. + * + * Note: The @value will be initialised with the exact type of + * @instance. If you wish to set the @value's type to a different GType + * (such as a parent class GType), you need to manually call + * g_value_init() and g_value_set_instance(). + * + * Since: 2.42 + */ +void +g_value_init_from_instance (GValue *value, + gpointer instance) +{ + g_return_if_fail (value != NULL && G_VALUE_TYPE(value) == 0); + + if (G_IS_OBJECT (instance)) + { + /* Fast-path. + * If G_IS_OBJECT() succeeds we know: + * * that instance is present and valid + * * that it is a GObject, and therefore we can directly + * use the collect implementation (g_object_ref) */ + value_meminit (value, G_TYPE_FROM_INSTANCE (instance)); + value->data[0].v_pointer = g_object_ref (instance); + } + else + { + GType g_type; + GTypeValueTable *value_table; + GTypeCValue cvalue; + gchar *error_msg; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + + g_type = G_TYPE_FROM_INSTANCE (instance); + value_table = g_type_value_table_peek (g_type); + g_return_if_fail (strcmp (value_table->collect_format, "p") == 0); + + memset (&cvalue, 0, sizeof (cvalue)); + cvalue.v_pointer = instance; + + /* setup and collect */ + value_meminit (value, g_type); + value_table->value_init (value); + error_msg = value_table->collect_value (value, 1, &cvalue, 0); + if (error_msg) + { + g_warning ("%s: %s", G_STRLOC, error_msg); + g_free (error_msg); + + /* we purposely leak the value here, it might not be + * in a correct state if an error condition occurred + */ + value_meminit (value, g_type); + value_table->value_init (value); + } + } +} + +static GType +transform_lookup_get_parent_type (GType type) +{ + if (g_type_fundamental (type) == G_TYPE_INTERFACE) + return g_type_interface_instantiatable_prerequisite (type); + + return g_type_parent (type); +} + +static GValueTransform +transform_func_lookup (GType src_type, + GType dest_type) +{ + TransformEntry entry; + + entry.src_type = src_type; + do + { + entry.dest_type = dest_type; + do + { + TransformEntry *e; + + e = g_bsearch_array_lookup (transform_array, &transform_bconfig, &entry); + if (e) + { + /* need to check that there hasn't been a change in value handling */ + if (g_type_value_table_peek (entry.dest_type) == g_type_value_table_peek (dest_type) && + g_type_value_table_peek (entry.src_type) == g_type_value_table_peek (src_type)) + return e->func; + } + entry.dest_type = transform_lookup_get_parent_type (entry.dest_type); + } + while (entry.dest_type); + + entry.src_type = transform_lookup_get_parent_type (entry.src_type); + } + while (entry.src_type); + + return NULL; +} + +static gint +transform_entries_cmp (gconstpointer bsearch_node1, + gconstpointer bsearch_node2) +{ + const TransformEntry *e1 = bsearch_node1; + const TransformEntry *e2 = bsearch_node2; + gint cmp = G_BSEARCH_ARRAY_CMP (e1->src_type, e2->src_type); + + if (cmp) + return cmp; + else + return G_BSEARCH_ARRAY_CMP (e1->dest_type, e2->dest_type); +} + +/** + * g_value_register_transform_func: (skip) + * @src_type: Source type. + * @dest_type: Target type. + * @transform_func: a function which transforms values of type @src_type + * into value of type @dest_type + * + * Registers a value transformation function for use in g_value_transform(). + * A previously registered transformation function for @src_type and @dest_type + * will be replaced. + */ +void +g_value_register_transform_func (GType src_type, + GType dest_type, + GValueTransform transform_func) +{ + TransformEntry entry; + + /* these checks won't pass for dynamic types. + * g_return_if_fail (G_TYPE_HAS_VALUE_TABLE (src_type)); + * g_return_if_fail (G_TYPE_HAS_VALUE_TABLE (dest_type)); + */ + g_return_if_fail (transform_func != NULL); + + entry.src_type = src_type; + entry.dest_type = dest_type; + +#if 0 /* let transform function replacement be a valid operation */ + if (g_bsearch_array_lookup (transform_array, &transform_bconfig, &entry)) + g_warning ("reregistering value transformation function (%p) for '%s' to '%s'", + transform_func, + g_type_name (src_type), + g_type_name (dest_type)); +#endif + + entry.func = transform_func; + transform_array = g_bsearch_array_replace (transform_array, &transform_bconfig, &entry); +} + +/** + * g_value_type_transformable: + * @src_type: Source type. + * @dest_type: Target type. + * + * Check whether g_value_transform() is able to transform values + * of type @src_type into values of type @dest_type. Note that for + * the types to be transformable, they must be compatible or a + * transformation function must be registered. + * + * Returns: %TRUE if the transformation is possible, %FALSE otherwise. + */ +gboolean +g_value_type_transformable (GType src_type, + GType dest_type) +{ + g_return_val_if_fail (src_type, FALSE); + g_return_val_if_fail (dest_type, FALSE); + + return (g_value_type_compatible (src_type, dest_type) || + transform_func_lookup (src_type, dest_type) != NULL); +} + +/** + * g_value_type_compatible: + * @src_type: source type to be copied. + * @dest_type: destination type for copying. + * + * Returns whether a #GValue of type @src_type can be copied into + * a #GValue of type @dest_type. + * + * Returns: %TRUE if g_value_copy() is possible with @src_type and @dest_type. + */ +gboolean +g_value_type_compatible (GType src_type, + GType dest_type) +{ + g_return_val_if_fail (src_type, FALSE); + g_return_val_if_fail (dest_type, FALSE); + + /* Fast path */ + if (src_type == dest_type) + return TRUE; + + return (g_type_is_a (src_type, dest_type) && + g_type_value_table_peek (dest_type) == g_type_value_table_peek (src_type)); +} + +/** + * g_value_transform: + * @src_value: Source value. + * @dest_value: Target value. + * + * Tries to cast the contents of @src_value into a type appropriate + * to store in @dest_value, e.g. to transform a %G_TYPE_INT value + * into a %G_TYPE_FLOAT value. Performing transformations between + * value types might incur precision lossage. Especially + * transformations into strings might reveal seemingly arbitrary + * results and shouldn't be relied upon for production code (such + * as rcfile value or object property serialization). + * + * Returns: Whether a transformation rule was found and could be applied. + * Upon failing transformations, @dest_value is left untouched. + */ +gboolean +g_value_transform (const GValue *src_value, + GValue *dest_value) +{ + GType dest_type; + + g_return_val_if_fail (src_value, FALSE); + g_return_val_if_fail (dest_value, FALSE); + + dest_type = G_VALUE_TYPE (dest_value); + if (g_value_type_compatible (G_VALUE_TYPE (src_value), dest_type)) + { + g_value_copy (src_value, dest_value); + + return TRUE; + } + else + { + GValueTransform transform = transform_func_lookup (G_VALUE_TYPE (src_value), dest_type); + + if (transform) + { + g_value_unset (dest_value); + + /* setup and transform */ + value_meminit (dest_value, dest_type); + transform (src_value, dest_value); + + return TRUE; + } + } + return FALSE; +} diff --git a/gobject/gvalue.h b/gobject/gvalue.h new file mode 100644 index 0000000..3630c0b --- /dev/null +++ b/gobject/gvalue.h @@ -0,0 +1,210 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * gvalue.h: generic GValue functions + */ +#ifndef __G_VALUE_H__ +#define __G_VALUE_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* --- type macros --- */ +/** + * G_TYPE_IS_VALUE: + * @type: A #GType value. + * + * Checks whether the passed in type ID can be used for g_value_init(). + * + * That is, this macro checks whether this type provides an implementation + * of the #GTypeValueTable functions required for a type to create a #GValue of. + * + * Returns: Whether @type is suitable as a #GValue type. + */ +#define G_TYPE_IS_VALUE(type) (g_type_check_is_value_type (type)) +/** + * G_IS_VALUE: + * @value: A #GValue structure. + * + * Checks if @value is a valid and initialized #GValue structure. + * + * Returns: %TRUE on success. + */ +#define G_IS_VALUE(value) (G_TYPE_CHECK_VALUE (value)) +/** + * G_VALUE_TYPE: + * @value: A #GValue structure. + * + * Get the type identifier of @value. + * + * Returns: the #GType. + */ +#define G_VALUE_TYPE(value) (((GValue*) (value))->g_type) +/** + * G_VALUE_TYPE_NAME: + * @value: A #GValue structure. + * + * Gets the type name of @value. + * + * Returns: the type name. + */ +#define G_VALUE_TYPE_NAME(value) (g_type_name (G_VALUE_TYPE (value))) +/** + * G_VALUE_HOLDS: + * @value: A #GValue structure. + * @type: A #GType value. + * + * Checks if @value holds (or contains) a value of @type. + * This macro will also check for @value != %NULL and issue a + * warning if the check fails. + * + * Returns: %TRUE if @value holds the @type. + */ +#define G_VALUE_HOLDS(value,type) (G_TYPE_CHECK_VALUE_TYPE ((value), (type))) + + +/* --- typedefs & structures --- */ +/** + * GValueTransform: + * @src_value: Source value. + * @dest_value: Target value. + * + * The type of value transformation functions which can be registered with + * g_value_register_transform_func(). + * + * @dest_value will be initialized to the correct destination type. + */ +typedef void (*GValueTransform) (const GValue *src_value, + GValue *dest_value); +/** + * GValue: + * + * An opaque structure used to hold different types of values. + * + * The data within the structure has protected scope: it is accessible only + * to functions within a #GTypeValueTable structure, or implementations of + * the g_value_*() API. That is, code portions which implement new fundamental + * types. + * + * #GValue users cannot make any assumptions about how data is stored + * within the 2 element @data union, and the @g_type member should + * only be accessed through the G_VALUE_TYPE() macro. + */ +struct _GValue +{ + /*< private >*/ + GType g_type; + + /* public for GTypeValueTable methods */ + union { + gint v_int; + guint v_uint; + glong v_long; + gulong v_ulong; + gint64 v_int64; + guint64 v_uint64; + gfloat v_float; + gdouble v_double; + gpointer v_pointer; + } data[2]; +}; + + +/* --- prototypes --- */ +GLIB_AVAILABLE_IN_ALL +GValue* g_value_init (GValue *value, + GType g_type); +GLIB_AVAILABLE_IN_ALL +void g_value_copy (const GValue *src_value, + GValue *dest_value); +GLIB_AVAILABLE_IN_ALL +GValue* g_value_reset (GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_unset (GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_instance (GValue *value, + gpointer instance); +GLIB_AVAILABLE_IN_2_42 +void g_value_init_from_instance (GValue *value, + gpointer instance); + + +/* --- private --- */ +GLIB_AVAILABLE_IN_ALL +gboolean g_value_fits_pointer (const GValue *value); +GLIB_AVAILABLE_IN_ALL +gpointer g_value_peek_pointer (const GValue *value); + + +/* --- implementation details --- */ +GLIB_AVAILABLE_IN_ALL +gboolean g_value_type_compatible (GType src_type, + GType dest_type); +GLIB_AVAILABLE_IN_ALL +gboolean g_value_type_transformable (GType src_type, + GType dest_type); +GLIB_AVAILABLE_IN_ALL +gboolean g_value_transform (const GValue *src_value, + GValue *dest_value); +GLIB_AVAILABLE_IN_ALL +void g_value_register_transform_func (GType src_type, + GType dest_type, + GValueTransform transform_func); + +/** + * G_VALUE_NOCOPY_CONTENTS: + * + * If passed to G_VALUE_COLLECT(), allocated data won't be copied + * but used verbatim. This does not affect ref-counted types like + * objects. This does not affect usage of g_value_copy(), the data will + * be copied if it is not ref-counted. + */ +#define G_VALUE_NOCOPY_CONTENTS (1 << 27) + +/** + * G_VALUE_INTERNED_STRING: + * + * For string values, indicates that the string contained is canonical and will + * exist for the duration of the process. See g_value_set_interned_string(). + * + * Since: 2.66 + */ +#define G_VALUE_INTERNED_STRING (1 << 28) GLIB_AVAILABLE_MACRO_IN_2_66 + +/** + * G_VALUE_INIT: + * + * A #GValue must be initialized before it can be used. This macro can + * be used as initializer instead of an explicit `{ 0 }` when declaring + * a variable, but it cannot be assigned to a variable. + * + * |[ + * GValue value = G_VALUE_INIT; + * ]| + * + * Since: 2.30 + */ +#define G_VALUE_INIT { 0, { { 0 } } } + + +G_END_DECLS + +#endif /* __G_VALUE_H__ */ diff --git a/gobject/gvaluearray.c b/gobject/gvaluearray.c new file mode 100644 index 0000000..83e03f7 --- /dev/null +++ b/gobject/gvaluearray.c @@ -0,0 +1,370 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include /* qsort() */ + +#include "gvaluearray.h" + + +/** + * SECTION:value_arrays + * @short_description: A container structure to maintain an array of + * generic values + * @see_also: #GValue, #GParamSpecValueArray, g_param_spec_value_array() + * @title: Value arrays + * + * The prime purpose of a #GValueArray is for it to be used as an + * object property that holds an array of values. A #GValueArray wraps + * an array of #GValue elements in order for it to be used as a boxed + * type through %G_TYPE_VALUE_ARRAY. + * + * #GValueArray is deprecated in favour of #GArray since GLib 2.32. It + * is possible to create a #GArray that behaves like a #GValueArray by + * using the size of #GValue as the element size, and by setting + * g_value_unset() as the clear function using g_array_set_clear_func(), + * for instance, the following code: + * + * |[ + * GValueArray *array = g_value_array_new (10); + * ]| + * + * can be replaced by: + * + * |[ + * GArray *array = g_array_sized_new (FALSE, TRUE, sizeof (GValue), 10); + * g_array_set_clear_func (array, (GDestroyNotify) g_value_unset); + * ]| + * + * Deprecated: 2.32: Use #GArray instead, if possible for the given use case, + * as described above. + */ + +#define GROUP_N_VALUES (8) /* power of 2 !! */ + + +/* --- functions --- */ +/** + * g_value_array_get_nth: + * @value_array: #GValueArray to get a value from + * @index_: index of the value of interest + * + * Return a pointer to the value at @index_ containd in @value_array. + * + * Returns: (transfer none): pointer to a value at @index_ in @value_array + * + * Deprecated: 2.32: Use g_array_index() instead. + */ +GValue* +g_value_array_get_nth (GValueArray *value_array, + guint index) +{ + g_return_val_if_fail (value_array != NULL, NULL); + g_return_val_if_fail (index < value_array->n_values, NULL); + + return value_array->values + index; +} + +static inline void +value_array_grow (GValueArray *value_array, + guint n_values, + gboolean zero_init) +{ + g_return_if_fail (n_values >= value_array->n_values); + + value_array->n_values = n_values; + if (value_array->n_values > value_array->n_prealloced) + { + guint i = value_array->n_prealloced; + + value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1); + value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced); + if (!zero_init) + i = value_array->n_values; + memset (value_array->values + i, 0, + (value_array->n_prealloced - i) * sizeof (value_array->values[0])); + } +} + +/** + * g_value_array_new: + * @n_prealloced: number of values to preallocate space for + * + * Allocate and initialize a new #GValueArray, optionally preserve space + * for @n_prealloced elements. New arrays always contain 0 elements, + * regardless of the value of @n_prealloced. + * + * Returns: a newly allocated #GValueArray with 0 values + * + * Deprecated: 2.32: Use #GArray and g_array_sized_new() instead. + */ +GValueArray* +g_value_array_new (guint n_prealloced) +{ + GValueArray *value_array = g_slice_new (GValueArray); + + value_array->n_values = 0; + value_array->n_prealloced = 0; + value_array->values = NULL; + value_array_grow (value_array, n_prealloced, TRUE); + value_array->n_values = 0; + + return value_array; +} + +/** + * g_value_array_free: (skip) + * @value_array: #GValueArray to free + * + * Free a #GValueArray including its contents. + * + * Deprecated: 2.32: Use #GArray and g_array_unref() instead. + */ +void +g_value_array_free (GValueArray *value_array) +{ + guint i; + + g_return_if_fail (value_array != NULL); + + for (i = 0; i < value_array->n_values; i++) + { + GValue *value = value_array->values + i; + + if (G_VALUE_TYPE (value) != 0) /* we allow unset values in the array */ + g_value_unset (value); + } + g_free (value_array->values); + g_slice_free (GValueArray, value_array); +} + +/** + * g_value_array_copy: + * @value_array: #GValueArray to copy + * + * Construct an exact copy of a #GValueArray by duplicating all its + * contents. + * + * Returns: (transfer full): Newly allocated copy of #GValueArray + * + * Deprecated: 2.32: Use #GArray and g_array_ref() instead. + */ +GValueArray* +g_value_array_copy (const GValueArray *value_array) +{ + GValueArray *new_array; + guint i; + + g_return_val_if_fail (value_array != NULL, NULL); + + new_array = g_slice_new (GValueArray); + new_array->n_values = 0; + new_array->values = NULL; + new_array->n_prealloced = 0; + value_array_grow (new_array, value_array->n_values, TRUE); + for (i = 0; i < new_array->n_values; i++) + if (G_VALUE_TYPE (value_array->values + i) != 0) + { + GValue *value = new_array->values + i; + + g_value_init (value, G_VALUE_TYPE (value_array->values + i)); + g_value_copy (value_array->values + i, value); + } + return new_array; +} + +/** + * g_value_array_prepend: + * @value_array: #GValueArray to add an element to + * @value: (nullable): #GValue to copy into #GValueArray, or %NULL + * + * Insert a copy of @value as first element of @value_array. If @value is + * %NULL, an uninitialized value is prepended. + * + * + * Returns: (transfer none): the #GValueArray passed in as @value_array + * + * Deprecated: 2.32: Use #GArray and g_array_prepend_val() instead. + */ +GValueArray* +g_value_array_prepend (GValueArray *value_array, + const GValue *value) +{ + g_return_val_if_fail (value_array != NULL, NULL); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + return g_value_array_insert (value_array, 0, value); + G_GNUC_END_IGNORE_DEPRECATIONS +} + +/** + * g_value_array_append: + * @value_array: #GValueArray to add an element to + * @value: (nullable): #GValue to copy into #GValueArray, or %NULL + * + * Insert a copy of @value as last element of @value_array. If @value is + * %NULL, an uninitialized value is appended. + * + * Returns: (transfer none): the #GValueArray passed in as @value_array + * + * Deprecated: 2.32: Use #GArray and g_array_append_val() instead. + */ +GValueArray* +g_value_array_append (GValueArray *value_array, + const GValue *value) +{ + g_return_val_if_fail (value_array != NULL, NULL); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + return g_value_array_insert (value_array, value_array->n_values, value); + G_GNUC_END_IGNORE_DEPRECATIONS +} + +/** + * g_value_array_insert: + * @value_array: #GValueArray to add an element to + * @index_: insertion position, must be <= value_array->;n_values + * @value: (nullable): #GValue to copy into #GValueArray, or %NULL + * + * Insert a copy of @value at specified position into @value_array. If @value + * is %NULL, an uninitialized value is inserted. + * + * Returns: (transfer none): the #GValueArray passed in as @value_array + * + * Deprecated: 2.32: Use #GArray and g_array_insert_val() instead. + */ +GValueArray* +g_value_array_insert (GValueArray *value_array, + guint index, + const GValue *value) +{ + guint i; + + g_return_val_if_fail (value_array != NULL, NULL); + g_return_val_if_fail (index <= value_array->n_values, value_array); + + i = value_array->n_values; + value_array_grow (value_array, value_array->n_values + 1, FALSE); + if (index + 1 < value_array->n_values) + memmove (value_array->values + index + 1, value_array->values + index, + (i - index) * sizeof (value_array->values[0])); + memset (value_array->values + index, 0, sizeof (value_array->values[0])); + if (value) + { + g_value_init (value_array->values + index, G_VALUE_TYPE (value)); + g_value_copy (value, value_array->values + index); + } + return value_array; +} + +/** + * g_value_array_remove: + * @value_array: #GValueArray to remove an element from + * @index_: position of value to remove, which must be less than + * @value_array->n_values + * + * Remove the value at position @index_ from @value_array. + * + * Returns: (transfer none): the #GValueArray passed in as @value_array + * + * Deprecated: 2.32: Use #GArray and g_array_remove_index() instead. + */ +GValueArray* +g_value_array_remove (GValueArray *value_array, + guint index) +{ + g_return_val_if_fail (value_array != NULL, NULL); + g_return_val_if_fail (index < value_array->n_values, value_array); + + if (G_VALUE_TYPE (value_array->values + index) != 0) + g_value_unset (value_array->values + index); + value_array->n_values--; + if (index < value_array->n_values) + memmove (value_array->values + index, value_array->values + index + 1, + (value_array->n_values - index) * sizeof (value_array->values[0])); + if (value_array->n_prealloced > value_array->n_values) + memset (value_array->values + value_array->n_values, 0, sizeof (value_array->values[0])); + + return value_array; +} + +/** + * g_value_array_sort: + * @value_array: #GValueArray to sort + * @compare_func: (scope call): function to compare elements + * + * Sort @value_array using @compare_func to compare the elements according to + * the semantics of #GCompareFunc. + * + * The current implementation uses the same sorting algorithm as standard + * C qsort() function. + * + * Returns: (transfer none): the #GValueArray passed in as @value_array + * + * Deprecated: 2.32: Use #GArray and g_array_sort(). + */ +GValueArray* +g_value_array_sort (GValueArray *value_array, + GCompareFunc compare_func) +{ + g_return_val_if_fail (compare_func != NULL, NULL); + + if (value_array->n_values) + qsort (value_array->values, + value_array->n_values, + sizeof (value_array->values[0]), + compare_func); + return value_array; +} + +/** + * g_value_array_sort_with_data: (rename-to g_value_array_sort) + * @value_array: #GValueArray to sort + * @compare_func: (scope call): function to compare elements + * @user_data: (closure): extra data argument provided for @compare_func + * + * Sort @value_array using @compare_func to compare the elements according + * to the semantics of #GCompareDataFunc. + * + * The current implementation uses the same sorting algorithm as standard + * C qsort() function. + * + * Returns: (transfer none): the #GValueArray passed in as @value_array + * + * Deprecated: 2.32: Use #GArray and g_array_sort_with_data(). + */ +GValueArray* +g_value_array_sort_with_data (GValueArray *value_array, + GCompareDataFunc compare_func, + gpointer user_data) +{ + g_return_val_if_fail (value_array != NULL, NULL); + g_return_val_if_fail (compare_func != NULL, NULL); + + if (value_array->n_values) + g_qsort_with_data (value_array->values, + value_array->n_values, + sizeof (value_array->values[0]), + compare_func, user_data); + return value_array; +} diff --git a/gobject/gvaluearray.h b/gobject/gvaluearray.h new file mode 100644 index 0000000..dbc6be7 --- /dev/null +++ b/gobject/gvaluearray.h @@ -0,0 +1,104 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * gvaluearray.h: GLib array type holding GValues + */ +#ifndef __G_VALUE_ARRAY_H__ +#define __G_VALUE_ARRAY_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * G_TYPE_VALUE_ARRAY: + * + * The type ID of the "GValueArray" type which is a boxed type, + * used to pass around pointers to GValueArrays. + * + * Deprecated: 2.32: Use #GArray instead of #GValueArray + */ +#define G_TYPE_VALUE_ARRAY (g_value_array_get_type ()) GLIB_DEPRECATED_MACRO_IN_2_32_FOR(G_TYPE_ARRAY) + +/* --- typedefs & structs --- */ +typedef struct _GValueArray GValueArray; +/** + * GValueArray: + * @n_values: number of values contained in the array + * @values: array of values + * + * A #GValueArray contains an array of #GValue elements. + */ +struct _GValueArray +{ + guint n_values; + GValue *values; + + /*< private >*/ + guint n_prealloced; +}; + +/* --- prototypes --- */ +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GType g_value_array_get_type (void) G_GNUC_CONST; + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValue* g_value_array_get_nth (GValueArray *value_array, + guint index_); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValueArray* g_value_array_new (guint n_prealloced); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +void g_value_array_free (GValueArray *value_array); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValueArray* g_value_array_copy (const GValueArray *value_array); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValueArray* g_value_array_prepend (GValueArray *value_array, + const GValue *value); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValueArray* g_value_array_append (GValueArray *value_array, + const GValue *value); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValueArray* g_value_array_insert (GValueArray *value_array, + guint index_, + const GValue *value); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValueArray* g_value_array_remove (GValueArray *value_array, + guint index_); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValueArray* g_value_array_sort (GValueArray *value_array, + GCompareFunc compare_func); + +GLIB_DEPRECATED_IN_2_32_FOR(GArray) +GValueArray* g_value_array_sort_with_data (GValueArray *value_array, + GCompareDataFunc compare_func, + gpointer user_data); + + +G_END_DECLS + +#endif /* __G_VALUE_ARRAY_H__ */ diff --git a/gobject/gvaluecollector.h b/gobject/gvaluecollector.h new file mode 100644 index 0000000..82e675c --- /dev/null +++ b/gobject/gvaluecollector.h @@ -0,0 +1,265 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * gvaluecollector.h: GValue varargs stubs + */ +/** + * SECTION:value_collection + * @Short_description: Converting varargs to generic values + * @Title: Varargs Value Collection + * + * The macros in this section provide the varargs parsing support needed + * in variadic GObject functions such as g_object_new() or g_object_set(). + * + * They currently support the collection of integral types, floating point + * types and pointers. + */ +#ifndef __G_VALUE_COLLECTOR_H__ +#define __G_VALUE_COLLECTOR_H__ + +#include + +G_BEGIN_DECLS + +/* we may want to add aggregate types here some day, if requested + * by users. the basic C types are covered already, everything + * smaller than an int is promoted to an integer and floats are + * always promoted to doubles for varargs call constructions. + */ +enum /*< skip >*/ +{ + G_VALUE_COLLECT_INT = 'i', + G_VALUE_COLLECT_LONG = 'l', + G_VALUE_COLLECT_INT64 = 'q', + G_VALUE_COLLECT_DOUBLE = 'd', + G_VALUE_COLLECT_POINTER = 'p' +}; + + +/* vararg union holding actual values collected + */ +/** + * GTypeCValue: + * @v_int: the field for holding integer values + * @v_long: the field for holding long integer values + * @v_int64: the field for holding 64 bit integer values + * @v_double: the field for holding floating point values + * @v_pointer: the field for holding pointers + * + * A union holding one collected value. + */ +union _GTypeCValue +{ + gint v_int; + glong v_long; + gint64 v_int64; + gdouble v_double; + gpointer v_pointer; +}; + +/** + * G_VALUE_COLLECT_INIT: + * @value: a #GValue return location. @value must contain only 0 bytes. + * @_value_type: the #GType to use for @value. + * @var_args: the va_list variable; it may be evaluated multiple times + * @flags: flags which are passed on to the collect_value() function of + * the #GTypeValueTable of @value. + * @__error: a #gchar** variable that will be modified to hold a g_new() + * allocated error messages if something fails + * + * Collects a variable argument value from a `va_list`. + * + * We have to implement the varargs collection as a macro, because on some + * systems `va_list` variables cannot be passed by reference. + * + * Since: 2.24 + */ +#define G_VALUE_COLLECT_INIT(value, _value_type, var_args, flags, __error) \ +G_STMT_START { \ + GValue *g_vci_val = (value); \ + guint g_vci_flags = (flags); \ + GTypeValueTable *g_vci_vtab = g_type_value_table_peek (_value_type); \ + const gchar *g_vci_collect_format = g_vci_vtab->collect_format; \ + GTypeCValue g_vci_cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, }; \ + guint g_vci_n_values = 0; \ + \ + g_vci_val->g_type = _value_type; /* value_meminit() from gvalue.c */ \ + while (*g_vci_collect_format) \ + { \ + GTypeCValue *g_vci_cvalue = g_vci_cvalues + g_vci_n_values++; \ + \ + switch (*g_vci_collect_format++) \ + { \ + case G_VALUE_COLLECT_INT: \ + g_vci_cvalue->v_int = va_arg ((var_args), gint); \ + break; \ + case G_VALUE_COLLECT_LONG: \ + g_vci_cvalue->v_long = va_arg ((var_args), glong); \ + break; \ + case G_VALUE_COLLECT_INT64: \ + g_vci_cvalue->v_int64 = va_arg ((var_args), gint64); \ + break; \ + case G_VALUE_COLLECT_DOUBLE: \ + g_vci_cvalue->v_double = va_arg ((var_args), gdouble); \ + break; \ + case G_VALUE_COLLECT_POINTER: \ + g_vci_cvalue->v_pointer = va_arg ((var_args), gpointer); \ + break; \ + default: \ + g_assert_not_reached (); \ + } \ + } \ + *(__error) = g_vci_vtab->collect_value (g_vci_val, \ + g_vci_n_values, \ + g_vci_cvalues, \ + g_vci_flags); \ +} G_STMT_END + +/** + * G_VALUE_COLLECT: + * @value: a #GValue return location. @value is supposed to be initialized + * according to the value type to be collected + * @var_args: the va_list variable; it may be evaluated multiple times + * @flags: flags which are passed on to the collect_value() function of + * the #GTypeValueTable of @value. + * @__error: a #gchar** variable that will be modified to hold a g_new() + * allocated error messages if something fails + * + * Collects a variable argument value from a `va_list`. + * + * We have to implement the varargs collection as a macro, because on some systems + * `va_list` variables cannot be passed by reference. + * + * Note: If you are creating the @value argument just before calling this macro, + * you should use the G_VALUE_COLLECT_INIT() variant and pass the uninitialized + * #GValue. That variant is faster than G_VALUE_COLLECT(). + */ +#define G_VALUE_COLLECT(value, var_args, flags, __error) G_STMT_START { \ + GValue *g_vc_value = (value); \ + GType g_vc_value_type = G_VALUE_TYPE (g_vc_value); \ + GTypeValueTable *g_vc_vtable = g_type_value_table_peek (g_vc_value_type); \ + \ + if (g_vc_vtable->value_free) \ + g_vc_vtable->value_free (g_vc_value); \ + memset (g_vc_value->data, 0, sizeof (g_vc_value->data)); \ + \ + G_VALUE_COLLECT_INIT(value, g_vc_value_type, var_args, flags, __error); \ +} G_STMT_END + +/** + * G_VALUE_COLLECT_SKIP: + * @_value_type: the #GType of the value to skip + * @var_args: the va_list variable; it may be evaluated multiple times + * + * Skip an argument of type @_value_type from @var_args. + */ +#define G_VALUE_COLLECT_SKIP(_value_type, var_args) \ +G_STMT_START { \ + GTypeValueTable *g_vcs_vtable = g_type_value_table_peek (_value_type); \ + const gchar *g_vcs_collect_format = g_vcs_vtable->collect_format; \ + \ + while (*g_vcs_collect_format) \ + { \ + switch (*g_vcs_collect_format++) \ + { \ + case G_VALUE_COLLECT_INT: \ + va_arg ((var_args), gint); \ + break; \ + case G_VALUE_COLLECT_LONG: \ + va_arg ((var_args), glong); \ + break; \ + case G_VALUE_COLLECT_INT64: \ + va_arg ((var_args), gint64); \ + break; \ + case G_VALUE_COLLECT_DOUBLE: \ + va_arg ((var_args), gdouble); \ + break; \ + case G_VALUE_COLLECT_POINTER: \ + va_arg ((var_args), gpointer); \ + break; \ + default: \ + g_assert_not_reached (); \ + } \ + } \ +} G_STMT_END + +/** + * G_VALUE_LCOPY: + * @value: a #GValue to store into the @var_args; this must be initialized + * and set + * @var_args: the va_list variable; it may be evaluated multiple times + * @flags: flags which are passed on to the lcopy_value() function of + * the #GTypeValueTable of @value. + * @__error: a #gchar** variable that will be modified to hold a g_new() + * allocated error message if something fails + * + * Stores a value’s value into one or more argument locations from a `va_list`. + * + * This is the inverse of G_VALUE_COLLECT(). + */ +#define G_VALUE_LCOPY(value, var_args, flags, __error) \ +G_STMT_START { \ + const GValue *g_vl_value = (value); \ + guint g_vl_flags = (flags); \ + GType g_vl_value_type = G_VALUE_TYPE (g_vl_value); \ + GTypeValueTable *g_vl_vtable = g_type_value_table_peek (g_vl_value_type); \ + const gchar *g_vl_lcopy_format = g_vl_vtable->lcopy_format; \ + GTypeCValue g_vl_cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, }; \ + guint g_vl_n_values = 0; \ + \ + while (*g_vl_lcopy_format) \ + { \ + GTypeCValue *g_vl_cvalue = g_vl_cvalues + g_vl_n_values++; \ + \ + switch (*g_vl_lcopy_format++) \ + { \ + case G_VALUE_COLLECT_INT: \ + g_vl_cvalue->v_int = va_arg ((var_args), gint); \ + break; \ + case G_VALUE_COLLECT_LONG: \ + g_vl_cvalue->v_long = va_arg ((var_args), glong); \ + break; \ + case G_VALUE_COLLECT_INT64: \ + g_vl_cvalue->v_int64 = va_arg ((var_args), gint64); \ + break; \ + case G_VALUE_COLLECT_DOUBLE: \ + g_vl_cvalue->v_double = va_arg ((var_args), gdouble); \ + break; \ + case G_VALUE_COLLECT_POINTER: \ + g_vl_cvalue->v_pointer = va_arg ((var_args), gpointer); \ + break; \ + default: \ + g_assert_not_reached (); \ + } \ + } \ + *(__error) = g_vl_vtable->lcopy_value (g_vl_value, \ + g_vl_n_values, \ + g_vl_cvalues, \ + g_vl_flags); \ +} G_STMT_END + + +/** + * G_VALUE_COLLECT_FORMAT_MAX_LENGTH: + * + * The maximal number of #GTypeCValues which can be collected for a + * single #GValue. + */ +#define G_VALUE_COLLECT_FORMAT_MAX_LENGTH (8) + +G_END_DECLS + +#endif /* __G_VALUE_COLLECTOR_H__ */ diff --git a/gobject/gvaluetransform.c b/gobject/gvaluetransform.c new file mode 100644 index 0000000..a346a54 --- /dev/null +++ b/gobject/gvaluetransform.c @@ -0,0 +1,428 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include "config.h" + +#include + +#include "gvalue.h" +#include "gtype-private.h" +#include "genums.h" + + +/* same type transforms + */ +static void +value_transform_memcpy_data0 (const GValue *src_value, + GValue *dest_value) +{ + memcpy (&dest_value->data[0], &src_value->data[0], sizeof (src_value->data[0])); +} +#define value_transform_int_int value_transform_memcpy_data0 +#define value_transform_uint_uint value_transform_memcpy_data0 +#define value_transform_long_long value_transform_memcpy_data0 +#define value_transform_ulong_ulong value_transform_memcpy_data0 +#define value_transform_int64_int64 value_transform_memcpy_data0 +#define value_transform_uint64_uint64 value_transform_memcpy_data0 +#define value_transform_float_float value_transform_memcpy_data0 +#define value_transform_double_double value_transform_memcpy_data0 + + +/* numeric casts + */ +#define DEFINE_CAST(func_name, from_member, ctype, to_member) \ +static void \ +value_transform_##func_name (const GValue *src_value, \ + GValue *dest_value) \ +{ \ + ctype c_value = src_value->data[0].from_member; \ + dest_value->data[0].to_member = c_value; \ +} extern void glib_dummy_decl (void) +DEFINE_CAST (int_s8, v_int, gint8, v_int); +DEFINE_CAST (int_u8, v_int, guint8, v_uint); +DEFINE_CAST (int_uint, v_int, guint, v_uint); +DEFINE_CAST (int_long, v_int, glong, v_long); +DEFINE_CAST (int_ulong, v_int, gulong, v_ulong); +DEFINE_CAST (int_int64, v_int, gint64, v_int64); +DEFINE_CAST (int_uint64, v_int, guint64, v_uint64); +DEFINE_CAST (int_float, v_int, gfloat, v_float); +DEFINE_CAST (int_double, v_int, gdouble, v_double); +DEFINE_CAST (uint_s8, v_uint, gint8, v_int); +DEFINE_CAST (uint_u8, v_uint, guint8, v_uint); +DEFINE_CAST (uint_int, v_uint, gint, v_int); +DEFINE_CAST (uint_long, v_uint, glong, v_long); +DEFINE_CAST (uint_ulong, v_uint, gulong, v_ulong); +DEFINE_CAST (uint_int64, v_uint, gint64, v_int64); +DEFINE_CAST (uint_uint64, v_uint, guint64, v_uint64); +DEFINE_CAST (uint_float, v_uint, gfloat, v_float); +DEFINE_CAST (uint_double, v_uint, gdouble, v_double); +DEFINE_CAST (long_s8, v_long, gint8, v_int); +DEFINE_CAST (long_u8, v_long, guint8, v_uint); +DEFINE_CAST (long_int, v_long, gint, v_int); +DEFINE_CAST (long_uint, v_long, guint, v_uint); +DEFINE_CAST (long_ulong, v_long, gulong, v_ulong); +DEFINE_CAST (long_int64, v_long, gint64, v_int64); +DEFINE_CAST (long_uint64, v_long, guint64, v_uint64); +DEFINE_CAST (long_float, v_long, gfloat, v_float); +DEFINE_CAST (long_double, v_long, gdouble, v_double); +DEFINE_CAST (ulong_s8, v_ulong, gint8, v_int); +DEFINE_CAST (ulong_u8, v_ulong, guint8, v_uint); +DEFINE_CAST (ulong_int, v_ulong, gint, v_int); +DEFINE_CAST (ulong_uint, v_ulong, guint, v_uint); +DEFINE_CAST (ulong_int64, v_ulong, gint64, v_int64); +DEFINE_CAST (ulong_uint64, v_ulong, guint64, v_uint64); +DEFINE_CAST (ulong_long, v_ulong, glong, v_long); +DEFINE_CAST (ulong_float, v_ulong, gfloat, v_float); +DEFINE_CAST (ulong_double, v_ulong, gdouble, v_double); +DEFINE_CAST (int64_s8, v_int64, gint8, v_int); +DEFINE_CAST (int64_u8, v_int64, guint8, v_uint); +DEFINE_CAST (int64_int, v_int64, gint, v_int); +DEFINE_CAST (int64_uint, v_int64, guint, v_uint); +DEFINE_CAST (int64_long, v_int64, glong, v_long); +DEFINE_CAST (int64_uint64, v_int64, guint64, v_uint64); +DEFINE_CAST (int64_ulong, v_int64, gulong, v_ulong); +DEFINE_CAST (int64_float, v_int64, gfloat, v_float); +DEFINE_CAST (int64_double, v_int64, gdouble, v_double); +DEFINE_CAST (uint64_s8, v_uint64, gint8, v_int); +DEFINE_CAST (uint64_u8, v_uint64, guint8, v_uint); +DEFINE_CAST (uint64_int, v_uint64, gint, v_int); +DEFINE_CAST (uint64_uint, v_uint64, guint, v_uint); +DEFINE_CAST (uint64_long, v_uint64, glong, v_long); +DEFINE_CAST (uint64_ulong, v_uint64, gulong, v_ulong); +DEFINE_CAST (uint64_int64, v_uint64, gint64, v_int64); +DEFINE_CAST (uint64_float, v_uint64, gfloat, v_float); +DEFINE_CAST (uint64_double, v_uint64, gdouble, v_double); +DEFINE_CAST (float_s8, v_float, gint8, v_int); +DEFINE_CAST (float_u8, v_float, guint8, v_uint); +DEFINE_CAST (float_int, v_float, gint, v_int); +DEFINE_CAST (float_uint, v_float, guint, v_uint); +DEFINE_CAST (float_long, v_float, glong, v_long); +DEFINE_CAST (float_ulong, v_float, gulong, v_ulong); +DEFINE_CAST (float_int64, v_float, gint64, v_int64); +DEFINE_CAST (float_uint64, v_float, guint64, v_uint64); +DEFINE_CAST (float_double, v_float, gdouble, v_double); +DEFINE_CAST (double_s8, v_double, gint8, v_int); +DEFINE_CAST (double_u8, v_double, guint8, v_uint); +DEFINE_CAST (double_int, v_double, gint, v_int); +DEFINE_CAST (double_uint, v_double, guint, v_uint); +DEFINE_CAST (double_long, v_double, glong, v_long); +DEFINE_CAST (double_ulong, v_double, gulong, v_ulong); +DEFINE_CAST (double_int64, v_double, gint64, v_int64); +DEFINE_CAST (double_uint64, v_double, guint64, v_uint64); +DEFINE_CAST (double_float, v_double, gfloat, v_float); + + +/* boolean assignments + */ +#define DEFINE_BOOL_CHECK(func_name, from_member) \ +static void \ +value_transform_##func_name (const GValue *src_value, \ + GValue *dest_value) \ +{ \ + dest_value->data[0].v_int = src_value->data[0].from_member != 0; \ +} extern void glib_dummy_decl (void) +DEFINE_BOOL_CHECK (int_bool, v_int); +DEFINE_BOOL_CHECK (uint_bool, v_uint); +DEFINE_BOOL_CHECK (long_bool, v_long); +DEFINE_BOOL_CHECK (ulong_bool, v_ulong); +DEFINE_BOOL_CHECK (int64_bool, v_int64); +DEFINE_BOOL_CHECK (uint64_bool, v_uint64); + + +/* string printouts + */ +#define DEFINE_SPRINTF(func_name, from_member, format) \ +static void \ +value_transform_##func_name (const GValue *src_value, \ + GValue *dest_value) \ +{ \ + dest_value->data[0].v_pointer = g_strdup_printf ((format), \ + src_value->data[0].from_member); \ +} extern void glib_dummy_decl (void) +DEFINE_SPRINTF (int_string, v_int, "%d"); +DEFINE_SPRINTF (uint_string, v_uint, "%u"); +DEFINE_SPRINTF (long_string, v_long, "%ld"); +DEFINE_SPRINTF (ulong_string, v_ulong, "%lu"); +DEFINE_SPRINTF (int64_string, v_int64, "%" G_GINT64_FORMAT); +DEFINE_SPRINTF (uint64_string, v_uint64, "%" G_GUINT64_FORMAT); +DEFINE_SPRINTF (float_string, v_float, "%f"); +DEFINE_SPRINTF (double_string, v_double, "%f"); + + +/* special cases + */ +static void +value_transform_bool_string (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_pointer = g_strdup_printf ("%s", + src_value->data[0].v_int ? + "TRUE" : "FALSE"); +} +static void +value_transform_string_string (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer); +} +static void +value_transform_enum_string (const GValue *src_value, + GValue *dest_value) +{ + gint v_enum = src_value->data[0].v_long; + gchar *str = g_enum_to_string (G_VALUE_TYPE (src_value), v_enum); + + dest_value->data[0].v_pointer = str; +} +static void +value_transform_flags_string (const GValue *src_value, + GValue *dest_value) +{ + GFlagsClass *class = g_type_class_ref (G_VALUE_TYPE (src_value)); + GFlagsValue *flags_value = g_flags_get_first_value (class, src_value->data[0].v_ulong); + + /* Note: this does not use g_flags_to_string() + * to keep backwards compatibility. + */ + if (flags_value) + { + GString *gstring = g_string_new (NULL); + guint v_flags = src_value->data[0].v_ulong; + + do + { + v_flags &= ~flags_value->value; + + if (gstring->str[0]) + g_string_append (gstring, " | "); + g_string_append (gstring, flags_value->value_name); + flags_value = g_flags_get_first_value (class, v_flags); + } + while (flags_value && v_flags); + + if (v_flags) + dest_value->data[0].v_pointer = g_strdup_printf ("%s | %u", + gstring->str, + v_flags); + else + dest_value->data[0].v_pointer = g_strdup (gstring->str); + g_string_free (gstring, TRUE); + } + else + dest_value->data[0].v_pointer = g_strdup_printf ("%lu", src_value->data[0].v_ulong); + + g_type_class_unref (class); +} + + +/* registration + */ +void +_g_value_transforms_init (void) +{ + /* some transformations are a bit questionable, + * we currently skip those + */ +#define SKIP____register_transform_func(type1,type2,transform_func) /* skip questionable transforms */ \ + (void)0 + + /* numeric types (plus to string) */ + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_CHAR, value_transform_int_int); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_UCHAR, value_transform_int_u8); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_BOOLEAN, value_transform_int_bool); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_INT, value_transform_int_int); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_UINT, value_transform_int_uint); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_LONG, value_transform_int_long); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_ULONG, value_transform_int_ulong); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_INT64, value_transform_int_int64); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_UINT64, value_transform_int_uint64); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_ENUM, value_transform_int_long); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_FLAGS, value_transform_int_ulong); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_FLOAT, value_transform_int_float); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_DOUBLE, value_transform_int_double); + g_value_register_transform_func (G_TYPE_CHAR, G_TYPE_STRING, value_transform_int_string); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_CHAR, value_transform_uint_s8); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_UCHAR, value_transform_uint_uint); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_BOOLEAN, value_transform_uint_bool); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_INT, value_transform_uint_int); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_UINT, value_transform_uint_uint); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_LONG, value_transform_uint_long); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_ULONG, value_transform_uint_ulong); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_INT64, value_transform_uint_int64); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_UINT64, value_transform_uint_uint64); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_ENUM, value_transform_uint_long); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_FLAGS, value_transform_uint_ulong); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_FLOAT, value_transform_uint_float); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_DOUBLE, value_transform_uint_double); + g_value_register_transform_func (G_TYPE_UCHAR, G_TYPE_STRING, value_transform_uint_string); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_CHAR, value_transform_int_s8); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_UCHAR, value_transform_int_u8); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, value_transform_int_int); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_INT, value_transform_int_int); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_UINT, value_transform_int_uint); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_LONG, value_transform_int_long); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_ULONG, value_transform_int_ulong); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_INT64, value_transform_int_int64); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_UINT64, value_transform_int_uint64); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_ENUM, value_transform_int_long); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_FLAGS, value_transform_int_ulong); + SKIP____register_transform_func (G_TYPE_BOOLEAN, G_TYPE_FLOAT, value_transform_int_float); + SKIP____register_transform_func (G_TYPE_BOOLEAN, G_TYPE_DOUBLE, value_transform_int_double); + g_value_register_transform_func (G_TYPE_BOOLEAN, G_TYPE_STRING, value_transform_bool_string); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_CHAR, value_transform_int_s8); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_UCHAR, value_transform_int_u8); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_BOOLEAN, value_transform_int_bool); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_INT, value_transform_int_int); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_UINT, value_transform_int_uint); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_LONG, value_transform_int_long); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_ULONG, value_transform_int_ulong); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_INT64, value_transform_int_int64); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_UINT64, value_transform_int_uint64); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_ENUM, value_transform_int_long); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_FLAGS, value_transform_int_ulong); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_FLOAT, value_transform_int_float); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_DOUBLE, value_transform_int_double); + g_value_register_transform_func (G_TYPE_INT, G_TYPE_STRING, value_transform_int_string); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_CHAR, value_transform_uint_s8); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_UCHAR, value_transform_uint_u8); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_BOOLEAN, value_transform_uint_bool); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_INT, value_transform_uint_int); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_UINT, value_transform_uint_uint); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_LONG, value_transform_uint_long); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_ULONG, value_transform_uint_ulong); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_INT64, value_transform_uint_int64); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_UINT64, value_transform_uint_uint64); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_ENUM, value_transform_uint_long); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_FLAGS, value_transform_uint_ulong); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_FLOAT, value_transform_uint_float); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_DOUBLE, value_transform_uint_double); + g_value_register_transform_func (G_TYPE_UINT, G_TYPE_STRING, value_transform_uint_string); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_CHAR, value_transform_long_s8); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_UCHAR, value_transform_long_u8); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_BOOLEAN, value_transform_long_bool); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_INT, value_transform_long_int); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_UINT, value_transform_long_uint); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_LONG, value_transform_long_long); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_ULONG, value_transform_long_ulong); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_INT64, value_transform_long_int64); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_UINT64, value_transform_long_uint64); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_ENUM, value_transform_long_long); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_FLAGS, value_transform_long_ulong); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_FLOAT, value_transform_long_float); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_DOUBLE, value_transform_long_double); + g_value_register_transform_func (G_TYPE_LONG, G_TYPE_STRING, value_transform_long_string); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_CHAR, value_transform_ulong_s8); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_UCHAR, value_transform_ulong_u8); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_BOOLEAN, value_transform_ulong_bool); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_INT, value_transform_ulong_int); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_UINT, value_transform_ulong_uint); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_LONG, value_transform_ulong_long); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_ULONG, value_transform_ulong_ulong); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_INT64, value_transform_ulong_int64); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_UINT64, value_transform_ulong_uint64); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_ENUM, value_transform_ulong_long); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_FLAGS, value_transform_ulong_ulong); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_FLOAT, value_transform_ulong_float); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_DOUBLE, value_transform_ulong_double); + g_value_register_transform_func (G_TYPE_ULONG, G_TYPE_STRING, value_transform_ulong_string); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_CHAR, value_transform_int64_s8); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_UCHAR, value_transform_int64_u8); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_BOOLEAN, value_transform_int64_bool); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_INT, value_transform_int64_int); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_UINT, value_transform_int64_uint); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_LONG, value_transform_int64_long); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_ULONG, value_transform_int64_ulong); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_INT64, value_transform_int64_int64); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_UINT64, value_transform_int64_uint64); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_ENUM, value_transform_int64_long); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_FLAGS, value_transform_int64_ulong); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_FLOAT, value_transform_int64_float); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_DOUBLE, value_transform_int64_double); + g_value_register_transform_func (G_TYPE_INT64, G_TYPE_STRING, value_transform_int64_string); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_CHAR, value_transform_uint64_s8); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_UCHAR, value_transform_uint64_u8); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_BOOLEAN, value_transform_uint64_bool); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_INT, value_transform_uint64_int); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_UINT, value_transform_uint64_uint); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_LONG, value_transform_uint64_long); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_ULONG, value_transform_uint64_ulong); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_INT64, value_transform_uint64_int64); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_UINT64, value_transform_uint64_uint64); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_ENUM, value_transform_uint64_long); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_FLAGS, value_transform_uint64_ulong); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_FLOAT, value_transform_uint64_float); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_DOUBLE, value_transform_uint64_double); + g_value_register_transform_func (G_TYPE_UINT64, G_TYPE_STRING, value_transform_uint64_string); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_CHAR, value_transform_long_s8); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_UCHAR, value_transform_long_u8); + SKIP____register_transform_func (G_TYPE_ENUM, G_TYPE_BOOLEAN, value_transform_long_bool); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_INT, value_transform_long_int); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_UINT, value_transform_long_uint); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_LONG, value_transform_long_long); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_ULONG, value_transform_long_ulong); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_INT64, value_transform_long_int64); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_UINT64, value_transform_long_uint64); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_ENUM, value_transform_long_long); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_FLAGS, value_transform_long_ulong); + SKIP____register_transform_func (G_TYPE_ENUM, G_TYPE_FLOAT, value_transform_long_float); + SKIP____register_transform_func (G_TYPE_ENUM, G_TYPE_DOUBLE, value_transform_long_double); + g_value_register_transform_func (G_TYPE_ENUM, G_TYPE_STRING, value_transform_enum_string); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_CHAR, value_transform_ulong_s8); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_UCHAR, value_transform_ulong_u8); + SKIP____register_transform_func (G_TYPE_FLAGS, G_TYPE_BOOLEAN, value_transform_ulong_bool); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_INT, value_transform_ulong_int); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_UINT, value_transform_ulong_uint); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_LONG, value_transform_ulong_long); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_ULONG, value_transform_ulong_ulong); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_INT64, value_transform_ulong_int64); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_UINT64, value_transform_ulong_uint64); + SKIP____register_transform_func (G_TYPE_FLAGS, G_TYPE_ENUM, value_transform_ulong_long); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_FLAGS, value_transform_ulong_ulong); + SKIP____register_transform_func (G_TYPE_FLAGS, G_TYPE_FLOAT, value_transform_ulong_float); + SKIP____register_transform_func (G_TYPE_FLAGS, G_TYPE_DOUBLE, value_transform_ulong_double); + g_value_register_transform_func (G_TYPE_FLAGS, G_TYPE_STRING, value_transform_flags_string); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_CHAR, value_transform_float_s8); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_UCHAR, value_transform_float_u8); + SKIP____register_transform_func (G_TYPE_FLOAT, G_TYPE_BOOLEAN, value_transform_float_bool); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_INT, value_transform_float_int); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_UINT, value_transform_float_uint); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_LONG, value_transform_float_long); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_ULONG, value_transform_float_ulong); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_INT64, value_transform_float_int64); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_UINT64, value_transform_float_uint64); + SKIP____register_transform_func (G_TYPE_FLOAT, G_TYPE_ENUM, value_transform_float_long); + SKIP____register_transform_func (G_TYPE_FLOAT, G_TYPE_FLAGS, value_transform_float_ulong); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_FLOAT, value_transform_float_float); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_DOUBLE, value_transform_float_double); + g_value_register_transform_func (G_TYPE_FLOAT, G_TYPE_STRING, value_transform_float_string); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_CHAR, value_transform_double_s8); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_UCHAR, value_transform_double_u8); + SKIP____register_transform_func (G_TYPE_DOUBLE, G_TYPE_BOOLEAN, value_transform_double_bool); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_INT, value_transform_double_int); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_UINT, value_transform_double_uint); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_LONG, value_transform_double_long); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_ULONG, value_transform_double_ulong); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_INT64, value_transform_double_int64); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_UINT64, value_transform_double_uint64); + SKIP____register_transform_func (G_TYPE_DOUBLE, G_TYPE_ENUM, value_transform_double_long); + SKIP____register_transform_func (G_TYPE_DOUBLE, G_TYPE_FLAGS, value_transform_double_ulong); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_FLOAT, value_transform_double_float); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_DOUBLE, value_transform_double_double); + g_value_register_transform_func (G_TYPE_DOUBLE, G_TYPE_STRING, value_transform_double_string); + /* string types */ + g_value_register_transform_func (G_TYPE_STRING, G_TYPE_STRING, value_transform_string_string); +} diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c new file mode 100644 index 0000000..60d7b66 --- /dev/null +++ b/gobject/gvaluetypes.c @@ -0,0 +1,1471 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * Copyright © 2010 Christian Persch + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include /* qsort() */ + +#include "gvaluetypes.h" +#include "gtype-private.h" +#include "gvaluecollector.h" +#include "gobject.h" +#include "gparam.h" +#include "gboxed.h" +#include "genums.h" + + +/* --- value functions --- */ +static void +value_init_long0 (GValue *value) +{ + value->data[0].v_long = 0; +} + +static void +value_copy_long0 (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_long = src_value->data[0].v_long; +} + +static gchar* +value_lcopy_char (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gint8 *int8_p = collect_values[0].v_pointer; + + g_return_val_if_fail (int8_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *int8_p = value->data[0].v_int; + + return NULL; +} + +static gchar* +value_lcopy_boolean (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gboolean *bool_p = collect_values[0].v_pointer; + + g_return_val_if_fail (bool_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *bool_p = value->data[0].v_int; + + return NULL; +} + +static gchar* +value_collect_int (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + value->data[0].v_int = collect_values[0].v_int; + + return NULL; +} + +static gchar* +value_lcopy_int (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gint *int_p = collect_values[0].v_pointer; + + g_return_val_if_fail (int_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *int_p = value->data[0].v_int; + + return NULL; +} + +static gchar* +value_collect_long (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + value->data[0].v_long = collect_values[0].v_long; + + return NULL; +} + +static gchar* +value_lcopy_long (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + glong *long_p = collect_values[0].v_pointer; + + g_return_val_if_fail (long_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *long_p = value->data[0].v_long; + + return NULL; +} + +static void +value_init_int64 (GValue *value) +{ + value->data[0].v_int64 = 0; +} + +static void +value_copy_int64 (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_int64 = src_value->data[0].v_int64; +} + +static gchar* +value_collect_int64 (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + value->data[0].v_int64 = collect_values[0].v_int64; + + return NULL; +} + +static gchar* +value_lcopy_int64 (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gint64 *int64_p = collect_values[0].v_pointer; + + g_return_val_if_fail (int64_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *int64_p = value->data[0].v_int64; + + return NULL; +} + +static void +value_init_float (GValue *value) +{ + value->data[0].v_float = 0.0; +} + +static void +value_copy_float (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_float = src_value->data[0].v_float; +} + +static gchar* +value_collect_float (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + value->data[0].v_float = collect_values[0].v_double; + + return NULL; +} + +static gchar* +value_lcopy_float (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gfloat *float_p = collect_values[0].v_pointer; + + g_return_val_if_fail (float_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *float_p = value->data[0].v_float; + + return NULL; +} + +static void +value_init_double (GValue *value) +{ + value->data[0].v_double = 0.0; +} + +static void +value_copy_double (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_double = src_value->data[0].v_double; +} + +static gchar* +value_collect_double (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + value->data[0].v_double = collect_values[0].v_double; + + return NULL; +} + +static gchar* +value_lcopy_double (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gdouble *double_p = collect_values[0].v_pointer; + + g_return_val_if_fail (double_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *double_p = value->data[0].v_double; + + return NULL; +} + +static void +value_init_string (GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static void +value_free_string (GValue *value) +{ + if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) + g_free (value->data[0].v_pointer); +} + +static void +value_copy_string (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[1].v_uint & G_VALUE_INTERNED_STRING) + { + dest_value->data[0].v_pointer = src_value->data[0].v_pointer; + dest_value->data[1].v_uint = src_value->data[1].v_uint; + } + else + { + dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer); + /* Don't copy over *any* flags, we're restarting from scratch */ + } +} + +static gchar* +value_collect_string (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + if (!collect_values[0].v_pointer) + value->data[0].v_pointer = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + { + value->data[0].v_pointer = collect_values[0].v_pointer; + value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; + } + else + value->data[0].v_pointer = g_strdup (collect_values[0].v_pointer); + + return NULL; +} + +static gchar* +value_lcopy_string (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gchar **string_p = collect_values[0].v_pointer; + + g_return_val_if_fail (string_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + if (!value->data[0].v_pointer) + *string_p = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + *string_p = value->data[0].v_pointer; + else + *string_p = g_strdup (value->data[0].v_pointer); + + return NULL; +} + +static void +value_init_pointer (GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static void +value_copy_pointer (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_pointer = src_value->data[0].v_pointer; +} + +static gpointer +value_peek_pointer0 (const GValue *value) +{ + return value->data[0].v_pointer; +} + +static gchar* +value_collect_pointer (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + value->data[0].v_pointer = collect_values[0].v_pointer; + + return NULL; +} + +static gchar* +value_lcopy_pointer (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + gpointer *pointer_p = collect_values[0].v_pointer; + + g_return_val_if_fail (pointer_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + *pointer_p = value->data[0].v_pointer; + + return NULL; +} + +static void +value_free_variant (GValue *value) +{ + if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) && + value->data[0].v_pointer) + g_variant_unref (value->data[0].v_pointer); +} + +static void +value_copy_variant (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[0].v_pointer) + dest_value->data[0].v_pointer = g_variant_ref_sink (src_value->data[0].v_pointer); + else + dest_value->data[0].v_pointer = NULL; +} + +static gchar* +value_collect_variant (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + if (!collect_values[0].v_pointer) + value->data[0].v_pointer = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + { + value->data[0].v_pointer = collect_values[0].v_pointer; + value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; + } + else + value->data[0].v_pointer = g_variant_ref_sink (collect_values[0].v_pointer); + + return NULL; +} + +static gchar* +value_lcopy_variant (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + GVariant **variant_p = collect_values[0].v_pointer; + + g_return_val_if_fail (variant_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value))); + + if (!value->data[0].v_pointer) + *variant_p = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + *variant_p = value->data[0].v_pointer; + else + *variant_p = g_variant_ref_sink (value->data[0].v_pointer); + + return NULL; +} + +/* --- type initialization --- */ +void +_g_value_types_init (void) +{ + GTypeInfo info = { + 0, /* class_size */ + NULL, /* base_init */ + NULL, /* base_destroy */ + NULL, /* class_init */ + NULL, /* class_destroy */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, }; + GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + /* G_TYPE_CHAR / G_TYPE_UCHAR + */ + { + static const GTypeValueTable value_table = { + value_init_long0, /* value_init */ + NULL, /* value_free */ + value_copy_long0, /* value_copy */ + NULL, /* value_peek_pointer */ + "i", /* collect_format */ + value_collect_int, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_char, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_CHAR, g_intern_static_string ("gchar"), &info, &finfo, 0); + g_assert (type == G_TYPE_CHAR); + type = g_type_register_fundamental (G_TYPE_UCHAR, g_intern_static_string ("guchar"), &info, &finfo, 0); + g_assert (type == G_TYPE_UCHAR); + } + + /* G_TYPE_BOOLEAN + */ + { + static const GTypeValueTable value_table = { + value_init_long0, /* value_init */ + NULL, /* value_free */ + value_copy_long0, /* value_copy */ + NULL, /* value_peek_pointer */ + "i", /* collect_format */ + value_collect_int, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_boolean, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_BOOLEAN, g_intern_static_string ("gboolean"), &info, &finfo, 0); + g_assert (type == G_TYPE_BOOLEAN); + } + + /* G_TYPE_INT / G_TYPE_UINT + */ + { + static const GTypeValueTable value_table = { + value_init_long0, /* value_init */ + NULL, /* value_free */ + value_copy_long0, /* value_copy */ + NULL, /* value_peek_pointer */ + "i", /* collect_format */ + value_collect_int, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_int, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_INT, g_intern_static_string ("gint"), &info, &finfo, 0); + g_assert (type == G_TYPE_INT); + type = g_type_register_fundamental (G_TYPE_UINT, g_intern_static_string ("guint"), &info, &finfo, 0); + g_assert (type == G_TYPE_UINT); + } + + /* G_TYPE_LONG / G_TYPE_ULONG + */ + { + static const GTypeValueTable value_table = { + value_init_long0, /* value_init */ + NULL, /* value_free */ + value_copy_long0, /* value_copy */ + NULL, /* value_peek_pointer */ + "l", /* collect_format */ + value_collect_long, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_long, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_LONG, g_intern_static_string ("glong"), &info, &finfo, 0); + g_assert (type == G_TYPE_LONG); + type = g_type_register_fundamental (G_TYPE_ULONG, g_intern_static_string ("gulong"), &info, &finfo, 0); + g_assert (type == G_TYPE_ULONG); + } + + /* G_TYPE_INT64 / G_TYPE_UINT64 + */ + { + static const GTypeValueTable value_table = { + value_init_int64, /* value_init */ + NULL, /* value_free */ + value_copy_int64, /* value_copy */ + NULL, /* value_peek_pointer */ + "q", /* collect_format */ + value_collect_int64, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_int64, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_INT64, g_intern_static_string ("gint64"), &info, &finfo, 0); + g_assert (type == G_TYPE_INT64); + type = g_type_register_fundamental (G_TYPE_UINT64, g_intern_static_string ("guint64"), &info, &finfo, 0); + g_assert (type == G_TYPE_UINT64); + } + + /* G_TYPE_FLOAT + */ + { + static const GTypeValueTable value_table = { + value_init_float, /* value_init */ + NULL, /* value_free */ + value_copy_float, /* value_copy */ + NULL, /* value_peek_pointer */ + "d", /* collect_format */ + value_collect_float, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_float, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_FLOAT, g_intern_static_string ("gfloat"), &info, &finfo, 0); + g_assert (type == G_TYPE_FLOAT); + } + + /* G_TYPE_DOUBLE + */ + { + static const GTypeValueTable value_table = { + value_init_double, /* value_init */ + NULL, /* value_free */ + value_copy_double, /* value_copy */ + NULL, /* value_peek_pointer */ + "d", /* collect_format */ + value_collect_double, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_double, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_DOUBLE, g_intern_static_string ("gdouble"), &info, &finfo, 0); + g_assert (type == G_TYPE_DOUBLE); + } + + /* G_TYPE_STRING + */ + { + static const GTypeValueTable value_table = { + value_init_string, /* value_init */ + value_free_string, /* value_free */ + value_copy_string, /* value_copy */ + value_peek_pointer0, /* value_peek_pointer */ + "p", /* collect_format */ + value_collect_string, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_string, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_STRING, g_intern_static_string ("gchararray"), &info, &finfo, 0); + g_assert (type == G_TYPE_STRING); + } + + /* G_TYPE_POINTER + */ + { + static const GTypeValueTable value_table = { + value_init_pointer, /* value_init */ + NULL, /* value_free */ + value_copy_pointer, /* value_copy */ + value_peek_pointer0, /* value_peek_pointer */ + "p", /* collect_format */ + value_collect_pointer, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_pointer, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_POINTER, g_intern_static_string ("gpointer"), &info, &finfo, 0); + g_assert (type == G_TYPE_POINTER); + } + + /* G_TYPE_VARIANT + */ + { + static const GTypeValueTable value_table = { + value_init_pointer, /* value_init */ + value_free_variant, /* value_free */ + value_copy_variant, /* value_copy */ + value_peek_pointer0, /* value_peek_pointer */ + "p", /* collect_format */ + value_collect_variant, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_variant, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_VARIANT, g_intern_static_string ("GVariant"), &info, &finfo, 0); + g_assert (type == G_TYPE_VARIANT); + } +} + + +/* --- GValue functions --- */ +/** + * g_value_set_char: + * @value: a valid #GValue of type %G_TYPE_CHAR + * @v_char: character value to be set + * + * Set the contents of a %G_TYPE_CHAR #GValue to @v_char. + * Deprecated: 2.32: This function's input type is broken, see g_value_set_schar() + */ +void +g_value_set_char (GValue *value, + gchar v_char) +{ + g_return_if_fail (G_VALUE_HOLDS_CHAR (value)); + + value->data[0].v_int = v_char; +} + +/** + * g_value_get_char: + * @value: a valid #GValue of type %G_TYPE_CHAR + * + * Do not use this function; it is broken on platforms where the %char + * type is unsigned, such as ARM and PowerPC. See g_value_get_schar(). + * + * Get the contents of a %G_TYPE_CHAR #GValue. + * + * Returns: character contents of @value + * Deprecated: 2.32: This function's return type is broken, see g_value_get_schar() + */ +gchar +g_value_get_char (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0); + + return value->data[0].v_int; +} + +/** + * g_value_set_schar: + * @value: a valid #GValue of type %G_TYPE_CHAR + * @v_char: signed 8 bit integer to be set + * + * Set the contents of a %G_TYPE_CHAR #GValue to @v_char. + * + * Since: 2.32 + */ +void +g_value_set_schar (GValue *value, + gint8 v_char) +{ + g_return_if_fail (G_VALUE_HOLDS_CHAR (value)); + + value->data[0].v_int = v_char; +} + +/** + * g_value_get_schar: + * @value: a valid #GValue of type %G_TYPE_CHAR + * + * Get the contents of a %G_TYPE_CHAR #GValue. + * + * Returns: signed 8 bit integer contents of @value + * Since: 2.32 + */ +gint8 +g_value_get_schar (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0); + + return value->data[0].v_int; +} + +/** + * g_value_set_uchar: + * @value: a valid #GValue of type %G_TYPE_UCHAR + * @v_uchar: unsigned character value to be set + * + * Set the contents of a %G_TYPE_UCHAR #GValue to @v_uchar. + */ +void +g_value_set_uchar (GValue *value, + guchar v_uchar) +{ + g_return_if_fail (G_VALUE_HOLDS_UCHAR (value)); + + value->data[0].v_uint = v_uchar; +} + +/** + * g_value_get_uchar: + * @value: a valid #GValue of type %G_TYPE_UCHAR + * + * Get the contents of a %G_TYPE_UCHAR #GValue. + * + * Returns: unsigned character contents of @value + */ +guchar +g_value_get_uchar (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_UCHAR (value), 0); + + return value->data[0].v_uint; +} + +/** + * g_value_set_boolean: + * @value: a valid #GValue of type %G_TYPE_BOOLEAN + * @v_boolean: boolean value to be set + * + * Set the contents of a %G_TYPE_BOOLEAN #GValue to @v_boolean. + */ +void +g_value_set_boolean (GValue *value, + gboolean v_boolean) +{ + g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (value)); + + value->data[0].v_int = v_boolean != FALSE; +} + +/** + * g_value_get_boolean: + * @value: a valid #GValue of type %G_TYPE_BOOLEAN + * + * Get the contents of a %G_TYPE_BOOLEAN #GValue. + * + * Returns: boolean contents of @value + */ +gboolean +g_value_get_boolean (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (value), 0); + + return value->data[0].v_int; +} + +/** + * g_value_set_int: + * @value: a valid #GValue of type %G_TYPE_INT + * @v_int: integer value to be set + * + * Set the contents of a %G_TYPE_INT #GValue to @v_int. + */ +void +g_value_set_int (GValue *value, + gint v_int) +{ + g_return_if_fail (G_VALUE_HOLDS_INT (value)); + + value->data[0].v_int = v_int; +} + +/** + * g_value_get_int: + * @value: a valid #GValue of type %G_TYPE_INT + * + * Get the contents of a %G_TYPE_INT #GValue. + * + * Returns: integer contents of @value + */ +gint +g_value_get_int (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_INT (value), 0); + + return value->data[0].v_int; +} + +/** + * g_value_set_uint: + * @value: a valid #GValue of type %G_TYPE_UINT + * @v_uint: unsigned integer value to be set + * + * Set the contents of a %G_TYPE_UINT #GValue to @v_uint. + */ +void +g_value_set_uint (GValue *value, + guint v_uint) +{ + g_return_if_fail (G_VALUE_HOLDS_UINT (value)); + + value->data[0].v_uint = v_uint; +} + +/** + * g_value_get_uint: + * @value: a valid #GValue of type %G_TYPE_UINT + * + * Get the contents of a %G_TYPE_UINT #GValue. + * + * Returns: unsigned integer contents of @value + */ +guint +g_value_get_uint (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_UINT (value), 0); + + return value->data[0].v_uint; +} + +/** + * g_value_set_long: + * @value: a valid #GValue of type %G_TYPE_LONG + * @v_long: long integer value to be set + * + * Set the contents of a %G_TYPE_LONG #GValue to @v_long. + */ +void +g_value_set_long (GValue *value, + glong v_long) +{ + g_return_if_fail (G_VALUE_HOLDS_LONG (value)); + + value->data[0].v_long = v_long; +} + +/** + * g_value_get_long: + * @value: a valid #GValue of type %G_TYPE_LONG + * + * Get the contents of a %G_TYPE_LONG #GValue. + * + * Returns: long integer contents of @value + */ +glong +g_value_get_long (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_LONG (value), 0); + + return value->data[0].v_long; +} + +/** + * g_value_set_ulong: + * @value: a valid #GValue of type %G_TYPE_ULONG + * @v_ulong: unsigned long integer value to be set + * + * Set the contents of a %G_TYPE_ULONG #GValue to @v_ulong. + */ +void +g_value_set_ulong (GValue *value, + gulong v_ulong) +{ + g_return_if_fail (G_VALUE_HOLDS_ULONG (value)); + + value->data[0].v_ulong = v_ulong; +} + +/** + * g_value_get_ulong: + * @value: a valid #GValue of type %G_TYPE_ULONG + * + * Get the contents of a %G_TYPE_ULONG #GValue. + * + * Returns: unsigned long integer contents of @value + */ +gulong +g_value_get_ulong (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_ULONG (value), 0); + + return value->data[0].v_ulong; +} + +/** + * g_value_get_int64: + * @value: a valid #GValue of type %G_TYPE_INT64 + * + * Get the contents of a %G_TYPE_INT64 #GValue. + * + * Returns: 64bit integer contents of @value + */ +void +g_value_set_int64 (GValue *value, + gint64 v_int64) +{ + g_return_if_fail (G_VALUE_HOLDS_INT64 (value)); + + value->data[0].v_int64 = v_int64; +} + +/** + * g_value_set_int64: + * @value: a valid #GValue of type %G_TYPE_INT64 + * @v_int64: 64bit integer value to be set + * + * Set the contents of a %G_TYPE_INT64 #GValue to @v_int64. + */ +gint64 +g_value_get_int64 (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_INT64 (value), 0); + + return value->data[0].v_int64; +} + +/** + * g_value_set_uint64: + * @value: a valid #GValue of type %G_TYPE_UINT64 + * @v_uint64: unsigned 64bit integer value to be set + * + * Set the contents of a %G_TYPE_UINT64 #GValue to @v_uint64. + */ +void +g_value_set_uint64 (GValue *value, + guint64 v_uint64) +{ + g_return_if_fail (G_VALUE_HOLDS_UINT64 (value)); + + value->data[0].v_uint64 = v_uint64; +} + +/** + * g_value_get_uint64: + * @value: a valid #GValue of type %G_TYPE_UINT64 + * + * Get the contents of a %G_TYPE_UINT64 #GValue. + * + * Returns: unsigned 64bit integer contents of @value + */ +guint64 +g_value_get_uint64 (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_UINT64 (value), 0); + + return value->data[0].v_uint64; +} + +/** + * g_value_set_float: + * @value: a valid #GValue of type %G_TYPE_FLOAT + * @v_float: float value to be set + * + * Set the contents of a %G_TYPE_FLOAT #GValue to @v_float. + */ +void +g_value_set_float (GValue *value, + gfloat v_float) +{ + g_return_if_fail (G_VALUE_HOLDS_FLOAT (value)); + + value->data[0].v_float = v_float; +} + +/** + * g_value_get_float: + * @value: a valid #GValue of type %G_TYPE_FLOAT + * + * Get the contents of a %G_TYPE_FLOAT #GValue. + * + * Returns: float contents of @value + */ +gfloat +g_value_get_float (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_FLOAT (value), 0); + + return value->data[0].v_float; +} + +/** + * g_value_set_double: + * @value: a valid #GValue of type %G_TYPE_DOUBLE + * @v_double: double value to be set + * + * Set the contents of a %G_TYPE_DOUBLE #GValue to @v_double. + */ +void +g_value_set_double (GValue *value, + gdouble v_double) +{ + g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value)); + + value->data[0].v_double = v_double; +} + +/** + * g_value_get_double: + * @value: a valid #GValue of type %G_TYPE_DOUBLE + * + * Get the contents of a %G_TYPE_DOUBLE #GValue. + * + * Returns: double contents of @value + */ +gdouble +g_value_get_double (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (value), 0); + + return value->data[0].v_double; +} + +/** + * g_value_set_string: + * @value: a valid #GValue of type %G_TYPE_STRING + * @v_string: (nullable): caller-owned string to be duplicated for the #GValue + * + * Set the contents of a %G_TYPE_STRING #GValue to a copy of @v_string. + */ +void +g_value_set_string (GValue *value, + const gchar *v_string) +{ + gchar *new_val; + + g_return_if_fail (G_VALUE_HOLDS_STRING (value)); + + new_val = g_strdup (v_string); + + if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) + value->data[1].v_uint = 0; + else + g_free (value->data[0].v_pointer); + + value->data[0].v_pointer = new_val; +} + +/** + * g_value_set_static_string: + * @value: a valid #GValue of type %G_TYPE_STRING + * @v_string: (nullable): static string to be set + * + * Set the contents of a %G_TYPE_STRING #GValue to @v_string. + * The string is assumed to be static, and is thus not duplicated + * when setting the #GValue. + * + * If the the string is a canonical string, using g_value_set_interned_string() + * is more appropriate. + */ +void +g_value_set_static_string (GValue *value, + const gchar *v_string) +{ + g_return_if_fail (G_VALUE_HOLDS_STRING (value)); + + if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) + g_free (value->data[0].v_pointer); + value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; + value->data[0].v_pointer = (gchar*) v_string; +} + +/** + * g_value_set_interned_string: + * @value: a valid #GValue of type %G_TYPE_STRING + * @v_string: (nullable): static string to be set + * + * Set the contents of a %G_TYPE_STRING #GValue to @v_string. The string is + * assumed to be static and interned (canonical, for example from + * g_intern_string()), and is thus not duplicated when setting the #GValue. + * + * Since: 2.66 + */ +void +g_value_set_interned_string (GValue *value, + const gchar *v_string) +{ + g_return_if_fail (G_VALUE_HOLDS_STRING (value)); + + if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) + g_free (value->data[0].v_pointer); + value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS | G_VALUE_INTERNED_STRING; + value->data[0].v_pointer = (gchar *) v_string; +} + +/** + * g_value_set_string_take_ownership: + * @value: a valid #GValue of type %G_TYPE_STRING + * @v_string: (nullable): duplicated unowned string to be set + * + * This is an internal function introduced mainly for C marshallers. + * + * Deprecated: 2.4: Use g_value_take_string() instead. + */ +void +g_value_set_string_take_ownership (GValue *value, + gchar *v_string) +{ + g_value_take_string (value, v_string); +} + +/** + * g_value_take_string: + * @value: a valid #GValue of type %G_TYPE_STRING + * @v_string: (nullable): string to take ownership of + * + * Sets the contents of a %G_TYPE_STRING #GValue to @v_string. + * + * Since: 2.4 + */ +void +g_value_take_string (GValue *value, + gchar *v_string) +{ + g_return_if_fail (G_VALUE_HOLDS_STRING (value)); + + if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) + value->data[1].v_uint = 0; + else + g_free (value->data[0].v_pointer); + value->data[0].v_pointer = v_string; +} + +/** + * g_value_get_string: + * @value: a valid #GValue of type %G_TYPE_STRING + * + * Get the contents of a %G_TYPE_STRING #GValue. + * + * Returns: string content of @value + */ +const gchar* +g_value_get_string (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL); + + return value->data[0].v_pointer; +} + +/** + * g_value_dup_string: + * @value: a valid #GValue of type %G_TYPE_STRING + * + * Get a copy the contents of a %G_TYPE_STRING #GValue. + * + * Returns: a newly allocated copy of the string content of @value + */ +gchar* +g_value_dup_string (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL); + + return g_strdup (value->data[0].v_pointer); +} + +/** + * g_value_set_pointer: + * @value: a valid #GValue of %G_TYPE_POINTER + * @v_pointer: pointer value to be set + * + * Set the contents of a pointer #GValue to @v_pointer. + */ +void +g_value_set_pointer (GValue *value, + gpointer v_pointer) +{ + g_return_if_fail (G_VALUE_HOLDS_POINTER (value)); + + value->data[0].v_pointer = v_pointer; +} + +/** + * g_value_get_pointer: + * @value: a valid #GValue of %G_TYPE_POINTER + * + * Get the contents of a pointer #GValue. + * + * Returns: (transfer none): pointer contents of @value + */ +gpointer +g_value_get_pointer (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_POINTER (value), NULL); + + return value->data[0].v_pointer; +} + +G_DEFINE_POINTER_TYPE (GType, g_gtype) + +/** + * g_value_set_gtype: + * @value: a valid #GValue of type %G_TYPE_GTYPE + * @v_gtype: #GType to be set + * + * Set the contents of a %G_TYPE_GTYPE #GValue to @v_gtype. + * + * Since: 2.12 + */ +void +g_value_set_gtype (GValue *value, + GType v_gtype) +{ + g_return_if_fail (G_VALUE_HOLDS_GTYPE (value)); + + value->data[0].v_pointer = GSIZE_TO_POINTER (v_gtype); + +} + +/** + * g_value_get_gtype: + * @value: a valid #GValue of type %G_TYPE_GTYPE + * + * Get the contents of a %G_TYPE_GTYPE #GValue. + * + * Since: 2.12 + * + * Returns: the #GType stored in @value + */ +GType +g_value_get_gtype (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_GTYPE (value), 0); + + return GPOINTER_TO_SIZE (value->data[0].v_pointer); +} + +/** + * g_value_set_variant: + * @value: a valid #GValue of type %G_TYPE_VARIANT + * @variant: (nullable): a #GVariant, or %NULL + * + * Set the contents of a variant #GValue to @variant. + * If the variant is floating, it is consumed. + * + * Since: 2.26 + */ +void +g_value_set_variant (GValue *value, + GVariant *variant) +{ + GVariant *old_variant; + + g_return_if_fail (G_VALUE_HOLDS_VARIANT (value)); + + old_variant = value->data[0].v_pointer; + + if (variant) + value->data[0].v_pointer = g_variant_ref_sink (variant); + else + value->data[0].v_pointer = NULL; + + if (old_variant) + g_variant_unref (old_variant); +} + +/** + * g_value_take_variant: + * @value: a valid #GValue of type %G_TYPE_VARIANT + * @variant: (nullable) (transfer full): a #GVariant, or %NULL + * + * Set the contents of a variant #GValue to @variant, and takes over + * the ownership of the caller's reference to @variant; + * the caller doesn't have to unref it any more (i.e. the reference + * count of the variant is not increased). + * + * If @variant was floating then its floating reference is converted to + * a hard reference. + * + * If you want the #GValue to hold its own reference to @variant, use + * g_value_set_variant() instead. + * + * This is an internal function introduced mainly for C marshallers. + * + * Since: 2.26 + */ +void +g_value_take_variant (GValue *value, + GVariant *variant) +{ + GVariant *old_variant; + + g_return_if_fail (G_VALUE_HOLDS_VARIANT (value)); + + old_variant = value->data[0].v_pointer; + + if (variant) + value->data[0].v_pointer = g_variant_take_ref (variant); + else + value->data[0].v_pointer = NULL; + + if (old_variant) + g_variant_unref (old_variant); +} + +/** + * g_value_get_variant: + * @value: a valid #GValue of type %G_TYPE_VARIANT + * + * Get the contents of a variant #GValue. + * + * Returns: (transfer none) (nullable): variant contents of @value (may be %NULL) + * + * Since: 2.26 + */ +GVariant* +g_value_get_variant (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL); + + return value->data[0].v_pointer; +} + +/** + * g_value_dup_variant: + * @value: a valid #GValue of type %G_TYPE_VARIANT + * + * Get the contents of a variant #GValue, increasing its refcount. The returned + * #GVariant is never floating. + * + * Returns: (transfer full) (nullable): variant contents of @value (may be %NULL); + * should be unreffed using g_variant_unref() when no longer needed + * + * Since: 2.26 + */ +GVariant* +g_value_dup_variant (const GValue *value) +{ + GVariant *variant; + + g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL); + + variant = value->data[0].v_pointer; + if (variant) + g_variant_ref_sink (variant); + + return variant; +} + +/** + * g_strdup_value_contents: + * @value: #GValue which contents are to be described. + * + * Return a newly allocated string, which describes the contents of a + * #GValue. The main purpose of this function is to describe #GValue + * contents for debugging output, the way in which the contents are + * described may change between different GLib versions. + * + * Returns: Newly allocated string. + */ +gchar* +g_strdup_value_contents (const GValue *value) +{ + const gchar *src; + gchar *contents; + + g_return_val_if_fail (G_IS_VALUE (value), NULL); + + if (G_VALUE_HOLDS_STRING (value)) + { + src = g_value_get_string (value); + + if (!src) + contents = g_strdup ("NULL"); + else + { + gchar *s = g_strescape (src, NULL); + + contents = g_strdup_printf ("\"%s\"", s); + g_free (s); + } + } + else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) + { + GValue tmp_value = G_VALUE_INIT; + gchar *s; + + g_value_init (&tmp_value, G_TYPE_STRING); + g_value_transform (value, &tmp_value); + s = g_strescape (g_value_get_string (&tmp_value), NULL); + g_value_unset (&tmp_value); + if (G_VALUE_HOLDS_ENUM (value) || G_VALUE_HOLDS_FLAGS (value)) + contents = g_strdup_printf ("((%s) %s)", + g_type_name (G_VALUE_TYPE (value)), + s); + else + contents = g_strdup (s ? s : "NULL"); + g_free (s); + } + else if (g_value_fits_pointer (value)) + { + gpointer p = g_value_peek_pointer (value); + + if (!p) + contents = g_strdup ("NULL"); + else if (G_VALUE_HOLDS_OBJECT (value)) + contents = g_strdup_printf ("((%s*) %p)", G_OBJECT_TYPE_NAME (p), p); + else if (G_VALUE_HOLDS_PARAM (value)) + contents = g_strdup_printf ("((%s*) %p)", G_PARAM_SPEC_TYPE_NAME (p), p); + else if (G_VALUE_HOLDS (value, G_TYPE_STRV)) + { + GStrv strv = g_value_get_boxed (value); + GString *tmp = g_string_new ("["); + + while (*strv != NULL) + { + gchar *escaped = g_strescape (*strv, NULL); + + g_string_append_printf (tmp, "\"%s\"", escaped); + g_free (escaped); + + if (*++strv != NULL) + g_string_append (tmp, ", "); + } + + g_string_append (tmp, "]"); + contents = g_string_free (tmp, FALSE); + } + else if (G_VALUE_HOLDS_BOXED (value)) + contents = g_strdup_printf ("((%s*) %p)", g_type_name (G_VALUE_TYPE (value)), p); + else if (G_VALUE_HOLDS_POINTER (value)) + contents = g_strdup_printf ("((gpointer) %p)", p); + else + contents = g_strdup ("???"); + } + else + contents = g_strdup ("???"); + + return contents; +} + +/** + * g_pointer_type_register_static: + * @name: the name of the new pointer type. + * + * Creates a new %G_TYPE_POINTER derived type id for a new + * pointer type with name @name. + * + * Returns: a new %G_TYPE_POINTER derived type id for @name. + */ +GType +g_pointer_type_register_static (const gchar *name) +{ + const GTypeInfo type_info = { + 0, /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL /* value_table */ + }; + GType type; + + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (g_type_from_name (name) == 0, 0); + + type = g_type_register_static (G_TYPE_POINTER, name, &type_info, 0); + + return type; +} diff --git a/gobject/gvaluetypes.h b/gobject/gvaluetypes.h new file mode 100644 index 0000000..f37504b --- /dev/null +++ b/gobject/gvaluetypes.h @@ -0,0 +1,316 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * gvaluetypes.h: GLib default values + */ +#ifndef __G_VALUETYPES_H__ +#define __G_VALUETYPES_H__ + +#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* --- type macros --- */ +/** + * G_VALUE_HOLDS_CHAR: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_CHAR. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_CHAR(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_CHAR)) +/** + * G_VALUE_HOLDS_UCHAR: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_UCHAR. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_UCHAR(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_UCHAR)) +/** + * G_VALUE_HOLDS_BOOLEAN: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_BOOLEAN. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_BOOLEAN(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_BOOLEAN)) +/** + * G_VALUE_HOLDS_INT: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_INT. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_INT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_INT)) +/** + * G_VALUE_HOLDS_UINT: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_UINT. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_UINT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_UINT)) +/** + * G_VALUE_HOLDS_LONG: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_LONG. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_LONG(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_LONG)) +/** + * G_VALUE_HOLDS_ULONG: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_ULONG. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_ULONG(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_ULONG)) +/** + * G_VALUE_HOLDS_INT64: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_INT64. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_INT64(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_INT64)) +/** + * G_VALUE_HOLDS_UINT64: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_UINT64. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_UINT64(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_UINT64)) +/** + * G_VALUE_HOLDS_FLOAT: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_FLOAT. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_FLOAT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_FLOAT)) +/** + * G_VALUE_HOLDS_DOUBLE: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_DOUBLE. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_DOUBLE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_DOUBLE)) +/** + * G_VALUE_HOLDS_STRING: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_STRING. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_STRING(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_STRING)) +/** + * G_VALUE_IS_INTERNED_STRING: + * @value: a valid #GValue structure + * + * Checks whether @value contains a string which is canonical. + * + * Returns: %TRUE if the value contains a string in its canonical + * representation, as returned by g_intern_string(). See also + * g_value_set_interned_string(). + * + * Since: 2.66 + */ +#define G_VALUE_IS_INTERNED_STRING(value) (G_VALUE_HOLDS_STRING (value) && ((value)->data[1].v_uint & G_VALUE_INTERNED_STRING)) GLIB_AVAILABLE_MACRO_IN_2_66 +/** + * G_VALUE_HOLDS_POINTER: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_POINTER. + * + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_POINTER(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_POINTER)) +/** + * G_TYPE_GTYPE: + * + * The type for #GType. + */ +#define G_TYPE_GTYPE (g_gtype_get_type()) +/** + * G_VALUE_HOLDS_GTYPE: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_GTYPE. + * + * Since: 2.12 + * Returns: %TRUE on success. + */ +#define G_VALUE_HOLDS_GTYPE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_GTYPE)) +/** + * G_VALUE_HOLDS_VARIANT: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_VARIANT. + * + * Returns: %TRUE on success. + * + * Since: 2.26 + */ +#define G_VALUE_HOLDS_VARIANT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_VARIANT)) + + +/* --- prototypes --- */ +GLIB_DEPRECATED_IN_2_32_FOR(g_value_set_schar) +void g_value_set_char (GValue *value, + gchar v_char); +GLIB_DEPRECATED_IN_2_32_FOR(g_value_get_schar) +gchar g_value_get_char (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_schar (GValue *value, + gint8 v_char); +GLIB_AVAILABLE_IN_ALL +gint8 g_value_get_schar (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_uchar (GValue *value, + guchar v_uchar); +GLIB_AVAILABLE_IN_ALL +guchar g_value_get_uchar (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_boolean (GValue *value, + gboolean v_boolean); +GLIB_AVAILABLE_IN_ALL +gboolean g_value_get_boolean (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_int (GValue *value, + gint v_int); +GLIB_AVAILABLE_IN_ALL +gint g_value_get_int (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_uint (GValue *value, + guint v_uint); +GLIB_AVAILABLE_IN_ALL +guint g_value_get_uint (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_long (GValue *value, + glong v_long); +GLIB_AVAILABLE_IN_ALL +glong g_value_get_long (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_ulong (GValue *value, + gulong v_ulong); +GLIB_AVAILABLE_IN_ALL +gulong g_value_get_ulong (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_int64 (GValue *value, + gint64 v_int64); +GLIB_AVAILABLE_IN_ALL +gint64 g_value_get_int64 (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_uint64 (GValue *value, + guint64 v_uint64); +GLIB_AVAILABLE_IN_ALL +guint64 g_value_get_uint64 (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_float (GValue *value, + gfloat v_float); +GLIB_AVAILABLE_IN_ALL +gfloat g_value_get_float (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_double (GValue *value, + gdouble v_double); +GLIB_AVAILABLE_IN_ALL +gdouble g_value_get_double (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_string (GValue *value, + const gchar *v_string); +GLIB_AVAILABLE_IN_ALL +void g_value_set_static_string (GValue *value, + const gchar *v_string); +GLIB_AVAILABLE_IN_2_66 +void g_value_set_interned_string (GValue *value, + const gchar *v_string); +GLIB_AVAILABLE_IN_ALL +const gchar * g_value_get_string (const GValue *value); +GLIB_AVAILABLE_IN_ALL +gchar* g_value_dup_string (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_pointer (GValue *value, + gpointer v_pointer); +GLIB_AVAILABLE_IN_ALL +gpointer g_value_get_pointer (const GValue *value); +GLIB_AVAILABLE_IN_ALL +GType g_gtype_get_type (void); +GLIB_AVAILABLE_IN_ALL +void g_value_set_gtype (GValue *value, + GType v_gtype); +GLIB_AVAILABLE_IN_ALL +GType g_value_get_gtype (const GValue *value); +GLIB_AVAILABLE_IN_ALL +void g_value_set_variant (GValue *value, + GVariant *variant); +GLIB_AVAILABLE_IN_ALL +void g_value_take_variant (GValue *value, + GVariant *variant); +GLIB_AVAILABLE_IN_ALL +GVariant* g_value_get_variant (const GValue *value); +GLIB_AVAILABLE_IN_ALL +GVariant* g_value_dup_variant (const GValue *value); + + +/* Convenience for registering new pointer types */ +GLIB_AVAILABLE_IN_ALL +GType g_pointer_type_register_static (const gchar *name); + +/* debugging aid, describe value contents as string */ +GLIB_AVAILABLE_IN_ALL +gchar* g_strdup_value_contents (const GValue *value); + + +GLIB_AVAILABLE_IN_ALL +void g_value_take_string (GValue *value, + gchar *v_string); +GLIB_DEPRECATED_FOR(g_value_take_string) +void g_value_set_string_take_ownership (GValue *value, + gchar *v_string); + + +/* humpf, need a C representable type name for G_TYPE_STRING */ +/** + * gchararray: + * + * A C representable type name for %G_TYPE_STRING. + */ +typedef gchar* gchararray; + + +G_END_DECLS + +#endif /* __G_VALUETYPES_H__ */ diff --git a/gobject/libgobject-gdb.py.in b/gobject/libgobject-gdb.py.in new file mode 100644 index 0000000..e8b9dee --- /dev/null +++ b/gobject/libgobject-gdb.py.in @@ -0,0 +1,10 @@ +import sys +import gdb + +# Update module path. +dir_ = '@datadir@/glib-2.0/gdb' +if not dir_ in sys.path: + sys.path.insert(0, dir_) + +from gobject_gdb import register +register (gdb.current_objfile ()) diff --git a/gobject/meson.build b/gobject/meson.build new file mode 100644 index 0000000..026a035 --- /dev/null +++ b/gobject/meson.build @@ -0,0 +1,190 @@ +gobject_install_headers = files( + 'gobject-autocleanups.h', + 'glib-types.h', + 'gbinding.h', + 'gbindinggroup.h', + 'gboxed.h', + 'gclosure.h', + 'genums.h', + 'gmarshal.h', + 'gobject.h', + 'gparam.h', + 'gparamspecs.h', + 'gsignal.h', + 'gsignalgroup.h', + 'gsourceclosure.h', + 'gtype.h', + 'gtypemodule.h', + 'gtypeplugin.h', + 'gvalue.h', + 'gvaluearray.h', + 'gvaluecollector.h', + 'gvaluetypes.h', + 'gobjectnotifyqueue.c', # sic +) +install_headers(gobject_install_headers, subdir : 'glib-2.0/gobject') + +gobject_sources = files( + 'gatomicarray.c', + 'gbinding.c', + 'gbindinggroup.c', + 'gboxed.c', + 'gclosure.c', + 'genums.c', + 'gmarshal.c', + 'gobject.c', + 'gparam.c', + 'gparamspecs.c', + 'gsignal.c', + 'gsignalgroup.c', + 'gsourceclosure.c', + 'gtype.c', + 'gtypemodule.c', + 'gtypeplugin.c', + 'gvalue.c', + 'gvaluearray.c', + 'gvaluetransform.c', + 'gvaluetypes.c', +) + +if host_system == 'windows' and get_option('default_library') == 'shared' + gobject_win_rc = configure_file( + input: 'gobject.rc.in', + output: 'gobject.rc', + configuration: glibconfig_conf, + ) + gobject_win_res = windows.compile_resources(gobject_win_rc) + gobject_sources += [gobject_win_res] +endif + +if enable_dtrace + gobject_dtrace_obj = dtrace_obj_gen.process('gobject_probes.d') + gobject_dtrace_hdr = dtrace_hdr_gen.process('gobject_probes.d') +else + gobject_dtrace_obj = [] + gobject_dtrace_hdr = [] +endif + +python_tools = [ + 'glib-genmarshal', + 'glib-mkenums', +] + +python_tools_conf = configuration_data() +python_tools_conf.set('VERSION', glib_version) +python_tools_conf.set('PYTHON', python_name) + +foreach tool: python_tools + tool_bin = configure_file( + input : tool + '.in', + output : tool, + configuration : python_tools_conf, + install_dir : glib_bindir, + ) + + # Set variables for later use + set_variable(tool.underscorify(), tool_bin) + # Provide tools for others when we're a subproject and they use the Meson GNOME module + meson.override_find_program(tool, tool_bin) +endforeach + +# Generate a header file containing the GObject enum types for the enums defined +# in libglib. +# +# For now, we only include gunicode.h here, since GScriptType is needed for +# Pango. More headers can be added as needed in future. +# +# We can't use gnome.mkenums() because the GNOME module looks for glib-mkenums +# in PATH, which means you can't bootstrap glib with its own glib-mkenums. +glib_enumtypes_input_headers = files( + '../glib/gunicode.h', +) + +glib_enumtypes_h = custom_target('glib_enumtypes_h', + output : 'glib-enumtypes.h', + capture : true, + input : glib_enumtypes_input_headers, + install : true, + install_dir : join_paths(get_option('includedir'), 'glib-2.0/gobject'), + command : [python, glib_mkenums, + '--template', files('glib-enumtypes.h.template'), + '@INPUT@']) + +glib_enumtypes_c = custom_target('glib_enumtypes_c', + output : 'glib-enumtypes.c', + capture : true, + input : glib_enumtypes_input_headers, + depends : [glib_enumtypes_h], + command : [python, glib_mkenums, + '--template', files('glib-enumtypes.c.template'), + '@INPUT@']) + +glib_enumtypes_dep = declare_dependency(sources : [glib_enumtypes_h]) + +# Expose as variable to be used by gobject-introspection +# when it includes GLib as a subproject +glib_types_h = files('glib-types.h') + +libgobject = library('gobject-2.0', + gobject_dtrace_obj, gobject_dtrace_hdr, glib_enumtypes_h, glib_enumtypes_c, + sources : gobject_sources, + version : library_version, + soversion : soversion, + darwin_versions : darwin_versions, + install : true, + include_directories : [configinc], + dependencies : [libffi_dep, libglib_dep], + c_args : ['-DG_LOG_DOMAIN="GLib-GObject"', '-DGOBJECT_COMPILATION'] + glib_hidden_visibility_args, + link_args : glib_link_flags, +) + +pkg.generate(libgobject, + requires : ['glib-2.0'], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gobject-2.0', + name : 'GObject', + description : 'GLib Type, Object, Parameter and Signal Library', +) + +libgobject_dep = declare_dependency(link_with : libgobject, + include_directories : [gobjectinc], + dependencies : [libglib_dep, glib_enumtypes_dep]) + +if meson.version().version_compare('>=0.54.0') + meson.override_dependency('gobject-2.0', libgobject_dep) +endif + +executable('gobject-query', 'gobject-query.c', + install : true, + dependencies : [libglib_dep, libgobject_dep]) + +install_data('gobject_gdb.py', install_dir : join_paths(glib_pkgdatadir, 'gdb')) +gdb_conf = configuration_data() +gdb_conf.set('datadir', glib_datadir) +configure_file( + input: 'libgobject-gdb.py.in', + output: 'libgobject-2.0.so.@0@-gdb.py'.format(library_version), + configuration: gdb_conf, + install_dir: gdb_install_dir, + install: gdb_install, +) + +# This is needed to make gdb find gobject_gdb.py +if meson.version().version_compare('>=0.58') + env = environment() + env.prepend('PYTHONPATH', meson.current_source_dir()) + meson.add_devenv(env) +endif + +if enable_systemtap + gobject_stp = configure_file(input : 'gobject.stp.in', + output : '@0@.stp'.format(libgobject.full_path().split('/').get(-1)), + configuration : stp_cdata, + install_dir : tapset_install_dir, + ) +endif + +if build_tests + subdir('tests') +endif diff --git a/gobject/tests/.gitignore b/gobject/tests/.gitignore new file mode 100644 index 0000000..06f3991 --- /dev/null +++ b/gobject/tests/.gitignore @@ -0,0 +1,18 @@ +binding +boxed +closure +dynamictests +enums +ifaceproperties +object +param +properties +qdata +reference +signal-handler +signals +threadtests +type +value +private +marshalers.[ch] diff --git a/gobject/tests/autoptr.c b/gobject/tests/autoptr.c new file mode 100644 index 0000000..ec3c89e --- /dev/null +++ b/gobject/tests/autoptr.c @@ -0,0 +1,237 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2018 Canonical Ltd + * Authors: Marco Trevisan + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include + +G_DECLARE_DERIVABLE_TYPE (TestAutoCleanupBase, test_base_auto_cleanup, TEST, BASE_AUTO_CLEANUP, GObject) + +struct _TestAutoCleanupBaseClass { + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (TestAutoCleanupBase, test_base_auto_cleanup, G_TYPE_OBJECT) + +static void +test_base_auto_cleanup_class_init (TestAutoCleanupBaseClass *class) +{ +} + +static void +test_base_auto_cleanup_init (TestAutoCleanupBase *tac) +{ +} + +G_DECLARE_FINAL_TYPE (TestAutoCleanup, test_auto_cleanup, TEST, AUTO_CLEANUP, TestAutoCleanupBase) + +struct _TestAutoCleanup +{ + TestAutoCleanupBase parent_instance; +}; + +G_DEFINE_TYPE (TestAutoCleanup, test_auto_cleanup, G_TYPE_OBJECT) + +static void +test_auto_cleanup_class_init (TestAutoCleanupClass *class) +{ +} + +static void +test_auto_cleanup_init (TestAutoCleanup *tac) +{ +} + +static TestAutoCleanup * +test_auto_cleanup_new (void) +{ + return g_object_new (test_auto_cleanup_get_type (), NULL); +} + +/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default + * autocleanup functions, defined using the ones of the base type (defined with + * G_DECLARE_DERIVABLE_TYPE) and so that it can be used with g_autoptr */ +static void +test_autoptr (void) +{ + TestAutoCleanup *tac_ptr = test_auto_cleanup_new (); + g_object_add_weak_pointer (G_OBJECT (tac_ptr), (gpointer *) &tac_ptr); + + { + g_autoptr (TestAutoCleanup) tac = tac_ptr; + g_assert_nonnull (tac); + } +#ifdef __GNUC__ + g_assert_null (tac_ptr); +#endif +} + +/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default + * autocleanup functions, defined using the ones of the base type (defined with + * G_DECLARE_DERIVABLE_TYPE) and that stealing an autopointer works properly */ +static void +test_autoptr_steal (void) +{ + g_autoptr (TestAutoCleanup) tac1 = test_auto_cleanup_new (); + TestAutoCleanup *tac_ptr = tac1; + + g_object_add_weak_pointer (G_OBJECT (tac_ptr), (gpointer *) &tac_ptr); + + { + g_autoptr (TestAutoCleanup) tac2 = g_steal_pointer (&tac1); + g_assert_nonnull (tac_ptr); + g_assert_null (tac1); + g_assert_true (tac2 == tac_ptr); + } +#ifdef __GNUC__ + g_assert_null (tac_ptr); +#endif +} + +/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default + * autolist cleanup functions defined using the ones of the parent type + * and so that can be used with g_autolist, and that freeing the list correctly + * unrefs the object too */ +static void +test_autolist (void) +{ + TestAutoCleanup *tac1 = test_auto_cleanup_new (); + TestAutoCleanup *tac2 = test_auto_cleanup_new (); + g_autoptr (TestAutoCleanup) tac3 = test_auto_cleanup_new (); + + g_object_add_weak_pointer (G_OBJECT (tac1), (gpointer *) &tac1); + g_object_add_weak_pointer (G_OBJECT (tac2), (gpointer *) &tac2); + g_object_add_weak_pointer (G_OBJECT (tac3), (gpointer *) &tac3); + + { + g_autolist (TestAutoCleanup) l = NULL; + + l = g_list_prepend (l, tac1); + l = g_list_prepend (l, tac2); + + /* Squash warnings about dead stores */ + (void) l; + } + + /* Only assert if autoptr works */ +#ifdef __GNUC__ + g_assert_null (tac1); + g_assert_null (tac2); +#endif + g_assert_nonnull (tac3); + + g_clear_object (&tac3); + g_assert_null (tac3); +} + +/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default + * autoslist cleanup functions (defined using the ones of the base type declared + * with G_DECLARE_DERIVABLE_TYPE) and so that can be used with g_autoslist, and + * that freeing the slist correctly unrefs the object too */ +static void +test_autoslist (void) +{ + TestAutoCleanup *tac1 = test_auto_cleanup_new (); + TestAutoCleanup *tac2 = test_auto_cleanup_new (); + g_autoptr (TestAutoCleanup) tac3 = test_auto_cleanup_new (); + + g_object_add_weak_pointer (G_OBJECT (tac1), (gpointer *) &tac1); + g_object_add_weak_pointer (G_OBJECT (tac2), (gpointer *) &tac2); + g_object_add_weak_pointer (G_OBJECT (tac3), (gpointer *) &tac3); + + { + g_autoslist (TestAutoCleanup) l = NULL; + + l = g_slist_prepend (l, tac1); + l = g_slist_prepend (l, tac2); + } + + /* Only assert if autoptr works */ +#ifdef __GNUC__ + g_assert_null (tac1); + g_assert_null (tac2); +#endif + g_assert_nonnull (tac3); + + g_clear_object (&tac3); + g_assert_null (tac3); +} + +/* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default + * autoqueue cleanup functions (defined using the ones of the base type declared + * with G_DECLARE_DERIVABLE_TYPE) and so that can be used with g_autoqueue, and + * that freeing the queue correctly unrefs the object too */ +static void +test_autoqueue (void) +{ + TestAutoCleanup *tac1 = test_auto_cleanup_new (); + TestAutoCleanup *tac2 = test_auto_cleanup_new (); + g_autoptr (TestAutoCleanup) tac3 = test_auto_cleanup_new (); + + g_object_add_weak_pointer (G_OBJECT (tac1), (gpointer *) &tac1); + g_object_add_weak_pointer (G_OBJECT (tac2), (gpointer *) &tac2); + g_object_add_weak_pointer (G_OBJECT (tac3), (gpointer *) &tac3); + + { + g_autoqueue (TestAutoCleanup) q = g_queue_new (); + + g_queue_push_head (q, tac1); + g_queue_push_tail (q, tac2); + } + + /* Only assert if autoptr works */ +#ifdef __GNUC__ + g_assert_null (tac1); + g_assert_null (tac2); +#endif + g_assert_nonnull (tac3); + + g_clear_object (&tac3); + g_assert_null (tac3); +} + +static void +test_autoclass (void) +{ + g_autoptr (TestAutoCleanupBaseClass) base_class_ptr = NULL; + g_autoptr (TestAutoCleanupClass) class_ptr = NULL; + + base_class_ptr = g_type_class_ref (test_base_auto_cleanup_get_type ()); + class_ptr = g_type_class_ref (test_auto_cleanup_get_type ()); + + g_assert_nonnull (base_class_ptr); + g_assert_nonnull (class_ptr); +} + +int +main (int argc, gchar *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/autoptr/autoptr", test_autoptr); + g_test_add_func ("/autoptr/autoptr_steal", test_autoptr_steal); + g_test_add_func ("/autoptr/autolist", test_autolist); + g_test_add_func ("/autoptr/autoslist", test_autoslist); + g_test_add_func ("/autoptr/autoqueue", test_autoqueue); + g_test_add_func ("/autoptr/autoclass", test_autoclass); + + return g_test_run (); +} diff --git a/gobject/tests/binding.c b/gobject/tests/binding.c new file mode 100644 index 0000000..e63dd1e --- /dev/null +++ b/gobject/tests/binding.c @@ -0,0 +1,1102 @@ +#include +#include +#include + +typedef struct { + GTypeInterface g_iface; +} FooInterface; + +GType foo_get_type (void); + +G_DEFINE_INTERFACE (Foo, foo, G_TYPE_OBJECT) + +static void +foo_default_init (FooInterface *iface) +{ +} + +typedef struct { + GObject parent; +} Baa; + +typedef struct { + GObjectClass parent_class; +} BaaClass; + +static void +baa_init_foo (FooInterface *iface) +{ +} + +GType baa_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (Baa, baa, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (foo_get_type (), baa_init_foo)) + +static void +baa_init (Baa *baa) +{ +} + +static void +baa_class_init (BaaClass *class) +{ +} + +typedef struct _BindingSource +{ + GObject parent_instance; + + gint foo; + gint bar; + gdouble double_value; + gboolean toggle; + gpointer item; +} BindingSource; + +typedef struct _BindingSourceClass +{ + GObjectClass parent_class; +} BindingSourceClass; + +enum +{ + PROP_SOURCE_0, + + PROP_SOURCE_FOO, + PROP_SOURCE_BAR, + PROP_SOURCE_DOUBLE_VALUE, + PROP_SOURCE_TOGGLE, + PROP_SOURCE_OBJECT +}; + +static GType binding_source_get_type (void); +G_DEFINE_TYPE (BindingSource, binding_source, G_TYPE_OBJECT) + +static void +binding_source_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BindingSource *source = (BindingSource *) gobject; + + switch (prop_id) + { + case PROP_SOURCE_FOO: + source->foo = g_value_get_int (value); + break; + + case PROP_SOURCE_BAR: + source->bar = g_value_get_int (value); + break; + + case PROP_SOURCE_DOUBLE_VALUE: + source->double_value = g_value_get_double (value); + break; + + case PROP_SOURCE_TOGGLE: + source->toggle = g_value_get_boolean (value); + break; + + case PROP_SOURCE_OBJECT: + source->item = g_value_get_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_source_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BindingSource *source = (BindingSource *) gobject; + + switch (prop_id) + { + case PROP_SOURCE_FOO: + g_value_set_int (value, source->foo); + break; + + case PROP_SOURCE_BAR: + g_value_set_int (value, source->bar); + break; + + case PROP_SOURCE_DOUBLE_VALUE: + g_value_set_double (value, source->double_value); + break; + + case PROP_SOURCE_TOGGLE: + g_value_set_boolean (value, source->toggle); + break; + + case PROP_SOURCE_OBJECT: + g_value_set_object (value, source->item); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_source_class_init (BindingSourceClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = binding_source_set_property; + gobject_class->get_property = binding_source_get_property; + + g_object_class_install_property (gobject_class, PROP_SOURCE_FOO, + g_param_spec_int ("foo", "Foo", "Foo", + -1, 100, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_BAR, + g_param_spec_int ("bar", "Bar", "Bar", + -1, 100, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_DOUBLE_VALUE, + g_param_spec_double ("double-value", "Value", "Value", + -100.0, 200.0, + 0.0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_TOGGLE, + g_param_spec_boolean ("toggle", "Toggle", "Toggle", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_OBJECT, + g_param_spec_object ("object", "Object", "Object", + G_TYPE_OBJECT, + G_PARAM_READWRITE)); +} + +static void +binding_source_init (BindingSource *self) +{ +} + +typedef struct _BindingTarget +{ + GObject parent_instance; + + gint bar; + gdouble double_value; + gboolean toggle; + gpointer foo; +} BindingTarget; + +typedef struct _BindingTargetClass +{ + GObjectClass parent_class; +} BindingTargetClass; + +enum +{ + PROP_TARGET_0, + + PROP_TARGET_BAR, + PROP_TARGET_DOUBLE_VALUE, + PROP_TARGET_TOGGLE, + PROP_TARGET_FOO +}; + +static GType binding_target_get_type (void); +G_DEFINE_TYPE (BindingTarget, binding_target, G_TYPE_OBJECT) + +static void +binding_target_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BindingTarget *target = (BindingTarget *) gobject; + + switch (prop_id) + { + case PROP_TARGET_BAR: + target->bar = g_value_get_int (value); + break; + + case PROP_TARGET_DOUBLE_VALUE: + target->double_value = g_value_get_double (value); + break; + + case PROP_TARGET_TOGGLE: + target->toggle = g_value_get_boolean (value); + break; + + case PROP_TARGET_FOO: + target->foo = g_value_get_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_target_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BindingTarget *target = (BindingTarget *) gobject; + + switch (prop_id) + { + case PROP_TARGET_BAR: + g_value_set_int (value, target->bar); + break; + + case PROP_TARGET_DOUBLE_VALUE: + g_value_set_double (value, target->double_value); + break; + + case PROP_TARGET_TOGGLE: + g_value_set_boolean (value, target->toggle); + break; + + case PROP_TARGET_FOO: + g_value_set_object (value, target->foo); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_target_class_init (BindingTargetClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = binding_target_set_property; + gobject_class->get_property = binding_target_get_property; + + g_object_class_install_property (gobject_class, PROP_TARGET_BAR, + g_param_spec_int ("bar", "Bar", "Bar", + -1, 100, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_TARGET_DOUBLE_VALUE, + g_param_spec_double ("double-value", "Value", "Value", + -100.0, 200.0, + 0.0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_TARGET_TOGGLE, + g_param_spec_boolean ("toggle", "Toggle", "Toggle", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_TARGET_FOO, + g_param_spec_object ("foo", "Foo", "Foo", + foo_get_type (), + G_PARAM_READWRITE)); +} + +static void +binding_target_init (BindingTarget *self) +{ +} + +static gboolean +celsius_to_fahrenheit (GBinding *binding, + const GValue *from_value, + GValue *to_value, + gpointer user_data G_GNUC_UNUSED) +{ + gdouble celsius, fahrenheit; + + g_assert_true (G_VALUE_HOLDS (from_value, G_TYPE_DOUBLE)); + g_assert_true (G_VALUE_HOLDS (to_value, G_TYPE_DOUBLE)); + + celsius = g_value_get_double (from_value); + fahrenheit = (9 * celsius / 5) + 32.0; + + if (g_test_verbose ()) + g_printerr ("Converting %.2fC to %.2fF\n", celsius, fahrenheit); + + g_value_set_double (to_value, fahrenheit); + + return TRUE; +} + +static gboolean +fahrenheit_to_celsius (GBinding *binding, + const GValue *from_value, + GValue *to_value, + gpointer user_data G_GNUC_UNUSED) +{ + gdouble celsius, fahrenheit; + + g_assert_true (G_VALUE_HOLDS (from_value, G_TYPE_DOUBLE)); + g_assert_true (G_VALUE_HOLDS (to_value, G_TYPE_DOUBLE)); + + fahrenheit = g_value_get_double (from_value); + celsius = 5 * (fahrenheit - 32.0) / 9; + + if (g_test_verbose ()) + g_printerr ("Converting %.2fF to %.2fC\n", fahrenheit, celsius); + + g_value_set_double (to_value, celsius); + + return TRUE; +} + +static void +binding_default (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GObject *tmp; + GBinding *binding; + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_DEFAULT); + + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + tmp = g_binding_dup_source (binding); + g_assert_nonnull (tmp); + g_assert_true ((BindingSource *) tmp == source); + g_object_unref (tmp); + tmp = g_binding_dup_target (binding); + g_assert_nonnull (tmp); + g_assert_true ((BindingTarget *) tmp == target); + g_object_unref (tmp); + g_assert_cmpstr (g_binding_get_source_property (binding), ==, "foo"); + g_assert_cmpstr (g_binding_get_target_property (binding), ==, "bar"); + g_assert_cmpint (g_binding_get_flags (binding), ==, G_BINDING_DEFAULT); + + g_object_set (source, "foo", 42, NULL); + g_assert_cmpint (source->foo, ==, target->bar); + + g_object_set (target, "bar", 47, NULL); + g_assert_cmpint (source->foo, !=, target->bar); + + g_object_unref (binding); + + g_object_set (source, "foo", 0, NULL); + g_assert_cmpint (source->foo, !=, target->bar); + + g_object_unref (source); + g_object_unref (target); + g_assert_null (binding); +} + +static void +binding_canonicalisation (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + GObject *tmp; + + g_test_summary ("Test that bindings set up with non-canonical property names work"); + + binding = g_object_bind_property (source, "double_value", + target, "double_value", + G_BINDING_DEFAULT); + + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + tmp = g_binding_dup_source (binding); + g_assert_nonnull (tmp); + g_assert_true ((BindingSource *) tmp == source); + g_object_unref (tmp); + tmp = g_binding_dup_target (binding); + g_assert_nonnull (tmp); + g_assert_true ((BindingTarget *) tmp == target); + g_object_unref (tmp); + g_assert_cmpstr (g_binding_get_source_property (binding), ==, "double-value"); + g_assert_cmpstr (g_binding_get_target_property (binding), ==, "double-value"); + g_assert_cmpint (g_binding_get_flags (binding), ==, G_BINDING_DEFAULT); + + g_object_set (source, "double-value", 24.0, NULL); + g_assert_cmpfloat (target->double_value, ==, source->double_value); + + g_object_set (target, "double-value", 69.0, NULL); + g_assert_cmpfloat (source->double_value, !=, target->double_value); + + g_object_unref (target); + g_object_unref (source); + g_assert_null (binding); +} + +static void +binding_bidirectional (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_BIDIRECTIONAL); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + + g_object_set (source, "foo", 42, NULL); + g_assert_cmpint (source->foo, ==, target->bar); + + g_object_set (target, "bar", 47, NULL); + g_assert_cmpint (source->foo, ==, target->bar); + + g_object_unref (binding); + + g_object_set (source, "foo", 0, NULL); + g_assert_cmpint (source->foo, !=, target->bar); + + g_object_unref (source); + g_object_unref (target); + g_assert_null (binding); +} + +static void +data_free (gpointer data) +{ + gboolean *b = data; + + *b = TRUE; +} + +static void +binding_transform_default (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + gpointer src, trg; + gchar *src_prop, *trg_prop; + GBindingFlags flags; + + binding = g_object_bind_property (source, "foo", + target, "double-value", + G_BINDING_BIDIRECTIONAL); + + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + + g_object_get (binding, + "source", &src, + "source-property", &src_prop, + "target", &trg, + "target-property", &trg_prop, + "flags", &flags, + NULL); + g_assert_true (src == source); + g_assert_true (trg == target); + g_assert_cmpstr (src_prop, ==, "foo"); + g_assert_cmpstr (trg_prop, ==, "double-value"); + g_assert_cmpint (flags, ==, G_BINDING_BIDIRECTIONAL); + g_object_unref (src); + g_object_unref (trg); + g_free (src_prop); + g_free (trg_prop); + + g_object_set (source, "foo", 24, NULL); + g_assert_cmpfloat (target->double_value, ==, 24.0); + + g_object_set (target, "double-value", 69.0, NULL); + g_assert_cmpint (source->foo, ==, 69); + + g_object_unref (target); + g_object_unref (source); + g_assert_null (binding); +} + +static void +binding_transform (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding G_GNUC_UNUSED; + gboolean unused_data = FALSE; + + binding = g_object_bind_property_full (source, "double-value", + target, "double-value", + G_BINDING_BIDIRECTIONAL, + celsius_to_fahrenheit, + fahrenheit_to_celsius, + &unused_data, data_free); + + g_object_set (source, "double-value", 24.0, NULL); + g_assert_cmpfloat (target->double_value, ==, ((9 * 24.0 / 5) + 32.0)); + + g_object_set (target, "double-value", 69.0, NULL); + g_assert_cmpfloat (source->double_value, ==, (5 * (69.0 - 32.0) / 9)); + + g_object_unref (source); + g_object_unref (target); + + g_assert_true (unused_data); +} + +static void +binding_transform_closure (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding G_GNUC_UNUSED; + gboolean unused_data_1 = FALSE, unused_data_2 = FALSE; + GClosure *c2f_clos, *f2c_clos; + + c2f_clos = g_cclosure_new (G_CALLBACK (celsius_to_fahrenheit), &unused_data_1, (GClosureNotify) data_free); + + f2c_clos = g_cclosure_new (G_CALLBACK (fahrenheit_to_celsius), &unused_data_2, (GClosureNotify) data_free); + + binding = g_object_bind_property_with_closures (source, "double-value", + target, "double-value", + G_BINDING_BIDIRECTIONAL, + c2f_clos, + f2c_clos); + + g_object_set (source, "double-value", 24.0, NULL); + g_assert_cmpfloat (target->double_value, ==, ((9 * 24.0 / 5) + 32.0)); + + g_object_set (target, "double-value", 69.0, NULL); + g_assert_cmpfloat (source->double_value, ==, (5 * (69.0 - 32.0) / 9)); + + g_object_unref (source); + g_object_unref (target); + + g_assert_true (unused_data_1); + g_assert_true (unused_data_2); +} + +static void +binding_chain (void) +{ + BindingSource *a = g_object_new (binding_source_get_type (), NULL); + BindingSource *b = g_object_new (binding_source_get_type (), NULL); + BindingSource *c = g_object_new (binding_source_get_type (), NULL); + GBinding *binding_1, *binding_2; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=621782"); + + /* A -> B, B -> C */ + binding_1 = g_object_bind_property (a, "foo", b, "foo", G_BINDING_BIDIRECTIONAL); + g_object_add_weak_pointer (G_OBJECT (binding_1), (gpointer *) &binding_1); + + binding_2 = g_object_bind_property (b, "foo", c, "foo", G_BINDING_BIDIRECTIONAL); + g_object_add_weak_pointer (G_OBJECT (binding_2), (gpointer *) &binding_2); + + /* verify the chain */ + g_object_set (a, "foo", 42, NULL); + g_assert_cmpint (a->foo, ==, b->foo); + g_assert_cmpint (b->foo, ==, c->foo); + + /* unbind A -> B and B -> C */ + g_object_unref (binding_1); + g_assert_null (binding_1); + g_object_unref (binding_2); + g_assert_null (binding_2); + + /* bind A -> C directly */ + binding_2 = g_object_bind_property (a, "foo", c, "foo", G_BINDING_BIDIRECTIONAL); + + /* verify the chain is broken */ + g_object_set (a, "foo", 47, NULL); + g_assert_cmpint (a->foo, !=, b->foo); + g_assert_cmpint (a->foo, ==, c->foo); + + g_object_unref (a); + g_object_unref (b); + g_object_unref (c); +} + +static void +binding_sync_create (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), + "foo", 42, + NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), + "bar", 47, + NULL); + GBinding *binding; + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); + + g_assert_cmpint (source->foo, ==, 42); + g_assert_cmpint (target->bar, ==, 42); + + g_object_set (source, "foo", 47, NULL); + g_assert_cmpint (source->foo, ==, target->bar); + + g_object_unref (binding); + + g_object_set (target, "bar", 49, NULL); + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + g_assert_cmpint (source->foo, ==, 47); + g_assert_cmpint (target->bar, ==, 47); + + g_object_unref (source); + g_object_unref (target); +} + +static void +binding_invert_boolean (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), + "toggle", TRUE, + NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), + "toggle", FALSE, + NULL); + GBinding *binding; + + binding = g_object_bind_property (source, "toggle", + target, "toggle", + G_BINDING_BIDIRECTIONAL | G_BINDING_INVERT_BOOLEAN); + + g_assert_true (source->toggle); + g_assert_false (target->toggle); + + g_object_set (source, "toggle", FALSE, NULL); + g_assert_false (source->toggle); + g_assert_true (target->toggle); + + g_object_set (target, "toggle", FALSE, NULL); + g_assert_true (source->toggle); + g_assert_false (target->toggle); + + g_object_unref (binding); + g_object_unref (source); + g_object_unref (target); +} + +static void +binding_same_object (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), + "foo", 100, + "bar", 50, + NULL); + GBinding *binding; + + binding = g_object_bind_property (source, "foo", + source, "bar", + G_BINDING_BIDIRECTIONAL); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + + g_object_set (source, "foo", 10, NULL); + g_assert_cmpint (source->foo, ==, 10); + g_assert_cmpint (source->bar, ==, 10); + g_object_set (source, "bar", 30, NULL); + g_assert_cmpint (source->foo, ==, 30); + g_assert_cmpint (source->bar, ==, 30); + + g_object_unref (source); + g_assert_null (binding); +} + +static void +binding_unbind (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_DEFAULT); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + + g_object_set (source, "foo", 42, NULL); + g_assert_cmpint (source->foo, ==, target->bar); + + g_object_set (target, "bar", 47, NULL); + g_assert_cmpint (source->foo, !=, target->bar); + + g_binding_unbind (binding); + g_assert_null (binding); + + g_object_set (source, "foo", 0, NULL); + g_assert_cmpint (source->foo, !=, target->bar); + + g_object_unref (source); + g_object_unref (target); + + + /* g_binding_unbind() has a special case for this */ + source = g_object_new (binding_source_get_type (), NULL); + binding = g_object_bind_property (source, "foo", + source, "bar", + G_BINDING_DEFAULT); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + + g_binding_unbind (binding); + g_assert_null (binding); + + g_object_unref (source); +} + +/* When source or target die, so does the binding if there is no other ref */ +static void +binding_unbind_weak (void) +{ + GBinding *binding; + BindingSource *source; + BindingTarget *target; + + /* first source, then target */ + source = g_object_new (binding_source_get_type (), NULL); + target = g_object_new (binding_target_get_type (), NULL); + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_DEFAULT); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + g_assert_nonnull (binding); + g_object_unref (source); + g_assert_null (binding); + g_object_unref (target); + g_assert_null (binding); + + /* first target, then source */ + source = g_object_new (binding_source_get_type (), NULL); + target = g_object_new (binding_target_get_type (), NULL); + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_DEFAULT); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + g_assert_nonnull (binding); + g_object_unref (target); + g_assert_null (binding); + g_object_unref (source); + g_assert_null (binding); + + /* target and source are the same */ + source = g_object_new (binding_source_get_type (), NULL); + binding = g_object_bind_property (source, "foo", + source, "bar", + G_BINDING_DEFAULT); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + g_assert_nonnull (binding); + g_object_unref (source); + g_assert_null (binding); +} + +/* Test that every call to unbind() after the first is a noop */ +static void +binding_unbind_multiple (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + guint i; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1373"); + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_DEFAULT); + g_object_ref (binding); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + g_assert_nonnull (binding); + + /* this shouldn't crash */ + for (i = 0; i < 50; i++) + { + g_binding_unbind (binding); + g_assert_nonnull (binding); + } + + g_object_unref (binding); + g_assert_null (binding); + + g_object_unref (source); + g_object_unref (target); +} + +static void +binding_fail (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + + /* double -> boolean is not supported */ + binding = g_object_bind_property (source, "double-value", + target, "toggle", + G_BINDING_DEFAULT); + g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, + "*Unable to convert*double*boolean*"); + g_object_set (source, "double-value", 1.0, NULL); + g_test_assert_expected_messages (); + + g_object_unref (source); + g_object_unref (target); + g_assert_null (binding); +} + +static gboolean +transform_to_func (GBinding *binding, + const GValue *value_a, + GValue *value_b, + gpointer user_data) +{ + if (g_value_type_compatible (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b))) + { + g_value_copy (value_a, value_b); + return TRUE; + } + + if (g_value_type_transformable (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b))) + { + if (g_value_transform (value_a, value_b)) + return TRUE; + } + + return FALSE; +} + +static void +binding_interface (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GObject *baa; + GBinding *binding; + GClosure *transform_to; + + /* binding a generic object property to an interface-valued one */ + binding = g_object_bind_property (source, "object", + target, "foo", + G_BINDING_DEFAULT); + + baa = g_object_new (baa_get_type (), NULL); + g_object_set (source, "object", baa, NULL); + g_object_unref (baa); + + g_binding_unbind (binding); + + /* the same, with a generic marshaller */ + transform_to = g_cclosure_new (G_CALLBACK (transform_to_func), NULL, NULL); + g_closure_set_marshal (transform_to, g_cclosure_marshal_generic); + binding = g_object_bind_property_with_closures (source, "object", + target, "foo", + G_BINDING_DEFAULT, + transform_to, + NULL); + + baa = g_object_new (baa_get_type (), NULL); + g_object_set (source, "object", baa, NULL); + g_object_unref (baa); + + g_binding_unbind (binding); + + g_object_unref (source); + g_object_unref (target); +} + +typedef struct { + GThread *thread; + GBinding *binding; + GMutex *lock; + GCond *cond; + gboolean *wait; + gint *count; /* (atomic) */ +} ConcurrentUnbindData; + +static gpointer +concurrent_unbind_func (gpointer data) +{ + ConcurrentUnbindData *unbind_data = data; + + g_mutex_lock (unbind_data->lock); + g_atomic_int_inc (unbind_data->count); + while (*unbind_data->wait) + g_cond_wait (unbind_data->cond, unbind_data->lock); + g_mutex_unlock (unbind_data->lock); + g_binding_unbind (unbind_data->binding); + g_object_unref (unbind_data->binding); + + return NULL; +} + +static void +binding_concurrent_unbind (void) +{ + guint i, j; + + g_test_summary ("Test that unbinding from multiple threads concurrently works correctly"); + + for (i = 0; i < 50; i++) + { + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + GQueue threads = G_QUEUE_INIT; + GMutex lock; + GCond cond; + gboolean wait = TRUE; + gint count = 0; /* (atomic) */ + ConcurrentUnbindData *data; + + g_mutex_init (&lock); + g_cond_init (&cond); + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_BIDIRECTIONAL); + g_object_ref (binding); + + for (j = 0; j < 10; j++) + { + data = g_new0 (ConcurrentUnbindData, 1); + + data->binding = g_object_ref (binding); + data->lock = &lock; + data->cond = &cond; + data->wait = &wait; + data->count = &count; + + data->thread = g_thread_new ("binding-concurrent", concurrent_unbind_func, data); + g_queue_push_tail (&threads, data); + } + + /* wait until all threads are started */ + while (g_atomic_int_get (&count) < 10) + g_thread_yield (); + + g_mutex_lock (&lock); + wait = FALSE; + g_cond_broadcast (&cond); + g_mutex_unlock (&lock); + + while ((data = g_queue_pop_head (&threads))) + { + g_thread_join (data->thread); + g_free (data); + } + + g_mutex_clear (&lock); + g_cond_clear (&cond); + + g_object_unref (binding); + g_object_unref (source); + g_object_unref (target); + } +} + +typedef struct { + GObject *object; + GMutex *lock; + GCond *cond; + gint *count; /* (atomic) */ + gboolean *wait; +} ConcurrentFinalizeData; + +static gpointer +concurrent_finalize_func (gpointer data) +{ + ConcurrentFinalizeData *finalize_data = data; + + g_mutex_lock (finalize_data->lock); + g_atomic_int_inc (finalize_data->count); + while (*finalize_data->wait) + g_cond_wait (finalize_data->cond, finalize_data->lock); + g_mutex_unlock (finalize_data->lock); + g_object_unref (finalize_data->object); + g_free (finalize_data); + + return NULL; +} + +static void +binding_concurrent_finalizing (void) +{ + guint i; + + g_test_summary ("Test that finalizing source/target from multiple threads concurrently works correctly"); + + for (i = 0; i < 50; i++) + { + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + GMutex lock; + GCond cond; + gboolean wait = TRUE; + ConcurrentFinalizeData *data; + GThread *source_thread, *target_thread; + gint count = 0; /* (atomic) */ + + g_mutex_init (&lock); + g_cond_init (&cond); + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_BIDIRECTIONAL); + g_object_ref (binding); + + data = g_new0 (ConcurrentFinalizeData, 1); + data->object = (GObject *) source; + data->wait = &wait; + data->lock = &lock; + data->cond = &cond; + data->count = &count; + source_thread = g_thread_new ("binding-concurrent", concurrent_finalize_func, data); + + data = g_new0 (ConcurrentFinalizeData, 1); + data->object = (GObject *) target; + data->wait = &wait; + data->lock = &lock; + data->cond = &cond; + data->count = &count; + target_thread = g_thread_new ("binding-concurrent", concurrent_finalize_func, data); + + /* wait until all threads are started */ + while (g_atomic_int_get (&count) < 2) + g_thread_yield (); + + g_mutex_lock (&lock); + wait = FALSE; + g_cond_broadcast (&cond); + g_mutex_unlock (&lock); + + g_thread_join (source_thread); + g_thread_join (target_thread); + + g_mutex_clear (&lock); + g_cond_clear (&cond); + + g_object_unref (binding); + } +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/binding/default", binding_default); + g_test_add_func ("/binding/canonicalisation", binding_canonicalisation); + g_test_add_func ("/binding/bidirectional", binding_bidirectional); + g_test_add_func ("/binding/transform", binding_transform); + g_test_add_func ("/binding/transform-default", binding_transform_default); + g_test_add_func ("/binding/transform-closure", binding_transform_closure); + g_test_add_func ("/binding/chain", binding_chain); + g_test_add_func ("/binding/sync-create", binding_sync_create); + g_test_add_func ("/binding/invert-boolean", binding_invert_boolean); + g_test_add_func ("/binding/same-object", binding_same_object); + g_test_add_func ("/binding/unbind", binding_unbind); + g_test_add_func ("/binding/unbind-weak", binding_unbind_weak); + g_test_add_func ("/binding/unbind-multiple", binding_unbind_multiple); + g_test_add_func ("/binding/fail", binding_fail); + g_test_add_func ("/binding/interface", binding_interface); + g_test_add_func ("/binding/concurrent-unbind", binding_concurrent_unbind); + g_test_add_func ("/binding/concurrent-finalizing", binding_concurrent_finalizing); + + return g_test_run (); +} diff --git a/gobject/tests/bindinggroup.c b/gobject/tests/bindinggroup.c new file mode 100644 index 0000000..94bc9b9 --- /dev/null +++ b/gobject/tests/bindinggroup.c @@ -0,0 +1,694 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * Copyright (C) 2015-2022 Christian Hergert + * Copyright (C) 2015 Garrett Regier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include + +/* Copied from glib */ +typedef struct _BindingSource +{ + GObject parent_instance; + + gint foo; + gint bar; + gdouble value; + gboolean toggle; +} BindingSource; + +typedef struct _BindingSourceClass +{ + GObjectClass parent_class; +} BindingSourceClass; + +enum +{ + PROP_SOURCE_FOO = 1, + PROP_SOURCE_BAR, + PROP_SOURCE_VALUE, + PROP_SOURCE_TOGGLE +}; + +static GType binding_source_get_type (void); +G_DEFINE_TYPE (BindingSource, binding_source, G_TYPE_OBJECT); + +static void +binding_source_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BindingSource *source = (BindingSource *) gobject; + + switch (prop_id) + { + case PROP_SOURCE_FOO: + source->foo = g_value_get_int (value); + break; + + case PROP_SOURCE_BAR: + source->bar = g_value_get_int (value); + break; + + case PROP_SOURCE_VALUE: + source->value = g_value_get_double (value); + break; + + case PROP_SOURCE_TOGGLE: + source->toggle = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_source_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BindingSource *source = (BindingSource *) gobject; + + switch (prop_id) + { + case PROP_SOURCE_FOO: + g_value_set_int (value, source->foo); + break; + + case PROP_SOURCE_BAR: + g_value_set_int (value, source->bar); + break; + + case PROP_SOURCE_VALUE: + g_value_set_double (value, source->value); + break; + + case PROP_SOURCE_TOGGLE: + g_value_set_boolean (value, source->toggle); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_source_class_init (BindingSourceClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = binding_source_set_property; + gobject_class->get_property = binding_source_get_property; + + g_object_class_install_property (gobject_class, PROP_SOURCE_FOO, + g_param_spec_int ("foo", "Foo", "Foo", + -1, 100, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_BAR, + g_param_spec_int ("bar", "Bar", "Bar", + -1, 100, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_VALUE, + g_param_spec_double ("value", "Value", "Value", + -100.0, 200.0, + 0.0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_TOGGLE, + g_param_spec_boolean ("toggle", "Toggle", "Toggle", + FALSE, + G_PARAM_READWRITE)); +} + +static void +binding_source_init (BindingSource *self) +{ +} + +typedef struct _BindingTarget +{ + GObject parent_instance; + + gint bar; + gdouble value; + gboolean toggle; +} BindingTarget; + +typedef struct _BindingTargetClass +{ + GObjectClass parent_class; +} BindingTargetClass; + +enum +{ + PROP_TARGET_BAR = 1, + PROP_TARGET_VALUE, + PROP_TARGET_TOGGLE +}; + +static GType binding_target_get_type (void); +G_DEFINE_TYPE (BindingTarget, binding_target, G_TYPE_OBJECT); + +static void +binding_target_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BindingTarget *target = (BindingTarget *) gobject; + + switch (prop_id) + { + case PROP_TARGET_BAR: + target->bar = g_value_get_int (value); + break; + + case PROP_TARGET_VALUE: + target->value = g_value_get_double (value); + break; + + case PROP_TARGET_TOGGLE: + target->toggle = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_target_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BindingTarget *target = (BindingTarget *) gobject; + + switch (prop_id) + { + case PROP_TARGET_BAR: + g_value_set_int (value, target->bar); + break; + + case PROP_TARGET_VALUE: + g_value_set_double (value, target->value); + break; + + case PROP_TARGET_TOGGLE: + g_value_set_boolean (value, target->toggle); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_target_class_init (BindingTargetClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = binding_target_set_property; + gobject_class->get_property = binding_target_get_property; + + g_object_class_install_property (gobject_class, PROP_TARGET_BAR, + g_param_spec_int ("bar", "Bar", "Bar", + -1, 100, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_TARGET_VALUE, + g_param_spec_double ("value", "Value", "Value", + -100.0, 200.0, + 0.0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_TARGET_TOGGLE, + g_param_spec_boolean ("toggle", "Toggle", "Toggle", + FALSE, + G_PARAM_READWRITE)); +} + +static void +binding_target_init (BindingTarget *self) +{ +} + +static gboolean +celsius_to_fahrenheit (GBinding *binding, + const GValue *from_value, + GValue *to_value, + gpointer user_data G_GNUC_UNUSED) +{ + gdouble celsius, fahrenheit; + + g_assert_true (G_VALUE_HOLDS (from_value, G_TYPE_DOUBLE)); + g_assert_true (G_VALUE_HOLDS (to_value, G_TYPE_DOUBLE)); + + celsius = g_value_get_double (from_value); + fahrenheit = (9 * celsius / 5) + 32.0; + + if (g_test_verbose ()) + g_printerr ("Converting %.2fC to %.2fF\n", celsius, fahrenheit); + + g_value_set_double (to_value, fahrenheit); + + return TRUE; +} + +static gboolean +fahrenheit_to_celsius (GBinding *binding, + const GValue *from_value, + GValue *to_value, + gpointer user_data G_GNUC_UNUSED) +{ + gdouble celsius, fahrenheit; + + g_assert_true (G_VALUE_HOLDS (from_value, G_TYPE_DOUBLE)); + g_assert_true (G_VALUE_HOLDS (to_value, G_TYPE_DOUBLE)); + + fahrenheit = g_value_get_double (from_value); + celsius = 5 * (fahrenheit - 32.0) / 9; + + if (g_test_verbose ()) + g_printerr ("Converting %.2fF to %.2fC\n", fahrenheit, celsius); + + g_value_set_double (to_value, celsius); + + return TRUE; +} + +static void +test_binding_group_invalid (void) +{ + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + + /* Invalid Target Property */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*find_property*target_property*!=*NULL*"); + g_binding_group_bind (group, "value", + target, "does-not-exist", + G_BINDING_DEFAULT); + g_test_assert_expected_messages (); + + g_binding_group_set_source (group, NULL); + + /* Invalid Source Property */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*find_property*source_property*!=*NULL*"); + g_binding_group_set_source (group, source); + g_binding_group_bind (group, "does-not-exist", + target, "value", + G_BINDING_DEFAULT); + g_test_assert_expected_messages (); + + g_binding_group_set_source (group, NULL); + + /* Invalid Source */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*find_property*->source_property*!=*NULL*"); + g_binding_group_bind (group, "does-not-exist", + target, "value", + G_BINDING_DEFAULT); + g_binding_group_set_source (group, source); + g_test_assert_expected_messages (); + + g_object_unref (target); + g_object_unref (source); + g_object_unref (group); +} + +static void +test_binding_group_default (void) +{ + gsize i, j; + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *targets[5]; + BindingSource *readback; + + for (i = 0; i < G_N_ELEMENTS (targets); ++i) + { + targets[i] = g_object_new (binding_target_get_type (), NULL); + g_binding_group_bind (group, "foo", + targets[i], "bar", + G_BINDING_DEFAULT); + } + + g_assert_null (g_binding_group_dup_source (group)); + g_binding_group_set_source (group, source); + readback = g_binding_group_dup_source (group); + g_assert_true (readback == source); + g_object_unref (readback); + + for (i = 0; i < 2; ++i) + { + g_object_set (source, "foo", 42, NULL); + for (j = 0; j < G_N_ELEMENTS (targets); ++j) + g_assert_cmpint (source->foo, ==, targets[j]->bar); + + g_object_set (targets[0], "bar", 47, NULL); + g_assert_cmpint (source->foo, !=, targets[0]->bar); + + /* Check that we transition the source correctly */ + g_binding_group_set_source (group, NULL); + g_assert_null (g_binding_group_dup_source (group)); + g_binding_group_set_source (group, source); + readback = g_binding_group_dup_source (group); + g_assert_true (readback == source); + g_object_unref (readback); + } + + g_object_unref (group); + + g_object_set (source, "foo", 0, NULL); + for (i = 0; i < G_N_ELEMENTS (targets); ++i) + g_assert_cmpint (source->foo, !=, targets[i]->bar); + + g_object_unref (source); + for (i = 0; i < G_N_ELEMENTS (targets); ++i) + g_object_unref (targets[i]); +} + +static void +test_binding_group_bidirectional (void) +{ + gsize i, j; + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *targets[5]; + BindingSource *readback; + + for (i = 0; i < G_N_ELEMENTS (targets); ++i) + { + targets[i] = g_object_new (binding_target_get_type (), NULL); + g_binding_group_bind (group, "value", + targets[i], "value", + G_BINDING_BIDIRECTIONAL); + } + + g_assert_null (g_binding_group_dup_source (group)); + g_binding_group_set_source (group, source); + readback = g_binding_group_dup_source (group); + g_assert_true (readback == source); + g_object_unref (readback); + + for (i = 0; i < 2; ++i) + { + g_object_set (source, "value", 42.0, NULL); + for (j = 0; j < G_N_ELEMENTS (targets); ++j) + g_assert_cmpfloat (source->value, ==, targets[j]->value); + + g_object_set (targets[0], "value", 47.0, NULL); + g_assert_cmpfloat (source->value, ==, targets[0]->value); + + /* Check that we transition the source correctly */ + g_binding_group_set_source (group, NULL); + g_assert_null (g_binding_group_dup_source (group)); + g_binding_group_set_source (group, source); + readback = g_binding_group_dup_source (group); + g_assert_true (readback == source); + g_object_unref (readback); + } + + g_object_unref (group); + + g_object_set (targets[0], "value", 0.0, NULL); + g_assert_cmpfloat (source->value, !=, targets[0]->value); + + g_object_unref (source); + for (i = 0; i < G_N_ELEMENTS (targets); ++i) + g_object_unref (targets[i]); +} + +static void +transform_destroy_notify (gpointer data) +{ + gboolean *transform_destroy_called = data; + + *transform_destroy_called = TRUE; +} + +static void +test_binding_group_transform (void) +{ + gboolean transform_destroy_called = FALSE; + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + + g_binding_group_set_source (group, source); + g_binding_group_bind_full (group, "value", + target, "value", + G_BINDING_BIDIRECTIONAL, + celsius_to_fahrenheit, + fahrenheit_to_celsius, + &transform_destroy_called, + transform_destroy_notify); + + g_object_set (source, "value", 24.0, NULL); + g_assert_cmpfloat (target->value, ==, ((9 * 24.0 / 5) + 32.0)); + + g_object_set (target, "value", 69.0, NULL); + g_assert_cmpfloat (source->value, ==, (5 * (69.0 - 32.0) / 9)); + + /* The GDestroyNotify should only be called when the + * set is freed, not when the various GBindings are freed + */ + g_binding_group_set_source (group, NULL); + g_assert_false (transform_destroy_called); + + g_object_unref (group); + g_assert_true (transform_destroy_called); + + g_object_unref (source); + g_object_unref (target); +} + +static void +test_binding_group_transform_closures (void) +{ + gboolean transform_destroy_called_1 = FALSE; + gboolean transform_destroy_called_2 = FALSE; + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GClosure *c2f_closure, *f2c_closure; + + c2f_closure = g_cclosure_new (G_CALLBACK (celsius_to_fahrenheit), + &transform_destroy_called_1, + (GClosureNotify) transform_destroy_notify); + f2c_closure = g_cclosure_new (G_CALLBACK (fahrenheit_to_celsius), + &transform_destroy_called_2, + (GClosureNotify) transform_destroy_notify); + + g_binding_group_set_source (group, source); + g_binding_group_bind_with_closures (group, "value", + target, "value", + G_BINDING_BIDIRECTIONAL, + c2f_closure, + f2c_closure); + + g_object_set (source, "value", 24.0, NULL); + g_assert_cmpfloat (target->value, ==, ((9 * 24.0 / 5) + 32.0)); + + g_object_set (target, "value", 69.0, NULL); + g_assert_cmpfloat (source->value, ==, (5 * (69.0 - 32.0) / 9)); + + /* The GClsoureNotify should only be called when the + * set is freed, not when the various GBindings are freed + */ + g_binding_group_set_source (group, NULL); + g_assert_false (transform_destroy_called_1); + g_assert_false (transform_destroy_called_2); + + g_object_unref (group); + g_assert_true (transform_destroy_called_1); + g_assert_true (transform_destroy_called_2); + + g_object_unref (source); + g_object_unref (target); +} + +static void +test_binding_group_same_object (void) +{ + gsize i; + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), + "foo", 100, + "bar", 50, + NULL); + + g_binding_group_set_source (group, source); + g_binding_group_bind (group, "foo", + source, "bar", + G_BINDING_BIDIRECTIONAL); + + for (i = 0; i < 2; ++i) + { + g_object_set (source, "foo", 10, NULL); + g_assert_cmpint (source->foo, ==, 10); + g_assert_cmpint (source->bar, ==, 10); + + g_object_set (source, "bar", 30, NULL); + g_assert_cmpint (source->foo, ==, 30); + g_assert_cmpint (source->bar, ==, 30); + + /* Check that it is possible both when initially + * adding the binding and when changing the source + */ + g_binding_group_set_source (group, NULL); + g_binding_group_set_source (group, source); + } + + g_object_unref (source); + g_object_unref (group); +} + +static void +test_binding_group_weak_ref_source (void) +{ + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + BindingSource *readback; + + g_binding_group_set_source (group, source); + g_binding_group_bind (group, "value", + target, "value", + G_BINDING_BIDIRECTIONAL); + + g_object_add_weak_pointer (G_OBJECT (source), (gpointer)&source); + readback = g_binding_group_dup_source (group); + g_assert_true (readback == source); + g_object_unref (readback); + g_object_unref (source); + g_assert_null (source); + g_assert_null (g_binding_group_dup_source (group)); + + /* Hopefully this would explode if the binding was still alive */ + g_object_set (target, "value", 0.0, NULL); + + g_object_unref (target); + g_object_unref (group); +} + +static void +test_binding_group_weak_ref_target (void) +{ + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + + g_binding_group_set_source (group, source); + g_binding_group_bind (group, "value", + target, "value", + G_BINDING_BIDIRECTIONAL); + + g_object_set (source, "value", 47.0, NULL); + g_assert_cmpfloat (target->value, ==, 47.0); + + g_object_add_weak_pointer (G_OBJECT (target), (gpointer)&target); + g_object_unref (target); + g_assert_null (target); + + /* Hopefully this would explode if the binding was still alive */ + g_object_set (source, "value", 0.0, NULL); + + g_object_unref (source); + g_object_unref (group); +} + +static void +test_binding_group_properties (void) +{ + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + BindingSource *other; + + g_binding_group_set_source (group, source); + g_binding_group_bind (group, "value", + target, "value", + G_BINDING_BIDIRECTIONAL); + + g_object_get (group, "source", &other, NULL); + g_assert_true (other == source); + g_object_unref (other); + + g_object_set (group, "source", NULL, NULL); + g_object_get (group, "source", &other, NULL); + g_assert_null (other); + + g_object_add_weak_pointer (G_OBJECT (target), (gpointer)&target); + g_object_unref (target); + g_assert_null (target); + + g_object_unref (source); + g_object_unref (group); +} + +static void +test_binding_group_weak_notify_no_bindings (void) +{ + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + + g_binding_group_set_source (group, source); + g_assert_finalize_object (source); + g_assert_finalize_object (group); +} + +static void +test_binding_group_empty_closures (void) +{ + GBindingGroup *group = g_binding_group_new (); + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + + g_binding_group_bind_full (group, "value", target, "value", 0, + NULL, NULL, NULL, NULL); + + g_assert_finalize_object (group); + g_assert_finalize_object (target); + g_assert_finalize_object (source); +} + +gint +main (gint argc, + gchar *argv[]) +{ + g_test_init (&argc, &argv, NULL); + g_test_add_func ("/GObject/BindingGroup/invalid", test_binding_group_invalid); + g_test_add_func ("/GObject/BindingGroup/default", test_binding_group_default); + g_test_add_func ("/GObject/BindingGroup/bidirectional", test_binding_group_bidirectional); + g_test_add_func ("/GObject/BindingGroup/transform", test_binding_group_transform); + g_test_add_func ("/GObject/BindingGroup/transform-closures", test_binding_group_transform_closures); + g_test_add_func ("/GObject/BindingGroup/same-object", test_binding_group_same_object); + g_test_add_func ("/GObject/BindingGroup/weak-ref-source", test_binding_group_weak_ref_source); + g_test_add_func ("/GObject/BindingGroup/weak-ref-target", test_binding_group_weak_ref_target); + g_test_add_func ("/GObject/BindingGroup/properties", test_binding_group_properties); + g_test_add_func ("/GObject/BindingGroup/weak-notify-no-bindings", test_binding_group_weak_notify_no_bindings); + g_test_add_func ("/GObject/BindingGroup/empty-closures", test_binding_group_empty_closures); + return g_test_run (); +} diff --git a/gobject/tests/boxed.c b/gobject/tests/boxed.c new file mode 100644 index 0000000..f961a2f --- /dev/null +++ b/gobject/tests/boxed.c @@ -0,0 +1,704 @@ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +typedef struct _MyBoxed MyBoxed; + +struct _MyBoxed +{ + gint ivalue; + gchar *bla; +}; + +static gpointer +my_boxed_copy (gpointer orig) +{ + MyBoxed *a = orig; + MyBoxed *b; + + b = g_slice_new (MyBoxed); + b->ivalue = a->ivalue; + b->bla = g_strdup (a->bla); + + return b; +} + +static gint my_boxed_free_count; + +static void +my_boxed_free (gpointer orig) +{ + MyBoxed *a = orig; + + g_free (a->bla); + g_slice_free (MyBoxed, a); + + my_boxed_free_count++; +} + +static GType my_boxed_get_type (void); +#define MY_TYPE_BOXED (my_boxed_get_type ()) + +G_DEFINE_BOXED_TYPE (MyBoxed, my_boxed, my_boxed_copy, my_boxed_free) + +static void +test_define_boxed (void) +{ + MyBoxed a; + MyBoxed *b; + + a.ivalue = 20; + a.bla = g_strdup ("bla"); + + b = g_boxed_copy (MY_TYPE_BOXED, &a); + + g_assert_cmpint (b->ivalue, ==, 20); + g_assert_cmpstr (b->bla, ==, "bla"); + + g_boxed_free (MY_TYPE_BOXED, b); + + g_free (a.bla); +} + +static void +test_boxed_ownership (void) +{ + GValue value = G_VALUE_INIT; + static MyBoxed boxed = { 10, "bla" }; + + g_value_init (&value, MY_TYPE_BOXED); + + my_boxed_free_count = 0; + + g_value_set_static_boxed (&value, &boxed); + g_value_reset (&value); + + g_assert_cmpint (my_boxed_free_count, ==, 0); + + g_value_set_boxed_take_ownership (&value, g_boxed_copy (MY_TYPE_BOXED, &boxed)); + g_value_reset (&value); + g_assert_cmpint (my_boxed_free_count, ==, 1); + + g_value_take_boxed (&value, g_boxed_copy (MY_TYPE_BOXED, &boxed)); + g_value_reset (&value); + g_assert_cmpint (my_boxed_free_count, ==, 2); + + g_value_set_boxed (&value, &boxed); + g_value_reset (&value); + g_assert_cmpint (my_boxed_free_count, ==, 3); +} + +static void +my_callback (gpointer user_data) +{ +} + +static gint destroy_count; + +static void +my_closure_notify (gpointer user_data, GClosure *closure) +{ + destroy_count++; +} + +static void +test_boxed_closure (void) +{ + GClosure *closure; + GClosure *closure2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_CLOSURE); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + closure = g_cclosure_new (G_CALLBACK (my_callback), "bla", my_closure_notify); + g_value_take_boxed (&value, closure); + + closure2 = g_value_get_boxed (&value); + g_assert (closure2 == closure); + + closure2 = g_value_dup_boxed (&value); + g_assert (closure2 == closure); /* closures use ref/unref for copy/free */ + g_closure_unref (closure2); + + g_value_unset (&value); + g_assert_cmpint (destroy_count, ==, 1); +} + +static void +test_boxed_date (void) +{ + GDate *date; + GDate *date2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_DATE); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + date = g_date_new_dmy (1, 3, 1970); + g_value_take_boxed (&value, date); + + date2 = g_value_get_boxed (&value); + g_assert (date2 == date); + + date2 = g_value_dup_boxed (&value); + g_assert (date2 != date); + g_assert (g_date_compare (date, date2) == 0); + g_date_free (date2); + + g_value_unset (&value); +} + +static void +test_boxed_value (void) +{ + GValue value1 = G_VALUE_INIT; + GValue *value2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_VALUE); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + g_value_init (&value1, G_TYPE_INT); + g_value_set_int (&value1, 26); + + g_value_set_static_boxed (&value, &value1); + + value2 = g_value_get_boxed (&value); + g_assert (value2 == &value1); + + value2 = g_value_dup_boxed (&value); + g_assert (value2 != &value1); + g_assert (G_VALUE_HOLDS_INT (value2)); + g_assert_cmpint (g_value_get_int (value2), ==, 26); + g_boxed_free (G_TYPE_VALUE, value2); + + g_value_unset (&value); +} + +static void +test_boxed_string (void) +{ + GString *v; + GString *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_GSTRING); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_string_new ("bla"); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v2 == v); + + v2 = g_value_dup_boxed (&value); + g_assert (v2 != v); + g_assert (g_string_equal (v, v2)); + g_string_free (v2, TRUE); + + g_value_unset (&value); +} + +static void +test_boxed_hashtable (void) +{ + GHashTable *v; + GHashTable *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_HASH_TABLE); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_hash_table_new (g_str_hash, g_str_equal); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v2 == v); + + v2 = g_value_dup_boxed (&value); + g_assert (v2 == v); /* hash tables use ref/unref for copy/free */ + g_hash_table_unref (v2); + + g_value_unset (&value); +} + +static void +test_boxed_array (void) +{ + GArray *v; + GArray *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_ARRAY); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_array_new (TRUE, FALSE, 1); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v2 == v); + + v2 = g_value_dup_boxed (&value); + g_assert (v2 == v); /* arrays use ref/unref for copy/free */ + g_array_unref (v2); + + g_value_unset (&value); +} + +static void +test_boxed_ptrarray (void) +{ + GPtrArray *v; + GPtrArray *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_PTR_ARRAY); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_ptr_array_new (); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v2 == v); + + v2 = g_value_dup_boxed (&value); + g_assert (v2 == v); /* ptr arrays use ref/unref for copy/free */ + g_ptr_array_unref (v2); + + g_value_unset (&value); +} + +static void +test_boxed_regex (void) +{ + GRegex *v; + GRegex *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_REGEX); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_regex_new ("a+b+", 0, 0, NULL); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v2 == v); + + v2 = g_value_dup_boxed (&value); + g_assert (v2 == v); /* regexes use ref/unref for copy/free */ + g_regex_unref (v2); + + g_value_unset (&value); +} + +static void +test_boxed_matchinfo (void) +{ + GRegex *r; + GMatchInfo *info, *info2; + gboolean ret; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_MATCH_INFO); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + r = g_regex_new ("ab", 0, 0, NULL); + ret = g_regex_match (r, "blabla abab bla", 0, &info); + g_assert (ret); + g_value_take_boxed (&value, info); + + info2 = g_value_get_boxed (&value); + g_assert (info == info2); + + info2 = g_value_dup_boxed (&value); + g_assert (info == info2); /* matchinfo uses ref/unref for copy/free */ + g_match_info_unref (info2); + + g_value_unset (&value); + g_regex_unref (r); +} + +static void +test_boxed_varianttype (void) +{ + GVariantType *v; + GVariantType *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_VARIANT_TYPE); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_variant_type_new ("mas"); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v2 == v); + + v2 = g_value_dup_boxed (&value); + g_assert (v2 != v); + g_assert_cmpstr (g_variant_type_peek_string (v), ==, g_variant_type_peek_string (v2)); + g_variant_type_free (v2); + + g_value_unset (&value); +} + +static void +test_boxed_datetime (void) +{ + GDateTime *v; + GDateTime *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_DATE_TIME); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_date_time_new_now_local (); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v2 == v); + + v2 = g_value_dup_boxed (&value); + g_assert (v2 == v); /* datetime uses ref/unref for copy/free */ + g_date_time_unref (v2); + + g_value_unset (&value); +} + +static void +test_boxed_error (void) +{ + GError *v; + GError *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_ERROR); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_error_new_literal (G_VARIANT_PARSE_ERROR, + G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG, + "Too damn big"); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v2 == v); + + v2 = g_value_dup_boxed (&value); + g_assert (v2 != v); + g_assert_cmpint (v->domain, ==, v2->domain); + g_assert_cmpint (v->code, ==, v2->code); + g_assert_cmpstr (v->message, ==, v2->message); + g_error_free (v2); + + g_value_unset (&value); +} + +static void +test_boxed_keyfile (void) +{ + GKeyFile *k, *k2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_KEY_FILE); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + k = g_key_file_new (); + g_value_take_boxed (&value, k); + + k2 = g_value_get_boxed (&value); + g_assert (k == k2); + + k2 = g_value_dup_boxed (&value); + g_assert (k == k2); /* keyfile uses ref/unref for copy/free */ + g_key_file_unref (k2); + + g_value_unset (&value); +} + +static void +test_boxed_mainloop (void) +{ + GMainLoop *l, *l2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_MAIN_LOOP); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + l = g_main_loop_new (NULL, FALSE); + g_value_take_boxed (&value, l); + + l2 = g_value_get_boxed (&value); + g_assert (l == l2); + + l2 = g_value_dup_boxed (&value); + g_assert (l == l2); /* mainloop uses ref/unref for copy/free */ + g_main_loop_unref (l2); + + g_value_unset (&value); +} + +static void +test_boxed_maincontext (void) +{ + GMainContext *c, *c2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_MAIN_CONTEXT); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + c = g_main_context_new (); + g_value_take_boxed (&value, c); + + c2 = g_value_get_boxed (&value); + g_assert (c == c2); + + c2 = g_value_dup_boxed (&value); + g_assert (c == c2); /* maincontext uses ref/unref for copy/free */ + g_main_context_unref (c2); + + g_value_unset (&value); +} + +static void +test_boxed_source (void) +{ + GSource *s, *s2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_SOURCE); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + s = g_idle_source_new (); + g_value_take_boxed (&value, s); + + s2 = g_value_get_boxed (&value); + g_assert (s == s2); + + s2 = g_value_dup_boxed (&value); + g_assert (s == s2); /* source uses ref/unref for copy/free */ + g_source_unref (s2); + + g_value_unset (&value); +} + +static void +test_boxed_variantbuilder (void) +{ + GVariantBuilder *v, *v2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_VARIANT_BUILDER); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + v = g_variant_builder_new (G_VARIANT_TYPE_OBJECT_PATH_ARRAY); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); + g_assert (v == v2); + + v2 = g_value_dup_boxed (&value); + g_assert (v == v2); /* variantbuilder uses ref/unref for copy/free */ + g_variant_builder_unref (v2); + + g_value_unset (&value); +} + +static void +test_boxed_timezone (void) +{ + GTimeZone *z, *z2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_TIME_ZONE); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + z = g_time_zone_new_utc (); + g_value_take_boxed (&value, z); + + z2 = g_value_get_boxed (&value); + g_assert (z == z2); + + z2 = g_value_dup_boxed (&value); + g_assert (z == z2); /* timezone uses ref/unref for copy/free */ + g_time_zone_unref (z2); + + g_value_unset (&value); +} + +static void +test_boxed_pollfd (void) +{ + GPollFD *p, *p2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_POLLFD); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + p = g_new (GPollFD, 1); + g_value_take_boxed (&value, p); + + p2 = g_value_get_boxed (&value); + g_assert (p == p2); + + p2 = g_value_dup_boxed (&value); + g_assert (p != p2); + g_free (p2); + + g_value_unset (&value); +} + +static void +test_boxed_markup (void) +{ + GMarkupParseContext *c, *c2; + const GMarkupParser parser = { 0 }; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_MARKUP_PARSE_CONTEXT); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + c = g_markup_parse_context_new (&parser, 0, NULL, NULL); + g_value_take_boxed (&value, c); + + c2 = g_value_get_boxed (&value); + g_assert (c == c2); + + c2 = g_value_dup_boxed (&value); + g_assert (c == c2); + g_markup_parse_context_unref (c2); + + g_value_unset (&value); +} + +static void +test_boxed_thread (void) +{ + GThread *t, *t2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_THREAD); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + t = g_thread_self (); + g_value_set_boxed (&value, t); + + t2 = g_value_get_boxed (&value); + g_assert (t == t2); + + t2 = g_value_dup_boxed (&value); + g_assert (t == t2); + g_thread_unref (t2); + + g_value_unset (&value); +} + +static void +test_boxed_checksum (void) +{ + GChecksum *c, *c2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_CHECKSUM); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + + c = g_checksum_new (G_CHECKSUM_SHA512); + g_value_take_boxed (&value, c); + + c2 = g_value_get_boxed (&value); + g_assert (c == c2); + + c2 = g_value_dup_boxed (&value); + g_assert (c != c2); + g_checksum_free (c2); + + g_value_unset (&value); +} + +static gint +treecmp (gconstpointer a, gconstpointer b) +{ + return (a < b) ? -1 : (a > b); +} + +static void +test_boxed_tree (void) +{ + GTree *t, *t2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_TREE); + g_assert_true (G_VALUE_HOLDS_BOXED (&value)); + + t = g_tree_new (treecmp); + g_value_take_boxed (&value, t); + + t2 = g_value_get_boxed (&value); + g_assert_true (t == t2); + + t2 = g_value_dup_boxed (&value); + g_assert_true (t == t2); /* trees use ref/unref for copy/free */ + g_tree_unref (t2); + + g_value_unset (&value); +} + +static void +test_boxed_pattern_spec (void) +{ + GPatternSpec *ps, *ps2; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_PATTERN_SPEC); + g_assert_true (G_VALUE_HOLDS_BOXED (&value)); + + ps = g_pattern_spec_new ("*abc*?cde"); + g_value_take_boxed (&value, ps); + + ps2 = g_value_get_boxed (&value); + g_assert_true (ps == ps2); + + ps2 = g_value_dup_boxed (&value); + g_assert_true (ps != ps2); + g_assert_true (g_pattern_spec_equal (ps, ps2)); + g_pattern_spec_free (ps2); + + g_value_unset (&value); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/boxed/define", test_define_boxed); + g_test_add_func ("/boxed/ownership", test_boxed_ownership); + g_test_add_func ("/boxed/closure", test_boxed_closure); + g_test_add_func ("/boxed/date", test_boxed_date); + g_test_add_func ("/boxed/value", test_boxed_value); + g_test_add_func ("/boxed/string", test_boxed_string); + g_test_add_func ("/boxed/hashtable", test_boxed_hashtable); + g_test_add_func ("/boxed/array", test_boxed_array); + g_test_add_func ("/boxed/ptrarray", test_boxed_ptrarray); + g_test_add_func ("/boxed/regex", test_boxed_regex); + g_test_add_func ("/boxed/varianttype", test_boxed_varianttype); + g_test_add_func ("/boxed/error", test_boxed_error); + g_test_add_func ("/boxed/datetime", test_boxed_datetime); + g_test_add_func ("/boxed/matchinfo", test_boxed_matchinfo); + g_test_add_func ("/boxed/keyfile", test_boxed_keyfile); + g_test_add_func ("/boxed/mainloop", test_boxed_mainloop); + g_test_add_func ("/boxed/maincontext", test_boxed_maincontext); + g_test_add_func ("/boxed/source", test_boxed_source); + g_test_add_func ("/boxed/variantbuilder", test_boxed_variantbuilder); + g_test_add_func ("/boxed/timezone", test_boxed_timezone); + g_test_add_func ("/boxed/pollfd", test_boxed_pollfd); + g_test_add_func ("/boxed/markup", test_boxed_markup); + g_test_add_func ("/boxed/thread", test_boxed_thread); + g_test_add_func ("/boxed/checksum", test_boxed_checksum); + g_test_add_func ("/boxed/tree", test_boxed_tree); + g_test_add_func ("/boxed/patternspec", test_boxed_pattern_spec); + + return g_test_run (); +} diff --git a/gobject/tests/closure-refcount.c b/gobject/tests/closure-refcount.c new file mode 100644 index 0000000..5a92005 --- /dev/null +++ b/gobject/tests/closure-refcount.c @@ -0,0 +1,337 @@ +/* Copyright (C) 2005 Imendio AB + * + * This software is provided "as is"; redistribution and modification + * is permitted, provided that the following disclaimer is retained. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#include + +#ifdef G_OS_UNIX +#include +#endif + +#define TEST_POINTER1 ((gpointer) 47) +#define TEST_POINTER2 ((gpointer) 49) +#define TEST_INT1 (-77) +#define TEST_INT2 (78) + +/* --- GTest class --- */ +typedef struct { + GObject object; + gint value; + gpointer test_pointer1; + gpointer test_pointer2; +} GTest; +typedef struct { + GObjectClass parent_class; + void (*test_signal1) (GTest * test, gint an_int); + void (*test_signal2) (GTest * test, gint an_int); +} GTestClass; + +#define G_TYPE_TEST (my_test_get_type ()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +#define MY_IS_TEST(test) (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST)) +#define MY_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass)) +#define MY_IS_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST)) +#define MY_TEST_GET_CLASS(test) (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass)) + +static GType my_test_get_type (void); +G_DEFINE_TYPE (GTest, my_test, G_TYPE_OBJECT) + +/* Test state */ +typedef struct +{ + GClosure *closure; /* (unowned) */ + gboolean stopping; + gboolean seen_signal_handler; + gboolean seen_cleanup; + gboolean seen_test_int1; + gboolean seen_test_int2; + gboolean seen_thread1; + gboolean seen_thread2; +} TestClosureRefcountData; + +/* --- functions --- */ +static void +my_test_init (GTest * test) +{ + g_test_message ("Init %p", test); + + test->value = 0; + test->test_pointer1 = TEST_POINTER1; + test->test_pointer2 = TEST_POINTER2; +} + +typedef enum +{ + PROP_TEST_PROP = 1, +} MyTestProperty; + +typedef enum +{ + SIGNAL_TEST_SIGNAL1, + SIGNAL_TEST_SIGNAL2, +} MyTestSignal; + +static guint signals[SIGNAL_TEST_SIGNAL2 + 1] = { 0, }; + +static void +my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTest *test = MY_TEST (object); + switch (prop_id) + { + case PROP_TEST_PROP: + test->value = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTest *test = MY_TEST (object); + switch (prop_id) + { + case PROP_TEST_PROP: + g_value_set_int (value, test->value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_test_signal2 (GTest *test, + gint an_int) +{ +} + +static void +my_test_emit_test_signal1 (GTest *test, + gint vint) +{ + g_signal_emit (G_OBJECT (test), signals[SIGNAL_TEST_SIGNAL1], 0, vint); +} + +static void +my_test_emit_test_signal2 (GTest *test, + gint vint) +{ + g_signal_emit (G_OBJECT (test), signals[SIGNAL_TEST_SIGNAL2], 0, vint); +} + +static void +my_test_class_init (GTestClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = my_test_set_property; + gobject_class->get_property = my_test_get_property; + + signals[SIGNAL_TEST_SIGNAL1] = + g_signal_new ("test-signal1", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GTestClass, test_signal1), NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + signals[SIGNAL_TEST_SIGNAL2] = + g_signal_new ("test-signal2", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GTestClass, test_signal2), NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TEST_PROP, + g_param_spec_int ("test-prop", "Test Prop", "Test property", + 0, 1, 0, G_PARAM_READWRITE)); + klass->test_signal2 = my_test_test_signal2; +} + +static void +test_closure (GClosure *closure) +{ + /* try to produce high contention in closure->ref_count */ + guint i = 0, n = g_random_int () % 199; + for (i = 0; i < n; i++) + g_closure_ref (closure); + g_closure_sink (closure); /* NOP */ + for (i = 0; i < n; i++) + g_closure_unref (closure); +} + +static gpointer +thread1_main (gpointer user_data) +{ + TestClosureRefcountData *data = user_data; + guint i = 0; + + for (i = 1; !g_atomic_int_get (&data->stopping); i++) + { + test_closure (data->closure); + if (i % 10000 == 0) + { + g_test_message ("Yielding from thread1"); + g_thread_yield (); /* force context switch */ + g_atomic_int_set (&data->seen_thread1, TRUE); + } + } + return NULL; +} + +static gpointer +thread2_main (gpointer user_data) +{ + TestClosureRefcountData *data = user_data; + guint i = 0; + + for (i = 1; !g_atomic_int_get (&data->stopping); i++) + { + test_closure (data->closure); + if (i % 10000 == 0) + { + g_test_message ("Yielding from thread2"); + g_thread_yield (); /* force context switch */ + g_atomic_int_set (&data->seen_thread2, TRUE); + } + } + return NULL; +} + +static void +test_signal_handler (GTest *test, + gint vint, + gpointer user_data) +{ + TestClosureRefcountData *data = user_data; + + g_assert_true (test->test_pointer1 == TEST_POINTER1); + + data->seen_signal_handler = TRUE; + data->seen_test_int1 |= vint == TEST_INT1; + data->seen_test_int2 |= vint == TEST_INT2; +} + +static void +destroy_data (gpointer user_data, + GClosure *closure) +{ + TestClosureRefcountData *data = user_data; + + data->seen_cleanup = TRUE; + g_assert_true (data->closure == closure); + g_assert_cmpint (closure->ref_count, ==, 0); +} + +static void +test_emissions (GTest *test) +{ + my_test_emit_test_signal1 (test, TEST_INT1); + my_test_emit_test_signal2 (test, TEST_INT2); +} + +/* Test that closure refcounting works even when high contested between three + * threads (the main thread, thread1 and thread2). Both child threads are + * contesting refs/unrefs, while the main thread periodically emits signals + * which also do refs/unrefs on closures. */ +static void +test_closure_refcount (void) +{ + GThread *thread1, *thread2; + TestClosureRefcountData test_data = { 0, }; + GClosure *closure; + GTest *object; + guint i, n_iterations; + + object = g_object_new (G_TYPE_TEST, NULL); + closure = g_cclosure_new (G_CALLBACK (test_signal_handler), &test_data, destroy_data); + + g_signal_connect_closure (object, "test-signal1", closure, FALSE); + g_signal_connect_closure (object, "test-signal2", closure, FALSE); + + test_data.stopping = FALSE; + test_data.closure = closure; + + thread1 = g_thread_new ("thread1", thread1_main, &test_data); + thread2 = g_thread_new ("thread2", thread2_main, &test_data); + + /* The 16-bit compare-and-swap operations currently used for closure + * refcounts are really slow on some ARM CPUs, notably Cortex-A57. + * Reduce the number of iterations so that the test completes in a + * finite time, but don't reduce it so much that the main thread + * starves the other threads and causes a test failure. + * + * https://gitlab.gnome.org/GNOME/glib/issues/1316 + * aka https://bugs.debian.org/880883 */ +#if defined(__aarch64__) || defined(__arm__) + n_iterations = 100000; +#else + n_iterations = 1000000; +#endif + + /* Run the test for a reasonably high number of iterations, and ensure we + * don’t terminate until at least 10000 iterations have completed in both + * thread1 and thread2. Even though @n_iterations is high, we can’t guarantee + * that the scheduler allocates time fairly (or at all!) to thread1 or + * thread2. */ + for (i = 1; + i < n_iterations || + !g_atomic_int_get (&test_data.seen_thread1) || + !g_atomic_int_get (&test_data.seen_thread2); + i++) + { + test_emissions (object); + if (i % 10000 == 0) + { + g_test_message ("Yielding from main thread"); + g_thread_yield (); /* force context switch */ + } + } + + g_atomic_int_set (&test_data.stopping, TRUE); + g_test_message ("Stopping"); + + /* wait for thread shutdown */ + g_thread_join (thread1); + g_thread_join (thread2); + + /* finalize object, destroy signals, run cleanup code */ + g_object_unref (object); + + g_test_message ("Stopped"); + + g_assert_true (g_atomic_int_get (&test_data.seen_thread1)); + g_assert_true (g_atomic_int_get (&test_data.seen_thread2)); + g_assert_true (test_data.seen_test_int1); + g_assert_true (test_data.seen_test_int2); + g_assert_true (test_data.seen_signal_handler); + g_assert_true (test_data.seen_cleanup); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/closure/refcount", test_closure_refcount); + + return g_test_run (); +} diff --git a/gobject/tests/closure.c b/gobject/tests/closure.c new file mode 100644 index 0000000..b761825 --- /dev/null +++ b/gobject/tests/closure.c @@ -0,0 +1,223 @@ +#include + +#ifdef G_OS_UNIX +#include + +#include +#include +#include +#endif + +static void +test_source (GSource *one, GCallback quit_callback) +{ + GClosure *closure; + GMainLoop *loop; + + /* Callback with GMainLoop user_data */ + loop = g_main_loop_new (NULL, FALSE); + + closure = g_cclosure_new (quit_callback, loop, NULL); + g_source_set_closure (one, closure); + + g_source_attach (one, NULL); + g_main_loop_run (loop); + + g_source_destroy (one); + g_main_loop_unref (loop); +} + +static gboolean +simple_quit_callback (gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_main_loop_quit (loop); + + return TRUE; +} + +static void +test_closure_idle (void) +{ + GSource *source; + + source = g_idle_source_new (); + test_source (source, G_CALLBACK (simple_quit_callback)); + g_source_unref (source); +} + +static void +test_closure_timeout (void) +{ + GSource *source; + + source = g_timeout_source_new (10); + test_source (source, G_CALLBACK (simple_quit_callback)); + g_source_unref (source); +} + +static gboolean +iochannel_quit_callback (GIOChannel *channel, + GIOCondition cond, + gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_main_loop_quit (loop); + + return TRUE; +} + +static void +test_closure_iochannel (void) +{ + GIOChannel *chan; + GSource *source; + char *path; + GError *error = NULL; + + if (g_path_is_absolute (g_get_prgname ())) + path = g_strdup (g_get_prgname ()); + else + { + path = g_test_build_filename (G_TEST_BUILT, + g_get_prgname (), + NULL); + } + chan = g_io_channel_new_file (path, "r", &error); + g_assert_no_error (error); + g_free (path); + + source = g_io_create_watch (chan, G_IO_IN); + test_source (source, G_CALLBACK (iochannel_quit_callback)); + g_source_unref (source); + + g_io_channel_unref (chan); +} + +static void +test_closure_child (void) +{ + GSource *source; + GPid pid; + GError *error = NULL; + gchar *argv[3]; + + g_assert (g_getenv ("DO_NOT_ACCIDENTALLY_RECURSE") == NULL); + g_setenv ("DO_NOT_ACCIDENTALLY_RECURSE", "1", TRUE); + + if (g_path_is_absolute (g_get_prgname ())) + argv[0] = g_strdup (g_get_prgname ()); + else + { + argv[0] = g_test_build_filename (G_TEST_BUILT, + g_get_prgname (), + NULL); + } + argv[1] = "-l"; + argv[2] = NULL; + + g_spawn_async (NULL, argv, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | + G_SPAWN_STDERR_TO_DEV_NULL | + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, + &pid, &error); + g_assert_no_error (error); + + g_free (argv[0]); + + source = g_child_watch_source_new (pid); + test_source (source, G_CALLBACK (iochannel_quit_callback)); + g_source_unref (source); +} + +#ifdef G_OS_UNIX +static gboolean +fd_quit_callback (gint fd, + GIOCondition condition, + gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_main_loop_quit (loop); + + return TRUE; +} + +static void +test_closure_fd (void) +{ + gint fd; + GSource *source; + + fd = open ("/dev/null", O_RDONLY); + g_assert (fd != -1); + + source = g_unix_fd_source_new (fd, G_IO_IN); + test_source (source, G_CALLBACK (fd_quit_callback)); + g_source_unref (source); + + close (fd); +} + +static gboolean +send_usr1 (gpointer user_data) +{ + kill (getpid (), SIGUSR1); + return FALSE; +} + +static gboolean +closure_quit_callback (gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_main_loop_quit (loop); + + return TRUE; +} + +static void +test_closure_signal (void) +{ + GSource *source; + + g_idle_add_full (G_PRIORITY_LOW, send_usr1, NULL, NULL); + + source = g_unix_signal_source_new (SIGUSR1); + test_source (source, G_CALLBACK (closure_quit_callback)); + g_source_unref (source); +} +#endif + +int +main (int argc, + char *argv[]) +{ +#ifndef G_OS_WIN32 + sigset_t sig_mask, old_mask; + + sigemptyset (&sig_mask); + sigaddset (&sig_mask, SIGUSR1); + if (sigprocmask (SIG_UNBLOCK, &sig_mask, &old_mask) == 0) + { + if (sigismember (&old_mask, SIGUSR1)) + g_message ("SIGUSR1 was blocked, unblocking it"); + } +#endif + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/closure/idle", test_closure_idle); + g_test_add_func ("/closure/timeout", test_closure_timeout); + g_test_add_func ("/closure/iochannel", test_closure_iochannel); + g_test_add_func ("/closure/child", test_closure_child); +#ifdef G_OS_UNIX + g_test_add_func ("/closure/fd", test_closure_fd); + g_test_add_func ("/closure/signal", test_closure_signal); +#endif + + return g_test_run (); +} diff --git a/gobject/tests/cxx.cpp b/gobject/tests/cxx.cpp new file mode 100644 index 0000000..210c897 --- /dev/null +++ b/gobject/tests/cxx.cpp @@ -0,0 +1,26 @@ +/* Copyright (C) 2001 Sebastian Wilhelmi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +/* A trivial C++ program to be compiled in C++ mode, which + * smoketests that the GObject headers are valid C++ headers. */ + +#include + +int +main () +{ + return 0; +} diff --git a/gobject/tests/dynamictests.c b/gobject/tests/dynamictests.c new file mode 100644 index 0000000..06e1e01 --- /dev/null +++ b/gobject/tests/dynamictests.c @@ -0,0 +1,368 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Imendio AB + * Authors: Tim Janik + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#include +#include + +/* This test tests the macros for defining dynamic types. + */ + +static GMutex sync_mutex; +static gboolean loaded = FALSE; + +/* MODULE */ +typedef struct _TestModule TestModule; +typedef struct _TestModuleClass TestModuleClass; + +#define TEST_TYPE_MODULE (test_module_get_type ()) +#define TEST_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), TEST_TYPE_MODULE, TestModule)) +#define TEST_MODULE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), TEST_TYPE_MODULE, TestModuleClass)) +#define TEST_IS_MODULE(module) (G_TYPE_CHECK_INSTANCE_TYPE ((module), TEST_TYPE_MODULE)) +#define TEST_IS_MODULE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), TEST_TYPE_MODULE)) +#define TEST_MODULE_GET_CLASS(module) (G_TYPE_INSTANCE_GET_CLASS ((module), TEST_TYPE_MODULE, TestModuleClass)) +typedef void (*TestModuleRegisterFunc) (GTypeModule *module); + +struct _TestModule +{ + GTypeModule parent_instance; + + TestModuleRegisterFunc register_func; +}; + +struct _TestModuleClass +{ + GTypeModuleClass parent_class; +}; + +static GType test_module_get_type (void); + +static gboolean +test_module_load (GTypeModule *module) +{ + TestModule *test_module = TEST_MODULE (module); + + test_module->register_func (module); + + return TRUE; +} + +static void +test_module_unload (GTypeModule *module) +{ +} + +static void +test_module_class_init (TestModuleClass *class) +{ + GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class); + + module_class->load = test_module_load; + module_class->unload = test_module_unload; +} + +static GType test_module_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) { + static const GTypeInfo object_info = + { + sizeof (TestModuleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) test_module_class_init, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (TestModule), + 0, + (GInstanceInitFunc)NULL, + NULL, + }; + object_type = g_type_register_static (G_TYPE_TYPE_MODULE, "TestModule", &object_info, 0); + } + return object_type; +} + + +static GTypeModule * +test_module_new (TestModuleRegisterFunc register_func) +{ + TestModule *test_module = g_object_new (TEST_TYPE_MODULE, NULL); + GTypeModule *module = G_TYPE_MODULE (test_module); + + test_module->register_func = register_func; + + /* Register the types initially */ + g_type_module_use (module); + g_type_module_unuse (module); + + return G_TYPE_MODULE (module); +} + + + +#define DYNAMIC_OBJECT_TYPE (dynamic_object_get_type ()) + +typedef GObject DynamicObject; +typedef struct _DynamicObjectClass DynamicObjectClass; + +struct _DynamicObjectClass +{ + GObjectClass parent_class; + guint val; +}; + +static GType dynamic_object_get_type (void); +G_DEFINE_DYNAMIC_TYPE(DynamicObject, dynamic_object, G_TYPE_OBJECT) + +static void +dynamic_object_class_init (DynamicObjectClass *class) +{ + class->val = 42; + g_assert (loaded == FALSE); + loaded = TRUE; +} + +static void +dynamic_object_class_finalize (DynamicObjectClass *class) +{ + g_assert (loaded == TRUE); + loaded = FALSE; +} + +static void +dynamic_object_init (DynamicObject *dynamic_object) +{ +} + + +static void +module_register (GTypeModule *module) +{ + dynamic_object_register_type (module); +} + +#define N_THREADS 100 +#define N_REFS 10000 + +static gpointer +ref_unref_thread (gpointer data) +{ + gint i; + /* first, synchronize with other threads, + */ + if (g_test_verbose()) + g_printerr ("WAITING!\n"); + g_mutex_lock (&sync_mutex); + g_mutex_unlock (&sync_mutex); + if (g_test_verbose ()) + g_printerr ("STARTING\n"); + + /* ref/unref the klass 10000000 times */ + for (i = N_REFS; i; i--) { + if (g_test_verbose ()) + if (i % 10) + g_printerr ("%d\n", i); + g_type_class_unref (g_type_class_ref ((GType) data)); + } + + if (g_test_verbose()) + g_printerr ("DONE !\n"); + + return NULL; +} + +static void +test_multithreaded_dynamic_type_init (void) +{ + GTypeModule *module; + DynamicObjectClass *class; + /* Create N_THREADS threads that are going to just ref/unref a class */ + GThread *threads[N_THREADS]; + guint i; + + module = test_module_new (module_register); + g_assert (module != NULL); + + /* Not loaded until we call ref for the first time */ + class = g_type_class_peek (DYNAMIC_OBJECT_TYPE); + g_assert (class == NULL); + g_assert (!loaded); + + /* pause newly created threads */ + g_mutex_lock (&sync_mutex); + + /* create threads */ + for (i = 0; i < N_THREADS; i++) { + threads[i] = g_thread_new ("test", ref_unref_thread, (gpointer) DYNAMIC_OBJECT_TYPE); + } + + /* execute threads */ + g_mutex_unlock (&sync_mutex); + + for (i = 0; i < N_THREADS; i++) { + g_thread_join (threads[i]); + } +} + +enum +{ + PROP_0, + PROP_FOO +}; + +typedef struct _DynObj DynObj; +typedef struct _DynObjClass DynObjClass; +typedef struct _DynIfaceInterface DynIfaceInterface; + +struct _DynObj +{ + GObject obj; + + gint foo; +}; + +struct _DynObjClass +{ + GObjectClass class; +}; + +struct _DynIfaceInterface +{ + GTypeInterface iface; +}; + +static void dyn_obj_iface_init (DynIfaceInterface *iface); + +static GType dyn_iface_get_type (void); +G_DEFINE_INTERFACE (DynIface, dyn_iface, G_TYPE_OBJECT) + +static GType dyn_obj_get_type (void); +G_DEFINE_DYNAMIC_TYPE_EXTENDED(DynObj, dyn_obj, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE_DYNAMIC(dyn_iface_get_type (), dyn_obj_iface_init)) + + +static void +dyn_iface_default_init (DynIfaceInterface *iface) +{ + g_object_interface_install_property (iface, + g_param_spec_int ("foo", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE)); +} + +static void +dyn_obj_iface_init (DynIfaceInterface *iface) +{ +} + +static void +dyn_obj_init (DynObj *obj) +{ + obj->foo = 0; +} + +static void +set_prop (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + DynObj *obj = (DynObj *)object; + + switch (prop_id) + { + case PROP_FOO: + obj->foo = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_prop (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + DynObj *obj = (DynObj *)object; + + switch (prop_id) + { + case PROP_FOO: + g_value_set_int (value, obj->foo); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dyn_obj_class_init (DynObjClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->set_property = set_prop; + object_class->get_property = get_prop; + + g_object_class_override_property (object_class, PROP_FOO, "foo"); +} + +static void +dyn_obj_class_finalize (DynObjClass *class) +{ +} + +static void +mod_register (GTypeModule *module) +{ + dyn_obj_register_type (module); +} + +static void +test_dynamic_interface_properties (void) +{ + GTypeModule *module; + DynObj *obj; + gint val; + + module = test_module_new (mod_register); + g_assert (module != NULL); + + obj = g_object_new (dyn_obj_get_type (), "foo", 1, NULL); + g_object_get (obj, "foo", &val, NULL); + g_assert_cmpint (val, ==, 1); + + g_object_unref (obj); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/GObject/threaded-dynamic-ref-unref-init", test_multithreaded_dynamic_type_init); + g_test_add_func ("/GObject/dynamic-interface-properties", test_dynamic_interface_properties); + + return g_test_run(); +} diff --git a/gobject/tests/enums.c b/gobject/tests/enums.c new file mode 100644 index 0000000..3b96417 --- /dev/null +++ b/gobject/tests/enums.c @@ -0,0 +1,170 @@ +#include + +static const GEnumValue my_enum_values[] = +{ + { 1, "the first value", "one" }, + { 2, "the second value", "two" }, + { 3, "the third value", "three" }, + { 0, NULL, NULL } +}; + +static void +test_enum_basic (void) +{ + GType type; + GEnumClass *class; + GEnumValue *val; + GValue value = G_VALUE_INIT; + gchar *to_string; + + type = g_enum_register_static ("MyEnum", my_enum_values); + + g_value_init (&value, type); + g_assert (G_VALUE_HOLDS_ENUM (&value)); + + g_value_set_enum (&value, 2); + g_assert_cmpint (g_value_get_enum (&value), ==, 2); + g_value_unset (&value); + + class = g_type_class_ref (type); + + g_assert_cmpint (class->minimum, ==, 1); + g_assert_cmpint (class->maximum, ==, 3); + g_assert_cmpint (class->n_values, ==, 3); + + val = g_enum_get_value (class, 2); + g_assert (val != NULL); + g_assert_cmpstr (val->value_name, ==, "the second value"); + val = g_enum_get_value (class, 15); + g_assert (val == NULL); + + val = g_enum_get_value_by_name (class, "the third value"); + g_assert (val != NULL); + g_assert_cmpint (val->value, ==, 3); + val = g_enum_get_value_by_name (class, "the color purple"); + g_assert (val == NULL); + + val = g_enum_get_value_by_nick (class, "one"); + g_assert (val != NULL); + g_assert_cmpint (val->value, ==, 1); + val = g_enum_get_value_by_nick (class, "purple"); + g_assert (val == NULL); + + to_string = g_enum_to_string (type, 2); + g_assert_cmpstr (to_string, ==, "the second value"); + g_free (to_string); + + to_string = g_enum_to_string (type, 15); + g_assert_cmpstr (to_string, ==, "15"); + g_free (to_string); + + g_type_class_unref (class); +} + +static const GFlagsValue my_flag_values[] = +{ + { 0, "no flags", "none" }, + { 1, "the first flag", "one" }, + { 2, "the second flag", "two" }, + { 8, "the third flag", "three" }, + { 0, NULL, NULL } +}; + +static const GFlagsValue no_default_flag_values[] = +{ + { 1, "the first flag", "one" }, + { 0, NULL, NULL } +}; + +static void +test_flags_transform_to_string (const GValue *value) +{ + GValue tmp = G_VALUE_INIT; + + g_value_init (&tmp, G_TYPE_STRING); + g_value_transform (value, &tmp); + g_value_unset (&tmp); +} + +static void +test_flags_basic (void) +{ + GType type, no_default_type; + GFlagsClass *class; + GFlagsValue *val; + GValue value = G_VALUE_INIT; + gchar *to_string; + + type = g_flags_register_static ("MyFlags", my_flag_values); + no_default_type = g_flags_register_static ("NoDefaultFlags", + no_default_flag_values); + + g_value_init (&value, type); + g_assert (G_VALUE_HOLDS_FLAGS (&value)); + + g_value_set_flags (&value, 2|8); + g_assert_cmpint (g_value_get_flags (&value), ==, 2|8); + + class = g_type_class_ref (type); + + g_assert_cmpint (class->mask, ==, 1|2|8); + g_assert_cmpint (class->n_values, ==, 4); + + val = g_flags_get_first_value (class, 2|8); + g_assert (val != NULL); + g_assert_cmpstr (val->value_name, ==, "the second flag"); + val = g_flags_get_first_value (class, 16); + g_assert (val == NULL); + + val = g_flags_get_value_by_name (class, "the third flag"); + g_assert (val != NULL); + g_assert_cmpint (val->value, ==, 8); + val = g_flags_get_value_by_name (class, "the color purple"); + g_assert (val == NULL); + + val = g_flags_get_value_by_nick (class, "one"); + g_assert (val != NULL); + g_assert_cmpint (val->value, ==, 1); + val = g_flags_get_value_by_nick (class, "purple"); + g_assert (val == NULL); + + test_flags_transform_to_string (&value); + g_value_unset (&value); + + to_string = g_flags_to_string (type, 1|8); + g_assert_cmpstr (to_string, ==, "the first flag | the third flag"); + g_free (to_string); + + to_string = g_flags_to_string (type, 0); + g_assert_cmpstr (to_string, ==, "no flags"); + g_free (to_string); + + to_string = g_flags_to_string (type, 16); + g_assert_cmpstr (to_string, ==, "0x10"); + g_free (to_string); + + to_string = g_flags_to_string (type, 1|16); + g_assert_cmpstr (to_string, ==, "the first flag | 0x10"); + g_free (to_string); + + to_string = g_flags_to_string (no_default_type, 0); + g_assert_cmpstr (to_string, ==, "0x0"); + g_free (to_string); + + to_string = g_flags_to_string (no_default_type, 16); + g_assert_cmpstr (to_string, ==, "0x10"); + g_free (to_string); + + g_type_class_unref (class); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/enum/basic", test_enum_basic); + g_test_add_func ("/flags/basic", test_flags_basic); + + return g_test_run (); +} diff --git a/gobject/tests/flags.c b/gobject/tests/flags.c new file mode 100644 index 0000000..afe3c2e --- /dev/null +++ b/gobject/tests/flags.c @@ -0,0 +1,179 @@ +/* flags.c + * Copyright (C) 2018 Arthur Demchenkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + */ + +#include + +/* Check that validation of flags works on architectures where + * #gint and #glong are different sizes, as the flags are cast + * between types a few times. + * + * See: https://gitlab.gnome.org/GNOME/glib/issues/1572 + */ + +enum { + PROP_FLAGS = 1 +}; + +typedef struct _GTest GTest; +typedef struct _GTestClass GTestClass; + +typedef enum { + NO_FLAG = 0, + LOWEST_FLAG = 1, + HIGHEST_FLAG = 1 << 31 +} MyFlagsEnum; + +struct _GTest { + GObject object; + MyFlagsEnum flags; +}; + +struct _GTestClass { + GObjectClass parent_class; +}; + +static GType my_test_get_type (void); +static GType my_test_flags_get_type (void); + +#define G_TYPE_TEST (my_test_get_type()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +G_DEFINE_TYPE (GTest, my_test, G_TYPE_OBJECT) + +static void my_test_class_init (GTestClass * klass); +static void my_test_init (GTest * test); +static void my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static GType +my_test_flags_get_type (void) +{ + static GType flags_type = 0; + + if (G_UNLIKELY(flags_type == 0)) + { + static const GFlagsValue values[] = { + { LOWEST_FLAG, "LOWEST_FLAG", "lowest" }, + { HIGHEST_FLAG, "HIGHEST_FLAG", "highest" }, + { 0, NULL, NULL } + }; + + flags_type = g_flags_register_static (g_intern_static_string ("GTestFlags"), values); + } + return flags_type; +} + +static void +my_test_class_init (GTestClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = my_test_get_property; + gobject_class->set_property = my_test_set_property; + + g_object_class_install_property (gobject_class, 1, + g_param_spec_flags ("flags", + "Flags", + "Flags test property", + my_test_flags_get_type(), 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); +} + +static void my_test_init (GTest *test) +{ +} + +static void +my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTest *test = MY_TEST (object); + + switch (prop_id) + { + case PROP_FLAGS: + g_value_set_flags (value, test->flags); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTest *test = MY_TEST (object); + + switch (prop_id) + { + case PROP_FLAGS: + test->flags = g_value_get_flags (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +check_flags_validation (void) +{ + guint test_flags[] = { + NO_FLAG, + LOWEST_FLAG, + HIGHEST_FLAG, + LOWEST_FLAG | HIGHEST_FLAG + }; + guint flag_read; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (test_flags); i++) + { + guint flag_set = test_flags[i]; + GObject *test = g_object_new (G_TYPE_TEST, + "flags", flag_set, + NULL); + + g_object_get (test, "flags", &flag_read, NULL); + + /* This check will fail in case of gint -> glong conversion + * in value_flags_enum_collect_value() */ + g_assert_cmpint (flag_read, ==, flag_set); + + g_object_unref (test); + } +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + g_test_add_func ("/gobject/flags/validate", check_flags_validation); + return g_test_run (); +} diff --git a/gobject/tests/genmarshal.py b/gobject/tests/genmarshal.py new file mode 100644 index 0000000..5323cfb --- /dev/null +++ b/gobject/tests/genmarshal.py @@ -0,0 +1,817 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# +# Copyright © 2019 Endless Mobile, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +"""Integration tests for glib-genmarshal utility.""" + +import collections +import os +import shutil +import subprocess +import sys +import tempfile +from textwrap import dedent +import unittest + +import taptestrunner + + +# Disable line length warnings as wrapping the C code templates would be hard +# flake8: noqa: E501 + + +Result = collections.namedtuple("Result", ("info", "out", "err", "subs")) + + +class TestGenmarshal(unittest.TestCase): + """Integration test for running glib-genmarshal. + + This can be run when installed or uninstalled. When uninstalled, it + requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set. + + The idea with this test harness is to test the glib-genmarshal utility, its + handling of command line arguments, its exit statuses, and its handling of + various marshaller lists. In future we could split the core glib-genmarshal + parsing and generation code out into a library and unit test that, and + convert this test to just check command line behaviour. + """ + + # Track the cwd, we want to back out to that to clean up our tempdir + cwd = "" + + def setUp(self): + self.timeout_seconds = 10 # seconds per test + self.tmpdir = tempfile.TemporaryDirectory() + self.cwd = os.getcwd() + os.chdir(self.tmpdir.name) + print("tmpdir:", self.tmpdir.name) + if "G_TEST_BUILDDIR" in os.environ: + self.__genmarshal = os.path.join( + os.environ["G_TEST_BUILDDIR"], "..", "glib-genmarshal" + ) + else: + self.__genmarshal = shutil.which("glib-genmarshal") + print("genmarshal:", self.__genmarshal) + + def tearDown(self): + os.chdir(self.cwd) + self.tmpdir.cleanup() + + def runGenmarshal(self, *args): + argv = [self.__genmarshal] + + # shebang lines are not supported on native + # Windows consoles + if os.name == "nt": + argv.insert(0, sys.executable) + + argv.extend(args) + print("Running:", argv) + + env = os.environ.copy() + env["LC_ALL"] = "C.UTF-8" + print("Environment:", env) + + # We want to ensure consistent line endings... + info = subprocess.run( + argv, + timeout=self.timeout_seconds, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + universal_newlines=True, + ) + info.check_returncode() + out = info.stdout.strip() + err = info.stderr.strip() + + # Known substitutions for standard boilerplate + subs = { + "standard_top_comment": "This file is generated by glib-genmarshal, do not modify " + "it. This code is licensed under the same license as the " + "containing project. Note that it links to GLib, so must " + "comply with the LGPL linking clauses.", + "standard_top_pragma": dedent( + """ + #ifndef __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ + #define __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ + """ + ).strip(), + "standard_bottom_pragma": dedent( + """ + #endif /* __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ */ + """ + ).strip(), + "standard_includes": dedent( + """ + #include + """ + ).strip(), + "standard_marshal_peek_defines": dedent( + """ + #ifdef G_ENABLE_DEBUG + #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) + #define g_marshal_value_peek_char(v) g_value_get_schar (v) + #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) + #define g_marshal_value_peek_int(v) g_value_get_int (v) + #define g_marshal_value_peek_uint(v) g_value_get_uint (v) + #define g_marshal_value_peek_long(v) g_value_get_long (v) + #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) + #define g_marshal_value_peek_int64(v) g_value_get_int64 (v) + #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) + #define g_marshal_value_peek_enum(v) g_value_get_enum (v) + #define g_marshal_value_peek_flags(v) g_value_get_flags (v) + #define g_marshal_value_peek_float(v) g_value_get_float (v) + #define g_marshal_value_peek_double(v) g_value_get_double (v) + #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) + #define g_marshal_value_peek_param(v) g_value_get_param (v) + #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) + #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) + #define g_marshal_value_peek_object(v) g_value_get_object (v) + #define g_marshal_value_peek_variant(v) g_value_get_variant (v) + #else /* !G_ENABLE_DEBUG */ + /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ + #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int + #define g_marshal_value_peek_char(v) (v)->data[0].v_int + #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint + #define g_marshal_value_peek_int(v) (v)->data[0].v_int + #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint + #define g_marshal_value_peek_long(v) (v)->data[0].v_long + #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong + #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 + #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 + #define g_marshal_value_peek_enum(v) (v)->data[0].v_long + #define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong + #define g_marshal_value_peek_float(v) (v)->data[0].v_float + #define g_marshal_value_peek_double(v) (v)->data[0].v_double + #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer + #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer + #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer + #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer + #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer + #define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer + #endif /* !G_ENABLE_DEBUG */ + """ + ).strip(), + } + + result = Result(info, out, err, subs) + + print("Output:", result.out) + return result + + def runGenmarshalWithList(self, list_contents, *args): + with tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, suffix=".list", delete=False + ) as list_file: + # Write out the list. + list_file.write(list_contents.encode("utf-8")) + print(list_file.name + ":", list_contents) + list_file.flush() + + header_result = self.runGenmarshal(list_file.name, "--header", *args) + body_result = self.runGenmarshal(list_file.name, "--body", *args) + + header_result.subs["list_path"] = list_file.name + body_result.subs["list_path"] = list_file.name + + return (header_result, body_result) + + def test_help(self): + """Test the --help argument.""" + result = self.runGenmarshal("--help") + self.assertIn("usage: glib-genmarshal", result.out) + + def test_no_args(self): + """Test running with no arguments at all.""" + result = self.runGenmarshal() + self.assertEqual("", result.err) + self.assertEqual("", result.out) + + def test_empty_list(self): + """Test running with an empty list.""" + (header_result, body_result) = self.runGenmarshalWithList("", "--quiet") + + self.assertEqual("", header_result.err) + self.assertEqual("", body_result.err) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_top_pragma} + + {standard_includes} + + G_BEGIN_DECLS + + + G_END_DECLS + + {standard_bottom_pragma} + """ + ) + .strip() + .format(**header_result.subs), + header_result.out.strip(), + ) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_includes} + + {standard_marshal_peek_defines} + """ + ) + .strip() + .format(**body_result.subs), + body_result.out.strip(), + ) + + def test_void_boolean(self): + """Test running with a basic VOID:BOOLEAN list.""" + (header_result, body_result) = self.runGenmarshalWithList( + "VOID:BOOLEAN", "--quiet" + ) + + self.assertEqual("", header_result.err) + self.assertEqual("", body_result.err) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_top_pragma} + + {standard_includes} + + G_BEGIN_DECLS + + /* VOID:BOOLEAN ({list_path}:1) */ + #define g_cclosure_user_marshal_VOID__BOOLEAN g_cclosure_marshal_VOID__BOOLEAN + + + G_END_DECLS + + {standard_bottom_pragma} + """ + ) + .strip() + .format(**header_result.subs), + header_result.out.strip(), + ) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_includes} + + {standard_marshal_peek_defines} + """ + ) + .strip() + .format(**body_result.subs), + body_result.out.strip(), + ) + + def test_void_boolean_int64(self): + """Test running with a non-trivial VOID:BOOLEAN,INT64 list.""" + (header_result, body_result) = self.runGenmarshalWithList( + "VOID:BOOLEAN,INT64", "--quiet" + ) + + self.assertEqual("", header_result.err) + self.assertEqual("", body_result.err) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_top_pragma} + + {standard_includes} + + G_BEGIN_DECLS + + /* VOID:BOOLEAN,INT64 ({list_path}:1) */ + extern + void g_cclosure_user_marshal_VOID__BOOLEAN_INT64 (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + + + G_END_DECLS + + {standard_bottom_pragma} + """ + ) + .strip() + .format(**header_result.subs), + header_result.out.strip(), + ) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_includes} + + {standard_marshal_peek_defines} + + /* VOID:BOOLEAN,INT64 ({list_path}:1) */ + void + g_cclosure_user_marshal_VOID__BOOLEAN_INT64 (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) + {{ + typedef void (*GMarshalFunc_VOID__BOOLEAN_INT64) (gpointer data1, + gboolean arg1, + gint64 arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__BOOLEAN_INT64 callback; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + {{ + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + }} + else + {{ + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + }} + callback = (GMarshalFunc_VOID__BOOLEAN_INT64) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_boolean (param_values + 1), + g_marshal_value_peek_int64 (param_values + 2), + data2); + }} + """ + ) + .strip() + .format(**body_result.subs), + body_result.out.strip(), + ) + + def test_void_variant_nostdinc_valist_marshaller(self): + """Test running with a basic VOID:VARIANT list, but without the + standard marshallers, and with valist support enabled. This checks that + the valist marshaller for VARIANT correctly sinks floating variants. + + See issue #1793. + """ + (header_result, body_result) = self.runGenmarshalWithList( + "VOID:VARIANT", "--quiet", "--nostdinc", "--valist-marshaller" + ) + + self.assertEqual("", header_result.err) + self.assertEqual("", body_result.err) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_top_pragma} + + G_BEGIN_DECLS + + /* VOID:VARIANT ({list_path}:1) */ + extern + void g_cclosure_user_marshal_VOID__VARIANT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + extern + void g_cclosure_user_marshal_VOID__VARIANTv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + + + G_END_DECLS + + {standard_bottom_pragma} + """ + ) + .strip() + .format(**header_result.subs), + header_result.out.strip(), + ) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_marshal_peek_defines} + + /* VOID:VARIANT ({list_path}:1) */ + void + g_cclosure_user_marshal_VOID__VARIANT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) + {{ + typedef void (*GMarshalFunc_VOID__VARIANT) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__VARIANT callback; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + {{ + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + }} + else + {{ + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + }} + callback = (GMarshalFunc_VOID__VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_variant (param_values + 1), + data2); + }} + + void + g_cclosure_user_marshal_VOID__VARIANTv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) + {{ + typedef void (*GMarshalFunc_VOID__VARIANT) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__VARIANT callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_variant_ref_sink (arg0); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + {{ + data1 = closure->data; + data2 = instance; + }} + else + {{ + data1 = instance; + data2 = closure->data; + }} + callback = (GMarshalFunc_VOID__VARIANT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_variant_unref (arg0); + }} + """ + ) + .strip() + .format(**body_result.subs), + body_result.out.strip(), + ) + + def test_void_string_nostdinc(self): + """Test running with a basic VOID:STRING list, but without the + standard marshallers, and with valist support enabled. This checks that + the valist marshaller for STRING correctly skips a string copy if the + argument is static. + + See issue #1792. + """ + (header_result, body_result) = self.runGenmarshalWithList( + "VOID:STRING", "--quiet", "--nostdinc", "--valist-marshaller" + ) + + self.assertEqual("", header_result.err) + self.assertEqual("", body_result.err) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_top_pragma} + + G_BEGIN_DECLS + + /* VOID:STRING ({list_path}:1) */ + extern + void g_cclosure_user_marshal_VOID__STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + extern + void g_cclosure_user_marshal_VOID__STRINGv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + + + G_END_DECLS + + {standard_bottom_pragma} + """ + ) + .strip() + .format(**header_result.subs), + header_result.out.strip(), + ) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_marshal_peek_defines} + + /* VOID:STRING ({list_path}:1) */ + void + g_cclosure_user_marshal_VOID__STRING (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) + {{ + typedef void (*GMarshalFunc_VOID__STRING) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING callback; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + {{ + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + }} + else + {{ + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + }} + callback = (GMarshalFunc_VOID__STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + data2); + }} + + void + g_cclosure_user_marshal_VOID__STRINGv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) + {{ + typedef void (*GMarshalFunc_VOID__STRING) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__STRING callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_strdup (arg0); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + {{ + data1 = closure->data; + data2 = instance; + }} + else + {{ + data1 = instance; + data2 = closure->data; + }} + callback = (GMarshalFunc_VOID__STRING) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_free (arg0); + }} + """ + ) + .strip() + .format(**body_result.subs), + body_result.out.strip(), + ) + + def test_void_param_nostdinc(self): + """Test running with a basic VOID:PARAM list, but without the + standard marshallers, and with valist support enabled. This checks that + the valist marshaller for PARAM correctly skips a param copy if the + argument is static. + + See issue #1792. + """ + self.maxDiff = None # TODO + (header_result, body_result) = self.runGenmarshalWithList( + "VOID:PARAM", "--quiet", "--nostdinc", "--valist-marshaller" + ) + + self.assertEqual("", header_result.err) + self.assertEqual("", body_result.err) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_top_pragma} + + G_BEGIN_DECLS + + /* VOID:PARAM ({list_path}:1) */ + extern + void g_cclosure_user_marshal_VOID__PARAM (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + extern + void g_cclosure_user_marshal_VOID__PARAMv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types); + + + G_END_DECLS + + {standard_bottom_pragma} + """ + ) + .strip() + .format(**header_result.subs), + header_result.out.strip(), + ) + + self.assertEqual( + dedent( + """ + /* {standard_top_comment} */ + {standard_marshal_peek_defines} + + /* VOID:PARAM ({list_path}:1) */ + void + g_cclosure_user_marshal_VOID__PARAM (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) + {{ + typedef void (*GMarshalFunc_VOID__PARAM) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__PARAM callback; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + {{ + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + }} + else + {{ + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + }} + callback = (GMarshalFunc_VOID__PARAM) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_param (param_values + 1), + data2); + }} + + void + g_cclosure_user_marshal_VOID__PARAMv (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) + {{ + typedef void (*GMarshalFunc_VOID__PARAM) (gpointer data1, + gpointer arg1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__PARAM callback; + gpointer arg0; + va_list args_copy; + + G_VA_COPY (args_copy, args); + arg0 = (gpointer) va_arg (args_copy, gpointer); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + arg0 = g_param_spec_ref (arg0); + va_end (args_copy); + + + if (G_CCLOSURE_SWAP_DATA (closure)) + {{ + data1 = closure->data; + data2 = instance; + }} + else + {{ + data1 = instance; + data2 = closure->data; + }} + callback = (GMarshalFunc_VOID__PARAM) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + arg0, + data2); + if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) + g_param_spec_unref (arg0); + }} + """ + ) + .strip() + .format(**body_result.subs), + body_result.out.strip(), + ) + + +if __name__ == "__main__": + unittest.main(testRunner=taptestrunner.TAPTestRunner()) diff --git a/gobject/tests/ifaceproperties.c b/gobject/tests/ifaceproperties.c new file mode 100644 index 0000000..cb7acf4 --- /dev/null +++ b/gobject/tests/ifaceproperties.c @@ -0,0 +1,645 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001, 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include +#include + +#include + +#include "testcommon.h" + +/* This test tests interface properties, implementing interface + * properties and #GParamSpecOverride. + * + * Four properties are tested: + * + * prop1: Defined in TestIface, Implemented in BaseObject with a GParamSpecOverride + * prop2: Defined in TestIface, Implemented in BaseObject with a new property + * prop3: Defined in TestIface, Implemented in BaseObject, Overridden in DerivedObject + * prop4: Defined in BaseObject, Overridden in DerivedObject + */ + +static GType base_object_get_type (void); +static GType derived_object_get_type (void); + +enum { + BASE_PROP_0, + BASE_PROP1, + BASE_PROP2, + BASE_PROP3, + BASE_PROP4 +}; + +enum { + DERIVED_PROP_0, + DERIVED_PROP3, + DERIVED_PROP4 +}; + +/* + * BaseObject, a parent class for DerivedObject + */ +#define BASE_TYPE_OBJECT (base_object_get_type ()) +#define BASE_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BASE_TYPE_OBJECT, BaseObject)) +typedef struct _BaseObject BaseObject; +typedef struct _BaseObjectClass BaseObjectClass; + +struct _BaseObject +{ + GObject parent_instance; + + gint val1; + gint val2; + gint val3; + gint val4; +}; +struct _BaseObjectClass +{ + GObjectClass parent_class; +}; + +GObjectClass *base_parent_class; + +/* + * DerivedObject, the child class of DerivedObject + */ +#define DERIVED_TYPE_OBJECT (derived_object_get_type ()) +typedef struct _DerivedObject DerivedObject; +typedef struct _DerivedObjectClass DerivedObjectClass; + +struct _DerivedObject +{ + BaseObject parent_instance; +}; +struct _DerivedObjectClass +{ + BaseObjectClass parent_class; +}; + +/* + * The interface + */ +typedef struct _TestIfaceClass TestIfaceClass; + +struct _TestIfaceClass +{ + GTypeInterface base_iface; +}; + +#define TEST_TYPE_IFACE (test_iface_get_type ()) + +/* The paramspecs installed on our interface + */ +static GParamSpec *iface_spec1, *iface_spec2, *iface_spec3; + +/* The paramspecs inherited by our derived object + */ +static GParamSpec *inherited_spec1, *inherited_spec2, *inherited_spec3, *inherited_spec4; + +static void +test_iface_default_init (TestIfaceClass *iface_vtable) +{ + inherited_spec1 = iface_spec1 = g_param_spec_int ("prop1", + "Prop1", + "Property 1", + G_MININT, /* min */ + 0xFFFF, /* max */ + 42, /* default */ + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + g_object_interface_install_property (iface_vtable, iface_spec1); + + iface_spec2 = g_param_spec_int ("prop2", + "Prop2", + "Property 2", + G_MININT, /* min */ + G_MAXINT, /* max */ + 0, /* default */ + G_PARAM_WRITABLE); + g_object_interface_install_property (iface_vtable, iface_spec2); + + inherited_spec3 = iface_spec3 = g_param_spec_int ("prop3", + "Prop3", + "Property 3", + G_MININT, /* min */ + G_MAXINT, /* max */ + 0, /* default */ + G_PARAM_READWRITE); + g_object_interface_install_property (iface_vtable, iface_spec3); +} + +static DEFINE_IFACE (TestIface, test_iface, NULL, test_iface_default_init) + + +static GObject* +base_object_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + /* The constructor is the one place where a GParamSpecOverride is visible + * to the outside world, so we do a bunch of checks here + */ + GValue value1 = G_VALUE_INIT; + GValue value2 = G_VALUE_INIT; + GParamSpec *pspec; + + g_assert (n_construct_properties == 1); + + pspec = construct_properties->pspec; + + /* Check we got the param spec we expected + */ + g_assert (G_IS_PARAM_SPEC_OVERRIDE (pspec)); + g_assert (pspec->param_id == BASE_PROP1); + g_assert (strcmp (g_param_spec_get_name (pspec), "prop1") == 0); + g_assert (g_param_spec_get_redirect_target (pspec) == iface_spec1); + + /* Test redirection of the nick and blurb to the redirect target + */ + g_assert (strcmp (g_param_spec_get_nick (pspec), "Prop1") == 0); + g_assert (strcmp (g_param_spec_get_blurb (pspec), "Property 1") == 0); + + /* Test forwarding of the various GParamSpec methods to the redirect target + */ + g_value_init (&value1, G_TYPE_INT); + g_value_init (&value2, G_TYPE_INT); + + g_param_value_set_default (pspec, &value1); + g_assert (g_value_get_int (&value1) == 42); + + g_value_reset (&value1); + g_value_set_int (&value1, 0x10000); + g_assert (g_param_value_validate (pspec, &value1)); + g_assert (g_value_get_int (&value1) == 0xFFFF); + g_assert (!g_param_value_validate (pspec, &value1)); + + g_value_reset (&value1); + g_value_set_int (&value1, 1); + g_value_set_int (&value2, 2); + g_assert (g_param_values_cmp (pspec, &value1, &value2) < 0); + g_assert (g_param_values_cmp (pspec, &value2, &value1) > 0); + + g_value_unset (&value1); + g_value_unset (&value2); + + return base_parent_class->constructor (type, + n_construct_properties, + construct_properties); +} + +static void +base_object_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BaseObject *base_object = BASE_OBJECT (object); + + switch (prop_id) + { + case BASE_PROP1: + g_assert (pspec == inherited_spec1); + base_object->val1 = g_value_get_int (value); + break; + case BASE_PROP2: + g_assert (pspec == inherited_spec2); + base_object->val2 = g_value_get_int (value); + break; + case BASE_PROP3: + g_assert_not_reached (); + break; + case BASE_PROP4: + g_assert_not_reached (); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +base_object_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BaseObject *base_object = BASE_OBJECT (object); + + switch (prop_id) + { + case BASE_PROP1: + g_assert (pspec == inherited_spec1); + g_value_set_int (value, base_object->val1); + break; + case BASE_PROP2: + g_assert (pspec == inherited_spec2); + g_value_set_int (value, base_object->val2); + break; + case BASE_PROP3: + g_assert_not_reached (); + break; + case BASE_PROP4: + g_assert_not_reached (); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +base_object_notify (GObject *object, + GParamSpec *pspec) +{ + /* The property passed to notify is the redirect target, not the + * GParamSpecOverride + */ + g_assert (pspec == inherited_spec1 || + pspec == inherited_spec2 || + pspec == inherited_spec3 || + pspec == inherited_spec4); +} + +static void +base_object_class_init (BaseObjectClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + base_parent_class= g_type_class_peek_parent (class); + + object_class->constructor = base_object_constructor; + object_class->set_property = base_object_set_property; + object_class->get_property = base_object_get_property; + object_class->notify = base_object_notify; + + g_object_class_override_property (object_class, BASE_PROP1, "prop1"); + + /* We override this one using a real property, not GParamSpecOverride + * We change the flags from READONLY to READWRITE to show that we + * can make the flags less restrictive + */ + inherited_spec2 = g_param_spec_int ("prop2", + "Prop2", + "Property 2", + G_MININT, /* min */ + G_MAXINT, /* max */ + 0, /* default */ + G_PARAM_READWRITE); + g_object_class_install_property (object_class, BASE_PROP2, inherited_spec2); + + g_object_class_override_property (object_class, BASE_PROP3, "prop3"); + + inherited_spec4 = g_param_spec_int ("prop4", + "Prop4", + "Property 4", + G_MININT, /* min */ + G_MAXINT, /* max */ + 0, /* default */ + G_PARAM_READWRITE); + g_object_class_install_property (object_class, BASE_PROP4, inherited_spec4); +} + +static void +base_object_init (BaseObject *base_object) +{ + base_object->val1 = 42; +} + +static DEFINE_TYPE_FULL (BaseObject, base_object, + base_object_class_init, NULL, base_object_init, + G_TYPE_OBJECT, + INTERFACE (NULL, TEST_TYPE_IFACE)) + +static void +derived_object_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BaseObject *base_object = BASE_OBJECT (object); + + switch (prop_id) + { + case DERIVED_PROP3: + g_assert (pspec == inherited_spec3); + base_object->val3 = g_value_get_int (value); + break; + case DERIVED_PROP4: + g_assert (pspec == inherited_spec4); + base_object->val4 = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +derived_object_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BaseObject *base_object = BASE_OBJECT (object); + + switch (prop_id) + { + case DERIVED_PROP3: + g_assert (pspec == inherited_spec3); + g_value_set_int (value, base_object->val3); + break; + case DERIVED_PROP4: + g_assert (pspec == inherited_spec4); + g_value_set_int (value, base_object->val4); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +derived_object_class_init (DerivedObjectClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->set_property = derived_object_set_property; + object_class->get_property = derived_object_get_property; + + /* Overriding a property that is itself overriding an interface property */ + g_object_class_override_property (object_class, DERIVED_PROP3, "prop3"); + + /* Overriding a property not from an interface */ + g_object_class_override_property (object_class, DERIVED_PROP4, "prop4"); +} + +static DEFINE_TYPE (DerivedObject, derived_object, + derived_object_class_init, NULL, NULL, + BASE_TYPE_OBJECT) + +/* Helper function for testing ...list_properties() */ +static void +assert_in_properties (GParamSpec *param_spec, + GParamSpec **properties, + gint n_properties) +{ + gint i; + gboolean found = FALSE; + + for (i = 0; i < n_properties; i++) + { + if (properties[i] == param_spec) + found = TRUE; + } + + g_assert (found); +} + +/* Test setting and getting the properties */ +static void +test_set (void) +{ + BaseObject *object; + gint val1, val2, val3, val4; + + object = g_object_new (DERIVED_TYPE_OBJECT, NULL); + + g_object_set (object, + "prop1", 0x0101, + "prop2", 0x0202, + "prop3", 0x0303, + "prop4", 0x0404, + NULL); + g_object_get (object, + "prop1", &val1, + "prop2", &val2, + "prop3", &val3, + "prop4", &val4, + NULL); + + g_assert (val1 == 0x0101); + g_assert (val2 == 0x0202); + g_assert (val3 == 0x0303); + g_assert (val4 == 0x0404); + + g_object_unref (object); +} + +/* Test that the right spec is passed on explicit notifications */ +static void +test_notify (void) +{ + BaseObject *object; + + object = g_object_new (DERIVED_TYPE_OBJECT, NULL); + + g_object_freeze_notify (G_OBJECT (object)); + g_object_notify (G_OBJECT (object), "prop1"); + g_object_notify (G_OBJECT (object), "prop2"); + g_object_notify (G_OBJECT (object), "prop3"); + g_object_notify (G_OBJECT (object), "prop4"); + g_object_thaw_notify (G_OBJECT (object)); + + g_object_unref (object); +} + +/* Test g_object_class_find_property() for overridden properties */ +static void +test_find_overridden (void) +{ + GObjectClass *object_class; + + object_class = g_type_class_peek (DERIVED_TYPE_OBJECT); + + g_assert (g_object_class_find_property (object_class, "prop1") == inherited_spec1); + g_assert (g_object_class_find_property (object_class, "prop2") == inherited_spec2); + g_assert (g_object_class_find_property (object_class, "prop3") == inherited_spec3); + g_assert (g_object_class_find_property (object_class, "prop4") == inherited_spec4); +} + +/* Test g_object_class_list_properties() for overridden properties */ +static void +test_list_overridden (void) +{ + GObjectClass *object_class; + GParamSpec **properties; + guint n_properties; + + object_class = g_type_class_peek (DERIVED_TYPE_OBJECT); + + properties = g_object_class_list_properties (object_class, &n_properties); + g_assert (n_properties == 4); + assert_in_properties (inherited_spec1, properties, n_properties); + assert_in_properties (inherited_spec2, properties, n_properties); + assert_in_properties (inherited_spec3, properties, n_properties); + assert_in_properties (inherited_spec4, properties, n_properties); + g_free (properties); +} + +/* Test g_object_interface_find_property() */ +static void +test_find_interface (void) +{ + TestIfaceClass *iface; + + iface = g_type_default_interface_peek (TEST_TYPE_IFACE); + + g_assert (g_object_interface_find_property (iface, "prop1") == iface_spec1); + g_assert (g_object_interface_find_property (iface, "prop2") == iface_spec2); + g_assert (g_object_interface_find_property (iface, "prop3") == iface_spec3); +} + +/* Test g_object_interface_list_properties() */ +static void +test_list_interface (void) +{ + TestIfaceClass *iface; + GParamSpec **properties; + guint n_properties; + + iface = g_type_default_interface_peek (TEST_TYPE_IFACE); + + properties = g_object_interface_list_properties (iface, &n_properties); + g_assert (n_properties == 3); + assert_in_properties (iface_spec1, properties, n_properties); + assert_in_properties (iface_spec2, properties, n_properties); + assert_in_properties (iface_spec3, properties, n_properties); + g_free (properties); +} + +/* Base2Object, which implements the interface but fails + * to override some of its properties + */ +#define BASE2_TYPE_OBJECT (base2_object_get_type ()) +#define BASE2_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BASE2_TYPE_OBJECT, Base2Object)) + +typedef struct _Base2Object Base2Object; +typedef struct _Base2ObjectClass Base2ObjectClass; + +static void +base2_object_test_iface_init (TestIfaceClass *iface) +{ +} + +enum { + BASE2_PROP_0, + BASE2_PROP1, + BASE2_PROP2 +}; + +struct _Base2Object +{ + GObject parent_instance; +}; + +struct _Base2ObjectClass +{ + GObjectClass parent_class; +}; + +static GType base2_object_get_type (void); +G_DEFINE_TYPE_WITH_CODE (Base2Object, base2_object, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE, + base2_object_test_iface_init)) + +static void +base2_object_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case BASE2_PROP1: + g_value_set_int (value, 0); + break; + case BASE2_PROP2: + g_value_set_int (value, 0); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +base2_object_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case BASE2_PROP1: + break; + case BASE2_PROP2: + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +base2_object_class_init (Base2ObjectClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->set_property = base2_object_set_property; + object_class->get_property = base2_object_get_property; + + g_object_class_override_property (object_class, BASE2_PROP1, "prop1"); + g_object_class_override_property (object_class, BASE2_PROP2, "prop2"); +} + +static void +base2_object_init (Base2Object *object) +{ +} + +static void +test_not_overridden (void) +{ + Base2Object *object; + + if (!g_test_undefined ()) + return; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=637738"); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*Base2Object doesn't implement property 'prop3' from interface 'TestIface'*"); + object = g_object_new (BASE2_TYPE_OBJECT, NULL); + g_test_assert_expected_messages (); + + g_object_unref (object); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/interface/properties/set", test_set); + g_test_add_func ("/interface/properties/notify", test_notify); + g_test_add_func ("/interface/properties/find-overridden", test_find_overridden); + g_test_add_func ("/interface/properties/list-overridden", test_list_overridden); + g_test_add_func ("/interface/properties/find-interface", test_find_interface); + g_test_add_func ("/interface/properties/list-interface", test_list_interface); + g_test_add_func ("/interface/properties/not-overridden", test_not_overridden); + + return g_test_run (); +} diff --git a/gobject/tests/marshalers.list b/gobject/tests/marshalers.list new file mode 100644 index 0000000..19167ea --- /dev/null +++ b/gobject/tests/marshalers.list @@ -0,0 +1,3 @@ +VOID:INT,BOOLEAN,CHAR,UCHAR,UINT,LONG,ULONG,ENUM,FLAGS,FLOAT,DOUBLE,STRING,PARAM,BOXED,POINTER,OBJECT,VARIANT,INT64,UINT64 +INT:VOID +UINT:VOID diff --git a/gobject/tests/meson.build b/gobject/tests/meson.build new file mode 100644 index 0000000..eb6a047 --- /dev/null +++ b/gobject/tests/meson.build @@ -0,0 +1,161 @@ +marshalers_h = custom_target('marshalers_h', + output : 'marshalers.h', + input : 'marshalers.list', + command : [ + python, glib_genmarshal, + '--prefix=test', + '--valist-marshallers', + '--output=@OUTPUT@', + '--quiet', + '--header', + '@INPUT@', + ], +) +marshalers_c = custom_target('marshalers_c', + output : 'marshalers.c', + input : 'marshalers.list', + command : [ + python, glib_genmarshal, + '--prefix=test', + '--valist-marshallers', + '--include-header=marshalers.h', + '--output=@OUTPUT@', + '--quiet', + '--body', + '@INPUT@', + ], +) + +gobject_tests = { + 'qdata' : {}, + 'boxed' : {}, + 'enums' : {}, + 'param' : {}, + 'threadtests' : {}, + 'dynamictests' : {}, + 'binding' : {}, + 'bindinggroup' : {}, + 'properties' : {}, + 'reference' : {}, + 'flags' : {}, + 'value' : {}, + 'type' : {}, + 'gobject-private' : { + 'source' : 'private.c', + }, + 'closure' : {}, + 'closure-refcount' : { 'suite': ['slow'] }, + 'object' : {}, + 'signal-handler' : {}, + 'ifaceproperties' : {}, + 'signals' : { + 'source' : ['signals.c', marshalers_h, marshalers_c], + }, + 'signalgroup' : {}, + 'testing' : {}, + 'type-flags' : {}, +} + +if have_cxx + gobject_tests += { + 'cxx' : { + 'source' : ['cxx.cpp'], + }, + } +endif + +if cc.get_id() != 'msvc' + gobject_tests += {'autoptr' : {}} +endif + +python_tests = [ + 'genmarshal.py', + 'mkenums.py', +] + +# FIXME: put common bits of test environment() in one location +# Not entirely random of course, but at least it changes over time +random_number = minor_version + meson.version().split('.').get(1).to_int() + +test_env = environment() +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +test_env.set('G_DEBUG', 'gc-friendly') +test_env.set('MALLOC_CHECK_', '2') +test_env.set('MALLOC_PERTURB_', '@0@'.format(random_number % 256)) + +test_deps = [libm, thread_dep, libglib_dep, libgobject_dep] +test_cargs = ['-DG_LOG_DOMAIN="GLib-GObject"', '-UG_DISABLE_ASSERT'] + +foreach test_name, extra_args : gobject_tests + source = extra_args.get('source', test_name + '.c') + install = installed_tests_enabled and extra_args.get('install', true) + + if install + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_conf.set('env', '') + configure_file( + input: installed_tests_template_tap, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf + ) + endif + + exe = executable(test_name, source, + c_args : test_cargs + extra_args.get('c_args', []), + dependencies : test_deps + extra_args.get('dependencies', []), + install_dir: installed_tests_execdir, + install: install, + ) + + suite = ['gobject'] + extra_args.get('suite', []) + timeout = suite.contains('slow') ? test_timeout_slow : test_timeout + + # FIXME: https://gitlab.gnome.org/GNOME/glib/issues/1316 + # aka https://bugs.debian.org/880883 + if test_name == 'closure-refcount' and ['arm', 'aarch64'].contains(host_machine.cpu_family()) + timeout = timeout * 10 + endif + + test(test_name, exe, env : test_env, timeout : timeout, suite : suite) +endforeach + +foreach test_name : python_tests + test( + test_name, + python, + args: ['-B', files(test_name)], + env: test_env, + suite: ['gobject', 'no-valgrind'], + ) + + if installed_tests_enabled + install_data( + files(test_name), + install_dir: installed_tests_execdir, + install_mode: 'rwxr-xr-x', + ) + + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_conf.set('env', '') + configure_file( + input: installed_tests_template_tap, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf, + ) + endif +endforeach + +# TAP test runner for Python tests +if installed_tests_enabled + install_data( + files('taptestrunner.py'), + install_dir: installed_tests_execdir, + ) +endif diff --git a/gobject/tests/mkenums.py b/gobject/tests/mkenums.py new file mode 100644 index 0000000..0d0c0d0 --- /dev/null +++ b/gobject/tests/mkenums.py @@ -0,0 +1,739 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# +# Copyright © 2018 Endless Mobile, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +"""Integration tests for glib-mkenums utility.""" + +import collections +import os +import shutil +import subprocess +import sys +import tempfile +import textwrap +import unittest + +import taptestrunner + + +Result = collections.namedtuple("Result", ("info", "out", "err", "subs")) + + +class TestMkenums(unittest.TestCase): + """Integration test for running glib-mkenums. + + This can be run when installed or uninstalled. When uninstalled, it + requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set. + + The idea with this test harness is to test the glib-mkenums utility, its + handling of command line arguments, its exit statuses, and its handling of + various C source codes. In future we could split the core glib-mkenums + parsing and generation code out into a library and unit test that, and + convert this test to just check command line behaviour. + """ + + # Track the cwd, we want to back out to that to clean up our tempdir + cwd = "" + rspfile = False + + def setUp(self): + self.timeout_seconds = 10 # seconds per test + self.tmpdir = tempfile.TemporaryDirectory() + self.cwd = os.getcwd() + os.chdir(self.tmpdir.name) + print("tmpdir:", self.tmpdir.name) + if "G_TEST_BUILDDIR" in os.environ: + self.__mkenums = os.path.join( + os.environ["G_TEST_BUILDDIR"], "..", "glib-mkenums" + ) + else: + self.__mkenums = shutil.which("glib-mkenums") + print("rspfile: {}, mkenums:".format(self.rspfile), self.__mkenums) + + def tearDown(self): + os.chdir(self.cwd) + self.tmpdir.cleanup() + + def _write_rspfile(self, argv): + import shlex + + with tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, mode="w", delete=False + ) as f: + contents = " ".join([shlex.quote(arg) for arg in argv]) + print("Response file contains:", contents) + f.write(contents) + f.flush() + return f.name + + def runMkenums(self, *args): + if self.rspfile: + rspfile = self._write_rspfile(args) + args = ["@" + rspfile] + argv = [self.__mkenums] + + # shebang lines are not supported on native + # Windows consoles + if os.name == "nt": + argv.insert(0, sys.executable) + + argv.extend(args) + print("Running:", argv) + + env = os.environ.copy() + env["LC_ALL"] = "C.UTF-8" + print("Environment:", env) + + # We want to ensure consistent line endings... + info = subprocess.run( + argv, + timeout=self.timeout_seconds, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + universal_newlines=True, + ) + info.check_returncode() + out = info.stdout.strip() + err = info.stderr.strip() + + # Known substitutions for standard boilerplate + subs = { + "standard_top_comment": "This file is generated by glib-mkenums, do not modify " + "it. This code is licensed under the same license as the " + "containing project. Note that it links to GLib, so must " + "comply with the LGPL linking clauses.", + "standard_bottom_comment": "Generated data ends here", + } + + result = Result(info, out, err, subs) + + print("Output:", result.out) + return result + + def runMkenumsWithTemplate(self, template_contents, *args): + with tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, suffix=".template", delete=False + ) as template_file: + # Write out the template. + template_file.write(template_contents.encode("utf-8")) + print(template_file.name + ":", template_contents) + template_file.flush() + + return self.runMkenums("--template", template_file.name, *args) + + def runMkenumsWithAllSubstitutions(self, *args): + """Run glib-mkenums with a template which outputs all substitutions.""" + template_contents = """ +/*** BEGIN file-header ***/ +file-header +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +file-production +filename: @filename@ +basename: @basename@ +/*** END file-production ***/ + +/*** BEGIN enumeration-production ***/ +enumeration-production +EnumName: @EnumName@ +enum_name: @enum_name@ +ENUMNAME: @ENUMNAME@ +ENUMSHORT: @ENUMSHORT@ +ENUMPREFIX: @ENUMPREFIX@ +enumsince: @enumsince@ +type: @type@ +Type: @Type@ +TYPE: @TYPE@ +/*** END enumeration-production ***/ + +/*** BEGIN value-header ***/ +value-header +EnumName: @EnumName@ +enum_name: @enum_name@ +ENUMNAME: @ENUMNAME@ +ENUMSHORT: @ENUMSHORT@ +ENUMPREFIX: @ENUMPREFIX@ +enumsince: @enumsince@ +type: @type@ +Type: @Type@ +TYPE: @TYPE@ +/*** END value-header ***/ + +/*** BEGIN value-production ***/ +value-production +VALUENAME: @VALUENAME@ +valuenick: @valuenick@ +valuenum: @valuenum@ +type: @type@ +Type: @Type@ +TYPE: @TYPE@ +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ +value-tail +EnumName: @EnumName@ +enum_name: @enum_name@ +ENUMNAME: @ENUMNAME@ +ENUMSHORT: @ENUMSHORT@ +ENUMPREFIX: @ENUMPREFIX@ +enumsince: @enumsince@ +type: @type@ +Type: @Type@ +TYPE: @TYPE@ +/*** END value-tail ***/ + +/*** BEGIN comment ***/ +comment +comment: @comment@ +/*** END comment ***/ + +/*** BEGIN file-tail ***/ +file-tail +/*** END file-tail ***/ +""" + return self.runMkenumsWithTemplate(template_contents, *args) + + def runMkenumsWithHeader(self, h_contents, encoding="utf-8"): + with tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, suffix=".h", delete=False + ) as h_file: + # Write out the header to be scanned. + h_file.write(h_contents.encode(encoding)) + print(h_file.name + ":", h_contents) + h_file.flush() + + # Run glib-mkenums with a template which outputs all substitutions. + result = self.runMkenumsWithAllSubstitutions(h_file.name) + + # Known substitutions for generated filenames. + result.subs.update( + {"filename": h_file.name, "basename": os.path.basename(h_file.name)} + ) + + return result + + def assertSingleEnum( + self, + result, + enum_name_camel, + enum_name_lower, + enum_name_upper, + enum_name_short, + enum_prefix, + enum_since, + type_lower, + type_camel, + type_upper, + value_name, + value_nick, + value_num, + ): + """Assert that out (from runMkenumsWithHeader()) contains a single + enum and value matching the given arguments.""" + subs = dict( + { + "enum_name_camel": enum_name_camel, + "enum_name_lower": enum_name_lower, + "enum_name_upper": enum_name_upper, + "enum_name_short": enum_name_short, + "enum_prefix": enum_prefix, + "enum_since": enum_since, + "type_lower": type_lower, + "type_camel": type_camel, + "type_upper": type_upper, + "value_name": value_name, + "value_nick": value_nick, + "value_num": value_num, + }, + **result.subs + ) + + self.assertEqual( + """ +comment +comment: {standard_top_comment} + + +file-header +file-production +filename: {filename} +basename: {basename} +enumeration-production +EnumName: {enum_name_camel} +enum_name: {enum_name_lower} +ENUMNAME: {enum_name_upper} +ENUMSHORT: {enum_name_short} +ENUMPREFIX: {enum_prefix} +enumsince: {enum_since} +type: {type_lower} +Type: {type_camel} +TYPE: {type_upper} +value-header +EnumName: {enum_name_camel} +enum_name: {enum_name_lower} +ENUMNAME: {enum_name_upper} +ENUMSHORT: {enum_name_short} +ENUMPREFIX: {enum_prefix} +enumsince: {enum_since} +type: {type_lower} +Type: {type_camel} +TYPE: {type_upper} +value-production +VALUENAME: {value_name} +valuenick: {value_nick} +valuenum: {value_num} +type: {type_lower} +Type: {type_camel} +TYPE: {type_upper} +value-tail +EnumName: {enum_name_camel} +enum_name: {enum_name_lower} +ENUMNAME: {enum_name_upper} +ENUMSHORT: {enum_name_short} +ENUMPREFIX: {enum_prefix} +enumsince: {enum_since} +type: {type_lower} +Type: {type_camel} +TYPE: {type_upper} +file-tail + +comment +comment: {standard_bottom_comment} +""".format( + **subs + ).strip(), + result.out, + ) + + def test_help(self): + """Test the --help argument.""" + result = self.runMkenums("--help") + self.assertIn("usage: glib-mkenums", result.out) + + def test_no_args(self): + """Test running with no arguments at all.""" + result = self.runMkenums() + self.assertEqual("", result.err) + self.assertEqual( + """/* {standard_top_comment} */ + + +/* {standard_bottom_comment} */""".format( + **result.subs + ), + result.out.strip(), + ) + + def test_empty_template(self): + """Test running with an empty template and no header files.""" + result = self.runMkenumsWithTemplate("") + self.assertEqual("", result.err) + self.assertEqual( + """/* {standard_top_comment} */ + + +/* {standard_bottom_comment} */""".format( + **result.subs + ), + result.out.strip(), + ) + + def test_no_headers(self): + """Test running with a complete template, but no header files.""" + result = self.runMkenumsWithAllSubstitutions() + self.assertEqual("", result.err) + self.assertEqual( + """ +comment +comment: {standard_top_comment} + + +file-header +file-tail + +comment +comment: {standard_bottom_comment} +""".format( + **result.subs + ).strip(), + result.out, + ) + + def test_empty_header(self): + """Test an empty header.""" + result = self.runMkenumsWithHeader("") + self.assertEqual("", result.err) + self.assertEqual( + """ +comment +comment: {standard_top_comment} + + +file-header +file-tail + +comment +comment: {standard_bottom_comment} +""".format( + **result.subs + ).strip(), + result.out, + ) + + def test_enum_name(self): + """Test typedefs with an enum and a typedef name. Bug #794506.""" + h_contents = """ + typedef enum _SomeEnumIdentifier { + ENUM_VALUE + } SomeEnumIdentifier; + """ + result = self.runMkenumsWithHeader(h_contents) + self.assertEqual("", result.err) + self.assertSingleEnum( + result, + "SomeEnumIdentifier", + "some_enum_identifier", + "SOME_ENUM_IDENTIFIER", + "ENUM_IDENTIFIER", + "SOME", + "", + "enum", + "Enum", + "ENUM", + "ENUM_VALUE", + "value", + "0", + ) + + def test_non_utf8_encoding(self): + """Test source files with non-UTF-8 encoding. Bug #785113.""" + h_contents = """ + /* Copyright © La Peña */ + typedef enum { + ENUM_VALUE + } SomeEnumIdentifier; + """ + result = self.runMkenumsWithHeader(h_contents, encoding="iso-8859-1") + self.assertIn("WARNING: UnicodeWarning: ", result.err) + self.assertSingleEnum( + result, + "SomeEnumIdentifier", + "some_enum_identifier", + "SOME_ENUM_IDENTIFIER", + "ENUM_IDENTIFIER", + "SOME", + "", + "enum", + "Enum", + "ENUM", + "ENUM_VALUE", + "value", + "0", + ) + + def test_reproducible(self): + """Test builds are reproducible regardless of file ordering. + Bug #691436.""" + template_contents = "template" + + h_contents1 = """ + typedef enum { + FIRST, + } Header1; + """ + + h_contents2 = """ + typedef enum { + SECOND, + } Header2; + """ + + with tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, suffix="1.h", delete=False + ) as h_file1, tempfile.NamedTemporaryFile( + dir=self.tmpdir.name, suffix="2.h", delete=False + ) as h_file2: + # Write out the headers. + h_file1.write(h_contents1.encode("utf-8")) + h_file2.write(h_contents2.encode("utf-8")) + + h_file1.flush() + h_file2.flush() + + # Run glib-mkenums with the headers in one order, and then again + # in another order. + result1 = self.runMkenumsWithTemplate( + template_contents, h_file1.name, h_file2.name + ) + self.assertEqual("", result1.err) + + result2 = self.runMkenumsWithTemplate( + template_contents, h_file2.name, h_file1.name + ) + self.assertEqual("", result2.err) + + # The output should be the same. + self.assertEqual(result1.out, result2.out) + + def test_no_nick(self): + """Test trigraphs with a desc but no nick. Issue #1360.""" + h_contents = """ + typedef enum { + GEGL_SAMPLER_NEAREST = 0, /*< desc="nearest" >*/ + } GeglSamplerType; + """ + result = self.runMkenumsWithHeader(h_contents) + self.assertEqual("", result.err) + self.assertSingleEnum( + result, + "GeglSamplerType", + "gegl_sampler_type", + "GEGL_SAMPLER_TYPE", + "SAMPLER_TYPE", + "GEGL", + "", + "enum", + "Enum", + "ENUM", + "GEGL_SAMPLER_NEAREST", + "nearest", + "0", + ) + + def test_filename_basename_in_fhead_ftail(self): + template_contents = """ +/*** BEGIN file-header ***/ +file-header +filename: @filename@ +basename: @basename@ +/*** END file-header ***/ + +/*** BEGIN comment ***/ +comment +comment: @comment@ +/*** END comment ***/ + +/*** BEGIN file-tail ***/ +file-tail +filename: @filename@ +basename: @basename@ +/*** END file-tail ***/""" + result = self.runMkenumsWithTemplate(template_contents) + self.assertEqual( + textwrap.dedent( + """ + WARNING: @filename@ used in file-header section. + WARNING: @basename@ used in file-header section. + WARNING: @filename@ used in file-tail section. + WARNING: @basename@ used in file-tail section. + """ + ).strip(), + result.err, + ) + self.assertEqual( + """ +comment +comment: {standard_top_comment} + + +file-header +filename: @filename@ +basename: @basename@ +file-tail +filename: @filename@ +basename: @basename@ + +comment +comment: {standard_bottom_comment} +""".format( + **result.subs + ).strip(), + result.out, + ) + + def test_since(self): + """Test user-provided 'since' version handling + https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1492""" + h_contents = """ + typedef enum { /*< since=1.0 >*/ + QMI_WMS_MESSAGE_PROTOCOL_CDMA = 0, + } QmiWmsMessageProtocol; + """ + result = self.runMkenumsWithHeader(h_contents) + self.assertEqual("", result.err) + self.assertSingleEnum( + result, + "QmiWmsMessageProtocol", + "qmi_wms_message_protocol", + "QMI_WMS_MESSAGE_PROTOCOL", + "WMS_MESSAGE_PROTOCOL", + "QMI", + "1.0", + "enum", + "Enum", + "ENUM", + "QMI_WMS_MESSAGE_PROTOCOL_CDMA", + "cdma", + "0", + ) + + def test_enum_private_public(self): + """Test private/public enums. Bug #782162.""" + h_contents1 = """ + typedef enum { + ENUM_VALUE_PUBLIC1, + /*< private >*/ + ENUM_VALUE_PRIVATE, + } SomeEnumA + """ + + h_contents2 = """ + typedef enum { + /*< private >*/ + ENUM_VALUE_PRIVATE, + /*< public >*/ + ENUM_VALUE_PUBLIC2, + } SomeEnumB; + """ + + result = self.runMkenumsWithHeader(h_contents1) + self.maxDiff = None + self.assertEqual("", result.err) + self.assertSingleEnum( + result, + "SomeEnumA", + "some_enum_a", + "SOME_ENUM_A", + "ENUM_A", + "SOME", + "", + "enum", + "Enum", + "ENUM", + "ENUM_VALUE_PUBLIC1", + "public1", + "0", + ) + result = self.runMkenumsWithHeader(h_contents2) + self.assertEqual("", result.err) + self.assertSingleEnum( + result, + "SomeEnumB", + "some_enum_b", + "SOME_ENUM_B", + "ENUM_B", + "SOME", + "", + "enum", + "Enum", + "ENUM", + "ENUM_VALUE_PUBLIC2", + "public2", + "0", + ) + + def test_available_in(self): + """Test GLIB_AVAILABLE_ENUMERATOR_IN_2_68 handling + https://gitlab.gnome.org/GNOME/glib/-/issues/2327""" + h_contents = """ + typedef enum { + G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_AVAILABLE_ENUMERATOR_IN_2_68 = (1<<2) + } GDBusServerFlags; + """ + result = self.runMkenumsWithHeader(h_contents) + self.assertEqual("", result.err) + self.assertSingleEnum( + result, + "GDBusServerFlags", + "g_dbus_server_flags", + "G_DBUS_SERVER_FLAGS", + "DBUS_SERVER_FLAGS", + "G", + "", + "flags", + "Flags", + "FLAGS", + "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER", + "user", + "4", + ) + + def test_deprecated_in(self): + """Test GLIB_DEPRECATED_ENUMERATOR_IN_2_68 handling + https://gitlab.gnome.org/GNOME/glib/-/issues/2327""" + h_contents = """ + typedef enum { + G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_DEPRECATED_ENUMERATOR_IN_2_68 = (1<<2) + } GDBusServerFlags; + """ + result = self.runMkenumsWithHeader(h_contents) + self.assertEqual("", result.err) + self.assertSingleEnum( + result, + "GDBusServerFlags", + "g_dbus_server_flags", + "G_DBUS_SERVER_FLAGS", + "DBUS_SERVER_FLAGS", + "G", + "", + "flags", + "Flags", + "FLAGS", + "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER", + "user", + "4", + ) + + def test_deprecated_in_for(self): + """Test GLIB_DEPRECATED_ENUMERATOR_IN_2_68_FOR() handling + https://gitlab.gnome.org/GNOME/glib/-/issues/2327""" + h_contents = """ + typedef enum { + G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER GLIB_DEPRECATED_ENUMERATOR_IN_2_68_FOR(G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER2) = (1<<2) + } GDBusServerFlags; + """ + result = self.runMkenumsWithHeader(h_contents) + self.assertEqual("", result.err) + self.assertSingleEnum( + result, + "GDBusServerFlags", + "g_dbus_server_flags", + "G_DBUS_SERVER_FLAGS", + "DBUS_SERVER_FLAGS", + "G", + "", + "flags", + "Flags", + "FLAGS", + "G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER", + "user", + "4", + ) + + +class TestRspMkenums(TestMkenums): + """Run all tests again in @rspfile mode""" + + rspfile = True + + +if __name__ == "__main__": + unittest.main(testRunner=taptestrunner.TAPTestRunner()) diff --git a/gobject/tests/object.c b/gobject/tests/object.c new file mode 100644 index 0000000..2519b00 --- /dev/null +++ b/gobject/tests/object.c @@ -0,0 +1,150 @@ +#include + +/* --------------------------------- */ +/* test_object_constructor_singleton */ + +typedef GObject MySingletonObject; +typedef GObjectClass MySingletonObjectClass; + +GType my_singleton_object_get_type (void); + +G_DEFINE_TYPE (MySingletonObject, my_singleton_object, G_TYPE_OBJECT) + +static MySingletonObject *singleton; + +static void +my_singleton_object_init (MySingletonObject *obj) +{ +} + +static GObject * +my_singleton_object_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + + if (singleton) + return g_object_ref (singleton); + + object = G_OBJECT_CLASS (my_singleton_object_parent_class)-> + constructor (type, n_construct_properties, construct_params); + singleton = (MySingletonObject *)object; + + return object; +} + +static void +my_singleton_object_finalize (MySingletonObject *obj) +{ + singleton = NULL; + + G_OBJECT_CLASS (my_singleton_object_parent_class)->finalize (obj); +} + +static void +my_singleton_object_class_init (MySingletonObjectClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructor = my_singleton_object_constructor; + object_class->finalize = my_singleton_object_finalize; +} + +static void +test_object_constructor_singleton (void) +{ + MySingletonObject *one, *two, *three; + + one = g_object_new (my_singleton_object_get_type (), NULL); + g_assert_cmpint (G_OBJECT (one)->ref_count, ==, 1); + + two = g_object_new (my_singleton_object_get_type (), NULL); + g_assert (one == two); + g_assert_cmpint (G_OBJECT (two)->ref_count, ==, 2); + + three = g_object_new (my_singleton_object_get_type (), NULL); + g_assert (one == three); + g_assert_cmpint (G_OBJECT (three)->ref_count, ==, 3); + + g_object_add_weak_pointer (G_OBJECT (one), (gpointer *)&one); + + g_object_unref (one); + g_assert (one != NULL); + + g_object_unref (three); + g_object_unref (two); + + g_assert (one == NULL); +} + +/* ----------------------------------- */ +/* test_object_constructor_infanticide */ + +typedef GObject MyInfanticideObject; +typedef GObjectClass MyInfanticideObjectClass; + +GType my_infanticide_object_get_type (void); + +G_DEFINE_TYPE (MyInfanticideObject, my_infanticide_object, G_TYPE_OBJECT) + +static void +my_infanticide_object_init (MyInfanticideObject *obj) +{ +} + +static GObject * +my_infanticide_object_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + + object = G_OBJECT_CLASS (my_infanticide_object_parent_class)-> + constructor (type, n_construct_properties, construct_params); + + g_object_unref (object); + + return NULL; +} + +static void +my_infanticide_object_class_init (MyInfanticideObjectClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructor = my_infanticide_object_constructor; +} + +static void +test_object_constructor_infanticide (void) +{ + GObject *obj; + int i; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=661576"); + + for (i = 0; i < 1000; i++) + { + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL, + "*finalized while still in-construction*"); + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL, + "*Custom constructor*returned NULL*"); + obj = g_object_new (my_infanticide_object_get_type (), NULL); + g_assert_null (obj); + g_test_assert_expected_messages (); + } +} + +/* --------------------------------- */ + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/object/constructor/singleton", test_object_constructor_singleton); + g_test_add_func ("/object/constructor/infanticide", test_object_constructor_infanticide); + + return g_test_run (); +} diff --git a/gobject/tests/param.c b/gobject/tests/param.c new file mode 100644 index 0000000..692f07d --- /dev/null +++ b/gobject/tests/param.c @@ -0,0 +1,1266 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include +#include + +static void +test_param_spec_char (void) +{ + GParamSpec *pspec; + GValue value = G_VALUE_INIT; + + pspec = g_param_spec_char ("char", "nick", "blurb", + 20, 40, 30, G_PARAM_READWRITE); + + g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "char"); + g_assert_cmpstr (g_param_spec_get_nick (pspec), ==, "nick"); + g_assert_cmpstr (g_param_spec_get_blurb (pspec), ==, "blurb"); + + g_value_init (&value, G_TYPE_CHAR); + g_value_set_char (&value, 30); + + g_assert_true (g_param_value_defaults (pspec, &value)); + + g_value_set_char (&value, 0); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_char (&value), ==, 20); + + g_value_set_char (&value, 20); + g_assert_false (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_char (&value), ==, 20); + + g_value_set_char (&value, 40); + g_assert_false (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_char (&value), ==, 40); + + g_value_set_char (&value, 60); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_char (&value), ==, 40); + + g_value_set_schar (&value, 0); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_schar (&value), ==, 20); + + g_value_set_schar (&value, 20); + g_assert_false (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_schar (&value), ==, 20); + + g_value_set_schar (&value, 40); + g_assert_false (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_schar (&value), ==, 40); + + g_value_set_schar (&value, 60); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_schar (&value), ==, 40); + + g_param_spec_unref (pspec); +} + +static void +test_param_spec_string (void) +{ + GParamSpec *pspec; + GValue value = G_VALUE_INIT; + + pspec = g_param_spec_string ("string", "nick", "blurb", + NULL, G_PARAM_READWRITE); + g_value_init (&value, G_TYPE_STRING); + + g_value_set_string (&value, "foobar"); + g_assert_false (g_param_value_validate (pspec, &value)); + + g_value_set_string (&value, ""); + g_assert_false (g_param_value_validate (pspec, &value)); + g_assert_nonnull (g_value_get_string (&value)); + + /* test ensure_non_null */ + + G_PARAM_SPEC_STRING (pspec)->ensure_non_null = TRUE; + + g_value_set_string (&value, NULL); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_nonnull (g_value_get_string (&value)); + + G_PARAM_SPEC_STRING (pspec)->ensure_non_null = FALSE; + + /* test null_fold_if_empty */ + + G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = TRUE; + + g_value_set_string (&value, ""); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_null (g_value_get_string (&value)); + + g_value_set_static_string (&value, ""); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_null (g_value_get_string (&value)); + + G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = FALSE; + + /* test cset_first */ + + G_PARAM_SPEC_STRING (pspec)->cset_first = g_strdup ("abc"); + G_PARAM_SPEC_STRING (pspec)->substitutor = '-'; + + g_value_set_string (&value, "ABC"); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_string (&value)[0], ==, '-'); + + g_value_set_static_string (&value, "ABC"); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_string (&value)[0], ==, '-'); + + /* test cset_nth */ + + G_PARAM_SPEC_STRING (pspec)->cset_nth = g_strdup ("abc"); + + g_value_set_string (&value, "aBC"); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_string (&value)[1], ==, '-'); + + g_value_set_static_string (&value, "aBC"); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_string (&value)[1], ==, '-'); + + g_value_unset (&value); + g_param_spec_unref (pspec); +} + +static void +test_param_spec_override (void) +{ + GParamSpec *ospec, *pspec; + GValue value = G_VALUE_INIT; + + ospec = g_param_spec_char ("char", "nick", "blurb", + 20, 40, 30, G_PARAM_READWRITE); + + pspec = g_param_spec_override ("override", ospec); + + g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "override"); + g_assert_cmpstr (g_param_spec_get_nick (pspec), ==, "nick"); + g_assert_cmpstr (g_param_spec_get_blurb (pspec), ==, "blurb"); + + g_value_init (&value, G_TYPE_CHAR); + g_value_set_char (&value, 30); + + g_assert_true (g_param_value_defaults (pspec, &value)); + + g_value_set_char (&value, 0); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_char (&value), ==, 20); + + g_value_set_char (&value, 20); + g_assert_false (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_char (&value), ==, 20); + + g_value_set_char (&value, 40); + g_assert_false (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_char (&value), ==, 40); + + g_value_set_char (&value, 60); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_char (&value), ==, 40); + + g_param_spec_unref (pspec); + g_param_spec_unref (ospec); +} + +static void +test_param_spec_gtype (void) +{ + GParamSpec *pspec; + GValue value = G_VALUE_INIT; + + pspec = g_param_spec_gtype ("gtype", "nick", "blurb", + G_TYPE_PARAM, G_PARAM_READWRITE); + + g_value_init (&value, G_TYPE_GTYPE); + g_value_set_gtype (&value, G_TYPE_PARAM); + + g_assert_true (g_param_value_defaults (pspec, &value)); + + g_value_set_gtype (&value, G_TYPE_INT); + g_assert_true (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_gtype (&value), ==, G_TYPE_PARAM); + + g_value_set_gtype (&value, G_TYPE_PARAM_INT); + g_assert_false (g_param_value_validate (pspec, &value)); + g_assert_cmpint (g_value_get_gtype (&value), ==, G_TYPE_PARAM_INT); + + g_param_spec_unref (pspec); +} + +static void +test_param_spec_variant (void) +{ + GParamSpec *pspec; + GValue value = G_VALUE_INIT; + GValue value2 = G_VALUE_INIT; + GValue value3 = G_VALUE_INIT; + GValue value4 = G_VALUE_INIT; + GValue value5 = G_VALUE_INIT; + gboolean modified; + + pspec = g_param_spec_variant ("variant", "nick", "blurb", + G_VARIANT_TYPE ("i"), + g_variant_new_int32 (42), + G_PARAM_READWRITE); + + g_value_init (&value, G_TYPE_VARIANT); + g_value_set_variant (&value, g_variant_new_int32 (42)); + + g_value_init (&value2, G_TYPE_VARIANT); + g_value_set_variant (&value2, g_variant_new_int32 (43)); + + g_value_init (&value3, G_TYPE_VARIANT); + g_value_set_variant (&value3, g_variant_new_int16 (42)); + + g_value_init (&value4, G_TYPE_VARIANT); + g_value_set_variant (&value4, g_variant_new_parsed ("[@u 15, @u 10]")); + + g_value_init (&value5, G_TYPE_VARIANT); + g_value_set_variant (&value5, NULL); + + g_assert_true (g_param_value_defaults (pspec, &value)); + g_assert_false (g_param_value_defaults (pspec, &value2)); + g_assert_false (g_param_value_defaults (pspec, &value3)); + g_assert_false (g_param_value_defaults (pspec, &value4)); + g_assert_false (g_param_value_defaults (pspec, &value5)); + + modified = g_param_value_validate (pspec, &value); + g_assert_false (modified); + + g_value_reset (&value); + g_value_set_variant (&value, g_variant_new_uint32 (41)); + modified = g_param_value_validate (pspec, &value); + g_assert_true (modified); + g_assert_cmpint (g_variant_get_int32 (g_value_get_variant (&value)), ==, 42); + g_value_unset (&value); + + g_value_unset (&value5); + g_value_unset (&value4); + g_value_unset (&value3); + g_value_unset (&value2); + + g_param_spec_unref (pspec); +} + +/* Test g_param_values_cmp() for #GParamSpecVariant. */ +static void +test_param_spec_variant_cmp (void) +{ + const struct + { + const GVariantType *pspec_type; + const gchar *v1; + enum + { + LESS_THAN = -1, + EQUAL = 0, + GREATER_THAN = 1, + NOT_EQUAL, + } expected_result; + const gchar *v2; + } + vectors[] = + { + { G_VARIANT_TYPE ("i"), "@i 1", LESS_THAN, "@i 2" }, + { G_VARIANT_TYPE ("i"), "@i 2", EQUAL, "@i 2" }, + { G_VARIANT_TYPE ("i"), "@i 3", GREATER_THAN, "@i 2" }, + { G_VARIANT_TYPE ("i"), NULL, LESS_THAN, "@i 2" }, + { G_VARIANT_TYPE ("i"), NULL, EQUAL, NULL }, + { G_VARIANT_TYPE ("i"), "@i 1", GREATER_THAN, NULL }, + { G_VARIANT_TYPE ("i"), "@u 1", LESS_THAN, "@u 2" }, + { G_VARIANT_TYPE ("i"), "@as ['hi']", NOT_EQUAL, "@u 2" }, + { G_VARIANT_TYPE ("i"), "@as ['hi']", NOT_EQUAL, "@as ['there']" }, + { G_VARIANT_TYPE ("i"), "@as ['hi']", EQUAL, "@as ['hi']" }, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + GParamSpec *pspec; + GValue v1 = G_VALUE_INIT; + GValue v2 = G_VALUE_INIT; + gint cmp; + + pspec = g_param_spec_variant ("variant", "nick", "blurb", + vectors[i].pspec_type, + NULL, + G_PARAM_READWRITE); + + g_value_init (&v1, G_TYPE_VARIANT); + g_value_set_variant (&v1, + (vectors[i].v1 != NULL) ? + g_variant_new_parsed (vectors[i].v1) : NULL); + + g_value_init (&v2, G_TYPE_VARIANT); + g_value_set_variant (&v2, + (vectors[i].v2 != NULL) ? + g_variant_new_parsed (vectors[i].v2) : NULL); + + cmp = g_param_values_cmp (pspec, &v1, &v2); + + switch (vectors[i].expected_result) + { + case LESS_THAN: + case EQUAL: + case GREATER_THAN: + g_assert_cmpint (cmp, ==, vectors[i].expected_result); + break; + case NOT_EQUAL: + g_assert_cmpint (cmp, !=, 0); + break; + default: + g_assert_not_reached (); + } + + g_value_unset (&v2); + g_value_unset (&v1); + g_param_spec_unref (pspec); + } +} + +static void +test_param_value (void) +{ + GParamSpec *p, *p2; + GParamSpec *pp; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_PARAM); + g_assert_true (G_VALUE_HOLDS_PARAM (&value)); + + p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE); + + g_value_take_param (&value, p); + p2 = g_value_get_param (&value); + g_assert_true (p2 == p); + + pp = g_param_spec_uint ("my-uint", "My UInt", "Blurb", 0, 10, 5, G_PARAM_READWRITE); + g_value_set_param (&value, pp); + + p2 = g_value_dup_param (&value); + g_assert_true (p2 == pp); /* param specs use ref/unref for copy/free */ + g_param_spec_unref (p2); + + g_value_unset (&value); + g_param_spec_unref (pp); +} + +static gint destroy_count; + +static void +my_destroy (gpointer data) +{ + destroy_count++; +} + +static void +test_param_qdata (void) +{ + GParamSpec *p; + gchar *bla; + GQuark q; + + q = g_quark_from_string ("bla"); + + p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE); + g_param_spec_set_qdata (p, q, "bla"); + bla = g_param_spec_get_qdata (p, q); + g_assert_cmpstr (bla, ==, "bla"); + + g_assert_cmpint (destroy_count, ==, 0); + g_param_spec_set_qdata_full (p, q, "bla", my_destroy); + g_param_spec_set_qdata_full (p, q, "blabla", my_destroy); + g_assert_cmpint (destroy_count, ==, 1); + g_assert_cmpstr (g_param_spec_steal_qdata (p, q), ==, "blabla"); + g_assert_cmpint (destroy_count, ==, 1); + g_assert_null (g_param_spec_get_qdata (p, q)); + + g_param_spec_ref_sink (p); + + g_param_spec_unref (p); +} + +static void +test_param_validate (void) +{ + GParamSpec *p; + GValue value = G_VALUE_INIT; + + p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE); + + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, 100); + g_assert_false (g_param_value_defaults (p, &value)); + g_assert_true (g_param_value_validate (p, &value)); + g_assert_cmpint (g_value_get_int (&value), ==, 20); + + g_param_value_set_default (p, &value); + g_assert_true (g_param_value_defaults (p, &value)); + g_assert_cmpint (g_value_get_int (&value), ==, 10); + + g_param_spec_unref (p); +} + +static void +test_param_strings (void) +{ + GParamSpec *p; + + /* test canonicalization */ + p = g_param_spec_int ("my_int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE); + + g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int"); + g_assert_cmpstr (g_param_spec_get_nick (p), ==, "My Int"); + g_assert_cmpstr (g_param_spec_get_blurb (p), ==, "Blurb"); + + g_param_spec_unref (p); + + /* test nick defaults to name */ + p = g_param_spec_int ("my-int", NULL, NULL, 0, 20, 10, G_PARAM_READWRITE); + + g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int"); + g_assert_cmpstr (g_param_spec_get_nick (p), ==, "my-int"); + g_assert_null (g_param_spec_get_blurb (p)); + + g_param_spec_unref (p); +} + +static void +test_param_invalid_name (gconstpointer test_data) +{ + const gchar *invalid_name = test_data; + + g_test_summary ("Test that properties cannot be created with invalid names"); + + if (g_test_subprocess ()) + { + GParamSpec *p; + p = g_param_spec_int (invalid_name, "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE); + g_param_spec_unref (p); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*g_param_spec_is_valid_name (name)*"); +} + +static void +test_param_convert (void) +{ + GParamSpec *p; + GValue v1 = G_VALUE_INIT; + GValue v2 = G_VALUE_INIT; + + p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE); + g_value_init (&v1, G_TYPE_UINT); + g_value_set_uint (&v1, 43); + + g_value_init (&v2, G_TYPE_INT); + g_value_set_int (&v2, -4); + + g_assert_false (g_param_value_convert (p, &v1, &v2, TRUE)); + g_assert_cmpint (g_value_get_int (&v2), ==, -4); + + g_assert_true (g_param_value_convert (p, &v1, &v2, FALSE)); + g_assert_cmpint (g_value_get_int (&v2), ==, 20); + + g_param_spec_unref (p); +} + +static void +test_value_transform (void) +{ + GValue src = G_VALUE_INIT; + GValue dest = G_VALUE_INIT; + +#define CHECK_INT_CONVERSION(type, getter, value) \ + g_assert_true (g_value_type_transformable (G_TYPE_INT, type)); \ + g_value_init (&src, G_TYPE_INT); \ + g_value_init (&dest, type); \ + g_value_set_int (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + /* Keep a check for an integer in the range of 0-127 so we're + * still testing g_value_get_char(). See + * https://bugzilla.gnome.org/show_bug.cgi?id=659870 + * for why it is broken. + */ + CHECK_INT_CONVERSION(G_TYPE_CHAR, char, 124) + + CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, -124) + CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, 124) + CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 0) + CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 255) + CHECK_INT_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_INT_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 0) + CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_INT_CONVERSION(G_TYPE_LONG, long, -12345678) + CHECK_INT_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_INT_CONVERSION(G_TYPE_INT64, int64, -12345678) + CHECK_INT_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_INT_CONVERSION(G_TYPE_FLOAT, float, 12345678) + CHECK_INT_CONVERSION(G_TYPE_DOUBLE, double, 12345678) + +#define CHECK_UINT_CONVERSION(type, getter, value) \ + g_assert_true (g_value_type_transformable (G_TYPE_UINT, type)); \ + g_value_init (&src, G_TYPE_UINT); \ + g_value_init (&dest, type); \ + g_value_set_uint (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124) + CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124) + CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 0) + CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 255) + CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 0) + CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_UINT_CONVERSION(G_TYPE_LONG, long, 12345678) + CHECK_UINT_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_UINT_CONVERSION(G_TYPE_INT64, int64, 12345678) + CHECK_UINT_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_UINT_CONVERSION(G_TYPE_FLOAT, float, 12345678) + CHECK_UINT_CONVERSION(G_TYPE_DOUBLE, double, 12345678) + +#define CHECK_LONG_CONVERSION(type, getter, value) \ + g_assert_true (g_value_type_transformable (G_TYPE_LONG, type)); \ + g_value_init (&src, G_TYPE_LONG); \ + g_value_init (&dest, type); \ + g_value_set_long (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, -124) + CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, 124) + CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 0) + CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 255) + CHECK_LONG_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_LONG_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 0) + CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_LONG_CONVERSION(G_TYPE_LONG, long, -12345678) + CHECK_LONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_LONG_CONVERSION(G_TYPE_INT64, int64, -12345678) + CHECK_LONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_LONG_CONVERSION(G_TYPE_FLOAT, float, 12345678) + CHECK_LONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678) + +#define CHECK_ULONG_CONVERSION(type, getter, value) \ + g_assert_true (g_value_type_transformable (G_TYPE_ULONG, type)); \ + g_value_init (&src, G_TYPE_ULONG); \ + g_value_init (&dest, type); \ + g_value_set_ulong (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124) + CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124) + CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 0) + CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 255) + CHECK_ULONG_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_ULONG_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 0) + CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_ULONG_CONVERSION(G_TYPE_LONG, long, 12345678) + CHECK_ULONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_ULONG_CONVERSION(G_TYPE_INT64, int64, 12345678) + CHECK_ULONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_ULONG_CONVERSION(G_TYPE_FLOAT, float, 12345678) + CHECK_ULONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678) + +#define CHECK_INT64_CONVERSION(type, getter, value) \ + g_assert_true (g_value_type_transformable (G_TYPE_INT64, type)); \ + g_value_init (&src, G_TYPE_INT64); \ + g_value_init (&dest, type); \ + g_value_set_int64 (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, -124) + CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, 124) + CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 0) + CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 255) + CHECK_INT64_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_INT64_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 0) + CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_INT64_CONVERSION(G_TYPE_LONG, long, -12345678) + CHECK_INT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_INT64_CONVERSION(G_TYPE_INT64, int64, -12345678) + CHECK_INT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_INT64_CONVERSION(G_TYPE_FLOAT, float, 12345678) + CHECK_INT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678) + +#define CHECK_UINT64_CONVERSION(type, getter, value) \ + g_assert_true (g_value_type_transformable (G_TYPE_UINT64, type)); \ + g_value_init (&src, G_TYPE_UINT64); \ + g_value_init (&dest, type); \ + g_value_set_uint64 (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, -124) + CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, 124) + CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 0) + CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 255) + CHECK_UINT64_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_UINT64_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 0) + CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_UINT64_CONVERSION(G_TYPE_LONG, long, -12345678) + CHECK_UINT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_UINT64_CONVERSION(G_TYPE_INT64, int64, -12345678) + CHECK_UINT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_UINT64_CONVERSION(G_TYPE_FLOAT, float, 12345678) + CHECK_UINT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678) + +#define CHECK_FLOAT_CONVERSION(type, getter, value) \ + g_assert_true (g_value_type_transformable (G_TYPE_FLOAT, type)); \ + g_value_init (&src, G_TYPE_FLOAT); \ + g_value_init (&dest, type); \ + g_value_set_float (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, -124) + CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, 124) + CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 0) + CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 255) + CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 0) + CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_FLOAT_CONVERSION(G_TYPE_LONG, long, -12345678) + CHECK_FLOAT_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_FLOAT_CONVERSION(G_TYPE_INT64, int64, -12345678) + CHECK_FLOAT_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_FLOAT_CONVERSION(G_TYPE_FLOAT, float, 12345678) + CHECK_FLOAT_CONVERSION(G_TYPE_DOUBLE, double, 12345678) + +#define CHECK_DOUBLE_CONVERSION(type, getter, value) \ + g_assert_true (g_value_type_transformable (G_TYPE_DOUBLE, type)); \ + g_value_init (&src, G_TYPE_DOUBLE); \ + g_value_init (&dest, type); \ + g_value_set_double (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, -124) + CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, 124) + CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 0) + CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 255) + CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, 12345) + CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 0) + CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_DOUBLE_CONVERSION(G_TYPE_LONG, long, -12345678) + CHECK_DOUBLE_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_DOUBLE_CONVERSION(G_TYPE_INT64, int64, -12345678) + CHECK_DOUBLE_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_DOUBLE_CONVERSION(G_TYPE_FLOAT, float, 12345678) + CHECK_DOUBLE_CONVERSION(G_TYPE_DOUBLE, double, 12345678) + +#define CHECK_BOOLEAN_CONVERSION(type, setter, value) \ + g_assert_true (g_value_type_transformable (type, G_TYPE_BOOLEAN)); \ + g_value_init (&src, type); \ + g_value_init (&dest, G_TYPE_BOOLEAN); \ + g_value_set_##setter (&src, value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpint (g_value_get_boolean (&dest), ==, TRUE); \ + g_value_set_##setter (&src, 0); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpint (g_value_get_boolean (&dest), ==, FALSE); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_BOOLEAN_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_BOOLEAN_CONVERSION(G_TYPE_LONG, long, -12345678) + CHECK_BOOLEAN_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_BOOLEAN_CONVERSION(G_TYPE_INT64, int64, -12345678) + CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + +#define CHECK_STRING_CONVERSION(int_type, setter, int_value) \ + g_assert_true (g_value_type_transformable (int_type, G_TYPE_STRING)); \ + g_value_init (&src, int_type); \ + g_value_init (&dest, G_TYPE_STRING); \ + g_value_set_##setter (&src, int_value); \ + g_assert_true (g_value_transform (&src, &dest)); \ + g_assert_cmpstr (g_value_get_string (&dest), ==, #int_value); \ + g_value_unset (&src); \ + g_value_unset (&dest); + + CHECK_STRING_CONVERSION(G_TYPE_INT, int, -12345) + CHECK_STRING_CONVERSION(G_TYPE_UINT, uint, 12345) + CHECK_STRING_CONVERSION(G_TYPE_LONG, long, -12345678) + CHECK_STRING_CONVERSION(G_TYPE_ULONG, ulong, 12345678) + CHECK_STRING_CONVERSION(G_TYPE_INT64, int64, -12345678) + CHECK_STRING_CONVERSION(G_TYPE_UINT64, uint64, 12345678) + CHECK_STRING_CONVERSION(G_TYPE_FLOAT, float, 0.500000) + CHECK_STRING_CONVERSION(G_TYPE_DOUBLE, double, -1.234567) + + g_assert_false (g_value_type_transformable (G_TYPE_STRING, G_TYPE_CHAR)); + g_value_init (&src, G_TYPE_STRING); + g_value_init (&dest, G_TYPE_CHAR); + g_value_set_static_string (&src, "bla"); + g_value_set_schar (&dest, 'c'); + g_assert_false (g_value_transform (&src, &dest)); + g_assert_cmpint (g_value_get_schar (&dest), ==, 'c'); + g_value_unset (&src); + g_value_unset (&dest); +} + + +/* We create some dummy objects with a simple relationship: + * + * GObject + * / \ + * TestObjectA TestObjectC + * | + * TestObjectB + * + * ie: TestObjectB is a subclass of TestObjectA and TestObjectC is + * related to neither. + */ + +static GType test_object_a_get_type (void); +typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass; +G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT) +static void test_object_a_class_init (TestObjectAClass *class) { } +static void test_object_a_init (TestObjectA *a) { } + +static GType test_object_b_get_type (void); +typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass; +G_DEFINE_TYPE (TestObjectB, test_object_b, test_object_a_get_type ()) +static void test_object_b_class_init (TestObjectBClass *class) { } +static void test_object_b_init (TestObjectB *b) { } + +static GType test_object_c_get_type (void); +typedef GObject TestObjectC; typedef GObjectClass TestObjectCClass; +G_DEFINE_TYPE (TestObjectC, test_object_c, G_TYPE_OBJECT) +static void test_object_c_class_init (TestObjectCClass *class) { } +static void test_object_c_init (TestObjectC *c) { } + +/* We create an interface and programmatically populate it with + * properties of each of the above type, with various flag combinations. + * + * Properties are named like "type-perm" where type is 'a', 'b' or 'c' + * and perm is a series of characters, indicating the permissions: + * + * - 'r': readable + * - 'w': writable + * - 'c': construct + * - 'C': construct-only + * + * It doesn't make sense to have a property that is neither readable nor + * writable. It is also not valid to have construct or construct-only + * on read-only params. Finally, it is invalid to have both construct + * and construct-only specified, so we do not consider those cases. + * That gives us 7 possible permissions: + * + * 'r', 'w', 'rw', 'wc', 'rwc', 'wC', 'rwC' + * + * And 9 impossible ones: + * + * '', 'c', 'rc', 'C', 'rC', 'cC', 'rcC', 'wcC', rwcC' + * + * For a total of 16 combinations. + * + * That gives a total of 48 (16 * 3) possible flag/type combinations, of + * which 27 (9 * 3) are impossible to install. + * + * That gives 21 (7 * 3) properties that will be installed. + */ +typedef GTypeInterface TestInterfaceInterface; +static GType test_interface_get_type (void); +//typedef struct _TestInterface TestInterface; +G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT) +static void +test_interface_default_init (TestInterfaceInterface *iface) +{ + const gchar *names[] = { "a", "b", "c" }; + const gchar *perms[] = { NULL, "r", "w", "rw", + NULL, NULL, "wc", "rwc", + NULL, NULL, "wC", "rwC", + NULL, NULL, NULL, NULL }; + const GType types[] = { test_object_a_get_type (), test_object_b_get_type (), test_object_c_get_type () }; + guint i, j; + + for (i = 0; i < G_N_ELEMENTS (types); i++) + for (j = 0; j < G_N_ELEMENTS (perms); j++) + { + gchar prop_name[10]; + GParamSpec *pspec; + + if (perms[j] == NULL) + { + if (!g_test_undefined ()) + continue; + + /* we think that this is impossible. make sure. */ + pspec = g_param_spec_object ("xyz", "xyz", "xyz", types[i], j); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*pspec->flags*failed*"); + g_object_interface_install_property (iface, pspec); + g_test_assert_expected_messages (); + + g_param_spec_unref (pspec); + continue; + } + + /* install the property */ + g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]); + pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[i], j); + g_object_interface_install_property (iface, pspec); + } +} + +/* We now have 21 properties. Each property may be correctly + * implemented with the following types: + * + * Properties Valid Types Reason + * + * a-r a, b Read only can provide subclasses + * a-w, wc, wC a, GObject Write only can accept superclasses + * a-rw, rwc, rwC a Read-write must be exactly equal + * + * b-r b (as above) + * b-w, wc, wC b, a, GObject + * b-rw, rwc, rwC b + * + * c-r c (as above) + * c-wo, wc, wC c, GObject + * c-rw, rwc, rwC c + * + * We can express this in a 48-by-4 table where each row represents an + * installed property and each column represents a type. The value in + * the table represents if it is valid to subclass the row's property + * with the type of the column: + * + * - 0: invalid because the interface property doesn't exist (invalid flags) + * - 'v': valid + * - '=': invalid because of the type not being exactly equal + * - '<': invalid because of the type not being a subclass + * - '>': invalid because of the type not being a superclass + * + * We organise the table by interface property type ('a', 'b', 'c') then + * by interface property flags. + */ + +static gint valid_impl_types[48][4] = { + /* a b c GObject */ + /* 'a-' */ { 0, }, + /* 'a-r' */ { 'v', 'v', '<', '<' }, + /* 'a-w' */ { 'v', '>', '>', 'v' }, + /* 'a-rw' */ { 'v', '=', '=', '=' }, + /* 'a-c */ { 0, }, + /* 'a-rc' */ { 0, }, + /* 'a-wc' */ { 'v', '>', '>', 'v' }, + /* 'a-rwc' */ { 'v', '=', '=', '=' }, + /* 'a-C */ { 0, }, + /* 'a-rC' */ { 0, }, + /* 'a-wC' */ { 'v', '>', '>', 'v' }, + /* 'a-rwC' */ { 'v', '=', '=', '=' }, + /* 'a-cC */ { 0, }, + /* 'a-rcC' */ { 0, }, + /* 'a-wcC' */ { 0, }, + /* 'a-rwcC' */ { 0, }, + + /* 'b-' */ { 0, }, + /* 'b-r' */ { '<', 'v', '<', '<' }, + /* 'b-w' */ { 'v', 'v', '>', 'v' }, + /* 'b-rw' */ { '=', 'v', '=', '=' }, + /* 'b-c */ { 0, }, + /* 'b-rc' */ { 0, }, + /* 'b-wc' */ { 'v', 'v', '>', 'v' }, + /* 'b-rwc' */ { '=', 'v', '=', '=' }, + /* 'b-C */ { 0, }, + /* 'b-rC' */ { 0, }, + /* 'b-wC' */ { 'v', 'v', '>', 'v' }, + /* 'b-rwC' */ { '=', 'v', '=', '=' }, + /* 'b-cC */ { 0, }, + /* 'b-rcC' */ { 0, }, + /* 'b-wcC' */ { 0, }, + /* 'b-rwcC' */ { 0, }, + + /* 'c-' */ { 0, }, + /* 'c-r' */ { '<', '<', 'v', '<' }, + /* 'c-w' */ { '>', '>', 'v', 'v' }, + /* 'c-rw' */ { '=', '=', 'v', '=' }, + /* 'c-c */ { 0, }, + /* 'c-rc' */ { 0, }, + /* 'c-wc' */ { '>', '>', 'v', 'v' }, + /* 'c-rwc' */ { '=', '=', 'v', '=' }, + /* 'c-C */ { 0, }, + /* 'c-rC' */ { 0, }, + /* 'c-wC' */ { '>', '>', 'v', 'v' }, + /* 'c-rwC' */ { '=', '=', 'v', '=' }, + /* 'c-cC */ { 0, }, + /* 'c-rcC' */ { 0, }, + /* 'c-wcC' */ { 0, }, + /* 'c-rwcC' */ { 0, } +}; + +/* We also try to change the flags. We must ensure that all + * implementations provide all functionality promised by the interface. + * We must therefore never remove readability or writability (but we can + * add them). Construct-only is a restrictions that applies to + * writability, so we can never add it unless writability was never + * present in the first place, in which case "writable at construct + * only" is still better than "not writable". + * + * The 'construct' flag is of interest only to the implementation. It + * may be changed at any time. + * + * Properties Valid Access Reason + * + * *-r r, rw, rwc, rwC Must keep readable, but can restrict newly-added writable + * *-w w, rw, rwc Must keep writable unrestricted + * *-rw rw, rwc Must not add any restrictions + * *-rwc rw, rwc Must not add any restrictions + * *-rwC rw, rwc, rwC Can remove 'construct-only' restriction + * *-wc rwc, rw, w, wc Can add readability + * *-wC rwC, rw, w, wC Can add readability or remove 'construct only' restriction + * rwc, wc + * + * We can represent this with a 16-by-16 table. The rows represent the + * flags of the property on the interface. The columns is the flags to + * try to use when overriding the property. The cell contents are: + * + * - 0: invalid because the interface property doesn't exist (invalid flags) + * - 'v': valid + * - 'i': invalid because the implementation flags are invalid + * - 'f': invalid because of the removal of functionality + * - 'r': invalid because of the addition of restrictions (ie: construct-only) + * + * We also ensure that removal of functionality is reported before + * addition of restrictions, since this is a more basic problem. + */ +static gint valid_impl_flags[16][16] = { + /* '' r w rw c rc wc rwc C rC wC rwC cC rcC wcC rwcC */ + /* '*-' */ { 0, }, + /* '*-r' */ { 'i', 'v', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' }, + /* '*-w' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' }, + /* '*-rw' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' }, + /* '*-c */ { 0, }, + /* '*-rc' */ { 0, }, + /* '*-wc' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' }, + /* '*-rwc' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' }, + /* '*-C */ { 0, }, + /* '*-rC' */ { 0, }, + /* '*-wC' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'i', 'i' }, + /* '*-rwC' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' }, +}; + +static guint change_this_flag; +static guint change_this_type; +static guint use_this_flag; +static guint use_this_type; + +typedef GObjectClass TestImplementationClass; +typedef GObject TestImplementation; + +static void test_implementation_init (TestImplementation *impl) { } +static void test_implementation_iface_init (TestInterfaceInterface *iface) { } + +static GType test_implementation_get_type (void); +G_DEFINE_TYPE_WITH_CODE (TestImplementation, test_implementation, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_implementation_iface_init)) + +static void test_implementation_class_init (TestImplementationClass *class) +{ + const gchar *names[] = { "a", "b", "c" }; + const gchar *perms[] = { NULL, "r", "w", "rw", + NULL, NULL, "wc", "rwc", + NULL, NULL, "wC", "rwC", + NULL, NULL, NULL, NULL }; + const GType types[] = { test_object_a_get_type (), test_object_b_get_type (), + test_object_c_get_type (), G_TYPE_OBJECT }; + gchar prop_name[10]; + GParamSpec *pspec; + guint i, j; + + class->get_property = GINT_TO_POINTER (1); + class->set_property = GINT_TO_POINTER (1); + + /* Install all of the non-modified properties or else GObject will + * complain about non-implemented properties. + */ + for (i = 0; i < 3; i++) + for (j = 0; j < G_N_ELEMENTS (perms); j++) + { + if (i == change_this_type && j == change_this_flag) + continue; + + if (perms[j] != NULL) + { + /* override the property without making changes */ + g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]); + g_object_class_override_property (class, 1, prop_name); + } + } + + /* Now try installing our modified property */ + if (perms[change_this_flag] == NULL) + g_error ("Interface property does not exist"); + + g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[change_this_type], perms[change_this_flag]); + pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[use_this_type], use_this_flag); + g_object_class_install_property (class, 1, pspec); +} + +typedef struct { + gint change_this_flag; + gint change_this_type; + gint use_this_flag; + gint use_this_type; +} TestParamImplementData; + +static void +test_param_implement_child (gconstpointer user_data) +{ + TestParamImplementData *data = (gpointer) user_data; + + /* GObject oddity: GObjectClass must be initialised before we can + * initialise a GTypeInterface. + */ + g_type_class_ref (G_TYPE_OBJECT); + + /* Bring up the interface first. */ + g_type_default_interface_ref (test_interface_get_type ()); + + /* Copy the flags into the global vars so + * test_implementation_class_init() will see them. + */ + change_this_flag = data->change_this_flag; + change_this_type = data->change_this_type; + use_this_flag = data->use_this_flag; + use_this_type = data->use_this_type; + + g_type_class_ref (test_implementation_get_type ()); +} + +static void +test_param_implement (void) +{ + gchar *test_path; + + for (change_this_flag = 0; change_this_flag < 16; change_this_flag++) + for (change_this_type = 0; change_this_type < 3; change_this_type++) + for (use_this_flag = 0; use_this_flag < 16; use_this_flag++) + for (use_this_type = 0; use_this_type < 4; use_this_type++) + { + if (!g_test_undefined ()) + { + /* only test the valid (defined) cases, e.g. under valgrind */ + if (valid_impl_flags[change_this_flag][use_this_flag] != 'v') + continue; + + if (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type] != 'v') + continue; + } + + test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d", + change_this_flag, change_this_type, + use_this_flag, use_this_type); + g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND, 0); + g_free (test_path); + + /* We want to ensure that any flags mismatch problems are reported first. */ + switch (valid_impl_flags[change_this_flag][use_this_flag]) + { + case 0: + /* make sure the other table agrees */ + g_assert_cmpint (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type], ==, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Interface property does not exist*"); + continue; + + case 'i': + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_object_class_install_property*"); + continue; + + case 'f': + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*remove functionality*"); + continue; + + case 'r': + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*introduce additional restrictions*"); + continue; + + case 'v': + break; + } + + /* Next, we check if there should have been a type error. */ + switch (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type]) + { + case 0: + /* this should have been caught above */ + g_assert_not_reached (); + + case '=': + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*exactly equal*"); + continue; + + case '<': + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*equal to or more restrictive*"); + continue; + + case '>': + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*equal to or less restrictive*"); + continue; + + case 'v': + break; + } + + g_test_trap_assert_passed (); + } +} + +static void +test_param_default (void) +{ + GParamSpec *param; + const GValue *def; + + param = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE); + def = g_param_spec_get_default_value (param); + + g_assert_true (G_VALUE_HOLDS (def, G_TYPE_INT)); + g_assert_cmpint (g_value_get_int (def), ==, 10); + + g_param_spec_unref (param); +} + +static void +test_param_is_valid_name (void) +{ + const gchar *valid_names[] = + { + "property", + "i", + "multiple-segments", + "segment0-SEGMENT1", + "using_underscores", + }; + const gchar *invalid_names[] = + { + "", + "7zip", + "my_int:hello", + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (valid_names); i++) + g_assert_true (g_param_spec_is_valid_name (valid_names[i])); + + for (i = 0; i < G_N_ELEMENTS (invalid_names); i++) + g_assert_false (g_param_spec_is_valid_name (invalid_names[i])); +} + +int +main (int argc, char *argv[]) +{ + TestParamImplementData data, *test_data; + gchar *test_path; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/param/value", test_param_value); + g_test_add_func ("/param/strings", test_param_strings); + g_test_add_data_func ("/param/invalid-name/colon", "my_int:hello", test_param_invalid_name); + g_test_add_data_func ("/param/invalid-name/first-char", "7zip", test_param_invalid_name); + g_test_add_data_func ("/param/invalid-name/empty", "", test_param_invalid_name); + g_test_add_func ("/param/qdata", test_param_qdata); + g_test_add_func ("/param/validate", test_param_validate); + g_test_add_func ("/param/convert", test_param_convert); + + if (g_test_slow ()) + g_test_add_func ("/param/implement", test_param_implement); + + for (data.change_this_flag = 0; data.change_this_flag < 16; data.change_this_flag++) + for (data.change_this_type = 0; data.change_this_type < 3; data.change_this_type++) + for (data.use_this_flag = 0; data.use_this_flag < 16; data.use_this_flag++) + for (data.use_this_type = 0; data.use_this_type < 4; data.use_this_type++) + { + test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d", + data.change_this_flag, data.change_this_type, + data.use_this_flag, data.use_this_type); + test_data = g_memdup2 (&data, sizeof (TestParamImplementData)); + g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free); + g_free (test_data); + g_free (test_path); + } + + g_test_add_func ("/value/transform", test_value_transform); + g_test_add_func ("/param/default", test_param_default); + g_test_add_func ("/param/is-valid-name", test_param_is_valid_name); + g_test_add_func ("/paramspec/char", test_param_spec_char); + g_test_add_func ("/paramspec/string", test_param_spec_string); + g_test_add_func ("/paramspec/override", test_param_spec_override); + g_test_add_func ("/paramspec/gtype", test_param_spec_gtype); + g_test_add_func ("/paramspec/variant", test_param_spec_variant); + g_test_add_func ("/paramspec/variant/cmp", test_param_spec_variant_cmp); + + return g_test_run (); +} diff --git a/gobject/tests/private.c b/gobject/tests/private.c new file mode 100644 index 0000000..1289c48 --- /dev/null +++ b/gobject/tests/private.c @@ -0,0 +1,261 @@ +/* We are testing some deprecated APIs here */ +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include + +typedef struct { + GObject parent_instance; +} TestObject; + +typedef struct { + int dummy_0; + float dummy_1; +} TestObjectPrivate; + +typedef struct { + GObjectClass parent_class; +} TestObjectClass; + +GType test_object_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT, + G_ADD_PRIVATE (TestObject)) + +static void +test_object_class_init (TestObjectClass *klass) +{ +} + +static void +test_object_init (TestObject *self) +{ + TestObjectPrivate *priv = test_object_get_instance_private (self); + + if (g_test_verbose ()) + g_printerr ("Offset of %sPrivate for type '%s': %d\n", + G_OBJECT_TYPE_NAME (self), + G_OBJECT_TYPE_NAME (self), + TestObject_private_offset); + + priv->dummy_0 = 42; + priv->dummy_1 = 3.14159f; +} + +static int +test_object_get_dummy_0 (TestObject *self) +{ + TestObjectPrivate *priv = test_object_get_instance_private (self); + + return priv->dummy_0; +} + +static float +test_object_get_dummy_1 (TestObject *self) +{ + TestObjectPrivate *priv = test_object_get_instance_private (self); + + return priv->dummy_1; +} + +typedef struct { + TestObject parent_instance; +} TestDerived; + +typedef struct { + char *dummy_2; +} TestDerivedPrivate; + +typedef struct { + TestObjectClass parent_class; +} TestDerivedClass; + +GType test_derived_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (TestDerived, test_derived, test_object_get_type (), + G_ADD_PRIVATE (TestDerived)) + +static void +test_derived_finalize (GObject *obj) +{ + TestDerivedPrivate *priv = test_derived_get_instance_private ((TestDerived *) obj); + + g_free (priv->dummy_2); + + G_OBJECT_CLASS (test_derived_parent_class)->finalize (obj); +} + +static void +test_derived_class_init (TestDerivedClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = test_derived_finalize; +} + +static void +test_derived_init (TestDerived *self) +{ + TestDerivedPrivate *priv = test_derived_get_instance_private (self); + + if (g_test_verbose ()) + g_printerr ("Offset of %sPrivate for type '%s': %d\n", + G_OBJECT_TYPE_NAME (self), + G_OBJECT_TYPE_NAME (self), + TestDerived_private_offset); + + priv->dummy_2 = g_strdup ("Hello"); +} + +static const char * +test_derived_get_dummy_2 (TestDerived *self) +{ + TestDerivedPrivate *priv = test_derived_get_instance_private (self); + + return priv->dummy_2; +} + +typedef struct { + TestObject parent_instance; +} TestMixed; + +typedef struct { + gint dummy_3; +} TestMixedPrivate; + +typedef struct { + TestObjectClass parent_class; +} TestMixedClass; + +GType test_mixed_get_type (void); + +G_DEFINE_TYPE (TestMixed, test_mixed, test_object_get_type ()) + +static void +test_mixed_class_init (TestMixedClass *klass) +{ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_type_class_add_private (klass, sizeof (TestMixedPrivate)); +G_GNUC_END_IGNORE_DEPRECATIONS +} + +static void +test_mixed_init (TestMixed *self) +{ + TestMixedPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, test_mixed_get_type (), TestMixedPrivate); + + if (g_test_verbose ()) + g_printerr ("Offset of %sPrivate for type '%s': %d\n", + G_OBJECT_TYPE_NAME (self), + G_OBJECT_TYPE_NAME (self), + TestMixed_private_offset); + + priv->dummy_3 = 47; +} + +static gint +test_mixed_get_dummy_3 (TestMixed *self) +{ + TestMixedPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, test_mixed_get_type (), TestMixedPrivate); + + return priv->dummy_3; +} + +typedef struct { + TestMixed parent_instance; +} TestMixedDerived; + +typedef struct { + gint64 dummy_4; +} TestMixedDerivedPrivate; + +typedef struct { + TestMixedClass parent_class; +} TestMixedDerivedClass; + +GType test_mixed_derived_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (TestMixedDerived, test_mixed_derived, test_mixed_get_type (), + G_ADD_PRIVATE (TestMixedDerived)) + +static void +test_mixed_derived_class_init (TestMixedDerivedClass *klass) +{ +} + +static void +test_mixed_derived_init (TestMixedDerived *self) +{ + TestMixedDerivedPrivate *priv = test_mixed_derived_get_instance_private (self); + + if (g_test_verbose ()) + g_printerr ("Offset of %sPrivate for type '%s': %d\n", + G_OBJECT_TYPE_NAME (self), + G_OBJECT_TYPE_NAME (self), + TestMixedDerived_private_offset); + + priv->dummy_4 = g_get_monotonic_time (); +} + +static gint64 +test_mixed_derived_get_dummy_4 (TestMixedDerived *self) +{ + TestMixedDerivedPrivate *priv = test_mixed_derived_get_instance_private (self); + + return priv->dummy_4; +} + +static void +private_instance (void) +{ + TestObject *obj = g_object_new (test_object_get_type (), NULL); + gpointer class; + gint offset; + + g_assert_cmpint (test_object_get_dummy_0 (obj), ==, 42); + g_assert_cmpfloat (test_object_get_dummy_1 (obj), ==, 3.14159f); + + class = g_type_class_ref (test_object_get_type ()); + offset = g_type_class_get_instance_private_offset (class); + g_type_class_unref (class); + + g_assert (offset == TestObject_private_offset); + + g_object_unref (obj); +} + +static void +private_derived_instance (void) +{ + TestDerived *obj = g_object_new (test_derived_get_type (), NULL); + + g_assert_cmpstr (test_derived_get_dummy_2 (obj), ==, "Hello"); + g_assert_cmpint (test_object_get_dummy_0 ((TestObject *) obj), ==, 42); + + g_object_unref (obj); +} + +static void +private_mixed_derived_instance (void) +{ + TestMixedDerived *derived = g_object_new (test_mixed_derived_get_type (), NULL); + TestMixed *mixed = g_object_new (test_mixed_get_type (), NULL); + + g_assert_cmpint (test_mixed_get_dummy_3 (mixed), ==, 47); + g_assert (test_mixed_derived_get_dummy_4 (derived) <= g_get_monotonic_time ()); + + g_object_unref (derived); + g_object_unref (mixed); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/private/instance", private_instance); + g_test_add_func ("/private/derived-instance", private_derived_instance); + g_test_add_func ("/private/mixed-derived-instance", private_mixed_derived_instance); + + return g_test_run (); +} diff --git a/gobject/tests/properties.c b/gobject/tests/properties.c new file mode 100644 index 0000000..208d5f1 --- /dev/null +++ b/gobject/tests/properties.c @@ -0,0 +1,658 @@ +#include +#include +#include + +typedef struct _TestObject { + GObject parent_instance; + gint foo; + gboolean bar; + gchar *baz; + gchar *quux; +} TestObject; + +typedef struct _TestObjectClass { + GObjectClass parent_class; +} TestObjectClass; + +enum { PROP_0, PROP_FOO, PROP_BAR, PROP_BAZ, PROP_QUUX, N_PROPERTIES }; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +static GType test_object_get_type (void); +G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT) + +static void +test_object_set_foo (TestObject *obj, + gint foo) +{ + if (obj->foo != foo) + { + obj->foo = foo; + + g_assert (properties[PROP_FOO] != NULL); + g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_FOO]); + } +} + +static void +test_object_set_bar (TestObject *obj, + gboolean bar) +{ + bar = !!bar; + + if (obj->bar != bar) + { + obj->bar = bar; + + g_assert (properties[PROP_BAR] != NULL); + g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_BAR]); + } +} + +static void +test_object_set_baz (TestObject *obj, + const gchar *baz) +{ + if (g_strcmp0 (obj->baz, baz) != 0) + { + g_free (obj->baz); + obj->baz = g_strdup (baz); + + g_assert (properties[PROP_BAZ] != NULL); + g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_BAZ]); + } +} + +static void +test_object_set_quux (TestObject *obj, + const gchar *quux) +{ + if (g_strcmp0 (obj->quux, quux) != 0) + { + g_free (obj->quux); + obj->quux = g_strdup (quux); + + g_assert (properties[PROP_QUUX] != NULL); + g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_QUUX]); + } +} + +static void +test_object_finalize (GObject *gobject) +{ + TestObject *self = (TestObject *) gobject; + + g_free (self->baz); + g_free (self->quux); + + /* When the ref_count of an object is zero it is still + * possible to notify the property, but it should do + * nothing and silently quit (bug #705570) + */ + g_object_notify (gobject, "foo"); + g_object_notify_by_pspec (gobject, properties[PROP_BAR]); + + G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject); +} + +static void +test_object_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + TestObject *tobj = (TestObject *) gobject; + + g_assert_cmpint (prop_id, !=, 0); + g_assert_true (prop_id < N_PROPERTIES && pspec == properties[prop_id]); + + switch (prop_id) + { + case PROP_FOO: + test_object_set_foo (tobj, g_value_get_int (value)); + break; + + case PROP_BAR: + test_object_set_bar (tobj, g_value_get_boolean (value)); + break; + + case PROP_BAZ: + test_object_set_baz (tobj, g_value_get_string (value)); + break; + + case PROP_QUUX: + test_object_set_quux (tobj, g_value_get_string (value)); + break; + + default: + g_assert_not_reached (); + } +} + +static void +test_object_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + TestObject *tobj = (TestObject *) gobject; + + g_assert_cmpint (prop_id, !=, 0); + g_assert_true (prop_id < N_PROPERTIES && pspec == properties[prop_id]); + + switch (prop_id) + { + case PROP_FOO: + g_value_set_int (value, tobj->foo); + break; + + case PROP_BAR: + g_value_set_boolean (value, tobj->bar); + break; + + case PROP_BAZ: + g_value_set_string (value, tobj->baz); + break; + + case PROP_QUUX: + g_value_set_string (value, tobj->quux); + break; + + default: + g_assert_not_reached (); + } +} + +static void +test_object_class_init (TestObjectClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "Foo", + -1, G_MAXINT, + 0, + G_PARAM_READWRITE); + properties[PROP_BAR] = g_param_spec_boolean ("bar", "Bar", "Bar", + FALSE, + G_PARAM_READWRITE); + properties[PROP_BAZ] = g_param_spec_string ("baz", "Baz", "Baz", + NULL, + G_PARAM_READWRITE); + properties[PROP_QUUX] = g_param_spec_string ("quux", "quux", "quux", + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); + + gobject_class->set_property = test_object_set_property; + gobject_class->get_property = test_object_get_property; + gobject_class->finalize = test_object_finalize; + + g_object_class_install_properties (gobject_class, N_PROPERTIES, properties); +} + +static void +test_object_init (TestObject *self) +{ + self->foo = 42; + self->bar = TRUE; + self->baz = g_strdup ("Hello"); + self->quux = NULL; +} + +static void +properties_install (void) +{ + TestObject *obj = g_object_new (test_object_get_type (), NULL); + GParamSpec *pspec; + + g_assert (properties[PROP_FOO] != NULL); + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), "foo"); + g_assert (properties[PROP_FOO] == pspec); + + g_object_unref (obj); +} + +typedef struct { + const gchar *name; + GParamSpec *pspec; + gboolean fired; +} TestNotifyClosure; + +static void +on_notify (GObject *gobject, + GParamSpec *pspec, + TestNotifyClosure *closure) +{ + g_assert (closure->pspec == pspec); + g_assert_cmpstr (closure->name, ==, pspec->name); + closure->fired = TRUE; +} + +static void +properties_notify (void) +{ + TestObject *obj = g_object_new (test_object_get_type (), NULL); + TestNotifyClosure closure; + + g_assert (properties[PROP_FOO] != NULL); + g_assert (properties[PROP_QUUX] != NULL); + g_signal_connect (obj, "notify", G_CALLBACK (on_notify), &closure); + + closure.name = "foo"; + closure.pspec = properties[PROP_FOO]; + + closure.fired = FALSE; + g_object_set (obj, "foo", 47, NULL); + g_assert (closure.fired); + + closure.name = "baz"; + closure.pspec = properties[PROP_BAZ]; + + closure.fired = FALSE; + g_object_set (obj, "baz", "something new", NULL); + g_assert (closure.fired); + + /* baz lacks explicit notify, so we will see this twice */ + closure.fired = FALSE; + g_object_set (obj, "baz", "something new", NULL); + g_assert (closure.fired); + + /* quux on the other hand, ... */ + closure.name = "quux"; + closure.pspec = properties[PROP_QUUX]; + + closure.fired = FALSE; + g_object_set (obj, "quux", "something new", NULL); + g_assert (closure.fired); + + /* no change; no notify */ + closure.fired = FALSE; + g_object_set (obj, "quux", "something new", NULL); + g_assert (!closure.fired); + + + g_object_unref (obj); +} + +typedef struct { + GParamSpec *pspec[3]; + gint pos; +} Notifys; + +static void +on_notify2 (GObject *gobject, + GParamSpec *pspec, + Notifys *n) +{ + g_assert (n->pspec[n->pos] == pspec); + n->pos++; +} + +static void +properties_notify_queue (void) +{ + TestObject *obj = g_object_new (test_object_get_type (), NULL); + Notifys n; + + g_assert (properties[PROP_FOO] != NULL); + + n.pspec[0] = properties[PROP_BAZ]; + n.pspec[1] = properties[PROP_BAR]; + n.pspec[2] = properties[PROP_FOO]; + n.pos = 0; + + g_signal_connect (obj, "notify", G_CALLBACK (on_notify2), &n); + + g_object_freeze_notify (G_OBJECT (obj)); + g_object_set (obj, "foo", 47, NULL); + g_object_set (obj, "bar", TRUE, "foo", 42, "baz", "abc", NULL); + g_object_thaw_notify (G_OBJECT (obj)); + g_assert (n.pos == 3); + + g_object_unref (obj); +} + +static void +properties_construct (void) +{ + TestObject *obj; + gint val; + gboolean b; + gchar *s; + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=630357"); + + /* more than 16 args triggers a realloc in g_object_new_valist() */ + obj = g_object_new (test_object_get_type (), + "foo", 1, + "foo", 2, + "foo", 3, + "foo", 4, + "foo", 5, + "bar", FALSE, + "foo", 6, + "foo", 7, + "foo", 8, + "foo", 9, + "foo", 10, + "baz", "boo", + "foo", 11, + "foo", 12, + "foo", 13, + "foo", 14, + "foo", 15, + "foo", 16, + "foo", 17, + "foo", 18, + NULL); + + g_object_get (obj, "foo", &val, NULL); + g_assert (val == 18); + g_object_get (obj, "bar", &b, NULL); + g_assert (!b); + g_object_get (obj, "baz", &s, NULL); + g_assert_cmpstr (s, ==, "boo"); + g_free (s); + + g_object_unref (obj); +} + +static void +properties_testv_with_no_properties (void) +{ + TestObject *test_obj; + const char *prop_names[4] = { "foo", "bar", "baz", "quux" }; + GValue values_out[4] = { G_VALUE_INIT }; + guint i; + + /* Test newv_with_properties && getv */ + test_obj = (TestObject *) g_object_new_with_properties ( + test_object_get_type (), 0, NULL, NULL); + g_object_getv (G_OBJECT (test_obj), 4, prop_names, values_out); + + /* It should have init values */ + g_assert_cmpint (g_value_get_int (&values_out[0]), ==, 42); + g_assert_true (g_value_get_boolean (&values_out[1])); + g_assert_cmpstr (g_value_get_string (&values_out[2]), ==, "Hello"); + g_assert_cmpstr (g_value_get_string (&values_out[3]), ==, NULL); + + for (i = 0; i < 4; i++) + g_value_unset (&values_out[i]); + g_object_unref (test_obj); +} + +static void +properties_testv_with_valid_properties (void) +{ + TestObject *test_obj; + const char *prop_names[4] = { "foo", "bar", "baz", "quux" }; + + GValue values_in[4] = { G_VALUE_INIT }; + GValue values_out[4] = { G_VALUE_INIT }; + guint i; + + g_value_init (&(values_in[0]), G_TYPE_INT); + g_value_set_int (&(values_in[0]), 100); + + g_value_init (&(values_in[1]), G_TYPE_BOOLEAN); + g_value_set_boolean (&(values_in[1]), TRUE); + + g_value_init (&(values_in[2]), G_TYPE_STRING); + g_value_set_string (&(values_in[2]), "pigs"); + + g_value_init (&(values_in[3]), G_TYPE_STRING); + g_value_set_string (&(values_in[3]), "fly"); + + /* Test newv_with_properties && getv */ + test_obj = (TestObject *) g_object_new_with_properties ( + test_object_get_type (), 4, prop_names, values_in); + g_object_getv (G_OBJECT (test_obj), 4, prop_names, values_out); + + g_assert_cmpint (g_value_get_int (&values_out[0]), ==, 100); + g_assert_true (g_value_get_boolean (&values_out[1])); + g_assert_cmpstr (g_value_get_string (&values_out[2]), ==, "pigs"); + g_assert_cmpstr (g_value_get_string (&values_out[3]), ==, "fly"); + + for (i = 0; i < G_N_ELEMENTS (values_out); i++) + g_value_unset (&values_out[i]); + + /* Test newv2 && getv */ + g_value_set_string (&(values_in[2]), "Elmo knows"); + g_value_set_string (&(values_in[3]), "where you live"); + g_object_setv (G_OBJECT (test_obj), 4, prop_names, values_in); + + g_object_getv (G_OBJECT (test_obj), 4, prop_names, values_out); + + g_assert_cmpint (g_value_get_int (&values_out[0]), ==, 100); + g_assert_true (g_value_get_boolean (&values_out[1])); + + g_assert_cmpstr (g_value_get_string (&values_out[2]), ==, "Elmo knows"); + g_assert_cmpstr (g_value_get_string (&values_out[3]), ==, "where you live"); + + for (i = 0; i < G_N_ELEMENTS (values_in); i++) + g_value_unset (&values_in[i]); + for (i = 0; i < G_N_ELEMENTS (values_out); i++) + g_value_unset (&values_out[i]); + + g_object_unref (test_obj); +} + +static void +properties_testv_with_invalid_property_type (void) +{ + if (g_test_subprocess ()) + { + TestObject *test_obj; + const char *invalid_prop_names[1] = { "foo" }; + GValue values_in[1] = { G_VALUE_INIT }; + + g_value_init (&(values_in[0]), G_TYPE_STRING); + g_value_set_string (&(values_in[0]), "fly"); + + test_obj = (TestObject *) g_object_new_with_properties ( + test_object_get_type (), 1, invalid_prop_names, values_in); + /* should give a warning */ + + g_object_unref (test_obj); + } + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*WARNING*foo*gint*gchararray*"); +} + + +static void +properties_testv_with_invalid_property_names (void) +{ + if (g_test_subprocess ()) + { + TestObject *test_obj; + const char *invalid_prop_names[4] = { "foo", "boo", "moo", "poo" }; + GValue values_in[4] = { G_VALUE_INIT }; + + g_value_init (&(values_in[0]), G_TYPE_INT); + g_value_set_int (&(values_in[0]), 100); + + g_value_init (&(values_in[1]), G_TYPE_BOOLEAN); + g_value_set_boolean (&(values_in[1]), TRUE); + + g_value_init (&(values_in[2]), G_TYPE_STRING); + g_value_set_string (&(values_in[2]), "pigs"); + + g_value_init (&(values_in[3]), G_TYPE_STRING); + g_value_set_string (&(values_in[3]), "fly"); + + test_obj = (TestObject *) g_object_new_with_properties ( + test_object_get_type (), 4, invalid_prop_names, values_in); + /* This call should give 3 Critical warnings. Actually, a critical warning + * shouldn't make g_object_new_with_properties to fail when a bad named + * property is given, because, it will just ignore that property. However, + * for test purposes, it is considered that the test doesn't pass. + */ + + g_object_unref (test_obj); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*g_object_new_is_valid_property*boo*"); +} + +static void +properties_testv_getv (void) +{ + TestObject *test_obj; + const char *prop_names[4] = { "foo", "bar", "baz", "quux" }; + GValue values_out_initialized[4] = { G_VALUE_INIT }; + GValue values_out_uninitialized[4] = { G_VALUE_INIT }; + guint i; + + g_value_init (&(values_out_initialized[0]), G_TYPE_INT); + g_value_init (&(values_out_initialized[1]), G_TYPE_BOOLEAN); + g_value_init (&(values_out_initialized[2]), G_TYPE_STRING); + g_value_init (&(values_out_initialized[3]), G_TYPE_STRING); + + test_obj = (TestObject *) g_object_new_with_properties ( + test_object_get_type (), 0, NULL, NULL); + + /* Test g_object_getv for an initialized values array */ + g_object_getv (G_OBJECT (test_obj), 4, prop_names, values_out_initialized); + /* It should have init values */ + g_assert_cmpint (g_value_get_int (&values_out_initialized[0]), ==, 42); + g_assert_true (g_value_get_boolean (&values_out_initialized[1])); + g_assert_cmpstr (g_value_get_string (&values_out_initialized[2]), ==, "Hello"); + g_assert_cmpstr (g_value_get_string (&values_out_initialized[3]), ==, NULL); + + /* Test g_object_getv for an uninitialized values array */ + g_object_getv (G_OBJECT (test_obj), 4, prop_names, values_out_uninitialized); + /* It should have init values */ + g_assert_cmpint (g_value_get_int (&values_out_uninitialized[0]), ==, 42); + g_assert_true (g_value_get_boolean (&values_out_uninitialized[1])); + g_assert_cmpstr (g_value_get_string (&values_out_uninitialized[2]), ==, "Hello"); + g_assert_cmpstr (g_value_get_string (&values_out_uninitialized[3]), ==, NULL); + + for (i = 0; i < 4; i++) + { + g_value_unset (&values_out_initialized[i]); + g_value_unset (&values_out_uninitialized[i]); + } + g_object_unref (test_obj); +} + +static void +properties_get_property (void) +{ + TestObject *test_obj; + struct { + const char *name; + GType gtype; + GValue value; + } test_props[] = { + { "foo", G_TYPE_INT, G_VALUE_INIT }, + { "bar", G_TYPE_INVALID, G_VALUE_INIT }, + { "bar", G_TYPE_STRING, G_VALUE_INIT }, + }; + gsize i; + + g_test_summary ("g_object_get_property() accepts uninitialized, " + "initialized, and transformable values"); + + for (i = 0; i < G_N_ELEMENTS (test_props); i++) + { + if (test_props[i].gtype != G_TYPE_INVALID) + g_value_init (&(test_props[i].value), test_props[i].gtype); + } + + test_obj = (TestObject *) g_object_new_with_properties (test_object_get_type (), 0, NULL, NULL); + + g_test_message ("Test g_object_get_property with an initialized value"); + g_object_get_property (G_OBJECT (test_obj), test_props[0].name, &(test_props[0].value)); + g_assert_cmpint (g_value_get_int (&(test_props[0].value)), ==, 42); + + g_test_message ("Test g_object_get_property with an uninitialized value"); + g_object_get_property (G_OBJECT (test_obj), test_props[1].name, &(test_props[1].value)); + g_assert_true (g_value_get_boolean (&(test_props[1].value))); + + g_test_message ("Test g_object_get_property with a transformable value"); + g_object_get_property (G_OBJECT (test_obj), test_props[2].name, &(test_props[2].value)); + g_assert_true (G_VALUE_HOLDS_STRING (&(test_props[2].value))); + g_assert_cmpstr (g_value_get_string (&(test_props[2].value)), ==, "TRUE"); + + for (i = 0; i < G_N_ELEMENTS (test_props); i++) + g_value_unset (&(test_props[i].value)); + + g_object_unref (test_obj); +} + +static void +properties_testv_notify_queue (void) +{ + TestObject *test_obj; + const char *prop_names[3] = { "foo", "bar", "baz" }; + GValue values_in[3] = { G_VALUE_INIT }; + Notifys n; + guint i; + + g_value_init (&(values_in[0]), G_TYPE_INT); + g_value_set_int (&(values_in[0]), 100); + + g_value_init (&(values_in[1]), G_TYPE_BOOLEAN); + g_value_set_boolean (&(values_in[1]), TRUE); + + g_value_init (&(values_in[2]), G_TYPE_STRING); + g_value_set_string (&(values_in[2]), ""); + + /* Test newv_with_properties && getv */ + test_obj = (TestObject *) g_object_new_with_properties ( + test_object_get_type (), 0, NULL, NULL); + + g_assert_nonnull (properties[PROP_FOO]); + + n.pspec[0] = properties[PROP_BAZ]; + n.pspec[1] = properties[PROP_BAR]; + n.pspec[2] = properties[PROP_FOO]; + n.pos = 0; + + g_signal_connect (test_obj, "notify", G_CALLBACK (on_notify2), &n); + + g_object_freeze_notify (G_OBJECT (test_obj)); + { + g_object_setv (G_OBJECT (test_obj), 3, prop_names, values_in); + + /* Set "foo" to 70 */ + g_value_set_int (&(values_in[0]), 100); + g_object_setv (G_OBJECT (test_obj), 1, prop_names, values_in); + } + g_object_thaw_notify (G_OBJECT (test_obj)); + g_assert_cmpint (n.pos, ==, 3); + + for (i = 0; i < 3; i++) + g_value_unset (&values_in[i]); + g_object_unref (test_obj); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/properties/install", properties_install); + g_test_add_func ("/properties/notify", properties_notify); + g_test_add_func ("/properties/notify-queue", properties_notify_queue); + g_test_add_func ("/properties/construct", properties_construct); + g_test_add_func ("/properties/get-property", properties_get_property); + + g_test_add_func ("/properties/testv_with_no_properties", + properties_testv_with_no_properties); + g_test_add_func ("/properties/testv_with_valid_properties", + properties_testv_with_valid_properties); + g_test_add_func ("/properties/testv_with_invalid_property_type", + properties_testv_with_invalid_property_type); + g_test_add_func ("/properties/testv_with_invalid_property_names", + properties_testv_with_invalid_property_names); + g_test_add_func ("/properties/testv_getv", properties_testv_getv); + g_test_add_func ("/properties/testv_notify_queue", + properties_testv_notify_queue); + + return g_test_run (); +} diff --git a/gobject/tests/qdata.c b/gobject/tests/qdata.c new file mode 100644 index 0000000..7d46efb --- /dev/null +++ b/gobject/tests/qdata.c @@ -0,0 +1,123 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * See the included COPYING file for more information. + */ + +#include + +gboolean fail; + +#define THREADS 10 +#define ROUNDS 10000 + +GObject *object; +gint bucket[THREADS]; /* accessed from multiple threads, but should never be contested due to the sequence of thread operations */ + +static gpointer +thread_func (gpointer data) +{ + gint idx = GPOINTER_TO_INT (data); + gint i; + gint d; + gint value; + gint new_value; + + for (i = 0; i < ROUNDS; i++) + { + d = g_random_int_range (-10, 100); + bucket[idx] += d; +retry: + value = GPOINTER_TO_INT (g_object_get_data (object, "test")); + new_value = value + d; + if (fail) + g_object_set_data (object, "test", GINT_TO_POINTER (new_value)); + else + { + if (!g_object_replace_data (object, "test", + GINT_TO_POINTER (value), + GINT_TO_POINTER (new_value), + NULL, NULL)) + goto retry; + } + g_thread_yield (); + } + + return NULL; +} + +static void +test_qdata_threaded (void) +{ + gint sum; + gint i; + GThread *threads[THREADS]; + gint result; + + object = g_object_new (G_TYPE_OBJECT, NULL); + g_object_set_data (object, "test", GINT_TO_POINTER (0)); + + for (i = 0; i < THREADS; i++) + bucket[i] = 0; + + for (i = 0; i < THREADS; i++) + threads[i] = g_thread_new ("qdata", thread_func, GINT_TO_POINTER (i)); + + for (i = 0; i < THREADS; i++) + g_thread_join (threads[i]); + + sum = 0; + for (i = 0; i < THREADS; i++) + sum += bucket[i]; + + result = GPOINTER_TO_INT (g_object_get_data (object, "test")); + + g_assert_cmpint (sum, ==, result); + + g_object_unref (object); +} + +static void +test_qdata_dup (void) +{ + gchar *s, *s2; + GQuark quark; + gboolean b; + + quark = g_quark_from_static_string ("test"); + object = g_object_new (G_TYPE_OBJECT, NULL); + s = g_strdup ("s"); + g_object_set_qdata_full (object, quark, s, g_free); + + s2 = g_object_dup_qdata (object, quark, (GDuplicateFunc)g_strdup, NULL); + + g_assert_cmpstr (s, ==, s2); + g_assert (s != s2); + + g_free (s2); + + b = g_object_replace_qdata (object, quark, s, "s2", NULL, NULL); + g_assert (b); + + g_free (s); + + g_object_unref (object); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + fail = !!g_getenv ("FAIL"); + + g_test_add_func ("/qdata/threaded", test_qdata_threaded); + g_test_add_func ("/qdata/dup", test_qdata_dup); + + return g_test_run (); +} diff --git a/gobject/tests/reference.c b/gobject/tests/reference.c new file mode 100644 index 0000000..c7afc8a --- /dev/null +++ b/gobject/tests/reference.c @@ -0,0 +1,973 @@ +#include + +static void +test_fundamentals (void) +{ + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_NONE)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INTERFACE)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_CHAR)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UCHAR)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_BOOLEAN)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INT)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UINT)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_LONG)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_ULONG)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INT64)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UINT64)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_ENUM)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_FLAGS)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_FLOAT)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_DOUBLE)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_STRING)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_POINTER)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_BOXED)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_PARAM)); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_OBJECT)); + g_assert (G_TYPE_OBJECT == g_object_get_type ()); + g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_VARIANT)); + g_assert (G_TYPE_IS_DERIVED (G_TYPE_INITIALLY_UNOWNED)); + + g_assert (g_type_fundamental_next () == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST)); +} + +static void +test_type_qdata (void) +{ + gchar *data; + + g_type_set_qdata (G_TYPE_ENUM, g_quark_from_string ("bla"), "bla"); + data = g_type_get_qdata (G_TYPE_ENUM, g_quark_from_string ("bla")); + g_assert_cmpstr (data, ==, "bla"); +} + +static void +test_type_query (void) +{ + GTypeQuery query; + + g_type_query (G_TYPE_ENUM, &query); + g_assert_cmpint (query.type, ==, G_TYPE_ENUM); + g_assert_cmpstr (query.type_name, ==, "GEnum"); + g_assert_cmpint (query.class_size, ==, sizeof (GEnumClass)); + g_assert_cmpint (query.instance_size, ==, 0); +} + +typedef struct _MyObject MyObject; +typedef struct _MyObjectClass MyObjectClass; +typedef struct _MyObjectClassPrivate MyObjectClassPrivate; + +struct _MyObject +{ + GObject parent_instance; + + gint count; +}; + +struct _MyObjectClass +{ + GObjectClass parent_class; +}; + +struct _MyObjectClassPrivate +{ + gint secret_class_count; +}; + +static GType my_object_get_type (void); +G_DEFINE_TYPE_WITH_CODE (MyObject, my_object, G_TYPE_OBJECT, + g_type_add_class_private (g_define_type_id, sizeof (MyObjectClassPrivate)) ); + +static void +my_object_init (MyObject *obj) +{ + obj->count = 42; +} + +static void +my_object_class_init (MyObjectClass *klass) +{ +} + +static void +test_class_private (void) +{ + GObject *obj; + MyObjectClass *class; + MyObjectClassPrivate *priv; + + obj = g_object_new (my_object_get_type (), NULL); + + class = g_type_class_ref (my_object_get_type ()); + priv = G_TYPE_CLASS_GET_PRIVATE (class, my_object_get_type (), MyObjectClassPrivate); + priv->secret_class_count = 13; + g_type_class_unref (class); + + g_object_unref (obj); + + g_assert_cmpint (g_type_qname (my_object_get_type ()), ==, g_quark_from_string ("MyObject")); +} + +static void +test_clear (void) +{ + GObject *o = NULL; + GObject *tmp; + + g_clear_object (&o); + g_assert (o == NULL); + + tmp = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (tmp->ref_count, ==, 1); + o = g_object_ref (tmp); + g_assert (o != NULL); + + g_assert_cmpint (tmp->ref_count, ==, 2); + g_clear_object (&o); + g_assert_cmpint (tmp->ref_count, ==, 1); + g_assert (o == NULL); + + g_object_unref (tmp); +} + +static void +test_clear_function (void) +{ + GObject *o = NULL; + GObject *tmp; + + (g_clear_object) (&o); + g_assert (o == NULL); + + tmp = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (tmp->ref_count, ==, 1); + o = g_object_ref (tmp); + g_assert (o != NULL); + + g_assert_cmpint (tmp->ref_count, ==, 2); + (g_clear_object) (&o); + g_assert_cmpint (tmp->ref_count, ==, 1); + g_assert (o == NULL); + + g_object_unref (tmp); +} + +static void +test_set (void) +{ + GObject *o = NULL; + GObject *tmp; + gpointer tmp_weak = NULL; + + g_assert (!g_set_object (&o, NULL)); + g_assert (o == NULL); + + tmp = g_object_new (G_TYPE_OBJECT, NULL); + tmp_weak = tmp; + g_object_add_weak_pointer (tmp, &tmp_weak); + g_assert_cmpint (tmp->ref_count, ==, 1); + + g_assert (g_set_object (&o, tmp)); + g_assert (o == tmp); + g_assert_cmpint (tmp->ref_count, ==, 2); + + g_object_unref (tmp); + g_assert_cmpint (tmp->ref_count, ==, 1); + + /* Setting it again shouldn’t cause finalisation. */ + g_assert (!g_set_object (&o, tmp)); + g_assert (o == tmp); + g_assert_cmpint (tmp->ref_count, ==, 1); + g_assert_nonnull (tmp_weak); + + g_assert (g_set_object (&o, NULL)); + g_assert (o == NULL); + g_assert_null (tmp_weak); +} + +static void +test_set_function (void) +{ + GObject *o = NULL; + GObject *tmp; + gpointer tmp_weak = NULL; + + g_assert (!(g_set_object) (&o, NULL)); + g_assert (o == NULL); + + tmp = g_object_new (G_TYPE_OBJECT, NULL); + tmp_weak = tmp; + g_object_add_weak_pointer (tmp, &tmp_weak); + g_assert_cmpint (tmp->ref_count, ==, 1); + + g_assert ((g_set_object) (&o, tmp)); + g_assert (o == tmp); + g_assert_cmpint (tmp->ref_count, ==, 2); + + g_object_unref (tmp); + g_assert_cmpint (tmp->ref_count, ==, 1); + + /* Setting it again shouldn’t cause finalisation. */ + g_assert (!(g_set_object) (&o, tmp)); + g_assert (o == tmp); + g_assert_cmpint (tmp->ref_count, ==, 1); + g_assert_nonnull (tmp_weak); + + g_assert ((g_set_object) (&o, NULL)); + g_assert (o == NULL); + g_assert_null (tmp_weak); +} + +static void +test_set_derived_type (void) +{ + GBinding *obj = NULL; + GObject *o = NULL; + GBinding *b = NULL; + + g_test_summary ("Check that g_set_object() doesn’t give strict aliasing " + "warnings when used on types derived from GObject"); + + g_assert_false (g_set_object (&o, NULL)); + g_assert_null (o); + + g_assert_false (g_set_object (&b, NULL)); + g_assert_null (b); + + obj = g_object_new (my_object_get_type (), NULL); + + g_assert_true (g_set_object (&o, G_OBJECT (obj))); + g_assert_true (o == G_OBJECT (obj)); + + g_assert_true (g_set_object (&b, obj)); + g_assert_true (b == obj); + + g_object_unref (obj); + g_clear_object (&b); + g_clear_object (&o); +} + +static void +toggle_cb (gpointer data, GObject *obj, gboolean is_last) +{ + gboolean *b = data; + + *b = TRUE; +} + +static void +test_object_value (void) +{ + GObject *v; + GObject *v2; + GValue value = G_VALUE_INIT; + gboolean toggled = FALSE; + + g_value_init (&value, G_TYPE_OBJECT); + + v = g_object_new (G_TYPE_OBJECT, NULL); + g_object_add_toggle_ref (v, toggle_cb, &toggled); + + g_value_take_object (&value, v); + + v2 = g_value_get_object (&value); + g_assert (v2 == v); + + v2 = g_value_dup_object (&value); + g_assert (v2 == v); /* objects use ref/unref for copy/free */ + g_object_unref (v2); + + g_assert (!toggled); + g_value_unset (&value); + g_assert (toggled); + + /* test the deprecated variant too */ + g_value_init (&value, G_TYPE_OBJECT); + /* get a new reference */ + g_object_ref (v); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_value_set_object_take_ownership (&value, v); +G_GNUC_END_IGNORE_DEPRECATIONS + + toggled = FALSE; + g_value_unset (&value); + g_assert (toggled); + + g_object_remove_toggle_ref (v, toggle_cb, &toggled); +} + +static void +test_initially_unowned (void) +{ + GObject *obj; + + obj = g_object_new (G_TYPE_INITIALLY_UNOWNED, NULL); + g_assert (g_object_is_floating (obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_ref_sink (obj); + g_assert (!g_object_is_floating (obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_ref_sink (obj); + g_assert (!g_object_is_floating (obj)); + g_assert_cmpint (obj->ref_count, ==, 2); + + g_object_unref (obj); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_force_floating (obj); + g_assert (g_object_is_floating (obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_ref_sink (obj); + g_object_unref (obj); + + obj = g_object_new (G_TYPE_INITIALLY_UNOWNED, NULL); + g_assert_true (g_object_is_floating (obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_take_ref (obj); + g_assert_false (g_object_is_floating (obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_take_ref (obj); + g_assert_false (g_object_is_floating (obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_unref (obj); +} + +static void +test_weak_pointer (void) +{ + GObject *obj; + gpointer weak; + gpointer weak2; + + weak = weak2 = obj = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_add_weak_pointer (obj, &weak); + g_object_add_weak_pointer (obj, &weak2); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert (weak == obj); + g_assert (weak2 == obj); + + g_object_remove_weak_pointer (obj, &weak2); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert (weak == obj); + g_assert (weak2 == obj); + + g_object_unref (obj); + g_assert (weak == NULL); + g_assert (weak2 == obj); +} + +static void +test_weak_pointer_clear (void) +{ + GObject *obj; + gpointer weak = NULL; + + g_clear_weak_pointer (&weak); + g_assert_null (weak); + + weak = obj = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_add_weak_pointer (obj, &weak); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_true (weak == obj); + + g_clear_weak_pointer (&weak); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_null (weak); + + g_object_unref (obj); +} + +static void +test_weak_pointer_clear_function (void) +{ + GObject *obj; + gpointer weak = NULL; + + (g_clear_weak_pointer) (&weak); + g_assert_null (weak); + + weak = obj = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_object_add_weak_pointer (obj, &weak); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_true (weak == obj); + + (g_clear_weak_pointer) (&weak); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_null (weak); + + g_object_unref (obj); +} + +static void +test_weak_pointer_set (void) +{ + GObject *obj; + gpointer weak = NULL; + + g_assert_false (g_set_weak_pointer (&weak, NULL)); + g_assert_null (weak); + + obj = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_assert_true (g_set_weak_pointer (&weak, obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_true (weak == obj); + + g_assert_true (g_set_weak_pointer (&weak, NULL)); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_null (weak); + + g_assert_true (g_set_weak_pointer (&weak, obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_true (weak == obj); + + g_object_unref (obj); + g_assert_null (weak); +} + +static void +test_weak_pointer_set_function (void) +{ + GObject *obj; + gpointer weak = NULL; + + g_assert_false ((g_set_weak_pointer) (&weak, NULL)); + g_assert_null (weak); + + obj = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (obj->ref_count, ==, 1); + + g_assert_true ((g_set_weak_pointer) (&weak, obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_true (weak == obj); + + g_assert_true ((g_set_weak_pointer) (&weak, NULL)); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_null (weak); + + g_assert_true ((g_set_weak_pointer) (&weak, obj)); + g_assert_cmpint (obj->ref_count, ==, 1); + g_assert_true (weak == obj); + + g_object_unref (obj); + g_assert_null (weak); +} + +/* See gobject/tests/threadtests.c for the threaded version */ +static void +test_weak_ref (void) +{ + GObject *obj; + GObject *obj2; + GObject *tmp; + GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } }; + GWeakRef weak2 = { { GUINT_TO_POINTER (0xDEADBEEFU) } }; + GWeakRef weak3 = { { GUINT_TO_POINTER (0xDEADBEEFU) } }; + GWeakRef *dynamic_weak = g_new (GWeakRef, 1); + + /* you can initialize to empty like this... */ + g_weak_ref_init (&weak2, NULL); + g_assert (g_weak_ref_get (&weak2) == NULL); + + /* ... or via an initializer */ + g_weak_ref_init (&weak3, NULL); + g_assert (g_weak_ref_get (&weak3) == NULL); + + obj = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (obj->ref_count, ==, 1); + + obj2 = g_object_new (G_TYPE_OBJECT, NULL); + g_assert_cmpint (obj2->ref_count, ==, 1); + + /* you can init with an object (even if uninitialized) */ + g_weak_ref_init (&weak, obj); + g_weak_ref_init (dynamic_weak, obj); + /* or set to point at an object, if initialized (maybe to 0) */ + g_weak_ref_set (&weak2, obj); + g_weak_ref_set (&weak3, obj); + /* none of this affects its refcount */ + g_assert_cmpint (obj->ref_count, ==, 1); + + /* getting the value takes a ref */ + tmp = g_weak_ref_get (&weak); + g_assert (tmp == obj); + g_assert_cmpint (obj->ref_count, ==, 2); + g_object_unref (tmp); + g_assert_cmpint (obj->ref_count, ==, 1); + + tmp = g_weak_ref_get (&weak2); + g_assert (tmp == obj); + g_assert_cmpint (obj->ref_count, ==, 2); + g_object_unref (tmp); + g_assert_cmpint (obj->ref_count, ==, 1); + + tmp = g_weak_ref_get (&weak3); + g_assert (tmp == obj); + g_assert_cmpint (obj->ref_count, ==, 2); + g_object_unref (tmp); + g_assert_cmpint (obj->ref_count, ==, 1); + + tmp = g_weak_ref_get (dynamic_weak); + g_assert (tmp == obj); + g_assert_cmpint (obj->ref_count, ==, 2); + g_object_unref (tmp); + g_assert_cmpint (obj->ref_count, ==, 1); + + /* clearing a weak ref stops tracking */ + g_weak_ref_clear (&weak); + + /* setting a weak ref to NULL stops tracking too */ + g_weak_ref_set (&weak2, NULL); + g_assert (g_weak_ref_get (&weak2) == NULL); + g_weak_ref_clear (&weak2); + + /* setting a weak ref to a new object stops tracking the old one */ + g_weak_ref_set (dynamic_weak, obj2); + tmp = g_weak_ref_get (dynamic_weak); + g_assert (tmp == obj2); + g_assert_cmpint (obj2->ref_count, ==, 2); + g_object_unref (tmp); + g_assert_cmpint (obj2->ref_count, ==, 1); + + g_assert_cmpint (obj->ref_count, ==, 1); + + /* free the object: weak3 is the only one left pointing there */ + g_object_unref (obj); + g_assert (g_weak_ref_get (&weak3) == NULL); + + /* setting a weak ref to a new object stops tracking the old one */ + g_weak_ref_set (dynamic_weak, obj2); + tmp = g_weak_ref_get (dynamic_weak); + g_assert (tmp == obj2); + g_assert_cmpint (obj2->ref_count, ==, 2); + g_object_unref (tmp); + g_assert_cmpint (obj2->ref_count, ==, 1); + + g_weak_ref_clear (&weak3); + + /* unset dynamic_weak... */ + g_weak_ref_set (dynamic_weak, NULL); + g_assert_null (g_weak_ref_get (dynamic_weak)); + + /* initializing a weak reference to an object that had before works */ + g_weak_ref_set (dynamic_weak, obj2); + tmp = g_weak_ref_get (dynamic_weak); + g_assert_true (tmp == obj2); + g_assert_cmpint (obj2->ref_count, ==, 2); + g_object_unref (tmp); + g_assert_cmpint (obj2->ref_count, ==, 1); + + /* clear and free dynamic_weak... */ + g_weak_ref_clear (dynamic_weak); + + /* ... to prove that doing so stops this from being a use-after-free */ + g_object_unref (obj2); + g_free (dynamic_weak); +} + +G_DECLARE_FINAL_TYPE (WeakReffedObject, weak_reffed_object, + WEAK, REFFED_OBJECT, GObject) + +struct _WeakReffedObject +{ + GObject parent; + + GWeakRef *weak_ref; +}; + +G_DEFINE_TYPE (WeakReffedObject, weak_reffed_object, G_TYPE_OBJECT) + +static void +weak_reffed_object_dispose (GObject *object) +{ + WeakReffedObject *weak_reffed = WEAK_REFFED_OBJECT (object); + + g_assert_cmpint (object->ref_count, ==, 1); + + g_weak_ref_set (weak_reffed->weak_ref, object); + + G_OBJECT_CLASS (weak_reffed_object_parent_class)->dispose (object); + + g_assert_null (g_weak_ref_get (weak_reffed->weak_ref)); +} + +static void +weak_reffed_object_init (WeakReffedObject *connector) +{ +} + +static void +weak_reffed_object_class_init (WeakReffedObjectClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = weak_reffed_object_dispose; +} + +static void +test_weak_ref_on_dispose (void) +{ + WeakReffedObject *obj; + GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } }; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2390"); + g_test_summary ("Test that a weak ref set during dispose vfunc is cleared"); + + g_weak_ref_init (&weak, NULL); + + obj = g_object_new (weak_reffed_object_get_type (), NULL); + obj->weak_ref = &weak; + + g_assert_cmpint (G_OBJECT (obj)->ref_count, ==, 1); + g_clear_object (&obj); + + g_assert_null (g_weak_ref_get (&weak)); +} + +static void +test_weak_ref_on_run_dispose (void) +{ + GObject *obj; + GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } }; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/865"); + g_test_summary ("Test that a weak ref is cleared on g_object_run_dispose()"); + + obj = g_object_new (G_TYPE_OBJECT, NULL); + g_weak_ref_init (&weak, obj); + + g_assert_true (obj == g_weak_ref_get (&weak)); + g_object_unref (obj); + + g_object_run_dispose (obj); + g_assert_null (g_weak_ref_get (&weak)); + + g_clear_object (&obj); + g_assert_null (g_weak_ref_get (&weak)); +} + +static void +on_weak_ref_toggle_notify (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + GWeakRef *weak = data; + + if (is_last_ref) + g_weak_ref_set (weak, object); +} + +static void +on_weak_ref_toggle_notify_disposed (gpointer data, + GObject *object) +{ + g_assert_cmpint (object->ref_count, ==, 1); + + g_object_ref (object); + g_object_unref (object); +} + +static void +test_weak_ref_on_toggle_notify (void) +{ + GObject *obj; + GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } }; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2390"); + g_test_summary ("Test that a weak ref set on toggle notify is cleared"); + + g_weak_ref_init (&weak, NULL); + + obj = g_object_new (G_TYPE_OBJECT, NULL); + g_object_add_toggle_ref (obj, on_weak_ref_toggle_notify, &weak); + g_object_weak_ref (obj, on_weak_ref_toggle_notify_disposed, NULL); + g_object_unref (obj); + + g_assert_cmpint (obj->ref_count, ==, 1); + g_clear_object (&obj); + + g_assert_null (g_weak_ref_get (&weak)); +} + +typedef struct +{ + gboolean should_be_last; + gint count; +} Count; + +static void +toggle_notify (gpointer data, + GObject *obj, + gboolean is_last) +{ + Count *c = data; + + g_assert (is_last == c->should_be_last); + + c->count++; +} + +static void +test_toggle_ref (void) +{ + GObject *obj; + Count c, c2; + + obj = g_object_new (G_TYPE_OBJECT, NULL); + + g_object_add_toggle_ref (obj, toggle_notify, &c); + g_object_add_toggle_ref (obj, toggle_notify, &c2); + + c.should_be_last = c2.should_be_last = TRUE; + c.count = c2.count = 0; + + g_object_unref (obj); + + g_assert_cmpint (c.count, ==, 0); + g_assert_cmpint (c2.count, ==, 0); + + g_object_ref (obj); + + g_assert_cmpint (c.count, ==, 0); + g_assert_cmpint (c2.count, ==, 0); + + g_object_remove_toggle_ref (obj, toggle_notify, &c2); + + g_object_unref (obj); + + g_assert_cmpint (c.count, ==, 1); + + c.should_be_last = FALSE; + + g_object_ref (obj); + + g_assert_cmpint (c.count, ==, 2); + + c.should_be_last = TRUE; + + g_object_unref (obj); + + g_assert_cmpint (c.count, ==, 3); + + g_object_remove_toggle_ref (obj, toggle_notify, &c); +} + +static gboolean global_destroyed; +static gint global_value; + +static void +data_destroy (gpointer data) +{ + g_assert_cmpint (GPOINTER_TO_INT (data), ==, global_value); + + global_destroyed = TRUE; +} + +static void +test_object_qdata (void) +{ + GObject *obj; + gpointer v; + GQuark quark; + + obj = g_object_new (G_TYPE_OBJECT, NULL); + + global_value = 1; + global_destroyed = FALSE; + g_object_set_data_full (obj, "test", GINT_TO_POINTER (1), data_destroy); + v = g_object_get_data (obj, "test"); + g_assert_cmpint (GPOINTER_TO_INT (v), ==, 1); + g_object_set_data_full (obj, "test", GINT_TO_POINTER (2), data_destroy); + g_assert (global_destroyed); + global_value = 2; + global_destroyed = FALSE; + v = g_object_steal_data (obj, "test"); + g_assert_cmpint (GPOINTER_TO_INT (v), ==, 2); + g_assert (!global_destroyed); + + global_value = 1; + global_destroyed = FALSE; + quark = g_quark_from_string ("test"); + g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (1), data_destroy); + v = g_object_get_qdata (obj, quark); + g_assert_cmpint (GPOINTER_TO_INT (v), ==, 1); + g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (2), data_destroy); + g_assert (global_destroyed); + global_value = 2; + global_destroyed = FALSE; + v = g_object_steal_qdata (obj, quark); + g_assert_cmpint (GPOINTER_TO_INT (v), ==, 2); + g_assert (!global_destroyed); + + g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (3), data_destroy); + global_value = 3; + global_destroyed = FALSE; + g_object_unref (obj); + + g_assert (global_destroyed); +} + +typedef struct { + const gchar *value; + gint refcount; +} Value; + +static gpointer +ref_value (gpointer value, gpointer user_data) +{ + Value *v = value; + Value **old_value_p = user_data; + + if (old_value_p) + *old_value_p = v; + + if (v) + v->refcount += 1; + + return value; +} + +static void +unref_value (gpointer value) +{ + Value *v = value; + + v->refcount -= 1; + if (v->refcount == 0) + g_free (value); +} + +static +Value * +new_value (const gchar *s) +{ + Value *v; + + v = g_new (Value, 1); + v->value = s; + v->refcount = 1; + + return v; +} + +static void +test_object_qdata2 (void) +{ + GObject *obj; + Value *v, *v1, *v2, *v3, *old_val; + GDestroyNotify old_destroy; + gboolean res; + + obj = g_object_new (G_TYPE_OBJECT, NULL); + + v1 = new_value ("bla"); + + g_object_set_data_full (obj, "test", v1, unref_value); + + v = g_object_get_data (obj, "test"); + g_assert_cmpstr (v->value, ==, "bla"); + g_assert_cmpint (v->refcount, ==, 1); + + v = g_object_dup_data (obj, "test", ref_value, &old_val); + g_assert (old_val == v1); + g_assert_cmpstr (v->value, ==, "bla"); + g_assert_cmpint (v->refcount, ==, 2); + unref_value (v); + + v = g_object_dup_data (obj, "nono", ref_value, &old_val); + g_assert (old_val == NULL); + g_assert (v == NULL); + + v2 = new_value ("not"); + + res = g_object_replace_data (obj, "test", v1, v2, unref_value, &old_destroy); + g_assert (res == TRUE); + g_assert (old_destroy == unref_value); + g_assert_cmpstr (v1->value, ==, "bla"); + g_assert_cmpint (v1->refcount, ==, 1); + + v = g_object_get_data (obj, "test"); + g_assert_cmpstr (v->value, ==, "not"); + g_assert_cmpint (v->refcount, ==, 1); + + v3 = new_value ("xyz"); + res = g_object_replace_data (obj, "test", v1, v3, unref_value, &old_destroy); + g_assert (res == FALSE); + g_assert_cmpstr (v2->value, ==, "not"); + g_assert_cmpint (v2->refcount, ==, 1); + + unref_value (v1); + + res = g_object_replace_data (obj, "test", NULL, v3, unref_value, &old_destroy); + g_assert (res == FALSE); + g_assert_cmpstr (v2->value, ==, "not"); + g_assert_cmpint (v2->refcount, ==, 1); + + res = g_object_replace_data (obj, "test", v2, NULL, unref_value, &old_destroy); + g_assert (res == TRUE); + g_assert (old_destroy == unref_value); + g_assert_cmpstr (v2->value, ==, "not"); + g_assert_cmpint (v2->refcount, ==, 1); + + unref_value (v2); + + v = g_object_get_data (obj, "test"); + g_assert (v == NULL); + + res = g_object_replace_data (obj, "test", NULL, v3, unref_value, &old_destroy); + g_assert (res == TRUE); + + v = g_object_get_data (obj, "test"); + g_assert (v == v3); + + ref_value (v3, NULL); + g_assert_cmpint (v3->refcount, ==, 2); + g_object_unref (obj); + g_assert_cmpint (v3->refcount, ==, 1); + unref_value (v3); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/type/fundamentals", test_fundamentals); + g_test_add_func ("/type/qdata", test_type_qdata); + g_test_add_func ("/type/query", test_type_query); + g_test_add_func ("/type/class-private", test_class_private); + g_test_add_func ("/object/clear", test_clear); + g_test_add_func ("/object/clear-function", test_clear_function); + g_test_add_func ("/object/set", test_set); + g_test_add_func ("/object/set-function", test_set_function); + g_test_add_func ("/object/set/derived-type", test_set_derived_type); + g_test_add_func ("/object/value", test_object_value); + g_test_add_func ("/object/initially-unowned", test_initially_unowned); + g_test_add_func ("/object/weak-pointer", test_weak_pointer); + g_test_add_func ("/object/weak-pointer/clear", test_weak_pointer_clear); + g_test_add_func ("/object/weak-pointer/clear-function", test_weak_pointer_clear_function); + g_test_add_func ("/object/weak-pointer/set", test_weak_pointer_set); + g_test_add_func ("/object/weak-pointer/set-function", test_weak_pointer_set_function); + g_test_add_func ("/object/weak-ref", test_weak_ref); + g_test_add_func ("/object/weak-ref/on-dispose", test_weak_ref_on_dispose); + g_test_add_func ("/object/weak-ref/on-run-dispose", test_weak_ref_on_run_dispose); + g_test_add_func ("/object/weak-ref/on-toggle-notify", test_weak_ref_on_toggle_notify); + g_test_add_func ("/object/toggle-ref", test_toggle_ref); + g_test_add_func ("/object/qdata", test_object_qdata); + g_test_add_func ("/object/qdata2", test_object_qdata2); + + return g_test_run (); +} diff --git a/gobject/tests/signal-handler.c b/gobject/tests/signal-handler.c new file mode 100644 index 0000000..7a236ee --- /dev/null +++ b/gobject/tests/signal-handler.c @@ -0,0 +1,299 @@ +#include + +typedef struct { + GObject instance; +} MyObj; + +typedef struct { + GObjectClass parent_class; +} MyObjClass; + +enum { + SIGNAL1, + SIGNAL2, + LAST_SIGNAL +}; + +guint signals[LAST_SIGNAL]; + +GType my_obj_get_type (void); + +G_DEFINE_TYPE (MyObj, my_obj, G_TYPE_OBJECT) + +static void +my_obj_init (MyObj *o) +{ +} + +static void +my_obj_class_init (MyObjClass *class) +{ + signals[SIGNAL1] = + g_signal_new ("signal1", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[SIGNAL2] = + g_signal_new ("signal2", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); +} + +static void +nop (void) +{ +} + +#define HANDLERS 500000 + +static void +test_connect_many (void) +{ + MyObj *o; + gdouble time_elapsed; + gint i; + + o = g_object_new (my_obj_get_type (), NULL); + + g_test_timer_start (); + + for (i = 0; i < HANDLERS; i++) + g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); + + time_elapsed = g_test_timer_elapsed (); + + g_object_unref (o); + + g_test_minimized_result (time_elapsed, "connected %u handlers in %6.3f seconds", HANDLERS, time_elapsed); +} + +static void +test_disconnect_many_ordered (void) +{ + MyObj *o; + gulong handlers[HANDLERS]; + gdouble time_elapsed; + gint i; + + o = g_object_new (my_obj_get_type (), NULL); + + for (i = 0; i < HANDLERS; i++) + handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); + + g_test_timer_start (); + + for (i = 0; i < HANDLERS; i++) + g_signal_handler_disconnect (o, handlers[i]); + + time_elapsed = g_test_timer_elapsed (); + + g_object_unref (o); + + g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", HANDLERS, time_elapsed); +} + +static void +test_disconnect_many_inverse (void) +{ + MyObj *o; + gulong handlers[HANDLERS]; + gdouble time_elapsed; + gint i; + + o = g_object_new (my_obj_get_type (), NULL); + + for (i = 0; i < HANDLERS; i++) + handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); + + g_test_timer_start (); + + for (i = HANDLERS - 1; i >= 0; i--) + g_signal_handler_disconnect (o, handlers[i]); + + time_elapsed = g_test_timer_elapsed (); + + g_object_unref (o); + + g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", HANDLERS, time_elapsed); +} + +static void +test_disconnect_many_random (void) +{ + MyObj *o; + gulong handlers[HANDLERS]; + gulong id; + gdouble time_elapsed; + gint i, j; + + o = g_object_new (my_obj_get_type (), NULL); + + for (i = 0; i < HANDLERS; i++) + handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); + + for (i = 0; i < HANDLERS; i++) + { + j = g_test_rand_int_range (0, HANDLERS); + id = handlers[i]; + handlers[i] = handlers[j]; + handlers[j] = id; + } + + g_test_timer_start (); + + for (i = 0; i < HANDLERS; i++) + g_signal_handler_disconnect (o, handlers[i]); + + time_elapsed = g_test_timer_elapsed (); + + g_object_unref (o); + + g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", HANDLERS, time_elapsed); +} + +static void +test_disconnect_2_signals (void) +{ + MyObj *o; + gulong handlers[HANDLERS]; + gulong id; + gdouble time_elapsed; + gint i, j; + + o = g_object_new (my_obj_get_type (), NULL); + + for (i = 0; i < HANDLERS; i++) + { + if (i % 2 == 0) + handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); + else + handlers[i] = g_signal_connect (o, "signal2", G_CALLBACK (nop), NULL); + } + + for (i = 0; i < HANDLERS; i++) + { + j = g_test_rand_int_range (0, HANDLERS); + id = handlers[i]; + handlers[i] = handlers[j]; + handlers[j] = id; + } + + g_test_timer_start (); + + for (i = 0; i < HANDLERS; i++) + g_signal_handler_disconnect (o, handlers[i]); + + time_elapsed = g_test_timer_elapsed (); + + g_object_unref (o); + + g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", HANDLERS, time_elapsed); +} + +static void +test_disconnect_2_objects (void) +{ + MyObj *o1, *o2, *o; + gulong handlers[HANDLERS]; + MyObj *objects[HANDLERS]; + gulong id; + gdouble time_elapsed; + gint i, j; + + o1 = g_object_new (my_obj_get_type (), NULL); + o2 = g_object_new (my_obj_get_type (), NULL); + + for (i = 0; i < HANDLERS; i++) + { + if (i % 2 == 0) + { + handlers[i] = g_signal_connect (o1, "signal1", G_CALLBACK (nop), NULL); + objects[i] = o1; + } + else + { + handlers[i] = g_signal_connect (o2, "signal1", G_CALLBACK (nop), NULL); + objects[i] = o2; + } + } + + for (i = 0; i < HANDLERS; i++) + { + j = g_test_rand_int_range (0, HANDLERS); + id = handlers[i]; + handlers[i] = handlers[j]; + handlers[j] = id; + o = objects[i]; + objects[i] = objects[j]; + objects[j] = o; + } + + g_test_timer_start (); + + for (i = 0; i < HANDLERS; i++) + g_signal_handler_disconnect (objects[i], handlers[i]); + + time_elapsed = g_test_timer_elapsed (); + + g_object_unref (o1); + g_object_unref (o2); + + g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", HANDLERS, time_elapsed); +} + +static void +test_block_many (void) +{ + MyObj *o; + gulong handlers[HANDLERS]; + gulong id; + gdouble time_elapsed; + gint i, j; + + o = g_object_new (my_obj_get_type (), NULL); + + for (i = 0; i < HANDLERS; i++) + handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); + + for (i = 0; i < HANDLERS; i++) + { + j = g_test_rand_int_range (0, HANDLERS); + id = handlers[i]; + handlers[i] = handlers[j]; + handlers[j] = id; + } + + g_test_timer_start (); + + for (i = 0; i < HANDLERS; i++) + g_signal_handler_block (o, handlers[i]); + + for (i = HANDLERS - 1; i >= 0; i--) + g_signal_handler_unblock (o, handlers[i]); + + time_elapsed = g_test_timer_elapsed (); + + g_object_unref (o); + + g_test_minimized_result (time_elapsed, "blocked and unblocked %u handlers in %6.3f seconds", HANDLERS, time_elapsed); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + if (g_test_perf ()) + { + g_test_add_func ("/signal/handler/connect-many", test_connect_many); + g_test_add_func ("/signal/handler/disconnect-many-ordered", test_disconnect_many_ordered); + g_test_add_func ("/signal/handler/disconnect-many-inverse", test_disconnect_many_inverse); + g_test_add_func ("/signal/handler/disconnect-many-random", test_disconnect_many_random); + g_test_add_func ("/signal/handler/disconnect-2-signals", test_disconnect_2_signals); + g_test_add_func ("/signal/handler/disconnect-2-objects", test_disconnect_2_objects); + g_test_add_func ("/signal/handler/block-many", test_block_many); + } + + return g_test_run (); +} diff --git a/gobject/tests/signalgroup.c b/gobject/tests/signalgroup.c new file mode 100644 index 0000000..5d1f17a --- /dev/null +++ b/gobject/tests/signalgroup.c @@ -0,0 +1,650 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * + * Copyright (C) 2015-2022 Christian Hergert + * Copyright (C) 2015 Garrett Regier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include + +G_DECLARE_FINAL_TYPE (SignalTarget, signal_target, TEST, SIGNAL_TARGET, GObject) + +struct _SignalTarget +{ + GObject parent_instance; +}; + +G_DEFINE_TYPE (SignalTarget, signal_target, G_TYPE_OBJECT) + +static G_DEFINE_QUARK (detail, signal_detail); + +enum { + THE_SIGNAL, + NEVER_EMITTED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +static void +signal_target_class_init (SignalTargetClass *klass) +{ + signals[THE_SIGNAL] = + g_signal_new ("the-signal", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); + + signals[NEVER_EMITTED] = + g_signal_new ("never-emitted", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); +} + +static void +signal_target_init (SignalTarget *self) +{ +} + +static gint global_signal_calls; +static gint global_weak_notify_called; + +static void +connect_before_cb (SignalTarget *target, + GSignalGroup *group, + gint *signal_calls) +{ + SignalTarget *readback; + + g_assert_true (TEST_IS_SIGNAL_TARGET (target)); + g_assert_true (G_IS_SIGNAL_GROUP (group)); + g_assert_nonnull (signal_calls); + g_assert_true (signal_calls == &global_signal_calls); + + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target); + g_object_unref (readback); + + *signal_calls += 1; +} + +static void +connect_after_cb (SignalTarget *target, + GSignalGroup *group, + gint *signal_calls) +{ + SignalTarget *readback; + + g_assert_true (TEST_IS_SIGNAL_TARGET (target)); + g_assert_true (G_IS_SIGNAL_GROUP (group)); + g_assert_nonnull (signal_calls); + g_assert_true (signal_calls == &global_signal_calls); + + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target); + g_object_unref (readback); + + g_assert_cmpint (*signal_calls, ==, 4); + *signal_calls += 1; +} + +static void +connect_swapped_cb (gint *signal_calls, + GSignalGroup *group, + SignalTarget *target) +{ + SignalTarget *readback; + + g_assert_true (signal_calls != NULL); + g_assert_true (signal_calls == &global_signal_calls); + g_assert_true (G_IS_SIGNAL_GROUP (group)); + g_assert_true (TEST_IS_SIGNAL_TARGET (target)); + + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target); + g_object_unref (readback); + + *signal_calls += 1; +} + +static void +connect_object_cb (SignalTarget *target, + GSignalGroup *group, + GObject *object) +{ + SignalTarget *readback; + gint *signal_calls; + + g_assert_true (TEST_IS_SIGNAL_TARGET (target)); + g_assert_true (G_IS_SIGNAL_GROUP (group)); + g_assert_true (G_IS_OBJECT (object)); + + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target); + g_object_unref (readback); + + signal_calls = g_object_get_data (object, "signal-calls"); + g_assert_nonnull (signal_calls); + g_assert_true (signal_calls == &global_signal_calls); + + *signal_calls += 1; +} + +static void +connect_bad_detail_cb (SignalTarget *target, + GSignalGroup *group, + GObject *object) +{ + g_error ("This detailed signal is never emitted!"); +} + +static void +connect_never_emitted_cb (SignalTarget *target, + gboolean *weak_notify_called) +{ + g_error ("This signal is never emitted!"); +} + +static void +connect_data_notify_cb (gboolean *weak_notify_called, + GClosure *closure) +{ + g_assert_nonnull (weak_notify_called); + g_assert_true (weak_notify_called == &global_weak_notify_called); + g_assert_nonnull (closure); + + g_assert_false (*weak_notify_called); + *weak_notify_called = TRUE; +} + +static void +connect_data_weak_notify_cb (gboolean *weak_notify_called, + GSignalGroup *group) +{ + g_assert_nonnull (weak_notify_called); + g_assert_true (weak_notify_called == &global_weak_notify_called); + g_assert_true (G_IS_SIGNAL_GROUP (group)); + + g_assert_true (*weak_notify_called); +} + +static void +connect_all_signals (GSignalGroup *group) +{ + GObject *object; + + /* Check that these are called in the right order */ + g_signal_group_connect (group, + "the-signal", + G_CALLBACK (connect_before_cb), + &global_signal_calls); + g_signal_group_connect_after (group, + "the-signal", + G_CALLBACK (connect_after_cb), + &global_signal_calls); + + /* Check that this is called with the arguments swapped */ + g_signal_group_connect_swapped (group, + "the-signal", + G_CALLBACK (connect_swapped_cb), + &global_signal_calls); + + /* Check that this is called with the arguments swapped */ + object = g_object_new (G_TYPE_OBJECT, NULL); + g_object_set_data (object, "signal-calls", &global_signal_calls); + g_signal_group_connect_object (group, + "the-signal", + G_CALLBACK (connect_object_cb), + object, + 0); + g_object_weak_ref (G_OBJECT (group), + (GWeakNotify)g_object_unref, + object); + + /* Check that a detailed signal is handled correctly */ + g_signal_group_connect (group, + "the-signal::detail", + G_CALLBACK (connect_before_cb), + &global_signal_calls); + g_signal_group_connect (group, + "the-signal::bad-detail", + G_CALLBACK (connect_bad_detail_cb), + NULL); + + /* Check that the notify is called correctly */ + global_weak_notify_called = FALSE; + g_signal_group_connect_data (group, + "never-emitted", + G_CALLBACK (connect_never_emitted_cb), + &global_weak_notify_called, + (GClosureNotify)connect_data_notify_cb, + 0); + g_object_weak_ref (G_OBJECT (group), + (GWeakNotify)connect_data_weak_notify_cb, + &global_weak_notify_called); +} + +static void +assert_signals (SignalTarget *target, + GSignalGroup *group, + gboolean success) +{ + g_assert (TEST_IS_SIGNAL_TARGET (target)); + g_assert (group == NULL || G_IS_SIGNAL_GROUP (group)); + + global_signal_calls = 0; + g_signal_emit (target, signals[THE_SIGNAL], + signal_detail_quark (), group); + g_assert_cmpint (global_signal_calls, ==, success ? 5 : 0); +} + +static void +dummy_handler (void) +{ +} + +static void +test_signal_group_invalid (void) +{ + GObject *invalid_target = g_object_new (G_TYPE_OBJECT, NULL); + SignalTarget *target = g_object_new (signal_target_get_type (), NULL); + GSignalGroup *group = g_signal_group_new (signal_target_get_type ()); + + /* Invalid Target Type */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*g_type_is_a*G_TYPE_OBJECT*"); + g_signal_group_new (G_TYPE_DATE_TIME); + g_test_assert_expected_messages (); + + /* Invalid Target */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*Failed to set GSignalGroup of target type SignalTarget using target * of type GObject*"); + g_signal_group_set_target (group, invalid_target); + g_assert_finalize_object (group); + g_test_assert_expected_messages (); + + /* Invalid Signal Name */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*g_signal_parse_name*"); + group = g_signal_group_new (signal_target_get_type ()); + g_signal_group_connect (group, + "does-not-exist", + G_CALLBACK (connect_before_cb), + NULL); + g_test_assert_expected_messages (); + g_assert_finalize_object (group); + + /* Invalid Callback */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*c_handler != NULL*"); + group = g_signal_group_new (signal_target_get_type ()); + g_signal_group_connect (group, + "the-signal", + G_CALLBACK (NULL), + NULL); + g_test_assert_expected_messages (); + g_assert_finalize_object (group); + + /* Connecting after setting target */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*Cannot add signals after setting target*"); + group = g_signal_group_new (signal_target_get_type ()); + g_signal_group_set_target (group, target); + g_signal_group_connect (group, + "the-signal", + G_CALLBACK (dummy_handler), + NULL); + g_test_assert_expected_messages (); + g_assert_finalize_object (group); + + g_assert_finalize_object (target); + g_assert_finalize_object (invalid_target); +} + +static void +test_signal_group_simple (void) +{ + SignalTarget *target; + GSignalGroup *group; + SignalTarget *readback; + + /* Set the target before connecting the signals */ + group = g_signal_group_new (signal_target_get_type ()); + target = g_object_new (signal_target_get_type (), NULL); + g_assert_null (g_signal_group_dup_target (group)); + g_signal_group_set_target (group, target); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target); + g_object_unref (readback); + g_assert_finalize_object (group); + assert_signals (target, NULL, FALSE); + g_assert_finalize_object (target); + + group = g_signal_group_new (signal_target_get_type ()); + target = g_object_new (signal_target_get_type (), NULL); + connect_all_signals (group); + g_signal_group_set_target (group, target); + assert_signals (target, group, TRUE); + g_assert_finalize_object (target); + g_assert_finalize_object (group); +} + +static void +test_signal_group_changing_target (void) +{ + SignalTarget *target1, *target2; + GSignalGroup *group = g_signal_group_new (signal_target_get_type ()); + SignalTarget *readback; + + connect_all_signals (group); + g_assert_null (g_signal_group_dup_target (group)); + + /* Set the target after connecting the signals */ + target1 = g_object_new (signal_target_get_type (), NULL); + g_signal_group_set_target (group, target1); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target1); + g_object_unref (readback); + + assert_signals (target1, group, TRUE); + + /* Set the same target */ + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target1); + g_object_unref (readback); + g_signal_group_set_target (group, target1); + + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target1); + g_object_unref (readback); + + assert_signals (target1, group, TRUE); + + /* Set a new target when the current target is non-NULL */ + target2 = g_object_new (signal_target_get_type (), NULL); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target1); + g_object_unref (readback); + + g_signal_group_set_target (group, target2); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target2); + g_object_unref (readback); + + assert_signals (target2, group, TRUE); + + g_assert_finalize_object (target2); + g_assert_finalize_object (target1); + g_assert_finalize_object (group); +} + +static void +assert_blocking (SignalTarget *target, + GSignalGroup *group, + gint count) +{ + gint i; + + assert_signals (target, group, TRUE); + + /* Assert that multiple blocks are effective */ + for (i = 0; i < count; ++i) + { + g_signal_group_block (group); + assert_signals (target, group, FALSE); + } + + /* Assert that the signal is not emitted after the first unblock */ + for (i = 0; i < count; ++i) + { + assert_signals (target, group, FALSE); + g_signal_group_unblock (group); + } + + assert_signals (target, group, TRUE); +} + +static void +test_signal_group_blocking (void) +{ + SignalTarget *target1, *target2, *readback; + GSignalGroup *group = g_signal_group_new (signal_target_get_type ()); + + /* Test blocking and unblocking null target */ + g_signal_group_block (group); + g_signal_group_unblock (group); + + connect_all_signals (group); + g_assert_null (g_signal_group_dup_target (group)); + + target1 = g_object_new (signal_target_get_type (), NULL); + g_signal_group_set_target (group, target1); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target1); + g_object_unref (readback); + + assert_blocking (target1, group, 1); + assert_blocking (target1, group, 3); + assert_blocking (target1, group, 15); + + /* Assert that blocking transfers across changing the target */ + g_signal_group_block (group); + g_signal_group_block (group); + + /* Set a new target when the current target is non-NULL */ + target2 = g_object_new (signal_target_get_type (), NULL); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target1); + g_object_unref (readback); + g_signal_group_set_target (group, target2); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target2); + g_object_unref (readback); + + assert_signals (target2, group, FALSE); + g_signal_group_unblock (group); + assert_signals (target2, group, FALSE); + g_signal_group_unblock (group); + assert_signals (target2, group, TRUE); + + g_assert_finalize_object (target2); + g_assert_finalize_object (target1); + g_assert_finalize_object (group); +} + +static void +test_signal_group_weak_ref_target (void) +{ + SignalTarget *target = g_object_new (signal_target_get_type (), NULL); + GSignalGroup *group = g_signal_group_new (signal_target_get_type ()); + SignalTarget *readback; + + g_assert_null (g_signal_group_dup_target (group)); + g_signal_group_set_target (group, target); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target); + g_object_unref (readback); + + g_assert_finalize_object (target); + g_assert_null (g_signal_group_dup_target (group)); + g_assert_finalize_object (group); +} + +static void +test_signal_group_connect_object (void) +{ + GObject *object = g_object_new (G_TYPE_OBJECT, NULL); + SignalTarget *target = g_object_new (signal_target_get_type (), NULL); + GSignalGroup *group = g_signal_group_new (signal_target_get_type ()); + SignalTarget *readback; + + /* We already do basic connect_object() tests in connect_signals(), + * this is only needed to test the specifics of connect_object() + */ + g_signal_group_connect_object (group, + "the-signal", + G_CALLBACK (connect_object_cb), + object, + 0); + + g_assert_null (g_signal_group_dup_target (group)); + g_signal_group_set_target (group, target); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target); + g_object_unref (readback); + + g_assert_finalize_object (object); + + /* This would cause a warning if the SignalGroup did not + * have a weakref on the object as it would try to connect again + */ + g_signal_group_set_target (group, NULL); + g_assert_null (g_signal_group_dup_target (group)); + g_signal_group_set_target (group, target); + readback = g_signal_group_dup_target (group); + g_assert_true (readback == target); + g_object_unref (readback); + + g_assert_finalize_object (group); + g_assert_finalize_object (target); +} + +static void +test_signal_group_signal_parsing (void) +{ + g_test_trap_subprocess ("/GObject/SignalGroup/signal-parsing/subprocess", 0, + G_TEST_SUBPROCESS_INHERIT_STDERR); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr (""); +} + +static void +test_signal_group_signal_parsing_subprocess (void) +{ + GSignalGroup *group; + + /* Check that the class has not been created and with it the + * signals registered. This will cause g_signal_parse_name() + * to fail unless GSignalGroup calls g_type_class_ref(). + */ + g_assert_null (g_type_class_peek (signal_target_get_type ())); + + group = g_signal_group_new (signal_target_get_type ()); + g_signal_group_connect (group, + "the-signal", + G_CALLBACK (connect_before_cb), + NULL); + + g_assert_finalize_object (group); +} + +static void +test_signal_group_properties (void) +{ + GSignalGroup *group; + SignalTarget *target, *other; + GType gtype; + + group = g_signal_group_new (signal_target_get_type ()); + g_object_get (group, + "target", &target, + "target-type", >ype, + NULL); + g_assert_cmpint (gtype, ==, signal_target_get_type ()); + g_assert_null (target); + + target = g_object_new (signal_target_get_type (), NULL); + g_object_set (group, "target", target, NULL); + g_object_get (group, "target", &other, NULL); + g_assert_true (target == other); + g_object_unref (other); + + g_assert_finalize_object (target); + g_assert_null (g_signal_group_dup_target (group)); + g_assert_finalize_object (group); +} + +G_DECLARE_INTERFACE (SignalThing, signal_thing, SIGNAL, THING, GObject) + +struct _SignalThingInterface +{ + GTypeInterface iface; + void (*changed) (SignalThing *thing); +}; + +G_DEFINE_INTERFACE (SignalThing, signal_thing, G_TYPE_OBJECT) + +static guint signal_thing_changed; + +static void +signal_thing_default_init (SignalThingInterface *iface) +{ + signal_thing_changed = + g_signal_new ("changed", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (SignalThingInterface, changed), + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +G_GNUC_NORETURN static void +thing_changed_cb (SignalThing *thing, + gpointer user_data G_GNUC_UNUSED) +{ + g_assert_not_reached (); +} + +static void +test_signal_group_interface (void) +{ + GSignalGroup *group; + + group = g_signal_group_new (signal_thing_get_type ()); + g_signal_group_connect (group, + "changed", + G_CALLBACK (thing_changed_cb), + NULL); + g_assert_finalize_object (group); +} + +gint +main (gint argc, + gchar *argv[]) +{ + g_test_init (&argc, &argv, NULL); + g_test_add_func ("/GObject/SignalGroup/invalid", test_signal_group_invalid); + g_test_add_func ("/GObject/SignalGroup/simple", test_signal_group_simple); + g_test_add_func ("/GObject/SignalGroup/changing-target", test_signal_group_changing_target); + g_test_add_func ("/GObject/SignalGroup/blocking", test_signal_group_blocking); + g_test_add_func ("/GObject/SignalGroup/weak-ref-target", test_signal_group_weak_ref_target); + g_test_add_func ("/GObject/SignalGroup/connect-object", test_signal_group_connect_object); + g_test_add_func ("/GObject/SignalGroup/signal-parsing", test_signal_group_signal_parsing); + g_test_add_func ("/GObject/SignalGroup/signal-parsing/subprocess", test_signal_group_signal_parsing_subprocess); + g_test_add_func ("/GObject/SignalGroup/properties", test_signal_group_properties); + g_test_add_func ("/GObject/SignalGroup/interface", test_signal_group_interface); + return g_test_run (); +} diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c new file mode 100644 index 0000000..ea9a778 --- /dev/null +++ b/gobject/tests/signals.c @@ -0,0 +1,1828 @@ +#include +#include "marshalers.h" + +#define g_assert_cmpflags(type,n1, cmp, n2) G_STMT_START { \ + type __n1 = (n1), __n2 = (n2); \ + if (__n1 cmp __n2) ; else \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); \ + } G_STMT_END +#define g_assert_cmpenum(type,n1, cmp, n2) G_STMT_START { \ + type __n1 = (n1), __n2 = (n2); \ + if (__n1 cmp __n2) ; else \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); \ + } G_STMT_END + +typedef enum { + TEST_ENUM_NEGATIVE = -30, + TEST_ENUM_NONE = 0, + TEST_ENUM_FOO = 1, + TEST_ENUM_BAR = 2 +} TestEnum; + +typedef enum { + TEST_UNSIGNED_ENUM_FOO = 1, + TEST_UNSIGNED_ENUM_BAR = 42 + /* Don't test 0x80000000 for now- nothing appears to do this in + * practice, and it triggers GValue/GEnum bugs on ppc64. + */ +} TestUnsignedEnum; + +static void +custom_marshal_VOID__INVOCATIONHINT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INVOCATIONHINT) (gpointer data1, + gpointer invocation_hint, + gpointer data2); + GMarshalFunc_VOID__INVOCATIONHINT callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; + + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INVOCATIONHINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + invocation_hint, + data2); +} + +static GType +test_enum_get_type (void) +{ + static gsize static_g_define_type_id = 0; + + if (g_once_init_enter (&static_g_define_type_id)) + { + static const GEnumValue values[] = { + { TEST_ENUM_NEGATIVE, "TEST_ENUM_NEGATIVE", "negative" }, + { TEST_ENUM_NONE, "TEST_ENUM_NONE", "none" }, + { TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" }, + { TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("TestEnum"), values); + g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + + return static_g_define_type_id; +} + +static GType +test_unsigned_enum_get_type (void) +{ + static gsize static_g_define_type_id = 0; + + if (g_once_init_enter (&static_g_define_type_id)) + { + static const GEnumValue values[] = { + { TEST_UNSIGNED_ENUM_FOO, "TEST_UNSIGNED_ENUM_FOO", "foo" }, + { TEST_UNSIGNED_ENUM_BAR, "TEST_UNSIGNED_ENUM_BAR", "bar" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("TestUnsignedEnum"), values); + g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + + return static_g_define_type_id; +} + +typedef enum { + MY_ENUM_VALUE = 1, +} MyEnum; + +static const GEnumValue my_enum_values[] = +{ + { MY_ENUM_VALUE, "the first value", "one" }, + { 0, NULL, NULL } +}; + +typedef enum { + MY_FLAGS_FIRST_BIT = (1 << 0), + MY_FLAGS_THIRD_BIT = (1 << 2), + MY_FLAGS_LAST_BIT = (1 << 31) +} MyFlags; + +static const GFlagsValue my_flag_values[] = +{ + { MY_FLAGS_FIRST_BIT, "the first bit", "first-bit" }, + { MY_FLAGS_THIRD_BIT, "the third bit", "third-bit" }, + { MY_FLAGS_LAST_BIT, "the last bit", "last-bit" }, + { 0, NULL, NULL } +}; + +static GType enum_type; +static GType flags_type; + +static guint simple_id; +static guint simple2_id; + +typedef struct { + GTypeInterface g_iface; +} FooInterface; + +GType foo_get_type (void); + +G_DEFINE_INTERFACE (Foo, foo, G_TYPE_OBJECT) + +static void +foo_default_init (FooInterface *iface) +{ +} + +typedef struct { + GObject parent; +} Baa; + +typedef struct { + GObjectClass parent_class; +} BaaClass; + +static void +baa_init_foo (FooInterface *iface) +{ +} + +GType baa_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (Baa, baa, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (foo_get_type (), baa_init_foo)) + +static void +baa_init (Baa *baa) +{ +} + +static void +baa_class_init (BaaClass *class) +{ +} + +typedef struct _Test Test; +typedef struct _TestClass TestClass; + +struct _Test +{ + GObject parent_instance; +}; + +static void all_types_handler (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64); +static gboolean accumulator_sum (GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer data); +static gboolean accumulator_concat_string (GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer data); +static gchar * accumulator_class (Test *test); + +struct _TestClass +{ + GObjectClass parent_class; + + void (* variant_changed) (Test *, GVariant *); + void (* all_types) (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64); + void (* all_types_null) (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64); + gchar * (*accumulator_class) (Test *test); +}; + +static GType test_get_type (void); +G_DEFINE_TYPE (Test, test, G_TYPE_OBJECT) + +static void +test_init (Test *test) +{ +} + +static void +test_class_init (TestClass *klass) +{ + guint s; + + enum_type = g_enum_register_static ("MyEnum", my_enum_values); + flags_type = g_flags_register_static ("MyFlag", my_flag_values); + + klass->all_types = all_types_handler; + klass->accumulator_class = accumulator_class; + + simple_id = g_signal_new ("simple", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 0); + g_signal_new ("simple-detailed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 0); + /* Deliberately install this one in non-canonical form to check that’s handled correctly: */ + simple2_id = g_signal_new ("simple_2", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 0); + g_signal_new ("simple-accumulator", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + accumulator_sum, NULL, + NULL, + G_TYPE_INT, + 0); + g_signal_new ("accumulator-class-first", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (TestClass, accumulator_class), + accumulator_concat_string, NULL, + NULL, + G_TYPE_STRING, + 0); + g_signal_new ("accumulator-class-last", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestClass, accumulator_class), + accumulator_concat_string, NULL, + NULL, + G_TYPE_STRING, + 0); + g_signal_new ("accumulator-class-cleanup", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_CLEANUP, + G_STRUCT_OFFSET (TestClass, accumulator_class), + accumulator_concat_string, NULL, + NULL, + G_TYPE_STRING, + 0); + g_signal_new ("accumulator-class-first-last", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestClass, accumulator_class), + accumulator_concat_string, NULL, + NULL, + G_TYPE_STRING, + 0); + g_signal_new ("accumulator-class-first-last-cleanup", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP, + G_STRUCT_OFFSET (TestClass, accumulator_class), + accumulator_concat_string, NULL, + NULL, + G_TYPE_STRING, + 0); + g_signal_new ("accumulator-class-last-cleanup", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP, + G_STRUCT_OFFSET (TestClass, accumulator_class), + accumulator_concat_string, NULL, + NULL, + G_TYPE_STRING, + 0); + g_signal_new ("generic-marshaller-1", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 7, + G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_INT, G_TYPE_LONG, G_TYPE_POINTER, G_TYPE_DOUBLE, G_TYPE_FLOAT); + g_signal_new ("generic-marshaller-2", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 5, + G_TYPE_INT, test_enum_get_type(), G_TYPE_INT, test_unsigned_enum_get_type (), G_TYPE_INT); + g_signal_new ("generic-marshaller-enum-return-signed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + test_enum_get_type(), + 0); + g_signal_new ("generic-marshaller-enum-return-unsigned", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + test_unsigned_enum_get_type(), + 0); + g_signal_new ("generic-marshaller-int-return", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_INT, + 0); + s = g_signal_new ("va-marshaller-int-return", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + test_INT__VOID, + G_TYPE_INT, + 0); + g_signal_set_va_marshaller (s, G_TYPE_FROM_CLASS (klass), + test_INT__VOIDv); + g_signal_new ("generic-marshaller-uint-return", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_UINT, + 0); + g_signal_new ("generic-marshaller-interface-return", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + foo_get_type (), + 0); + s = g_signal_new ("va-marshaller-uint-return", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + test_INT__VOID, + G_TYPE_UINT, + 0); + g_signal_set_va_marshaller (s, G_TYPE_FROM_CLASS (klass), + test_UINT__VOIDv); + g_signal_new ("custom-marshaller", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + custom_marshal_VOID__INVOCATIONHINT, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); + g_signal_new ("variant-changed-no-slot", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VARIANT, + G_TYPE_NONE, + 1, + G_TYPE_VARIANT); + g_signal_new ("variant-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT, + G_STRUCT_OFFSET (TestClass, variant_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VARIANT, + G_TYPE_NONE, + 1, + G_TYPE_VARIANT); + g_signal_new ("all-types", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestClass, all_types), + NULL, NULL, + test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64, + G_TYPE_NONE, + 19, + G_TYPE_INT, + G_TYPE_BOOLEAN, + G_TYPE_CHAR, + G_TYPE_UCHAR, + G_TYPE_UINT, + G_TYPE_LONG, + G_TYPE_ULONG, + enum_type, + flags_type, + G_TYPE_FLOAT, + G_TYPE_DOUBLE, + G_TYPE_STRING, + G_TYPE_PARAM_LONG, + G_TYPE_BYTES, + G_TYPE_POINTER, + test_get_type (), + G_TYPE_VARIANT, + G_TYPE_INT64, + G_TYPE_UINT64); + s = g_signal_new ("all-types-va", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestClass, all_types), + NULL, NULL, + test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64, + G_TYPE_NONE, + 19, + G_TYPE_INT, + G_TYPE_BOOLEAN, + G_TYPE_CHAR, + G_TYPE_UCHAR, + G_TYPE_UINT, + G_TYPE_LONG, + G_TYPE_ULONG, + enum_type, + flags_type, + G_TYPE_FLOAT, + G_TYPE_DOUBLE, + G_TYPE_STRING, + G_TYPE_PARAM_LONG, + G_TYPE_BYTES, + G_TYPE_POINTER, + test_get_type (), + G_TYPE_VARIANT, + G_TYPE_INT64, + G_TYPE_UINT64); + g_signal_set_va_marshaller (s, G_TYPE_FROM_CLASS (klass), + test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64v); + + g_signal_new ("all-types-generic", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestClass, all_types), + NULL, NULL, + NULL, + G_TYPE_NONE, + 19, + G_TYPE_INT, + G_TYPE_BOOLEAN, + G_TYPE_CHAR, + G_TYPE_UCHAR, + G_TYPE_UINT, + G_TYPE_LONG, + G_TYPE_ULONG, + enum_type, + flags_type, + G_TYPE_FLOAT, + G_TYPE_DOUBLE, + G_TYPE_STRING, + G_TYPE_PARAM_LONG, + G_TYPE_BYTES, + G_TYPE_POINTER, + test_get_type (), + G_TYPE_VARIANT, + G_TYPE_INT64, + G_TYPE_UINT64); + g_signal_new ("all-types-null", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestClass, all_types_null), + NULL, NULL, + test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64, + G_TYPE_NONE, + 19, + G_TYPE_INT, + G_TYPE_BOOLEAN, + G_TYPE_CHAR, + G_TYPE_UCHAR, + G_TYPE_UINT, + G_TYPE_LONG, + G_TYPE_ULONG, + enum_type, + flags_type, + G_TYPE_FLOAT, + G_TYPE_DOUBLE, + G_TYPE_STRING, + G_TYPE_PARAM_LONG, + G_TYPE_BYTES, + G_TYPE_POINTER, + test_get_type (), + G_TYPE_VARIANT, + G_TYPE_INT64, + G_TYPE_UINT64); + g_signal_new ("all-types-empty", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64, + G_TYPE_NONE, + 19, + G_TYPE_INT, + G_TYPE_BOOLEAN, + G_TYPE_CHAR, + G_TYPE_UCHAR, + G_TYPE_UINT, + G_TYPE_LONG, + G_TYPE_ULONG, + enum_type, + flags_type, + G_TYPE_FLOAT, + G_TYPE_DOUBLE, + G_TYPE_STRING, + G_TYPE_PARAM_LONG, + G_TYPE_BYTES, + G_TYPE_POINTER, + test_get_type (), + G_TYPE_VARIANT, + G_TYPE_INT64, + G_TYPE_UINT64); +} + +typedef struct _Test Test2; +typedef struct _TestClass Test2Class; + +static GType test2_get_type (void); +G_DEFINE_TYPE (Test2, test2, G_TYPE_OBJECT) + +static void +test2_init (Test2 *test) +{ +} + +static void +test2_class_init (Test2Class *klass) +{ +} + +static void +test_variant_signal (void) +{ + Test *test; + GVariant *v; + + /* Tests that the signal emission consumes the variant, + * even if there are no handlers connected. + */ + + test = g_object_new (test_get_type (), NULL); + + v = g_variant_new_boolean (TRUE); + g_variant_ref (v); + g_assert_true (g_variant_is_floating (v)); + g_signal_emit_by_name (test, "variant-changed-no-slot", v); + g_assert_false (g_variant_is_floating (v)); + g_variant_unref (v); + + v = g_variant_new_boolean (TRUE); + g_variant_ref (v); + g_assert_true (g_variant_is_floating (v)); + g_signal_emit_by_name (test, "variant-changed", v); + g_assert_false (g_variant_is_floating (v)); + g_variant_unref (v); + + g_object_unref (test); +} + +static void +on_generic_marshaller_1 (Test *obj, + gint8 v_schar, + guint8 v_uchar, + gint v_int, + glong v_long, + gpointer v_pointer, + gdouble v_double, + gfloat v_float, + gpointer user_data) +{ + g_assert_cmpint (v_schar, ==, 42); + g_assert_cmpint (v_uchar, ==, 43); + g_assert_cmpint (v_int, ==, 4096); + g_assert_cmpint (v_long, ==, 8192); + g_assert_null (v_pointer); + g_assert_cmpfloat (v_double, >, 0.0); + g_assert_cmpfloat (v_double, <, 1.0); + g_assert_cmpfloat (v_float, >, 5.0); + g_assert_cmpfloat (v_float, <, 6.0); +} + +static void +test_generic_marshaller_signal_1 (void) +{ + Test *test; + test = g_object_new (test_get_type (), NULL); + + g_signal_connect (test, "generic-marshaller-1", G_CALLBACK (on_generic_marshaller_1), NULL); + + g_signal_emit_by_name (test, "generic-marshaller-1", 42, 43, 4096, 8192, NULL, 0.5, 5.5); + + g_object_unref (test); +} + +static void +on_generic_marshaller_2 (Test *obj, + gint v_int1, + TestEnum v_enum, + gint v_int2, + TestUnsignedEnum v_uenum, + gint v_int3) +{ + g_assert_cmpint (v_int1, ==, 42); + g_assert_cmpint (v_enum, ==, TEST_ENUM_BAR); + g_assert_cmpint (v_int2, ==, 43); + g_assert_cmpint (v_uenum, ==, TEST_UNSIGNED_ENUM_BAR); + g_assert_cmpint (v_int3, ==, 44); +} + +static void +test_generic_marshaller_signal_2 (void) +{ + Test *test; + test = g_object_new (test_get_type (), NULL); + + g_signal_connect (test, "generic-marshaller-2", G_CALLBACK (on_generic_marshaller_2), NULL); + + g_signal_emit_by_name (test, "generic-marshaller-2", 42, TEST_ENUM_BAR, 43, TEST_UNSIGNED_ENUM_BAR, 44); + + g_object_unref (test); +} + +static TestEnum +on_generic_marshaller_enum_return_signed_1 (Test *obj) +{ + return TEST_ENUM_NEGATIVE; +} + +static TestEnum +on_generic_marshaller_enum_return_signed_2 (Test *obj) +{ + return TEST_ENUM_BAR; +} + +static void +test_generic_marshaller_signal_enum_return_signed (void) +{ + Test *test; + guint id; + TestEnum retval = 0; + + test = g_object_new (test_get_type (), NULL); + + /* Test return value NEGATIVE */ + id = g_signal_connect (test, + "generic-marshaller-enum-return-signed", + G_CALLBACK (on_generic_marshaller_enum_return_signed_1), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-enum-return-signed", &retval); + g_assert_cmpint (retval, ==, TEST_ENUM_NEGATIVE); + g_signal_handler_disconnect (test, id); + + /* Test return value BAR */ + retval = 0; + id = g_signal_connect (test, + "generic-marshaller-enum-return-signed", + G_CALLBACK (on_generic_marshaller_enum_return_signed_2), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-enum-return-signed", &retval); + g_assert_cmpint (retval, ==, TEST_ENUM_BAR); + g_signal_handler_disconnect (test, id); + + g_object_unref (test); +} + +static TestUnsignedEnum +on_generic_marshaller_enum_return_unsigned_1 (Test *obj) +{ + return TEST_UNSIGNED_ENUM_FOO; +} + +static TestUnsignedEnum +on_generic_marshaller_enum_return_unsigned_2 (Test *obj) +{ + return TEST_UNSIGNED_ENUM_BAR; +} + +static void +test_generic_marshaller_signal_enum_return_unsigned (void) +{ + Test *test; + guint id; + TestUnsignedEnum retval = 0; + + test = g_object_new (test_get_type (), NULL); + + /* Test return value FOO */ + id = g_signal_connect (test, + "generic-marshaller-enum-return-unsigned", + G_CALLBACK (on_generic_marshaller_enum_return_unsigned_1), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-enum-return-unsigned", &retval); + g_assert_cmpint (retval, ==, TEST_UNSIGNED_ENUM_FOO); + g_signal_handler_disconnect (test, id); + + /* Test return value BAR */ + retval = 0; + id = g_signal_connect (test, + "generic-marshaller-enum-return-unsigned", + G_CALLBACK (on_generic_marshaller_enum_return_unsigned_2), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-enum-return-unsigned", &retval); + g_assert_cmpint (retval, ==, TEST_UNSIGNED_ENUM_BAR); + g_signal_handler_disconnect (test, id); + + g_object_unref (test); +} + +/**********************/ + +static gint +on_generic_marshaller_int_return_signed_1 (Test *obj) +{ + return -30; +} + +static gint +on_generic_marshaller_int_return_signed_2 (Test *obj) +{ + return 2; +} + +static void +test_generic_marshaller_signal_int_return (void) +{ + Test *test; + guint id; + gint retval = 0; + + test = g_object_new (test_get_type (), NULL); + + /* Test return value -30 */ + id = g_signal_connect (test, + "generic-marshaller-int-return", + G_CALLBACK (on_generic_marshaller_int_return_signed_1), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-int-return", &retval); + g_assert_cmpint (retval, ==, -30); + g_signal_handler_disconnect (test, id); + + /* Test return value positive */ + retval = 0; + id = g_signal_connect (test, + "generic-marshaller-int-return", + G_CALLBACK (on_generic_marshaller_int_return_signed_2), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-int-return", &retval); + g_assert_cmpint (retval, ==, 2); + g_signal_handler_disconnect (test, id); + + /* Same test for va marshaller */ + + /* Test return value -30 */ + id = g_signal_connect (test, + "va-marshaller-int-return", + G_CALLBACK (on_generic_marshaller_int_return_signed_1), + NULL); + g_signal_emit_by_name (test, "va-marshaller-int-return", &retval); + g_assert_cmpint (retval, ==, -30); + g_signal_handler_disconnect (test, id); + + /* Test return value positive */ + retval = 0; + id = g_signal_connect (test, + "va-marshaller-int-return", + G_CALLBACK (on_generic_marshaller_int_return_signed_2), + NULL); + g_signal_emit_by_name (test, "va-marshaller-int-return", &retval); + g_assert_cmpint (retval, ==, 2); + g_signal_handler_disconnect (test, id); + + g_object_unref (test); +} + +static guint +on_generic_marshaller_uint_return_1 (Test *obj) +{ + return 1; +} + +static guint +on_generic_marshaller_uint_return_2 (Test *obj) +{ + return G_MAXUINT; +} + +static void +test_generic_marshaller_signal_uint_return (void) +{ + Test *test; + guint id; + guint retval = 0; + + test = g_object_new (test_get_type (), NULL); + + id = g_signal_connect (test, + "generic-marshaller-uint-return", + G_CALLBACK (on_generic_marshaller_uint_return_1), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-uint-return", &retval); + g_assert_cmpint (retval, ==, 1); + g_signal_handler_disconnect (test, id); + + retval = 0; + id = g_signal_connect (test, + "generic-marshaller-uint-return", + G_CALLBACK (on_generic_marshaller_uint_return_2), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-uint-return", &retval); + g_assert_cmpint (retval, ==, G_MAXUINT); + g_signal_handler_disconnect (test, id); + + /* Same test for va marshaller */ + + id = g_signal_connect (test, + "va-marshaller-uint-return", + G_CALLBACK (on_generic_marshaller_uint_return_1), + NULL); + g_signal_emit_by_name (test, "va-marshaller-uint-return", &retval); + g_assert_cmpint (retval, ==, 1); + g_signal_handler_disconnect (test, id); + + retval = 0; + id = g_signal_connect (test, + "va-marshaller-uint-return", + G_CALLBACK (on_generic_marshaller_uint_return_2), + NULL); + g_signal_emit_by_name (test, "va-marshaller-uint-return", &retval); + g_assert_cmpint (retval, ==, G_MAXUINT); + g_signal_handler_disconnect (test, id); + + g_object_unref (test); +} + +static gpointer +on_generic_marshaller_interface_return (Test *test) +{ + return g_object_new (baa_get_type (), NULL); +} + +static void +test_generic_marshaller_signal_interface_return (void) +{ + Test *test; + guint id; + gpointer retval; + + test = g_object_new (test_get_type (), NULL); + + /* Test return value -30 */ + id = g_signal_connect (test, + "generic-marshaller-interface-return", + G_CALLBACK (on_generic_marshaller_interface_return), + NULL); + g_signal_emit_by_name (test, "generic-marshaller-interface-return", &retval); + g_assert_true (g_type_check_instance_is_a ((GTypeInstance*)retval, foo_get_type ())); + g_object_unref (retval); + + g_signal_handler_disconnect (test, id); + + g_object_unref (test); +} + +static const GSignalInvocationHint dont_use_this = { 0, }; + +static void +custom_marshaller_callback (Test *test, + GSignalInvocationHint *hint, + gpointer unused) +{ + GSignalInvocationHint *ihint; + + g_assert_true (hint != &dont_use_this); + + ihint = g_signal_get_invocation_hint (test); + + g_assert_cmpuint (hint->signal_id, ==, ihint->signal_id); + g_assert_cmpuint (hint->detail , ==, ihint->detail); + g_assert_cmpflags (GSignalFlags, hint->run_type, ==, ihint->run_type); +} + +static void +test_custom_marshaller (void) +{ + Test *test; + + test = g_object_new (test_get_type (), NULL); + + g_signal_connect (test, + "custom-marshaller", + G_CALLBACK (custom_marshaller_callback), + NULL); + + g_signal_emit_by_name (test, "custom-marshaller", &dont_use_this); + + g_object_unref (test); +} + +static int all_type_handlers_count = 0; + +static void +all_types_handler (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64) +{ + all_type_handlers_count++; + + g_assert_cmpint (i, ==, 42); + g_assert_cmpint (b, ==, TRUE); + g_assert_cmpint (c, ==, 17); + g_assert_cmpuint (uc, ==, 140); + g_assert_cmpuint (ui, ==, G_MAXUINT - 42); + g_assert_cmpint (l, ==, -1117); + g_assert_cmpuint (ul, ==, G_MAXULONG - 999); + g_assert_cmpenum (MyEnum, e, ==, MY_ENUM_VALUE); + g_assert_cmpflags (MyFlags, f, ==, MY_FLAGS_FIRST_BIT | MY_FLAGS_THIRD_BIT | MY_FLAGS_LAST_BIT); + g_assert_cmpfloat (fl, ==, 0.25); + g_assert_cmpfloat (db, ==, 1.5); + g_assert_cmpstr (str, ==, "Test"); + g_assert_cmpstr (g_param_spec_get_nick (param), ==, "nick"); + g_assert_cmpstr (g_bytes_get_data (bytes, NULL), ==, "Blah"); + g_assert_true (ptr == &enum_type); + g_assert_cmpuint (g_variant_get_uint16 (var), == , 99); + g_assert_cmpint (i64, ==, G_MAXINT64 - 1234); + g_assert_cmpuint (ui64, ==, G_MAXUINT64 - 123456); +} + +static void +all_types_handler_cb (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, guint f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64, gpointer user_data) +{ + g_assert_true (user_data == &flags_type); + all_types_handler (test, i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, obj, var, i64, ui64); +} + +static void +test_all_types (void) +{ + Test *test; + + int i = 42; + gboolean b = TRUE; + char c = 17; + guchar uc = 140; + guint ui = G_MAXUINT - 42; + glong l = -1117; + gulong ul = G_MAXULONG - 999; + MyEnum e = MY_ENUM_VALUE; + MyFlags f = MY_FLAGS_FIRST_BIT | MY_FLAGS_THIRD_BIT | MY_FLAGS_LAST_BIT; + float fl = 0.25; + double db = 1.5; + char *str = "Test"; + GParamSpec *param = g_param_spec_long ("param", "nick", "blurb", 0, 10, 4, 0); + GBytes *bytes = g_bytes_new_static ("Blah", 5); + gpointer ptr = &enum_type; + GVariant *var = g_variant_new_uint16 (99); + gint64 i64; + guint64 ui64; + g_variant_ref_sink (var); + i64 = G_MAXINT64 - 1234; + ui64 = G_MAXUINT64 - 123456; + + test = g_object_new (test_get_type (), NULL); + + all_type_handlers_count = 0; + + g_signal_emit_by_name (test, "all-types", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-va", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-generic", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-empty", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-null", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + + g_assert_cmpint (all_type_handlers_count, ==, 3); + + all_type_handlers_count = 0; + + g_signal_connect (test, "all-types", G_CALLBACK (all_types_handler_cb), &flags_type); + g_signal_connect (test, "all-types-va", G_CALLBACK (all_types_handler_cb), &flags_type); + g_signal_connect (test, "all-types-generic", G_CALLBACK (all_types_handler_cb), &flags_type); + g_signal_connect (test, "all-types-empty", G_CALLBACK (all_types_handler_cb), &flags_type); + g_signal_connect (test, "all-types-null", G_CALLBACK (all_types_handler_cb), &flags_type); + + g_signal_emit_by_name (test, "all-types", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-va", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-generic", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-empty", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-null", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + + g_assert_cmpint (all_type_handlers_count, ==, 3 + 5); + + all_type_handlers_count = 0; + + g_signal_connect (test, "all-types", G_CALLBACK (all_types_handler_cb), &flags_type); + g_signal_connect (test, "all-types-va", G_CALLBACK (all_types_handler_cb), &flags_type); + g_signal_connect (test, "all-types-generic", G_CALLBACK (all_types_handler_cb), &flags_type); + g_signal_connect (test, "all-types-empty", G_CALLBACK (all_types_handler_cb), &flags_type); + g_signal_connect (test, "all-types-null", G_CALLBACK (all_types_handler_cb), &flags_type); + + g_signal_emit_by_name (test, "all-types", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-va", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-generic", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-empty", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + g_signal_emit_by_name (test, "all-types-null", + i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64); + + g_assert_cmpint (all_type_handlers_count, ==, 3 + 5 + 5); + + g_object_unref (test); + g_param_spec_unref (param); + g_bytes_unref (bytes); + g_variant_unref (var); +} + +static void +test_connect (void) +{ + GObject *test; + gint retval; + + test = g_object_new (test_get_type (), NULL); + + g_object_connect (test, + "signal::generic-marshaller-int-return", + G_CALLBACK (on_generic_marshaller_int_return_signed_1), + NULL, + "object-signal::va-marshaller-int-return", + G_CALLBACK (on_generic_marshaller_int_return_signed_2), + NULL, + NULL); + g_signal_emit_by_name (test, "generic-marshaller-int-return", &retval); + g_assert_cmpint (retval, ==, -30); + g_signal_emit_by_name (test, "va-marshaller-int-return", &retval); + g_assert_cmpint (retval, ==, 2); + + g_object_disconnect (test, + "any-signal", + G_CALLBACK (on_generic_marshaller_int_return_signed_1), + NULL, + "any-signal::va-marshaller-int-return", + G_CALLBACK (on_generic_marshaller_int_return_signed_2), + NULL, + NULL); + + g_object_unref (test); +} + +static void +simple_handler1 (GObject *sender, + GObject *target) +{ + g_object_unref (target); +} + +static void +simple_handler2 (GObject *sender, + GObject *target) +{ + g_object_unref (target); +} + +static void +test_destroy_target_object (void) +{ + Test *sender, *target1, *target2; + + sender = g_object_new (test_get_type (), NULL); + target1 = g_object_new (test_get_type (), NULL); + target2 = g_object_new (test_get_type (), NULL); + g_signal_connect_object (sender, "simple", G_CALLBACK (simple_handler1), target1, 0); + g_signal_connect_object (sender, "simple", G_CALLBACK (simple_handler2), target2, 0); + g_signal_emit_by_name (sender, "simple"); + g_object_unref (sender); +} + +static gboolean +hook_func (GSignalInvocationHint *ihint, + guint n_params, + const GValue *params, + gpointer data) +{ + gint *count = data; + + (*count)++; + + return TRUE; +} + +static void +test_emission_hook (void) +{ + GObject *test1, *test2; + gint count = 0; + gulong hook; + + test1 = g_object_new (test_get_type (), NULL); + test2 = g_object_new (test_get_type (), NULL); + + hook = g_signal_add_emission_hook (simple_id, 0, hook_func, &count, NULL); + g_assert_cmpint (count, ==, 0); + g_signal_emit_by_name (test1, "simple"); + g_assert_cmpint (count, ==, 1); + g_signal_emit_by_name (test2, "simple"); + g_assert_cmpint (count, ==, 2); + g_signal_remove_emission_hook (simple_id, hook); + g_signal_emit_by_name (test1, "simple"); + g_assert_cmpint (count, ==, 2); + + g_object_unref (test1); + g_object_unref (test2); +} + +static void +simple_cb (gpointer instance, gpointer data) +{ + GSignalInvocationHint *ihint; + + ihint = g_signal_get_invocation_hint (instance); + + g_assert_cmpstr (g_signal_name (ihint->signal_id), ==, "simple"); + + g_signal_emit_by_name (instance, "simple-2"); +} + +static void +simple2_cb (gpointer instance, gpointer data) +{ + GSignalInvocationHint *ihint; + + ihint = g_signal_get_invocation_hint (instance); + + g_assert_cmpstr (g_signal_name (ihint->signal_id), ==, "simple-2"); +} + +static void +test_invocation_hint (void) +{ + GObject *test; + + test = g_object_new (test_get_type (), NULL); + + g_signal_connect (test, "simple", G_CALLBACK (simple_cb), NULL); + g_signal_connect (test, "simple-2", G_CALLBACK (simple2_cb), NULL); + g_signal_emit_by_name (test, "simple"); + + g_object_unref (test); +} + +static gboolean +accumulator_sum (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + gint acc = g_value_get_int (return_accu); + gint ret = g_value_get_int (handler_return); + + g_assert_cmpint (ret, >, 0); + + if (ihint->run_type & G_SIGNAL_ACCUMULATOR_FIRST_RUN) + { + g_assert_cmpint (acc, ==, 0); + g_assert_cmpint (ret, ==, 1); + g_assert_true (ihint->run_type & G_SIGNAL_RUN_FIRST); + g_assert_false (ihint->run_type & G_SIGNAL_RUN_LAST); + } + else if (ihint->run_type & G_SIGNAL_RUN_FIRST) + { + /* Only the first signal handler was called so far */ + g_assert_cmpint (acc, ==, 1); + g_assert_cmpint (ret, ==, 2); + g_assert_false (ihint->run_type & G_SIGNAL_RUN_LAST); + } + else if (ihint->run_type & G_SIGNAL_RUN_LAST) + { + /* Only the first two signal handler were called so far */ + g_assert_cmpint (acc, ==, 3); + g_assert_cmpint (ret, ==, 3); + g_assert_false (ihint->run_type & G_SIGNAL_RUN_FIRST); + } + else + { + g_assert_not_reached (); + } + + g_value_set_int (return_accu, acc + ret); + + /* Continue with the other signal handlers as long as the sum is < 6, + * i.e. don't run simple_accumulator_4_cb() */ + return acc + ret < 6; +} + +static gint +simple_accumulator_1_cb (gpointer instance, gpointer data) +{ + return 1; +} + +static gint +simple_accumulator_2_cb (gpointer instance, gpointer data) +{ + return 2; +} + +static gint +simple_accumulator_3_cb (gpointer instance, gpointer data) +{ + return 3; +} + +static gint +simple_accumulator_4_cb (gpointer instance, gpointer data) +{ + return 4; +} + +static void +test_accumulator (void) +{ + GObject *test; + gint ret = -1; + + test = g_object_new (test_get_type (), NULL); + + /* Connect in reverse order to make sure that LAST signal handlers are + * called after FIRST signal handlers but signal handlers in each "group" + * are called in the order they were registered */ + g_signal_connect_after (test, "simple-accumulator", G_CALLBACK (simple_accumulator_3_cb), NULL); + g_signal_connect_after (test, "simple-accumulator", G_CALLBACK (simple_accumulator_4_cb), NULL); + g_signal_connect (test, "simple-accumulator", G_CALLBACK (simple_accumulator_1_cb), NULL); + g_signal_connect (test, "simple-accumulator", G_CALLBACK (simple_accumulator_2_cb), NULL); + g_signal_emit_by_name (test, "simple-accumulator", &ret); + + /* simple_accumulator_4_cb() is not run because accumulator is 6 */ + g_assert_cmpint (ret, ==, 6); + + g_object_unref (test); +} + +static gboolean +accumulator_concat_string (GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer data) +{ + const gchar *acc = g_value_get_string (return_accu); + const gchar *ret = g_value_get_string (handler_return); + + g_assert_nonnull (ret); + + if (acc == NULL) + g_value_set_string (return_accu, ret); + else + g_value_take_string (return_accu, g_strconcat (acc, ret, NULL)); + + return TRUE; +} + +static gchar * +accumulator_class_before_cb (gpointer instance, gpointer data) +{ + return g_strdup ("before"); +} + +static gchar * +accumulator_class_after_cb (gpointer instance, gpointer data) +{ + return g_strdup ("after"); +} + +static gchar * +accumulator_class (Test *test) +{ + return g_strdup ("class"); +} + +static void +test_accumulator_class (void) +{ + const struct { + const gchar *signal_name; + const gchar *return_string; + } tests[] = { + {"accumulator-class-first", "classbeforeafter"}, + {"accumulator-class-last", "beforeclassafter"}, + {"accumulator-class-cleanup", "beforeafterclass"}, + {"accumulator-class-first-last", "classbeforeclassafter"}, + {"accumulator-class-first-last-cleanup", "classbeforeclassafterclass"}, + {"accumulator-class-last-cleanup", "beforeclassafterclass"}, + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + GObject *test; + gchar *ret = NULL; + + g_test_message ("Signal: %s", tests[i].signal_name); + + test = g_object_new (test_get_type (), NULL); + + g_signal_connect (test, tests[i].signal_name, G_CALLBACK (accumulator_class_before_cb), NULL); + g_signal_connect_after (test, tests[i].signal_name, G_CALLBACK (accumulator_class_after_cb), NULL); + g_signal_emit_by_name (test, tests[i].signal_name, &ret); + + g_assert_cmpstr (ret, ==, tests[i].return_string); + g_free (ret); + + g_object_unref (test); + } +} + +static gboolean +in_set (const gchar *s, + const gchar *set[]) +{ + gint i; + + for (i = 0; set[i]; i++) + { + if (g_strcmp0 (s, set[i]) == 0) + return TRUE; + } + + return FALSE; +} + +static void +test_introspection (void) +{ + guint *ids; + guint n_ids; + const gchar *name; + guint i; + const gchar *names[] = { + "simple", + "simple-detailed", + "simple-2", + "simple-accumulator", + "accumulator-class-first", + "accumulator-class-last", + "accumulator-class-cleanup", + "accumulator-class-first-last", + "accumulator-class-first-last-cleanup", + "accumulator-class-last-cleanup", + "generic-marshaller-1", + "generic-marshaller-2", + "generic-marshaller-enum-return-signed", + "generic-marshaller-enum-return-unsigned", + "generic-marshaller-int-return", + "va-marshaller-int-return", + "generic-marshaller-uint-return", + "generic-marshaller-interface-return", + "va-marshaller-uint-return", + "variant-changed-no-slot", + "variant-changed", + "all-types", + "all-types-va", + "all-types-generic", + "all-types-null", + "all-types-empty", + "custom-marshaller", + NULL + }; + GSignalQuery query; + + ids = g_signal_list_ids (test_get_type (), &n_ids); + g_assert_cmpuint (n_ids, ==, g_strv_length ((gchar**)names)); + + for (i = 0; i < n_ids; i++) + { + name = g_signal_name (ids[i]); + g_assert_true (in_set (name, names)); + } + + g_signal_query (simple_id, &query); + g_assert_cmpuint (query.signal_id, ==, simple_id); + g_assert_cmpstr (query.signal_name, ==, "simple"); + g_assert_true (query.itype == test_get_type ()); + g_assert_cmpint (query.signal_flags, ==, G_SIGNAL_RUN_LAST); + g_assert_cmpint (query.return_type, ==, G_TYPE_NONE); + g_assert_cmpuint (query.n_params, ==, 0); + + g_free (ids); +} + +static void +test_handler (gpointer instance, gpointer data) +{ + gint *count = data; + + (*count)++; +} + +static void +test_block_handler (void) +{ + GObject *test1, *test2; + gint count1 = 0; + gint count2 = 0; + gulong handler1, handler; + + test1 = g_object_new (test_get_type (), NULL); + test2 = g_object_new (test_get_type (), NULL); + + handler1 = g_signal_connect (test1, "simple", G_CALLBACK (test_handler), &count1); + g_signal_connect (test2, "simple", G_CALLBACK (test_handler), &count2); + + handler = g_signal_handler_find (test1, G_SIGNAL_MATCH_ID, simple_id, 0, NULL, NULL, NULL); + + g_assert_true (handler == handler1); + + g_assert_cmpint (count1, ==, 0); + g_assert_cmpint (count2, ==, 0); + + g_signal_emit_by_name (test1, "simple"); + g_signal_emit_by_name (test2, "simple"); + + g_assert_cmpint (count1, ==, 1); + g_assert_cmpint (count2, ==, 1); + + g_signal_handler_block (test1, handler1); + + g_signal_emit_by_name (test1, "simple"); + g_signal_emit_by_name (test2, "simple"); + + g_assert_cmpint (count1, ==, 1); + g_assert_cmpint (count2, ==, 2); + + g_signal_handler_unblock (test1, handler1); + + g_signal_emit_by_name (test1, "simple"); + g_signal_emit_by_name (test2, "simple"); + + g_assert_cmpint (count1, ==, 2); + g_assert_cmpint (count2, ==, 3); + + g_assert_cmpuint (g_signal_handlers_block_matched (test1, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_block_handler, NULL), ==, 0); + g_assert_cmpuint (g_signal_handlers_block_matched (test2, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_handler, NULL), ==, 1); + + g_signal_emit_by_name (test1, "simple"); + g_signal_emit_by_name (test2, "simple"); + + g_assert_cmpint (count1, ==, 3); + g_assert_cmpint (count2, ==, 3); + + g_signal_handlers_unblock_matched (test2, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_handler, NULL); + + g_object_unref (test1); + g_object_unref (test2); +} + +static void +stop_emission (gpointer instance, gpointer data) +{ + g_signal_stop_emission (instance, simple_id, 0); +} + +static void +stop_emission_by_name (gpointer instance, gpointer data) +{ + g_signal_stop_emission_by_name (instance, "simple"); +} + +static void +dont_reach (gpointer instance, gpointer data) +{ + g_assert_not_reached (); +} + +static void +test_stop_emission (void) +{ + GObject *test1; + gulong handler; + + test1 = g_object_new (test_get_type (), NULL); + handler = g_signal_connect (test1, "simple", G_CALLBACK (stop_emission), NULL); + g_signal_connect_after (test1, "simple", G_CALLBACK (dont_reach), NULL); + + g_signal_emit_by_name (test1, "simple"); + + g_signal_handler_disconnect (test1, handler); + g_signal_connect (test1, "simple", G_CALLBACK (stop_emission_by_name), NULL); + + g_signal_emit_by_name (test1, "simple"); + + g_object_unref (test1); +} + +static void +test_signal_disconnect_wrong_object (void) +{ + Test *object, *object2; + Test2 *object3; + guint signal_id; + + object = g_object_new (test_get_type (), NULL); + object2 = g_object_new (test_get_type (), NULL); + object3 = g_object_new (test2_get_type (), NULL); + + signal_id = g_signal_connect (object, + "simple", + G_CALLBACK (simple_handler1), + NULL); + + /* disconnect from the wrong object (same type), should warn */ + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, + "*: instance '*' has no handler with id '*'"); + g_signal_handler_disconnect (object2, signal_id); + g_test_assert_expected_messages (); + + /* and from an object of the wrong type */ + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, + "*: instance '*' has no handler with id '*'"); + g_signal_handler_disconnect (object3, signal_id); + g_test_assert_expected_messages (); + + /* it's still connected */ + g_assert_true (g_signal_handler_is_connected (object, signal_id)); + + g_object_unref (object); + g_object_unref (object2); + g_object_unref (object3); +} + +static void +test_clear_signal_handler (void) +{ + GObject *test_obj; + gulong handler; + + test_obj = g_object_new (test_get_type (), NULL); + + handler = g_signal_connect (test_obj, "simple", G_CALLBACK (dont_reach), NULL); + g_assert_cmpuint (handler, >, 0); + + g_clear_signal_handler (&handler, test_obj); + g_assert_cmpuint (handler, ==, 0); + + g_signal_emit_by_name (test_obj, "simple"); + + g_clear_signal_handler (&handler, test_obj); + + if (g_test_undefined ()) + { + handler = g_random_int_range (0x01, 0xFF); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "*instance '* has no handler with id *'"); + g_clear_signal_handler (&handler, test_obj); + g_assert_cmpuint (handler, ==, 0); + g_test_assert_expected_messages (); + } + + g_object_unref (test_obj); +} + +static void +test_lookup (void) +{ + GTypeClass *test_class; + guint signal_id, saved_signal_id; + + g_test_summary ("Test that g_signal_lookup() works with a variety of inputs."); + + test_class = g_type_class_ref (test_get_type ()); + + signal_id = g_signal_lookup ("all-types", test_get_type ()); + g_assert_cmpint (signal_id, !=, 0); + + saved_signal_id = signal_id; + + /* Try with a non-canonical name. */ + signal_id = g_signal_lookup ("all_types", test_get_type ()); + g_assert_cmpint (signal_id, ==, saved_signal_id); + + /* Looking up a non-existent signal should return nothing. */ + g_assert_cmpint (g_signal_lookup ("nope", test_get_type ()), ==, 0); + + g_type_class_unref (test_class); +} + +static void +test_lookup_invalid (void) +{ + g_test_summary ("Test that g_signal_lookup() emits a warning if looking up an invalid signal name."); + + if (g_test_subprocess ()) + { + GTypeClass *test_class; + guint signal_id; + + test_class = g_type_class_ref (test_get_type ()); + + signal_id = g_signal_lookup ("", test_get_type ()); + g_assert_cmpint (signal_id, ==, 0); + + g_type_class_unref (test_class); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*WARNING*unable to look up invalid signal name*"); +} + +static void +test_parse_name (void) +{ + GTypeClass *test_class; + guint signal_id, saved_signal_id; + gboolean retval; + GQuark detail, saved_detail; + + g_test_summary ("Test that g_signal_parse_name() works with a variety of inputs."); + + test_class = g_type_class_ref (test_get_type ()); + + /* Simple test. */ + retval = g_signal_parse_name ("simple-detailed", test_get_type (), &signal_id, &detail, TRUE); + g_assert_true (retval); + g_assert_cmpint (signal_id, !=, 0); + g_assert_cmpint (detail, ==, 0); + + saved_signal_id = signal_id; + + /* Simple test with detail. */ + retval = g_signal_parse_name ("simple-detailed::a-detail", test_get_type (), &signal_id, &detail, TRUE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, !=, 0); + + saved_detail = detail; + + /* Simple test with the same detail again. */ + retval = g_signal_parse_name ("simple-detailed::a-detail", test_get_type (), &signal_id, &detail, FALSE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, ==, saved_detail); + + /* Simple test with a new detail. */ + retval = g_signal_parse_name ("simple-detailed::another-detail", test_get_type (), &signal_id, &detail, FALSE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, ==, 0); /* we didn’t force the quark */ + + /* Canonicalisation shouldn’t affect the results. */ + retval = g_signal_parse_name ("simple_detailed::a-detail", test_get_type (), &signal_id, &detail, FALSE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, ==, saved_detail); + + /* Details don’t have to look like property names. */ + retval = g_signal_parse_name ("simple-detailed::hello::world", test_get_type (), &signal_id, &detail, TRUE); + g_assert_true (retval); + g_assert_cmpint (signal_id, ==, saved_signal_id); + g_assert_cmpint (detail, !=, 0); + + /* Trying to parse a detail for a signal which isn’t %G_SIGNAL_DETAILED should fail. */ + retval = g_signal_parse_name ("all-types::a-detail", test_get_type (), &signal_id, &detail, FALSE); + g_assert_false (retval); + + g_type_class_unref (test_class); +} + +static void +test_parse_name_invalid (void) +{ + GTypeClass *test_class; + gsize i; + guint signal_id; + GQuark detail; + const gchar *vectors[] = + { + "", + "7zip", + "invalid:signal", + "simple-detailed::", + "simple-detailed:", + ":", + "::", + ":valid-detail", + "::valid-detail", + }; + + g_test_summary ("Test that g_signal_parse_name() ignores a variety of invalid inputs."); + + test_class = g_type_class_ref (test_get_type ()); + + for (i = 0; i < G_N_ELEMENTS (vectors); i++) + { + g_test_message ("Parser input: %s", vectors[i]); + g_assert_false (g_signal_parse_name (vectors[i], test_get_type (), &signal_id, &detail, TRUE)); + } + + g_type_class_unref (test_class); +} + +static void +test_signals_invalid_name (gconstpointer test_data) +{ + const gchar *signal_name = test_data; + + g_test_summary ("Check that g_signal_new() rejects invalid signal names."); + + if (g_test_subprocess ()) + { + g_signal_new (signal_name, + test_get_type (), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 0); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*g_signal_is_valid_name (signal_name)*"); +} + +static void +test_signal_is_valid_name (void) +{ + const gchar *valid_names[] = + { + "signal", + "i", + "multiple-segments", + "segment0-SEGMENT1", + "using_underscores", + }; + const gchar *invalid_names[] = + { + "", + "7zip", + "my_int:hello", + }; + gsize i; + + for (i = 0; i < G_N_ELEMENTS (valid_names); i++) + g_assert_true (g_signal_is_valid_name (valid_names[i])); + + for (i = 0; i < G_N_ELEMENTS (invalid_names); i++) + g_assert_false (g_signal_is_valid_name (invalid_names[i])); +} + +/* --- */ + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gobject/signals/all-types", test_all_types); + g_test_add_func ("/gobject/signals/variant", test_variant_signal); + g_test_add_func ("/gobject/signals/destroy-target-object", test_destroy_target_object); + g_test_add_func ("/gobject/signals/generic-marshaller-1", test_generic_marshaller_signal_1); + g_test_add_func ("/gobject/signals/generic-marshaller-2", test_generic_marshaller_signal_2); + g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-signed", test_generic_marshaller_signal_enum_return_signed); + g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-unsigned", test_generic_marshaller_signal_enum_return_unsigned); + g_test_add_func ("/gobject/signals/generic-marshaller-int-return", test_generic_marshaller_signal_int_return); + g_test_add_func ("/gobject/signals/generic-marshaller-uint-return", test_generic_marshaller_signal_uint_return); + g_test_add_func ("/gobject/signals/generic-marshaller-interface-return", test_generic_marshaller_signal_interface_return); + g_test_add_func ("/gobject/signals/custom-marshaller", test_custom_marshaller); + g_test_add_func ("/gobject/signals/connect", test_connect); + g_test_add_func ("/gobject/signals/emission-hook", test_emission_hook); + g_test_add_func ("/gobject/signals/accumulator", test_accumulator); + g_test_add_func ("/gobject/signals/accumulator-class", test_accumulator_class); + g_test_add_func ("/gobject/signals/introspection", test_introspection); + g_test_add_func ("/gobject/signals/block-handler", test_block_handler); + g_test_add_func ("/gobject/signals/stop-emission", test_stop_emission); + g_test_add_func ("/gobject/signals/invocation-hint", test_invocation_hint); + g_test_add_func ("/gobject/signals/test-disconnection-wrong-object", test_signal_disconnect_wrong_object); + g_test_add_func ("/gobject/signals/clear-signal-handler", test_clear_signal_handler); + g_test_add_func ("/gobject/signals/lookup", test_lookup); + g_test_add_func ("/gobject/signals/lookup/invalid", test_lookup_invalid); + g_test_add_func ("/gobject/signals/parse-name", test_parse_name); + g_test_add_func ("/gobject/signals/parse-name/invalid", test_parse_name_invalid); + g_test_add_data_func ("/gobject/signals/invalid-name/colon", "my_int:hello", test_signals_invalid_name); + g_test_add_data_func ("/gobject/signals/invalid-name/first-char", "7zip", test_signals_invalid_name); + g_test_add_data_func ("/gobject/signals/invalid-name/empty", "", test_signals_invalid_name); + g_test_add_func ("/gobject/signals/is-valid-name", test_signal_is_valid_name); + + return g_test_run (); +} diff --git a/gobject/tests/taptestrunner.py b/gobject/tests/taptestrunner.py new file mode 100644 index 0000000..9ce3b43 --- /dev/null +++ b/gobject/tests/taptestrunner.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright (c) 2015 Remko Tronçon (https://el-tramo.be) +# Copied from https://github.com/remko/pycotap/ +# +# Released under the MIT license +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +import unittest +import sys +import base64 +from io import StringIO + + +# Log modes +class LogMode(object): + LogToError, LogToDiagnostics, LogToYAML, LogToAttachment = range(4) + + +class TAPTestResult(unittest.TestResult): + def __init__(self, output_stream, error_stream, message_log, test_output_log): + super(TAPTestResult, self).__init__(self, output_stream) + self.output_stream = output_stream + self.error_stream = error_stream + self.orig_stdout = None + self.orig_stderr = None + self.message = None + self.test_output = None + self.message_log = message_log + self.test_output_log = test_output_log + self.output_stream.write("TAP version 13\n") + self._set_streams() + + def printErrors(self): + self.print_raw("1..%d\n" % self.testsRun) + self._reset_streams() + + def _set_streams(self): + self.orig_stdout = sys.stdout + self.orig_stderr = sys.stderr + if self.message_log == LogMode.LogToError: + self.message = self.error_stream + else: + self.message = StringIO() + if self.test_output_log == LogMode.LogToError: + self.test_output = self.error_stream + else: + self.test_output = StringIO() + + if self.message_log == self.test_output_log: + self.test_output = self.message + sys.stdout = sys.stderr = self.test_output + + def _reset_streams(self): + sys.stdout = self.orig_stdout + sys.stderr = self.orig_stderr + + def print_raw(self, text): + self.output_stream.write(text) + self.output_stream.flush() + + def print_result(self, result, test, directive=None): + self.output_stream.write("%s %d %s" % (result, self.testsRun, test.id())) + if directive: + self.output_stream.write(" # " + directive) + self.output_stream.write("\n") + self.output_stream.flush() + + def ok(self, test, directive=None): + self.print_result("ok", test, directive) + + def not_ok(self, test): + self.print_result("not ok", test) + + def startTest(self, test): + super(TAPTestResult, self).startTest(test) + + def stopTest(self, test): + super(TAPTestResult, self).stopTest(test) + if self.message_log == self.test_output_log: + logs = [(self.message_log, self.message, "output")] + else: + logs = [ + (self.test_output_log, self.test_output, "test_output"), + (self.message_log, self.message, "message"), + ] + for log_mode, log, log_name in logs: + if log_mode != LogMode.LogToError: + output = log.getvalue() + if len(output): + if log_mode == LogMode.LogToYAML: + self.print_raw(" ---\n") + self.print_raw(" " + log_name + ": |\n") + self.print_raw( + " " + output.rstrip().replace("\n", "\n ") + "\n" + ) + self.print_raw(" ...\n") + elif log_mode == LogMode.LogToAttachment: + self.print_raw(" ---\n") + self.print_raw(" " + log_name + ":\n") + self.print_raw(" File-Name: " + log_name + ".txt\n") + self.print_raw(" File-Type: text/plain\n") + self.print_raw( + " File-Content: " + base64.b64encode(output) + "\n" + ) + self.print_raw(" ...\n") + else: + self.print_raw( + "# " + output.rstrip().replace("\n", "\n# ") + "\n" + ) + # Truncate doesn't change the current stream position. + # Seek to the beginning to avoid extensions on subsequent writes. + log.seek(0) + log.truncate(0) + + def addSuccess(self, test): + super(TAPTestResult, self).addSuccess(test) + self.ok(test) + + def addError(self, test, err): + super(TAPTestResult, self).addError(test, err) + self.message.write(self.errors[-1][1] + "\n") + self.not_ok(test) + + def addFailure(self, test, err): + super(TAPTestResult, self).addFailure(test, err) + self.message.write(self.failures[-1][1] + "\n") + self.not_ok(test) + + def addSkip(self, test, reason): + super(TAPTestResult, self).addSkip(test, reason) + self.ok(test, "SKIP " + reason) + + def addExpectedFailure(self, test, err): + super(TAPTestResult, self).addExpectedFailure(test, err) + self.ok(test) + + def addUnexpectedSuccess(self, test): + super(TAPTestResult, self).addUnexpectedSuccess(test) + self.message.write("Unexpected success" + "\n") + self.not_ok(test) + + +class TAPTestRunner(object): + def __init__( + self, + message_log=LogMode.LogToYAML, + test_output_log=LogMode.LogToDiagnostics, + output_stream=sys.stdout, + error_stream=sys.stderr, + ): + self.output_stream = output_stream + self.error_stream = error_stream + self.message_log = message_log + self.test_output_log = test_output_log + + def run(self, test): + result = TAPTestResult( + self.output_stream, + self.error_stream, + self.message_log, + self.test_output_log, + ) + test(result) + result.printErrors() + + return result diff --git a/gobject/tests/testcommon.h b/gobject/tests/testcommon.h new file mode 100644 index 0000000..a2b69b7 --- /dev/null +++ b/gobject/tests/testcommon.h @@ -0,0 +1,105 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __TEST_COMMON_H__ +#define __TEST_COMMON_H__ + +G_BEGIN_DECLS + +#define DEFINE_TYPE_FULL(name, prefix, \ + class_init, base_init, instance_init, \ + parent_type, interface_decl) \ +GType \ +prefix ## _get_type (void) \ +{ \ + static GType object_type = 0; \ + \ + if (!object_type) \ + { \ + static const GTypeInfo object_info = \ + { \ + sizeof (name ## Class), \ + (GBaseInitFunc) base_init, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) class_init, \ + (GClassFinalizeFunc) NULL, \ + NULL, /* class_data */ \ + sizeof (name), \ + 0, /* n_prelocs */ \ + (GInstanceInitFunc) instance_init, \ + (const GTypeValueTable *) NULL, \ + }; \ + \ + object_type = g_type_register_static (parent_type, \ + # name, \ + &object_info, 0); \ + interface_decl \ + } \ + \ + return object_type; \ +} + +#define DEFINE_TYPE(name, prefix, \ + class_init, base_init, instance_init, \ + parent_type) \ + DEFINE_TYPE_FULL(name, prefix, class_init, base_init, \ + instance_init, parent_type, {}) + +#define DEFINE_IFACE(name, prefix, base_init, dflt_init) \ +GType \ +prefix ## _get_type (void) \ +{ \ + static GType iface_type = 0; \ + \ + if (!iface_type) \ + { \ + static const GTypeInfo iface_info = \ + { \ + sizeof (name ## Class), \ + (GBaseInitFunc) base_init, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) dflt_init, \ + (GClassFinalizeFunc) NULL, \ + (gconstpointer) NULL, \ + (guint16) 0, \ + (guint16) 0, \ + (GInstanceInitFunc) NULL, \ + (const GTypeValueTable*) NULL, \ + }; \ + \ + iface_type = g_type_register_static (G_TYPE_INTERFACE, \ + # name, \ + &iface_info, 0); \ + } \ + return iface_type; \ +} + +#define INTERFACE_FULL(type, init_func, iface_type) \ +{ \ + static GInterfaceInfo const iface = \ + { \ + (GInterfaceInitFunc) init_func, NULL, NULL \ + }; \ + \ + g_type_add_interface_static (type, iface_type, &iface); \ +} +#define INTERFACE(init_func, iface_type) \ + INTERFACE_FULL(object_type, init_func, iface_type) + +G_END_DECLS + +#endif /* __TEST_COMMON_H__ */ diff --git a/gobject/tests/testing.c b/gobject/tests/testing.c new file mode 100644 index 0000000..5c7e663 --- /dev/null +++ b/gobject/tests/testing.c @@ -0,0 +1,71 @@ +/* GLib testing framework examples and tests + * + * Copyright © 2019 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Author: Philip Withnall + */ + +#include "config.h" + +/* We want to distinguish between messages originating from libglib + * and messages originating from this program. + */ +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "testing" + +#include +#include +#include +#include + +static void +test_assert_finalize_object_subprocess_bad (void) +{ + GObject *obj = g_object_new (G_TYPE_OBJECT, NULL); + g_object_ref (obj); + + /* This should emit an assertion failure. */ + g_assert_finalize_object (obj); + + g_object_unref (obj); + + exit (0); +} + +static void +test_assert_finalize_object (void) +{ + GObject *obj = g_object_new (G_TYPE_OBJECT, NULL); + + g_assert_finalize_object (obj); + + g_test_trap_subprocess ("/assert/finalize_object/subprocess/bad", 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_assert_finalize_object:*'weak_pointer' should be NULL*"); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/assert/finalize_object", test_assert_finalize_object); + g_test_add_func ("/assert/finalize_object/subprocess/bad", + test_assert_finalize_object_subprocess_bad); + + return g_test_run (); +} diff --git a/gobject/tests/threadtests.c b/gobject/tests/threadtests.c new file mode 100644 index 0000000..3b485eb --- /dev/null +++ b/gobject/tests/threadtests.c @@ -0,0 +1,525 @@ +/* GLib testing framework examples and tests + * Copyright (C) 2008 Imendio AB + * Authors: Tim Janik + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#endif + +#include +#include + +static int mtsafe_call_counter = 0; /* multi thread safe call counter, must be accessed atomically */ +static int unsafe_call_counter = 0; /* single-threaded call counter */ +static GCond sync_cond; +static GMutex sync_mutex; + +#define NUM_COUNTER_INCREMENTS 100000 + +static void +call_counter_init (gpointer tclass) +{ + int i; + for (i = 0; i < NUM_COUNTER_INCREMENTS; i++) + { + int saved_unsafe_call_counter = unsafe_call_counter; + g_atomic_int_add (&mtsafe_call_counter, 1); /* real call count update */ + g_thread_yield(); /* let concurrent threads corrupt the unsafe_call_counter state */ + unsafe_call_counter = 1 + saved_unsafe_call_counter; /* non-atomic counter update */ + } +} + +static void interface_per_class_init (void) { call_counter_init (NULL); } + +/* define 3 test interfaces */ +typedef GTypeInterface MyFace0Interface; +static GType my_face0_get_type (void); +G_DEFINE_INTERFACE (MyFace0, my_face0, G_TYPE_OBJECT) +static void my_face0_default_init (MyFace0Interface *iface) { call_counter_init (iface); } +typedef GTypeInterface MyFace1Interface; +static GType my_face1_get_type (void); +G_DEFINE_INTERFACE (MyFace1, my_face1, G_TYPE_OBJECT) +static void my_face1_default_init (MyFace1Interface *iface) { call_counter_init (iface); } + +/* define 3 test objects, adding interfaces 0 & 1, and adding interface 2 after class initialization */ +typedef GObject MyTester0; +typedef GObjectClass MyTester0Class; +static GType my_tester0_get_type (void); +G_DEFINE_TYPE_WITH_CODE (MyTester0, my_tester0, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (my_face0_get_type(), interface_per_class_init) + G_IMPLEMENT_INTERFACE (my_face1_get_type(), interface_per_class_init)) +static void my_tester0_init (MyTester0*t) {} +static void my_tester0_class_init (MyTester0Class*c) { call_counter_init (c); } +typedef GObject MyTester1; +typedef GObjectClass MyTester1Class; + +/* Disabled for now (see https://bugzilla.gnome.org/show_bug.cgi?id=687659) */ +#if 0 +typedef GTypeInterface MyFace2Interface; +static GType my_face2_get_type (void); +G_DEFINE_INTERFACE (MyFace2, my_face2, G_TYPE_OBJECT) +static void my_face2_default_init (MyFace2Interface *iface) { call_counter_init (iface); } + +static GType my_tester1_get_type (void); +G_DEFINE_TYPE_WITH_CODE (MyTester1, my_tester1, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (my_face0_get_type(), interface_per_class_init) + G_IMPLEMENT_INTERFACE (my_face1_get_type(), interface_per_class_init)) +static void my_tester1_init (MyTester1*t) {} +static void my_tester1_class_init (MyTester1Class*c) { call_counter_init (c); } +typedef GObject MyTester2; +typedef GObjectClass MyTester2Class; +static GType my_tester2_get_type (void); +G_DEFINE_TYPE_WITH_CODE (MyTester2, my_tester2, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (my_face0_get_type(), interface_per_class_init) + G_IMPLEMENT_INTERFACE (my_face1_get_type(), interface_per_class_init)) +static void my_tester2_init (MyTester2*t) {} +static void my_tester2_class_init (MyTester2Class*c) { call_counter_init (c); } + +static gpointer +tester_init_thread (gpointer data) +{ + const GInterfaceInfo face2_interface_info = { (GInterfaceInitFunc) interface_per_class_init, NULL, NULL }; + gpointer klass; + /* first, synchronize with other threads, + * then run interface and class initializers, + * using unsafe_call_counter concurrently + */ + g_mutex_lock (&sync_mutex); + g_mutex_unlock (&sync_mutex); + /* test default interface initialization for face0 */ + g_type_default_interface_unref (g_type_default_interface_ref (my_face0_get_type())); + /* test class initialization, face0 per-class initializer, face1 default and per-class initializer */ + klass = g_type_class_ref ((GType) data); + /* test face2 default and per-class initializer, after class_init */ + g_type_add_interface_static (G_TYPE_FROM_CLASS (klass), my_face2_get_type(), &face2_interface_info); + /* cleanups */ + g_type_class_unref (klass); + return NULL; +} + +static void +test_threaded_class_init (void) +{ + GThread *t1, *t2, *t3; + + /* pause newly created threads */ + g_mutex_lock (&sync_mutex); + + /* create threads */ + t1 = g_thread_create (tester_init_thread, (gpointer) my_tester0_get_type(), TRUE, NULL); + t2 = g_thread_create (tester_init_thread, (gpointer) my_tester1_get_type(), TRUE, NULL); + t3 = g_thread_create (tester_init_thread, (gpointer) my_tester2_get_type(), TRUE, NULL); + + /* execute threads */ + g_mutex_unlock (&sync_mutex); + while (g_atomic_int_get (&mtsafe_call_counter) < (3 + 3 + 3 * 3) * NUM_COUNTER_INCREMENTS) + { + if (g_test_verbose()) + g_printerr ("Initializers counted: %u\n", g_atomic_int_get (&mtsafe_call_counter)); + g_usleep (50 * 1000); /* wait for threads to complete */ + } + if (g_test_verbose()) + g_printerr ("Total initializers: %u\n", g_atomic_int_get (&mtsafe_call_counter)); + /* ensure non-corrupted counter updates */ + g_assert_cmpint (g_atomic_int_get (&mtsafe_call_counter), ==, unsafe_call_counter); + + g_thread_join (t1); + g_thread_join (t2); + g_thread_join (t3); +} +#endif + +typedef struct { + GObject parent; + char *name; +} PropTester; +typedef GObjectClass PropTesterClass; +static GType prop_tester_get_type (void); +G_DEFINE_TYPE (PropTester, prop_tester, G_TYPE_OBJECT) +#define PROP_NAME 1 +static void +prop_tester_init (PropTester* t) +{ + if (t->name == NULL) + { } /* needs unit test framework initialization: g_test_bug ("race initializing properties"); */ +} +static void +prop_tester_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{} +static void +prop_tester_class_init (PropTesterClass *c) +{ + int i; + GParamSpec *param; + GObjectClass *gobject_class = G_OBJECT_CLASS (c); + + gobject_class->set_property = prop_tester_set_property; /* silence GObject checks */ + + g_mutex_lock (&sync_mutex); + g_cond_signal (&sync_cond); + g_mutex_unlock (&sync_mutex); + + for (i = 0; i < 100; i++) /* wait a bit. */ + g_thread_yield(); + + call_counter_init (c); + param = g_param_spec_string ("name", "name_i18n", + "yet-more-wasteful-i18n", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | + G_PARAM_STATIC_NICK); + g_object_class_install_property (gobject_class, PROP_NAME, param); +} + +static gpointer +object_create (gpointer data) +{ + GObject *obj = g_object_new (prop_tester_get_type(), "name", "fish", NULL); + g_object_unref (obj); + return NULL; +} + +static void +test_threaded_object_init (void) +{ + GThread *creator; + g_mutex_lock (&sync_mutex); + + creator = g_thread_create (object_create, NULL, TRUE, NULL); + /* really provoke the race */ + g_cond_wait (&sync_cond, &sync_mutex); + + object_create (NULL); + g_mutex_unlock (&sync_mutex); + + g_thread_join (creator); +} + +typedef struct { + MyTester0 *strong; + guint unref_delay; +} UnrefInThreadData; + +static gpointer +unref_in_thread (gpointer p) +{ + UnrefInThreadData *data = p; + + g_usleep (data->unref_delay); + g_object_unref (data->strong); + + return NULL; +} + +/* undefine to see this test fail without GWeakRef */ +#define HAVE_G_WEAK_REF + +#define SLEEP_MIN_USEC 1 +#define SLEEP_MAX_USEC 10 + +static void +test_threaded_weak_ref (void) +{ + guint i; + guint get_wins = 0, unref_wins = 0; + guint n; + + if (g_test_thorough ()) + n = NUM_COUNTER_INCREMENTS; + else + n = NUM_COUNTER_INCREMENTS / 20; + +#ifdef G_OS_WIN32 + /* On Windows usleep has millisecond resolution and gets rounded up + * leading to the test running for a long time. */ + n /= 10; +#endif + + for (i = 0; i < n; i++) + { + UnrefInThreadData data; +#ifdef HAVE_G_WEAK_REF + /* GWeakRef in C++ terms */ + GWeakRef weak; +#else + gpointer weak; +#endif + MyTester0 *strengthened; + guint get_delay; + GThread *thread; + GError *error = NULL; + + if (g_test_verbose () && (i % (n/20)) == 0) + g_printerr ("%u%%\n", ((i * 100) / n)); + + /* Have an object and a weak ref to it */ + data.strong = g_object_new (my_tester0_get_type (), NULL); + +#ifdef HAVE_G_WEAK_REF + g_weak_ref_init (&weak, data.strong); +#else + weak = data.strong; + g_object_add_weak_pointer ((GObject *) weak, &weak); +#endif + + /* Delay for a random time on each side of the race, to perturb the + * timing. Ideally, we want each side to win half the races; on + * smcv's laptop, these timings are about right. + */ + data.unref_delay = g_random_int_range (SLEEP_MIN_USEC / 2, SLEEP_MAX_USEC / 2); + get_delay = g_random_int_range (SLEEP_MIN_USEC, SLEEP_MAX_USEC); + + /* One half of the race is to unref the shared object */ + thread = g_thread_create (unref_in_thread, &data, TRUE, &error); + g_assert_no_error (error); + + /* The other half of the race is to get the object from the "global + * singleton" + */ + g_usleep (get_delay); + +#ifdef HAVE_G_WEAK_REF + strengthened = g_weak_ref_get (&weak); +#else + /* Spot the unsafe pointer access! In GDBusConnection this is rather + * better-hidden, but ends up with essentially the same thing, albeit + * cleared in dispose() rather than by a traditional weak pointer + */ + strengthened = weak; + + if (strengthened != NULL) + g_object_ref (strengthened); +#endif + + if (strengthened != NULL) + g_assert (G_IS_OBJECT (strengthened)); + + /* Wait for the thread to run */ + g_thread_join (thread); + + if (strengthened != NULL) + { + get_wins++; + g_assert (G_IS_OBJECT (strengthened)); + g_object_unref (strengthened); + } + else + { + unref_wins++; + } + +#ifdef HAVE_G_WEAK_REF + g_weak_ref_clear (&weak); +#else + if (weak != NULL) + g_object_remove_weak_pointer (weak, &weak); +#endif + } + + if (g_test_verbose ()) + g_printerr ("Race won by get %u times, unref %u times\n", + get_wins, unref_wins); +} + +typedef struct +{ + GObject *object; + GWeakRef *weak; + gint started; /* (atomic) */ + gint finished; /* (atomic) */ + gint disposing; /* (atomic) */ +} ThreadedWeakRefData; + +static void +on_weak_ref_disposed (gpointer data, + GObject *gobj) +{ + ThreadedWeakRefData *thread_data = data; + + /* Wait until the thread has started */ + while (!g_atomic_int_get (&thread_data->started)) + continue; + + g_atomic_int_set (&thread_data->disposing, 1); + + /* Wait for the thread to act, so that the object is still valid */ + while (!g_atomic_int_get (&thread_data->finished)) + continue; + + g_atomic_int_set (&thread_data->disposing, 0); +} + +static gpointer +on_other_thread_weak_ref (gpointer user_data) +{ + ThreadedWeakRefData *thread_data = user_data; + GObject *object = thread_data->object; + + g_atomic_int_set (&thread_data->started, 1); + + /* Ensure we've started disposal */ + while (!g_atomic_int_get (&thread_data->disposing)) + continue; + + g_object_ref (object); + g_weak_ref_set (thread_data->weak, object); + g_object_unref (object); + + g_assert_cmpint (thread_data->disposing, ==, 1); + g_atomic_int_set (&thread_data->finished, 1); + + return NULL; +} + +static void +test_threaded_weak_ref_finalization (void) +{ + GObject *obj = g_object_new (G_TYPE_OBJECT, NULL); + GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } }; + ThreadedWeakRefData thread_data = { + .object = obj, .weak = &weak, .started = 0, .finished = 0 + }; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2390"); + g_test_summary ("Test that a weak ref added by another thread during dispose " + "of a GObject is cleared during finalisation. " + "Use on_weak_ref_disposed() to synchronize the other thread " + "with the dispose vfunc."); + + g_weak_ref_init (&weak, NULL); + g_object_weak_ref (obj, on_weak_ref_disposed, &thread_data); + + g_assert_cmpint (obj->ref_count, ==, 1); + g_thread_unref (g_thread_new ("on_other_thread", + on_other_thread_weak_ref, + &thread_data)); + g_object_unref (obj); + + /* This is what this test is about: at this point the weak reference + * should have been unset (and not point to a dead object either). */ + g_assert_null (g_weak_ref_get (&weak)); +} + +typedef struct +{ + GObject *object; + int done; /* (atomic) */ + int toggles; /* (atomic) */ +} ToggleNotifyThreadData; + +static gpointer +on_reffer_thread (gpointer user_data) +{ + ToggleNotifyThreadData *thread_data = user_data; + + while (!g_atomic_int_get (&thread_data->done)) + { + g_object_ref (thread_data->object); + g_object_unref (thread_data->object); + } + + return NULL; +} + +static void +on_toggle_notify (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + /* Anything could be put here, but we don't care for this test. + * Actually having this empty made the bug to happen more frequently (being + * timing related). + */ +} + +static gpointer +on_toggler_thread (gpointer user_data) +{ + ToggleNotifyThreadData *thread_data = user_data; + + while (!g_atomic_int_get (&thread_data->done)) + { + g_object_ref (thread_data->object); + g_object_remove_toggle_ref (thread_data->object, on_toggle_notify, thread_data); + g_object_add_toggle_ref (thread_data->object, on_toggle_notify, thread_data); + g_object_unref (thread_data->object); + g_atomic_int_add (&thread_data->toggles, 1); + } + + return NULL; +} + +static void +test_threaded_toggle_notify (void) +{ + GObject *object = g_object_new (G_TYPE_OBJECT, NULL); + ToggleNotifyThreadData data = { object, FALSE, 0 }; + GThread *threads[3]; + gsize i; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/2394"); + g_test_summary ("Test that toggle reference notifications can be changed " + "safely from another (the main) thread without causing the " + "notifying thread to abort"); + + g_object_add_toggle_ref (object, on_toggle_notify, &data); + g_object_unref (object); + + g_assert_cmpint (object->ref_count, ==, 1); + threads[0] = g_thread_new ("on_reffer_thread", on_reffer_thread, &data); + threads[1] = g_thread_new ("on_another_reffer_thread", on_reffer_thread, &data); + threads[2] = g_thread_new ("on_main_toggler_thread", on_toggler_thread, &data); + + /* We need to wait here for the threads to run for a bit in order to make the + * race to happen, so we wait for an high number of toggle changes to be met + * so that we can be consistent on each platform. + */ + while (g_atomic_int_get (&data.toggles) < 1000000) + ; + g_atomic_int_set (&data.done, TRUE); + + for (i = 0; i < G_N_ELEMENTS (threads); i++) + g_thread_join (threads[i]); + + g_assert_cmpint (object->ref_count, ==, 1); + g_clear_object (&object); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + /* g_test_add_func ("/GObject/threaded-class-init", test_threaded_class_init); */ + g_test_add_func ("/GObject/threaded-object-init", test_threaded_object_init); + g_test_add_func ("/GObject/threaded-weak-ref", test_threaded_weak_ref); + g_test_add_func ("/GObject/threaded-weak-ref/on-finalization", + test_threaded_weak_ref_finalization); + g_test_add_func ("/GObject/threaded-toggle-notify", + test_threaded_toggle_notify); + + return g_test_run(); +} diff --git a/gobject/tests/type-flags.c b/gobject/tests/type-flags.c new file mode 100644 index 0000000..249153b --- /dev/null +++ b/gobject/tests/type-flags.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: 2021 Emmanuele Bassi + +#include + +#define TEST_TYPE_FINAL (test_final_get_type()) +G_DECLARE_FINAL_TYPE (TestFinal, test_final, TEST, FINAL, GObject) + +struct _TestFinal +{ + GObject parent_instance; +}; + +struct _TestFinalClass +{ + GObjectClass parent_class; +}; + +G_DEFINE_FINAL_TYPE (TestFinal, test_final, G_TYPE_OBJECT) + +static void +test_final_class_init (TestFinalClass *klass) +{ +} + +static void +test_final_init (TestFinal *self) +{ +} + +#define TEST_TYPE_FINAL2 (test_final2_get_type()) +G_DECLARE_FINAL_TYPE (TestFinal2, test_final2, TEST, FINAL2, TestFinal) + +struct _TestFinal2 +{ + TestFinal parent_instance; +}; + +struct _TestFinal2Class +{ + TestFinalClass parent_class; +}; + +G_DEFINE_TYPE (TestFinal2, test_final2, TEST_TYPE_FINAL) + +static void +test_final2_class_init (TestFinal2Class *klass) +{ +} + +static void +test_final2_init (TestFinal2 *self) +{ +} + +/* test_type_flags_final: Check that trying to derive from a final class + * will result in a warning from the type system + */ +static void +test_type_flags_final (void) +{ + GType final2_type; + + /* This is the message we print out when registering the type */ + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, + "*cannot derive*"); + + /* This is the message when we fail to return from the GOnce init + * block within the test_final2_get_type() function + */ + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, + "*g_once_init_leave: assertion*"); + + final2_type = TEST_TYPE_FINAL2; + g_assert_true (final2_type == G_TYPE_INVALID); + + g_test_assert_expected_messages (); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/type/flags/final", test_type_flags_final); + + return g_test_run (); +} diff --git a/gobject/tests/type.c b/gobject/tests/type.c new file mode 100644 index 0000000..30e138a --- /dev/null +++ b/gobject/tests/type.c @@ -0,0 +1,215 @@ +#include + +static void +test_registration_serial (void) +{ + gint serial1, serial2, serial3; + + serial1 = g_type_get_type_registration_serial (); + g_pointer_type_register_static ("my+pointer"); + serial2 = g_type_get_type_registration_serial (); + g_assert (serial1 != serial2); + serial3 = g_type_get_type_registration_serial (); + g_assert (serial2 == serial3); +} + +typedef struct { + GTypeInterface g_iface; +} BarInterface; + +GType bar_get_type (void); + +G_DEFINE_INTERFACE (Bar, bar, G_TYPE_OBJECT) + +static void +bar_default_init (BarInterface *iface) +{ +} + +typedef struct { + GTypeInterface g_iface; +} FooInterface; + +GType foo_get_type (void); + +G_DEFINE_INTERFACE_WITH_CODE (Foo, foo, G_TYPE_OBJECT, + g_type_interface_add_prerequisite (g_define_type_id, bar_get_type ())) + +static void +foo_default_init (FooInterface *iface) +{ +} + +typedef struct { + GTypeInterface g_iface; +} BaaInterface; + +GType baa_get_type (void); + +G_DEFINE_INTERFACE (Baa, baa, G_TYPE_INVALID) + +static void +baa_default_init (BaaInterface *iface) +{ +} + +typedef struct { + GTypeInterface g_iface; +} BooInterface; + +GType boo_get_type (void); + +G_DEFINE_INTERFACE_WITH_CODE (Boo, boo, G_TYPE_INVALID, + g_type_interface_add_prerequisite (g_define_type_id, baa_get_type ())) + +static void +boo_default_init (BooInterface *iface) +{ +} + +typedef struct { + GTypeInterface g_iface; +} BibiInterface; + +GType bibi_get_type (void); + +G_DEFINE_INTERFACE (Bibi, bibi, G_TYPE_INITIALLY_UNOWNED) + +static void +bibi_default_init (BibiInterface *iface) +{ +} + +typedef struct { + GTypeInterface g_iface; +} BozoInterface; + +GType bozo_get_type (void); + +G_DEFINE_INTERFACE_WITH_CODE (Bozo, bozo, G_TYPE_INVALID, + g_type_interface_add_prerequisite (g_define_type_id, foo_get_type ()); + g_type_interface_add_prerequisite (g_define_type_id, bibi_get_type ())) + +static void +bozo_default_init (BozoInterface *iface) +{ +} + + + +static void +test_interface_prerequisite (void) +{ + GType *prereqs; + guint n_prereqs; + gpointer iface; + gpointer parent; + + prereqs = g_type_interface_prerequisites (foo_get_type (), &n_prereqs); + g_assert_cmpint (n_prereqs, ==, 2); + g_assert (prereqs[0] == bar_get_type ()); + g_assert (prereqs[1] == G_TYPE_OBJECT); + g_assert (g_type_interface_instantiatable_prerequisite (foo_get_type ()) == G_TYPE_OBJECT); + + iface = g_type_default_interface_ref (foo_get_type ()); + parent = g_type_interface_peek_parent (iface); + g_assert (parent == NULL); + g_type_default_interface_unref (iface); + + g_free (prereqs); + + g_assert_cmpint (g_type_interface_instantiatable_prerequisite (baa_get_type ()), ==, G_TYPE_INVALID); + g_assert_cmpint (g_type_interface_instantiatable_prerequisite (boo_get_type ()), ==, G_TYPE_INVALID); + + g_assert_cmpint (g_type_interface_instantiatable_prerequisite (bozo_get_type ()), ==, G_TYPE_INITIALLY_UNOWNED); +} + +typedef struct { + GTypeInterface g_iface; +} BazInterface; + +GType baz_get_type (void); + +G_DEFINE_INTERFACE (Baz, baz, G_TYPE_OBJECT) + +static void +baz_default_init (BazInterface *iface) +{ +} + +typedef struct { + GObject parent; +} Bazo; + +typedef struct { + GObjectClass parent_class; +} BazoClass; + +GType bazo_get_type (void); +static void bazo_iface_init (BazInterface *i); + +G_DEFINE_TYPE_WITH_CODE (Bazo, bazo, G_TYPE_INITIALLY_UNOWNED, + G_IMPLEMENT_INTERFACE (baz_get_type (), + bazo_iface_init);) + +static void +bazo_init (Bazo *b) +{ +} + +static void +bazo_class_init (BazoClass *c) +{ +} + +static void +bazo_iface_init (BazInterface *i) +{ +} + +static gint check_called; + +static void +check_func (gpointer check_data, + gpointer g_iface) +{ + g_assert (check_data == &check_called); + + check_called++; +} + +static void +test_interface_check (void) +{ + GObject *o; + + check_called = 0; + g_type_add_interface_check (&check_called, check_func); + o = g_object_new (bazo_get_type (), NULL); + g_object_unref (o); + g_assert_cmpint (check_called, ==, 1); + g_type_remove_interface_check (&check_called, check_func); +} + +static void +test_next_base (void) +{ + GType type; + + type = g_type_next_base (bazo_get_type (), G_TYPE_OBJECT); + + g_assert (type == G_TYPE_INITIALLY_UNOWNED); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/type/registration-serial", test_registration_serial); + g_test_add_func ("/type/interface-prerequisite", test_interface_prerequisite); + g_test_add_func ("/type/interface-check", test_interface_check); + g_test_add_func ("/type/next-base", test_next_base); + + return g_test_run (); +} diff --git a/gobject/tests/value.c b/gobject/tests/value.c new file mode 100644 index 0000000..3c7e881 --- /dev/null +++ b/gobject/tests/value.c @@ -0,0 +1,752 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_30 + +#include +#include +#include "gobject/gvaluecollector.h" + +static void +test_enum_transformation (void) +{ + GType type; + GValue orig = G_VALUE_INIT; + GValue xform = G_VALUE_INIT; + GEnumValue values[] = { {0,"0","0"}, {1,"1","1"}}; + + type = g_enum_register_static ("TestEnum", values); + + g_value_init (&orig, type); + g_value_set_enum (&orig, 1); + + memset (&xform, 0, sizeof (GValue)); + g_value_init (&xform, G_TYPE_CHAR); + g_value_transform (&orig, &xform); + g_assert_cmpint (g_value_get_char (&xform), ==, 1); + g_assert_cmpint (g_value_get_schar (&xform), ==, 1); + + memset (&xform, 0, sizeof (GValue)); + g_value_init (&xform, G_TYPE_UCHAR); + g_value_transform (&orig, &xform); + g_assert_cmpint (g_value_get_uchar (&xform), ==, 1); + + memset (&xform, 0, sizeof (GValue)); + g_value_init (&xform, G_TYPE_INT); + g_value_transform (&orig, &xform); + g_assert_cmpint (g_value_get_int (&xform), ==, 1); + + memset (&xform, 0, sizeof (GValue)); + g_value_init (&xform, G_TYPE_UINT); + g_value_transform (&orig, &xform); + g_assert_cmpint (g_value_get_uint (&xform), ==, 1); + + memset (&xform, 0, sizeof (GValue)); + g_value_init (&xform, G_TYPE_LONG); + g_value_transform (&orig, &xform); + g_assert_cmpint (g_value_get_long (&xform), ==, 1); + + memset (&xform, 0, sizeof (GValue)); + g_value_init (&xform, G_TYPE_ULONG); + g_value_transform (&orig, &xform); + g_assert_cmpint (g_value_get_ulong (&xform), ==, 1); + + memset (&xform, 0, sizeof (GValue)); + g_value_init (&xform, G_TYPE_INT64); + g_value_transform (&orig, &xform); + g_assert_cmpint (g_value_get_int64 (&xform), ==, 1); + + memset (&xform, 0, sizeof (GValue)); + g_value_init (&xform, G_TYPE_UINT64); + g_value_transform (&orig, &xform); + g_assert_cmpint (g_value_get_uint64 (&xform), ==, 1); +} + + +static void +test_gtype_value (void) +{ + GType type; + GValue value = G_VALUE_INIT; + GValue copy = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_GTYPE); + + g_value_set_gtype (&value, G_TYPE_BOXED); + type = g_value_get_gtype (&value); + g_assert_true (type == G_TYPE_BOXED); + + g_value_init (©, G_TYPE_GTYPE); + g_value_copy (&value, ©); + type = g_value_get_gtype (©); + g_assert_true (type == G_TYPE_BOXED); +} + +static gchar * +collect (GValue *value, ...) +{ + gchar *error; + va_list var_args; + + error = NULL; + + va_start (var_args, value); + G_VALUE_COLLECT (value, var_args, 0, &error); + va_end (var_args); + + return error; +} + +static gchar * +lcopy (GValue *value, ...) +{ + gchar *error; + va_list var_args; + + error = NULL; + + va_start (var_args, value); + G_VALUE_LCOPY (value, var_args, 0, &error); + va_end (var_args); + + return error; +} + +static void +test_collection (void) +{ + GValue value = G_VALUE_INIT; + gchar *error; + + g_value_init (&value, G_TYPE_CHAR); + error = collect (&value, 'c'); + g_assert_null (error); + g_assert_cmpint (g_value_get_char (&value), ==, 'c'); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_UCHAR); + error = collect (&value, 129); + g_assert_null (error); + g_assert_cmpint (g_value_get_uchar (&value), ==, 129); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_BOOLEAN); + error = collect (&value, TRUE); + g_assert_null (error); + g_assert_cmpint (g_value_get_boolean (&value), ==, TRUE); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_INT); + error = collect (&value, G_MAXINT); + g_assert_null (error); + g_assert_cmpint (g_value_get_int (&value), ==, G_MAXINT); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_UINT); + error = collect (&value, G_MAXUINT); + g_assert_null (error); + g_assert_cmpuint (g_value_get_uint (&value), ==, G_MAXUINT); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_LONG); + error = collect (&value, G_MAXLONG); + g_assert_null (error); + g_assert_cmpint (g_value_get_long (&value), ==, G_MAXLONG); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_ULONG); + error = collect (&value, G_MAXULONG); + g_assert_null (error); + g_assert_cmpuint (g_value_get_ulong (&value), ==, G_MAXULONG); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_INT64); + error = collect (&value, G_MAXINT64); + g_assert_null (error); + g_assert_cmpint (g_value_get_int64 (&value), ==, G_MAXINT64); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_UINT64); + error = collect (&value, G_MAXUINT64); + g_assert_null (error); + g_assert_cmpuint (g_value_get_uint64 (&value), ==, G_MAXUINT64); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_FLOAT); + error = collect (&value, G_MAXFLOAT); + g_assert_null (error); + g_assert_cmpfloat (g_value_get_float (&value), ==, G_MAXFLOAT); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_DOUBLE); + error = collect (&value, G_MAXDOUBLE); + g_assert_null (error); + g_assert_cmpfloat (g_value_get_double (&value), ==, G_MAXDOUBLE); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_STRING); + error = collect (&value, "string ?"); + g_assert_null (error); + g_assert_cmpstr (g_value_get_string (&value), ==, "string ?"); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_GTYPE); + error = collect (&value, G_TYPE_BOXED); + g_assert_null (error); + g_assert_true (g_value_get_gtype (&value) == G_TYPE_BOXED); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_VARIANT); + error = collect (&value, g_variant_new_uint32 (42)); + g_assert_null (error); + g_assert_true (g_variant_is_of_type (g_value_get_variant (&value), + G_VARIANT_TYPE ("u"))); + g_assert_cmpuint (g_variant_get_uint32 (g_value_get_variant (&value)), ==, 42); + + g_value_unset (&value); +} + +static void +test_copying (void) +{ + GValue value = G_VALUE_INIT; + gchar *error; + + { + gchar c = 0; + + g_value_init (&value, G_TYPE_CHAR); + g_value_set_char (&value, 'c'); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert_cmpint (c, ==, 'c'); + } + + { + guchar c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_UCHAR); + g_value_set_uchar (&value, 129); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert_cmpint (c, ==, 129); + } + + { + gint c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, G_MAXINT); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert_cmpint (c, ==, G_MAXINT); + } + + { + guint c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_UINT); + g_value_set_uint (&value, G_MAXUINT); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert_cmpuint (c, ==, G_MAXUINT); + } + + { + glong c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_LONG); + g_value_set_long (&value, G_MAXLONG); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert (c == G_MAXLONG); + } + + { + gulong c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_ULONG); + g_value_set_ulong (&value, G_MAXULONG); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert (c == G_MAXULONG); + } + + { + gint64 c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_INT64); + g_value_set_int64 (&value, G_MAXINT64); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert (c == G_MAXINT64); + } + + { + guint64 c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_UINT64); + g_value_set_uint64 (&value, G_MAXUINT64); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert (c == G_MAXUINT64); + } + + { + gfloat c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_FLOAT); + g_value_set_float (&value, G_MAXFLOAT); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert (c == G_MAXFLOAT); + } + + { + gdouble c = 0; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_DOUBLE); + g_value_set_double (&value, G_MAXDOUBLE); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert (c == G_MAXDOUBLE); + } + + { + gchar *c = NULL; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, "string ?"); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert_cmpstr (c, ==, "string ?"); + g_free (c); + } + + { + GType c = G_TYPE_NONE; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_GTYPE); + g_value_set_gtype (&value, G_TYPE_BOXED); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert_true (c == G_TYPE_BOXED); + } + + { + GVariant *c = NULL; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_VARIANT); + g_value_set_variant (&value, g_variant_new_uint32 (42)); + error = lcopy (&value, &c); + g_assert_null (error); + g_assert_nonnull (c); + g_assert (g_variant_is_of_type (c, G_VARIANT_TYPE ("u"))); + g_assert_cmpuint (g_variant_get_uint32 (c), ==, 42); + g_variant_unref (c); + g_value_unset (&value); + } +} + +static void +test_value_basic (void) +{ + GValue value = G_VALUE_INIT; + + g_assert_false (G_IS_VALUE (&value)); + g_assert_false (G_VALUE_HOLDS_INT (&value)); + g_value_unset (&value); + g_assert_false (G_IS_VALUE (&value)); + g_assert_false (G_VALUE_HOLDS_INT (&value)); + + g_value_init (&value, G_TYPE_INT); + g_assert_true (G_IS_VALUE (&value)); + g_assert_true (G_VALUE_HOLDS_INT (&value)); + g_assert_false (G_VALUE_HOLDS_UINT (&value)); + g_assert_cmpint (g_value_get_int (&value), ==, 0); + + g_value_set_int (&value, 10); + g_assert_cmpint (g_value_get_int (&value), ==, 10); + + g_value_reset (&value); + g_assert_true (G_IS_VALUE (&value)); + g_assert_true (G_VALUE_HOLDS_INT (&value)); + g_assert_cmpint (g_value_get_int (&value), ==, 0); + + g_value_unset (&value); + g_assert_false (G_IS_VALUE (&value)); + g_assert_false (G_VALUE_HOLDS_INT (&value)); +} + +static void +test_value_string (void) +{ + const gchar *static1 = "static1"; + const gchar *static2 = "static2"; + const gchar *storedstr; + const gchar *copystr; + gchar *str1, *str2; + GValue value = G_VALUE_INIT; + GValue copy = G_VALUE_INIT; + + g_test_summary ("Test that G_TYPE_STRING GValue copy properly"); + + /* + * Regular strings (ownership not passed) + */ + + /* Create a regular string gvalue and make sure it copies the provided string */ + g_value_init (&value, G_TYPE_STRING); + g_assert_true (G_VALUE_HOLDS_STRING (&value)); + + /* The string contents should be empty at this point */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr == NULL); + + g_value_set_string (&value, static1); + /* The contents should be a copy of the same string */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr != static1); + g_assert_cmpstr (storedstr, ==, static1); + /* Check g_value_dup_string() provides a copy */ + str1 = g_value_dup_string (&value); + g_assert_true (storedstr != str1); + g_assert_cmpstr (str1, ==, static1); + g_free (str1); + + /* Copying a regular string gvalue should copy the contents */ + g_value_init (©, G_TYPE_STRING); + g_value_copy (&value, ©); + copystr = g_value_get_string (©); + g_assert_true (copystr != storedstr); + g_assert_cmpstr (copystr, ==, static1); + g_value_unset (©); + + /* Setting a new string should change the contents */ + g_value_set_string (&value, static2); + /* The contents should be a copy of that *new* string */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr != static2); + g_assert_cmpstr (storedstr, ==, static2); + + /* Setting a static string over that should also change it (test for + * coverage and valgrind) */ + g_value_set_static_string (&value, static1); + storedstr = g_value_get_string (&value); + g_assert_true (storedstr != static2); + g_assert_cmpstr (storedstr, ==, static1); + + /* Giving a string directly (ownership passed) should replace the content */ + str2 = g_strdup (static2); + g_value_take_string (&value, str2); + storedstr = g_value_get_string (&value); + g_assert_true (storedstr != static2); + g_assert_cmpstr (storedstr, ==, str2); + + g_value_unset (&value); + + /* + * Regular strings (ownership passed) + */ + + g_value_init (&value, G_TYPE_STRING); + g_assert_true (G_VALUE_HOLDS_STRING (&value)); + str1 = g_strdup (static1); + g_value_take_string (&value, str1); + /* The contents should be the string we provided */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr == str1); + /* But g_value_dup_string() should provide a copy */ + str2 = g_value_dup_string (&value); + g_assert_true (storedstr != str2); + g_assert_cmpstr (str2, ==, static1); + g_free (str2); + + /* Copying a regular string gvalue (even with ownership passed) should copy + * the contents */ + g_value_init (©, G_TYPE_STRING); + g_value_copy (&value, ©); + copystr = g_value_get_string (©); + g_assert_true (copystr != storedstr); + g_assert_cmpstr (copystr, ==, static1); + g_value_unset (©); + + /* Setting a new regular string should change the contents */ + g_value_set_string (&value, static2); + /* The contents should be a copy of that *new* string */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr != static2); + g_assert_cmpstr (storedstr, ==, static2); + + g_value_unset (&value); + + /* + * Static strings + */ + g_value_init (&value, G_TYPE_STRING); + g_assert_true (G_VALUE_HOLDS_STRING (&value)); + g_value_set_static_string (&value, static1); + /* The contents should be the string we provided */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr == static1); + /* But g_value_dup_string() should provide a copy */ + str2 = g_value_dup_string (&value); + g_assert_true (storedstr != str2); + g_assert_cmpstr (str2, ==, static1); + g_free (str2); + + /* Copying a static string gvalue should *actually* copy the contents */ + g_value_init (©, G_TYPE_STRING); + g_value_copy (&value, ©); + copystr = g_value_get_string (©); + g_assert_true (copystr != static1); + g_value_unset (©); + + /* Setting a new string should change the contents */ + g_value_set_static_string (&value, static2); + /* The contents should be a copy of that *new* string */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr != static1); + g_assert_cmpstr (storedstr, ==, static2); + + g_value_unset (&value); + + /* + * Interned/Canonical strings + */ + static1 = g_intern_static_string (static1); + g_value_init (&value, G_TYPE_STRING); + g_assert_true (G_VALUE_HOLDS_STRING (&value)); + g_value_set_interned_string (&value, static1); + g_assert_true (G_VALUE_IS_INTERNED_STRING (&value)); + /* The contents should be the string we provided */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr == static1); + /* But g_value_dup_string() should provide a copy */ + str2 = g_value_dup_string (&value); + g_assert_true (storedstr != str2); + g_assert_cmpstr (str2, ==, static1); + g_free (str2); + + /* Copying an interned string gvalue should *not* copy the contents + * and should still be an interned string */ + g_value_init (©, G_TYPE_STRING); + g_value_copy (&value, ©); + g_assert_true (G_VALUE_IS_INTERNED_STRING (©)); + copystr = g_value_get_string (©); + g_assert_true (copystr == static1); + g_value_unset (©); + + /* Setting a new interned string should change the contents */ + static2 = g_intern_static_string (static2); + g_value_set_interned_string (&value, static2); + g_assert_true (G_VALUE_IS_INTERNED_STRING (&value)); + /* The contents should be the interned string */ + storedstr = g_value_get_string (&value); + g_assert_cmpstr (storedstr, ==, static2); + + /* Setting a new regular string should change the contents */ + g_value_set_string (&value, static2); + g_assert_false (G_VALUE_IS_INTERNED_STRING (&value)); + /* The contents should be a copy of that *new* string */ + storedstr = g_value_get_string (&value); + g_assert_true (storedstr != static2); + g_assert_cmpstr (storedstr, ==, static2); + + g_value_unset (&value); +} + +static gint +cmpint (gconstpointer a, gconstpointer b) +{ + const GValue *aa = a; + const GValue *bb = b; + + return g_value_get_int (aa) - g_value_get_int (bb); +} + +static void +test_valuearray_basic (void) +{ + GValueArray *a; + GValueArray *a2; + GValue v = G_VALUE_INIT; + GValue *p; + guint i; + + a = g_value_array_new (20); + + g_value_init (&v, G_TYPE_INT); + for (i = 0; i < 100; i++) + { + g_value_set_int (&v, i); + g_value_array_append (a, &v); + } + + g_assert_cmpint (a->n_values, ==, 100); + p = g_value_array_get_nth (a, 5); + g_assert_cmpint (g_value_get_int (p), ==, 5); + + for (i = 20; i < 100; i+= 5) + g_value_array_remove (a, 100 - i); + + for (i = 100; i < 150; i++) + { + g_value_set_int (&v, i); + g_value_array_prepend (a, &v); + } + + g_value_array_sort (a, cmpint); + for (i = 0; i < a->n_values - 1; i++) + g_assert_cmpint (g_value_get_int (&a->values[i]), <=, g_value_get_int (&a->values[i+1])); + + a2 = g_value_array_copy (a); + for (i = 0; i < a->n_values; i++) + g_assert_cmpint (g_value_get_int (&a->values[i]), ==, g_value_get_int (&a2->values[i])); + + g_value_array_free (a); + g_value_array_free (a2); +} + +/* We create some dummy objects with this relationship: + * + * GObject TestInterface + * / \ / / + * TestObjectA TestObjectB / + * / \ / + * TestObjectA1 TestObjectA2------- + * + * ie: TestObjectA1 and TestObjectA2 are subclasses of TestObjectA + * and TestObjectB is related to neither. TestObjectA2 and TestObjectB + * implement TestInterface + */ + +typedef GTypeInterface TestInterfaceInterface; +static GType test_interface_get_type (void); +G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT) +static void test_interface_default_init (TestInterfaceInterface *iface) { } + +static GType test_object_a_get_type (void); +typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass; +G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT) +static void test_object_a_class_init (TestObjectAClass *class) { } +static void test_object_a_init (TestObjectA *a) { } + +static GType test_object_b_get_type (void); +typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass; +static void test_object_b_iface_init (TestInterfaceInterface *iface) { } +G_DEFINE_TYPE_WITH_CODE (TestObjectB, test_object_b, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_object_b_iface_init)) +static void test_object_b_class_init (TestObjectBClass *class) { } +static void test_object_b_init (TestObjectB *b) { } + +static GType test_object_a1_get_type (void); +typedef GObject TestObjectA1; typedef GObjectClass TestObjectA1Class; +G_DEFINE_TYPE (TestObjectA1, test_object_a1, test_object_a_get_type ()) +static void test_object_a1_class_init (TestObjectA1Class *class) { } +static void test_object_a1_init (TestObjectA1 *c) { } + +static GType test_object_a2_get_type (void); +typedef GObject TestObjectA2; typedef GObjectClass TestObjectA2Class; +static void test_object_a2_iface_init (TestInterfaceInterface *iface) { } +G_DEFINE_TYPE_WITH_CODE (TestObjectA2, test_object_a2, test_object_a_get_type (), + G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_object_a2_iface_init)) +static void test_object_a2_class_init (TestObjectA2Class *class) { } +static void test_object_a2_init (TestObjectA2 *b) { } + +static void +test_value_transform_object (void) +{ + GValue src = G_VALUE_INIT; + GValue dest = G_VALUE_INIT; + GObject *object; + guint i, s, d; + GType types[] = { + G_TYPE_OBJECT, + test_interface_get_type (), + test_object_a_get_type (), + test_object_b_get_type (), + test_object_a1_get_type (), + test_object_a2_get_type () + }; + + for (i = 0; i < G_N_ELEMENTS (types); i++) + { + if (!G_TYPE_IS_CLASSED (types[i])) + continue; + + object = g_object_new (types[i], NULL); + + for (s = 0; s < G_N_ELEMENTS (types); s++) + { + if (!G_TYPE_CHECK_INSTANCE_TYPE (object, types[s])) + continue; + + g_value_init (&src, types[s]); + g_value_set_object (&src, object); + + for (d = 0; d < G_N_ELEMENTS (types); d++) + { + g_test_message ("Next: %s object in GValue of %s to GValue of %s", g_type_name (types[i]), g_type_name (types[s]), g_type_name (types[d])); + g_assert_true (g_value_type_transformable (types[s], types[d])); + g_value_init (&dest, types[d]); + g_assert_true (g_value_transform (&src, &dest)); + g_assert_cmpint (g_value_get_object (&dest) != NULL, ==, G_TYPE_CHECK_INSTANCE_TYPE (object, types[d])); + g_value_unset (&dest); + } + g_value_unset (&src); + } + + g_object_unref (object); + } +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/value/basic", test_value_basic); + g_test_add_func ("/value/array/basic", test_valuearray_basic); + g_test_add_func ("/value/collection", test_collection); + g_test_add_func ("/value/copying", test_copying); + g_test_add_func ("/value/enum-transformation", test_enum_transformation); + g_test_add_func ("/value/gtype", test_gtype_value); + g_test_add_func ("/value/string", test_value_string); + g_test_add_func ("/value/transform-object", test_value_transform_object); + + return g_test_run (); +} diff --git a/gthread/gthread-impl.c b/gthread/gthread-impl.c new file mode 100644 index 0000000..266dd84 --- /dev/null +++ b/gthread/gthread-impl.c @@ -0,0 +1,48 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: thread related functions + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include + +void +g_thread_init (gpointer init) +{ + if (init != NULL) + g_warning ("GThread system no longer supports custom thread implementations."); +} + +void +g_thread_init_with_errorcheck_mutexes (gpointer vtable) +{ + g_assert (vtable == NULL); + g_warning ("GThread system no longer supports errorcheck mutexes."); +} diff --git a/gthread/gthread.def b/gthread/gthread.def new file mode 100644 index 0000000..200b043 --- /dev/null +++ b/gthread/gthread.def @@ -0,0 +1,3 @@ +EXPORTS + g_thread_init + g_thread_init_with_errorcheck_mutexes diff --git a/gthread/gthread.rc.in b/gthread/gthread.rc.in new file mode 100644 index 0000000..9e45fdf --- /dev/null +++ b/gthread/gthread.rc.in @@ -0,0 +1,30 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + FILEFLAGSMASK 0 + FILEFLAGS 0 + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "The GLib developer community" + VALUE "FileDescription", "GThread" + VALUE "FileVersion", "@GLIB_VERSION@.0" + VALUE "InternalName", "libgthread-2.0-@LT_CURRENT_MINUS_AGE@" + VALUE "LegalCopyright", "Copyright 1995-2011 Peter Mattis, Spencer Kimball, Josh MacDonald, Sebastian Wilhelmi and others." + VALUE "OriginalFilename", "libgthread-2.0-@LT_CURRENT_MINUS_AGE@.dll" + VALUE "ProductName", "GLib" + VALUE "ProductVersion", "@GLIB_VERSION@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END + END diff --git a/gthread/meson.build b/gthread/meson.build new file mode 100644 index 0000000..808e889 --- /dev/null +++ b/gthread/meson.build @@ -0,0 +1,40 @@ +# Just a skeleton lib for backwards compatibility since all the functionaliy +# has been moved into glib now + +gthread_sources = ['gthread-impl.c'] +if host_system == 'windows' + gthread_win_rc = configure_file( + input: 'gthread.rc.in', + output: 'gthread.rc', + configuration: glibconfig_conf, + ) + gthread_win_res = windows.compile_resources(gthread_win_rc) + gthread_sources += [gthread_win_res] +endif + +libgthread = library('gthread-2.0', + sources : gthread_sources, + version : library_version, + soversion : soversion, + darwin_versions : darwin_versions, + install : true, + dependencies : [libglib_dep], + c_args : ['-DG_LOG_DOMAIN="GThread"' ] + glib_hidden_visibility_args, + link_args : glib_link_flags, +) + +pkg.generate(libgthread, + libraries : [thread_dep], + requires : ['glib-2.0'], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gthread-2.0', + name : 'GThread', + description : 'Thread support for GLib', +) + +libgthread_dep = declare_dependency(link_with : libgthread) + +if meson.version().version_compare('>=0.54.0') + meson.override_dependency('gthread-2.0', libgthread_dep) +endif diff --git a/m4macros/attributes.m4 b/m4macros/attributes.m4 new file mode 100644 index 0000000..f0bcf24 --- /dev/null +++ b/m4macros/attributes.m4 @@ -0,0 +1,288 @@ +dnl Macros to check the presence of generic (non-typed) symbols. +dnl Copyright (c) 2006-2008 Diego Pettenò +dnl Copyright (c) 2006-2008 xine project +dnl Copyright (c) 2012 Lucas De Marchi +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. +dnl +dnl As a special exception, the copyright owners of the +dnl macro gives unlimited permission to copy, distribute and modify the +dnl configure scripts that are the output of Autoconf when processing the +dnl Macro. You need not follow the terms of the GNU General Public +dnl License when using or distributing such scripts, even though portions +dnl of the text of the Macro appear in them. The GNU General Public +dnl License (GPL) does govern all other use of the material that +dnl constitutes the Autoconf Macro. +dnl +dnl This special exception to the GPL applies to versions of the +dnl Autoconf Macro released by this project. When you make and +dnl distribute a modified version of the Autoconf Macro, you may extend +dnl this special exception to the GPL to apply to your modified version as +dnl well. + +dnl Check if FLAG in ENV-VAR is supported by compiler and append it +dnl to WHERE-TO-APPEND variable +dnl CC_CHECK_FLAG_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG]) + +AC_DEFUN([CC_CHECK_FLAG_APPEND], [ + AC_CACHE_CHECK([if $CC supports flag $3 in envvar $2], + AS_TR_SH([cc_cv_$2_$3]), + [eval "AS_TR_SH([cc_save_$2])='${$2}'" + eval "AS_TR_SH([$2])='-Werror $3'" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])], + [eval "AS_TR_SH([cc_cv_$2_$3])='yes'"], + [eval "AS_TR_SH([cc_cv_$2_$3])='no'"]) + eval "AS_TR_SH([$2])='$cc_save_$2'"]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_$2_$3])[ = xyes], + [eval "$1='${$1} $3'"]) +]) + +dnl CC_CHECK_FLAGS_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG1 FLAG2]) +AC_DEFUN([CC_CHECK_FLAGS_APPEND], [ + for flag in $3; do + CC_CHECK_FLAG_APPEND($1, $2, $flag) + done +]) + +dnl Check if the flag is supported by linker (cacheable) +dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_LDFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_ldflags_$1]), + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $1" + AC_LINK_IFELSE([int main() { return 1; }], + [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) + LDFLAGS="$ac_save_LDFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for +dnl the current linker to avoid undefined references in a shared object. +AC_DEFUN([CC_NOUNDEFINED], [ + dnl We check $host for which systems to enable this for. + AC_REQUIRE([AC_CANONICAL_HOST]) + + case $host in + dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads + dnl are requested, as different implementations are present; to avoid problems + dnl use -Wl,-z,defs only for those platform not behaving this way. + *-freebsd* | *-openbsd*) ;; + *) + dnl First of all check for the --no-undefined variant of GNU ld. This allows + dnl for a much more readable commandline, so that people can understand what + dnl it does without going to look for what the heck -z defs does. + for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do + CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) + break + done + ;; + esac + + AC_SUBST([LDFLAGS_NOUNDEFINED]) +]) + +dnl Check for a -Werror flag or equivalent. -Werror is the GCC +dnl and ICC flag that tells the compiler to treat all the warnings +dnl as fatal. We usually need this option to make sure that some +dnl constructs (like attributes) are not simply ignored. +dnl +dnl Other compilers don't support -Werror per se, but they support +dnl an equivalent flag: +dnl - Sun Studio compiler supports -errwarn=%all +AC_DEFUN([CC_CHECK_WERROR], [ + AC_CACHE_CHECK( + [for $CC way to treat warnings as errors], + [cc_cv_werror], + [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], + [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) + ]) +]) + +AC_DEFUN([CC_CHECK_ATTRIBUTE], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], + AS_TR_SH([cc_cv_attribute_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], + [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], + [AC_DEFINE( + AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, + [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] + ) + $4], + [$5]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ + CC_CHECK_ATTRIBUTE( + [constructor],, + [void __attribute__((constructor)) ctor() { int a; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ + CC_CHECK_ATTRIBUTE( + [format], [format(printf, n, n)], + [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ + CC_CHECK_ATTRIBUTE( + [format_arg], [format_arg(printf)], + [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ + CC_CHECK_ATTRIBUTE( + [visibility_$1], [visibility("$1")], + [void __attribute__((visibility("$1"))) $1_function() { }], + [$2], [$3]) +]) + +AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ + CC_CHECK_ATTRIBUTE( + [nonnull], [nonnull()], + [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ + CC_CHECK_ATTRIBUTE( + [unused], , + [void some_function(void *foo, __attribute__((unused)) void *bar);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ + CC_CHECK_ATTRIBUTE( + [sentinel], , + [void some_function(void *foo, ...) __attribute__((sentinel));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ + CC_CHECK_ATTRIBUTE( + [deprecated], , + [void some_function(void *foo, ...) __attribute__((deprecated));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ + CC_CHECK_ATTRIBUTE( + [alias], [weak, alias], + [void other_function(void *foo) { } + void some_function(void *foo) __attribute__((weak, alias("other_function")));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ + CC_CHECK_ATTRIBUTE( + [malloc], , + [void * __attribute__((malloc)) my_alloc(int n);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_PACKED], [ + CC_CHECK_ATTRIBUTE( + [packed], , + [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONST], [ + CC_CHECK_ATTRIBUTE( + [const], , + [int __attribute__((const)) twopow(int n) { return 1 << n; } ], + [$1], [$2]) +]) + +AC_DEFUN([CC_FLAG_VISIBILITY], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], + [cc_cv_flag_visibility], + [cc_flag_visibility_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], + cc_cv_flag_visibility='yes', + cc_cv_flag_visibility='no') + CFLAGS="$cc_flag_visibility_save_CFLAGS"]) + + AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], + [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, + [Define this if the compiler supports the -fvisibility flag]) + $1], + [$2]) +]) + +AC_DEFUN([CC_FUNC_EXPECT], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if compiler has __builtin_expect function], + [cc_cv_func_expect], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [int some_function() { + int a = 3; + return (int)__builtin_expect(a, 3); + }])], + [cc_cv_func_expect=yes], + [cc_cv_func_expect=no]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([test "x$cc_cv_func_expect" = "xyes"], + [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, + [Define this if the compiler supports __builtin_expect() function]) + $1], + [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], + [cc_cv_attribute_aligned], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + for cc_attribute_align_try in 64 32 16 8 4 2; do + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + int main() { + static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; + return c; + }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) + done + CFLAGS="$ac_save_CFLAGS" + ]) + + if test "x$cc_cv_attribute_aligned" != "x"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], + [Define the highest alignment supported]) + fi +]) diff --git a/m4macros/glib-2.0.m4 b/m4macros/glib-2.0.m4 new file mode 100644 index 0000000..5fc357c --- /dev/null +++ b/m4macros/glib-2.0.m4 @@ -0,0 +1,215 @@ +# Configure paths for GLIB +# Owen Taylor 1997-2001 + +# Increment this whenever this file is changed. +#serial 4 + +dnl AM_PATH_GLIB_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) +dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject, +dnl gthread, or gio is specified in MODULES, pass to pkg-config +dnl +AC_DEFUN([AM_PATH_GLIB_2_0], +[dnl +dnl Get the cflags and libraries from pkg-config +dnl + +dnl We can't use PKG_PREREQ because that needs 0.29. +m4_ifndef([PKG_PROG_PKG_CONFIG], + [pkg.m4 version 0.28 or later is required]) + +AC_ARG_ENABLE(glibtest, [ --disable-glibtest do not try to compile and run a test GLIB program], + , enable_glibtest=yes) + + min_glib_version=ifelse([$1], [], [2.0.0], [$1]) + pkg_config_args="glib-2.0 >= $min_glib_version" + for module in . $4 + do + case "$module" in + gmodule) + pkg_config_args="$pkg_config_args gmodule-2.0" + ;; + gmodule-no-export) + pkg_config_args="$pkg_config_args gmodule-no-export-2.0" + ;; + gobject) + pkg_config_args="$pkg_config_args gobject-2.0" + ;; + gthread) + pkg_config_args="$pkg_config_args gthread-2.0" + ;; + gio*) + pkg_config_args="$pkg_config_args $module-2.0" + ;; + esac + done + + PKG_PROG_PKG_CONFIG([0.16]) + + no_glib="" + + if test "x$PKG_CONFIG" = x ; then + no_glib=yes + PKG_CONFIG=no + fi + + dnl For GLIB_CFLAGS and GLIB_LIBS + PKG_CHECK_MODULES([GLIB], [$pkg_config_args], [:], [:]) + + dnl For the tools + PKG_CHECK_VAR([GLIB_GENMARSHAL], [glib-2.0], [glib_genmarshal]) + PKG_CHECK_VAR([GOBJECT_QUERY], [glib-2.0], [gobject_query]) + PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.0], [glib_mkenums]) + PKG_CHECK_VAR([GLIB_COMPILE_RESOURCES], [gio-2.0], [glib_compile_resources]) + + AC_MSG_CHECKING(for GLIB - version >= $min_glib_version) + + if test x$PKG_CONFIG != xno ; then + ## don't try to run the test against uninstalled libtool libs + if $PKG_CONFIG --uninstalled $pkg_config_args; then + echo "Will use uninstalled version of GLib found in PKG_CONFIG_PATH" + enable_glibtest=no + fi + + if $PKG_CONFIG --atleast-version $min_glib_version $pkg_config_args; then + : + else + no_glib=yes + fi + fi + + if test x"$no_glib" = x ; then + glib_config_major_version=`$PKG_CONFIG --modversion glib-2.0 | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + glib_config_minor_version=`$PKG_CONFIG --modversion glib-2.0 | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + glib_config_micro_version=`$PKG_CONFIG --modversion glib-2.0 | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_glibtest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GLIB_CFLAGS" + LIBS="$GLIB_LIBS $LIBS" +dnl +dnl Now check if the installed GLib is sufficiently new. (Also sanity +dnl checks the results of pkg-config to some extent) +dnl + rm -f conf.glibtest + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include + +int +main (void) +{ + unsigned int major, minor, micro; + + fclose (fopen ("conf.glibtest", "w")); + + if (sscanf("$min_glib_version", "%u.%u.%u", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_glib_version"); + exit(1); + } + + if ((glib_major_version != $glib_config_major_version) || + (glib_minor_version != $glib_config_minor_version) || + (glib_micro_version != $glib_config_micro_version)) + { + printf("\n*** 'pkg-config --modversion glib-2.0' returned %d.%d.%d, but GLIB (%d.%d.%d)\n", + $glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version, + glib_major_version, glib_minor_version, glib_micro_version); + printf ("*** was found! If pkg-config was correct, then it is best\n"); + printf ("*** to remove the old version of GLib. You may also be able to fix the error\n"); + printf("*** by modifying your LD_LIBRARY_PATH environment variable, or by editing\n"); + printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); + printf("*** required on your system.\n"); + printf("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n"); + printf("*** to point to the correct configuration files\n"); + } + else if ((glib_major_version != GLIB_MAJOR_VERSION) || + (glib_minor_version != GLIB_MINOR_VERSION) || + (glib_micro_version != GLIB_MICRO_VERSION)) + { + printf("*** GLib header files (version %d.%d.%d) do not match\n", + GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); + printf("*** library (version %d.%d.%d)\n", + glib_major_version, glib_minor_version, glib_micro_version); + } + else + { + if ((glib_major_version > major) || + ((glib_major_version == major) && (glib_minor_version > minor)) || + ((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** An old version of GLib (%u.%u.%u) was found.\n", + glib_major_version, glib_minor_version, glib_micro_version); + printf("*** You need a version of GLib newer than %u.%u.%u. The latest version of\n", + major, minor, micro); + printf("*** GLib is always available from ftp://ftp.gtk.org.\n"); + printf("***\n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the pkg-config shell script is\n"); + printf("*** being found. The easiest way to fix this is to remove the old version\n"); + printf("*** of GLib, but you can also set the PKG_CONFIG environment to point to the\n"); + printf("*** correct copy of pkg-config. (In this case, you will have to\n"); + printf("*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf\n"); + printf("*** so that the correct libraries are found at run-time))\n"); + } + } + return 1; +} +]])],[],[no_glib=yes],[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_glib" = x ; then + AC_MSG_RESULT(yes (version $glib_config_major_version.$glib_config_minor_version.$glib_config_micro_version)) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$PKG_CONFIG" = "no" ; then + echo "*** A new enough version of pkg-config was not found." + echo "*** See http://www.freedesktop.org/software/pkgconfig/" + else + if test -f conf.glibtest ; then + : + else + echo "*** Could not run GLib test program, checking why..." + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GLIB_CFLAGS" + LIBS="$LIBS $GLIB_LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +]], [[ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ]])], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding GLib or finding the wrong" + echo "*** version of GLib. If it is not finding GLib, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occurred. This usually means GLib is incorrectly installed."]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + GLIB_CFLAGS="" + GLIB_LIBS="" + GLIB_GENMARSHAL="" + GOBJECT_QUERY="" + GLIB_MKENUMS="" + GLIB_COMPILE_RESOURCES="" + ifelse([$3], , :, [$3]) + fi + rm -f conf.glibtest +]) diff --git a/m4macros/glib-gettext.m4 b/m4macros/glib-gettext.m4 new file mode 100644 index 0000000..df6fbf0 --- /dev/null +++ b/m4macros/glib-gettext.m4 @@ -0,0 +1,486 @@ +# Copyright (C) 1995-2002 Free Software Foundation, Inc. +# Copyright (C) 2001-2003,2004 Red Hat, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995, 1996 +# +# Modified to never use included libintl. +# Owen Taylor , 12/15/1998 +# +# Major rework to remove unused code +# Owen Taylor , 12/11/2002 +# +# Added better handling of ALL_LINGUAS from GNU gettext version +# written by Bruno Haible, Owen Taylor 5/30/3002 +# +# Modified to require ngettext +# Matthias Clasen 08/06/2004 + +# Increment this whenever this file is changed. +#serial 1 + +# We need this here as well, since someone might use autoconf-2.5x +# to configure GLib then an older version to configure a package +# using AM_GLIB_GNU_GETTEXT +AC_PREREQ(2.53) + +dnl +dnl We go to great lengths to make sure that aclocal won't +dnl try to pull in the installed version of these macros +dnl when running aclocal in the glib directory. +dnl +m4_copy([AC_DEFUN],[glib_DEFUN]) +m4_copy([AC_REQUIRE],[glib_REQUIRE]) +dnl +dnl At the end, if we're not within glib, we'll define the public +dnl definitions in terms of our private definitions. +dnl + +# GLIB_LC_MESSAGES +#-------------------- +glib_DEFUN([GLIB_LC_MESSAGES], + [AC_CHECK_HEADERS([locale.h]) + if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi + fi]) + +# GLIB_PATH_PROG_WITH_TEST +#---------------------------- +dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +dnl Checks for special options needed on Mac OS X. +dnl Defines INTL_MACOSX_LIBS. +dnl +dnl Copied from intlmacosx.m4 in gettext, GPL. +dnl Copyright (C) 2004-2013 Free Software Foundation, Inc. +glib_DEFUN([glib_gt_INTL_MACOSX], +[ + dnl Check for API introduced in Mac OS X 10.2. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + [gt_cv_func_CFPreferencesCopyAppValue], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[CFPreferencesCopyAppValue(NULL, NULL)]])], + [gt_cv_func_CFPreferencesCopyAppValue=yes], + [gt_cv_func_CFPreferencesCopyAppValue=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], + [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi + dnl Check for API introduced in Mac OS X 10.3. + AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[CFLocaleCopyCurrent();]])], + [gt_cv_func_CFLocaleCopyCurrent=yes], + [gt_cv_func_CFLocaleCopyCurrent=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], + [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + AC_SUBST([INTL_MACOSX_LIBS]) +]) + +# GLIB_WITH_NLS +#----------------- +glib_DEFUN([GLIB_WITH_NLS], + dnl NLS is obligatory + [USE_NLS=yes + AC_SUBST(USE_NLS) + + gt_cv_have_gettext=no + + CATOBJEXT=NONE + XGETTEXT=: + INTLLIBS= + + glib_gt_INTL_MACOSX + + AC_CHECK_HEADER(libintl.h, + [gt_cv_func_dgettext_libintl="no" + libintl_extra_libs="" + + # + # First check in libc + # + AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc, + [AC_TRY_LINK([ +#include +], + [return !ngettext ("","", 1)], + gt_cv_func_ngettext_libc=yes, + gt_cv_func_ngettext_libc=no) + ]) + + if test "$gt_cv_func_ngettext_libc" = "yes" ; then + AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, + [AC_TRY_LINK([ +#include +], + [return !dgettext ("","")], + gt_cv_func_dgettext_libc=yes, + gt_cv_func_dgettext_libc=no) + ]) + fi + + if test "$gt_cv_func_ngettext_libc" = "yes" ; then + AC_CHECK_FUNCS(bind_textdomain_codeset) + fi + + # + # If we don't have everything we want, check in libintl + # + if test "$gt_cv_func_dgettext_libc" != "yes" \ + || test "$gt_cv_func_ngettext_libc" != "yes" \ + || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then + + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CHECK_LIB(intl, ngettext, + [AC_CHECK_LIB(intl, dgettext, + gt_cv_func_dgettext_libintl=yes)])]) + + if test "$gt_cv_func_dgettext_libintl" != "yes" ; then + AC_MSG_CHECKING([if -liconv is needed to use gettext]) + AC_MSG_RESULT([]) + AC_CHECK_LIB(intl, ngettext, + [AC_CHECK_LIB(intl, dcgettext, + [gt_cv_func_dgettext_libintl=yes + libintl_extra_libs=-liconv], + :,-liconv)], + :,-liconv) + fi + + # + # If we found libintl, then check in it for bind_textdomain_codeset(); + # we'll prefer libc if neither have bind_textdomain_codeset(), + # and both have dgettext and ngettext + # + if test "$gt_cv_func_dgettext_libintl" = "yes" ; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS -lintl $libintl_extra_libs" + unset ac_cv_func_bind_textdomain_codeset + AC_CHECK_FUNCS(bind_textdomain_codeset) + LIBS="$glib_save_LIBS" + + if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then + gt_cv_func_dgettext_libc=no + else + if test "$gt_cv_func_dgettext_libc" = "yes" \ + && test "$gt_cv_func_ngettext_libc" = "yes"; then + gt_cv_func_dgettext_libintl=no + fi + fi + fi + fi + + if test "$gt_cv_func_dgettext_libc" = "yes" \ + || test "$gt_cv_func_dgettext_libintl" = "yes"; then + gt_cv_have_gettext=yes + fi + + if test "$gt_cv_func_dgettext_libintl" = "yes"; then + INTLLIBS="-lintl $libintl_extra_libs $INTL_MACOSX_LIBS" + fi + + if test "$gt_cv_have_gettext" = "yes"; then + AC_DEFINE(HAVE_GETTEXT,1, + [Define if the GNU gettext() function is already present or preinstalled.]) + GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS $INTLLIBS" + AC_CHECK_FUNCS(dcgettext) + MSGFMT_OPTS= + AC_MSG_CHECKING([if msgfmt accepts -c]) + GLIB_RUN_PROG([$MSGFMT -c -o /dev/null],[ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: test 1.0\n" +"PO-Revision-Date: 2007-02-15 12:01+0100\n" +"Last-Translator: test \n" +"Language-Team: C \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) + AC_SUBST(MSGFMT_OPTS) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [case $host in + *-*-solaris*) + dnl On Solaris, if bind_textdomain_codeset is in libc, + dnl GNU format message catalog is always supported, + dnl since both are added to the libc all together. + dnl Hence, we'd like to go with DATADIRNAME=share and + dnl and CATOBJEXT=.gmo in this case. + AC_CHECK_FUNC(bind_textdomain_codeset, + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + ;; + *-*-openbsd*) + CATOBJEXT=.mo + DATADIRNAME=share + ;; + *) + CATOBJEXT=.mo + DATADIRNAME=lib + ;; + esac]) + LIBS="$glib_save_LIBS" + INSTOBJEXT=.mo + else + gt_cv_have_gettext=no + fi + fi + ]) + + if test "$gt_cv_have_gettext" = "yes" ; then + AC_DEFINE(ENABLE_NLS, 1, + [always defined to indicate that i18n is enabled]) + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is not GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + + AC_OUTPUT_COMMANDS( + [case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac]) + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.ac. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLLIBS) + AC_SUBST(PO_IN_DATADIR_TRUE) + AC_SUBST(PO_IN_DATADIR_FALSE) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +# AM_GLIB_GNU_GETTEXT +# ------------------- +# Do checks necessary for use of gettext. If a suitable implementation +# of gettext is found in either in libintl or in the C library, +# it will set INTLLIBS to the libraries needed for use of gettext +# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable +# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() +# on various variables needed by the Makefile.in.in installed by +# glib-gettextize. +dnl +AU_DEFUN([GLIB_GNU_GETTEXT], + [AC_REQUIRE([AC_PROG_CC])dnl + + GLIB_LC_MESSAGES + GLIB_WITH_NLS + + if test "$gt_cv_have_gettext" = "yes"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + NEW_LINGUAS="$NEW_LINGUAS $presentlang" + fi + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but ($top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ], + [[$0: This macro is deprecated. You should use upstream gettext instead.]]) + +# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) +# ------------------------------- +# Define VARIABLE to the location where catalog files will +# be installed by po/Makefile. +glib_DEFUN([GLIB_DEFINE_LOCALEDIR], +[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl +glib_save_prefix="$prefix" +glib_save_exec_prefix="$exec_prefix" +glib_save_datarootdir="$datarootdir" +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix=$prefix +datarootdir=`eval echo "${datarootdir}"` +if test "x$CATOBJEXT" = "x.mo" ; then + localedir=`eval echo "${libdir}/locale"` +else + localedir=`eval echo "${datadir}/locale"` +fi +prefix="$glib_save_prefix" +exec_prefix="$glib_save_exec_prefix" +datarootdir="$glib_save_datarootdir" +AC_DEFINE_UNQUOTED($1, "$localedir", + [Define the location where the catalogs will be installed]) +]) + +dnl +dnl Now the definitions that aclocal will find +dnl +ifdef(glib_configure_ac,[],[ +AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) +AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) +])dnl + +# GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL]) +# +# Create a temporary file with TEST-FILE as its contents and pass the +# file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with +# 0 and perform ACTION-IF-FAIL for any other exit status. +AC_DEFUN([GLIB_RUN_PROG], +[cat >conftest.foo <<_ACEOF +$2 +_ACEOF +if AC_RUN_LOG([$1 conftest.foo]); then + m4_ifval([$3], [$3], [:]) +m4_ifvaln([$4], [else $4])dnl +echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD +sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD +fi]) + diff --git a/m4macros/glibtests.m4 b/m4macros/glibtests.m4 new file mode 100644 index 0000000..581726a --- /dev/null +++ b/m4macros/glibtests.m4 @@ -0,0 +1,31 @@ +# Increment this whenever this file is changed. +#serial 1 + +dnl GLIB_TESTS +dnl + +AC_DEFUN([GLIB_TESTS], +[ + AC_ARG_ENABLE(installed-tests, + AS_HELP_STRING([--enable-installed-tests], + [Enable installation of some test cases]), + [case ${enableval} in + yes) ENABLE_INSTALLED_TESTS="1" ;; + no) ENABLE_INSTALLED_TESTS="" ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-installed-tests]) ;; + esac]) + AM_CONDITIONAL([ENABLE_INSTALLED_TESTS], test "$ENABLE_INSTALLED_TESTS" = "1") + AC_ARG_ENABLE(always-build-tests, + AS_HELP_STRING([--enable-always-build-tests], + [Enable always building tests during 'make all']), + [case ${enableval} in + yes) ENABLE_ALWAYS_BUILD_TESTS="1" ;; + no) ENABLE_ALWAYS_BUILD_TESTS="" ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-always-build-tests]) ;; + esac]) + AM_CONDITIONAL([ENABLE_ALWAYS_BUILD_TESTS], test "$ENABLE_ALWAYS_BUILD_TESTS" = "1") + if test "$ENABLE_INSTALLED_TESTS" = "1"; then + AC_SUBST(installed_test_metadir, [${datadir}/installed-tests/]AC_PACKAGE_NAME) + AC_SUBST(installed_testdir, [${libexecdir}/installed-tests/]AC_PACKAGE_NAME) + fi +]) diff --git a/m4macros/gsettings.m4 b/m4macros/gsettings.m4 new file mode 100644 index 0000000..882e6a8 --- /dev/null +++ b/m4macros/gsettings.m4 @@ -0,0 +1,88 @@ +# Increment this whenever this file is changed. +#serial 2 + +dnl GLIB_GSETTINGS +dnl Defines GSETTINGS_SCHEMAS_INSTALL which controls whether +dnl the schema should be compiled +dnl + +AC_DEFUN([GLIB_GSETTINGS], +[ + dnl We can't use PKG_PREREQ because that needs 0.29. + m4_ifndef([PKG_PROG_PKG_CONFIG], + [pkg.m4 version 0.28 or later is required]) + + m4_pattern_allow([AM_V_GEN]) + AC_ARG_ENABLE(schemas-compile, + AS_HELP_STRING([--disable-schemas-compile], + [Disable regeneration of gschemas.compiled on install]), + [case ${enableval} in + yes) GSETTINGS_DISABLE_SCHEMAS_COMPILE="" ;; + no) GSETTINGS_DISABLE_SCHEMAS_COMPILE="1" ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-schemas-compile]) ;; + esac]) + AC_SUBST([GSETTINGS_DISABLE_SCHEMAS_COMPILE]) + PKG_PROG_PKG_CONFIG([0.16]) + AC_SUBST(gsettingsschemadir, [${datadir}/glib-2.0/schemas]) + AS_IF([test x$cross_compiling != xyes], + [PKG_CHECK_VAR([GLIB_COMPILE_SCHEMAS], [gio-2.0], [glib_compile_schemas])], + [AC_PATH_PROG([GLIB_COMPILE_SCHEMAS], [glib-compile-schemas])]) + AC_SUBST(GLIB_COMPILE_SCHEMAS) + if test "x$GLIB_COMPILE_SCHEMAS" = "x"; then + ifelse([$2],,[AC_MSG_ERROR([glib-compile-schemas not found.])],[$2]) + else + ifelse([$1],,[:],[$1]) + fi + + GSETTINGS_RULES=' +.PHONY : uninstall-gsettings-schemas install-gsettings-schemas clean-gsettings-schemas + +mostlyclean-am: clean-gsettings-schemas + +gsettings__enum_file = $(addsuffix .enums.xml,$(gsettings_ENUM_NAMESPACE)) + +%.gschema.valid: %.gschema.xml $(gsettings__enum_file) + $(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) --strict --dry-run $(addprefix --schema-file=,$(gsettings__enum_file)) --schema-file=$< && mkdir -p [$](@D) && touch [$]@ + +all-am: $(gsettings_SCHEMAS:.xml=.valid) +uninstall-am: uninstall-gsettings-schemas +install-data-am: install-gsettings-schemas + +.SECONDARY: $(gsettings_SCHEMAS) + +install-gsettings-schemas: $(gsettings_SCHEMAS) $(gsettings__enum_file) + @$(NORMAL_INSTALL) + if test -n "$^"; then \ + test -z "$(gsettingsschemadir)" || $(MKDIR_P) "$(DESTDIR)$(gsettingsschemadir)"; \ + $(INSTALL_DATA) $^ "$(DESTDIR)$(gsettingsschemadir)"; \ + test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir); \ + fi + +uninstall-gsettings-schemas: + @$(NORMAL_UNINSTALL) + @list='\''$(gsettings_SCHEMAS) $(gsettings__enum_file)'\''; test -n "$(gsettingsschemadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e '\''s|^.*/||'\''`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '\''$(DESTDIR)$(gsettingsschemadir)'\'' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(gsettingsschemadir)" && rm -f $$files + test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir) + +clean-gsettings-schemas: + rm -f $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file) + +ifdef gsettings_ENUM_NAMESPACE +$(gsettings__enum_file): $(gsettings_ENUM_FILES) + $(AM_V_GEN) glib-mkenums --comments '\'''\'' --fhead "" --vhead " <@type@ id='\''$(gsettings_ENUM_NAMESPACE).@EnumName@'\''>" --vprod " " --vtail " " --ftail "" [$]^ > [$]@.tmp && mv [$]@.tmp [$]@ +endif +' + _GSETTINGS_SUBST(GSETTINGS_RULES) +]) + +dnl _GSETTINGS_SUBST(VARIABLE) +dnl Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST +AC_DEFUN([_GSETTINGS_SUBST], +[ +AC_SUBST([$1]) +m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])]) +] +) diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..0a53ad8 --- /dev/null +++ b/meson.build @@ -0,0 +1,2455 @@ +project('glib', 'c', + version : '2.72.4', + # NOTE: We keep this pinned at 0.52 because that's what Debian Stable ships + meson_version : '>= 0.52.0', + default_options : [ + 'buildtype=debugoptimized', + 'warning_level=3', + 'c_std=gnu99' + ] +) + +cc = meson.get_compiler('c') +if meson.version().version_compare('>= 0.54.0') + have_cxx = add_languages('cpp', native: false, required: get_option('oss_fuzz').enabled()) +else + have_cxx = add_languages('cpp', required: get_option('oss_fuzz').enabled()) +endif +if have_cxx + cxx = meson.get_compiler('cpp') +endif + +cc_can_run = not meson.is_cross_build() or meson.has_exe_wrapper() + +if cc.get_argument_syntax() == 'msvc' + # Ignore several spurious warnings for things glib does very commonly + # (also for clang-cl) + add_project_arguments('/FImsvc_recommended_pragmas.h',language : 'c') +endif + +if cc.get_id() == 'msvc' + # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it + # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once + # NOTE: Only add warnings here if you are sure they're spurious + add_project_arguments(cc.get_supported_arguments([ + '/wo4057', # 'operator': 'identifier1' differs in indirection to slightly different base types from 'identifier2' + '/wd4068', # unknown pragma + '/wo4090', # 'operation': different 'modifier' qualifiers + '/wd4100', # 'identifier': unreferenced formal parameter + '/wd4116', # unnamed type definition in parentheses + '/wo4125', # decimal digit terminates octal escape sequence + '/wd4127', # conditional expression is constant + '/wd4146', # unary minus operator applied to unsigned type, result still unsigned + '/wd4152', # nonstandard extension, function/data pointer conversion in expression + '/wd4201', # nonstandard extension used: nameless struct/union + '/wd4232', # nonstandard extension used: 'identifier': address of dllimport 'dllimport' is not static, identity not guaranteed + '/wo4245', # 'conversion_type': conversion from 'type1' to 'type2', signed/unsigned mismatch + '/wo4267', # 'variable': conversion from 'size_t' to 'type', possible loss of data + '/wd4334', # 'shift_operator': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) + '/wo4389', # 'operator': signed/unsigned mismatch + '/wo4702', # unreachable code + '/wd4706' # assignment within conditional expression + ]), language : 'c') + # Set the input and exec encoding to utf-8, like is the default with GCC + add_project_arguments(cc.get_supported_arguments(['/utf-8']), language: 'c') + # Disable SAFESEH with MSVC for plugins and libs that use external deps that + # are built with MinGW + noseh_link_args = ['/SAFESEH:NO'] +else + noseh_link_args = [] + # -mms-bitfields vs -fnative-struct ? +endif + +host_system = host_machine.system() + +if host_system == 'darwin' + ios_test_code = '''#include + #if ! TARGET_OS_IPHONE + #error "Not iOS/tvOS/watchOS/iPhoneSimulator" + #endif''' + if cc.compiles(ios_test_code, name : 'building for iOS') + host_system = 'ios' + endif +endif + +glib_version = meson.project_version() +glib_api_version = '2.0' +version_arr = glib_version.split('.') +major_version = version_arr[0].to_int() +minor_version = version_arr[1].to_int() +micro_version = version_arr[2].to_int() + +interface_age = minor_version.is_odd() ? 0 : micro_version +binary_age = 100 * minor_version + micro_version + +soversion = 0 +# Maintain compatibility with previous libtool versioning +# current = minor * 100 + micro +current = binary_age - interface_age +library_version = '@0@.@1@.@2@'.format(soversion, current, interface_age) +darwin_versions = [current + 1, '@0@.@1@'.format(current + 1, interface_age)] + +configinc = include_directories('.') +glibinc = include_directories('glib') +gobjectinc = include_directories('gobject') +gmoduleinc = include_directories('gmodule') +gioinc = include_directories('gio') + +glib_prefix = get_option('prefix') +glib_bindir = join_paths(glib_prefix, get_option('bindir')) +glib_libdir = join_paths(glib_prefix, get_option('libdir')) +glib_libexecdir = join_paths(glib_prefix, get_option('libexecdir')) +glib_datadir = join_paths(glib_prefix, get_option('datadir')) +glib_pkgdatadir = join_paths(glib_datadir, 'glib-2.0') +glib_includedir = join_paths(glib_prefix, get_option('includedir')) +if get_option('gio_module_dir') != '' + glib_giomodulesdir = join_paths(glib_prefix, get_option('gio_module_dir')) +else + glib_giomodulesdir = join_paths(glib_libdir, 'gio', 'modules') +endif + +glib_pkgconfigreldir = join_paths(glib_libdir, 'pkgconfig') + +if get_option('charsetalias_dir') != '' + glib_charsetaliasdir = join_paths(glib_prefix, get_option('charsetalias_dir')) +else + glib_charsetaliasdir = glib_libdir +endif + +glib_localstatedir = get_option('localstatedir') +if not glib_localstatedir.startswith('/') + # See https://mesonbuild.com/Builtin-options.html#directories + glib_localstatedir = join_paths(glib_prefix, glib_localstatedir) +endif + +installed_tests_metadir = join_paths(glib_datadir, 'installed-tests', meson.project_name()) +installed_tests_execdir = join_paths(glib_libexecdir, 'installed-tests', meson.project_name()) +installed_tests_enabled = get_option('installed_tests') +installed_tests_template = files('template.test.in') +installed_tests_template_tap = files('template-tap.test.in') + +# Don’t build the tests unless we can run them (either natively, in an exe wrapper, or by installing them for later use) +build_tests = get_option('tests') and (not meson.is_cross_build() or (meson.is_cross_build() and meson.has_exe_wrapper()) or installed_tests_enabled) + +add_project_arguments('-D_GNU_SOURCE', language: 'c') + +if host_system == 'qnx' + add_project_arguments('-D_QNX_SOURCE', language: 'c') +endif + +# Disable strict aliasing; +# see https://bugzilla.gnome.org/show_bug.cgi?id=791622 +if cc.has_argument('-fno-strict-aliasing') + add_project_arguments('-fno-strict-aliasing', language: 'c') +endif + +######################## +# Configuration begins # +######################## +glib_conf = configuration_data() +glibconfig_conf = configuration_data() + +# accumulated list of defines as we check for them, so we can easily +# use them later in test programs (autoconf does this automatically) +glib_conf_prefix = '' + +glib_conf.set('GLIB_MAJOR_VERSION', major_version) +glib_conf.set('GLIB_MINOR_VERSION', minor_version) +glib_conf.set('GLIB_MICRO_VERSION', micro_version) +glib_conf.set('GLIB_INTERFACE_AGE', interface_age) +glib_conf.set('GLIB_BINARY_AGE', binary_age) +glib_conf.set_quoted('GETTEXT_PACKAGE', 'glib20') +glib_conf.set_quoted('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new') +glib_conf.set_quoted('PACKAGE_NAME', 'glib') +glib_conf.set_quoted('PACKAGE_STRING', 'glib @0@'.format(meson.project_version())) +glib_conf.set_quoted('PACKAGE_TARNAME', 'glib') +glib_conf.set_quoted('PACKAGE_URL', '') +glib_conf.set_quoted('PACKAGE_VERSION', meson.project_version()) +glib_conf.set('ENABLE_NLS', 1) + +# used by the .rc.in files +glibconfig_conf.set('LT_CURRENT_MINUS_AGE', soversion) + +glib_conf.set('_GNU_SOURCE', 1) + +if host_system in ['windows', 'darwin'] + # Poll doesn't work on devices on Windows, and macOS's poll() implementation is known to be broken + glib_conf.set('BROKEN_POLL', true) +endif + +if host_system == 'windows' and cc.get_id() != 'msvc' and cc.get_id() != 'clang-cl' + # FIXME: Ideally we shouldn't depend on this on Windows and should use + # 64 bit capable Windows API that also works with MSVC. + # The autotools build did set this for mingw and while meson sets it + # for gcc/clang by default, it doesn't do so on Windows. + glib_conf.set('_FILE_OFFSET_BITS', 64) +endif + +# Check for GNU visibility attributes +g_have_gnuc_visibility = cc.compiles(''' + void + __attribute__ ((visibility ("hidden"))) + f_hidden (void) + { + } + void + __attribute__ ((visibility ("internal"))) + f_internal (void) + { + } + void + __attribute__ ((visibility ("default"))) + f_default (void) + { + } + int main (void) + { + f_hidden(); + f_internal(); + f_default(); + return 0; + } + ''', + # Not supported by MSVC, but MSVC also won't support visibility, + # so it's OK to pass -Werror explicitly. Replace with + # override_options : 'werror=true' once that is supported + args: ['-Werror'], + name : 'GNU C visibility attributes test') + +if g_have_gnuc_visibility + glibconfig_conf.set('G_HAVE_GNUC_VISIBILITY', '1') +endif + +# Detect and set symbol visibility +glib_hidden_visibility_args = [] +if get_option('default_library') != 'static' + if host_system == 'windows' or host_system == 'cygwin' + if get_option('default_library') != 'shared' + error('On Windows default_library must be "shared" or "static" but not "both"') + endif + glib_conf.set('DLL_EXPORT', true) + if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' + glib_conf.set('_GLIB_EXTERN', '__declspec(dllexport) extern') + elif cc.has_argument('-fvisibility=hidden') + glib_conf.set('_GLIB_EXTERN', '__attribute__((visibility("default"))) __declspec(dllexport) extern') + glib_hidden_visibility_args = ['-fvisibility=hidden'] + endif + elif cc.has_argument('-fvisibility=hidden') + glib_conf.set('_GLIB_EXTERN', '__attribute__((visibility("default"))) extern') + glib_hidden_visibility_args = ['-fvisibility=hidden'] + endif +endif + +if get_option('default_library') == 'static' + glibconfig_conf.set('GLIB_STATIC_COMPILATION', '1') + glibconfig_conf.set('GOBJECT_STATIC_COMPILATION', '1') + glibconfig_conf.set('G_INTL_STATIC_COMPILATION', '1') + glibconfig_conf.set('FFI_STATIC_BUILD', '1') +endif + +# Cygwin glib port maintainers made it clear +# (via the patches they apply) that they want no +# part of glib W32 code, therefore we do not define +# G_PLATFORM_WIN32 for host_system == 'cygwin'. +# This makes G_PLATFORM_WIN32 a synonym for +# G_OS_WIN32. +if host_system == 'windows' + glib_os = '''#define G_OS_WIN32 +#define G_PLATFORM_WIN32''' +elif host_system == 'cygwin' + glib_os = '''#define G_OS_UNIX +#define G_WITH_CYGWIN''' +else + glib_os = '#define G_OS_UNIX' +endif +glibconfig_conf.set('glib_os', glib_os) + +# We need to know the CRT being used to determine what .lib files we need on +# Visual Studio for dependencies that don't normally come with pkg-config files +vs_crt = 'release' +vs_crt_opt = get_option('b_vscrt') +if vs_crt_opt in ['mdd', 'mtd'] + vs_crt = 'debug' +elif vs_crt_opt == 'from_buildtype' + if get_option('buildtype') == 'debug' + vs_crt = 'debug' + endif +endif + +# Use debug/optimization flags to determine whether to enable debug or disable +# cast checks +glib_debug_cflags = [] +glib_debug = get_option('glib_debug') +if glib_debug.enabled() or (glib_debug.auto() and get_option('debug')) + glib_debug_cflags += ['-DG_ENABLE_DEBUG'] + message('Enabling various debug infrastructure') +elif get_option('optimization') in ['2', '3', 's'] + glib_debug_cflags += ['-DG_DISABLE_CAST_CHECKS'] + message('Disabling cast checks') +endif + +if not get_option('glib_assert') + glib_debug_cflags += ['-DG_DISABLE_ASSERT'] + message('Disabling GLib asserts') +endif + +if not get_option('glib_checks') + glib_debug_cflags += ['-DG_DISABLE_CHECKS'] + message('Disabling GLib checks') +endif + +add_project_arguments(glib_debug_cflags, language: 'c') + +# check for header files + +headers = [ + 'alloca.h', + 'afunix.h', + 'crt_externs.h', + 'dirent.h', # MSC does not come with this by default + 'float.h', + 'fstab.h', + 'grp.h', + 'inttypes.h', + 'limits.h', + 'locale.h', + 'mach/mach_time.h', + 'memory.h', + 'mntent.h', + 'poll.h', + 'pwd.h', + 'sched.h', + 'spawn.h', + 'stdatomic.h', + 'stdint.h', + 'stdlib.h', + 'string.h', + 'strings.h', + 'sys/auxv.h', + 'sys/event.h', + 'sys/filio.h', + 'sys/inotify.h', + 'sys/mkdev.h', + 'sys/mntctl.h', + 'sys/mnttab.h', + 'sys/mount.h', + 'sys/param.h', + 'sys/resource.h', + 'sys/select.h', + 'sys/statfs.h', + 'sys/stat.h', + 'sys/statvfs.h', + 'sys/sysctl.h', + 'sys/time.h', # MSC does not come with this by default + 'sys/times.h', + 'sys/types.h', + 'sys/uio.h', + 'sys/vfs.h', + 'sys/vfstab.h', + 'sys/vmount.h', + 'sys/wait.h', + 'termios.h', + 'unistd.h', + 'values.h', + 'wchar.h', + 'xlocale.h', +] + +foreach h : headers + if cc.has_header(h) + define = 'HAVE_' + h.underscorify().to_upper() + glib_conf.set(define, 1) + glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(define) + endif +endforeach + +# FIXME: Use cc.check_header from Meson 0.47. +# FreeBSD includes a malloc.h which always throw compilation error. +if cc.compiles('#include ', name : 'malloc.h') + glib_conf.set('HAVE_MALLOC_H', 1) + glib_conf_prefix = glib_conf_prefix + '#define HAVE_MALLOC_H 1\n' +endif + +if cc.has_header('linux/netlink.h') + glib_conf.set('HAVE_NETLINK', 1) +endif + +# Is statx() supported? Android systems don’t reliably support it as of August 2020. +statx_code = ''' + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif + #include + #include + int main (void) + { + struct statx stat_buf; + return statx (AT_FDCWD, "/", AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS | STATX_BTIME, &stat_buf); + } + ''' +if host_system != 'android' and cc.compiles(statx_code, name : 'statx() test') + glib_conf.set('HAVE_STATX', 1) +endif + +if glib_conf.has('HAVE_LOCALE_H') + if cc.has_header_symbol('locale.h', 'LC_MESSAGES') + glib_conf.set('HAVE_LC_MESSAGES', 1) + endif +endif + +struct_stat_blkprefix = ''' +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_STATFS_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif +''' + +struct_members = [ + [ 'stat', 'st_mtimensec' ], + [ 'stat', 'st_mtim.tv_nsec' ], + [ 'stat', 'st_atimensec' ], + [ 'stat', 'st_atim.tv_nsec' ], + [ 'stat', 'st_ctimensec' ], + [ 'stat', 'st_ctim.tv_nsec' ], + [ 'stat', 'st_birthtime' ], + [ 'stat', 'st_birthtimensec' ], + [ 'stat', 'st_birthtim' ], + [ 'stat', 'st_birthtim.tv_nsec' ], + [ 'stat', 'st_blksize', struct_stat_blkprefix ], + [ 'stat', 'st_blocks', struct_stat_blkprefix ], + [ 'statfs', 'f_fstypename', struct_stat_blkprefix ], + [ 'statfs', 'f_bavail', struct_stat_blkprefix ], + [ 'dirent', 'd_type', '''#include + #include ''' ], + [ 'statvfs', 'f_basetype', '#include ' ], + [ 'statvfs', 'f_fstypename', '#include ' ], + [ 'tm', 'tm_gmtoff', '#include ' ], + [ 'tm', '__tm_gmtoff', '#include ' ], +] + +foreach m : struct_members + header_check_prefix = glib_conf_prefix + if m.length() == 3 + header_check_prefix = header_check_prefix + m[2] + else + header_check_prefix = header_check_prefix + '#include ' + endif + if cc.has_member('struct ' + m[0], m[1], prefix : header_check_prefix) + define = 'HAVE_STRUCT_@0@_@1@'.format(m[0].to_upper(), m[1].underscorify().to_upper()) + glib_conf.set(define, 1) + glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(define) + else + endif +endforeach + +# Compiler flags +if cc.get_id() == 'gcc' or cc.get_id() == 'clang' + warning_common_args = [ + '-Wduplicated-branches', + '-Wimplicit-fallthrough', + '-Wmisleading-indentation', + '-Wunused', + # Due to maintained deprecated code, we do not want to see unused parameters + '-Wno-unused-parameter', + # Due to pervasive use of things like GPOINTER_TO_UINT(), we do not support + # building with -Wbad-function-cast. + '-Wno-cast-function-type', + # Due to function casts through (void*) we cannot support -Wpedantic: + # https://wiki.gnome.org/Projects/GLib/CompilerRequirements#Function_pointer_conversions. + '-Wno-pedantic', + # A zero-length format string shouldn't be considered an issue. + '-Wno-format-zero-length', + # We explicitly require variadic macros + '-Wno-variadic-macros', + '-Werror=format=2', + '-Werror=init-self', + '-Werror=missing-include-dirs', + '-Werror=pointer-arith', + ] + + warning_c_args = warning_common_args + [ + '-Wstrict-prototypes', + # Due to pervasive use of things like GPOINTER_TO_UINT(), we do not support + # building with -Wbad-function-cast. + '-Wno-bad-function-cast', + '-Werror=declaration-after-statement', + '-Werror=implicit-function-declaration', + '-Werror=missing-prototypes', + ] + warning_cxx_args = warning_common_args + warning_objc_args = warning_c_args + warning_c_link_args = [ + '-Wl,-z,nodelete', + ] + if get_option('bsymbolic_functions') + warning_c_link_args += ['-Wl,-Bsymbolic-functions'] + endif +else + warning_c_args = [] + warning_cxx_args = [] + warning_objc_args = [] + warning_c_link_args = [] +endif + +add_project_arguments(cc.get_supported_arguments(warning_c_args), language: 'c') +if have_cxx + add_project_arguments(cxx.get_supported_arguments(warning_cxx_args), language: 'cpp') +endif + +# FIXME: We cannot build some of the GResource tests with -z nodelete, which +# means we cannot use that flag in add_project_link_arguments(), and must add +# it to the relevant targets manually. We do the same with -Bsymbolic-functions +# because that is what the autotools build did. +# See https://github.com/mesonbuild/meson/pull/3520 for a way to eventually +# improve this. +glib_link_flags = cc.get_supported_link_arguments(warning_c_link_args) + +# Windows SDK requirements and checks +if host_system == 'windows' + # Check whether we're building for UWP apps + code = ''' + #include + #if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) + #error "Not building for UWP" + #endif''' + if cc.compiles(code, name : 'building for UWP') + glib_conf.set('G_WINAPI_ONLY_APP', true) + # We require Windows 10+ on WinRT + glib_conf.set('_WIN32_WINNT', '0x0A00') + uwp_gio_deps = [cc.find_library('shcore'), + cc.find_library('runtimeobject')] + else + # We require Windows 7+ on Win32 + glib_conf.set('_WIN32_WINNT', '0x0601') + uwp_gio_deps = [] + endif +endif + +functions = [ + 'close_range', + 'endmntent', + 'endservent', + 'epoll_create', + 'fallocate', + 'fchmod', + 'fchown', + 'fdwalk', + 'fsync', + 'getauxval', + 'getc_unlocked', + 'getfsstat', + 'getgrgid_r', + 'getmntent_r', + 'getpwuid_r', + 'getresuid', + 'getvfsstat', + 'gmtime_r', + 'hasmntopt', + 'inotify_init1', + 'issetugid', + 'kevent', + 'kqueue', + 'lchmod', + 'lchown', + 'link', + 'localtime_r', + 'lstat', + 'mbrtowc', + 'memalign', + 'mmap', + 'newlocale', + 'pipe2', + 'poll', + 'prlimit', + 'readlink', + 'recvmmsg', + 'sendmmsg', + 'setenv', + 'setmntent', + 'strerror_r', + 'strnlen', + 'strsignal', + 'strtod_l', + 'strtoll_l', + 'strtoull_l', + 'symlink', + 'timegm', + 'unsetenv', + 'uselocale', + 'utimes', + 'valloc', + 'vasprintf', + 'vsnprintf', + 'wcrtomb', + 'wcslen', + 'wcsnlen', + 'sysctlbyname', +] + +# _NSGetEnviron is available on iOS too, but its usage gets apps rejected from +# the app store since it's considered 'private API' +if host_system == 'darwin' + functions += ['_NSGetEnviron'] +endif + +if glib_conf.has('HAVE_SYS_STATVFS_H') + functions += ['statvfs'] +else + have_func_statvfs = false +endif +if glib_conf.has('HAVE_SYS_STATFS_H') or glib_conf.has('HAVE_SYS_MOUNT_H') + functions += ['statfs'] +else + have_func_statfs = false +endif + +if host_system == 'windows' + iphlpapi_dep = cc.find_library('iphlpapi') + iphlpapi_funcs = ['if_nametoindex', 'if_indextoname'] + foreach ifunc : iphlpapi_funcs + iphl_prefix = '''#define _WIN32_WINNT @0@ + #include + #include '''.format(glib_conf.get('_WIN32_WINNT')) + if cc.has_function(ifunc, + prefix : iphl_prefix, + dependencies : iphlpapi_dep) + idefine = 'HAVE_' + ifunc.underscorify().to_upper() + glib_conf.set(idefine, 1) + glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(idefine) + set_variable('have_func_' + ifunc, true) + else + set_variable('have_func_' + ifunc, false) + endif + endforeach +else + functions += ['if_indextoname', 'if_nametoindex'] +endif + +# AIX splice is something else +if host_system != 'aix' + functions += ['splice'] +endif + +foreach f : functions + if cc.has_function(f) + define = 'HAVE_' + f.underscorify().to_upper() + glib_conf.set(define, 1) + glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format(define) + set_variable('have_func_' + f, true) + else + set_variable('have_func_' + f, false) + endif +endforeach + +# Check that stpcpy() is usable; must use header. +# cc.has_function() in some cases (clang, gcc 10+) assumes that if the +# compiler provides a builtin of the same name that the function exists, while +# it's in fact not provided by any header or library. This is true for +# stpcpy() on Windows using clang and gcc as well as posix_memalign() using +# gcc on Windows. Skip these checks on Windows for now to avoid false +# positives. See https://github.com/mesonbuild/meson/pull/7116, +# https://github.com/mesonbuild/meson/issues/3672 and +# https://github.com/mesonbuild/meson/issues/5628. +# FIXME: Once meson no longer returns success for stpcpy() and +# posix_memalign() on Windows using GCC and clang we can remove this. +if host_system != 'windows' and cc.has_function('stpcpy', prefix : '#include ') + glib_conf.set('HAVE_STPCPY', 1) +endif + +# When building for Android-20 and earlier, require Meson 0.54.2 or newer. +# This is needed, because Meson build versions prior to 0.54.2 return false +# positive for stpcpy has_function check when building for legacy Android. +if host_system == 'android' + android_is_older = cc.compiles('''#if __ANDROID_API__ >= 21 + #error Android is 21 or newer + #endif''') + if android_is_older and meson.version().version_compare('< 0.54.2') + error('Compiling for \n#include ') + glib_conf.set('HAVE_MEMALIGN', 1) +endif + +if cc.has_function('_aligned_malloc', prefix: '#include ') + glib_conf.set('HAVE__ALIGNED_MALLOC', 1) +endif + +if host_system != 'windows' and cc.has_function('aligned_alloc', prefix: '#include ') + glib_conf.set('HAVE_ALIGNED_ALLOC', 1) +endif + +if host_system != 'windows' and cc.has_function('posix_memalign', prefix: '#include ') + glib_conf.set('HAVE_POSIX_MEMALIGN', 1) +endif + +# Check that posix_spawn() is usable; must use header +if cc.has_function('posix_spawn', prefix : '#include ') + glib_conf.set('HAVE_POSIX_SPAWN', 1) +endif + +# Check whether strerror_r returns char * +if have_func_strerror_r + if cc.compiles('''#define _GNU_SOURCE + #include + int func (void) { + char error_string[256]; + char *ptr = strerror_r (-2, error_string, 256); + char c = *strerror_r (-2, error_string, 256); + return c != 0 && ptr != (void*) 0L; + } + ''', + name : 'strerror_r() returns char *') + glib_conf.set('STRERROR_R_CHAR_P', 1, + description: 'Defined if strerror_r returns char *') + endif +endif + +# Special-case these functions that have alternative names on Windows/MSVC +if cc.has_function('snprintf') or cc.has_header_symbol('stdio.h', 'snprintf') + glib_conf.set('HAVE_SNPRINTF', 1) + glib_conf_prefix = glib_conf_prefix + '#define HAVE_SNPRINTF 1\n' +elif cc.has_function('_snprintf') or cc.has_header_symbol('stdio.h', '_snprintf') + hack_define = '1\n#define snprintf _snprintf' + glib_conf.set('HAVE_SNPRINTF', hack_define) + glib_conf_prefix = glib_conf_prefix + '#define HAVE_SNPRINTF ' + hack_define +endif + +if cc.has_function('strcasecmp', prefix: '#include ') + glib_conf.set('HAVE_STRCASECMP', 1) + glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRCASECMP 1\n' +elif cc.has_function('_stricmp') + hack_define = '1\n#define strcasecmp _stricmp' + glib_conf.set('HAVE_STRCASECMP', hack_define) + glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRCASECMP ' + hack_define +endif + +if cc.has_function('strncasecmp', prefix: '#include ') + glib_conf.set('HAVE_STRNCASECMP', 1) + glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRNCASECMP 1\n' +elif cc.has_function('_strnicmp') + hack_define = '1\n#define strncasecmp _strnicmp' + glib_conf.set('HAVE_STRNCASECMP', hack_define) + glib_conf_prefix = glib_conf_prefix + '#define HAVE_STRNCASECMP ' + hack_define +endif + +if cc.has_header_symbol('sys/sysmacros.h', 'major') + glib_conf.set('MAJOR_IN_SYSMACROS', 1) +elif cc.has_header_symbol('sys/mkdev.h', 'major') + glib_conf.set('MAJOR_IN_MKDEV', 1) +elif cc.has_header_symbol('sys/types.h', 'major') + glib_conf.set('MAJOR_IN_TYPES', 1) +endif + +if cc.has_header_symbol('dlfcn.h', 'RTLD_LAZY') + glib_conf.set('HAVE_RTLD_LAZY', 1) +endif + +if cc.has_header_symbol('dlfcn.h', 'RTLD_NOW') + glib_conf.set('HAVE_RTLD_NOW', 1) +endif + +if cc.has_header_symbol('dlfcn.h', 'RTLD_GLOBAL') + glib_conf.set('HAVE_RTLD_GLOBAL', 1) +endif + +have_rtld_next = false +if cc.has_header_symbol('dlfcn.h', 'RTLD_NEXT', args: '-D_GNU_SOURCE') + have_rtld_next = true + glib_conf.set('HAVE_RTLD_NEXT', 1) +endif + +# Check whether to use statfs or statvfs +# Some systems have both statfs and statvfs, pick the most "native" for these +if have_func_statfs and have_func_statvfs + # on solaris and irix, statfs doesn't even have the f_bavail field + if not glib_conf.has('HAVE_STRUCT_STATFS_F_BAVAIL') + have_func_statfs = false + else + # at least on linux, statfs is the actual syscall + have_func_statvfs = false + endif +endif +if have_func_statfs + glib_conf.set('USE_STATFS', 1) + stat_func_to_use = 'statfs' +elif have_func_statvfs + glib_conf.set('USE_STATVFS', 1) + stat_func_to_use = 'statvfs' +else + stat_func_to_use = 'neither' +endif +message('Checking whether to use statfs or statvfs .. ' + stat_func_to_use) + +if host_system == 'linux' + if cc.has_function('mkostemp', + prefix: '''#define _GNU_SOURCE + #include ''') + glib_conf.set('HAVE_MKOSTEMP', 1) + endif +endif + +glib_have_os_x_9_or_later = false +glib_have_carbon = false +glib_have_cocoa = false +if host_system == 'darwin' + add_languages('objc') + objcc = meson.get_compiler('objc') + + add_project_arguments(objcc.get_supported_arguments(warning_objc_args), language: 'objc') + + # Mac OS X Carbon support + glib_have_carbon = objcc.compiles('''#include + #include ''', + name : 'Mac OS X Carbon support') + + if glib_have_carbon + glib_conf.set('HAVE_CARBON', true) + glib_have_os_x_9_or_later = objcc.compiles('''#include + #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 + #error Compiling for minimum OS X version before 10.9 + #endif''', + name : 'OS X 9 or later') + endif + + # Mac OS X Cocoa support + glib_have_cocoa = objcc.compiles('''#include + #ifdef GNUSTEP_BASE_VERSION + #error "Detected GNUstep, not Cocoa" + #endif''', + name : 'Mac OS X Cocoa support') + + if glib_have_cocoa + glib_conf.set('HAVE_COCOA', true) + endif +endif + +if host_system == 'qnx' + glib_conf.set('HAVE_QNX', 1) +endif + +# Check for futex(2) +if cc.links('''#include + #include + #include + int main (int argc, char ** argv) { + syscall (__NR_futex, NULL, FUTEX_WAKE, FUTEX_WAIT); + return 0; + }''', name : 'futex(2) system call') + glib_conf.set('HAVE_FUTEX', 1) +endif + +# Check for eventfd(2) +if cc.links('''#include + #include + int main (int argc, char ** argv) { + eventfd (0, EFD_CLOEXEC); + return 0; + }''', name : 'eventfd(2) system call') + glib_conf.set('HAVE_EVENTFD', 1) +endif + +# Check for __uint128_t (gcc) by checking for 128-bit division +uint128_t_src = '''int main() { +static __uint128_t v1 = 100; +static __uint128_t v2 = 10; +static __uint128_t u; +u = v1 / v2; +}''' +if cc.compiles(uint128_t_src, name : '__uint128_t available') + glib_conf.set('HAVE_UINT128_T', 1) +endif + +clock_gettime_test_code = ''' + #include + struct timespec t; + int main (int argc, char ** argv) { + return clock_gettime(CLOCK_REALTIME, &t); + }''' +librt = [] +if cc.links(clock_gettime_test_code, name : 'clock_gettime') + glib_conf.set('HAVE_CLOCK_GETTIME', 1) +elif cc.links(clock_gettime_test_code, args : '-lrt', name : 'clock_gettime in librt') + glib_conf.set('HAVE_CLOCK_GETTIME', 1) + librt = cc.find_library('rt') +endif + +dlopen_dlsym_test_code = ''' +#include +int glib_underscore_test (void) { return 42; } +int main (int argc, char ** argv) { + void *f1 = (void*)0, *f2 = (void*)0, *handle; + handle = dlopen ((void*)0, 0); + if (handle) { + f1 = dlsym (handle, "glib_underscore_test"); + f2 = dlsym (handle, "_glib_underscore_test"); + } + return (!f2 || f1); +}''' +libdl_dep = [] +if cc.links(dlopen_dlsym_test_code, name : 'dlopen() and dlsym() in system libraries') + have_dlopen_dlsym = true +elif cc.links(dlopen_dlsym_test_code, args : '-ldl', name : 'dlopen() and dlsym() in libdl') + have_dlopen_dlsym = true + libdl_dep = cc.find_library('dl') +else + have_dlopen_dlsym = false +endif + +# if statfs() takes 2 arguments (Posix) or 4 (Solaris) +if have_func_statfs + if cc.compiles(glib_conf_prefix + ''' + #include + #ifdef HAVE_SYS_PARAM_H + #include + #endif + #ifdef HAVE_SYS_VFS_H + #include + #endif + #ifdef HAVE_SYS_MOUNT_H + #include + #endif + #ifdef HAVE_SYS_STATFS_H + #include + #endif + void some_func (void) { + struct statfs st; + statfs("/", &st); + }''', name : 'number of arguments to statfs() (n=2)') + glib_conf.set('STATFS_ARGS', 2) + elif cc.compiles(glib_conf_prefix + ''' + #include + #ifdef HAVE_SYS_PARAM_H + #include + #endif + #ifdef HAVE_SYS_VFS_H + #include + #endif + #ifdef HAVE_SYS_MOUNT_H + #include + #endif + #ifdef HAVE_SYS_STATFS_H + #include + #endif + void some_func (void) { + struct statfs st; + statfs("/", &st, sizeof (st), 0); + }''', name : 'number of arguments to statfs() (n=4)') + glib_conf.set('STATFS_ARGS', 4) + else + error('Unable to determine number of arguments to statfs()') + endif +endif + +# open takes O_DIRECTORY as an option +#AC_MSG_CHECKING([]) +if cc.compiles('''#include + #include + #include + void some_func (void) { + open(0, O_DIRECTORY, 0); + }''', name : 'open() option O_DIRECTORY') + glib_conf.set('HAVE_OPEN_O_DIRECTORY', 1) +endif + +# fcntl takes F_FULLFSYNC as an option +# See https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fsync.2.html +if cc.compiles('''#include + #include + #include + void some_func (void) { + fcntl(0, F_FULLFSYNC, 0); + }''', name : 'fcntl() option F_FULLFSYNC') + glib_conf.set('HAVE_FCNTL_F_FULLFSYNC', 1) +endif + +# Check whether there is a vsnprintf() function with C99 semantics installed. +# (similar tests to AC_FUNC_VSNPRINTF_C99) +# Check whether there is a snprintf() function with C99 semantics installed. +# (similar tests to AC_FUNC_SNPRINTF_C99) +# Check whether there is a printf() function with Unix98 semantics installed. +# (similar tests to AC_FUNC_PRINTF_UNIX98) +have_good_vsnprintf = false +have_good_snprintf = false +have_good_printf = false + +if host_system == 'windows' and (cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl') + # Unfortunately the Visual Studio 2015+ implementations of C99-style + # snprintf and vsnprintf don't seem to be quite good enough. + # (Sorry, I don't know exactly what is the problem, + # but it is related to floating point formatting and decimal point vs. comma.) + # The simple tests in AC_FUNC_VSNPRINTF_C99 and AC_FUNC_SNPRINTF_C99 aren't + # rigorous enough to notice, though. + glib_conf.set('HAVE_C99_SNPRINTF', false) + glib_conf.set('HAVE_C99_VSNPRINTF', false) + glib_conf.set('HAVE_UNIX98_PRINTF', false) +elif not cc_can_run and host_system in ['ios', 'darwin'] + # All these are true when compiling natively on macOS, so we should use good + # defaults when building for iOS and tvOS. + glib_conf.set('HAVE_C99_SNPRINTF', true) + glib_conf.set('HAVE_C99_VSNPRINTF', true) + glib_conf.set('HAVE_UNIX98_PRINTF', true) + have_good_vsnprintf = true + have_good_snprintf = true + have_good_printf = true +else + vsnprintf_c99_test_code = ''' +#include +#include +#include + +int +doit(char * s, ...) +{ + char buffer[32]; + va_list args; + int r; + + va_start(args, s); + r = vsnprintf(buffer, 5, s, args); + va_end(args); + + if (r != 7) + exit(1); + + /* AIX 5.1 and Solaris seems to have a half-baked vsnprintf() + implementation. The above will return 7 but if you replace + the size of the buffer with 0, it borks! */ + va_start(args, s); + r = vsnprintf(buffer, 0, s, args); + va_end(args); + + if (r != 7) + exit(1); + + exit(0); +} + +int +main(void) +{ + doit("1234567"); + exit(1); +}''' + + if cc_can_run + rres = cc.run(vsnprintf_c99_test_code, name : 'C99 vsnprintf') + if rres.compiled() and rres.returncode() == 0 + glib_conf.set('HAVE_C99_VSNPRINTF', 1) + have_good_vsnprintf = true + endif + else + have_good_vsnprintf = meson.get_cross_property('have_c99_vsnprintf', false) + glib_conf.set('HAVE_C99_VSNPRINTF', have_good_vsnprintf) + endif + + snprintf_c99_test_code = ''' +#include +#include +#include + +int +doit() +{ + char buffer[32]; + va_list args; + int r; + + r = snprintf(buffer, 5, "1234567"); + + if (r != 7) + exit(1); + + r = snprintf(buffer, 0, "1234567"); + + if (r != 7) + exit(1); + + r = snprintf(NULL, 0, "1234567"); + + if (r != 7) + exit(1); + + exit(0); +} + +int +main(void) +{ + doit(); + exit(1); +}''' + + if cc_can_run + rres = cc.run(snprintf_c99_test_code, name : 'C99 snprintf') + if rres.compiled() and rres.returncode() == 0 + glib_conf.set('HAVE_C99_SNPRINTF', 1) + have_good_snprintf = true + endif + else + have_good_snprintf = meson.get_cross_property('have_c99_snprintf', false) + glib_conf.set('HAVE_C99_SNPRINTF', have_good_snprintf) + endif + + printf_unix98_test_code = ''' +#include +#include +#include + +int +main (void) +{ + char buffer[128]; + + sprintf (buffer, "%2\$d %3\$d %1\$d", 1, 2, 3); + if (strcmp ("2 3 1", buffer) == 0) + exit (0); + exit (1); +}''' + + if cc_can_run + rres = cc.run(printf_unix98_test_code, name : 'Unix98 printf positional parameters') + if rres.compiled() and rres.returncode() == 0 + glib_conf.set('HAVE_UNIX98_PRINTF', 1) + have_good_printf = true + endif + else + have_good_printf = meson.get_cross_property('have_unix98_printf', false) + glib_conf.set('HAVE_UNIX98_PRINTF', have_good_printf) + endif +endif + +if host_system == 'windows' + glib_conf.set_quoted('EXEEXT', '.exe') +else + glib_conf.set('EXEEXT', '') +endif + +# Our printf is 'good' only if vsnpintf()/snprintf()/printf() supports C99 well enough +use_system_printf = have_good_vsnprintf and have_good_snprintf and have_good_printf +glib_conf.set('USE_SYSTEM_PRINTF', use_system_printf) +glibconfig_conf.set('GLIB_USING_SYSTEM_PRINTF', use_system_printf) + +if not use_system_printf + # gnulib has vasprintf so override the previous check + glib_conf.set('HAVE_VASPRINTF', 1) +endif + +# Check for nl_langinfo and CODESET +if cc.links('''#include + int main (int argc, char ** argv) { + char *codeset = nl_langinfo (CODESET); + return 0; + }''', name : 'nl_langinfo and CODESET') + glib_conf.set('HAVE_LANGINFO_CODESET', 1) + glib_conf.set('HAVE_CODESET', 1) +endif + +# Check for nl_langinfo and LC_TIME parts that are needed in gdatetime.c +if cc.links('''#include + int main (int argc, char ** argv) { + char *str; + str = nl_langinfo (PM_STR); + str = nl_langinfo (D_T_FMT); + str = nl_langinfo (D_FMT); + str = nl_langinfo (T_FMT); + str = nl_langinfo (T_FMT_AMPM); + str = nl_langinfo (MON_1); + str = nl_langinfo (ABMON_12); + str = nl_langinfo (DAY_1); + str = nl_langinfo (ABDAY_7); + return 0; + }''', name : 'nl_langinfo (PM_STR)') + glib_conf.set('HAVE_LANGINFO_TIME', 1) +endif +if cc.links('''#include + int main (int argc, char ** argv) { + char *str; + str = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT1_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT2_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT3_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT4_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT5_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT6_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT7_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT8_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT9_MB); + return 0; + }''', name : 'nl_langinfo (_NL_CTYPE_OUTDIGITn_MB)') + glib_conf.set('HAVE_LANGINFO_OUTDIGIT', 1) +endif + +# Check for nl_langinfo and alternative month names +if cc.links('''#ifndef _GNU_SOURCE + # define _GNU_SOURCE + #endif + #include + int main (int argc, char ** argv) { + char *str; + str = nl_langinfo (ALTMON_1); + str = nl_langinfo (ALTMON_2); + str = nl_langinfo (ALTMON_3); + str = nl_langinfo (ALTMON_4); + str = nl_langinfo (ALTMON_5); + str = nl_langinfo (ALTMON_6); + str = nl_langinfo (ALTMON_7); + str = nl_langinfo (ALTMON_8); + str = nl_langinfo (ALTMON_9); + str = nl_langinfo (ALTMON_10); + str = nl_langinfo (ALTMON_11); + str = nl_langinfo (ALTMON_12); + return 0; + }''', name : 'nl_langinfo (ALTMON_n)') + glib_conf.set('HAVE_LANGINFO_ALTMON', 1) +endif + +# Check for nl_langinfo and abbreviated alternative month names +if cc.links('''#ifndef _GNU_SOURCE + # define _GNU_SOURCE + #endif + #include + int main (int argc, char ** argv) { + char *str; + str = nl_langinfo (_NL_ABALTMON_1); + str = nl_langinfo (_NL_ABALTMON_2); + str = nl_langinfo (_NL_ABALTMON_3); + str = nl_langinfo (_NL_ABALTMON_4); + str = nl_langinfo (_NL_ABALTMON_5); + str = nl_langinfo (_NL_ABALTMON_6); + str = nl_langinfo (_NL_ABALTMON_7); + str = nl_langinfo (_NL_ABALTMON_8); + str = nl_langinfo (_NL_ABALTMON_9); + str = nl_langinfo (_NL_ABALTMON_10); + str = nl_langinfo (_NL_ABALTMON_11); + str = nl_langinfo (_NL_ABALTMON_12); + return 0; + }''', name : 'nl_langinfo (_NL_ABALTMON_n)') + glib_conf.set('HAVE_LANGINFO_ABALTMON', 1) +endif + +# Check for nl_langinfo and _NL_TIME_CODESET +if cc.links('''#include + int main (int argc, char ** argv) { + char *codeset = nl_langinfo (_NL_TIME_CODESET); + return 0; + }''', name : 'nl_langinfo and _NL_TIME_CODESET') + glib_conf.set('HAVE_LANGINFO_TIME_CODESET', 1) +endif + +# Check if C compiler supports the 'signed' keyword +if not cc.compiles('''signed char x;''', name : 'signed') + glib_conf.set('signed', '/* NOOP */') +endif + +# Check if the ptrdiff_t type exists +if cc.has_header_symbol('stddef.h', 'ptrdiff_t') + glib_conf.set('HAVE_PTRDIFF_T', 1) +endif + +# Check for sig_atomic_t type +if cc.links('''#include + #include + sig_atomic_t val = 42; + int main (int argc, char ** argv) { + return val == 42 ? 0 : 1; + }''', name : 'sig_atomic_t') + glib_conf.set('HAVE_SIG_ATOMIC_T', 1) +endif + +# Check if 'long long' works +# jm_AC_TYPE_LONG_LONG +if cc.compiles('''long long ll = 1LL; + int i = 63; + int some_func (void) { + long long llmax = (long long) -1; + return ll << i | ll >> i | llmax / ll | llmax % ll; + }''', name : 'long long') + glib_conf.set('HAVE_LONG_LONG', 1) + have_long_long = true +else + have_long_long = false +endif + +# Test whether the compiler supports the 'long double' type. +if cc.compiles('''/* The Stardent Vistra knows sizeof(long double), but does not support it. */ + long double foo = 0.0; + /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + int array [2*(sizeof(long double) >= sizeof(double)) - 1];''', + name : 'long double') + glib_conf.set('HAVE_LONG_DOUBLE', 1) +endif + +# Test whether has the 'wchar_t' type. +if cc.has_header_symbol('stddef.h', 'wchar_t') + glib_conf.set('HAVE_WCHAR_T', 1) +endif + +# Test whether has the 'wint_t' type. +if cc.has_header_symbol('wchar.h', 'wint_t') + glib_conf.set('HAVE_WINT_T', 1) +endif + +found_uintmax_t = false + +# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. +# jm_AC_HEADER_INTTYPES_H +if cc.compiles('''#include + #include + void some_func (void) { + uintmax_t i = (uintmax_t) -1; + }''', name : 'uintmax_t in inttypes.h') + glib_conf.set('HAVE_INTTYPES_H_WITH_UINTMAX', 1) + found_uintmax_t = true +endif + +# Define HAVE_STDINT_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. +# jm_AC_HEADER_STDINT_H +if cc.compiles('''#include + #include + void some_func (void) { + uintmax_t i = (uintmax_t) -1; + }''', name : 'uintmax_t in stdint.h') + glib_conf.set('HAVE_STDINT_H_WITH_UINTMAX', 1) + found_uintmax_t = true +endif + +# Define intmax_t to 'long' or 'long long' +# if it is not already defined in or . +# For simplicity, we assume that a header file defines 'intmax_t' if and +# only if it defines 'uintmax_t'. +if found_uintmax_t + glib_conf.set('HAVE_INTMAX_T', 1) +elif have_long_long + glib_conf.set('intmax_t', 'long long') +else + glib_conf.set('intmax_t', 'long') +endif + +char_size = cc.sizeof('char') +short_size = cc.sizeof('short') +int_size = cc.sizeof('int') +voidp_size = cc.sizeof('void*') +long_size = cc.sizeof('long') +if have_long_long + long_long_size = cc.sizeof('long long') +else + long_long_size = 0 +endif +sizet_size = cc.sizeof('size_t') +if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' + ssizet_size = cc.sizeof('SSIZE_T', prefix : '#include ') +else + ssizet_size = cc.sizeof('ssize_t', prefix : '#include ') +endif + +# Some platforms (Apple) hard-code int64_t to long long instead of +# using long on 64-bit architectures. This can cause type mismatch +# warnings when trying to interface with code using the standard +# library type. Test for the warnings and set gint64 to whichever +# works. +if long_long_size == long_size + if cc.compiles('''#if defined(_AIX) && !defined(__GNUC__) + #pragma options langlvl=stdc99 + #endif + #pragma GCC diagnostic error "-Wincompatible-pointer-types" + #include + #include + int main () { + int64_t i1 = 1; + long *i2 = &i1; + return 1; + }''', name : 'int64_t is long') + int64_t_typedef = 'long' + elif cc.compiles('''#if defined(_AIX) && !defined(__GNUC__) + #pragma options langlvl=stdc99 + #endif + #pragma GCC diagnostic error "-Wincompatible-pointer-types" + #include + #include + int main () { + int64_t i1 = 1; + long long *i2 = &i1; + return 1; + }''', name : 'int64_t is long long') + int64_t_typedef = 'long long' + endif +endif + +int64_m = 'll' +char_align = cc.alignment('char') +short_align = cc.alignment('short') +int_align = cc.alignment('int') +voidp_align = cc.alignment('void*') +long_align = cc.alignment('long') +long_long_align = cc.alignment('long long') +# NOTE: We don't check for size of __int64 because long long is guaranteed to +# be 64-bit in C99, and it is available on all supported compilers +sizet_align = cc.alignment('size_t') + +glib_conf.set('ALIGNOF_UNSIGNED_LONG', long_align) + +glib_conf.set('SIZEOF_CHAR', char_size) +glib_conf.set('SIZEOF_INT', int_size) +glib_conf.set('SIZEOF_SHORT', short_size) +glib_conf.set('SIZEOF_LONG', long_size) +glib_conf.set('SIZEOF_LONG_LONG', long_long_size) +glib_conf.set('SIZEOF_SIZE_T', sizet_size) +glib_conf.set('SIZEOF_SSIZE_T', ssizet_size) +glib_conf.set('SIZEOF_VOID_P', voidp_size) +glib_conf.set('SIZEOF_WCHAR_T', cc.sizeof('wchar_t', prefix: '#include ')) + +if short_size == 2 + gint16 = 'short' + gint16_modifier='h' + gint16_format='hi' + guint16_format='hu' +elif int_size == 2 + gint16 = 'int' + gint16_modifier='' + gint16_format='i' + guint16_format='u' +else + error('Compiler provides no native 16-bit integer type') +endif +glibconfig_conf.set('gint16', gint16) +glibconfig_conf.set_quoted('gint16_modifier', gint16_modifier) +glibconfig_conf.set_quoted('gint16_format', gint16_format) +glibconfig_conf.set_quoted('guint16_format', guint16_format) + +if short_size == 4 + gint32 = 'short' + gint32_modifier='h' + gint32_format='hi' + guint32_format='hu' + guint32_align = short_align +elif int_size == 4 + gint32 = 'int' + gint32_modifier='' + gint32_format='i' + guint32_format='u' + guint32_align = int_align +elif long_size == 4 + gint32 = 'long' + gint32_modifier='l' + gint32_format='li' + guint32_format='lu' + guint32_align = long_align +else + error('Compiler provides no native 32-bit integer type') +endif +glibconfig_conf.set('gint32', gint32) +glibconfig_conf.set_quoted('gint32_modifier', gint32_modifier) +glibconfig_conf.set_quoted('gint32_format', gint32_format) +glibconfig_conf.set_quoted('guint32_format', guint32_format) +glib_conf.set('ALIGNOF_GUINT32', guint32_align) + +if int_size == 8 + gint64 = 'int' + gint64_modifier='' + gint64_format='i' + guint64_format='u' + glib_extension='' + gint64_constant='(val)' + guint64_constant='(val)' + guint64_align = int_align +elif long_size == 8 and (long_long_size != long_size or int64_t_typedef == 'long') + gint64 = 'long' + glib_extension='' + gint64_modifier='l' + gint64_format='li' + guint64_format='lu' + gint64_constant='(val##L)' + guint64_constant='(val##UL)' + guint64_align = long_align +elif long_long_size == 8 and (long_long_size != long_size or int64_t_typedef == 'long long') + gint64 = 'long long' + glib_extension='G_GNUC_EXTENSION ' + gint64_modifier=int64_m + gint64_format=int64_m + 'i' + guint64_format=int64_m + 'u' + gint64_constant='(G_GNUC_EXTENSION (val##LL))' + guint64_constant='(G_GNUC_EXTENSION (val##ULL))' + guint64_align = long_long_align +else + error('Compiler provides no native 64-bit integer type') +endif +glibconfig_conf.set('glib_extension', glib_extension) +glibconfig_conf.set('gint64', gint64) +glibconfig_conf.set_quoted('gint64_modifier', gint64_modifier) +glibconfig_conf.set_quoted('gint64_format', gint64_format) +glibconfig_conf.set_quoted('guint64_format', guint64_format) +glibconfig_conf.set('gint64_constant', gint64_constant) +glibconfig_conf.set('guint64_constant', guint64_constant) +glib_conf.set('ALIGNOF_GUINT64', guint64_align) + +if host_system == 'windows' + glibconfig_conf.set('g_pid_type', 'void*') + glibconfig_conf.set_quoted('g_pid_format', 'p') + if host_machine.cpu_family() == 'x86_64' + glibconfig_conf.set_quoted('g_pollfd_format', '%#' + int64_m + 'x') + else + glibconfig_conf.set_quoted('g_pollfd_format', '%#x') + endif + glibconfig_conf.set('g_dir_separator', '\\\\') + glibconfig_conf.set('g_searchpath_separator', ';') +else + glibconfig_conf.set('g_pid_type', 'int') + glibconfig_conf.set_quoted('g_pid_format', 'i') + glibconfig_conf.set_quoted('g_pollfd_format', '%d') + glibconfig_conf.set('g_dir_separator', '/') + glibconfig_conf.set('g_searchpath_separator', ':') +endif + +g_sizet_compatibility = { + 'short': sizet_size == short_size, + 'int': sizet_size == int_size, + 'long': sizet_size == long_size, + 'long long': sizet_size == long_long_size, +} + +# Do separate checks for gcc/clang (and ignore other compilers for now), since +# we need to explicitly pass -Werror to the compilers. +# FIXME: https://github.com/mesonbuild/meson/issues/5399 +# We can’t simplify these checks using a foreach loop because dictionary keys +# have to be string literals. +# FIXME: https://github.com/mesonbuild/meson/issues/5231 +if cc.get_id() == 'gcc' or cc.get_id() == 'clang' + g_sizet_compatibility += { + 'short': g_sizet_compatibility['short'] and cc.compiles( + '''#include + size_t f (size_t *i) { return *i + 1; } + int main (void) { + unsigned short i = 0; + f (&i); + return 0; + }''', + args: ['-Werror'], + name : 'GCC size_t typedef is short'), + 'int': g_sizet_compatibility['int'] and cc.compiles( + '''#include + size_t f (size_t *i) { return *i + 1; } + int main (void) { + unsigned int i = 0; + f (&i); + return 0; + }''', + args: ['-Werror'], + name : 'GCC size_t typedef is int'), + 'long': g_sizet_compatibility['long'] and cc.compiles( + '''#include + size_t f (size_t *i) { return *i + 1; } + int main (void) { + unsigned long i = 0; + f (&i); + return 0; + }''', + args: ['-Werror'], + name : 'GCC size_t typedef is long'), + 'long long': g_sizet_compatibility['long long'] and cc.compiles( + '''#include + size_t f (size_t *i) { return *i + 1; } + int main (void) { + unsigned long long i = 0; + f (&i); + return 0; + }''', + args: ['-Werror'], + name : 'GCC size_t typedef is long long'), + } +endif + +if g_sizet_compatibility['short'] + glibconfig_conf.set('glib_size_type_define', 'short') + glibconfig_conf.set_quoted('gsize_modifier', 'h') + glibconfig_conf.set_quoted('gssize_modifier', 'h') + glibconfig_conf.set_quoted('gsize_format', 'hu') + glibconfig_conf.set_quoted('gssize_format', 'hi') + glibconfig_conf.set('glib_msize_type', 'SHRT') +elif g_sizet_compatibility['int'] + glibconfig_conf.set('glib_size_type_define', 'int') + glibconfig_conf.set_quoted('gsize_modifier', '') + glibconfig_conf.set_quoted('gssize_modifier', '') + glibconfig_conf.set_quoted('gsize_format', 'u') + glibconfig_conf.set_quoted('gssize_format', 'i') + glibconfig_conf.set('glib_msize_type', 'INT') +elif g_sizet_compatibility['long'] + glibconfig_conf.set('glib_size_type_define', 'long') + glibconfig_conf.set_quoted('gsize_modifier', 'l') + glibconfig_conf.set_quoted('gssize_modifier', 'l') + glibconfig_conf.set_quoted('gsize_format', 'lu') + glibconfig_conf.set_quoted('gssize_format', 'li') + glibconfig_conf.set('glib_msize_type', 'LONG') +elif g_sizet_compatibility['long long'] + glibconfig_conf.set('glib_size_type_define', 'long long') + glibconfig_conf.set_quoted('gsize_modifier', int64_m) + glibconfig_conf.set_quoted('gssize_modifier', int64_m) + glibconfig_conf.set_quoted('gsize_format', int64_m + 'u') + glibconfig_conf.set_quoted('gssize_format', int64_m + 'i') + glibconfig_conf.set('glib_msize_type', 'INT64') +else + error('Could not determine size of size_t.') +endif + +if voidp_size == int_size + glibconfig_conf.set('glib_intptr_type_define', 'int') + glibconfig_conf.set_quoted('gintptr_modifier', '') + glibconfig_conf.set_quoted('gintptr_format', 'i') + glibconfig_conf.set_quoted('guintptr_format', 'u') + glibconfig_conf.set('glib_gpi_cast', '(gint)') + glibconfig_conf.set('glib_gpui_cast', '(guint)') +elif voidp_size == long_size + glibconfig_conf.set('glib_intptr_type_define', 'long') + glibconfig_conf.set_quoted('gintptr_modifier', 'l') + glibconfig_conf.set_quoted('gintptr_format', 'li') + glibconfig_conf.set_quoted('guintptr_format', 'lu') + glibconfig_conf.set('glib_gpi_cast', '(glong)') + glibconfig_conf.set('glib_gpui_cast', '(gulong)') +elif voidp_size == long_long_size + glibconfig_conf.set('glib_intptr_type_define', 'long long') + glibconfig_conf.set_quoted('gintptr_modifier', int64_m) + glibconfig_conf.set_quoted('gintptr_format', int64_m + 'i') + glibconfig_conf.set_quoted('guintptr_format', int64_m + 'u') + glibconfig_conf.set('glib_gpi_cast', '(gint64)') + glibconfig_conf.set('glib_gpui_cast', '(guint64)') +else + error('Could not determine size of void *') +endif + +if long_size != 8 and long_long_size != 8 and int_size != 8 + error('GLib requires a 64-bit type. You might want to consider using the GNU C compiler.') +endif + +glibconfig_conf.set('gintbits', int_size * 8) +glibconfig_conf.set('glongbits', long_size * 8) +glibconfig_conf.set('gsizebits', sizet_size * 8) +glibconfig_conf.set('gssizebits', ssizet_size * 8) + +# XXX: https://gitlab.gnome.org/GNOME/glib/issues/1413 +if host_system == 'windows' + g_module_suffix = 'dll' +else + g_module_suffix = 'so' +endif +glibconfig_conf.set('g_module_suffix', g_module_suffix) + +glibconfig_conf.set('GLIB_MAJOR_VERSION', major_version) +glibconfig_conf.set('GLIB_MINOR_VERSION', minor_version) +glibconfig_conf.set('GLIB_MICRO_VERSION', micro_version) +glibconfig_conf.set('GLIB_VERSION', glib_version) + +glibconfig_conf.set('glib_void_p', voidp_size) +glibconfig_conf.set('glib_long', long_size) +glibconfig_conf.set('glib_size_t', sizet_size) +glibconfig_conf.set('glib_ssize_t', ssizet_size) +if host_machine.endian() == 'big' + glibconfig_conf.set('g_byte_order', 'G_BIG_ENDIAN') + glibconfig_conf.set('g_bs_native', 'BE') + glibconfig_conf.set('g_bs_alien', 'LE') +else + glibconfig_conf.set('g_byte_order', 'G_LITTLE_ENDIAN') + glibconfig_conf.set('g_bs_native', 'LE') + glibconfig_conf.set('g_bs_alien', 'BE') +endif + +# === va_copy checks === +# we currently check for all three va_copy possibilities, so we get +# all results in config.log for bug reports. + +va_copy_func = '' +foreach try_func : [ '__va_copy', 'va_copy' ] + if cc.compiles('''#include + #include + #ifdef _MSC_VER + # include "msvc_recommended_pragmas.h" + #endif + void f (int i, ...) { + va_list args1, args2; + va_start (args1, i); + @0@ (args2, args1); + if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42) + exit (1); + va_end (args1); va_end (args2); + } + int main() { + f (0, 42); + return 0; + }'''.format(try_func), + name : try_func + ' check') + va_copy_func = try_func + endif +endforeach +if va_copy_func != '' + glib_conf.set('G_VA_COPY', va_copy_func) + glib_vacopy = '#define G_VA_COPY ' + va_copy_func +else + glib_vacopy = '/* #undef G_VA_COPY */' +endif + +va_list_val_copy_prog = ''' + #include + #include + void f (int i, ...) { + va_list args1, args2; + va_start (args1, i); + args2 = args1; + if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42) + exit (1); + va_end (args1); va_end (args2); + } + int main() { + f (0, 42); + return 0; + }''' + +if cc_can_run + rres = cc.run(va_list_val_copy_prog, name : 'va_lists can be copied as values') + glib_va_val_copy = rres.compiled() and rres.returncode() == 0 +else + glib_va_val_copy = meson.get_cross_property('va_val_copy', true) +endif +if not glib_va_val_copy + glib_vacopy = glib_vacopy + '\n#define G_VA_COPY_AS_ARRAY 1' + glib_conf.set('G_VA_COPY_AS_ARRAY', 1) +endif +glibconfig_conf.set('glib_vacopy', glib_vacopy) + +# check for flavours of varargs macros +g_have_iso_c_varargs = cc.compiles(''' + void some_func (void) { + int a(int p1, int p2, int p3); + #define call_a(...) a(1,__VA_ARGS__) + call_a(2,3); + }''', name : 'ISO C99 varargs macros in C') + +if g_have_iso_c_varargs + glibconfig_conf.set('g_have_iso_c_varargs', ''' +#ifndef __cplusplus +# define G_HAVE_ISO_VARARGS 1 +#endif''') +endif + +if have_cxx + g_have_iso_cxx_varargs = cxx.compiles(''' + void some_func (void) { + int a(int p1, int p2, int p3); + #define call_a(...) a(1,__VA_ARGS__) + call_a(2,3); + }''', name : 'ISO C99 varargs macros in C++') + + if g_have_iso_cxx_varargs + glibconfig_conf.set('g_have_iso_cxx_varargs', ''' + #ifdef __cplusplus + # define G_HAVE_ISO_VARARGS 1 + #endif''') + endif +endif + +g_have_gnuc_varargs = cc.compiles(''' + void some_func (void) { + int a(int p1, int p2, int p3); + #define call_a(params...) a(1,params) + call_a(2,3); + }''', name : 'GNUC varargs macros') + +if cc.has_header('alloca.h') + glibconfig_conf.set('GLIB_HAVE_ALLOCA_H', true) +endif +has_syspoll = cc.has_header('sys/poll.h') +has_systypes = cc.has_header('sys/types.h') +if has_syspoll + glibconfig_conf.set('GLIB_HAVE_SYS_POLL_H', true) +endif +has_winsock2 = cc.has_header('winsock2.h') + +if has_syspoll and has_systypes + poll_includes = ''' + #include + #include''' +elif has_winsock2 + poll_includes = ''' + #define _WIN32_WINNT @0@ + #include '''.format(glib_conf.get('_WIN32_WINNT')) +else + # FIXME? + error('FIX POLL* defines') +endif + +poll_defines = [ + [ 'POLLIN', 'g_pollin', 1 ], + [ 'POLLOUT', 'g_pollout', 4 ], + [ 'POLLPRI', 'g_pollpri', 2 ], + [ 'POLLERR', 'g_pollerr', 8 ], + [ 'POLLHUP', 'g_pollhup', 16 ], + [ 'POLLNVAL', 'g_pollnval', 32 ], +] + +if has_syspoll and has_systypes + foreach d : poll_defines + val = cc.compute_int(d[0], prefix: poll_includes) + glibconfig_conf.set(d[1], val) + endforeach +elif has_winsock2 + # Due to a missed bug in configure.ac the poll test + # never succeeded on Windows and used some pre-defined + # values as a fallback. Keep using them to maintain + # ABI compatibility with autotools builds of glibs + # and with *any* glib-using code compiled against them, + # since these values end up in a public header glibconfig.h. + foreach d : poll_defines + glibconfig_conf.set(d[1], d[2]) + endforeach +endif + +# Internet address families +# FIXME: what about Cygwin (G_WITH_CYGWIN) +if host_system == 'windows' + inet_includes = ''' + #include ''' +else + inet_includes = ''' + #include + #include ''' +endif + +inet_defines = [ + [ 'AF_UNIX', 'g_af_unix' ], + [ 'AF_INET', 'g_af_inet' ], + [ 'AF_INET6', 'g_af_inet6' ], + [ 'MSG_OOB', 'g_msg_oob' ], + [ 'MSG_PEEK', 'g_msg_peek' ], + [ 'MSG_DONTROUTE', 'g_msg_dontroute' ], +] +foreach d : inet_defines + val = cc.compute_int(d[0], prefix: inet_includes) + glibconfig_conf.set(d[1], val) +endforeach + +if host_system == 'windows' + have_ipv6 = true +else + have_ipv6 = cc.has_type('struct in6_addr', prefix: '#include ') +endif +glib_conf.set('HAVE_IPV6', have_ipv6) + +# We need to decide at configure time if GLib will use real atomic +# operations ("lock free") or emulated ones with a mutex. This is +# because we must put this information in glibconfig.h so we know if +# it is safe or not to inline using compiler intrinsics directly from +# the header. +# +# We also publish the information via G_ATOMIC_LOCK_FREE in case the +# user is interested in knowing if they can use the atomic ops across +# processes. +# +# We can currently support the atomic ops natively when building GLib +# with recent versions of GCC or MSVC. +# +# Note that the atomic ops are only available with GCC on x86 when +# using -march=i486 or higher. If we detect that the atomic ops are +# not available but would be available given the right flags, we want +# to abort and advise the user to fix their CFLAGS. It's better to do +# that then to silently fall back on emulated atomic ops just because +# the user had the wrong build environment. +atomictest = '''int main() { + int atomic = 2; + __sync_bool_compare_and_swap (&atomic, 2, 3); + return 0; +} +''' + +atomicdefine = ''' +#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 +#error "compiler has atomic ops, but doesn't define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4" +#endif +''' + +# We know that we can always use real ("lock free") atomic operations with MSVC +if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' or cc.links(atomictest, name : 'atomic ops') + have_atomic_lock_free = true + if cc.get_id() == 'gcc' and not cc.compiles(atomicdefine, name : 'atomic ops define') + # Old gcc release may provide + # __sync_bool_compare_and_swap but doesn't define + # __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + glib_conf.set('__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4', true) + endif +else + have_atomic_lock_free = false + if host_machine.cpu_family() == 'x86' and cc.links(atomictest, args : '-march=i486') + error('GLib must be built with -march=i486 or later.') + endif +endif +glibconfig_conf.set('G_ATOMIC_LOCK_FREE', have_atomic_lock_free) + +# === Threads === + +if get_option('force_posix_threads') + warning('DEPRECATION: Option \'force_posix_threads\' is deprecated and will be removed after GLib 2.72; please file an issue with your use case if you still require it') +endif + +# Determination of thread implementation +if host_system == 'windows' and not get_option('force_posix_threads') + thread_dep = [] + threads_implementation = 'win32' + glibconfig_conf.set('g_threads_impl_def', 'WIN32') + glib_conf.set('THREADS_WIN32', 1) +else + thread_dep = dependency('threads') + threads_implementation = 'posix' + pthread_prefix = ''' + #ifndef _GNU_SOURCE + # define _GNU_SOURCE + #endif + #include ''' + glibconfig_conf.set('g_threads_impl_def', 'POSIX') + glib_conf.set('THREADS_POSIX', 1) + if cc.has_header_symbol('pthread.h', 'pthread_attr_setstacksize') + glib_conf.set('HAVE_PTHREAD_ATTR_SETSTACKSIZE', 1) + endif + if cc.has_header_symbol('pthread.h', 'pthread_attr_setinheritsched') + glib_conf.set('HAVE_PTHREAD_ATTR_SETINHERITSCHED', 1) + endif + if cc.has_header_symbol('pthread.h', 'pthread_condattr_setclock') + glib_conf.set('HAVE_PTHREAD_CONDATTR_SETCLOCK', 1) + endif + if cc.has_header_symbol('pthread.h', 'pthread_cond_timedwait_relative_np') + glib_conf.set('HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP', 1) + endif + if cc.has_header_symbol('pthread.h', 'pthread_getname_np', prefix : pthread_prefix) + glib_conf.set('HAVE_PTHREAD_GETNAME_NP', 1) + endif + + if cc.has_header_symbol('sys/syscall.h', 'SYS_sched_getattr') + glib_conf.set('HAVE_SYS_SCHED_GETATTR', 1) + endif + + # Assume that pthread_setname_np is available in some form; same as configure + if cc.links(pthread_prefix + ''' + int main() { + pthread_setname_np("example"); + return 0; + }''', + name : 'pthread_setname_np(const char*)', + dependencies : thread_dep) + # macOS and iOS + glib_conf.set('HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID', 1) + elif cc.links(pthread_prefix + ''' + int main() { + pthread_setname_np(pthread_self(), "example"); + return 0; + }''', + name : 'pthread_setname_np(pthread_t, const char*)', + dependencies : thread_dep) + # Linux, Solaris, etc. + glib_conf.set('HAVE_PTHREAD_SETNAME_NP_WITH_TID', 1) + elif cc.links(pthread_prefix + ''' + int main() { + pthread_setname_np(pthread_self(), "%s", "example"); + return 0; + }''', + name : 'pthread_setname_np(pthread_t, const char*, void*)', + dependencies : thread_dep) + # NetBSD + glib_conf.set('HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG', 1) + elif cc.links(pthread_prefix + ''' + #include + int main() { + pthread_set_name_np(pthread_self(), "example"); + return 0; + }''', + name : 'pthread_set_name_np(pthread_t, const char*)', + dependencies : thread_dep) + # FreeBSD, DragonFlyBSD, OpenBSD, etc. + glib_conf.set('HAVE_PTHREAD_SET_NAME_NP', 1) + endif +endif + +# FIXME: we should make it print the result and always return 0, so that +# the output in meson shows up as green +# volatile is needed here to avoid optimisations in the test +stack_grows_check_prog = ''' + volatile int *a = 0, *b = 0; + void f (int i) { + volatile int x = 5; + if (i == 0) + b = &x; + else + f (i - 1); + } + int main () { + volatile int y = 7; + a = &y; + f (100); + return b > a ? 0 : 1; + }''' + +if cc_can_run + rres = cc.run(stack_grows_check_prog, name : 'stack grows check') + growing_stack = rres.compiled() and rres.returncode() == 0 +else + growing_stack = meson.get_cross_property('growing_stack', false) +endif + +glibconfig_conf.set10('G_HAVE_GROWING_STACK', growing_stack) + +# Tests for iconv +# +# We should never use the MinGW C library's iconv because it may not be +# available in the actual runtime environment. On Windows, we always use +# the built-in implementation +iconv_opt = get_option('iconv') +if host_system == 'windows' + libiconv = [] + # We have a #include "win_iconv.c" in gconvert.c on Windows, so we don't need + # any external library for it + if iconv_opt != 'auto' + warning('-Diconv was set to @0@, which was ignored') + endif +else + found_iconv = false + if ['auto', 'libc'].contains(iconv_opt) and cc.has_function('iconv_open') + libiconv = [] + found_iconv = true + endif + if not found_iconv and ['auto', 'external'].contains(iconv_opt) and cc.has_header_symbol('iconv.h', 'iconv_open') + libiconv = [cc.find_library('iconv')] + found_iconv = true + endif + + if not found_iconv + error('iconv implementation "@0@" not found'.format(iconv_opt)) + endif +endif + +pcre = dependency('libpcre', version: '>= 8.31', required : false) # Should check for Unicode support, too. FIXME +if not pcre.found() + if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' + # MSVC: Search for the PCRE library by the configuration, which corresponds + # to the output of CMake builds of PCRE. Note that debugoptimized + # is really a Release build with .PDB files. + if vs_crt == 'debug' + pcre = cc.find_library('pcred', required : false) + else + pcre = cc.find_library('pcre', required : false) + endif + endif +endif + +# Try again with the fallback +if not pcre.found() + pcre = dependency('libpcre', required : true, fallback : ['pcre', 'pcre_dep']) + use_pcre_static_flag = true +elif host_system == 'windows' + pcre_static = cc.links('''#define PCRE_STATIC + #include + int main() { + void *p = NULL; + pcre_free(p); + return 0; + }''', + dependencies: pcre, + name : 'Windows system PCRE is a static build') + use_pcre_static_flag = pcre_static +else + use_pcre_static_flag = false +endif + +libm = cc.find_library('m', required : false) +libffi_dep = dependency('libffi', version : '>= 3.0.0', fallback : ['libffi', 'ffi_dep']) + +if get_option('wrap_mode') == 'forcefallback' + # Respects "wrap_mode=forcefallback" option + libz_dep = subproject('zlib').get_variable('zlib_dep') +else + # Don't use the bundled ZLib sources until we are sure that we can't find it on + # the system + libz_dep = dependency('zlib', required : false) +endif + +if not libz_dep.found() + if cc.get_id() != 'msvc' and cc.get_id() != 'clang-cl' + libz_dep = cc.find_library('z', required : false) + else + libz_dep = cc.find_library('zlib1', required : false) + if not libz_dep.found() + libz_dep = cc.find_library('zlib', required : false) + endif + endif + if not libz_dep.found() or not cc.has_header('zlib.h') + libz_dep = subproject('zlib').get_variable('zlib_dep') + endif +endif + +# First check in libc, fallback to libintl, and as last chance build +# proxy-libintl subproject. +# FIXME: glib-gettext.m4 has much more checks to detect broken/uncompatible +# implementations. This could be extended if issues are found in some platforms. +libintl_deps = [] +if cc.has_function('ngettext') + have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset') +else + # First just find the bare library. + libintl = cc.find_library('intl', required : false) + # The bare library probably won't link without help if it's static. + if libintl.found() and not cc.has_function('ngettext', dependencies : libintl) + libintl_iconv = cc.find_library('iconv', required : false) + # libintl supports different threading APIs, which may not + # require additional flags, but it defaults to using pthreads if + # found. Meson's "threads" dependency does not allow you to + # prefer pthreads. We may not be using pthreads for glib itself + # either so just link the library to satisfy libintl rather than + # also defining the macros with the -pthread flag. + libintl_pthread = cc.find_library('pthread', required : false) + # Try linking with just libiconv. + if libintl_iconv.found() and cc.has_function('ngettext', dependencies : [libintl, libintl_iconv]) + libintl_deps += [libintl_iconv] + # Then also try linking with pthreads. + elif libintl_iconv.found() and libintl_pthread.found() and cc.has_function('ngettext', dependencies : [libintl, libintl_iconv, libintl_pthread]) + libintl_deps += [libintl_iconv, libintl_pthread] + else + libintl = disabler() + endif + endif + if not libintl.found() + libintl = subproject('proxy-libintl').get_variable('intl_dep') + libintl_deps = [libintl] + libintl_deps + have_bind_textdomain_codeset = true # proxy-libintl supports it + else + libintl_deps = [libintl] + libintl_deps + have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset', + dependencies : libintl_deps) + endif +endif + +glib_conf.set('HAVE_BIND_TEXTDOMAIN_CODESET', have_bind_textdomain_codeset) + +# We require gettext to always be present +glib_conf.set('HAVE_DCGETTEXT', 1) +glib_conf.set('HAVE_GETTEXT', 1) + +glib_conf.set_quoted('GLIB_LOCALE_DIR', join_paths(glib_datadir, 'locale')) + +# libmount is only used by gio, but we need to fetch the libs to generate the +# pkg-config file below +libmount_dep = [] +if host_system == 'linux' + libmount_dep = dependency('mount', version : '>=2.23', required : get_option('libmount')) + glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found()) +endif + +if host_system == 'windows' + winsock2 = cc.find_library('ws2_32') +endif + +selinux_dep = [] +if host_system == 'linux' + selinux_dep = dependency('libselinux', version: '>=2.2', required: get_option('selinux')) + + glib_conf.set('HAVE_SELINUX', selinux_dep.found()) +endif + +xattr_dep = [] +if host_system != 'windows' and get_option('xattr') + # either glibc or libattr can provide xattr support + # for both of them, we check for getxattr being in + # the library and a valid xattr header. + + # try glibc + if cc.has_function('getxattr') and cc.has_header('sys/xattr.h') + glib_conf.set('HAVE_SYS_XATTR_H', 1) + glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format('HAVE_SYS_XATTR_H') + #failure. try libattr + elif cc.has_header_symbol('attr/xattr.h', 'getxattr') + glib_conf.set('HAVE_ATTR_XATTR_H', 1) + glib_conf_prefix = glib_conf_prefix + '#define @0@ 1\n'.format('HAVE_ATTR_XATTR_H') + xattr_dep = [cc.find_library('xattr')] + else + error('No getxattr implementation found in C library or libxattr') + endif + + glib_conf.set('HAVE_XATTR', 1) + if cc.compiles(glib_conf_prefix + ''' + #include + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #ifdef HAVE_SYS_XATTR_H + #include + #elif HAVE_ATTR_XATTR_H + #include + #endif + + int main (void) { + ssize_t len = getxattr("", "", NULL, 0, 0, XATTR_NOFOLLOW); + return len; + }''', + name : 'XATTR_NOFOLLOW') + glib_conf.set('HAVE_XATTR_NOFOLLOW', 1) + endif +endif + +# If strlcpy is present (BSD and similar), check that it conforms to the BSD +# specification. Specifically Solaris 8's strlcpy() does not, see +# https://bugzilla.gnome.org/show_bug.cgi?id=53933 for further context. +if cc.has_function('strlcpy') + if cc_can_run + rres = cc.run('''#include + #include + int main() { + char p[10]; + (void) strlcpy (p, "hi", 10); + if (strlcat (p, "bye", 0) != 3) + return 1; + return 0; + }''', + name : 'OpenBSD strlcpy/strlcat') + if rres.compiled() and rres.returncode() == 0 + glib_conf.set('HAVE_STRLCPY', 1) + endif + elif meson.get_cross_property('have_strlcpy', false) + glib_conf.set('HAVE_STRLCPY', 1) + endif +endif + +cmdline_test_code = ''' +#include +#include +#include +#include +#include + +static int +__getcmdline (void) +{ +/* This code is a dumbed-down version of g_file_get_contents() */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif +#define BUFSIZE 1024 + char result[BUFSIZE]; + struct stat stat_buf; + + int fd = open ("/proc/self/cmdline", O_RDONLY|O_BINARY); + if (fd < 0) + exit (1); + if (fstat (fd, &stat_buf)) + exit (1); + + if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode)) + { + if (read (fd, result, BUFSIZE) <= 0) + exit (1); + } + else + { + FILE *f = fdopen (fd, "r"); + if (f == NULL) + exit (1); + + if (fread (result, 1, BUFSIZE, f) <= 0) + exit (1); + } + + return 0; +} + +int +main (void) +{ + exit (__getcmdline ()); +}''' + +if cc_can_run + rres = cc.run(cmdline_test_code, name : '/proc/self/cmdline') + have_proc_self_cmdline = rres.compiled() and rres.returncode() == 0 +else + have_proc_self_cmdline = meson.get_cross_property('have_proc_self_cmdline', false) +endif + +glib_conf.set('HAVE_PROC_SELF_CMDLINE', have_proc_self_cmdline) + +python = import('python').find_installation('python3') +# used for '#!/usr/bin/env ' +python_name = 'python3' + +python_version = python.language_version() +python_version_req = '>=3.5' +if not python_version.version_compare(python_version_req) + error('Requires Python @0@, @1@ found.'.format(python_version_req, python_version)) +endif + +# Determine which user environment-dependent files that we want to install +have_bash = find_program('bash', required : false).found() # For completion scripts +bash_comp_dep = dependency('bash-completion', version: '>=2.0', required: false) +have_sh = find_program('sh', required : false).found() # For glib-gettextize + +# Some installed tests require a custom environment +env_program = find_program('env', required: installed_tests_enabled) + +# FIXME: How to detect Solaris? https://github.com/mesonbuild/meson/issues/1578 +if host_system == 'sunos' + glib_conf.set('_XOPEN_SOURCE_EXTENDED', 1) + glib_conf.set('_XOPEN_SOURCE', 2) + glib_conf.set('__EXTENSIONS__',1) +endif + +# Sadly Meson does not expose this value: +# https://github.com/mesonbuild/meson/pull/3460 +if host_system == 'windows' + # Autotools explicitly removed --Wl,--export-all-symbols from windows builds, + # with no explanation. Do the same here for now but this could be revisited if + # if causes issues. + export_dynamic_ldflags = [] +elif host_system == 'cygwin' + export_dynamic_ldflags = ['-Wl,--export-all-symbols'] +elif host_system in ['darwin', 'ios'] + export_dynamic_ldflags = [] +elif host_system == 'sunos' + export_dynamic_ldflags = [] +else + export_dynamic_ldflags = ['-Wl,--export-dynamic'] +endif + +win32_cflags = [] +win32_ldflags = [] +if host_system == 'windows' and cc.get_id() != 'msvc' and cc.get_id() != 'clang-cl' + # Ensure MSVC-compatible struct packing convention is used when + # compiling for Win32 with gcc. It is used for the whole project and exposed + # in glib-2.0.pc. + win32_cflags = ['-mms-bitfields'] + add_project_arguments(win32_cflags, language : 'c') + + # Win32 API libs, used only by libglib and exposed in glib-2.0.pc + win32_ldflags = ['-lws2_32', '-lole32', '-lwinmm', '-lshlwapi', '-luuid'] +elif host_system == 'cygwin' + win32_ldflags = ['-luser32', '-lkernel32'] +endif + +# Tracing: dtrace +want_dtrace = get_option('dtrace') +enable_dtrace = false + +# Since dtrace support is opt-in we just error out if it was requested but +# is not available. We don't bother with autodetection yet. +if want_dtrace + if glib_have_carbon + error('GLib dtrace support not yet compatible with macOS dtrace') + endif + dtrace = find_program('dtrace', required : true) # error out if not found + if not cc.has_header('sys/sdt.h') + error('dtrace support needs sys/sdt.h header') + endif + # FIXME: autotools build also passes -fPIC -DPIC but is it needed in this case? + dtrace_obj_gen = generator(dtrace, + output : '@BASENAME@.o', + arguments : ['-G', '-s', '@INPUT@', '-o', '@OUTPUT@']) + # FIXME: $(SED) -e "s,define STAP_HAS_SEMAPHORES 1,undef STAP_HAS_SEMAPHORES," + # -e "s,define _SDT_HAS_SEMAPHORES 1,undef _SDT_HAS_SEMAPHORES," + dtrace_hdr_gen = generator(dtrace, + output : '@BASENAME@.h', + arguments : ['-h', '-s', '@INPUT@', '-o', '@OUTPUT@']) + glib_conf.set('HAVE_DTRACE', 1) + enable_dtrace = true +endif + +# systemtap +want_systemtap = get_option('systemtap') +enable_systemtap = false + +if want_systemtap and enable_dtrace + tapset_install_dir = get_option('tapset_install_dir') + if tapset_install_dir == '' + tapset_install_dir = join_paths(get_option('datadir'), 'systemtap/tapset', host_machine.cpu_family()) + endif + stp_cdata = configuration_data() + stp_cdata.set('ABS_GLIB_RUNTIME_LIBDIR', glib_libdir) + stp_cdata.set('LT_CURRENT', minor_version * 100) + stp_cdata.set('LT_REVISION', micro_version) + enable_systemtap = true +endif + +test_timeout = 60 +test_timeout_slow = 180 + +pkg = import('pkgconfig') +windows = import('windows') +subdir('glib') +subdir('gobject') +subdir('gthread') +subdir('gmodule') +subdir('gio') +subdir('fuzzing') +if build_tests + subdir('tests') +endif + +# xgettext is optional (on Windows for instance) +if find_program('xgettext', required : get_option('nls')).found() + subdir('po') +endif + +# Install glib-gettextize executable, if a UNIX-style shell is found +if have_sh + # These should not contain " quotes around the values + gettextize_conf = configuration_data() + gettextize_conf.set('PACKAGE', 'glib') + gettextize_conf.set('VERSION', meson.project_version()) + gettextize_conf.set('prefix', glib_prefix) + gettextize_conf.set('datarootdir', glib_datadir) + gettextize_conf.set('datadir', glib_datadir) + configure_file(input : 'glib-gettextize.in', + install_dir : glib_bindir, + output : 'glib-gettextize', + configuration : gettextize_conf) +endif + +# Install m4 macros that other projects use +install_data('m4macros/glib-2.0.m4', 'm4macros/glib-gettext.m4', 'm4macros/gsettings.m4', + install_dir : join_paths(get_option('datadir'), 'aclocal')) + +if host_system != 'windows' + # Install Valgrind suppression file (except on Windows, + # as Valgrind is currently not supported on Windows) + install_data('glib.supp', + install_dir : join_paths(get_option('datadir'), 'glib-2.0', 'valgrind')) +endif + +configure_file(output : 'config.h', configuration : glib_conf) + +if host_system == 'windows' + install_headers([ 'msvc_recommended_pragmas.h' ], subdir : 'glib-2.0') +endif + +if get_option('man') + xsltproc = find_program('xsltproc', required : true) + xsltproc_command = [ + xsltproc, + '--nonet', + '--stringparam', 'man.output.quietly', '1', + '--stringparam', 'funcsynopsis.style', 'ansi', + '--stringparam', 'man.th.extra1.suppress', '1', + '--stringparam', 'man.authors.section.enabled', '0', + '--stringparam', 'man.copyright.section.enabled', '0', + '-o', '@OUTPUT@', + 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl', + '@INPUT@', + ] + man1_dir = join_paths(glib_prefix, get_option('mandir'), 'man1') +endif + +gnome = import('gnome') +subdir('docs/reference') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..6cd7bc9 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,124 @@ +option('runtime_libdir', + type : 'string', + value : '', + description : 'install runtime libraries relative to libdir') + +option('iconv', + type : 'combo', + choices : ['auto', 'libc', 'external'], + value : 'auto', + description : 'iconv implementation to use (\'libc\' = \'Part of the C library\'; \'external\' = \'External libiconv\'; \'auto\' = \'Auto-detect which iconv is available\')') + +option('charsetalias_dir', + type : 'string', + value : '', + description : 'directory for charset.alias dir (default to \'libdir\' if unset)') + +option('gio_module_dir', + type : 'string', + value : '', + description : 'load gio modules from this directory (default to \'libdir/gio/modules\' if unset)') + +option('selinux', + type : 'feature', + value : 'auto', + description : 'build with selinux support') + +option('xattr', + type : 'boolean', + value : true, + description : 'build with xattr support') + +option('libmount', + type : 'feature', + value : 'auto', + description : 'build with libmount support') + +option('man', + type : 'boolean', + value : false, + description : 'generate man pages (requires xsltproc)') + +option('dtrace', + type : 'boolean', + value : false, + description : 'include tracing support for dtrace') + +option('systemtap', + type : 'boolean', + value : false, + description : 'include tracing support for systemtap') + +option('tapset_install_dir', + type : 'string', + value : '', + description : 'path where systemtap tapsets are installed') + +option('sysprof', + type : 'feature', + value : 'disabled', + description : 'include tracing support for sysprof') + +option('gtk_doc', + type : 'boolean', + value : false, + description : 'use gtk-doc to build documentation') + +option('bsymbolic_functions', + type : 'boolean', + value : true, + description : 'link with -Bsymbolic-functions if supported') + +option('force_posix_threads', + type : 'boolean', + value : false, + description : 'Also use posix threads in case the platform defaults to another implementation (on Windows for example)') + +option('fam', + type : 'boolean', + value : false, + description : 'Use fam for file system monitoring') + +option('tests', + type : 'boolean', + value : true, + description : 'build tests') + +option('installed_tests', + type : 'boolean', + value : false, + description : 'enable installed tests') + +option('nls', + type : 'feature', + value : 'auto', + yield: true, + description : 'Enable native language support (translations)') + +option('oss_fuzz', + type : 'feature', + value : 'disabled', + description : 'Indicate oss-fuzz build environment') + +option('glib_debug', + type : 'feature', + value : 'auto', + yield : true, + description : 'Enable GLib debug infrastructure (see docs/macros.txt)') + +option('glib_assert', + type : 'boolean', + value : true, + yield : true, + description : 'Enable GLib assertion (see docs/macros.txt)') + +option('glib_checks', + type : 'boolean', + value : true, + yield : true, + description : 'Enable GLib checks such as API guards (see docs/macros.txt)') + +option('libelf', + type : 'feature', + value : 'auto', + description : 'Enable support for listing and extracting from ELF resource files with gresource tool') \ No newline at end of file diff --git a/msvc_recommended_pragmas.h b/msvc_recommended_pragmas.h new file mode 100644 index 0000000..051a02a --- /dev/null +++ b/msvc_recommended_pragmas.h @@ -0,0 +1,41 @@ +#ifndef _MSC_VER +#pragma error "This header is for Microsoft VC or clang-cl only." +#endif /* _MSC_VER */ + +/* Make MSVC more pedantic, this is a recommended pragma list + * from _Win32_Programming_ by Rector and Newcomer. + */ +#ifndef __clang__ +#pragma warning(error:4002) /* too many actual parameters for macro */ +#pragma warning(error:4003) /* not enough actual parameters for macro */ +#pragma warning(1:4010) /* single-line comment contains line-continuation character */ +#pragma warning(error:4013) /* 'function' undefined; assuming extern returning int */ +#pragma warning(1:4016) /* no function return type; using int as default */ +#pragma warning(error:4020) /* too many actual parameters */ +#pragma warning(error:4021) /* too few actual parameters */ +#pragma warning(error:4027) /* function declared without formal parameter list */ +#pragma warning(error:4029) /* declared formal parameter list different from definition */ +#pragma warning(error:4033) /* 'function' must return a value */ +#pragma warning(error:4035) /* 'function' : no return value */ +#pragma warning(error:4045) /* array bounds overflow */ +#pragma warning(error:4047) /* different levels of indirection */ +#pragma warning(error:4049) /* terminating line number emission */ +#pragma warning(error:4053) /* An expression of type void was used as an operand */ +#pragma warning(error:4071) /* no function prototype given */ +#pragma warning(disable:4101) /* unreferenced local variable */ +#pragma warning(error:4150) + +/* G_NORETURN */ +#pragma warning(error:4646) /* function declared with __declspec(noreturn) has non-void return type */ +#pragma warning(error:4715) /* 'function': not all control paths return a value */ +#pragma warning(error:4098) /* 'void' function returning a value */ + +#pragma warning(disable:4244) /* No possible loss of data warnings */ +#pragma warning(disable:4305) /* No truncation from int to char warnings */ + +#pragma warning(error:4819) /* The file contains a character that cannot be represented in the current code page */ +#endif /* __clang__ */ + +/* work around Microsoft's premature attempt to deprecate the C-Library */ +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NONSTDC_NO_WARNINGS diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 0000000..7a2b776 --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,100 @@ +# please keep this list sorted alphabetically +# +af +am +an +ar +as +ast +az +be +be@latin +bg +bn +bn_IN +bs +ca +ca@valencia +cs +cy +da +de +dz +el +en_CA +en_GB +en@shaw +eo +es +et +eu +fa +fi +fr +fur +ga +gd +gl +gu +he +hi +hr +hu +hy +id +is +it +ja +ka +kk +kn +ko +ku +lt +lv +mai +mg +mk +ml +mn +mr +ms +nb +nds +ne +nl +nn +oc +or +pa +pl +ps +pt +pt_BR +ro +ru +rw +si +sk +sl +sq +sr +sr@latin +sr@ije +sv +ta +te +tg +th +tl +tr +ug +tt +uk +vi +wa +xh +yi +zh_CN +zh_HK +zh_TW diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 0000000..fb60b9b --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,268 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. +# +# - Modified by Owen Taylor to use GETTEXT_PACKAGE +# instead of PACKAGE and to look for po2tbl in ./ not in intl/ +# +# - Modified by jacob berkman to install +# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize + +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = @SHELL@ +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +datadir = @datadir@ +libdir = @libdir@ +localedir = $(libdir)/locale +gnulocaledir = $(datadir)/locale +gettextsrcdir = $(datadir)/glib-2.0/gettext/po +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = mkdir -p + +CC = @CC@ +GENCAT = @GENCAT@ +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +XGETTEXT = @XGETTEXT@ +MSGMERGE = msgmerge + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. -I$(top_srcdir)/intl + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +SOURCES = +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +DISTFILES = LINGUAS Makefile.in.in POTFILES.in $(GETTEXT_PACKAGE).pot \ +$(POFILES) $(GMOFILES) $(SOURCES) + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(GETTEXT_PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(GETTEXT_PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + $(AM_V_GEN) file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) $(MSGFMT_OPTS) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && $(GENCAT) $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: $(CATALOGS) +all-no: + +$(srcdir)/$(GETTEXT_PACKAGE).pot: $(POTFILES) + $(XGETTEXT) --default-domain=$(GETTEXT_PACKAGE) --from-code=UTF-8 \ + --msgid-bugs-address='http://bugzilla.gnome.org/enter_bug.cgi?product=glib&keywords=I18N+L10N&component=general' \ + --add-comments --keyword=_ --keyword=N_ \ + --keyword=C_:1c,2 \ + --keyword=NC_:1c,2 \ + --keyword=g_dcgettext:2 \ + --keyword=g_dngettext:2,3 \ + --keyword=g_dpgettext2:2c,3 \ + --flag=N_:1:pass-c-format \ + --flag=C_:2:pass-c-format \ + --flag=NC_:2:pass-c-format \ + --flag=g_dngettext:2:pass-c-format \ + --flag=g_strdup_printf:1:c-format \ + --flag=g_string_printf:2:c-format \ + --flag=g_string_append_printf:2:c-format \ + --flag=g_error_new:3:c-format \ + --flag=g_set_error:4:c-format \ + --flag=g_markup_printf_escaped:1:c-format \ + --flag=g_log:3:c-format \ + --flag=g_print:1:c-format \ + --flag=g_printerr:1:c-format \ + --flag=g_printf:1:c-format \ + --flag=g_fprintf:2:c-format \ + --flag=g_sprintf:2:c-format \ + --flag=g_snprintf:3:c-format \ + --flag=g_scanner_error:2:c-format \ + --flag=g_scanner_warn:2:c-format \ + $(POTFILES) \ + && test ! -f $(GETTEXT_PACKAGE).po \ + || ( rm -f $(srcdir)/$(GETTEXT_PACKAGE).pot \ + && mv $(GETTEXT_PACKAGE).po $(srcdir)/$(GETTEXT_PACKAGE).pot ) + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + case "$$cat" in \ + *.gmo) destdir=$(gnulocaledir);; \ + *) destdir=$(localedir);; \ + esac; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \ + $(MKINSTALLDIRS) $$dir; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ + echo "installing $$cat as $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT)"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT)"; \ + fi; \ + if test -r $$cat.m; then \ + $(INSTALL_DATA) $$cat.m $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $$cat.m as $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m"; \ + else \ + if test -r $(srcdir)/$$cat.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$cat.m \ + $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m"; \ + else \ + true; \ + fi; \ + fi; \ + done + if test "$(PACKAGE)" = "glib"; then \ + $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \ + $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ + $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ + rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ + rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \ + done + if test "$(PACKAGE)" = "glib"; then \ + rm -f $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ + fi + +check: all + +dvi info tags TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(GETTEXT_PACKAGE).po *.old.po cat-id-tbl.tmp + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(GMOFILES) + +distdir = ../$(GETTEXT_PACKAGE)-$(VERSION)/$(subdir) +dist distdir: $(DISTFILES) + dists="$(DISTFILES)"; \ + for file in $$dists; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(GETTEXT_PACKAGE).pot + tmpdir=`pwd`; \ + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + echo "$$lang:"; \ + if $(MSGMERGE) $$lang.po $(GETTEXT_PACKAGE).pot -o $$tmpdir/$$lang.new.po; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$cat failed!"; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi; \ + done + +# POTFILES is created from POTFILES.in by stripping comments, empty lines +# and Intltool tags (enclosed in square brackets), and appending a full +# relative path to them +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + rm -f $@-t $@ \ + && (sed -e '/^#/d' \ + -e "s/^\[.*\] +//" \ + -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ + | sed -e '$$s/\\$$//') > $@-t \ + && chmod a-w $@-t \ + && mv $@-t $@ ) + +Makefile: Makefile.in.in ../config.status POTFILES + cd .. \ + && $(SHELL) ./config.status $(subdir)/$@.in + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..24daa08 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,205 @@ +gio/gaction.c +gio/gactiongroup.c +gio/gappinfo.c +gio/gapplication.c +gio/gapplicationcommandline.c +gio/gapplication-tool.c +gio/gasynchelper.c +gio/gasyncinitable.c +gio/gasyncresult.c +gio/gbufferedinputstream.c +gio/gbufferedoutputstream.c +gio/gbytesicon.c +gio/gcancellable.c +gio/gcharsetconverter.c +gio/gcontenttype.c +gio/gcontenttype-win32.c +gio/gconverter.c +gio/gconverterinputstream.c +gio/gconverteroutputstream.c +gio/gcredentials.c +gio/gdatagrambased.c +gio/gdatainputstream.c +gio/gdataoutputstream.c +gio/gdbusaddress.c +gio/gdbusauth.c +gio/gdbusauthmechanism.c +gio/gdbusauthmechanismsha1.c +gio/gdbusauthobserver.c +gio/gdbusconnection.c +gio/gdbusdaemon.c +gio/gdbusinterfaceskeleton.c +gio/gdbusmessage.c +gio/gdbusmethodinvocation.c +gio/gdbusobject.c +gio/gdbusobjectmanager.c +gio/gdbusobjectmanagerclient.c +gio/gdbusobjectskeleton.c +gio/gdbusprivate.c +gio/gdbusproxy.c +gio/gdbusserver.c +gio/gdbus-tool.c +gio/gdebugcontrollerdbus.c +gio/gdesktopappinfo.c +gio/gdrive.c +gio/gdtlsclientconnection.c +gio/gdtlsconnection.c +gio/gdtlsserverconnection.c +gio/gdummyfile.c +gio/gdummytlsbackend.c +gio/gemblem.c +gio/gemblemedicon.c +gio/gfileattribute.c +gio/gfile.c +gio/gfileenumerator.c +gio/gfileicon.c +gio/gfileinfo.c +gio/gfileinputstream.c +gio/gfileiostream.c +gio/gfilemonitor.c +gio/gfilenamecompleter.c +gio/gfileoutputstream.c +gio/gfilterinputstream.c +gio/gfilteroutputstream.c +gio/ghttpproxy.c +gio/gicon.c +gio/ginetaddress.c +gio/ginetaddressmask.c +gio/ginetsocketaddress.c +gio/ginitable.c +gio/ginputstream.c +gio/gioerror.c +gio/giomodule.c +gio/gioscheduler.c +gio/giostream.c +gio/gio-tool.c +gio/gio-tool-cat.c +gio/gio-tool-copy.c +gio/gio-tool-info.c +gio/gio-tool-launch.c +gio/gio-tool-list.c +gio/gio-tool-mime.c +gio/gio-tool-mkdir.c +gio/gio-tool-monitor.c +gio/gio-tool-mount.c +gio/gio-tool-move.c +gio/gio-tool-open.c +gio/gio-tool-remove.c +gio/gio-tool-rename.c +gio/gio-tool-save.c +gio/gio-tool-set.c +gio/gio-tool-trash.c +gio/gio-tool-tree.c +gio/gkeyfilesettingsbackend.c +gio/glib-compile-resources.c +gio/glib-compile-schemas.c +gio/glistmodel.c +gio/gloadableicon.c +gio/glocalfile.c +gio/glocalfileenumerator.c +gio/glocalfileinfo.c +gio/glocalfileinputstream.c +gio/glocalfilemonitor.c +gio/glocalfileoutputstream.c +gio/glocalvfs.c +gio/gmemoryinputstream.c +gio/gmemorymonitor.c +gio/gmemoryoutputstream.c +gio/gmenumodel.c +gio/gmount.c +gio/gmountoperation.c +gio/gnativesocketaddress.c +gio/gnativevolumemonitor.c +gio/gnetworkaddress.c +gio/gnetworkmonitorbase.c +gio/gnetworkmonitor.c +gio/gnetworkmonitornetlink.c +gio/gnetworkmonitornm.c +gio/gnetworkservice.c +gio/goutputstream.c +gio/gpermission.c +gio/gpollableinputstream.c +gio/gpollableoutputstream.c +gio/gpollfilemonitor.c +gio/gpropertyaction.c +gio/gproxyaddress.c +gio/gproxyaddressenumerator.c +gio/gresolver.c +gio/gresource.c +gio/gresourcefile.c +gio/gresource-tool.c +gio/gseekable.c +gio/gsettingsbackend.c +gio/gsettings.c +gio/gsettings-tool.c +gio/gsimpleaction.c +gio/gsimpleasyncresult.c +gio/gsimpleiostream.c +gio/gsimpleproxyresolver.c +gio/gsocketaddress.c +gio/gsocket.c +gio/gsocketclient.c +gio/gsocketconnectable.c +gio/gsocketconnection.c +gio/gsocketinputstream.c +gio/gsocketlistener.c +gio/gsocketoutputstream.c +gio/gsocketservice.c +gio/gsocks4aproxy.c +gio/gsocks5proxy.c +gio/gsubprocess.c +gio/gtask.c +gio/gtcpconnection.c +gio/gtcpwrapperconnection.c +gio/gtestdbus.c +gio/gthemedicon.c +gio/gthreadedresolver.c +gio/gthreadedsocketservice.c +gio/gtlscertificate.c +gio/gtlsclientconnection.c +gio/gtlsconnection.c +gio/gtlsfiledatabase.c +gio/gtlspassword.c +gio/gtlsserverconnection.c +gio/gunionvolumemonitor.c +gio/gunixconnection.c +gio/gunixcredentialsmessage.c +gio/gunixinputstream.c +gio/gunixmount.c +gio/gunixmounts.c +gio/gunixoutputstream.c +gio/gunixsocketaddress.c +gio/gunixvolume.c +gio/gunixvolumemonitor.c +gio/gvfs.c +gio/gvolume.c +gio/gvolumemonitor.c +gio/gwin32appinfo.c +gio/gwin32inputstream.c +gio/gwin32outputstream.c +gio/gzlibcompressor.c +gio/gzlibdecompressor.c +gio/tests/gdbus-daemon.c +gio/win32/gwinhttpfile.c +glib/gatomic.c +glib/gbookmarkfile.c +glib/gconvert.c +glib/gdatetime.c +glib/gdir.c +glib/gfileutils.c +glib/giochannel.c +glib/giowin32.c +glib/gkeyfile.c +glib/gmappedfile.c +glib/gmarkup.c +glib/goption.c +glib/gregex.c +glib/gshell.c +glib/gspawn.c +glib/gspawn-win32.c +glib/gstrfuncs.c +glib/guri.c +glib/gutf8.c +glib/gutils.c +glib/guuid.c +gobject/gbinding.c diff --git a/po/POTFILES.skip b/po/POTFILES.skip new file mode 100644 index 0000000..6e12c7e --- /dev/null +++ b/po/POTFILES.skip @@ -0,0 +1,2 @@ +glib/tests/utils.c +tests/gio-ls.c diff --git a/po/af.po b/po/af.po new file mode 100644 index 0000000..846a2ab --- /dev/null +++ b/po/af.po @@ -0,0 +1,3818 @@ +# Afrikaans translation for glib. +# Copyright (C) 2010 glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the glib package. +# F Wolff , 2010, 2011. +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2011-03-30 18:52+0200\n" +"Last-Translator: F Wolff \n" +"Language-Team: translate-discuss-af@lists.sourceforge.net\n" +"Language: af\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: Virtaal 0.7.0-beta4\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Ongeldige gasheernaam" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "vm." + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "nm." + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%y-%m-%d" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +#, fuzzy +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%H:%M:%S" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Januarie" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Februarie" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Maart" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Mei" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Junie" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Julie" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "Augustus" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "Oktober" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "Desember" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mrt" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mei" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Des" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Maandag" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Dinsdag" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Woensdag" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Donderdag" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Vrydag" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Saterdag" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Sondag" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Ma." + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Di." + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Wo." + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Do." + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Vr." + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sa." + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "So." + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Fout met oopmaak van die gids '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Fout met lees van lêer '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Die lêer \"%s\" is te groot" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Kon nie lees vanaf lêer '%s' nie: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Kon nie lêer '%s' oopmaak nie: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Kon nie lêer '%s' skep nie: %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KG" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MG" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GG" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f TG" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f PG" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f EG" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KG" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MG" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GG" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TG" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PG" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EG" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KG" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Kon nie simboliese skakel '%s' lees nie: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Simboliese skakels word nie ondersteun nie" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "'%s' is nie 'n geldige naam nie " + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "'%s' is nie 'n geldige naam nie: '%c' " + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Fout op lyn %d: %s" + +#: ../glib/gmarkup.c:638 +#, fuzzy, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "Kon nie '%-.*s' ontleed nie. Dit moes 'n getal in 'n karakter" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Gebruik:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[KEUSE...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Hulpkeuses:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Wys hulpkeuses" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Wys alle hulpkeuses" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Toepassingkeuses:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Onbekende keuse %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Nie 'n gewone lêer nie" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Lêer is leeg" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ongeldige groepnaam: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Onbekende tipe" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s-lêertipe" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s-tipe" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Fout met oopmaak van lêer: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Fout met oopmaak van lêer '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Fout met lees van lêer '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Fout met lees van lêer '%s': %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Fout met skryf na lêer: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Fout met lees van lêer '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Onbekende tipe" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Fout met oopmaak van die gids '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Fout met skep van gids: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Fout met oopmaak van lêer '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Fout met lees van lêer '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Fout met lees van lêer '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Fout met toemaak van lêer: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Fout met oopmaak van lêer '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Fout met oopmaak van lêer '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, fuzzy, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "'%s' is nie 'n geldige naam nie " + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Fout met skryf na lêer: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Simboliese skakels word nie ondersteun nie" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Fout met skryf na lêer: %s" + +#: ../gio/gdbusserver.c:1042 +#, fuzzy, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' is nie 'n geldige naam nie " + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Fout op lyn %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Fout met skep van gids: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Fout met oopmaak van lêer: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, fuzzy, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "'%s' is nie 'n geldige naam nie " + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "'%s' is nie 'n geldige naam nie " + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "'%s' is nie 'n geldige naam nie " + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "'%s' is nie 'n geldige naam nie " + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Fout met oopmaak van die gids '%s': %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Fout met oopmaak van lêer: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Fout met oopmaak van die gids '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "Kan nie oor 'n gids kopieer nie" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "Kan nie 'n gids oor 'n gids kopieer nie" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "Teiken lêer bestaan" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "Kan nie gids rekursief kopieer nie" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2762 +#, c-format +msgid "Error splicing file: %s" +msgstr "" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "Kan nie spesiale lêer kopieer nie" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "Ongeldige waarde vir simboliese skakel gegee" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Lêernaam kan nie '%c' bevat nie" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "Geen toepassing is geregistreer om hierdie lêer te hanteer nie" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +msgid "empty names are not permitted" +msgstr "leë name word nie toegelaat nie" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Ongeldige lêernaam %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Fout met kry van lêerstelselinligting: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "Kan nie wortelgids hernoem nie" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Fout met hernoem van lêer: %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "Kan nie lêer hernoem nie - lêernaam bestaan reeds" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Ongeldige lêernaam" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Fout met oopmaak van lêer: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "Kan nie gids open nie" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Fout met skrap van lêer: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "Fout met skep van gids: %s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Lêerstelsel ondersteun nie simboliese skakels nie" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Fout met maak van simboliese skakel: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Fout met skuif van lêer: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "Kan nie 'n gids oor 'n gids skuif nie" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "Kon nie rugsteunlêer skep nie" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "Fout met skrap van teikenlêer: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (ongeldige enkodering)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +msgid "Cannot set permissions on symlinks" +msgstr "" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Fout met lees vanaf lêer: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Fout met toemaak van lêer: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Fout met skryf na lêer: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Fout met skep van rugsteunkopie: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Fout met hernoeming van tydelike lêer: %s " + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Fout met oopmaak van lêer '%s': %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "Teikenlêer is 'n gids" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "Teikenlêer is nie 'n gewone lêer nie" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "Die lêer is ekstern gewysig" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "Fout met skrap van ou lêer: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "" + +#: ../gio/gresolver.c:829 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, c-format +msgid "Error resolving '%s'" +msgstr "" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, c-format +msgid "Unable to create socket: %s" +msgstr "" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, c-format +msgid "Error binding to address: %s" +msgstr "" + +#: ../gio/gsocket.c:1566 +#, c-format +msgid "Error accepting connection: %s" +msgstr "" + +#: ../gio/gsocket.c:1683 +msgid "Error connecting: " +msgstr "" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, c-format +msgid "Error connecting: %s" +msgstr "" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "" + +#: ../gio/gsocket.c:1875 +#, c-format +msgid "Error receiving data: %s" +msgstr "" + +#: ../gio/gsocket.c:2050 +#, c-format +msgid "Error sending data: %s" +msgstr "" + +#: ../gio/gsocket.c:2163 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "" + +#: ../gio/gsocket.c:2242 +#, c-format +msgid "Error closing socket: %s" +msgstr "" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, c-format +msgid "Error sending message: %s" +msgstr "" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, c-format +msgid "Error receiving message: %s" +msgstr "" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Simboliese skakels word nie ondersteun nie" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Fout met oopmaak van lêer: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Fout met hernoem van lêer: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Fout met lees vanaf lêer: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Fout met toemaak van lêer: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Fout met skryf na lêer: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "Onvoldoende geheue" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "Interne fout: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "Benodig meer toevoer" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "Ongeldige saamgepersde data" + +msgctxt "full month name with day" +msgid "January" +msgstr "Januarie" + +msgctxt "full month name with day" +msgid "February" +msgstr "Februarie" + +msgctxt "full month name with day" +msgid "March" +msgstr "Maart" + +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +msgctxt "full month name with day" +msgid "May" +msgstr "Mei" + +msgctxt "full month name with day" +msgid "June" +msgstr "Junie" + +msgctxt "full month name with day" +msgid "July" +msgstr "Julie" + +msgctxt "full month name with day" +msgid "August" +msgstr "Augustus" + +msgctxt "full month name with day" +msgid "September" +msgstr "September" + +msgctxt "full month name with day" +msgid "October" +msgstr "Oktober" + +msgctxt "full month name with day" +msgid "November" +msgstr "November" + +msgctxt "full month name with day" +msgid "December" +msgstr "Desember" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mrt" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mei" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Aug" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Okt" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Des" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "vm." + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "nm." + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Kan nie 'n gids oor 'n gids skuif nie" diff --git a/po/am.po b/po/am.po new file mode 100644 index 0000000..23e0681 --- /dev/null +++ b/po/am.po @@ -0,0 +1,3731 @@ +# Translations into the Amharic Language. +# Copyright (C) 2002 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Ge'ez Frontier Foundation , 2002. +# +# +msgid "" +msgstr "" +"Project-Id-Version: glib VERSION\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2003-01-16 08:39+EDT\n" +"Last-Translator: Ge'ez Frontier Foundation \n" +"Language-Team: Amharic \n" +"Language: am\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s'ን ተቀብáˆáˆ" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "የእንáŒá‹³ ተቀባይ ስሠተቀብáˆáˆ" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "ጡዋት" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "ከሰዓት" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Aᣠ%B %e ቀን %Y %r %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%l:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%X %p" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "ጃንዩወሪ" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "áŒá‰¥áˆ©á‹ˆáˆª" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "ማርች" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "ኤá•ረáˆ" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "ሜይ" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "áŒáŠ•" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "áŒáˆ‹á‹­" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ጃንዩ" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "áŒá‰¥áˆ©" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "ማርች" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "ኤá•ረ" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "ሜይ " + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "áŒáŠ• " + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "áŒáˆ‹á‹­" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "ሰኞ" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "ማክሰኞ" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "ረቡዕ" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "áˆáˆ™áˆµ" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "ዓርብ" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "ቅዳሜ" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "እሑድ" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ሰኞ " + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ማክሰ" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ረቡዕ" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "áˆáˆ™áˆµ" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ዓርብ" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ቅዳሜ" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "እሑድ" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "የማይሰራ የUTF-8 ጽሑá" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:444 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "የእንáŒá‹³ ተቀባይ ስሠተቀብáˆáˆ" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "የእንáŒá‹³ ተቀባይ ስሠተቀብáˆáˆ" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "የእንáŒá‹³ ተቀባይ ስሠተቀብáˆáˆ" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +msgid "Abstract name space not supported" +msgstr "" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:646 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +msgid "empty names are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "የእንáŒá‹³ ተቀባይ ስሠተቀብáˆáˆ" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "የእንáŒá‹³ ተቀባይ ስሠተቀብáˆáˆ" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "የእንáŒá‹³ ተቀባይ ስሠተቀብáˆáˆ" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "የእንáŒá‹³ ተቀባይ ስሠተቀብáˆáˆ" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "የማይሰራ የUTF-8 ጽሑá" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "የማይሰራ የUTF-8 ጽሑá" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "á‹á‹­áˆ '%s'ን ለማንበብ ስህተት አለᦠ%s" + +#~ msgid "Socket error" +#~ msgstr "የሶከት ስህተት" diff --git a/po/an.po b/po/an.po new file mode 100644 index 0000000..5814852 --- /dev/null +++ b/po/an.po @@ -0,0 +1,4568 @@ +# Aragonese translation for glib. +# Copyright (C) 2013 glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the glib package. +# Jorge Pérez Pérez , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-04-27 19:45+0000\n" +"PO-Revision-Date: 2013-04-27 22:36+0100\n" +"Last-Translator: Jorge Pérez Pérez \n" +"Language-Team: Aragonese \n" +"Language: an\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.5.4\n" + +#: ../gio/gbufferedinputstream.c:427 ../gio/gbufferedinputstream.c:506 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:377 +#: ../gio/ginputstream.c:615 ../gio/ginputstream.c:833 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:732 +#: ../gio/gpollableinputstream.c:207 ../gio/gpollableoutputstream.c:208 +#, c-format +msgid "Too large count value passed to %s" +msgstr "A valor de conteyo pasada a %s ye masiau gran" + +#: ../gio/gbufferedinputstream.c:899 ../gio/gbufferedoutputstream.c:581 +#: ../gio/gdataoutputstream.c:568 +msgid "Seek not supported on base stream" +msgstr "No se permite mirar en o fluixo base" + +#: ../gio/gbufferedinputstream.c:945 +msgid "Cannot truncate GBufferedInputStream" +msgstr "No se puede truncar GBufferedInputStream" + +#: ../gio/gbufferedinputstream.c:990 ../gio/ginputstream.c:1023 +#: ../gio/giostream.c:291 ../gio/goutputstream.c:1334 +msgid "Stream is already closed" +msgstr "O fluixo ya s'ha zarrau" + +#: ../gio/gbufferedoutputstream.c:618 ../gio/gdataoutputstream.c:598 +msgid "Truncate not supported on base stream" +msgstr "No se suporta o truncau en o fluixo base" + +#: ../gio/gcancellable.c:318 ../gio/gdbusconnection.c:1885 +#: ../gio/gdbusconnection.c:1977 ../gio/gdbusprivate.c:1421 +#: ../gio/glocalfile.c:2172 ../gio/gsimpleasyncresult.c:843 +#: ../gio/gsimpleasyncresult.c:869 +#, c-format +msgid "Operation was cancelled" +msgstr "S'ha cancelau a operación" + +#: ../gio/gcharsetconverter.c:262 +msgid "Invalid object, not initialized" +msgstr "L'obchecto no ye valido, no s'ha inicializau" + +#: ../gio/gcharsetconverter.c:283 ../gio/gcharsetconverter.c:311 +msgid "Incomplete multibyte sequence in input" +msgstr "Seqüencia multibyte incompleta en a dentrada" + +#: ../gio/gcharsetconverter.c:317 ../gio/gcharsetconverter.c:326 +msgid "Not enough space in destination" +msgstr "No bi ha suficient espacio en o destín" + +#: ../gio/gcharsetconverter.c:344 ../gio/gdatainputstream.c:854 +#: ../gio/gdatainputstream.c:1264 ../glib/gconvert.c:764 +#: ../glib/gconvert.c:1156 ../glib/giochannel.c:1586 ../glib/giochannel.c:1628 +#: ../glib/giochannel.c:2472 ../glib/gutf8.c:833 ../glib/gutf8.c:1284 +msgid "Invalid byte sequence in conversion input" +msgstr "Bi ha una seqüencia de bytes no valida en a dentrada de conversión" + +#: ../gio/gcharsetconverter.c:349 ../glib/gconvert.c:772 +#: ../glib/gconvert.c:1081 ../glib/giochannel.c:1593 ../glib/giochannel.c:2484 +#, c-format +msgid "Error during conversion: %s" +msgstr "Ha fallau entre a conversión: %s" + +#: ../gio/gcharsetconverter.c:446 ../gio/gsocket.c:991 +msgid "Cancellable initialization not supported" +msgstr "A inicialización cancelable no eestá suportada" + +#: ../gio/gcharsetconverter.c:457 ../glib/gconvert.c:564 +#: ../glib/gconvert.c:642 ../glib/giochannel.c:1414 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" +"A conversión dende o conchunto de caracters «%s» ta «%s» no ye suportada" + +#: ../gio/gcharsetconverter.c:461 ../glib/gconvert.c:568 +#: ../glib/gconvert.c:646 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "No s'ha puesto ubrir o conversor de «%s» ta «%s»" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "mena %s" + +#: ../gio/gcontenttype-win32.c:162 +msgid "Unknown type" +msgstr "Mena desconoixida" + +#: ../gio/gcontenttype-win32.c:163 +#, c-format +msgid "%s filetype" +msgstr "Mena de fichero %s" + +#: ../gio/gcredentials.c:264 ../gio/gcredentials.c:528 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials no ye implementau en iste sistema operativo" + +#: ../gio/gcredentials.c:438 +msgid "There is no GCredentials support for your platform" +msgstr "No existe suporte de GCredentials ta la tuya plataforma" + +#: ../gio/gcredentials.c:480 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials no contién un IT de proceso en iste sistema operativo" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "Fin de fluxo inasperadament prematuro" + +#: ../gio/gdbusaddress.c:150 ../gio/gdbusaddress.c:238 +#: ../gio/gdbusaddress.c:319 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "Clau «%s» no suportada en a dentrada d'adreza «%s»" + +#: ../gio/gdbusaddress.c:177 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"L'adreza «%s» no ye valida (s'ameneste exactament una rota, dirtemp u claus " +"abstractas)" + +#: ../gio/gdbusaddress.c:190 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "Combinación d'o par clau/valor sin sentiu en a dentrada d'adreza «%s»" + +#: ../gio/gdbusaddress.c:253 ../gio/gdbusaddress.c:334 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" +"S'a produciu una error en l'adreza «%s»; l'atributo de puerto ye mal formau" + +#: ../gio/gdbusaddress.c:264 ../gio/gdbusaddress.c:345 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" +"S'ha produciu una error en l'adreza «%s»; l'atributo de familia ye mal formau" + +#: ../gio/gdbusaddress.c:454 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "L'elemento d'adreza «%s» no contién dos puntos (:)" + +#: ../gio/gdbusaddress.c:475 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" +"O par clau/valor %d, «%s», en l'elemento d'adreza «%s», no contién una " +"sinyal d'igual" + +#: ../gio/gdbusaddress.c:489 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"S'ha produciu una error a lo desescapar a clau u a valor en o par clau/valor " +"%d, «%s», en l'elemento d'adreza «%s»" + +#: ../gio/gdbusaddress.c:567 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"S'ha produciu una error en l'adreza «%s»: o transporte UNIX requier " +"exactament que una d'as claus «path» u «abstract» siga establida" + +#: ../gio/gdbusaddress.c:603 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" +"S'ha produciu una error en l'adreza «%s»: Manca u ye mal formau l'atributo " +"ta lo servidor" + +#: ../gio/gdbusaddress.c:617 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" +"S'ha produciu una error en l'adreza «%s»: Manca u ye mal formau l'atributo " +"ta lo puerto" + +#: ../gio/gdbusaddress.c:631 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" +"S'ha produciu una error en l'adreza «%s»: Manca u ye mal formau l'atributo " +"ta lo fichero de numero usau una sola vegada" + +#: ../gio/gdbusaddress.c:652 +msgid "Error auto-launching: " +msgstr "S'ha produciu una error a lo lanzar-ne automaticament: " + +#: ../gio/gdbusaddress.c:660 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "Transporte «%s» desconoixiu u no suportau ta l'adreza «%s»" + +#: ../gio/gdbusaddress.c:696 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "" +"S'ha produciu una error en ubrir o fichero de numero usau una sola vegada " +"«%s»: %s" + +#: ../gio/gdbusaddress.c:714 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "" +"S'ha produciu una error en leyer o fichero de numero usau una sola vegada " +"«%s»: %s" + +#: ../gio/gdbusaddress.c:723 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "" +"S'ha produciu una error en leyer o fichero de numero usau una sola vegada " +"«%s», s'asperaban 16 bytes, s'obtenioron %d" + +#: ../gio/gdbusaddress.c:741 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "" +"S'ha produciu una error en escribir o conteniu d'o fichero de numero usau " +"una sola vegada «%s» a lo fluxo:" + +#: ../gio/gdbusaddress.c:960 +msgid "The given address is empty" +msgstr "L'adreza proporcionada ye vueda" + +#: ../gio/gdbusaddress.c:1030 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "No se puet lanzar («spawn») un mensache a lo bus con setuid" + +#: ../gio/gdbusaddress.c:1037 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"No se puet lanzar («spawn») un mensache a lo bus sin un IT de maquina: " + +#: ../gio/gdbusaddress.c:1079 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "S'ha produciu una error en lanzar («spawn») o comando «%s»: " + +#: ../gio/gdbusaddress.c:1296 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Escribe un caracter qualsiquiera ta zarrar ista finestra)\n" + +#: ../gio/gdbusaddress.c:1421 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"A sesión de dbus no ye en execución, y ha fallau o lanzamiento automatico" + +#: ../gio/gdbusaddress.c:1442 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"No se puet determinar l'adreza d'o bus de sesión (no implementau ta iste " +"sistema operativo)" + +#: ../gio/gdbusaddress.c:1541 ../gio/gdbusconnection.c:6757 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"No se puet determinar l'adreza d'o bus dende a variable d'entorno " +"DBUS_STARTER_BUS_TYPE; variable «%s» desconoixida" + +#: ../gio/gdbusaddress.c:1550 ../gio/gdbusconnection.c:6766 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"No se puet determinar l'adreza d'o bus porque a variable d'entorno " +"DBUS_STARTER_BUS_TYPE no ye establida" + +#: ../gio/gdbusaddress.c:1560 +#, c-format +msgid "Unknown bus type %d" +msgstr "Mena de bus %d desconoixida" + +#: ../gio/gdbusauth.c:298 +msgid "Unexpected lack of content trying to read a line" +msgstr "Falta de conteniu inasperada en intentar leyer una linia" + +#: ../gio/gdbusauth.c:342 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Falta de conteniu inasperada en intentar leyer (de traza segura) una linia" + +#: ../gio/gdbusauth.c:513 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"S'han acotolau totz os mecanismos d'autenticación (intentaus: %s) " +"(disponibles: %s)" + +#: ../gio/gdbusauth.c:1175 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Cancelau a traviés de GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "S'ha produciu una error en obtener a información d'a carpeta «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Os permisos d'a carpeta «%s» son mal formaus. S'asperaba o modo 0700, " +"s'obtenió 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "S'ha produciu una error en creyar a carpeta «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "" +"S'ha produciu una error en ubrir l'aniello de claus «%s» ta la suya lectura: " + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:719 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"A linia %d de l'aniello de claus en «%s» con conteniu «%s» ye mal formada" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:733 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"O primer teste d'a linia %d de l'aniello de claus en «%s» con conteniu «%s» " +"ye mal formau" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:747 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"O segundo teste d'a linia %d d'o aniello de claus en «%s» con conteniu «%s» " +"ye mal formau" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "No s'ha trobau a cookie con IT %d en l'aniello de claus en «%s»" + +#: ../gio/gdbusauthmechanismsha1.c:537 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "" +"S'ha produciu una error en eliminar o fichero de bloqueyo antigo «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:569 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "S'ha produciu una error en creyar o fichero de bloqueyo «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:599 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "" +"S'ha produciu una error en zarrar (desenlazar) o fichero de bloqueyo «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "S'ha produciu una error a lo desenlazar o fichero de bloqueyo «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:686 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "" +"S'ha produciu una error en ubrir l'aniello de claus «%s» ta la suya " +"escritura:" + +#: ../gio/gdbusauthmechanismsha1.c:883 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(Amás, tamién ha fallau a liberación d'o bloqueyo ta «%s»: %s)" + +#: ../gio/gdbusconnection.c:597 ../gio/gdbusconnection.c:2440 +msgid "The connection is closed" +msgstr "A connexión ye zarrada" + +#: ../gio/gdbusconnection.c:1930 +msgid "Timeout was reached" +msgstr "S'ha acotolau o tiempo d'expiración" + +#: ../gio/gdbusconnection.c:2562 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"S'han trobau opcions no suportadas en construir a connexión d'o costau d'o " +"client" + +#: ../gio/gdbusconnection.c:4065 ../gio/gdbusconnection.c:4381 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"No existe a interficie «org.freedesktop.DBus.Properties» en l'obchecto en a " +"rota %s" + +#: ../gio/gdbusconnection.c:4136 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"S'ha produciu una error en establir a propiedat «%s»: S'asperaba a mena " +"«%s» pero se ha obteniu «%s»" + +#: ../gio/gdbusconnection.c:4231 +#, c-format +msgid "No such property '%s'" +msgstr "No existe a propiedat «%s»" + +#: ../gio/gdbusconnection.c:4243 +#, c-format +msgid "Property '%s' is not readable" +msgstr "No se puet leyer a clau «%s»" + +#: ../gio/gdbusconnection.c:4254 +#, c-format +msgid "Property '%s' is not writable" +msgstr "No se puet escribir a clau «%s»" + +#: ../gio/gdbusconnection.c:4324 ../gio/gdbusconnection.c:6200 +#, c-format +msgid "No such interface '%s'" +msgstr "A interficie «%s» no existe" + +#: ../gio/gdbusconnection.c:4508 +msgid "No such interface" +msgstr "No existe tal interficie" + +#: ../gio/gdbusconnection.c:4726 ../gio/gdbusconnection.c:6706 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "No existe a interficie «%s» en l'obchecto en a rota %s" + +#: ../gio/gdbusconnection.c:4781 +#, c-format +msgid "No such method '%s'" +msgstr "No existe o metodo «%s»" + +#: ../gio/gdbusconnection.c:4812 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "A mena de mensache, «%s», no coincide con a mena asperada «%s»" + +#: ../gio/gdbusconnection.c:5032 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Ya existe un obchecto exportau ta la interficie %s en %s" + +#: ../gio/gdbusconnection.c:5230 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "O metodo «%s» ha tornau a mena «%s» pero s'asperaba «%s»" + +#: ../gio/gdbusconnection.c:6311 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "O metodo «%s» con interficie «%s» y sinya «%s» no existe" + +#: ../gio/gdbusconnection.c:6430 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Ya s'ha exportau un subárbol ta %s" + +#: ../gio/gdbusmessage.c:1271 +msgid "type is INVALID" +msgstr "A mena no ye valida)" + +#: ../gio/gdbusmessage.c:1282 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Mensache de METHOD_CALL: falta o campo de capitero PATH u MEMBER" + +#: ../gio/gdbusmessage.c:1293 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Mensache de METHOD_RETURN: falta o campo de capitero REPLY_SERIAL" + +#: ../gio/gdbusmessage.c:1305 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Mensache d'ERROR: falta o campo de capitero REPLY_SERRIAL u ERROR_NAME" + +#: ../gio/gdbusmessage.c:1318 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Mensache de SIGNAL: falta o campo de capitero PATH, INTERFACE u MEMBER" + +#: ../gio/gdbusmessage.c:1326 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Mensache de SIGNAL: o campo de capitero PATH ye usando a valor reservada /" +"org/freedesktop/DBus/Local" + +#: ../gio/gdbusmessage.c:1334 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Mensache de SIGNAL: o campo de capitero INTERFACE ye usando a valor " +"reservada org.freedesktop.DBus.Local" + +#: ../gio/gdbusmessage.c:1383 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Se quereba leyer %lu byte pero solament s'ha obteniu %lu" +msgstr[1] "Se quereban leyer %lu bytes pero solament s'ha obteniu %lu" + +#: ../gio/gdbusmessage.c:1398 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" +"S'asperaba o byte NULL dimpués d'a cadena «%s» pero s'ha trobau o byte %d" + +#: ../gio/gdbusmessage.c:1417 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"S'asperaba una cadena valida en UTF-8 pero s'han trobau bytes no validos en " +"o byte desplazau %d (a longaria d'a cadena ye %d). A cadena UTF-8 valida " +"dica ixe punto yera «%s»." + +#: ../gio/gdbusmessage.c:1619 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "A valor analisada «%s» no ye un obchecto de rota D-Bus valido" + +#: ../gio/gdbusmessage.c:1643 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "A valor analisada «%s» no ye una sinyatura de D-Bus valida" + +#: ../gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"S'ha trobau un array de longaria %u byte. A longaria maxima ye 2<<26 bytes " +"(64 MiB)." +msgstr[1] "" +"S'ha trobau un array de longaria %u bytes. A longaria maxima ye 2<<26 bytes " +"(64 MiB)." + +#: ../gio/gdbusmessage.c:1851 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" +"A valor analisada «%s» ta la variant no ye una sinyatura de D-Bus valida" + +#: ../gio/gdbusmessage.c:1875 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"S'ha produciu una error a lo deserializar GVariant con a mena de cadena «%s» " +"ta lo formato de mensache de D-Bus" + +#: ../gio/gdbusmessage.c:2062 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"Valor endian no valido. S'asperaba 0x6c («l») u 0x42 («B»)» pero s'ha " +"obteniu a valor 0x%02x" + +#: ../gio/gdbusmessage.c:2075 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"A versión prencipal d'o protocolo no ye valida. S'asperaba 1 pero s'ha " +"trobau %d." + +#: ../gio/gdbusmessage.c:2131 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" +"S'ha trobau o capitero de sinyatura con sinyatura «%s» pero o cuerpo d'o " +"mensache ye vuedo" + +#: ../gio/gdbusmessage.c:2145 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" +"A valor analisada «%s» no ye una sinyatura de D-Bus valida (ta lo cuerpo)" + +#: ../gio/gdbusmessage.c:2175 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"No existe o capitero de sinyatura en o mensache pero o cuerpo d'o mensache " +"tien %u byte" +msgstr[1] "" +"No existe o capitero de sinyatura en o mensache pero o cuerpo d'o mensache " +"tien %u bytes" + +#: ../gio/gdbusmessage.c:2185 +msgid "Cannot deserialize message: " +msgstr "No se puet deserializar o mensache: " + +#: ../gio/gdbusmessage.c:2506 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"S'ha produciu una error a lo serializar GVariant con a mena de cadena «%s» " +"ta lo formato de mensache de D-Bus" + +#: ../gio/gdbusmessage.c:2643 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"O mensache tien %d descriptors de fichero pero o campo de capitero indica %d " +"descriptors de fichero" + +#: ../gio/gdbusmessage.c:2651 +msgid "Cannot serialize message: " +msgstr "No se puet serializar o mensache: " + +#: ../gio/gdbusmessage.c:2695 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" +"O cuerpo d'o mensache tien la sinya «%s» pero no existe o capitero de " +"sinyatura" + +#: ../gio/gdbusmessage.c:2705 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" +"O cuerpo d'o mensache tien un tipo de sinyatura «%s» pero a sinyatura en o " +"campo de capitero ye «%s»" + +#: ../gio/gdbusmessage.c:2721 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" +"O cuerpo d'o mensache ye vuedo pero a sinyatura en o campo de capitero ye " +"«(%s)»" + +#: ../gio/gdbusmessage.c:3271 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "S'ha produciu una error a lo tornar o cuerpo de mena «%s»" + +#: ../gio/gdbusmessage.c:3279 +msgid "Error return with empty body" +msgstr "S'ha produciu una error a lo tornar un cuerpo vuedo" + +#: ../gio/gdbusprivate.c:2069 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "No s'ha puesto obtener o perfil d'hardware: %s" + +#: ../gio/gdbusprivate.c:2114 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "No se puet cargar /var/lib/dbus/machine-it u /etc./machine-it: " + +#: ../gio/gdbusproxy.c:1640 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "S'ha produciu una error en clamar StartSereviceByName ta %s: " + +#: ../gio/gdbusproxy.c:1663 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Respuesta %d no asperada d'o metodo StartServiceByName(«%s»)" + +#: ../gio/gdbusproxy.c:2763 ../gio/gdbusproxy.c:2900 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"No se puet invocar a lo metodo; o proxy no tien duenyo ta un nombre conoixiu " +"y o proxy se construyó con a opción G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: ../gio/gdbusserver.c:709 +msgid "Abstract name space not supported" +msgstr "No se suporta o espacio de nombres abstracto" + +#: ../gio/gdbusserver.c:796 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"No se puet especificar o fichero de numero usau una sola vegada en creyar un " +"servidor" + +#: ../gio/gdbusserver.c:874 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "" +"S'ha produciu una error en escribir o fichero de numero usau una sola vegada " +"en «%s»: %s" + +#: ../gio/gdbusserver.c:1043 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "A cadena «%s» no ye un GUID valido de D-Bus" + +#: ../gio/gdbusserver.c:1083 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "No se puet escuitar en un transporte no suportau «%s»" + +#: ../gio/gdbus-tool.c:92 +msgid "COMMAND" +msgstr "COMANDO" + +#: ../gio/gdbus-tool.c:97 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"Comandos:\n" +" help Amostrar ista información\n" +" introspect Introspeccionar un obchecto remoto\n" +" monitor Monitorizar un obchecto remoto\n" +" call Invocar un metodo sobre un obchecto remoto\n" +" emit Emitir un sinyal\n" +"\n" +"Usa «%s COMANDO --help» ta obtener aduya d'os comandos individuals.\n" + +#: ../gio/gdbus-tool.c:166 ../gio/gdbus-tool.c:222 ../gio/gdbus-tool.c:294 +#: ../gio/gdbus-tool.c:318 ../gio/gdbus-tool.c:701 ../gio/gdbus-tool.c:1020 +#: ../gio/gdbus-tool.c:1453 +#, c-format +msgid "Error: %s\n" +msgstr "Error: %s\n" + +#: ../gio/gdbus-tool.c:177 ../gio/gdbus-tool.c:235 ../gio/gdbus-tool.c:1469 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "S'ha produciu una error en analisar a introspección XML: %s\n" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to the system bus" +msgstr "Connectar con o bus d'o sistema" + +#: ../gio/gdbus-tool.c:353 +msgid "Connect to the session bus" +msgstr "Connectar con o bus de sesión" + +#: ../gio/gdbus-tool.c:354 +msgid "Connect to given D-Bus address" +msgstr "Connectar con l'adreza de D-Bus proporcionada" + +#: ../gio/gdbus-tool.c:364 +msgid "Connection Endpoint Options:" +msgstr "Opcions de connexión d'o cabo:" + +#: ../gio/gdbus-tool.c:365 +msgid "Options specifying the connection endpoint" +msgstr "Opcions ta especificar a connexión d'o cabo:" + +#: ../gio/gdbus-tool.c:387 +#, c-format +msgid "No connection endpoint specified" +msgstr "No s'ha especificau garra punto de connexión extremo" + +#: ../gio/gdbus-tool.c:397 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "S'han especificau quantos puntos de connexión extremos" + +#: ../gio/gdbus-tool.c:467 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" +"Alvertencia: seguntes a introspección d'os datos, a interficie «%s» no " +"existe\n" + +#: ../gio/gdbus-tool.c:476 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"Alvertencia: seguntes a introspección d'os datos, o metodo «%s» no existe en " +"a interficie «%s»\n" + +#: ../gio/gdbus-tool.c:538 +msgid "Optional destination for signal (unique name)" +msgstr "Destín opcional ta lo sinyal (nombre solo)" + +#: ../gio/gdbus-tool.c:539 +msgid "Object path to emit signal on" +msgstr "Rota de l'obchecto sobre o qual emitir o sinyal" + +#: ../gio/gdbus-tool.c:540 +msgid "Signal and interface name" +msgstr "Nombres d'a interficie y sinyal" + +#: ../gio/gdbus-tool.c:572 +msgid "Emit a signal." +msgstr "Emitir un sinyal." + +#: ../gio/gdbus-tool.c:606 ../gio/gdbus-tool.c:832 ../gio/gdbus-tool.c:1559 +#: ../gio/gdbus-tool.c:1791 +#, c-format +msgid "Error connecting: %s\n" +msgstr "S'ha produciu una error en connectar: %s\n" + +#: ../gio/gdbus-tool.c:618 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "S'ha produciu una error: no s'ha especificau a rota de l'obchecto.\n" + +#: ../gio/gdbus-tool.c:623 ../gio/gdbus-tool.c:893 ../gio/gdbus-tool.c:1617 +#: ../gio/gdbus-tool.c:1850 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "S'ha produciu una error: %s no ye una rota d'obchecto valida\n" + +#: ../gio/gdbus-tool.c:629 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "S'ha produciu una error: no s'ha especificau o sinyal.\n" + +#: ../gio/gdbus-tool.c:636 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "" +"S'ha produciu una error: o sinyal debe estar o nombre completament " +"qualificau.\n" + +#: ../gio/gdbus-tool.c:644 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "S'ha produciu una error: %s no ye un nombre d'interficie valida\n" + +#: ../gio/gdbus-tool.c:650 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "S'ha produciu una error: %s no ye un nombre de miembro valido\n" + +#: ../gio/gdbus-tool.c:656 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "S'ha produciu una error: %s no ye un nombre de bus solo valido.\n" + +#: ../gio/gdbus-tool.c:679 ../gio/gdbus-tool.c:992 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "S'ha produciu una error en analisar o parametro %d: %s\n" + +#: ../gio/gdbus-tool.c:708 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "S'ha produciu una error en limpiar a connexión: %s\n" + +#: ../gio/gdbus-tool.c:735 +msgid "Destination name to invoke method on" +msgstr "Nombre d'o destín sobre o qual invocar o metodo" + +#: ../gio/gdbus-tool.c:736 +msgid "Object path to invoke method on" +msgstr "Rota de l'obchecto sobre a quala invocar o metodo" + +#: ../gio/gdbus-tool.c:737 +msgid "Method and interface name" +msgstr "Nombre d'a interficie y metodo" + +#: ../gio/gdbus-tool.c:738 +msgid "Timeout in seconds" +msgstr "Tiempo d'expiración en segundos" + +#: ../gio/gdbus-tool.c:777 +msgid "Invoke a method on a remote object." +msgstr "Invocar un metodo en un obchecto remoto." + +#: ../gio/gdbus-tool.c:852 ../gio/gdbus-tool.c:1578 ../gio/gdbus-tool.c:1810 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "S'ha produciu una error: o destín no ye especificau\n" + +#: ../gio/gdbus-tool.c:873 ../gio/gdbus-tool.c:1597 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "S'ha produciu una error: no s'ha especificau a rota de l'obchecto\n" + +#: ../gio/gdbus-tool.c:908 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "S'ha produciu una error: no s'ha especificau o nombre d'o metodo\n" + +#: ../gio/gdbus-tool.c:919 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "S'ha produciu una error: o nombre d'o metodo «%s» no ye valido\n" + +#: ../gio/gdbus-tool.c:984 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "S'ha produciu una error en analisar o parametro %d d'a mena «%s»: %s\n" + +#: ../gio/gdbus-tool.c:1416 +msgid "Destination name to introspect" +msgstr "Nombre de destín que introspeccionar" + +#: ../gio/gdbus-tool.c:1417 +msgid "Object path to introspect" +msgstr "Rota de l'obchecto que introspeccionar" + +#: ../gio/gdbus-tool.c:1418 +msgid "Print XML" +msgstr "Imprentar o XML" + +#: ../gio/gdbus-tool.c:1419 +msgid "Introspect children" +msgstr "Introspeccionar o fillo" + +#: ../gio/gdbus-tool.c:1420 +msgid "Only print properties" +msgstr "Nomás amostrar as propiedatz" + +#: ../gio/gdbus-tool.c:1511 +msgid "Introspect a remote object." +msgstr "Introspeccionar un obchecto remoto." + +#: ../gio/gdbus-tool.c:1709 +msgid "Destination name to monitor" +msgstr "Nombre de destín ta monitorizar" + +#: ../gio/gdbus-tool.c:1710 +msgid "Object path to monitor" +msgstr "Rota de l'obchecto ta monitorizar" + +#: ../gio/gdbus-tool.c:1743 +msgid "Monitor a remote object." +msgstr "Monitorizar un obchecto remoto." + +#: ../gio/gdesktopappinfo.c:625 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Sin nombre" + +#: ../gio/gdesktopappinfo.c:1038 +msgid "Desktop file didn't specify Exec field" +msgstr "O fichero d'escritorio no ha especificau o campo Exec" + +#: ../gio/gdesktopappinfo.c:1326 +msgid "Unable to find terminal required for application" +msgstr "Ye estau imposible trobar o terminal requeriu por l'aplicación" + +#: ../gio/gdesktopappinfo.c:1628 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" +"No se puet creyar a carpeta de configuración de l'aplicación %s de " +"l'usuario: %s" + +#: ../gio/gdesktopappinfo.c:1632 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "No se puet creyar a carpeta de configuración MIME %s de l'usuario: %s" + +#: ../gio/gdesktopappinfo.c:1872 ../gio/gdesktopappinfo.c:1896 +msgid "Application information lacks an identifier" +msgstr "A información de l'aplicación careix d'un identificador" + +#: ../gio/gdesktopappinfo.c:2128 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "No se puet creyar o fichero d'escritorio %s de l'usuario" + +#: ../gio/gdesktopappinfo.c:2252 +#, c-format +msgid "Custom definition for %s" +msgstr "Definición presonalizada ta %s" + +#: ../gio/gdrive.c:394 +msgid "drive doesn't implement eject" +msgstr "a unidat no implementa a expulsión" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:472 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "a unidat no implementa a expulsión u expulsión con operación" + +#: ../gio/gdrive.c:548 +msgid "drive doesn't implement polling for media" +msgstr "a unidat no implementa o sondeyo ta meyos" + +#: ../gio/gdrive.c:753 +msgid "drive doesn't implement start" +msgstr "a unidat no implementa reproducir" + +#: ../gio/gdrive.c:855 +msgid "drive doesn't implement stop" +msgstr "a unidat no implementa aturar" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "O suporte de TSL no ye disponible" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "No se puet maniar a versión %d d'a codificación GEmblem" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Numero de testes (%d) mal formaus en a codificación GEmblem" + +#: ../gio/gemblemedicon.c:367 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "No se puet maniar a versión %d d'a codificación GEmblemedIcon" + +#: ../gio/gemblemedicon.c:377 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Numero de testes (%d) mal formaus en a codificación GEmblemedIcon" + +#: ../gio/gemblemedicon.c:400 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "S'asperaba un GEmblem ta GEmblemedIconjo" + +#: ../gio/gfile.c:917 ../gio/gfile.c:1156 ../gio/gfile.c:1295 +#: ../gio/gfile.c:1535 ../gio/gfile.c:1590 ../gio/gfile.c:1648 +#: ../gio/gfile.c:1732 ../gio/gfile.c:1789 ../gio/gfile.c:1853 +#: ../gio/gfile.c:1908 ../gio/gfile.c:3469 ../gio/gfile.c:3524 +#: ../gio/gfile.c:3670 ../gio/gfile.c:3712 ../gio/gfile.c:4114 +#: ../gio/gfile.c:4526 ../gio/gfile.c:4611 ../gio/gfile.c:4701 +#: ../gio/gfile.c:4798 ../gio/gfile.c:4885 ../gio/gfile.c:4986 +#: ../gio/gfile.c:5259 ../gio/gfile.c:5537 ../gio/gfile.c:5591 +#: ../gio/gfile.c:7136 ../gio/gfile.c:7226 ../gio/gfile.c:7310 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Operación no suportada" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1419 ../gio/glocalfile.c:1096 ../gio/glocalfile.c:1107 +#: ../gio/glocalfile.c:1120 +msgid "Containing mount does not exist" +msgstr "O punto de montache conteniu no existe" + +#: ../gio/gfile.c:2474 ../gio/glocalfile.c:2328 +msgid "Can't copy over directory" +msgstr "No se puet copiar sobre a carpeta" + +#: ../gio/gfile.c:2534 +msgid "Can't copy directory over directory" +msgstr "No se puet copiar una carpeta sobre unatra" + +#: ../gio/gfile.c:2542 ../gio/glocalfile.c:2337 +msgid "Target file exists" +msgstr "O fichero de destín ya existe" + +#: ../gio/gfile.c:2561 +msgid "Can't recursively copy directory" +msgstr "No se puet copiar a carpeta recursivament" + +#: ../gio/gfile.c:2825 +msgid "Splice not supported" +msgstr "A unión no ye suportada" + +#: ../gio/gfile.c:2829 +#, c-format +msgid "Error splicing file: %s" +msgstr "S'ha produciu una error en unir o fichero: %s" + +#: ../gio/gfile.c:2960 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Copiar (reflink/clone) entre puntos de montache no ye suportau" + +#: ../gio/gfile.c:2964 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Copiar (reflink/clone) no ye suportau u no ye valido" + +#: ../gio/gfile.c:2969 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "Copiar (reflink/clone) no ye suportau u no ha funcionau" + +#: ../gio/gfile.c:3029 +msgid "Can't copy special file" +msgstr "No se puet copiar o fichero especial" + +#: ../gio/gfile.c:3660 +msgid "Invalid symlink value given" +msgstr "A valor d'o vinclo simbolico dau no ye valido" + +#: ../gio/gfile.c:3820 +msgid "Trash not supported" +msgstr "No se suporta mover a la papelera" + +#: ../gio/gfile.c:3871 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Os nombres de fichero no pueden contener «%c»" + +#: ../gio/gfile.c:6259 ../gio/gvolume.c:365 +msgid "volume doesn't implement mount" +msgstr "o volumen no implementa l'amontau" + +#: ../gio/gfile.c:6368 +msgid "No application is registered as handling this file" +msgstr "No bi ha garra aplicación rechistrada ta maniar iste fichero" + +#: ../gio/gfileenumerator.c:204 +msgid "Enumerator is closed" +msgstr "O enumerador ye zarrau" + +#: ../gio/gfileenumerator.c:211 ../gio/gfileenumerator.c:270 +#: ../gio/gfileenumerator.c:367 ../gio/gfileenumerator.c:467 +msgid "File enumerator has outstanding operation" +msgstr "O enumerador d'o fichero tien una operación excepcional" + +#: ../gio/gfileenumerator.c:358 ../gio/gfileenumerator.c:458 +msgid "File enumerator is already closed" +msgstr "O enumerador d'o fichero ya ye zarrau" + +#: ../gio/gfileicon.c:237 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "No se puet maniar a versión %d d'a codificación GFileIcon" + +#: ../gio/gfileicon.c:247 +msgid "Malformed input data for GFileIcon" +msgstr "Datos de dentrada mal formaus ta GFileIcon" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:400 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:503 +msgid "Stream doesn't support query_info" +msgstr "O fluxo no suporta query_*info" + +#: ../gio/gfileinputstream.c:331 ../gio/gfileiostream.c:383 +#: ../gio/gfileoutputstream.c:377 +msgid "Seek not supported on stream" +msgstr "No se permite buscar en o fluxo" + +#: ../gio/gfileinputstream.c:375 +msgid "Truncate not allowed on input stream" +msgstr "No se permite truncar en o fluxo de dentrada" + +#: ../gio/gfileiostream.c:459 ../gio/gfileoutputstream.c:453 +msgid "Truncate not supported on stream" +msgstr "No se suporta o truncamiento en o fluxo" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Numero de testes (%d) incorrecto" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "No existe a mena ta la clase de nombre %s" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "A mena %s no implementa a interficie GIcon" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "A mena %s no tien clase" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "Numero de versión mal formau: %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "A mena %s no implementa from_tokens() en a interficie GIcon" + +#: ../gio/gicon.c:428 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "No se puet maniar a versión proporcionada d'a codificación d'icono" + +#: ../gio/ginetaddressmask.c:184 +msgid "No address specified" +msgstr "No s'especificó garra adreza" + +#: ../gio/ginetaddressmask.c:192 +#, c-format +msgid "Length %u is too long for address" +msgstr "A longaria de %u ye masiau larga ta una adreza" + +#: ../gio/ginetaddressmask.c:225 +msgid "Address has bits set beyond prefix length" +msgstr "L'adreza tien bits dillá d'a longaria d'o prefixo" + +#: ../gio/ginetaddressmask.c:304 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "No s'ha puesto analisar «%s» como una mascareta d'una adreza IP" + +#: ../gio/ginetsocketaddress.c:206 ../gio/ginetsocketaddress.c:223 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "No bi ha suficient espacio ta l'adreza d'o socket" + +#: ../gio/ginetsocketaddress.c:238 +msgid "Unsupported socket address" +msgstr "Adreza d'o socket no suportada" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "O fluxo de dentrada no implementa a lectura" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1033 ../gio/giostream.c:301 +#: ../gio/goutputstream.c:1344 +msgid "Stream has outstanding operation" +msgstr "O fluxo tien una operación excepcional" + +#: ../gio/glib-compile-resources.c:145 ../gio/glib-compile-schemas.c:1459 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "No se permite l'elemento <%s> adentro de <%s>" + +#: ../gio/glib-compile-resources.c:149 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "No se permite l'elemento <%s> en o ran superior" + +#: ../gio/glib-compile-resources.c:239 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "O fichero %s amaneixe quantas vegadas en o recurso" + +#: ../gio/glib-compile-resources.c:252 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "Ha fallau en buscar «%s» en qualsiquier carpeta fuent" + +#: ../gio/glib-compile-resources.c:263 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "Ha fallau en buscar «%s» en a carpeta actual" + +#: ../gio/glib-compile-resources.c:291 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "Opción de procesau desconoixida «%s»" + +#: ../gio/glib-compile-resources.c:310 ../gio/glib-compile-resources.c:370 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "Ha fallau en creyar o fichero temporal: %s" + +#: ../gio/glib-compile-resources.c:340 +#, c-format +msgid "" +"Error processing input file with xmllint:\n" +"%s" +msgstr "" +"S'ha produciu una error en procesar o fichero de dentrada con xmllint:\n" +"%s" + +#: ../gio/glib-compile-resources.c:396 +#, c-format +msgid "" +"Error processing input file with to-pixdata:\n" +"%s" +msgstr "" +"S'ha produciu una error en procesar o fichero de dentrada con to-pixdata:\n" +"%s" + +#: ../gio/glib-compile-resources.c:410 +#, c-format +msgid "Error reading file %s: %s" +msgstr "S'ha produciu una error en leyer o fichero %s: %s" + +#: ../gio/glib-compile-resources.c:430 +#, c-format +msgid "Error compressing file %s" +msgstr "S'ha produciu una error en comprimir o fichero %s" + +#: ../gio/glib-compile-resources.c:494 ../gio/glib-compile-schemas.c:1571 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "O texto no debe amaneixer dentro de <%s>" + +#: ../gio/glib-compile-resources.c:619 +msgid "name of the output file" +msgstr "nombre d'o fichero de salida" + +#: ../gio/glib-compile-resources.c:619 ../gio/glib-compile-resources.c:650 +#: ../gio/gresource-tool.c:482 ../gio/gresource-tool.c:548 +msgid "FILE" +msgstr "FICHERO" + +#: ../gio/glib-compile-resources.c:620 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"A carpeta d'a quala s'han de leyer os fichers (a predeterminada ye a carpeta " +"actual)" + +#: ../gio/glib-compile-resources.c:620 ../gio/glib-compile-schemas.c:1999 +#: ../gio/glib-compile-schemas.c:2028 +msgid "DIRECTORY" +msgstr "CARPETA" + +#: ../gio/glib-compile-resources.c:621 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Chenerar a salida en o formato seleccionau por a extensión d'o nombre d'o " +"fichero objetivo" + +#: ../gio/glib-compile-resources.c:622 +msgid "Generate source header" +msgstr "Chenerar o capitero fuent" + +#: ../gio/glib-compile-resources.c:623 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" +"Chenerar o codigo fuent usau ta enlazar o fichero d'o recurso en o suyo " +"codigo fuent" + +#: ../gio/glib-compile-resources.c:624 +msgid "Generate dependency list" +msgstr "Chenerar a lista de dependencias" + +#: ../gio/glib-compile-resources.c:625 +msgid "Don't automatically create and register resource" +msgstr "No creyar y rechistrar automaticament un recurso" + +#: ../gio/glib-compile-resources.c:626 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "No exportar funcions; declarar-las como G_GNUC_INTERNAL" + +#: ../gio/glib-compile-resources.c:627 +msgid "C identifier name used for the generated source code" +msgstr "Nombre de l'identificador C usau ta o codigo fuent chenerau" + +#: ../gio/glib-compile-resources.c:653 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compilar a especificación d'un recurso en un fichero de recurso.\n" +"Os fichers d'especificación de recursos han de tener a extensión .gresource." +"xml,\n" +"y o fichero d'o recurso debe tener a extensión se diz .gresource." + +#: ../gio/glib-compile-resources.c:669 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "Habrás de proporcionar exactament un nombre de fichero\n" + +#: ../gio/glib-compile-schemas.c:778 +msgid "empty names are not permitted" +msgstr "no se permiten nombres vuedos" + +#: ../gio/glib-compile-schemas.c:788 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" +"nombre «%s» no valido: os nombres han de prencipiar por una letra minuscla" + +#: ../gio/glib-compile-schemas.c:800 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"nombre «%s» no valido: o caracter «%c» no ye valido; solament se permiten " +"nombres en minuscla, numeros y guión («-»)." + +#: ../gio/glib-compile-schemas.c:809 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "nombre «%s» no valido: no se permiten dos guións seguius («--»)." + +#: ../gio/glib-compile-schemas.c:818 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "nombre «%s» no valido: o zaguer caracter no puet estar un guión («-»)." + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "nombre «%s» no valido: a longaria maxima ye 1024" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr " ya especificau" + +#: ../gio/glib-compile-schemas.c:921 +msgid "cannot add keys to a 'list-of' schema" +msgstr "no se pueden adhibir claus a un esquema de «lista-de»" + +#: ../gio/glib-compile-schemas.c:932 +#, c-format +msgid " already specified" +msgstr " ya especificada" + +#: ../gio/glib-compile-schemas.c:950 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" eclipsa a en ; usa " +" ta modificar a valor" + +#: ../gio/glib-compile-schemas.c:961 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"Cal especificar exactament un de «type», «enum» u «flags» como atributo ta " +"" + +#: ../gio/glib-compile-schemas.c:980 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s it='%s'> encara no especificau." + +#: ../gio/glib-compile-schemas.c:995 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "Mena de cadena GVarian «%s» no valida" + +#: ../gio/glib-compile-schemas.c:1025 +msgid " given but schema isn't extending anything" +msgstr "S'ha proporcionau pero o esquema no ye extendendo cosa" + +#: ../gio/glib-compile-schemas.c:1038 +#, c-format +msgid "no to override" +msgstr "no existe ta sobrescribir" + +#: ../gio/glib-compile-schemas.c:1046 +#, c-format +msgid " already specified" +msgstr " ya especificada" + +#: ../gio/glib-compile-schemas.c:1117 +#, c-format +msgid " already specified" +msgstr " ya especificau" + +#: ../gio/glib-compile-schemas.c:1129 +#, c-format +msgid " extends not-yet-existing schema '%s'" +msgstr " extiende o esquema «%s» que encara no existe" + +#: ../gio/glib-compile-schemas.c:1145 +#, c-format +msgid " is list of not-yet-existing schema '%s'" +msgstr " ye una lista d'o esquema «%s» que encara no existe" + +#: ../gio/glib-compile-schemas.c:1153 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "No puet estar una lista d'un esquema con una rota" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "No se puet extender un esquema con una rota" + +#: ../gio/glib-compile-schemas.c:1173 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ye una lista, extendendo que no ye una " +"lista" + +#: ../gio/glib-compile-schemas.c:1183 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" extiende pero " +"«%s» no extiende «%s»" + +#: ../gio/glib-compile-schemas.c:1200 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "si s'especifica una rota, debe prencipiar y rematar con una barra" + +#: ../gio/glib-compile-schemas.c:1207 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "a rota d'a lista debe rematar con «:/»" + +#: ../gio/glib-compile-schemas.c:1239 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s it='%s'> ya especificau" + +#: ../gio/glib-compile-schemas.c:1463 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "No se permite l'elemento <%s> en o libel superior" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1757 ../gio/glib-compile-schemas.c:1828 +#: ../gio/glib-compile-schemas.c:1904 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "s'ha especificau --strict; salindo.\n" + +#: ../gio/glib-compile-schemas.c:1765 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "S'ha ignorau iste fichero completament.\n" + +#: ../gio/glib-compile-schemas.c:1824 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Se ye ignorando iste fichero.\n" + +#: ../gio/glib-compile-schemas.c:1864 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"No existe a clau «%s» en o esquema «%s» como s'especificó en o fichero de " +"sobrescritura «%s»" + +#: ../gio/glib-compile-schemas.c:1870 ../gio/glib-compile-schemas.c:1928 +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; Se ye ignorando a sobrescritura ta ista clau.\n" + +#: ../gio/glib-compile-schemas.c:1874 ../gio/glib-compile-schemas.c:1932 +#: ../gio/glib-compile-schemas.c:1960 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "y s'ha especificau --strict; salindo.\n" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"S'ha produciu una error en analisar a clau «%s» en o esquema «%s» como s'ha " +"especificau en o fichero de sobrescritura «%s»: %s." + +#: ../gio/glib-compile-schemas.c:1900 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "Se ye ignorando a sobrescritura ta ista clau.\n" + +#: ../gio/glib-compile-schemas.c:1918 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"a clau de sobrescritura «%s» en o esquema «%s» en o fichero de sobrescritura " +"«%s» ye difuera d'o rango proporcionau en o esquema" + +#: ../gio/glib-compile-schemas.c:1946 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"a clau de sobrescritura «%s» en o esquema «%s» en o fichero de sobrescritura " +"«%s» no ye en a lista d'opcions validas" + +#: ../gio/glib-compile-schemas.c:1999 +msgid "where to store the gschemas.compiled file" +msgstr "Do almagazenar o fichero gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2000 +msgid "Abort on any errors in schemas" +msgstr "Abortar debant de qualsiquier error en os esquemas" + +#: ../gio/glib-compile-schemas.c:2001 +msgid "Do not write the gschema.compiled file" +msgstr "No escribir o fichero gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2002 +msgid "Do not enforce key name restrictions" +msgstr "No forzar as restriccions de nombre d'as claus" + +#: ../gio/glib-compile-schemas.c:2031 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compilar totz os fichers d'esquema de GSettings en una caché de esquemas.\n" +"Os fichers d'esquema han de tener a extensión .gschema.xml,\n" +"y o fichero de caché se diz gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:2047 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "Habrás de proporcionar exactament un nombre de carpeta\n" + +#: ../gio/glib-compile-schemas.c:2086 +#, c-format +msgid "No schema files found: " +msgstr "No s'ha trobau garra fichero d'esquemas: " + +#: ../gio/glib-compile-schemas.c:2089 +#, c-format +msgid "doing nothing.\n" +msgstr "sin fer cosa.\n" + +#: ../gio/glib-compile-schemas.c:2092 +#, c-format +msgid "removed existing output file.\n" +msgstr "s'ha sacau o fichero de salida existent.\n" + +#: ../gio/glocaldirectorymonitor.c:252 +msgid "Unable to find default local directory monitor type" +msgstr "" +"No s'ha puesto trobar a mena de monitorización d'a carpeta local " +"predeterminada" + +#: ../gio/glocalfile.c:597 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Nombre de fichero no valido %s" + +#: ../gio/glocalfile.c:974 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "" +"S'ha produciu una error en obtener a información d'o sistema de fichers: %s" + +#: ../gio/glocalfile.c:1142 +msgid "Can't rename root directory" +msgstr "No se puet renombrar a carpeta radiz" + +#: ../gio/glocalfile.c:1162 ../gio/glocalfile.c:1188 +#, c-format +msgid "Error renaming file: %s" +msgstr "S'ha produciu una error en renombrar o fichero: %s" + +#: ../gio/glocalfile.c:1171 +msgid "Can't rename file, filename already exists" +msgstr "No se puet renombrar o fichero, o nombre de fichero ya existe" + +#: ../gio/glocalfile.c:1184 ../gio/glocalfile.c:2201 ../gio/glocalfile.c:2230 +#: ../gio/glocalfile.c:2390 ../gio/glocalfileoutputstream.c:575 +#: ../gio/glocalfileoutputstream.c:628 ../gio/glocalfileoutputstream.c:673 +#: ../gio/glocalfileoutputstream.c:1161 +msgid "Invalid filename" +msgstr "Nombre de fichero no valido" + +#: ../gio/glocalfile.c:1351 ../gio/glocalfile.c:1375 +msgid "Can't open directory" +msgstr "No se puet ubrir a carpeta" + +#: ../gio/glocalfile.c:1359 +#, c-format +msgid "Error opening file: %s" +msgstr "S'ha produciu una error en ubrir o fichero: %s" + +#: ../gio/glocalfile.c:1500 +#, c-format +msgid "Error removing file: %s" +msgstr "S'ha produciu una error en eliminar o fichero: %s" + +#: ../gio/glocalfile.c:1880 +#, c-format +msgid "Error trashing file: %s" +msgstr "S'ha produciu una error en mover ta la papelera lo fichero: %s" + +#: ../gio/glocalfile.c:1903 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "No s'ha puesto creyar a carpeta de papelera %s: %s" + +#: ../gio/glocalfile.c:1924 +msgid "Unable to find toplevel directory for trash" +msgstr "No s'ha puesto trobar a carpeta de libel superior ta la papelera" + +#: ../gio/glocalfile.c:2003 ../gio/glocalfile.c:2023 +msgid "Unable to find or create trash directory" +msgstr "No s'ha puesto trobar u creyar a carpeta d'a papelera" + +#: ../gio/glocalfile.c:2057 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "No s'ha puesto creyar a información de papelera ta lo fichero: %s" + +#: ../gio/glocalfile.c:2086 ../gio/glocalfile.c:2091 ../gio/glocalfile.c:2171 +#: ../gio/glocalfile.c:2178 +#, c-format +msgid "Unable to trash file: %s" +msgstr "No s'ha puesto ninviar a la papelera lo fichero: %s" + +#: ../gio/glocalfile.c:2179 ../glib/gregex.c:280 +msgid "internal error" +msgstr "S'ha produciu una error interna" + +#: ../gio/glocalfile.c:2205 +#, c-format +msgid "Error creating directory: %s" +msgstr "S'ha produciu una error en creyar a carpeta: %s" + +#: ../gio/glocalfile.c:2234 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "O sistema de fichers no suporta vinclos simbolicos" + +#: ../gio/glocalfile.c:2238 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "S'ha produciu una error en creyar o vinclo simbolico: %s" + +#: ../gio/glocalfile.c:2300 ../gio/glocalfile.c:2394 +#, c-format +msgid "Error moving file: %s" +msgstr "S'ha produciu una error en mover o fichero: %s" + +#: ../gio/glocalfile.c:2323 +msgid "Can't move directory over directory" +msgstr "No se puet mover una carpeta sobre unatra carpeta" + +#: ../gio/glocalfile.c:2350 ../gio/glocalfileoutputstream.c:959 +#: ../gio/glocalfileoutputstream.c:973 ../gio/glocalfileoutputstream.c:988 +#: ../gio/glocalfileoutputstream.c:1004 ../gio/glocalfileoutputstream.c:1018 +msgid "Backup file creation failed" +msgstr "Ha fallau a creyación d'o fichero de copia de seguranza" + +#: ../gio/glocalfile.c:2369 +#, c-format +msgid "Error removing target file: %s" +msgstr "S'ha produciu una error en eliminar o fichero de destín: %s" + +#: ../gio/glocalfile.c:2383 +msgid "Move between mounts not supported" +msgstr "No se suporta mover fichers entre puntos de montache" + +#: ../gio/glocalfileinfo.c:722 +msgid "Attribute value must be non-NULL" +msgstr "A valor de l'atributo d'estar no nulo" + +#: ../gio/glocalfileinfo.c:729 +msgid "Invalid attribute type (string expected)" +msgstr "Mena d'atributo no valida (s'asperaba una cadena)" + +#: ../gio/glocalfileinfo.c:736 +msgid "Invalid extended attribute name" +msgstr "Nombre extendiu de l'atributo no valido" + +#: ../gio/glocalfileinfo.c:776 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "S'ha produciu una error en establir l'atributo extendiu «%s»: %s" + +#: ../gio/glocalfileinfo.c:1542 +msgid " (invalid encoding)" +msgstr " (codificación no valida)" + +#: ../gio/glocalfileinfo.c:1734 ../gio/glocalfileoutputstream.c:837 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "S'ha produciu una error en obtener a información d'o fichero «%s»: %s" + +#: ../gio/glocalfileinfo.c:1980 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" +"S'ha produciu una error en obtener a información d'o descriptor d'o fichero: " +"%s" + +#: ../gio/glocalfileinfo.c:2025 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Mena d'atributo no valida (s'asperaba uint32)" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Mena d'atributo no valida (s'asperaba uint64)" + +#: ../gio/glocalfileinfo.c:2062 ../gio/glocalfileinfo.c:2081 +msgid "Invalid attribute type (byte string expected)" +msgstr "Mena d'atributo no valida (s'asperaba una cadena byte)" + +#: ../gio/glocalfileinfo.c:2116 +msgid "Cannot set permissions on symlinks" +msgstr "No se pueden establir permisos en vinclos simbolicos" + +#: ../gio/glocalfileinfo.c:2132 +#, c-format +msgid "Error setting permissions: %s" +msgstr "S'ha produciu una error en establir os permisos: %s" + +#: ../gio/glocalfileinfo.c:2183 +#, c-format +msgid "Error setting owner: %s" +msgstr "S'ha produciu una error en establir o propietario: %s" + +#: ../gio/glocalfileinfo.c:2206 +msgid "symlink must be non-NULL" +msgstr "o vinclo simbolico debe estar no nulo" + +#: ../gio/glocalfileinfo.c:2216 ../gio/glocalfileinfo.c:2235 +#: ../gio/glocalfileinfo.c:2246 +#, c-format +msgid "Error setting symlink: %s" +msgstr "S'ha produciu una error en establir o vinclo simbolico: %s" + +#: ../gio/glocalfileinfo.c:2225 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"S'ha produciu una error en establir o vinclo simbolico: o fichero no ye un " +"vinclo simbolico" + +#: ../gio/glocalfileinfo.c:2351 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "S'ha produciu una error en establir u modificar o tiempo d'acceso: %s" + +#: ../gio/glocalfileinfo.c:2374 +msgid "SELinux context must be non-NULL" +msgstr "O contexto SELinux debe estar no nulo" + +#: ../gio/glocalfileinfo.c:2389 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "S'ha produciu una error en establir o contexto SELinux: %s" + +#: ../gio/glocalfileinfo.c:2396 +msgid "SELinux is not enabled on this system" +msgstr "SELinux no ye activau en iste sistema" + +#: ../gio/glocalfileinfo.c:2488 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Establir l'atributo %s no ye suportau" + +#: ../gio/glocalfileinputstream.c:186 ../gio/glocalfileoutputstream.c:726 +#, c-format +msgid "Error reading from file: %s" +msgstr "S'ha produciu una error en leyer dende o fichero: %s" + +#: ../gio/glocalfileinputstream.c:217 ../gio/glocalfileinputstream.c:229 +#: ../gio/glocalfileinputstream.c:336 ../gio/glocalfileoutputstream.c:464 +#: ../gio/glocalfileoutputstream.c:1036 +#, c-format +msgid "Error seeking in file: %s" +msgstr "S'ha produciu una error en mirar en o fichero: %s" + +#: ../gio/glocalfileinputstream.c:258 ../gio/glocalfileoutputstream.c:254 +#: ../gio/glocalfileoutputstream.c:348 +#, c-format +msgid "Error closing file: %s" +msgstr "S'ha produciu una error en zarrar o fichero: %s" + +#: ../gio/glocalfilemonitor.c:176 +msgid "Unable to find default local file monitor type" +msgstr "" +"No s'ha puesto trobar o tipo de monitorización d'o fichero local " +"predeterminau" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:234 +#: ../gio/glocalfileoutputstream.c:747 +#, c-format +msgid "Error writing to file: %s" +msgstr "S'ha produciu una error en escribir en o fichero: %s" + +#: ../gio/glocalfileoutputstream.c:281 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" +"S'ha produciu una error en eliminar o vinclo de copia de seguranza antigo: %s" + +#: ../gio/glocalfileoutputstream.c:295 ../gio/glocalfileoutputstream.c:308 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "S'ha produciu una error en creyar una copia de seguranza: %s" + +#: ../gio/glocalfileoutputstream.c:326 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "S'ha produciu una error en renombrar o fichero temporal: %s" + +#: ../gio/glocalfileoutputstream.c:510 ../gio/glocalfileoutputstream.c:1087 +#, c-format +msgid "Error truncating file: %s" +msgstr "S'ha produciu una error en truncar o fichero: %s" + +#: ../gio/glocalfileoutputstream.c:581 ../gio/glocalfileoutputstream.c:634 +#: ../gio/glocalfileoutputstream.c:679 ../gio/glocalfileoutputstream.c:819 +#: ../gio/glocalfileoutputstream.c:1068 ../gio/glocalfileoutputstream.c:1167 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "S'ha produciu una error en ubrir o fichero «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:850 +msgid "Target file is a directory" +msgstr "O fichero de destín ye una carpeta" + +#: ../gio/glocalfileoutputstream.c:855 +msgid "Target file is not a regular file" +msgstr "O fichero de destín no ye un fichero regular" + +#: ../gio/glocalfileoutputstream.c:867 +msgid "The file was externally modified" +msgstr "O fichero s'ha modificau externament" + +#: ../gio/glocalfileoutputstream.c:1052 +#, c-format +msgid "Error removing old file: %s" +msgstr "S'ha produciu una error en eliminar o fichero antigo: %s" + +#: ../gio/gmemoryinputstream.c:476 ../gio/gmemoryoutputstream.c:739 +msgid "Invalid GSeekType supplied" +msgstr "S'ha proporcionau un GSeekType no valido" + +#: ../gio/gmemoryinputstream.c:486 +msgid "Invalid seek request" +msgstr "Petición de busca no valida" + +#: ../gio/gmemoryinputstream.c:510 +msgid "Cannot truncate GMemoryInputStream" +msgstr "No se puet truncar GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:544 +msgid "Memory output stream not resizable" +msgstr "O fluxo de salida d'a memoria no ye redimensionable" + +#: ../gio/gmemoryoutputstream.c:560 +msgid "Failed to resize memory output stream" +msgstr "Ha fallau en redimensionar o fluxo de salida d'a memoria" + +#: ../gio/gmemoryoutputstream.c:648 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"A cantidat de memoria necesaria ta procesar o escrito ye mayor que o espacio " +"d'adrezas libre disponible" + +#: ../gio/gmemoryoutputstream.c:749 +msgid "Requested seek before the beginning of the stream" +msgstr "A busca solicitada antes de l'inicio d'o fluxo" + +#: ../gio/gmemoryoutputstream.c:758 +msgid "Requested seek beyond the end of the stream" +msgstr "A busca solicitada dimpués d'o final d'o fluxo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:395 +msgid "mount doesn't implement \"unmount\"" +msgstr "o punto de montache no implementa lo desmontau («unmount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:471 +msgid "mount doesn't implement \"eject\"" +msgstr "o punto de montache no implementa a expulsión («eject»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:549 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"o punto de montache no implementa desmontau («umount») u desmontau con " +"operación («unmount_*with_*operation»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:634 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"o punto de montache no implementa a expulsión («eject») u expulsión con " +"operación («eject_*with_*operation»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:722 +msgid "mount doesn't implement \"remount\"" +msgstr "o punto de montache no implementa o remontau («remount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:803 +msgid "mount doesn't implement content type guessing" +msgstr "o punto de montache no implementa esbrinamiento d'o tipo de conteniu" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" +"o punto de montache no implementa esbrinamiento d'o tipo de conteniu sincrono" + +#: ../gio/gnetworkaddress.c:354 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "O nombre de l'equipo «%s» contién «[» pero no «]»" + +#: ../gio/gnetworkmonitorbase.c:195 ../gio/gnetworkmonitorbase.c:298 +msgid "Network unreachable" +msgstr "Ret no adubible" + +#: ../gio/gnetworkmonitorbase.c:233 ../gio/gnetworkmonitorbase.c:263 +msgid "Host unreachable" +msgstr "Equipo no adubible" + +#: ../gio/gnetworkmonitornetlink.c:98 ../gio/gnetworkmonitornetlink.c:110 +#: ../gio/gnetworkmonitornetlink.c:129 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "No s'ha puesto creyar o monitor de ret: %s" + +#: ../gio/gnetworkmonitornetlink.c:119 +msgid "Could not create network monitor: " +msgstr "No s'ha puesto creyar o monitor de ret: " + +#: ../gio/gnetworkmonitornetlink.c:177 +msgid "Could not get network status: " +msgstr "No s'ha puesto obtener l'estau d'o ret: " + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:464 +msgid "Output stream doesn't implement write" +msgstr "O fluxo de salida no implementa la escritura" + +#: ../gio/goutputstream.c:425 ../gio/goutputstream.c:950 +msgid "Source stream is already closed" +msgstr "O fluxo d'orichen ya ye zarrau" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:454 +#: ../gio/gresourcefile.c:555 ../gio/gresourcefile.c:657 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "O recurso en «%s» no existe" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "O recurso en «%s» ha fallau a lo descomprimir" + +#: ../gio/gresourcefile.c:653 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "O recurso en «%s» no ye una carpeta" + +#: ../gio/gresourcefile.c:861 +msgid "Input stream doesn't implement seek" +msgstr "O fluxo de dentrada no implementa la busca" + +#: ../gio/gresource-tool.c:475 ../gio/gsettings-tool.c:529 +msgid "Print help" +msgstr "Imprentar l'aduya" + +#: ../gio/gresource-tool.c:476 ../gio/gresource-tool.c:544 +msgid "[COMMAND]" +msgstr "[COMANDO]" + +#: ../gio/gresource-tool.c:481 +msgid "List sections containing resources in an elf FILE" +msgstr "Listar as seccions que contiengan recursos en un FICHERO elf" + +#: ../gio/gresource-tool.c:487 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Listar os recursos\n" +"Si se da la SECCIÓN, listar solament os recursos d'ista sección.\n" +"Si se da la ROTA, listar solament os recursos que coincidan" + +#: ../gio/gresource-tool.c:490 ../gio/gresource-tool.c:500 +msgid "FILE [PATH]" +msgstr "FICHERO [ROTA]" + +#: ../gio/gresource-tool.c:491 ../gio/gresource-tool.c:501 +#: ../gio/gresource-tool.c:508 +msgid "SECTION" +msgstr "SECCIÓN" + +#: ../gio/gresource-tool.c:496 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Listar os recursos con detalles\n" +"Si se da la SECCIÓN, listar solament os recursos d'ista sección.\n" +"Si se da la ROTA, listar solament os recursos que coincidan\n" +"Os detalles incluyen a sección, a grandaria y a compresión" + +#: ../gio/gresource-tool.c:506 +msgid "Extract a resource file to stdout" +msgstr "Extrayer un fichero de recursos a stdout" + +#: ../gio/gresource-tool.c:507 +msgid "FILE PATH" +msgstr "FICHERO de ROTA" + +#: ../gio/gresource-tool.c:513 ../gio/gsettings-tool.c:609 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Comando «%s» desconoixiu\n" +"\n" + +#: ../gio/gresource-tool.c:521 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gresource [--section SECCIÓN] COMANDO [ARGUMENTOS...]\n" +"\n" +"Comandos:\n" +" help Amostrar ista información\n" +" sections Listar as seccions de recursos\n" +" list Listar os recursos\n" +" details Listar os recursos con detalle\n" +" extract Extrayer un recurso\n" +"\n" +"Usa «gresource help COMANDO» ta obtener aduya detallada.\n" +"\n" + +#: ../gio/gresource-tool.c:535 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:538 ../gio/gsettings-tool.c:642 +msgid "Arguments:\n" +msgstr "Argumentos:\n" + +#: ../gio/gresource-tool.c:542 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECCIÓN O nombre d'a sección (opcional) d'un elf\n" + +#: ../gio/gresource-tool.c:546 ../gio/gsettings-tool.c:649 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMANDO O comando (opcional) que explicar\n" + +#: ../gio/gresource-tool.c:552 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" FICHERO Un fichero elf (un binario u una biblioteca compartida)\n" + +#: ../gio/gresource-tool.c:555 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FICHERO Un fichero elf (un binario u una biblioteca compartida)\n" +" u un fichero de recursos compilau\n" + +#: ../gio/gresource-tool.c:559 +msgid "[PATH]" +msgstr "[ROTA]" + +#: ../gio/gresource-tool.c:561 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " ROTA A rota (opcional) d'un recurso (puet estar parcial)\n" + +#: ../gio/gresource-tool.c:562 +msgid "PATH" +msgstr "ROTA" + +#: ../gio/gresource-tool.c:564 +msgid " PATH A resource path\n" +msgstr " ROTA A rota d'un recurso\n" + +#: ../gio/gsettings-tool.c:57 ../gio/gsettings-tool.c:78 +#, c-format +msgid "No such schema '%s'\n" +msgstr "No existe l'esquema «%s»\n" + +#: ../gio/gsettings-tool.c:63 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "L'esquema «%s» no ye reubicable (no cal especificar a rota)\n" + +#: ../gio/gsettings-tool.c:84 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "L'esquema «%s» ye reubicable (cal especificar a rota)\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Empty path given.\n" +msgstr "S'ha proporcionau una rota vueda.\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "A rota debe prencipiar con una barra (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "A rota debe rematar con una barra (/)\n" + +#: ../gio/gsettings-tool.c:116 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "A rota no debe contener dos barras adchacents (//)\n" + +#: ../gio/gsettings-tool.c:137 +#, c-format +msgid "No such key '%s'\n" +msgstr "No existe a clau «%s»\n" + +#: ../gio/gsettings-tool.c:502 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "A valor proporcionada ye difuera d'o rango valido\n" + +#: ../gio/gsettings-tool.c:535 +msgid "List the installed (non-relocatable) schemas" +msgstr "Listar os esquemas instalaus (no reubicables)" + +#: ../gio/gsettings-tool.c:541 +msgid "List the installed relocatable schemas" +msgstr "Listar os esquemas reubicables instalaus" + +#: ../gio/gsettings-tool.c:547 +msgid "List the keys in SCHEMA" +msgstr "Listar as claus en l'ESQUEMA" + +#: ../gio/gsettings-tool.c:548 ../gio/gsettings-tool.c:554 +#: ../gio/gsettings-tool.c:591 +msgid "SCHEMA[:PATH]" +msgstr "ESQUEMA[:ROTA]" + +#: ../gio/gsettings-tool.c:553 +msgid "List the children of SCHEMA" +msgstr "Listar os fillos de l'ESQUEMA" + +#: ../gio/gsettings-tool.c:559 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Listar as claus y as valors recursivament\n" +"Si no se proporciona un ESQUEMA, listar todas as claus\n" + +#: ../gio/gsettings-tool.c:561 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESQUEMA[:ROTA]]" + +#: ../gio/gsettings-tool.c:566 +msgid "Get the value of KEY" +msgstr "Obtener a valor d'a CLAU" + +#: ../gio/gsettings-tool.c:567 ../gio/gsettings-tool.c:573 +#: ../gio/gsettings-tool.c:585 ../gio/gsettings-tool.c:597 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESQUEMA[:ROTA] CLAU" + +#: ../gio/gsettings-tool.c:572 +msgid "Query the range of valid values for KEY" +msgstr "Consultar o rango de valors validas ta la CLAU" + +#: ../gio/gsettings-tool.c:578 +msgid "Set the value of KEY to VALUE" +msgstr "Establir a valor d'a CLAU ta VALOR" + +#: ../gio/gsettings-tool.c:579 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESQUEMA[:ROTA] CLAU VALOR" + +#: ../gio/gsettings-tool.c:584 +msgid "Reset KEY to its default value" +msgstr "Restablir a CLAU a la valor predeterminada d'ella" + +#: ../gio/gsettings-tool.c:590 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" +"Restablir todas as claus en un ESQUEMA a las valors predeterminadas d'ellas" + +#: ../gio/gsettings-tool.c:596 +msgid "Check if KEY is writable" +msgstr "Comprebar si a CLAU se puet escribir" + +#: ../gio/gsettings-tool.c:602 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitorizar os cambeos en a CLAU.\n" +"Si no s'especifica una CLAU, monitorizar todas as claus en l'ESQUEMA.\n" +"Usa ^C ta aturar a monitorización.\n" + +#: ../gio/gsettings-tool.c:605 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESQUEMA[:ROTA] [CLAU]" + +#: ../gio/gsettings-tool.c:617 +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings [--schemadir CARPETA_ESQUEMA] COMANDO [ARGUMENTOS...]\n" +"\n" +"Comandos:\n" +" help Amostrar ista información\n" +" list-schemas Listar os esquemas instalaus\n" +" list-relocatable-schemas Listar os esquemas reubicables\n" +" list-keys Listar as claus en un esquema\n" +" list-children Listar os fillos d'un esquema\n" +" list-recursively Listar as claus y as valors recursivament\n" +" range Consultar o rango d'una clau\n" +" get Obtener a valor d'una clau\n" +" set Establir a valor d'una clau\n" +" reset Restablir a valor d'una clau\n" +" reset-recursively Restablir todas as valors en un esquema dau\n" +" writable Comprebar si una clau se puet escribir\n" +" monitor Monitorizar os cambeos\n" +"\n" +"Usa «gsettings help COMANDO» ta obtener una aduya detallada.\n" +"\n" + +#: ../gio/gsettings-tool.c:639 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings [--schemadir CARPETA_ESQUEMA] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:645 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " CARPETA_ESQUEMA: una carpeta ta mirar esquemas adicionals\n" + +#: ../gio/gsettings-tool.c:653 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA O nombre d'o esquema\n" +" ROTA A rota, ta los esquemas reubicables\n" + +#: ../gio/gsettings-tool.c:658 +msgid " KEY The (optional) key within the schema\n" +msgstr " CLAU A clau (opcional) ta l'esquema\n" + +#: ../gio/gsettings-tool.c:662 +msgid " KEY The key within the schema\n" +msgstr " CLAU A clau ta l'esquema\n" + +#: ../gio/gsettings-tool.c:666 +msgid " VALUE The value to set\n" +msgstr " VALOR A valor ta establir\n" + +#: ../gio/gsettings-tool.c:725 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "No s'han puesto cargar os esquemas de %s: %s\n" + +#: ../gio/gsettings-tool.c:784 +#, c-format +msgid "Empty schema name given\n" +msgstr "S'ha proporcionau un nombre d'esquema vuedo\n" + +#: ../gio/gsocket.c:311 +msgid "Invalid socket, not initialized" +msgstr "Socket no valido, sin inicializar" + +#: ../gio/gsocket.c:318 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Socket no valido, ha fallau a instalación a causa de: %s" + +#: ../gio/gsocket.c:326 +msgid "Socket is already closed" +msgstr "O socket ya ye zarrau" + +#: ../gio/gsocket.c:334 ../gio/gsocket.c:3525 ../gio/gsocket.c:3580 +msgid "Socket I/O timed out" +msgstr "Ha expirau a E/S d'o socket" + +#: ../gio/gsocket.c:481 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "Seye creyando lo GSocket dende fd: %s" + +#: ../gio/gsocket.c:509 ../gio/gsocket.c:563 ../gio/gsocket.c:570 +#, c-format +msgid "Unable to create socket: %s" +msgstr "No s'ha puesto creyar o socket: %s" + +#: ../gio/gsocket.c:563 +msgid "Unknown family was specified" +msgstr "S'ha especificau una familia desconoixida" + +#: ../gio/gsocket.c:570 +msgid "Unknown protocol was specified" +msgstr "S'ha especificau un protocolo desconoixiu" + +#: ../gio/gsocket.c:1728 +#, c-format +msgid "could not get local address: %s" +msgstr "no s'ha puesto obtener l'adreza local: %s" + +#: ../gio/gsocket.c:1771 +#, c-format +msgid "could not get remote address: %s" +msgstr "no s'ha puesto obtener l'adreza remota: %s" + +#: ../gio/gsocket.c:1832 +#, c-format +msgid "could not listen: %s" +msgstr "no s'ha puesto escuitar: %s" + +#: ../gio/gsocket.c:1904 +#, c-format +msgid "Error binding to address: %s" +msgstr "S'ha produciu una error en vincular con l'adreza: %s" + +#: ../gio/gsocket.c:1957 ../gio/gsocket.c:1994 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "S'ha produciu una error en unir-se a lo grupo de multicast: %s" + +#: ../gio/gsocket.c:1958 ../gio/gsocket.c:1995 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "S'ha produciu una error en abandonar lo grupo de multicast: %s" + +#: ../gio/gsocket.c:1959 +msgid "No support for source-specific multicast" +msgstr "No se suporta o multicast especifico d'a fuent" + +#: ../gio/gsocket.c:2178 +#, c-format +msgid "Error accepting connection: %s" +msgstr "S'ha produciu una error en acceptar a connexión: %s" + +#: ../gio/gsocket.c:2299 +msgid "Connection in progress" +msgstr "Connexión en progreso" + +#: ../gio/gsocket.c:2346 +msgid "Unable to get pending error: " +msgstr "No s'ha puesto obtener a error pendient: " + +#: ../gio/gsocket.c:2512 +#, c-format +msgid "Error receiving data: %s" +msgstr "S'ha produciu una error en recibir os datos: %s" + +#: ../gio/gsocket.c:2690 +#, c-format +msgid "Error sending data: %s" +msgstr "S'ha produciu una error en ninviar os datos: %s" + +#: ../gio/gsocket.c:2804 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "No s'ha puesto desconnectar o socket: %s" + +#: ../gio/gsocket.c:2883 +#, c-format +msgid "Error closing socket: %s" +msgstr "S'ha produciu una error en zarrar o socket: %s" + +#: ../gio/gsocket.c:3518 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Se ye asperando a condición d'o socket: %s" + +#: ../gio/gsocket.c:3796 ../gio/gsocket.c:3877 +#, c-format +msgid "Error sending message: %s" +msgstr "S'ha produciu una error en ninviar o mensache: %s" + +#: ../gio/gsocket.c:3821 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage no ye suportau en Windows" + +#: ../gio/gsocket.c:4155 ../gio/gsocket.c:4290 +#, c-format +msgid "Error receiving message: %s" +msgstr "S'ha produciu una error en recibir o mensache: %s" + +#: ../gio/gsocket.c:4372 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "No s'ha puesto obtener a error pendient: %s" + +#: ../gio/gsocket.c:4391 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials no ye implementau en iste sistema operativo" + +#: ../gio/gsocketclient.c:177 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "No s'ha puesto connectar a lo servidor proxy %s: " + +#: ../gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to %s: " +msgstr "No s'ha puesto connectar a %s: " + +#: ../gio/gsocketclient.c:193 +msgid "Could not connect: " +msgstr "No s'ha puesto connectar: " + +#: ../gio/gsocketclient.c:1072 ../gio/gsocketclient.c:1636 +msgid "Unknown error on connect" +msgstr "S'ha produciu una error desconoixida en connectar" + +#: ../gio/gsocketclient.c:1125 ../gio/gsocketclient.c:1574 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "No se suporta intentar fer de proxy sobre una connexión que no ye TCP." + +#: ../gio/gsocketclient.c:1151 ../gio/gsocketclient.c:1595 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "O protocolo d'o proxy «%s» no se suporta." + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "O receptor de connexions ye zarrau" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "O socket adhibiu ye zarrau" + +#: ../gio/gsocks4aproxy.c:120 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 no suporta l'adreza de IPv6 «%s»" + +#: ../gio/gsocks4aproxy.c:138 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "O nombre d'usuario u a clau son masiau luengos ta lo protocolo SOCKSv5" + +#: ../gio/gsocks4aproxy.c:155 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "O nombre d'equipo «%s» ye masiau luengo ta lo protocolo SOCKSv5" + +#: ../gio/gsocks4aproxy.c:181 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "O servidor no ye un servidor proxy SOCKSv4." + +#: ../gio/gsocks4aproxy.c:188 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "S'ha refusau a connexión a traviés d'o servidor SOCKSv4" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:326 +#: ../gio/gsocks5proxy.c:336 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "O servidor no ye un servidor proxy SOCKSv5." + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "O servidor proxy SOCKSv5 requiere autenticación." + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"O servidor SOCKSv5 requiere un metodo d'autenticación que GLib no suporta." + +#: ../gio/gsocks5proxy.c:208 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"O nombre d'usuario u a clau son masiau luengos ta lo protocolo SOCKSv5." + +#: ../gio/gsocks5proxy.c:238 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Ha fallau l'autenticación SOCKSv5 a causa d'un nombre d'usuario u una clau " +"incorrecta." + +#: ../gio/gsocks5proxy.c:288 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "O nombre d'equipo «%s» ye masiau luengo ta lo protocolo SOCKSv5" + +#: ../gio/gsocks5proxy.c:350 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "O servidor proxy SOCKSv5 usa una mena d'adreza desconoixida." + +#: ../gio/gsocks5proxy.c:357 +msgid "Internal SOCKSv5 proxy server error." +msgstr "S'ha produciu una error interna de SOCKSv5 d'o servidor proxy." + +#: ../gio/gsocks5proxy.c:363 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "O conchunto de regles no permite a connexión SOCKSv5." + +#: ../gio/gsocks5proxy.c:370 +msgid "Host unreachable through SOCKSv5 server." +msgstr "O servidor no ye adubible a traviés d'o servidor SOCKSv5." + +#: ../gio/gsocks5proxy.c:376 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "O ret no ye adubible a traviés d'o proxy SOCKSv5." + +#: ../gio/gsocks5proxy.c:382 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "S'ha refusau a connexión a traviés d'o proxy SOCKSv5." + +#: ../gio/gsocks5proxy.c:388 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "O proxy SOCKSv5 no suporta lo comando «connect»." + +#: ../gio/gsocks5proxy.c:394 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "O proxy SOCKSv5 no suporta a mena d'adreza proporcionada." + +#: ../gio/gsocks5proxy.c:400 +msgid "Unknown SOCKSv5 proxy error." +msgstr "S'ha produciu una error desconoixida d'o proxy SOCKSv5." + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "No se puet maniar a versión %d d'a codificación GThemedIcon" + +#: ../gio/gthreadedresolver.c:110 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "S'ha produciu una error en resolver «%s»: %s" + +#: ../gio/gthreadedresolver.c:195 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "S'ha produciu una error en resolver «%s» de traza inversa: %s" + +#: ../gio/gthreadedresolver.c:397 ../gio/gthreadedresolver.c:571 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "No bi ha un rechistro de DNS d'a mena solicitada ta «%s»" + +#: ../gio/gthreadedresolver.c:402 ../gio/gthreadedresolver.c:576 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "No se puet resolver «%s» temporalment" + +#: ../gio/gthreadedresolver.c:407 ../gio/gthreadedresolver.c:581 +#, c-format +msgid "Error resolving '%s'" +msgstr "SS'ha produciu una error en resolver «%s»" + +#: ../gio/gtlscertificate.c:248 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "No s'ha puesto deszifrar a clau privada codificada con PEM" + +#: ../gio/gtlscertificate.c:253 +msgid "No PEM-encoded private key found" +msgstr "No s'ha trobau garra clau privada codificada con PEM" + +#: ../gio/gtlscertificate.c:263 +msgid "Could not parse PEM-encoded private key" +msgstr "No s'ha puesto analisar a clau privada codificada con PEM" + +#: ../gio/gtlscertificate.c:288 +msgid "No PEM-encoded certificate found" +msgstr "No s'ha trobau garra certificau codificau con PEM" + +#: ../gio/gtlscertificate.c:297 +msgid "Could not parse PEM-encoded certificate" +msgstr "No s'ha puesto analisar o certificau codificau con PEM" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ista ye a zaguera oportunidat ta introducir a clau correctament antis que o " +"tuyo acceso se bloqueye." + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"S'han introduciu quantas claus incorrectas, y lo tuyo acceso se bloqueyará " +"dimpués de mas fallos." + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "A clau introducida no ye correcta" + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:548 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "S'asperaba un mensache de control, s'han obteniu %d" + +#: ../gio/gunixconnection.c:172 ../gio/gunixconnection.c:558 +msgid "Unexpected type of ancillary data" +msgstr "Menas de datos complementarios inasperadas" + +#: ../gio/gunixconnection.c:190 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "S'asperaba un fd pero s'han obteniu %d\n" + +#: ../gio/gunixconnection.c:206 +msgid "Received invalid fd" +msgstr "S'ha recibiu un fd no valido" + +#: ../gio/gunixconnection.c:342 +msgid "Error sending credentials: " +msgstr "S'ha produciu una error en ninviar as credencials: " + +#: ../gio/gunixconnection.c:490 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"S'ha produciu una error en comprebar si SO_PASSCRED ye activada ta lo " +"socket: %s" + +#: ../gio/gunixconnection.c:505 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "S'ha produciu una error en activar SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:534 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"S'asperaba leyer un solo byte ta recibir as credencials pero s'han leyiu " +"zero bytes" + +#: ../gio/gunixconnection.c:572 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "No s'asperaba un mensache de control, pero s'ha obteniu %d" + +#: ../gio/gunixconnection.c:596 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "S'ha produciu una error en desactivar SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:382 ../gio/gunixinputstream.c:403 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "S'ha produciu una error en leyer d'o descriptor d'o fichero: %s" + +#: ../gio/gunixinputstream.c:436 ../gio/gunixoutputstream.c:422 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "S'ha produciu una error en zarrar o descriptor d'o fichero: %s" + +#: ../gio/gunixmounts.c:1983 ../gio/gunixmounts.c:2036 +msgid "Filesystem root" +msgstr "Sistema de fichers radiz" + +#: ../gio/gunixoutputstream.c:368 ../gio/gunixoutputstream.c:389 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "S'ha produciu una error en escribir en o descriptor d'o fichero: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Iste sistema no suporta adrezas de socket de dominio UNIX abstracto" + +#: ../gio/gvolume.c:439 +msgid "volume doesn't implement eject" +msgstr "o volumen no implementa la expulsión" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:516 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "o volumen no implementa la expulsión u la expulsión con operación" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "No se puet trobar l'aplicación" + +#: ../gio/gwin32appinfo.c:308 +#, c-format +msgid "Error launching application: %s" +msgstr "S'ha produciu una error en analisar l'aplicación: %s" + +#: ../gio/gwin32appinfo.c:344 +msgid "URIs not supported" +msgstr "No se suportan URI" + +#: ../gio/gwin32appinfo.c:366 +msgid "association changes not supported on win32" +msgstr "os cambeos d'asociación no son suportaus en win32" + +#: ../gio/gwin32appinfo.c:378 +msgid "Association creation not supported on win32" +msgstr "A creyación d'asociación no ye suportada en win32" + +#: ../gio/gwin32inputstream.c:355 +#, c-format +msgid "Error reading from handle: %s" +msgstr "S'ha produciu una error en leyer d'o maneyador: %s" + +#: ../gio/gwin32inputstream.c:387 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "S'ha produciu una error en zarrar o maneyador: %s" + +#: ../gio/gwin32outputstream.c:343 +#, c-format +msgid "Error writing to handle: %s" +msgstr "S'ha produciu una error en escribir en o maneyador: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "No bi ha suficient memoria" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "S'ha produciu una error interna: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "S'ameneste mas dentrada" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "Datos comprimius no validos" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adreza en a quala escuitar" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "S'ignora, por compatibilidat con GTestDbus" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Imprentar l'adreza" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Imprentar l'adreza en modo consola" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Executar un servicio dbus" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "Argumentos incorrectos\n" + +#: ../glib/gbookmarkfile.c:760 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Atributo inasperau «%s» ta l'elemento «%s»" + +#: ../glib/gbookmarkfile.c:771 ../glib/gbookmarkfile.c:842 +#: ../glib/gbookmarkfile.c:852 ../glib/gbookmarkfile.c:959 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "L'atributo «%s» de l'elemento «%s» no s'ha trobau" + +#: ../glib/gbookmarkfile.c:1129 ../glib/gbookmarkfile.c:1194 +#: ../glib/gbookmarkfile.c:1258 ../glib/gbookmarkfile.c:1268 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Etiqueta «%s» inasperada, s'asperaba a etiqueta «%s»" + +#: ../glib/gbookmarkfile.c:1154 ../glib/gbookmarkfile.c:1168 +#: ../glib/gbookmarkfile.c:1236 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Etiqueta «%s» inasperada adentro de «%s»" + +#: ../glib/gbookmarkfile.c:1798 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"No s'ha puesto trobar garra fichero de marcadors valido en as carpetas de " +"datos" + +#: ../glib/gbookmarkfile.c:1999 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Ya bi existe un marcador ta l'URI «%s»" + +#: ../glib/gbookmarkfile.c:2045 ../glib/gbookmarkfile.c:2203 +#: ../glib/gbookmarkfile.c:2288 ../glib/gbookmarkfile.c:2368 +#: ../glib/gbookmarkfile.c:2453 ../glib/gbookmarkfile.c:2536 +#: ../glib/gbookmarkfile.c:2614 ../glib/gbookmarkfile.c:2693 +#: ../glib/gbookmarkfile.c:2735 ../glib/gbookmarkfile.c:2832 +#: ../glib/gbookmarkfile.c:2952 ../glib/gbookmarkfile.c:3142 +#: ../glib/gbookmarkfile.c:3218 ../glib/gbookmarkfile.c:3386 +#: ../glib/gbookmarkfile.c:3475 ../glib/gbookmarkfile.c:3565 +#: ../glib/gbookmarkfile.c:3693 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "No s'ha trobau un marcador ta l'URI «%s»" + +#: ../glib/gbookmarkfile.c:2377 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Garra mena MIME definida en o marcador ta l'URI «%s»" + +#: ../glib/gbookmarkfile.c:2462 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "No s'ha definiu garra sinyalador privau en o marcador ta l'URI «%s»" + +#: ../glib/gbookmarkfile.c:2841 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "No s'ha establiu garra grupo en o marcador ta l'URI «%s»" + +#: ../glib/gbookmarkfile.c:3239 ../glib/gbookmarkfile.c:3396 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "Garra aplicación con nombre «%s» ha rechistrau un marcador ta «%s»" + +#: ../glib/gbookmarkfile.c:3419 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Ha fallau a expansión d'a linia executable «%s» con l'URI «%s»" + +#: ../glib/gconvert.c:803 ../glib/gutf8.c:829 ../glib/gutf8.c:1039 +#: ../glib/gutf8.c:1176 ../glib/gutf8.c:1280 +msgid "Partial character sequence at end of input" +msgstr "Bi ha una seqüencia parcial de caracters en o final d'a dentrada" + +#: ../glib/gconvert.c:1053 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" +"No se puet convertir l'alternativa «%s» ta lo conchunto de codigos «%s»" + +#: ../glib/gconvert.c:1871 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "L'URI «%s» no ye una URI absoluta utilizando l'esquema «file»" + +#: ../glib/gconvert.c:1881 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "O fichero local en a URI «%s» no debe incluir un «#»" + +#: ../glib/gconvert.c:1898 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "L'URI «%s» no ye valido" + +#: ../glib/gconvert.c:1910 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "O nombre d'o host d'a URI «%s» no ye valido" + +#: ../glib/gconvert.c:1926 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "L'URI «%s» contién caracters d'escape no validos" + +#: ../glib/gconvert.c:2021 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "O nombre d'a rota «%s» no ye una rota absoluta" + +#: ../glib/gconvert.c:2031 +msgid "Invalid hostname" +msgstr "O nombre d'o host no ye valido" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %H:%M:%S, %y de %B de %Y" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:219 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "January" +msgstr "Chinero" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "February" +msgstr "Febrero" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "March" +msgstr "Marzo" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "April" +msgstr "Abril" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "May" +msgstr "Mayo" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "June" +msgstr "Chunio" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "July" +msgstr "Chulio" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "August" +msgstr "Agosto" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "September" +msgstr "Setiembre" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "October" +msgstr "Octubre" + +#: ../glib/gdatetime.c:252 +msgctxt "full month name" +msgid "November" +msgstr "Noviembre" + +#: ../glib/gdatetime.c:254 +msgctxt "full month name" +msgid "December" +msgstr "Aviento" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Chi" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Abr" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "May" +msgstr "May" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Chn" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Chl" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ago" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Set" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Oct" + +#: ../glib/gdatetime.c:289 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: ../glib/gdatetime.c:291 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Abi" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Luns" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Martes" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Miercols" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Chueves" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Viernes" + +#: ../glib/gdatetime.c:316 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sabado" + +#: ../glib/gdatetime.c:318 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Domingo" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Lun" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Mar" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mie" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Chu" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Vie" + +#: ../glib/gdatetime.c:343 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sab" + +#: ../glib/gdatetime.c:345 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Dom" + +#: ../glib/gdir.c:120 ../glib/gdir.c:143 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "S'ha produciu una error en ubrir a carpeta «%s»: %s" + +#: ../glib/gfileutils.c:671 ../glib/gfileutils.c:759 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "No s'ha puesto asignar %lu byte ta leyer o fichero «%s»" +msgstr[1] "No s'han puesto asignar %lu bytes ta leyer o fichero «%s»" + +#: ../glib/gfileutils.c:686 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "S'ha produciu una error en leyer o fichero «%s»: %s" + +#: ../glib/gfileutils.c:700 +#, c-format +msgid "File \"%s\" is too large" +msgstr "O fichero «%s» ye masiau gran" + +#: ../glib/gfileutils.c:783 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Ha fallau en leyer dende o fichero «%s»: %s" + +#: ../glib/gfileutils.c:834 ../glib/gfileutils.c:921 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Ha fallau en ubrir o fichero «%s»: %s" + +#: ../glib/gfileutils.c:851 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" +"Ha fallau en obtener os atributos d'o fichero «%s»: fstat() ha fallau: %s" + +#: ../glib/gfileutils.c:885 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Ha fallau en ubrir o fichero «%s»: fdopen() ha fallau: %s" + +#: ../glib/gfileutils.c:993 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Ha fallau en renombrar o fichero «%s» a «%s»: g_rename() ha fallau: %s" + +#: ../glib/gfileutils.c:1035 ../glib/gfileutils.c:1593 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Ha fallau en creyar o fichero «%s»: %s" + +#: ../glib/gfileutils.c:1049 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Ha fallau en ubrir o fichero «%s» ta escritura: fdopen() ha fallau: %s" + +#: ../glib/gfileutils.c:1074 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Ha fallau en escribir o fichero «%s»: ha fallau fwrite(): %s" + +#: ../glib/gfileutils.c:1093 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Ha fallau en escribir o fichero «%s»: ha fallau fflush(): %s" + +#: ../glib/gfileutils.c:1137 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Ha fallau en escribir o fichero «%s»: ha fallau fsync(): %s" + +#: ../glib/gfileutils.c:1161 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Ha fallau en zarrar o fichero «%s»: ha fallau fclose(): %s" + +#: ../glib/gfileutils.c:1282 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" +"O fichero existent «%s» no s'ha puesto eliminar: g_unlink() ha fallau: %s" + +#: ../glib/gfileutils.c:1556 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "A plantilla «%s» no ye valida, no habría de contener un «%s»" + +#: ../glib/gfileutils.c:1569 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "A plantilla «%s» no contién XXXXXX" + +#: ../glib/gfileutils.c:2097 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Ha fallau en leyer o vinclo simbolico «%s»: %s" + +#: ../glib/gfileutils.c:2118 +msgid "Symbolic links not supported" +msgstr "Vinclos simbolicos no suportaus" + +#: ../glib/giochannel.c:1418 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "No s'ha puesto ubrir o convertidor de «%s» a «%s»: %s" + +#: ../glib/giochannel.c:1763 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" +"No se puet fer una lectura en bruto (raw) en g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1810 ../glib/giochannel.c:2068 +#: ../glib/giochannel.c:2155 +msgid "Leftover unconverted data in read buffer" +msgstr "S'han deixau datos no convertius en o búfer de lectura" + +#: ../glib/giochannel.c:1891 ../glib/giochannel.c:1968 +msgid "Channel terminates in a partial character" +msgstr "A canal remata en un caracter parcial" + +#: ../glib/giochannel.c:1954 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "No se puet fer una lectura en bruto (raw) en g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:722 +msgid "Valid key file could not be found in search dirs" +msgstr "No s'ha puesto trobar a clau de fichero valida en as carpetas de busca" + +#: ../glib/gkeyfile.c:758 +msgid "Not a regular file" +msgstr "No ye un fichero regular" + +#: ../glib/gkeyfile.c:1158 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"O fichero de claus contién a linia «%s» que no ye un par valor-clau, grupo u " +"comentario" + +#: ../glib/gkeyfile.c:1215 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nombre de grupo no valido: %s" + +#: ../glib/gkeyfile.c:1237 +msgid "Key file does not start with a group" +msgstr "O fichero de claus no empecipia por un grupo" + +#: ../glib/gkeyfile.c:1263 +#, c-format +msgid "Invalid key name: %s" +msgstr "Nombre de clau no valida: %s" + +#: ../glib/gkeyfile.c:1290 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "O fichero de claus contién una codificación «%s» no suportada" + +#: ../glib/gkeyfile.c:1533 ../glib/gkeyfile.c:1695 ../glib/gkeyfile.c:3073 +#: ../glib/gkeyfile.c:3139 ../glib/gkeyfile.c:3265 ../glib/gkeyfile.c:3398 +#: ../glib/gkeyfile.c:3540 ../glib/gkeyfile.c:3770 ../glib/gkeyfile.c:3837 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "O fichero de claus no tien o grupo «%s»" + +#: ../glib/gkeyfile.c:1707 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "O fichero de claus no tien a clau «%s»" + +#: ../glib/gkeyfile.c:1814 ../glib/gkeyfile.c:1930 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"O fichero de claus contién a clau «%s» con a valor «%s» o qual no ye UTF-8" + +#: ../glib/gkeyfile.c:1834 ../glib/gkeyfile.c:1950 ../glib/gkeyfile.c:2319 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"O fichero de claus contién a clau «%s» que tien una valor que no se puet " +"interpretar." + +#: ../glib/gkeyfile.c:2536 ../glib/gkeyfile.c:2902 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"O fichero de claus contién a clau «%s» en o grupo «%s» que tien una valor " +"que no puet interpretar-se." + +#: ../glib/gkeyfile.c:2614 ../glib/gkeyfile.c:2690 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "A clau «%s» en o grupo «%s» tien a valor «%s», pero s'asperaba %s" + +#: ../glib/gkeyfile.c:3088 ../glib/gkeyfile.c:3280 ../glib/gkeyfile.c:3848 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "O fichero de claus no tien a clau «%s» en o grupo «%s»" + +#: ../glib/gkeyfile.c:4080 +msgid "Key file contains escape character at end of line" +msgstr "O fichero de claus contién un caracter d'escape a la fin d'a linia" + +#: ../glib/gkeyfile.c:4102 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "O fichero de claus contién a seqüencia d'escape no valida «%s»" + +#: ../glib/gkeyfile.c:4244 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "A valor «%s» no puet interpretar-se como un numero." + +#: ../glib/gkeyfile.c:4258 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "A valor entera «%s» ye difuera de rango" + +#: ../glib/gkeyfile.c:4291 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "A valor «%s» no puet interpretar-se como un numero de coma flotant." + +#: ../glib/gkeyfile.c:4315 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "A valor «%s» no puet interpretar-se como un booleano." + +#: ../glib/gmappedfile.c:130 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "" +"Ha fallau en obtener os atributos d'o fichero «%s%s%s%s»: fstat() ha fallau: " +"%s" + +#: ../glib/gmappedfile.c:196 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Ha fallau a lo mapeyar o fichero «%s%s%s%s»: mmap() falló: %s" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Ha fallau en ubrir o fichero «%s»: open() ha fallau: %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Bi ha una error en a linia %d, caracter %d: " + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Texto codificau como UTF-8 en o nombre no valido; «%s» no ye valido" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "«%s» no ye un nombre valido" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "«%s» no ye un nombre valido: «%c»" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "Bi ha una error en a linia %d: %s" + +#: ../glib/gmarkup.c:682 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Ha fallau en analisar «%-.*s», o qual habría de tener un dichito adentro " +"d'un caracter de referencia( por eixemplo &234;) - tal vegada o dichito ye " +"masiau gran" + +#: ../glib/gmarkup.c:694 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"O caracter de referencia no remata con punto y coma; prebablement has " +"utilizau un caracter «&» sin pretender encetar una entidat, escape o " +"caracter \"&\" como &" + +#: ../glib/gmarkup.c:720 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "O caracter de referencia «%-.*s» no codifica un caracter permitiu" + +#: ../glib/gmarkup.c:758 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"A entidat '&;' ye vueda; as entidatz validas son: & " < > " +"'" + +#: ../glib/gmarkup.c:766 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "O nombre d'a entidat «%-.*s» ye desconoixiu" + +#: ../glib/gmarkup.c:771 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"A entidat no remata con un punto y coma; prebablement has utilizau o " +"caracter \"&\" sin a intención d'indicar una entidat, escape u sinyal \"&\" " +"como &" + +#: ../glib/gmarkup.c:1119 +msgid "Document must begin with an element (e.g. )" +msgstr "O documento debe prencipiar con un elemento (por eixemplo: )" + +#: ../glib/gmarkup.c:1159 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"«%s» no ye un caracter valido a l'arreu d'o caracter '<'; no debe encetar un " +"nombre d'elemento" + +#: ../glib/gmarkup.c:1227 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Caracter «%s» impropio, s'asperaba un caracter «>» ta rematar a etiqueta " +"vueda de l'elemento «%s»" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Caracter «%s» impropio, s'asperaba o caracter '=' dimpués d'o nombre de " +"atributo «%s» de l'elemento «%s»" + +#: ../glib/gmarkup.c:1352 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Caracter «%s» impropio, s'asperaba un caracter '>' u '/' ta rematar a " +"etiqueta d'inicio de l'elemento «%s» u opcionalment un atributo; tal vegada " +"has utilizau un caracter que no ye valido en un nombre d'atributo" + +#: ../glib/gmarkup.c:1396 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Caracter «%s» impropio, s'asperaba una marca d'obridura de cometas dimpués " +"d'o sinyal igual en dar-le valor a l'atributo «%s» de l'elemento «%s»" + +#: ../glib/gmarkup.c:1529 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"«%s» no ye un caracter valido a l'arreu d'o nombre de l'elemento de zarre " +"«%s»; o caracter permitiu ye '>'" + +#: ../glib/gmarkup.c:1576 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "L'elemento «%s» ye estau zarrau, no existe garra elemento ubierto" + +#: ../glib/gmarkup.c:1585 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"S'ha zarrau l'elemento «%s», pero l'elemento que ye ubierto actualment ye " +"«%s»" + +#: ../glib/gmarkup.c:1753 +msgid "Document was empty or contained only whitespace" +msgstr "O documento yera vuedo u solament conteneba espacios en blanco" + +#: ../glib/gmarkup.c:1767 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "O documento remata inasperadament chusto dimpués d'un '<'" + +#: ../glib/gmarkup.c:1775 ../glib/gmarkup.c:1820 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"O documento remata inasperadament con elementos encara ubiertos - «%s» ye " +"estau o zaguer elemento ubierto" + +#: ../glib/gmarkup.c:1783 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"O documento remata inasperadament, s'asperaba un caracter '>' rematando a " +"etiqueta <%s/>" + +#: ../glib/gmarkup.c:1789 +msgid "Document ended unexpectedly inside an element name" +msgstr "O documento remata inasperadament adentro d'un nombre d'elemento" + +#: ../glib/gmarkup.c:1795 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "O documento remata inasperadament adentro d'un nombre d'atributo" + +#: ../glib/gmarkup.c:1800 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"O documento ha rematau inasperadament adentro d'una etiqueta d'obridura " +"d'elemento." + +#: ../glib/gmarkup.c:1806 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"O documento remata inasperadament dimpués d'os sinyals igual que siguen a lo " +"nombre d'atributo; sin valor d'atributo" + +#: ../glib/gmarkup.c:1813 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "O documento remata inasperadament adentro d'a valor d'un atributo" + +#: ../glib/gmarkup.c:1829 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"O documento remata inasperadament adentro d'a etiqueta de zarre de " +"l'elemento «%s»" + +#: ../glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"O documento remata inasperadament adentro d'un comentario u instrucción de " +"proceso" + +#: ../glib/goption.c:754 +msgid "Usage:" +msgstr "Uso:" + +#: ../glib/goption.c:754 +msgid "[OPTION...]" +msgstr "[OPCIÓN…]" + +#: ../glib/goption.c:870 +msgid "Help Options:" +msgstr "Opcions d'aduya:" + +#: ../glib/goption.c:871 +msgid "Show help options" +msgstr "Amostrar as opcions d'aduya" + +#: ../glib/goption.c:877 +msgid "Show all help options" +msgstr "Amuestra todas as opcions d'aduya" + +#: ../glib/goption.c:939 +msgid "Application Options:" +msgstr "Opcions de l'aplicación:" + +#: ../glib/goption.c:1003 ../glib/goption.c:1073 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "No se puet analisar a valor entera «%s» ta %s" + +#: ../glib/goption.c:1013 ../glib/goption.c:1081 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "A valor entera «%s» ta %s ye difuera de rango" + +#: ../glib/goption.c:1038 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "No se puet analisar a valor dople «%s» ta %s" + +#: ../glib/goption.c:1046 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "A valor dople «%s» ta %s ye difuera de rango" + +#: ../glib/goption.c:1309 ../glib/goption.c:1388 +#, c-format +msgid "Error parsing option %s" +msgstr "S'ha produciu una error en analisar a opción: %s" + +#: ../glib/goption.c:1419 ../glib/goption.c:1532 +#, c-format +msgid "Missing argument for %s" +msgstr "Falta un argumento ta %s" + +#: ../glib/goption.c:1985 +#, c-format +msgid "Unknown option %s" +msgstr "Opción desconoixida %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "obchecto corrupto" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "error interna u obchecto corrupto" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "Difuera de memoria" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "s'ha acotolau o limite de «backtracking»" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "o patrón contién elementos no suportaus ta una coincidencia parcial" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "no se suportan referencias anteriors como condicions ta coincidencias " + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "s'ha acotolau o limite de recursividad" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "combinación de banderas de nueva linia no validas" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "desplazamiento erronio" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "UTF8 curto" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "bucle de repetición" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "error desconoixida" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ a la fin d'o patrón" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c a la fin d'o patrón" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "caracter no reconoixiu dimpués de \\" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "numeros difuera de rango en o quantificador {}" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "numero masiau gran en o quantificador {}" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "falta la rematanza ] ta la clase de caracter" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "seqüencia d'escape no valida en a clase de caracter" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "rango difuera d'orden en a clase de caracter" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "Pon que repetir" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "repetición inasperada" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "caracter no reconoixiu dimpués de (? u (?-" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "Solament se suportan as clases con nombres POSIX dentro d'una clase" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "falta lo ) de rematanza" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "referencia a un subpatrón no existent" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "falta ) dimpués d'o comentario" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "a expresión regular ye masiau luenga" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "ha fallau en obtener memoria" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr ") sin ( que lo ubrise" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "desbordamiento de codigo" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "caracter no reconoixiu dimpués de (?<" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "a comprebación «lookbehind» no tien una longaria fixa" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "numero u nombre mal formau dimpués de (?(" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "o grupo condicional contién mas de dos ramas" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "s'asperaba una comprebación dimpués de (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R u os dichitos (?[+-] han d'estar seguius por )" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "nombre de clase POSIX desconoixiu" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "os elementos POSIX recopilaus no son suportaus" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "a valor d'o caracter en la seqüencia \\x{…} ye masiau luengo" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "condición no valida (?(0)" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "no se permite \\C en comprebacions «lookbehind»" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" +"as seqüencias d'escape \\L, \\l, \\N{nombre}, \\U, y \\u no son suportadas" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "una clamada recursiva podrá creyar un bucle infinito" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "caracter no reconoixiu dimpués de (?P" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "falta o terminador en o nombre d'o subpatrón" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "dos subpatrons tienen o mesmo nombre" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "seqüencia \\P u \\p mal formada" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "nombre de propiedat desconoixiu dimpués de \\P u \\p" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "o nombre d'o subpatrón ye masiau luengo (maximo 32 caracters)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "masiaus subpatrons con nombre (maximo 10.000)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "a valor octal ye mayor que \\377" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "se sobreixió o espacio de treballo de compilación" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "no s'ha trobau o subpatrón referenciau anteriorment comprebau" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "o grupo DEFINE contién mas d'una rama" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "opcions NEWLINE inconsistents" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g no ye siguiu por un nombre entre claus, corchetes angulars u numero u " +"entre cometas, u por un numero simple" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "una referencia con numero no puet estar zero" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "no se permite un argumento ta (*ACCEPT), (*FAIL), u (*COMMIT)" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) no reconoixiu" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "o numero ye masiau gran" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "falta l'o nombre d'o subpatrón dimpués de (?&" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "s'asperaba un dichito dimpués de (?+" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] ye un caracter de datos no valido en o modo de compatibilidat de Javascript" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "no se permiten diferents nombres ta subpatrons d'o mesmo numero" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) debe tener un argumento" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c debe estar siguiu d'un caracter ASCII" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k no ye siguiu por un nombre entre claus, gafetz angulars u entre cometas" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "\\N no ye suportau en una clase" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "masiadas referencias enta debant" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "o nombre ye masiau luengo en (*MARK), (*PRUNE), (*SKIP), u (*THEN)" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "a valor d'o caracter en a seqüencia \\u{…} ye masiau luenga" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1899 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "S'ha produciu una error en coincidir con a expresión regular %s: %s" + +#: ../glib/gregex.c:1319 +msgid "PCRE library is compiled without UTF8 support" +msgstr "A biblioteca PCRE ye compilada sin suporte ta UTF8" + +#: ../glib/gregex.c:1323 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "A biblioteca PCRE ye compilada sin suporte ta las propiedatz de UTF8" + +#: ../glib/gregex.c:1331 +msgid "PCRE library is compiled with incompatible options" +msgstr "A biblioteca PCRE ye compilada con opcions incompatibles" + +#: ../glib/gregex.c:1390 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"S'ha produciu una error en compilar a expresión regular %s en o caracter %d: " +"%s" + +#: ../glib/gregex.c:1432 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "S'ha produciu una error en optimizar a expresión regular %s: %s" + +#: ../glib/gregex.c:2331 +msgid "hexadecimal digit or '}' expected" +msgstr "s'asperaba un dichito hexadecimal u «}»" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit expected" +msgstr "s'asperaba un dichito hexadecimal" + +#: ../glib/gregex.c:2387 +msgid "missing '<' in symbolic reference" +msgstr "falta «<» en a referencia simbolica" + +#: ../glib/gregex.c:2396 +msgid "unfinished symbolic reference" +msgstr "referencia de simbolo sin rematar" + +#: ../glib/gregex.c:2403 +msgid "zero-length symbolic reference" +msgstr "referencia simbolica de longaria zero" + +#: ../glib/gregex.c:2414 +msgid "digit expected" +msgstr "s'asperaba un dichito" + +#: ../glib/gregex.c:2432 +msgid "illegal symbolic reference" +msgstr "referencia simbolica ilegal" + +#: ../glib/gregex.c:2494 +msgid "stray final '\\'" +msgstr "«\\» a la fin d'a cadena" + +#: ../glib/gregex.c:2498 +msgid "unknown escape sequence" +msgstr "seqüencia d'escape desconoixida" + +#: ../glib/gregex.c:2508 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" +"S'ha produciu una error en analisar o texto de substitución «%s» en o " +"caracter %lu: %s" + +#: ../glib/gshell.c:88 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "O texto entre cometas no empecipia por un signo de cometa" + +#: ../glib/gshell.c:178 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Falta una cometa en a linia de comandos u en unatro texto con cometas mena " +"shell" + +#: ../glib/gshell.c:574 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "O texto remata chusto dimpués d'un caracter '\\'. (O texto yera «%s»)" + +#: ../glib/gshell.c:581 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"O texto ha rematau antes que se trobase a cometa correspondient con %c. (O " +"texto yera «%s»)" + +#: ../glib/gshell.c:593 +msgid "Text was empty (or contained only whitespace)" +msgstr "O texto ye vuedo (u no contién que espacios en blanco)" + +#: ../glib/gspawn.c:202 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Ha fallau en a lectura de datos dende o proceso fillo (%s)" + +#: ../glib/gspawn.c:345 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"S'ha produciu un fallo inasperau en select() leyendo datos dende o proceso " +"fillo (%s)" + +#: ../glib/gspawn.c:430 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "O proceso fillo ha rematau con o codigo %ld" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "O proceso fillo rematau por o sinyal %ld" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "O proceso fillo ye estau aturau por o sinyal %ld" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "O proceso fillo HA REMATAU de TRAZA anormal" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Ha fallau en leyer dende o conducto fillo (%s)" + +#: ../glib/gspawn.c:1344 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Ha fallau a lo bifurcar (fork) (%s)" + +#: ../glib/gspawn.c:1492 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Ha fallau en cambiar ta la carpeta «%s» (%s)" + +#: ../glib/gspawn.c:1502 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Ha fallau en executar o proceso fillo «%s» (%s)" + +#: ../glib/gspawn.c:1512 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Ha fallau en reendrezar a salida u a dentrada d'o proceso fillo (%s)" + +#: ../glib/gspawn.c:1521 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Ha fallau a lo bifurcar o proceso fillo (%s)" + +#: ../glib/gspawn.c:1529 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "S'ha produciu un fallo desconoixiu en executar o proceso fillo «%s»" + +#: ../glib/gspawn.c:1553 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Ha fallau en leyer suficients datos dende o conducto d'o pid fillo (%s)" + +#: ../glib/gspawn.c:1626 ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Ha fallau en a creyación d'un conducto (pipe) ta comunicar-se con o proceso " +"fillo (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "Ha fallau en leyer os datos dende un proceso fillo" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Ha fallau en executar o proceso fillo (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nombre de programa no valido: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Cadena no valida en o vector de l'argumento en %d: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Cadena no valida en l'entorno: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Carpeta de treballo no valido: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Ha fallau en executar o programa auxiliar (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"S'ha produciu un fallo inasperau en g_io_channel_win32_poll() en leyer datos " +"dende un proceso fillo" + +#: ../glib/gutf8.c:907 +msgid "Character out of range for UTF-8" +msgstr "O caracter se sale d'o rango ta UTF-8" + +#: ../glib/gutf8.c:1007 ../glib/gutf8.c:1016 ../glib/gutf8.c:1146 +#: ../glib/gutf8.c:1155 ../glib/gutf8.c:1294 ../glib/gutf8.c:1390 +msgid "Invalid sequence in conversion input" +msgstr "Seqüencia no valida en a dentrada de conversión" + +#: ../glib/gutf8.c:1305 ../glib/gutf8.c:1401 +msgid "Character out of range for UTF-16" +msgstr "O caracter se sale d'o rango ta UTF-16" + +#: ../glib/gutils.c:2183 ../glib/gutils.c:2210 ../glib/gutils.c:2314 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: ../glib/gutils.c:2189 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2191 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2194 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2197 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2200 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2203 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2216 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2219 ../glib/gutils.c:2332 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2222 ../glib/gutils.c:2337 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2224 ../glib/gutils.c:2342 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2227 ../glib/gutils.c:2347 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2230 ../glib/gutils.c:2352 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2267 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2327 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "Chinero" + +msgctxt "full month name with day" +msgid "February" +msgstr "Febrero" + +msgctxt "full month name with day" +msgid "March" +msgstr "Marzo" + +msgctxt "full month name with day" +msgid "April" +msgstr "Abril" + +msgctxt "full month name with day" +msgid "May" +msgstr "Mayo" + +msgctxt "full month name with day" +msgid "June" +msgstr "Chunio" + +msgctxt "full month name with day" +msgid "July" +msgstr "Chulio" + +msgctxt "full month name with day" +msgid "August" +msgstr "Agosto" + +msgctxt "full month name with day" +msgid "September" +msgstr "Setiembre" + +msgctxt "full month name with day" +msgid "October" +msgstr "Octubre" + +msgctxt "full month name with day" +msgid "November" +msgstr "Noviembre" + +msgctxt "full month name with day" +msgid "December" +msgstr "Aviento" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Chi" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Abr" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "May" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Chn" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Chl" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ago" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Set" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Oct" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Abi" diff --git a/po/ar.po b/po/ar.po new file mode 100644 index 0000000..2854e45 --- /dev/null +++ b/po/ar.po @@ -0,0 +1,4275 @@ +# translation of glib.HEAD.po to Arabic +# translation of glib.po to +# Copyright (C) 2001,2002,2003, 2006, 2007, 2008 Free Software Foundation, Inc. +# Isam Bayazidi , 2001,2002. +# Arafat Medini , 2003. +# Djihed Afifi , 2006, 2007. +# Khaled Hosny , 2006, 2007, 2008, 2010, 2011, 2012. +# Anas Afif Emad , 2008. +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-13 21:00+0200\n" +"PO-Revision-Date: 2012-06-13 21:00+0200\n" +"Last-Translator: Khaled Hosny \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" +"X-Generator: Virtaal 0.7.0\n" + +#: ../gio/gbufferedinputstream.c:427 ../gio/gbufferedinputstream.c:508 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:376 +#: ../gio/ginputstream.c:615 ../gio/ginputstream.c:854 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:800 +#: ../gio/gpollableinputstream.c:207 ../gio/gpollableoutputstream.c:208 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Ù…ÙØ±Ù‘ÙØ±Øª قيمة كبيرة جدّا إلى %s" + +#: ../gio/gbufferedinputstream.c:909 ../gio/gbufferedoutputstream.c:581 +#: ../gio/gdataoutputstream.c:568 +msgid "Seek not supported on base stream" +msgstr "عملية السعي غير Ù…ÙØ¯Ø¹Ù…Ø© على الدَÙÙ‚ الأساسي" + +#: ../gio/gbufferedinputstream.c:955 +msgid "Cannot truncate GBufferedInputStream" +msgstr "تعذر بَتْر٠GBufferedInputStream" + +#: ../gio/gbufferedinputstream.c:1000 ../gio/ginputstream.c:1062 +#: ../gio/giostream.c:292 ../gio/goutputstream.c:1385 +msgid "Stream is already closed" +msgstr "سبق إغلاق الدَÙÙ‚ " + +#: ../gio/gbufferedoutputstream.c:618 ../gio/gdataoutputstream.c:598 +msgid "Truncate not supported on base stream" +msgstr "البَتْر٠غير مدعم على الدَÙÙ‚ الأساسي" + +#: ../gio/gcancellable.c:318 ../gio/gdbusconnection.c:1885 +#: ../gio/gdbusconnection.c:1977 ../gio/gdbusprivate.c:1414 +#: ../gio/glocalfile.c:2133 ../gio/gsimpleasyncresult.c:833 +#: ../gio/gsimpleasyncresult.c:859 +#, c-format +msgid "Operation was cancelled" +msgstr "Ø£Ùلغيت العملية " + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "سلسلة بايتات غير سليمة ÙÙŠ الدخْل" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "لا يوجد مساحة كاÙية ÙÙŠ Ø§Ù„ÙˆÙØ¬Ù‡Ø©" + +#: ../gio/gcharsetconverter.c:345 ../gio/gdatainputstream.c:854 +#: ../gio/gdatainputstream.c:1294 ../glib/gconvert.c:768 +#: ../glib/gconvert.c:1160 ../glib/giochannel.c:1583 ../glib/giochannel.c:1625 +#: ../glib/giochannel.c:2468 ../glib/gutf8.c:841 ../glib/gutf8.c:1292 +msgid "Invalid byte sequence in conversion input" +msgstr "سلسلة بايتات غير سليمة ÙÙŠ دخْل التحويل" + +#: ../gio/gcharsetconverter.c:350 ../glib/gconvert.c:776 +#: ../glib/gconvert.c:1085 ../glib/giochannel.c:1590 ../glib/giochannel.c:2480 +#, c-format +msgid "Error during conversion: %s" +msgstr "خطأ أثناء التحويل: %s" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:959 +msgid "Cancellable initialization not supported" +msgstr "الاستبداء القابل للإلغاء غير مدعوم" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:568 +#: ../glib/gconvert.c:646 ../glib/giochannel.c:1411 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "التحويل من مجموعة المحار٠'%s' إلى '%s' غير مدعوم" + +#: ../gio/gcharsetconverter.c:462 ../glib/gconvert.c:572 +#: ../glib/gconvert.c:650 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "تعذّر ÙØªØ­ Ø§Ù„Ù…ÙØ­ÙˆÙ‘ÙÙ„ من '%s' إلى '%s'" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "نوع مجهول" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "نوع ملÙÙ‘ %s" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "نوع %s" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "لم ØªÙØ·Ø¨Ù‚ GCredentials لهذا النظام" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "لم تدعم GCredentials على هذه المنصة" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "نهاية دَÙÙ‚ غير متوقّعة وغير متوقعة " + +#: ../gio/gdbusaddress.c:150 ../gio/gdbusaddress.c:238 +#: ../gio/gdbusaddress.c:319 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:177 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:190 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:253 ../gio/gdbusaddress.c:334 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:264 ../gio/gdbusaddress.c:345 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:454 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:475 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:489 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:567 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:603 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:617 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:631 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:652 +msgid "Error auto-launching: " +msgstr "" + +#: ../gio/gdbusaddress.c:660 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:696 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:714 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:723 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "" + +#: ../gio/gdbusaddress.c:741 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "" + +#: ../gio/gdbusaddress.c:960 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1029 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1066 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "" + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1091 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1312 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: ../gio/gdbusaddress.c:1437 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: ../gio/gdbusaddress.c:1458 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1557 ../gio/gdbusconnection.c:6755 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1566 ../gio/gdbusconnection.c:6764 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1576 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:298 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:342 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:513 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1174 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:597 ../gio/gdbusconnection.c:2440 +msgid "The connection is closed" +msgstr "الاتصال مغلق" + +#: ../gio/gdbusconnection.c:1930 +msgid "Timeout was reached" +msgstr "انتهت المهلة" + +#: ../gio/gdbusconnection.c:2562 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:4065 ../gio/gdbusconnection.c:4381 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4136 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4231 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4243 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:4254 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4324 ../gio/gdbusconnection.c:6198 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4508 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4726 ../gio/gdbusconnection.c:6704 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4781 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4812 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5032 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:5230 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:6309 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6428 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1325 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: ../gio/gdbusmessage.c:1483 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1510 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1712 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1769 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1783 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1814 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: ../gio/gdbusmessage.c:1824 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2156 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2297 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2305 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2349 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2359 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2375 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2932 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2940 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:2062 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "" + +#: ../gio/gdbusprivate.c:2107 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1640 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1663 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2763 ../gio/gdbusproxy.c:2900 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "" + +#: ../gio/gdbusserver.c:1041 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1081 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, c-format +msgid "Error: %s\n" +msgstr "خطأ: %s\n" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, c-format +msgid "Error connecting: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:646 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:698 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:581 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "غير مسمّى" + +#: ../gio/gdesktopappinfo.c:994 +msgid "Desktop file didn't specify Exec field" +msgstr "مل٠سطح المكتب لم يحدد الحقل التنÙيدي" + +#: ../gio/gdesktopappinfo.c:1282 +msgid "Unable to find terminal required for application" +msgstr "تعذّر إيجاد الطرÙية المطلوبة للتطبيق" + +#: ../gio/gdesktopappinfo.c:1570 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "تعذّر إنشاء مجلد التهيئة الخاص بتطبيق المستخدم %s: â€%s" + +#: ../gio/gdesktopappinfo.c:1574 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "لا يمكن إنشاء مجلد التهيئة MIME %s للمستخدم: %s" + +#: ../gio/gdesktopappinfo.c:1814 ../gio/gdesktopappinfo.c:1838 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2071 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "لا يمكن إنشاء المل٠%s" + +#: ../gio/gdesktopappinfo.c:2193 +#, c-format +msgid "Custom definition for %s" +msgstr "تعري٠مخصص Ù„Ù %s" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "محرك الأقراص لا يدعم الإخراج" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "محرك الأقراص لا يدعم eject أو eject_with_operation" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "محرك الأقراص لا يدعم جسّ الوسائط" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "محرك الأقراص لا يدعم البدء" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "محرك الأقراص لا يدعم الإيقاÙ" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:367 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:377 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:400 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:874 ../gio/gfile.c:1105 ../gio/gfile.c:1240 +#: ../gio/gfile.c:1477 ../gio/gfile.c:1531 ../gio/gfile.c:1588 +#: ../gio/gfile.c:1671 ../gio/gfile.c:1726 ../gio/gfile.c:1786 +#: ../gio/gfile.c:1840 ../gio/gfile.c:3312 ../gio/gfile.c:3366 +#: ../gio/gfile.c:3511 ../gio/gfile.c:3552 ../gio/gfile.c:3882 +#: ../gio/gfile.c:4284 ../gio/gfile.c:4370 ../gio/gfile.c:4459 +#: ../gio/gfile.c:4557 ../gio/gfile.c:4644 ../gio/gfile.c:4738 +#: ../gio/gfile.c:5059 ../gio/gfile.c:5326 ../gio/gfile.c:5391 +#: ../gio/gfile.c:7018 ../gio/gfile.c:7108 ../gio/gfile.c:7194 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "عمليّة غير مدعومة" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1361 ../gio/glocalfile.c:1070 ../gio/glocalfile.c:1081 +#: ../gio/glocalfile.c:1094 +msgid "Containing mount does not exist" +msgstr "الوصل الحاوي غير موجود" + +#: ../gio/gfile.c:2414 ../gio/glocalfile.c:2289 +msgid "Can't copy over directory" +msgstr "لا يمكنك نقل دليل على دليل" + +#: ../gio/gfile.c:2475 +msgid "Can't copy directory over directory" +msgstr "لا يمكنك نسخ دليل على دليل" + +#: ../gio/gfile.c:2483 ../gio/glocalfile.c:2298 +msgid "Target file exists" +msgstr "المل٠الهد٠موجود مسبّقا" + +#: ../gio/gfile.c:2501 +msgid "Can't recursively copy directory" +msgstr " لا يمكنك النسخ التكراري للدليل " + +#: ../gio/gfile.c:2761 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2765 +#, c-format +msgid "Error splicing file: %s" +msgstr "" + +#: ../gio/gfile.c:2912 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3501 +msgid "Invalid symlink value given" +msgstr "قيمة الوصلة الرمزية Ø§Ù„Ù…ÙØ¹Ø·Ø§Ø© غير سليمة" + +#: ../gio/gfile.c:3595 +msgid "Trash not supported" +msgstr "المهملات غير مدعومة" + +#: ../gio/gfile.c:3644 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "لا يمكن لأسماء Ø§Ù„Ù…Ù„ÙØ§Øª أن تحتوي على '%c' " + +#: ../gio/gfile.c:6077 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "الجهاز لا ÙŠÙ†ÙØ° الوَصل" + +#: ../gio/gfile.c:6188 +msgid "No application is registered as handling this file" +msgstr "لم يسجل أي تطبيق كمعالج لهذا الملÙ" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "Ø§Ù„Ù…ÙØ¹Ø¯Ù‘ÙØ¯ مغلق" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "Ù…ÙØ¹Ø¯Ø¯ المل٠له عملية عالقة" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "Ù…ÙØ¹Ø¯Ø¯ المل٠سبق إغلاقه" + +#: ../gio/gfileicon.c:237 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:247 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "الدَÙÙ‚ لا يدعم query_info" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "عملية السعي البحث غير Ù…ÙØ¯Ø¹Ù…Ø© على الدَÙÙ‚" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "البَتْر٠غير مسموح به على دَÙÙ‚ الإدخال" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "البَتْر٠غير مدعم على الدَÙÙ‚" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:428 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginetaddressmask.c:184 +msgid "No address specified" +msgstr "" + +#: ../gio/ginetaddressmask.c:192 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: ../gio/ginetaddressmask.c:225 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: ../gio/ginetaddressmask.c:304 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "" + +#: ../gio/ginetsocketaddress.c:206 ../gio/ginetsocketaddress.c:223 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:238 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "دَÙÙ‚ الإدخال لا ÙŠÙÙ†ÙŽÙØ° القراءة" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1072 ../gio/giostream.c:302 +#: ../gio/goutputstream.c:1395 +msgid "Stream has outstanding operation" +msgstr " للدَÙÙ‚ عملية عالقة" + +#: ../gio/glib-compile-resources.c:144 ../gio/glib-compile-schemas.c:1455 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:148 ../gio/glib-compile-schemas.c:1459 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-resources.c:238 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:251 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "" + +#: ../gio/glib-compile-resources.c:262 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "" + +#: ../gio/glib-compile-resources.c:291 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "" + +#: ../gio/glib-compile-resources.c:309 ../gio/glib-compile-resources.c:368 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:338 +#, c-format +msgid "" +"Error processing input file with xmllint:\n" +"%s" +msgstr "" + +#: ../gio/glib-compile-resources.c:394 +#, c-format +msgid "" +"Error processing input file with to-pixdata:\n" +"%s" +msgstr "" + +#: ../gio/glib-compile-resources.c:408 +#, c-format +msgid "Error reading file %s: %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:428 +#, c-format +msgid "Error compressing file %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:492 ../gio/glib-compile-schemas.c:1567 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:615 +msgid "name of the output file" +msgstr "" + +#: ../gio/glib-compile-resources.c:615 ../gio/glib-compile-resources.c:648 +#: ../gio/gresource-tool.c:477 ../gio/gresource-tool.c:543 +msgid "FILE" +msgstr "" + +#: ../gio/glib-compile-resources.c:616 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" + +#: ../gio/glib-compile-resources.c:616 ../gio/glib-compile-schemas.c:1995 +#: ../gio/glib-compile-schemas.c:2025 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-resources.c:617 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: ../gio/glib-compile-resources.c:618 +msgid "Generate source header" +msgstr "" + +#: ../gio/glib-compile-resources.c:619 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" + +#: ../gio/glib-compile-resources.c:620 +msgid "Generate dependency list" +msgstr "" + +#: ../gio/glib-compile-resources.c:621 +msgid "Don't automatically create and register resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:622 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: ../gio/glib-compile-resources.c:651 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: ../gio/glib-compile-resources.c:667 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:774 +msgid "empty names are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:784 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:796 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:805 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:814 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:822 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:891 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:917 +msgid "cannot add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:928 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:946 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:957 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:976 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:991 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1021 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1034 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1042 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1113 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1125 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1141 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1149 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1159 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1169 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1179 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1203 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1235 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1753 ../gio/glib-compile-schemas.c:1824 +#: ../gio/glib-compile-schemas.c:1900 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1761 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1820 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1860 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1866 ../gio/glib-compile-schemas.c:1924 +#: ../gio/glib-compile-schemas.c:1952 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1870 ../gio/glib-compile-schemas.c:1928 +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1886 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1896 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1914 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1998 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:2044 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2083 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2086 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2089 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "تعذّر ايجاد نوع المراقبة للدليل المحلي Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ " + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "اسم مل٠غير صالح %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "خطأ أثناء تلقي معلومات نظام Ø§Ù„Ù…Ù„ÙØ§Øª: %s" + +#: ../gio/glocalfile.c:1116 +msgid "Can't rename root directory" +msgstr " لا يمكنك إعادة تسمية الدليل الجذري " + +#: ../gio/glocalfile.c:1136 ../gio/glocalfile.c:1162 +#, c-format +msgid "Error renaming file: %s" +msgstr "خطأ عند إعادة تسمية الملÙ: %s" + +#: ../gio/glocalfile.c:1145 +msgid "Can't rename file, filename already exists" +msgstr "لا يمكنك إعادة تسمية Ø§Ù„Ù…Ù„ÙØŒ اسم المل٠موجود Ø¨Ø§Ù„ÙØ¹Ù„" + +#: ../gio/glocalfile.c:1158 ../gio/glocalfile.c:2162 ../gio/glocalfile.c:2191 +#: ../gio/glocalfile.c:2351 ../gio/glocalfileoutputstream.c:581 +#: ../gio/glocalfileoutputstream.c:634 ../gio/glocalfileoutputstream.c:679 +#: ../gio/glocalfileoutputstream.c:1167 +msgid "Invalid filename" +msgstr "اسم مل٠غير صالح" + +#: ../gio/glocalfile.c:1325 ../gio/glocalfile.c:1349 +msgid "Can't open directory" +msgstr "لا يمكن ÙØªØ­ الدّليل" + +#: ../gio/glocalfile.c:1333 +#, c-format +msgid "Error opening file: %s" +msgstr "خطأ عند ÙØªØ­ الملÙ: %s" + +#: ../gio/glocalfile.c:1474 +#, c-format +msgid "Error removing file: %s" +msgstr "خطأ عند حذ٠الملÙ: %s" + +#: ../gio/glocalfile.c:1841 +#, c-format +msgid "Error trashing file: %s" +msgstr "خطأ عند ارسال المل٠للمهملات: %s" + +#: ../gio/glocalfile.c:1864 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "تعذّر إنشاء مجلد سلة المهملات %s: â€%s" + +#: ../gio/glocalfile.c:1885 +msgid "Unable to find toplevel directory for trash" +msgstr "تعذّر إيجاد دليل المستوى الأعلى للمهملات" + +#: ../gio/glocalfile.c:1964 ../gio/glocalfile.c:1984 +msgid "Unable to find or create trash directory" +msgstr "تعذّر ايجاد أو إنشاء دليل المهملات" + +#: ../gio/glocalfile.c:2018 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "تعذّر إنشاء مل٠المÙهْملات: %s" + +#: ../gio/glocalfile.c:2047 ../gio/glocalfile.c:2052 ../gio/glocalfile.c:2132 +#: ../gio/glocalfile.c:2139 +#, c-format +msgid "Unable to trash file: %s" +msgstr "تعذّر نقل الملÙ: %s إلى المهملات " + +#: ../gio/glocalfile.c:2140 ../glib/gregex.c:213 +msgid "internal error" +msgstr "خطأ داخلي" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error creating directory: %s" +msgstr "خطأ أثناء إنشاء الدليل: %s" + +#: ../gio/glocalfile.c:2195 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "لا يدعم نظام Ø§Ù„Ù…Ù„ÙØ§Øª الوصلات الرمزية." + +#: ../gio/glocalfile.c:2199 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "خطأ أثناء تشكيل الوصلة الرمزية: %s" + +#: ../gio/glocalfile.c:2261 ../gio/glocalfile.c:2355 +#, c-format +msgid "Error moving file: %s" +msgstr "خطأ عندنقل الملÙ: %s" + +#: ../gio/glocalfile.c:2284 +msgid "Can't move directory over directory" +msgstr "لا يمكنك نقل دليل على دليل" + +#: ../gio/glocalfile.c:2311 ../gio/glocalfileoutputstream.c:965 +#: ../gio/glocalfileoutputstream.c:979 ../gio/glocalfileoutputstream.c:994 +#: ../gio/glocalfileoutputstream.c:1010 ../gio/glocalfileoutputstream.c:1024 +msgid "Backup file creation failed" +msgstr "ÙØ´Ù„ إنشاء مل٠النسخة الاحتياطية" + +#: ../gio/glocalfile.c:2330 +#, c-format +msgid "Error removing target file: %s" +msgstr "خطأ ÙÙŠ إزالة المل٠الهدÙ: %s" + +#: ../gio/glocalfile.c:2344 +msgid "Move between mounts not supported" +msgstr "النقل بين الوصلات غير مدعوم" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "قيمة الخاصية لا بد أن تكون غير منعدمة" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "نوع الخاصية غير سليم ( ÙŠÙÙØªØ±Ø¶ أن يكون مقطعا )" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "اسم غير سليم للخاصية الممتدة" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "خطأ عند ضبط الخاصية الممتدة '%s'â€: %s" + +#: ../gio/glocalfileinfo.c:1426 +msgid " (invalid encoding)" +msgstr " (ترميز غير سليم)" + +#: ../gio/glocalfileinfo.c:1527 ../gio/glocalfileoutputstream.c:843 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "خطأ عند جلب معلومات المل٠'%s': %s" + +#: ../gio/glocalfileinfo.c:1779 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "خطأ عند جلب معلومات الملÙ: %s" + +#: ../gio/glocalfileinfo.c:1824 +msgid "Invalid attribute type (uint32 expected)" +msgstr "نوع الخاصية غير سليم ( ÙŠÙÙØªØ±Ø¶ uint32 )" + +#: ../gio/glocalfileinfo.c:1842 +msgid "Invalid attribute type (uint64 expected)" +msgstr "نوع الخاصية غير سليم ( ÙŠÙÙØªØ±Ø¶ uint64 )" + +#: ../gio/glocalfileinfo.c:1861 ../gio/glocalfileinfo.c:1880 +msgid "Invalid attribute type (byte string expected)" +msgstr "نوع الخاصية غير سليم ( ÙŠÙنتضر مقطع بايت )" + +#: ../gio/glocalfileinfo.c:1915 +msgid "Cannot set permissions on symlinks" +msgstr "لا يمكن ضبط صلاحيات الوصلات الرمزية" + +#: ../gio/glocalfileinfo.c:1931 +#, c-format +msgid "Error setting permissions: %s" +msgstr "خطأ ضبط الصلاحيات: %s" + +#: ../gio/glocalfileinfo.c:1982 +#, c-format +msgid "Error setting owner: %s" +msgstr "خطأ ضبط المالك: %s" + +#: ../gio/glocalfileinfo.c:2005 +msgid "symlink must be non-NULL" +msgstr "يجب أن يكون Ùهرس القائمة غير سلبي" + +#: ../gio/glocalfileinfo.c:2015 ../gio/glocalfileinfo.c:2034 +#: ../gio/glocalfileinfo.c:2045 +#, c-format +msgid "Error setting symlink: %s" +msgstr "خطأ أثناء ضبط الوصلة الرمزية: %s" + +#: ../gio/glocalfileinfo.c:2024 +msgid "Error setting symlink: file is not a symlink" +msgstr "خطأ ÙÙŠ ضبط الوصلة الرمزية: المل٠ليس وصلة رمزية" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2173 +msgid "SELinux context must be non-NULL" +msgstr "يجب ألا يكون سياق SELinux ØµÙØ±Ø§" + +#: ../gio/glocalfileinfo.c:2188 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "خطأ ÙÙŠ ضبط سياق SELinux: â€%s" + +#: ../gio/glocalfileinfo.c:2195 +msgid "SELinux is not enabled on this system" +msgstr "â€SELinux ليس Ù…ÙØ¹Ù„ا على هذا النظام" + +#: ../gio/glocalfileinfo.c:2287 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "ضبط Ø§Ù„ØµÙØ© %s غير Ù…ÙØ¯ÙŽØ¹Ù‘ÙŽÙ…" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:732 +#, c-format +msgid "Error reading from file: %s" +msgstr "خطأ أثناء القراءة من الملÙ: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1042 +#, c-format +msgid "Error seeking in file: %s" +msgstr "خطأ أثناء ØªØµÙØ­ الملÙ: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "خطأ عند غلق الملÙ: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "تعذّر إيجاد نوع المراقبة للمل٠المحلي Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ " + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:753 +#, c-format +msgid "Error writing to file: %s" +msgstr "خطأ ÙÙŠ الكتابة للملÙ: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "خطأ أثناء إزالة وصلة النسخة الاحتياطية القديمة: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "خطأ أثناء إنشاء النسخة الاحتياطية: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "خطأ عند إعادة تسمية المل٠المؤقت: %s " + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1093 +#, c-format +msgid "Error truncating file: %s" +msgstr "خطأ أثناء بَتْر الملÙ: %s " + +#: ../gio/glocalfileoutputstream.c:587 ../gio/glocalfileoutputstream.c:640 +#: ../gio/glocalfileoutputstream.c:685 ../gio/glocalfileoutputstream.c:825 +#: ../gio/glocalfileoutputstream.c:1074 ../gio/glocalfileoutputstream.c:1173 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "خطأ عند ÙØªØ­ المل٠'%s'â€: %s " + +#: ../gio/glocalfileoutputstream.c:856 +msgid "Target file is a directory" +msgstr "المل٠الهد٠هو دليل" + +#: ../gio/glocalfileoutputstream.c:861 +msgid "Target file is not a regular file" +msgstr "المل٠الهد٠هو ليس ملÙًا عاديًا" + +#: ../gio/glocalfileoutputstream.c:873 +msgid "The file was externally modified" +msgstr "تمّ تعديل المل٠خارجيّا" + +#: ../gio/glocalfileoutputstream.c:1058 +#, c-format +msgid "Error removing old file: %s" +msgstr "خطأ عند حذ٠المل٠القديم: %s" + +#: ../gio/gmemoryinputstream.c:483 ../gio/gmemoryoutputstream.c:734 +msgid "Invalid GSeekType supplied" +msgstr "تم تقديم GSeekType غير سليم" + +#: ../gio/gmemoryinputstream.c:493 +msgid "Invalid seek request" +msgstr "طلب بحث غير سليم" + +#: ../gio/gmemoryinputstream.c:517 +msgid "Cannot truncate GMemoryInputStream" +msgstr "تعذر بَتْر٠GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:530 +msgid "Memory output stream not resizable" +msgstr "دَÙْق٠الاخراج للذاكرة غير قابل لتغيير القياس" + +#: ../gio/gmemoryoutputstream.c:546 +msgid "Failed to resize memory output stream" +msgstr "ÙØ´Ù„ تغيير قياس دَÙْق٠الاخراج للذاكرة" + +#: ../gio/gmemoryoutputstream.c:634 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:744 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:753 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "نقطة الوصل لا تدعم \"Ø§Ù„ÙØµÙ„\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "نقطة الوصْل لا تدعم \"الإخراج\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "نقطة الوصل لا تدعم \"unmount\" أو \"unmount_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "نقطة الوصل لا تدعم \"eject\" أو \"eject_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "نقطة الوصل لا تدعم \"إعادة الوصل\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "نقطة الوصل لا تدعم تخمين نوع المحتوى" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "نقطة الوصل لا تدعم التخمين المتزامن لنوع المحتوى" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "يحتوي اسم المستضي٠'%s' '[' لكن لا ']'" + +#: ../gio/gnetworkmonitorbase.c:178 +msgid "Network unreachable" +msgstr "" + +#: ../gio/gnetworkmonitorbase.c:218 +msgid "Host unreachable" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:97 ../gio/gnetworkmonitornetlink.c:109 +#: ../gio/gnetworkmonitornetlink.c:120 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:129 +msgid "Could not create network monitor: " +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:177 +msgid "Could not get network status: " +msgstr "" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:464 +msgid "Output stream doesn't implement write" +msgstr "دَÙْق٠الاخراج لا يدعم الكتابة" + +#: ../gio/goutputstream.c:425 ../gio/goutputstream.c:1033 +msgid "Source stream is already closed" +msgstr "دَÙْق٠المَصدر سبق إغلاقه" + +#: ../gio/gresolver.c:937 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "" + +#: ../gio/gresolver.c:987 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "" + +#: ../gio/gresolver.c:1146 ../gio/gresolver.c:1320 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "" + +#: ../gio/gresolver.c:1151 ../gio/gresolver.c:1325 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:1156 ../gio/gresolver.c:1330 +#, c-format +msgid "Error resolving '%s'" +msgstr "" + +#: ../gio/gresource.c:295 ../gio/gresource.c:543 ../gio/gresource.c:560 +#: ../gio/gresource.c:681 ../gio/gresource.c:750 ../gio/gresource.c:811 +#: ../gio/gresource.c:891 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "" + +#: ../gio/gresource.c:460 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "" + +#: ../gio/gresource-tool.c:470 ../gio/gsettings-tool.c:530 +msgid "Print help" +msgstr "" + +#: ../gio/gresource-tool.c:471 ../gio/gresource-tool.c:539 +msgid "[COMMAND]" +msgstr "" + +#: ../gio/gresource-tool.c:476 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: ../gio/gresource-tool.c:482 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: ../gio/gresource-tool.c:485 ../gio/gresource-tool.c:495 +msgid "FILE [PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:486 ../gio/gresource-tool.c:496 +#: ../gio/gresource-tool.c:503 +msgid "SECTION" +msgstr "" + +#: ../gio/gresource-tool.c:491 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: ../gio/gresource-tool.c:501 +msgid "Extract a resource file to stdout" +msgstr "" + +#: ../gio/gresource-tool.c:502 +msgid "FILE PATH" +msgstr "" + +#: ../gio/gresource-tool.c:508 ../gio/gsettings-tool.c:610 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"أمرٌ مجهول %s\n" +"\n" + +#: ../gio/gresource-tool.c:516 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:530 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:533 ../gio/gsettings-tool.c:643 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gresource-tool.c:537 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: ../gio/gresource-tool.c:541 ../gio/gsettings-tool.c:650 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gresource-tool.c:547 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: ../gio/gresource-tool.c:550 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: ../gio/gresource-tool.c:554 +msgid "[PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:556 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: ../gio/gresource-tool.c:557 +msgid "PATH" +msgstr "" + +#: ../gio/gresource-tool.c:559 +msgid " PATH A resource path\n" +msgstr "" + +#: ../gio/gsettings-tool.c:53 ../gio/gsettings-tool.c:74 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:59 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:80 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:94 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:100 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:106 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:112 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:133 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:503 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:536 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:542 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:548 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:549 ../gio/gsettings-tool.c:555 +#: ../gio/gsettings-tool.c:592 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:554 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:560 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:562 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:567 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:568 ../gio/gsettings-tool.c:574 +#: ../gio/gsettings-tool.c:586 ../gio/gsettings-tool.c:598 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:573 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:579 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:580 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:585 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:591 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:597 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:603 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:618 +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:640 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:646 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:654 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:659 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:663 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:667 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:788 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:282 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:289 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:297 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:305 ../gio/gsocket.c:3525 ../gio/gsocket.c:3580 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:472 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "" + +#: ../gio/gsocket.c:506 ../gio/gsocket.c:513 ../gio/gsocket.c:529 +#, c-format +msgid "Unable to create socket: %s" +msgstr "" + +#: ../gio/gsocket.c:506 +msgid "Unknown family was specified" +msgstr "" + +#: ../gio/gsocket.c:513 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1718 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1761 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1822 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1896 +#, c-format +msgid "Error binding to address: %s" +msgstr "" + +#: ../gio/gsocket.c:1949 ../gio/gsocket.c:1985 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "" + +#: ../gio/gsocket.c:1950 ../gio/gsocket.c:1986 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "" + +#: ../gio/gsocket.c:1951 +msgid "No support for source-specific multicast" +msgstr "" + +#: ../gio/gsocket.c:2170 +#, c-format +msgid "Error accepting connection: %s" +msgstr "" + +#: ../gio/gsocket.c:2291 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:2343 ../gio/gsocket.c:4322 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "" + +#: ../gio/gsocket.c:2513 +#, c-format +msgid "Error receiving data: %s" +msgstr "" + +#: ../gio/gsocket.c:2691 +#, c-format +msgid "Error sending data: %s" +msgstr "" + +#: ../gio/gsocket.c:2805 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "" + +#: ../gio/gsocket.c:2884 +#, c-format +msgid "Error closing socket: %s" +msgstr "" + +#: ../gio/gsocket.c:3518 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3796 ../gio/gsocket.c:3877 +#, c-format +msgid "Error sending message: %s" +msgstr "" + +#: ../gio/gsocket.c:3821 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:4101 ../gio/gsocket.c:4237 +#, c-format +msgid "Error receiving message: %s" +msgstr "" + +#: ../gio/gsocket.c:4341 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:174 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: ../gio/gsocketclient.c:188 +#, c-format +msgid "Could not connect to %s: " +msgstr "" + +#: ../gio/gsocketclient.c:190 +msgid "Could not connect: " +msgstr "" + +#: ../gio/gsocketclient.c:976 ../gio/gsocketclient.c:1547 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:1029 ../gio/gsocketclient.c:1486 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:1055 ../gio/gsocketclient.c:1507 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:156 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:182 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:189 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:326 +#: ../gio/gsocks5proxy.c:336 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" + +#: ../gio/gsocks5proxy.c:238 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:288 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "" + +#: ../gio/gsocks5proxy.c:350 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:357 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:363 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:370 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:376 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:382 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:388 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:394 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:400 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:249 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:254 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:264 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:289 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:298 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:589 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:347 +msgid "Error sending credentials: " +msgstr "" + +#: ../gio/gunixconnection.c:510 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:519 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:603 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:629 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:382 ../gio/gunixinputstream.c:403 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:438 ../gio/gunixinputstream.c:510 +#: ../gio/gunixoutputstream.c:424 ../gio/gunixoutputstream.c:465 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "" + +#: ../gio/gunixmounts.c:1983 ../gio/gunixmounts.c:2020 +msgid "Filesystem root" +msgstr "جذر نظام الملÙّات" + +#: ../gio/gunixoutputstream.c:368 ../gio/gunixoutputstream.c:389 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "الجزء لا يدعم الإخراج" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "تعذّر العثور على التّطبيق" + +#: ../gio/gwin32appinfo.c:308 +#, c-format +msgid "Error launching application: %s" +msgstr "خطأ عند تشغيل التطبيق: %s" + +#: ../gio/gwin32appinfo.c:344 +msgid "URIs not supported" +msgstr "المسارات غير مدعومة" + +#: ../gio/gwin32appinfo.c:366 +msgid "association changes not supported on win32" +msgstr "تغيير الترابطات غير مدعوم على win32" + +#: ../gio/gwin32appinfo.c:378 +msgid "Association creation not supported on win32" +msgstr "إنشاء الترابط غير مدعوم على win32" + +#: ../gio/gwin32inputstream.c:318 +#, c-format +msgid "Error reading from handle: %s" +msgstr "" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, c-format +msgid "Error closing handle: %s" +msgstr "" + +#: ../gio/gwin32outputstream.c:318 +#, c-format +msgid "Error writing to handle: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:30 +msgid "Run a dbus service" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:44 +#, c-format +msgid "Wrong args\n" +msgstr "" + +#: ../glib/gbookmarkfile.c:760 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "ØµÙØ© غير متوقّعة '%s' للعنصر '%s'" + +#: ../glib/gbookmarkfile.c:771 ../glib/gbookmarkfile.c:842 +#: ../glib/gbookmarkfile.c:852 ../glib/gbookmarkfile.c:959 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Ø§Ù„ØµÙØ© '%s' للعنصر '%s' غير موجودة" + +#: ../glib/gbookmarkfile.c:1129 ../glib/gbookmarkfile.c:1194 +#: ../glib/gbookmarkfile.c:1258 ../glib/gbookmarkfile.c:1268 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "وسْم غير متوقع '%s'ØŒ توقّعت الوسْم '%s'" + +#: ../glib/gbookmarkfile.c:1154 ../glib/gbookmarkfile.c:1168 +#: ../glib/gbookmarkfile.c:1236 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "وسْم غير متوقّع '%s' داخل '%s'" + +#: ../glib/gbookmarkfile.c:1806 +msgid "No valid bookmark file found in data dirs" +msgstr "لا يوجد مل٠علامات سليم ÙÙŠ أدلّة البيانات" + +#: ../glib/gbookmarkfile.c:2007 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "توجد Ø¨Ø§Ù„ÙØ¹Ù„ علامة للمسار '%s'" + +#: ../glib/gbookmarkfile.c:2053 ../glib/gbookmarkfile.c:2211 +#: ../glib/gbookmarkfile.c:2296 ../glib/gbookmarkfile.c:2376 +#: ../glib/gbookmarkfile.c:2461 ../glib/gbookmarkfile.c:2544 +#: ../glib/gbookmarkfile.c:2622 ../glib/gbookmarkfile.c:2701 +#: ../glib/gbookmarkfile.c:2743 ../glib/gbookmarkfile.c:2840 +#: ../glib/gbookmarkfile.c:2960 ../glib/gbookmarkfile.c:3150 +#: ../glib/gbookmarkfile.c:3226 ../glib/gbookmarkfile.c:3391 +#: ../glib/gbookmarkfile.c:3480 ../glib/gbookmarkfile.c:3570 +#: ../glib/gbookmarkfile.c:3698 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "لا توجد علامة للمسار '%s'" + +#: ../glib/gbookmarkfile.c:2385 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "لم يعرّ٠نوع MIME ÙÙŠ علامة المسار '%s'" + +#: ../glib/gbookmarkfile.c:2470 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "لم يعر٠علم خاص ÙÙŠ العلامات للمسار '%s'" + +#: ../glib/gbookmarkfile.c:2849 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "لم تحدد أي مجموعات ÙÙŠ علامة '%s'" + +#: ../glib/gbookmarkfile.c:3244 ../glib/gbookmarkfile.c:3401 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "لم يسجل أي تطبيق بالاسم '%s' علامة '%s'" + +#: ../glib/gbookmarkfile.c:3424 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "ÙØ´Ù„ تمديد سطر exec '%s' بالمسار '%s'" + +#: ../glib/gconvert.c:807 ../glib/gutf8.c:837 ../glib/gutf8.c:1047 +#: ../glib/gutf8.c:1184 ../glib/gutf8.c:1288 +msgid "Partial character sequence at end of input" +msgstr "تتابع محار٠جزئي عند نهاية الدخْل" + +#: ../glib/gconvert.c:1057 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "تعذّر تحويل fallback '%s' إلى مجموعة المحار٠'%s'" + +#: ../glib/gconvert.c:1874 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "المسار '%s' ليس مسارا مطلقا باستخدام المخطط \"file\"" + +#: ../glib/gconvert.c:1884 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "مل٠المسار المحلي '%s' لا يمكن أن يحتوي على '#'" + +#: ../glib/gconvert.c:1901 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "المسار '%s' غير سليم" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "اسم مستضي٠المسار '%s' غير سليم" + +#: ../glib/gconvert.c:1929 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "المسار '%s' يحتوي على محار٠خلوص غير سليمة " + +#: ../glib/gconvert.c:2024 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "اسم المسار '%s' ليس مسارا كاملا" + +#: ../glib/gconvert.c:2034 +msgid "Invalid hostname" +msgstr "اسم المستضي٠غير سليم" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "AM" +msgstr "ص" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "PM" +msgstr "Ù…" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %e %B %l:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%dâ€/%mâ€/%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:219 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%OI:%OM:%OS %p" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "January" +msgstr "يناير" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "February" +msgstr "ÙØ¨Ø±Ø§ÙŠØ±" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "March" +msgstr "مارس" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "April" +msgstr "أبريل" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "May" +msgstr "مايو" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "June" +msgstr "يونيو" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "July" +msgstr "يوليو" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "August" +msgstr "أغسطس" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "September" +msgstr "سبتمبر" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "October" +msgstr "أكتوبر" + +#: ../glib/gdatetime.c:252 +msgctxt "full month name" +msgid "November" +msgstr "نوÙمبر" + +#: ../glib/gdatetime.c:254 +msgctxt "full month name" +msgid "December" +msgstr "ديسمبر" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "يناير" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ÙØ¨Ø±Ø§ÙŠØ±" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "مارس" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "أبريل" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "May" +msgstr "مايو" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "يونيو" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "يوليو" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "أغسطس" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "سبتمبر" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "أكتوبر" + +#: ../glib/gdatetime.c:289 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "نوÙمبر" + +#: ../glib/gdatetime.c:291 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ديسمبر" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Monday" +msgstr "الاثنين" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "الثلاثاء" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "الأربعاء" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "الخميس" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Friday" +msgstr "الجمعة" + +#: ../glib/gdatetime.c:316 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "السبت" + +#: ../glib/gdatetime.c:318 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "الأحد" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "اثنين" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ثلاثاء" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "أربعاء" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "خميس" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "جمعة" + +#: ../glib/gdatetime.c:343 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "سبت" + +#: ../glib/gdatetime.c:345 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "أحد" + +#: ../glib/gdir.c:121 ../glib/gdir.c:144 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "خطأ أثناء ÙØªØ­ الدليل '%s'â€: %s" + +#: ../glib/gfileutils.c:675 ../glib/gfileutils.c:763 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "تعذّر تحصيص %Ilu بايتات لقرائة المل٠\"%s\"" + +#: ../glib/gfileutils.c:690 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "خطأ عند قراءة المل٠'%s'â€: %s" + +#: ../glib/gfileutils.c:704 +#, c-format +msgid "File \"%s\" is too large" +msgstr "المل٠\"%s\" كبير جدا" + +#: ../glib/gfileutils.c:787 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "ÙØ´Ù„ت القراءة من المل٠'%s'â€: %s" + +#: ../glib/gfileutils.c:838 ../glib/gfileutils.c:925 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "ÙØ´Ù„ ÙØªØ­ المل٠'%s'â€: %s" + +#: ../glib/gfileutils.c:855 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "ÙØ´Ù„ت ÙÙŠ أخذ ØµÙØ§Øª المل٠'%s': ÙØ´Ù„ fstat(): %s" + +#: ../glib/gfileutils.c:889 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "ÙØ´Ù„ ÙØªØ­ المل٠'%s': ÙØ´Ù„ fdopen(): %s" + +#: ../glib/gfileutils.c:997 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "ÙØ´Ù„ إعادة تسمية المل٠'%s' إلى '%s': ÙØ´Ù„ g_rename(): %s" + +#: ../glib/gfileutils.c:1039 ../glib/gfileutils.c:1584 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "ÙØ´Ù„ إنشاء المل٠'%s'â€: %s" + +#: ../glib/gfileutils.c:1053 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "ÙØ´Ù„ ÙØªØ­ المل٠'%s' للكتابة: ÙØ´Ù„ fdopen(): %s" + +#: ../glib/gfileutils.c:1078 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "ÙØ´Ù„ت ÙÙŠ كتابة المل٠'%s': ÙØ´Ù„ fwrite(): %s" + +#: ../glib/gfileutils.c:1097 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "ÙØ´Ù„ت ÙÙŠ كتابة المل٠'%s': ÙØ´Ù„ fflush(): %s" + +#: ../glib/gfileutils.c:1141 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "ÙØ´Ù„ت ÙÙŠ كتابة المل٠'%s': ÙØ´Ù„ fsync(): %s" + +#: ../glib/gfileutils.c:1165 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "ÙØ´Ù„ت ÙÙŠ غلق المل٠'%s': ÙØ´Ù„ fclose(): %s" + +#: ../glib/gfileutils.c:1287 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "لا يمكن حذ٠المل٠الموجود مسبقا '%s': ÙØ´Ù„ g_unlink(): %s" + +#: ../glib/gfileutils.c:1547 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "القالب '%s' غير سليم، لا يجب أن يحتوي على '%s'" + +#: ../glib/gfileutils.c:1560 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "لا يحتوي القالب '%s' على XXXXXX" + +#: ../glib/gfileutils.c:2088 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "ÙØ´Ù„ت قراءة الوصلة الرمزية '%s'â€: %s" + +#: ../glib/gfileutils.c:2109 +msgid "Symbolic links not supported" +msgstr "الوصلات الرمزية غير مدعومة" + +#: ../glib/giochannel.c:1415 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "تعذّر ÙØªØ­ Ø§Ù„Ù…ÙØ­ÙˆÙ‘ÙÙ„ من '%s' إلى '%s'â€: %s" + +#: ../glib/giochannel.c:1760 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "لا يمكن عمل قراءة خام ÙÙŠ g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1807 ../glib/giochannel.c:2064 +#: ../glib/giochannel.c:2151 +msgid "Leftover unconverted data in read buffer" +msgstr "بيانات غير Ù…ÙØ­ÙˆÙ‘لة باقية ÙÙŠ حاجز القراءة الخلÙÙŠ" + +#: ../glib/giochannel.c:1888 ../glib/giochannel.c:1965 +msgid "Channel terminates in a partial character" +msgstr "تنتهي القناة عند محر٠جزئي" + +#: ../glib/giochannel.c:1951 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "لا يمكن عمل قراءة خام ÙÙŠ g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:726 +msgid "Valid key file could not be found in search dirs" +msgstr "لا يمكن إيجاد Ù…Ù„Ù Ù…ÙØªØ§Ø­ صحيح ÙÙŠ دلائل البحث" + +#: ../glib/gkeyfile.c:762 +msgid "Not a regular file" +msgstr "ليس Ù…Ù„ÙØ§ اعتياديا" + +#: ../glib/gkeyfile.c:1162 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ يحتوي على سطر '%s' والذي ليس زوج قيمة Ù…ÙØ§ØªÙŠØ­ ØŒ مجموعة ØŒ أو تعليق" + +#: ../glib/gkeyfile.c:1222 +#, c-format +msgid "Invalid group name: %s" +msgstr "اسم مجموعة غير صحيح: %s" + +#: ../glib/gkeyfile.c:1244 +msgid "Key file does not start with a group" +msgstr "لا يبدأ Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ بمجموعة" + +#: ../glib/gkeyfile.c:1270 +#, c-format +msgid "Invalid key name: %s" +msgstr "اسم Ù…ÙØªØ§Ø­ غير صحيح: %s" + +#: ../glib/gkeyfile.c:1297 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "يحتوي Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø¹ على ترميز غير مدعوم '%s'" + +#: ../glib/gkeyfile.c:1541 ../glib/gkeyfile.c:1703 ../glib/gkeyfile.c:3081 +#: ../glib/gkeyfile.c:3147 ../glib/gkeyfile.c:3273 ../glib/gkeyfile.c:3406 +#: ../glib/gkeyfile.c:3548 ../glib/gkeyfile.c:3778 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "لا يحتوي Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ على المجموعة '%s'" + +#: ../glib/gkeyfile.c:1715 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "لا يحتوي Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ على Ø§Ù„Ù…ÙØªØ§Ø­ '%s'" + +#: ../glib/gkeyfile.c:1822 ../glib/gkeyfile.c:1938 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "يحتوي Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ على Ø§Ù„Ù…ÙØªØ§Ø­ '%s' ذو القيمة '%s' التي ليست UTF-8" + +#: ../glib/gkeyfile.c:1842 ../glib/gkeyfile.c:1958 ../glib/gkeyfile.c:2327 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ يحتوي على Ù…ÙØªØ§Ø­ '%s' والذي لديه قيمة لا يمكن ØªÙØ³ÙŠØ±Ù‡Ø§." + +#: ../glib/gkeyfile.c:2544 ../glib/gkeyfile.c:2910 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ يحتوي على Ù…ÙØªØ§Ø­ '%s' ÙÙŠ المجموعة '%s' والتي لديها قيمة لا يمكن " +"ØªÙØ³ÙŠØ±Ù‡Ø§>" + +#: ../glib/gkeyfile.c:2622 ../glib/gkeyfile.c:2698 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" + +#: ../glib/gkeyfile.c:3096 ../glib/gkeyfile.c:3288 ../glib/gkeyfile.c:3857 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "لا يحتوي Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ على Ù…ÙØªØ§Ø­ '%s' ÙÙŠ المجموعة '%s'" + +#: ../glib/gkeyfile.c:4089 +msgid "Key file contains escape character at end of line" +msgstr "Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ يحتوي على محر٠الخلوص ÙÙŠ آخر السطر" + +#: ../glib/gkeyfile.c:4111 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ يحتوي على تتابع خلوص غير صالح '%s'" + +#: ../glib/gkeyfile.c:4253 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "لا يمكن ØªÙØ³ÙŠØ± القيمة '%s' كعدد." + +#: ../glib/gkeyfile.c:4267 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "قيمة عدد صحيح '%s' خارج المدى" + +#: ../glib/gkeyfile.c:4300 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "لا يمكن ØªÙØ³ÙŠØ± القيمة '%s' كعدد عشري." + +#: ../glib/gkeyfile.c:4324 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "لا يمكن ØªÙØ³ÙŠØ± القيمة '%s' كعدد منطقي." + +#: ../glib/gmappedfile.c:128 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "ÙØ´Ù„ت ÙÙŠ أخذ ØµÙØ§Øª المل٠'%s%s%s%s': ÙØ´Ù„ fstat‪()‬â€: %s" + +#: ../glib/gmappedfile.c:194 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "ÙØ´Ù„ ÙÙŠ مقابلة %s%s%s%sâ€: ‪mmap()‬ ÙØ´Ù„: %s" + +#: ../glib/gmappedfile.c:260 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "ÙØ´Ù„ ÙØªØ­ المل٠'%s': ÙØ´Ù„ open(): %s" + +#: ../glib/gmarkup.c:356 ../glib/gmarkup.c:397 +#, c-format +msgid "Error on line %d char %d: " +msgstr "خطأ ÙÙŠ السطر %Id الرمز %Id: " + +#: ../glib/gmarkup.c:419 ../glib/gmarkup.c:502 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "نص مرمّز بـ UTF-8 غير سليم ÙÙŠ الاسم - غير سليم '%s'" + +#: ../glib/gmarkup.c:430 +#, c-format +msgid "'%s' is not a valid name " +msgstr "ليس '%s' اسما سليما" + +#: ../glib/gmarkup.c:446 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "ليس '%s' اسما سليما: '%c'" + +#: ../glib/gmarkup.c:555 +#, c-format +msgid "Error on line %d: %s" +msgstr "خطأ ÙÙŠ السطر %Idâ€: ‎%s" + +#: ../glib/gmarkup.c:639 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"ÙØ´Ù„ ÙÙŠ تحليل '%-.*s'ØŒ والتي كان لابد من كتبتها بالأرقام داخل مرجع محر٠" +"(ê كمثال) - ربما الرقم كبير جدًا" + +#: ../glib/gmarkup.c:651 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"مرجع المحر٠لم ينته Ø¨ÙØ§ØµÙ„Ø© منقوطة؛ الأرجح أنك استخدمت علامة امبارساند دون أن " +"تنوي بدء كيان - تخطا العلامت عن طريق اعتبارها &" + +#: ../glib/gmarkup.c:677 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "مرجع المحر٠'%-.*s' لا يقوم بترميز محر٠مسموح به" + +#: ../glib/gmarkup.c:715 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "Ø±ÙØ¤ÙŠ ÙƒÙŠØ§Ù† ÙØ§Ø±Øº '&;'ØŒ الكيانات السليمة هي:& " < > ' " + +#: ../glib/gmarkup.c:723 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "اسم الكيان '%-.*s' غير معروÙ" + +#: ../glib/gmarkup.c:728 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"اسم الكيان لم ينته Ø¨ÙØ§ØµÙ„Ø© منقوطة؛ الأرجح أنك استخدمت علامة & دون أن تنوي بدء " +"كيان - تخطى العلامة عن طريق اعتبارها &" + +#: ../glib/gmarkup.c:1076 +msgid "Document must begin with an element (e.g. )" +msgstr "يجب أن يبدأ المستند بعنصر ( مثلا)" + +#: ../glib/gmarkup.c:1116 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "'%s' محر٠غير سليم بعد المحر٠'<'Ø› ربما لا يبدأ هذا المحر٠اسم عنصر" + +#: ../glib/gmarkup.c:1184 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "محر٠غريب '%s'ØŒ توقعت محر٠'>' لإنهاء بداية وسم العنصر '%s'" + +#: ../glib/gmarkup.c:1268 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "محر٠غريب '%s'ØŒ توقعت '=' بعد اسم Ø§Ù„ØµÙØ© '%s' للعنصر '%s'" + +#: ../glib/gmarkup.c:1309 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"محر٠غريب '%s'ØŒ توقعت المحر٠'>' أو '/' لإنهاء علامة البداية للعنصر '%s'ØŒ أو " +"بشكل اختياري ØµÙØ©Ø› ربما استخدمت محرÙًا غير صالح ÙÙŠ اسم ØµÙØ©" + +#: ../glib/gmarkup.c:1353 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"محر٠غريب '%s'ØŒ توقعت علامة اقتباس Ù…ÙØªÙˆØ­Ø© بعد علامة التساوي عند إعطاء قيمة " +"من Ø§Ù„ØµÙØ© '%s' للعنصر '%s'" + +#: ../glib/gmarkup.c:1486 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "'%s' محر٠غير صالح بعد اغلاق اسم العنصر '%s'Ø› المحر٠المسموح به هو '>'" + +#: ../glib/gmarkup.c:1533 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "العنصر '%s' كان مغلقا، لا عنصر Ù…ÙØªÙˆØ­ حاليا" + +#: ../glib/gmarkup.c:1542 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "العنصر '%s' كان مغلقا، لكن العنصر Ø§Ù„Ù…ÙØªÙˆØ­ حاليا هو '%s'" + +#: ../glib/gmarkup.c:1710 +msgid "Document was empty or contained only whitespace" +msgstr "المستند كان ÙØ§Ø±ØºØ§ أو كان يحتوي Ùقط على مساحات ÙØ§Ø±ØºØ©" + +#: ../glib/gmarkup.c:1724 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "انتهى المستند بشكل غير متوقع بعد قوس بزاوية ‪'<'‬" + +#: ../glib/gmarkup.c:1732 ../glib/gmarkup.c:1777 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"انتهى المستند بشكل غير متوقع مع عناصر لا زالت Ù…ÙØªÙˆØ­Ø© - '%s' كان آخر عنصر " +"Ù…ÙØªÙˆØ­" + +#: ../glib/gmarkup.c:1740 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"انتهى المستند بشكل غير متوقع، توقعت رؤية قوس ذا زاوية لينهي العلامة‪<%s/>‬" + +#: ../glib/gmarkup.c:1746 +msgid "Document ended unexpectedly inside an element name" +msgstr "انتهى المستند بشكل غير متوقع داخل اسم عنصر" + +#: ../glib/gmarkup.c:1752 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "انتهى المستند بشكل غير متوقع داخل اسم ØµÙØ©" + +#: ../glib/gmarkup.c:1757 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "انتهى المستند بشكل غير متوقع بعد علامة ÙØªØ­ عنصر." + +#: ../glib/gmarkup.c:1763 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"انتهى المستند بشكل غير متوقع بعد علامة التساوي اثر اسم ØµÙØ©Ø› لا توجد قيمة " +"Ù„Ù„ØµÙØ©" + +#: ../glib/gmarkup.c:1770 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "انتهى المستند بشكل غير متوقع وهو داخلَ قيمة ØµÙØ©" + +#: ../glib/gmarkup.c:1786 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "انتهى المستند بشكل غير متوقع داخل علامة انهاء للعنصر '%s'" + +#: ../glib/gmarkup.c:1792 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "انتهى المستند بشكل غير متوقع داخل تعليق أو تعليمات معالجة" + +#: ../glib/goption.c:745 +msgid "Usage:" +msgstr "الاستخدام:" + +#: ../glib/goption.c:745 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:851 +msgid "Help Options:" +msgstr "خيارات المساعدة:" + +#: ../glib/goption.c:852 +msgid "Show help options" +msgstr "اعرض خيارات المساعدة" + +#: ../glib/goption.c:858 +msgid "Show all help options" +msgstr "اعرض كل خيارات المساعدة" + +#: ../glib/goption.c:920 +msgid "Application Options:" +msgstr "خيارات التطبيق:" + +#: ../glib/goption.c:982 ../glib/goption.c:1052 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "تعذّر تحليل قيمة العدد الصحيح '%s' Ù„ %s" + +#: ../glib/goption.c:992 ../glib/goption.c:1060 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "قيمة الرقم الصحيح '%s' Ù„ %s خارج المجال" + +#: ../glib/goption.c:1017 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "تعذّر تحليل القيمة المزدوجة '%s' Ù„ %s" + +#: ../glib/goption.c:1025 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "القيمة المزدوجة '%s' Ù„ %s خارج المجال" + +#: ../glib/goption.c:1288 ../glib/goption.c:1367 +#, c-format +msgid "Error parsing option %s" +msgstr "خطأ أثناء تحليل الخيار %s" + +#: ../glib/goption.c:1398 ../glib/goption.c:1511 +#, c-format +msgid "Missing argument for %s" +msgstr "معامل %s Ù…Ùقود" + +#: ../glib/goption.c:1964 +#, c-format +msgid "Unknown option %s" +msgstr "خيار مجهول %s" + +#: ../glib/gregex.c:190 +msgid "corrupted object" +msgstr "كائن تالÙ" + +#: ../glib/gregex.c:192 +msgid "internal error or corrupted object" +msgstr "خطأ داخلي أو كائن تالÙ" + +#: ../glib/gregex.c:194 +msgid "out of memory" +msgstr "Ù†ÙØ°Øª الذّاكرة" + +#: ../glib/gregex.c:199 +msgid "backtracking limit reached" +msgstr "ÙˆÙØµÙÙ„ÙŽ للحد المسموح به من أمكنة الرجوع للوراء" + +#: ../glib/gregex.c:211 ../glib/gregex.c:219 +msgid "the pattern contains items not supported for partial matching" +msgstr "المثال يحتوي على عناصر لا تحتمل التطابق الجزئي" + +#: ../glib/gregex.c:221 +msgid "back references as conditions are not supported for partial matching" +msgstr "المراجع الرجعية غير مدعومة كشرط للتطابق الجزئي" + +#: ../glib/gregex.c:230 +msgid "recursion limit reached" +msgstr "ÙˆÙØµÙÙ„ÙŽ للحد المسموح به من التواتر" + +#: ../glib/gregex.c:232 +msgid "workspace limit for empty substrings reached" +msgstr "ÙˆÙØµÙÙ„ÙŽ للحد المسموح به لمساحة العمل بالسلاسل الجزئية Ø§Ù„ÙØ§Ø±ØºØ©" + +#: ../glib/gregex.c:234 +msgid "invalid combination of newline flags" +msgstr "ائتلا٠غير صحيح لأعلمة السطر الجديد" + +#: ../glib/gregex.c:236 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:238 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:242 +msgid "unknown error" +msgstr "خطأ مجهول" + +#: ../glib/gregex.c:262 +msgid "\\ at end of pattern" +msgstr "\\ ÙÙŠ نهاية النمط" + +#: ../glib/gregex.c:265 +msgid "\\c at end of pattern" +msgstr "â€\\c ÙÙŠ نهاية النمط" + +#: ../glib/gregex.c:268 +msgid "unrecognized character follows \\" +msgstr "رمز غير معرو٠بعد \\" + +#: ../glib/gregex.c:275 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "خلوصات تغيير المحار٠(\\l, \\L, \\u, \\U) غير مسموح بها هنا" + +#: ../glib/gregex.c:278 +msgid "numbers out of order in {} quantifier" +msgstr "الأعداد خارج التغطية ÙÙŠ المكمم {}" + +#: ../glib/gregex.c:281 +msgid "number too big in {} quantifier" +msgstr "العدد كبير جدا ÙÙŠ المكمم {}" + +#: ../glib/gregex.c:284 +msgid "missing terminating ] for character class" +msgstr "الرمز ] غير موجود" + +#: ../glib/gregex.c:287 +msgid "invalid escape sequence in character class" +msgstr "سلسلة غير سليمة" + +#: ../glib/gregex.c:290 +msgid "range out of order in character class" +msgstr "مجال خارج التغطية ÙÙŠ نوع الرموز" + +#: ../glib/gregex.c:293 +msgid "nothing to repeat" +msgstr "لا شيئ للإعادة" + +#: ../glib/gregex.c:296 +msgid "unrecognized character after (?" +msgstr "رمز غير معرو٠بعد (?" + +#: ../glib/gregex.c:300 +msgid "unrecognized character after (?<" +msgstr "رمز غير معرو٠بعد (?<" + +#: ../glib/gregex.c:304 +msgid "unrecognized character after (?P" +msgstr "رمز غير معرو٠بعد (?P" + +#: ../glib/gregex.c:307 +msgid "POSIX named classes are supported only within a class" +msgstr "أصنا٠POSIX المسماة مدعومة Ùقط داخل صنÙ" + +#: ../glib/gregex.c:310 +msgid "missing terminating )" +msgstr "القوس الغالق غير موجود )" + +#: ../glib/gregex.c:314 +msgid ") without opening (" +msgstr ") بلا قوس ÙØ§ØªØ­ (" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:321 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "â€(?R أو (?[+-] أرقام يجب أن تتبع ب )" + +#: ../glib/gregex.c:324 +msgid "reference to non-existent subpattern" +msgstr "إشارة لقالب داخلي غير موجود" + +#: ../glib/gregex.c:327 +msgid "missing ) after comment" +msgstr "الرمز ) غير موجود بعد التعليق" + +#: ../glib/gregex.c:330 +msgid "regular expression too large" +msgstr "قالب كبير جدًّا" + +#: ../glib/gregex.c:333 +msgid "failed to get memory" +msgstr "ÙØ´Ù„ تلقي الذاكرة" + +#: ../glib/gregex.c:336 +msgid "lookbehind assertion is not fixed length" +msgstr "مصادقة العثور الخلÙÙŠ ليست بحجم واحد" + +#: ../glib/gregex.c:339 +msgid "malformed number or name after (?(" +msgstr "اسم أو عدد غير صحيح بعد (?(" + +#: ../glib/gregex.c:342 +msgid "conditional group contains more than two branches" +msgstr "المجموعة الشرطية تحتوي على أكثر من ÙØ±Ø¹ÙŠÙ†" + +#: ../glib/gregex.c:345 +msgid "assertion expected after (?(" +msgstr "مصادقة منتظرة بعد (?(" + +#: ../glib/gregex.c:348 +msgid "unknown POSIX class name" +msgstr "اسم نوع POSIX غير معروÙ" + +#: ../glib/gregex.c:351 +msgid "POSIX collating elements are not supported" +msgstr "عناصر الترتيب POSIX غير مدعومة" + +#: ../glib/gregex.c:354 +msgid "character value in \\x{...} sequence is too large" +msgstr "قيمة الرمز ÙÙŠ سلسلة \\x{...} كبيرة جدًا" + +#: ../glib/gregex.c:357 +msgid "invalid condition (?(0)" +msgstr "شرط غير صحيح (?(0)" + +#: ../glib/gregex.c:360 +msgid "\\C not allowed in lookbehind assertion" +msgstr "â€\\C غير مسموحة له عند العثور الخلÙÙŠ" + +#: ../glib/gregex.c:363 +msgid "recursive call could loop indefinitely" +msgstr "Ø§Ù„ÙˆØ¸ÙŠÙØ© التكرارية يمكن أن تستمر إلى ما لا نهاية" + +#: ../glib/gregex.c:366 +msgid "missing terminator in subpattern name" +msgstr "منهي غير موجود ÙÙŠ اسم القالب الداخلي" + +#: ../glib/gregex.c:369 +msgid "two named subpatterns have the same name" +msgstr "هناك قالبان داخليان لهما Ù†ÙØ³ الاسم" + +#: ../glib/gregex.c:372 +msgid "malformed \\P or \\p sequence" +msgstr "سلسلة \\P أو \\p سيئة التركيب" + +#: ../glib/gregex.c:375 +msgid "unknown property name after \\P or \\p" +msgstr "اسم خاصية غير Ù…Ø¹Ø±ÙˆÙØ© بعد \\P أو \\p" + +#: ../glib/gregex.c:378 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "اسم القالب الداخلي كبير جدا" + +#: ../glib/gregex.c:381 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "هناك عدد كبير جدا من اسماء القوالب الداخلية (الأقصى 10,000)" + +#: ../glib/gregex.c:384 +msgid "octal value is greater than \\377" +msgstr "القيمة الثمانية أكبر من \\377" + +#: ../glib/gregex.c:387 +msgid "DEFINE group contains more than one branch" +msgstr "مجموعة DEFINE تحتوي على أكثر من ÙØ±Ø¹ واحد" + +#: ../glib/gregex.c:390 +msgid "repeating a DEFINE group is not allowed" +msgstr "إعادة مجموعة DEFINE غير مسموحة" + +#: ../glib/gregex.c:393 +msgid "inconsistent NEWLINE options" +msgstr "خيارات NEWLINE غير صحيحة " + +#: ../glib/gregex.c:396 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "â€\\g غير متبوعة باسم قوس أو عدد بقوس" + +#: ../glib/gregex.c:401 +msgid "unexpected repeat" +msgstr "إعادة غير متوقعة" + +#: ../glib/gregex.c:405 +msgid "code overflow" +msgstr "Ùيضان الرموز" + +#: ../glib/gregex.c:409 +msgid "overran compiling workspace" +msgstr "خطأ تركيب مساحة العمل" + +#: ../glib/gregex.c:413 +msgid "previously-checked referenced subpattern not found" +msgstr "القالب الداخلى المراقب مسبقا غير موجود" + +#: ../glib/gregex.c:631 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "خطأ عند تطابق جملة المقارنة %s: â€%s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "تم تجميع مكتبة PCRE من دون دعم UTF8 " + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "تم تجميع مكتبة PCRE من دون دعم خصائص UTF8 " + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "خطأ عند تجميع جملة المقارنة %s عند المحر٠%Id: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "خطأ عند تحسين جملة المقارنة %s: â€%s" + +#: ../glib/gregex.c:2182 +msgid "hexadecimal digit or '}' expected" +msgstr "رقم من نظام 16 أو '}' متوقع" + +#: ../glib/gregex.c:2198 +msgid "hexadecimal digit expected" +msgstr "رقم من نظام 16 متوقع" + +#: ../glib/gregex.c:2238 +msgid "missing '<' in symbolic reference" +msgstr "'<' غير موجود ÙÙŠ المرجع الرمزي" + +#: ../glib/gregex.c:2247 +msgid "unfinished symbolic reference" +msgstr "مرجع كيان غير مكتمل" + +#: ../glib/gregex.c:2254 +msgid "zero-length symbolic reference" +msgstr "مرجع رمزي معدوم الطول" + +#: ../glib/gregex.c:2265 +msgid "digit expected" +msgstr "رقم متوقع" + +#: ../glib/gregex.c:2283 +msgid "illegal symbolic reference" +msgstr "مرجع كيان غير صحيح" + +#: ../glib/gregex.c:2345 +msgid "stray final '\\'" +msgstr "نتيجة نهائية '\\'" + +#: ../glib/gregex.c:2349 +msgid "unknown escape sequence" +msgstr "سلسلة خروج غير Ù…Ø¹Ø±ÙˆÙØ©" + +#: ../glib/gregex.c:2359 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "خطأ عند قراءة نص الإستبدال \"%s\" عند المحر٠%Ilu: â€%s" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "النص المقتبس لا يبدأ بعلامة اقتباس" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "علامة اقتباس غير مطابقة ÙÙŠ سطر الأوامر أو نص منقول من Ø§Ù„ØµØ¯ÙØ©" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "انتهى النص بعد المحر٠'\\' (النص كان '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "انتهى النص قبل ايجاد المÙقتَبَس لـ%c (النص كان '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "كان النص ÙØ§Ø±ØºØ§ (أو كان يحتوي على ÙØ±Ø§Øº أبيض)" + +#: ../glib/gspawn.c:210 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ÙØ´Ù„ت قراءة البيانات من العملية الإبنة (%s)" + +#: ../glib/gspawn.c:351 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "خطأ غير متوقع ÙÙŠ select() أثناء قراءة البيانات من العملية الإبنة (%s)" + +#: ../glib/gspawn.c:436 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "خطأ غير متوقع ÙÙŠ waitpid() (%s)" + +#: ../glib/gspawn.c:1190 ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ÙØ´Ù„ت القراءة من الأنبوب الإبن (%s)" + +#: ../glib/gspawn.c:1258 +#, c-format +msgid "Failed to fork (%s)" +msgstr "ÙØ´Ù„ تشعيب (%s)" + +#: ../glib/gspawn.c:1406 ../glib/gspawn-win32.c:369 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "ÙØ´Ù„ التغيير إلى الدليل '%s' â€(%s)" + +#: ../glib/gspawn.c:1416 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "ÙØ´Ù„ تنÙيذ العملية الإبنة \"%s\" â€(%s)" + +#: ../glib/gspawn.c:1426 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "ÙØ´Ù„ اعادة توجيه الخرْج أو الدخْل للعملية الإبنة (%s)" + +#: ../glib/gspawn.c:1435 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ÙØ´Ù„ تشعيب العملية الإبنة (%s)" + +#: ../glib/gspawn.c:1443 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "خطأ غير معرو٠أثناء تنÙيذ العملية الإبنة \"%s\"" + +#: ../glib/gspawn.c:1467 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "ÙØ´Ù„ت قراءة بيانات كاÙية من أنبوب child pid â€(%s)" + +#: ../glib/gspawn.c:1540 ../glib/gspawn-win32.c:299 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ÙØ´Ù„ عمل أنبوب للاتصال بالعملية الإبنة (%s)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "ÙØ´Ù„ت قراءة البيانات من العملية الإبنة" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ÙØ´Ù„ تنÙيذ العملية الإبنة (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "اسم برنامج غير صحيح: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "سلسلة غير صالحة ÙÙŠ متجه الأحجية عند %Id: â€%s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "سلسلة غير صالحة ÙÙŠ البيئة: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "دليل عمل غير سليم: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ÙØ´Ù„ تنÙيذ البرنامج المساعد (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "خطأ غير متوقع ÙÙŠ g_io_channel_win32_poll() أثناء القراءة من عملية ابنة" + +#: ../glib/gutf8.c:915 +msgid "Character out of range for UTF-8" +msgstr "محر٠خارج حدود UTF-8" + +#: ../glib/gutf8.c:1015 ../glib/gutf8.c:1024 ../glib/gutf8.c:1154 +#: ../glib/gutf8.c:1163 ../glib/gutf8.c:1302 ../glib/gutf8.c:1398 +msgid "Invalid sequence in conversion input" +msgstr "تتابع غير سليم ÙÙŠ دخْل التحويل" + +#: ../glib/gutf8.c:1313 ../glib/gutf8.c:1409 +msgid "Character out of range for UTF-16" +msgstr "محر٠خارج حدود UTF-16" + +#: ../glib/gutils.c:2184 ../glib/gutils.c:2211 ../glib/gutils.c:2315 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "ØµÙØ± بايت" +msgstr[1] "بايت واحد" +msgstr[2] "%u بايت" +msgstr[3] "%u بايت" +msgstr[4] "%u بايت" +msgstr[5] "%u بايت" + +#: ../glib/gutils.c:2190 +#, c-format +msgid "%.1f KiB" +msgstr "%I.1f Ùƒ.بايت" + +#: ../glib/gutils.c:2192 +#, c-format +msgid "%.1f MiB" +msgstr "%I.1f Ù….بايت" + +#: ../glib/gutils.c:2195 +#, c-format +msgid "%.1f GiB" +msgstr "%I.1f ج.بايت" + +#: ../glib/gutils.c:2198 +#, c-format +msgid "%.1f TiB" +msgstr "%I.1f ت.بايت" + +#: ../glib/gutils.c:2201 +#, c-format +msgid "%.1f PiB" +msgstr "%I.1f ب.بايت" + +#: ../glib/gutils.c:2204 +#, c-format +msgid "%.1f EiB" +msgstr "%I.1f Ø¥.بايت" + +#: ../glib/gutils.c:2217 +#, c-format +msgid "%.1f kB" +msgstr "%I.1f Ùƒ.بايت" + +#: ../glib/gutils.c:2220 ../glib/gutils.c:2328 +#, c-format +msgid "%.1f MB" +msgstr "%I.1f Ù….بايت" + +#: ../glib/gutils.c:2223 ../glib/gutils.c:2333 +#, c-format +msgid "%.1f GB" +msgstr "%I.1f ج.بايت" + +#: ../glib/gutils.c:2225 ../glib/gutils.c:2338 +#, c-format +msgid "%.1f TB" +msgstr "%I.1f ت.بايت" + +#: ../glib/gutils.c:2228 ../glib/gutils.c:2343 +#, c-format +msgid "%.1f PB" +msgstr "%I.1f ب.بايت" + +#: ../glib/gutils.c:2231 ../glib/gutils.c:2348 +#, c-format +msgid "%.1f EB" +msgstr "%I.1f Ø¥.بايت" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2268 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "ØµÙØ± بايت" +msgstr[1] "بايت واحد" +msgstr[2] "%s بايت" +msgstr[3] "%s بايت" +msgstr[4] "%s بايت" +msgstr[5] "%s بايت" + +#: ../glib/gutils.c:2323 +#, c-format +msgid "%.1f KB" +msgstr "%I.1f Ùƒ.بايت" + +msgctxt "full month name with day" +msgid "January" +msgstr "يناير" + +msgctxt "full month name with day" +msgid "February" +msgstr "ÙØ¨Ø±Ø§ÙŠØ±" + +msgctxt "full month name with day" +msgid "March" +msgstr "مارس" + +msgctxt "full month name with day" +msgid "April" +msgstr "أبريل" + +msgctxt "full month name with day" +msgid "May" +msgstr "مايو" + +msgctxt "full month name with day" +msgid "June" +msgstr "يونيو" + +msgctxt "full month name with day" +msgid "July" +msgstr "يوليو" + +msgctxt "full month name with day" +msgid "August" +msgstr "أغسطس" + +msgctxt "full month name with day" +msgid "September" +msgstr "سبتمبر" + +msgctxt "full month name with day" +msgid "October" +msgstr "أكتوبر" + +msgctxt "full month name with day" +msgid "November" +msgstr "نوÙمبر" + +msgctxt "full month name with day" +msgid "December" +msgstr "ديسمبر" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "يناير" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ÙØ¨Ø±Ø§ÙŠØ±" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "مارس" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "أبريل" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "مايو" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "يونيو" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "يوليو" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "أغسطس" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "سبتمبر" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "أكتوبر" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "نوÙمبر" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ديسمبر" + +#~ msgid "File is empty" +#~ msgstr "Ø§Ù„Ù…Ù„Ù ÙØ§Ø±Øº" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "Ù…Ù„Ù Ø§Ù„Ù…ÙØªØ§Ø­ يحتوي على Ù…ÙØªØ§Ø­ '%s' والذي لديه قيمة لايمكن ØªÙØ³ÙŠØ±Ù‡Ø§." + +#~ msgid "Error reading from unix: %s" +#~ msgstr "خطأ عند القراءة من يونكس: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "خطأ عند غلق يونكس: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "خطأ أثناء الكتابة إلى يونكس: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "ص" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "Ù…" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "لا يمكنك نقل دليل على دليل" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "تتابع غير سليم ÙÙŠ دخْل التحويل" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "تَمَّ بÙلوغ أقصى حد لمصÙÙˆÙØ© المعطيات" + +#~ msgid "do not hide entries" +#~ msgstr "لا تخÙ٠العناصر" + +#~ msgid "use a long listing format" +#~ msgstr "استخدم تهيئة العرض المسترسل" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "المحر٠'%s' غير سليم عند بداية اسم الكيان؛ المحر٠& يبدأ كيانا، ان كان " +#~ "علامة اﻻمبارساند هذه غير موضوعة على انها كيان، تخطاها باعتبارها &" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "المحر٠'%s' غير موجود داخل اسم أي كيان" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "مرجع Ù…Ø­Ø±Ù ÙØ§Ø±ØºØ› يجب أن يتضمن رقما مثل dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "مرجع كيان غير مكتمل" + +#~ msgid "Unfinished character reference" +#~ msgstr "مرجع محر٠غير مكتمل" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "نص مرمّز بـ UTF-8 غير سليم - سلسة طويلة جدا" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "نص مرمّز بـ UTF-8 غير سليم - ليس محر٠بداية" + +#~ msgid "file" +#~ msgstr "ملÙ" + +#~ msgid "The file containing the icon" +#~ msgstr "المل٠الذي يحتوي على الأيقونة" + +#~ msgid "names" +#~ msgstr "أسماء" + +#~ msgid "An array containing the icon names" +#~ msgstr "مصÙÙˆÙØ© تحتوي أسماء الأيقونات" + +#~ msgid "use default fallbacks" +#~ msgstr "استخدم الاحتياط المبدئي" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "ما إذا سيستخدم الاحتياط المبدئي الموجود بقص الأسماء عند محار٠'-'. تجاهل " +#~ "الأسماء بعد الأول إذا خدد أكثر من اسم." + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "خطأ ÙÙ‰ تناول واص٠الملÙ: %s" diff --git a/po/as.po b/po/as.po new file mode 100644 index 0000000..400d511 --- /dev/null +++ b/po/as.po @@ -0,0 +1,4808 @@ +# translation of as.po to Assamese +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Amitakhya Phukan , 2007, 2008. +# Amitakhya Phukan , 2009. +# Nilamdyuti Goswami , 2012, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: as\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-08-18 05:54+0000\n" +"PO-Revision-Date: 2014-08-18 21:12+0530\n" +"Last-Translator: Nilamdyuti Goswami \n" +"Language-Team: Assamese \n" +"Language: as\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=(n!=1)\n" + +#: ../gio/gapplication.c:511 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"GApplication সেৱা অৱসà§à¦¥à¦¾ সà§à¦®à§à§±à¦¾à¦“ক (D-Bus সেৱা ফাইলসমূহৰ পৰা বà§à¦¯à§±à¦¹à¦¾à§° কৰক)" + +#: ../gio/gapplication.c:516 +#| msgid "Application Options:" +msgid "GApplication options" +msgstr "GApplication বিকলà§à¦ªà¦¸à¦®à§‚হ" + +#: ../gio/gapplication.c:516 +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "GApplication বিকলà§à¦ªà¦¸à¦®à§‚হ দেখà§à§±à¦¾à¦“ক" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:481 ../gio/gsettings-tool.c:508 +msgid "Print help" +msgstr "পà§à§°à¦¿à¦¨à§à¦Ÿ সহায়" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:482 +#: ../gio/gresource-tool.c:550 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "পà§à§°à¦¿à¦¨à§à¦Ÿ সংসà§à¦•ৰণ" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:514 +msgid "Print version information and exit" +msgstr "সংসà§à¦•ৰণ তথà§à¦¯ পà§à§°à¦¿à¦¨à§à¦Ÿ কৰক আৰৠপà§à§°à¦¸à§à¦¥à¦¾à¦¨ কৰক" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচনসমূহ তালিকাভà§à¦•à§à¦¤ কৰক" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"ইনসà§à¦Ÿà¦²à§à¦¡ D-Bus সকà§à§°à¦¿à§Ÿà¦¯à§‹à¦—à§à¦¯ à¦à¦ªà§à¦²à¦¿à¦•েচনসমূহ তালিকাভà§à¦•à§à¦¤ কৰক (.desktop ফাইলসমূহৰে)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "à¦à¦Ÿà¦¾ à¦à¦ªà§à¦²à¦¿à¦•েচন আৰমà§à¦­ কৰক" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচন আৰমà§à¦­ কৰক (খোলিবলৈ বৈকলà§à¦ªà¦¿à¦• ফাইলসমূহৰ সৈতে)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "à¦à¦Ÿà¦¾ কাৰà§à¦¯à§à¦¯ সকà§à§°à¦¿à§Ÿ কৰক" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচনত à¦à¦Ÿà¦¾ কাৰà§à¦¯à§à¦¯ আৱাহন কৰক" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "উপলবà§à¦§ কাৰà§à¦¯à§à¦¯à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"à¦à¦Ÿà¦¾ à¦à¦ªà§à¦²à¦¿à¦•েচনৰ বাবে সà§à¦¥à¦¿à§° কাৰà§à¦¯à§à¦¯à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক (.desktop ফাইলৰ পৰা)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "কমানà§à¦¡ যাৰ বাবে বিৱৰিত সহায় পà§à§°à¦¿à¦¨à§à¦Ÿ কৰা হব" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus বিনà§à¦¯à¦¾à¦¸à¦¤ à¦à¦ªà§à¦²à¦¿à¦•েচন পৰিচয়ক (উদাহৰণ: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:488 +#: ../gio/gresource-tool.c:554 +msgid "FILE" +msgstr "FILE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "বৈকলà§à¦ªà¦¿à¦• পà§à§°à¦¾à¦¸à¦‚গিক অথবা পà§à§°à¦¾à¦¸à¦‚গিক ফাইলনামসমূহ, অথবা খোলিবলৈ URls" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "কাৰà§à¦¯à§à¦¯" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "আৱাহন কৰিবলৈ কাৰà§à¦¯à§à¦¯à§° নাম" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "পà§à§°à¦¾à¦šà¦²" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "কাৰà§à¦¯à§à¦¯ আৱাহনৰ বাবে বৈকলà§à¦ªà¦¿à¦• পà§à§°à¦¾à¦šà¦², GVariant বিনà§à¦¯à¦¾à¦¸à¦¤" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:519 +#: ../gio/gsettings-tool.c:594 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"অজà§à¦žà¦¾à¦¤ কমানà§à¦¡ %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "বà§à¦¯à§±à¦¹à¦¾à§°:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:544 +#: ../gio/gsettings-tool.c:628 +msgid "Arguments:\n" +msgstr "তৰà§à¦•সমূহ:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "কমানà§à¦¡à¦¸à¦®à§‚হ:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"বিৱৰিত সহায়ৰ বাবে '%s help COMMAND' বà§à¦¯à§±à¦¹à¦¾à§° কৰক।\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s কমানà§à¦¡à§° পà§à§°à¦¤à§à¦¯à¦•à§à¦·à¦­à¦¾à§±à§‡ অনà§à¦•ৰণ কৰিবলৈ à¦à¦Ÿà¦¾ à¦à¦ªà§à¦²à¦¿à¦•েচন আইডিৰ পà§à§°à§Ÿà§‹à¦œà¦¨\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "অবৈধ à¦à¦ªà§à¦²à¦¿à¦•েচন আইডি: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' ঠকোনো তৰà§à¦• নলয়\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus লৈ সংযোগ কৰিব নোৱাৰি: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচনলৈ %s বাৰà§à¦¤à¦¾ পঠাওতে তà§à§°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "কাৰà§à¦¯à§à¦¯à§° নাম à¦à¦ªà§à¦²à¦¿à¦•েচন আইডিৰ পিছত দিব লাগিব\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"অবৈধ কাৰà§à¦¯à§à¦¯ নাম: '%s'\n" +"কাৰà§à¦¯à§à¦¯à§° নামত কেৱল আলà§à¦«à¦¾à¦¨à¦¿à¦‰à¦®à¦¾à§°à¦¿à¦•, '-' আৰৠ'.' থাকিব লাগিব\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "কাৰà§à¦¯à§à¦¯à§° পà§à§°à¦¾à¦šà¦² বিশà§à¦²à§‡à¦·à¦£ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "কাৰà§à¦¯à§à¦¯à¦¸à¦®à§‚হে সৰà§à¦¬à¦¾à¦§à¦¿à¦• à¦à¦Ÿà¦¾ পà§à§°à¦¾à¦šà¦² গà§à§°à¦¹à¦£ কৰে\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "list-actions কমানà§à¦¡à§‡ কেৱল à¦à¦ªà§à¦²à¦¿à¦•েচন আইডি লয়" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচন %s à§° বাবে ডেসà§à¦•টপ ফাইল সনà§à¦§à¦¾à¦¨ কৰিবলৈ অকà§à¦·à¦®\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"অজà§à¦žà¦¾à¦¤ কমানà§à¦¡: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:370 +#: ../gio/ginputstream.c:608 ../gio/ginputstream.c:828 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:823 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s লৈ বহà§à¦¤ ডাঙৰ count মান দিয়া হৈছে" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "ভিতà§à¦¤à¦¿ সà§à§°à§‹à¦¤à¦¤ Seek সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream ক truncate কৰিব নোৱাৰি" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1017 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1464 +msgid "Stream is already closed" +msgstr "সà§à§°à§‹à¦¤ ইতিমধà§à¦¯à§‡ বনà§à¦§" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "ভিতà§à¦¤à¦¿ সà§à§°à§‹à¦¤à¦¤ Truncate à§° সমৰà§à¦¥à¦¨ নাই" + +#: ../gio/gcancellable.c:310 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "কৰà§à¦® বাতিল কৰা হৈছে" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "অবৈধ অবজেকà§à¦Ÿ, আৰমà§à¦­ কৰা হোৱা নাই" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "ইনপà§à¦Ÿà¦¤ অবৈধ মালà§à¦Ÿà¦¿à¦¬à¦¾à¦‡à¦Ÿ কà§à§°à¦®" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "গনà§à¦¤à¦¬à§à¦¯à¦¤ পৰà§à¦¯à¦¾à¦ªà§à¦¤ সà§à¦¥à¦¾à¦¨ নাই" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "সলনি কৰাৰ ইনপà§à¦Ÿà¦¤ অৱৈধ byte কà§à§°à¦®" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "সলনি কৰাৰ সময়ত তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "বাতিল কৰিব পৰা আৰমà§à¦­ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "আখৰৰ সংহতি '%s' à§° পৰা '%s' লৈ সলনি কৰাৰ সমৰà§à¦¥à¦¨ নাই" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' à§° পৰা '%s' লৈ সলনি কৰা পৰিৱৰà§à¦¤à¦•ক খোলিব নোৱাৰি" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s ধৰণ" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "অজà§à¦žà¦¾à¦¤ ধৰণ" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s ফাইলৰ ধৰণ" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials à¦à¦‡ OS ত পà§à§°à¦£à§Ÿà¦¨ কৰা হোৱা নাই" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "আপোনাৰ পà§à¦²à§‡à¦Ÿà¦«à§°à§à¦®à§° বাবে কোনো GCredentials সমৰà§à¦¥à¦¨ নাই" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials à§° à¦à¦‡ OS ত à¦à¦Ÿà¦¾ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ ID নাই" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "à¦à¦‡ OS ত তথà§à¦¯ সà§à¦ªà§à¦«à¦¿à¦‚ সমà§à¦­à¦¬ নহয়" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "সà§à§°à§‹à¦¤à§° অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ আগতীয়া অনà§à¦¤à¥¤" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "ঠিকনা পà§à§°à¦¬à¦¿à¦·à§à¦Ÿà¦¿ '%s' ত অসমৰà§à¦¥à¦¿à¦¤ কি '%s'" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "ঠিকনা '%s' অবৈধ (সঠিক à¦à¦Ÿà¦¾ পথৰ পà§à§°à§Ÿà§‹à¦œà¦¨, tmpdir অথবা à¦à¦¬à¦¸à§à¦Ÿà§à§°à§‡à¦•à§à¦Ÿ কিসমূহ)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "ঠিকনা পà§à§°à¦¬à¦¿à¦·à§à¦Ÿà¦¿ '%s' ত মূলà§à¦¯à¦¹à¦¿à¦¨ কি/মান যোৰ সংযà§à¦•à§à¦¤à¦¿" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "ঠিকনা '%s' ত তà§à§°à§à¦Ÿà¦¿ - পৰà§à¦Ÿ বৈশিষà§à¦Ÿ কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "ঠিকনা '%s' ত তà§à§°à§à¦Ÿà¦¿ - পৰিয়াল বৈশিষà§à¦Ÿ কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "ঠিকনা উপাদান '%s' ঠà¦à¦Ÿà¦¾ কলন (:) অনà§à¦¤à§°à§à¦­à§à¦•à§à¦¤ নকৰে" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" +"কি/মান যোৰ %d, '%s', ঠিকনা উপাদান '%s' ত à¦à¦Ÿà¦¾ ইকà§à§±à§‡à¦² চিহà§à¦¨ অনà§à¦¤à§°à§à¦­à§à¦•à§à¦¤ নকৰে" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"কি অথবা মান আনà¦à¦•à§à¦¸à§‡à¦‡à¦ª কৰোতে তà§à§°à§à¦Ÿà¦¿ কি/মান যোৰ %d, %s ত,ঠিকনা উপাদান '%s' ত" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"ঠিকনা '%s' ত তà§à§°à§à¦Ÿà¦¿ - unix পৰিৱহনৰ কেৱল à¦à¦Ÿà¦¾ 'পথ' অথবা 'à¦à¦¬à¦¸à§à¦Ÿà§à§°à§‡à¦•à§à¦Ÿ' সংহতি " +"কৰাৰ " +"পà§à§°à§Ÿà§‹à¦œà¦¨" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "ঠিকনা '%s' ত তà§à§°à§à¦Ÿà¦¿ - হসà§à¦Ÿ বৈশিষà§à¦Ÿ সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨ অথবা কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "ঠিকনা '%s' ত তà§à§°à§à¦Ÿà¦¿ - পৰà§à¦Ÿ বৈশিষà§à¦Ÿ সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨ অথবা কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "ঠিকনা '%s' ত তà§à§°à§à¦Ÿà¦¿ - noncefile বৈশিষà§à¦Ÿ সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨ অথবা কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "সà§à¦¬à¦šà¦¾à¦²à¦¿à¦¤-লঞà§à¦š কৰোতে তà§à§°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "ঠিকনা '%s' à§° বাবে অজà§à¦žà¦¾à¦¤ অথবা অসমৰà§à¦¥à¦¿à¦¤ পৰিৱহন '%s'" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "nonce file '%s' খোলোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "nonce file '%s' à§° পà§à§‹à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "nonce file '%s' à§° পৰা পà§à§‹à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿, ১৬ বাইট আশা কৰা হৈছিল, %d পোৱা গল" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "nonce file '%s' à§° সমলসমূহ সà§à§°à§‹à¦¤à¦²à§‡ লিখোতে তà§à§°à§à¦Ÿà¦¿:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "দিয়া ঠিকনা ৰিকà§à¦¤" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "setuid অৱসà§à¦¥à¦¾à¦¤ à¦à¦Ÿà¦¾ বাৰà§à¦¤à¦¾ বাচ পà§à§°à¦œà¦¨à¦¨ কৰিব নোৱাৰি" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "à¦à¦Ÿà¦¾ মেচিন-আইডিৰ অৱিহনে à¦à¦Ÿà¦¾ বাৰà§à¦¤à¦¾ বাচ সৃজন কৰিব নোৱাৰি: " + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "কমানà§à¦¡ শাৰী '%s' সৃজন কৰোতে তà§à§°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(à¦à¦‡ উইনà§à¦¡à§‹ বনà§à¦§ কৰিবলে যিকোনো আখৰ টাইপ কৰক)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "অধিবেশন dbus চলি থকা নাই, আৰৠautolaunch বà§à¦¯à§°à§à¦¥ হল" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "অধিবেশন বাচ ঠিকনা নিৰà§à¦§à¦¾à§°à¦£ কৰিব নোৱাৰি (à¦à¦‡ OS à§° বাবে পà§à§°à¦£à§Ÿà¦¨ কৰা নহয়)" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"DBUS_STARTER_BUS_TYPE পৰিৱেশ চলকৰ পৰা বাচ ঠিকনা নিৰà§à¦§à¦¾à§°à¦£ কৰিব নোৱাৰি - অজà§à¦žà¦¾à¦¤ " +"মান '%s'" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"বাচ ঠিকনা নিৰà§à¦§à¦¾à§°à¦£ কৰিব নোৱাৰি কাৰণ DBUS_STARTER_BUS_TYPE পৰিৱেশ চলক সংহতি " +"কৰা হোৱা নাই" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "অজà§à¦žà¦¾à¦¤ বাচ ধৰণ %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "à¦à¦Ÿà¦¾ শাৰী পà§à§‹à¦¤à§‡ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ সমল চেষà§à¦Ÿà¦¾à§° অভাৱ" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "à¦à¦Ÿà¦¾ শাৰী (সà§à§°à¦•à§à¦·à¦¿à¦¤à¦­à¦¾à§±à§‡) পà§à¦¾à§° চেষà§à¦Ÿà¦¾à¦¤ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ সমল চেষà§à¦Ÿà¦¾à§° অভাৱ" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"সকলো উপলবà§à¦§ পà§à§°à¦®à¦¾à¦£à§€à¦•ৰণ পদà§à¦§à¦¤à¦¿ শেষ হৈছে (চেষà§à¦Ÿà¦¾ কৰা হৈছে: %s) (উপলবà§à¦§: %s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer ৰে বাতিল কৰা হৈছে" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "ডাইৰেকটৰি '%s' à§° বাবে তথà§à¦¯ পà§à§°à¦¾à¦ªà§à¦¤ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"ডাইৰেকটৰি '%s' ত অনà§à¦®à¦¤à¦¿à¦¸à¦®à§‚হ কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥à¥¤ আশা কৰা অৱসà§à¦¥à¦¾ 0700, পà§à§°à¦¾à¦ªà§à¦¤ হল 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "ডাইৰেকটৰি '%s' সৃষà§à¦Ÿà¦¿ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "keyring '%s' ক পà§à¦¾à§° বাবে খোলোতে তà§à§°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "keyring à§° শাৰী %d কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥ '%s' ত সমল '%s' à§° সৈতে" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "keyring à§° %d শাৰীৰ পà§à§°à¦¥à¦® টকেন কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥ '%s' ত সমল '%s' à§° সৈতে" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "keyring à§° %d শাৰীৰ দà§à¦¬à¦¿à¦¤à§€à§Ÿ টকেন কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¥ '%s' ত সমল '%s' à§° সৈতে" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "আইডি %d à§° সৈতে কà§à¦•ি পোৱা নগল '%s' à§° keyring ত" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "পà§à§°à¦¨à¦¿ lock file '%s' মচি পেলাওতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "lock file '%s' সৃষà§à¦Ÿà¦¿ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "(অসংযà§à¦•à§à¦¤) lock file '%s' বনà§à¦§ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "lock file '%s' আনসংযোগ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "লিখিবৰ বাবে keyring '%s' খোলিবলে তà§à§°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(অতিৰিকà§à¦¤à¦­à¦¾à§±à§‡, '%s' à§° বাবে লক মà§à¦•à§à¦¤ কৰাও বà§à¦¯à§°à§à¦¥ হল: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "সংযোগ বনà§à¦§" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "সময়অনà§à¦¤ পà§à§°à¦¾à¦ªà§à¦¤ কৰা হৈছিল" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "à¦à¦Ÿà¦¾ কà§à¦²à¦¾à¦à¦¨à§à¦Ÿ দিশ সংযোগ সৃষà§à¦Ÿà¦¿ কৰোতে অসমৰà§à¦¥à¦¿à¦¤ ফà§à¦²à§‡à¦—সমূহৰ সনà§à¦®à§à¦–িন হৈছে" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"পথ %s à§° অবজেকà§à¦Ÿà¦¤ à¦à¦¨à§‡ কোনো আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  'org.freedesktop.DBus.Properties' নাই" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "à¦à¦¨à§‡ কোনো বৈশিষà§à¦Ÿ '%s' নাই" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "বৈশিষà§à¦Ÿ '%s' পà§à¦¿à¦¬ নোৱাৰি" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "বৈশিষà§à¦Ÿ '%s' লিখিব নোৱাৰি" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"বৈশিষà§à¦Ÿ '%s' সংহতি কৰোতে তà§à§°à§à¦Ÿà¦¿: আশা কৰা হৈছিল '%s' কিনà§à¦¤à§ পোৱা গল '%s'" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "à¦à¦¨à§‡ কোনো আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  '%s' নাই" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "à¦à¦¨à§‡ কোনো আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  নাই" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "পথ %s ত অবজেকà§à¦Ÿà¦¤ à¦à¦¨à§‡ কোনো আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  '%s' নাই" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "à¦à¦¨à§‡ কোনো পদà§à¦§à¦¤à¦¿ '%s' নাই" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "বাৰà§à¦¤à¦¾à§° ধৰণ, '%s', পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ ধৰণ '%s' à§° সৈতে মিল নাখায়" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "%s ত আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  %s à§° বাবে ইতিমধà§à¦¯à§‡ à¦à¦Ÿà¦¾ অবজেকà§à¦Ÿ à¦à¦•à§à¦¸à¦ªà§°à§à¦Ÿ কৰা হৈছে" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "পদà§à¦§à¦¤à¦¿ '%s' ঠধৰণ '%s' ঘà§à§°à¦¾à¦‡ দিছে, কিনà§à¦¤à§ আশা কৰা হৈছিল '%s'" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  '%s' ত সà§à¦¬à¦¾à¦•à§à¦·à§° '%s' à§° সৈতে পদà§à¦§à¦¤à¦¿ '%s' অসà§à¦¤à¦¿à¦¤à§à¦¬à¦¬à¦¾à¦¨ নহয়" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "%s à§° বাবে à¦à¦Ÿà¦¾ চাবটà§à§°à¦¿ ইতিমধà§à¦¯à§‡ à¦à¦•à§à¦¸à¦ªà§°à§à¦Ÿ কৰা হৈছে" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "ধৰণ INVALID" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL বাৰà§à¦¤à¦¾: PATH অথবা MEMBER হেডাৰ কà§à¦·à§‡à¦¤à§à§° সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN বাৰà§à¦¤à¦¾: REPLY_SERIAL হেডাৰ কà§à¦·à§‡à¦¤à§à§° সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR বাৰà§à¦¤à¦¾: REPLY_SERIAL অথবা ERROR_NAME হেডাৰ কà§à¦·à§‡à¦¤à§à§° সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL বাৰà§à¦¤à¦¾: PATH, INTERFACE অথবা MEMBER হেডাৰ কà§à¦·à§‡à¦¤à§à§° সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL বাৰà§à¦¤à¦¾: PATH হেডাৰ কà§à¦·à§‡à¦¤à§à§°à§Ÿ সংৰকà§à¦·à§€à¦¤ মান /org/freedesktop/DBus/Local " +"বà§à¦¯à§±à¦¹à¦¾à§° কৰি আছে" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL বাৰà§à¦¤à¦¾: INTERFACE হেডাৰ কà§à¦·à§‡à¦¤à§à§°à§Ÿ সংৰকà§à¦·à§€à¦¤ মান " +"org.freedesktop.DBus.Local " +"বà§à¦¯à§±à¦¹à¦¾à§° কৰি আছে" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu বাইট পà§à¦¿à¦¬à§° ইচà§à¦›à¦¾ আছিল কিনà§à¦¤à§ %lu পà§à§°à¦¾à¦ªà§à¦¤ হল" +msgstr[1] "%lu বাইট পà§à¦¿à¦¬à§° ইচà§à¦›à¦¾ আছিল কিনà§à¦¤à§ %lu পà§à§°à¦¾à¦ªà§à¦¤ হল" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "সà§à¦Ÿà§à§°à¦¿à¦‚ '%s' à§° পিছত NUL বাইট আশা কৰা হৈছিল কিনà§à¦¤à§ বাইট %d পোৱা গল" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"বৈধ UTF-8 সà§à¦Ÿà§à§°à¦¿à¦‚ আশা কৰা হৈছিল কিনà§à¦¤à§ বাইট অফচেট %d ত অবৈধ বাইটসমূহ পোৱা গল " +"(সà§à¦Ÿà§à§°à¦¿à¦‚à§° দৈৰà§à¦˜ %d)। সেই বিনà§à¦¦à§ লৈকে বৈধ UTF-8 সà§à¦Ÿà§à§°à¦¿à¦‚ '%s' আছিল" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "বিশà§à¦²à§‡à¦·à¦£ কৰা মান '%s' à¦à¦Ÿà¦¾ বৈধ D-Bus অবজেকà§à¦Ÿ পথ নহয়" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "বিশà§à¦²à§‡à¦·à¦£ কৰা মান '%s' à¦à¦Ÿà¦¾ বৈধ D-Bus সà§à¦¬à¦¾à¦•à§à¦·à§° নহয়" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"%u বাইট দৈৰà§à¦˜à§° à¦à§°à§‡ সনà§à¦®à§à¦–িন হল। সৰà§à¦¬à¦¾à¦§à¦¿à¦• দৈৰà§à¦˜ হল 2<<26 bytes (64 MiB)।" +msgstr[1] "" +"%u বাইটসমূহ দৈৰà§à¦˜à§° à¦à§°à§‡ সনà§à¦®à§à¦–িন হল। সৰà§à¦¬à¦¾à¦§à¦¿à¦• দৈৰà§à¦˜ হল 2<<26 bytes (64 MiB)।" + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"'a%c' ধৰণৰ à¦à§°à§‡à§° সনà§à¦®à§à¦–িন হল, %u বাইটৰ বহà§à¦—à§à¦¨ হিচাপে à¦à¦Ÿà¦¾ দৈৰà§à¦˜à§à¦¯ আশা কৰা " +"হৈছিল, কিনà§à¦¤à§ %u " +"বাইট দৈৰà§à¦˜à§à¦¯ পà§à§°à¦¾à¦ªà§à¦¤ হল" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "অপৰৰ বাবে বিশà§à¦²à§‡à¦·à¦£ কৰা মান '%s' à¦à¦Ÿà¦¾ বৈধ D-Bus সà§à¦¬à¦¾à¦•à§à¦·à§° নহয়" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"D-Bus তাà¦à§° বিনà§à¦¯à¦¾à¦¸à§° পৰা ধৰণ সà§à¦Ÿà§à§°à¦¿à¦‚ '%s' à§° সৈতে GVariant ডিচিৰিà¦à¦²à¦¾à¦‡à¦œ কৰোতে " +"তà§à§°à§à¦Ÿà¦¿" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"অবৈধ endianness মান। 0x6c ('l') অথবা 0x42 ('B') আশা কৰা হৈছিল কিনà§à¦¤à§ মান 0x" +"%02x পোৱা গল" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "অবৈধ মূখà§à¦¯ পà§à§°à¦Ÿà§‹à¦•ল সংসà§à¦•ৰণ। আশা কৰা হৈছিল 1 কিনà§à¦¤à§ পোৱা গল %d" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "সà§à¦¬à¦¾à¦•à§à¦·à§° '%s' à§° সৈতে সà§à¦¬à¦¾à¦•à§à¦·à§° হেডাৰ পোৱা গল কিনà§à¦¤à§ বাৰà§à¦¤à¦¾ অংশ ৰিকà§à¦¤" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "বিশà§à¦²à§‡à¦·à¦£ কৰা মান '%s' à¦à¦Ÿà¦¾ বৈধ D-Bus সà§à¦¬à¦¾à¦•à§à¦·à§° (দেহৰ বাবে)" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "বাৰà§à¦¤à¦¾à¦¤ কোনো সà§à¦¬à¦¾à¦•à§à¦·à§° হেডাৰ নাই কিনà§à¦¤à§ বাৰà§à¦¤à¦¾ দেহ হল %u বাইট" +msgstr[1] "বাৰà§à¦¤à¦¾à¦¤ কোনো সà§à¦¬à¦¾à¦•à§à¦·à§° হেডাৰ নাই কিনà§à¦¤à§ বাৰà§à¦¤à¦¾ দেহ হল %u বাইটসমূহ" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "বাৰà§à¦¤à¦¾ deserialize কৰিব নোৱাৰি: " + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"D-Bus তাà¦à§° বিনà§à¦¯à¦¾à¦¸à§° লে ধৰণ সà§à¦Ÿà§à§°à¦¿à¦‚ '%s' à§° সৈতে GVariant চিৰিà¦à¦²à¦¾à¦‡à¦œ কৰোতে তà§à§°à§à¦Ÿà¦¿" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"বাৰà§à¦¤à¦¾à§° %d ফাইল বিৱৰকসমূহ আছে কিনà§à¦¤à§ হেডাৰ কà§à¦·à§‡à¦¤à§à§°à§Ÿ %d ফাইল বিৱৰকসমূহৰ সূচনা " +"দিয়ে" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "বাৰà§à¦¤à¦¾ চিৰিয়েলাইজ কৰিব নোৱাৰি: " + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "বাৰà§à¦¤à¦¾ দেহৰ সà§à¦¬à¦¾à¦•à§à¦·à§° '%s' আছে কিনà§à¦¤à§ কোনো সà§à¦¬à¦¾à¦•à§à¦·à§° হেডাৰ নাই" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "বাৰà§à¦¤à¦¾ দেহৰ ধৰণ সà§à¦¬à¦¾à¦•à§à¦·à§° '%s' আছে কিনà§à¦¤à§ হেডাৰ কà§à¦·à§‡à¦¤à§à§°à¦¤ সà§à¦¬à¦¾à¦•à§à¦·à§° '%s'" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "বাৰà§à¦¤à¦¾ দেহ ৰিকà§à¦¤ কিনà§à¦¤à§ হেডাৰ কà§à¦·à§‡à¦¤à§à§°à¦¤ সà§à¦¬à¦¾à¦•à§à¦·à§° হল '(%s)'" + +#: ../gio/gdbusmessage.c:3282 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' ধৰণৰ দেহৰ সৈতে তà§à§°à§à¦Ÿà¦¿ ঘà§à§°à¦¾à¦‡ দিয়া হৈছে" + +#: ../gio/gdbusmessage.c:3290 +msgid "Error return with empty body" +msgstr "ৰিকà§à¦¤ দেহৰ সৈতে তà§à§°à§à¦Ÿà¦¿ ঘà§à§°à¦¾à¦‡ দিয়া হৈছে" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "হাৰà§à¦¡à§±à§‡à§° আলেখà§à¦¯ পà§à§°à¦¾à¦ªà§à¦¤ কৰিবলে অকà§à¦·à¦®: %s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "/var/lib/dbus/machine-id অথবা /etc/machine-id ল'ড কৰিবলে অকà§à¦·à¦®: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s à§° বাবে StartServiceByName কল কৰোতে তà§à§°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ উতà§à¦¤à§° %d StartServiceByName(\"%s\") পদà§à¦§à¦¤à¦¿à§° পৰা" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"পদà§à¦§à¦¤à¦¿ আৱাহন কৰিব নোৱাৰি; পà§à§°à¦•à§à¦¸à¦¿ à¦à¦Ÿà¦¾ জনপà§à§°à¦¿à§Ÿ কিনà§à¦¤à§ গৰাকী নথকা নামৰ বাবে আৰৠ" +"পà§à§°à¦•à§à¦¸à¦¿ " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START à§° সৈতে সৃষà§à¦Ÿà¦¿ কৰা হৈছিল" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "à¦à¦¬à¦¸à§à¦Ÿà§à§°à§‡à¦•à§à¦Ÿ নাম-সà§à¦ªà§‡à¦‡à¦š সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "à¦à¦Ÿà¦¾ চাৰà§à¦­à¦¾à§° সৃষà§à¦Ÿà¦¿ কৰোতে nonce file ধাৰà§à¦¯à§à¦¯ কৰিব নোৱাৰি" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' ত nonce file লিখোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "সà§à¦Ÿà§à§°à¦¿à¦‚ '%s' à¦à¦Ÿà¦¾ বৈধ D-Bus GUID নহয়" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "অসমৰà§à¦¥à¦¿à¦¤ পৰিৱহন '%s' ত শà§à¦¨à¦¿à¦¬ নোৱাৰি" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"কমানà§à¦¡à¦¸à¦®à§‚হ:\n" +" help à¦à¦‡ তথà§à¦¯ দেখà§à§±à¦¾à§Ÿ\n" +" introspect à¦à¦Ÿà¦¾ দূৰৱৰà§à¦¤à§€ অবজেকà§à¦Ÿ নিৰীকà§à¦·à¦£ কৰক\n" +" monitor à¦à¦Ÿà¦¾ দূৰৱৰà§à¦¤à§€ অবজেকà§à¦Ÿ মনিটৰ কৰক\n" +" call à¦à¦Ÿà¦¾ দূৰৱৰà§à¦¤à§€ অবজেকà§à¦Ÿà¦¤ à¦à¦Ÿà¦¾ পদà§à¦§à¦¤à¦¿ আৱাহন কৰক\n" +" emit à¦à¦Ÿà¦¾ সংকেত à¦à§°à¦•\n" +"\n" +"পà§à§°à¦¤à¦¿à¦Ÿà§‹ কমানà§à¦¡à¦¤ সহায়ৰ বাবে \"%s COMMAND --help\" বà§à¦¯à§±à¦¹à¦¾à§° কৰক।\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "নিৰীকà§à¦·à¦£ XML বিশà§à¦²à§‡à¦·à¦£ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "চিসà§à¦Ÿà§‡à¦® বাচৰ সৈতে সংযোগ কৰক" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "অধিবেশন বাচৰ সৈতে সংযোগ কৰক" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "পà§à§°à¦¦à¦¾à¦¨ কৰা D-Bus ঠিকনাৰ সৈতে সংযোগ কৰক" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "সংযোগ অনà§à¦¤à¦¬à¦¿à¦¨à§à¦¦à§ বিকলà§à¦ªà¦¸à¦®à§‚হ:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "সংযোগ অনà§à¦¤à¦¬à¦¿à¦¨à§à¦¦à§ ধাৰà§à¦¯à§à¦¯ কৰা বিকলà§à¦ªà¦¸à¦®à§‚হ" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "কোনো সংযোগ অনà§à¦¤à¦¬à¦¿à¦¨à§à¦¦à§ ধাৰà§à¦¯à§à¦¯ কৰা হোৱা নাই" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "বহৠসংযোগ অনà§à¦¤à¦¬à¦¿à¦¨à§à¦¦à§ ধাৰà§à¦¯à§à¦¯ কৰা হৈছে" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "সতৰà§à¦•বাৰà§à¦¤à¦¾: নিৰীকà§à¦·à¦£ তথà§à¦¯à§° মতে, আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  '%s' à§° অসà§à¦¤à¦¿à¦¤à§à¦¬ নাই\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"সতৰà§à¦•বাৰà§à¦¤à¦¾: নিৰীকà§à¦·à¦£ তথà§à¦¯à§° মতে, আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  '%s' ত পদà§à¦§à¦¤à¦¿ '%s' à§° অসà§à¦¤à¦¿à¦¤à§à¦¬ " +"নাই\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "সংকেতৰ বাবে বৈকলà§à¦ªà¦¿à¦• গনà§à¦¤à¦¬à§à¦¯ (অবিকলà§à¦ª নাম)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "সংকেত à¦à§°à¦¿à¦¬à¦²à§‡ অবজেকà§à¦Ÿ পথ" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "সংকেত আৰৠআনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  নাম" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "à¦à¦Ÿà¦¾ সংকেত à¦à§°à¦•।" + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "সংযোগ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: অবজেকà§à¦Ÿ পথ ধাৰà§à¦¯à§à¦¯ কৰা হোৱা নাই।\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: %s à¦à¦Ÿà¦¾ বৈধ অবজেকà§à¦Ÿ পথ নহয়\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: সংকেত ধাৰà§à¦¯à§à¦¯ কৰা হোৱা নাই।\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: সংকেত সমà§à¦ªà§‚à§°à§à¦£à¦­à¦¾à§±à§‡-অৰà§à¦¹à¦¤à¦¾à¦¸à¦®à§à¦ªà¦¨à§à¦¨ নাম হব লাগিব।\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: %s à¦à¦Ÿà¦¾ বৈধ আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  নাম নহয়\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: %s à¦à¦Ÿà¦¾ বৈধ সদসà§à¦¯ নাম নহয়\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: %s à¦à¦Ÿà¦¾ বৈধ অবিকলà§à¦ª বাচ নাম নহয়।\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "পà§à§°à¦¾à¦šà¦² %d বিশà§à¦²à§‡à¦·à¦£ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "সংযোগ পৰিষà§à¦•াৰ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "পদà§à¦§à¦¤à¦¿ আৱাহন কৰিবলে গনà§à¦¤à¦¬à§à¦¯ নাম" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "পদà§à¦§à¦¤à¦¿ আৱাহন কৰিবলে অবজেকà§à¦Ÿ পথ" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "পদà§à¦§à¦¤à¦¿ আৰৠআনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  নাম" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "ছেকেণà§à¦¡à¦¸à¦®à§‚হত সময়অনà§à¦¤" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "à¦à¦Ÿà¦¾ দূৰৱৰà§à¦¤à§€ অবজেকà§à¦Ÿà¦¤ à¦à¦Ÿà¦¾ পদà§à¦§à¦¤à¦¿ আৱাহন কৰক।" + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: গনà§à¦¤à¦¬à§à¦¯ ধাৰà§à¦¯à§à¦¯ কৰা হোৱা নাই\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: অবজেকà§à¦Ÿ পথ ধাৰà§à¦¯à§à¦¯ কৰা হোৱা নাই\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: পদà§à¦§à¦¤à¦¿ নাম ধাৰà§à¦¯à§à¦¯ কৰা হোৱা নাই\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "তà§à§°à§à¦Ÿà¦¿: পদà§à¦§à¦¤à¦¿ নাম '%s' অবৈধ\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "পà§à§°à¦¾à¦šà¦² %d বিশà§à¦²à§‡à¦·à¦£ কৰোতে তà§à§°à§à¦Ÿà¦¿ ধৰণ '%s': %s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "নিৰীকà§à¦·à¦£ কৰিবলে গনà§à¦¤à¦¬à§à¦¯ নাম" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "নিৰীকà§à¦·à¦£ কৰিবলে অবজেকà§à¦Ÿ পথ" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "XML পà§à§°à¦¿à¦¨à§à¦Ÿ কৰক" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "সনà§à¦¤à¦¾à¦¨ নিৰীকà§à¦·à¦£ কৰক" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "কেৱল বৈশিষà§à¦Ÿà¦¸à¦®à§‚হ পà§à§°à¦¿à¦¨à§à¦Ÿ কৰক" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "à¦à¦Ÿà¦¾ দূৰৱৰà§à¦¤à§€ অবজেকà§à¦Ÿ নিৰীকà§à¦·à¦£ কৰক।" + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "মনিটৰলে গনà§à¦¤à¦¬à§à¦¯ নাম" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "মনিটৰলে অবজেকà§à¦Ÿ পথ" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "à¦à¦Ÿà¦¾ দূৰৱৰà§à¦¤à§€ অবজেকà§à¦Ÿ মনিটৰ কৰক।" + +#: ../gio/gdesktopappinfo.c:1919 ../gio/gdesktopappinfo.c:4440 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "নামবিহীন" + +#: ../gio/gdesktopappinfo.c:2328 +msgid "Desktop file didn't specify Exec field" +msgstr "ডেসà§à¦•টপ ফাইলত Exec কà§à¦·à§‡à¦¤à§à§° নিৰà§à¦§à¦¾à§°à¦¿à¦¤ নহয়" + +#: ../gio/gdesktopappinfo.c:2613 +msgid "Unable to find terminal required for application" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচনৰ বাবে আৱশà§à¦¯à¦• টাৰà§à¦®à¦¿à¦¨à§‡à¦² পোৱা নাযায়" + +#: ../gio/gdesktopappinfo.c:3034 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "বà§à¦¯à§±à¦¹à¦¾à§°à¦•াৰী à¦à¦ªà§à¦²à¦¿à¦•েচনৰ বিনà§à¦¯à¦¾à¦¸ ফোলà§à¦¡à¦¾à§° %s সৃষà§à¦Ÿà¦¿ কৰিবলৈ বà§à¦¯à§°à§à¦¥: %s" + +#: ../gio/gdesktopappinfo.c:3038 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "বà§à¦¯à§±à¦¹à¦¾à§°à¦•াৰী MIME বিনà§à¦¯à¦¾à¦¸ ফোলà§à¦¡à¦¾à§° %s সৃষà§à¦Ÿà¦¿ কৰিবলৈ বà§à¦¯à§°à§à¦¥: %s" + +#: ../gio/gdesktopappinfo.c:3278 ../gio/gdesktopappinfo.c:3302 +msgid "Application information lacks an identifier" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচন তথà§à¦¯à§° à¦à¦Ÿà¦¾ পৰিচয়কৰ পà§à§°à§Ÿà§‹à¦œà¦¨" + +#: ../gio/gdesktopappinfo.c:3535 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "বà§à¦¯à§±à¦¹à¦¾à§°à¦•াৰী ডেসà§à¦•টপ ফাইল %s সৃষà§à¦Ÿà¦¿ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../gio/gdesktopappinfo.c:3669 +#, c-format +msgid "Custom definition for %s" +msgstr "%s à§° বাবে সà§à¦¬à¦¨à¦¿à§°à§à¦§à¦¾à§°à¦¤ বà§à¦¯à¦¾à¦–à§à¦¯à¦¾" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "ডà§à§°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à§°à¦¾ ইজেকà§à¦Ÿ কৰà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ নহয়" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "ডà§à§°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à§°à¦¾ ইজেকà§à¦Ÿ বা eject_with_operation কৰà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ নহয়" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "ডà§à§°à¦¾à¦‡à¦­à¦¤ মিডিয়াৰ বাবে প'ল কৰাৰ কাৰà§à¦¯à¦•à§à¦·à¦®à¦¤à¦¾ নাই" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "ডà§à§°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à§°à¦¾ আৰমà§à¦­ কৰà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ নহয়" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "ডà§à§°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à§°à¦¾ বনà§à¦§ কৰà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ নহয়" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS সমৰà§à¦¥à¦¨ উপলবà§à¦§ নহয়" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem encoding à§° %d সংসà§à¦•ৰণ পৰিচালন কৰিব নোৱাৰি" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem encoding ত ট'কেনৰ তà§à§°à§à¦Ÿà¦¿ সংখà§à¦¯à¦¾ (%d)" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon encoding à§° %d সংসà§à¦•ৰণ পৰিচালন কৰিব নোৱাৰি" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon encoding ত ট'কেনৰ তà§à§°à§à¦Ÿà¦¿ সংখà§à¦¯à¦¾ (%d)" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon à§° কাৰণে à¦à¦Ÿà¦¾ GEmblem পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../gio/gfile.c:956 ../gio/gfile.c:1194 ../gio/gfile.c:1332 +#: ../gio/gfile.c:1570 ../gio/gfile.c:1625 ../gio/gfile.c:1683 +#: ../gio/gfile.c:1767 ../gio/gfile.c:1824 ../gio/gfile.c:1888 +#: ../gio/gfile.c:1943 ../gio/gfile.c:3591 ../gio/gfile.c:3646 +#: ../gio/gfile.c:3853 ../gio/gfile.c:3895 ../gio/gfile.c:4358 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7748 ../gio/gfile.c:7838 ../gio/gfile.c:7922 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "কাৰà§à¦¯à§à¦¯ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1455 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "ধাৰণকাৰী মাউনà§à¦Ÿ উপসà§à¦¥à¦¿à¦¤ নাই" + +#: ../gio/gfile.c:2502 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "ডাইৰেকটৰিৰ ওপৰত কপি কৰা নাযাব" + +#: ../gio/gfile.c:2562 +msgid "Can't copy directory over directory" +msgstr "ডাইৰেকটৰিৰ ওপৰত ডাইৰেকটৰি কপি কৰা নাযায়" + +#: ../gio/gfile.c:2570 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "লকà§à¦·à§à¦¯ ফাইল উপসà§à¦¥à¦¿à¦¤ আছে" + +#: ../gio/gfile.c:2589 +msgid "Can't recursively copy directory" +msgstr "ৰিকাৰà§à¦›à¦¿à¦­ ভাবে ডাইৰেকটৰি কপি কৰা নাযাব" + +#: ../gio/gfile.c:2871 +msgid "Splice not supported" +msgstr "Splice সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gfile.c:2875 +#, c-format +msgid "Error splicing file: %s" +msgstr "ফাইল splice কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gfile.c:3006 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "মাউনà§à¦Ÿà¦¸à¦®à§‚হৰ মাজত কপি (ৰিফà§à¦²à¦¿à¦™à§à¦•/কà§à¦²à§Œà¦¨) সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gfile.c:3010 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "কপি (ৰিফà§à¦²à¦¿à¦™à§à¦•/কà§à¦²à§Œà¦¨) সমৰà§à¦¥à¦¿à¦¤ নহয় অথবা অবৈধ" + +#: ../gio/gfile.c:3015 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "কপি (ৰিফà§à¦²à¦¿à§ƒà¦™à§à¦•/কà§à¦²à§Œà¦¨) সমৰà§à¦¥à¦¿à¦¤ নহয় অথবা কাম নকৰিলে" + +#: ../gio/gfile.c:3078 +msgid "Can't copy special file" +msgstr "বিশেষ ফাইল কপি কৰিব নোৱাৰি" + +#: ../gio/gfile.c:3843 +msgid "Invalid symlink value given" +msgstr "অৱৈধ চিমসংযোগ মান উপলবà§à¦§ কৰা হৈছে" + +#: ../gio/gfile.c:4004 +msgid "Trash not supported" +msgstr "আবৰà§à¦œà¦¨à¦¾ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gfile.c:4116 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ফাইলৰ নামত '%c' বà§à¦¯à§±à¦¹à¦¾à§° কৰা নাযাব" + +#: ../gio/gfile.c:6540 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "ভলিউম দà§à¦¬à¦¾à§°à¦¾ mount পà§à§°à§Ÿà§‹à¦— কৰা নহয়" + +#: ../gio/gfile.c:6649 +msgid "No application is registered as handling this file" +msgstr "চিহà§à¦¨à¦¿à¦¤ ফাইল বà§à¦¯à§±à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾à§° উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ কোনো à¦à¦ªà§à¦²à¦¿à¦•েচন নিবনà§à¦§à¦¿à¦¤ নহয়" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator বনà§à¦§" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ফাইল enumerator ত অসমাপà§à¦¤ কৰà§à¦® উপসà§à¦¥à¦¿à¦¤" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ফাইল enumerator à§° বনà§à¦§" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon encoding à§° %d সংসà§à¦•ৰণ পৰিচালন কৰিব নোৱাৰি" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon à§° কাৰণে তà§à§°à§à¦Ÿà¦¿ ইনপà§à¦Ÿ তথà§à¦¯" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "সà§à§°à§‹à¦¤ দà§à¦¬à¦¾à§°à¦¾ query_info সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "সà§à§°à§‹à¦¤ দà§à¦¬à¦¾à§°à¦¾ Seek সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ইনপà§à¦Ÿ সà§à§°à§‹à¦¤à¦¤ Truncate à§° অনà§à¦®à¦¤à¦¿ নাই" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "সà§à§°à§‹à¦¤à¦¤ Truncate à§° সমৰà§à¦¥à¦¨ নাই" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "ট'কেনৰ তà§à§°à§à¦Ÿà¦¿ সংখà§à¦¯à¦¾ (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "শà§à§°à§‡à¦£à§€à§° নাম %s à§° ধৰণ নাই" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s ধৰনে GIcon আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦  পà§à§°à¦£à§Ÿà¦¨ নকৰে" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "%s ধৰণক class কৰা হোৱা নাই" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "তà§à§°à§à¦Ÿà¦¿ সংসà§à¦•ৰণ সংখà§à¦¯à¦¾: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s ধৰণে from_tokens() পà§à§°à¦£à§Ÿà¦¨ নকৰে GIcon আনà§à¦¤à¦ƒà¦ªà§ƒà¦·à§à¦ à¦¤" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "আইকন à¦à¦¨à¦•'ডিংৰ পà§à§°à¦¦à¦¾à¦¨ কৰা সংসà§à¦•ৰণ পৰিচালন কৰিব নোৱাৰি" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "কোনো ঠিকনা ধাৰà§à¦¯à§à¦¯ কৰা হোৱা নাই" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "দৈৰà§à¦˜à§à¦¯ %u ঠিকনাৰ বাবে অতি দীঘল" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ঠিকনাৰ বিটসমূহ সংহতি উপসৰà§à¦— দৈৰà§à¦˜à§° বাহিৰ আছে" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "'%s' ক IP ঠিকনা মাসà§à¦• হিচাপে বিশà§à¦²à§‡à¦·à¦£ কৰিব পৰা নগল" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "চকেট ঠিকনাৰ কাৰণে যথেষà§à¦Ÿ সà§à¦¥à¦¾à¦¨ নাই" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "অসমৰà§à¦¥à¦¿à¦¤ চকেট ঠিকনা" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "ইনপà§à¦Ÿ সà§à§°à§‹à¦¤à§‡ পà§à¦¾ কাৰà§à¦¯ ৰূপায়ন নকৰে" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1027 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1474 +msgid "Stream has outstanding operation" +msgstr "সà§à§°à§‹à¦¤à§° কà§à¦·à§‡à¦¤à§à§°à¦¤ অসমাপà§à¦¤ কৰà§à¦® উপসà§à¦¥à¦¿à¦¤ আছে" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "উপাদান <%s> <%s> à§° ভিতৰত অনà§à¦®à§‹à¦¦à¦¿à¦¤ নহয়" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "উপাদান <%s> ওপৰসà§à¦¤à§°à¦¤ অনà§à¦®à§‹à¦¦à¦¿à¦¤ নহয়" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "ফাইল %s সমà§à¦ªà¦¦à¦¤ বহà§à¦¬à¦¾à§° দেখা গৈছে" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "কোনো উৎস ডাইৰেকটৰিত '%s' অৱসà§à¦¥à¦¾à¦¨ কৰাত বà§à¦¯à§°à§à¦¥" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "বৰà§à¦¤à¦®à¦¾à¦¨ ডাইৰেকটৰিত '%s' অৱসà§à¦¥à¦¾à¦¨ কৰাত বà§à¦¯à§°à§à¦¥" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "অজà§à¦žà¦¾à¦¤ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à¦•ৰণ বিকলà§à¦ª \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "অসà§à¦¥à¦¾à§Ÿà§€ ফাইল সৃষà§à¦Ÿà¦¿ কৰোতে বà§à¦¯à§°à§à¦¥: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "ফাইল %s পà§à§‹à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "ফাইল %s সংকোচন কৰোতে তà§à§°à§à¦Ÿà¦¿" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "লিখনি <%s> à§° ভিতৰত নাহিবও পাৰে" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "আউটপà§à¦Ÿ ফাইলৰ নাম" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "ডাইৰেকটৰিসমূহ যৰ পৰা ফাইলসমূহ পà§à¦¾ হব (বৰà§à¦¤à¦®à¦¾à¦¨ ডাইৰেকটৰিলে অবিকলà§à¦ªà¦¿à¦¤) " + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "লকà§à¦·à§à¦¯ ফাইল সমà§à¦ªà§à§°à¦¸à¦¾à§°à¦¨ দà§à¦¬à¦¾à§°à¦¾ নিৰà§à¦¬à¦¾à¦šà¦¿à¦¤ বিনà§à¦¯à¦¾à¦¸à¦¤ আউটপà§à¦Ÿ সৃজন কৰক" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "উৎস হেডাৰ সৃজন কৰক" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "আপোনাৰ ক'ডত সমà§à¦ªà¦¦ ফাইলৰ সৈতে সংযোগ কৰিবলে বà§à¦¯à§±à¦¹à§ƒà¦¤ উৎসক'ড সৃজন কৰক" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "নিৰà§à¦­à§°à¦¤à¦¾ তালিকা সৃজন কৰক" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "সমà§à¦ªà¦¦à¦• সà§à¦¬à¦šà¦¾à¦²à¦¿à¦¤à¦­à¦¾à§±à§‡ সৃষà§à¦Ÿà¦¿ আৰৠৰেজিসà§à¦Ÿà¦¾à§° নকৰিব" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "ফলনসমূহ à¦à¦•à§à¦¸à¦ªà§‹à§°à§à¦Ÿ নকৰিব; সিহতক G_GNUC_INTERNAL ঘোষণা কৰক" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "সৃজন কৰা উৎস ক'ডৰ বাবে C identifier নাম বà§à¦¯à§±à¦¹à¦¾à§° কৰা হৈছে" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"à¦à¦Ÿà¦¾ সমà§à¦ªà¦¦ ফাইলত à¦à¦Ÿà¦¾ সমà§à¦ªà¦¦ ধাৰà§à¦¯à§à¦¯à¦•ৰণ কমপাইল কৰক।\n" +"সমà§à¦ªà¦¦ ধাৰà§à¦¯à§à¦¯à¦•ৰণ ফাইলসমূহৰ পà§à§°à¦¸à¦¾à§°à¦£ .gresource.xml থাকে,\n" +"আৰৠসমà§à¦ªà¦¦ ফাইলৰ পà§à§°à¦¸à¦¾à§°à¦£ .gresource থাকে।" + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "আপà§à¦¨à¦¿ à¦à¦Ÿà¦¾ ফাইল নাম দিব লাগিব\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "ৰিকà§à¦¤ নামসমূহৰ অনà§à¦®à¦¤à¦¿ নাই" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "অবৈধ নাম '%s': নামসমূহ à¦à¦Ÿà¦¾ তলফলা আখৰৰে আৰমà§à¦­ হব লাগিব" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"অবৈধ নাম '%s': অবৈধ আখৰ '%c'; কেৱল তলৰফলা আখৰসমূহ, নমà§à¦¬à§°à¦¸à¦®à§‚হ আৰৠহাইফেন ('-') " +"à§° " +"অনà§à¦®à¦¤à¦¿ আছে।" + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "অবৈধ নাম '%s': দà§à¦Ÿà¦¾ কà§à§°à¦®à¦¾à¦—ত হাইফেন ('--') à§° অনà§à¦®à¦¤à¦¿ নাই।" + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "অবৈধ নাম '%s': শেষ আখৰ à¦à¦Ÿà¦¾ হাইফেন ('-') নহবও পাৰে।" + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "অবৈধ নাম '%s': সৰà§à¦¬à¦¾à¦§à¦¿à¦• দৈৰà§à¦˜ হল ১০২৪" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " ইতিমধà§à¦¯à§‡ ধাৰà§à¦¯à§à¦¯à¦¤" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "à¦à¦Ÿà¦¾ 'list-of' সà§à¦•িমালে কিসমূহ যোগ কৰিব নোৱাৰি" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " ইতিমধà§à¦¯à§‡ ধাৰà§à¦¯à§à¦¯à¦¤" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" ত ছায়াসমূহ ; মান সলনি কৰিবলে " +" বà§à¦¯à§±à¦¹à¦¾à§° কৰক" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"à¦à¦Ÿà¦¾ 'type', 'enum' অথবা 'flags' à¦à¦Ÿà¦¾ বৈশিষà§à¦Ÿ হিচাপে লে ধাৰà§à¦¯à§à¦¯ কৰিব লাগিব" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (à¦à¦¤à¦¿à§Ÿà¦¾à¦“) বিৱৰিত নহয়।" + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "অবৈধ GVariant ধৰণ সà§à¦Ÿà§à§°à¦¿à¦‚ '%s'" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " দিয়া হৈছে কিনà§à¦¤à§ সà§à¦•িমায় à¦à¦•à§‹ পà§à§°à¦¸à¦¾à§°à¦¨ কৰা নাই" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "অভাৰৰাইড কৰিবলে কোনো নাই" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " ইতিমধà§à¦¯à§‡ ধাৰà§à¦¯à§à¦¯à¦¤" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " ইতিমধà§à¦¯à§‡ ধাৰà§à¦¯à§à¦¯à¦¤" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " ঠà¦à¦¤à¦¿à§Ÿà¦¾à¦“ অসà§à¦¤à¦¿à¦¤à§à¦¬à¦¤ নহোৱা সà§à¦•িমা '%s' ক পà§à§°à¦¸à¦¾à§°à¦¨ কৰে" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " à¦à¦¤à¦¿à§Ÿà¦¾à¦“ অসà§à¦¤à¦¿à¦¤à§à¦¬à¦¤ নহোৱা সà§à¦•িমা '%s' à§° তালিকা" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "à¦à¦Ÿà¦¾ পথৰ সৈতে à¦à¦Ÿà¦¾ সà§à¦•িমাৰ à¦à¦Ÿà¦¾ তালিকা হব নোৱাৰিব" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "à¦à¦Ÿà¦¾ পথৰ সৈতে à¦à¦Ÿà¦¾ সà§à¦•িমা পà§à§°à¦¸à¦¾à§°à¦¨ কৰিব নোৱাৰি" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" à¦à¦Ÿà¦¾ তালিকা, যি à¦à¦Ÿà¦¾ তালিকা নহয় পà§à§°à¦¸à¦¾à§°à¦¨ কৰা " +"হৈছে" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" ঠপà§à§°à¦¸à¦¾à§°à¦¨ কৰে " +"কিনà§à¦¤à§ '%s' ঠ'%s' পà§à§°à¦¸à¦¾à§°à¦¨ নকৰে" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "à¦à¦Ÿà¦¾ পথ, যদি দিয়া আছে, à¦à¦Ÿà¦¾ সà§à¦²à§‡à¦¶à§° সৈতে আৰমà§à¦­ আৰৠঅনà§à¦¤ হব লাগিব" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "à¦à¦Ÿà¦¾ তালিকাৰ পথ ':/' à§° সৈতে শেষ হব লাগিব" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ইতিমধà§à¦¯à§‡ ধাৰà§à¦¯à§à¦¯à¦¤" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "উপাদান <%s> ওপৰ সà§à¦¤à§°à¦¤ অনà§à¦®à§‹à¦¦à¦¿à¦¤ নহয়" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict ধাৰà§à¦¯à§à¦¯ কৰা হৈছিল; পà§à§°à¦¸à§à¦¥à¦¾à¦¨ কৰা হৈছিল।\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "à¦à¦‡ সমà§à¦ªà§‚à§°à§à¦£ ফাইল উপেকà§à¦·à¦¾ কৰা হৈছে।\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "à¦à¦‡ ফাইল উপেকà§à¦·à¦¾ কৰা হৈছে।\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "অভাৰৰাইড ফাইল '%s' ত দেখà§à§±à¦¾ দৰে সà§à¦•িমা '%s' ত à¦à¦¨à§‡ কোনো কি '%s' নাই" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; à¦à¦‡ কিৰ বাবে অভাৰৰাইড উপেকà§à¦·à¦¾ কৰা হৈছে।\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " আৰৠ--strict ধাৰà§à¦¯à§à¦¯ কৰা হৈছিল; পà§à§°à¦¸à§à¦¥à¦¾à¦¨ কৰা হৈছে।\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"অভাৰৰাইড ফাইল '%s' ত দেখà§à§±à¦¾ দৰে সà§à¦•িমা '%s' ত কি' '%s' বিশà§à¦²à§‡à¦·à¦£ কৰোতে তà§à§°à§à¦Ÿà¦¿: " +"%s।" + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "à¦à¦‡ কিৰ বাবে অভাৰৰাইড উপেকà§à¦·à¦¾ কৰা হৈছে।\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"অভাৰৰাইড ফাইল '%s' ত সà§à¦•িমা '%s' ত কি '%s' à§° বাবে অভাৰৰাইড সà§à¦•িমাত দিয়া " +"বিসà§à¦¤à¦¾à§°à§° বাহিৰ" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"অভাৰৰাইড ফাইল '%s' ত সà§à¦•িমা '%s' ত কি '%s' à§° বাবে অভাৰৰাইড বৈধ পছনà§à¦¦à¦¸à¦®à§‚হৰ " +"তালিকাত নাই" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled ফাইল ক'ত সংৰকà§à¦·à¦£ কৰা হব" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "সà§à¦•িমাসমূহত যিকোনো তà§à§°à§à¦Ÿà¦¿à¦¤ বাতিল কৰিব" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled ফাইল নিলিখিব" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "কি নাম বাধাসমূহ বলৱৎ নকৰিব" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"সকলো GSettings সà§à¦•িমা ফাইলসমূহক à¦à¦Ÿà¦¾ সà§à¦•িমা কà§à¦¯à¦¾à¦¶à¦¤ কমপাইল কৰক।\n" +"সà§à¦•িমা ফাইলসমূহৰ সমà§à¦ªà§à§°à¦¸à¦¾à§°à¦¨ .gschema.xml থাকিব লাগিব,\n" +"আৰৠকà§à¦¯à¦¾à¦¶ ফাইলক gschemas.compiled কোৱা হয়।" + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "আপà§à¦¨à¦¿ à¦à¦Ÿà¦¾ ডাইৰেকটৰি নাম দিব লাগিব\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "কোনো সà§à¦•িমা ফাইল পোৱা নগল:" + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "à¦à¦•à§‹ কৰা নাই।\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "অসà§à¦¤à¦¿à¦¤à§à¦¬à¦¬à¦¾à¦¨ আউটপà§à¦Ÿ ফাইল আতৰোৱা হল।\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "অবিকলà§à¦ªà¦¿à¦¤ সà§à¦¥à¦¾à¦¨à§€à§Ÿ ডাইৰেকটৰিৰ মনিটৰৰ ধৰণ পোৱা নগল" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "ফাইলৰ নাম অৱৈধ: %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ফাইলচিসà§à¦Ÿà§‡à¦® তথà§à¦¯ পà§à§°à¦¾à¦ªà§à¦¤ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "root ডাইৰেকটৰিৰ নাম পৰিবৰà§à¦¤à¦¨ কৰা সমà§à¦­à§± নহয়" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "ফাইলৰ নাম পৰিবৰà§à¦¤à¦¨à¦¤ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "ফাইল পà§à¦¨à§° নামকৰণ কৰিব নোৱাৰি, ফাইলনাম ইতিমধà§à¦¯à§‡ অসà§à¦¤à¦¿à¦¤à§à¦¬à¦¬à¦¾à¦¨" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "ফাইলৰ নাম অবৈধ" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "ডাইৰেকটৰি খোলিবলৈ সমসà§à¦¯à¦¾" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "ফাইল খোলিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "ফাইল আà¦à¦¤à§°à¦¾à¦¬à¦²à§ˆ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "ফাইল আবৰà§à¦œà¦¨à¦¾à¦²à§ˆ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à§° কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "আবৰà§à¦œà¦¨à¦¾à§° ডাইৰেকটৰি %s সৃষà§à¦Ÿà¦¿ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "আবৰà§à¦œà¦¨à¦¾à§° ঊৰà§à¦§à§à¦¬à¦¤à¦¨ ডাইৰেকটৰি চিনাকà§à¦¤ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "আবৰà§à¦œà¦¨à¦¾à§° ডাইৰেকটৰি চিনাকà§à¦¤ বা সৃষà§à¦Ÿà¦¿ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "trashing তথà§à¦¯à§° ফাইল সৃষà§à¦Ÿà¦¿ কৰিব নোৱাৰি: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ফাইল বৰà§à¦œà¦¨ কৰিবলৈ বà§à¦¯à§°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "অভà§à¦¯à¦¨à§à¦¤à§°à§€à¦£ তà§à§°à§à¦Ÿà¦¿" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "ডাইৰেকটৰি সৃষà§à¦Ÿà¦¿ কৰিবলৈ বà§à¦¯à§°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ফাইলচিসà§à¦Ÿà§‡à¦®à§Ÿà§‡ সাংকেতিক সংযোগসমূহ সমৰà§à¦¥à¦¨ নকৰে" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "চিমসংযোগ সৃষà§à¦Ÿà¦¿ কৰিবলৈ বà§à¦¯à§°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "ফাইল সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à§° কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "ডাইৰেকটৰিৰ ওপৰত ডাইৰেকটৰি সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à§° কৰা নাযাব" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "বেক-আপ ফাইল সৃষà§à¦Ÿà¦¿ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "লকà§à¦·à§à¦¯ ফাইল আà¦à¦¤à§°à¦¾à¦¬à¦²à§ˆ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "মাউনà§à¦Ÿ কৰা অৱসà§à¦¥à¦¾à¦¨à¦¤ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à§° কৰা সমà§à¦­à§± নহয়" + +#: ../gio/glocalfile.c:2603 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s à§° ডিসà§à¦• বà§à¦¯à§±à¦¹à¦¾à§° নিৰà§à¦§à¦¾à§°à¦£ কৰিব পৰা নগল: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "বৈশিষà§à¦Ÿà§° মান নন-NULL হব লাগিব" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "অবৈধ বৈশিষà§à¦Ÿà§° ধৰণ (সà§à¦Ÿà§à§°à¦¿à¦‚ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "অবৈধ সমà§à¦ªà§à§°à¦¸à¦¾à§°à¦¿à¦¤ বৈশিষà§à¦Ÿà§° নাম" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "সমà§à¦ªà§à§°à¦¸à¦¾à§°à¦¿à¦¤ বৈশিষà§à¦Ÿ নিৰà§à¦§à¦¾à§°à¦£ কৰোà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿ '%s': %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (অৱৈধ à¦à¦¨à¦•'ডিং)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "ফাইল '%s' à§° বাবে তথà§à¦¯ পà§à§°à¦¾à¦ªà§à¦¤ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "ফাইল বিৱৰকৰ বাবে তথà§à¦¯ পà§à§°à¦¾à¦ªà§à¦¤ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "অবৈধ বৈশিষà§à¦Ÿà§° ধৰণ (পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ uint32)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "অবৈধ বৈশিষà§à¦Ÿà§° ধৰণ (পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ uint64)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "অবৈধ বৈশিষà§à¦Ÿà§° ধৰণ (পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ byte সà§à¦Ÿà§à§°à¦¿à¦‚)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "চিমসংযোগসমূহত সনà§à¦®à¦¤à¦¿ নিৰà§à¦§à¦¾à§°à¦£ কৰিব নোৱাৰি" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "অনà§à¦®à¦¤à¦¿ নিৰà§à¦§à¦¾à§°à¦£ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "গৰাকী নিৰà§à¦§à¦¾à§°à¦£ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "চিমসংযোগ NULL হ'ব নোৱাৰে" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "চিমসংযোগ নিৰà§à¦§à¦¾à§°à¦£ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "চিমসংযোগ নিৰà§à¦§à¦¾à§°à¦£ কৰিবলৈ তà§à§°à§à¦Ÿà¦¿: ফাইল চিমসংযোগ নহয়" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "পৰিবৰà§à¦¤à¦¨ বা অভিগমৰ সময় নিৰà§à¦§à¦¾à§°à¦£ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux à§° সনà§à¦¦à§°à§à¦­ NULL হ'ব নোৱাৰে" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux à§° সনà§à¦¦à§°à§à¦­ নিৰà§à¦§à¦¾à§°à¦£ কৰিবলৈ বà§à¦¯à§°à§à¦¥: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "à¦à¦‡ চিসà§à¦Ÿà§‡à¦®à¦¤ SELinux সকà§à§°à¦¿à§Ÿ কৰা নাই" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s বৈশিষà§à¦Ÿà§° মান নিৰà§à¦§à¦¾à§°à¦£ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "ফাইলৰ পৰা পà§à¦¿à¦¬à¦²à§ˆ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ফাইলত seek কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "ফাইল বনà§à¦§ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "অবিকলà§à¦ªà¦¿à¦¤ সà§à¦¥à¦¾à¦¨à§€à§Ÿ ফাইলৰ মনিটৰৰ ধৰণ পোৱা নগল" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "ফাইললৈ লিখিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "পà§à§°à¦¨à¦¿ বেক-আপ সংযোগ আà¦à¦¤à§°à¦¾à¦¬à¦²à§ˆ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "বেক-আপ পà§à§°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ সৃষà§à¦Ÿà¦¿ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "অসà§à¦¥à¦¾à§Ÿà§€ ফাইলৰ নাম পৰিবৰà§à¦¤à¦¨ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "ফাইল সৰৠকৰিবলৈ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "ফাইল '%s' খোলিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "লকà§à¦·à§à¦¯ ফাইল à¦à¦Ÿà¦¾ ডাইৰেকটৰি" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "লকà§à¦·à§à¦¯ ফাইল সাধাৰণ ফাইল নহয়" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "ফাইল বহিৰà§à¦¤à¦®à¦­à¦¾à§±à§‡ পৰিবৰà§à¦¤à¦¨ কৰা হৈছে" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "পà§à§°à¦¨à¦¿ ফাইল আà¦à¦¤à§°à¦¾à¦¬à¦²à§ˆ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "অৱৈধ GSeekType উলà§à¦²à¦¿à¦–িত হৈছে" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "অৱৈধ seek à§° অনà§à§°à§‹à¦§" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream ক truncate কৰিব নোৱাৰি" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "মেমৰিৰ আউটপà§à¦Ÿà§° সà§à§°à§‹à¦¤à¦• পà§à¦¨à¦ƒ আকাৰ দিব নোৱাৰি" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "মেমৰিৰ আউটপà§à¦Ÿà§° সà§à§°à§‹à¦¤à¦• পà§à¦¨à¦ƒ আকাৰ দিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"লিখা পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ কৰিবলে পà§à§°à§Ÿà§‹à¦œà¦¨à§€à§Ÿ মেমৰিৰ পৰিমাণ উপসà§à¦¥à¦¿à¦¤ ঠিকনা সà§à¦¥à¦¾à¦¨à¦¤à¦•ে অধিক" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "সà§à§°à§‹à¦¤à§° আৰমà§à¦­à¦£à¦¿à§° আগত সনà§à¦§à¦¾à¦¨à§° অনà§à§°à§‹à¦§ কৰা হৈছে" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "সà§à§°à§‹à¦¤à§° শেষ পাৰ হৈ সনà§à¦§à¦¾à¦¨à§° অনà§à§°à§‹à¦§ কৰা হৈছে" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "mount ঠ\"unmount\" পà§à§°à¦£à§Ÿà¦¨ নকৰে" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "mount ঠ\"eject\" পà§à§°à¦£à§Ÿà¦¨ নকৰে " + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "mount ঠ\"unmount\" অথবা \"unmount_with_operation\" পà§à§°à¦£à§Ÿà¦¨ নকৰে" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "mount ঠ\"eject\" অথবা \"eject_with_operation\" পà§à§°à¦£à§Ÿà¦¨ নকৰে" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "mount ঠ\"remount\" পà§à§°à¦£à§Ÿà¦¨ নকৰে" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "mount দà§à¦¬à¦¾à§°à¦¾ সামগà§à§°à§€à§° ধৰণ অনà§à¦®à¦¾à¦¨ কৰা সমà§à¦­à§± নহয়" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "mount দà§à¦¬à¦¾à§°à¦¾ সà§à¦¸à¦‚গতভাবে সামগà§à§°à§€à§° ধৰণ অনà§à¦®à¦¾à¦¨ কৰা সমà§à¦­à§± নহয়" + +#: ../gio/gnetworkaddress.c:338 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "হসà§à¦Ÿà¦¨à¦¾à¦® '%s' ঠ'[' কিনà§à¦¤à§ নহয় ']' অনà§à¦¤à§°à§à¦­à§à¦•à§à¦¤ কৰে" + +#: ../gio/gnetworkmonitorbase.c:189 ../gio/gnetworkmonitorbase.c:292 +msgid "Network unreachable" +msgstr "নেটৱৰà§à¦• পà§à§°à¦¾à¦ªà§à¦¤ কৰিব নোৱাৰি" + +#: ../gio/gnetworkmonitorbase.c:227 ../gio/gnetworkmonitorbase.c:257 +msgid "Host unreachable" +msgstr "হসà§à¦Ÿ পà§à§°à¦¾à¦ªà§à¦¤ কৰিব নোৱাৰি" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "নেটৱৰà§à¦• মনিটৰ সৃষà§à¦Ÿà¦¿ কৰিব পৰা নগল: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "নেটৱৰà§à¦• মনিটৰ সৃষà§à¦Ÿà¦¿ কৰিব পৰা নগল:" + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "নেটৱৰà§à¦• অৱসà§à¦¥à¦¾ পà§à§°à¦¾à¦ªà§à¦¤ কৰিব নোৱাৰি: " + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:550 +msgid "Output stream doesn't implement write" +msgstr "আউটপà§à¦Ÿà§° সà§à§°à§‹à¦¤à§‡ লিখা কাৰà§à¦¯ ৰূপায়ন নকৰে" + +#: ../gio/goutputstream.c:511 ../gio/goutputstream.c:1028 +msgid "Source stream is already closed" +msgstr "উৎসৰ সà§à§°à§‹à¦¤ ইতিমধà§à¦¯à§‡ বনà§à¦§" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' বিশà§à¦²à§‡à¦·à¦£ কৰোà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' ত সমà§à¦ªà¦¦ অসà§à¦¤à¦¿à¦¤à§à¦¬à¦¬à¦¾à¦¨ নহয়" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "'%s' ত সমà§à¦ªà¦¦ অসংকোচন হবলে বà§à¦¯à§°à§à¦¥ হল" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "'%s' à§° সমà§à¦ªà¦¦ à¦à¦Ÿà¦¾ ডাইৰেকটৰি নহয়" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "ইনপà§à¦Ÿ সà§à¦Ÿà§à§°à¦¿à¦®à§‡ সনà§à¦§à¦¾à¦¨ পà§à§°à¦£à§Ÿà¦¨ নকৰে" + +#: ../gio/gresource-tool.c:487 +msgid "List sections containing resources in an elf FILE" +msgstr "à¦à¦Ÿà¦¾ elf ফাইলত সমà§à¦ªà¦¦à¦¸à¦®à§‚হ অনà§à¦¤à§°à§à¦­à§à¦•à§à¦¤ কৰা অংশসমূহ তালিকাভà§à¦•à§à¦¤ কৰে" + +#: ../gio/gresource-tool.c:493 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"সমà§à¦ªà¦¦à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক\n" +"যদি SECTION দিয়া থাকে, কেৱল à¦à¦‡ অংশত সমà§à¦ªà¦¦à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক\n" +"যদি PATH দিয়া থাকে, কেৱল মিল খোৱা সমà§à¦ªà¦¦à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক" + +#: ../gio/gresource-tool.c:496 ../gio/gresource-tool.c:506 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:497 ../gio/gresource-tool.c:507 +#: ../gio/gresource-tool.c:514 +msgid "SECTION" +msgstr "SECTION" + +#: ../gio/gresource-tool.c:502 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"বিৱৰণ থকা সমà§à¦ªà¦¦à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক\n" +"যদি SECTION দিয়া থাকে, কেৱল à¦à¦‡ অংশৰ সমà§à¦ªà¦¦à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক\n" +"যদি PATH দিয়া থাকে, কেৱল মিল খোৱা সমà§à¦ªà¦¦à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক\n" +"বিৱৰণসমূহে অংশ, আকাৰ আৰৠসংকোচন অনà§à¦¤à§°à§à¦­à§à¦•à§à¦¤ কৰে" + +#: ../gio/gresource-tool.c:512 +msgid "Extract a resource file to stdout" +msgstr "stdout লে à¦à¦Ÿà¦¾ সমà§à¦ªà¦¦ ফাইল নিষà§à¦•াষণ কৰক" + +#: ../gio/gresource-tool.c:513 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: ../gio/gresource-tool.c:527 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"বà§à¦¯à§±à¦¹à¦¾à§°:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"কমানà§à¦¡à¦¸à¦®à§‚হ:\n" +" help à¦à¦‡ তথà§à¦¯ দেখà§à§±à¦¾à¦“ক\n" +" sections সমà§à¦ªà¦¦ অংশসমূহ তালিকাভà§à¦•à§à¦¤ কৰক\n" +" list সমà§à¦ªà¦¦à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক\n" +" details বিৱৰণৰ সৈতে সমà§à¦ªà¦¦à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক\n" +" extract à¦à¦Ÿà¦¾ সমà§à¦ªà¦¦ নিষà§à¦•াষণ কৰক\n" +"\n" +"বিৱৰিত সহায়ৰ বাবে 'gresource help COMMAND' বà§à¦¯à§±à¦¹à¦¾à§° কৰক।\n" +"\n" + +#: ../gio/gresource-tool.c:541 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"বà§à¦¯à§±à¦¹à¦¾à§°:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:548 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION à¦à¦Ÿà¦¾ (বৈকলà§à¦ªà¦¿à¦•) elf অংশ নাম\n" + +#: ../gio/gresource-tool.c:552 ../gio/gsettings-tool.c:635 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND বিৱৰণ কৰিবলে (বিকলà§à¦ª) কমানà§à¦¡\n" + +#: ../gio/gresource-tool.c:558 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE à¦à¦Ÿà¦¾ elf ফাইল (à¦à¦Ÿà¦¾ বাইনাৰি অথবা à¦à¦Ÿà¦¾ অংশীদাৰী লাইবà§à§°à§‡à§°à§€)\n" + +#: ../gio/gresource-tool.c:561 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE à¦à¦Ÿà¦¾ elf ফাইল (à¦à¦Ÿà¦¾ বাইনাৰি অথবা à¦à¦Ÿà¦¾ অংশীদাৰী লাইবà§à§°à§‡à§°à§€)\n" +" অথবা à¦à¦Ÿà¦¾ কমপাইলà§à¦¡ সমà§à¦ªà¦¦ ফাইল\n" + +#: ../gio/gresource-tool.c:565 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:567 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH à¦à¦Ÿà¦¾ (বৈকলà§à¦ªà¦¿à¦•) সমà§à¦ªà¦¦ পথ (আংশিক হব পাৰে)\n" + +#: ../gio/gresource-tool.c:568 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:570 +msgid " PATH A resource path\n" +msgstr " PATH à¦à¦Ÿà¦¾ সমà§à¦ªà¦¦ পথ\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "à¦à¦¨à§‡ কোনো সà§à¦•িমা '%s' নাই\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "সà§à¦•িমা '%s' পà§à¦¨à§°à¦…ৱসà§à¦¥à¦¿à¦¤ কৰিব নোৱাৰি (পথ ধাৰà§à¦¯à§à¦¯ কৰা হব নালাগিব)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "সà§à¦•িমা '%s' পà§à¦¨à§°à¦…ৱসà§à¦¥à¦¿à¦¤ কৰিব পাৰি (পথ ধাৰà§à¦¯à§à¦¯ কৰিব লাগিব)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "ৰিকà§à¦¤ পথ দিয়া হৈছে।\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "পথ à¦à¦Ÿà¦¾ সà§à¦²à§‡à¦¶ (/) à§° সৈতে আৰমà§à¦­ হব লাগিব\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "পথ à¦à¦Ÿà¦¾ সà§à¦²à§‡à¦¶ (/) à§° সৈতে শেষ হব লাগিব\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "পথত দà§à¦Ÿà¦¾ কাষৰীয়া সà§à¦²à§‡à¦¶ থাকিব নালাগিব (//)\n" + +#: ../gio/gsettings-tool.c:477 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "পà§à§°à¦¦à¦¾à¦¨ কৰা মান বৈধ বিসà§à¦¤à¦¾à§°à§° বাহিৰ\n" + +#: ../gio/gsettings-tool.c:484 +#, c-format +msgid "The key is not writable\n" +msgstr "কি' লিখিব পৰা নহয়\n" + +#: ../gio/gsettings-tool.c:520 +msgid "List the installed (non-relocatable) schemas" +msgstr "ইনসà§à¦Ÿà¦² (অৱসà§à¦¥à¦¿à¦¤ কৰিব নোৱাৰা) সà§à¦•িমাসমূহ তালিকাভà§à¦•à§à¦¤ কৰক" + +#: ../gio/gsettings-tool.c:526 +msgid "List the installed relocatable schemas" +msgstr "ইনসà§à¦Ÿà¦² থকা পà§à¦¨à§° অৱসà§à¦¥à¦¿à¦¤ কৰিব পৰা সà§à¦•িমাসমূহ তালিকাভà§à¦•à§à¦¤ কৰক" + +#: ../gio/gsettings-tool.c:532 +msgid "List the keys in SCHEMA" +msgstr "কিসমূহক SCHEMA ত তালিকাভà§à¦•à§à¦¤ কৰক" + +#: ../gio/gsettings-tool.c:533 ../gio/gsettings-tool.c:539 +#: ../gio/gsettings-tool.c:576 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:538 +msgid "List the children of SCHEMA" +msgstr "SCHEMA সনà§à¦¤à¦¾à¦¨à¦¸à¦®à§‚হ তালিকাভà§à¦•à§à¦¤ কৰক" + +#: ../gio/gsettings-tool.c:544 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"কি আৰৠমানসমূহ তালিকাভà§à¦•à§à¦¤ কৰক, বাৰংবাৰভাৱে\n" +"যদি কোনো SCHEMA দিয়া হোৱা নাই, সকলো কি তালিকাভà§à¦•à§à¦¤ কৰক\n" + +#: ../gio/gsettings-tool.c:546 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:551 +msgid "Get the value of KEY" +msgstr "KEY à§° মান পà§à§°à¦¾à¦ªà§à¦¤ কৰক" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:570 ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:557 +msgid "Query the range of valid values for KEY" +msgstr "KEY à§° বাবে বৈধ মানসমূহৰ বিসà§à¦¤à¦¾à§°à¦• পà§à§°à¦¶à§à¦¨ কৰক" + +#: ../gio/gsettings-tool.c:563 +msgid "Set the value of KEY to VALUE" +msgstr "KEY à§° মান VALUE লে সংহতি কৰক" + +#: ../gio/gsettings-tool.c:564 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:569 +msgid "Reset KEY to its default value" +msgstr "KEY ক ইয়াৰ অবিকলà§à¦ªà¦¿à¦¤ মানলে পà§à¦¨à§°à¦¸à¦‚হতি কৰক" + +#: ../gio/gsettings-tool.c:575 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "SCHEMA ত থকা সকলো কিক সিহতৰ অবিকলà§à¦ªà¦¿à¦¤à¦¸à¦®à§‚হলে পà§à¦¨à§°à¦¸à¦‚হতি কৰক" + +#: ../gio/gsettings-tool.c:581 +msgid "Check if KEY is writable" +msgstr "নিৰীকà§à¦·à¦£ কৰক KEY লিখাযোগà§à¦¯ হয় নে" + +#: ../gio/gsettings-tool.c:587 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"KEY ক পৰিবৰà§à¦¤à¦¨à¦¸à¦®à§‚হৰ বাবে মনিটৰ কৰক।\n" +"যদি কোনো কি ধাৰà§à¦¯à§à¦¯ কৰা নহয়, SCHEMA ত থকা সকলো কি মনিটৰ কৰক।\n" +"মনিটৰিং বনà§à¦§ কৰিবলে ^C বà§à¦¯à§±à¦¹à¦¾à§° কৰক।\n" + +#: ../gio/gsettings-tool.c:590 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:602 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" + +#: ../gio/gsettings-tool.c:625 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"বà§à¦¯à§±à¦¹à¦¾à§°:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:631 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR অতিৰিকà§à¦¤ সà§à¦•িমাসমূহ সনà§à¦§à¦¾à¦¨ কৰিবলে à¦à¦Ÿà¦¾ ডাইৰেকটৰি\n" + +#: ../gio/gsettings-tool.c:639 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA সà§à¦•িমাৰ নাম\n" +" PATH পথ, পà§à¦¨à§° অৱসà§à¦¥à¦¾à¦¨ কৰিব পৰা সà§à¦•িমাসমূহৰ বাবে\n" + +#: ../gio/gsettings-tool.c:644 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY সà§à¦•িমাৰ ভিতৰত (বিকলà§à¦ª) কি\n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The key within the schema\n" +msgstr " KEY সà§à¦•িমাৰ ভিতৰত কি\n" + +#: ../gio/gsettings-tool.c:652 +msgid " VALUE The value to set\n" +msgstr " VALUE সংহতি কৰিবলে মান\n" + +#: ../gio/gsettings-tool.c:707 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s à§° পৰা সà§à¦•িমাসমূহ ল'ড কৰিব পৰা নগল: %s\n" + +#: ../gio/gsettings-tool.c:769 +#, c-format +msgid "Empty schema name given\n" +msgstr "ৰিকà§à¦¤ সà§à¦•িমা নাম দিয়া হৈছে\n" + +#: ../gio/gsettings-tool.c:798 +#, c-format +msgid "No such key '%s'\n" +msgstr "à¦à¦¨à§‡ কোনো কি '%s' নাই\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "অবৈধ চকেট, আৰমà§à¦­ কৰা হোৱা নাই" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "অবৈধ চকেট, ইয়াৰ কাৰণে আৰমà§à¦­ কৰিব নোৱাৰি: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "চকেট ইতিমধà§à¦¯à§‡ বনà§à¦§" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "চকেট I/O সময়অনà§à¦¤ হল" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd à§° পৰা GSocket সৃষà§à¦Ÿà¦¿ কৰা হৈছে: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "চকেট সৃষà§à¦Ÿà¦¿ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "অজà§à¦žà¦¾à¦¤ পৰিয়াল ধাৰà§à¦¯à§à¦¯ কৰা হৈছিল" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "অজà§à¦žà¦¾à¦¤ পà§à§°à¦Ÿà§‹à¦•ল ধাৰà§à¦¯à§à¦¯ কৰা হৈছিল" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ঠিকনা পোৱা নাযায়: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "দূৰৰ ঠিকনা পোৱা নাযায়: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "শà§à¦¨à¦¿à¦¬ পৰা নগল: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "ঠিকনালৈ বানà§à¦§à¦¿à¦¬à¦²à§ˆ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "মালà§à¦Ÿà¦¿à¦•াসà§à¦Ÿ দলত অংশগà§à§°à¦¹à¦£ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "মালà§à¦Ÿà¦¿à¦•াসà§à¦Ÿ দল à¦à§°à§‹à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "উৎস-বিশেষ মালà§à¦Ÿà¦¿à¦•াসà§à¦Ÿà§° বাবে কোনো সমৰà§à¦¥à¦¨ নাই" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "সংযোগ গà§à§°à¦¹à¦£ কৰোà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "সংযোগ চলি আছে" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "পেনà§à¦¡à¦¿à¦‚ তà§à§°à§à¦Ÿà¦¿ পাবলৈ বà§à¦¯à§°à§à¦¥:" + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "তথà§à¦¯ পাওà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "তথà§à¦¯ পঠিয়াবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "চকেট বনà§à¦§ কৰিবলে অকà§à¦·à¦®: %s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "চকেট বনà§à¦§ কৰোà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "চকেট অৱসà§à¦¥à¦¾à§° কাৰণে পà§à§°à¦¤à§€à¦•à§à¦·à¦¾ কৰা হৈছে: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "সমà§à¦¬à¦¾à¦¦ পঠিয়াওà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage ক Windows ত সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "সমà§à¦¬à¦¾à¦¦ পাওà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:4516 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "চকেট তথà§à¦¯à¦¸à¦®à§‚হ পà§à¦¿à¦¬à¦²à§ˆ অকà§à¦·à¦®: %s" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "à¦à¦‡ OS à§° বাবে g_socket_get_credentials পà§à§°à¦£à§Ÿà¦¨ কৰা হোৱা নাই" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "পà§à§°à¦•à§à¦¸à¦¿ চাৰà§à¦­à¦¾à§° %s লে সংযোগ কৰিব নোৱাৰি: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s লে সংযোগ কৰিব নোৱাৰি: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "সংযোগ কৰিব পৰা নগল: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1597 +msgid "Unknown error on connect" +msgstr "সংযোগত অজà§à¦žà¦¾à¦¤ তà§à§°à§à¦Ÿà¦¿" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1532 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "নন-TCP সংযোগৰ ওপৰত পà§à§°à¦•à§à¦¸à¦¿ কৰাটো সমৰà§à¦¥à¦¨ কৰা নহয়।" + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1553 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "পà§à§°à¦•à§à¦¸à¦¿ পà§à§°à¦Ÿà§‹à¦•ল '%s' সমৰà§à¦¥à¦¿à¦¤ নহয়।" + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "সà§à§°à§‹à¦¤ ইতিমধà§à¦¯à§‡ বনà§à¦§" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "যোগ কৰা চকেট বনà§à¦§" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 ঠIPv6 ঠিকনা '%s' ক সমৰà§à¦¥à¦¨ নকৰে" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "বà§à¦¯à§±à¦¹à¦¾à§°à¦•াৰীনাম SOCKSv4 পà§à§°à¦Ÿà§‹à¦•লৰ বাবে অতি দীঘল" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "হসà§à¦Ÿà¦¨à¦¾à¦® '%s' SOCKSv4 পà§à§°à¦Ÿà§‹à¦•লৰ বাবে অতি দীঘল" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "চাৰà§à¦­à¦¾à§° à¦à¦Ÿà¦¾ SOCKSv4 পà§à§°à¦•à§à¦¸à¦¿ চাৰà§à¦­à¦¾à§° নহয়।" + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 পà§à§°à¦•à§à¦¸à¦¿ চাৰà§à¦­à¦¾à§°à§° সৈতে সংযোগ নাকচ কৰা হৈছিল" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "চাৰà§à¦­à¦¾à§° à¦à¦Ÿà¦¾ SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿ চাৰà§à¦­à¦¾à§° নহয়।" + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿ চাৰà§à¦­à¦¾à§°à§° পà§à§°à¦®à¦¾à¦£à§€à¦•ৰণৰ পà§à§°à§Ÿà§‹à¦œà¦¨à¥¤" + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿à§° à¦à¦Ÿà¦¾ পà§à§°à¦®à¦¾à¦£à§€à¦•ৰণ পদà§à¦§à¦¤à¦¿à§° পà§à§°à§Ÿà§‹à¦œà¦¨ যি GLib দà§à¦¬à¦¾à§°à¦¾ সমৰà§à¦¥à¦¿à¦¤ নহয়।" + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "বà§à¦¯à§±à¦¹à¦¾à§°à¦•াৰীনাম অথবা পাছৱৰà§à¦¡ SOCKSv5 পà§à§°à¦Ÿà§‹à¦•লৰ বাবে অতি দীঘল।" + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5 পà§à§°à¦®à¦¾à¦£à§€à¦•ৰণ তà§à§°à§à¦Ÿà¦¿ বà§à¦¯à§±à¦¹à¦¾à§°à¦•াৰীনাম অথবা পাছৱৰà§à¦¡à§° কাৰণে বà§à¦¯à§°à§à¦¥ হল।" + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "হসà§à¦Ÿà¦¨à¦¾à¦® '%s' SOCKSv5 পà§à§°à¦Ÿà§‹à¦•লৰ বাবে অতি দীঘল" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿ চাৰà§à¦­à¦¾à§°à§‡ অজà§à¦žà¦¾à¦¤ ঠিকনা ধৰণ বà§à¦¯à§±à¦¹à¦¾à§° কৰে।" + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "অভà§à¦¯à¦¨à§à¦¤à§°à§€à¦• SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿ চাৰà§à¦­à¦¾à§° তà§à§°à§à¦Ÿà¦¿à¥¤" + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 সংযোগ নিয়মসংহতি দà§à¦¬à¦¾à§°à¦¾ অনà§à¦®à§‹à¦¦à¦¿à¦¤ নহয়। " + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "হসà§à¦Ÿ SOCKSv5 চাৰà§à¦­à¦¾à§° দà§à¦¬à¦¾à§°à¦¾ পà§à§°à¦¾à¦ªà§à¦¤ নহয়।" + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "নেটৱৰà§à¦• SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿ দà§à¦¬à¦¾à§°à¦¾ পà§à§°à¦¾à¦ªà§à¦¤ নহয়।" + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "সংযোগ SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿ দà§à¦¬à¦¾à§°à¦¾ নাকচ কৰা হৈছে।" + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿à§Ÿà§‡ 'connect' কমানà§à¦¡à§° সমৰà§à¦¥à¦¨ নকৰে।" + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿à§Ÿà§‡ পà§à§°à¦¦à¦¾à¦¨ কৰা ঠিকনা ধৰণ সমৰà§à¦¥à¦¨ নকৰে।" + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "অজà§à¦žà¦¾à¦¤ SOCKSv5 পà§à§°à¦•à§à¦¸à¦¿ তà§à§°à§à¦Ÿà¦¿à¥¤" + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon encoding à§° %d সংসà§à¦•ৰণ পৰিচালন কৰিব নোৱাৰি" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "কোনো বৈধ ঠিকনা পোৱা নগল" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' ক ওলোটা ভাবে বà§à¦œà¦¿à¦¬à¦²à§ˆ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "'%s' à§° বাবে অনà§à§°à§‹à¦§ কৰা ধৰণৰ কোনো DNS ৰেকৰà§à¦¡ নাই" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "'%s' ক অসà§à¦¥à¦¾à§Ÿà§€à¦­à¦¾à¦¬à§‡ বà§à¦œà¦¿à¦¬ পৰা নাযায়" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "'%s' বà§à¦œà¦¿à¦¬ লওà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿" + +#: ../gio/gtlscertificate.c:247 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM à¦à¦¨à¦•'ড থকা বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত কিক ডিকà§à§°à¦¿à¦ªà§à¦Ÿ কৰিব নোৱাৰি" + +#: ../gio/gtlscertificate.c:252 +msgid "No PEM-encoded private key found" +msgstr "কোনো PEM à¦à¦¨à¦•োডেড বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত কি পোৱা নগল" + +#: ../gio/gtlscertificate.c:262 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM à¦à¦¨à¦•োডেড বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত কি বিশà§à¦²à§‡à¦·à¦£ কৰিব নোৱাৰি" + +#: ../gio/gtlscertificate.c:287 +msgid "No PEM-encoded certificate found" +msgstr "কোনো PEM à¦à¦¨à¦•োডেড পà§à§°à¦®à¦¾à¦£à¦ªà¦¤à§à§° পোৱা নগল" + +#: ../gio/gtlscertificate.c:296 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM à¦à¦¨à¦•োডেড পà§à§°à¦®à¦¾à¦£à¦ªà¦¤à§à§° বিশà§à¦²à§‡à¦·à¦£ কৰিব পৰা নগল" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"আপোনাৰ অভিগম লকআউট হৈ যোৱাৰ আগত পাছৱৰà§à¦¡ সঠিকভাৱে সà§à¦®à§à§±à¦¾à§° à¦à§Ÿà¦¾ শেষ সà§à¦¯à§‹à¦—।" + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"বহৠসà§à¦®à§à§±à¦¾ পাছৱৰà§à¦¡ তà§à§°à§à¦Ÿà¦¿ হৈছে, আৰৠআপোনাৰ অভিগম ততোধিক বà§à¦¯à§°à§à¦¥à¦¤à¦¾à§° পিছত লক " +"আউট কৰি " +"দিয়া হব।" + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "সà§à¦®à§à§±à¦¾ পাছৱৰà§à¦¡ শà§à¦¦à§à¦§ নহয়।" + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 নিয়নà§à¦¤à§à§°à¦£à§° সমà§à¦¬à¦¾à¦¦ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, %d পà§à§°à¦¾à¦ªà§à¦¤ হল" +msgstr[1] "1 নিয়নà§à¦¤à§à§°à¦£à§° সমà§à¦¬à¦¾à¦¦ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, %d পà§à§°à¦¾à¦ªà§à¦¤ হল" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "à¦à¦žà§à¦šà¦¿à¦²à¦¾à§°à¦¿ তথà§à¦¯à§° অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ ধৰণ" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "à¦à¦Ÿà¦¾ fd পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, কিনà§à¦¤à§ পà§à§°à¦¾à¦ªà§à¦¤ হল %d\n" +msgstr[1] "à¦à¦Ÿà¦¾ fd পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, কিনà§à¦¤à§ পà§à§°à¦¾à¦ªà§à¦¤ হল %d\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "অবৈধ fd পোৱা গ'ল" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "তথà§à¦¯ পঠিয়াওতে তà§à§°à§à¦Ÿà¦¿: " + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "SO_PASSCRED চকেটৰ বাবে সামৰà§à¦¥à¦¬à¦¾à¦¨ আছে নে নিৰীকà§à¦·à¦£ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED সামৰà§à¦¥à¦¬à¦¾à¦¨ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"তথà§à¦¯à¦¸à¦®à§‚হ গà§à§°à¦¹à¦¨ কৰাৰ বাবে à¦à¦Ÿà¦¾ বাইট পà§à¦¿à¦¬à¦²à§‡ আশা কৰা হৈ আছিল কিনà§à¦¤à§ শূণà§à¦¯ বাইট " +"পà§à¦¾ হল" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "নিয়নà§à¦¤à§à§°à¦£ বাৰà§à¦¤à¦¾ আশা কৰা হোৱা নাছিল, কিনà§à¦¤à§ %d পোৱা গল" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED অসামৰà§à¦¥à¦¬à¦¾à¦¨ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ফাইল বিৱৰকৰ পৰা পà§à§‹à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ফাইল বিৱৰক বনà§à¦§ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixmounts.c:1991 ../gio/gunixmounts.c:2044 +msgid "Filesystem root" +msgstr "ফাইলচিসà§à¦Ÿà§‡à¦® root" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ফাইল বিৱৰকলে লিখোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "à¦à¦‡ চিসà§à¦Ÿà§‡à¦®à¦¤ à¦à¦¬à¦¸à§à¦Ÿà§à§°à§‡à¦•à§à¦Ÿ UNIX ডমেইন চকেট ঠিকনাসমূহ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "ভলিউম দà§à¦¬à¦¾à§°à¦¾ ইজেকà§à¦Ÿ পà§à§°à§Ÿà§‹à¦— কৰা নহয়" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "ভলিউম দà§à¦¬à¦¾à§°à¦¾ ইজেকà§à¦Ÿ বা eject_with_operation পà§à§°à§Ÿà§‹à¦— কৰা নহয়" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচন পোৱা নাযায়" + +#: ../gio/gwin32appinfo.c:306 +#, c-format +msgid "Error launching application: %s" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচন আৰমà§à¦­ কৰিবলৈ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gwin32appinfo.c:342 +msgid "URIs not supported" +msgstr "URI সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gwin32appinfo.c:364 +msgid "association changes not supported on win32" +msgstr "win32 ত à¦à¦ªà§à¦²à¦¿à¦•েচনৰ সমà§à¦¬à¦¨à§à¦§à§° সলনি সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gwin32appinfo.c:376 +msgid "Association creation not supported on win32" +msgstr "win32 ত à¦à¦ªà§à¦²à¦¿à¦•েচনৰ সমà§à¦¬à¦¨à§à¦§à§° সৃষà§à¦Ÿà¦¿ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "হাতলৰ পৰা পà§à§‹à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "হাতল বনà§à¦§ কৰোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "হাতললে লিখোতে তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "পৰà§à¦¯à¦¾à¦ªà§à¦¤ মেমৰি নাই" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "অভà§à¦¯à¦¨à§à¦¤à§°à§€à¦• তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "অধিক ইনপà§à¦Ÿà§° পà§à§°à§Ÿà§‹à¦œà¦¨" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "অবৈধ সংকোচিত তথà§à¦¯" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "শà§à¦¨à¦¿à¦¬à¦²à§‡ ঠিকনা" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "উপেকà§à¦·à¦¾ কৰা হৈছে, GTestDbus à§° সৈতে compat à§° বাবে" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "ঠিকনা পà§à§°à¦¿à¦¨à§à¦Ÿ কৰক" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "শà§à¦¬à§‡à¦² অৱসà§à¦¥à¦¾à¦¤ ঠিকনা পà§à§°à¦¿à¦¨à§à¦Ÿ কৰক" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "à¦à¦Ÿà¦¾ dbus সেৱা চলাওক" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "ভà§à¦² args\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ বৈশিষà§à¦Ÿ '%s' পদাৰà§à¦¥ '%s' à§° বাবে" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' বৈশিষà§à¦Ÿ '%s' পদাৰà§à¦¥à§° পোৱা নগল" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ চিহà§à¦¨ '%s', '%s' চিহà§à¦¨ আশা কৰা হৈছিল" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ চিহà§à¦¨ '%s', '%s' à§° ভিতৰত" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "তথà§à¦¯ ডাইৰেকটৰিত কোনো বৈধ পতà§à§°à¦šà¦¿à¦¹à§à¦¨à§° ফাইল পোৱা নগল" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s' à§° বাবে পতà§à§°à¦šà¦¿à¦¹à§à¦¨ ইতিমধà§à¦¯à§‡ আছে" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s' à§° বাবে পতà§à§°à¦šà¦¿à¦¹à§à¦¨ পোৱা নগল" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s' à§° পতà§à§°à¦šà¦¿à¦¹à§à¦¨à§° বাবে কোনো MIME à§° ধৰণ সংজà§à¦žà¦¾ দিয়া হোৱা নাই" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s' à§° পতà§à§°à¦šà¦¿à¦¹à§à¦¨à¦¤ কোনো বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত চিহà§à¦¨à§° সংজà§à¦žà¦¾ দিয়া হোৱা নাই" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s' à§° পতà§à§°à¦šà¦¿à¦¹à§à¦¨à§° বাবে কোনো দল পà§à§°à¦¤à¦¿à¦·à§à¦ à¦¾ কৰা হোৱা নাই" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "'%s' নামৰ কোনো à¦à¦ªà§à¦²à¦¿à¦•েচনে '%s' à§° বাবে কোনো পতà§à§°à¦šà¦¿à¦¹à§à¦¨ ৰেজিসà§à¦Ÿà¦¾à§° কৰা নাই" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "exec শাৰী '%s', য'ত URI '%s' আছে, বিসà§à¦¤à§ƒà¦¤ কৰাত বà§à¦¯à§°à§à¦¥" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "ইনপà§à¦Ÿà§° অনà§à¦¤à¦¤ অসমà§à¦ªà§‚à§°à§à¦£ আখৰৰ কà§à§°à¦®" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "fallback '%s' ক codeset '%s' লৈ সলনি কৰিব নোৱাৰি" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "\"file\" আà¦à¦šà¦¨à¦¿ বà§à¦¯à§±à¦¹à¦¾à§° কৰা URI '%s' à¦à¦Ÿà¦¾ সমà§à¦ªà§‚à§°à§à¦£ URI নহয়" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "সà§à¦¥à¦¾à¦¨à¦¿à¦• ফাইলৰ URI '%s' ত à¦à¦Ÿà¦¾ '#' থাকিব নোৱাৰে" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' অৱৈধ" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI '%s' à§° হসà§à¦Ÿà¦¨à¦¾à¦® অৱৈধ" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' ত অৱৈধভাবে মà§à¦•à§à¦¤à¦¿ পোৱা আখৰ আছে" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s' পথৰ নাম à¦à¦Ÿà¦¾ সমà§à¦ªà§‚à§°à§à¦£ পথৰ নাম নহয়" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "অৱৈধ হসà§à¦Ÿà¦¨à¦¾à¦®" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "পূৰà§à¦¬à§à¦¬à¦¾à¦¹à§à¦¨" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "অপৰাহà§à¦¨" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %b %e %H:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I.%M.%S %p" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "জানà§à§±à¦¾à§°à§€" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "ফেবà§à§°à§à§±à¦¾à§°à§€" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "মাৰà§à¦š" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "à¦à¦ªà§à§°à¦¿à¦²" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "মে" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "জà§à¦¨" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "জà§à¦²à¦¾à¦‡" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "আগষà§à¦Ÿ" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "চেপà§à¦¤à§‡à¦®à§à¦¬à§°" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "অকà§à¦Ÿà§‹à¦¬à§°" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "নভেমà§à¦¬à§°" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "ডিচেমà§à¦¬à§°" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "জান" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ফেবà§à§°à§" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "মাৰà§à¦š" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à¦à¦ªà§à§°à¦¿" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "মে" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "জà§à¦¨" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "জà§à¦²" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "আগ" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "চেপ" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "অকà§à¦Ÿ" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "নভ" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ডিচ" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "সোমবাৰ" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "মঙà§à¦—লবাৰ" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "বà§à¦§à¦¬à¦¾à§°" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "বৃহষà§à¦ªà¦¤à¦¿à¦¬à¦¾à§°" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "শà§à¦•à§à§°à¦¬à¦¾à§°" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "শনিবাৰ" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "দেওবাৰ" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "সোম" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "মঙà§à¦—ল" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "বà§à¦§" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "বৃহষà§à¦ªà¦¤à¦¿" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "শà§à¦•à§à§°" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "শনি" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "দেও" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "'%s' ডাইৰেকটৰি খোলোà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "ফাইল পà§à¦¿à¦¬à¦²à§‡ %lu বাইট আবনà§à¦Ÿà¦¨ কৰিব পৰা নগল \"%s\"" +msgstr[1] "ফাইল পà§à¦¿à¦¬à¦²à§‡ %lu বাইট আবনà§à¦Ÿà¦¨ কৰিব পৰা নগল \"%s\"" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "ফাইল '%s' পà§à§‹à¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "\"%s\" ফাইল বৰ ডাঙৰ" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' ফাইলৰ পৰা পà§à§‹à¦à¦¤à§‡ বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' ফাইল খোলোà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' ফাইলৰ বৈশিষà§à¦Ÿ পাওà¦à¦¤à§‡ বà§à¦¯à§°à§à¦¥: fstat() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' ফাইল খোলোà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿: fdopen() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "'%s' ফাইলক '%s' লৈ পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•ৰণ কৰোà¦à¦¤à§‡ বà§à¦¯à§°à§à¦¥: g_rename() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' ফাইল সৃষà§à¦Ÿà¦¿ কৰোà¦à¦¤à§‡ বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "ফাইল '%s' লিখিবলে বà§à¦¯à§°à§à¦¥: write() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' ফাইল লিখাত বà§à¦¯à§°à§à¦¥: fsync() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "বৰà§à¦¤à§à¦¤à¦®à¦¾à¦¨à§‡ থকা ফাইল '%s' আà¦à¦¤à§°à¦¾à¦¬ পৰা নগল: g_unlink() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "'%s' টেমপà§à¦²à§‡à¦Ÿ অৱৈধ, à¦à¦Ÿà¦¾ '%s' থাকিব নালাগে" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "'%s' টেমপà§à¦²à§‡à¦Ÿà¦¤ XXXXXX নাই" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "চিমসংযোগ পà§à¦¾à¦¤ বà§à¦¯à§°à§à¦¥ '%s': %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "চিমসংযোগ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' à§° পৰা '%s' লৈ সলনি কৰা পৰিৱৰà§à¦¤à¦• খোলিব পৰা নগল: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string ত raw read কৰিব নোৱাৰি" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "read বাফাৰত অৱশিষà§à¦Ÿ অপৰিবৰà§à¦¤à¦¿à¦¤ তথà§à¦¯ আছে" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "চেনেল অসমà§à¦ªà§‚à§°à§à¦£ আখৰত অনà§à¦¤ হয়" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end ত à¦à¦Ÿà¦¾ raw read কৰিব নোৱাৰি" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§° dirs ত বৈধ কি ফাইল পোৱা নাযায়" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "সাধাৰণ ফাইল নহয়" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "কি ফাইলত '%s' পংকà§à¦¤à¦¿ আছে যি কি-মানৰ জোৰা, দল বা মনà§à¦¤à¦¬à§à¦¯ নহয়" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "দলৰ নাম অৱৈধ: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "কি-ফাইলৰ আৰমà§à¦­à¦¤ কোনো দল উলà§à¦²à¦¿à¦–িত নাই" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "অৱৈধ কিৰ নাম: %s:" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "কি ফাইলত অসমৰà§à¦¥à¦¿à¦¤ à¦à¦¨à¦•'ডিং '%s'" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1692 ../glib/gkeyfile.c:3072 +#: ../glib/gkeyfile.c:3138 ../glib/gkeyfile.c:3264 ../glib/gkeyfile.c:3397 +#: ../glib/gkeyfile.c:3539 ../glib/gkeyfile.c:3768 ../glib/gkeyfile.c:3835 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "কি ফাইলত কোনো দল অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ '%s'" + +#: ../glib/gkeyfile.c:1704 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "কি ফাইলত কোনো কি উপসà§à¦¥à¦¿à¦¤ নাই '%s'" + +#: ../glib/gkeyfile.c:1811 ../glib/gkeyfile.c:1927 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "কি ফাইলত '%s' কি আছে '%s' মান সহ যি UTF-8 বিনà§à¦¯à¦¾à¦¸à¦¤ নাই।" + +#: ../glib/gkeyfile.c:1831 ../glib/gkeyfile.c:1947 ../glib/gkeyfile.c:2316 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "কি ফাইলত '%s' কি উপসà§à¦¥à¦¿à¦¤ আছে যাৰ মান বà§à¦œà¦¿à¦¬ পৰা নাযায়।" + +#: ../glib/gkeyfile.c:2533 ../glib/gkeyfile.c:2901 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"কি ফাইলয় দল '%s' ত কি '%s' অনà§à¦¤à§°à§à¦­à§à¦•à§à¦¤ কৰে যাৰ à¦à¦Ÿà¦¾ অনà§à¦¬à¦¾à¦¦ কৰিব নোৱাৰা মান আছে।" + +#: ../glib/gkeyfile.c:2611 ../glib/gkeyfile.c:2688 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "দল '%s' ত কি '%s' à§° মান '%s' আছে যত %s পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ আছিল" + +#: ../glib/gkeyfile.c:3087 ../glib/gkeyfile.c:3279 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "কি ফাইলত '%s' কি '%s' দলত নাই" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "কি ফাইলত পংকà§à¦¤à¦¿à§° অৱশেষত à¦à¦¸à§à¦•েইপ আখৰ উপসà§à¦¥à¦¿à¦¤ আছে" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "কি ফাইলত অৱৈধ à¦à¦¸à§à¦•েইপ ধাৰা উপসà§à¦¥à¦¿à¦¤ আছে '%s'" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "'%s' মান কোনো সংখà§à¦¯à¦¾à§°à§‚পে বà§à¦œà¦¿à¦¬ পৰা নাযায়।" + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "'%s' পূৰà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ মান সীমা বহিৰà§à¦­à§‚ত" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "'%s' মান float সংখà§à¦¯à¦¾ ৰূপে বà§à¦œà¦¿à¦¬ পৰা নাযায়।" + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "'%s' মান বà§à¦²à¦¿à§Ÿà§‡à¦¨ ৰূপে বà§à¦œà¦¿à¦¬ পৰা নাযায়।" + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "" +"ফাইল '%s%s%s%s' à§° বৈশিষà§à¦Ÿà¦¸à¦®à§‚হ পà§à§°à¦¾à¦ªà§à¦¤ কৰিবলে বà§à¦¯à§°à§à¦¥: fstat() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s মেপ কৰিবলে বà§à¦¯à§°à§à¦¥: mmap() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "'%s' ফাইল খোলোà¦à¦¤à§‡ বà§à¦¯à§°à§à¦¥: open() বà§à¦¯à§°à§à¦¥: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "%d শাৰীৰ %d আখৰত তà§à§°à§à¦Ÿà¦¿:" + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "নামত অৱৈধ UTF-8 সাঙà§à¦•েতিক লিপি - অৱৈধ '%s'" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' à¦à¦Ÿà¦¾ বৈধ নাম নহয়" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' à¦à¦Ÿà¦¾ বৈধ নাম নহয়: '%c'" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d শাৰীত তà§à§°à§à¦Ÿà¦¿: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' বিশà§à¦²à§‡à¦·à¦£ কৰোà¦à¦¤à§‡ তà§à§°à§à¦Ÿà¦¿, যি কোনো আখৰৰ উলà§à¦²à§‡à¦–à§° ভিতৰৰ à¦à¦Ÿà¦¾ সংখà§à¦¯à¦¾ হ'ব " +"লাগিছিল " +"(&#২৩৪; যেনে) - হয়তো সংখà§à¦¯à¦¾à¦Ÿà§‹ বৰ ডাঙৰ" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"আখৰৰ উলà§à¦²à§‡à¦– à¦à¦Ÿà¦¾ ছেমিকলনেৰে অনà§à¦¤ নহল; খà§à¦¬ সমà§à¦­à§± পদাৰà§à¦¥ à¦à¦Ÿà¦¾ আৰমà§à¦­ কৰিব " +"নিবিচাৰিও " +"আপà§à¦¨à¦¿ à¦à¦Ÿà¦¾ à¦à¦®à§à¦ªà¦¾à§°à¦›à§‡à¦¨à§à¦¦ আখৰ বà§à¦¯à§±à¦¹à¦¾à§° কৰিছে - à¦à¦®à§à¦ªà¦¾à§°à¦›à§‡à¦¨à§à¦¦à¦• & হিচাপে à¦à¦¸à§à¦•েইপ " +"কৰক" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" +"আখৰৰ উলà§à¦²à§‡à¦– থকা '%-.*s' ঠà¦à¦Ÿà¦¾ আজà§à¦žà¦¾ থকা আখৰক সাঙà§à¦•েতিক লিপিলৈ পৰিবৰà§à¦¤à¦¿à¦¤ নকৰে" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"ৰিকà§à¦¤ পদাৰà§à¦¥ '&;' দেখা গ'ল; বৈধ পদাৰà§à¦¥à¦¸à¦®à§‚হ হ'ল: & " < > '" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "পদাৰà§à¦¥à§° নাম '%-.*s' অজà§à¦žà¦¾à¦¤" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"পদাৰà§à¦¥ à¦à¦Ÿà¦¾ ছেমিকলনেৰে অনà§à¦¤ নহল; খà§à¦¬ সমà§à¦­à§± পদাৰà§à¦¥ à¦à¦Ÿà¦¾ আৰমà§à¦­ কৰিব নিবিচাৰিও " +"আপà§à¦¨à¦¿ à¦à¦Ÿà¦¾ " +"à¦à¦®à§à¦ªà¦¾à§°à¦›à§‡à¦¨à§à¦¦ আখৰ বà§à¦¯à§±à¦¹à¦¾à§° কৰিছে - à¦à¦®à§à¦ªà¦¾à§°à¦›à§‡à¦¨à§à¦¦à¦• & হিচাপে à¦à¦¸à§à¦•েইপ কৰক" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "দসà§à¦¤à¦¾à¦¬à§‡à¦œ à¦à¦Ÿà¦¾ উপাদানৰ সৈতে আৰমà§à¦­ হ'ব লাগিব (যেনে )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' à¦à¦Ÿà¦¾ বৈধ আখৰ নহয় '<' আখৰৰ পিছত; ইয়াৰ দà§à¦¬à¦¾à§°à¦¾ পদাৰà§à¦¥à§° নাম আৰমà§à¦­ নহবও পাৰে" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"তà§à§°à§à¦Ÿà¦¿ আখৰ '%s', à¦à¦Ÿà¦¾ '>' আখৰ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ ৰিকà§à¦¤ পদাৰà§à¦¥à§° টেগ '%s' শেষ কৰিবলৈ" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"'%s' আখৰ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ নহয়, à¦à¦Ÿà¦¾ '=' চিহà§à¦¨ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ বৈশিষà§à¦Ÿà§° নাম '%s', পদাৰà§à¦¥ '%" +"s' à§°, " +"পিছত" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"'%s' আখৰ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ নহয়, '%s' পদাৰà§à¦¥à§° পà§à§°à¦¾à§°à¦®à§à¦­à¦¿à¦• টেগ সমাপà§à¦¤ কৰাৰ উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ '>" +"' বা " +"'/' চিহà§à¦¨ বা কোনো বৈশিষà§à¦Ÿà§à¦¯à§° উপসà§à¦¥à¦¿à¦¤à¦¿ কামà§à¦¯; সমà§à¦­à§±à¦¤à¦ƒ কোনো বৈশিষà§à¦Ÿà§à¦¯à§° নামত " +"অৱৈধ আখৰ " +"বà§à¦¯à§±à¦¹à§ƒà¦¤ হৈছে" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"'%s' আখৰ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, '%s' বৈশিষà§à¦Ÿà§°, পদাৰà§à¦¥ '%s' à§°, মান নিৰà§à¦§à¦¾à§°à¦£à§° উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ " +"সমান " +"চিহà§à¦¨à§° পিছত à¦à¦Ÿà¦¾ উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨à§° পà§à§°à¦¾à§°à¦®à§à¦­à¦¿à¦• অংশ উপসà§à¦¥à¦¿à¦¤à¦¿ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' আখৰৰ বà§à¦¯à§±à¦¹à¦¾à§° বৈধ নহয় '%s' বদà§à¦§ পদাৰà§à¦¥à§° নামৰ পিছত; অনà§à¦®à§‹à¦¦à¦¿à¦¤ আখৰ হ'ল '>'" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "'%s' পদাৰà§à¦¥ বদà§à¦§ অৱসà§à¦¥à¦¾à¦¤, বৰà§à¦¤à¦®à¦¾à¦¨à§‡ কোনো পদাৰà§à¦¥ খোলা অৱসà§à¦¥à¦¾à¦¤ নাই" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "'%s' পদাৰà§à¦¥ বদà§à¦§ অৱসà§à¦¥à¦¾à¦¤, বৰà§à¦¤à¦®à¦¾à¦¨à§‡ '%s' পদাৰà§à¦¥ খোলা অৱসà§à¦¥à¦¾à¦¤ আছে" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "দসà§à¦¤à¦¾à¦¬à§‡à¦œ ৰিকà§à¦¤ বা অকল ৰিকà§à¦¤ সà§à¦¥à¦¾à¦¨ আছিলে" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"খোলা বà§à§°à§‡à¦•েটৰ পà§à§°à¦¾à§°à¦®à§à¦­à¦¿à¦• চিহà§à¦¨à§° '<' ঠিক পিছত দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ " +"হৈছে" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"খোলা পদাৰà§à¦¥à¦¸à¦¹ দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ হৈছে - '%s' পদাৰà§à¦¥ সৰà§à¦¬à¦¶à§‡à¦· খোলা " +"হৈছিল" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ হৈছে, <%s/> টেগ সমাপà§à¦¤à¦¿à§° বাবে খোলা বà§à§°à§‡à¦•েট " +"চিহà§à¦¨à§° " +"অনà§à¦¤à¦¿à¦® অংশৰ উপসà§à¦¥à¦¿à¦¤à¦¿ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "পদাৰà§à¦¥à§° নামত দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ হৈছে" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "বৈশিষà§à¦Ÿà§à¦¯à§° নামত দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ হৈছে" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "পদাৰà§à¦¥à§° পà§à§°à¦¾à§°à¦®à§à¦­à¦¿à¦• টেগত দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ হৈছে" + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"বৈশিষà§à¦Ÿà§à¦¯à§° নামৰ পিছত উপসà§à¦¥à¦¿à¦¤ সমান চিহà§à¦¨à§° পিছত দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ " +"হৈছে; " +"বৈশিষà§à¦Ÿà§à¦¯à§° মান অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "বৈশিষà§à¦Ÿà§à¦¯à§° মানত দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ হৈছে" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "'%s' পদাৰà§à¦¥à§° অনà§à¦¤à¦¿à¦® টেগত দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ হৈছে" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"কোনো মনà§à¦¤à¦¬à§à¦¯ বা পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à¦•ৰণৰ নিৰà§à¦¦à§‡à¦¶à¦¤ দসà§à¦¤à¦¾à¦¬à§‡à¦œ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à§°à§‚পে সমাপà§à¦¤ হৈছে" + +#: ../glib/goption.c:795 +msgid "Usage:" +msgstr "বà§à¦¯à§±à¦¹à¦¾à§°:" + +#: ../glib/goption.c:795 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:911 +msgid "Help Options:" +msgstr "সহায় বিকলà§à¦ªà¦¸à¦®à§‚হ:" + +#: ../glib/goption.c:912 +msgid "Show help options" +msgstr "সহায় বিকলà§à¦ªà¦¸à¦®à§‚হ দেখà§à§±à¦¾à¦“ক" + +#: ../glib/goption.c:918 +msgid "Show all help options" +msgstr "সহায় সমসà§à¦¤ বিকলà§à¦ª দেখà§à§±à¦¾à¦“ক" + +#: ../glib/goption.c:980 +msgid "Application Options:" +msgstr "à¦à¦ªà§à¦²à¦¿à¦•েচন বিকলà§à¦ªà¦¸à¦®à§‚হ:" + +#: ../glib/goption.c:1044 ../glib/goption.c:1114 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "'%s' পূৰà§à¦£à¦¸à¦‚খà§à¦¯à¦¾à§° মান %s à§° বাবে বিশà§à¦²à§‡à¦·à¦£ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../glib/goption.c:1054 ../glib/goption.c:1122 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "'%s' পূৰà§à¦£à¦¸à¦‚খà§à¦¯à¦¾à§° মান %s à§° বাবে সীমাৰ বহিৰà§à¦­à§‚ত" + +#: ../glib/goption.c:1079 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "'%s' à§° দà§à¦¬à§€à¦¬à§ˆà¦¶à¦¿à¦·à§à¦Ÿ মান %s à§° বাবে বিশà§à¦²à§‡à¦·à¦£ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../glib/goption.c:1087 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "'%s' à§° দà§à¦¬à§€à¦¬à§ˆà¦¶à¦¿à¦·à§à¦Ÿ মান %s à§° বাবে সীমা বহিৰà§à¦­à§‚ত" + +#: ../glib/goption.c:1373 ../glib/goption.c:1452 +#, c-format +msgid "Error parsing option %s" +msgstr "%s বিকলà§à¦ª বিশà§à¦²à§‡à¦·à¦£ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../glib/goption.c:1483 ../glib/goption.c:1596 +#, c-format +msgid "Missing argument for %s" +msgstr "%s à§° তৰà§à¦• সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨" + +#: ../glib/goption.c:2057 +#, c-format +msgid "Unknown option %s" +msgstr "অজà§à¦žà¦¾à¦¤ বিকলà§à¦ª %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¤ অৱজেকà§à¦Ÿ" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "অভà§à¦¯à¦¨à§à¦¤à§°à§€à¦£ তà§à§°à§à¦Ÿà¦¿ বা কà§à¦·à¦¤à¦¿à¦—à§à§°à¦¸à§à¦¤ অৱজেকà§à¦Ÿ" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "মেমৰি অৱশিষà§à¦Ÿ নাই" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "backtracking à§° সà§à¦¨à¦¿à§°à§à¦¦à¦¿à¦·à§à¦Ÿ সীমা পূৰà§à¦£" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"উলà§à¦²à¦¿à¦–িত বিনà§à¦¯à¦¾à¦¸à¦¤ অনà§à¦¤à§°à§à¦­à§à¦•à§à¦¤ সামগà§à§°à§€, আংশিক মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à¦¤ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "আংশিক মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§° সময় বেক পà§à§°à¦¸à¦‚গ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "পà§à¦¨à§°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿à§° সীমা পূৰà§à¦£" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "নতà§à¦¨ পংকà§à¦¤à¦¿ চিহà§à¦¨à¦•াৰী ফà§à¦²à§‡à¦—à§° অৱৈধ দল" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "বেয়া অফচেট" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "সৰৠutf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "বাৰংবাৰতা লà§à¦ª" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "অজà§à¦žà¦¾à¦¤ তà§à§°à§à¦Ÿà¦¿" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "পংকà§à¦¤à¦¿à§° শেষত \\ উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "পংকà§à¦¤à¦¿à§° শেষত \\c উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "\\ à§° পিছত অজà§à¦žà¦¾à¦¤ আখৰ উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} quantifier ত সংখà§à¦¯à¦¾ কà§à§°à¦®à¦¤ নাই" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} quantifier à§° সংখà§à¦¯à¦¾ অতà§à¦¯à¦¾à¦§à¦¿à¦• ডাঙৰ" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "আখৰৰ শà§à§°à§‡à¦£à§€à§° শেষত ] চিহà§à¦¨ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "আখৰৰ শà§à§°à§‡à¦£à§€à¦¤ অৱৈধ escape কà§à§°à¦®" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "আখৰৰ শà§à§°à§‡à¦£à§€à§° অঞà§à¦šà¦² সীমাৰ বাহিৰত" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "পà§à¦¨à§°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿à§° বাবে à¦à¦•à§‹ উপসà§à¦¥à¦¿à¦¤ নাই" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ পà§à¦¨à§°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? অথবা (?- à§° পিছত অপৰিচিত আখৰ" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX নামৰ শà§à§°à§‡à¦£à§€à¦¸à¦®à§‚হ অকল শà§à§°à§‡à¦£à§€à¦¤ সমৰà§à¦¥à¦¿à¦¤ হ'ব" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "শেষৰ ) অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ উপবিনà§à¦¯à¦¾à¦¸ নিৰà§à¦¦à§‡à¦¶ কৰা হৈছে" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "বকà§à¦¤à¦¬à§à¦¯à§° পিছত ) চিহà§à¦¨ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "সাধাৰণ অভিবà§à¦¯à¦•à§à¦¤à¦¿ অতà§à¦¯à¦¾à¦§à¦¿à¦• ডাঙৰ" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "মেমৰি পà§à§°à¦¾à¦ªà§à¦¤ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr "( চিহà§à¦¨ নোহোৱাকে ) চিহà§à¦¨ পà§à§°à§Ÿà§‹à¦— কৰা হৈছে" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "ক'ড অভাৰফà§à¦²à§‹" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "(?< চিহà§à¦¨à§° পিছত অজà§à¦žà¦¾à¦¤ আখৰ উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind assertion সীমিত দৈৰà§à¦˜à§à¦¯à§° নহয়" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "(?( à§° পিছত তà§à§°à§à¦Ÿà¦¿à¦ªà§‚à§°à§à¦£ সংখà§à¦¯à¦¾ বা নাম উপসà§à¦¥à¦¿à¦¤ আছে" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "চৰà§à¦¤à¦¸à¦¾à¦ªà§‡à¦•à§à¦· দলত দà§à¦Ÿà¦¾à¦¤à¦•ৈ অধিক শাখা আছে" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "(?( à§° পিছত assertion পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R বা (?[+-]সংখà§à¦¯à¦¾ à§° পিছত ) চিহà§à¦¨ বà§à¦¯à§±à¦¹à¦¾à§° কৰা আৱশà§à¦¯à¦•" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "অজà§à¦žà¦¾à¦¤ POSIX শà§à§°à§‡à¦£à§€à§° নাম" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "POSIX কলেটিং পদাৰà§à¦¥ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} শাৰীত আখৰৰ মান বৰ ডাঙৰ" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "অৱৈধ চৰà§à¦¤ (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "lookbehind assertion ত \\C à§° অনà§à¦®à¦¤à¦¿ নাই" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escape \\L, \\l, \\N{name}, \\U, আৰৠ\\u সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "ৰিকাৰà§à¦›à¦¿à¦­ কল অনিশà§à¦šà¦¿à¦¤ কাললৈ লà§à¦ª কৰিব পাৰে" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "(?P চিহà§à¦¨à§° পিছত অজà§à¦žà¦¾à¦¤ আখৰ উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "উপবিনà§à¦¯à¦¾à¦¸ নামত হেৰà§à§±à¦¾ টাৰà§à¦®à¦¿à¦¨à§‡à¦Ÿà§°" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "দà§à¦Ÿà¦¾ নাম দিয়া উপবিনà§à¦¯à¦¾à¦¸à¦¸à¦®à§‚হ à§° à¦à¦•ে নাম" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "তà§à§°à§à¦Ÿà¦¿à¦ªà§‚à§°à§à¦£ \\P বা \\p কà§à§°à¦®" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "\\P বা \\p à§° পিছত অজà§à¦žà¦¾à¦¤ বৈশিষà§à¦Ÿà§° নাম" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "উপবিনà§à¦¯à¦¾à¦¸ নাম বৰ দীঘল (সৰà§à¦¬à¦¾à¦§à¦¿à¦• ৩২ টা আখৰ)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "বহà§à¦¤ নাম দিয়া উপবিনà§à¦¯à¦¾à¦¸à¦¸à¦®à§‚হ (সৰà§à¦¬à¦¾à¦§à¦¿à¦• ১০,০০০)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "অকà§à¦Ÿà¦¾à¦² মান \\377 à§° অধিক" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "অভাৰৰেন কমপাইলিং কৰà§à¦®à¦¸à§à¦¥à¦¾à¦¨" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "আগতে পৰীকà§à¦·à¦¾ কৰা সনà§à¦¦à§°à§à¦­ থকা উপবিনà§à¦¯à¦¾à¦¸ পোৱা নগল" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE দলত à¦à¦•াধিক বà§à§°à¦¾à¦žà§à¦š উপসà§à¦¥à¦¿à¦¤ আছে" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "বিসংগত NEWLINE বিকলà§à¦ªà¦¸à¦®à§‚হ" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g à¦à¦Ÿà¦¾ বà§à§°à§‡à¦‡à¦š, à¦à¦™à§à¦²-বà§à§°à§‡à¦•েট, অথবা কৌট নাম অথবা নমà§à¦¬à§°, অথবা à¦à¦Ÿà¦¾ সাধাৰণ নমà§à¦¬à§° " +"দà§à¦¬à¦¾à§°à¦¾ অনà§à¦•ৰিত নহয়" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "à¦à¦Ÿà¦¾ সাংখà§à¦¯à¦¿à¦• পà§à§°à¦¸à¦‚গ শূনà§à¦¯ হব নোৱাৰিব" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "(*ACCEPT), (*FAIL), অথবা (*COMMIT) à§° বাবে à¦à¦Ÿà¦¾ তৰà§à¦•à§° অনà§à¦®à¦¤à¦¿ নাই" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) পৰিচিত নহয়" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "নমà§à¦¬à§° অতà§à¦¯à¦¾à¦§à¦¿à¦• ডাঙৰ" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& পিছৰ উপবিনà§à¦¯à¦¾à¦¸ নাম সনà§à¦§à¦¾à¦¨à¦¹à§€à¦¨" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ à§° পিছত ডিজিট পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "JavaScript সংগতি অৱসà§à¦¥à¦¾à¦¤ ] à¦à¦Ÿà¦¾ অবৈধ তথà§à¦¯ আখৰ" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "à¦à¦•ে নমà§à¦¬à§°à§° উপবিনà§à¦¯à¦¾à¦¸à§° বাবে ভিনà§à¦¨ নাম অনà§à¦®à§‹à¦¦à¦¿à¦¤ নহয়" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) à§° à¦à¦Ÿà¦¾ তৰà§à¦• থাকিব লাগিব" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c à¦à¦Ÿà¦¾ ASCII আখৰ দà§à¦¬à¦¾à§°à¦¾ অনà§à¦•ৰিত হব লাগিব" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k à¦à¦Ÿà¦¾ বà§à§°à§‡à¦‡à¦š, à¦à¦™à§à¦²-বà§à§°à§‡à¦•েট, অথবা কৌট নাম দà§à¦¬à¦¾à§°à¦¾ অনà§à¦•ৰিত নহয়" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N à¦à¦Ÿà¦¾ শà§à§°à§‡à¦£à§€à¦¤ সমৰà§à¦¥à¦¿à¦¤ নহয়" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "অতà§à¦¯à¦¾à¦§à¦¿à¦• আগবà§à§‹à§±à¦¾ পà§à§°à¦¸à¦‚গসমূহ" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), অথবা (*THEN) ত নাম অতà§à¦¯à¦¾à¦§à¦¿à¦• ডাঙৰ" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... কà§à§°à¦®à¦¤ আখৰ মান অতি ডাঙৰ" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "সাধাৰণ অভিবà§à¦¯à¦•à§à¦¤à¦¿ %s à§° মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à¦¤ সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE লাইবà§à§°à§‡à§°à¦¿ UTF8 সমৰà§à¦¥à¦¨ নোহোৱাকে কমপাইল কৰা হৈছে" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE লাইবà§à§°à§‡à§°à¦¿ UTF8 বৈশিষà§à¦Ÿà§à¦¯à§° সমৰà§à¦¥à¦¨ নোহোৱাকে কমপাইল কৰা হৈছে" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE লাইবà§à§°à§‡à§°à§€ অসংগত বিকলà§à¦ªà¦¸à¦®à§‚হ দà§à¦¬à¦¾à§°à¦¾ কমপাইল কৰা আছে" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "সাধাৰণ অভিবà§à¦¯à¦•à§à¦¤à¦¿ %s, %d আখৰত কমপাইল কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "সাধাৰণ অভিবà§à¦¯à¦•à§à¦¤à¦¿ %s à§° সৰà§à¦¬à§‹à¦¤à§à¦¤à¦® বà§à¦¯à§±à¦¹à¦¾à§°à¦¤ সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "hexadecimal সংখà§à¦¯à¦¾ বা '}' পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "hexadecimal সংখà§à¦¯à¦¾ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "সাঙà§à¦•েতিক পà§à§°à¦¸à¦‚গত '<' অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "সাঙà§à¦•েতিক পà§à§°à¦¸à¦‚গ অসমà§à¦ªà§‚à§°à§à¦£" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "সাঙà§à¦•েতিক পà§à§°à¦¸à¦‚গত আখৰ সংখà§à¦¯à¦¾ শূণà§à¦¯" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "সংখà§à¦¯à¦¾ পà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "অৱৈধ সাঙà§à¦•েতিক পà§à§°à¦¸à¦‚গ" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "অনà§à¦¤à¦¤ অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ '\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "অজà§à¦žà¦¾à¦¤ à¦à¦¸à§à¦•েইপ কà§à§°à¦®" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "পà§à§°à¦¤à¦¿à¦¸à§à¦¥à¦¾à¦ªà¦¨ লিখনি \"%s\" আখৰ %lu ত বিশà§à¦²à§‡à¦·à¦£ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "উদà§à¦§à§ƒà¦¤à¦¿à§° অংশ উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨ দà§à¦¬à¦¾à§°à¦¾ আৰমà§à¦­ কৰা নহয়" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "কমানà§à¦¡ শাৰী বা শà§à¦¬à§‡à¦² à§° উদà§à¦§à§ƒà¦¤à¦¿à¦¤ অসংগত উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "'\\' আখৰৰ পিছত লিখনি সমাপà§à¦¤ হৈছে। (লিখনি আছিল '%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "%c à§° কà§à¦·à§‡à¦¤à§à§°à¦¤ সà§à¦¸à¦‚গত উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨ পোৱা নাযায়। (লিখনি আছিল '%s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "লিখনি ৰিকà§à¦¤ (বা অকল শূণà§à¦¯à¦¸à§à¦¥à¦¾à¦¨à¦¸à¦¹)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à§° পৰা তথà§à¦¯ পà§à¦¿à¦¬à¦²à§ˆ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à§° পৰা তথà§à¦¯ পà§à¦¾à§° সময়ত select() অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ তà§à§°à§à¦Ÿà¦¿ (%s)" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() ত অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ তà§à§°à§à¦Ÿà¦¿ (%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ ক'ড %ld à§° সৈতে পà§à§°à¦¸à§à¦¥à¦¾à¦¨ কৰিলে" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ সংকেত %ld দà§à¦¬à¦¾à§°à¦¾ kill কৰা হৈছে" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ সংকেত %ld দà§à¦¬à¦¾à§°à¦¾ বনà§à¦§ কৰা হৈছে" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ অসà§à¦¬à¦¾à¦­à¦¾à§±à¦¿à¦•ভাৱে পà§à§°à¦¸à§à¦¥à¦¾à¦¨ কৰিলে" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "চাইলà§à¦¡ পাইপৰ পৰা পà§à¦¿à¦¬à¦²à§ˆ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork কৰিবলৈ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "'%s' ডাইৰেকটৰিলৈ পৰিবৰà§à¦¤à¦¨ কৰিবলৈ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ \"%s\" চলাওà¦à¦¤à§‡ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à§° আউটপà§à¦Ÿ বা ইনপà§à¦Ÿ পà§à¦¨à§°à¦¨à¦¿à§°à§à¦¦à§‡à¦¶ কৰিবলৈ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ fork কৰিবলৈ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ \"%s\" পà§à§°à¦£à§Ÿà¦¨ কৰিবলৈ অজà§à¦žà¦¾à¦¤ তà§à§°à§à¦Ÿà¦¿" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "চাইলà§à¦¡ pid পাইপৰ পৰা পৰà§à¦¯à¦¾à¦ªà§à¦¤ তথà§à¦¯ পà§à¦¿à¦¬à¦²à§ˆ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à§° পৰা তথà§à¦¯ পà§à¦¿à¦¬à¦²à§ˆ বà§à¦¯à§°à§à¦¥" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à§° সৈতে যোগাযোগৰ উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পাইপ সৃষà§à¦Ÿà¦¿à¦¤ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾ পà§à§°à¦£à§Ÿà¦¨ কৰিবলৈ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "অৱৈধ পà§à§°à¦—à§à§°à¦¾à¦®à§° নাম: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d ত তৰà§à¦• সদিশত উলà§à¦²à¦¿à¦–িত পংকà§à¦¤à¦¿ বৈধ নহয়: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "পৰিবেশত উলà§à¦²à¦¿à¦–িত পংকà§à¦¤à¦¿ বৈধ নহয়: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "সকà§à§°à¦¿à§Ÿ ডাইৰেকটৰি বৈধ নহয়: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "সহায়ক পà§à§°à¦—à§à§°à¦¾à¦® চলাওà¦à¦¤à§‡ বà§à¦¯à§°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"চাইলà§à¦¡ পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à§° পৰা তথà§à¦¯ পà§à¦¾à§° সময়ত g_io_channel_win32_poll() ত অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ " +"তà§à§°à§à¦Ÿà¦¿" + +#: ../glib/gutf8.c:780 +msgid "Failed to allocate memory" +msgstr "মেমৰি আবনà§à¦Ÿà¦¨ কৰিবলৈ বà§à¦¯à§°à§à¦¥" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "আখৰ UTF-8 à§° আয়তà§à¦¬à§° বাহিৰত" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "ৰূপানà§à¦¤à§° কৰাৰ উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পà§à§°à¦¦à¦¤à§à¦¤ তথà§à¦¯à¦¤ অৱৈধ ধাৰা" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "আখৰ UTF-16 à§° আয়তà§à¦¬à§° বাহিৰত" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u বাইট" +msgstr[1] "%u বাইটসমূহ" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s বাইট" +msgstr[1] "%s বাইটসমূহ" + +msgctxt "full month name with day" +msgid "January" +msgstr "জানà§à§±à¦¾à§°à§€" + +msgctxt "full month name with day" +msgid "February" +msgstr "ফেবà§à§°à§à§±à¦¾à§°à§€" + +msgctxt "full month name with day" +msgid "March" +msgstr "মাৰà§à¦š" + +msgctxt "full month name with day" +msgid "April" +msgstr "à¦à¦ªà§à§°à¦¿à¦²" + +msgctxt "full month name with day" +msgid "May" +msgstr "মে" + +msgctxt "full month name with day" +msgid "June" +msgstr "জà§à¦¨" + +msgctxt "full month name with day" +msgid "July" +msgstr "জà§à¦²à¦¾à¦‡" + +msgctxt "full month name with day" +msgid "August" +msgstr "আগষà§à¦Ÿ" + +msgctxt "full month name with day" +msgid "September" +msgstr "চেপà§à¦¤à§‡à¦®à§à¦¬à§°" + +msgctxt "full month name with day" +msgid "October" +msgstr "অকà§à¦Ÿà§‹à¦¬à§°" + +msgctxt "full month name with day" +msgid "November" +msgstr "নভেমà§à¦¬à§°" + +msgctxt "full month name with day" +msgid "December" +msgstr "ডিচেমà§à¦¬à§°" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "জান" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ফেবà§à§°à§" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "মাৰà§à¦š" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "à¦à¦ªà§à§°à¦¿" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "মে" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "জà§à¦¨" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "জà§à¦²" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "আগ" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "চেপ" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "অকà§à¦Ÿ" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "নভ" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ডিচ" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "ইনপà§à¦Ÿ ফাইলক xmllint à§° সৈতে পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à¦•ৰণ কৰোতে তà§à§°à§à¦Ÿà¦¿:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata à§° সৈতে ইনপà§à¦Ÿ ফাইল পà§à§°à¦•à§à§°à¦¿à§Ÿà¦¾à¦•ৰণ কৰোতে তà§à§°à§à¦Ÿà¦¿:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "পেনà§à¦¡à¦¿à¦‚ তà§à§°à§à¦Ÿà¦¿ পাবলৈ বà§à¦¯à§°à§à¦¥: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "'%s' ফাইল লিখিবৰ বাবে খোলাত বà§à¦¯à§°à§à¦¥: fdopen() বà§à¦¯à§°à§à¦¥: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "'%s' ফাইল লিখাত বà§à¦¯à§°à§à¦¥: fflush() বà§à¦¯à§°à§à¦¥: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "'%s' ফাইল বনà§à¦§ কৰাত বà§à¦¯à§°à§à¦¥: fclose() বà§à¦¯à§°à§à¦¥: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "'%s' à§° বাবে অসমà§à¦ªà§‚à§°à§à¦£ তথà§à¦¯ পà§à§°à¦¾à¦ªà§à¦¤ হৈছে" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "SO_PASSCRED চকেটৰ বাবে সামৰà§à¦¥à¦¬à¦¾à¦¨ আছে নে নিৰীকà§à¦·à¦£ কৰোতে অপà§à§°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ বিকলà§à¦ª " +#~ "দৈৰà§à¦˜à§à¦¯à¥¤ আশা কৰা হৈছিল %d বাইটসমূহ, পোৱা গল %d" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "কমানà§à¦¡ শাৰী '%s' সৃজন কৰোতে অসà§à¦¬à¦¾à¦­à¦¾à§±à¦¿à¦• পà§à§°à¦—à§à§°à¦¾à¦® অনà§à¦¤: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "কমানà§à¦¡ শাৰী '%s' অ-শূণà§à¦¯ পà§à§°à¦¸à§à¦¥à¦¾à¦¨ অৱসà§à¦¥à¦¾ %d সৈতে পà§à§°à¦¸à§à¦¥à¦¾à¦¨ কৰিছে: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "ৰিকà§à¦¤ উপসà§à¦Ÿà§à§°à¦¿à¦‚ à§° কৰà§à¦®à¦•à§à¦·à§‡à¦¤à§à§°à§° সীমা পূৰà§à¦£" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "ফলা সলনি কৰা escapes (\\l, \\L, \\u, \\U) à§° ইয়াত অনà§à¦®à¦¤à¦¿ নাই" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "কোনো DEFINE দলৰ পà§à¦¨à§°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿ কৰা নাযাব" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' à§° কাৰণে সেৱাৰ ৰেকৰà§à¦¡ নাই" + +#~ msgid "File is empty" +#~ msgstr "ফাইল ৰিকà§à¦¤" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "কি ফাইলত '%s' কি উপসà§à¦¥à¦¿à¦¤ আছে যাৰ মান বà§à¦œà¦¿à¦¬ পৰা নাযায়।" + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "ফাইল '%s' stat কৰিবলৈ বà§à¦¯à§°à§à¦¥: %s" + +#~ msgid "Error connecting: " +#~ msgstr "সংযোগ কৰিবলৈ তà§à§°à§à¦Ÿà¦¿:" + +#~ msgid "Error connecting: %s" +#~ msgstr "সংযোগ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "unix à§° পৰা পà§à¦¿à¦¬à¦²à§ˆ সমসà§à¦¯à¦¾: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "unix বনà§à¦§ কৰিবলৈ সমসà§à¦¯à¦¾: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "unix লৈ লিখিবলৈ সমসà§à¦¯à¦¾: %s" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "ডাইৰেকটৰিৰ ওপৰত ডাইৰেকটৰি সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à§° কৰা নাযাব" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "ৰূপানà§à¦¤à§° কৰাৰ উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পà§à§°à¦¦à¦¤à§à¦¤ তথà§à¦¯à¦¤ অৱৈধ ধাৰা" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "সৰà§à¦¬à¦¾à¦§à¦¿à¦• তথà§à¦¯ শাৰীৰ সীমা পোৱা গ'ল" + +#~ msgid "do not hide entries" +#~ msgstr "ইনপà§à¦Ÿ লà§à¦•à§à§±à¦¾ কৰা নহব" + +#~ msgid "use a long listing format" +#~ msgstr "দীঘল তালিকাৰ আকৃতি বà§à¦¯à§±à¦¹à¦¾à§° কৰক" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "'%s' আখৰ পদাৰà§à¦¥à§° নামৰ আৰমà§à¦­à¦¨à¦¿à§° বাবে বৈধ নহয়; & আখৰে à¦à¦Ÿà¦¾ পদাৰà§à¦¥ আৰমà§à¦­ কৰে; যদি " +#~ "à¦à¦‡ à¦à¦®à§à¦ªà¦¾à§°à¦›à§‡à¦¨à§à¦¦ à¦à¦Ÿà¦¾ পদাৰà§à¦¥ নহব লাগে, তাক & হিচাপে আউটপà§à¦Ÿà¦¨ কৰক" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "'%s' আখৰ পদাৰà§à¦¥à§° নামৰ ভিতৰত বৈধ নহয়" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "ৰিকà§à¦¤ আখৰৰ সঙà§à¦•েত; à¦à¦Ÿà¦¾ সংখà§à¦¯à¦¾ থাকিব লাগে যেনে &#৪৫৪;" + +#~ msgid "Unfinished entity reference" +#~ msgstr "অসমà§à¦ªà§‚à§°à§à¦£ পদাৰà§à¦¥à§° উলà§à¦²à§‡à¦–" + +#~ msgid "Unfinished character reference" +#~ msgstr "অসমà§à¦ªà§‚à§°à§à¦£ আখৰৰ উলà§à¦²à§‡à¦–" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "অৱৈধ UTF-8 সাঙà§à¦•েতিক লিপি - overlong কà§à§°à¦®" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "অৱৈধ UTF-8 সাঙà§à¦•েতিক লিপি - à¦à¦Ÿà¦¾ আৰমà§à¦­à§° আখৰ নহয়" + +#~ msgid "file" +#~ msgstr "ফাইল" + +#~ msgid "The file containing the icon" +#~ msgstr "আইকন ধাৰণকাৰী ফাইল" + +#~ msgid "name" +#~ msgstr "নাম" + +#~ msgid "names" +#~ msgstr "নাম" + +#~ msgid "An array containing the icon names" +#~ msgstr "আইকনৰ নাম ধাৰণকাৰী à¦à¦Ÿà¦¾ শাৰী" + +#~ msgid "use default fallbacks" +#~ msgstr "অবিকলà§à¦ªà¦¿à¦¤ fallbacks বà§à¦¯à§±à¦¹à¦¾à§° কৰক" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "'-' আখৰত নাম সৰৠকৰি পোৱা অবিকলà§à¦ªà¦¿à¦¤ fallbacks বà§à¦¯à§±à¦¹à¦¾à§° কৰা হ'ব নে নহয়। বহà§à¦¤ " +#~ "নাম দিলে পà§à§°à¦¥à¦® নামৰ পিছৰ নাম আওকাণ কৰা হয়।" + +#~ msgid "File descriptor" +#~ msgstr "ফাইলৰ দেসà§à¦•à§à§°à¦¿à¦ªà§à¦Ÿà§°" + +#~ msgid "The file descriptor to read from" +#~ msgstr "পà§à¦¿à¦¬ লগা ফাইলৰ দেসà§à¦•à§à§°à¦¿à¦ªà§à¦Ÿà§°" + +#~ msgid "Close file descriptor" +#~ msgstr "ফাইলৰ দেসà§à¦•à§à§°à¦¿à¦ªà§à¦Ÿà§° নিৰà§à¦¬à§à¦¬à¦¾à¦šà¦¨ কৰক" + +#~ msgid "Whether to close the file descriptor when the stream is closed" +#~ msgstr "সà§à§°à§‹à¦¤ বনà§à¦§ কৰিলে ফাইলৰ দেসà§à¦•à§à§°à¦¿à¦ªà§à¦Ÿà§° বনà§à¦§ কৰা হ'ব নে নহয়" + +#~ msgid "The file descriptor to write to" +#~ msgstr "ফাইল দেসà§à¦•à§à§°à¦¿à¦ªà§à¦Ÿà§° য'ত লিখিব লাগে" diff --git a/po/ast.po b/po/ast.po new file mode 100644 index 0000000..9144b60 --- /dev/null +++ b/po/ast.po @@ -0,0 +1,3821 @@ +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2010-01-04 19:27+0100\n" +"Last-Translator: astur \n" +"Language-Team: Asturian \n" +"Language: ast\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-Launchpad-Export-Date: 2010-01-04 18:12+0000\n" +"X-Generator: Launchpad (build Unknown)\n" +"X-Poedit-Language: asturian\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Atributu inesperáu «%s» pal elementu «%s»" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "L'atributu «%s» del elementu «%s» nun s'atopó" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Etiqueta «%s» inesperada, esperabase la etiqueta «%s»" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Etiqueta «%s» inesperada dientro de «%s»" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Nun pudo atopase dengún ficheru de marcadores válidu nos direutorios de datos" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Yá esiste un marcador pal URI «%s»" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Nun s'atopó un marcador pal URI «%s»" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Denguna triba MIME definida nel marcador pa la URI «%s»" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Nun se definió dengún flag priváu nel marcador pal URI «%s»" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Nun s'afitó dengún grupu nel marcador pal URI «%s»" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "Denguna aplicación con nome «%s» registró un marcador pa «%s»" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Fallu al espander la llinia d'execución '%s' con URI '%s'" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" +"La conversión dende'l conxuntu de carauteres «%s» a «%s» nun ye sofitada" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Nun pudo abrir el conversor de «%s» a «%s»" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Hai una secuencia de bytes nun válida na entrada de conversión" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Ocurrió un fallu durante la conversión: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Hai una secuencia parcial de carauteres nel final de la entrada" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Nun puede convertise'l fallback «%s» al conxuntu de códigos «%s»" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "La URI «%s» nun ye una URI absoluta usando l'esquema «file»" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "El ficheru llocal na URI «%s» nun tien d'incluyir un «#»" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "La URI «%s» ye non válida" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "El nome del anfitrión de la URI «%s» ye non válidu" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "La URI «%s» caltién carauteres d'escape inválidos" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "El nome de la camín «%s» nun ye un camín absolutu" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "El nome del anfitrión ye non válidu" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "xineru" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "febreru" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "marzu" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "abril" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "mayu" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "xunu" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "xunetu" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "xin" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "abr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "may" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "xun" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "xnt" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "llunes" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "martes" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "miércoles" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "xueves" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "vienres" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sábadu" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "domingu" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "llu" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "mar" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "mié" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "xue" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "vie" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sáb" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "dom" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Ocurrió un fallu al abrir el direutoriu «%s»: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Nun se pueden asignar %lu bytes pa lleer el ficheru «%s»" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Ocurrió un fallu al lleer el ficheru «%s»: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "El ficheru «%s» ye enforma grande" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Ocurrido un fallu na llectura dende'l ficheru «%s»: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Ocurrido un fallu al abrir el ficheru «%s»: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" +"Ocurrió un fallu al algamar los atributos del ficheru «%s»: fstat() falló: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Ocurrió un fallu al abrir el ficheru «%s»: fdopen() falló: %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Falló al renomar el ficheru «%s» a «%s»: g_rename() falló: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Ocurrió un fallu al criar el ficheru «%s»: %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Falló al abrir el ficheru «%s» pa escritura: fdopen() falló: %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Ocurrió un fallu al escribir el ficheru «%s»: fwrite() falló: %s" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Falló al escribir el ficheru «%s»: falló fflush(): %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Falló al escribir el ficheru «%s»: falló fsync(): %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Ocurrió un fallu al zarrar el ficheru «%s»: fclose() falló: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "El ficheru esistente «%s» nun pudo desaniciase: g_unlink() falló: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "La plantilla «%s» ye non válida, nun tendría que caltener un «%s»" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "La plantilla «%s» nun caltién XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f EB" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, fuzzy, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Ocurrió un fallu al lleer l'enllaz simbólicu «%s»: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Enllaces simbólicos non sofitaos" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Nun pudo abrise'l conversor de «%s» a «%s»: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" +"Nun puede facese una llectura en brutu (raw) en g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Dexarónse datos non convertíos nel búfer de llectura" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "La canal fina nun caráuter parcial" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" +"Nun puede facese una llectura en brutu (raw) en g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Ocurrió un fallu al abrir el ficheru «%s»: open() falló: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Ocurrió un fallu al mapear el ficheru «%s»: mmap() falló: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Fallu na llinia %d, caráuter %d: " + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Testu codificáu como UTF-8 nel nome non válidu; «%s» nun ye válidu" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "«%s» nun ye un nome válidu " + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "«%s» nun ye un nome válidu: «%c» " + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Fallu na llinia %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Asocedió un fallu al analizar «%-.*s», el cual tendría de tener un díxitu " +"dientro d'un caráuter de referencia( por exemplu ê) - seique'l díxitu " +"ye enforma grande" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"El caráuter de referencia nun fina con puntu y coma; probablemente usaste un " +"caráuter «&» ensin pretender aniciar una entidá - escapa'l caráuter \"&\" " +"como &" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "El caráuter de referencia «%-.*s» non codifica un caráuter permitíu" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"La entidá '&;' ta vacía; les entidaes válides son: & " < > " +"'" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "El nome de la entidá «%-.*s» desconozse" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"La entidá nun fina con un puntu y coma; probablemente usaste'l caráuter \"&" +"\" ensin la intención d'indicar una entidá - escapa'l signu \"&\" como &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "El documentu tien d'entamar con un elementu (por exemplu: )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"«%s» nun ye un caráuter válidu de siguio del caráuter '<': nun tien " +"d'aniciar el nome d'un elementu" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Caráuter «%s» impropiu, esperabase un caráuter «>» pa finar la etiqueta " +"vacía del elementu «%s»" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Caráuter impropiu «%s», esperabase'l caráuter '=' dempués del nome " +"d'atributu «%s» del elementu «%s»" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Caráuter impropiu «%s», esperabase un caráuter '>' o '/' pa finar l'aniciu " +"de la etiqueta del elementu «%s» o opcionalmente un atributu; tal vez usaste " +"un caráuter que nun ye válidu nun nome d'atributu" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Caráuter impropiu «%s», esperabase una marca d'apertura de comilles dempués " +"del signu igual al da-y valor al atributu «%s» del elementu «%s»" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"«%s» nun ye un caráuter válidu de siguio del nome del elementu de cierre " +"«%s»; el caráuter permitíu ye '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "L'elementu «%s» foi zarráu, nun esiste dengún elementu abiertu" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"L'elementu «%s» zarróse, pero l'elemento que ta abiertu anguaño ye «%s»" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "El documentu taba ermu o namái caltenía espacios en blancu" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "El documentu fina inesperadamente xusto dempués d'un '<'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"El documentu fina inesperadamente con ementos todavía abiertos - «%s» foi'l " +"caberu elementu abiertu" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"El documentu fina inesperadamente, esperabase un caráuter '>' finanando la " +"etiqueta <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "El documentu fina inesperadamente dientro d'un nome d'elementu" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "El documentu fina inesperadamente dientro d'un nome d'atributu" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"El documentu fina inesperadamente dientro d'una etiqueta d'apertura " +"d'elementu." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"El documentu fina inesperadamente dempués de los signos igual que siguen al " +"nome d'atributu; ensin valor d'atributu" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "El documentu fina inesperadamente dientro del valor d'un atributu" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"El documentu fina inesperadamente dientro de la etiqueta cierre del elementu " +"«%s»" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"El documentu fina inesperadamente dientro d'un comentariu o procesando una " +"instrucción" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "oxetu corruptu" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "fallu internu o oxetu corruptu" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "ensin memoria" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "algamóse'l llímite de «backtracking»" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "el patrón caltién elementos non sofitaos pa una coincidencia parcial" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "fallu internu" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"nun se sofiten referencies anteriores como condiciones pa coincidencies " +"parciales" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "algamóse'l llímite de recursividá" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "llímite del espaciu de trabayu cuando s'alcancen subcadenes vacíes" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "combinación de banderes de nueva llinia inválides" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "fallu desconocíu" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ al final del patrón" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c al final del patrón" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "caráuter non reconocíu dempués de \\" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" +"equí nun se permite escapar les lletres (\\l, \\L, \\u, \\U) (mayúscula y " +"minúscula)" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "númberos fuera de rangu nel cuantificador {}" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "númberu enforma grande nel cuantificador {}" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "falta la terminación ] pa la clas de caráuter" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "secuencia d'escape non válida na clas de caráuter" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "rangu fuera d'orde na clas de caráuter" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "na que repetir" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "caráuter non reconocíu dempués de (?" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "caráuter non reconocíu dempués de (?<" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "caráuter non reconocíu dempués de (?P" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "Sólo sofitense les clases con nomes POSIX dientro d'una clase" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "falta'l ) de terminación" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") ensin ( que lu abra" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R o los díxitos (?[+-] deben tar seguíos por )" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "referencia a un subpatrón non esistente" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "falta ) dempués del comentariu" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "la espresión regular ye enforma llarga" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "falló al obtener memoria" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "la comprobación «lookbehind» nun tien una llonxitú fixa" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "númberu o nome mal formáu dempués de (?(" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "el grupu condicional caltién más de dos rames" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "esperabase una comprobación dempués de (?(" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "nome de clas POSIX desconocíu" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "los elementos POSIX recopilaos nun tán sofitaos" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "el valor del caráuter na secuencia \\x{…} ye enforma llargu" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "condición nun válida (?(0)" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "nun se permite \\C en comprobaciones «lookbehind»" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "una llamada recursiva podrá criar un bucle infinitu" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "falta'l terminador nel nome del subpatrón" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "dos subpatrones tien el mesmu nome" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "secuencia \\P o \\p mal formada" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "nome de propiedá desconocíu dempués de \\P o \\p" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "el nome del subpatrón ye enforma llargu (máximu 32 caracteres)" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "demasiados subpatrones con nome (máximu 10.000)" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "el valor octal ye mayor que \\377" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "el grupu DEFINE caltién más d'una rama" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "nun se permite repetir un grupu DEFINE" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "opciones NEWLINE inconsistentes" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" +"\\g nun tá seguíu por un nome de llave o un númberu distintu de cero con una " +"llave opcional" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "repetición inesperada" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "desbordamientu de códigu" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "desbordóse l'espaciu de trabayu de compilación" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "nun s'atopó'l subpatrón referenciáu anteriormente comprobáu" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Fallu al coincidir cola espresión regular %s: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "La biblioteca PCRE ta compilada ensin sofitu pa UTF8" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "La biblioteca PCRE ta compilada ensin sofitu pa les propiedaes d'UTF8" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Fallu al compilar la espresión regular %s nel caráuter %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Fallu al optimizar la espresión regular %s: %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "esperábase un díxitu hexadecimal o «}»" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "esperábase un díxitu hexadecimal" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "falta «<» na referencia simbólica" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "referencia de símbolu ensin finar" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "referencia simbólica de llonxitú cero" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "esperábase un díxitu" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "referencia simbólica illegal" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "final '\\' perdiu" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "secuencia d'escape desconocía" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "Fallu al analizar el testu de reemplazu «%s» nel caráuter %lu: %s" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "El testu entrecomilláu non entama con un signu de comilla" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Falta una comilla na llinia de comandos o n'otru testu con comilles de la " +"triba shell" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "El testu fina xusto dempués d'un caráuter '\\'. (El testu yera «%s»)" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"El testu finó enantes de que s'atopará la comilla correspondiente con %c (El " +"testu yera «%s»)" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "El testu ta ermu (o namái caltién espacios en blancu)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Ocurrió un fallu al lleer los datos dende un procesu fíu" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Ocurrió un fallu na creación d'un conductu (pipe) pa comunicase col procesu " +"fíu (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Ocurrió un fallu al lleer dende'l conductu (pipe) fíu (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Ocurrió un fallu al camudar al direutoriu «%s» (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Ocurrió un fallu al executar el procesu fíu (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nome de programa non válidu: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Cadena non válida nel vector del argumentu en %d: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Cadena non válida nel entornu: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Directoriu de trabayu non válidu: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Ocurrió un fallu al executar el programa auxiliar (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ocurrió un fallu inesperáu en g_io_channel_win32_poll() al lleer datos dende " +"un procesu fíu" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Ocurrió un fallu na llectura de datos dende'l procesu fíu (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Ocurrió un fallu inesperáu en select() lleendo datos dende'l procesu fíu (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ocurrió un fallu inesperáu en waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Falló al bifurcar (fork) (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Ocurrió un fallu al executar el procesu fíu «%s» (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"Ocurrió un fallu al redirigir la salida o la entrada del procesu fíu (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Ocurrió un fallu al llanzar el procesu fíu (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Ocurrió un fallu desconocíu al executar el procesu fíu «%s»" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Ocurrió un fallu al intentar lleer suficientes datos dende'l conductu fíu " +"(%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "El caráuter atopáse fuera del rangu pa UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "La secuencia na conversión d'entrada nun ye válida" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "El caráuter atopáse fuera del rangu pa UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Usu:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPCIÓN...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Opciones d'aida:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Amosar opciones d'aida" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Amosar toles opciones d'aida" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Opciones de l'aplicación:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Nun puede analizase'l valor enteru «%s» pa %s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "El valor enteru «%s» pa %s ta fuera de rangu" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Nun puede analizase'l valor duble «%s» pa %s" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "El valor duble «%s» pa %s ta fuera de rangu" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Fallu al analizar la opción: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Falta un argumentu pa %s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Opción desconocía %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Nun pudo atopase la contraseña de ficheru válida nos direutorios de gueta" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Nun ye un ficheru regular" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "El ficheru ta ermu" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"El ficheru de claves caltién la llinia «%s» que nun ye un par valor-" +"contraseña, grupu o comentariu" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nome de grupu non válidu: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "El ficheru de claves non entama con un grupu" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Nome de claves non válida: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "El ficheru de claves caltién una codificación non sofitada «%s»" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "El ficheru de claves nun tien el grupu «%s»" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "El ficheru de claves nun tien la contraseña «%s»" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"El ficheru de claves caltién la contraseña «%s» col valor «%s» el cual nun " +"ye UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" +"El ficheru de claves caltién la contraseña «%s» que tien un valor que non " +"puede ser interpretáu." + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"El ficheru de claves contién la clave «%s» que tien un valor que nun se " +"puede interpretar." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"El ficheru de claves caltién la contraseña «%s» nel grupu «%s» que tien un " +"valor que nun puede ser interpretáu." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "El ficheru de claves nun tien la contraseña «%s» nel grupu «%s»" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" +"El ficheru de claves caltién un caráuter d'escape al final de la llinia" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "El ficheru de claves caltién la secuencia d'escape non válida «%s»" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "El valor «%s» nun puede interpretase como un númberu." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "El valor enteru «%s» ta fuera de rangu" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "El valor «%s» nun puede interpretase como un númberu de coma flotante." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "El valor «%s» nun puede interpretase como un booleanu." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "El valor de conteu pasáu a %s ye enforma llargu" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "El fluxu ya se zarró" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "Encaboxóse la operación" + +#: ../gio/gcharsetconverter.c:263 +#, fuzzy +msgid "Invalid object, not initialized" +msgstr "Socket incorreutu, non anicializáu" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Hai una secuencia de bytes nun válida na entrada de conversión" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +#, fuzzy +msgid "Not enough space in destination" +msgstr "Nun hai abondu espaciu pa la direición del socket" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "Anicialización encaboxable non soportada" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Triba desconocía" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "triba de ficheru %s" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "triba %s" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "Final de fluxu inesperadamente prematuru" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, fuzzy, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "Direición de socket non sofitada" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Fallu coneutando: " + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Fallu al abrir el ficheru «%s»: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Ocurrió un fallu al lleer el ficheru «%s»: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Ocurrió un fallu al lleer el ficheru «%s»: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Fallu al escribir nel ficheru: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Ocurrió un fallu al lleer el ficheru «%s»: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Triba desconocía" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Ocurrió un fallu al abrir el direutoriu «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Fallu al criar el direutoriu: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Fallu al abrir el ficheru «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Ocurrió un fallu al lleer el ficheru «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Ocurrió un fallu al lleer el ficheru «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Fallu al zarrar el ficheru: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Fallu al abrir el ficheru «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Fallu al abrir el ficheru «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "El socket amestáu ta peslláu" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, fuzzy, c-format +msgid "Property '%s' is not readable" +msgstr "La triba %s nun tien clas" + +#: ../gio/gdbusconnection.c:3959 +#, fuzzy, c-format +msgid "Property '%s' is not writable" +msgstr "La triba %s nun tien clas" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "L'escuchador yá ta peslláu" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, fuzzy, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "«%s» nun ye un nome válidu " + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Fallu al escribir nel ficheru: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Nun ta sofitao mover a la papelera" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Fallu al escribir nel ficheru: %s" + +#: ../gio/gdbusserver.c:1042 +#, fuzzy, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "«%s» nun ye un nome válidu " + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Fallu na llinia %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Fallu al analizar la opción: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +#, fuzzy +msgid "Connect to given D-Bus address" +msgstr "Conexón en cursu" + +#: ../gio/gdbus-tool.c:360 +#, fuzzy +msgid "Connection Endpoint Options:" +msgstr "Conexón en cursu" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Fallu coneutando: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, fuzzy, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "«%s» nun ye un nome válidu " + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "«%s» nun ye un nome válidu " + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "«%s» nun ye un nome válidu " + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "«%s» nun ye un nome válidu " + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Fallu al analizar la opción: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Fallu aceutando conexón: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Ocurrió un fallu al abrir el direutoriu «%s»: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "oxetu corruptu" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Ensin nome" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "El ficheru d'escritoriu nun especificó'l campu Exec" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "Imposible atopar el terminal requeríu pola aplicación" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" +"Nun puede criase la carpeta de configuración de l'aplicación %s del usuariu: " +"%s" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "Nun puede criase la carpeta de configuración MIME %s d'usuariu: %s" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Nun puede criase'l ficheru d'escritoriu %s d'usuariu" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "Definición personalizada pa %s" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "la unidá non implementa la espulsión" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "la unidá nun implementa la espulsión o espulsión-con-operación" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "la unidad non implementa'l sondeu pa medios" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "la unidá nun implementa reproducir" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "la unidá nun implementa detener" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "Nun puede manexase la versión %d de la codificación GEmblem" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Númberu de tokens (%d) mal formaos na codificación GEmblem" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "Nun puede manexase la versión %d de la codificación GEmblemedIcon" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Númberu de tokens (%d) mal formaos na codificación GEmblemedIcon" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Esperabase un GEmblem pa GEmblemedIconjo" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Operación non sofitada" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "El puntu de montaxe conteníu nun esiste" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "Nun puede copiase sobro'l direutoriu" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "Nun puede copiase direutoriu sobro direutoriu" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "El ficheru destín ya esiste" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "Nun puede copiase'l direutoriu recursivamente" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Enllaces simbólicos non sofitaos" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Fallu al abrir el ficheru: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "Nun puede copiase'l ficheru especial" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "El valor del enllaz simbólicu dáu nun ye válidu" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "Nun ta sofitao mover a la papelera" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Los nomes de ficheru nun pueden caltener «%c»" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "el volume nun implementa'l montáu" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "Nun hai denguna aplicación rexistrada pa manexar esti ficheru" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "L'enumerador ta zarráu" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "L'enumerador del ficheru tien una operación excepcional" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "L'enumerador del ficheru ya ta zarráu" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "Nun puede remanase la versión %d de la codificación GFileIcon" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Datos d'entrada mal formaos pa GFileIcon" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "El fluxu non sofita query_info" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "Nun se permite guetar nel fluxu" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "Nun se permite truncar nel fluxu d'entrada" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "Nun se sofita'l truncamiento nel fluxu" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Númberu de tokens (%d) incorreutu" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "Non esiste la triba pa la clas de nome %s" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "La triba %s non implementa la interface GIcon" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "La triba %s nun tien clas" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "Númberu de versión mal formáu: %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "La triba %s non implementa from_tokens() na interface GIcon" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "Nun puede manexase la versión proporcionada de la codificación d'iconu" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "El fluxu d'entrada non implementa la llectura" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "El fluxu tien una operación excepcional" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "Nun hai abondu espaciu pa la direición del socket" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "Direición de socket non sofitada" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Nun ta sofitao mover a la papelera" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, fuzzy, c-format +msgid "invalid GVariant type string '%s'" +msgstr "Triba d'atributu non válidu (esperabase una cadena)" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" +"Nun pudo atopase la triba de monitorización del direutoriu llocal " +"predetermináu" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Nome de ficheru nun válidu %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Fallu al obtener la información del sistema de ficheros: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "Nun puede renomase'l direutoriu raíz" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Fallu al renomar el ficheru: %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "Nun puede renomase'l ficheru, el nome ya esiste" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Nome de ficheru non válidu" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Fallu al abrir el ficheru: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "Nun puede abrise'l direutoriu" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Fallu al desaniciar el ficheru: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "Fallu al mover a la papelera'l ficheru: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Nun pudo criase'l direutoriu papelera %s: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "Nun pudo atopase'l direutoriu de nivel superior pa mover a la papelera" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "Nun pudo atopase o criar el direutoriu de la papelera" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Nun pudo criase la información de papelera pal ficheru: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Nun pudo unviase a la papelera'l ficheru: %s" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "Fallu al criar el direutoriu: %s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "El sistema de ficheros nun sofita enllaces simbólicos" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Fallu al criar l'enllaz simbólicu: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Fallu al mover el ficheru: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "Nun puede movese un direutoriu sobro un direutoriu" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "Falló la criación del ficheru de respaldu" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "Fallu al desaniciar el ficheru destín: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "Nun se sofita mover ficheros ente puntos de montaxe" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "El valor del atributu de ser non nulu" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "Triba d'atributu non válidu (esperabase una cadena)" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "Nome extendíu del atributu non válidu" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Fallu al afitar l'atributu estendíu «%s»: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "Fallu al amosar información del estáu del ficheru «%s»: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (codificación non válida)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "" +"Fallu al amosar la información del estáu del descriptor del ficheru: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Triba d'atributu non válida (esperabase uint32)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Triba d'atributu nun válida (esperabase uint64)" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "Triba d'atributu non válida (esperabase una cadena byte)" + +#: ../gio/glocalfileinfo.c:1904 +msgid "Cannot set permissions on symlinks" +msgstr "Nun pueden afitase permisos n'enllaces simbólicos" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Fallu al afitar permisos: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "Fallu al afitar el propietariu: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "l'enllaz simbólicu tien de ser non nulu" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Fallu al afitar l'enllaz simbólicu: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Fallu al afitar l'enllaz simbólicu: el ficheru nun ye un enllaz simbólicu" + +#: ../gio/glocalfileinfo.c:2139 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Fallu al afitar o modificar el tiempu d'accesu: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "El contestu SELinux tien de ser non nulu" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Fallu al afitar el contestu SELinux: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nun ta activáu n'esti sistema" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Afitar l'atributu %s nun tá sofitáu" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Fallu al lleer del ficheru: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Fallu al guetar nel ficheru: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Fallu al zarrar el ficheru: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" +"Nun pudo atopase la triba de monitorización del ficheru llocal predetermináu" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Fallu al escribir nel ficheru: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Fallu al desaniciar l'enllaz de respaldu antiguu: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Fallu al criar una copia de respaldu: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Fallu al renomar el ficheru temporal: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "Fallu al truncar el ficheru: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Fallu al abrir el ficheru «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "El ficheru destín ye un direutoriu" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "El ficheru destín nun ye un ficheru regular" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "El ficheru camudóse esternamente" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "Fallu al desaniciar el ficheru antiguu: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "Proporcionóse un GSeekType non válidu" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Petición de gueta non válida" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Nun puede truncase GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "El fluxu de salida de la memoria nun ye redimensionable" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "Falló al redimensionar el fluxu de salida de la memoria" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "el puntu de montaxe non implementa'l desmontáu («unmount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "el puntu de montaxe non implementa la espulsión («eject»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"el puntu de montaxe nun implementa desmontáu («unmount») o desmontáu-con-" +"operación («unmount_with_operation»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"el puntu de montaxe nun implementa la espulsión («eject») o espulsión-con-" +"operación («eject_with_operation»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "el puntu de montaxe non implementa remontáu («eject_with_operation»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" +"el puntu de montaxe non implementa averiguación de la triba de conteníu" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" +"el puntu de montaxe non implementa averiguación de la triba de conteníu " +"síncrona" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "El nome del equipu «%s» contién «[» pero non «]»" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "El fluxu de salida non implementa la escritura" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "El fluxu d'orixe ya ta zarráu" + +#: ../gio/gresolver.c:779 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "Fallu na resolución de «%s»: %s" + +#: ../gio/gresolver.c:829 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Fallu na resolución inversa de «%s»: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "Nun hai dengún rexistru de serviciu pa «%s»" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "Nun ye dable resolver temporalmente «%s»" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, c-format +msgid "Error resolving '%s'" +msgstr "Fallu na resolución de «%s»" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Opción desconocía %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "Socket incorreutu, non anicializáu" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Socket incorreutu, falló n'anicialización darréu de: %s" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "El socket áa ta peslláu" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "creando Gsocket de df: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Nun pudo crease'l socket: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "Especificóse un protocolu desconocíu" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "nun pudo obtenese la direición llocal: %s" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "nun pudo obtenese la direición remota: %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "nun s'escuchó: %s" + +#: ../gio/gsocket.c:1446 +#, c-format +msgid "Error binding to address: %s" +msgstr "Fallu al vinculase a la direición: %s" + +#: ../gio/gsocket.c:1566 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Fallu aceutando conexón: %s" + +#: ../gio/gsocket.c:1683 +msgid "Error connecting: " +msgstr "Fallu coneutando: " + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "Conexón en cursu" + +#: ../gio/gsocket.c:1695 +#, c-format +msgid "Error connecting: %s" +msgstr "Fallu coneutando: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "Incapaz d'obtener el fallu pendiente: %s" + +#: ../gio/gsocket.c:1875 +#, c-format +msgid "Error receiving data: %s" +msgstr "Fallu al recibir datos: %s" + +#: ../gio/gsocket.c:2050 +#, c-format +msgid "Error sending data: %s" +msgstr "Fallu al unviar datos: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Nun pudo crease'l socket: %s" + +#: ../gio/gsocket.c:2242 +#, c-format +msgid "Error closing socket: %s" +msgstr "Fallu al pesllar el socket: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Esperando la condición del socket: %s" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, c-format +msgid "Error sending message: %s" +msgstr "Fallu al unviar mensax: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "GSocketControlMessage non sofitáu sobro ventanes" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, c-format +msgid "Error receiving message: %s" +msgstr "Fallu al recibir mensax: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "Fallu desconocíu al coneutar" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "La triba %s nun tien clas" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "L'escuchador yá ta peslláu" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "El socket amestáu ta peslláu" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "Nun puede manexase la versión %d de la codificación GThemedIcon" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "Esperábase 1 mensax de control, obtúvose %d" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "Triba inesperada de datos auxiliares" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "Esperábase un fd, pero obtúvose %d\n" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "fd inválidu recibíu" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Fallu al unviar datos: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Fallu al renomar el ficheru: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, fuzzy, c-format +msgid "Not expecting control message, but got %d" +msgstr "Esperábase 1 mensax de control, obtúvose %d" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "Fallu al lleer d'unix: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "Fallu al zarrar unix: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "Sistema de ficheros raíz" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "Fallu al escribir n'unix: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" +"Esti sistema nun almite direiciones abstrautes de sockets de dominiu Unix." + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "el volume non implementa la espulsión" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "el volume nun implementa la espulsión o espulsión-con-operación" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "Nun puede atopase l'aplicación" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "Fallu al analizar l'aplicación: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "Nun se sofita URI" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "los cambeos d'asociación nun tán sofitaos en win32" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "La criación d'asociación nun tá sofitada en win32" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Fallu al lleer del ficheru: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Fallu al zarrar el ficheru: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Fallu al escribir nel ficheru: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "ensin memoria" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "fallu internu" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "El nome del anfitrión ye non válidu" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Nun puede movese un direutoriu sobro un direutoriu" + +#, fuzzy +#~ msgid "Key %s is not writable\n" +#~ msgstr "La triba %s nun tien clas" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "La secuencia na conversión d'entrada nun ye válida" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "Algamóse'l llímite máximu del array de datos" diff --git a/po/az.po b/po/az.po new file mode 100644 index 0000000..7059ceb --- /dev/null +++ b/po/az.po @@ -0,0 +1,3817 @@ +# translation of glib.HEAD.az.po to Azerbaijani Turkish +# Copyright (C) 2001, 2004 Free Software Foundation, Inc. +# KEMAL YILMAZ , 2001. +# MÉ™tin Æmirov , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD.az\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2004-02-02 12:12+0200\n" +"Last-Translator: MÉ™tin Æmirov \n" +"Language-Team: Azerbaijani Turkish \n" +"Language: az\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0.2\n" + +#: ../glib/gbookmarkfile.c:780 +#, fuzzy, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" +"TÉ™k hÉ™rf '%s', xüsusiyyÉ™t adı '%s' olan element '%s' dÉ™n sonra '=' gözlÉ™nilir" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "'%s' simvolik körpüsü oxuna bilmÉ™di: %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "'%s' hÉ™rf dÉ™stÉ™sindÉ™n '%s' hÉ™rf dÉ™stÉ™sinÉ™ dönüşdürmÉ™ dÉ™stÉ™klÉ™nmir" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' dÉ™n '%s' É™ dönüşdürücü açıla bilmir: %s" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "dönüşdürmÉ™ giriÅŸindÉ™ hökmsüz bayt qatarı" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "GiriÅŸin sonunda parçalı hÉ™rf qatarı" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "fallback '%s' hÉ™rf dÉ™stÉ™si '%s' É™ dönüşdürülÉ™ bilmir" + +#: ../glib/gconvert.c:1886 +#, fuzzy, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "'%s' URI-si fayl sxemini iÅŸlÉ™dÉ™n mütlÉ™q URI deyildir" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "Yerli fayl uRI-si '%s' '#' daxil edÉ™ bilmÉ™z" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "'%s' URI-si sÉ™hvdir" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "'%s' URI-sinin qovÅŸaq adı sÉ™hv qaçırılmış" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "'%s'in URİ-si sÉ™hv qaçırılmış xarakterlÉ™r daxil edir" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s'in cığır adı mütlÉ™q cığır deyildir" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Hökmsüz qovÅŸaq adı" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A, %d %B %Y %T" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "yanvar" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "fevral" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "mart" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "aprel" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "may" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "iyun" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "iyul" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Yan" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Fev" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "May" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "İyn" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "İyl" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "bazar ertÉ™si" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "çərÅŸÉ™nbÉ™ axÅŸamı" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "çərÅŸÉ™nbÉ™" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "cümÉ™ axÅŸamı" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "cümÉ™" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "ÅŸÉ™nbÉ™" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "bazar günü" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ber" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "çax" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "çər" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "cax" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "cüm" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ÅŸnb" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "baz" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "CÉ™rgÉ™ açma xÉ™tası: '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "\"%2$s\" faylını oxumaq üçün %1$lu bayt ayrıla bilmir" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Fayldan oxuma iflası '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Fayl açma iflası '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Faylın xüsusiyyÉ™tlÉ™rini É™ldÉ™ etmÉ™ iflası '%s': fstat() iflası: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gfileutils.c:862 +#, fuzzy, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Fayl yaratma iflası '%s': %s" + +#: ../glib/gfileutils.c:918 +#, fuzzy, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gfileutils.c:943 +#, fuzzy, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gfileutils.c:1030 +#, fuzzy, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "NümunÉ™ '%s' hökmsüzdür, '%s' daxil etmÉ™mÉ™lidir" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Åžablon '%s' XXXXXX ilÉ™ qurtarmır" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "'%s' simvolik körpüsü oxuna bilmÉ™di: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../glib/giochannel.c:1408 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' dÉ™n '%s' É™ dönüşdürücü açıla bilmir: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Can't do a raw read in g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Oxuna buferdÉ™ dönüşdürülmÉ™miÅŸ verilÉ™nlÉ™r var" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Kanal qismi xarakterlÉ™ bitir" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Can't do a raw read in g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, fuzzy, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gmappedfile.c:229 +#, fuzzy, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "%d. sÉ™tir %d. xarakterindÉ™ xÉ™ta: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Hökmsüz UTF-8 kodlanmış mÉ™tn" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d sÉ™tirindÉ™ xÉ™ta : %s" + +#: ../glib/gmarkup.c:638 +#, fuzzy, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%s' i ÅŸÉ™rhlÉ™ndirmÉ™ xÉ™tası, hÉ™rf içindÉ™ bir rÉ™qÉ™m olmalıdır referens (mÉ™s; " +"ê) - belki rÉ™qÉ™m çok böyükdür" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Xarakter referens nöqtÉ™li vergül ilÉ™ qurtarmır; böyük ehtimalla ampersand " +"xarakteri elementÉ™ baÅŸlamaq üçün iÅŸlÉ™tmÉ™diniz - ampersand yerinÉ™ & iÅŸlÉ™dÉ™ " +"bilÉ™rsiniz" + +#: ../glib/gmarkup.c:676 +#, fuzzy, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Xarakter referens '%s' icazÉ™ verilÉ™n xarakteri kodlaya bilmir" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"BoÅŸ element '&;' tapldı; hökmlü elementlÉ™r: & " < &qt; '" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Element adı '%s' bilinmir" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Element nöqtÉ™li vergül ilÉ™ qurtarmır; böyük ehtimalla bir ampersand " +"iÅŸlÉ™tdiniz bir element baÅŸlanğıcı ola bilmÉ™yÉ™n hÉ™rf üçün ampersandı & " +"olaraq iÅŸlÉ™din" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "SÉ™nÉ™d bir element ilÉ™ baÅŸlamalıdır (mÉ™s. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'<' xarakterindÉ™n sonra gÉ™lÉ™n '%s' hökmlü bir xarakter deyil; bir element " +"adı olmaya bilÉ™r" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"TÉ™k hÉ™rf '%s', Elementın baÅŸlanğıç etiketinin sonuna '>' xarakteri " +"gözlÉ™nilir '%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"TÉ™k hÉ™rf '%s', xüsusiyyÉ™t adı '%s' olan element '%s' dÉ™n sonra '=' gözlÉ™nilir" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"TÉ™k hÉ™rf '%s', '%s' elementin baÅŸlanğıç etiketinin sonuna '>' vÉ™ ya '/' " +"gözlÉ™nilir, vÉ™ ya bir xüsusiyyÉ™t; xüsusiyyÉ™t adında hökmsüz bir hÉ™rf " +"iÅŸlÉ™dilmiÅŸ ola bilÉ™rsiniz" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"TÉ™k hÉ™rf '%s',element '%s'in xüsusiyyÉ™ti '%s''É™ qiymÉ™t verilirkÉ™n bÉ™rabÉ™rdir " +"iÅŸarÉ™tindÉ™n sonra açıq alıntı iÅŸarÉ™ti gözlÉ™nilir" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"BaÄŸlı element '%s' dÉ™n sonra gÉ™lÉ™n '%s' hökmlü bir hÉ™rf deyildir; icazÉ™ " +"verilÉ™n hÉ™rf isÉ™ '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Element '%s' baÄŸlanıb, heç bir element açıq deyildir" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Element '%s' baÄŸlanıb, fÉ™qÉ™t indi açıq element '%s'" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "SÉ™nÉ™d boÅŸdur vÉ™ ya tÉ™kcÉ™ boÅŸluq xarakteri daxil etmÉ™kdÉ™dir" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"SÉ™nÉ™d açıq üçbucaq mötÉ™rizÉ™ '<'den sonra gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"SÉ™nÉ™d elementlÉ™ri hÉ™lÉ™ açıq olaraq gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı - son " +"element '%s' açıq idi" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"SÉ™nÉ™d gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı, etiket <%s/> ilÉ™ qurtaran qapalı " +"üçbucaq mötÉ™rizÉ™ gözlÉ™nilir" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "SÉ™nÉ™d bir elementin içindÉ™ gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "SÉ™nÉ™d bir xüsusiyyÉ™t adı içindÉ™ gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "SÉ™nÉ™d bir element-açma etiketi içindÉ™ gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"SÉ™nÉ™d xüsusiyyÉ™t adını tÉ™qib edÉ™n bÉ™rabÉ™rdir iÅŸarÉ™tindÉ™n sonra gözlÉ™nilmÉ™z " +"bir ÅŸÉ™kildÉ™ qurtardı: xüsusiyyÉ™t qiymÉ™ti yoxdur" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"SÉ™nÉ™d bir xüsusiyyÉ™t qiymÉ™ti içindÉ™ ikÉ™n gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "SÉ™nÉ™d baÄŸlı etiket '%s' içindÉ™ gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"SÉ™nÉ™d bir ÅŸÉ™rh vÉ™ ya gediÅŸat göstÉ™riÅŸi içindÉ™ ikÉ™n gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ " +"qurtarır" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "Kanal qismi xarakterlÉ™ bitir" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "dönüşdürmÉ™ giriÅŸindÉ™ hökmsüz bayt qatarı" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "BitirilmÉ™miÅŸ xarakter mÉ™'lumatı" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "BitirilmÉ™miÅŸ xarakter mÉ™'lumatı" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "BitirilmÉ™miÅŸ xarakter mÉ™'lumatı" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "%d. sÉ™tir %d. xarakterindÉ™ xÉ™ta: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "BitirilmÉ™miÅŸ varlıq mÉ™'lumatı" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "alıntılı mÉ™tn alıntı iÅŸarÉ™ti ilÉ™ baÅŸlamır" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Æmr sÉ™tirindÉ™ vÉ™ ya digÉ™r shell-quoted mÉ™tndÉ™ uyÄŸunsuz alıntı iÅŸarÉ™ti" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "MÉ™tn '\\' xarakterindÉ™n hÉ™mÉ™n sonra qurtardı. (MÉ™tn '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "%c üçün uyÄŸunluq alıntısı tapılmadan mÉ™tn qurtardı. (MÉ™tn '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "MÉ™tn boÅŸ idi (vÉ™ ya tÉ™kcÉ™ boÅŸluq daxil edirdi)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "TörÉ™mÉ™ gediÅŸatdan mÉ™'lumat oxuma iflası" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "TörÉ™mÉ™ gediÅŸatların xÉ™bÉ™rləşmÉ™yi üçün pipe yaratma iflası (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "TörÉ™mÉ™ pipe-dan oxuma iflası (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Qovluq dÉ™yiÅŸdirmÉ™ iflası '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "TörÉ™mÉ™ gediÅŸat icra iflası (%s)" + +#: ../glib/gspawn-win32.c:444 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "Hökmsüz qovÅŸaq adı" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, fuzzy, c-format +msgid "Invalid string in environment: %s" +msgstr "dönüşdürmÉ™ giriÅŸi içindÉ™ hökmsüz qatar" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, fuzzy, c-format +msgid "Invalid working directory: %s" +msgstr "CÉ™rgÉ™ açma xÉ™tası: '%s': %s" + +#: ../glib/gspawn-win32.c:783 +#, fuzzy, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Yardımcı proqram icra edilÉ™ bilmÉ™di" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"g_io_channel_win32_poll() törÉ™mÉ™ gediÅŸatdan mÉ™'lumat oxumada gözlÉ™nilmÉ™z xÉ™ta" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "TörÉ™mÉ™ gediÅŸatdan mÉ™'lumat oxuma iflası (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "törÉ™mÉ™ gediÅŸatdan mÉ™'lumat oxuma select()'dÉ™ namÉ™'lum xÉ™ta (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid()'dÉ™ namÉ™'lum xÉ™ta (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork iflası (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "\"%s\" törÉ™mÉ™ gediÅŸat icra iflası (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "TörÉ™mÉ™ gediÅŸat giriÅŸ vÉ™ ya yekun istiqamÉ™tlÉ™ndirmÉ™ xÉ™tası (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "TörÉ™mÉ™ gediÅŸat fork xÉ™tası (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "\"%s\" törÉ™mÉ™ gediÅŸat iÅŸindÉ™ namÉ™'lum xÉ™ta" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "TörÉ™mÉ™ pid pipe dan kifayÉ™t qÉ™dÉ™r mÉ™'lumat oxuma iflası (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 üçün hÉ™rf sÉ™rhÉ™dinin xaricindÉ™" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "dönüşdürmÉ™ giriÅŸi içindÉ™ hökmsüz qatar" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 üçün hÉ™rf sÉ™rhÉ™dinin xaricindÉ™dir" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "Hökmsüz qovÅŸaq adı" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "Hökmsüz qovÅŸaq adı" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, fuzzy, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "'%s'in URİ-si sÉ™hv qaçırılmış xarakterlÉ™r daxil edir" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "dönüşdürmÉ™ giriÅŸindÉ™ hökmsüz bayt qatarı" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "CÉ™rgÉ™ açma xÉ™tası: '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "CÉ™rgÉ™ açma xÉ™tası: '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "%d sÉ™tirindÉ™ xÉ™ta : %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Xarakter '%s' bir element adının içindÉ™ hökmlü deyildir" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Xarakter '%s' bir element adının içindÉ™ hökmlü deyildir" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Xarakter '%s' bir element adının içindÉ™ hökmlü deyildir" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "CÉ™rgÉ™ açma xÉ™tası: '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Hökmsüz qovÅŸaq adı" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "Hökmsüz qovÅŸaq adı" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Fayl yaratma iflası '%s': %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Fayl yaratma iflası '%s': %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "Fayl yaratma iflası '%s': %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "CÉ™rgÉ™ açma xÉ™tası: '%s': %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "'%s' simvolik körpüsü oxuna bilmÉ™di: %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "SÉ™nÉ™d bir xüsusiyyÉ™t adı içindÉ™ gözlÉ™nilmÉ™z bir ÅŸÉ™kildÉ™ qurtardı" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "CÉ™rgÉ™ açma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "%d sÉ™tirindÉ™ xÉ™ta : %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Hökmsüz qovÅŸaq adı" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Fayl yaratma iflası '%s': %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "\"%2$s\" faylını oxumaq üçün %1$lu bayt ayrıla bilmir" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Fayl yaratma iflası '%s': %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Fayl yaratma iflası '%s': %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "%d sÉ™tirindÉ™ xÉ™ta : %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "Simvolik körpülÉ™r dÉ™stÉ™klÉ™nmir" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Hökmsüz qovÅŸaq adı" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "dönüşdürmÉ™ giriÅŸi içindÉ™ hökmsüz qatar" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Element adının başındakı hÉ™rf '%s' hökmlü deyil; & hÉ™rf bir elementlÉ™ " +#~ "baÅŸlayar; É™gÉ™r bu ampersand bir element olaraq var sayılmazsa, & " +#~ "olaraq iÅŸlÉ™dÉ™ bilÉ™rsiniz" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "BoÅŸ hÉ™rf referens; dž kimi bir rÉ™qÉ™m daxil etmÉ™lidir;" + +#~ msgid "Unfinished entity reference" +#~ msgstr "BitirilmÉ™miÅŸ varlıq mÉ™'lumatı" + +#~ msgid "Unfinished character reference" +#~ msgstr "BitirilmÉ™miÅŸ xarakter mÉ™'lumatı" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Hökmsüz UTF-8 kodlanmış mÉ™tn" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Hökmsüz UTF-8 kodlanmış mÉ™tn" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "'%s' URI-sinin qovÅŸaq adı sÉ™hv qaçırılmış" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "'%s' URI-sinin qovÅŸaq adı sÉ™hv qaçırılmış" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Fayl oxuma xÉ™tası: '%s': %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "DönüşdürmÉ™ sırasında xÉ™ta yarandı: %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Fayl açma iflası '%s': fdopen() iflası: %s" diff --git a/po/be.po b/po/be.po new file mode 100644 index 0000000..2031ab5 --- /dev/null +++ b/po/be.po @@ -0,0 +1,4509 @@ +# Ihar Hrachyshka , 2011-2013. +# Kasia Bondarava , 2012. +msgid "" +msgstr "" +"Project-Id-Version: glib.master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-09-11 19:37+0000\n" +"PO-Revision-Date: 2012-09-14 13:26+0300\n" +"Last-Translator: Ihar Hrachyshka \n" +"Language-Team: Belarusian \n" +"Language: be\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Virtaal 0.7.0\n" +"X-Project-Style: gnome\n" + +#: ../gio/gbufferedinputstream.c:424 ../gio/gbufferedinputstream.c:503 +#: ../gio/ginputstream.c:174 ../gio/ginputstream.c:366 +#: ../gio/ginputstream.c:604 ../gio/ginputstream.c:822 +#: ../gio/goutputstream.c:192 ../gio/goutputstream.c:721 +#: ../gio/gpollableinputstream.c:207 ../gio/gpollableoutputstream.c:208 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Ðадта вÑлікае значÑнне перададзена Ñž %s" + +#: ../gio/gbufferedinputstream.c:896 ../gio/gbufferedoutputstream.c:577 +#: ../gio/gdataoutputstream.c:564 +msgid "Seek not supported on base stream" +msgstr "Базавы Ñтрумень не падтрымлівае пракрутку" + +#: ../gio/gbufferedinputstream.c:942 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Ðемагчыма абрÑзаць GBufferedInputStream" + +#: ../gio/gbufferedinputstream.c:987 ../gio/ginputstream.c:1012 +#: ../gio/giostream.c:280 ../gio/goutputstream.c:1323 +msgid "Stream is already closed" +msgstr "Струмень ужо закрыты" + +#: ../gio/gbufferedoutputstream.c:614 ../gio/gdataoutputstream.c:594 +msgid "Truncate not supported on base stream" +msgstr "Базавы Ñтрумень не падтрымлівае абразаннÑ" + +#: ../gio/gcancellable.c:314 ../gio/gdbusconnection.c:1897 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1421 +#: ../gio/glocalfile.c:2178 ../gio/gsimpleasyncresult.c:843 +#: ../gio/gsimpleasyncresult.c:869 +#, c-format +msgid "Operation was cancelled" +msgstr "ДзеÑнне ÑкаÑавана" + +#: ../gio/gcharsetconverter.c:262 +msgid "Invalid object, not initialized" +msgstr "Хібны, неініцыÑваны аб'ект" + +#: ../gio/gcharsetconverter.c:283 ../gio/gcharsetconverter.c:311 +msgid "Incomplete multibyte sequence in input" +msgstr "ÐбрÑÐ·Ð°Ð½Ð°Ñ Ð¼Ð½Ð¾Ð³Ð°Ð±Ð°Ð¹Ñ‚Ð°Ð²Ð°Ñ Ð¿Ð°ÑлÑдоўнаÑць на ўваходзе" + +#: ../gio/gcharsetconverter.c:317 ../gio/gcharsetconverter.c:326 +msgid "Not enough space in destination" +msgstr "У меÑцы прызначÑÐ½Ð½Ñ Ð½Ðµ Ñтае вольнай праÑторы" + +#: ../gio/gcharsetconverter.c:344 ../gio/gdatainputstream.c:849 +#: ../gio/gdatainputstream.c:1259 ../glib/gconvert.c:467 +#: ../glib/gconvert.c:859 ../glib/giochannel.c:1586 ../glib/giochannel.c:1628 +#: ../glib/giochannel.c:2472 ../glib/gutf8.c:833 ../glib/gutf8.c:1284 +msgid "Invalid byte sequence in conversion input" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð¿Ð°ÑлÑдоўнаÑць байтаў ва ўводзе на пераўтварÑнне" + +#: ../gio/gcharsetconverter.c:349 ../glib/gconvert.c:475 +#: ../glib/gconvert.c:784 ../glib/giochannel.c:1593 ../glib/giochannel.c:2484 +#, c-format +msgid "Error during conversion: %s" +msgstr "ÐŸÐ°Ð´Ñ‡Ð°Ñ Ð¿ÐµÑ€Ð°ÑžÑ‚Ð²Ð°Ñ€ÑÐ½Ð½Ñ ÑžÐ·Ð½Ñ–ÐºÐ»Ð° памылка: %s" + +#: ../gio/gcharsetconverter.c:446 ../gio/gsocket.c:993 +msgid "Cancellable initialization not supported" +msgstr "ІніцыÑÑ†Ñ‹Ñ Ð· магчымаÑцю ÑкаÑÐ°Ð²Ð°Ð½Ð½Ñ Ð½Ðµ падтрымліваецца" + +#: ../gio/gcharsetconverter.c:457 ../glib/gconvert.c:347 +#: ../glib/giochannel.c:1414 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "ПераўтварÑнне даных Ñа знаказбору \"%s\" у \"%s\" не падтрымліваецца" + +#: ../gio/gcharsetconverter.c:461 ../glib/gconvert.c:351 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÐºÑ€Ñ‹Ñ†ÑŒ пераўтваральнік з \"%s\" у \"%s\"" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "Тып %s" + +#: ../gio/gcontenttype-win32.c:162 +msgid "Unknown type" +msgstr "ÐевÑдомы тып" + +#: ../gio/gcontenttype-win32.c:163 +#, c-format +msgid "%s filetype" +msgstr "Тып файлаў %s" + +#: ../gio/gcredentials.c:264 ../gio/gcredentials.c:528 +msgid "GCredentials is not implemented on this OS" +msgstr "Механізм GCredentials адÑутнічае Ð´Ð»Ñ Ð³Ñтай аперацыйнай ÑÑ–ÑÑ‚Ñмы" + +#: ../gio/gcredentials.c:438 +msgid "There is no GCredentials support for your platform" +msgstr "Ваша Ð¿Ñ€Ð°Ð³Ñ€Ð°Ð¼Ð½Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° не падтрымлівае механізму GCredentials" + +#: ../gio/gcredentials.c:480 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"GCredentials не змÑшчаюць ідÑнтыфікатара працÑÑу Ð´Ð»Ñ Ð³Ñтай аперацыйнай " +"ÑÑ–ÑÑ‚Ñмы" + +#: ../gio/gdatainputstream.c:306 +msgid "Unexpected early end-of-stream" +msgstr "Ðечаканы заўчаÑны канец ÑтруменÑ" + +#: ../gio/gdbusaddress.c:150 ../gio/gdbusaddress.c:238 +#: ../gio/gdbusaddress.c:319 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "ÐевÑдомы ключ \"%s\" у адраÑе \"%s\"" + +#: ../gio/gdbusaddress.c:177 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"ÐÐ´Ñ€Ð°Ñ \"%s\" мае хібу (трÑба вызначыць толькі адзін з ключоў: Ñцежку, чаÑовы " +"каталог або абÑтрактны Ñокет)" + +#: ../gio/gdbusaddress.c:190 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "БеÑÑÑнÑÐ¾ÑžÐ½Ð°Ñ Ð¿Ð°Ñ€Ð° ключ-значÑнне Ñž адраÑе \"%s\"" + +#: ../gio/gdbusaddress.c:253 ../gio/gdbusaddress.c:334 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "Памылка Ñž адраÑе \"%s\": хібны атрыбут порта" + +#: ../gio/gdbusaddress.c:264 ../gio/gdbusaddress.c:345 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "Памылка Ñž адраÑе \"%s\": хібны атрыбут пратакола" + +#: ../gio/gdbusaddress.c:454 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "Элемент адраÑу \"%s\" не змÑшчае двукроп'Ñ (:)" + +#: ../gio/gdbusaddress.c:475 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" +"Пара ключ-значÑнне %d, \"%s\" (у Ñлеменце адраÑу \"%s\") не змÑшчае знака " +"роўнаÑці" + +#: ../gio/gdbusaddress.c:489 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"Памылка ÑкаÑÐ°Ð²Ð°Ð½Ð½Ñ ÑÐºÑ€Ð°Ð½Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° або Ñго значÑÐ½Ð½Ñ Ñž пары %d, \"%s\", " +"Ð´Ð»Ñ Ñлемента адраÑу \"%s\"" + +#: ../gio/gdbusaddress.c:567 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"Памылка Ñž адраÑе \"%s\": unix-транÑпарт вымагае дакладна толькі аднаго з " +"ключоў \"path\" (Ñцежка) або \"abstract\" (абÑтрактны адраÑ)" + +#: ../gio/gdbusaddress.c:603 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "Памылка Ñž адраÑе \"%s\": атрыбут азначÑÐ½Ð½Ñ Ð¼Ð°ÑˆÑ‹Ð½Ñ‹ адÑутнічае або хібны" + +#: ../gio/gdbusaddress.c:617 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "Памылка Ñž адраÑе \"%s\": атрыбут азначÑÐ½Ð½Ñ Ð¿Ð¾Ñ€Ñ‚Ð° адÑутнічае або хібны" + +#: ../gio/gdbusaddress.c:631 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" +"Памылка Ñž адраÑе \"%s\": атрыбут азначÑÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° таÑмніцы (\"noncefile\") " +"адÑутнічае або хібны" + +#: ../gio/gdbusaddress.c:652 +msgid "Error auto-launching: " +msgstr "Памылка аўтазапуÑку: " + +#: ../gio/gdbusaddress.c:660 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" +"ÐевÑдомы транÑпарт або транÑпарт, Ñкі не абÑлугоўваецца, (\"%s\") Ð´Ð»Ñ Ð°Ð´Ñ€Ð°Ñу " +"\"%s\"" + +#: ../gio/gdbusaddress.c:696 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Памылка Ð°Ð´ÐºÑ€Ñ‹Ñ†Ñ†Ñ Ñ„Ð°Ð¹Ð»Ð° таÑмніцы (\"nonce\") \"%s\": %s" + +#: ../gio/gdbusaddress.c:714 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Памылка Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ Ð· файла таÑмніцы (\"nonce\") \"%s\": %s" + +#: ../gio/gdbusaddress.c:723 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "" +"Памылка Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ Ð· файла таÑмніцы (\"nonce\") \"%s\": чакалі 16 байтаў, а " +"атрымалі %d" + +#: ../gio/gdbusaddress.c:741 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "" +"Памылка пераÑылкі змеÑціва файла таÑмніцы (\"nonce\") \"%s\" у Ñтрумень:" + +#: ../gio/gdbusaddress.c:960 +msgid "The given address is empty" +msgstr "ГÑты Ð°Ð´Ñ€Ð°Ñ Ð¿ÑƒÑты" + +#: ../gio/gdbusaddress.c:1030 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Ðемагчыма Ñтварыць шыну апавÑшчÑÐ½Ð½Ñ Ñƒ Ñ€Ñжыме setuid" + +#: ../gio/gdbusaddress.c:1037 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ðемагчыма Ñтварыць шыну апавÑшчÑÐ½Ð½Ñ Ð±ÐµÐ· ідÑнтыфікатара машыны: " + +#: ../gio/gdbusaddress.c:1079 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "Памылка запуÑку праграмы \"%s\": " + +#: ../gio/gdbusaddress.c:1296 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(УвÑдзіце любы знак, каб закрыць гÑта акно)\n" + +#: ../gio/gdbusaddress.c:1429 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"DBUS-магіÑтраль ÑеанÑа не запушчана, але такÑама не ўдалоÑÑ Ð°ÑžÑ‚Ð°Ð¼Ð°Ñ‚Ñ‹Ñ‡Ð½Ð° " +"запуÑціць новую" + +#: ../gio/gdbusaddress.c:1450 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Ðемагчыма вызначыць Ð°Ð´Ñ€Ð°Ñ ÑеанÑавай магіÑтралі (Ñ‚Ð°ÐºÐ°Ñ Ð·Ð´Ð¾Ð»ÑŒÐ½Ð°Ñць не " +"Ñ€ÑÐ°Ð»Ñ–Ð·Ð°Ð²Ð°Ð½Ð°Ñ Ð´Ð»Ñ Ð²Ð°ÑˆÐ°Ð¹ аперацыйнай ÑÑ–ÑÑ‚Ñмы)" + +#: ../gio/gdbusaddress.c:1549 ../gio/gdbusconnection.c:6908 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"Ðе ўдалоÑÑ Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ñ‹Ñ†ÑŒ Ð°Ð´Ñ€Ð°Ñ Ð¼Ð°Ð³Ñ–Ñтралі апавÑшчÑннÑÑž Ñа зменнай аÑÑÑ€Ð¾Ð´Ð´Ð·Ñ " +"DBUS_STARTER_BUS_TYPE. Ð—Ð¼ÐµÐ½Ð½Ð°Ñ Ð¼Ð°Ðµ невÑдомае значÑнне \"%s\"" + +#: ../gio/gdbusaddress.c:1558 ../gio/gdbusconnection.c:6917 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ðе ўдалоÑÑ Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ñ‹Ñ†ÑŒ Ð°Ð´Ñ€Ð°Ñ Ð¼Ð°Ð³Ñ–Ñтралі апавÑшчÑннÑÑž, бо Ð·Ð¼ÐµÐ½Ð½Ð°Ñ Ð°ÑÑÑ€Ð¾Ð´Ð´Ð·Ñ " +"DBUS_STARTER_BUS_TYPE не наÑтаўлена" + +#: ../gio/gdbusaddress.c:1568 +#, c-format +msgid "Unknown bus type %d" +msgstr "ÐевÑдомы тып магіÑтралі %d" + +#: ../gio/gdbusauth.c:295 +msgid "Unexpected lack of content trying to read a line" +msgstr "Ðечакана не хапіла змеÑціва Ð´Ð»Ñ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ Ñ€Ð°Ð´ÐºÐ°" + +#: ../gio/gdbusauth.c:339 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Ðечакана не хапіла змеÑціва Ð´Ð»Ñ Ð±ÑÑпечнага Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ Ñ€Ð°Ð´ÐºÐ°" + +#: ../gio/gdbusauth.c:510 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"УÑе наÑÑžÐ½Ñ‹Ñ Ð¼ÐµÑ…Ð°Ð½Ñ–Ð·Ð¼Ñ‹ праверкі тоеÑнаÑці вычарпаны (былі Ñпробы: %s) " +"(наÑўна: %s)" + +#: ../gio/gdbusauth.c:1172 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "СкаÑавана праз GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:262 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "Памылка пры зборы звеÑтак аб каталогу \"%s\": %s" + +#: ../gio/gdbusauthmechanismsha1.c:274 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Дазволы на каталог \"%s\" хібныÑ. Чакалі Ñ€Ñжым дазволаў 0700, а маем 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:295 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "Памылка ÑтварÑÐ½Ð½Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð° \"%s\": %s" + +#: ../gio/gdbusauthmechanismsha1.c:378 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Памылка Ð°Ð´ÐºÑ€Ñ‹Ñ†Ñ†Ñ Ð²Ñзкі ключоў \"%s\" Ð´Ð»Ñ Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ: " + +#: ../gio/gdbusauthmechanismsha1.c:402 ../gio/gdbusauthmechanismsha1.c:715 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "Радок %1$d (змеÑÑ‚ радка: \"%3$s\") з вÑзкі ключоў на \"%2$s\" хібны" + +#: ../gio/gdbusauthmechanismsha1.c:416 ../gio/gdbusauthmechanismsha1.c:729 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"Першы Ñкладнік радка %1$d (змеÑÑ‚ радка: \"%3$s\") з вÑзкі ключоў \"%2$s\" " +"хібны" + +#: ../gio/gdbusauthmechanismsha1.c:431 ../gio/gdbusauthmechanismsha1.c:743 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"Другі Ñкладнік радка %1$d (змеÑÑ‚ радка: \"%3$s\") з вÑзкі ключоў \"%2$s\" " +"хібны" + +#: ../gio/gdbusauthmechanismsha1.c:455 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "Квіток з ідÑнтыфікатарам %d не знойдзены Ñž вÑзцы ключоў \"%s\"" + +#: ../gio/gdbusauthmechanismsha1.c:533 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Памылка Ð²Ñ‹Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÑаÑтарÑлага блок-файла \"%s\": %s" + +#: ../gio/gdbusauthmechanismsha1.c:565 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Памылка ÑтварÑÐ½Ð½Ñ Ð±Ð»Ð¾Ðº-файла \"%s\": %s" + +#: ../gio/gdbusauthmechanismsha1.c:595 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Памылка Ð·Ð°ÐºÑ€Ñ‹Ñ†Ñ†Ñ (выдаленага) блок-файла \"%s\": %s" + +#: ../gio/gdbusauthmechanismsha1.c:605 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Памылка Ð²Ñ‹Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð±Ð»Ð¾Ðº-файла \"%s\": %s" + +#: ../gio/gdbusauthmechanismsha1.c:682 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Памылка Ð°Ð´ÐºÑ€Ñ‹Ñ†Ñ†Ñ Ð²Ñзкі ключоў \"%s\" Ð´Ð»Ñ Ð·Ð°Ð¿Ñ–Ñу: " + +#: ../gio/gdbusauthmechanismsha1.c:879 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" +"(Да таго ж, вызваленне блок-файла Ð´Ð»Ñ \"%s\" такÑама пацÑрпела нÑўдачу: %s) " + +#: ../gio/gdbusconnection.c:609 ../gio/gdbusconnection.c:2452 +msgid "The connection is closed" +msgstr "ЗлучÑнне закрыта" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "ТÑрмін Ñ‡Ð°ÐºÐ°Ð½Ð½Ñ ÑкончыўÑÑ" + +#: ../gio/gdbusconnection.c:2574 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "ÐŸÐ°Ð´Ñ‡Ð°Ñ ÑтварÑÐ½Ð½Ñ Ð·Ð»ÑƒÑ‡ÑÐ½Ð½Ñ Ð· боку кліента Ð½Ð°Ð¿Ð°Ñ‚ÐºÐ°Ð½Ñ‹Ñ Ð½ÐµÐ²ÑÐ´Ð¾Ð¼Ñ‹Ñ ÑцÑжкі" + +#: ../gio/gdbusconnection.c:4146 ../gio/gdbusconnection.c:4489 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"Ðб'ект Ñа Ñцежкі \"%s\" не мае інтÑрфейÑу \"org.freedesktop.DBus.Properties\"" + +#: ../gio/gdbusconnection.c:4288 +#, c-format +msgid "No such property '%s'" +msgstr "ÐÑма такой улаÑціваÑці (\"%s\")" + +#: ../gio/gdbusconnection.c:4300 +#, c-format +msgid "Property '%s' is not readable" +msgstr "ÐÑма дазволу на прачытанне ўлаÑціваÑці \"%s\"" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not writable" +msgstr "ÐÑма дазволу на Ð·Ð°Ð¿Ñ–Ñ ÑƒÐ»Ð°ÑціваÑці \"%s\"" + +#: ../gio/gdbusconnection.c:4331 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"Памылка наÑÑ‚Ð°ÑžÐ»ÐµÐ½Ð½Ñ ÑžÐ»Ð°ÑціваÑці \"%s\": чакалі тып \"%s\", а маем \"%s\"" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6351 +#, c-format +msgid "No such interface '%s'" +msgstr "ÐÑма такога інтÑрфейÑу (\"%s\")" + +#: ../gio/gdbusconnection.c:4639 +msgid "No such interface" +msgstr "ÐÑма такога інтÑрфейÑу" + +#: ../gio/gdbusconnection.c:4857 ../gio/gdbusconnection.c:6857 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "Ðб'ект Ñа Ñцежкі \"%2$s\" не мае такога інтÑрфейÑу (\"%1$s\")" + +#: ../gio/gdbusconnection.c:4954 +#, c-format +msgid "No such method '%s'" +msgstr "ÐÑма такога метаду (\"%s\")" + +#: ../gio/gdbusconnection.c:4985 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "Тып Ð¿Ð°Ð²ÐµÐ´Ð°Ð¼Ð»ÐµÐ½Ð½Ñ \"%s\" не адпавÑдае чаканаму тыпу \"%s\"" + +#: ../gio/gdbusconnection.c:5183 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Ðб'ект ужо ÑкÑпартаваны Ð´Ð»Ñ Ñ–Ð½Ñ‚ÑрфейÑу \"%s\" на \"%s\"" + +#: ../gio/gdbusconnection.c:5381 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "Метад \"%s\" вÑрнуў значÑнне тыпу \"%s\", хоць чакалі \"%s\"" + +#: ../gio/gdbusconnection.c:6462 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "Метад \"%s\" на інтÑрфейÑе \"%s\" з подпіÑам \"%s\" не Ñ–Ñнуе" + +#: ../gio/gdbusconnection.c:6581 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "ПаддрÑва Ð´Ð»Ñ \"%s\" ужо ÑкÑпартавана" + +#: ../gio/gdbusmessage.c:1271 +msgid "type is INVALID" +msgstr "тып хібны (INVALID)" + +#: ../gio/gdbusmessage.c:1282 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Паведамленне METHOD_CALL: не Ñтае загалоўнай графы PATH або MEMBER" + +#: ../gio/gdbusmessage.c:1293 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Паведамленне METHOD_RETURN: не Ñтае загалоўнай графы REPLY_SERIAL" + +#: ../gio/gdbusmessage.c:1305 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Паведамленне ERROR: не Ñтае загалоўнай графы REPLY_SERIAL або ERROR_NAME" + +#: ../gio/gdbusmessage.c:1318 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Паведамленне SIGNAL: не Ñтае загалоўнай графы PATH, INTERFACE або MEMBER" + +#: ../gio/gdbusmessage.c:1326 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Паведамленне SIGNAL: Ð·Ð°Ð³Ð°Ð»Ð¾ÑžÐ½Ð°Ñ Ð³Ñ€Ð°Ñ„Ð° PATH выкарыÑтоўвае зарÑзерваванае " +"значÑнне /org/freedesktop/DBus/Local" + +#: ../gio/gdbusmessage.c:1334 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Паведамленне SIGNAL: Ð·Ð°Ð³Ð°Ð»Ð¾ÑžÐ½Ð°Ñ Ð³Ñ€Ð°Ñ„Ð° INTERFACE выкарыÑтоўвае зарÑзерваванае " +"значÑнне org.freedesktop.DBus.Local" + +#: ../gio/gdbusmessage.c:1383 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Хацелі прачытаць %lu байт, а атрымалі толькі %lu" +msgstr[1] "Хацелі прачытаць %lu байты, а атрымалі толькі %lu" +msgstr[2] "Хацелі прачытаць %lu байтаў, а атрымалі толькі %lu" + +#: ../gio/gdbusmessage.c:1398 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "ЗамеÑÑ‚ чаканага NULL-байта паÑÐ»Ñ Ð»Ð°Ð½Ñ†ÑƒÐ¶ÐºÐ° \"%s\" напаткалі байт %d" + +#: ../gio/gdbusmessage.c:1417 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"Чакалі правільны UTF-8 ланцужок, але напаткалі Ñ…Ñ–Ð±Ð½Ñ‹Ñ Ð±Ð°Ð¹Ñ‚Ñ‹ на зруху %d " +"(Ð´Ð°ÑžÐ¶Ñ‹Ð½Ñ Ð»Ð°Ð½Ñ†ÑƒÐ¶ÐºÐ°: %d). Да гÑтага моманту прачытаны наÑтупны бÑÑхібны UTF-8 " +"ланцужок: \"%s\"" + +#: ../gio/gdbusmessage.c:1619 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "ЗначÑнне \"%s\" не з'ÑўлÑецца Ñцежкай аб'екта D-Bus" + +#: ../gio/gdbusmessage.c:1643 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "ЗначÑнне \"%s\" не з'ÑўлÑецца подпіÑам D-Bus" + +#: ../gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Ðапаткалі маÑÑ–Ñž даўжынёй у %u байт. ÐÐ°Ð¹Ð±Ð¾Ð»ÑŒÑˆÐ°Ñ Ð´Ð°ÑžÐ¶Ñ‹Ð½Ñ Ñ€Ð¾ÑžÐ½Ð°Ñ 2<<26 байтам " +"(64 Мбайт)." +msgstr[1] "" +"Ðапаткалі маÑÑ–Ñž даўжынёй у %u байты. ÐÐ°Ð¹Ð±Ð¾Ð»ÑŒÑˆÐ°Ñ Ð´Ð°ÑžÐ¶Ñ‹Ð½Ñ Ñ€Ð¾ÑžÐ½Ð°Ñ 2<<26 байтам " +"(64 Мбайт)." +msgstr[2] "" +"Ðапаткалі маÑÑ–Ñž даўжынёй у %u байтаў. ÐÐ°Ð¹Ð±Ð¾Ð»ÑŒÑˆÐ°Ñ Ð´Ð°ÑžÐ¶Ñ‹Ð½Ñ Ñ€Ð¾ÑžÐ½Ð°Ñ 2<<26 байтам " +"(64 Мбайт)." + +#: ../gio/gdbusmessage.c:1851 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "ЗначÑнне \"%s\" варыÑнта не з'ÑўлÑецца подпіÑам D-Bus" + +#: ../gio/gdbusmessage.c:1875 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"Памылка дÑÑерыÑлізацыі аб'екта GVariant (тып: \"%s\") з Ñеткавага фармату D-" +"Bus" + +#: ../gio/gdbusmessage.c:2062 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"Хібнае азначÑнне байтавага ладу. ЗамеÑÑ‚ чаканых 0x6c ('l') або 0x42 ('B') " +"атрымалі 0x%02x" + +#: ../gio/gdbusmessage.c:2075 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"Ð¥Ñ–Ð±Ð½Ð°Ñ major-верÑÑ–Ñ Ð¿Ñ€Ð°Ñ‚Ð°ÐºÐ¾Ð»Ð°. ЗамеÑÑ‚ чаканай верÑÑ–Ñ– \"1\" атрымалі \"%d\"" + +#: ../gio/gdbusmessage.c:2131 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" +"Знойдзены загаловак подпіÑу Ñ– Ñам Ð¿Ð¾Ð´Ð¿Ñ–Ñ \"%s\", але цела Ð¿Ð°Ð²ÐµÐ´Ð°Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿ÑƒÑтое" + +#: ../gio/gdbusmessage.c:2145 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "ЗначÑнне \"%s\" не з'ÑўлÑецца подпіÑам D-Bus (Ð´Ð»Ñ Ñ†ÐµÐ»Ð° паведамленнÑ)" + +#: ../gio/gdbusmessage.c:2175 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Паведамленне не мае загалоўка з подпіÑам, але Ñго цела мае даўжыню %u байт" +msgstr[1] "" +"Паведамленне не мае загалоўка з подпіÑам, але Ñго цела мае даўжыню %u байты" +msgstr[2] "" +"Паведамленне не мае загалоўка з подпіÑам, але Ñго цела мае даўжыню %u байтаў" + +#: ../gio/gdbusmessage.c:2185 +msgid "Cannot deserialize message: " +msgstr "Ðе ўдалоÑÑ Ð´ÑÑерыÑлізаваць паведамленне: " + +#: ../gio/gdbusmessage.c:2506 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"Памылка ÑерыÑлізацыі аб'екта GVariant (тып: \"%s\") у Ñеткавы фармат D-Bus" + +#: ../gio/gdbusmessage.c:2643 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"Паведамленне мае %d файлавых дÑÑкрыптараў, але загаловак абвÑшчае аб %d " +"дÑÑкрыптарах" + +#: ../gio/gdbusmessage.c:2651 +msgid "Cannot serialize message: " +msgstr "Ðе ўдалоÑÑ ÑерыÑлізаваць паведамленне: " + +#: ../gio/gdbusmessage.c:2695 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "Цела Ð¿Ð°Ð²ÐµÐ´Ð°Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð°Ðµ Ð¿Ð¾Ð´Ð¿Ñ–Ñ \"%s\", але не Ñтае подпіÑу загалоўка" + +#: ../gio/gdbusmessage.c:2705 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "Цела Ð¿Ð°Ð²ÐµÐ´Ð°Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð°Ðµ Ð¿Ð¾Ð´Ð¿Ñ–Ñ \"%s\", але Ð¿Ð¾Ð´Ð¿Ñ–Ñ Ð·Ð°Ð³Ð°Ð»Ð¾ÑžÐºÐ° іншы: \"%s\"" + +#: ../gio/gdbusmessage.c:2721 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "Цела Ð¿Ð°Ð²ÐµÐ´Ð°Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿ÑƒÑтое, але Ð¿Ð¾Ð´Ð¿Ñ–Ñ Ð·Ð°Ð³Ð°Ð»Ð¾ÑžÐºÐ°: \"%s\"" + +#: ../gio/gdbusmessage.c:3271 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "Памылка вÑрнулаÑÑ Ð· целам тыпу \"%s\"" + +#: ../gio/gdbusmessage.c:3279 +msgid "Error return with empty body" +msgstr "Памылка вÑрнулаÑÑ Ð· пуÑтым целам" + +#: ../gio/gdbusprivate.c:2069 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Ðе ўдалоÑÑ Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ñ†ÑŒ профіль апаратуры: %s" + +#: ../gio/gdbusprivate.c:2114 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ /var/lib/dbus/machine-id або /etc/machine-id: " + +#: ../gio/gdbusproxy.c:1638 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Памылка запуÑку StartServiceByName Ð´Ð»Ñ %s: " + +#: ../gio/gdbusproxy.c:1661 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Ðечаканы адказ %d ад метаду StartServiceByName(\"%s\")" + +#: ../gio/gdbusproxy.c:2761 ../gio/gdbusproxy.c:2898 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ðемагчыма выклікаць метад. ПрокÑÑ– прызначаны Ð´Ð»Ñ ÑˆÑ‹Ñ€Ð¾ÐºÐ° вÑдомай назвы без " +"улаÑніка, Ñ– ён быў Ñтвораны з наÑтаўленым ÑцÑжком " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START." + +#: ../gio/gdbusserver.c:709 +msgid "Abstract name space not supported" +msgstr "ÐбÑÑ‚Ñ€Ð°ÐºÑ‚Ð½Ð°Ñ Ð¿Ñ€Ð°Ñтора назваў не падтрымліваецца" + +#: ../gio/gdbusserver.c:796 +msgid "Cannot specify nonce file when creating a server" +msgstr "Ðемагчыма вызначыць файл таÑмніцы (\"nonce\") пры ÑтварÑнні Ñервера" + +#: ../gio/gdbusserver.c:874 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Памылка запіÑу Ñž файл таÑмніцы (\"nonce\") \"%s\": %s" + +#: ../gio/gdbusserver.c:1043 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "Ланцужок \"%s\" не з'ÑўлÑецца Ñапраўдным D-Bus GUID" + +#: ../gio/gdbusserver.c:1083 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" +"Ðемагчыма пачаць Ñлухаць порт Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ñпарту \"%s\", Ñкі не падтрымліваецца" + +#: ../gio/gdbus-tool.c:92 +msgid "COMMAND" +msgstr "ЗÐГÐД" + +#: ../gio/gdbus-tool.c:97 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"Загады:\n" +" help Паказаць гÑтую даведку\n" +" introspect ВывучÑнне аддаленага аб'екта\n" +" monitor ÐдÑочванне аддаленага аб'екта\n" +" call Выклік метаду аддаленага аб'екта\n" +" emit Падаць Ñігнал\n" +"\n" +"Каб атрымаць даведку Ð´Ð»Ñ Ð¿Ñўнага загаду, выканайце \"%s ЗÐГÐД --help\".\n" + +#: ../gio/gdbus-tool.c:166 ../gio/gdbus-tool.c:222 ../gio/gdbus-tool.c:294 +#: ../gio/gdbus-tool.c:318 ../gio/gdbus-tool.c:701 ../gio/gdbus-tool.c:1022 +#: ../gio/gdbus-tool.c:1456 +#, c-format +msgid "Error: %s\n" +msgstr "Памылка: %s\n" + +#: ../gio/gdbus-tool.c:177 ../gio/gdbus-tool.c:235 ../gio/gdbus-tool.c:1472 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" +"Памылка разбору XML-файла з атрыманымі данымі: %s\n" +"\n" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to the system bus" +msgstr "Далучыцца да ÑÑ–ÑÑ‚Ñмнай магіÑтралі" + +#: ../gio/gdbus-tool.c:353 +msgid "Connect to the session bus" +msgstr "Далучыцца да ÑеанÑавай магіÑтралі" + +#: ../gio/gdbus-tool.c:354 +msgid "Connect to given D-Bus address" +msgstr "Далучыцца да пÑўнага D-Bus адраÑу" + +#: ../gio/gdbus-tool.c:364 +msgid "Connection Endpoint Options:" +msgstr "Опцыі канцавога вузла злучÑннÑ:" + +#: ../gio/gdbus-tool.c:365 +msgid "Options specifying the connection endpoint" +msgstr "Опцыі, ÑÐºÑ–Ñ Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ð°ÑŽÑ†ÑŒ канцавы вузел злучÑннÑ" + +#: ../gio/gdbus-tool.c:387 +#, c-format +msgid "No connection endpoint specified" +msgstr "Канцавы вузел злучÑÐ½Ð½Ñ Ð½Ðµ вызначаны" + +#: ../gio/gdbus-tool.c:397 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Вызначана некалькі канцавых вузлоў злучÑннÑ" + +#: ../gio/gdbus-tool.c:467 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "Увага: ÑÐ°Ð±Ñ€Ð°Ð½Ñ‹Ñ Ð´Ð°Ð½Ñ‹Ñ Ñведчаць, што інтÑÑ€Ñ„ÐµÐ¹Ñ \"%s\" не Ñ–Ñнуе\n" + +#: ../gio/gdbus-tool.c:476 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"Увага: ÑÐ°Ð±Ñ€Ð°Ð½Ñ‹Ñ Ð´Ð°Ð½Ñ‹Ñ Ñведчаць, што на інтÑрфейÑе \"%2$s\" нÑма метаду \"%1$s" +"\"\n" + +#: ../gio/gdbus-tool.c:538 +msgid "Optional destination for signal (unique name)" +msgstr "ÐеабавÑзковае меÑца прызначÑÐ½Ð½Ñ Ñігналу (ÑƒÐ½Ñ–ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð½Ð°Ð·Ð²Ð°)" + +#: ../gio/gdbus-tool.c:539 +msgid "Object path to emit signal on" +msgstr "Сцежка аб'екта Ð´Ð»Ñ Ð¿Ð°Ð´Ð°Ñ‡Ñ‹ Ñігналу" + +#: ../gio/gdbus-tool.c:540 +msgid "Signal and interface name" +msgstr "Сігнал Ñ– назва інтÑрфейÑу" + +#: ../gio/gdbus-tool.c:572 +msgid "Emit a signal." +msgstr "Падаць Ñігнал." + +#: ../gio/gdbus-tool.c:606 ../gio/gdbus-tool.c:832 ../gio/gdbus-tool.c:1562 +#: ../gio/gdbus-tool.c:1794 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Памылка злучÑннÑ: %s\n" + +#: ../gio/gdbus-tool.c:618 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "Памылка: Ñцежка аб'екта не вызначана.\n" + +#: ../gio/gdbus-tool.c:623 ../gio/gdbus-tool.c:893 ../gio/gdbus-tool.c:1620 +#: ../gio/gdbus-tool.c:1853 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Памылка: %s не з'ÑўлÑецца Ñцежкай аб'екта\n" + +#: ../gio/gdbus-tool.c:629 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "Памылка: Ñігнал не вызначаны.\n" + +#: ../gio/gdbus-tool.c:636 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "" +"Памылка: Ñігнал муÑіць мець форму поўнаÑцю вызначанай даменнай назвы " +"(FQDN).\n" + +#: ../gio/gdbus-tool.c:644 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Памылка: %s не з'ÑўлÑецца прыдатнай назвай інтÑрфейÑу\n" + +#: ../gio/gdbus-tool.c:650 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Памылка: %s не з'ÑўлÑецца прыдатнай назвай члена\n" + +#: ../gio/gdbus-tool.c:656 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Памылка: %s не з'ÑўлÑецца прыдатнай унікальнай назвай магіÑтралі.\n" + +#: ../gio/gdbus-tool.c:679 ../gio/gdbus-tool.c:992 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Памылка разбору параметра %d: %s\n" + +#: ../gio/gdbus-tool.c:708 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Памылка давÑршÑÐ½Ð½Ñ Ð·Ð»ÑƒÑ‡ÑннÑ: %s\n" + +#: ../gio/gdbus-tool.c:735 +msgid "Destination name to invoke method on" +msgstr "МÑÑ‚Ð°Ð²Ð°Ñ Ð½Ð°Ð·Ð²Ð°, Ð´Ð»Ñ Ñкой трÑба выклікаць метад" + +#: ../gio/gdbus-tool.c:736 +msgid "Object path to invoke method on" +msgstr "Сцежка аб'екта, Ð´Ð»Ñ Ñкой трÑба выклікаць метад" + +#: ../gio/gdbus-tool.c:737 +msgid "Method and interface name" +msgstr "Метад Ñ– назва інтÑрфейÑу" + +#: ../gio/gdbus-tool.c:738 +msgid "Timeout in seconds" +msgstr "ТÑрмін чаканнÑ, Ñекундаў" + +#: ../gio/gdbus-tool.c:777 +msgid "Invoke a method on a remote object." +msgstr "Выклікаць метад Ð´Ð»Ñ Ð°Ð´Ð´Ð°Ð»ÐµÐ½Ð°Ð³Ð° аб'екта." + +#: ../gio/gdbus-tool.c:852 ../gio/gdbus-tool.c:1581 ../gio/gdbus-tool.c:1813 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "Памылка: мÑта не вызначана\n" + +#: ../gio/gdbus-tool.c:873 ../gio/gdbus-tool.c:1600 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "Памылка: Ñцежка аб'екта не вызначана\n" + +#: ../gio/gdbus-tool.c:908 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "Памылка: назва метаду не вызначана\n" + +#: ../gio/gdbus-tool.c:919 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "Памылка: Ñ…Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° метаду \"%s\"\n" + +#: ../gio/gdbus-tool.c:984 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Памылка разбору параметра %d тыпу \"%s\": %s\n" + +#: ../gio/gdbus-tool.c:1419 +msgid "Destination name to introspect" +msgstr "МÑÑ‚Ð°Ð²Ð°Ñ Ð½Ð°Ð·Ð²Ð° Ð´Ð»Ñ Ð²Ñ‹Ð²ÑƒÑ‡ÑннÑ" + +#: ../gio/gdbus-tool.c:1420 +msgid "Object path to introspect" +msgstr "Сцежка аб'екта Ð´Ð»Ñ Ð²Ñ‹Ð²ÑƒÑ‡ÑннÑ" + +#: ../gio/gdbus-tool.c:1421 +msgid "Print XML" +msgstr "ВывеÑці XML" + +#: ../gio/gdbus-tool.c:1422 +msgid "Introspect children" +msgstr "ДаÑледаваць дзÑцей" + +#: ../gio/gdbus-tool.c:1423 +msgid "Only print properties" +msgstr "Толькі вывеÑці ўлаÑціваÑці" + +#: ../gio/gdbus-tool.c:1514 +msgid "Introspect a remote object." +msgstr "ДаÑледаваць аддалены аб'ект." + +#: ../gio/gdbus-tool.c:1712 +msgid "Destination name to monitor" +msgstr "МÑÑ‚Ð°Ð²Ð°Ñ Ð½Ð°Ð·Ð²Ð° Ð´Ð»Ñ Ð°Ð´ÑочваннÑ" + +#: ../gio/gdbus-tool.c:1713 +msgid "Object path to monitor" +msgstr "Сцежка аб'екта Ð´Ð»Ñ Ð°Ð´ÑочваннÑ" + +#: ../gio/gdbus-tool.c:1746 +msgid "Monitor a remote object." +msgstr "ÐдÑочваць аддалены аб'ект." + +#: ../gio/gdesktopappinfo.c:660 ../gio/gdesktopappinfo.c:3793 +#: ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Без назвы" + +#: ../gio/gdesktopappinfo.c:1074 +msgid "Desktop file didn't specify Exec field" +msgstr "Ðртыкульны файл не мае графы Exec" + +#: ../gio/gdesktopappinfo.c:1359 +msgid "Unable to find terminal required for application" +msgstr "Ðе ўдалоÑÑ Ð·Ð½Ð°Ð¹Ñці Ñ‚Ñрмінал, патрÑбны Ð´Ð»Ñ Ð¿Ñ€Ð°Ð³Ñ€Ð°Ð¼Ñ‹" + +#: ../gio/gdesktopappinfo.c:1772 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" +"Ðе ўдалоÑÑ Ñтварыць папку %s Ð´Ð»Ñ ÐºÐ°Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ‹Ñ– праграм карыÑтальніка: %s" + +#: ../gio/gdesktopappinfo.c:1776 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "Ðе ўдалоÑÑ Ñтварыць папку %s Ð´Ð»Ñ MIME-канфігурацыі карыÑтальніка: %s" + +#: ../gio/gdesktopappinfo.c:2016 ../gio/gdesktopappinfo.c:2040 +msgid "Application information lacks an identifier" +msgstr "Інфармацыі аб праграме не Ñтае ідÑнтыфікатара" + +#: ../gio/gdesktopappinfo.c:2272 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Ðе ўдалоÑÑ Ñтварыць артыкульны файл %s" + +#: ../gio/gdesktopappinfo.c:2396 +#, c-format +msgid "Custom definition for %s" +msgstr "УлаÑнае азначÑнне Ð´Ð»Ñ %s" + +#: ../gio/gdrive.c:394 +msgid "drive doesn't implement eject" +msgstr "прывод не падтрымлівае аперацыі eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:472 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "прывод не падтрымлівае аперацыі eject або eject_with_operation" + +#: ../gio/gdrive.c:548 +msgid "drive doesn't implement polling for media" +msgstr "прывод не падтрымлівае функцыі Ð°Ð¿Ñ‹Ñ‚Ð²Ð°Ð½Ð½Ñ Ð½Ð°ÐºÐ¾Ð½Ñ‚ наÑўнаÑці ноÑьбіта" + +#: ../gio/gdrive.c:753 +msgid "drive doesn't implement start" +msgstr "прывод не падтрымлівае аперацыі start" + +#: ../gio/gdrive.c:855 +msgid "drive doesn't implement stop" +msgstr "прывод не падтрымлівае аперацыі stop" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "ÐдÑутнічае падтрымка TLS" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "Ðе ўдалоÑÑ Ð°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ñ†ÑŒ верÑÑ–ÑŽ %d ÐºÐ°Ð´Ð°Ð²Ð°Ð½Ð½Ñ GEmblem" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ ÐºÐ¾Ð»ÑŒÐºÐ°Ñць Ñкладнікаў (%d) у кадаванні GEmblem" + +#: ../gio/gemblemedicon.c:364 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "Ðе ўдалоÑÑ Ð°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ñ†ÑŒ верÑÑ–ÑŽ %d ÐºÐ°Ð´Ð°Ð²Ð°Ð½Ð½Ñ GEmblemedIcon" + +#: ../gio/gemblemedicon.c:374 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ ÐºÐ¾Ð»ÑŒÐºÐ°Ñць Ñкладнікаў (%d) у кадаванні GEmblemedIcon" + +#: ../gio/gemblemedicon.c:397 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Чакалі GEmblem Ð´Ð»Ñ GEmblemedIcon" + +#: ../gio/gfile.c:965 ../gio/gfile.c:1204 ../gio/gfile.c:1343 +#: ../gio/gfile.c:1583 ../gio/gfile.c:1638 ../gio/gfile.c:1696 +#: ../gio/gfile.c:1780 ../gio/gfile.c:1837 ../gio/gfile.c:1901 +#: ../gio/gfile.c:1956 ../gio/gfile.c:3586 ../gio/gfile.c:3641 +#: ../gio/gfile.c:3849 ../gio/gfile.c:3891 ../gio/gfile.c:4357 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7682 ../gio/gfile.c:7772 ../gio/gfile.c:7856 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "ДзеÑнне не падтрымліваецца" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1467 ../gio/glocalfile.c:1102 ../gio/glocalfile.c:1113 +#: ../gio/glocalfile.c:1126 +msgid "Containing mount does not exist" +msgstr "Прымацаваны дыÑк, Ñкі змÑшчае файл, не Ñ–Ñнуе" + +#: ../gio/gfile.c:2522 ../gio/glocalfile.c:2334 +msgid "Can't copy over directory" +msgstr "Ðельга Ñкапіраваць на меÑца каталога" + +#: ../gio/gfile.c:2582 +msgid "Can't copy directory over directory" +msgstr "Ðельга Ñкапіраваць каталог на меÑца іншага каталога" + +#: ../gio/gfile.c:2590 ../gio/glocalfile.c:2343 +msgid "Target file exists" +msgstr "МÑтавы файл Ñ–Ñнуе" + +#: ../gio/gfile.c:2609 +msgid "Can't recursively copy directory" +msgstr "Ðе ўдалоÑÑ Ñ€ÑкурÑіўна Ñкапіраваць каталог" + +#: ../gio/gfile.c:2891 +msgid "Splice not supported" +msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ‹Ñ splice не падтрымліваецца" + +#: ../gio/gfile.c:2895 +#, c-format +msgid "Error splicing file: %s" +msgstr "Памылка ÑžÐ¶Ñ‹Ð²Ð°Ð½Ð½Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ‹Ñ– splice Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð°: %s" + +#: ../gio/gfile.c:3026 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"Капіраванне (reflink/clone) з аднаго прымацаванага дыÑка на іншы не " +"падтрымліваецца" + +#: ../gio/gfile.c:3030 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Капіраванне (reflink/clone) не падтрымліваецца або памылковае" + +#: ../gio/gfile.c:3035 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "Капіраванне (reflink/clone) не падтрымліваецца або Ñхібіла" + +#: ../gio/gfile.c:3098 +msgid "Can't copy special file" +msgstr "Ðе ўдалоÑÑ Ñкапіраваць аÑаблівы файл" + +#: ../gio/gfile.c:3839 +msgid "Invalid symlink value given" +msgstr "Хібнае значÑнне Ð´Ð»Ñ Ñімвальнай ÑпаÑылкі" + +#: ../gio/gfile.c:4001 +msgid "Trash not supported" +msgstr "Функцыі Ñметніцы не падтрымліваюцца" + +#: ../gio/gfile.c:4114 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Ðазвы файлаў не павінны змÑшчаць \"%c\"" + +#: ../gio/gfile.c:6531 ../gio/gvolume.c:365 +msgid "volume doesn't implement mount" +msgstr "дыÑкавы том не падтрымлівае Ð¼Ð°Ñ†Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð° файлавай ÑÑ–ÑÑ‚Ñмы" + +#: ../gio/gfile.c:6640 +msgid "No application is registered as handling this file" +msgstr "ÐÑма праграм, зарÑгіÑтраваных Ð´Ð»Ñ Ð¿Ñ€Ð°Ñ†Ñ‹ з гÑтым файлам" + +#: ../gio/gfileenumerator.c:213 +msgid "Enumerator is closed" +msgstr "Ðб'ект пераліку закрыты" + +#: ../gio/gfileenumerator.c:220 ../gio/gfileenumerator.c:279 +#: ../gio/gfileenumerator.c:379 ../gio/gfileenumerator.c:479 +msgid "File enumerator has outstanding operation" +msgstr "Ðб'ект пераліку файлаў мае нÑÑкончаную аперацыю" + +#: ../gio/gfileenumerator.c:370 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "Ðб'ект пераліку файлаў ужо закрыты" + +#: ../gio/gfileicon.c:237 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "Ðе ўдалоÑÑ Ð°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ñ†ÑŒ верÑÑ–ÑŽ %d ÐºÐ°Ð´Ð°Ð²Ð°Ð½Ð½Ñ GFileIcon" + +#: ../gio/gfileicon.c:247 +msgid "Malformed input data for GFileIcon" +msgstr "Ð¥Ñ–Ð±Ð½Ñ‹Ñ ÑžÐ²Ð¾Ð´Ð½Ñ‹Ñ Ð´Ð°Ð½Ñ‹Ñ Ð´Ð»Ñ GFileIcon" + +#: ../gio/gfileinputstream.c:151 ../gio/gfileinputstream.c:397 +#: ../gio/gfileiostream.c:169 ../gio/gfileoutputstream.c:166 +#: ../gio/gfileoutputstream.c:500 +msgid "Stream doesn't support query_info" +msgstr "Струмень не падтрымлівае функцыі query_info" + +#: ../gio/gfileinputstream.c:328 ../gio/gfileiostream.c:382 +#: ../gio/gfileoutputstream.c:374 +msgid "Seek not supported on stream" +msgstr "Струмень не падтрымлівае пракручваннÑ" + +#: ../gio/gfileinputstream.c:372 +msgid "Truncate not allowed on input stream" +msgstr "Ð”Ð»Ñ ÑžÐ²Ð°Ñ…Ð¾Ð´Ð½Ð°Ð³Ð° ÑÑ‚Ñ€ÑƒÐ¼ÐµÐ½Ñ Ð·Ð°Ð±Ð°Ñ€Ð¾Ð½ÐµÐ½Ð° абразанне" + +#: ../gio/gfileiostream.c:458 ../gio/gfileoutputstream.c:450 +msgid "Truncate not supported on stream" +msgstr "Струмень не падтрымлівае абразаннÑ" + +#: ../gio/gicon.c:297 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ ÐºÐ¾Ð»ÑŒÐºÐ°Ñць Ñкладнікаў (%d)" + +#: ../gio/gicon.c:317 +#, c-format +msgid "No type for class name %s" +msgstr "Ðазва клаÑа %s не мае тыпу" + +#: ../gio/gicon.c:327 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Тып %s не мае інтÑрфейÑу GIcon" + +#: ../gio/gicon.c:338 +#, c-format +msgid "Type %s is not classed" +msgstr "Тып %s не мае клаÑаў" + +#: ../gio/gicon.c:352 +#, c-format +msgid "Malformed version number: %s" +msgstr "Хібны нумар верÑÑ–Ñ–: %s" + +#: ../gio/gicon.c:366 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Тып %s не мае функцыі from_tokens() Ð´Ð»Ñ Ñ–Ð½Ñ‚ÑрфейÑу GIcon" + +#: ../gio/gicon.c:468 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "Ðе ўдалоÑÑ Ð°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ñ†ÑŒ гÑтую верÑÑ–ÑŽ ÐºÐ°Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐºÐ¾Ñž" + +#: ../gio/ginetaddressmask.c:183 +msgid "No address specified" +msgstr "ÐÐ´Ñ€Ð°Ñ Ð½Ðµ вызначаны" + +#: ../gio/ginetaddressmask.c:191 +#, c-format +msgid "Length %u is too long for address" +msgstr "Ð”Ð°ÑžÐ¶Ñ‹Ð½Ñ %u надта вÑÐ»Ñ–ÐºÐ°Ñ Ð´Ð»Ñ Ð°Ð´Ñ€Ð°Ñу" + +#: ../gio/ginetaddressmask.c:224 +msgid "Address has bits set beyond prefix length" +msgstr "ГÑты Ð°Ð´Ñ€Ð°Ñ Ð¼Ð°Ðµ выÑÑ‚Ð°ÑžÐ»ÐµÐ½Ñ‹Ñ Ð±Ñ–Ñ‚Ñ‹, ÑÐºÑ–Ñ Ð½Ðµ ўваходзÑць у Ñеткавы прÑфікÑ" + +#: ../gio/ginetaddressmask.c:301 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð°Ð±Ñ€Ð°Ñ†ÑŒ \"%s\" Ñк Ñеткавую маÑку IP-адраÑу" + +#: ../gio/ginetsocketaddress.c:197 ../gio/ginetsocketaddress.c:214 +#: ../gio/gunixsocketaddress.c:211 +msgid "Not enough space for socket address" +msgstr "Ðе Ñтае вольнай праÑторы Ð´Ð»Ñ Ð°Ð´Ñ€Ð°Ñу Ñокета" + +#: ../gio/ginetsocketaddress.c:229 +msgid "Unsupported socket address" +msgstr "ÐÐ´Ñ€Ð°Ñ Ñокета, Ñкі не падтрымліваецца" + +#: ../gio/ginputstream.c:183 +msgid "Input stream doesn't implement read" +msgstr "Уваходны Ñтрумень не мае функцыі чытаннÑ" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1022 ../gio/giostream.c:290 +#: ../gio/goutputstream.c:1333 +msgid "Stream has outstanding operation" +msgstr "Струмень мае нÑÑкончаную аперацыю" + +#: ../gio/glib-compile-resources.c:145 ../gio/glib-compile-schemas.c:1459 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Элемент <%s> унутры <%s> забаронены" + +#: ../gio/glib-compile-resources.c:149 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Элемент <%s> забаронены Ð´Ð»Ñ Ð½Ð°Ð¹Ð²Ñ‹ÑˆÑйшага ўзроўню" + +#: ../gio/glib-compile-resources.c:239 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Файл %s з'ÑўлÑецца Ñž Ñ€ÑÑурÑе некалькі разоў" + +#: ../gio/glib-compile-resources.c:252 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÑˆÑƒÐºÐ°Ñ†ÑŒ \"%s\" ва ÑžÑÑ–Ñ… выточных каталогах" + +#: ../gio/glib-compile-resources.c:263 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÑˆÑƒÐºÐ°Ñ†ÑŒ \"%s\" у бÑгучым каталогу" + +#: ../gio/glib-compile-resources.c:291 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "ÐевÑÐ´Ð¾Ð¼Ð°Ñ Ð¾Ð¿Ñ†Ñ‹Ñ Ð°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ð½Ð½Ñ \"%s\"" + +#: ../gio/glib-compile-resources.c:310 ../gio/glib-compile-resources.c:370 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "Ðе ўдалоÑÑ Ñтварыць чаÑовы файл: %s" + +#: ../gio/glib-compile-resources.c:340 +#, c-format +msgid "" +"Error processing input file with xmllint:\n" +"%s" +msgstr "" +"Памылка Ð°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ð½Ð½Ñ ÑžÐ²Ð°Ñ…Ð¾Ð´Ð½Ð°Ð³Ð° файла з дапамогай xmllint:\n" +"%s" + +#: ../gio/glib-compile-resources.c:396 +#, c-format +msgid "" +"Error processing input file with to-pixdata:\n" +"%s" +msgstr "" +"Памылка Ð°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ð½Ð½Ñ ÑžÐ²Ð°Ñ…Ð¾Ð´Ð½Ð°Ð³Ð° файла з дапамогай to-pixdata:\n" +"%s" + +#: ../gio/glib-compile-resources.c:410 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ файл %s: %s" + +#: ../gio/glib-compile-resources.c:430 +#, c-format +msgid "Error compressing file %s" +msgstr "Памылка ÑціÑÐºÐ°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð°: %s" + +#: ../gio/glib-compile-resources.c:494 ../gio/glib-compile-schemas.c:1571 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "Ñ‚ÑкÑÑ‚ не павінен быць унутры <%s>" + +#: ../gio/glib-compile-resources.c:619 +msgid "name of the output file" +msgstr "назва файла вываду" + +#: ../gio/glib-compile-resources.c:619 ../gio/glib-compile-resources.c:650 +#: ../gio/gresource-tool.c:482 ../gio/gresource-tool.c:548 +msgid "FILE" +msgstr "ФÐЙЛ" + +#: ../gio/glib-compile-resources.c:620 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "Каталог, файлы з Ñкога трÑба прачытаць (прадвызначана: бÑгучы каталог)" + +#: ../gio/glib-compile-resources.c:620 ../gio/glib-compile-schemas.c:1999 +#: ../gio/glib-compile-schemas.c:2028 +msgid "DIRECTORY" +msgstr "КÐТÐЛОГ" + +#: ../gio/glib-compile-resources.c:621 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Згенераваць вывад у фармаце, абраным Ð´Ð»Ñ Ð¿Ð°ÑˆÑ‹Ñ€ÑÐ½Ð½Ñ Ð¼Ñтавага файла" + +#: ../gio/glib-compile-resources.c:622 +msgid "Generate source header" +msgstr "Згенераваць загаловак крыніцы" + +#: ../gio/glib-compile-resources.c:623 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "Згенераваць выточны код Ð´Ð»Ñ ÑпаÑылкі на файл Ñ€ÑÑурÑа Ñž вашым кодзе" + +#: ../gio/glib-compile-resources.c:624 +msgid "Generate dependency list" +msgstr "Згенераваць ÑÐ¿Ñ–Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð°ÑцÑÑž" + +#: ../gio/glib-compile-resources.c:625 +msgid "Don't automatically create and register resource" +msgstr "Ðе Ñтвараць Ñ– не Ñ€ÑгіÑтраваць Ñ€ÑÑурÑÑ‹ аўтаматычна" + +#: ../gio/glib-compile-resources.c:626 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "Ðе ÑкÑпартаваць функцыі; аб'Ñвіць Ñ–Ñ… Ñк G_GNUC_INTERNAL" + +#: ../gio/glib-compile-resources.c:627 +msgid "C identifier name used for the generated source code" +msgstr "" +"Ðазва ідÑнтыфікатара \"С\", ÑÐºÐ°Ñ Ð±ÑƒÐ´Ð·Ðµ ўжывацца Ñž згенераваным выточным кодзе" + +#: ../gio/glib-compile-resources.c:653 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"СкампілÑваць Ñпецыфікацыю Ñ€ÑÑурÑа Ñž файл Ñ€ÑÑурÑа.\n" +"Файлы Ñпецыфікацыі Ñ€ÑÑурÑа муÑÑць мець пашырÑнне .gresource.xml,\n" +"а файл Ñ€ÑÑурÑа мае пашырÑнне .gresource." + +#: ../gio/glib-compile-resources.c:669 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "ТрÑба падаць дакладна адну назву файла\n" + +#: ../gio/glib-compile-schemas.c:778 +msgid "empty names are not permitted" +msgstr "пуÑÑ‚Ñ‹Ñ Ð½Ð°Ð·Ð²Ñ‹ забаронены" + +#: ../gio/glib-compile-schemas.c:788 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "Ñ…Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° \"%s\": назвы муÑÑць пачынацца з літары ніжнÑга Ñ€ÑгіÑтра" + +#: ../gio/glib-compile-schemas.c:800 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"Ñ…Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° \"%s\": хібны знак \"%c\"; дазволены толькі літары ніжнÑга " +"Ñ€ÑгіÑтра, лічбы Ñ– злучок." + +#: ../gio/glib-compile-schemas.c:809 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "Ñ…Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° \"%s\": два паÑлÑÐ´Ð¾ÑžÐ½Ñ‹Ñ Ð·Ð»ÑƒÑ‡ÐºÑ– забаронены." + +#: ../gio/glib-compile-schemas.c:818 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "Ñ…Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° \"%s\": апошні знак не можа быць злучком." + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "Ñ…Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° \"%s\": макÑÑ–Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð°ÑžÐ¶Ñ‹Ð½Ñ = 1024" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr " ужо вызначана" + +#: ../gio/glib-compile-schemas.c:921 +msgid "cannot add keys to a 'list-of' schema" +msgstr "не ўдалоÑÑ Ð´Ð°Ð´Ð°Ñ†ÑŒ ключы да Ñхемы \"list-of\"" + +#: ../gio/glib-compile-schemas.c:932 +#, c-format +msgid " already specified" +msgstr " ужо вызначана" + +#: ../gio/glib-compile-schemas.c:950 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" заÑланÑе з ; каб змÑніць " +"значÑнне, ужыйце " + +#: ../gio/glib-compile-schemas.c:961 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"дакладна адзін з атрыбутаў \"type\" (тып), \"enum\" (пералік) або \"flags" +"\" (ÑцÑжкі) муÑіць быць вызначаны Ð´Ð»Ñ " + +#: ../gio/glib-compile-schemas.c:980 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (пакуль) не зызначана." + +#: ../gio/glib-compile-schemas.c:995 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "Хібны ланцужок тыпу GVariant: \"%s\"" + +#: ../gio/glib-compile-schemas.c:1025 +msgid " given but schema isn't extending anything" +msgstr "ужыта , але Ñхема нічога не заÑланÑе" + +#: ../gio/glib-compile-schemas.c:1038 +#, c-format +msgid "no to override" +msgstr "нÑма Ð´Ð»Ñ Ð·Ð°ÑланеннÑ" + +#: ../gio/glib-compile-schemas.c:1046 +#, c-format +msgid " already specified" +msgstr " ужо вызначана" + +#: ../gio/glib-compile-schemas.c:1117 +#, c-format +msgid " already specified" +msgstr " ужо вызначана" + +#: ../gio/glib-compile-schemas.c:1129 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " заÑланÑе ÑÑˆÑ‡Ñ Ð°Ð´Ñутную Ñхему \"%s\"" + +#: ../gio/glib-compile-schemas.c:1145 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " з'ÑўлÑецца ÑпіÑам Ð´Ð»Ñ ÑÑˆÑ‡Ñ Ð°Ð´Ñутнай Ñхемы \"%s\"" + +#: ../gio/glib-compile-schemas.c:1153 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "Ðе можа быць ÑпіÑам Ñхемы Ñа Ñцежкай" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "Ðе можа заÑланÑць Ñхему Ñа Ñцежкай" + +#: ../gio/glib-compile-schemas.c:1173 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" з'ÑўлÑецца ÑпіÑам, Ñкі заÑланÑе нÑ-ÑÐ¿Ñ–Ñ " + +#: ../gio/glib-compile-schemas.c:1183 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" заÑланÑе , але " +"\"%s\" не заÑланÑе \"%s\"" + +#: ../gio/glib-compile-schemas.c:1200 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "Ñцежка муÑіць пачынацца Ñ– канчацца знакам ÑкоÑу" + +#: ../gio/glib-compile-schemas.c:1207 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "Ñцежка ÑпіÑа муÑіць канчацца \":/\"" + +#: ../gio/glib-compile-schemas.c:1239 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ужо вызначана" + +#: ../gio/glib-compile-schemas.c:1463 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Элемент <%s> забаронены Ð´Ð»Ñ Ð½Ð°Ð¹Ð²Ñ‹ÑˆÑйшага ўзроўню" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1757 ../gio/glib-compile-schemas.c:1828 +#: ../gio/glib-compile-schemas.c:1904 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "выбрана Ð¾Ð¿Ñ†Ñ‹Ñ --strict; выходзім.\n" + +#: ../gio/glib-compile-schemas.c:1765 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "УвеÑÑŒ гÑты файл быў праігнараваны.\n" + +#: ../gio/glib-compile-schemas.c:1824 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Ігнараванне гÑтага файла.\n" + +#: ../gio/glib-compile-schemas.c:1864 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"У Ñхеме \"%2$s\" нÑма ключа \"%1$s\", вызначанага Ñž файле заÑлоны \"%3$s\"" + +#: ../gio/glib-compile-schemas.c:1870 ../gio/glib-compile-schemas.c:1928 +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; заÑлона гÑтага ключа праігнараванаÑ.\n" + +#: ../gio/glib-compile-schemas.c:1874 ../gio/glib-compile-schemas.c:1932 +#: ../gio/glib-compile-schemas.c:1960 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " , а такÑама вызначана Ð¾Ð¿Ñ†Ñ‹Ñ --strict; выходзім.\n" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"памылка разбору ключа \"%s\" Ñхемы \"%s\", вызначанага Ñž файле заÑлоны \"%s" +"\": %s." + +#: ../gio/glib-compile-schemas.c:1900 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "ЗаÑлона Ð´Ð»Ñ Ð³Ñтага ключа праігнараванаÑ.\n" + +#: ../gio/glib-compile-schemas.c:1918 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"заÑлона Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° \"%s\" Ñхемы \"%s\" у файле заÑлоны \"%s\" не Ñž дыÑпазоне, " +"вызначаным Ñхемай" + +#: ../gio/glib-compile-schemas.c:1946 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"заÑлона Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° \"%s\" Ñхемы \"%s\" у файле заÑлоны \"%s\" не Ñž ÑпіÑе " +"магчымага выбару" + +#: ../gio/glib-compile-schemas.c:1999 +msgid "where to store the gschemas.compiled file" +msgstr "дзе захоўваць файл gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2000 +msgid "Abort on any errors in schemas" +msgstr "Перапыніць працу пры знаходжанні памылак у Ñхемах" + +#: ../gio/glib-compile-schemas.c:2001 +msgid "Do not write the gschema.compiled file" +msgstr "Ðе запіÑваць файл gschema.compiled" + +#: ../gio/glib-compile-schemas.c:2002 +msgid "Do not enforce key name restrictions" +msgstr "Ðе пільнавацца абмежаваннÑÑž на назвы ключоў" + +#: ../gio/glib-compile-schemas.c:2031 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"СкампілÑваць файлы Ñхем GSettings у кÑш.\n" +"Файлы Ñхем муÑÑць мець пашырÑнне .gschema.xml,\n" +"а файл кÑшу называецца gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:2047 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "ТрÑба падаць дакладна адну назву каталога\n" + +#: ../gio/glib-compile-schemas.c:2086 +#, c-format +msgid "No schema files found: " +msgstr "Файлы Ñхем не знойдзены: " + +#: ../gio/glib-compile-schemas.c:2089 +#, c-format +msgid "doing nothing.\n" +msgstr "нічога не ўчынена.\n" + +#: ../gio/glib-compile-schemas.c:2092 +#, c-format +msgid "removed existing output file.\n" +msgstr "наÑўны выхадны файл выдалены.\n" + +#: ../gio/glocaldirectorymonitor.c:252 +msgid "Unable to find default local directory monitor type" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÑˆÑƒÐºÐ°Ñ†ÑŒ прадвызначаны тып назіральніка за каталогам" + +#: ../gio/glocalfile.c:603 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° файла %s" + +#: ../gio/glocalfile.c:980 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Памылка Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ð½Ð½Ñ Ð·Ð²ÐµÑтак аб файлавай ÑÑ–ÑÑ‚Ñме: %s" + +#: ../gio/glocalfile.c:1148 +msgid "Can't rename root directory" +msgstr "Ðемагчыма пераназваць каранёвы каталог" + +#: ../gio/glocalfile.c:1168 ../gio/glocalfile.c:1194 +#, c-format +msgid "Error renaming file: %s" +msgstr "Памылка Ð¿ÐµÑ€Ð°Ð½Ð°Ð·Ð²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð°: %s" + +#: ../gio/glocalfile.c:1177 +msgid "Can't rename file, filename already exists" +msgstr "Ðе ўдалоÑÑ Ð¿ÐµÑ€Ð°Ð½Ð°Ð·Ð²Ð°Ñ†ÑŒ файл, бо файл з такой назвай ужо Ñ–Ñнуе" + +#: ../gio/glocalfile.c:1190 ../gio/glocalfile.c:2207 ../gio/glocalfile.c:2236 +#: ../gio/glocalfile.c:2396 ../gio/glocalfileoutputstream.c:553 +msgid "Invalid filename" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° файла" + +#: ../gio/glocalfile.c:1357 ../gio/glocalfile.c:1381 +msgid "Can't open directory" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÐºÑ€Ñ‹Ñ†ÑŒ каталог" + +#: ../gio/glocalfile.c:1365 +#, c-format +msgid "Error opening file: %s" +msgstr "Памылка Ð°Ð´ÐºÑ€Ñ‹Ñ†Ñ†Ñ Ñ„Ð°Ð¹Ð»Ð°: %s" + +#: ../gio/glocalfile.c:1506 +#, c-format +msgid "Error removing file: %s" +msgstr "Памылка Ð²Ñ‹Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð°: %s" + +#: ../gio/glocalfile.c:1886 +#, c-format +msgid "Error trashing file: %s" +msgstr "Памылка пераноÑу файла Ñž Ñметніцу: %s" + +#: ../gio/glocalfile.c:1909 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Ðе ўдалоÑÑ Ñтварыць каталог Ð´Ð»Ñ ÑÐ¼ÐµÑ†Ñ†Ñ \"%s\": %s" + +#: ../gio/glocalfile.c:1930 +msgid "Unable to find toplevel directory for trash" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÑˆÑƒÐºÐ°Ñ†ÑŒ каталог верхнÑга ўзроўню Ð´Ð»Ñ Ñметніцы" + +#: ../gio/glocalfile.c:2009 ../gio/glocalfile.c:2029 +msgid "Unable to find or create trash directory" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÑˆÑƒÐºÐ°Ñ†ÑŒ ці Ñтварыць каталог Ð´Ð»Ñ ÑмеццÑ" + +#: ../gio/glocalfile.c:2063 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Ðе ўдалоÑÑ Ñтварыць файл Ñа звеÑткамі аб Ñмецці: %s" + +#: ../gio/glocalfile.c:2092 ../gio/glocalfile.c:2097 ../gio/glocalfile.c:2177 +#: ../gio/glocalfile.c:2184 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Ðе ўдалоÑÑ Ð¿ÐµÑ€Ð°Ð½ÐµÑці файл у Ñметніцу: %s" + +#: ../gio/glocalfile.c:2185 ../glib/gregex.c:280 +msgid "internal error" +msgstr "ÑƒÐ½ÑƒÑ‚Ñ€Ð°Ð½Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ°" + +#: ../gio/glocalfile.c:2211 +#, c-format +msgid "Error creating directory: %s" +msgstr "Памылка ÑтварÑÐ½Ð½Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð°: %s" + +#: ../gio/glocalfile.c:2240 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Ð¤Ð°Ð¹Ð»Ð°Ð²Ð°Ñ ÑÑ–ÑÑ‚Ñма не падтрымлівае Ñімвальных ÑпаÑылак" + +#: ../gio/glocalfile.c:2244 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Памылка ÑтварÑÐ½Ð½Ñ Ñімвальнай ÑпаÑылкі: %s" + +#: ../gio/glocalfile.c:2306 ../gio/glocalfile.c:2400 +#, c-format +msgid "Error moving file: %s" +msgstr "Памылка перамÑшчÑÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð°: %s" + +#: ../gio/glocalfile.c:2329 +msgid "Can't move directory over directory" +msgstr "Ðемагчыма перамÑÑціць каталог на меÑца іншага каталога" + +#: ../gio/glocalfile.c:2356 ../gio/glocalfileoutputstream.c:929 +#: ../gio/glocalfileoutputstream.c:943 ../gio/glocalfileoutputstream.c:958 +#: ../gio/glocalfileoutputstream.c:974 ../gio/glocalfileoutputstream.c:988 +msgid "Backup file creation failed" +msgstr "Ðе ўдалоÑÑ Ñтварыць запаÑную копію файла" + +#: ../gio/glocalfile.c:2375 +#, c-format +msgid "Error removing target file: %s" +msgstr "Памылка Ð²Ñ‹Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¼Ñтавага файла: %s" + +#: ../gio/glocalfile.c:2389 +msgid "Move between mounts not supported" +msgstr "ПерамÑшчÑнне з аднаго прымацаванага дыÑка на іншы не падтрымліваецца" + +#: ../gio/glocalfile.c:2572 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ðе ўдалоÑÑ Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ñ‹Ñ†ÑŒ узровень выкарыÑÑ‚Ð°Ð½Ð½Ñ Ð´Ñ‹Ñка Ð´Ð»Ñ %s: %s" + +#: ../gio/glocalfileinfo.c:722 +msgid "Attribute value must be non-NULL" +msgstr "Ðтрыбут не можа мець NULL-значÑнне" + +#: ../gio/glocalfileinfo.c:729 +msgid "Invalid attribute type (string expected)" +msgstr "Хібны тып атрыбута (чакаўÑÑ Ð»Ð°Ð½Ñ†ÑƒÐ¶Ð¾Ðº знакаў)" + +#: ../gio/glocalfileinfo.c:736 +msgid "Invalid extended attribute name" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° пашыранага атрыбута" + +#: ../gio/glocalfileinfo.c:776 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Памылка наÑÑ‚Ð°ÑžÐ»ÐµÐ½Ð½Ñ Ð¿Ð°ÑˆÑ‹Ñ€Ð°Ð½Ð°Ð³Ð° атрыбута \"%s\": %s" + +#: ../gio/glocalfileinfo.c:1544 +msgid " (invalid encoding)" +msgstr " (хібнае кадаванне)" + +#: ../gio/glocalfileinfo.c:1736 ../gio/glocalfileoutputstream.c:807 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "Памылка пры зборы звеÑтак аб файле \"%s\": %s" + +#: ../gio/glocalfileinfo.c:1982 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Памылка пры зборы звеÑтак аб дÑÑкрыптары файла: %s" + +#: ../gio/glocalfileinfo.c:2027 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Хібны тып атрыбута (чакаўÑÑ uint32)" + +#: ../gio/glocalfileinfo.c:2045 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Хібны тып атрыбута (чакаўÑÑ uint64)" + +#: ../gio/glocalfileinfo.c:2064 ../gio/glocalfileinfo.c:2083 +msgid "Invalid attribute type (byte string expected)" +msgstr "Хібны тып атрыбута (чакаўÑÑ Ð»Ð°Ð½Ñ†ÑƒÐ¶Ð¾Ðº байтаў)" + +#: ../gio/glocalfileinfo.c:2118 +msgid "Cannot set permissions on symlinks" +msgstr "Ðемагчыма наÑтаўлÑць дазволы Ð´Ð»Ñ Ñімвальных ÑпаÑылак" + +#: ../gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Памылка наÑÑ‚Ð°ÑžÐ»ÐµÐ½Ð½Ñ Ð´Ð°Ð·Ð²Ð¾Ð»Ð°Ñž: %s" + +#: ../gio/glocalfileinfo.c:2185 +#, c-format +msgid "Error setting owner: %s" +msgstr "Памылка прызначÑÐ½Ð½Ñ ÑžÐ»Ð°Ñніка: %s" + +#: ../gio/glocalfileinfo.c:2208 +msgid "symlink must be non-NULL" +msgstr "ÑÑ–Ð¼Ð²Ð°Ð»ÑŒÐ½Ð°Ñ ÑпаÑылка не можа мець NULL-значÑнне" + +#: ../gio/glocalfileinfo.c:2218 ../gio/glocalfileinfo.c:2237 +#: ../gio/glocalfileinfo.c:2248 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Памылка наÑÑ‚Ð°ÑžÐ»ÐµÐ½Ð½Ñ Ñімвальнай ÑпаÑылкі: %s" + +#: ../gio/glocalfileinfo.c:2227 +msgid "Error setting symlink: file is not a symlink" +msgstr "Памылка наÑтаўленнÑ: файл не з'ÑўлÑецца Ñімвальнай ÑпаÑылкай" + +#: ../gio/glocalfileinfo.c:2353 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Памылка наÑÑ‚Ð°ÑžÐ»ÐµÐ½Ð½Ñ Ñ‡Ð°Ñавых метак змÑÐ½ÐµÐ½Ð½Ñ Ñ– доÑтупу: %s" + +#: ../gio/glocalfileinfo.c:2376 +msgid "SELinux context must be non-NULL" +msgstr "SELinux-кантÑкÑÑ‚ не можа мець NULL-значÑнне" + +#: ../gio/glocalfileinfo.c:2391 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Памылка наÑÑ‚Ð°ÑžÐ»ÐµÐ½Ð½Ñ SELinux-кантÑкÑту: %s" + +#: ../gio/glocalfileinfo.c:2398 +msgid "SELinux is not enabled on this system" +msgstr "SELinux не ўключаны Ð´Ð»Ñ Ð³Ñтай ÑÑ–ÑÑ‚Ñмы" + +#: ../gio/glocalfileinfo.c:2490 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "ÐаÑтаўленне атрыбута %s не падтрымліваецца" + +#: ../gio/glocalfileinputstream.c:172 ../gio/glocalfileoutputstream.c:698 +#, c-format +msgid "Error reading from file: %s" +msgstr "Памылка Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ Ð· файла: %s" + +#: ../gio/glocalfileinputstream.c:203 ../gio/glocalfileinputstream.c:215 +#: ../gio/glocalfileinputstream.c:322 ../gio/glocalfileoutputstream.c:460 +#: ../gio/glocalfileoutputstream.c:1006 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Памылка Ð¿Ñ€Ð°ÐºÑ€ÑƒÑ‡Ð²Ð°Ð½Ð½Ñ Ð·Ð¼ÐµÑціва файла: %s" + +#: ../gio/glocalfileinputstream.c:244 ../gio/glocalfileoutputstream.c:250 +#: ../gio/glocalfileoutputstream.c:344 +#, c-format +msgid "Error closing file: %s" +msgstr "Памылка Ð·Ð°ÐºÑ€Ñ‹Ñ†Ñ†Ñ Ñ„Ð°Ð¹Ð»Ð°: %s" + +#: ../gio/glocalfilemonitor.c:176 +msgid "Unable to find default local file monitor type" +msgstr "" +"Ðе ўдалоÑÑ Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ñ‹Ñ†ÑŒ прадвызначаны тып назіральніка за мÑÑцовымі файламі" + +#: ../gio/glocalfileoutputstream.c:198 ../gio/glocalfileoutputstream.c:230 +#: ../gio/glocalfileoutputstream.c:719 +#, c-format +msgid "Error writing to file: %s" +msgstr "Памылка запіÑу Ñž файл: %s" + +#: ../gio/glocalfileoutputstream.c:277 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Памылка Ð²Ñ‹Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñтарой запаÑной ÑпаÑылкі: %s" + +#: ../gio/glocalfileoutputstream.c:291 ../gio/glocalfileoutputstream.c:304 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Памылка ÑтварÑÐ½Ð½Ñ Ð·Ð°Ð¿Ð°Ñной копіі: %s" + +#: ../gio/glocalfileoutputstream.c:322 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Памылка Ð¿ÐµÑ€Ð°Ð½Ð°Ð·Ð²Ð°Ð½Ð½Ñ Ñ‡Ð°Ñовага файла: %s" + +#: ../gio/glocalfileoutputstream.c:506 ../gio/glocalfileoutputstream.c:1057 +#, c-format +msgid "Error truncating file: %s" +msgstr "Памылка Ð°Ð±Ñ€Ð°Ð·Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð°: %s" + +#: ../gio/glocalfileoutputstream.c:559 ../gio/glocalfileoutputstream.c:789 +#: ../gio/glocalfileoutputstream.c:1038 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Памылка Ð°Ð´ÐºÑ€Ñ‹Ñ†Ñ†Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\": %s" + +#: ../gio/glocalfileoutputstream.c:820 +msgid "Target file is a directory" +msgstr "МÑтавы файл з'ÑўлÑецца каталогам" + +#: ../gio/glocalfileoutputstream.c:825 +msgid "Target file is not a regular file" +msgstr "МÑтавы файл не з'ÑўлÑецца звычайным файлам" + +#: ../gio/glocalfileoutputstream.c:837 +msgid "The file was externally modified" +msgstr "Файл быў зменены звонку" + +#: ../gio/glocalfileoutputstream.c:1022 +#, c-format +msgid "Error removing old file: %s" +msgstr "Памылка Ð²Ñ‹Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñтарога файла: %s" + +#: ../gio/gmemoryinputstream.c:473 ../gio/gmemoryoutputstream.c:736 +msgid "Invalid GSeekType supplied" +msgstr "Хібны тып GSeekType" + +#: ../gio/gmemoryinputstream.c:483 +msgid "Invalid seek request" +msgstr "Хібны запыт пракруткі" + +#: ../gio/gmemoryinputstream.c:507 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ðемагчыма абрÑзаць Ñтрумень GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:541 +msgid "Memory output stream not resizable" +msgstr "Ðемагчыма змÑнÑць памер ÑÑ‚Ñ€ÑƒÐ¼ÐµÐ½Ñ Ð²Ñ‹Ð²Ð°Ð´Ñƒ змеÑціва памÑці" + +#: ../gio/gmemoryoutputstream.c:557 +msgid "Failed to resize memory output stream" +msgstr "Ðе ўдалоÑÑ Ð·Ð¼Ñніць памер ÑÑ‚Ñ€ÑƒÐ¼ÐµÐ½Ñ Ð²Ñ‹Ð²Ð°Ð´Ñƒ змеÑціва памÑці" + +#: ../gio/gmemoryoutputstream.c:645 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "ПамÑць, патрÑÐ±Ð½Ð°Ñ Ð´Ð»Ñ Ð·Ð°Ð¿Ñ–Ñу, Ð±Ð¾Ð»ÑŒÑˆÐ°Ñ Ð·Ð° даÑтупную адраÑную праÑтору" + +#: ../gio/gmemoryoutputstream.c:746 +msgid "Requested seek before the beginning of the stream" +msgstr "Ðтрыманы загад на пракрутку ÑÑ‚Ñ€ÑƒÐ¼ÐµÐ½Ñ Ð´Ð°Ð»ÐµÐ¹ за Ñго пачатак" + +#: ../gio/gmemoryoutputstream.c:755 +msgid "Requested seek beyond the end of the stream" +msgstr "Ðтрыманы загад на пракрутку далей за Ñго канец" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:395 +msgid "mount doesn't implement \"unmount\"" +msgstr "прымацаваны дыÑк не падтрымлівае функцыі \"unmount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:471 +msgid "mount doesn't implement \"eject\"" +msgstr "прымацаваны дыÑк не падтрымлівае функцыі \"eject\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:549 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"прымацаваны дыÑк не падтрымлівае функцый \"unmount\" Ñ– " +"\"unmount_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:634 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"прымацаваны дыÑк не падтрымлівае функцый \"eject\" Ñ– \"eject_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:722 +msgid "mount doesn't implement \"remount\"" +msgstr "прымацаваны дыÑк не падтрымлівае функцыі \"remount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:803 +msgid "mount doesn't implement content type guessing" +msgstr "прымацаваны дыÑк не падтрымлівае функцыі вызначÑÐ½Ð½Ñ Ñ‚Ñ‹Ð¿Ñƒ змеÑціва" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" +"прымацаваны дыÑк не падтрымлівае функцыі Ñіхроннага вызначÑÐ½Ð½Ñ Ñ‚Ñ‹Ð¿Ñƒ змеÑціва" + +#: ../gio/gnetworkaddress.c:353 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "Ðазва машыны \"%s\" змÑшчае знак \"[\" без \"]\"" + +#: ../gio/gnetworkmonitorbase.c:191 ../gio/gnetworkmonitorbase.c:294 +msgid "Network unreachable" +msgstr "Сетка недаÑÑгальнаÑ" + +#: ../gio/gnetworkmonitorbase.c:229 ../gio/gnetworkmonitorbase.c:259 +msgid "Host unreachable" +msgstr "Машына недаÑÑгальнаÑ" + +#: ../gio/gnetworkmonitornetlink.c:97 ../gio/gnetworkmonitornetlink.c:109 +#: ../gio/gnetworkmonitornetlink.c:128 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ðе ўдалоÑÑ Ñтварыць Ñеткавага назіральніка: %s" + +#: ../gio/gnetworkmonitornetlink.c:118 +msgid "Could not create network monitor: " +msgstr "Ðе ўдалоÑÑ Ñтварыць Ñеткавага назіральніка: " + +#: ../gio/gnetworkmonitornetlink.c:176 +msgid "Could not get network status: " +msgstr "Ðе ўдалоÑÑ Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ñ‹Ñ†ÑŒ Ñеткавы Ñтан: " + +#: ../gio/goutputstream.c:201 ../gio/goutputstream.c:453 +msgid "Output stream doesn't implement write" +msgstr "Выхадны Ñтрумень не падтрымлівае функцыі запіÑу" + +#: ../gio/goutputstream.c:414 ../gio/goutputstream.c:939 +msgid "Source stream is already closed" +msgstr "Выточны Ñтрумень ужо закрыты" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:454 +#: ../gio/gresourcefile.c:555 ../gio/gresourcefile.c:657 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "РÑÑÑƒÑ€Ñ Ð½Ð° \"%s\" не Ñ–Ñнуе" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "Памылка раÑÐ¿Ð°ÐºÐ°Ð²Ð°Ð½Ð½Ñ Ñ€ÑÑурÑа на \"%s\"" + +#: ../gio/gresourcefile.c:653 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "РÑÑÑƒÑ€Ñ Ð½Ð° \"%s\" не з'ÑўлÑецца каталогам" + +#: ../gio/gresourcefile.c:861 +msgid "Input stream doesn't implement seek" +msgstr "Уваходны Ñтрумень не мае функцыі пошуку" + +#: ../gio/gresource-tool.c:475 ../gio/gsettings-tool.c:542 +msgid "Print help" +msgstr "ВывеÑці даведку" + +#: ../gio/gresource-tool.c:476 ../gio/gresource-tool.c:544 +msgid "[COMMAND]" +msgstr "[ЗÐГÐД]" + +#: ../gio/gresource-tool.c:481 +msgid "List sections containing resources in an elf FILE" +msgstr "Пералічыць Ñекцыі, ÑÐºÑ–Ñ Ð·Ð¼Ñшчаюць Ñ€ÑÑурÑÑ‹ Ñž elf-файле ФÐЙЛ" + +#: ../gio/gresource-tool.c:487 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Пералічыць Ñ€ÑÑурÑÑ‹\n" +"Калі дадзена СЕКЦЫЯ, пералічвае толькі Ñ€ÑÑурÑÑ‹ з гÑтай Ñекцыі\n" +"Калі дадзена СЦЕЖКÐ, пералічвае толькі Ð°Ð´Ð¿Ð°Ð²ÐµÐ´Ð½Ñ‹Ñ Ñ€ÑÑурÑÑ‹" + +#: ../gio/gresource-tool.c:490 ../gio/gresource-tool.c:500 +msgid "FILE [PATH]" +msgstr "ФÐЙЛ [СЦЕЖКÐ]" + +#: ../gio/gresource-tool.c:491 ../gio/gresource-tool.c:501 +#: ../gio/gresource-tool.c:508 +msgid "SECTION" +msgstr "СЕКЦЫЯ" + +#: ../gio/gresource-tool.c:496 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Пералічыць Ñ€ÑÑурÑÑ‹ з падрабÑзнаÑцÑмі\n" +"Калі дадзена СЕКЦЫЯ, пералічвае толькі Ñ€ÑÑурÑÑ‹ з гÑтай Ñекцыі\n" +"Калі дадзена СЦЕЖКÐ, пералічвае толькі Ð°Ð´Ð¿Ð°Ð²ÐµÐ´Ð½Ñ‹Ñ Ñ€ÑÑурÑÑ‹\n" +"ПадрабÑзнаÑці ўключаюць Ñекцыю, памер Ñ– ÑціÑканне" + +#: ../gio/gresource-tool.c:506 +msgid "Extract a resource file to stdout" +msgstr "ВынÑць файл Ñ€ÑÑурÑа Ñž Ñтандартны выхад" + +#: ../gio/gresource-tool.c:507 +msgid "FILE PATH" +msgstr "СЦЕЖКРФÐЙЛ" + +#: ../gio/gresource-tool.c:513 ../gio/gsettings-tool.c:628 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"ÐевÑдомы загад %s\n" +"\n" + +#: ../gio/gresource-tool.c:521 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Правілы выкарыÑтаннÑ:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Загады:\n" +" help Паказаць гÑту інфармацыю\n" +" sections Пералічыць Ñекцыі Ñ€ÑÑурÑаў\n" +" list Пералічыць Ñ€ÑÑурÑÑ‹\n" +" details Пералічыць Ñ€ÑÑурÑÑ‹ з падрабÑзнаÑцÑмі\n" +" extract ВынÑць Ñ€ÑÑурÑ\n" +"\n" +"ВыкарыÑтоўвайце \"gresource help ЗÐГÐД\", каб атрымаць падрабÑзную даведку.\n" +"\n" + +#: ../gio/gresource-tool.c:535 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Правілы выкарыÑтаннÑ:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:538 ../gio/gsettings-tool.c:661 +msgid "Arguments:\n" +msgstr "Ðргументы:\n" + +#: ../gio/gresource-tool.c:542 +msgid " SECTION An (optional) elf section name\n" +msgstr " СЕКЦЫЯ (ÐеабавÑзковаÑ) назва elf-Ñекцыі\n" + +#: ../gio/gresource-tool.c:546 ../gio/gsettings-tool.c:668 +msgid " COMMAND The (optional) command to explain\n" +msgstr " ЗÐГÐД (ÐеабавÑзковы) загад, Ñкі трÑба патлумачыць\n" + +#: ../gio/gresource-tool.c:552 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " ФÐЙЛ Elf-файл (Ð´Ð²Ð°Ð¹ÐºÐ¾Ð²Ð°Ñ Ñ†Ñ– ÑÑƒÐ¿Ð¾Ð»ÑŒÐ½Ð°Ñ Ð±Ñ–Ð±Ð»Ñ–ÑÑ‚Ñка)\n" + +#: ../gio/gresource-tool.c:555 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" ФÐЙЛ Elf-файл (Ð´Ð²Ð°Ð¹ÐºÐ¾Ð²Ð°Ñ Ñ†Ñ– ÑÑƒÐ¿Ð¾Ð»ÑŒÐ½Ð°Ñ Ð±Ñ–Ð±Ð»Ñ–ÑÑ‚Ñка)\n" +" ці ÑкампілÑваны файл Ñ€ÑÑурÑа\n" + +#: ../gio/gresource-tool.c:559 +msgid "[PATH]" +msgstr "[СЦЕЖКÐ]" + +#: ../gio/gresource-tool.c:561 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " СЦЕЖКР(ÐеабавÑзковаÑ) Ñцежка Ñ€ÑÑурÑа (можа быць нÑпоўнай)\n" + +#: ../gio/gresource-tool.c:562 +msgid "PATH" +msgstr "СЦЕЖКÐ" + +#: ../gio/gresource-tool.c:564 +msgid " PATH A resource path\n" +msgstr " СЦЕЖКРСцежка Ñ€ÑÑурÑа\n" + +#: ../gio/gsettings-tool.c:57 ../gio/gsettings-tool.c:78 +#, c-format +msgid "No such schema '%s'\n" +msgstr "Схема \"%s\" не Ñ–Ñнуе\n" + +#: ../gio/gsettings-tool.c:63 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "Схема \"%s\" непераноÑÐ½Ð°Ñ (трÑба вызначыць Ñцежку)\n" + +#: ../gio/gsettings-tool.c:84 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "Схема \"%s\" пераноÑÐ½Ð°Ñ (трÑба вызначыць Ñцежку)\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Empty path given.\n" +msgstr "Сцежка пуÑтаÑ.\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "Сцежка муÑіць пачынацца Ñа ÑкоÑу (\"/\")\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "Сцежка муÑіць канчацца ÑкоÑам (\"/\")\n" + +#: ../gio/gsettings-tool.c:116 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Сцежка не можа змÑшчаць два паÑлÑÐ´Ð¾ÑžÐ½Ñ‹Ñ ÑкоÑÑ‹ (\"//\")\n" + +#: ../gio/gsettings-tool.c:137 +#, c-format +msgid "No such key '%s'\n" +msgstr "Ключ \"%s\" не Ñ–Ñнуе\n" + +#: ../gio/gsettings-tool.c:511 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "ЗначÑнне не Ñž дазволеным дыÑпазоне\n" + +#: ../gio/gsettings-tool.c:518 +#, c-format +msgid "The key is not writable\n" +msgstr "ÐÑма дазволу на Ð·Ð°Ð¿Ñ–Ñ ÐºÐ»ÑŽÑ‡Ð°\n" + +#: ../gio/gsettings-tool.c:548 +msgid "Print version information and exit" +msgstr "ВывеÑці звеÑткі аб верÑÑ–Ñ– праграмы Ñ– выйÑці" + +#: ../gio/gsettings-tool.c:554 +msgid "List the installed (non-relocatable) schemas" +msgstr "Пералічыць уÑталÑÐ²Ð°Ð½Ñ‹Ñ (непераноÑныÑ) Ñхемы" + +#: ../gio/gsettings-tool.c:560 +msgid "List the installed relocatable schemas" +msgstr "Пералічыць уÑталÑÐ²Ð°Ð½Ñ‹Ñ Ð¿ÐµÑ€Ð°Ð½Ð¾ÑÐ½Ñ‹Ñ Ñхемы" + +#: ../gio/gsettings-tool.c:566 +msgid "List the keys in SCHEMA" +msgstr "Пералічыць ключы СХЕМЫ" + +#: ../gio/gsettings-tool.c:567 ../gio/gsettings-tool.c:573 +#: ../gio/gsettings-tool.c:610 +msgid "SCHEMA[:PATH]" +msgstr "СХЕМÐ[:СЦЕЖКÐ]" + +#: ../gio/gsettings-tool.c:572 +msgid "List the children of SCHEMA" +msgstr "Пералічыць нашчадкаў СХЕМЫ" + +#: ../gio/gsettings-tool.c:578 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"РÑкурÑіўна пералічыць ключы Ñ– Ñ–Ñ… значÑнні\n" +"Калі СХЕМРне вызначана, пералічыць уÑе ключы\n" + +#: ../gio/gsettings-tool.c:580 +msgid "[SCHEMA[:PATH]]" +msgstr "[СХЕМÐ[:СЦЕЖКÐ]]" + +#: ../gio/gsettings-tool.c:585 +msgid "Get the value of KEY" +msgstr "Ðтрымаць значÑнне КЛЮЧÐ" + +#: ../gio/gsettings-tool.c:586 ../gio/gsettings-tool.c:592 +#: ../gio/gsettings-tool.c:604 ../gio/gsettings-tool.c:616 +msgid "SCHEMA[:PATH] KEY" +msgstr "СХЕМÐ[:СЦЕЖКÐ] КЛЮЧ" + +#: ../gio/gsettings-tool.c:591 +msgid "Query the range of valid values for KEY" +msgstr "Запытаць аб дыÑпазоне магчымых значÑннÑÑž КЛЮЧÐ" + +#: ../gio/gsettings-tool.c:597 +msgid "Set the value of KEY to VALUE" +msgstr "Прызначыць ЗÐÐЧЭÐÐЕ КЛЮЧУ" + +#: ../gio/gsettings-tool.c:598 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "СХЕМÐ[:СЦЕЖКÐ] КЛЮЧ ЗÐÐЧЭÐÐЕ" + +#: ../gio/gsettings-tool.c:603 +msgid "Reset KEY to its default value" +msgstr "Ð’Ñрнуць прадвызначанае значÑнне КЛЮЧÐ" + +#: ../gio/gsettings-tool.c:609 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Ð’Ñрнуць Ð¿Ñ€Ð°Ð´Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ð°Ð½Ñ‹Ñ Ð·Ð½Ð°Ñ‡Ñнні ÑžÑÑ–Ñ… ключоў СХЕМЫ" + +#: ../gio/gsettings-tool.c:615 +msgid "Check if KEY is writable" +msgstr "Праверыць магчымаÑць змÑÐ½ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÑÐ½Ð½Ñ ÐšÐ›Ð®Ð§Ð" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Ðазіраць за зменамі КЛЮЧÐ.\n" +"Калі КЛЮЧ не вызначаны, назіраць за ÑžÑімі ключамі СХЕМЫ.\n" +"Каб Ñпыніць назіранне, націÑніце ^C.\n" + +#: ../gio/gsettings-tool.c:624 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "СХЕМÐ[:СЦЕЖКÐ] [КЛЮЧ]" + +#: ../gio/gsettings-tool.c:636 +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Правілы карыÑтаннÑ:\n" +" gsettings [--schemadir КÐТÐЛОГ_СХЕМ] ЗÐГÐД [ÐРГУМЕÐТЫ...]\n" +"\n" +"Загады:\n" +" help Паказаць гÑтую даведку\n" +" list-schemas Пералічыць уÑталÑÐ²Ð°Ð½Ñ‹Ñ Ñхемы\n" +" list-relocatable-schemas Пералічыць пераноÑÐ½Ñ‹Ñ Ñхемы\n" +" list-keys Пералічыць ключы Ñхемы\n" +" list-children Пералічыць нашчадкаў Ñхемы\n" +" list-recursively РÑкурÑіўна пералічыць ключы Ñ– Ñ–Ñ… значÑнні\n" +" range Запытаць аб дыÑпазоне магчымых значÑннÑÑž ключа\n" +" get Ðтрымаць значÑнне ключа\n" +" set Прызначыць значÑнне ключу\n" +" reset Ð’Ñрнуць прадвызначанае значÑнне ключа\n" +" reset-recursively Ð’Ñрнуць Ð¿Ñ€Ð°Ð´Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ð°Ð½Ñ‹Ñ Ð·Ð½Ð°Ñ‡Ñнні ÑžÑÑ–Ñ… ключоў " +"Ñхемы\n" +" writable Праверыць магчымаÑць змÑÐ½ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÑÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð°\n" +" monitor Ðазіраць за зменамі\n" +"\n" +"Каб атрымаць падрабÑзнейшую даведку, выканайце загад \"gsettings help ЗÐГÐД" +"\".\n" +"\n" + +#: ../gio/gsettings-tool.c:658 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Правілы карыÑтаннÑ:\n" +"gsettings [--schemadir КÐТÐЛОГ_СХЕМ] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:664 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " КÐТÐЛОГ_СХЕМ Каталог Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ дадатковых Ñхем\n" + +#: ../gio/gsettings-tool.c:672 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" СХЕМРÐазва Ñхемы\n" +" СЦЕЖКРСцежка (Ð´Ð»Ñ Ð¿ÐµÑ€Ð°Ð½Ð¾Ñных Ñхем)\n" + +#: ../gio/gsettings-tool.c:677 +msgid " KEY The (optional) key within the schema\n" +msgstr " КЛЮЧ (неабавÑзковы) ключ у Ñхеме\n" + +#: ../gio/gsettings-tool.c:681 +msgid " KEY The key within the schema\n" +msgstr " КЛЮЧ Ключ у Ñхеме\n" + +#: ../gio/gsettings-tool.c:685 +msgid " VALUE The value to set\n" +msgstr " ЗÐÐЧЭÐÐЕ ПатрÑбнае значÑнне ключа\n" + +#: ../gio/gsettings-tool.c:744 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Ðе ўдалоÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·Ñ–Ñ†ÑŒ Ñхемы з %s: %s\n" + +#: ../gio/gsettings-tool.c:806 +#, c-format +msgid "Empty schema name given\n" +msgstr "ПуÑÑ‚Ð°Ñ Ð½Ð°Ð·Ð²Ð° Ñхемы\n" + +#: ../gio/gsocket.c:313 +msgid "Invalid socket, not initialized" +msgstr "Хібны Ñокет не ініцыÑваны" + +#: ../gio/gsocket.c:320 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Хібны Ñокет не ініцыÑваны з наÑтупнай прычыны: %s" + +#: ../gio/gsocket.c:328 +msgid "Socket is already closed" +msgstr "Сокет ужо закрыты" + +#: ../gio/gsocket.c:336 ../gio/gsocket.c:3623 ../gio/gsocket.c:3678 +msgid "Socket I/O timed out" +msgstr "СкончыўÑÑ Ñ‚Ñрмін Ñ‡Ð°ÐºÐ°Ð½Ð½Ñ ÑžÐ²Ð¾Ð´Ñƒ-вываду на Ñокеце" + +#: ../gio/gsocket.c:483 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ÑтварÑнне GSocket-аб'екта з fd: %s" + +#: ../gio/gsocket.c:511 ../gio/gsocket.c:565 ../gio/gsocket.c:572 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ðе ўдалоÑÑ Ñтварыць Ñокет: %s" + +#: ../gio/gsocket.c:565 +msgid "Unknown family was specified" +msgstr "ÐевÑдомае ÑÑмейÑтва пратакола" + +#: ../gio/gsocket.c:572 +msgid "Unknown protocol was specified" +msgstr "ÐевÑдомы пратакол" + +#: ../gio/gsocket.c:1730 +#, c-format +msgid "could not get local address: %s" +msgstr "не ўдалоÑÑ Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ñ‹Ñ†ÑŒ Ñвой адраÑ: %s" + +#: ../gio/gsocket.c:1773 +#, c-format +msgid "could not get remote address: %s" +msgstr "не ўдалоÑÑ Ð²Ñ‹Ð·Ð½Ð°Ñ‡Ñ‹Ñ†ÑŒ Ð°Ð´Ñ€Ð°Ñ Ð°Ð´Ð´Ð°Ð»ÐµÐ½Ð°Ð¹ машыны: %s" + +#: ../gio/gsocket.c:1834 +#, c-format +msgid "could not listen: %s" +msgstr "не ўдалоÑÑ Ð¿Ð°Ñ‡Ð°Ñ†ÑŒ Ñлухаць: %s" + +#: ../gio/gsocket.c:1933 +#, c-format +msgid "Error binding to address: %s" +msgstr "Памылка прывÑÐ·Ð°Ð½Ð½Ñ Ð´Ð° адраÑу: %s" + +#: ../gio/gsocket.c:2045 ../gio/gsocket.c:2082 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Ðе ўдалоÑÑ Ð´Ð°Ð»ÑƒÑ‡Ñ‹Ñ†Ñ†Ð° да групы multicast: %s" + +#: ../gio/gsocket.c:2046 ../gio/gsocket.c:2083 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Ðе ўдалоÑÑ Ð²Ñ‹Ð¹Ñці з групы multicast: %s" + +#: ../gio/gsocket.c:2047 +msgid "No support for source-specific multicast" +msgstr "Ð¡Ð¿ÐµÑ†Ñ‹Ñ„Ñ–Ñ‡Ð½Ð°Ñ ÐºÑ€Ñ‹Ð½Ñ–Ñ†Ð° multicast не падтрымліваецца" + +#: ../gio/gsocket.c:2266 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Памылка ÑžÑ…Ð²Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð»ÑƒÑ‡ÑннÑ: %s" + +#: ../gio/gsocket.c:2387 +msgid "Connection in progress" +msgstr "Ðдбываецца злучÑнне" + +#: ../gio/gsocket.c:2434 +msgid "Unable to get pending error: " +msgstr "Ðе ўдалоÑÑ ÑžÐ·Ñць чарговую памылку: " + +#: ../gio/gsocket.c:2620 +#, c-format +msgid "Error receiving data: %s" +msgstr "Памылка Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ñ‹Ñ…: %s" + +#: ../gio/gsocket.c:2798 +#, c-format +msgid "Error sending data: %s" +msgstr "Памылка паÑÐ»Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ñ‹Ñ…: %s" + +#: ../gio/gsocket.c:2912 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ðе ўдалоÑÑ Ñпыніць працу Ñокета: %s" + +#: ../gio/gsocket.c:2991 +#, c-format +msgid "Error closing socket: %s" +msgstr "Памылка Ð·Ð°ÐºÑ€Ñ‹Ñ†Ñ†Ñ Ñокета: %s" + +#: ../gio/gsocket.c:3616 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Чакаем умовы на Ñокеце: %s" + +#: ../gio/gsocket.c:3894 ../gio/gsocket.c:3975 +#, c-format +msgid "Error sending message: %s" +msgstr "Памылка паÑÑ‹Ð»Ð°Ð½Ð½Ñ Ð¿Ð°Ð²ÐµÐ´Ð°Ð¼Ð»ÐµÐ½Ð½Ñ: %s" + +#: ../gio/gsocket.c:3919 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage не падтрымліваецца Ñž ÑÑ–ÑÑ‚Ñме Windows" + +#: ../gio/gsocket.c:4253 ../gio/gsocket.c:4388 +#, c-format +msgid "Error receiving message: %s" +msgstr "Памылка Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ð½Ð½Ñ Ð¿Ð°Ð²ÐµÐ´Ð°Ð¼Ð»ÐµÐ½Ð½Ñ: %s" + +#: ../gio/gsocket.c:4470 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð½Ñ‹Ñ Ð´Ð°Ð½Ñ‹Ñ Ð´Ð° Ñокета: %s" + +#: ../gio/gsocket.c:4489 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials адÑутнічае Ð´Ð»Ñ Ð³Ñтай аперацыйнай ÑÑ–ÑÑ‚Ñмы" + +#: ../gio/gsocketclient.c:177 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ðе ўдалоÑÑ Ð·Ð»ÑƒÑ‡Ñ‹Ñ†Ñ†Ð° з прокÑÑ–-Ñерверам %s: " + +#: ../gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ðе ўдалоÑÑ Ð·Ð»ÑƒÑ‡Ñ‹Ñ†Ñ†Ð° з %s: " + +#: ../gio/gsocketclient.c:193 +msgid "Could not connect: " +msgstr "Ðе ўдалоÑÑ Ð·Ð»ÑƒÑ‡Ñ‹Ñ†Ñ†Ð°: " + +#: ../gio/gsocketclient.c:1067 ../gio/gsocketclient.c:1631 +msgid "Unknown error on connect" +msgstr "ÐŸÐ°Ð´Ñ‡Ð°Ñ Ð·Ð»ÑƒÑ‡ÑÐ½Ð½Ñ ÑžÐ·Ð½Ñ–ÐºÐ»Ð° невÑÐ´Ð¾Ð¼Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° " + +#: ../gio/gsocketclient.c:1120 ../gio/gsocketclient.c:1569 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "ПрокÑÑ–-пераÑылка падтрымліваецца толькі Ð´Ð»Ñ TCP-злучÑннÑÑž." + +#: ../gio/gsocketclient.c:1146 ../gio/gsocketclient.c:1590 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Пратакол \"%s\" не падтрымліваецца Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐºÑÑ–-злучÑннÑÑž." + +#: ../gio/gsocketlistener.c:187 +msgid "Listener is already closed" +msgstr "Слухач ужо закрыў Ñокет" + +#: ../gio/gsocketlistener.c:228 +msgid "Added socket is closed" +msgstr "Дададзены Ñокет закрыты" + +#: ../gio/gsocks4aproxy.c:120 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "Пратакол SOCKSv4 не падтрымлівае IPv6-адраÑу \"%s\"" + +#: ../gio/gsocks4aproxy.c:138 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Ð†Ð¼Ñ ÐºÐ°Ñ€Ñ‹Ñтальніка надта доўгае Ð´Ð»Ñ Ð¿Ñ€Ð°Ñ‚Ð°ÐºÐ¾Ð»Ð° SOCKSv4" + +#: ../gio/gsocks4aproxy.c:155 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "Ðазва машыны \"%s\" надта Ð´Ð¾ÑžÐ³Ð°Ñ Ð´Ð»Ñ Ð¿Ñ€Ð°Ñ‚Ð°ÐºÐ¾Ð»Ð° SOCKSv4" + +#: ../gio/gsocks4aproxy.c:181 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "ГÑты прокÑÑ–-Ñервер не з'ÑўлÑецца SOCKSv4-Ñерверам." + +#: ../gio/gsocks4aproxy.c:188 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "ЗлучÑнне праз SOCKSv4-Ñервер было адпрÑчана" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:326 +#: ../gio/gsocks5proxy.c:336 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "ГÑты прокÑÑ–-Ñервер не з'ÑўлÑецца SOCKSv5-Ñерверам." + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "ГÑты SOCKSv5-Ñервер вымагае праверкі тоеÑнаÑці." + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"ГÑты SOCKSv5 прокÑÑ–-Ñервер патрабуе такога ÑпоÑабу ідÑнтыфікацыі, Ñкі не " +"падтрымліваецца бібліÑÑ‚Ñкай GLib." + +#: ../gio/gsocks5proxy.c:208 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Ð†Ð¼Ñ ÐºÐ°Ñ€Ñ‹Ñтальніка ці пароль надта Ð´Ð¾ÑžÐ³Ñ–Ñ Ð´Ð»Ñ Ð¿Ñ€Ð°Ñ‚Ð°ÐºÐ¾Ð»Ð° SOCKSv5." + +#: ../gio/gsocks5proxy.c:238 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Праверка тоеÑнаÑці пратакола SOCKSv5 ÑкончылаÑÑ Ð½Ñўдачай праз Ñ…Ñ–Ð±Ð½Ñ‹Ñ Ñ–Ð¼Ñ " +"карыÑтальніка ці пароль." + +#: ../gio/gsocks5proxy.c:288 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "Ðазва машыны \"%s\" надта Ð´Ð¾ÑžÐ³Ð°Ñ Ð´Ð»Ñ Ð¿Ñ€Ð°Ñ‚Ð°ÐºÐ¾Ð»Ð° SOCKSv5" + +#: ../gio/gsocks5proxy.c:350 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 прокÑÑ–-Ñервер мае невÑдомы тып адраÑу." + +#: ../gio/gsocks5proxy.c:357 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Ð£Ð½ÑƒÑ‚Ñ€Ð°Ð½Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° SOCKSv5 прокÑÑ–-Ñервера." + +#: ../gio/gsocks5proxy.c:363 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5-злучÑнне забаронена правіламі." + +#: ../gio/gsocks5proxy.c:370 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Машына недаÑÑÐ³Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð°Ð· гÑты SOCKSv5-Ñервер." + +#: ../gio/gsocks5proxy.c:376 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Сетка недаÑÑÐ³Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð°Ð· гÑты SOCKSv5-Ñервер." + +#: ../gio/gsocks5proxy.c:382 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Прапанова злучÑÐ½Ð½Ñ Ð¿Ñ€Ð°Ð· SOCKSv5-Ñервер адпрÑчана." + +#: ../gio/gsocks5proxy.c:388 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 прокÑÑ–-Ñервер не падтрымлівае загаду \"connect\"." + +#: ../gio/gsocks5proxy.c:394 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 прокÑÑ–-Ñервер не падтрымлівае гÑтага тыпу адраÑоў." + +#: ../gio/gsocks5proxy.c:400 +msgid "Unknown SOCKSv5 proxy error." +msgstr "ÐевÑÐ´Ð¾Ð¼Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° прокÑÑ–-Ñервера SOCKSv5." + +#: ../gio/gthemedicon.c:521 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "Ðе ўдалоÑÑ Ð°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ñ†ÑŒ верÑÑ–ÑŽ %d ÐºÐ°Ð´Ð°Ð²Ð°Ð½Ð½Ñ GThemedIcon" + +#: ../gio/gthreadedresolver.c:110 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "Памылка вызначÑÐ½Ð½Ñ Ð°Ð´Ñ€Ð°Ñу \"%s\": %s" + +#: ../gio/gthreadedresolver.c:195 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Памылка адваротнага вызначÑÐ½Ð½Ñ Ð°Ð´Ñ€Ð°Ñу \"%s\": %s" + +#: ../gio/gthreadedresolver.c:533 ../gio/gthreadedresolver.c:614 +#: ../gio/gthreadedresolver.c:715 ../gio/gthreadedresolver.c:766 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "Ð”Ð»Ñ \"%s\" адÑутнічае DNS-Ð·Ð°Ð¿Ñ–Ñ Ð¿Ð°Ñ‚Ñ€Ñбнага тыпу" + +#: ../gio/gthreadedresolver.c:538 ../gio/gthreadedresolver.c:720 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "ЧаÑова немагчыма вызначыць Ð°Ð´Ñ€Ð°Ñ \"%s\"" + +#: ../gio/gthreadedresolver.c:543 ../gio/gthreadedresolver.c:725 +#, c-format +msgid "Error resolving '%s'" +msgstr "Памылка вызначÑÐ½Ð½Ñ Ð°Ð´Ñ€Ð°Ñу \"%s\"" + +#: ../gio/gtlscertificate.c:248 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ðе ўдалоÑÑ Ñ€Ð°Ñшыфраваць закрыты ключ, закадаваны Ñк PEM" + +#: ../gio/gtlscertificate.c:253 +msgid "No PEM-encoded private key found" +msgstr "Закрыты ключ, закадаваны Ñк PEM, не знойдзены" + +#: ../gio/gtlscertificate.c:263 +msgid "Could not parse PEM-encoded private key" +msgstr "Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð°Ð±Ñ€Ð°Ñ†ÑŒ закрыты ключ, закадаваны Ñк PEM" + +#: ../gio/gtlscertificate.c:288 +msgid "No PEM-encoded certificate found" +msgstr "Сертыфікат, закадаваны Ñк PEM, не знойдзены" + +#: ../gio/gtlscertificate.c:297 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð°Ð±Ñ€Ð°Ñ†ÑŒ Ñертыфікат, закадаваны Ñк PEM" + +#: ../gio/gtlspassword.c:113 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "ГÑта апошні шанец увеÑці правільны пароль да Ð±Ð»Ð°ÐºÑ–Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð¾Ñтупу." + +#: ../gio/gtlspassword.c:115 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"Ð’Ñ‹ некалькі разоў уводзілі Ñ…Ñ–Ð±Ð½Ñ‹Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ–, Ñ– калі вы працÑгнеце ўводзіць " +"Ñ…Ñ–Ð±Ð½Ñ‹Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ–, дык будзеце заблакіраваны." + +#: ../gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Уведзены пароль нÑправільны." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Чакалі аднаго кіроўнага паведамленнÑ, а маем %d" +msgstr[1] "Чакалі аднаго кіроўнага паведамленнÑ, а маем %d" +msgstr[2] "Чакалі аднаго кіроўнага паведамленнÑ, а маем %d" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "Ðечаканы тып дадатковых даных" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Чакалі аднаго fd, а маем %d\n" +msgstr[1] "Чакалі аднаго fd, а маем %d\n" +msgstr[2] "Чакалі аднаго fd, а маем %d\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "Ðтрымалі хібны fd" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "Памылка паÑÐ»Ð°Ð½Ð½Ñ Ð¿Ð°ÑведчаннÑÑž: " + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ð²ÐµÑ€Ñ‹Ñ†ÑŒ, ці ÑžÐºÐ»ÑŽÑ‡Ð°Ð½Ð°Ñ Ð¾Ð¿Ñ†Ñ‹Ñ SO_PASSCRED Ð´Ð»Ñ Ñокета: %s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Ðе ўдалоÑÑ ÑžÐºÐ»ÑŽÑ‡Ñ‹Ñ†ÑŒ опцыю SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Чакалі аднаго байта, Ñкі б пацвердзіў атрыманне паÑведчаннÑÑž, але нічога не " +"атрымалі" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ðе чакалі кіроўнага паведамленнÑ, але маем %d" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Ðе ўдалоÑÑ Ð²Ñ‹ÐºÐ»ÑŽÑ‡Ñ‹Ñ†ÑŒ опцыю SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:372 ../gio/gunixinputstream.c:393 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Памылка Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ Ð· дÑÑкрыптара файла: %s" + +#: ../gio/gunixinputstream.c:426 ../gio/gunixoutputstream.c:412 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Памылка Ð·Ð°ÐºÑ€Ñ‹Ñ†Ñ†Ñ Ð´ÑÑкрыптара файла: %s" + +#: ../gio/gunixmounts.c:1985 ../gio/gunixmounts.c:2038 +msgid "Filesystem root" +msgstr "Корань файлавай ÑÑ–ÑÑ‚Ñмы" + +#: ../gio/gunixoutputstream.c:358 ../gio/gunixoutputstream.c:379 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Памылка запіÑу Ñž дÑÑкрыптар файла: %s" + +#: ../gio/gunixsocketaddress.c:234 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "ÐбÑÑ‚Ñ€Ð°ÐºÑ‚Ð½Ñ‹Ñ Ð°Ð´Ñ€Ð°ÑÑ‹ UNIX-Ñокетаў не падтрымліваюцца Ñž гÑтай ÑÑ–ÑÑ‚Ñме" + +#: ../gio/gvolume.c:439 +msgid "volume doesn't implement eject" +msgstr "дыÑкавы том не мае функцыі \"eject\"" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:516 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "дыÑкавы том не мае функцый \"eject\" ці \"eject_with_operation\"" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÑˆÑƒÐºÐ°Ñ†ÑŒ праграму" + +#: ../gio/gwin32appinfo.c:308 +#, c-format +msgid "Error launching application: %s" +msgstr "Ðе ўдалоÑÑ Ð·Ð°Ð¿ÑƒÑціць праграму: %s" + +#: ../gio/gwin32appinfo.c:344 +msgid "URIs not supported" +msgstr "URI-адраÑÑ‹ не абÑлугоўваюцца" + +#: ../gio/gwin32appinfo.c:366 +msgid "association changes not supported on win32" +msgstr "" +"змÑненне ÑувÑзі праграм Ñ– тыпаў файлаў не падтрымліваецца Ñž win32-аÑÑроддзі" + +#: ../gio/gwin32appinfo.c:378 +msgid "Association creation not supported on win32" +msgstr "" +"СтварÑнне ÑувÑзей праграм Ñ– тыпаў файлаў не падтрымліваецца Ñž win32-аÑÑроддзі" + +#: ../gio/gwin32inputstream.c:343 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ з файлавага аб'екта: %s" + +#: ../gio/gwin32inputstream.c:375 ../gio/gwin32outputstream.c:362 +#, c-format +msgid "Error closing handle: %s" +msgstr "Ðе ўдалоÑÑ Ð·Ð°ÐºÑ€Ñ‹Ñ†ÑŒ файлавы аб'ект: %s" + +#: ../gio/gwin32outputstream.c:330 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Ðе ўдалоÑÑ Ð·Ð°Ð¿Ñ–Ñаць у файлавы аб'ект: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "Ðе Ñтае памÑці" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "Ð£Ð½ÑƒÑ‚Ñ€Ð°Ð½Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ°: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "ТрÑба болей уводных даных" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "Ð¥Ñ–Ð±Ð½Ñ‹Ñ ÑціÑÐ½ÑƒÑ‚Ñ‹Ñ Ð´Ð°Ð½Ñ‹Ñ" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ÐÐ´Ñ€Ð°Ñ Ð´Ð»Ñ Ð¿Ñ€Ð°ÑлухоўваннÑ" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ігнаруецца, захаваны Ð´Ð»Ñ ÑумÑшчальнаÑці з GTestDbus" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "ВывеÑці адраÑ" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "ВывеÑці Ð°Ð´Ñ€Ð°Ñ Ñƒ Ñ€Ñжыме абалонкі" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "ЗапуÑціць dbus-Ñлужбу" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "Ð¥Ñ–Ð±Ð½Ñ‹Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñ‹\n" + +#: ../glib/gbookmarkfile.c:760 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Ðечаканы атрыбут \"%s\" Ð´Ð»Ñ Ñкладніка \"%s\"" + +#: ../glib/gbookmarkfile.c:771 ../glib/gbookmarkfile.c:842 +#: ../glib/gbookmarkfile.c:852 ../glib/gbookmarkfile.c:959 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Ðтрыбут \"%s\" Ñлемента \"%s\" не знойдзены" + +#: ../glib/gbookmarkfile.c:1129 ../glib/gbookmarkfile.c:1194 +#: ../glib/gbookmarkfile.c:1258 ../glib/gbookmarkfile.c:1268 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Ðечаканы Ñ‚Ñг \"%s\" замеÑÑ‚ чаканага \"%s\"" + +#: ../glib/gbookmarkfile.c:1154 ../glib/gbookmarkfile.c:1168 +#: ../glib/gbookmarkfile.c:1236 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Ðечаканы Ñ‚Ñг \"%s\" унутры \"%s\"" + +#: ../glib/gbookmarkfile.c:1798 +msgid "No valid bookmark file found in data dirs" +msgstr "У каталогах з данымі не знойдзена файлаў з закладкамі" + +#: ../glib/gbookmarkfile.c:1999 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Закладка Ð´Ð»Ñ Ð°Ð´Ñ€Ð°Ñу \"%s\" ужо Ñ–Ñнуе" + +#: ../glib/gbookmarkfile.c:2045 ../glib/gbookmarkfile.c:2203 +#: ../glib/gbookmarkfile.c:2288 ../glib/gbookmarkfile.c:2368 +#: ../glib/gbookmarkfile.c:2453 ../glib/gbookmarkfile.c:2536 +#: ../glib/gbookmarkfile.c:2614 ../glib/gbookmarkfile.c:2693 +#: ../glib/gbookmarkfile.c:2735 ../glib/gbookmarkfile.c:2832 +#: ../glib/gbookmarkfile.c:2952 ../glib/gbookmarkfile.c:3142 +#: ../glib/gbookmarkfile.c:3218 ../glib/gbookmarkfile.c:3386 +#: ../glib/gbookmarkfile.c:3475 ../glib/gbookmarkfile.c:3565 +#: ../glib/gbookmarkfile.c:3693 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Ð”Ð»Ñ Ð°Ð´Ñ€Ð°Ñу \"%s\" не знойдзена закладкі" + +#: ../glib/gbookmarkfile.c:2377 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "MIME-тып не вызначаны Ð´Ð»Ñ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÑ– на Ð°Ð´Ñ€Ð°Ñ \"%s\"" + +#: ../glib/gbookmarkfile.c:2462 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Закладка на Ð°Ð´Ñ€Ð°Ñ \"%s\" не мае ÑцÑжка прыватнаÑці" + +#: ../glib/gbookmarkfile.c:2841 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Ð”Ð»Ñ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÑ– на Ð°Ð´Ñ€Ð°Ñ \"%s\" не вызначана груп" + +#: ../glib/gbookmarkfile.c:3239 ../glib/gbookmarkfile.c:3396 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "ÐÑма праграм з назвай \"%s\", ÑÐºÑ–Ñ Ð± зарÑгіÑтравалі закладу на \"%s\"" + +#: ../glib/gbookmarkfile.c:3419 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð³Ð°Ñ€Ð½ÑƒÑ†ÑŒ загад \"%s\" з дапамогай адраÑу \"%s\"" + +#: ../glib/gconvert.c:506 ../glib/gutf8.c:829 ../glib/gutf8.c:1039 +#: ../glib/gutf8.c:1176 ../glib/gutf8.c:1280 +msgid "Partial character sequence at end of input" +msgstr "ÐбрÑÐ·Ð°Ð½Ð°Ñ Ð¿Ð°ÑлÑдоўнаÑць знакаў напрыканцы ўводу" + +#: ../glib/gconvert.c:756 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Ðе ўдалоÑÑ Ð¿ÐµÑ€Ð°ÑžÑ‚Ð²Ð°Ñ€Ñ‹Ñ†ÑŒ Ð´Ð°Ð½Ñ‹Ñ Ð· падменнага знаказбору \"%s\" у \"%s\"" + +#: ../glib/gconvert.c:1574 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "\"%s\" не з'ÑўлÑецца абÑалютным адраÑам файла" + +#: ../glib/gconvert.c:1584 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "ÐÐ´Ñ€Ð°Ñ Ð¼ÑÑцовага файла \"%s\" не можа змÑшчаць знак \"#\"" + +#: ../glib/gconvert.c:1601 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "ÐÐ´Ñ€Ð°Ñ \"%s\" нÑправільны" + +#: ../glib/gconvert.c:1613 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Ðазва машыны Ñž адраÑе \"%s\" нÑправільнаÑ" + +#: ../glib/gconvert.c:1629 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "ÐÐ´Ñ€Ð°Ñ \"%s\" змÑшчае памылкова ÑÐºÑ€Ð°Ð½Ð°Ð²Ð°Ð½Ñ‹Ñ Ð·Ð½Ð°ÐºÑ–" + +#: ../glib/gconvert.c:1724 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "\"%s\" не з'ÑўлÑецца абÑалютнай Ñцежкай" + +#: ../glib/gconvert.c:1734 +msgid "Invalid hostname" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° машыны" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "AM" +msgstr "да поўднÑ" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "PM" +msgstr "паÑÐ»Ñ Ð¿Ð¾ÑžÐ´Ð½Ñ" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%2$d.%1$m.%3$y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:219 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%H:%M:%S" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "January" +msgstr "Ñтудзень" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "February" +msgstr "люты" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "March" +msgstr "Ñакавік" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "April" +msgstr "краÑавік" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "May" +msgstr "май" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "June" +msgstr "чÑрвень" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "July" +msgstr "ліпень" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "August" +msgstr "жнівень" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "September" +msgstr "вераÑень" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "October" +msgstr "каÑтрычнік" + +#: ../glib/gdatetime.c:252 +msgctxt "full month name" +msgid "November" +msgstr "ліÑтапад" + +#: ../glib/gdatetime.c:254 +msgctxt "full month name" +msgid "December" +msgstr "Ñнежань" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Ñту" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "лют" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Ñак" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "кра" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "May" +msgstr "май" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "чÑÑ€" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ліп" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "жні" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "вер" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "каÑ" + +#: ../glib/gdatetime.c:289 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ліÑ" + +#: ../glib/gdatetime.c:291 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Ñне" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Monday" +msgstr "панÑдзелак" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "аўторак" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Ñерада" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "чацвер" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Friday" +msgstr "пÑтніца" + +#: ../glib/gdatetime.c:316 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Ñубота" + +#: ../glib/gdatetime.c:318 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "нÑдзелÑ" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "пан" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "аўт" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ñер" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "чац" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "пÑÑ‚" + +#: ../glib/gdatetime.c:343 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Ñуб" + +#: ../glib/gdatetime.c:345 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "нÑдз" + +#: ../glib/gdir.c:120 ../glib/gdir.c:143 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÐºÑ€Ñ‹Ñ†ÑŒ каталог \"%s\": %s" + +#: ../glib/gfileutils.c:671 ../glib/gfileutils.c:759 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "Ðе ўдалоÑÑ Ð²Ñ‹Ð´Ð·ÐµÐ»Ñ–Ñ†ÑŒ %lu байт, каб прачытаць файл \"%s\"" +msgstr[1] "Ðе ўдалоÑÑ Ð²Ñ‹Ð´Ð·ÐµÐ»Ñ–Ñ†ÑŒ %lu байты, каб прачытаць файл \"%s\"" +msgstr[2] "Ðе ўдалоÑÑ Ð²Ñ‹Ð´Ð·ÐµÐ»Ñ–Ñ†ÑŒ %lu байтаў, каб прачытаць файл \"%s\"" + +#: ../glib/gfileutils.c:686 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ файл \"%s\": %s" + +#: ../glib/gfileutils.c:700 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Файл \"%s\" надта вÑлікі" + +#: ../glib/gfileutils.c:783 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ з файла \"%s\": %s" + +#: ../glib/gfileutils.c:834 ../glib/gfileutils.c:921 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÐºÑ€Ñ‹Ñ†ÑŒ файл \"%s\": %s" + +#: ../glib/gfileutils.c:851 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Ðе ўдалоÑÑ Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ñ†ÑŒ ÑÐ¿Ñ–Ñ Ð°Ñ‚Ñ€Ñ‹Ð±ÑƒÑ‚Ð°Ñž файла \"%s\": памылка fstat(): %s" + +#: ../glib/gfileutils.c:885 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÐºÑ€Ñ‹Ñ†ÑŒ файл \"%s\": памылка fdopen(): %s" + +#: ../glib/gfileutils.c:993 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"Ðе ўдалоÑÑ Ð·Ð¼Ñніць назву файла з \"%s\" на \"%s\": памылка g_rename(): %s" + +#: ../glib/gfileutils.c:1047 ../glib/gfileutils.c:1554 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Ðе ўдалоÑÑ Ñтварыць файл \"%s\": %s" + +#: ../glib/gfileutils.c:1071 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "Ðе ўдалоÑÑ Ð·Ð°Ð¿Ñ–Ñаць файл \"%s\": памылка write(): %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Ðе ўдалоÑÑ Ð·Ð°Ð¿Ñ–Ñаць файл \"%s\": памылка fsync(): %s" + +#: ../glib/gfileutils.c:1243 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "Ðе ўдалоÑÑ Ñцерці наÑўны файл \"%s\": памылка g_unlink(): %s" + +#: ../glib/gfileutils.c:1517 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Шаблон \"%s\" хібны, бо змÑшчае \"%s\"" + +#: ../glib/gfileutils.c:1530 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Шаблон \"%s\" не змÑшчае XXXXXX" + +#: ../glib/gfileutils.c:2058 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ Ñімвальную ÑпаÑылку \"%s\": %s" + +#: ../glib/gfileutils.c:2079 +msgid "Symbolic links not supported" +msgstr "Ð¡Ñ–Ð¼Ð²Ð°Ð»ÑŒÐ½Ñ‹Ñ ÑпаÑылкі не падтрымліваюцца" + +#: ../glib/giochannel.c:1418 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÐºÑ€Ñ‹Ñ†ÑŒ пераўтваральнік Ñа знаказбору \"%s\" у \"%s\": %s" + +#: ../glib/giochannel.c:1763 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" +"Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ ÑÑ‹Ñ€Ñ‹Ñ Ð´Ð°Ð½Ñ‹Ñ Ñž функцыі g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1810 ../glib/giochannel.c:2068 +#: ../glib/giochannel.c:2155 +msgid "Leftover unconverted data in read buffer" +msgstr "У буферы даных Ð´Ð»Ñ Ð¿ÐµÑ€Ð°ÑžÑ‚Ð²Ð°Ñ€ÑÐ½Ð½Ñ Ð·Ð°ÑталіÑÑ Ð½ÐµÐ°Ð¿Ñ€Ð°Ñ†Ð°Ð²Ð°Ð½Ñ‹Ñ Ð´Ð°Ð½Ñ‹Ñ" + +#: ../glib/giochannel.c:1891 ../glib/giochannel.c:1968 +msgid "Channel terminates in a partial character" +msgstr "Канал закончыўÑÑ Ð°Ð±Ñ€Ñзаным знакам" + +#: ../glib/giochannel.c:1954 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ ÑÑ‹Ñ€Ñ‹Ñ Ð´Ð°Ð½Ñ‹Ñ Ñž функцыі g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:722 +msgid "Valid key file could not be found in search dirs" +msgstr "У каталогах пошуку не знойдзена ключавых файлаў" + +#: ../glib/gkeyfile.c:758 +msgid "Not a regular file" +msgstr "ГÑта не звычайны файл" + +#: ../glib/gkeyfile.c:1158 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Ключавы файл змÑшчае радок \"%s\", Ñкі не з'ÑўлÑецца ані парай ключ-" +"значÑнне, ані групай, ані каментарыем" + +#: ../glib/gkeyfile.c:1215 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° групы: %s" + +#: ../glib/gkeyfile.c:1237 +msgid "Key file does not start with a group" +msgstr "Ключавы файл не пачынаецца з групы" + +#: ../glib/gkeyfile.c:1263 +#, c-format +msgid "Invalid key name: %s" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° ключа: %s" + +#: ../glib/gkeyfile.c:1290 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" +"Ключавы файл змÑшчае даныÑ, Ð·Ð°ÐºÐ°Ð´Ð°Ð²Ð°Ð½Ñ‹Ñ Ñк \"%s\". ГÑты ÑпоÑаб ÐºÐ°Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ðµ " +"падтрымліваецца." + +#: ../glib/gkeyfile.c:1533 ../glib/gkeyfile.c:1695 ../glib/gkeyfile.c:3073 +#: ../glib/gkeyfile.c:3139 ../glib/gkeyfile.c:3265 ../glib/gkeyfile.c:3398 +#: ../glib/gkeyfile.c:3540 ../glib/gkeyfile.c:3770 ../glib/gkeyfile.c:3837 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Ключавы файл не мае групы \"%s\"" + +#: ../glib/gkeyfile.c:1707 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Ключавы файл не мае ключа \"%s\"" + +#: ../glib/gkeyfile.c:1814 ../glib/gkeyfile.c:1930 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"Ключавы файл змÑшчае ключ \"%s\" Ñа значÑннем \"%s\", закадаваным не Ñк UTF-8" + +#: ../glib/gkeyfile.c:1834 ../glib/gkeyfile.c:1950 ../glib/gkeyfile.c:2319 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"Ключавы файл змÑшчае ключ \"%s\" Ñа значÑннем, Ñкое немагчыма зразумець." + +#: ../glib/gkeyfile.c:2536 ../glib/gkeyfile.c:2902 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"Ключавы файл змÑшчае ключ \"%s\" у групе \"%s\" Ñа значÑннем, Ñкое немагчыма " +"зразумець." + +#: ../glib/gkeyfile.c:2614 ../glib/gkeyfile.c:2690 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "Ключ \"%s\" у групе \"%s\" мае значÑнне \"%s\", хоць чакалаÑÑ %s" + +#: ../glib/gkeyfile.c:3088 ../glib/gkeyfile.c:3280 ../glib/gkeyfile.c:3848 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Ключавы файл не мае ключа \"%s\" у групе \"%s\"" + +#: ../glib/gkeyfile.c:4080 +msgid "Key file contains escape character at end of line" +msgstr "Ключавы файл змÑшчае знак ÑÐºÑ€Ð°Ð½Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ð°Ð¿Ñ€Ñ‹ÐºÐ°Ð½Ñ†Ñ‹ радка" + +#: ../glib/gkeyfile.c:4102 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Ключавы файл змÑшчае хібную кіроўную паÑлÑдоўнаÑць \"%s\"" + +#: ../glib/gkeyfile.c:4244 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Ðе ўдалоÑÑ ÑžÑпрынÑць значÑнне \"%s\" Ñк лік." + +#: ../glib/gkeyfile.c:4258 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "ЦÑлае значÑнне \"%s\" не Ñž дыÑпазоне" + +#: ../glib/gkeyfile.c:4291 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Ðе ўдалоÑÑ ÑžÑпрынÑць значÑнне \"%s\" Ñк дробавы лік." + +#: ../glib/gkeyfile.c:4315 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Ðе ўдалоÑÑ ÑžÑпрынÑць значÑнне \"%s\" Ñк булева." + +#: ../glib/gmappedfile.c:130 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "" +"Ðе ўдалоÑÑ Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ñ†ÑŒ ÑÐ¿Ñ–Ñ Ð°Ñ‚Ñ€Ñ‹Ð±ÑƒÑ‚Ð°Ñž файла \"%s%s%s%s\": памылка fstat(): %s" + +#: ../glib/gmappedfile.c:196 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Ðе ўдалоÑÑ Ð°Ð»ÑŽÑтраваць файл %s%s%s%s у памÑці: памылка mmap(): %s" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Ðе ўдалоÑÑ Ð°Ð´ÐºÑ€Ñ‹Ñ†ÑŒ файл \"%s\": памылка open(): %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Памылка Ñž радку %d, знак %d: " + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "ÐÑправільны UTF-8 Ñ‚ÑкÑÑ‚ у назве - хібны \"%s\"" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "\"%s\" не з'ÑўлÑецца правільнай назвай" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "\"%s\" не з'ÑўлÑецца правільнай назвай: \"%c\"" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "Памылка Ñž радку %d: %s" + +#: ../glib/gmarkup.c:682 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð°Ð±Ñ€Ð°Ñ†ÑŒ \"%-.*s\", Ñкое муÑіла быць лікам у адÑылцы да знака " +"(напрыклад, \"ê\"). Мабыць, лік надта вÑлікі." + +#: ../glib/gmarkup.c:694 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"ÐдÑылка да знака не Ñкончана кропкай з коÑкай. Відаць, вы ўжылі знак \"&\", " +"не плануючы Ñтвараць новы знакавы Ñлемент. Каб пазбегнуць такіх паводзін, " +"пішыце знак \"&\" Ñк \"&\"." + +#: ../glib/gmarkup.c:720 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "ÐдÑылка да знака \"%-.*s\" не азначае дазволенага знака" + +#: ../glib/gmarkup.c:758 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Ðапатканы пуÑты знакавы Ñлемент \"&;\". Ð”Ð°Ð·Ð²Ð¾Ð»ÐµÐ½Ñ‹Ñ Ñлементы: \"&\", " +"\""\", \"<\", \">\" Ñ– \"'\"." + +#: ../glib/gmarkup.c:766 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Ðазва знакавага Ñлемента \"%-.*s\" невÑдомаÑ." + +#: ../glib/gmarkup.c:771 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Знакавы Ñлемент не Ñкончаны кропкай з коÑкай. Відаць, вы ўжылі знак \"&\", " +"не плануючы Ñтвараць новы знакавы Ñлемент. Каб пазбегнуць такіх паводзін, " +"пішыце знак \"&\" Ñк \"&\"." + +#: ../glib/gmarkup.c:1119 +msgid "Document must begin with an element (e.g. )" +msgstr "Дакумент муÑіць пачынацца з Ñлемента (напрыклад, з )." + +#: ../glib/gmarkup.c:1159 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"Знак \"%s\" забаронены паÑÐ»Ñ Ð·Ð½Ð°ÐºÐ° \"<\". Ðазва Ñлемента не можа пачынацца з " +"гÑтага знака." + +#: ../glib/gmarkup.c:1227 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Ðапатканы нечаканы \"%s\" замеÑÑ‚ чаканага знака \">\", Ñкі б закрыў Ñ‚Ñг \"%s" +"\" пуÑтога Ñлемента." + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Ðапатканы нечаканы \"%s\" замеÑÑ‚ чаканага знака \"=\" паÑÐ»Ñ Ð½Ð°Ð·Ð²Ñ‹ атрыбута " +"\"%s\" Ñлемента \"%s\"." + +#: ../glib/gmarkup.c:1352 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Ðапатканы нечаканы \"%s\" замеÑÑ‚ аднаго з чаканых знакаў \">\" або \"/\", " +"Ñкі б закрыў пачатковы Ñ‚Ñг Ñлемента \"%s\", або замеÑÑ‚ магчымага атрыбута. " +"Магчыма, вы ўжылі хібны знак у назве атрыбута." + +#: ../glib/gmarkup.c:1396 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Ðапатканы нечаканы \"%s\" замеÑÑ‚ чаканага знака двукоÑÑÑÑž паÑÐ»Ñ Ð·Ð½Ð°ÐºÐ° " +"роўнаÑці Ð¿Ð°Ð´Ñ‡Ð°Ñ Ð°Ð·Ð½Ð°Ñ‡ÑÐ½Ð½Ñ Ð°Ñ‚Ñ€Ñ‹Ð±ÑƒÑ‚Ð° \"%s\" Ñлемента \"%s\"." + +#: ../glib/gmarkup.c:1529 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"Знак \"%s\" не дазволены Ð´Ð»Ñ Ð·Ð¼ÑшчÑÐ½Ð½Ñ Ð¿Ð°ÑÐ»Ñ ÐºÐ°Ð½Ñ†Ð°Ð²Ð¾Ð¹ назвы Ñлемента \"%s\". " +"У гÑтым меÑцы дазволены толькі знак \">\"." + +#: ../glib/gmarkup.c:1576 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Элемент \"%s\" закрыты, Ñ– ўжо больш нÑма адкрытых Ñлементаў." + +#: ../glib/gmarkup.c:1585 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Элемент \"%s\" закрыты, але цÑпер адкрытым заÑтаецца Ñлемент \"%s\"." + +#: ../glib/gmarkup.c:1753 +msgid "Document was empty or contained only whitespace" +msgstr "Дакумент быў пуÑтым або змÑшчаў толькі Ð¿Ñ€Ð°Ð±ÐµÐ»ÑŒÐ½Ñ‹Ñ Ð·Ð½Ð°ÐºÑ–." + +#: ../glib/gmarkup.c:1767 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Дакумент нечакана ÑкончыўÑÑ Ð°Ð´Ñ€Ð°Ð·Ñƒ паÑÐ»Ñ Ð¿Ð°Ñ‡Ð°Ñ‚ÐºÐ¾Ð²Ð°Ð³Ð° знака \"<\"." + +#: ../glib/gmarkup.c:1775 ../glib/gmarkup.c:1820 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Дакумент нечакана ÑкончыўÑÑ, Ñ…Ð°Ñ†Ñ ÑÑˆÑ‡Ñ Ð·Ð°ÑталіÑÑ Ð°Ð´ÐºÑ€Ñ‹Ñ‚Ñ‹Ñ Ñлементы. Ðпошнім " +"адкрытым Ñлементам з'ÑўлÑецца \"%s\"." + +#: ../glib/gmarkup.c:1783 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Дакумент нечакана ÑкончыўÑÑ, Ñ…Ð°Ñ†Ñ Ð´Ð°Ð»ÐµÐ¹ муÑÑ–Ñž быць канцавы знак \">\", Ñкі б " +"закрыў Ñ‚Ñг <%s/>." + +#: ../glib/gmarkup.c:1789 +msgid "Document ended unexpectedly inside an element name" +msgstr "Дакумент нечакана ÑкончыўÑÑ Ð¿Ð°ÑÑрод назвы Ñлемента." + +#: ../glib/gmarkup.c:1795 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Дакумент нечакана ÑкончыўÑÑ Ð¿Ð°ÑÑрод назвы атрыбута." + +#: ../glib/gmarkup.c:1800 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Дакумент нечакана ÑкончыўÑÑ Ð¿Ð°ÑÑрод Ñ‚Ñга, Ñкі адкрывае Ñлемент." + +#: ../glib/gmarkup.c:1806 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Дакумент нечакана ÑкончыўÑÑ Ð¿Ð°ÑÐ»Ñ Ð·Ð½Ð°ÐºÐ° роўнаÑці, змешчанага паÑÐ»Ñ Ð½Ð°Ð·Ð²Ñ‹ " +"атрыбута. ЗначÑнне атрыбута не вызначана." + +#: ../glib/gmarkup.c:1813 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Дакумент нечакана ÑкончыўÑÑ Ð¿Ð°ÑÑрод значÑÐ½Ð½Ñ Ð°Ñ‚Ñ€Ñ‹Ð±ÑƒÑ‚Ð°." + +#: ../glib/gmarkup.c:1829 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Дакумент нечакана ÑкончыўÑÑ Ð¿Ð°ÑÑрод Ñ‚Ñга, Ñкі закрывае Ñлемент \"%s\"." + +#: ../glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Дакумент нечакана ÑкончыўÑÑ Ð¿Ð°ÑÑрод ÐºÐ°Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ‹Ñ Ð°Ð±Ð¾ інÑтрукцыі Ð´Ð»Ñ " +"апрацоўваннÑ." + +#: ../glib/goption.c:754 +msgid "Usage:" +msgstr "Правілы выкарыÑтаннÑ:" + +#: ../glib/goption.c:754 +msgid "[OPTION...]" +msgstr "[ОПЦЫЯ...]" + +#: ../glib/goption.c:870 +msgid "Help Options:" +msgstr "Опцыі дапамогі:" + +#: ../glib/goption.c:871 +msgid "Show help options" +msgstr "Паказаць опцыі дапамогі" + +#: ../glib/goption.c:877 +msgid "Show all help options" +msgstr "Паказаць уÑе опцыі дапамогі" + +#: ../glib/goption.c:939 +msgid "Application Options:" +msgstr "Опцыі праграмы:" + +#: ../glib/goption.c:1003 ../glib/goption.c:1073 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð°Ð±Ñ€Ð°Ñ†ÑŒ цÑлае значÑнне \"%s\" Ð´Ð»Ñ %s" + +#: ../glib/goption.c:1013 ../glib/goption.c:1081 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "ЦÑлае значÑнне \"%s\" Ð´Ð»Ñ %s не Ñž дыÑпазоне" + +#: ../glib/goption.c:1038 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" +"Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð°Ð±Ñ€Ð°Ñ†ÑŒ дробавае значÑнне падвойнай дакладнаÑці \"%s\" Ð´Ð»Ñ %s" + +#: ../glib/goption.c:1046 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Дробавае значÑнне падвойнай дакладнаÑці \"%s\" Ð´Ð»Ñ %s не Ñž дыÑпазоне" + +#: ../glib/goption.c:1309 ../glib/goption.c:1388 +#, c-format +msgid "Error parsing option %s" +msgstr "Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð°Ð±Ñ€Ð°Ñ†ÑŒ опцыю %s" + +#: ../glib/goption.c:1419 ../glib/goption.c:1532 +#, c-format +msgid "Missing argument for %s" +msgstr "ÐдÑутнічае аргумент да %s" + +#: ../glib/goption.c:1985 +#, c-format +msgid "Unknown option %s" +msgstr "ÐевÑÐ´Ð¾Ð¼Ð°Ñ Ð¾Ð¿Ñ†Ñ‹Ñ %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "пашкоджаны аб'ект" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "ÑƒÐ½ÑƒÑ‚Ñ€Ð°Ð½Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° або пашкоджаны аб'ект" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "памÑць вычарпана" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "даÑÑгнута абмежаванне на колькаÑць галін пошуку" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"шаблон змÑшчае Ñкладнікі, ÑÐºÑ–Ñ Ð½Ðµ падтрымліваюцца Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ нÑпоўных " +"адпаведнікаў" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"Ð·Ð²Ð°Ñ€Ð¾Ñ‚Ð½Ñ‹Ñ Ð°Ð´Ñылкі Ñк умовы не падтрымліваюцца Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ нÑпоўных " +"адпаведнікаў" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "даÑÑгнута абмежаванне на глыбіню Ñ€ÑкурÑÑ–Ñ–" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "памылковае ÑпалучÑнне ÑцÑжкоў новага радка" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "хібны зрух" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "кароткі utf8" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "Ñ€ÑкурÑіўны цыкл" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "невÑÐ´Ð¾Ð¼Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ°" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "знак \"\\\" напрыканцы шаблона" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "знак \"\\c\" напрыканцы шаблона" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "невÑдомы знак паÑÐ»Ñ \"\\\"" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "Ð½ÐµÑžÐ¿Ð°Ñ€Ð°Ð´ÐºÐ°Ð²Ð°Ð½Ñ‹Ñ Ð»Ñ–ÐºÑ– Ñž квантары {}" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "надта вÑлікі лік у квантары {}" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "адÑутнічае канцавы знак \"]\" клаÑа знакаў" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "Ñ…Ñ–Ð±Ð½Ð°Ñ ÐºÑ–Ñ€Ð¾ÑžÐ½Ð°Ñ Ð¿Ð°ÑлÑдоўнаÑць у клаÑе знакаў" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "дыÑпазон у клаÑе знакаў па-за дапушчальнымі межамі" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "нÑма што паўтараць" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "нечаканы паўтор" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "невÑдомы знак паÑÐ»Ñ \"(?\" ці \"(?-\"" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX-клаÑÑ‹ з назвамі падтрымліваюцца толькі ўнутры іншага клаÑа" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "адÑутны канцавы знак \")\"" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "адÑылка да адÑутнага падшаблона" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "паÑÐ»Ñ ÐºÐ°Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ‹Ñ Ð°Ð´Ñутнічае знак \")\"" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "надта доўгі Ñ€ÑгулÑрны выраз" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "не ўдалоÑÑ Ð·Ð°Ð¹Ð¼ÐµÑ†ÑŒ памÑць" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr "знак \")\" не мае адпаведнага пачатковага знака \"(\"" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "перапаўненне коду" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "невÑдомы знак паÑÐ»Ñ \"(?<\"" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "праверка з азіраннем назад не мае Ñталай даўжыні" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "паÑÐ»Ñ \"(?(\" змешчаны хібны лік ці назва" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "ÑƒÐ¼Ð¾ÑžÐ½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð° змÑшчае больш за дзве галіны" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "паÑÐ»Ñ \"(?(\" чакалі праверкі" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "паÑÐ»Ñ \"(?R\" Ñ– \"(?[+-]лічбы\" муÑіць Ñ–Ñці знак \")\"" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "назва невÑдомага POSIX-клаÑа" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "Ñлементы Ð¿Ð°Ñ€Ð°Ð´ÐºÐ°Ð²Ð°Ð½Ð½Ñ POSIX не падтрымліваюцца" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "надта вÑлікае значÑнне знака Ñž паÑлÑдоўнаÑці \"\\x{...}\"" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "Ñ…Ñ–Ð±Ð½Ð°Ñ ÑžÐ¼Ð¾Ð²Ð° \"(?(0)\"" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\"\\C\" забаронена Ð´Ð»Ñ Ð¿Ñ€Ð°Ð²ÐµÑ€ÐºÑ– з азіраннем назад" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "паÑлÑдоўнаÑці \\L, \\l, \\N{назва}, \\U Ñ– \\u не падтрымліваюцца" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "Ñ€ÑкурÑÑ–Ñ Ð¼Ð°Ð³Ð»Ð° ніколі не Ñкончыцца" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "невÑдомы знак паÑÐ»Ñ \"(?P\"" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "у назве падшаблона адÑутнічае канцавы Ñлемент" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "два падшаблоны маюць аднолькавую назву" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "Ñ…Ñ–Ð±Ð½Ð°Ñ Ð¿Ð°ÑлÑдоўнаÑць \"\\P\" ці \"\\p\"" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "назва невÑдомай улаÑціваÑці паÑÐ»Ñ \"\\P\" ці \"\\p\"" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "надта Ð´Ð¾ÑžÐ³Ð°Ñ Ð½Ð°Ð·Ð²Ð° падшаблона (дазволена не больш за 32 знакі)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "надта шмат падшаблонаў з назвамі (дазволена не больш за 10 тыÑ.)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "ваÑьмÑрковае значÑнне большае за \\377" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "пераўпоўнена Ð¿Ñ€Ð°Ñ†Ð¾ÑžÐ½Ð°Ñ Ð¿Ñ€Ð°Ñтора Ð´Ð»Ñ ÐºÐ°Ð¼Ð¿Ñ–Ð»Ñцыі" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "раней правераны падшаблон з адÑылкай не знойдзены" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "Група DEFINE змÑшчае больш за адну галіну" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "ÐÑўзгоднены выбар NEWLINE" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"паÑÐ»Ñ \"\\g\" адÑутнічае назва ці лік у дужках (круглых або вуглавых) ці Ñž " +"двукоÑÑÑ–, або проÑта лік" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "Ð¿Ñ€Ð°Ð½ÑƒÐ¼Ð°Ñ€Ð°Ð²Ð°Ð½Ð°Ñ Ð°Ð´Ñылка муÑіць быць ненулÑвой" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "Ð´Ð»Ñ (*ACCEPT), (*FAIL) ці (*COMMIT) не Ð´Ð°Ð·Ð²Ð¾Ð»ÐµÐ½Ñ‹Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñ‹" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) не апазнаны" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "надта вÑлікі лік" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "паÑÐ»Ñ \"(?&\" адÑутнічае назва падшаблона" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "паÑÐ»Ñ \"(?+\" чакалі лічбу" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"\"]\" з'ÑўлÑецца хібным знакам даных у Ñ€Ñжыме ÑумÑшчальнаÑці з JavaScript" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "Ñ€Ð¾Ð·Ð½Ñ‹Ñ Ð½Ð°Ð·Ð²Ñ‹ Ð´Ð»Ñ Ð¿Ð°Ð´ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ñž з аднолькавым нумарам забароненыÑ" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) муÑіць прымаць аргумент" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "паÑÐ»Ñ \"\\c\" муÑіць быць ASCII-знак" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"паÑÐ»Ñ \"\\k\" адÑутнічае назва Ñž дужках (круглых ці вуглавых) або Ñž двукоÑÑÑ–" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "\"\\N\" не падтрымліваецца Ñž клаÑе" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "надта шмат адÑылак наперад" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "надта Ð´Ð¾ÑžÐ³Ð°Ñ Ð½Ð°Ð·Ð²Ð° Ñž (*MARK), (*PRUNE), (*SKIP) ці (*THEN)" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "надта вÑлікае значÑнне знака Ñž паÑлÑдоўнаÑці \"\\u....\"" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1914 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Памылка Ð¿Ð°Ð´Ñ‡Ð°Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ адпаведнікаў да Ñ€ÑгулÑрнага выразу %s: %s" + +#: ../glib/gregex.c:1311 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" +"ÐŸÑ€Ð°Ð³Ñ€Ð°Ð¼Ð½Ð°Ñ Ð±Ñ–Ð±Ð»Ñ–ÑÑ‚Ñка PCRE ÑкампілÑÐ²Ð°Ð½Ð°Ñ Ð±ÐµÐ· падтрымкі ÐºÐ°Ð´Ð°Ð²Ð°Ð½Ð½Ñ UTF-8." + +#: ../glib/gregex.c:1315 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"ÐŸÑ€Ð°Ð³Ñ€Ð°Ð¼Ð½Ð°Ñ Ð±Ñ–Ð±Ð»Ñ–ÑÑ‚Ñка PCRE ÑкампілÑÐ²Ð°Ð½Ð°Ñ Ð±ÐµÐ· падтрымкі ўлаÑціваÑцÑÑž UTF-8." + +#: ../glib/gregex.c:1323 +msgid "PCRE library is compiled with incompatible options" +msgstr "ÐŸÑ€Ð°Ð³Ñ€Ð°Ð¼Ð½Ð°Ñ Ð±Ñ–Ð±Ð»Ñ–ÑÑ‚Ñка PCRE ÑкампілÑÐ²Ð°Ð½Ð°Ñ Ð· неÑумÑшчальнымі опцыÑмі" + +#: ../glib/gregex.c:1382 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Памылка Ð¿Ð°Ð´Ñ‡Ð°Ñ ÐºÐ°Ð¼Ð¿Ñ–Ð»ÑÐ²Ð°Ð½Ð½Ñ Ñ€ÑгулÑрнага выразу \"%s\" на знаку %d: %s" + +#: ../glib/gregex.c:1424 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Памылка Ð¿Ð°Ð´Ñ‡Ð°Ñ Ð°Ð¿Ñ‚Ñ‹Ð¼Ñ–Ð·Ð°Ð²Ð°Ð½Ð½Ñ Ñ€ÑгулÑрнага выразу \"%s\": %s" + +#: ../glib/gregex.c:2346 +msgid "hexadecimal digit or '}' expected" +msgstr "чакалі шаÑнаццатковую лічбу або знак \"}\"" + +#: ../glib/gregex.c:2362 +msgid "hexadecimal digit expected" +msgstr "чакалі шаÑнаццатковую лічбу" + +#: ../glib/gregex.c:2402 +msgid "missing '<' in symbolic reference" +msgstr "адÑутнічае знак \"<\" у Ñімвальнай адÑылцы" + +#: ../glib/gregex.c:2411 +msgid "unfinished symbolic reference" +msgstr "нÑÑÐºÐ¾Ð½Ñ‡Ð°Ð½Ð°Ñ ÑÑ–Ð¼Ð²Ð°Ð»ÑŒÐ½Ð°Ñ Ð°Ð´Ñылка" + +#: ../glib/gregex.c:2418 +msgid "zero-length symbolic reference" +msgstr "ÑÑ–Ð¼Ð²Ð°Ð»ÑŒÐ½Ð°Ñ Ð°Ð´Ñылка нулÑвой даўжыні" + +#: ../glib/gregex.c:2429 +msgid "digit expected" +msgstr "чакалі лічбу" + +#: ../glib/gregex.c:2447 +msgid "illegal symbolic reference" +msgstr "Ð·Ð°Ð±Ð°Ñ€Ð¾Ð½ÐµÐ½Ð°Ñ ÑÑ–Ð¼Ð²Ð°Ð»ÑŒÐ½Ð°Ñ Ð°Ð´Ñылка" + +#: ../glib/gregex.c:2509 +msgid "stray final '\\'" +msgstr "нÑправільна змешчаны канцавы знак \"\\\"" + +#: ../glib/gregex.c:2513 +msgid "unknown escape sequence" +msgstr "невÑÐ´Ð¾Ð¼Ð°Ñ ÐºÑ–Ñ€Ð¾ÑžÐ½Ð°Ñ Ð¿Ð°ÑлÑдоўнаÑць" + +#: ../glib/gregex.c:2523 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "Памылка Ð¿Ð°Ð´Ñ‡Ð°Ñ Ñ€Ð°Ð·Ð±Ð¾Ñ€Ñƒ Ñ‚ÑкÑту замены \"%s\" у знаку %lu: %s" + +#: ../glib/gshell.c:88 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Цытаваны Ñ‚ÑкÑÑ‚ не пачынаецца з двукоÑÑÑ" + +#: ../glib/gshell.c:178 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Самотнае двукоÑÑе Ñž загадным радку ці Ñž іншым цытаваным Ñ‚ÑкÑце" + +#: ../glib/gshell.c:574 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "ТÑкÑÑ‚ (\"%s\") абрÑзаны адразу паÑÐ»Ñ Ð·Ð½Ð°ÐºÐ° \"\\\"." + +#: ../glib/gshell.c:581 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "ТÑкÑÑ‚ (\"%2$s\") абрÑзаны да парнага двукоÑÑÑ Ð´Ð»Ñ %1$c." + +#: ../glib/gshell.c:593 +msgid "Text was empty (or contained only whitespace)" +msgstr "ТÑкÑÑ‚ пуÑты (або змÑшчаў толькі Ð¿Ñ€Ð°Ð±ÐµÐ»ÑŒÐ½Ñ‹Ñ Ð·Ð½Ð°ÐºÑ–)." + +#: ../glib/gspawn.c:202 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ Ð´Ð°Ð½Ñ‹Ñ Ð¿Ñ€Ð°Ñ†ÑÑу-нашчадка (%s)" + +#: ../glib/gspawn.c:345 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"ÐÐµÑ‡Ð°ÐºÐ°Ð½Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° Ñž функцыі select() Ð¿Ð°Ð´Ñ‡Ð°Ñ Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ñ‹Ñ… працÑÑу-нашчадка " +"(%s)" + +#: ../glib/gspawn.c:430 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "ÐÐµÑ‡Ð°ÐºÐ°Ð½Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° Ñž waitpid() (%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "ПрацÑÑ-нашчадак выйшаў, вÑрнуўшы код %ld" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "ПрацÑÑ-нашчадак забіты Ñігналам %ld" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "ПрацÑÑ-нашчадак Ñпынены Ñігналам %ld" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "ПрацÑÑ-нашчадак Ñкончыў працу надзвычайным чынам" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ†ÑŒ з канала ÑувÑзі з нашчадкам (%s)" + +#: ../glib/gspawn.c:1344 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Ðе ўдалоÑÑ Ñ€Ð°Ð·Ð³Ð°Ð»Ñ–Ð½Ð°Ð²Ð°Ñ†ÑŒ працÑÑ (%s)" + +#: ../glib/gspawn.c:1493 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Ðе ўдалоÑÑ Ð¿ÐµÑ€Ð°Ð¹Ñці Ñž каталог \"%s\" (%s)" + +#: ../glib/gspawn.c:1503 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Ðе ўдалоÑÑ Ð·Ð°Ð¿ÑƒÑціць працÑÑ-нашчадак \"%s\" (%s)" + +#: ../glib/gspawn.c:1513 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Ðе ўдалоÑÑ Ð¿ÐµÑ€Ð°Ð½Ð°ÐºÑ–Ñ€Ð°Ð²Ð°Ñ†ÑŒ вывад ці ўвод працÑÑу-нашчадка (%s)" + +#: ../glib/gspawn.c:1522 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Ðе ўдалоÑÑ Ð°Ð´Ð³Ð°Ð»Ñ–Ð½Ð°Ð²Ð°Ñ†ÑŒ працÑÑ-нашчадак (%s)" + +#: ../glib/gspawn.c:1530 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "ÐевÑÐ´Ð¾Ð¼Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° запуÑку працÑÑу-нашчадка \"%s\"" + +#: ../glib/gspawn.c:1554 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ даÑтатковую колькаÑць даных з канала ÑувÑзі з нашчадкам " +"(%s)" + +#: ../glib/gspawn.c:1627 ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Ðе ÑžÑталÑваць Ñтварыць канал ÑувÑзі з працÑÑам-нашчадкам (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "Ðе ўдалоÑÑ Ð¿Ñ€Ð°Ñ‡Ñ‹Ñ‚Ð°Ñ†ÑŒ Ð´Ð°Ð½Ñ‹Ñ Ð°Ð´ працÑÑу-нашчадка" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Ðе ўдалоÑÑ Ð·Ð°Ð¿ÑƒÑціць працÑÑ-нашчадак (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð½Ð°Ð·Ð²Ð° праграмы: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "хібны ланцужок у маÑіве аргументаў у пазіцыі %d: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "хібны ланцужок у аÑÑроддзі: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "хібны рабочы каталог: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Ðе ўдалоÑÑ Ð·Ð°Ð¿ÑƒÑціць дапаможную праграму (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"ÐÐµÑ‡Ð°ÐºÐ°Ð½Ð°Ñ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° Ñž функцыі g_io_channel_win32_poll() Ð¿Ð°Ð´Ñ‡Ð°Ñ Ñ‡Ñ‹Ñ‚Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ñ‹Ñ… " +"працÑÑу-нашчадка" + +#: ../glib/gutf8.c:907 +msgid "Character out of range for UTF-8" +msgstr "Знак не Ñž дыÑпазоне UTF-8" + +#: ../glib/gutf8.c:1007 ../glib/gutf8.c:1016 ../glib/gutf8.c:1146 +#: ../glib/gutf8.c:1155 ../glib/gutf8.c:1294 ../glib/gutf8.c:1390 +msgid "Invalid sequence in conversion input" +msgstr "Ð¥Ñ–Ð±Ð½Ð°Ñ Ð¿Ð°ÑлÑдоўнаÑць на ўваходзе пераўтварÑннÑ" + +#: ../glib/gutf8.c:1305 ../glib/gutf8.c:1401 +msgid "Character out of range for UTF-16" +msgstr "Знак не Ñž дыÑпазоне UTF-16" + +#: ../glib/gutils.c:2179 ../glib/gutils.c:2206 ../glib/gutils.c:2310 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u байт" +msgstr[1] "%u байты" +msgstr[2] "%u байтаў" + +#: ../glib/gutils.c:2185 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f Кбайт" + +#: ../glib/gutils.c:2187 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f Мбайт" + +#: ../glib/gutils.c:2190 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f Гбайт" + +#: ../glib/gutils.c:2193 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f Тбайт" + +#: ../glib/gutils.c:2196 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f Пбайт" + +#: ../glib/gutils.c:2199 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f Эбайт" + +#: ../glib/gutils.c:2212 +#, c-format +msgid "%.1f kB" +msgstr "%.1f кб" + +#: ../glib/gutils.c:2215 ../glib/gutils.c:2328 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Мб" + +#: ../glib/gutils.c:2218 ../glib/gutils.c:2333 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Гб" + +#: ../glib/gutils.c:2220 ../glib/gutils.c:2338 +#, c-format +msgid "%.1f TB" +msgstr "%.1f Тб" + +#: ../glib/gutils.c:2223 ../glib/gutils.c:2343 +#, c-format +msgid "%.1f PB" +msgstr "%.1f Пб" + +#: ../glib/gutils.c:2226 ../glib/gutils.c:2348 +#, c-format +msgid "%.1f EB" +msgstr "%.1f Эб" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2263 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s байт" +msgstr[1] "%s байты" +msgstr[2] "%s байтаў" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2323 +#, c-format +msgid "%.1f KB" +msgstr "%.1f кб" + +msgctxt "full month name with day" +msgid "January" +msgstr "ÑтудзенÑ" + +msgctxt "full month name with day" +msgid "February" +msgstr "лютага" + +msgctxt "full month name with day" +msgid "March" +msgstr "Ñакавіка" + +msgctxt "full month name with day" +msgid "April" +msgstr "краÑавіка" + +msgctxt "full month name with day" +msgid "May" +msgstr "маÑ" + +msgctxt "full month name with day" +msgid "June" +msgstr "чÑрвенÑ" + +msgctxt "full month name with day" +msgid "July" +msgstr "ліпенÑ" + +msgctxt "full month name with day" +msgid "August" +msgstr "жніўнÑ" + +msgctxt "full month name with day" +msgid "September" +msgstr "вераÑнÑ" + +msgctxt "full month name with day" +msgid "October" +msgstr "каÑтрычніка" + +msgctxt "full month name with day" +msgid "November" +msgstr "ліÑтапада" + +msgctxt "full month name with day" +msgid "December" +msgstr "ÑнежнÑ" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Ñту" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "лют" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Ñак" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "кра" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "маÑ" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "чÑÑ€" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "ліп" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "жні" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "вер" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "каÑ" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ліÑ" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Ñне" diff --git a/po/be@latin.po b/po/be@latin.po new file mode 100644 index 0000000..11ed1c0 --- /dev/null +++ b/po/be@latin.po @@ -0,0 +1,4125 @@ +# PierakÅ‚ad glib.HEAD. +# Copyright (C) 2007 THE glib.HEAD'S COPYRIGHT HOLDER +# Alaksandar Navicki , 2007. www.lacinka.org +# www.lacinka.org +# +msgid "" +msgstr "" +"Project-Id-Version: glib HEAD\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2008-02-16 23:33+0200\n" +"Last-Translator: Ihar Hrachyshka \n" +"Language-Team: Belarusian Latin \n" +"Language: be@latin\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +# glib/gmarkup.c:1120 +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "NieÄakany atrybut '%s' dla elementu '%s'" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Atrybut '%s' elementu '%s' nia znojdzieny" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "NieÄakany znaÄnik '%s', spadziavalisia znaÄnika '%s'" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "NieÄakany znaÄnik '%s' unutry '%s'" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "NiemahÄyma znajÅ›ci pravilnaha fajÅ‚u zakÅ‚adak u katalohach źviestak" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "ZakÅ‚adka dla URI '%s' užo isnuje" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Dla URI '%s' nia znojdziena zakÅ‚adak" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Nie akreÅ›leny typ MIME Å­ zakÅ‚adcy dla URI '%s'" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Nie akreÅ›lili pryvatnaha Å›ciažka Å­ zakÅ‚adcy dla URI '%s'" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Nie akreÅ›lili hrup u zakÅ‚adcy dla URI '%s'" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" +"Nivodnaja aplikacyja pad nazvaj '%s' nie zarehistravaÅ‚a zakÅ‚adki dla '%s'" + +# glib/gfileutils.c:745 +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Prablema z razhortvaÅ„niem radka zapusku '%s' z URI '%s'" + +# glib/gconvert.c:390 +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Kanversija naboru znakaÅ­ '%s' na '%s' nie padtrymlivajecca" + +# glib/gconvert.c:394 +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "NiemahÄyma adÄynić kanverter z '%s' na '%s'" + +# glib/gconvert.c:592 glib/gconvert.c:882 glib/giochannel.c:1282 +# glib/giochannel.c:1324 glib/giochannel.c:2163 glib/gutf8.c:875 +# glib/gutf8.c:1320 +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Niapravilnaja paÅ›ladoÅ­naść bajtaÅ­ na Å­vachodzie kanversii" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "PamyÅ‚ka padÄas kanversii: %s" + +# glib/gconvert.c:615 glib/gutf8.c:871 glib/gutf8.c:1071 glib/gutf8.c:1212 +# glib/gutf8.c:1316 +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "NiapoÅ­ny znak u kancy Å­vachodnaha radka" + +# glib/gconvert.c:788 +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "NiemahÄyma pierakanvertavać surahat znaku '%s' na nabor znakaÅ­ '%s'" + +# glib/gconvert.c:1593 +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" +"URI '%s' nie źjaÅ­lajucca absalutnym URI vykarystaÅ„nia \"fajÅ‚avaj\" schiemy" + +# glib/gconvert.c:1603 +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "URI '%s' miascovaha fajÅ‚u nia moža Å­kluÄać '#'" + +# glib/gconvert.c:1620 +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' niapravilny" + +# glib/gconvert.c:1632 +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Niapravilnaja nazva hostu Å­ URI '%s' " + +# glib/gconvert.c:1648 +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' utrymlivaje nieadpaviedna cytavanyja znaki" + +# glib/gconvert.c:1719 +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Åšciežka '%s nie źjaÅ­lajecca absalutnaj" + +# glib/gconvert.c:1729 +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Niapravilnaja nazva kamputara" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "StudzieÅ„" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Luty" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Sakavik" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "Krasavik" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "TravieÅ„" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "ÄŒervieÅ„" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "LipieÅ„" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Stu" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Lut" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Sak" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Kra" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Tra" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ÄŒer" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Lip" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "PaniadzieÅ‚ak" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "AÅ­torak" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Sierada" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ÄŒaćvier" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Piatnica" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Subota" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Niadziela" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Pan" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "AÅ­t" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Sie" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ÄŒać" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Pia" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sub" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Nia" + +# glib/gdir.c:79 +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "PamyÅ‚ka pry adÄynieÅ„ni katalohu '%s': %s" + +# glib/gfileutils.c:337 glib/gfileutils.c:402 +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Nie atrymaÅ‚asia raźmierkavać %lu bajtaÅ­ dla adÄytaÅ„nia fajÅ‚u \"%s\"" + +# glib/gfileutils.c:348 +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +# glib/gfileutils.c:426 +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "PamyÅ‚ka ÄytaÅ„nia z fajÅ‚u '%s': %s" + +# glib/gfileutils.c:465 glib/gfileutils.c:533 +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "NiemahÄyma adÄynić fajÅ‚ '%s': %s" + +# glib/gfileutils.c:479 +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" +"NiemahÄyma atrymać atrybuty fajÅ‚u '%s': funkcyja fstat() vyvieÅ‚a pamyÅ‚ku: %s" + +# glib/gfileutils.c:505 +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "NiemahÄyma adÄynić fajÅ‚ '%s': funkcyja fdopen() vyvieÅ‚a pamyÅ‚ku: %s" + +# glib/gfileutils.c:505 +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"NiemahÄyma źmianic nazvu fajÅ‚u '%s' na '%s': funkcyja g_rename() vyvieÅ‚a " +"pamyÅ‚ku: %s" + +# glib/gfileutils.c:745 +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "NiemahÄyma stvaryć fajÅ‚ '%s': %s" + +# glib/gfileutils.c:505 +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" +"NiemahÄyma adÄynic fajÅ‚ %s' dla zapisu: funkcyja fdopen() vyvieÅ‚a pamyÅ‚ku: %s" + +# glib/gfileutils.c:505 +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "NiemahÄyma zapisać fajÅ‚ '%s': funkcyja fwrite() vyvieÅ‚a pamyÅ‚ku: %s" + +# glib/gfileutils.c:505 +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "NiemahÄyma zapisać fajÅ‚ '%s': funkcyja fwrite() vyvieÅ‚a pamyÅ‚ku: %s" + +# glib/gfileutils.c:505 +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "NiemahÄyma zapisać fajÅ‚ '%s': funkcyja fwrite() vyvieÅ‚a pamyÅ‚ku: %s" + +# glib/gfileutils.c:505 +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "NiemahÄyma zaÄynić fajÅ‚ %s': funkcyja fclose() vyvieÅ‚a pamyÅ‚ku: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" +"NiemahÄyma vydalić najaÅ­ny fajÅ‚ '%s': funkcyja g_unlink() vyvieÅ‚a pamyÅ‚ku: %s" + +# glib/gfileutils.c:712 +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Å ablon '%s' niapravilny, u im nie pavinna być '%s'" + +# glib/gfileutils.c:724 +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "U Å¡ablonie '%s' niama XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajt" +msgstr[1] "%u bajty" +msgstr[2] "%u bajtaÅ­" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, fuzzy, c-format +msgid "%.1f TB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, fuzzy, c-format +msgid "%.1f PB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, fuzzy, c-format +msgid "%.1f EB" +msgstr "%.1f KB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, fuzzy, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%u bajt" +msgstr[1] "%u bajty" +msgstr[2] "%u bajtaÅ­" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +# glib/gfileutils.c:745 +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "NiemahÄyma praÄytać symbalnuju spasyÅ‚ku '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Symbalnyja spasyÅ‚ki nie padtrymlivajucca" + +# glib/giochannel.c:1114 +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Nielha adÄynić kanverter z '%s' na '%s': %s" + +# glib/giochannel.c:1460 +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" +"NiemahÄyma vykanać niepasrednaje ÄytaÅ„nie Å­ funkcyi " +"g_io_channel_read_line_string" + +# glib/giochannel.c:1507 glib/giochannel.c:1761 glib/giochannel.c:1847 +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "U bufery ÄytaÅ„nia zastalisia niepieraÅ­tvoranyja źviestki" + +# glib/giochannel.c:1587 glib/giochannel.c:1661 +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Na kancy kanaÅ‚u isnuje paÅ›ladoÅ­naść, jakaja adpaviadaje Äastcy znaku" + +# glib/giochannel.c:1647 +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" +"NiemahÄyma vykanać niepasrednaje ÄytaÅ„nie Å­ funkcyi g_io_channel_read_to_end" + +# glib/gfileutils.c:505 +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "NiemahÄyma adÄynić fajÅ‚ '%s': funkcyja open() vyvieÅ‚a pamyÅ‚ku: %s" + +# glib/gfileutils.c:505 +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "NiemahÄyma zmapavać fajÅ‚ '%s': funkcyja mmap() vyvieÅ‚a: %s" + +# glib/gmarkup.c:219 +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "PamyÅ‚ka Å­ %d radku pry znaku %d: " + +# glib/gmarkup.c:837 glib/gmarkup.c:865 glib/gmarkup.c:896 +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Niapravilna kadavany tekst UTF-8 - niapravilny \"%s\"" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +# glib/gmarkup.c:303 +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "PamyÅ‚ka Å­ radku %d: %s" + +# glib/gmarkup.c:528 +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"NiemahÄyma pierapracavać '%-.*s', dzie musić być liÄba unutry Å‚uÄyva da " +"znaku (naprykÅ‚ad ê) — mahÄyma, liÄba zavialikaja" + +# glib/gmarkup.c:580 +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"SpasyÅ‚ka na znak nie kanÄajecca kropkaj z koskaj; mahÄyma znak & vykarystany " +"nie dla paznaÄeÅ„nia paÄatku adzinki — u takim vypadku zamianicie jaho jak " +"&" + +# glib/gmarkup.c:553 +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "SpasyÅ‚ka na znak '%-.*s' nie źjaÅ­lajecca zapisam dazvolenaha znaku" + +# glib/gmarkup.c:382 +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "Pusty zapis '&;' adÅ¡ukany; dapuÅ¡Äalnyja: & " < > '" + +# glib/gmarkup.c:472 +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Nieviadomaja nazva adzinki '%s'" + +# glib/gmarkup.c:482 +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Zapis nie kanÄajecca kropkaj z koskaj; zdajecca, vykarystali znak &, jaki " +"nia mieÅ­ aznaÄać paÄatku adzinki — zamianicie jaho na &" + +# glib/gmarkup.c:932 +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Dakument musić paÄynacca z elementu (naprykÅ‚ad )" + +# glib/gmarkup.c:970 +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' nie źjaÅ­lajecca dapuÅ¡Äalnym znakam, paÅ›la znaku '<'; hety znak nia moža " +"paÄynać nazvy adzinki" + +# glib/gmarkup.c:1033 +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"DziÅ­ny znak '%s', ÄakaÅ­sia znak '>' dla zakanÄeÅ„nia znaÄnika elementu '%s'" + +# glib/gmarkup.c:1120 +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"DziÅ­ny znak '%s', ÄakaÅ­sia znak '=' paÅ›la nazvy atrybutu '%s' elementu '%s'" + +# glib/gmarkup.c:1161 +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"DziÅ­ny znak '%s', Äakali znaku '>' albo '/' dla zakryćcia paÄatkovaha " +"znaÄnika elementu '%s' ci dadatkova atrybutu; mahÄyma, byÅ­ vykarystany " +"niedapuÅ¡Äalny znak u nazovie atrybutu" + +# glib/gmarkup.c:1244 +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"DziÅ­ny znak '%s', ÄakaÅ‚asia padvojnaja dužka paÅ›la znaku roÅ­naÅ›ci, kali " +"nadajecca znaÄeÅ„nie atrybutu '%s' elementu '%s'" + +# glib/gmarkup.c:1384 +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' nia źjaÅ­lajecca dapuÅ¡Äalnym znakam zakanÄeÅ„nia nazvy elementu '%s'; " +"dapuÅ¡Äalnym znakam źjaÅ­lajecca '>'" + +# glib/gmarkup.c:1433 +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Element '%s' byÅ­ zaÄynieny, dziejna niama adÄynienych elementaÅ­" + +# glib/gmarkup.c:1442 +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Element '%s' byÅ­ zaÄynieny, ale dziejna adÄynieny '%s'" + +# glib/gmarkup.c:1574 +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Dakument byÅ­ pusty albo Å­trymlivaÅ­ tolki prabieÅ‚y" + +# glib/gmarkup.c:1588 +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Adrazu paÅ›la znaku '%s' dakument nieÄakana skonÄyÅ­sia" + +# glib/gmarkup.c:1596 glib/gmarkup.c:1640 +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Dakument nieÄakana skonÄyÅ­sia, kali peÅ­nyja elementy byli jaÅ¡Äe adÄynienyja " +"— '%s' byÅ­ apoÅ¡nim adÄynienym elementam" + +# glib/gmarkup.c:1604 +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dakument nieÄakana skonÄyÅ­sia, ÄakaÅ‚asia vuhÅ‚avaja dužka, jakaja zaÄyniaje " +"znaÄnik <%s/>" + +# glib/gmarkup.c:1610 +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dakument nieÄakana skonÄyÅ­sia Å­nutry nazvy elementu" + +# glib/gmarkup.c:1615 +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dakument nieÄakana skonÄyÅ­sia Å­nutry nazvy atrybutu" + +# glib/gmarkup.c:1620 +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dakument nieÄakana skonÄyÅ­sia Å­nutry elementu, jaki adkryvaje znaÄnik." + +# glib/gmarkup.c:1626 +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dakument nieÄakana skonÄyÅ­sia paÅ›la znaku roÅ­naÅ›ci, jaki iÅ¡oÅ­ za nazvaj " +"atrybutu: niama vartaÅ›ci atrybutu" + +# glib/gmarkup.c:1633 +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dakument nieÄakana skonÄyÅ­sia Å­nutry vartaÅ›ci atrybutu" + +# glib/gmarkup.c:1648 +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Dakument nieÄakana skonÄyÅ­sia Å­nutry znaÄnika zamykaÅ„nia elementu '%s'" + +# glib/gmarkup.c:1654 +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dakument nieÄakana skonÄyÅ­sia Å­nutry kamentara albo instrukcyi" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "sapsavany abjekt" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "unutranaja pamyÅ‚ka ci sapsavany abjekt" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "nie chapiÅ‚a pamiaci" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "limit viartaÅ„nia (backtracking) dasiahnutaja" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"Å¡ablon utrymlivaje elementy, jakija nie padtrymvajucca dla Äastkovaj " +"adpaviadnaÅ›ci" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "unutranaja pamyÅ‚ka" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"advarotnyja spasyÅ‚ki jak umovy nie padtrymvajucca dla Äastkovaj adpaviadnaÅ›ci" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "limit rekursii dasiahnuty" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "limit raboÄaj prastory dla pustych padradkoÅ­ dasiahnuty" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "niapravilnaja kambinacyja Å›ciažkoÅ­ novych radkoÅ­" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "nieviadomaja pamyÅ‚ka" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ u kancy Å¡ablonu" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c u kancy Å¡ablonu" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "za \\ Å›leduje nieviadomy znak" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" +"escapy, jakija źmianiajuć rehistar (\\l, \\L, \\u, \\U), tut nie dazvolenyja" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "nieÄarhovyja liki Å­ quantyfikatary {}" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "zavialiki lik u quantyfikatary {}" + +# glib/giochannel.c:1587 glib/giochannel.c:1661 +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "nie staje kancavoj [ dziela znakavaj klasy" + +# glib/gconvert.c:592 glib/gconvert.c:882 glib/giochannel.c:1282 +# glib/giochannel.c:1324 glib/giochannel.c:2163 glib/gutf8.c:875 +# glib/gutf8.c:1320 +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "niapravilnaja paÅ›ladoÅ­naść escape Å­ znakavaj klasie" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "dyjapazon nie Å­ paradku Å­ klasie znakaÅ­" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "niama Äaho paÅ­tarać" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "nieviadomy znak paÅ›la (?" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "nieviadomy znak paÅ›la (?<" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "nieviadomy znak paÅ›la (?P" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "Nazvanyja klasy POSIX padtrymlivajucca tolki Å­ klasach" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "nie staje kancavoha )" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") biaz paÄatkovaj (" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ci (?[+-]liÄby musić zakanÄvacca na )" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "spasyÅ‚ka na niaisny padÅ¡ablon" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "nie staje ) paÅ›la kamentara" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "rehularny vyraz zavialiki" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "niemahÄyma atrymać pamiaci" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "assertacyja lookbehind niastaÅ‚aj daŭžyni" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "niereÄaisny lik ci nazva paÅ›la (?(" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "umoÅ­naja hrupa maje bolej za dźvie haliny" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "ÄakaÅ­sia assert paÅ›la (?(" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "nieviadomaja nazva klasy POSIX" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "elementy paradkavaÅ„nia POSIX nie padtrymlivajucca" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "znakavaja vartaść u paÅ›ladoÅ­naÅ›ci \\x{...} zavialikaja" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "niapravilnaja Å­mova (?(0)" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C nie dazvoleny Å­ assertacyi lookbehind" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "rekursiÅ­ny vyklik moža zacyklicca niapeÅ­nym Äynam" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "nie staje terminatara Å­ naźvie padÅ¡ablonu" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "dva nazvanyja padÅ¡ablony adnolkava nazyvajucca" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "niereÄaisnaja paÅ›ladoÅ­naść \\P ci \\p" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "nazva nieviadomaj uÅ‚aÅ›civaÅ›ci paÅ›la \\P ci \\p" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "nazva padÅ¡ablonu zavialikaja (maksymalna 32 znakaÅ­)" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "zaÅ¡mat nazvanych padÅ¡ablonaÅ­ (maksymalna 10,000)" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "vaÅ›miarkovaja vartaść bolÅ¡aja za \\377" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "Hrupa DEFINE źmiaÅ¡Äaje bolÅ¡ za adnu halinu" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "paÅ­tor hrupy DEFINE nie dazvoleny" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "niapoÅ­nyja opcyi NEWLINE" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" +"paÅ›la \\g nie padadziena nazvy Å­ dužkach ci nienulavoha liku Å­ " +"nieabaviazkovych dužkach" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "nieÄakany paÅ­tor" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "pierapaÅ­nieÅ„nie kodu" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "raboÄy abÅ¡ar dla kampilavaÅ„nia pierapaÅ­nieÅ„nia" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "raniej pravierany padÅ¡ablon sa spasyÅ‚kami nia znojdzieny" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "PamyÅ‚ka padÄas poÅ¡uku adpaviednikaÅ­ dla rehularnaha vyrazu %s: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Biblijateka PCRE skampilavanaja biez padtrymki UTF8" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Biblijateka PCRE skampilavanaja biez padtrymki Å­Å‚aÅ›civaÅ›ciaÅ­ UTF8" + +# glib/gmarkup.c:219 +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "PamyÅ‚ka padÄas kampilavaÅ„nia rehularnaha vyrazu %s pry znaku %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "PamyÅ‚ka padÄas aptymizacyi rehularnaha vyrazu %s: %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "Å¡asnaccatkovaja liÄba ci \"}\" Äakalisia" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "Å¡asnaccatkovaja liÄba ÄakaÅ‚asia" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "nie staje \"<\" u symbalnaj spasyÅ‚cy" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "niezavierÅ¡anaja symbalnaja spasyÅ‚ka" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "symbalnaja spasyÅ‚ka nulavoj daŭžyni" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "ÄakaÅ‚asia liÄba" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "zabaronienaja symbalnaja spasyÅ‚ka" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "zabÅ‚ukaÅ­Å¡y kancavy \"\\\"" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "nieviadomaja cytavanaja paÅ›ladoÅ­naść" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "PamyÅ‚ka padÄas razboru tekstu zamieny \"%s\" pry znaku %lu: %s" + +# glib/gshell.c:71 +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Cytavany znak nie paÄynajecca znakam dvukoÅ›sia" + +# glib/gshell.c:161 +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"U zahadnym radku albo inÅ¡ym cytavanym, jak u abaÅ‚oncy, tekÅ›cie pajaviÅ­sia " +"adzinoÄny znak cytavaÅ„nia" + +# glib/gshell.c:529 +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Tekst skonÄyÅ­sia adrazu paÅ›la znaku '\\'. (Tekst byÅ­ '%s')" + +# glib/gshell.c:536 +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"Tekst skonÄyÅ­sia pierad adpaviednym dvukoÅ›siem dla %c. (Tekst byÅ­ '%s')" + +# glib/gshell.c:548 +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Tekst byÅ­ pusty (albo Å­ im byli tolki prabieÅ‚y)" + +# glib/gspawn-win32.c:214 +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "NiemahÄyma adÄytać źviestki pracesu-naÅ¡Äadka" + +# glib/gspawn-win32.c:981 glib/gspawn.c:1228 +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Nielha stvaryć pÅ‚yniu dziela kamunikacyi z pracesam-naÅ¡Äadkam (%s)" + +# glib/gspawn-win32.c:843 glib/gspawn.c:914 +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "NiemahÄyma adÄytać pÅ‚yniu naÅ¡Äadka (%s)" + +# glib/gspawn-win32.c:931 glib/gspawn.c:1119 +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "NiemahÄyma źmianić kataloh na '%s' (%s)" + +# glib/gspawn-win32.c:940 +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "NiemahÄyma vykanać praces-naÅ¡Äadka (%s)" + +# glib/gconvert.c:1729 +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Niapravilnaja nazva prahramy: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Niapravilny paradak u arhumencie %d: %s" + +# glib/gutf8.c:1039 glib/gutf8.c:1048 glib/gutf8.c:1180 glib/gutf8.c:1189 +# glib/gutf8.c:1330 glib/gutf8.c:1426 +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Niapravilny radok u asiarodździ: %s" + +# glib/gdir.c:79 +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Niapravilny raboÄy kataloh: %s" + +# glib/gspawn-win32.c:940 +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "NiemahÄyma Å­kluÄyć prahramu dapamohi (%s)" + +# glib/gspawn-win32.c:365 +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Pry adÄytvaÅ„ni źviestak pracesu-naÅ¡Äadka Å­ funkcyi g_io_channel_win32_poll() " +"adbyÅ‚asia nieviadomaja pamyÅ‚ka" + +# glib/gspawn.c:161 +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "NiemahÄyma adÄytać źviestki pracesu-naÅ¡Äadka (%s)" + +# glib/gspawn.c:293 +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"NieÄakanaja pamyÅ‚ka Å­ funkcyi select() padÄas ÄytaÅ„nia źviestak pracesu-" +"naÅ¡Äadka (%s)" + +# glib/gspawn.c:376 +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NieÄakanaja pamyÅ‚ka Å­ waitpid() (%s)" + +# glib/gspawn.c:979 +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "NiemahÄyma stvaryć praces (%s)" + +# glib/gspawn.c:1129 +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Niemahvyma vykanać praces-naÅ¡Äadka \"%s\" (%s)" + +# glib/gspawn.c:1139 +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "NiemahÄyma pierakiravać uvachod albo vyjÅ›cie pracesu-naÅ¡Äadka (%s)" + +# glib/gspawn.c:1148 +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "NiemahÄyma stvaryć praces-naÅ¡Äadka (%s)" + +# glib/gspawn.c:1156 +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Nieviadomaja pamyÅ‚ka vykanaÅ„nia pracesu-naÅ¡Äadka \"%s\"" + +# glib/gspawn.c:1178 +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"NiemahÄyma adÄytać adpaviednuju kolkaść źviestak ź PID kanaÅ‚u naÅ¡Äadka (%s)" + +# glib/gutf8.c:950 +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Znak pa-za dyjapazonam UTF-8" + +# glib/gutf8.c:1039 glib/gutf8.c:1048 glib/gutf8.c:1180 glib/gutf8.c:1189 +# glib/gutf8.c:1330 glib/gutf8.c:1426 +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Niapravilny paradak na Å­vachodzie kanversii" + +# glib/gutf8.c:1341 glib/gutf8.c:1437 +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Znak pa-za dyjapazonam UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "VykarystaÅ„nie:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPCYJA...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Opcyi dapamohi:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Pakažy opcyi dapamohi" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Pakažy Å­sie opcyi dapamohi" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Opcyi aplikacyi:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "NiemahÄyma pierapracavać liÄbavaj vartaÅ›ci '%s' dla %s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "LiÄbavaja vartaść '%s' dla %s pa-za dapuÅ¡Äalnymi miežami" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Nielha pierapracavać padvojnuju liÄbavuju vartaść '%s' dla %s" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Padvojnaja liÄbavaja vartaść '%s' dla %s pa-za dapuÅ¡Äalnymi miežami" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "PamyÅ‚ka padÄas pierapracoÅ­ki %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Adsutny parametar dla %s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Nieviadomaja opcyja %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "NiemahÄyma znajÅ›ci pravilnaha fajÅ‚u kluÄa Å­ katalohach poÅ¡uku" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Heta nie zvyÄajny fajÅ‚" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "FajÅ‚ pusty" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"FajÅ‚ kluÄu Å­trymlivaje radok '%s', jaki nie źjaÅ­lajecca paraj kluÄ-vartaść, " +"hrupaj, albo kamentarom" + +# glib/gconvert.c:1729 +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Niapravilnaja nazva hrupy: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "FajÅ‚ kluÄa nie paÄynajecca ad hrupy" + +# glib/gconvert.c:1729 +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Niapravilnaja nazva kluÄa: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "FajÅ‚ kluÄa Å­trymlivaje kadavaÅ„nie '%s', jakoje nie absÅ‚uhoÅ­vajecca" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "FajÅ‚ kluÄa nie Å­kluÄaje Å­ siabie hrupy '%s'" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "FajÅ‚ kluÄa nie Å­kluÄaje Å­ siabie kluÄa '%s'" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"FajÅ‚ kluÄa Å­kluÄaje Å­ siabie kluÄ '%s' z vartaÅ›ciu '%s', nie zapisanaj jak " +"UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" +"FajÅ‚ kluÄa Å­kluÄaje Å­ siabie kluÄ '%s' ź nieinterpretavalnaj vartaÅ›ciu." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"FajÅ‚ kluÄa Å­kluÄaje Å­ siabie kluÄ '%s' ź nieinterpretavalnaj vartaÅ›ciu." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"FajÅ‚ kluÄa Å­kluÄaje Å­ siabie kluÄ '%s' u hrupie '%s', jaki maje " +"nieinterpretavalnuju vartaść." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "FajÅ‚ kluÄa nia maje kluÄa '%s' u hrupie '%s'" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "FajÅ‚ kluÄa maje Å­ sabie cytavany znak na kancy radka" + +# glib/gconvert.c:1648 +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "FajÅ‚ kluÄa maje Å­ sabie niedapuÅ¡Äalny cytavalny Å‚ancužok '%s'" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Nielha interpretavać '%s' jak liÄbavuju vartaść." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "LiÄbavaja vartaść '%s' pa-za dapuÅ¡Äalnymi miežami" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" +"NiemahÄyma interpretavać znaÄeÅ„nie '%s' jak liÄbavuju vartaść ź " +"niefiksavanaj koskaj." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "LiÄbavuju vartaść '%s' niemahÄyma interpretavać jak lahiÄnuju vartaść." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Funkcyi %s pieradadzieny nadta vialiki liÄylnik" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "PÅ‚yÅ„ užo zaÄynienaja" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "Aperacyja anulavanaja" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +# glib/gconvert.c:592 glib/gconvert.c:882 glib/giochannel.c:1282 +# glib/giochannel.c:1324 glib/giochannel.c:2163 glib/gutf8.c:875 +# glib/gutf8.c:1320 +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Niapravilnaja paÅ›ladoÅ­naść bajtaÅ­ na Å­vachodzie kanversii" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Aperacyja nie padtrymlivajecca" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Nieviadomy typ" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "typ fajÅ‚aÅ­ %s" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "typ %s" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "ZaÅ­Äasny kaniec pÅ‚yni" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "PamyÅ‚ka abcinaÅ„nia fajÅ‚u: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "PamyÅ‚ka zapisu Å­ fajÅ‚: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Nieviadomy typ" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +# glib/gdir.c:79 +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "PamyÅ‚ka pry adÄynieÅ„ni katalohu '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +# glib/gdir.c:79 +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "PamyÅ‚ka pry adÄynieÅ„ni katalohu '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "PamyÅ‚ka zaÄynieÅ„nia fajÅ‚u: %s" + +# glib/gfileutils.c:348 +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "LiÄylnik zaÄynieny" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "PÅ‚yÅ„ užo zaÄynienaja" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "PamyÅ‚ka zapisu Å­ fajÅ‚: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Åšmietnica nie padtrymlivajacca" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "PamyÅ‚ka zapisu Å­ fajÅ‚: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +# glib/gmarkup.c:303 +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "PamyÅ‚ka Å­ radku %d: %s" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "PamyÅ‚ka padÄas pierapracoÅ­ki %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +# glib/gmarkup.c:428 +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Znak '%s' niedapuÅ¡Äalny Å­nutry nazvy adzinki" + +# glib/gmarkup.c:428 +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Znak '%s' niedapuÅ¡Äalny Å­nutry nazvy adzinki" + +# glib/gmarkup.c:428 +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Znak '%s' niedapuÅ¡Äalny Å­nutry nazvy adzinki" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "PamyÅ‚ka padÄas pierapracoÅ­ki %s" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "PamyÅ‚ka padÄas kanversii: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +# glib/gdir.c:79 +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "PamyÅ‚ka pry adÄynieÅ„ni katalohu '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "sapsavany abjekt" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Nienazvany" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "FajÅ‚ staÅ‚a nie akreÅ›livaje pola Exec" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "NiemahÄyma znajÅ›ci terminaÅ‚u, vymahanaha dla aplikacyi" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" +"NiemahÄyma stvaryć kanfihuracyjny kataloh %s karystalnika dla aplikacyi: %s" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "NiemahÄyma stvaryć kanfihuracyjny kataloh MIME %s dla karystalnika: %s" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "NiemahÄyma stvaryć fajÅ‚ staÅ‚a %s dla karystalnika" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "Asablivaje aznaÄeÅ„nie dla %s" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "pryÅ‚ada nie zaimplementavaÅ‚a vysoÅ­vaÅ„nia (eject)" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +#, fuzzy +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "pryÅ‚ada nie zaimplementavaÅ‚a vysoÅ­vaÅ„nia (eject)" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "pryÅ‚ada nie zaimplementavaÅ‚a apytaÅ„nia noÅ›bitaÅ­ (poll)" + +#: ../gio/gdrive.c:728 +#, fuzzy +msgid "drive doesn't implement start" +msgstr "pryÅ‚ada nie zaimplementavaÅ‚a vysoÅ­vaÅ„nia (eject)" + +#: ../gio/gdrive.c:831 +#, fuzzy +msgid "drive doesn't implement stop" +msgstr "pryÅ‚ada nie zaimplementavaÅ‚a vysoÅ­vaÅ„nia (eject)" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Aperacyja nie padtrymlivajecca" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "ŹmiaÅ¡Äalnaje mantavaÅ„nie nie isnuje" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "NiemahÄyma skapijavać zamiest katalohu" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "NiemahÄyma skapijavać kataloh zamiest inÅ¡aha katalohu" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "Metavy fajÅ‚ isnuje" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "NiemahÄyma rekursiÅ­na skapijavać kataloh" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Symbalnyja spasyÅ‚ki nie padtrymlivajucca" + +# glib/gfileutils.c:348 +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u: %s" + +#: ../gio/gfile.c:2909 +#, fuzzy +msgid "Can't copy special file" +msgstr "NiemahÄyma skapijavać zamiest katalohu" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "Padadzienaja niapravilnaja vartaść symbalnaj spasyÅ‚ki" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "Åšmietnica nie padtrymlivajacca" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Nazvy fajÅ‚aÅ­ nia mohuć utrymlivać \"%c\"" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "masiÅ­ nie zaimplementavaÅ­ mantavaÅ„nia (mount)" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "Nivodnaja aplikacyja nie zarehistravanaja dla pracy z hetym fajÅ‚am" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "LiÄylnik zaÄynieny" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "U fajÅ‚avaha liÄylnika jość važkaja aperacyja" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "FajÅ‚avy liÄylnik užo zaÄynieny" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "PÅ‚yÅ„ nie padtrymlivaje query_info" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "Dla pÅ‚yni nie padtrymlivajecca zruch" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "Dla Å­vachodnaj pÅ‚yni nie dazvolenaje abcinaÅ„nie" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "Dla pÅ‚yni nie padtrymlivajecca abcinaÅ„nie" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "Uvachodnaja pÅ‚yÅ„ nie zaimplementavaÅ‚a ÄytaÅ„nia (read)" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "Dla pÅ‚yni jość važkaja aperacyja" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Åšmietnica nie padtrymlivajacca" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, fuzzy, c-format +msgid "invalid GVariant type string '%s'" +msgstr "Niapravilny typ atrybutu (ÄakaÅ­sia tekstavy radok)" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "NiemahÄyma znajÅ›ci zmoÅ­Äany typ manitora dla lakalnaha katalohu" + +# glib/gconvert.c:1729 +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Niapravilnaja nazva fajÅ‚u %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "PamyÅ‚ka atrymaÅ„nia źviestak ab fajÅ‚avaj systemie: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "NiemahÄyma źmianić nazvu dla karaniovaha katalohu" + +# glib/gfileutils.c:348 +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u: %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "NiemahÄyma źmianić nazvu dla fajÅ‚u, taki fajÅ‚ užo isnuje" + +# glib/gconvert.c:1729 +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Niapravilnaja nazva fajÅ‚u" + +# glib/gfileutils.c:348 +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "NiemahÄyma adÄynić kataloh" + +# glib/gfileutils.c:348 +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "PamyÅ‚ka vydaleÅ„nia fajÅ‚u: %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "PamyÅ‚ka vykidaÅ„nia Å­ Å›mietnicu fajÅ‚u: %s" + +# glib/gfileutils.c:745 +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "NiemahÄyma stvaryć kataloh Å›mietnicy %s: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "NiemahÄyma znajÅ›ci najvyÅ¡ejÅ¡y kataloh dziela Å›miećcia" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "NiemahÄyma znajÅ›ci ci stvaryć kataloh dziela Å›miećcia" + +# glib/gfileutils.c:745 +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "NiemahÄyma stvaryć Å›miaćciovy fajÅ‚ źviestak: %s" + +# glib/gfileutils.c:745 +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "NiemahÄyma vykinuć u Å›mietnicu fajÅ‚: %s" + +# glib/gdir.c:79 +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "PamyÅ‚ka pry adÄynieÅ„ni katalohu '%s': %s" + +# glib/gfileutils.c:745 +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "NiemahÄyma praÄytać symbalnuju spasyÅ‚ku '%s': %s" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "PamyÅ‚ka stvareÅ„nia symbalnaj spasyÅ‚ki: %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "PamyÅ‚ka pieranosu fajÅ‚u: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "NiemahÄyma pieranieÅ›ci kataloh zamiest inÅ¡aha katalohu" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "NiaÅ­daÅ‚aje stvareÅ„nie zapasnoha fajÅ‚u" + +# glib/gfileutils.c:348 +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "PamyÅ‚ka vydaleÅ„nia metavaha fajÅ‚u: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "Pieranos pamiž punktami mantavaÅ„nia nie padtrymlivajecca" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "Vartaść atrybutu musić być nia-NULL" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "Niapravilny typ atrybutu (ÄakaÅ­sia tekstavy radok)" + +# glib/gmarkup.c:1615 +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "Niapravilnaja nazva paÅ¡yranaha atrybutu" + +# glib/gdir.c:79 +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "PamyÅ‚ka akreÅ›leÅ„nia paÅ¡yranaha atrybutu '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "PamyÅ‚ka atrymaÅ„nia stat() dla fajÅ‚u '%s': %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (niapravilnaje kadavaÅ„nie)" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "PamyÅ‚ka atrymaÅ„nia stat() dla fajÅ‚avaha deskryptara: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Niapravilny typ atrybutu (ÄakaÅ­sia uint32)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Niapravilny typ atrybutu (ÄakaÅ­sia uint64)" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "Niapravilny typ atrybutu (ÄakaÅ­sia bajtavy radok)" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "PamyÅ‚ka akreÅ›leÅ„nia pravoÅ­: %s" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "PamyÅ‚ka akreÅ›leÅ„nia pravoÅ­: %s" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "PamyÅ‚ka akreÅ›leÅ„nia Å­Å‚adalnika: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "symbalnaja spasyÅ‚ka musić być nia-NULL" + +# glib/gmarkup.c:303 +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "PamyÅ‚ka akreÅ›leÅ„nia symbalnaj spasyÅ‚ki: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"PamyÅ‚ka akreÅ›leÅ„nia symbalnaj spasyÅ‚ki: fajÅ‚ nie źjaÅ­lajecca symbalnaj " +"spasyÅ‚kaj" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "PamyÅ‚ka akreÅ›leÅ„nia pravoÅ­: %s" + +#: ../gio/glocalfileinfo.c:2162 +#, fuzzy +msgid "SELinux context must be non-NULL" +msgstr "symbalnaja spasyÅ‚ka musić być nia-NULL" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "PamyÅ‚ka akreÅ›leÅ„nia Å­Å‚adalnika: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "AkreÅ›leÅ„nie atrybutu %s nie padtrymlivajecca" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia z fajÅ‚u: %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "PamyÅ‚ka zruchu Å­ fajle: %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "PamyÅ‚ka zaÄynieÅ„nia fajÅ‚u: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "NiemahÄyma znajÅ›ci zmoÅ­Äany typ manitora dla lakalnaha fajÅ‚u" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "PamyÅ‚ka zapisu Å­ fajÅ‚: %s" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "PamyÅ‚ka vydaleÅ„nia staroj zapasnoj spasyÅ‚ki: %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "PamyÅ‚ka stvareÅ„nia zapasnoj kopii: %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "PamyÅ‚ka źmieny nazy Äasovaha fajÅ‚u: %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "PamyÅ‚ka abcinaÅ„nia fajÅ‚u: %s" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u '%s': %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "Metavy fajÅ‚ źjaÅ­lajecca kataloham" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "Metavy fajÅ‚ nia prosty" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "FajÅ‚ byÅ­ źmienieny zvonku" + +# glib/gfileutils.c:348 +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "PamyÅ‚ka vydaleÅ„nia fajÅ‚u: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "AkreÅ›leny niapravilny GSeekType" + +# glib/gconvert.c:1729 +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Niapravilnaja zapyt pieraskoku Å­ fajle" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "NiemahÄyma padrezać GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "Nielha źmianiać pamier pÅ‚yni vyjÅ›cia Å­ pamiaci" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "Nie Å­daÅ‚osia źmianić pamier pÅ‚yni vyjÅ›cia Å­ pamiaci" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +#, fuzzy +msgid "mount doesn't implement \"unmount\"" +msgstr "mantavaÅ„nie nie zaimplementavaÅ‚a admantavaÅ„nia (unmount)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +#, fuzzy +msgid "mount doesn't implement \"eject\"" +msgstr "mantavaÅ„nie nie zaimplementavaÅ‚a vysoÅ­vaÅ„nia (eject)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +#, fuzzy +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "mantavaÅ„nie nie zaimplementavaÅ‚a admantavaÅ„nia (unmount)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +#, fuzzy +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "mantavaÅ„nie nie zaimplementavaÅ‚a vysoÅ­vaÅ„nia (eject)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +#, fuzzy +msgid "mount doesn't implement \"remount\"" +msgstr "mantavaÅ„nie nie zaimplementavaÅ‚a pieramantavaÅ„nia (remount)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +#, fuzzy +msgid "mount doesn't implement content type guessing" +msgstr "mantavaÅ„nie nie zaimplementavaÅ‚a admantavaÅ„nia (unmount)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +#, fuzzy +msgid "mount doesn't implement synchronous content type guessing" +msgstr "mantavaÅ„nie nie zaimplementavaÅ‚a admantavaÅ„nia (unmount)" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "VyjÅ›ciovaja pÅ‚yÅ„ nie zaimplementavaÅ‚a zapisu (write)" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "KryniÄnaja pÅ‚yÅ„ užo zaÄynienaja" + +# glib/gfileutils.c:348 +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u '%s': %s" + +# glib/gfileutils.c:348 +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u '%s': %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "PamyÅ‚ka vydaleÅ„nia fajÅ‚u: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Nieviadomaja opcyja %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +#, fuzzy +msgid "Socket is already closed" +msgstr "KryniÄnaja pÅ‚yÅ„ užo zaÄynienaja" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia z fajÅ‚u: %s" + +# glib/gfileutils.c:745 +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "NiemahÄyma stvaryć kataloh Å›mietnicy %s: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "PamyÅ‚ka zapisu Å­ fajÅ‚: %s" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "PamyÅ‚ka padÄas kanversii: %s" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "PamyÅ‚ka abcinaÅ„nia fajÅ‚u: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u: %s" + +# glib/gfileutils.c:745 +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "NiemahÄyma vykinuć u Å›mietnicu fajÅ‚: %s" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "PamyÅ‚ka vydaleÅ„nia fajÅ‚u: %s" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u: %s" + +# glib/gfileutils.c:745 +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "NiemahÄyma stvaryć kataloh Å›mietnicy %s: %s" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "PamyÅ‚ka zaÄynieÅ„nia fajÅ‚u: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u: %s" + +#: ../gio/gsocket.c:3081 +#, fuzzy +msgid "GSocketControlMessage not supported on windows" +msgstr "źmieny asacyjacyjaÅ­ nie padtrymlivajucca dla win32" + +# glib/gfileutils.c:348 +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "PamyÅ‚ka vydaleÅ„nia fajÅ‚u: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +#, fuzzy +msgid "Unknown error on connect" +msgstr "nieviadomaja pamyÅ‚ka" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Symbalnyja spasyÅ‚ki nie padtrymlivajucca" + +#: ../gio/gsocketlistener.c:191 +#, fuzzy +msgid "Listener is already closed" +msgstr "PÅ‚yÅ„ užo zaÄynienaja" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +#, fuzzy +msgid "Unexpected type of ancillary data" +msgstr "ZaÅ­Äasny kaniec pÅ‚yni" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "PamyÅ‚ka adÄynieÅ„nia fajÅ‚u: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia fajÅ‚u: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +# glib/gfileutils.c:348 +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia z unix: %s" + +# glib/gmarkup.c:303 +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "PamyÅ‚ka zaÄynieÅ„nia unix: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "KoraÅ„ fajÅ‚avaj systemy" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "PamyÅ‚ka zapisu Å­ unix: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "masiÅ­ nie zaimplementavaÅ­ vysoÅ­vaÅ„nia (eject)" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +#, fuzzy +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "masiÅ­ nie zaimplementavaÅ­ vysoÅ­vaÅ„nia (eject)" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "NiemahÄyma znajÅ›ci aplikacyju" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "PamyÅ‚ka Å­kluÄeÅ„nia aplikacyi: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "Adrasy URI nie padtrymlivajucca" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "źmieny asacyjacyjaÅ­ nie padtrymlivajucca dla win32" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "StvareÅ„nie asacyjacyjaÅ­ nie padtrymlivajecca dla win32" + +# glib/gfileutils.c:348 +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "PamyÅ‚ka adÄytaÅ„nia z fajÅ‚u: %s" + +# glib/gfileutils.c:348 +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "PamyÅ‚ka zaÄynieÅ„nia fajÅ‚u: %s" + +# glib/gfileutils.c:348 +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "PamyÅ‚ka zapisu Å­ fajÅ‚: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "nie chapiÅ‚a pamiaci" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "unutranaja pamyÅ‚ka" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +# glib/gconvert.c:1729 +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Niapravilnaja nazva kamputara" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "NiemahÄyma pieranieÅ›ci kataloh zamiest inÅ¡aha katalohu" + +# glib/gutf8.c:1039 glib/gutf8.c:1048 glib/gutf8.c:1180 glib/gutf8.c:1189 +# glib/gutf8.c:1330 glib/gutf8.c:1426 +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Niapravilny paradak na Å­vachodzie kanversii" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "Dasiahnuta maksymalnaje abmiežavaÅ„nie masiva źviestak" + +#~ msgid "do not hide entries" +#~ msgstr "nie chavaj elementaÅ­" + +#~ msgid "use a long listing format" +#~ msgstr "užyj daÅ­hi Å›piskavy farmat" + +#~ msgid "[FILE...]" +#~ msgstr "[FAJÅ...]" + +# glib/gmarkup.c:392 +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Znak '%s' niedapuÅ¡Äalny na paÄatku nazvy adzinki; znak & paÄynaje " +#~ "adzinku; kali hety znak nie pavinien paÄynać adzinki, zamianicie jaho na " +#~ "znak &" + +# glib/gmarkup.c:570 +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "" +#~ "Pustaja spasyÅ‚ka na znak: u joj pavinien być numar, naprykÅ‚ad dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "NiezavierÅ¡anaja spasyÅ‚ka na adzinku" + +#~ msgid "Unfinished character reference" +#~ msgstr "NiezavierÅ¡anaja spasyÅ‚ka na znak" + +# glib/gmarkup.c:837 glib/gmarkup.c:865 glib/gmarkup.c:896 +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Niapravilna kadavany tekst UTF-8 - zadoÅ­haja paÅ›ladoÅ­naść" + +# glib/gmarkup.c:837 glib/gmarkup.c:865 glib/gmarkup.c:896 +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Niapravilna kadavany tekst UTF-8 - nie paÄatkovy znak" + +# glib/gconvert.c:1632 +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Niapravilnaja nazva hostu Å­ URI '%s' " + +#, fuzzy +#~ msgid "name" +#~ msgstr "Nienazvany" + +# glib/gconvert.c:1632 +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Niapravilnaja nazva hostu Å­ URI '%s' " + +#, fuzzy +#~ msgid "names" +#~ msgstr "Nienazvany" + +# glib/gfileutils.c:348 +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "PamyÅ‚ka atrymaÅ„nia stat() dla fajÅ‚avaha deskryptara: %s" + +#~ msgid "Can't load just created desktop file" +#~ msgstr "NiemahÄyma zahruzić tolki Å¡to stvorany fajÅ‚ staÅ‚a" + +# glib/gconvert.c:597 glib/gconvert.c:813 glib/giochannel.c:1289 +# glib/giochannel.c:2175 +#~ msgid "Error creating backup link: %s" +#~ msgstr "PamyÅ‚ka stvareÅ„nia zapasnoj spasyÅ‚ki: %s" + +#~ msgid "Too large count value passed to g_input_stream_read_async" +#~ msgstr "" +#~ "Funkcyi g_input_stream_read_async pieradadzieny nadta vialiki liÄylnik" + +#~ msgid "Too large count value passed to g_input_stream_skip" +#~ msgstr "Funkcyi g_input_stream_skip pieradadzieny nadta vialiki liÄylnik" + +#~ msgid "Too large count value passed to g_input_stream_skip_async" +#~ msgstr "" +#~ "Funkcyi g_input_stream_skip_async pieradadzieny nadta vialiki liÄylnik" + +#~ msgid "Target file already exists" +#~ msgstr "Metavy fajÅ‚ užo isnuje" + +#~ msgid "Too large count value passed to g_output_stream_write" +#~ msgstr "Funkcyi g_output_stream_write pieradadzieny nadta vialiki liÄylnik" + +#~ msgid "Too large count value passed to g_output_stream_write_async" +#~ msgstr "" +#~ "Funkcyi g_output_stream_write_async pieradadzieny nadta vialiki liÄylnik" diff --git a/po/bg.po b/po/bg.po new file mode 100644 index 0000000..b53f296 --- /dev/null +++ b/po/bg.po @@ -0,0 +1,6380 @@ +# Bulgarian translation of glib po-file. +# Copyright (C) 2002, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. +# Copyright (C) 2010, 2011, 2012, 2013, 2015 Free Software Foundation, Inc. +# Copyright (C) 2016 Free Software Foundation, Inc. +# Borislav Aleksandrov , 2002. +# Alexander Shopov , 2002, 2005, 2006, 2007, 2008, 2009, 2010, 2011. +# Alexander Shopov , 2012, 2013, 2015, 2016. +# Damyan Ivanov , 2010. +# Krasimir Chonov , 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-08 12:19+0000\n" +"PO-Revision-Date: 2022-04-09 09:55+0200\n" +"Last-Translator: Alexander Shopov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Задаването на приложение като Ñтандартно не Ñе поддържа" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Задаването на поÑледно ползваното приложение като Ñтандартно не Ñе поддържа" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "ÐаÑтройки на „GApplication“" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Извеждане на наÑтройките за „GApplication“" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Влизане в обÑлужващ режим на „GAplication“ (чрез обÑлужващи файлове на D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Предефиниране на идентификатора на приложение" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "ЗамÑна на ÑÑ‚Ð°Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑ" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Извеждане на помощта" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[КОМÐÐДÐ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Извеждане на верÑиÑта" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Извеждане на верÑиÑта" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Показване на приложениÑ" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Показване на инÑталираните Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° D-Bus, които може да Ñе задейÑтват " +"(чрез файлове „.desktop“)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Стартиране на програма" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Стартиране на програма (евентуално Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ за отварÑне)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "ИД_ÐÐ_ПРИЛОЖЕÐИЕ [ФÐЙЛ…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Ðктивиране на дейÑтвие" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Повикване на дейÑтвие за приложението" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ИД_ÐÐ_ПРИЛОЖЕÐИЕ ДЕЙСТВИЕ [ПÐРÐМЕТЪР]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Показване на дейÑтвиÑта" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"Показване на предварително зададени дейÑÑ‚Ð²Ð¸Ñ Ð·Ð° приложение (от файл „." +"desktop“)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ИД_ÐÐ_ПРИЛОЖЕÐИЕ" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "КОМÐÐДÐ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Командата за извеждане на подробна помощ за" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Идентификатор на приложение във формат D-Bus (например: „org.example.viewer“)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "ФÐЙЛ" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Ðезадължителни отноÑителни или абÑолютни пътища или адреÑи за отварÑне" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ДЕЙСТВИЕ" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "ДейÑтвието, което да Ñе извърши" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "ПÐРÐМЕТЪР" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" +"Ðезадължителен параметър при извикване на дейÑтвието. Във формат за " +"„GVariant“" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Ðепозната команда „%s“\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Употреба:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Ðргументи:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ÐРГУМЕÐТ…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Команди:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Въведете „%s help КОМÐÐДГ за подробна помощ.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Командата „%s“ изиÑква идентификатор на приложение за директно Ñледене\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "неизвеÑтен идентификатор на приложение „%s“\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"„%s“ не приема аргументи\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "неуÑпешно Ñвързване към D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "грешка при изпращане на Ñъобщение „%s“ до приложение „%s“\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "" +"името на дейÑтвие трÑбва да бъде подадено Ñлед идентификатора на приложение\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"неправилно име на дейÑтвие: „%s“\n" +"името трÑбва да Ñъдържа букви, цифри, „-“ или „.“\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "грешка при анализа на параметър: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "дейÑтвиÑта приемат Ñамо по един параметър\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "командата „list-actions“ изиÑква Ñамо идентификатор на приложение" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "не може да Ñе открие файл „.desktop“ за приложението „%s“\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"непозната команда „%s“\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Подадена е прекалено голÑма ÑтойноÑÑ‚ на „%s“" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "ТърÑенето не Ñе поддържа от оÑÐ½Ð¾Ð²Ð½Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾Ðº" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "„GBufferedInputStream“ не може да Ñе Ñъкрати" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Потокът вече е затворен" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "ОÑновниÑÑ‚ поток не може да Ñе Ñъкращава" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "ДейÑтвието е прекратено" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Ðеправилен обект, не е инициализирано" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Ðепълна байтова поÑледователноÑÑ‚ на входа" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "ÐÑма доÑтатъчно мÑÑто в целта" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Грешна байтова поÑледователноÑÑ‚ на входа за преобразуване" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Грешка по време на преобразуване: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Ðе Ñе поддържа отменима инициализациÑ" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Преобразуването от набора знаци „%s“ към „%s“ не Ñе поддържа" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Ðе може да Ñе отвори конвертор от „%s“ към „%s“" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "Вид на „%s“" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Ðепознат вид" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "Вид на файла „%s“" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "„GCredentials“ Ñъдържат неправилни данни" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "Операционната ÑиÑтема нÑма Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° „GCredentials“" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Платформата не поддържа „GCredentials“" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"РеализациÑта на „GCredentials“ върху тази операционна ÑиÑтема не Ñъдържа " +"идентификатор на процеÑ" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" +"ЗамÑната на данни за Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ðµ невъзможна на тази операционна ÑиÑтема" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Ðеочаквано ранен край на поток" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Ðеподдържан ключ „%s“ в Ð°Ð´Ñ€ÐµÑ â€ž%s“" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "БезÑмиÑлена ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ ключ и ÑтойноÑÑ‚ в адреÑа „%s“" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"ÐдреÑÑŠÑ‚ „%s“ е грешен (трÑбва да Ñъдържа Ñамо едно от Ñледните: път, " +"директориÑ, временна Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð¸Ð»Ð¸ абÑтрактни ключове)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Грешка в адреÑа „%s“ — атрибутът „%s“ е неправилен" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Ðепознат или неподдържан транÑпорт „%s“ за Ð°Ð´Ñ€ÐµÑ â€ž%s“" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Елементът на адреÑа „%s“ не Ñъдържа двоеточие („:“)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Името на транÑпорта в елемента на адреÑа „%s“ не трÑбва да е празно" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Двойката ключ/ÑтойноÑÑ‚ %d, „%s“ в адреÑÐ½Ð¸Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚ „%s“ не Ñъдържа знак за " +"равенÑтво („=“)" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Двойката ключ/ÑтойноÑÑ‚ %d, „%s“ в адреÑÐ½Ð¸Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚ „%s“ Ñъдържа празен ключ" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Грешка при декодиране на ключа или ÑтойноÑтта в двойката %d, „%s“ в адреÑÐ½Ð¸Ñ " +"елемент „%s“" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Грешка в адреÑа „%s“ — транÑпортът „unix“ изиÑква точно един от ключовете " +"„path“ или „abstract“" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Грешка в адреÑа „%s“ — атрибутът за хоÑÑ‚ „host“ липÑва или е грешен" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Грешка в адреÑа „%s“ — атрибутът за порт „port“ липÑва или е грешен" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Грешка в адреÑа „%s“ — атрибутът за момент „noncefile“ липÑва или е грешен" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Грешка при автоматично Ñтартиране: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Грешка при отварÑне на моментен файл „%s“: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Грешка при четене на моментен файл „%s“: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Грешка при четене на моментен файл „%s“, очакват Ñе 16 байта, а Ñа получени " +"%d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Грешка при Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° Ñъдържанието на моментен файл „%s“ в поток:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "ДадениÑÑ‚ Ð°Ð´Ñ€ÐµÑ Ðµ празен" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Създаването на шина за обмен на ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ðµ е възможно при изрично зададен " +"„AT_SECURE“" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Създаването на шина за обмен на ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ðµ е възможно без идентификатор на " +"машина: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "D-Bus не може да Ñе Ñтартира автоматично без „$DISPLAY“ от X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Грешка при изпълнÑване на външна команда „%s“: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"ÐдреÑÑŠÑ‚ на шината на ÑеÑиÑта не може да Ñе определи (липÑва Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð·Ð° " +"тази операционна ÑиÑтема)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"ÐдреÑÑŠÑ‚ на шината не може да Ñе определи от променливата на обкръжението " +"„DBUS_STARTER_BUS_TYPE“ — непозната ÑтойноÑÑ‚ „%s“" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"ÐдреÑÑŠÑ‚ на шината не може да Ñе определи, защото променливата " +"„DBUS_STARTER_BUS_TYPE“ липÑва в обкръжението" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Ðепознат вид шина %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Ðеочаквана липÑа на Ñъдържание при опит за четене на ред" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Ðеочаквана липÑа на Ñъдържание при опит за (безопаÑно) четене на ред" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Изчерпване на наличните механизми за Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ (пробвани: %s) (налични: " +"%s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" +"Идентификаторите за потребител от Ñървъра и отÑрещната Ñтрана трÑбва да Ñа " +"еднакви" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "ПрекъÑване чрез „GDBusAuthObserver::authorize-authenticated-peer“" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Грешка при получаване на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° папка „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Правата за доÑтъп до папката „%s“ Ñа повредени. Очакван режим 0700, получен " +"0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Грешка при Ñъздаване на папка „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "ДейÑтвието не Ñе поддържа" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Грешка при отварÑне на ÐºÐ»ÑŽÑ‡Ð¾Ð´ÑŠÑ€Ð¶Ð°Ñ‚ÐµÐ»Ñ â€ž%s“ за четене: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Ред %d на ÐºÐ»ÑŽÑ‡Ð¾Ð´ÑŠÑ€Ð¶Ð°Ñ‚ÐµÐ»Ñ â€ž%s“, Ñъдържащ „%s“, е повреден" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Първата лекÑема на ред %d на ÐºÐ»ÑŽÑ‡Ð¾Ð´ÑŠÑ€Ð¶Ð°Ñ‚ÐµÐ»Ñ â€ž%s“, Ñъдържащ „%s“, е повреден" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Втората лекÑема на ред %d на ÐºÐ»ÑŽÑ‡Ð¾Ð´ÑŠÑ€Ð¶Ð°Ñ‚ÐµÐ»Ñ â€ž%s“, Ñъдържащ „%s“, е повредена" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Ðе е намерена биÑквитка Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ %d в ÐºÐ»ÑŽÑ‡Ð¾Ð´ÑŠÑ€Ð¶Ð°Ñ‚ÐµÐ»Ñ Ð² „%s“" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Грешка при Ñъздаване на файла за ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ â€ž%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Грешка при изтриване на оÑÑ‚Ð°Ñ€ÐµÐ»Ð¸Ñ Ñ„Ð°Ð¹Ð» за ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ â€ž%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "" +"Грешка при затварÑне на възможно Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚Ð¸Ñ Ñ„Ð°Ð¹Ð» за ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ â€ž%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Грешка при изтриване на файла за ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ â€ž%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Грешка при отварÑне на ÐºÐ»ÑŽÑ‡Ð¾Ð´ÑŠÑ€Ð¶Ð°Ñ‚ÐµÐ»Ñ â€ž%s“ за запиÑ: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Допълнително, отключването на „%s“ бе Ñъщо неуÑпешно: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Връзката прекъÑна" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Времето за изчакване е проÑрочено" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Ðеподдържани флагове при Ñъздаване на изходÑща връзка" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "Обектът в „%s“ нÑма Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ â€žorg.freedesktop.DBus.Properties“" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "ЛипÑва ÑвойÑтво „%s“" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "СвойÑтвото „%s“ не поддържа четене" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "СвойÑтвото „%s“ не поддържа запиÑ" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Грешка при задаване на ÑвойÑтвото „%s“: Очакван е вид „%s“, а е получен „%s“" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "ЛипÑва Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ â€ž%s“" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "ЛипÑва Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ â€ž%s“ към обекта в „%s“" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "ЛипÑва метод „%s“" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Видът на Ñъобщението („%s“) не Ñъвпада Ñ Ð¾Ñ‡Ð°ÐºÐ²Ð°Ð½Ð¸Ñ („%s“)" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Вече е наличен обект за интерфейÑа „%s“ в „%s“" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "СвойÑтвото „%s.%s“ не може да бъде получено" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "СвойÑтвото „%s.%s“ не може да бъде зададено" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Методът „%s“ върна вид „%s“, а Ñе очаква „%s“" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Ðе ÑъщеÑтвува метод „%s“ на интерфейÑа „%s“ ÑÑŠÑ Ñигнатура „%s“" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Вече е изнеÑено поддърво за „%s“" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Обектът липÑва в Ð¿ÑŠÑ‚Ñ â€ž%s“" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "видът е „INVALID“" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" +"Съобщение „METHOD_CALL“: в заглавната чаÑÑ‚ липÑват полета „PATH“ или „MEMBER“" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" +"Съобщение „METHOD_RETURN“: в заглавната чаÑÑ‚ липÑва поле „REPLY_SERIAL“" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Съобщение „ERROR“: в заглавната чаÑÑ‚ липÑват полета „REPLY_SERIAL“ или " +"„ERROR_NAME“" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Съобщение „SIGNAL“: в заглавната чаÑÑ‚ липÑват полета „PATH“, „INTERFACE“ или " +"„MEMBER“" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Съобщение „SIGNAL“: Полето „PATH“ в заглавната чаÑÑ‚ използва запазената " +"ÑтойноÑÑ‚ „/org/freedesktop/DBus/Local“" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Съобщение „SIGNAL“: Полето „INTERFACE“ в заглавната чаÑÑ‚ използва запазената " +"ÑтойноÑÑ‚ „org.freedesktop.DBus.Local“" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "При опит за четене на %lu байт бÑха получени %lu" +msgstr[1] "При опит за четене на %lu байта бÑха получени %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "След низа „%s“ Ñе очаква байт NUL, а не %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Очаква Ñе низ, кодиран в UTF-8, а Ñа получени неправилни байтове при " +"отмеÑтване %d (дължината на низа е %d). ДекодираниÑÑ‚ от UTF-8 низ до тази " +"Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ðµ „%s“" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Прекалено дълбоко вложена ÑтойноÑÑ‚" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Ðнализираната ÑтойноÑÑ‚ „%s“ не е допуÑтим път до обект в D-Bus" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Ðнализираната ÑтойноÑÑ‚ „%s“ не е допуÑтима Ñигнатура в D-Bus" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Срещнат е маÑив Ñ Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð° %u байт. МакÑималната дължина е 2²ⶠ(64 MiB)" +msgstr[1] "" +"Срещнат е маÑив Ñ Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð° %u байта. МакÑималната дължина е 2²ⶠ(64 MiB)" + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Получен бе маÑив от вид „a%c“. Очакваше Ñе да има дължина делима на %u " +"байта, но Ñ‚Ñ Ð±Ðµ %u байта" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Празни Ñтруктури (n-орки) не Ñа позволени в D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Ðнализираната вариантна ÑтойноÑÑ‚ „%s“ не е допуÑтима Ñигнатура в D-Bus" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Грешка при деÑериализиране на „GVariant“ от вид „%s“ от Ð¼Ð°ÑˆÐ¸Ð½Ð½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ на D-" +"Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"ÐедопуÑтима ÑтойноÑÑ‚ на индикатора за подреждане на байтовете в думи. Очаква " +"Ñе или 0x6c („l“), или 0x42 („B“), а е открита ÑтойноÑÑ‚ 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "ÐедопуÑтима главна верÑÐ¸Ñ Ð½Ð° протокола. Очаква Ñе 1, а е открита %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Заглавната чаÑÑ‚ ÑÑŠÑ Ñигнатура е намерена, на Ñ‚Ñ Ð½Ðµ е за вид" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Открита е заглавна чаÑÑ‚ ÑÑŠÑ Ñигнатура „%s“, обаче Ñ‚Ñлото на Ñъобщението е " +"празно" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Разчетената ÑтойноÑÑ‚ „%s“ не е допуÑтима Ñигнатура в D-Bus (за Ñ‚Ñло)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Ð’ заглавната чаÑÑ‚ на Ñъобщението нÑма Ñигнатура, а Ñ‚Ñлото е %u байт" +msgstr[1] "" +"Ð’ заглавната чаÑÑ‚ на Ñъобщението нÑма Ñигнатура, а Ñ‚Ñлото е %u байта" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "ÐеуÑпешно декодиране на Ñъобщение: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Грешка при Ñериализиране на „GVariant“ от вид „%s“ в Ð¼Ð°ÑˆÐ¸Ð½Ð½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ на D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"БроÑÑ‚ файлови деÑкриптори в Ñъобщението (%d) е различно от Ð±Ñ€Ð¾Ñ Ð² заглавното " +"поле (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "ÐеуÑпешна ÑÐµÑ€Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° Ñъобщението: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"ТÑлото на Ñъобщението има Ñигнатура „%s“, но нÑма заглавна чаÑÑ‚ за Ñигнатура" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"ТÑлото на Ñъобщението има Ñигнатура за вид „%s“, но полето в заглавната чаÑÑ‚ " +"за Ñигнатури е „%s“" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"ТÑлото на Ñъобщението е празно, а Ñигнатурата в полето на заглавната чаÑÑ‚ е " +"„(%s)“" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Връщане на грешка Ñ Ñ‚Ñло от вид „%s“" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Връщане на грешка Ñ Ð¿Ñ€Ð°Ð·Ð½Ð¾ Ñ‚Ñло на Ñъобщението" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Въведете произволен знак, за да затворите този прозорец)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"Шината на ÑеÑиÑта D-Bus не е Ñтартирана. Ðвтоматичното Ñ Ñтартиране бе Ñъщо " +"неуÑпешно" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "ÐеуÑпешно определÑне на Ñ…Ð°Ñ€Ð´ÑƒÐµÑ€Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "ÐеуÑпешно зареждане на „%s“ или „%s“: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Грешка при извикване на „StartServiceByName“ за %s:" + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Ðеочакван отговор „%d“ от метода „StartServicebyName(\"%s\")“" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ðе може да Ñе направи обръщение към метода. ПоÑредникът е за извеÑтно име " +"без ÑобÑтвеник „%s“, а е Ñъздаден Ñ Ñ„Ð»Ð°Ð³Ð° " +"„G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START“" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Ðе Ñе поддържа абÑтрактно проÑтранÑтво за имена" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Ðе може да Ñе задава моментен файл при Ñъздаване на Ñървър" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Грешка при Ð·Ð°Ð¿Ð¸Ñ Ð² моментен файл „%s“: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Ðизът „%s“ не е допуÑтим глобален идентификатор (GIUD) в D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Ðевъзможно е да Ñе чака за връзки по неподдържан транÑпорт „%s“" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Команди:\n" +" help Извеждане на този текÑÑ‚\n" +" introspect Ðнализ на отдалечен обект\n" +" monitor Ðаблюдение на отдалечен обект\n" +" call Обръщане към метод на отдалечен обект\n" +" emit Издаване на Ñигнал\n" +" wait Изчакване да Ñе поÑви името\n" +"\n" +"Използвайте „%s КОМÐÐДР--help“ за допълнителна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° вÑÑка " +"команда.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Грешка: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Грешка при анализа на XML Ñ Ð°Ð½Ð°Ð»Ð¸Ñ‚Ð¸Ñ‡Ð½Ð° информациÑ: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Грешка: „%s“ не е вÑрно име\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Грешка: „%s“ не е допуÑтим път до обект\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Свързване към ÑиÑтемната шина" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Свързване към ÑеÑийната шина" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Свързване към даден Ð°Ð´Ñ€ÐµÑ Ð½Ð° D-Bus" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Варианти за връзка:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Опции, указващи точката за връзка" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Ðе е указана точка за връзка" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Указани Ñа множеÑтво точки за връзка" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Предупреждение: Според анализа интерфейÑÑŠÑ‚ „%s“ не ÑъщеÑтвува\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Предупреждение: Според анализа методът „%s“ не Ñе предлага от интерфейÑа " +"„%s“\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Ðезадължителен получател на Ñигнала (уникално име)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Път до обекта, към който да Ñе излъчи Ñигнал" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Име на Ñигнал и интерфейÑ" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Издаване на Ñигнал." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Грешка при Ñвързване: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Грешка: „%s“ не е вÑрно, уникално име на шина\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Грешка: Ðе е указан път до обект\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Грешка: Ðе е указано име на Ñигнал\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Грешка: „%s“ не е допуÑтимо име на Ñигнал\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Грешка: „%s“ не е допуÑтимо име на интерфейÑ\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Грешка: „%s“ не е допуÑтимо име на член\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Грешка при анализ на параметър %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "" +"Грешка при изчиÑтване на буферите при предаването на данните на връзка: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Целево име, към чийто метод да Ñе направи обръщение" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Път до обект, към чийто метод да Ñе направи обръщение" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Име на метод и интерфейÑ" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Време за изчакване в Ñекунди" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "ПозволÑване на интерактивно упълномощаване" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Обръщение към метод на отдалечен обект" + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Грешка: не е указана цел\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Грешка: „%s“ е неправилно име на шина\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Грешка: Ðе е указано име на метод\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Грешка: „%s“ е неправилно име на метод\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Грешка при анализ на параметър %d от вид „%s“: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Грешка при добавÑне на Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð·Ð° обработка %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Име на целта за анализ" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Път до обекта за анализ" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Извеждане на XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Ðнализ на наÑледниците" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Извеждане Ñамо на ÑвойÑтвата" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Ðнализ на отдалечен обект." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Име на целта за наблюдение" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Път до обекта за наблюдение" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Ðаблюдение на отдалечен обект." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "ГРЕШКÐ: може да Ñе наблюдават Ñамо връзки към шината за ÑъобщениÑ\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" +"УÑлуга за задейÑтване преди изчакване на другата (трÑбва да е извеÑтно име)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Време за изчакване в Ñекунди преди изход Ñ Ð³Ñ€ÐµÑˆÐºÐ°. Стандартно е 0 за " +"изчакване без ограничение" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[ОПЦИЯ…] ИМЕ_ПО_ШИÐÐ" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Изчакване за поÑвата на името по шината." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Грешка: не е указана уÑлуга за задейÑтване.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Грешка: не е указана уÑлуга за изчакване.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Грешка: Твърде много аргументи.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Грешка: „%s“ не е извеÑтно име на шина.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "ÐÑма права за ÑмÑната на наÑтройки за изчиÑтване на грешки" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Без име" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Във файла „.desktop“ липÑва поле за изпълнение (Exec)" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Ðе може да Ñе открие терминал за приложението" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Ðе може да Ñе Ñъздаде папката Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñките наÑтройки %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Ðе може да Ñе Ñъздаде папката Ñ Ð½Ð°Ñтройките за MIME %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Ð’ информациÑта за програма липÑва идентификатор" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Ðе може да Ñе Ñъздаде файл „.desktop“: „%s“" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "ПотребителÑка Ð´ÐµÑ„Ð¸Ð½Ð¸Ñ†Ð¸Ñ Ð·Ð° %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "уÑтройÑтвото не поддържа изваждане" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "уÑтройÑтвото не поддържа нито изваждане, нито изваждане Ñ Ð´ÐµÐ¹Ñтвие" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "уÑтройÑтвото не поддържа Ñледене за ноÑител" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "уÑтройÑтвото не поддържа Ñтартиране" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "уÑтройÑтвото не поддържа Ñпиране" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "Поддръжката на TLS е без изтеглÑне на Ñвързването по TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "ЛипÑва поддръжка на TLS" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "ЛипÑва поддръжка на DTLS" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "ВерÑÐ¸Ñ %d на кодирането „GEmblem“ не Ñе поддържа" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Ðеправилен брой лекÑеми (%d) в кодирането „GEmblem“" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "ВерÑÐ¸Ñ %d на кодирането „GEmblemedIcon“ не Ñе поддържа" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Ðеправилен брой лекÑеми (%d) в кодирането „GEmblemedIcon“" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Очакваше Ñе „GEmblem“ за „GEmblemedIcon“" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "СъдържащиÑÑ‚ монтиран обект не ÑъщеÑтвува" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Ðе може да Ñе копира върху папка" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Папка не може да Ñе копира върху папка" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "ЦелевиÑÑ‚ файл ÑъщеÑтвува" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Папката не може да Ñе копира рекурÑивно" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Ðе Ñе поддържа прилепване (splice)" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Грешка при прилепване (splice) на файл: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"Копирането между различни монтирани дÑлове чрез „reflink“/„clone“ не Ñе " +"поддържа" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" +"Копирането чрез „reflink“/„clone“ не Ñе поддържа или е извършено неправилно" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Копирането чрез „reflink“/„clone“ не Ñе поддържа или не проработи" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Ðе може да Ñе копира Ñпециален файл" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Зададена е неправилна ÑтойноÑÑ‚ на Ñимволна връзка" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Символни връзки не Ñе поддържат" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Ðе Ñе поддържа кошче" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Файловите имена не може да Ñъдържат „%c“" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "томът не поддържа монтиране" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Ðе е региÑтрирано приложение за обработка на този вид файлове" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "БроÑчът е затворен" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ФайловиÑÑ‚ броÑч вÑе още не е привършил" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ФайловиÑÑ‚ броÑч вече е затворен" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "ВерÑÐ¸Ñ %d на кодирането „GFileIcon“ не Ñе поддържа" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Ðеправилни входни данни за „GFileIcon“" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Потокът не поддържа запитване за Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ („query_info“)" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ТърÑенето не Ñе поддържа от потока" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ВходниÑÑ‚ поток не може да Ñе Ñъкращава" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Потокът не може да Ñе Ñъкращава" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Ðеправилно име на хоÑÑ‚" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Ðеправилен отговор от Ñървъра-поÑредник по HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Ðе е позволена връзка към Ñървъра-поÑредник по HTTP" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "ÐеуÑпешна Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿Ñ€ÐµÐ´ Ñървъра-поÑредник по HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "ИзиÑква Ñе Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿Ñ€ÐµÐ´ Ñървъра-поÑредник по HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "ÐеуÑпешна връзка към Ñървъра-поÑредник по HTTP: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Отговорът от Ñървъра-поÑредник по HTTP е прекалено дълъг" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Сървърът-поÑредник по HTTP неочаквано прекрати връзката" + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Ðеправилен брой лекÑеми (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "ЛипÑва вид за името на ÐºÐ»Ð°Ñ â€ž%s“" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Видът „%s“ не поддържа интерфейÑа „GIcon“" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Видът „%s“ не е клаÑ" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Ðеправилен номер на верÑиÑ: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Видът „%s“ не поддържа „from_tokens()“ от интерфейÑа „GIcon“" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Подадената верÑÐ¸Ñ Ð½Ð° кодирането на икони не Ñе поддържа" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Ðе е указан адреÑ" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Дължината на адреÑа %u е прекалено голÑма" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Ð’ адреÑа Ñа зададени битове Ñлед префикÑа му" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "„%s“ не е маÑка за адреÑи на IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "ÐÑма доÑтатъчно мÑÑто за адреÑа на гнездо" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Ðеподдържан Ð°Ð´Ñ€ÐµÑ Ð½Ð° гнездо" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "ВходниÑÑ‚ поток не поддържа четене" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "ДейÑтвиÑта върху потока не Ñа привършили" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Копиране ÑÑŠÑ Ñ„Ð°Ð¹Ð»Ð°" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Да Ñе меÑти заедно Ñ Ñ„Ð°Ð¹Ð»Ð°" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "„version“ не приема аргументи" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Употреба:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Извеждане на верÑиÑта и изход." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Команди:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "ОбединÑване на Ñъдържанието на файловете на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð¸Ð·Ñ…Ð¾Ð´" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Копиране на един или повече файлове" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Извеждане на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° меÑтоположениÑта" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Стартиране на приложение чрез файл „.desktop“" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Извеждане на Ñъдържанието на меÑтоположениÑта" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "" +"Получаване или задаване на програмата за обработка на определен вид по MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Създаване на папки" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Ðаблюдаване на файлове и директории за промени" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Монтиране/демонтиране на меÑтоположение" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "ПремеÑтване на един или повече файлове" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "ОтварÑне на файлове ÑÑŠÑ Ñтандартната програма" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Преименуване на файл" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Изтриване на един или повече файлове" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Изчитане от ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð²Ñ…Ð¾Ð´ и запазване" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Задаване на файлов атрибут" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "ПремеÑтване на файлове или папки в кошчето" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Извеждане на Ñъдържанието на меÑтоположение в дървовиден изглед" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Въведете %s за подробна помощ.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Грешка при извеждане към ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð¸Ð·Ñ…Ð¾Ð´" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "МЕСТОПОЛОЖЕÐИЕ" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" +"ОбединÑване на Ñъдържанието на файловете и извеждане на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð¸Ð·Ñ…Ð¾Ð´." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"„gio cat“ е аналог на „cat“, но Ñе ползват меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ GIO, а не " +"локални\n" +"файлове. Така може да ползвате „smb://server/resource/file.txt“, например." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Ðе Ñа дадени меÑтоположениÑ" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ðе е зададена целева папка" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Извеждане на прогреÑа" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Питане преди презапиÑ" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Запазване на вÑички атрибути" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Резервно копие на ÑъщеÑтвуващи целеви файлове" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Без проÑледÑване на Ñимволни връзки" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Стандартни права за целта" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Прехвърлени Ñа %s от общо %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ИЗТОЧÐИК" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ЦЕЛ" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Копиране на един или повече файлове от ИЗТОЧÐИКа към ЦЕЛта." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"„gio copy“ е аналог на „cp“, но Ñе ползват меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ GIO, а не " +"локални\n" +"файлове. Така може да ползвате „smb://server/resource/file.txt“, например." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Целта „%s“ не е папка" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: да Ñе презапише ли „%s“? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "СпиÑък на атрибутите, които може да Ñе запишат" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Получаване на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° файловата ÑиÑтема" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Ðтрибути за получаване" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ÐТРИБУТИ" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Без проÑледÑване на Ñимволни връзки" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "атрибути:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "име за показване: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "име за редактиране: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "име: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "вид: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "размер: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "Ñкрит\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "адреÑ: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "локален път: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "монтирано по unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Ðтрибути за задаване:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "ПроÑтранÑтва от имена на атрибути за запиÑ:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Извеждане на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° меÑтоположениÑта." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"„gio info“ е аналог на „ls“, но Ñе ползват меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ GIO, а не " +"локални\n" +"файлове. Така може да ползвате „smb://server/resource/file.txt“, например.\n" +"Файловите атрибути Ñъщо Ñе указват Ñ Ð¸Ð¼ÐµÑ‚Ð¾ им по GIO, напр: „standard::" +"icon“,\n" +"проÑто чрез името на проÑтранÑтвото от имена „unix“ или „*“, което " +"ÑъответÑтва\n" +"на вÑички атрибути" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "ФÐЙЛ_DESKTOP [ÐРГУМЕÐТ_ФÐЙЛ …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Стартиране на приложение от файл „desktop“ като може да Ñе добавÑÑ‚ аргументи-" +"имена на файлове." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Ðе е указан файл „desktop“" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Командата за Ñтартиране не Ñе поддържа на тази платформа" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Ðе може да Ñе зареди „%s“: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Ðе може да Ñе зареди информациÑта за приложението „%s“" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Ðе може да Ñе Ñтартира приложението „%s“: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Показване на Ñкритите файлове" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Подробен формат на извеждане" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Отпечатване на имената за показване" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Отпечатване на целите адреÑи" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "ИзброÑване на Ñъдържанието на меÑтоположениÑта." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon<\n" +"\n" +"„gio list“ е аналог на „ls“, но Ñе ползват меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ GIO, а не\n" +"локални файлове. Така може да ползвате „smb://server/resource/file.txt“,\n" +"например. Файловите атрибути Ñъщо Ñе указват Ñ Ð¸Ð¼ÐµÑ‚Ð¾ им по GIO, напр:\n" +"„standard::icon“" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "ВИД_MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "ОБРÐБОТВÐЩÐ_ПРОГРÐМÐ" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Получаване или задаване на ОБРÐБОТВÐЩÐта_ПРОГРÐМРза даден ВИД_MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Ðко не е указано обработващо приложение, Ñе извеждат региÑтрирани и " +"препоръчани\n" +"програми за този вид MIME. Ðко е указана такова, то Ñе задава като " +"Ñтандартното\n" +"за обработка на този вид MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "ТрÑбва да укажете точно един вид MIME и макÑимум едно приложение" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "ÐÑма Ñтандартно приложение за „%s“\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Стандартно приложение за „%s“: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "РегиÑтрирани приложениÑ:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "ÐÑма региÑтрирани приложениÑ:\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Препоръчани приложениÑ:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "ÐÑма препоръчани приложениÑ:\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "ÐеуÑпешно зареждане на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° функциÑта за обработка „%s“" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"„%s“ не може да Ñе зададе като Ñтандартното приложение за обработка на „%s“: " +"%s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Създаване на родителÑките папки" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Създаване на папки." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"„gio mkdir“ е аналог на „mkdir“, но Ñе ползват меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ GIO, а не\n" +"локални файлове. Така може да ползвате „smb://server/resource/file.txt“,\n" +"например." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Следене на Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ (Ñтандартно: завиÑи от вида)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Следене на файл (Ñтандартно: завиÑи от вида)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Директно Ñледене на файл (отбелÑзват Ñе промени през твърди връзки)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Директно Ñледене на файл без докладване на промени" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Докладване на премеÑтваниÑта/преименуваниÑта като проÑти ÑÑŠÐ±Ð¸Ñ‚Ð¸Ñ Ð·Ð° " +"изтриване и Ñъздаване наново" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Следене за ÑÑŠÐ±Ð¸Ñ‚Ð¸Ñ Ð¿Ð¾ монтиране" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Следене на файлове или директории за промени." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Монтиране като подлежащо за монтиране" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Монтиране на том чрез файла му за уÑтройÑтво или друг идентификатор" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ИДЕÐТИФИКÐТОР" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Демонтиране" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Изваждане" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Спиране на уÑтройÑтвото, отговарÑщо на файла за уÑтройÑтво" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "УСТРОЙСТВО" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Демонтиране на вÑичко монтирано Ñ Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ‚Ð° Ñхема" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "СХЕМÐ" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "При демонтиране или изваждане предÑтоÑщите операции да Ñе преÑкочат" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ ÐºÐ°Ñ‚Ð¾ анонимен потребител" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "ИзброÑване" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Ðаблюдаване на ÑъбитиÑта" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Показване на допълнителна информациÑ" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" +"Личен мултипликатор на итерациите (PIM) при дешифрирането на том на VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Монтиране на том Ñкрит Ñ TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Монтиране на ÑиÑтемен том Ñ TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "ÐнонимниÑÑ‚ доÑтъп е отказан" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "ÐÑма уÑтройÑтво към файла за уÑтройÑтво" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "ÐÑма том Ñ Ñ‚Ð°ÐºÑŠÐ² идентификатор" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Монтиране или демонтиране на меÑтоположениÑта." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Без Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¸Ñ Ð²Ð°Ñ€Ð¸Ð°Ð½Ñ‚ Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ðµ и поÑледващо изтриване" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "ПремеÑтване на един или повече файлове от ИЗТОЧÐИКа към ЦЕЛта." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"„gio move“ е аналог на „mv“, но Ñе ползват меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ GIO, а не " +"локални\n" +"файлове. Така може да ползвате „smb://server/resource/file.txt“, например" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Целта „%s“ не е папка" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"ОтварÑне на файлове ÑÑŠÑ Ñтандартното приложение, което\n" +"е региÑтрирано да обработва файлове от този вид." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "ПреÑкачане на неÑъщеÑтвуващите файлове без предупреждаване" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Изтриване на изброените файлове." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "ИМЕ" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Преименуване на файл." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "ЛипÑва аргумент" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Прекалено много аргументи" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "УÑпешно преименуване. ÐовиÑÑ‚ Ð°Ð´Ñ€ÐµÑ Ðµ: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Създаване, ако не ÑъщеÑтвува" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "ДобавÑне към ÐºÑ€Ð°Ñ Ð½Ð° файла" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "При Ñъздаване ограничаване на права до такива за Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "При замеÑтване да Ñе замеÑтва вÑе едно целта не ÑъщеÑтвува" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Отпечатване на нов ETAG в краÑ" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Етикетът ETAG на файла, който Ñе презапиÑва" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Грешка при четене от ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð²Ñ…Ð¾Ð´" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "ЛипÑва ETAG\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Четене от ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð²Ñ…Ð¾Ð´ и Ð·Ð°Ð¿Ð¸Ñ Ð² ЦЕЛта." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Ðе е зададена цел" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Вид атрибут" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "ВИД" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ÐТРИБУТ" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "СТОЙÐОСТ" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Задаване на файлов атрибут МЕСТОПОЛОЖЕÐИЕ." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "МеÑтоположението не е указано" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Ðтрибутът не е указан" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "СтойноÑтта не е указана" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Ðеправилен вид на атрибут „%s“" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "ИзчиÑтване на кошчето" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "" +"СпиÑък на файловете в кошчето заедно Ñ Ð¿ÑŠÑ€Ð²Ð¾Ð½Ð°Ñ‡Ð°Ð»Ð½Ð¾Ñ‚Ð¾ им меÑтоположение" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"ВъзÑтановÑване на файл от кошчето в първоначалното му меÑтоположение (това " +"може да доведе до възÑтановÑване на папка)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "ПървоначалниÑÑ‚ път не може да бъде открит" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Първоначалното меÑтоположение не може да Ñе възÑтанови: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Този файл не може да Ñе премеÑти на първоначалното Ñи меÑтоположение: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "ПремеÑтване/възÑтановÑване на файлове или директории от кошчето." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Бележка: ако на оригиналното меÑтоположение ÑъответÑтващо обекта поÑочен " +"към\n" +"опциÑта „--restore“ ÑъщеÑтвува, то нÑма да бъде презапиÑано, оÑвен ако не е\n" +"дадена и опциÑта „--force“." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "МеÑтоположението не започва Ñ â€žtrash:///“" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" +"ПроÑледÑване на Ñимволните връзки, монтираните уÑтройÑтва и уÑкорителите" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Извеждане на Ñъдържанието на директориите в дървовиден вариант." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Елементът <%s> не е позволен в <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Елементът <%s> не е позволен на най-горно ниво" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Файлът „%s“ приÑÑŠÑтва многократно в реÑурÑа" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "„%s“ липÑва във вÑички папки за реÑурÑи" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "„%s“ липÑва в текущата папка" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Ðепозната Ð¾Ð¿Ñ†Ð¸Ñ Ð·Ð° обработка „%s“" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"ЗаÑвена е предварителна обработка Ñ â€ž%s“, но „%s“ не е зададен, а и „%s“ не " +"е в „PATH“" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Грешка при четене на файл „%s“: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Грешка при компреÑиране на файл: %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "в <%s> не е позволен текÑÑ‚" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Извеждане на верÑиÑта на програмата и изход" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Име на Ð¸Ð·Ñ…Ð¾Ð´Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Папката откъдето да Ñе заредÑÑ‚ файловете, указани във ФÐЙЛа (Ñтандартно е " +"текущата)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "ПÐПКÐ" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Формат на изхода Ñпоред разширението на Ð¸Ð·Ñ…Ð¾Ð´Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Заглавни чаÑти" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Генериране на Ð¸Ð·Ñ…Ð¾Ð´Ð½Ð¸Ñ ÐºÐ¾Ð´ за Ñвързване на реÑурÑÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð» в кода ви" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "СпиÑък ÑÑŠÑ Ð·Ð°Ð²Ð¸ÑимоÑтите" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Име на файл ÑÑŠÑ Ð·Ð°Ð²Ð¸ÑимоÑти, който да Ñе генерира" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Включване на изкуÑтвените цели в генерираните файлове ÑÑŠÑ Ð·Ð°Ð²Ð¸ÑимоÑти" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Без автоматично генериране и региÑтриране на реÑурÑи" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ðе изнаÑÑйте функции. Декларирайте ги Ñ â€žG_GNUC_INTERNAL“" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Без вграждане на реÑурÑните данни във файла на C — приемане, че е Ñвързан" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Идентификатор на C за Ð³ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ð½Ð¸Ñ Ð¸Ð·Ñ…Ð¾Ð´ÐµÐ½ код" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "" +"Целеви компилатор на C (Ñтандартно: Ñъдържанието на променливата на Ñредата " +"„CC“)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Компилиране на файловете Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð·Ð° реÑурÑи в реÑурÑен файл.\n" +"Файловете за указване на реÑурÑи трÑбва да завършват на „.gresource.xml“,\n" +"а реÑурÑниÑÑ‚ файл — на „.gresource“." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "ИзиÑква Ñе точно едно име на файл\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "пÑевдонимът трÑбва да е поне 2 знака" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Ðеправилна чиÑлова ÑтойноÑÑ‚" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr "вече е указано " + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' вече е указано" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "ÑтойноÑтта за флаговете трÑбва да има поне един зададен бит" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> трÑбва да Ñъдържа поне един възел " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> липÑва в ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> не е правилен член на ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð¸Ð·Ð±Ñ€Ð¾Ð¸Ð¼ вид" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> Ñъдържа низ, който не е в ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð²Ð¸Ð´ за флагове" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> Ñъдържа низ, който липÑва в " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " вече е указано за ключа" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " не Ñе позволÑва за ключове от вида „%s“" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "указаниÑÑ‚ минимум за е по-голÑм от макÑимума" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "неподдържана ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ð·Ð° локализиране: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "изиÑкано е локализиране, но липÑва облаÑÑ‚ на „gettext“" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "даден е преводачеÑки контекÑÑ‚ за ÑтойноÑÑ‚ без локализиране" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "ÐеуÑпешен анализ на ÑтойноÑтта за от вида „%s“: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" не може да Ñе указва за ключове, които Ñа отбелÑзани, че Ñа от " +"изброим вид" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " вече е указано за този ключ" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " не е позволен за ключове от вид „%s“" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " вече е указано за този ключ" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " трÑбва да Ñъдържа поне един " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " вече е указано за този ключ" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" може да Ñе указва Ñамо за ключове от изброим или флагов вид или " +"Ñлед " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" е указано, но „%s“ вече е е член на е Ð¸Ð·Ð±Ñ€Ð¾Ð¸Ð¼Ð¸Ñ Ð²Ð¸Ð´" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " е указано, но вече е зададен" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " вече е указано за този ключ" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "целта на пÑевдоним „%s“ не е изброим вид" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "целта на пÑевдоним „%s“ не е в " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " трÑбва да Ñъдържа поне един " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Празни имена не Ñа позволени" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Ðеправилно име „%s“: имената трÑбва да започват Ñ Ð¼Ð°Ð»ÐºÐ° буква" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Ðеправилно име „%s“: неправилен знак „%c“ — позволени Ñа Ñамо малки букви, " +"цифри и тире („-“)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Ðеправилно име „%s“: не Ñа позволени две поÑледователни тирета („--“)" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Ðеправилно име „%s“: поÑледниÑÑ‚ знак не може да е тире („-“)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Ðеправилно име „%s“: макÑималната дължина е 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " вече е указано" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Към Ñхема „list-of“ не може да Ñе добавÑÑ‚ ключове" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " вече е указано" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" заÑенчва в . Използвайте " +", за да промените ÑтойноÑтта" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Като атрибут на трÑбва да приÑÑŠÑтва точно едно от „type“, „enum“ или " +"„flags“" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> не е дефинирано (вÑе още)." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Ðеправилен низ за вид на „GVariant“: „%s“" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "Използвано е , но Ñхемата не разширÑва нищо" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "ЛипÑва за предефиниране" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr "Вече е указано " + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr "Вече е указано " + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " Ð´Ð¾Ð±Ð°Ð²Ñ ÐºÑŠÐ¼ Ñхема „%s“, коÑто още не ÑъщеÑтвува" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " е ÑпиÑък на Ñхема „%s“, коÑто още не ÑъщеÑтвува" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Ðе може да е ÑпиÑък от Ñхема Ñ Ð¿ÑŠÑ‚" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Схема не може да Ñе разширÑва Ñ Ð¿ÑŠÑ‚" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" е ÑпиÑък, разширÑващ , коÑто не е ÑпиÑък" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" разширÑва , но " +"„%s“ не разширÑва „%s“" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Ð’Ñеки път трÑбва да започва и да завършва Ñ Ð½Ð°ÐºÐ»Ð¾Ð½ÐµÐ½Ð° черта („/“)" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "ПътÑÑ‚ на ÑпиÑък трÑбва да завършва Ñ â€ž:/“" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"ПРЕДУПРЕЖДЕÐИЕ: Ñхемата „%s“ Ñъдържа Ð¿ÑŠÑ‚Ñ â€ž%s“. Пътищата, които започват Ñ â€ž/" +"apps/“, „/desktop/“ или „/system/“ Ñа оÑтарели." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "вече е указано <%s id='%s'>" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Само един елемент <%s> е позволен в <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Елементът <%s> не е позволен на най-горно ниво" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Задължително е в да има елемент " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Ð’ <%s> не е позволен текÑÑ‚" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "ПРЕДУПРЕЖДЕÐИЕ: недефиниран указател към " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "Указано е „--strict“, изход." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "ЦелиÑÑ‚ файл е пренебрегнат." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Пренебрегване на файла." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"ЛипÑва ключ „%s“ в Ñхемата „%s“, указан във файла за предефиниране „%s“. " +"Това предифиниране Ñе преÑкача." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"ЛипÑва ключ „%s“ в Ñхемата „%s“, указан във файла за предефиниране „%s“, " +"зададена е и опциÑта „--strict“, затова програмата приключва." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Ðе може да Ñе предоÑтави предефиниране за вÑÑка работна Ñреда за " +"Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð¸Ñ€Ð°Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ „%s“ в Ñхемата „%s“ (файлът Ñ Ð¿Ñ€ÐµÐ´ÐµÑ„Ð¸Ð½Ð¸Ñ€Ð°Ð½Ð° ÑтойноÑÑ‚ е " +"„%s“). Това предифиниране Ñе преÑкача." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Ðе може да Ñе предоÑтави предефиниране за вÑÑка работна Ñреда за " +"Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð¸Ñ€Ð°Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ „%s“ в Ñхемата „%s“ (файлът Ñ Ð¿Ñ€ÐµÐ´ÐµÑ„Ð¸Ð½Ð¸Ñ€Ð°Ð½Ð° ÑтойноÑÑ‚ е " +"„%s“), зададена е и опциÑта „--strict“, затова програмата приключва." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Грешка при анализиране на ключа „%s“ от Ñхемата „%s“, указан във файла за " +"предефиниране „%s“ — %s. Това предифиниране Ñе преÑкача." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Грешка при анализиране на ключа „%s“ от Ñхемата „%s“, указан във файла за " +"предефиниране „%s“ — %s, зададена е и опциÑта „--strict“, затова програмата " +"приключва." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Предефинирането на ключа „%s“ в Ñхемата „%s“ във файла за предефиниране „%s“ " +"е извън обÑега, даден в Ñхемата. Това предифиниране Ñе преÑкача." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Предефинирането на ключа „%s“ в Ñхемата „%s“ във файла за предефиниране „%s“ " +"е извън обÑега, даден в Ñхемата, зададена е и опциÑта „--strict“, затова " +"програмата приключва." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Предефинирането на ключа „%s“ в Ñхемата „%s“ във файла за предефиниране „%s“ " +"не е в ÑпиÑъка Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑтойноÑти. Това предифиниране Ñе преÑкача." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Предефинирането на ключа „%s“ в Ñхемата „%s“ във файла за предефиниране „%s“ " +"не е в ÑпиÑъка Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑтойноÑти, зададена е и опциÑта „--strict“, " +"затова програмата приключва." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "МÑÑто за ÑъхранÑване на файла „gschemas.compiled“" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "ПрекъÑване на работа при вÑÑкакви грешки в Ñхемите" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Без Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° файл „gschema.compiled“" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Без налагане на ограничениÑта за имена на ключове" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Компилиране на вÑички файлове ÑÑŠÑ Ñхеми за „GSettings“ в кеш.\n" +"Файловете ÑÑŠÑ Ñхемите трÑбва да завършват на „.gschema.xml“,\n" +"а файлът Ñ ÐºÐµÑˆÐ° Ñе нарича „gschemas.compiled“." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "ИзиÑква Ñе точно едно име на папка" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Ðе Ñа открити файлове ÑÑŠÑ Ñхеми: нищо нÑма да Ñе прави." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Ðе Ñа открити файлове ÑÑŠÑ Ñхеми: ÑъщеÑтвуващиÑÑ‚ резултатен файл е премахнат." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Ðеправилно име на файл: %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Грешка при получаване на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° файловата ÑиÑтема за „%s“: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "СъдържащиÑÑ‚ монтиран обект за файла „%s“ не ÑъщеÑтвува" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Кореновата папка не може да Ñе преименува" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Грешка при преименуване на файла „%s“: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Файлът не може да Ñе преименува — ÑъщеÑтвува друг файл Ñ Ñ‚Ð°ÐºÐ¾Ð²Ð° име" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Ðеправилно име на файл" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Грешка при отварÑне на файла „%s“: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Грешка при изтриване на файла „%s“: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Грешка при премеÑтване на файл в кошчето „%s“: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "ÐеуÑпешно Ñъздаване на папката за кошче „%s“: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "" +"Ðе може да Ñе открие най-горната папка за премеÑтване в кошчето на „%s“" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"ПремеÑтване в кошчето на монтираните вътрешни ÑиÑтемни томове не Ñе поддържа" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Ðе може да Ñе Ñъздаде папката за кошче „%s“ за изхвърлÑнето на „%s“" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "ÐеуÑпешно Ñъздаване на файл Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° кошчето за „%s“: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "ÐеуÑпешно премеÑтване на файл в кошче на друга файлова ÑиÑтема: %s" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "ÐеуÑпешно премеÑтване на файл в кошчето „%s“: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "ÐеуÑпешно премеÑтване на файл в кошчето „%s“" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Грешка при Ñъздаване на папка „%s“: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Файловата ÑиÑтема не поддържа Ñимволни връзки" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Грешка при Ñъздаване на Ñимволна връзка „%s“: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Грешка при премеÑтване на файл „%s“: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Папка не може да бъде премеÑтена върху папка" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "ÐеуÑпешно Ñъздаване на резервен файл" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Грешка при премахване на Ñ†ÐµÐ»ÐµÐ²Ð¸Ñ Ñ„Ð°Ð¹Ð»: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Ðе Ñе поддържа меÑтене между монтирани меÑтоположениÑ" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ðе може да Ñе определи заетото мÑÑто на %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "СтойноÑтта на атрибут не трÑбва да е NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Ðеправилен вид на атрибут (очакваше Ñе низ)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Ðеправилно име на допълнителен атрибут" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Грешка при задаване на разширен атрибут „%s“: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (неправилно кодиране)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Грешка при получаване на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° файла „%s“: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Грешка при получаване на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¸Ñ Ð´ÐµÑкриптор: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ðеправилен вид на атрибут (очакваше Ñе uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ðеправилен вид на атрибут (очакваше Ñе uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ðеправилен вид на атрибут (очакваше Ñе низ от байтове)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Грешка при задаване на правата за доÑтъп на Ñимволната връзка" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Грешка при задаване на правата за доÑтъп: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Грешка при задаване на ÑобÑтвеник: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "Ñимволната връзка трÑбва да не е NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Грешка при задаване на Ñимволна връзка: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Грешка при задаване на Ñимволна връзка: файлът не е такава" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"Допълнителните наноÑекунди %d за времевото клеймо по UNIX %lld Ñа отрицателни" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Допълнителните наноÑекунди %d за времевото клеймо по UNIX %lld Ñтигат 1 " +"Ñекунда" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "Времевото клеймо по UNIX %lld не Ñе помеÑтва в 64 бита" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "Времевото клеймо по UNIX %lld е извън диапазона, поддържан в Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Името на файла „%s“ не може да Ñе преобразува в UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Файлът „%s“ не може да бъде отворен — грешка от Windows: %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Грешка при задаване на времето на промÑна или доÑтъп на файла „%s“: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Грешка при задаване на времето на промÑна или доÑтъп: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "КонтекÑтът на SELinux трÑбва да не е NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux не е включен на тази ÑиÑтема" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Грешка при задаване на контекÑта на SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Ðе Ñе поддържа задаването на атрибута %s" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Грешка при четене от файл: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Грешка при затварÑне на файл: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Грешка при търÑене във файл: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "" +"Стандартната функционалноÑÑ‚ за наблюдение на локални файлове не може да бъде " +"открита" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Грешка при Ð·Ð°Ð¿Ð¸Ñ Ð²ÑŠÐ² файл: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Грешка при премахване на Ñтара, резервна връзка: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Грешка при Ñъздаване на резервно копие: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Грешка при преименуване на временен файл: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Грешка при Ñъкращаване на файл: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Грешка при отварÑне на файла „%s“: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "ЦелевиÑÑ‚ файл е папка" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "ЦелевиÑÑ‚ файл не е обикновен файл" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Файлът бе променен от външно приложение" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Грешка при изтриване на Ñтар файл: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Зададен е неправилен „GSeekType“" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Ðеправилна заÑвка за търÑене" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "„GMemoryInputStream“ не може да Ñе Ñъкрати" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "ИзходÑщиÑÑ‚ поток в паметта не може да бъде преоразмерен" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "ÐеуÑпешно преоразмерÑване на изходÑÑ‰Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾Ðº в паметта" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"КоличеÑтвото памет, необходимо за обработката на запиÑа, е по-голÑмо от " +"наличното адреÑно проÑтранÑтво." + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "ЗаÑвеното търÑене е преди началото на потока" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "ЗаÑвеното търÑене е Ñлед ÐºÑ€Ð°Ñ Ð½Ð° потока" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "монтираниÑÑ‚ обект не поддържа демонтиране" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "монтираниÑÑ‚ обект не поддържа изваждане" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"монтираниÑÑ‚ обект не поддържа нито демонтиране, нито демонтиране Ñ Ð´ÐµÐ¹Ñтвие" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"монтираниÑÑ‚ обект не поддържа нито изваждане, нито изваждане Ñ Ð´ÐµÐ¹Ñтвие" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "монтираниÑÑ‚ обект не поддържа повторно монтиране" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "монтираниÑÑ‚ обект не поддържа откриване на вида" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "монтираниÑÑ‚ обект не поддържа Ñинхронно откриване на вида" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Името на хоÑта „%s“ Ñъдържа „[“, но липÑва „]“" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Мрежата е недоÑтъпна" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "ХоÑтът е недоÑтъпен" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "СъÑтоÑнието на мрежата не може да бъде наблюдавано: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "СъÑтоÑнието на мрежата не може да бъде наблюдавано: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "СъÑтоÑнието на мрежата не може да бъде получено: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "„NetworkManager“ не работи" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Прекалено Ñтара верÑÐ¸Ñ Ð½Ð° „NetworkManager“" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "ИзходниÑÑ‚ поток не поддържа запиÑ" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Сумата на векторите подадена на „%s“ е прекалено голÑма" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "ИзходниÑÑ‚ поток вече е затворен" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Грешка при откриване по Ð°Ð´Ñ€ÐµÑ Ð½Ð° „%s“: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "нÑма Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° „%s“" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Ðеправилен домейн" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "РеÑурÑÑŠÑ‚ при „%s“ не ÑъщеÑтвува" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "РеÑурÑÑŠÑ‚ при „%s“ не може да Ñе декомпреÑира" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "РеÑурÑÑŠÑ‚ при „%s“ не е папка" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "ВходниÑÑ‚ поток не поддържа търÑене" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "ИзброÑване на разделите Ñ Ñ€ÐµÑурÑи във ФÐЙЛа във формат elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"ИзброÑване на реÑурÑите\n" +"Ðко е даден РÐЗДЕЛ, Ñе изброÑват Ñамо реÑурÑите в него\n" +"Ðко е даден ПЪТ, Ñе изброÑват Ñамо Ñъвпадащите реÑурÑи" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "ФÐЙЛ [ПЪТ]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "РÐЗДЕЛ" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Подробно изброÑване на реÑурÑите\n" +"Ðко е даден РÐЗДЕЛ, Ñе изброÑват Ñамо реÑурÑите в него\n" +"Ðко е даден ПЪТ, Ñе изброÑват Ñамо Ñъвпадащите реÑурÑи\n" +"ПодробноÑтите включват раздел, размер и компреÑиÑ" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Разархивиране на реÑÑƒÑ€Ñ ÐºÑŠÐ¼ ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð¸Ð·Ñ…Ð¾Ð´" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "ПЪТ ДО ФÐЙЛ" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Употреба:\n" +" gresource [--section РÐЗДЕЛ] КОМÐÐДР[ÐРГУМЕÐТ…]\n" +"\n" +"Команда:\n" +" help Тази информациÑ\n" +" sections СпиÑък Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚Ðµ реÑурÑи\n" +" list СпиÑък Ñ Ñ€ÐµÑурÑите\n" +" details Подробен ÑпиÑък Ñ Ñ€ÐµÑурÑи\n" +" extract Разархивиране на реÑурÑ\n" +"\n" +"За подробна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¸Ð·Ð¿ÑŠÐ»Ð½ÐµÑ‚Ðµ „gresource help КОМÐÐДГ\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Употреба:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " РÐЗДЕЛ (Ðезадължително) име на раздел в elf\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " КОМÐÐДРПомощ за командата или обща помощ, ако не е указано име\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " ФÐЙЛ Файл във формат elf (изпълним или Ñподелена библиотека)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" ФÐЙЛ Файл във формат elf (изпълним или Ñподелена библиотека)\n" +" или компилиран файл Ñ Ñ€ÐµÑурÑи\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[ПЪТ]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " ПЪТ (Ðезадължителен) (непълен) път до реÑурÑ\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "ПЪТ" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " ПЪТ Път до реÑурÑ\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "ЛипÑва Ñхема „%s“\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Схемата „%s“ не може да Ñе меÑти (не трÑбва да указвате път)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Схемата „%s“ може да Ñе меÑти (трÑбва да укажете път)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Даден е празен път.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "ПътÑÑ‚ трÑбва да започва Ñ Ð½Ð°ÐºÐ»Ð¾Ð½ÐµÐ½Ð° черта („/“)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "ПътÑÑ‚ трÑбва да завършва Ñ Ð½Ð°ÐºÐ»Ð¾Ð½ÐµÐ½Ð° черта („/“)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "ПътÑÑ‚ не трÑбва да Ñъдържа две поÑледователни наклонени черти („//“)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "СтойноÑтта е извън интервала на допуÑтимите ÑтойноÑти\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Ключът не поддържа запиÑ\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Извеждане на инÑталираните Ñхеми (които не Ñе меÑÑ‚ÑÑ‚)" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Извеждане на инÑталираните Ñхеми, които може да Ñе меÑÑ‚ÑÑ‚" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Извеждане на ключовете в СХЕМÐта" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "СХЕМÐ[:ПЪТ]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Извеждане на наÑледниците на СХЕМÐта" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"РекурÑивно извеждане на ключовете и ÑтойноÑтите им.\n" +"Ðко липÑва СХЕМÐ, Ñе извеждат вÑички ключове\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[СХЕМÐ[:ПЪТ]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Получаване на ÑтойноÑтта на КЛЮЧ" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "СХЕМÐ[:ПЪТ] КЛЮЧ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Запитване за интервала от допуÑтими ÑтойноÑти за КЛЮЧа" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Запитване на опиÑанието за КЛЮЧа" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Задаване на СТОЙÐОСТта на КЛЮЧ" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "СХЕМÐ[:ПЪТ] КЛЮЧ СТОЙÐОСТ" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Връщане на Ñтандартната ÑтойноÑÑ‚ на КЛЮЧ" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Връщане на Ñтандартната ÑтойноÑÑ‚ на вÑички ключове в СХЕМÐта" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Проверка дали ÑтойноÑтта на КЛЮЧ може да Ñе променÑ" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Ðаблюдение на КЛЮЧа за промени.\n" +"Ðко не е указан определен КЛЮЧ, Ñе ÑледÑÑ‚ вÑички във СХЕМÐта.\n" +"Ðаблюдението Ñе Ñпира Ñ â€ž^C“.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "СХЕМÐ[:ПЪТ] [КЛЮЧ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Употреба:\n" +" gsettings --version\n" +" gsettings [--schemadir ПÐПКÐ_ÐÐ_СХЕМÐ] КОМÐÐДР[ÐРГУМЕÐТИ…]\n" +"\n" +"Команди:\n" +" help Показване на този текÑÑ‚\n" +" list-schemas Извеждане на инÑталираните Ñхеми\n" +" list-relocatable-schemas Извеждане на Ñхемите, които може да Ñе меÑÑ‚ÑÑ‚\n" +" list-keys Извеждане на ключовете в Ñхема\n" +" list-children Извеждане на наÑледниците на Ñхема\n" +" list-recursively РекурÑивно извеждане на ключовете и ÑтойноÑтите " +"им\n" +" range Какъв е интервалът от допуÑтими ÑтойноÑти за " +"ключ\n" +" get Получаване на ÑтойноÑтта на даден ключ\n" +" set ПромÑна на ÑтойноÑтта на даден ключ\n" +" reset Връщане на Ñтандартната ÑтойноÑÑ‚ на даден ключ\n" +" reset-recursively Връщане на ÑтойноÑтите на вÑички ключове в " +"Ñхема\n" +" writable Проверка дали даден ключ може да Ñе променÑ\n" +" monitor Ðаблюдение на даден ключ за промени\n" +"\n" +"Използвайте „gsettings help КОМÐÐДГ за допълнителна информациÑ.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Уореба:\n" +" gsettings [--schemadir ПÐПКÐ_ÐÐ_СХЕМÐ] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " ПÐПКÐ_ÐÐ_СХЕМРПапка, в коÑто да Ñе търÑÑÑ‚ допълнителни Ñхеми\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +"Ðргументи:\n" +" СХЕМРИмето на Ñхемата\n" +" ПЪТ Път (за Ñхеми, които може да Ñе меÑÑ‚ÑÑ‚)\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " КЛЮЧ Ключ в Ñхемата (незадължителен)\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " КЛЮЧ Ключ в Ñхемата\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " СТОЙÐОСТ СтойноÑÑ‚, коÑто да бъде зададена\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Схеми от „%s“ не може да Ñе заредÑÑ‚: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Ðе Ñа открити Ñхеми\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Подадено е празно име за Ñхема\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "ЛипÑва ключ „%s“\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Ðеправилно гнездо, не е инициализирано" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Ðеправилно гнездо, неуÑпешна Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ð¾Ð½ÐµÐ¶Ðµ: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Гнездото вече е затворено" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "ПроÑрочено време за отговор при входни-изходна Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ Ð³Ð½ÐµÐ·Ð´Ð¾Ñ‚Ð¾" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "Ñъздаване на „GSocket“ от файлов деÑкриптор: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "ÐеуÑпешно Ñъздаване на гнездо: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Указан е непознат вид верÑÐ¸Ñ Ð½Ð° протокол" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Указан е непознат протокол" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Ðе може да Ñе използват операции за дейтаграми върху гнезда, които не Ñа за " +"дейтаграми." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Ðе може да Ñе използват операции за дейтаграми върху гнезда без зададено " +"макÑимално време за операциÑта." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "локалниÑÑ‚ Ð°Ð´Ñ€ÐµÑ Ð½Ðµ може да бъде получен :%s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "отдалечениÑÑ‚ Ð°Ð´Ñ€ÐµÑ Ð½Ðµ може да бъде получен :%s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "не може да Ñе Ñлуша: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Грешка при Ñвързване към Ð°Ð´Ñ€ÐµÑ %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Грешка при включване към група за разпръÑкване: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Грешка при напуÑкане на група за разпръÑкване: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "ЛипÑва поддръжка за наÑочено разпръÑкване" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Ðеподдържана Ñ„Ð°Ð¼Ð¸Ð»Ð¸Ñ Ð³Ð½ÐµÐ·Ð´Ð¾" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "наÑочено разпръÑкване не към Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾ IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Името на интерфейÑа е твърде дълго" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "ИнтерфейÑÑŠÑ‚ липÑва: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "ЛипÑва поддръжка за наÑочено разпръÑкване по IPv4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "ЛипÑва поддръжка за наÑочено разпръÑкване по IPv6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Грешка при приемане на връзка: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Ð’ момента Ñе оÑъщеÑтвÑва връзка" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "ÐеуÑпешно получаване на текущата грешка: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Грешка при получаване на данни: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Грешка при изпращане на данни: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ÐеуÑпешно изключване на гнездо: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Грешка при затварÑне на гнездо: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Изчакване за ÑÑŠÑтоÑние на гнездо: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "ÐеуÑпешно изпращане на Ñъобщение: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Векторите на Ñъобщението Ñа прекалено дълги" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Грешка при изпращане на Ñъобщение: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "„GSocketControlMessage“ не Ñе поддържа под Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Грешка при изпращане на Ñъобщение: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "ÐеуÑпешно изчитане на правата на гнездо: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"„g_socket_get_credentials“ не е реализирана на тази операционна ÑиÑтема" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "ÐеуÑпешно Ñвързване към Ñървъра-поÑредник %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "ÐеуÑпешно Ñвързване към „%s“: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "ÐеуÑпешно Ñвързване: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Ðе Ñе поддържа поÑредничеÑтво на връзки извън TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Протоколът за поÑредничеÑтво „%s“ не Ñе поддържа." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "ФункциÑта за Ñлушане вече е затворена" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Добавеното гнездо е затворено" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 не поддържа адреÑа IPv6 „%s“" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "ПотребителÑкото име е твърде дълго за протокола SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Името на хоÑта „%s“ е твърде дълго за протокола SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Този Ñървър не е поÑредник чрез SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Връзката през Ñървъра SOCKSv4 беше отхвърлена" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Този Ñървър не поÑредничи чрез SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "ПоÑредникът чрез SOCKSv5 изиÑква идентификациÑ." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"ПоÑредникът чрез SOCKSv5 изиÑква механизъм за идентификациÑ, който не Ñе " +"поддържа от GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "ПотребителÑкото име или паролата Ñа твърде дълги за протокола SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Идентифицирането за SOCKSv4 не уÑÐ¿Ñ Ð¿Ð¾Ñ€Ð°Ð´Ð¸ грешно потребителÑко име или " +"парола." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Името на хоÑта „%s“ е твърде дълго за протокола SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Сървърът-поÑредник за SOCKSv5 използва непознат вид адреÑ." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Вътрешна грешка на Ñървъра-поÑредник за SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Правилата не позволÑват Ñвързването по SOCKSv5." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "ХоÑтът не е доÑтъпен през Ñървъра за SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Мрежата не е доÑтъпна през Ñървъра-поÑредник за SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Връзката през поÑредник за SOCKSv5 е отказана." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Сървърът-поÑредник за SOCKSv5 не поддържа командата „connect“." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Сървърът-поÑредник за SOCKSv5 не поддържа предоÑÑ‚Ð°Ð²ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´ адреÑ." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "ÐеизвеÑтна грешка ÑÑŠÑ Ñървъра-поÑредник за SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ÐеуÑпешно Ñъздаване на канал за ÐºÐ¾Ð¼ÑƒÐ½Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ Ð´ÑŠÑ‰ÐµÑ€ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Тази платформа не поддържа програмни канали" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "ВерÑÐ¸Ñ %d на кодирането „GThemedIcon“ не Ñе поддържа" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Ðе бÑха намерени валидни адреÑи" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Грешка при обратно откриване по Ð°Ð´Ñ€ÐµÑ Ð½Ð° „%s“: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Грешка при анализ на Ð·Ð°Ð¿Ð¸Ñ Ð¾Ñ‚ DNS — „%s“: неправилен пакет от DNS" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "ÐÑма Ð·Ð°Ð¿Ð¸Ñ Ð² DNS от ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð²Ð¸Ð´ за „%s“" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Временно е невъзможно „%s“ да бъде открит по адреÑ" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Грешка при откриване по Ð°Ð´Ñ€ÐµÑ Ð½Ð° „%s“" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Ðеправилен пакет от DNS" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "ÐеуÑпешен анализ на отговор от DNS за „%s“: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "ЛипÑва чаÑтен ключ, шифриран Ñ PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "ЧаÑтниÑÑ‚ ключ, шифриран Ñ PEM, не може да бъде дешифриран" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "ЧаÑтниÑÑ‚ ключ, шифриран Ñ PEM, не може да бъде анализиран" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "ЛипÑва Ñертификат, шифриран Ñ PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Сертификатът, шифриран Ñ PEM, не може да бъде анализиран" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "РеализациÑта на TLS не поддържа PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" +"Тази Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° „GTlsBackend“ не поддържа Ñъздаване на Ñертификати PKCS " +"#11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Това е поÑледниÑÑ‚ ви ÑˆÐ°Ð½Ñ Ð´Ð° въведете правилна парола, преди машината да Ñе " +"заключи." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"ÐÑколко пъти Ñте въвели неправилна парола. Ðко отново Ñгрешите, машината ще " +"Ñе заключи за доÑтъп." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Въведената парола е неправилна." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Изпращането на файлов деÑкриптор не Ñе поддържа" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Очакваше Ñе 1 контролно Ñъобщение, а беше получено %d" +msgstr[1] "Очакваше Ñе 1 контролно Ñъобщение, а бÑха получени %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Ðеочакван вид на помощните данни" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Очакваше Ñе един файлов деÑкриптор, а беше получен %d\n" +msgstr[1] "Очакваше Ñе един файлов деÑкриптор, а бÑха получени %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Получен е неправилен файлов деÑкриптор" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Получаването на файлов деÑкриптор не Ñе поддържа" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Грешка при изпращане на ÑамоличноÑÑ‚: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Грешка при проверка дали „SO_PASSCRED“ е позволено за гнездото: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Грешка при разрешаване на „SO_PASSCRED“: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Очаква Ñе един байт за получаване на ÑамоличноÑÑ‚, но Ñа прочетени 0 байта." + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ðе Ñе очакваше контролно Ñъобщение, а бÑха получени %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Грешка при забранÑване на „SO_PASSCRED“: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Грешка при четене от Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¸Ñ Ð´ÐµÑкриптор: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Грешка при затварÑне на Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¸Ñ Ð´ÐµÑкриптор: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Коренова папка на файловата ÑиÑтема" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Грешка при Ð·Ð°Ð¿Ð¸Ñ Ð²ÑŠÐ² Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¸Ñ Ð´ÐµÑкриптор: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Тази ÑиÑтема не поддържа абÑтрактни адреÑи на гнезда за домейни в Unix" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "томът не поддържа изваждане" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "томът не поддържа нито изваждане, нито изваждане Ñ Ð´ÐµÐ¹Ñтвие" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Грешка при четене от манипулатор: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Грешка при затварÑне на манипулатор: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Грешка при Ð·Ð°Ð¿Ð¸Ñ Ð² манипулатор: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "недоÑтатъчно памет" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Вътрешна грешка: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Ðеобходими Ñа още данни от входа" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Ðеправилни, компреÑирани данни" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ÐдреÑ, на който да Ñе Ñлуша" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "СтойноÑтта нÑма значение, проÑто оÑигурÑва ÑъвмеÑтимоÑÑ‚ Ñ â€žGTestDbus“" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Извеждане на адреÑа" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Извеждане на адреÑа в режим за обвивката" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Стартиране на ÑеÑийна шина D-Bus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Ðеправилни аргументи\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Ðеочакван атрибут „%s“ на елемента „%s“" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Ðтрибутът „%s“ на елемента „%s“ не е открит" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Ðеочакван етикет „%s“, очакваше Ñе „%s“" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Ðеочакван етикет „%s“ вътре в „%s“" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Ðеправилна дата или време „%s“ във файла Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¸" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Ðе може да Ñе открие валиден файл Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¸ в папките Ñ Ð´Ð°Ð½Ð½Ð¸" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Вече ÑъщеÑтвува отметка за адреÑа „%s“" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Ðе е открита отметка за адреÑа „%s“" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Ðе е указан видът MIME в отметката за адреÑа „%s“" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Ðе е зададен флаг за лични данни в отметката за адреÑа „%s“" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Ðе Ñа зададени групи в отметката за адреÑа „%s“" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "ÐÐ¸ÐºÐ¾Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð° „%s“ не е региÑтрирала отметка за „%s“" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "ÐеуÑпешно допиÑване за изпълнение на реда „%s“ Ñ Ð°Ð´Ñ€ÐµÑа „%s“" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Ðеправилна поÑледователноÑÑ‚ на входа" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Ðепълна знакова поÑледователноÑÑ‚ в ÐºÑ€Ð°Ñ Ð½Ð° входните данни" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" +"ЗамеÑтващиÑÑ‚ знак „%s“ не може да бъде преобразуван към знак от набора „%s“" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Ðа входа за преобразуване има байт NUL" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Ðа изхода от преобразуване има байт NUL" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" +"ÐдреÑÑŠÑ‚ „%s“ не е абÑолютен при използване на Ñхемата „file“ (файлова " +"ÑиÑтема)" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "ÐдреÑÑŠÑ‚ „%s“ на локален файл не може да включва „#“" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "ÐдреÑÑŠÑ‚ „%s“ е неправилен" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Името на хоÑта в адреÑа „%s“ е неправилно" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "ÐдреÑÑŠÑ‚ „%s“ Ñъдържа грешни екраниращи поÑледователноÑти" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "ПътÑÑ‚ „%s“ не е абÑолютен" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%d.%m.%Y, %a, %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%l:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Ñнуари" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "февруари" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "март" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "април" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "май" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "юни" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "юли" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "авгуÑÑ‚" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Ñептември" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "октомври" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "ноември" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "декември" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Ñну" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "фев" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "мар" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "апр" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "май" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "юни" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "юли" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "авг" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Ñеп" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "окт" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ное" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "дек" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "понеделник" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "вторник" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "ÑÑ€Ñда" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "четвъртък" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "петък" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Ñъбота" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "неделÑ" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "пн" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "вт" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ÑÑ€" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "чт" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "пт" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Ñб" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "нд" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Ñнуари" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "февруари" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "март" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "април" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "май" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "юни" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "юли" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "авгуÑÑ‚" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Ñептември" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "октомври" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "ноември" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "декември" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Ñну" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "фев" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "мар" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "апр" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "май" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "юни" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "юли" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "авг" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Ñеп" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "окт" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ное" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "дек" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "пр.об." + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "Ñл.об." + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Грешка при отварÑне на папка „%s“: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "ÐеуÑпешно заделÑне на %lu байт за четене на файла „%s“" +msgstr[1] "ÐеуÑпешно заделÑне на %lu байта за четене на файла „%s“" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Грешка при четене на файл „%s“: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Файлът „%s“ е прекалено голÑм" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "ÐеуÑпешно четене от файл „%s“: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "ÐеуÑпешно отварÑне на файл „%s“: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"ÐеуÑпешно получаване на атрибутите на файл „%s“: неуÑпешно изпълнение на " +"„fstat()“: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "" +"ÐеуÑпешно отварÑне на файл „%s“: неуÑпешно изпълнение на „fdopen()“: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"ÐеуÑпешно преименуване на файл „%s“ на „%s“: неуÑпешно изпълнение на " +"„g_rename()“: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "ÐеуÑпешен Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° файл „%s“: неуÑпешно изпълнение на „write()“: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "ÐеуÑпешен Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° файл „%s“: неуÑпешно изпълнение на „fsync()“: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "ÐеуÑпешно Ñъздаване на файл „%s“: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"ÐеуÑпешно изтриване на ÑъщеÑÑ‚Ð²ÑƒÐ²Ð°Ñ‰Ð¸Ñ Ñ„Ð°Ð¹Ð» „%s“: неуÑпешно изпълнение на " +"„g_unlink()“: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Шаблонът „%s“ е неправилен, не трÑбва да Ñъдържа „%s“" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Шаблонът „%s“ не Ñъдържа „XXXXXX“" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "ÐеуÑпешно четене на Ñимволната връзка „%s“: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Ðе може да Ñе отвори конвертор от „%s“ към „%s“: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Ðе може да Ñе чете от „g_io_channel_read_line_string“" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Ð’ буфера за четене оÑтанаха непреобразувани данни" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Каналът прекъÑна на непълен знак" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Ðе може да Ñе чете от „g_io_channel_read_to_end“" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Ðе може да Ñе открие валиден файл Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ðµ в папките Ñ Ð´Ð°Ð½Ð½Ð¸" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Ðе е обикновен файл" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"КлючовиÑÑ‚ файл Ñъдържа реда „%s“, който не е нито двойка ключ-ÑтойноÑÑ‚, нито " +"група, нито коментар" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ðеправилно име на група: „%s“" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "КлючовиÑÑ‚ файл не започва Ñ Ð³Ñ€ÑƒÐ¿Ð°" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Ðеправилно име на ключ: „%.*s“" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "КлючовиÑÑ‚ файл Ñъдържа неподдържаното кодиране „%s“" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "КлючовиÑÑ‚ файл не Ñъдържа групата „%s“" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "КлючовиÑÑ‚ файл не Ñъдържа ключа „%s“ в групата „%s“" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "КлючовиÑÑ‚ файл Ñъдържа ключ „%s“ ÑÑŠÑ ÑтойноÑÑ‚ „%s“, коÑто не е в UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"КлючовиÑÑ‚ файл Ñъдържа ключа „%s“, чиÑто ÑтойноÑÑ‚ не може да бъде " +"анализирана." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"КлючовиÑÑ‚ файл Ñъдържа ключа „%s“ в групата „%s“, чиÑто ÑтойноÑÑ‚ не може да " +"бъде анализирана." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Ключът „%s“ в групата „%s“ има ÑтойноÑÑ‚ „%s“, а Ñе очакваше „%s“" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "КлючовиÑÑ‚ файл Ñъдържа екранираща поÑледователноÑÑ‚ в край на ред" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "КлючовиÑÑ‚ файл Ñъдържа грешна екранираща поÑледователноÑÑ‚ — „%s“" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "СтойноÑтта „%s“ не може да Ñе интерпретира като чиÑло." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "ЦелочиÑлената ÑтойноÑÑ‚ „%s“ е извън интервала на допуÑтими ÑтойноÑти" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "" +"СтойноÑтта „%s“ не може да Ñе интерпретира като чиÑло Ñ Ð¿Ð»Ð°Ð²Ð°Ñ‰Ð° запетаÑ." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "СтойноÑтта „%s“ не може да Ñе интерпретира като булева." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"ÐеуÑпешно получаване на атрибутите на файла „%s%s%s%s“: неуÑпешно изпълнение " +"на „fstat()“: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" +"ÐеуÑпешно отварÑне на файл в паметта „%s%s%s%s“: неуÑпешно изпълнение на " +"„mmap()“: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "ÐеуÑпешно отварÑне на файл „%s“: неуÑпешно изпълнение на „open()“: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Грешка на ред %d, знак %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Ðеправилно кодиран текÑÑ‚ в UTF-8 — „%s“ е грешен" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "„%s“ е неправилно име" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "„%s“ е неправилно име: „%c“" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Грешка на ред %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Грешка при анализ на „%-.*s“, което трÑбва да е чиÑло в указател на знак " +"(напр. „ê“). ВероÑтно чиÑлото е твърде голÑмо" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"УказателÑÑ‚ на знак не завършва Ñ â€ž;“. Ðай-вероÑтно Ñте използвали „&“, без " +"той да е начало на замеÑтваща поÑледователноÑÑ‚. ПредÑтавете го чрез „&“" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "УказателÑÑ‚ на знак „%-.*s“ не предÑÑ‚Ð°Ð²Ñ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½ знак при декодиране" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Ðамерена е празна замеÑтваща поÑледователноÑÑ‚: „&;“. Валидни " +"поÑледователноÑти Ñа: „&“, „"“, „<“, „>“, „'“" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Името на замеÑтващата поÑледователноÑÑ‚ „%-.*s“ е неизвеÑтно" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"ЗамеÑтващата поÑледователноÑÑ‚ не завършва Ñ â€ž;“. Ðай-вероÑтно Ñте използвали " +"„&“, без той да е начало на замеÑтваща поÑледователноÑÑ‚. ПредÑтавете го чрез " +"„&“" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Документът трÑбва да започва Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚ (напр. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"„%s“ е неправилен знак Ñлед „<“. Името на елемент не може да започне Ñ Ð½ÐµÐ³Ð¾" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"ÐеподходÑщ знак „%s“, очаква Ñе етикетът на Ð¿Ñ€Ð°Ð·Ð½Ð¸Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚ „%s“ да завърши " +"Ñ â€ž>“" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Прекалено много атрибути в елемента „%s“" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"ÐеподходÑщ знак „%s“, очаква Ñе „=“ Ñлед името на атрибут „%s“ на елемент " +"„%s“" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ÐеподходÑщ знак „%s“, очаква Ñе или отварÑщиÑÑ‚ етикет на елемента „%s“ да " +"завърши ÑÑŠÑ Ð·Ð½Ð°Ðº „>“ или „/“, или евентуално да продължи Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚. Ðай-" +"вероÑтно използвате неправилен знак в името на атрибут" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"ÐеподходÑщ знак „%s“, очаква Ñе знак „\"“ или „'“ Ñлед знака за равенÑтво, " +"когато Ñе приÑвоÑва ÑтойноÑÑ‚ на атрибута „%s“ на елемент „%s“" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"„%s“ е неправилен знак при завършването на затварÑщ етикет Ñ Ð¸Ð¼Ðµ „%s“. " +"Позволен е знакът „>“" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Елементът „%s“ е затворен, нÑма текущо отворен елемент" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Елементът „%s“ е затворен, но текущо е отворен елемент „%s“" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Документът е празен или Ñъдържа Ñамо празни знаци" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Документът завършва неочаквано веднага Ñлед отварÑща Ñчупена Ñкоба — „<“" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Документът завършва неочаквано — има отворени елементи. ПоÑледно отворен е " +"„%s“" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Документът завършва неочаквано, очаква Ñе затварÑща Ñчупена Ñкоба да завърши " +"етикета <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Документът завършва неочаквано в името на елемент" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Документът завършва неочаквано в името на атрибут" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Документът завършва неочаквано в отварÑщ етикет на елемент " + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Документът завършва неочаквано Ñлед знака за равенÑтво Ñлед името на " +"атрибута. Ðтрибутът нÑма ÑтойноÑÑ‚" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Документът завършва неочаквано вътре в ÑтойноÑтта на атрибут" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Документът завършва неочаквано в затварÑÑ‰Ð¸Ñ ÐµÑ‚Ð¸ÐºÐµÑ‚ на елемент „%s“" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Документът завършва неочаквано в затварÑÑ‰Ð¸Ñ ÐµÑ‚Ð¸ÐºÐµÑ‚ на неотворен елемент" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Документът завършва неочаквано в коментар или инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ð·Ð° обработка" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[ОПЦИЯ…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "ÐаÑтройки на помощта:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Показване на наÑтройките на помощта" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Показване на вÑички наÑтройки на помощта" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "ÐаÑтройки на приложението:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "ÐаÑтройки:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Ðе може да Ñе анализира целочиÑлената ÑтойноÑÑ‚ „%s“ за %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "" +"ЦелочиÑлената ÑтойноÑÑ‚ „%s“ за %s е извън интервала на допуÑтимите ÑтойноÑти" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "" +"Ðе може да Ñе анализира ÑтойноÑтта Ñ Ð¿Ð¾Ð²Ð¸ÑˆÐµÐ½Ð° точноÑÑ‚ double „%s“ за %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "" +"СтойноÑтта Ñ Ð¿Ð¾Ð²Ð¸ÑˆÐµÐ½Ð° точноÑÑ‚ — double „%s“ за %s е извън интервала на " +"допуÑтимите ÑтойноÑти" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Грешка при анализа на опциÑта „%s“" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "ЛипÑва аргумент за „%s“" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Ðепозната Ð¾Ð¿Ñ†Ð¸Ñ â€ž%s“" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "повреден обект" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "вътрешна грешка или повреден обект" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "недоÑтатъчно памет" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "доÑтигната е границата на обратното връщане" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"шаблонът Ñъдържа елементи, които не Ñе поддържат при чаÑтично Ñъвпадение" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "вътрешна грешка" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"обратните указатели не Ñе поддържат като уÑловие при чаÑтично Ñъвпадение" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "прекалено дълбока рекурÑиÑ" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "неправилна ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ флагове за нов ред" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "неправилно отмеÑтване" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "прекалено ÐºÑŠÑ UTF-8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "зациклÑне при рекурÑиÑ" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "непозната грешка" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "„\\“ в ÐºÑ€Ð°Ñ Ð½Ð° шаблон" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "„\\c“ в ÐºÑ€Ð°Ñ Ð½Ð° шаблон" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "Ñлед „\\“ Ñледва непознат знак" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "чиÑлата не Ñа в правилен ред в определението за брой Ñ â€ž{}“" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "прекалено голÑмо чиÑло в определението за брой Ñ â€ž{}“" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "липÑва завършващ знак „]“ за ÐºÐ»Ð°Ñ Ð¾Ñ‚ знаци" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "грешна екранираща поÑледователноÑÑ‚ в клаÑа от знаци" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "знаците Ñа в неправилен ред в клаÑа от знаци" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "нÑма какво да Ñе повтори" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "неочаквано повторение" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "непознат знак Ñлед „(?“ или „(?-“" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "именованите клаÑове от POSIX Ñе поддържат Ñамо в клаÑ" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "липÑва завършваща „)“" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "указател към неÑъщеÑтвуващ подшаблон" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "липÑва „)“ Ñлед коментар" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "регулÑрниÑÑ‚ израз е прекалено голÑм" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "неуÑпешно получаване на памет" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "„)“ без отварÑща „(“" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "препълване на кода" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "непознат знак Ñлед „(?<“" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "предположението за преглед назад не е Ñ Ð¿Ð¾ÑтоÑнна дължина" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "неправилен номер или име Ñлед „(?(“" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "уÑловната група Ñъдържа повече от две разклонениÑ" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "очаква Ñе предположение Ñлед „(?(“" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "„(?R“ или „(?[+-]цифри“ трÑбва да Ñе Ñледват от „)“" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "непознато име на ÐºÐ»Ð°Ñ Ð¿Ð¾ POSIX" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "не Ñе поддържат елементи на POSIX за подредба" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "знаковата ÑтойноÑÑ‚ в поÑледователноÑтта „\\x{…}“ е прекалено голÑма" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "неправилно уÑловие „(?(0)“" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "предположението за преглед назад не може да Ñъдържа „\\C“" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "екранираниÑта „\\L“, „\\l“, „\\N{name}“, „\\U“ и „\\u“ не Ñе поддържат" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "рекурÑивно извикване може да доведе до безкраен цикъл" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "непознат знак Ñлед „(?P“" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "липÑва краен знак в име на подшаблон" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "два именовани подшаблона Ñа Ñ ÐµÐ´Ð½Ð°ÐºÐ²Ð¾ име" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "неправилни поÑледователноÑти „\\P“ или „\\p“" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "непознато име на ÑвойÑтво Ñлед „\\P“ или „\\p“" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "името на подшаблон е прекалено дълго (макÑимално е 32 знака)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "прекалено много именовани подшаблони (макÑимумът е 10 000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "оÑмичната ÑтойноÑÑ‚ е по-голÑма от „\\377“" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "надхвърлено е работното проÑтранÑтво за компилациÑ" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "не е открит указан предварително проверен подшаблон" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "група „DEFINE“ Ñъдържа повече от едно разклонение" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "неÑъвмеÑтими опции за нов ред" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"„\\g“ не е поÑледвано от име, чиÑло във фигурни или квадратни Ñкоби, " +"цитирано име или обикновено чиÑло" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "номерираниÑÑ‚ указател не трÑбва да е „0“" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "„(*ACCEPT)“, „(*FAIL)“ и „(*COMMIT)“ не приемат аргументи" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "неразпознат „(*ГЛÐГОЛ)“" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "чиÑлото е прекалено голÑмо" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "липÑва име на подшаблон Ñлед „(?&“" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "очаква Ñе цифра Ñлед „(?+“" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "„]“ е неправилен знак за данни в режима ÑъвмеÑтим Ñ JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "не Ñа позволени различни имена за подшаблони Ñ ÐµÐ´Ð½Ð°ÐºÑŠÐ² номер" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "„(*MARK)“ изиÑква аргумент" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "„\\c“ трÑбва да Ñе Ñледва от знак от ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"„\\k“ не е поÑледвано от име във фигурни или квадратни Ñкоби или от цитирано " +"име" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "„\\N“ не Ñе поддържа в клаÑ" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "прекалено много указатели напред" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" +"името е прекалено дълго за „(*MARK)“, „(*PRUNE)“, „(*SKIP)“ и „(*THEN)“" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "знаковата ÑтойноÑÑ‚ в поÑледователноÑтта „\\u…“ е прекалено голÑма" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Грешка при напаÑването на регулÑÑ€Ð½Ð¸Ñ Ð¸Ð·Ñ€Ð°Ð· „%s“: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Библиотеката PCRE е компилирана без поддръжка на UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Библиотеката PCRE е компилирана без поддръжка на наÑтройки в UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Библиотеката PCRE е компилирана Ñ Ð½ÐµÑъвмеÑтими опции" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Грешка при оптимизирането на регулÑÑ€Ð½Ð¸Ñ Ð¸Ð·Ñ€Ð°Ð· %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Грешка при компилирането на регулÑÑ€Ð½Ð¸Ñ Ð¸Ð·Ñ€Ð°Ð· %s, знак %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "очаква Ñе шеÑтнадеÑетично чиÑло или „}“" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "очаква Ñе шеÑтнадеÑетично чиÑло" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "в ÑÐ¸Ð¼Ð²Ð¾Ð»Ð½Ð¸Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ» липÑва „<“" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "незавършен Ñимволен указател" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "Ñимволен указател Ñ Ð½ÑƒÐ»ÐµÐ²Ð° дължина" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "очаква Ñе цифра" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "неправилен Ñимволен указател" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "в ÐºÑ€Ð°Ñ Ð¸Ð¼Ð° един знак „\\“ в повече" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "непозната екранираща поÑледователноÑÑ‚" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Грешка при анализа на текÑта за замÑна „%s“ при знак %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Цитиран текÑÑ‚ не започва ÑÑŠÑ Ð·Ð½Ð°ÐºÐ° „\"“ или „'“" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"ЛипÑват затварÑщи кавички в команден ред или друг текÑÑ‚ цитиран за обвивката" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "ТекÑтът Ñвърши веднага Ñлед знак „\\“. (ТекÑтът е „%s“)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"ТекÑтът Ñвърши преди откриването на затварÑщи кавички за „%c“. (ТекÑтът е " +"„%s“)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "ТекÑтът е празен (или Ñъдържа Ñамо празни знаци)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ÐеуÑпешно четене на данни от дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "" +"Ðеочаквана грешка в „select()“ при четене на данни от дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ðеочаквана грешка в „waitpid()“ (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "ДъщерниÑÑ‚ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð·Ð°Ð²ÑŠÑ€ÑˆÐ¸ Ñ ÐºÐ¾Ð´ %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "ДъщерниÑÑ‚ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð±Ðµ убит от Ñигнал %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "ДъщерниÑÑ‚ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð±Ðµ ÑпрÑн от Ñигнал %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "ДъщерниÑÑ‚ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð·Ð°Ð²ÑŠÑ€ÑˆÐ¸ аварийно" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ÐеуÑпешно четене от дъщерен канал (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "ÐеуÑпешно пораждане на дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ â€ž%s“ (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "ÐеуÑпешно пораждане (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "ÐеуÑпешна ÑмÑна към папка „%s“ (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "ÐеуÑпешно изпълнение на дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ â€ž%s“ (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "ÐеуÑпешно отварÑне на файл за замеÑтване на файлов деÑкриптор (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "ÐеуÑпешно дублиране на файлов деÑкриптор за дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ÐеуÑпешно разклонÑване на дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "ÐеуÑпешно затварÑне на Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¸Ñ Ð´ÐµÑкриптор на дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "ÐеизвеÑтна грешка при изпълнение на дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ â€ž%s“" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"ÐеуÑпешно четене на доÑтатъчно данни от канала на дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ (Ñ " +"идентификатор %s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "ÐеуÑпешно четене на данни от дъщерен процеÑ" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ÐеуÑпешно изпълнение на дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "ÐеуÑпешно разклонÑване на дъщерен Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ‡Ñ€ÐµÐ· „dup()“ (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ðеправилно име на програма: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ðеправилен низ във вектора Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð¸ на Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ðеправилен низ в Ñредата: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ðеправилна работна папка: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ÐеуÑпешно изпълнение на програмата за помощта (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ðеочаквана грешка в „g_io_channel_win32_poll()“ при четене на данни от " +"дъщерен процеÑ" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Празен низ не е чиÑло" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s“ е чиÑло ÑÑŠÑ Ð·Ð½Ð°Ðº" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "ЧиÑлото „%s“ е извън диапазона на допуÑтимите ÑтойноÑти [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s“ не е чиÑло без знак" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Ðеправилно кодиране Ñ â€ž%“ в адреÑ" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Ðеправилен знак в адреÑ" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Знаци в адреÑ, които не Ñа UTF-8" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Ðеправилен Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° IPv6 „%.*s“ в адреÑа" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Ðеправилен Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° IP „%.*s“ в адреÑа" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Ðеправилно име не на латиница „%.*s“ в адреÑа" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Портът в адреÑа „%.*s“ не може да Ñе анализира" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Портът в адреÑа „%.*s“ е извън допуÑÑ‚Ð¸Ð¼Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "ÐдреÑÑŠÑ‚ „%s“ не е абÑолютен" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "ЛипÑва хоÑÑ‚ в адреÑа „%s“" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "ÐдреÑÑŠÑ‚ не абÑолютен, а не е зададен базов адреÑ" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "ЛипÑва „=“ и ÑтойноÑÑ‚ на параметъра" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "ÐеуÑпешно заделÑне на памет" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Знак извън обхвата на UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Ðеправилна поÑледователноÑÑ‚ на входа" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Знак извън обхвата на UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u B" +msgstr[1] "%u B" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u бит" +msgstr[1] "%u бита" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s байт" +msgstr[1] "%s байта" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s бит" +msgstr[1] "%s бита" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" diff --git a/po/bn.po b/po/bn.po new file mode 100644 index 0000000..710a5c6 --- /dev/null +++ b/po/bn.po @@ -0,0 +1,3802 @@ +# Bengali translation for Glib +# Copyright (C) 2002 +# This file is distributed under the same license as the glib package. +# +# Taneem Ahmed , 2002. +# Mahay Alam Khan , 2005. +# Samia Niamatullah , 2005. +# Runa Bhattacharjee , 2007. +# Runa Bhattacharjee , 2008. +# Runa Bhattacharjee , 2008, 2009. +# Saad M Niamatullah, 2009 +# Loba Yeasmeen , 2010. +# Israt Jahan , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: bn\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2010-03-07 01:38+0600\n" +"Last-Translator: Israt Jahan \n" +"Language-Team: Bengali \n" +"Language: bn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-Language: Bengali\n" +"X-Poedit-Country: BANGLADESH\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ '%s' বৈশিষà§à¦Ÿà§à¦¯ '%s' বসà§à¦¤à§à¦° জনà§à¦¯ উলà§à¦²à¦¿à¦–িত হয়েছে" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' বৈশিষà§à¦Ÿà§à¦¯ '%s' বসà§à¦¤à§à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ পাওয়া যায়নি" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ টà§à¦¯à¦¾à¦— '%s', টà§à¦¯à¦¾à¦— '%s' পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ '%s' টà§à¦¯à¦¾à¦— '%s'-à¦à¦° মধà§à¦¯à§‡" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "তথà§à¦¯ ডিরেকà§à¦Ÿà¦°à¦¿à¦° মধà§à¦¯à§‡ বৈধ বà§à¦•মারà§à¦• ফাইল পাওয়া যায়নি" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s'-à¦à¦° জনà§à¦¯ বà§à¦•মারà§à¦• বরà§à¦¤à¦®à¦¾à¦¨à§‡ উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s'-à¦à¦° জনà§à¦¯ বà§à¦•মারà§à¦• পাওয়া যায়নি" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s'-à¦à¦° বà§à¦•মারà§à¦•ের কà§à¦·à§‡à¦¤à§à¦°à§‡ MIME-à¦à¦° ধরন নিরà§à¦§à¦¾à¦°à¦¿à¦¤ নেই" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s'-à¦à¦° বà§à¦•মারà§à¦•ের কà§à¦·à§‡à¦¤à§à¦°à§‡ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত ফà§à¦²à§à¦¯à¦¾à¦— চিহà§à¦¨ দেওয়া হয়নি" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s'-à¦à¦° বà§à¦•মারà§à¦•ের কà§à¦·à§‡à¦¤à§à¦°à§‡ গà§à¦°à§à¦ª নিরà§à¦§à¦¾à¦°à¦£ করা হয়নি" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "'%s' নামক কোনো অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনের দà§à¦¬à¦¾à¦°à¦¾ '%s' বà§à¦•মারà§à¦• নিবনà§à¦§à¦¿à¦¤ হয়নি" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "exec লাইন '%s'-টির URI '%s' সহ পà§à¦°à¦¸à¦¾à¦°à¦£ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "'%s' অকà§à¦·à¦°à¦®à¦¾à¦²à¦¾ থেকে '%s'-ঠরূপানà§à¦¤à¦° করা সমরà§à¦¥à¦¿à¦¤ নয়" + +# sam: রà§à¦ªà¦¾à¦¨à§à¦¤à¦°à¦•ারক +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' থেকে '%s' রà§à¦ªà¦¾à¦¨à§à¦¤à¦°à¦•ারক খোলা যায়নি" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "রূপানà§à¦¤à¦° করার জনà§à¦¯ পà§à¦°à¦¦à¦¤à§à¦¤ ইনপà§à¦Ÿà§‡à¦° মধà§à¦¯à§‡ বাইটের অনà§à¦•à§à¦°à¦® সঠিক নয়" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "রূপানà§à¦¤à¦° করà§à¦® সঞà§à¦šà¦¾à¦²à¦¨à¦•ালের উৎপনà§à¦¨ তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "পà§à¦°à¦¦à¦¤à§à¦¤ ইনপà§à¦Ÿà§‡à¦° অনà§à¦¤à§‡ আংশিক অকà§à¦·à¦° অনà§à¦•à§à¦°à¦®" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "ফলবà§à¦¯à¦¾à¦• '%s' থেকে '%s' কোড-সেটে পরিবরà§à¦¤à¦¨ করা যায়নি" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s'-টি \"file\" সà§à¦•িম বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•ারী সà§à¦¨à¦¿à¦¶à§à¦šà¦¿à¦¤ URI নয়" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ফাইল URI '%s'-à¦à¦° মধà§à¦¯à§‡ '#' চিহà§à¦¨ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ করা যাবে না" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' অকারà§à¦¯à¦•র" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI '%s'-à¦à¦° হোসà§à¦Ÿ-নেম অকারà§à¦¯à¦•র" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s'-à¦à¦° মধà§à¦¯à§‡ অবৈধরূপে à¦à¦¸à§à¦•েপ অকà§à¦·à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হয়েছে" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s' পাথটি সà§à¦¨à¦¿à¦¶à§à¦šà¦¿à¦¤ নয়" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "হোসà§à¦Ÿ-নেম অকারà§à¦¯à¦•র" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "পূরà§à¦¬à¦¾à¦¹à§à¦£" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "অপরাহà§à¦£" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%A %d %b %Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%I:%M:%S %Z" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "জানà§à§Ÿà¦¾à¦°à¦¿" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "ফেবà§à¦°à§à§Ÿà¦¾à¦°à¦¿" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "মারà§à¦š" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "à¦à¦ªà§à¦°à¦¿à¦²" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "মে" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "জà§à¦¨" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "জà§à¦²à¦¾à¦‡" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "জানà§" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ফেবà§à¦°à§" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "মারà§à¦š" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à¦à¦ªà§à¦°à¦¿" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "মে" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "জà§à¦¨" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "জà§à¦²" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "সোমবার" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "মঙà§à¦—লবার" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "বà§à¦§à¦¬à¦¾à¦°" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "বৃহসà§à¦ªà¦¤à¦¿à¦¬à¦¾à¦°" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "শà§à¦•à§à¦°à¦¬à¦¾à¦°" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "শনিবার" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "রবিবার" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "সোম" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "মঙà§à¦—ল" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "বà§à¦§" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "বৃহঃ" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "শà§à¦•à§à¦°" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "শনি" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "রবি" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "'%s' ডিরেকà§à¦Ÿà¦°à¦¿ খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "%lu বাইট, \"%s\" ফাইল পড়ার জনà§à¦¯ বরাদà§à¦¦ করা যায়নি" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' ফাইল পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "\"%s\" ফাইল অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' ফাইল থেকে পড়তে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' ফাইল খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' ফাইলের বৈশিষà§à¦Ÿà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥: fstat() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' ফাইল খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: fdopen() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "'%s' ফাইলের নাম '%s'-ঠপরিবরà§à¦¤à¦¨ করতে বà§à¦¯à¦°à§à¦¥: g_rename() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' ফাইল তৈরি করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "লেখার উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ '%s' খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: fdopen() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "'%s' ফাইলে লিখতে বà§à¦¯à¦°à§à¦¥: fwrite() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "'%s' ফাইলে লিখতে বà§à¦¯à¦°à§à¦¥: fflush() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' ফাইলে লিখতে বà§à¦¯à¦°à§à¦¥: fsync() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "'%s' ফাইল বনà§à¦§ করতে বà§à¦¯à¦°à§à¦¥: fclose() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "বিদà§à¦¯à¦®à¦¾à¦¨ ফাইল '%s' অপসারিত করা যায়নি: g_unlink() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "নমà§à¦¨à¦¾ '%s' সঠিক নয়, '%s' থাকা উচিত নয়" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "'%s' টেমপà§à¦²à§‡à¦Ÿà§‡à¦° মধà§à¦¯à§‡ XXXXXX অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ নেই" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f কিলোবাইট" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f মেগাবাইট" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f গিগাবাইট" + +# TB= টেরাবাইট +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f টেরাবাইট" + +# PB= পেটাবাইট +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f পেটাবাইট" + +# EB= ইকà§à¦¸à¦¾à¦¬à¦¾à¦‡à¦Ÿ +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f ইকà§à¦¸à¦¾à¦¬à¦¾à¦‡à¦Ÿ" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f কিলোবাইট" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f মেগাবাইট" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f গিগাবাইট" + +# TB= টেরাবাইট +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f টেরাবাইট" + +# PB= পেটাবাইট +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f পেটাবাইট" + +# EB= ইকà§à¦¸à¦¾à¦¬à¦¾à¦‡à¦Ÿ +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ইকà§à¦¸à¦¾à¦¬à¦¾à¦‡à¦Ÿ" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f কিলোবাইট" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "'%s' সিমà§à¦¬à§‹à¦²à¦¿à¦™à§à¦• লিঙà§à¦• পড়তে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "সিমà§à¦¬à§‹à¦²à¦¿à¦• লিঙà§à¦• সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' থেকে '%s' রà§à¦ªà¦¾à¦¨à§à¦¤à¦°à¦•ারক খোলা যায়নি: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string-ঠraw read করা সমà§à¦­à¦¬ নয়" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "read বাফারের মধà§à¦¯à§‡ অরূপানà§à¦¤à¦°à¦¿à¦¤ তথà§à¦¯ অবশিষà§à¦Ÿ রয়েছে" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "আংশিক অকà§à¦·à¦° দà§à¦¬à¦¾à¦°à¦¾ চà§à¦¯à¦¾à¦¨à§‡à¦²à§‡à¦° সমাপà§à¦¤à¦¿" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end-ঠraw read করা সমà§à¦­à¦¬ নয়" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "'%s' খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: open() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "'%s' ফাইল মà§à¦¯à¦¾à¦ª করতে বà§à¦¯à¦°à§à¦¥: mmap() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "রেখা %d অকà§à¦·à¦° %d-তে তà§à¦°à§à¦Ÿà¦¿: " + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "নামের মধà§à¦¯à§‡ অবৈধ UTF-8 à¦à¦¨à¦•োডিং সহ টেকà§à¦¸à¦Ÿ - কারà§à¦¯à¦•র '%s' নয়" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "'%s' কারà§à¦¯à¦•র নাম নয়" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "'%s' কারà§à¦¯à¦•র নাম নয়: '%c' " + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d রেখার মধà§à¦¯à§‡ তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥, à¦à¦Ÿà¦¿ কোনো অকà§à¦·à¦°à§‡à¦° রেফারেনà§à¦¸à§‡à¦° মধà§à¦¯à§‡ à¦à¦•টি সংখà§à¦¯à¦¾ হওয়া উচিত " +"(উদাহরণসà§à¦¬à¦°à§‚প ê) - সমà§à¦­à¦¬à¦¤ সংখà§à¦¯à¦¾à¦Ÿà¦¿ অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"অকà§à¦·à¦°à§‡à¦° রেফারেনà§à¦¸ সেমি-কোলন চিহà§à¦¨ দà§à¦¬à¦¾à¦°à¦¾ সমাপà§à¦¤ হয়নি; সমà§à¦­à¦¬à¦¤ আপনি সà§à¦¬à¦¤à§à¦¬à¦¾ হিসাবে " +"বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ à¦à§à¦¯à¦¾à¦®à§à¦ªà¦¾à¦°à§à¦¸à§à¦¯à¦¨à§à¦¡ চিহà§à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করেননি - & রূপে à¦à¦®à§à¦ªà¦¾à¦°à¦¸à§‡à¦¨à§à¦¡ à¦à¦¸à§à¦•েপ " +"করানো যাবে" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "'%-.*s' অকà§à¦·à¦°à§‡à¦° রেফারেনà§à¦¸à§‡à¦° মধà§à¦¯à§‡ অনà§à¦®à§‹à¦¦à¦¿à¦¤ অকà§à¦·à¦° à¦à¦¨à¦•োড করা হয়নি" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"তথà§à¦¯à¦¬à¦¿à¦¹à§€à¦¨ à¦à¦¨à¦Ÿà¦¿à¦Ÿà¦¿ '&;' পà§à¦°à¦¦à¦°à§à¦¶à¦¿à¦¤; বৈধ à¦à¦¨à¦Ÿà¦¿à¦Ÿà¦¿ হল: & " < > '" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "à¦à¦¨à¦Ÿà¦¿à¦Ÿà¦¿à¦° নাম '%-.*s' অজানা" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"à¦à¦¨à¦Ÿà¦¿à¦Ÿà¦¿à¦° নাম সেমিকোলোন চিহà§à¦¨ দà§à¦¬à¦¾à¦°à¦¾ সমাপà§à¦¤ হয়নি; সমà§à¦­à¦¬à¦¤ আপনি à¦à¦¨à¦Ÿà¦¿à¦Ÿà¦¿ হিসাবে " +"বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ à¦à¦®à§à¦ªà¦¾à¦°à¦¸à§‡à¦¨à§à¦¡ চিহà§à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করেননি - & রূপে à¦à¦®à§à¦ªà¦¾à¦°à¦¸à§‡à¦¨à§à¦¡ à¦à¦¸à§à¦•েপ " +"করানো যাবে" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "ডকà§à¦®à§‡à¦¨à§à¦Ÿ কোনো à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ দà§à¦¬à¦¾à¦°à¦¾ আরমà§à¦­ হওয়া আবশà§à¦¯à¦• (উদাহরণসà§à¦¬à¦°à§‚প )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'<' অকà§à¦·à¦°à§‡à¦° পরে '%s'-à¦à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° বৈধ নয়; à¦à¦° দà§à¦¬à¦¾à¦°à¦¾ à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° নাম আরমà§à¦­ করা যাবে না" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"'%s' অকà§à¦·à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ নয়, '%s' ফাà¦à¦•া à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• টà§à¦¯à¦¾à¦— সমাপà§à¦¤ করার উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ " +"'>' চিহà§à¦¨ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"'%1$s' অকà§à¦·à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ নয়, '%3$s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° '%2$s' নামক বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° নামের পরে " +"à¦à¦•টি '=' চিহà§à¦¨ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"'%s' অকà§à¦·à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ নয়, '%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• টà§à¦¯à¦¾à¦— সমাপà§à¦¤ করার উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ '>' " +"অথবা '/' চিহà§à¦¨ অথবা কোনো বৈশিষà§à¦Ÿà§à¦¯à¦° উপসà§à¦¥à¦¿à¦¤à¦¿ কামà§à¦¯; সমà§à¦­à¦¬à¦¤ কোনো বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° নামের " +"মধà§à¦¯à§‡ অবৈধ অকà§à¦·à¦° বà§à¦¯à¦¬à¦¹à§ƒà¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"'%1$s' অকà§à¦·à¦° অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, '%3$s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° '%2$s' বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° মান নিরà§à¦§à¦¾à¦°à¦£à§‡à¦° " +"উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ সমান চিহà§à¦¨à§‡à¦° (=) পরে à¦à¦•টি উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨à§‡à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• অংশ উপসà§à¦¥à¦¿à¦¤à¦¿ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%2$s' বদà§à¦§ à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° নামের পশà§à¦šà¦¾à§Ž '%1$s' অকà§à¦·à¦°à§‡à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° বৈধ নয়; অনà§à¦®à§‹à¦¦à¦¿à¦¤ অকà§à¦·à¦° " +"হল '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "'%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ বদà§à¦§ অবসà§à¦¥à¦¾à§Ÿ ছিলো, তবে বরà§à¦¤à¦®à¦¾à¦¨à§‡ কোনো à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ খোলা অবসà§à¦¥à¦¾à§Ÿ নেই" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"'%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ বদà§à¦§ অবসà§à¦¥à¦¾à§Ÿ ছিলো, তবে বরà§à¦¤à¦®à¦¾à¦¨à§‡ '%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ খোলা অবসà§à¦¥à¦¾à§Ÿ রয়েছে" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "ডকà§à¦®à§‡à¦¨à§à¦Ÿ ফাà¦à¦•া ছিলো অথবা শà§à¦§à§à¦®à¦¾à¦¤à§à¦° শূণà§à¦¯à¦¸à§à¦¥à¦¾à¦¨ উপসà§à¦¥à¦¿à¦¤ ছিলো" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"তেরছা বনà§à¦§à¦¨à§€à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• চিহà§à¦¨à§‡à¦° '<' ঠিক পরে ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"খোলা à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà¦¸à¦¹ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে - '%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ সরà§à¦¬à¦¶à§‡à¦· খোলা " +"হয়েছিল" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে, <%s/> টà§à¦¯à¦¾à¦— সমাপà§à¦¤à¦¿à¦° জনà§à¦¯ তেরছা বনà§à¦§à¦¨à§€ চিহà§à¦¨à§‡à¦° " +"অনà§à¦¤à¦¿à¦® অংশের উপসà§à¦¥à¦¿à¦¤à¦¿ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° নামের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° নামের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• টà§à¦¯à¦¾à¦—ের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে।" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° নামের পরে উপসà§à¦¥à¦¿à¦¤ সমান চিহà§à¦¨à§‡à¦° পরে ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে; " +"বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° মান অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° মানের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "'%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° অনà§à¦¤à¦¿à¦® টà§à¦¯à¦¾à¦—ের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"কোনো মনà§à¦¤à¦¬à§à¦¯ অথবা পà§à¦°à¦•à§à¦°à¦¿à§Ÿà¦¾à¦•রণের নিরà§à¦¦à§‡à¦¶à§‡à¦° মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ অবজেকà§à¦Ÿ" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ সমসà§à¦¯à¦¾ অথবা কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ অবজেকà§à¦Ÿ" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "মেমরি অবশিষà§à¦Ÿ নেই" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "বà§à¦¯à¦¾à¦•-টà§à¦¯à¦¾à¦• করার সà§à¦¨à¦¿à¦°à§à¦¦à¦¿à¦·à§à¦Ÿ সীমা পূরà§à¦£" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "উলà§à¦²à¦¿à¦–িত বিনà§à¦¯à¦¾à¦¸à¦Ÿà¦¿à¦° মধà§à¦¯à§‡ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ সামগà§à¦°à§€, আংশিক মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ তà§à¦°à§à¦Ÿà¦¿" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "আংশিক মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡à¦° সময় বà§à¦¯à¦¾à¦• রেফারেনà§à¦¸ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿à¦° সীমা পূরà§à¦£" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "ফাà¦à¦•া সাবসà§à¦Ÿà§à¦°à¦¿à¦‚-à¦à¦° করà§à¦®à¦•à§à¦·à§‡à¦¤à§à¦°à§‡à¦° সীমা পূরà§à¦£" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "নতà§à¦¨ রেখা চিহà§à¦¨à¦•ারী ফà§à¦²à§à¦¯à¦¾à¦—ের অবৈধ সমষà§à¦Ÿà¦¿" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "অজানা তà§à¦°à§à¦Ÿà¦¿" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨à§‡à¦° শেষে \\ উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨à§‡à¦° শেষে \\c উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "\\-à¦à¦° পরে অজà§à¦žà¦¾à¦¤ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤ " + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" +"হরফের ছাà¦à¦¦ পরিবরà§à¦¤à¦¨à¦•ারী à¦à¦¸à§à¦•েপ অকà§à¦·à¦° (\\l, \\L, \\u, \\U) à¦à¦–ানে বà§à¦¯à¦¬à¦¹à¦¾à¦° করা যায় না" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "{} কোয়ানà§à¦Ÿà¦¿à¦«à¦¾à§Ÿà¦¾à¦°à§‡à¦° মধà§à¦¯à§‡ উলà§à¦²à¦¿à¦–িত সংখà§à¦¯à¦¾à¦—à§à¦²à§‹ কà§à¦°à¦®à¦¬à¦¿à¦¹à§€à¦¨" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "{} কোয়ানà§à¦Ÿà¦¿à¦«à¦¾à§Ÿà¦¾à¦°à§‡à¦° সংখà§à¦¯à¦¾ অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "অকà§à¦·à¦°à§‡à¦° কà§à¦²à¦¾à¦¸à§‡à¦° শেষে ] চিহà§à¦¨ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "অকà§à¦·à¦°à§‡à¦° কà§à¦²à¦¾à¦¸à§‡à¦° মধà§à¦¯à§‡ অকারà§à¦¯à¦•র à¦à¦¸à§à¦•েপ সিকোয়েনà§à¦¸" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "অকà§à¦·à¦°à§‡à¦° কà§à¦²à¦¾à¦¸à§‡à¦° মধà§à¦¯à§‡ উলà§à¦²à¦¿à¦–িত সীমা কà§à¦°à¦®à¦¬à¦¹à¦¿à¦°à§à¦­à§‚ত" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿à¦° জনà§à¦¯ কিছৠনেই" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "(? চিহà§à¦¨à§‡à¦° পরে অজà§à¦žà¦¾à¦¤ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "(?< চিহà§à¦¨à§‡à¦° পরে অজà§à¦žà¦¾à¦¤ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "(?P চিহà§à¦¨à§‡à¦° পরে অজà§à¦žà¦¾à¦¤ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX named কà§à¦²à¦¾à¦¸à¦—à§à¦²à¦¿ শà§à¦§à§à¦®à¦¾à¦¤à§à¦° কà§à¦²à¦¾à¦¸à§‡à¦° মধà§à¦¯à§‡ সমরà§à¦¥à¦¿à¦¤ হবে" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "শেষে ) অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "( চিহà§à¦¨ বিনা ) চিহà§à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হয়েছে" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R অথবা (?[+-]সংখà§à¦¯à¦¾-à¦à¦° পরে ) চিহà§à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা আবশà§à¦¯à¦•" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨ নিরà§à¦¦à§‡à¦¶ করা হয়েছে" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "বকà§à¦¤à¦¬à§à¦¯à§‡à¦° পরে ) চিহà§à¦¨ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "রেগà§à¦²à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨à¦Ÿà¦¿ অতà§à¦¯à¦¾à¦§à¦¿à¦• লমà§à¦¬à¦¾" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "মেমরি গà§à¦°à¦¹à¦¨ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "লà§à¦•-বিহাইনà§à¦¡ অà§à¦¯à¦¾à¦¸à¦¾à¦°à¦¶à¦¨à§‡à¦° দৈরà§à¦˜à§à¦¯ সà§à¦¨à¦¿à¦°à§à¦¦à¦¿à¦·à§à¦Ÿ নয়" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "(?(-à¦à¦° পরে তà§à¦°à§à¦Ÿà¦¿à¦ªà§‚রà§à¦£ সংখà§à¦¯à¦¾ অথবা নাম উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "অবসà§à¦¥à¦¾à¦­à¦¿à¦¤à§à¦¤à¦¿à¦• দলের মধà§à¦¯à§‡ দà§à¦Ÿà¦¿à¦° বেশি শà§à¦°à§‡à¦£à§€ উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "(?(-à¦à¦° পরে অà§à¦¯à¦¾à¦¸à¦¾à¦°à¦¶à¦¨ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "অজানা POSIX কà§à¦²à¦¾à¦¸à§‡à¦° নাম" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "POSIX কোলেটিং à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} অনà§à¦•à§à¦°à¦®à§‡à¦° মধà§à¦¯à§‡ উপসà§à¦¥à¦¿à¦¤ অকà§à¦·à¦°à§‡à¦° মান অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "অবৈধ কনà§à¦¡à¦¿à¦¶à¦¨ (?(0)" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "লà§à¦•-বিহাইনà§à¦¡ অà§à¦¯à¦¾à¦¸à¦¾à¦°à¦¶à¦¨à§‡à¦° মধà§à¦¯à§‡ \\C অনà§à¦®à§‹à¦¦à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "রিকারà§à¦¸à¦¿à¦­ কল-টি সীমাহীন সংখà§à¦¯à¦¾à§Ÿ লà§à¦ª করতে পারবে" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨ নামের মধà§à¦¯à§‡ সমাপà§à¦¤à¦¿ নিরà§à¦¦à§‡à¦¶à¦• অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "দà§à¦Ÿà¦¿ named সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ à¦à¦•ই নাম বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হয়েছে" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "তà§à¦°à§à¦Ÿà¦¿à¦ªà§‚রà§à¦£ \\P অথবা \\p সিকোয়েনà§à¦¸" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "\\P অথবা \\p-à¦à¦° পরে অজানা পà§à¦°à¦ªà¦¾à¦°à§à¦Ÿà¦¿à¦° নাম" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨à§‡à¦° নাম অতà§à¦¯à¦¾à¦§à¦¿à¦• লমà§à¦¬à¦¾ (সরà§à¦¬à¦¾à¦§à¦¿à¦• ৩২-টি অকà§à¦·à¦°)" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "নামসহ অতà§à¦¯à¦¾à¦§à¦¿à¦• সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨ (সরà§à¦¬à¦¾à¦§à¦¿à¦• ১০,০০০)" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "অকà§à¦Ÿà¦¾à¦² মান \\377-à¦à¦° অধিক" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE দলের মধà§à¦¯à§‡ à¦à¦•াধিক বà§à¦°à¦¾à¦žà§à¦š উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "কোনো DEFINE দলের পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿ করা যাবে না" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "বিসংগত NEWLINE বিকলà§à¦ª" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "\\g-à¦à¦° পরে braced নাম অথবা à¦à¦šà§à¦›à¦¿à¦•রূপে শূণà§à¦¯ ভিনà§à¦¨ braced সংখà§à¦¯à¦¾ উপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "কোড ওভার-ফà§à¦²à§‹" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "কমà§à¦ªà¦¾à¦‡à¦² করার করà§à¦®à¦•à§à¦·à§‡à¦¤à§à¦° অতিকà§à¦°à¦¾à¦¨à§à¦¤ হয়েছে" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "পূরà§à¦¬à§‡ পরীকà§à¦·à¦¿à¦¤ রেফারেনà§à¦¸ করা সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨ পাওয়া যায়নি" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "রেগà§à¦²à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨ %s-à¦à¦° মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE লাইবà§à¦°à§‡à¦°à¦¿ UTF8 সমরà§à¦¥à¦¨ ছাড়া কমà§à¦ªà¦¾à¦‡à¦² করা হয়েছে" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE লাইবà§à¦°à§‡à¦°à¦¿ UTF8 বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° সমরà§à¦¥à¦¨ ছাড়া কমà§à¦ªà¦¾à¦‡à¦² করা হয়েছে" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "রেগà§à¦²à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨ %s, %d অকà§à¦·à¦°à§‡ কমà§à¦ªà¦¾à¦‡à¦² করতে সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "রেগà§à¦²à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨ %s-à¦à¦° সেরা-অনà§à¦•ূল করতে সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "হেকà§à¦¸à¦¾à¦¡à§‡à¦¸à¦¿à¦®à¦¾à¦² সংখà§à¦¯à¦¾ অথবা '}' পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "হেকà§à¦¸à¦¾à¦¡à§‡à¦¸à¦¿à¦®à¦¾à¦² সংখà§à¦¯à¦¾ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "সিমà§à¦¬à¦²à¦¿à¦• রেফারেনà§à¦¸à§‡à¦° মধà§à¦¯à§‡ '<' অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "সিমà§à¦¬à¦²à¦¿à¦• রেফারেনà§à¦¸ অসমà§à¦ªà§‚রà§à¦£" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "সিমà§à¦¬à¦²à¦¿à¦• রেফারেনà§à¦¸à§‡à¦° মধà§à¦¯à§‡ অকà§à¦·à¦° সংখà§à¦¯à¦¾ শূণà§à¦¯" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "সংখà§à¦¯à¦¾ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "অবৈধ সিমà§à¦¬à¦²à¦¿à¦• রেফারেনà§à¦¸" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "অনà§à¦¤à§‡ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ '\\'" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "অজানা à¦à¦¸à§à¦•েপ সিকোয়েনà§à¦¸" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "পà§à¦°à¦¤à¦¿à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾à¦° টেকà§à¦¸à¦Ÿ \"%s\", %lu অকà§à¦·à¦°à§‡ পারà§à¦¸ করতে সমসà§à¦¯à¦¾: %s" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "উদà§à¦§à§ƒà¦¤à¦¿à¦° অংশ উদà§à¦§à¦¿à¦¤à¦¿ চিহà§à¦¨ দà§à¦¬à¦¾à¦°à¦¾ আরমà§à¦­ করা হয়নি" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "কমানà§à¦¡-লাইন অথবা শেল-à¦à¦° উদà§à¦§à§ƒà¦¤à¦¿à¦° মধà§à¦¯à§‡ অসংগত উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "'\\' অকà§à¦·à¦°à§‡à¦° পরে টেকà§à¦¸à¦Ÿ সমাপà§à¦¤ হয়েছে। (সংশà§à¦²à¦¿à¦·à§à¦Ÿ টেকà§à¦¸à¦Ÿ হল '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "%c-à¦à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ সà§à¦¸à¦‚গত উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨ পাওয়া যায়নি। (সংশà§à¦²à¦¿à¦·à§à¦Ÿ টেকà§à¦¸à¦Ÿ হল '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "টেকà§à¦¸à¦Ÿ ফাà¦à¦•া (অথবা শà§à¦§à§à¦®à¦¾à¦¤à§à¦° শূণà§à¦¯à¦¸à§à¦¥à¦¾à¦¨à¦¸à¦¹)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ থেকে তথà§à¦¯ পড়তে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸à§‡à¦° সাথে যোগাযোগের উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পাইপ তৈরি করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "চাইলà§à¦¡ পাইপ থেকে পড়তে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "'%s' ডিরেকà§à¦Ÿà¦°à¦¿à¦¤à§‡ পরিবরà§à¦¤à¦¨ করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ কারà§à¦¯à¦•র করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à§‡à¦° নাম অবৈধ: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d-তে আরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ ভেকà§à¦Ÿà¦°-ঠউলà§à¦²à¦¿à¦–িত সà§à¦Ÿà§à¦°à¦¿à¦‚টি বৈধ নয়: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "পরিবেশের মধà§à¦¯à§‡ উলà§à¦²à¦¿à¦–িত সà§à¦Ÿà§à¦°à¦¿à¦‚ বৈধ নয়: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "সকà§à¦°à¦¿à§Ÿ ডিরেকà§à¦Ÿà¦°à¦¿ বৈধ নয়: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "সহায়ক পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® চালাতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ থেকে তথà§à¦¯ পড়ার সময় g_io_channel_win32_poll()-ঠঅপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ তà§à¦°à§à¦Ÿà¦¿" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ থেকে তথà§à¦¯ পড়তে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ থেকে তথà§à¦¯ পড়ার সময় select() সংকà§à¦°à¦¾à¦¨à§à¦¤ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ তà§à¦°à§à¦Ÿà¦¿ (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid()-তে অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ তà§à¦°à§à¦Ÿà¦¿ (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ \"%s\" চালাতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸à§‡à¦° আউটপà§à¦Ÿ অথবা ইনপà§à¦Ÿ রি-ডাইরেকà§à¦Ÿ করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ fork করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ \"%s\" কারà§à¦¯à¦•র করতে অজানা সমসà§à¦¯à¦¾" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "চাইলà§à¦¡ pid পাইপ থেকে পরà§à¦¯à¦¾à¦ªà§à¦¤ তথà§à¦¯ পড়তে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "অকà§à¦·à¦°à¦Ÿà¦¿ UTF-8-à¦à¦° আয়তà§à¦¬à§‡à¦° বাইরে" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "রূপানà§à¦¤à¦° করার উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পà§à¦°à¦¦à¦¤à§à¦¤ তথà§à¦¯à§‡à¦° মধà§à¦¯à§‡ অবৈধ ধারা" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "অকà§à¦·à¦°à¦Ÿà¦¿ UTF-16-à¦à¦° আয়তà§à¦¬à§‡à¦° বাইরে" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦ªà§à¦°à¦£à¦¾à¦²à§€:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "সহায়তা সংকà§à¦°à¦¾à¦¨à§à¦¤ অপশন:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "সহায়তা সংকà§à¦°à¦¾à¦¨à§à¦¤ অপশন পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করা হবে" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "সহায়তা সংকà§à¦°à¦¾à¦¨à§à¦¤ সমসà§à¦¤ অপশন পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করা হবে" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন সংকà§à¦°à¦¾à¦¨à§à¦¤ অপশন:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "%2$s-à¦à¦° জনà§à¦¯ '%1$s'-à¦à¦° পূরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ মান পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%2$s-à¦à¦° জনà§à¦¯ '%1$s'-à¦à¦° পূরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ মান সীমা বহিরà§à¦­à§‚ত" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "%2$s-à¦à¦° জনà§à¦¯ '%1$s'-à¦à¦° দà§à¦¬à¦¿à¦—à§à¦£ মান পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "%2$s-à¦à¦° জনà§à¦¯ '%1$s'-à¦à¦° দà§à¦¬à¦¿à¦—à§à¦£ মান সীমা বহিরà§à¦­à§‚ত" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "%s অপশন পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "%s-à¦à¦° আরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "অজানা অপশন %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡à¦° ডিরেকà§à¦Ÿà¦°à¦¿à¦¤à§‡ মধà§à¦¯à§‡ কারà§à¦¯à¦•র কি-ফাইল পাওয়া যায়নি" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "সাধারণ ফাইল নয়" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "ফাইল ফাà¦à¦•া" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "কী-ফাইলের মধà§à¦¯à§‡ '%s' রেখাটি রয়েছে, à¦à¦Ÿà¦¿ কী-মান জà§à¦Ÿà¦¿, গà§à¦°à§à¦ª অথবা মনà§à¦¤à¦¬à§à¦¯ নয়" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "দলের নাম অকারà§à¦¯à¦•র: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "কী-ফাইলের পà§à¦°à¦¾à¦°à¦®à§à¦­à§‡ কোনো গà§à¦°à§à¦ª উলà§à¦²à¦¿à¦–িত নেই" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "কী-à¦à¦° নাম অকারà§à¦¯à¦•র: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "কী-ফাইলের মধà§à¦¯à§‡ অসমরà§à¦¥à¦¿à¦¤ à¦à¦¨à¦•োডিং '%s'" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "কী-ফাইলের মধà§à¦¯à§‡ কোনো গà§à¦°à§à¦ª অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ '%s'" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "কী-ফাইলের মধà§à¦¯à§‡ কোনো '%s' কি উপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"কী-ফাইলের মধà§à¦¯à§‡ '%2$s' মান সহ '%1$s' কি উপসà§à¦¥à¦¿à¦¤ রয়েছে যা UTF-8 বিনà§à¦¯à¦¾à¦¸à§‡ নেই।" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "কী-ফাইলের মধà§à¦¯à§‡ '%s' কি উপসà§à¦¥à¦¿à¦¤ রয়েছে যার মান বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "কী-ফাইলের মধà§à¦¯à§‡ '%s' কি উপসà§à¦¥à¦¿à¦¤ রয়েছে যার মান বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"কী-ফাইলের মধà§à¦¯à§‡ '%2$s' গà§à¦°à§à¦ªà§‡ '%1$s' কি উপসà§à¦¥à¦¿à¦¤ রয়েছে যার মান বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "কী-ফাইলের মধà§à¦¯à§‡ '%2$s' গà§à¦°à§à¦ªà§‡ '%1$s' কি উপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "কী-ফাইলের মধà§à¦¯à§‡ রেখার অবশেষে à¦à¦¸à§à¦•েপ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "কী-ফাইলের মধà§à¦¯à§‡ অকারà§à¦¯à¦•র à¦à¦¸à§à¦•েপ ধারা উপসà§à¦¥à¦¿à¦¤ রয়েছে '%s'" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "'%s' মান কোনো সংখà§à¦¯à¦¾à¦°à§‚পে বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "'%s' পূরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ মান সীমা বহিরà§à¦­à§‚ত" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "'%s' মান ফà§à¦²à§‹à¦Ÿ সংখà§à¦¯à¦¾ রূপে বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "'%s' মান বà§à¦²à¦¿à§Ÿà¦¾à¦¨ রূপে বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s-à¦à¦° জনà§à¦¯ উলà§à¦²à¦¿à¦–িত গণনার মান অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦® বরà§à¦¤à¦®à¦¾à¦¨ বনà§à¦§ হয়েছে" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "করà§à¦® বাতিল করা হয়েছে" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "অকারà§à¦¯à¦•র অবজেকà§à¦Ÿ, আরমà§à¦­ করা হয়নি" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "রূপানà§à¦¤à¦° করার জনà§à¦¯ পà§à¦°à¦¦à¦¤à§à¦¤ ইনপà§à¦Ÿà§‡à¦° মধà§à¦¯à§‡ বাইটের অনà§à¦•à§à¦°à¦® সমà§à¦ªà§‚রà§à¦¨ নয়" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "গনà§à¦¤à¦¬à§à¦¯à§‡à¦° জনà§à¦¯ পরà§à¦¯à¦¾à¦ªà§à¦¤ সà§à¦¥à¦¾à¦¨ নেই" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "বাতিল করার যোগà§à¦¯ পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• করà§à¦® সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "অজানা পà§à¦°à¦•ৃতি" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s ফাইলের ধরন" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s ধরণ" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° সমাপà§à¦¤à¦¿à¦¸à§à¦¥à¦² অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦­à¦¾à¦¬à§‡ শীঘà§à¦°à¦‡ পাওয়া গিয়েছে" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, fuzzy, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "সকেটের ঠিকানা সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করতে সমসà§à¦¯à¦¾:" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "ফাইল '%s' খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "'%s' ফাইল পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "'%s' ফাইল পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "ফাইলে লিখতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "'%s' ফাইল পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "অজানা পà§à¦°à¦•ৃতি" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "'%s' ডিরেকà§à¦Ÿà¦°à¦¿ খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿ তৈরি করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "ফাইল '%s' খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "'%s' ফাইল পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "'%s' ফাইল পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "ফাইল বনà§à¦§ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "ফাইল '%s' খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "ফাইল '%s' খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "যোগ করা সকেট বরà§à¦¤à¦®à¦¾à¦¨ বনà§à¦§ করা আছে" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, fuzzy, c-format +msgid "Property '%s' is not readable" +msgstr "%s ধরন কোনো শà§à¦°à§‡à¦£à§€à¦° মধà§à¦¯à§‡ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ নয়" + +#: ../gio/gdbusconnection.c:3959 +#, fuzzy, c-format +msgid "Property '%s' is not writable" +msgstr "%s ধরন কোনো শà§à¦°à§‡à¦£à§€à¦° মধà§à¦¯à§‡ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ নয়" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "লিসেনার বরà§à¦¤à¦®à¦¾à¦¨à§‡ বনà§à¦§ করা আছে" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, fuzzy, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "'%s' কারà§à¦¯à¦•র নাম নয়" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "ফাইলে লিখতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "আবরà§à¦œà¦¨à¦¾ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "ফাইলে লিখতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbusserver.c:1042 +#, fuzzy, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' কারà§à¦¯à¦•র নাম নয়" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "%d রেখার মধà§à¦¯à§‡ তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "%s অপশন পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +#, fuzzy +msgid "Connect to given D-Bus address" +msgstr "সংযোগ বরà§à¦¤à¦®à¦¾à¦¨à§‡ সà§à¦¥à¦¾à¦ªà¦¿à¦¤ হচà§à¦›à§‡" + +#: ../gio/gdbus-tool.c:360 +#, fuzzy +msgid "Connection Endpoint Options:" +msgstr "সংযোগ বরà§à¦¤à¦®à¦¾à¦¨à§‡ সà§à¦¥à¦¾à¦ªà¦¿à¦¤ হচà§à¦›à§‡" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, fuzzy, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "'%s' কারà§à¦¯à¦•র নাম নয়" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "'%s' কারà§à¦¯à¦•র নাম নয়" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "'%s' কারà§à¦¯à¦•র নাম নয়" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "'%s' কারà§à¦¯à¦•র নাম নয়" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%s অপশন পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "সংযোগ গà§à¦°à¦¹à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "'%s' ডিরেকà§à¦Ÿà¦°à¦¿ খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ অবজেকà§à¦Ÿ" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "নামবিহীন" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "ডেসà§à¦•টপ ফাইলের মধà§à¦¯à§‡ Exec ফিলà§à¦¡ উলà§à¦²à§‡à¦– করা নেই" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনের জনà§à¦¯ আবশà§à¦¯à¦• টারà§à¦®à¦¿à¦¨à¦¾à¦² পাওয়া যায়নি" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•ারী অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনের কনফিগারেশন ফোলà§à¦¡à¦¾à¦° %s তৈরি করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•ারী MIME কনফিগারেশন ফোলà§à¦¡à¦¾à¦° %s তৈরি করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•ারী ডেসà§à¦•টপ ফাইল %s তৈরি করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "%s-à¦à¦° জনà§à¦¯ সà§à¦¬à¦¨à¦¿à¦°à§à¦§à¦¾à¦°à¦¿à¦¤ বà§à¦¯à¦¾à¦–à§à¦¯à¦¾" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "ডà§à¦°à¦¾à¦‡à¦­à¦Ÿà¦¿ বের হয়ে যাওয়া বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¨ করতে পারে না" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" +"ডà§à¦°à¦¾à¦‡à¦­à¦Ÿà¦¿ বের করতে অথবা যে অপারেশন দিয়ে বের করা হবে বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¨ করতে পারে না" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "ডà§à¦°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à¦°à¦¾ মিডিয়া পোল করার বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¨ নেই" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "ডà§à¦°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à¦°à¦¾ পà§à¦°à¦¾à¦°à¦®à§à¦­à§‡à¦° করà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ নেই" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "ডà§à¦°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à¦°à¦¾ বনà§à¦§ করার করà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ নেই" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem à¦à¦¨à¦•োডিং-à¦à¦° %d সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem à¦à¦¨à¦•োডিং-à¦à¦° মধà§à¦¯à§‡ উপসà§à¦¥à¦¿à¦¤ কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ টোকেনের সংখà§à¦¯à¦¾ (%d)" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon à¦à¦¨à¦•োডিং-à¦à¦° %d সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon à¦à¦¨à¦•োডিং-à¦à¦° মধà§à¦¯à§‡ উপসà§à¦¥à¦¿à¦¤ কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ টোকেনের সংখà§à¦¯à¦¾ (%d)" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon-à¦à¦° জনà§à¦¯ à¦à¦•টি GEmblem পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "করà§à¦® সমরà§à¦¥à¦¿à¦¤ নয়" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "ধারণকারী মাউনà§à¦Ÿ উপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿à¦° উপরে অনà§à¦²à¦¿à¦ªà¦¿ করা যাবে না" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿à¦° উপর ডিরেকà§à¦Ÿà¦°à¦¿ অনà§à¦²à¦¿à¦ªà¦¿ করা যায়নি" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "টারগেট ফাইল উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "রিকারà§à¦¸à¦¿à¦­ ভাবে ডিরেকà§à¦Ÿà¦°à¦¿ অনà§à¦²à¦¿à¦ªà¦¿ করা যাবে না" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "সà§à¦ªà§à¦¯à¦¾à¦‡à¦¸ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gfile.c:2762 +#, c-format +msgid "Error splicing file: %s" +msgstr "সà§à¦ªà§à¦¯à¦¾à¦‡à¦¸à¦¿à¦‚ ফাইলে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "বিশেষ ফাইল অনà§à¦²à¦¿à¦ªà¦¿ করা যাবে না" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "অকারà§à¦¯à¦•র symlink মান দেয়া হয়েছে" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "আবরà§à¦œà¦¨à¦¾ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ফাইলের নামের মধà§à¦¯à§‡ '%c' বà§à¦¯à¦¬à¦¹à¦¾à¦° করা যাবে না" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "ভলিউম দà§à¦¬à¦¾à¦°à¦¾ মাউনà§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হয় না" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "চিহà§à¦¨à¦¿à¦¤ ফাইল বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾à¦° উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ কোনো অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন নিবনà§à¦§à¦¿à¦¤ হয়নি" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "ইনà§à¦®à§‡à¦°à§‡à¦Ÿà¦° বনà§à¦§" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "ফাইল enumerator-à¦à¦° মধà§à¦¯à§‡ অসমাপà§à¦¤ করà§à¦® উপসà§à¦¥à¦¿à¦¤" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "ফাইল enumerator বনà§à¦§ আছে" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon à¦à¦¨à¦•োডিং-à¦à¦° %d সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon-à¦à¦° জনà§à¦¯ কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ ইনপà§à¦Ÿ তথà§à¦¯ উপসà§à¦¥à¦¿à¦¤" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ query_info সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ Seek সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "ইনপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ টà§à¦°à¦¾à¦¨à¦•েট অরà§à¦¥à¦¾à§Ž ছাà¦à¦Ÿà¦¾à¦‡à§Ÿà§‡à¦° অনà§à¦®à¦¤à¦¿ নেই" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ টà§à¦°à¦¾à¦¨à¦•েট অরà§à¦¥à¦¾à§Ž ছাà¦à¦Ÿà¦¾à¦‡à§Ÿà§‡à¦° সমরà§à¦¥à¦¨ নেই" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "টোকেনের সংখà§à¦¯à¦¾ সঠিক নয় (%d)" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "%s কà§à¦²à¦¾à¦¸à§‡à¦° নামের জনà§à¦¯ কোনো ধরন নিরà§à¦§à¦¾à¦°à¦¿à¦¤ হয়নি" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s ধরন দà§à¦¬à¦¾à¦°à¦¾ GIcon ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "%s ধরন কোনো শà§à¦°à§‡à¦£à§€à¦° মধà§à¦¯à§‡ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ নয়" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "সংসà§à¦•রণ সংখà§à¦¯à¦¾ সটিকরূপে গঠিত হয়নি: %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s ধরণ দà§à¦¬à¦¾à¦°à¦¾ GIcon ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸à§‡à¦° মধà§à¦¯à§‡ from_tokens() বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "উপলবà§à¦§ আইকন à¦à¦¨à¦•োডিং-à¦à¦° সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "ইনপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ read বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ অসমাপà§à¦¤ করà§à¦® উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "সকেটের ঠিকানার জনà§à¦¯ পরà§à¦¯à¦¾à¦ªà§à¦¤ সà§à¦¥à¦¾à¦¨ নেই" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "সকেটের ঠিকানা সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "আবরà§à¦œà¦¨à¦¾ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, fuzzy, c-format +msgid "invalid GVariant type string '%s'" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (string পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤)" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ডিরেকà§à¦Ÿà¦°à¦¿ নিয়নà§à¦¤à§à¦°à¦£à§‡à¦° ডিফলà§à¦Ÿ ধরণ সনà§à¦§à¦¾à¦¨ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "ফাইলের নাম অবৈধ: %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ফাইল-সিসà§à¦Ÿà§‡à¦® সংকà§à¦°à¦¾à¦¨à§à¦¤ তথà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "root ডিরেকà§à¦Ÿà¦°à¦¿à¦° নাম পরিবরà§à¦¤à¦¨ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "ফাইলের নাম পরিবরà§à¦¤à¦¨à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "" +"ফাইলের নাম পরিবরà§à¦¤à¦¨ করা যায়নি, নতà§à¦¨ নামের à¦à¦•টি ফাইলের নাম বরà§à¦¤à¦®à¦¾à¦¨à§‡ উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "ফাইলের নাম অকারà§à¦¯à¦•র নয়" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "ফাইল খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿ খà§à¦²à¦¤à§‡ পারেনি" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "ফাইল মà§à¦›à§‡ ফেলতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "ফাইলটি আবরà§à¦œà¦¨à¦¾à§Ÿ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "আবরà§à¦œà¦¨à¦¾à¦° ডিরেকà§à¦Ÿà¦°à¦¿ %s তৈরি করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "আবরà§à¦œà¦¨à¦¾à¦° ঊরà§à¦§à§à¦¬à¦¤à¦¨ ডিরেকà§à¦Ÿà¦°à¦¿ সনাকà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "আবরà§à¦œà¦¨à¦¾à¦° ডিরেকà§à¦Ÿà¦°à¦¿ সনাকà§à¦¤ অথবা তৈরি করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "trashing info ফাইল তৈরি করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ফাইল বরà§à¦œà¦¨ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿ তৈরি করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ফাইলসিসà§à¦Ÿà§‡à¦® সিমà§à¦¬à§‹à¦²à¦¿à¦™à§à¦• লিঙà§à¦• সমরà§à¦¥à¦¨ করে না" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "সিমà§â€Œà¦¬à¦²à¦¿à¦• লিঙà§à¦• তৈরি করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "ফাইল সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿à¦° উপর ডিরেকà§à¦Ÿà¦°à¦¿ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করা যাবে না" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "বà§à¦¯à¦¾à¦•-আপ ফাইল তৈরি করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "উদà§à¦¦à¦¿à¦·à§à¦Ÿ ফাইল মà§à¦›à§‡ ফেলতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "মাউনà§à¦Ÿ করা অবসà§à¦¥à¦¾à¦¨à§‡à¦° মধà§à¦¯à§‡ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করা সমà§à¦­à¦¬ নয়" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ NULL-বà§à¦¯à¦¤à§€à¦¤ অনà§à¦¯ মান নিরà§à¦§à¦¾à¦°à¦£ করা আবশà§à¦¯à¦•" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (string পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤)" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "পà§à¦°à¦¸à¦¾à¦°à¦¿à¦¤ অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° নাম অবৈধ" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "পà§à¦°à¦¸à¦¾à¦°à¦¿à¦¤ অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿ '%s'-কে নিরà§à¦§à¦¾à¦°à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "ফাইল '%s' stat করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (অবৈধ à¦à¦¨à¦•োডিং)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "ফাইলের বিবরণ stat করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ uint32)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ uint64)" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (byte string পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤)" + +#: ../gio/glocalfileinfo.c:1904 +msgid "Cannot set permissions on symlinks" +msgstr "সিমলিংকের অনà§à¦®à¦¤à¦¿ নিরà§à¦§à¦¾à¦°à¦£ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "অনà§à¦®à¦¤à¦¿ নিরà§à¦§à¦¾à¦°à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "মালিকানা নিরà§à¦§à¦¾à¦°à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "সিমà§â€Œ-লিঙà§à¦• NULL-বà§à¦¯à¦¾à¦¤à§€à¦¤ মান হওয়া আবশà§à¦¯à¦•" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "সিমà§â€Œ-লিঙà§à¦• নিরà§à¦§à¦¾à¦°à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "সিমà§â€Œ-লিঙà§à¦• নিরà§à¦§à¦¾à¦°à¦£ করতে তà§à¦°à§à¦Ÿà¦¿: ফাইলটি সিমà§â€Œ-লিঙà§à¦• নয়" + +#: ../gio/glocalfileinfo.c:2139 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "পরিবরà§à¦¤à¦¨ অথবা বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° সময় নিরà§à¦§à¦¾à¦°à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "SELinux কনটেকà§à¦¸à¦Ÿà§‡à¦° NULL-বà§à¦¯à¦¾à¦¤à§€à¦¤ মান হওয়া আবশà§à¦¯à¦•" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux কনটেকà§à¦¸à¦Ÿ নিরà§à¦§à¦¾à¦°à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "à¦à¦‡ সিসà§à¦Ÿà§‡à¦®à§‡ SELinux সকà§à¦°à¦¿à§Ÿ করা হয়নি" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° মান নিরà§à¦§à¦¾à¦°à¦£ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "ফাইল থেকে পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ফাইলের মধà§à¦¯à§‡ seek করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "ফাইল বনà§à¦§ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ডিরেকà§à¦Ÿà¦°à¦¿ নিয়নà§à¦¤à§à¦°à¦£à§‡à¦° ডিফলà§à¦Ÿ ধরন সনà§à¦§à¦¾à¦¨ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "ফাইলে লিখতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "পà§à¦°à§‹à¦¨à§‹ বà§à¦¯à¦¾à¦•-আপের লিংক মà§à¦›à§‡ ফেলতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "বà§à¦¯à¦¾à¦•-আপ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ তৈরি করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "অসà§à¦¥à¦¾à§Ÿà§€ ফাইলের নাম পরিবরà§à¦¤à¦¨ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "ফাইল টà§à¦°à¦¾à¦¨à¦•েট (ছাà¦à¦Ÿà¦¾à¦‡) করতে সমসà§à¦¯à¦¾ %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "ফাইল '%s' খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "উদà§à¦¦à¦¿à¦·à§à¦Ÿ ফাইলটি à¦à¦•টি ডিরেকà§à¦Ÿà¦°à¦¿" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "উদà§à¦¦à¦¿à¦·à§à¦Ÿ ফাইলটি সাধারণ ফাইল নয়" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "ফাইলটি সà§à¦¬à¦¤à¦¨à§à¦¤à§à¦°à¦°à§‚পে পরিবরà§à¦¤à¦¨ করা হয়েছে" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "পà§à¦°à§‹à¦¨à§‹ ফাইল মà§à¦›à§‡ ফেলতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "অবৈধ GSeekType উলà§à¦²à¦¿à¦–িত হয়েছে" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "অবৈধ seek-à¦à¦° অনà§à¦°à§‹à¦§" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream টà§à¦°à¦¾à¦¨à¦•েট করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "মেমরি আউটপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° মাপ পরিবরà§à¦¤à¦¨à¦¯à§‹à¦—à§à¦¯ নয়" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "মেমরি আউটপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° মাপ পরিবরà§à¦¤à¦¨ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"রাইট পà§à¦°à¦¸à§‡à¦¸ করার জনà§à¦¯ পà§à¦°à§Ÿà§‹à¦œà¦¨à§€à§Ÿ মেমরির পরিমান বিদà§à¦¯à¦®à¦¾à¦¨ ঠিকানার জনà§à¦¯ ফাà¦à¦•া সà§à¦¥à¦¾à¦¨à§‡à¦° " +"অধিক" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "সà§à¦Ÿà§à¦°à§€à¦®à§‡à¦° শà§à¦°à§à¦° পূরà§à¦¬à§‡ অনà§à¦°à§‹à¦§à¦•ৃত সিক" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "সà§à¦Ÿà§à¦°à§€à¦®à§‡à¦° শেষের অতিরিকà§à¦¤ অনà§à¦°à§‹à¦§à¦•ৃত সিক" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "মাউনà§à¦Ÿ করা বসà§à¦¤à§à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ \"আনমাউনà§à¦Ÿ\" পà§à¦°à§Ÿà§‹à¦— করা সমà§à¦­à¦¬ নয়" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "মাউনà§à¦Ÿ করা বসà§à¦¤à§à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ \"বের করা\" পà§à¦°à§Ÿà§‹à¦— করা সমà§à¦­à¦¬ নয়" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"মাউনà§à¦Ÿ করা বসà§à¦¤à§à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ \"unmount\" অথবা \"unmount_with_operation\" পà§à¦°à§Ÿà§‹à¦— করা " +"সমà§à¦­à¦¬ নয়" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"মাউনà§à¦Ÿ করা বসà§à¦¤à§à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ \"eject\" অথবা \"eject_with_operation\" পà§à¦°à§Ÿà§‹à¦— করা সমà§à¦­à¦¬ " +"নয়" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "মাউনà§à¦Ÿ করা বসà§à¦¤à§à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ \"remount\" পà§à¦°à§Ÿà§‹à¦— করা সমà§à¦­à¦¬ নয়" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "mount দà§à¦¬à¦¾à¦°à¦¾ সামগà§à¦°à§€à¦° ধরন অনà§à¦®à¦¾à¦¨ করা সমà§à¦­à¦¬ নয়" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "mount দà§à¦¬à¦¾à¦°à¦¾ সà§à¦¸à¦‚গতভাবে সামগà§à¦°à§€à¦° ধরন অনà§à¦®à¦¾à¦¨ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "'%s' হোসà§à¦Ÿ-নেমের মধà§à¦¯à§‡ '[' উপসà§à¦¥à¦¿à¦¤ রয়েছে কিনà§à¦¤à§ ']' অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "আউটপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ write বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "মূল সà§à¦Ÿà§à¦°à¦¿à¦® বরà§à¦¤à¦®à¦¾à¦¨à§‡ বনà§à¦§ করা হয়েছে" + +#: ../gio/gresolver.c:779 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' মীমাংসা করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gresolver.c:829 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "বিপরীত কà§à¦°à¦®à§‡ '%s' মীমাংসা করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "'%s'-à¦à¦° পরিসেবার কোনো রেকরà§à¦¡ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "সাময়িকভাবে '%s' মীমাংসা করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, c-format +msgid "Error resolving '%s'" +msgstr "'%s' মীমাংসা করতে তà§à¦°à§à¦Ÿà¦¿" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "অজানা অপশন %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "অবৈধ সকেট, আরমà§à¦­ করা হয়নি" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "অবৈধ সকেট, চিহà§à¦¨à¦¿à¦¤ কারণে আরমà§à¦­ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "সকেট বরà§à¦¤à¦®à¦¾à¦¨à§‡ বনà§à¦§ করা হয়েছে" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd থেকে GSocket তৈরি করা হচà§à¦›à§‡: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, c-format +msgid "Unable to create socket: %s" +msgstr "সকেট তৈরি করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "অজানা পà§à¦°à§‹à¦Ÿà§‹à¦•ল নিরà§à¦§à¦¾à¦°à¦£ করা হয়" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ঠিকানা পেতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "দূরবরà§à¦¤à§€ ঠিকানা পেতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "অপেকà§à¦·à¦¾ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:1446 +#, c-format +msgid "Error binding to address: %s" +msgstr "ঠিকানার সাথে বাইনà§à¦¡ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:1566 +#, c-format +msgid "Error accepting connection: %s" +msgstr "সংযোগ গà§à¦°à¦¹à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:1683 +msgid "Error connecting: " +msgstr "সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করতে সমসà§à¦¯à¦¾:" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "সংযোগ বরà§à¦¤à¦®à¦¾à¦¨à§‡ সà§à¦¥à¦¾à¦ªà¦¿à¦¤ হচà§à¦›à§‡" + +#: ../gio/gsocket.c:1695 +#, c-format +msgid "Error connecting: %s" +msgstr "সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "অপেকà§à¦·à¦¾à¦°à¦¤ তà§à¦°à§à¦Ÿà¦¿ পেতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:1875 +#, c-format +msgid "Error receiving data: %s" +msgstr "তথà§à¦¯ পেতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:2050 +#, c-format +msgid "Error sending data: %s" +msgstr "তথà§à¦¯ পাঠাতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "সকেট তৈরি করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:2242 +#, c-format +msgid "Error closing socket: %s" +msgstr "সকেট বনà§à¦§ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "সকেটের অবসà§à¦¥à¦¾ পেতে অপেকà§à¦·à¦¾ করা হচà§à¦›à§‡: %s" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, c-format +msgid "Error sending message: %s" +msgstr "বারà§à¦¤à¦¾ পাঠাতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "উইনà§à¦¡à§‹à¦¤à§‡ GSocketControlMessage সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, c-format +msgid "Error receiving message: %s" +msgstr "বারà§à¦¤à¦¾ পেতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "সংযোগ সà§à¦¥à¦¾à¦ªà¦¨à¦•ালে অজানা সমসà§à¦¯à¦¾" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "%s ধরন কোনো শà§à¦°à§‡à¦£à§€à¦° মধà§à¦¯à§‡ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ নয়" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "লিসেনার বরà§à¦¤à¦®à¦¾à¦¨à§‡ বনà§à¦§ করা আছে" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "যোগ করা সকেট বরà§à¦¤à¦®à¦¾à¦¨ বনà§à¦§ করা আছে" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GEmblemedIcon à¦à¦¨à¦•োডিং-à¦à¦° %d সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "à§§-টি কনটà§à¦°à§‹à¦² বারà§à¦¤à¦¾ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, %d-টি পেয়েছে" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ পà§à¦°à¦•ৃতির আনà§à¦·à¦™à§à¦—িক তথà§à¦¯" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "à¦à¦•টি fd পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, কিনà§à¦¤à§ %d পেয়েছে\n" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "অকারà§à¦¯à¦•র fd পেয়েছে" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "তথà§à¦¯ পাঠাতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "ফাইলের নাম পরিবরà§à¦¤à¦¨à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, fuzzy, c-format +msgid "Not expecting control message, but got %d" +msgstr "à§§-টি কনটà§à¦°à§‹à¦² বারà§à¦¤à¦¾ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, %d-টি পেয়েছে" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "unix থেকে পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "unix বনà§à¦§ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "ফাইল-সিসà§à¦Ÿà§‡à¦®à§‡à¦° root" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "unix-ঠলিখতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "à¦à¦‡ সিসà§à¦Ÿà§‡à¦®à§‡à¦° মধà§à¦¯à§‡ অà§à¦¯à¦¾à¦¬à¦¸à§à¦Ÿà§à¦°à§à¦¯à¦¾à¦•à§à¦Ÿ unix ডোমেইন সকেট ঠিকানা সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "ভলিউম দà§à¦¬à¦¾à¦°à¦¾ বের করা বà§à¦¯à¦¬à¦¹à¦¾à¦° করা সমà§à¦­à¦¬ নয়" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "ভলিউম দà§à¦¬à¦¾à¦°à¦¾ eject অথবা eject_with_operation বà§à¦¯à¦¬à¦¹à¦¾à¦° করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন পাওয়া যায়নি" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন আরমà§à¦­ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "URI সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "সংসরà§à¦— সমà§à¦¬à¦¨à§à¦§à§€à§Ÿ পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ win32-à¦à¦° মধà§à¦¯à§‡ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "সংসরà§à¦— নিরà§à¦§à¦¾à¦°à¦£ win32-à¦à¦° মধà§à¦¯à§‡ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "ফাইল থেকে পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "ফাইল বনà§à¦§ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "ফাইলে লিখতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "যথেষà§à¦Ÿ মেমরি নেই" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "আরও ইনপà§à¦Ÿ পà§à¦°à§Ÿà§‹à¦œà¦¨" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "অকারà§à¦¯à¦•র কমপà§à¦°à§‡à¦¸ করা ডাটা" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "ডিরেকà§à¦Ÿà¦°à¦¿à¦° উপর ডিরেকà§à¦Ÿà¦°à¦¿ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করা যাবে না" + +#, fuzzy +#~ msgid "Key %s is not writable\n" +#~ msgstr "%s ধরন কোনো শà§à¦°à§‡à¦£à§€à¦° মধà§à¦¯à§‡ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ নয়" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "রূপানà§à¦¤à¦° করার উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পà§à¦°à¦¦à¦¤à§à¦¤ তথà§à¦¯à§‡à¦° মধà§à¦¯à§‡ অবৈধ ধারা" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "ডাটা অà§à¦¯à¦¾à¦°à§‡à¦° সরà§à¦¬à¦¾à¦§à¦¿à¦• সীমা উপসà§à¦¥à¦¿à¦¤ হয়েছে" + +#~ msgid "do not hide entries" +#~ msgstr "à¦à¦¨à§à¦Ÿà§à¦°à¦¿ আড়াল করা হবে না" + +#~ msgid "use a long listing format" +#~ msgstr "লং লিসà§à¦Ÿà¦¿à¦‚ বিনà§à¦¯à¦¾à¦¸ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হবে" + +#~ msgid "[FILE...]" +#~ msgstr "[FILE...]" diff --git a/po/bn_IN.po b/po/bn_IN.po new file mode 100644 index 0000000..d71dc75 --- /dev/null +++ b/po/bn_IN.po @@ -0,0 +1,4796 @@ +# translation of bn_IN.po to Bengali INDIA +# The Bengali India translation for glib. +# Copyright (C) 2002 +# This file is distributed under the same license as the glib package. +# +# Taneem Ahmed , 2002. +# Mahay Alam Khan , 2005. +# Samia Niamatullah , 2005. +# Runa Bhattacharjee , 2007. +# Runa Bhattacharjee , 2008. +# Runa Bhattacharjee , 2008, 2009, 2011. +# sray , 2013, 2014. #zanata. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-23 05:55+0000\n" +"PO-Revision-Date: 2014-09-23 16:46+0000\n" +"Last-Translator: \n" +"Language-Team: Bengali (India) \n" +"Language: bn_IN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.5\n" + +#: ../gio/gapplication.c:514 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"GApplication পরিষেবা মোড পà§à¦°à¦¬à§‡à¦¶ করান (D-Bus পরিষেবা ফাইলগà§à¦²à¦¿ থেকে বà§à¦¯à¦¬à¦¹à¦¾à¦° " +"করà§à¦¨)" + +#: ../gio/gapplication.c:519 +msgid "GApplication options" +msgstr "GApplication বিকলà§à¦ª" + +#: ../gio/gapplication.c:519 +msgid "Show GApplication options" +msgstr "GApplication বিকলà§à¦ªà¦—à§à¦²à¦¿ দেখান" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:485 ../gio/gsettings-tool.c:508 +msgid "Print help" +msgstr "মà§à¦¦à§à¦°à¦£ সহায়তা" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:486 +#: ../gio/gresource-tool.c:554 +msgid "[COMMAND]" +msgstr "[কমà§à¦¯à¦¾à¦¨à§à¦¡]" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "ঠিকানা মà§à¦¦à§à¦°à¦£" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:514 +msgid "Print version information and exit" +msgstr "সংসà§à¦•রণ সংকà§à¦°à¦¾à¦¨à§à¦¤ তথà§à¦¯ পà§à¦°à¦¿à¦¨à§à¦Ÿ করে পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করà§à¦¨" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনগà§à¦²à¦¿à¦° তালিকা তৈরি করà§à¦¨" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"ইনসà§à¦Ÿà¦² করা D-Bus সকà§à¦°à¦¿à§Ÿà¦¯à§‹à¦—à§à¦¯ অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনগà§à¦²à¦¿à¦° তালিকা (.desktop ফাইলগà§à¦²à¦¿ " +"দà§à¦¬à¦¾à¦°à¦¾)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "à¦à¦•টি অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন লঞà§à¦š করà§à¦¨" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনটি লঞà§à¦š করà§à¦¨ (বিকলà§à¦ª ফাইলগà§à¦²à¦¿ খোলা সমেত)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "à¦à¦•টি অà§à¦¯à¦¾à¦•শন সকà§à¦°à¦¿à§Ÿ করà§à¦¨" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনে à¦à¦•টি অà§à¦¯à¦¾à¦•শন পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করà§à¦¨" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "উপলবà§à¦§ অà§à¦¯à¦¾à¦•শনগà§à¦²à¦¿à¦° তালিকা তৈরি করà§à¦¨" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"à¦à¦•টি অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনের জনà§à¦¯ সà§à¦Ÿà§à¦¯à¦¾à¦Ÿà¦¿à¦• অà§à¦¯à¦¾à¦•শনগà§à¦²à¦¿à¦° তালিকা তৈরি করà§à¦¨ (.desktop " +"ফাইল থেকে)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "à¦à¦° জনà§à¦¯ বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ সহায়তা মà§à¦¦à§à¦°à¦£ করার জনà§à¦¯ কমà§à¦¯à¦¾à¦¨à§à¦¡" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus ফরà§à¦®à§à¦¯à¦¾à¦Ÿà§‡ অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন শনাকà§à¦¤à¦•ারী (উদাঃ org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:492 +#: ../gio/gresource-tool.c:558 +msgid "FILE" +msgstr "ফাইল" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "খোলার বৈকলà§à¦ªà¦¿à¦• সমà§à¦ªà¦°à§à¦•িত বা সমà§à¦ªà¦°à§à¦•িত ফাইলনামগà§à¦²à¦¿, বা URIগà§à¦²à¦¿" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "অà§à¦¯à¦¾à¦•শন" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করার অà§à¦¯à¦¾à¦•শনের নাম" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "পà§à¦¯à¦¾à¦°à¦¾à¦®à¦¿à¦Ÿà¦¾à¦°" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "অà§à¦¯à¦¾à¦•শন পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦°à§‡ বৈকলà§à¦ªà¦¿à¦• পà§à¦¯à¦¾à¦°à¦¾à¦®à¦¿à¦Ÿà¦¾à¦°, GVariant ফরà§à¦®à§à¦¯à¦¾à¦Ÿà§‡" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:523 +#: ../gio/gsettings-tool.c:594 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"অজানা কমà§à¦¯à¦¾à¦¨à§à¦¡ %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "বà§à¦¯à¦¬à¦¹à¦¾à¦°:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:548 +#: ../gio/gsettings-tool.c:628 +msgid "Arguments:\n" +msgstr "অারà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "কমà§à¦¯à¦¾à¦¨à§à¦¡:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ সহায়তা পেতে '%s help COMMAND' বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s কমà§à¦¯à¦¾à¦¨à§à¦¡à§‡ à¦à¦•টি অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন অাইডি যোগ করতে হবে\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "অবৈধ অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন অাইডি: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' ঠকোনো অারà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ থাকে না\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus-ঠসংযোগ করতে বà§à¦¯à¦°à§à¦¥: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "%s বারà§à¦¤à¦¾ à¦à¦‡ অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনে পাঠাতে তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন অাইডি'র পরে অবশà§à¦¯à¦‡ অà§à¦¯à¦¾à¦•শন নাম দিতে হবে\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"অবৈধ অà§à¦¯à¦¾à¦•শন নাম: '%s'\n" +"অà§à¦¯à¦¾à¦•শন নামগà§à¦²à¦¿à¦¤à§‡ শà§à¦§à§à¦®à¦¾à¦¤à§à¦° বরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾, '-' à¦à¦¬à¦‚ '.' থাকতে পারবে\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "অà§à¦¯à¦¾à¦•শন পà§à¦¯à¦¾à¦°à¦¾à¦®à¦¿à¦Ÿà¦¾à¦° পারà§à¦œ করতে তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "অà§à¦¯à¦¾à¦•শনগà§à¦²à¦¿ সরà§à¦¬à¦¾à¦§à¦¿à¦• à¦à¦•টি পà§à¦¯à¦¾à¦°à¦¾à¦®à¦¿à¦Ÿà¦¾à¦° সà§à¦¬à§€à¦•ার করে\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "list-actions কমà§à¦¯à¦¾à¦¨à§à¦¡ শà§à¦§à§à¦®à¦¾à¦¤à§à¦° অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন অাইডি নেয়" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "%s অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনের জনà§à¦¯ ডেসà§à¦•টপ ফাইল খà§à¦à¦œà§‡ পেতে বà§à¦¯à¦°à§à¦¥\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"অসà§à¦¬à§€à¦•ৃত কমà§à¦¯à¦¾à¦¨à§à¦¡: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:370 +#: ../gio/ginputstream.c:608 ../gio/ginputstream.c:828 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:823 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s-র জনà§à¦¯ উলà§à¦²à¦¿à¦–িত গণনার মান অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "বেস সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ seek কমানà§à¦¡ সহযোগে খোà¦à¦œà¦¾ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream ছাà¦à¦Ÿà¦¾ যায় না" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1017 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1464 +msgid "Stream is already closed" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦® বরà§à¦¤à¦®à¦¾à¦¨ বনà§à¦§ হয়েছে" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "বেস সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ টà§à¦°à¦¾à¦¨à¦•েট অরà§à¦¥à¦¾à§Ž ছাà¦à¦Ÿà¦¾à¦‡à§Ÿà§‡à¦° সমরà§à¦¥à¦¨ নেই" + +#: ../gio/gcancellable.c:310 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "করà§à¦® বাতিল করা হয়েছে" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "অবৈধ অবজেকà§à¦Ÿ, আরমà§à¦­ করা হয়নি" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "পà§à¦°à¦¦à¦¤à§à¦¤ ইনপà§à¦Ÿà§‡à¦° মধà§à¦¯à§‡ অসমà§à¦ªà§‚রà§à¦£ মালà§à¦Ÿà¦¿-বাইটের অনà§à¦•à§à¦°à¦®" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "গনà§à¦¤à¦¬à§à¦¯à¦¸à§à¦¥à¦²à§‡à¦° মধà§à¦¯à§‡ পরà§à¦¯à¦¾à¦ªà§à¦¤ সà§à¦¥à¦¾à¦¨ উপলবà§à¦§ নেই" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "রূপানà§à¦¤à¦° করার জনà§à¦¯ পà§à¦°à¦¦à¦¤à§à¦¤ ইনপà§à¦Ÿà§‡à¦° মধà§à¦¯à§‡ বাইটের অনà§à¦•à§à¦°à¦® সঠিক নয়" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "রূপানà§à¦¤à¦° করà§à¦® সঞà§à¦šà¦¾à¦²à¦¨à¦•ালের উৎপনà§à¦¨ সমসà§à¦¯à¦¾: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "বাতিল করার যোগà§à¦¯ পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• করà§à¦® সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "'%s' অকà§à¦·à¦°à¦®à¦¾à¦²à¦¾ থেকে '%s'-ঠরূপানà§à¦¤à¦° করা যাবে না" + +# sam: রà§à¦ªà¦¾à¦¨à§à¦¤à¦°à¦•ারক +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' থেকে '%s' রূপানà§à¦¤à¦° বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ খোলা যায়নি" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s ধরন" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "অজানা পà§à¦°à¦•ৃতি" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s ফাইলের ধরন" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "à¦à¦‡ অপারেটিং সিসà§à¦Ÿà§‡à¦®à§‡à¦° মধà§à¦¯à§‡ GCredentials সà§à¦¥à¦¾à¦ªà¦¨ করা হয়নি" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "আপনার বà§à¦¯à¦¬à¦¹à§ƒà¦¤ পà§à¦²à§à¦¯à¦¾à¦Ÿà¦«à¦°à§à¦®à§‡à¦° মধà§à¦¯à§‡ কোনো GCredentials সমরà§à¦¥à¦¨ উপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials à¦à¦‡ OS ঠà¦à¦•টি পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ ID বিশিষà§à¦Ÿ নয়" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "à¦à¦‡ OS-ঠশংসাপতà§à¦°à¦—à§à¦²à¦¿ নকল সমà§à¦­à¦¬ নয়" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° সমাপà§à¦¤à¦¿à¦¸à§à¦¥à¦² অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦­à¦¾à¦¬à§‡ শীঘà§à¦° পাওয়া গিয়েছে" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "অসমরà§à¦¥à¦¿à¦¤ কী '%s' '%s' ঠিকানা à¦à¦¨à§à¦Ÿà§à¦°à¦¿à¦¤à§‡" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "ঠিকানা '%s' অবৈধ (path, tmpdir বা abstract কী'র হà§à¦¬à¦¹à§ à¦à¦•টি অাবশà§à¦¯à¦•)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "'%s' ঠিকানা à¦à¦¨à§à¦Ÿà§à¦°à¦¿à¦¤à§‡ অরà§à¦¥à¦¹à§€à¦¨ কী/যà§à¦—à§à¦® সমনà§à¦¬à¦¯à¦¼ " + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "'%s' ঠিকানায় তà§à¦°à§à¦Ÿà¦¿ - পোরà§à¦Ÿ অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿ ভà§à¦² ভাবে গঠিত" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "'%s' ঠিকানায় তà§à¦°à§à¦Ÿà¦¿ - ফà§à¦¯à¦¾à¦®à¦¿à¦²à¦¿ অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿ ভà§à¦² ভাবে গঠিত" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "ঠিকানা উপাদান '%s' ঠকোলোন থাকে না (:)" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "কী/মান যà§à¦—à§à¦® %d, '%s', '%s' ঠিকানা উপাদানে সমতা চিহà§à¦¨ নেই" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"%d, '%s' কী/মান যà§à¦—à§à¦®à§‡ কী বা মান অানà¦à¦¸à¦•েপিঙে তà§à¦°à§à¦Ÿà¦¿, '%s' ঠিকানা উপাদানে" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"'%s' ঠিকানায় তà§à¦°à§à¦Ÿà¦¿ - unix টà§à¦°à§à¦¯à¦¾à¦¨à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ সেট হতে 'path' বা 'abstract' কী'র " +"হà§à¦¬à¦¹à§ à¦à¦•টি অাবশà§à¦¯à¦•" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" +"'%s' ঠিকানায় তà§à¦°à§à¦Ÿà¦¿ - হোসà§à¦Ÿ অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿ হয় অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ বা বাজে ভাবে গঠিত" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "'%s' ঠিকানায় তà§à¦°à§à¦Ÿà¦¿ - পোরà§à¦Ÿ অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ বা ভà§à¦² ভাবে গঠিত" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" +"`%s' ঠিকানায় তà§à¦°à§à¦Ÿà¦¿ - noncefile অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿ হয় অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ বা বাজে ভাবে গঠিত" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "auto-launching ঠতà§à¦°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "'%s' অজানা বা অসমরà§à¦¥à¦¿à¦¤ টà§à¦°à§à¦¯à¦¾à¦¨à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ `%s' ঠিকানার জনà§à¦¯" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "'%s' nonce ফাইল খà§à¦²à¦¤à§‡ তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "'%s' nonce ফাইল থেকে পড়তে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "'%s' nonce ফাইল থেকে পড়তে তà§à¦°à§à¦Ÿà¦¿, পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ 16 বাইট, পাওয়া গেছে %d" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "'%s' nonce ফাইলের বিষয়বসà§à¦¤à§ সà§à¦Ÿà§à¦°à§€à¦®à§‡ লিখতে তà§à¦°à§à¦Ÿà¦¿:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "পà§à¦°à¦¦à¦¤à§à¦¤ ঠিকানা খালি" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "setuid à¦à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ à¦à¦•টি বারà§à¦¤à¦¾ বাস পà§à¦°à¦¯à¦¼à§‹à¦— করতে পারে না" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "à¦à¦•টি মেশিন-অাইডি ছাড়া à¦à¦•টি বারà§à¦¤à¦¾ বাস পà§à¦°à¦¯à¦¼à§‹à¦— করতে পারা যায় না: " + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "'%s' কমà§à¦¯à¦¾à¦¨à§à¦¡ লাইন পà§à¦°à¦¯à¦¼à§‹à¦— করতে তà§à¦°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(à¦à¦‡ উইনà§à¦¡à§‹ বনà§à¦§ করতে যেকোনো অকà§à¦·à¦° লিখà§à¦¨)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "সেশন dbus চলছে না, à¦à¦¬à¦‚ autolaunch বà§à¦¯à¦°à§à¦¥ হয়েছে" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "সেশন বাস ঠিকানা নিরà§à¦§à¦¾à¦°à¦£ করা যায় না (à¦à¦‡ OS à¦à¦° জনà§à¦¯ বাসà§à¦¤à¦¬à¦¾à¦¯à¦¼à¦¿à¦¤ নয়)" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"DBUS_STARTER_BUS_TYPE à¦à¦¨à¦­à¦¾à¦¯à¦¼à¦°à¦¨à¦®à§‡à¦¨à§à¦Ÿ বিভেদতা থেকে বাস ঠিকানা নিরà§à¦§à¦¾à¦°à¦£ করা যায় " +"না " +"- অজানা মান '%s'" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"বাস ঠিকানা নিরà§à¦§à¦¾à¦°à¦£ করা যায় না কারণ DBUS_STARTER_BUS_TYPE à¦à¦¨à¦­à¦¾à¦¯à¦¼à¦°à¦¨à¦®à§‡à¦¨à§à¦Ÿ " +"ভà§à¦¯à¦¾à¦°à¦¿à¦¯à¦¼à§‡à¦¬à¦² সেট করা হয়নি" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "অজানা bus ধরন %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ বিষয়বসà§à¦¤à§à¦° অপà§à¦°à¦¤à§à¦²à¦¤à¦¾ à¦à¦•টি লাইন পড়ার চেষà§à¦Ÿà¦¾ করছে" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ বিষয়বসà§à¦¤à§à¦° অপà§à¦°à¦¤à§à¦²à¦¤à¦¾ (নিরাপদে) à¦à¦•টি লাইন পড়ার চেষà§à¦Ÿà¦¾ করছে" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"সকল উপলবà§à¦§ পà§à¦°à¦®à¦¾à¦£à§€à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ বà§à¦¯à¦¬à¦¹à§ƒà¦¤ (চেষà§à¦Ÿà¦¾ করা হয়েছে: %s) (উপলবà§à¦§: %s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" +"à¦à¦° মাধà§à¦¯à¦®à§‡ বাতিল করা হয়েছে GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "'%s' ডিরেকà§à¦Ÿà¦°à¦¿à¦° জনà§à¦¯ তথà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করার সময়ে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"'%s' ডিরেকà§à¦Ÿà¦°à¦¿à¦¤à§‡ অনà§à¦®à¦¤à¦¿ বাজে ভাবে গঠিত। পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ মোড 0700, পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে 0%" +"o" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "'%s' ডিরেকà§à¦Ÿà¦°à¦¿ তৈরি করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "পড়ার জনà§à¦¯ keyring '%s' খà§à¦²à¦¤à§‡ তà§à¦°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "লাইন %d keyring à¦à¦° '%s' ঠ'%s' বিষয়বসà§à¦¤à§ সমেত, বাজে ভাবে গঠিত" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"%d লাইনের পà§à¦°à¦¥à¦® টোকেন keyring à¦à¦° '%s' ঠ'%s' বিষয়বসà§à¦¤à§ সমেত, বাজে ভাবে গঠিত" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"keyring à¦à¦° %d লাইনের দà§à¦¬à¦¿à¦¤à§€à¦¯à¦¼ টোকেন '%s' ঠ'%s' বিষয়বসà§à¦¤à§ সমেত, বাজে ভাবে " +"গঠিত" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "%d অাইডি সমেত কà§à¦•ি পাওয়া যায়নি, '%s' keyring à¦" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "'%s' সà§à¦Ÿà§‡à¦² লক ফাইল মà§à¦›à¦¤à§‡ তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "'%s' লক ফাইল তৈরি করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "'%s' লক ফাইল বনà§à¦§ (অানলিঙà§à¦•ড) তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "'%s' লক ফাইল অান-লিঙà§à¦• করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "লেখার জনà§à¦¯ keyring '%s' খà§à¦²à¦¤à§‡ তà§à¦°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(তাছাড়া, '%s' à¦à¦° জনà§à¦¯ লক রিলিজ করাও বà§à¦¯à¦°à§à¦¥ হয়েছে: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "সংযোগটি অাবদà§à¦§" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "সময় সমাপà§à¦¤ হয়ে গেছে" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"à¦à¦•টি কà§à¦²à¦¾à¦¯à¦¼à§‡à¦¨à§à¦Ÿ-সাইড সংযোগ গঠনের সময়ে অসমরà§à¦¥à¦¿à¦¤ ফà§à¦²à§à¦¯à¦¾à¦—ের সমà§à¦®à§à¦–ীন হয়েছে" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"%s পাথে অবজেকà§à¦Ÿà§‡ 'org.freedesktop.DBus.Properties' ধরনের কোনো ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ নেই" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "'%s' ধরনের কোনো বিশিষà§à¦Ÿà¦¤à¦¾ নেই" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "বিশিষà§à¦Ÿà¦¤à¦¾ '%s' পঠনযোগà§à¦¯ নয়" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "'%s' বিশিষà§à¦Ÿà¦¤à¦¾ লিখনযোগà§à¦¯ নয়" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"'%s' বিশিষà§à¦Ÿà¦¤à¦¾ সেট করতে তà§à¦°à§à¦Ÿà¦¿: পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ ধরন '%s' তবে '%s' পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "'%s' ধরনের কোনো ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ নেই" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "ধরনের কোনো ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ নেই" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "%s পাথে অবজেকà§à¦Ÿà§‡ '%s' ধরনের কোনো ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ নেই" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "'%s' ধরনের কোনো পদà§à¦§à¦¤à¦¿ নেই" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "বারà§à¦¤à¦¾à¦° ধরন, '%s', '%s' পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ ধরনের সংগে মিলছে না" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "%s ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸à§‡à¦° জনà§à¦¯ %s ঠইতিমধà§à¦¯à§‡à¦‡ à¦à¦•টি অবজেকà§à¦Ÿ রপà§à¦¤à¦¾à¦¨à¦¿ করা হয়েছে" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "পদà§à¦§à¦¤à¦¿ '%s' '%s' ধরন পাঠিয়েছে, কিনà§à¦¤à§ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ '%s'" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "পদà§à¦§à¦¤à¦¿ '%s' '%s' ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸à§‡ '%s' সà§à¦¬à¦¾à¦•à§à¦·à¦° সমেত বিদà§à¦¯à¦®à¦¾à¦¨ নয়" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "%s à¦à¦° জনà§à¦¯ ইতিমধà§à¦¯à§‡à¦‡ à¦à¦•টি সাব-টà§à¦°à§€ রপà§à¦¤à¦¾à¦¨à¦¿ করা হয়েছে" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "ধরন অবৈধ" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL বারà§à¦¤à¦¾: PATH বা MEMBER হেডার ফিলà§à¦¡ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN বারà§à¦¤à¦¾: REPLY_SERIAL হেডার ফিলà§à¦¡ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "তà§à¦°à§à¦Ÿà¦¿ বারà§à¦¤à¦¾: REPLY_SERIAL বা ERROR_NAME হেডার ফিলà§à¦¡ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL বারà§à¦¤à¦¾: PATH, INTERFACE বা MEMBER হেডার ফিলà§à¦¡ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL বারà§à¦¤à¦¾: PATH হেডার ফিলà§à¦¡ সংরকà§à¦·à¦¿à¦¤ মান /org/freedesktop/DBus/Local " +"বà§à¦¯à¦¬à¦¹à¦¾à¦° " +"করছে" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL বারà§à¦¤à¦¾: INTERFACE হেডার ফিলà§à¦¡ সংরকà§à¦·à¦¿à¦¤ মান org.freedesktop.DBus.Local " +"বà§à¦¯à¦¬à¦¹à¦¾à¦° করছে" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu বাইট পড়তে চেয়েছে কিনà§à¦¤à§ মাতà§à¦° %lu পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে" +msgstr[1] "%lu বাইট পড়তে চেয়েছে কিনà§à¦¤à§ মাতà§à¦° %lu পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ NUL বাইট, '%s' সà§à¦Ÿà§à¦°à§€à¦™à§‡à¦° পরে, তবে %d বাইট পাওয়া গেছে" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"বৈধ UTF-8 সà§à¦Ÿà§à¦°à§€à¦‚ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ কিনà§à¦¤à§ %d বাইট অফসেটে অবৈধ বাইট পাওয়া গেছে " +"(সà§à¦Ÿà§à¦°à§€à¦‚ à¦à¦° " +"দৈরà§à¦˜à§à¦¯ হল %d)। à¦à¦‡ পয়েনà§à¦Ÿ পরà§à¦¯à¦¨à§à¦¤ বৈধ UTF-8 সà§à¦Ÿà§à¦°à§€à¦‚ হল '%s'" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "পারà§à¦œà¦¡ মান '%s' à¦à¦•টি বৈধ D-Bus অবজেকà§à¦Ÿ পাথ নয়" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "পারà§à¦œà¦¡ মান '%s' à¦à¦•টি বৈধ D-Bus সà§à¦¬à¦¾à¦•à§à¦·à¦° নয়" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"সমà§à¦®à§à¦–ীন হওয়া দৈরà§à¦˜à§à¦¯à§‡à¦° সজà§à¦œà¦¾ হল %u বাইট। সরà§à¦¬à¦¾à¦§à¦¿à¦• দৈরà§à¦˜à§à¦¯ হল 2<<26 বাইট (64 " +"MiB)।" +msgstr[1] "" +"সমà§à¦®à§à¦–ীন হওয়া দৈরà§à¦˜à§à¦¯à§‡à¦° সজà§à¦œà¦¾ হল %u বাইট। সরà§à¦¬à¦¾à¦§à¦¿à¦• দৈরà§à¦˜à§à¦¯ হল 2<<26 বাইট (64 " +"MiB)।" + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"সমà§à¦®à§à¦–ীন হওয়া ধরনের সজà§à¦œà¦¾ 'a%c', %u বাইটের গà§à¦¨à¦¿à¦¤à¦•ের হিসাবে দৈরà§à¦˜à§à¦¯ " +"পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, কিনà§à¦¤à§ " +"দৈরà§à¦˜à§à¦¯ হল %u বাইট" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "ভà§à¦¯à¦¾à¦°à¦¿à¦¯à¦¼à§‡à¦¨à§à¦Ÿà§‡à¦° জনà§à¦¯ পারà§à¦œà¦¡ মান '%s' à¦à¦•টি বৈধ D-Bus সà§à¦¬à¦¾à¦•à§à¦·à¦° নয়" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"D-Bus ওয়à§à¦¯à¦¾à¦° ফরà§à¦®à§à¦¯à¦¾à¦Ÿ থেকে ধরন সà§à¦Ÿà§à¦°à§€à¦‚ '%s' সমেত GVariant ডি-সিরিয়ালাইজিং " +"করতে তà§à¦°à§à¦Ÿà¦¿" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"অবৈধ endianness মান। পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ 0x6c ('l') বা 0x42 ('B') তবে পà§à¦°à¦¾à¦ªà§à¦¤ মান 0x%" +"02x" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "অবৈধ মেজর পà§à¦°à§‹à¦Ÿà§‹à¦•ল সংসà§à¦•রণ। পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ 1 তবে পাওয়া গেছে %d" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "'%s' সà§à¦¬à¦¾à¦•à§à¦·à¦° সমেত সà§à¦¬à¦¾à¦•à§à¦·à¦° হেডার পাওয়া গেছে তবে বারà§à¦¤à¦¾ বডি খালি" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "পারà§à¦œà¦¡ মান '%s' à¦à¦•টি বৈধ D-Bus সà§à¦¬à¦¾à¦•à§à¦·à¦° নয় (বডির জনà§à¦¯)" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "বারà§à¦¤à¦¾à¦¯à¦¼ কোনো সà§à¦¬à¦¾à¦•à§à¦·à¦° হেডার নেই তবে বারà§à¦¤à¦¾ বডি হল %u বাইট" +msgstr[1] "বারà§à¦¤à¦¾à¦¯à¦¼ কোনো সà§à¦¬à¦¾à¦•à§à¦·à¦° হেডার নেই তবে বারà§à¦¤à¦¾ বডি হল %u বাইট" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "বারà§à¦¤à¦¾ ডিসিরিয়ালাইজ করা যায় না: " + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"D-Bus ওয়à§à¦¯à¦¾à¦° ফরà§à¦®à§à¦¯à¦¾à¦Ÿà§‡ ধরন সà§à¦Ÿà§à¦°à§€à¦‚ '%s' সমেত GVariant সিরিয়ালাইজিং করতে " +"তà§à¦°à§à¦Ÿà¦¿" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"বারà§à¦¤à¦¾à¦¯à¦¼ %d ফাইল ডেসকà§à¦°à¦¿à¦ªà¦Ÿà¦° অাছে তবে হেডার ফিলà§à¦¡ %d ফাইল ডেসকà§à¦°à¦¿à¦ªà¦Ÿà¦° সূচিত করে" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "বারà§à¦¤à¦¾ সিরিয়ালাইজ করা যায় না: " + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "বারà§à¦¤à¦¾ বডিতে '%s' সà§à¦¬à¦¾à¦•à§à¦·à¦° অাছে তবে কোনো সà§à¦¬à¦¾à¦•à§à¦·à¦° হেডার নেই" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "বারà§à¦¤à¦¾ বডিতে '%s' ধরন সà§à¦¬à¦¾à¦•à§à¦·à¦° অাছে তবে হেডার ফিলà§à¦¡à§‡à¦° সà§à¦¬à¦¾à¦•à§à¦·à¦° হল `%s'" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "বারà§à¦¤à¦¾ বডি খালি কিনà§à¦¤à§ হেডার ফিলà§à¦¡à§‡à¦° সà§à¦¬à¦¾à¦•à§à¦·à¦° হল '(%s)'" + +#: ../gio/gdbusmessage.c:3282 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' ধরনের বডি সমেত তà§à¦°à§à¦Ÿà¦¿ ফেরত পাঠানো হয়েছে" + +#: ../gio/gdbusmessage.c:3290 +msgid "Error return with empty body" +msgstr "খালি বডির সংগে ফেরত তà§à¦°à§à¦Ÿà¦¿" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "হারà§à¦¡à¦“য়à§à¦¯à¦¾à¦° পà§à¦°à§‹à¦«à¦¾à¦‡à¦² পেতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "/var/lib/dbus/machine-id বা /etc/machine-id লোড করতে বà§à¦¯à¦°à§à¦¥: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s à¦à¦° জনà§à¦¯ StartServiceByName কল করতে তà§à¦°à§à¦Ÿà¦¿: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ পà§à¦°à¦¤à§à¦¯à§à¦¤à§à¦¤à¦° %d StartServiceByName(\"%s\") পদà§à¦§à¦¤à¦¿ থেকে" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"পদà§à¦§à¦¤à¦¿ পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করা যায় না; পà§à¦°à¦•à§à¦¸à¦¿ হল মালিক ছাড়া অতিপরিচিত নামের জনà§à¦¯ " +"à¦à¦¬à¦‚ " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START ফà§à¦²à§à¦¯à¦¾à¦— সমেত পà§à¦°à¦•à§à¦¸à¦¿ গঠন করা হয়েছে" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "অà§à¦¯à¦¾à¦¬à¦¸à§à¦Ÿà§à¦°à¦¾à¦•à§à¦Ÿ নাম সà§à¦ªà§‡à¦¸ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "à¦à¦•টি সারà§à¦­à¦¾à¦° তৈরি করার সময়ে nonce ফাইল উলà§à¦²à§‡à¦– করা যায় না" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' ঠnonce ফাইল লিখতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "সà§à¦Ÿà§à¦°à§€à¦‚ '%s' à¦à¦•টি বৈধ D-Bus GUID নয়" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "'%s' অসমরà§à¦¥à¦¿à¦¤ টà§à¦°à§à¦¯à¦¾à¦¨à§à¦¸à¦ªà§‹à¦°à§à¦Ÿà§‡ শোনা যায় না" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"কমà§à¦¯à¦¾à¦¨à§à¦¡:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"পà§à¦°à¦¤à¦¿à¦Ÿà¦¿ কমà§à¦¯à¦¾à¦¨à§à¦¡à§‡ সহায়তা পেতে \"%s COMMAND --help\" বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "XML ইনà§à¦Ÿà§à¦°à§‹à¦¸à§à¦ªà§‡à¦•শন পারà§à¦œ করতে তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "সিসà§à¦Ÿà§‡à¦® বাসে সংযোগ করà§à¦¨" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "সেশন বাসে সংযোগ করà§à¦¨" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "পà§à¦°à¦¦à¦¤à§à¦¤ D-Bus ঠিকানায় সংযোগ করà§à¦¨" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "সংযোগ à¦à¦¨à§à¦¡à¦ªà¦¯à¦¼à§‡à¦¨à§à¦Ÿ বিকলà§à¦ª:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "সংযোগ à¦à¦¨à§à¦¡à¦ªà¦¯à¦¼à§‡à¦¨à§à¦Ÿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করার বিকলà§à¦ª" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "কোনো সংযোগ à¦à¦¨à§à¦¡à¦ªà¦¯à¦¼à§‡à¦¨à§à¦Ÿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা হয়নি" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "à¦à¦•াধিক সংযোগ à¦à¦¨à§à¦¡à¦ªà¦¯à¦¼à§‡à¦¨à§à¦Ÿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা হয়েছে" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "সরà§à¦¤à¦•তা: ইনà§à¦Ÿà§à¦°à§‹à¦¸à§à¦ªà§‡à¦•শন ডেটা অনà§à¦¸à¦¾à¦°à§‡, ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ '%s' à¦à¦° অসà§à¦¤à¦¿à¦¤à§à¦¬ নেই\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"সরà§à¦¤à¦•তা: ইনà§à¦Ÿà§à¦°à§‹à¦¸à§à¦ªà§‡à¦•শন ডেটা অনà§à¦¸à¦¾à¦°à§‡, পদà§à¦§à¦¤à¦¿ '%s' à¦à¦° '%s' ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸à§‡ অসà§à¦¤à¦¿à¦¤à§à¦¬ " +"নেই\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "সংকেতের বৈকলà§à¦ªà¦¿à¦• গনà§à¦¤à¦¬à§à¦¯ (অদà§à¦¬à¦¿à¦¤à§€à¦¯à¦¼ নাম)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "সংকেত পাঠানোর অবজেকà§à¦Ÿ পাথ" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "সংকেত à¦à¦¬à¦‚ ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ নাম" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "à¦à¦•টি সংকেত পাঠান।" + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "সংযোগে তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: অবজেকà§à¦Ÿ পাথ উলà§à¦²à§‡à¦– করা হয়নি।\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: %s à¦à¦•টি বৈধ অবজেকà§à¦Ÿ পাথ নয়\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: সংকেত নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা হয়নি।\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: সংকেত অবশà§à¦¯à¦‡ fully-qualified নাম হত হবে।\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: %s à¦à¦•টি বৈধ ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ নাম নয়\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: %s à¦à¦•টি বৈধ সদসà§à¦¯ নাম নয়\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: %s à¦à¦•টি বৈধ অদà§à¦¬à¦¿à¦¤à§€à¦¯à¦¼ বাস নাম নয়।\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%d পà§à¦¯à¦¾à¦°à¦¾à¦®à¦¿à¦Ÿà¦¾à¦° পারà§à¦œà¦¿à¦™à§‡ তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "সংযোগ ফà§à¦²à§à¦¯à¦¾à¦¶ করতে তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "পদà§à¦§à¦¤à¦¿ নিয়ে অাসার গনà§à¦¤à¦¬à§à¦¯ নাম" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "পদà§à¦§à¦¤à¦¿ নিয়ে অাসার অবজেকà§à¦Ÿ পাথ" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "পদà§à¦§à¦¤à¦¿ à¦à¦¬à¦‚ ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ নাম" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "সময়সমাপà§à¦¤à¦¿, সেকেনà§à¦¡à§‡" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "à¦à¦•টি রিমোট অবজেকà§à¦Ÿà§‡ পদà§à¦§à¦¤à¦¿ নিয়ে অাসà§à¦¨à¥¤" + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: গনà§à¦¤à¦¬à§à¦¯ উলà§à¦²à§‡à¦– করা হয়নি\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: অবজেকà§à¦Ÿ পাথ উলà§à¦²à§‡à¦– করা হয়নি\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: পদà§à¦§à¦¤à¦¿ নাম উলà§à¦²à§‡à¦– করা হয়নি\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "তà§à¦°à§à¦Ÿà¦¿: পদà§à¦§à¦¤à¦¿ নাম '%s' অবৈধ\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "%d পà§à¦¯à¦¾à¦°à¦¾à¦®à¦¿à¦Ÿà¦¾à¦° পারà§à¦œ করতে তà§à¦°à§à¦Ÿà¦¿, '%s' ধরনের: %s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "ইনà§à¦Ÿà§à¦°à§‹à¦¸à§à¦ªà§‡à¦•à§à¦Ÿ করার গনà§à¦¤à¦¬à§à¦¯ নাম" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "ইনà§à¦Ÿà§à¦°à§‹à¦¸à§à¦ªà§‡à¦•à§à¦Ÿ করার অবজেকà§à¦Ÿ পাথ" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "পà§à¦°à¦¿à¦¨à§à¦Ÿ XML" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "ইনà§à¦Ÿà§à¦°à§‹à¦¸à§à¦ªà§‡à¦•à§à¦Ÿ চিলডà§à¦°à§‡à¦¨" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° বিশিষà§à¦Ÿà¦¤à¦¾ পà§à¦°à¦¿à¦¨à§à¦Ÿ করà§à¦¨" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "à¦à¦•টি রিমোট অবজেকà§à¦Ÿ ইনà§à¦Ÿà§à¦°à§‹à¦¸à§à¦ªà§‡à¦•à§à¦Ÿ করà§à¦¨à¥¤" + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "মনিটর করার গনà§à¦¤à¦¬à§à¦¯ নাম" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "মনিটর করার অবজেকà§à¦Ÿ পাথ" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "à¦à¦•টি রিমোট অবজেকà§à¦Ÿ মনিটর করà§à¦¨à¥¤" + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4525 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "নামবিহীন" + +#: ../gio/gdesktopappinfo.c:2410 +msgid "Desktop file didn't specify Exec field" +msgstr "ডেসà§à¦•টপ ফাইলের মধà§à¦¯à§‡ Exec ফিলà§à¦¡" + +#: ../gio/gdesktopappinfo.c:2695 +msgid "Unable to find terminal required for application" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনের জনà§à¦¯ আবশà§à¦¯à¦• টারà§à¦®à¦¿à¦¨à¦¾à¦² পাওয়া যায়নি" + +#: ../gio/gdesktopappinfo.c:3116 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "উইজার অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনের কনফিগারেশন ফোলà§à¦¡à¦¾à¦° %s নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gdesktopappinfo.c:3120 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "ইউজার MIME কনফিগারেশন ফোলà§à¦¡à¦¾à¦° %s নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gdesktopappinfo.c:3360 ../gio/gdesktopappinfo.c:3384 +msgid "Application information lacks an identifier" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন তথà§à¦¯à§‡ সনাকà§à¦¤à¦•ারীর অভাব রয়েছে" + +#: ../gio/gdesktopappinfo.c:3617 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "ইউজার ডেসà§à¦•টপ ফাইল %s নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gdesktopappinfo.c:3751 +#, c-format +msgid "Custom definition for %s" +msgstr "%s-র জনà§à¦¯ সà§à¦¬à¦¨à¦¿à¦°à§à¦§à¦¾à¦°à¦¤ বà§à¦¯à¦¾à¦–à§à¦¯à¦¾" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "ডà§à¦°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à¦°à¦¾ ইজেকà§à¦Ÿ করà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ হয় না" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "ডà§à¦°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à¦°à¦¾ eject অথবা eject_with_operation কারà§à¦¯à¦•রী করা হয় না" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "ডà§à¦°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à¦°à¦¾ মিডিয়া পোল করার বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ পà§à¦°à§Ÿà§‹à¦— করা হয় না" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "ডà§à¦°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à¦°à¦¾ পà§à¦°à¦¾à¦°à¦®à§à¦­à§‡à¦° করà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ হয় না" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "ডà§à¦°à¦¾à¦‡à¦­ দà§à¦¬à¦¾à¦°à¦¾ বনà§à¦§ করার করà§à¦® সঞà§à¦šà¦¾à¦²à¦¿à¦¤ হয় না" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS সহায়তা উপলবà§à¦§ নয়" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem à¦à¦¨à¦•োডিং-র %d সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem à¦à¦¨à¦•োডিং-র মধà§à¦¯à§‡ উপসà§à¦¥à¦¿à¦¤ কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ টোকেনের সংখà§à¦¯à¦¾ (%d)" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon à¦à¦¨à¦•োডিং-র %d সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon à¦à¦¨à¦•োডিং-র মধà§à¦¯à§‡ উপসà§à¦¥à¦¿à¦¤ কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ টোকেনের সংখà§à¦¯à¦¾ (%d)" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon-র জনà§à¦¯ à¦à¦•টি GEmblem পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../gio/gfile.c:956 ../gio/gfile.c:1194 ../gio/gfile.c:1332 +#: ../gio/gfile.c:1570 ../gio/gfile.c:1625 ../gio/gfile.c:1683 +#: ../gio/gfile.c:1767 ../gio/gfile.c:1824 ../gio/gfile.c:1888 +#: ../gio/gfile.c:1943 ../gio/gfile.c:3591 ../gio/gfile.c:3646 +#: ../gio/gfile.c:3853 ../gio/gfile.c:3895 ../gio/gfile.c:4358 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7748 ../gio/gfile.c:7838 ../gio/gfile.c:7922 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "করà§à¦® সমরà§à¦¥à¦¿à¦¤ হয় না" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1455 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "ধারণকারী মাউনà§à¦Ÿ উপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../gio/gfile.c:2502 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿à¦° উপরে কপি করা যাবে না" + +#: ../gio/gfile.c:2562 +msgid "Can't copy directory over directory" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿à¦° উপর ডিরেকà§à¦Ÿà¦°à¦¿ কপি করা যায়নি" + +#: ../gio/gfile.c:2570 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "উদà§à¦¦à¦¿à¦·à§à¦Ÿ ফাইল উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../gio/gfile.c:2589 +msgid "Can't recursively copy directory" +msgstr "রিকারà§à¦¸à¦¿à¦­ ভাবে ডিরেকà§à¦Ÿà¦°à¦¿ কপি করা যাবে না" + +#: ../gio/gfile.c:2871 +msgid "Splice not supported" +msgstr "à¦à¦•তà§à¦°à¦¿à¦•রণ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gfile.c:2875 +#, c-format +msgid "Error splicing file: %s" +msgstr "ফাইল à¦à¦•তà§à¦°à¦¿à¦•রণে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gfile.c:3006 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "মাউনà§à¦Ÿà§‡à¦° মধà§à¦¯à§‡ অনà§à¦²à¦¿à¦ªà¦¿ করা সমরà§à¦¥à¦¿à¦¤ নয় (reflink/clone)" + +#: ../gio/gfile.c:3010 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "অনà§à¦²à¦¿à¦ªà¦¿ (reflink/clone) সমরà§à¦¥à¦¿à¦¤ নয় বা অবৈধ" + +#: ../gio/gfile.c:3015 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "অনà§à¦²à¦¿à¦ªà¦¿ (reflink/clone) সমরà§à¦¥à¦¿à¦¤ নয় বা কাজ করছে না" + +#: ../gio/gfile.c:3078 +msgid "Can't copy special file" +msgstr "বিশেষ ফাইল কপি করা যাবে না" + +#: ../gio/gfile.c:3843 +msgid "Invalid symlink value given" +msgstr "অবৈধ সিম-লিঙà§à¦• মান উপলবà§à¦§ করা হয়েছে" + +#: ../gio/gfile.c:4004 +msgid "Trash not supported" +msgstr "আবরà§à¦œà¦¨à¦¾ সমরà§à¦¥à¦¿à¦¤ হয় না" + +#: ../gio/gfile.c:4116 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ফাইলের নামের মধà§à¦¯à§‡ '%c' বà§à¦¯à¦¬à¦¹à¦¾à¦° করা যাবে না" + +#: ../gio/gfile.c:6540 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "ভলিউম দà§à¦¬à¦¾à¦°à¦¾ mount পà§à¦°à§Ÿà§‹à¦— করা হয় না" + +#: ../gio/gfile.c:6649 +msgid "No application is registered as handling this file" +msgstr "চিহà§à¦¨à¦¿à¦¤ ফাইল বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾à¦° উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ কোনো অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন নিবনà§à¦§à¦¿à¦¤ হয়নি" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator বনà§à¦§" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ফাইল enumerator-র মধà§à¦¯à§‡ অসমাপà§à¦¤ করà§à¦® উপসà§à¦¥à¦¿à¦¤" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ফাইল enumerator-র বনà§à¦§" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon à¦à¦¨à¦•োডিং-র %d সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon-র জনà§à¦¯ কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ ইনপà§à¦Ÿ তথà§à¦¯ উপসà§à¦¥à¦¿à¦¤" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ query_info সমরà§à¦¥à¦¿à¦¤ হয় না" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ Seek সমরà§à¦¥à¦¿à¦¤ হয় না" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ইনপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ টà§à¦°à¦¾à¦¨à¦•েট অরà§à¦¥à¦¾à§Ž ছাà¦à¦Ÿà¦¾à¦‡à§Ÿà§‡à¦° অনà§à¦®à¦¤à¦¿ নেই" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ টà§à¦°à¦¾à¦¨à¦•েট অরà§à¦¥à¦¾à§Ž ছাà¦à¦Ÿà¦¾à¦‡à§Ÿà§‡à¦° সমরà§à¦¥à¦¨ নেই" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "টোকেনের সংখà§à¦¯à¦¾ সঠিক নয় (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "%s কà§à¦²à¦¾à¦¸à§‡à¦° নামের জনà§à¦¯ কোনো ধরন নিরà§à¦§à¦¾à¦°à¦¿à¦¤ হয়নি" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s ধরন দà§à¦¬à¦¾à¦°à¦¾ GIcon ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸ বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "%s ধরন কোনো শà§à¦°à§‡à¦£à§€à¦° মধà§à¦¯à§‡ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ নয়" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "সংসà§à¦•রণ সংখà§à¦¯à¦¾ সটিকরূপে গঠিত হয়নি: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s ধরন দà§à¦¬à¦¾à¦°à¦¾ GIcon ইনà§à¦Ÿà¦¾à¦°à¦«à§‡à¦¸à§‡à¦° মধà§à¦¯à§‡ from_tokens() বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "অাইকন à¦à¦¨à¦•োডিঙের সরবরাহ করা সংসà§à¦•রণ পরিচালনা করা যায় না" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "কোনো ঠিকানা উলà§à¦²à§‡à¦– করা হয়নি" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "দৈরà§à¦˜à§à¦¯ %u ঠিকানার কà§à¦·à§‡à¦¤à§à¦°à§‡ অতà§à¦¯à¦¨à§à¦¤ দৈরà§à¦˜à§à¦¯" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ঠিকানায় পà§à¦°à§‡à¦«à¦¿à¦•à§à¦¸ দৈরà§à¦˜à§à¦¯ ছাড়িয়ে বিট সেট করা অাছে" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "IP ঠিকানা মাসà§à¦• হিসাবে '%s' পারà§à¦œ করা যায়নি" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "সকেটের ঠিকানার জনà§à¦¯ পরà§à¦¯à¦¾à¦ªà§à¦¤ সà§à¦¥à¦¾à¦¨ উপলবà§à¦§ নেই" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "সকেটের ঠিকানা সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "ইনপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ read বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1027 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1474 +msgid "Stream has outstanding operation" +msgstr "সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ অসমাপà§à¦¤ করà§à¦® উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> সà§à¦¬à¦¤à§à¦¬à¦¾à¦Ÿà¦¿ <%s>-র নীচে বà§à¦¯à¦¬à¦¹à¦¾à¦° করা যাবে না" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> সà§à¦¬à¦¤à§à¦¬à¦¾à¦Ÿà¦¿ সরà§à¦¬à§‹à¦šà§à¦š সà§à¦¤à¦°à§‡ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা যাবে না" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "রিসোরà§à¦¸à§‡ ফাইল %s à¦à¦•াধিক বার উপসà§à¦¥à¦¿à¦¤ হয়" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "যেকোনো সোরà§à¦¸ ডিরেকà§à¦Ÿà¦°à¦¿à¦¤à§‡ '%s' চিহà§à¦¨à¦¿à¦¤ করা যায়নি" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "বরà§à¦¤à¦®à¦¾à¦¨ ডিরেকà§à¦Ÿà¦°à¦¿à¦¤à§‡ '%s' চিহà§à¦¨à¦¿à¦¤ করা যায়নি" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "অজানা পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ বিকলà§à¦ª \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "অসà§à¦¥à¦¾à¦¯à¦¼à§€ ফাইল তৈরি করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s ফাইল পড়তে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "%s ফাইল সংকà§à¦šà¦¿à¦¤ করতে তà§à¦°à§à¦Ÿà¦¿" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s>-র অধীন টেকà§à¦¸à¦Ÿ উপসà§à¦¥à¦¿à¦¤ না হতে পারে" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "অাউটপà§à¦Ÿ ফাইলের নাম" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"যে ডিরেকà§à¦Ÿà¦°à¦¿à¦—à§à¦²à¦¿ থেকে ফাইলগà§à¦²à¦¿ পড়া হবে (ডিফলà§à¦Ÿ থেকে বরà§à¦¤à¦®à¦¾à¦¨ ডিরেকà§à¦Ÿà¦°à¦¿)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"টারà§à¦—েট ফাইল-নাম à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ দà§à¦¬à¦¾à¦°à¦¾ নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ ফরà§à¦®à§à¦¯à¦¾à¦Ÿà§‡ অাউটপà§à¦Ÿ পà§à¦°à¦¸à§à¦¤à§à¦¤ করà§à¦¨" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "সোরà§à¦¸ হেডার পà§à¦°à¦¸à§à¦¤à§à¦¤ করà§à¦¨" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "অাপনার কোডে রিসোরà§à¦¸ ফাইলে লিঙà§à¦• করতে বà§à¦¯à¦¬à¦¹à§ƒà¦¤ সোরà§à¦¸-কোড পà§à¦°à¦¸à§à¦¤à§à¦¤ করà§à¦¨" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "নিরà§à¦­à¦°à¦¶à§€à¦²à¦¤à¦¾ তালিকা তৈরি করà§à¦¨" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "সà§à¦¬à¦¯à¦¼à¦‚কà§à¦°à¦¿à¦¯à¦¼ ভাবে রিসোরà§à¦¸ তৈরি à¦à¦¬à¦‚ নিবনà§à¦§à¦¨ করবেন না" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "ফাংশন রপà§à¦¤à¦¾à¦¨à¦¿ করবেন না; তাদের G_GNUC_INTERNAL ঘোষণা করà§à¦¨" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "পà§à¦°à¦¸à§à¦¤à§à¦¤ করা সোরà§à¦¸ কোডের কà§à¦·à§‡à¦¤à§à¦°à§‡ C সনাকà§à¦¤à¦•ারীর নাম বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হয়েছে" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"রিসোরà§à¦¸ বিশেষীকরণ à¦à¦•টি রিসোরà§à¦¸ ফাইলে সমনà§à¦¬à¦¿à¦¤ করà§à¦¨à¥¤\n" +"রিসোরà§à¦¸ বিশেষীকরণ ফাইলের à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ হল extension .gresource.xml,\n" +"à¦à¦¬à¦‚ রিসোরà§à¦¸ ফাইলের à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ হল called .gresource।" + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "অাপনাকে à¦à¦•টি হà§à¦¬à¦¹à§ à¦à¦•টি ফাইল নাম দেওয়া উচিত\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "নামের জায়গা খালি রাখা যাবে না" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "অবৈধ নাম '%s': নাম অবশà§à¦¯à¦‡ ছোট হাতের অকà§à¦·à¦° দিয়ে শà§à¦°à§ হতে হবে" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"অবৈধ নাম '%s': অবৈধ অকà§à¦·à¦° '%c'; শà§à¦§à§à¦®à¦¾à¦¤à§à¦° ছোট হাতের অকà§à¦·à¦°, সংখà§à¦¯à¦¾ à¦à¦¬à¦‚ হাইফেন " +"('-') " +"অনà§à¦®à§‹à¦¦à¦¿à¦¤à¥¤" + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "অবৈধ নাম '%s': পরপর দà§à¦‡à¦Ÿà¦¿ হাইফেন ('--') অনà§à¦®à§‹à¦¦à¦¿à¦¤ নয়।" + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "অবৈধ নাম '%s': শেষ অকà§à¦·à¦° à¦à¦•টি হাইফেন হতে পারে না ('-')।" + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "অবৈধ নাম '%s': সরà§à¦¬à¦¾à¦§à¦¿à¦• দৈরà§à¦˜à§à¦¯ হল 1024" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " ইতিমধà§à¦¯à§‡à¦‡ উলà§à¦²à§‡à¦– করা হয়েছে" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "'list-of' সà§à¦•িমে কী যোগ করা যায় না" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " ইতিমধà§à¦¯à§‡à¦‡ উলà§à¦²à§‡à¦– করা হয়েছে" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" পà§à¦°à¦¤à¦¿à¦«à¦²à¦¿à¦¤ করে à¦; " +"বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨, মান সংশোধন করতে" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"'type' à¦à¦° হà§à¦¬à¦¹à§ à¦à¦•টি, 'enum' বা 'flags' অবশà§à¦¯à¦‡ à¦à¦° à¦à¦•টি অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿ " +"হিসাবে " +"উলà§à¦²à§‡à¦– করতে হবে" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (à¦à¦–নও) নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা হয়নি।" + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "অবৈধ GVariant ধরন সà§à¦Ÿà§à¦°à§€à¦‚ '%s'" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " পà§à¦°à¦¦à¦¤à§à¦¤ কিনà§à¦¤à§ সà§à¦•িম কিছà§à¦‡ বিসà§à¦¤à§ƒà¦¤ করছে না" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "ওভার-রাইড করার কোনো নেই" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " ইতিমধà§à¦¯à§‡à¦‡ উলà§à¦²à§‡à¦– করা হয়েছে" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " ইতিমধà§à¦¯à§‡à¦‡ উলà§à¦²à§‡à¦– করা হয়েছে" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " not yet existing সà§à¦•িম '%s' দেয়" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " not yet existing সà§à¦•িম '%s' à¦à¦° তালিকা" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "à¦à¦•টি পাথ সমেত সà§à¦•িমের à¦à¦•টি তালিকা হতে পারে না" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "à¦à¦•টি পাথ সমেত à¦à¦•টি সà§à¦•িম বিসà§à¦¤à§ƒà¦¤ করা যায় না" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" হল à¦à¦•টি তালিকা, বিসà§à¦¤à§ƒà¦¤ করা হচà§à¦›à§‡, যা à¦à¦•টি " +"তালিকা নয়" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" বাড়ায় কিনà§à¦¤à§ '%" +"s' " +"'%s' বাড়ায় না" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "à¦à¦•টি পাথ, দেওয়া হলে, অবশà§à¦¯à¦‡ à¦à¦•টি সà§à¦²à§à¦¯à¦¾à¦¶ দিয়ে শà§à¦°à§ à¦à¦¬à¦‚ শেষ হবে" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "à¦à¦•টি তালিকার পাথ অবশà§à¦¯à¦‡ ':/' দিয়ে শেষ হবে" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ইতিমধà§à¦¯à§‡à¦‡ উলà§à¦²à§‡à¦– করা হয়েছে" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "উপাদান <%s> উপরের লেবেলে অনà§à¦®à§‹à¦¦à¦¿à¦¤ নয়" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict উলà§à¦²à§‡à¦– করা হয়েছে; পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করা হচà§à¦›à§‡à¥¤\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "à¦à¦‡ সমগà§à¦° ফাইল উপেকà§à¦·à¦¾ করা হয়েছে।\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "à¦à¦‡ ফাইল উপেকà§à¦·à¦¾ করা হচà§à¦›à§‡à¥¤\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"'%s' ধরনের কোনো কী নেই, '%s' সà§à¦•িমে, '%s' ওভার-রাইড ফাইলে যেভাবে উলà§à¦²à§‡à¦– করা " +"হয়েছে" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; à¦à¦‡ কী'র জনà§à¦¯ ওভার-রাইড উপেকà§à¦·à¦¾ করা হচà§à¦›à§‡à¥¤\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " à¦à¦¬à¦‚ --strict নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা হয়েছে; পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করা হচà§à¦›à§‡à¥¤\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"'%s' কী পারà§à¦œ করতে তà§à¦°à§à¦Ÿà¦¿, '%s' সà§à¦•িমে, '%s' ওভার-রাইড ফাইলে যেভাবে উলà§à¦²à§‡à¦– " +"করা " +"হয়েছে: %s।" + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "à¦à¦‡ কী'র জনà§à¦¯ ওভার-রাইড উপেকà§à¦·à¦¾ করা হচà§à¦›à§‡à¥¤\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"'%s' কী'র কà§à¦·à§‡à¦¤à§à¦°à§‡ ওভার-রাইড, '%s'সà§à¦•িমে, '%s' ওভার-রাইড ফাইলে, সà§à¦•িমে দেওয়া " +"রেঞà§à¦œà§‡à¦° বাইরে" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"'%s' কী'র কà§à¦·à§‡à¦¤à§à¦°à§‡ ওভার-রাইড, '%s' সà§à¦•িমে, '%s' ওভার-রাইড ফাইলে, বৈধ পছনà§à¦¦à§‡à¦° " +"তালিকায় নেই" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled ফাইল সঞà§à¦šà¦¯à¦¼ করার সà§à¦¥à¦¾à¦¨" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "schemas ঠযেকোনো তà§à¦°à§à¦Ÿà¦¿ ছেড়ে যান" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled ফাইল লিখবেন না" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "কী নাম সীমাবদà§à¦§à¦¤à¦¾ চালৠকরবেন না" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"সকল GSettings সà§à¦•িম ফাইল à¦à¦•টি সà§à¦•িম কà§à¦¯à¦¾à¦¶à§‡ সমনà§à¦¬à¦¿à¦¤ করà§à¦¨à¥¤\n" +"সà§à¦•িম ফাইলে থাকতে হবে à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ .gschema.xml,\n" +"à¦à¦¬à¦‚ কà§à¦¯à¦¾à¦¶à§‡ ফাইলকে বলা হয় gschemas.compiled।" + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "অাপনাকে à¦à¦•টি হà§à¦¬à¦¹à§ à¦à¦•টি ডিরেকà§à¦Ÿà¦°à¦¿ নাম দেওয়া উচিত\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "à¦à¦•টিও সà§à¦•িম ফাইল পাওয়া যায়নি:" + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "কিছà§à¦‡ করা হচà§à¦›à§‡ না।\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "সরানো বিদà§à¦¯à¦®à¦¾à¦¨ অাউটপà§à¦Ÿ ফাইল।\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ডিরেকà§à¦Ÿà¦°à¦¿ নিয়নà§à¦¤à§à¦°à¦£à§‡à¦° ডিফলà§à¦Ÿ ধরন সনà§à¦§à¦¾à¦¨ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "ফাইলের নাম অবৈধ: %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ফাইল-সিসà§à¦Ÿà§‡à¦® সংকà§à¦°à¦¾à¦¨à§à¦¤ তথà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "root ডিরেকà§à¦Ÿà¦°à¦¿à¦° নাম পরিবরà§à¦¤à¦¨ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "ফাইলের নাম পরিবরà§à¦¤à¦¨à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "ফাইলের পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করা যাবে না, ফাইল-নাম ইতিমধà§à¦¯à§‡à¦‡ উপসà§à¦¥à¦¿à¦¤" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "ফাইলের নাম বৈধ নয়" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿ খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "ফাইল খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "ফাইল মà§à¦›à§‡ ফেলতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "ফাইলটি আবরà§à¦œà¦¨à¦¾à§Ÿ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "আবরà§à¦œà¦¨à¦¾à¦° ডিরেকà§à¦Ÿà¦°à¦¿ %s নিরà§à¦®à¦¾à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "আবরà§à¦œà¦¨à¦¾à¦° ঊরà§à¦§à§à¦¬à¦¤à¦¨ ডিরেকà§à¦Ÿà¦°à¦¿ সনাকà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "আবরà§à¦œà¦¨à¦¾à¦° ডিরেকà§à¦Ÿà¦°à¦¿ সনাকà§à¦¤ অথবা নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "trashing info ফাইল নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ফাইল বরà§à¦œà¦¨ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ সমসà§à¦¯à¦¾" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿ নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ফাইলসিসà§à¦Ÿà§‡à¦® সাংকেতিক লিঙà§à¦• সমরà§à¦¥à¦¨ করে না" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "সিমà§â€Œà¦¬à¦²à¦¿à¦• লিঙà§à¦• নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "ফাইল সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "ডিরেকà§à¦Ÿà¦°à¦¿à¦° উপর ডিরেকà§à¦Ÿà¦°à¦¿ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করা যাবে না" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "বà§à¦¯à¦¾à¦•-আপ ফাইল নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "উদà§à¦¦à¦¿à¦·à§à¦Ÿ ফাইল মà§à¦›à§‡ ফেলতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "মাউনà§à¦Ÿ করা অবসà§à¦¥à¦¾à¦¨à§‡à¦° মধà§à¦¯à§‡ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করা সমà§à¦­à¦¬ নয়" + +#: ../gio/glocalfile.c:2603 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s-à¦à¦° ডিসà§à¦• বà§à¦¯à¦¬à¦¹à¦¾à¦° নিরà§à¦§à¦¾à¦°à¦£ করা যায়নি: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ NULL-বà§à¦¯à¦¤à§€à¦¤ অনà§à¦¯ মান নিরà§à¦§à¦¾à¦°à¦£ করা আবশà§à¦¯à¦•" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (string পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "পà§à¦°à¦¸à¦¾à¦°à¦¿à¦¤ অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° নাম অবৈধ" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "পà§à¦°à¦¸à¦¾à¦°à¦¿à¦¤ অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿ '%s'-কে নিরà§à¦§à¦¾à¦°à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (অবৈধ à¦à¦¨à¦•োডিং)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "'%s' ফাইলের জনà§à¦¯ তথà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করার সময়ে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "বরà§à¦£à¦¨à¦¾à¦•ারীর জনà§à¦¯ তথà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করার সময়ে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ uint32)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ uint64)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° ধরন বৈধ নয় (byte string পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "সিমলিংকের অনà§à¦®à¦¤à¦¿ নিরà§à¦§à¦¾à¦°à¦£ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "অনà§à¦®à¦¤à¦¿ নিরà§à¦§à¦¾à¦°à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "মালিকানা নিরà§à¦§à¦¾à¦°à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "সিমà§â€Œ-লিঙà§à¦• NULL-বà§à¦¯à¦¾à¦¤à§€à¦¤ মান হওয়া আবশà§à¦¯à¦•" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "সিমà§â€Œ-লিঙà§à¦• নিরà§à¦§à¦¾à¦°à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "সিমà§â€Œ-লিঙà§à¦• নিরà§à¦§à¦¾à¦°à¦£ করতে তà§à¦°à§à¦Ÿà¦¿: ফাইলটি সিমà§â€Œ-লিঙà§à¦• নয়" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "পরিবরà§à¦¤à¦¨ অথবা বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° সময় নিরà§à¦§à¦¾à¦°à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux কনটেকà§à¦¸à¦Ÿà§‡à¦° NULL-বà§à¦¯à¦¾à¦¤à§€à¦¤ মান হওয়া আবশà§à¦¯à¦•" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux কনটেকà§à¦¸à¦Ÿ নিরà§à¦§à¦¾à¦°à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "à¦à¦‡ সিসà§à¦Ÿà§‡à¦®à§‡ SELinux সকà§à¦°à¦¿à§Ÿ করা হয়নি" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s অà§à¦¯à¦¾à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà§‡à¦° মান নিরà§à¦§à¦¾à¦°à¦£ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "ফাইল থেকে পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ফাইলের মধà§à¦¯à§‡ seek করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "ফাইল বনà§à¦§ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ডিরেকà§à¦Ÿà¦°à¦¿ নিয়নà§à¦¤à§à¦°à¦£à§‡à¦° ডিফলà§à¦Ÿ ধরন সনà§à¦§à¦¾à¦¨ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "ফাইলে লিখতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "পà§à¦°à§‹à¦¨à§‹ বà§à¦¯à¦¾à¦•-আপের লিংক মà§à¦›à§‡ ফেলতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "বà§à¦¯à¦¾à¦•-আপ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ নিরà§à¦®à¦¾à¦£ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "অসà§à¦¥à¦¾à§Ÿà§€ ফাইলের নাম পরিবরà§à¦¤à¦¨ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "ফাইল টà§à¦°à¦¾à¦¨à¦•েট (ছাà¦à¦Ÿà¦¾à¦‡) করতে সমসà§à¦¯à¦¾ %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "ফাইল '%s' খà§à¦²à¦¤à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "উদà§à¦¦à¦¿à¦·à§à¦Ÿ ফাইলটি à¦à¦•টি ডিরেকà§à¦Ÿà¦°à¦¿" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "উদà§à¦¦à¦¿à¦·à§à¦Ÿ ফাইলটি সাধারণ ফাইল নয়" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "ফাইলটি সà§à¦¬à¦¤à¦¨à§à¦¤à§à¦°à¦°à§‚পে পরিবরà§à¦¤à¦¨ করা হয়েছে" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "পà§à¦°à§‹à¦¨à§‹ ফাইল মà§à¦›à§‡ ফেলতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "অবৈধ GSeekType উলà§à¦²à¦¿à¦–িত হয়েছে" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "অবৈধ seek-র অনà§à¦°à§‹à¦§" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream টà§à¦°à¦¾à¦¨à¦•েট করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "মেমরি আউটপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° মাপ পরিবরà§à¦¤à¦¨à¦¯à§‹à¦—à§à¦¯ নয়" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "মেমরি আউটপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦®à§‡à¦° মাপ পরিবরà§à¦¤à¦¨ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"লেখা পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ করতে যত পরিমাণ মেমরি পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨ তা উপলবà§à¦§ ঠিকানা সà§à¦¥à¦¾à¦¨à§‡à¦° " +"তà§à¦²à¦¨à¦¾à¦¯à¦¼ বড়" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "সà§à¦Ÿà§à¦°à§€à¦® শà§à¦°à§ হওয়ার অাগের অনà§à¦°à§‹à¦§ জানানো সিক" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "সà§à¦Ÿà§à¦°à§€à¦® শেষ হওয়ার পরের অনà§à¦°à§‹à¦§ জানানো সীক" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "মাউনà§à¦Ÿ \"unmount\" বাসà§à¦¤à¦¬à¦¾à¦¯à¦¼à¦¿à¦¤ করে না" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "মাউনà§à¦Ÿ \"eject\" বাসà§à¦¤à¦¬à¦¾à¦¯à¦¼à¦¿à¦¤ করে না" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "মাউনà§à¦Ÿ \"unmount\" বা \"unmount_with_operation\" বাসà§à¦¤à¦¬à¦¾à¦¯à¦¼à¦¿à¦¤ করে না" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "মাউনà§à¦Ÿ \"eject\" বা \"eject_with_operation\" বাসà§à¦¤à¦¬à¦¾à¦¯à¦¼à¦¿à¦¤ করা হয় না" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "মাউনà§à¦Ÿ \"remount\" বাসà§à¦¤à¦¬à¦¾à¦¯à¦¼à¦¿à¦¤ করে না" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "mount দà§à¦¬à¦¾à¦°à¦¾ সামগà§à¦°à§€à¦° ধরন অনà§à¦®à¦¾à¦¨ করা সমà§à¦­à¦¬ নয়" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "mount দà§à¦¬à¦¾à¦°à¦¾ সà§à¦¸à¦‚গতভাবে সামগà§à¦°à§€à¦° ধরন অনà§à¦®à¦¾à¦¨ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gnetworkaddress.c:338 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "'%s' হোসà§à¦Ÿ-নেমের মধà§à¦¯à§‡ '[' উপসà§à¦¥à¦¿à¦¤ রয়েছে কিনà§à¦¤à§ ']' অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../gio/gnetworkmonitorbase.c:189 ../gio/gnetworkmonitorbase.c:292 +msgid "Network unreachable" +msgstr "নেটওয়ারà§à¦•ে পৌà¦à¦›à¦¾à¦¨à§‹ যাচà§à¦›à§‡ না" + +#: ../gio/gnetworkmonitorbase.c:227 ../gio/gnetworkmonitorbase.c:257 +msgid "Host unreachable" +msgstr "হোসà§à¦Ÿà§‡ পৌà¦à¦›à¦¾à¦¨à§‹ যাচà§à¦›à§‡ না" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "নেটওয়ারà§à¦• মনিটর তৈরি করা যায়নি: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "নেটওয়ারà§à¦• মনিটর তৈরি করা যায়নি: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "নেটওয়ারà§à¦• সà§à¦Ÿà§à¦¯à¦¾à¦Ÿà¦¾à¦¸ পাওয়া যায়নি: " + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:550 +msgid "Output stream doesn't implement write" +msgstr "আউটপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ write বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#: ../gio/goutputstream.c:511 ../gio/goutputstream.c:1028 +msgid "Source stream is already closed" +msgstr "মূল সà§à¦Ÿà§à¦°à¦¿à¦® বরà§à¦¤à¦®à¦¾à¦¨à§‡ বনà§à¦§ করা হয়েছে" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' মীমাংসা করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' ঠরিসোরà§à¦¸à§‡à¦° অসà§à¦¤à¦¿à¦¤à§à¦¬ নেই" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "'%s' ঠরিসোরà§à¦¸ ডিকমà§à¦ªà§à¦°à§‡à¦¶ হতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "'%s' ঠরিসোরà§à¦¸ à¦à¦•টি ডিরেকà§à¦Ÿà¦°à¦¿ নয়" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "ইনপà§à¦Ÿ সà§à¦Ÿà§à¦°à¦¿à¦® দà§à¦¬à¦¾à¦°à¦¾ সীক বাসà§à¦¤à¦¬à¦¾à§Ÿà¦¿à¦¤ হয় না" + +#: ../gio/gresource-tool.c:491 +msgid "List sections containing resources in an elf FILE" +msgstr "à¦à¦•টি elf FILE ঠরিসোরà§à¦¸ বিশিষà§à¦Ÿ বিভাগগà§à¦²à¦¿à¦•ে তালিকাভà§à¦•à§à¦¤ করà§à¦¨" + +#: ../gio/gresource-tool.c:497 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"রিসোরà§à¦¸à¦—à§à¦²à¦¿ তালিকাভà§à¦•à§à¦¤ করà§à¦¨\n" +"SECTION দেওয়া থাকলে, à¦à¦‡ বিভাগে শà§à¦§à§à¦®à¦¾à¦¤à§à¦° রিসোরà§à¦¸ তালিকাভà§à¦•à§à¦¤ করà§à¦¨\n" +"PATH দেওয়া থাকলে, শà§à¦§à§à¦®à¦¾à¦¤à§à¦° মানানসই রিসোরà§à¦¸ তালিকাভà§à¦•à§à¦¤ করà§à¦¨" + +#: ../gio/gresource-tool.c:500 ../gio/gresource-tool.c:510 +msgid "FILE [PATH]" +msgstr "ফাইল [পাথ]" + +#: ../gio/gresource-tool.c:501 ../gio/gresource-tool.c:511 +#: ../gio/gresource-tool.c:518 +msgid "SECTION" +msgstr "বিভাগ" + +#: ../gio/gresource-tool.c:506 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ সমেত রিসোরà§à¦¸à¦—à§à¦²à¦¿ তালিকাভà§à¦•à§à¦¤ করà§à¦¨\n" +"SECTION দেওয়া থাকলে, à¦à¦‡ বিভাগে শà§à¦§à§à¦®à¦¾à¦¤à§à¦° রিসোরà§à¦¸ তালিকাভà§à¦•à§à¦¤ করà§à¦¨\n" +"PATH দেওয়া থাকলে, শà§à¦§à§à¦®à¦¾à¦¤à§à¦° মানানসই রিসোরà§à¦¸ তালিকাভà§à¦•à§à¦¤ করà§à¦¨\n" +"বিসà§à¦¤à¦¾à¦°à¦¿à¦¤à§‡à¦° মধà§à¦¯à§‡ রয়েছে বিভাগ, মাপ à¦à¦¬à¦‚ কমà§à¦ªà§à¦°à§‡à¦¶à¦¨" + +#: ../gio/gresource-tool.c:516 +msgid "Extract a resource file to stdout" +msgstr "à¦à¦•টি রিসোরà§à¦¸ ফাইল stdout ঠবের করà§à¦¨" + +#: ../gio/gresource-tool.c:517 +msgid "FILE PATH" +msgstr "ফাইল পাথ" + +#: ../gio/gresource-tool.c:531 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"বà§à¦¯à¦¬à¦¹à¦¾à¦°:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"কমà§à¦¯à¦¾à¦¨à§à¦¡:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ সহায়তা পেতে 'gresource help COMMAND' বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤\n" +"\n" + +#: ../gio/gresource-tool.c:545 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"বà§à¦¯à¦¬à¦¹à¦¾à¦°:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:552 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION à¦à¦•টি (বৈকলà§à¦ªà¦¿à¦•) elf বিভাগ নাম\n" + +#: ../gio/gresource-tool.c:556 ../gio/gsettings-tool.c:635 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করার (বৈকলà§à¦ªà¦¿à¦•) কমà§à¦¯à¦¾à¦¨à§à¦¡\n" + +#: ../gio/gresource-tool.c:562 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE à¦à¦•টি elf ফাইল (à¦à¦•টি বাইনারি বা শেয়ারà§à¦¡ লাইবà§à¦°à§‡à¦°à¦¿)\n" + +#: ../gio/gresource-tool.c:565 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE à¦à¦•টি elf ফাইল (à¦à¦•টি বাইনারি বা শেয়ারà§à¦¡ লাইবà§à¦°à§‡à¦°à¦¿)\n" +" বা à¦à¦•টি সমনà§à¦¬à¦¿à¦¤ রিসোরà§à¦¸ ফাইল\n" + +#: ../gio/gresource-tool.c:569 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:571 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH à¦à¦•টি (বৈকলà§à¦ªà¦¿à¦•) রিসোরà§à¦¸ পাথ (অাংশিক হতে পারে)\n" + +#: ../gio/gresource-tool.c:572 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:574 +msgid " PATH A resource path\n" +msgstr " PATH à¦à¦•টি রিসোরà§à¦¸ পাথ\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "'%s' ধরনের কোনো সà§à¦•িম নেই\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "সà§à¦•িম '%s' রিলোকেটেবল নয় (পাথ উলà§à¦²à§‡à¦– করা চলবে না)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "সà§à¦•িম '%s' রিলোকেটেবল (পাথ অবশà§à¦¯à¦‡ উলà§à¦²à§‡à¦– করতে হবে)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "খালি পাথ দেওয়া হয়েছে।\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "পাথ অবশà§à¦¯à¦‡ à¦à¦•টি সà§à¦²à§à¦¯à¦¾à¦¶ (/) দিয়ে শà§à¦°à§ হতে হবে\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "পাথ অবশà§à¦¯à¦‡ à¦à¦•টি সà§à¦²à§à¦¯à¦¾à¦¶ (/) দিয়ে শেষ হতে হবে\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "পাথে পরপর দà§à¦‡à¦Ÿà¦¿ সà§à¦²à§à¦¯à¦¾à¦¶ থাকতে পারবে না (//)\n" + +#: ../gio/gsettings-tool.c:477 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "দেওয়া মান বৈধ রেঞà§à¦œà§‡à¦° বাইরে\n" + +#: ../gio/gsettings-tool.c:484 +#, c-format +msgid "The key is not writable\n" +msgstr "কী লিখনযোগà§à¦¯ নয়\n" + +#: ../gio/gsettings-tool.c:520 +msgid "List the installed (non-relocatable) schemas" +msgstr "ইনসà§à¦Ÿà¦² করা (non-relocatable) সà§à¦•িম তালিকাভà§à¦•à§à¦¤ করà§à¦¨" + +#: ../gio/gsettings-tool.c:526 +msgid "List the installed relocatable schemas" +msgstr "ইনসà§à¦Ÿà¦² করা রিলোকেটেবল সà§à¦•িম তালিকাভà§à¦•à§à¦¤ করà§à¦¨" + +#: ../gio/gsettings-tool.c:532 +msgid "List the keys in SCHEMA" +msgstr "SCHEMA ঠকী তালিকাভà§à¦•à§à¦¤ করà§à¦¨" + +#: ../gio/gsettings-tool.c:533 ../gio/gsettings-tool.c:539 +#: ../gio/gsettings-tool.c:576 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:538 +msgid "List the children of SCHEMA" +msgstr "SCHEMA à¦à¦° চিলডà§à¦°à§‡à¦¨ তালিকাভà§à¦•à§à¦¤ করà§à¦¨" + +#: ../gio/gsettings-tool.c:544 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"কী à¦à¦¬à¦‚ মান তালিকাভà§à¦•à§à¦¤ করà§à¦¨, সূতà§à¦° ধরে\n" +"কোনো SCHEMA দেওয়া না থাকলে, সকল কী তালিকাভà§à¦•à§à¦¤ করà§à¦¨\n" + +#: ../gio/gsettings-tool.c:546 +msgid "[SCHEMA[:PATH]]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:551 +msgid "Get the value of KEY" +msgstr "KEY à¦à¦° মান পান" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:570 ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:557 +msgid "Query the range of valid values for KEY" +msgstr "KEY à¦à¦° জনà§à¦¯ বৈধ মানগà§à¦²à¦¿à¦° রেঞà§à¦œ কোয়à§à¦¯à¦¾à¦°à¦¿ করà§à¦¨" + +#: ../gio/gsettings-tool.c:563 +msgid "Set the value of KEY to VALUE" +msgstr "KEY à¦à¦° মান VALUE ঠসেট করà§à¦¨" + +#: ../gio/gsettings-tool.c:564 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:569 +msgid "Reset KEY to its default value" +msgstr "KEY তার ডিফলà§à¦Ÿ মানে রিসেট করà§à¦¨" + +#: ../gio/gsettings-tool.c:575 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "SCHEMA ঠসকল কী তাদের ডিফলà§à¦Ÿà§‡ সেট করà§à¦¨" + +#: ../gio/gsettings-tool.c:581 +msgid "Check if KEY is writable" +msgstr "KEY লিখনযোগà§à¦¯ কিনা যাচাই করà§à¦¨" + +#: ../gio/gsettings-tool.c:587 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"পরিবরà§à¦¤à¦¨à§‡à¦° উপরে নজর রাখতে KEY নিয়নà§à¦¤à§à¦°à¦£ করà§à¦¨à¥¤\n" +"কোনো KEY উলà§à¦²à§‡à¦– করা না থাকলে, SCHEMA ঠসকল কী নিয়নà§à¦¤à§à¦°à¦£ করà§à¦¨à¥¤\n" +"নিয়নà§à¦¤à§à¦°à¦£ থামাতে ^C বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤\n" + +#: ../gio/gsettings-tool.c:590 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:602 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"বà§à¦¯à¦¬à¦¹à¦¾à¦°:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"কমà§à¦¯à¦¾à¦¨à§à¦¡:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ সাহাযà§à¦¯ পেতে 'gsettings help COMMAND' বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤\n" +"\n" + +#: ../gio/gsettings-tool.c:625 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"বà§à¦¯à¦¬à¦¹à¦¾à¦°:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:631 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR অতিরিকà§à¦¤ সà§à¦•িম অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করার à¦à¦•টি ডিরেকà§à¦Ÿà¦°à¦¿\n" + +#: ../gio/gsettings-tool.c:639 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA সà§à¦•িমের নাম\n" +" PATH পাথ, রিলোকেটেবল সà§à¦•িমের জনà§à¦¯\n" + +#: ../gio/gsettings-tool.c:644 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY সà§à¦•িমার (বৈকলà§à¦ªà¦¿à¦•) মধà§à¦¯à§‡ কী\n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The key within the schema\n" +msgstr " KEY সà§à¦•িমার মধà§à¦¯à§‡ কী\n" + +#: ../gio/gsettings-tool.c:652 +msgid " VALUE The value to set\n" +msgstr " VALUE সেট করার মান\n" + +#: ../gio/gsettings-tool.c:707 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s থেকে সà§à¦•িম লোড করা যায়নি: %s\n" + +#: ../gio/gsettings-tool.c:769 +#, c-format +msgid "Empty schema name given\n" +msgstr "সà§à¦•িম নাম খালি অাছে\n" + +#: ../gio/gsettings-tool.c:798 +#, c-format +msgid "No such key '%s'\n" +msgstr "'%s' ধরনের কোনো কী নেই\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "অবৈধ সকেট, আরমà§à¦­ করা হয়নি" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "অবৈধ সকেট, চিহà§à¦¨à¦¿à¦¤ কারণে আরমà§à¦­ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "সকেট বরà§à¦¤à¦®à¦¾à¦¨à§‡ বনà§à¦§ করা হয়েছে" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "সকেট I/O সময়সমাপà§à¦¤" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd থেকে GSocket নিরà§à¦®à¦¾à¦£ করা হচà§à¦›à§‡: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "সকেট নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "অজানা ফà§à¦¯à¦¾à¦®à¦¿à¦²à¦¿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা হয়েছে" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "অজানা পà§à¦°à§‹à¦Ÿà§‹à¦•ল নিরà§à¦§à¦¾à¦°à¦£ করা হয়" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ঠিকানা পà§à¦°à¦¾à¦ªà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "দূরবরà§à¦¤à§€ ঠিকানা পà§à¦°à¦¾à¦ªà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "অপেকà§à¦·à¦¾ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "ঠিকানার সাথে বাইনà§à¦¡ করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "মালà§à¦Ÿà¦¿à¦•াসà§à¦Ÿ গà§à¦°à§à¦ª সমনà§à¦¬à¦¯à¦¼à§‡ তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "মালà§à¦Ÿà¦¿à¦•াসà§à¦Ÿ গà§à¦°à§à¦ª ছেড়ে যেতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "source-specific মালà§à¦Ÿà¦¿à¦•াসà§à¦Ÿà§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ কোনো সহায়তা নেই" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "সংযোগ গà§à¦°à¦¹à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "সংযোগ বরà§à¦¤à¦®à¦¾à¦¨à§‡ সà§à¦¥à¦¾à¦ªà¦¿à¦¤ হচà§à¦›à§‡" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "অপেকà§à¦·à¦¾à¦°à¦¤ তà§à¦°à§à¦Ÿà¦¿ পà§à¦°à¦¾à¦ªà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥:" + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "তথà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "তথà§à¦¯ পাঠাতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "সকেট শাটডাউন করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "সকেট বনà§à¦§ করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "সকেটের অবসà§à¦¥à¦¾ পà§à¦°à¦¾à¦ªà§à¦¤ করতে অপেকà§à¦·à¦¾ করা হচà§à¦›à§‡: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "বারà§à¦¤à¦¾ পাঠাতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage Windows ঠসমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "বারà§à¦¤à¦¾ পà§à¦°à¦¾à¦ªà§à¦¤ করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gsocket.c:4516 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "সকেট শংসাপতà§à¦°à¦—à§à¦²à¦¿ পড়তে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials à¦à¦‡ OS à¦à¦° জনà§à¦¯ বাসà§à¦¤à¦¬à¦¾à¦¯à¦¼à¦¿à¦¤ নয়" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "%s পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦°à§‡à¦° সাথে সংযোগ করা গেল না:" + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s'র সাথে সংযোগ করা গেল না:" + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "সংযোগ করা গেল না: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1603 +msgid "Unknown error on connect" +msgstr "সংযোগ সà§à¦¥à¦¾à¦ªà¦¨à¦•ালে অজানা সমসà§à¦¯à¦¾" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1538 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "à¦à¦•টি নন-TCP সংযোগ বরাবর পà§à¦°à¦•à§à¦¸à¦¿ সমরà§à¦¥à¦¿à¦¤ নয়।" + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1559 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "পà§à¦°à¦•à§à¦¸à¦¿ পà§à¦°à§‹à¦Ÿà§‹à¦•ল '%s' সমরà§à¦¥à¦¿à¦¤ নয।" + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "লিসেনার বরà§à¦¤à¦®à¦¾à¦¨à§‡ বনà§à¦§ করা আছে" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "যোগ করা সকেট বরà§à¦¤à¦®à¦¾à¦¨ বনà§à¦§ করা আছে" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 IPv6 ঠিকানা '%s' সমরà§à¦¥à¦¨ করে না" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 পà§à¦°à§‹à¦Ÿà§‹à¦•লের কà§à¦·à§‡à¦¤à§à¦°à§‡ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•ারী নাম অতà§à¦¯à¦¨à§à¦¤ বড়" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 পà§à¦°à§‹à¦Ÿà§‹à¦•লের কà§à¦·à§‡à¦¤à§à¦°à§‡ হোসà§à¦Ÿà¦¨à¦¾à¦® '%s' অতà§à¦¯à¦¨à§à¦¤ বড়" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "সারà§à¦­à¦¾à¦° à¦à¦•টি SOCKSv4 পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦° নয়।" + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 সারà§à¦­à¦¾à¦° মারফত সংযোগ পà§à¦°à¦¤à§à¦¯à¦¾à¦–à§à¦¯à¦¾à¦¨ করা হয়েছে" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "সারà§à¦­à¦¾à¦° à¦à¦•টি SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦° নয়।" + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿'র পà§à¦°à¦®à¦¾à¦£à§€à¦•রণের পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨à¥¤" + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿'র à¦à¦•টি পà§à¦°à¦®à¦¾à¦£à§€à¦•রণ পদà§à¦§à¦¤à¦¿à¦° পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨ যা GLib à¦à¦° দà§à¦¬à¦¾à¦°à¦¾ সমরà§à¦¥à¦¿à¦¤ " +"নয়।" + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•ারী নাম বা পাসওয়ারà§à¦¡ SOCKSv5 পà§à¦°à§‹à¦Ÿà§‹à¦•লের কà§à¦·à§‡à¦¤à§à¦°à§‡ অতà§à¦¯à¦¨à§à¦¤ বড়।" + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"ভà§à¦² বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•ারীনাম বা পাসওয়ারà§à¦¡à§‡à¦° কারণে SOCKSv5 পà§à¦°à¦®à¦¾à¦£à§€à¦•রণ বà§à¦¯à¦°à§à¦¥ হয়েছে।" + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "SOCKSv5 পà§à¦°à§‹à¦Ÿà§‹à¦•লের কà§à¦·à§‡à¦¤à§à¦°à§‡ হোসà§à¦Ÿà¦¨à¦¾à¦® '%s' অতà§à¦¯à¦¨à§à¦¤ বড়" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦° অজানা ঠিকানা ধরন বà§à¦¯à¦¬à¦¹à¦¾à¦° করে।" + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦° তà§à¦°à§à¦Ÿà¦¿à¥¤" + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 সংযোগ ruleset দà§à¦¬à¦¾à¦°à¦¾ অনà§à¦®à§‹à¦¦à¦¿à¦¤ নয়।" + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 সারà§à¦­à¦¾à¦°à§‡à¦° মারফত হোসà§à¦Ÿà§‡ পৌà¦à¦›à¦¾à¦¨à§‹ যাচà§à¦›à§‡ না।" + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿à¦° মাধà§à¦¯à¦®à§‡ নেটওয়ারà§à¦•ে পৌà¦à¦›à¦¾à¦¨à§‹ যাচà§à¦›à§‡ না।" + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿ মারফত সংযোগ পà§à¦°à¦¤à§à¦¯à¦¾à¦–à§à¦¯à¦¾à¦¨ করা হয়েছে।" + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿ 'connect' কমà§à¦¯à¦¾à¦¨à§à¦¡ সমরà§à¦¥à¦¨ করে না।" + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿ পà§à¦°à¦¦à¦¤à§à¦¤ ঠিকানা ধরন সমরà§à¦¥à¦¨ করে না।" + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "অজানা SOCKSv5 পà§à¦°à¦•à§à¦¸à¦¿ তà§à¦°à§à¦Ÿà¦¿à¥¤" + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GEmblemedIcon à¦à¦¨à¦•োডিং-র %d সংসà§à¦•রণ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾ করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "কোনো বৈধ ঠিকানা খà§à¦à¦œà§‡ পাওয়া যায়নি" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "বিপরীত দিশায় '%s' মীমাংসা করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "'%s' à¦à¦° জনà§à¦¯ অনà§à¦°à§‹à¦§ জানানো ধরনের কোনো DNS রেকরà§à¦¡ নেই " + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "সাময়িকভাবে '%s' মীমাংসা করতে বà§à¦¯à¦°à§à¦¥" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "'%s' মীমাংসা করতে তà§à¦°à§à¦Ÿà¦¿" + +#: ../gio/gtlscertificate.c:247 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-encoded বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত কী ডিকà§à¦°à¦¿à¦ªà§à¦Ÿ করা যায় না" + +#: ../gio/gtlscertificate.c:252 +msgid "No PEM-encoded private key found" +msgstr "কোনো PEM-encoded বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত কী পাওয়া যায়নি" + +#: ../gio/gtlscertificate.c:262 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-encoded বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত কী পারà§à¦œ করা যায়নি" + +#: ../gio/gtlscertificate.c:287 +msgid "No PEM-encoded certificate found" +msgstr "কোনো PEM-encoded শংসাপতà§à¦° পাওয়া যায়নি" + +#: ../gio/gtlscertificate.c:296 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-encoded শংসাপতà§à¦° পারà§à¦œ করা যায়নি" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"অাপনার অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ অাটকে যাওয়ার অাগে সঠিক ভাবে পাসওয়ারà§à¦¡ দেওয়ার à¦à¦‡ শেষ সà§à¦¯à§‹à¦—।" + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"à¦à¦•াধিক বার ভà§à¦² পাসওয়ারà§à¦¡ দিয়েছেন, à¦à¦¬à¦‚ অাবার ভà§à¦² দিলে অাপনার অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ অাটকে " +"দেওয়া " +"হবে।" + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "দেওয়া পাসওয়ারà§à¦¡à¦Ÿà¦¿ ভà§à¦²à¥¤" + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "à§§-টি কনটà§à¦°à§‹à¦² বারà§à¦¤à¦¾ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, %d-টি পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে" +msgstr[1] "à§§-টি কনটà§à¦°à§‹à¦² বারà§à¦¤à¦¾ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, %d-টি পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ পà§à¦°à¦•ৃতির অনà§à¦·à¦…ঙà§à¦—িক তথà§à¦¯" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "à¦à¦•টি fd পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, কিনà§à¦¤à§ %d পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে\n" +msgstr[1] "à¦à¦•টি fd পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, কিনà§à¦¤à§ %d পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "অবৈধ fd পà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "শংসাপতà§à¦° পাঠাতে তà§à¦°à§à¦Ÿà¦¿: " + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"সকেটের কà§à¦·à§‡à¦¤à§à¦°à§‡ SO_PASSCRED সকà§à¦°à¦¿à¦¯à¦¼ করা হয়েছে কিনা তা যাচাইয়ে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED সকà§à¦°à¦¿à¦¯à¦¼ করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"পà§à¦°à¦¾à¦ªà§à¦¤ শংসাপতà§à¦°à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ à¦à¦•টি à¦à¦•ক বাইট পড়ার পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¾ রয়েছে তবে শূনà§à¦¯ " +"বাইট পড়া হচà§à¦›à§‡" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "নিয়নà§à¦¤à§à¦°à¦£ বারà§à¦¤à¦¾à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¾ করা হচà§à¦›à§‡ না, তবে পাওয়া গেছে %d" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED নিষà§à¦•à§à¦°à¦¿à¦¯à¦¼ করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ফাইল ডেসকà§à¦°à¦¿à¦ªà¦Ÿà¦° থেকে পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ফাইল ডেসকà§à¦°à¦¿à¦ªà¦Ÿà¦° বনà§à¦§ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gunixmounts.c:2054 ../gio/gunixmounts.c:2107 +msgid "Filesystem root" +msgstr "ফাইল-সিসà§à¦Ÿà§‡à¦®à§‡à¦° root" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ফাইল ডেসকà§à¦°à¦¿à¦ªà¦Ÿà¦°à§‡ লিখতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "à¦à¦‡ সিসà§à¦Ÿà§‡à¦®à§‡ অসমরà§à¦¥à¦¿à¦¤ UNIX ডোমেন সকেট ঠিকানা বের করà§à¦¨" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "ভলিউম দà§à¦¬à¦¾à¦°à¦¾ eject পà§à¦°à§Ÿà§‹à¦— করা সমà§à¦­à¦¬ নয়" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "ভলিউম দà§à¦¬à¦¾à¦°à¦¾ eject অথবা eject_with_operation পà§à¦°à§Ÿà§‹à¦— করা সমà§à¦­à¦¬ নয়" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন পাওয়া যায়নি" + +#: ../gio/gwin32appinfo.c:306 +#, c-format +msgid "Error launching application: %s" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন আরমà§à¦­ করতে সমসà§à¦¯à¦¾: %s" + +#: ../gio/gwin32appinfo.c:342 +msgid "URIs not supported" +msgstr "URI সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gwin32appinfo.c:364 +msgid "association changes not supported on win32" +msgstr "সংসরà§à¦— সমà§à¦¬à¦¨à§à¦§à§€à§Ÿ পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ win32-র মধà§à¦¯à§‡ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gwin32appinfo.c:376 +msgid "Association creation not supported on win32" +msgstr "সংসরà§à¦— নিরà§à¦§à¦¾à¦°à¦£ win32-র মধà§à¦¯à§‡ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "হà§à¦¯à¦¾à¦¨à§à¦¡à¦² থেকে পড়তে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "হà§à¦¯à¦¾à¦¨à§à¦¡à¦² বনà§à¦§ করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "হà§à¦¯à¦¾à¦¨à§à¦¡à¦²à§‡ লিখতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "পরà§à¦¯à¦¾à¦ªà§à¦¤ মেমরি উপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ তà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "অারো ইনপà§à¦Ÿ পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "সংকà§à¦šà¦¿à¦¤ তথà§à¦¯ বৈধ নয়" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "শোনার ঠিকানা" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "উপেকà§à¦·à¦¿à¦¤, GTestDbus সমেত compat à¦à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ " + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "ঠিকানা মà§à¦¦à§à¦°à¦£" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "শেল মোডে ঠিকানা মà§à¦¦à§à¦°à¦£" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "à¦à¦•টি dbus পরিষেবা চালান" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "ভà§à¦² অারà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ '%s' বৈশিষà§à¦Ÿà§à¦¯ '%s' বসà§à¦¤à§à¦° জনà§à¦¯ উলà§à¦²à¦¿à¦–িত হয়েছে" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' বৈশিষà§à¦Ÿà§à¦¯ '%s' বসà§à¦¤à§à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ পাওয়া যায়নি" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ টà§à¦¯à¦¾à¦— '%s', টà§à¦¯à¦¾à¦— '%s' পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ '%s' টà§à¦¯à¦¾à¦— '%s'-র মধà§à¦¯à§‡" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "data dir'র মধà§à¦¯à§‡ বৈধ বà§à¦•মারà§à¦• ফাইল পাওয়া যায়নি" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s'-র জনà§à¦¯ বà§à¦•মারà§à¦• বরà§à¦¤à¦®à¦¾à¦¨à§‡ উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s'-র জনà§à¦¯ বà§à¦•মারà§à¦• পাওয়া যায়নি" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s'-র বà§à¦•মারà§à¦•ের কà§à¦·à§‡à¦¤à§à¦°à§‡ MIME'র ধরন নিরà§à¦§à¦¾à¦°à¦¿à¦¤ হয়নি" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s'-র বà§à¦•মারà§à¦•ের কà§à¦·à§‡à¦¤à§à¦°à§‡ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত ফà§à¦²à§à¦¯à¦¾à¦— চিহà§à¦¨ দেওয়া হয়নি" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s'-র বà§à¦•মারà§à¦•ের কà§à¦·à§‡à¦¤à§à¦°à§‡ দল নিরà§à¦§à¦¾à¦°à¦£ করা হয়নি" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "'%s' নামক কোনো অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশনের দà§à¦¬à¦¾à¦°à¦¾ '%s' বà§à¦•মারà§à¦• নিবনà§à¦§à¦¿à¦¤ হয়নি" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "exec পংকà§à¦¤à¦¿ '%s'-টি URI '%s' সহ পà§à¦°à¦¸à¦¾à¦°à¦£ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "পà§à¦°à¦¦à¦¤à§à¦¤ ইনপà§à¦Ÿà§‡à¦° অনà§à¦¤à§‡ আংশিক অকà§à¦·à¦° অনà§à¦•à§à¦°à¦®" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "ফলবà§à¦¯à¦¾à¦• '%s' থেকে '%s' কোড-সেটে পরিবরà§à¦¤à¦¨ করা যায়নি" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s'-টি \"file\" সà§à¦•িম পà§à¦°à§Ÿà§‹à¦—কারী সà§à¦¨à¦¿à¦¶à§à¦šà¦¿à¦¤ URI নয়" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ ফাইল URI '%s'-র মধà§à¦¯à§‡ '#' চিহà§à¦¨ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ করা যাবে না" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' বৈধ নয়" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI '%s'-র হোসà§à¦Ÿ-নেম বৈধ নয়" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s'-র মধà§à¦¯à§‡ অবৈধরূপে à¦à¦¸à§à¦•েপ অকà§à¦·à¦° পà§à¦°à§Ÿà§‹à¦— করা হয়েছে" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s' পাথটি সà§à¦¨à¦¿à¦¶à§à¦šà¦¿à¦¤ নয়" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "হোসà§à¦Ÿ-নেম বৈধ নয়" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "পূরà§à¦¬à¦¾à¦¹à§à¦¨" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "অপরাহà§à¦¨" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "জানà§à§Ÿà¦¾à¦°à¦¿" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "ফেবà§à¦°à§à§Ÿà¦¾à¦°à¦¿" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "মারà§à¦š" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "à¦à¦ªà§à¦°à¦¿à¦²" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "মে" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "জà§à¦¨" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "জà§à¦²à¦¾à¦‡" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "আগসà§à¦Ÿ" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "সেপà§à¦Ÿà§‡à¦®à¦¬à¦°" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "অকà§à¦Ÿà§‹à¦¬à¦°" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "নভেমà§à¦¬à¦°" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "ডিসেমà§à¦¬à¦°" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "জানà§à§Ÿà¦¾à¦°à¦¿" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ফেবà§à¦°à§à§Ÿà¦¾à¦°à¦¿" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "মারà§à¦š" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à¦à¦ªà§à¦°à¦¿à¦²" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "মে" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "জà§à¦¨" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "জà§à¦²à¦¾à¦‡" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "আগসà§à¦Ÿ" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "সেপà§à¦Ÿà§‡à¦®à§à¦¬à¦°" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "অকà§à¦Ÿà§‹à¦¬à¦°" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "নভেমà§à¦¬à¦°" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ডিসেমà§à¦¬à¦°" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "সোমবার" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "মঙà§à¦—লবার" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "বà§à¦§à¦¬à¦¾à¦°" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "বৃহসà§à¦ªà¦¤à¦¿à¦¬à¦¾à¦°" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "শà§à¦•à§à¦°à¦¬à¦¾à¦°" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "শনিবার" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "রবিবার" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "সোম" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "মঙà§à¦—ল" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "বà§à¦§" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "বৃহঃ" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "শà§à¦•à§à¦°" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "শনি" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "রবি" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "'%s' ডিরেকà§à¦Ÿà¦°à¦¿ খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "%lu বাইট নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা যায়নি, \"%s\" ফাইল পড়তে" +msgstr[1] "%lu বাইট নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা যায়নি, \"%s\" ফাইল পড়তে" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' ফাইল পড়তে সমসà§à¦¯à¦¾: %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "\"%s\" ফাইল অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' ফাইল থেকে পড়তে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' ফাইল খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' ফাইলের বৈশিষà§à¦Ÿà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥: fstat() বিফল: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' ফাইল খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: fdopen() বিফল: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "'%s' ফাইলের নাম '%s'-ঠপরিবরà§à¦¤à¦¨ করতে বà§à¦¯à¦°à§à¦¥: g_rename() বিফল: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' ফাইল নিরà§à¦®à¦¾à¦£ করতে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "'%s' ফাইলে লিখতে বà§à¦¯à¦°à§à¦¥: write() বিফল: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' ফাইলে লিখতে বà§à¦¯à¦°à§à¦¥: fsync() বিফল: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "বিদà§à¦¯à¦®à¦¾à¦¨ ফাইল '%s' অপসারিত করা যায়নি: g_unlink() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "নমà§à¦¨à¦¾ '%s' সঠিক নয়, '%s' থাকা উচিত নয়" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "'%s' টেমপà§à¦²à§‡à¦Ÿà§‡à¦° মধà§à¦¯à§‡ XXXXXX অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ নেই" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "'%s' সিমà§à¦¬à§‹à¦²à¦¿à¦™à§à¦• লিঙà§à¦• পড়তে বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "সিমà§à¦¬à§‹à¦²à¦¿à¦• লিঙà§à¦• সমরà§à¦¥à¦¿à¦¤ হয় না" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' থেকে '%s' পরিবরà§à¦¤à¦¨ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾ খোলা সমà§à¦­à¦¬ হয়নি: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string'র উপর raw read করা সমà§à¦­à¦¬ নয়" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "read বাফারের মধà§à¦¯à§‡ অরূপানà§à¦¤à¦°à¦¿à¦¤ তথà§à¦¯ অবশিষà§à¦Ÿ রয়েছে" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "আংশিক অকà§à¦·à¦° দà§à¦¬à¦¾à¦°à¦¾ চà§à¦¯à¦¾à¦¨à§‡à¦²à§‡à¦° সমাপà§à¦¤à¦¿" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end'ঠraw read করা যায়নি" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡à¦° dirs-র মধà§à¦¯à§‡ বৈধ কি-ফাইল পাওয়া যায়নি" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "সাধারণ ফাইল নয়" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"কি-ফাইলের মধà§à¦¯à§‡ '%s' পংকà§à¦¤à¦¿à¦Ÿà¦¿ রয়েছে, à¦à¦Ÿà¦¿ কি-মান জà§à¦Ÿà¦¿, সংকলন অথবা মনà§à¦¤à¦¬à§à¦¯ নয়" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "দলের নাম অবৈধ: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "কি-ফাইলের পà§à¦°à¦¾à¦°à¦®à§à¦­à§‡ কোনো সংকলন উলà§à¦²à¦¿à¦–িত নেই" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "কি-র নাম অবৈধ: %s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "কি-ফাইলের মধà§à¦¯à§‡ অসমরà§à¦¥à¦¿à¦¤ à¦à¦¨à¦•োডিং '%s'" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1692 ../glib/gkeyfile.c:3072 +#: ../glib/gkeyfile.c:3138 ../glib/gkeyfile.c:3264 ../glib/gkeyfile.c:3397 +#: ../glib/gkeyfile.c:3539 ../glib/gkeyfile.c:3768 ../glib/gkeyfile.c:3835 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "কি-ফাইলের মধà§à¦¯à§‡ কোনো সংকলন অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ '%s'" + +#: ../glib/gkeyfile.c:1704 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "কি-ফাইলের মধà§à¦¯à§‡ কোনো কি উপসà§à¦¥à¦¿à¦¤ নেই '%s'" + +#: ../glib/gkeyfile.c:1811 ../glib/gkeyfile.c:1927 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"কি-ফাইলের মধà§à¦¯à§‡ '%2$s' মান সহ '%1$s' কি উপসà§à¦¥à¦¿à¦¤ রয়েছে যা UTF-8 বিনà§à¦¯à¦¾à¦¸à§‡ নেই।" + +#: ../glib/gkeyfile.c:1831 ../glib/gkeyfile.c:1947 ../glib/gkeyfile.c:2316 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "কি-ফাইলের মধà§à¦¯à§‡ '%s' কি উপসà§à¦¥à¦¿à¦¤ রয়েছে যার মান বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gkeyfile.c:2533 ../glib/gkeyfile.c:2901 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"কি-ফাইলের মধà§à¦¯à§‡ '%s' কি উপসà§à¦¥à¦¿à¦¤ রয়েছে, '%s' গà§à¦°à§à¦ªà§‡ যার মান বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ " +"নয়।" + +#: ../glib/gkeyfile.c:2611 ../glib/gkeyfile.c:2688 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "'%s' কী'র '%s' গà§à¦°à§à¦ªà§‡ '%s' মান অাছে যেখানে %s পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gkeyfile.c:3087 ../glib/gkeyfile.c:3279 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "কি-ফাইলের মধà§à¦¯à§‡ '%2$s' সংকলনে '%1$s' কি উপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "কি-ফাইলের মধà§à¦¯à§‡ পংকà§à¦¤à¦¿à¦° অবশেষে à¦à¦¸à§à¦•েপ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "কি-ফাইলের মধà§à¦¯à§‡ অবৈধ à¦à¦¸à§à¦•েপ ধারা উপসà§à¦¥à¦¿à¦¤ রয়েছে '%s'" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "'%s' মান কোনো সংখà§à¦¯à¦¾à¦°à§‚পে বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "'%s' পূরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ মান সীমা বহিরà§à¦­à§‚ত" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "'%s' মান float সংখà§à¦¯à¦¾ রূপে বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "'%s' মান বà§à¦²à¦¿à§Ÿà¦¾à¦¨ রূপে বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "'%s%s%s%s' ফাইলের বৈশিষà§à¦Ÿà§à¦¯ পà§à¦°à¦¾à¦ªà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥: fstat() বিফল: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s মà§à¦¯à¦¾à¦ª করতে বà§à¦¯à¦°à§à¦¥: mmap() বà§à¦¯à¦°à§à¦¥: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "'%s' খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: open() বিফল: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "পংকà§à¦¤à¦¿ %d অকà§à¦·à¦° %d'ঠতà§à¦°à§à¦Ÿà¦¿: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "নামের মধà§à¦¯à§‡ অবৈধ UTF-8 à¦à¦¨à¦•োডিং সহ টেকà§à¦¸à¦Ÿ - বৈধ '%s' নয়" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' à¦à¦•টি বৈধ নাম নয়" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' à¦à¦•টি বৈধ নাম নয়: '%c'" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "পংকà§à¦¤à¦¿ %d'ঠতà§à¦°à§à¦Ÿà¦¿: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥, à¦à¦Ÿà¦¿ কোনো অকà§à¦·à¦°à§‡à¦° রেফারেনà§à¦¸à§‡à¦° মধà§à¦¯à§‡ à¦à¦•টি সংখà§à¦¯à¦¾ " +"হওয়া উচিত " +"(উদাহরণসà§à¦¬à¦°à§‚প ê) - সমà§à¦­à¦¬à¦¤ সংখà§à¦¯à¦¾à¦Ÿà¦¿ অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"অকà§à¦·à¦°à§‡à¦° রেফারেনà§à¦¸ সেমি-কোলন চিহà§à¦¨ দà§à¦¬à¦¾à¦°à¦¾ সমাপà§à¦¤ হয়নি; সমà§à¦­à¦¬à¦¤ আপনি সà§à¦¬à¦¤à§à¦¬à¦¾ " +"হিসাবে " +"বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ à¦à¦®à§à¦ªà¦¾à¦°à¦¸à§‡à¦¨à§à¦¡ চিহà§à¦¨ পà§à¦°à§Ÿà§‹à¦— করেননি - & রূপে à¦à¦®à§à¦ªà¦¾à¦°à¦¸à§‡à¦¨à§à¦¡ " +"à¦à¦¸à§à¦•েপ " +"করানো যাবে" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "'%-.*s' অকà§à¦·à¦°à§‡à¦° রেফারেনà§à¦¸à§‡à¦° মধà§à¦¯à§‡ অনà§à¦®à§‹à¦¦à¦¿à¦¤ অকà§à¦·à¦° à¦à¦¨à¦•োড করা হয়নি" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"তথà§à¦¯à¦¬à¦¿à¦¹à§€à¦¨ সà§à¦¬à¦¤à§à¦¬à¦¾ '&;' পà§à¦°à¦¦à¦°à§à¦¶à¦¿à¦¤; বৈধ সà§à¦¬à¦¤à§à¦¬à¦¾ হল: & " < > " +"'" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "সà§à¦¬à¦¤à§à¦¤à§à¦¬à¦¾à¦° নাম '%-.*s' অজানা" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"সà§à¦¬à¦¤à§à¦¬à¦¾à¦° নাম সেমিকোলোন চিহà§à¦¨ দà§à¦¬à¦¾à¦°à¦¾ সমাপà§à¦¤ হয়নি; সমà§à¦­à¦¬à¦¤ আপনি সà§à¦¬à¦¤à§à¦¬à¦¾ হিসাবে " +"বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° " +"উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ à¦à¦®à§à¦ªà¦¾à¦°à¦¸à§‡à¦¨à§à¦¡ চিহà§à¦¨ পà§à¦°à§Ÿà§‹à¦— করেননি - & রূপে à¦à¦®à§à¦ªà¦¾à¦°à¦¸à§‡à¦¨à§à¦¡ à¦à¦¸à§à¦•েপ " +"করানো যাবে" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "নথি কোনো à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ দà§à¦¬à¦¾à¦°à¦¾ আরমà§à¦­ হওয়া আবশà§à¦¯à¦• (উদাহরণসà§à¦¬à¦°à§‚প )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'<' অকà§à¦·à¦°à§‡à¦° পরে '%s'-র বà§à¦¯à¦¬à¦¹à¦¾à¦° বৈধ নয়; à¦à¦° দà§à¦¬à¦¾à¦°à¦¾ à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° নাম আরমà§à¦­ করা " +"যাবে না" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"'%s' অকà§à¦·à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ নয়, '%s' ফাà¦à¦•া à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• টà§à¦¯à¦¾à¦— সমাপà§à¦¤ করার " +"উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ " +"'>' চিহà§à¦¨ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"'%1$s' অকà§à¦·à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ নয়, '%3$s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° '%2$s' নামক বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° নামের " +"পরে " +"à¦à¦•টি '=' চিহà§à¦¨ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"'%s' অকà§à¦·à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ নয়, '%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• টà§à¦¯à¦¾à¦— সমাপà§à¦¤ করার " +"উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ '>' " +"অথবা '/' চিহà§à¦¨ অথবা কোনো বৈশিষà§à¦Ÿà§à¦¯à¦° উপসà§à¦¥à¦¿à¦¤à¦¿ কামà§à¦¯; সমà§à¦­à¦¬à¦¤ কোনো বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° " +"নামের " +"মধà§à¦¯à§‡ অবৈধ অকà§à¦·à¦° বà§à¦¯à¦¬à¦¹à§ƒà¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"'%1$s' অকà§à¦·à¦° অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤, '%3$s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° '%2$s' বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° মান নিরà§à¦§à¦¾à¦°à¦£à§‡à¦° " +"উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ সমান চিহà§à¦¨à§‡à¦° (=) পরে à¦à¦•টি উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨à§‡à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• অংশ উপসà§à¦¥à¦¿à¦¤à¦¿ " +"পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%2$s' বদà§à¦§ à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° নামের পশà§à¦šà¦¾à¦¤ '%1$s' অকà§à¦·à¦°à§‡à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° বৈধ নয়; অনà§à¦®à§‹à¦¦à¦¿à¦¤ " +"অকà§à¦·à¦° " +"হল '>'" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "'%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ বদà§à¦§ অবসà§à¦¥à¦¾à§Ÿ, বরà§à¦¤à¦®à¦¾à¦¨à§‡ কোনো à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ খোলা অবসà§à¦¥à¦¾à§Ÿ নেই" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "'%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ বদà§à¦§ অবসà§à¦¥à¦¾à§Ÿ, বরà§à¦¤à¦®à¦¾à¦¨à§‡ '%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ খোলা অবসà§à¦¥à¦¾à§Ÿ রয়েছে" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "ডকà§à¦®à§‡à¦¨à§à¦Ÿ সমà§à¦­à¦¬à¦¤ ফাà¦à¦•া অথবা শà§à¦§à§à¦®à¦¾à¦¤à§à¦° শূণà§à¦¯à¦¸à§à¦¥à¦¾à¦¨ উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"তেরছা বনà§à¦§à¦¨à§€à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• চিহà§à¦¨à§‡à¦° '<' ঠিক পরে ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ " +"হয়েছে" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"খোলা à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà¦¸à¦¹ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে - '%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ সরà§à¦¬à¦¶à§‡à¦· " +"খোলা " +"হয়েছিল" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"নথি অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে, <%s/> টà§à¦¯à¦¾à¦— সমাপà§à¦¤à¦¿à¦° জনà§à¦¯ তেরছা বনà§à¦§à¦¨à§€ " +"চিহà§à¦¨à§‡à¦° " +"অনà§à¦¤à¦¿à¦® অংশের উপসà§à¦¥à¦¿à¦¤à¦¿ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° নামের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° নামের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° পà§à¦°à¦¾à¦°à¦®à§à¦­à¦¿à¦• টà§à¦¯à¦¾à¦—ের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° নামের পরে উপসà§à¦¥à¦¿à¦¤ সমান চিহà§à¦¨à§‡à¦° (=) পরে ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে " +"সমাপà§à¦¤ " +"হয়েছে; বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° মান অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° মানের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"'%s' à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿà§‡à¦° অনà§à¦¤à¦¿à¦® টà§à¦¯à¦¾à¦—ের মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে সমাপà§à¦¤ হয়েছে" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"কোনো মনà§à¦¤à¦¬à§à¦¯ অথবা পà§à¦°à¦•à§à¦°à¦¿à§Ÿà¦¾à¦•রণের নিরà§à¦¦à§‡à¦¶à§‡à¦° মধà§à¦¯à§‡ ডকà§à¦®à§‡à¦¨à§à¦Ÿ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦°à§‚পে " +"সমাপà§à¦¤ হয়েছে" + +#: ../glib/goption.c:795 +msgid "Usage:" +msgstr "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦ªà§à¦°à¦£à¦¾à¦²à§€:" + +#: ../glib/goption.c:795 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:911 +msgid "Help Options:" +msgstr "সহায়তা সংকà§à¦°à¦¾à¦¨à§à¦¤ বিকলà§à¦ª:" + +#: ../glib/goption.c:912 +msgid "Show help options" +msgstr "সহায়তা সংকà§à¦°à¦¾à¦¨à§à¦¤ বিকলà§à¦ª পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করা হবে" + +#: ../glib/goption.c:918 +msgid "Show all help options" +msgstr "সহায়তা সংকà§à¦°à¦¾à¦¨à§à¦¤ সমসà§à¦¤ বিকলà§à¦ª পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করা হবে" + +#: ../glib/goption.c:980 +msgid "Application Options:" +msgstr "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•েশন সংকà§à¦°à¦¾à¦¨à§à¦¤ বিকলà§à¦ª:" + +#: ../glib/goption.c:1044 ../glib/goption.c:1114 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "%2$s-র জনà§à¦¯ '%1$s'-র পূরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ মান পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/goption.c:1054 ../glib/goption.c:1122 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%2$s-র জনà§à¦¯ '%1$s'-র পূরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ মান সীমা বহিরà§à¦­à§‚ত" + +#: ../glib/goption.c:1079 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "%2$s-র জনà§à¦¯ '%1$s'-র দà§à¦¬à§€à¦—à§à¦£ মান পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/goption.c:1087 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "%2$s-র জনà§à¦¯ '%1$s'-র দà§à¦¬à§€à¦—à§à¦£ মান সীমা বহিরà§à¦­à§‚ত" + +#: ../glib/goption.c:1373 ../glib/goption.c:1452 +#, c-format +msgid "Error parsing option %s" +msgstr "%s বিকলà§à¦ª পারà§à¦¸ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/goption.c:1483 ../glib/goption.c:1596 +#, c-format +msgid "Missing argument for %s" +msgstr "%s'র আরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/goption.c:2057 +#, c-format +msgid "Unknown option %s" +msgstr "অজানা বিকলà§à¦ª %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ অবজেকà§à¦Ÿ" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ সমসà§à¦¯à¦¾ অথবা কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ অবজেকà§à¦Ÿ" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "মেমরি অবশিষà§à¦Ÿ নেই" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "বà§à¦¯à¦¾à¦•-টà§à¦¯à¦¾à¦• করার সà§à¦¨à¦¿à¦°à§à¦¦à¦¿à¦·à§à¦Ÿ সীমা পূরà§à¦£" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"উলà§à¦²à¦¿à¦–িত বিনà§à¦¯à¦¾à¦¸à¦Ÿà¦¿à¦° মধà§à¦¯à§‡ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ সামগà§à¦°à§€, আংশিক মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "আংশিক মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡à¦° সময় বà§à¦¯à¦¾à¦• রেফারেনà§à¦¸ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿à¦° সীমা পূরà§à¦£" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "নতà§à¦¨ পংকà§à¦¤à¦¿ চিহà§à¦¨à¦•ারী ফà§à¦²à§à¦¯à¦¾à¦—ের অবৈধ সমষà§à¦Ÿà¦¿" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "ভà§à¦² অফসেট" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "শরà§à¦Ÿ utf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "রিকারশন লà§à¦ª" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "অজানা সমসà§à¦¯à¦¾" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "পংকà§à¦¤à¦¿à¦° শেষে \\ উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "পংকà§à¦¤à¦¿à¦° শেষে \\c উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "\\ চিহà§à¦¨à§‡à¦° পরে অজà§à¦žà¦¾à¦¤ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} সংখà§à¦¯à¦¾ নিরà§à¦¦à§‡à¦¶à¦•ের মধà§à¦¯à§‡ উলà§à¦²à¦¿à¦–িত সংখà§à¦¯à¦¾à¦—à§à¦² কà§à¦°à¦®à¦¬à¦¿à¦¹à§€à¦¨" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} কোয়ানà§à¦Ÿà¦¿à¦«à¦¾à§Ÿà¦¾à¦°à§‡à¦° সংখà§à¦¯à¦¾ অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "অকà§à¦·à¦°à§‡à¦° কà§à¦²à¦¾à¦¸à§‡à¦° শেষে ] চিহà§à¦¨ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "অকà§à¦·à¦°à§‡à¦° কà§à¦²à¦¾à¦¸à§‡à¦° মধà§à¦¯à§‡ অবৈধ à¦à¦¸à§à¦•েপ সিকোয়েনà§à¦¸" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "অকà§à¦·à¦°à§‡à¦° কà§à¦²à¦¾à¦¸à§‡à¦° মধà§à¦¯à§‡ উলà§à¦²à¦¿à¦–িত সীমা কà§à¦°à¦®à¦¬à¦¹à¦¿à¦°à§à¦­à§‚ত" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿à¦° জনà§à¦¯ কিছৠউপসà§à¦¥à¦¿à¦¤ নেই" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? বা (?- চিহà§à¦¨à§‡à¦° পরে অজà§à¦žà¦¾à¦¤ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX named কà§à¦²à¦¾à¦¸à¦—à§à¦²à¦¿ শà§à¦§à§à¦®à¦¾à¦¤à§à¦° কà§à¦²à¦¾à¦¸à§‡à¦° মধà§à¦¯à§‡ সমরà§à¦¥à¦¿à¦¤ হবে" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "শেষে ) অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨ নিরà§à¦¦à§‡à¦¶ করা হয়েছে" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "বকà§à¦¤à¦¬à§à¦¯à§‡à¦° পরে ) চিহà§à¦¨ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "রেগà§à¦°à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨ অতà§à¦¯à¦¨à§à¦¤ বড়" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "মেমরি পà§à¦°à¦¾à¦ªà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr "( চিহà§à¦¨ বিনা ) চিহà§à¦¨ পà§à¦°à§Ÿà§‹à¦— করা হয়েছে" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "কোড ওভার-ফà§à¦²à§‹" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "(?< চিহà§à¦¨à§‡à¦° পরে অজà§à¦žà¦¾à¦¤ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "লà§à¦•-বিহাইনà§à¦¡ অà§à¦¯à¦¾à¦¸à¦¾à¦°à¦¶à¦¨à§‡à¦° দৈরà§à¦˜à§à¦¯ সà§à¦¨à¦¿à¦°à§à¦¦à¦¿à¦·à§à¦Ÿ নয়" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "(?(-র পরে তà§à¦°à§à¦Ÿà¦¿à¦ªà§‚রà§à¦£ সংখà§à¦¯à¦¾ অথবা নাম উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "অবসà§à¦¥à¦¾à¦­à¦¿à¦¤à§à¦¤à¦¿à¦• দলের মধà§à¦¯à§‡ দà§à¦Ÿà¦¿à¦° বেশি শà§à¦°à§‡à¦£à§€ উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "(?(-র পরে অà§à¦¯à¦¾à¦¸à¦¾à¦°à¦¶à¦¨ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R অথবা (?[+-]সংখà§à¦¯à¦¾-র পরে ) চিহà§à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা আবশà§à¦¯à¦•" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "অজানা POSIX কà§à¦²à¦¾à¦¸à§‡à¦° নাম" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "POSIX কোলেটিং à¦à¦²à¦¿à¦®à§‡à¦¨à§à¦Ÿ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} অনà§à¦•à§à¦°à¦®à§‡à¦° মধà§à¦¯à§‡ উপসà§à¦¥à¦¿à¦¤ অকà§à¦·à¦°à§‡à¦° মান অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "অবৈধ কনà§à¦¡à¦¿à¦¶à¦¨ (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "লà§à¦•-বিহাইনà§à¦¡ অà§à¦¯à¦¾à¦¸à¦¾à¦°à¦¶à¦¨à§‡à¦° মধà§à¦¯à§‡ \\C অনà§à¦®à§‹à¦¦à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, à¦à¦¬à¦‚ \\u সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "রিকারà§à¦¸à¦¿à¦­ কল-টি সীমাহীন সংখà§à¦¯à¦¾à§Ÿ লà§à¦ª করতে পারবে" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "(?P চিহà§à¦¨à§‡à¦° পরে অজà§à¦žà¦¾à¦¤ অকà§à¦·à¦° উপসà§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨ নামের মধà§à¦¯à§‡ সমাপà§à¦¤à¦¿ নিরà§à¦¦à§‡à¦¶à¦• অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "দà§à¦Ÿà¦¿ named সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨à§‡à¦° কà§à¦·à§‡à¦¤à§à¦°à§‡ à¦à¦•ই নাম পà§à¦°à§Ÿà§‹à¦— করা হয়েছে" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "তà§à¦°à§à¦Ÿà¦¿à¦ªà§‚রà§à¦£ \\P অথবা \\p সিকোয়েনà§à¦¸" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "\\P অথবা \\p-র পরে অজানা পà§à¦°à¦ªà¦¾à¦°à§à¦Ÿà¦¿à¦° নাম" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨à§‡à¦° নাম অতà§à¦¯à¦¾à¦§à¦¿à¦• লমà§à¦¬à¦¾ (সরà§à¦¬à¦¾à¦§à¦¿à¦• ৩২-টি অকà§à¦·à¦°)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "নামসহ অতà§à¦¯à¦¾à¦§à¦¿à¦• সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨ (সরà§à¦¬à¦¾à¦§à¦¿à¦• ১০,০০০)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "অকà§à¦Ÿà¦¾à¦² মান \\377-র অধিক" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "কমà§à¦ªà¦¾à¦‡à¦² করার করà§à¦®à¦•à§à¦·à§‡à¦¤à§à¦° অতিকà§à¦°à¦¾à¦¨à§à¦¤ হয়েছে" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "পূরà§à¦¬à§‡ পরীকà§à¦·à¦¿à¦¤ রেফারেনà§à¦¸ করা সাব-পà§à¦¯à¦¾à¦Ÿà¦¾à¦°à§à¦¨ পাওয়া যায়নি" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE দলের মধà§à¦¯à§‡ à¦à¦•াধিক বà§à¦°à¦¾à¦žà§à¦š উপসà§à¦¥à¦¿à¦¤ রয়েছে" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "বিসংগত NEWLINE বিকলà§à¦ª" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g à¦à¦° পরে থাকবে না কোনো braced, angle-bracketed, বা quoted নাম বা নমà§à¦¬à¦°, বা " +"à¦à¦•টি সরল সংখà§à¦¯à¦¾" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "à¦à¦•টি সংখà§à¦¯à¦¾à¦¬à¦¿à¦¶à¦¿à¦·à§à¦Ÿ রেফারেনà§à¦¸ শূনà§à¦¯ হতে পারে না" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "(*ACCEPT), (*FAIL), বা (*COMMIT) à¦à¦° জনà§à¦¯ à¦à¦•টি অারà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ অনà§à¦®à§‹à¦¦à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) সà§à¦¬à§€à¦•ৃত নয়" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "নমà§à¦¬à¦° অতà§à¦¯à¦¨à§à¦¤ বড়" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& à¦à¦° পরে অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤ উপধরণ নাম" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ à¦à¦° পরে পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ সংখà§à¦¯à¦¾" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "JavaScript সà§à¦¸à¦‚গততা মোডে ] à¦à¦•টি অবৈধ ডেটা অকà§à¦·à¦°" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "à¦à¦•ই সংখà§à¦¯à¦¾à¦° উপধরণের পৃথক নাম অনà§à¦®à§‹à¦¦à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) অবশà§à¦¯à¦‡ à¦à¦• অারà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ থাকতে হবে" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c à¦à¦° পরে অবশà§à¦¯à¦‡ ASCII অকà§à¦·à¦° থাকতে হবে" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k à¦à¦° পরে braced, angle-bracketed, বা quoted নাম নেই" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N à¦à¦•টি কà§à¦²à¦¾à¦¸à§‡ সমরà§à¦¥à¦¿à¦¤ নয়" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "অতà§à¦¯à¦¾à¦§à¦¿à¦• ফরোয়ারà§à¦¡ রেফারেনà§à¦¸" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), বা (*THEN) ঠনাম অতà§à¦¯à¦¨à§à¦¤ বড়" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... অনà§à¦•à§à¦°à¦®à§‡à¦° মধà§à¦¯à§‡ উপসà§à¦¥à¦¿à¦¤ অকà§à¦·à¦°à§‡à¦° মান অতà§à¦¯à¦¾à¦§à¦¿à¦• বড়" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "রেগà§à¦²à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨ %s-র মিল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE লাইবà§à¦°à§‡à¦°à¦¿ UTF8 সমরà§à¦¥à¦¨ বিনা কমà§à¦ªà¦¾à¦‡à¦² করা হয়েছে" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE লাইবà§à¦°à§‡à¦°à¦¿ UTF8 বৈশিষà§à¦Ÿà§à¦¯à§‡à¦° সমরà§à¦¥à¦¨ বিনা কমà§à¦ªà¦¾à¦‡à¦² করা হয়েছে" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE লাইবà§à¦°à§‡à¦°à¦¿ অসà§à¦¸à¦‚গত বিকলà§à¦ªà§‡à¦° সংগে à¦à¦•তà§à¦°à¦¿à¦¤" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "রেগà§à¦²à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨ %s, %d অকà§à¦·à¦°à§‡ কমà§à¦ªà¦¾à¦‡à¦² করতে সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "রেগà§à¦²à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨ %s-র সরà§à¦¬à§‹à¦¤à§à¦¤à¦® বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡ সমসà§à¦¯à¦¾: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "হেকà§à¦¸à¦¾à¦¡à§‡à¦¸à¦¿à¦®à¦¾à¦² সংখà§à¦¯à¦¾ অথবা '}' পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "হেকà§à¦¸à¦¾à¦¡à§‡à¦¸à¦¿à¦®à¦¾à¦² সংখà§à¦¯à¦¾ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "সিমà§à¦¬à¦²à¦¿à¦• রেফারেনà§à¦¸à§‡à¦° মধà§à¦¯à§‡ '<' অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "সিমà§à¦¬à¦²à¦¿à¦• রেফারেনà§à¦¸ অসমà§à¦ªà§‚রà§à¦£" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "সিমà§à¦¬à¦²à¦¿à¦• রেফারেনà§à¦¸à§‡à¦° মধà§à¦¯à§‡ অকà§à¦·à¦° সংখà§à¦¯à¦¾ শূণà§à¦¯" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "সংখà§à¦¯à¦¾ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "অবৈধ সিমà§à¦¬à¦²à¦¿à¦• রেফারেনà§à¦¸" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "অনà§à¦¤à§‡ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ '\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "অজানা à¦à¦¸à§à¦•েপ সিকোয়েনà§à¦¸" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "পà§à¦°à¦¤à¦¿à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾à¦° টেকà§à¦¸à¦Ÿ \"%s\", %lu অকà§à¦·à¦°à§‡ পারà§à¦¸ করতে সমসà§à¦¯à¦¾: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "উদà§à¦§à§ƒà¦¤à¦¿à¦° অংশ উদà§à¦§à¦¿à¦¤à¦¿ চিহà§à¦¨ দà§à¦¬à¦¾à¦°à¦¾ আরমà§à¦­ করা হয়নি" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "কমানà§à¦¡-লাইন অথবা শেল'র উদà§à¦§à§ƒà¦¤à¦¿à¦° মধà§à¦¯à§‡ অসংগত উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "'\\' অকà§à¦·à¦°à§‡à¦° পরে টেকà§à¦¸à¦Ÿ সমাপà§à¦¤ হয়েছে। (সংশà§à¦²à¦¿à¦·à§à¦Ÿ টেকà§à¦¸à¦Ÿ হল '%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"%c'র কà§à¦·à§‡à¦¤à§à¦°à§‡ সà§à¦¸à¦‚গত উদà§à¦§à§ƒà¦¤à¦¿ চিহà§à¦¨ পাওয়া যায়নি। (সংশà§à¦²à¦¿à¦·à§à¦Ÿ টেকà§à¦¸à¦Ÿ হল '%s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "টেকà§à¦¸à¦Ÿ ফাà¦à¦•া (অথবা শà§à¦§à§à¦®à¦¾à¦¤à§à¦° শূণà§à¦¯à¦¸à§à¦¥à¦¾à¦¨à¦¸à¦¹)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ থেকে তথà§à¦¯ পড়তে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ থেকে তথà§à¦¯ পড়ার সময় select() সংকà§à¦°à¦¾à¦¨à§à¦¤ অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ তà§à¦°à§à¦Ÿà¦¿ (%s)" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid()'ঠঅপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ তà§à¦°à§à¦Ÿà¦¿ (%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "%ld কোড সমেত চাইলà§à¦¡ পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করা হয়েছে" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "%ld সংকেত দà§à¦¬à¦¾à¦°à¦¾ চাইলà§à¦¡ পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ সমাপà§à¦¤ হয়েছে" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "%ld সংকেত দà§à¦¬à¦¾à¦°à¦¾ চাইলà§à¦¡ পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ থামানো হয়েছে" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "অসà§à¦¬à¦¾à¦­à¦¾à¦¬à¦¿à¦• ভাবে চাইলà§à¦¡ পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করা হয়েছে" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "চাইলà§à¦¡ পাইপ থেকে পড়তে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "'%s' ডিরেকà§à¦Ÿà¦°à¦¿à¦¤à§‡ পরিবরà§à¦¤à¦¨ করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ \"%s\" চালাতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸à§‡à¦° আউটপà§à¦Ÿ অথবা ইনপà§à¦Ÿ রি-ডাইরেকà§à¦Ÿ করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ fork করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ \"%s\" কারà§à¦¯à¦•র করতে অজানা সমসà§à¦¯à¦¾" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "চাইলà§à¦¡ pid পাইপ থেকে পরà§à¦¯à¦¾à¦ªà§à¦¤ তথà§à¦¯ পড়তে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ থেকে তথà§à¦¯ পড়তে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸à§‡à¦° সাথে যোগাযোগের উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পাইপ নিরà§à¦®à¦¾à¦£à§‡ বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ কারà§à¦¯à¦•র করতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à§‡à¦° নাম অবৈধ: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d'ঠআরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ ভেকà§à¦Ÿà¦°'ঠউলà§à¦²à¦¿à¦–িত পংকà§à¦¤à¦¿ বৈধ নয়: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "পরিবেশের মধà§à¦¯à§‡ উলà§à¦²à¦¿à¦–িত পংকà§à¦¤à¦¿ বৈধ নয়: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "সকà§à¦°à¦¿à§Ÿ ডিরেকà§à¦Ÿà¦°à¦¿ বৈধ নয়: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "সহায়ক পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® চালাতে বà§à¦¯à¦°à§à¦¥ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"চাইলà§à¦¡ পà§à¦°à¦¸à§‡à¦¸ থেকে তথà§à¦¯ পড়ার সময় g_io_channel_win32_poll()'ঠঅপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ " +"তà§à¦°à§à¦Ÿà¦¿" + +#: ../glib/gutf8.c:780 +msgid "Failed to allocate memory" +msgstr "মেমরি নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করতে বà§à¦¯à¦°à§à¦¥" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "অকà§à¦·à¦°à¦Ÿà¦¿ UTF-8'র আয়তà§à¦¬à§‡à¦° বাইরে" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "রূপানà§à¦¤à¦° করার উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পà§à¦°à¦¦à¦¤à§à¦¤ তথà§à¦¯à§‡à¦° মধà§à¦¯à§‡ অবৈধ ধারা" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "অকà§à¦·à¦°à¦Ÿà¦¿ UTF-16'র আয়তà§à¦¬à§‡à¦° বাইরে" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u বাইট" +msgstr[1] "%u বাইট" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f °C" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f মেগাবাইট" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f গিগাবাইট" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s বাইট" +msgstr[1] "%s বাইট" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f কিলোবাইট" + +msgid "workspace limit for empty substrings reached" +msgstr "ফাà¦à¦•া সাব-সà§à¦Ÿà§à¦°à¦¿à¦‚-র করà§à¦®à¦•à§à¦·à§‡à¦¤à§à¦°à§‡à¦° সীমা পূরà§à¦£" + +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" +"হরফের ছাà¦à¦¦ পরিবরà§à¦¤à¦¨à¦•ারী à¦à¦¸à§à¦•েপ অকà§à¦·à¦° (\\l, \\L, \\u, \\U) à¦à¦–ানে বà§à¦¯à¦¬à¦¹à¦¾à¦° করা " +"সমà§à¦­à¦¬ " +"নয়" + +msgid "repeating a DEFINE group is not allowed" +msgstr "কোনো DEFINE দলের পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿ করা যাবে না" + +msgid "File is empty" +msgstr "ফাইল ফাà¦à¦•া" + +msgid "No service record for '%s'" +msgstr "'%s'-র পরিসেবার কোনো রেকরà§à¦¡ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤" + +msgctxt "GDateTime" +msgid "am" +msgstr "পূরà§à¦¬à¦¾à¦¹à§à¦¨" + +msgctxt "GDateTime" +msgid "pm" +msgstr "অপরাহà§à¦¨" + +msgid "Reached maximum data array limit" +msgstr "ডাটা অà§à¦¯à¦¾à¦°à§‡à¦° সরà§à¦¬à¦¾à¦§à¦¿à¦• সীমা উপসà§à¦¥à¦¿à¦¤ হয়েছে" + +msgid "do not hide entries" +msgstr "à¦à¦¨à§à¦Ÿà§à¦°à¦¿ আড়াল করা হবে না" + +msgid "use a long listing format" +msgstr "লং লিসà§à¦Ÿà¦¿à¦‚ বিনà§à¦¯à¦¾à¦¸ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হবে" + +msgctxt "full month name with day" +msgid "January" +msgstr "জানà§à§Ÿà¦¾à¦°à¦¿" + +msgctxt "full month name with day" +msgid "February" +msgstr "ফেবà§à¦°à§à§Ÿà¦¾à¦°à¦¿" + +msgctxt "full month name with day" +msgid "March" +msgstr "মারà§à¦š" + +msgctxt "full month name with day" +msgid "April" +msgstr "à¦à¦ªà§à¦°à¦¿à¦²" + +msgctxt "full month name with day" +msgid "May" +msgstr "মে" + +msgctxt "full month name with day" +msgid "June" +msgstr "জà§à¦¨" + +msgctxt "full month name with day" +msgid "July" +msgstr "জà§à¦²à¦¾à¦‡" + +msgctxt "full month name with day" +msgid "August" +msgstr "আগসà§à¦Ÿ" + +msgctxt "full month name with day" +msgid "September" +msgstr "সেপà§à¦Ÿà§‡à¦®à¦¬à¦°" + +msgctxt "full month name with day" +msgid "October" +msgstr "অকà§à¦Ÿà§‹à¦¬à¦°" + +msgctxt "full month name with day" +msgid "November" +msgstr "নভেমà§à¦¬à¦°" + +msgctxt "full month name with day" +msgid "December" +msgstr "ডিসেমà§à¦¬à¦°" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "জানà§à§Ÿà¦¾à¦°à¦¿" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ফেবà§à¦°à§à§Ÿà¦¾à¦°à¦¿" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "মারà§à¦š" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "à¦à¦ªà§à¦°à¦¿à¦²" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "মে" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "জà§à¦¨" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "জà§à¦²à¦¾à¦‡" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "আগসà§à¦Ÿ" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "সেপà§à¦Ÿà§‡à¦®à§à¦¬à¦°" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "অকà§à¦Ÿà§‹à¦¬à¦°" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "নভেমà§à¦¬à¦°" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ডিসেমà§à¦¬à¦°" + +#, fuzzy +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "'%s' ফাইল খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: fdopen() বিফল: %s" + +#, fuzzy +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "'%s' ফাইলে লিখতে বà§à¦¯à¦°à§à¦¥: fsync() বিফল: %s" + +#, fuzzy +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "'%s' ফাইল খà§à¦²à¦¤à§‡ বà§à¦¯à¦°à§à¦¥: fdopen() বিফল: %s" + +#, fuzzy +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "কি-ফাইলের মধà§à¦¯à§‡ '%s' কি উপসà§à¦¥à¦¿à¦¤ রয়েছে যার মান বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা সমà§à¦­à¦¬ নয়।" + +#, fuzzy +#~ msgid "Error statting directory '%s': %s" +#~ msgstr "`%s' ডিরেকà§à¦Ÿà¦°à¦¿ তৈরি করতে তà§à¦°à§à¦Ÿà¦¿: %s" + +#, fuzzy +#~ msgid "Error stating file '%s': %s" +#~ msgstr "'%s' ফাইল পড়তে সমসà§à¦¯à¦¾: %s" + +#, fuzzy +#~ msgid "Error connecting: " +#~ msgstr "সংযোগে তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#, fuzzy +#~ msgid "Error connecting: %s" +#~ msgstr "সংযোগে তà§à¦°à§à¦Ÿà¦¿: %s\n" + +#, fuzzy +#~ msgid "Error reading from unix: %s" +#~ msgstr "ফাইল থেকে পড়তে সমসà§à¦¯à¦¾: %s" + +#, fuzzy +#~ msgid "Error closing unix: %s" +#~ msgstr "ফাইল বনà§à¦§ করতে সমসà§à¦¯à¦¾: %s" + +#, fuzzy +#~ msgid "Error writing to unix: %s" +#~ msgstr "ফাইলে লিখতে সমসà§à¦¯à¦¾: %s" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "ডিরেকà§à¦Ÿà¦°à¦¿à¦° উপর ডিরেকà§à¦Ÿà¦°à¦¿ সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করা যাবে না" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "রূপানà§à¦¤à¦° করার উদà§à¦¦à§‡à¦¶à§à¦¯à§‡ পà§à¦°à¦¦à¦¤à§à¦¤ তথà§à¦¯à§‡à¦° মধà§à¦¯à§‡ অবৈধ ধারা" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "xmllint দিয়ে ইনপà§à¦Ÿ ফাইল পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ করতে তà§à¦°à§à¦Ÿà¦¿:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata দিয়ে ইনপà§à¦Ÿ ফাইল পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ করতে তà§à¦°à§à¦Ÿà¦¿:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "অপেকà§à¦·à¦¾à¦°à¦¤ তà§à¦°à§à¦Ÿà¦¿ পà§à¦°à¦¾à¦ªà§à¦¤ করতে বà§à¦¯à¦°à§à¦¥: %s" diff --git a/po/bs.po b/po/bs.po new file mode 100644 index 0000000..1ec2e12 --- /dev/null +++ b/po/bs.po @@ -0,0 +1,4680 @@ +# translation of glib to Bosnian +# This file is distributed under the same license as the glib package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER, 2004. +# Kenan Hadžiavdić , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.glib-2-4\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2015-02-27 07:51+0000\n" +"PO-Revision-Date: 2015-02-27 15:00+0100\n" +"Last-Translator: Samir Ribic \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" +"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Launchpad-Export-Date: 2015-02-15 06:18+0000\n" +"X-Generator: Launchpad (build 17341)\n" + +#: ../gio/gapplication.c:531 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"UÄ‘i u GApplication servisni mod (koriÅ¡tenje iz D-Bus servisnih datoteka)" + +#: ../gio/gapplication.c:536 +msgid "GApplication options" +msgstr "GApplication opcije" + +#: ../gio/gapplication.c:536 +msgid "Show GApplication options" +msgstr "Prikaži GApplication opcije" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:485 ../gio/gsettings-tool.c:521 +msgid "Print help" +msgstr "Prikaži pomoć" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:486 +#: ../gio/gresource-tool.c:554 +msgid "[COMMAND]" +msgstr "[NAREDBA]" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "IspiÅ¡i verziju" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:527 +msgid "Print version information and exit" +msgstr "IspiÅ¡i podatke o izdanju i izaÄ‘i" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Lista aplikacija" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Lista instaliranih D-Bus aplikacija sa aktiviranjem (kao .desktop datoteke)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "Pokreni aplikaciju" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "Pokreni aplikaciju(sa otvaranjem opcionalnih datoteka)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [Datoteka...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "Aktiviraj akciju" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "Pozovi akciju nad aplikacijom" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Lista dostupnih akcija" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "Lista statiÄkih akcija za aplikaciju (iz .desktop datoteke)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "KOMANDA" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "Komanda za printenje detalja pomaže za" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Identifikator aplikacije u D-Bus formatu (eg: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:492 +#: ../gio/gresource-tool.c:558 +msgid "FILE" +msgstr "DATOTEKA" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "Opcionalni putevi ili ime datoteke ili adresa za otvaranje" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "AKCIJA" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "Ime akcije za pokretanje" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARAMETAR" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Opcionalni parametar za pozivanje akcije, u GVariant formatu" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:523 +#: ../gio/gsettings-tool.c:607 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Nepoznata komanda %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "Upotreba:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:548 +#: ../gio/gsettings-tool.c:641 +msgid "Arguments:\n" +msgstr "Argumenti:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGUMENTI...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Komande:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Koristi '%s help komandu' za dobijanje detaljne pomoći.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s komanda zahtijeva ID aplikacije za direktni pristup\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "neispravan ID aplikacije: '%s'\n" + +#. Translators: %s is replaced with a command nami liki 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' ne prima argumenta\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "nemoguće pristupiti D-Bus -u : %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "greska prilikom slanja %s poruke aplikaciji %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "ime akcije mora biti dato poslije ID-a aplikacije\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "neispravno ime akcije: '%s'\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "greÅ¡ka pri analizi parametra akcije: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "akcija prima maksimalno jedan parametar\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "komanda lista akcija prima samo ID aplikacije" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "nije moguce pronaći datoteku radne povrÅ¡i za aplikaciju %s\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"nepoznata naredba: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:376 +#: ../gio/ginputstream.c:614 ../gio/ginputstream.c:1013 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:830 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Prevelika brojÄana vrijednost je proslijeÄ‘ena u %s" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Pozicioniranje nije podrzano na osnovnom toku" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Ne može se skratiti GBufferedInputStream" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1202 +#: ../gio/giostream.c:278 ../gio/goutputstream.c:1654 +msgid "Stream is already closed" +msgstr "Tok je već zatvoren" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Skraćivanje nije podržano na osnovnom toku" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1421 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "Radnja je prekinuta" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Neispravan objekat, nije pokrenuto" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Nepotpun niz bajtova na ulazu" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Nema dovoljno mjesta u odrediÅ¡tu" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "Nevažeći niz bajtova u ulaznim podacima za pretvaranje" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "GreÅ¡ka tokom pretvaranja: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "Nije podržano pokretanje uz mogućnost prekida" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Pretvaranje iz skupa znakova '%s' u '%s' nije podržano" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Nisam mogao pokrenuti pretvaranje iz '%s' u '%s'" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s vrsta" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "Nepoznata vrsta" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s vrsta datoteke" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "Gakreditacija nije podržana na operativnom sistemu" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "Nemate podrÅ¡ku za Gakreditacije na ovoj platformi" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials ne sadrži IB procesa na ovom operativnom sistemu" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "OponaÅ¡anje akreditiva nije moguće na ovom OS" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "NeoÄekivan, preran kraj toka" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "KljuÄ â€ž%s“ nije podržan unutar adrese „%s“" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"Adresa „%s“ je neispravna (potrebna samo jedna putanja, privremeni " +"direktorijum ili apstraktni kljuÄ)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "BeznaÄajna kombinacija kljuÄ/vrednost unutar adrese „%s“" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "GreÅ¡ka unutar adrese „%s“ — port nije ispravno upisan" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "GreÅ¡ka unutar adrese „%s“ — atribut familije je neispravno upisan" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "Element adrese „%s“ ne sadrži dvije taÄke (:)" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" +"Par kljuÄ/vrijednost %d, „%s“, u elementu adrese „%s“ ne sadrži znak " +"jednakosti" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"GreÅ¡ka pri neizbjegavanju kljuÄa ili vrijednosti u paru KljuÄ/Vrijednosti %" +"d, „%s“, u elementu adrese „%s“" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"GreÅ¡ka u adresi „%s“ — Unix-ov prijenos zahtijeva postavljanje ili kljuÄa " +"„path“ (putanja) ili „abstract“ (rezime)" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" +"GreÅ¡ka unutar adrese „%s“ — atribut domaćina nedostaje ili je neispravan" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "GreÅ¡ka unutar adrese „%s“ — port nedostaje ili je neispravan" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" +"GreÅ¡ka unutar adrese „%s“ — atribut datoteke jednokratnih sluÄajnih brojeva " +"nedostaje ili je neispravan" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "GreÅ¡ka u samopokretanju: " + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "Nepoznati ili nepodržani prijenos „%s“ za adrese „%s“" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "" +"GreÅ¡ka prilikom otvaranja datoteke jednokratnih sluÄajnih brojeva „%s“: %s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "GreÅ¡ka pri Äitanju datoteke jednokratnih sluÄajnih brojeva „%s“: %s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "" +"GreÅ¡ka pri Äitanju datoteke jednokratnih sluÄajnih brojeva „%s“, oÄekivano " +"16 bajtova, a dobijeno %d" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "" +"GreÅ¡ka prilikom upisa sadržaja datoteke jednokratnih sluÄajnih brojeva „%s“ " +"u tok:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "Data adresa je prazna" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Ne mogu pokrenuti sabirnicu poruka kada se obavlja" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ne mogu da pokrenem magistralu poruka bez identifikacije maÅ¡ine: " + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "GreÅ¡ka pri pokretanju komandne linije „%s“: " + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Unesi bilo koji karakter da zatvoriÅ¡ prozor)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Sesijski dbus ne radi a automatsko pokretanje nije uspjelo" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Ne mogu da odredim adresu magistrale sesije (nije napravljeno za ovaj " +"operativni sistem)" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"Ne mogu da odredim adresu magistrale sesije iz promjenljive okruženja " +"DBUS_STARTER_BUS_TYPE — nepoznata vrijednost „%s“" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ne mogu da odredim adresu magistrale sesije jer nije postavljena " +"promjenljiva okruženja DBUS_STARTER_BUS_TYPE" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "Nepoznata tip magistrale %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "NeoÄekivani nedostatak sadržaja pri Äitanju linije" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "NeoÄekivani nedostatak sadržaja pri (sigurnom) Äitanju linije" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"IstroÅ¡eni su svi dostupni mehanizmi prijavljivanja (pokuÅ¡ano: %s) (dostupno: " +"%s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "PoniÅ¡teno preko GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "GreÅ¡ka prilikom dobavljanja podataka za direktorijum „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Ovlašćenja nad direktorijem „%s“ su neispravna. OÄekivana vrijednost je bila " +"0700, a dobijeno je 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "GreÅ¡ka prilikom pravljenja direktorija '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "GreÅ¡ka prilikom otvaranja prstena kljuÄeva „%s“ za Äitanje: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "Linija %d prstena kljuÄeva na „%s“ sa sadržajem „%s“ nije ispravna" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"Prvi token linije %d prstena kljuÄeva na „%s“ sa sadržajem „%s“ nije ispravan" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"Drugi token linije %d prstena kljuÄeva na „%s“ sa sadržajem „%s“ nije " +"ispravan" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "Nisam naÅ¡ao kolaÄić sa identifikacijom %d u prstenu kljuÄeva na „%s“" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "GreÅ¡ka pri brisanju zaostale datoteke zakljuÄavanja „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "GreÅ¡ka pri pravljenju datoteke zakljuÄavanja „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "" +"GreÅ¡ka prilikom zatvaranja (nepovezane) datoteke zakljuÄavanja „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "GreÅ¡ka prilikom odvezivanja datoteke zakljuÄavanja „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "GreÅ¡ka prilikom otvaranja privjeska kljuÄeva „%s“ za pisanje: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(Dodatno, otpuÅ¡tanje kljuÄa sa „%s“ takoÄ‘e nije uspjelo: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "Veza je zatvorena" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "Vrijeme je isteklo" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "NaiÅ¡ao sam na nepodržane oznake pri izgradnji klijentskog djela veze" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"Nema interfejsa „org.freedesktop.DBus.Properties“ u objektu na putanji %s" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "Nema osobine „%s“" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "Osobina „%s“ nije Äitljiva" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "Nije moguće pisanje osobine „%s“" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"GreÅ¡ka pri postavljanju osobine „%s“: OÄekivani tip je bio „%s“, a dobijen " +"je „%s“" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "Nema interfejsa „%s“" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "Nema takvog interfejsa" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "Nema interfejsa „%s“ u objektu na putanji %s" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "Nema metoda „%s“" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "Tip poruke, „%s“, ne odgovara oÄekivanom tipu „%s“" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Objekat je već izvezen za interfejs %s na %s" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "Metod „%s“ je vratio tip „%s“, ali je bio oÄekivan „%s“" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "Metod „%s“ na interfejsu „%s“ sa potpisom „%s“ ne postoji" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Poddrvo je već izvezeno za %s" + +#: ../gio/gdbusmessage.c:1244 +msgid "type is INVALID" +msgstr "tip je INVALID" + +#: ../gio/gdbusmessage.c:1255 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL poruka: PATH ili MEMBER polja zaglavlja nedostaju" + +#: ../gio/gdbusmessage.c:1266 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN poruka: REPLY_SERIAL polje zaglavlja nedostaje" + +#: ../gio/gdbusmessage.c:1278 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR poruka: REPLY_SERIAL ili ERROR_NAME polja zaglavlja nedostaju" + +#: ../gio/gdbusmessage.c:1291 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL poruka: PATH, INTERFACE ili MEMBER polja zaglavlja nedostaju" + +#: ../gio/gdbusmessage.c:1299 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL poruka: PATH polje zaglavlja koristi rezervisanu vrijednost /org/" +"freedesktop/DBus/Local" + +#: ../gio/gdbusmessage.c:1307 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL poruka: INTERFACE polje zaglavlja koristi rezervisanu vrijednost org." +"freedesktop.DBus.Local" + +#: ../gio/gdbusmessage.c:1355 ../gio/gdbusmessage.c:1415 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "PokuÅ¡ao da Äitam %lu bajt, ali dobio samo %lu" +msgstr[1] "PokuÅ¡ao da Äitam %lu bajta, ali dobio samo %lu" +msgstr[2] "PokuÅ¡ao da Äitam %lu bajtova, ali dobio samo %lu" + +#: ../gio/gdbusmessage.c:1369 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "OÄekivao sam NUL bajt posle niske „%s“, ali sam naÅ¡ao bajt %d" + +#: ../gio/gdbusmessage.c:1388 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"OÄekivah ispravnu UTF-8 nisku, ali naÄ‘oh neispravne bajtove na bajt " +"pomjeraju %d (dužina niske je %d). Ispravna niska do tog djela je bila „%s“" + +#: ../gio/gdbusmessage.c:1587 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "RaÅ¡Älanjena vrijednost „%s“ nije ispravna putanja objekta D-Bus" + +#: ../gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "RaÅ¡Älanjena vrijednost „%s“ nije ispravan potpis D-Bus" + +#: ../gio/gdbusmessage.c:1656 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"NaÄ‘en niz dužine %u bajt. Maaksimalna dužina je 2<<26 bajta (64 MiB)." +msgstr[1] "" +"NaÄ‘en niz dužine %u bajta. Maaksimalna dužina je 2<<26 bajta (64 MiB)." +msgstr[2] "" +"NaÄ‘en niz dužine %u bajtova. Maaksimalna dužina je 2<<26 bajta (64 MiB)." + +#: ../gio/gdbusmessage.c:1676 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Niz tipa 'a%c' ocekuje da ima dužinu %u bajtova, a pronaÄ‘eno %u bajtova u " +"dužini" + +#: ../gio/gdbusmessage.c:1843 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "RaÅ¡Älanjena vrijednost „%s“ za varijantu nije ispravan potpis D-Bus" + +#: ../gio/gdbusmessage.c:1867 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"GreÅ¡ka pri deserijalizaciji Gvariant-a sa nizom vrste „%s“ iz žiÄanog " +"formata D-Bus" + +#: ../gio/gdbusmessage.c:2051 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"Neispravna vrijednost za krajnjost. OÄekivao sam 0x6c ('l') ili 0x42 ('B') " +"ali sam naÅ¡ao vrijednost 0x%02x" + +#: ../gio/gdbusmessage.c:2064 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Neispravna glavno izdanje protokola. OÄekivano 1, ali naÄ‘eno %d" + +#: ../gio/gdbusmessage.c:2120 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" +"Potpis zaglavlja sa potpisom „%s“ je naÄ‘en, ali je tijelo poruke prazno" + +#: ../gio/gdbusmessage.c:2134 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" +"RaÅ¡Älanjena vrijednost „%s“ nije ispravan potpis D-Bus (za tijelo poruke)" + +#: ../gio/gdbusmessage.c:2164 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Nema zaglavlja potpisa u poruci ali je tijelo poruke %u bajt" +msgstr[1] "Nema zaglavlja potpisa u poruci ali je tijelo poruke %u bajta" +msgstr[2] "Nema zaglavlja potpisa u poruci ali je tijelo poruke %u bajtova" + +#: ../gio/gdbusmessage.c:2174 +msgid "Cannot deserialize message: " +msgstr "Ne mogu da deserijalizujem poruku: " + +#: ../gio/gdbusmessage.c:2515 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"GreÅ¡ka pri serijalizaciji Gvariant-a sa nizom vrste „%s“ iz žiÄanog formata " +"D-Bus" + +#: ../gio/gdbusmessage.c:2652 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"Poruka ima %d datoteÄnih deskriptora ali polje zaglavlja indicira %d " +"datoteÄnih deskriptora" + +#: ../gio/gdbusmessage.c:2660 +msgid "Cannot serialize message: " +msgstr "Ne mogu da serijalizujem poruku: " + +#: ../gio/gdbusmessage.c:2704 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "Tijelo poruke ima potpis „%s“, ali nedostaje zaglavlje potpisa" + +#: ../gio/gdbusmessage.c:2714 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '%" +"s'" +msgstr "" +"Tijelo poruke ima tip potpisa „%s“, ali potpis u polju zaglavlja je „%s“" + +#: ../gio/gdbusmessage.c:2730 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "Tijelo poruke je prazno,,, ali je potpis u polju zaglavlja „(%s)“" + +#: ../gio/gdbusmessage.c:3280 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "Dobijena je greÅ¡ka sa tijelom poruke tipa „%s“" + +#: ../gio/gdbusmessage.c:3288 +msgid "Error return with empty body" +msgstr "Dobijena je greÅ¡ka sa praznim tijelom poruke" + +#: ../gio/gdbusprivate.c:2085 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Ne mogu dobaviti hardverski profil: %s" + +#: ../gio/gdbusprivate.c:2130 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Ne mogu da uÄitam „/var/lib/dbus/machine-id“ ili „/etc/machine-id:“ " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "GreÅ¡ka pri pozivu StartServiceByName za %s: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "NeoÄekivan odgovor %d od StartServiceByName(„%s“) metoda" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ne mogu da pozovem metod; proksi je za već poznato ime bez vlasnika, a " +"napravljen je bez G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START oznake" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "Apstraktni imenski prostor nije podržan" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Ne mogu da navedem datoteku jednokratnih sluÄajnih brojeva pri povezivanju " +"sa serverom" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "" +"GreÅ¡ka prilikom upisa datoteke jednokratnih sluÄajnih brojeva na „%s“: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "Niz „%s“ nije ispravni GJIB za D-Bus" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "Ne mogu da sluÅ¡am na nepodržanom prijenosnom mehanizmu „%s“" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"Naredbe:\n" +" help Prikazuje ovu informaciju\n" +" introspect Ispituje udaljeni objekat\n" +" monitor Nadgleda udaljeni objekat\n" +" call Poziva naÄin na udaljenom objektu\n" +" emit OdaÅ¡ilja signal\n" +"\n" +"Koristite „%s NAREDBA --help“ da dobijete pomoć za pojedinaÄne naredbe.\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "GreÅ¡ka: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "GreÅ¡ka pri raÅ¡Älanjivanju XML-a dobijenog ispitivanjem: %s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "Povezivanje na sistemsku magistrali" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "Povezivanje na magistralu sesije" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "Povezivanje na zadatu D-bus adresu" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "Opcije krajnje taÄke veze:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "Opcije koje odreÄ‘uju krajnju taÄku veze" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nije navedena krajnja taÄka veze" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Navedeno viÅ¡e krajnjih taÄaka veze" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" +"Upozorenje: Prema podacima dobijenim ispitivanjem, interfejs „%s“ ne " +"postoji\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"Upozorenje: Prema podacima dobijenim ispitivanjem, metod „%s“ ne postoji na " +"interfejsu „%s“\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "Opcionalna destinacija signala (jedinstveno ime)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "Putanja objekta za emitovanje signala" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "Naziv signala i suÄelja" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "Emituje signal." + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "GreÅ¡ka u povezivanju: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "GreÅ¡ka: nije izabrana putanja objekta\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "GreÅ¡ka: %s nije ispravna putanja do objekata\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "GreÅ¡ka: signal nije naveden.\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "GreÅ¡ka: signal mora biti potpuno - kvalifikovano ime.\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv suÄelja\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv Älana\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv jedinstvene magistrale\n" + +#. Usi the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "GreÅ¡ka pri obradi parametra %d: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "GreÅ¡ka puÅ¡tanja veze: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "OdrediÅ¡no ime na kome treba pozvati metod" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "Putanja objekta na kome treba pozvati metod" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "Ime metoda i interfejsa" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "Vrijeme isteka u sekundama" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "Pozivanje metoda na udaljenom objektu." + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "GreÅ¡ka: Nije izabrano odrediÅ¡te\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "GreÅ¡ka: Nije izabrana putanja do objekta\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "GreÅ¡ka: Ime naÄina nije odreÄ‘eno\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "GreÅ¡ka: Ime naÄina „%s“ nije odreÄ‘eno\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "GreÅ¡ka pri obradi parametra %d vrste „%s“: %s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "OdrediÅ¡no ime za ispitivanje" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "Putanja objekta za ispitivanje" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "Å tampaj XML" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "Preispituje Älanove" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "Samo Å¡tampa svojstva" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "Ispitivanje udaljenog objekta." + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "OdrediÅ¡no ime za nadgledanje" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "Putanja objekta za nadgledanje" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "Nadgledanje udaljenog objekta." + +#: ../gio/gdesktopappinfo.c:1999 ../gio/gdesktopappinfo.c:4530 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "Neimenovano" + +#: ../gio/gdesktopappinfo.c:2408 +msgid "Desktop file didn't specify Exec field" +msgstr "Datoteka za radnu povrÅ¡ ne sadrži Exec unos" + +#: ../gio/gdesktopappinfo.c:2693 +msgid "Unable to find terminal required for application" +msgstr "Ne mogu da naÄ‘em terminal radi pokretanja ovog programa" + +#: ../gio/gdesktopappinfo.c:3114 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "Ne mogu da napravim fasciklu za korisnikova podeÅ¡avanja %s: %s" + +#: ../gio/gdesktopappinfo.c:3118 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "Ne mogu da napravim fasciklu za korisnikova MIME podeÅ¡avanja %s: %s" + +#: ../gio/gdesktopappinfo.c:3358 ../gio/gdesktopappinfo.c:3382 +msgid "Application information lacks an identifier" +msgstr "Aplikacijskoj informaciji nedostaje identifikator" + +#: ../gio/gdesktopappinfo.c:3615 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Ne mogu da napravim datoteku radne povrÅ¡i %s" + +#: ../gio/gdesktopappinfo.c:3749 +#, c-format +msgid "Custom definition for %s" +msgstr "Proizvoljne odrednice za %s" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "ureÄ‘aj ne podržava eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "ureÄ‘aj ne podržava eject ili eject_with_operation" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "nije podržano izvlaÄenje medijuma na ureÄ‘aju" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "ureÄ‘aj ne podržava start" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "ureÄ‘aj ne podržava stop" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS podrÅ¡ka nije dostupna" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "Ne mogu da radim sa izdanjem %d za kodiranje GEmblem-a" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Neispravno zadat broj tokena (%d) u kodiranju GEmblem-a" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "Ne mogu da radim sa izdanjem %d za kodiranje GEmblemedIcon" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Nije ispravno zadat broj tokena (%d) u kodiranju GEmblemedIcon" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "OÄekivano je GEmblem za GEmblemedIcon" + +#: ../gio/gfile.c:962 ../gio/gfile.c:1200 ../gio/gfile.c:1338 +#: ../gio/gfile.c:1576 ../gio/gfile.c:1631 ../gio/gfile.c:1689 +#: ../gio/gfile.c:1773 ../gio/gfile.c:1830 ../gio/gfile.c:1894 +#: ../gio/gfile.c:1949 ../gio/gfile.c:3597 ../gio/gfile.c:3652 +#: ../gio/gfile.c:3887 ../gio/gfile.c:3929 ../gio/gfile.c:4392 +#: ../gio/gfile.c:4803 ../gio/gfile.c:4888 ../gio/gfile.c:4978 +#: ../gio/gfile.c:5075 ../gio/gfile.c:5162 ../gio/gfile.c:5263 +#: ../gio/gfile.c:7782 ../gio/gfile.c:7872 ../gio/gfile.c:7956 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "Radnja nije podržana" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1461 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "Sadržano montiranje ne postoji" + +#: ../gio/gfile.c:2508 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "Ne mogu da umnožim preko direktorijuma" + +#: ../gio/gfile.c:2568 +msgid "Can't copy directory over directory" +msgstr "Ne mogu da umnožim direktorijum preko direktorijuma" + +#: ../gio/gfile.c:2576 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "Ciljna datoteka već postoji" + +#: ../gio/gfile.c:2595 +msgid "Can't recursively copy directory" +msgstr "Ne mogu da umnožim direktorijum i njegov sadržaj" + +#: ../gio/gfile.c:2877 +msgid "Splice not supported" +msgstr "Dijeljenje nije podržano" + +#: ../gio/gfile.c:2881 +#, c-format +msgid "Error splicing file: %s" +msgstr "GreÅ¡ka prilikom dijeljenja datoteke: %s" + +#: ../gio/gfile.c:3012 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Nije podržano kopiranje (reflink/clone) izmeÄ‘u montiranih ureÄ‘aja" + +#: ../gio/gfile.c:3016 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopiranje (reflink/clone) nije podržano ili je neispravno" + +#: ../gio/gfile.c:3021 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "Kopiranje (reflink/clone) nije podržano ili ne radi" + +#: ../gio/gfile.c:3084 +msgid "Can't copy special file" +msgstr "Ne mogu da umnožim specijalnu datoteku" + +#: ../gio/gfile.c:3877 +msgid "Invalid symlink value given" +msgstr "Data je neispravna simboliÄka veza" + +#: ../gio/gfile.c:4038 +msgid "Trash not supported" +msgstr "Nije podržano smeće" + +#: ../gio/gfile.c:4150 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Imena datoteka ne mogu da sadrže „%c“" + +#: ../gio/gfile.c:6574 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "nije podržano montiranje diska" + +#: ../gio/gfile.c:6683 +msgid "No application is registered as handling this file" +msgstr "Ni jedan program ne može da otvori ovu datoteku" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Nabrajanje je zatvoreno" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Brojanje datoteka ima neispunjenu radnju" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Brojanje datoteka je već zavrÅ¡eno" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "Ne mogu da radim sa izdanjem %d za kodiranje GFileIcon-a" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Ulazni podaci za GFileIcon su loÅ¡i" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "Tok ne podržava query_info" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Nije podržavano premotavanje toka" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Sasjecanje nije dozvoljenu nad ulaznim tokom" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Sasjecanje nije dozvoljeno nad tokom" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nije ispravan broj tokena (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "Ne postoji vrsta za ime klase %s" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Vrsta %s ne podržava GIcon suÄelje" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "Vrsta %s ne pripada ni jednoj klasi" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "Broj izdanja je loÅ¡e zadat: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s vrsta ne podržava from_tokens() na GIcon suÄelju" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "Ne mozi obraditi podržanu verziju kodiranja ikone" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nije navedena adresa" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Dužina %u je previÅ¡e duga za adresu" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adresa ima skup bitova preko dužine prefiksa" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "Ne mogu da obradim „%s“ kao masku IP adrese" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "Nema dovoljno mjesta za adresu utiÄnice" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "Nije podržana adresa utiÄnice" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "Ulazni tok ne podržava Äitanje" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1212 ../gio/giostream.c:288 +#: ../gio/goutputstream.c:1664 +msgid "Stream has outstanding operation" +msgstr "Tok radi jako dobro" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> nije dozvoljen unutar <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> nije dozvoljen kao element najviÅ¡eg nivoa" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Datoteka „%s“ se pojavljuje viÅ¡e puta u izvoru" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "Nisam uspio da pronaÄ‘em „%s“ ni u jednom izvornom direktorijumu" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "Nisam uspio da pronaÄ‘em „%s“ u tekućem direktorijumu" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "Nepoznata opcija obrade „%s“" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "Nisam uspio da napravim privremenu datoteku: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "GreÅ¡ka pri Äitanju datoteke „%s“: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "GreÅ¡ka pri sažimanju datoteke „%s“" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "tekst ne može da se pojavljuje unutar <%s>" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "ime datoteke na izlazu" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"Direktorijumi iz kojih će datoteke biti Äitane (osnovno je tekući " +"direktorijum)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Stvara izlaz u formatu izabranom proÅ¡irenjem naziva ciljne datoteke" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "Stvara zaglavlje izvora" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "Stvara izvorni kod korišćen da poveže datoteku resursa u vaÅ¡ kod" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "Stvara spisak zavisnosti" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "Ne stvara samostalno i ne bilježi izvor" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "Ne izvozite funkcije; deklariÅ¡ite ih „G_GNUC_UNUTRAÅ NJIM“" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "Naziv C identifikatora korišćenog za stvoreni izvorni kod" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Prevodi odrednicu resursa u datoteku resursa.\n" +"Datoteke odrednice resursa imaju proÅ¡irenje „.gresource.xml“,\n" +"a datoteke resursa imaju proÅ¡irenje „.gresource“." + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "Treba da navedete taÄno jedan naziv datoteke\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "prazna imena nisu dozvoljena" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "neispravno ime „%s“: imena moraju da poÄinju malim slovom" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"netaÄno ime '%s': netaÄan karakter '%c'; samo mala slova, brojevi i crtica" +"('-') su dozvoljeni." + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "" +"neodgovarajuce ime '%s': dvije uzastopne crtice ('--') nisu dozvoljenje." + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "NetaÄno ime '%s': posljednji karakter ne mozi biti crtira ('-')." + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "neispravno ime „%s“: najveća dužina je 1024" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "ne mogu da dodam kljuÄeve u Å¡emu „list-of“" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" prekriva u ; koristite " +" da izmijenite vrijednost" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"taÄno jedna stvar od „type“, „enum“ ili „flags“ mora biti navedena kao " +"atribut za " + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> nije (joÅ¡) definisano." + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "neispravan GVariant tip niske znakova „%s“" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " je dato, ali Å¡ema ne proÅ¡iruje niÅ¡ta" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "nema za preklapanje" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " proÅ¡iruje Å¡emu „%s“ koja joÅ¡ ne postoji" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " je spisak joÅ¡ nepostojeće Å¡eme „%s“" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "Ne može biti lista Å¡ema sa stazom" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "Ne može se dodati u listu Å¡ema sa adresom" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" je spisak koji proÅ¡iruje koja nije spisak" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" proÅ¡iruje ali „%" +"s“ ne proÅ¡iruje „%s“" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "putanja, ako se navodi mora da poÄinje i zavrÅ¡ava sa kosom crtom" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "lista se mora zavrÅ¡avati sa ´:/ '" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> je već navedeno" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> nije dopuÅ¡ten na najviÅ¡em nivou" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict j navedeno; izlazim.\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "Sadržaj cijelog direktorija je zanemaren.\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Zanemarujem ovaj direktorij.\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"Ne postoji kljuÄ â€ž%s“ u Å¡imi „%s“ kao Å¡to je navedeno u datoteci zamjene „%s“" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; zanemarujem premošćenje ove tipke.\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " i --strict je navedeno; izlazim.\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"greÅ¡ka u analizi kljuÄa „%s“ u Å¡imi „%s“ kao Å¡to je navedeno u datoteci " +"zamjene „%s“: %s." + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "Zanemarujem premošćenje ove tipke.\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"preklapanje za kljuÄ â€ž%s“ u Å¡imi „%s“ u preklopljenoj datoteci „%s“ je izvan " +"opsega datog u Å¡imi" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"preklapanje za kljuÄ â€ž%s“ u Å¡imi „%s“ u preklopljenoj datoteci „%s“ nije u " +"spisku dozvoljenih izbora" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gdje da skladiÅ¡tim gschemas.compiled datoteku" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "Prekidam ako doÄ‘e do bilo kakve greÅ¡ke u Å¡imi" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "Ne upisuj gschemas.compiled datoteku" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "Ne nameći ograniÄenja za ime kljuÄa" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Prevoddi sve GSettings datoteke Å¡ema u keÅ¡ Å¡ema.\n" +"Datoteke Å¡ema moraju da se zavrÅ¡avaju sa .gschema.xml,\n" +"a datoteke keÅ¡a imaju ime gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "Trebate navesti taÄno jedno ime fascikle\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "Nijedna datoteka sa Å¡emama nije naÄ‘ena: " + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "ne radim niÅ¡ta.\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "uklonjena postojeća izlazna datoteka.\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "" +"Ne mogu da naÄ‘em podrazumijevanu vrstu monitora za lokalni direktorijum" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "Neispravno ime datoteke %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "GreÅ¡ka prilikom dobijanja podataka o sistemu datoteka: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "Ne mogu da preimenujem korijeni direktorijum" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "GreÅ¡ka u preimenovanju datoteke: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "Ne mogu preimenovati datoteku, ime datoteke već postoji" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "Ime datoteke je neispravno" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "Ne mogu da otvorim direktorijum" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "GreÅ¡ka prilikom otvaranja datoteke: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "GreÅ¡ka prilikom uklanjanja datoteke: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "GreÅ¡ka prilikom premjeÅ¡tanja datoteke u smeće: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Ne mogu da napravim direktorijum za smeće %s: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "Ne mogu da naÄ‘em korijeni direktorijum za smeće" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "Ne mogu da naÄ‘em ili napravim direktorijum za smeće" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Ne mogu da napravim datoteku sa podacima o smeću: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Ne mogu da poÅ¡aljem datoteku u smeće: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "interna greÅ¡ka" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "GreÅ¡ka prilikom obrazovanja direktorijuma: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Sistem datoteka ne podržava simboliÄke veze" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "GreÅ¡ka prilikom obrazovanja simboliÄke veze: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "GreÅ¡ka prilikom premjeÅ¡tanja datoteke: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "Ne mogu da premjestim direktorijum preko direktorijuma" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "Nije uspjela izrada rezervne kopije datoteke" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "GreÅ¡ka prilikom uklanjanja ciljnje datoteke: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "Nije podržano premjeÅ¡tanje izmeÄ‘u montiranih ureÄ‘aja" + +#: ../gio/glocalfile.c:2603 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ne mogu odrediti iskoriÅ¡tenost diska za %s: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "Vrijednost osobine mora biti razliÄita od NULL" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "Nije ispravna vrsta atributa (oÄekivana je niska znakova)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "Nije ispravno proÅ¡ireno ime osobine" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "GreÅ¡ka prilikom postavljanja proÅ¡irene osobine „%s“: %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (neispravno kodiranje)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "GreÅ¡ka prilikom dobavljanja podataka za datoteku „%s“: %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "GreÅ¡ka prilikom dobavljanja podataka za deskriptor datoteke: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Nije ispravna vrsta osobine (oÄekivana je uint32)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Nije ispravna vrsta osobine (oÄekivana je uint64)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "Nije ispravna vrsta osobine (oÄekivana je niska bitova)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "Ne mogu da postavim ovlašćenja za simboliÄke veze" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "GreÅ¡ka prilikom postavljanja ovlašćenja: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "GreÅ¡ka prilikom postavljanja vlasnika: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "simboliÄke veze moraju biti razliÄite od NULL" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "GreÅ¡ka prilikom postavljanja simboliÄke veze: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "GreÅ¡ka pri postavljanju simboliÄke veze: datoteka nije simboliÄka veza" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "GreÅ¡ka pri postavljanju datuma izmjene ili pristupa: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux kontekst ne smje biti NULL" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "GreÅ¡ka prilikom postavljanja SELinux konteksta: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nije ukljuÄen na vaÅ¡em sistemu" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Nije podržano postavljanje osobine %s" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "GreÅ¡ka prilikom Äitanja datoteke: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "GreÅ¡ka prilikom pretrage unutar datoteke: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "GreÅ¡ka prilikom zatvaranja datoteke: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "Ne mogu da pronaÄ‘em podrazumijevanu, lokalnu vrstu monitora datoteke" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "GreÅ¡ka prilikom upisa u datoteku: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "GreÅ¡ka prilikom uklanjanja stare rezervne kopije veze: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "GreÅ¡ka prilikom obrazovanja rezervne kopije: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "GreÅ¡ka prilikom preimenovanja privremene datoteke: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "GreÅ¡ka pri sasijecanju datoteke: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "GreÅ¡ka prilikom otvaranja datoteke „%s“: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "Ciljna datoteka je direktorijum" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "Ciljna datoteka nije obiÄna datoteka" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "Datoteka je izmijenjena nekim drugim programom" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "GreÅ¡ka prilikom uklanjanja stare datoteke: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:769 +msgid "Invalid GSeekType supplied" +msgstr "Nije ispravno odreÄ‘en GSeekType" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "Zatražena je neispravna pretraga" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ne mogu da sasijeÄem GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "VeliÄina izlazne memorije se ne može promijeniti" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "Ne mogu da promijenim veliÄinu izlaznog memorijskog toka" + +#: ../gio/gmemoryoutputstream.c:671 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "Ima viÅ¡e memorije za upis nego Å¡to ima mjesta u datoj adresi" + +#: ../gio/gmemoryoutputstream.c:779 +msgid "Requested seek before the beginning of the stream" +msgstr "Zahtevano je premotavanje na dio prije poÄetka toka" + +#: ../gio/gmemoryoutputstream.c:794 +msgid "Requested seek beyond the end of the stream" +msgstr "Zahtevano je premotavanje na dio nakon zavrÅ¡etka toka" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "montiranje ne podržava „unmount“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "montiranje ne podržava „eject“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "montiranje ne podržava „unmount“ ili „unmount_with_operation“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "montiranje ne podržava „eject“ ili „eject_with_operation“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "montiranje ne podržava „remount“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "montiranje ne podržava nalaženje vrste sadržaja" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "montiranje ne podržava sinhronizovano nalaženje vrste sadržaja" + +#: ../gio/gnetworkaddress.c:383 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "Ime domaćina „%s“ sadrži „[“, ali ne i „]“" + +#: ../gio/gnetworkmonitorbase.c:199 ../gio/gnetworkmonitorbase.c:302 +msgid "Network unreachable" +msgstr "Mreža je nedostižna" + +#: ../gio/gnetworkmonitorbase.c:237 ../gio/gnetworkmonitorbase.c:267 +msgid "Host unreachable" +msgstr "Domaćin je nedostižan" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ne mogu da napravim pratioca mreže: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "Ne mogu da napravim pratioca mreže: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "Ne mogu da dobavim stanje mreže: " + +#: ../gio/gnetworkmonitornm.c:278 +#, c-format +msgid "NetworkManager version too old" +msgstr "Verzija NetworkManager previÅ¡e stara" + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:557 +msgid "Output stream doesn't implement write" +msgstr "Izlazni tok ne podržava upis" + +#: ../gio/goutputstream.c:518 ../gio/goutputstream.c:1218 +msgid "Source stream is already closed" +msgstr "Izvorni tok je već zatvoren" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "GreÅ¡ka u razrjeÅ¡avanju „%s“: %s" + +#: ../gio/gresource.c:298 ../gio/gresource.c:546 ../gio/gresource.c:563 +#: ../gio/gresource.c:684 ../gio/gresource.c:753 ../gio/gresource.c:814 +#: ../gio/gresource.c:894 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "Resurs na „%s“ ne postoji" + +#: ../gio/gresource.c:463 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "Resurs na „%s“ nije uspio da se raspakuje" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "Resurs na „%s“ nije direktorijum" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "Ulazni tok ne podržava pozicioniranje" + +#: ../gio/gresource-tool.c:491 +msgid "List sections containing resources in an elf FILE" +msgstr "Navodi odjeljke koji sadrže resurse u elf DATOTECI" + +#: ../gio/gresource-tool.c:497 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Navodi resurse\n" +"Ako je dato ODJELJAK, navodi samo resurse u tom odjeljku\n" +"Ako je dato PUTANJA, navodi samo odgovarajuće resurse" + +#: ../gio/gresource-tool.c:500 ../gio/gresource-tool.c:510 +msgid "FILE [PATH]" +msgstr "DATOTEKA [PUTANJA]" + +#: ../gio/gresource-tool.c:501 ../gio/gresource-tool.c:511 +#: ../gio/gresource-tool.c:518 +msgid "SECTION" +msgstr "SEKCIJA" + +#: ../gio/gresource-tool.c:506 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Navodi resurse sa pojedinostima\n" +"Ako je dato SEKCIJA, navodi samo resurse u toj sekciji\n" +"Ako je dato PUTANJA, navodi samo odgovarajuće resurse\n" +"U pojedinosti spadaju sekcija, veliÄina i sažimanje" + +#: ../gio/gresource-tool.c:516 +msgid "Extract a resource file to stdout" +msgstr "IzvlaÄi datoteku resursa u standardni izlaz" + +#: ../gio/gresource-tool.c:517 +msgid "FILE PATH" +msgstr "PUTANJA DATOTEKE" + +#: ../gio/gresource-tool.c:531 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Upotreba:\n" +" gresource [--section ODELJAK] NAREDBA [ARGUMENTI...]\n" +"\n" +"Naredbe:\n" +" help Prikazuje ovo obavjeÅ¡tenje\n" +" sections Ispisuje sekcije resursa\n" +" list Ispisuje resurse\n" +" details Ispisuje resurse sa pojedinostima\n" +" extract IzvlaÄi resurs\n" +"\n" +"Koristite „gresource help NAREDBA“ da prikažete opÅ¡irniju pomoć.\n" +"\n" + +#: ../gio/gresource-tool.c:545 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Korišćenje:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:552 +msgid " SECTION An (optional) elf section name\n" +msgstr " ODELJAK Naziv (opcionalno) elf odeljka\n" + +#: ../gio/gresource-tool.c:556 ../gio/gsettings-tool.c:648 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMANDA (Opciona) komanda za objaÅ¡njenje\n" + +#: ../gio/gresource-tool.c:562 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " DATOTEKA Elf datoteka (izvrÅ¡na ili dijeljena biblioteka)\n" + +#: ../gio/gresource-tool.c:565 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" DATOTEKA Elf datoteka (izvrÅ¡na ili dijeljena biblioteka)\n" +" ili prevedena datoteka resursa\n" + +#: ../gio/gresource-tool.c:569 +msgid "[PATH]" +msgstr "[PUTANJA]" + +#: ../gio/gresource-tool.c:571 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PUTANJA Putanja (opcionalno) resursa (može biti delimiÄna)\n" + +#: ../gio/gresource-tool.c:572 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:574 +msgid " PATH A resource path\n" +msgstr " PUTANJA Putanja resursa\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "Nema takve Å¡eme '%s'\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "Å ema '%s' se ne može premjeÅ¡tati (staza ne smije biti navedena)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "Å ema '%s' se može premjeÅ¡tati (staza mora biti navedena)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "Data je prazna staza.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "Staza mora poÄeti kosom crtom (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "Staza mora zavrÅ¡iti kosom crtom (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Staza ne smije sadržati dvije susjedne kose crte (//)\n" + +#: ../gio/gsettings-tool.c:490 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "Navedena vrijednost je izvan važećeg opsega\n" + +#: ../gio/gsettings-tool.c:497 +#, c-format +msgid "The key is not writable\n" +msgstr "KljuÄ nije upisiv\n" + +#: ../gio/gsettings-tool.c:533 +msgid "List the installed (non-relocatable) schemas" +msgstr "Spisak instaliranih (nepomjerljivih) Å¡ema" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed relocatable schemas" +msgstr "Spisak instaliranih pomjerljivih Å¡ema" + +#: ../gio/gsettings-tool.c:545 +msgid "List the keys in SCHEMA" +msgstr "Spisak kljuÄeva u Å EMA" + +#: ../gio/gsettings-tool.c:546 ../gio/gsettings-tool.c:552 +#: ../gio/gsettings-tool.c:589 +msgid "SCHEMA[:PATH]" +msgstr "Å EMA[:STAZA]" + +#: ../gio/gsettings-tool.c:551 +msgid "List the children of SCHEMA" +msgstr "Spisak djece u Å¡ema" + +#: ../gio/gsettings-tool.c:557 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Navodi kljuÄeve i vrijednosti, rekurzivno\n" +"Ako SHEMA nije data, navodi sve kljuÄeve\n" + +#: ../gio/gsettings-tool.c:559 +msgid "[SCHEMA[:PATH]]" +msgstr "[Å EMA[:PUTANJA]]" + +#: ../gio/gsettings-tool.c:564 +msgid "Get the value of KEY" +msgstr "Uzima vrijednost kljuÄa KEY" + +#: ../gio/gsettings-tool.c:565 ../gio/gsettings-tool.c:571 +#: ../gio/gsettings-tool.c:583 ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH] KEY" +msgstr "Å EMA[:STAZA] KLUÄŒ" + +#: ../gio/gsettings-tool.c:570 +msgid "Query the range of valid values for KEY" +msgstr "Upit opsega važećih vrijednosti za KLJUÄŒ" + +#: ../gio/gsettings-tool.c:576 +msgid "Set the value of KEY to VALUE" +msgstr "Postavlja KLJUÄŒ na VRIJEDNOST" + +#: ../gio/gsettings-tool.c:577 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "Å EMA[:STAZA] KLJUÄŒ VRIJEDNOST" + +#: ../gio/gsettings-tool.c:582 +msgid "Reset KEY to its default value" +msgstr "Postavlja KLJUÄŒ na podrazumijevanu vrijednost" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Vraća sve kljuÄeve u SHEMI na osnovne vrijednosti" + +#: ../gio/gsettings-tool.c:594 +msgid "Check if KEY is writable" +msgstr "Provjerava da lije se KLJUÄŒ može pisati" + +#: ../gio/gsettings-tool.c:600 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Prati da li se KLJUÄŒ mijenja\n" +"Ako KLJUÄŒ nije naveden prati sve kljuÄeve u Å EMA.\n" +"Koristtei ^C da prekinete praćenje.\n" + +#: ../gio/gsettings-tool.c:603 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "Å EMA[:STAZA] [KLJUÄŒ]" + +#: ../gio/gsettings-tool.c:615 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Upotreba:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Komande:\n" +" help Prikaži ovu informaciju\n" +" list-schemas Lista instaliranih Å¡ema\n" +" list-relocatable-schemas Lista relokatibilnih Å¡ema\n" +" list-keys Lista kljuÄeva u Å¡emi\n" +" list-children Lista djece u Å¡emi\n" +" list-recursively Lista kljuÄeva i vrijednosti, rekurzivno\n" +" range Upit opsega kljuÄeva\n" +" get Dobavi vrijednost kljuÄa\n" +" set Postavi vrijednost kljuÄa\n" +" reset Resetuj vrijednost kljuÄa\n" +" reset-recursively Resetuj sve vrijednosti u datoj Å¡emi\n" +" writable Provjeri da li je kljuÄ upisiv\n" +" monitor Posmatraj promjene\n" +"\n" +"Koristite 'gsettings help KOMANDA' za detaljnu pomoć.\n" +"\n" + +#: ../gio/gsettings-tool.c:638 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Korišćenje:\n" +" gsettings [--schemadir Å EMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:644 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " Å EMADIR Direktorijum za traženje dodatnih Å¡ema\n" + +#: ../gio/gsettings-tool.c:652 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" Å EMA Ime Å¡eme\n" +" STAZA Staza za pomjerljive Å¡eme\n" + +#: ../gio/gsettings-tool.c:657 +msgid " KEY The (optional) key within the schema\n" +msgstr " KLJUÄŒ (Opcioni) kljuÄ unutar Å¡eme\n" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The key within the schema\n" +msgstr " KLJUÄŒ KljkuÄ unutar Å¡eme\n" + +#: ../gio/gsettings-tool.c:665 +msgid " VALUE The value to set\n" +msgstr " VRIJEDNOST Vrijednost koja se postavlja\n" + +#: ../gio/gsettings-tool.c:720 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Ne mogu da uÄitam Å¡eme iz „%s“: %s\n" + +#: ../gio/gsettings-tool.c:782 +#, c-format +msgid "Empty schema name given\n" +msgstr "Dat je prazan naziv Å¡eme\n" + +#: ../gio/gsettings-tool.c:811 +#, c-format +msgid "No such key '%s'\n" +msgstr "Nema takvog kljuÄa '%s'\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "Neispravna utiÄnica, nije pokrenuto" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Neispravna utiÄnica, pokretanje nije uspjelo zbog: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "UtiÄnica je već zatvorena" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3619 ../gio/gsocket.c:3674 +msgid "Socket I/O timed out" +msgstr "Isteklo vrijeme za U/I utiÄnice" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "pravim GSocket iz fd: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ne mogu da napravim utiÄnicu: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "Zadata je nepoznata porodica" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "Zadat je nepoznati protokol" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "ne mogu da dobijem lokalnu adresu: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "ne mogu da dobijem udaljenu adresu: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "ne mogu da sluÅ¡am: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "GreÅ¡ka pri povezivanju na adresu: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "GreÅ¡ka prilikom pristupanja grupi viÅ¡estrukog emitovanja: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "GreÅ¡ka prilikom napuÅ¡tanja grupe viÅ¡estrukog emitovanja: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "Nema podrÅ¡ke za posebno viÅ¡estruko emitovanje izvora" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "GreÅ¡ka u prihvatanju veze: %s" + +#: ../gio/gsocket.c:2384 +msgid "Connection in progress" +msgstr "Povezivanje je u toku" + +#: ../gio/gsocket.c:2434 +msgid "Unable to get pending error: " +msgstr "Ne mogu da dobijem greÅ¡ku na Äekanju: " + +#: ../gio/gsocket.c:2637 +#, c-format +msgid "Error receiving data: %s" +msgstr "GreÅ¡ka u primanju podataka: %s" + +#: ../gio/gsocket.c:2812 +#, c-format +msgid "Error sending data: %s" +msgstr "GreÅ¡ka u slanju podataka: %s" + +#: ../gio/gsocket.c:2926 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ne mogu da ugasim utiÄnicu: %s" + +#: ../gio/gsocket.c:3005 +#, c-format +msgid "Error closing socket: %s" +msgstr "GreÅ¡ka u zatvaranju utiÄnice: %s" + +#: ../gio/gsocket.c:3612 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ÄŒekam uslov utiÄnice: %s" + +#: ../gio/gsocket.c:3899 ../gio/gsocket.c:3982 ../gio/gsocket.c:4210 +#, c-format +msgid "Error sending message: %s" +msgstr "GreÅ¡ka pri slanju poruke: %s" + +#: ../gio/gsocket.c:3924 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage nije podržan od strane Windows-a" + +#: ../gio/gsocket.c:4538 ../gio/gsocket.c:4676 +#, c-format +msgid "Error receiving message: %s" +msgstr "GreÅ¡ka pri primanju poruke: %s" + +#: ../gio/gsocket.c:4798 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Ne mogu proÄitati povjerenja soketa: %s" + +#: ../gio/gsocket.c:4807 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials funkcija nije implementirana za ovaj operativni " +"sistem" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ne mogu da se povežem na server posrednika „%s“: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ne mogu se povezati na %s: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "Ne mogu da se povežem: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1603 +msgid "Unknown error on connect" +msgstr "Nepoznata greÅ¡ka veze" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1538 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Posredovanje preko ne - TPC konekcije nije podržano." + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1559 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Proksi protokol „%s“ nije podržan." + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "SluÅ¡anje je već zatvoreno" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "Dodata utiÄnica je zatvorena" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 ne podržava IPv6 adresu „%s“" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "KorisniÄko ime je predugo za SOCKSv5 protokol" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "Ime domaćina „%s“ je predugo za SOCKSv4 protokol" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Server nije SOCKSv4 proksi server." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Veza kroz SOCKSv4 server je odbijena." + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Server nije SOCKSv5 proksi server." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "The SOCKSv5 proksi zahtjeva prijavljivanje." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 proxy zahtijeva naÄin provjere identiteta koga ne podržava GLib." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "KorisniÄko ime ili lozinka su predugi za SOCKSv5 protokol." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5 prijavljivanje nije uspjelo jer su korisniÄko ime ili lozinka " +"pogreÅ¡ni." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "Ime domaćina „%s“ je predugo za SOCKSv5 protokol" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 proxy server koristi nepoznatu vrstu adrese." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "UnutraÅ¡nja SOCKSv5 proksi server greÅ¡ka." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 veza nije dozvoljena od strane skupa pravila." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Domaćin nedostupan kroz SOCKSv5 server." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Mreža nedostupna kroz SOCKSv5 server." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Veza odbijena kroz SOCKSv5 proksi." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 proksi ne podržava „connect“ naredbu." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 proksi ne podržava dati tip adrese." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Nepoznata SOCKSv5 proxy greÅ¡ka." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "Ne mogu da radim sa izdanjem kodiranja %d za GThemedIcon" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "Nije pronaÄ‘ena ispravna adresa" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "GreÅ¡ka u obrnutom razrjeÅ¡avanju „%s“: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "Nema DNS zapisa zahtijevanog tipa za '%s'" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "Privremeno ne mogu da razrijeÅ¡im „%s“" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "GreÅ¡ka u razreÅ¡ivanju „%s“" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ne mogu da deÅ¡ifrujem PEM Å¡ifrovani privatni kljuÄ" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "Nisam pronaÅ¡ao PEM Å¡ifrovani privatni kljuÄ" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "Ne mogu analizirati PEM-kodirani privatni kljuÄ" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "Nema naÄ‘enog PEM-kodiranog certifikata" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ne može se analizirati PEM-kodirani certifikat" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ovo je zadnja Å¡ansa da unesete lozinku prije nego se vaÅ¡ pristup zakljuÄa." + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"ViÅ¡e unesenih lozinki je neispravno i vaÅ¡ pristup će biti zakljuÄan nakon " +"daljnjih neuspjeha." + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "Unesena lozinka je neispravna." + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:561 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "OÄekujem jednu kontrolnu poruku, dobio sam %d" +msgstr[1] "OÄekujem jednu kontrolnu poruku, dobio sam %d" +msgstr[2] "OÄekujem jednu kontrolnu poruku, dobio sam %d" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:573 +msgid "Unexpected type of ancillary data" +msgstr "NeoÄekivana vrsta podreÄ‘enih podataka" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "OÄekujem jedan fd, dobio sam %d\n" +msgstr[1] "OÄekujem jedan fd, dobio sam %d\n" +msgstr[2] "OÄekujem jedan fd, dobio sam %d\n" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Primljen je neispravni fd" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "GreÅ¡ka u slanju akreditiva: " + +#: ../gio/gunixconnection.c:503 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "GreÅ¡ka prilikom provjere da li je SO_PASSCRED omogućen za utiÄnicu: %s" + +#: ../gio/gunixconnection.c:518 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "GreÅ¡ka prilikom omogućavanja SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:547 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"OÄekivano da se proÄita jedan bajt za dobijanje akreditiva, ali je je " +"proÄitano nula bajtova." + +#: ../gio/gunixconnection.c:587 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Nisam oÄekivao kontrolnu poruku, ali sam dobio %d" + +#: ../gio/gunixconnection.c:611 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "GreÅ¡ka prilikom onemogućavanja SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "GreÅ¡ka prilikom Äitanja iz deskriptora datoteke: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "GreÅ¡ka prilikom zatvaranja deskriptora datoteke: %s" + +#: ../gio/gunixmounts.c:2054 ../gio/gunixmounts.c:2107 +msgid "Filesystem root" +msgstr "Korijeni sistem datoteka" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "GreÅ¡ka prilikom pisanja u deskriptor datoteke: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Apstraktna UNIX domene udubljene adrese nije podrzana na ovom sistemu" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "disk ne podržava izbacivanje" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "disk ne podržava eject ili eject_with_operation" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "Ne mogu da naÄ‘em program" + +#: ../gio/gwin32appinfo.c:303 +#, c-format +msgid "Error launching application: %s" +msgstr "GreÅ¡ka pri pokretanju programa: %s" + +#: ../gio/gwin32appinfo.c:378 +msgid "association changes not supported on win32" +msgstr "nisu podržane promjene pridruživanja za win32" + +#: ../gio/gwin32appinfo.c:390 +msgid "Association creation not supported on win32" +msgstr "Nisu podržane promjene pridruživanja za win32" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "GreÅ¡ka prilikom Äitanja ruÄke: %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "GreÅ¡ka prilikom zatvaranja ruÄke: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "GreÅ¡ka prilikom upisa u ruÄku: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nema dovoljno memorije" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "GreÅ¡ka u programu: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Potreban je veći unos" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Podaci nisu ispravno zapakovani" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adrese za sluÅ¡anje" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorisano, za usaglasavanje sa GTestDbus" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Adresa printanja" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Adresa printanja u ljuska nacinu" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Pokrenuti dbus uslugu" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "PogreÅ¡ni argumenti\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "NeoÄekivano svojstvo „%s“ elementa „%s“" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Svojstvo „%s“ elementa „%s“ nije pronaÄ‘eno" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "NeoÄekivana oznaka „%s“, oÄekivano je „%s“" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "NeoÄekivana oznaka „%s“ unutar „%s“" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Ne mogu da naÄ‘em ispravnu datoteku sa obilježivaÄima meÄ‘u direktorijima sa " +"podacima" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "ObilježivaÄ ka „%s“ već postoji" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Nije pronaÄ‘en obilježivaÄ ka „%s“" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "MIME tip nije definisan u obilježivaÄu za putanju „%s“" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Privatna oznaka nije definisana u obilježivaÄu za putanju „%s“" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "U obilježivaÄu ka „%s“ nisu odreÄ‘ene grupe" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "Program „%s“ nije registrovao obilježivaÄ ka „%s“" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Ne mogu da proÅ¡irim komadnu liniju „%s“ sa vezom ka „%s“" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "DjelimiÄan niz znakova na kraju ulaznih podataka" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Ne mogu pretvoriti '%s' u znakovni skup '%s'" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "Adresa „%s“ nije apsolutna adresa pomoću „file“ Å¡eme" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "URI lokalne datoteke '%s' ne smije sadržavati '#'" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' je nevažeći" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Ime raÄunara URI-ja '%s' je nevažeće" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' sadrži nevažeće escape znakove" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Putanja '%s' nije absolutna putanja" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "Nevažeće ime raÄunara" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "Januar" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "Februar" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "Mart" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "Maj" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "Juni" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "Juli" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "August" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "Septembar" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "Oktobar" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "Novembar" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "Decembar" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Maj" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep." + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt." + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov." + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday nami" +msgid "Monday" +msgstr "Ponedjeljak" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday nami" +msgid "Tuesday" +msgstr "Utorak" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday nami" +msgid "Wednesday" +msgstr "Srijeda" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday nami" +msgid "Thursday" +msgstr "ÄŒetvrtak" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday nami" +msgid "Friday" +msgstr "Petak" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday nami" +msgid "Saturday" +msgstr "Subota" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday nami" +msgid "Sunday" +msgstr "Nedjelja" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday nami" +msgid "Mon" +msgstr "Pon" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday nami" +msgid "Tue" +msgstr "Uto" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday nami" +msgid "Wed" +msgstr "Sri" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday nami" +msgid "Thu" +msgstr "ÄŒet" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday nami" +msgid "Fri" +msgstr "Pet" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday nami" +msgid "Sat" +msgstr "Sub" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday nami" +msgid "Sun" +msgstr "Ned" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "GreÅ¡ka tokom otvaranja direktorija '%s': %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "Ne mogu da alociram %lu bajt za Äitanje datoteke „%s“" +msgstr[1] "Ne mogu da alociram %lu bajta za Äitanje datoteke „%s“" +msgstr[2] "Ne mogu da alociram %lu bajtova za Äitanje datoteke „%s“" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "GreÅ¡ka tokom Äitanja datoteke '%s': %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Datoteka „%s“ je prevelika" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "NeuspjeÅ¡no Äitanje datoteke '%s': %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "NeuspjeÅ¡no otvaranje datoteke '%s': %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "NeuspjeÅ¡no preuzimanje osobina datoteke '%s': fstat() neuspjeÅ¡an: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "NeuspjeÅ¡no otvaranje datoteke '%s': fdopen() neuspjeÅ¡an: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Ne mogu da preimenujem datoteku „%s“ u „%s“: neuspjeÅ¡an g_rename(): %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "NeuspjeÅ¡no pravljenje datoteke '%s': %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "Neuspjelo pisanje datoteke '%s': write() neuspio: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Ne mogu da upiÅ¡em u datoteku „%s“: neuspjeÅ¡an fsync(): %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "Postojeća datoteka „%s“ se ne može ukloniti: neuspjeÅ¡an g_unlink(): %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Nevažeći Å¡ablon '%s', ne bi trebao sadržavati '%s'" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Å ablon „%s“ ne sadrži XXXXXX" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "NeuspjeÅ¡no Äitanje simboliÄkog linka '%s': %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "SimboliÄki linkovi nisu podržani" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Ne mogu da pokrenem pretvaranje iz „%s“ u „%s“: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Ne mogu Äitati sirovo u g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "Preostali nepretvoreni podaci u baferu za Äitanje" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "Kanal zavrÅ¡ava djelimiÄnim znakom" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Ne mogu Äitati sirovo u g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:737 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Ne mogu da naÄ‘em ispravnu datoteku sa kljuÄevima meÄ‘u direktorijumima " +"pretrage" + +#: ../glib/gkeyfile.c:773 +msgid "Not a regular file" +msgstr "Nije ispravna datoteka" + +#: ../glib/gkeyfile.c:1173 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Datoteka sa kljuÄevima sadrži red „%s“ Å¡to ne Äini par kljuÄ-vrednost, grupu " +"ili primjedbu" + +#: ../glib/gkeyfile.c:1230 +#, c-format +msgid "Invalid group name: %s" +msgstr "Neispravno ime grupe: %s" + +#: ../glib/gkeyfile.c:1252 +msgid "Key file does not start with a group" +msgstr "Datoteka sa kljuÄevima ne poÄinje grupom" + +#: ../glib/gkeyfile.c:1278 +#, c-format +msgid "Invalid key name: %s" +msgstr "Neispravno ime kljuÄa: %s" + +#: ../glib/gkeyfile.c:1305 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Datoteka sa kljuÄevima sadrži nepodržano kodiranje „%s“" + +#: ../glib/gkeyfile.c:1548 ../glib/gkeyfile.c:1721 ../glib/gkeyfile.c:3099 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3288 ../glib/gkeyfile.c:3418 +#: ../glib/gkeyfile.c:3560 ../glib/gkeyfile.c:3789 ../glib/gkeyfile.c:3856 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Datoteka sa kljuÄevima nema grupu „%s“" + +#: ../glib/gkeyfile.c:1676 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Datoteka sa kljuÄevima ne sadrži kljuÄ â€ž%s“ u grupi „%s“" + +#: ../glib/gkeyfile.c:1838 ../glib/gkeyfile.c:1954 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"Datoteka sa kljuÄevima sadrži kljuÄ â€ž%s“ vrijednosti „%s“ Å¡to nije UTF-8" + +#: ../glib/gkeyfile.c:1858 ../glib/gkeyfile.c:1974 ../glib/gkeyfile.c:2343 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "Datoteka sa kljuÄevima sadrži kljuÄ â€ž%s“ nerazumljive vrijednosti." + +#: ../glib/gkeyfile.c:2560 ../glib/gkeyfile.c:2928 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"Datoteka sa kljuÄevima sadrži kljuÄ â€ž%s“ u grupi „%s“ nerazumljive " +"vrijednosti." + +#: ../glib/gkeyfile.c:2638 ../glib/gkeyfile.c:2715 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "KljuÄ â€ž%s“ u grupi „%s“ ima vrijednost „%s“ gdje je oÄekivano %s" + +#: ../glib/gkeyfile.c:4096 +msgid "Key file contains escape character at end of line" +msgstr "Datoteka sa kljuÄevima sadrži znak ESC na kraju reda" + +#: ../glib/gkeyfile.c:4118 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Datoteka sa kljuÄevima sadrži nedozvoljen niz isticanja „%s“" + +#: ../glib/gkeyfile.c:4260 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Vrijednost „%s“ se ne može smatrati brojem." + +#: ../glib/gkeyfile.c:4274 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Cjelobrojna vrijednost „%s“ je izvan opsega" + +#: ../glib/gkeyfile.c:4307 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" +"Vrijednost „%s“ se ne može smatrati realnim brojem jednostruke taÄnosti." + +#: ../glib/gkeyfile.c:4331 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Vrijednost '%s' se ne može tumaÄiti kao boolean." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "Ne mogu da saznam osobine datoteke „%s%s%s%s“: neuspjeÅ¡an fstat(): %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Ne mogu da mapiram datoteku „%s%s%s%s“: neuspjeÅ¡an mmap(): %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Ne mogu da otvorim datoteku „%s“: neuspjeÅ¡an opijen(): %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "GreÅ¡ka u %d. redu, %d. znak: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Neispravan UTF-8 tekst u imenu — „%s“ nije ispravno" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "„%s“ nije ispravno ime" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "„%s“ nije ispravno ime: „%c“" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "GreÅ¡ka u %d. redu: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Nisam uspio da raÅ¡Älanim „%-.*s“, Å¡to je trebalo da predstavlja cifru unutar " +"znakovne reference (na primjer ê) — možda je cifra prevelika" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Referenca znaka se ne zavrÅ¡ava taÄka-zarezom; vjerovatno je koriÅ¡ten znak " +"bez namjere zapoÄinjanja entiteta - izbjegnite koriÅ¡tenje znaka upisivanjem " +"&" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Znakovna referenca „%-.*s“ ne predstavlja dozvoljeni znak" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Primijećen prazan entitet '&;'; važeći entiteti su: & " < > " +"'" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Ime entiteta „%-.*s“ nije poznato" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Znak na kraju entiteta nije taÄka-zarez; vjerovatno je koriÅ¡ten znak bez " +"namjere zapoÄinjanja entiteta - izbjegnite koriÅ¡tenje znaka upisivanjem " +"&" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument mora poÄeti elementom (npr. )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' je nevažeći prateći znak nakon znaka '<'; ne može zapoÄeti naziv " +"elementa" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag '%" +"s'" +msgstr "" +"ÄŒudan znak „%s“, a oÄekivan je „>“ znak radi okonÄanja oznake praznog " +"elementa „%s“" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "ÄŒudan znak '%s', oÄekivan znak '=' nakon osobine '%s' elementa '%s'" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ÄŒudan znak '%s', oÄekivan znak '>' ili '/' radi okonÄanja poÄetne oznake " +"elementa '%s' ili eventualno osobine; možda je koriÅ¡ten nevažeći znak u " +"imenu osobine" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"ÄŒudan znak '%s', oÄekivan navodni znak nakon znaka jednakosti pri davanju " +"vrijednosti osobini '%s' elementa '%s'" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' je nevažeći prateći znak nakon zatvaranja elementa '%s'; dopuÅ¡teni znak " +"je '>'" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Element '%s' je zatvoren, trenutno nema otvorenih elemenata" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Element '%s' je zatvoren ali trenutno je otvoren element '%s'" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument je bio prazan ili je sadržavao samo prazna polja" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "NeoÄekivan kraj dokumenta nakon otvorene zagrade '<'" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"NeoÄekivan kraj dokumenta uz joÅ¡ otvorene elemente - element '%s' je otvoren " +"posljednji" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"NeoÄekivan kraj dokumenta, oÄekivano zatvaranje zagrade radi okonÄanja " +"oznake <%s/>" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "NeoÄekivan kraj dokumenta unutar imena elementa" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "NeoÄekivan kraj dokumenta unutar imena osobine" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "NeoÄekivan kraj dokumenta unutar oznake za otvaranje elementa." + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"NeoÄekivan kraj dokumenta nakon pratećeg znaka jednakosti iza naziva " +"osobine; nedostaje vrijednost osobine" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "NeoÄekivan kraj dokumenta unutar vrijednosti atributa" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "NeoÄekivan kraj dokumenta unutar oznake za zatvaranje elementa '%s'" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"NeoÄekivan kraj dokumenta unutar komentara ili instrukcije procesiranja" + +#: ../glib/goption.c:858 +msgid "Usage:" +msgstr "Upotreba:" + +#: ../glib/goption.c:858 +msgid "[OPTION...]" +msgstr "[OPCIJA...]" + +#: ../glib/goption.c:974 +msgid "Help Options:" +msgstr "Pomoćne opcije:" + +#: ../glib/goption.c:975 +msgid "Show help options" +msgstr "Prikaži opcije za pomoć" + +#: ../glib/goption.c:981 +msgid "Show all help options" +msgstr "Prikaži sve opcije za pomoć" + +#: ../glib/goption.c:1043 +msgid "Application Options:" +msgstr "Opcije programa:" + +#: ../glib/goption.c:1107 ../glib/goption.c:1177 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Ne mogu da raÅ¡lanim celobrojnu vrijednost „%s“ za %s" + +#: ../glib/goption.c:1117 ../glib/goption.c:1185 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Celobrojna vrijednost „%s“ za %s je izvan opsega" + +#: ../glib/goption.c:1142 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Ne mogu da raÅ¡Älanim realnu vrijednost dvostruke taÄnosti „%s“ za %s" + +#: ../glib/goption.c:1150 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Realna vrijednost dvostruke taÄnosti „%s“ za %s je izvan opsega" + +#: ../glib/goption.c:1436 ../glib/goption.c:1515 +#, c-format +msgid "Error parsing option %s" +msgstr "GreÅ¡ka pri raÅ¡Älanjivanju mogućnosti %s" + +#: ../glib/goption.c:1546 ../glib/goption.c:1659 +#, c-format +msgid "Missing argument for %s" +msgstr "Nedostaje argument za %s" + +#: ../glib/goption.c:2120 +#, c-format +msgid "Unknown option %s" +msgstr "Nepoznata opcija %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "oÅ¡tećen objekat" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "interna greÅ¡ka ili oÅ¡tećen objekat" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "nema memorije" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "dostignut je limit pretraživanja unazad" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "obrazac sadrži stavke koje nisu podržane za djelimiÄno poklapanje" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"reference na prethodno poklapanje ne mogu biti uslov za djelimiÄno poklapanje" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "dostignut je limit rekurzije" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "neispravna kombinacija oznaka za novu liniju" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "loÅ¡ pomak" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "kratki utf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "rekurzivna petlja" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "nepoznata greÅ¡ka" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ na kraju obrasca" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c na kraju obrasca" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "karakter nije prepoznatljiv iza \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "brojevi nisu po redu u {} brojaÄu" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "brojevi su preveliki u {} brojaÄu" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "nedostaje zavrÅ¡nica ] za klasu znakova" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "neispravan izbegavaÄki niz u klasi znakova" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "opseg je neispravan unutar klase znakova" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "nema niÄega za ponavljanje" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "neoÄekivano ponavljanje" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "neprepoznat znak poslije (? ili (?-" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "Klase imenovane POSIX-om su podržane samo unutar klase" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "nedostaje zavrÅ¡nica )" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "referenca na nepostojeći podobrazac" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "nedostaje ) nakon komentara" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "regularani izraz je prevelik" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "ne mogu da dobijem memoriju" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") bez otvaranja (" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "prekoraÄenje koda" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "nepoznat znak nakon (?<" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "podaci iza tvrdnje nisu zadate dužine" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "neispravno zadat broj ili naziv nakon (?(" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "uslovna grupa sadrži viÅ¡e od dvije grane" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "oÄekivana je tvrdnja nakon (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would bje an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "nakon(?R ili (?[+-]brojeva mora da sledi )" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "nepoznat naziv POSIX klase" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "Nisu podržani POSIX kolacioni elementi" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "prevelika je vrijednost karaktera u \\x{...} sekvenci" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "neispravan je uslov (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "nije dozvoljeno \\C u podacima iza tvrdnje" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "iskoÄni znakovi \\L, \\I, \\N(ime), \\U, i \\u nisu podržani" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "rekurzivan zahtjev se može ponavljati beskonaÄno" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "nepoznat znak nakon (?P" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "nedostaje zavrÅ¡nica u nazivu podobrasca" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "dvoimeni podobrasci imaju isto ime" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "nije ispravno zadata \\P ili \\p sekvenca" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "nije poznat naziv osobine nakon \\P ili \\p" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "naziv podobrasca je predugaÄak (smje da ima najviÅ¡e 32 karakatera)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ima previÅ¡e imenovanih podobrazaca (smje ih biti najviÅ¡e 10000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "osmobrojna vrijednost je veća od \\377" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "previÅ¡e pokrenutih radnih prostora za prevoÄ‘enje izvornog koda" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "nije naÄ‘en prethodno provjereni i povezani podobrazac" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE grupa sadrži viÅ¡e od jedne grane" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "neujednaÄene NEWLINE opcije" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g nije pracen sa vitiÄastom, uglastom zagradom, imenom ili brojem pod " +"navodnicima, ili obiÄnim brojem" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "numerisana referenca ne mozi biti nula" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "argument nije dopusten za (*ACCEPT), (*FAIL), ILI (*COMMIT)" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*GLAGOL) nije prepoznat" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "predug broj" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "nedostaje poduzorak imena poslije (?&" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "oÄekuje se cifra nakon (?-" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] je netaÄan karakter u JavaScript kompatibilnom nacinu" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "razliÄita imena za poduzorke od istih brojeva nisu dozvoljena" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) mora imati argument" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c mora biti praćen sa ASCII karakterom" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k nije pracen sa vitiÄastom, uglastom zagradom, ili imenima pod navodnicima" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N nije podrzan u klasi" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "previÅ¡e referenci unaprijed" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "predugo ime u(*MARK), (*PRUNE), (*SKIP), ili (*THEN)" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "vrijednost karaktera u \\u.... sekvenci je prevelika" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "GreÅ¡ka prilikom slaganja s regularnim izrazom %s: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE biblioteka je prevedena bez podrÅ¡ka za UTF8" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE biblioteka je prevedena bez podrÅ¡ke za UTF8 osobine" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE biblioteka je kompajlirana sa nespojivim opcijama" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "GreÅ¡ka pri prevoÄ‘enju regularnog izraza %s kod znaka %d: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "GreÅ¡ka pri optimizovanju regularnog izraza %s: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "oÄekivana je heksadekadna cifra ili „}“" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "oÄekivana je heksadekadna cifra" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "nedostaje „<“ u referenci simbola" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "nedovrÅ¡ena referenca simbola" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "referenca simbola je dužine nula" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "oÄekivana je cifra" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "neispravna referenca simbola" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "odlutalo zavrÅ¡no „\\“" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "nepoznata ESC sekvenca" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "GreÅ¡ka prilikom obrade teksta za zamjenu „%s“ kod znaka %lu: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Citat ne poÄinje navodnim znakom" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Neuparen navodni znak u naredbi ili drugom citatu iz shella" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Tekst se zavrÅ¡io nakon znaka '\\'. (Tekst je bio '%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "Tekst se zavrÅ¡io bez uparenog navodnog znaka %c. (Teskt je bio '%s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "Tekst je bio prazan (ili je sadržavao samo prazna polja)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "NeuspjeÅ¡no Äitanje podataka iz podreÄ‘enog procesa (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"NeoÄekivana greÅ¡ka u select() tokom Äitanja podataka iz podreÄ‘enog procesa (%" +"s)" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NeoÄekivana greÅ¡ka u waitpid() (%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Djeciji proces zavrsen sa kodom %ld" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "DjeÄiji proces ubijen sa signalom %ld" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Djeciji proces zaustavljen sa signalom %ld" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "DjeÄiji proces neobicno zavrsen" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "NeuspjeÅ¡no Äitanje iz podreÄ‘ene cijevi (%s)" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "NeuspjeÅ¡an fork (%s)" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "NeuspjeÅ¡an prelazak u direktorij '%s' (%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "NeuspjeÅ¡no izvrÅ¡avanje podreÄ‘enog procesa \"%s\" (%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "NeuspjeÅ¡no preusmjeravanje ulaza ili izlaza podreÄ‘enog procesa (%s)" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "NeuspjeÅ¡no pokretanje fork za podreÄ‘eni proces (%s)" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Nepoznata greÅ¡ka tokom izvrÅ¡enja podreÄ‘enog procesa \"%s\"" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "NeuspjeÅ¡no Äitanje dovoljno podataka iz podreÄ‘ene pid cijevi (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "NeuspjeÅ¡no Äitanje podataka iz podreÄ‘enog procesa" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"NeuspjeÅ¡no stvaranje cijevi za komuniciranje sa podreÄ‘enim procesom (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "NeuspjeÅ¡no pokretanje podreÄ‘enog procesa (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "Neispravno ime programa: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Neispravn niz znakova u argumentskom vektoru %d: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Neispravna niska u okruženju: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Neispravna radna fascikla: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Neuspjelo izvrÅ¡avanje pomoćnog programa (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"NeoÄekivana greÅ¡ka u g_io_channel_win32_poll() tokom Äitanja podataka iz " +"podreÄ‘enog procesa" + +#: ../glib/gutf8.c:780 +msgid "Failed to allocate memory" +msgstr "Nije uspijelo zauzimanje memorije" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "Znak izvan raspona za UTF-8" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "Nevažeći niz u unosu za pretvaranje" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "Znak izvan raspona za UTF-16" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajt" +msgstr[1] "%u bajta" +msgstr[2] "%u bajtova" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f Kib" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always bje replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bajt" +msgstr[1] "%s bajta" +msgstr[2] "%s bajtova" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not seje this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "Januar" + +msgctxt "full month name with day" +msgid "February" +msgstr "Februar" + +msgctxt "full month name with day" +msgid "March" +msgstr "Mart" + +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +msgctxt "full month name with day" +msgid "May" +msgstr "Maj" + +msgctxt "full month name with day" +msgid "June" +msgstr "Juni" + +msgctxt "full month name with day" +msgid "July" +msgstr "Juli" + +msgctxt "full month name with day" +msgid "August" +msgstr "August" + +msgctxt "full month name with day" +msgid "September" +msgstr "Septembar" + +msgctxt "full month name with day" +msgid "October" +msgstr "Oktobar" + +msgctxt "full month name with day" +msgid "November" +msgstr "Novembar" + +msgctxt "full month name with day" +msgid "December" +msgstr "Decembar" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Maj" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Aug" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep." + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Okt." + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov." + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dec" diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 0000000..796544d --- /dev/null +++ b/po/ca.po @@ -0,0 +1,6478 @@ +# glib translation to Catalan. +# Copyright © 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# Softcatalà , 2001. +# Jordi Mallach , 2002, 2003, 2004, 2005, 2006. +# Josep Puigdemont , 2006. +# Sílvia Miranda , 2011. +# Jordi Serratosa , 2012, 2017. +# Gil Forcada , 2008-2013, 2013, 2014, 2016. +# Jordi Mas i Hernàndez , 2016-2022 +# Xavi Ivars , 2017. +msgid "" +msgstr "" +"Project-Id-Version: glib 2.8\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 15:19+0000\n" +"PO-Revision-Date: 2022-03-22 11:48+0100\n" +"Last-Translator: Jordi Mas \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" +"X-Project-Style: gnome\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Encara no s'admeten les aplicacions per defecte" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"L'establiment de l'aplicació com a última utilitzada per al tipus encara no " +"és compatible" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opcions de la GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Mostra les opcions de la GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Introduïu un mode de servei GApplication (utilitzeu-lo des de fitxers de " +"servei D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Sobreescriu l'identificador de l'aplicació" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Reemplaça la instància en execució" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Mostra l'ajuda" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 +#: gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[ORDRE]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Mostra la versió" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Mostra la informació de la versió i surt" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Llista les aplicacions" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Llista totes les aplicacions instal·lades que es poden activar per D-Bus " +"(mitjançant fitxers .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Executa una aplicació" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Executa l'aplicació (amb fitxers opcionals que s'han d'obrir)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FITXER...]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Activa una acció" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invoca una acció de l'aplicació" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACCIÓ [PARÀMETRE]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Llista les accions disponibles" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Llista les accions estàtiques d'una aplicació (del fitxer .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "ORDRE" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "L'ordre per la qual imprimir l'ajuda detallada" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identificador de l'aplicació en format D-Bus (p. ex.: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FITXER" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Noms de fitxers relatius opcionals o relatius, o URI que s'han d'obrir" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACCIÓ" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "El nom de l'acció que s'ha d'invocar" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARÀMETRE" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Paràmetre opcional per la invocació de l'acció, en format GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 +#: gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Es desconeix l'ordre «%s»\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Forma d'ús:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Arguments:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTS...]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Ordres:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Feu servir «%s help ORDRE» per a obtenir l'ajuda detallada.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"L'ordre %s requereix que la segueixi un identificador d'aplicació\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "l'identificador de l'aplicació no és vàlid: «%s»\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"«%s» no pren cap argument\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "no s'ha pogut connectar a D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "s'ha produït un error en enviar el missatge %s: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "" +"s'ha de proporcionar el nom de l'acció després de l'identificador de " +"l'aplicació\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"el nom d'acció no és vàlid: «%s»\n" +"els noms d'acció han d'estar formats per caràcters alfanumèrics, «-» i «.»\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "s'ha produït un error en analitzar el paràmetre d'acció: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "les accions accepten com a màxim un paràmetre\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "" +"l'ordre de llistat d'aplicacions (list-actions) només pren l'identificador " +"d'aplicació" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "no s'ha pogut trobar el fitxer d'escriptori de l'aplicació %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"es desconeix l'ordre: «%s»\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "El valor de comptatge passat a %s és massa gran" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "No està implementada la cerca en el flux base" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "No es pot truncar el GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Ja està tancat el flux" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "No es permet truncar en els fluxos base" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "S'ha cancel·lat l'operació" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "L'objecte no és vàlid, no s'ha inicialitzat" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "La seqüència de múltiples bytes de l'entrada no és completa" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "No hi ha prou espai a la destinació" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "La seqüència de bytes a l'entrada de conversió no és vàlida" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "S'ha produït un error durant la conversió: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "La cancel·lació de la inicialització no està implementada" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "No es permet la conversió entre els jocs de caràcters «%s» i «%s»" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "No s'ha pogut obrir el convertidor de «%s» a «%s»" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "tipus %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Tipus desconegut" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "tipus de fitxer %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials conté dades no vàlides" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "Aquest sistema operatiu no implementa les GCredentials" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "La vostra plataforma no implementa les GCredentials" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"Les GCredentials no contenen cap identificador de procés en aquest sistema " +"operatiu" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Aquest sistema operatiu no implementa el falsejament de credencials" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "No s'esperava un final de flux tan aviat" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "No es permet la clau «%s» en l'entrada de l'adreça «%s»" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "L'entrada d'adreça «%s» té una parella clau/valor que no té sentit" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"L'adreça «%s» no és vàlida (ha de ser, o bé un camí, o bé un tmpdir " +"-directori temporal-, o bé unes claus abstractes)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Hi ha un error a l'adreça «%s» — l'atribut «%s» no està ben formatat" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" +"El transport «%s» per a l'adreça «%s» és desconegut o no està implementat" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "L'element d'adreça «%s» no conté dos punts (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "El nom del transport a l'adreça a l'element «%s» no pot estar buit" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"La parella de clau/valor %d, «%s», a l'element d'adreça «%s», no conté un " +"signe d'igual" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"La parella de clau/valor %d, «%s», a l'element d'adreça «%s», no conté un " +"signe d'igual" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element" +" “%sâ€" +msgstr "" +"S'ha produït un error en suprimir l'escapament d'una clau o d'un valor en la" +" parella clau/valor %d, «%s», de l'element d'adreça «%s»" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Hi ha un error a l'adreça «%s»: el transport unix requereix que hi hagi " +"establerta exactament una clau, o bé de tipus «path» (camí), o bé de tipus " +"«abstract» (abstracte)" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Hi ha un error a l'adreça «%s»: manca o està mal formatat l'atribut del nom " +"d'ordinador" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Hi ha un error a l'adreça «%s»: manca o està mal formatat l'atribut del port" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "" +"Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Hi ha un error a l'adreça «%s»: l'atribut noncefile no existeix o està mal " +"formatat" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "S'ha produït un error en executar-se automàticament: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "S'ha produït un error en obrir el fitxer nonce «%s»: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "S'ha produït un error en llegir el fitxer nonce «%s»: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"S'ha produït un error en llegir el fitxer nonce «%s»: s'esperaven 16 bytes, " +"però se n'han obtingut %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"S'ha produït un error en escriure els continguts del fitxer nonce «%s» al " +"flux:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "L'adreça que s'ha indicat és buida" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "No es pot engendrar un bus de missatges quan s'ha definit AT_SECURE" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"No es pot engendrar un bus de missatge sense un identificador de màquina: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "No es pot executar D-Bus automàticament sense X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "S'ha produït un error en engendrar la línia d'ordres «%s»: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"No s'ha pogut determinar l'adreça del bus de sessió (no està implementat en " +"aquest sistema operatiu)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable" +" — unknown value “%sâ€" +msgstr "" +"No es pot determinar l'adreça del bus a través de la variable d'entorn " +"«DBUS_STARTER_BUS_TYPE»: conté un valor desconegut «%s»" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"No es pot determinar l'adreça del bus perquè la variable d'entorn " +"«DBUS_STARTER_BUS_TYPE» no està establerta" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipus de bus desconegut %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "S'ha trobat una inesperada falta de contingut en llegir una línia" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"S'ha trobat una inesperada falta de contingut en llegir (de forma segura) " +"una línia" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: " +"%s)" +msgstr "" +"S'han exhaurit tots els mecanismes d'autenticació disponibles (s'han provat:" +" %s) (hi ha disponibles: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" +"Els identificadors d'usuari han de ser els mateixos per a clients i servidor" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" +"S'ha cancel·lat a través de GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "S'ha produït un error en obtenir la informació del directori «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Els permisos del directori «%s» no estan ben formatats. S'esperava el mode " +"0700, però s'ha obtingut el 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "S'ha produït un error en crear el directori «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "L'operació no està implementada" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "" +"S'ha produït un error en obrir l'anell de claus «%s» per a llegir-lo: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"La línia %d de l'anell de claus a «%s» amb el contingut «%s» no està ben " +"formatada" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"El primer testimoni de la línia %d de l'anell de claus a «%s» amb el " +"contingut «%s» no està ben formatat" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is " +"malformed" +msgstr "" +"El segon testimoni de la línia %d de l'anell de claus a «%s» amb el " +"contingut «%s» no està ben formatat" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" +"No s'ha trobat la galeta amb l'identificador %d a l'anell de claus a «%s»" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "S'ha produït un error en crear el fitxer de blocatge «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "S'ha produït un suprimir el fitxer de blocatge antic «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "" +"S'ha produït un error en tancar el fitxer (no enllaçat) de blocatge «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "S'ha produït un error en desenllaçar el fitxer de blocatge «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "" +"S'ha produït un error en obrir l'anell de claus «%s» per a escriptura: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" +"(A més a més, l'alliberació del blocatge per a «%s» també ha fallat: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "La connexió està tancada" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "S'ha esgotat el temps d'espera" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"S'han trobat senyaladors no implementats en construir-se la part de la " +"connexió del client" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"No existeix la interfície «org.freedesktop.DBus.Properties» en l'objecte al " +"camí %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "No existeix la propietat «%s»" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "La propietat «%s» no és de lectura" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "La propietat «%s» no és d'escriptura" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"S'ha produït un error en establir la propietat «%s»: s'esperava el tipus " +"«%s», però s'ha obtingut el «%s»" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "No existeix la interfície «%s»" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "No existeix la interfície «%s» en l'objecte al camí %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "No existeix el mètode «%s»" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "El tipus de missatge «%s» no correspon al tipus «%s» que s'esperava" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Ja hi ha un objecte exportat per a la interfície %s a %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "No s'ha pogut recuperar la propietat %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "No s'ha pogut establir la propietat %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "El mètode «%s» ha retornat un tipus «%s», però s'esperava «%s»" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "No existeix el mètode «%s» a la interfície «%s» amb la signatura «%s»" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Ja està exportat un subarbre per a %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "L'objecte no existeix al camí «%s»" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "el tipus és no vàlid" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Missatge «METHOD_CALL»: manca el camp de capçalera «PATH» o «MEMBER»" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Missatge «METHOD_RETURN»: manca el camp de capçalera «REPLY_SERIAL»" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Missatge «ERROR»: manca el camp de capçalera «REPLY_SERIAL» o «ERROR_NAME»" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Missatge «SIGNAL»: manca el camp de capçalera «PATH», «INTERFACE» o «MEMBER»" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value " +"/org/freedesktop/DBus/Local" +msgstr "" +"Missatge «SIGNAL»: el camp de la capçalera «PATH» utilitza el valor reservat" +" «/org/freedesktop/DBus/Local»" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value " +"org.freedesktop.DBus.Local" +msgstr "" +"Missatge SIGNAL: el camp de capçalera INTERFACE utilitza el valor reservat " +"org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Es volia llegir %lu byte però només s'han rebut %lu" +msgstr[1] "Es volien llegir %lu bytes però només s'han rebut %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"S'esperava el byte «NUL» després de la cadena «%s» però s'ha trobat el byte " +"%d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was " +"“%sâ€" +msgstr "" +"S'esperava una cadena UTF-8 vàlida però s'han trobat bytes no vàlids a " +"l'òfset %d (la llargada de la cadena és %d). La cadena UTF-8 vàlida fins " +"aquell moment era «%s»" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Valor imbricat massa profund" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "El valor analitzat «%s» no és un camí d'objecte D-Bus vàlid" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "El valor analitzat «%s» no és una signatura D-Bus vàlida" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 " +"MiB)." +msgstr[0] "" +"S'ha trobat una matriu de llargada %u byte. La llargada màxima és de 2<<26 " +"bytes (64 MiB)." +msgstr[1] "" +"S'ha trobat una matriu de llargada %u bytes. La llargada màxima és de 2<<26 " +"bytes (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"S'ha trobat una matriu de tipus «a%c» que s'esperava que tingués una " +"llargada múltiple de %u bytes, però en realitat és de %u bytes" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "No es permeten estructures buides (tuples) a D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "El valor analitzat «%s» per variant no és una signatura D-Bus vàlida" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire " +"format" +msgstr "" +"S'ha produït un error en convertir a estructura de dades la GVariant amb el " +"tipus de cadena «%s» del format de cable D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valor d'ordenació de bits (endianness) no vàlid. S'esperava 0x6c («l») o " +"0x42 («B») però s'ha trobat el valor 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Versió major del protocol no vàlida. S'esperava 1 però s'ha trobat %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "S'ha trobat la capçalera de signatura però no és del tipus signatura" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"S'ha trobat la capçalera de la signatura amb la signatura «%s», però el cos " +"és buit" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "El valor analitzat «%s» no és una signatura de D-Bus vàlida (pel cos)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"No hi ha cap capçalera de la signatura en el missatge, però el cos és de %u " +"byte" +msgstr[1] "" +"No hi ha cap capçalera de la signatura en el missatge, però el cos és de %u " +"bytes" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "No s'ha pogut tornar a convertir el missatge a estructura de dades: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"No s'ha pogut convertir a seqüència de bits la GVariant de tipus cadena «%s»" +" al format de cable D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"El nombre de descriptors de fitxer al missatge (%d) difereix del camp de la " +"capçalera (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "No s'ha pogut convertir a seqüència de bits el missatge: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"El cos del missatge té la signatura «%s» però no hi ha cap capçalera de " +"signatura" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"El cos del missatge té el tipus de signatura «%s» però la signatura en el " +"camp de la capçalera és «%s»" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"El cos del missatge és buit però la signatura en el camp de la capçalera és " +"«(%s)»" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "S'ha retornat un error amb el cos de tipus «%s»" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "S'ha retornat un error amb el cos buit" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Premeu qualsevol tecla per a tancar aquesta finestra)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"El bus de sessió (D-Bus) no està en funcionament i l'arrencada automàtica no" +" ha funcionat" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "No s'ha pogut obtenir el perfil de maquinari: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "No s'ha pogut carregar %s ni %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "S'ha produït un error en cridar «StartServiceByName» per a %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" +"S'ha obtingut una resposta inesperada %d per al mètode " +"«StartServiceByName(\"%s\")»" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"No es pot invocar el mètode: el servidor intermediari és per a un nom ben " +"conegut %s sense cap propietari i el servidor intermediari s'ha construït " +"amb el senyalador «G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START»" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "No es pot utilitzar l'espai de noms abstracte" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "No es pot especificar el fitxer «nonce» quan es crea un servidor" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "S'ha produït un error en escriure el fitxer nonce a «%s»: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "La cadena «%s» no és un GUID vàlid de D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "No es pot escoltar «%s», és un transport desconegut" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Ordres:\n" +" help Mostra aquesta informació\n" +" introspect Examina un objecte remot\n" +" monitor Fa un seguiment d'un objecte remot\n" +" call Invoca un mètode en l'objecte remot\n" +" emit Emet un senyal\n" +" wait Espera que aparegui un nom de bus\n" +"\n" +"Utilitzeu «%s ORDRE --help» per a veure l'ajuda de cada ordre en particular.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "S'ha produït un error: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "S'ha produït un error en analitzar la introspecció XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Error: %s no és un nom de membre vàlid\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Error: «%s» no és un camí d'objecte vàlid\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Connecta al bus del sistema" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Connecta al bus de la sessió" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Connecta a l'adreça de D-Bus donada" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opcions del punt final de connexió:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opcions d'especificació del punt final de connexió" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "No s'ha especificat el punt final de connexió" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "S'han especificat més d'un punt final de connexió" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Avís: d'acord amb les dades d'introspecció no existeix la interfície «%s»\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Avís: d'acord amb les dades d'introspecció no existeix el mètode «%s» a la " +"interfície «%s»\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Destinació opcional del senyal (nom únic)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Camí a l'objecte al qual se li enviarà un senyal" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Senyal i nom d'interfície" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Envia un senyal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "S'ha produït un error en connectar-se: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Error: %s no és un nom de bus únic vàlid.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Error: no s'ha especificat el camí a l'objecte\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Error: no s'ha especificat el nom del senyal\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Error: el nom del senyal «%s» no és vàlid\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Error: %s no és un nom d'interfície vàlid\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Error: %s no és un nom de membre vàlid\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "S'ha produït un error en analitzar el paràmetre %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "S'ha produït un error en buidar la connexió: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nom de destinació on invocar el mètode" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Camí a l'objecte on invocar el mètode" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Mètode i nom d'interfície" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Temps d'espera, en segons" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Permet l'autorització interactiva" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Invoca un mètode en un objecte remot." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Error: no s'ha especificat la destinació\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Error: %s no és un nom de bus vàlid\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Error: no s'ha especificat el nom del mètode\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Error: el nom del mètode «%s» no és vàlid\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "S'ha produït un error en analitzar el paràmetre %d del tipus «%s»: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "S'ha produït un error en afegir el gestor %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nom de destinació a examinar" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Camí a l'objecte a examinar" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Imprimeix XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Examina el fill" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Només mostra les propietats" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Examina un objecte remot." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nom de destinació al qual se li vol fer un seguiment" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Camí a l'objecte al qual se li vol fer un seguiment" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Fes el seguiment a un objecte remot." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"Error: no es pot fer un seguiment d'una connexió que no sigui de missatges " +"del bus\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Servei a activar abans d'esperar l'altre (nom conegut)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout" +" (default)" +msgstr "" +"Temps d'espera abans de sortir amb un error (segons); 0 si no voleu temps " +"d'espera (predeterminat)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPCIÓ...] NOM-DEL-BUS" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Espera que aparegui el nom del bus." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Error: no s'ha especificat el servei a activar.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Error: no s'ha especificat el servei a esperar.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Error: massa arguments.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Error: %s no és un nom de bus conegut vàlid.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "No esteu autoritzat a canviar la configuració de depuració" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Sense nom" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "El fitxer d'escriptori no especificava el camp d'execució" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "No s'ha pogut trobar el terminal que demanava l'aplicació" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"No s'ha pogut crear el directori de configuració de l'aplicació de l'usuari " +"%s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" +"No s'ha pogut crear el directori de configuració MIME de l'usuari %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "A la informació d'aplicació li manca un identificador" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "No s'ha pogut crear el fitxer d'escriptori de l'usuari %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Definició personalitzada per a %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "la unitat no implementa l'expulsió" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "la unitat no implementa l'expulsió o «eject_with_operation»" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "la unitat no implementa el sondeig per si hi ha un suport" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "la unitat no implementa la inicialització" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "la unitat no implementa l'aturada" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "El backend TLS no implementa la recuperació de la vinculació TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "El TLS no està implementat" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "El DTLS no està implementat" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "No es pot gestionar la versió %d de la codificació del GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" +"Un nombre de testimonis (%d) de la codificació del GEmblem no són formats " +"correctament" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "No es pot gestionar la versió %d de la codificació del GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" +"Un nombre de testimonis (%d) en la codificació del GEmblemedIcon no són " +"formats correctament" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "S'esperava un GEmblem per a un GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "No existeix el punt de muntatge contenidor" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "No es pot copiar al directori" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "No es pot copiar el directori al directori" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Ja existeix el fitxer de destinació" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "No es pot copiar el directori de forma recursiva" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "No es pot empalmar" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "S'ha produït un error en empalmar el fitxer: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"No està implementada la còpia (referències, clonacions) entre muntatges" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" +"No està implementada o no és vàlida la còpia (referències, clonacions)" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" +"No està implementada o no ha funcionat la còpia (referències, clonacions)" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "No es pot copiar el fitxer especial" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "El valor donat per a l'enllaç simbòlic no és vàlid" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "No es poden utilitzar els enllaços simbòlics" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "No es pot utilitzar la paperera" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "En els noms de fitxers no pot haver-hi «%c»" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "el volum no implementa el muntatge" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "" +"No hi ha cap aplicació que s'hagi registrat per a gestionar aquest fitxer" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "L'enumerador està tancat" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "L'enumerador de fitxer té una operació pendent" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Ja està tancat l'enumerador de fitxer" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "No es pot gestionar la versió %d de la codificació del GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Les dades d'entrada pel GFileIcon no són formades correctament" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "El flux no implementa «query_info»" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "No està implementada la cerca en el flux" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "No es permet truncar en els fluxos d'entrada" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "No es permet truncar en els fluxos" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "El nom de l'ordinador no és vàlid" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Resposta incorrecta del servidor intermediari d'HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "La connexió al servidor intermediari d'HTTP no permesa" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Ha fallat l'autenticació en el servidor intermediari d'HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Cal autenticació en el servidor intermediari d'HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Ha fallat la connexió al servidor intermediari d'HTTP: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "La resposta del servidor intermediari d'HTTP és massa gran" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "El servidor intermediari d'HTTP ha tancat la connexió inesperadament." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nombre de testimonis erroni (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "El nom de classe %s no té tipus" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "El tipus %s no implementa la interfície GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "El tipus %s no té classe" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "El número de versió no és format correctament: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "El tipus %s no implementa «from_tokens()» a la interfície GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "" +"No es pot gestionar la versió proporcionada de la codificació de la icona" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "No s'ha especificat cap adreça" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "L'adreça és massa llarga (%u)" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "L'adreça conté bits més enllà de la llargada del prefix" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "No s'ha pogut analitzar «%s» com a màscara d'adreça IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "No hi ha prou espai per a l'adreça del sòcol" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "L'adreça de sòcol no és compatible" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "El flux d'entrada no té implementada la lectura" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "El flux té una operació pendent" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copia amb el fitxer" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Mantén-lo amb el fitxer quan es mogui" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "«version» no té arguments" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Forma d'ús:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Mostra la informació de la versió i surt." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Ordres:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatena fitxers i els mostra per la sortida estàndard" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copia un, o més, fitxers" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Mostra informació sobre ubicacions" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Executa una aplicació des d'un fitxer d'escriptori" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Llista el contingut de les ubicacions" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Obteniu o establiu el gestor d'un tipus MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Crea els directoris" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Fes un seguiment dels directoris per a veure si hi ha canvis" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Munta o desmunta les ubicacions" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Mou un, o més, fitxers" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Obre els fitxers amb l'aplicació per defecte" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Canvia el nom del fitxer" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Suprimeix un o més fitxers" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Llegeix de l'entrada estàndard i desa-ho" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Establiu un atribut de fitxer" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Mou els fitxers o directoris a la paperera" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Llista els continguts de les ubicacions en un arbre" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Feu servir %s per a obtenir ajuda detallada.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "S'ha produït un error en escriure a la sortida estàndard" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "UBICACIÓ" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatena fitxers i els mostra per la sortida estàndard." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat funciona com l'eina tradicional cat, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar quelcom com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "No s'ha donat cap ubicació" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "No hi ha cap directori de destinació" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Mostra el progrés" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Pregunta abans de sobreescriure" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Conserva tots els atributs" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "" +"Crea una còpia de seguretat dels fitxers existents al directori de " +"destinació" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "No segueixis mai els enllaços simbòlics" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Usa els permisos predeterminats per la destinació" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "S'han transferit %s de %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "FONT" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINACIÓ" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copia un, o més, fitxers des de la FONT a la DESTINACIÓ." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy és similar a l'eina tradicional cp, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar quelcom com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "La destinació «%s» no és un directori" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: voleu sobreescriure «%s»? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Llista els atributs d'escriptura" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Obté la informació del sistema de fitxers" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Els atributs que es volen obtenir" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTS" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "No segueixis els enllaços simbòlics" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributs:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nom que es mostra: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "edita el nom: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nom: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipus: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "mida: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "ocult\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "camí local: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix mount: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atributs que es poden establir:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Espais de nom d'atributs d'escriptura:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Mostra informació sobre ubicacions." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info és similar a l'eina tradicional ls, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar quelcom com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació. Els atributs de fitxer poden\n" +"especificar-se amb el seu nom GIO. Per exemple, standard::icon o usant només el\n" +"nom d'espais, p. ex. unix, o usant «*», que coincideix amb tots els atributs" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "FITXER-DESKTOP [ARG-FITXER ...]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Inicia una aplicació des d'un fitxer d'escriptori amb arguments de nom de " +"fitxer opcionals." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "No s'ha introduït cap fitxer d'escriptori" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "L'ordre d'inici no s'admet actualment en aquesta plataforma" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "No s'ha pogut carregar «%s»: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "No s'ha pogut carregar la informació d'aplicació de «%s»" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "No s'ha pogut iniciar l'aplicació «%s»: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Mostra els fitxers ocults" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Utilitza un format de llistat ampliat" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Imprimeix els noms que es mostren" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Mostra els URI complets" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Llista el contingut de les ubicacions." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list és similar a l'eina tradicional ls, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar quelcom com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació. Els atributs de fitxer poden\n" +"especificar-se amb el seu nom GIO. Per exemple, standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TIPUS-MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "GESTIONADOR" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Obteniu o establiu el gestor d'un tipus MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Si no es dona un gestor, mostra les aplicacions recomanades i registrades\n" +"pel tipus MIME. Si es dona un gestor, s'estableix com a gestor per defecte\n" +"pel tipus MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Heu d'especificar un únic tipus MIME, i potser un gestor" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "No hi ha cap aplicació per defecte per a «%s»\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplicació per defecte per a «%s»: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplicacions registrades:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "No hi ha cap aplicació registrada\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplicacions recomanades:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "No hi ha cap aplicació recomanada\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "No s'ha pogut carregar la informació del gestor «%s»" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"S'ha produït un error en establir «%s» com a gestor per defecte de «%s»: " +"%s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Crea els directoris pare" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Crea directoris." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir és similar a l'eina tradicional mkdir, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar quelcom com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Fes el seguiment a un directori (per defecte: depèn del tipus)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Fes el seguiment a un fitxer (per defecte: depèn del tipus)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Fes el seguiment a un fitxer directament (s'adona de canvis fets mitjançant " +"enllaços forts)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Fes el seguiment a un fitxer directament, però no informa dels canvis" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Informa de moviments i canvis de nom com a esdeveniments de supressió i " +"creació simples" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Vigila els esdeveniments de muntatge" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Fes un seguiment dels directoris per a veure si hi ha canvis." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Munta com a muntable" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Munta el volum amb el fitxer de dispositiu, o un altre identificador" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Desmunta" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Expulsa" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Atura el disc amb el fitxer de dispositiu" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DISPOSITIU" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Desmunta tots els muntables que compleixin l'esquema donat" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ESQUEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignora les operacions de fitxers restants quan es desmunta o extreu" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Usa un usuari anònim en autenticar" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Llista" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Fes un seguiment dels esdeveniments" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Mostra informació addicional" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "El PIM numèric quan es desbloqueja un volum VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Munta un volum ocult TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Munta un volum de sistema TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "S'ha denegat l'accés anònim" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "No hi ha cap disc pel fitxer de dispositiu" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "No hi ha cap volum per a l'identificador donat" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Munta o desmunta les ubicacions." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "No usis el sistema alternatiu de còpia i esborrat" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Mou un, o més, fitxers des de la FONT a la DESTINACIÓ." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move és similar a l'eina tradicional mv, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar quelcom com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "La destinació %s no és un directori" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Obre els fitxers amb l'aplicació registrada per\n" +"defecte per a gestionar aquest tipus de fitxer." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignora els fitxers que no existeixin, no ho preguntis mai" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Suprimeix els fitxers donats." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOM" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Canvia el nom del fitxer." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Manca l'argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Massa arguments" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "S'ha canviat el nom correctament. URI nou: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Crea només si no existeix" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Afegeix al final del fitxer" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "En crear un fitxer, limita'n l'accés a només l'usuari actual" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Quan es reemplaci, fes com si el destí no existís" + +#. Translators: The "etag" is a token allowing to verify whether a file has +#. been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Mostra la nova etag al final" + +#. Translators: The "etag" is a token allowing to verify whether a file has +#. been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "L'etag del fitxer que s'està sobreescrivint" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "S'ha produït un error en llegir de l'entrada estàndard" + +#. Translators: The "etag" is a token allowing to verify whether a file has +#. been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "L'etag no està disponible\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Llegeix de l'entrada estàndard i desa-ho a la DESTINACIÓ." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "No s'ha donat una destinació" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "El tipus de l'atribut" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPUS" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALOR" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Establiu un atribut de fitxer d'UBICACIÓ." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "No s'ha especificat la ubicació" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "No s'ha especificat l'atribut" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "No s'ha especificat el valor" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "El tipus d'atribut «%s» no és vàlid" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Buida la paperera" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Llista els fitxers de la paperera amb les ubicacions originals" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restaura un fitxer de la paperera a la ubicació original (i torna a crear el" +" directori si cal)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "No s'ha pogut trobar el camí original" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "No s'ha pogut tornar a crear la ubicació original: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "No s'ha pogut moure el fitxer a la ubicació original: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Mou o restaura els fitxers o directoris a la paperera." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Nota: l'opció --restore no sobreescriurà la ubicació original del fitxer\n" +"restaurat si ja existeix, tret que s'estableixi l'opció --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "La ubicació indicada no comença amb trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Segueix els enllaços simbòlics, els punts de muntatge i les dreceres" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Llista el contingut dels directoris en un format d'arbre." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "No es permet posar l'element <%s> dins de <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "No es permet posar l'element <%s> al primer nivell" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "El fitxer %s existeix més d'una vegada en els recursos" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "No s'ha pogut trobar «%s» en cap directori de recursos" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "No s'ha pogut trobar «%s» en el directori actual" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Es desconeix l'opció de processament «%s»" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"s'ha demanat preprocessar %s, però %s no està configurat, i %s no està al " +"PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "S'ha produït un error en llegir el fitxer %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "S'ha produït un error en comprimir el fitxer %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "no pot haver-hi text dins de <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Mostra la versió del programa i surt" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nom del fitxer de sortida" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Els directoris des d'on s'han de llegir els fitxers (per defecte és el " +"directori actual)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIRECTORI" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Genera la sortida en el format seleccionat per l'extensió del nom de fitxer " +"de destinació" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Genera la capçalera del codi" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Genera el codi font que es fa servir per a enllaçar el fitxer de recurs amb " +"el codi" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Genera una llista de dependències" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nom del fitxer de dependència a generar" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Inclou destinacions falses en el fitxer de dependències generat" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "No creïs ni registris automàticament els recursos" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "No exportis les funcions, declara-les com a «G_GNUC_INTERNAL»" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"No incrusteu recursos de dades a un fitxer C; en comptes assumiu que està " +"enllaçat externament" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "" +"El nom de l'identificador de C que s'utilitzarà en el codi font generat" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "El compilador C de destinació (per defecte: la variable d'entorn CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compila una especificació de recursos en un fitxer de recursos.\n" +"Els fitxers d'especificació de recursos tenen l'extensió .gresource.xml\n" +"i els fitxers de recursos tenen l'extensió .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Heu de donar un sol nom de fitxer\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "el nom ha de ser com a mínim de 2 caràcters" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "El valor numèric no és vàlid" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " ja s'ha especificat" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' ja s'ha especificat" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "els indicadors han de tenir com a mínim 1 bit establert" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> ha de contenir com a mínim un " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> no està en el rang especificat" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> no és un membre vàlid del tipus enumerat especificat" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> conté una cadena no especificada en el tipus d'indicadors" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> conté una cadena que no està a " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr "el ja està especificat per a aquesta clau" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " no està permès per a claus del tipus «%s»" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "el mínim especificat per al és major que el màxim" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categoria de l10n no admesa: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n demanada, però no s'ha especificat un domini de gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" +"s'ha especificat un context de traducció per al valor sense l10n habilitat" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "No s'ha pogut analitzar el valor del tipus «%s»: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" no es pot especificar per als tipus etiquetats que contenen un " +"tipus enumerat" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " ja està especificat per a aquesta clau" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " no està permès per a claus del tipus «%s»" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr "ja està especificat " + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " ha de contenir com a mínim un " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " ja està especificat per a aquesta clau" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" només es poden especificar per a claus amb tipus enumerats o " +"d'indicadors després de " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +"s'ha especificat quan «%s» ja és membre del tipus " +"enumerat" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +"s'ha especificat quan ja s'havia " +"proporcionat" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr "ja està especificat " + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "l'àlies de destinació «%s» no està en el tipus enumerat" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "l'àlies de destinació «%s» no està a " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " ha de contenir com a mínim un " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "No es permet utilitzar noms buits" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" +"El nom «%s» no és vàlid: els noms han de començar amb una lletra minúscula" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"El nom «%s» no és vàlid: el caràcter «%c» no és vàlid. Només es permeten " +"lletres minúscules, nombres i el guionet («-»)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"El nom «%s» no és vàlid: no es poden posar dos guionets seguits («--»)" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "El nom «%s» no és vàlid: l'últim caràcter no pot ser un guionet («-»)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "El nom «%s» no és vàlid: la llargada màxima és de 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr "ja està especificat " + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "No es poden afegir claus a un esquema del tipus «list-of»" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr "ja està especificat " + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +"La emmascara la a . " +"Utilitzeu per a modificar-ne el valor" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"L'atribut de la ha de ser necessàriament «type», «enum» o «flags»" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "(encara) no s'ha definit <%s id='%s'>." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "El tipus de cadena GVariant «%s» no és vàlid" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "S'ha indicat però l'esquema no està ampliant res" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "No hi ha cap a sobreescriure" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr "ja s'ha especificat " + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr "ja s'ha especificat " + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "El amplia l'esquema «%s» que encara no existeix" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" +"El és una llista d'un esquema «%s» que encara no existeix" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "No pot ser una llista d'un esquema amb un camí" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "No es pot ampliar un esquema amb un camí" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +"El és una llista i amplia el que no és una" +" llista" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%sâ€" +" does not extend “%sâ€" +msgstr "" +"El amplia el " +"però «%s» no amplia «%s»" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Si es dona un camí ha de començar i acabar amb una barra inclinada" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "El camí d'una llista ha d'acabar amb «:/»" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, " +"“/desktop/†or “/system/†are deprecated." +msgstr "" +"Avís: l'esquema «%s» conté el camí «%s». Els camins que comencen amb " +"«/apps/», «/desktop/» o «/system/» estan obsolets." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "ja s'ha especificat <%s id='%s'>" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "No es permet posar l'element <%s> dins de <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "No es permet posar l'element <%s> al primer nivell" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "L'element està requerit a " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "No pot haver-hi text dins de <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Avís: referència no definida a " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "S'ha especificat «--strict», se surt." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "S'ha ignorat el fitxer sencer." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "S'està ignorant aquest fitxer." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring" +" override for this key." +msgstr "" +"No existeix la clau «%s» en l'esquema «%s» tal com especifica el fitxer de " +"sobreescriptura «%s»; s'ignora la sobreescriptura d'aquesta clau." + +# c-format +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and " +"--strict was specified; exiting." +msgstr "" +"No existeix la clau «%s» en l'esquema «%s» tal com especifica el fitxer de " +"sobreescriptura «%s» i s'ha especificat --strict; se surt." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema “%s†" +"(override file “%sâ€); ignoring override for this key." +msgstr "" +"No es pot proveir la sobreescriptura per escriptori de la clau traduïda «%s»" +" a l'esquema «%s» (fitxer de sobreescriptura «%s»); s'ignora la " +"sobreescriptura d'aquesta clau." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema “%s†" +"(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"No es pot proveir la sobreescriptura per escriptori de la clau traduïda «%s»" +" a l'esquema «%s» (fitxer de sobreescriptura «%s») i s'ha especificat " +"--strict; se surt." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"S'ha produït un error en analitzar la clau «%s» en l'esquema «%s» tal com " +"especifica el fitxer de sobreescriptura «%s»: %s. S'ignora la " +"sobreescriptura d'aquesta clau." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"S'ha produït un error en analitzar la clau «%s» en l'esquema «%s» tal com " +"especifica el fitxer de sobreescriptura «%s»: %s. S'ha especificat --strict;" +" se surt." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"La sobreescriptura de la clau «%s» de l'esquema «%s» en el fitxer de " +"sobreescriptura «%s» és fora de l'interval de l'esquema donat; s'ignora la " +"sobreescriptura d'aquesta clau." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"La sobreescriptura de la clau «%s» de l'esquema «%s» en el fitxer de " +"sobreescriptura «%s» és fora de l'interval de l'esquema donat i s'ha " +"especificat --strict; se surt." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"La sobreescriptura de la clau «%s» de l'esquema «%s» en el fitxer de " +"sobreescriptura «%s» no és a la llista de valors vàlids; s'ignora la " +"sobreescriptura d'aquesta clau." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"La sobreescriptura de la clau «%s» de l'esquema «%s» en el fitxer de " +"sobreescriptura «%s» no és a la llista de valors vàlids i s'ha especificat " +"--strict; se surt." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "On desar el fitxer gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Interromp si hi ha cap error en els esquemes" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "No escriguis el fitxer gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "No siguis estricte amb les restriccions dels noms de les claus" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compila tots els fitxers d'esquema GSettings en una memòria cau d'esquemes.\n" +"Els fitxers d'esquema han de tenir l'extensió .gschema.xml\n" +"i el fitxer de memòria cau es dirà gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Heu de donar un sol nom de directori" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "No s'ha trobat cap fitxer d'esquemes: no es fa res." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"No s'ha trobat cap fitxer d'esquemes: suprimeix el fitxer de sortida actual." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "El nom del fitxer no és vàlid: %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "" +"S'ha produït un error en obtenir la informació del sistema de fitxers per " +"%s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "No s'ha trobat el punt del muntatge pel fitxer %s" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "No es pot canviar el nom del directori arrel" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "S'ha produït un error en canviar el nom del fitxer %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "No es pot canviar el nom del fitxer, ja existeix aquest nom" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nom de fitxer no vàlid" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "S'ha produït un error en obrir el fitxer %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "S'ha produït un error en suprimir el fitxer %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "S'ha produït un error en enviar a la paperera el fitxer %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "No s'ha pogut crear el directori de la paperera %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "No s'ha pogut trobar el directori superior per a la paperera %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"No està implementat l'enviament a la paperera en muntatges interns del " +"sistema" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "No s'ha pogut trobar o crear el directori %s de la paperera per %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "No s'ha pogut crear el fitxer d'informació de la paperera per %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"No s'ha pogut enviar el fitxer %s a la paperera als límits del sistema de " +"fitxers" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "No s'ha pogut enviar el fitxer a la paperera %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "No s'ha pogut enviar el fitxer %s a la paperera" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "S'ha produït un error en crear el directori %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "El sistema de fitxers no implementa enllaços simbòlics" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "S'ha produït un error en fer l'enllaç simbòlic: %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "S'ha produït un error en moure el fitxer %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "No s'ha pogut moure el directori al directori" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Ha fallat la creació del fitxer de còpia de seguretat" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "S'ha produït un error en suprimir el fitxer objectiu: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "No està implementat moure entre muntatges" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "No s'han pogut determinar l'ús del disc de %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "El valor de l'atribut no pot ser nul" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tipus d'atribut no vàlid (s'esperava una cadena)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "El nom de l'atribut ampliat no és vàlid" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "S'ha produït un error en establir l'atribut ampliat «%s»: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codificació no vàlida)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "S'ha produït un error en obtenir informació del fitxer «%s»: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" +"S'ha produït un error en obtenir informació del descriptor de fitxer: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tipus d'atribut no vàlid (s'esperava un uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tipus d'atribut no vàlid (s'esperava un uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Tipus d'atribut no vàlid (s'esperava una cadena de bytes)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "No es poden establir permisos en els enllaços simbòlics" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "S'ha produït un error en establir els permisos: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "S'ha produït un error en establir el propietari: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "l'enllaç simbòlic no pot ser nul" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "S'ha produït un error en establir l'enllaç simbòlic: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"S'ha produït un error en establir l'enllaç simbòlic: el fitxer no és un " +"enllaç simbòlic" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"%d nanosegons addicionals per a la marca horària d'UNIX %lld és negatiu" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"%d nanosegons addicionals per a la marca horària d'UNIX %lld arriba al segon" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "La marca horària d'UNIX %lld no hi cap en 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"La marca horària d'UNIX %lld és fora de l'interval suportat per Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "El valor «%s» no es pot convertir a UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "No es pot obrir el fitxer «%s»: error %lu del Windows" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"S'ha produït un error en establir el temps de modificació o d'accés per al " +"fitxer: «%s»: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" +"S'ha produït un error en establir el temps de modificació o d'accés: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "El context del SELinux no pot ser nul" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "Aquest sistema no té habilitat el SELinux" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "S'ha produït un error en establir el context del SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "No està implementat establir l'atribut %s" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "S'ha produït un error en llegir des del fitxer: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "S'ha produït un error en tancar el fitxer: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "S'ha produït un error en cercar en el fitxer: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "" +"No s'ha pogut trobar el tipus de seguiment de fitxer local predeterminat" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "S'ha produït un error en escriure al fitxer: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" +"S'ha produït un error en suprimir l'enllaç de còpia de seguretat antic: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "S'ha produït un error en crear la còpia de seguretat: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "S'ha produït un error en canviar el nom del fitxer temporal: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "S'ha produït un error en truncar el fitxer: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "S'ha produït un error en obrir el fitxer «%s»: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "El fitxer objectiu és un directori" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "El fitxer objectiu no és un fitxer regular" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "El fitxer ha estat modificat des d'alguna aplicació externa" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "S'ha produït un error en suprimir el fitxer vell: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "El GSeekType proporcionat no és vàlid" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "La sol·licitud de cerca és no vàlida" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "No es pot truncar el GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "El flux de sortida de memòria no és modificable" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Ha fallat el redimensionament de la memòria del flux de sortida" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"La quantitat de memòria necessària per a processar l'escriptura és més gran " +"que l'espai d'adreces disponible" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "S'ha sol·licitat un desplaçament abans de l'inici del flux" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "S'ha sol·licitat un desplaçament més enllà del final del flux" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "el muntatge no implementa el desmuntatge («unmount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "el muntatge no implementa l'expulsió («eject»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"el muntatge no implementa el desmuntatge («unmount») o " +"l'«unmount_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"el muntatge no implementa l'expulsió («eject») o l'«eject_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "el muntatge no implementa tornar-se a muntar («remount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "el muntatge no implementa l'estimació de tipus de contingut" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "el muntatge no implementa l'estimació de tipus de contingut síncron" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "El nom de l'ordinador «%s» conté «[» però no «]»" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "No es pot accedir a la xarxa" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "No es pot accedir a la màquina" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "No s'ha pogut crear el monitor de xarxa: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "No s'ha pogut crear el monitor de xarxa: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "No s'ha pogut obtenir l'estat de la xarxa: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "El NetworkManager no s'està executant" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "La versió del NetworkManager és massa antiga" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "El flux de sortida no implementa l'escriptura" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "La suma de vectors donada a %s és massa gran" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "El flux font ja està tancat" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "S'ha produït un error en resoldre «%s»: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "no s'ha implementat %s" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "El domini no és vàlid" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "No existeix el recurs a «%s»" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "No s'ha pogut descomprimir el recurs «%s»" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "El recurs a «%s» no és un directori" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "El flux d'entrada no té implementada la cerca" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Llista les seccions que contenen recursos en un FITXER elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Llista recursos\n" +"Si s'especifica una SECCIÓ, només es llisten els recursos d'aquella secció\n" +"Si s'especifica un CAMÃ, només es llisten els recursos que hi coincideixin" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FITXER [CAMÃ]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECCIÓ" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Llista els recursos amb les seves dades\n" +"Si s'especifica la SECCIÓ, només es mostren els recursos de la secció\n" +"Si s'especifica el CAMÃ, només es mostren els recursos que hi coincideixin\n" +"Les dades són la secció, la mida i la compressió" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extreu un fitxer de recurs a la sortida estàndard" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "CAMà AL FITXER" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Ús:\n" +" gresource [--section SECCIÓ] ORDRE [ARGUMENTS...]\n" +"\n" +"Ordres:\n" +" help Mostra aquesta informació\n" +" sections Llista les seccions de recursos\n" +" list Llista els recursos\n" +" details Llista els recursos amb les seves dades\n" +" extract Extreu un recurs\n" +"\n" +"Utilitzeu «gresource help ORDRE» per a obtenir informació més detallada.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilització:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECCIÓ El nom (opcional) d'una secció elf\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " ORDRE L'ordre (opcional) que s'explicarà\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" FITXER Un fitxer elf (un fitxer binari o una biblioteca compartida)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FITXER Un fitxer elf (un fitxer binari o una biblioteca\n" +" compartida) o un fitxer de recurs compilat\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[CAMÃ]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " CAMà Un (opcional) camí (pot ser parcial) de recurs\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CAMÃ" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " CAMà Un camí de recurs\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "No existeix l'esquema «%s»\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" +"No es pot canviar de lloc l'esquema «%s» (no s'ha d'especificar el camí)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Es pot canviar de lloc l'esquema «%s» (s'ha d'especificar el camí)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "S'ha donat un camí buit.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "El camí ha de començar amb una barra inclinada (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "El camí ha d'acabar amb una barra inclinada (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "El camí no pot contenir dues barres inclinades seguides (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "El valor proporcionat està fora del rang vàlid\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "La clau no és d'escriptura\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Llista els esquemes instal·lats (que no es poden canviar de lloc)" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Llista els esquemes instal·lats que es poden canviar de lloc" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Llista les claus a l'ESQUEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "ESQUEMA[:CAMÃ]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Llista els fills de l'ESQUEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Llista les claus i els valors recursivament\n" +"Si no es passa cap ESQUEMA, es llista totes les claus\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESQUEMA[:CAMÃ]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Obtén el valor de la CLAU" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESQUEMA[:CAMÃ] CLAU" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Consulta el rang de valors vàlids per a la CLAU" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Consulta la descripció per a la CLAU" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Estableix el valor de la CLAU a VALOR" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESQUEMA[:CAMÃ] CLAU VALOR" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Reinicia la CLAU al seu valor predeterminat" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Reinicia totes les claus de l'ESQUEMA als seus valors per defecte" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Comprova si la CLAU és d'escriptura" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Fes un seguiment de la CLAU per si hi ha canvis.\n" +"Si no s'especifica cap CLAU, es farà un seguiment a \n" +"totes les claus de l'ESQUEMA.\n" +"Utilitzeu ^C per a deixar de fer el seguiment.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESQUEMA[:CAMÃ] [CLAU]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Forma d'ús:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] ORDRE [ARGUMENTS...]\n" +"\n" +"Ordres:\n" +" help Mostra aquesta informació\n" +" list-schemas Llista els esquemes instal·lats\n" +" list-relocatable-schemas Llista els esquemes que es poden canviar de lloc\n" +" list-keys Llista les claus d'un esquema\n" +" list-children Llista els fills d'un esquema\n" +" list-recursively Llista les claus i els valors recursivament\n" +" range Consulta el rang d'una clau\n" +" get Obtén el valor d'una clau\n" +" set Estableix el valor d'una clau\n" +" reset Reinicia el valor d'una clau\n" +" reset-recursively Reinicia tots els valors de l'esquema donat\n" +" writable Comprova si es pot escriure a la clau\n" +" monitor Fa un seguiment per si hi ha canvis\n" +"\n" +"Utilitzeu «gsettings help ORDRE» per a veure l'ajuda més detallada.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Ús:\n" +" gsettings [--schemadir DIRECTORI_D'ESQUEMES] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " DIRECTORI_D'ESQUEMES Un directori on cercar-hi esquemes addicionals\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" ESQUEMA El nom de l'esquema\n" +" CAMà El camí, pels esquemes que es poden canviar de lloc\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " CLAU La clau (opcional) de l'esquema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " CLAU La clau de l'esquema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALOR El valor a establir\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "No s'han pogut carregar els esquemes %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "No hi ha cap esquema instal·lat\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "S'ha donat un nom d'esquema buit\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "No existeix la clau «%s»\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "El sòcol no és vàlid, no està inicialitzat" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "El sòcol no és vàlid, ha fallat la inicialització a causa de: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "El sòcol ja és tancat" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "S'ha excedit el temps d'espera d'entrada/sortida del sòcol" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "s'està creant un GSocket a partir del descriptor de fitxer: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "No s'ha pogut crear el sòcol: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "S'ha especificat una família desconeguda" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "S'ha especificat un protocol desconegut" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"No es poden realitzar operacions de datagrames a un sòcol que no és de " +"datagrama." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"No es poden realitzar operacions de datagrames a un sòcol que tingui un " +"temps d'espera màxim establert." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "no s'ha pogut obtenir l'adreça local: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "no s'ha pogut obtenir l'adreça remota: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "no s'ha pogut escoltar: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "S'ha produït un error en vincular-se a l'adreça %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "S'ha produït un error en unir-se a un grup de multidestinació: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "S'ha produït un error en deixar un grup de multidestinació: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Encara no es pot fer multidestinació des d'un origen concret" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "La família del sòcol no és compatible" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "la font especificada no és una adreça IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "El nom de la interfície és massa llarg" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "No s'ha trobat la interfície: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Encara no es pot fer multidestinació en IPv4 des d'un origen concret" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Encara no es pot fer multidestinació en IPv6 des d'un origen concret" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "S'ha produït un error en acceptar la connexió: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Connexió en curs" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "No s'ha pogut obtenir l'error pendent: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "S'ha produït un error en rebre les dades: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "S'ha produït un error en enviar les dades: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "No s'ha pogut aturar el sòcol: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "S'ha produït un error en tancar el sòcol: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "S'està esperant la condició del sòcol: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "S'ha produït un error en enviar el missatge: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Els vectors del missatge són massa grans" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "S'ha produït un error en enviar el missatge: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "El GSocketControlMessage no està implementat a Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "S'ha produït un error en rebre un missatge: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "No s'han pogut llegir les credencials del sòcol: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "aquest sistema operatiu no admet g_socket_get_credentials" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "No s'ha pogut connectar al servidor intermediari %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "No s'ha pogut connectar a %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "No s'ha pogut connectar: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" +"Encara no es pot fer de servidor intermediari d'una connexió que no sigui " +"TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "El protocol del servidor intermediari «%s» no està implementat." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Ja està tancat el receptor de connexions" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "El sòcol que s'ha afegit és tancat" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "El SOCKSv4 no permet utilitzar adreces IPv6 «%s»" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "El nom d'usuari és massa llarg pel protocol SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "El nom d'ordinador «%s» és massa llarg pel protocol SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "El servidor no és un servidor intermediari de SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "S'ha rebutjat la connexió a través d'un servidor SOCKSv4" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "El servidor no és un servidor intermediari SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "El servidor intermediari SOCKSv5 requereix autenticació." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by" +" GLib." +msgstr "" +"El servidor intermediari SOCKSv5 requereix un mètode d'autenticació que " +"encara no està implementat a la GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"El protocol SOCKSv5 no permet un nom d'usuari o de contrasenya d'aquesta " +"mida." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Ha fallat l'autenticació SOCKSv5 a causa d'un nom d'usuari o contrasenya " +"errònies." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "El nom d'ordinador «%s» és massa llarg pel protocol SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" +"El servidor intermediari SOCKSv5 utilitza un tipus d'adreça desconeguda." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "S'ha produït un error intern del servidor intermediari SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "El conjunt de regles no permet fer connexions SOCKSv5." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" +"No es pot arribar al servidor a través del servidor intermediari SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" +"No es pot arribar a la xarxa a través del servidor intermediari SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "S'ha refusat la connexió a través del servidor intermediari SOCKSv5." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "El servidor intermediari SOCKSv5 no permet l'ús de l'ordre «connect»." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" +"El servidor intermediari SOCKSv5 no permet l'ús del tipus d'adreça " +"proporcionada." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "S'ha produït un error desconegut en el servidor intermediari SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"No s'ha pogut crear el conducte per a comunicar-se amb el procés fill (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Els conductes no són compatibles amb aquesta plataforma" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "No es pot gestionar la versió %d de la codificació del GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "No s'ha trobat cap adreça vàlida" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "S'ha produït un error en resoldre a la inversa «%s»: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "" +"S'ha produït un error en analitzar el registre de DNS %s: paquet DNS mal " +"format" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "No hi ha cap registre del tipus sol·licitat al DNS per «%s»" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "No s'ha pogut resoldre «%s» de forma temporal" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "S'ha produït un error en resoldre «%s»" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Paquet DNS mal format" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "No s'ha pogut analitzar la resposta DNS per a «%s»: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "No s'ha trobat cap clau privada codificada amb PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "No s'ha pogut desxifrar la clau privada codificada amb PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "No s'ha pogut analitzar la clau privada codificada amb PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "No s'ha trobat cap certificat codificat amb PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "No s'ha pogut analitzar el certificat codificat amb PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "El backend TLS actual no és compatible amb PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Aquest GTlsBackend no admet la creació de certificats PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Últim intent per a introduir la contrasenya correctament abans que se us " +"bloquegi l'accés." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"S'han introduït diverses contrasenyes errònies i se us bloquejarà l'accés " +"després de més intents." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "La contrasenya introduïda no és correcta." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "L'enviament de FD no és compatible" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "S'esperava un missatge de control però se n'ha obtingut %d" +msgstr[1] "S'esperava un missatge de control però se n'han obtingut %d" + +# FIXME +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Tipus de dades extres no esperades" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "S'esperava un descriptor de fitxer però se n'ha obtingut %d\n" +msgstr[1] "S'esperava un descriptor de fitxer però se n'han obtingut %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "S'ha rebut un descriptor de fitxer no vàlid" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "No s'admet la recepció de FD" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "S'ha produït un error en enviar les credencials: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"S'ha produït un error en la comprovació de si «SO_PASSCRED» és habilitat en " +"el sòcol: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "S'ha produït un error en habilitar «SO_PASSCRED»: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero " +"bytes" +msgstr "" +"S'esperava llegir un sol byte per a rebre les credencials però s'han llegit " +"zero bytes" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "No s'esperava un missatge de control però s'ha obtingut %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "S'ha produït un error en inhabilitar «SO_PASSCRED»: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "S'ha produït un error en llegir del descriptor de fitxer: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "S'ha produït un error en tancar el descriptor de fitxer: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Arrel del sistema de fitxers" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "S'ha produït un error en escriure al descriptor de fitxer: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Aquest sistema no admet adreces de sòcol de domini UNIX abstractes" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "el volum no implementa l'expulsió" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "el volum no implementa l'expulsió o «eject_with_operation»" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "S'ha produït un error en llegir del gestor: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "S'ha produït un error en tancar el gestor: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "S'ha produït un error en escriure al gestor: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "No hi ha prou memòria" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Error intern: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Fan falta més dades d'entrada" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Les dades comprimides no són vàlides" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adreça on s'escoltarà" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorat, per a mantenir la compatibilitat amb el GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Mostra l'adreça" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Mostra l'adreça en mode intèrpret d'ordres" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Executa un servei de D-Bus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Els arguments no són vàlids\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "No s'esperava l'atribut «%s» per a l'element «%s»" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "No s'ha trobat l'atribut «%s» de l'element «%s»" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "No s'esperava l'etiqueta «%s», s'esperava «%s»" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "No s'esperava l'etiqueta «%s» dins «%s»" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "La data/hora «%s» no és vàlida al fitxer d'adreces d'interès" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"No s'ha trobat cap fitxer d'adreces d'interès dins dels directoris de dades" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Ja existeix una adreça d'interès per a l'URI «%s»" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "No s'ha trobat cap adreça d'interès per a l'URI «%s»" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "No hi ha cap tipus MIME definit a l'adreça d'interès per a l'URI «%s»" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" +"No hi ha cap senyalador privat definit a l'adreça d'interès per a l'URI «%s»" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "No hi ha cap grup establert a l'adreça d'interès per a l'URI «%s»" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" +"No hi ha cap aplicació amb el nom «%s» que hagi registrat l'adreça d'interès" +" «%s»" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "No s'ha pogut ampliar la línia d'execució «%s» amb l'URI «%s»" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Caràcter no representable a l'entrada de la conversió" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Seqüència de caràcters parcial al final de l'entrada" + +# FIXME: fallback +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "No es pot convertir el «fallback» «%s» al joc de codis «%s»" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "NUL byte incrustat a l'entrada de conversió" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "La seqüència de bytes a l'entrada de conversió no és vàlida" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "L'URI «%s» no és un URI absolut que utilitzi l'esquema «file»" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Pot ser que l'URI del fitxer local «%s» no inclogui cap «#»" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "L'URI «%s» no és vàlid" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "El nom de l'ordinador de l'URI «%s» no és vàlid" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "L'URI «%s» conté caràcters d'escapada no vàlids" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "El nom de camí «%s» no és un camí absolut" + +#. Translators: this is the preferred format for expressing the date and the +#. time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %-d %b de %Y, %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%-H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "gener" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "febrer" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "març" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "abril" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "maig" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "juny" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "juliol" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "agost" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "setembre" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "octubre" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "novembre" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "desembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "gen." + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "febr." + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "març" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "abr." + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "maig" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "juny" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jul." + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ag." + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "set." + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "oct." + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov." + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "des." + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "dilluns" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "dimarts" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "dimecres" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "dijous" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "divendres" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "dissabte" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "diumenge" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "dl." + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "dt." + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "dc." + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "dj." + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "dv." + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ds." + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "dg." + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "de gener" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "de febrer" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "de març" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "d'abril" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "de maig" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "de juny" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "de juliol" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "d'agost" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "de setembre" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "d'octubre" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "de novembre" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "de desembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "de gen." + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "de febr." + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "de març" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "d'abr." + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "de maig" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "de juny" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "de jul." + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "d'ag." + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "de set." + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "d'oct." + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "de nov." + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "de des." + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "a. m." + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "p. m." + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "S'ha produït un error en obrir el directori «%s»: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "No s'han pogut assignar %lu byte per a llegir el fitxer «%s»" +msgstr[1] "No s'han pogut assignar %lu bytes per a llegir el fitxer «%s»" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "S'ha produït un error en llegir el fitxer «%s»: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "El fitxer «%s» és massa gran" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "No s'ha pogut llegir del fitxer «%s»: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "No s'ha pogut obrir el fitxer «%s»: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"No s'han pogut obtenir els atributs del fitxer «%s»: ha fallat la funció " +"fstat(): %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "No s'ha pogut obrir el fitxer «%s»: ha fallat la funció fdopen(): %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"No s'ha pogut canviar el nom del fitxer «%s» a «%s»: ha fallat la funció " +"g_rename(): %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "" +"No s'ha pogut escriure el fitxer «%s»: ha fallat la funció write(): %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "" +"No s'ha pogut escriure el fitxer «%s»: ha fallat la funció fsync(): %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "No s'ha pogut crear el fitxer «%s»: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"No s'ha pogut suprimir el fitxer existent «%s»: ha fallat la funció " +"g_unlink(): %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "La plantilla «%s» no és vàlida, no hauria de tenir cap «%s»" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "La plantilla «%s» no conté XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "No s'ha pogut llegir l'enllaç simbòlic «%s»: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "No s'ha pogut obrir el convertidor de «%s» a «%s»: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "No es pot fer una lectura bàsica a g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "" +"A la memòria intermèdia de lectura hi ha dades sobrants no convertides" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "El canal acaba en un caràcter parcial" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "No es pot fer una lectura bàsica a g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"No s'ha pogut trobar cap fitxer de claus vàlid als directoris de cerca" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "No és un fitxer regular" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"El fitxer de claus conté la línia «%s» que no és una parella clau-valor, " +"grup o comentari" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "El nom del grup no és vàlid: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "El fitxer de claus no comença amb un grup" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "El nom de la clau no és vàlid: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "El fitxer de claus conté la codificació no implementada «%s»" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "El fitxer de claus no té el grup «%s»" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "El fitxer de claus no conté una clau «%s» en el grup «%s»" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"El fitxer de claus conté la clau «%s» amb el valor «%s», que no és UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"El fitxer de claus conté la clau «%s», que té un valor que no es pot " +"interpretar." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"El fitxer de claus conté la clau «%s» en el grup «%s», que té un valor que " +"no es pot interpretar." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"La clau «%s» en el grup «%s» té el valor «%s» però s'esperava el valor %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "El fitxer de claus conté un caràcter d'escapada al final de línia" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "El fitxer de claus conté la seqüència d'escapada no vàlida «%s»" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "El valor «%s» no es pot interpretar com un nombre." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "El valor enter «%s» és fora de l'interval" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "El valor «%s» no es pot interpretar com un nombre amb coma flotant." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "El valor «%s» no es pot interpretar com un booleà." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"No s'han pogut obtenir els atributs del fitxer «%s%s%s%s»: ha fallat la " +"funció fstat(): %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" +"No s'ha pogut mapar el fitxer «%s%s%s%s»: ha fallat la funció mmap(): %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "No s'ha pogut obrir el fitxer «%s»: ha fallat la funció open(): %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "S'ha produït un error a la línia %d caràcter %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "El nom conté caràcters UTF-8 no vàlids: «%s»" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "«%s» no és un nom vàlid" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "«%s» no és un nom vàlid: «%c»" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "S'ha produït un error a la línia %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"No s'ha pogut analitzar «%-.*s»: hi hauria d'haver hagut un dígit dins un " +"caràcter de referència (per exemple ê). Potser el dígit és massa gran" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"La referència del caràcter no acaba amb un punt i coma. Segurament heu " +"utilitzat un caràcter «&» sense intenció d'iniciar una entitat. Substituïu " +"el caràcter «&» per &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "El caràcter de referència «%-.*s» no codifica un caràcter permès" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"S'ha detectat una entitat buida «&;». Les entitats vàlides són: & "" +" < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Es desconeix el nom d'entitat «%-.*s»" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"L'entitat no acaba amb un punt i coma. Segurament heu utilitzat un caràcter " +"«&» sense intenció d'iniciar una entitat. Substituïu el caràcter «&» per " +"&" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "El document ha de començar amb un element (p. ex. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an" +" element name" +msgstr "" +"«%s» no és un caràcter vàlid després d'un caràcter «<»: no pot començar un " +"nom d'element" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"S'ha trobat un caràcter estrany: «%s». S'esperava el caràcter «>» per a " +"tancar l'etiqueta d'element buit «%s»" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Massa atributs en l'element «%s»" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"S'ha trobat un caràcter estrany: «%s». S'esperava un «=» després del nom " +"d'atribut «%s» de l'element «%s»" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"S'ha trobat un caràcter estrany: «%s». S'esperava un caràcter «>» o «/» per " +"a finalitzar l'etiqueta d'inici de l'element «%s», o opcionalment un " +"atribut. Potser heu utilitzat un caràcter no vàlid en un nom d'atribut" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"S'ha trobat un caràcter estrany: «%s». S'esperaven unes cometes d'obertura " +"després del signe «=» en donar valor a l'atribut «%s» de l'element «%s»" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"«%s» no és un caràcter vàlid després del nom d'element de tancament «%s». El" +" caràcter permès és «>»" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "L'element «%s» estava tancat. Actualment no hi ha cap element obert" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "L'element «%s» estava tancat. L'element obert actualment és «%s»" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "El document era buit o només contenia espais en blanc" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"El document ha acabat de manera inesperada immediatament després del símbol " +"«<»" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"El document ha acabat de manera inesperada amb elements que encara eren " +"oberts. «%s» era l'últim element obert" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"El document ha acabat de manera inesperada. S'esperava trobar un símbol «>» " +"que acabés l'etiqueta <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "El document ha acabat de manera inesperada enmig d'un nom d'element" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "El document ha acabat de manera inesperada enmig d'un nom d'atribut" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"El document ha acabat de manera inesperada enmig d'una etiqueta d'obertura " +"d'un element." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"El document ha acabat de manera inesperada després d'un signe d'igual " +"després d'un nom d'atribut. No hi ha cap valor d'atribut" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "El document ha acabat de manera inesperada enmig d'un valor d'atribut" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"El document ha acabat de manera inesperada enmig de l'etiqueta de tancament " +"de l'element «%s»" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"El document ha acabat de manera inesperada enmig de l'etiqueta de tancament " +"per un element no obert" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"El document ha acabat de manera inesperada enmig d'un comentari o d'una " +"instrucció de processament" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPCIÓ...]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opcions d'ajuda:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Mostra les opcions d'ajuda" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Mostra totes les opcions d'ajuda" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opcions de l'aplicació:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opcions:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "No es pot analitzar el valor enter «%s» per a %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "El valor enter «%s» per a %s és fora de l'interval" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "No es pot analitzar el valor doble «%s» per a %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "El valor doble «%s» per a %s és fora de l'interval" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "S'ha produït un error en analitzar l'opció %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Manca un argument per a %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Es desconeix l'opció %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "objecte malmès" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "error intern o objecte malmès" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "no hi ha prou memòria" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "s'ha arribat al límit de tornades enrere" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"el patró conté elements que no estan implementats en les concordances " +"parcials" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "error intern" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"no s'ha implementat l'ús de referències anteriors per a coincidències " +"parcials" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "s'ha arribat al límit de recurrències" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "la combinació de senyaladors de línia nova no és vàlida" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "desplaçament incorrecte" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "UTF-8 curt" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "bucle recursiu" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "error desconegut" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ al final del patró" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c al final del patró" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "caràcter no reconegut després de \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "nombres fora de l'interval en el quantificador {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "nombre massa gran en el quantificador {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "falta el «]» per a la classe de caràcter" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "la seqüència d'escapada en la classe de caràcter no és vàlida" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "s'ha sortit de l'interval en la classe de caràcter" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "no hi ha res per a repetir" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "repetició no esperada" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "no es reconeix el caràcter després de «(?» o «(?-»" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "" +"Només es permeten les classes amb nom de POSIX dins de la pròpia classe" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "falta un «)»" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referència a un subpatró que no existeix" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "falta un «)» després del comentari" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "l'expressió regular és massa gran" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "no s'ha pogut obtenir memòria" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "hi ha un «)» sense el corresponent «(»" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "desbordament del codi" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "no es reconeix el caràcter després de «(?<»" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "l'asserció cap enrere no té llargada fixa" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "el nombre o el nom no estan ben formats després de «(?(»" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "el grup condicional conté més de dues branques" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "s'esperava una asserció després de «(?(»" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "«(?R» o «(?[+-]dígits» han d'anar seguits de «)»" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nom de classe POSIX desconeguda" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "No es poden utilitzar els elements d'ordenació de POSIX" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "el valor del caràcter a la seqüència «\\x{...}» és massa gran" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condició «(?(0)» no vàlida" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "no es permet \\C en assercions cap enrere" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "no s'admeten els caràcters d'escapada «\\L», «\\l», «\\N{nom}», «\\U» i «\\u»" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "la crida recursiva podria entrar en bucle indefinidament" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "no es reconeix el caràcter després de «(?P»" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "falta la finalització en el nom del subpatró" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dos noms de subpatró tenen el mateix nom" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "la seqüència «\\P» o «\\p» no està ben formada" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "es desconeix el nom de la propietat després de «\\P» o «\\p»" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "el nom del subpatró és massa llarg (32 caràcters com a màxim)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "hi ha massa subpatrons amb nom (màxim de 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "el valor octal és més gran que \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "s'ha produït un desbordament en compilar l'espai de treball" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "no s'ha trobat el subpatró referenciat comprovat anteriorment" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "El grup «DEFINE» conté més d'una branca" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opcions «NEWLINE» incoherents" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"després de «\\g» no hi ha cap número o cap nom o número entre claudàtors, " +"claus angulars o cometes" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "les referències numerades no poden ser zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "no es permeten arguments per «(*ACCEPT)», «(*FAIL)» o «(*COMMIT)»" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "no es reconeix «(*VERB)»" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "el número és massa gran" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "falta el nom del subpatró després de (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "s'esperava un dígit després de (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"el caràcter«]» no és un caràcter de dades vàlid en el mode de compatibilitat" +" amb JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "no s'accepten noms diferents per subpatrons del mateix número" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "«(*MARK)» ha de tenir un argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "després de «\\c» ha d'haver-hi un caràcter ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"després de «\\k» no hi ha cap nom entre claudàtors, claus angulars o cometes" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "no es pot utilitzar \\N en una classe" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "hi ha massa referències cap endavant" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "el nom és massa llarg a «(*MARK)«, «(*PRUNE)«, «(*SKIP)» o «(*THEN)»" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "el valor del caràcter a la seqüència «\\u...» és massa gran" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "S'ha produït un error en fer coincidir l'expressió regular %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "La biblioteca PCRE no està compilada per a interpretar UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"La biblioteca PCRE no està compilada per a interpretar les propietats UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "La biblioteca PCRE ha estat compilada amb opcions incompatibles" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "S'ha produït un error en optimitzar l'expressió regular %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"S'ha produït un error en compilar l'expressió regular %s al caràcter %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "s'esperava un dígit hexadecimal o bé «}»" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "s'esperava un dígit hexadecimal" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "falta un «<» en la referència simbòlica" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "la referència simbòlica no està acabada" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "referència simbòlica de longitud zero" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "s'esperava un dígit" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "la referència simbòlica no és vàlida" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "«\\» final extraviat" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "no es reconeix la seqüència d'escapament" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"S'ha produït un error en analitzar el text de reemplaçament «%s» al caràcter" +" %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "El text citat no comença amb cometes" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"S'han trobat unes cometes desaparellades en una línia d'ordres o en un altre" +" text entre cometes" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "El text acaba just després d'un caràcter «\\». (El text era «%s».)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"El text ha acabat abans de trobar les cometes corresponents a %c. (El text " +"era «%s».)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "El text era buit (o només contenia espais en blanc)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "No s'han pogut llegir dades des del procés fill (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "" +"S'ha produït un error no esperat en llegir dades des d'un procés fill (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "S'ha produït un error inesperat en waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "El procés fill ha sortit amb el codi %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "El senyal %ld ha matat el procés fill" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "El senyal %ld ha aturat el procés fill" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "El procés fill ha sortit inesperadament" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "No s'ha pogut llegir des del conducte fill (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "No s'ha pogut engendrar el procés fill «%s» (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "No s'ha pogut bifurcar (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "No s'ha pogut canviar al directori «%s» (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "No s'ha pogut executar el procés fill «%s» (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" +"No s'ha pogut obrir el fitxer per a tornar a assignar el descriptor de " +"fitxers (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "" +"No s'ha pogut duplicar el descriptor de fitxers per al procés fill (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "No s'ha pogut bifurcar el procés fill (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "No s'ha pogut tancar el descriptor de fitxers per al procés fill (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "S'ha produït un error desconegut en executar el procés fill «%s»" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"No s'han pogut llegir prou dades del conducte de l'identificador del procés " +"fill (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "No s'han pogut llegir dades del procés fill" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "No s'ha pogut executar el procés fill (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "No s'ha pogut dup() en el procés fill (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "El nom del programa no és vàlid: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "La cadena en el vector d'argument no és vàlida a %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Cadena no vàlida a l'entorn: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "El directori de treball no és vàlid: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "No s'ha pogut executar el programa d'ajuda (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"S'ha produït un error inesperat a g_io_channel_win32_poll() en llegir dades " +"d'un procés fill" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "La cadena buida no és un número" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "«%s» no és un nombre amb signe" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "El número «%s» està fora de rangs [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "«%s» no és un nombre sense signe" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Codificació %-e no vàlida en l'URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Caràcters no UTF-8 en l'URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caràcters no UTF-8 en l'URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Adreça IPv6 no vàlida «%.*s» en URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Adreça IP codificada incorrectament «%.*s» en URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nom d'amfitrió internacionalitzat incorrectament «%.*s» a l'URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "No s'ha pogut analitzar el port «%.*s» en l'URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "El port «%.*s» de l'URI està fora de rang" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "L'URI «%s» no és un URI absolut" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "L'URI «%s» no té un component amfitrió" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "L'URI no és absolut i no s'ha proporcionat cap URI base" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Falta «=» i el valor del paràmetre" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "No s'ha pogut ubicar memòria" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "El caràcter és fora de l'interval d'UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Seqüència no vàlida a l'entrada de la conversió" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "El caràcter és fora de l'interval d'UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function +#. g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been +#. preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using +#. this deprecated function. +#. * Please translate as literally as possible. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "No s'ha pogut carregar «/var/lib/dbus/machine-id» o «/etc/machine-id»: " diff --git a/po/ca@valencia.po b/po/ca@valencia.po new file mode 100644 index 0000000..0c6265e --- /dev/null +++ b/po/ca@valencia.po @@ -0,0 +1,5897 @@ +# glib translation to Catalan. +# Copyright © 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# Softcatalà , 2001. +# Jordi Mallach , 2002, 2003, 2004, 2005, 2006. +# Josep Puigdemont , 2006. +# Sílvia Miranda , 2011. +# Jordi Serratosa , 2012, 2017. +# Gil Forcada , 2008-2013, 2013, 2014, 2016. +# Jordi Mas i Hernàndez , 2016, 2017 +# Xavi Ivars , 2017. +msgid "" +msgstr "" +"Project-Id-Version: glib 2.8\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-09-29 06:41+0000\n" +"PO-Revision-Date: 2017-09-03 22:07+0200\n" +"Last-Translator: Xavi Ivars \n" +"Language-Team: Xavi Ivars\n" +"Language: ca-valencia\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: Virtaal 0.7.1\n" +"X-Project-Style: gnome\n" + +#: ../gio/gapplication.c:490 +msgid "GApplication options" +msgstr "Opcions de la GApplication" + +#: ../gio/gapplication.c:490 +msgid "Show GApplication options" +msgstr "Mostra les opcions de la GApplication" + +#: ../gio/gapplication.c:535 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Introduïu un mode de servei GApplication (utilitzeu-lo des de fitxers de " +"servei D-Bus)" + +#: ../gio/gapplication.c:547 +msgid "Override the application’s ID" +msgstr "Sobreescriu l'identificador de l'aplicació" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gio-tool.c:227 ../gio/gresource-tool.c:488 +#: ../gio/gsettings-tool.c:522 +msgid "Print help" +msgstr "Mostra l'ajuda" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:489 +#: ../gio/gresource-tool.c:557 +msgid "[COMMAND]" +msgstr "[ORDRE]" + +#: ../gio/gapplication-tool.c:49 ../gio/gio-tool.c:228 +msgid "Print version" +msgstr "Mostra la versió" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:528 +msgid "Print version information and exit" +msgstr "Mostra la informació de la versió i ix" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Llista les aplicacions" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Llista totes les aplicacions instal·lades que es poden activar per D-Bus " +"(mitjançant fitxers .desktop)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "Executa una aplicació" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "Executa l'aplicació (amb fitxers opcionals que s'han d'obrir)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "APPID [FITXER...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "Activa una acció" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "Invoca una acció de l'aplicació" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACCIÓ [PARÀMETRE]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Llista les accions disponibles" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "Llista les accions estàtiques d'una aplicació (del fitxer .desktop)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 ../gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "ORDRE" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "L'orde per la qual imprimir l'ajuda detallada" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identificador de l'aplicació en format D-Bus (p. ex.: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:665 +#: ../gio/glib-compile-resources.c:671 ../gio/glib-compile-resources.c:698 +#: ../gio/gresource-tool.c:495 ../gio/gresource-tool.c:561 +msgid "FILE" +msgstr "FITXER" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Noms de fitxers relatius opcionals o relatius, o URI que s'han d'obrir" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "ACCIÓ" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "El nom de l'acció que s'ha d'invocar" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARÀMETRE" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Paràmetre opcional per la invocació de l'acció, en format GVariant" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:526 +#: ../gio/gsettings-tool.c:614 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Es desconeix l'orde «%s»\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "Forma d'ús:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:551 +#: ../gio/gsettings-tool.c:649 +msgid "Arguments:\n" +msgstr "Arguments:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS…]" +msgstr "[ARGUMENTS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Ordes:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Feu servir «%s help ORDRE» per obtindre l'ajuda detallada.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"L'orde %s requereix que la seguïsca un identificador d'aplicació\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "l'identificador de l'aplicació no és vàlid: «%s»\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"«%s» no pren cap argument\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "no s'ha pogut connectar a D-Bus: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "s'ha produït un error en enviar el missatge %s: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "" +"s'ha de proporcionar el nom de l'acció després de l'identificador de " +"l'aplicació\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"el nom d'acció no és vàlid: «%s»\n" +"els noms d'acció han d'estar formats per caràcters alfanumèrics, «-» i «.»\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "s'ha produït un error en analitzar el paràmetre d'acció: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "les accions accepten com a màxim un paràmetre\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "" +"l'orde de llistat d'aplicacions (list-actions) només pren l'identificador " +"d'aplicació" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "no s'ha pogut trobar el fitxer d'escriptori de l'aplicació %s\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"es desconeix l'orde: «%s»\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:179 ../gio/ginputstream.c:379 +#: ../gio/ginputstream.c:617 ../gio/ginputstream.c:1019 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:834 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "El valor de comptatge passat a %s és massa gran" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "No està implementada la busca en el flux base" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "No es pot truncar el GBufferedInputStream" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1208 +#: ../gio/giostream.c:300 ../gio/goutputstream.c:1660 +msgid "Stream is already closed" +msgstr "Ja està tancat el flux" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "No es permet truncar en els fluxos base" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1849 +#: ../gio/gdbusprivate.c:1402 ../gio/gsimpleasyncresult.c:870 +#: ../gio/gsimpleasyncresult.c:896 +#, c-format +msgid "Operation was cancelled" +msgstr "S'ha cancel·lat l'operació" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "L'objecte no és vàlid, no s'ha inicialitzat" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "La seqüència de múltiples bytes de l'entrada no és completa" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "No hi ha prou espai a la destinació" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1257 ../glib/gconvert.c:438 ../glib/gconvert.c:845 +#: ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:866 ../glib/gutf8.c:1319 +msgid "Invalid byte sequence in conversion input" +msgstr "La seqüència de bytes a l'entrada de conversió no és vàlida" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 ../glib/gconvert.c:770 +#: ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "S'ha produït un error durant la conversió: %s" + +#: ../gio/gcharsetconverter.c:445 ../gio/gsocket.c:1089 +msgid "Cancellable initialization not supported" +msgstr "La cancel·lació de la inicialització no està implementada" + +#: ../gio/gcharsetconverter.c:456 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "No es permet la conversió entre els jocs de caràcters «%s» i «%s»" + +#: ../gio/gcharsetconverter.c:460 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "No s'ha pogut obrir el convertidor de «%s» a «%s»" + +#: ../gio/gcontenttype.c:358 +#, c-format +msgid "%s type" +msgstr "tipus %s" + +#: ../gio/gcontenttype-win32.c:177 +msgid "Unknown type" +msgstr "Tipus desconegut" + +#: ../gio/gcontenttype-win32.c:179 +#, c-format +msgid "%s filetype" +msgstr "tipus de fitxer %s" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "Este sistema operatiu no implementa les GCredentials" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "La vostra plataforma no implementa les GCredentials" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"Les GCredentials no contenen cap identificador de procés en este sistema " +"operatiu" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Este sistema operatiu no implementa el falsejament de credencials" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "No s'esperava un final de flux tan prompte" + +#: ../gio/gdbusaddress.c:155 ../gio/gdbusaddress.c:243 +#: ../gio/gdbusaddress.c:324 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "No es permet la clau «%s» en l'entrada de l'adreça «%s»" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"L'adreça «%s» no és vàlida (ha de ser, o bé un camí, o bé un tmpdir -" +"directori temporal-, o bé unes claus abstractes)" + +#: ../gio/gdbusaddress.c:195 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "L'entrada d'adreça «%s» té una parella clau/valor que no té sentit" + +#: ../gio/gdbusaddress.c:258 ../gio/gdbusaddress.c:339 +#, c-format +msgid "Error in address “%s†— the port attribute is malformed" +msgstr "" +"Hi ha un error a l'adreça «%s»: l'atribut del port no està ben formatat" + +#: ../gio/gdbusaddress.c:269 ../gio/gdbusaddress.c:350 +#, c-format +msgid "Error in address “%s†— the family attribute is malformed" +msgstr "" +"Hi ha un error a l'adreça «%s»: l'atribut de la família no està ben formatat" + +#: ../gio/gdbusaddress.c:460 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "L'element d'adreça «%s» no conté dos punts (:)" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"La parella de clau/valor %d, «%s», a l'element d'adreça «%s», no conté un " +"signe d'igual" + +#: ../gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"S'ha produït un error en suprimir l'escapament d'una clau o d'un valor en la " +"parella clau/valor %d, «%s», de l'element d'adreça «%s»" + +#: ../gio/gdbusaddress.c:573 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Hi ha un error a l'adreça «%s»: el transport unix requereix que hi haja " +"establida exactament una clau, o bé de tipus «path» (camí), o bé de tipus " +"«abstract» (abstracte)" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Hi ha un error a l'adreça «%s»: falta o està mal formatat l'atribut del nom " +"d'ordinador" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Hi ha un error a l'adreça «%s»: falta o està mal formatat l'atribut del port" + +#: ../gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Hi ha un error a l'adreça «%s»: l'atribut noncefile no existeix o està mal " +"formatat" + +#: ../gio/gdbusaddress.c:658 +msgid "Error auto-launching: " +msgstr "S'ha produït un error en executar-se automàticament: " + +#: ../gio/gdbusaddress.c:666 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" +"El transport «%s» per a l'adreça «%s» és desconegut o no està implementat" + +#: ../gio/gdbusaddress.c:704 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "S'ha produït un error en obrir el fitxer nonce «%s»: %s" + +#: ../gio/gdbusaddress.c:723 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "S'ha produït un error en llegir el fitxer nonce «%s»: %s" + +#: ../gio/gdbusaddress.c:732 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"S'ha produït un error en llegir el fitxer nonce «%s»: s'esperaven 16 bytes " +"però se n'han obtingut %d" + +#: ../gio/gdbusaddress.c:750 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"S'ha produït un error en escriure els continguts del fitxer nonce «%s» al " +"flux:" + +#: ../gio/gdbusaddress.c:959 +msgid "The given address is empty" +msgstr "L'adreça que s'ha indicat és buida" + +#: ../gio/gdbusaddress.c:1072 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "" +"No es pot engendrar un bus de missatge si s'executa com un altre usuari " +"(setuid)" + +#: ../gio/gdbusaddress.c:1079 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"No es pot engendrar un bus de missatge sense un identificador de màquina: " + +#: ../gio/gdbusaddress.c:1086 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "No es pot executar D-Bus automàticament sense X11 $DISPLAY" + +#: ../gio/gdbusaddress.c:1128 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "S'ha produït un error en engendrar la línia d'ordes «%s»: " + +#: ../gio/gdbusaddress.c:1345 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Premeu qualsevol tecla per tancar esta finestra)\n" + +#: ../gio/gdbusaddress.c:1499 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"El bus de sessió (D-Bus) no està en funcionament i l'arrencada automàtica no " +"ha funcionat" + +#: ../gio/gdbusaddress.c:1510 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"No s'ha pogut determinar l'adreça del bus de sessió (no està implementat en " +"este sistema operatiu)" + +#: ../gio/gdbusaddress.c:1648 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"No es pot determinar l'adreça del bus a través de la variable d'entorn " +"«DBUS_STARTER_BUS_TYPE»: conté un valor desconegut «%s»" + +#: ../gio/gdbusaddress.c:1657 ../gio/gdbusconnection.c:7155 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"No es pot determinar l'adreça del bus perquè la variable d'entorn " +"«DBUS_STARTER_BUS_TYPE» no està establida" + +#: ../gio/gdbusaddress.c:1667 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipus de bus desconegut %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "S'ha trobat una inesperada falta de contingut en llegir una línia" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"S'ha trobat una inesperada falta de contingut en llegir (de forma segura) " +"una línia" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"S'han exhaurit tots els mecanismes d'autenticació disponibles (s'han provat: " +"%s) (hi ha disponibles: %s)" + +#: ../gio/gdbusauth.c:1174 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" +"S'ha cancel·lat a través de GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:262 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "S'ha produït un error en obtindre la informació del directori «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:274 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Els permisos del directori «%s» no estan ben formatats. S'esperava el mode " +"0700 però s'ha obtingut el 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:296 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "S'ha produït un error en crear el directori %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:379 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "S'ha produït un error en obrir l'anell de claus «%s» per llegir-lo: " + +#: ../gio/gdbusauthmechanismsha1.c:403 ../gio/gdbusauthmechanismsha1.c:721 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"La línia %d de l'anell de claus a «%s» amb el contingut «%s» no està ben " +"formatada" + +#: ../gio/gdbusauthmechanismsha1.c:417 ../gio/gdbusauthmechanismsha1.c:735 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"El primer testimoni de la línia %d de l'anell de claus a «%s» amb el " +"contingut «%s» no està ben formatat" + +#: ../gio/gdbusauthmechanismsha1.c:432 ../gio/gdbusauthmechanismsha1.c:749 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"El segon testimoni de la línia %d de l'anell de claus a «%s» amb el " +"contingut «%s» no està ben formatat" + +#: ../gio/gdbusauthmechanismsha1.c:456 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" +"No s'ha trobat la galeta amb l'identificador %d a l'anell de claus a «%s»" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "S'ha produït un suprimir el fitxer de blocatge antic «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:569 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "S'ha produït un error en crear el fitxer de blocatge «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:600 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "" +"S'ha produït un error en tancar el fitxer (no enllaçat) de blocatge «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:611 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "S'ha produït un error en desenllaçar el fitxer de blocatge «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:688 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "" +"S'ha produït un error en obrir l'anell de claus «%s» per a escriptura: " + +#: ../gio/gdbusauthmechanismsha1.c:885 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" +"(A més a més, l'alliberació del blocatge per a «%s» també ha fallat: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2378 +msgid "The connection is closed" +msgstr "La connexió està tancada" + +#: ../gio/gdbusconnection.c:1879 +msgid "Timeout was reached" +msgstr "S'ha esgotat el temps d'espera" + +#: ../gio/gdbusconnection.c:2500 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"S'han trobat senyaladors no implementats en construir-se la part de la " +"connexió del client" + +#: ../gio/gdbusconnection.c:4124 ../gio/gdbusconnection.c:4471 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"No existeix la interfície «org.freedesktop.DBus.Properties» en l'objecte al " +"camí %s" + +#: ../gio/gdbusconnection.c:4266 +#, c-format +msgid "No such property '%s'" +msgstr "No existeix la propietat «%s»" + +#: ../gio/gdbusconnection.c:4278 +#, c-format +msgid "Property '%s' is not readable" +msgstr "La propietat «%s» no és de lectura" + +#: ../gio/gdbusconnection.c:4289 +#, c-format +msgid "Property '%s' is not writable" +msgstr "La propietat «%s» no és d'escriptura" + +#: ../gio/gdbusconnection.c:4309 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"S'ha produït un error en establir la propietat «%s»: s'esperava el tipus " +"«%s» però s'ha obtingut el «%s»" + +#: ../gio/gdbusconnection.c:4414 ../gio/gdbusconnection.c:4622 +#: ../gio/gdbusconnection.c:6586 +#, c-format +msgid "No such interface '%s'" +msgstr "No existeix la interfície «%s»" + +#: ../gio/gdbusconnection.c:4840 ../gio/gdbusconnection.c:7095 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "No existeix la interfície «%s» en l'objecte al camí %s" + +#: ../gio/gdbusconnection.c:4938 +#, c-format +msgid "No such method '%s'" +msgstr "No existeix el mètode «%s»" + +#: ../gio/gdbusconnection.c:4969 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "El tipus de missatge «%s» no correspon al tipus «%s» que s'esperava" + +#: ../gio/gdbusconnection.c:5167 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Ja hi ha un objecte exportat per a la interfície %s a %s" + +#: ../gio/gdbusconnection.c:5393 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "No s'ha pogut recuperar la propietat %s.%s" + +#: ../gio/gdbusconnection.c:5449 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "No s'ha pogut establir la propietat %s.%s" + +#: ../gio/gdbusconnection.c:5625 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "El mètode «%s» ha retornat un tipus «%s» però s'esperava «%s»" + +#: ../gio/gdbusconnection.c:6697 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "No existeix el mètode «%s» a la interfície «%s» amb la signatura «%s»" + +#: ../gio/gdbusconnection.c:6818 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Ja està exportat un subarbre per a %s" + +#: ../gio/gdbusconnection.c:7146 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"No es pot determinar l'adreça del bus a través de la variable d'entorn " +"«DBUS_STARTER_BUS_TYPE»: conté un valor desconegut «%s»" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "el tipus és no vàlid" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Missatge «METHOD_CALL»: falta el camp de capçalera «PATH» o «MEMBER»" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Missatge «METHOD_RETURN»: falta el camp de capçalera «REPLY_SERIAL»" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Missatge «ERROR»: falta el camp de capçalera «REPLY_SERIAL» o «ERROR_NAME»" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Missatge «SIGNAL»: falta el camp de capçalera «PATH», «INTERFACE» o «MEMBER»" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Missatge «SIGNAL»: el camp de la capçalera «PATH» utilitza el valor reservat " +"«/org/freedesktop/DBus/Local»" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"missatge «SIGNAL»: el camp de capçalera «INTERFACE» utilitza el valor " +"reservat «org.freedesktop.DBus.Local»" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Es volia llegir %lu byte però només s'han rebut %lu" +msgstr[1] "Es volien llegir %lu bytes però només s'han rebut %lu" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"S'esperava el byte «NUL» després de la cadena «%s» però s'ha trobat el byte " +"%d" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"S'esperava una cadena UTF-8 vàlida però s'han trobat bytes no vàlids a " +"l'òfset %d (la llargada de la cadena és %d). La cadena UTF-8 vàlida fins " +"aquell moment era «%s»" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "El valor analitzat «%s» no és un camí d'objecte D-Bus vàlid" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "El valor analitzat «%s» no és una signatura D-Bus vàlida" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"S'ha trobat una matriu de llargada %u byte. La llargada màxima és de 2<<26 " +"bytes (64 MiB)." +msgstr[1] "" +"S'ha trobat una matriu de llargada %u bytes. La llargada màxima és de 2<<26 " +"bytes (64 MiB)." + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"S'ha trobat una matriu de tipus «a%c» que s'esperava que tinguera una " +"llargada múltiple de %u bytes, però en realitat és de %u bytes" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "El valor analitzat «%s» per variant no és una signatura D-Bus vàlida" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"S'ha produït un error en convertir a estructura de dades la GVariant amb el " +"tipus de cadena «%s» del format de cable D-Bus" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valor d'ordenació de bits (endianness) no vàlid. S'esperava 0x6c («l») o " +"0x42 («B») però s'ha trobat el valor 0x%02x" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Versió major del protocol no vàlida. S'esperava 1 però s'ha trobat %d" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"S'ha trobat la capçalera de la signatura amb la signatura «%s», però el cos " +"és buit" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "El valor analitzat «%s» no és una signatura de D-Bus vàlida (pel cos)" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"No hi ha cap capçalera de la signatura en el missatge, però el cos és de %u " +"byte" +msgstr[1] "" +"No hi ha cap capçalera de la signatura en el missatge, però el cos és de %u " +"bytes" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "No s'ha pogut tornar a convertir el missatge a estructura de dades: " + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"No s'ha pogut convertir a seqüència de bits la GVariant de tipus cadena «%s» " +"al format de cable D-Bus" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"El missatge conté %d descriptors de fitxers, però el camp de la capçalera " +"n'indica %d" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "No s'ha pogut convertir a seqüència de bits el missatge: " + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"El cos del missatge té la signatura «%s» però no hi ha cap capçalera de " +"signatura" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"El cos del missatge té el tipus de signatura «%s» però la signatura en el " +"camp de la capçalera és «%s»" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"El cos del missatge és buit però la signatura en el camp de la capçalera és " +"«(%s)»" + +#: ../gio/gdbusmessage.c:3285 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "S'ha retornat un error amb el cos de tipus «%s»" + +#: ../gio/gdbusmessage.c:3293 +msgid "Error return with empty body" +msgstr "S'ha retornat un error amb el cos buit" + +#: ../gio/gdbusprivate.c:2066 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "No s'ha pogut obtindre el perfil de maquinari: %s" + +#: ../gio/gdbusprivate.c:2111 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" +"No s'ha pogut carregar «/var/lib/dbus/machine-id» o «/etc/machine-id»: " + +#: ../gio/gdbusproxy.c:1611 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "S'ha produït un error en cridar «StartServiceByName» per a %s: " + +#: ../gio/gdbusproxy.c:1634 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" +"S'ha obtingut una resposta inesperada %d per al mètode " +"«StartServiceByName(\"%s\")»" + +#: ../gio/gdbusproxy.c:2719 ../gio/gdbusproxy.c:2853 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"No es pot invocar el mètode: el servidor intermediari és per a un nom ben " +"conegut sense cap propietari i el servidor intermediari s'ha construït amb " +"el senyalador «G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START»" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "No es pot utilitzar l'espai de noms abstracte" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "No es pot especificar el fitxer «nonce» quan es crea un servidor" + +#: ../gio/gdbusserver.c:876 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "S'ha produït un error en escriure el fitxer nonce a «%s»: %s" + +#: ../gio/gdbusserver.c:1047 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "La cadena «%s» no és un GUID vàlid de D-Bus" + +#: ../gio/gdbusserver.c:1087 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "No es pot escoltar «%s», és un transport desconegut" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Ordes:\n" +" help Mostra esta informació\n" +" introspect Introspecciona un objecte remot\n" +" monitor Fa un seguiment d'un objecte remot\n" +" call Invoca un mètode en l'objecte remot\n" +" emit Emet un senyal\n" +" wait Espera que aparega un nom de bus\n" +"\n" +"Utilitzeu «%s ORDRE --help» per veure l'ajuda de cada orde en particular.\n" + +#: ../gio/gdbus-tool.c:165 ../gio/gdbus-tool.c:227 ../gio/gdbus-tool.c:299 +#: ../gio/gdbus-tool.c:323 ../gio/gdbus-tool.c:725 ../gio/gdbus-tool.c:1068 +#: ../gio/gdbus-tool.c:1510 +#, c-format +msgid "Error: %s\n" +msgstr "S'ha produït un error: %s\n" + +#: ../gio/gdbus-tool.c:176 ../gio/gdbus-tool.c:240 ../gio/gdbus-tool.c:1526 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "S'ha produït un error en analitzar la introspecció XML: %s\n" + +#: ../gio/gdbus-tool.c:209 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Error: %s no és un nom de membre vàlid\n" + +#: ../gio/gdbus-tool.c:357 +msgid "Connect to the system bus" +msgstr "Connecta al bus del sistema" + +#: ../gio/gdbus-tool.c:358 +msgid "Connect to the session bus" +msgstr "Connecta al bus de la sessió" + +#: ../gio/gdbus-tool.c:359 +msgid "Connect to given D-Bus address" +msgstr "Connecta a l'adreça de D-Bus donada" + +#: ../gio/gdbus-tool.c:369 +msgid "Connection Endpoint Options:" +msgstr "Opcions del punt final de connexió:" + +#: ../gio/gdbus-tool.c:370 +msgid "Options specifying the connection endpoint" +msgstr "Opcions d'especificació del punt final de connexió" + +#: ../gio/gdbus-tool.c:392 +#, c-format +msgid "No connection endpoint specified" +msgstr "No s'ha especificat el punt final de connexió" + +#: ../gio/gdbus-tool.c:402 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "S'han especificat més d'un punt final de connexió" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Avís: d'acord amb les dades d'introspecció no existeix la interfície «%s»\n" + +#: ../gio/gdbus-tool.c:481 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Avís: d'acord amb les dades d'introspecció no existeix el mètode «%s» a la " +"interfície «%s»\n" + +#: ../gio/gdbus-tool.c:543 +msgid "Optional destination for signal (unique name)" +msgstr "Destinació opcional del senyal (nom únic)" + +#: ../gio/gdbus-tool.c:544 +msgid "Object path to emit signal on" +msgstr "Camí a l'objecte al qual se li enviarà un senyal" + +#: ../gio/gdbus-tool.c:545 +msgid "Signal and interface name" +msgstr "Senyal i nom d'interfície" + +#: ../gio/gdbus-tool.c:579 +msgid "Emit a signal." +msgstr "Envia un senyal." + +#: ../gio/gdbus-tool.c:613 ../gio/gdbus-tool.c:858 ../gio/gdbus-tool.c:1616 +#: ../gio/gdbus-tool.c:1851 ../gio/gdbus-tool.c:2067 +#, c-format +msgid "Error connecting: %s\n" +msgstr "S'ha produït un error en connectar-se: %s\n" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "Error: no s'ha especificat el camí a l'objecte.\n" + +#: ../gio/gdbus-tool.c:630 ../gio/gdbus-tool.c:925 ../gio/gdbus-tool.c:1681 +#: ../gio/gdbus-tool.c:1917 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Error: «%s» no és un camí d'objecte vàlid\n" + +#: ../gio/gdbus-tool.c:636 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "Error: no s'ha especificat el senyal.\n" + +#: ../gio/gdbus-tool.c:643 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "Error: el senyal no pot ser un nom parcial.\n" + +#: ../gio/gdbus-tool.c:651 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Error: %s no és un nom d'interfície vàlid\n" + +#: ../gio/gdbus-tool.c:657 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Error: %s no és un nom de membre vàlid\n" + +#: ../gio/gdbus-tool.c:663 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Error: %s no és un nom de bus únic vàlid.\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:700 ../gio/gdbus-tool.c:1037 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "S'ha produït un error en analitzar el paràmetre %d: %s\n" + +#: ../gio/gdbus-tool.c:732 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "S'ha produït un error en buidar la connexió: %s\n" + +#: ../gio/gdbus-tool.c:759 +msgid "Destination name to invoke method on" +msgstr "Nom de destinació on invocar el mètode" + +#: ../gio/gdbus-tool.c:760 +msgid "Object path to invoke method on" +msgstr "Camí a l'objecte on invocar el mètode" + +#: ../gio/gdbus-tool.c:761 +msgid "Method and interface name" +msgstr "Mètode i nom d'interfície" + +#: ../gio/gdbus-tool.c:762 +msgid "Timeout in seconds" +msgstr "Temps d'espera, en segons" + +#: ../gio/gdbus-tool.c:803 +msgid "Invoke a method on a remote object." +msgstr "Invoca un mètode en un objecte remot." + +#: ../gio/gdbus-tool.c:878 ../gio/gdbus-tool.c:1635 ../gio/gdbus-tool.c:1870 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "Error: no s'ha especificat la destinació\n" + +#: ../gio/gdbus-tool.c:890 ../gio/gdbus-tool.c:1652 ../gio/gdbus-tool.c:1882 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Error: %s no és un nom de bus vàlid\n" + +#: ../gio/gdbus-tool.c:905 ../gio/gdbus-tool.c:1661 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "Error: no s'ha especificat el camí a l'objecte\n" + +#: ../gio/gdbus-tool.c:940 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "Error: no s'ha especificat el nom del mètode\n" + +#: ../gio/gdbus-tool.c:951 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Error: el nom del mètode «%s» no és vàlid\n" + +#: ../gio/gdbus-tool.c:1029 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "" +"S'ha produït un error en analitzar el paràmetre %d del tipus «%s»: %s\n" + +#: ../gio/gdbus-tool.c:1473 +msgid "Destination name to introspect" +msgstr "Nom de destinació a introspeccionar" + +#: ../gio/gdbus-tool.c:1474 +msgid "Object path to introspect" +msgstr "Camí a l'objecte a introspeccionar" + +#: ../gio/gdbus-tool.c:1475 +msgid "Print XML" +msgstr "Imprimeix XML" + +#: ../gio/gdbus-tool.c:1476 +msgid "Introspect children" +msgstr "Introspecciona el fill" + +#: ../gio/gdbus-tool.c:1477 +msgid "Only print properties" +msgstr "Només mostra les propietats" + +#: ../gio/gdbus-tool.c:1568 +msgid "Introspect a remote object." +msgstr "Introspecciona un objecte remot." + +#: ../gio/gdbus-tool.c:1773 +msgid "Destination name to monitor" +msgstr "Nom de destinació al qual se li vol fer un seguiment" + +#: ../gio/gdbus-tool.c:1774 +msgid "Object path to monitor" +msgstr "Camí a l'objecte al qual se li vol fer un seguiment" + +#: ../gio/gdbus-tool.c:1803 +msgid "Monitor a remote object." +msgstr "Fes el seguiment a un objecte remot." + +#: ../gio/gdbus-tool.c:1980 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Servei a activar abans d'esperar l'altre (nom conegut)" + +#: ../gio/gdbus-tool.c:1983 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Temps d'espera abans d'eixir amb un error (segons); 0 si no voleu temps " +"d'espera (predeterminat)" + +#: ../gio/gdbus-tool.c:2031 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPCIÓ...] NOM-DEL-BUS" + +#: ../gio/gdbus-tool.c:2033 +msgid "Wait for a bus name to appear." +msgstr "Espera que aparega el nom del bus." + +#: ../gio/gdbus-tool.c:2109 +#, c-format +msgid "Error: A service to activate for must be specified.\n" +msgstr "Error: no s'ha especificat el servei a activar.\n" + +#: ../gio/gdbus-tool.c:2114 +#, c-format +msgid "Error: A service to wait for must be specified.\n" +msgstr "Error: no s'ha especificat el servei a esperar.\n" + +#: ../gio/gdbus-tool.c:2119 +#, c-format +msgid "Error: Too many arguments.\n" +msgstr "Error: massa arguments.\n" + +#: ../gio/gdbus-tool.c:2127 ../gio/gdbus-tool.c:2134 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Error: %s no és un nom de bus conegut vàlid\n" + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4531 +msgid "Unnamed" +msgstr "Sense nom" + +#: ../gio/gdesktopappinfo.c:2411 +msgid "Desktop file didn’t specify Exec field" +msgstr "El fitxer d'escriptori no especificava el camp d'execució" + +#: ../gio/gdesktopappinfo.c:2694 +msgid "Unable to find terminal required for application" +msgstr "No s'ha pogut trobar el terminal que demanava l'aplicació" + +#: ../gio/gdesktopappinfo.c:3127 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"No s'ha pogut crear el directori de configuració de l'aplicació de l'usuari " +"%s: %s" + +#: ../gio/gdesktopappinfo.c:3131 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" +"No s'ha pogut crear el directori de configuració MIME de l'usuari %s: %s" + +#: ../gio/gdesktopappinfo.c:3371 ../gio/gdesktopappinfo.c:3395 +msgid "Application information lacks an identifier" +msgstr "A la informació d'aplicació li falta un identificador" + +#: ../gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "No s'ha pogut crear el fitxer d'escriptori de l'usuari %s" + +#: ../gio/gdesktopappinfo.c:3763 +#, c-format +msgid "Custom definition for %s" +msgstr "Definició personalitzada per a %s" + +#: ../gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "la unitat no implementa l'expulsió" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "la unitat no implementa l'expulsió o «eject_with_operation»" + +#: ../gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "la unitat no implementa el sondeig per si hi ha un suport" + +#: ../gio/gdrive.c:776 +msgid "drive doesn’t implement start" +msgstr "la unitat no implementa la inicialització" + +#: ../gio/gdrive.c:878 +msgid "drive doesn’t implement stop" +msgstr "la unitat no implementa l'aturada" + +#: ../gio/gdummytlsbackend.c:195 ../gio/gdummytlsbackend.c:317 +#: ../gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "El TLS no està implementat" + +#: ../gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "El DTLS no està implementat" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "No es pot gestionar la versió %d de la codificació del GEmblem" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" +"Un nombre de testimonis (%d) de la codificació del GEmblem no són formats " +"correctament" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "No es pot gestionar la versió %d de la codificació del GEmblemedIcon" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" +"Un nombre de testimonis (%d) en la codificació del GEmblemedIcon no són " +"formats correctament" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "S'esperava un GEmblem per a un GEmblemedIcon" + +#: ../gio/gfile.c:969 ../gio/gfile.c:1207 ../gio/gfile.c:1345 +#: ../gio/gfile.c:1583 ../gio/gfile.c:1638 ../gio/gfile.c:1696 +#: ../gio/gfile.c:1780 ../gio/gfile.c:1837 ../gio/gfile.c:1901 +#: ../gio/gfile.c:1956 ../gio/gfile.c:3602 ../gio/gfile.c:3657 +#: ../gio/gfile.c:3893 ../gio/gfile.c:3935 ../gio/gfile.c:4403 +#: ../gio/gfile.c:4814 ../gio/gfile.c:4899 ../gio/gfile.c:4989 +#: ../gio/gfile.c:5086 ../gio/gfile.c:5173 ../gio/gfile.c:5274 +#: ../gio/gfile.c:7815 ../gio/gfile.c:7905 ../gio/gfile.c:7989 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "L'operació no està implementada" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: ../gio/gfile.c:1468 +msgid "Containing mount does not exist" +msgstr "No existeix el punt de muntatge contenidor" + +#: ../gio/gfile.c:2515 ../gio/glocalfile.c:2377 +msgid "Can’t copy over directory" +msgstr "No es pot copiar al directori" + +#: ../gio/gfile.c:2575 +msgid "Can’t copy directory over directory" +msgstr "No es pot copiar el directori al directori" + +#: ../gio/gfile.c:2583 +msgid "Target file exists" +msgstr "Ja existeix el fitxer de destinació" + +#: ../gio/gfile.c:2602 +msgid "Can’t recursively copy directory" +msgstr "No es pot copiar el directori de forma recursiva" + +#: ../gio/gfile.c:2877 +msgid "Splice not supported" +msgstr "No es pot empalmar" + +#: ../gio/gfile.c:2881 +#, c-format +msgid "Error splicing file: %s" +msgstr "S'ha produït un error en empalmar el fitxer: %s" + +#: ../gio/gfile.c:3013 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"No està implementada la còpia (referències, clonacions) entre muntatges" + +#: ../gio/gfile.c:3017 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "No està implementada o no és vàlida la còpia (referències, clonacions)" + +#: ../gio/gfile.c:3022 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" +"No està implementada o no ha funcionat la còpia (referències, clonacions)" + +#: ../gio/gfile.c:3085 +msgid "Can’t copy special file" +msgstr "No es pot copiar el fitxer especial" + +#: ../gio/gfile.c:3883 +msgid "Invalid symlink value given" +msgstr "El valor donat per a l'enllaç simbòlic no és vàlid" + +#: ../gio/gfile.c:4044 +msgid "Trash not supported" +msgstr "No es pot utilitzar la paperera" + +#: ../gio/gfile.c:4156 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "En els noms de fitxers no pot haver-hi «%c»" + +#: ../gio/gfile.c:6602 ../gio/gvolume.c:363 +msgid "volume doesn’t implement mount" +msgstr "el volum no implementa el muntatge" + +#: ../gio/gfile.c:6711 +msgid "No application is registered as handling this file" +msgstr "" +"No hi ha cap aplicació que s'haja registrat per gestionar este fitxer" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "L'enumerador està tancat" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "L'enumerador de fitxer té una operació pendent" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Ja està tancat l'enumerador de fitxer" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "No es pot gestionar la versió %d de la codificació del GFileIcon" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Les dades d'entrada pel GFileIcon no són formades correctament" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "El flux no implementa «query_info»" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "No està implementada la busca en el flux" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "No es permet truncar en els fluxos d'entrada" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "No es permet truncar en els fluxos" + +#: ../gio/ghttpproxy.c:91 ../gio/gresolver.c:410 ../gio/gresolver.c:476 +#: ../glib/gconvert.c:1650 +msgid "Invalid hostname" +msgstr "El nom de l'ordinador no és vàlid" + +#: ../gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Resposta incorrecta del servidor intermediari d'HTTP" + +#: ../gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "La connexió al servidor intermediari d'HTTP no permesa" + +#: ../gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Ha fallat l'autenticació en el servidor intermediari d'HTTP" + +#: ../gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Cal autenticació en el servidor intermediari d'HTTP" + +#: ../gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Ha fallat la connexió al servidor intermediari d'HTTP: %i" + +#: ../gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "El servidor intermediari d'HTTP ha tancat la connexió inesperadament." + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nombre de testimonis erroni (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "El nom de classe %s no té tipus" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "El tipus %s no implementa la interfície GIcon" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "El tipus %s no té classe" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "El número de versió no és format correctament: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "El tipus %s no implementa «from_tokens()» a la interfície GIcon" + +#: ../gio/gicon.c:461 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "" +"No es pot gestionar la versió proporcionada de la codificació de la icona" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "No s'ha especificat cap adreça" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "L'adreça és massa llarga (%u)" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "L'adreça conté bits més enllà de la llargada del prefix" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "No s'ha pogut analitzar «%s» com a màscara d'adreça IP" + +#: ../gio/ginetsocketaddress.c:203 ../gio/ginetsocketaddress.c:220 +#: ../gio/gnativesocketaddress.c:106 ../gio/gunixsocketaddress.c:218 +msgid "Not enough space for socket address" +msgstr "No hi ha prou espai per a l'adreça del sòcol" + +#: ../gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "L'adreça de sòcol no és compatible" + +#: ../gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "El flux d'entrada no té implementada la lectura" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1218 ../gio/giostream.c:310 +#: ../gio/goutputstream.c:1670 +msgid "Stream has outstanding operation" +msgstr "El flux té una operació pendent" + +#: ../gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copia amb el fitxer" + +#: ../gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Mantén-lo amb el fitxer quan es mogui" + +#: ../gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "«version» no té arguments" + +#: ../gio/gio-tool.c:207 ../gio/gio-tool.c:223 ../glib/goption.c:857 +msgid "Usage:" +msgstr "Forma d'ús:" + +#: ../gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Mostra la informació de la versió i ix." + +#: ../gio/gio-tool.c:224 +msgid "[ARGS...]" +msgstr "[ARGUMENTS...]" + +#: ../gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Ordes:" + +#: ../gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatena fitxers i els mostra per l'eixida estàndard" + +#: ../gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copia un, o més, fitxers" + +#: ../gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Mostra informació sobre ubicacions" + +#: ../gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "Llista el contingut de les ubicacions" + +#: ../gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "Obteniu o establiu el gestor d'un tipus MIME" + +#: ../gio/gio-tool.c:234 +msgid "Create directories" +msgstr "Crea els directoris" + +#: ../gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "Fes un seguiment dels directoris per veure si hi ha canvis" + +#: ../gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "Munta o desmunta les ubicacions" + +#: ../gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "Mou un, o més, fitxers" + +#: ../gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "Obri els fitxers amb l'aplicació per defecte" + +#: ../gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "Canvia el nom del fitxer" + +#: ../gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "Suprimeix un o més fitxers" + +#: ../gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "Llig de l'entrada estàndard i guarda-ho" + +#: ../gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "Establiu un atribut de fitxer" + +#: ../gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "Mou els fitxers o directoris a la paperera" + +#: ../gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "Llista els continguts de les ubicacions en un arbre" + +#: ../gio/gio-tool.c:246 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Feu servir %s per obtindre ajuda detallada.\n" + +# +#: ../gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "S'ha produït un error en escriure a l'eixida estàndard" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-cat.c:133 ../gio/gio-tool-info.c:282 +#: ../gio/gio-tool-list.c:165 ../gio/gio-tool-mkdir.c:48 +#: ../gio/gio-tool-monitor.c:37 ../gio/gio-tool-monitor.c:39 +#: ../gio/gio-tool-monitor.c:41 ../gio/gio-tool-monitor.c:43 +#: ../gio/gio-tool-monitor.c:203 ../gio/gio-tool-mount.c:1141 +#: ../gio/gio-tool-open.c:45 ../gio/gio-tool-remove.c:48 +#: ../gio/gio-tool-rename.c:45 ../gio/gio-tool-set.c:89 +#: ../gio/gio-tool-trash.c:81 ../gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "UBICACIÓ" + +#: ../gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatena fitxers i els mostra per l'eixida estàndard." + +#: ../gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat funciona com l'eina tradicional cat, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar alguna cosa com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació." + +#: ../gio/gio-tool-cat.c:162 ../gio/gio-tool-info.c:313 +#: ../gio/gio-tool-mkdir.c:76 ../gio/gio-tool-monitor.c:228 +#: ../gio/gio-tool-open.c:71 ../gio/gio-tool-remove.c:72 +msgid "No locations given" +msgstr "No s'ha donat cap ubicació" + +#: ../gio/gio-tool-copy.c:42 ../gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "No hi ha cap directori de destinació" + +#: ../gio/gio-tool-copy.c:43 ../gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Mostra el progrés" + +#: ../gio/gio-tool-copy.c:44 ../gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Pregunta abans de sobreescriure" + +#: ../gio/gio-tool-copy.c:45 +msgid "Preserve all attributes" +msgstr "Conserva tots els atributs" + +#: ../gio/gio-tool-copy.c:46 ../gio/gio-tool-move.c:41 +#: ../gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "" +"Crea una còpia de seguretat dels fitxers existents al directori de destinació" + +#: ../gio/gio-tool-copy.c:47 +msgid "Never follow symbolic links" +msgstr "No seguïsques mai els enllaços simbòlics" + +#: ../gio/gio-tool-copy.c:72 ../gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "S'han transferit %s de %s (%s/s)" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "FONT" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +#: ../gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINACIÓ" + +#: ../gio/gio-tool-copy.c:103 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copia un, o més, fitxers des de la FONT a la DESTINACIÓ." + +#: ../gio/gio-tool-copy.c:105 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy és similar a l'eina tradicional cp, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar alguna cosa com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació." + +#: ../gio/gio-tool-copy.c:147 +#, c-format +msgid "Destination %s is not a directory" +msgstr "La destinació «%s» no és un directori" + +#: ../gio/gio-tool-copy.c:192 ../gio/gio-tool-move.c:185 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: voleu sobreescriure «%s»?" + +#: ../gio/gio-tool-info.c:34 +msgid "List writable attributes" +msgstr "Llista els atributs d'escriptura" + +#: ../gio/gio-tool-info.c:35 +msgid "Get file system info" +msgstr "Obté la informació del sistema de fitxers" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "The attributes to get" +msgstr "Els atributs que es volen obtindre" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "ATTRIBUTES" +msgstr "ATRIBUTS" + +#: ../gio/gio-tool-info.c:37 ../gio/gio-tool-list.c:38 ../gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "No seguïsques els enllaços simbòlics" + +#: ../gio/gio-tool-info.c:75 +#, c-format +msgid "attributes:\n" +msgstr "atributs:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "nom que es mostra: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "edita el nom: %s\n" + +#: ../gio/gio-tool-info.c:138 +#, c-format +msgid "name: %s\n" +msgstr "nom: %s\n" + +#: ../gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "tipus: %s\n" + +#: ../gio/gio-tool-info.c:151 +#, c-format +msgid "size: " +msgstr "mida: " + +#: ../gio/gio-tool-info.c:156 +#, c-format +msgid "hidden\n" +msgstr "ocult\n" + +#: ../gio/gio-tool-info.c:159 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: ../gio/gio-tool-info.c:228 +#, c-format +msgid "Settable attributes:\n" +msgstr "Atributs que es poden establir:\n" + +#: ../gio/gio-tool-info.c:252 +#, c-format +msgid "Writable attribute namespaces:\n" +msgstr "Espais de nom d'atributs d'escriptura:\n" + +#: ../gio/gio-tool-info.c:287 +msgid "Show information about locations." +msgstr "Mostra informació sobre ubicacions." + +#: ../gio/gio-tool-info.c:289 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info és similar a l'eina tradicional ls, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar alguna cosa com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació. Els atributs de fitxer " +"poden\n" +"especificar-se amb el seu nom GIO. Per exemple, standard::icon o usant només " +"el\n" +"nom d'espais, p. ex. unix, o usant «*», que coincideix amb tots els atributs." + +#: ../gio/gio-tool-list.c:36 ../gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Mostra els fitxers ocults" + +#: ../gio/gio-tool-list.c:37 +msgid "Use a long listing format" +msgstr "Utilitza un format de llistat ampliat" + +#: ../gio/gio-tool-list.c:39 +msgid "Print full URIs" +msgstr "Mostra els URI complets" + +#: ../gio/gio-tool-list.c:170 +msgid "List the contents of the locations." +msgstr "Llista el contingut de les ubicacions." + +#: ../gio/gio-tool-list.c:172 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list és similar a l'eina tradicional ls, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar alguna cosa com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació. Els atributs de fitxer " +"poden\n" +"especificar-se amb el seu nom GIO. Per exemple, standard::icon" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TIPUS-MIME" + +#: ../gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "GESTIONADOR" + +#: ../gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Obteniu o establiu el gestor d'un tipus MIME." + +#: ../gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Si no es dóna un gestor, mostra les aplicacions recomanades i registrades\n" +"pel tipus MIME. Si es dóna un gestor, s'estableix com a gestor per defecte\n" +"pel tipus MIME." + +#: ../gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Heu d'especificar un únic tipus MIME, i potser un gestor" + +#: ../gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "No hi ha cap aplicació per defecte per a «%s»\n" + +#: ../gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplicació per defecte per a «%s»: %s\n" + +#: ../gio/gio-tool-mime.c:127 +#, c-format +msgid "Registered applications:\n" +msgstr "Aplicacions registrades:\n" + +#: ../gio/gio-tool-mime.c:129 +#, c-format +msgid "No registered applications\n" +msgstr "No hi ha cap aplicació registrada\n" + +#: ../gio/gio-tool-mime.c:140 +#, c-format +msgid "Recommended applications:\n" +msgstr "Aplicacions recomanades:\n" + +#: ../gio/gio-tool-mime.c:142 +#, c-format +msgid "No recommended applications\n" +msgstr "No hi ha cap aplicació recomanada\n" + +#: ../gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "No s'ha pogut carregar la informació del gestor «%s»" + +#: ../gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"S'ha produït un error en establir «%s» com a gestor per defecte de «%s»: %s\n" + +#: ../gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Crea els directoris pare" + +#: ../gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Crea directoris." + +#: ../gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir és similar a l'eina tradicional mkdir, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar alguna cosa com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació." + +#: ../gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Fes el seguiment a un directori (per defecte: depèn del tipus)" + +#: ../gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Fes el seguiment a un fitxer (per defecte: depèn del tipus)" + +#: ../gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Fes el seguiment a un fitxer directament (s'adona de canvis fets mitjançant " +"enllaços forts)" + +#: ../gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Fes el seguiment a un fitxer directament, però no informa dels canvis" + +#: ../gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Informa de moviments i canvis de nom com a esdeveniments de supressió i " +"creació simples" + +#: ../gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Vigila els esdeveniments de muntatge" + +#: ../gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "Fes un seguiment dels directoris per veure si hi ha canvis." + +#: ../gio/gio-tool-mount.c:58 +msgid "Mount as mountable" +msgstr "Munta com a muntable" + +#: ../gio/gio-tool-mount.c:59 +msgid "Mount volume with device file" +msgstr "Munta el volum amb el fitxer de dispositiu" + +#: ../gio/gio-tool-mount.c:59 +msgid "DEVICE" +msgstr "DISPOSITIU" + +#: ../gio/gio-tool-mount.c:60 +msgid "Unmount" +msgstr "Desmunta" + +#: ../gio/gio-tool-mount.c:61 +msgid "Eject" +msgstr "Expulsa" + +#: ../gio/gio-tool-mount.c:62 +msgid "Unmount all mounts with the given scheme" +msgstr "Desmunta tots els muntables que complisquen l'esquema donat" + +#: ../gio/gio-tool-mount.c:62 +msgid "SCHEME" +msgstr "ESQUEMA" + +#: ../gio/gio-tool-mount.c:63 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignora les operacions de fitxers restants quan es desmunta o extreu" + +#: ../gio/gio-tool-mount.c:64 +msgid "Use an anonymous user when authenticating" +msgstr "Usa un usuari anònim en autenticar" + +#. Translator: List here is a verb as in 'List all mounts' +#: ../gio/gio-tool-mount.c:66 +msgid "List" +msgstr "Llista" + +#: ../gio/gio-tool-mount.c:67 +msgid "Monitor events" +msgstr "Fes un seguiment dels esdeveniments" + +#: ../gio/gio-tool-mount.c:68 +msgid "Show extra information" +msgstr "Mostra informació addicional" + +#: ../gio/gio-tool-mount.c:246 ../gio/gio-tool-mount.c:276 +msgid "Anonymous access denied" +msgstr "S'ha denegat l'accés anònim" + +#: ../gio/gio-tool-mount.c:897 +#, c-format +msgid "Mounted %s at %s\n" +msgstr "S'ha muntat %s a %s\n" + +#: ../gio/gio-tool-mount.c:950 +msgid "No volume for device file" +msgstr "No hi ha cap volum pel fitxer de dispositiu" + +#: ../gio/gio-tool-mount.c:1145 +msgid "Mount or unmount the locations." +msgstr "Munta o desmunta les ubicacions." + +#: ../gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "No usis el sistema alternatiu de copia i esborrat" + +#: ../gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Mou un, o més, fitxers des de la FONT a la DESTINACIÓ." + +#: ../gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move és similar a l'eina tradicional mv, però usant ubicacions GIO\n" +"en comptes de fitxers locals: per exemple, podeu usar alguna cosa com ara\n" +"smb://servidor/recurs/fitxer.txt com a ubicació." + +#: ../gio/gio-tool-move.c:142 +#, c-format +msgid "Target %s is not a directory" +msgstr "La destinació %s no és un directori" + +#: ../gio/gio-tool-open.c:50 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Obri els fitxers amb l'aplicació registrada per\n" +"defecte per gestionar este tipus de fitxer." + +#: ../gio/gio-tool-remove.c:31 ../gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignora els fitxers que no existisquen, no ho preguntes mai" + +#: ../gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Suprimeix els fitxers donats." + +#: ../gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOM" + +#: ../gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Canvia el nom del fitxer." + +#: ../gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Falta l'argument" + +#: ../gio/gio-tool-rename.c:76 ../gio/gio-tool-save.c:190 +#: ../gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Massa arguments" + +#: ../gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "S'ha canviat el nom correctament. URI nou: %s\n" + +#: ../gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Crea només si no existeix" + +#: ../gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Afig al final del fitxer" + +#: ../gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "En crear un fitxer, limita'n l'accés a només l'usuari actual" + +#: ../gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Quan es reemplaci, fes com si el destí no existís" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Mostra la nova etag al final" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "L'etag del fitxer que s'està sobreescrivint" + +#: ../gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: ../gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "S'ha produït un error en llegir de l'entrada estàndard" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:139 +#, c-format +msgid "Etag not available\n" +msgstr "L'etag no està disponible\n" + +#: ../gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Llig de l'entrada estàndard i guarda-ho a la DESTINACIÓ." + +#: ../gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "No s'ha donat una destinació" + +#: ../gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "El tipus de l'atribut" + +#: ../gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPUS" + +#: ../gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: ../gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALOR" + +#: ../gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Establiu un atribut de fitxer d'UBICACIÓ." + +#: ../gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "No s'ha especificat la ubicació" + +#: ../gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "No s'ha especificat l'atribut" + +#: ../gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "No s'ha especificat el valor" + +#: ../gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "El tipus d'atribut «%s» no és vàlid" + +#: ../gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "Buida la paperera" + +#: ../gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "Mou els fitxers o directoris a la paperera." + +#: ../gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Segueix els enllaços simbòlics, els punts de muntatge i les dreceres" + +#: ../gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Llista el contingut dels directoris en un format d'arbre." + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1501 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "No es permet posar l'element <%s> dins de <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "No es permet posar l'element <%s> al primer nivell" + +#: ../gio/glib-compile-resources.c:237 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "El fitxer %s existeix més d'una vegada en els recursos" + +#: ../gio/glib-compile-resources.c:248 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "No s'ha pogut trobar «%s» en cap directori de recursos" + +#: ../gio/glib-compile-resources.c:259 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "No s'ha pogut trobar «%s» en el directori actual" + +#: ../gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Es desconeix l'opció de processament «%s»" + +#: ../gio/glib-compile-resources.c:308 ../gio/glib-compile-resources.c:354 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "No s'ha pogut crear el fitxer temporal: %s" + +#: ../gio/glib-compile-resources.c:382 +#, c-format +msgid "Error reading file %s: %s" +msgstr "S'ha produït un error en llegir el fitxer %s: %s" + +#: ../gio/glib-compile-resources.c:402 +#, c-format +msgid "Error compressing file %s" +msgstr "S'ha produït un error en comprimir el fitxer %s" + +#: ../gio/glib-compile-resources.c:469 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "no pot haver-hi text dins de <%s>" + +#: ../gio/glib-compile-resources.c:664 ../gio/glib-compile-schemas.c:2067 +msgid "Show program version and exit" +msgstr "Mostra la versió del programa i ix" + +#: ../gio/glib-compile-resources.c:665 +msgid "name of the output file" +msgstr "el nom del fitxer d'eixida" + +#: ../gio/glib-compile-resources.c:666 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"Els directoris des d'on s'han de llegir els fitxers (per defecte és el " +"directori actual)" + +#: ../gio/glib-compile-resources.c:666 ../gio/glib-compile-schemas.c:2068 +#: ../gio/glib-compile-schemas.c:2096 +msgid "DIRECTORY" +msgstr "DIRECTORI" + +#: ../gio/glib-compile-resources.c:667 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Genera l'eixida en el format seleccionat per l'extensió del nom de fitxer " +"de destinació" + +#: ../gio/glib-compile-resources.c:668 +msgid "Generate source header" +msgstr "Genera la capçalera del codi" + +#: ../gio/glib-compile-resources.c:669 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" +"Genera el codi font que es fa servir per enllaçar el fitxer de recurs amb el " +"codi" + +#: ../gio/glib-compile-resources.c:670 +msgid "Generate dependency list" +msgstr "Genera una llista de dependències" + +#: ../gio/glib-compile-resources.c:671 +msgid "name of the dependency file to generate" +msgstr "nom del fitxer de dependència a generar" + +#: ../gio/glib-compile-resources.c:672 +msgid "Include phony targets in the generated dependency file" +msgstr "Inclou destinacions falses en el fitxer de dependències generat" + +#: ../gio/glib-compile-resources.c:673 +msgid "Don’t automatically create and register resource" +msgstr "No crees ni registris automàticament els recursos" + +#: ../gio/glib-compile-resources.c:674 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "No exportis les funcions, declara-les com a «G_GNUC_INTERNAL»" + +#: ../gio/glib-compile-resources.c:675 +msgid "C identifier name used for the generated source code" +msgstr "" +"El nom de l'identificador de C que s'utilitzarà en el codi font generat" + +#: ../gio/glib-compile-resources.c:701 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compila una especificació de recursos en un fitxer de recursos.\n" +"Els fitxers d'especificació de recursos tenen l'extensió .gresource.xml\n" +"i els fitxers de recursos tenen l'extensió .gresource." + +#: ../gio/glib-compile-resources.c:723 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "Heu de donar un sol nom de fitxer\n" + +#: ../gio/glib-compile-schemas.c:95 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "el nom ha de ser com a mínim de 2 caràcters" + +#: ../gio/glib-compile-schemas.c:106 +#, c-format +msgid "Invalid numeric value" +msgstr "El valor numèric no és vàlid" + +#: ../gio/glib-compile-schemas.c:114 +#, c-format +msgid " already specified" +msgstr " ja s'ha especificat" + +#: ../gio/glib-compile-schemas.c:122 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' ja s'ha especificat" + +#: ../gio/glib-compile-schemas.c:136 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "els indicadors han de tindre com a mínim 1 bit establit" + +#: ../gio/glib-compile-schemas.c:161 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> ha de contindre com a mínim un " + +#: ../gio/glib-compile-schemas.c:315 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> no està en el rang especificat" + +#: ../gio/glib-compile-schemas.c:327 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> no és un membre vàlid del tipus enumerat especificat" + +#: ../gio/glib-compile-schemas.c:333 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> conté una cadena no especificada en el tipus d'indicadors" + +#: ../gio/glib-compile-schemas.c:339 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> conté una cadena que no està a " + +# +#: ../gio/glib-compile-schemas.c:373 +msgid " already specified for this key" +msgstr "el ja està especificat per a esta clau" + +#: ../gio/glib-compile-schemas.c:391 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " no està permés per a claus del tipus «%s»" + +#: ../gio/glib-compile-schemas.c:408 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "el mínim especificat per al és major que el màxim" + +#: ../gio/glib-compile-schemas.c:433 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categoria de l10n no admesa: %s" + +#: ../gio/glib-compile-schemas.c:441 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n demanada, però no s'ha especificat un domini de gettext" + +#: ../gio/glib-compile-schemas.c:453 +msgid "translation context given for value without l10n enabled" +msgstr "" +"s'ha especificat un context de traducció per al valor sense l10n habilitat" + +#: ../gio/glib-compile-schemas.c:475 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "No s'ha pogut analitzar el valor del tipus «%s»" + +#: ../gio/glib-compile-schemas.c:492 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" no es pot especificar per als tipus etiquetats que contenen un " +"tipus enumerat" + +# +#: ../gio/glib-compile-schemas.c:501 +msgid " already specified for this key" +msgstr " ja està especificat per a esta clau" + +#: ../gio/glib-compile-schemas.c:513 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " no està permés per a claus del tipus «%s»" + +#: ../gio/glib-compile-schemas.c:529 +#, c-format +msgid " already given" +msgstr "ja està especificat " + +#: ../gio/glib-compile-schemas.c:544 +#, c-format +msgid " must contain at least one " +msgstr " ha de contindre com a mínim un " + +# +#: ../gio/glib-compile-schemas.c:558 +msgid " already specified for this key" +msgstr " ja està especificat per a esta clau" + +#: ../gio/glib-compile-schemas.c:562 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" només es poden especificar per a claus amb tipus enumerats o " +"d'indicadors després de " + +#: ../gio/glib-compile-schemas.c:581 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +"s'ha especificat quan «%s» ja és membre del tipus " +"enumerat" + +#: ../gio/glib-compile-schemas.c:587 +#, c-format +msgid " given when was already given" +msgstr "" +"s'ha especificat quan ja s'havia " +"proporcionat" + +#: ../gio/glib-compile-schemas.c:595 +#, c-format +msgid " already specified" +msgstr "ja està especificat " + +#: ../gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "l'àlies de destinació «%s» no està en el tipus enumerat" + +#: ../gio/glib-compile-schemas.c:606 +#, c-format +msgid "alias target “%s†is not in " +msgstr "l'àlies de destinació «%s» no està a " + +#: ../gio/glib-compile-schemas.c:621 +#, c-format +msgid " must contain at least one " +msgstr " ha de contindre com a mínim un " + +# +#: ../gio/glib-compile-schemas.c:786 +msgid "Empty names are not permitted" +msgstr "No es permet utilitzar noms buits" + +#: ../gio/glib-compile-schemas.c:796 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" +"El nom «%s» no és vàlid: els noms han de començar amb una lletra minúscula" + +#: ../gio/glib-compile-schemas.c:808 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"El nom «%s» no és vàlid: el caràcter «%c» no és vàlid. Només es permeten " +"lletres minúscules, nombres i el guionet («-»)." + +#: ../gio/glib-compile-schemas.c:817 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"El nom «%s» no és vàlid: no es poden posar dos guionets seguits («--»)." + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "El nom «%s» no és vàlid: l'últim caràcter no pot ser un guionet («-»)." + +#: ../gio/glib-compile-schemas.c:834 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "El nom «%s» no és vàlid: la llargada màxima és de 1024" + +#: ../gio/glib-compile-schemas.c:904 +#, c-format +msgid " already specified" +msgstr "ja està especificat " + +# +#: ../gio/glib-compile-schemas.c:930 +msgid "Cannot add keys to a “list-of†schema" +msgstr "No es poden afegir claus a un esquema del tipus «list-of»" + +#: ../gio/glib-compile-schemas.c:941 +#, c-format +msgid " already specified" +msgstr "ja està especificat " + +#: ../gio/glib-compile-schemas.c:959 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +"La emmascara la a . " +"Utilitzeu per modificar-ne el valor." + +#: ../gio/glib-compile-schemas.c:970 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"L'atribut de la ha de ser necessàriament «type», «enum» o «flags»" + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "(encara) no s'ha definit <%s id='%s'>." + +#: ../gio/glib-compile-schemas.c:1004 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "El tipus de cadena GVariant «%s» no és vàlid" + +# +#: ../gio/glib-compile-schemas.c:1034 +msgid " given but schema isn’t extending anything" +msgstr "S'ha indicat però l'esquema no està ampliant res" + +#: ../gio/glib-compile-schemas.c:1047 +#, c-format +msgid "No to override" +msgstr "No hi ha cap a sobreescriure" + +#: ../gio/glib-compile-schemas.c:1055 +#, c-format +msgid " already specified" +msgstr "ja s'ha especificat " + +#: ../gio/glib-compile-schemas.c:1128 +#, c-format +msgid " already specified" +msgstr "ja s'ha especificat " + +#: ../gio/glib-compile-schemas.c:1140 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "El amplia l'esquema «%s» que encara no existeix" + +#: ../gio/glib-compile-schemas.c:1156 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" +"El és una llista d'un esquema «%s» que encara no existeix" + +#: ../gio/glib-compile-schemas.c:1164 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "No pot ser una llista d'un esquema amb un camí" + +#: ../gio/glib-compile-schemas.c:1174 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "No es pot ampliar un esquema amb un camí" + +#: ../gio/glib-compile-schemas.c:1184 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +"El és una llista i amplia el que no és una " +"llista" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +"El amplia el " +"però «%s» no amplia «%s»" + +#: ../gio/glib-compile-schemas.c:1211 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Si es dóna un camí ha de començar i acabar amb una barra inclinada" + +#: ../gio/glib-compile-schemas.c:1218 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "El camí d'una llista ha d'acabar amb «:/»" + +#: ../gio/glib-compile-schemas.c:1227 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Avís: l'esquema «%s» conté el camí «%s». Els camins que comencen amb «/" +"apps/», «/desktop/» o «/system/» estan obsolets." + +#: ../gio/glib-compile-schemas.c:1257 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "ja s'ha especificat <%s id='%s'>" + +#: ../gio/glib-compile-schemas.c:1407 ../gio/glib-compile-schemas.c:1423 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "No es permet posar l'element <%s> dins de <%s>" + +#: ../gio/glib-compile-schemas.c:1505 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "No es permet posar l'element <%s> al primer nivell" + +#: ../gio/glib-compile-schemas.c:1523 +msgid "Element is required in " +msgstr "L'element està requerit a " + +#: ../gio/glib-compile-schemas.c:1613 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "No pot haver-hi text dins de <%s>" + +#: ../gio/glib-compile-schemas.c:1681 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Avís: referència no definida a " + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1820 ../gio/glib-compile-schemas.c:1894 +#: ../gio/glib-compile-schemas.c:1970 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "S'ha especificat «--strict», se ix.\n" + +#: ../gio/glib-compile-schemas.c:1830 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "S'ha ignorat el fitxer sencer.\n" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "Ignoring this file.\n" +msgstr "S'està ignorant este fitxer.\n" + +#: ../gio/glib-compile-schemas.c:1930 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"No existeix la clau «%s» en l'esquema «%s» tal com especifica el fitxer de " +"sobreescriptura «%s»" + +#: ../gio/glib-compile-schemas.c:1936 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2022 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; s'està ignorant la sobreescriptura d'esta clau.\n" + +#: ../gio/glib-compile-schemas.c:1940 ../gio/glib-compile-schemas.c:1998 +#: ../gio/glib-compile-schemas.c:2026 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " i s'havia especificat «--strict», se ix.\n" + +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"s'ha produït un error en analitzar la clau «%s» en l'esquema «%s» tal com " +"especifica el fitxer de sobreescriptura «%s»: %s." + +#: ../gio/glib-compile-schemas.c:1966 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "S'està ignorant la sobreescriptura d'esta clau.\n" + +#: ../gio/glib-compile-schemas.c:1984 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"la sobreescriptura de la clau «%s» de l'esquema «%s» en el fitxer de " +"sobreescriptura «%s» és fora de l'interval de l'esquema donat" + +#: ../gio/glib-compile-schemas.c:2012 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"la sobreescriptura de la clau «%s» de l'esquema «%s» en el fitxer de " +"sobreescriptura «%s» no és a la llista de valors vàlids" + +#: ../gio/glib-compile-schemas.c:2068 +msgid "where to store the gschemas.compiled file" +msgstr "on guardar el fitxer gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2069 +msgid "Abort on any errors in schemas" +msgstr "Interromp si hi ha cap error en els esquemes" + +#: ../gio/glib-compile-schemas.c:2070 +msgid "Do not write the gschema.compiled file" +msgstr "No escrigues el fitxer gschema.compiled" + +#: ../gio/glib-compile-schemas.c:2071 +msgid "Do not enforce key name restrictions" +msgstr "No siguis estricte amb les restriccions dels noms de les claus" + +#: ../gio/glib-compile-schemas.c:2099 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compila tots els fitxers d'esquema GSettings en una memòria cau d'esquemes.\n" +"Els fitxers d'esquema han de tindre l'extensió .gschema.xml\n" +"i el fitxer de memòria cau es dirà gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:2120 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "Heu de donar un sol nom de directori\n" + +#: ../gio/glib-compile-schemas.c:2162 +#, c-format +msgid "No schema files found: " +msgstr "No s'ha trobat cap fitxer d'esquemes: " + +#: ../gio/glib-compile-schemas.c:2165 +#, c-format +msgid "doing nothing.\n" +msgstr "no faces res.\n" + +#: ../gio/glib-compile-schemas.c:2168 +#, c-format +msgid "removed existing output file.\n" +msgstr "suprimeix el fitxer d'eixida actual.\n" + +#: ../gio/glocalfile.c:643 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "El nom del fitxer no és vàlid: %s" + +#: ../gio/glocalfile.c:1037 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "" +"S'ha produït un error en obtindre la informació del sistema de fitxers per " +"%s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: ../gio/glocalfile.c:1176 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "No s'ha trobat el punt del muntatge pel fitxer %s" + +#: ../gio/glocalfile.c:1199 +msgid "Can’t rename root directory" +msgstr "No es pot canviar el nom del directori arrel" + +#: ../gio/glocalfile.c:1217 ../gio/glocalfile.c:1240 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "S'ha produït un error en canviar el nom del fitxer %s: %s" + +#: ../gio/glocalfile.c:1224 +msgid "Can’t rename file, filename already exists" +msgstr "No es pot canviar el nom del fitxer, ja existeix este nom" + +#: ../gio/glocalfile.c:1237 ../gio/glocalfile.c:2253 ../gio/glocalfile.c:2281 +#: ../gio/glocalfile.c:2438 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "Nom de fitxer no vàlid" + +#: ../gio/glocalfile.c:1404 ../gio/glocalfile.c:1419 +#, c-format +msgid "Error opening file %s: %s" +msgstr "S'ha produït un error en obrir el fitxer %s: %s" + +#: ../gio/glocalfile.c:1544 +#, c-format +msgid "Error removing file %s: %s" +msgstr "S'ha produït un error en suprimir el fitxer %s: %s" + +#: ../gio/glocalfile.c:1928 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "S'ha produït un error en enviar a la paperera el fitxer %s: %s" + +#: ../gio/glocalfile.c:1951 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "No s'ha pogut crear el directori de la paperera %s: %s" + +#: ../gio/glocalfile.c:1971 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "No s'ha pogut trobar el directori superior per a la paperera %s" + +#: ../gio/glocalfile.c:2050 ../gio/glocalfile.c:2070 +#, c-format +msgid "Unable to find or create trash directory for %s" +msgstr "No s'ha pogut trobar o crear el directori de la paperera per %s" + +#: ../gio/glocalfile.c:2105 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "No s'ha pogut crear el fitxer d'informació de la paperera per %s: %s" + +#: ../gio/glocalfile.c:2164 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"No s'ha pogut enviar el fitxer %s a la paperera als límits del sistema de " +"fitxers" + +#: ../gio/glocalfile.c:2168 ../gio/glocalfile.c:2224 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "No s'ha pogut enviar el fitxer a la paperera %s: %s" + +#: ../gio/glocalfile.c:2230 +#, c-format +msgid "Unable to trash file %s" +msgstr "No s'ha pogut enviar el fitxer %s a la paperera" + +#: ../gio/glocalfile.c:2256 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "S'ha produït un error en crear el directori %s: %s" + +#: ../gio/glocalfile.c:2285 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "El sistema de fitxers no implementa enllaços simbòlics" + +#: ../gio/glocalfile.c:2288 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "S'ha produït un error en fer l'enllaç simbòlic: %s: %s" + +#: ../gio/glocalfile.c:2294 ../glib/gfileutils.c:2077 +msgid "Symbolic links not supported" +msgstr "No es poden utilitzar els enllaços simbòlics" + +#: ../gio/glocalfile.c:2349 ../gio/glocalfile.c:2384 ../gio/glocalfile.c:2441 +#, c-format +msgid "Error moving file %s: %s" +msgstr "S'ha produït un error en moure el fitxer %s: %s" + +#: ../gio/glocalfile.c:2372 +msgid "Can’t move directory over directory" +msgstr "No s'ha pogut moure el directori al directori" + +#: ../gio/glocalfile.c:2398 ../gio/glocalfileoutputstream.c:933 +#: ../gio/glocalfileoutputstream.c:947 ../gio/glocalfileoutputstream.c:962 +#: ../gio/glocalfileoutputstream.c:979 ../gio/glocalfileoutputstream.c:993 +msgid "Backup file creation failed" +msgstr "Ha fallat la creació del fitxer de còpia de seguretat" + +#: ../gio/glocalfile.c:2417 +#, c-format +msgid "Error removing target file: %s" +msgstr "S'ha produït un error en suprimir el fitxer objectiu: %s" + +#: ../gio/glocalfile.c:2431 +msgid "Move between mounts not supported" +msgstr "No està implementat moure entre muntatges" + +#: ../gio/glocalfile.c:2622 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "No s'han pogut determinar l'ús del disc de %s: %s" + +#: ../gio/glocalfileinfo.c:731 +msgid "Attribute value must be non-NULL" +msgstr "El valor de l'atribut no pot ser nul" + +#: ../gio/glocalfileinfo.c:738 +msgid "Invalid attribute type (string expected)" +msgstr "Tipus d'atribut no vàlid (s'esperava una cadena)" + +#: ../gio/glocalfileinfo.c:745 +msgid "Invalid extended attribute name" +msgstr "El nom de l'atribut ampliat no és vàlid" + +#: ../gio/glocalfileinfo.c:785 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "S'ha produït un error en establir l'atribut ampliat «%s»: %s" + +#: ../gio/glocalfileinfo.c:1586 +msgid " (invalid encoding)" +msgstr " (codificació no vàlida)" + +#: ../gio/glocalfileinfo.c:1777 ../gio/glocalfileoutputstream.c:811 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "S'ha produït un error en obtindre informació del fitxer «%s»: %s" + +#: ../gio/glocalfileinfo.c:2028 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" +"S'ha produït un error en obtindre informació del descriptor de fitxer: %s" + +#: ../gio/glocalfileinfo.c:2073 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tipus d'atribut no vàlid (s'esperava un uint32)" + +#: ../gio/glocalfileinfo.c:2091 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tipus d'atribut no vàlid (s'esperava un uint64)" + +#: ../gio/glocalfileinfo.c:2110 ../gio/glocalfileinfo.c:2129 +msgid "Invalid attribute type (byte string expected)" +msgstr "Tipus d'atribut no vàlid (s'esperava una cadena de bytes)" + +#: ../gio/glocalfileinfo.c:2164 +msgid "Cannot set permissions on symlinks" +msgstr "No es poden establir permisos en els enllaços simbòlics" + +#: ../gio/glocalfileinfo.c:2180 +#, c-format +msgid "Error setting permissions: %s" +msgstr "S'ha produït un error en establir els permisos: %s" + +#: ../gio/glocalfileinfo.c:2231 +#, c-format +msgid "Error setting owner: %s" +msgstr "S'ha produït un error en establir el propietari: %s" + +#: ../gio/glocalfileinfo.c:2254 +msgid "symlink must be non-NULL" +msgstr "l'enllaç simbòlic no pot ser nul" + +#: ../gio/glocalfileinfo.c:2264 ../gio/glocalfileinfo.c:2283 +#: ../gio/glocalfileinfo.c:2294 +#, c-format +msgid "Error setting symlink: %s" +msgstr "S'ha produït un error en establir l'enllaç simbòlic: %s" + +#: ../gio/glocalfileinfo.c:2273 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"S'ha produït un error en establir l'enllaç simbòlic: el fitxer no és un " +"enllaç simbòlic" + +#: ../gio/glocalfileinfo.c:2399 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" +"S'ha produït un error en establir el temps de modificació o d'accés: %s" + +#: ../gio/glocalfileinfo.c:2422 +msgid "SELinux context must be non-NULL" +msgstr "El context del SELinux no pot ser nul" + +#: ../gio/glocalfileinfo.c:2437 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "S'ha produït un error en establir el context del SELinux: %s" + +#: ../gio/glocalfileinfo.c:2444 +msgid "SELinux is not enabled on this system" +msgstr "Este sistema no té habilitat el SELinux" + +#: ../gio/glocalfileinfo.c:2536 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "No està implementat establir l'atribut %s" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "S'ha produït un error en llegir des del fitxer: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1011 +#, c-format +msgid "Error seeking in file: %s" +msgstr "S'ha produït un error en buscar en el fitxer: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "S'ha produït un error en tancar el fitxer: %s" + +#: ../gio/glocalfilemonitor.c:840 +msgid "Unable to find default local file monitor type" +msgstr "" +"No s'ha pogut trobar el tipus de seguiment de fitxer local predeterminat" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "S'ha produït un error en escriure al fitxer: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" +"S'ha produït un error en suprimir l'enllaç de còpia de seguretat antic: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "S'ha produït un error en crear la còpia de seguretat: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "S'ha produït un error en canviar el nom del fitxer temporal: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1062 +#, c-format +msgid "Error truncating file: %s" +msgstr "S'ha produït un error en truncar el fitxer: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:793 +#: ../gio/glocalfileoutputstream.c:1043 ../gio/gsubprocess.c:380 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "S'ha produït un error en obrir el fitxer %s: %s" + +#: ../gio/glocalfileoutputstream.c:824 +msgid "Target file is a directory" +msgstr "El fitxer objectiu és un directori" + +#: ../gio/glocalfileoutputstream.c:829 +msgid "Target file is not a regular file" +msgstr "El fitxer objectiu no és un fitxer regular" + +#: ../gio/glocalfileoutputstream.c:841 +msgid "The file was externally modified" +msgstr "El fitxer ha estat modificat des d'alguna aplicació externa" + +#: ../gio/glocalfileoutputstream.c:1027 +#, c-format +msgid "Error removing old file: %s" +msgstr "S'ha produït un error en suprimir el fitxer vell: %s" + +#: ../gio/gmemoryinputstream.c:474 ../gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "El GSeekType proporcionat no és vàlid" + +#: ../gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "La sol·licitud de busca és no vàlida" + +#: ../gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "No es pot truncar el GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "El flux d'eixida de memòria no és modificable" + +#: ../gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Ha fallat el redimensionament de la memòria del flux d'eixida" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"La quantitat de memòria necessària per processar l'escriptura és més gran " +"que l'espai d'adreces disponible" + +#: ../gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "S'ha sol·licitat un desplaçament abans de l'inici del flux" + +#: ../gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "S'ha sol·licitat un desplaçament més enllà del final del flux" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn’t implement “unmountâ€" +msgstr "el muntatge no implementa el desmuntatge («unmount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn’t implement “ejectâ€" +msgstr "el muntatge no implementa l'expulsió («eject»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"el muntatge no implementa el desmuntatge («unmount») o " +"l'«unmount_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"el muntatge no implementa l'expulsió («eject») o l'«eject_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn’t implement “remountâ€" +msgstr "el muntatge no implementa tornar-se a muntar («remount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn’t implement content type guessing" +msgstr "el muntatge no implementa l'estimació de tipus de contingut" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "el muntatge no implementa l'estimació de tipus de contingut síncron" + +#: ../gio/gnetworkaddress.c:378 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "El nom de l'ordinador «%s» conté «[» però no «]»" + +#: ../gio/gnetworkmonitorbase.c:206 ../gio/gnetworkmonitorbase.c:310 +msgid "Network unreachable" +msgstr "No es pot accedir a la xarxa" + +#: ../gio/gnetworkmonitorbase.c:244 ../gio/gnetworkmonitorbase.c:274 +msgid "Host unreachable" +msgstr "No es pot accedir a la màquina" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "No s'ha pogut crear el monitor de xarxa: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "No s'ha pogut crear el monitor de xarxa: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "No s'ha pogut obtindre l'estat de la xarxa: " + +#: ../gio/gnetworkmonitornm.c:329 +#, c-format +msgid "NetworkManager version too old" +msgstr "La versió del NetworkManager és massa antiga" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:560 +msgid "Output stream doesn’t implement write" +msgstr "El flux d'eixida no implementa l'escriptura" + +#: ../gio/goutputstream.c:521 ../gio/goutputstream.c:1224 +msgid "Source stream is already closed" +msgstr "El flux font ja està tancat" + +#: ../gio/gresolver.c:342 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "S'ha produït un error en resoldre «%s»: %s" + +#: ../gio/gresource.c:606 ../gio/gresource.c:857 ../gio/gresource.c:874 +#: ../gio/gresource.c:998 ../gio/gresource.c:1070 ../gio/gresource.c:1143 +#: ../gio/gresource.c:1213 ../gio/gresourcefile.c:453 +#: ../gio/gresourcefile.c:576 ../gio/gresourcefile.c:713 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "No existeix el recurs a «%s»" + +#: ../gio/gresource.c:771 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "No s'ha pogut descomprimir el recurs «%s»" + +#: ../gio/gresourcefile.c:709 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "El recurs a «%s» no és un directori" + +#: ../gio/gresourcefile.c:917 +msgid "Input stream doesn’t implement seek" +msgstr "El flux d'entrada no té implementada la busca" + +#: ../gio/gresource-tool.c:494 +msgid "List sections containing resources in an elf FILE" +msgstr "Llista les seccions que contenen recursos en un FITXER elf" + +#: ../gio/gresource-tool.c:500 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Llista recursos\n" +"Si s'especifica una SECCIÓ, només es llisten els recursos d'aquella secció\n" +"Si s'especifica un CAMÃ, només es llisten els recursos que hi coincidisquen" + +#: ../gio/gresource-tool.c:503 ../gio/gresource-tool.c:513 +msgid "FILE [PATH]" +msgstr "FITXER [CAMÃ]" + +#: ../gio/gresource-tool.c:504 ../gio/gresource-tool.c:514 +#: ../gio/gresource-tool.c:521 +msgid "SECTION" +msgstr "SECCIÓ" + +#: ../gio/gresource-tool.c:509 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Llista els recursos amb les seues dades\n" +"Si s'especifica la SECCIÓ, només es mostren els recursos de la secció\n" +"Si s'especifica el CAMÃ, només es mostren els recursos que hi coincidisquen\n" +"Les dades són la secció, la mida i la compressió" + +#: ../gio/gresource-tool.c:519 +msgid "Extract a resource file to stdout" +msgstr "Extreu un fitxer de recurs a l'eixida estàndard" + +#: ../gio/gresource-tool.c:520 +msgid "FILE PATH" +msgstr "CAMà AL FITXER" + +#: ../gio/gresource-tool.c:534 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Ús:\n" +" gresource [--section SECCIÓ] ORDRE [ARGUMENTS...]\n" +"\n" +"Ordes:\n" +" help Mostra esta informació\n" +" sections Llista les seccions de recursos\n" +" list Llista els recursos\n" +" details Llista els recursos amb les seues dades\n" +" extract Extreu un recurs\n" +"\n" +"Utilitzeu «gresource help ORDRE» per obtindre informació més detallada.\n" +"\n" + +#: ../gio/gresource-tool.c:548 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilització:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:555 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECCIÓ El nom (opcional) d'una secció elf\n" + +#: ../gio/gresource-tool.c:559 ../gio/gsettings-tool.c:656 +msgid " COMMAND The (optional) command to explain\n" +msgstr " ORDRE L'orde (opcional) que s'explicarà\n" + +#: ../gio/gresource-tool.c:565 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" FITXER Un fitxer elf (un fitxer binari o una biblioteca compartida)\n" + +#: ../gio/gresource-tool.c:568 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FITXER Un fitxer elf (un fitxer binari o una biblioteca\n" +" compartida) o un fitxer de recurs compilat\n" + +#: ../gio/gresource-tool.c:572 +msgid "[PATH]" +msgstr "[CAMÃ]" + +#: ../gio/gresource-tool.c:574 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " CAMà Un (opcional) camí (pot ser parcial) de recurs\n" + +#: ../gio/gresource-tool.c:575 +msgid "PATH" +msgstr "CAMÃ" + +#: ../gio/gresource-tool.c:577 +msgid " PATH A resource path\n" +msgstr " CAMà Un camí de recurs\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#: ../gio/gsettings-tool.c:853 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "No existeix l'esquema «%s»\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" +"No es pot canviar de lloc l'esquema «%s» (no s'ha d'especificar el camí)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Es pot canviar de lloc l'esquema «%s» (s'ha d'especificar el camí)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "S'ha donat un camí buit.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "El camí ha de començar amb una barra inclinada (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "El camí ha d'acabar amb una barra inclinada (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "El camí no pot contindre dues barres inclinades seguides (//)\n" + +#: ../gio/gsettings-tool.c:491 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "El valor proporcionat està fora del rang vàlid\n" + +#: ../gio/gsettings-tool.c:498 +#, c-format +msgid "The key is not writable\n" +msgstr "La clau no és d'escriptura\n" + +#: ../gio/gsettings-tool.c:534 +msgid "List the installed (non-relocatable) schemas" +msgstr "Llista els esquemes instal·lats (que no es poden canviar de lloc)" + +#: ../gio/gsettings-tool.c:540 +msgid "List the installed relocatable schemas" +msgstr "Llista els esquemes instal·lats que es poden canviar de lloc" + +#: ../gio/gsettings-tool.c:546 +msgid "List the keys in SCHEMA" +msgstr "Llista les claus a l'ESQUEMA" + +#: ../gio/gsettings-tool.c:547 ../gio/gsettings-tool.c:553 +#: ../gio/gsettings-tool.c:596 +msgid "SCHEMA[:PATH]" +msgstr "ESQUEMA[:CAMÃ]" + +#: ../gio/gsettings-tool.c:552 +msgid "List the children of SCHEMA" +msgstr "Llista els fills de l'ESQUEMA" + +#: ../gio/gsettings-tool.c:558 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Llista les claus i els valors recursivament\n" +"Si no es passa cap ESQUEMA, es llista totes les claus\n" + +#: ../gio/gsettings-tool.c:560 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESQUEMA[:CAMÃ]]" + +#: ../gio/gsettings-tool.c:565 +msgid "Get the value of KEY" +msgstr "Obtén el valor de la CLAU" + +#: ../gio/gsettings-tool.c:566 ../gio/gsettings-tool.c:572 +#: ../gio/gsettings-tool.c:578 ../gio/gsettings-tool.c:590 +#: ../gio/gsettings-tool.c:602 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESQUEMA[:CAMÃ] CLAU" + +#: ../gio/gsettings-tool.c:571 +msgid "Query the range of valid values for KEY" +msgstr "Consulta el rang de valors vàlids per a la CLAU" + +#: ../gio/gsettings-tool.c:577 +msgid "Query the description for KEY" +msgstr "Consulta la descripció per a la CLAU" + +#: ../gio/gsettings-tool.c:583 +msgid "Set the value of KEY to VALUE" +msgstr "Estableix el valor de la CLAU a VALOR" + +#: ../gio/gsettings-tool.c:584 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESQUEMA[:CAMÃ] CLAU VALOR" + +#: ../gio/gsettings-tool.c:589 +msgid "Reset KEY to its default value" +msgstr "Reinicia la CLAU al seu valor predeterminat" + +#: ../gio/gsettings-tool.c:595 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Reinicia totes les claus de l'ESQUEMA als seus valors per defecte" + +#: ../gio/gsettings-tool.c:601 +msgid "Check if KEY is writable" +msgstr "Comprova si la CLAU és d'escriptura" + +#: ../gio/gsettings-tool.c:607 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Fes un seguiment de la CLAU per si hi ha canvis.\n" +"Si no s'especifica cap CLAU, es farà un seguiment a \n" +"totes les claus de l'ESQUEMA.\n" +"Utilitzeu ^C per deixar de fer el seguiment.\n" + +#: ../gio/gsettings-tool.c:610 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESQUEMA[:CAMÃ] [CLAU]" + +#: ../gio/gsettings-tool.c:622 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Forma d'ús:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] ORDRE [ARGUMENTS...]\n" +"\n" +"Ordes:\n" +" help Mostra esta informació\n" +" list-schemas Llista els esquemes instal·lats\n" +" list-relocatable-schemas Llista els esquemes que es poden canviar de " +"lloc\n" +" list-keys Llista les claus d'un esquema\n" +" list-children Llista els fills d'un esquema\n" +" list-recursively Llista les claus i els valors recursivament\n" +" range Consulta el rang d'una clau\n" +" get Obtén el valor d'una clau\n" +" set Estableix el valor d'una clau\n" +" reset Reinicia el valor d'una clau\n" +" reset-recursively Reinicia tots els valors de l'esquema donat\n" +" writable Comprova si es pot escriure a la clau\n" +" monitor Fa un seguiment per si hi ha canvis\n" +"\n" +"Utilitzeu «gsettings help ORDRE» per veure l'ajuda més detallada.\n" +"\n" + +#: ../gio/gsettings-tool.c:646 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Ús:\n" +" gsettings [--schemadir DIRECTORI_D'ESQUEMES] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:652 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" +" DIRECTORI_D'ESQUEMES Un directori on buscar-hi esquemes addicionals\n" + +#: ../gio/gsettings-tool.c:660 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" ESQUEMA El nom de l'esquema\n" +" CAMà El camí, pels esquemes que es poden canviar de lloc\n" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The (optional) key within the schema\n" +msgstr " CLAU La clau (opcional) de l'esquema\n" + +#: ../gio/gsettings-tool.c:669 +msgid " KEY The key within the schema\n" +msgstr " CLAU La clau de l'esquema\n" + +#: ../gio/gsettings-tool.c:673 +msgid " VALUE The value to set\n" +msgstr " VALOR El valor a establir\n" + +#: ../gio/gsettings-tool.c:728 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "No s'han pogut carregar els esquemes %s: %s\n" + +#: ../gio/gsettings-tool.c:740 +#, c-format +msgid "No schemas installed\n" +msgstr "No hi ha cap esquema instal·lat\n" + +#: ../gio/gsettings-tool.c:811 +#, c-format +msgid "Empty schema name given\n" +msgstr "S'ha donat un nom d'esquema buit\n" + +#: ../gio/gsettings-tool.c:866 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "No existeix la clau «%s»\n" + +#: ../gio/gsocket.c:374 +msgid "Invalid socket, not initialized" +msgstr "El sòcol no és vàlid, no està inicialitzat" + +#: ../gio/gsocket.c:381 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "El sòcol no és vàlid, ha fallat la inicialització degut a: %s" + +#: ../gio/gsocket.c:389 +msgid "Socket is already closed" +msgstr "El sòcol ja és tancat" + +#: ../gio/gsocket.c:404 ../gio/gsocket.c:2762 ../gio/gsocket.c:3908 +#: ../gio/gsocket.c:3965 +msgid "Socket I/O timed out" +msgstr "S'ha excedit el temps d'espera d'entrada/eixida del sòcol" + +#: ../gio/gsocket.c:536 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "s'està creant un GSocket a partir del descriptor de fitxer: %s" + +#: ../gio/gsocket.c:565 ../gio/gsocket.c:619 ../gio/gsocket.c:626 +#, c-format +msgid "Unable to create socket: %s" +msgstr "No s'ha pogut crear el sòcol: %s" + +#: ../gio/gsocket.c:619 +msgid "Unknown family was specified" +msgstr "S'ha especificat una família desconeguda" + +#: ../gio/gsocket.c:626 +msgid "Unknown protocol was specified" +msgstr "S'ha especificat un protocol desconegut" + +#: ../gio/gsocket.c:1115 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"No es poden realitzar operacions de datagrames a un sòcol que no és de " +"datagrama." + +#: ../gio/gsocket.c:1132 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"No es poden realitzar operacions de datagrames a un sòcol que tinga un " +"temps d'espera màxim establit." + +#: ../gio/gsocket.c:1936 +#, c-format +msgid "could not get local address: %s" +msgstr "no s'ha pogut obtindre l'adreça local: %s" + +#: ../gio/gsocket.c:1979 +#, c-format +msgid "could not get remote address: %s" +msgstr "no s'ha pogut obtindre l'adreça remota: %s" + +#: ../gio/gsocket.c:2045 +#, c-format +msgid "could not listen: %s" +msgstr "no s'ha pogut escoltar: %s" + +#: ../gio/gsocket.c:2144 +#, c-format +msgid "Error binding to address: %s" +msgstr "S'ha produït un error en vincular-se a l'adreça: %s" + +#: ../gio/gsocket.c:2259 ../gio/gsocket.c:2296 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "S'ha produït un error en unir-se a un grup de multidestinació: %s" + +#: ../gio/gsocket.c:2260 ../gio/gsocket.c:2297 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "S'ha produït un error en deixar un grup de multidestinació: %s" + +#: ../gio/gsocket.c:2261 +msgid "No support for source-specific multicast" +msgstr "Encara no es pot fer multidestinació des d'un origen concret" + +#: ../gio/gsocket.c:2481 +#, c-format +msgid "Error accepting connection: %s" +msgstr "S'ha produït un error en acceptar la connexió: %s" + +#: ../gio/gsocket.c:2604 +msgid "Connection in progress" +msgstr "Connexió en curs" + +#: ../gio/gsocket.c:2655 +msgid "Unable to get pending error: " +msgstr "No s'ha pogut obtindre l'error pendent: " + +#: ../gio/gsocket.c:2827 +#, c-format +msgid "Error receiving data: %s" +msgstr "S'ha produït un error en rebre les dades: %s" + +#: ../gio/gsocket.c:3024 +#, c-format +msgid "Error sending data: %s" +msgstr "S'ha produït un error en enviar les dades: %s" + +#: ../gio/gsocket.c:3211 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "No s'ha pogut aturar el sòcol: %s" + +#: ../gio/gsocket.c:3292 +#, c-format +msgid "Error closing socket: %s" +msgstr "S'ha produït un error en tancar el sòcol: %s" + +#: ../gio/gsocket.c:3901 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "S'està esperant la condició del sòcol: %s" + +#: ../gio/gsocket.c:4374 ../gio/gsocket.c:4454 ../gio/gsocket.c:4632 +#, c-format +msgid "Error sending message: %s" +msgstr "S'ha produït un error en enviar el missatge: %s" + +#: ../gio/gsocket.c:4398 +msgid "GSocketControlMessage not supported on Windows" +msgstr "El GSocketControlMessage no està implementat a Windows" + +#: ../gio/gsocket.c:4851 ../gio/gsocket.c:4924 ../gio/gsocket.c:5151 +#, c-format +msgid "Error receiving message: %s" +msgstr "S'ha produït un error en rebre un missatge: %s" + +#: ../gio/gsocket.c:5423 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "No s'han pogut llegir les credencials del sòcol: %s" + +#: ../gio/gsocket.c:5432 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "Este sistema operatiu no implementa el «g_socket_get_credentials»" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "No s'ha pogut connectar al servidor intermediari %s: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "No s'ha pogut connectar a %s: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "No s'ha pogut connectar: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "S'ha produït un error desconegut en connectar-se" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" +"Encara no es pot fer de servidor intermediari d'una connexió que no siga " +"TCP." + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "El protocol del servidor intermediari «%s» no està implementat." + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "Ja està tancat el receptor de connexions" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "El sòcol que s'ha afegit és tancat" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "El SOCKSv4 no permet utilitzar adreces IPv6 «%s»" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "El nom d'usuari és massa llarg pel protocol SOCKSv4" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "El nom d'ordinador «%s» és massa llarg pel protocol SOCKSv4" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "El servidor no és un servidor intermediari de SOCKSv4." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "S'ha rebutjat la connexió a través d'un servidor SOCKSv4" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "El servidor no és un servidor intermediari SOCKSv5." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "El servidor intermediari SOCKSv5 requereix autenticació." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"El servidor intermediari SOCKSv5 requereix un mètode d'autenticació que " +"encara no està implementat a la GLib." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"El protocol SOCKSv5 no permet un nom d'usuari o de contrasenya d'esta " +"mida." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Ha fallat l'autenticació SOCKSv5 degut a un nom d'usuari o contrasenya " +"errònies." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "El nom d'ordinador «%s» és massa llarg pel protocol SOCKSv5" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" +"El servidor intermediari SOCKSv5 utilitza un tipus d'adreça desconeguda." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "S'ha produït un error intern del servidor intermediari SOCKSv5." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "El conjunt de regles no permet fer connexions SOCKSv5." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" +"No es pot arribar al servidor a través del servidor intermediari SOCKSv5." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" +"No es pot arribar a la xarxa a través del servidor intermediari SOCKSv5." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "S'ha refusat la connexió a través del servidor intermediari SOCKSv5." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "El servidor intermediari SOCKSv5 no permet l'ús de l'orde «connect»." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" +"El servidor intermediari SOCKSv5 no permet l'ús del tipus d'adreça " +"proporcionada." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "S'ha produït un error desconegut en el servidor intermediari SOCKSv5." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "No es pot gestionar la versió %d de la codificació del GThemedIcon" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "No s'ha trobat cap adreça vàlida" + +#: ../gio/gthreadedresolver.c:213 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "S'ha produït un error en resoldre a la inversa «%s»: %s" + +#: ../gio/gthreadedresolver.c:550 ../gio/gthreadedresolver.c:630 +#: ../gio/gthreadedresolver.c:728 ../gio/gthreadedresolver.c:778 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "No hi ha cap registre del tipus sol·licitat al DNS per «%s»" + +#: ../gio/gthreadedresolver.c:555 ../gio/gthreadedresolver.c:733 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "No s'ha pogut resoldre «%s» de forma temporal" + +#: ../gio/gthreadedresolver.c:560 ../gio/gthreadedresolver.c:738 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "S'ha produït un error en resoldre «%s»" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "No s'ha pogut desencriptar la clau privada codificada amb PEM" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "No s'ha trobat cap clau privada codificada amb PEM" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "No s'ha pogut analitzar la clau privada codificada amb PEM" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "No s'ha trobat cap certificat codificat amb PEM" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "No s'ha pogut analitzar el certificat codificat amb PEM" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Últim intent per introduir la contrasenya correctament abans que se vos " +"bloquegi l'accés." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: ../gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"S'han introduït diverses contrasenyes errònies i se vos bloquejarà l'accés " +"després de més intents." + +#: ../gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "La contrasenya introduïda no és correcte." + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:563 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "S'esperava un missatge de control però se n'ha obtingut %d" +msgstr[1] "S'esperava un missatge de control però se n'han obtingut %d" + +# FIXME +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:575 +msgid "Unexpected type of ancillary data" +msgstr "Tipus de dades extres no esperades" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "S'esperava un descriptor de fitxer però se n'ha obtingut %d\n" +msgstr[1] "S'esperava un descriptor de fitxer però se n'han obtingut %d\n" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "S'ha rebut un descriptor de fitxer no vàlid" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "S'ha produït un error en enviar les credencials: " + +#: ../gio/gunixconnection.c:504 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"S'ha produït un error en la comprovació de si «SO_PASSCRED» és habilitat en " +"el sòcol: %s" + +#: ../gio/gunixconnection.c:520 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "S'ha produït un error en habilitar «SO_PASSCRED»: %s" + +#: ../gio/gunixconnection.c:549 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"S'esperava llegir un sol byte per rebre les credencials però s'han llegit " +"zero bytes" + +#: ../gio/gunixconnection.c:589 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "No s'esperava un missatge de control però s'ha obtingut %d" + +#: ../gio/gunixconnection.c:614 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "S'ha produït un error en inhabilitar «SO_PASSCRED»: %s" + +#: ../gio/gunixinputstream.c:372 ../gio/gunixinputstream.c:393 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "S'ha produït un error en llegir del descriptor de fitxer: %s" + +#: ../gio/gunixinputstream.c:426 ../gio/gunixoutputstream.c:411 +#: ../gio/gwin32inputstream.c:217 ../gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "S'ha produït un error en tanar el descriptor de fitxer: %s" + +#: ../gio/gunixmounts.c:2430 ../gio/gunixmounts.c:2483 +msgid "Filesystem root" +msgstr "Arrel del sistema de fitxers" + +#: ../gio/gunixoutputstream.c:358 ../gio/gunixoutputstream.c:378 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "S'ha produït un error en escriure al descriptor de fitxer: %s" + +#: ../gio/gunixsocketaddress.c:241 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Este sistema no admet adreces de sòcol de domini UNIX abstractes" + +#: ../gio/gvolume.c:437 +msgid "volume doesn’t implement eject" +msgstr "el volum no implementa l'expulsió" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "el volum no implementa l'expulsió o «eject_with_operation»" + +#: ../gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "S'ha produït un error en llegir del gestor: %s" + +#: ../gio/gwin32inputstream.c:232 ../gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "S'ha produït un error en tancar el gestor: %s" + +#: ../gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "S'ha produït un error en escriure al gestor: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "No hi ha prou memòria" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Error intern: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Fan falta més dades d'entrada" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Les dades comprimides no són vàlides" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adreça on s'escoltarà" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorat, per mantindre la compatibilitat amb el GTestDbus" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Mostra l'adreça" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Mostra l'adreça en mode intèrpret d'ordes" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Executa un servei de D-Bus" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "Els arguments no són vàlids\n" + +#: ../glib/gbookmarkfile.c:754 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "No s'esperava l'atribut «%s» per a l'element «%s»" + +#: ../glib/gbookmarkfile.c:765 ../glib/gbookmarkfile.c:836 +#: ../glib/gbookmarkfile.c:846 ../glib/gbookmarkfile.c:953 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "No s'ha trobat l'atribut «%s» de l'element «%s»" + +#: ../glib/gbookmarkfile.c:1123 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1252 ../glib/gbookmarkfile.c:1262 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "No s'esperava l'etiqueta «%s», s'esperava «%s»" + +#: ../glib/gbookmarkfile.c:1148 ../glib/gbookmarkfile.c:1162 +#: ../glib/gbookmarkfile.c:1230 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "No s'esperava l'etiqueta «%s» dins «%s»" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"No s'ha trobat cap fitxer d'adreces d'interés dins dels directoris de dades" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Ja existeix una adreça d'interés per a l'URI «%s»" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "No s'ha trobat cap adreça d'interés per a l'URI «%s»" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "No hi ha cap tipus MIME definit a l'adreça d'interés per a l'URI «%s»" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" +"No hi ha cap senyalador privat definit a l'adreça d'interés per a l'URI «%s»" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "No hi ha cap grup establit a l'adreça d'interés per a l'URI «%s»" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" +"No hi ha cap aplicació amb el nom «%s» que haja registrat l'adreça d'interés " +"«%s»" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "No s'ha pogut ampliar la línia d'execució «%s» amb l'URI «%s»" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:862 ../glib/gutf8.c:1074 +#: ../glib/gutf8.c:1211 ../glib/gutf8.c:1315 +msgid "Partial character sequence at end of input" +msgstr "Seqüència de caràcters parcial al final de l'entrada" + +# FIXME: fallback +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "No es pot convertir el «fallback» «%s» al joc de codis «%s»" + +#: ../glib/gconvert.c:1513 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "L'URI «%s» no és un URI absolut que utilitze l'esquema «file»" + +#: ../glib/gconvert.c:1523 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Pot ser que l'URI del fitxer local «%s» no incloga cap «#»" + +#: ../glib/gconvert.c:1540 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "L'URI «%s» no és vàlid" + +#: ../glib/gconvert.c:1552 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "El nom de l'ordinador de l'URI «%s» no és vàlid" + +#: ../glib/gconvert.c:1568 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "L'URI «%s» conté caràcters d'escapada no vàlids" + +#: ../glib/gconvert.c:1640 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "El nom de camí «%s» no és un camí absolut" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:208 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:211 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:224 +msgctxt "full month name" +msgid "January" +msgstr "Gener" + +#: ../glib/gdatetime.c:226 +msgctxt "full month name" +msgid "February" +msgstr "Febrer" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "March" +msgstr "Març" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "April" +msgstr "Abril" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "May" +msgstr "Maig" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "June" +msgstr "Juny" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "July" +msgstr "Juliol" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "August" +msgstr "Agost" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "September" +msgstr "Setembre" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "October" +msgstr "Octubre" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "November" +msgstr "Novembre" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "December" +msgstr "Desembre" + +#: ../glib/gdatetime.c:261 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "gen" + +#: ../glib/gdatetime.c:263 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "març" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "abr" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "May" +msgstr "maig" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "juny" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jul" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ag" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "set" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "oct" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "des" + +#: ../glib/gdatetime.c:298 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Dilluns" + +#: ../glib/gdatetime.c:300 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Dimarts" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Dimecres" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Dijous" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Divendres" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Dissabte" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Diumenge" + +#: ../glib/gdatetime.c:325 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "dl" + +#: ../glib/gdatetime.c:327 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "dt" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "dm" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "dj" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "dv" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ds" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "dg" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:354 +msgctxt "GDateTime" +msgid "AM" +msgstr "A. M." + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:357 +msgctxt "GDateTime" +msgid "PM" +msgstr "P. M." + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "S'ha produït un error en obrir el directori «%s»: %s" + +#: ../glib/gfileutils.c:706 ../glib/gfileutils.c:798 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "No s'han pogut assignar %lu byte per llegir el fitxer «%s»" +msgstr[1] "No s'han pogut assignar %lu bytes per llegir el fitxer «%s»" + +#: ../glib/gfileutils.c:723 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "S'ha produït un error en llegir el fitxer %s: %s" + +#: ../glib/gfileutils.c:759 +#, c-format +msgid "File “%s†is too large" +msgstr "El fitxer «%s» és massa gran" + +#: ../glib/gfileutils.c:823 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "No s'ha pogut llegir del fitxer «%s»: %s" + +#: ../glib/gfileutils.c:871 ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "No s'ha pogut obrir el fitxer «%s»: %s" + +#: ../glib/gfileutils.c:883 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"No s'han pogut obtindre els atributs del fitxer «%s»: ha fallat la funció " +"fstat(): %s" + +#: ../glib/gfileutils.c:913 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "No s'ha pogut obrir el fitxer «%s»: ha fallat la funció fdopen(): %s" + +#: ../glib/gfileutils.c:1012 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"No s'ha pogut canviar el nom del fitxer «%s» a «%s»: ha fallat la funció " +"g_rename(): %s" + +#: ../glib/gfileutils.c:1047 ../glib/gfileutils.c:1554 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "No s'ha pogut crear el fitxer «%s»: %s" + +#: ../glib/gfileutils.c:1074 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "No s'ha pogut escriure el fitxer «%s»: ha fallat la funció write(): %s" + +#: ../glib/gfileutils.c:1117 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "No s'ha pogut escriure el fitxer «%s»: ha fallat la funció fsync(): %s" + +#: ../glib/gfileutils.c:1241 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"No s'ha pogut suprimir el fitxer existent «%s»: ha fallat la funció " +"g_unlink(): %s" + +#: ../glib/gfileutils.c:1520 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "La plantilla «%s» no és vàlida, no hauria de tindre cap «%s»" + +#: ../glib/gfileutils.c:1533 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "La plantilla «%s» no conté XXXXXX" + +#: ../glib/gfileutils.c:2058 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "No s'ha pogut llegir l'enllaç simbòlic «%s»: %s" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "No s'ha pogut obrir el convertidor de «%s» a «%s»: %s" + +# +#: ../glib/giochannel.c:1734 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "No es pot fer una lectura bàsica a g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "A la memòria intermèdia de lectura hi ha dades sobrants no convertides" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "El canal acaba en un caràcter parcial" + +#: ../glib/giochannel.c:1925 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "No es pot fer una lectura bàsica a g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:736 +msgid "Valid key file could not be found in search dirs" +msgstr "No s'ha pogut trobar cap fitxer de claus vàlid als directoris de busca" + +#: ../glib/gkeyfile.c:773 +msgid "Not a regular file" +msgstr "No és un fitxer regular" + +#: ../glib/gkeyfile.c:1218 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"El fitxer de claus conté la línia «%s» que no és una parella clau-valor, " +"grup o comentari" + +#: ../glib/gkeyfile.c:1275 +#, c-format +msgid "Invalid group name: %s" +msgstr "El nom del grup no és vàlid: %s" + +#: ../glib/gkeyfile.c:1297 +msgid "Key file does not start with a group" +msgstr "El fitxer de claus no comença amb un grup" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Invalid key name: %s" +msgstr "El nom de la clau no és vàlid: %s" + +#: ../glib/gkeyfile.c:1350 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "El fitxer de claus conté la codificació no implementada «%s»" + +#: ../glib/gkeyfile.c:1593 ../glib/gkeyfile.c:1766 ../glib/gkeyfile.c:3146 +#: ../glib/gkeyfile.c:3209 ../glib/gkeyfile.c:3339 ../glib/gkeyfile.c:3469 +#: ../glib/gkeyfile.c:3613 ../glib/gkeyfile.c:3842 ../glib/gkeyfile.c:3909 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "El fitxer de claus no té el grup «%s»" + +#: ../glib/gkeyfile.c:1721 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "El fitxer de claus no conté una clau «%s» en el grup «%s»" + +#: ../glib/gkeyfile.c:1883 ../glib/gkeyfile.c:1999 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"El fitxer de claus conté la clau «%s» amb el valor «%s», que no és UTF-8" + +#: ../glib/gkeyfile.c:1903 ../glib/gkeyfile.c:2019 ../glib/gkeyfile.c:2388 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"El fitxer de claus conté la clau «%s», que té un valor que no es pot " +"interpretar." + +#: ../glib/gkeyfile.c:2606 ../glib/gkeyfile.c:2975 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"El fitxer de claus conté la clau «%s» en el grup «%s», que té un valor que " +"no es pot interpretar." + +#: ../glib/gkeyfile.c:2684 ../glib/gkeyfile.c:2761 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"La clau «%s» en el grup «%s» té el valor «%s» però s'esperava el valor %s" + +#: ../glib/gkeyfile.c:4149 +msgid "Key file contains escape character at end of line" +msgstr "El fitxer de claus conté un caràcter d'escapada al final de línia" + +#: ../glib/gkeyfile.c:4171 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "El fitxer de claus conté la seqüència d'escapada no vàlida «%s»" + +#: ../glib/gkeyfile.c:4315 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "El valor «%s» no es pot interpretar com un nombre." + +#: ../glib/gkeyfile.c:4329 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "El valor enter «%s» és fora de l'interval" + +#: ../glib/gkeyfile.c:4362 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "El valor «%s» no es pot interpretar com un nombre amb coma flotant." + +#: ../glib/gkeyfile.c:4401 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "El valor «%s» no es pot interpretar com un booleà." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"No s'han pogut obtindre els atributs del fitxer «%s%s%s%s»: ha fallat la " +"funció fstat(): %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" +"No s'ha pogut mapar el fitxer «%s%s%s%s»: ha fallat la funció mmap(): %s" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "No s'ha pogut obrir el fitxer «%s»: ha fallat la funció open(): %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "S'ha produït un error a la línia %d caràcter %d: " + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "El nom conté caràcters UTF-8 no vàlids: «%s»" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "«%s» no és un nom vàlid" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "«%s» no és un nom vàlid: «%c»" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "S'ha produït un error a la línia %d: %s" + +#: ../glib/gmarkup.c:675 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"No s'ha pogut analitzar «%-.*s»: hi hauria d'haver hagut un dígit dins un " +"caràcter de referència (per exemple ê). Potser el dígit és massa gran." + +#: ../glib/gmarkup.c:687 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"La referència del caràcter no acaba amb un punt i coma. Segurament heu " +"utilitzat un caràcter «&» sense intenció d'iniciar una entitat. Substituïu " +"el caràcter «&» per &." + +#: ../glib/gmarkup.c:713 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "El caràcter de referència «%-.*s» no codifica un caràcter permés" + +#: ../glib/gmarkup.c:751 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"S'ha detectat una entitat buida «&;». Les entitats vàlides són: & " " +"< > '." + +#: ../glib/gmarkup.c:759 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Es desconeix el nom d'entitat «%-.*s»" + +#: ../glib/gmarkup.c:764 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"L'entitat no acaba amb un punt i coma. Segurament heu utilitzat un caràcter " +"«&» sense intenció d'iniciar una entitat. Substituïu el caràcter «&» per " +"&." + +#: ../glib/gmarkup.c:1170 +msgid "Document must begin with an element (e.g. )" +msgstr "El document ha de començar amb un element (p. ex. )" + +#: ../glib/gmarkup.c:1210 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"«%s» no és un caràcter vàlid després d'un caràcter «<»: no pot començar un " +"nom d'element." + +#: ../glib/gmarkup.c:1252 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"S'ha trobat un caràcter estrany: «%s». S'esperava el caràcter «>» per tancar " +"l'etiqueta d'element buit «%s»." + +#: ../glib/gmarkup.c:1333 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"S'ha trobat un caràcter estrany: «%s». S'esperava un «=» després del nom " +"d'atribut «%s» de l'element «%s»." + +#: ../glib/gmarkup.c:1374 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"S'ha trobat un caràcter estrany: «%s». S'esperava un caràcter «>» o «/» per " +"finalitzar l'etiqueta d'inici de l'element «%s», o opcionalment un atribut. " +"Potser heu utilitzat un caràcter no vàlid en un nom d'atribut." + +#: ../glib/gmarkup.c:1418 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"S'ha trobat un caràcter estrany: «%s». S'esperaven unes cometes d'obertura " +"després del signe «=» en donar valor a l'atribut «%s» de l'element «%s»." + +#: ../glib/gmarkup.c:1551 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"«%s» no és un caràcter vàlid després del nom d'element de tancament «%s». El " +"caràcter permés és «>»." + +#: ../glib/gmarkup.c:1598 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "L'element «%s» estava tancat. Actualment no hi ha cap element obert." + +#: ../glib/gmarkup.c:1607 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "L'element «%s» estava tancat. L'element obert actualment és «%s»." + +#: ../glib/gmarkup.c:1760 +msgid "Document was empty or contained only whitespace" +msgstr "El document era buit o només contenia espais en blanc" + +#: ../glib/gmarkup.c:1774 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"El document ha acabat de manera inesperada immediatament després del símbol " +"«<»" + +#: ../glib/gmarkup.c:1782 ../glib/gmarkup.c:1827 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"El document ha acabat de manera inesperada amb elements que encara eren " +"oberts. «%s» era l'últim element obert." + +#: ../glib/gmarkup.c:1790 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"El document ha acabat de manera inesperada. S'esperava trobar un símbol «>» " +"que acabés l'etiqueta <%s/>." + +#: ../glib/gmarkup.c:1796 +msgid "Document ended unexpectedly inside an element name" +msgstr "El document ha acabat de manera inesperada enmig d'un nom d'element" + +#: ../glib/gmarkup.c:1802 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "El document ha acabat de manera inesperada enmig d'un nom d'atribut" + +#: ../glib/gmarkup.c:1807 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"El document ha acabat de manera inesperada enmig d'una etiqueta d'obertura " +"d'un element." + +#: ../glib/gmarkup.c:1813 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"El document ha acabat de manera inesperada després d'un signe d'igual " +"després d'un nom d'atribut. No hi ha cap valor d'atribut." + +#: ../glib/gmarkup.c:1820 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "El document ha acabat de manera inesperada enmig d'un valor d'atribut" + +#: ../glib/gmarkup.c:1836 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"El document ha acabat de manera inesperada enmig de l'etiqueta de tancament " +"de l'element «%s»" + +#: ../glib/gmarkup.c:1842 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"El document ha acabat de manera inesperada enmig d'un comentari o d'una " +"instrucció de processament" + +# +#: ../glib/goption.c:861 +msgid "[OPTION…]" +msgstr "[OPCIÓ...]" + +#: ../glib/goption.c:977 +msgid "Help Options:" +msgstr "Opcions d'ajuda:" + +#: ../glib/goption.c:978 +msgid "Show help options" +msgstr "Mostra les opcions d'ajuda" + +#: ../glib/goption.c:984 +msgid "Show all help options" +msgstr "Mostra totes les opcions d'ajuda" + +#: ../glib/goption.c:1047 +msgid "Application Options:" +msgstr "Opcions de l'aplicació:" + +#: ../glib/goption.c:1049 +msgid "Options:" +msgstr "Opcions:" + +#: ../glib/goption.c:1113 ../glib/goption.c:1183 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "No es pot analitzar el valor enter «%s» per a %s" + +#: ../glib/goption.c:1123 ../glib/goption.c:1191 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "El valor enter «%s» per a %s és fora de l'interval" + +#: ../glib/goption.c:1148 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "No es pot analitzar el valor doble «%s» per a %s" + +#: ../glib/goption.c:1156 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "El valor doble «%s» per a %s és fora de l'interval" + +#: ../glib/goption.c:1448 ../glib/goption.c:1527 +#, c-format +msgid "Error parsing option %s" +msgstr "S'ha produït un error en analitzar l'opció %s" + +#: ../glib/goption.c:1558 ../glib/goption.c:1671 +#, c-format +msgid "Missing argument for %s" +msgstr "Falta un argument per a %s" + +#: ../glib/goption.c:2132 +#, c-format +msgid "Unknown option %s" +msgstr "Es desconeix l'opció %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "objecte malmés" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "error intern o objecte malmés" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "no hi ha prou memòria" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "s'ha arribat al límit de tornades arrere" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"el patró conté elements que no estan implementats en les concordances " +"parcials" + +#: ../glib/gregex.c:280 +msgid "internal error" +msgstr "error intern" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"no s'ha implementat l'ús de referències anteriors per a coincidències " +"parcials" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "s'ha arribat al límit de recurrències" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "la combinació de senyaladors de línia nova no és vàlida" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "desplaçament incorrecte" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "UTF-8 curt" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "bucle recursiu" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "error desconegut" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ al final del patró" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c al final del patró" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "caràcter no reconegut després de \\" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "nombres fora de l'interval en el quantificador {}" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "nombre massa gran en el quantificador {}" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "falta el «]» per a la classe de caràcter" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "la seqüència d'escapada en la classe de caràcter no és vàlida" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "s'ha eixit de l'interval en la classe de caràcter" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "no hi ha res per repetir" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "repetició no esperada" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "no es reconeix el caràcter després de «(?» o «(?-»" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "" +"només es permeten les classes amb nom de POSIX dins de la pròpia classe" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "falta un «)»" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "referència a un subpatró que no existeix" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "falta un «)» després del comentari" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "l'expressió regular és massa gran" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "no s'ha pogut obtindre memòria" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr "hi ha un «)» sense el corresponent «(»" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "desbordament del codi" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "no es reconeix el caràcter després de «(?<»" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "l'asserció cap arrere no té llargada fixa" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "el nombre o el nom no estan ben formats després de «(?(»" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "el grup condicional conté més de dues branques" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "s'esperava una asserció després de «(?(»" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "«(?R» o «(?[+-]dígits» han d'anar seguits de «)»" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "nom de classe POSIX desconeguda" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "no es poden utilitzar els elements d'ordenació de POSIX" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "el valor del caràcter a la seqüència «\\x{...}» és massa gran" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "condició «(?(0)» no vàlida" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "no es permet \\C en assercions cap arrere" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" +"no s'admeten els caràcters d'escapada «\\L», «\\l», «\\N{nom}», «\\U» i «\\u»" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "la crida recursiva podria entrar en bucle indefinidament" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "no es reconeix el caràcter després de «(?P»" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "falta la finalització en el nom del subpatró" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "dos noms de subpatró tenen el mateix nom" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "la seqüència «\\P» o «\\p» no està ben formada" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "es desconeix el nom de la propietat després de «\\P» o «\\p»" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "el nom del subpatró és massa llarg (32 caràcters com a màxim)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "hi ha massa subpatrons amb nom (màxim de 10.000)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "el valor octal és més gran que \\377" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "s'ha produït un desbordament en compilar l'espai de treball" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "no s'ha trobat el subpatró referenciat comprovat anteriorment" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "el grup «DEFINE» conté més d'una branca" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "opcions «NEWLINE» incoherents" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"després de «\\g» no hi ha cap número o cap nom o número entre claudàtors, " +"claus angulars o cometes" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "les referències numerades no poden ser zero" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "no es permeten arguments per «(*ACCEPT)», «(*FAIL)» o «(*COMMIT)»" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "no es reconeix «(*VERB)»" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "el número és massa gran" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "falta el nom del subpatró després de (?&" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "s'esperava un dígit després de (?+" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"el caràcter«]» no és un caràcter de dades vàlid en el mode de compatibilitat " +"amb JavaScript" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "no s'accepten noms diferents per subpatrons del mateix número" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "«(*MARK)» ha de tindre un argument" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "després de «\\c» ha d'haver-hi un caràcter ASCII" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"després de «\\k» no hi ha cap nom entre claudàtors, claus angulars o cometes" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "no es pot utilitzar \\N en una classe" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "hi ha massa referències cap avant" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "el nom és massa llarg a «(*MARK)«, «(*PRUNE)«, «(*SKIP)» o «(*THEN)»" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "el valor del caràcter a la seqüència «\\u...» és massa gran" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1977 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "S'ha produït un error en fer coincidir l'expressió regular %s: %s" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "La biblioteca PCRE no està compilada per interpretar UTF-8" + +#: ../glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"La biblioteca PCRE no està compilada per interpretar les propietats UTF-8" + +#: ../glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "La biblioteca PCRE ha estat compilada amb opcions incompatibles" + +#: ../glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "S'ha produït un error en optimitzar l'expressió regular %s: %s" + +#: ../glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"S'ha produït un error en compilar l'expressió regular %s al caràcter %d: %s" + +#: ../glib/gregex.c:2413 +msgid "hexadecimal digit or “}†expected" +msgstr "s'esperava un dígit hexadecimal o bé «}»" + +#: ../glib/gregex.c:2429 +msgid "hexadecimal digit expected" +msgstr "s'esperava un dígit hexadecimal" + +#: ../glib/gregex.c:2469 +msgid "missing “<†in symbolic reference" +msgstr "falta un «<» en la referència simbòlica" + +#: ../glib/gregex.c:2478 +msgid "unfinished symbolic reference" +msgstr "la referència simbòlica no està acabada" + +#: ../glib/gregex.c:2485 +msgid "zero-length symbolic reference" +msgstr "referència simbòlica de longitud zero" + +#: ../glib/gregex.c:2496 +msgid "digit expected" +msgstr "s'esperava un dígit" + +#: ../glib/gregex.c:2514 +msgid "illegal symbolic reference" +msgstr "la referència simbòlica no és vàlida" + +#: ../glib/gregex.c:2576 +msgid "stray final “\\â€" +msgstr "«\\» final extraviat" + +#: ../glib/gregex.c:2580 +msgid "unknown escape sequence" +msgstr "no es reconeix la seqüència d'escapament" + +#: ../glib/gregex.c:2590 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"S'ha produït un error en analitzar el text de reemplaçament «%s» al caràcter " +"%lu: %s" + +#: ../glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "El text citat no comença amb cometes" + +#: ../glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"S'han trobat unes cometes desaparellades en una línia d'ordes o en un altre " +"text entre cometes" + +#: ../glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "El text acaba just després d'un caràcter «\\». (El text era «%s».)" + +#: ../glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"El text ha acabat abans de trobar les cometes corresponents a %c. (El text " +"era «%s».)" + +#: ../glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "El text era buit (o només contenia espais en blanc)" + +#: ../glib/gspawn.c:250 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "No s'han pogut llegir dades des del procés fill (%s)" + +#: ../glib/gspawn.c:394 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"S'ha produït un error inesperat a select() en llegir dades des d'un procés " +"fill (%s)" + +#: ../glib/gspawn.c:479 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "S'ha produït un error inesperat en waitpid() (%s)" + +#: ../glib/gspawn.c:886 ../glib/gspawn-win32.c:1231 +#, c-format +msgid "Child process exited with code %ld" +msgstr "El procés fill ha eixit amb el codi %ld" + +#: ../glib/gspawn.c:894 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "El senyal %ld ha matat el procés fill" + +#: ../glib/gspawn.c:901 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "El senyal %ld ha aturat el procés fill" + +#: ../glib/gspawn.c:908 +#, c-format +msgid "Child process exited abnormally" +msgstr "El procés fill ha eixit inesperadament" + +#: ../glib/gspawn.c:1313 ../glib/gspawn-win32.c:337 ../glib/gspawn-win32.c:345 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "No s'ha pogut llegir des del conducte fill (%s)" + +#: ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to fork (%s)" +msgstr "No s'ha pogut bifurcar-se (%s)" + +#: ../glib/gspawn.c:1532 ../glib/gspawn-win32.c:368 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "No s'ha pogut canviar al directori «%s» (%s)" + +#: ../glib/gspawn.c:1542 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "No s'ha pogut executar el procés fill «%s» (%s)" + +#: ../glib/gspawn.c:1552 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "No s'ha pogut redirigir l'entrada o l'eixida del procés fill (%s)" + +#: ../glib/gspawn.c:1561 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "No s'ha pogut bifurcar el procés fill (%s)" + +#: ../glib/gspawn.c:1569 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "S'ha produït un error desconegut en executar el procés fill «%s»" + +#: ../glib/gspawn.c:1593 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"No s'han pogut llegir prou dades del conducte de l'identificador del procés " +"fill (%s)" + +#: ../glib/gspawn-win32.c:281 +msgid "Failed to read data from child process" +msgstr "No s'han pogut llegir dades del procés fill" + +#: ../glib/gspawn-win32.c:298 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"No s'ha pogut crear el conducte per comunicar-se amb el procés fill (%s)" + +#: ../glib/gspawn-win32.c:374 ../glib/gspawn-win32.c:493 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "No s'ha pogut executar el procés fill (%s)" + +#: ../glib/gspawn-win32.c:443 +#, c-format +msgid "Invalid program name: %s" +msgstr "El nom del programa no és vàlid: %s" + +#: ../glib/gspawn-win32.c:453 ../glib/gspawn-win32.c:720 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "La cadena en el vector d'argument no és vàlida a %d: %s" + +#: ../glib/gspawn-win32.c:464 ../glib/gspawn-win32.c:735 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Cadena no vàlida a l'entorn: %s" + +#: ../glib/gspawn-win32.c:716 +#, c-format +msgid "Invalid working directory: %s" +msgstr "El directori de treball no és vàlid: %s" + +#: ../glib/gspawn-win32.c:781 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "No s'ha pogut executar el programa d'ajuda (%s)" + +#: ../glib/gspawn-win32.c:995 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"S'ha produït un error inesperat a g_io_channel_win32_poll() en llegir dades " +"d'un procés fill" + +#: ../glib/gstrfuncs.c:3247 ../glib/gstrfuncs.c:3348 +msgid "Empty string is not a number" +msgstr "La cadena buida no és un número" + +#: ../glib/gstrfuncs.c:3271 +#, c-format +msgid "“%s†is not a signed number" +msgstr "«%s» no és un nombre amb signe" + +#: ../glib/gstrfuncs.c:3281 ../glib/gstrfuncs.c:3384 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "El número «%s» està fora de rangs [%s, %s]" + +#: ../glib/gstrfuncs.c:3374 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "«%s» no és un nombre sense signe" + +#: ../glib/gutf8.c:808 +msgid "Failed to allocate memory" +msgstr "No s'ha pogut ubicar memòria" + +#: ../glib/gutf8.c:941 +msgid "Character out of range for UTF-8" +msgstr "El caràcter és fora de l'interval d'UTF-8" + +#: ../glib/gutf8.c:1042 ../glib/gutf8.c:1051 ../glib/gutf8.c:1181 +#: ../glib/gutf8.c:1190 ../glib/gutf8.c:1329 ../glib/gutf8.c:1426 +msgid "Invalid sequence in conversion input" +msgstr "Seqüència no vàlida a l'entrada de la conversió" + +#: ../glib/gutf8.c:1340 ../glib/gutf8.c:1437 +msgid "Character out of range for UTF-16" +msgstr "El caràcter és fora de l'interval d'UTF-16" + +#: ../glib/gutils.c:2209 ../glib/gutils.c:2236 ../glib/gutils.c:2342 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: ../glib/gutils.c:2215 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2217 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2220 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2223 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2226 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2229 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2242 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2245 ../glib/gutils.c:2360 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2248 ../glib/gutils.c:2365 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2250 ../glib/gutils.c:2370 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2253 ../glib/gutils.c:2375 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2256 ../glib/gutils.c:2380 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2293 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2355 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "de gener" + +msgctxt "full month name with day" +msgid "February" +msgstr "de febrer" + +msgctxt "full month name with day" +msgid "March" +msgstr "de març" + +msgctxt "full month name with day" +msgid "April" +msgstr "d’abril" + +msgctxt "full month name with day" +msgid "May" +msgstr "de maig" + +msgctxt "full month name with day" +msgid "June" +msgstr "de juny" + +msgctxt "full month name with day" +msgid "July" +msgstr "de juliol" + +msgctxt "full month name with day" +msgid "August" +msgstr "d’agost" + +msgctxt "full month name with day" +msgid "September" +msgstr "de setembre" + +msgctxt "full month name with day" +msgid "October" +msgstr "d’octubre" + +msgctxt "full month name with day" +msgid "November" +msgstr "de novembre" + +msgctxt "full month name with day" +msgid "December" +msgstr "de desembre" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "de gen." + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "de febr." + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "de març" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "d’abr." + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "de maig" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "de juny" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "de jul." + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "d’ag." + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "de set." + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "d’oct." + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "de nov." + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "de des." + +#~ msgid "No files given" +#~ msgstr "No s'ha donat cap fitxer" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "S'ha produït un error en obtenir els atributs d'escriptura: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "S'ha produït un error en muntar la ubicació: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "S'ha produït un error desmuntar el muntatge: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "No s'ha pogut trobar el punt de muntatge de tancament: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "S'ha produït un error en expulsar el muntatge: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "S'ha produït un error en muntar %s: %s\n" + +#~ msgid "No files to open" +#~ msgstr "Cap fitxer a obrir" + +#~ msgid "No files to delete" +#~ msgstr "Cap fitxer a suprimir" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "S'ha produït un error en establir l'atribut: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "S'ha produït un error en crear el directori «%s»: %s" + +#~ msgid "No such interface" +#~ msgstr "No existeix la interfície" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "S'ha produït un error en obrir el fitxer «%s»: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "S'ha produït un error en llegir el fitxer «%s»: %s" + +#~ msgid "No locations gives" +#~ msgstr "No s'ha donat cap ubicació" + +#~ msgid "Error renaming file: %s" +#~ msgstr "S'ha produït un error en canviar el nom del fitxer: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "S'ha produït un error en obrir el fitxer: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "S'ha produït un error en crear el directori: %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "" +#~ "No s'ha pogut trobar el tipus de seguiment de directoris locals " +#~ "predeterminat" + +#~ msgid "association changes not supported on win32" +#~ msgstr "els canvis associatius no estan implementats a win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "La creació associativa no està implementada a win32" + +#~ msgid "URIs not supported" +#~ msgstr "No estan implementats els URI" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "El fitxer de claus no té la clau «%s»" diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000..a0e4a4f --- /dev/null +++ b/po/cs.po @@ -0,0 +1,6296 @@ +# Czech translation of glib. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 the author(s) of glib. +# Copyright (C) 2004, 2005 Miloslav Trmac . +# Copyright (C) 2006 Lukas Novotny . +# This file is distributed under the same license as the glib package. +# +# Petr Pytelka , 2002. +# Miloslav Trmac , 2002, 2004, 2005. +# Lukas Novotny , 2006. +# Jakub Friedl , 2006, 2007. +# Petr Kovar , 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015. +# Marek ÄŒernocký , 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib glib-2-72\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-08-15 19:44+0000\n" +"PO-Revision-Date: 2022-08-29 10:46+0200\n" +"Last-Translator: Marek ÄŒernocký \n" +"Language-Team: ÄeÅ¡tina \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Gtranslator 2.91.7\n" +"X-Project-Style: gnome\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Nastavení výchozích aplikací není podporováno" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Nastavení aplikace, jako poslední použité pro daný typ, není zatím " +"podporováno" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Volby GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Zobrazit volby GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Vstoupit do režimu služby GApplication (použít ze souborů služby D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "PÅ™epsat ID aplikace" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Nahradit běžící instanci" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Vypsat nápovÄ›du" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[PŘÃKAZ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Vypsat verzi" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Vypsat informace o verzi a skonÄit" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Vypsat aplikace" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Vypsat nainstalované aktivovatelné aplikace D-Bus (podle souborů .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Spustit aplikaci" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Spustit aplikaci (a otevřít v ní volitelné soubory)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "IDAPLIKACE [SOUBOR…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktivovat akci" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Vyvolat akci na aplikaci" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "IDAPLIKACE AKCE [PARAMETR]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Vypsat dostupné akce" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Vypsat statické akce svázané s aplikací (ze souboru .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "IDAPLIKACE" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "PŘÃKAZ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Příkaz, ke kterému vypsat podrobnou nápovÄ›du" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Identifikátor aplikace ve formátu D-Bus (napÅ™. org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "SOUBOR" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Volitelné relativní nebo absolutní názvy souborů nebo adresy URI, které se " +"mají otevřít" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "AKCE" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Název akce, kterou chcete vyvolat" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETR" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Volitelný parametr k akci vyvolání ve formátu GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Neznámý příkaz „%s“\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Použití:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumenty:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTY…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Příkazy:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Podrobnou nápovÄ›du získáte spuÅ¡tÄ›ním „%s help PŘÃKAZ“.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Příkaz %s vyžaduje, aby bezprostÅ™ednÄ› po nÄ›m následovalo ID aplikace\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "neplatné ID aplikace: „%s“\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"„%s“ nelze použít s argumenty\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "nelze se pÅ™ipojit k D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "chyba pÅ™i odesílání zprávy %s aplikaci: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "název aplikace musí následovat po ID aplikace\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"neplatný název akce: „%s“\n" +"názvy akcí mohou obsahovat pouze alfanumerické znaky, „-“ a „.“\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "chyba pÅ™i analyzování parametru akce: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "akce podporují nanejvýš jeden parametr\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "S příkazem list-actions lze použít pouze ID aplikace" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "nelze nalézt soubor desktop pro aplikaci %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"neznámý příkaz: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s poskytnut příliÅ¡ vysoký poÄet" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Posouvání není v proudu podporováno" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Nelze zkrátit GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Proud je již uzavÅ™en" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Zkrácování není v proudu podporováno" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operace byla zruÅ¡ena" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Neplatný objekt, nebyl spuÅ¡tÄ›n" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Neúplná vícebajtová posloupnost na vstupu" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Cíl nemá dostatek místa" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Neplatná posloupnost bajtů na vstupu pÅ™evodu" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Chyba pÅ™i pÅ™evodu: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "ZruÅ¡itelné spuÅ¡tÄ›ní není podporováno" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "PÅ™evod ze znakové sady „%s“ do „%s“ není podporován" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Nelze otevřít pÅ™evodník z „%s“ do „%s“" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "typ %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Neznámý typ" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "typ souboru %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials obsahuje neplatná data" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials na tomto OS není implementováno" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Danou platformu GCredentials nepodporuje" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials na tomto OS neobsahuje ID procesu" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "ZmÄ›na pÅ™ihlaÅ¡ovacích údajů na tomto OS není implementován" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "NeoÄekávaný Äasný konec proudu" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nepodporovaný klÃ­Ä â€ž%s“ v záznamu s adresou „%s“" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Nesmyslná párová kombinace klíÄ/hodnota v záznamu s adresou „%s“" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adresa „%s“ je neplatná (je zapotÅ™ebí právÄ› jeden z klíÄů path, tmpdir nebo " +"abstract)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Chyba v adrese „%s“ – atribut „%s“ má chybný formát" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Neznámý nebo nepodporovaný pÅ™enos „%s“ adresy „%s“" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Prvek adresy „%s“ neobsahuje dvojteÄku (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Název pÅ™enosu v prvku adresy „%s“ nesmí být prázdný" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Pár klíÄ/hodnota %d, „%s“, v prvku adresy „%s“ neobsahuje znak rovná se" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "Pár klíÄ/hodnota %d, „%s“ v prvku adresy „%s“ nesmí mít prázdný klíÄ" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Chyba v neuvozeném klíÄi nebo hodnotÄ› v páru klíÄ/hodnota %d, „%s“, v prvku " +"adresy „%s“" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Chyba v adrese „%s“ – unix transport vyžaduje jako nastavený právÄ› jeden z " +"klíÄů „path“ nebo „abstract“" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Chyba v adrese „%s“ – atribut poÄítaÄe schází nebo má chybný formát" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Chyba v adrese „%s“ – atribut portu schází nebo má chybný formát" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "Chyba v adrese „%s“ – atribut noncefile schází nebo má chybný formát" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Chyba pÅ™i automatickém spouÅ¡tÄ›ní: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Chyba pÅ™i otevírání souboru nonce „%s“: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Chyba pÅ™i Ätení ze souboru nonce „%s“: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Chyba pÅ™i Ätení ze souboru nonce „%s“, oÄekáváno 16 bajtů, obdrženo %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Chyba pÅ™i zápisu obsahu souboru nonce „%s“ do proudu:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Daná adresa je prázdná" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Nelze spustit sbÄ›rnici zpráv, když je nastaveno AT_SECURE" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Nelze spustit sbÄ›rnici zpráv bez machine-id: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Nelze automaticky spustit D-Bus bez X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Chyba pÅ™i spouÅ¡tÄ›ní příkazového řádku „%s“: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "Nelze urÄit adresu sbÄ›rnice sezení (v tomto OS neimplementováno)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Nelze urÄit adresu sbÄ›rnice z promÄ›nné prostÅ™edí DBUS_STARTER_BUS_TYPE – " +"neznámá hodnota „%s“" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Nelze urÄit adresu sbÄ›rnice, jelikož promÄ›nná prostÅ™edí " +"DBUS_STARTER_BUS_TYPE není nastavena" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Neznámý typ sbÄ›rnice %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "NeoÄekávanÄ› scházející obsah pÅ™i pokusu o pÅ™eÄtení řádku" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "NeoÄekávanÄ› scházející obsah pÅ™i pokusu o (bezpeÄné) pÅ™eÄtení řádku" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"VyÄerpány vÅ¡echny dostupné ověřovací mechanismy (pokusů: %s) (dostupných: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "ID uživatele musí být stejné pro klienta i server" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "ZruÅ¡eno pÅ™es GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Chyba pÅ™i získávání informací pro složku „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"OprávnÄ›ní složky „%s“ mají chybný formát. OÄekáván režim 0700, obdržen 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Chyba pÅ™i vytváření složky %s: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operace není podporována" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Chyba pÅ™i otevírání klíÄenky „%s“ ke Ätení: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Řádek %d klíÄenky na „%s“ s obsahem „%s“ má chybný formát" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "První symbol řádku %d klíÄenky na „%s“ s obsahem „%s“ má chybný formát" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Druhý symbol řádku %d klíÄenky na „%s“ s obsahem „%s“ má chybný formát" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Nenalezena cookie s id %d v klíÄence na „%s“" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Chyba pÅ™i vytváření zamykacího souboru „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Chyba pÅ™i mazání zastaralého zamykacího souboru „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Chyba pÅ™i zavírání (neodkazovaného) zamykacího souboru „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Chyba mazámí zamykacího souboru „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Chyba pÅ™i otevírání klíÄenky „%s“ k zápisu: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Navíc selhalo také uvolnÄ›ní zámku pro „%s“: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Spojení bylo ukonÄeno" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "ÄŒasový limit vyprÅ¡el" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Nalezeny nepodporované příznaky pÅ™i vytváření spojení na stranÄ› klienta" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Rozhraní „org.freedesktop.DBus.Properties“ na objektu na cestÄ› %s neexistuje" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Vlastnost „%s“ neexistuje" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Vlastnost „%s“ není ke Ätení" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Vlastnost „%s“ není zapisovatelná" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Chyba pÅ™i nastavování vlastnosti „%s“: OÄekáván typ „%s“, ale obdržen „%s“" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Rozhraní „%s“ neexistuje" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Rozhraní „%s“na objektu na cestÄ› %s neexistuje" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Metoda „%s“ neexistuje" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Typ zprávy „%s“ se neshoduje s oÄekávaným typem „%s“" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Objekt je již exportován pro prostÅ™edí %s na %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Nelze naÄíst vlastnost %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Nelze nastavit vlastnost %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metoda „%s“ vrátila typ „%s“, ale oÄekáván byl „%s“" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metoda „%s“ na rozhraní „%s“ s podpisem „%s“ neexistuje" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Podstrom je již exportován pro %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "V cestÄ› „%s“ objekt neexistuje" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "typ je INVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Zpráva METHOD_CALL: pole se záhlavím PATH nebo MEMBER schází" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Zpráva METHOD_RETURN: pole se záhlavím REPLY_SERIAL schází" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Zpráva ERROR: pole se záhlavím REPLY_SERIAL nebo ERROR_NAME schází" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Zpráva SIGNAL: pole se záhlavím PATH, INTERFACE nebo MEMBER schází" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Zpráva SIGNAL: pole se záhlavím PATH používá rezervovanou hodnotu /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Zpráva SIGNAL: pole se záhlavím INTERFACE používá rezervovanou hodnotu org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Zamýšlel se pÅ™eÄíst %lu bajt, ale obdrženo %lu" +msgstr[1] "Zamýšlely se pÅ™eÄíst %lu bajty, ale obdrženo %lu" +msgstr[2] "Zamýšlelo se pÅ™eÄíst %lu bajtů, ale obdrženo %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "OÄekáván bajt NULL za Å™etÄ›zcem „%s“, ale byl nalezen bajt %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"OÄekáván platný Å™etÄ›zec UTF-8, ale byly nalezeny neplatné bajty na pozici %d " +"(délka Å™etÄ›zce je %d). Platný Å™etÄ›zec UTF-8 až do přísluÅ¡ného bodu byl „%s“" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Hodnota je zanoÅ™ená příliÅ¡ hluboko" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Analyzovaná hodnota „%s“ není platná cesta objektu D-Bus" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Analyzovaná hodnota „%s“ není platný podpis D-Bus" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"ZjiÅ¡tÄ›no pole o délce %u bajt. Maximální délka je 2<<26 bajtů (64 MiB)." +msgstr[1] "" +"ZjiÅ¡tÄ›no pole o délce %u bajty. Maximální délka je 2<<26 bajtů (64 MiB)." +msgstr[2] "" +"ZjiÅ¡tÄ›no pole o délce %u bajtů. Maximální délka je 2<<26 bajtů (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Vyskytlo se pole typu „a%c“, které by mÄ›lo mít délku v násobku %u bajtů, ale " +"skuteÄná délka je %u bajtů" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Prázdné struktury (n-tice) nejsou na sbÄ›rnici D-Bus dovoleny" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Analyzovaná hodnota „%s“ varianty není platným podpisem D-Bus" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Chyba pÅ™i ruÅ¡ení serializace GVariant s Å™etÄ›zcem typu „%s“ z pÅ™enosového " +"formátu D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Neplatná hodnota endianity. OÄekávána 0x6c („l“) nebo 0x42 („B“), ale " +"nalezena hodnota 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Neplatná verze hlavního protokolu. OÄekávána 1, ale nalezena %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Byla nalezena hlaviÄka podpisu, ale není typu podpis" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Byla nalezena hlaviÄka podpisu s podpisem „%s“, ale tÄ›lo zprávy je prázdné" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Analyzovaná hodnota „%s“ není platným podpisem D-Bus (pro tÄ›lo)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Ve zprávÄ› není hlaviÄka s podpisem, ale tÄ›lo zprávy má %u bajt" +msgstr[1] "Ve zprávÄ› není hlaviÄka s podpisem, ale tÄ›lo zprávy má %u bajty" +msgstr[2] "Ve zprávÄ› není hlaviÄka s podpisem, ale tÄ›lo zprávy má %u bajtů" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Nelze zruÅ¡it serializaci zprávy: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Chyba pÅ™i serializaci GVariant s Å™etÄ›zcem typu „%s“ do pÅ™enosového formátu D-" +"Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"PoÄet popisovaÄů souborů ve zprávÄ› (%d) se liší od pole v hlaviÄce (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Nelze serializovat zprávu: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "TÄ›lo zprávy má podpis „%s“, ale záhlaví s podpisem neexistuje" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "TÄ›lo zprávy má podpis typu „%s“, ale podpis v poli se záhlavím je „%s“" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "TÄ›lo zprávy je prázdné, ale podpis v poli se záhlavím je „(%s)“" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Navrácena chyba s tÄ›lem typu „%s“" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Navrácena chyba s prázdným tÄ›lem" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(ZmáÄknutím libovolného znaku okno zavÅ™ete)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Služba dbus sezení neběží a automatické spuÅ¡tÄ›ní selhalo" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Nelze získat profil hardwaru: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Nelze naÄíst %s: %s" + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Chyba pÅ™i volání StartServiceByName pro %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "NeoÄekávaná odpovÄ›Ä %d od metody StartServiceByName(„%s“)" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Metodu nelze vyvolat; proxy je na dobÅ™e známý název %s bez vlastníka a proxy " +"byla vytvoÅ™ena s příznakem G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstraktní jmenný prostor není podporován" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "PÅ™i vytváření serveru nelze urÄit soubor nonce" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Chyba pÅ™i zápisu souboru nonce na „%s“: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "ŘetÄ›zec „%s“ není platné D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Nelze naslouchat na nepodporovaném pÅ™enosu „%s“" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Příkazy:\n" +" help Zobrazit tyto informace\n" +" introspect Provést introspection vzdáleného objektu\n" +" monitor Sledovat vzdálený objekt\n" +" call Spustit metodu na vzdáleném objektu\n" +" emit Vyslat signál\n" +" wait ÄŒekat, než se objeví název sbÄ›rnice\n" +"\n" +"NápovÄ›du k jednotlivým příkazům získáte použitím „%s PŘÃKAZ --help“.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Chyba: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Chyba pÅ™i analýze introspection XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Chyba: %s není platným názvem\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Chyba: %s není platnou cestou objektu\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "PÅ™ipojit k systémové sbÄ›rnici" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "PÅ™ipojit ke sbÄ›rnici sezení" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "PÅ™ipojit k dané adrese D-Bus" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Volby koncového bodu spojení:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Volby urÄující koncový bod spojení" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "NeurÄen žádný koncový bod spojení" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "UrÄeno více koncových bodů spojení" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Varování: Podle introspektivních dat rozhraní „%s“ neexistuje\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Varování: Podle introspektivních dat metoda „%s“ neexistuje na rozhraní " +"„%s“\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Volitelný cíl signálu (jedineÄný název)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Cesta objektu, na kterou se má vyslat signál" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Název signálu a rozhraní" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Vyslat signál." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Chyba pÅ™i spojení: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Chyba: %s není platným jedineÄným názvem sbÄ›rnice.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Chyba: Není urÄena žádná cesta k objektu\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Chyba: Není urÄen název signálu\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Chyba: Název signálu „%s“ je neplatný\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Chyba: %s není platným názvem rozhraní\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Chyba: %s není platným názvem Älenu\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Chyba pÅ™i analyzování parametru %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Chyba pÅ™i vyprazdňování spojení: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Název cíle, u kterého se má spustit metoda" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Cesta objektu, u kterého se má spustit metoda" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Název metody a rozhraní" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "ÄŒasový limit v sekundách" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Povolit interaktivní autorizaci" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Spustit metodu na vzdáleném objektu." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Chyba: Není urÄen žádný cíl\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Chyba: %s není platným názvem sbÄ›rnice\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Chyba: Není urÄen název metody\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Chyba: Název metody „%s“ je neplatný\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Chyba pÅ™i analyzování parametru %d typu „%s“: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Chyba pÅ™i pÅ™idávání obsluhy %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Název cíle, u kterého provést introspection" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Cesta objektu, u které provést introspection" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Vypsat XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Provést introspection potomka" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Vypsat pouze vlastnosti" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Provést introspection vzdáleného objektu." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Název cíle urÄený ke sledování" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Cesta objektu urÄená ke sledování" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Sledovat vzdálený objekt." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Chyba: nelze monitorovat pÅ™ipojení na sbÄ›rnici bez zpráv\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" +"Služba, která se má aktivovat pÅ™ed Äekáním na jinou službu (oficiálnÄ› známý " +"název)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"ÄŒasové omezení Äekaní, po kterém se skonÄí s chybou (v sekundách). 0 znamená " +"bez omezení (výchozí)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[PŘEPÃNAČ…] NÃZEV-SBÄšRNICE" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "ÄŒekat, než se objeví název sbÄ›rnice." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Chyba: Musí být urÄena služba, pro kterou provádíte aktivaci.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Chyba: Musí být urÄena služba, na kterou Äekáte.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Chyba: PříliÅ¡ mnoho argumentů.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Chyba: %s není platným oficiálnÄ› známým názvem sbÄ›rnice.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Neautorizováno ke zmÄ›nám ladicích nastavení" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Bez názvu" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "V souboru .desktop není urÄeno pole Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "NezdaÅ™ilo se najít terminál vyžadovaný pro aplikaci" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "NezdaÅ™ilo se vytvoÅ™it složku %s s uživatelským nastavením aplikace: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "NezdaÅ™ilo se vytvoÅ™it složku %s s uživatelským nastavením MIME: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Informace o aplikaci postrádá identifikátor" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "NezdaÅ™ilo se vytvoÅ™it uživatelský soubor .desktop %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Vlastní definice %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "mechanika neumí vysouvání" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "mechanika neumí vysouvací funkce eject nebo eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "mechanika neumí dotazování na média" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "mechanika neumí spuÅ¡tÄ›ní" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "mechanika neumí zastavení" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "Knihovna TLS neimplementuje zjišťování vazeb TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Podpora TLS není dostupná" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Podpora DTLS není dostupná" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Nelze zpracovat verzi %d kódování GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Chybný poÄet tokenů (%d) v kódování GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Nelze zpracovat verzi %d kódování GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Chybný poÄet tokenů (%d) v kódování GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "OÄekáváno GEmblem u GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Obsahující pÅ™ipojené neexistuje" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Nelze kopírovat nad složku" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Nelze kopírovat složku nad složku" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Cílový soubor existuje" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Složku nelze kopírovat rekurzivnÄ›" + +# For splice(), see http://en.wikipedia.org/w/index.php?title=Splice_(system_call)&oldid=334434835 +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "splice() není podporováno" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Chyba pÅ™i spojování souboru: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopírování (reflink/clone) mezi pÅ™ipojeními není podporováno" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopírování (reflink/clone) není podporováno nebo je neplatné" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopírování (reflink/clone) není podporováno nebo neprobÄ›hlo správnÄ›" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Nelze kopírovat zvláštní soubor" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Zadaný symbolický odkaz je neplatný" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Symbolické odkazy nejsou podporovány" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Zahozené není podporováno" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Názvy souborů nemohou obsahovat „%c“" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "svazek neumí pÅ™ipojení" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Žádná aplikace není zaregistrována k obsluze tohoto souboru" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator je uzavÅ™en" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Souborový enumerator má nevykonanou operaci" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Souborový enumerator je již uzavÅ™en" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Nelze zpracovat verzi %d kódování GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Chybná vstupní data u GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Datový proud nepodporuje query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Posouvání není v datovém proudu podporováno" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Oříznutí není možné ve vstupním datovém proudu" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Oříznutí není v datovém proudu podporováno" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Neplatný název poÄítaÄe" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Chybná odpovÄ›Ä HTTP proxy" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Spojení pÅ™es HTTP proxy není povoleno" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Ověření HTTP proxy selhalo" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Vyžadováno ověření HTTP proxy" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Spojení pÅ™es HTTP proxy selhalo: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "OdpovÄ›Ä z HTTP proxy je příliÅ¡ velká" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Server HTTP proxy neoÄekávanÄ› ukonÄil spojení." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Chybný poÄet tokenů (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Název třídy %s nemá typ" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Typ %s neimplementuje rozhraní GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Typ %s není mezi třídami" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Chybné Äíslo verze: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Typ %s neimplementuje from_tokens() v rozhraní GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Nelze zpracovat poskytnutou verzi kódování ikony" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Není zadána žádná adresa" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Délka %u je pro adresu příliÅ¡ dlouhá" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adresa má nastavené bity za hranicí danou prefixem délky" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Nelze zpracovat „%s“ jak masku adresy IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Adresa soketu nemá dostatek místa" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nepodporovaná adresa soketu" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Vstupní datový proud neumí Ätení" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Proud má otevÅ™enou operaci" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopírovat se souborem" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Zachovat u souboru, když je pÅ™esunut" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "„version“ nepÅ™ebírá žádné argumenty" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Použití:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Vypsat informace o verzi a skonÄit." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Příkazy:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Spojit soubory do standardního výstupu" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopírovat jeden nebo více souborů" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Zobrazit informace o umístÄ›ních" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Spustit aplikaci ze souboru .desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Vypsat obsah umístÄ›ní" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Vypsat nebo nastavit obsluhu pro typ MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "VytvoÅ™it složky" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Sledovat soubory a složky ohlednÄ› zmÄ›n" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "PÅ™ipojit nebo odpojit umístÄ›ní" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "PÅ™esunout jeden nebo více souborů" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Otevřít soubory pomocí výchozí aplikace" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "PÅ™ejmenovat soubor" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Smazat jeden nebo více souborů" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Číst a ukládat ze standardního vstupu" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Nastavit atribut souboru" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "PÅ™esunout soubory nebo složky do koÅ¡e" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Vypsat obsah umístÄ›ní ve stromu" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Podrobnou nápovÄ›du získáte spuÅ¡tÄ›ním %s.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Chyba pÅ™i zápisu do standardního výstupu" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:91 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "UMÃSTÄšNÃ" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Spojit soubory a vypsat je do standardního výstupu." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"cat z gio funguje úplnÄ› stejnÄ› jako tradiÄní příkaz cat, ale namísto\n" +"lokálních souborů používá umístÄ›ní GIO: například můžete pro umístÄ›ní\n" +"použít nÄ›co jako smb://server/cesta/soubor.txt" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nebylo zadáno žádné umístÄ›ní" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nebyla zadána žádná cílová složka" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Zobrazovat průbÄ›h" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "PÅ™ed pÅ™epsáním se dotázat" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Zachovat vÅ¡echny atributy" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Zálohovat stávající cílové soubory" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nenásledovat symbolické odkazy" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Používat pro tento cíl výchozí oprávnÄ›ní" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "PÅ™eneseno %s z %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ZDROJ" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "CÃL" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopírovat jeden nebo více souborů ze ZDROJE do CÃLE." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"copy z gio funguje úplnÄ› stejnÄ› jako tradiÄní příkaz copy, ale používá\n" +"namísto lokálních souborů umístÄ›ní GIO: například můžete pro umístÄ›ní\n" +"použít nÄ›co jako smb://server/cesta/soubor.txt." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Cíl %s není složka" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: pÅ™epsat „%s“?" + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Vypsat zapisovatelné atributy" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Vypsat informace o souborovém systému" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Atributy, které se mají vypsat" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTY" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Nenásledovat symbolické odkazy" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributy:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "zobrazovaný název: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "upravovaný název: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "název: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "typ: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "velikost: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "skrytý\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "adresa uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "místní cesta: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "pÅ™ipojené unixové svazky: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Nastavitelné atributy:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Jmenné prostory zapisovatelných atributů:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Zobrazit informace o umístÄ›ní" + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"info z gio je podobné jako tradiÄní příkaz ls, ale používá namísto\n" +"lokálních souborů umístÄ›ní GIO: například můžete pro umístÄ›ní použít\n" +"nÄ›co jako smb://server/cesta/soubor.txt. Atributy souboru lze zadat\n" +"jejich názvy GIO: napÅ™. standard::icon, nebo jednoduÅ¡e pomocí jmenného\n" +"prostoru, napÅ™. unix, nebo pomocí „*“, která odpovídá vÅ¡em atributům." + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "SOUBOR-DESKTOP [ARG-SOUBOR …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Spustit aplikaci ze souboru .desktop, případnÄ› ji pÅ™i tom pÅ™edat volitelný " +"argument s názvem souboru." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nebylo zadán žádný soubor .desktop" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "SpouÅ¡tÄ›cí příkaz není v souÄasnosti na této platformÄ› podporován" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "NezdaÅ™ilo se naÄíst „%s“: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "NezdaÅ™ilo se naÄíst informace o aplikaci pro „%s“" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "NezdaÅ™ilo se naÄíst aplikaci „%s“: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Zobrazit skryté soubory" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Použít dlouhý formát výpisu" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Vypisovat zobrazované názvy" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Vypsat úplné adresy URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Vypsat obsahy umístÄ›ní." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"list z gio funguje úplnÄ› stejnÄ› jako tradiÄní příkaz ls, ale používá\n" +"namísto lokálních souborů umístÄ›ní GIO: například můžete pro umístÄ›ní\n" +"použít nÄ›co jako smb://server/cesta/soubor.txt. Atributy souboru lze\n" +"zadat jejich názvy GIO: napÅ™. standard::icon." + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TYP_MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "OBSLUHA" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Zobrazit nebo nastavit obsluhu pro typ MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Když není zadaná žádná obsluha, vypsat registrované a doporuÄené\n" +"aplikace pro typ MIME. Když je obsluha zadaná, nastaví se jako\n" +"výchozí obsluha pro typ MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Musíte zadat jeden typ MIME a případnÄ› obsluhu" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Pro „%s“ není žádná výchozí aplikace\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Výchozí aplikace pro „%s“: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registrované aplikace:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nejsou registrované žádné aplikace\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "DoporuÄené aplikace:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Žádné aplikace nejsou doporuÄené\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Selhalo naÄtení informací pro obsluhu „%s“" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Selhalo nastavení „%s“ jako výchozí obsluhy pro „%s“: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "VytvoÅ™it rodiÄovské složky" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "VytvoÅ™it složky." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"mkdir z gio je podobný jako tradiÄní příkaz mkdir, ale používá namísto\n" +"lokálních souborů umístÄ›ní GIO: například můžete pro umístÄ›ní použít\n" +"nÄ›co jako smb://server/cesta/moje_složka." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Sledovat složku (výchozí: závisí na typu)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Sledovat soubor (výchozí: závisí na typu)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Sledovat soubor přímo (vÅ¡imne si i zmÄ›n pÅ™es tvrdé odkazy)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Sledovat soubor přímo, ale nehlásit zmÄ›ny" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "Hlásit pÅ™esuny a pÅ™ejmenování jako oddÄ›lené události smazání/vytvoÅ™ení" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Sledovat události pÅ™ipojení" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Sledovat soubory nebo složky ohlednÄ› zmÄ›n" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "PÅ™ipojit jako pÅ™ipojitelný" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "" +"PÅ™ipojit svazek odpovídající souboru zařízení nebo jinému identifikátoru" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Odpojit" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Vysunout" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Zastavit médium odpovídající souboru zařízení" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ZAŘÃZENÃ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Odpojit vÅ¡echna pÅ™ipojení se zadaným schématem" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHÉMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "PÅ™i odpojování nebo vysouvání ignorovat nedokonÄené operace se soubory" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "PÅ™i ověřování použít anonymního uživatele" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Vypsat" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Sledovat události" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Zobrazit doplňující informace" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Číselný PIM pro odemykání svazku VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "PÅ™ipojit skrytý svazek TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "PÅ™ipojit systémový svazek TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonymní přístup byl zamítnut" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Pro soubor zařízení není žádné médium" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Pro dané ID není žádný svazek" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "PÅ™ipojit nebo odpojit umístÄ›ní." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Nepoužívat jako náhradu kopírování a mazání" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "PÅ™esunout jeden nebo více souborů ze ZDROJE do CÃLE." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"move z gio je podobný jako tradiÄní příkaz mv, ale používá namísto\n" +"lokálních souborů umístÄ›ní GIO: například můžete pro umístÄ›ní\n" +"použít nÄ›co jako smb://server/cesta/soubor.txt." + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Cíl %s není složka" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Otevřít soubory pomocí výchozí aplikace, která\n" +"je registrovaná k obsluze souborů tohoto typu." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignorovat neexistující soubory, neptat se" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Odstranit zadané soubory." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NÃZEV" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "PÅ™ejmenovat soubor." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Schází argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:139 +msgid "Too many arguments" +msgstr "PříliÅ¡ mnoho argumentů" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "PÅ™ejmenování bylo úspěšné. Nová adresa URI je: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "VytvoÅ™it, jen když neexistuje" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "PÅ™idat na konec souboru" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "PÅ™i vytváření omezit přístup jen na aktuálního uživatele" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "PÅ™i nahrazování nahradit, jako by cíl neexistoval" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Vypsat nový etag a skonÄit" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Etag souboru, který je pÅ™episován" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Chyba pÅ™i Ätení ze standardního vstupu" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag není dostupný\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Číst ze standardního vstupu a uložit do CÃLE." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nebylo zadán žádný cíl" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Typ atributu" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYP" + +#: gio/gio-tool-set.c:91 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: gio/gio-tool-set.c:91 +msgid "VALUE" +msgstr "HODNOTA" + +#: gio/gio-tool-set.c:95 +msgid "Set a file attribute of LOCATION." +msgstr "Nastavit souborový atribut UMÃSTÄšNÃ." + +#: gio/gio-tool-set.c:115 +msgid "Location not specified" +msgstr "Není zadáno umístÄ›ní" + +#: gio/gio-tool-set.c:122 +msgid "Attribute not specified" +msgstr "Není zadán atribut" + +#: gio/gio-tool-set.c:132 +msgid "Value not specified" +msgstr "Není urÄena hodnota" + +#: gio/gio-tool-set.c:182 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Neplatný typ atributu „%s“" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Vysypat koÅ¡" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Vypsat soubory v koÅ¡i vÄetnÄ› jejich původního umístÄ›ní" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Obnovit soubory z koÅ¡e do jejich původního umístÄ›ní (může případnÄ› znovu " +"vytvoÅ™it složky)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "NezdaÅ™ilo se najít původní cestu" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "NezdaÅ™ilo se vytvoÅ™it původní umístÄ›ní: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "NezdaÅ™ilo se pÅ™esunout soubory do jejich původního umístÄ›ní: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "PÅ™esunout/obnovit soubory nebo složky do/z koÅ¡e." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Poznámka pro pÅ™epínaÄ --restore: pokud původní umístÄ›ní vyhozeného souboru " +"momentálnÄ› existuje, nebude pÅ™epsáno, ledaže použijete pÅ™epínaÄ --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Zadané umístÄ›ní nezaÄíná trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Následovat symbolické odkazy, pÅ™ipojení a zástupce." + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Vypsat obsah složek v podobÄ› stromu." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Prvek <%s> není povolen uvnitÅ™ <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Prvek <%s> není povolen na nejvyšší úrovni" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Soubor %s s v prostÅ™edku nachází vícekrát" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Nelze najít „%s“ v žádné ze zdrojových složek" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Nelze nají „%s“ v aktuální složce" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Neznámá volba zpracování „%s“" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Je požadováno pÅ™edzpracování %s, ale promÄ›nná %s není nastavená a %s není v " +"prohledávaných cestách PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Chyba Ätení souboru „%s“: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Chyba pÅ™i komprimaci souboru „%s“" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "text nemůže být umístÄ›n uvnitÅ™ <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Zobrazit verzi programu a skonÄit" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Název výstupního souboru" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Složka, ze které mají být Äteny soubory odkazované v SOUBOR (výchozí je " +"aktuální složka)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "SLOŽKA" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Generovat výstup ve formátu vybraného podle přípony v názvu cílového souboru" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Generovat hlaviÄkový soubor" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Generovat zdrojový kód, který se použije ve vaÅ¡em zdrojovém kódu jako odkaz " +"na soubor prostÅ™edků" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Generovat seznam závislostí" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Název souboru se závislostmi, který se má vygenerovat" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Do generovaných souborů závislostí zahrnout i fiktivní cíle" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "ProstÅ™edek nevytvářet a neregistrovat automaticky" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Neexportovat funkce; oznaÄit je za G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Nevkládat data prostÅ™edků do souborů C; pÅ™edpokládat, že jsou místo toho " +"navázána externÄ›" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Název identifikátoru C použitý ke generování zdrojového kódu" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Kompilátor C pro cíl (výchozí: promÄ›nná prostÅ™edí CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"PÅ™eložit vÅ¡echny specifikace prostÅ™edků do souboru prostÅ™edků.\n" +"Soubory se specifikacemi prostÅ™edků musí mít příponu .gschema.xml,\n" +"a soubor prostÅ™edků musí mít příponu .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "MÄ›l by být zadán právÄ› jeden název souboru\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "pÅ™ezdívka musí mít nejménÄ› 2 znaky" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Neplatná Äíselná hodnota" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " již bylo urÄeno" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' již bylo urÄeno" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "hodnoty příznaků musí mít nastavený alespoň 1 bit" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> musí obsahovat nejménÄ› jednu " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> se nenachází v urÄeném rozsahu" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> není platným Älenem urÄeného výÄtového typu" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> obsahuje Å™etÄ›zec, který není v urÄeném příznakovém typu" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> obsahuje Å™etÄ›zec, který není ve volbách " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " již bylo pro tento klÃ­Ä urÄeno" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " není možné použít pro klíÄe typu „%s“" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " urÄující minimum je vÄ›tší než maximum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "nepodporovaná kategorie l10n: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "je požadována l10n, ale není uvedena doména gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "uveden pÅ™ekladový kontext pro hodnotu bez povolené l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Selhalo zpracování hodnoty pro typ „%s“: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" nelze uvést u klíÄů, které jsou oznaÄené, že mají výÄtový typ" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " již bylo pro tento klÃ­Ä urÄeno" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " není možné použít pro klíÄe typu „%s“" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " již bylo uvedeno" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " musí nejménÄ› jedenkrát obsahovat " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " již bylo pro tento klÃ­Ä urÄeno" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" může být uvedeno jen pro klíÄe s výÄtovým nebo příznakovým typem, " +"nebo za " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" uvedeno ve chvíli, kdy „%s“ je již Älenem výÄtového typu" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" uvedeno v chvíli, kdy je již zadáno " + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " již bylo urÄeno" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "alias cíle „%s“ není ve výÄtovém typu" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "alias cíle „%s“ není v " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " musí nejménÄ› jedenkrát obsahovat " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Prázdné názvy nejsou povoleny" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Neplatný název „%s“: názvy musí zaÄínat malým písmenem" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Neplatný název „%s“: neplatný znak „%c“; pouze malá písmena, Äíslice a " +"pomlÄka („-“) jsou povoleny." + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Neplatný název „%s“: dvÄ› po sobÄ› následující pomlÄky („--“) nejsou povoleny." + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Neplatný název „%s“: posledním znakem nemůže být pomlÄka („-“)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Neplatný název „%s“: maximální délka je 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " již bylo urÄeno" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Ke schématu „list-of“ nelze pÅ™idat klíÄe" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " již bylo urÄeno" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" má pÅ™ednost pÅ™ed v ; " +"použijte ke zmÄ›nÄ› hodnoty" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"PrávÄ› jeden z „type“, „enum“ nebo „flags“ musí být vybrán jako atribut ke " +"klíÄi " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (zatím) nebylo urÄeno." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Neplatný Å™etÄ›zec typu GVariant „%s“" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "Zadáno , ale schéma nic nerozÅ¡iÅ™uje" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Neexistuje žádné k pÅ™epsání" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " již bylo urÄeno" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " již bylo urÄeno" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " rozÅ¡iÅ™uje zatím neexistující schéma „%s“" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " je seznamem zatím neexistujícího schématu „%s“" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Nemůže být seznamem schématu s cestou" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Nemůže rozšířit schéma s cestou" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" je seznam rozÅ¡iÅ™ující , což není seznam" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" rozÅ¡iÅ™uje , ale " +"„%s“ nerozÅ¡iÅ™uje „%s“" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Cesta, je-li zadána, musí zaÄínat a konÄit lomítkem" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Cesta seznamu musí konÄit „:/“" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Varování: Schéma „%s“ má cestu „%s“. Cesty zaÄínající „/apps/“, „/desktop/“ " +"nebo „/system/“ jsou zavržené." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> již bylo urÄeno" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "UvnitÅ™ <%2$s> je povolen jen jeden prvek <%1$s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Prvek <%s> není povolen na nejvyšší úrovni" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "V prvku je vyžadován prvek " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Text nemůže být umístÄ›n uvnitÅ™ <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Varování: nedefinovaný odkaz na " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "Bylo zadáno --strict; ukonÄuje se." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Celý tento soubor byl ignorován." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Tento soubor se ignoruje." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"KlÃ­Ä â€ž%s“ neexistuje ve schématu „%s“, jak bylo urÄeno v pÅ™episovacím " +"souboru „%s“; pÅ™episování bude pro tento klÃ­Ä ignorováno." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"KlÃ­Ä â€ž%s“ neexistuje ve schématu „%s“, jak bylo urÄeno v pÅ™episovacím " +"souboru „%s“, a pÅ™itom bylo zadáno --strict; ukonÄuje se." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Nelze poskytnout pÅ™epis podle uživatelského prostÅ™edí pro lokalizovaný klÃ­Ä " +"„%s“ ve schématu „%s“ (pÅ™episovací soubor „%s“); pÅ™episování bude pro tento " +"klÃ­Ä ignorováno." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Nelze poskytnout pÅ™epis podle uživatelského prostÅ™edí pro lokalizovaný klÃ­Ä " +"„%s“ ve schématu „%s“ (pÅ™episovací soubor „%s“) a pÅ™itom bylo zadáno --" +"strict; ukonÄuje se." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Chyba pÅ™i zpracování klíÄe „%s“ ve schématu „%s“, jenž je uveden v " +"pÅ™episovacím souboru „%s“: %s. PÅ™episování bude pro tento klÃ­Ä ignorováno." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Chyba pÅ™i zpracování klíÄe „%s“ ve schématu „%s“, jenž je uveden v " +"pÅ™episovacím souboru „%s“: %s. PÅ™itom bylo zadáno --strict; ukonÄuje se." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"PÅ™epis pro klÃ­Ä â€ž%s“ ve schématu „%s“ v pÅ™episovacím souboru „%s“ je mimo " +"rozsah zadaný ve schématu; pÅ™episování bude pro tento klÃ­Ä ignorováno." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"PÅ™epis pro klÃ­Ä â€ž%s“ ve schématu „%s“ v pÅ™episovacím souboru „%s“ je mimo " +"rozsah zadaný ve schématu a pÅ™itom bylo zadáno --strict; ukonÄuje se." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"PÅ™epis pro klÃ­Ä â€ž%s“ ve schématu „%s“ v pÅ™episovacím souboru „%s“ není v " +"seznamu platných možností; pÅ™episování bude pro tento klÃ­Ä ignorováno." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"PÅ™epis pro klÃ­Ä â€ž%s“ ve schématu „%s“ v pÅ™episovacím souboru „%s“ není v " +"seznamu platných možností a pÅ™itom bylo zadáno --strict; ukonÄuje se." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Kam ukládat soubor gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "PÅ™eruÅ¡it pÅ™i libovolných chybách ve schématech" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Nezapisovat soubor gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Nevynucovat omezení názvů klíÄe" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompilovat vÅ¡echny soubory schémat GSettings do mezipamÄ›ti schémat.\n" +"Soubory schémat musí mít rozšíření .gschema.xml,\n" +"a soubor mezipamÄ›ti se jmenuje gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "MÄ›l by být zadán právÄ› jeden název složky" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Žádné soubory schémat nenalezeny: nebude se nic dÄ›lat." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Žádné soubory schémat nenalezeny: odstranÄ›n existující výstupní soubor." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Neplatný název souboru %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Chyba pÅ™i získávání informace o souborovém systému pro %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Přípojení obsahující soubor %s nebylo nalezen" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Nelze pÅ™ejmenovat koÅ™enovou složku" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Chyba pÅ™i pÅ™ejmenovávání souboru %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Soubor nelze pÅ™ejmenovat, název souboru již existuje" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Neplatný název souboru" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Chyba pÅ™i otevírání souboru %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Chyba pÅ™i odstraňování souboru %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Chyba pÅ™i zahazování souboru %s do koÅ¡e: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Nelze vytvoÅ™it složku koÅ¡e %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "NezdaÅ™ilo se najít složku nejvyšší úrovnÄ› pro vyhození %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"PÅ™esouvání do koÅ¡e na svazku pÅ™ipojeném internÄ› systémem není podporováno" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "NezdaÅ™ilo se najít nebo vytvoÅ™it složku koÅ¡e %s pro vyhození %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Nelze vytvoÅ™it informaÄní soubor o koÅ¡i pro %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Nelze zahodit soubor %s do koÅ¡e mimo hranice souborového systému" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Nelze zahodit soubor %s do koÅ¡e: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Nelze zahodit soubor %s do koÅ¡e" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Chyba pÅ™i vytváření složky %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Systém souborů nepodporuje symbolické odkazy" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Chyba pÅ™i vytváření symbolického odkazu %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Chyba pÅ™i pÅ™esunování souboru %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Složku nelze pÅ™esunout nad složku" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "VytvoÅ™ení záložního souboru selhalo" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Chyba pÅ™i odstraňování cílového souboru: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "PÅ™esunování mezi pÅ™ipojeními není podporováno" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Nelze zjistit využití disku %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Hodnota atributu nesmí být prázdná" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Neplatný typ atributu (oÄekáván Å™etÄ›zec)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Neplatný název rozšířeného atributu" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Chyba pÅ™i nastavování rozšířeného atributu „%s“: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (neplatné kódování)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Chyba pÅ™i získávání informací pro soubor „%s“: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Chyba pÅ™i získávání informací pro popisovaÄe souboru: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Neplatný typ atributu (oÄekáván uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Neplatný typ atributu (oÄekáván uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Neplatný typ atributu (oÄekáván bajtový Å™etÄ›zec)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Nelze nastavit oprávnÄ›ní na symbolických odkazech" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Chyba pÅ™i nastavování oprávnÄ›ní: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Chyba pÅ™i nastavování vlastníka: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "symbolický odkaz nesmí být prázdný" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Chyba pÅ™i nastavování symbolického odkazu: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Chyba pÅ™i nastavování symbolického odkazu: soubor není symbolickým odkazem" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "DodateÄné nanosekundy %d pro UNIXové Äasové razítko %lld jsou záporné." + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"DodateÄné nanosekundy %d pro UNIXové Äasové razítko %lld dosáhly 1 sekundy." + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIXové Äasové razítko %lld se nevleze do 64 bitů." + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "UNIXové Äasové razítko %lld je mimo rozsah podporovaný Windows." + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Název souboru „%s“ se nezdaÅ™ilo pÅ™evést do UTF-16." + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Soubor „%s“ se nezdaÅ™ilo otevřít: chyba Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Chyba pÅ™i nastavování Äasu zmÄ›ny nebo přístupu u souboru „%s“: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Chyba pÅ™i nastavování Äasu zmÄ›ny nebo přístupu: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Kontext SELinux nesmí být prázdný." + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "V tomto systému není SELinux povolen" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Chyba pÅ™i nastavování kontextu SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Nastavení atributu %s není podporováno" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Chyba pÅ™i Ätení ze souboru: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Chyba pÅ™i zavírání souboru: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Chyba pÅ™i hledání v souboru: %s" + +#: gio/glocalfilemonitor.c:879 +msgid "Unable to find default local file monitor type" +msgstr "Nelze nalézt výchozí typ sledování místního souboru" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Chyba pÅ™i zápisu do souboru: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Chyba pÅ™i odstraňování starého záložního odkazu: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Chyba pÅ™i vytváření záložní kopie: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Chyba pÅ™i pÅ™ejmenovávání doÄasného souboru: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Chyba pÅ™i zkracování souboru: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Chyba pÅ™i otevírání souboru %s: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Cílový soubor je složka" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Cílový soubor není obyÄejným souborem" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Soubor byl externÄ› pozmÄ›nÄ›n" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Chyba pÅ™i odstraňování starého souboru: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Poskytnut neplatný GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Neplatný požadavek na hledání" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Nelze zkrátit GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Nelze mÄ›nit velikost výstupního proudu pamÄ›ti" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Nelze zmÄ›nit velikost výstupního proudu pamÄ›ti" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Velikost pamÄ›ti potÅ™ebná ke zpracování zápisu je vÄ›tší než dostupný adresní " +"prostor" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Požadováno hledání pÅ™ed poÄátkem proudu" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Požadováno hledání za ukonÄením proudu" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "pÅ™ipojené neprovádí odpojovací operaci „unmount“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "pÅ™ipojené neumí vysouvací operaci „eject“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"pÅ™ipojené neumí odpojovací operaci „unmount“ nebo „unmount_with_operation“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "pÅ™ipojené neumí vysouvací operaci „eject“ nebo „eject_with_operation“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "pÅ™ipojené neumí operaci opakovaného pÅ™ipojení „remount“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "pÅ™ipojené neumí odhad typu obsahu" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "pÅ™ipojené neumí synchronní odhad typu obsahu" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Název poÄítaÄe „%s“ obsahuje „[“, ale nikoliv „]“" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Síť není dostupná" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "PoÄítaÄ není dostupný" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Nelze vytvoÅ™it sledování sítÄ›: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Nelze vytvoÅ™it sledování sítÄ›: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Nelze zjistit stav sítÄ›: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager neběží" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager je v příliÅ¡ staré verzi" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Výstupní datový proud neumí zápis" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "SouÄet vektorů pÅ™edaných do %s je příliÅ¡ velký" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Zdrojový proud je již ukonÄen" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Chyba pÅ™i Å™eÅ¡ení „%s“: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "Funkce %s není implementovaná" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Neplatná doména" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "ProstÅ™edek v „%s“ neexistuje" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Selhala dekomprimace prostÅ™edku v „%s“" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "ProstÅ™edek v „%s“ není složka" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Vstupní datový proud neumí pÅ™eskakování" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Vypsat oddíly obsahující prostÅ™edky v SOUBORU ve formátu elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Vypsat prostÅ™edky\n" +"Je-li zadán ODDÃL, jsou vypsány pouze prostÅ™edky v tomto oddíle\n" +"Je-li zadána CESTA, jsou vypsány jen odpovídající prostÅ™edky" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "SOUBOR [CESTA]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "ODDÃL" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Vypsat prostÅ™edky vÄetnÄ› podrobností\n" +"Je-li zadán ODDÃL, jsou vypsány pouze prostÅ™edky v tomto oddíle\n" +"Je-li zadána CESTA, jsou vypsány jen odpovídající prostÅ™edky\n" +"Podrobnosti zahrnují oddíl, velikost a komprimaci" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Vybalit prostÅ™edky ze souboru na standardní výstup" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "SOUBOR CESTA" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Použití:\n" +" gresource [--section ODDÃL] PŘÃKAZ [ARGUMENTY…]\n" +"\n" +"Příkazy:\n" +" help Zobrazit tyto informace\n" +" sections Vypsat oddíly s prostÅ™edky\n" +" list Vypsat prostÅ™edky\n" +" details Vypsat prostÅ™edky vÄetnÄ› prodrobností\n" +" extract Vybalit prostÅ™edky\n" +"\n" +"Další informace získáte zadáním „gresource help PŘÃKAZ“.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Použití:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " ODDÃL (Volitelný) název oddílu elf\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " PŘÃKAZ (Volitelný) příkaz, který má být popsán\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" SOUBOR Soubor ve formátu elf (spustitelný nebo sdílená knihovna)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" SOUBOR Soubor ve formátu elf (spustitelný nebo sdílená knihovna)\n" +" nebo pÅ™eložený soubor prostÅ™edků\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[CESTA]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " CESTA (Volitelná) cesta k prostÅ™edku (může být neúplná)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CESTA" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " CESTA Cesta k prostÅ™edku\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Schéma „%s“ neexistuje\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Schéma „%s“ není pÅ™emístitelné (cesta nesmí být urÄena)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schéma „%s“ je pÅ™emístitelné (cesta musí být urÄena)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Poskytnuta prázdná cesta.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Cesta musí zaÄínat lomítkem (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Cesta musí konÄit lomítkem (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Cesta nesmí obsahovat dvÄ› po sobÄ› jdoucí lomítka (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Poskytnutá hodnota je mimo platný rozsah\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "KlÃ­Ä není zapisovatelný\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Vypíše nainstalovaná (nepÅ™emístitelná) schémata" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Vypíše nainstalovaná pÅ™emístitelná schémata" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Vypíše klíÄe ve SCHÉMATU" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHÉMA[:CESTA]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Vypíše potomky SCHÉMATU" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Vypíše klíÄe a hodnoty, rekurzivnÄ›\n" +"Není-li zadáno SCHÉMA, vypíše vÅ¡echny klíÄe\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHÉMA[:CESTA]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Získá hodnotu KLÃÄŒE" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHÉMA[:CESTA] KLÃÄŒ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Dotáže se na rozsah platných hodnot KLÃÄŒE" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Dotáže se na popis KLÃÄŒE" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Nastaví hodnotu KLÃÄŒE k HODNOTÄš" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHÉMA[:CESTA] KLÃÄŒ HODNOTA" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Nastaví KLÃÄŒ na výchozí hodnotu" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Resetovat vÅ¡echny klíÄe ve SCHÉMATU na výchozí hodnoty" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Zjistí, zda je KLÃÄŒ zapisovatelný" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Sleduje zmÄ›ny KLÃÄŒE.\n" +"Není-li zadán KLÃÄŒ, sleduje vÅ¡echny klíÄe ve SCHÉMATU.\n" +"Sledování zastavíte použitím ^C.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHÉMA[:CESTA] [KLÃÄŒ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Použití:\n" +" gsettings --version\n" +" gsettings [--schemadir SLOŽKA_SCHÉMAT] PŘÃKAZ [ARGUMENTY...]\n" +"\n" +"Příkazy:\n" +" help Zobrazit tuto informaci\n" +" list-schemas Vypsat nainstalovaná schémata\n" +" list-relocatable-schemas Vypsat pÅ™emístitelná schémata\n" +" list-keys Vypsat klíÄe ve schématu\n" +" list-children Vypsat potomky schématu\n" +" list-recursively Vypsat klíÄe a hodnoty, rekurzivnÄ›\n" +" range Dotázat se na rozsah hodnot klíÄe\n" +" describe Dotázat se na popis klíÄe\n" +" get Získat hodnotu klíÄe\n" +" set Nastavit hodnotu klíÄe\n" +" reset Resetovat hodnotu klíÄe\n" +" reset-recursively Resetovat vÅ¡echny hodnoty v daném schématu\n" +" writable Zkontrolovat, zda je klÃ­Ä zapisovatelný\n" +" monitor Sledovat zmÄ›ny\n" +"\n" +"Podrobnou nápovÄ›du získáte použitím „gsettings help PŘÃKAZ“.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Použití:\n" +" gsettings [--schemadir SLOŽKA_SCHÉMAT] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SLOŽKA_SCHÉMAT Složka, ve které se mají hledat dodateÄná schémata\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHÉMA Název schématu\n" +" CESTA Cesta, pro pÅ™emístitelná schémata\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KLÃÄŒ (Volitelný) klÃ­Ä uvnitÅ™ schématu\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KLÃÄŒ KlÃ­Ä uvnitÅ™ schématu\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " HODNOTA Hodnota, která má být nastavena\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Nelze nahrát schémata z %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nejsou nainstalována žádná schémata\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Poskytnut prázdný název schématu\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "KlÃ­Ä â€ž%s“ neexistuje\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Neplatný soket, nebyl spuÅ¡tÄ›n" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Neplatný soket, spuÅ¡tÄ›ní selhalo kvůli: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Soket je již ukonÄen" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "ÄŒasový limit V/V soketu vyprÅ¡el" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "vytváří se GSocket z fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Nelze vytvoÅ™it soket: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Byla zadána neznámá rodina" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Byl zadán neznámý protokol" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Nelze používat datagramové operace na nedatagramovém soketu." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Nelze používat datagramové operace na soketu s nastaveným Äasovým limitem." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "nezdaÅ™ilo se získat místní adresu: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "nezdaÅ™ilo se získat vzdálenou adresu: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "nezdaÅ™ilo se naslouchání: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Chyba pÅ™i navázání na adresu %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Chyba pÅ™ipojování ke skupinÄ› hromadného vysílání: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Chyba pÅ™i opouÅ¡tÄ›ní skupiny hromadného vysílání: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Není podpora pro hromadné vysílání urÄené zdrojem" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Nepodporovaná rodina soketů" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "urÄení zdroje není adresa IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Název rozhraní je příliÅ¡ dlouhý" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Rozhraní nebylo nalezeno: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Není podpora pro hromadné vysílání urÄené zdrojem IPv4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Není podpora pro hromadné vysílání urÄené zdrojem IPv6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Chyba pÅ™i pÅ™ijímání spojení: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Probíhá spojení" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Nelze získat nevyřízenou chybu: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Chyba pÅ™i získávání dat: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Chyba pÅ™i odesílání dat: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Nelze ukonÄit soket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Chyba pÅ™i zavírání soketu: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ÄŒeká se na stav soketu: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "NezdaÅ™ilo se odeslat zprávu: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vektory zprávy jsou příliÅ¡ rozsáhlé" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Chyba pÅ™i odesílání zprávy: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage nepodporováno na Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Chyba pÅ™i získávání zprávy: %s" + +#: gio/gsocket.c:6092 gio/gsocket.c:6103 gio/gsocket.c:6166 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Nelze Äíst pověření k soketu: %s" + +#: gio/gsocket.c:6175 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials není u tohoto OS implementováno" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Nelze se pÅ™ipojit k serveru proxy %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Nelze se pÅ™ipojit k %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Nelze se pÅ™ipojit: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1805 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" +"Není podporován pokus o proxy pÅ™es spojení, které není založeno na TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1834 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Protokol proxy „%s“ není podporován." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Naslouchající je již uzavÅ™en" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "PÅ™idaný soket je uzavÅ™en" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 nepodporuje adresy IPv6 „%s“" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Uživatelské jméno je příliÅ¡ dlouhé na protokol SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Název poÄítaÄe „%s“ je na protokol SOCKSv4 příliÅ¡ dlouhý" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Server není proxy serverem SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Spojení pÅ™es server SOCKSv4 bylo odmítnuto" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Server není proxy serverem SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 proxy vyžaduje ověření." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 vyžaduje metodu ověření nepodporovanou v GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Uživatelské jméno nebo heslo je příliÅ¡ dlouhé na protokol SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Ověření SOCKSv5 selhalo z důvodu chybného uživatelského jména nebo hesla." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Název poÄítaÄe „%s“ je na protokol SOCKSv5 příliÅ¡ dlouhý" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Proxy server SOCKSv5 používá neznámý typ adresy." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "VnitÅ™ní chyba proxy serveru SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Spojení SOCKSv5 není povoleno zadaným pravidlem." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "PoÄítaÄ není pÅ™es server SOCKSv5 dostupný." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Síť není pÅ™es server SOCKSv5 dostupná." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Spojení bylo pÅ™es SOCKSv5 proxy odmítnuto." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 proxy nepodporuje příkaz „connect“." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 proxy nepodporuje poskytnutý typ adresy." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Neznámá chyba SOCKSv5 proxy." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Selhalo vytvoÅ™ení roury ke komunikaci s procesem potomka (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Roury nejsou na této platformÄ› podporovány" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Nelze zpracovat verzi %d kódování GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Nebyly nalezeny žádné platné adresy" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Chyba pÅ™i reverzním Å™eÅ¡ení „%s“: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Chyba pÅ™i zpracování záznamu %s z DNS: poÅ¡kozený paket DNS" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Záznam DNS požadovaného typu pro „%s“ neexistuje" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "DoÄasnÄ› není možné vyÅ™eÅ¡it „%s“" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Chyba pÅ™i Å™eÅ¡ení „%s“" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "PoÅ¡kozený paket DNS" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Selhalo zpracování odpovÄ›di DNS pro „%s“: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Nebyl nalezen žádný soukromý klÃ­Ä kódovaný jako PEM." + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Nelze deÅ¡ifrovat soukromý klÃ­Ä kódovaný jako PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "NezdaÅ™ilo se analyzovat soukromý klÃ­Ä kódovaný jako PEM." + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Nebyl nalezen žádný certifikát kódovaný jako PEM." + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "NezdaÅ™ilo se analyzovat certifikát kódovaný jako PEM." + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Tato knihovna TLS nepodporuje PKCS #12." + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Tento GTlsBackend nepodporuje vytváření certifikátů PKCS #11." + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Toto je poslední možnost zadat heslo správnÄ› pÅ™ed tím, než bude přístup " +"zablokován." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"NÄ›kolik pÅ™edeÅ¡lých hesel nebylo zadáno správnÄ› a po dalším nesprávnÄ› zadaném " +"hesle bude přístup zablokován." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Zadané heslo není správné." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Odesílání popisovaÄe souboru není podporováno" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "OÄekávána 1 ovládací zpráva, získána %d" +msgstr[1] "OÄekávána 1 ovládací zpráva, získány %d" +msgstr[2] "OÄekávána 1 ovládací zpráva, získáno %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "NeoÄekávaný typ pomocných dat" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "OÄekáváno jedno fd, ale získána %d\n" +msgstr[1] "OÄekáváno jedno fd, ale získány %d\n" +msgstr[2] "OÄekáváno jedno fd, ale získáno %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "PÅ™ijat neplatný popisovaÄ souboru" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "PÅ™ijímání popisovaÄe souboru není podporováno" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Chyba pÅ™i odesílání pÅ™ihlaÅ¡ovacích údajů: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Chyba pÅ™i kontrole, zda je SO_PASSCRED povoleno u soketu: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Chyba pÅ™i povolování SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"U odeslání pÅ™ihlaÅ¡ovacích údajů oÄekáváno pÅ™eÄtení jednoho bajtu, ale " +"pÅ™eÄteno nula bajtů" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ovládací zpráva nebyla oÄekávána, ale obdrženo %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Chyba pÅ™i zakazování SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Chyba pÅ™i Ätení z popisovaÄe souboru: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Chyba pÅ™i zavírání popisovaÄe souboru: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "KoÅ™en systému souborů" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Chyba pÅ™i zápisu do popisovaÄe souboru: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "V tomto systému nejsou podporovány abstraktní adresy soketů domén UNIX" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "svazek neumí vysouvací operaci eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "svazek neumí vysouvací operaci eject nebo eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Chyba pÅ™i Ätení z obsluhy: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Chyba pÅ™i zavírání obsluhy: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Chyba pÅ™i zápisu do obsluhy: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nedostatek pamÄ›ti" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "VnitÅ™ní chyba: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Vyžadováno více na vstupu" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Neplatná komprimovaná data" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresa, na které se má naslouchat" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorováno, kvůli kompatibilitÄ› s GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Vypsat adresu" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Vypsat adresu v režimu shellu" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Spustit službu dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Nesprávné argumenty\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "NeoÄekávaný atribut „%s“ prvku „%s“" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atribut „%s“ prvku „%s“ nebyl nalezen" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "NeoÄekávaná znaÄka „%s“, byla oÄekávána znaÄka „%s“" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "NeoÄekávaná znaÄka „%s“ v „%s“" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Neplatné datum/Äas „%s“ v souboru se záložkami" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "V datových složkách nebyl nalezen platný soubor záložek" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Záložka URI „%s“ již existuje" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nebyla nalezena záložka URI „%s“" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "V záložce URI „%s“ není definován žádný typ MIME" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "V záložce URI „%s“ nebyl definován žádný soukromý příznak" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "V záložce URI „%s“ nejsou nastavené žádné skupiny" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Žádná aplikace s názvem „%s“ nezaregistrovala záložku „%s“" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Nelze rozšířit řádek exec „%s“ pomocí URI „%s“" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Nereprezentovatelný znak na vstupu pÅ™evodu" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "ČásteÄná posloupnost znaků na konci vstupu" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Nelze pÅ™evést zálohu „%s“ do znakové sady „%s“" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Vležený nulový bajt na vstupu pÅ™evodu" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Vložený nulový bajt na výstupu pÅ™evodu" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "Adresa URI „%s“ není absolutní URI používající schéma „file“" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Adresa URI „%s“ místního souboru nesmí obsahovat „#“" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Adresa URI „%s“ je neplatné" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Název poÄítaÄe v adrese URI „%s“ je neplatný" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI „%s“ obsahuje nesprávnÄ› zmÄ›nÄ›né znaky" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Název cesty „%s“ není absolutní cestou" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %-d. %B %Y, %H:%M:%S %Z" + +# This might be e.g. %Y-%m-%d or %e. %m. %Y as well. See also http://prirucka.ujc.cas.cz/?id=810. +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +# This might be e.g. %k:%M:%S or %k.%M.%S as well. See also http://prirucka.ujc.cas.cz/?id=820. +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "leden" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "únor" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "bÅ™ezen" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "duben" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "kvÄ›ten" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Äerven" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Äervenec" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "srpen" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "září" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "říjen" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "listopad" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "prosinec" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "led" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "úno" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "bÅ™e" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "dub" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "kvÄ›" + +# Might be e.g. "Äer" as well. +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Äen" + +# Might be e.g. "Ävc" as well. +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Äec" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "srp" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "zář" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "říj" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "lis" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "pro" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "pondÄ›lí" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "úterý" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "stÅ™eda" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Ätvrtek" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "pátek" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sobota" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "nedÄ›le" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "po" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "út" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "st" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Ät" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "pá" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "so" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ne" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "ledna" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "února" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "bÅ™ezna" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "dubna" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "kvÄ›tna" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Äervna" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Äervence" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "srpna" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "září" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "října" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "listopadu" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "prosince" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "led" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "úno" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "bÅ™e" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "dub" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "kvÄ›" + +# Might be e.g. "Äer" as well. +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Äen" + +# Might be e.g. "Ävc" as well. +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Äec" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "srp" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "zář" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "říj" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "lis" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "pro" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "dop." + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "odp." + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Chyba pÅ™i otevírání složky „%s“: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Nelze alokovat %lu bajtů k pÅ™eÄtení souboru „%s“" +msgstr[1] "Nelze alokovat %lu bajty k pÅ™eÄtení souboru „%s“" +msgstr[2] "Nelze alokovat %lu bajtů k pÅ™eÄtení souboru „%s“" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Chyba Ätení souboru „%s“: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Soubor „%s“ je příliÅ¡ velký" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Chyba pÅ™i Ätení ze souboru „%s“: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Nelze otevřít soubor „%s“: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Nelze získat atributy souboru „%s“: funkce fstat() selhala: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Nelze otevřít soubor „%s“: funkce fdopen() selhala: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Nelze pÅ™ejmenovat soubor „%s“ na „%s“: funkce g_rename() selhala: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Nelze zapisovat do souboru „%s“: funkce write() selhala: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Nelze zapisovat do souboru „%s“: funkce fsync() selhala: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Nelze vytvoÅ™it soubor „%s“: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Existující soubor „%s“ nelze odstranit: funkce g_unlink() selhala: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Å ablona „%s“ je neplatná, nemÄ›la by obsahovat „%s“" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Å ablona „%s“ neobsahuje XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Nelze pÅ™eÄíst symbolický odkaz „%s“: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Nelze otevřít pÅ™evodník z „%s“ do „%s“: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Nelze přímo Äíst v g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Ve vstupní vyrovnávací pamÄ›ti zbyla nepÅ™evedená data" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanál ukonÄen Äástí znaku" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Nelze přímo Äíst v g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "V složkách hledání nelze najít platný soubor klíÄe" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Není obyÄejným souborem" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Soubor klíÄe obsahuje „%s“, což není dvojice klíÄ-hodnota, skupina ani " +"komentář" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Neplatný název skupiny: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Soubor klíÄe nezaÄíná skupinou" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Neplatný název klíÄe: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Soubor klíÄe obsahuje nepodporované kódování „%s“" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Soubor klíÄe nemá skupinu „%s“" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Soubor klíÄe nemá klÃ­Ä â€ž%s“ ve skupinÄ› „%s“" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Soubor klíÄe obsahuje klÃ­Ä â€ž%s“ s hodnotou „%s“, která není v UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Soubor klíÄe obsahuje klÃ­Ä â€ž%s“, který má neinterpretovatelnou hodnotu." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Soubor klíÄe obsahuje klÃ­Ä â€ž%s“ ve skupinÄ› „%s“, který má " +"neinterpretovatelnou hodnotu." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "KlÃ­Ä â€ž%s“ ve skupinÄ› „%s“ má hodnotu „%s“, když byla oÄekávána „%s“" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Soubor klíÄe obsahuje na konci řádku znak zmÄ›ny" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Soubor klíÄe obsahuje neplatnou únikovou sekvenci „%s“" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Hodnotu „%s“ nelze interpretovat jako Äíslo." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "CeloÄíselná hodnota „%s“ je mimo rozsah" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Hodnotu „%s“ nelze interpretovat jako reálné (plovoucí) Äíslo." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Hodnotu „%s“ nelze interpretovat jako pravdivostní hodnotu." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Selhalo získání atributů souboru „%s%s%s%s“: selhala funkce fstat(): %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Selhalo namapování „%s%s%s%s“: selhala funkce mmap(): %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Selhalo otevÅ™ení souboru „%s“: selhala funkce open(): %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Chyba na řádku %d, znak %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "V názvu je neplatný text v kódování UTF-8 – platné není „%s“" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "„%s“ není platným názvem" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "„%s“ není platným názvem: „%c“" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Chyba na řádku %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Nelze zpracovat „%-.*s“, což by mÄ›lo být Äíslo v znakové entitÄ› (například " +"ê) – Äíslo je možná příliÅ¡ velké" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Znaková entita nekonÄí stÅ™edníkem; pravdÄ›podobnÄ› jste použili znak & bez " +"úmyslu zaÄít entitu – zapiÅ¡te prosím ligaturu et jako &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Znaková entita „%-.*s“ nekóduje povolený znak" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Nalezena prázdná entita „&;“, platnými entitami jsou: & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Název entity „%-.*s“ není znám" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entita nekonÄí stÅ™edníkem; pravdÄ›podobnÄ› jste použili znak & bez úmyslu " +"zaÄít entitu – zapiÅ¡te prosím ligaturu et jako &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument musí zaÄínat prvkem (například: )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "„%s“ není platný znak po znaku „<“; nesmí jím zaÄínat název prvku" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Nezapadající znak „%s“, byl oÄekáván znak „>“ k ukonÄení znaÄky empty-" +"element „%s“" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "PříliÅ¡ mnoho atributů v prvku „%s“" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Nezapadající znak „%s“, po názvu atributu „%s“ prvku „%s“ bylo oÄekáváno „=“" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Nezapadající znak „%s“, bylo oÄekáváno „>“ nebo „/“ k ukonÄení poÄáteÄní " +"znaÄky prvku „%s“, nebo případnÄ› atribut; pravdÄ›podobnÄ› jste použili " +"neplatný znak v názvu atributu" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Nezapadající znak „%s“, po znaku rovnítka pÅ™i udávání hodnoty atributu „%s“ " +"prvku „%s“ byly oÄekávány uvozovky" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"„%s“ není povoleným znakem po ukonÄovacím názvu prvku „%s“; povoleným znakem " +"je „>“" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Prvek „%s“ byl uzavÅ™en, žádný prvek není momentálnÄ› otevÅ™ený" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Prvek „%s“ byl uzavÅ™en, ale aktuálnÄ› je otevÅ™ený prvek „%s“" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument je prázdný nebo obsahuje pouze mezery" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokument neoÄekávanÄ› skonÄil ihned po otevírací znaÄce „<“" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokument neoÄekávanÄ› skonÄil s otevÅ™enými prvky – poslední otevÅ™ený prvek " +"byl „%s“" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokument neoÄekávanÄ› skonÄil, byla oÄekávána uzavírací závorka znaÄky <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokument neoÄekávanÄ› skonÄil uvnitÅ™ názvu prvku" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokument neoÄekávanÄ› skonÄil uvnitÅ™ názvu atributu" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokument neoÄekávanÄ› skonÄil ve znaÄce otevírající prvek." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokument neoÄekávanÄ› skonÄil po znaku pÅ™iÅ™azení následujícím za názvem " +"atributu; chybí hodnota atributu" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokument neoÄekávanÄ› skonÄil uvnitÅ™ hodnoty atributu" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokument neoÄekávanÄ› skonÄil uvnitÅ™ uzavírací znaÄky prvku „%s“" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Dokument neoÄekávanÄ› skonÄil uvnitÅ™ uzavírací znaÄky neotevÅ™eného prvku" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokument neoÄekávanÄ› skonÄil uvnitÅ™ komentáře nebo instrukce pro zpracování" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[PŘEPÃNAČ…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "PÅ™epínaÄe nápovÄ›dy:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Zobrazit pÅ™epínaÄe nápovÄ›dy" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Zobrazit vÅ¡echny pÅ™epínaÄe nápovÄ›dy" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "PÅ™epínaÄe aplikace:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "PÅ™epínaÄe:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Nelze zpracovat celoÄíselnou hodnotu „%s“ u %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "CeloÄíselná hodnota „%s“ pro %s je mimo rozsah" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "" +"Nelze zpracovat reálnou hodnotu s dvojitou pÅ™esností (double) „%s“ u %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "" +"Reálná hodnota s dvojitou pÅ™esností (double) „%s“ pro %s je mimo rozsah" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Chyba volby %s pÅ™i syntaktické analýze" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Chybí parametr %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Neznámý pÅ™epínaÄ %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "poÅ¡kozený objekt" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "vnitÅ™ní chyba nebo poÅ¡kozený objekt" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "nedostatek pamÄ›ti" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "dosažen limit zpÄ›tného vyhledávání" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "vzorek obsahuje položky nepodporované u ÄásteÄného porovnávání" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "vnitÅ™ní chyba" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"zpÄ›tné odkazy coby podmínky nejsou podporované u ÄásteÄného porovnávání" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "dosažen limit rekurze" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "neplatná kombinace příznaků nového řádku" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "chybný offset" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "zkrácené utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "rekurzivní smyÄka" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "neznámá chyba" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ na konci vzorku" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c na konci vzorku" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "nerozpoznaný znak následuje po \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "Äísla v {} quantifier nejsou v pořádku" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "Äíslo v {} quantifier je příliÅ¡ vysoké" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "schází koncový znak ] znakové třídy" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "neplatná posloupnost pro zmÄ›nu ve znakové třídÄ›" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "rozsah ve znakové třídÄ› není v pořádku" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nic k opakování" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "nepÅ™edpokládané opakování" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "nerozpoznaný znak po (? nebo (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "třídy nazvané po POSIX nejsou uvnitÅ™ třídy podporovány" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "schází koncový znak )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "odkaz na neexistující podÅ™azený vzorek" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "po komentáři schází znak )" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "regulární výraz je příliÅ¡ dlouhý" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "nelze získat paměť" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "znak ) bez poÄáteÄního znaku (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "pÅ™eteÄení kódu" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "nerozpoznaný znak pÅ™ed (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "zpÄ›tný výrok není pevné délky" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "nesprávnÄ› utvoÅ™ené Äíslo nebo název po (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "podmínková skupina obsahuje více než dvÄ› vÄ›tve" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "po (?( oÄekáván výrok" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R Äi (?[+-]Äíslice musí být následovány znakem )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "neplatný název třídy POSIX" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "Porovnávací prvky POSIX nejsou podporovány" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "znaková hodnota v posloupnosti \\x{…} je příliÅ¡ vysoká" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "neplatná podmínka (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C není dovoleno ve zpÄ›tném výroku" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "znaky escape \\L, \\l, \\N{název}, \\U a \\u nejsou podporovány" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "rekurzivní volání by se mohlo dostat do nekoneÄné smyÄky" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "nerozpoznaný znak pÅ™e (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "schází ukonÄovací Älen v názvu podÅ™azeného vzorku" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dva nazvané podÅ™azené vzorky mají stejný název" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "chybnÄ› utvoÅ™ená posloupnost \\P nebo \\p" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "neznámý název vlastnosti po \\P Äi \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "název podÅ™azeného vzorku je příliÅ¡ dlouhý (maximem je 32 znaků)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "příliÅ¡ mnoho nazvaných podÅ™azených vzorků (maximem je 10 000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "osmiÄková hodnota je vÄ›tší než \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "pÅ™eteÄení pÅ™ijímaných informací pÅ™ekládaného pracovního prostoru" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "v pÅ™edchozím kroku kontrolovaný odkazovaný podÅ™azený vzorek nenalezen" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "skupina DEFINE obsahuje více než jednu vÄ›tev" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "nesluÄitelné volby NEWLINE" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"po \\g nenásleduje název nebo Äíslo ve složené nebo lomené závorce nebo v " +"uvozovkách, nebo nenulové Äíslo" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "Äíslovaná reference nesmí být nula" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "argument není povolen u (*ACCEPT), (*FAIL) nebo (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) nerozpoznáno" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "Äíslo je příliÅ¡ velké" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "schází název podÅ™azeného vzorku po (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "oÄekáváno Äíslo za (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] je neplatný datový znak v režimu kompatibility JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "rozdílné názvy podÅ™azených vzorků stejného Äísla nejsou povoleny" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) musí mít argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "po \\c nesmí následovat znak ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"po \\k nenásleduje název ve složené nebo lomné závorce nebo v uvozovkách" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N není podporováno ve třídÄ›" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "příliÅ¡ mnoho dopÅ™edných referencí" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "název je příliÅ¡ dlouhý v (*MARK), (*PRUNE), (*SKIP) nebo (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "znaková hodnota v posloupnosti \\u.... je příliÅ¡ vysoká" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Chyba pÅ™i porovnávání regulárního výrazu %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Knihovna PCRE byla pÅ™eložena bez podpory UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Knihovna PCRE byla pÅ™eložena bez podpory vlastností UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Knihovna PCRE je pÅ™eložena s nekompatibilními volbami" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Chyba pÅ™i optimalizaci regulárního výrazu %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Chyba pÅ™i kompilaci regulárního výrazu %s na znaku %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "oÄekávána Å¡estnáctková Äíslice nebo „}“" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "oÄekávána Å¡estnáctková Äíslice" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "v symbolickém odkazu chybí „<“" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "neukonÄený symbolický odkaz" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "symbolický odkaz o nulové délce" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "oÄekávána Äíslice" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "nedovolený symbolický odkaz" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "osamocené koncové „\\“" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "neznámá úniková sekvence" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Chyba pÅ™i zpracování náhradního textu „%s“ na znaku %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Text v uvozovkách nezaÄíná uvozovkami" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Nenalezena uzavírací uvozovka v příkazovém řádku nebo jiném uvozeném textu" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Text skonÄil právÄ› za znakem „\\“. (Text znÄ›l „%s“)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Text skonÄil pÅ™ed nalezením odpovídajících uvozovek znakem %c. (Text znÄ›l " +"„%s“)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Text je prázdný (nebo obsahuje pouze mezery)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Nelze Äíst data z procesu potomka (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "NeoÄekávaná chyba pÅ™i Ätení dat z procesu potomka (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NeoÄekávaná chyba v waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Proces potomka skonÄil s kódem %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Proces potomka byl zabit signálem %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Proces potomka byl zastaven signálem %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Proces potomka neskonÄil normálnÄ›" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Selhalo Ätení z roury potomka (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Selhalo zplození procesu potomka „%s“ (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Selhalo rozvÄ›tvení procesu (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Selhal pÅ™echod do složky „%s“ (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Selhalo spuÅ¡tÄ›ní procesu potomka „%s“ (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Selhalo otevÅ™ení souboru pro pÅ™emapování popisovaÄe souboru (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Selhalo zduplikování popisovaÄe souboru pro proces potomka (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Selhalo rozvÄ›tvení procesu potomka (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Selhalo zavÅ™ení popisovaÄe souboru pro proces potomka (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Neznámá chyba pÅ™i bÄ›hu procesu potomka „%s“" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "NezdaÅ™ilo se pÅ™eÄíst dostatek dat z roury pid potomka (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Selhalo Ätení dat z procesu potomka" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Selhalo spuÅ¡tÄ›ní procesu potomka (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Selhala funkce dup() v procesu potomka (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Neplatný název programu: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Neplatný Å™etÄ›zec v poli argumentů na %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Neplatný Å™etÄ›zec v prostÅ™edí: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Neplatná aktuální složka: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Nelze spustit pomocný program (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"NeoÄekávaná chyba v g_io_channel_win32_poll() pÅ™i Ätení dat z procesu potomka" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Prázdný Å™etÄ›zec není Äíslo" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s“ není Äíslo se znaménkem" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Číslo „%s“ je mimo meze [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s“ není Äíslo bez znaménka" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Neplatné kódování pomocí % v adrese URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Neplatný znak v adrese URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Znak mimo standard UTF-8 v adrese URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Neplatná adresa IPv6 „%.*s“ v adrese URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Neplatná zakódovaná adresa IP „%.*s“ v adrese URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Neplatná internacionalizace názvu hostitele „%.*s“ v adrese URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "NezdaÅ™ilo se zpracovat port „%.*s“ v adrese URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Port „%.*s“ v adrese URI je mimo rozsah" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "Adresa URI „%s“ není absolutní" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "Adresa URI „%s“ nemá Äást s hostitelem" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "Adresa URI není absolutní a není poskytnuta žádná základní URI" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Schází „=“ a hodnota parametru" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Nelze alokovat paměť" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Znak je mimo rozsah UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Neplatná posloupnost na vstupu pÅ™evodu" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Znak je mimo rozsah UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajt" +msgstr[1] "%u bajty" +msgstr[2] "%u bajtů" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bity" +msgstr[2] "%u bitů" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bajt" +msgstr[1] "%s bajty" +msgstr[2] "%s bajtů" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bity" +msgstr[2] "%s bitů" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" diff --git a/po/cy.po b/po/cy.po new file mode 100644 index 0000000..78c233b --- /dev/null +++ b/po/cy.po @@ -0,0 +1,3850 @@ +# glib yn Gymraeg. +# This file is distributed under the same license as the libgnome package. +# Kyfieithu (http://www.kyfieithu.co.uk), 2003. +# Dafydd Harries , 2003 2004. +# Rhys Jones , 2003-2006. +# Iestyn Pryce , 2009. +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2009-12-21 14:56+0100\n" +"Last-Translator: Iestyn Pryce \n" +"Language-Team: Welsh \n" +"Language: cy\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==2) ? 1 : 0;\n" +"X-Generator: Virtaal 0.5.0\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Priodwedd annisgwyl '%s' i'r elfen '%s'" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Priodwedd '%s' o elfen '%s' heb ei chanfod" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Tag annisgwyl '%s'; disgwyliwyd y tag '%s'" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Tag annisgwyl '%s' o fewn '%s'" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "Ni ddarganfuwyd ffeil llyfrnodau ddilys yn y plygell data" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Llyfrnod ar gyfer yr URI '%s' yn bodoli eisoes" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Dim llyfrnod wedi ei ganfod ar gyfer yr URI '%s'" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Dim math MIME wedi'i ddiffinio yn y llyfrnod ar gyfer yr URI '%s'" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Dim baner breifat wedi'i diffinio yn y llyfrnod ar gyfer yr URI '%s'" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Dim grwpiau wedi'u gosod yn y llyfrnod ar gyfer yr URI '%s'" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "Does dim un rhaglen o'r enw '%s' wedi cofrestru llyfrnod ar gyfer '%s'" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Methwyd darllen y cyswllt symbolaidd '%s': %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Ni chynhelir trawsnewidiad o set nodau '%s' i '%s'" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Methwyd agor trawsnewidydd rhwng '%s' a '%s'" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Dilyniant beit annilys ym mewnbwn trawsnewid" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Gwall wrth drawsnewid: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Dilyniant nod rhannol ar ddiwedd y mewnbwn" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Methu trawsnewid '%s' wrth gefn i'r set godau '%s'" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "Nid yw'r LAU '%s' yn LAU absoliwt yn y cynllun \"file\"" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "Ni chaniateir i'r LAU ffeil lleol '%s' gynnwys '#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "Mae'r LAU '%s' yn annilys" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Mae'r enw gwesteiwr yn y LAU '%s' yn annilys" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "Mae'r LAU '%s' yn cynnwys nodau wedi eu dianc mewn modd annilys" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Nid yw'r llwybr '%s' yn llwybr gosodedig" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Enw gwesteiwr annilys" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "Dydd %A %d mis %B %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%l:%M:%S %P %Z" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Ionawr" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Chwefror" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Mawrth" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "Ebrill" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Mai" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Mehefin" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Gorffennaf" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Ion" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Chw" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Maw" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Ebr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Meh" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Gor" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Llun" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Mawrth" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Mercher" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Iau" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Gwener" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sadwrn" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Sul" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Llu" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Maw" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mer" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Iau" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Gwe" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sad" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Sul" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Gwall y cyfeiriadur '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Methwyd canfod %lu beit er mwyn darllen y ffeil \"%s\"" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Mae'r ffeil \"%s\" yn rhy fawr" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Methwyd darllen o'r ffeil '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Methwyd agor y ffeil '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Methwyd darllen agweddau ffeil '%s': methiant fstat(): %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Methwyd agor y ffeil '%s': methiant yn fdopen(): %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Methwyd ail-enwi'r ffeil'%s' i '%s': methodd g_rename(): %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Methwyd creu'r ffeil '%s': %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Methu agor y ffeil '%s' er mwyn ysgrifennu iddi: methodd fdopen(): %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Methwyd ysgrifennu i'r ffeil '%s': methodd fwrite(): %s" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Methwyd ysgrifennu i'r ffeil '%s': methodd fflush(): %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Methwyd ysgrifennu i'r ffeil '%s': methodd fsync(): %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Methwyd cau'r ffeil '%s': methodd fclose(): %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "Methu tynnu'r ffeil '%s' oedd eisoes yn bodoli: methodd g_unlink(): %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Mae'r patrymlun '%s' yn annilys: ni ddylai gynnwys '%s'" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Nid yw'r patrymlun '%s' yn cynnwys XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u beit" +msgstr[1] "%u beit" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f EB" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, fuzzy, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%u beit" +msgstr[1] "%u beit" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Methwyd darllen y cyswllt symbolaidd '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Ni chynhelir cysylltion symbolaidd" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Methwyd agor trawsnewidydd o '%s' i '%s': %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Methu gwneud darlleniad crau yn g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Data dros ben heb ei drawsnewid yn y byffer ddarllen" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Mae'r sianel yn gorffen a nod rhannol" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Methu gwneud darlleniad crai yn g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Methwyd agor y ffeil '%s': methodd open(): %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Methwyd mapio'r ffeil '%s': methodd mmap(): %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Gwall ar linell %d golofn %d: " + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Testun annilys wedi ei amgodio fel UTF-8 yn yr enw - '%s' annilys" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "dydy '%s' ddim yn enw dilys" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "dydy '%s' ddim yn enw dilys: '%c'" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Gwall ar linell %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Methwyd adnabod '%-.*s', a ddylai fod yn ddigid o fewn cyfeiriant nod " +"(ê er enghraifft) - hwyrach fod y digid yn rhy fawr" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Ni orffennwyd cyfeiriant nod gyda hanner-colon - mwy na thebyg y defnyddiwyd " +"ampersand heb fwriadu dechrau endid - dylid defnyddio & yn lle" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Nid yw'r cyfeiriant nod '%-.*s' yn amgodio nod a ganiateir" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Gwelwyd endid gwag '&;'; mae & " < > a ' yn endidau dilys" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Mae'r enw endid '%-.*s' yn anhysbys" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Ni orffennwyd yr endid gyda hanner-colon - mwy na thebyg y defnyddiwyd " +"ampersand heb fwriadu dechrau endid - dylid defnyddio & yn lle" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Rhaid i'r ddogfen ddechrau gydag elfen (e.e. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"Nid yw '%s' yn nod dilys yn dilyn '<'; nid yw'n gallu dechrau enw elfen" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "Nod od '%s', disgwyliwyd nod '>' er mwyn gorffen y tag elfen wag '%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Nod od '%s', disgwyliwyd '=' ar ôl yr enw priodoledd '%s' o'r elfen '%s'" + +# c-format +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Nod od '%s', disgwyliwyd '>' neu '/' er mwyn gorffen tag dechrau'r elfen " +"'%s', neu briodoledd ddewisol; efallai defnyddiwyd nod annilys mewn enw " +"priodoledd" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Nod od '%s', disgwyliwyd dyfynnod agored ar ôl y '=' wrth roi gwerth i'r " +"priodoledd '%s' o'r elfen '%s'" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"Nid yw '%s' yn nod ddilys yn dilyn y nodau '" +msgstr "" +"Gorffennodd y ddogfen yn annisgwyl, disgwyliwyd ongl-fraced caeedig i " +"ddiweddu'r tag <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Gorffennodd y ddogfen yn annisgwyl y tu fewn i enw elfen" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Gorffennodd y ddogfen yn annisgwyl y tu fewn i enw priodoledd" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Gorffennodd y ddogfen yn annisgwyl y tu fewn i dag agor elfen" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Gorffennodd y ddogfen yn annisgwyl ar ôl yr hafalnod yn dilyn enw " +"priodoledd; dim gwerth priodoledd" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Gorffennodd y ddogfen yn annisgwyl y tu fewn i werth priodoledd" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Gorffennodd y ddogfen yn annisgwyl y tu fewn i dag cau'r elfen '%s'" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Gorffennodd y ddogfen yn annisgwyl y tu fewn i sylw neu gyfarwyddiad brosesu" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "gwrthrych wedi'i lygru" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "gwall mewnol neu gwrthrych wedi'i lygru" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "allan o gof" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "wedi cyrraedd terfan cilio" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "mae'r patrwm yn cynnwys eitemau na chynhelir ar gyfer cydweddu rhannol" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "gwall mewnol" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"dydy cyfeiriadau yn ôl fel amodau heb cynhaliaeth ar gyfer cydweddu rhannol" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "wedi cyrraedd cyfyngiad ymgylchu" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "gwall anhysbys" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ ar diwedd patrwm" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c ar ddiwedd patrwm" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "mae nod anhysbys yn dilyn \\" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "] terfynol ar goll ar gyfer y dosbarth nod" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "Dilyniant beit annilys ym mewnbwn trawsnewid" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "dim byd i ailadrodd" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "nod anhysbys ar ôl (?" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "nod anhysbys ar ôl (?<" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "nod anhysbys ar ôl (?P" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" +"Mae dosbarthiadau POSIX a enwyd yn cael eu cefnogi o fewn dosbarth yn unig" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr ") terfynol ar goll" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") heb ( agoriadol" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr ") ar goll ar ôl sylw" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "mynegiad rheolaidd yn rhy fawr" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "wedi methu cael cof" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "enw dosbarth POSIX anhysbys" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Ni chynhelir cysylltion symbolaidd" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "gall yr alwad aliadroddus ailadrodd heb derfyn" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "gwerth octal yn fwy na \\377" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "mae'r grŵp DEFINE yn cynnwys mwy nag un cangen" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "ni chaniateir ailadrodd grŵp DEFINE" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "ailadroddiad anisgwyl" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "gorlif côd" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Gwall tra'n gweddu y mynegiad cyffredinol %s: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Mae'r llyfrgell PCRE wedi'i grynhoi heb cymorth UTF8" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Mae'r llyfrgell PCRE wedi'i grynhoi heb cymorth rhinweddau UTF8" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Gwall tra'n crynhoi'r mynegiad cyffredinol %s ar golofn %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "yn disgwyl digid hex neu '}'" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "yn disgwyl digid hex" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "Cyfeiriant endid heb ei orffen" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "disgwyl digid" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Nid yw'r testun dyfynedig yn dechrau gyda dyfynnod" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Dyfynnod heb ei gydweddu mewn llinell orchymyn neu destun arall wedi ei " +"gragen-ddyfynnu" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Gorffennodd y testun ar ôl '\\'. ('%s' oedd y testun.)" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"Gorffennodd y testun cyn y darganfuwyd dyfynnod i gydweddu %c. ('%s' oedd y " +"testun.)" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Roedd y testun yn wag, neu'n cynnwys gofodnodau'n unig" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Methwyd darllen data o broses plentyn" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Methwyd creu pibell er mwyn cyfathrebu â phroses plentyn (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Methwyd darllen o bibell plentyn (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Methwyd newid i'r cyfeiriadur '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Methwyd gweithredu proses plentyn (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Enw rhaglen annilys: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Arg ar goll yn y fector argiau yn %d: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Llinyn annilys yn yr amgylchedd: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Cyfeiriadur gweithio annilys: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Methwyd gweithredu proses cymorth (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Gwall annisgwyl yn g_io_channel_win32_poll() wrth ddarllen data o broses " +"plentyn" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Methwyd darllen data o broses plentyn (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Gwall annisgwyl yn select() wrth ddarllen o broses plentyn (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Gwall annisgwyl yn waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Methwyd fforcio (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Methwyd gweithredu proses plentyn \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Methwyd ailgyrchu mewnbwn neu allbwn proses blentyn (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Methwyd fforcio proses plentyn (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Gwall anhysbys wrth weithredu proses blentyn \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Methwyd darllen digon o ddata o bibell plentyn (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Nod y tu allan i ystod ddilys UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Dilyniant annilys ym mewnbwn trawsnewidiad" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Nod y tu allan i ystod ddilys UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Defnydd:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPSIWN...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Cymorth Opsiynau:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Dangos opsiynau cymorth" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Dangos bob opsiwn cymorth" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Opsiynau Rhaglen:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Methu gramadegu'r gwerth cyfanrif '%s' ar gyfer %s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Mae'r gwerth cyfanrif '%s' ar gyfer %s y tu allan i'r cwmpas" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Methu gramadegu'r gwerth dwbl '%s' ar gyfer %s" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Mae'r gwerth dwbl '%s' ar gyfer %s y tu allan i'r cwmpas" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Gwall wrth ramadegu opsiwn %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Arg ar goll ar gyfer %s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Opsiwn anhysbys %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "Ni ddarganfuwyd ffeil allwedd ddilys yn y plygellau data" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Ddim yn ffeil cyffredin" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Ffeil yn wag" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Ffeil allwedd yn cynnwys y llinell '%s' sydd ddim yn bâr allwedd-gwerth, " +"na'n grŵp, na'n sylw" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Enw grŵp annilys: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Nid yw'r ffeil allwedd yn dechrau gyda grŵp" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Enw allwedd annilys: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Ffeil allwedd yn cynnwys yr amgodiad '%s', na gynhelir" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Nid oes gan y ffeil allwedd y grŵp '%s'" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Ffeil allwedd heb fod yn cynnwys yr allwedd '%s'" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"Ffeil allwedd yn cynnwys yr allwedd '%s' gyda'r gwerth '%s' nad yw'n UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" +"Ffeil allwedd yn cynnwys yr allwedd '%s' sydd â gwerth na ellir ei ddirnad." + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"Ffeil allwedd yn cynnwys yr allwedd '%s' sydd â gwerth na ellir ei ddirnad." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"Ffeil allwedd yn cynnwys yr allwedd '%s' yng ngrŵp '%s' sydd â gwerth na " +"ellir ei ddirnad." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Ffeil allwedd heb fod ganddi'r allwedd '%s' yn y grŵp '%s'" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Ffeil allwedd yn cynnwys nod dianc ar ddiwedd llinell" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Ffeil allwedd yn cynnwys '%s', sy'n ddilyniant dianc annilys" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Ni ellir darllen y gwerth '%s' fel rhif." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Gwerth cyfanrif '%s' y tu allan i'r ystod" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Ni ellir darllen y gwerth '%s' fel rhif arnawf." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Ni ellir darllen '%s' fel gwerth Boole." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "Mae'r llif wedi'i gau yn barod" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "Diddymwyd y weithred" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Dilyniant beit annilys ym mewnbwn trawsnewid" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Ni chynhelir cysylltion symbolaidd" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Fath anhysbys" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "math ffeil %s" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "math %s" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Gwall wrth agor ffeil '%s': %s " + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Gwall wrth ysgrifennu i ffeil: %s " + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Fath anhysbys" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Gwall y cyfeiriadur '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Gwall wrth creu plygell: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Gwall wrth agor ffeil '%s': %s " + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Gwall wrth cau ffeil': %s " + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Gwall wrth agor ffeil '%s': %s " + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Gwall wrth agor ffeil '%s': %s " + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, fuzzy, c-format +msgid "Property '%s' is not readable" +msgstr "Dydy %s heb ei ddosbarthu" + +#: ../gio/gdbusconnection.c:3959 +#, fuzzy, c-format +msgid "Property '%s' is not writable" +msgstr "Dydy %s heb ei ddosbarthu" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "Mae'r llif wedi'i gau yn barod" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, fuzzy, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "dydy '%s' ddim yn enw dilys" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Gwall wrth ysgrifennu i ffeil: %s " + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Ni chynhelir sbwriel" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Gwall wrth ysgrifennu i ffeil: %s " + +#: ../gio/gdbusserver.c:1042 +#, fuzzy, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "dydy '%s' ddim yn enw dilys" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Gwall ar linell %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Gwall wrth ramadegu opsiwn %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, fuzzy, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "dydy '%s' ddim yn enw dilys" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "dydy '%s' ddim yn enw dilys" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "dydy '%s' ddim yn enw dilys" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "dydy '%s' ddim yn enw dilys" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Gwall wrth ramadegu opsiwn %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Gwall wrth drawsnewid: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Gwall y cyfeiriadur '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "gwrthrych wedi'i lygru" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Heb enw" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "Methwyd canfod y terfynell angenrheidiol ar gyfer y rhaglen" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Methu creu ffeil penbwrdd defnyddiwr %s" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Ni chynhelir y weithred" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "Methu copïo plygell drosodd" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "Methu copïo plygell dros plygell" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "Methu copïo plygell yn ailadroddus" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Ni chynhelir cysylltion symbolaidd" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Gwall wrth agor ffeil: %s " + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "Methu copïo ffeil arbennig" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "Ni chynhelir sbwriel" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Dydy enwai ffeiliau ddim yn gallu cynnwys '%c'" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +#, fuzzy +msgid "No application is registered as handling this file" +msgstr "Does dim un rhaglen wedi cofrestru llyfrnod ar gyfer '%s'" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nifer anghywir o docynnau (%d)" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "Dim fath ar gyfer enw dosbarth %s" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "Dydy %s heb ei ddosbarthu" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Ni chynhelir sbwriel" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Enw ffeil annilys %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Gwall wrth gyrchu gwybodaeth y system ffeiliau: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "Methu ailenwi'r plygell gwraidd" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Gwall wrth ailenwi ffeil: %s " + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "Methu ailenwi ffeil, mae ffeil gyda'r enw'n bodoli'n barod" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Enw ffeil annilys" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Gwall wrth agor ffeil: %s " + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "Methu agor plygell" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Gwall wrth gwaredu ffeil: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "Gwall wrth rhoi ffeil yn y sbwriel: %s " + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Methwyd creu'r plygell sbwriel %s: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "Methu canfod na chreu plygell sbwriel" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Methwyd creu'r ffeil '%s': %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Methwyd creu ffeil sbwriel: %s" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "Gwall wrth creu plygell: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Methwyd darllen y cyswllt symbolaidd '%s': %s" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Gwall wrth creu cyswllt symbolaidd: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Gwall wrth symud ffeil: %s " + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "Methu symud plygell dros plygell" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "Gorffennodd y ddogfen yn annisgwyl y tu fewn i enw priodoledd" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Gwall y cyfeiriadur '%s': %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (amgodiad annilys)" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Gwall wrth drawsnewid: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Gwall wrth drawsnewid: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Gwall wrth drawsnewid: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Gwall wrth osod cyswllt symbolaidd: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Gwall wrth osod cyswllt symbolaidd: dydy'r ffeil ddim yn gyswllt symbolaidd" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Gwall wrth drawsnewid: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Gwall wrth drawsnewid: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Ni chynhelir cysylltion symbolaidd" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Gwall wrth ddarllen ffeil: %s " + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Gwall wrth chwilio ffeil: %s " + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Gwall wrth cau ffeil': %s " + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Gwall wrth ysgrifennu i ffeil: %s " + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Gwall wrth ramadegu opsiwn %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Gwall wrth greu copï wrth gefn: %s " + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Gwall wrth ailenwi ffeil dros dro: %s " + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "Gwall wrth talfyrru ffeil: %s " + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Gwall wrth agor ffeil '%s': %s " + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +#, fuzzy +msgid "Target file is not a regular file" +msgstr "Ddim yn ffeil cyffredin" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "Gwall wrth gwaredu hen ffeil: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Enw rhaglen annilys: %s" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Methu talfyrru GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Opsiwn anhysbys %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Methwyd creu'r ffeil '%s': %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "Methu newid modd ffeil: methodd waitpid(): %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Gwall wrth drawsnewid: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Methwyd creu'r ffeil '%s': %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Methwyd creu'r ffeil '%s': %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Dydy %s heb ei ddosbarthu" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Gwall wrth ailenwi ffeil: %s " + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "Gwall ar linell %d: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Gwall wrth ramadegu opsiwn %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Gwall wrth ramadegu opsiwn %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "Ni chynhelir cysylltion symbolaidd" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Gwall wrth ddarllen ffeil: %s " + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Gwall wrth cau ffeil': %s " + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Gwall wrth ysgrifennu i ffeil: %s " + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "allan o gof" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "gwall mewnol" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Enw gwesteiwr annilys" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Methu symud plygell dros plygell" + +#, fuzzy +#~ msgid "Key %s is not writable\n" +#~ msgstr "Dydy %s heb ei ddosbarthu" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Dilyniant annilys ym mewnbwn trawsnewidiad" + +#, fuzzy +#~ msgid "[FILE...]" +#~ msgstr "[OPSIWN...]" + +# c-format +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Mae'r nod '%s' yn annilys ar ddechrau endid; mae'r nod & yn dechrau " +#~ "endid; os nad yw'r & yma i fod yn endid, defnyddiwch & yn ei le" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "Nid yw'r nod '%s' yn ddilys o fewn enw endid" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Cyfeiriant nod gwag; dylai gynnwys digid megis dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Cyfeiriant endid heb ei orffen" + +#~ msgid "Unfinished character reference" +#~ msgstr "Cyfeiriant nod heb ei orffen" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Testun annilys wedi ei amgodio fel UTF-8" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Testun annilys wedi ei amgodio fel UTF-8" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Mae'r enw gwesteiwr yn y LAU '%s' yn annilys" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Mae'r enw gwesteiwr yn y LAU '%s' yn annilys" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Gwall wrth ddarllen ffeil '%s': %s " + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Gwall wrth ramadegu opsiwn %s" + +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Methu newid modd ffeil: methodd fork(): %s" + +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Methu newid modd ffeil: methodd chmod(): %s" + +#~ msgid "Could not change file mode: Child terminated by signal: %s" +#~ msgstr "Methu newid modd ffeil: Plentyn wedi'i derfynu gan signal: %s" + +#~ msgid "Could not change file mode: Child terminated abnormally" +#~ msgstr "Methu newid modd ffeil: Plentyn wedi'i derfynu'n anarferol" + +#~ msgid "Incorrect message size" +#~ msgstr "Maint neges anghywir" + +#~ msgid "Socket error" +#~ msgstr "Gwall soced" diff --git a/po/da.po b/po/da.po new file mode 100644 index 0000000..b373781 --- /dev/null +++ b/po/da.po @@ -0,0 +1,6333 @@ +# Danish translation for glib. +# Copyright (C) 2001-2019 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# +# Keld Simonsen , 2001. +# Kjartan Maraas , 2001. +# Ole Laursen , 2002 - 2003. +# Martin Willemoes Hansen , 2004-2005. +# Kenneth Nielsen , 2011. +# Joe Hansen , 2013. +# Ask Hjorth Larsen , 2007, 08, 09, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20. +# Alan Mortensen , 2019, 2022. +# +# Konventioner: +# +# attribute -> attribut +# header -> teksthoved +# message -> besked +# message body -> beskedtekst +# override (objektorienteret programmering) -> overskrive +# property -> egenskab +# signature -> signatur +# volume -> diskenhed (OBS. Diskuteres nu pÃ¥ listen, skal mÃ¥ske ændres) +# +# trash -> papirkurv ? +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-08 12:19+0000\n" +"PO-Revision-Date: 2022-04-18 19:18+0200\n" +"Last-Translator: Alan Mortensen \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.3\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Indstilling af standardprogrammer understøttes endnu ikke" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Indstilling af program som det sidst brugte til typen understøttes endnu ikke" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication-indstillinger" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Vis GApplication-indstillinger" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Indtast GApplication-tjenestetilstand (brug fra D-Bus-tjenestefiler)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Tilsidesæt programmets id" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Erstat den kørende instans" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Udskriv hjælp" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[KOMMANDO]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Udskriv version" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Udskriv versionsoplysninger og afslut" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Vis programmer" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Vis de installerede D-Bus-programmer som kan aktiveres (efter .desktop-filer)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Kør et program" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Kør programmet (med valgfri filer der skal Ã¥bnes)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FIL …]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktivér en handling" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Udfør en handling pÃ¥ programmet" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID HANDLING [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Vis tilgængelige handlinger" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Vis statiske handlinger for et program (fra .desktop-fil)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMMANDO" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Kommandoen, der skal vises uddybende hjælp for" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Programidentifikator i D-Bus-format (f.eks. org.eksempel.fremviser)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FIL" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Valgfri relative eller absolutte filnavne, eller URI'er der skal Ã¥bnes" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "HANDLING" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Navnet pÃ¥ handlingen, der skal køres" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Valgfri parameter til handlingen i GVariant-format" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Ukendt kommando “%sâ€\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Brug:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumenter:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARG …]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Kommandoer:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Brug “%s help KOMMANDO†for at fÃ¥ uddybende hjælp.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s-kommandoen kræver et program-id, som skal følge direkte\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "ugyldig program-id: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†tager ikke nogen argumenter\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "kan ikke forbinde til D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "fejl ved afsendelse af meddelelse %s til program: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "der skal gives et handlingsnavn efter program-id\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"ugyldigt handlingsnavn: “%sâ€\n" +"handlingsnavne kan kun bestÃ¥ af alfanumeriske tegn, “-†og “.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "fejl ved fortolkning af handlingsparameter: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "handlinger tager maksimalt en enkelt parameter\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "kommandoen list-actions tager kun program-id" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "kan ikke finde skrivebordsfil for programmet %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"ukendt kommando: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "For stor talværdi givet til %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Søgning understøttes ikke af basisstrømmen" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Kan ikke afkorte GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Strømmen er allerede lukket" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Afkortning understøttes ikke af basisstrømmen" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operationen blev afbrudt" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Ugyldigt objekt, ikke initialiseret" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Ufuldstændig flerbytesekvens i inddata" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Ikke nok plads pÃ¥ destinationen" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Ugyldig bytesekvens i konverteringsinddata" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Fejl under konvertering: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Initialisering med mulighed for afbrydelse understøttes ikke" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Konvertering fra tegnsæt “%s†til “%s†er ikke understøttet" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Kunne ikke konvertere fra “%s†til “%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s-type" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Ukendt type" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s-filtype" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials indeholder ugyldige data" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials er ikke implementeret pÃ¥ dette operativsystem" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Der er ingen understøttelse for GCredentials pÃ¥ din platform" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials indeholder ikke en proces-id pÃ¥ dette operativsystem" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Falske akkreditiver er ikke mulige pÃ¥ dette operativsystem" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Uventet tidlig strømafslutning" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Ikke-understøttet nøgle “%s†i adresseindgang “%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Meningsløst nøgle-/værdikombination i adresseindgang “%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adressen “%s†er ugyldig (kræver præcist en af nøglerne path, dir, tmpdir " +"eller abstract)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Fejl i adressen “%s†— attributten “%s†er fejlformateret" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Ukendt eller ikke-understøttet transport “%s†for adressen “%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adresseelementet “%s†indeholder intet kolon (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Transportnavn i adresseelementet “%s†mÃ¥ ikke være tomt" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Nøgle-/værdiparret %d, “%s†i adresseelementet “%s†indeholder ikke et " +"lighedstegn" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Nøgle-/værdiparret %d, “%s†i adresseelementet “%s†mÃ¥ ikke have en tom nøgle" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Fejl ved af-undvigelse af nøgle eller værdi i nøgle-/værdiparret %d, “%s†i " +"adresseelementet “%sâ€" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Fejl i adressen “%s†— unix-transporten kræver at præcist en af nøglerne " +"“path†eller “abstract†er givet" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Fejl i adressen “%s†— værtsattributten mangler eller er fejlformateret" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Fejl i adressen “%s†— portattributten mangler eller er fejlformateret" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Fejl i adressen “%s†— noncefile-attributten mangler eller er fejlformateret" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Fejl ved automatisk opstart: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Fejl ved Ã¥bning af “nonceâ€-filen “%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Fejl ved læsning af “nonceâ€-filen “%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Fejl ved læsning af “nonceâ€-filen “%sâ€. Forventede 16 byte, fandt %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Fejl under skrivning af indhold af “nonceâ€-filen “%s†til strømmen:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Den givne adresse er tom" + +# nÃ¥ ja, det er ikke grimmere pÃ¥ dansk end pÃ¥ engelsk +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Kan ikke starte en meddelelsesbus, nÃ¥r AT_SECURE er indstillet" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Kan ikke starte en meddelelsesbus uden maskine-id: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Kan ikke køre D-Bus automatisk uden $DISPLAY til X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Fejl ved kørsel af kommandolinjen “%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Kan ikke bestemme sessionsbussens adresse (ikke implementeret for dette " +"operativsystem)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Kan ikke bestemme busadressen fra miljøvariablen DBUS_STARTER_BUS_TYPE — " +"ukendt værdi “%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Kan ikke bestemme busadressen, da miljøvariablen DBUS_STARTER_BUS_TYPE ikke " +"er angivet" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Ukendt bustype %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Uventet mangel pÃ¥ indhold ved forsøg pÃ¥ at læse en linje" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Uventet mangel pÃ¥ indhold ved forsøg pÃ¥ (sikkert) at læse en linje" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Forsøgte alle tilgængelige godkendelsesmekanismer (forsøgt: %s) " +"(tilgængelige: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Bruger-id'er skal være de samme for peer og server" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Annulleret via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Fejl ved indhentning af oplysninger for mappen “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Rettigheder for mappen “%s†er fejlformateret. Forventede tilstanden 0700, " +"fandt 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Fejl ved oprettelse af mappen “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operationen understøttes ikke" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Fejl ved Ã¥bning af nøgleringen “%s†til læsning: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Linje %d i nøgleringen pÃ¥ “%s†med indholdet “%s†er fejlformateret" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Første symbol i linje %d af nøgleringen pÃ¥ “%s†med indholdet “%s†er " +"fejlformateret" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Andet symbol i linje %d af nøgleringen pÃ¥ “%s†med indholdet “%s†er " +"fejlformateret" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Fandt ingen cookie med id %d i nøgleringen pÃ¥ “%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Fejl ved oprettelse af lÃ¥sefil “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Fejl ved sletning af forældet lÃ¥sefil “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Fejl ved lukning af lÃ¥sefil (uden link) “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Fejl ved fjernelse af link til lÃ¥sefil “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Fejl ved Ã¥bning af nøgleringen “%s†til skrivning: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Yderligere kunne lÃ¥sen for “%s†ikke opgives: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Forbindelsen er lukket" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Tiden løb ud" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Der blev fundet ikke-understøttede flag ved oprettelse af en forbindelse pÃ¥ " +"klientsiden" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Ingen grænseflade “org.freedesktop.DBus.Properties†pÃ¥ objekt ved stien %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Ingen sÃ¥dan egenskab “%sâ€" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Egenskaben “%s†kan ikke læses" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Egenskaben “%s†er skrivebeskyttet" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Fejl ved anvendelse af egenskaben “%sâ€: Forventede typen “%sâ€, men fik “%sâ€" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Ingen sÃ¥dan grænseflade “%sâ€" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Ingen sÃ¥dan grænseflade “%s†pÃ¥ objektet ved stien %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Ingen sÃ¥dan metode “%sâ€" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Beskedtypen “%s†er ikke den forventede type, “%sâ€" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Der er allerede eksporteret et objekt for grænsefladen %s pÃ¥ %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Kan ikke hente egenskaben %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Kan ikke sætte egenskaben %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metoden “%s†returnerede typen “%sâ€, men forventede “%sâ€" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metoden “%s†pÃ¥ grænsefladen “%s†med signatur “%s†findes ikke" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Der er allerede eksporteret et undertræ for %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Objektet findes ikke ved stien “%sâ€" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "typen er INVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" +"Meddelelse for METHOD_CALL: Et af teksthovederne PATH eller MEMBER mangler" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Meddelelse for METHOD_RETURN: Teksthovedet REPLY_SERIAL mangler" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "FEJLmeddelelse: Teksthovedet REPLY_SERIAL eller ERROR_NAME mangler" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNALmeddelelse: Teksthovedet PATH, INTERFACE eller MEMBER mangler" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNALmeddelelse: Teksthovedet PATH bruger den reserverede værdi /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNALbesked: Teksthovedet INTERFACE bruger den reserverede værdi org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Ville læse %lu byte men fik kun %lu" +msgstr[1] "Ville læse %lu byte men fik kun %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Forventede NUL-byte efter strengen “%sâ€, men fandt byte %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Forventede gyldig UTF-8-streng, men fandt ugyldige byte ved afsæt %d " +"(strengens længde er %d). Den gyldige UTF-8-streng indtil dette punkt var " +"“%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Værdien er for dybt indlejret" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Den fortolkede værdi “%s†er ikke en gyldig objektsti til D-Bus" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Fortolket værdi “%s†er ikke en gyldig D-Bus-signatur" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Stødte pÃ¥ et array med længde %u byte. Den maksimale længde er 2<<26 byte " +"(64 MiB)." +msgstr[1] "" +"Stødte pÃ¥ et array med længde %u byte. Den maksimale længde er 2<<26 byte " +"(64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Stødte pÃ¥ et array af typen “a%câ€, som ventes at have en længde som er et " +"multiplum af %u byte, men som havde længde %u byte" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Tomme strukturer (tupler) er ikke tilladte i D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Fortolket værdi “%s†for variant er ikke en gyldig D-Bus-signatur" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Fejl ved deserialisering af GVariant med type-streng “%s†fra D-Bus-wire-" +"formatet" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Ugyldigt værdi for byterækkefølge (endianness). Forventede 0x6c (“lâ€) eller " +"0x42 (“Bâ€), men fandt værdien 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Ugyldig hovedprotokolversion. Forventede 1 men fandt %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Signaturteksthoved fundet, men er ikke af typen signatur" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Signaturteksthoved med signaturen “%s†fundet, men beskedteksten er tom" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Fortolket værdi “%s†er ikke en gyldig D-Bus-signatur (for tekst)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Intet signaturteksthoved i beskeden, men beskedteksten er %u byte" +msgstr[1] "Intet signaturteksthoved i beskeden, men beskedteksten er %u byte" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Kan ikke deserialisere besked: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Fejl ved serialisering af GVariant med typestreng “%s†til D-Bus-wire-" +"formatet" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Antal fildeskriptorer i meddelelsen (%d) er forskelligt fra teksthovedet (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Kan ikke serialisere besked: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Beskedteksten har signatur “%sâ€, men der er intet signaturteksthoved" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Beskedteksten har typesignatur “%sâ€, men signaturen i teksthovedet er “%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Beskedteksten er tom, men signaturen i teksthovedet er “(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Fejlagtig returværdi med beskedtekst af typen “%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Fejlagtig returværdi - tom beskedtekst" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Tryk pÃ¥ en tast for at lukke dette vindue)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Sessions-dbus kører ikke, og autostart mislykkedes" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Kan ikke hente hardwareprofil: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Kan ikke indlæse %s eller %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Fejl ved kald til StartServiceByName for %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Uventet svar %d fra metoden StartServiceByName(“%sâ€)" + +# Ved ikke helt hvad proxy dækker over her +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Kan ikke kalde metode; proxy er for et velkendt navn %s uden ejer, og proxy " +"blev konstrueret med flaget G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstrakt navnerum understøttes ikke" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Kan ikke angive “nonceâ€-fil ved oprettelse af server" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Fejl ved skrivning af “nonceâ€-fil i “%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Strengen “%s†er ikke en gyldig D-Bus-GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Kan ikke lytte pÃ¥ ikke-understøttet transport “%sâ€" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Kommandoer:\n" +" help Viser denne information\n" +" introspect Introspicér et fjernobjekt\n" +" monitor OvervÃ¥g et fjernobjekt\n" +" call Kald en metode pÃ¥ et fjernobjekt\n" +" emit Udsend et signal\n" +" wait Vent pÃ¥ at et busnavn fremkommer\n" +"\n" +"Brug “%s KOMMANDO --help†for at fÃ¥ hjælp om hver kommando.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Fejl: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Fejl ved fortolkning af XML til introspektion: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Fejl: %s er ikke et gyldigt navn\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Fejl: “%s†er ikke en gyldig objektsti\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Forbind til systembussen" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Forbind til sessionsbussen" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Forbind til den givne D-Bus-adresse" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Tilvalg for forbindelsesslutpunkt:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Tilvalg, der angiver forbindelsens slutpunkt" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Intet slutpunkt for forbindelsen angivet" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Flere slutpunkter for forbindelsen angivet" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Advarsel: Grænsefladen “%s†findes ikke ifølge introspektionsdata\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Advarsel: Metoden “%s†findes ikke i grænsefladen “%s†ifølge " +"introspektionsdata\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Valgfri destination for signal (unikt navn)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Objektsti, der skal udsendes et signal fra" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Signal- og grænsefladenavn" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Udsend et signal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Fejl ved forbindelse: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Fejl: “%s†er ikke et gyldigt unikt busnavn.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Fejl: Objektstien er ikke angivet\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Fejl: Signalnavnet er ikke angivet\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Fejl: Signalnavnet “%s†er ugyldigt\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Fejl: “%s†er ikke et gyldigt grænsefladenavn\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Fejl: “%s†er ikke et gyldigt medlemsnavn\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Fejl ved fortolkning af parameter %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Fejl ved tømning (flush) af forbindelse: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Destinationsnavnet, som metoden skal kaldes pÃ¥" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Objektstien, som metoden skal kaldes pÃ¥" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Metode- og grænsefladenavn" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Tidsudløb i sekunder" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Tillad interaktiv godkendelse" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Kald en metode pÃ¥ et fjernobjekt." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Fejl: Destinationen er ikke angivet\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Fejl: %s er ikke et gyldigt busnavn\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Fejl: Metodenavnet er ikke angivet\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Fejl: Metodenavnet “%s†er ugyldigt\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Fejl ved fortolkning af parameter %d af typen “%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Fejl ved tilføjelse af hÃ¥ndtag: %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Destinationsnavnet, der skal introspiceres" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Objektstien, der skal introspiceres" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Udskriv XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Foretag introspektion af underelementer" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Vis kun egenskaber" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspicér et fjernobjekt." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Navn pÃ¥ destination, der skal overvÃ¥ges" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Objektsti, der skal overvÃ¥ges" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "OvervÃ¥g et fjernobjekt." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Fejl: Kan ikke overvÃ¥ge en ikke-meddelelsesbus-forbindelse\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Tjeneste som skal aktiveres, før den anden afventes (velkendt navn)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Ventetid før afslutning med fejl (sekunder); 0 for ingen tidsgrænse " +"(standard)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[TILVALG …] BUSNAVN" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Vent pÃ¥ at et busnavn fremkommer." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Fejl: Der skal angives en tjeneste at aktivere for.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Fejl: Der skal angives en tjeneste at vente pÃ¥.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Fejl: For mange argumenter.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Fejl: %s er ikke et gyldigt velkendt busnavn.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Ikke godkendt til at ændre fejlsøgningsindstillinger" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Unavngivet" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Skrivebordsfil angav intet Exec-felt" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Kan ikke finde terminal krævet af dette program" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Kan ikke oprette konfigurationsfolder %s for brugerprogram: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Kan ikke oprette bruger-MIME-konfigurationsfolder %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Programinformation mangler en identifikator" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Kan ikke oprette brugerskrivebords-fil %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Tilpasset definition for %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "drevet implementerer ikke eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "drevet implementerer ikke eject eller eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "drevet implementerer ikke forespørgsel om medier" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "drevet implementerer ikke start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "drevet implementerer ikke stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS-motor implementerer ikke hentning af TLS-bindinger" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS-understøttelse er ikke tilgængelig" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS-understøttelse er ikke tilgængelig" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Kan ikke hÃ¥ndtere version %d af GEmblem-kodning" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Forkert antal symboler (%d) i GEmblem-kodning" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Kan ikke hÃ¥ndtere version %d af GEmblemIcon-kodning" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Forkert antal symboler (%d) i GEmblemedIcon-kodning" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Forventede et GEmblem til GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Indeholdende montering findes ikke" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Kan ikke kopiere over mappe" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Kan ikke kopiere mappe over mappe" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "MÃ¥lfilen findes" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Kan ikke kopiere mappe rekursivt" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Splejsning understøttes ikke" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Fejl ved splejsning af fil: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopiering (reflink/klon) mellem monteringer understøttes ikke" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopiering (reflink/klon) er ikke understøttet eller ugyldigt" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopiering (reflink/klon) er ikke understøttet eller virkede ikke" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Kan ikke kopiere specialfil" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Ugyldig værdi givet for symlink" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Symbolske links er ikke understøttet" + +# I koden er det en funktion der hedder g_file_trash, som kan give dette som en fejlmeddelelse +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Flyt til papirkurv understøttes ikke" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Filnavne mÃ¥ ikke indeholder “%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "diskenheden implementerer ikke montering" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Intet program er registreret til hÃ¥ndtering af denne fil" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Optæller er lukket" + +# udviklerkommentar ved tilsvarende streng andetsteds i filen forklarer dette +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Filoptæller arbejder stadig" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Filoptæller er allerede lukket" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Kan ikke hÃ¥ndtere version %d af GFileIcon-kodning" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Fejlformateret inddata til GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Strømmen understøtter ikke query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Søgning understøttes ikke pÃ¥ strømmen" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Afkortning tillades ikke for inputstrømmen" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Afkortning understøttes ikke pÃ¥ strømmen" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Ugyldigt værtsnavn" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Ugyldigt HTTP-proxysvar" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP-proxyforbindelse ikke tilladt" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP-proxygodkendelse mislykkedes" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP-proxygodkendelse pÃ¥krævet" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Fejl i HTTP-proxyforbindelsen: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP-proxysvaret er for stort" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP-proxyserveren lukkede uventet forbindelsen." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Forkert antal tegn (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Ingen type til klassenavn %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Typen %s implementerer ikke GIcon-grænsefladen" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Typen %s har ingen klasse" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Fejlformateret versionsnummer %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" +"Typen %s implementerer ikke from_tokens(), som er del af GIcon-grænsefladen" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Kan ikke hÃ¥ndtere den givne version af ikonkodningen" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Ingen adresse angivet" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Længden %u er for stor til adressen" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adressen har bit sat ud over præfikslængden" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Kunne ikke fortolke “%s†som en IP-adresse-maske" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Utilstrækkelig plads til sokkeladresse" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Sokkeladresse understøttes ikke" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Inputstrøm implementerer ikke læsning" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Strøm arbejder stadig" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopiér med fil" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Behold med fil ved flytning" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†tager ikke nogen argumenter" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Brug:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Udskriv versionsoplysninger og afslut." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Kommandoer:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Sammenkæd filer til standardoutput" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopiér en eller flere filer" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Vis oplysninger om steder" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Start et program fra en skrivebordsfil" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Vis indholdet af steder" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Hent eller sæt hÃ¥ndtering til en mimetype" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Opret mapper" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "OvervÃ¥g ændringer af filer og mapper" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montér eller afmontér stederne" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Flyt en eller flere filer" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Ã…bn filer med standardprogrammet" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Omdøb en fil" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Slet en eller flere filer" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Læs fra standardinput og gem" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Sæt en filattribut" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Flyt filer eller mapper til papirkurv" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Viser indholdet af stederne i et træ" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Brug %s for at fÃ¥ uddybende hjælp.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Fejl under skrivning til stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "STED" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Sammenkæd filer og udskriv til standardoutput." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat virker som det traditionelle cat-værktøj, men bruger GIO-steder i\n" +"stedet for lokale filer. For eksempel kan du bruge noget i stil med\n" +"smb://server/ressource/fil.txt som sted." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Ingen steder givet" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ingen mÃ¥lmappe" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Vis fremgang" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Spørg før overskrivning" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Behold alle attributter" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Sikkerhedskopiér eksisterende destinationsfiler" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Følg aldrig symbolske links" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Brug standardrettigheder for destinationen" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Overførte %s ud af %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "KILDE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINATION" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopiér en eller flere filer fra KILDE til DESTINATION." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy virker som det traditionelle cp-værktøj, men bruger GIO-steder i\n" +"stedet for lokale filer. For eksempel kan du bruge noget i stil med\n" +"smb://server/ressource/fil.txt som sted." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Destinationen %s er ikke en mappe" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: overskriv “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Vis attributter som kan ændres" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Hent filsysteminfo" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Attributterne som skal hentes" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTTER" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Følg ikke symbolske links" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "attributter:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "visningsnavn: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "redigeringsnavn: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "navn: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "type: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "størrelse: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "skjult\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "lokal sti: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix-montering: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Attributter som kan ændres:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Navnerum for attributter som kan ændres:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Vis oplysninger om steder." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info virker som det traditionelle ls-værktøj, men bruger GIO-steder i\n" +"stedet for lokale filer. For eksempel kan du bruge noget i stil med\n" +"smb://server/ressource/fil.txt som sted. Filattributter kan angives ved " +"deres\n" +"GIO-navn sÃ¥som standard::icon, eller blot ved navnerum som f.eks. unix, " +"eller\n" +"ved '*', som matcher alle attributter" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "SKRIVEBORDSFIL [FILARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Start et program fra en skrivebordsfil og giv valgfri filnavnsargumenter til " +"det." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Ingen skrivebordsfil givet" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Startkommandoen understøttes ikke pÃ¥ denne platform i øjeblikket" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Kan ikke indlæse “%sâ€: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Kan ikke indlæse programinformation for “%sâ€" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Kan ikke starte programmet “%sâ€: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Vis skjulte filer" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Brug langt listeformat" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Vis skærmnavne" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Vis fulde URI'er" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Vis stedernes indhold." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list virker som det traditionelle ls-værktøj, men bruger GIO-steder i\n" +"stedet for lokale filer. For eksempel kan du bruge noget i stil med\n" +"smb://server/ressource/fil.txt som sted. Filattributter kan angives ved " +"deres\n" +"GIO-navn sÃ¥som standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "HÃ…NDTERING" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Hent eller sæt hÃ¥ndteringen for en mimetype." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Hvis der ikke er givet nogen hÃ¥ndtering, sÃ¥ vis registrerede og anbefalede\n" +"programmer til mimetypen. Hvis der er givet en hÃ¥ndtering, angives den som\n" +"standardhÃ¥ndtering for mimetypen." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Der skal angives en mimetype, og eventuelt en hÃ¥ndtering" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Ingen standardprogrammer for “%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Standardprogram for “%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registrerede programmer:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Ingen registrerede programmer\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Anbefalede programmer:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Ingen anbefalede programmer\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Kunne ikke indlæse info for hÃ¥ndteringen “%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Kunne ikke angive “%s†som standardhÃ¥ndtering for “%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Opret ophavsmapper" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Opret mapper." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir virker som det traditionelle mkdir-værktøj, men bruger GIO-steder\n" +"i stedet for lokale filer. For eksempel kan du bruge noget i stil med\n" +"smb://server/ressource/mappe som sted." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "OvervÃ¥g en mappe (som standard: afhænger af type)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "OvervÃ¥g en fil (som standard: afhænger af type)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"OvervÃ¥g en fil direkte (opdager ændringer som foretages gennem hÃ¥rde links)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "OvervÃ¥ger en fil direkte, men rapporterer ikke ændringer" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "Rapportér flytning og omdøbning som simple opret/slet-begivenheder" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "OvervÃ¥g monteringsbegivenheder" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "OvervÃ¥g ændringer af filer eller mapper." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Montér som monterbar" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Montér diskenhed med enhedsfil eller anden id" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "Id" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Afmontér" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Skub ud" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Stop drev med enhedsfil" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ENHED" + +# Ikke sikker jf. nedenfor +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Afmontér alle monteringer med et givent skema" + +# Ikke sikker pÃ¥ denne +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SKEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Ignorér afventende filoperationer ved afmontering eller nÃ¥r der skubbes ud" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Brug en anonym bruger ved godkendelse" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Vis" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "OvervÃ¥g hændelser" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Vis yderligere oplysninger" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Den numeriske PIN ved oplÃ¥sning af en VeraCrypt-diskenhed" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montér en skjult TCRYPT-diskenhed" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montér en TCRYPT-systemdiskenhed" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonym adgang nægtet" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Intet drev for enhedsfilen" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Ingen diskenhed for givent id" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montér eller afmontér stederne." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Brug ikke kopiering og sletning som nødplan" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Flyt en eller flere filer fra KILDE til DEST." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move virker som det traditionelle mv-værktøj, men bruger GIO-steder i\n" +"stedet for lokale filer. For eksempel kan du bruge noget i stil med\n" +"smb://server/ressource/fil.txt som sted" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "MÃ¥let %s er ikke en mappe" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Ã…bn filer med standardprogrammet, som er\n" +"registreret til at hÃ¥ndtere denne filtype." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignorér filer som ikke eksisterer, og spørg ikke" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Slet de givne filer." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAVN" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Omdøb en fil." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Mangler argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "For mange argumenter" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Omdøbning fuldført. Ny uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Opret kun hvis den ikke findes" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Tilføj sidst i filen" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Ved oprettelse, sÃ¥ begræns adgang til nuværende bruger" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Ved erstatning, sÃ¥ erstat som hvis destinationen ikke fandtes" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Skriv nyt etag til sidst" + +# Etag skrives med stort senere (pÃ¥ engelsk), sÃ¥ vi behandler det som et ord +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Etag for filen, som overskrives" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Fejl ved læsning fra standardinput" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag er ikke tilgængeligt\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Læs fra standardinput og gem til DEST." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Ingen destination givet" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Type af attribut" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATTRIBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VÆRDI" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Sæt en filattribut for STED." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Sted ikke angivet" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Attribut ikke angivet" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Værdi ikke angivet" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Ugyldig attributtype “%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Tøm papirkurven" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Vis filerne i papirkurven med deres oprindelige placeringer" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Genskab en fil fra papirkurven til sin oprindelige placering (hvorved mappen " +"muligvis genoprettes)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Kan ikke finde oprindelige sti" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Kan ikke genoprette oprindelig placering: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Kan ikke flytte filen til sin oprindelige placering: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Flyt/genskab filer eller mapper til papirkurven." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Bemærk: til kontakten --restore, hvis den oprindelige placering af filen i " +"papirkurven allerede findes \n" +", sÃ¥ overskrives den ikke medmindre --force er angivet." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Den angivne placering begynder ikke med trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Følg symbolske links, monteringer og genveje" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Vis indhold af mapper i et træagtigt format." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elementet <%s> er ikke tilladt inden i <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elementet <%s> er ikke tilladt pÃ¥ topniveau" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Filen %s findes flere steder i ressourcen" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Kunne ikke finde “%s†i nogen kildemappe" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Kunne ikke finde “%s†i det nuværende katalog" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Ukendt behandlingstilvalg “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"%s-præprocessering forespurgt, men %s er ikke angivet, og %s er ikke i PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Fejl ved læsning af filen %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Fejl ved komprimering af filen %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "der mÃ¥ ikke være tekst inden i <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Vis programversion og afslut" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Navnet pÃ¥ outputfilen" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Katalogerne hvorfra filer fra henvisninger i FIL læses (som standard det " +"nuværende katalog)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "KATALOG" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Generér output i formatet givet ved mÃ¥lets filendelse" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Generér kildeheader" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Generér kildekoden, der bruges til at linke fra ressourcefilen ind i din kode" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Generér liste af afhængigheder" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Navn pÃ¥ afhængighedsfil som skal oprettes" + +# phony er et nøgleord i make +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Inkludér falske (phony) mÃ¥l i den genererede afhængighedsfil" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Opret og registrér ikke ressource automatisk" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Eksporter ikke funktioner; erklær dem G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Indlejr ikke ressourcedata i C-filen; antag at den i stedet er linket " +"eksternt" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C-identifikatornavn, der bruges til genereret kildekode" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "MÃ¥l-C-kompileren (standard: CC-miljøvariablen)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompilér en ressourcespecifikation til en ressourcefil.\n" +"Ressourcespecifikationsfiler har filendelsen .gresource.xml,\n" +"og ressourcefilen har filendelsen .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Du skal angive præcist ét filnavn\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "kaldenavn (nick) skal være pÃ¥ mindst 2 tegn" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Ugyldig numerisk værdi" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " allerede angivet" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' allerede angivet" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "værdier til flag mÃ¥ højst have 1 bit sat" + +# value eller værdi? +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> skal indeholde mindst én " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> indgÃ¥r ikke i det givne interval" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> er ikke et gyldigt medlem af den angivne numererede type" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> indeholder en streng, som ikke tilhører den angivne flagtype" + +# oversæt choices? +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> indeholder en streng, som ikke er blandt " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " er allerede angivet for denne nøgle" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " er ikke tilladt for nøgler af typen “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "-minimum er større end maksimum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "l10n-kategori ikke understøttet: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n blev forespurgt, men intet gettext-domæne givet" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "oversættelseskontekst givet for værdi uden at l10n er slÃ¥et til" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Kunne ikke fortolke -værdi for typen “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" kan ikke angives for nøgler, der er markeret som havende en " +"nummereret type" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " er allerede givet for denne nøgle" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " er ikke tilladt for nøgler af typen “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " er allerede givet" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " skal indeholde mindst én " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " er allerede angivet for denne nøgle" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" kan kun angives for nøgler af nummereret type eller flagtype, " +"eller efter " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" givet mens “%s†allerede er medlem i nummereret type" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " givet mens allerede var givet" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " er allerede givet" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "alias-mÃ¥let “%s†er ikke en nummereret type" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "alias-mÃ¥let “%s†er ikke i " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " skal indeholde mindst én " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Tomme navne er ikke tilladt" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Ugyldigt navn “%sâ€: Navne skal begynde med et lille bogstav" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Ugyldigt navn “%sâ€: ugyldigt tegn “%câ€; kun smÃ¥ bogstaver, tal og bindestreg " +"(“-â€) er tilladt" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Ugyldigt navn “%sâ€: To bindestreger i træk (“--â€) er ikke tilladt" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Ugyldigt navn “%sâ€: Sidste tegn mÃ¥ ikke være en bindestreg (“-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Ugyldigt navn “%sâ€: maksimale længde er 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " allerede angivet" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Kan ikke føje nøgler til et “list-ofâ€-skema" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " allerede angivet" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" overskygger i ; brug " +" for at ændre værdi" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Præcist en af “typeâ€, “enum†eller “flags†skal være angivet som attribut " +"for " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (endnu) ikke defineret." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Ugyldig typestreng “%s†for GVariant" + +# override og extend bruges i forbindelse med nedarvning i forbindelse med objektorienteret programmering +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " givet, men skemaet nedarver ikke fra noget" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Ingen at overskrive" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " er allerede angivet" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " er allerede angivet" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " nedarver fra skemaet “%sâ€, som ikke findes endnu" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " er en liste for skemaet “%sâ€, som ikke findes endnu" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Kan ikke være en liste for et skema med en sti" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Kan ikke nedarve fra et skema med en sti" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" er en liste, der nedarver fra , som ikke er " +"en liste" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" nedarver fra , " +"men “%s†nedarver ikke fra “%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "En sti, hvis givet, skal starte og slutte med skrÃ¥streg" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Stien for en liste skal slutte med “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Advarsel: Skemaet “%s†har stien “%sâ€. Stier som begynder med “/apps/â€, “/" +"desktop/†eller “/system/†er forældede." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> allerede angivet" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Kun ét <%s>-element er tilladt inden i <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Elementet <%s> er ikke tilladt i topniveau" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Elementet er pÃ¥krævet i " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Der mÃ¥ ikke være tekst inden i <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Advarsel: udefineret reference til " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict blev angivet; afslutter." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Hele denne fil er blevet ignoreret." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignorerer denne fil." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Ingen sÃ¥dan nøgle “%s†i skemaet “%s†som angivet i overskrivningsfilen " +"“%sâ€; ignorerer overskrivning for denne nøgle." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Ingen sÃ¥dan nøgle “%s†i skemaet “%s†som angivet i overskrivningsfilen " +"“%sâ€, og --strict var givet; afslutter." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Kan ikke skrivebordsspecifikt overskrive den lokaliserede nøgle “%s†i " +"skemaet “%s†(overskrivelsesfil “%sâ€); ignorerer overskrivning for denne " +"nøgle." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Kan ikke skrivebordsspecifikt overskrive den lokaliserede nøgle “%s†i " +"skemaet “%s†(overskrivelsesfil “%sâ€), og --strict var givet; afslutter." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Fejl ved fortolkning af nøglen “%s†i skemaet “%s†som givet i " +"overskrivningsfilen “%sâ€: %s. Ignorerer overskrivning for denne nøgle." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Fejl ved fortolkning af nøglen “%s†i skemaet “%s†som givet i " +"overskrivningsfilen “%sâ€: %s. --strict var givet; afslutter." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Overskrivning for nøglen “%s†i skemaet “%s†i overskrivningsfilen “%s†er " +"ikke i det interval, skemaet angiver; ignorerer overskrivning for denne " +"nøgle." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Overskrivning for nøglen “%s†i skemaet “%s†i overskrivningsfilen “%s†er " +"ikke i det interval, skemaet angiver, og --strict var givet; afslutter." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Overskrivning for nøglen “%s†i skemaet “%s†i overskrivningsfilen “%s†" +"findes ikke i listen over gyldige valg; ignorerer overskrivning for denne " +"nøgle." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Overskrivning for nøglen “%s†i skemaet “%s†i overskrivningsfilen “%s†" +"findes ikke i listen over gyldige valg, og --strict var givet; afslutter." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Hvor filen gschemas.compiled skal lægges" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Afbryd ved enhver fejl i skemaer" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Skriv ikke filen gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Gennemtving ikke begrænsninger pÃ¥ nøglenavn" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompilér alle GSettings-skemafiler til et skemamellemlager.\n" +"Schemafiler skal have filendelsen .gschema.xml,\n" +"og mellemlagerfilen kaldes gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Du skal give præcist et katalognavn" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Ingen skemafiler fundet: Gør intet." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Ingen skemafiler fundet: fjernede eksisterende uddatafil." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Ugyldigt filnavn %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Fejl ved hentning af filsysteminfo for %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Indeholdende montering for filen %s blev ikke fundet" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Kan ikke omdøbe rodmappen" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Fejl ved omdøbning af filen %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Kan ikke omdøbe fil, da filnavnet allerede findes" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Ugyldigt filnavn" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Fejl ved Ã¥bning af filen %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Fejl under fjernelse af filen %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Fejl ved flytning af filen %s til papirkurv: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Kan ikke oprette papirkurvskatalog %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Kan ikke finde topniveau-katalog til papirkurv %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Papirkurv understøttes ikke pÃ¥ interne systemmonteringer" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Kan ikke finde eller oprette papirkurvskatalog %s til papirkurv %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Kan ikke oprette papirkurvs-infofil for %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Kan ikke smide filen %s ud pÃ¥ andet filsystem" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Kan ikke smide filen %s ud: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Kan ikke smide filen %s ud" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Fejl ved oprettelse af mappen %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Filsystemet understøtter ikke symbolske links" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Fejl under oprettelse af symbolsk link %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Fejl ved flytning af filen %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Kan ikke flytte mappe over mappe" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Oprettelse af sikkerhedskopi mislykkedes" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Fejl ved fjernelse af mÃ¥lfil: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Flytning mellem monteringer understøttes ikke" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Kunne ikke bestemme diskforbruget af %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Attributværdien mÃ¥ ikke være NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Ugyldig attributtype (streng forventet)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Ugyldigt udvidet attributnavn" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Fejl ved indstilling af udvidet attribut “%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (ugyldig kodning)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Fejl ved indhentning af oplysninger om filen “%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Fejl ved indhentning af oplysninger om fildeskriptor: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ugyldig attributtype (uint32 forventet)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ugyldig attributtype (uint64 forventet)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ugyldig attributtype (byte-streng forventet)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Kan ikke ændre rettigheder pÃ¥ symlinks" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Fejl ved ændring af rettigheder: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Fejl ved ændring af ejer: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "symlink mÃ¥ ikke være NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Fejl ved manipulation af symlink: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Fejl ved manipulation af symlink: filen er ikke et symlink" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Antal ekstra nanosekunder %d for UNIX-tidsstempel %lld er negativt" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Antal ekstra nanosekunder %d for UNIX-tidsstempel %lld nÃ¥r op pÃ¥ 1 sekund" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX-tidsstempel %lld passer ikke ind i 64 bit" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"UNIX-tidsstempel %lld ligger uden for intervallet, som understøttes af " +"Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Filnavnet “%s†kan ikke konverteres til UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Filen “%s†kan ikke Ã¥bnes: Windowsfejl %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Fejl ved ændring af tidspunkt for ændring eller tilgang for filen “%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Fejl ved ændring af tidspunkt for ændring eller tilgang: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux-kontekst skal være forskellig fra NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux er ikke aktiveret pÃ¥ dette system" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Fejl ved ændring af SELinux-kontekst: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Indstilling af attributten %s understøttes ikke" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Fejl ved læsning fra filen: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Fejl ved lukning af filen: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Fejl under søgning i filen: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Kan ikke finde standardmonitortype for lokal fil" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Fejl under skrivning til filen: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Fejl under fjernelse af gammelt link til sikkerhedskopi: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Fejl under oprettelse af sikkerhedskopi: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Fejl under omdøbning af midlertidig fil: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Fejl ved afkortning af filen: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Fejl ved Ã¥bning af filen “%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "MÃ¥lfilen er en mappe" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "MÃ¥lfilen er ikke en almindelig fil" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Filen blev ændret eksternt" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Fejl under fjernelse af gammel fil: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Ugyldig GSeekType angivet" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Ugyldig søgeforespørgsel" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Kan ikke afkorte GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Hukommelses-uddatastrøm kan ikke ændre størrelse" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Kunne ikke ændre størrelse for hukommelses-uddatastrøm" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Mængden af hukommelse, der kræves af skrivningen, er større end det " +"tilgængelige adresserum" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Forespurgte om søgning før begyndelse af strøm" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Forespurgte om søgning efter afslutning af strøm" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "monteringsobjekt implementerer ikke “unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "monteringsobjekt implementerer ikke “ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"monteringsobjekt implementerer ikke “unmount†eller “unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"monteringsobjekt implementerer ikke “eject†eller “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "monteringsobjekt implementerer ikke “remountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "monteringsobjekt implementerer ikke gæt pÃ¥ indholdstype" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "monteringsobjekt implementerer ikke synkrone gæt pÃ¥ indholdstype" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Værtsnavnet “%s†indeholder “[â€, men ikke “]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Netværket kan ikke nÃ¥s" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Værten kan ikke nÃ¥s" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Kunne ikke oprette netværksovervÃ¥gning: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Kunne ikke oprette netværksovervÃ¥gning: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Kunne ikke finde netværksstatus: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetværkshÃ¥ndtering kører ikke" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Versionen af NetværksHÃ¥ndtering er for gammel" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Uddatastrøm implementerer ikke write" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Summen af vektorer givet til %s er for stor" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Kildestrømmen er allerede lukket" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Fejl ved opløsning af “%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s er ikke implementeret" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Ugyldigt domæne" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Ressourcen pÃ¥ “%s†findes ikke" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Ressourcen pÃ¥ “%s†kunne ikke udpakkes" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Ressourcen i “%s†er ikke et katalog" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Inputstrømmen implementerer ikke søgning" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Vis sektioner, der indeholder ressourcer, i en elf-FIL" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Vis ressourcer\n" +"Hvis SEKTION er givet, sÃ¥ vis kun ressourcer i denne sektion\n" +"Hvis STI er givet, sÃ¥ vis kun matchende ressourcer" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FIL [STI]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEKTION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Vis ressourcer med detaljer\n" +"Hvis SEKTION er givet, sÃ¥ vis kun ressourcer i denne sektion\n" +"Hvis STI er givet, sÃ¥ vis kun matchende ressourcer\n" +"Detaljerne inkluderer sektion, størrelse og komprimering" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Udskriv en ressourcefil til stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FILSTI" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Brug:\n" +" gresource [--section SEKTION] KOMMANDO [ARG …]\n" +"\n" +"Kommandoer:\n" +" help Vis denne information\n" +" sections Vis ressourcesektioner\n" +" list Vis ressourcer\n" +" details Vis ressourcer med detaljer\n" +" extract Udskriv en ressource\n" +"\n" +"Brug “gresource help KOMMANDO†til at fÃ¥ uddybende hjælp.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Brug:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEKTION Navn pÃ¥ elf-sektion (valgfri)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMMANDO Den kommandoen der skal forklares (valgfri)\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FIL En elf-fil (et binært eller delt bibliotek)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FIL En elf-fil (et binært eller delt bibliotek)\n" +" eller en kompileret ressourcefil\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[STI]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " STI En eventuelt delvis ressourcesti (valgfri)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "STI" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " STI En ressourcesti\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Intet sÃ¥dant skema “%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Skemaet “%s†kan ikke flyttes (stien mÃ¥ ikke være angivet)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Skemaet “%s†kan flyttes (sti skal angives)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Tom sti givet.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Sti skal begynde med skrÃ¥streg (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Sti skal slutte med skrÃ¥streg (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Sti mÃ¥ ikke indeholde to skrÃ¥streger i træk (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Den givne værdi ligger uden for det gyldige interval\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Nøglen er skrivebeskyttet\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Vis de installerede (uflytbare) skemaer" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Vis de installerede flytbare skemaer" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Vis nøglerne i SKEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SKEMA[:STI]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Vis underelementerne af SKEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Vis nøgler og værdier rekursivt\n" +"Hvis intet SKEMA er angivet, vis alle nøgler\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SKEMA[:STI]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Hent værdien for NØGLE" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SKEMA[:STI] NØGLE" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Forespørg om det gyldige interval af værdier for NØGLE" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Forespørg om beskrivelsen af NØGLE" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Sæt værdien af NØGLE til VÆRDI" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SKEMA[:STI] NØGLE VÆRDI" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Nulstil NØGLE til dens standardværdi" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Nulstil alle nøgler i SKEMA til deres standardværdier" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Se om NØGLE er skrivbar" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"OvervÃ¥g ændringer af NØGLE.\n" +"Hvis ingen NØGLE er givet, overvÃ¥ges alle nøgler i SKEMA.\n" +"Brug ^C for at standse overvÃ¥gning.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SKEMA[:STI] [NØGLE]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Brug:\n" +" gsettings --version\n" +" gsettings [--schemadir SKEMAKAT] KOMMANDO [ARG …]\n" +"\n" +"Kommandoer:\n" +" help Vis denne information\n" +" list-schemas Vis installerede skemaer\n" +" list-relocatable-schemas Vis flytbare skemaer\n" +" list-keys Vis nøgler i et skema\n" +" list-children Vis underelementer af et skema\n" +" list-recursively Vis nøgler og værdier rekursivt\n" +" range Forespørg om interval for nøgle\n" +" describe Forespørg om beskrivelsen af en nøgle\n" +" get Hent værdi af en nøgle\n" +" set Sæt værdien af en nøgle\n" +" reset Nulstil værdien af en nøgle\n" +" reset-recursively Nulstil alle værdier i et skema\n" +" writable Se om en nøgle er skrivbar\n" +" monitor OvervÃ¥g ændringer\n" +"\n" +"Brug “gsettings help KOMMANDO†for at fÃ¥ uddybende hjælp.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Brug:\n" +" gsettings [--schemadir SKEMAKAT] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SKEMAKAT Et katalog hvor der søges efter yderligere skemaer\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SKEMA Navnet pÃ¥ skemaet\n" +" STI Stien, for flytbare skemaer\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " NØGLE Den (valgfri) nøgle inden for skemaet\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " NØGLE Nøglen inden for skemaet\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VÆRDI Værdien der skal sættes\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Kunne ikke indlæse skemaer fra %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Ingen skemaer installeret\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Tomt skemanavn givet\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Ingen sÃ¥dan nøgle “%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Ugyldig sokkel, ikke initialiseret" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Ugyldig sokkel, initialisering mislykkedes pÃ¥ grund af: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Soklen er allerede lukket" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Tidsudløb for sokkel-I/O" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "opretter GSocket fra fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Kan ikke oprette sokkel: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Der blev angivet en ukendt familie" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Der blev angivet en ukendt protokol" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Kan ikke bruge datagramoperationer pÃ¥ en ikke-datagram-sokkel." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "Kan ikke bruge datagramoperationer pÃ¥ en sokkel med angivet udløbstid." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "kunne ikke finde lokal adresse: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "kunne ikke finde fjern adresse: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "kunne ikke lytte: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Fejl ved binding til adresse %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Fejl ved deltagelse i multicastgruppe: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Fejl ved fratræden fra multicastgruppe: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Ingen understøttelse for kildespecifik multicast" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Sokkelfamilie understøttes ikke" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "kildespecifik er ikke en IPv4-adresse" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Grænsefladenavnet er for langt" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Grænseflade ikke fundet: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Ingen understøttelse for kildespecifik multicast med IPv4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Ingen understøttelse for kildespecifik multicast med IPv6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Fejl ved accept af forbindelse: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Forbinder" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Kan ikke hente verserende fejl: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Fejl ved modtagelse af data: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Fejl ved afsendelse af data: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Kan ikke nedlukke sokkel: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Fejl ved lukning af sokkel: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Venter pÃ¥ sokkelbetingelse: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Kan ikke sende meddelelse: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Meddelelsesvektorer er for store" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Fejl ved afsendelse af meddelelse: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage understøttes ikke af Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Fejl ved modtagelse af meddelelse: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Kan ikke læse sokkelakkreditiver: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials ikke implementeret pÃ¥ dette operativsystem" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Kunne ikke forbinde til proxyserver %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Kunne ikke forbinde til %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Kunne ikke forbinde: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Brug af proxy over ikke-TCP-forbindelse understøttes ikke." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proxyprotokollen “%s†understøttes ikke." + +# Relateret til ordlistens "(SMTP )listener -> *(SMTP-)modtager" +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Modtager er allerede lukket" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Tilføjede sokkel er lukket" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 understøtter ikke IPv6-adressen “%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Brugernavnet er for langt til SOCKSv4-protokollen" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Værtsnavnet “%s†er for langt til SOCKSv4-protokollen" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Serveren er ikke en SOCKSv4-proxyserver." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Forbindelsen gennem SOCKSv4-serveren blev afslÃ¥et" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Serveren er ikke en SOCKSv5-proxyserver." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5-proxyen kræver godkendelse." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 kræver en godkendelsesmetode, der ikke understøttes af GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Brugernavn eller adgangskode er for langt til SOCKSv5-protokollen." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5-godkendelse slog fejl pÃ¥ grund af forkert brugernavn og adgangskode." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Værtsnavnet “%s†er for langt til SOCKSv5-protokollen" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5-proxyserveren bruger ukendt adressetype." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Intern SOCKSv5-proxyserverfejl." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5-forbindelse tillades ikke af regelsættet." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Vært kan ikke nÃ¥s gennem SOCKSv5-server." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Netværket kan ikke nÃ¥s gennem SOCKSv5-proxy." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Forbindelsen afslÃ¥et gennem SOCKSv5-proxy." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5-proxy understøtter ikke “connectâ€-kommando." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5-proxy understøtter ikke den givne adressetype." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Ukendt SOCKSv5-proxyfejl." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Fejl under oprettelse af kommunikationskanal til underproces (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Kanaler understøttes ikke pÃ¥ denne platform" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Kan ikke hÃ¥ndtere version %d af GThemedIcon-kodningen" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Der blev ikke fundet nogen gyldige adresser" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Fejl ved baglæns opløsning af “%sâ€: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Fejl ved fortolkning af DNS-post %s: fejlformateret DNS-pakke" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Ingen DNS-post af den forespurgte type for “%sâ€" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Midlertidigt ude af stand til at opløse “%sâ€" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Fejl ved opløsning af “%sâ€" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Fejlformateret DNS-pakke" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Kunne ikke fortolke DNS-svar for “%sâ€: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Intet privat, PEM-kodet nøgle fundet" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Kan ikke dekryptere PEM-kodet privat nøgle" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Kunne ikke fortolke PEM-kodet privat nøgle" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Intet PEM-kodet certifikat fundet" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Kunne ikke fortolke PEM-kodet certifikat" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Den nuværende TLS-motor understøtter ikke PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" +"Denne GTlsBackend understøtter ikke oprettelse af PKCS #11-certifikater" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Dette er den sidste chance for at skrive adgangskoden korrekt, før din " +"adgang vil blive lÃ¥st." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Adskillige indtastede adgangskoder var forkerte og din adgang vil blive lÃ¥st " +"efter yderligere fejlslagne forsøg." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Den indtastede adgangskode er forkert." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Afsendelse af FD understøttes ikke" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Forventede én kontrolmeddelelse, men fik %d" +msgstr[1] "Forventede én kontrolmeddelelse, men fik %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Uventet type af supplerende data" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Forventede én fd, men fik %d\n" +msgstr[1] "Forventede én fd, men fik %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Modtog ugyldig fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Modtagelse af FD understøttes ikke" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Fejl ved afsendelse af akkreditiver: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Fejl ved kontrol af om SO_PASSCRED er slÃ¥et til for sokkel: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Fejl ved aktivering af SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Forventede at læse en enkelt byte for at modtage akkreditiver, men læste nul " +"byte" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Forventer ikke kontrolmeddelelse, men modtog %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Fejl ved deaktivering af SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Fejl ved læsning fra fildeskriptor: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Fejl ved lukning af fildeskriptor: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Filsystemets rod" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Fejl under skrivning til fildeskriptor: %s" + +# "[abstract unix domain]-socket address" eller "abstract [unix domain socket] address", eller en anden kombination? Vi mÃ¥ hellere bibeholde ordenes rækkefølge pÃ¥ bekostning af at ordet bliver meget langt +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Abstrakte UNIX-domænesokkeladresser understøttes ikke af dette system" + +# eject og eject_with_operation mÃ¥ være funktionskald, sÃ¥ de bør ikke oversættes (naturligvis er det ikke en særlig brugervenlig fejlmeddelelse, men det er jo udviklerne der bestemmer dette) +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "diskenheden implementerer ikke eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "diskenheden implementerer ikke eject eller eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Fejl ved læsning fra hÃ¥ndtag: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Fejl ved lukning af hÃ¥ndtag: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Fejl under skrivning til hÃ¥ndtag: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Utilstrækkelig hukommelse" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Intern fejl: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Kræver yderligere input" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Ugyldige komprimerede data" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresse, der skal lyttes pÃ¥" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignoreres af hensyn til kompatibilitet med GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Udskriv adresse" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Udskriv adresse i skaltilstand" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Kør en dbus-tjeneste" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Forkerte argumenter\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Uventet attribut “%s†for elementet “%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Attributten “%s†for elementet “%s†blev ikke fundet" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Uventet mærke “%sâ€, forventede mærket “%sâ€" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Uventet mærke “%s†inden i “%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Ugyldig dato/klokkeslæt “%s†i bogmærkefil" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Ingen gyldig bogmærkefil blev fundet i datakatalogerne" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Et bogmærke for URI'en “%s†findes allerede" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Der blev intet bogmærke fundet for URI'en “%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Ingen MIME-type er defineret i bogmærket for URI'en “%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Intet privat flag er defineret i bogmærket for URI'en “%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Ingen grupper er sat i bogmærket for URI'en “%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Intet program med navnet “%s†har registreret et bogmærke for “%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Kunne ikke udvide eksekveringslinjen “%s†med URI'en “%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Konverteringsinddata indeholder et tegn, som ikke kan repræsenteres" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Delvis tegnsekvens ved slutningen af inddata" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Kan ikke konvertere tilbagefaldet “%s†til tegnsæt “%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Indlejret NUL-byte i konverteringsinddata" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Indlejret NUL-byte i konverteringsuddata" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI'en “%s†er ikke en absolut URI, ved brug af “filâ€-metoden" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Den lokale fil-URI “%s†mÃ¥ ikke indeholde en “#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI'en “%s†er ugyldig" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Værtsnavnet for URI'en “%s†er ugyldig" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI'en “%s†indeholder ugyldigt beskyttede tegn" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Stinavnet “%s†er ikke en absolut sti" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m-%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +# Læg mærke til programmørkommentaren. Selvom vi ikke bruger AM/PM %p mÃ¥ det jo stadig være den foretrukne mÃ¥de at udtrykke 12-timers tid. +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "januar" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "februar" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "marts" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "april" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "juni" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "juli" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "august" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "september" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "oktober" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "aug" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "mandag" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "tirsdag" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "onsdag" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "torsdag" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "fredag" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "lørdag" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "søndag" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "man" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "tirs" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ons" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "tors" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "fre" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "lør" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "søn" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "januar" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "februar" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "marts" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "april" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "juni" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "juli" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "august" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "september" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "oktober" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "aug" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Fejl ved Ã¥bning af mappen “%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Kunne ikke allokere %lu byte til at læse filen “%sâ€" +msgstr[1] "Kunne ikke allokere %lu byte til at læse filen “%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Fejl ved læsning af filen “%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Filen “%s†er for stor" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Kunne ikke læse fra filen “%sâ€: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Kunne ikke Ã¥bne filen “%sâ€: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Kunne ikke læse attributter for filen “%sâ€: fstat() mislykkedes: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Kunne ikke Ã¥bne filen “%sâ€: fdopen() mislykkedes: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Kunne ikke omdøbe filen “%s†til “%sâ€: g_rename() mislykkedes: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Kunne ikke skrive filen “%sâ€: write() mislykkedes: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Kunne ikke skrive filen “%sâ€: fsync() mislykkedes: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Fejl under oprettelse af filen “%sâ€: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Den eksisterende fil “%s†kunne ikke fjernes: g_unlink() mislykkedes: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Skabelonen “%s†er ugyldig, mÃ¥ ikke indeholde en “%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Skabelonen “%s†indeholder ikke XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Kunne ikke læse den symbolske link “%sâ€: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Kunne ikke Ã¥bne konverterer fra “%s†til “%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Kan ikke foretage en rÃ¥ læsning i g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Resterende ukonverterede data i læsemellemlager" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanal afslutter med et ufuldendt tegn" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Kan ikke foretage en rÃ¥ læsning i g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Gyldig nøglefil blev ikke fundet i søgekatalogerne" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Ikke en almindelig fil" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Nøglefilen indeholder linjen “%s†hvilken ikke er et nøgle-værdi-par, en " +"gruppe eller en kommentar" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ugyldigt gruppenavn: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Nøglefilen starter ikke med en gruppe" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Ugyldigt nøglenavn: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Nøglefilen indeholder kodningen “%sâ€, der ikke understøttes" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Nøglefilen indeholder ikke gruppen “%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Nøglefilen indeholder ikke nøglen “%s†i gruppen “%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Nøglefilen indeholder nøglen “%s†med værdien “%s†der ikke er UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Nøglefilen indeholder nøglen “%sâ€, som har en værdi, der ikke kan fortolkes." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Nøglefilen indeholder nøglen “%s†i gruppen “%sâ€, som har en værdi der ikke " +"kan fortolkes." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Nøglen “%s†i gruppen “%s†har værdien “%sâ€, mens %s blev forventet" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Nøglefilen indeholder beskyttede tegn for enden af linjen" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Nøglefilen indeholder en ugyldig undvigesekvens “%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Værdien “%s†kan ikke fortolkes som et nummer." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Heltalsværdien “%s†er ikke i gyldigt interval" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Værdien “%s†kan ikke fortolkes som en float." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Værdien “%s†kan ikke fortolkes som en sandhedsværdi." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Kunne ikke læse attributter for filen “%s%s%s%sâ€: fstat() mislykkedes: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Kunne ikke kortlægge %s%s%s%s: mmap() mislykkedes: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Kunne ikke Ã¥bne filen “%sâ€: open() mislykkedes: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Fejl pÃ¥ linje %d tegn %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Ugyldig UTF-8-kodet tekst i navnet — ugyldig “%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†er ikke et gyldigt navn" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†er ikke et gyldigt navn: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Fejl pÃ¥ linje %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Fejl ved fortolkning af “%-.*s†som skulle have været et ciffer i en " +"tegnreference (ê for eksempel) — mÃ¥ske er cifret for stort" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Tegnreferencen sluttede ikke med et semikolon; du har sandsynligvis brugt et " +"og-tegn uden at det var beregnet pÃ¥ at starte en entitet — undgÃ¥ dette ved " +"at bruge & i stedet" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Tegnreferencen “%-.*s†koder ikke et tilladt tegn" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Tom entitet “&;†fundet; gyldige entiteter er: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Entitetsnavnet “%-.*s†er ukendt" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entiteten sluttede ikke med et semikolon; du har sandsynligvis brugt et og-" +"tegn uden at det var beregnet pÃ¥ at starte en entitet — dette undgÃ¥s ved at " +"bruge & i stedet" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumentet skal begynde med et element (f.eks )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%s†er ikke et gyldigt tegn efter et “<â€-tegn; det kan ikke være " +"begyndelsen pÃ¥ et elementnavn" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Mærkeligt tegn “%sâ€, forventede et “>â€-tegn for at afslutte det tomme " +"elementmærke “%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "For mange attributter i elementet “%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Mærkeligt tegn “%sâ€, forventede et “=†efter attributnavn “%s†for elementet " +"“%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Mærkeligt tegn “%sâ€, forventede tegnet “>†eller “/†for at afslutte " +"begyndelsesmærket til elementet “%s†eller alternativt en attribut; mÃ¥ske " +"brugte du et ugyldigt tegn i attributnavnet" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Mærkeligt tegn “%sâ€, forventede et Ã¥bningsanførselstegn efter lighedstegnet " +"nÃ¥r værdien for egenskaben “%s†for attributten “%s†angives" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%s†er ikke et gyldigt tegn efter det lukkende elementnavn “%sâ€; tilladt " +"tegn er “>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Element “%s†blev lukket, ingen Ã¥bne elementer nu" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Element “%s†blev lukket, men aktivt Ã¥bent element er “%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumentet var tomt eller indeholdt kun blanke tegn" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokumentet sluttede uventet lige efter en Ã¥ben vinkelparentes “<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokumentet sluttede uventet med Ã¥bne elementer — “%s†var sidste Ã¥bne element" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokumentet sluttede uventet, forventede at se en vinkelparentes for at " +"afslutte det sidste mærke <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumentet sluttede uventet inden i et elementnavn" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumentet sluttede uventet inden i et attributnavn" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumentet sluttede uventet inden i et element-Ã¥bnende mærke." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokumentet sluttede uventet efter lighedstegnet efter et attributnavn; ingen " +"attributværdi" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumentet sluttede uventet inden i en attributværdi" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokumentet sluttede uventet inden i lukningsmærket for elementet “%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Dokumentet sluttede uventet inden i lukningsmærket for et uÃ¥bnet element" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokumentet sluttede uventet inden i en kommentar eller behandlingsinstruktion" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[TILVALG …]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Tilvalg til hjælp:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Vis tilvalg for hjælp" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Vis alle tilvalg for hjælp" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Tilvalg for programmet:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Tilvalg:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Kan ikke fortolke heltalsværdien “%s†for %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Heltalsværdien “%s†for %s er ikke i gyldigt interval" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Kan ikke fortolke double-værdien “%s†for %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Double-værdien “%s†for %s er ikke i gyldigt interval" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Kunne ikke fortolke tilvalg %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Mangler argument for %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Ukendt tilvalg %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "beskadiget objekt" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "intern fejl eller beskadiget objekt" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "ikke mere ledig hukommelse" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "grænse for bagudlæsning nÃ¥et" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"mønsteret indeholder elementer der ikke understøttes i forbindelse med " +"partiel træfning" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "intern fejl" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"baglæns referencer som betingelser understøttes ikke i forbindelse med " +"partiel træfning" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "rekursionsgrænse nÃ¥et" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "ugyldig kombination af linjeskift-flag" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "ugyldig forskydning" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "kort utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "rekursiv løkke" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "ukendt fejl" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ sidst i mønster" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c sidst i mønster" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "ukendt tegn følger \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "tal er ude af rækkefølge i {}-kvantor" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "for stort tal i {}-kvantor" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "manglende afsluttende ] for tegnklasse" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "ugyldig undvigesekvens i tegnklasse" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "følgen er ikke ordnet i tegnklassen" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "intet at gentage" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "uventet gentagelse" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "ukendt tegn efter (? eller (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX-navngivne klasser understøttes kun inden i en klasse" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "manglende afsluttende )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "reference til ikke-eksisterende undermønster" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "manglende ) efter kommentar" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "regulært udtryk for stort" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "kunne ikke hente hukommelse" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") uden Ã¥bnende (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "kodeoverløb" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "ukendt tegn efter (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind-assert-erklæring har ikke fast længde" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "fejlformateret tal eller navn efter (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "betinget gruppe indeholder mere end to grene" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "assert-erklæring forventet efter (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R eller (?[+-]cifre skal efterfølges af )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "ukendt POSIX-klassenavn" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX-arrangerende elementer understøttes ikke" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "tegnværdi i \\x{…}-sekvens er for stor" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "ugyldig betingelse (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C ikke tillad i lookbehind-assert-erklæring" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "undvigesekvenserne \\L, \\l, \\N{navn}, \\U og \\u understøttes ikke" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "rekursive kald kan danne uendelig løkke" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "ukendt tegn efter (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "manglende terminator i undermønsters navn" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "to navngivne undermønstre har samme navn" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "fejlformateret \\P- eller \\p-sekvens" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "ukendt egenskabsnavn efter \\P eller \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "undermønsters navn er for langt (maksimal 32 tegn)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "for mange navngivne undermønstre (maksimalt 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "oktal værdi er større end \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "overløb kompileringsarbejdspladsen" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "tidligere kontrolleret, refereret undermønster blev ikke fundet" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE-gruppe indeholder mere end én gren" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "inkonsistente NEWLINE-indstillinger" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g følges ikke af et navn eller tal indeholdt i klammer eller " +"vinkelklammer, eller af et enkeltstÃ¥ende tal" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "en nummereret reference kan ikke være nul" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "et argument er ikke tilladt for (*ACCEPT), (*FAIL) eller (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ikke genkendt" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "tallet er for stort" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "manglende undermønsternavn efter (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "ciffer forventet efter (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] er et ugyldigt datategn i JavaScript-kompatibilitetstilstand" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "forskellige navne til undermønstre med samme nummer er ikke tilladt" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) skal have et argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c skal være efterfulgt af et ASCII-tegn" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k følges ikke af et navn indeholdt i klammer, vinkelklammer eller " +"citationstegn" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N understøttes ikke i en klasse" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "for mange fremadreferencer" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "navn er for langt i (*MARK), (*PRUNE), (*SKIP) eller (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "tegnværdi i \\u....-sekvens er for stor" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Fejl under søgning med det regulære udtryk %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE-biblioteket er kompileret uden UTF8-understøttelse" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE-biblioteket er kompileret uden understøttelse af UTF8-egenskaber" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE-biblioteket er kompileret med inkompatible indstillinger" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Fejl under optimering af det regulære udtryk %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Fejl under kompilering af det regulære udtryk %s ved tegn %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "hexadecimalt ciffer eller “}†forventet" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "hexadecimalt ciffer forventet" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "manglende “<†i symbolsk reference" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "ufærdig symbolsk reference" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "symbolsk reference med længde nul" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "ciffer forventet" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "ugyldig symbolsk reference" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "løst afsluttende “\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "ukendt undvigesekvens" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Fejl under fortolkning af erstatningstekst “%s†ved tegn %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Anført tekst begynder ikke med anførselstegn" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Uafbalanceret anførselstegn i kommandolinje eller anden skal-anført tekst" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Tekst sluttede lige efter et “\\â€-tegn. (Teksten var “%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Tekst sluttede før tilsvarende anførselstegn blev fundet for %c (teksten var " +"“%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Tekst var tom (eller indeholdt kun blanke tegn)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Fejl ved læsning af data fra underproces (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Uventet fejl ved læsning af data fra underproces (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Uventet fejl i waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Underproces afsluttede med kode %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Underproces dræbt med signal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Underproces stoppet med signal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Underproces afsluttede fejlagtigt" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Fejl under læsning fra barnedatakanal (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Fejl under kørsel af underprocessen “%s†(%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Fejl under fraspaltning af proces (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Fejl ved skift til mappen “%s†(%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Kunne ikke køre underprocessen “%s†(%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Kunne ikke Ã¥bne filen for at omtildele fildeskriptoren (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Kunne ikke duplikere fildeskriptoren for underproces (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Fejl ved fraspaltning af underproces (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Kunne ikke lukke fildeskriptoren for underproces (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Ukendt fejl under kørsel af underprocessen “%sâ€" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Kunne ikke læse tilstrækkelig mængde data fra underprocessens pid-kanal (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Fejl under læsning af data fra underproces" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Kunne ikke køre underproces (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Kunne ikke dup() i underproces (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ugyldigt programnavn: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ugyldig streng i argumentvektor pÃ¥ %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ugyldig streng i miljø: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ugyldigt arbejdskatalog: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Fejl under kørsel af hjælpeprogram (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Uventet fejl i g_io_channel_win32_poll() under læsning af data fra en " +"underproces" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Tom streng er ikke et tal" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†er ikke et tal med fortegn" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Tallet “%s†er uden for det gyldige interval [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†er ikke et tal uden fortegn" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Ugyldig %-kodning i URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Ugyldigt tegn i URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Ikke-UTF-8-tegn i URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Ugyldig IPv6-adresse “%.*s†i URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Ugyldigt kodet IP-adresse “%.*s†i URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Ugyldigt internationaliseret værtsnavn ‘%.*s’ i URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Kunne ikke fortolke port “%.*s†i URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Porten “%.*s†i URI ligger uden for gyldigt interval" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI'en “%s†er ikke en absolut URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI'en “%s†har ingen værtskomponent" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI'en er ikke absolut og der er ikke givet nogen basis-URI" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Mangler “=†og parameterværdi" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Kunne ikke allokere hukommelse" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Tegn uden for gyldigt interval for UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Ugyldig sekvens i konverteringsinddata" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Tegn uden for gyldigt interval for UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u byte" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s byte" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s byte" +msgstr[1] "%s byte" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Kan ikke indlæse /var/lib/dbus/machine-id eller /etc/machine-id: " diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..c95dcdd --- /dev/null +++ b/po/de.po @@ -0,0 +1,6473 @@ +# German glib translation. +# Copyright (C) 2001-2004, 2007 Free Software Foundation, Inc. +# +# Christian Meyer , 2001, 2002. +# Christian Neumair , 2002-2004. +# Hendrik Brandt , 2004. +# Andre Klapper , 2007, 2008. +# Philipp Kerling , 2008. +# Hendrik Richter , 2004-2009. +# Christian Kirbach , 2009, 2010, 2012. +# Tobias Endrigkeit , 2012. +# Bernd Homuth , 2015. +# Wolfgang Stöggl , 2011, 2015-2016. +# Tim Sabsch , 2019-2022. +# Mario Blättermann , 2010-2013, 2015-2018, 2020-2021. +# Philipp Kiemle , 2021-2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-05-18 14:09+0000\n" +"PO-Revision-Date: 2022-05-22 12:39+0200\n" +"Last-Translator: Tim Sabsch \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Setzen von Standardanwendungen wird noch nicht unterstützt" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Setzen einer Anwendung als »zuletzt verwendet für einen Typ« wird noch nicht " +"unterstützt" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Optionen für GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Optionen für GApplication anzeigen" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication Dienstmodus starten (aus D-Bus Dienstdateien verwenden)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Anwendungskennung überschreiben" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Laufende Instanz ersetzen" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Hilfe ausgeben" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[BEFEHL]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Version ausgeben" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Versionsinformationen anzeigen und beenden" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Anwendungen auflisten" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Die über D-Bus aktivierbaren Anwendungen auflisten (aus .desktop-Dateien)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Eine Anwendung starten" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Die Anwendung starten (mit optional zu öffnenden Dateien)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "ANWENDUNGSKENNUNG [DATEI …]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Eine Aktion starten" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Eine Aktion auf die Anwendung starten" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ANWENDUNGSKENNUNG AKTION [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Verfügbare Aktionen auflisten" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Statische Aktionen einer Anwendung auflisten (aus .desktop-Datei)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ANWENDUNGSKENNUNG" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "BEFEHL" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Der Befehl, für den eine detaillierte Hilfe ausgegeben wird" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Anwendungsbezeichnung im D-Bus-Format (z.B: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "DATEI" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Optional relative oder absolute Dateinamen oder Adressen (URIs) zum Öffnen" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "AKTION" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Der Name der aufzurufenden Aktion" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Optionaler Parameter für den Aufruf der Aktion, im GVariant-Format" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Unbekannter Befehl %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumente:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTE …]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Befehle:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Rufen Sie »%s help BEFEHL« auf, um detaillierte Hilfe zu erhalten.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Der Befehl %s erfordert eine unmittelbar folgende Anwendungskennung\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "Ungültige Anwendungskennung: »%s«\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"»%s« akzeptiert keine Argumente\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "Verbindung mit D-Bus ist nicht möglich: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "Fehler beim Senden der %s-Nachricht zur Anwendung: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "Der Aktionsname muss nach der Anwendungskennung angegeben werden\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"Ungültiger Aktionsname: »%s«\n" +"Aktionsnamen dürfen nur aus alphanumerischen Zeichen, »-« und ».« bestehen\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "Fehler bei der Verarbeitung des Aktionsparameters: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "Aktionen akzeptiert maximal einen Parameter\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "Der Befehl list-actions akzeptiert nur die Anwendungskennung" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "Die desktop-Datei für die Anwendung %s konnte nicht gefunden werden\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"Unbekannter Befehl: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Zu großer Zählwert an %s übermittelt" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Suchen im Basis-Datenstrom nicht unterstützt" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream konnte nicht abgeschnitten werden" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Datenstrom ist bereits geschlossen" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Abschneiden wird vom Basis-Datenstrom nicht unterstützt" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Vorgang wurde abgebrochen" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Ungültiges Objekt, wurde nicht initialisiert" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Ungültige Multibyte-Folge in Eingabe" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Nicht genug Platz im Ziel" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Ungültige Bytefolge in Umwandlungseingabe" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Fehler bei der Umwandlung: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Abbrechbare Initialisierung wird nicht unterstützt" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Umwandlung von Zeichensatz »%s« in »%s« wird nicht unterstützt" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Konverter von »%s« in »%s« konnte nicht geöffnet werden" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s-Typ" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Unbekannter Typ" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s-Dateityp" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials enthält ungültige Daten" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials ist in diesem Betriebssystem nicht implementiert" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Es gibt auf Ihrer Plattform keine Unterstützung für GCredentials" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials enthält in diesem Betriebssystem keine Prozesskennung" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" +"Fälschen von Anmeldedaten ist unter diesem Betriebssystem nicht möglich" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Unerwartet frühes Datenstromende" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nicht unterstützter Schlüssel »%s« im Adresseintrag »%s«" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Bedeutungsloses Schlüssel-Wert-Paar im Adresseintrag »%s«" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adresse »%s« ist ungültig (benötigt genau einen der Schlüssel path, dir, " +"tmpdir oder abstract keys)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Fehler in Adresse »%s« – Das Attribut »%s« ist nicht korrekt" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Unbekannter oder nicht unterstützter Transport »%s« für Adresse »%s«" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adresselement »%s« enthält keinen Doppelpunkt" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Der Transportname im Adresselement »%s« darf nicht leer sein" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Schlüssel-Wert-Paar %d, »%s«, in Adresselement »%s« enthält kein " +"Gleichheitszeichen" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Schlüssel-Wert-Paar %d, »%s«, in Adresselement »%s« darf keinen leeren " +"Schlüssel enthalten" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Fehler beim Entfernen von Escape-Zeichen im Schlüssel-Wert-Paar %d, »%s«, im " +"Adresselement »%s«" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Fehler in Adresse »%s« - für den Unix-Transport muss genau einer der " +"Schlüssel »path« oder »abstract« gesetzt sein" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Fehler in Adresse »%s« – Das Host-Attribut fehlt oder ist nicht korrekt" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Fehler in Adresse »%s« – Das Port-Attribut fehlt oder ist nicht korrekt" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Fehler in Adresse »%s« – Das noncefile-Attribut fehlt oder ist nicht korrekt" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Fehler beim automatischen Starten: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Fehler beim Öffnen der Nonce-Datei »%s«: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Fehler beim Lesen der Nonce-Datei »%s«: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Fehler beim Lesen der Nonce-Datei »%s«, erwartet wurden 16 Bytes, jedoch %d " +"erhalten" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Fehler beim Schreiben des Inhalts der Nonce-Datei »%s« in den Datenstrom:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Die angegebene Adresse ist leer" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Ein Nachrichtenbus kann nicht erzeugt werden, wenn AT_SECURE gesetzt ist" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Ein Nachrichtenbus kann nicht ohne eine Rechner-Kennung erzeugt werden: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "D-Bus kann nicht automatisch ohne X11 $DISPLAY gestartet werden" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Fehler beim Erzeugen der Befehlszeile »%s«: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Adresse des Sitzungsbus konnte nicht ermittelt werden (für dieses " +"Betriebssystem nicht implementiert)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Bus-Adresse konnte nicht über die Umgebungsvariable DBUS_STARTER_BUS_TYPE " +"ermittelt werden – unbekannter Wert »%s«" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Bus-Adresse konnte nicht ermittelt werden, da die Umgebungsvariable " +"DBUS_STARTER_BUS_TYPE nicht gesetzt ist" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Unbekannter Bus-Typ %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Unerwarteter Mangel an Inhalt beim Versuch, eine Zeile zu lesen" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Unerwarteter Mangel an Inhalt beim Versuch, eine Zeile (sicher) zu lesen" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Alle verfügbaren Legitimierungsmechanismen sind ausgeschöpft (%s Versuche) " +"(verfügbar: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Benutzerkennungen müssen für Server und Gegenstelle gleich sein" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Abgebrochen durch GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Fehler beim Holen der Informationen für Ordner »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Zugriffsrechte des Ordners »%s« sind inkorrekt. Erwarteter Modus ist 0700, " +"0%o wurde erhalten" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Fehler beim Erstellen des Ordners »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Vorgang wird nicht unterstützt" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Fehler beim Öffnen des Schlüsselbundes »%s« zum Lesen: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Zeile %d des Schlüsselbundes auf »%s« mit Inhalt »%s« ist inkorrekt" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Der erste Token in Zeile %d des Schlüsselbundes bei »%s« mit dem Inhalt »%s« " +"ist inkorrekt" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Der zweite Token in Zeile %d des Schlüsselbundes bei »%s« mit dem Inhalt " +"»%s« ist inkorrekt" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" +"Cookie mit Kennung %d konnte im Schlüsselbund auf »%s« nicht gefunden werden" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Fehler beim Erstellen der Sperrdatei »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Fehler beim Löschen der alten Sperrdatei »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Fehler beim Schließen der entknüpften Sperrdatei »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Fehler beim Entknüpfen der Sperrdatei »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Fehler beim Öffnen des Schlüsselbundes »%s« zum Schreiben: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Außerdem schlug das Entsperren von »%s« ebenso fehl: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Verbindung ist geschlossen" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Zeitüberschreitung wurde erreicht" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Beim Erstellen einer client-seitigen Verbindung wurden nicht unterstützte " +"Flags entdeckt" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Keine derartige Schnittstelle »org.freedesktop.DBus.Properties« des Objekts " +"im Pfad %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Keine derartige Eigenschaft »%s«" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Eigenschaft »%s« ist nicht lesbar" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Eigenschaft »%s« ist nicht schreibbar" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Fehler beim Setzen der Eigenschaft »%s«: Erwarteter Typ war »%s«, aber »%s« " +"wurde erhalten" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Keine derartige Schnittstelle »%s«" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Keine derartige Schnittstelle »%s« des Objekts im Pfad %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Keine derartige Methode »%s«" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Der Nachrichtentyp »%s« entspricht nicht dem erwarteten Typ »%s«" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Für die Schnittstelle %s auf %s wurde bereits ein Objekt exportiert" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Eigenschaft kann nicht abgefragt werden: %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Eigenschaft kann nicht gesetzt werden: %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Methode »%s« gab Typ »%s« zurück, aber »%s« wurde erwartet" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Methode »%s« in Schnittstelle »%s« mit Signatur »%s« existiert nicht" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Ein Unterbaum wurde bereits für %s exportiert" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Das Objekt existiert nicht am Pfad »%s«" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "Typ ist UNGÜLTIG" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL-Meldung: Kopfzeilenfeld PATH oder MEMBER fehlt" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN-Meldung: Kopfzeilenfeld REPLY_SERIAL fehlt" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR-Meldung: Kopfzeilenfeld REPLY_SERIAL oder ERROR_NAME fehlt" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL-Meldung: Kopfzeilenfeld PATH, INTERFACE oder MEMBER fehlt" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL-Meldung: Das Kopfzeilenfeld PATH verwendet den reservierten Wert /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL-Meldung: Das Kopfzeilenfeld INTERFACE verwendet den reservierten Wert " +"org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu Byte sollte gelesen werden, aber nur %lu erhalten" +msgstr[1] "%lu Bytes sollten gelesen werden, aber nur %lu erhalten" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"Ein NUL-Byte wurde nach der Zeichenkette »%s« erwartet, aber es wurde Byte " +"%d gefunden" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Gültige UTF-8-Zeichenkette wurde erwartet, aber ungültige Bytes an Byte-" +"Position %d gefunden (Länge der Zeichenkette ist %d). Die gültige UTF-8-" +"Zeichenkette bis zu diesem Punkt war »%s«." + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Der Wert ist zu tief verschachtelt" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Verarbeiteter Wert »%s« ist kein gültiger D-Bus-Objektpfad" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Verarbeiteter Wert »%s« ist keine gültige D-Bus-Signatur" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Array der Länge %u Byte wurde erkannt. Maximale Länge ist 2<<26 Bytes (64 " +"MiB)." +msgstr[1] "" +"Array der Länge %u Bytes wurde erkannt. Maximale Länge ist 2<<26 Bytes (64 " +"MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Es wurde ein Feld des Typs »a%c« gefunden. Erwartet wurde als Länge ein " +"Vielfaches von %u Byte, aber es waren %u Byte Länge" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Leere Strukturen (Tupel) sind in D-Bus nicht erlaubt" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Verarbeiteter Wert »%s« für Variante ist keine gültige D-Bus-Signatur" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Fehler beim Deserialisieren von GVariant mit der Typenzeichenkette »%s« aus " +"dem D-Bus Wire-Format" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Ungültiger Wert für die Speicherreihenfolge. Es wird entweder 0x6c (»l«) " +"oder 0x42 (»B«) erwartet, aber der Wert 0x%02x gefunden" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"Ungültige Version des Hauptprotokolls. Erwartet wurde 1, jedoch %d gefunden" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Signatur-Kopfzeilenfeld gefunden, ist aber nicht vom Typ Signatur" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Signatur-Kopfzeilenfeld mit Signatur »%s« gefunden, aber Nachrichtenrumpf " +"ist leer" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Verarbeiteter Wert »%s« ist keine gültige D-Bus-Signatur (für Rumpf)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Kein Signatur-Kopfzeilenfeld in der Nachricht, aber der Nachrichtenrumpf ist " +"%u Byte groß" +msgstr[1] "" +"Kein Signatur-Kopfzeilenfeld in der Nachricht, aber der Nachrichtenrumpf ist " +"%u Bytes groß" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Meldung kann nicht deserialisiert werden: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Fehler beim Deserialisieren von GVariant mit der Typenzeichenkette »%s« in " +"das D-Bus Wire-Format" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Anzahl der Dateideskriptoren in Meldung (%d) und Kopfzeilenfeld (%d) ist " +"unterschiedlich" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Meldung kann nicht serialisiert werden: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Nachrichtenrumpf hat den Signaturtyp »%s«, aber es gibt keine Signatur im " +"Kopfzeilenfeld" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Nachrichtenrumpf hat den Signaturtyp »%s«, aber die Signatur im " +"Kopfzeilenfeld ist »%s«" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"Nachrichtenrumpf ist leer, aber die Signatur im Kopfzeilenfeld ist »(%s)«" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Fehlerrückmeldung mit Inhalt des Typs »%s«" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Fehlerrückmeldung mit leerem Inhalt" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" +"(Geben Sie ein beliebiges Zeichen ein, um dieses Fenster zu schließen)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Der Sitzungs-dbus läuft nicht und automatisches Starten schlug fehl" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Hardware-Profil konnte nicht ermittelt werden: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "%s oder %s kann nicht geladen werden: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Fehler beim Aufruf von StartServiceByName für %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Unerwartete Antwort %d von der Methode StartServiceByName(»%s«)" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Die Methode kann nicht aufgerufen werden; Der Proxy ist fürden allgemein " +"bekannten Namen %s ohne Besitzer, und der Proxy wurde mit dem Flag " +"»G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START« erstellt" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstrakter Namensraum wird nicht unterstützt" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Nonce-Datei kann beim Erstellen eines Servers nicht angegeben werden" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Fehler beim Schreiben der Nonce-Datei auf »%s«: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Die Zeichenkette »%s« ist keine gültige GUID für D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "An nicht unterstützter Übertragung »%s« kann nicht gelauscht werden" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Befehle:\n" +" help zeigt diese Information an\n" +" introspect inspiziert ein entferntes Objekt\n" +" monitor überwacht ein entferntes Objekt\n" +" call ruft eine Methode für ein entferntes Objekt auf\n" +" emit gibt ein Signal aus\n" +" wait Warte, bis ein Bus-Name auftritt\n" +"\n" +"Mit »%s BEFEHL --help« erhalten Sie Hilfe zu jedem der Befehle.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Fehler: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Fehler beim Verarbeiten des XML-Codes der Inspektion: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Fehler: %s ist kein gültiger Name\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Fehler: %s ist kein gültiger Objektpfad\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Zum Systembus verbinden" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Zum Sitzungsbus verbinden" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Zur angegebenen D-Bus-Adresse verbinden" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Optionen für Gegenstelle der Verbindung:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Optionen zur Gegenstelle der Verbindung" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Keine Gegenstelle der Verbindung angegeben" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Mehrere Gegenstellen der Verbindung angegeben" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Warnung: Entsprechend den Inspektionsdaten existiert die Schnittstelle »%s« " +"nicht\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Warnung: Entsprechend den Inspektionsdaten existiert die Methode »%s« nicht " +"in der Schnittstelle »%s«\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Optionales Ziel des Signals (eindeutiger Name)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Objektpfad, auf den das Signal ausgegeben werden soll" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Signal und Schnittstellenname" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Ein Signal ausgeben." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Fehler beim Verbinden: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Fehler: %s ist kein gültiger eindeutiger Bus-Name.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Fehler: Objektpfad wurde nicht angegeben\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Fehler: Signalname wurde nicht angegeben\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Fehler: Signalname »%s« ist ungültig\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Fehler: %s ist kein gültiger Schnittstellenname\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Fehler: %s ist kein gültiger Mitgliedsname\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Fehler bei der Verarbeitung des Parameters %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Fehler beim Löschen der Verbindung: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Name des Ziels, für das die Methode aufgerufen werden soll" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Objektpfad, für den die Methode aufgerufen werden soll" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Methode und Schnittstellenname" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Zeitablauf in Sekunden" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Interaktive Legitimierung erlauben" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Eine Methode für ein entferntes Objekt aufrufen." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Fehler: Ziel wurde nicht angegeben\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Fehler: %s ist kein gültiger Bus-Name\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Fehler: Name der Methode wurde nicht angegeben\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Fehler: Name der Methode »%s« ist ungültig\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Fehler bei der Verarbeitung des Parameters %d vom Typ »%s«: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Fehler beim Hinzufügen des Handlers %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Name des Ziels der Inspektion" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Zu inspizierender Objektpfad" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "XML drucken" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Unterelemente inspizieren" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Nur Eigenschaften ausgeben" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Ein entferntes Objekt inspizieren." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Name des zu überwachenden Ziels" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Zu überwachender Objektpfad" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Ein entferntes Objekt überwachen." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"Fehler: eine Nicht-Message-Bus-Verbindung kann nicht überwacht werden\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" +"Zu aktivierender Dienst, bevor auf den anderen gewartet wird (allgemein " +"bekannter Name)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Zeitspanne, die gewartet werden soll, bis mit einer Fehlermeldung " +"abgebrochen wird (Sekunden); 0 für keine Zeitspanne (Voreinstellung)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPTION …] BUS-NAME" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Name eines Busses, auf dessen Verfügbarkeit gewartet werden soll." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "" +"Fehler: Es muss ein Dienst angegeben werden, der gestartet werden soll.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "" +"Fehler: Es muss ein Dienst angegeben werden, auf den gewartet werden soll.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Fehler: Zu viele Argumente.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Fehler: %s ist kein gültiger, bekannter Bus-Name\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Nicht berechtigt, Fehlerdiagnose-Einstellungen zu ändern" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Unbenannt" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Desktop-Datei hat kein Exec-Feld angegeben" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Für die Anwendung benötigtes Terminal konnte nicht gefunden werden" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Konfigurationsordner %s für Benutzeranwendungen konnte nicht erstellt " +"werden: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" +"MIME-Konfigurationsordner %s des Benutzers konnte nicht erstellt werden: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Den Anwendungsinformationen fehlt ein Bezeichner" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Benutzer-Desktop-Datei %s kann nicht erstellt werden" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Benutzerdefinition für %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "Laufwerk unterstützt Auswerfen nicht" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "Laufwerk unterstützt weder ein Auswerfen noch »eject_with_operation«" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "Laufwerk unterstützt Prüfen auf Datenträger nicht" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "Laufwerk unterstützt keinen Startvorgang" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "Laufwerk unterstützt keinen Stoppvorgang" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS-Backend implementiert keine TLS-Bindungs-Ermittlung" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS-Unterstützung ist nicht verfügbar" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS-Unterstützung ist nicht verfügbar" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Version %d der GEmblem-Kodierung kann nicht verarbeitet werden" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Ungültige Symbolanzahl (%d) in GEmblem-Kodierung" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Version %d der GEmblemedIcon-Kodierung kann nicht verarbeitet werden" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Ungültige Symbolanzahl (%d) in GEmblemedIcon-Kodierung" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Es wurde ein GEmblem für GEmblemedIcon erwartet" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Enthaltender Einhängepunkt existiert nicht" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Es kann nicht über den Ordner kopiert werden" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Ordner kann nicht über Ordner kopiert werden" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Zieldatei existiert" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Ordner kann nicht rekursiv kopiert werden" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Zusammenfügen wird nicht unterstützt" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Fehler beim Zusammenfügen der Datei: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopieren (reflink/clone) zwischen Einhängepunkten nicht unterstützt" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopieren (reflink/clone) wird nicht unterstützt oder ist ungültig" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" +"Kopieren (reflink/clone) wird nicht unterstützt oder funktioniert nicht" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Spezielle Datei kann nicht kopiert werden" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Ungültiger Wert für symbolische Verknüpfung angegeben" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Symbolische Verknüpfungen nicht unterstützt" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Papierkorb nicht unterstützt" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Dateinamen dürfen kein »%c« enthalten" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "Datenträger unterstützt Einhängen nicht" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Es wurde keine Anwendung gefunden, die diese Datei verarbeiten kann" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Datei-Enumerator ist geschlossen" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Datei-Enumerator hat noch einen ausstehenden Vorgang" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Datei-Enumerator ist bereits geschlossen" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Version %d der GFileIcon-Kodierung kann nicht verarbeitet werden" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Ungültige Eingangsdaten für GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Datenstrom unterstützt query_info nicht" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Suchen im Datenstrom nicht unterstützt" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Abschneiden des Eingabedatenstroms nicht erlaubt" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Abschneiden wird vom Datenstrom nicht unterstützt" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Ungültiger Rechnername" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Ungültige Antwort vom HTTP-Proxy" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Verbindung zum HTTP-Proxy nicht zugelassen" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Legitimierung am HTTP-Proxy ist fehlgeschlagen" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Legitimierung ist erforderlich am HTTP-Proxy" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Verbindung zum HTTP-Proxy ist fehlgeschlagen: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Antwort vom HTTP-Proxy ist zu groß" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP Proxy-Server hat die Verbindung unerwartet geschlossen." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Ungültige Symbolanzahl (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Kein Typ für Klassenname %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "GIcon-Schnittstelle wird vom Typ %s nicht unterstützt" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Typ %s ist keine Klasse" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Ungültige Versionsnummer: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Typ %s implementiert nicht from_tokens() der GIcon-Schnittstelle" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Übergebene Version der Symbol-Kodierung kann nicht verarbeitet werden" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Keine Adresse angegeben" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Länge %u ist zu groß für eine Adresse" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Für die Adresse sind Bits außerhalb der Präfix-Länge gesetzt" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "»%s« konnte nicht als IP-Adressmaske verarbeitet werden" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Nicht genug Platz für eine Socket-Adresse" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nicht unterstützte Socket-Adresse" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Eingabedatenstrom unterstützt kein Lesen" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Datenstrom hat noch einen ausstehenden Vorgang" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Mit Datei kopieren" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Zusammen mit Datei verschieben" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "»version« akzeptiert keine Argumente" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Aufruf:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Versionsinformationen ausgeben und beenden." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Befehle:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Dateien aneinander hängen und auf der Standardausgabe ausgeben" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Eine oder mehrere Dateien kopieren" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Informationen zu Orten anzeigen" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Anwendung mittels desktop-Datei starten" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Den Inhalt der Orte auflisten" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Anwendung für MIME-Typ ermitteln oder festlegen" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Ordner erstellen" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Dateien und Ordner auf Änderungen überwachen" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Die Orte ein- oder aushängen" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Eine oder mehrere Dateien verschieben" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Dateien mit der Standard-Anwendung öffnen" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Eine Datei umbenennen" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Eine oder mehrere Dateien löschen" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Aus der Standardeingabe lesen und speichern" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Ein Dateiattribut festlegen" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Dateien oder Ordner in den Papierkorb verschieben" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Den Inhalt der Orte in einer Baumstruktur auflisten" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Verwenden Sie »%s«, um detaillierte Hilfe zu erhalten.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Fehler beim Schreiben in die Standardausgabe" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:91 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "ORT" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Dateien aneinander hängen und auf der Standardausgabe ausgeben." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat arbeitet vergleichbar mit dem herkömmlichen cat-Programm,\n" +"jedoch werden GIO-Orte statt lokaler Dateien verwendet; z.B. können\n" +"Sie als Ort etwas wie »smb://server/ressource/datei.txt« angeben." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Keine Orte angegeben" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Kein Zielordner" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Fortschritt zeigen" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Vor Überschreiben nachfragen" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Alle Attribute übernehmen" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Vorhandene Zieldateien sichern" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Niemals symbolischen Verknüpfungen folgen" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Standardberechtigungen für das Ziel verwenden" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%s von %s übertragen (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "QUELLE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ZIEL" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Eine oder mehrere Dateien von QUELLE nach ZIEL kopieren." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy arbeitet vergleichbar mit dem herkömmlichen cp-Programm,\n" +"jedoch werden GIO-Orte statt lokaler Dateien verwendet; z.B. können\n" +"Sie als Ort etwas wie »smb://server/ressource/datei.txt« angeben." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Das Ziel »%s« ist kein Ordner" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: Soll »%s« überschrieben werden? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Schreibbare Attribute auflisten" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Informationen zum Dateisystem erhalten" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Das einzulesende Attribut" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTE" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Symbolischen Verknüpfungen nicht folgen" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "Attribute:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "Anzeigename: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "Name bearbeiten: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "Name: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "Typ: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "Größe: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "verborgen\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "Adresse: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "Lokaler Pfad: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "Unix-Einhängepunkt: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Setzbare Attribute:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Namensraum der schreibbaren Attribute:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Informationen zu Orten zeigen." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info arbeitet vergleichbar mit dem herkömmlichen ls-Programm,\n" +"jedoch werden GIO-Orte statt lokaler Dateien verwendet: Z. B. können\n" +"Sie als Ort etwas wie »smb://server/resource/Datei.txt« angeben.\n" +"Dateiattribute können anhand der GIO-Namen, z.B. »standard::icon«, oder\n" +"anhand des Namensraums, z.B. »unix«, oder durch »*« angegeben werden,\n" +"was auf alle Attribute passt" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-DATEI [DATEI-ARGUMENT …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Eine Anwendung mittels desktop-Datei starten, mit der Möglichkeit optionale " +"Dateinamen-Optionen anzugeben." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Keine desktop-Datei angegeben" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" +"Der »launch«-Befehl wird momentan nicht auf dieser Plattform unterstützt" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "»%s« kann nicht geladen werden: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Information zur Anwendung »%s« kann nicht geladen werden" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Anwendung »%s« kann nicht gestartet werden: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Verborgene Dateien zeigen" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Langes Listenformat verwenden" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Anzeigenamen ausgeben" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Volle Adressen ausgeben" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Den Inhalt der Orte auflisten." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list arbeitet vergleichbar mit dem herkömmlichen ls-Programm,\n" +"jedoch werden GIO-Orte statt lokaler Dateien verwendet; z.B. können\n" +"Sie als Ort etwas wie »smb://server/ressource/datei.txt« angeben.\n" +"Dateiattribute werden mit dem GIO-Namen angegeben, z.B. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIME-TYP" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "BEHANDLUNGSROUTINE" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Anwendung für MIME-Typ ermitteln oder festlegen." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Wenn keine Behandlungsroutine angegeben ist, werden für diesen MIME-Typ\n" +"registrierte und empfohlene Anwendungen aufgelistet. Wenn eine Behandlungs-\n" +"routine angegeben ist, wird diese als Voreinstellung für den MIME-Typ " +"gesetzt." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" +"Ein einzelner MIME-Typ und eventuell eine Behandlungsroutine müssen " +"angegeben werden" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Keine Vorgabeanwendungen für »%s«\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Standardanwendung für »%s«: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registrierte Anwendungen:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Keine registrierten Anwendungen\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Empfohlene Anwendungen:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Keine empfohlenen Anwendungen\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Information zur Anwendung »%s« kann nicht geladen werden" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "»%s« kann nicht als Vorgabeanwendung für »%s« gesetzt werden: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Elternordner erstellen" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Ordner erstellen." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir arbeitet vergleichbar mit dem herkömmlichen mkdir-Programm,\n" +"jedoch werden GIO-Orte statt lokaler Dateien verwendet; z.B. können\n" +"Sie als Ort etwas wie »smb://server/ressource/Ordner« angeben." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Einen Ordner überwachen (Vorgabe: abhängig vom Typ)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Eine Datei überwachen (Vorgabe: abhängig vom Typ)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Eine Datei direkt überwachen (erkennt über harte Verknüpfungen gemachte " +"Änderungen)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Überwacht eine Datei direkt, aber berichtet nicht über Änderungen" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Verschiebungen und Umbenennungen als einfache Lösch- oder Erzeugungsvorgänge " +"melden" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Auf Einhängevorgänge überwachen" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Dateien und Ordner auf Änderungen überwachen." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Als einhängbar einbinden" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Datenträger über Gerätedatei oder anderen Bezeichner einhängen" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "Kennung" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Aushängen" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Auswerfen" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Datenträger über Gerätedatei stoppen" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "GERÄT" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Alle Einhängepunkte passend zum Namensschema aushängen" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Ausstehende Dateioperationen ignorieren, wenn ausgehängt oder ausgeworfen " +"wird" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Nutzen Sie einen anonymen Nutzer bei der Legitimierung" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Auflisten" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Ereignisse überwachen" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Zusätzliche Informationen anzeigen" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Die numerische PIM beim Entsperren eines VeraCrypt-Datenträgers" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Einen verborgenen TCRYPT-Datenträger einhängen" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Einen TCRYPT-Systemdatenträger einhängen" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Der anonyme Zugriff wurde verwehrt" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Kein Laufwerk für Gerätedatei" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Kein Datenträger für angegebene Kennung" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Die Orte ein- oder aushängen." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ersatz für Kopieren und Löschen nicht verwenden" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Eine oder mehrere Dateien von QUELLE nach ZIEL verschieben." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move arbeitet vergleichbar mit dem herkömmlichen mv-Programm,\n" +"jedoch werden GIO-Orte statt lokaler Dateien verwendet: Z. B. können\n" +"Sie als Ort etwas wie »smb://server/resource/Datei.txt« angeben" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Das Ziel »%s« ist kein Ordner" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Dateien mit der Standard-Anwendung öffnen,\n" +"die als Programm für diesen Dateityp eingestellt ist." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Nicht vorhandene Dateien ignorieren und niemals nachfragen" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Die gegebenen Dateien löschen." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Eine Datei umbenennen." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Fehlendes Argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:139 +msgid "Too many arguments" +msgstr "Zu viele Argumente" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Umbenennung erfolgreich. Neue Adresse: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Nur erstellen, wenn nicht bereits vorhanden" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "An Dateiende anhängen" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Beim Erstellen Zugriff auf den aktuellen Benutzer beschränken" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Beim Ersetzen davon ausgehen, dass das Ziel nicht existiert" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Neuen Etag am Ende drucken" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Der Etag der Datei, die überschrieben wird" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Fehler beim Lesen von der Standardeingabe" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag ist nicht verfügbar\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Aus der Standardeingabe lesen und in ZIEL speichern." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Kein Ziel vorgegeben" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Typ des Attributs" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYP" + +#: gio/gio-tool-set.c:91 +msgid "ATTRIBUTE" +msgstr "ATTRIBUT" + +#: gio/gio-tool-set.c:91 +msgid "VALUE" +msgstr "WERT" + +#: gio/gio-tool-set.c:95 +msgid "Set a file attribute of LOCATION." +msgstr "Ein Dateiattribut von ORT festlegen." + +#: gio/gio-tool-set.c:115 +msgid "Location not specified" +msgstr "Kein Ort angegeben" + +#: gio/gio-tool-set.c:122 +msgid "Attribute not specified" +msgstr "Kein Attribut angegeben" + +#: gio/gio-tool-set.c:132 +msgid "Value not specified" +msgstr "Kein Wert angegeben" + +#: gio/gio-tool-set.c:182 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Ungültiger Attributtyp »%s«" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Den Papierkorb leeren" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Dateien im Papierkorb mit ihren ursprünglichen Orten auflisten" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Eine Datei aus dem Papierkorb am ursprünglichen Ort wiederherstellen " +"(erstellt unter Umständen wieder den Ordner)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Ursprünglicher Pfad konnte nicht gefunden werden" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Wiederherstellen des ursprünglichen Orts fehlgeschlagen: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Verschieben der Datei zum ursprünglichen Ort fehlgeschlagen: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Dateien oder Ordner in den Papierkorb verschieben/wiederherstellen." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Hinweis: Wenn der ursprüngliche Ort der gelöschten Datei bereits existiert, " +"wird er mit der Option »--restore« nicht überschrieben, außer »--force« ist " +"gesetzt." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Angegebener Ort beginnt nicht mit trash://" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" +"Symbolischen Verknüpfungen, Einhängepunkten und Schnellzugriffen folgen" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Den Inhalt von Ordnern in einer Baumstruktur auflisten." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> ist innerhalb <%s> nicht erlaubt" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> ist in der obersten Ebene nicht erlaubt" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Datei %s tritt in der Ressource mehrfach auf" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "»%s« konnte in keinem Quellordner gefunden werden" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "»%s« konnte im aktuellen Ordner nicht gefunden werden" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Unbekannte Verarbeitungsoption »%s«" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"%s-Vorverarbeitung wurde angefordert, aber %s ist nicht gesetzt und %s ist " +"nicht in PATH enthalten" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Fehler beim Lesen der Datei »%s«: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Fehler beim Komprimieren der Datei %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "Text könnte nicht innerhalb von <%s> erscheinen" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Programm-Version anzeigen und beenden" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Name der Ausgabedatei" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Die Ordner, aus denen in FILE referenzierte Dateien gelesen werden sollen " +"(Vorgabe ist der aktuelle Ordner)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "ORDNER" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Ausgabe in dem Format generieren, welches durch die Dateiendung der " +"Zieldatei vorgegeben wird" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Quellcode-Header generieren" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Quellcode zum Verlinken der Ressourcendatei in Ihren Code verwenden" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Abhängigkeitsliste generieren" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Name der zu erzeugenden Abhängigkeitsdatei" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Phony-Ziele in der erzeugten Abhängigkeitsdatei einschließen" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Die Ressource nicht automatisch anlegen und registrieren" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Keine Funktionen exportieren; als G_GNUC_INTERNAL deklarieren" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Ressourcendaten nicht in der C-Datei einbetten; stattdesssen externe " +"Verlinkung voraussetzen" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C-Bezeichnername für den generierten Quellcode" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Der Ziel-C-Compiler (Voreinstellung: die CC-Umgebungsvariable)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Eine Ressourcenspezifikation in eine Ressourcendatei kompilieren.\n" +"Ressourcenspezifikationsdateien müssen die Erweiterung .gresource.xml " +"haben,\n" +"die Ressourcendateien die Erweiterung .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Sie sollten genau einen Dateinamen angeben\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "Nick muss aus mindestens zwei Zeichen bestehen" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Ungültiger numerischer Wert" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " bereits angegeben" + +# Hier scheinen im Original die spitzen Klammern zu fehlen +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr " wurde bereits angegeben" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "Für Flag-Werte darf höchstens 1 Bit gesetzt sein" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> muss mindestens ein enthalten" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> ist im angegebenen Bereich nicht enthalten" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> ist kein gültiges Element des angegebenen Aufzählungstyps" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> enthält eine Zeichenkette, die nicht den angegebenen Flag-Typ hat" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> enthält eine Zeichenkette, die nicht in enthalten ist" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " wurde für diesen Schlüssel bereits angegeben" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ist für Schlüssel des Typs »%s« nicht erlaubt" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " angebenenes Minimum ist größer als das Maximum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "Nicht unterstützte l10n-Kategorie: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n wurde angefordert, aber keine Gettext-Domain angegeben" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" +"Übersetzungskontext wurde für den Wert angegeben, ohne dass l10n aktiviert " +"ist" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Der -Wert des Typs »%s« konnte nicht ausgewertet werden: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" kann nicht für Schlüssel angegeben werden, die als Aufzählungstyp " +"markiert sind" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " wurde für diesen Schlüssel bereits angegeben" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ist für Schlüssel des Typs »%s« nicht erlaubt" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " wurde bereits angegeben" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " muss mindestens ein enthalten" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " wurde für diesen Schlüssel bereits angegeben" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" kann nur für Schlüssel mit Aufzählungs- oder Flag-Typ oder nach " +" angebenden werden" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" wurde angegeben, wobei »%s« bereits ein Element des " +"Aufzählungstyps ist" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" wurde angegeben, während bereits " +"angegeben war" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " bereits angegeben" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "Alias-Ziel »%s« ist kein Aufzählungstyp" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "Alias-Ziel »%s« ist nicht in " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " muss mindestens einen enthalten" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Leere Namen sind nicht zulässig" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Ungültiger Name »%s«: Namen müssen mit einem Kleinbuchstaben beginnen" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Ungültiger Name »%s«: ungültiges Zeichen »%c«; nur Kleinbuchstaben, Ziffern " +"und Bindestriche »-« sind zulässig" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Ungültiger Name »%s«: Zwei aufeinander folgende Bindestriche »--« sind nicht " +"zulässig" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" +"Ungültiger Name »%s«: das letzte Zeichen darf kein Bindestrich »-« sein." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Ungültiger Name »%s«: maximale Länge ist 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " wurde bereits angegeben" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Schlüssel können nicht zum Schema »list-of« hinzugefügt werden" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " wurde bereits angegeben" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" verdeckt in ; verwenden Sie " +", um den Wert anzupassen" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Genau eines von »type«, »enum« oder »flags« muss als Attribut für " +"angegeben werden" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (noch) nicht definiert." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Ungültige GVariant-Typzeichenkette »%s«" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " angegeben, aber das Schema erweitert nichts" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Kein zum Überschreiben" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " wurde bereits angegeben" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " wurde bereits angegeben" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " erweitert noch nicht vorhandenes Schema »%s«" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" +" ist eine Liste des noch nicht vorhandenen Schemas »%s«" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Darf keine Liste von Schemata mit einem Pfad sein" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Ein Schema darf nicht um einen Pfad erweitert werden" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ist eine Liste, welche erweitert, das " +"keine Liste ist" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" erweitert , aber " +"»%s« erweitert »%s« nicht" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"Ein Pfad, falls angegeben, muss mit einem Schrägstrich beginnen und enden" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Der Pfad einer Liste muss mit »:/« enden" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Warnung: Schema »%s« hat den Pfad »%s«. Mit »/apps/«, »/desktop/« oder »/" +"system/« beginnende Pfade gelten jedoch als veraltet." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> bereits angegeben" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Nur ein <%s>-Element ist innerhalb von <%s> erlaubt" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> ist in der obersten Ebene nicht erlaubt" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Element wird in benötigt" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Text darf nicht innerhalb von <%s> erscheinen" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Warnung: nicht definierte Referenz zu " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict wurde angegeben; Abbruch." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Die gesamte Datei wurde ignoriert." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Diese Datei wird ignoriert." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Kein Schlüssel »%s« in Schema »%s« wie angegeben in überschreibender Datei " +"»%s«. Die Überschreibung wird für diesen Schlüssel ignoriert." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Kein Schlüssel »%s« in Schema »%s« wie angegeben in überschreibender Datei " +"»%s«, und »--strict« wurde angegeben. Abbruch." + +# Das habe ich nicht wirklich verstanden, bitte sorgfältig gegenlesen. +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Desktop-bezogenes Überschreiben kann für lokalisierten Schlüssel »%s« im " +"Schema »%s« (überschreibende Datei »%s«) nicht bereitgestellt werden. Die " +"Überschreibung wird für diesen Schlüssel ignoriert." + +# Das habe ich nicht wirklich verstanden, bitte sorgfältig gegenlesen. +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Desktop-bezogenes Überschreiben kann für lokalisierten Schlüssel »%s« im " +"Schema »%s« (überschreibende Datei »%s«) nicht bereitgestellt werden, und »--" +"strict« wurde angegeben. Abbruch." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Fehler beim Verarbeiten des Schlüssels »%s« in Schema »%s« wie angegeben in " +"überschreibender Datei »%s«: %s. Die Überschreibung wird für diesen " +"Schlüssel ignoriert." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Fehler beim Verarbeiten des Schlüssels »%s« in Schema »%s« wie angegeben in " +"überschreibender Datei »%s«: %s, und »--strict« wurde angegeben. Abbruch." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Überschreiben für Schlüssel »%s« in Schema »%s« in überschreibender Datei " +"»%s« liegt außerhalb des im Schema angegebenen Bereichs. Die Überschreibung " +"wird für diesen Schlüssel ignoriert." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Überschreiben für Schlüssel »%s« in Schema »%s« in überschreibender Datei " +"»%s« liegt außerhalb des im Schema angegebenen Bereichs, und »--strict« " +"wurde angegeben. Abbruch." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Überschreiben für Schlüssel »%s« in Schema »%s« in überschreibender Datei " +"»%s« befindet sich nicht in der Liste gültiger Auswahlmöglichkeiten. Die " +"Überschreibung wird für diesen Schlüssel ignoriert." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Überschreiben für Schlüssel »%s« in Schema »%s« in überschreibender Datei " +"»%s« befindet sich nicht in der Liste gültiger Auswahlmöglichkeiten, und »--" +"strict« wurde angegeben. Abbruch." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Speicherort der Datei gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Abbruch wegen einiger Fehler in Schemata" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Die Datei »gschema.compiled« nicht schreiben" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Keine Einschränkungen für Schlüsselnamen erzwingen" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Alle GSettings-Schemadateien in eine Zwischenspeicherdatei kompilieren.\n" +"Schemadateien müssen die Erweiterung .gschema.xml haben,\n" +"die Zwischenspeicherdatei die Erweiterung gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Sie sollten genau einen Ordnernamen angeben" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Keine Schema-Dateien gefunden. Es wird nichts unternommen." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Keine Schema-Dateien gefunden. Vorhandene Ausgabedatei wurde entfernt." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Ungültiger Dateiname %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Fehler beim Einlesen der Dateisystem-Information für %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Enthaltender Einhängepunkt für Datei %s wurde nicht gefunden" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Wurzelordner kann nicht umbenannt werden" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Fehler beim Umbenennen der Datei %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Datei kann nicht umbenannt werden, da der Dateiname bereits existiert" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Ungültiger Dateiname" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Fehler beim Öffnen der Datei »%s«: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Fehler beim Entfernen der Datei »%s«: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Fehler beim Verschieben der Datei %s in den Papierkorb: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Papierkorb-Ordner %s konnte nicht angelegt werden: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "" +"Oberster Ordner konnte zum Verschieben von %s in den Papierkorb nicht " +"gefunden werden" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"Papierkorbaktionen zwischen systeminternen Einhängepunkten werden nicht " +"unterstützt" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Papierkorb-Ordner %s konnte für %s nicht gefunden oder angelegt werden" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Löschprotokoll-Datei für %s konnte nicht angelegt werden: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Datei %s kann nicht über Dateisystemgrenzen hinweg in den Papierkorb " +"verschoben werden" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Datei %s kann nicht in den Papierkorb verschoben werden: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Datei %s kann nicht in den Papierkorb verschoben werden" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Fehler beim Erstellen des Ordners »%s«: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Das Dateisystem unterstützt keine symbolische Verknüpfungen" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Fehler beim Erstellen der symbolischen Verknüpfung %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Fehler beim Verschieben der Datei %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Ordner kann nicht über Ordner verschoben werden" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Erstellen der Sicherungsdatei gescheitert" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Fehler beim Entfernen der Zieldatei: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Verschieben zwischen Einhängepunkten nicht unterstützt" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Konnte die Festplattenbelegung von %s nicht bestimmen: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Attributwert darf nicht NULL sein" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Ungültiger Attributtyp (»string« erwartet)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Ungültiger erweiterter Attributname" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Fehler beim Setzen des erweiterten Attributs »%s«: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (ungültige Kodierung)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Fehler beim Holen der Informationen für Datei »%s«: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Fehler beim Holen der Informationen für Dateideskriptor: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ungültiger Attributtyp (»uint32« erwartet)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ungültiger Attributtyp (»uint64« erwartet)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ungültiger Attributtyp (»byte string« erwartet)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "" +"Zugriffsrechte für symbolische Verknüpfungen können nicht gesetzt werden" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Fehler beim Setzen der Zugriffsrechte: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Fehler beim Setzen des Besitzers: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "Symbolische Verknüpfung darf nicht NULL sein" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Fehler beim Setzen der symbolischen Verknüpfung: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Fehler beim Setzen der symbolischen Verknüpfung: Datei ist keine symbolische " +"Verknüpfung" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Zusätzliche Nanosekunden %d für UNIX-Zeitstempel %lld sind negativ" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Zusätzliche Nanosekunden %d für UNIX-Zeitstempel %lld erreichen 1 Sekunde" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX-Zeitstempel %lld passt nicht in 64 Bit" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"UNIX-Zeitstempel %lld ist außerhalb des von Windows unterstützten Bereichs" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Dateiname »%s« kann nicht nach UTF-16 konvertiert werden" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Datei »%s« kann nicht geöffnet werden: Windows-Fehler %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Fehler beim Setzen der Änderungs- oder Zugriffszeit für Datei »%s«: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Fehler beim Setzen der Zugriffsrechte oder der Zugriffszeit: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux-Kontext darf nicht NULL sein" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux ist auf diesem System nicht aktiviert" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Fehler beim Setzen des SELinux-Kontexts: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Setzen des Attributs %s nicht unterstützt" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Fehler beim Lesen aus Datei: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Fehler beim Schließen der Datei: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Fehler beim Suchen in Datei: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "" +"Vorgegebener Überwachungstyp für lokale Dateien konnte nicht gefunden werden" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Fehler beim Schreiben in Datei: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Fehler beim Entfernen der alten Sicherungsverknüpfung: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Fehler beim Erzeugen der Sicherungskopie: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Fehler beim Umbenennen der temporären Datei: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Fehler beim Abschneiden der Datei: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Fehler beim Öffnen der Datei »%s«: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Zieldatei ist ein Ordner" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Zieldatei ist keine reguläre Datei" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Die Datei wurde extern verändert" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Fehler beim Entfernen der alten Datei: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Ungültiger GSeekType übergeben" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Ungültige Suchanfrage" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream konnte nicht abgeschnitten werden" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Größe des Speicherausgabestroms ist nicht änderbar" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Größe des Speicherausgabestroms konnte nicht geändert werden" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Für den Schreibvorgang erforderliche Speichermenge ist größer als der " +"verfügbare Adressbereich" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Angeforderte Suche vor dem Beginn des Datenstroms" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Angeforderte Suche nach dem Ende des Datenstroms" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "Einhängepunkt unterstützt Aushängen nicht" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "Einhängepunkt unterstützt Auswerfen nicht" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"Einhängepunkt unterstützt nicht das Aushängen oder »unmount_with_operation«" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "Einhängepunkt unterstützt Auswerfen oder »eject_with_operation« nicht" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "Einhängepunkt unterstützt erneutes Einhängen nicht" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "Einhängepunkt unterstützt Erraten des Inhaltstyps nicht" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "Einhängepunkt unterstützt synchrones Erraten des Inhaltstyps nicht" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Rechnername »%s« enthält »[«, aber nicht »]«" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Das Netzwerk ist nicht erreichbar" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Rechner ist nicht erreichbar" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Netzwerkmonitor konnte nicht erstellt werden: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Netzwerkmonitor konnte nicht erstellt werden: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Netzwerkstatus konnte nicht ermittelt werden: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager läuft nicht" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Die Version von NetworkManager ist zu alt" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Ausgabedatenstrom unterstützt kein Schreiben" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "An %s übermittelte Vektorsumme ist zu groß" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Quelldatenstrom ist bereits geschlossen" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Fehler beim Auflösen von »%s«: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s ist nicht implementiert" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Ungültige Domain" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Die Ressource auf »%s« existiert nicht" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Die Ressource auf »%s« konnte nicht entpackt werden" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Die Ressource auf »%s« ist ein Ordner" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Eingabedatenstrom unterstützt kein Suchen" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Sektionen einer ELF-Datei auflisten, welche Ressourcen enthält" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Ressourcen auflisten\n" +"Falls SEKTION angegeben ist, nur die Ressourcen dieser Sektion auflisten\n" +"Falls PFAD angegeben ist, nur die betreffenden Ressourcen auflisten" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "DATEI [PFAD]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEKTION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Ressourcen detailliert auflisten\n" +"Falls SEKTION angegeben ist, nur die Ressourcen dieser Sektion auflisten\n" +"Falls PFAD angegeben ist, nur die betreffenden Ressourcen auflisten\n" +"Details enthalten Sektion, Größe und Kompression" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Eine Ressourcendatei in stdout auspacken" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "DATEIPFAD" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Aufruf:\n" +" gresource [--section SEKTION] BEFEHL [ARGUMENTE …]\n" +"\n" +"Befehle:\n" +" help zeigt diese Information an\n" +" sections listet Ressourcensektionen auf\n" +" list listet Ressourcen auf\n" +" details listet Ressourcen detailliert auf\n" +" extract entpackt eine Ressource\n" +"\n" +"Rufen Sie »gresource help BEFEHL« auf, um detaillierte Hilfe zu erhalten.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Aufruf:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEKTION Ein (optionaler) Name einer ELF-Sektion\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " BEFEHL Der (optionale) zu erklärende Befehl\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" DATEI Eine ELF-Datei (ein Binary oder eine gemeinsame Bibliothek)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" DATEI Eine ELF-Datei (ein Binary oder eine gemeinsame Bibliothek)\n" +" oder eine kompilierte Ressourcendatei\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[PFAD]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" +" PFAD Ein (optionaler) Ressourcenpfad (kann unvollständig sein)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "PFAD" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " PFAD Ein Ressourcenpfad\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Kein derartiges Schema »%s«\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" +"Schema »%s« ist nicht verschiebbar (Pfad darf nicht angegeben werden)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schema »%s« ist verschiebbar (Pfad muss angegeben werden)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Leerer Pfad angegeben.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Pfad muss mit einem Schrägstrich beginnen (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Pfad muss mit einem Schrägstrich enden (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" +"Pfad darf nicht zwei aufeinander folgende Schrägstriche enthalten (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Der angegebene Wert liegt außerhalb des gültigen Bereichs\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Der Schlüssel ist nicht schreibbar\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Installierte (nicht verschiebbare) Schemata auflisten" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Installierte (verschiebbare) Schemata auflisten" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Schlüssel in SCHEMA auflisten" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PFAD]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Unterelemente von SCHEMA auflisten" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Schlüssel und Werte rekursiv auflisten\n" +"Falls kein Schema angegeben, alle Schlüssel auflisten\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PFAD]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Den Wert von SCHLÜSSEL ermitteln" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PFAD] SCHLÜSSEL" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Den Bereich gültiger Werte für SCHLÜSSEL abfragen" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Die Beschreibung für SCHLÜSSEL abfragen" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Den Wert von SCHLÜSSEL auf WERT setzen" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PFAD] SCHLÜSSEL WERT" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "SCHLÜSSEL auf Vorgabewert setzen" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Alle Schlüssel in SCHEMA auf deren Vorgaben zurücksetzen" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Prüfen, ob SCHLÜSSEL schreibgeschützt ist" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"SCHLÜSSEL auf Änderungen überwachen.\n" +"Falls kein SCHLÜSSEL angegeben wird, werden alle Schlüssel\n" +"in SCHEMA überwacht.\n" +"Drücken Sie ^C, um die Überwachung zu beenden.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PFAD] [SCHLÜSSEL]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Aufruf:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMAORDNER] BEFEHL [ARGUMENTE …]\n" +"\n" +"Befehle:\n" +" help zeigt diese Information an\n" +" list-schemas listet installierte Schemata auf\n" +" list-relocatable-schemas listet verschiebbare Schemata auf\n" +" list-keys listet Schlüssel in einem Schema auf\n" +" list-children listet Unterelemente eines Schemas auf\n" +" list-recursively listet Schlüssel und Werte rekursiv auf\n" +" range fragt den Bereich eines Schlüssels ab\n" +" describe fragt die Beschreibung eines Schlüssels ab\n" +" get ermittelt den Wert eines Schlüssels\n" +" set setzt den Wert eines Schlüssels\n" +" reset setzt den Wert eines Schlüssels zurück\n" +" reset-recursively setzt die Werte aller Schlüssel eines gegebenen\n" +" Schemas zurück\n" +" writable prüft, ob der Schlüssel schreibgeschützt ist\n" +" monitor überwacht auf Änderungen\n" +"\n" +"Rufen Sie »gsettings help BEFEHL« auf, um eine detaillierte Hilfe zu " +"erhalten.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Aufruf:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR Ein Ordner zum Suchen nach zusätzlichen Schemas\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA Die Kennung des Schemas\n" +" SCHLÜSSEL Der Name des Schlüssels\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " SCHLÜSSEL Der (optionale) Schlüssel innerhalb des Schemas\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " SCHLÜSSEL Der Schlüssel innerhalb des Schemas\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " WERT Der zu setzende Wert\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Schemata von »%s« konnten nicht geladen werden: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Keine Schemata installiert\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Leerer Schema-Name wurde angegeben\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Kein derartiger Schlüssel »%s«\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Ungültiger Socket, wurde nicht initialisiert" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Ungültiger Socket, Initialisierung schlug fehl wegen: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Der Socket ist bereits geschlossen" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Zeitüberschreitung bei Ein-/Ausgabeoperation des Sockets" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "GSocket wird erstellt von Dateideskriptor: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Socket kann nicht angelegt werden: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Eine unbekannte Familie wurde angegeben" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Ein unbekanntes Protokoll wurde angegeben" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Datagramm-Operationen können nicht auf einem Nicht-Datagramm-Socket " +"ausgeführt werden." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Datagramm-Operationen können nicht auf einem Socket mit gesetzter " +"Zeitüberschreitung ausgeführt werden." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "Lokale Adresse konnte nicht gelesen werden: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "Entfernte Adresse konnte nicht gelesen werden: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "Es konnte nicht gelauscht werden: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Fehler beim Binden an Adresse %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Fehler beim Beitreten zur Multicast-Gruppe: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Fehler beim Verlassen der Multicast-Gruppe: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Quellen-spezifisches Multicast wird nicht unterstützt" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Nicht unterstützte Socket-Familie" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "Quellen-spezifisch ist keine IPv4-Adresse" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Schnittstellenname ist zu lang" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Schnittstelle nicht gefunden: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Quellen-spezifisches IPv4-Multicast wird nicht unterstützt" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Quellen-spezifisches IPv6-Multicast wird nicht unterstützt" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Fehler bei Annahme der Verbindung: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Verbindungsvorgang läuft" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Ausstehender Fehler konnte nicht erhalten werden: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Fehler beim Erhalt von Daten: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Fehler beim Senden von Daten: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Socket kann nicht heruntergefahren werden: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Fehler beim Schließen des Sockets: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Es wird auf eine Socket-Bedingung gewartet: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Nachricht konnte nicht gesendet werden: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Nachrichtenträger sind zu lang" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Fehler beim Senden der Nachricht: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage wird unter Windows nicht unterstützt" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Fehler beim Empfang der Nachricht: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Socket-Berechtigungen konnten nicht gelesen werden: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials ist für dieses Betriebssystem nicht implementiert" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Verbindung zum Proxy-Server %s konnte nicht aufgebaut werden: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Verbindung mit %s ist gescheitert: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Verbindung ist gescheitert: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Nicht-TCP-Verbindung über Proxy wird nicht unterstützt." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proxy-Protokoll »%s« wird nicht unterstützt." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Lauscher ist bereits geschlossen" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Der hinzugefügte Socket ist geschlossen" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 unterstützt die IPv6-Adresse »%s« nicht" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Benutzername ist zu lang für das SOCKSv4-Protokoll" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Rechnername »%s« ist zu lang für das SOCKSv4-Protokoll" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Der Server ist kein SOCKSv4-Proxy-Server." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Verbindung durch SOCKSv4-Server wurde abgewiesen" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Der Server ist kein SOCKSv5-Proxy-Server." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Der SOCKSv5-Proxy erfordert Legitimierung." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Der SOCKSv5 erfordert eine Legitimierungsmethode, die durch GLib nicht " +"unterstützt wird." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Benutzername oder Passwort ist zu lang für das SOCKSv5-Protokoll." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5-Legitimierung scheiterte wegen falschen Benutzernamens oder " +"Passworts." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Rechnername »%s« ist zu lang für das SOCKSv5-Protokoll" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Der SOCKSv5-Proxy-Server verwendet einen unbekannten Adresstyp." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Interner Fehler des SOCKSv5-Proxy-Servers." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5-Verbindung ist aufgrund des Regelwerks nicht erlaubt." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Rechner ist über den SOCKSv5-Server nicht erreichbar." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Das Netzwerk ist durch den SOCKSv5-Proxy nicht erreichbar." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Verbindung wurde durch SOCKSv5-Proxy abgewiesen." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5-Proxy unterstützt den Befehl »connect« nicht." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5-Proxy unterstützt den angegebenen Adresstyp nicht." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Unbekannter Fehler im SOCKSv5-Proxy." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Weiterleitung für Kommunikation mit Kindprozess (%s) konnte nicht erzeugt " +"werden" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Weiterleitungen werden auf dieser Plattform nicht unterstützt" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Version %d der GThemedIcon-Kodierung kann nicht verarbeitet werden" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Es wurden keine gültigen Adressen gefunden" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Fehler beim Rückwärtsauflösen von »%s«: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Fehler bei der Verarbeitung des DNS %s-Eintrags: ungültiges DNS-Paket" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Kein DNS-Eintrag des angeforderten Typs für »%s«" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "»%s« kann vorübergehend nicht aufgelöst werden" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Fehler beim Auflösen von »%s«" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Ungültiges DNS-Paket" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Fehler bei der Verarbeitung der DNS-Antwort zu »%s«: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Kein PEM-enkodierter geheimer Schlüssel gefunden" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-enkodierter geheimer Schlüssel konnte nicht entschlüsselt werden" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-enkodierter geheimer Schlüssel konnte nicht verarbeitet werden" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Kein PEM-enkodiertes Zertifikat gefunden" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-enkodiertes Zertifikat konnte nicht verarbeitet werden" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Das aktuelle TLS-Backend unterstützt PKCS #12 nicht" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" +"Das GTlsBackend unterstützt die Erstellung von PKCS #11-Zertifikaten nicht" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Dies ist die letzte Möglichkeit, das Passwort korrekt einzugeben, bevor Ihr " +"Zugang gesperrt wird." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Passwörter wurden mehrfach inkorrekt eingegeben, daher wird Ihr Zugriff nach " +"weiteren Fehleingaben gesperrt." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Das eingegebene Passwort ist ungültig." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Senden von FD wird nicht unterstützt" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 Kontrollnachricht wird erwartet, %d wurde erhalten" +msgstr[1] "1 Kontrollnachricht wird erwartet, %d wurden erhalten" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Unerwartete Art von Zusatzdaten" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Ein Dateideskriptor wird erwartet, aber %d wurde erhalten\n" +msgstr[1] "Ein Dateideskriptor wird erwartet, aber %d wurden erhalten\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Ungültiger Dateideskriptor wurde erhalten" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Erhalten von FD wird nicht unterstützt" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Fehler beim Senden der Anmeldedaten: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"Fehler bei der Überprüfung, ob SO_PASSCRED für Socket aktiviert ist: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Fehler beim Aktivieren von SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Erwartet wurde der Empfang eines einzelnen Bytes als Anmeldedaten, jedoch " +"null Bytes gelesen" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Kontrollnachricht wurde nicht erwartet, %d wurde erhalten" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Fehler beim Deaktivieren von SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Fehler beim Lesen aus dem Dateideskriptor: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Fehler beim Schließen des Dateideskriptors: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Wurzelordner des Dateisystems" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Fehler beim Schreiben in den Dateideskriptor: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Abstrakte Unix Domänen-Socket-Adresse wird auf diesem System nicht " +"unterstützt" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "Datenträger unterstützt Auswerfen nicht" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "Datenträger unterstützt weder Auswerfen noch »eject_with_operation«" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Fehler beim Lesen aus dem Handler: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Fehler beim Schließen des Handlers: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Fehler beim Schreiben in das Handle: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nicht genügend freier Speicher" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Interner Fehler: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Weitere Eingaben erforderlich" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Ungültige komprimierte Daten" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresse, an der gelauscht werden soll" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignoriert (für Kompatibilität mit GTestDbus)" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Adresse ausgeben" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Adresse im Shell-Modus ausgeben" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Einen D-Bus-Dienst ausführen" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Falsche Argumente\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Unerwartetes Attribut »%s« des Elements »%s«" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Attribut »%s« des Elements »%s« konnte nicht gefunden werden" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Unerwarteter Tag »%s«; Tag »%s« wird erwartet" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Unerwarteter Tag »%s« innerhalb von »%s«" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Ungültiges Datum bzw. Uhrzeit »%s« in der Lesezeichendatei" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Es wurde keine gültige Lesezeichendatei in den Datenordnern gefunden" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Es existiert bereits ein Lesezeichen für die Adresse »%s«" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Es konnte kein Lesezeichen für die Adresse »%s« gefunden werden." + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Es ist kein MIME-Typ im Lesezeichen für die Adresse »%s« definiert." + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" +"Es konnte keine »privat«-Markierung für das Lesezeichen für die Adresse »%s« " +"gefunden werden." + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "" +"Es wurden keine Gruppen für das Lesezeichen für die Adresse »%s« festgelegt." + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" +"Es wurde keine Anwendung namens »%s« gefunden, die ein Lesezeichen für »%s« " +"registriert hat." + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "" +"Die Befehlszeile »%s« konnte nicht mit der Adresse »%s« verknüpft werden." + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Nicht darstellbares Zeichen in Umwandlungsausgabe" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Bruchstückhafte Zeichenfolge am Eingabeende" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Notnagel »%s« kann nicht in Kodierung »%s« umgewandelt werden" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Eingebettetes NUL-Byte in Umwandlungseingabe" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Eingebettetes NUL-Byte in Umwandlungsausgabe" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" +"Die Adresse »%s« ist keine absolute Adresse, die das »file«-Schema verwendet" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Die lokale Adresse »%s« darf kein »#« enthalten" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Die Adresse »%s« ist ungültig" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Der Rechnername der Adresse »%s« ist ungültig" + +# CHECK +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Die Adresse »%s« enthält ungültige Escape-Zeichen" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Der Pfadname »%s« ist kein absoluter Pfad" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e. %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Januar" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Februar" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "März" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Juni" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Juli" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "August" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Oktober" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Dezember" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mär" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dez" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Montag" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Dienstag" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Mittwoch" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Donnerstag" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Freitag" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Samstag" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Sonntag" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Mo" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Di" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mi" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Do" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Fr" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sa" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "So" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Januar" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Februar" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "März" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Juni" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Juli" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "August" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Oktober" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Dezember" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mär" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Okt" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dez" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Fehler beim Öffnen des Ordners »%s«: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "%lu Byte konnte nicht zugeordnet werden, um Datei »%s« zu lesen" +msgstr[1] "%lu Bytes konnten nicht zugeordnet werden, um Datei »%s« zu lesen" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Fehler beim Lesen der Datei »%s«: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Datei »%s« ist zu groß" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Aus der Datei »%s« konnte nicht gelesen werden: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Datei »%s« konnte nicht geöffnet werden: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Attribute der Datei »%s« konnten nicht ermittelt werden: fstat() " +"gescheitert: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Datei »%s« konnte nicht geöffnet werden: fdopen() gescheitert: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Datei »%s« konnte nicht in »%s« umbenannt werden: g_rename() ist " +"gescheitert: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Schreiben der Datei »%s« schlug fehl: write() ist gescheitert: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "" +"Datei »%s« konnte nicht geschrieben werden: fsync() ist gescheitert: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Datei »%s« konnte nicht angelegt werden: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Die vorhandene Datei »%s« konnte nicht entfernt werden: g_unlink() ist " +"gescheitert: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Vorlage »%s« ungültig, sollte kein »%s« enthalten" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Vorlage »%s« enthält nicht XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Die symbolische Verknüpfung »%s« konnte nicht gelesen werden: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Konverter von »%s« in »%s« konnte nicht geöffnet werden: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Raw-read in g_io_channel_read_line_string nicht möglich" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Nicht konvertierte Daten befinden sich noch im Lesepuffer" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanal endet mit einem Teilzeichen" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Raw-read in g_io_channel_read_to_end nicht möglich" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Es wurde keine gültige Schlüsselwertedatei in den Suchordnern gefunden" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Keine reguläre Datei" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Die Schlüsselwertedatei enthält die Zeile »%s«, welche kein zulässiges " +"Schlüssel-Wert-Paar, keine Gruppe und kein Kommentar ist" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ungültiger Gruppenname: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Die Schlüsselwertedatei beginnt nicht mit einer Gruppe" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Ungültiger Schlüsselname: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Die Schlüsselwertedatei enthält die nicht unterstützte Kodierung »%s«" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Die Schlüsselwertedatei enthält nicht die Gruppe »%s«" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Die Schlüsselwertedatei hat keinen Schlüssel »%s« in der Gruppe »%s«" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Die Schlüsselwertedatei enthält den Schlüssel »%s« mit dem Wert »%s«, der " +"nicht in UTF-8 kodiert ist" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Die Schlüsselwertedatei enthält den Schlüssel »%s« mit einem Wert, der nicht " +"interpretiert werden konnte." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Die Schlüsselwertedatei enthält den Schlüssel »%s« in der Gruppe »%s« mit " +"einem Wert, der nicht interpretiert werden konnte." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"Der Schlüssel »%s« in der Gruppe »%s« enthält den Wert »%s«, obwohl %s " +"erwartet wurde" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Die Schlüsselwertedatei enthält ein Escape-Zeichen am Zeilenende" + +# CHECK +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Die Schlüsselwertedatei enthält das ungültige Escape-Zeichen »%s«" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Der Wert »%s« konnte nicht als Zahl interpretiert werden." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Ganzzahliger Wert »%s« ist außerhalb des Wertebereiches" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Der Wert »%s« konnte nicht als Gleitkommazahl interpretiert werden." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "" +"Der Wert »%s« konnte nicht als boolescher Ausdruck interpretiert werden." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Attribute der Datei »%s%s%s%s« konnten nicht ermittelt werden: fstat() " +"gescheitert: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "»%s%s%s%s« konnte nicht abgebildet werden: mmap() ist gescheitert: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Datei »%s« konnte nicht geöffnet werden: open() ist gescheitert: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Fehler in Zeile %d, Zeichen %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Ungültiger UTF-8-kodierter Text im Namen – »%s« ist nicht gültig" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "»%s« ist kein gültiger Name" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "»%s« ist kein gültiger Name: »%c«" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Fehler in Zeile %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"»%-.*s«, was eine Zahl in einer Zeichenreferenz (wie ê) sein sollte, " +"konnte nicht analysiert werden – vielleicht ist die Zahl zu groß" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Zeichenangabe endete nicht mit einem Semikolon; wahrscheinlich haben Sie ein " +"&-Zeichen benutzt, ohne eine Entität beginnen zu wollen – umschreiben Sie " +"das »&« als &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Zeichenreferenz »%-.*s« kodiert kein zulässiges Zeichen" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Leere Entität »&;« gefunden; gültige Entitäten sind & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Entitätenname »%-.*s« ist unbekannt" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entität endete nicht mit einem Semikolon; wahrscheinlich haben Sie ein &-" +"Zeichen benutzt, ohne eine Entität beginnen zu wollen – umschreiben Sie das " +"»&« als &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument muss mit einem Element beginnen (e.g. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"»%s« ist kein gültiges Zeichen nach einem »<«-Zeichen; es darf keinen " +"Elementnamen beginnen" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Seltsames Zeichen »%s«, »>« erwartet um Start-Tag des leeren Elements »%s« " +"abzuschließen" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Zu viele Attribute im Element »%s«" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Seltsames Zeichen »%s«, »=« wird nach dem Attributnamen »%s« des Elements " +"»%s« erwartet" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Seltsames Zeichen »%s«, es wurde entweder ein Attribut oder aber »>« oder " +"»/« erwartet, um das Start-Tag des Elements »%s« abzuschließen; vielleicht " +"haben Sie ein ungültiges Zeichen in einem Attributnamen benutzt" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Seltsames Zeichen »%s«; bei der Wertangabe für das Attribut »%s« des " +"Elements »%s« wurde ein Anführungszeichen nach dem Gleichheitszeichen " +"erwartet" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"»%s« ist kein gültiges Zeichen, wenn es auf den schließenden Elementnamen " +"»%s« folgt; das erlaubte Zeichen ist »>«" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Element »%s« wurde geschlossen, kein Element ist derzeit offen" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"Element »%s« wurde geschlossen, aber das derzeit offene Element ist »%s«" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument ist leer oder enthält nur Leerraum" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokument endete unerwartet nach einer offenen spitzen Klammer »<«" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokument endete unerwartet mit noch offenen Elementen – »%s« war das letzte " +"offene Element" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokument endete unerwartet, es wurde eine spitze Klammer »>«, die das Tag <" +"%s/> schließt, erwartet" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokument endete unerwartet innerhalb eines Elementnamens" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokument endete unerwartet innerhalb eines Attributnamens" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokument endete unerwartet innerhalb eines Element-öffnenden Tags." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokument endete unerwartet nach dem Gleichheitszeichen, das einem " +"Attributnamen folgt; kein Attributwert" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokument endete unerwartet innerhalb eines Attributwertes" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Dokument endete unerwartet innerhalb eines schließenden Tags für das Element " +"»%s«" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Dokument endete unerwartet innerhalb eines schließenden Tags für ein " +"ungeöffnetes Element" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokument endete unerwartet innerhalb eines Kommentars oder " +"Verarbeitungsanweisung" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPTION …]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Hilfeoptionen:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Hilfeoptionen anzeigen" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Alle Hilfeoptionen anzeigen" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Anwendungsoptionen:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Optionen:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "»%s« konnte nicht als ganzzahliger Wert für %s interpretiert werden" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Ganzzahliger Wert »%s« für %s ist außerhalb des Bereiches" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "»%s« konnte nicht als »double«-Wert für %s interpretiert werden" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "»double«-Wert »%s« für %s ist außerhalb des Bereiches" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Fehler beim Verarbeiten der Option: %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Für %s wird ein Argument benötigt" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Unbekannte Option %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "Beschädigtes Objekt" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "Interner Fehler oder beschädigtes Objekt" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "Nicht genügend freier Speicher" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "Rückverfolgungsgrenze wurde erreicht" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"Der Ausdruck enthält Elemente, die teilweise Übereinstimmung nicht " +"unterstützen" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "Interner Fehler" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"Rückreferenzen als Bedingungen werden für teilweise Übereinstimmung nicht " +"unterstützt" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "Rekursionslimit wurde erreicht" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "Ungültige Kombination von newline-Markierungen" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "fehlerhafter Versatz" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "Kurzes UTF-8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "Rekursionsschleife" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "Unbekannter Fehler" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ am Ende des Ausdrucks" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c am Ende des Ausdrucks" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "Unbekanntes Zeichen nach \\" + +# CHECK +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "Ziffern wirkungslos in {}-Quantifizierer" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "Ziffer zu groß in {}-Quantifizierer" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "Terminierendes ] für Zeichenklasse fehlt" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "Ungültige Escape-Sequenz in Zeichenklasse" + +# CHECK +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "Bereich wirkungslos in Zeichenklasse" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "Nichts zum Wiederholen" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "Unerwartete Wiederholung" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "Unbekanntes Zeichen nach (? oder (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX-benannte Klassen werden nur innerhalb einer Klasse unterstützt" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "Abschließende ) fehlt" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "Referenz auf nicht existierenden Unterausdruck" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "fehlende ) nach Kommentar" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "Regulärer Ausdruck zu groß" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "Fehler beim Holen von Speicher" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") ohne öffnende (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "Code-Überlauf" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "Unbekanntes Zeichen nach (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "Rückblickende Annahme hat keine feste Länge" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "Falsch formatierte Zahl oder Name nach (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "Bedingte Gruppe enthält mehr als zwei Verzweigungen" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "Annahme erwartet nach (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "auf (?R oder (?[+-]Ziffern muss ) folgen" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "Unbekannter POSIX-Klassenname" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX-Elementverknüpfungen nicht unterstützt" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "Wert in \\x{…}-Sequenz ist zu groß" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "Ungültige Bedingung (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C nicht erlaubt in rückblickender Annahme" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" +"Escape-Sequenzen \\L, \\l, \\N{name}, \\U, und \\u werden nicht unterstützt" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "Rekursive Aufrufe könnten unendlich oft aufgerufen werden" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "Unbekanntes Zeichen nach (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "Terminierung im Namen des Unterausdrucks fehlt" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "Zwei benannte Unterausdrücke haben den gleichen Namen" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "Fehlerhafte \\P- oder \\p-Sequenz" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "Unbekannte Eigenschaftsname nach \\P oder \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "Name des Unterausdrucks ist zu lang (maximal 32 Zeichen)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "Zu viele benannte Unterausdrücke (maximal 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "Oktaler Wert ist größer als \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "Überlauf beim Kompilieren des Arbeitsbereichs" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "" +"Bereits geprüfter, referenzierter Unterausdruck konnte nicht gefunden werden" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE-Gruppe enthält mehr als eine Verzweigung" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "Inkonsistente NEWLINE-Optionen" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"Auf \\g folgt kein eingeklammerter, in eckigen Klammern eingeklammerter oder " +"zitierter Name oder eine Zahl oder eine einfache Zahl" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "Eine nummerierte Referenz darf nicht Null sein" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "Ein Argument ist für (*ACCEPT), (*FAIL), oder (*COMMIT) nicht erlaubt" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) nicht erkannt" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "Zahl ist zu groß" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "Name des Unterausdrucks nach (?& fehlt" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "Ziffer erwartet nach (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] ist ein ungültiges Datenzeichen im JavaScript-Kompatibilitätsmodus" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" +"Verschiedene Namen für Unterausdrücke der gleichen Nummer sind nicht erlaubt" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) benötigt ein Argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "Auf \\c muss ein ASCII-Zeichen folgen" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"Auf \\k folgt kein eingeklammerter, in eckigen Klammern eingeklammerter oder " +"zitierter Name" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N wird in einer Klasse nicht unterstützt" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "Zu viele Vorwärtsreferenzen" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "Name ist zu lang in (*MARK), (*PRUNE), (*SKIP), oder (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "Zeichenwert in \\u....-Sequenz ist zu groß" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Fehler beim Anwenden des regulären Ausdrucks %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE-Bibliothek wurde ohne UTF8-Unterstützung kompiliert" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"PCRE-Bibliothek wurde ohne Unterstützung für UTF8-Eigenschaften kompiliert" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "" +"PCRE-Bibliothek wurde mit Unterstützung für nicht-kompatible Optionen " +"kompiliert" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Fehler beim Optimieren des regulären Ausdrucks %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Fehler beim Kompilieren des regulären Ausdrucks %s an Zeichen %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "Hexadezimalzahl oder »}« erwartet" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "Hexadezimalzahl erwartet" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "Fehlendes »<» in symbolischer Referenz" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "Unvollendete symbolische Referenz" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "Symbolische Referenz der Länge 0" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "Ziffer erwartet" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "Illegale symbolische Referenz" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "Verirrtes abschließendes »\\«" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "Unbekannte Escape-Sequenz" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Fehler beim Verarbeiten des Ersetzungstextes »%s« an Zeichen %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Zitierter Text beginnt nicht mit einem Anführungszeichen" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Unbalanciertes Anführungszeichen in Befehlszeile oder anderem Text in " +"Shellquotes" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Text endete nach einem »\\«-Zeichen. (Der Text war »%s«)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Text endete, bevor ein passendes Anführungszeichen für %c gefunden wurde. " +"(Der Text war »%s«)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Text war leer (oder enthielt nur Leerraum)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Daten vom Kindprozess konnten nicht gelesen werden (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Unerwarteter Fehler beim Lesen von Daten eines Kindprozesses (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Unerwarteter Fehler in waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Der Kindprozess wurde mit Status %ld beendet" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Der Kindprozess wurde mit Signal %ld beendet" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Der Kindprozess wurde mit Signal %ld beendet" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Der Kindprozess wurde gewaltsam beendet" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Lesen aus Weiterleitung zum Kind (%s) gescheitert" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Abspalten des Kindprozesses »%s« gescheitert (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Abspalten gescheitert (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "In Ordner »%s« (%s) konnte nicht gewechselt werden" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Kindprozess »%s« konnte nicht ausgeführt werden (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" +"Öffnen der Datei zur Neuzuweisung des Datei-Deskriptors ist fehlgeschlagen " +"(%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "" +"Duplizieren des Datei-Deskriptors für Kindprozess ist fehlgeschlagen (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Abspalten des Kindprozesses gescheitert (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "" +"Schließen des Datei-Deskriptors des Kindprozesses ist fehlgeschlagen (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Unbekannter Fehler beim Ausführen des Kindprozesses »%s«" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Es konnten nicht genug Daten von Kind-Programmkennungsweiterleitung (%s) " +"gelesen werden" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Daten konnten nicht vom Kindprozess gelesen werden" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Kindprozess konnte nicht ausgeführt werden (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "dup() im Kindprozess ist fehlgeschlagen (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ungültiger Programmname: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ungültige Zeichenkette im Argumentsvektor bei %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ungültige Zeichenkette in der Umgebung: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ungültiger Arbeitsordner: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Hilfsprogramm (%s) konnte nicht ausgeführt werden" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Unerwarteter Fehler in g_io_channel_win32_poll() beim Lesen aus dem " +"Kindprozess" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Leere Zeichenkette ist keine Zahl" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "»%s« ist keine vorzeichenbehaftete Zahl" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Zahl »%s« ist außerhalb des zulässigen Bereichs [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "»%s« ist keine vorzeichenlose Zahl" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Unzulässige %-Kodierung in Adresse" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Unzulässiges Zeichen in Adresse" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Nicht-UTF-8-Zeichen in Adresse" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Ungültige IPv6-Adresse »%.*s« in Adresse" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Unzulässig kodierte IP-Adresse »%.*s« in Adresse" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Unzulässig internationalisierter Rechnername »%.*s« in Adresse" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Port »%.*s« in Adresse konnte nicht verarbeitet werden" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Port »%.*s« in Adresse ist außerhalb des Bereiches" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "Adresse »%s« ist keine absolute Adresse" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "Adresse »%s« hat keine Host-Komponente" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "Adresse ist nicht absolut und es wurde keine Basis-Adresse angegeben" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "»=« und Parameter-Wert fehlen" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Fehler beim Anfordern von Speicher" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Zeichen außerhalb des Bereiches für UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Ungültige Folge in Umwandlungseingabe" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Zeichen außerhalb des Bereiches für UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kbit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mbit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gbit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tbit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pbit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Ebit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kibit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mibit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gibit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tibit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pibit" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eibit" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u Byte" +msgstr[1] "%u Bytes" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s Byte" +msgstr[1] "%s Bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Failed to redirect output or input of child process (%s)" +#~ msgstr "" +#~ "Umleiten der Ausgabe oder Eingabe des Kindprozesses (%s) gescheitert" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "/var/lib/dbus/machine-id oder /etc/machine-id konnte nicht geladen " +#~ "werden: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Unbekannter Fehler bei Verbindungsversuch" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Fehler in Adresse »%s« – Das Familien-Attribut ist nicht korrekt" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "»%s« wurde unter »%s« eingehängt\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; Überschreiben dieses Schlüssels wird ignoriert.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " und --strict wurde angegeben; Abbruch.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Überschreiben dieses Schlüssels wird ignoriert.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "Nichts wird getan.\n" diff --git a/po/dz.po b/po/dz.po new file mode 100644 index 0000000..b5a253f --- /dev/null +++ b/po/dz.po @@ -0,0 +1,3833 @@ +# Dzongkha translation of glib +# Copyright @ 2006, Free software foundation, Inc. +# Mindu Dorji. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD.dz\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2006-08-09 10:23+0530\n" +"Last-Translator: Mindu Dorji\n" +"Language-Team: DZONGKHA \n" +"Language: dz\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Dzongkha\n" +"X-Poedit-Country: BHUTAN\n" +"X-Poedit-SourceCharset: utf-8\n" +"Plural-Forms: nplurals=2;plural=(n!=1);\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "རེ་བ་མེད་པའི་à½à¾±à½‘་ཆོས་ '%s'ཆ་ཤས་'%s'གི་དོན་ལུà¼" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "à½à¾±à½‘་ཆོས་'%s'འཚོལ་མ་à½à½¼à½–་ ཆ་ཤས་'%sགི" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "རེ་བ་མེད་པའི་ངོ་རྟགས་ '%s'༠རེ་བ་བསà¾à¾±à½ºà½‘་མི་ངོ་རྟགས་'%s'à¼" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "རེ་བ་མེད་པའི་ངོ་རྟགས་ '%s' ངོ་རྟགས༠'%s'ནང་ནà¼" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "གནད་སྡུད་སྣོད་à½à½¼à¼‹à½šà½´à¼‹à½“ང་ ནུས་ཅན་དེབ་རྟགས་ཡིག་སྣོད་ འཚོལ་མ་à½à½¼à½–à¼" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "ཡུ་ཨར་ཨའི་'%s'གི་དོན་ལུ་ དེབ་རྟགས་ཅིག་ཧེ་མ་ལས་རང་འདུག" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "ཡུ་ཨར་ཨའི་'%s'གི་དོན་ལུ་དེབ་རྟགས་མ་à½à½¼à½–à¼" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "ཡུ་ཨར་ཨའི་'%s'གི་དོན་ལུ་དེབ་རྟགས་ནང་ མ་ཡིམ་གྱི་དབྱེ་བ་ངེས་འཛིན་མ་འབད་བས༠" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "ཡུ་ཨར་ཨའི་'%s'གི་དོན་ལུ་དེབ་རྟགས་ནང་ སྒེར་གྱི་ཟུར་རྟགས་ངེས་འཛིན་མ་འབད་བསà¼" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "ཡུ་ཨར་ཨའི་'%sགི་དོན་ལུ་ དེབ་རྟགས་ནང་ སྡེ་ཚན་གཞི་སྒྲིག་མ་འབད་བསà¼" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "མིང་'%sའབད་མི་གློག་རིམ་གྱིས་ '%s དོན་ལུ་ དེབ་རྟགས་ཅིག་à½à½¼à¼‹à½ à½‚ོད་མ་འབད་བས༠" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ ’%s’:%s ལྷག་མ་ཚུགསà¼" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "ཡིག་འབྲུའི་ཆ་ཚན་ ‘%s’ ལས་ ‘%s’ ལུ་གཞི་བསྒྱུར་འབད་ནི་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "‘%s’ ལས་ '%s' ལུ་ སྒྱུར་བྱེད་à½à¼‹à½•ྱེ་མ་ཚུགསà¼" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "གཞི་བསྒྱུར་གྱི་ཨིན་པུཊི་ནང་ བའིཊི་གི་འབྱུང་རིམ་ ནུས་མེད་ཨིན་པསà¼" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "གཞི་བསྒྱུར་གྱི་སà¾à½–ས་འཛོལ་བ་ :%s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "ཨིན་པུཊི་མཇུག་ལུ་ ཡི་གུའི་འབྱུང་རིམ་ཆ་ཤསà¼" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "གློ་བུར་རྒྱབ་à½à½‚ ’%s’ ལས་ ཀོཌི་སེཊི་ ’%s’ ལུ་ གཞི་བསྒྱུར་འབད་མི་ཚུགས༠" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" +"ཡུ་ཨར་ཨའི་ ’%s’ འབད་མི་དེ་ \"file\" འཆར་ལས་ལག་ལེན་འà½à½–་པའི་ ཡུ་ཨར་ཨའི་ཡང་དག་ཅིག་མེནà¼" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "ཉེ་གནས་་ཀྱི་ཡིག་སྣོད་ ཡུ་ཨར་ཨའི་ ’%s’ འབད་མི་དེ་ནང་ '#' ཅིག་མེདཔ་འོང༌à¼" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "ཡུ་ཨར་ཨའི་ ’%s’ ནུས་མེད་ཨིན་པསà¼" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "ཡུ་ཨར་ཨའི་ ’%s’ གི་ ཧོསཊི་ནེམ་དེ་ ནུས་མེད་ཨིན་པསà¼" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "ཡུ་ཨར་ཨའི་ ’%s’ གི་ནང་ན་ ནུས་མེད་à½à½¼à½‚་ལས་à½à½¢à¼‹à½˜à½²à¼‹ ཡིག་འབྲུ་་ཚུ་འདུག" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "འགྲུལ་ལམ་གྱི་མིང་ ’%s’ འབད་མི་དེ་ འགྲུལ་ལམ་ཡང་དག་ཅིག་མེནà¼" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "ནུས་མེད་ཀྱི་ ཧོསཊི་ནེམà¼" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "ངས་ཆ" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "ཕྱི་ཆ" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "པསྱི་ལོ%yཟལ%mཚེས%dཆུ་ཚོད%Hཀསར་མ%Mཀསར་ཆ%S" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "པསྱི་ལོ%yཟལ%mཚེས%d" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "ཆུ་ཚོད%Hཀསར་མ%Mཀསར་ཆ%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "ཆུ་ཚོད%Iཀསར་མ%Mཀསར་ཆ%S %p" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "ཟླ་བ་དང་པ་" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "ཟླ་བ་གཉིས་པ་" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "ཟླ་བ་གསུམ་པ་" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "ཟླ་བ་བཞི་པ་" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "ཟླ་བ་ལྔ་ཕ་" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "ཟླ་བ་དྲུག་པ་" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "ཟླ་བ་བདུནཔ་" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ཟླ་༡" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ཟླ་༢" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "ཟླ་༣" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "ཟླ་༤" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "ཟླ་༥" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ཟླ་༦" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ཟླ་༧" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "གཟའ་མིག་དམར་" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "གཟའ་ལྷག་ཕ་" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "གཟའ་པུར་བུ་" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "གཟའ་པ་སངས་" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "གཟའ་སྤེན་ཕ་" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "གཟའ་ཉི་མ་" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "གཟའ་ཟླ་བ་" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "མིར་" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ལྷག་" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "པུར་" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "སངས་" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "སྤེན་" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ཉི་" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ཟླ་" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "སྣོད་à½à½¼à¼‹ '%s':%s à½à¼‹à½•ྱེ་ནི་ལུ་འཛོལ་བà¼" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "བཱཡིཊི་ %lu བསà¾à½£à¼‹à½¦à¾¤à¾²à½¼à½‘་འབད་མ་ཚུགས་ \"%s\" ལྷག་ནི་ལུà¼" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ནང་ལས་ ལྷག་མ་ཚུགསà¼" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s à½à¼‹à½•ྱེ་མ་ཚུགསà¼" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "ཡིག་སྣོད་ '%s': fstat() གི་à½à¾±à½‘་ཆོས་ཚུ་ ལེན་མ་ཚུགས་ :%sམ་བà½à½´à½–à¼" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "ཡིག་སྣོད་ ’%s’:fdopen() à½à¼‹à½•ྱེ་མ་ཚུགས༠%s་མ་བà½à½´à½–à¼" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "ཡིག་སྣོད་ ’%s’ལས་'%s' ལུ་ བསà¾à¾±à½¢à¼‹à½˜à½²à½„་བà½à½‚ས་མ་ཚུགས༠g_rename() གིས་ %s ལུ་མ་བà½à½´à½–à¼" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’:%s གསར་བསà¾à¾²à½´à½“་འབད་མ་ཚུགསà¼" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "ཡིག་སྣོད་’%s’ འབྲི་ནིའི་དོན་ལུ་ à½à¼‹à½•ྱེ་མ་ཚུགས་: fdopen() མ་བà½à½´à½–་:%sà¼" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "ཡིག་སྣོད་ ’%s’འབྲི་མ་ཚུགས་: fwrite() མ་བà½à½´à½–་:%sà¼" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "ཡིག་སྣོད་ ’%s’འབྲི་མ་ཚུགས་: fwrite() མ་བà½à½´à½–་:%sà¼" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "ཡིག་སྣོད་ ’%s’འབྲི་མ་ཚུགས་: fwrite() མ་བà½à½´à½–་:%sà¼" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "ཡིག་སྣོད་ ’%s’à½à¼‹à½–སྡམས་མ་ཚུགས་: fclose() མ་བà½à½´à½–་:%sà¼" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "ཡོད་བཞིན་པའི་ཡིག་སྣོད་'%s' དེ་ རྩ་བསà¾à¾²à½‘་གà½à½„་མ་ཚུགས་: g_unlink() མ་བà½à½´à½–་:%s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "ཊེམ་པེ་ལེཊི་ '%s' དེ་ནུས་མེད་ཨིན༠དེ་ནང་ '%s' འབད་མི་ བཞག་ནི་མི་འོང༌à¼" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "ཊེམ་པེལེཊི་ ’%s’ འབད་མི་དེ་ནང་ XXXXXX མིན་འདུགà¼" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ ’%s’:%s ལྷག་མ་ཚུགསà¼" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "‘%s’ ལས་ ‘%s’:%s ལུ་སྒྱུར་བྱེད་à½à¼‹à½•ྱེ་མ་ཚུགསà¼" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "ཇི་ཨའི་ ཨོ་ རྒྱུ་ལམ་ ལྷག་ གྱལ་རིམ་ ཡིག་རྒྱུན་ཚུ་ནང་ རགས་ལྷག་མི་བà½à½´à½–à¼" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "ལྷག་ནིའི་གནད་à½à½¼à½„ས་ནང་ གཞི་བསྒྱུར་མ་འབད་བའི་གནད་སྡུད་ ལྷག་ལུས་འདུག" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "ཡིག་འབྲུ་ནང་ཆ་ཤས་ནང་ལུ་ རྒྱུ་ལམ་རྩ་འགྲོལ་འགྱོà½à¼‹à½¨à½²à½“à¼" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "ཇི་ཨའི ཨོ་ རྒྱ་ལམ་ མཇུག་ ཚུན་ ལྷག་ནི་ཚུ་ནང་ རགས་ལྷག་མི་བà½à½´à½–à¼" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "ཡིག་སྣོད་ ’%s’ à½à¼‹à½•ྱེ་མ་ཚུགས་: open()མ་བà½à½´à½–་:%sà¼" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "ཡིག་སྣོད་’%s’ གི་ས་à½à¾²à¼‹à½ à½–ྲི་མ་ཚུགས་: mmap() མ་བà½à½´à½–་:%sà¼" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "གྱལ་རིམ་%d ཡིག་འབྲུ་ %d:%s ལུ་འཛོལ་བà¼" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "ནུས་མེད་ཡུ་ཊི་ཨེཕ་-༨ ཀྱི ཨིན་ཀོ་དེཌི་ཚིག་ཡིག" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "གྱལ་རིམ་ %d་: %s ལུ་འཛོལ་བà¼" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s'ལུ་ མིང་དཔྱད་འབད་མ་ཚུགས༠འདི་ཡིག་འབྲུ་གཞི་བསྟུན་ (དཔེར་ན་ (ê ) ཅིག་ནང་གི་ ཨང་" +"ཡིག་ཅིག་འོང་དགོཔ་ཨིན་ - ཨང་ཡིག་དེ་ སྦོམ་དྲགསཔ་འོང་ནི་མསà¼" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"ཡིག་འབྲུ་གཞི་བསྟུན་དེ་ སེ་མི་ཀོ་ལཱོན་ ; གྱིས་ མཇུག་མ་བསྡུ་བས༠à½à¾±à½¼à½‘་ཀྱིས་ ངོ་བོ་ཅིག་ འགོ་བཙུགས་ནིའི་རེ་འདུན་" +"མེད་པར་ དང་རྟགས་ ཡིག་འབྲུ་ ལག་ལེན་འà½à½–་འà½à½–་འོང་ནི་མས༠དང་རྟགས་དེ་ & བཟུམ་སྦེ་ གྲོས་à½à½¢à¼‹" +"འབདà¼" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "ཡིག་འབྲུ་གཞི་བསྟུན་ '%-.*s' དེ་གིས་ གནང་བ་ཅན་གྱི་ཡིག་འབྲུ་ཅིག་ལུ་ ཨིན་ཀོཌི་མི་འབད་བསà¼" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"ངོ་བོ་སྟོང་པ་ ’&;’ མà½à½¼à½„་ཅི༠ནུས་ཅན་ངོ་བོ་ཚུ་: & " < > ' ཚུ་ཨིནà¼" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "ངོ་བོའི་མིང་ '%s' ཧ་མ་གོ" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"ངོ་བོ་འདི་ སེ་མི་ཀོ་ལཱོན་ ; གིས་འབད་ མཇུག་མ་བསྡུ་བས༠à½à¾±à½¼à½‘་ཀྱིས་ངོ་བོ་ཅིག་ འགོ་མ་བཙུགས་པར་ དང་རྟགས་" +"ཡིག་འབྲུ་ཅིག་ ལག་ལེན་འà½à½–་འà½à½–་བཟུམ་ཅིག་འདུག དང་རྟགས་་ & བཟུམ་ཅིག་སྦེ་ གྲོས་à½à½¢à¼‹à½ à½–དà¼" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "ཡིག་ཆ་དེ་ (དཔེར་ན་ ) བཟུམ་མའི་ཆ་ཤས་ཅིག་གིས་ འགོ་བཙུགས་དགོ" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"ཡིག་འབྲུ་ ’%s’ དེ་ ཡིག་འབྲུ་’<’ ཅིག་གི་རྗེས་སུ་འོངམ་ད་ ནུས་པ་ཡོད་པའི་ཡིག་འབྲུ་ཅིག་མིན༠འདི་གིས་ཆ་ཤས་" +"ཀྱི་མིང་ཅིག་ འགོ་མི་བཙུགསཔ་འོང༌à¼" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"’%s’ དེ་རà¾à¾±à½„་ཡིག་ཨིན་པས༠ཆ་ཤས་ཀྱི་ འགོ་བཙུགས་ངོ་རྟགས་ %s’ དེ་མཇུག་བསྡུ་ནི་ལུ་ ཡིག་འབྲུ་ ’>’ ཅིག་ " +"ཨིན་པའི་རེ་བ་ཡོདà¼" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"’%s’ དེ་རà¾à¾±à½„་ཡིག་ཨིན་པས༠’=’ ཅིག་ཡོད་པའི་ རེ་བ་ཡོད་ à½à¾±à½‘་ཆོས་ཀྱི་མིང་ ’%s’ ཆ་ཤས་ ’%s’ གི་རྗེས་" +"སུà¼" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"’%s’ དེ་རà¾à¾±à½„་ཡིག་ཨིན་པས༠ཆ་ཤས་ ’%s’ གི་འགོ་བཙུགས་ངོ་རྟགས་ མཇུག་བསྡུ་ནི་ལུ་ ཡིག་འབྲུ་ ’>’ ཡང་ན་ " +"’/’ གི་རེ་བ་ཡོདà¼" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"’%s’ དེ་རà¾à¾±à½„་ཡིག་ཨིན་པས༠à½à¾±à½‘་ཆོས་’%s’ གི་ ཆ་ཤས’%s’ གི་དོན་ལུ་ བེ་ལུ་བྱིནམ་ད་ མཉམ་རྟགས་ཀྱི་ཤུལ་" +"ལུ་ འགོ་བཙུགས་འདྲེན་རྟགས་ཅིག་ ཚུད་ཡོད་པའི་རེ་བ་ཡོདà¼" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"’%s’ དེ་ ཡིག་འབྲུ་ནུས་ཅན་ཅིག་མེན༠à½à¼‹à½–སྡམ་ནིའི་ཆ་ཤས་མིང་ ’%s’; གི་རྟིང་བདའ་འོངམ་ད་ ཆོག་པའི་ཡིག་" +"འབྲུ་དེ་ ’>’ ཨིནà¼" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "ཆ་ཤས་ ’%s’ དེ་ à½à¼‹à½–སྡམས་à½à½ºà¼‹à½¡à½¼à½‘པ་ལས་ ད་ལྟོ་ཆ་ཤས་གཅིག་ཡང་ à½à¼‹à½•ྱེ་ཕྱེà½à¼‹à½˜à½²à½“་འདུག" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "ཆ་ཤས་ ’%s’ དེ་ à½à¼‹à½–སྡམས་ནུག དེ་འབདà½à¼‹à½‘་ ད་ལྟོ་à½à¼‹à½•ྱེ་སྟེ་ཡོད་མི་ཆ་ཤས་དེ་ ’%s’ ཨིནà¼" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "ཡིག་ཆ་དེ་སྟོང་པའམ་ ཡང་ཅིན་ ནང་ན་ས་སྟོང་དཀརཔོ་མ་གà½à½¼à½‚ས་ མེདཔ་འོང་ནི་མསà¼" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "ཡིག་ཆ་དེ་ ཟུར་à½à½´à½‚་གུག་ཤད་ ’<’ ཅིག་གི་ཤུལ་ལས་ རེ་བ་མེད་པར་ རྫོགས་སོ་ཡིà¼" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"ཡིག་ཆ་དེ་ རེ་བ་མེད་པར་རྫོགས་སོ་རུང་ ཆ་ཤས་དེ་ à½à¼‹à½•ྱེ་སྟེ་རང་འདུག མà½à½ à¼‹à½˜à½‡à½´à½‚་à½à¼‹à½•ྱེ་མི་ ཆ་ཤས་དེ་ " +"-’%s’ ཨིན་པསà¼" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ཡིག་ཆ་དེ་ རེ་བ་མེད་པར་རྫོགས་སོ་ནུག ངོ་རྟགས་ <%s/> མཇུག་བསྡུ་བའི་ à½à¼‹à½–སྡམ་ཟུར་à½à½´à½‚་གུག་ཤད་ཅིག་ " +"མà½à½¼à½„་བའི་རེ་བ་ཡོདà¼" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "ཡིག་ཆ་དེ་ ཆ་ཤས་ཅིག་གི་ མིང་གི་ནང་ན་ རེ་བ་མེད་པར་རྫོགས་སོ་ནུག" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "ཡིག་ཆ་དེ་ à½à¾±à½‘་ཆོས་ཀྱི་མིང་ཅིག་གི་ནང་ན་ རེ་བ་མེད་པར་རྫོགས་སོ་ནུག" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ཡིག་ཆ་དེ་ ཆ་ཤས་à½à¼‹à½•ྱེ་ནིའི་ ངོ་རྟགས་ཅིག་གི་ནང་ན་ རེ་བ་མེད་པར་ རྫོགས་སོ་ནུག" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"ཡིག་ཆ་དེ་ à½à¾±à½‘་ཆོས་ཀྱི་མིང་ཅིག་གི་ཤུལ་ལས་ མཉམ་རྟགས་ཀྱི་རྗེས་སུ་ རེ་བ་མེད་པར་ རྫོགས་སོ་ནུག à½à¾±à½‘་ཆོས་ཀྱི་བེ་" +"ལུ་མིན་འདུག" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ཡིག་ཆ་དེ་ à½à¾±à½‘་ཆོས་ཀྱི་ བེ་ལུ་ཅིག་གི་ནང་ན་སྡོད་པའི་སà¾à½–ས་ལུ་ རེ་བ་མེད་པར་ རྫོགས་སོ་ནུག" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "ཡིག་ཆ་དེ་ ཆ་ཤས་ ’%s’ གི་དོན་ལུ་ à½à¼‹à½–སྡམ་ངོ་རྟགས་ནང་ན་ རེ་བ་མེད་པར་ རྫོགས་སོ་ནུག" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "ཡིག་ཆ་དེ་ བསམ་བཀོད་ ཡང་ན་ ལས་སྦྱོར་བཀོད་རྒྱ་ཅིག་གི་ནང་ན་ རེ་བ་མེད་པར་ རྫོགས་སོ་ནུག" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "ཡིག་འབྲུ་ནང་ཆ་ཤས་ནང་ལུ་ རྒྱུ་ལམ་རྩ་འགྲོལ་འགྱོà½à¼‹à½¨à½²à½“à¼" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "གཞི་བསྒྱུར་གྱི་ཨིན་པུཊི་ནང་ བའིཊི་གི་འབྱུང་རིམ་ ནུས་མེད་ཨིན་པསà¼" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "མཇུག་མ་བསྡུ་བའི་ ཡིག་འབྲུའི་གཞི་བསྟུནà¼" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "མཇུག་མ་བསྡུ་བའི་ ཡིག་འབྲུའི་གཞི་བསྟུནà¼" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "མཇུག་མ་བསྡུ་བའི་ ཡིག་འབྲུའི་གཞི་བསྟུནà¼" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "གྱལ་རིམ་%d ཡིག་འབྲུ་ %d:%s ལུ་འཛོལ་བà¼" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "མཇུག་མ་བསྡུ་བའི་ ངོ་བོའི་གཞི་བསྟུནà¼" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "ལུང་འདྲེན་ཚིག་ཡིག་ཚུ་ འདྲེན་རྟགས་ཀྱི་à½à½¼à½‚་ལས་ འགོ་མི་བཙུགསà¼" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"བཀོད་ལམ་ནང་ ཡང་ན་ གཞན་ ཤལ་གྱི་འདྲེན་རྟགས་ནང་བཙུགས་པའི་ཚིག་ཡིག་ཚུ་ནང་ མི་མà½à½´à½“་པའི་འདྲེན་རྟགས་" +"འདུག" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" +"ཚིག་ཡིག་དེ་ ཡིག་འབྲུ་ ’\\’ ཅིག་གི་ རྟིང་བདའ་སྟེ་རང་ རྫོགས་སོ་ནུག (ཚིག་ཡིག་དེ་ ’%s’ ཨིན་པསà¼)" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"འདྲེན་རྟགས་དང་ མ་མà½à½´à½“་པའི་ཧེ་མར་ རྫོགས་སོང་མི་ ཚིག་ཡིག་དེ་ %c ཨིན་མས༠(ཚིག་ཡིག་དེ་ ’%s’ ཨིན་པས)" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "ཚིག་ཡིག་དེ་ སྟོང་པའམ་ (ཡང་ཅིན་ ནང་ན་ས་སྟོང་དཀརཔོ་རà¾à¾±à½„མ་ཅིག་ འོང་ནི་མསà¼)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "ཆ་ལག་ལས་སྦྱོར་ནང་ལས་ གནད་སྡུད་ལྷག་མ་ཚུགས༠" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"ཆ་ལག་ལས་སྦྱོར་ (%s) དང་གཅིག་à½à½¢à¼‹ རྒྱུད་འབྲེལ་འà½à½–་ནིའི་དོན་ལུ་ རྒྱུད་དུང་གསར་བསà¾à¾²à½´à½“་འབད་མ་ཚུགསà¼" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ཆ་ལག་རྒྱུད་དུང་ (%s) ནང་ལས་ ལྷག་མ་ཚུགསà¼" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "སྣོད་à½à½¼à¼‹â€™%s’ (%s)ལུ་ བསྒྱུར་བཅོས་འབད་མ་ཚུགས༠" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ཆ་ལག་ལས་སྦྱོར་ (%s) དེ་ ལག་ལེན་འà½à½–་མ་ཚུགསà¼" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "ནུས་མེད་ལསརིམ་མིང་:%sà¼" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d: %s ལུ་ སྒྲུབ་རྟགས་à½à½ºà½€à¼‹à½Šà½¼à½¢à¼‹à½“ང་ ནུས་མེད་ཡིག་རྒྱུནà¼" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "མà½à½ à¼‹à½ à½à½¼à½¢à¼‹:%sནང་ལུ་ ནུས་མེད་ཡིག་རྒྱུནà¼" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ནུས་མེད་ལཱ་གཡོག་སྣོད་à½à½¼à¼‹:%sà¼" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ལས་རོགས་པའི་ལས་རིམ་ (%s) ལག་ལེན་འà½à½–་མ་ཚུགསà¼" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"ཆ་ལག་ལས་སྦྱོར་ནང་ལས་ གནད་སྡུད་ལྷག་ནི་ལུ་ རེ་བ་མེད་པའི་འཛོལ་བ་ g_io_channel_win32_poll() " +"ཚུ་འདུག" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ཆ་ལག་ལས་སྦྱོར་ (%s) ནང་ལས་ གནད་སྡུད་ལྷག་མ་ཚུགསà¼" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"སེལ་འà½à½´à¼‹() ནང་ལུ་ རེ་བ་མེད་པའི་འཛོལ་བ་བྱུང་སྟེ་ ཆ་ལག་ལས་སྦྱོར་ (%s) ནང་ལས་ གནད་སྡུད་ལྷག་དོà¼" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "à½à½ºà½Šà½²à¼‹à½”ིཌི་ () (%s) ནང་ལུ་ རེ་བ་མེད་པའི་འཛོལ་བ༠" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) ལུ་ à½à¼‹à½¦à¾¤à½ºà½£à¼‹à½˜à¼‹à½šà½´à½‚སà¼" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "ཆ་ལག་ལས་སྦྱོར་ \"%s\" (%s) ལག་ལེན་འà½à½–་མ་ཚུགསà¼" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "ཆ་ལག་ལས་སྦྱོར་ (%s) གི་ ཨའུཊི་པུཊི་ ཡང་ཅིན་ ཨིན་པུཊི་ ལོག་གà½à½„་མ་ཚུགསà¼" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ཆ་ལག་ལས་སྦྱོར་ (%s) à½à¼‹à½¦à¾¤à½ºà½£à¼‹à½˜à¼‹à½šà½´à½‚སà¼" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "མ་ཤེས་པའི་འཛོལ་བ་ཅིག་གིས ཆ་ལག་ལས་སྦྱོར་ \"%s\" ལག་ལེན་འà½à½–་དོà¼" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "ཆ་ལག་ པིཨའི་ཌི་ རྒྱུད་དུང་ (%s) ནང་ལས་ གནད་སྡུད་ལངམ་ ལྷག་མ་ཚུགསà¼" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "ཡིག་འབྲུ་ ཡུ་ཊི་ཨེཕ་ - ༨ ཀྱི་ à½à¾±à½–་ཚད་ཀྱི་ཕྱི་à½à½¢à¼‹à½¨à½²à½“་མསà¼" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "བསྒྱུར་བཅོས་ཀྱི་ ཨིན་པུཊི་ནང་ལུ་ ནུས་མེད་འབྱུང་རིམ་འདུག" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "ཡིག་འབྲུ་ ཡུ་ཊི་ཨེཕ་- ༡༦ གི་ à½à¾±à½–་ཚད་ཀྱི་ཕྱི་à½à½¢à¼‹à½¨à½²à½“་མསà¼" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "ལག་ལེན:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[ གདམ་à½... ] " + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "གྲོགས་རམ་གདམ་à½à¼‹à½šà½´à¼" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "གྲོགས་རམ་གདམ་à½à¼‹à½šà½´à¼‹à½¦à¾Ÿà½¼à½“à¼" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "གྲོགས་རམ་གདམ་à½à¼‹à½šà½´à¼‹ ཆ་མཉམ་སྟོནà¼" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "གློག་རིམ་གྱི་གདམ་à½à¼" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "ཧྲིལ་ཨང་བེ་ལུ་ ’%s’དེ་%s གི་དོན་ལུ་ མིང་དཔྱད་འབད་མི་ཚུགསà¼" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%s གི་དོན་ལུ་ ཧྲིལ་ཨང་བེ་ལུ་ ’%s’ དེ་ à½à¾±à½–་ཚད་ཀྱི་ཕྱི་à½à½¢à¼‹à½¨à½²à½“་པསà¼" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "བེ་ལུ་གཉིས་བལྟབ་%s'མིང་དཔྱད་འབད་མི་ཚུགས༠%sགི་དོན་ལུà¼" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "བེ་ལུ་གཉིས་བལྟབ་'%s' དེ་%s གི་དོན་ལུ་ à½à¾±à½–་ཚད་ཀྱི་ཕྱི་à½à½¢à¼‹à½¨à½²à½“་པསà¼" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "གདམ་à½à¼‹%s མིང་དཔྱད་འབད་ནི་ལུ་འཛོལ་བà¼" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "%s གི་དོན་ལུ་ སྒྲུབ་རྟགས་བརླག་སྟོར་ཞུགས་ནུག" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "ཤེས་མ་ཚུགས་པའི་གདམ་à½à¼‹ %sà¼" + +#: ../glib/gkeyfile.c:366 +#, fuzzy +msgid "Valid key file could not be found in search dirs" +msgstr "གནད་སྡུད་སྣོད་à½à½¼à¼‹à½šà½´à¼‹à½“ང་ ནུས་ཅན་ལྡེ་མིག་ཡིག་སྣོད་ འཚོལ་མ་à½à½¼à½–à¼" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "དུས་རྒྱུན་གྱི་ཡིག་སྣོད་ཅིག་མེན་པསà¼" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "ཡིག་སྣོད་སྟོངམ་ཨིན་པསà¼" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ ལྡེ་མིག་-བེ་ལུ་དང་ སྡེ་ཚན་ བསམ་བཀོད་མེན་པའི་ གྱལ་རིམ་'%s' ཡོད༠" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "ནུས་མེད་ལསརིམ་མིང་:%sà¼" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་དེ་ སྡེ་ཚན་ཅིག་གི་à½à½¼à½‚་ལས་ འགོ་མི་བཙུགསà¼" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "ནུས་མེད་ལསརིམ་མིང་:%sà¼" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½ºà½‘་པའི་ ཨིན་ཀོ་ཌིང་'%s'ཡོདà¼" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ སྡེ་ཚན་ '%s' མིན་འདུགà¼" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ ལྡེ་མིག་'%s'མིན་འདུག" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ ཡུ་ཊི་ཨེཕ་-༨ མེད་པའི་ ལྡེ་མིག་'%s' བེ་ལུ་'%s' དང་བཅསཔ་སྦེ་འདུག" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ à½à¼‹à½–སྒྱུར་འབད་མ་ཚུགས་པའི་ བེ་ལུ་ཡོད་མི་ ལྡེ་མིག་ '%s'འདུག" + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ à½à¼‹à½–སྒྱུར་འབད་མ་ཚུགས་པའི་ བེ་ལུ་ཡོད་མི་ ལྡེ་མིག་ '%s'འདུག" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ à½à¼‹à½–སྒྱུར་འབད་མ་ཚུགས་པའི་ ལྡེ་མིག་'%s'སྡེ་ཚན་'%s' ནང་འདུགà¼" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་དེ་ལུ་ ལྡེ་མིག་'%s' སྡེ་ཚན་'%s' ནང་མིན་འདུག" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ གྱལ་རིམ་མཇུག་ལུ་ གྲོས་à½à½¢à¼‹à½ à½–ད་མི་ཡིག་འབྲུ་འདུག" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "ལྡེ་མིག་ཡིག་སྣོད་ནང་ལུ་ ནུས་མེད་གྲོས་à½à½¢à¼‹à½ à½–ྱུང་རིམ་ '%s' འདུག" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "བེ་ལུ་'%s'དེ་ ཨང་གྲངས་ཅིག་སྦེ་ à½à¼‹à½–སྒྱུར་འབད་མི་ཚུགསà¼" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "ཧྲིལ་ཨང་བེ་ལུ་ ’%s’ དེ་ à½à¾±à½–་ཚད་ཀྱི་ཕྱི་à½à½¢à¼‹à½¨à½²à½“་པསà¼" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "བེ་ལུ་'%s'དེ་ འཕུར་ལྡིང་ཨང་གྲངས་ཅིག་སྦེ་ à½à¼‹à½–སྒྱུར་འབད་མི་ཚུགསà¼" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "བེ་ལུ་'%s'དེ་ བུ་ལིན་ཅིག་སྦེ་ à½à¼‹à½–སྒྱུར་འབད་མི་ཚུགསà¼" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "གཞི་བསྒྱུར་གྱི་ཨིན་པུཊི་ནང་ བའིཊི་གི་འབྱུང་རིམ་ ནུས་མེད་ཨིན་པསà¼" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "ཤེས་མ་ཚུགས་པའི་གདམ་à½à¼‹ %sà¼" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "ཤེས་མ་ཚུགས་པའི་གདམ་à½à¼‹ %sà¼" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "སྣོད་à½à½¼à¼‹ '%s':%s à½à¼‹à½•ྱེ་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "སྣོད་à½à½¼à¼‹ '%s':%s à½à¼‹à½•ྱེ་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "གྱལ་རིམ་ %d་: %s ལུ་འཛོལ་བà¼" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "གདམ་à½à¼‹%s མིང་དཔྱད་འབད་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "ཡིག་འབྲུ་ ’%s དེ་ ངོ་བོའི་མིང་ཅིག་གི་ ནང་འà½à½¼à½‘་ལུ་ ནུས་མེད་ཨིན༠" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "ཡིག་འབྲུ་ ’%s དེ་ ངོ་བོའི་མིང་ཅིག་གི་ ནང་འà½à½¼à½‘་ལུ་ ནུས་མེད་ཨིན༠" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "ཡིག་འབྲུ་ ’%s དེ་ ངོ་བོའི་མིང་ཅིག་གི་ ནང་འà½à½¼à½‘་ལུ་ ནུས་མེད་ཨིན༠" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "གདམ་à½à¼‹%s མིང་དཔྱད་འབད་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "གཞི་བསྒྱུར་གྱི་སà¾à½–ས་འཛོལ་བ་ :%s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "སྣོད་à½à½¼à¼‹ '%s':%s à½à¼‹à½•ྱེ་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +#, fuzzy +msgid "No application is registered as handling this file" +msgstr "མིང་'%sའབད་མི་གློག་རིམ་གྱིས་ '%s དོན་ལུ་ དེབ་རྟགས་ཅིག་à½à½¼à¼‹à½ à½‚ོད་མ་འབད་བས༠" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "ནུས་མེད་ལསརིམ་མིང་:%sà¼" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "ནུས་མེད་ཀྱི་ ཧོསཊི་ནེམà¼" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "ཡིག་སྣོད་ ’%s’:%s གསར་བསà¾à¾²à½´à½“་འབད་མ་ཚུགསà¼" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "ཡིག་སྣོད་ ’%s’:%s གསར་བསà¾à¾²à½´à½“་འབད་མ་ཚུགསà¼" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "ཡིག་སྣོད་ ’%s’:%s གསར་བསà¾à¾²à½´à½“་འབད་མ་ཚུགསà¼" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "སྣོད་à½à½¼à¼‹ '%s':%s à½à¼‹à½•ྱེ་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ ’%s’:%s ལྷག་མ་ཚུགསà¼" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "གདམ་à½à¼‹%s མིང་དཔྱད་འབད་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "ཡིག་ཆ་དེ་ à½à¾±à½‘་ཆོས་ཀྱི་མིང་ཅིག་གི་ནང་ན་ རེ་བ་མེད་པར་རྫོགས་སོ་ནུག" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "སྣོད་à½à½¼à¼‹ '%s':%s à½à¼‹à½•ྱེ་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "གཞི་བསྒྱུར་གྱི་སà¾à½–ས་འཛོལ་བ་ :%s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "གཞི་བསྒྱུར་གྱི་སà¾à½–ས་འཛོལ་བ་ :%s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "གཞི་བསྒྱུར་གྱི་སà¾à½–ས་འཛོལ་བ་ :%s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "གྱལ་རིམ་ %d་: %s ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "གཞི་བསྒྱུར་གྱི་སà¾à½–ས་འཛོལ་བ་ :%s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "གཞི་བསྒྱུར་གྱི་སà¾à½–ས་འཛོལ་བ་ :%s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "གདམ་à½à¼‹%s མིང་དཔྱད་འབད་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +#, fuzzy +msgid "Target file is not a regular file" +msgstr "དུས་རྒྱུན་གྱི་ཡིག་སྣོད་ཅིག་མེན་པསà¼" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "ནུས་མེད་ལསརིམ་མིང་:%sà¼" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "ཤེས་མ་ཚུགས་པའི་གདམ་à½à¼‹ %sà¼" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "ཡིག་སྣོད་ ’%s’:%s གསར་བསà¾à¾²à½´à½“་འབད་མ་ཚུགསà¼" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "ཡིག་སྣོད་à½à½–ས་ལམ་ བསྒྱུར་བཅོས་འབད་མ་ཚུགས་: waitpid() གིས་%s ལུ་མ་བà½à½´à½–à¼" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "གཞི་བསྒྱུར་གྱི་སà¾à½–ས་འཛོལ་བ་ :%s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "ཡིག་སྣོད་ ’%s’:%s གསར་བསà¾à¾²à½´à½“་འབད་མ་ཚུགསà¼" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ཡིག་སྣོད་ ’%s’:%s གསར་བསà¾à¾²à½´à½“་འབད་མ་ཚུགསà¼" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "གྱལ་རིམ་ %d་: %s ལུ་འཛོལ་བà¼" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "གདམ་à½à¼‹%s མིང་དཔྱད་འབད་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "གདམ་à½à¼‹%s མིང་དཔྱད་འབད་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "བརྡ་མཚོན་འགྲེལ་ལམ་ལུ་ རྒྱབ་སà¾à¾±à½¼à½¢à¼‹à½˜à½²à½“་འདུག" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "ནུས་མེད་ཀྱི་ ཧོསཊི་ནེམà¼" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "བསྒྱུར་བཅོས་ཀྱི་ ཨིན་པུཊི་ནང་ལུ་ ནུས་མེད་འབྱུང་རིམ་འདུག" + +#, fuzzy +#~ msgid "[FILE...]" +#~ msgstr "[ གདམ་à½... ] " + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "ངོ་བོའི་མིང་ འགོ་བཙུགས་སར ཡིག་འབྲུ་་ ’%s’ ནུས་མེད་ཨིན་པས༠ཡིག་འབྲུ་ & འདི་གིས་ངོ་བོ་ཅིག་ འགོ་" +#~ "བཙུགསཔ་ཨིན༠གལ་སྲིད་ དང་རྟགས་འདི་ ངོ་བོ་མིནམ་ཅིག་དགོ་པཅིན་ & བཟུམ་ཅིག་སྦེ་ གྲོས་à½à½¢à¼‹à½ à½–དà¼" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "ཡིག་འབྲུ་སྟོང་པའི་འབྲེལ་བ་འདི་ནང་ dž བཟུམ་མའི་ ཨང་ཡིག་ཅིག་འོང་དགོ" + +#~ msgid "Unfinished entity reference" +#~ msgstr "མཇུག་མ་བསྡུ་བའི་ ངོ་བོའི་གཞི་བསྟུནà¼" + +#~ msgid "Unfinished character reference" +#~ msgstr "མཇུག་མ་བསྡུ་བའི་ ཡིག་འབྲུའི་གཞི་བསྟུནà¼" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "ནུས་མེད་ཡུ་ཊི་ཨེཕ་-༨ ཀྱི ཨིན་ཀོ་དེཌི་ཚིག་ཡིག" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "ནུས་མེད་ཡུ་ཊི་ཨེཕ་-༨ ཀྱི ཨིན་ཀོ་དེཌི་ཚིག་ཡིག" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "ཡུ་ཨར་ཨའི་ ’%s’ གི་ ཧོསཊི་ནེམ་དེ་ ནུས་མེད་ཨིན་པསà¼" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "ཡུ་ཨར་ཨའི་ ’%s’ གི་ ཧོསཊི་ནེམ་དེ་ ནུས་མེད་ཨིན་པསà¼" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "ཡིག་སྣོད་ ’%s’: %s ལྷག་ནི་ལུ་འཛོལ་བà¼" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "གདམ་à½à¼‹%s མིང་དཔྱད་འབད་ནི་ལུ་འཛོལ་བà¼" + +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "ཡིག་སྣོད་à½à½–ས་ལམ་ བསྒྱུར་བཅོས་འབད་མ་ཚུགས་: fork() གིས་ %s ལུ་མ་བà½à½´à½–à¼" + +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "ཡིག་སྣོད་à½à½–ས་བསྒྱུར་བཅོས་འབདམ་ཚུགས་: chmod() མ་བà½à½´à½–་:%sà¼" + +#~ msgid "Could not change file mode: Child terminated by signal: %s" +#~ msgstr "" +#~ "ཡིག་སྣོད་à½à½–ས་ལམ་ བསྒྱུར་བཅོས་འབད་མ་ཚུགས་: ཆ་ལག་དེ་ བརྡ་རྟགས་: %s གིས་ རྩ་གྲོལ་བà½à½„་ནུག" + +#~ msgid "Could not change file mode: Child terminated abnormally" +#~ msgstr "ཡིག་སྣོད་à½à½–ས་ལམ་ བསྒྱུར་བཅོས་འབད་མ་ཚུགས་: ཆ་ལག་དེ་ ཚུལ་མིན་à½à½¼à½‚་ལས་ རྩ་གྲོལ་སོང་ནུག" diff --git a/po/el.po b/po/el.po new file mode 100644 index 0000000..9abbb4c --- /dev/null +++ b/po/el.po @@ -0,0 +1,6893 @@ +# translation of glib.HEAD.po to Greek +# Greek translation of glib. +# Copyright (C) 2002, 2004, 2006, 2009 Free Software Foundation, Inc. +# Simos Xenitellis , 2002. +# Kostas Papadimas , 2002. +# Kostas Papadimas , 2004, 2006. +# Jennie Petoumenou , 2009. +# Fotis Tsamis , 2009. +# Michael Kotsarinis , 2011. +# Dimitris Spingos (ΔημήτÏης Σπίγγος) , 2012. +# Dimitris Spingos (ΔημήτÏης Σπίγγος) , 2012, 2013, 2014, 2015. +# Efstathios Iosifidis , 2015. +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2020-07-15 15:47+0000\n" +"PO-Revision-Date: 2020-09-21 23:06+0300\n" +"Last-Translator: Efstathios Iosifidis \n" +"Language-Team: www.gnome.gr\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 2.3\n" +"X-Project-Style: gnome\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Επιλογές GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Εμφάνιση επιλογών GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Εισαγωγή Ï„Ïόπου λειτουÏγίας της εφαÏμογής GApplication (χÏήση από αÏχεία " +"υπηÏεσίας D-Bus)" + +#: gio/gapplication.c:557 +#, fuzzy +#| msgid "Override the application's ID" +msgid "Override the application’s ID" +msgstr "Αντικατάσταση αναγνωÏÎ¹ÏƒÏ„Î¹ÎºÎ¿Ï Ï„Î·Ï‚ εφαÏμογής" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:493 gio/gsettings-tool.c:567 +msgid "Print help" +msgstr "Εμφάνιση βοήθειας" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:494 gio/gresource-tool.c:562 +msgid "[COMMAND]" +msgstr "[ΕÎΤΟΛΗ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Εμφάνιση έκδοσης" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:573 +msgid "Print version information and exit" +msgstr "ΠÏοβολή πληÏοφοÏιών έκδοσης και έξοδος" + +#: gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Κατάλογος εφαÏμογών" + +#: gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Καταλογοποιεί τις εγκατεστημένες ενεÏγοποιήσιμες εφαÏμογές D-Bus (από ." +"desktop files)" + +#: gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "ΈναÏξη εφαÏμογής" + +#: gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "ΈναÏξη της εφαÏμογής (με Ï€ÏοαιÏετικά αÏχεία για άνοιγμα)" + +#: gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "APPID [FILE…]" + +#: gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "ΕνεÏγοποίηση μιας ενέÏγειας" + +#: gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "Κλήση μιας ενέÏγειας στην εφαÏμογή" + +#: gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Κατάλογος διαθέσιμων ενεÏγειών" + +#: gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "Κατάλογος στατικών ενεÏγειών για μια εφαÏμογή (από αÏχείο .desktop)" + +#: gio/gapplication-tool.c:65 gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "ΕÎΤΟΛΗ" + +#: gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "Η εντολή για εκτÏπωση λεπτομεÏοÏÏ‚ βοήθειας για" + +#: gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Το αναγνωÏιστικό εφαÏμογής σε μοÏφή D-Bus (πχ: org.example.viewer)" + +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:500 gio/gresource-tool.c:566 +msgid "FILE" +msgstr "ΑΡΧΕΙΟ" + +#: gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "ΠÏοαιÏετικά σχετικά ή απόλυτα ονόματα αÏχείων, ή URIs για άνοιγμα" + +#: gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "ΕÎΕΡΓΕΙΑ" + +#: gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "Το όνομα ενέÏγειας για κλήση" + +#: gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "ΠΑΡΑΜΕΤΡΟΣ" + +#: gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "ΠÏοαιÏετική παÏάμετÏος στην κλήση ενέÏγειας, στη μοÏφή GVariant" + +#: gio/gapplication-tool.c:96 gio/gresource-tool.c:531 gio/gsettings-tool.c:659 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Άγνωστη εντολή %s\n" +"\n" + +#: gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "ΧÏήση:\n" + +#: gio/gapplication-tool.c:114 gio/gresource-tool.c:556 +#: gio/gsettings-tool.c:694 +msgid "Arguments:\n" +msgstr "ΟÏίσματα:\n" + +#: gio/gapplication-tool.c:133 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS…]" + +#: gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Εντολές:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:146 +#, fuzzy, c-format +#| msgid "" +#| "Use '%s help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ΧÏησιμοποιήστε το '%s help COMMAND' για να πάÏετε λεπτομεÏή βοήθεια.\n" +"\n" + +#: gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Η εντολή %s απαιτεί το αναγνωÏιστικό μιας εφαÏμογής για άμεση παÏακολοÏθηση\n" +"\n" + +#: gio/gapplication-tool.c:171 +#, fuzzy, c-format +#| msgid "invalid application id: '%s'\n" +msgid "invalid application id: “%sâ€\n" +msgstr "άκυÏο αναγνωÏιστικό εφαÏμογής: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:182 +#, fuzzy, c-format +#| msgid "" +#| "'%s' takes no arguments\n" +#| "\n" +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"Το '%s' δεν παίÏνει οÏίσματα\n" +"\n" + +#: gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "αδÏνατη η σÏνδεση με το D-Bus: %s\n" + +#: gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "σφάλμα αποστολής μηνÏματος %s στην εφαÏμογή: %s\n" + +#: gio/gapplication-tool.c:317 +msgid "action name must be given after application id\n" +msgstr "" +"το όνομα της ενέÏγειας Ï€Ïέπει να δοθεί μετά το αναγνωÏιστικό της εφαÏμογής\n" + +#: gio/gapplication-tool.c:325 +#, fuzzy, c-format +#| msgid "" +#| "invalid action name: '%s'\n" +#| "action names must consist of only alphanumerics, '-' and '.'\n" +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"άκυÏο όνομα ενέÏγειας: '%s'\n" +"τα ονόματα ενεÏγειών Ï€Ïέπει να αποτελοÏνται μόνο από αλφαÏιθμητικά, '-' και " +"'.'\n" + +# gconf/gconftool.c:1181 +#: gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "σφάλμα ανάλυσης παÏαμέτÏου ενέÏγειας: %s\n" + +#: gio/gapplication-tool.c:356 +msgid "actions accept a maximum of one parameter\n" +msgstr "οι ενέÏγειες δέχονται το Ï€Î¿Î»Ï Î¼Î¯Î± παÏάμετÏο\n" + +#: gio/gapplication-tool.c:411 +msgid "list-actions command takes only the application id" +msgstr "" +"η εντολή ενεÏγειών καταλόγου παίÏνει μόνο το αναγνωÏιστικό της εφαÏμογής" + +#: gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "αδÏνατη η εÏÏεση αÏχείου επιφάνειας εÏγασίας για την εφαÏμογή %s\n" + +#: gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"μη αναγνωÏίσιμη εντολή: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Η τιμή που διαβιβάστηκε στο %s είναι υπεÏβολικά μεγάλη" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Δεν υποστηÏίζεται η αναζήτηση στη βασική Ïοή" + +#: gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Αδυναμία πεÏικοπής του GMemoryInputStream" + +#: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Η Ïοή έχει ήδη κλείσει" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Δεν υποστηÏίζεται η πεÏικοπή στη βασική Ïοή" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1413 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Η λειτουÏγία ακυÏώθηκε" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "ΆκυÏο αντικείμενο, δεν αÏχικοποιήθηκε" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Ελλιπής σειÏά πολλαπλών byte στην είσοδο" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Μη επαÏκής χώÏος στην πεÏιοχή Ï€ÏοοÏισμοÏ" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:447 glib/gconvert.c:877 +#: glib/giochannel.c:1564 glib/giochannel.c:1606 glib/giochannel.c:2461 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "ΆκυÏη σειÏά byte στην είσοδο μετατÏοπής" + +# gconf/gconftool.c:1181 +#: gio/gcharsetconverter.c:347 glib/gconvert.c:455 glib/gconvert.c:791 +#: glib/giochannel.c:1571 glib/giochannel.c:2473 +#, c-format +msgid "Error during conversion: %s" +msgstr "Σφάλμα κατά τη μετατÏοπή: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1138 +msgid "Cancellable initialization not supported" +msgstr "Δεν υποστηÏίζεται η ακυÏώσιμη αÏχικοποίηση" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:320 glib/giochannel.c:1392 +#, fuzzy, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Η μετατÏοπή από την ομάδα χαÏακτήÏων '%s' σε '%s' δεν υποστηÏίζεται" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:324 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Αδυναμία ανοίγματος μετατÏοπέα από '%s' σε '%s'" + +#: gio/gcontenttype.c:452 +#, c-format +msgid "%s type" +msgstr "ΤÏπος %s" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Άγνωστος Ï„Ïπος" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s Ï„Ïπος αÏχείων" + +#: gio/gcredentials.c:323 +msgid "GCredentials contains invalid data" +msgstr "Το GCredentials πεÏιέχει μη έγκυÏα δεδομένα" + +#: gio/gcredentials.c:383 gio/gcredentials.c:667 +msgid "GCredentials is not implemented on this OS" +msgstr "Το GCredentials δεν έχει υλοποιηθεί σε αυτό το λειτουÏγικό σÏστημα" + +#: gio/gcredentials.c:538 gio/gcredentials.c:556 +msgid "There is no GCredentials support for your platform" +msgstr "Δεν υπάÏχει υποστήÏιξη του GCredentials για το λογισμικό σας" + +#: gio/gcredentials.c:607 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"Το GCredentials δεν πεÏιέχει αναγνωÏιστικό διεÏγασίας σε αυτό το λειτουÏγικό " +"σÏστημα" + +#: gio/gcredentials.c:661 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" +"Το διαπιστευτήÏια αντιποίησης δεν είναι δυνατά σε αυτό το λειτουÏγικό σÏστημα" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Αναπάντεχο Ï€ÏόωÏο τέλος Ïοής" + +#: gio/gdbusaddress.c:158 gio/gdbusaddress.c:232 gio/gdbusaddress.c:321 +#, fuzzy, c-format +#| msgid "Unsupported key '%s' in address entry '%s'" +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "ΑνυποστήÏικτο κλειδί '%s' στην εισαγωγή διεÏθυνσης'%s'" + +#: gio/gdbusaddress.c:171 +#, fuzzy, c-format +#| msgid "Meaningless key/value pair combination in address entry '%s'" +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" +"Συνδυασμός χωÏίς νόημα ζευγαÏÎ¹Î¿Ï ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï/τιμής στην εισαγόμενη διεÏθυνση " +"'%s'" + +#: gio/gdbusaddress.c:180 +#, fuzzy, c-format +#| msgid "" +#| "Address '%s' is invalid (need exactly one of path, tmpdir or abstract " +#| "keys)" +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Η διεÏθυνση '%s' είναι άκυÏη (χÏειάζεται ακÏιβώς μια διαδÏομή, tmpdir ή " +"αφηÏημένα κλειδιά)" + +#: gio/gdbusaddress.c:247 gio/gdbusaddress.c:258 gio/gdbusaddress.c:273 +#: gio/gdbusaddress.c:336 gio/gdbusaddress.c:347 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the port attribute is malformed" +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Σφάλμα στη διεÏθυνση '%s' - η ιδιότητα θÏÏας είναι κακοδιατυπωμένη" + +#: gio/gdbusaddress.c:417 gio/gdbusaddress.c:681 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Άγνωστη ή ανυποστήÏικτη μεταφοÏά «%s» για τη διεÏθυνση «%s»" + +#: gio/gdbusaddress.c:461 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Το στοιχείο διευθÏνσεως «%s» δεν πεÏιέχει διπλή στιγμή (:)" + +#: gio/gdbusaddress.c:470 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:491 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Το δίδυμο κλειδί/τιμή %d, «%s», στο στοιχείο διεÏθυνσης «%s» δεν πεÏιέχει " +"τον τελεστή ίσον" + +#: gio/gdbusaddress.c:502 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Το δίδυμο κλειδί/τιμή %d, «%s», στο στοιχείο διεÏθυνσης «%s» δεν πεÏιέχει " +"τον τελεστή ίσον" + +#: gio/gdbusaddress.c:516 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Σφάλμα στη μη διαφυγή του ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Î® της τιμής στο δίδυμο κλειδί/τιμή %d, " +"«%s», στο στοιχείο διεÏθυνσης «%s»" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Σφάλμα στη διεÏθυνση «%s» — ο μεταφοÏέας unix απαιτεί ακÏιβώς ένα από τα " +"κλειδιά «path» ή «abstract» να οÏιστοÏν" + +#: gio/gdbusaddress.c:624 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Σφάλμα στη διεÏθυνση «%s» — η ιδιότητα κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î® λείπει ή είναι " +"κακοδιατυπωμένη" + +#: gio/gdbusaddress.c:638 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Σφάλμα στη διεÏθυνση «%s» — η ιδιότητα θÏÏας λείπει ή είναι κακοδιατυπωμένη" + +#: gio/gdbusaddress.c:652 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Σφάλμα στη διεÏθυνση «%s» — η ιδιότητα του παÏόντος αÏχείου λείπει ή είναι " +"κακοδιατυπωμένη" + +# +#: gio/gdbusaddress.c:673 +msgid "Error auto-launching: " +msgstr "Σφάλμα αυτόματης εκκίνησης: " + +# +#: gio/gdbusaddress.c:726 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Σφάλμα ανοίγματος παÏόντος αÏχείου «%s»: %s" + +# +#: gio/gdbusaddress.c:745 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Σφάλμα ανάγνωσης από το παÏόν αÏχείο «%s»: %s" + +# +#: gio/gdbusaddress.c:754 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Σφάλμα ανάγνωσης από το παÏόν αÏχείο «%s», αναμενόμενες 16 bytes, " +"παÏαλήφθηκαν %d" + +#: gio/gdbusaddress.c:772 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Σφάλμα εγγÏαφής πεÏιεχομένου του παÏόντος αÏχείου «%s» στην Ïοή:" + +#: gio/gdbusaddress.c:981 +msgid "The given address is empty" +msgstr "Η δεδομένη διεÏθυνση είναι κενή" + +#: gio/gdbusaddress.c:1094 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Αδυναμία δημιουÏγίας διαÏλου μηνυμάτων όταν χÏησιμοποιείται setuid" + +#: gio/gdbusaddress.c:1101 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Αδυναμία δημιουÏγίας διαÏλου μηνυμάτων χωÏίς ταυτότητα μηχανήματος: " + +#: gio/gdbusaddress.c:1108 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +# +#: gio/gdbusaddress.c:1150 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Σφάλμα δημιουÏγίας στη γÏαμμή εντολών «%s»: " + +#: gio/gdbusaddress.c:1219 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Αδυναμία καθοÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ διεÏθυνσης διαÏλου συνόδου (μη υλοποιημένος σε αυτό " +"το λειτουÏγικό)" + +#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7192 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Αδυναμία καθοÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ διεÏθυνση διαÏλου από την μεταβλητή πεÏιβάλλοντος " +"DBUS_STARTER_BUS_TYPE - άγνωστη τιμή «%s»" + +#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7201 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Αδυναμία καθοÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ διεÏθυνσης διαÏλου επειδή η μεταβλητή πεÏιβάλλοντος " +"DBUS_STARTER_BUS_TYPE δεν είναι οÏισθεί" + +#: gio/gdbusaddress.c:1376 +#, c-format +msgid "Unknown bus type %d" +msgstr "Άγνωστος Ï„Ïπος διαÏλου %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "" +"ΑπÏοσδόκητη έλλειψη πεÏιεχομένου κατά την Ï€Ïοσπάθεια ανάγνωσης μιας γÏαμμής" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"ΑπÏοσδόκητη έλλειψη πεÏιεχομένου που Ï€Ïοσπαθεί (με ασφάλεια) να διαβάσει μια " +"γÏαμμή" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Εξάντληση όλων των διαθέσιμων μηχανισμών επικÏÏωσης (χÏησιμοποιήθηκε: %s) " +"(διαθέσιμο: %s)" + +#: gio/gdbusauth.c:1167 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "ΑκυÏώθηκε μέσω του GDBusAuthObserver::authorize-authenticated-peer" + +# +#: gio/gdbusauthmechanismsha1.c:265 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Σφάλμα λήψης πληÏοφοÏίας του καταλόγου «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:280 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Δικαιώματα στον κατάλογο «%s» είναι κακοδιατυπωμένα. Αναμενόμενη κατάσταση " +"0700, ελήφθη 0%o" + +#: gio/gdbusauthmechanismsha1.c:310 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Σφάλμα δημιουÏγίας καταλόγου «%s»: %s" + +# +#: gio/gdbusauthmechanismsha1.c:355 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Σφάλμα ανοίγματος της κλειδοθήκης «%s» για ανάγνωση: " + +#: gio/gdbusauthmechanismsha1.c:378 gio/gdbusauthmechanismsha1.c:700 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Η γÏαμμή %d από την κλειδοθήκη στο «%s» με το πεÏιεχόμενο «%s» είναι " +"κακοδιατυπωμένη" + +#: gio/gdbusauthmechanismsha1.c:392 gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Το Ï€Ïώτο σημείο της γÏαμμής %d της κλειδοθήκης στο «%s» με πεÏιεχόμενο «%s» " +"είναι κακοδιατυπωμένο" + +#: gio/gdbusauthmechanismsha1.c:406 gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Το δεÏτεÏο διακÏιτικό της γÏαμμής %d της κλειδοθήκης στο «%s» με πεÏιεχόμενο " +"«%s» είναι κακοδιατυπωμένο" + +#: gio/gdbusauthmechanismsha1.c:430 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Δεν βÏήκε το cookie με ταυτότητα %d στη κλειδοθήκη στο «%s»" + +# +#: gio/gdbusauthmechanismsha1.c:476 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Σφάλμα δημιουÏγίας αÏχείου κλειδαÏιών «%s»: %s" + +# +#: gio/gdbusauthmechanismsha1.c:540 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Σφάλμα διαγÏαφής ξεπεÏασμένου αÏχείου κλειδαÏιών «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:579 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Σφάλμα στο κλείσιμο (αποσυνδεμένου) αÏχείου κλειδαÏιών «%s»: %s" + +# +#: gio/gdbusauthmechanismsha1.c:590 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Σφάλμα αποσÏνδεσης αÏχείου κλειδαÏιών «%s»: %s" + +# +#: gio/gdbusauthmechanismsha1.c:667 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Σφάλμα στο άνοιγμα της κλειδοθήκης «%s» για εγγÏαφή: " + +#: gio/gdbusauthmechanismsha1.c:863 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Επιπλέον, απελευθεÏώνοντας το κλείδωμα για «%s» απέτυχε επίσης: %s) " + +#: gio/gdbusconnection.c:595 gio/gdbusconnection.c:2391 +msgid "The connection is closed" +msgstr "Η σÏνδεση είναι κλειστή" + +#: gio/gdbusconnection.c:1892 +msgid "Timeout was reached" +msgstr "Έφτασε ο χÏόνος λήξης" + +#: gio/gdbusconnection.c:2513 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Î’Ïέθηκαν ανυποστήÏικτες σημαίες κατά την κατασκευή μίας client-side σÏνδεσης" + +#: gio/gdbusconnection.c:4163 gio/gdbusconnection.c:4510 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Καμία τέτοια διεπαφή «org.freedesktop.DBus.Properties» στο αντικείμενο στη " +"διαδÏομή %s" + +#: gio/gdbusconnection.c:4305 +#, c-format +msgid "No such property “%sâ€" +msgstr "Δεν υπάÏχει η ιδιότητα «%s»" + +#: gio/gdbusconnection.c:4317 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Η ιδιότητα «%s» δεν είναι αναγνώσιμη" + +#: gio/gdbusconnection.c:4328 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Η ιδιότητα «%s» δεν είναι εγγÏάψιμη" + +#: gio/gdbusconnection.c:4348 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Σφάλμα ÏÏθμισης της ιδιότητας «%s»: Αναμενόμενος Ï„Ïπος «%s» αλλά βÏήκε «%s»" + +#: gio/gdbusconnection.c:4453 gio/gdbusconnection.c:4661 +#: gio/gdbusconnection.c:6632 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Δεν υπάÏχει η διεπαφή «%s»" + +#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7141 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Δεν υπάÏχει η διεπαφή «%s» στο αντικείμενο στην διαδÏομή %s" + +#: gio/gdbusconnection.c:4977 +#, c-format +msgid "No such method “%sâ€" +msgstr "Δεν υπάÏχει η μέθοδος «%s»" + +#: gio/gdbusconnection.c:5008 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Ο Ï„Ïπος μηνÏματος, «%s», δεν ταιÏιάζει με τον αναμενόμενο Ï„Ïπο «%s»" + +#: gio/gdbusconnection.c:5206 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Ένα αντικείμενο έχει εξαχθεί ήδη για τη διεπαφή %s στο %s" + +# gconf/gconf-internals.c:2416 +#: gio/gdbusconnection.c:5432 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Αδυναμία ανάκτησης της ιδιότητας %s.%s" + +# gconf/gconf-internals.c:2416 +#: gio/gdbusconnection.c:5488 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Αδυναμία οÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ ιδιότητας %s.%s" + +#: gio/gdbusconnection.c:5666 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Η μέθοδος «%s» επέστÏεψε τον Ï„Ïπο «%s», αλλά αναμενόταν «%s»" + +#: gio/gdbusconnection.c:6743 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Η μέθοδος «%s» στη διεπαφή «%s» με υπογÏαφή «%s» δεν υπάÏχει" + +#: gio/gdbusconnection.c:6864 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Ένα υποδένδÏο εξάγεται ήδη για %s" + +#: gio/gdbusmessage.c:1255 +msgid "type is INVALID" +msgstr "ο Ï„Ïπος είναι ΑΚΥΡΟΣ" + +#: gio/gdbusmessage.c:1266 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Μήνυμα METHOD_CALL: το πεδίο κεφαλίδας PATH ή MEMBER λείπει" + +#: gio/gdbusmessage.c:1277 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Μήνυμα METHOD_RETURN: το πεδίο κεφαλίδας REPLY_SERIAL λείπει" + +#: gio/gdbusmessage.c:1289 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Μήνυμα σφάλματος: το πεδίο κεφαλίδας REPLY_SERIAL ή ERROR_NAME λείπει" + +#: gio/gdbusmessage.c:1302 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Μήνυμα σήματος: το πεδίο κεφαλίδας PATH, INTERFACE ή MEMBER λείπει" + +#: gio/gdbusmessage.c:1310 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Μήνυμα ΣΗΜΑΤΟΣ: Το πεδίο κεφαλίδας PATH χÏησιμοποιεί τη δεσμευμένη τιμή /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1318 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Μήνυμα σήματος: Το πεδίο κεφαλίδας INTERFACE χÏησιμοποιεί τη δεσμευμένη τιμή " +"org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Απαίτηση για ανάγνωση %lu byte αλλά ελήφθη μόνο %lu" +msgstr[1] "Απαίτηση για ανάγνωση %lu bytes αλλά ελήφθησαν μόνο %lu" + +#: gio/gdbusmessage.c:1380 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"Αναμενόμενo byte NUL μετά από τη συμβολοσειÏά «%s» αλλά βÏέθηκε byte %d" + +#: gio/gdbusmessage.c:1399 +#, fuzzy, c-format +#| msgid "" +#| "Expected valid UTF-8 string but found invalid bytes at byte offset %d " +#| "(length of string is %d). The valid UTF-8 string up until that point was " +#| "'%s'" +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Αναμενόταν έγκυÏh συμβολοσειÏά UTF-8 αλλά βÏέθηκαν άκυÏα bytes στη " +"μετατόπιση byte %d (μήκος thw συμβολοσειÏάς %d). Η έγκυÏη συμβολοσειÏά UTF-8 " +"μέχÏι εκείνο το σημείο ήταν '%s'" + +#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Η αναλυμένη τιμή «%s» δεν είναι αποδεκτή διαδÏομή αντικειμένου D-Bus" + +#: gio/gdbusmessage.c:1631 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Η αναλυμένη τιμή «%s» δεν είναι έγκυÏη υπογÏαφή D-Bus" + +#: gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Î’Ïέθηκε πίνακας μήκους %u byte. Μέγιστο μήκος είναι 2<<26 bytes (64 MiB)." +msgstr[1] "" +"Î’Ïέθηκε πίνακας μήκους %u bytes. Μέγιστο μήκος είναι 2<<26 bytes (64 MiB)." + +#: gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Î’Ïέθηκε πίνακας Ï„Ïπου «a%c», αναμενόταν να έχει μήκος πολλαπλάσιο από %u " +"bytes, αλλά βÏέθηκε να έχει μήκος %u bytes" + +#: gio/gdbusmessage.c:1884 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"Η αναλυμένη τιμή «%s» για την παÏαλλαγή δεν είναι αποδεκτή υπογÏαφή D-Bus" + +#: gio/gdbusmessage.c:1925 +#, fuzzy, c-format +#| msgid "" +#| "Error deserializing GVariant with type string '%s' from the D-Bus wire " +#| "format" +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Σφάλμα αποσειÏιοποίησης GVariant με τον Ï„Ïπο συμβολοσειÏάς '%s' από τη μοÏφή " +"καλωδίου D-Bus" + +#: gio/gdbusmessage.c:2110 +#, fuzzy, c-format +#| msgid "" +#| "Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found " +#| "value 0x%02x" +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"ΆκυÏη τιμή διάταξης ψηφιολέξεων. Αναμενόμενη 0x6c ('l') ή 0x42 ('B') αλλά " +"βÏέθηκε η τιμή 0x%02x" + +#: gio/gdbusmessage.c:2123 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "ΆκυÏη κÏÏια έκδοση Ï€Ïωτοκόλλου. Αναμενόμενη 1 αλλά βÏέθηκε %d" + +#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2189 +#, fuzzy, c-format +#| msgid "Signature header with signature '%s' found but message body is empty" +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Η κεφαλίδα υπογÏαφών με υπογÏαφή '%s' βÏέθηκε αλλά το σώμα του μηνÏματος " +"είναι κενό" + +#: gio/gdbusmessage.c:2204 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Η αναλυμένη τιμή «%s» δεν είναι αποδεκτή υπογÏαφή D-Bus (για το σώμα)" + +#: gio/gdbusmessage.c:2236 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Δεν υπάÏχει κεφαλίδα υπογÏαφών στο μήνυμα αλλά το σώμα του μηνυμάτων είναι " +"%u byte" +msgstr[1] "" +"Δεν υπάÏχει κεφαλίδα υπογÏαφών στο μήνυμα αλλά το σώμα του μηνυμάτων είναι " +"%u bytes" + +#: gio/gdbusmessage.c:2246 +msgid "Cannot deserialize message: " +msgstr "Αδυναμία αποσειÏιοποίησης μηνÏματος: " + +#: gio/gdbusmessage.c:2590 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Σφάλμα στην σειÏιακή διάταξη GVariant με Ï„Ïπο συμβολοσειÏάς «%s» στην μοÏφή " +"δικτυώματος D-Bus" + +#: gio/gdbusmessage.c:2727 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2735 +msgid "Cannot serialize message: " +msgstr "Αδυναμία σειÏιακής διάταξης μηνÏματος: " + +#: gio/gdbusmessage.c:2788 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Το σώμα του μηνÏματος έχει υπογÏαφή «%s» αλλά δεν υπάÏχει κεφαλίδα υπογÏαφής" + +#: gio/gdbusmessage.c:2798 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Το σώμα του μηνÏματος έχει την υπογÏαφή Ï„Ïπου «%s» αλλά η υπογÏαφή στο πεδίο " +"κεφαλίδας είναι «%s»" + +#: gio/gdbusmessage.c:2814 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"Το σώμα του μηνÏματος είναι κενό αλλά η υπογÏαφή στο πεδίο κεφαλίδας είναι " +"«(%s)»" + +#: gio/gdbusmessage.c:3367 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Σφάλμα επιστÏοφής με σώμα Ï„Ïπου «%s»" + +#: gio/gdbusmessage.c:3375 +msgid "Error return with empty body" +msgstr "ΕπιστÏοφή σφάλματος με κενό σώμα" + +#: gio/gdbusprivate.c:2244 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" +"(ΠληκτÏολογήστε οποιοδήποτε χαÏακτήÏα για να κλείσετε αυτό το παÏάθυÏο)\n" + +#: gio/gdbusprivate.c:2418 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Η σÏνοδος dbus δεν εκτελείται και η αυτόματη εκκίνηση απέτυχε" + +# gconf/gconf-internals.c:2416 +#: gio/gdbusprivate.c:2441 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "ΑδÏνατη η λήψη κατατομής υλικοÏ: %s" + +#: gio/gdbusprivate.c:2486 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Αδυναμία φόÏτωσης /var/lib/dbus/machine-id ή /etc/machine-id: " + +#: gio/gdbusproxy.c:1562 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Σφάλμα στην κλήση StartServiceByName για το %s: " + +#: gio/gdbusproxy.c:1585 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "ΑπÏοσδόκητη απάντηση %d από την μέθοδο StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2688 gio/gdbusproxy.c:2823 +#, fuzzy, c-format +#| msgid "" +#| "Cannot invoke method; proxy is for a well-known name without an owner and " +#| "proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Αδυναμία επίκλησης της μεθόδου· ο διαμεσολαβητής είναι για ένα γνωστό όνομα " +"χωÏίς ιδιοκτήτη και ο διαμεσολαβητής δημιουÏγήθηκε με την σημαία " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:755 +#, fuzzy +#| msgid "Abstract name space not supported" +msgid "Abstract namespace not supported" +msgstr "Δεν υποστηÏίζονται αφηÏημένα ονόματα χώÏου" + +#: gio/gdbusserver.c:848 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Αδυναμία διευκÏίνισης του Ï„Ïέχοντος αÏχείου κατά τη δημιουÏγία διακομιστή" + +#: gio/gdbusserver.c:930 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Σφάλμα εγγÏαφής στο παÏόν αÏχείο στο «%s»: %s" + +#: gio/gdbusserver.c:1103 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Η συμβολοσειÏά «%s» δεν είναι αποδεκτό D-Bus GUID" + +#: gio/gdbusserver.c:1143 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Αδυναμία ακÏόασης στην ανυποστήÏικτη μεταφοÏά «%s»" + +#: gio/gdbus-tool.c:107 +#, fuzzy, c-format +#| msgid "" +#| "Commands:\n" +#| " help Shows this information\n" +#| " introspect Introspect a remote object\n" +#| " monitor Monitor a remote object\n" +#| " call Invoke a method on a remote object\n" +#| " emit Emit a signal\n" +#| "\n" +#| "Use \"%s COMMAND --help\" to get help on each command.\n" +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Εντολές:\n" +" help ΠαÏουσιάζει αυτές τις πληÏοφοÏίες\n" +" introspect Ενδοσκόπηση ενός μακÏÎ¹Î½Î¿Ï Î±Î½Ï„Î¹ÎºÎµÎ¹Î¼Î­Î½Î¿Ï…\n" +" monitor ΠαÏακολοÏθηση ενός μακÏÎ¹Î½Î¿Ï Î±Î½Ï„Î¹ÎºÎµÎ¹Î¼Î­Î½Î¿Ï…\n" +" call Καλέστε μια μέθοδο επάνω ένα μακÏινό αντικείμενο\n" +" emit Εκπομπή σήματος\n" +"\n" +"ΧÏησιμοποιείστε \"%s COMMAND --help\" για λήψη βοήθειας για κάθε εντολή.\n" + +# +#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336 +#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:850 gio/gdbus-tool.c:1187 +#: gio/gdbus-tool.c:1672 +#, c-format +msgid "Error: %s\n" +msgstr "Σφάλμα: %s\n" + +# gconf/gconftool.c:1181 +#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1688 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Ενδοσκόπηση της ανάλυσης λάθους XML: %s\n" + +#: gio/gdbus-tool.c:246 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Σφάλμα: το %s δεν είναι έγκυÏο όνομα\n" + +#: gio/gdbus-tool.c:394 +msgid "Connect to the system bus" +msgstr "ΣÏνδεση με το δίαυλο συστήματος" + +#: gio/gdbus-tool.c:395 +msgid "Connect to the session bus" +msgstr "ΣÏνδεση με το δίαυλο συνόδου" + +#: gio/gdbus-tool.c:396 +msgid "Connect to given D-Bus address" +msgstr "ΣÏνδεση με δεδομένη διεÏθυνση D-Bus" + +#: gio/gdbus-tool.c:406 +msgid "Connection Endpoint Options:" +msgstr "Επιλογές σημείου τέλους σÏνδεσης:" + +#: gio/gdbus-tool.c:407 +msgid "Options specifying the connection endpoint" +msgstr "Οι επιλογές που διευκÏινίζουν το σημείο τέλους σÏνδεσης" + +#: gio/gdbus-tool.c:430 +#, c-format +msgid "No connection endpoint specified" +msgstr "Δεν διευκÏινίζεται σημείο τέλους σÏνδεσης" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "ΔιευκÏινίστηκαν πολλαπλά σημεία τέλους σÏνδεσης" + +#: gio/gdbus-tool.c:513 +#, fuzzy, c-format +#| msgid "" +#| "Warning: According to introspection data, interface '%s' does not exist\n" +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"ΠÏοειδοποίηση: ΣÏμφωνα με τα στοιχεία ενδοσκόπησης, η διεπαφή '%s' δεν " +"υπάÏχει\n" + +#: gio/gdbus-tool.c:522 +#, fuzzy, c-format +#| msgid "" +#| "Warning: According to introspection data, method '%s' does not exist on " +#| "interface '%s'\n" +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"ΠÏοειδοποίηση: ΣÏμφωνα με τα στοιχεία ενδοσκόπησης, η μέθοδος '%s' δεν " +"υπάÏχει στη διεπαφή '%s'\n" + +#: gio/gdbus-tool.c:584 +msgid "Optional destination for signal (unique name)" +msgstr "ΠÏοαιÏετικός Ï€ÏοοÏισμός για σήμα (μοναδικό όνομα)" + +#: gio/gdbus-tool.c:585 +msgid "Object path to emit signal on" +msgstr "Η διαδÏομή αντικειμένου για εκπομπή σήματος" + +#: gio/gdbus-tool.c:586 +msgid "Signal and interface name" +msgstr "Σήμα και όνομα διεπαφής" + +#: gio/gdbus-tool.c:619 +msgid "Emit a signal." +msgstr "Εκπομπή σήματος." + +#: gio/gdbus-tool.c:674 gio/gdbus-tool.c:981 gio/gdbus-tool.c:1775 +#: gio/gdbus-tool.c:2007 gio/gdbus-tool.c:2227 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Σφάλμα σÏνδεσης: %s\n" + +#: gio/gdbus-tool.c:694 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Σφάλμα: το %s δεν είναι έγκυÏο μοναδικό όνομα διαÏλου.\n" + +#: gio/gdbus-tool.c:713 gio/gdbus-tool.c:1024 gio/gdbus-tool.c:1818 +msgid "Error: Object path is not specified\n" +msgstr "Σφάλμα: αδιευκÏίνιστη διαδÏομή αντικειμένου\n" + +#: gio/gdbus-tool.c:736 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1838 +#: gio/gdbus-tool.c:2078 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Σφάλμα: το %s δεν είναι έγκυÏη διαδÏομή αντικειμένου\n" + +#: gio/gdbus-tool.c:756 +#, fuzzy +#| msgid "Error: Method name is not specified\n" +msgid "Error: Signal name is not specified\n" +msgstr "Σφάλμα: αδιευκÏίνιστο όνομα μεθόδου\n" + +#: gio/gdbus-tool.c:770 +#, fuzzy, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Σφάλμα: Το όνομα μεθόδου «%s» είναι άκυÏο\n" + +#: gio/gdbus-tool.c:782 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Σφάλμα: Το %s δεν είναι έγκυÏο όνομα διεπαφής\n" + +#: gio/gdbus-tool.c:788 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Σφάλμα: το %s δεν είναι έγκυÏο όνομα μέλους\n" + +# gconf/gconftool.c:1181 +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:825 gio/gdbus-tool.c:1156 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Σφάλμα ανάλυσης παÏαμέτÏου %d: %s\n" + +# gconf/gconftool.c:1181 +#: gio/gdbus-tool.c:857 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Σφάλμα εκκένωσης σÏνδεσης: %s\n" + +#: gio/gdbus-tool.c:884 +msgid "Destination name to invoke method on" +msgstr "Το όνομα Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï Î³Î¹Î± την κλήση της μεθόδου" + +#: gio/gdbus-tool.c:885 +msgid "Object path to invoke method on" +msgstr "Η διαδÏομή αντικειμένου για κλήση της μεθόδου" + +#: gio/gdbus-tool.c:886 +msgid "Method and interface name" +msgstr "Μέθοδος και όνομα διεπαφής" + +#: gio/gdbus-tool.c:887 +msgid "Timeout in seconds" +msgstr "Ο χÏόνος λήξης σε δευτεÏόλεπτα" + +#: gio/gdbus-tool.c:926 +msgid "Invoke a method on a remote object." +msgstr "Κλήση μεθόδου σε απομακÏυσμένο αντικείμενο." + +#: gio/gdbus-tool.c:998 gio/gdbus-tool.c:1792 gio/gdbus-tool.c:2032 +msgid "Error: Destination is not specified\n" +msgstr "Σφάλμα: αδιευκÏίνιστος Ï€ÏοοÏισμός\n" + +#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1809 gio/gdbus-tool.c:2043 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Σφάλμα: το %s δεν είναι έγκυÏο όνομα διαÏλου\n" + +#: gio/gdbus-tool.c:1059 +msgid "Error: Method name is not specified\n" +msgstr "Σφάλμα: αδιευκÏίνιστο όνομα μεθόδου\n" + +#: gio/gdbus-tool.c:1070 +#, fuzzy, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Method name “%s†is invalid\n" +msgstr "Σφάλμα: Το όνομα μεθόδου '%s' είναι άκυÏο\n" + +# +#: gio/gdbus-tool.c:1148 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d of type '%s': %s\n" +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Σφάλμα στην ανάλυσης παÏαμέτÏου %d του Ï„Ïπου '%s': %s\n" + +#: gio/gdbus-tool.c:1634 +msgid "Destination name to introspect" +msgstr "Όνομα Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï Î³Î¹Î± ενδοσκόπηση" + +#: gio/gdbus-tool.c:1635 +msgid "Object path to introspect" +msgstr "ΔιαδÏομή αντικειμένου για ενδοσκόπηση" + +#: gio/gdbus-tool.c:1636 +msgid "Print XML" +msgstr "ΕκτÏπωση XML" + +#: gio/gdbus-tool.c:1637 +msgid "Introspect children" +msgstr "Ενδοσκόπηση θυγατÏικής" + +#: gio/gdbus-tool.c:1638 +msgid "Only print properties" +msgstr "Μόνο ιδιότητες εκτÏπωσης" + +#: gio/gdbus-tool.c:1727 +msgid "Introspect a remote object." +msgstr "Ενδοσκόπηση απομακÏυσμένου αντικειμένου." + +#: gio/gdbus-tool.c:1933 +msgid "Destination name to monitor" +msgstr "Όνομα Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï Î³Î¹Î± έλεγχο" + +#: gio/gdbus-tool.c:1934 +msgid "Object path to monitor" +msgstr "Η διαδÏομή αντικειμένου για έλεγχο" + +#: gio/gdbus-tool.c:1959 +msgid "Monitor a remote object." +msgstr "Έλεγχος απομακÏυσμένου αντικειμένου." + +#: gio/gdbus-tool.c:2017 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: gio/gdbus-tool.c:2141 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2144 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: gio/gdbus-tool.c:2192 +msgid "[OPTION…] BUS-NAME" +msgstr "" + +#: gio/gdbus-tool.c:2193 +msgid "Wait for a bus name to appear." +msgstr "Αναμονή να εμφανιστεί ένα όνομα διαÏλου." + +#: gio/gdbus-tool.c:2269 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to activate for must be specified.\n" +msgstr "Σφάλμα: αδιευκÏίνιστη διαδÏομή αντικειμένου.\n" + +#: gio/gdbus-tool.c:2274 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to wait for must be specified.\n" +msgstr "Σφάλμα: αδιευκÏίνιστη διαδÏομή αντικειμένου.\n" + +#: gio/gdbus-tool.c:2279 +msgid "Error: Too many arguments.\n" +msgstr "" + +#: gio/gdbus-tool.c:2287 gio/gdbus-tool.c:2294 +#, fuzzy, c-format +#| msgid "Error: %s is not a valid bus name\n" +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Σφάλμα: το %s δεν είναι έγκυÏο όνομα διαÏλου\n" + +#: gio/gdesktopappinfo.c:2071 gio/gdesktopappinfo.c:4885 +msgid "Unnamed" +msgstr "Ανώνυμο" + +#: gio/gdesktopappinfo.c:2481 +#, fuzzy +#| msgid "Desktop file didn't specify Exec field" +msgid "Desktop file didn’t specify Exec field" +msgstr "Το αÏχείο επιφάνειας εÏγασίας δεν ÏŒÏισε πεδίο Exec" + +#: gio/gdesktopappinfo.c:2761 +msgid "Unable to find terminal required for application" +msgstr "Αδυναμία εÏÏεσης του απαιτοÏμενου τεÏÎ¼Î±Ï„Î¹ÎºÎ¿Ï Î³Î¹Î± την εφαÏμογή" + +#: gio/gdesktopappinfo.c:3412 +#, fuzzy, c-format +#| msgid "Can't create user application configuration folder %s: %s" +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Αδυναμία δημιουÏγίας φακέλου Ïυθμίσεων εφαÏμογής %s: %s" + +#: gio/gdesktopappinfo.c:3416 +#, fuzzy, c-format +#| msgid "Can't create user MIME configuration folder %s: %s" +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Αδυναμία δημιουÏγίας φακέλου Ïυθμίσεων MIME %s: %s" + +#: gio/gdesktopappinfo.c:3656 gio/gdesktopappinfo.c:3680 +msgid "Application information lacks an identifier" +msgstr "Οι πληÏοφοÏίες εφαÏμογής στεÏοÏνται ταυτοποιητή" + +#: gio/gdesktopappinfo.c:3914 +#, fuzzy, c-format +#| msgid "Can't create user desktop file %s" +msgid "Can’t create user desktop file %s" +msgstr "Αδυναμία δημιουÏγίας αÏχείου επιφάνειας εÏγασίας %s" + +#: gio/gdesktopappinfo.c:4048 +#, c-format +msgid "Custom definition for %s" +msgstr "ΠÏοσαÏμοσμένος οÏισμός του %s" + +#: gio/gdrive.c:417 +#, fuzzy +#| msgid "drive doesn't implement eject" +msgid "drive doesn’t implement eject" +msgstr "ο οδηγός δεν υποστηÏίζει εξαγωγή" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +#, fuzzy +#| msgid "drive doesn't implement eject or eject_with_operation" +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "η μονάδα δίσκου δεν υποστηÏίζει εξαγωγή ή eject_with_operation" + +#: gio/gdrive.c:571 +#, fuzzy +#| msgid "drive doesn't implement polling for media" +msgid "drive doesn’t implement polling for media" +msgstr "ο οδηγός δεν υποστηÏίζει αναζήτηση πολυμέσων" + +#: gio/gdrive.c:778 +#, fuzzy +#| msgid "drive doesn't implement start" +msgid "drive doesn’t implement start" +msgstr "ο οδηγός δεν υποστηÏίζει έναÏξη" + +#: gio/gdrive.c:880 +#, fuzzy +#| msgid "drive doesn't implement stop" +msgid "drive doesn’t implement stop" +msgstr "ο οδηγός δεν υποστηÏίζει τεÏματισμό" + +#: gio/gdtlsconnection.c:1120 gio/gtlsconnection.c:921 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Η υποστήÏιξη TLS δεν είναι διαθέσιμη" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Η υποστήÏιξη DTLS δεν είναι διαθέσιμη" + +#: gio/gemblem.c:323 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GEmblem encoding" +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Αδυναμία χειÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ έκδοσης %d της κωδικοποίησης GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Κακοδιατυπωμένος αÏιθμός κουπονιών (%d) στην κωδικοποίηση GEmblem" + +#: gio/gemblemedicon.c:362 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GEmblemedIcon encoding" +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Αδυναμία χειÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ έκδοσης %d της κωδικοποίησης GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" +"Κακοδιατυπωμένος αÏιθμός κουπονιών (%d) στην κωδικοποίηση GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Αναμενόταν GEmblem για το GEmblemedIcon" + +#: gio/gfile.c:1044 gio/gfile.c:1282 gio/gfile.c:1420 gio/gfile.c:1658 +#: gio/gfile.c:1713 gio/gfile.c:1771 gio/gfile.c:1855 gio/gfile.c:1912 +#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3722 gio/gfile.c:3777 +#: gio/gfile.c:4055 gio/gfile.c:4523 gio/gfile.c:4934 gio/gfile.c:5019 +#: gio/gfile.c:5109 gio/gfile.c:5206 gio/gfile.c:5293 gio/gfile.c:5394 +#: gio/gfile.c:8104 gio/gfile.c:8194 gio/gfile.c:8278 +#: gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "ΑνυποστήÏικτη λειτουÏγία" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1543 +msgid "Containing mount does not exist" +msgstr "Δεν υπάÏχει η πεÏιέχουσα Ï€ÏοσάÏτηση" + +#: gio/gfile.c:2590 gio/glocalfile.c:2435 +#, fuzzy +#| msgid "Can't copy over directory" +msgid "Can’t copy over directory" +msgstr "Αδυναμία αντιγÏαφής σε κατάλογο" + +#: gio/gfile.c:2650 +#, fuzzy +#| msgid "Can't copy directory over directory" +msgid "Can’t copy directory over directory" +msgstr "Αδυναμία αντιγÏαφής καταλόγου σε κατάλογο" + +#: gio/gfile.c:2658 +msgid "Target file exists" +msgstr "Το αÏχείο Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï Ï…Ï€Î¬Ïχει" + +#: gio/gfile.c:2677 +#, fuzzy +#| msgid "Can't recursively copy directory" +msgid "Can’t recursively copy directory" +msgstr "Αδυναμία αναδÏομικής αντιγÏαφής καταλόγου" + +#: gio/gfile.c:2952 +msgid "Splice not supported" +msgstr "Η αÏμολόγηση δεν υποστηÏίζεται" + +#: gio/gfile.c:2956 gio/gfile.c:3001 +#, c-format +msgid "Error splicing file: %s" +msgstr "Σφάλμα αÏμολόγησης αÏχείου: %s" + +#: gio/gfile.c:3117 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"Δεν υποστηÏίζεται η αντιγÏαφή (συνδέσμου αναφοÏάς/κλώνου) Î¼ÎµÏ„Î±Î¾Ï Ï€ÏοσαÏτήσεων" + +#: gio/gfile.c:3121 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" +"Η αντιγÏαφή (συνδέσμου αναφοÏάς/κλώνου) δεν υποστηÏίζεται ή είναι άκυÏη" + +#: gio/gfile.c:3126 +#, fuzzy +#| msgid "Copy (reflink/clone) is not supported or didn't work" +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" +"Η αντιγÏαφή (συνδέσμου αναφοÏάς/κλώνου) δεν υποστηÏίζεται ή δεν δοÏλεψε" + +#: gio/gfile.c:3190 +msgid "Can’t copy special file" +msgstr "Αδυναμία αντιγÏαφής του ÎµÎ¹Î´Î¹ÎºÎ¿Ï Î±Ïχείου" + +#: gio/gfile.c:4003 +msgid "Invalid symlink value given" +msgstr "ΆκυÏη τιμή ÏƒÏ…Î¼Î²Î¿Î»Î¹ÎºÎ¿Ï ÏƒÏ…Î½Î´Î­ÏƒÎ¼Î¿Ï…" + +#: gio/gfile.c:4013 glib/gfileutils.c:2172 +msgid "Symbolic links not supported" +msgstr "Οι συμβολικοί σÏνδεσμοι δεν υποστηÏίζονται" + +#: gio/gfile.c:4164 +msgid "Trash not supported" +msgstr "Δεν υποστηÏίζονται αποÏÏίμματα" + +#: gio/gfile.c:4276 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Τα ονόματα των αÏχείων δεν μποÏοÏν να πεÏιέχουν «%c»" + +#: gio/gfile.c:6757 gio/gvolume.c:364 +#, fuzzy +#| msgid "volume doesn't implement mount" +msgid "volume doesn’t implement mount" +msgstr "ο τόμος δεν υποστηÏίζει Ï€ÏοσάÏτηση" + +#: gio/gfile.c:6871 gio/gfile.c:6919 +msgid "No application is registered as handling this file" +msgstr "Δεν έχουν οÏιστεί εφαÏμογές για το χειÏισμό Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… αÏχείου" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Ο μετÏητής είναι κλειστός" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ΕκκÏεμεί μία ενέÏγεια του μετÏητή αÏχείων" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Ο μετÏητής αÏχείων έχει ήδη κλείσει" + +#: gio/gfileicon.c:236 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GFileIcon encoding" +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Αδυναμία χειÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ έκδοσης %d της κωδικοποίησης GFileIcon" + +#: gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Κακοδιατυπωμένη μοÏφή δεδομένων εισόδου του GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +#, fuzzy +#| msgid "Stream doesn't support query_info" +msgid "Stream doesn’t support query_info" +msgstr "Η Ïοή δεν υποστηÏίζει το query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ΑνυποστήÏικτη η αναζήτηση στη Ïοή" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Δεν επιτÏέπεται η πεÏικοπή για τη Ïοή εισόδου" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Δεν υποστηÏίζεται η πεÏικοπή Ïοής" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:596 +#: glib/gconvert.c:1777 +msgid "Invalid hostname" +msgstr "ΆκυÏο όνομα κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î®" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Κακή απάντηση από τον διαμεσολαβητή HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Δεν επιτÏάπηκε η σÏνδεση με τον διαμεσολαβητή HTTP" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Απέτυχε η πιστοποποίηση με τον διαμεσολαβητή HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Απαιτείται πιστοποίηση με τον διαμεσολαβητή HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Απέτυχε η σÏνδεση διαμεσολαβητή HTTP: %i" + +#: gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Έκλεισε απÏοσδόκητα η σÏνδεση με τον διακομιστή διαμεσολάβησης HTTP." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Λανθασμένος αÏιθμός ÎºÎ¿Ï…Ï€Î¿Î½Î¹Î¿Ï (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "ΧωÏίς Ï„Ïπο ονόματος κλάσης %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Ο Ï„Ïπος %s δεν υποστηÏίζει τη διεπαφή GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Ο Ï„Ïπος %s δεν είναι καταχωÏημένος" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Κακοδιατυπωμένος αÏιθμός έκδοσης: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Ο Ï„Ïπος %s δεν υποστηÏίζει from_tokens() στη διεπαφή GIcon" + +#: gio/gicon.c:469 +#, fuzzy +#| msgid "Can't handle the supplied version of the icon encoding" +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "" +"Αδυναμία χειÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ παÏεχόμενης έκδοσης της κωδικοποίησης του εικονιδίου" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "ΧωÏίς συγκεκÏιμένη διεÏθυνση" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Το μήκος %u είναι υπεÏβολικά μεγάλο για διεÏθυνση" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Η διεÏθυνση έχει σÏνολα δυαδικών πέÏα από το μήκος Ï€Ïοθέματος" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Αδυναμία ανάλυσης του «%s» ως μάσκα διεÏθυνσης IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:220 +msgid "Not enough space for socket address" +msgstr "ΑνεπαÏκής χώÏος για την διεÏθυνση υποδοχέα" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "ΑνυποστήÏικτη διεÏθυνση υποδοχέα" + +#: gio/ginputstream.c:188 +#, fuzzy +#| msgid "Input stream doesn't implement read" +msgid "Input stream doesn’t implement read" +msgstr "Η Ïοή εισόδου δεν υποστηÏίζει την ανάγνωση" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "ΕκκÏεμεί μία ενέÏγεια για τη Ïοή" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "ΑντιγÏαφή με αÏχείο" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Îα διατηÏηθεί με το αÏχείο όταν μετακινηθεί" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "Η «έκδοση» δεν παίÏνει οÏίσματα" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "ΧÏήση:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "ΠÏοβολή πληÏοφοÏιών έκδοσης και έξοδος." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Εντολές:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "ΑντιγÏαφή ενός ή πεÏισσοτέÏων αÏχείων" + +#: gio/gio-tool.c:231 +#, fuzzy +#| msgid "Show GApplication options" +msgid "Show information about locations" +msgstr "Εμφάνιση επιλογών GApplication" + +#: gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "Λίστα των πεÏιεχομένων των τοποθεσιών" + +#: gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: gio/gio-tool.c:234 +msgid "Create directories" +msgstr "ΔημιουÏγία καταλόγων" + +#: gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "" + +#: gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "" + +#: gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "Μετακίνηση ενός ή πεÏισσοτέÏων αÏχείων" + +#: gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "Άνοιγμα αÏχείων με την Ï€Ïοεπιλεγμένη εφαÏμογή" + +#: gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "Μετονομασία αÏχείου" + +#: gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "ΔιαγÏαφή ενός ή πεÏισσοτέÏων αÏχείων" + +#: gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "" + +#: gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "ΟÏίστε ένα χαÏακτηÏιστικό αÏχείου" + +#: gio/gio-tool.c:243 +#, fuzzy +#| msgid "The file descriptor to write to" +msgid "Move files or directories to the trash" +msgstr "Ο πεÏιγÏαφέας αÏχείου στον οποίο θα γίνει η εγγÏαφή" + +#: gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: gio/gio-tool.c:246 +#, fuzzy, c-format +#| msgid "" +#| "Use '%s help COMMAND' to get detailed help.\n" +#| "\n" +msgid "Use %s to get detailed help.\n" +msgstr "" +"ΧÏησιμοποιήστε το '%s help COMMAND' για να πάÏετε λεπτομεÏή βοήθεια.\n" +"\n" + +#: gio/gio-tool-cat.c:87 +#, fuzzy +#| msgid "Error writing to file: %s" +msgid "Error writing to stdout" +msgstr "Σφάλμα εγγÏαφής στο αÏχείο: %s" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:333 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "ΤΟΠΟΘΕΣΙΑ" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:364 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 +msgid "No locations given" +msgstr "Δεν δόθηκαν τοποθεσίες" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +#, fuzzy +#| msgid "Target file is a directory" +msgid "No target directory" +msgstr "Το αÏχείο Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï ÎµÎ¯Î½Î±Î¹ κατάλογος" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Εμφάνιση Ï€Ïοόδου" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +#, fuzzy +#| msgid "Backup file creation failed" +msgid "Backup existing destination files" +msgstr "Αποτυχία δημιουÏγίας αντιγÏάφου ασφαλείας" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Îα μην ακολουθοÏνται οι συμβολικοί σÏνδεσμοι" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "ΧÏήση Ï€Ïοεπιλεγμένων δικαιωμάτων για τον Ï€ÏοοÏισμό" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ΠΗΓΗ" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ΠΡΟΟΡΙΣΜΟΣ" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-copy.c:149 +#, fuzzy, c-format +#| msgid "The resource at '%s' is not a directory" +msgid "Destination %s is not a directory" +msgstr "Η πηγή στο '%s' δεν είναι κατάλογος" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "" + +#: gio/gio-tool-info.c:37 +#, fuzzy +#| msgid "List available actions" +msgid "List writable attributes" +msgstr "Κατάλογος διαθέσιμων ενεÏγειών" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Λήψη πληÏοφοÏιών συστήματος αÏχείων" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Îα μην ακολουθεοÏνται οι συμβολικοί σÏνδεσμοι" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "επεξεÏγασία ονόματος: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "όνομα: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "Ï„Ïπος: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "μέγεθος: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "" + +# +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "τοπική διαδÏομή: %s\n" + +#: gio/gio-tool-info.c:199 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:279 +msgid "Settable attributes:\n" +msgstr "" + +#: gio/gio-tool-info.c:303 +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: gio/gio-tool-info.c:338 +msgid "Show information about locations." +msgstr "Εμφάνιση πληÏοφοÏιών σχετικά με τις τοποθεσίες." + +#: gio/gio-tool-info.c:340 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Εμφάνιση κÏυφών αÏχείων" + +#: gio/gio-tool-list.c:38 +#, fuzzy +#| msgid "use a long listing format" +msgid "Use a long listing format" +msgstr "χÏήση αναπτυγμένης μοÏφής λιστών" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "ΠÏοεπιλεγμένη εφαÏμογή για «%s»: %s\n" + +#: gio/gio-tool-mime.c:127 +#, fuzzy +#| msgid "List applications" +msgid "Registered applications:\n" +msgstr "Κατάλογος εφαÏμογών" + +#: gio/gio-tool-mime.c:129 +#, fuzzy +#| msgid "List applications" +msgid "No registered applications\n" +msgstr "Κατάλογος εφαÏμογών" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Συνιστώμενες εφαÏμογές:\n" + +#: gio/gio-tool-mime.c:142 +#, fuzzy +#| msgid "Can't find application" +msgid "No recommended applications\n" +msgstr "Αδυναμία εÏÏεσης εφαÏμογής" + +# gconf/gconf-internals.c:2416 +#: gio/gio-tool-mime.c:162 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "Αποτυχία ανάγνωσης από το αÏχείο '%s': %s" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mkdir.c:31 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create parent directories" +msgstr "Αδυναμία ανοίγματος καταλόγου" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "ΔημιουÏγία καταλόγων." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "ΑποπÏοσάÏτηση" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Εξαγωγή" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Διακοπή της μονάδας δίσκου με αÏχείο συσκευής" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ΣΥΣΚΕΥΗ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Λίστα" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "" + +#: gio/gio-tool-mount.c:74 +#, fuzzy +#| msgid "Show help options" +msgid "Show extra information" +msgstr "Εμφάνιση επιλογών βοήθειας" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +#| msgctxt "GDateTime" +#| msgid "PM" +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Δεν επετÏάπη η ανώνυμη Ï€Ïόσβαση" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: gio/gio-tool-move.c:143 +#, fuzzy, c-format +#| msgid "Target file is a directory" +msgid "Target %s is not a directory" +msgstr "Το αÏχείο Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï ÎµÎ¯Î½Î±Î¹ κατάλογος" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "ΟÎΟΜΑ" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Μετονομασία αÏχείου." + +#: gio/gio-tool-rename.c:70 +#, fuzzy +#| msgid "Missing argument for %s" +msgid "Missing argument" +msgstr "Λείπει ÏŒÏισμα για %s" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "ΠάÏα πολλά οÏίσματα" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Îα δημιουÏγείται εάν δεν υπάÏχει" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "ΠÏοσάÏτηση στο τέλος του αÏχείου" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +#, fuzzy +#| msgid "Error reading from handle: %s" +msgid "Error reading from standard input" +msgstr "Σφάλμα ανάγνωσης χειÏιστηÏίου: %s" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Μη διαθέσιμη Etag\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Δεν δόθηκε Ï€ÏοοÏισμός" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "ΤÏπος του χαÏακτηÏιστικοÏ" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATTRIBUTE" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALUE" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "" + +#: gio/gio-tool-set.c:113 +#, fuzzy +#| msgid "No connection endpoint specified" +msgid "Location not specified" +msgstr "Δεν διευκÏινίζεται σημείο τέλους σÏνδεσης" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Το χαÏακτηÏιστικό δεν καθοÏίστηκε" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Η τιμή δεν καθοÏίστηκε" + +#: gio/gio-tool-set.c:180 +#, fuzzy, c-format +#| msgid "Invalid attribute type (string expected)" +msgid "Invalid attribute type “%sâ€" +msgstr "ΆκυÏος Ï„Ïπος γνωÏίσματος (αναμενόταν συμβολοσειÏά)" + +#: gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "Άδειασμα αποÏÏιμάτων" + +#: gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "Μετακίνηση αÏχείων ή καταλόγων στα αποÏÏίμματα." + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Το στοιχείο <%s> δεν επιτÏέπεται μέσα στο <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Το στοιχείο <%s> δεν επιτÏέπεται στο κοÏυφαίο επίπεδο" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Το αÏχείο %s φαίνεται πολλές φοÏές στην πηγή" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Αποτυχία ÎµÎ½Ï„Î¿Ï€Î¹ÏƒÎ¼Î¿Ï Â«%s» σε οποιοδήποτε κατάλογο πηγής" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Αποτυχία ÎµÎ½Ï„Î¿Ï€Î¹ÏƒÎ¼Î¿Ï Â«%s» στον Ï„Ïέχοντα κατάλογο" + +#: gio/glib-compile-resources.c:290 +#, fuzzy, c-format +#| msgid "Unknown processing option \"%s\"" +msgid "Unknown processing option “%sâ€" +msgstr "Άγνωστη επιλογή διαδικασίας \"%s\"" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +# +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Σφάλμα ανάγνωσης αÏχείου %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Σφάλμα αÏχείου συμπίεσης %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "το κείμενο μποÏεί να μην εμφανιστεί μέσα στο <%s>" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Εμφάνιση έκδοσης Ï€ÏογÏάμματος και έξοδος" + +#: gio/glib-compile-resources.c:738 +msgid "Name of the output file" +msgstr "Όνομα του αÏχείου εξόδου" + +#: gio/glib-compile-resources.c:739 +#, fuzzy +#| msgid "" +#| "The directories where files are to be read from (default to current " +#| "directory)" +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Οι κατάλογοι από όπου Ï€Ïόκειται να διαβαστοÏν αÏχεία (Ï€Ïοεπιλογή ο Ï„Ïέχον " +"κατάλογος)" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "ΚΑΤΑΛΟΓΟΣ" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"ΔημιουÏγία εξόδου στην επιλεγμένη μοÏφή από την επέκταση ονόματος αÏχείου " +"Ï€ÏοοÏισμοÏ" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "ΔημιουÏγία κεφαλίδας πηγής" + +#: gio/glib-compile-resources.c:742 +#, fuzzy +#| msgid "Generate sourcecode used to link in the resource file into your code" +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"ΔημιουÏγία πηγαίου κώδικα για σÏνδεση στο πηγαίο αÏχείο στον κωδικά σας" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "ΔημιουÏγία λίστας εξαÏτήσεων" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:746 +#, fuzzy +#| msgid "Don't automatically create and register resource" +msgid "Don’t automatically create and register resource" +msgstr "Îα μην δημιουÏγείται αυτόματα και καταχωÏείται ο πόÏος" + +#: gio/glib-compile-resources.c:747 +#, fuzzy +#| msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Μην εξάγετε συναÏτήσεις· δηλώστε τες στο G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "" +"Το χÏησιμοποιοÏμενο όνομα ταυτοποιητή C για το δημιουÏγοÏμενο πηγαίο κώδικα" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Μεταγλώττιση Ï€ÏοδιαγÏαφής πόÏου σε αÏχείο πόÏου.\n" +"Τα αÏχεία Ï€ÏοδιαγÏαφής πόÏου έχουν την επέκταση .gresource.xml,\n" +"και το αÏχείο πόÏου έχει την επέκταση που αποκαλείται .gresource." + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "ΠÏέπει να δώσετε ακÏιβώς ένα όνομα αÏχείου\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, fuzzy, c-format +#| msgid "Invalid symlink value given" +msgid "Invalid numeric value" +msgstr "ΆκυÏη τιμή ÏƒÏ…Î¼Î²Î¿Î»Î¹ÎºÎ¿Ï ÏƒÏ…Î½Î´Î­ÏƒÎ¼Î¿Ï…" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " είναι ήδη οÏισμένο" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' είναι ήδη οÏισμένο" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, fuzzy, c-format +#| msgid "No connection endpoint specified" +msgid "<%s> is not contained in the specified range" +msgstr "Δεν διευκÏινίζεται σημείο τέλους σÏνδεσης" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +#, fuzzy +#| msgid " already specified" +msgid " already specified for this key" +msgstr " έχει ήδη οÏιστεί" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "" + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +#, fuzzy +#| msgid " already specified" +msgid " already specified for this key" +msgstr " έχει ήδη οÏιστεί" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, fuzzy, c-format +#| msgid " already specified" +msgid " already given" +msgstr " έχει ήδη οÏιστεί" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +#, fuzzy +#| msgid " already specified" +msgid " already specified for this key" +msgstr " έχει ήδη οÏιστεί" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, fuzzy, c-format +#| msgid "<%s id='%s'> already specified" +msgid " already specified" +msgstr "<%s id='%s'> είναι ήδη οÏισμένο" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Κκενά ονόματα δεν επιτÏέπονται" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Μη έγκυÏο όνομα «%s»: τα ονόματα Ï€Ïέπει να αÏχίσουν με πεζό γÏάμμα" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Μη έγκυÏο όνομα «%s»: μη έγκυÏος χαÏακτήÏας «%c»· μόνο πεζά γÏάμματα, " +"αÏιθμοί και παÏλες («-») επιτÏέπονται" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Μη έγκυÏο όνομα «%s»: δÏο διαδοχικές παÏλες («--») δεν επιτÏέπονται" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" +"Μη έγκυÏο όνομα «%s»: ο τελευταίος χαÏακτήÏας μποÏεί να μην είναι παÏλα " +"(«-»)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Μη έγκυÏο όνομα «%s»: το μέγιστο μήκος είναι 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " έχει ήδη οÏιστεί" + +#: gio/glib-compile-schemas.c:943 +#, fuzzy +#| msgid "cannot add keys to a 'list-of' schema" +msgid "Cannot add keys to a “list-of†schema" +msgstr "αδυναμία Ï€Ïοσθήκης κλειδιών σε σχήμα 'list-of'" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " έχει ήδη οÏιστεί" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" σκιές στο · χÏησιμοποιεί " +" για Ï„Ïοποποίηση της τιμής" + +#: gio/glib-compile-schemas.c:983 +#, fuzzy, c-format +#| msgid "" +#| "exactly one of 'type', 'enum' or 'flags' must be specified as an " +#| "attribute to " +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"ακÏιβώς ένα από 'type', 'enum' ή 'flags' Ï€Ïέπει να διευκÏινιστείτε ως " +"ιδιότητα στο " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> αδιευκÏίνιστη (ακόμα)." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Μη έγκυÏος Ï„Ïπος συμβολοσειÏάς GVariant «%s»" + +#: gio/glib-compile-schemas.c:1047 +#, fuzzy +#| msgid " given but schema isn't extending anything" +msgid " given but schema isn’t extending anything" +msgstr " δόθηκε αλλά το σχήμα δεν επεκτείνει τίποτα" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Δεν υπάÏχει για αντικατάσταση" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " έχει ήδη οÏιστεί" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " έχει ήδη οÏιστεί" + +#: gio/glib-compile-schemas.c:1153 +#, fuzzy, c-format +#| msgid " extends not yet existing schema '%s'" +msgid " extends not yet existing schema “%sâ€" +msgstr " επεκτείνει ένα μη υπάÏχον ακόμα σχήμα '%s'" + +#: gio/glib-compile-schemas.c:1169 +#, fuzzy, c-format +#| msgid " is list of not yet existing schema '%s'" +msgid " is list of not yet existing schema “%sâ€" +msgstr "" +" είναι κατάλογος ενός μη υπάÏχοντος ακόμα σχήματος '%s'" + +#: gio/glib-compile-schemas.c:1177 +#, fuzzy, c-format +#| msgid "Can not be a list of a schema with a path" +msgid "Cannot be a list of a schema with a path" +msgstr "Αδυναμία ÏπαÏξης λίστας σχήματος με διαδÏομή" + +#: gio/glib-compile-schemas.c:1187 +#, fuzzy, c-format +#| msgid "Can not extend a schema with a path" +msgid "Cannot extend a schema with a path" +msgstr "Αδυναμία επέκτασης σχήματος με διαδÏομή" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +"Το είναι λίστα, που επεκτείνει το που δεν " +"είναι λίστα" + +#: gio/glib-compile-schemas.c:1207 +#, fuzzy, c-format +#| msgid "" +#| " extends but " +#| "'%s' does not extend '%s'" +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" επεκτείνει το " +"αλλά το '%s' δεν επεκτείνει το '%s'" + +#: gio/glib-compile-schemas.c:1224 +#, fuzzy, c-format +#| msgid "a path, if given, must begin and end with a slash" +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"μία διαδÏομή, εάν έχει δοθεί, Ï€Ïέπει να αÏχίζει και να τελειώνει με κάθετο" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Η διαδÏομή μίας λίστας Ï€Ïέπει να τελειώσει με «:/»" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> είναι ήδη οÏισμένο" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Μόνο ένα στοιχείο <%s> επιτÏέπεται μέσα στο <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Το στοιχείο <%s> δεν επιτÏέπεται στο κοÏυφαίο επίπεδο" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, fuzzy, c-format +#| msgid "text may not appear inside <%s>" +msgid "Text may not appear inside <%s>" +msgstr "το κείμενο μποÏεί να μην εμφανιστεί μέσα στο <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +#, fuzzy +#| msgid "--strict was specified; exiting.\n" +msgid "--strict was specified; exiting." +msgstr "οÏίστηκε το --strict· γίνεται έξοδος.\n" + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Έχει παÏαβλεφθεί όλο αυτό το αÏχείο." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "ΠαÏάβλεψη Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… αÏχείου." + +#: gio/glib-compile-schemas.c:1963 +#, fuzzy, c-format +#| msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Δεν υπάÏχει τέτοιο κλειδί '%s' στο σχήμα '%s' όπως οÏίζεται στο αÏχείο " +"αντικατάστασης '%s'" + +#: gio/glib-compile-schemas.c:1971 +#, fuzzy, c-format +#| msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Δεν υπάÏχει τέτοιο κλειδί '%s' στο σχήμα '%s' όπως οÏίζεται στο αÏχείο " +"αντικατάστασης '%s'" + +#: gio/glib-compile-schemas.c:1993 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"η αντικατάσταση για το κλειδί'%s' στο σχήμα '%s' στο αÏχείο αντικατάστασης " +"'%s' δεν είναι στον κατάλογο έγκυÏων επιλογών" + +#: gio/glib-compile-schemas.c:2002 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"η αντικατάσταση για το κλειδί'%s' στο σχήμα '%s' στο αÏχείο αντικατάστασης " +"'%s' δεν είναι στον κατάλογο έγκυÏων επιλογών" + +#: gio/glib-compile-schemas.c:2026 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s." +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"σφάλμα ανάλυσης ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï '%s' στο σχήμα '%s' όπως οÏίστηκε στο αÏχείο " +"αντικατάστασης '%s': %s." + +#: gio/glib-compile-schemas.c:2038 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s." +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"σφάλμα ανάλυσης ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï '%s' στο σχήμα '%s' όπως οÏίστηκε στο αÏχείο " +"αντικατάστασης '%s': %s." + +#: gio/glib-compile-schemas.c:2065 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is outside the " +#| "range given in the schema" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"η αντικατάσταση για το κλειδί '%s' στο σχήμα '%s' στο αÏχείο αντικατάστασης " +"'%s' είναι εκτός της εμβέλειας που έχει δοθεί στο σχήμα" + +#: gio/glib-compile-schemas.c:2075 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is outside the " +#| "range given in the schema" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"η αντικατάσταση για το κλειδί '%s' στο σχήμα '%s' στο αÏχείο αντικατάστασης " +"'%s' είναι εκτός της εμβέλειας που έχει δοθεί στο σχήμα" + +#: gio/glib-compile-schemas.c:2101 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"η αντικατάσταση για το κλειδί'%s' στο σχήμα '%s' στο αÏχείο αντικατάστασης " +"'%s' δεν είναι στον κατάλογο έγκυÏων επιλογών" + +#: gio/glib-compile-schemas.c:2111 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"η αντικατάσταση για το κλειδί'%s' στο σχήμα '%s' στο αÏχείο αντικατάστασης " +"'%s' δεν είναι στον κατάλογο έγκυÏων επιλογών" + +#: gio/glib-compile-schemas.c:2173 +#, fuzzy +#| msgid "where to store the gschemas.compiled file" +msgid "Where to store the gschemas.compiled file" +msgstr "Ï€Î¿Ï Î½Î± αποθηκευτεί το αÏχείο gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Εγκατάλειψη σε κάθε σφάλμα σε σχήματα" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Μην γÏάφετε το αÏχείο gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Μην επιβάλετε πεÏιοÏισμοÏÏ‚ στο όνομα κλειδιοÏ" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Μεταγλώττιση όλων των αÏχείων σχημάτων GSettings σε κÏυφή μνήμη σχημάτων.\n" +"Τα αÏχεία σχημάτων απαιτείται να έχουν την επέκταση.gschema.xml\n" +"και το αÏχείο κÏυφής μνήμης καλείται gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +#, fuzzy +#| msgid "You should give exactly one directory name\n" +msgid "You should give exactly one directory name" +msgstr "ΠÏέπει να δώσετε ακÏιβώς ένα όνομα καταλόγου\n" + +#: gio/glib-compile-schemas.c:2269 +#, fuzzy +#| msgid "No schema files found: " +msgid "No schema files found: doing nothing." +msgstr "Κανένα αÏχείο σχημάτων δεν βÏέθηκε: " + +#: gio/glib-compile-schemas.c:2271 +#, fuzzy +#| msgid "removed existing output file.\n" +msgid "No schema files found: removed existing output file." +msgstr "αφαίÏεση υπάÏχοντος αÏχείου εξόδου.\n" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "ΆκυÏο όνομα αÏχείου: %s" + +#: gio/glocalfile.c:1018 +#, fuzzy, c-format +#| msgid "Error getting filesystem info: %s" +msgid "Error getting filesystem info for %s: %s" +msgstr "Σφάλμα λήψης πληÏοφοÏιών συστήματος αÏχείων: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1159 +#, fuzzy, c-format +#| msgid "Containing mount does not exist" +msgid "Containing mount for file %s not found" +msgstr "Δεν υπάÏχει η πεÏιέχουσα Ï€ÏοσάÏτηση" + +#: gio/glocalfile.c:1182 +#, fuzzy +#| msgid "Can't rename root directory" +msgid "Can’t rename root directory" +msgstr "Αδυναμία μετονομασίας του καταλόγου root" + +# +#: gio/glocalfile.c:1200 gio/glocalfile.c:1223 +#, fuzzy, c-format +#| msgid "Error reading file %s: %s" +msgid "Error renaming file %s: %s" +msgstr "Σφάλμα ανάγνωσης αÏχείου %s: %s" + +#: gio/glocalfile.c:1207 +#, fuzzy +#| msgid "Can't rename file, filename already exists" +msgid "Can’t rename file, filename already exists" +msgstr "Αδυναμία μετονομασίας του αÏχείου, το όνομα αÏχείου υπάÏχει ήδη" + +#: gio/glocalfile.c:1220 gio/glocalfile.c:2329 gio/glocalfile.c:2357 +#: gio/glocalfile.c:2496 gio/glocalfileoutputstream.c:647 +msgid "Invalid filename" +msgstr "ΆκυÏο όνομα αÏχείου" + +# +#: gio/glocalfile.c:1388 gio/glocalfile.c:1403 +#, fuzzy, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file %s: %s" +msgstr "Σφάλμα ανοίγματος αÏχείου '%s': %s" + +#: gio/glocalfile.c:1528 +#, fuzzy, c-format +#| msgid "Error removing file: %s" +msgid "Error removing file %s: %s" +msgstr "Σφάλμα αφαίÏεσης αÏχείου: %s" + +#: gio/glocalfile.c:1970 +#, fuzzy, c-format +#| msgid "Error trashing file: %s" +msgid "Error trashing file %s: %s" +msgstr "Σφάλμα μεταφοÏάς αÏχείου στα αποÏÏίμματα: %s" + +# gconf/gconf-internals.c:2416 +#: gio/glocalfile.c:2011 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Αποτυχία δημιουÏγίας καταλόγου αποÏÏιμμάτων %s: %s" + +#: gio/glocalfile.c:2032 +#, fuzzy, c-format +#| msgid "Unable to find toplevel directory for trash" +msgid "Unable to find toplevel directory to trash %s" +msgstr "Αδυναμία εÏÏεσης καταλόγου ανωτάτου επιπέδου για τα αποÏÏίμματα" + +#: gio/glocalfile.c:2041 +#, fuzzy, c-format +#| msgid "Copy (reflink/clone) between mounts is not supported" +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"Δεν υποστηÏίζεται η αντιγÏαφή (συνδέσμου αναφοÏάς/κλώνου) Î¼ÎµÏ„Î±Î¾Ï Ï€ÏοσαÏτήσεων" + +#: gio/glocalfile.c:2125 gio/glocalfile.c:2145 +#, fuzzy, c-format +#| msgid "Unable to find or create trash directory" +msgid "Unable to find or create trash directory for %s" +msgstr "ΑδÏνατη η εÏÏεση ή δημιουÏγία του καταλόγου αποÏÏιμμάτων" + +# gconf/gconf-internals.c:2416 +#: gio/glocalfile.c:2180 +#, fuzzy, c-format +#| msgid "Unable to create trashing info file: %s" +msgid "Unable to create trashing info file for %s: %s" +msgstr "Αποτυχία δημιουÏγίας αÏχείου πληÏοφοÏιών αποÏÏιμμάτων: %s" + +# gconf/gconf-internals.c:2416 +#: gio/glocalfile.c:2240 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "ΑδÏνατη η μεταφοÏά του αÏχείου στα αποÏÏίμματα: %s" + +# gconf/gconf-internals.c:2416 +#: gio/glocalfile.c:2244 gio/glocalfile.c:2300 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s: %s" +msgstr "ΑδÏνατη η μεταφοÏά του αÏχείου στα αποÏÏίμματα: %s" + +# gconf/gconf-internals.c:2416 +#: gio/glocalfile.c:2306 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s" +msgstr "ΑδÏνατη η μεταφοÏά του αÏχείου στα αποÏÏίμματα: %s" + +#: gio/glocalfile.c:2332 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory %s: %s" +msgstr "Σφάλμα δημιουÏγίας καταλόγου '%s': %s" + +# gconf/gconf-internals.c:2416 +#: gio/glocalfile.c:2361 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Το σÏστημα αÏχείων δεν υποστηÏίζει συμβολικοÏÏ‚ συνδέσμους" + +# gconf/gconftool.c:1181 +#: gio/glocalfile.c:2364 +#, fuzzy, c-format +#| msgid "Error making symbolic link: %s" +msgid "Error making symbolic link %s: %s" +msgstr "Σφάλμα δημιουÏγίας ÏƒÏ…Î¼Î²Î¿Î»Î¹ÎºÎ¿Ï ÏƒÏ…Î½Î´Î­ÏƒÎ¼Î¿Ï…: %s" + +#: gio/glocalfile.c:2407 gio/glocalfile.c:2442 gio/glocalfile.c:2499 +#, fuzzy, c-format +#| msgid "Error moving file: %s" +msgid "Error moving file %s: %s" +msgstr "Σφάλμα μετακίνησης αÏχείου: %s" + +#: gio/glocalfile.c:2430 +#, fuzzy +#| msgid "Can't move directory over directory" +msgid "Can’t move directory over directory" +msgstr "Αδυναμία μετακίνησης καταλόγου σε άλλον" + +#: gio/glocalfile.c:2456 gio/glocalfileoutputstream.c:1031 +#: gio/glocalfileoutputstream.c:1045 gio/glocalfileoutputstream.c:1060 +#: gio/glocalfileoutputstream.c:1077 gio/glocalfileoutputstream.c:1091 +msgid "Backup file creation failed" +msgstr "Αποτυχία δημιουÏγίας αντιγÏάφου ασφαλείας" + +#: gio/glocalfile.c:2475 +#, c-format +msgid "Error removing target file: %s" +msgstr "Σφάλμα αφαίÏεσης του αÏχείου Ï€ÏοοÏισμοÏ: %s" + +#: gio/glocalfile.c:2489 +msgid "Move between mounts not supported" +msgstr "Δεν υποστηÏίζεται η μετακίνηση Î¼ÎµÏ„Î±Î¾Ï Ï€ÏοσαÏτήσεων" + +#: gio/glocalfile.c:2663 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Αδυναμία Ï€ÏοσδιοÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ χÏήσης δίσκου %s: %s" + +#: gio/glocalfileinfo.c:760 +msgid "Attribute value must be non-NULL" +msgstr "Η τιμή του γνωÏίσματος Ï€Ïέπει να είναι μη μηδενική" + +#: gio/glocalfileinfo.c:767 +msgid "Invalid attribute type (string expected)" +msgstr "ΆκυÏος Ï„Ïπος γνωÏίσματος (αναμενόταν συμβολοσειÏά)" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid extended attribute name" +msgstr "ΆκυÏο εκτεταμένο όνομα γνωÏίσματος" + +#: gio/glocalfileinfo.c:814 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Σφάλμα οÏÎ¹ÏƒÎ¼Î¿Ï ÎµÎºÏ„ÎµÏ„Î±Î¼Î­Î½Î¿Ï… γνωÏίσματος «%s»: %s" + +#: gio/glocalfileinfo.c:1650 +msgid " (invalid encoding)" +msgstr " (άκυÏη κωδικοποίηση)" + +# +#: gio/glocalfileinfo.c:1814 gio/glocalfileoutputstream.c:909 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Σφάλμα λήψης πληÏοφοÏιών αÏχείου «%s»: %s" + +#: gio/glocalfileinfo.c:2084 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Σφάλμα λήψης πληÏοφοÏιών για πεÏιγÏαφέα αÏχείου: %s" + +#: gio/glocalfileinfo.c:2129 +msgid "Invalid attribute type (uint32 expected)" +msgstr "ΆκυÏος Ï„Ïπος γνωÏίσματος (αναμένεται uint32)" + +#: gio/glocalfileinfo.c:2147 +msgid "Invalid attribute type (uint64 expected)" +msgstr "ΆκυÏος Ï„Ïπος γνωÏίσματος (αναμένεται uint64)" + +#: gio/glocalfileinfo.c:2166 gio/glocalfileinfo.c:2185 +msgid "Invalid attribute type (byte string expected)" +msgstr "ΆκυÏος Ï„Ïπος γνωÏίσματος (αναμένεται συμβολοσειÏά byte)" + +# gconf/gconftool.c:1181 +#: gio/glocalfileinfo.c:2232 +msgid "Cannot set permissions on symlinks" +msgstr "Αδυναμία οÏÎ¹ÏƒÎ¼Î¿Ï Î´Î¹ÎºÎ±Î¹Ï‰Î¼Î¬Ï„Ï‰Î½ σε συμβολικοÏÏ‚ συνδέσμους" + +# gconf/gconftool.c:1181 +#: gio/glocalfileinfo.c:2248 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Σφάλμα ÏÏθμισης δικαιωμάτων: %s" + +# gconf/gconftool.c:1181 +#: gio/glocalfileinfo.c:2299 +#, c-format +msgid "Error setting owner: %s" +msgstr "Σφάλμα ÏÏθμισης ιδιοκτήτη: %s" + +#: gio/glocalfileinfo.c:2322 +msgid "symlink must be non-NULL" +msgstr "ο συμβολικός σÏνδεσμος Ï€Ïέπει να είναι μη μηδενικός" + +#: gio/glocalfileinfo.c:2332 gio/glocalfileinfo.c:2351 +#: gio/glocalfileinfo.c:2362 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Σφάλμα οÏÎ¹ÏƒÎ¼Î¿Ï ÏƒÏ…Î¼Î²Î¿Î»Î¹ÎºÎ¿Ï ÏƒÏ…Î½Î´Î­ÏƒÎ¼Î¿Ï…: %s" + +#: gio/glocalfileinfo.c:2341 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Σφάλμα οÏÎ¹ÏƒÎ¼Î¿Ï ÏƒÏ…Î¼Î²Î¿Î»Î¹ÎºÎ¿Ï ÏƒÏ…Î½Î´Î­ÏƒÎ¼Î¿Ï…: το αÏχείο δεν είναι συμβολικός σÏνδεσμος" + +#: gio/glocalfileinfo.c:2413 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2422 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2432 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2443 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2507 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a number." +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Η τιμή '%s' δεν μποÏεί να εÏμηνευθεί ως αÏιθμός." + +#: gio/glocalfileinfo.c:2526 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a number." +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Η τιμή '%s' δεν μποÏεί να εÏμηνευθεί ως αÏιθμός." + +# gconf/gconftool.c:1181 +#: gio/glocalfileinfo.c:2539 +#, fuzzy, c-format +#| msgid "Error setting modification or access time: %s" +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Σφάλμα ÏÏθμισης Ï„Ïοποποίησης ή χÏόνου Ï€Ïόσβασης: %s" + +# gconf/gconftool.c:1181 +#: gio/glocalfileinfo.c:2640 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Σφάλμα ÏÏθμισης Ï„Ïοποποίησης ή χÏόνου Ï€Ïόσβασης: %s" + +#: gio/glocalfileinfo.c:2663 +msgid "SELinux context must be non-NULL" +msgstr "Το πεÏιεχόμενο SELinux Ï€Ïέπει να είναι μη μηδενικό" + +# gconf/gconftool.c:1181 +#: gio/glocalfileinfo.c:2678 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Σφάλμα ÏÏθμισης του πεÏιεχομένου SELinux: %s" + +#: gio/glocalfileinfo.c:2685 +msgid "SELinux is not enabled on this system" +msgstr "Το SELinux δεν έχει ενεÏγοποιηθεί στο σÏστημά σας" + +#: gio/glocalfileinfo.c:2777 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Δεν υποστηÏίζεται ο οÏισμός του γνωÏίσματος %s" + +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:792 +#, c-format +msgid "Error reading from file: %s" +msgstr "Σφάλμα ανάγνωσης από το αÏχείο: %s" + +#: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 +#: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 +#: gio/glocalfileoutputstream.c:554 gio/glocalfileoutputstream.c:1109 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Σφάλμα αναζήτησης στο αÏχείο: %s" + +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:344 +#: gio/glocalfileoutputstream.c:438 +#, c-format +msgid "Error closing file: %s" +msgstr "Σφάλμα κλεισίματος αÏχείου: %s" + +#: gio/glocalfilemonitor.c:865 +msgid "Unable to find default local file monitor type" +msgstr "Δε βÏέθηκε ο Ï„Ïπος παÏακολοÏθησης του Ï€Ïοεπιλεγμένου Ï„Î¿Ï€Î¹ÎºÎ¿Ï Î±Ïχείου" + +#: gio/glocalfileoutputstream.c:209 gio/glocalfileoutputstream.c:287 +#: gio/glocalfileoutputstream.c:324 gio/glocalfileoutputstream.c:813 +#, c-format +msgid "Error writing to file: %s" +msgstr "Σφάλμα εγγÏαφής στο αÏχείο: %s" + +# gconf/gconftool.c:1181 +#: gio/glocalfileoutputstream.c:371 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Σφάλμα αφαίÏεσης Ï€Î±Î»Î±Î¹Î¿Ï ÏƒÏ…Î½Î´Î­ÏƒÎ¼Î¿Ï… αντιγÏάφου: %s" + +# +#: gio/glocalfileoutputstream.c:385 gio/glocalfileoutputstream.c:398 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Σφάλμα δημιουÏγίας αντιγÏάφου ασφαλείας: %s" + +# +#: gio/glocalfileoutputstream.c:416 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Σφάλμα μετονομασίας Ï€ÏοσωÏÎ¹Î½Î¿Ï Î±Ïχείου: %s" + +# +#: gio/glocalfileoutputstream.c:600 gio/glocalfileoutputstream.c:1160 +#, c-format +msgid "Error truncating file: %s" +msgstr "Σφάλμα πεÏικοπής αÏχείου: %s" + +# +#: gio/glocalfileoutputstream.c:653 gio/glocalfileoutputstream.c:891 +#: gio/glocalfileoutputstream.c:1141 gio/gsubprocess.c:380 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Σφάλμα ανοίγματος αÏχείου «%s»: %s" + +#: gio/glocalfileoutputstream.c:922 +msgid "Target file is a directory" +msgstr "Το αÏχείο Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï ÎµÎ¯Î½Î±Î¹ κατάλογος" + +#: gio/glocalfileoutputstream.c:927 +msgid "Target file is not a regular file" +msgstr "Το αÏχείο Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï Î´ÎµÎ½ είναι κανονικό αÏχείο" + +#: gio/glocalfileoutputstream.c:939 +msgid "The file was externally modified" +msgstr "Το αÏχείο Ï„Ïοποποιήθηκε εξωτεÏικά" + +#: gio/glocalfileoutputstream.c:1125 +#, c-format +msgid "Error removing old file: %s" +msgstr "Σφάλμα αφαίÏεσης Ï€Î±Î»Î±Î¹Î¿Ï Î±Ïχείου: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Δόθηκε άκυÏο GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "ΆκυÏη αίτηση αναζήτησης" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Αδυναμία πεÏικοπής του GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Η Ïοή εξόδου μνήμης δεν είναι κλιμακώσιμη" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Αποτυχία κλιμάκωσης της Ïοής εξόδου μνήμης" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Το ποσό μνήμης που απαιτείται για την επεξεÏγασία της εγγÏαφής είναι " +"μεγαλÏτεÏο από το διαθέσιμο χώÏο διευθÏνσεων" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Αίτηση αναζήτησης Ï€Ïιν την έναÏξη της Ïοής" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Αίτηση αναζήτησης πέÏαν του τέλους της Ïοής" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "η Ï€ÏοσάÏτηση δεν υποστηÏίζει «αποπÏοσάÏτηση»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "η Ï€ÏοσάÏτηση δεν υποστηÏίζει «εξαγωγή»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"η Ï€ÏοσάÏτηση δεν υποστηÏίζει «αποπÏοσάÏτηση» ή την «unmount_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "η Ï€ÏοσάÏτηση δεν υποστηÏίζει «εξαγωγή» ή «eject_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "η Ï€ÏοσάÏτηση δεν υποστηÏίζει την «επαναπÏοσάÏτηση»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +#, fuzzy +#| msgid "mount doesn't implement content type guessing" +msgid "mount doesn’t implement content type guessing" +msgstr "η Ï€ÏοσάÏτηση δεν υποστηÏίζει την Ï€Ïόβλεψη του Ï„Ïπου πεÏιεχομένων" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +#, fuzzy +#| msgid "mount doesn't implement synchronous content type guessing" +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "η Ï€ÏοσάÏτηση δεν υποστηÏίζει την Ï€Ïόβλεψη σÏγχÏονου Ï„Ïπου πεÏιεχομένου" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Το όνομα κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î® «%s» πεÏιέχει το «[» αλλά όχι το «]»" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "ΑπÏοσπέλαστο δίκτυο" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "ΑπÏοσπέλαστος κεντÏικός υπολογιστής" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Αδυναμία δημιουÏγίας παÏακολοÏθησης δικτÏου: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Αδυναμία δημιουÏγίας παÏακολοÏθησης δικτÏου: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Αδυναμία λήψης κατάστασης δικτÏου: " + +#: gio/gnetworkmonitornm.c:348 +#, c-format +msgid "NetworkManager not running" +msgstr "Δεν εκτελείται το NetworkManager" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "Î Î¿Î»Ï Ï€Î±Î»Î¹Î¬ έκδοση του NetworkManager" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +#, fuzzy +#| msgid "Output stream doesn't implement write" +msgid "Output stream doesn’t implement write" +msgstr "Η Ïοή εξόδου δεν υποστηÏίζει την εγγÏαφή" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Η Ïοή πηγής έχει ήδη κλείσει" + +# +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Σφάλμα επίλυσης του «%s»: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:615 +#, c-format +msgid "%s not implemented" +msgstr "" + +#: gio/gresolver.c:984 gio/gresolver.c:1036 +msgid "Invalid domain" +msgstr "Μη έγκυÏος τομέας" + +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, fuzzy, c-format +#| msgid "The resource at '%s' does not exist" +msgid "The resource at “%s†does not exist" +msgstr "Η πηγή στο '%s' δεν υπάÏχει" + +#: gio/gresource.c:830 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Αποτυχία αποσυμπίεσης πηγής στο «%s»" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Η πηγή στο «%s» δεν είναι κατάλογος" + +#: gio/gresourcefile.c:940 +#, fuzzy +#| msgid "Input stream doesn't implement seek" +msgid "Input stream doesn’t implement seek" +msgstr "Η Ïοή εισόδου δεν υποστηÏίζει αναζήτηση" + +#: gio/gresource-tool.c:499 +msgid "List sections containing resources in an elf FILE" +msgstr "Οι ενότητες λίστας πεÏιέχουν πηγές σε ΑΡΧΕΙΟ elf" + +#: gio/gresource-tool.c:505 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Πηγές λίστας\n" +"Εάν δίνεται ΕÎΟΤΗΤΑ, μόνο πηγές λίστας σε αυτήν την ενότητα\n" +"Εάν δίνεται ΔΙΑΔΡΟΜΗ, μόνο λίστα που ταιÏιάζει στις πηγές" + +#: gio/gresource-tool.c:508 gio/gresource-tool.c:518 +msgid "FILE [PATH]" +msgstr "ΑΡΧΕΙΟ [ΔΙΑΔΡΟΜΗ]" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 gio/gresource-tool.c:526 +msgid "SECTION" +msgstr "ΕÎΟΤΗΤΑ" + +#: gio/gresource-tool.c:514 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Πηγές λίστας με λεπτομέÏειες\n" +"Εάν δίνεται ΕÎΟΤΗΤΑ, μόνο πηγές λίστας σε αυτήν την ενότητα\n" +"Εάν δίνεται ΔΙΑΔΡΟΜΗ, μόνο λίστα που ταιÏιάζει στις πηγές\n" +"Οι λεπτομέÏειες πεÏιλαμβάνουν την ενότητα, μέγεθος και συμπίεση" + +#: gio/gresource-tool.c:524 +msgid "Extract a resource file to stdout" +msgstr "Εξαγωγή αÏχείου πηγής σε τυπική έξοδο" + +#: gio/gresource-tool.c:525 +msgid "FILE PATH" +msgstr "ΔΙΑΔΡΟΜΗ ΑΡΧΕΙΟΥ" + +#: gio/gresource-tool.c:539 +#, fuzzy +#| msgid "" +#| "Usage:\n" +#| " gresource [--section SECTION] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " sections List resource sections\n" +#| " list List resources\n" +#| " details List resources with details\n" +#| " extract Extract a resource\n" +#| "\n" +#| "Use 'gresource help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ΧÏήση:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Εντολές:\n" +" help ΠÏοβολή αυτών των πληÏοφοÏιών\n" +" sections Ενότητες πηγής λίστας\n" +" list Πηγές λίστας\n" +" details Πηγές λίστας με λεπτομέÏειες\n" +" extract Εξαγωγή πηγής\n" +"\n" +"ΧÏήση 'gresource help COMMAND' για λήψη αναλυτικής βοήθειας.\n" +"\n" + +#: gio/gresource-tool.c:553 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ΧÏήση:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:560 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION Ένα (Ï€ÏοαιÏετικό) όνομα ενότητας elf\n" + +#: gio/gresource-tool.c:564 gio/gsettings-tool.c:701 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND Η (Ï€ÏοαιÏετική) εντολή για επεξήγηση\n" + +#: gio/gresource-tool.c:570 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE Ένα αÏχείο elf (δυαδικό ή κοινόχÏηστης βιβλιοθήκης)\n" + +#: gio/gresource-tool.c:573 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE ΑÏχείο elf (δυαδικό ή κοινόχÏηστης βιβλιοθήκης)\n" +" ή μεταγλωττισμένο πηγαίο αÏχείο\n" + +#: gio/gresource-tool.c:577 +msgid "[PATH]" +msgstr "[ΔΙΑΔΡΟΜΗ]" + +#: gio/gresource-tool.c:579 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH (ΠÏοαιÏετική) διαδÏομή πηγής (μποÏεί να είναι μεÏικό)\n" + +#: gio/gresource-tool.c:580 +msgid "PATH" +msgstr "ΔΙΑΔΡΟΜΗ" + +#: gio/gresource-tool.c:582 +msgid " PATH A resource path\n" +msgstr " PATH ΔιαδÏομή πηγής\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:906 +#, fuzzy, c-format +#| msgid "No such schema '%s'\n" +msgid "No such schema “%sâ€\n" +msgstr "ΧωÏίς τέτοιο σχήμα '%s'\n" + +#: gio/gsettings-tool.c:55 +#, fuzzy, c-format +#| msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" +"Το σχήμα '%s' δεν μποÏεί να μετακινηθεί (δεν Ï€Ïέπει να οÏισθεί διαδÏομή)\n" + +#: gio/gsettings-tool.c:76 +#, fuzzy, c-format +#| msgid "Schema '%s' is relocatable (path must be specified)\n" +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Το σχήμα '%s' μποÏεί να μετακινηθεί (Ï€Ïέπει να οÏισθεί διαδÏομή)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Δόθηκε κενή διαδÏομή.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Η διαδÏομή Ï€Ïέπει να αÏχίζει με μια κάθετο (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Η διαδÏομή Ï€Ïέπει να τελειώνει με μια κάθετο (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Η διαδÏομή δεν Ï€Ïέπει να πεÏιέχει δÏο συνεχόμενες καθέτους (//)\n" + +#: gio/gsettings-tool.c:536 +msgid "The provided value is outside of the valid range\n" +msgstr "Η παÏεχόμενη τιμή είναι εκτός του έγκυÏου εÏÏους\n" + +#: gio/gsettings-tool.c:543 +msgid "The key is not writable\n" +msgstr "Το κλειδί δεν είναι εγγÏάψιμο\n" + +#: gio/gsettings-tool.c:579 +msgid "List the installed (non-relocatable) schemas" +msgstr "ΑπαÏίθμηση των εγκατεστήμενων (μη μετακινοÏμενων) σχημάτων" + +#: gio/gsettings-tool.c:585 +msgid "List the installed relocatable schemas" +msgstr "ΑπαÏίθμηση των εγκατεστήμενων μετακινοÏμενων σχημάτων" + +#: gio/gsettings-tool.c:591 +msgid "List the keys in SCHEMA" +msgstr "ΑπαÏιθμεί τα κλειδιά στο SCHEMA" + +#: gio/gsettings-tool.c:592 gio/gsettings-tool.c:598 gio/gsettings-tool.c:641 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:597 +msgid "List the children of SCHEMA" +msgstr "ΑπαÏιθμεί τις θυγατÏικές του SCHEMA" + +#: gio/gsettings-tool.c:603 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"ΑπαÏίθμηση κλειδιών και τιμών, αναδÏομικά\n" +"Αν δε δίνεται SCHEMA, Ï€Ïοβολή όλων των κλειδιών\n" + +#: gio/gsettings-tool.c:605 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:610 +msgid "Get the value of KEY" +msgstr "Λήψη τιμής της KEY" + +#: gio/gsettings-tool.c:611 gio/gsettings-tool.c:617 gio/gsettings-tool.c:623 +#: gio/gsettings-tool.c:635 gio/gsettings-tool.c:647 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:616 +msgid "Query the range of valid values for KEY" +msgstr "Αναζητεί το εÏÏος των έγκυÏων τιμών για KEY" + +#: gio/gsettings-tool.c:622 +#, fuzzy +#| msgid "Query the range of valid values for KEY" +msgid "Query the description for KEY" +msgstr "Αναζητεί το εÏÏος των έγκυÏων τιμών για KEY" + +#: gio/gsettings-tool.c:628 +msgid "Set the value of KEY to VALUE" +msgstr "ΟÏίζει την τιμή της KEY σε VALUE" + +#: gio/gsettings-tool.c:629 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:634 +msgid "Reset KEY to its default value" +msgstr "ΕπαναφέÏει την KEY στην Ï€Ïοεπιλεγμένη της τιμή" + +#: gio/gsettings-tool.c:640 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "ΕπαναφοÏά όλων των κλειδιών στο SCHEMA στις Ï€Ïοεπιλογές τους" + +#: gio/gsettings-tool.c:646 +msgid "Check if KEY is writable" +msgstr "Έλεγχος εγγÏαψιμότητας του KEY" + +#: gio/gsettings-tool.c:652 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"ΠαÏακολουθεί το KEY για αλλαγές.\n" +"Αν δεν έχει οÏισθεί KEY, παÏακολουθεί όλα τα κλειδιά στο SCHEMA.\n" +"ΧÏησιμοποιείστε το ^C για τεÏματισμό της παÏακολοÏθησης.\n" + +#: gio/gsettings-tool.c:655 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: gio/gsettings-tool.c:667 +#, fuzzy +#| msgid "" +#| "Usage:\n" +#| " gsettings --version\n" +#| " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " list-schemas List installed schemas\n" +#| " list-relocatable-schemas List relocatable schemas\n" +#| " list-keys List keys in a schema\n" +#| " list-children List children of a schema\n" +#| " list-recursively List keys and values, recursively\n" +#| " range Queries the range of a key\n" +#| " get Get the value of a key\n" +#| " set Set the value of a key\n" +#| " reset Reset the value of a key\n" +#| " reset-recursively Reset all values in a given schema\n" +#| " writable Check if a key is writable\n" +#| " monitor Watch for changes\n" +#| "\n" +#| "Use 'gsettings help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ΧÏήση:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Εντολές:\n" +" help Εμφάνιση αυτών των πληÏοφοÏιών\n" +" list-schemas Λίστα εγκατεστημένων σχημάτων\n" +" list-relocatable-schemas Λίστα μετακινοÏμενων σχημάτων\n" +" list-keys Λίστα κλειδιών σε σχήματος\n" +" list-children Λίστα θυγατÏικών ενός σχήματος\n" +" list-recursively Λίστα κλειδιών και τιμών, αναδÏομικά\n" +" range Αναζήτηση εÏÏους κλειδιοÏ\n" +" get Λήψη τιμής κλειδιοÏ\n" +" set ΟÏισμός τιμής ενός κλειδιοÏ\n" +" reset-recursively ΕπαναφοÏά όλων των τιμών σε δεδομένο σχήμα\n" +" reset ΕπαναφοÏά τιμής κλειδιοÏ\n" +" writable Έλεγχος εγγÏαψιμότητας κλειδιοÏ\n" +" monitor ΠαÏακολοÏθηση αλλαγών\n" +"\n" +"ΧÏησιμοποιήστε 'gsettings help COMMAND' για αναλυτική βοήθεια.\n" +"\n" + +#: gio/gsettings-tool.c:691 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ΧÏήση:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:697 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR Κατάλογος αναζήτησης για Ï€Ïόσθετα σχήματα\n" + +#: gio/gsettings-tool.c:705 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA Το όνομα του σχήματος\n" +" PATH Η διαδÏομή, για μετακινοÏμενα σχήματα\n" + +#: gio/gsettings-tool.c:710 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY Το (Ï€ÏοαιÏετικό) κλειδί στο σχήμα\n" + +#: gio/gsettings-tool.c:714 +msgid " KEY The key within the schema\n" +msgstr " KEY Το κλειδί στο σχήμα\n" + +#: gio/gsettings-tool.c:718 +msgid " VALUE The value to set\n" +msgstr " VALUE Η τιμή που θα οÏισθεί\n" + +#: gio/gsettings-tool.c:773 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Αδυναμία φόÏτωσης διατάξεων από %s: %s\n" + +#: gio/gsettings-tool.c:785 +msgid "No schemas installed\n" +msgstr "Δεν εγκαταστάθηκαν σχήματα\n" + +#: gio/gsettings-tool.c:864 +msgid "Empty schema name given\n" +msgstr "Δόθηκε κενό όνομα σχήματος\n" + +#: gio/gsettings-tool.c:919 +#, fuzzy, c-format +#| msgid "No such key '%s'\n" +msgid "No such key “%sâ€\n" +msgstr "ΧωÏίς τέτοιο κλειδί '%s'\n" + +#: gio/gsocket.c:418 +msgid "Invalid socket, not initialized" +msgstr "ΆκυÏος υποδοχέας, δεν αÏχικοποιήθηκε" + +#: gio/gsocket.c:425 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ΆκυÏος υποδοχέας, η αÏχικοποίηση απέτυχε λόγω του: %s" + +#: gio/gsocket.c:433 +msgid "Socket is already closed" +msgstr "Ο υποδοχέας είναι ήδη κλειστός" + +#: gio/gsocket.c:448 gio/gsocket.c:3185 gio/gsocket.c:4408 gio/gsocket.c:4466 +msgid "Socket I/O timed out" +msgstr "Η υποδοχή I/O έληξε" + +#: gio/gsocket.c:583 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "δημιουÏγία GSocket από fd: %s" + +# gconf/gconf-internals.c:2416 +#: gio/gsocket.c:612 gio/gsocket.c:666 gio/gsocket.c:673 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Αδυναμία δημιουÏγίας υποδοχέα: %s" + +#: gio/gsocket.c:666 +msgid "Unknown family was specified" +msgstr "ΟÏίστηκε άγνωστη οικογένεια" + +#: gio/gsocket.c:673 +msgid "Unknown protocol was specified" +msgstr "ΟÏίστηκε άγνωστο Ï€Ïωτόκολλο" + +#: gio/gsocket.c:1164 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Αδυναμία χÏήσης αυτοδÏναμων λειτουÏγιών σε μια μη αυτοδÏναμη υποδοχή." + +#: gio/gsocket.c:1181 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Αδυναμία χÏήσης αυτοδÏναμων λειτουÏγιών σε μια υποδοχή με οÏισμένο χÏόνο " +"λήξης." + +#: gio/gsocket.c:1988 +#, c-format +msgid "could not get local address: %s" +msgstr "αδυναμία λήψης τοπικής διεÏθυνσης: %s" + +#: gio/gsocket.c:2034 +#, c-format +msgid "could not get remote address: %s" +msgstr "αδυναμία λήψης απομακÏυσμένης διεÏθυνσης: %s" + +#: gio/gsocket.c:2100 +#, c-format +msgid "could not listen: %s" +msgstr "αδυναμία ακÏόασης: %s" + +#: gio/gsocket.c:2204 +#, fuzzy, c-format +#| msgid "Error binding to address: %s" +msgid "Error binding to address %s: %s" +msgstr "Σφάλμα σÏνδεσης στην διεÏθυνση: %s" + +# gconf/gconftool.c:1181 +#: gio/gsocket.c:2380 gio/gsocket.c:2417 gio/gsocket.c:2527 gio/gsocket.c:2552 +#: gio/gsocket.c:2615 gio/gsocket.c:2673 gio/gsocket.c:2691 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Σφάλμα ένωσης ομάδας πολυεκπομπής: %s" + +# gconf/gconftool.c:1181 +#: gio/gsocket.c:2381 gio/gsocket.c:2418 gio/gsocket.c:2528 gio/gsocket.c:2553 +#: gio/gsocket.c:2616 gio/gsocket.c:2674 gio/gsocket.c:2692 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Σφάλμα απομάκÏυνσης ομάδας πολυεκπομπής: %s" + +#: gio/gsocket.c:2382 +msgid "No support for source-specific multicast" +msgstr "ΧωÏίς υποστήÏιξη για πολυεκπομπή ειδικής πηγής" + +#: gio/gsocket.c:2529 +#, fuzzy +#| msgid "Unsupported socket address" +msgid "Unsupported socket family" +msgstr "ΑνυποστήÏικτη διεÏθυνση υποδοχέα" + +#: gio/gsocket.c:2554 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2578 +#, c-format +msgid "Interface name too long" +msgstr "Το όνομα διεπαφής είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿" + +#: gio/gsocket.c:2591 gio/gsocket.c:2641 +#, c-format +msgid "Interface not found: %s" +msgstr "Δεν βÏέθηκε η διεπαφή: %s" + +#: gio/gsocket.c:2617 +#, fuzzy +#| msgid "No support for source-specific multicast" +msgid "No support for IPv4 source-specific multicast" +msgstr "ΧωÏίς υποστήÏιξη για πολυεκπομπή ειδικής πηγής" + +#: gio/gsocket.c:2675 +#, fuzzy +#| msgid "No support for source-specific multicast" +msgid "No support for IPv6 source-specific multicast" +msgstr "ΧωÏίς υποστήÏιξη για πολυεκπομπή ειδικής πηγής" + +# gconf/gconftool.c:1181 +#: gio/gsocket.c:2884 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Σφάλμα αποδοχής σÏνδεσης: %s" + +#: gio/gsocket.c:3010 +msgid "Connection in progress" +msgstr "ΣÏνδεση σε εξέλιξη" + +# gconf/gconf-internals.c:2416 +#: gio/gsocket.c:3061 +msgid "Unable to get pending error: " +msgstr "Αδυναμία λήψης εκκÏεμοÏÏ‚ σφάλματος: " + +#: gio/gsocket.c:3250 +#, c-format +msgid "Error receiving data: %s" +msgstr "Σφάλμα λήψης δεδομένων: %s" + +#: gio/gsocket.c:3447 +#, c-format +msgid "Error sending data: %s" +msgstr "Σφάλμα αποστολής δεδομένων: %s" + +# gconf/gconf-internals.c:2416 +#: gio/gsocket.c:3634 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Αδυναμία τεÏÎ¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Ï…Ï€Î¿Î´Î¿Ï‡Î®Ï‚: %s" + +#: gio/gsocket.c:3715 +#, c-format +msgid "Error closing socket: %s" +msgstr "Σφάλμα τεÏÎ¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Ï…Ï€Î¿Î´Î¿Ï‡Î­Î±: %s" + +#: gio/gsocket.c:4401 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Αναμονή για την συνθήκη υποδοχέα: %s" + +#: gio/gsocket.c:4779 gio/gsocket.c:4781 gio/gsocket.c:4928 gio/gsocket.c:5013 +#: gio/gsocket.c:5191 gio/gsocket.c:5231 gio/gsocket.c:5233 +#, c-format +msgid "Error sending message: %s" +msgstr "Σφάλμα αποστολής μηνÏματος: %s" + +#: gio/gsocket.c:4955 +msgid "GSocketControlMessage not supported on Windows" +msgstr "Το GSocketControlMessage δεν υποστηÏίζεται στα Windows" + +#: gio/gsocket.c:5424 gio/gsocket.c:5497 gio/gsocket.c:5723 +#, c-format +msgid "Error receiving message: %s" +msgstr "Σφάλμα λήψης μηνÏματος: %s" + +# gconf/gconf-internals.c:2416 +#: gio/gsocket.c:5995 gio/gsocket.c:6043 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "ΑδÏνατη η ανάγνωση διαπιστευτηÏίων υποδοχής: %s" + +#: gio/gsocket.c:6052 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"το g_socket_get_credentials δεν έχει υλοποιηθεί για αυτό το λειτουÏγικό " +"σÏστημα" + +#: gio/gsocketclient.c:182 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Αδυναμία σÏνδεσης στον διακομιστή διαμεσολάβησης %s: " + +#: gio/gsocketclient.c:196 +#, c-format +msgid "Could not connect to %s: " +msgstr "Αδυναμία σÏνδεσης στο %s: " + +#: gio/gsocketclient.c:198 +msgid "Could not connect: " +msgstr "Αδυναμία σÏνδεσης: " + +#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1866 +msgid "Unknown error on connect" +msgstr "Άγνωστο σφάλμα σÏνδεσης" + +#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1668 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Η Ï€Ïοσπάθεια διαμεσολάβησης σε σÏνδεση εκτός TCP δεν υποστηÏίζεται." + +#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698 +#, fuzzy, c-format +#| msgid "Proxy protocol '%s' is not supported." +msgid "Proxy protocol “%s†is not supported." +msgstr "Το Ï€Ïωτόκολλο διαμεσολαβητή '%s' δεν υποστηÏίζεται." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Η ακÏόαση έχει ήδη κλείσει" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Ο Ï€Ïόσθετος υποδοχέας είναι κλειστός" + +#: gio/gsocks4aproxy.c:118 +#, fuzzy, c-format +#| msgid "SOCKSv4 does not support IPv6 address '%s'" +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "Το SOCKSv4 δεν υποστηÏίζει τη διεÏθυνση IPv6 '%s'" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Το όνομα χÏήστη είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿ για το Ï€Ïωτόκολλο SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, fuzzy, c-format +#| msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "" +"Το όνομα του κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î® '%s' είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿ για το Ï€Ïωτόκολλο " +"SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Ο διακομιστής δεν είναι διαμεσολαβητής SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Η σÏνδεση μέσω διακομιστή SOCKSv4 αποÏÏίφθηκε" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Ο διακομιστής δεν είναι διαμεσολαβητής SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Ο διαμεσολαβητής SOCKSv5 απαιτεί επικÏÏωση." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Ο διαμεσολαβητής SOCKSv5 απαιτεί μέθοδο επικÏÏωσης που δεν υποστηÏίζεται από " +"GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"Το όνομα χÏήστη ή ο κωδικός Ï€Ïόσβασης είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î± για το Ï€Ïωτόκολλο " +"SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "Αποτυχία επικÏÏωσης SOCKSv5 οφειλόμενη σε λάθος όνομα χÏήστη ή κωδικό." + +#: gio/gsocks5proxy.c:300 +#, fuzzy, c-format +#| msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "" +"Το όνομα κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î® '%s' είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿ για το Ï€Ïωτόκολλο " +"SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" +"Ο διακομιστής διαμεσολάβησης SOCKSv5 χÏησιμοποιεί άγνωστο Ï„Ïπο διεÏθυνσης." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "ΕσωτεÏικό σφάλμα διακομιστή διαμεσολάβησης SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Η σÏνδεση SOCKSv5 δεν επιτÏέπεται από το σÏνολο των κανόνων." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "ΑπÏόσιτος κεντÏικός υπολογιστής μέσω του διακομιστή SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "ΑπÏοσπέλαστο δίκτυο μέσω του διαμεσολαβητή SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Η σÏνδεση αποÏÏίφθηκε από τον διαμεσολαβητή SOCKSv5." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Ο διαμεσολαβητής SOCKSv5 δεν υποστηÏίζει την εντολή «σÏνδεση»." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" +"Ο διαμεσολαβητής SOCKSv5 δεν υποστηÏίζει τον παÏεχόμενο Ï„Ïπο διεÏθυνσης." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Άγνωστο σφάλμα του διαμεσολαβητή SOCKSv5." + +#: gio/gthemedicon.c:595 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Αδυναμία χειÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ έκδοσης %d της κωδικοποίησης GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Δεν βÏέθηκαν έγκυÏες διευθÏνσεις" + +# +#: gio/gthreadedresolver.c:337 +#, fuzzy, c-format +#| msgid "Error reverse-resolving '%s': %s" +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Σφάλμα ανάστÏοφης επίλυσης του '%s': %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "ΧωÏίς εγγÏαφή DNS του αιτοÏμενου Ï„Ïπου για «%s»" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "ΠÏοσωÏινή αδυναμία επίλυσης του «%s»" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Σφάλμα επίλυσης του «%s»" + +#: gio/gtlscertificate.c:243 +msgid "No PEM-encoded private key found" +msgstr "Δεν βÏέθηκε ιδιωτικό κλειδί κωδικοποιημένο κατά PEM" + +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Αδυναμία αποκÏυπτογÏάφησης Î¹Î´Î¹Ï‰Ï„Î¹ÎºÎ¿Ï ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎºÏ‰Î´Î¹ÎºÎ¿Ï€Î¿Î¹Î·Î¼Î­Î½Î¿Ï… κατά PEM" + +#: gio/gtlscertificate.c:264 +msgid "Could not parse PEM-encoded private key" +msgstr "Αδυναμία ανάλυσης Î¹Î´Î¹Ï‰Ï„Î¹ÎºÎ¿Ï ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎºÏ‰Î´Î¹ÎºÎ¿Ï€Î¿Î¹Î·Î¼Î­Î½Î¿Ï… κατά PEM" + +#: gio/gtlscertificate.c:291 +msgid "No PEM-encoded certificate found" +msgstr "Δεν βÏέθηκε πιστοποιητικό κωδικοποιημένο κατά PEM" + +#: gio/gtlscertificate.c:300 +msgid "Could not parse PEM-encoded certificate" +msgstr "Αδυναμία ανάλυσης Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï ÎºÏ‰Î´Î¹ÎºÎ¿Ï€Î¿Î¹Î·Î¼Î­Î½Î¿Ï… κατά PEM" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Αυτή είναι η τελευταία ευκαιÏία εισαγωγής ÏƒÏ‰ÏƒÏ„Î¿Ï ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïιν το κλείδωμα " +"της Ï€Ïόσβασής σας." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +#, fuzzy +#| msgid "" +#| "Several password entered have been incorrect, and your access will be " +#| "locked out after further failures." +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Οι εισαγμένοι κωδικοί είναι λάθος και η Ï€Ïόσβασή σας θα κλειδωθεί μετά από " +"Ï€Ïόσθετες αποτυχίες." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Ο εισαγμένος κωδικός είναι λάθος." + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Αναμενόταν 1 μήνυμα έλεγχου, ελήφθη %d" +msgstr[1] "Αναμενόταν 1 μήνυμα έλεγχου, ελήφθη %d" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "Αναπάντεχος Ï„Ïπος βοηθητικών δεδομένων" + +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Αναμενόταν ένα fd, αλλά ελήφθη %d\n" +msgstr[1] "Αναμενόταν ένα fd, αλλά ελήφθη %d\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Λήψη άκυÏου fd" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "Σφάλμα στην αποστολή πιστοποιητικών: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Σφάλμα ελέγχου ενεÏγοποίησης SO_PASSCRED υποδοχής: %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Σφάλμα ενεÏγοποίησης SO_PASSCRED: %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Αναμονή ανάγνωσης μιας μόνο byte για τη λήψη πιστοποιητικών, αλλά ανάγνωση " +"μηδέν bytes" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "ΧωÏίς αναμονή μηνÏματος έλεγχου, αλλά λήψη %d" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Σφάλμα απενεÏγοποίησης SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:362 gio/gunixinputstream.c:383 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Σφάλμα ανάγνωσης πεÏιγÏαφέα αÏχείου: %s" + +#: gio/gunixinputstream.c:416 gio/gunixoutputstream.c:525 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Σφάλμα κλεισίματος πεÏιγÏαφέα αÏχείου: %s" + +#: gio/gunixmounts.c:2709 gio/gunixmounts.c:2762 +msgid "Filesystem root" +msgstr "ΔιαχειÏιστής συστήματος αÏχείων" + +#: gio/gunixoutputstream.c:362 gio/gunixoutputstream.c:382 +#: gio/gunixoutputstream.c:469 gio/gunixoutputstream.c:489 +#: gio/gunixoutputstream.c:635 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Σφάλμα εγγÏαφής πεÏιγÏαφέα αÏχείου: %s" + +#: gio/gunixsocketaddress.c:243 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Δεν υποστηÏίζονται αφηÏημένες διευθÏνσεις υποδοχής τομέα unix σε αυτό το " +"σÏστημα" + +#: gio/gvolume.c:438 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "volume doesn’t implement eject" +msgstr "ο τόμος δεν υποστηÏίζει εξαγωγή" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "ο τόμος δεν υποστηÏίζει την εξαγωγή ή eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Σφάλμα ανάγνωσης χειÏιστηÏίου: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Σφάλμα κλεισίματος χειÏιστηÏίου: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Σφάλμα εγγÏαφής επεξεÏγασίας: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "ΑνεπάÏκεια μνήμης" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "ΕσωτεÏικό σφάλμα: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "ΧÏειάζεται πεÏισσότεÏες εισαγωγές" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "ΆκυÏα συμπιεσμένα δεδομένα" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ΔιεÏθυνση ακÏόασης" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "ΠαÏάβλεψη συμβατότητας με GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "ΔιεÏθυνση εκτÏπωσης" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "ΕκτÏπωση διεÏθυνσης σε κατάσταση κελÏφους" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Εκτέλεση υπηÏεσίας dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Εσφαλμένα οÏίσματα\n" + +#: glib/gbookmarkfile.c:768 +#, fuzzy, c-format +#| msgid "Unexpected attribute '%s' for element '%s'" +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Αναπάντεχο γνώÏισμα '%s' για το στοιχείο '%s'" + +#: glib/gbookmarkfile.c:779 glib/gbookmarkfile.c:859 glib/gbookmarkfile.c:869 +#: glib/gbookmarkfile.c:982 +#, fuzzy, c-format +#| msgid "Attribute '%s' of element '%s' not found" +msgid "Attribute “%s†of element “%s†not found" +msgstr "Το γνώÏισμα '%s' του στοιχείου '%s' δεν βÏέθηκε" + +#: glib/gbookmarkfile.c:1191 glib/gbookmarkfile.c:1256 +#: glib/gbookmarkfile.c:1320 glib/gbookmarkfile.c:1330 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "ΑπÏόσμενη ετικέτα «%s», αναμενόταν ετικέτα «%s»" + +#: glib/gbookmarkfile.c:1216 glib/gbookmarkfile.c:1230 +#: glib/gbookmarkfile.c:1298 glib/gbookmarkfile.c:1344 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "ΑπÏόσμενη ετικέτα «%s» στο «%s»" + +#: glib/gbookmarkfile.c:1624 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1827 +msgid "No valid bookmark file found in data dirs" +msgstr "Δεν βÏέθηκε έγκυÏο αÏχείο σελιδοδεικτών στους καταλόγους δεδομένων" + +#: glib/gbookmarkfile.c:2028 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "ΥπάÏχει ήδη ένας σελιδοδείκτης για το URI «%s»" + +#: glib/gbookmarkfile.c:2077 glib/gbookmarkfile.c:2235 +#: glib/gbookmarkfile.c:2320 glib/gbookmarkfile.c:2400 +#: glib/gbookmarkfile.c:2485 glib/gbookmarkfile.c:2619 +#: glib/gbookmarkfile.c:2752 glib/gbookmarkfile.c:2887 +#: glib/gbookmarkfile.c:2929 glib/gbookmarkfile.c:3026 +#: glib/gbookmarkfile.c:3147 glib/gbookmarkfile.c:3341 +#: glib/gbookmarkfile.c:3482 glib/gbookmarkfile.c:3701 +#: glib/gbookmarkfile.c:3790 glib/gbookmarkfile.c:3879 +#: glib/gbookmarkfile.c:3998 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Δεν βÏέθηκε σελιδοδείκτης για το URI «%s»" + +#: glib/gbookmarkfile.c:2409 +#, fuzzy, c-format +#| msgid "No MIME type defined in the bookmark for URI '%s'" +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Δεν αναγνωÏίστηκε κανένας Ï„Ïπος MIME στο σελιδοδείκτη για το URI '%s'" + +#: glib/gbookmarkfile.c:2494 +#, fuzzy, c-format +#| msgid "No private flag has been defined in bookmark for URI '%s'" +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" +"Καμιά Ï€Ïοσωπική σημαία δεν έχει αναγνωÏιστεί στο σελιδοδείκτη για το URI '%s'" + +#: glib/gbookmarkfile.c:3035 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Δεν οÏίστηκαν ομάδες στο σελιδοδείκτη για το URI «%s»" + +#: glib/gbookmarkfile.c:3503 glib/gbookmarkfile.c:3711 +#, fuzzy, c-format +#| msgid "No application with name '%s' registered a bookmark for '%s'" +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" +"Καμιά εφαÏμογή με όνομα '%s' δεν έχει καταχωÏήσει σελιδοδείκτη για τη '%s'" + +# gconf/gconf-internals.c:2416 +#: glib/gbookmarkfile.c:3734 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Αποτυχία ανάπτυξης της γÏαμμής exec «%s» με URI «%s»" + +#: glib/gconvert.c:466 +#, fuzzy +#| msgid "Invalid sequence in conversion input" +msgid "Unrepresentable character in conversion input" +msgstr "ΆκυÏη σειÏά στην είσοδο μετατÏοπής" + +#: glib/gconvert.c:493 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "Ημιτελής σειÏά χαÏακτήÏα στο τέλος της εισόδου" + +#: glib/gconvert.c:762 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Αδυναμία μετατÏοπής υποχώÏησης «%s» σε σÏνολο κώδικα «%s»" + +#: glib/gconvert.c:934 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "ΆκυÏη σειÏά byte στην είσοδο μετατÏοπής" + +#: glib/gconvert.c:955 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "ΆκυÏη σειÏά byte στην είσοδο μετατÏοπής" + +#: glib/gconvert.c:1640 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" +"Το URI «%s» δεν είναι ένα απόλυτο URI με την χÏήση του σχήματος «αÏχείου»" + +#: glib/gconvert.c:1650 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Το URI Ï„Î¿Ï€Î¹ÎºÎ¿Ï Î±Ïχείου «%s» μποÏεί να μην πεÏιέχει ένα «#»" + +#: glib/gconvert.c:1667 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Το URI «%s» δεν είναι έγκυÏο" + +#: glib/gconvert.c:1679 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Το όνομα κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î® του URI «%s» δεν είναι έγκυÏο" + +#: glib/gconvert.c:1695 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Το URI «%s» πεÏιέχει άκυÏους χαÏακτήÏες διαφυγής" + +#: glib/gconvert.c:1767 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Το όνομα διαδÏομής «%s» δεν είναι απόλυτη διαδÏομή" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:220 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e %b %Y %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:223 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:268 +msgctxt "full month name" +msgid "January" +msgstr "ΙανουάÏιος" + +#: glib/gdatetime.c:270 +msgctxt "full month name" +msgid "February" +msgstr "ΦεβÏουάÏιος" + +#: glib/gdatetime.c:272 +msgctxt "full month name" +msgid "March" +msgstr "ΜάÏτιος" + +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "April" +msgstr "ΑπÏίλιος" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "May" +msgstr "Μάιος" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "June" +msgstr "ΙοÏνιος" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "July" +msgstr "ΙοÏλιος" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "August" +msgstr "ΑÏγουστος" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "September" +msgstr "ΣεπτέμβÏιος" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "October" +msgstr "ΟκτώβÏιος" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "November" +msgstr "ÎοέμβÏιος" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "December" +msgstr "ΔεκέμβÏιος" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:322 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Ιαν" + +#: glib/gdatetime.c:324 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Φεβ" + +#: glib/gdatetime.c:326 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "ΜάÏ" + +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "ΑπÏ" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Μάι" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ΙοÏν" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ΙοÏλ" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ΑÏγ" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Σεπ" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Οκτ" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Îοέ" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Δεκ" + +#: glib/gdatetime.c:359 +msgctxt "full weekday name" +msgid "Monday" +msgstr "ΔευτέÏα" + +#: glib/gdatetime.c:361 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "ΤÏίτη" + +#: glib/gdatetime.c:363 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "ΤετάÏτη" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Πέμπτη" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Friday" +msgstr "ΠαÏασκευή" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Σάββατο" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ΚυÏιακή" + +#: glib/gdatetime.c:386 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Δευ" + +#: glib/gdatetime.c:388 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ΤÏί" + +#: glib/gdatetime.c:390 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Τετ" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Πέμ" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ΠαÏ" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Σάβ" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ΚυÏ" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:462 +msgctxt "full month name with day" +msgid "January" +msgstr "ΙανουαÏίου" + +#: glib/gdatetime.c:464 +msgctxt "full month name with day" +msgid "February" +msgstr "ΦεβÏουαÏίου" + +#: glib/gdatetime.c:466 +msgctxt "full month name with day" +msgid "March" +msgstr "ΜαÏτίου" + +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "April" +msgstr "ΑπÏιλίου" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "May" +msgstr "ΜαÎου" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "June" +msgstr "Ιουνίου" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "July" +msgstr "Ιουλίου" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "August" +msgstr "ΑυγοÏστου" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "September" +msgstr "ΣεπτεμβÏίου" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "October" +msgstr "ΟκτωβÏίου" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "November" +msgstr "ÎοεμβÏίου" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "December" +msgstr "ΔεκεμβÏίου" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:549 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Ιαν" + +#: glib/gdatetime.c:551 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Φεβ" + +#: glib/gdatetime.c:553 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "ΜαÏ" + +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "ΑπÏ" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "ΜαÎ" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Ιουν" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Ιουλ" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Αυγ" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Σεπ" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Οκτ" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Îοε" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Δεκ" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:588 +msgctxt "GDateTime" +msgid "AM" +msgstr "ΠΜ" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:591 +msgctxt "GDateTime" +msgid "PM" +msgstr "ΜΜ" + +# +#: glib/gdir.c:154 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Σφάλμα ανοίγματος καταλόγου «%s»: %s" + +# +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Αδυναμία διάθεσης %lu byte για ανάγνωση αÏχείου «%s»" +msgstr[1] "Αδυναμία διάθεσης %lu bytes για ανάγνωση αÏχείου «%s»" + +# +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Σφάλμα ανάγνωσης αÏχείου «%s»: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Το αÏχείο «%s» είναι υπεÏβολικά μεγάλο" + +# gconf/gconf-internals.c:2416 +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Αποτυχία ανάγνωσης από το αÏχείο «%s»: %s" + +# gconf/gconf-internals.c:2416 +#: glib/gfileutils.c:898 glib/gfileutils.c:970 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Αποτυχία ανοίγματος αÏχείου «%s»: %s" + +# gconf/gconfd.c:1701 +#: glib/gfileutils.c:910 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Αποτυχία λήψης γνωÏισμάτων αÏχείου «%s»: fstat() απέτυχε: %s" + +# gconf/gconf-internals.c:2416 +#: glib/gfileutils.c:940 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Αποτυχία ανοίγματος αÏχείου «%s»: fdopen() απέτυχε: %s" + +# gconf/gconf-internals.c:2416 +#: glib/gfileutils.c:1039 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Αποτυχία μετονομασίας αÏχείου «%s» σε «%s»: g_rename() απέτυχε: %s" + +# gconf/gconf-internals.c:2416 +#: glib/gfileutils.c:1074 glib/gfileutils.c:1592 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Αποτυχία δημιουÏγίας αÏχείου «%s»: %s" + +# gconf/gconf-internals.c:2416 +#: glib/gfileutils.c:1101 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Αποτυχία εγγÏαφής αÏχείου «%s»: write() απέτυχε: %s" + +# gconf/gconf-internals.c:2416 +#: glib/gfileutils.c:1144 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Αποτυχία εγγÏαφής αÏχείου «%s»: fsync() απέτυχε: %s" + +#: glib/gfileutils.c:1279 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Αδυναμία απομάκÏυνσης του υπάÏχοντος αÏχείου «%s»: g_unlink() απέτυχε: %s" + +#: glib/gfileutils.c:1558 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "ΆκυÏο Ï€Ïότυπο «%s», δεν Ï€Ïέπει να πεÏιέχει «%s»" + +#: glib/gfileutils.c:1571 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Το Ï€Ïότυπο «%s» δεν πεÏιέχει XXXXXX" + +# gconf/gconf-internals.c:2416 +#: glib/gfileutils.c:2129 glib/gfileutils.c:2157 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Αποτυχία ανάγνωσης ÏƒÏ…Î¼Î²Î¿Î»Î¹ÎºÎ¿Ï ÏƒÏ…Î½Î´Î­ÏƒÎ¼Î¿Ï… «%s»: %s" + +#: glib/giochannel.c:1396 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Αδυναμία ανοίγματος μετατÏοπέα από «%s» σε «%s»: %s" + +#: glib/giochannel.c:1749 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_line_string" +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Αδυναμία ανάγνωσης raw σε g_io_channel_read_line_string" + +#: glib/giochannel.c:1796 glib/giochannel.c:2054 glib/giochannel.c:2141 +msgid "Leftover unconverted data in read buffer" +msgstr "Εναπομείναντα αμετάτÏεπτα δεδομένα σε μνήμη ανάγνωσης" + +#: glib/giochannel.c:1877 glib/giochannel.c:1954 +msgid "Channel terminates in a partial character" +msgstr "Το κανάλι τεÏματίζει σε ημιτελή χαÏακτήÏα" + +#: glib/giochannel.c:1940 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_to_end" +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Αδυναμία ανάγνωσης raw σε g_io_channel_read_to_end" + +#: glib/gkeyfile.c:789 +msgid "Valid key file could not be found in search dirs" +msgstr "Αδυναμία εÏÏεσης έγκυÏου αÏχείου ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï ÏƒÏ„Î¿Ï…Ï‚ καταλόγους αναζήτησης" + +#: glib/gkeyfile.c:826 +msgid "Not a regular file" +msgstr "Δεν είναι κανονικό αÏχείο" + +#: glib/gkeyfile.c:1275 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Ï€ÎµÏιέχει την γÏαμμή «%s» που δεν είναι ζεÏγος κλειδιοÏ-" +"τιμής, ομάδας, ή σχολίου" + +#: glib/gkeyfile.c:1332 +#, c-format +msgid "Invalid group name: %s" +msgstr "ΆκυÏο όνομα ομάδας: %s" + +#: glib/gkeyfile.c:1354 +msgid "Key file does not start with a group" +msgstr "Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Î´ÎµÎ½ ξεκινάει με ομάδα" + +#: glib/gkeyfile.c:1380 +#, c-format +msgid "Invalid key name: %s" +msgstr "ΆκυÏο όνομα κλειδιοÏ: %s" + +#: glib/gkeyfile.c:1407 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Ï€ÎµÏιέχει μη υποστηÏιζόμενη κωδικοποίηση «%s»" + +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3340 glib/gkeyfile.c:3470 glib/gkeyfile.c:3602 +#: glib/gkeyfile.c:3748 glib/gkeyfile.c:3977 glib/gkeyfile.c:4044 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Î´ÎµÎ½ έχει ομάδα «%s»" + +#: glib/gkeyfile.c:1778 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Î´ÎµÎ½ έχει κλειδί «%s» στην ομάδα «%s»" + +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Ï€ÎµÏιέχει κλειδί «%s» με τιμή «%s» που δεν είναι UTF-8" + +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Ï€ÎµÏιέχει κλειδί «%s» που πεÏιέχει μια τιμή που δεν μποÏεί " +"να εÏμηνευθεί." + +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Ï€ÎµÏιέχει κλειδί «%s» στην ομάδα «%s» που η τιμή του δεν " +"μποÏεί να εÏμηνευθεί." + +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Το κλειδί «%s» στην ομάδα «%s» έχει τιμή «%s» όταν αναμενόταν %s" + +#: glib/gkeyfile.c:4284 +msgid "Key file contains escape character at end of line" +msgstr "Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Ï€ÎµÏιέχει χαÏακτήÏα διαφυγής στο τέλος της γÏαμμής" + +#: glib/gkeyfile.c:4306 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Ï€ÎµÏιέχει άκυÏη σειÏά διαφυγής «%s»" + +#: glib/gkeyfile.c:4450 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Η τιμή «%s» δεν μποÏεί να εÏμηνευθεί ως αÏιθμός." + +#: glib/gkeyfile.c:4464 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Η ακέÏαιη τιμή «%s» είναι εκτός εÏÏους" + +#: glib/gkeyfile.c:4497 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Η τιμή «%s» δεν μποÏεί να εÏμηνευθεί ως αÏιθμός κινητής υποδιαστολής." + +#: glib/gkeyfile.c:4536 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Η τιμή «%s» δεν μποÏεί να εÏμηνευθεί ως Μπουλ." + +# gconf/gconfd.c:1701 +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Αποτυχία λήψης γνωÏισμάτων του αÏχείου «%s%s%s%s»: fstat() απέτυχε: %s" + +# gconf/gconf-internals.c:2416 +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Αποτυχία χαÏτογÏάφησης %s%s%s%s: mmap() απέτυχε: %s" + +# gconf/gconf-internals.c:2416 +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Αποτυχία ανοίγματος αÏχείου «%s»: open() απέτυχε: %s" + +# gconf/gconfd.c:1676 +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Σφάλμα στη γÏαμμή %d χαÏακτήÏας %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "ΆκυÏο κωδικοποιημένο κείμενο UTF-8 στο όνομα - μη έγκυÏο «%s»" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "Το «%s» δεν είναι έγκυÏο όνομα" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "Το «%s» δεν είναι ένα έγκυÏο όνομα: «%c»" + +# +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Σφάλμα στη γÏαμμή %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Αποτυχία ανάλυσης του «%-.*s», που θα έπÏεπε να υπήÏχε ένα ψηφίο μέσα στην " +"αναφοÏά χαÏακτήÏα (ê για παÏάδειγμα) - ίσως το ψηφίο να είναι Ï€Î¿Î»Ï " +"μεγάλο" + +#: glib/gmarkup.c:702 +#, fuzzy +#| msgid "" +#| "Character reference did not end with a semicolon; most likely you used an " +#| "ampersand character without intending to start an entity - escape " +#| "ampersand as &" +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Η αναφοÏά χαÏακτήÏα δεν τελειώνει με εÏωτηματικό ;· πιθανόν να " +"χÏησιμοποιήσατε συμπλεκτικό χαÏακτήÏα χωÏίς να θέλετε να ξεκινήσετε μια " +"οντότητα - διαφυγή ÏƒÏ…Î¼Ï€Î»ÎµÎºÏ„Î¹ÎºÎ¿Ï Ï‰Ï‚ &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "" +"Η αναφοÏά χαÏακτήÏα «%-.*s» δεν κωδικοποιεί έναν επιτÏεπόμενο χαÏακτήÏα" + +#: glib/gmarkup.c:766 +#, fuzzy +#| msgid "" +#| "Empty entity '&;' seen; valid entities are: & " < > '" +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Κενή οντότητα '&;' παÏατηÏήθηκε· έγκυÏες οντότητες είναι: & " < " +"> '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Το όνομα οντότητας «%-.*s» δεν είναι γνωστό" + +#: glib/gmarkup.c:779 +#, fuzzy +#| msgid "" +#| "Entity did not end with a semicolon; most likely you used an ampersand " +#| "character without intending to start an entity - escape ampersand as &" +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Η οντότητα δεν τελειώνει με εÏωτηματικό ;· πιθανόν να χÏησιμοποιήσατε " +"συμπλεκτικό χαÏακτήÏα χωÏίς να θέλετε να ξεκινήσετε οντότητα - διαφυγή " +"ÏƒÏ…Î¼Ï€Î»ÎµÎºÏ„Î¹ÎºÎ¿Ï Ï‰Ï‚ &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Το έγγÏαφο Ï€Ïέπει να ξεκινά με στοιχείο (Ï€.χ. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"Το «%s» δεν είναι έγκυÏος χαÏακτήÏας όταν ακολουθείται από χαÏακτήÏα «<»· " +"δεν μποÏεί να ξεκινά όνομα στοιχείου" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"ΠεÏίεÏγος χαÏακτήÏας «%s», αναμενόταν ο χαÏακτήÏας «>» στο τέλος της " +"ετικέτας του κενοÏ-στοιχείου «%s»" + +#: glib/gmarkup.c:1346 +#, fuzzy, c-format +#| msgid "Unexpected attribute '%s' for element '%s'" +msgid "Too many attributes in element “%sâ€" +msgstr "Αναπάντεχο γνώÏισμα '%s' για το στοιχείο '%s'" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"ΠεÏίεÏγος χαÏακτήÏας «%s», αναμενόταν ένα «=» μετά το όνομα γνωÏίσματος «%s» " +"του στοιχείου «%s»" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ΠεÏίεÏγος χαÏακτήÏας «%s», αναμενόταν ένας χαÏακτήÏας «>» ή «/» στο τέλος " +"της ετικέτας έναÏξης του στοιχείου «%s» ή Ï€ÏοαιÏετικά ένα γνώÏισμα· πιθανόν " +"να χÏησιμοποιήσατε έναν άκυÏο χαÏακτήÏα σε όνομα γνωÏίσματος" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"ΠεÏίεÏγος χαÏακτήÏας «%s», αναμενόταν ένα ανοικτό εισαγωγικό μετά το σÏμβολο " +"ίσον στην τιμή για το γνώÏισμα «%s» του στοιχείου «%s»" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"Το «%s» δεν είναι έγκυÏος χαÏακτήÏας ακολουθοÏμενος από το όνομα στοιχείου " +"κλεισίματος «%s»· ο επιτÏεπόμενος χαÏακτήÏας είναι «>»" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Το στοιχείο «%s» έκλεισε, κανένα στοιχείο δεν είναι ανοικτό" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Το στοιχείο «%s» έκλεισε, αλλά το Ï„Ïέχον ανοικτό στοιχείο είναι «%s»" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Το έγγÏαφο ήταν κενό ή πεÏιέχει μόνο λευκό κενό" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Το έγγÏαφο τεÏματίστηκε απÏόσμενα αμέσως μετά από μια ανοικτή γωνιακή " +"παÏένθεση «<»" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Το έγγÏαφο τεÏματίστηκε απÏόσμενα με στοιχεία ακόμα ανοικτά — «%s» ήταν το " +"τελευταίο στοιχείο που ανοίχθηκε" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Το έγγÏαφο τεÏματίστηκε απÏόσμενα, αναμενόταν μια γωνιακή παÏένθεση " +"κλεισίματος στο τέλος της ετικέτας <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Το έγγÏαφο τεÏματίστηκε απÏόσμενα σε όνομα στοιχείου" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Το έγγÏαφο τεÏματίστηκε απÏόσμενα σε όνομα γνωÏίσματος" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Το έγγÏαφο τεÏματίστηκε απÏόσμενα μέσα σε ετικέτα ανοίγματος στοιχείου." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Το έγγÏαφο τεÏματίστηκε απÏόσμενα μετά το σÏμβολο ίσον ακολουθοÏμενο από " +"όνομα γνωÏίσματος· δεν υπάÏχει τιμή γνωÏίσματος" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Το έγγÏαφο τεÏματίστηκε απÏόσμενα σε τιμή γνωÏίσματος" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Το έγγÏαφο τεÏματίστηκε απÏόσμενα σε ετικέτα κλεισίματος για στοιχείο «%s»" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Το έγγÏαφο τεÏματίστηκε απÏόσμενα σε ετικέτα κλεισίματος για στοιχείο «%s»" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Το έγγÏαφο τεÏματίστηκε απÏόσμενα σε σχόλιο ή οδηγία επεξεÏγασίας" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[ΕΠΙΛΟΓΗ…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Επιλογές βοήθειας:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Εμφάνιση επιλογών βοήθειας" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Εμφάνιση όλων των επιλογών βοήθειας" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Επιλογές εφαÏμογής:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Επιλογές:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Αδυναμία ανάλυσης ακέÏαιης τιμής «%s» για %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "ΑκέÏαιη τιμή «%s» για %s είναι εκτός πεÏιοχής" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Αδυναμία ανάλυσης διπλής τιμής «%s» για %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Η διπλή τιμή «%s» για %s είναι εκτός πεÏιοχής" + +# gconf/gconftool.c:1181 +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Σφάλμα επιλογής ανάλυσης %s" + +#: glib/goption.c:1570 glib/goption.c:1683 +#, c-format +msgid "Missing argument for %s" +msgstr "Λείπει ÏŒÏισμα για %s" + +#: glib/goption.c:2194 +#, c-format +msgid "Unknown option %s" +msgstr "Άγνωστη επιλογή %s" + +#: glib/gregex.c:257 +msgid "corrupted object" +msgstr "κατεστÏαμμένο αντικείμενο" + +#: glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "εσωτεÏικό σφάλμα ή κατεστÏαμμένο αντικείμενο" + +#: glib/gregex.c:261 +msgid "out of memory" +msgstr "ανεπάÏκεια μνήμης" + +#: glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "εξάντληση οÏίου οπισθοανίχνευσης" + +#: glib/gregex.c:278 glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"το Ï€Ïότυπο πεÏιέχει στοιχεία που δεν υποστηÏίζονται για μεÏικό ταίÏιασμα" + +#: glib/gregex.c:280 +msgid "internal error" +msgstr "εσωτεÏικό σφάλμα" + +#: glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "οι οπισθοαναφοÏές ως συνθήκες, δεν υποστηÏίζονται για μεÏικό ταίÏιασμα" + +#: glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "εξάντληση οÏίου αναδÏομής" + +#: glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "άκυÏος συνδυασμός για σημαίες αλλαγής γÏαμμής" + +#: glib/gregex.c:301 +msgid "bad offset" +msgstr "κακή μετατόπιση" + +#: glib/gregex.c:303 +msgid "short utf8" +msgstr "short utf8" + +#: glib/gregex.c:305 +msgid "recursion loop" +msgstr "κυκλική επανάληψη" + +#: glib/gregex.c:309 +msgid "unknown error" +msgstr "άγνωστο σφάλμα" + +#: glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ στο τέλος του υποδείγματος" + +#: glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c στο τέλος του υποδείγματος" + +#: glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "ακολουθεί άγνωστος χαÏακτήÏας \\" + +#: glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "οι αÏιθμοί είναι εκτός σειÏάς στον Ï€ÏοσδιοÏιστή {}" + +#: glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿Ï‚ αÏιθμός στον Ï€ÏοσδιοÏιστή {}" + +#: glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "λείπει η τελική ] για την κλάση χαÏακτήÏων" + +#: glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "άκυÏη ακολουθία διαφυγής σε κλάση χαÏακτήÏων" + +#: glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "εÏÏος εκτός σειÏάς στην κλάση χαÏακτήÏων" + +#: glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "τίποτα για επανάληψη" + +#: glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "απÏόσμενη επανάληψη" + +#: glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "άγνωστος χαÏακτήÏας μετά τα (? ή (?-" + +#: glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "Οι κλάσεις με ονόματα κατά POSIX υποστηÏίζονται μόνο στις κλάσεις" + +#: glib/gregex.c:366 +msgid "missing terminating )" +msgstr "λείπει η τελική )" + +#: glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "αναφοÏά σε ανÏπαÏκτο υποπÏότυπο" + +#: glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "λείπει η ) μετά από το σχόλιο" + +#: glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "η κανονική έκφÏαση είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î·" + +#: glib/gregex.c:378 +msgid "failed to get memory" +msgstr "αποτυχία στη λήψη μνήμης" + +#: glib/gregex.c:382 +msgid ") without opening (" +msgstr ") χωÏίς άνοιγμα (" + +#: glib/gregex.c:386 +msgid "code overflow" +msgstr "υπεÏχείλιση κώδικα" + +#: glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "άγνωστος χαÏακτήÏας μετά το (?<" + +#: glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "ο ισχυÏισμός ανασκόπησης δεν έχει σταθεÏÏŒ μήκος" + +#: glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "κακοδιατυπωμένος αÏιθμός ή ονόματος μετά το (?(" + +#: glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "η ομάδα υποθετικών πεÏιέχει πεÏισσότεÏους από δÏο κλάδους" + +#: glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "αναμένεται ισχυÏισμός μετά το (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "τα (?R ή (?[+-]ψηφία Ï€Ïέπει να ακολουθοÏνται από )" + +#: glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "άγνωστο όνομα κλάσης POSIX" + +#: glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "Δεν υποστηÏίζονται τα στοιχεία ταξινόμησης POSIX" + +#: glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "η τιμή του χαÏακτήÏα στην ακολουθία \\x{...} είναι υπεÏβολικά μεγάλη" + +#: glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "άκυÏη συνθήκη (?(0)" + +#: glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "δεν επιτÏέπεται \\C στον ισχυÏισμό ανασκόπησης" + +#: glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "δεν υποστηÏίζονται τα escapes \\L, \\l, \\N{name}, \\U, και \\u" + +#: glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "η αναδÏομική κλήση μποÏεί να οδηγήσει σε ατέÏμονα βÏόγχο" + +#: glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "άγνωστος χαÏακτήÏας μετά (?P" + +#: glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "λείπει το τέλος του ονόματος του υποπÏότυπου" + +#: glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "δÏο επώνυμα υποπÏότυπα έχουν το ίδιο όνομα" + +#: glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "κακοδιατυπωμένο \\P ή \\p αλληλουχία" + +#: glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "άγνωστο όνομα ιδιότητας μετά το \\P ή το \\p" + +#: glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" +"το όνομα του υποπÏοτÏπου είναι υπεÏβολικά μεγάλο (μέγιστο 32 χαÏακτήÏες)" + +#: glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "υπεÏβολικά μεγάλος αÏιθμός υποπÏοτÏπων (επιτÏέπονται μέχÏι 10.000)" + +#: glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "η οκταδική τιμή είναι μεγαλÏτεÏη από \\377" + +#: glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "υπέÏβαση μεταγλώττισης χώÏου εÏγασίας" + +#: glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "δε βÏέθηκε το αναφεÏόμενο υποπÏότυπο που είχε ελεγχθεί Ï€Ïοηγουμένως" + +#: glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "Η ομάδα DEFINE πεÏιέχει πεÏισσότεÏους από έναν κλάδους" + +#: glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "αντιφατικές επιλογές NEWLINE" + +#: glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"το \\g δεν ακολουθείται από ένα άγκιστÏο, γωνιώδεις αγκÏλες, όνομα ή αÏιθμό " +"σε εισαγωγικά, ή από έναν απλό αÏιθμό" + +#: glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "δεν Ï€Ïέπει να είναι μηδέν μια αναφοÏά χαÏακτήÏα" + +#: glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "δεν επιτÏέπεται ένα ÏŒÏισμα για το (*ACCEPT), (*FAIL), ή (*COMMIT)" + +#: glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "Δεν αναγνωÏίσθηκε το (*VERB)" + +#: glib/gregex.c:489 +msgid "number is too big" +msgstr "ο αÏιθμός είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿Ï‚" + +#: glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "λείπει το όνομα του υποπÏότυπου μετά το (?&" + +#: glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "αναμένεται ψηφίο μετά το (?+" + +#: glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"το ] είναι ένας μη συμβατός χαÏακτήÏας στη λειτουÏγία συμβατότητας της " +"JavaScript" + +#: glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "δεν επιτÏέπονται διαφοÏετικά ονόματα για υποπÏότυπα του ίδιου αÏιθμοÏ" + +#: glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "Το (*MARK) Ï€Ïέπει να έχει ένα ÏŒÏισμα" + +#: glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "το \\c Ï€Ïέπει να ακολουθείτε από έναν χαÏακτήÏα ASCII" + +#: glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"το \\g δεν ακολουθείται από ένα άγκιστÏο, γωνιώδεις αγκÏλες, ή όνομα σε " +"εισαγωγικά" + +#: glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "το \\N δεν υποστηÏίζεται σε μια κλάση" + +#: glib/gregex.c:516 +msgid "too many forward references" +msgstr "πάÏα πολλές Ï€ÏοωθοÏμενες αναφοÏές" + +#: glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "το όνομα είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î¿ στο (*MARK), (*PRUNE), (*SKIP), ή (*THEN)" + +#: glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "η τιμή του χαÏακτήÏα στην ακολουθία \\u.... είναι υπεÏβολικά μεγάλη" + +#: glib/gregex.c:745 glib/gregex.c:1983 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Σφάλμα αντιστοίχισης της κανονικής έκφÏασης %s: %s" + +#: glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Η βιβλιοθήκη PCRE έχει μεταγλωττιστεί χωÏίς υποστήÏιξη UTF8" + +#: glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Η βιβλιοθήκη PCRE έχει μεταγλωττιστεί χωÏίς υποστήÏιξη ιδιοτήτων UTF8" + +#: glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "Η βιβλιοθήκη PCRE έχει μεταγλωττιστεί με ασÏμβατες επιλογές" + +#: glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Σφάλμα κατά τη βελτιστοποίηση της κανονικής έκφÏασης %s: %s" + +# gconf/gconfd.c:1676 +#: glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"Σφάλμα κατά τη μεταγλώττιση της κανονικής έκφÏασης %s στον χαÏακτήÏα %d: %s" + +#: glib/gregex.c:2419 +msgid "hexadecimal digit or “}†expected" +msgstr "αναμένεται δεκαεξαδικό ψηφίο ή «}»" + +#: glib/gregex.c:2435 +msgid "hexadecimal digit expected" +msgstr "αναμένεται δεκαεξαδικό ψηφίο" + +#: glib/gregex.c:2475 +msgid "missing “<†in symbolic reference" +msgstr "λείπει το «<» από τη συμβολική αναφοÏά" + +#: glib/gregex.c:2484 +msgid "unfinished symbolic reference" +msgstr "ημιτελής συμβολική αναφοÏά" + +#: glib/gregex.c:2491 +msgid "zero-length symbolic reference" +msgstr "συμβολική αναφοÏά Î¼Î·Î´ÎµÎ½Î¹ÎºÎ¿Ï Î¼Î®ÎºÎ¿Ï…Ï‚" + +#: glib/gregex.c:2502 +msgid "digit expected" +msgstr "αναμένεται ψηφίο" + +#: glib/gregex.c:2520 +msgid "illegal symbolic reference" +msgstr "παÏάνομη συμβολική αναφοÏά" + +#: glib/gregex.c:2583 +msgid "stray final “\\â€" +msgstr "αδέσποτο τελικό «\\»" + +#: glib/gregex.c:2587 +msgid "unknown escape sequence" +msgstr "άγνωστη ακολουθία διαφυγής" + +#: glib/gregex.c:2597 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Σφάλμα ανάλυσης του κειμένου αντικατάστασης «%s» στον χαÏακτήÏα %lu: %s" + +# gconf/gconf-internals.c:1577 +#: glib/gshell.c:94 +#, fuzzy +#| msgid "Quoted text doesn't begin with a quotation mark" +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Το παÏατιθέμενο αλφαÏιθμητικό δεν αÏχίζει με εισαγωγικό σημείο" + +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"ΑταίÏιαστο εÏωτηματικό στη γÏαμμή εντολών ή άλλο παÏατιθέμενο κείμενο " +"κελÏφους" + +#: glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "" +"Το κείμενο τεÏματίστηκε αμέσως μετά χαÏακτήÏα «\\». (Το κείμενο ήταν «%s»)" + +#: glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Το κείμενο τεÏματίστηκε Ï€Ïιν να βÏεθεί ταιÏιαστή παÏάθεση για %c. (Το " +"κείμενο ήταν «%s»)" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Το κείμενο ήταν κενό (ή πεÏιέχει μόνο λευκό κενό)" + +# gconf/gconf-internals.c:2416 +#: glib/gspawn.c:323 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Αποτυχία ανάγνωσης δεδομένων από θυγατÏική διεÏγασία (%s)" + +#: glib/gspawn.c:468 +#, fuzzy, c-format +#| msgid "Unexpected error in select() reading data from a child process (%s)" +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "" +"ΑπÏόσμενο σφάλμα στο select() ανάγνωσης δεδομένων από θυγατÏική διεÏγασία " +"(%s)" + +#: glib/gspawn.c:553 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "ΑπÏόσμενο σφάλμα στη waitpid() (%s)" + +#: glib/gspawn.c:1061 glib/gspawn-win32.c:1329 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Η θυγατÏική διεÏγασία τεÏματίστηκε με κωδικό %ld" + +#: glib/gspawn.c:1069 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Η θυγατÏική διεÏγασία τεÏματίστηκε από το σήμα %ld" + +#: glib/gspawn.c:1076 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Η θυγατÏική διεÏγασία διακόπηκε από το σήμα %ld" + +#: glib/gspawn.c:1083 +#, c-format +msgid "Child process exited abnormally" +msgstr "Η θυγατÏική διεÏγασία τεÏματίστηκε ασυνήθιστα" + +# gconf/gconftool.c:881 +#: glib/gspawn.c:1532 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Αποτυχία ανάγνωσης από τη θυγατÏική διοχέτευση (%s)" + +#: glib/gspawn.c:1788 +#, fuzzy, c-format +#| msgid "Failed to fork child process (%s)" +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Αποτυχία δικÏάνωσης θυγατÏικής διεÏγασίας (%s)" + +# gconf/gconf-internals.c:2416 +#: glib/gspawn.c:1871 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Αποτυχία δικÏάνωσης (%s)" + +#: glib/gspawn.c:2026 glib/gspawn-win32.c:381 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Αποτυχία αλλαγής καταλόγου «%s» (%s)" + +# gconf/gconf-internals.c:2416 +#: glib/gspawn.c:2036 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Αποτυχία εκτέλεσης θυγατÏικής διεÏγασίας «%s» (%s)" + +#: glib/gspawn.c:2046 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Αποτυχία ανακατεÏθυνσης εισόδου ή εξόδου θυγατÏικής διεÏγασίας (%s)" + +#: glib/gspawn.c:2055 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Αποτυχία δικÏάνωσης θυγατÏικής διεÏγασίας (%s)" + +#: glib/gspawn.c:2063 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Άγνωστο σφάλμα εκτέλεσης θυγατÏικής διεÏγασίας «%s»" + +#: glib/gspawn.c:2087 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Αποτυχία ανάγνωσης επαÏκών δεδομένων από θυγατÏική διοχέτευση pid (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "Αποτυχία ανάγνωσης δεδομένων από θυγατÏική διεÏγασία" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Αποτυχία δημιουÏγίας διοχέτευσης για την επικοινωνία με θυγατÏική διεÏγασία " +"(%s)" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Αποτυχία εκτέλεσης θυγατÏικής διεÏγασίας (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "ΆκυÏο όνομα Ï€ÏογÏάμματος: %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "ΆκυÏη συμβολοσειÏά σε ÏŒÏισμα διανÏσματος στο %d: %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "ΆκυÏη συμβολοσειÏά σε πεÏιβάλλον: %s" + +# +#: glib/gspawn-win32.c:721 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ΆκυÏος κατάλογος εÏγασίας: %s" + +#: glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Αποτυχία εκτέλεσης Î²Î¿Î·Î¸Î·Ï„Î¹ÎºÎ¿Ï Ï€ÏογÏάμματος(%s)" + +#: glib/gspawn-win32.c:1056 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"ΑπÏόσμενο σφάλμα στο g_io_channel_win32_poll() ανάγνωση δεδομένων από " +"θυγατÏική διεÏγασία" + +#: glib/gstrfuncs.c:3303 glib/gstrfuncs.c:3405 +msgid "Empty string is not a number" +msgstr "Το κενό αλφαÏιθμητικό δεν είναι αÏιθμός" + +#: glib/gstrfuncs.c:3327 +#, fuzzy, c-format +msgid "“%s†is not a signed number" +msgstr "Το «%s» δεν είναι έγκυÏο όνομα" + +#: glib/gstrfuncs.c:3337 glib/gstrfuncs.c:3441 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: glib/gstrfuncs.c:3431 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name" +msgid "“%s†is not an unsigned number" +msgstr "'%s' δεν είναι έγκυÏο όνομα" + +#: glib/guri.c:270 +#, fuzzy, no-c-format +#| msgid " (invalid encoding)" +msgid "Invalid %-encoding in URI" +msgstr " (άκυÏη κωδικοποίηση)" + +#: glib/guri.c:287 +msgid "Illegal character in URI" +msgstr "ΑπαγοÏευμένος χαÏακτήÏας στο URI" + +#: glib/guri.c:315 +msgid "Non-UTF-8 characters in URI" +msgstr "" + +#: glib/guri.c:418 +#, c-format +msgid "Invalid IPv6 address '%.*s' in URI" +msgstr "" + +#: glib/guri.c:480 +#, c-format +msgid "Illegal encoded IP address '%.*s' in URI" +msgstr "ΑπαγοÏευμένη κωδικοποιημένη διεÏθυνση IP «%.*s» στο URI" + +#: glib/guri.c:514 glib/guri.c:526 +#, c-format +msgid "Could not parse port '%.*s' in URI" +msgstr "" + +#: glib/guri.c:533 +#, c-format +msgid "Port '%.*s' in URI is out of range" +msgstr "" + +#: glib/guri.c:1009 +#, c-format +msgid "URI '%s' is not an absolute URI" +msgstr "Το URI «%s» δεν είναι απόλυτη διαδÏομή URI" + +#: glib/guri.c:1015 +#, c-format +msgid "URI '%s' has no host component" +msgstr "" + +#: glib/guri.c:1193 +msgid "URI is not absolute, and no base URI was provided" +msgstr "" + +#: glib/guri.c:1851 +msgid "Missing '=' and parameter value" +msgstr "" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "Αποτυχία κατανομής μνήμης" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "Ο χαÏακτήÏας είναι εκτός πεÏιοχής UTF-8" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "ΆκυÏη σειÏά στην είσοδο μετατÏοπής" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "Ο χαÏακτήÏας είναι εκτός πεÏιοχής UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2756 +#, c-format +#| msgid "%.1f kB" +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2758 +#, c-format +#| msgid "%.1f MB" +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2760 +#, c-format +#| msgid "%.1f GB" +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2762 +#, c-format +#| msgid "%.1f TB" +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2764 +#, c-format +#| msgid "%.1f PB" +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2766 +#, c-format +#| msgid "%.1f EB" +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2770 +#, c-format +#| msgid "%.1f KiB" +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2772 +#, c-format +#| msgid "%.1f MiB" +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2774 +#, c-format +#| msgid "%.1f GiB" +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2776 +#, c-format +#| msgid "%.1f TiB" +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2778 +#, c-format +#| msgid "%.1f PiB" +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2780 +#, c-format +#| msgid "%.1f EiB" +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2784 +#, c-format +#| msgid "%.1f kb" +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2786 +#, c-format +#| msgid "%.1f Mb" +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2788 +#, c-format +#| msgid "%.1f Gb" +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2790 +#, c-format +#| msgid "%.1f Tb" +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2792 +#, c-format +#| msgid "%.1f Pb" +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2794 +#, c-format +#| msgid "%.1f Eb" +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2798 +#, c-format +#| msgid "%.1f Kib" +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2800 +#, c-format +#| msgid "%.1f Mib" +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2802 +#, c-format +#| msgid "%.1f Gib" +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2804 +#, c-format +#| msgid "%.1f Tib" +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2806 +#, c-format +#| msgid "%.1f Pib" +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2808 +#, c-format +#| msgid "%.1f Eib" +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2842 glib/gutils.c:2959 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: glib/gutils.c:2846 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2913 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2918 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2972 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:2977 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2982 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2987 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2992 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2997 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#, fuzzy +#~| msgid "Error in address '%s' - the family attribute is malformed" +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Σφάλμα στη διεÏθυνση '%s' - η ιδιότητα ομάδας είναι κακοδιατυπωμένη" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "· παÏάβλεψη αντικατάστασης για αυτό το κλειδί.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " και οÏίστηκε το --strict· έξοδος.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "ΠαÏάβλεψη αντικατάστασης για αυτό το κλειδί.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "αδÏανές.\n" + +#~ msgid "No such interface" +#~ msgstr "Δεν υπάÏχει τέτοια διεπαφή" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Το μήνυμα έχει %d πεÏιγÏαφείς αÏχείου αλλά η κεφαλίδα δείχνει %d " +#~ "πεÏιγÏαφείς αÏχείου" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Σφάλμα: το σήμα Ï€Ïέπει να είναι το πλήÏως εξειδικευμένο όνομα.\n" + +# gconf/gconf-internals.c:2416 +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Αποτυχία δημιουÏγίας Ï€ÏοσωÏÎ¹Î½Î¿Ï Î±Ïχείου: %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Σφάλμα μετονομασίας αÏχείου: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Σφάλμα ανοίγματος αÏχείου: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Σφάλμα δημιουÏγίας καταλόγου: %s" + +# +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Σφάλμα ανάγνωσης αÏχείου '%s': %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "" +#~ "Δε βÏέθηκε ο Ï„Ïπος παÏακολοÏθησης του Ï€Ïοεπιλεγμένου Ï„Î¿Ï€Î¹ÎºÎ¿Ï ÎºÎ±Ï„Î±Î»ÏŒÎ³Î¿Ï…" + +# gconf/gconftool.c:1181 +#~ msgid "Error launching application: %s" +#~ msgstr "Σφάλμα εκκίνησης εφαÏμογής: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "οι αλλαγές συσχετίσεων δεν υποστηÏίζονται στα win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Η δημιουÏγία συσχέτισης δεν υποστηÏίζεται σε win32" + +#~ msgid "URIs not supported" +#~ msgstr "URIs δεν υποστηÏίζονται" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Το αÏχείο ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Î´ÎµÎ½ έχει κλειδί '%s'" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "Σφάλμα επεξεÏγασίας αÏχείου εισόδου με xmllint:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "Σφάλμα επεξεÏγασίας αÏχείου εισόδου με to-pixdata:\n" +#~ "%s" + +# gconf/gconf-internals.c:2416 +#~ msgid "Unable to get pending error: %s" +#~ msgstr "Αδυναμία λήψης εκκÏεμοÏÏ‚ σφάλματος: %s" + +# gconf/gconf-internals.c:2416 +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Αδυναμία ανοίγματος αÏχείου '%s' για εγγÏαφή: fdopen() απέτυχε: %s" + +# gconf/gconf-internals.c:2416 +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Αδυναμία εγγÏαφής αÏχείου '%s': fflush() απέτυχε: %s" + +# gconf/gconf-internals.c:2416 +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Αδυναμία κλεισίματος αÏχείου '%s': fclose() απέτυχε: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "Ελήφθησαν ελλιπής στοιχεία για το '%s'" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "ΑπÏοσδόκητο μήκος επιλογής ελέγχου ενεÏγοποίησης SO_PASSCRED υποδοχής. " +#~ "Αναμονή %d bytes, λήψη %d" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "" +#~ "Ανώμαλος τεÏματισμός Ï€ÏογÏάμματος κατά την δημιουÏγία της γÏαμμής εντολών " +#~ "'%s': %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "" +#~ "Η γÏαμμή εντολών '%s' τεÏματίστηκε με κατάσταση εξόδου διαφοÏετική από το " +#~ "μηδέν %d: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "εξάντληση οÏίου χώÏου εÏγασίας για κενές υποσυμβολοσειÏές" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "δεν επιτÏέπονται εδώ οι διαφυγές εναλλαγής πεζών-κεφαλαίων (\\l, \\L, " +#~ "\\u, \\U)" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "δεν επιτÏέπεται η επανάληψη ομάδας DEFINE" + +#~ msgid "File is empty" +#~ msgstr "Το αÏχείο είναι κενό" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "Το key file πεÏιέχει key '%s' που η τιμή του δεν μποÏεί να εÏμηνευθεί." + +#~ msgid "This option will be removed soon." +#~ msgstr "Αυτή η επιλογή θα αφαιÏεθεί σÏντομα." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Σφάλμα δήλωσης αÏχείου '%s': %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "Δεν υπάÏχει αÏχείο υπηÏεσιών για το '%s'" + +# +#~ msgid "Error connecting: " +#~ msgstr "Σφάλμα σÏνδεσης:" + +#~ msgid "Error connecting: %s" +#~ msgstr "Σφάλμα σÏνδεσης: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "" +#~ "Η υλοποίηση του SOCKSv4a πεÏιοÏίζει το όνομα χÏήστη σε %i χαÏακτήÏες" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "" +#~ "Η υλοποίηση του SOCKSv4a πεÏιοÏίζει το όνομα υπολογιστή υποδοχής σε %i " +#~ "χαÏακτήÏες" + +# +#~ msgid "Error reading from unix: %s" +#~ msgstr "Σφάλμα ανάγνωσης από unix: %s" + +# +#~ msgid "Error closing unix: %s" +#~ msgstr "Σφάλμα κλεισίματος unix: %s" + +# gconf/gconftool.c:1181 +#~ msgid "Error writing to unix: %s" +#~ msgstr "Σφάλμα εγγÏαφής σε unix: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "πμ" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "μμ" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "" +#~ "Ο Ï„Ïπος της τιμής επιστÏοφής είναι ανακÏιβής, δόθηκε '%s', αναμενόταν '%s'" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "ΠÏοσπάθεια να τεθεί η ιδιότητα %s του Ï„Ïπου %s αλλά σÏμφωνα με την " +#~ "αναμενόμενη διεπαφή ο Ï„Ïπος είναι %s" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "Εντολές:\n" +#~ " help Εμφανίζει αυτές τις πληÏοφοÏίες\n" +#~ " get ΕπιστÏοφή της τιμής ενός κλειδιοÏ\n" +#~ " set ΟÏισμός της τιμής ενός κλειδιοÏ\n" +#~ " reset ΕπανοÏισμός της τιμής ενός κλειδιοÏ\n" +#~ " monitor ΠαÏακολοÏθηση ενός ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Î³Î¹Î± αλλαγές\n" +#~ " writable Έλεγχος εάν ένα κλειδί είναι εγγÏάψιμο \n" +#~ "\n" +#~ "ΧÏήσημοποιήστε '%s COMMAND --help' για να πάÏτε βοήθεια για μεμονωμένες " +#~ "εντολές.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "ΔιευκÏινίστε την διαδÏομή για το σχήμα" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "ΟÏίσματα:\n" +#~ " SCHEMA Η ταυτότητα του σχήματος \n" +#~ " KEY Το όνομα του ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï \n" +#~ " VALUE Η τιμή για να οÏιστεί το κλειδί, ως σειÏιακή διάταξη " +#~ "GVariant\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "ΠαÏακολοÏθηση του KEY για αλλαγές και εκτÏπωση των αλλαγμένων τιμών.\n" +#~ "Η παÏακολοÏθηση θα συνεχιστεί έως ότου ολοκληÏωθεί η διαδικασία." + +#~ msgid "No such schema '%s' specified in override file '%s'" +#~ msgstr "Δεν υπάÏχει το σχήμα '%s' όπως οÏίζεται στο αÏχείο παÏάκαμψης '%s'" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Αδυναμία μετακίνησης ενός καταλόγου πάνω σε άλλον κατάλογο" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Μη έγκυÏη σειÏά στην είσοδο μετατÏοπής" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "ΥπέÏβαση του μέγιστου οÏίου δεδομένων πίνακα" + +#~ msgid "do not hide entries" +#~ msgstr "να μην αποκÏÏπτονται οι εγγÏαφές" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Ο χαÏακτήÏας '%s' δεν επιτÏέπεται στην αÏχή ονόματος οντότητας, ο " +#~ "χαÏακτήÏας & ξεκινά οντότητα. Αν δεν επιθυμείτε να ξεκινήσετε οντότητα, " +#~ "χÏησιμοποιήστε το συνδυασμό διαφυγής & στη θέση του &" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "Ο χαÏακτήÏας '%s' δεν επιτÏέπεται να πεÏιέχεται σε όνομα οντότητας" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Κενή αναφοÏά χαÏακτήÏα· Ï€Ïέπει να πεÏιέχει ένα ψηφίο όπως dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Ημιτελής αναφοÏά οντότητας" + +#~ msgid "Unfinished character reference" +#~ msgstr "Ημιτελής αναφοÏά χαÏακτήÏα" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Μη έγκυÏα κωδικοποιημένο κείμενο UTF-8 - overlong sequence" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Μη έγκυÏα κωδικοποιημένο κείμενο UTF-8 - not a start char" + +#~ msgid "file" +#~ msgstr "αÏχείο" + +#~ msgid "The file containing the icon" +#~ msgstr "Το αÏχείο που πεÏιέχει το εικονίδιο" + +#~ msgid "An array containing the icon names" +#~ msgstr "Πίνακας που πεÏιέχει τα ονόματα των εικονιδίων" + +#~ msgid "use default fallbacks" +#~ msgstr "χÏήση των Ï€Ïοεπιλεγμένων εφεδÏικών" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "Αν θα χÏησιμοποιοÏνται τα Ï€Ïοεπιλεγμένα εφεδÏικά που Ï€ÏοκÏπτουν από τη " +#~ "συντόμευση του ονόματος στους χαÏακτήÏες '-'. Αγνοεί όλα τα ονόματα μετά " +#~ "το Ï€Ïώτο, αν έχουν δοθεί πολλαπλά ονόματα." + +#~ msgid "File descriptor" +#~ msgstr "ΠεÏιγÏαφέας αÏχείου" + +#~ msgid "The file descriptor to read from" +#~ msgstr "Ο πεÏιγÏαφέας αÏχείου από τον οποίο θα γίνει η ανάγνωση" + +#~ msgid "Close file descriptor" +#~ msgstr "Κλείσιμο πεÏιγÏαφέα αÏχείου" + +#~ msgid "Whether to close the file descriptor when the stream is closed" +#~ msgstr "Αν θα κλείσει ο πεÏιγÏαφέας αÏχείου όταν κλείσει η Ïοή" diff --git a/po/en@shaw.po b/po/en@shaw.po new file mode 100644 index 0000000..ef56244 --- /dev/null +++ b/po/en@shaw.po @@ -0,0 +1,3809 @@ +# Shavian translation. +# Copyright (C) 2010. +# This file is distributed under the same license as the GLib package. +# Thomas Thurman , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2010-05-12 18:36 -0400\n" +"Last-Translator: Thomas Thurman \n" +"Language-Team: Shavian \n" +"Language: en@shaw\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" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ '%s' ð‘“𑹠ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ '%s" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ '%s' ð‘ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ '%s' ð‘¯ð‘ªð‘‘ ð‘“ð‘¬ð‘¯ð‘›" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘‘ð‘¨ð‘œ '%s', ð‘‘ð‘¨ð‘œ '%s' ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘‘ð‘¨ð‘œ '%s' ð‘¦ð‘¯ð‘•ð‘²ð‘› '%s'" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "ð‘¯ð‘´ ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘šð‘«ð‘’ð‘¥ð‘¸ð‘’ ð‘“ð‘²ð‘¤ ð‘“ð‘¬ð‘¯ð‘› ð‘¦ð‘¯ ð‘›ð‘±ð‘‘ð‘© ð‘›ð‘»ð‘Ÿ" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "ð‘© ð‘šð‘«ð‘’ð‘¥ð‘¸ð‘’ ð‘“𑹠URI '%s' ð‘·ð‘¤ð‘®ð‘§ð‘›ð‘¦ ð‘§ð‘’ð‘Ÿð‘¦ð‘•ð‘‘ð‘•" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "ð‘¯ð‘´ ð‘šð‘«ð‘’ð‘¥ð‘¸ð‘’ ð‘“ð‘¬ð‘¯ð‘› ð‘“𑹠URI '%s'" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "ð‘¯ð‘´ MIME ð‘‘ð‘²ð‘ ð‘›ð‘¦ð‘“ð‘²ð‘¯ð‘› ð‘¦ð‘¯ 𑞠ð‘šð‘«ð‘’ð‘¥ð‘¸ð‘’ ð‘“𑹠ð‘˜ð‘»ð‘° '%s'" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "ð‘¯ð‘´ ð‘ð‘®ð‘²ð‘ð‘©ð‘‘ ð‘“ð‘¤ð‘¨ð‘œ ð‘£ð‘¨ð‘Ÿ ð‘šð‘°ð‘¯ ð‘›ð‘¦ð‘“ð‘²ð‘¯ð‘› ð‘¦ð‘¯ ð‘šð‘«ð‘’ð‘¥ð‘¸ð‘’ ð‘“𑹠URI '%s'" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "ð‘¯ð‘´ ð‘œð‘®ð‘µð‘ð‘• ð‘•ð‘§ð‘‘ ð‘¦ð‘¯ ð‘šð‘«ð‘’ð‘¥ð‘¸ð‘’ ð‘“𑹠URI '%s'" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "ð‘¯ð‘´ ð‘©ð‘ð‘¤ð‘¦ð‘’ð‘±ð‘•ð‘©ð‘¯ ð‘¢ð‘¦ð‘ž ð‘¯ð‘±ð‘¥ '%s' ð‘®ð‘§ð‘¡ð‘¦ð‘•ð‘‘ð‘¼ð‘› ð‘© ð‘šð‘«ð‘’ð‘¥ð‘¸ð‘’ ð‘“𑹠'%s'" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘¦ð‘’ð‘•ð‘ð‘¨ð‘¯ð‘› ð‘§ð‘œð‘Ÿð‘§ð‘’ ð‘¤ð‘²ð‘¯ '%s' ð‘¢ð‘¦ð‘ž URI '%s'" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "ð‘’ð‘©ð‘¯ð‘ð‘»ð‘–ð‘©ð‘¯ ð‘“ð‘®ð‘ªð‘¥ ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘•ð‘§ð‘‘ '%s' ð‘‘ '%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "ð‘’ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘´ð‘ð‘©ð‘¯ ð‘’ð‘©ð‘¯ð‘ð‘»ð‘‘ð‘» ð‘“ð‘®ð‘ªð‘¥ '%s' ð‘‘ '%s'" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘šð‘²ð‘‘ ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘• ð‘¦ð‘¯ ð‘’ð‘©ð‘¯ð‘ð‘»ð‘–ð‘©ð‘¯ ð‘¦ð‘¯ð‘ð‘«ð‘‘" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "ð‘»ð‘¼ ð‘›ð‘˜ð‘«ð‘¼ð‘¦ð‘™ ð‘’ð‘©ð‘¯ð‘ð‘»ð‘–ð‘©ð‘¯: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "ð‘ð‘¸ð‘‘ð‘¦ð‘¨ð‘¤ ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘• ð‘¨ð‘‘ ð‘§ð‘¯ð‘› ð‘ ð‘¦ð‘¯ð‘ð‘«ð‘‘" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘’ð‘©ð‘¯ð‘ð‘»ð‘‘ ð‘“ð‘ªð‘¤ð‘šð‘¨ð‘’ '%s' ð‘‘ ð‘’ð‘´ð‘›ð‘•ð‘§ð‘‘ '%s'" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "𑞠URI '%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘©ð‘¯ ð‘¨ð‘šð‘•ð‘´ð‘¤ð‘µð‘‘ URI ð‘¿ð‘Ÿð‘¦ð‘™ 𑞠\"file\" ð‘•ð‘’ð‘°ð‘¥" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "𑞠ð‘¤ð‘´ð‘’ð‘©ð‘¤ ð‘“ð‘²ð‘¤ URI '%s' ð‘¥ð‘± ð‘¯ð‘ªð‘‘ ð‘¦ð‘¯ð‘’ð‘¤ð‘µð‘› ð‘© '#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "𑞠URI '%s' ð‘¦ð‘Ÿ ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘›" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "𑞠ð‘£ð‘´ð‘•ð‘‘ð‘¯ð‘±ð‘¥ ð‘ 𑞠URI '%s' ð‘¦ð‘Ÿ ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘›" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "𑞠URI '%s' ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘›ð‘¤ð‘¦ ð‘¦ð‘•ð‘’ð‘±ð‘ð‘‘ ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘ð‘¼ð‘Ÿ" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "𑞠ð‘ð‘­ð‘”ð‘¯ð‘±ð‘¥ '%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘©ð‘¯ ð‘¨ð‘šð‘•ð‘´ð‘¤ð‘µð‘‘ ð‘ð‘­ð‘”" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘£ð‘´ð‘•ð‘‘ð‘¯ð‘±ð‘¥" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "ð‘’ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘¨ð‘¤ð‘´ð‘’ð‘±ð‘‘ %lu ð‘šð‘²ð‘‘ð‘• ð‘‘ ð‘®ð‘°ð‘› ð‘“ð‘²ð‘¤ \"%s\"" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "ð‘“ð‘²ð‘¤ \"%s\" ð‘¦ð‘Ÿ ð‘‘𑵠ð‘¤ð‘¸ð‘¡" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘› ð‘“ð‘®ð‘ªð‘¥ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘´ð‘ð‘©ð‘¯ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘œð‘§ð‘‘ ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ð‘• ð‘ ð‘“ð‘²ð‘¤ '%s': fstat() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘´ð‘ð‘©ð‘¯ ð‘“ð‘²ð‘¤ '%s': fdopen() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘¯ð‘±ð‘¥ ð‘“ð‘²ð‘¤ '%s' ð‘‘ '%s': g_rename() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘´ð‘ð‘©ð‘¯ ð‘“ð‘²ð‘¤ '%s' ð‘“𑹠ð‘®ð‘²ð‘‘ð‘¦ð‘™: fdopen() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘²ð‘‘ ð‘“ð‘²ð‘¤ '%s': fwrite() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘²ð‘‘ ð‘“ð‘²ð‘¤ '%s': fflush() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘²ð‘‘ ð‘“ð‘²ð‘¤ '%s': fsync() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘’ð‘¤ð‘´ð‘• ð‘“ð‘²ð‘¤ '%s': fclose() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "ð‘§ð‘’ð‘Ÿð‘¦ð‘•ð‘‘ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s' ð‘’ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘šð‘° ð‘®ð‘¦ð‘¥ð‘µð‘ð‘›: g_unlink() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "ð‘‘ð‘§ð‘¥ð‘ð‘¤ð‘±ð‘‘ '%s' ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘›, ð‘–ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ ð‘© '%s'" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "ð‘‘ð‘§ð‘¥ð‘ð‘¤ð‘±ð‘‘ '%s' ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ð‘šð‘²ð‘‘" +msgstr[1] "%u ð‘šð‘²ð‘‘ð‘•" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f EB" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, fuzzy, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%u ð‘šð‘²ð‘‘" +msgstr[1] "%u ð‘šð‘²ð‘‘ð‘•" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘› 𑞠ð‘•ð‘¦ð‘¥ð‘šð‘ªð‘¤ð‘¦ð‘’ ð‘¤ð‘¦ð‘™ð‘’ '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "ð‘•ð‘¦ð‘¥ð‘šð‘ªð‘¤ð‘¦ð‘’ ð‘¤ð‘¦ð‘™ð‘’ð‘• ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "ð‘’ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘´ð‘ð‘©ð‘¯ ð‘’ð‘©ð‘¯ð‘ð‘»ð‘‘ð‘» ð‘“ð‘®ð‘ªð‘¥ '%s' ð‘‘ '%s': %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘›ð‘µ ð‘© ð‘®ð‘· ð‘®ð‘§ð‘› ð‘¦ð‘¯ g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "ð‘¤ð‘§ð‘“ð‘‘ð‘´ð‘ð‘» ð‘©ð‘¯ð‘’ð‘©ð‘¯ð‘ð‘»ð‘‘ð‘¦ð‘› ð‘›ð‘±ð‘‘ð‘© ð‘¦ð‘¯ ð‘®ð‘°ð‘› ð‘šð‘³ð‘“ð‘¼" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "ð‘—ð‘¨ð‘¯ð‘©ð‘¤ ð‘‘ð‘»ð‘¥ð‘¦ð‘¯ð‘±ð‘‘ð‘• ð‘¦ð‘¯ ð‘© ð‘ð‘¸ð‘‘ð‘¦ð‘¨ð‘¤ ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘ð‘¼" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘›ð‘µ ð‘© ð‘®ð‘· ð‘®ð‘§ð‘› ð‘¦ð‘¯ g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘´ð‘ð‘©ð‘¯ ð‘“ð‘²ð‘¤ '%s': open() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘¥ð‘¨ð‘ ð‘“ð‘²ð‘¤ '%s': mmap() ð‘“ð‘±ð‘¤ð‘›: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "ð‘»ð‘¼ ð‘ªð‘¯ ð‘¤ð‘²ð‘¯ %d ð‘—𑸠%d: " + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› UTF-8 ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘©ð‘› ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘¦ð‘¯ ð‘¯ð‘±ð‘¥ - ð‘¯ð‘ªð‘‘ ð‘ð‘¨ð‘¤ð‘¦ð‘› '%s'" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¯ð‘±ð‘¥ " + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¯ð‘±ð‘¥: '%c' " + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "ð‘»ð‘¼ ð‘ªð‘¯ ð‘¤ð‘²ð‘¯ %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘ð‘¸ð‘• '%-.*s', ð‘¢ð‘¦ð‘— ð‘–ð‘«ð‘› ð‘£ð‘¨ð‘ ð‘šð‘°ð‘¯ ð‘© ð‘›ð‘¦ð‘¡ð‘¦ð‘‘ ð‘¦ð‘¯ð‘•ð‘²ð‘› ð‘© ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘• (ê " +"ð‘“𑹠ð‘¦ð‘œð‘Ÿð‘­ð‘¥ð‘ð‘©ð‘¤) - ð‘ð‘¼ð‘£ð‘¨ð‘𑕠𑞠ð‘›ð‘¦ð‘¡ð‘¦ð‘‘ ð‘¦ð‘Ÿ ð‘‘𑵠ð‘¤ð‘¸ð‘¡" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘• ð‘›ð‘¦ð‘› ð‘¯ð‘ªð‘‘ ð‘§ð‘¯ð‘› ð‘¢ð‘¦ð‘ž ð‘© ð‘•ð‘§ð‘¥ð‘¦ð‘’ð‘´ð‘¤ð‘ªð‘¯; ð‘¥ð‘´ð‘•ð‘‘ ð‘¤ð‘²ð‘’ð‘¤ð‘¦ ð‘¿ ð‘¿ð‘•ð‘‘ ð‘©ð‘¯ ð‘¨ð‘¥ð‘ð‘»ð‘•ð‘¨ð‘¯ð‘› " +"ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘¢ð‘¦ð‘žð‘¬ð‘‘ ð‘¦ð‘¯ð‘‘ð‘§ð‘¯ð‘›ð‘¦ð‘™ ð‘‘ ð‘•ð‘‘ð‘¸ð‘‘ ð‘©ð‘¯ ð‘§ð‘¯ð‘‘ð‘¦ð‘‘𑦠- ð‘¦ð‘•ð‘’ð‘±ð‘ ð‘¨ð‘¥ð‘ð‘»ð‘•ð‘¨ð‘¯ð‘› ð‘¨ð‘Ÿ &" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘• '%-.*s' ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘§ð‘¯ð‘’ð‘´ð‘› ð‘© ð‘ð‘¼ð‘¥ð‘¦ð‘‘ð‘©ð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘ð‘¼" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "ð‘§ð‘¥ð‘ð‘‘𑦠ð‘§ð‘¯ð‘‘ð‘¦ð‘‘𑦠'&;' ð‘•ð‘°ð‘¯; ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘§ð‘¯ð‘‘ð‘¦ð‘‘ð‘¦ð‘Ÿ ð‘¸: & " < > '" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "ð‘§ð‘¯ð‘‘ð‘¦ð‘‘𑦠ð‘¯ð‘±ð‘¥ '%-.*s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘¯ð‘´ð‘¯" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"ð‘§ð‘¯ð‘‘ð‘¦ð‘‘𑦠ð‘›ð‘¦ð‘› ð‘¯ð‘ªð‘‘ ð‘§ð‘¯ð‘› ð‘¢ð‘¦ð‘ž ð‘© ð‘•ð‘§ð‘¥ð‘¦ð‘’ð‘´ð‘¤ð‘ªð‘¯; ð‘¥ð‘´ð‘•ð‘‘ ð‘¤ð‘²ð‘’ð‘¤ð‘¦ ð‘¿ ð‘¿ð‘•ð‘‘ ð‘©ð‘¯ ð‘¨ð‘¥ð‘ð‘»ð‘•ð‘¨ð‘¯ð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠" +"ð‘¢ð‘¦ð‘žð‘¬ð‘‘ ð‘¦ð‘¯ð‘‘ð‘§ð‘¯ð‘›ð‘¦ð‘™ ð‘‘ ð‘•ð‘‘ð‘¸ð‘‘ ð‘©ð‘¯ ð‘§ð‘¯ð‘‘ð‘¦ð‘‘𑦠- ð‘¦ð‘•ð‘’ð‘±ð‘ ð‘¨ð‘¥ð‘ð‘»ð‘•ð‘¨ð‘¯ð‘› ð‘¨ð‘Ÿ &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘¥ð‘³ð‘•ð‘‘ ð‘šð‘©ð‘œð‘¦ð‘¯ ð‘¢ð‘¦ð‘ž ð‘©ð‘¯ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ (e.g. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘“ð‘ªð‘¤ð‘´ð‘¦ð‘™ ð‘© '<' ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘ð‘¼; ð‘¦ð‘‘ ð‘¥ð‘± ð‘¯ð‘ªð‘‘ ð‘šð‘©ð‘œð‘¦ð‘¯ ð‘©ð‘¯ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ " +"ð‘¯ð‘±ð‘¥" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"ð‘ªð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠'%s', ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘© '>' ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠𑑠ð‘§ð‘¯ð‘› 𑞠ð‘§ð‘¥ð‘ð‘‘ð‘¦-ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ ð‘‘ð‘¨ð‘œ '%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "ð‘ªð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠'%s', ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘© '=' ð‘­ð‘“ð‘‘𑼠ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘¯ð‘±ð‘¥ '%s' ð‘ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ '%s'" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ð‘ªð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠'%s', ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘© '>' 𑹠'/' ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠𑑠ð‘§ð‘¯ð‘› 𑞠ð‘•ð‘‘ð‘¸ð‘‘ ð‘‘ð‘¨ð‘œ ð‘ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ " +"'%s',𑹠ð‘ªð‘ð‘–ð‘©ð‘¯ð‘©ð‘¤ð‘¦ ð‘©ð‘¯ ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘; ð‘ð‘¼ð‘£ð‘¨ð‘ð‘• ð‘¿ ð‘¿ð‘•ð‘‘ ð‘©ð‘¯ ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘¦ð‘¯ ð‘©ð‘¯ ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘¯ð‘±ð‘¥" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"ð‘ªð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠'%s', ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘©ð‘¯ ð‘´ð‘ð‘©ð‘¯ ð‘’ð‘¢ð‘´ð‘‘ ·ð‘¥ð‘¸ð‘’ ð‘­ð‘“ð‘‘𑼠𑞠ð‘°ð‘’ð‘¢ð‘©ð‘¤ð‘Ÿ ð‘•ð‘²ð‘¯ ð‘¢ð‘§ð‘¯ ð‘œð‘¦ð‘ð‘¦ð‘™ " +"ð‘ð‘¨ð‘¤ð‘¿ ð‘“𑹠ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ '%s' ð‘ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ '%s'" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘“ð‘ªð‘¤ð‘´ð‘¦ð‘™ 𑞠ð‘’ð‘¤ð‘´ð‘• ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ ð‘¯ð‘±ð‘¥ '%s'; 𑞠ð‘©ð‘¤ð‘¬ð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠" +"ð‘¦ð‘Ÿ '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ '%s' ð‘¢ð‘ªð‘Ÿ ð‘’ð‘¤ð‘´ð‘Ÿð‘›, ð‘¯ð‘´ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ ð‘¦ð‘Ÿ ð‘’ð‘³ð‘®ð‘©ð‘¯ð‘‘ð‘¤ð‘¦ ð‘´ð‘ð‘©ð‘¯" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ '%s' ð‘¢ð‘ªð‘Ÿ ð‘’ð‘¤ð‘´ð‘Ÿð‘›, ð‘šð‘³ð‘‘ 𑞠ð‘’ð‘³ð‘®ð‘©ð‘¯ð‘‘ð‘¤ð‘¦ ð‘´ð‘ð‘©ð‘¯ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ ð‘¦ð‘Ÿ '%s'" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘¢ð‘ªð‘Ÿ ð‘§ð‘¥ð‘ð‘‘𑦠𑹠ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘› ð‘´ð‘¯ð‘¤ð‘¦ ð‘¢ð‘²ð‘‘ð‘•ð‘ð‘±ð‘•" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘¡ð‘³ð‘•ð‘‘ ð‘­ð‘“ð‘‘𑼠ð‘©ð‘¯ ð‘´ð‘ð‘©ð‘¯ ð‘¨ð‘™ð‘œð‘¤ ð‘šð‘®ð‘¨ð‘’ð‘©ð‘‘ '<'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘¢ð‘¦ð‘ž ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ð‘• ð‘•ð‘‘ð‘¦ð‘¤ ð‘´ð‘ð‘©ð‘¯ - '%s' ð‘¢ð‘ªð‘Ÿ 𑞠ð‘¤ð‘­ð‘•ð‘‘ " +"ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ ð‘´ð‘ð‘©ð‘¯ð‘›" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘°, ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘‘ ð‘•ð‘° ð‘© ð‘’ð‘¤ð‘´ð‘• ð‘¨ð‘™ð‘œð‘¤ ð‘šð‘®ð‘¨ð‘’ð‘©ð‘‘ ð‘§ð‘¯ð‘›ð‘¦ð‘™ 𑞠ð‘‘ð‘¨ð‘œ <" +"%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘¦ð‘¯ð‘•ð‘²ð‘› ð‘©ð‘¯ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ ð‘¯ð‘±ð‘¥" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘¦ð‘¯ð‘•ð‘²ð‘› ð‘©ð‘¯ ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘¯ð‘±ð‘¥" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘¦ð‘¯ð‘•ð‘²ð‘› ð‘©ð‘¯ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘-ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘‘ð‘¨ð‘œ." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘­ð‘“ð‘‘𑼠𑞠ð‘°ð‘’ð‘¢ð‘©ð‘¤ð‘Ÿ ð‘•ð‘²ð‘¯ ð‘“ð‘ªð‘¤ð‘´ð‘¦ð‘™ ð‘©ð‘¯ ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘¯ð‘±ð‘¥; ð‘¯ð‘´ " +"ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘ð‘¨ð‘¤ð‘¿" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘¢ð‘²ð‘¤ ð‘¦ð‘¯ð‘•ð‘²ð‘› ð‘©ð‘¯ ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘ð‘¨ð‘¤ð‘¿" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘¦ð‘¯ð‘•ð‘²ð‘› 𑞠ð‘’ð‘¤ð‘´ð‘• ð‘‘ð‘¨ð‘œ ð‘“𑹠ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘ '%s'" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "ð‘›ð‘ªð‘’ð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘›ð‘¤ð‘° ð‘¦ð‘¯ð‘•ð‘²ð‘› ð‘© ð‘’ð‘³ð‘¥ð‘¥ð‘©ð‘¯ð‘‘ 𑹠ð‘ð‘®ð‘´ð‘•ð‘§ð‘•ð‘¦ð‘™ ð‘¦ð‘¯ð‘•ð‘‘ð‘®ð‘³ð‘’ð‘–ð‘©ð‘¯" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "ð‘’ð‘¼ð‘³ð‘ð‘‘ð‘©ð‘› ð‘©ð‘šð‘¡ð‘§ð‘’ð‘‘" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "ð‘¦ð‘¯ð‘‘ð‘»ð‘¯ð‘©ð‘¤ ð‘»ð‘¼ 𑹠ð‘’ð‘¼ð‘³ð‘ð‘‘ð‘©ð‘› ð‘©ð‘šð‘¡ð‘§ð‘’ð‘‘" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "ð‘¬ð‘‘ ð‘ ð‘¥ð‘§ð‘¥ð‘¼ð‘¦" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "ð‘šð‘¨ð‘’ð‘‘ð‘®ð‘¨ð‘’ð‘¦ð‘™ ð‘¤ð‘¦ð‘¥ð‘¦ð‘‘ ð‘®ð‘°ð‘—ð‘‘" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "𑞠ð‘ð‘¨ð‘‘ð‘¼ð‘¯ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘²ð‘‘ð‘©ð‘¥ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘“𑹠ð‘ð‘¸ð‘‘ð‘¦ð‘¨ð‘¤ ð‘¥ð‘¨ð‘—ð‘¦ð‘™" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "ð‘¦ð‘¯ð‘‘ð‘»ð‘¯ð‘©ð‘¤ ð‘»ð‘¼" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "ð‘šð‘¨ð‘’ ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘•ð‘©ð‘Ÿ ð‘¨ð‘Ÿ ð‘’ð‘©ð‘¯ð‘›ð‘¦ð‘–ð‘©ð‘¯ð‘Ÿ 𑸠ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘“𑹠ð‘ð‘¸ð‘‘ð‘¦ð‘¨ð‘¤ ð‘¥ð‘¨ð‘—ð‘¦ð‘™" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "ð‘®ð‘¦ð‘’ð‘»ð‘–ð‘©ð‘¯ ð‘¤ð‘¦ð‘¥ð‘¦ð‘‘ ð‘®ð‘°ð‘—ð‘‘" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "ð‘¢ð‘»ð‘’ð‘•ð‘ð‘±ð‘• ð‘¤ð‘¦ð‘¥ð‘¦ð‘‘ ð‘“𑹠ð‘§ð‘¥ð‘ð‘‘𑦠ð‘•ð‘³ð‘šð‘•ð‘‘ð‘®ð‘¦ð‘™ð‘Ÿ ð‘®ð‘°ð‘—ð‘‘" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘’ð‘ªð‘¥ð‘šð‘¦ð‘¯ð‘±ð‘–ð‘©ð‘¯ ð‘ ð‘¯ð‘¿ð‘¤ð‘²ð‘¯ ð‘“ð‘¤ð‘¨ð‘œð‘Ÿ" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘»ð‘¼" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ ð‘¨ð‘‘ ð‘§ð‘¯ð‘› ð‘ ð‘ð‘¨ð‘‘ð‘¼ð‘¯" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c ð‘¨ð‘‘ ð‘§ð‘¯ð‘› ð‘ ð‘ð‘¨ð‘‘ð‘¼ð‘¯" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "ð‘©ð‘¯ð‘®ð‘§ð‘’ð‘©ð‘œð‘¯ð‘²ð‘Ÿð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘“ð‘ªð‘¤ð‘´ð‘Ÿ \\" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "ð‘’ð‘±ð‘•-ð‘—ð‘±ð‘¯ð‘¡ð‘¦ð‘™ ð‘¦ð‘•ð‘’ð‘±ð‘ð‘• (\\l, \\L, \\u, \\U) 𑸠ð‘¯ð‘ªð‘‘ ð‘©ð‘¤ð‘¬ð‘› ð‘£ð‘½" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "ð‘¯ð‘³ð‘¥ð‘šð‘¼ð‘Ÿ ð‘¬ð‘‘ ð‘ ð‘¹ð‘›ð‘¼ ð‘¦ð‘¯ {} ð‘’ð‘¢ð‘ªð‘¯ð‘‘ð‘¦ð‘“ð‘²ð‘¼" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "ð‘¯ð‘³ð‘¥ð‘šð‘¼ ð‘‘𑵠ð‘šð‘¦ð‘œ ð‘¦ð‘¯ {} ð‘’ð‘¢ð‘ªð‘¯ð‘‘ð‘¦ð‘“ð‘²ð‘¼" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "ð‘¥ð‘¦ð‘•ð‘¦ð‘™ ð‘‘ð‘»ð‘¥ð‘©ð‘¯ð‘±ð‘‘ð‘¦ð‘™ ] ð‘“𑹠ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘’ð‘¤ð‘­ð‘•" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¦ð‘•ð‘’ð‘±ð‘ ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘• ð‘¦ð‘¯ ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘’ð‘¤ð‘­ð‘•" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "ð‘®ð‘±ð‘¯ð‘¡ ð‘¬ð‘‘ ð‘ ð‘¹ð‘›ð‘¼ ð‘¦ð‘¯ ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘’ð‘¤ð‘­ð‘•" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "ð‘¯ð‘³ð‘”ð‘¦ð‘™ ð‘‘ ð‘®ð‘¦ð‘ð‘°ð‘‘" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "ð‘©ð‘¯ð‘®ð‘§ð‘’ð‘©ð‘œð‘¯ð‘²ð‘Ÿð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘­ð‘“ð‘‘𑼠(?" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "ð‘©ð‘¯ð‘®ð‘§ð‘’ð‘©ð‘œð‘¯ð‘²ð‘Ÿð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘­ð‘“ð‘‘𑼠(?<" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "ð‘©ð‘¯ð‘®ð‘§ð‘’ð‘©ð‘œð‘¯ð‘²ð‘Ÿð‘› ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘­ð‘“ð‘‘𑼠(?P" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX ð‘¯ð‘±ð‘¥ð‘› ð‘’ð‘¤ð‘­ð‘•ð‘©ð‘Ÿ 𑸠ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘´ð‘¯ð‘¤ð‘¦ ð‘¢ð‘¦ð‘žð‘¦ð‘¯ ð‘© ð‘’ð‘¤ð‘­ð‘•" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "ð‘¥ð‘¦ð‘•ð‘¦ð‘™ ð‘‘ð‘»ð‘¥ð‘©ð‘¯ð‘±ð‘‘ð‘¦ð‘™ )" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") ð‘¢ð‘¦ð‘žð‘¬ð‘‘ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ (" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?ð‘­ð‘® 𑹠(?[+-]ð‘›ð‘¦ð‘¡ð‘©ð‘‘ð‘• ð‘¥ð‘³ð‘•ð‘‘ ð‘šð‘° ð‘“ð‘ªð‘¤ð‘´ð‘› ð‘šð‘² )" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘• ð‘‘ ð‘¯ð‘ªð‘¯-ð‘§ð‘œð‘Ÿð‘¦ð‘•ð‘‘ð‘©ð‘¯ð‘‘ ð‘•ð‘³ð‘šð‘ð‘¨ð‘‘ð‘¼ð‘¯" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "ð‘¥ð‘¦ð‘•ð‘¦ð‘™ ) ð‘­ð‘“ð‘‘𑼠ð‘’ð‘³ð‘¥ð‘¥ð‘©ð‘¯ð‘‘" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "ð‘®ð‘§ð‘œð‘˜ð‘«ð‘¤ð‘¼ ð‘¦ð‘’ð‘•ð‘ð‘®ð‘§ð‘–ð‘©ð‘¯ ð‘‘𑵠ð‘¤ð‘¸ð‘¡" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘œð‘§ð‘‘ ð‘¥ð‘§ð‘¥ð‘¼ð‘¦" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "ð‘¤ð‘«ð‘’ð‘šð‘©ð‘£ð‘¦ð‘¯ð‘› ð‘©ð‘•ð‘»ð‘•ð‘©ð‘¯ ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘“ð‘¦ð‘’ð‘•ð‘‘ ð‘¤ð‘§ð‘™ð‘”" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "ð‘¥ð‘¨ð‘¤ð‘“ð‘¹ð‘¥ð‘› ð‘¯ð‘³ð‘¥ð‘šð‘¼ 𑹠ð‘¯ð‘±ð‘¥ ð‘­ð‘“ð‘‘𑼠(?(" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "ð‘’ð‘©ð‘¯ð‘›ð‘¦ð‘–ð‘©ð‘¯ð‘©ð‘¤ ð‘œð‘®ð‘µð‘ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘¥ð‘¹ ð‘žð‘¨ð‘¯ ð‘‘𑵠ð‘šð‘®ð‘­ð‘¯ð‘—ð‘©ð‘Ÿ" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "ð‘©ð‘•ð‘»ð‘•ð‘©ð‘¯ ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘­ð‘“ð‘‘𑼠(?(" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ POSIX ð‘’ð‘¤ð‘­ð‘• ð‘¯ð‘±ð‘¥" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "POSIX ð‘’ð‘ªð‘¤ð‘±ð‘‘ð‘¦ð‘™ ð‘§ð‘¤ð‘©ð‘¥ð‘©ð‘¯ð‘‘𑕠𑸠ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘ð‘¨ð‘¤ð‘¿ ð‘¦ð‘¯ \\x{...} ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘• ð‘¦ð‘Ÿ ð‘‘𑵠ð‘¤ð‘¸ð‘¡" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘’ð‘©ð‘¯ð‘›ð‘¦ð‘–ð‘©ð‘¯ (?(0)" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C ð‘¯ð‘ªð‘‘ ð‘©ð‘¤ð‘¬ð‘› ð‘¦ð‘¯ lookbehind ð‘©ð‘•ð‘»ð‘•ð‘©ð‘¯" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "ð‘®ð‘¦ð‘’ð‘»ð‘•ð‘¦ð‘ ð‘’ð‘·ð‘¤ ð‘’ð‘«ð‘› ð‘¤ð‘µð‘ ð‘¦ð‘¯ð‘›ð‘§ð‘“ð‘©ð‘¯ð‘©ð‘‘ð‘¤ð‘¦" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "ð‘¥ð‘¦ð‘•ð‘¦ð‘™ ð‘‘ð‘»ð‘¥ð‘©ð‘¯ð‘±ð‘‘ð‘» ð‘¦ð‘¯ ð‘•ð‘³ð‘šð‘ð‘¨ð‘‘ð‘¼ð‘¯ ð‘¯ð‘±ð‘¥" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "ð‘‘𑵠ð‘¯ð‘±ð‘¥ð‘› ð‘•ð‘³ð‘šð‘ð‘¨ð‘‘ð‘¼ð‘¯ð‘Ÿ ð‘£ð‘¨ð‘ 𑞠ð‘•ð‘±ð‘¥ ð‘¯ð‘±ð‘¥" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "ð‘¥ð‘¨ð‘¤ð‘“ð‘¹ð‘¥ð‘› \\P 𑹠\\p ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘•" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘ð‘®ð‘ªð‘ð‘¼ð‘‘𑦠ð‘¯ð‘±ð‘¥ ð‘­ð‘“ð‘‘𑼠\\P 𑹠\\p" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ð‘•ð‘³ð‘šð‘ð‘¨ð‘‘ð‘¼ð‘¯ ð‘¯ð‘±ð‘¥ ð‘¦ð‘Ÿ ð‘‘𑵠ð‘¤ð‘ªð‘™ (ð‘¥ð‘¨ð‘’ð‘•ð‘¦ð‘¥ð‘©ð‘¥ 32 ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘ð‘¼ð‘Ÿ)" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ð‘‘𑵠ð‘¥ð‘§ð‘¯ð‘¦ ð‘¯ð‘±ð‘¥ð‘› ð‘•ð‘³ð‘šð‘ð‘¨ð‘‘ð‘¼ð‘¯ð‘Ÿ (ð‘¥ð‘¨ð‘’ð‘•ð‘¦ð‘¥ð‘©ð‘¥ 10,000)" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "ð‘ªð‘’ð‘‘ð‘©ð‘¤ ð‘ð‘¨ð‘¤ð‘¿ ð‘¦ð‘Ÿ ð‘œð‘®ð‘±ð‘‘𑼠ð‘žð‘¨ð‘¯ \\377" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE ð‘œð‘®ð‘µð‘ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘¥ð‘¹ ð‘žð‘¨ð‘¯ ð‘¢ð‘³ð‘¯ ð‘šð‘®ð‘­ð‘¯ð‘—" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "ð‘®ð‘¦ð‘ð‘°ð‘‘ð‘¦ð‘™ ð‘© DEFINE ð‘œð‘®ð‘µð‘ ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘©ð‘¤ð‘¬ð‘›" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "ð‘¦ð‘¯ð‘’ð‘©ð‘¯ð‘•ð‘¦ð‘•ð‘‘ð‘©ð‘¯ð‘‘ NEWLINE ð‘ªð‘ð‘–ð‘©ð‘¯ð‘Ÿ" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "\\g ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘“ð‘ªð‘¤ð‘´ð‘› ð‘šð‘² ð‘© ð‘šð‘®ð‘±ð‘•ð‘‘ ð‘¯ð‘±ð‘¥ 𑹠ð‘©ð‘¯ ð‘ªð‘ð‘–ð‘©ð‘¯ð‘©ð‘¤ð‘¦ ð‘šð‘®ð‘±ð‘•ð‘‘ ð‘¯ð‘ªð‘¯-ð‘Ÿð‘½ð‘´ ð‘¯ð‘³ð‘¥ð‘šð‘¼" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘®ð‘¦ð‘ð‘°ð‘‘" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "ð‘’ð‘´ð‘› ð‘´ð‘ð‘¼ð‘“ð‘¤ð‘´" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "ð‘´ð‘ð‘»ð‘®ð‘¨ð‘¯ ð‘’ð‘©ð‘¥ð‘ð‘²ð‘¤ð‘¦ð‘™ ð‘¢ð‘»ð‘’ð‘•ð‘ð‘±ð‘•" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "ð‘ð‘®ð‘°ð‘ð‘¦ð‘©ð‘•ð‘¤ð‘¦-ð‘—ð‘§ð‘’ð‘‘ ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘•ð‘‘ ð‘•ð‘³ð‘šð‘ð‘¨ð‘‘ð‘¼ð‘¯ ð‘¯ð‘ªð‘‘ ð‘“ð‘¬ð‘¯ð‘›" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "ð‘»ð‘¼ ð‘¢ð‘²ð‘¤ ð‘¥ð‘¨ð‘—ð‘¦ð‘™ ð‘®ð‘§ð‘œð‘˜ð‘«ð‘¤ð‘¼ ð‘¦ð‘’ð‘•ð‘ð‘®ð‘§ð‘–ð‘©ð‘¯ %s: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE ð‘¤ð‘²ð‘šð‘®ð‘¼ð‘¦ ð‘¦ð‘Ÿ ð‘’ð‘©ð‘¥ð‘ð‘²ð‘¤ð‘› ð‘¢ð‘¦ð‘žð‘¬ð‘‘ UTF8 ð‘•ð‘©ð‘ð‘¹ð‘‘" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE ð‘¤ð‘²ð‘šð‘®ð‘¼ð‘¦ ð‘¦ð‘Ÿ ð‘’ð‘©ð‘¥ð‘ð‘²ð‘¤ð‘› ð‘¢ð‘¦ð‘žð‘¬ð‘‘ UTF8 ð‘ð‘®ð‘ªð‘ð‘¼ð‘‘ð‘¦ð‘Ÿ ð‘•ð‘©ð‘ð‘¹ð‘‘" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "ð‘»ð‘¼ ð‘¢ð‘²ð‘¤ ð‘’ð‘©ð‘¥ð‘ð‘²ð‘¤ð‘¦ð‘™ ð‘®ð‘§ð‘œð‘˜ð‘«ð‘¤ð‘¼ ð‘¦ð‘’ð‘•ð‘ð‘®ð‘§ð‘–ð‘©ð‘¯ %s ð‘¨ð‘‘ ð‘—𑸠%d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "ð‘»ð‘¼ ð‘¢ð‘²ð‘¤ ð‘ªð‘ð‘‘ð‘¦ð‘¥ð‘²ð‘Ÿð‘¦ð‘™ ð‘®ð‘§ð‘œð‘˜ð‘«ð‘¤ð‘¼ ð‘¦ð‘’ð‘•ð‘ð‘®ð‘§ð‘–ð‘©ð‘¯ %s: %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "ð‘£ð‘§ð‘’ð‘•ð‘©ð‘›ð‘§ð‘•ð‘¦ð‘¥ð‘©ð‘¤ ð‘›ð‘¦ð‘¡ð‘¦ð‘‘ 𑹠'}' ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "ð‘£ð‘§ð‘’ð‘•ð‘©ð‘›ð‘§ð‘•ð‘¦ð‘¥ð‘©ð‘¤ ð‘›ð‘¦ð‘¡ð‘¦ð‘‘ ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "ð‘¥ð‘¦ð‘•ð‘¦ð‘™ '<' ð‘¦ð‘¯ ð‘•ð‘¦ð‘¥ð‘šð‘ªð‘¤ð‘¦ð‘’ ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘•" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "ð‘©ð‘¯ð‘“ð‘¦ð‘¯ð‘¦ð‘–ð‘‘ ð‘•ð‘¦ð‘¥ð‘šð‘ªð‘¤ð‘¦ð‘’ ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘•" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "ð‘Ÿð‘½ð‘´-ð‘¤ð‘§ð‘™ð‘” ð‘•ð‘¦ð‘¥ð‘šð‘ªð‘¤ð‘¦ð‘’ ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘•" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "ð‘›ð‘¦ð‘¡ð‘¦ð‘‘ ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "ð‘¦ð‘¤ð‘°ð‘œð‘©ð‘¤ ð‘•ð‘¦ð‘¥ð‘šð‘ªð‘¤ð‘¦ð‘’ ð‘®ð‘§ð‘“ð‘¼ð‘©ð‘¯ð‘•" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "ð‘•ð‘‘ð‘®ð‘± ð‘“ð‘²ð‘¯ð‘©ð‘¤ '\\'" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘¦ð‘•ð‘’ð‘±ð‘ ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘•" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "ð‘»ð‘¼ ð‘¢ð‘²ð‘¤ ð‘ð‘¸ð‘•ð‘¦ð‘™ ð‘®ð‘¦ð‘ð‘¤ð‘±ð‘•ð‘¥ð‘©ð‘¯ð‘‘ ð‘‘ð‘§ð‘’ð‘•ð‘‘ \"%s\" ð‘¨ð‘‘ ð‘—𑸠%lu: %s" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "ð‘’ð‘¢ð‘´ð‘‘ð‘©ð‘› ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘šð‘©ð‘œð‘¦ð‘¯ ð‘¢ð‘¦ð‘ž ð‘© ð‘’ð‘¢ð‘´ð‘‘ð‘±ð‘–ð‘©ð‘¯ ·ð‘¥ð‘¸ð‘’" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "ð‘©ð‘¯ð‘¥ð‘¨ð‘—ð‘‘ ð‘’ð‘¢ð‘´ð‘‘ð‘±ð‘–ð‘©ð‘¯ ð‘¥ð‘¸ð‘’ ð‘¦ð‘¯ ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘› ð‘¤ð‘²ð‘¯ 𑹠ð‘³ð‘žð‘¼ ð‘–ð‘§ð‘¤-ð‘’ð‘¢ð‘´ð‘‘ð‘©ð‘› ð‘‘ð‘§ð‘’ð‘•ð‘‘" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘¡ð‘³ð‘•ð‘‘ ð‘­ð‘“ð‘‘𑼠𑩠'\\' ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘ð‘¼. (𑞠ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘¢ð‘ªð‘Ÿ '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘šð‘¦ð‘“𑹠ð‘¥ð‘¨ð‘—ð‘¦ð‘™ ð‘’ð‘¢ð‘´ð‘‘ ð‘¢ð‘ªð‘Ÿ ð‘“ð‘¬ð‘¯ð‘› ð‘“𑹠%c. (𑞠ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘¢ð‘ªð‘Ÿ '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘¢ð‘ªð‘Ÿ ð‘§ð‘¥ð‘ð‘‘𑦠(𑹠ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘› ð‘´ð‘¯ð‘¤ð‘¦ ð‘¢ð‘²ð‘‘ð‘•ð‘ð‘±ð‘•)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘› ð‘›ð‘±ð‘‘ð‘© ð‘“ð‘®ð‘ªð‘¥ ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘•" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘ð‘²ð‘ ð‘“𑹠ð‘’ð‘©ð‘¥ð‘¿ð‘¯ð‘¦ð‘’ð‘±ð‘‘ð‘¦ð‘™ ð‘¢ð‘¦ð‘ž ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘• (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘› ð‘“ð‘®ð‘ªð‘¥ ð‘—ð‘²ð‘¤ð‘› ð‘ð‘²ð‘ (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘—ð‘±ð‘¯ð‘¡ ð‘‘ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘§ð‘’ð‘•ð‘©ð‘’ð‘¿ð‘‘ ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘• (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘ð‘®ð‘´ð‘œð‘®ð‘¨ð‘¥ ð‘¯ð‘±ð‘¥: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘•ð‘‘ð‘®ð‘¦ð‘™ ð‘¦ð‘¯ ð‘¸ð‘œð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘ð‘§ð‘’ð‘‘𑼠ð‘¨ð‘‘ %d: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘•ð‘‘ð‘®ð‘¦ð‘™ ð‘¦ð‘¯ ð‘§ð‘¯ð‘ð‘²ð‘¼ð‘¯ð‘¥ð‘©ð‘¯ð‘‘: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¢ð‘»ð‘’ð‘¦ð‘™ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘§ð‘’ð‘•ð‘©ð‘’ð‘¿ð‘‘ ð‘£ð‘§ð‘¤ð‘𑼠ð‘ð‘®ð‘´ð‘œð‘®ð‘¨ð‘¥ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘»ð‘¼ ð‘¦ð‘¯ g_io_channel_win32_poll() ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘›ð‘±ð‘‘ð‘© ð‘“ð‘®ð‘ªð‘¥ ð‘© ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘•" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘› ð‘›ð‘±ð‘‘ð‘© ð‘“ð‘®ð‘ªð‘¥ ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘• (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘»ð‘¼ ð‘¦ð‘¯ select() ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘›ð‘±ð‘‘ð‘© ð‘“ð‘®ð‘ªð‘¥ ð‘© ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘• (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘»ð‘¼ ð‘¦ð‘¯ waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘“ð‘¹ð‘’ (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘§ð‘’ð‘•ð‘©ð‘’ð‘¿ð‘‘ ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘• \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘›ð‘»ð‘§ð‘’ð‘‘ ð‘¬ð‘‘ð‘ð‘«ð‘‘ 𑹠ð‘¦ð‘¯ð‘ð‘«ð‘‘ ð‘ ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘• (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘“ð‘¹ð‘’ ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘• (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘»ð‘¼ ð‘§ð‘’ð‘•ð‘©ð‘’ð‘¿ð‘‘ð‘¦ð‘™ ð‘—ð‘²ð‘¤ð‘› ð‘ð‘®ð‘´ð‘•ð‘§ð‘• \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘› ð‘¦ð‘¯ð‘³ð‘“ ð‘›ð‘±ð‘‘ð‘© ð‘“ð‘®ð‘ªð‘¥ ð‘—ð‘²ð‘¤ð‘› pid ð‘ð‘²ð‘ (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘¬ð‘‘ ð‘ ð‘®ð‘±ð‘¯ð‘¡ ð‘“𑹠UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘• ð‘¦ð‘¯ ð‘’ð‘©ð‘¯ð‘ð‘»ð‘–ð‘©ð‘¯ ð‘¦ð‘¯ð‘ð‘«ð‘‘" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘¬ð‘‘ ð‘ ð‘®ð‘±ð‘¯ð‘¡ ð‘“𑹠UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "ð‘¿ð‘•ð‘¦ð‘¡:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[ð‘ªð‘ð‘–ð‘©ð‘¯...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "ð‘£ð‘§ð‘¤ð‘ ð‘ªð‘ð‘–ð‘©ð‘¯ð‘Ÿ:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "ð‘–ð‘´ ð‘£ð‘§ð‘¤ð‘ ð‘ªð‘ð‘–ð‘©ð‘¯ð‘Ÿ" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "ð‘–ð‘´ ð‘·ð‘¤ ð‘£ð‘§ð‘¤ð‘ ð‘ªð‘ð‘–ð‘©ð‘¯ð‘Ÿ" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "ð‘©ð‘ð‘¤ð‘¦ð‘’ð‘±ð‘•ð‘©ð‘¯ ð‘ªð‘ð‘–ð‘©ð‘¯ð‘Ÿ:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘ð‘¸ð‘• ð‘¦ð‘¯ð‘‘ð‘©ð‘¡ð‘¼ ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘“𑹠%s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "ð‘¦ð‘¯ð‘‘ð‘©ð‘¡ð‘¼ ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘“𑹠%s ð‘¬ð‘‘ ð‘ ð‘®ð‘±ð‘¯ð‘¡" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘ð‘¸ð‘• ð‘›ð‘³ð‘šð‘©ð‘¤ ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘“𑹠%s" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "ð‘›ð‘³ð‘šð‘©ð‘¤ ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘“𑹠%s ð‘¬ð‘‘ ð‘ ð‘®ð‘±ð‘¯ð‘¡" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "ð‘»ð‘¼ ð‘ð‘¸ð‘•ð‘¦ð‘™ ð‘ªð‘ð‘–ð‘©ð‘¯ %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "ð‘¥ð‘¦ð‘•ð‘¦ð‘™ ð‘¸ð‘œð‘¿ð‘¥ð‘©ð‘¯ð‘‘ ð‘“𑹠%s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘ªð‘ð‘–ð‘©ð‘¯ %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘šð‘° ð‘“ð‘¬ð‘¯ð‘› ð‘¦ð‘¯ ð‘•ð‘»ð‘— ð‘›ð‘»ð‘Ÿ" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "ð‘¯ð‘ªð‘‘ ð‘© ð‘®ð‘§ð‘œð‘˜ð‘«ð‘¤ð‘¼ ð‘“ð‘²ð‘¤" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "ð‘“ð‘²ð‘¤ ð‘¦ð‘Ÿ ð‘§ð‘¥ð‘ð‘‘ð‘¦" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘¤ð‘²ð‘¯ '%s' ð‘¢ð‘¦ð‘— ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘’ð‘°-ð‘ð‘¨ð‘¤ð‘¿ ð‘ð‘º, ð‘œð‘®ð‘µð‘, 𑹠ð‘’ð‘³ð‘¥ð‘¥ð‘©ð‘¯ð‘‘" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘œð‘®ð‘µð‘ ð‘¯ð‘±ð‘¥: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘•ð‘‘ð‘¸ð‘‘ ð‘¢ð‘¦ð‘ž ð‘© ð‘œð‘®ð‘µð‘" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘’ð‘° ð‘¯ð‘±ð‘¥: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘³ð‘¯ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™ '%s'" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘£ð‘¨ð‘ ð‘œð‘®ð‘µð‘ '%s'" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘£ð‘¨ð‘ ð‘’ð‘° '%s'" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘’ð‘° '%s' ð‘¢ð‘¦ð‘ž ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘¢ð‘¦ð‘— ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘’ð‘° '%s' ð‘¢ð‘¦ð‘— ð‘£ð‘¨ð‘Ÿ ð‘ð‘¨ð‘¤ð‘¿ ð‘žð‘¨ð‘‘ ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘šð‘° ð‘¦ð‘¯ð‘‘ð‘»ð‘ð‘®ð‘©ð‘‘ð‘©ð‘›." + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘’ð‘° '%s' ð‘¢ð‘¦ð‘— ð‘£ð‘¨ð‘Ÿ ð‘© ð‘ð‘¨ð‘¤ð‘¿ ð‘žð‘¨ð‘‘ ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘šð‘° ð‘¦ð‘¯ð‘‘ð‘»ð‘ð‘®ð‘©ð‘‘ð‘©ð‘›." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘’ð‘° '%s' ð‘¦ð‘¯ ð‘œð‘®ð‘µð‘ '%s' ð‘¢ð‘¦ð‘— ð‘£ð‘¨ð‘Ÿ ð‘ð‘¨ð‘¤ð‘¿ ð‘žð‘¨ð‘‘ ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘šð‘° ð‘¦ð‘¯ð‘‘ð‘»ð‘ð‘®ð‘©ð‘‘ð‘©ð‘›." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘£ð‘¨ð‘ ð‘’ð‘° '%s' ð‘¦ð‘¯ ð‘œð‘®ð‘µð‘ '%s'" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘¦ð‘•ð‘’ð‘±ð‘ ð‘’ð‘¨ð‘®ð‘©ð‘’ð‘‘𑼠ð‘¨ð‘‘ ð‘§ð‘¯ð‘› ð‘ ð‘¤ð‘²ð‘¯" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "ð‘’ð‘° ð‘“ð‘²ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¦ð‘•ð‘’ð‘±ð‘ ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘• '%s'" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘šð‘° ð‘¦ð‘¯ð‘‘ð‘»ð‘ð‘®ð‘©ð‘‘ð‘©ð‘› ð‘¨ð‘Ÿ ð‘© ð‘¯ð‘³ð‘¥ð‘šð‘¼." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "ð‘¦ð‘¯ð‘‘ð‘©ð‘¡ð‘¼ ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘¬ð‘‘ ð‘ ð‘®ð‘±ð‘¯ð‘¡" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘šð‘° ð‘¦ð‘¯ð‘‘ð‘»ð‘ð‘®ð‘©ð‘‘ð‘©ð‘› ð‘¨ð‘Ÿ ð‘© ð‘“ð‘¤ð‘´ð‘‘ ð‘¯ð‘³ð‘¥ð‘šð‘¼." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "ð‘ð‘¨ð‘¤ð‘¿ '%s' ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘šð‘° ð‘¦ð‘¯ð‘‘ð‘»ð‘ð‘®ð‘©ð‘‘ð‘©ð‘› ð‘¨ð‘Ÿ ð‘© ð‘šð‘µð‘¤ð‘°ð‘©ð‘¯." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "ð‘‘𑵠ð‘¤ð‘¸ð‘¡ ð‘’ð‘¬ð‘¯ð‘‘ ð‘ð‘¨ð‘¤ð‘¿ ð‘ð‘­ð‘•ð‘‘ ð‘‘ %s" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "ð‘•ð‘‘ð‘®ð‘°ð‘¥ ð‘¦ð‘Ÿ ð‘·ð‘¤ð‘®ð‘§ð‘›ð‘¦ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "ð‘ªð‘ð‘¼ð‘±ð‘–ð‘©ð‘¯ ð‘¢ð‘ªð‘Ÿ ð‘’ð‘¨ð‘¯ð‘•ð‘©ð‘¤ð‘›" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘©ð‘šð‘¡ð‘§ð‘’ð‘‘, ð‘¯ð‘ªð‘‘ ð‘¦ð‘¯ð‘¦ð‘–ð‘©ð‘¤ð‘²ð‘Ÿð‘›" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "ð‘¦ð‘¯ð‘’ð‘©ð‘¥ð‘ð‘¤ð‘°ð‘‘ ð‘¥ð‘³ð‘¤ð‘‘ð‘¦ð‘šð‘²ð‘‘ ð‘•ð‘°ð‘’ð‘¢ð‘©ð‘¯ð‘• ð‘¦ð‘¯ ð‘¦ð‘¯ð‘ð‘«ð‘‘" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "ð‘¯ð‘ªð‘‘ ð‘¦ð‘¯ð‘³ð‘“ ð‘•ð‘ð‘±ð‘• ð‘¦ð‘¯ ð‘›ð‘§ð‘•ð‘‘ð‘¦ð‘¯ð‘±ð‘–ð‘©ð‘¯" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "ð‘’ð‘¨ð‘¯ð‘•ð‘§ð‘¤ð‘©ð‘šð‘©ð‘¤ ð‘¦ð‘¯ð‘¦ð‘‘ð‘¦ð‘©ð‘¤ð‘²ð‘Ÿð‘¨ð‘–ð‘©ð‘¯ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘‘ð‘²ð‘" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s ð‘“ð‘²ð‘¤ð‘‘ð‘²ð‘" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s ð‘‘ð‘²ð‘" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘»ð‘¤ð‘° ð‘§ð‘¯ð‘›-ð‘-ð‘•ð‘‘ð‘®ð‘°ð‘¥" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, fuzzy, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "ð‘³ð‘¯ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘•ð‘ªð‘’ð‘©ð‘‘ ð‘©ð‘›ð‘®ð‘§ð‘•" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "ð‘»ð‘¼ ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘‘ð‘¦ð‘™: " + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "ð‘»ð‘¼ ð‘®ð‘²ð‘‘ð‘¦ð‘™ ð‘‘ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘‘ð‘²ð‘" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘®ð‘¦ð‘±ð‘‘ð‘¦ð‘™ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘¤ð‘´ð‘Ÿð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "ð‘¨ð‘›ð‘©ð‘› ð‘•ð‘ªð‘’ð‘©ð‘‘ ð‘¦ð‘Ÿ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, fuzzy, c-format +msgid "Property '%s' is not readable" +msgstr "ð‘’ð‘° %s ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘®ð‘²ð‘‘ð‘©ð‘šð‘©ð‘¤\n" + +#: ../gio/gdbusconnection.c:3959 +#, fuzzy, c-format +msgid "Property '%s' is not writable" +msgstr "ð‘’ð‘° %s ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘®ð‘²ð‘‘ð‘©ð‘šð‘©ð‘¤\n" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "ð‘¤ð‘¦ð‘•ð‘©ð‘¯ð‘» ð‘¦ð‘Ÿ ð‘·ð‘¤ð‘®ð‘§ð‘›ð‘¦ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, fuzzy, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¯ð‘±ð‘¥ " + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "ð‘»ð‘¼ ð‘®ð‘²ð‘‘ð‘¦ð‘™ ð‘‘ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "ð‘‘ð‘®ð‘¨ð‘– ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘²ð‘‘ð‘¦ð‘™ ð‘‘ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gdbusserver.c:1042 +#, fuzzy, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¯ð‘±ð‘¥ " + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘›" + +#: ../gio/gdbus-tool.c:93 +#, fuzzy, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘›ð‘Ÿ:\n" +" help ð‘–ð‘´ ð‘žð‘¦ð‘• ð‘¦ð‘¯ð‘“ð‘¼ð‘¥ð‘±ð‘–ð‘©ð‘¯\n" +" get ð‘œð‘§ð‘‘ 𑞠ð‘ð‘¨ð‘¤ð‘¿ ð‘ ð‘© ð‘’ð‘°\n" +" set ð‘•ð‘§ð‘‘ 𑞠ð‘ð‘¨ð‘¤ð‘¿ ð‘ ð‘© ð‘’ð‘°\n" +" monitor ð‘¥ð‘ªð‘¯ð‘¦ð‘‘𑼠𑩠ð‘’ð‘° ð‘“𑹠ð‘—ð‘±ð‘¯ð‘¡ð‘©ð‘Ÿ\n" +" writable ð‘—ð‘§ð‘’ ð‘¦ð‘“ ð‘© ð‘’ð‘° ð‘¦ð‘Ÿ ð‘®ð‘²ð‘‘ð‘©ð‘šð‘©ð‘¤\n" +"\n" +"ð‘¿ð‘Ÿ '%s ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘› --help' ð‘‘ ð‘œð‘§ð‘‘ ð‘£ð‘§ð‘¤ð‘ ð‘“𑹠ð‘¦ð‘¯ð‘›ð‘¦ð‘ð‘¦ð‘›ð‘¿ð‘©ð‘¤ ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘›ð‘Ÿ.\n" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "ð‘»ð‘¼ ð‘ªð‘¯ ð‘¤ð‘²ð‘¯ %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "ð‘»ð‘¼ ð‘ð‘¸ð‘•ð‘¦ð‘™ ð‘ªð‘ð‘–ð‘©ð‘¯ %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +#, fuzzy +msgid "Connect to given D-Bus address" +msgstr "ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘–ð‘©ð‘¯ ð‘¦ð‘¯ ð‘ð‘®ð‘´ð‘œð‘®ð‘§ð‘•" + +#: ../gio/gdbus-tool.c:360 +#, fuzzy +msgid "Connection Endpoint Options:" +msgstr "ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘–ð‘©ð‘¯ ð‘¦ð‘¯ ð‘ð‘®ð‘´ð‘œð‘®ð‘§ð‘•" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "ð‘»ð‘¼ ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘‘ð‘¦ð‘™: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, fuzzy, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¯ð‘±ð‘¥ " + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¯ð‘±ð‘¥ " + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¯ð‘±ð‘¥ " + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "'%s' ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¯ð‘±ð‘¥ " + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "ð‘»ð‘¼ ð‘ð‘¸ð‘•ð‘¦ð‘™ ð‘ªð‘ð‘–ð‘©ð‘¯ %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "ð‘»ð‘¼ ð‘¨ð‘’ð‘•ð‘§ð‘ð‘‘ð‘¦ð‘™ ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘–ð‘©ð‘¯: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "ð‘’ð‘¼ð‘³ð‘ð‘‘ð‘©ð‘› ð‘©ð‘šð‘¡ð‘§ð‘’ð‘‘" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "ð‘©ð‘¯ð‘¯ð‘±ð‘¥ð‘›" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "ð‘›ð‘§ð‘•ð‘’ð‘‘ð‘ªð‘ ð‘“ð‘²ð‘¤ ð‘›ð‘¦ð‘›ð‘¯ð‘‘ ð‘•ð‘ð‘§ð‘•ð‘¦ð‘“𑲠Exec ð‘“ð‘°ð‘¤ð‘›" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘“ð‘²ð‘¯ð‘› ð‘‘ð‘»ð‘¥ð‘¦ð‘¯ð‘©ð‘¤ ð‘®ð‘¦ð‘’ð‘¢ð‘²ð‘¼ð‘› ð‘“𑹠ð‘©ð‘ð‘¤ð‘¦ð‘’ð‘±ð‘•ð‘©ð‘¯" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘¿ð‘Ÿð‘¼ ð‘©ð‘ð‘¤ð‘¦ð‘’ð‘±ð‘•ð‘©ð‘¯ ð‘’ð‘©ð‘¯ð‘“ð‘¦ð‘œð‘˜ð‘¼ð‘±ð‘–ð‘©ð‘¯ ð‘“ð‘´ð‘¤ð‘›ð‘¼ %s: %s" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘¿ð‘Ÿð‘¼ MIME ð‘’ð‘©ð‘¯ð‘“ð‘¦ð‘œð‘˜ð‘¼ð‘±ð‘–ð‘©ð‘¯ ð‘“ð‘´ð‘¤ð‘›ð‘¼ %s: %s" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘¿ð‘Ÿð‘¼ ð‘›ð‘§ð‘•ð‘’ð‘‘ð‘ªð‘ ð‘“ð‘²ð‘¤ %s" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "ð‘’ð‘³ð‘•ð‘‘ð‘©ð‘¥ ð‘›ð‘§ð‘“ð‘©ð‘¯ð‘¦ð‘–ð‘©ð‘¯ ð‘“𑹠%s" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "ð‘›ð‘®ð‘²ð‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘¦ð‘¡ð‘§ð‘’ð‘‘" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "ð‘›ð‘®ð‘²ð‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ eject 𑹠eject_with_operation" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "ð‘›ð‘®ð‘²ð‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘ð‘´ð‘¤ð‘¦ð‘™ ð‘“𑹠ð‘¥ð‘°ð‘›ð‘¦ð‘©" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "ð‘›ð‘®ð‘²ð‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘•ð‘‘ð‘¸ð‘‘" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "ð‘›ð‘®ð‘²ð‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘•ð‘‘ð‘ªð‘" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘£ð‘¨ð‘¯ð‘›ð‘©ð‘¤ ð‘ð‘»ð‘ ð‘©ð‘¯ %d ð‘ GEmblem ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "ð‘¥ð‘¨ð‘¤ð‘“ð‘¹ð‘¥ð‘› ð‘¯ð‘³ð‘¥ð‘šð‘¼ ð‘ ð‘‘ð‘´ð‘’ð‘©ð‘¯ð‘Ÿ (%d) ð‘¦ð‘¯ GEmblem ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘£ð‘¨ð‘¯ð‘›ð‘©ð‘¤ ð‘ð‘»ð‘ ð‘©ð‘¯ %d ð‘ GEmblemedIcon ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "ð‘¥ð‘¨ð‘¤ð‘“ð‘¹ð‘¥ð‘› ð‘¯ð‘³ð‘¥ð‘šð‘¼ ð‘ ð‘‘ð‘´ð‘’ð‘©ð‘¯ð‘Ÿ (%d) ð‘¦ð‘¯ GEmblemedIcon ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘© GEmblem ð‘“𑹠GEmblemedIcon" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "ð‘ªð‘ð‘¼ð‘±ð‘–ð‘©ð‘¯ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘¦ð‘™ ð‘¥ð‘¬ð‘¯ð‘‘ ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘§ð‘’ð‘Ÿð‘¦ð‘•ð‘‘" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘’ð‘ªð‘𑦠ð‘´ð‘𑼠ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘’ð‘ªð‘𑦠ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ ð‘´ð‘𑼠ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "ð‘‘ð‘¸ð‘œð‘§ð‘‘ ð‘“ð‘²ð‘¤ ð‘§ð‘’ð‘Ÿð‘¦ð‘•ð‘‘ð‘•" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘®ð‘¦ð‘’ð‘»ð‘•ð‘¦ð‘ð‘¤ð‘¦ ð‘’ð‘ªð‘𑦠ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "ð‘•ð‘ð‘¤ð‘²ð‘• ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../gio/gfile.c:2762 +#, c-format +msgid "Error splicing file: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘ð‘¤ð‘²ð‘•ð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘’ð‘ªð‘𑦠ð‘•ð‘ð‘§ð‘–ð‘©ð‘¤ ð‘“ð‘²ð‘¤" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘•ð‘¦ð‘¥ð‘¤ð‘¦ð‘™ð‘’ ð‘ð‘¨ð‘¤ð‘¿ ð‘œð‘¦ð‘ð‘©ð‘¯" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "ð‘‘ð‘®ð‘¨ð‘– ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ð‘“ð‘²ð‘¤ ð‘¯ð‘±ð‘¥ð‘Ÿ ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ '%c'" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "ð‘ð‘ªð‘¤ð‘¿ð‘¥ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘¥ð‘¬ð‘¯ð‘‘" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "ð‘¯ð‘´ ð‘©ð‘ð‘¤ð‘¦ð‘’ð‘±ð‘•ð‘©ð‘¯ ð‘¦ð‘Ÿ ð‘®ð‘§ð‘¡ð‘¦ð‘•ð‘‘ð‘¼ð‘› ð‘¨ð‘Ÿ ð‘£ð‘¨ð‘¯ð‘›ð‘¤ð‘¦ð‘™ ð‘žð‘¦ð‘• ð‘“ð‘²ð‘¤" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "ð‘§ð‘¯ð‘¿ð‘¥ð‘»ð‘±ð‘‘𑼠ð‘¦ð‘Ÿ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "ð‘“ð‘²ð‘¤ ð‘§ð‘¯ð‘¿ð‘¥ð‘»ð‘±ð‘‘𑼠ð‘£ð‘¨ð‘Ÿ ð‘¶ð‘‘ð‘•ð‘‘ð‘¨ð‘¯ð‘›ð‘¦ð‘™ ð‘ªð‘ð‘¼ð‘±ð‘–ð‘©ð‘¯" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "ð‘“ð‘²ð‘¤ ð‘§ð‘¯ð‘¿ð‘¥ð‘»ð‘±ð‘‘𑼠ð‘¦ð‘Ÿ ð‘·ð‘¤ð‘®ð‘§ð‘›ð‘¦ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘£ð‘¨ð‘¯ð‘›ð‘©ð‘¤ ð‘ð‘»ð‘ ð‘©ð‘¯ %d ð‘ GFileIcon ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "ð‘¥ð‘¨ð‘¤ð‘“ð‘¹ð‘¥ð‘› ð‘¦ð‘¯ð‘ð‘«ð‘‘ ð‘›ð‘±ð‘‘ð‘© ð‘“𑹠GFileIcon" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "ð‘•ð‘‘ð‘®ð‘°ð‘¥ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ query_info" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "ð‘•ð‘°ð‘’ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘ªð‘¯ ð‘•ð‘‘ð‘®ð‘°ð‘¥" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "ð‘‘ð‘®ð‘©ð‘™ð‘’ð‘±ð‘‘ ð‘¯ð‘ªð‘‘ ð‘©ð‘¤ð‘¬ð‘› ð‘ªð‘¯ ð‘¦ð‘¯ð‘ð‘«ð‘‘ ð‘•ð‘‘ð‘®ð‘°ð‘¥" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "ð‘‘ð‘®ð‘©ð‘™ð‘’ð‘±ð‘‘ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘ªð‘¯ ð‘•ð‘‘ð‘®ð‘°ð‘¥" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "ð‘®ð‘ªð‘™ ð‘¯ð‘³ð‘¥ð‘šð‘¼ ð‘ ð‘‘ð‘´ð‘’ð‘©ð‘¯ð‘Ÿ (%d)" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "ð‘¯ð‘´ ð‘‘ð‘²ð‘ ð‘“𑹠ð‘’ð‘¤ð‘­ð‘• ð‘¯ð‘±ð‘¥ %s" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "ð‘‘ð‘²ð‘ %s ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ 𑞠GIcon ð‘¦ð‘¯ð‘‘ð‘¼ð‘“ð‘±ð‘•" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "ð‘‘ð‘²ð‘ %s ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘’ð‘¤ð‘¨ð‘•ð‘‘" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "ð‘¥ð‘¨ð‘¤ð‘“ð‘¹ð‘¥ð‘› ð‘ð‘»ð‘ ð‘©ð‘¯ ð‘¯ð‘³ð‘¥ð‘šð‘¼: %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "ð‘‘ð‘²ð‘ %s ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ from_tokens() ð‘ªð‘¯ 𑞠GIcon ð‘¦ð‘¯ð‘‘ð‘¼ð‘“ð‘±ð‘•" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘£ð‘¨ð‘¯ð‘›ð‘©ð‘¤ 𑞠ð‘•ð‘©ð‘ð‘¤ð‘²ð‘› ð‘ð‘»ð‘ ð‘©ð‘¯ 𑞠ð‘²ð‘’ð‘ªð‘¯ ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "ð‘¦ð‘¯ð‘ð‘«ð‘‘ ð‘•ð‘‘ð‘®ð‘°ð‘¥ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘®ð‘§ð‘›" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "ð‘•ð‘‘ð‘®ð‘°ð‘¥ ð‘£ð‘¨ð‘Ÿ ð‘¶ð‘‘ð‘•ð‘‘ð‘¨ð‘¯ð‘›ð‘¦ð‘™ ð‘ªð‘ð‘¼ð‘±ð‘–ð‘©ð‘¯" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "ð‘¯ð‘ªð‘‘ ð‘¦ð‘¯ð‘³ð‘“ ð‘•ð‘ð‘±ð‘• ð‘“𑹠ð‘•ð‘ªð‘’ð‘©ð‘‘ ð‘©ð‘›ð‘®ð‘§ð‘•" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "ð‘³ð‘¯ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘•ð‘ªð‘’ð‘©ð‘‘ ð‘©ð‘›ð‘®ð‘§ð‘•" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "ð‘‘ð‘®ð‘¨ð‘– ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, fuzzy, c-format +msgid "invalid GVariant type string '%s'" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘‘ð‘²ð‘ (ð‘•ð‘‘ð‘®ð‘¦ð‘™ ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›)" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "ð‘¢ð‘º ð‘‘ ð‘•ð‘‘𑹠𑞠gschemas.compiled ð‘“ð‘²ð‘¤" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "ð‘›ð‘µ ð‘¯ð‘ªð‘‘ ð‘®ð‘²ð‘‘ 𑞠gschema.compiled ð‘“ð‘²ð‘¤" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "ð‘›ð‘µ ð‘¯ð‘ªð‘‘ ð‘§ð‘¯ð‘“ð‘ªð‘®ð‘• ð‘’ð‘° ð‘¯ð‘±ð‘¥ ð‘®ð‘°ð‘•ð‘‘ð‘®ð‘¦ð‘’ð‘–ð‘©ð‘¯ð‘Ÿ" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"ð‘’ð‘ªð‘¥ð‘ð‘²ð‘¤ ð‘·ð‘¤ GSettings ð‘•ð‘’ð‘°ð‘¥ð‘© ð‘“ð‘²ð‘¤ð‘Ÿ ð‘¦ð‘¯ð‘‘ð‘« ð‘© ð‘•ð‘’ð‘°ð‘¥ð‘© ð‘’ð‘¨ð‘–.\n" +"ð‘•ð‘’ð‘°ð‘¥ð‘© ð‘“ð‘²ð‘¤ð‘Ÿ 𑸠ð‘®ð‘¦ð‘’ð‘¢ð‘²ð‘¼ð‘› ð‘‘ ð‘£ð‘¨ð‘ 𑞠ð‘©ð‘’ð‘•ð‘‘ð‘§ð‘¯ð‘–ð‘©ð‘¯ .gschema.xml,\n" +"𑯠𑞠ð‘’ð‘¨ð‘– ð‘“ð‘²ð‘¤ ð‘¦ð‘Ÿ ð‘’ð‘·ð‘¤ð‘› gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "ð‘¿ ð‘–ð‘«ð‘› ð‘œð‘¦ð‘ ð‘¦ð‘œð‘Ÿð‘¨ð‘’ð‘‘ð‘¤ð‘¦ ð‘¢ð‘³ð‘¯ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ ð‘¯ð‘±ð‘¥\n" + +#: ../gio/glib-compile-schemas.c:2028 +#, fuzzy, c-format +msgid "No schema files found: " +msgstr "ð‘¯ð‘´ ð‘•ð‘’ð‘°ð‘¥ð‘© ð‘“ð‘²ð‘¤ð‘Ÿ ð‘“ð‘¬ð‘¯ð‘›\n" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘“ð‘²ð‘¯ð‘› ð‘›ð‘¦ð‘“ð‘·ð‘¤ð‘‘ ð‘¤ð‘´ð‘’ð‘©ð‘¤ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ ð‘¥ð‘ªð‘¯ð‘¦ð‘‘𑼠ð‘‘ð‘²ð‘" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘“ð‘²ð‘¤ð‘¯ð‘±ð‘¥ %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ð‘»ð‘¼ ð‘œð‘§ð‘‘ð‘¦ð‘™ ð‘“ð‘²ð‘¤ð‘•ð‘¦ð‘•ð‘‘ð‘©ð‘¥ ð‘¦ð‘¯ð‘“ð‘´: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘®ð‘°ð‘¯ð‘±ð‘¥ ð‘®ð‘µð‘‘ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘¯ð‘±ð‘¥ð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘®ð‘°ð‘¯ð‘±ð‘¥ ð‘“ð‘²ð‘¤, ð‘“ð‘²ð‘¤ð‘¯ð‘±ð‘¥ ð‘·ð‘¤ð‘®ð‘§ð‘›ð‘¦ ð‘§ð‘’ð‘Ÿð‘¦ð‘•ð‘‘" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘“ð‘²ð‘¤ð‘¯ð‘±ð‘¥" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘´ð‘ð‘©ð‘¯ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘¦ð‘¥ð‘µð‘ð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "ð‘»ð‘¼ ð‘‘ð‘®ð‘¨ð‘–ð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘‘ð‘®ð‘¨ð‘– ð‘›ð‘» %s: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘“ð‘²ð‘¯ð‘› ð‘‘ð‘ªð‘ð‘¤ð‘§ð‘ð‘©ð‘¤ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ ð‘“𑹠ð‘‘ð‘®ð‘¨ð‘–" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘“ð‘²ð‘¯ð‘› 𑹠ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘‘ð‘®ð‘¨ð‘– ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘‘ð‘®ð‘¨ð‘–ð‘¦ð‘™ ð‘¦ð‘¯ð‘“ð‘´ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘‘ð‘®ð‘¨ð‘– ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘®ð‘¦ð‘±ð‘‘ð‘¦ð‘™ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦: %s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ð‘“ð‘²ð‘¤ð‘•ð‘¦ð‘•ð‘‘ð‘©ð‘¥ ð‘›ð‘³ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ ð‘•ð‘¦ð‘¥ð‘šð‘ªð‘¤ð‘¦ð‘’ ð‘¤ð‘¦ð‘™ð‘’ð‘•" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "ð‘»ð‘¼ ð‘¥ð‘±ð‘’ð‘¦ð‘™ ð‘•ð‘¦ð‘¥ð‘šð‘ªð‘¤ð‘¦ð‘’ ð‘¤ð‘¦ð‘™ð‘’: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "ð‘»ð‘¼ ð‘¥ð‘µð‘ð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘¥ð‘µð‘ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ ð‘´ð‘𑼠ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "ð‘šð‘¨ð‘’ð‘³ð‘ ð‘“ð‘²ð‘¤ ð‘’ð‘®ð‘°ð‘±ð‘–ð‘©ð‘¯ ð‘“ð‘±ð‘¤ð‘›" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘¦ð‘¥ð‘µð‘ð‘¦ð‘™ ð‘‘ð‘¸ð‘œð‘§ð‘‘ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "ð‘¥ð‘µð‘ ð‘šð‘¦ð‘‘ð‘¢ð‘°ð‘¯ ð‘¥ð‘¶ð‘¯ð‘‘ð‘• ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘ð‘¨ð‘¤ð‘¿ ð‘¥ð‘³ð‘•ð‘‘ ð‘šð‘° ð‘¯ð‘ªð‘¯-NULL" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘‘ð‘²ð‘ (ð‘•ð‘‘ð‘®ð‘¦ð‘™ ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›)" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘¦ð‘’ð‘•ð‘‘ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘¯ð‘±ð‘¥" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘‘ð‘¦ð‘™ ð‘¦ð‘’ð‘•ð‘‘ð‘§ð‘¯ð‘›ð‘©ð‘› ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ '%s': %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘‘ð‘¨ð‘‘ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘‘ð‘±ð‘‘ð‘¦ð‘™ ð‘“ð‘²ð‘¤ ð‘›ð‘§ð‘•ð‘’ð‘®ð‘¦ð‘ð‘‘ð‘¼: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘‘ð‘²ð‘ (uint32 ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘‘ð‘²ð‘ (uint64 ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›)" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘©ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ ð‘‘ð‘²ð‘ (ð‘šð‘²ð‘‘ ð‘•ð‘‘ð‘®ð‘¦ð‘™ ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘›)" + +#: ../gio/glocalfileinfo.c:1904 +msgid "Cannot set permissions on symlinks" +msgstr "ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘•ð‘§ð‘‘ ð‘ð‘»ð‘¥ð‘¦ð‘–ð‘ªð‘¯ð‘Ÿ ð‘ªð‘¯ ð‘•ð‘¦ð‘¥ð‘¤ð‘¦ð‘™ð‘’ð‘•" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘‘ð‘¦ð‘™ ð‘ð‘»ð‘¥ð‘¦ð‘–ð‘ªð‘¯ð‘Ÿ: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘‘ð‘¦ð‘™ ð‘´ð‘¯ð‘¼: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "ð‘•ð‘¦ð‘¥ð‘¤ð‘¦ð‘™ð‘’ ð‘¥ð‘³ð‘•ð‘‘ ð‘šð‘° ð‘¯ð‘ªð‘¯-NULL" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘‘ð‘¦ð‘™ ð‘•ð‘¦ð‘¥ð‘¤ð‘¦ð‘™ð‘’: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘‘ð‘¦ð‘™ ð‘•ð‘¦ð‘¥ð‘¤ð‘¦ð‘™ð‘’: ð‘“ð‘²ð‘¤ ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘•ð‘¦ð‘¥ð‘¤ð‘¦ð‘™ð‘’" + +#: ../gio/glocalfileinfo.c:2139 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘‘ð‘¦ð‘™ ð‘¥ð‘ªð‘›ð‘¦ð‘“ð‘¦ð‘’ð‘±ð‘–ð‘©ð‘¯ 𑹠ð‘¨ð‘’ð‘•ð‘§ð‘• ð‘‘ð‘²ð‘¥: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "SELinux ð‘’ð‘ªð‘¯ð‘‘ð‘§ð‘’ð‘•ð‘‘ ð‘¥ð‘³ð‘•ð‘‘ ð‘šð‘° ð‘¯ð‘ªð‘¯-NULL" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘‘ð‘¦ð‘™ SELinux ð‘’ð‘ªð‘¯ð‘‘ð‘§ð‘’ð‘•ð‘‘: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "SELinux ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘¦ð‘¯ð‘±ð‘šð‘©ð‘¤ð‘› ð‘ªð‘¯ ð‘žð‘¦ð‘• ð‘•ð‘¦ð‘•ð‘‘ð‘©ð‘¥" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "ð‘•ð‘§ð‘‘ð‘¦ð‘™ ð‘¨ð‘‘ð‘®ð‘¦ð‘šð‘¿ð‘‘ %s ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘®ð‘ªð‘¥ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘°ð‘’ð‘¦ð‘™ ð‘¦ð‘¯ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘¤ð‘´ð‘Ÿð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘“ð‘²ð‘¯ð‘› ð‘›ð‘¦ð‘“ð‘·ð‘¤ð‘‘ ð‘¤ð‘´ð‘’ð‘©ð‘¤ ð‘“ð‘²ð‘¤ ð‘¥ð‘ªð‘¯ð‘¦ð‘‘𑼠ð‘‘ð‘²ð‘" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘²ð‘‘ð‘¦ð‘™ ð‘‘ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘¦ð‘¥ð‘µð‘ð‘¦ð‘™ ð‘´ð‘¤ð‘› ð‘šð‘¨ð‘’ð‘³ð‘ ð‘¤ð‘¦ð‘™ð‘’: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘®ð‘¦ð‘±ð‘‘ð‘¦ð‘™ ð‘šð‘¨ð‘’ð‘³ð‘ ð‘’ð‘ªð‘ð‘¦: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘¯ð‘±ð‘¥ð‘¦ð‘™ ð‘‘ð‘§ð‘¥ð‘ð‘¼ð‘¼ð‘¦ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "ð‘»ð‘¼ ð‘‘ð‘®ð‘©ð‘™ð‘’ð‘±ð‘‘ð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "ð‘»ð‘¼ ð‘´ð‘ð‘©ð‘¯ð‘¦ð‘™ ð‘“ð‘²ð‘¤ '%s': %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "ð‘‘ð‘¸ð‘œð‘§ð‘‘ ð‘“ð‘²ð‘¤ ð‘¦ð‘Ÿ ð‘© ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "ð‘‘ð‘¸ð‘œð‘§ð‘‘ ð‘“ð‘²ð‘¤ ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘© ð‘®ð‘§ð‘œð‘˜ð‘«ð‘¤ð‘¼ ð‘“ð‘²ð‘¤" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "𑞠ð‘“ð‘²ð‘¤ ð‘¢ð‘ªð‘Ÿ ð‘¦ð‘’ð‘•ð‘‘ð‘»ð‘¯ð‘©ð‘¤ð‘¦ ð‘¥ð‘ªð‘›ð‘¦ð‘“ð‘²ð‘›" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘¦ð‘¥ð‘µð‘ð‘¦ð‘™ ð‘´ð‘¤ð‘› ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› GSeekType ð‘•ð‘©ð‘ð‘¤ð‘²ð‘›" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘•ð‘°ð‘’ ð‘®ð‘¦ð‘’ð‘¢ð‘§ð‘•ð‘‘" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "ð‘’ð‘¨ð‘¯ð‘ªð‘‘ ð‘‘ð‘®ð‘©ð‘™ð‘’ð‘±ð‘‘ GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "ð‘¥ð‘§ð‘¥ð‘¼ð‘¦ ð‘¬ð‘‘ð‘ð‘«ð‘‘ ð‘•ð‘‘ð‘®ð‘°ð‘¥ ð‘¯ð‘ªð‘‘ ð‘®ð‘§ð‘•ð‘²ð‘Ÿð‘©ð‘šð‘©ð‘¤" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "ð‘“ð‘±ð‘¤ð‘› ð‘‘ ð‘®ð‘°ð‘•ð‘²ð‘Ÿ ð‘¥ð‘§ð‘¥ð‘¼ð‘¦ ð‘¬ð‘‘ð‘ð‘«ð‘‘ ð‘•ð‘‘ð‘®ð‘°ð‘¥" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "ð‘©ð‘¥ð‘¬ð‘¯ð‘‘ ð‘ ð‘¥ð‘§ð‘¥ð‘¼ð‘¦ ð‘®ð‘¦ð‘’ð‘¢ð‘²ð‘¼ð‘› ð‘‘ ð‘ð‘®ð‘´ð‘•ð‘§ð‘• 𑞠ð‘®ð‘²ð‘‘ ð‘¦ð‘Ÿ ð‘¤ð‘¸ð‘¡ð‘¼ ð‘žð‘¨ð‘¯ ð‘©ð‘ð‘±ð‘¤ð‘©ð‘šð‘©ð‘¤ ð‘©ð‘›ð‘®ð‘§ð‘• ð‘•ð‘ð‘±ð‘•" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "ð‘®ð‘¦ð‘’ð‘¢ð‘§ð‘•ð‘‘ð‘©ð‘› ð‘•ð‘°ð‘’ ð‘šð‘¦ð‘“𑹠𑞠ð‘šð‘©ð‘œð‘¦ð‘¯ð‘¦ð‘™ ð‘ 𑞠ð‘•ð‘‘ð‘®ð‘°ð‘¥" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "ð‘®ð‘¦ð‘’ð‘¢ð‘§ð‘•ð‘‘ð‘©ð‘› ð‘•ð‘°ð‘’ ð‘šð‘¦ð‘˜ð‘ªð‘¯ð‘› 𑞠ð‘§ð‘¯ð‘› ð‘ 𑞠ð‘•ð‘‘ð‘®ð‘°ð‘¥" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "ð‘¥ð‘¬ð‘¯ð‘‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ \"ð‘³ð‘¯ð‘¥ð‘¬ð‘¯ð‘‘\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "ð‘¥ð‘¬ð‘¯ð‘‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ \"ð‘¦ð‘¡ð‘§ð‘’ð‘‘\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "ð‘¥ð‘¬ð‘¯ð‘‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ \"ð‘³ð‘¯ð‘¥ð‘¬ð‘¯ð‘‘\" 𑹠\"ð‘³ð‘¯ð‘¥ð‘¬ð‘¯ð‘‘_ð‘¢ð‘¦ð‘ž_ð‘ªð‘ð‘¼ð‘±ð‘–ð‘©ð‘¯\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "ð‘¥ð‘¬ð‘¯ð‘‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ \"ð‘¦ð‘¡ð‘§ð‘’ð‘‘\" 𑹠\"ð‘¦ð‘¡ð‘§ð‘’ð‘‘_ð‘¢ð‘¦ð‘ž_ð‘ªð‘ð‘¼ð‘±ð‘–ð‘©ð‘¯\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "ð‘¥ð‘¬ð‘¯ð‘‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ \"ð‘®ð‘°ð‘¥ð‘¬ð‘¯ð‘‘\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "ð‘¥ð‘¬ð‘¯ð‘‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘’ð‘ªð‘¯ð‘‘ð‘§ð‘¯ð‘‘ ð‘‘ð‘²ð‘ ð‘œð‘§ð‘•ð‘¦ð‘™" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "ð‘¥ð‘¬ð‘¯ð‘‘ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘•ð‘¦ð‘¯ð‘’ð‘®ð‘©ð‘¯ð‘©ð‘• ð‘’ð‘ªð‘¯ð‘‘ð‘§ð‘¯ð‘‘ ð‘‘ð‘²ð‘ ð‘œð‘§ð‘•ð‘¦ð‘™" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "ð‘£ð‘´ð‘•ð‘‘ð‘¯ð‘±ð‘¥ '%s' ð‘’ð‘©ð‘¯ð‘‘ð‘±ð‘¯ð‘Ÿ '[' ð‘šð‘³ð‘‘ ð‘¯ð‘ªð‘‘ ']'" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "ð‘¬ð‘‘ð‘ð‘«ð‘‘ ð‘•ð‘‘ð‘®ð‘°ð‘¥ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘®ð‘²ð‘‘" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "ð‘•ð‘¹ð‘• ð‘•ð‘‘ð‘®ð‘°ð‘¥ ð‘¦ð‘Ÿ ð‘·ð‘¤ð‘®ð‘§ð‘›ð‘¦ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gresolver.c:779 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘¦ð‘Ÿð‘ªð‘¤ð‘ð‘¦ð‘™ '%s': %s" + +#: ../gio/gresolver.c:829 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘ð‘»ð‘•-ð‘®ð‘¦ð‘Ÿð‘ªð‘¤ð‘ð‘¦ð‘™ '%s': %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "ð‘¯ð‘´ ð‘•ð‘»ð‘ð‘¦ð‘• ð‘®ð‘©ð‘’ð‘¹ð‘› ð‘“𑹠'%s'" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "ð‘‘ð‘§ð‘¥ð‘ð‘¼ð‘¼ð‘¦ð‘¤ð‘¦ ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘®ð‘¦ð‘Ÿð‘ªð‘¤ð‘ '%s'" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, c-format +msgid "Error resolving '%s'" +msgstr "ð‘»ð‘¼ ð‘®ð‘¦ð‘Ÿð‘ªð‘¤ð‘ð‘¦ð‘™ '%s'" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "ð‘œð‘§ð‘‘ 𑞠ð‘ð‘¨ð‘¤ð‘¿ ð‘ ð‘’ð‘°" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +#, fuzzy +msgid "SCHEMA[:PATH] KEY" +msgstr "ð‘•ð‘’ð‘°ð‘¥ð‘© ð‘’ð‘°" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +#, fuzzy +msgid "Set the value of KEY to VALUE" +msgstr "ð‘•ð‘§ð‘‘ 𑞠ð‘ð‘¨ð‘¤ð‘¿ ð‘ ð‘’ð‘°" + +#: ../gio/gsettings-tool.c:583 +#, fuzzy +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ð‘•ð‘’ð‘°ð‘¥ð‘© ð‘’ð‘° ð‘ð‘¨ð‘¤ð‘¿" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +#, fuzzy +msgid "Check if KEY is writable" +msgstr "ð‘“ð‘²ð‘¯ð‘› ð‘¬ð‘‘ ð‘¢ð‘§ð‘žð‘¼ ð‘’ð‘° ð‘¦ð‘Ÿ ð‘®ð‘²ð‘‘ð‘©ð‘šð‘©ð‘¤" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +#, fuzzy +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ð‘•ð‘’ð‘°ð‘¥ð‘© ð‘’ð‘°" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘› '%s'\n" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +#, fuzzy +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +"ð‘¸ð‘œð‘¿ð‘¥ð‘©ð‘¯ð‘‘ð‘•:\n" +" ð‘•ð‘’ð‘°ð‘¥ð‘© 𑞠ð‘¦ð‘› ð‘ 𑞠schema\n" +" ð‘’𑰠𑞠ð‘¯ð‘±ð‘¥ ð‘ 𑞠ð‘’ð‘°\n" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘•ð‘ªð‘’ð‘©ð‘‘, ð‘¯ð‘ªð‘‘ ð‘¦ð‘¯ð‘¦ð‘–ð‘©ð‘¤ð‘²ð‘Ÿð‘›" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘•ð‘ªð‘’ð‘©ð‘‘, ð‘¦ð‘¯ð‘¦ð‘‘ð‘¦ð‘©ð‘¤ð‘²ð‘Ÿð‘¨ð‘–ð‘©ð‘¯ ð‘“ð‘±ð‘¤ð‘› ð‘›ð‘¿ ð‘‘: %s" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "ð‘•ð‘ªð‘’ð‘©ð‘‘ ð‘¦ð‘Ÿ ð‘·ð‘¤ð‘®ð‘§ð‘›ð‘¦ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "ð‘•ð‘ªð‘’ð‘©ð‘‘ I/O ð‘‘ð‘²ð‘¥ð‘› ð‘¬ð‘‘" + +#: ../gio/gsocket.c:464 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ð‘’ð‘®ð‘¦ð‘±ð‘‘ð‘¦ð‘™ GSocket ð‘“ð‘®ð‘ªð‘¥ fd: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, c-format +msgid "Unable to create socket: %s" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘•ð‘ªð‘’ð‘©ð‘‘: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘ð‘®ð‘´ð‘‘ð‘©ð‘’ð‘ªð‘¤ ð‘¢ð‘ªð‘Ÿ ð‘•ð‘ð‘§ð‘•ð‘¦ð‘“ð‘²ð‘›" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "ð‘’ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘œð‘§ð‘‘ ð‘¤ð‘´ð‘’ð‘©ð‘¤ ð‘©ð‘›ð‘®ð‘§ð‘•: %s" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "ð‘’ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘œð‘§ð‘‘ ð‘®ð‘¦ð‘¥ð‘´ð‘‘ ð‘©ð‘›ð‘®ð‘§ð‘•: %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "ð‘’ð‘«ð‘› ð‘¯ð‘ªð‘‘ ð‘¤ð‘¦ð‘•ð‘©ð‘¯: %s" + +#: ../gio/gsocket.c:1446 +#, c-format +msgid "Error binding to address: %s" +msgstr "ð‘»ð‘¼ ð‘šð‘²ð‘¯ð‘›ð‘¦ð‘™ ð‘‘ ð‘©ð‘›ð‘®ð‘§ð‘•: %s" + +#: ../gio/gsocket.c:1566 +#, c-format +msgid "Error accepting connection: %s" +msgstr "ð‘»ð‘¼ ð‘¨ð‘’ð‘•ð‘§ð‘ð‘‘ð‘¦ð‘™ ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘–ð‘©ð‘¯: %s" + +#: ../gio/gsocket.c:1683 +msgid "Error connecting: " +msgstr "ð‘»ð‘¼ ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘‘ð‘¦ð‘™: " + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘–ð‘©ð‘¯ ð‘¦ð‘¯ ð‘ð‘®ð‘´ð‘œð‘®ð‘§ð‘•" + +#: ../gio/gsocket.c:1695 +#, c-format +msgid "Error connecting: %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘‘ð‘¦ð‘™: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘œð‘§ð‘‘ ð‘ð‘§ð‘¯ð‘›ð‘¦ð‘™ ð‘»ð‘¼: %s" + +#: ../gio/gsocket.c:1875 +#, c-format +msgid "Error receiving data: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘¦ð‘•ð‘°ð‘ð‘¦ð‘™ ð‘›ð‘±ð‘‘ð‘©: %s" + +#: ../gio/gsocket.c:2050 +#, c-format +msgid "Error sending data: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘¯ð‘›ð‘¦ð‘™ ð‘›ð‘±ð‘‘ð‘©: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ð‘³ð‘¯ð‘±ð‘šð‘©ð‘¤ ð‘‘ ð‘’ð‘®ð‘¦ð‘±ð‘‘ ð‘•ð‘ªð‘’ð‘©ð‘‘: %s" + +#: ../gio/gsocket.c:2242 +#, c-format +msgid "Error closing socket: %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘¤ð‘´ð‘Ÿð‘¦ð‘™ ð‘•ð‘ªð‘’ð‘©ð‘‘: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ð‘¢ð‘±ð‘‘ð‘¦ð‘™ ð‘“𑹠ð‘•ð‘ªð‘’ð‘©ð‘‘ ð‘’ð‘©ð‘¯ð‘›ð‘¦ð‘–ð‘©ð‘¯: %s" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, c-format +msgid "Error sending message: %s" +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘¯ð‘›ð‘¦ð‘™ ð‘¥ð‘§ð‘•ð‘¦ð‘¡: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "GSocketControlMessage ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘ªð‘¯ ·ð‘¢ð‘¦ð‘¯ð‘›ð‘´ð‘Ÿ" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, c-format +msgid "Error receiving message: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘¦ð‘•ð‘°ð‘ð‘¦ð‘™ ð‘¥ð‘§ð‘•ð‘¦ð‘¡: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "ð‘³ð‘¯ð‘´ð‘¯ ð‘»ð‘¼ ð‘ªð‘¯ ð‘’ð‘©ð‘¯ð‘§ð‘’ð‘‘" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "ð‘’ð‘° %s ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘®ð‘²ð‘‘ð‘©ð‘šð‘©ð‘¤\n" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "ð‘¤ð‘¦ð‘•ð‘©ð‘¯ð‘» ð‘¦ð‘Ÿ ð‘·ð‘¤ð‘®ð‘§ð‘›ð‘¦ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "ð‘¨ð‘›ð‘©ð‘› ð‘•ð‘ªð‘’ð‘©ð‘‘ ð‘¦ð‘Ÿ ð‘’ð‘¤ð‘´ð‘Ÿð‘›" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘£ð‘¨ð‘¯ð‘›ð‘©ð‘¤ ð‘ð‘»ð‘ ð‘©ð‘¯ %d ð‘ GThemedIcon ð‘§ð‘¯ð‘’ð‘´ð‘›ð‘¦ð‘™" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘™ 1 ð‘’ð‘©ð‘¯ð‘‘ð‘®ð‘´ð‘¤ ð‘¥ð‘§ð‘•ð‘¦ð‘¡, ð‘œð‘ªð‘‘ %d" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "ð‘³ð‘¯ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘©ð‘› ð‘‘ð‘²ð‘ ð‘ ð‘¨ð‘¯ð‘•ð‘©ð‘¤ð‘§ð‘®ð‘° ð‘›ð‘±ð‘‘ð‘©" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘™ ð‘¢ð‘³ð‘¯ fd, ð‘šð‘³ð‘‘ ð‘œð‘ªð‘‘ %d\n" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "ð‘®ð‘¦ð‘•ð‘°ð‘ð‘› ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› fd" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "ð‘»ð‘¼ ð‘•ð‘§ð‘¯ð‘›ð‘¦ð‘™ ð‘›ð‘±ð‘‘ð‘©: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘¯ð‘±ð‘¥ð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, fuzzy, c-format +msgid "Not expecting control message, but got %d" +msgstr "ð‘¦ð‘’ð‘•ð‘ð‘§ð‘’ð‘‘ð‘¦ð‘™ 1 ð‘’ð‘©ð‘¯ð‘‘ð‘®ð‘´ð‘¤ ð‘¥ð‘§ð‘•ð‘¦ð‘¡, ð‘œð‘ªð‘‘ %d" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘®ð‘ªð‘¥ ·ð‘¿ð‘¯ð‘¦ð‘’ð‘•: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘¤ð‘´ð‘Ÿð‘¦ð‘™ ·ð‘¿ð‘¯ð‘¦ð‘’ð‘•: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "ð‘“ð‘²ð‘¤ð‘•ð‘¦ð‘•ð‘‘ð‘©ð‘¥ ð‘®ð‘µð‘‘" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘²ð‘‘ð‘¦ð‘™ 𑑠·ð‘¿ð‘¯ð‘¦ð‘’ð‘•: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "ð‘¨ð‘šð‘•ð‘‘ð‘®ð‘¨ð‘’𑑠·ð‘¿ð‘¯ð‘¦ð‘’ð‘• ð‘›ð‘´ð‘¥ð‘±ð‘¯ ð‘•ð‘ªð‘’ð‘©ð‘‘ ð‘©ð‘›ð‘®ð‘§ð‘•ð‘©ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘ªð‘¯ ð‘žð‘¦ð‘• ð‘•ð‘¦ð‘•ð‘‘ð‘©ð‘¥" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "ð‘ð‘ªð‘¤ð‘¿ð‘¥ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘¦ð‘¡ð‘§ð‘’ð‘‘" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "ð‘ð‘ªð‘¤ð‘¿ð‘¥ ð‘›ð‘³ð‘Ÿð‘¯ð‘‘ ð‘¦ð‘¥ð‘ð‘¤ð‘§ð‘¥ð‘§ð‘¯ð‘‘ ð‘¦ð‘¡ð‘§ð‘’𑑠𑹠eject_with_operation" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘“ð‘²ð‘¯ð‘› ð‘©ð‘ð‘¤ð‘¦ð‘’ð‘±ð‘•ð‘©ð‘¯" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "ð‘»ð‘¼ ð‘¤ð‘·ð‘¯ð‘—ð‘¦ð‘™ ð‘©ð‘ð‘¤ð‘¦ð‘’ð‘±ð‘•ð‘©ð‘¯: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "URI𑟠ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘›" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "ð‘©ð‘•ð‘´ð‘•ð‘¦ð‘±ð‘–ð‘©ð‘¯ ð‘—ð‘±ð‘¯ð‘¡ð‘©ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘ªð‘¯ win32" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "ð‘©ð‘•ð‘´ð‘•ð‘¦ð‘±ð‘–ð‘©ð‘¯ ð‘’ð‘®ð‘°ð‘±ð‘–ð‘©ð‘¯ ð‘¯ð‘ªð‘‘ ð‘•ð‘©ð‘ð‘¹ð‘‘ð‘©ð‘› ð‘ªð‘¯ win32" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘°ð‘›ð‘¦ð‘™ ð‘“ð‘®ð‘ªð‘¥ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "ð‘»ð‘¼ ð‘’ð‘¤ð‘´ð‘Ÿð‘¦ð‘™ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "ð‘»ð‘¼ ð‘®ð‘²ð‘‘ð‘¦ð‘™ ð‘‘ ð‘“ð‘²ð‘¤: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "ð‘¯ð‘ªð‘‘ ð‘¦ð‘¯ð‘³ð‘“ ð‘¥ð‘§ð‘¥ð‘¼ð‘¦" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "ð‘¦ð‘¯ð‘‘ð‘»ð‘¯ð‘©ð‘¤ ð‘»ð‘¼: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "ð‘¯ð‘°ð‘› ð‘¥ð‘¹ ð‘¦ð‘¯ð‘ð‘«ð‘‘" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "ð‘¦ð‘¯ð‘ð‘¨ð‘¤ð‘¦ð‘› ð‘’ð‘ªð‘¥ð‘ð‘®ð‘§ð‘•ð‘‘ ð‘›ð‘±ð‘‘ð‘©" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "ð‘’ð‘¨ð‘¯ð‘‘ ð‘¥ð‘µð‘ ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦ ð‘´ð‘𑼠ð‘›ð‘²ð‘®ð‘§ð‘’ð‘‘ð‘¼ð‘¦" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘›ð‘Ÿ:\n" +#~ " help ð‘–ð‘´ ð‘žð‘¦ð‘• ð‘¦ð‘¯ð‘“ð‘¼ð‘¥ð‘±ð‘–ð‘©ð‘¯\n" +#~ " get ð‘œð‘§ð‘‘ 𑞠ð‘ð‘¨ð‘¤ð‘¿ ð‘ ð‘© ð‘’ð‘°\n" +#~ " set ð‘•ð‘§ð‘‘ 𑞠ð‘ð‘¨ð‘¤ð‘¿ ð‘ ð‘© ð‘’ð‘°\n" +#~ " monitor ð‘¥ð‘ªð‘¯ð‘¦ð‘‘𑼠𑩠ð‘’ð‘° ð‘“𑹠ð‘—ð‘±ð‘¯ð‘¡ð‘©ð‘Ÿ\n" +#~ " writable ð‘—ð‘§ð‘’ ð‘¦ð‘“ ð‘© ð‘’ð‘° ð‘¦ð‘Ÿ ð‘®ð‘²ð‘‘ð‘©ð‘šð‘©ð‘¤\n" +#~ "\n" +#~ "ð‘¿ð‘Ÿ '%s ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘› --help' ð‘‘ ð‘œð‘§ð‘‘ ð‘£ð‘§ð‘¤ð‘ ð‘“𑹠ð‘¦ð‘¯ð‘›ð‘¦ð‘ð‘¦ð‘›ð‘¿ð‘©ð‘¤ ð‘’ð‘©ð‘¥ð‘­ð‘¯ð‘›ð‘Ÿ.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "ð‘•ð‘ð‘§ð‘•ð‘¦ð‘“𑲠𑞠ð‘ð‘­ð‘” ð‘“𑹠𑞠ð‘•ð‘’ð‘°ð‘¥ð‘©" + +#~ msgid "PATH" +#~ msgstr "ð‘ð‘­ð‘”" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "ð‘¸ð‘œð‘¿ð‘¥ð‘©ð‘¯ð‘‘ð‘•:\n" +#~ " ð‘•ð‘’ð‘°ð‘¥ð‘© 𑞠ð‘¦ð‘› ð‘ 𑞠schema\n" +#~ " ð‘’𑰠𑞠ð‘¯ð‘±ð‘¥ ð‘ 𑞠ð‘’ð‘°\n" +#~ " ð‘ð‘¨ð‘¤ð‘¿ 𑞠ð‘ð‘¨ð‘¤ð‘¿ ð‘‘ ð‘•ð‘§ð‘‘ ð‘’ð‘° ð‘‘, ð‘¨ð‘Ÿ ð‘© ð‘•ð‘¦ð‘®ð‘°ð‘©ð‘¤ð‘²ð‘Ÿð‘› GVariant\n" + +#~ msgid "Key %s is not writable\n" +#~ msgstr "ð‘’ð‘° %s ð‘¦ð‘Ÿ ð‘¯ð‘ªð‘‘ ð‘®ð‘²ð‘‘ð‘©ð‘šð‘©ð‘¤\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "ð‘¥ð‘ªð‘¯ð‘¦ð‘‘𑼠ð‘’ð‘° ð‘“𑹠ð‘—ð‘±ð‘¯ð‘¡ð‘©ð‘Ÿ 𑯠ð‘ð‘®ð‘¦ð‘¯ð‘‘ 𑞠ð‘—ð‘±ð‘¯ð‘¡ð‘› ð‘ð‘¨ð‘¤ð‘¿ð‘Ÿ.\n" +#~ "ð‘¥ð‘­ð‘¯ð‘©ð‘‘ð‘»ð‘¦ð‘™ ð‘¢ð‘¦ð‘¤ ð‘’ð‘©ð‘¯ð‘‘ð‘¦ð‘¯ð‘¿ ð‘³ð‘¯ð‘‘ð‘¦ð‘¤ 𑞠ð‘ð‘®ð‘´ð‘•ð‘§ð‘• ð‘¦ð‘Ÿ ð‘‘ð‘»ð‘¥ð‘©ð‘¯ð‘±ð‘‘ð‘©ð‘›." diff --git a/po/en_CA.po b/po/en_CA.po new file mode 100644 index 0000000..18525fb --- /dev/null +++ b/po/en_CA.po @@ -0,0 +1,4018 @@ +# English/Canada translation of glib. +# Copyright (C) 2004-2005 Adam Weinberger +# This file is distributed under the same licence as the glib package. +# Adam Weinberger , 2004, 2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2005-08-27 16:20-0400\n" +"Last-Translator: Ryan Lortie \n" +"Language-Team: Canadian English \n" +"Language: en_CA\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" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Unexpected attribute '%s' for element '%s'" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Attribute '%s' of element '%s' not found" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Unexpected tag '%s'; tag '%s' expected" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Unexpected tag '%s' inside '%s'" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "No valid bookmark file found in data dirs" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "A bookmark for URI '%s' already exists" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "No bookmark found for URI '%s'" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "No MIME type defined in the bookmark for URI '%s'" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "No private flag has been defined in bookmark for URI '%s'" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "No groups set in bookmark for URI '%s'" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "No application with name '%s' registered a bookmark for '%s'" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Failed to expand exec line '%s' with URI '%s'" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Conversion from character set '%s' to '%s' is not supported" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Could not open converter from '%s' to '%s'" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Invalid byte sequence in conversion input" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Error during conversion: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Partial character sequence at end of input" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Cannot convert fallback '%s' to codeset '%s'" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "The URI '%s' is not an absolute URI using the \"file\" scheme" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "The local file URI '%s' may not include a '#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "The URI '%s' is invalid" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "The hostname of the URI '%s' is invalid" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "The URI '%s' contains invalidly escaped characters" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "The pathname '%s' is not an absolute path" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Invalid hostname" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %r %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%F" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%r" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "January" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "February" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "March" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "May" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "June" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "July" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "August" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "October" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "December" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "May" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Oct" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Monday" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Tuesday" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Wednesday" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Thursday" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Friday" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Saturday" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Sunday" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Mon" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Tue" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Wed" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Thu" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Fri" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sat" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Sun" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Error opening directory '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Could not allocate %lu bytes to read file \"%s\"" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Error reading file '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "File \"%s\" is too large" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Failed to read from file '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Failed to open file '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Failed to get attributes of file '%s': fstat() failed: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Failed to open file '%s': fdopen() failed: %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Failed to rename file '%s' to '%s': g_rename() failed: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Failed to create file '%s': %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Failed to open file '%s' for writing: fdopen() failed: %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Failed to write file '%s': fwrite() failed: %s" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Failed to write file '%s': fflush() failed: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Failed to write file '%s': fsync() failed: %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Failed to close file '%s': fclose() failed: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "Existing file '%s' could not be removed: g_unlink() failed: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Template '%s' invalid, should not contain a '%s'" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Template '%s' does not contain XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Failed to read the symbolic link '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Symbolic links not supported" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Could not open converter from '%s' to '%s': %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Can't do a raw read in g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Leftover unconverted data in read buffer" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Channel terminates in a partial character" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Cannot do a raw read in g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Failed to open file '%s': open() failed: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Failed to map file '%s': mmap() failed: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Error on line %d char %d: " + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Invalid UTF-8 encoded text in name - not valid '%s'" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "'%s' is not a valid name " + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "'%s' is not a valid name: '%c' " + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Error on line %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Character reference '%-.*s' does not encode a permitted character" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Empty entity '&;' seen; valid entities are: & " < > '" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Entity name '%-.*s' is not known" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Document must begin with an element (e.g. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' is not a valid character following the close element name '%s'; the " +"allowed character is '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Element '%s' was closed, no element is currently open" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Element '%s' was closed, but the currently open element is '%s'" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Document was empty or contained only whitespace" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Document ended unexpectedly just after an open angle bracket '<'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Document ended unexpectedly inside an element name" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Document ended unexpectedly inside an attribute name" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Document ended unexpectedly inside an element-opening tag." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Document ended unexpectedly while inside an attribute value" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Document ended unexpectedly inside the close tag for element '%s'" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Document ended unexpectedly inside a comment or processing instruction" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "corrupted object" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "internal error or corrupted object" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "out of memory" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "backtracking limit reached" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "the pattern contains items not supported for partial matching" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "internal error" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "back references as conditions are not supported for partial matching" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "recursion limit reached" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "workspace limit for empty substrings reached" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "invalid combination of newline flags" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "bad offset" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "short utf8" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "unknown error" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ at end of pattern" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c at end of pattern" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "unrecognized character follows \\" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "numbers out of order in {} quantifier" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "number too big in {} quantifier" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "missing terminating ] for character class" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "invalid escape sequence in character class" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "range out of order in character class" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "nothing to repeat" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "unrecognized character after (?" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "unrecognized character after (?<" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "unrecognized character after (?P" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX named classes are supported only within a class" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "missing terminating )" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") without opening (" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R or (?[+-]digits must be followed by )" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "reference to non-existent subpattern" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "missing ) after comment" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "regular expression too large" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "failed to get memory" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind assertion is not fixed length" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "malformed number or name after (?(" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "conditional group contains more than two branches" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "assertion expected after (?(" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "unknown POSIX class name" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "POSIX collating elements are not supported" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "character value in \\x{...} sequence is too large" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "invalid condition (?(0)" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C not allowed in lookbehind assertion" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "recursive call could loop indefinitely" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "missing terminator in subpattern name" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "two named subpatterns have the same name" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "malformed \\P or \\p sequence" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "unknown property name after \\P or \\p" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "subpattern name is too long (maximum 32 characters)" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "too many named subpatterns (maximum 10,000)" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "octal value is greater than \\377" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE group contains more than one branch" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "repeating a DEFINE group is not allowed" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "inconsistent NEWLINE options" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" +"\\g is not followed by a braced name or an optionally braced non-zero number" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "unexpected repeat" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "code overflow" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "overran compiling workspace" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "previously-checked referenced subpattern not found" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Error while matching regular expression %s: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE library is compiled without UTF8 support" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE library is compiled without UTF8 properties support" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Error while compiling regular expression %s at char %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Error while optimizing regular expression %s: %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "hexadecimal digit or '}' expected" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "hexadecimal digit expected" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "missing '<' in symbolic reference" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "unfinished symbolic reference" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "zero-length symbolic reference" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "digit expected" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "illegal symbolic reference" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "stray final '\\'" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "unknown escape sequence" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "Error while parsing replacement text \"%s\" at char %lu: %s" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Quoted text does not begin with a quotation mark" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Unmatched quotation mark in command line or other shell-quoted text" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Text ended just after a '\\' character. (The text was '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "Text ended before matching quote was found for %c. (The text was '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Text was empty (or contained only whitespace)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Failed to read data from child process" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Failed to create pipe for communicating with child process (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Failed to read from child pipe (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Failed to change to directory '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Failed to execute child process (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Invalid program name: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Invalid string in argument vector at %d: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Invalid string in environment: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Invalid working directory: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Failed to execute helper program (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Failed to read data from child process (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Unexpected error in select() reading data from a child process (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Unexpected error in waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Failed to fork (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Failed to execute child process \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Failed to redirect output or input of child process (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Failed to fork child process (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Unknown error executing child process \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Failed to read enough data from child pid pipe (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Character out of range for UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Invalid sequence in conversion input" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Character out of range for UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Usage:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Help Options:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Show help options" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Show all help options" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Application Options:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Cannot parse integer value '%s' for %s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Integer value '%s' for %s out of range" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Cannot parse double value '%s' for %s" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Double value '%s' for %s out of range" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Error parsing option %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Missing argument for %s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Unknown option %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "Valid key file could not be found in search dirs" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Not a regular file" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "File is empty" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Invalid group name: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Key file does not start with a group" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Invalid key name: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Key file contains unsupported encoding '%s'" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Key file does not have group '%s'" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Key file does not have key '%s'" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "Key file contains key '%s' with value '%s' which is not UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "Key file contains key '%s' which has value that cannot be interpreted." + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"Key file contains key '%s' which has a value that cannot be interpreted." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Key file does not have key '%s' in group '%s'" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Key file contains escape character at end of line" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Key file contains invalid escape sequence '%s'" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Value '%s' cannot be interpreted as a number." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Integer value '%s' out of range" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Value '%s' cannot be interpreted as a float number." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Value '%s' cannot be interpreted as a boolean." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Too large count value passed to %s" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "Stream is already closed" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "Operation was cancelled" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "Invalid object, not initialized" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "Incomplete multibyte sequence in input" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "Not enough space in destination" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "Cancellable initialization not supported" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Unknown type" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s filetype" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s type" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials is not implemented on this OS" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "There is no GCredentials support for your platform" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "Unexpected early end-of-stream" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "Unsupported key '%s' in address entry '%s'" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "Meaningless key/value pair combination in address entry '%s'" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "Error in address '%s' - the port attribute is malformed" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "Error in address '%s' - the family attribute is malformed" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "Address element '%s', does not contain a colon (:)" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "Error in address '%s' - the host attribute is missing or malformed" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "Error in address '%s' - the port attribute is missing or malformed" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" +"Error in address '%s' - the noncefile attribute is missing or malformed" + +#: ../gio/gdbusaddress.c:644 +msgid "Error auto-launching: " +msgstr "Error auto-launching: " + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "Unknown or unsupported transport '%s' for address '%s'" + +#: ../gio/gdbusaddress.c:688 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Error opening nonce file '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Error reading from nonce file '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Error reading from nonce file '%s', expected 16 bytes, got %d" + +#: ../gio/gdbusaddress.c:733 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Error writing contents of nonce file '%s' to stream:" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "The given address is empty" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Cannot spawn a message bus without a machine-id: " + +#: ../gio/gdbusaddress.c:1057 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "Error spawning command line '%s': " + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "Abnormal program termination spawning command line '%s': %s" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "Command line '%s' exited with non-zero exit status %d: %s" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "Cannot determine session bus address (not implemented for this OS)" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" + +#: ../gio/gdbusaddress.c:1273 +#, c-format +msgid "Unknown bus type %d" +msgstr "Unknown bus type %d" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "Unexpected lack of content trying to read a line" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Unexpected lack of content trying to (safely) read a line" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, c-format +msgid "Error statting directory '%s': %s" +msgstr "Error statting directory '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "Error creating directory '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Error opening keyring '%s' for reading: " + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "Line %d of the keyring at '%s' with content '%s' is malformed" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "Didn't find cookie with id %d in the keyring at '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Error deleting stale lock file '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Error creating lock file '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Error closing (unlinked) lock file '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Error unlinking lock file '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Error opening keyring '%s' for writing: " + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(Additionally, releasing the lock for '%s' also failed: %s) " + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "The connection is closed" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "Timeout was reached" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Unsupported flags encountered when constructing a client-side connection" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "Error setting property '%s': Expected type '%s' but got '%s'" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "No such property '%s'" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "Property '%s' is not readable" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "Property '%s' is not writable" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "No such interface '%s'" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "No such interface" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "No such interface '%s' on object at path %s" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "No such method '%s'" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "Type of message, '%s', does not match expected type '%s'" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "An object is already exported for the interface %s at %s" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "Method '%s' returned type '%s', but expected '%s'" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "Method '%s' on interface '%s' with signature '%s' does not exist" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "A subtree is already exported for %s" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "type is INVALID" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL message: PATH or MEMBER header field is missing" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN message: REPLY_SERIAL header field is missing" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "Wanted to read %lu byte but got EOF" +msgstr[1] "Wanted to read %lu bytes but got EOF" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "Expected NUL byte after the string '%s' but found byte %d" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "Parsed value '%s' is not a valid D-Bus object path" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "Parsed value '%s' is not a valid D-Bus signature" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[1] "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "Parsed value '%s' for variant is not a valid D-Bus signature" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Invalid major protocol version. Expected 1 but found %d" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "Signature header with signature '%s' found but message body is empty" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "Parsed value '%s' is not a valid D-Bus signature (for body)" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "No signature header in message but the message body is %u byte" +msgstr[1] "No signature header in message but the message body is %u bytes" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "Cannot deserialize message: " + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "Cannot serialize message: " + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "Message body has signature '%s' but there is no signature header" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "Message body is empty but signature in the header field is '(%s)'" + +#: ../gio/gdbusmessage.c:2938 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "Error return with body of type '%s'" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "Error return with empty body" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "Unable to load /var/lib/dbus/machine-id: " + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Error calling StartServiceByName for %s: " + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Unexpected reply %d from StartServiceByName(\"%s\") method" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" + +#: ../gio/gdbusserver.c:711 +msgid "Abstract name space not supported" +msgstr "Abstract name space not supported" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "Cannot specify nonce file when creating a server" + +#: ../gio/gdbusserver.c:875 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Error writing nonce file at '%s': %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "The string '%s' is not a valid D-Bus GUID" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "Cannot listen on unsupported transport '%s'" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, c-format +msgid "Error: %s\n" +msgstr "Error: %s\n" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Error parsing introspection XML: %s\n" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "Connect to the system bus" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "Connect to the session bus" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "Connect to given D-Bus address" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "Connection Endpoint Options:" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "Options specifying the connection endpoint" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "No connection endpoint specified" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Multiple connection endpoints specified" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" +"Warning: According to introspection data, interface '%s' does not exist\n" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "Optional destination for signal (unique name)" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "Object path to emit signal on" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "Signal and interface name" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "Emit a signal." + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Error connecting: %s\n" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "Error: object path not specified.\n" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Error: %s is not a valid object path\n" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "Error: signal not specified.\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Error: %s is not a valid interface name\n" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Error: %s is not a valid member name\n" + +#: ../gio/gdbus-tool.c:646 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Error: %s is not a valid unique bus name.\n" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Error parsing parameter %d: %s\n" + +#: ../gio/gdbus-tool.c:698 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Error flushing connection: %s\n" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "Destination name to invoke method on" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "Object path to invoke method on" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "Method and interface name" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "Timeout in seconds" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "Invoke a method on a remote object." + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "Error: Destination is not specified\n" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "Error: Object path is not specified\n" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "Error: Method name is not specified\n" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "Error: Method name '%s' is invalid\n" + +#: ../gio/gdbus-tool.c:974 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Error parsing parameter %d of type '%s': %s\n" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "Destination name to introspect" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "Object path to introspect" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "Print XML" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "Introspect children" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "Only print properties" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "Introspect a remote object." + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "Destination name to monitor" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "Object path to monitor" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "Monitor a remote object." + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Unnamed" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "Desktop file didn't specify Exec field" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "Unable to find terminal required for application" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "Can't create user application configuration folder %s: %s" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "Can't create user MIME configuration folder %s: %s" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "Application information lacks an identifier" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Can't create user desktop file %s" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "Custom definition for %s" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "drive doesn't implement eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "drive doesn't implement eject or eject_with_operation" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "drive doesn't implement polling for media" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "drive doesn't implement start" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "drive doesn't implement stop" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "TLS support is not available" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "Can't handle version %d of GEmblem encoding" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Malformed number of tokens (%d) in GEmblem encoding" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "Can't handle version %d of GEmblemedIcon encoding" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Malformed number of tokens (%d) in GEmblemedIcon encoding" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Expected a GEmblem for GEmblemedIcon" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Operation not supported" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "Containing mount does not exist" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "Can't copy over directory" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "Can't copy directory over directory" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "Target file exists" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "Can't recursively copy directory" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "Splice not supported" + +#: ../gio/gfile.c:2762 +#, c-format +msgid "Error splicing file: %s" +msgstr "Error splicing file: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "Can't copy special file" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "Invalid symlink value given" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "Trash not supported" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "File names cannot contain '%c'" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "volume doesn't implement mount" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "No application is registered as handling this file" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "Enumerator is closed" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "File enumerator has outstanding operation" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "File enumerator is already closed" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "Can't handle version %d of GFileIcon encoding" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Malformed input data for GFileIcon" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "Stream doesn't support query_info" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "Seek not supported on stream" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "Truncate not allowed on input stream" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "Truncate not supported on stream" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Wrong number of tokens (%d)" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "No type for class name %s" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Type %s does not implement the GIcon interface" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "Type %s is not classed" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "Malformed version number: %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Type %s does not implement from_tokens() on the GIcon interface" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "Can't handle the supplied version the icon encoding" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "Input stream doesn't implement read" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "Stream has outstanding operation" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "Not enough space for socket address" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "Unsupported socket address" + +#: ../gio/glib-compile-schemas.c:741 +msgid "empty names are not permitted" +msgstr "empty names are not permitted" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "invalid name '%s': names must begin with a lowercase letter" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "invalid name '%s': two successive dashes ('--') are not permitted." + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "invalid name '%s': the last character may not be a dash ('-')." + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "invalid name '%s': maximum length is 1024" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "can not add keys to a 'list-of' schema" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" shadows in ; use " +"to modify value" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> not (yet) defined." + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "invalid GVariant type string '%s'" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr " given but schema isn't extending anything" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "no to override" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " extends not yet existing schema '%s'" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " is list of not yet existing schema '%s'" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "Can not be a list of a schema with a path" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "Can not extend a schema with a path" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" is a list, extending which is not a list" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" extends but '%s' " +"does not extend '%s'" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "a path, if given, must begin and end with a slash" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "the path of a list must end with ':/'" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> already specified" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> not allowed inside <%s>" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> not allowed at toplevel" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "text may not appear inside <%s>" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict was specified; exiting.\n" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "This entire file has been ignored.\n" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Ignoring this file.\n" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "No such key '%s' in schema '%s' as specified in override file '%s'" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; ignoring override for this key.\n" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " and --strict was specified; exiting.\n" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "Ignoring override for this key.\n" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "where to store the gschemas.compiled file" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "Abort on any errors in schemas" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "Do not write the gschema.compiled file" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "This option will be removed soon." + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "Do not enforce key name restrictions" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "You should give exactly one directory name\n" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "No schema files found: " + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "doing nothing.\n" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "removed existing output file.\n" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "Unable to find default local directory monitor type" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Invalid filename %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Error getting filesystem info: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "Can't rename root directory" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Error renaming file: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "Can't rename file, filename already exists" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Invalid filename" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Error opening file: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "Can't open directory" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Error removing file: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "Error trashing file: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Unable to create trash dir %s: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "Unable to find toplevel directory for trash" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "Unable to find or create trash directory" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Unable to create trashing info file: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Unable to trash file: %s" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "Error creating directory: %s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Filesystem does not support symbolic links" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Error making symbolic link: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Error moving file: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "Can't move directory over directory" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "Backup file creation failed" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "Error removing target file: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "Move between mounts not supported" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "Attribute value must be non-NULL" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "Invalid attribute type (string expected)" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "Invalid extended attribute name" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Error setting extended attribute '%s': %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "Error stating file '%s': %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (invalid encoding)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "Error stating file descriptor: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Invalid attribute type (uint32 expected)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Invalid attribute type (uint64 expected)" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "Invalid attribute type (byte string expected)" + +#: ../gio/glocalfileinfo.c:1904 +msgid "Cannot set permissions on symlinks" +msgstr "Cannot set permissions on symlinks" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Error setting permissions: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "Error setting owner: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "symlink must be non-NULL" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Error setting symlink: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "Error setting symlink: file is not a symlink" + +#: ../gio/glocalfileinfo.c:2139 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Error setting modification or access time: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "SELinux context must be non-NULL" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Error setting SELinux context: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "SELinux is not enabled on this system" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Setting attribute %s not supported" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Error reading from file: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Error seeking in file: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Error closing file: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "Unable to find default local file monitor type" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Error writing to file: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Error removing old backup link: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Error creating backup copy: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Error renaming temporary file: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "Error truncating file: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Error opening file '%s': %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "Target file is a directory" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "Target file is not a regular file" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "The file was externally modified" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "Error removing old file: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "Invalid GSeekType supplied" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Invalid seek request" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Cannot truncate GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "Memory output stream not resizable" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "Failed to resize memory output stream" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Amount of memory required to process the write is larger than available " +"address space" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "Requested seek before the beginning of the stream" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "Requested seek beyond the end of the stream" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "mount doesn't implement \"unmount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "mount doesn't implement \"eject\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "mount doesn't implement \"eject\" or \"eject_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "mount doesn't implement \"remount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "mount doesn't implement content type guessing" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "mount doesn't implement synchronous content type guessing" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "Hostname '%s' contains '[' but not ']'" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "Output stream doesn't implement write" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "Source stream is already closed" + +#: ../gio/gresolver.c:779 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "Error resolving '%s': %s" + +#: ../gio/gresolver.c:829 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Error reverse-resolving '%s': %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "No service record for '%s'" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "Temporarily unable to resolve '%s'" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, c-format +msgid "Error resolving '%s'" +msgstr "Error resolving '%s'" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "Schema '%s' is not relocatable (path must not be specified)\n" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "No such schema '%s'\n" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "Schema '%s' is relocatable (path must be specified)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "Empty path given.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "Path must begin with a slash (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "Path must end with a slash (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Path must not contain two adjacent slashes (//)\n" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "No such key '%s'\n" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "The provided value is outside of the valid range\n" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "Print help" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "List the installed (non-relocatable) schemas" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "List the installed relocatable schemas" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "List the keys in SCHEMA" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "List the children of SCHEMA" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "Get the value of KEY" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "Query the range of valid values for KEY" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "Set the value of KEY to VALUE" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "Reset KEY to its default value" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Reset all keys in SCHEMA to their defaults" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "Check if KEY is writable" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:613 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Unknown command %s\n" +"\n" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "Arguments:\n" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND The (optional) command to explain\n" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY The (optional) key within the schema\n" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr " KEY The key within the schema\n" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr " VALUE The value to set\n" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "Empty schema name given\n" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "Invalid socket, not initialized" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Invalid socket, initialization failed due to: %s" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "Socket is already closed" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "Socket I/O timed out" + +#: ../gio/gsocket.c:464 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "creating GSocket from fd: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Unable to create socket: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "Unknown protocol was specified" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "could not get local address: %s" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "could not get remote address: %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "could not listen: %s" + +#: ../gio/gsocket.c:1446 +#, c-format +msgid "Error binding to address: %s" +msgstr "Error binding to address: %s" + +#: ../gio/gsocket.c:1566 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Error accepting connection: %s" + +#: ../gio/gsocket.c:1683 +msgid "Error connecting: " +msgstr "Error connecting: " + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "Connection in progress" + +#: ../gio/gsocket.c:1695 +#, c-format +msgid "Error connecting: %s" +msgstr "Error connecting: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "Unable to get pending error: %s" + +#: ../gio/gsocket.c:1875 +#, c-format +msgid "Error receiving data: %s" +msgstr "Error receiving data: %s" + +#: ../gio/gsocket.c:2050 +#, c-format +msgid "Error sending data: %s" +msgstr "Error sending data: %s" + +#: ../gio/gsocket.c:2163 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Unable to shutdown socket: %s" + +#: ../gio/gsocket.c:2242 +#, c-format +msgid "Error closing socket: %s" +msgstr "Error closing socket: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Waiting for socket condition: %s" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, c-format +msgid "Error sending message: %s" +msgstr "Error sending message: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "GSocketControlMessage not supported on windows" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, c-format +msgid "Error receiving message: %s" +msgstr "Error receiving message: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials not implemented for this OS" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "Unknown error on connect" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "Trying to proxy over non-TCP connection is not supported." + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Proxy protocol '%s' is not supported." + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "Listener is already closed" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "Added socket is closed" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 does not support IPv6 address '%s'" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "SOCKSv4 implementation limits username to %i characters" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "SOCKSv4a implementation limits hostname to %i characters" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "The server is not a SOCKSv4 proxy server." + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Connection through SOCKSv4 server was rejected" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "The server is not a SOCKSv5 proxy server." + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "The SOCKSv5 proxy requires authentication." + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "Username or password is too long for SOCKSv5 protocol (max. is %i)." + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 authentication failed due to wrong username or password." + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "The SOCKSv5 proxy server uses unknown address type." + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Internal SOCKSv5 proxy server error." + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 connection not allowed by ruleset." + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Host unreachable through SOCKSv5 server." + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Network unreachable through SOCKSv5 proxy." + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Connection refused through SOCKSv5 proxy." + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 proxy does not support 'connect' command." + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 proxy does not support provided address type." + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Unknown SOCKSv5 proxy error." + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "Can't handle version %d of GThemedIcon encoding" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "No PEM-encoded private key found" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "Could not parse PEM-encoded private key" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "No PEM-encoded certificate found" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "Could not parse PEM-encoded certificate" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"This is the last chance to enter the password correctly before your access " +"is locked out." + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "The password entered is incorrect." + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "Expecting 1 control message, got %d" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "Unexpected type of ancillary data" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "Expecting one fd, but got %d\n" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "Received invalid fd" + +#: ../gio/gunixconnection.c:371 +msgid "Error sending credentials: " +msgstr "Error sending credentials: " + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Error checking if SO_PASSCRED is enabled for socket: %s" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" + +#: ../gio/gunixconnection.c:478 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Error enabling SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Expecting to read a single byte for receiving credentials but read zero bytes" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Not expecting control message, but got %d" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Error while disabling SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "Error reading from UNIX: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "Error closing UNIX: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "Filesystem root" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "Error writing to UNIX: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "Abstract unix domain socket addresses not supported on this system" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "volume doesn't implement eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "volume doesn't implement eject or eject_with_operation" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "Can't find application" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "Error launching application: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "URIs not supported" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "association changes not supported on win32" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "Association creation not supported on win32" + +#: ../gio/gwin32inputstream.c:318 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Error reading from handle: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, c-format +msgid "Error closing handle: %s" +msgstr "Error closing handle: %s" + +#: ../gio/gwin32outputstream.c:318 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Error writing to handle: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "Not enough memory" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "Internal error: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "Need more input" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "Invalid compressed data" + +msgctxt "full month name with day" +msgid "January" +msgstr "January" + +msgctxt "full month name with day" +msgid "February" +msgstr "February" + +msgctxt "full month name with day" +msgid "March" +msgstr "March" + +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +msgctxt "full month name with day" +msgid "May" +msgstr "May" + +msgctxt "full month name with day" +msgid "June" +msgstr "June" + +msgctxt "full month name with day" +msgid "July" +msgstr "July" + +msgctxt "full month name with day" +msgid "August" +msgstr "August" + +msgctxt "full month name with day" +msgid "September" +msgstr "September" + +msgctxt "full month name with day" +msgid "October" +msgstr "October" + +msgctxt "full month name with day" +msgid "November" +msgstr "November" + +msgctxt "full month name with day" +msgid "December" +msgstr "December" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "May" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Aug" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Oct" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dec" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Can't move directory over directory" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Invalid sequence in conversion input" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "Reached maximum data array limit" + +#~ msgid "do not hide entries" +#~ msgstr "do not hide entries" + +#~ msgid "use a long listing format" +#~ msgstr "use a long listing format" + +#~ msgid "[FILE...]" +#~ msgstr "[FILE...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand is not supposed to be an " +#~ "entity, escape it as &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Empty character reference; should include a digit such as dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Unfinished entity reference" + +#~ msgid "Unfinished character reference" +#~ msgstr "Unfinished character reference" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Invalid UTF-8 encoded text - overlong sequence" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Invalid UTF-8 encoded text - not a start char" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "An array containing the icon names" + +#~ msgid "The name of the icon" +#~ msgstr "The name of the icon" + +#~ msgid "names" +#~ msgstr "names" + +#~ msgid "An array containing the icon names" +#~ msgstr "An array containing the icon names" + +#~ msgid "use default fallbacks" +#~ msgstr "use default fallbacks" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Error stating file descriptor: %s" diff --git a/po/en_GB.po b/po/en_GB.po new file mode 100644 index 0000000..95c45ba --- /dev/null +++ b/po/en_GB.po @@ -0,0 +1,6605 @@ +# English (British) translation. +# Copyright (C) 2004 glib's COPYRIGHT HOLDER +# This file is distributed under the same licence as the GLIB package. +# Gareth Owen 2004 +# Philip Withnall , 2010. +# Zander Brown , 2019-2021. +# Bruce Cowan , 2009-2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-08 12:19+0000\n" +"PO-Revision-Date: 2022-04-24 11:26+0100\n" +"Last-Translator: Bruce Cowan \n" +"Language-Team: English - United Kingdom \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Gtranslator 42.0\n" +"X-Project-Style: gnome\n" +"X-DL-Team: en_GB\n" +"X-DL-Module: glib\n" +"X-DL-Branch: glib-2-68\n" +"X-DL-Domain: po\n" +"X-DL-State: Translating\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Setting default applications not supported yet" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "Setting application as last used for type not supported yet" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication options" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Show GApplication options" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Enter GApplication service mode (use from D-Bus service files)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Override the application’s ID" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Replace the running instance" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Print help" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Print version" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Print version information and exit" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "List applications" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "List the installed D-Bus activatable applications (by .desktop files)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Launch an application" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Launch the application (with optional files to open)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FILE…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Activate an action" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invoke an action on the application" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "List available actions" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "List static actions for an application (from .desktop file)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMMAND" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "The command to print detailed help for" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Application identifier in D-Bus format (eg: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FILE" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Optional relative or absolute filenames, or URIs to open" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACTION" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "The action name to invoke" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Optional parameter to the action invocation, in GVariant format" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Unknown command %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Usage:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Arguments:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Commands:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s command requires an application id to directly follow\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "invalid application id: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†takes no arguments\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "unable to connect to D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "error sending %s message to application: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "action name must be given after application id\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "error parsing action parameter: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "actions accept a maximum of one parameter\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions command takes only the application id" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "unable to find desktop file for application %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"unrecognised command: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Too large count value passed to %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Seek not supported on base stream" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Cannot truncate GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Stream is already closed" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Truncate not supported on base stream" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operation was cancelled" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Invalid object, not initialised" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Incomplete multibyte sequence in input" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Not enough space in destination" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Invalid byte sequence in conversion input" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Error during conversion: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Cancellable initialisation not supported" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Conversion from character set “%s†to “%s†is not supported" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Could not open converter from “%s†to “%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s type" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Unknown type" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s filetype" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials contains invalid data" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials is not implemented on this OS" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "There is no GCredentials support for your platform" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials does not contain a process ID on this OS" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Credentials spoofing is not possible on this OS" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Unexpected early end-of-stream" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Unsupported key “%s†in address entry “%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Meaningless key/value pair combination in address entry “%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Error in address “%s†— the “%s†attribute is malformed" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Unknown or unsupported transport “%s†for address “%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Address element “%s†does not contain a colon (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Transport name in address element “%s†must not be empty" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Error in address “%s†— the host attribute is missing or malformed" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Error in address “%s†— the port attribute is missing or malformed" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Error in address “%s†— the noncefile attribute is missing or malformed" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Error auto-launching: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Error opening nonce file “%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Error reading from nonce file “%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Error writing contents of nonce file “%s†to stream:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "The given address is empty" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Cannot spawn a message bus when AT_SECURE is set" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Cannot spawn a message bus without a machine-id: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Cannot autolaunch D-Bus without X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Error spawning command line “%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "Cannot determine session bus address (not implemented for this OS)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Unknown bus type %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Unexpected lack of content trying to read a line" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Unexpected lack of content trying to (safely) read a line" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "User IDs must be the same for peer and server" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Error when getting information for directory “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Error creating directory “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operation not supported" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Error opening keyring “%s†for reading: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Line %d of the keyring at “%s†with content “%s†is malformed" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Didn’t find cookie with id %d in the keyring at “%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Error creating lock file “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Error deleting stale lock file “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Error closing (unlinked) lock file “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Error unlinking lock file “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Error opening keyring “%s†for writing: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Additionally, releasing the lock for “%s†also failed: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "The connection is closed" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Timeout was reached" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Unsupported flags encountered when constructing a client-side connection" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "No such property “%sâ€" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Property “%s†is not readable" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Property “%s†is not writable" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "No such interface “%sâ€" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "No such interface “%s†on object at path %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "No such method “%sâ€" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Type of message, “%sâ€, does not match expected type “%sâ€" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "An object is already exported for the interface %s at %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Unable to retrieve property %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Unable to set property %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Method “%s†returned type “%sâ€, but expected “%sâ€" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Method “%s†on interface “%s†with signature “%s†does not exist" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "A subtree is already exported for %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Object does not exist at path “%sâ€" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "type is INVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL message: PATH or MEMBER header field is missing" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN message: REPLY_SERIAL header field is missing" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Wanted to read %lu byte but only got %lu" +msgstr[1] "Wanted to read %lu bytes but only got %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Expected NUL byte after the string “%s†but found byte %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Value nested too deeply" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Parsed value “%s†is not a valid D-Bus object path" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Parsed value “%s†is not a valid D-Bus signature" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[1] "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Empty structures (tuples) are not allowed in D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Parsed value “%s†for variant is not a valid D-Bus signature" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Error deserialising GVariant with type string “%s†from the D-Bus wire format" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Invalid major protocol version. Expected 1 but found %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Signature header found but is not of type signature" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "Signature header with signature “%s†found but message body is empty" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Parsed value “%s†is not a valid D-Bus signature (for body)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "No signature header in message but the message body is %u byte" +msgstr[1] "No signature header in message but the message body is %u bytes" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Cannot deserialise message: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Error serialising GVariant with type string “%s†to the D-Bus wire format" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Number of file descriptors in message (%d) differs from header field (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Cannot serialise message: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Message body has signature “%s†but there is no signature header" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Message body is empty but signature in the header field is “(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Error return with body of type “%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Error return with empty body" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Type any character to close this window)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Session dbus not running, and autolaunch failed" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Unable to get Hardware profile: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Unable to load %s or %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Error calling StartServiceByName for %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Unexpected reply %d from StartServiceByName(\"%s\") method" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Cannot invoke method; proxy is for the well-known name “%s†without an " +"owner, and proxy was constructed with the " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstract namespace not supported" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Cannot specify nonce file when creating a server" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Error writing nonce file at “%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "The string “%s†is not a valid D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Cannot listen on unsupported transport “%sâ€" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Error: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Error parsing introspection XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Error: %s is not a valid name\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Error: %s is not a valid object path\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Connect to the system bus" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Connect to the session bus" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Connect to given D-Bus address" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Connection Endpoint Options:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Options specifying the connection endpoint" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "No connection endpoint specified" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Multiple connection endpoints specified" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Warning: According to introspection data, interface “%s†does not exist\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Optional destination for signal (unique name)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Object path to emit signal on" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Signal and interface name" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emit a signal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Error connecting: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Error: %s is not a valid unique bus name.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Error: Object path is not specified\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Error: Signal name is not specified\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Error: Signal name “%s†is invalid\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Error: %s is not a valid interface name\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Error: %s is not a valid member name\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Error parsing parameter %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Error flushing connection: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Destination name to invoke method on" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Object path to invoke method on" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Method and interface name" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Timeout in seconds" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Allow interactive authorisation" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Invoke a method on a remote object." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Error: Destination is not specified\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Error: %s is not a valid bus name\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Error: Method name is not specified\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Error: Method name “%s†is invalid\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Error parsing parameter %d of type “%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Error adding handle %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Destination name to introspect" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Object path to introspect" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Print XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Introspect children" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Only print properties" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspect a remote object." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Destination name to monitor" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Object path to monitor" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitor a remote object." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Error: can’t monitor a non-message-bus connection\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Service to activate before waiting for the other one (well-known name)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPTION…] BUS-NAME" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Wait for a bus name to appear." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Error: A service to activate for must be specified.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Error: A service to wait for must be specified.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Error: Too many arguments.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Error: %s is not a valid well-known bus name.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Not authorised to change debug settings" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Unnamed" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Desktop file didn’t specify Exec field" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Unable to find terminal required for application" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Can’t create user application configuration folder %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Can’t create user MIME configuration folder %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Application information lacks an identifier" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Can’t create user desktop file %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Custom definition for %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "drive doesn’t implement eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "drive doesn’t implement eject or eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "drive doesn’t implement polling for media" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "drive doesn’t implement start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "drive doesn’t implement stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS backend does not implement TLS binding retrieval" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS support is not available" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS support is not available" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Can’t handle version %d of GEmblem encoding" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Malformed number of tokens (%d) in GEmblem encoding" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Can’t handle version %d of GEmblemedIcon encoding" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Malformed number of tokens (%d) in GEmblemedIcon encoding" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Expected a GEmblem for GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Containing mount does not exist" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Can’t copy over directory" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Can’t copy directory over directory" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Target file exists" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Can’t recursively copy directory" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Splice not supported" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Error splicing file: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Copy (reflink/clone) between mounts is not supported" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Copy (reflink/clone) is not supported or invalid" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Copy (reflink/clone) is not supported or didn’t work" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Can’t copy special file" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Invalid symlink value given" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Symbolic links not supported" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Wastebasket not supported" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "File names cannot contain “%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "volume doesn’t implement mount" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "No application is registered as handling this file" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator is closed" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "File enumerator has outstanding operation" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "File enumerator is already closed" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Can’t handle version %d of GFileIcon encoding" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Malformed input data for GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Stream doesn’t support query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Seek not supported on stream" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Truncate not allowed on input stream" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Truncate not supported on stream" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Invalid hostname" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Bad HTTP proxy reply" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP proxy connection not allowed" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP proxy authentication failed" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP proxy authentication required" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP proxy connection failed: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP proxy response too big" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP proxy server closed connection unexpectedly." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Wrong number of tokens (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "No type for class name %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Type %s does not implement the GIcon interface" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Type %s is not classed" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Malformed version number: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Type %s does not implement from_tokens() on the GIcon interface" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Can’t handle the supplied version of the icon encoding" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "No address specified" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Length %u is too long for address" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Address has bits set beyond prefix length" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Could not parse “%s†as IP address mask" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Not enough space for socket address" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Unsupported socket address" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Input stream doesn’t implement read" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Stream has outstanding operation" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copy with file" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Keep with file when moved" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†takes no arguments" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Usage:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Print version information and exit." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Commands:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatenate files to standard output" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copy one or more files" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Show information about locations" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Launch an application from a desktop file" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "List the contents of locations" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Get or set the handler for a mimetype" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Create directories" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitor files and directories for changes" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Mount or unmount the locations" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Move one or more files" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Open files with the default application" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Rename a file" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Delete one or more files" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Read from standard input and save" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Set a file attribute" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Move files or directories to the wastebasket" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Lists the contents of locations in a tree" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Use %s to get detailed help.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Error writing to stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCATION" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatenate files and print to standard output." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "No locations given" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "No target directory" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Show progress" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Prompt before overwrite" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Preserve all attributes" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Backup existing destination files" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Never follow symbolic links" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Use default permissions for the destination" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Transferred %s out of %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SOURCE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINATION" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copy one or more files from SOURCE to DESTINATION." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Destination %s is not a directory" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: overwrite “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "List writable attributes" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Get file system info" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "The attributes to get" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTES" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Don’t follow symbolic links" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "attributes:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "display name: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "edit name: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "name: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "type: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "size: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "hidden\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "local path: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix mount: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Settable attributes:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Writable attribute namespaces:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Show information about locations." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-FILE [FILE-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "No desktop file given" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "The launch command is not currently supported on this platform" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Unable to load ‘%s‘: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Unable to load application information for ‘%s‘" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Unable to launch application ‘%s’: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Show hidden files" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Use a long listing format" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Print display names" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Print full URIs" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "List the contents of the locations." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "HANDLER" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Get or set the handler for a mimetype." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Must specify a single mimetype, and maybe a handler" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "No default applications for “%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Default application for “%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registered applications:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "No registered applications\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Recommended applications:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "No recommended applications\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Failed to load info for handler “%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Failed to set “%s†as the default handler for “%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Create parent directories" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Create directories." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitor a directory (default: depends on type)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitor a file (default: depends on type)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Monitor a file directly (notices changes made via hardlinks)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitors a file directly, but doesn’t report changes" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "Report moves and renames as simple deleted/created events" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Watch for mount events" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitor files or directories for changes." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Mount as mountable" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Mount volume with device file, or other identifier" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Unmount" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Eject" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Stop drive with device file" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DEVICE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Unmount all mounts with the given scheme" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEME" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignore outstanding file operations when unmounting or ejecting" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Use an anonymous user when authenticating" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "List" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitor events" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Show extra information" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "The numeric PIM when unlocking a VeraCrypt volume" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Mount a TCRYPT hidden volume" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Mount a TCRYPT system volume" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonymous access denied" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "No drive for device file" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "No volume for given ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Mount or unmount the locations." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Don’t use copy and delete fallback" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Move one or more files from SOURCE to DEST." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Target %s is not a directory" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Open files with the default application that\n" +"is registered to handle files of this type." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignore nonexistent files, never prompt" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Delete the given files." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Rename a file." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Missing argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Too many arguments" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Rename successful. New uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Only create if not existing" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Append to end of file" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "When creating, restrict access to the current user" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "When replacing, replace as if the destination did not exist" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Print new etag at end" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "The etag of the file being overwritten" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Error reading from standard input" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag not available\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Read from standard input and save to DEST." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "No destination given" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Type of the attribute" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATTRIBUTE" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALUE" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Set a file attribute of LOCATION." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Location not specified" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Attribute not specified" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Value not specified" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Invalid attribute type “%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Empty the wastebasket" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "List files in the wastebasket with their original locations" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restore a file from the wastebasket to its original location (possibly " +"recreating the directory)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Unable to find original path" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Unable to recreate original location: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Unable to move file to its original location: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Move/Restore files or directories to the wastebasket." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Note: for --restore switch, if the original location of the file before\n" +"moved to the wastebasket already exists, it will not be overwritten unless\n" +"--force is set." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Location given doesn’t start with trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Follow symbolic links, mounts and shortcuts" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "List contents of directories in a tree-like format." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> not allowed inside <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> not allowed at the top level" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "File %s appears multiple times in the resource" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Failed to locate “%s†in any source directory" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Failed to locate “%s†in current directory" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Unknown processing option “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "%s preprocessing requested, but %s is not set, and %s is not in PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Error reading file %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Error compressing file %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "text may not appear inside <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Show program version and exit" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Name of the output file" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"The directories to load files referenced in FILE from (default: current " +"directory)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Generate output in the format selected for by the target filename extension" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Generate source header" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Generate source code used to link in the resource file into your code" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Generate dependency list" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Name of the dependency file to generate" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Include phony targets in the generated dependency file" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Don’t automatically create and register resource" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Don’t export functions; declare them G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Don’t embed resource data in the C file; assume it’s linked externally " +"instead" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C identifier name used for the generated source code" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "The target C compiler (default: the CC environment variable)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "You should give exactly one file name\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "nick must be a minimum of 2 characters" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Invalid numeric value" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' already specified" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "flags values must have at most 1 bit set" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> must contain at least one " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> is not contained in the specified range" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> is not a valid member of the specified enumerated type" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> contains string not in the specified flags type" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> contains a string not in " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " already specified for this key" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " not allowed for keys of type “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " specified minimum is greater than maximum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "unsupported l10n category: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n requested, but no gettext domain given" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "translation context given for value without l10n enabled" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Failed to parse value of type “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" cannot be specified for keys tagged as having an enumerated type" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " already specified for this key" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " not allowed for keys of type “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " already given" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " must contain at least one " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " already specified for this key" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" can only be specified for keys with enumerated or flags types or " +"after " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" given when “%s†is already a member of the enumerated " +"type" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " given when was already given" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "alias target “%s†is not in enumerated type" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "alias target “%s†is not in " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " must contain at least one " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Empty names are not permitted" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Invalid name “%sâ€: names must begin with a lowercase letter" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Invalid name “%sâ€: maximum length is 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Cannot add keys to a “list-of†schema" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" shadows in ; use " +"to modify value" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> not (yet) defined." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Invalid GVariant type string “%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " given but schema isn’t extending anything" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "No to override" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " extends not yet existing schema “%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " is list of not yet existing schema “%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Cannot be a list of a schema with a path" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Cannot extend a schema with a path" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" is a list, extending which is not a list" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" extends but “%s†" +"does not extend “%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "A path, if given, must begin and end with a slash" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "The path of a list must end with “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> already specified" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Only one <%s> element allowed inside <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> not allowed at the top level" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Element is required in " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Text may not appear inside <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Warning: undefined reference to " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict was specified; exiting." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "This entire file has been ignored." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignoring this file." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Cannot provide per-desktop overrides for localised key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Cannot provide per-desktop overrides for localised key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Where to store the gschemas.compiled file" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Abort on any errors in schemas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Do not write the gschema.compiled file" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Do not enforce key name restrictions" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "You should give exactly one directory name" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "No schema files found: doing nothing." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "No schema files found: removed existing output file." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Invalid filename %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Error getting filesystem info for %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Containing mount for file %s not found" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Can’t rename root directory" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Error renaming file %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Can’t rename file, filename already exists" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Invalid filename" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Error opening file %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Error removing file %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Error moving file %s to the wastebasket: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Unable to create the wastebasket directory %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Unable to find toplevel directory to move %s to the wastebasket" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Can’t move to wastebasket on system internal mounts" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Unable to find or create wastebasket directory %s to move %s to" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Unable to create wastebasket info file for %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Unable to move %s to wastebasket across filesystem boundaries" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Unable to move file %s to the wastebasket: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Unable to move file %s to the wastebasket" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Error creating directory %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Filesystem does not support symbolic links" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Error making symbolic link %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Error moving file %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Can’t move directory over directory" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Backup file creation failed" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Error removing target file: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Move between mounts not supported" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Could not determine the disk usage of %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Attribute value must be non-NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Invalid attribute type (string expected)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Invalid extended attribute name" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Error setting extended attribute “%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (invalid encoding)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Error when getting information for file “%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Error when getting information for file descriptor: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Invalid attribute type (uint32 expected)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Invalid attribute type (uint64 expected)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Invalid attribute type (byte string expected)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Cannot set permissions on symlinks" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Error setting permissions: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Error setting owner: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "symlink must be non-NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Error setting symlink: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Error setting symlink: file is not a symlink" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Extra nanoseconds %d for UNIX timestamp %lld are negative" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX timestamp %lld does not fit into 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "UNIX timestamp %lld is outside of the range supported by Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "File name “%s†cannot be converted to UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "File “%s†cannot be opened: Windows Error %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Error setting modification or access time for file “%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Error setting modification or access time: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux context must be non-NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux is not enabled on this system" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Error setting SELinux context: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Setting attribute %s not supported" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Error reading from file: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Error closing file: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Error seeking in file: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Unable to find default local file monitor type" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Error writing to file: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Error removing old backup link: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Error creating backup copy: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Error renaming temporary file: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Error truncating file: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Error opening file “%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Target file is a directory" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Target file is not a regular file" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "The file was externally modified" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Error removing old file: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Invalid GSeekType supplied" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Invalid seek request" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Cannot truncate GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Memory output stream not resizable" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Failed to resize memory output stream" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Amount of memory required to process the write is larger than available " +"address space" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Requested seek before the beginning of the stream" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Requested seek beyond the end of the stream" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "mount doesn’t implement “unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount doesn’t implement “ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "mount doesn’t implement “unmount†or “unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "mount doesn’t implement “eject†or “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "mount doesn’t implement “remountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "mount doesn’t implement content type guessing" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "mount doesn’t implement synchronous content type guessing" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Hostname “%s†contains “[†but not “]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Network unreachable" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Host unreachable" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Could not create network monitor: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Could not create network monitor: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Could not get network status: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager not running" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager version too old" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Output stream doesn’t implement write" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Sum of vectors passed to %s too large" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Source stream is already closed" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Error resolving “%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s not implemented" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Invalid domain" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "The resource at “%s†does not exist" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "The resource at “%s†failed to decompress" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "The resource at “%s†is not a directory" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Input stream doesn’t implement seek" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "List sections containing resources in an elf FILE" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECTION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extract a resource file to stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION An (optional) elf section name\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND The (optional) command to explain\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE An elf file (a binary or a shared library)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[PATH]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH An (optional) resource path (may be partial)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "PATH" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " PATH A resource path\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "No such schema “%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Schema “%s†is not relocatable (path must not be specified)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schema “%s†is relocatable (path must be specified)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Empty path given.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Path must begin with a slash (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Path must end with a slash (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Path must not contain two adjacent slashes (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "The provided value is outside of the valid range\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "The key is not writable\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "List the installed (non-relocatable) schemas" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "List the installed relocatable schemas" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "List the keys in SCHEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "List the children of SCHEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Get the value of KEY" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Query the range of valid values for KEY" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Query the description for KEY" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Set the value of KEY to VALUE" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Reset KEY to its default value" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Reset all keys in SCHEMA to their defaults" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Check if KEY is writable" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR A directory to search for additional schemas\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY The (optional) key within the schema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KEY The key within the schema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALUE The value to set\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Could not load schemas from %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "No schemas installed\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Empty schema name given\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "No such key “%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Invalid socket, not initialised" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Invalid socket, initialisation failed due to: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Socket is already closed" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Socket I/O timed out" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "creating GSocket from fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Unable to create socket: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Unknown family was specified" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Unknown protocol was specified" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Cannot use datagram operations on a non-datagram socket." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "Cannot use datagram operations on a socket with a timeout set." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "could not get local address: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "could not get remote address: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "could not listen: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Error binding to address %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Error joining multicast group: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Error leaving multicast group: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "No support for source-specific multicast" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Unsupported socket family" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "source-specific not an IPv4 address" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Interface name too long" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interface not found: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "No support for IPv4 source-specific multicast" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "No support for IPv6 source-specific multicast" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Error accepting connection: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Connection in progress" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Unable to get pending error: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Error receiving data: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Error sending data: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Unable to shutdown socket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Error closing socket: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Waiting for socket condition: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Unable to send message: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Message vectors too large" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Error sending message: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage not supported on Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Error receiving message: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Unable to read socket credentials: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials not implemented for this OS" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Could not connect to proxy server %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Could not connect to %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Could not connect: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Proxying over a non-TCP connection is not supported." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proxy protocol “%s†is not supported." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Listener is already closed" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Added socket is closed" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 does not support IPv6 address “%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Username is too long for SOCKSv4 protocol" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Hostname “%s†is too long for SOCKSv4 protocol" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "The server is not a SOCKSv4 proxy server." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Connection through SOCKSv4 server was rejected" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "The server is not a SOCKSv5 proxy server." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "The SOCKSv5 proxy requires authentication." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Username or password is too long for SOCKSv5 protocol." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 authentication failed due to wrong username or password." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Hostname “%s†is too long for SOCKSv5 protocol" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "The SOCKSv5 proxy server uses unknown address type." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Internal SOCKSv5 proxy server error." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 connection not allowed by ruleset." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Host unreachable through SOCKSv5 server." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Network unreachable through SOCKSv5 proxy." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Connection refused through SOCKSv5 proxy." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 proxy does not support “connect†command." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 proxy does not support provided address type." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Unknown SOCKSv5 proxy error." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Failed to create pipe for communicating with child process (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Pipes are not supported in this platform" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Can’t handle version %d of GThemedIcon encoding" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "No valid addresses were found" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Error reverse-resolving “%sâ€: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Error parsing DNS %s record: malformed DNS packet" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "No DNS record of the requested type for “%sâ€" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Temporarily unable to resolve “%sâ€" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Error resolving “%sâ€" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Malformed DNS packet" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Failed to parse DNS response for “%sâ€: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "No PEM-encoded private key found" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Cannot decrypt PEM-encoded private key" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Could not parse PEM-encoded private key" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "No PEM-encoded certificate found" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Could not parse PEM-encoded certificate" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "The current TLS backend does not support PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "This GTlsBackend does not support creating PKCS #11 certificates" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"This is the last chance to enter the password correctly before your access " +"is locked out." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "The password entered is incorrect." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Sending FD is not supported" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Expecting 1 control message, got %d" +msgstr[1] "Expecting 1 control message, got %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Unexpected type of ancillary data" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Expecting one fd, but got %d\n" +msgstr[1] "Expecting one fd, but got %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Received invalid fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Receiving FD is not supported" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Error sending credentials: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Error checking if SO_PASSCRED is enabled for socket: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Error enabling SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Expecting to read a single byte for receiving credentials but read zero bytes" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Not expecting control message, but got %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Error while disabling SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Error reading from file descriptor: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Error closing file descriptor: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Filesystem root" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Error writing to file descriptor: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Abstract UNIX domain socket addresses not supported on this system" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "volume doesn’t implement eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volume doesn’t implement eject or eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Error reading from handle: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Error closing handle: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Error writing to handle: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Not enough memory" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Internal error: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Need more input" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Invalid compressed data" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Address to listen on" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignored, for compat with GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Print address" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Print address in shell mode" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Run a dbus service" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Wrong args\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Unexpected attribute “%s†for element “%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Attribute “%s†of element “%s†not found" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Unexpected tag “%sâ€, tag “%s†expected" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Unexpected tag “%s†inside “%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Invalid date/time ‘%s’ in bookmark file" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "No valid bookmark file found in data dirs" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "A bookmark for URI “%s†already exists" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "No bookmark found for URI “%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "No MIME type defined in the bookmark for URI “%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "No private flag has been defined in bookmark for URI “%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "No groups set in bookmark for URI “%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "No application with name “%s†registered a bookmark for “%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Failed to expand exec line “%s†with URI “%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Unrepresentable character in conversion input" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Partial character sequence at end of input" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Cannot convert fallback “%s†to codeset “%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Embedded NUL byte in conversion input" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Embedded NUL byte in conversion output" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "The URI “%s†is not an absolute URI using the “file†scheme" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "The local file URI “%s†may not include a “#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "The URI “%s†is invalid" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "The hostname of the URI “%s†is invalid" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "The URI “%s†contains invalidly escaped characters" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "The pathname “%s†is not an absolute path" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e %b %Y %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%l:%M:%S %P" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "January" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "February" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "March" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "May" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "June" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "July" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "August" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "October" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "December" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "May" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Oct" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Monday" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Tuesday" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Wednesday" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Thursday" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Friday" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Saturday" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Sunday" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Mon" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Tue" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Wed" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Thu" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Fri" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sat" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Sun" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "January" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "February" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "March" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "May" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "June" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "July" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "August" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "October" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "December" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "May" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Oct" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dec" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Error opening directory “%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Could not allocate %lu byte to read file “%sâ€" +msgstr[1] "Could not allocate %lu bytes to read file “%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Error reading file “%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "File “%s†is too large" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Failed to read from file “%sâ€: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Failed to open file “%sâ€: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Failed to get attributes of file “%sâ€: fstat() failed: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Failed to open file “%sâ€: fdopen() failed: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Failed to write file “%sâ€: write() failed: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Failed to write file “%sâ€: fsync() failed: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Failed to create file “%sâ€: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Existing file “%s†could not be removed: g_unlink() failed: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Template “%s†invalid, should not contain a “%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Template “%s†doesn’t contain XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Failed to read the symbolic link “%sâ€: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Could not open converter from “%s†to “%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Can’t do a raw read in g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Leftover unconverted data in read buffer" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Channel terminates in a partial character" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Can’t do a raw read in g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Valid key file could not be found in search dirs" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Not a regular file" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Invalid group name: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Key file does not start with a group" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Invalid key name: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Key file contains unsupported encoding “%sâ€" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Key file does not have group “%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Key file does not have key “%s†in group “%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Key file contains key “%s†with value “%s†which is not UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Key file contains key “%s†which has a value that cannot be interpreted." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Key “%s†in group “%s†has value “%s†where %s was expected" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Key file contains escape character at end of line" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Key file contains invalid escape sequence “%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Value “%s†cannot be interpreted as a number." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Integer value “%s†out of range" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Value “%s†cannot be interpreted as a float number." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Value “%s†cannot be interpreted as a boolean." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Failed to map %s%s%s%s: mmap() failed: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Failed to open file “%sâ€: open() failed: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Error on line %d char %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Invalid UTF-8 encoded text in name — not valid “%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†is not a valid name" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†is not a valid name: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Error on line %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Character reference “%-.*s†does not encode a permitted character" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Empty entity “&;†seen; valid entities are: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Entity name “%-.*s†is not known" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Document must begin with an element (e.g. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Odd character “%sâ€: expected a '>' character to end the empty-element tag " +"“%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Too many attributes in element “%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Odd character “%sâ€, expected a '=' after attribute name “%s†of element “%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%s†is not a valid character following the close element name “%sâ€; the " +"allowed character is '>'" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Element “%s†was closed, no element is currently open" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Element “%s†was closed, but the currently open element is “%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Document was empty or contained only whitespace" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Document ended unexpectedly just after an open angle bracket “<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Document ended unexpectedly inside an element name" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Document ended unexpectedly inside an attribute name" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Document ended unexpectedly inside an element-opening tag." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Document ended unexpectedly while inside an attribute value" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Document ended unexpectedly inside the close tag for element “%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Document ended unexpectedly inside the close tag for an unopened element" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Document ended unexpectedly inside a comment or processing instruction" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPTION…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Help Options:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Show help options" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Show all help options" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Application Options:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Options:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Cannot parse integer value “%s†for %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Integer value “%s†for %s out of range" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Cannot parse double value “%s†for %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Double value “%s†for %s out of range" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Error parsing option %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Missing argument for %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Unknown option %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "corrupted object" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "internal error or corrupted object" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "out of memory" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "backtracking limit reached" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "the pattern contains items not supported for partial matching" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "internal error" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "back references as conditions are not supported for partial matching" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "recursion limit reached" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "invalid combination of newline flags" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "bad offset" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "short utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "recursion loop" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "unknown error" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ at end of pattern" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c at end of pattern" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "unrecognised character following \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "numbers out of order in {} quantifier" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "number too big in {} quantifier" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "missing terminating ] for character class" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "invalid escape sequence in character class" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "range out of order in character class" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nothing to repeat" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "unexpected repeat" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "unrecognised character after (? or (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX named classes are supported only within a class" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "missing terminating )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "reference to non-existent subpattern" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "missing ) after comment" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "regular expression is too large" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "failed to get memory" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") without opening (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "code overflow" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "unrecognised character after (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind assertion is not fixed length" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "malformed number or name after (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "conditional group contains more than two branches" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "assertion expected after (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R or (?[+-]digits must be followed by )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "unknown POSIX class name" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX collating elements are not supported" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "character value in \\x{…} sequence is too large" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "invalid condition (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C not allowed in lookbehind assertion" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "recursive call could loop indefinitely" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "unrecognised character after (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "missing terminator in subpattern name" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "two named subpatterns have the same name" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "malformed \\P or \\p sequence" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "unknown property name after \\P or \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "subpattern name is too long (maximum 32 characters)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "too many named subpatterns (maximum 10,000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "octal value is greater than \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "overran compiling workspace" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "previously-checked referenced subpattern not found" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE group contains more than one branch" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "inconsistent NEWLINE options" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "a numbered reference must not be zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) not recognised" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "number is too big" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "missing subpattern name after (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "digit expected after (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] is an invalid data character in JavaScript compatibility mode" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "different names for subpatterns of the same number are not allowed" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) must have an argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c must be followed by an ASCII character" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k is not followed by a braced, angle-bracketed, or quoted name" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N is not supported in a class" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "too many forward references" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "character value in \\u.... sequence is too large" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Error while matching regular expression %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE library is compiled without UTF8 support" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE library is compiled without UTF8 properties support" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE library is compiled with incompatible options" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Error while optimising regular expression %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Error while compiling regular expression %s at char %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "hexadecimal digit or “}†expected" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "hexadecimal digit expected" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "missing “<†in symbolic reference" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "unfinished symbolic reference" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "zero-length symbolic reference" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "digit expected" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "illegal symbolic reference" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "stray final “\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "unknown escape sequence" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Error while parsing replacement text “%s†at char %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Quoted text doesn’t begin with a quotation mark" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Unmatched quotation mark in command line or other shell-quoted text" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Text ended just after a “\\†character. (The text was “%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "Text ended before matching quote was found for %c. (The text was “%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Text was empty (or contained only whitespace)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Failed to read data from child process (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Unexpected error in reading data from a child process (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Unexpected error in waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Child process exited with code %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Child process killed by signal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Child process stopped by signal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Child process exited abnormally" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Failed to read from child pipe (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Failed to spawn child process “%s†(%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Failed to fork (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Failed to change to directory “%s†(%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Failed to execute child process “%s†(%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Failed to open file to remap file descriptor (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Failed to duplicate file descriptor for child process (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Failed to fork child process (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Failed to close file descriptor for child process (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Unknown error executing child process “%sâ€" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Failed to read enough data from child pid pipe (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Failed to read data from child process" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Failed to execute child process (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Failed to dup() in child process (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Invalid program name: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Invalid string in argument vector at %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Invalid string in environment: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Invalid working directory: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Failed to execute helper program (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Empty string is not a number" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†is not a signed number" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Number “%s†is out of bounds [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†is not an unsigned number" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Invalid %-encoding in URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Illegal character in URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Non-UTF-8 characters in URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Invalid IPv6 address ‘%.*s’ in URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Illegal encoded IP address ‘%.*s’ in URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Illegal internationalised hostname ‘%.*s’ in URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Could not parse port ‘%.*s’ in URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Port ‘%.*s’ in URI is out of range" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI ‘%s’ is not an absolute URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI ‘%s’ has no host component" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI is not absolute, and no base URI was provided" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Missing ‘=’ and parameter value" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Failed to allocate memory" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Character out of range for UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Invalid sequence in conversion input" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Character out of range for UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Unknown error on connect" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "Mounted %s at %s\n" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Error in address “%s†— the family attribute is malformed" + +#~ msgid "No such method '%s'" +#~ msgstr "No such method '%s'" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable: unknown value '%s'" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGS...]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Failed to create temp file: %s" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; ignoring override for this key.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " and --strict was specified; exiting.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Ignoring override for this key.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "doing nothing.\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Error creating directory '%s': %s" + +#~ msgid "No such interface" +#~ msgstr "No such interface" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Error: signal not specified.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Error: signal must be the fully-qualified name.\n" + +#~| msgid "Error setting extended attribute '%s': %s" +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Error getting writable attributes: %s\n" + +#~| msgid "Error launching application: %s" +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Error mounting location: %s\n" + +#~| msgid "Error connecting: %s\n" +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Error unmounting mount: %s\n" + +#~| msgid "Error closing unix: %s" +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Error finding enclosing mount: %s\n" + +#~| msgid "Error setting owner: %s" +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Error ejecting mount: %s\n" + +#~| msgid "Error connecting: %s\n" +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Error mounting %s: %s\n" + +#~ msgid "No files to open" +#~ msgstr "No files to open" + +#~ msgid "No files to delete" +#~ msgstr "No files to delete" + +#~| msgid "Error setting extended attribute '%s': %s" +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Error setting attribute: %s\n" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Error opening file '%s': %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Error reading file '%s': %s" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Unable to find default local directory monitor type" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Error renaming file: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Error opening file: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Error creating directory: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "Incomplete data received for '%s'" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" + +#~ msgid "association changes not supported on win32" +#~ msgstr "association changes not supported on win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Association creation not supported on win32" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Failed to open file '%s' for writing: fdopen() failed: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Failed to write file '%s': fflush() failed: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Failed to close file '%s': fclose() failed: %s" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Key file does not have key '%s'" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "Abnormal program termination when spawning command line '%s': %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "Command line '%s' exited with non-zero exit status %d: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "No service record for '%s'" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "workspace limit for empty substrings reached" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "repeating a DEFINE group is not allowed" + +#~ msgid "File is empty" +#~ msgstr "File is empty" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." + +#~ msgid "This option will be removed soon." +#~ msgstr "This option will be removed soon." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Error stating file '%s': %s" + +#~ msgid "Error connecting: " +#~ msgstr "Error connecting: " + +#~ msgid "Error connecting: %s" +#~ msgstr "Error connecting: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "SOCKSv4 implementation limits username to %i characters" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKSv4a implementation limits hostname to %i characters" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Error reading from Unix: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Error writing to Unix: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "am" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "Type of return value is incorrect: got '%s', expected '%s'" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writeable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "Specify the path for the schema" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "Arguments:\n" +#~ " SCHEMA The ID of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set the key to, as a serialised GVariant\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." + +#~ msgid "No such schema '%s' specified in override file '%s'" +#~ msgstr "No such schema '%s' specified in override file '%s'" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Can't move directory over directory" + +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Invalid UTF-8 sequence in input" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "Reached maximum data array limit" + +#~ msgid "do not hide entries" +#~ msgstr "do not hide entries" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "Character '%s' is not valid inside an entity name" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Empty character reference; should include a digit such as dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Unfinished entity reference" + +#~ msgid "Unfinished character reference" +#~ msgstr "Unfinished character reference" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Invalid UTF-8 encoded text — overlong sequence" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Invalid UTF-8 encoded text — not a start char" + +#~ msgid "file" +#~ msgstr "file" + +#~ msgid "The file containing the icon" +#~ msgstr "The file containing the icon" + +#~ msgid "An array containing the icon names" +#~ msgstr "An array containing the icon names" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." + +#~ msgid "File descriptor" +#~ msgstr "File descriptor" + +#~ msgid "The file descriptor to read from" +#~ msgstr "The file descriptor from which to read" + +#~ msgid "Close file descriptor" +#~ msgstr "Close file descriptor" + +#~ msgid "Whether to close the file descriptor when the stream is closed" +#~ msgstr "Whether to close the file descriptor when the stream is closed" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Error parsing option %s" + +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Could not change file mode: fork() failed: %s" + +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Could not change file mode: chmod() failed: %s" + +#~ msgid "Could not change file mode: Child terminated by signal: %s" +#~ msgstr "Could not change file mode: Child terminated by signal: %s" + +#~ msgid "Could not change file mode: Child terminated abnormally" +#~ msgstr "Could not change file mode: Child terminated abnormally" diff --git a/po/eo.po b/po/eo.po new file mode 100644 index 0000000..3bbd014 --- /dev/null +++ b/po/eo.po @@ -0,0 +1,5984 @@ +# Esperanto translation for glib. +# Copyright (C) 2003-2012 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Charles VOELGER , 2003. +# Joop EGGEN < <, 2006. +# Brian CROOM < >, 2008. +# Manuel < >, 2010. +# Ryan LORTIE , 2011. +# Tiffany ANTOPOLSKI , 2011, 2012. +# Kristjan SCHMIDT , 2010, 2011, 2012, 2017. +msgid "" +msgstr "" +"Project-Id-Version: glib 2.3.0\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=glib&k" +"eywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-05-29 10:24+0000\n" +"PO-Revision-Date: 2017-06-11 02:06+0200\n" +"Last-Translator: Kristjan SCHMIDT \n" +"Language-Team: Esperanto \n" +"Language: eo\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: Virtaal 0.7.1\n" +"X-Project-Style: gnome\n" + +#: ../gio/gapplication.c:490 +#| msgid "Application Options:" +msgid "GApplication options" +msgstr "Aplikaĵaj opcioj" + +#: ../gio/gapplication.c:490 +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "Montri aplikaĵajn opciojn" + +#: ../gio/gapplication.c:535 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" + +#: ../gio/gapplication.c:547 +msgid "Override the application’s ID" +msgstr "" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gio-tool.c:227 ../gio/gresource-tool.c:488 +#: ../gio/gsettings-tool.c:520 +msgid "Print help" +msgstr "Presi helpon" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:489 +#: ../gio/gresource-tool.c:557 +msgid "[COMMAND]" +msgstr "[KOMANDO]" + +#: ../gio/gapplication-tool.c:49 ../gio/gio-tool.c:228 +#, fuzzy +#| msgid "Print help" +msgid "Print version" +msgstr "Montri helpon" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:526 +msgid "Print version information and exit" +msgstr "" + +#: ../gio/gapplication-tool.c:52 +#, fuzzy +#| msgid "Can't find application" +msgid "List applications" +msgstr "Ne eblas trovi aplikaĵon" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" + +#: ../gio/gapplication-tool.c:55 +#, fuzzy +#| msgid "Can't find application" +msgid "Launch an application" +msgstr "Ne eblas trovi aplikaĵon" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 ../gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMANDO" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:665 +#: ../gio/glib-compile-resources.c:671 ../gio/glib-compile-resources.c:698 +#: ../gio/gresource-tool.c:495 ../gio/gresource-tool.c:561 +msgid "FILE" +msgstr "DOSIERO" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" + +#: ../gio/gapplication-tool.c:73 +#| msgid "SECTION" +msgid "ACTION" +msgstr "AGO" + +#: ../gio/gapplication-tool.c:73 +#, fuzzy +#| msgid "Destination name to introspect" +msgid "The action name to invoke" +msgstr "Nomo de celo por introspekti" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:526 +#: ../gio/gsettings-tool.c:612 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Nekonata komando %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +#| msgid "Usage:" +msgid "Usage:\n" +msgstr "Uzo:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:551 +#: ../gio/gsettings-tool.c:647 +msgid "Arguments:\n" +msgstr "Argumentoj:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS…]" +msgstr "" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:266 +#, c-format +#| msgid "Could not connect to %s: " +msgid "unable to connect to D-Bus: %s\n" +msgstr "ne eblas konekti al D-Bus: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "eraro dum sendado de %s mesaÄo al aplikaĵo: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" + +#: ../gio/gapplication-tool.c:344 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "eraro dum sintaksa analizo de la parametro: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "" + +#: ../gio/gapplication-tool.c:421 +#, fuzzy, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "ne eblas trovi terminalon bezonata por aplikaĵo %s\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +#| msgid "" +#| "Unknown command %s\n" +#| "\n" +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"nekonata komando: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:179 ../gio/ginputstream.c:379 +#: ../gio/ginputstream.c:617 ../gio/ginputstream.c:1019 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:834 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Tro granda nombra valoro transdonita al %s" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +#, fuzzy +#| msgid "Seek not supported on stream" +msgid "Seek not supported on base stream" +msgstr "Serĉo ne estas subtenata en fluo" + +#: ../gio/gbufferedinputstream.c:937 +#, fuzzy +#| msgid "Cannot truncate GMemoryInputStream" +msgid "Cannot truncate GBufferedInputStream" +msgstr "Ne eblas trunki GMemoryInputStream-on" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1208 +#: ../gio/giostream.c:300 ../gio/goutputstream.c:1660 +msgid "Stream is already closed" +msgstr "Fluo estas jam fermita" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +#, fuzzy +#| msgid "Truncate not supported on stream" +msgid "Truncate not supported on base stream" +msgstr "Trunki ne permesita en fluo" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1849 +#: ../gio/gdbusprivate.c:1402 ../gio/gsimpleasyncresult.c:870 +#: ../gio/gsimpleasyncresult.c:896 +#, c-format +msgid "Operation was cancelled" +msgstr "Operacio rezignita" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Nevalida objekto, ne pravalorizita" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Nekompleta plurbajta sekvenco en enigo" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Ne sufiĉa spaco en la cel-loko" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1257 ../glib/gconvert.c:438 ../glib/gconvert.c:845 +#: ../glib/giochannel.c:1556 ../glib/giochannel.c:1598 +#: ../glib/giochannel.c:2442 ../glib/gutf8.c:856 ../glib/gutf8.c:1309 +msgid "Invalid byte sequence in conversion input" +msgstr "Nevalida bajtosekvenco en konverta enigo" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 ../glib/gconvert.c:770 +#: ../glib/giochannel.c:1563 ../glib/giochannel.c:2454 +#, c-format +msgid "Error during conversion: %s" +msgstr "Eraro dum la konverto: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:1085 +msgid "Cancellable initialization not supported" +msgstr "Rezignebla pravalorizo ne estas subtenata" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1384 +#, fuzzy, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Konverto de signaro '%s' al '%s' ne estas subtenata" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Ne eblas malfermi konvertilon de '%s' al '%s'" + +#: ../gio/gcontenttype.c:358 +#, c-format +msgid "%s type" +msgstr "%s tipo" + +#: ../gio/gcontenttype-win32.c:177 +msgid "Unknown type" +msgstr "Nekonata tipo" + +#: ../gio/gcontenttype-win32.c:179 +#, c-format +msgid "%s filetype" +msgstr "%s dosierotipo" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials ne estas realigita sur ĉi tiu operaciumo" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "Estas neniu subteno por GCredentials por via platformo" + +#: ../gio/gcredentials.c:513 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials ne estas realigita sur ĉi tiu operaciumo" + +#: ../gio/gcredentials.c:565 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "Credentials ne estas realigita sur ĉi tiu operaciumo" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Neatendata frua flufino" + +#: ../gio/gdbusaddress.c:155 ../gio/gdbusaddress.c:243 +#: ../gio/gdbusaddress.c:324 +#, fuzzy, c-format +#| msgid "Unsupported key '%s' in address entry '%s'" +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nesubtenata Ålosilo '%s' en adresenigo '%s'" + +#: ../gio/gdbusaddress.c:182 +#, fuzzy, c-format +#| msgid "" +#| "Address '%s' is invalid (need exactly one of path, tmpdir or abstract " +#| "keys)" +msgid "" +"Address “%s†is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"Adreso “%s†estas malvalida (bezonas precize unu el 'path', 'tmpdir' aÅ­ " +"'abstract' Ålosiloj)" + +#: ../gio/gdbusaddress.c:195 +#, fuzzy, c-format +#| msgid "Meaningless key/value pair combination in address entry '%s'" +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Sensignifa Ålosilo/valoro parokombinaĵo en adresa enigo '%s'" + +#: ../gio/gdbusaddress.c:258 ../gio/gdbusaddress.c:339 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the port attribute is malformed" +msgid "Error in address “%s†— the port attribute is malformed" +msgstr "Eraro en adreso '%s' - la 'port' atributo estas misformita" + +#: ../gio/gdbusaddress.c:269 ../gio/gdbusaddress.c:350 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the family attribute is malformed" +msgid "Error in address “%s†— the family attribute is malformed" +msgstr "Eraro en adreso '%s' - la 'family' atributo estas misformita" + +#: ../gio/gdbusaddress.c:460 +#, fuzzy, c-format +#| msgid "Address element '%s', does not contain a colon (:)" +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adresa elemento '%s', ne havas dupunkton (:)" + +#: ../gio/gdbusaddress.c:481 +#, fuzzy, c-format +#| msgid "" +#| "Key/Value pair %d, '%s', in address element '%s', does not contain an " +#| "equal sign" +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Åœlosilo/valoro paro %d, '%s', en adresa elemento '%s', ne havas egalsignon" + +#: ../gio/gdbusaddress.c:495 +#, fuzzy, c-format +#| msgid "" +#| "Error unescaping key or value in Key/Value pair %d, '%s', in address " +#| "element '%s'" +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Eraro dum malkodÅanÄo de la Ålosilo aÅ­ la valoro en Ålosilo/valoro paro %d, " +"'%s', en adresa elemento '%s'" + +#: ../gio/gdbusaddress.c:573 +#, fuzzy, c-format +#| msgid "" +#| "Error in address '%s' - the unix transport requires exactly one of the " +#| "keys 'path' or 'abstract' to be set" +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Eraro en adreso '%s' - la uniksa transporto bezonas precize unu de la " +"Ålosiloj 'path' aÅ­ 'abstract' esti agordita" + +#: ../gio/gdbusaddress.c:609 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the host attribute is missing or malformed" +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Eraro en adreso '%s' - la 'host' atributo mankas aÅ­ estas misformita" + +#: ../gio/gdbusaddress.c:623 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the port attribute is missing or malformed" +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Eraro en adreso '%s' - la 'port' atributo estas maka aÅ­ estas misformita" + +#: ../gio/gdbusaddress.c:637 +#, fuzzy, c-format +#| msgid "" +#| "Error in address '%s' - the noncefile attribute is missing or malformed" +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Eraro en adreso '%s' - la 'noncefile' atributo mankas aÅ­ estas misformita" + +#: ../gio/gdbusaddress.c:658 +msgid "Error auto-launching: " +msgstr "Eraro dum aÅ­tolanĉo: " + +#: ../gio/gdbusaddress.c:666 +#, fuzzy, c-format +#| msgid "Unknown or unsupported transport '%s' for address '%s'" +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Nekonata aÅ­ nesubtenata transporto '%s' por adreso '%s'" + +#: ../gio/gdbusaddress.c:702 +#, fuzzy, c-format +#| msgid "Error opening nonce file '%s': %s" +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Eraro dum malfermo de dosiero 'nonce' '%s': %s" + +#: ../gio/gdbusaddress.c:720 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s': %s" +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Eraro dum legado de dosiero 'nonce' “%sâ€: %s" + +#: ../gio/gdbusaddress.c:729 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Eraro dum legado de dosiero nonce '%s', 16 baitoj atendita, akirita %d" + +#: ../gio/gdbusaddress.c:747 +#, fuzzy, c-format +#| msgid "Error writing contents of nonce file '%s' to stream:" +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Eraro dum skribado de enhavo de dosiero nonce '%s' al la fluo:" + +#: ../gio/gdbusaddress.c:956 +msgid "The given address is empty" +msgstr "La donita adreso estas malplena" + +#: ../gio/gdbusaddress.c:1069 +#, fuzzy, c-format +#| msgid "Cannot spawn a message bus without a machine-id: " +msgid "Cannot spawn a message bus when setuid" +msgstr "Ne eblas starti mesaÄan buson sen maÅino-identigo" + +#: ../gio/gdbusaddress.c:1076 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ne eblas starti mesaÄan buson sen maÅino-identigo: " + +#: ../gio/gdbusaddress.c:1083 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: ../gio/gdbusaddress.c:1125 +#, fuzzy, c-format +#| msgid "Error spawning command line '%s': " +msgid "Error spawning command line “%sâ€: " +msgstr "Eraro dum starto de la komanda linio “%sâ€: " + +#: ../gio/gdbusaddress.c:1342 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: ../gio/gdbusaddress.c:1496 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: ../gio/gdbusaddress.c:1507 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Ne eblas determini seancobusan adreson (ne estas realigita por ĉi tiu " +"operaciumo)" + +#: ../gio/gdbusaddress.c:1645 +#, fuzzy, c-format +#| msgid "" +#| "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#| "variable - unknown value '%s'" +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Ne eblas determi busadreson per DBUS_STARTER_BUS_TYPE medivariablo - " +"nekonata valoron '%s'" + +#: ../gio/gdbusaddress.c:1654 ../gio/gdbusconnection.c:7155 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ne eblas determi busadreso ĉar la DBUS_STARTER_BUS_TYPE medivariable ne " +"estas agordita" + +#: ../gio/gdbusaddress.c:1664 +#, c-format +msgid "Unknown bus type %d" +msgstr "Nekonata bustipo %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "Neatendita manko de enhavo kiam provas legi linion" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Neatendita manko de enhavo kiam provas legi (sekure) linion" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Eluzis ĉiujn haveblajn aÅ­tentigajn metodojn (provinta: %s) (havebla: %s)" + +#: ../gio/gdbusauth.c:1174 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Resignita per GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, fuzzy, c-format +#| msgid "Error when getting information for directory '%s': %s" +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Eraro dum akiro de informo de dosierujo '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, fuzzy, c-format +#| msgid "" +#| "Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Permesoj sur dosierujo '%s' estas misformitaj. Atendita reÄimo 0700, akirita " +"0%o" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory “%sâ€: %s" +msgstr "Eraro dum kreo de la dosierujo '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for reading: " +msgid "Error opening keyring “%s†for reading: " +msgstr "Eraro dum malfermo de la Ålosiloringo “%s†por legi: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, fuzzy, c-format +#| msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Linio %d de la Ålosiloringo al '%s' kun enhavo '%s' estas misformita" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, fuzzy, c-format +#| msgid "" +#| "First token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Unua ĵetono de linio %d de la Ålosiloringo al '%s' kun enhavo '%s' estas " +"misformita" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, fuzzy, c-format +#| msgid "" +#| "Second token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Dua ĵetono de linio %d de la Ålosiloringo al '%s' kun enhavo '%s' estas " +"misformita" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, fuzzy, c-format +#| msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Ne trovas kuketon kun identigo %d en la Ålosiloringo ĉe '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, fuzzy, c-format +#| msgid "Error deleting stale lock file '%s': %s" +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Eraro dum forigo de la malnova Ålosdosiero '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +#| msgid "Error creating lock file '%s': %s" +msgid "Error creating lock file “%sâ€: %s" +msgstr "Eraro dum kreo de la Ålosdosiero “%sâ€: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, fuzzy, c-format +#| msgid "Error closing (unlinked) lock file '%s': %s" +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Eraro dum fermo de la (malligita) Ålosdosiero '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +#| msgid "Error unlinking lock file '%s': %s" +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Eraro dum malligado de la Ålosdosiero “%sâ€: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for writing: " +msgid "Error opening keyring “%s†for writing: " +msgstr "Eraro dum malfermo de Ålosiringo '%s' por skribi: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, fuzzy, c-format +#| msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Cetere, liberigo de la seruro por “%s†ankaÅ­ ne sukcesis: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2378 +msgid "The connection is closed" +msgstr "La konekto estas fermita" + +#: ../gio/gdbusconnection.c:1879 +msgid "Timeout was reached" +msgstr "Tempolimo estis atingita" + +#: ../gio/gdbusconnection.c:2500 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Nesubtenataj flagoj renkontitaj dum kreo de klientflanka konekto" + +#: ../gio/gdbusconnection.c:4124 ../gio/gdbusconnection.c:4471 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"Neniu tia interfaco 'org.freedesktop.DBus.Properties' en objekto en vojo %s" + +#: ../gio/gdbusconnection.c:4266 +#, c-format +msgid "No such property '%s'" +msgstr "Neniu tia atributo '%s'" + +#: ../gio/gdbusconnection.c:4278 +#, c-format +msgid "Property '%s' is not readable" +msgstr "Atributo '%s' ne estas legebla" + +#: ../gio/gdbusconnection.c:4289 +#, c-format +msgid "Property '%s' is not writable" +msgstr "Atributo '%s' ne estas skribebla" + +#: ../gio/gdbusconnection.c:4309 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"Eraro dum agordado de la atributo '%s': Atendita tipo '%s' sed akiris '%s'" + +#: ../gio/gdbusconnection.c:4414 ../gio/gdbusconnection.c:4622 +#: ../gio/gdbusconnection.c:6586 +#, c-format +msgid "No such interface '%s'" +msgstr "Neniu tia interfaco '%s'" + +#: ../gio/gdbusconnection.c:4840 ../gio/gdbusconnection.c:7095 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "Neniu tia interfaco '%s' sur objekto en vojo %s" + +#: ../gio/gdbusconnection.c:4938 +#, c-format +msgid "No such method '%s'" +msgstr "Neniu tia metodo '%s'" + +#: ../gio/gdbusconnection.c:4969 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "Tipo de mesaÄo, '%s', ne kongruas kun la atendita tipo '%s'" + +#: ../gio/gdbusconnection.c:5167 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Objekto jam estas elportita por la interfaco %s ĉe %s" + +#: ../gio/gdbusconnection.c:5393 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to retrieve property %s.%s" +msgstr "Ne eblas krei kontaktskatolon %s.%s" + +#: ../gio/gdbusconnection.c:5449 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to set property %s.%s" +msgstr "Ne eblas krei kontaktskatolon %s.%s" + +#: ../gio/gdbusconnection.c:5625 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "Metodo '%s' redonis tipo '%s', sed estis atendata '%s' '" + +#: ../gio/gdbusconnection.c:6697 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "Metodo '%s' sur interfaco '%s' kun subskribo '%s' ne existas" + +#: ../gio/gdbusconnection.c:6818 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Subarbo estas jam elportita por %s" + +#: ../gio/gdbusconnection.c:7146 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"Ne eblas determi busadreson per DBUS_STARTER_BUS_TYPE medivariablo - " +"nekonata valoron '%s'" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "tipo estas NEVALIDA" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METODO_VOKO mesaÄo: VOJO aÅ­ MEMBRO kapo-kampo mankas" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METOD_REVENO mesaÄo: RESPONDO_SERI0 kapo-kampo mankas" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERARMESAÄœO: RESPONDO_SERIO kapo-kampo aÅ­ ERARO_NOMO mankas" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNALMESAÄœO: VOJO, INTERFACO or MEMBRO kapo-kampo mankas" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNALMESAÄœO: La VOJO-a kapo-kampo uzas la valoron reservitan " +"/org/freedesktop/DBus/Local" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNALMESAÄœO: La kapo-kampo INTERFACO uzas la valoron reservitan org." +"freedesktop.DBus.Local" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +#| msgid "Wanted to read %lu byte but got EOF" +#| msgid_plural "Wanted to read %lu bytes but got EOF" +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Volis legi %lu bajto sed nur akiris %lu" +msgstr[1] "Volis legi %lu bajtoj sed nur akiris %lu" + +#: ../gio/gdbusmessage.c:1371 +#, fuzzy, c-format +#| msgid "Expected NUL byte after the string '%s' but found byte %d" +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Atendita NUL bajto post la ĉeno '%s' sed trovita bajto %d" + +#: ../gio/gdbusmessage.c:1390 +#, fuzzy, c-format +#| msgid "" +#| "Expected valid UTF-8 string but found invalid bytes at byte offset %d " +#| "(length of string is %d). The valid UTF-8 string up until that point was " +#| "'%s'" +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Atendis validan UTF-8 ĉenon sed trovitaj nevalidaj bajtoj ĉe bajto deÅovo %d " +"(longeco de ĉeno estas %d). La valida UTF-8 ĉeno Äis tiu punkto estis “%sâ€" + +#: ../gio/gdbusmessage.c:1589 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus object path" +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Analizita valoro '%s' ne estas valida D-Bus objektovojo" + +#: ../gio/gdbusmessage.c:1611 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus signature" +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Analizita valoro '%s' ne estas valida D-Busa subskribo" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Renkontis matricon de longeco %u bajto. Maksimumo estas 2<<26 bajtoj (64 " +"MiB)." +msgstr[1] "" +"Renkontis matricon de longeco %u bajtoj. Maksimumo estas 2<<26 bajtoj (64 " +"MiB)." + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: ../gio/gdbusmessage.c:1845 +#, fuzzy, c-format +#| msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Analizita valoro '%s' por variaĵo ne estas valida D-Busa subskribo" + +#: ../gio/gdbusmessage.c:1869 +#, fuzzy, c-format +#| msgid "" +#| "Error deserializing GVariant with type string '%s' from the D-Bus wire " +#| "format" +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Eraro dum malseriigo de GVariant kun tipo ĉeno '%s' de la D-Buso dratoformo" + +#: ../gio/gdbusmessage.c:2053 +#, fuzzy, c-format +#| msgid "" +#| "Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found " +#| "value 0x%02x" +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Nevalida pezekstrem('endianness')-valoro. Atendita 0x6c ('l') aÅ­ 0x42 ('B') " +"sed trovas valoron 0x%02x" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Nevalida ĉefprotokolo versio. Atendita 1 sed trovita %d" + +#: ../gio/gdbusmessage.c:2122 +#, fuzzy, c-format +#| msgid "Signature header with signature '%s' found but message body is empty" +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Subskriba kapo kun subskribo '%s' estis trovita sed korpo de mesaÄo estas " +"malplena" + +#: ../gio/gdbusmessage.c:2136 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Analizita valoro '%s' ne estas valida D-Bus subskribo (por korpo)" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Ne estas subskriba kapo en mesaÄo sed la korpo de mesaÄo estas %u bajtoj" +msgstr[1] "" +"Ne estas subskriba kapo en mesaÄo sed la korpo de mesaÄo estas %u bajtoj" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "Ne eblas malseriigi mesaÄon: " + +#: ../gio/gdbusmessage.c:2517 +#, fuzzy, c-format +#| msgid "" +#| "Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Eraro dum seriigo de GVariant kun tipoĉeno '%s' al la D-Buso dratoformo" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"MesaÄo havas %d dosiernumerojn sed la kapo-kampo indikas %d dosiernumeroj" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "Ne eblas seriigi mesaÄon: " + +#: ../gio/gdbusmessage.c:2706 +#, fuzzy, c-format +#| msgid "Message body has signature '%s' but there is no signature header" +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Korpo de mesaÄo havas subskribon '%s' sed ne estas iu subskribokapo" + +#: ../gio/gdbusmessage.c:2716 +#, fuzzy, c-format +#| msgid "" +#| "Message body has type signature '%s' but signature in the header field is " +#| "'%s'" +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "Korpo de mesaÄo havas tipon '%s' sed tipo en la mesaÄokapo estas '%s'" + +#: ../gio/gdbusmessage.c:2732 +#, fuzzy, c-format +#| msgid "Message body is empty but signature in the header field is '(%s)'" +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Korpo de mesaÄo estas malplena sed tipo en la masaÄokapo estas '(%s)'" + +#: ../gio/gdbusmessage.c:3285 +#, fuzzy, c-format +#| msgid "Error return with body of type '%s'" +msgid "Error return with body of type “%sâ€" +msgstr "Erara reveno kun korpo de tipo '%s'" + +#: ../gio/gdbusmessage.c:3293 +msgid "Error return with empty body" +msgstr "Erara reveno kun malplena korpo" + +#: ../gio/gdbusprivate.c:2066 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to get Hardware profile: %s" +msgstr "Ne eblas forÅovi dosieron %s al rubujo" + +#: ../gio/gdbusprivate.c:2111 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Ne eblas Åargi na /var/lib/dbus/machine-id aÅ­ /etc/machine-id: " + +#: ../gio/gdbusproxy.c:1611 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Eraro dum voko de StartServiceByName por %s: " + +#: ../gio/gdbusproxy.c:1634 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Neatendata respondo %d de StartServiceByName(\"%s\") metodo" + +#: ../gio/gdbusproxy.c:2719 ../gio/gdbusproxy.c:2853 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ne eblas envoki metodon; prokurilo estas por bonkonata nomo sen posedanto " +"kaj prokurilo estis kreita kun la G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flago" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "Abstrakta nomspaco nesubtenatas" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "Ne eblas specifi 'nonce'-dosieron dum kreo de servilo" + +#: ../gio/gdbusserver.c:873 +#, fuzzy, c-format +#| msgid "Error writing nonce file at '%s': %s" +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Eraro dum skribo de 'nonce'-dosiero ĉe '%s': %s" + +#: ../gio/gdbusserver.c:1044 +#, fuzzy, c-format +#| msgid "The string '%s' is not a valid D-Bus GUID" +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "La ĉeno '%s' ne estas valida D-Bus GUID" + +#: ../gio/gdbusserver.c:1084 +#, fuzzy, c-format +#| msgid "Cannot listen on unsupported transport '%s'" +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Ne eblas aÅ­skulti sur nesubtenata transporto '%s'" + +#: ../gio/gdbus-tool.c:95 +#, fuzzy, c-format +#| msgid "" +#| "Commands:\n" +#| " help Shows this information\n" +#| " introspect Introspect a remote object\n" +#| " monitor Monitor a remote object\n" +#| " call Invoke a method on a remote object\n" +#| " emit Emit a signal\n" +#| "\n" +#| "Use \"%s COMMAND --help\" to get help on each command.\n" +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Komandoj:\n" +" help Montri ĉi tiu informojn\n" +" introspect Introspekti foran objekton\n" +" monitor Kontroladi foran objekton\n" +" call Envoki metodon sur foran objekto\n" +" emit Sendi signalon\n" +"\n" +"Uzi \"%s KOMANDON --help\" por akiri helpon pri ĉiu komando.\n" + +#: ../gio/gdbus-tool.c:165 ../gio/gdbus-tool.c:227 ../gio/gdbus-tool.c:299 +#: ../gio/gdbus-tool.c:323 ../gio/gdbus-tool.c:725 ../gio/gdbus-tool.c:1068 +#: ../gio/gdbus-tool.c:1510 +#, c-format +msgid "Error: %s\n" +msgstr "Eraro: %s\n" + +#: ../gio/gdbus-tool.c:176 ../gio/gdbus-tool.c:240 ../gio/gdbus-tool.c:1526 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Eraro analizanta introspektan XML-datumaron: %s\n" + +#: ../gio/gdbus-tool.c:209 +#, c-format +#| msgid "Error: %s is not a valid member name\n" +msgid "Error: %s is not a valid name\n" +msgstr "Eraro: %s ne estas valida nomo\n" + +#: ../gio/gdbus-tool.c:357 +msgid "Connect to the system bus" +msgstr "Konekti al la systemabuso" + +#: ../gio/gdbus-tool.c:358 +msgid "Connect to the session bus" +msgstr "Konekti al la seanca buso" + +#: ../gio/gdbus-tool.c:359 +msgid "Connect to given D-Bus address" +msgstr "Konekti al donita D-Buso adreso" + +#: ../gio/gdbus-tool.c:369 +msgid "Connection Endpoint Options:" +msgstr "Opcioj de konekta finpunkto:" + +#: ../gio/gdbus-tool.c:370 +msgid "Options specifying the connection endpoint" +msgstr "Opcioj specifantaj la konektan finpunkton" + +#: ../gio/gdbus-tool.c:392 +#, c-format +msgid "No connection endpoint specified" +msgstr "Ne konekta finpunkto specifita" + +#: ../gio/gdbus-tool.c:402 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Multoblaj konektaj finpunktoj specifitaj" + +#: ../gio/gdbus-tool.c:472 +#, fuzzy, c-format +#| msgid "" +#| "Warning: According to introspection data, interface '%s' does not exist\n" +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Averto: LaÅ­ introspekta datumaro, interfaco '%s' ne ekzistas\n" + +#: ../gio/gdbus-tool.c:481 +#, fuzzy, c-format +#| msgid "" +#| "Warning: According to introspection data, method '%s' does not exist on " +#| "interface '%s'\n" +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Averto: LaÅ­ introspekta datumaro, metodo '%s' ne ekzistas sur interfaco " +"'%s'\n" + +#: ../gio/gdbus-tool.c:543 +msgid "Optional destination for signal (unique name)" +msgstr "Malnepra celo por signalo (unika nomo)" + +#: ../gio/gdbus-tool.c:544 +msgid "Object path to emit signal on" +msgstr "Objektovojo por sendi signalon sur" + +#: ../gio/gdbus-tool.c:545 +msgid "Signal and interface name" +msgstr "Signalo kaj interfaco nomo" + +#: ../gio/gdbus-tool.c:579 +msgid "Emit a signal." +msgstr "Sendi signalon." + +#: ../gio/gdbus-tool.c:613 ../gio/gdbus-tool.c:858 ../gio/gdbus-tool.c:1616 +#: ../gio/gdbus-tool.c:1851 ../gio/gdbus-tool.c:2067 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Konekt-eraro: %s\n" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "Eraro: objektovojo ne specifita.\n" + +#: ../gio/gdbus-tool.c:630 ../gio/gdbus-tool.c:925 ../gio/gdbus-tool.c:1681 +#: ../gio/gdbus-tool.c:1917 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Eraro: %s ne estas valida objekto-vojo\n" + +#: ../gio/gdbus-tool.c:636 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "Eraro: signalo ne specifita.\n" + +#: ../gio/gdbus-tool.c:643 +#, fuzzy, c-format +#| msgid "Error: signal not specified.\n" +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "Eraro: signalo ne specifita.\n" + +#: ../gio/gdbus-tool.c:651 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Eraro: '%s' ne estas valida interfaco-nomo\n" + +#: ../gio/gdbus-tool.c:657 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Eraro: %s ne estas valida membro-nomo\n" + +#: ../gio/gdbus-tool.c:663 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Eraro: %s ne estas valida unika buso-nomo.\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:700 ../gio/gdbus-tool.c:1037 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Eraro dum sintaksa analizo de la parametro %d: %s\n" + +#: ../gio/gdbus-tool.c:732 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Eraro dum elbufrigo de la konekto: %s\n" + +#: ../gio/gdbus-tool.c:759 +msgid "Destination name to invoke method on" +msgstr "Nomo de celvojo por envoki sur Äin metodon" + +#: ../gio/gdbus-tool.c:760 +msgid "Object path to invoke method on" +msgstr "Vojo al objekto por envoki sur Äin metodon" + +#: ../gio/gdbus-tool.c:761 +msgid "Method and interface name" +msgstr "Metodo- kaj interfaco-nomo" + +#: ../gio/gdbus-tool.c:762 +msgid "Timeout in seconds" +msgstr "Tempolimo en sekundoj" + +#: ../gio/gdbus-tool.c:803 +msgid "Invoke a method on a remote object." +msgstr "Envoki metodon sur fora objekto." + +#: ../gio/gdbus-tool.c:878 ../gio/gdbus-tool.c:1635 ../gio/gdbus-tool.c:1870 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "Eraro: Celzono ne estas specifita\n" + +#: ../gio/gdbus-tool.c:890 ../gio/gdbus-tool.c:1652 ../gio/gdbus-tool.c:1882 +#, c-format +#| msgid "Error: %s is not a valid member name\n" +msgid "Error: %s is not a valid bus name\n" +msgstr "Eraro: %s ne estas valida bus-nomo\n" + +#: ../gio/gdbus-tool.c:905 ../gio/gdbus-tool.c:1661 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "Eraro: Objektvojo ne estas specifita\n" + +#: ../gio/gdbus-tool.c:940 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "Eraro: Metodonomo ne estas specifita\n" + +#: ../gio/gdbus-tool.c:951 +#, fuzzy, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Method name “%s†is invalid\n" +msgstr "Eraro: Metodonomo'%s' estas nevalida\n" + +#: ../gio/gdbus-tool.c:1029 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d of type '%s': %s\n" +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Eraro dum sintaksa analizo de la parametro %d de tipo '%s': %s\n" + +#: ../gio/gdbus-tool.c:1473 +msgid "Destination name to introspect" +msgstr "Nomo de celo por introspekti" + +#: ../gio/gdbus-tool.c:1474 +msgid "Object path to introspect" +msgstr "Objektvojo por introspekti" + +#: ../gio/gdbus-tool.c:1475 +msgid "Print XML" +msgstr "Presi XML" + +#: ../gio/gdbus-tool.c:1476 +msgid "Introspect children" +msgstr "Introspekti idoj" + +#: ../gio/gdbus-tool.c:1477 +msgid "Only print properties" +msgstr "Nur presi agordojn" + +#: ../gio/gdbus-tool.c:1568 +msgid "Introspect a remote object." +msgstr "Introspekti foran objekton." + +#: ../gio/gdbus-tool.c:1773 +msgid "Destination name to monitor" +msgstr "Nomo de celo de kontrolota" + +#: ../gio/gdbus-tool.c:1774 +msgid "Object path to monitor" +msgstr "Vojo de kontrolota objekto" + +#: ../gio/gdbus-tool.c:1803 +msgid "Monitor a remote object." +msgstr "Kontroli foran objekton." + +#: ../gio/gdbus-tool.c:1980 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: ../gio/gdbus-tool.c:1983 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: ../gio/gdbus-tool.c:2031 +msgid "[OPTION…] BUS-NAME" +msgstr "" + +#: ../gio/gdbus-tool.c:2033 +msgid "Wait for a bus name to appear." +msgstr "" + +#: ../gio/gdbus-tool.c:2109 +#, fuzzy, c-format +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to activate for must be specified.\n" +msgstr "Eraro: objektovojo ne specifita.\n" + +#: ../gio/gdbus-tool.c:2114 +#, fuzzy, c-format +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to wait for must be specified.\n" +msgstr "Eraro: objektovojo ne specifita.\n" + +#: ../gio/gdbus-tool.c:2119 +#, c-format +msgid "Error: Too many arguments.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:2127 ../gio/gdbus-tool.c:2134 +#, c-format +#| msgid "Error: %s is not a valid unique bus name.\n" +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Eraro: %s ne estas valida konata buso-nomo.\n" + +#: ../gio/gdesktopappinfo.c:1997 ../gio/gdesktopappinfo.c:4504 +msgid "Unnamed" +msgstr "Sennoma" + +#: ../gio/gdesktopappinfo.c:2407 +#, fuzzy +#| msgid "Desktop file didn't specify Exec field" +msgid "Desktop file didn’t specify Exec field" +msgstr "Labortabla dosiero ne specifis Exec-kampon" + +#: ../gio/gdesktopappinfo.c:2692 +msgid "Unable to find terminal required for application" +msgstr "Ne eblas trovi terminalon bezonata por aplikaĵo" + +#: ../gio/gdesktopappinfo.c:3100 +#, fuzzy, c-format +#| msgid "Can't create user application configuration folder %s: %s" +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Ne eblas krei uzanto-aplikaĵan agordodosierujon %s: %s" + +#: ../gio/gdesktopappinfo.c:3104 +#, fuzzy, c-format +#| msgid "Can't create user MIME configuration folder %s: %s" +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Ne eblas krei por uzanto MIME-an agordodosierujon %s: %s" + +#: ../gio/gdesktopappinfo.c:3344 ../gio/gdesktopappinfo.c:3368 +msgid "Application information lacks an identifier" +msgstr "Mankas identigilo en la aplikaĵaj informoj" + +#: ../gio/gdesktopappinfo.c:3602 +#, fuzzy, c-format +#| msgid "Can't create user desktop file %s" +msgid "Can’t create user desktop file %s" +msgstr "Ne eblas krei por uzanto labortablan dosieron %s" + +#: ../gio/gdesktopappinfo.c:3736 +#, c-format +msgid "Custom definition for %s" +msgstr "Propra difino por %s" + +#: ../gio/gdrive.c:417 +#, fuzzy +#| msgid "drive doesn't implement eject" +msgid "drive doesn’t implement eject" +msgstr "diskingo ne realigas elĵeton" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:495 +#, fuzzy +#| msgid "drive doesn't implement eject or eject_with_operation" +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "diskingo ne realigas 'eject' aÅ­ eject_with_operation" + +#: ../gio/gdrive.c:571 +#, fuzzy +#| msgid "drive doesn't implement polling for media" +msgid "drive doesn’t implement polling for media" +msgstr "diskingo ne realigas demandadon pri datumportiloj" + +#: ../gio/gdrive.c:776 +#, fuzzy +#| msgid "drive doesn't implement start" +msgid "drive doesn’t implement start" +msgstr "diskingo ne realigas start (starton)" + +#: ../gio/gdrive.c:878 +#, fuzzy +#| msgid "drive doesn't implement stop" +msgid "drive doesn’t implement stop" +msgstr "diskingo ne realigas stop (halton)" + +#: ../gio/gdummytlsbackend.c:195 ../gio/gdummytlsbackend.c:317 +#: ../gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "TLS subteno ne estas havebla" + +#: ../gio/gdummytlsbackend.c:419 +#, fuzzy +#| msgid "TLS support is not available" +msgid "DTLS support is not available" +msgstr "TLS subteno ne estas havebla" + +#: ../gio/gemblem.c:323 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GEmblem encoding" +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Ne eblas trakti version %d de GEmblem kodoprezento" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Misformita nombro da ĵetonoj (%d) en GEmblem kodoprezento" + +#: ../gio/gemblemedicon.c:362 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GEmblemedIcon encoding" +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Ne eblas trakti version %d de GEmblemedIcon kodoprezento" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Misformita nombro da ĵetonoj (%d) en GEmblemedIcon kodoprezento" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Atendis GEmblem por GEmblemedIcon" + +#: ../gio/gfile.c:969 ../gio/gfile.c:1207 ../gio/gfile.c:1345 +#: ../gio/gfile.c:1583 ../gio/gfile.c:1638 ../gio/gfile.c:1696 +#: ../gio/gfile.c:1780 ../gio/gfile.c:1837 ../gio/gfile.c:1901 +#: ../gio/gfile.c:1956 ../gio/gfile.c:3609 ../gio/gfile.c:3664 +#: ../gio/gfile.c:3900 ../gio/gfile.c:3942 ../gio/gfile.c:4410 +#: ../gio/gfile.c:4821 ../gio/gfile.c:4906 ../gio/gfile.c:4996 +#: ../gio/gfile.c:5093 ../gio/gfile.c:5180 ../gio/gfile.c:5281 +#: ../gio/gfile.c:7822 ../gio/gfile.c:7912 ../gio/gfile.c:7996 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "Operacio ne estas subtenata" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: ../gio/gfile.c:1468 +msgid "Containing mount does not exist" +msgstr "Enhavantan munton ne ekzistas" + +#: ../gio/gfile.c:2515 ../gio/glocalfile.c:2375 +#, fuzzy +#| msgid "Can't copy over directory" +msgid "Can’t copy over directory" +msgstr "Ne eblas kopii super dosierujo" + +#: ../gio/gfile.c:2575 +#, fuzzy +#| msgid "Can't copy directory over directory" +msgid "Can’t copy directory over directory" +msgstr "Ne eblas kopii dosierujon super dosierujo" + +#: ../gio/gfile.c:2583 +msgid "Target file exists" +msgstr "Celdosiero jam ekzistas" + +#: ../gio/gfile.c:2602 +#, fuzzy +#| msgid "Can't recursively copy directory" +msgid "Can’t recursively copy directory" +msgstr "Ne eblas rikure kopii dosierujon" + +#: ../gio/gfile.c:2889 +msgid "Splice not supported" +msgstr "Splisi ne subtenata" + +#: ../gio/gfile.c:2893 +#, c-format +msgid "Error splicing file: %s" +msgstr "Eraro dum splisado de la dosiero: %s" + +#: ../gio/gfile.c:3024 +#| msgid "Move between mounts not supported" +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopii (reflink/clone) inter muntoj ne estas subtenata" + +#: ../gio/gfile.c:3028 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: ../gio/gfile.c:3033 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" + +#: ../gio/gfile.c:3096 +#, fuzzy +#| msgid "Can't copy special file" +msgid "Can’t copy special file" +msgstr "Ne eblas kopii specialan dosieron" + +#: ../gio/gfile.c:3890 +msgid "Invalid symlink value given" +msgstr "Invalida simligila valoro donita" + +#: ../gio/gfile.c:4051 +msgid "Trash not supported" +msgstr "Rubujo ne estas subtenata" + +#: ../gio/gfile.c:4163 +#, c-format +#| msgid "File names cannot contain '%c'" +msgid "File names cannot contain “%câ€" +msgstr "Dosiernomoj ne povas enhavi “%câ€" + +#: ../gio/gfile.c:6609 ../gio/gvolume.c:363 +#, fuzzy +#| msgid "volume doesn't implement mount" +msgid "volume doesn’t implement mount" +msgstr "datumportilo ne realigas 'mount'" + +#: ../gio/gfile.c:6718 +msgid "No application is registered as handling this file" +msgstr "Neniu aplikaĵo estas registrita kiel traktilo por ĉi tiu dosiero" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumeraciilo estas fermita" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Dosierenumeraciilo havas restantan operacion" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Dosierenumeraciilo jam estas fermita" + +#: ../gio/gfileicon.c:236 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GFileIcon encoding" +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Ne eblas trakti version %d de GFileIcon-kodoprezento" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Esti misformita eniga datumaro por GFileIcon" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +#, fuzzy +#| msgid "Stream doesn't support query_info" +msgid "Stream doesn’t support query_info" +msgstr "Fluo ne subtenas query_info-on" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Serĉo ne estas subtenata en fluo" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Trunki ne permesita en eniga fluo" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Trunki ne permesita en fluo" + +#: ../gio/ghttpproxy.c:91 ../gio/gresolver.c:410 ../gio/gresolver.c:476 +#: ../glib/gconvert.c:1650 +msgid "Invalid hostname" +msgstr "Nevalida gastiga komputilonomo" + +#: ../gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "" + +#: ../gio/ghttpproxy.c:159 +#, fuzzy +#| msgid "The connection is closed" +msgid "HTTP proxy connection not allowed" +msgstr "La konekto estas fermita" + +#: ../gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "" + +#: ../gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "" + +#: ../gio/ghttpproxy.c:171 +#, c-format +#| msgid "The connection is closed" +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP-prokurila konekto malsukcesis: %i" + +#: ../gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "MalÄusta nombro de ĵetonoj (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "Neniu tipo por klasnomo %s" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Tipo %s ne realigas la GIcon interfaco" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "Tipo %s ne estas klasata" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "Misformita versionumero: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Tipo %s ne realigas from_tokens() sur la GIcon Interfaco" + +#: ../gio/gicon.c:461 +#, fuzzy +#| msgid "Can't handle the supplied version the icon encoding" +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Ne eblas trakti la provizitan version de bildsimbolo kodoprezento" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Neniu adreso specifita" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Longeco %u estas tro longa por adreso" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +#| msgid "Could not parse '%s' as IP address mask" +msgid "Could not parse “%s†as IP address mask" +msgstr "Ne eblas analizi na “%s†kiel IP-adresa masko" + +#: ../gio/ginetsocketaddress.c:203 ../gio/ginetsocketaddress.c:220 +#: ../gio/gnativesocketaddress.c:106 ../gio/gunixsocketaddress.c:218 +msgid "Not enough space for socket address" +msgstr "Ne sufiĉa spaco por kontaktskatolo adreso" + +#: ../gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nesubtenata kontaktskatolo adreso" + +#: ../gio/ginputstream.c:188 +#, fuzzy +#| msgid "Input stream doesn't implement read" +msgid "Input stream doesn’t implement read" +msgstr "Eniga fluo ne realigas legon" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1218 ../gio/giostream.c:310 +#: ../gio/goutputstream.c:1670 +msgid "Stream has outstanding operation" +msgstr "Fluo havas restantan operacion" + +#: ../gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "" + +#: ../gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "" + +#: ../gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "" + +#: ../gio/gio-tool.c:207 ../gio/gio-tool.c:223 ../glib/goption.c:857 +msgid "Usage:" +msgstr "Uzo:" + +#: ../gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "" + +#: ../gio/gio-tool.c:224 +msgid "[ARGS...]" +msgstr "" + +#: ../gio/gio-tool.c:226 +msgid "Commands:" +msgstr "" + +#: ../gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: ../gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "" + +#: ../gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "" + +#: ../gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "" + +#: ../gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: ../gio/gio-tool.c:234 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create directories" +msgstr "Ne eblas malfermi dosierujon" + +#: ../gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "" + +#: ../gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "" + +#: ../gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "" + +#: ../gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "" + +#: ../gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "" + +#: ../gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "" + +#: ../gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "" + +#: ../gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "" + +#: ../gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "" + +#: ../gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: ../gio/gio-tool.c:246 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" + +#: ../gio/gio-tool-cat.c:80 +#| msgid "Error writing to file: %s" +msgid "Error writing to stdout" +msgstr "Eraro dum skribado al stdout" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-cat.c:124 ../gio/gio-tool-info.c:282 +#: ../gio/gio-tool-list.c:165 ../gio/gio-tool-mkdir.c:48 +#: ../gio/gio-tool-monitor.c:37 ../gio/gio-tool-monitor.c:39 +#: ../gio/gio-tool-monitor.c:41 ../gio/gio-tool-monitor.c:43 +#: ../gio/gio-tool-monitor.c:203 ../gio/gio-tool-mount.c:1141 +#: ../gio/gio-tool-open.c:45 ../gio/gio-tool-remove.c:48 +#: ../gio/gio-tool-rename.c:45 ../gio/gio-tool-set.c:89 +#: ../gio/gio-tool-trash.c:81 ../gio/gio-tool-tree.c:239 +#, fuzzy +#| msgid "SECTION" +msgid "LOCATION" +msgstr "SEKCIO" + +#: ../gio/gio-tool-cat.c:129 +msgid "Concatenate files and print to standard output." +msgstr "" + +#: ../gio/gio-tool-cat.c:131 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: ../gio/gio-tool-cat.c:153 ../gio/gio-tool-info.c:313 +#: ../gio/gio-tool-mkdir.c:76 ../gio/gio-tool-monitor.c:228 +#: ../gio/gio-tool-open.c:71 ../gio/gio-tool-remove.c:72 +msgid "No locations given" +msgstr "" + +#: ../gio/gio-tool-copy.c:42 ../gio/gio-tool-move.c:38 +#, fuzzy +#| msgid "Target file is a directory" +msgid "No target directory" +msgstr "Celdosiero estas dosierujo" + +#: ../gio/gio-tool-copy.c:43 ../gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "" + +#: ../gio/gio-tool-copy.c:44 ../gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "" + +#: ../gio/gio-tool-copy.c:45 +msgid "Preserve all attributes" +msgstr "" + +#: ../gio/gio-tool-copy.c:46 ../gio/gio-tool-move.c:41 +#: ../gio/gio-tool-save.c:49 +#, fuzzy +#| msgid "Backup file creation failed" +msgid "Backup existing destination files" +msgstr "Sekurkopia kreado malsukcesis" + +#: ../gio/gio-tool-copy.c:47 +msgid "Never follow symbolic links" +msgstr "" + +#: ../gio/gio-tool-copy.c:72 ../gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +#: ../gio/gio-tool-save.c:165 +msgid "DESTINATION" +msgstr "" + +#: ../gio/gio-tool-copy.c:103 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" + +#: ../gio/gio-tool-copy.c:105 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: ../gio/gio-tool-copy.c:147 +#, fuzzy, c-format +#| msgid "The resource at '%s' is not a directory" +msgid "Destination %s is not a directory" +msgstr "La risurco ĉe '%s' ne estas dosierujo" + +#: ../gio/gio-tool-copy.c:192 ../gio/gio-tool-move.c:185 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "" + +#: ../gio/gio-tool-info.c:34 +msgid "List writable attributes" +msgstr "" + +#: ../gio/gio-tool-info.c:35 +#| msgid "Error getting filesystem info: %s" +msgid "Get file system info" +msgstr "Akiro de dosiersistema informo" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "The attributes to get" +msgstr "" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "ATTRIBUTES" +msgstr "" + +#: ../gio/gio-tool-info.c:37 ../gio/gio-tool-list.c:38 ../gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "" + +#: ../gio/gio-tool-info.c:75 +#, c-format +msgid "attributes:\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:138 +#, c-format +msgid "name: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:151 +#, c-format +msgid "size: " +msgstr "" + +#: ../gio/gio-tool-info.c:156 +#, c-format +msgid "hidden\n" +msgstr "" + +#: ../gio/gio-tool-info.c:159 +#, c-format +#| msgid "Error: %s\n" +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: ../gio/gio-tool-info.c:228 +#, c-format +msgid "Settable attributes:\n" +msgstr "" + +#: ../gio/gio-tool-info.c:252 +#, c-format +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: ../gio/gio-tool-info.c:287 +msgid "Show information about locations." +msgstr "" + +#: ../gio/gio-tool-info.c:289 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#: ../gio/gio-tool-list.c:36 ../gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "" + +#: ../gio/gio-tool-list.c:37 +msgid "Use a long listing format" +msgstr "" + +#: ../gio/gio-tool-list.c:39 +msgid "Print full URIs" +msgstr "" + +#: ../gio/gio-tool-list.c:170 +msgid "List the contents of the locations." +msgstr "" + +#: ../gio/gio-tool-list.c:172 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: ../gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: ../gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: ../gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: ../gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: ../gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:127 +#, c-format +msgid "Registered applications:\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:129 +#, c-format +#| msgid "Can't find application" +msgid "No registered applications\n" +msgstr "Neniu registrita aplikaĵo\n" + +#: ../gio/gio-tool-mime.c:140 +#, c-format +msgid "Recommended applications:\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:142 +#, c-format +#| msgid "Can't find application" +msgid "No recommended applications\n" +msgstr "Neniu rekomendita aplikaĵo\n" + +#: ../gio/gio-tool-mime.c:162 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "Malsukcesis Åargi el dosiero “%sâ€" + +#: ../gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" + +#: ../gio/gio-tool-mkdir.c:31 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create parent directories" +msgstr "Ne eblas malfermi dosierujon" + +#: ../gio/gio-tool-mkdir.c:52 +#| msgid "Can't open directory" +msgid "Create directories." +msgstr "Krei doserujojn." + +#: ../gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: ../gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: ../gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: ../gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: ../gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "" + +#: ../gio/gio-tool-mount.c:58 +msgid "Mount as mountable" +msgstr "" + +#: ../gio/gio-tool-mount.c:59 +msgid "Mount volume with device file" +msgstr "" + +#: ../gio/gio-tool-mount.c:59 +msgid "DEVICE" +msgstr "" + +#: ../gio/gio-tool-mount.c:60 +msgid "Unmount" +msgstr "" + +#: ../gio/gio-tool-mount.c:61 +msgid "Eject" +msgstr "" + +#: ../gio/gio-tool-mount.c:62 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: ../gio/gio-tool-mount.c:62 +msgid "SCHEME" +msgstr "" + +#: ../gio/gio-tool-mount.c:63 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: ../gio/gio-tool-mount.c:64 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: ../gio/gio-tool-mount.c:66 +msgid "List" +msgstr "" + +#: ../gio/gio-tool-mount.c:67 +msgid "Monitor events" +msgstr "" + +#: ../gio/gio-tool-mount.c:68 +#, fuzzy +#| msgid "Show help options" +msgid "Show extra information" +msgstr "Montri helpajn opciojn" + +#: ../gio/gio-tool-mount.c:246 ../gio/gio-tool-mount.c:276 +msgid "Anonymous access denied" +msgstr "" + +#: ../gio/gio-tool-mount.c:897 +#, c-format +msgid "Mounted %s at %s\n" +msgstr "" + +#: ../gio/gio-tool-mount.c:950 +msgid "No volume for device file" +msgstr "" + +#: ../gio/gio-tool-mount.c:1145 +msgid "Mount or unmount the locations." +msgstr "" + +#: ../gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: ../gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: ../gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: ../gio/gio-tool-move.c:142 +#, c-format +#| msgid "Target file is a directory" +msgid "Target %s is not a directory" +msgstr "Celo %s ne estas dosierujo" + +#: ../gio/gio-tool-open.c:50 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: ../gio/gio-tool-remove.c:31 ../gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: ../gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "" + +#: ../gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "" + +#: ../gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "" + +#: ../gio/gio-tool-rename.c:70 +#| msgid "Missing argument for %s" +msgid "Missing argument" +msgstr "Mankas argumento" + +#: ../gio/gio-tool-rename.c:76 ../gio/gio-tool-save.c:195 +#: ../gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "" + +#: ../gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: ../gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "" + +#: ../gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "" + +#: ../gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: ../gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: ../gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "" + +#: ../gio/gio-tool-save.c:119 +#, fuzzy +#| msgid "Error reading from handle: %s" +msgid "Error reading from standard input" +msgstr "Eraro dum lego de dosiernumero" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:145 +#, c-format +#| msgid "TLS support is not available" +msgid "Etag not available\n" +msgstr "Etag ne estas havebla\n" + +#: ../gio/gio-tool-save.c:168 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: ../gio/gio-tool-save.c:188 +msgid "No destination given" +msgstr "" + +#: ../gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "" + +#: ../gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "" + +#: ../gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "" + +#: ../gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "" + +#: ../gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "" + +#: ../gio/gio-tool-set.c:113 +#, fuzzy +#| msgid "No connection endpoint specified" +msgid "Location not specified" +msgstr "Ne konekta finpunkto specifita" + +#: ../gio/gio-tool-set.c:120 +#| msgid "Error: signal not specified.\n" +msgid "Attribute not specified" +msgstr "Atributo ne estas specifita" + +#: ../gio/gio-tool-set.c:130 +#| msgid "Error: signal not specified.\n" +msgid "Value not specified" +msgstr "Valoro ne estas specifita" + +#: ../gio/gio-tool-set.c:180 +#, c-format +#| msgid "Invalid attribute type (string expected)" +msgid "Invalid attribute type “%sâ€" +msgstr "Nevalida atributa tipo “%sâ€" + +#: ../gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "" + +#: ../gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "" + +#: ../gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" + +#: ../gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1492 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elemento <%s> ne estas permesita interne de <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elemento <%s> ne estas permesita je plejsupre nivelo" + +#: ../gio/glib-compile-resources.c:237 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:248 +#, fuzzy, c-format +#| msgid "Failed to locate '%s' in current directory" +msgid "Failed to locate “%s†in any source directory" +msgstr "Malsukcesis trovi na “%s†en fonta dosierujo" + +#: ../gio/glib-compile-resources.c:259 +#, fuzzy, c-format +#| msgid "Failed to locate '%s' in current directory" +msgid "Failed to locate “%s†in current directory" +msgstr "Malsukcesis trovi na “%s†en aktuala dosierujo" + +#: ../gio/glib-compile-resources.c:290 +#, fuzzy, c-format +#| msgid "Unknown processing option \"%s\"" +msgid "Unknown processing option “%sâ€" +msgstr "Nekonata opcio de traktado “%sâ€" + +#: ../gio/glib-compile-resources.c:308 ../gio/glib-compile-resources.c:354 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "Malsukcesis krei dosieron: %s" + +#: ../gio/glib-compile-resources.c:382 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Eraro dum legado de la dosiero %s: %s" + +#: ../gio/glib-compile-resources.c:402 +#, c-format +msgid "Error compressing file %s" +msgstr "Eraro dum kompaktigo de dosiero: %s" + +#: ../gio/glib-compile-resources.c:469 ../gio/glib-compile-schemas.c:1604 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "teksto ne povi montriÄas interne de <%s>" + +#: ../gio/glib-compile-resources.c:664 ../gio/glib-compile-schemas.c:2053 +msgid "Show program version and exit" +msgstr "" + +#: ../gio/glib-compile-resources.c:665 +msgid "name of the output file" +msgstr "nomo de la elig-dosiero" + +#: ../gio/glib-compile-resources.c:666 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" + +#: ../gio/glib-compile-resources.c:666 ../gio/glib-compile-schemas.c:2054 +#: ../gio/glib-compile-schemas.c:2082 +msgid "DIRECTORY" +msgstr "DOSIERUJO" + +#: ../gio/glib-compile-resources.c:667 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: ../gio/glib-compile-resources.c:668 +msgid "Generate source header" +msgstr "" + +#: ../gio/glib-compile-resources.c:669 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" + +#: ../gio/glib-compile-resources.c:670 +msgid "Generate dependency list" +msgstr "Generi liston de dependeco" + +#: ../gio/glib-compile-resources.c:671 +msgid "name of the dependency file to generate" +msgstr "" + +#: ../gio/glib-compile-resources.c:672 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: ../gio/glib-compile-resources.c:673 +#, fuzzy +#| msgid "Don't automatically create and register resource" +msgid "Don’t automatically create and register resource" +msgstr "Ne aÅ­tomate generi aÅ­ registri risurcon" + +#: ../gio/glib-compile-resources.c:674 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: ../gio/glib-compile-resources.c:675 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: ../gio/glib-compile-resources.c:701 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompili risurcan specifigon al risurca dosiero.\n" +"Risurca specifiga dosiero havas la sufikson .gresource.xml,\n" +"kaj la risurca dosiero estas nomita .gresource." + +#: ../gio/glib-compile-resources.c:723 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "Vi devus doni precize unu dosieran nomon\n" + +#: ../gio/glib-compile-schemas.c:784 +msgid "empty names are not permitted" +msgstr "malplenaj nomoj ne estas permesataj" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "nevalida nomo '%s': nomoj devas komenciÄi per minusklo" + +#: ../gio/glib-compile-schemas.c:806 +#, fuzzy, c-format +#| msgid "" +#| "invalid name '%s': invalid character '%c'; only lowercase letters, " +#| "numbers and dash ('-') are permitted." +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"nevalida nomo '%s: nevalida karaktro '%c'; nur minuskloj, nombroj kaj " +"streketo ('-') permesataj." + +#: ../gio/glib-compile-schemas.c:815 +#, fuzzy, c-format +#| msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "nevalida nomo '%s': du sinsekvaj streketoj ('--') ne permesataj." + +#: ../gio/glib-compile-schemas.c:824 +#, fuzzy, c-format +#| msgid "invalid name '%s': the last character may not be a dash ('-')." +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "nevalida nomo '%s': la fina karaktro ne povas esti streketo ('-')." + +#: ../gio/glib-compile-schemas.c:832 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "nevalida nomo '%s': maksimuma longeco estas 1024" + +#: ../gio/glib-compile-schemas.c:902 +#, c-format +msgid " already specified" +msgstr " jam specifita" + +#: ../gio/glib-compile-schemas.c:928 +msgid "cannot add keys to a 'list-of' schema" +msgstr "ne eblas aldoni Ålosilojn al skemo 'list-of'" + +#: ../gio/glib-compile-schemas.c:939 +#, c-format +msgid " already specified" +msgstr " jam specifita" + +#: ../gio/glib-compile-schemas.c:957 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" kaÅas en ; uzu " +"por modifi valoron" + +#: ../gio/glib-compile-schemas.c:968 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"precize unu el 'type', 'enum' aÅ­ 'flags' devas esti specifita kiel atributo " +"de " + +#: ../gio/glib-compile-schemas.c:987 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> ne (jam) difinita." + +#: ../gio/glib-compile-schemas.c:1002 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "nevalida GVariant tipo-ĉeno '%s'" + +#: ../gio/glib-compile-schemas.c:1032 +msgid " given but schema isn't extending anything" +msgstr " donita sed skemo ne etendanta io" + +#: ../gio/glib-compile-schemas.c:1045 +#, c-format +msgid "no to override" +msgstr "neniu por superregi" + +#: ../gio/glib-compile-schemas.c:1053 +#, c-format +msgid " already specified" +msgstr " jam specifita" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid " already specified" +msgstr " jam specifita" + +#: ../gio/glib-compile-schemas.c:1138 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " etendas skemo '%s' kiu ankoraÅ­ ne ekzistas" + +#: ../gio/glib-compile-schemas.c:1154 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " estas listo de skemo '%s' kiu ankoraÅ­ ne ekzistas" + +#: ../gio/glib-compile-schemas.c:1162 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "Ne eblas esti listo de skemo kun vojo" + +#: ../gio/glib-compile-schemas.c:1172 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "Ne eblas etendi liston de skemo kun vojo" + +#: ../gio/glib-compile-schemas.c:1182 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" estas listo, etendanta kiu ne estas listo" + +#: ../gio/glib-compile-schemas.c:1192 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" etendas sed '%s' " +"ne etendas '%s'" + +#: ../gio/glib-compile-schemas.c:1209 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "vojo, se donita, devas komenciÄi kaj finiÄi kun oblikvo" + +#: ../gio/glib-compile-schemas.c:1216 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "la vojo de listo devas finiÄi en ':/'" + +#: ../gio/glib-compile-schemas.c:1248 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> jam specifita" + +#: ../gio/glib-compile-schemas.c:1398 ../gio/glib-compile-schemas.c:1414 +#, c-format +#| msgid "Element <%s> not allowed inside <%s>" +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Elemento <%s> ne estas permesata ene de <%s>" + +#: ../gio/glib-compile-schemas.c:1496 +#, c-format +#| msgid "Element <%s> not allowed at toplevel" +msgid "Element <%s> not allowed at the top level" +msgstr "Elemento <%s> ne estas permesata je plejsupra nivelo" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1806 ../gio/glib-compile-schemas.c:1880 +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict estis specifita; eliranta.\n" + +#: ../gio/glib-compile-schemas.c:1816 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "Ĉi tiu tuta dosiero estas ignorita.\n" + +#: ../gio/glib-compile-schemas.c:1876 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Ignoras ĉi tiun dosieron.\n" + +#: ../gio/glib-compile-schemas.c:1916 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"Neniu tia Ålosilo '%s' en skemo '%s' kiel estas specifite en superrego-" +"dosiero '%s'" + +#: ../gio/glib-compile-schemas.c:1922 ../gio/glib-compile-schemas.c:1980 +#: ../gio/glib-compile-schemas.c:2008 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; ignoras superrego por ĉi tiu Ålosilo.\n" + +#: ../gio/glib-compile-schemas.c:1926 ../gio/glib-compile-schemas.c:1984 +#: ../gio/glib-compile-schemas.c:2012 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " kaj --strict estis specifita; eliranta.\n" + +#: ../gio/glib-compile-schemas.c:1942 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s. " +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"eraro dum sintaksa analizo de la Ålosilo '%s' en skemo '%s' kiel estas " +"specifita en superrego-dosiero '%s': %s." + +#: ../gio/glib-compile-schemas.c:1952 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "Ignoras superregon por ĉi tiu Ålosilo.\n" + +#: ../gio/glib-compile-schemas.c:1970 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is out of the " +#| "range given in the schema" +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"superrego por Ålosilo '%s' en skemo '%s' en superrego-dosiero '%s' ne estas " +"en la intervalo donita en la skemo" + +#: ../gio/glib-compile-schemas.c:1998 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"superrego por Ålosilo '%s' en skemo '%s' en superrego-dosiero '%s' ne estas " +"en la listo de la validaj elektoj" + +#: ../gio/glib-compile-schemas.c:2054 +msgid "where to store the gschemas.compiled file" +msgstr "kie enmemorigi la gschema.compiled dosieron" + +#: ../gio/glib-compile-schemas.c:2055 +msgid "Abort on any errors in schemas" +msgstr "Ĉesigi se iuj eraroj en skemoj" + +#: ../gio/glib-compile-schemas.c:2056 +msgid "Do not write the gschema.compiled file" +msgstr "Ne verki na la gschema.compiled dosieron" + +#: ../gio/glib-compile-schemas.c:2057 +msgid "Do not enforce key name restrictions" +msgstr "Ne devigi Ålosilonomajn limigojn" + +#: ../gio/glib-compile-schemas.c:2085 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompili ciujn GSettings skemajn dosierojn en skema kaÅmemoro.\n" +"Skemaj dosieroj estas bezonas havi la sufikson .gschema.xml,\n" +"kaj la kaÅmemora dosiero estas nomita gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:2106 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "Vi devus doni precize unu dosierujan nomon\n" + +#: ../gio/glib-compile-schemas.c:2148 +#, c-format +msgid "No schema files found: " +msgstr "Neniuj skemaj dosieroj trovitaj: " + +#: ../gio/glib-compile-schemas.c:2151 +#, c-format +msgid "doing nothing.\n" +msgstr "faranta nenion.\n" + +#: ../gio/glib-compile-schemas.c:2154 +#, c-format +msgid "removed existing output file.\n" +msgstr "forigis ekzistantan eliran dosieron.\n" + +#: ../gio/glocalfile.c:643 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "Nevalida dosiernomo %s" + +#: ../gio/glocalfile.c:1037 +#, fuzzy, c-format +#| msgid "Error getting filesystem info: %s" +msgid "Error getting filesystem info for %s: %s" +msgstr "Eraro dum akiro de dosiersistema informo %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: ../gio/glocalfile.c:1176 +#, fuzzy, c-format +#| msgid "Containing mount does not exist" +msgid "Containing mount for file %s not found" +msgstr "Enhavantan munton por dosiero %s ne trovis" + +#: ../gio/glocalfile.c:1199 +#, fuzzy +#| msgid "Can't rename root directory" +msgid "Can’t rename root directory" +msgstr "Ne eblas alinomi radikan dosierujon" + +#: ../gio/glocalfile.c:1217 ../gio/glocalfile.c:1240 +#, fuzzy, c-format +#| msgid "Error reading file %s: %s" +msgid "Error renaming file %s: %s" +msgstr "Eraro dum legado de la dosiero %s: %s" + +#: ../gio/glocalfile.c:1224 +#, fuzzy +#| msgid "Can't rename file, filename already exists" +msgid "Can’t rename file, filename already exists" +msgstr "Ne eblas alinomi dosieron, dosiernomo jam ekzistas" + +#: ../gio/glocalfile.c:1237 ../gio/glocalfile.c:2251 ../gio/glocalfile.c:2279 +#: ../gio/glocalfile.c:2436 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "Nevalida dosiernomo" + +#: ../gio/glocalfile.c:1404 ../gio/glocalfile.c:1419 +#, fuzzy, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file %s: %s" +msgstr "Eraro dum malfermo de la dosiero '%s': %s" + +#: ../gio/glocalfile.c:1544 +#, c-format +#| msgid "Error removing file: %s" +msgid "Error removing file %s: %s" +msgstr "Eraro dum forigo de la dosiero %s: %s" + +#: ../gio/glocalfile.c:1927 +#, c-format +#| msgid "Error trashing file: %s" +msgid "Error trashing file %s: %s" +msgstr "Eraro dum forigo de la dosiero %s: %s" + +#: ../gio/glocalfile.c:1950 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Ne eblas krei rubujan dosierujon %s: %s" + +#: ../gio/glocalfile.c:1970 +#, fuzzy, c-format +#| msgid "Unable to find toplevel directory for trash" +msgid "Unable to find toplevel directory to trash %s" +msgstr "Ne eblas trovi plejsupra-nivelan dosierujon por rubujo %s" + +#: ../gio/glocalfile.c:2049 ../gio/glocalfile.c:2069 +#, fuzzy, c-format +#| msgid "Unable to find or create trash directory" +msgid "Unable to find or create trash directory for %s" +msgstr "Ne eblas trovi aÅ­ krei rubujan dosierujon %s" + +#: ../gio/glocalfile.c:2103 +#, fuzzy, c-format +#| msgid "Unable to create trashing info file: %s" +msgid "Unable to create trashing info file for %s: %s" +msgstr "Ne eblas krei trashinfo-dosieron %s: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Ne eblas forÅovi dosieron %s al rubujo" + +#: ../gio/glocalfile.c:2166 ../gio/glocalfile.c:2222 +#, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s: %s" +msgstr "Ne eblas forigi dosieron %s: %s" + +#: ../gio/glocalfile.c:2228 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s" +msgstr "Ne eblas forÅovi dosieron %s al rubujo" + +#: ../gio/glocalfile.c:2254 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory %s: %s" +msgstr "Eraro dum kreo de la dosierujo '%s': %s" + +#: ../gio/glocalfile.c:2283 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Dosiersistemo ne subtenas simbolajn ligilojn" + +#: ../gio/glocalfile.c:2286 +#, c-format +#| msgid "Error making symbolic link: %s" +msgid "Error making symbolic link %s: %s" +msgstr "Eraro dum kreo de la simbola ligilo %s: %s" + +#: ../gio/glocalfile.c:2292 ../glib/gfileutils.c:2077 +msgid "Symbolic links not supported" +msgstr "Simbolaj ligiloj ne estas subtenataj" + +#: ../gio/glocalfile.c:2347 ../gio/glocalfile.c:2382 ../gio/glocalfile.c:2439 +#, c-format +#| msgid "Error moving file: %s" +msgid "Error moving file %s: %s" +msgstr "Eraro dum movado de la dosiero %s: %s" + +#: ../gio/glocalfile.c:2370 +#, fuzzy +#| msgid "Can't move directory over directory" +msgid "Can’t move directory over directory" +msgstr "Ne eblas movi dosierujon super dosierujo" + +#: ../gio/glocalfile.c:2396 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:971 ../gio/glocalfileoutputstream.c:985 +msgid "Backup file creation failed" +msgstr "Sekurkopia kreado malsukcesis" + +#: ../gio/glocalfile.c:2415 +#, c-format +msgid "Error removing target file: %s" +msgstr "Eraro dum forigo de la celdosiero: %s" + +#: ../gio/glocalfile.c:2429 +msgid "Move between mounts not supported" +msgstr "Movo inter muntoj ne estas subtenata" + +#: ../gio/glocalfile.c:2620 +#, fuzzy, c-format +#| msgid "could not get remote address: %s" +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ne eblas akiri foran adreson %s: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "Atributa valoro devas ne esti NUL-a" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "Nevalida atributa tipo (ĉeno atendata)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "Nevalida etendita atributnomo" + +#: ../gio/glocalfileinfo.c:775 +#, fuzzy, c-format +#| msgid "Error setting extended attribute '%s': %s" +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Eraro dum agordado de la etendita atributo “%sâ€: %s" + +#: ../gio/glocalfileinfo.c:1575 +msgid " (invalid encoding)" +msgstr " (nevalida kodoprezento)" + +#: ../gio/glocalfileinfo.c:1766 ../gio/glocalfileoutputstream.c:803 +#, fuzzy, c-format +#| msgid "Error when getting information for file '%s': %s" +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Eraro dum akiro de informo de dosiero “%sâ€: %s" + +#: ../gio/glocalfileinfo.c:2017 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Eraro dum akiro informo pri dosierpriskribilo: %s" + +#: ../gio/glocalfileinfo.c:2062 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Nevalida atributa tipo (uint32 atendata)" + +#: ../gio/glocalfileinfo.c:2080 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Nevalida atributa tipo (uint64 atendata)" + +#: ../gio/glocalfileinfo.c:2099 ../gio/glocalfileinfo.c:2118 +msgid "Invalid attribute type (byte string expected)" +msgstr "Nevalida atributa tipo (bajta ĉeno atendata)" + +#: ../gio/glocalfileinfo.c:2153 +msgid "Cannot set permissions on symlinks" +msgstr "Ne eblas agordi permesojn sur simbolaj ligiloj" + +#: ../gio/glocalfileinfo.c:2169 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Eraro dum agordado de la permesoj: %s" + +#: ../gio/glocalfileinfo.c:2220 +#, c-format +msgid "Error setting owner: %s" +msgstr "Eraro dum agordado de posedanto: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "symlink must be non-NULL" +msgstr "simligilo devas ne esti NUL-a" + +#: ../gio/glocalfileinfo.c:2253 ../gio/glocalfileinfo.c:2272 +#: ../gio/glocalfileinfo.c:2283 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Eraro dum agordado de simligilo: %s" + +#: ../gio/glocalfileinfo.c:2262 +msgid "Error setting symlink: file is not a symlink" +msgstr "Eraro dum agordado de simligilo: dosiero ne estas simligilo" + +#: ../gio/glocalfileinfo.c:2388 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Eraro dum agordado de modifaĵo aÅ­ alira horo: %s" + +#: ../gio/glocalfileinfo.c:2411 +msgid "SELinux context must be non-NULL" +msgstr "SELinuksa kunteksto devas ne esti NUL-a" + +#: ../gio/glocalfileinfo.c:2426 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Eraro dum agordado de la SELinuksa kunteksto: %s" + +#: ../gio/glocalfileinfo.c:2433 +msgid "SELinux is not enabled on this system" +msgstr "SELinux ne estas enÅaltita sur ĉi tiu sistemo" + +#: ../gio/glocalfileinfo.c:2525 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Agordi atributon %s ne subtenita" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "Eraro dum legado de la dosiero: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1003 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Eraro dum serĉo en la dosiero: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "Eraro dum fermado de la dosiero: %s" + +#: ../gio/glocalfilemonitor.c:840 +msgid "Unable to find default local file monitor type" +msgstr "Ne eblas trovi defaÅ­ltan tipon de loka dosiera monitoro" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "Eraro dum skribado de la dosiero: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Eraro dum forigo de la malnova sekurkopia ligilo: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Eraro dum kreado de sekurkopio: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Eraro dum alinomo de la provizora dosiero: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1054 +#, c-format +msgid "Error truncating file: %s" +msgstr "Eraro dum trunko de la dosiero: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1035 ../gio/gsubprocess.c:360 +#, fuzzy, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file “%sâ€: %s" +msgstr "Eraro dum malfermo de la dosiero “%sâ€: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "Celdosiero estas dosierujo" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "Celdosiero ne estas regula dosiero" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "La dosiero estis ekstere modifita" + +#: ../gio/glocalfileoutputstream.c:1019 +#, c-format +msgid "Error removing old file: %s" +msgstr "Eraro dum forigo de la malnova dosiero: %s" + +#: ../gio/gmemoryinputstream.c:474 ../gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Nevalida GSeekType liverita" + +#: ../gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Nevalida serĉpeto" + +#: ../gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ne eblas trunki GMemoryInputStream-on" + +#: ../gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Grando de memoro-eliga fluo ne estas ÅanÄebla" + +#: ../gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Malsuksesis ÅanÄi la grandon de memoro-eliga fluo" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Sumo de memoro kiu estas bezonata por trakti de la skribo estas pli granda " +"ol havebla adresa spaco" + +#: ../gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Petita enpozicigo antaÅ­ la komencon de la fluo" + +#: ../gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Petita serĉ-loko estas preter la finon de la fluo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +#, fuzzy +#| msgid "mount doesn't implement \"unmount\"" +msgid "mount doesn’t implement “unmountâ€" +msgstr "munto ne realigas “unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +#, fuzzy +#| msgid "mount doesn't implement \"eject\"" +msgid "mount doesn’t implement “ejectâ€" +msgstr "munto ne realigas “ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +#, fuzzy +#| msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "munto ne realigas “unmount†aÅ­ “unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +#, fuzzy +#| msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "munto ne realigas “eject†aÅ­ “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +#, fuzzy +#| msgid "mount doesn't implement \"remount\"" +msgid "mount doesn’t implement “remountâ€" +msgstr "munto ne realigas \"remount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +#, fuzzy +#| msgid "mount doesn't implement content type guessing" +msgid "mount doesn’t implement content type guessing" +msgstr "munto ne realigas konjektanta de enhava tipo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +#, fuzzy +#| msgid "mount doesn't implement synchronous content type guessing" +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "munto ne realigas konjektadon pri enhava tipo sinkrone" + +#: ../gio/gnetworkaddress.c:378 +#, fuzzy, c-format +#| msgid "Hostname '%s' contains '[' but not ']'" +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Gastiga komputilnomo '%s' havas '[' sed ne ']'" + +#: ../gio/gnetworkmonitorbase.c:206 ../gio/gnetworkmonitorbase.c:310 +msgid "Network unreachable" +msgstr "Loka reto estas ne kontaktebla" + +#: ../gio/gnetworkmonitorbase.c:244 ../gio/gnetworkmonitorbase.c:274 +msgid "Host unreachable" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ne eblas krei retmonitoron: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "Ne eblas krei retmonitoron: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "Ne eblas akiri restaton: " + +#: ../gio/gnetworkmonitornm.c:329 +#, c-format +msgid "NetworkManager version too old" +msgstr "" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:560 +#, fuzzy +#| msgid "Output stream doesn't implement write" +msgid "Output stream doesn’t implement write" +msgstr "Eliga fluo ne realigas skribon" + +#: ../gio/goutputstream.c:521 ../gio/goutputstream.c:1224 +msgid "Source stream is already closed" +msgstr "Fontfluo jam estas fermita" + +#: ../gio/gresolver.c:342 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, fuzzy, c-format +#| msgid "Error resolving '%s': %s" +msgid "Error resolving “%sâ€: %s" +msgstr "Eraro dum serĉo '%s': %s" + +#: ../gio/gresource.c:595 ../gio/gresource.c:846 ../gio/gresource.c:863 +#: ../gio/gresource.c:987 ../gio/gresource.c:1059 ../gio/gresource.c:1132 +#: ../gio/gresource.c:1202 ../gio/gresourcefile.c:453 +#: ../gio/gresourcefile.c:576 ../gio/gresourcefile.c:713 +#, fuzzy, c-format +#| msgid "The resource at '%s' does not exist" +msgid "The resource at “%s†does not exist" +msgstr "La risurco ĉe '%s' ne ekzistas" + +#: ../gio/gresource.c:760 +#, fuzzy, c-format +#| msgid "The resource at '%s' is not a directory" +msgid "The resource at “%s†failed to decompress" +msgstr "La risurco ĉe '%s' ne estas dosierujo" + +#: ../gio/gresourcefile.c:709 +#, fuzzy, c-format +#| msgid "The resource at '%s' is not a directory" +msgid "The resource at “%s†is not a directory" +msgstr "La risurco ĉe '%s' ne estas dosierujo" + +#: ../gio/gresourcefile.c:917 +#, fuzzy +#| msgid "Input stream doesn't implement seek" +msgid "Input stream doesn’t implement seek" +msgstr "Eniga fluo ne realigas serĉon" + +#: ../gio/gresource-tool.c:494 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: ../gio/gresource-tool.c:500 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: ../gio/gresource-tool.c:503 ../gio/gresource-tool.c:513 +msgid "FILE [PATH]" +msgstr "DOSIERO [VOJO]" + +#: ../gio/gresource-tool.c:504 ../gio/gresource-tool.c:514 +#: ../gio/gresource-tool.c:521 +msgid "SECTION" +msgstr "SEKCIO" + +#: ../gio/gresource-tool.c:509 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: ../gio/gresource-tool.c:519 +msgid "Extract a resource file to stdout" +msgstr "Eltiri risurcan dosieron al 'stdout'" + +#: ../gio/gresource-tool.c:520 +msgid "FILE PATH" +msgstr "DOSIERA VOJO" + +#: ../gio/gresource-tool.c:534 +#, fuzzy +#| msgid "" +#| "Usage:\n" +#| " gresource [--section SECTION] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " sections List resource sections\n" +#| " list List resources\n" +#| " details List resources with details\n" +#| " extract Extract a resource\n" +#| "\n" +#| "Use 'gresource help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uzo:\n" +" gresource [--section SEKCIO] KOMANDO [ARGUMENTOJ...]\n" +"\n" +"Komandoj:\n" +" helpo Montri ĉi tiun informon\n" +" sections Listigi risurcan sekciojn\n" +" list Listigi risurcojn\n" +" details Listigi risurcojn kun detaloj\n" +" extract Eltiri risurcon\n" +"\n" +"Uzu 'gresource help KOMANDO' por akiri helpon detale.\n" +"\n" + +#: ../gio/gresource-tool.c:548 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uzo:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:555 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEKCIO (laÅ­vola) nomo de elf-a sekcio\n" + +#: ../gio/gresource-tool.c:559 ../gio/gsettings-tool.c:654 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMANDO La (laÅ­vola) komando por klarigi\n" + +#: ../gio/gresource-tool.c:565 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: ../gio/gresource-tool.c:568 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: ../gio/gresource-tool.c:572 +msgid "[PATH]" +msgstr "[VOJO]" + +#: ../gio/gresource-tool.c:574 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " VOJO (laÅ­vola) vojo de risurco (eble parta)\n" + +#: ../gio/gresource-tool.c:575 +msgid "PATH" +msgstr "VOJO" + +#: ../gio/gresource-tool.c:577 +msgid " PATH A resource path\n" +msgstr " VOJO vojo de risurco\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#: ../gio/gsettings-tool.c:851 +#, fuzzy, c-format +#| msgid "No such schema '%s'\n" +msgid "No such schema “%sâ€\n" +msgstr "Neniu tia skemo '%s'\n" + +#: ../gio/gsettings-tool.c:57 +#, fuzzy, c-format +#| msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Skemo '%s' ne estas translokigebla (vojo devas ne esti specifita)\n" + +#: ../gio/gsettings-tool.c:78 +#, fuzzy, c-format +#| msgid "Schema '%s' is relocatable (path must be specified)\n" +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Skemo '%s' estas translokigebla (vojo devas esti specifita)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "Malplena vojo estis donita.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "Vojo devas komenciÄi per oblikvo (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "Vojo devas finiÄi per oblikvo (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Vojo devas ne havi du apudajn oblikvojn (//)\n" + +#: ../gio/gsettings-tool.c:489 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "La valoro provizita estas preter la valida intervalo\n" + +#: ../gio/gsettings-tool.c:496 +#, c-format +#| msgid "Property '%s' is not writable" +msgid "The key is not writable\n" +msgstr "La Ålosilo ne estas skribebla\n" + +#: ../gio/gsettings-tool.c:532 +msgid "List the installed (non-relocatable) schemas" +msgstr "Listigi la instalitajn (ne translokigeblajn) skemojn" + +#: ../gio/gsettings-tool.c:538 +msgid "List the installed relocatable schemas" +msgstr "Listigi la instalintajn translokiÄeblajn skemojn" + +#: ../gio/gsettings-tool.c:544 +msgid "List the keys in SCHEMA" +msgstr "Listi la Ålosilojn en SKEMO" + +#: ../gio/gsettings-tool.c:545 ../gio/gsettings-tool.c:551 +#: ../gio/gsettings-tool.c:594 +msgid "SCHEMA[:PATH]" +msgstr "SKEMO[:VOJO]" + +#: ../gio/gsettings-tool.c:550 +msgid "List the children of SCHEMA" +msgstr "Listi la idojn de SKEMO" + +#: ../gio/gsettings-tool.c:556 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Listi Ålosilojn kaj valorojn, rikure\n" +"Se ne SKEMO estas donita, listi ĉiujn Ålosilojn\n" + +#: ../gio/gsettings-tool.c:558 +msgid "[SCHEMA[:PATH]]" +msgstr "[SKEMO[:VOJO]]" + +#: ../gio/gsettings-tool.c:563 +msgid "Get the value of KEY" +msgstr "Akiri la valoron de ÅœLOSILO" + +#: ../gio/gsettings-tool.c:564 ../gio/gsettings-tool.c:570 +#: ../gio/gsettings-tool.c:576 ../gio/gsettings-tool.c:588 +#: ../gio/gsettings-tool.c:600 +msgid "SCHEMA[:PATH] KEY" +msgstr "SKEMO[:VOJO] ÅœLOSILO" + +#: ../gio/gsettings-tool.c:569 +msgid "Query the range of valid values for KEY" +msgstr "Informpeti la intervalon de validaj valoroj por ÅœLOSILO" + +#: ../gio/gsettings-tool.c:575 +#, fuzzy +#| msgid "Query the range of valid values for KEY" +msgid "Query the description for KEY" +msgstr "Informpeti la intervalon de validaj valoroj por ÅœLOSILO" + +#: ../gio/gsettings-tool.c:581 +msgid "Set the value of KEY to VALUE" +msgstr "Agordi la valoron de ÅœLOSILO al VALORO" + +#: ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SKEMO[:VOJO] ÅœLOSILO VALORO" + +#: ../gio/gsettings-tool.c:587 +msgid "Reset KEY to its default value" +msgstr "ReÅargi ÅœLOSILO-n al Äia defaÅ­lta valoro" + +#: ../gio/gsettings-tool.c:593 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "ReÅargi ĉiujn Ålosilojn en SKEMO al iliaj defaÅ­ltoj" + +#: ../gio/gsettings-tool.c:599 +msgid "Check if KEY is writable" +msgstr "Kontroli ĉu ÅœLOSILO estas skribebla" + +#: ../gio/gsettings-tool.c:605 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Kontroladi ÅœLOSILO-n por ÅanÄoj.\n" +"Se ÅœLOSILO ne estas specifata, kontroladi ĉiujn Ålosilojn en SKEMO.\n" +"Uzu ^C por haltigi kontroladon.\n" + +#: ../gio/gsettings-tool.c:608 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SKEMO[:VOJO] [ÅœLOSILO]" + +#: ../gio/gsettings-tool.c:620 +#, fuzzy +#| msgid "" +#| "Usage:\n" +#| " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " list-schemas List installed schemas\n" +#| " list-relocatable-schemas List relocatable schemas\n" +#| " list-keys List keys in a schema\n" +#| " list-children List children of a schema\n" +#| " list-recursively List keys and values, recursively\n" +#| " range Queries the range of a key\n" +#| " get Get the value of a key\n" +#| " set Set the value of a key\n" +#| " reset Reset the value of a key\n" +#| " reset-recursively Reset all values in a given schema\n" +#| " writable Check if a key is writable\n" +#| " monitor Watch for changes\n" +#| "\n" +#| "Use 'gsettings help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uzo:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] KOMANDO [ARGUMENTOJ...]\n" +"\n" +"Komandoj:\n" +" help Montri ĉi tiu informon\n" +" list-schemas Listi instalitajn skemojn\n" +" list-relocatable-schemas Listi translokigeblajn skemojn\n" +" list-keys Listi Ålosilojn en skemo\n" +" list-children Listi idojn de skemo\n" +" list-recursively Listi Ålosilojn kaj valorojn, rikure\n" +" range Informpetas la intervalon de la Ålosilo\n" +" get Akiri la valoron de Ålosilo\n" +" set Difini la valoron de Ålosilo\n" +" reset RedefaÅ­ltigi la valoron de Ålosilo\n" +" reset-recursively RedefaÅ­ltigi ĉiujn valorojn en donita skemo\n" +" writable Kontroli ĉu Ålosilo estas skribebla\n" +" monitor Kontroladi por ÅanÄoj\n" +"\n" +"Uzu “gsettings help KOMANDO†por akiri helpon detale.\n" +"\n" + +#: ../gio/gsettings-tool.c:644 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uzo:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:650 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR Dosierujo por serĉi pliajn skemojn\n" + +#: ../gio/gsettings-tool.c:658 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SKEMO La nomo de la skemo\n" +" VOJO La vojo, por translokigeblaj skemoj\n" + +#: ../gio/gsettings-tool.c:663 +msgid " KEY The (optional) key within the schema\n" +msgstr " ÅœLOSILO La (laÅ­vola) Ålosilo interne de la skemo\n" + +#: ../gio/gsettings-tool.c:667 +msgid " KEY The key within the schema\n" +msgstr " ÅœLOSILO La Ålosilo interne de la skemo\n" + +#: ../gio/gsettings-tool.c:671 +msgid " VALUE The value to set\n" +msgstr " VALUE La valoro agordota\n" + +#: ../gio/gsettings-tool.c:726 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not load schemas from %s: %s\n" +msgstr "Ne eblas ÅarÄi skemon de %s: %s\n" + +#: ../gio/gsettings-tool.c:738 +#, c-format +#| msgid "No schema files found: " +msgid "No schemas installed\n" +msgstr "Neniuj skemo instalita\n" + +#: ../gio/gsettings-tool.c:809 +#, c-format +msgid "Empty schema name given\n" +msgstr "Malplena skemo-nomo donita\n" + +#: ../gio/gsettings-tool.c:864 +#, fuzzy, c-format +#| msgid "No such key '%s'\n" +msgid "No such key “%sâ€\n" +msgstr "Neniu tia Ålosilo '%s'\n" + +#: ../gio/gsocket.c:369 +msgid "Invalid socket, not initialized" +msgstr "Nevalida kontaktskatolo, ne pravalorizita" + +#: ../gio/gsocket.c:376 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Nevalida kontaktskatolo, pravalorizo malsukcesis pro: %s" + +#: ../gio/gsocket.c:384 +msgid "Socket is already closed" +msgstr "Kontaktskatolo estas jam fermita" + +#: ../gio/gsocket.c:399 ../gio/gsocket.c:2754 ../gio/gsocket.c:3939 +#: ../gio/gsocket.c:3995 +msgid "Socket I/O timed out" +msgstr "Kontaktoskatolo I/O eltempiÄis" + +#: ../gio/gsocket.c:531 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "kreanta GSocket de fd: %s" + +#: ../gio/gsocket.c:559 ../gio/gsocket.c:613 ../gio/gsocket.c:620 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ne eblas krei kontaktskatolon: %s" + +#: ../gio/gsocket.c:613 +#, fuzzy +#| msgid "Unknown protocol was specified" +msgid "Unknown family was specified" +msgstr "Nekonata protokolo estis specifita" + +#: ../gio/gsocket.c:620 +msgid "Unknown protocol was specified" +msgstr "Nekonata protokolo estis specifita" + +#: ../gio/gsocket.c:1111 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: ../gio/gsocket.c:1128 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: ../gio/gsocket.c:1932 +#, c-format +msgid "could not get local address: %s" +msgstr "ne eblas akiri lokan adreson: %s" + +#: ../gio/gsocket.c:1975 +#, c-format +msgid "could not get remote address: %s" +msgstr "ne eblas akiri foran adreson: %s" + +#: ../gio/gsocket.c:2041 +#, c-format +msgid "could not listen: %s" +msgstr "ne eblas aÅ­skulti: %s" + +#: ../gio/gsocket.c:2140 +#, c-format +msgid "Error binding to address: %s" +msgstr "Eraro dum bindado al la adreso: %s" + +#: ../gio/gsocket.c:2255 ../gio/gsocket.c:2292 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Eraro kunigante plurelsendgrupon: %s" + +#: ../gio/gsocket.c:2256 ../gio/gsocket.c:2293 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Eraro lasante plurelsendgrupon: %s" + +#: ../gio/gsocket.c:2257 +msgid "No support for source-specific multicast" +msgstr "Neniu subteno por fontspecifa plurelsendgrupo" + +#: ../gio/gsocket.c:2477 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Eraro dum akcepto de la konekto: %s" + +#: ../gio/gsocket.c:2598 +msgid "Connection in progress" +msgstr "Farata konektado" + +#: ../gio/gsocket.c:2647 +#| msgid "Unable to get pending error: %s" +msgid "Unable to get pending error: " +msgstr "Ne eblas akiri okazontan eraron: " + +#: ../gio/gsocket.c:2817 +#, c-format +msgid "Error receiving data: %s" +msgstr "Eraro dum ricevo de la datumaro: %s" + +#: ../gio/gsocket.c:3012 +#, c-format +msgid "Error sending data: %s" +msgstr "Eraro dum sendado de la datumaro: %s" + +#: ../gio/gsocket.c:3199 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ne eblas fermi kontaktskatolon: %s" + +#: ../gio/gsocket.c:3280 +#, c-format +msgid "Error closing socket: %s" +msgstr "Eraro malfermi kontaktskatolon: %s" + +#: ../gio/gsocket.c:3932 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Atendanta kontaktskatolon kondiĉon: %s" + +#: ../gio/gsocket.c:4404 ../gio/gsocket.c:4484 ../gio/gsocket.c:4662 +#, c-format +msgid "Error sending message: %s" +msgstr "Eraro dum sendado de la mesaÄo: %s" + +#: ../gio/gsocket.c:4428 +#, fuzzy +#| msgid "GSocketControlMessage not supported on windows" +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage ne estas subternata sur Vindozo" + +#: ../gio/gsocket.c:4881 ../gio/gsocket.c:4954 ../gio/gsocket.c:5180 +#, c-format +msgid "Error receiving message: %s" +msgstr "Eraro dum ricevo de la mesaÄo: %s" + +#: ../gio/gsocket.c:5452 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to read socket credentials: %s" +msgstr "Ne eblas krei kontaktskatolon: %s" + +#: ../gio/gsocket.c:5461 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials ne realigita por ĉi tiu mastruma sistemo" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ne eblis konekti al prokura servilo %s: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ne eblis konekti al %s: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "Ne eblis konekti: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "Nekonata eraro okazis je konektado" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +#, fuzzy +#| msgid "Trying to proxy over non-TCP connection is not supported." +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Provo prokuri tra ne-TCP-a konekto ne estas subtenata." + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, fuzzy, c-format +#| msgid "Proxy protocol '%s' is not supported." +msgid "Proxy protocol “%s†is not supported." +msgstr "Prokura protokolo “%s†ne estas subtenata." + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "AÅ­skultilo estas jam fermita" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "Aldonita kontaktskatolo estas fermita" + +#: ../gio/gsocks4aproxy.c:118 +#, fuzzy, c-format +#| msgid "SOCKSv4 does not support IPv6 address '%s'" +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 ne subtenas IPv6-an adreson “%sâ€" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Uzantonomo estas tro longa por SOCKSv4-protokolo" + +#: ../gio/gsocks4aproxy.c:153 +#, fuzzy, c-format +#| msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Gastiga komputilonomo “%s†estas tro longa por SOCKSv4-protokolo" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "La servilo ne estas SOCKSv4-prokura servilo." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Konekto tra SOCKSv4-servilo malakceptiÄis" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "La servilo ne estas SOCKSv5-prokura servilo." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "La SOCKSv5-prokurilo bezonas aÅ­tentokontrolon." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"La SOCKSv5-prokurilo benzonas aÅ­tentokontrolan metodon ke ne estas subtenita " +"per GLib." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Uzantonomo aÅ­ pasvorto estas tro longa por SOCKSv5-protokolo." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5-aÅ­tentokontrolo malsukcesis pro erara uzantonomo aÅ­ pasvorto." + +#: ../gio/gsocks5proxy.c:286 +#, fuzzy, c-format +#| msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Gastiga komputilonomo “%s†estas tro longa por SOCKSv5-protokolo" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "La SOCKSv5-prokura servilo uzas adrestipon kiu estas nekonata." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Interna SOCKSv5-prokur-servila eraro." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5-konekto ne estas permesita laÅ­ servila agordo." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Gastiga komputilo estas ne kontaktebla per SOCKSv5-servilo." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Loka reto estas ne kontaktebla per SOCKSv5-prokurilo." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Konekto ne estis akceptita per SOCKv5 prokurilo." + +#: ../gio/gsocks5proxy.c:386 +#, fuzzy +#| msgid "SOCKSv5 proxy does not support 'connect' command." +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Komando “connect†ne estas subtenata de SOCKSv5-prokurilo." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Provizita adrestipo ne estas subtenata de SOCKSv5-prokurilo." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Nekonata SOCKv5 prokurilo eraro." + +#: ../gio/gthemedicon.c:518 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Ne eblas trakti version %d de GThemedIcon kodoprezento" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "" + +#: ../gio/gthreadedresolver.c:213 +#, fuzzy, c-format +#| msgid "Error reverse-resolving '%s': %s" +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Eraro dum inversa serĉo “%sâ€: %s" + +#: ../gio/gthreadedresolver.c:550 ../gio/gthreadedresolver.c:630 +#: ../gio/gthreadedresolver.c:728 ../gio/gthreadedresolver.c:778 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: ../gio/gthreadedresolver.c:555 ../gio/gthreadedresolver.c:733 +#, fuzzy, c-format +#| msgid "Temporarily unable to resolve '%s'" +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Ne eblas solvi “%s†provizore" + +#: ../gio/gthreadedresolver.c:560 ../gio/gthreadedresolver.c:738 +#, fuzzy, c-format +#| msgid "Error resolving '%s'" +msgid "Error resolving “%sâ€" +msgstr "Eraro dum solvado de “%sâ€" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ne eblas malĉifri PEM-kodigitan privatan Ålosilon" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "Neniu PEM-kodigita privata Ålosilo trovita" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "Ne eblas analizi PEM-kodigitan privatan Ålosilon" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "Neniu PEM-kodigita atestilo trovita" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ne eblas analizi PEM-kodigitan atestilon" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ĉi tiu estas la fina ebleco enigi la pasvorton Äuste antaÅ­ ol via aliro " +"estos barita." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: ../gio/gtlspassword.c:115 +#, fuzzy +#| msgid "" +#| "Several password entered have been incorrect, and your access will be " +#| "locked out after further failures." +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Kelkaj eraraj pasvortoj enigitaj, kaj via aliro estos barita se pliaj " +"malsukcesoj okazos." + +#: ../gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "La pasvorto enigita estas ne korekta." + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:561 +#, fuzzy, c-format +#| msgid "Expecting 1 control message, got %d" +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Atendita 1 stirmesaÄo, akirita %d" +msgstr[1] "Atendita 1 stirmesaÄo, akirita %d" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:573 +msgid "Unexpected type of ancillary data" +msgstr "Ne atendita tipo de helpa datumaro" + +#: ../gio/gunixconnection.c:200 +#, fuzzy, c-format +#| msgid "Expecting one fd, but got %d\n" +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Atendita unu fd, sed akirita %d\n" +msgstr[1] "Atendita unu fd, sed akirita %d\n" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Akirita ne valida fd" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "Eraro dum sendo de la akreditaĵoj: " + +#: ../gio/gunixconnection.c:503 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"Eraro kontrolanta ĉu SO_PASSCRED estas enÅaltita por kontaktskatolo: %s" + +#: ../gio/gunixconnection.c:518 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Eraro dum enÅalto de SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:547 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Atendanta legi unuopan bajton por ricevi akreditaĵojn sed legis neniom da " +"bajtoj" + +#: ../gio/gunixconnection.c:587 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ne atendanta stirmesaÄon, sed akiris %d" + +#: ../gio/gunixconnection.c:611 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Eraro dum elÅalto de SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:369 ../gio/gunixinputstream.c:390 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Eraro dum legado de la dosiernumero: %s" + +#: ../gio/gunixinputstream.c:423 ../gio/gunixoutputstream.c:409 +#: ../gio/gwin32inputstream.c:217 ../gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Eraro dum fermado de la dosiernumero: %s" + +#: ../gio/gunixmounts.c:2422 ../gio/gunixmounts.c:2475 +msgid "Filesystem root" +msgstr "Dosiersistema radiko" + +#: ../gio/gunixoutputstream.c:355 ../gio/gunixoutputstream.c:376 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Eraro dum skribado de la dosiernumero: %s" + +#: ../gio/gunixsocketaddress.c:241 +#, fuzzy +#| msgid "Abstract unix domain socket addresses not supported on this system" +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Abstraktaj uniksoretregionaj kontaktoskatolaj adresoj ne estas subtenataj " +"sur ĉi tiu sistemo" + +#: ../gio/gvolume.c:437 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "volume doesn’t implement eject" +msgstr "datumportilo ne realigas eject-an funkcion" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "datumportilo ne realigas eject-an aÅ­ eject_with_operation-an funkciojn" + +#: ../gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Eraro dum lego de dosiernumero: %s" + +#: ../gio/gwin32inputstream.c:232 ../gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Eraro dum fermo de dosiernumero: %s" + +#: ../gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Eraro dum skribo al dosiernumero: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Memoro ne sufiĉas" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Interna eraro: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Bezonas pli da enigo" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Nevalida densigita datumaro" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:20 +#, fuzzy +#| msgid "Print help" +msgid "Print address" +msgstr "Presi helpon" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "" + +#: ../glib/gbookmarkfile.c:754 +#, fuzzy, c-format +#| msgid "Unexpected attribute '%s' for element '%s'" +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Neatendita atributo “%s†pri elemento “%sâ€" + +#: ../glib/gbookmarkfile.c:765 ../glib/gbookmarkfile.c:836 +#: ../glib/gbookmarkfile.c:846 ../glib/gbookmarkfile.c:953 +#, fuzzy, c-format +#| msgid "Attribute '%s' of element '%s' not found" +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atributo “%s†de elemento “%s†ne trovita" + +#: ../glib/gbookmarkfile.c:1123 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1252 ../glib/gbookmarkfile.c:1262 +#, fuzzy, c-format +#| msgid "Unexpected tag '%s', tag '%s' expected" +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Etikedo “%s†estas neatendita, etikedo “%s†estas atendita" + +#: ../glib/gbookmarkfile.c:1148 ../glib/gbookmarkfile.c:1162 +#: ../glib/gbookmarkfile.c:1230 +#, fuzzy, c-format +#| msgid "Unexpected tag '%s' inside '%s'" +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Neatendita etikedo “%s†interne de “%sâ€" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "Neniu valida legosigna dosiero estis trovita en datumaj dosierujoj" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +#| msgid "A bookmark for URI '%s' already exists" +msgid "A bookmark for URI “%s†already exists" +msgstr "Legosigno por URI “%s†jam ekzistas" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, fuzzy, c-format +#| msgid "No bookmark found for URI '%s'" +msgid "No bookmark found for URI “%sâ€" +msgstr "Neniu legosigno trovita por URI “%sâ€" + +#: ../glib/gbookmarkfile.c:2335 +#, fuzzy, c-format +#| msgid "No MIME type defined in the bookmark for URI '%s'" +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Neniu MIME-tipo estas difinita en la legosigno por URI “%sâ€" + +#: ../glib/gbookmarkfile.c:2420 +#, fuzzy, c-format +#| msgid "No private flag has been defined in bookmark for URI '%s'" +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Neniu privata flago estis difinita en legosigno por URI “%sâ€" + +#: ../glib/gbookmarkfile.c:2799 +#, fuzzy, c-format +#| msgid "No groups set in bookmark for URI '%s'" +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Neniuj grupoj agorditaj en legosigno por URI-o “%sâ€" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, fuzzy, c-format +#| msgid "No application with name '%s' registered a bookmark for '%s'" +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Neniu aplikaĵo kun nomo “%s†registris legosignon por “%sâ€" + +#: ../glib/gbookmarkfile.c:3377 +#, fuzzy, c-format +#| msgid "Failed to expand exec line '%s' with URI '%s'" +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Malsukcesis ekspansii plenuman linion '%s' per URI '%s'" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:852 ../glib/gutf8.c:1064 +#: ../glib/gutf8.c:1201 ../glib/gutf8.c:1305 +msgid "Partial character sequence at end of input" +msgstr "Parta karaktrosekvenco ĉe enigofino" + +#: ../glib/gconvert.c:742 +#, fuzzy, c-format +#| msgid "Cannot convert fallback '%s' to codeset '%s'" +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Ne eblas konverti la retrodefaÅ­lton '%s' al kodaro '%s'" + +#: ../glib/gconvert.c:1513 +#, fuzzy, c-format +#| msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "La URI '%s' ne estas absolutan URI uzanta la \"file\"-skemon" + +#: ../glib/gconvert.c:1523 +#, fuzzy, c-format +#| msgid "The local file URI '%s' may not include a '#'" +msgid "The local file URI “%s†may not include a “#â€" +msgstr "La loka dosiera URI '%s' devas ne havi la '#'" + +#: ../glib/gconvert.c:1540 +#, fuzzy, c-format +#| msgid "The URI '%s' is invalid" +msgid "The URI “%s†is invalid" +msgstr "La URI '%s' estas nevalida" + +#: ../glib/gconvert.c:1552 +#, fuzzy, c-format +#| msgid "The hostname of the URI '%s' is invalid" +msgid "The hostname of the URI “%s†is invalid" +msgstr "La gastiga komputilnomo de la URI '%s' ne estas valida" + +#: ../glib/gconvert.c:1568 +#, fuzzy, c-format +#| msgid "The URI '%s' contains invalidly escaped characters" +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "La URI '%s' havas karaktrojn kiuj estas eskapataj nevalide" + +#: ../glib/gconvert.c:1640 +#, fuzzy, c-format +#| msgid "The pathname '%s' is not an absolute path" +msgid "The pathname “%s†is not an absolute path" +msgstr "La vojnomo '%s' ne estas absoluta vojo" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %b %e %H:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%F" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:208 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:211 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:224 +msgctxt "full month name" +msgid "January" +msgstr "januaro" + +#: ../glib/gdatetime.c:226 +msgctxt "full month name" +msgid "February" +msgstr "februaro" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "March" +msgstr "marto" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "April" +msgstr "aprilo" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "May" +msgstr "majo" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "June" +msgstr "junio" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "July" +msgstr "julio" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "August" +msgstr "aÅ­gusto" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "September" +msgstr "septembro" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "October" +msgstr "oktobro" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "November" +msgstr "novembro" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "December" +msgstr "decembro" + +#: ../glib/gdatetime.c:261 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "jan" + +#: ../glib/gdatetime.c:263 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "apr" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "May" +msgstr "maj" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jun" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jul" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "aÅ­g" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "sep" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "okt" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "dec" + +#: ../glib/gdatetime.c:298 +msgctxt "full weekday name" +msgid "Monday" +msgstr "lundo" + +#: ../glib/gdatetime.c:300 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "mardo" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "merkredo" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ĵaÅ­do" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Friday" +msgstr "vendredo" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sabato" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "dimanĉo" + +#: ../glib/gdatetime.c:325 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "lun" + +#: ../glib/gdatetime.c:327 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "mar" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "mer" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ĵaÅ­" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ven" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sab" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "dim" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:354 +msgctxt "GDateTime" +msgid "AM" +msgstr "ATM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:357 +msgctxt "GDateTime" +msgid "PM" +msgstr "PTM" + +#: ../glib/gdir.c:155 +#, fuzzy, c-format +#| msgid "Error opening directory '%s': %s" +msgid "Error opening directory “%sâ€: %s" +msgstr "Eraro dum malfermado de la dosierujo '%s': %s" + +#: ../glib/gfileutils.c:706 ../glib/gfileutils.c:798 +#, fuzzy, c-format +#| msgid "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ne eblis akiri %lu bajtojn por legi la dosieron \"%s\"" +msgstr[1] "Ne eblis akiri %lu bajtojn por legi la dosieron \"%s\"" + +#: ../glib/gfileutils.c:723 +#, fuzzy, c-format +#| msgid "Error reading file %s: %s" +msgid "Error reading file “%sâ€: %s" +msgstr "Eraro dum legado de la dosiero %s: %s" + +#: ../glib/gfileutils.c:759 +#, fuzzy, c-format +#| msgid "File \"%s\" is too large" +msgid "File “%s†is too large" +msgstr "Dosiero \"%s\" estas tro granda" + +#: ../glib/gfileutils.c:823 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to read from file “%sâ€: %s" +msgstr "Malsukcesis legi el dosiero '%s': %s" + +#: ../glib/gfileutils.c:871 ../glib/gfileutils.c:943 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': %s" +msgid "Failed to open file “%sâ€: %s" +msgstr "Malsukcesis malfermi dosieron '%s': %s" + +#: ../glib/gfileutils.c:883 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Malsukcesis akiri atributojn de dosiero '%s': fstat() malsukcesis: %s" + +#: ../glib/gfileutils.c:913 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': fdopen() failed: %s" +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Malsukcesis malfermi dosieron '%s': fdopen() malsukcesis: %s" + +#: ../glib/gfileutils.c:1012 +#, fuzzy, c-format +#| msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Malsukcesis alinomi dosieron de '%s' al '%s': g_rename() malsukcesis: %s" + +#: ../glib/gfileutils.c:1047 ../glib/gfileutils.c:1554 +#, fuzzy, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to create file “%sâ€: %s" +msgstr "Malsukcesis krei dosieron '%s': %s" + +#: ../glib/gfileutils.c:1074 +#, c-format +#| msgid "Failed to write file '%s': fwrite() failed: %s" +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Malsukcesis skribi dosieron “%sâ€: write() malsukcesis: %s" + +#: ../glib/gfileutils.c:1117 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': fsync() failed: %s" +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Skribi dosieron malsukcesis '%s': fsync() malsukcesis: %s" + +#: ../glib/gfileutils.c:1241 +#, fuzzy, c-format +#| msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Ne eblas forigi ekzistatan dosieron '%s': g_unlink() malsukcesis: %s" + +#: ../glib/gfileutils.c:1520 +#, fuzzy, c-format +#| msgid "Template '%s' invalid, should not contain a '%s'" +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Åœablono '%s' ne estas valida, Äi devas ne havi '%s'" + +#: ../glib/gfileutils.c:1533 +#, fuzzy, c-format +#| msgid "Template '%s' doesn't contain XXXXXX" +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Åœablono '%s' ne havas XXXXXX" + +#: ../glib/gfileutils.c:2058 +#, fuzzy, c-format +#| msgid "Failed to read the symbolic link '%s': %s" +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Malsukcesis legi la simbolan ligilon '%s': %s" + +#: ../glib/giochannel.c:1388 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s': %s" +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Ne eblis malfermi konvertilon de '%s al '%s: %s" + +#: ../glib/giochannel.c:1733 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_line_string" +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Ne eblas fari krudan legon en g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1780 ../glib/giochannel.c:2038 +#: ../glib/giochannel.c:2125 +msgid "Leftover unconverted data in read buffer" +msgstr "Kroma nekonvertita datumaro en legbufro" + +#: ../glib/giochannel.c:1861 ../glib/giochannel.c:1938 +msgid "Channel terminates in a partial character" +msgstr "Kanalo finas per parta karaktro" + +#: ../glib/giochannel.c:1924 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_to_end" +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Ne eblas fari krudan legon en g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:736 +msgid "Valid key file could not be found in search dirs" +msgstr "Valida Ålosilodosiero ne povas esti trovita en serĉaj dosierujoj" + +#: ../glib/gkeyfile.c:772 +msgid "Not a regular file" +msgstr "Ne estas regula dosiero" + +#: ../glib/gkeyfile.c:1212 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains line '%s' which is not a key-value pair, group, or " +#| "comment" +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Åœlosilodosiero havas linion '%s' kiu ne estas Ålosilo-valoro paro, grupo, aÅ­ " +"komento" + +#: ../glib/gkeyfile.c:1269 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nevalida grupa nomo: %s" + +#: ../glib/gkeyfile.c:1291 +msgid "Key file does not start with a group" +msgstr "Åœlosilodosiero ne komenciÄas per grupo" + +#: ../glib/gkeyfile.c:1317 +#, c-format +msgid "Invalid key name: %s" +msgstr "Nevalida Ålosilonomo: %s" + +#: ../glib/gkeyfile.c:1344 +#, fuzzy, c-format +#| msgid "Key file contains unsupported encoding '%s'" +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Åœlosilodosiero havas nesubtenatan kodoprezenton '%s'" + +#: ../glib/gkeyfile.c:1587 ../glib/gkeyfile.c:1760 ../glib/gkeyfile.c:3140 +#: ../glib/gkeyfile.c:3203 ../glib/gkeyfile.c:3333 ../glib/gkeyfile.c:3463 +#: ../glib/gkeyfile.c:3607 ../glib/gkeyfile.c:3836 ../glib/gkeyfile.c:3903 +#, fuzzy, c-format +#| msgid "Key file does not have group '%s'" +msgid "Key file does not have group “%sâ€" +msgstr "Åœlosilodosiero ne havas grupon '%s'" + +#: ../glib/gkeyfile.c:1715 +#, fuzzy, c-format +#| msgid "Key file does not have key '%s' in group '%s'" +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Åœlosilodosiero ne havas Ålosilon '%s' en grupo '%s'" + +#: ../glib/gkeyfile.c:1877 ../glib/gkeyfile.c:1993 +#, fuzzy, c-format +#| msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Åœlosildosiero havas Ålosilon '%s' kun valoro '%s' kiu ne estas UTF-8" + +#: ../glib/gkeyfile.c:1897 ../glib/gkeyfile.c:2013 ../glib/gkeyfile.c:2382 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' which has a value that cannot be interpreted." +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "Åœlosildosiero havas Ålosilon '%s' kiu havas neinterpeteblan valoron." + +#: ../glib/gkeyfile.c:2600 ../glib/gkeyfile.c:2969 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' in group '%s' which has a value that cannot be " +#| "interpreted." +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Åœlosilodosiero havas Ålosilon '%s' en grupo '%s' kiu havas neinterpeteblan " +"valoron." + +#: ../glib/gkeyfile.c:2678 ../glib/gkeyfile.c:2755 +#, c-format +#| msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Åœlosilo “%s†en grupo “%s†havas valoron “%s†kie %s estis atendita" + +#: ../glib/gkeyfile.c:4143 +msgid "Key file contains escape character at end of line" +msgstr "Åœlosilodosiero havas kodÅanÄan signon ĉe fino de linio" + +#: ../glib/gkeyfile.c:4165 +#, fuzzy, c-format +#| msgid "Key file contains invalid escape sequence '%s'" +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "La Ålosildosiero havas nevalidan kodÅanÄan sekvencon '%s'" + +#: ../glib/gkeyfile.c:4307 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a number." +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Valoro '%s' neinterpreteblas kiel nombro." + +#: ../glib/gkeyfile.c:4321 +#, fuzzy, c-format +#| msgid "Integer value '%s' out of range" +msgid "Integer value “%s†out of range" +msgstr "Entjera valoro '%s' estas ekster la intervalo" + +#: ../glib/gkeyfile.c:4354 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a float number." +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Valoro '%s' neinterpreteblas kiel glita nombro." + +#: ../glib/gkeyfile.c:4393 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a boolean." +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Valoro '%s' neinterpreteblas kiel bulea." + +#: ../glib/gmappedfile.c:129 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Malsukcesis akiri atributojn de dosiero '%s%s%s%s': fstat() malsukcesis: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Malsukcesis mapigi dosieron %s%s%s%s: mmap() malsukcesis: %s" + +#: ../glib/gmappedfile.c:262 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': open() failed: %s" +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Malsukcesis malfermi dosieron '%s': open() malsukcesis: %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Eraro sur linio %d karaktro %d: " + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Nevalida UTF-8-kodigita teksto en nomo - ne valida '%s'" + +#: ../glib/gmarkup.c:472 +#, c-format +#| msgid "'%s' is not a valid name " +msgid "'%s' is not a valid name" +msgstr "'%s' ne estas valida nomo" + +#: ../glib/gmarkup.c:488 +#, c-format +#| msgid "'%s' is not a valid name: '%c' " +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' ne estas valida nomo: '%c'" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "Eraro sur linio %d: %s" + +#: ../glib/gmarkup.c:675 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Malsukcesis analizi '%-.*s', kiu devus esti cifero en karaktra referenco (" +"ekzemple ê) - la cifero estas eble tro granda" + +#: ../glib/gmarkup.c:687 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Karaktra referenco ne finis per punktokomo; vi verÅajne uzas kaj-signon sen " +"intenco komencigi eron - nuligu kaj-signon kiel &" + +#: ../glib/gmarkup.c:713 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Karaktra referenco '%-.*s' ne enkodigas permesatan karaktron" + +#: ../glib/gmarkup.c:751 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Malplena ento '&;' vidita; validaj entoj estas : & " < > " +"'" + +#: ../glib/gmarkup.c:759 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Ento-nomo '%-.*s' ne estas konata" + +#: ../glib/gmarkup.c:764 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Ento ne finiÄis per punktokomo; vi eble uzis kaj-signon sen intenco " +"komencigi enton - nuligu kaj-signon kiel &" + +#: ../glib/gmarkup.c:1170 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumento devas komenci per elemento (ekz. )" + +#: ../glib/gmarkup.c:1210 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' ne estas valida karaktro post '<' karaktro; Äi ne povas komenci " +"elementan nomon" + +#: ../glib/gmarkup.c:1252 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Malbona karaktro '%s', karaktro '>' atendita por fini la malplena-elementon " +"etikedon '%s'" + +#: ../glib/gmarkup.c:1333 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Malbona karaktro '%s', karaktro '=' estas atendita post atributnomo '%s' de " +"elemento '%s'" + +#: ../glib/gmarkup.c:1374 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Malbona karaktro '%s', '>' aÅ­ '/' estas atendita por fini la komencan " +"etikedon de elemento '%s', aÅ­ laÅ­vole atributon; eble vi uzas nevalidan " +"karaktron en atributnomo" + +#: ../glib/gmarkup.c:1418 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Malbona karaktro '%s', maldekstra citilo estas atendita post la egalsigno " +"kiam donanta valoron por atributo '%s' de elemento '%s'" + +#: ../glib/gmarkup.c:1551 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' ne estas valida karaktro post la fermiga elementnomo '%s'; la permesata " +"karaktro estas '>'" + +#: ../glib/gmarkup.c:1598 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Elemento '%s' estis fermita, neniu elemento estas malferma nun" + +#: ../glib/gmarkup.c:1607 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Elemento '%s' estis fermita, sed la malfermita elemento estas '%s' nun" + +#: ../glib/gmarkup.c:1760 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumento estis malpena aÅ­ Äi havis nur blankspacon" + +#: ../glib/gmarkup.c:1774 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Dokumento finiÄis neatendite tuj post maldekstra angulkrampon '<'" + +#: ../glib/gmarkup.c:1782 ../glib/gmarkup.c:1827 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Dokumento finiÄis neatendite kun elementoj ankoraÅ­ malfermaj - '%s' estis la " +"elemento malfermita laste" + +#: ../glib/gmarkup.c:1790 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokumento finiÄis neatendite, atendis vidi etikedon finiÄanta per dekstra " +"angulkrampo <%s/>" + +#: ../glib/gmarkup.c:1796 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumento finiÄis neatendite interne de elementnomo" + +#: ../glib/gmarkup.c:1802 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumento finiÄis neatendite interne de atributnomo" + +#: ../glib/gmarkup.c:1807 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumento finiÄis neatendite interne de elemento-malfermanta etikedo." + +#: ../glib/gmarkup.c:1813 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokumento finiÄis neatendite post la egalsigno sekvanta atributnomo; neniu " +"atributvaloro" + +#: ../glib/gmarkup.c:1820 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumento finiÄis neatendite dum interne de atributvaloro" + +#: ../glib/gmarkup.c:1836 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Dokumento finiÄis interne de la ferma etikedo por elemento '%s'" + +#: ../glib/gmarkup.c:1842 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokumento finiÄis neatendite interne de komento aÅ­ traktada instrukcio" + +#: ../glib/goption.c:861 +#, fuzzy +#| msgid "[OPTION...]" +msgid "[OPTION…]" +msgstr "[OPCIO...]" + +#: ../glib/goption.c:977 +msgid "Help Options:" +msgstr "Helpaj Opcioj:" + +#: ../glib/goption.c:978 +msgid "Show help options" +msgstr "Montri helpajn opciojn" + +#: ../glib/goption.c:984 +msgid "Show all help options" +msgstr "Montri ĉiujn helpan opciojn" + +#: ../glib/goption.c:1047 +msgid "Application Options:" +msgstr "Aplikaĵaj Opcioj:" + +#: ../glib/goption.c:1049 +#| msgid "Help Options:" +msgid "Options:" +msgstr "Opcioj:" + +#: ../glib/goption.c:1113 ../glib/goption.c:1183 +#, fuzzy, c-format +#| msgid "Cannot parse integer value '%s' for %s" +msgid "Cannot parse integer value “%s†for %s" +msgstr "Ne eblas analizi entjeran valoron '%s' de %s" + +#: ../glib/goption.c:1123 ../glib/goption.c:1191 +#, fuzzy, c-format +#| msgid "Integer value '%s' for %s out of range" +msgid "Integer value “%s†for %s out of range" +msgstr "Entjera valoro '%s' de %s estas ekster la intervalo" + +#: ../glib/goption.c:1148 +#, fuzzy, c-format +#| msgid "Cannot parse double value '%s' for %s" +msgid "Cannot parse double value “%s†for %s" +msgstr "Ne eblas analizi duoblan valoron '%s' de %s" + +#: ../glib/goption.c:1156 +#, fuzzy, c-format +#| msgid "Double value '%s' for %s out of range" +msgid "Double value “%s†for %s out of range" +msgstr "Duobla valoro '%s' de %s estas ekster la intervalo" + +#: ../glib/goption.c:1448 ../glib/goption.c:1527 +#, c-format +msgid "Error parsing option %s" +msgstr "Eraro dum sintaksa analizo de la opcio %s" + +#: ../glib/goption.c:1558 ../glib/goption.c:1671 +#, c-format +msgid "Missing argument for %s" +msgstr "Mankas argumento de %s" + +#: ../glib/goption.c:2132 +#, c-format +msgid "Unknown option %s" +msgstr "Nekonata opcio %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "difektita objekto" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "interna eraro aÅ­ difektita objekto" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "memormanko" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "retrospurada limo estas atingata" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "la modelo havas erojn kiuj ne estas subtenataj por parta kongruado" + +#: ../glib/gregex.c:280 +msgid "internal error" +msgstr "interna eraro" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "retroreferencoj kiel kondiĉoj ne estas subtenataj por parta kongruado" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "rekurslimo atingita" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "nevalida kombinaĵo de novlinioj flagoj" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "malbona deÅovo" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "mallonga utf8" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "nekonata eraro" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ ĉe fino de modelo" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c ĉe fino de modelo" + +#: ../glib/gregex.c:335 +#, fuzzy +#| msgid "unrecognized character follows \\" +msgid "unrecognized character following \\" +msgstr "nerekonata karaktro sekvas \\" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "nombroj neordigitaj en {} kvantoro" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "nombro tro granda en {} kvantoro" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "mankas finiga ] por karaktro-klaso" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "nevalida kodÅanÄa sekvenco en karaktro-klaso" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "intervalo ne ordigita en karaktro-klaso" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "nenio ripetebla" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "neatendita ripeto" + +#: ../glib/gregex.c:360 +#| msgid "unrecognized character after (?" +msgid "unrecognized character after (? or (?-" +msgstr "nekonata karaktro post (? aÅ­ (?-" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX nomitaj klasoj estas subtenataj nur ene de klaso" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "mankas finiga )" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "referenco al ne ekzistanta submodelo" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "manka ) post komento" + +#: ../glib/gregex.c:375 +#, fuzzy +#| msgid "regular expression too large" +msgid "regular expression is too large" +msgstr "regula esprima tro granda" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "malsukcesis akiri memoron" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr ") sen komenca (" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "koda troo" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "nekonata karaktro post (?<" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "retrorigarda aserto ne havas fiksitan longon" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "misformata nombro aÅ­ nomo post (?(" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "kondiĉa grupo havas pli ol du branĉigojn" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "aserto atendata post (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R aÅ­ (?[+-]ciferoj devas esti sekvataj de )" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "nekonata POSIX klasnomo" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "POSIX kunmetigaj elementoj ne estas subtenataj" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "karaktro-valoro en \\x{...} sekvenco estas tro granda" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "nevalida kondiĉo (?(0)" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C ne estas permesata en retrorigarda aserto" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "rikura voko povus iteracii senfine" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "nekonata karaktro post (?P" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "manka finilo en submodela nomo" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "du nomitaj submodeloj havas la saman nomon" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "misformita \\P aÅ­ \\p sekvenco" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "nekonata eco-nomo post \\P aÅ­ \\p" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "submodela nomo estas tro longa (maksimume 32 karaktroj)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "tro multaj nomitaj submodeloj (maksimume 10.000)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "okuma valoro estas pli granda ol \\377" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "troplenigis kompilada laborspaco" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "antaÅ­e kontrolita referencita submodelo ne trovita" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DIFINI grupo havas pli ol unu branĉo" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "nekoheraj NOVLINIO-j opcioj" + +#: ../glib/gregex.c:476 +#, fuzzy +#| msgid "" +#| "\\g is not followed by a braced name or an optionally braced non-zero " +#| "number" +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ne estas sekvata de nomo inter kunigaj krampoj, aÅ­ de nenula nombro " +"malnepre en kunigaj krampoj" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "" + +#: ../glib/gregex.c:492 +#, fuzzy +#| msgid "missing terminator in subpattern name" +msgid "missing subpattern name after (?&" +msgstr "manka finilo en submodela nomo post (?&" + +#: ../glib/gregex.c:495 +#, fuzzy +#| msgid "digit expected" +msgid "digit expected after (?+" +msgstr "cifero atendata post (?+" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: ../glib/gregex.c:501 +#, fuzzy +#| msgid "two named subpatterns have the same name" +msgid "different names for subpatterns of the same number are not allowed" +msgstr "du nomitaj submodeloj havas la saman nomon" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: ../glib/gregex.c:510 +#, fuzzy +#| msgid "" +#| "\\g is not followed by a braced name or an optionally braced non-zero " +#| "number" +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\g ne estas sekvata de nomo inter kunigaj krampoj, aÅ­ de nenula nombro " +"malnepre en kunigaj krampoj" + +#: ../glib/gregex.c:513 +#| msgid "URIs not supported" +msgid "\\N is not supported in a class" +msgstr "\\N ne estas subtenataj en klaso" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: ../glib/gregex.c:522 +#| msgid "character value in \\x{...} sequence is too large" +msgid "character value in \\u.... sequence is too large" +msgstr "karaktro-valoro en \\u.... sekvenco estas tro granda" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1977 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Eraro dum kongruado de regula esprimo %s: %s" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE-biblioteko estas kompilata sen UTF8-subteno" + +#: ../glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE-biblioteko estas kompilata sen UTF8-ecoj-subteno" + +#: ../glib/gregex.c:1328 +#, fuzzy +#| msgid "PCRE library is compiled without UTF8 properties support" +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE-biblioteko estas kompilata sen nekongruaj opcioj" + +#: ../glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Eraro dum optimumigo de regula esprimo %s: %s" + +#: ../glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Eraro dum kompilo de regula esprimo %s ĉe karaktro %d: %s" + +#: ../glib/gregex.c:2413 +#, fuzzy +#| msgid "hexadecimal digit or '}' expected" +msgid "hexadecimal digit or “}†expected" +msgstr "deksusuma cifero aÅ­ '}' atendata" + +#: ../glib/gregex.c:2429 +msgid "hexadecimal digit expected" +msgstr "deksesuma cifero atendata" + +#: ../glib/gregex.c:2469 +#, fuzzy +#| msgid "missing '<' in symbolic reference" +msgid "missing “<†in symbolic reference" +msgstr "mankas '<' en simbola referenco" + +#: ../glib/gregex.c:2478 +msgid "unfinished symbolic reference" +msgstr "nefinita simbola referenco" + +#: ../glib/gregex.c:2485 +msgid "zero-length symbolic reference" +msgstr "nulo-longa simbola referenco" + +#: ../glib/gregex.c:2496 +msgid "digit expected" +msgstr "cifero atendata" + +#: ../glib/gregex.c:2514 +msgid "illegal symbolic reference" +msgstr "malpermesita simbola referenco" + +#: ../glib/gregex.c:2576 +#, fuzzy +#| msgid "stray final '\\'" +msgid "stray final “\\â€" +msgstr "ne bezonata fina '\\'" + +#: ../glib/gregex.c:2580 +msgid "unknown escape sequence" +msgstr "nekonata kodÅanÄa sekvenco" + +#: ../glib/gregex.c:2590 +#, fuzzy, c-format +#| msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Eraro dum sintaksa analizo de anstataÅ­a teksto \"%s\" ĉe karaktro %lu: %s" + +#: ../glib/gshell.c:94 +#, fuzzy +#| msgid "Quoted text doesn't begin with a quotation mark" +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Citata teksto ne komenciÄas per citilo" + +#: ../glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Ne kongrua citilo sur komanda linio aÅ­ alia teksto citis en Åelo" + +#: ../glib/gshell.c:580 +#, fuzzy, c-format +#| msgid "Text ended just after a '\\' character. (The text was '%s')" +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Teksto finiÄis post '\\' karaktron. (La teksto estis '%s')" + +#: ../glib/gshell.c:587 +#, fuzzy, c-format +#| msgid "" +#| "Text ended before matching quote was found for %c. (The text was '%s')" +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Teksto finiÄis antaÅ­ kongrua citilo por %c estis trovita. (La teksto estis " +"'%s')" + +#: ../glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Teksto estis malplena (aÅ­ havis nur blankspacon)" + +#: ../glib/gspawn.c:250 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Malsukcesis legi datumaron de procezido (%s)" + +#: ../glib/gspawn.c:394 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Neatendita eraro en select() dum datumlegado de procezido (%s)" + +#: ../glib/gspawn.c:479 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Neatendita eraro en waitpid() (%s)" + +#: ../glib/gspawn.c:886 ../glib/gspawn-win32.c:1231 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: ../glib/gspawn.c:894 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:901 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:908 +#, c-format +msgid "Child process exited abnormally" +msgstr "" + +#: ../glib/gspawn.c:1313 ../glib/gspawn-win32.c:337 ../glib/gspawn-win32.c:345 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Malsukcesis legi de duktido (%s)" + +#: ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Malsukcesis branĉiÄi (%s)" + +#: ../glib/gspawn.c:1532 ../glib/gspawn-win32.c:368 +#, fuzzy, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to change to directory “%s†(%s)" +msgstr "Malsukcesis ÅanÄi al dosierujo '%s' (%s)" + +#: ../glib/gspawn.c:1542 +#, fuzzy, c-format +#| msgid "Failed to execute child process \"%s\" (%s)" +msgid "Failed to execute child process “%s†(%s)" +msgstr "Malsukcesis plenumi procezidon \"%s\" (%s)" + +#: ../glib/gspawn.c:1552 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Malsukcesis alidirektigi enigon aÅ­ eligon de procezido (%s)" + +#: ../glib/gspawn.c:1561 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Malsukcesis branĉiÄi procezidon (%s)" + +#: ../glib/gspawn.c:1569 +#, fuzzy, c-format +#| msgid "Unknown error executing child process \"%s\"" +msgid "Unknown error executing child process “%sâ€" +msgstr "Nekonata eraro dum plenumanta de la procezido \"%s\"" + +#: ../glib/gspawn.c:1593 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Malsukcesis legi sufiĉe datumaron de pid-duktido (%s)" + +#: ../glib/gspawn-win32.c:281 +msgid "Failed to read data from child process" +msgstr "Malsukesis legi datumaron de procezido" + +#: ../glib/gspawn-win32.c:298 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Malsukcesis krei dukton por komunikado kun procezido (%s)" + +#: ../glib/gspawn-win32.c:374 ../glib/gspawn-win32.c:493 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Malsukcesis plenumi procezidon (%s)" + +#: ../glib/gspawn-win32.c:443 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nevalida programa nomo: %s" + +#: ../glib/gspawn-win32.c:453 ../glib/gspawn-win32.c:720 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Nevalida ĉeno en argument-vektoro ĉe %d: %s" + +#: ../glib/gspawn-win32.c:464 ../glib/gspawn-win32.c:735 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Nevalida ĉeno en medio: %s" + +#: ../glib/gspawn-win32.c:716 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Nevalida kuranta dosierujo: %s" + +#: ../glib/gspawn-win32.c:781 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Malsukcesis plenumi helpan programon (%s)" + +#: ../glib/gspawn-win32.c:995 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Neatendita eraro dum g_io_channel_win32_poll() legado de datumaro de " +"procezido" + +#: ../glib/gstrfuncs.c:3237 ../glib/gstrfuncs.c:3338 +msgid "Empty string is not a number" +msgstr "" + +#: ../glib/gstrfuncs.c:3261 +#, c-format +#| msgid "'%s' is not a valid name " +msgid "“%s†is not a signed number" +msgstr "“%s†ne estas valida numero" + +#: ../glib/gstrfuncs.c:3271 ../glib/gstrfuncs.c:3374 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: ../glib/gstrfuncs.c:3364 +#, c-format +#| msgid "'%s' is not a valid name " +msgid "“%s†is not an unsigned number" +msgstr "“%s†ne estas valida numero" + +#: ../glib/gutf8.c:798 +#| msgid "failed to get memory" +msgid "Failed to allocate memory" +msgstr "Malsukcesis akiri memoron" + +#: ../glib/gutf8.c:931 +msgid "Character out of range for UTF-8" +msgstr "Karaktro estas ekster la intervalo de UTF-8" + +#: ../glib/gutf8.c:1032 ../glib/gutf8.c:1041 ../glib/gutf8.c:1171 +#: ../glib/gutf8.c:1180 ../glib/gutf8.c:1319 ../glib/gutf8.c:1416 +msgid "Invalid sequence in conversion input" +msgstr "Nevalida sekvenco en konverta enigo" + +#: ../glib/gutf8.c:1330 ../glib/gutf8.c:1427 +msgid "Character out of range for UTF-16" +msgstr "Karaktro estas ekster la intervalo de UTF-16" + +#: ../glib/gutils.c:2139 ../glib/gutils.c:2166 ../glib/gutils.c:2272 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajto" +msgstr[1] "%u bajtoj" + +#: ../glib/gutils.c:2145 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2147 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2150 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2153 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2156 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2159 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2172 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2175 ../glib/gutils.c:2290 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2178 ../glib/gutils.c:2295 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2180 ../glib/gutils.c:2300 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2183 ../glib/gutils.c:2305 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2186 ../glib/gutils.c:2310 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2223 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bajto" +msgstr[1] "%s bajtoj" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2285 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "januaro" + +msgctxt "full month name with day" +msgid "February" +msgstr "februaro" + +msgctxt "full month name with day" +msgid "March" +msgstr "marto" + +msgctxt "full month name with day" +msgid "April" +msgstr "aprilo" + +msgctxt "full month name with day" +msgid "May" +msgstr "majo" + +msgctxt "full month name with day" +msgid "June" +msgstr "junio" + +msgctxt "full month name with day" +msgid "July" +msgstr "julio" + +msgctxt "full month name with day" +msgid "August" +msgstr "aÅ­gusto" + +msgctxt "full month name with day" +msgid "September" +msgstr "septembro" + +msgctxt "full month name with day" +msgid "October" +msgstr "oktobro" + +msgctxt "full month name with day" +msgid "November" +msgstr "novembro" + +msgctxt "full month name with day" +msgid "December" +msgstr "decembro" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "maj" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jun" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "jul" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "aÅ­g" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sep" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "Nenormala programfiniÄo dum starto de komanda linio '%s': %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "Komanda linio '%s' elirinta kun nenula elira kodo %d: %s" + +#~ msgid "No such interface" +#~ msgstr "Neniu tia interfaco" + +#~| msgid "Error setting symlink: file is not a symlink" +#~ msgid "Error processing input file with xmllint" +#~ msgstr "Eraro dum traktado de enig-dosiero per 'xmllint'" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Ne eblas trovi defaÅ­ltan tipon de loka dosieruja kontrolado" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Eraro dum alinomo de la dosiero: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Eraro dum malfermo de la dosiero: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Eraro dum kreo de la dosierujo: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "Ne ekzistas servorikordo por '%s'" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Neatendita opciolongo dum kontrolanta ĉu SO_PASSCRED estas enÅaltita por " +#~ "kontaktskatolo. Atendita %d bajtoj, akiras %d" + +#~ msgid "Error launching application: %s" +#~ msgstr "Eraro dum lanĉo de la aplikaĵo: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "asociigaj ÅanÄoj ne subtenitaj en vin32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Asociiga kreado ne subtenita en win32" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Eraro dum legado de la dosiero '%s': %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "" +#~ "Malsukcesis malfermi dosieron '%s' por skribi: fdopen() malsukcesis: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Skribi dosieron malsukcesis '%s': fflush() malsukcesis: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Malsukcesis fermi dosieron '%s': fclose() malsukcesis: %s" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Åœlosilodosiero ne havas Ålosilon '%s'" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "laborspaca limo por malplenaj subĉenoj estas atingitaj" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "kodÅanÄaj sekvencoj kiuj ÅanÄas usklecon (\\l, \\L, \\u, \\U) ne estas " +#~ "permesi ĉi tie" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "ripeto de DIFIN-grupo ne estas permesata" + +#~ msgid "File is empty" +#~ msgstr "Dosiero estas malplena" + +#~ msgid "Error connecting: " +#~ msgstr "Eraro dum la konektado: " + +#~ msgid "Error connecting: %s" +#~ msgstr "Eraro dum konektado: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Eraro legante de unikso: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "Eraro dum fermo de unikson: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Eraro dum skribo al unikso: %s" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "Åœlosilodosiero havas Ålosilon '%s' kiu havas neinterpreteblan valoron." + +#~ msgid "This option will be removed soon." +#~ msgstr "Ĉi tiu opcio estos forigita baldaÅ­." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Eraro dum funkcivoko de stati() sur dosierujo '%s': %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "SOCKSv4 realigo limigas uzantonomon al %i karaktroj" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKSv4a realigo limigas gastiga komputilnomo al %i karaktroj" diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..369b339 --- /dev/null +++ b/po/es.po @@ -0,0 +1,6825 @@ +# translation of glib.HEAD.po to Español +# Spanish translation of glib. +# Copyright (C) 2001, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# José Antonio Salgueiro , 2001. +# Germán Poo Caamaño , 2002. +# Francisco Javier F. Serrador , 2004, 2005, 2006. +# +# +# Jorge González , 2007, 2008, 2009, 2010, 2011, 2012. +# Daniel Mustieles , 2010-2022. +# Daniel Mustieles García , 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-07-12 16:10+0000\n" +"PO-Revision-Date: 2022-08-08 12:20+0200\n" +"Last-Translator: Daniel Mustieles García \n" +"Language-Team: Spanish - Spain \n" +"Language: es_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Gtranslator 42.0\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Todavía no se soporta establecer aplicaciones predeterminadas" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Establecer aplicación como la usada por última vez para el tipo no está " +"soportado" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opciones de GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Mostrar las opciones de GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Entrar en modo de servicio de GApplication (usar desde archivos de servicio " +"de D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Omitir el ID de la aplicación" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Reemplazar la instancia actual en ejecución" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Imprimir ayuda" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMANDO]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Imprimir versión" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Mostrar informacioÌn de la versioÌn y salir" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Listar aplicaciones" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Listar las aplicaciones instalas activables por D-Bus (por archivos .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Lanzar como aplicación" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Lanzar la aplicación (con archivos opcionales que abrir)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [ARCHIVO...]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Activar una acción" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invocar una acción en la aplicación" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACCION [PARÃMETRO]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Listar las acciones disponibles" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"Listar las acciones estáticas para una aplicación (desde el archivo .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMANDO" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "El comando para el que mostrar ayuda detallada" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identificador de la aplicación en formato D-Bus (ej. org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "ARCHIVO" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Nombres de archivos relativos o absolutos, o URI que abrir" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACCIÓN" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "El nombre de la acción a la que invocar" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAÌMETRO" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" +"Parámetro opcionales para la invocación de la acción, en formato GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Comando «%s» desconocido\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Uso:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumentos:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Comandos:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Use «%s help COMANDO» para obtener ayuda detallada.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"el comando %s requiere un ID de aplicación para seguir directamente\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "ID de aplicación no válido: «%s»\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"«%s» no lleva ningún argumento\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "no se pudo conectar a D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "error al enviar el mensaje %s a la aplicación: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "" +"se debe indicar el nombre de la acción después del ID de la aplicación\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nombre de acción no válido: «%s»\n" +"los nombres de las acciones sólo pueden tener caracteres alfanuméricos «-» y " +"«.»\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "error al analizar el parámetro de la acción: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "las acciones aceptan un máximo de un parámetro\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "el comando «list-actions» sólo toma el ID de la aplicación" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "no se puede encontrar un archivo .desktop para la aplicación %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"comando desconocido: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "El valor de conteo pasado a %s es demasiado largo" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "No se permite buscar en el flujo base" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "No se puede truncar GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "El flujo ya se cerró" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "No se soporta el truncado en el flujo base" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Se canceló la operación" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Objeto no válido, no inicializado" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Secuencia multibyte incompleta en la entrada" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "No hay suficiente espacio en el destino" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Hay una secuencia de bytes no válida en la entrada de conversión" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Falló durante la conversión: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "La inicialización cancelable no eestá soportada" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "" +"La conversión desde el conjunto de caracteres «%s» a «%s» no está soportada" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "No se pudo abrir el conversor de «%s» a «%s»" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "tipo %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Tipo desconocido" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "tipo de archivo %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials contiene datos no válidos" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials no está implementado en este SO" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "No existe soporte de GCredentials para su plataforma" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials no contiene un ID de proceso en este SO" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "No se soporta la burla de credenciales en este SO" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Final de flujo inesperadamente prematuro" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Clave «%s» no soportada en la entrada de dirección «%s»" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" +"Combinación del par clave/valor sin sentido en la entrada de dirección «%s»" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"La dirección «%s» no es válida (se necesita exactamente una ruta, carpeta, " +"carpeta temporal o claves abstractas)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Error en la direccioÌn «%s» — el atributo «%s» estaÌ mal formado" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transporte «%s» desconocido o no soportado para la dirección «%s»" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "El elemento de dirección «%s» no contiene dos puntos (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" +"El nombre del transporte en el elemento de dirección «%s» no debe estar vacío" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"El par clave/valor %d, «%s», en el elemento de dirección «%s», no contiene " +"un signo de igual" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"El par clave/valor %d, «%s», en el elemento de dirección «%s», no debe " +"contener una clave vacía" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Error al desescapar la clave o el valor en el par clave/valor %d, «%s», en " +"el elemento de dirección «%s»" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Error en la dirección «%s»: el transporte UNIX requiere exactamente que una " +"de las claves «path» o «abstract» esté establecida" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Error en la dirección «%s»: falta o está mal formado el atributo para el " +"servidor" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Error en la direccioÌn «%s»: falta o estaÌ mal formado el atributo para el " +"puerto" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Error en la dirección «%s»: falta o está mal formado el atributo para el " +"archivo de número usado una sola vez" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Error al autolanzar: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Error al abrir el archivo de número usado una sola vez «%s»: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Error al leer el archivo de número usado una sola vez «%s»: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Error al leer el archivo de número usado una sola vez «%s», se esperaban 16 " +"bytes, se obtuvieron %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Error al escribir el contenido del archivo de número usado una sola vez «%s» " +"al flujo:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "La dirección proporcionada está vacía" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "No se puede lanzar un mensaje cuando AT_SECURE está activado" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "No se puede lanzar («spawn») un mensaje al bus sin un ID de máquina: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "No se puede lanzar D-Bus automáticamente sin X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Error al lanzar («spawn») el comando «%s»: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"No se puede determinar la dirección del bus de sesión (no implementado para " +"este SO)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"No se puede determinar la dirección del bus desde la variable de entorno " +"DBUS_STARTER_BUS_TYPE; variable «%s» desconocida" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"No se puede determinar la dirección del bus porque la variable de entorno " +"DBUS_STARTER_BUS_TYPE no está establecida" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipo de bus %d desconocido" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Falta de contenido inesperada al intentar leer una línea" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Falta de contenido inesperada al intentar leer (de forma segura) una línea" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Se agotaron todos los mecanismos de autenticación (intentados: %s) " +"(disponibles: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "El ID del usuario debe ser el mismo en el par y el servidor" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Cancelado a través de GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Error al obtener la información de la carpeta «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Los permisos de la carpeta «%s» están mal formados. Se esperaba el modo " +"0700, se obtuvo 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Error al crear la carpeta %s: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operación no soportada" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Error al abrir el depósito de claves «%s» para su lectura: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"La línea %d del depósito de claves en «%s» con contenido «%s» está mal " +"formada" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"El primer token de la línea %d del depósito de claves en «%s» con contenido " +"«%s» está mal formado" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"El segundo token de la liÌnea %d del depoÌsito de claves en «%s» con contenido " +"«%s» estaÌ mal formado" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "No se encontró la «cookie» con ID %d en el depósito de claves en «%s»" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Error al crear el archivo de bloqueo «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Error al eliminar el archivo de bloqueo antiguo «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Error al cerrar (desenlazar) el archivo de bloqueo «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Error al desenlazar el archivo de bloqueo «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Error al abrir el depósito de claves «%s» para su escritura:" + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" +"(Adicionalmente, también falló la liberación del bloqueo para «%s»: %s)" + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "La conexión está cerrada" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Se alcanzó el tiempo de expiración" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Se encontraron opciones no soportadas al construir la conexión del lado del " +"cliente" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"No existe la interfaz «org.freedesktop.DBus.Properties» en el objeto en la " +"ruta %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "No existe la propiedad «%s»" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "No se puede leer la propiedad «%s»" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "No se puede escribir la propiedad «%s»" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Error al establecer la propiedad «%s». Se esperaba el tipo «%s» pero se " +"obtuvo «%s»." + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "La interfaz «%s» no existe" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "No existe la interfaz «%s» en el objeto en la ruta %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "No existe el método «%s»" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "El tipo de mensaje, «%s», no coincide con el tipo esperado «%s»" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Ya existe un objeto exportado para la interfaz %s en %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "No se pudo obtener la propiedad %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "No se pudo establecer la propiedad %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "El método «%s» devolvió el tipo «%s» pero se esperaba «%s»" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "El método «%s» con interfaz «%s» y firma «%s» no existe" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Ya se ha exportado un subárbol para %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "El objeto no existe en la ruta «%s»" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "el tipo no es válido («INVALID»)" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Mensaje de METHOD_CALL: falta el campo de cabecera PATH o MEMEBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Mensaje de METHOD_RETURN: falta el campo de cabecera REPLY_SERIAL" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Mensaje de ERROR: falta el campo de cabecera REPLY_SERRIAL o ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Mensaje de SIGNAL: falta el campo de cabecera PATH, INTERFACE o MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Mensaje de SIGNAL: el campo de cabecera PATH está usando el valor reservado /" +"org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Mensaje de SIGNAL: el campo de cabecera INTERFACE estaÌ usando el valor " +"reservado org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Se quería leer %lu byte pero sólo se obtuvo %lu" +msgstr[1] "Se querían leer %lu bytes pero sólo se obtuvo %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"Se esperaba el byte NULL después de la cadena «%s» pero se encontró el byte " +"%d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Se esperaba una cadena válida en UTF-8 pero se encontraron bytes no válidos " +"en el byte desplazado %d (la longitud de la cadena es %d). La cadena UTF-8 " +"válida hasta ese punto era «%s»." + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Valor anidado demasiado profundamente" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "El valor analizado «%s» no es un objeto de ruta D-Bus válido" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "El valor analizado «%s» no es una firma de D-Bus válida" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Se encontró un array de longitud %u byte. La longitud máxima es 2<<26 bytes " +"(64 MiB)." +msgstr[1] "" +"Se encontró un array de longitud %u bytes. La longitud máxima es 2<<26 bytes " +"(64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Encontrado un vector de tipo «a%c», esperando que su longitud fuese múltiplo " +"de %u bytes, pero su longitud es de %u" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Las estructuras vacías (tuplas) no están permitidas en D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"El valor analizado «%s» para la variante no es una firma de D-Bus válida" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Error al deserializar GVariant con el tipo de cadena «%s» al formato de " +"mensaje de D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valor endian no válido. Se esperaba 0x6c («l») o 0x42 («B»)» pero se obtuvo " +"el valor 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"La versión principal del protocolo no es válida. Se esperaba 1 pero se " +"encontró %d." + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Cabecera de firma encontrada pero no es del tipo firma" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Se encontró la cabecera de firma con firma «%s» pero el cuerpo del mensaje " +"está vacío" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"El valor analizado «%s» no es una firma de D-Bus válida (para el cuerpo)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"No existe la cabecera de firma en el mensaje pero el cuerpo del mensaje " +"tiene %u byte" +msgstr[1] "" +"No existe la cabecera de firma en el mensaje pero el cuerpo del mensaje " +"tiene %u bytes" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "No se puede deserializar el mensaje: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Error al serializar GVariant con el tipo de cadena «%s» al formato de " +"mensaje de D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"El número de descriptores de archivos en el mensaje (%d) es distinto del " +"campo de cabecera (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "No se puede serializar el mensaje: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"El cuerpo del mensaje tiene la firma «%s» pero no existe la cabecera de firma" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"El cuerpo del mensaje tiene un tipo de firma «%s» pero la firma en el campo " +"de cabecera es «%s»" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"El cuerpo del mensaje está vacío pero la firma en el campo de cabecera es " +"«(%s)»" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Error al devolver el cuerpo de tipo «%s»" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Error al devolver un cuepro vacío" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Escriba un caraÌcter cualquiera para cerrar esta ventana)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"La sesión de dbus no está en ejecución, y falló el lanzamiento automático" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "No se pudo obtener el perfil de hardware: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "No se pudo cargar «%s» o %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Error al llamar StartSereviceByName para %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Respuesta %d no esperada del método StartServiceByName(«%s»)" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"No se puede invocar al método; el proxy no tiene dueño para un nombre " +"%sconocido y el proxy se construyó con la opción " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Espacio de nombres abstracto no soportado" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"No se puede especificar el archivo de número usado una sola vez al crear un " +"servidor" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Error al escribir el archivo de número usado una sola vez en «%s»: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "La cadena «%s» no es un GUID válido de D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "No se puede escuchar en un transporte no soportado «%s»" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Comandos:\n" +" help Mostrar esta información\n" +" introspect Introspeccionar un objeto remoto\n" +" monitor Monitorizar un objeto remoto\n" +" call Invocar un método sobre un objeto remoto\n" +" emit Emitir una señal\n" +" wait Esperar a que aparezca el nombre del bus\n" +"\n" +"Use «%s COMANDO --help» para obtener ayuda de cada comando.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Error: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Error al analizar la introspección XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Error: %s no es un nombre válido\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Error: %s no es una ruta de objeto válida\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Conectar con el bus del sistema" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Conectar con el bus de sesión" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Conectar con la dirección de D-Bus proporcionada" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opciones de conexión del extremo:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opciones para especificar la conexión del extremo:" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "No se especificó ningún punto de conexión extremo" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Se especificaron varios puntos de conexión extremos" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Advertencia: según la introspección de los datos, la interfaz «%s» no " +"existe\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Advertencia: según la introspección de los datos, el método «%s» no existe " +"en la interfaz «%s»\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Destino opcional para la señal (nombre único)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Ruta del objeto sobre el que emitir la señal" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Nombres de la interfaz y señal" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emitir una señal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Error al conectar: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Error: %s no es un nombre de bus único válido.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Error: no se especificó la ruta del objeto\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Error: no se especificó el nombre de la señal\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Error: el nombre de la señal «%s» no es válido\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Error: %s no es un nombre de interfaz válida\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Error: %s no es un nombre de miembro válido\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Error al analizar el parámetro %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Error al limpiar la conexión: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nombre del detino sobre el que invocar elmétodo" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Ruta del objeto sobre la que invocar el método" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Nombre de la interfaz y método" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Tiempo de expiración en segundos" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Permitir autorización interactiva" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Invocar un método en un objeto remoto." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Error: el destino no está especificado\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Error: %s no es un nombre de bus válido\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Error: no se especificó el nombre del método\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Error: el nombre del método «%s» no es válido\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Error al analizar el parámetro %d del tipo «%s»: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Error al añadir el manejador %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nombre de destino que introspeccionar" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Ruta del objeto que introspeccionar" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Imprimir XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Introspeccionar hijo" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Solo mostrar propiedades" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspeccionar un objeto remoto." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nombre de destino para monitorizar" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Ruta objeto para monitorizar" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitorizar un objeto remoto." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"Error: no se puede monitorizar una conexión que no sea de mensajes del bus\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Servicio que activar antes de esperar a otro (nombre conocido)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Tiempo que esperar antes de salir con un error (en segundos); 0 para que no " +"haya tiempo de expiración (predeterminado)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPCIÓN…] NOMBRE-BUS" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Esperar a que aparezca el nombre del bus." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Error: se debe especificar un servicio que activar.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Error: se debe especificar un servicio al que esperar.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Demasiados argumentos.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Error: %s no es un nombre de bus conocido válido\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "No autorizado para cambiar la configuración de depuración" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Sin nombre" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "El archivo de escritorio no especificó el campo Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Imposible encontrar el terminal requerido por la aplicación" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"No se puede crear la carpeta de configuración de la aplicación %s del " +"usuario: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "No se puede crear la carpeta de configuración MIME %s del usuario: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "La información de la aplicación carece de un identificador" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "No se puede crear el archivo de escritorio %s del usuario" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Definición personalizada para %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "la unidad no implementa la expulsión" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "la unidad no implementa la expulsión o expulsión con operación" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "la unidad no implementa el sondeo para medios" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "la unidad no implementa reproducir" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "la unidad no implementa detener" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "El «backend» de TLS no implementa recuperación de enlace de TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "El soporte de TSL no está disponible" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Soporte de DTSL no disponible" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "No se puede manejar la versión %d de la codificación GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Número de tokens (%d) mal formados en la codificación GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "No se puede manejar la versión %d de la codificación GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Número de tokens (%d) mal formados en la codificación GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Se esperaba un GEmblem para GEmblemedIconjo" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "El punto de montaje contenido no existe" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "No se puede copiar sobre la carpeta" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "No se puede copiar una carpeta sobre otra" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "El archivo destino ya existe" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "No se puede copiar la carpeta recursivamente" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "La unión no está soportada" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Error al unir el archivo: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Copiar (reflink/clone) entre puntos de montaje no está soportado" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Copiar (reflink/clone) no está soportado o no es válido" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Copiar (reflink/clone) no está soportado o no ha funcionado" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "No se puede copiar el archivo especial" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "El valor del enlace simbólico dado no es válido" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Enlaces simbólicos no soportados" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "No se soporta mover a la papelera" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Los nombres de archivo no pueden contener «%c»" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "el volumen no implementa el montaje" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "No hay ninguna aplicación registrada para manejar este archivo" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "El enumerador está cerrado" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "El enumerador del archivo tiene una operación excepcional" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "El enumerador del archivo ya está cerrado" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "No se puede manejar la versión %d de la codificación GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Datos de entrada mal formados para GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "El flujo no soporta query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "No se permite buscar en el flujo" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "No se permite truncar en el flujo de entrada" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "No se soporta el truncamiento en el flujo" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "El nombre del host no es válido" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Respuesta del proxy HTTP incorrecta" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Conexión al proxy HTTP no permitida" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Falló la autenticación en el proxy HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Autenticación requerida en el proxy HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Falló la conexión al proxy HTTP: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "La respuesta del proxy HTTP es demasiado grande" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "El servidor proxy HTTP cerró la conexión inesperadamente." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Número de tokens (%d) incorrecto" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "No existe el tipo para la clase de nombre %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "El tipo %s no implementa la interfaz GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "El tipo %s no tiene clase" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Número de versión mal formado: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "El tipo %s no implementa from_tokens() en la interfaz GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "" +"No se puede manejar la versión proporcionada de la codificación de icono" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "No se especificó ninguna dirección" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "La longitud de %u es demasiado larga para una dirección" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "La dirección tiene bits más allá de la longitud del prefijo" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "No se pudo analizar «%s» como una máscara de una dirección IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "No hay suficiente espacio para la dirección del socket" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Dirección del socket no soportada" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "El flujo de entrada no implementa la lectura" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "El flujo tiene una operación excepcional" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copiar con archivo" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Mantener con archivo cuando se mueva" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "«version» no lleva ningún argumento" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Uso:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Mostrar informacioÌn de la versioÌn y salir." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Comandos:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatenar archivos en la salida estándar" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copiar uno o más archivos" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Mostrar información sobre las ubicaciones" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Lanzar una aplicación desde un archivo .desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Listar el contenido de las ubicaciones" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Obtener o establecer el gestor para un tipo MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Crear carpetas" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitorizar cambios en archivos y claves" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montar o desmontar las ubicaciones" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Mover uno o más archivos" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Abrir archivos con la aplicación predeterminada" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Renombrar un archivo" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Eliminar uno o más archivos" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Leer de la entrada estándar y guardar" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Establecer el atributo de un archivo" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Mover archivos o carpetas a la papelera" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Listar el contenido de las ubicaciones en un árbol" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" +"Use %s para obtener ayuda detallada.\n" +"\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Error al escribir en la salida estándar" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:91 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "UBICACIÓN" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatenar archivos e imprimir por la salida estándar." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat funciona igual que la utilidad «cat» tradicional, pero usando\n" +"ubicaciones GIO en lugar de archivos locales: por ejemplo, puede\n" +"usar algo como smb://servidor/recurso/archivo.txt como ubicación." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "No se han proporcionado ubicaciones" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "No hay carpeta de destino" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Mostrar progreso" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Preguntar antes de sobrescribir" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Conservar todos los atributos" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Respaldar los archivos de destino existentes" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "No seguir nunca enlaces simbólicos" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Usar permisos predeterminados para el destino" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Transferido %s de %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ORIGEN" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINO" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copiar uno o más archivos desde el ORIGEN al DESTINO." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy es similar a la utilidad «cp» tradicional, pero usando\n" +"ubicaciones GIO en lugar de archivos locales: por ejemplo, puede\n" +"usar algo como smb://servidor/recurso/archivo.txt como ubicación." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "El destino %s no es una carpeta" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: ¿sobrescribir «%s» ? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Listar los atributos que se pueden escribir" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Obtener información del sistema de archivos" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Los atributos que obtener" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTOS" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "No seguir enlaces simbólicos" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributos:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nombre que mostrar: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "nombre editado: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nombre: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipo: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "tamaño: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "oculto\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "URI: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "ruta local: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "montaje unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atributos que se pueden establecer:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Espacios de nombres de atributos que se pueden escribir:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Mostrar información sobre las ubicaciones." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info es similar a la utilidad «ls» tradicional, pero usando ubicaciones\n" +"GIO en lugar de archivos locales: por ejemplo, puede usar algo\n" +"como smb://servidor/recurso/archivo.txt como ubicación. Los atributos \n" +"del archivo se puede especificar con su nombre GIO, es decir standard::icon\n" +"o simplemente por su espacio de nombres, ej. unix o con «*», que obtiene " +"todos los atributos" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "ARCHIVO-DESKTOP [ARG-ARCH …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Lanzar una aplicación desde un archivo .desktop, pasándole argumentos de " +"nombre de archivo opcionales." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "No se han proporcionado un archivo .desktop" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "El comando lanzado no está soportado actualmente en esta plataforma" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "No se pudo cargar «%s»: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "No se pudo cargar la información de la aplicación para «%s»" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "No se pudo lanzar la aplicación «%s»: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Mostrar archivos ocultos" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Usar un formato de listado largo" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Imprimir nombres que mostrar" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Imprimir URI completos" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Listar el contenido de las ubicaciones." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio copy es similar a la utilidad «ls» tradicional, pero usando\n" +"ubicaciones GIO en lugar de archivos locales: por ejemplo, puede usar\n" +"algo como smb://servidor/recurso/archivo.txt como ubicación. Los\n" +"atributos del archivo se puede especificar con su nombre GIO, ej standard::" +"icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TIPOMIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "GESTOR" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Obtener o establecer el gestor para un tipo MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Si no se indica un gestor, lista las aplicaciones registradas y " +"recomendadas\n" +"para el tipo MIME. Si se indica un gestor, se establece como el gestor\n" +"predeterminado para el tipo MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Debe especificar un único tipo MIME, y tal vez un gestor" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "No hay aplicación predeterminada para «%s»\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplicación predeterminada para «%s»: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplicaciones registradas:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "No hay aplicaciones registradas\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplicaciones recomendadas:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "No hay aplicaciones recomendadas\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Falló al cargar la información para el gestor «%s»" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Falló al establecer el gestor «%s» como predeterminado para «%s»: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Crear carpetas padre" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Crear carpetas." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir es similar a la utilidad «mkdir» tradicional, pero usando\n" +"ubicaciones GIO en lugar de archivos locales: por ejemplo, puede\n" +"usar algo como smb://servidor/recurso/archivo.txt como ubicación." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitorizar una carpeta (predeterminado: depende del tipo)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitorizar un archivo (predeterminado: depende del tipo)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Monitorizar un archivo directamente (se notifican los cambios mediante " +"enlaces duros)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitoriza un archivo directamente, pero no informa de los cambios" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Informar de movimientos y renombrados como simples eventos de eliminación/" +"creación" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Vigilar eventos de montaje" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitorizar cambios en archivos o carpetas." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Montar como montable" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Montar volumen con archivo de dispositivo u otro identificador" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Desmontar" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Expulsar" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Detener unidad con archivo de dispositivo" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DISPOSITIVO" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Desmontar todos los puntos de montaje con el esquema dado" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ESQUEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignorar operaciones de archivos pendientes al desmontar o expulsar" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Usar un usuario anónimo al autenticar" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Listar" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitorizar eventos" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Mostrar información adicional" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "El PIM numérico al desbloquear un volumen VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montar un volumen TCRYPT oculto" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montar un volumen de sistema TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Acceso anónimo denegado" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "No hay unidad para el archivo de dispositivo" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "No hay volumen para el ID dado" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montar o desmontar las ubicaciones." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "No usar copia y eliminación de reserva" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Mover uno o más archivos de ORIGEN a DESTINO." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move es similar a la utilidad «mv» tradicional, pero usando\n" +"ubicaciones GIO en lugar de archivos locales: por ejemplo, puede\n" +"usar algo como smb://servidor/recurso/archivo.txt como ubicación" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "El destino %s no es una carpeta" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Abrir archivos con la aplicación predeterminada que\n" +"esté registrada para manejar archivos de este tipo." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignorar archivos no existentes, nunca preguntar" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Eliminar los archivos dados." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOMBRE" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Renombrar un archivo." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Falta el argumento" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:139 +msgid "Too many arguments" +msgstr "Demasiados argumentos" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Renombrado correcto. Nuevo URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Crear sólo si no existe" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Añadir al final de un archivo" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Al crear, restringir el acceso al usuario actual" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Al reemplazar, hacerlo como si el destino no existiera" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Imprimir nueva etag al final" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "La etag del archivo que se está sobrescribiendo" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Error al leer de la entrada estándar" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag no disponible\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Leer de la entrada estándar y guardar en DESTINO." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "No se ha indicado el destino" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Tipo del atributo" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPO" + +#: gio/gio-tool-set.c:91 +msgid "ATTRIBUTE" +msgstr "ATRIBUTO" + +#: gio/gio-tool-set.c:91 +msgid "VALUE" +msgstr "VALOR" + +#: gio/gio-tool-set.c:95 +msgid "Set a file attribute of LOCATION." +msgstr "Establecer el atributo UBICACIÓN de un archivo." + +#: gio/gio-tool-set.c:115 +msgid "Location not specified" +msgstr "Ubicación no encontrada" + +#: gio/gio-tool-set.c:122 +msgid "Attribute not specified" +msgstr "Atributo no especificado" + +#: gio/gio-tool-set.c:132 +msgid "Value not specified" +msgstr "Valor no especificado" + +#: gio/gio-tool-set.c:182 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Tipo de atributo «%s» no válido" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Vaciar la papelera" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Listar los archivos de la papelera con sus ubicaciones originales" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restaurar un archivo de la papelera a su ubicación original (posiblemente " +"recreando la carpeta)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "No se pudo encontrar la ruta original" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "No se pudo recrear la ubicación original: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "No se puede mover el archivo a su ubicación original: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Mover o restaurar archivos o carpetas a/de la papelera." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Nota: para la opción --restore, si la ubicación original del archivo " +"eliminado\n" +"ya existe no se sobrescribirá a menos que se indique la opción --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "La ubicación indicada no empieza por trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Seguir enlaces simbólicos, puntos de montaje y atajos" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Listar el contenido de las carpetas en forma de árbol." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "No se permite el elemento <%s> dentro de <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "No se permite el elemento <%s> en el nivel superior" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "El archivo %s aparece varias veces en el recurso" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Falló al buscar «%s» en cualquier carpeta fuente" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Falló al buscar «%s» en la carpeta actual" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Opción de procesado desconocida «%s»" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"solicitado preprocesar %s, pero %s no está establecido y %s no está en el " +"PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Error al leer el archivo %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Error al comprimir el archivo %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "El texto no debe aparecer dentro de <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Mostrar la versión del programa y salir" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nombre del archivo de salida" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"La carpeta de la que se tienen que leer los archivos indicados en ARCHIVO " +"(la predeterminada es la carpeta actual)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "CARPETA" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Generar salida en el formato seleccionado por la extensión del nombre del " +"archivo objetivo" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Generar cabecera fuente" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Generar el código fuente usado para enlazar el archivo del recurso en su " +"código fuente" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Generar lista de dependencias" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nombre del archivo de dependencias que generar" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Incluir objetivos falsos en el archivo de dependencias generado" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "No crear y registrar automáticamente un recurso" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "No exportar funciones; declararlas como G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"No incluir datos de recursos en el archivo C; en su lugar, asumir que está " +"enlazado de manera externa" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Nombre del identificador C usado para el código fuente generado" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "El compilador C objetivo (predeterminado: la variable de entorno CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compilar la especificación de un recurso en un archivo de recurso.\n" +"Los archivos de especificación de recursos deben tener la extensión ." +"gresource.xml,\n" +"y el archivo del recurso debe tener la extensión se llama .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Deberá proporcionar exactamente un nombre de archivo\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "«nick» debe tener al menos dos caracteres" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Valor numérico no válido" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " ya especificado" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' ya especificado" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "los valores de las opciones deben tener al menos 1 bit establecido" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> debe contener al menos un " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> no está dentro del rango especificado" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> no es un miembro válido del tipo enumerado especificado" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" +"<%s> contiene una cadena que no está especificada en los tipos de opciones" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> contiene una cadena que no está en " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " ya especificada para esta clave" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " no permitido para las claves de tipo «%s»" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " mínimo especificado es mayor que el máximo" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categoría l10n no soportada: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n solicitado, pero no se ha dado el dominio de gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "contexto de traducción especificado sin tener l10n activado" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Falló al analizar el valor del tipo «%s»: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" no se puede especificar para tipos etiquetados como que tienen un " +"tipo enumerado" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " ya especificado para esta clave" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " no permitido para las claves de tipo «%s»" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " ya especificado" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " debe contener al menos un " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " ya especificado por esta clave" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" sólo se puede especificar para claves con tipos enumerados, de " +"opciones o después de " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" dado cuando «%s» ya es un miembro del tipo enumerado" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " dado cuando ya se había dado " + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " ya especificado" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "el alias del objetivo «%s» no está en el tipo enumerado" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "el alias del objetivo «%s» no está en " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " debe contener al menos un " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "No se permiten nombres vacíos" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" +"Nombre «%s» no válido: los nombres deben comenzar por una letra minúscula" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nombre «%s» no válido: el carácter «%c» no es válido; sólo se permiten " +"nombres en minúscula, números y guión («-»)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Nombre «%s» no válido: no se permiten dos guiones seguidos («--»)" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Nombre «%s» no válido: el último carácter no puede ser un guión («-»)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nombre «%s» no válido: la longitud máxima es 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " ya especificado" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "no se pueden añadir claves a un esquema «list-of»" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " ya especificada" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" eclipsa a en ; use " +" para modificar el valor" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Se debe especificar exactamente uno de «type», «enum» o «flags» como " +"atributo para " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> aún no especificado." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Tipo de cadena GVariant «%s» no válida" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "Se proporcionó pero el esquema no extiende nada" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "No existe para sobrescribir" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " ya especificada" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " ya especificado" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " extiende el esquema «%s» que aún no existe" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " es una lista del esquema «%s» que aún no existe" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "No puede ser una lista de un esquema con una ruta" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "No se puede extender un esquema con una ruta" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" es una lista, extendiendo que no es una " +"lista" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" extiende pero " +"«%s» no extiende «%s»" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Si se especifica una ruta, debe comenzar y terminar con una barra" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "La ruta de la lista debe terminar con «:/»" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Advertencia: el esquema «%s» tiene la ruta «%s». Las rutas que empiezan por " +"«/apps/», «/desktop/» o «/system/» están obsoletas." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ya especificado" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Sólo se permite un elemento <%s> dentro de <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "No se permite el elemento <%s> en el nivel superior" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Se requiere el elemento en " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "El texto no debe aparecer dentro de <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Advertencia: referencia a no definida" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "se especificoÌ --strict; saliendo." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Se ha ignorado este archivo completamente." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignorando este archivo." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"No existe la clave «%s» en el esquema «%s» como se especificó en el archivo " +"de sobrescritura «%s»; se ignora para esta clave." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"No existe la clave «%s» en el esquema «%s» como se especificó en el archivo " +"de sobrescritura «%s» y se ha especificado --strict; saliendo." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"No se pueden proporcionar las alternativas para la clave «%s» traducida en " +"el esquema «%s» (sobrescribe el archivo %s): se ignora para esta clave." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"No se pueden proporcionar las alternativas para la clave «%s» traducida en " +"el esquema «%s» (sobrescribe el archivo %s) y se ha especificado --strict; " +"saliendo." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Error al analizar la clave «%s» en el esquema «%s» como se especificoÌ en el " +"archivo de sobrescritura «%s»: %s; se ignora para esta clave." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Error al analizar la clave «%s» en el esquema «%s» como se especificoÌ en el " +"archivo de sobrescritura «%s»: %s y se ha especificado --strict; saliendo." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"La clave de sobrescritura «%s» en el esquema «%s» en el archivo de " +"sobrescritura «%s» está fuera del rango proporcionado en el esquema; se " +"ignora para esta clave." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"La clave de sobrescritura «%s» en el esquema «%s» en el archivo de " +"sobrescritura «%s» está fuera del rango proporcionado en el esquema y se ha " +"especificado --strict; saliendo." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"La clave de sobrescritura «%s» en el esquema «%s» en el archivo de " +"sobrescritura «%s» no está en la lista de opciones válidas; se ignora para " +"esta clave." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"La clave de sobrescritura «%s» en el esquema «%s» en el archivo de " +"sobrescritura «%s» no está en la lista de opciones válidas y se ha " +"especificado --strict; saliendo." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Dónde almacenar el archivo gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Abortar ante cualquier error en los esquemas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "No escribir el archivo gschemas.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "No forzar las restricciones de nombre de las claves" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compilar todos los archivos de esquema de GSettings en una caché de " +"esquemas.\n" +"Los archivos de esquema deben tener la extensión .gschema.xml,\n" +"y el archivo de caché se llama gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Deberá proporcionar exactamente un nombre de carpeta" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "No se encontró ningún archivo de esquemas: no se hace nada." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"No se han encontrado archivos de esquemas: se ha eliminado el archivo de " +"salida existente." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Nombre de archivo no válido %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Error al obtener la información del sistema de archivos para %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "No se ha encontrado el punto de montaje para el archivo %s" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "No se puede renombrar la carpeta raíz" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Error al leer el archivo %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "No se puede renombrar el archivo, el nombre de archivo ya existe" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nombre de archivo no válido" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Error al abrir el archivo %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Error al eliminar el archivo %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Error al mover a la papelera el archivo %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "No se pudo crear la carpeta de papelera %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "No se pudo encontrar la carpeta de nivel superior para la papelera %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Copiar (reflink/clone) entre puntos de montaje no está soportado" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "No se pudo encontrar o crear la carpeta %s de la papelera para %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "No se pudo crear la información de papelera para el archivo %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"No se pudo enviar a la papelera el archivo %s entre sistemas de archivos" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "No se pudo enviar a la papelera el archivo %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "No se pudo enviar a la papelera el archivo %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Error al crear la carpeta %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "El sistema de archivos no soporta enlaces simbólicos" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Error al crear el enlace simbólico %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Error al mover el archivo %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "No se puede mover una carpeta sobre una carpeta" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Falló la creación del archivo de respaldo" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Error al eliminar el archivo destino: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "No se soporta mover archivos entre puntos de montaje" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "No se pudo determinar el uso de disco de %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "El valor del atributo de ser no nulo" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tipo de atributo no válido (se esperaba una cadena)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nombre extendido del atributo no válido" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Error al establecer el atributo extendido «%s»: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codificación no válida)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Error al obtener la información del archivo «%s»: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Error al obtener la información del descriptor del archivo: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tipo de atributo no válido (se esperaba uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tipo de atributo no válido (se esperaba uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Tipo de atributo no válido (se esperaba una cadena byte)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "No se pueden establecer permisos en enlaces simbólicos" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Error al establecer permisos: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Error al establecer el propietario: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "el enlace simbólico debe ser no nulo" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Error al establecer el enlace simbólico: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Error al establecer el enlace simbólico: el archivo no es un enlace simbólico" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"Los %d nanosegundos adicionales para la marca de tiempo UNIX %lld son " +"negativos" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Los %d nanosegundos adicionales para la marca de tiempo UNIX %lld alcanzan 1 " +"segundo" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "La marca de tiempo UNIX %lld no cabe en 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"La marca de tiempo UNIX %lld está fuera del rango soportado por Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "El nombre de archivo «%s» no se puede convertir a UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "No se puede abrir el archivo «%s»: error de Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Error al establecer o modificar la hora de acceso para el archivo %s: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Error al establecer o modificar el tiempo de acceso: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "El contexto SELinux debe ser no nulo" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux no está activado en este sistema" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Error al establecer el contexto SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Establecer el atributo %s no está soportado" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Error al leer del archivo: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Error al cerrar el archivo: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Error al buscar en el archivo: %s" + +#: gio/glocalfilemonitor.c:879 +msgid "Unable to find default local file monitor type" +msgstr "" +"No se pudo encontrar el tipo de monitorización del archivo local " +"predeterminado" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Error al escribir en el archivo: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Error al eliminar el enlace de respaldo antiguo: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Error al crear una copia de respaldo: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Error al renombrar el archivo temporal: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Error al truncar el archivo: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Error al abrir el archivo %s: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "El archivo destino es una carpeta" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "El archivo destino no es un archivo regular" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "El archivo se modificó externamente" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Error al eliminar el archivo antiguo: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Se proporcionó un GSeekType no válido" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Petición de búsqueda no válida" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "No se puede truncar GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "El flujo de salida de la memoria no es redimensionable" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Falló al redimensionar el flujo de salida de la memoria" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"La cantidad de memoria necesaria para procesar el escrito es mayor que el " +"espacio de direcciones libre disponible" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "La búsqueda solicitada antes del inicio del flujo" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "La búsqueda solicitada después del final del flujo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "el punto de montaje no implementa el desmontado («unmount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "el punto de montaje no implementa la expulsión («eject»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"el punto de montaje no implementa desmontado («umount») o desmontado con " +"operación («unmount_with_operation»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"el punto de montaje no implementa la expulsión («eject») o expulsión con " +"operación («eject_with_operation»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "el punto de montaje no implementa el remontado («remount»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "el punto de montaje no implementa averiguación del tipo de contenido" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" +"el punto de montaje no implementa averiguación síncrona del tipo de contenido" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "El nombre del equipo «%s» contiene «[» pero no «]»" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Red no alcanzable" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Equipo no alcanzable" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "No se pudo crear el monitor de red: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "No se pudo crear el monitor de red: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "No se pudo obtener el estado de la red: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager no está en ejecución" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Versión de NetworkManager demasiado antigua" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "El flujo de salida no implementa la escritura" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "La suma de vectores pasada a %s es demasiado grande" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "El flujo de origen ya está cerrado" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Error al resolver «%s»: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s no está implementado" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Dominio no válido" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "El recurso en «%s» no existe" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "El recurso en «%s» falló al descomprimir" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "El recurso en «%s» no es una carpeta" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "El flujo de entrada no implementa la búsqueda" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Listar secciones que contengan recursos en un ARCHIVO elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Listar recursos\n" +"Si se da la SECCIÓN, listar solo los recursos de esta sección.\n" +"Si se da la RUTA, listar solo los recursos que coincidan" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "ARCHIVO [RUTA]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECCIOÌN" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Listar recursos con detalles\n" +"Si se da la SECCIÓN, listar solo los recursos de esta sección.\n" +"Si se da la RUTA, listar solo los recursos que coincidan\n" +"Los detalles incluyen la sección, el tamaño y la compresión" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extraer un archivo de recursos a stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "ARCHIVO RUTA" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gresource [--section SECCIÓN] COMANDO [ARGUMENTOS...]\n" +"\n" +"Comandos:\n" +" help Mostrar esta información\n" +" sections Listar secciones de recursos\n" +" list Listar recursos\n" +" details Listar recursos con detalle\n" +" extract Extraer un recurso\n" +"\n" +"Use «gresource help COMANDO» para obtener ayuda detallada.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECCIÓN El nombre de sección (opcional) de un elf\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMANDO El comando (opcional) que explicar\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" ARCHIVO Un archivo elf (un binario o una biblioteca compartida)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" ARCHIVO Un archivo elf (un binario o una biblioteca compartida)\n" +" o un archivo de recursos compilado\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[RUTA]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " RUTA La ruta (opcional) de un recurso (puede ser parcial)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "RUTA" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " RUTA La ruta de un recurso\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "No existe el esquema «%s»\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "El esquema «%s» no es reubicable (no se debe especificar la ruta)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "El esquema «%s» es reubicable (se debe especificar la ruta)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Se proporcionó una ruta vacía.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "La ruta debe comenzar con una barra (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "La ruta debe terminar con una barra (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "La ruta no debe contener dos barras adyacentes (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "El valor proporcionado está fuera del rango válido\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "No se puede escribir la clave\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Listar los esquemas instalados (no reubicables)" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Listar los esquemas reubicables instalados" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Listar las claves en el ESQUEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "ESQUEMA[:RUTA]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Listar los hijos del ESQUEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Listar las claves y valores recursivamente\n" +"Si no se proporciona un ESQUEMA, listar todas las claves\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESQUEMA[:RUTA]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Obtener el valor de la CLAVE" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESQUEMA[:RUTA] CLAVE" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Consultar el rango de valores válidos para la CLAVE" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Consultar la descripción para la CLAVE" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Establecer el valor de la CLAVE a VALOR" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESQUEMA[:RUTA] CLAVE VALOR" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Restablecer la CLAVE a su valor predeterminado" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" +"Restablecer todas las claves en un ESQUEMA a sus valores predeterminados" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Comprobar si la CLAVE se puede escribir" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitorizar cambios en la CLAVE.\n" +"Si no se especifica una CLAVE, monitorizar todas las claves en el ESQUEMA.\n" +"Use ^C para detener la monitorización.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESQUEMA[:RUTA] [CLAVE]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings --version\n" +" gsettings [--schemadir CARPETA_ESQUEMA] COMANDO [ARGUMENTOS...]\n" +"\n" +"Comandos:\n" +" help Mostrar esta información\n" +" list-schemas Listar los esquemas instalados\n" +" list-relocatable-schemas Listar los esquemas reubicables\n" +" list-keys Listar las claves en un esquema\n" +" list-children Listar los hijos de un esquema\n" +" list-recursively Listar claves y valores recursivamente\n" +" range Consultar el rango de una clave\n" +" describe Consultar la descripción de la clave\n" +" get Obtener el valor de una clave\n" +" set Establecer el valor de una clave\n" +" reset Restablecer el valor de una clave\n" +" reset-recursively Restablecer todos los valores en un esquema " +"dado\n" +" writable Comprobar si una clave se puede escribir\n" +" monitor Monitorizar cambios\n" +"\n" +"Use «gsettings help COMANDO» para obtener una ayuda detallada.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings [--schemadir CARPETA_ESQUEMA] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " CARPETA_ESQUEMA: una carpeta para buscar esquemas adicionales\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA El nombre del esquema\n" +" RUTA La ruta, para esquemas reubicables\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " CLAVE La clave (opcional) para el esquema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " CLAVE La clave para el esquema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALOR El valor para establecer\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "No se pudieron cargar los esquemas de %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "No hay esquemas instalados\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Se proporcionó un nombre de esquema vacío\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "No existe la clave «%s»\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Socket no válido, no inicializado" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Socket no válido, falló la instalación debido a: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "El socket ya está cerrado" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Expiró la E/S del socket" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "creando el GSocket desde fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "No se pudo crear el socket: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Se especificó una familia desconocida" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Se especificó un protocolo desconocido" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"No se pueden usar operaciones de datagrama en un zócalo que no es de " +"datagrama." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"No se pueden usar operaciones de datagrama en un zócalo sin un tiempo de " +"expiración establecido." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "no se pudo obtener la dirección local: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "no se pudo obtener la dirección remota: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "no se pudo escuchar: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Error al vincular con la dirección %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Error al unirse al grupo de multicast: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Error al abandonar al grupo de multicast: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "No se soporta el multicast específico de la fuente" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Familia del socket no soportada" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "la fuente específica no es una dirección IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "El nombre de la interfaz es demasiado largo" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interfaz no encontrada: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "No se soporta el multicast específico de la fuente para IPv4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "No se soporta el multicast específico de la fuente para IPv6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Error al aceptar la conexión: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Conexión en progreso" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "No se pudo obtener el error pendiente: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Error al recibir los datos: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Error al enviar los datos: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "No se pudo desconectar el socket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Error al cerrar el socket: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Esperando la condición del socket: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "No se pudo enviar el mensaje: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vectores de mensaje demasiado largos" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Error al enviar el mensaje: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage no está soportado en Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Error al recibir el mensaje: %s" + +#: gio/gsocket.c:6092 gio/gsocket.c:6103 gio/gsocket.c:6166 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "No se pudieron leer las credenciales del socket: %s" + +#: gio/gsocket.c:6175 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials no está implementado en este SO" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "No se pudo conectar al servidor proxy %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "No se pudo conectar a %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "No se pudo conectar: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1805 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" +"No se soporta intentar hacer de proxy sobre una conexión que no es TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1834 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "El protocolo del proxy «%s» no está soportado." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "El «listener» ya está cerrado" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "El socket añadido está cerrado" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 no soporta la dirección de IPv6 «%s»" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "El nombre de usuario es demasiado largo para el protocolo SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "" +"El nombre de equipo «%s» es demasiado largo para el protocolo SOCKSv4\t" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "El servidor no es un servidor proxy SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Se rechazó la conexión a través del servidor SOCKSv4" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "El servidor no es un servidor proxy SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "El servidor proxy SOCKSv5 requiere autenticación." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"El servidor SOCKSv5 requiere un método de autenticación que GLib no soporta." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"El nombre de usuario o la contraseña son demasiado largos para el protocolo " +"SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Falló la autenticación SOCKSv5 debido a un nombre de usuario o contraseña " +"incorrecta." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "El nombre de equipo «%s» es demasiado largo para el protocolo SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "El servidor proxy SOCKSv5 usa un tipo de dirección desconocido." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Error interno de SOCKSv5 del servidor proxy." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "El conjunto de reglas no permite la conexión SOCKSv5." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "El servidor no es alcanzable a traveÌs del servidor SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "La red no es alcanzable a través del proxy SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Se rechazó la conexión a través del proxy SOCKSv5." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "El proxy SOCKSv5 no soporta el comando «connect»." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "El proxy SOCKSv5 no soporta el tipo de dirección proporcionado." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Error desconocido del proxy SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Falló en la creación de un conducto (pipe) para comunicarse con el proceso " +"hijo (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "En esta plataforma no se soportan las tuberías" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "No se puede manejar la versión %d de la codificación GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "No se han encontrado direcciones válidas" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Error al resolver «%s» de forma inversa: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Error al analizar el registro DNS %s: paquete DNS mal formado" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "No hay un registro de DNS del tipo solicitado para «%s»" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "No se puede resolver «%s» temporalmente" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Error al resolver «%s»" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Paquete DNS mal formado" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Falló al analizar la respuesta DNS para «%s»: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "No se encontró ninguna clave privada codificada con PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "No se pudo descifrar la clave privada codificada con PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "No se pudo analizar la clave privada codificada con PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "No se encontró ningún certificado codificado con PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "No se pudo analizar el certificado codificado con PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Este «backend» de TLS actual no soporta crear certificados PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Este GTlsBackend no soporta crear certificados PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Esta es la última oportunidad para introducir la contraseña correctamente " +"antes de que su acceso se bloquee." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Se han introducido varias contraseñas incorrectas, y su acceso se bloqueará " +"después de más fallos." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "La contraseña introducida no es correcta." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "No se soporta el envío de FD" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Se esperaba un mensaje de control, se obtuvo %d" +msgstr[1] "Se esperaba un mensaje de control, se obtuvieron %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Tipos de datos complementarios inesperados" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Se esperaba un fd pero se obtuvo %d\n" +msgstr[1] "Se esperaba un fd pero se obtuvieron %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Se recibió un fd no válido" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "No se soporta recibid FD" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Error al enviar las credenciales: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Error al comprobar si SO_PASSCRED está activada para el socket: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Error al activar SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Se esperaba leer un solo byte para recibir las credenciales pero se leyeron " +"cero bytes" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "No se esperaba un mensaje de control, pero se obtuvo %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Error al desactivar SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Error al leer del descriptor del archivo: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Error al cerrar el descriptor del archivo: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Sistema de archivos raíz" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Error al escribir en el descriptor del archivo: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Este sistema no soporta direcciones de socket de dominio UNIX abstracto" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "el volumen no implementa la expulsión" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "el volumen no implementa la expulsión o expulsión con operación" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Error al leer del gestor: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Error al cerrar el gestor: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Error al escribir en el gestor: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "No hay suficiente memoria" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Error interno: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Se necesita más entrada" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Datos comprimidos no válidos" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Dirección en la que escuchar" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Se ignora, por compatibilidad con GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Imprimir dirección" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Imprimir dirección en modo consola" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Ejecutar un servicio dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Argumentos incorrectos\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Atributo inesperado «%s» para el elemento «%s»" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "El atributo «%s» del elemento «%s» no se ha encontrado" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Etiqueta «%s» inesperada, se esperaba la etiqueta «%s»" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Etiqueta «%s» inesperada dentro de «%s»" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Fecha/hora «%s» no válida en el archivo de marcadores" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"No se pudo encontrar ningún archivo de marcadores válido en las carpetas de " +"datos" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Ya existe un marcador para el URI «%s»" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "No se encontró un marcador para el URI «%s»" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Ningún tipo MIME definido en el marcador para la URI «%s»" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "No se ha definido ningún flag privado en el marcador para el URI «%s»" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "No se ha establecido ningún grupo en el marcador para el URI «%s»" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Ninguna aplicación con nombre «%s» registró un marcador para «%s»" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Falló la expansión de lalinea ejecutable «%s» con el URI «%s»" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Carácter no representable en entrada de conversión" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Hay una secuencia parcial de caracteres en el final de la entrada" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "No se puede convertir el fallback «%s» al conjunto de códigos «%s»" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Tipo NUL empotrado en la entrada de conversión" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Tipo NUL empotrado en la salida de conversión" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "El URI «%s» no es una URI absoluta utilizando el esquema «file»" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "El archivo local en la URI «%s» no debe incluir un «#»" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "El URI «%s» no es válido" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "El nombre del host de la URI «%s» no es válido" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "El URI «%s» contiene caracteres de escape no válidos" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "El nombre de la ruta «%s» no es una ruta absoluta" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %H:%M:%S, %e de %B de %Y" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "enero" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "febrero" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "marzo" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "abril" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "mayo" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "junio" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "julio" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "agosto" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "septiembre" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "octubre" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "noviembre" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "diciembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ene" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "abr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "may" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ago" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "oct" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "dic" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Lunes" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Martes" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "MieÌrcoles" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Jueves" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Viernes" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "SaÌbado" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Domingo" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Lun" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Mar" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mié" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Jue" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Vie" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sáb" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Dom" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "enero" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "febrero" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "marzo" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "abril" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "mayo" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "junio" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "julio" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "agosto" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "septiembre" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "octubre" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "noviembre" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "diciembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ene" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "abr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "may" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ago" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "oct" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dic" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Falló al abrir la carpeta «%s»: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "No se pudo asignar %lu byte para leer el archivo «%s»" +msgstr[1] "No se pudieron asignar %lu bytes para leer el archivo «%s»" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Error al leer el archivo %s: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "El archivo «%s» es demasiado grande" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Falló al leer del archivo «%s»: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Falló al abrir el archivo «%s»: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Falló al obtener los atributos del archivo «%s»: fstat() falló: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Falló al abrir el archivo «%s»: fdopen() falló: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Falló al renombrar el archivo «%s» a «%s»: g_rename() falló: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Falló al escribir el archivo «%s»: falló write(): %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Falló al escribir el archivo «%s»: falló fsync(): %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Falló al crear el archivo «%s»: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "El archivo existente «%s» no se pudo eliminar: g_unlink() falló: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "La plantilla «%s» no es válida, no debería contener un «%s»" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "La plantilla «%s» no contiene XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Falló al leer el enlace simbólico «%s»: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "No se pudo abrir el conversor de «%s» a «%s»: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"No se puede hacer una lectura en bruto (raw) en g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Se han dejado datos no convertidos en el búfer de lectura" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "El canal termina en un carácter parcial" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "" +"No se puede hacer una lectura en bruto (raw) en g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"No se pudo encontrar la clave de archivo válida en las carpetas de búsqueda" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "No es un archivo regular" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"El archivo de claves contiene la línea «%s» que no es un par valor-clave, " +"grupo o comentario" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nombre de grupo no válido: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "El archivo de claves no empieza por un grupo" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nombre de clave no válido: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "El archivo de claves contiene una codificación «%s» no soportada" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "El archivo de claves no tiene el grupo «%s»" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "El archivo de claves no tiene la clave «%s» en el grupo «%s»" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"El archivo de claves contiene la clave «%s» con el valor «%s» el cual no es " +"UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"El archivo de claves contiene la clave «%s» que tiene un valor que no se " +"puede interpretar." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"El archivo de claves contiene la clave «%s» en el grupo «%s» que tiene un " +"valor que no puede interpretarse." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"La clave «%s» en el grupo «%s» tiene el valor «%s», pero se esperaba %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "" +"El archivo de claves contiene un carácter de escape al final de la línea" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "El archivo de claves contiene la secuencia de escape no válida «%s»" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "El valor «%s» no puede interpretarse como un número." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "El valor entero «%s» está fuera de rango" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "El valor «%s» no puede interpretarse como un número de coma flotante." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "El valor «%s» no puede interpretarse como un booleano." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Falló al obtener los atributos del archivo «%s%s%s%s»: fstat() falló: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Falló al mapear el archivo «%s%s%s%s»: mmap() falló: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Falló al abrir el archivo «%s»: open() falló: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Error en la línea %d, carácter %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Texto codificado como UTF-8 en el nombre no válido; «%s» no es válido" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "«%s» no es un nombre válido" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "«%s» no es un nombre válido: «%c»" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Error en la línea %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Falló al analizar «%-.*s», el cual debería tener un dígito dentro de un " +"carácter de referencia( por ejemplo ê) - tal vez el dígito es demasiado " +"grande" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"El carácter de referencia no termina con punto y coma; probablemente utilizó " +"un carácter «&» sin pretender iniciar una entidad; escape el carácter \"&\" " +"como &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "El carácter de referencia «%-.*s» no codifica un carácter permitido" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"La entidad «&;» está vacía; las entidades válidas son: & " < " +"> '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "El nombre de la entidad «%-.*s» es desconocido" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"La entidad no termina con un punto y coma; probablemente utilizó el carácter " +"\"&\" sin la intención de indicar una entidad, escape el signo \"&\" como " +"&" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "El documento debe comenzar con un elemento (por ejemplo: )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"«%s» no es un carácter válido a continuación del carácter '<'; no debe " +"iniciar un nombre de elemento" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Carácter «%s» impropio, se esperaba un carácter «>» para terminar la " +"etiqueta vacía del elemento «%s»" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Demasiados atributos en el elemento «%s»" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Carácter «%s» impropio, se esperaba el carácter '=' después del nombre de " +"atributo «%s» del elemento «%s»" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Carácter «%s» impropio, se esperaba un carácter '>' o '/' para finalizar la " +"etiqueta de inicio del elemento «%s» u opcionalmente un atributo; tal vez " +"utilizó un carácter que no es válido en un nombre de atributo" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Carácter «%s» impropio, se esperaba una marca de apertura de comillas " +"después del signo igual al darle valor al atributo «%s» del elemento «%s»" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"«%s» no es un carácter válido a continuación del nombre del elemento de " +"cierre «%s»; el carácter permitido es '>'" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Se cerró el elemento «%s», no existe ningún elemento abierto" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"Se cerró el elemento «%s», pero el elemento que está abierto actualmente es " +"«%s»" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "El documento estaba vacío o sólo contenía espacios en blanco" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "El documento termina inesperadamente justo después de un '<'" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"El documento termina inesperadamente con elementos todavía abiertos - «%s» " +"fue el último elemento abierto" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"El documento termina inesperadamente, se esperaba un carácter '>' " +"finalizando la etiqueta <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "El documento termina inesperadamente dentro de un nombre de elemento" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "El documento termina inesperadamente dentro de un nombre de atributo" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"El documento terminó inesperadamente dentro de una etiqueta de apertura de " +"elemento." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"El documento termina inesperadamente después de los signos igual que siguen " +"al nombre de atributo; sin valor de atributo" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "El documento termina inesperadamente dentro del valor de un atributo" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"El documento termina inesperadamente dentro de la etiqueta de cierre del " +"elemento «%s»" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"El documento termina inesperadamente dentro de la etiqueta de cierre para un " +"elemento no abierto" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"El documento termina inesperadamente dentro de un comentario o instrucción " +"de proceso" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPCIÓN…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opciones de ayuda:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Mostrar opciones de ayuda" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Muestra todas las opciones de ayuda" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opciones de la aplicación:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opciones:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "No se puede analizar el valor entero «%s» para %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "El valor entero «%s» para %s está fuera de rango" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "No se puede analizar el valor doble «%s» para %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "El valor doble «%s» para %s está fuera de rango" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Error al analizar la opción: %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Falta un argumento para %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Opción desconocida %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "objeto corrupto" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "error interno u objeto corrupto" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "sin memoria" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "se alcanzó el límite de «backtracking»" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"el patrón contiene elementos no soportados para una coincidencia parcial" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "error interno" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"no se soportan referencias anteriores como condiciones para coincidencias " +"parciales" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "se alcanzó el límite de recursividad" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "combinación de banderas de nueva línea no válidas" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "desplazamiento erróneo" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "UTF8 corto" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "bucle de repetición" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "error desconocido" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ al final del patrón" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c al final del patrón" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "carácter no reconocido después de \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "números fuera de rango en el cuantificador {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "número demasiado grande en el cuantificador {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "falta la terminación ] para la clase de carácter" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "secuencia de escape no válida en la clase de carácter" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "rango fuera de orden en la clase de carácter" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nada que repetir" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "repetición inesperada" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "carácter no reconocido después de (? o (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "Sólo se soportan las clases con nombres POSIX dentro de una clase" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "falta el ) de terminación" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referencia a un subpatrón no existente" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "falta ) después del comentario" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "la expresión regular es demasiado larga" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "falló al obtener memoria" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") sin ( que lo abriera" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "desbordamiento de código" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "carácter no reconocido después de (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "la comprobación «lookbehind» no tiene una longitud fija" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "número o nombre mal formado después de (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "el grupo condicional contiene más de dos ramas" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "se esperaba una comprobación después de (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R o los dígitos (?[+-] deben estar seguidos por )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nombre de clase POSIX desconocido" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "los elementos POSIX recopilados no están soportados" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "el valor del carácter en la secuencia \\x{…} es demasiado largo" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condición no válida (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "no se permite \\C en comprobaciones «lookbehind»" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" +"las secuencias de escape \\L, \\l, \\N{nombre}, \\U, y \\u no están " +"soportadas" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "una llamada recursiva podrá crear un bucle infinito" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "carácter no reconocido después de (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "falta el terminador en el nombre del subpatrón" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dos subpatrones tienen el mismo nombre" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "secuencia \\P o \\p mal formada" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nombre de propiedad desconocido después de \\P o \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "el nombre del subpatrón es demasiado largo (máximo 32 caracteres)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "demasiados subpatrones con nombre (máximo 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "el valor octal es mayor que \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "se desbordó el espacio de trabajo de compilación" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "no se encontró el subpatrón referenciado anteriormente comprobado" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "el grupo DEFINE contiene más de una rama" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opciones NEWLINE inconsistentes" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g no está seguido por un nombre entre llaves, corchetes angulares o número " +"o entre comillas, o por un número simple" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "una referencia con número no puede ser cero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "no se permite un argumento para (*ACCEPT), (*FAIL), o (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) no reconocido" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "el número es demasiado grande" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "falta elnombre del subpatrón después de (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "se esperaba un dígito después de (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] es un carácter de datos no válido en el modo de compatibilidad de " +"JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "no se permiten diferentes nombres para subpatrones del mismo número" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) debe tener un argumento" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c debe estar seguido de un carácter ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k no está seguido por un nombre entre llaves, corchetes angulares o entre " +"comillas" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N no está soportado en una clase" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "demasiadas referencias hacia adelante" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "el nombre es demasiado largo en (*MARK), (*PRUNE), (*SKIP), o (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "el valor del carácter en la secuencia \\u{…} es demasiado largo" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Error al coincidir con la expresión regular %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "La biblioteca PCRE está compilada sin soporte para UTF8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"La biblioteca PCRE está compilada sin soporte para las propiedades de UTF8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "La biblioteca PCRE está compilada con opciones incompatibles" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Error al optimizar la expresión regular %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Error al compilar la expresión regular %s en el carácter %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "se esperaba un dígito hexadecimal o «}»" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "se esperaba un dígito hexadecimal" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "falta «<» en la referencia simbólica" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "referencia de símbolo sin terminar" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "referencia simbólica de longitud cero" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "se esperaba un dígito" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "referencia simbólica ilegal" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "«\\» al final de la cadena" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "secuencia de escape desconocida" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Error al analizar el texto de reemplazo «%s» en el carácter %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "El texto entrecomillado no empieza por un signo de comilla" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Falta una comilla en la línea de comandos o en otro texto con comillas tipo " +"shell" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "" +"El texto termina justo después de un carácter '\\'. (El texto era «%s»)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"El texto terminó antes de que se encontrase la comilla correspondiente con " +"%c. (El texto era «%s»)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "El texto está vacío (o sólo contiene espacios en blanco)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Falló en la lectura de datos desde el proceso hijo (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Error inesperado al leer datos desde el proceso hijo (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Falló inesperado en waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "El proceso hijo terminó con el código %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "El proceso hijo terminado por la señal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "El proceso hijo se detuvo por la señal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "El proceso hijo terminó de forma anormal" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Falló al leer desde el conducto hijo (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Falló al ejecutar el proceso hijo «%s» (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Falló al bifurcar (fork) (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Falló al cambiar a la carpeta «%s» (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Falló al ejecutar el proceso hijo «%s» (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Falló al abrir el archivo para volver a mapear el descriptor: (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Falló al duplicar el descriptor del archivo para el proceso hijo (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Falló al bifurcar el proceso hijo (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Falló al cerrar el descriptor del archivo para el proceso hijo (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Error desconocido al ejecutar el proceso hijo «%s»" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Falló al leer suficientes datos desde el conducto del pid hijo (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Falló al leer los datos desde un proceso hijo" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Falló al ejecutar el proceso hijo (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Falló al hacer dup() en el proceso hijo (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nombre de programa no válido: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Cadena no válida en el vector del argumento en %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Cadena no válida en el entorno: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Carpeta de trabajo no válido: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Falló al ejecutar el programa auxiliar (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Falló inesperado en g_io_channel_win32_poll() al leer datos desde un proceso " +"hijo" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Una cadena vacía no es un número" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "«%s» no es un número con signo" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "El número «%s» está fuera de los límites [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "«%s» no es un número sin signo" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "codificación %-e no válida en el URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Caracter ilegal en el URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caracteres no UTF-8 en el URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Dirección IPv6 «%.*s» no válida en el URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Dirección IP codificada «%.*s» no válida en el URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nombre de equipo traducido «%.*s» no válido en el URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "No se pudo analizar el puerto «%.*s» en el URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Puerto «%.*s» en el URI fuera de rango" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "El URI «%s» no es un URI absoluto" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "El URI «%s» no tiene componente de equipo" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "El URI no es absoluto y no se ha proporcionado un URI base" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Faltan el «=» y el valor del parámetro" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Falló al obtener memoria" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "El carácter se sale del rango para UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Secuencia no válida en la entrada de conversión" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "El carácter se sale del rango para UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "No se puede cargar /var/lib/dbus/machine-id o /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Error desconocido al conectar" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s montado en %s\n" + +#~ msgid "macOS" +#~ msgstr "macOS" + +#~ msgid "Windows" +#~ msgstr "Windows" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Error en la dirección «%s»; el atributo de familia está mal formado" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; ignorando la sobrescritura para esta clave.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr "y se especificoÌ --strict; saliendo.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Ignorando la sobrescritura para esta clave.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "sin hacer nada.\n" + +#~ msgid "No such interface '%s'" +#~ msgstr "La interfaz «%s» no existe" + +#~ msgid "No such method '%s'" +#~ msgstr "No existe el método «%s»" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "No se puede determinar la dirección del bus desde la variable de entorno " +#~ "DBUS_STARTER_BUS_TYPE; variable «%s» desconocida" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGS...]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "FalloÌ al crear el archivo temporal: %s" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "El mensaje tiene %d descriptores de archivo pero el campo de cabecera " +#~ "indica %d descriptores de archivo" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Error: no se especificó la ruta del objeto.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Error: no se especificó la señal.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Error: la señal debe ser el nombre completamente cualificado.\n" + +#~ msgid "No such interface" +#~ msgstr "No existe tal interfaz" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Error al obtener los atributos que se pueden escribir: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Error al montar la ubicación: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Error al desmontar: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Error al buscar el punto de montaje: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Error al expulsar el punto de montaje: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Error al montar %s: %s\n" + +#~ msgid "No files to open" +#~ msgstr "No hay archivos que abrir" + +#~ msgid "No files to delete" +#~ msgstr "No hay archivos que eliminar" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Error al establecer el atributo: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Error al crear la carpeta «%s»: %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Error al abrir el archivo «%s»: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Falló al leer el archivo «%s»: %s" + +#~ msgid "No locations gives" +#~ msgstr "No se han indicado las ubicaciones" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Error al renombrar el archivo: %s" + +#~ msgid "Can't open directory" +#~ msgstr "No se puede abrir la carpeta" + +#~ msgid "Error opening file: %s" +#~ msgstr "Error al abrir el archivo: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Error al crear la carpeta: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "los cambios de asociación no están soportados en win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "La creación de asociación no está soportada en win32" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "" +#~ "No se pudo encontrar el tipo de monitorización de la carpeta local " +#~ "predeterminada" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "El archivo de claves no tiene la clave «%s»" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "Error al procesar el archivo de entrada con xmllint:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "Error al procesar el archivo de entrada con to-pixdata:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "No se pudo obtener el error pendiente: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Falló al abrir el archivo «%s» para escritura: fdopen() falló: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Falló al escribir el archivo «%s»: falló fflush(): %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Falló al cerrar el archivo «%s»: falló fclose(): %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "Recibidos datos incompletos de «%s»" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Opción de longitud inesperada al comprobar si SO_PASSCRED estaba activada " +#~ "para el socket. Se esperaban %d bytes, se obtuvieron %d." + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "" +#~ "Terminación anómala de programa al lanzar («spawn») el comando «%s»: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "" +#~ "El comando de línea «%s» finalizó con un estado de salida distinto de " +#~ "cero %d: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "límite del espacio de trabajo cuando se alcanzan subcadenas vacías" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "aquí no se permite escapar las letras (\\l, \\L, \\u, \\U) (mayúscula y " +#~ "minúscula)" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "no se permite repetir un grupo DEFINE" + +#~ msgid "No service record for '%s'" +#~ msgstr "No hay registro de servicio para «%s»" + +#~ msgid "Could not bind netlink socket: %s" +#~ msgstr "No se pudo conectar el socket netlink: %s:" + +#~ msgid "Could not set options on netlink socket: %s" +#~ msgstr "No se pudieron establecer las opciones del socket netlink: %s" + +#~ msgid "Could not send netlink request: " +#~ msgstr "No se pudo enviar la solicitud netlink:" + +#~ msgid "File is empty" +#~ msgstr "El archivo está vacío" + +#~ msgid "Error connecting: " +#~ msgstr "Error al conectar: " + +#~ msgid "Error connecting: %s" +#~ msgstr "Error al conectar: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Error al leer de unix: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Error al escribir en unix: %s" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "El archivo de claves contiene la clave «%s» que tiene un valor que no " +#~ "puede interpretarse." + +#~ msgid "This option will be removed soon." +#~ msgstr "Pronto se quitará esta opción." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Error al mostrar la información del estado del archivo «%s»: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "" +#~ "La implementación de SOCKSv4 limita el nombre de usuario a %i caracteres" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "" +#~ "La implementación de SOCKSv4a limita el nombre del servidor a %i " +#~ "caracteres" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "am" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" + +#~ msgid "Failed to set value\n" +#~ msgstr "Falló al establecer el valor\n" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "" +#~ "El tipo del valor devuelto es incorrecto, se obtuvo «%s», se esperaba «%s»" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "Intentando establecer la propiedad %s del tipo %s pero según la interfaz " +#~ "esperada el tipo es %s" + +#~| msgid "" +#~| "Error in address '%s' - the noncefile attribute is missing or malformed" +#~ msgid "Error in address '%s' - missing noncefile attribute" +#~ msgstr "" +#~ "Error en la dirección «%s»: falta el atributo para el archivo de número " +#~ "usado una sola vez" + +#~| msgid "Error in address '%s' - the port attribute is malformed" +#~ msgid "Error in address '%s' - missing host attribute" +#~ msgstr "Error en la direccioÌn «%s»; falta el atributo para el servidor" + +#~ msgid "No such schema '%s' specified in override file '%s'" +#~ msgstr "" +#~ "No existe el esquema «%s» especificado en el archivo de sobrescritura «%s»" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "Comandos:\n" +#~ " help Mostrar esta información\n" +#~ " get Obtener el valor de una clave\n" +#~ " set Establecer el valor de una clave\n" +#~ " reset Restablecer el valor de una clave\n" +#~ " monitor Monitorizar si hay cambios en una clave\n" +#~ " writable Comprobar si una clave se puede escribir\n" +#~ "\n" +#~ "Use «%s COMANDO --help» para obtener ayuda de los comandos individuales.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "Especificar la ruta para el esquema" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "Argumentos:\n" +#~ " SCHEMA El ID del esquema\n" +#~ " KEY El nombre de la clave\n" +#~ " VALUE El valor con el que establecer una clave, serializado como " +#~ "GVariant\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "Monitorizar si hay cambios en una clave e imprimir los valores de " +#~ "cambio.\n" +#~ "La monitorización continuará hasta que el proceso haya terminado." + +#~ msgid "Error writing first 16 bytes of message to socket: " +#~ msgstr "Error al escribir los primeros 16 bytes del mensaje en el socket: " + +#~ msgid "Encountered array of length %" +#~ msgstr "Se encontró un vector de longitud %" + +#~ msgid "Do not give error for empty directory" +#~ msgstr "No proporcionar error para un directorio vacío" + +#~ msgid "Manipulate GSettings configuration" +#~ msgstr "Gestionar la configuración de GSettings" + +#~ msgid "" +#~ "You must specify exactly one of --get, --set, --writable or --monitor\n" +#~ msgstr "" +#~ "Debe especificar exactamente una de --get, --set, --writable o --monitor\n" + +#~ msgid "You must specify a schema and a key\n" +#~ msgstr "Debe especificar un esquema y una clave\n" + +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Secuencia inválida en la entrada UTF-8" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "Se alcanzó el límite máximo del array de datos" + +#~ msgid "do not hide entries" +#~ msgstr "no ocultar entradas" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "El carácter «%s» no es válido al inicio del nombre de una entidad; el " +#~ "carácter «&» inicia una entidad; si el signo et ('&') no debiera ser una " +#~ "entidad, escápela como &" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "El carácter «%s» no es válido dentro del nombre de una entidad" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "" +#~ "El carácter de referencia está vacío; debería incluir un dígito tal como " +#~ "dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Referencia de entidad sin terminar" + +#~ msgid "Unfinished character reference" +#~ msgstr "Referencia de carácter sin terminar" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Texto codificado como UTF-8 inválido; secuencia demasiado larga" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Texto codificado como UTF-8 inválido; sin carácter de comienzo" + +#~ msgid "file" +#~ msgstr "archivo" + +#~ msgid "The file containing the icon" +#~ msgstr "El archivo que contiene el icono" + +#~ msgid "An array containing the icon names" +#~ msgstr "Un array que contiene los nombres de los iconos" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "Indica si se debe usar los valores de reserva encontrados al acortar el " +#~ "nombre en los caracteres «-». Si se proporcionan varios nombres los " +#~ "ignora después del primero." + +#~ msgid "File descriptor" +#~ msgstr "Descriptor del archivo" + +#~ msgid "The file descriptor to read from" +#~ msgstr "El descriptor del archivo del que leer" + +#~ msgid "Close file descriptor" +#~ msgstr "Elegir el descriptor del archivo" + +#~ msgid "Whether to close the file descriptor when the stream is closed" +#~ msgstr "" +#~ "Indica si se debe cerrar el descriptor del archivo cuando se cierra el " +#~ "flujo" diff --git a/po/et.po b/po/et.po new file mode 100644 index 0000000..de1cb25 --- /dev/null +++ b/po/et.po @@ -0,0 +1,5932 @@ +# GLib'i eesti tõlge. +# Estonian translation of GLib. +# +# Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 2007–2011 The GNOME Project. +# This file is distributed under the same license as the GLib package. +# +# Allan Sims , 2002. +# Ivar Smolin , 2005–2011. +# Priit Laes , 2005, 2007, 2009 +# Mattias Põldaru , 2009, 2012. +# Mart Raudsepp , 2018 +# +msgid "" +msgstr "" +"Project-Id-Version: glib MASTER\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2018-03-05 13:29+0000\n" +"PO-Revision-Date: 2018-03-12 18:22+0200\n" +"Last-Translator: Mart Raudsepp \n" +"Language-Team: Estonian \n" +"Language: et\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 2.0.6\n" + +#: ../gio/gapplication.c:495 +#, fuzzy +msgid "GApplication options" +msgstr "GApplication võtmed" + +#: ../gio/gapplication.c:495 +#, fuzzy +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "Rakenduse võtmed:" + +#: ../gio/gapplication.c:540 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" + +#: ../gio/gapplication.c:552 +msgid "Override the application’s ID" +msgstr "" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gio-tool.c:227 ../gio/gresource-tool.c:488 +#: ../gio/gsettings-tool.c:569 +msgid "Print help" +msgstr "Prindi abi" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:489 +#: ../gio/gresource-tool.c:557 +msgid "[COMMAND]" +msgstr "[KÄSK]" + +#: ../gio/gapplication-tool.c:49 ../gio/gio-tool.c:228 +#, fuzzy +#| msgid "Print address" +msgid "Print version" +msgstr "Prindi aadress" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:575 +msgid "Print version information and exit" +msgstr "" + +#: ../gio/gapplication-tool.c:52 +#, fuzzy +#| msgid "Can't find application" +msgid "List applications" +msgstr "Rakendust pole võimalik leida" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" + +#: ../gio/gapplication-tool.c:55 +#, fuzzy +#| msgid "Can't find application" +msgid "Launch an application" +msgstr "Rakendust pole võimalik leida" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 ../gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KÄSK" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:665 +#: ../gio/glib-compile-resources.c:671 ../gio/glib-compile-resources.c:698 +#: ../gio/gresource-tool.c:495 ../gio/gresource-tool.c:561 +msgid "FILE" +msgstr "" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "" + +#: ../gio/gapplication-tool.c:73 +#, fuzzy +#| msgid "The connection is closed" +msgid "The action name to invoke" +msgstr "Ühendus on suletud" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:526 +#: ../gio/gsettings-tool.c:661 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Tundmatu käsk '%s'\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +#, fuzzy +#| msgid "Usage:" +msgid "Usage:\n" +msgstr "Kasutamine:" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:551 +#: ../gio/gsettings-tool.c:696 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS…]" +msgstr "" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:266 +#, fuzzy, c-format +#| msgid "Could not connect to %s: " +msgid "unable to connect to D-Bus: %s\n" +msgstr "Pole võimalik %s-ga ühenduda:" + +#: ../gio/gapplication-tool.c:286 +#, fuzzy, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "Viga sõnumi saatmisel: %s" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" + +#: ../gio/gapplication-tool.c:344 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "Viga parameetri %d analüüsimisel: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "" + +#: ../gio/gapplication-tool.c:421 +#, fuzzy, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "" +"Rakenduse käivitamiseks vajalikku terminalprogrammi pole võimalik leida" + +#: ../gio/gapplication-tool.c:466 +#, fuzzy, c-format +#| msgid "" +#| "Unknown command %s\n" +#| "\n" +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"Tundmatu käsk '%s'\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:179 ../gio/ginputstream.c:379 +#: ../gio/ginputstream.c:617 ../gio/ginputstream.c:1019 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:834 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:209 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s-le edastati liiga suur loendi väärtus" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +#, fuzzy +msgid "Seek not supported on base stream" +msgstr "Voogu pole võimalik kerida" + +#: ../gio/gbufferedinputstream.c:937 +#, fuzzy +msgid "Cannot truncate GBufferedInputStream" +msgstr "GMemoryInputStream'i pole võimalik kärpida" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1208 +#: ../gio/giostream.c:300 ../gio/goutputstream.c:1661 +msgid "Stream is already closed" +msgstr "Voog on juba suletud" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Andmevoo alusvoo kärpimine pole toetatud" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1849 +#: ../gio/gdbusprivate.c:1402 ../gio/gsimpleasyncresult.c:871 +#: ../gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operatsioon tühistati" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Vigane objekt, lähtestamata" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Sisendis olev mitmebaidine jada on poolik" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Sihtkohas pole piisavalt vaba ruumi" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1261 ../glib/gconvert.c:454 ../glib/gconvert.c:883 +#: ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:869 ../glib/gutf8.c:1322 +msgid "Invalid byte sequence in conversion input" +msgstr "Vigane baidijada sisendi teisendamisel" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:462 ../glib/gconvert.c:797 +#: ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "Viga teisendamisel: %s" + +#: ../gio/gcharsetconverter.c:445 ../gio/gsocket.c:1104 +msgid "Cancellable initialization not supported" +msgstr "Tühistatav käivitamine ei ole toetatud" + +#: ../gio/gcharsetconverter.c:456 ../glib/gconvert.c:327 +#: ../glib/giochannel.c:1385 +#, fuzzy, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Teisendamine koodistikust '%s' koodistikku '%s' ei ole toetatud" + +#: ../gio/gcharsetconverter.c:460 ../glib/gconvert.c:331 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Konverterit '%s'-st '%s'-ks pole võimalik avada" + +#: ../gio/gcontenttype.c:358 +#, c-format +msgid "%s type" +msgstr "%s tüüp" + +#: ../gio/gcontenttype-win32.c:177 +msgid "Unknown type" +msgstr "Tundmatu tüüp" + +#: ../gio/gcontenttype-win32.c:179 +#, c-format +msgid "%s filetype" +msgstr "%s failitüüp" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "Selle operatsioonisüsteemi jaoks pole loodud GCredentialsi tuge" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "Sinu platvormile puudub GCredentialsi tugi" + +#: ../gio/gcredentials.c:513 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "GCredentials does not contain a process ID on this OS" +msgstr "Selle operatsioonisüsteemi jaoks pole loodud GCredentialsi tuge" + +#: ../gio/gcredentials.c:565 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "Selle operatsioonisüsteemi jaoks pole loodud GCredentialsi tuge" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Ootamatult varajane voolõpp" + +#: ../gio/gdbusaddress.c:158 ../gio/gdbusaddress.c:246 +#: ../gio/gdbusaddress.c:327 +#, fuzzy, c-format +#| msgid "Unsupported key '%s' in address entry '%s'" +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Toetamata võti \"%s\" aadressikirjes \"%s\"" + +#: ../gio/gdbusaddress.c:185 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:198 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:261 ../gio/gdbusaddress.c:342 +#, c-format +msgid "Error in address “%s†— the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:272 ../gio/gdbusaddress.c:353 +#, c-format +msgid "Error in address “%s†— the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:463 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:484 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:498 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:576 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:612 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:626 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:640 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:661 +msgid "Error auto-launching: " +msgstr "Viga automaatsel käivitamisel: " + +#: ../gio/gdbusaddress.c:669 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:714 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Viga nonce faili „%s“ avamisel: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s': %s" +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Viga nonce failist '%s' lugemisel: %s" + +#: ../gio/gdbusaddress.c:742 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Viga nonce failist '%s' lugemisel, oodati 16 baiti, saadi %d" + +#: ../gio/gdbusaddress.c:760 +#, fuzzy, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Viga faili kirjutamisel: %s" + +#: ../gio/gdbusaddress.c:969 +msgid "The given address is empty" +msgstr "Antud aadress on tühi" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "" + +#: ../gio/gdbusaddress.c:1089 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1096 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: ../gio/gdbusaddress.c:1138 +#, fuzzy, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Viga failist '%s' lugemisel: %s" + +#: ../gio/gdbusaddress.c:1355 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: ../gio/gdbusaddress.c:1509 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: ../gio/gdbusaddress.c:1520 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1658 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:1667 ../gio/gdbusconnection.c:7160 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1677 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tundmatu siinitüüp %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1171 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:262 +#, fuzzy, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Viga kataloogi '%s' avamisel: %s" + +#: ../gio/gdbusauthmechanismsha1.c:274 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:296 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory “%sâ€: %s" +msgstr "Viga kataloogi '%s' loomisel: %s" + +#: ../gio/gdbusauthmechanismsha1.c:379 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for reading: " +msgid "Error opening keyring “%s†for reading: " +msgstr "Viga võtmerõnga '%s' avamisel lugemiseks: " + +#: ../gio/gdbusauthmechanismsha1.c:402 ../gio/gdbusauthmechanismsha1.c:720 +#, fuzzy, c-format +#| msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Rida %d võtmerõngas kohas '%s' sisuga '%s' on vigane" + +#: ../gio/gdbusauthmechanismsha1.c:416 ../gio/gdbusauthmechanismsha1.c:734 +#, fuzzy, c-format +#| msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Rida %d võtmerõngas kohas '%s' sisuga '%s' on vigane" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:748 +#, fuzzy, c-format +#| msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Rida %d võtmerõngas kohas '%s' sisuga '%s' on vigane" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, fuzzy, c-format +#| msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Küpsist id-ga %d võtmerõngas kohas '%s' ei leitud" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +#| msgid "Error deleting stale lock file '%s': %s" +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Viga iganenud lukufaili '%s' kustutamisel: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +#| msgid "Error creating lock file '%s': %s" +msgid "Error creating lock file “%sâ€: %s" +msgstr "Viga lukufaili '%s' loomisel: %s" + +#: ../gio/gdbusauthmechanismsha1.c:599 +#, fuzzy, c-format +#| msgid "Error closing (unlinked) lock file '%s': %s" +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Viga (kustutatud) lukufaili '%s' sulgemisel: %s" + +#: ../gio/gdbusauthmechanismsha1.c:610 +#, fuzzy, c-format +#| msgid "Error unlinking lock file '%s': %s" +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Viga lukufaili '%s' kustutamisel: %s" + +#: ../gio/gdbusauthmechanismsha1.c:687 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for writing: " +msgid "Error opening keyring “%s†for writing: " +msgstr "Viga võtmerõnga '%s' avamisel kirjutamiseks:" + +#: ../gio/gdbusauthmechanismsha1.c:883 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2378 +msgid "The connection is closed" +msgstr "Ühendus on suletud" + +#: ../gio/gdbusconnection.c:1879 +msgid "Timeout was reached" +msgstr "Ületati ajapiirang" + +#: ../gio/gdbusconnection.c:2500 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:4124 ../gio/gdbusconnection.c:4471 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4266 +#, c-format +msgid "No such property '%s'" +msgstr "Omadust '%s' pole" + +#: ../gio/gdbusconnection.c:4278 +#, c-format +msgid "Property '%s' is not readable" +msgstr "Omadus '%s' pole loetav" + +#: ../gio/gdbusconnection.c:4289 +#, c-format +msgid "Property '%s' is not writable" +msgstr "Omadus '%s' pole kirjutatav" + +#: ../gio/gdbusconnection.c:4309 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4414 ../gio/gdbusconnection.c:4622 +#: ../gio/gdbusconnection.c:6591 +#, c-format +msgid "No such interface '%s'" +msgstr "Liidest '%s' pole" + +#: ../gio/gdbusconnection.c:4840 ../gio/gdbusconnection.c:7100 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "Objektil asukohas %s pole liidest '%s'" + +#: ../gio/gdbusconnection.c:4938 +#, c-format +msgid "No such method '%s'" +msgstr "Meetodit '%s' pole" + +#: ../gio/gdbusconnection.c:4969 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5167 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:5393 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to retrieve property %s.%s" +msgstr "Soklit pole võimalik luua: %s" + +#: ../gio/gdbusconnection.c:5449 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to set property %s.%s" +msgstr "Soklit pole võimalik luua: %s" + +#: ../gio/gdbusconnection.c:5627 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:6702 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6823 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "Kuulaja on juba suletud" + +#: ../gio/gdbusconnection.c:7151 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" + +#: ../gio/gdbusmessage.c:1593 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Analüüsitud väärtus „%s“ pole korrektne D-Busi objekti rada" + +#: ../gio/gdbusmessage.c:1615 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Analüüsitud väärtus „%s“ pole korrektne D-Busi signatuur" + +#: ../gio/gdbusmessage.c:1662 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1682 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: ../gio/gdbusmessage.c:1849 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Analüüsitud variandi väärtus „%s“ pole korrektne D-Busi signatuur" + +#: ../gio/gdbusmessage.c:1873 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2055 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:2068 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:2124 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:2138 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Analüüsitud väärtus \"%s\" pole korrektne D-Busi signatuur (keha jaoks)" + +#: ../gio/gdbusmessage.c:2168 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:2178 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2519 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2656 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: ../gio/gdbusmessage.c:2664 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2708 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2718 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" + +#: ../gio/gdbusmessage.c:2734 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" + +#: ../gio/gdbusmessage.c:3287 +#, fuzzy, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Viga faili kirjutamisel: %s" + +#: ../gio/gdbusmessage.c:3295 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:2066 +#, fuzzy, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Faili pole võimalik prügikasti visata: %s" + +#: ../gio/gdbusprivate.c:2111 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1612 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1635 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2726 ../gio/gdbusproxy.c:2860 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "Abstraktne nimeruum pole toetatud" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:876 +#, fuzzy, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Viga faili kirjutamisel: %s" + +#: ../gio/gdbusserver.c:1047 +#, fuzzy, c-format +#| msgid "The string '%s' is not a valid D-Bus GUID" +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "String '%s' pole korrektne D-Bus GUID" + +#: ../gio/gdbusserver.c:1087 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:185 ../gio/gdbus-tool.c:252 ../gio/gdbus-tool.c:324 +#: ../gio/gdbus-tool.c:348 ../gio/gdbus-tool.c:834 ../gio/gdbus-tool.c:1171 +#: ../gio/gdbus-tool.c:1613 +#, c-format +msgid "Error: %s\n" +msgstr "Viga: %s\n" + +#: ../gio/gdbus-tool.c:196 ../gio/gdbus-tool.c:265 ../gio/gdbus-tool.c:1629 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:234 +#, fuzzy, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Viga: %s pole korrektne objekti rada\n" + +#: ../gio/gdbus-tool.c:382 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:384 +msgid "Connect to given D-Bus address" +msgstr "Ühendumine määratud D-Bus aadressiga" + +#: ../gio/gdbus-tool.c:394 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:395 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:417 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:427 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:497 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:506 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:569 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:570 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:603 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:658 ../gio/gdbus-tool.c:965 ../gio/gdbus-tool.c:1715 +#: ../gio/gdbus-tool.c:1944 ../gio/gdbus-tool.c:2164 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Viga ühendumisel: %s\n" + +#: ../gio/gdbus-tool.c:678 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Viga: %s pole korrektne objekti rada\n" + +#: ../gio/gdbus-tool.c:697 ../gio/gdbus-tool.c:1008 ../gio/gdbus-tool.c:1758 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "Viga: objekti rada on määramata\n" + +#: ../gio/gdbus-tool.c:720 ../gio/gdbus-tool.c:1028 ../gio/gdbus-tool.c:1778 +#: ../gio/gdbus-tool.c:2015 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Viga: %s pole korrektne objekti rada\n" + +#: ../gio/gdbus-tool.c:740 +#, fuzzy, c-format +#| msgid "Error: Method name is not specified\n" +msgid "Error: Signal name is not specified\n" +msgstr "Viga: meetodi nimi on määramata\n" + +#: ../gio/gdbus-tool.c:754 +#, fuzzy, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Viga: vigane meetodi nimi \"%s\"\n" + +#: ../gio/gdbus-tool.c:766 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Viga: %s pole korrektne objekti rada\n" + +#: ../gio/gdbus-tool.c:772 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Viga: %s pole korrektne objekti rada\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:809 ../gio/gdbus-tool.c:1140 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Viga parameetri %d analüüsimisel: %s\n" + +#: ../gio/gdbus-tool.c:841 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Viga ühendusega nõustumisel: %s" + +#: ../gio/gdbus-tool.c:868 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:869 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:870 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:871 +#, fuzzy +msgid "Timeout in seconds" +msgstr "Ületati ajapiirang" + +#: ../gio/gdbus-tool.c:910 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:982 ../gio/gdbus-tool.c:1732 ../gio/gdbus-tool.c:1969 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "Viga: sihtkoht on määramata\n" + +#: ../gio/gdbus-tool.c:993 ../gio/gdbus-tool.c:1749 ../gio/gdbus-tool.c:1980 +#, fuzzy, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Viga: %s pole korrektne objekti rada\n" + +#: ../gio/gdbus-tool.c:1043 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "Viga: meetodi nimi on määramata\n" + +#: ../gio/gdbus-tool.c:1054 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Viga: vigane meetodi nimi „%s“\n" + +#: ../gio/gdbus-tool.c:1132 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Viga „%2$s“ tüüpi parameetri %1$d analüüsimisel: %3$s\n" + +#: ../gio/gdbus-tool.c:1576 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1577 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1578 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1579 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1580 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1667 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1870 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1871 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1896 +msgid "Monitor a remote object." +msgstr "Kaugobjekti monitoorimine." + +#: ../gio/gdbus-tool.c:1954 +#, c-format +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: ../gio/gdbus-tool.c:2078 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: ../gio/gdbus-tool.c:2081 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: ../gio/gdbus-tool.c:2129 +msgid "[OPTION…] BUS-NAME" +msgstr "" + +#: ../gio/gdbus-tool.c:2130 +msgid "Wait for a bus name to appear." +msgstr "" + +#: ../gio/gdbus-tool.c:2206 +#, fuzzy, c-format +msgid "Error: A service to activate for must be specified.\n" +msgstr "Viga: objekti rada on määramata\n" + +#: ../gio/gdbus-tool.c:2211 +#, fuzzy, c-format +msgid "Error: A service to wait for must be specified.\n" +msgstr "Viga: objekti rada on määramata\n" + +#: ../gio/gdbus-tool.c:2216 +#, c-format +msgid "Error: Too many arguments.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:2224 ../gio/gdbus-tool.c:2231 +#, fuzzy, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Viga: %s pole korrektne objekti rada\n" + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4566 +msgid "Unnamed" +msgstr "Nimeta" + +#: ../gio/gdesktopappinfo.c:2411 +#, fuzzy +#| msgid "Desktop file didn't specify Exec field" +msgid "Desktop file didn’t specify Exec field" +msgstr "Töölauafail ei määra Exec-välja" + +#: ../gio/gdesktopappinfo.c:2701 +msgid "Unable to find terminal required for application" +msgstr "" +"Rakenduse käivitamiseks vajalikku terminalprogrammi pole võimalik leida" + +#: ../gio/gdesktopappinfo.c:3135 +#, fuzzy, c-format +#| msgid "Can't create user application configuration folder %s: %s" +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Kasutaja rakenduse seadistustekataloogi %s pole võimalik luua: %s" + +#: ../gio/gdesktopappinfo.c:3139 +#, fuzzy, c-format +#| msgid "Can't create user MIME configuration folder %s: %s" +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Kasutaja MIME-seadistustekataloogi %s pole võimalik luua: %s" + +#: ../gio/gdesktopappinfo.c:3379 ../gio/gdesktopappinfo.c:3403 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3637 +#, fuzzy, c-format +#| msgid "Can't create user desktop file %s" +msgid "Can’t create user desktop file %s" +msgstr "Kasutaja töölauafaili %s pole võimalik luua" + +#: ../gio/gdesktopappinfo.c:3771 +#, c-format +msgid "Custom definition for %s" +msgstr "%s oma definitsioon" + +#: ../gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "seade ei toeta väljastamist" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "seade ei toeta väljastamist ega väljastamist koos operatsiooniga" + +#: ../gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "seade ei toeta meediumi olemasolu pärimist" + +#: ../gio/gdrive.c:776 +msgid "drive doesn’t implement start" +msgstr "seade ei toeta käivitamist" + +#: ../gio/gdrive.c:878 +msgid "drive doesn’t implement stop" +msgstr "seade ei toeta seiskamist" + +#: ../gio/gdummytlsbackend.c:195 ../gio/gdummytlsbackend.c:317 +#: ../gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "GEmblem’i kodeeringu versiooni %d pole võimalik käsitseda" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Vigane märgiste arv (%d) GEmblem’i kodeeringus" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon’i kodeeringu versiooni %d pole võimalik käsitseda" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Vigane märgiste arv (%d) GEmblemedIcon'i kodeeringus" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Oodati GEmblem'i GEmblemedIcon'i jaoks" + +#: ../gio/gfile.c:1071 ../gio/gfile.c:1309 ../gio/gfile.c:1447 +#: ../gio/gfile.c:1685 ../gio/gfile.c:1740 ../gio/gfile.c:1798 +#: ../gio/gfile.c:1882 ../gio/gfile.c:1939 ../gio/gfile.c:2003 +#: ../gio/gfile.c:2058 ../gio/gfile.c:3725 ../gio/gfile.c:3780 +#: ../gio/gfile.c:4016 ../gio/gfile.c:4058 ../gio/gfile.c:4526 +#: ../gio/gfile.c:4937 ../gio/gfile.c:5022 ../gio/gfile.c:5112 +#: ../gio/gfile.c:5209 ../gio/gfile.c:5296 ../gio/gfile.c:5397 +#: ../gio/gfile.c:7975 ../gio/gfile.c:8065 ../gio/gfile.c:8149 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "Operatsioon ei ole toetatud" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: ../gio/gfile.c:1570 +msgid "Containing mount does not exist" +msgstr "Sisalduvat haaget pole olemas" + +#: ../gio/gfile.c:2617 ../gio/glocalfile.c:2446 +#, fuzzy +#| msgid "Can't copy over directory" +msgid "Can’t copy over directory" +msgstr "Kataloogi peale pole võimalik kopeerida" + +#: ../gio/gfile.c:2677 +msgid "Can’t copy directory over directory" +msgstr "Kataloogi pole võimalik kataloogi peale kopeerida" + +#: ../gio/gfile.c:2685 +msgid "Target file exists" +msgstr "Sihtfail on olemas" + +#: ../gio/gfile.c:2704 +msgid "Can’t recursively copy directory" +msgstr "Kataloogi pole võimalik rekursiivselt kopeerida" + +#: ../gio/gfile.c:2979 +msgid "Splice not supported" +msgstr "Ühendamine ei ole toetatud" + +#: ../gio/gfile.c:2983 ../gio/gfile.c:3027 +#, c-format +msgid "Error splicing file: %s" +msgstr "Viga faili ühendamisel: %s" + +#: ../gio/gfile.c:3136 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"Erinevate haakeseadmete vahel kopeerimine (reflink/clone) pole toetatud" + +#: ../gio/gfile.c:3140 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: ../gio/gfile.c:3145 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" + +#: ../gio/gfile.c:3208 +msgid "Can’t copy special file" +msgstr "Erifaili pole võimalik kopeerida" + +#: ../gio/gfile.c:4006 +msgid "Invalid symlink value given" +msgstr "Määrati vigane nimeviida väärtus" + +#: ../gio/gfile.c:4167 +msgid "Trash not supported" +msgstr "Prügikast pole toetatud" + +#: ../gio/gfile.c:4279 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Failinimed ei tohi sisaldada märki „%c“" + +#: ../gio/gfile.c:6760 ../gio/gvolume.c:363 +msgid "volume doesn’t implement mount" +msgstr "köide ei toeta haakimist" + +#: ../gio/gfile.c:6869 +msgid "No application is registered as handling this file" +msgstr "Selle faili käsitlemiseks pole rakendust registreeritud" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Nummerdaja on suletud" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Failide nummerdajat kasutatakse väljastpoolt" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Failinummerdaja on juba suletud" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "GFileIcon’i kodeeringu versiooni %d pole võimalik käsitseda" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Vigaselt vormindatud andmed GFileIcon'i jaoks" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Voog ei toeta query_info’t" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Voogu pole võimalik kerida" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Sisendvoo kärpimine pole lubatud" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Andmevoo kärpimine pole toetatud" + +#: ../gio/ghttpproxy.c:91 ../gio/gresolver.c:410 ../gio/gresolver.c:476 +#: ../glib/gconvert.c:1786 +msgid "Invalid hostname" +msgstr "Vigane hostinimi" + +#: ../gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "" + +#: ../gio/ghttpproxy.c:159 +#, fuzzy +#| msgid "The connection is closed" +msgid "HTTP proxy connection not allowed" +msgstr "Ühendus on suletud" + +#: ../gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "" + +#: ../gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "" + +#: ../gio/ghttpproxy.c:171 +#, fuzzy, c-format +#| msgid "The connection is closed" +msgid "HTTP proxy connection failed: %i" +msgstr "Ühendus on suletud" + +#: ../gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Vale arv märgiseid (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "Klassinimel %s puudub tüüp" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Tüüp %s ei toeta GIcon liidest" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "Liik %s pole klassifitseeritud" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "Vigaselt vormindatud versiooninumber: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Tüüp %s ei toeta from_tokens() funktsiooni GIcon liidese jaoks" + +#: ../gio/gicon.c:461 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Antud ikooni kodeerimise versiooni pole võimalik käsitseda" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: ../gio/ginetaddressmask.c:300 +#, fuzzy, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "kohalikku aadressi ei suudeta määrata: %s" + +#: ../gio/ginetsocketaddress.c:203 ../gio/ginetsocketaddress.c:220 +#: ../gio/gnativesocketaddress.c:109 ../gio/gunixsocketaddress.c:218 +msgid "Not enough space for socket address" +msgstr "Sokliaadressi jaoks ei ole piisavalt vaba ruumi" + +#: ../gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Toetamata sokliaadress" + +#: ../gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Sisendvoog ei toeta lugemist" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1218 ../gio/giostream.c:310 +#: ../gio/goutputstream.c:1671 +msgid "Stream has outstanding operation" +msgstr "Voogu juba kasutatakse väljastpoolt" + +#: ../gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "" + +#: ../gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "" + +#: ../gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "" + +#: ../gio/gio-tool.c:207 ../gio/gio-tool.c:223 ../glib/goption.c:857 +msgid "Usage:" +msgstr "Kasutamine:" + +#: ../gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "" + +#: ../gio/gio-tool.c:224 +msgid "[ARGS...]" +msgstr "" + +#: ../gio/gio-tool.c:226 +msgid "Commands:" +msgstr "" + +#: ../gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: ../gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "" + +#: ../gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "" + +#: ../gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "" + +#: ../gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: ../gio/gio-tool.c:234 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create directories" +msgstr "Kataloogi pole võimalik avada" + +#: ../gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "" + +#: ../gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "" + +#: ../gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "" + +#: ../gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "" + +#: ../gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "" + +#: ../gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "" + +#: ../gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "" + +#: ../gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "" + +#: ../gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "" + +#: ../gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: ../gio/gio-tool.c:246 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" + +#: ../gio/gio-tool-cat.c:87 +#, fuzzy +#| msgid "Error writing to file: %s" +msgid "Error writing to stdout" +msgstr "Viga faili kirjutamisel: %s" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-cat.c:133 ../gio/gio-tool-info.c:282 +#: ../gio/gio-tool-list.c:165 ../gio/gio-tool-mkdir.c:48 +#: ../gio/gio-tool-monitor.c:37 ../gio/gio-tool-monitor.c:39 +#: ../gio/gio-tool-monitor.c:41 ../gio/gio-tool-monitor.c:43 +#: ../gio/gio-tool-monitor.c:203 ../gio/gio-tool-mount.c:1141 +#: ../gio/gio-tool-open.c:113 ../gio/gio-tool-remove.c:48 +#: ../gio/gio-tool-rename.c:45 ../gio/gio-tool-set.c:89 +#: ../gio/gio-tool-trash.c:81 ../gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "" + +#: ../gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" + +#: ../gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: ../gio/gio-tool-cat.c:162 ../gio/gio-tool-info.c:313 +#: ../gio/gio-tool-mkdir.c:76 ../gio/gio-tool-monitor.c:228 +#: ../gio/gio-tool-open.c:139 ../gio/gio-tool-remove.c:72 +msgid "No locations given" +msgstr "" + +#: ../gio/gio-tool-copy.c:42 ../gio/gio-tool-move.c:38 +#, fuzzy +#| msgid "Target file is a directory" +msgid "No target directory" +msgstr "Sihtfail on kataloog" + +#: ../gio/gio-tool-copy.c:43 ../gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "" + +#: ../gio/gio-tool-copy.c:44 ../gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "" + +#: ../gio/gio-tool-copy.c:45 +msgid "Preserve all attributes" +msgstr "" + +#: ../gio/gio-tool-copy.c:46 ../gio/gio-tool-move.c:41 +#: ../gio/gio-tool-save.c:49 +#, fuzzy +#| msgid "Backup file creation failed" +msgid "Backup existing destination files" +msgstr "Tõrge varufaili loomisel" + +#: ../gio/gio-tool-copy.c:47 +msgid "Never follow symbolic links" +msgstr "" + +#: ../gio/gio-tool-copy.c:72 ../gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +#: ../gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "" + +#: ../gio/gio-tool-copy.c:103 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" + +#: ../gio/gio-tool-copy.c:105 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: ../gio/gio-tool-copy.c:147 +#, fuzzy, c-format +msgid "Destination %s is not a directory" +msgstr "Sihtfail on kataloog" + +#: ../gio/gio-tool-copy.c:192 ../gio/gio-tool-move.c:185 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "" + +#: ../gio/gio-tool-info.c:34 +msgid "List writable attributes" +msgstr "" + +#: ../gio/gio-tool-info.c:35 +#, fuzzy +#| msgid "Error getting filesystem info: %s" +msgid "Get file system info" +msgstr "Viga failisüsteemi andmete hankimisel: %s" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "The attributes to get" +msgstr "" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "ATTRIBUTES" +msgstr "" + +#: ../gio/gio-tool-info.c:37 ../gio/gio-tool-list.c:38 ../gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "" + +#: ../gio/gio-tool-info.c:75 +#, c-format +msgid "attributes:\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:138 +#, c-format +msgid "name: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:151 +#, c-format +msgid "size: " +msgstr "" + +#: ../gio/gio-tool-info.c:156 +#, c-format +msgid "hidden\n" +msgstr "" + +#: ../gio/gio-tool-info.c:159 +#, fuzzy, c-format +#| msgid "Error: %s\n" +msgid "uri: %s\n" +msgstr "Viga: %s\n" + +#: ../gio/gio-tool-info.c:228 +#, c-format +msgid "Settable attributes:\n" +msgstr "" + +#: ../gio/gio-tool-info.c:252 +#, c-format +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: ../gio/gio-tool-info.c:287 +msgid "Show information about locations." +msgstr "" + +#: ../gio/gio-tool-info.c:289 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#: ../gio/gio-tool-list.c:36 ../gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "" + +#: ../gio/gio-tool-list.c:37 +msgid "Use a long listing format" +msgstr "" + +#: ../gio/gio-tool-list.c:39 +msgid "Print full URIs" +msgstr "" + +#: ../gio/gio-tool-list.c:170 +msgid "List the contents of the locations." +msgstr "" + +#: ../gio/gio-tool-list.c:172 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: ../gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: ../gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: ../gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: ../gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: ../gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:127 +#, c-format +msgid "Registered applications:\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:129 +#, fuzzy, c-format +#| msgid "Can't find application" +msgid "No registered applications\n" +msgstr "Rakendust pole võimalik leida" + +#: ../gio/gio-tool-mime.c:140 +#, c-format +msgid "Recommended applications:\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:142 +#, fuzzy, c-format +#| msgid "Can't find application" +msgid "No recommended applications\n" +msgstr "Rakendust pole võimalik leida" + +#: ../gio/gio-tool-mime.c:162 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "Tõrge failist '%s' lugemisel: %s" + +#: ../gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" + +#: ../gio/gio-tool-mkdir.c:31 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create parent directories" +msgstr "Kataloogi pole võimalik avada" + +#: ../gio/gio-tool-mkdir.c:52 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create directories." +msgstr "Kataloogi pole võimalik avada" + +#: ../gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: ../gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: ../gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: ../gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: ../gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "" + +#: ../gio/gio-tool-mount.c:58 +msgid "Mount as mountable" +msgstr "" + +#: ../gio/gio-tool-mount.c:59 +msgid "Mount volume with device file" +msgstr "" + +#: ../gio/gio-tool-mount.c:59 +msgid "DEVICE" +msgstr "" + +#: ../gio/gio-tool-mount.c:60 +msgid "Unmount" +msgstr "" + +#: ../gio/gio-tool-mount.c:61 +msgid "Eject" +msgstr "" + +#: ../gio/gio-tool-mount.c:62 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: ../gio/gio-tool-mount.c:62 +msgid "SCHEME" +msgstr "" + +#: ../gio/gio-tool-mount.c:63 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: ../gio/gio-tool-mount.c:64 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: ../gio/gio-tool-mount.c:66 +msgid "List" +msgstr "" + +#: ../gio/gio-tool-mount.c:67 +msgid "Monitor events" +msgstr "" + +#: ../gio/gio-tool-mount.c:68 +msgid "Show extra information" +msgstr "Lisateabe näitamine" + +#: ../gio/gio-tool-mount.c:246 ../gio/gio-tool-mount.c:276 +msgid "Anonymous access denied" +msgstr "" + +#: ../gio/gio-tool-mount.c:897 +#, c-format +msgid "Mounted %s at %s\n" +msgstr "" + +#: ../gio/gio-tool-mount.c:950 +msgid "No volume for device file" +msgstr "" + +#: ../gio/gio-tool-mount.c:1145 +msgid "Mount or unmount the locations." +msgstr "" + +#: ../gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: ../gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: ../gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: ../gio/gio-tool-move.c:142 +#, fuzzy, c-format +#| msgid "Target file is a directory" +msgid "Target %s is not a directory" +msgstr "Sihtfail on kataloog" + +#: ../gio/gio-tool-open.c:118 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: ../gio/gio-tool-remove.c:31 ../gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: ../gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "" + +#: ../gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "" + +#: ../gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "" + +#: ../gio/gio-tool-rename.c:70 +#, fuzzy +#| msgid "Missing argument for %s" +msgid "Missing argument" +msgstr "Puuduv argument %s'i jaoks" + +#: ../gio/gio-tool-rename.c:76 ../gio/gio-tool-save.c:190 +#: ../gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "" + +#: ../gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: ../gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "" + +#: ../gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "" + +#: ../gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: ../gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: ../gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "" + +#: ../gio/gio-tool-save.c:113 +#, fuzzy +msgid "Error reading from standard input" +msgstr "Viga pidemest lugemisel: %s" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:139 +#, c-format +msgid "Etag not available\n" +msgstr "" + +#: ../gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: ../gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "" + +#: ../gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "" + +#: ../gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "" + +#: ../gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "" + +#: ../gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "" + +#: ../gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "" + +#: ../gio/gio-tool-set.c:113 +#, fuzzy +#| msgid "Error: Destination is not specified\n" +msgid "Location not specified" +msgstr "Viga: sihtkoht on määramata\n" + +#: ../gio/gio-tool-set.c:120 +#, fuzzy +msgid "Attribute not specified" +msgstr "Viga: sihtkoht on määramata\n" + +#: ../gio/gio-tool-set.c:130 +#, fuzzy +msgid "Value not specified" +msgstr "Viga: sihtkoht on määramata\n" + +#: ../gio/gio-tool-set.c:180 +#, fuzzy, c-format +#| msgid "Invalid attribute type (string expected)" +msgid "Invalid attribute type “%sâ€" +msgstr "Vigane rekvisiidi tüüp (oodatakse stringi)" + +#: ../gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "" + +#: ../gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "" + +#: ../gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" + +#: ../gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1501 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-resources.c:237 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:248 +#, fuzzy, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Tõrge kataloogi '%s' muutmisel (%s)" + +#: ../gio/glib-compile-resources.c:259 +#, fuzzy, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Tõrge kataloogi '%s' muutmisel (%s)" + +#: ../gio/glib-compile-resources.c:290 +#, fuzzy, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Tundmatu võti %s" + +#: ../gio/glib-compile-resources.c:308 ../gio/glib-compile-resources.c:354 +#, fuzzy, c-format +msgid "Failed to create temp file: %s" +msgstr "Tõrge faili '%s' loomisel: %s" + +#: ../gio/glib-compile-resources.c:382 +#, fuzzy, c-format +msgid "Error reading file %s: %s" +msgstr "Viga failist '%s' lugemisel: %s" + +#: ../gio/glib-compile-resources.c:402 +#, fuzzy, c-format +msgid "Error compressing file %s" +msgstr "Viga faili sulgemisel: %s" + +#: ../gio/glib-compile-resources.c:469 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:664 ../gio/glib-compile-schemas.c:2067 +msgid "Show program version and exit" +msgstr "" + +#: ../gio/glib-compile-resources.c:665 +msgid "name of the output file" +msgstr "" + +#: ../gio/glib-compile-resources.c:666 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" + +#: ../gio/glib-compile-resources.c:666 ../gio/glib-compile-schemas.c:2068 +#: ../gio/glib-compile-schemas.c:2096 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-resources.c:667 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: ../gio/glib-compile-resources.c:668 +msgid "Generate source header" +msgstr "" + +#: ../gio/glib-compile-resources.c:669 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" + +#: ../gio/glib-compile-resources.c:670 +msgid "Generate dependency list" +msgstr "" + +#: ../gio/glib-compile-resources.c:671 +msgid "name of the dependency file to generate" +msgstr "" + +#: ../gio/glib-compile-resources.c:672 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: ../gio/glib-compile-resources.c:673 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:674 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: ../gio/glib-compile-resources.c:675 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: ../gio/glib-compile-resources.c:701 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: ../gio/glib-compile-resources.c:723 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:95 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: ../gio/glib-compile-schemas.c:106 +#, fuzzy, c-format +#| msgid "Invalid symlink value given" +msgid "Invalid numeric value" +msgstr "Määrati vigane nimeviida väärtus" + +#: ../gio/glib-compile-schemas.c:114 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:122 +#, c-format +msgid "value='%s' already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:136 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: ../gio/glib-compile-schemas.c:161 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: ../gio/glib-compile-schemas.c:315 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "" + +#: ../gio/glib-compile-schemas.c:327 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:333 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:339 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:373 +msgid " already specified for this key" +msgstr "" + +#: ../gio/glib-compile-schemas.c:391 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:408 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: ../gio/glib-compile-schemas.c:433 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: ../gio/glib-compile-schemas.c:441 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: ../gio/glib-compile-schemas.c:453 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: ../gio/glib-compile-schemas.c:475 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:492 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:501 +msgid " already specified for this key" +msgstr "" + +#: ../gio/glib-compile-schemas.c:513 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:529 +#, c-format +msgid " already given" +msgstr "" + +#: ../gio/glib-compile-schemas.c:544 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: ../gio/glib-compile-schemas.c:558 +msgid " already specified for this key" +msgstr "" + +#: ../gio/glib-compile-schemas.c:562 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: ../gio/glib-compile-schemas.c:581 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:587 +#, c-format +msgid " given when was already given" +msgstr "" + +#: ../gio/glib-compile-schemas.c:595 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:606 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:621 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: ../gio/glib-compile-schemas.c:786 +#, fuzzy +#| msgid "empty names are not permitted" +msgid "Empty names are not permitted" +msgstr "tühjad nimed pole lubatud" + +#: ../gio/glib-compile-schemas.c:796 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:808 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:817 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" + +#: ../gio/glib-compile-schemas.c:834 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:904 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:930 +msgid "Cannot add keys to a “list-of†schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:941 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:959 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:970 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1004 +#, fuzzy, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Vigane rekvisiidi tüüp (oodatakse stringi)" + +#: ../gio/glib-compile-schemas.c:1034 +msgid " given but schema isn’t extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1047 +#, c-format +msgid "No to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1055 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1128 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1140 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1156 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1164 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1174 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1184 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1211 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1218 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1227 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1257 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1407 ../gio/glib-compile-schemas.c:1423 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1505 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1523 +msgid "Element is required in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1613 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1681 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1820 ../gio/glib-compile-schemas.c:1894 +#: ../gio/glib-compile-schemas.c:1970 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1830 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "Tervet faili ignoreeriti.\n" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Seda faili ignoreeritakse.\n" + +#: ../gio/glib-compile-schemas.c:1930 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1936 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2022 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 ../gio/glib-compile-schemas.c:1998 +#: ../gio/glib-compile-schemas.c:2026 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1966 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1984 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2012 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2068 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2069 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2070 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2071 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2099 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:2120 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2162 +#, c-format +msgid "No schema files found: " +msgstr "Ühtegi skeemifaili ei leitud:" + +#: ../gio/glib-compile-schemas.c:2165 +#, c-format +msgid "doing nothing.\n" +msgstr "ei tehta midagi.\n" + +#: ../gio/glib-compile-schemas.c:2168 +#, c-format +msgid "removed existing output file.\n" +msgstr "eemaldati olemasolev väljundfail.\n" + +#: ../gio/glocalfile.c:643 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "Vigane failinimi %s" + +#: ../gio/glocalfile.c:1105 +#, fuzzy, c-format +#| msgid "Error getting filesystem info: %s" +msgid "Error getting filesystem info for %s: %s" +msgstr "Viga failisüsteemi andmete hankimisel: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: ../gio/glocalfile.c:1244 +#, fuzzy, c-format +#| msgid "Containing mount does not exist" +msgid "Containing mount for file %s not found" +msgstr "Sisalduvat haaget pole olemas" + +#: ../gio/glocalfile.c:1267 +#, fuzzy +#| msgid "Can't rename root directory" +msgid "Can’t rename root directory" +msgstr "Juurkataloogi nime pole võimalik muuta" + +#: ../gio/glocalfile.c:1285 ../gio/glocalfile.c:1308 +#, fuzzy, c-format +msgid "Error renaming file %s: %s" +msgstr "Viga failist '%s' lugemisel: %s" + +#: ../gio/glocalfile.c:1292 +msgid "Can’t rename file, filename already exists" +msgstr "Faili pole võimalik ümber nimetada, failinimi on juba olemas" + +#: ../gio/glocalfile.c:1305 ../gio/glocalfile.c:2322 ../gio/glocalfile.c:2350 +#: ../gio/glocalfile.c:2507 ../gio/glocalfileoutputstream.c:551 +msgid "Invalid filename" +msgstr "Vigane failinimi" + +#: ../gio/glocalfile.c:1473 ../gio/glocalfile.c:1488 +#, fuzzy, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file %s: %s" +msgstr "Viga faili '%s' avamisel: %s" + +#: ../gio/glocalfile.c:1613 +#, fuzzy, c-format +#| msgid "Error removing file: %s" +msgid "Error removing file %s: %s" +msgstr "Viga faili eemaldamisel: %s" + +#: ../gio/glocalfile.c:1997 +#, fuzzy, c-format +#| msgid "Error trashing file: %s" +msgid "Error trashing file %s: %s" +msgstr "Viga faili prügikasti viskamisel: %s" + +#: ../gio/glocalfile.c:2020 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Prügikataloogi %s pole võimalik luua: %s" + +#: ../gio/glocalfile.c:2040 +#, fuzzy, c-format +#| msgid "Unable to find toplevel directory for trash" +msgid "Unable to find toplevel directory to trash %s" +msgstr "Prügikasti ülemise taseme kataloogi pole võimalik leida" + +#: ../gio/glocalfile.c:2119 ../gio/glocalfile.c:2139 +#, fuzzy, c-format +#| msgid "Unable to find or create trash directory" +msgid "Unable to find or create trash directory for %s" +msgstr "Prügikasti kataloogi pole võimalik leida või luua" + +#: ../gio/glocalfile.c:2174 +#, fuzzy, c-format +#| msgid "Unable to create trashing info file: %s" +msgid "Unable to create trashing info file for %s: %s" +msgstr "Prügiinfo faili pole võimalik luua: %s" + +#: ../gio/glocalfile.c:2233 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Faili pole võimalik prügikasti visata: %s" + +#: ../gio/glocalfile.c:2237 ../gio/glocalfile.c:2293 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s: %s" +msgstr "Faili pole võimalik prügikasti visata: %s" + +#: ../gio/glocalfile.c:2299 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s" +msgstr "Faili pole võimalik prügikasti visata: %s" + +#: ../gio/glocalfile.c:2325 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory %s: %s" +msgstr "Viga kataloogi '%s' loomisel: %s" + +#: ../gio/glocalfile.c:2354 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Failisüsteem ei toeta nimeviitasid" + +#: ../gio/glocalfile.c:2357 +#, fuzzy, c-format +#| msgid "Error making symbolic link: %s" +msgid "Error making symbolic link %s: %s" +msgstr "Viga nimeviida loomisel: %s" + +#: ../gio/glocalfile.c:2363 ../glib/gfileutils.c:2127 +msgid "Symbolic links not supported" +msgstr "Nimeviidad ei ole toetatud" + +#: ../gio/glocalfile.c:2418 ../gio/glocalfile.c:2453 ../gio/glocalfile.c:2510 +#, fuzzy, c-format +#| msgid "Error moving file: %s" +msgid "Error moving file %s: %s" +msgstr "Viga faili ümbertõstmisel: %s" + +#: ../gio/glocalfile.c:2441 +#, fuzzy +#| msgid "Can't move directory over directory" +msgid "Can’t move directory over directory" +msgstr "Kataloogi pole võimalik kataloogi peale liigutada" + +#: ../gio/glocalfile.c:2467 ../gio/glocalfileoutputstream.c:935 +#: ../gio/glocalfileoutputstream.c:949 ../gio/glocalfileoutputstream.c:964 +#: ../gio/glocalfileoutputstream.c:981 ../gio/glocalfileoutputstream.c:995 +msgid "Backup file creation failed" +msgstr "Tõrge varufaili loomisel" + +#: ../gio/glocalfile.c:2486 +#, c-format +msgid "Error removing target file: %s" +msgstr "Viga sihtfaili eemaldamisel: %s" + +#: ../gio/glocalfile.c:2500 +msgid "Move between mounts not supported" +msgstr "Erinevate haakeseadmete vahel liigutamine pole toetatud" + +#: ../gio/glocalfile.c:2691 +#, fuzzy, c-format +#| msgid "could not get remote address: %s" +msgid "Could not determine the disk usage of %s: %s" +msgstr "kaugaadressi ei suudeta määrata: %s" + +#: ../gio/glocalfileinfo.c:745 +msgid "Attribute value must be non-NULL" +msgstr "Rekvisiidi väärtus ei tohi olla NULL" + +#: ../gio/glocalfileinfo.c:752 +msgid "Invalid attribute type (string expected)" +msgstr "Vigane rekvisiidi tüüp (oodatakse stringi)" + +#: ../gio/glocalfileinfo.c:759 +msgid "Invalid extended attribute name" +msgstr "Vigane laiendatud rekvisiidi nimi" + +#: ../gio/glocalfileinfo.c:799 +#, fuzzy, c-format +#| msgid "Error setting extended attribute '%s': %s" +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Viga laiendatud rekvisiidi '%s' seadmisel: %s" + +#: ../gio/glocalfileinfo.c:1607 +msgid " (invalid encoding)" +msgstr " (vigane kodeering)" + +#: ../gio/glocalfileinfo.c:1776 ../gio/glocalfileoutputstream.c:813 +#, fuzzy, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Viga faili '%s' avamisel: %s" + +#: ../gio/glocalfileinfo.c:2038 +#, fuzzy, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Viga failideskriptori kohta andmete hankimisel: %s" + +#: ../gio/glocalfileinfo.c:2083 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Vigane rekvisiidi tüüp (oodatakse tüüpi uint32)" + +#: ../gio/glocalfileinfo.c:2101 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Vigane rekvisiidi tüüp (oodatakse tüüpi uint64)" + +#: ../gio/glocalfileinfo.c:2120 ../gio/glocalfileinfo.c:2139 +msgid "Invalid attribute type (byte string expected)" +msgstr "Vigane rekvisiidi tüüp (oodatakse baitstringi)" + +#: ../gio/glocalfileinfo.c:2184 +msgid "Cannot set permissions on symlinks" +msgstr "Nimeviitadele pole võimalik pääsuõiguseid määrata" + +#: ../gio/glocalfileinfo.c:2200 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Viga pääsuõiguste määramisel: %s" + +#: ../gio/glocalfileinfo.c:2251 +#, c-format +msgid "Error setting owner: %s" +msgstr "Viga omaniku seadmisel: %s" + +#: ../gio/glocalfileinfo.c:2274 +msgid "symlink must be non-NULL" +msgstr "nimeviit ei tohi olla NULL" + +#: ../gio/glocalfileinfo.c:2284 ../gio/glocalfileinfo.c:2303 +#: ../gio/glocalfileinfo.c:2314 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Viga nimeviida seadmisel: %s" + +#: ../gio/glocalfileinfo.c:2293 +msgid "Error setting symlink: file is not a symlink" +msgstr "Viga nimeviida seadmisel: fail pole nimeviide" + +#: ../gio/glocalfileinfo.c:2419 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Viga muutmise või kasutamise aja määramisel: %s" + +#: ../gio/glocalfileinfo.c:2442 +msgid "SELinux context must be non-NULL" +msgstr "SELinuxi kontekst ei tohi olla NULL" + +#: ../gio/glocalfileinfo.c:2457 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Viga SELinuxi konteksti seadmisel: %s" + +#: ../gio/glocalfileinfo.c:2464 +msgid "SELinux is not enabled on this system" +msgstr "SELinux pole selles süsteemis lubatud" + +#: ../gio/glocalfileinfo.c:2556 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Rekvisiidi %s seadmine pole toetatud" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:696 +#, c-format +msgid "Error reading from file: %s" +msgstr "Viga failist lugemisel: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:458 ../gio/glocalfileoutputstream.c:1013 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Viga faili kerimisel: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:248 +#: ../gio/glocalfileoutputstream.c:342 +#, c-format +msgid "Error closing file: %s" +msgstr "Viga faili sulgemisel: %s" + +#: ../gio/glocalfilemonitor.c:840 +msgid "Unable to find default local file monitor type" +msgstr "Failimonitori vaikimisi tüüpi pole võimalik leida" + +#: ../gio/glocalfileoutputstream.c:196 ../gio/glocalfileoutputstream.c:228 +#: ../gio/glocalfileoutputstream.c:717 +#, c-format +msgid "Error writing to file: %s" +msgstr "Viga faili kirjutamisel: %s" + +#: ../gio/glocalfileoutputstream.c:275 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Viga vana varuviite eemaldamisel: %s" + +#: ../gio/glocalfileoutputstream.c:289 ../gio/glocalfileoutputstream.c:302 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Viga varukoopia loomisel: %s" + +#: ../gio/glocalfileoutputstream.c:320 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Viga ajutise faili nime muutmisel: %s" + +#: ../gio/glocalfileoutputstream.c:504 ../gio/glocalfileoutputstream.c:1064 +#, c-format +msgid "Error truncating file: %s" +msgstr "Viga faili kärpimisel: %s" + +#: ../gio/glocalfileoutputstream.c:557 ../gio/glocalfileoutputstream.c:795 +#: ../gio/glocalfileoutputstream.c:1045 ../gio/gsubprocess.c:380 +#, fuzzy, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file “%sâ€: %s" +msgstr "Viga faili '%s' avamisel: %s" + +#: ../gio/glocalfileoutputstream.c:826 +msgid "Target file is a directory" +msgstr "Sihtfail on kataloog" + +#: ../gio/glocalfileoutputstream.c:831 +msgid "Target file is not a regular file" +msgstr "Sihtfail pole tavaline fail" + +#: ../gio/glocalfileoutputstream.c:843 +msgid "The file was externally modified" +msgstr "Faili muudeti väljaspool" + +#: ../gio/glocalfileoutputstream.c:1029 +#, c-format +msgid "Error removing old file: %s" +msgstr "Viga vana faili eemaldamisel: %s" + +#: ../gio/gmemoryinputstream.c:474 ../gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Pakutud GSeekType pole sobiv" + +#: ../gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Sobimatu kerimise päring" + +#: ../gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream'i pole võimalik kärpida" + +#: ../gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Mäluväljundi voo suurus pole muudetav" + +#: ../gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Mäluväljundi voo suuruse muutmine nurjus" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Kirjutamise töötlemiseks vajaminev mäluhulk on suurem kui saadaolev " +"aadressiruum" + +#: ../gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Küsitud ümberpositsioneerimine osutab andmevoo algusest ettepoole" + +#: ../gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Küsitud ümberpositsioneerimine osutab andmevoo lõpust kaugemale" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:396 +msgid "mount doesn’t implement “unmountâ€" +msgstr "haage ei toeta lahtihaakimist (unmount)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:472 +msgid "mount doesn’t implement “ejectâ€" +msgstr "haage ei toeta väljastamist (eject)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:550 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"haage ei toeta ei lahtihaakimist (unmount) ega lahtihaakimist koos " +"toiminguga (unmount_with_operation)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:635 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"haage ei toeta ei väljastamist (eject) ega väljastamist koos toiminguga " +"(eject_with_operation)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:723 +msgid "mount doesn’t implement “remountâ€" +msgstr "haage ei toeta taashaakimist (remount)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:805 +msgid "mount doesn’t implement content type guessing" +msgstr "haage ei toeta sisuliigi arvamist" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:892 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "haage ei toeta sünkroonset sisutüübi arvamist" + +#: ../gio/gnetworkaddress.c:378 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Hostinimi „%s“ sisaldab „[“ aga mitte „]“" + +#: ../gio/gnetworkmonitorbase.c:212 ../gio/gnetworkmonitorbase.c:316 +msgid "Network unreachable" +msgstr "Võrk pole kättesaadav" + +#: ../gio/gnetworkmonitorbase.c:250 ../gio/gnetworkmonitorbase.c:280 +msgid "Host unreachable" +msgstr "Host pole kättesaadav" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, fuzzy, c-format +msgid "Could not create network monitor: %s" +msgstr "kaugaadressi ei suudeta määrata: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "Võrgumonitoriga pole võimalik ühenduda:" + +#: ../gio/gnetworkmonitornetlink.c:175 +#, fuzzy +msgid "Could not get network status: " +msgstr "kaugaadressi ei suudeta määrata: %s" + +#: ../gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:560 +#, fuzzy +#| msgid "Output stream doesn't implement write" +msgid "Output stream doesn’t implement write" +msgstr "Väljundvoog ei toeta kirjutusoperatsiooni" + +#: ../gio/goutputstream.c:521 ../gio/goutputstream.c:1224 +msgid "Source stream is already closed" +msgstr "Lähtevoog on juba suletud" + +#: ../gio/gresolver.c:342 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, fuzzy, c-format +#| msgid "Error resolving '%s': %s" +msgid "Error resolving “%sâ€: %s" +msgstr "Viga '%s' lahendamisel: %s" + +#: ../gio/gresolver.c:729 ../gio/gresolver.c:781 +#, fuzzy +#| msgid "Invalid filename" +msgid "Invalid domain" +msgstr "Vigane failinimi" + +#: ../gio/gresource.c:621 ../gio/gresource.c:880 ../gio/gresource.c:919 +#: ../gio/gresource.c:1043 ../gio/gresource.c:1115 ../gio/gresource.c:1188 +#: ../gio/gresource.c:1258 ../gio/gresourcefile.c:476 +#: ../gio/gresourcefile.c:599 ../gio/gresourcefile.c:736 +#, fuzzy, c-format +msgid "The resource at “%s†does not exist" +msgstr "Sihtfail on kataloog" + +#: ../gio/gresource.c:786 +#, fuzzy, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Sihtfail on kataloog" + +#: ../gio/gresourcefile.c:732 +#, fuzzy, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Sihtfail on kataloog" + +#: ../gio/gresourcefile.c:940 +#, fuzzy +msgid "Input stream doesn’t implement seek" +msgstr "Sisendvoog ei toeta lugemist" + +#: ../gio/gresource-tool.c:494 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: ../gio/gresource-tool.c:500 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: ../gio/gresource-tool.c:503 ../gio/gresource-tool.c:513 +msgid "FILE [PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:504 ../gio/gresource-tool.c:514 +#: ../gio/gresource-tool.c:521 +msgid "SECTION" +msgstr "" + +#: ../gio/gresource-tool.c:509 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: ../gio/gresource-tool.c:519 +msgid "Extract a resource file to stdout" +msgstr "" + +#: ../gio/gresource-tool.c:520 +msgid "FILE PATH" +msgstr "" + +#: ../gio/gresource-tool.c:534 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:548 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:555 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: ../gio/gresource-tool.c:559 ../gio/gsettings-tool.c:703 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gresource-tool.c:565 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: ../gio/gresource-tool.c:568 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: ../gio/gresource-tool.c:572 +msgid "[PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:574 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: ../gio/gresource-tool.c:575 +msgid "PATH" +msgstr "" + +#: ../gio/gresource-tool.c:577 +msgid " PATH A resource path\n" +msgstr "" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#: ../gio/gsettings-tool.c:908 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Skeemi „%s“ pole\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:538 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +#, fuzzy, c-format +#| msgid "Property '%s' is not writable" +msgid "The key is not writable\n" +msgstr "Omadus '%s' pole kirjutatav" + +#: ../gio/gsettings-tool.c:581 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:587 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:593 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:594 ../gio/gsettings-tool.c:600 +#: ../gio/gsettings-tool.c:643 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:599 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:605 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:607 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:612 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:613 ../gio/gsettings-tool.c:619 +#: ../gio/gsettings-tool.c:625 ../gio/gsettings-tool.c:637 +#: ../gio/gsettings-tool.c:649 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:618 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:624 +msgid "Query the description for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:630 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:631 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:636 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:642 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:654 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:657 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:693 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:699 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:707 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:712 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:716 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:720 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:775 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not load schemas from %s: %s\n" +msgstr "Konverterit '%s'-st '%s'-ks pole võimalik avada" + +#: ../gio/gsettings-tool.c:787 +#, fuzzy, c-format +#| msgid "No schema files found: " +msgid "No schemas installed\n" +msgstr "Ühtegi skeemifaili ei leitud:" + +#: ../gio/gsettings-tool.c:866 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsettings-tool.c:921 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Võtit „%s“ pole\n" + +#: ../gio/gsocket.c:384 +msgid "Invalid socket, not initialized" +msgstr "Vigane sokkel, käivitamata" + +#: ../gio/gsocket.c:391 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Vigane sokkel, käivitamine nurjus kuna: %s" + +#: ../gio/gsocket.c:399 +msgid "Socket is already closed" +msgstr "Sokkel on juba suletud" + +#: ../gio/gsocket.c:414 ../gio/gsocket.c:3010 ../gio/gsocket.c:4220 +#: ../gio/gsocket.c:4278 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:549 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "GSocketi loomine fd-st: %s" + +#: ../gio/gsocket.c:578 ../gio/gsocket.c:632 ../gio/gsocket.c:639 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Soklit pole võimalik luua: %s" + +#: ../gio/gsocket.c:632 +msgid "Unknown family was specified" +msgstr "Etteantud perekond on tundmatu" + +#: ../gio/gsocket.c:639 +msgid "Unknown protocol was specified" +msgstr "Etteantud protokoll on tundmatu" + +#: ../gio/gsocket.c:1130 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: ../gio/gsocket.c:1147 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: ../gio/gsocket.c:1954 +#, c-format +msgid "could not get local address: %s" +msgstr "kohalikku aadressi ei suudeta määrata: %s" + +#: ../gio/gsocket.c:2000 +#, c-format +msgid "could not get remote address: %s" +msgstr "kaugaadressi ei suudeta määrata: %s" + +#: ../gio/gsocket.c:2066 +#, c-format +msgid "could not listen: %s" +msgstr "pole võimalik kuulata: %s" + +#: ../gio/gsocket.c:2168 +#, c-format +msgid "Error binding to address: %s" +msgstr "Viga aadressile sidumisel: %s" + +#: ../gio/gsocket.c:2226 ../gio/gsocket.c:2263 ../gio/gsocket.c:2373 +#: ../gio/gsocket.c:2391 ../gio/gsocket.c:2461 ../gio/gsocket.c:2519 +#: ../gio/gsocket.c:2537 +#, fuzzy, c-format +msgid "Error joining multicast group: %s" +msgstr "Viga rakenduse käivitamisel: %s" + +#: ../gio/gsocket.c:2227 ../gio/gsocket.c:2264 ../gio/gsocket.c:2374 +#: ../gio/gsocket.c:2392 ../gio/gsocket.c:2462 ../gio/gsocket.c:2520 +#: ../gio/gsocket.c:2538 +#, fuzzy, c-format +msgid "Error leaving multicast group: %s" +msgstr "Viga rakenduse käivitamisel: %s" + +#: ../gio/gsocket.c:2228 +msgid "No support for source-specific multicast" +msgstr "" + +#: ../gio/gsocket.c:2375 +#, fuzzy +#| msgid "Unsupported socket address" +msgid "Unsupported socket family" +msgstr "Toetamata sokliaadress" + +#: ../gio/gsocket.c:2393 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: ../gio/gsocket.c:2411 ../gio/gsocket.c:2440 ../gio/gsocket.c:2487 +#, c-format +msgid "Interface not found: %s" +msgstr "" + +#: ../gio/gsocket.c:2427 +#, c-format +msgid "Interface name too long" +msgstr "" + +#: ../gio/gsocket.c:2463 +msgid "No support for IPv4 source-specific multicast" +msgstr "" + +#: ../gio/gsocket.c:2521 +msgid "No support for IPv6 source-specific multicast" +msgstr "" + +#: ../gio/gsocket.c:2730 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Viga ühendusega nõustumisel: %s" + +#: ../gio/gsocket.c:2854 +msgid "Connection in progress" +msgstr "Ühendumise edenemine" + +#: ../gio/gsocket.c:2903 +msgid "Unable to get pending error: " +msgstr "Aktiivset viga pole võimalik saada: " + +#: ../gio/gsocket.c:3073 +#, c-format +msgid "Error receiving data: %s" +msgstr "Viga andmete vastuvõtmisel: %s" + +#: ../gio/gsocket.c:3268 +#, c-format +msgid "Error sending data: %s" +msgstr "Viga andmete saatmisel: %s" + +#: ../gio/gsocket.c:3455 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Soklit pole võimalik luua: %s" + +#: ../gio/gsocket.c:3536 +#, c-format +msgid "Error closing socket: %s" +msgstr "Viga sokli sulgemisel: %s" + +#: ../gio/gsocket.c:4213 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Sokli ülesseadmise ootamine: %s" + +#: ../gio/gsocket.c:4687 ../gio/gsocket.c:4767 ../gio/gsocket.c:4945 +#, c-format +msgid "Error sending message: %s" +msgstr "Viga sõnumi saatmisel: %s" + +#: ../gio/gsocket.c:4711 +#, fuzzy +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage pole windows-platvormil toetatud" + +#: ../gio/gsocket.c:5164 ../gio/gsocket.c:5237 ../gio/gsocket.c:5463 +#, c-format +msgid "Error receiving message: %s" +msgstr "Viga sõnumi vastuvõtmisel: %s" + +#: ../gio/gsocket.c:5735 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to read socket credentials: %s" +msgstr "Soklit pole võimalik luua: %s" + +#: ../gio/gsocket.c:5744 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Proksiserveriga %s pole võimalik ühenduda:" + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "Pole võimalik %s-ga ühenduda:" + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "Pole võimalik ühenduda:" + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "Tundmatu viga ühendumisel" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Proksimine mitte-TCP ühenduse kaudu pole toetatud." + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proksi protokoll „%s“ pole toetatud." + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "Kuulaja on juba suletud" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "Lisatud sokkel on suletud" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 ei toeta IPv6-aadressi „%s“" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Kasutajanimi on SOCKSv4 protokolli jaoks liiga pikk" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Hostinimi „%s“ on SOCKSv4 protokolli jaoks liiga pikk" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Server ei ole SOCKSv4 proksiserver." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Ühendus läbi SOCKSv4-serveri lükati tagasi" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Server ei ole SOCKSv5 proksiserver." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 proksi nõuab autentimist." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 proksi nõuab GLibi poolt toetamata autentimismeetodit." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Kasutajanimi või parool on SOCKSv5 protokolli jaoks liiga pikk." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 autentimine nurjus vale kasutajanime või parooli tõttu." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Hostinimi „%s“ on SOCKSv5 protokolli jaoks liiga pikk" + +#: ../gio/gsocks5proxy.c:348 +#, fuzzy +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 proksi nõuab autentimist." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Sisemine SOCKSv5 proksiserveri viga." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "" + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "SOCKSv5 proksi tundmatu viga." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon kodeeringu versiooni %d pole võimalik käsitseda" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "" + +#: ../gio/gthreadedresolver.c:213 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Viga „%s“ pöördlahendamisel: %s" + +#: ../gio/gthreadedresolver.c:549 ../gio/gthreadedresolver.c:628 +#: ../gio/gthreadedresolver.c:726 ../gio/gthreadedresolver.c:776 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: ../gio/gthreadedresolver.c:554 ../gio/gthreadedresolver.c:731 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Ajutiselt pole võimalik „%s“ lahendada" + +#: ../gio/gthreadedresolver.c:559 ../gio/gthreadedresolver.c:736 +#: ../gio/gthreadedresolver.c:842 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Viga „%s“ lahendamisel" + +#: ../gio/gtlscertificate.c:250 +#, fuzzy +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-kodeeritud privaatvõtit pole võimalik analüüsida" + +#: ../gio/gtlscertificate.c:255 +#, fuzzy +msgid "No PEM-encoded private key found" +msgstr "PEM-kodeeritud sertifikaati ei leitud" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-kodeeritud privaatvõtit pole võimalik analüüsida" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "PEM-kodeeritud sertifikaati ei leitud" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-kodeeritud sertifikaati pole võimalik analüüsida" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: ../gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Sisestatud parool on vale." + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:563 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Eeldati ühte kontrollsõnumit, aga saadi %d" +msgstr[1] "Eeldati ühte kontrollsõnumit, aga saadi %d" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:575 +msgid "Unexpected type of ancillary data" +msgstr "Ootamatu kõrvalteabe tüüp" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Eeldati ühte fd-d, aga saadi %d\n" +msgstr[1] "Eeldati ühte fd-d, aga saadi %d\n" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Saadi vigane fd" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "Viga tõendite saatmisel: " + +#: ../gio/gunixconnection.c:504 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:520 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Viga SO_PASSCRED lubamisel: %s" + +#: ../gio/gunixconnection.c:549 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:589 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ei eeldatud ühtegi kontrollsõnumit, aga saadi %d" + +#: ../gio/gunixconnection.c:614 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Viga SO_PASSCRED keelamisel: %s" + +#: ../gio/gunixinputstream.c:372 ../gio/gunixinputstream.c:393 +#, fuzzy, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Viga failideskriptori kohta andmete hankimisel: %s" + +#: ../gio/gunixinputstream.c:426 ../gio/gunixoutputstream.c:411 +#: ../gio/gwin32inputstream.c:217 ../gio/gwin32outputstream.c:204 +#, fuzzy, c-format +msgid "Error closing file descriptor: %s" +msgstr "Viga failideskriptori kohta andmete hankimisel: %s" + +#: ../gio/gunixmounts.c:2556 ../gio/gunixmounts.c:2609 +msgid "Filesystem root" +msgstr "Failisüsteemi juurikas" + +#: ../gio/gunixoutputstream.c:358 ../gio/gunixoutputstream.c:378 +#, fuzzy, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Viga failideskriptori kohta andmete hankimisel: %s" + +#: ../gio/gunixsocketaddress.c:241 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Abstraktse UNIX-domeeni sokliaadressid ei ole selles süsteemis toetatud" + +#: ../gio/gvolume.c:437 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "volume doesn’t implement eject" +msgstr "kõide ei toeta lahtihaakimist" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "köide ei toeta haakimist või haakimist koos tegevusega" + +#: ../gio/gwin32inputstream.c:185 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Viga pidemest lugemisel: %s" + +#: ../gio/gwin32inputstream.c:232 ../gio/gwin32outputstream.c:219 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Viga pideme sulgemisel: %s" + +#: ../gio/gwin32outputstream.c:172 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Viga faili kirjutamisel: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Pole piisavalt mälu" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Sisemine viga: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Vaja on rohkem sisendit" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Vigaselt pakitud andmed" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Prindi aadress" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "" + +#: ../glib/gbookmarkfile.c:754 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Ootamatu rekvisiit „%s“ elemendile „%s“" + +#: ../glib/gbookmarkfile.c:765 ../glib/gbookmarkfile.c:836 +#: ../glib/gbookmarkfile.c:846 ../glib/gbookmarkfile.c:953 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Elemendil „%2$s“ ei leitud rekvisiiti „%1$s“" + +#: ../glib/gbookmarkfile.c:1123 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1252 ../glib/gbookmarkfile.c:1262 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Ootamatu silt „%s“, oodati silti „%s“" + +#: ../glib/gbookmarkfile.c:1148 ../glib/gbookmarkfile.c:1162 +#: ../glib/gbookmarkfile.c:1230 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "„%2$s“ sees on ootamatu silt „%1$s“" + +#: ../glib/gbookmarkfile.c:1757 +msgid "No valid bookmark file found in data dirs" +msgstr "Andmekataloogidest ei leitud korrektset järjehoidjafaili" + +#: ../glib/gbookmarkfile.c:1958 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "URI-le „%s“ on juba järjehoidja olemas" + +#: ../glib/gbookmarkfile.c:2004 ../glib/gbookmarkfile.c:2162 +#: ../glib/gbookmarkfile.c:2247 ../glib/gbookmarkfile.c:2327 +#: ../glib/gbookmarkfile.c:2412 ../glib/gbookmarkfile.c:2495 +#: ../glib/gbookmarkfile.c:2573 ../glib/gbookmarkfile.c:2652 +#: ../glib/gbookmarkfile.c:2694 ../glib/gbookmarkfile.c:2791 +#: ../glib/gbookmarkfile.c:2912 ../glib/gbookmarkfile.c:3102 +#: ../glib/gbookmarkfile.c:3178 ../glib/gbookmarkfile.c:3346 +#: ../glib/gbookmarkfile.c:3435 ../glib/gbookmarkfile.c:3524 +#: ../glib/gbookmarkfile.c:3640 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "URI-le „%s“ ei leitud järjehoidjat" + +#: ../glib/gbookmarkfile.c:2336 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "URI „%s“ järjehoidjas pole MIME tüüpe määratud" + +#: ../glib/gbookmarkfile.c:2421 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "URI „%s“ järjehoidjas pole privaatlippu kirjeldatud" + +#: ../glib/gbookmarkfile.c:2800 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI „%s“ järjehoidjas pole gruppe määratud" + +#: ../glib/gbookmarkfile.c:3199 ../glib/gbookmarkfile.c:3356 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Rakendus nimega „%s“ pole „%s“ kohta järjehoidjat registreerinud" + +#: ../glib/gbookmarkfile.c:3379 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Tõrge rea „%s“ käivitamisel koos URI-ga „%s“" + +#: ../glib/gconvert.c:473 +#, fuzzy +#| msgid "Invalid sequence in conversion input" +msgid "Unrepresentable character in conversion input" +msgstr "Vigane jada sisendi teisendamisel" + +#: ../glib/gconvert.c:500 ../glib/gutf8.c:865 ../glib/gutf8.c:1077 +#: ../glib/gutf8.c:1214 ../glib/gutf8.c:1318 +msgid "Partial character sequence at end of input" +msgstr "Osaline märgijada sisendi lõpus" + +#: ../glib/gconvert.c:769 +#, fuzzy, c-format +#| msgid "Cannot convert fallback '%s' to codeset '%s'" +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Taandresiimi '%s' pole võimalik teisendada kooditabelisse '%s'" + +#: ../glib/gconvert.c:940 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "Vigane baidijada sisendi teisendamisel" + +#: ../glib/gconvert.c:961 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "Vigane baidijada sisendi teisendamisel" + +#: ../glib/gconvert.c:1649 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI „%s“ ei ole failiskeemi („file“) jaoks absoluutne URI" + +#: ../glib/gconvert.c:1659 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Kohaliku faili URI „%s“ ei tohi sisaldada märki „#“" + +#: ../glib/gconvert.c:1676 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI „%s“ on vigane" + +#: ../glib/gconvert.c:1688 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI „%s“ hostinimi on vigane" + +#: ../glib/gconvert.c:1704 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI „%s“ sisaldab vigaseid paomärke" + +#: ../glib/gconvert.c:1776 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Rajanimi „%s“ ei ole absoluutne rada" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %-d %b %Y, %H∶%M∶%S" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%-d. %b %Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "January" +msgstr "Jaanuar" + +#: ../glib/gdatetime.c:253 +msgctxt "full month name" +msgid "February" +msgstr "Veebruar" + +#: ../glib/gdatetime.c:255 +msgctxt "full month name" +msgid "March" +msgstr "Märts" + +#: ../glib/gdatetime.c:257 +msgctxt "full month name" +msgid "April" +msgstr "Aprill" + +#: ../glib/gdatetime.c:259 +msgctxt "full month name" +msgid "May" +msgstr "Mai" + +#: ../glib/gdatetime.c:261 +msgctxt "full month name" +msgid "June" +msgstr "Juuni" + +#: ../glib/gdatetime.c:263 +msgctxt "full month name" +msgid "July" +msgstr "Juuli" + +#: ../glib/gdatetime.c:265 +msgctxt "full month name" +msgid "August" +msgstr "August" + +#: ../glib/gdatetime.c:267 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: ../glib/gdatetime.c:269 +msgctxt "full month name" +msgid "October" +msgstr "Oktoober" + +#: ../glib/gdatetime.c:271 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: ../glib/gdatetime.c:273 +msgctxt "full month name" +msgid "December" +msgstr "Detsember" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: ../glib/gdatetime.c:305 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jaan" + +#: ../glib/gdatetime.c:307 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Veebr" + +#: ../glib/gdatetime.c:309 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Märts" + +#: ../glib/gdatetime.c:311 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:313 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: ../glib/gdatetime.c:315 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Juuni" + +#: ../glib/gdatetime.c:317 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Juuli" + +#: ../glib/gdatetime.c:319 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: ../glib/gdatetime.c:321 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sept" + +#: ../glib/gdatetime.c:323 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: ../glib/gdatetime.c:325 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: ../glib/gdatetime.c:327 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dets" + +#: ../glib/gdatetime.c:342 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Esmaspäev" + +#: ../glib/gdatetime.c:344 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Teisipäev" + +#: ../glib/gdatetime.c:346 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Kolmapäev" + +#: ../glib/gdatetime.c:348 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Neljapäev" + +#: ../glib/gdatetime.c:350 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Reede" + +#: ../glib/gdatetime.c:352 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Laupäev" + +#: ../glib/gdatetime.c:354 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Pühapäev" + +#: ../glib/gdatetime.c:369 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "E" + +#: ../glib/gdatetime.c:371 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "T" + +#: ../glib/gdatetime.c:373 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "K" + +#: ../glib/gdatetime.c:375 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "N" + +#: ../glib/gdatetime.c:377 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "R" + +#: ../glib/gdatetime.c:379 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "L" + +#: ../glib/gdatetime.c:381 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "P" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: ../glib/gdatetime.c:441 +msgctxt "full month name with day" +msgid "January" +msgstr "jaanuar" + +#: ../glib/gdatetime.c:443 +msgctxt "full month name with day" +msgid "February" +msgstr "veebruar" + +#: ../glib/gdatetime.c:445 +msgctxt "full month name with day" +msgid "March" +msgstr "märts" + +#: ../glib/gdatetime.c:447 +msgctxt "full month name with day" +msgid "April" +msgstr "aprill" + +#: ../glib/gdatetime.c:449 +msgctxt "full month name with day" +msgid "May" +msgstr "mai" + +#: ../glib/gdatetime.c:451 +msgctxt "full month name with day" +msgid "June" +msgstr "juuni" + +#: ../glib/gdatetime.c:453 +msgctxt "full month name with day" +msgid "July" +msgstr "juuli" + +#: ../glib/gdatetime.c:455 +msgctxt "full month name with day" +msgid "August" +msgstr "august" + +#: ../glib/gdatetime.c:457 +msgctxt "full month name with day" +msgid "September" +msgstr "september" + +#: ../glib/gdatetime.c:459 +msgctxt "full month name with day" +msgid "October" +msgstr "oktoober" + +#: ../glib/gdatetime.c:461 +msgctxt "full month name with day" +msgid "November" +msgstr "november" + +#: ../glib/gdatetime.c:463 +msgctxt "full month name with day" +msgid "December" +msgstr "detsember" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: ../glib/gdatetime.c:524 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jaan" + +#: ../glib/gdatetime.c:526 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "veebr" + +#: ../glib/gdatetime.c:528 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "märts" + +#: ../glib/gdatetime.c:530 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +#: ../glib/gdatetime.c:532 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "mai" + +#: ../glib/gdatetime.c:534 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "juuni" + +#: ../glib/gdatetime.c:536 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "juuli" + +#: ../glib/gdatetime.c:538 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "aug" + +#: ../glib/gdatetime.c:540 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sept" + +#: ../glib/gdatetime.c:542 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +#: ../glib/gdatetime.c:544 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: ../glib/gdatetime.c:546 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dets" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:563 +msgctxt "GDateTime" +msgid "AM" +msgstr "e. l." + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:566 +msgctxt "GDateTime" +msgid "PM" +msgstr "p. l." + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Viga kataloogi „%s“ avamisel: %s" + +#: ../glib/gfileutils.c:716 ../glib/gfileutils.c:808 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ei saa eraldada %lu baiti faili „%s“ lugemiseks" +msgstr[1] "Ei saa eraldada %lu baiti faili „%s“ lugemiseks" + +#: ../glib/gfileutils.c:733 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Viga failist „%s“ lugemisel: %s" + +#: ../glib/gfileutils.c:769 +#, c-format +msgid "File “%s†is too large" +msgstr "Fail „%s“ on liiga suur" + +#: ../glib/gfileutils.c:833 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Tõrge failist „%s“ lugemisel: %s" + +#: ../glib/gfileutils.c:881 ../glib/gfileutils.c:953 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Tõrge faili „%s“ avamisel: %s" + +#: ../glib/gfileutils.c:893 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Tõrge faili „%s“ rekvisiitide hankimisel: fstat() nurjus: %s" + +#: ../glib/gfileutils.c:923 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Tõrge faili „%s“ avamisel: fdopen() nurjus: %s" + +#: ../glib/gfileutils.c:1022 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Tõrge faili „%s“ ümbernimetamisel nimega „%s“: g_rename() nurjus: %s" + +#: ../glib/gfileutils.c:1057 ../glib/gfileutils.c:1564 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Tõrge faili „%s“ loomisel: %s" + +#: ../glib/gfileutils.c:1084 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Tõrge faili „%s“ kirjutamisel: fwrite() nurjus: %s" + +#: ../glib/gfileutils.c:1127 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Tõrge faili „%s“ kirjutamisel: fsync() nurjus: %s" + +#: ../glib/gfileutils.c:1251 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Olemasolevat faili „%s“ pole võimalik eemaldada: g_unlink() nurjus: %s" + +#: ../glib/gfileutils.c:1530 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Mall „%s“ vigane, see ei tohiks sisaldada '%s'" + +#: ../glib/gfileutils.c:1543 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Mall „%s“ ei sisalda XXXXXX-i" + +#: ../glib/gfileutils.c:2105 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Tõrge nimeviida „%s“ lugemisel: %s" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Konverterit „%s“-st „%s“-ks pole võimalik avada: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Ei saa teostada toorest lugemist g_io_channel_read_line_string’i sees" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "Lugemispuhvrisse jäi teisendamata andmeid" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "Kanali katkestus poole märgi pealt" + +#: ../glib/giochannel.c:1925 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Ei saa teostada toorest lugemist g_io_channel_read_to_end’i sees" + +#: ../glib/gkeyfile.c:788 +msgid "Valid key file could not be found in search dirs" +msgstr "Sobivat võtmefaili pole võimalik otsingukataloogidest leida" + +#: ../glib/gkeyfile.c:825 +msgid "Not a regular file" +msgstr "Pole tavaline fail" + +#: ../glib/gkeyfile.c:1270 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Võtmefail sisaldab rida „%s“, mis ei ole võti-väärtus paar, grupp ega ka " +"kommentaar" + +#: ../glib/gkeyfile.c:1327 +#, c-format +msgid "Invalid group name: %s" +msgstr "Vigane grupi nimi: %s" + +#: ../glib/gkeyfile.c:1349 +msgid "Key file does not start with a group" +msgstr "Võtmefail ei alga grupiga" + +#: ../glib/gkeyfile.c:1375 +#, c-format +msgid "Invalid key name: %s" +msgstr "Vigane võtme nimi: %s" + +#: ../glib/gkeyfile.c:1402 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Võtmefail sisaldab toetamata kodeeringut „%s“" + +#: ../glib/gkeyfile.c:1645 ../glib/gkeyfile.c:1818 ../glib/gkeyfile.c:3271 +#: ../glib/gkeyfile.c:3334 ../glib/gkeyfile.c:3464 ../glib/gkeyfile.c:3594 +#: ../glib/gkeyfile.c:3738 ../glib/gkeyfile.c:3967 ../glib/gkeyfile.c:4034 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Võtmefail ei sisalda gruppi „%s“" + +#: ../glib/gkeyfile.c:1773 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Võtmefail ei sisalda võtit „%s“ grupis „%s“" + +#: ../glib/gkeyfile.c:1935 ../glib/gkeyfile.c:2051 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Võtmefail sisaldab võtit „%s“, mille väärtus „%s“ pole UTF-8 kodeeringus" + +#: ../glib/gkeyfile.c:1955 ../glib/gkeyfile.c:2071 ../glib/gkeyfile.c:2513 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "Võtmefail sisaldab võtit „%s“, mille väärtust pole võimalik kasutada." + +#: ../glib/gkeyfile.c:2731 ../glib/gkeyfile.c:3100 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Võtmefail sisaldab võtit „%s“ grupis „%s“, aga selle väärtust pole võimalik " +"kasutada" + +#: ../glib/gkeyfile.c:2809 ../glib/gkeyfile.c:2886 +#, fuzzy, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"Võtmefail sisaldab võtit '%s' grupis '%s' aga selle väärtust pole võimalik " +"kasutada" + +#: ../glib/gkeyfile.c:4274 +msgid "Key file contains escape character at end of line" +msgstr "Võtmefail sisaldab rea lõpus paomärki" + +#: ../glib/gkeyfile.c:4296 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Võtmefail sisaldab vigast paojada „%s“" + +#: ../glib/gkeyfile.c:4440 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Väärtust „%s“ pole võimalik arvulise väärtusena kasutada." + +#: ../glib/gkeyfile.c:4454 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Täisarvu väärtus „%s“ on väljaspool lubatud piire" + +#: ../glib/gkeyfile.c:4487 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Väärtust „%s“ pole võimalik ujukomalise väärtusena kasutada." + +#: ../glib/gkeyfile.c:4526 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Väärtust „%s“ pole võimalik tõeväärtusena kasutada." + +#: ../glib/gmappedfile.c:129 +#, fuzzy, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Tõrge faili '%s' rekvisiitide hankimisel: fstat() nurjus: %s" + +#: ../glib/gmappedfile.c:195 +#, fuzzy, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Tõrge faili '%s' avamisel: mmap() nurjus: %s" + +#: ../glib/gmappedfile.c:262 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': open() failed: %s" +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Tõrge faili '%s' avamisel: open() nurjus: %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Viga real %d märgil %d: " + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Nimes on vigaselt kodeeritud UTF-8 tekst - vigane '%s'" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' pole korrektne nimi" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' pole korrektne nimi: '%c' " + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "Viga real %d: %s" + +#: ../glib/gmarkup.c:675 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Viga '%-.*s' analüüsimisel. See võiks olla märgiviites olev number (näiteks " +"ê) - võib-olla on number liiga suur" + +#: ../glib/gmarkup.c:687 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Märgiviide ei lõpe semikooloniga. Enamasti kasutatakse ampersand märki ilma " +"kavatsuseta olemit alustada - märgi see kui &" + +#: ../glib/gmarkup.c:713 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Märgiviide '%-.*s' ei teisendu lubatud märgiks" + +#: ../glib/gmarkup.c:751 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Avastati tühi olem '&'; lubatud olemid on: & " < > '" + +#: ../glib/gmarkup.c:759 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Olemi nimi '%-.*s' on tundmatu" + +#: ../glib/gmarkup.c:764 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Olem ei lõppenud semikooloniga; kõige tõenäolisemalt ei kavatsenud sa " +"ampersandi kasutades olemit alustada - märgi see kui &" + +#: ../glib/gmarkup.c:1170 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument peab algama elemendiga (nt: )" + +#: ../glib/gmarkup.c:1210 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"Märk '%s' ei ole märgi '<' järel lubatud, see võib mitte olla elemendi nimi" + +#: ../glib/gmarkup.c:1252 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Veider märk '%s', elemendi '%s' lõpusildi lõpetamiseks oodatakse märki '>'" + +#: ../glib/gmarkup.c:1333 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Veider märk '%1$s', pärast elemendi '%3$s' tunnust nimega '%2$s' oodatakse " +"märki '='" + +#: ../glib/gmarkup.c:1374 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Veider märk '%s', oodatakse märke '>' või '/', mis tähitaksid elemendi '%s' " +"sildi algust või lõppu, ühe võimalusena ka rekvisiiti. Võib-olla kasutad sa " +"rekvisiidi nimes vigast märki?" + +#: ../glib/gmarkup.c:1418 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Veider märk '%s', oodatakse võrdusmärgi järel tulevat jutumärki, mis aitaks " +"rekvisiidile '%s' väärtust seada (element '%s')" + +#: ../glib/gmarkup.c:1551 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"Märk '%s' ei ole lubatud märk elemendi '%s' nime sulgemise järel, lubatud " +"märk on '>'" + +#: ../glib/gmarkup.c:1598 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Element '%s' on suletud, avatud elemente ei ole" + +#: ../glib/gmarkup.c:1607 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Element '%s' on suletud, kuid praegu avatud element on '%s'" + +#: ../glib/gmarkup.c:1760 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument on tühi või sisaldab ainult tühja ruumi" + +#: ../glib/gmarkup.c:1774 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Dokument lõppes ootamatult ilma avatud nurksulgu '<' sulgemata" + +#: ../glib/gmarkup.c:1782 ../glib/gmarkup.c:1827 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Dokument lõppes ootamatult ilma, et avatud elemente sulgemata - '%s' oli " +"viimane avatud element" + +#: ../glib/gmarkup.c:1790 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokument lõppes ootamatult, sildi <%s/> lõpetamiseks loodetakse näha " +"nurksulgu" + +#: ../glib/gmarkup.c:1796 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokument lõppes ootamatult elemendi nime sees" + +#: ../glib/gmarkup.c:1802 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokument lõppes ootamatult rekvisiidi nime sees" + +#: ../glib/gmarkup.c:1807 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokument lõppes ootamatult elemendi avamise sildi sees" + +#: ../glib/gmarkup.c:1813 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokument lõppes ootamatult pärast rekvisiidi nime järel olevat võrdusmärki, " +"rekvisiidi väärtus on puudu" + +#: ../glib/gmarkup.c:1820 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokument lõppes ootamatult keset attribuudi väärtust" + +#: ../glib/gmarkup.c:1836 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Dokument lõppes ootamatult elementi '%s' sulgemissildi sees" + +#: ../glib/gmarkup.c:1842 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokument lõppes ootamatult kommentaaride või töötlemis juhiste sees" + +#: ../glib/goption.c:861 +msgid "[OPTION…]" +msgstr "[VÕTI…]" + +#: ../glib/goption.c:977 +msgid "Help Options:" +msgstr "Abiteabe võtmed:" + +#: ../glib/goption.c:978 +msgid "Show help options" +msgstr "Abiteabe võtmete näitamine" + +#: ../glib/goption.c:984 +msgid "Show all help options" +msgstr "Kõikide abiteabe võtmete näitamine" + +#: ../glib/goption.c:1047 +msgid "Application Options:" +msgstr "Rakenduse võtmed:" + +#: ../glib/goption.c:1049 +msgid "Options:" +msgstr "Võtmed:" + +#: ../glib/goption.c:1113 ../glib/goption.c:1183 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Täisarvulist väärtust „%s“ pole võimalik %s jaoks parsida" + +#: ../glib/goption.c:1123 ../glib/goption.c:1191 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Täisarv „%s“ %s jaoks on väljaspool lubatud piire" + +#: ../glib/goption.c:1148 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Arvväärtust „%s“ pole võimalik %s jaoks parsida" + +#: ../glib/goption.c:1156 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Arv „%s“ %s jaoks on väljaspool lubatud piire" + +#: ../glib/goption.c:1448 ../glib/goption.c:1527 +#, c-format +msgid "Error parsing option %s" +msgstr "Viga võtme analüüsimisel: %s" + +#: ../glib/goption.c:1558 ../glib/goption.c:1671 +#, c-format +msgid "Missing argument for %s" +msgstr "Puuduv argument %s'i jaoks" + +#: ../glib/goption.c:2132 +#, c-format +msgid "Unknown option %s" +msgstr "Tundmatu võti %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "rikutud objekt" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "sisemine viga või rikutud objekt" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "mälu lõppes" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "tagasiviidete limiit saavutatud" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"muster sisaldab kirjeid, mis pole osalise vastavuse otsingu puhul toetatud" + +#: ../glib/gregex.c:280 +msgid "internal error" +msgstr "sisemine viga" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "osaliste vastete otsimisel pole tingimuslikud tagasiviited toetatud" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "suurim rekursioonide arv saavutatud" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "vigane reavahetusmärgiste kombinatsioon" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "vale nihe" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "lühike utf8" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "tundmatu viga" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ mustri lõpus" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c mustri lõpus" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "\\ järel on tundmatu märk" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "{} kvantori numbrid pole järjekorras" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "{} kvantori number liiga suur" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "märgiklassil puudub sulgev ]" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "märgiklassis on vigane paojada" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "märgiklassi vahemik pole järjekorras" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "pole midagi korrata" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "ootamatu kordus" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "tundmatu märk pärast (? või (?-" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX-i nimelised klassid on toetatud ainult klassi sees" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "puudub lõpetav sulg )" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "viide olematule alammustrile" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "kommentaari järel puudub sulg )" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "regulaaravaldis on liiga pikk" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "tõrge mälu hankimisel" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr ") ilma algussuluta (" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "koodi ületäitumine" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "tundmatu märk pärast (?<" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "tagasivaate esitus ei oma kindlat suurust" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "vigane number või nimi pärast (?(" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "tingimusgrupp sisaldab rohkem kui kahte haru" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "(?( järel oodatakse esitust" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R või (?[+-]digits järel peab olema )" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "tundmatu POSIX-klassi nimi" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "POSIX-i koondavad elemendid pole toetatud" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "märgi väärtus \\x{...} jadas on liiga suur" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "vigane tingimus (?(0)" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C ei ole tagasivaate esituses lubatud" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "rekursiivne kutsung võib jääda lõpmatusse tsüklisse" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "tundmatu märk pärast (?P" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "alammustri nimes puudub katkestaja" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "kaks nimelist alammustrit on sama nimega" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "vigane \\P või \\p jada" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "tundmatu omaduse nimi \\P või \\p järel" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "alammustri nimi on liiga pikk (maksimaalselt 32 märki)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "liiga palju alammustreid (suurim lubatud arv on 10 000)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "kaheksandväärtus on suurem kui \\377" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "kompilaatori tööruumi ületäitumine" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "varem kontrollitud viidatud alammustrid ei leitud" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE grupp sisaldab rohkem kui ühte haru" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "NEWLINE võtmed pole kooskõlalised" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"võtmele \\g ei järgne looksulgude, nurksulgude ega jutumärkide vahel olev " +"nimi või number ega ka lihtsalt number" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "(?& järel puudub alammustri nimi" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "(?+ järel oodati numbrit" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "sama taseme kaks nimelist alammustrit ei tohi olla sama nimega" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"võtmele \\k ei järgne looksulgude, nurksulgude või jutumärkide vahel olev " +"nimi" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "klass ei toeta \\N" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "märgi väärtus \\u.... jadas on liiga suur" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1977 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Viga regulaaravaldise %s vastavuse otsimisel: %s" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE teek on kompileeritud ilma UTF8 toeta" + +#: ../glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE teek on kompileeritud ilma UTF8 omaduste toeta" + +#: ../glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE teek on kompileeritud sobimatute valikutega" + +#: ../glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Viga regulaaravaldise %s optimeerimisel: %s" + +#: ../glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Viga regulaaravaldise %s kompileerimisel %d. märgi juures: %s" + +#: ../glib/gregex.c:2413 +msgid "hexadecimal digit or “}†expected" +msgstr "oodati kuueteistkümnendsüsteemi numbrit või „}“ märki" + +#: ../glib/gregex.c:2429 +msgid "hexadecimal digit expected" +msgstr "oodati kuueteistkümnendsüsteemi numbrit" + +#: ../glib/gregex.c:2469 +msgid "missing “<†in symbolic reference" +msgstr "puuduv „<“ märgiviites" + +#: ../glib/gregex.c:2478 +msgid "unfinished symbolic reference" +msgstr "lõpetamata märgiviide" + +#: ../glib/gregex.c:2485 +msgid "zero-length symbolic reference" +msgstr "nullpikkusega märgiviide" + +#: ../glib/gregex.c:2496 +msgid "digit expected" +msgstr "oodati numbrit" + +#: ../glib/gregex.c:2514 +msgid "illegal symbolic reference" +msgstr "keelatud märgiviide" + +#: ../glib/gregex.c:2576 +msgid "stray final “\\â€" +msgstr "liigne lõpp „\\“" + +#: ../glib/gregex.c:2580 +msgid "unknown escape sequence" +msgstr "tundmatu paojada" + +#: ../glib/gregex.c:2590 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Viga asendusteksti „%s“ analüüsimisel märgi %lu kohal: %s" + +#: ../glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Tsiteeritav tekst ei alga jutumärgiga" + +#: ../glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Vastavuseta jutumärk käsureal või kestprogrammi tsiteeritud tekstis" + +#: ../glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Tekst lõppes pärast „\\“ märki. (Tekst on „%s“)" + +#: ../glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "Tekst lõppes enne kui leiti vastav jutumärk %c jaoks. (Tekst oli „%s“)" + +#: ../glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Tekst puudus (või sisaldas ainult tühja ruumi)" + +#: ../glib/gspawn.c:253 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Tõrge andmete lugemisel alamprotsessilt (%s)" + +#: ../glib/gspawn.c:401 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Ootamatu funktsiooni select() viga andmete lugemisel alamprotsessilt (%s)" + +#: ../glib/gspawn.c:486 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ootamatu viga funktsioonis waitpid() (%s)" + +#: ../glib/gspawn.c:897 ../glib/gspawn-win32.c:1231 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: ../glib/gspawn.c:905 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:912 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:919 +#, c-format +msgid "Child process exited abnormally" +msgstr "" + +#: ../glib/gspawn.c:1324 ../glib/gspawn-win32.c:337 ../glib/gspawn-win32.c:345 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Tõrge alamprotsessi torust lugemisel (%s)" + +#: ../glib/gspawn.c:1394 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Viga poolitamisel funktsiooniga fork() (%s)" + +#: ../glib/gspawn.c:1543 ../glib/gspawn-win32.c:368 +#, fuzzy, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to change to directory “%s†(%s)" +msgstr "Tõrge kataloogi '%s' muutmisel (%s)" + +#: ../glib/gspawn.c:1553 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Tõrge alamprotsessi „%s“ käivitamisel (%s)" + +#: ../glib/gspawn.c:1563 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Tõrge alamprotsessi sisendi või väljundi ümbersuunamisel (%s)" + +#: ../glib/gspawn.c:1572 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Tõrge alamprotsessi poolitamisel funktsiooniga fork() (%s)" + +#: ../glib/gspawn.c:1580 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Tundmatu viga alamprotsessi „%s“ käivitamisel" + +#: ../glib/gspawn.c:1604 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Tõrge piisavate andmete lugemisel lapsprotsessi torust (%s)" + +#: ../glib/gspawn-win32.c:281 +msgid "Failed to read data from child process" +msgstr "Tõrge andmete lugemisel alamprotsessilt" + +#: ../glib/gspawn-win32.c:298 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Tõrge toru loomisel alamprotsessiga suhtlemiseks (%s)" + +#: ../glib/gspawn-win32.c:374 ../glib/gspawn-win32.c:493 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Tõrge alamprotsessi käivitamisel (%s)" + +#: ../glib/gspawn-win32.c:443 +#, c-format +msgid "Invalid program name: %s" +msgstr "Vigane programmi nimi: %s" + +#: ../glib/gspawn-win32.c:453 ../glib/gspawn-win32.c:720 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Vigane string argumendivektoris %d: %s" + +#: ../glib/gspawn-win32.c:464 ../glib/gspawn-win32.c:735 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Vigane string keskkonnamuutujates: %s" + +#: ../glib/gspawn-win32.c:716 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Vigane töökataloog: %s" + +#: ../glib/gspawn-win32.c:781 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Tõrge abiprogrammi käivitamisel (%s)" + +#: ../glib/gspawn-win32.c:995 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ootamatu viga, kui g_io_channel_win32_poll() funktsioon luges " +"lapsprotsessilt andmeid" + +#: ../glib/gstrfuncs.c:3247 ../glib/gstrfuncs.c:3348 +msgid "Empty string is not a number" +msgstr "" + +#: ../glib/gstrfuncs.c:3271 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s“ pole märgiga arv" + +#: ../glib/gstrfuncs.c:3281 ../glib/gstrfuncs.c:3384 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: ../glib/gstrfuncs.c:3374 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s“ pole märgita arv" + +#: ../glib/gutf8.c:811 +#, fuzzy +#| msgid "failed to get memory" +msgid "Failed to allocate memory" +msgstr "tõrge mälu hankimisel" + +#: ../glib/gutf8.c:944 +msgid "Character out of range for UTF-8" +msgstr "Märk on väljaspool UTF-8 ulatust" + +#: ../glib/gutf8.c:1045 ../glib/gutf8.c:1054 ../glib/gutf8.c:1184 +#: ../glib/gutf8.c:1193 ../glib/gutf8.c:1332 ../glib/gutf8.c:1429 +msgid "Invalid sequence in conversion input" +msgstr "Vigane jada sisendi teisendamisel" + +#: ../glib/gutf8.c:1343 ../glib/gutf8.c:1440 +msgid "Character out of range for UTF-16" +msgstr "Märk on väljaspool UTF-16 ulatust" + +#: ../glib/gutils.c:2229 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2230 ../glib/gutils.c:2436 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2231 ../glib/gutils.c:2441 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2232 ../glib/gutils.c:2446 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2233 ../glib/gutils.c:2451 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2234 ../glib/gutils.c:2456 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#: ../glib/gutils.c:2237 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2238 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2239 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2240 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2241 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2242 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2245 +#, c-format +#| msgid "%.1f kB" +msgid "%.1f kb" +msgstr "%.1f kb" + +#: ../glib/gutils.c:2246 +#, c-format +#| msgid "%.1f MB" +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#: ../glib/gutils.c:2247 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#: ../glib/gutils.c:2248 +#, c-format +#| msgid "%.1f TB" +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#: ../glib/gutils.c:2249 +#, c-format +#| msgid "%.1f PB" +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#: ../glib/gutils.c:2250 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#: ../glib/gutils.c:2253 +#, c-format +#| msgid "%.1f KiB" +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#: ../glib/gutils.c:2254 +#, c-format +#| msgid "%.1f MiB" +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#: ../glib/gutils.c:2255 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#: ../glib/gutils.c:2256 +#, c-format +#| msgid "%.1f TiB" +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#: ../glib/gutils.c:2257 +#, c-format +#| msgid "%.1f PiB" +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#: ../glib/gutils.c:2258 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: ../glib/gutils.c:2292 ../glib/gutils.c:2418 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bait" +msgstr[1] "%u baiti" + +#: ../glib/gutils.c:2296 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bitt" +msgstr[1] "%u bitti" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2363 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bait" +msgstr[1] "%s baiti" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: ../glib/gutils.c:2368 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bitt" +msgstr[1] "%s bitti" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2431 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#~ msgid "No such interface" +#~ msgstr "Sellist liidest pole" + +#, fuzzy +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Viga: sihtkoht on määramata\n" + +#, fuzzy +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "Viga nimeviida seadmisel: fail pole nimeviide" + +#, fuzzy +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "Viga nimeviida seadmisel: fail pole nimeviide" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Vaikimisi kohaliku kataloogimonitori liiki pole võimalik leida" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Viga faili nime muutmisel: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Viga avamisel: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Viga kataloogi loomisel: %s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "Aktiivset viga pole võimalik saada: %s" + +#~ msgid "Error launching application: %s" +#~ msgstr "Viga rakenduse käivitamisel: %s" + +#~ msgid "URIs not supported" +#~ msgstr "URI-d ei ole toetatud" + +#~ msgid "association changes not supported on win32" +#~ msgstr "seose muutmine pole win32 keskkonnas toetatud" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Seose loomine pole win32 keskkonnas toetatud" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Viga failist '%s' lugemisel: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Tõrge faili '%s' avamisel kirjutamiseks: fdopen() nurjus: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Tõrge faili '%s' kirjutamisel: fflush() nurjus: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Tõrge faili '%s' sulgemisel: fclose() nurjus: %s" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Võtmefail ei sisalda võtit '%s'" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "Käsk '%s' väljus mitteväljumise olekuga %d: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' teenuskirje puudub" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "töötsooni suurim tühjade alamstringide arv saavutatud" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "tõstumuutmise märgid (\\l, \\L, \\u, \\U) pole siin lubatud" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE grupi kordused pole lubatud" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "el" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pl" + +#~ msgid "File is empty" +#~ msgstr "Fail on tühi" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "Võtmefail sisaldab võtit '%s', mille väärtus pole võimalik kasutada." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Viga faili '%s' kohta andmete hankimisel: %s" + +#~ msgid "Error connecting: " +#~ msgstr "Viga ühendumisel: " + +#~ msgid "Error connecting: %s" +#~ msgstr "Viga ühendumisel: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "SOCKSv4 implementatsioon piirab kasutajanime pikkuse %i märgiga" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKSv4 implementatsioon piirab hostinime pikkuse %i märgiga" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Viga unix'ist lugemisel: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "Viga unix'i sulgemisel: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Viga unix'isse kirjutamisel: %s" diff --git a/po/eu.po b/po/eu.po new file mode 100644 index 0000000..8406e4d --- /dev/null +++ b/po/eu.po @@ -0,0 +1,6094 @@ +# Basque translation of glib. +# Copyright (C) 2004-2011 Free Software Foundation, Inc. +# +# Joseba Bidaurrazaga van Dierdonck , 2001. +# Hizkuntza Politikarako Sailburuordetza , 2004. +# Iñaki Larrañaga Murgoitio , 2004, 2005, 2006, 2007, 2008, 2009, 2010. +# Iñaki Larrañaga Murgoitio , 2011, 2012, 2013, 2014, 2015, 2016, 2017. +# Asier Sarasua Garmendia , 2019, 2020, 2021, 2022. +# +msgid "" +msgstr "Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-02-22 18:23+0000\n" +"PO-Revision-Date: 2022-02-27 10:00+0100\n" +"Last-Translator: Asier Sarasua Garmendia \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Aplikazio lehenetsia ezartzea edago onartuta oraindik" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "Erabilitako azken aplikazioa motarako ezartzea ez dago onartuta oraindik" + +#: gio/gapplication.c:497 +msgid "GApplication options" +msgstr "GApplication aplikazioaren aukerak" + +#: gio/gapplication.c:497 +msgid "Show GApplication options" +msgstr "Erakutsi GApplication-en aukerak" + +#: gio/gapplication.c:542 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Sartu GApplication zerbitzu moduan (erabili D-Bus zerbitzuaren fitxategietatik)" + +#: gio/gapplication.c:554 +msgid "Override the application’s ID" +msgstr "Gainidatzi aplikazioaren IDa" + +#: gio/gapplication.c:566 +msgid "Replace the running instance" +msgstr "Ordeztu exekuzioan dagoen instantzia" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Erakutsi laguntza" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[KOMANDOA]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Bistaratu bertsioa" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Erakutsi bertsioaren informazioa eta irten" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Zerrendatu aplikazioak" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "Zerrendatu instalatutako aplikazioak D-Bus-agatik aktibagarriak (.desktop fitxategien arabera)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Abiarazi aplikazioa" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Abiarazi aplikazioa (aukerako fitxategiekin irekitzeko)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FITXATEGIA…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktibatu ekintza bat" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Deitu aplikazioaren ekintza bati" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APP_ID EKINTZA [PARAMETROA]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Zerrendatu ekintza erabilgarriak" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Zerrendatu aplikazioaren ekintza estatikoak (.desktop fitxategitik)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APP_ID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMANDOA" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Erakutsi komandoaren laguntza xehea" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Aplikazioaren identifikatzailea D-bus formatuan (adib: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FITXATEGIA" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Aukerako fitxategi-izen erlatibo edo absolutuak, edo URIak irekitzeko" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "EKINTZA" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Ekintzaren izena deitzeko" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETROA" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Ekintza deitzean emango zaion parametroa, GVariant formatuan" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "'%s' komando ezezaguna\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Erabilera:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumentuak:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTUAK…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Komandoak:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "Erabili “%s help KOMANDOA“ laguntza xehea lortzeko.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "'%s' komandoak aplikazioaren IDa behar du zuzenean jarraitzeko\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "aplikazioaren IDa baliogabea: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "“%s†ez du argumenturik hartzen\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "ezin da D-Bus-arekin konektatu: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "errorea '%s' mezua aplikazioari bidaltzean: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "ekintzaren izena eman behar da aplikazioaren IDaren ondoren\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "baliogabeko ekintza-izena: “%sâ€\n" +"ekintzaren izenak soilik karaktere alfanumerikoak, “-†eta “.†karaktereak\n" +"eduki ditzake\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "errorea ekintzaren parametroa analizatzean: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "ekintzak gehienez parametro bat onartzen du\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "'list-actions' komandoak soilik aplikazioaren IDa hartzen du" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "ezin da '%s' aplikazioaren '.desktop' fitxategia aurkitu\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "komando ezezaguna: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Zenbaketaren balio handiegia honi pasatuta: %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Ez da bilaketarik onartzen oinarrizko korrontean" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Ezin da GBufferedInputStream trunkatu" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Korrontea jadanik itxita dago" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Trunkatzea ez da onartzen oinarrizko korrontean" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1873 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Eragiketa bertan behera utzi da" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Baliogabeko objektua, hasieratu gabe dago" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Byteen sekuentzia baliogabea sarreran" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Ez dago nahikoa lekurik helburuan" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Byteen sekuentzia baliogabea bihurketa-sarreran" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Errorea bihurtzean: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Hasieratzea bertan behera uztea ez dago onartuta" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "“%s†karaktere-multzoa “%s†bihurtzea ez da onartzen" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Ezin izan da “%s†“%s†bihurtzeko tresna ireki" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s mota" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Mota ezezaguna" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s fitxategi mota" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials-ek baliogabeko datuak ditu" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials ez dago inplementatuta SE honetan" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Ez dago GCredentials euskarririk plataforma honetan" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials-ek ez dauka prozesuaren IDrik SE honetan" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Kredentzialak usurpatzea ezinezkoa da SE honetan" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Ustekabeko korronte-amaiera azkarregia" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Onartu gabeko “%s†gakoa helbidearen “%s†sarreran" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Zentzurik gabeko gakoa/balioa bikotearen konbinazioa “%s†helbidearen sarreran" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "“%s†helbidea baliogabea da (gako hauetako bat behar du: “path†(bide-izena), “tmpdir†(aldi baterako direktorioa) edo “abstract†(abstraktua))" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Errorea “%s†helbidean — “%s†atributua gaizki osatuta dago" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "“%2$s†helbidearen “%1$s†garraioa ezezaguna edo onartu gabea" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "“%s†helbidearen elementuak ez dauka bi punturik (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "“%s†helbidearen elementuko garraio-izenak ez du hutsik egon behar" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "%d. gakoa/balioa bikoteak, “%sâ€, “%s†helbidearen elementuan, ez dauka berdina (=) ikurrik" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "%d. gakoa/balioa bikoteak, “%sâ€, “%s†helbidearen elementuan, ez du gakoa hutsik eduki behar" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "Errorea gakoa edo balioa iheseko modutik kentzean %d. gakoa/balioa bikotean, “%sâ€, “%s†helbidearen elementuan" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "Errorea “%s†helbidean - unix-eko garraioak “path†edo “abstract†gakoetariko bat behar du hain zuzen." + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Errorea “%s†helbidean — ostalariaren atributua falta da edo gaizki osatuta dago" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Errorea “%s†helbidean — atakaren atributua falta da edo gaizki osatuta dago" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "Errorea “%s†helbidean — izendapenaren fitxategiaren atributua falta da edo gaizki osatuta dago" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Errorea automatikoki abiaraztean: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Errorea “%s†izendapeneko fitxategia irekitzean: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Errorea “%s†izendapeneko fitxategitik irakurtzean: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Errorea “%s†izendapeneko fitxategitik irakurtzean: 16 byte espero ziren, baina %d lortu dira" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Errorea “%s†izendapeneko fitxategiko edukia korrontean idaztean:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Emandako helbidea hutsik dago" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Ezin da mezuaren deia abiarazi AT_SECURE ezarrita dagoenean" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ezin da mezuaren deia abiarazi makinaren IDrik gabe: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Ezin da D-Bus automatikoki abiarazi X11 $DISPLAY gabe" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Errorea “%s†komando-lerroa abiaraztean: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "Ezin da saioaren bus-eko helbidea zehaztu (ez dago SE honetan garatuta)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7334 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "Ezin da bus-aren helbidea zehaztua inguruneko DBUS_STARTER_BUS_TYPE aldagaitik. “%s†balio ezezaguna" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7343 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "Ezin da bus-aren helbidea zehaztua, inguruneko DBUS_STARTER_BUS_TYPE aldagaia ezarri gabe dagoelako" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "%d bus mota ezezaguna" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Edukiaren zati bat falta da lerro bat irakurtzean" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Edukiaren zati bat falta da lerro bat modu seguruan irakurtzean" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "Autentifikazioko metodo guztiak agortuta (saiatuta: %s) (erabilgarri: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Erabiltzailearen IDak ID bera izan behar du parekoan eta zerbitzarian" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Bertan behera utzita GDBusAuthObserver::authorize-authenticated-peer erabiliz" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Errorea “%s†direktorioaren informazioa eskuratzean: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "“%s†direktorioko baimenak gaizki osatuta. 0700 modua espero zen, baina 0%o lortuta" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Errorea “%s†direktorioa sortzean: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Eragiketa ez dago onartuta" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Errorea “%s†gako sorta irakurtzeko irekitzean: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%2$sâ€(e)ngo gako sortako %1$d. lerroa (“%3$s†edukiarekin) gaizki osatuta dago" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%2$sâ€(e)ngo gako sortako %1$d. lerroko aurreneko tokena (“%3$s†edukiarekin) gaizki osatuta dago" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%2$sâ€(e)ngo gako sortako %1$d. lerroko bigarren tokena (“%3$s†edukiarekin) gaizki osatuta dago" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Ez da %d IDko cookie-rik aurkitu “%sâ€(e)ngo gako sortan" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Errorea blokeoko “%s†fitxategia sortzean: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Errorea blokeoaren “%s†fitxategi zaharkitua ezabatzean: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Errorea blokeoko (estekatu gabeko) “%s†fitxategia ixtean: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Errorea blokeoko “%s†fitxategia desestekatzean: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Errorea “%s†gako sorta idazteko irekitzean: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Gainera, “%sâ€(r)en blokeoa askatzeak ere huts egin du: %s) " + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2418 +msgid "The connection is closed" +msgstr "Konexioa itxi egin da" + +#: gio/gdbusconnection.c:1903 +msgid "Timeout was reached" +msgstr "Denbora-mugara iritsi da" + +#: gio/gdbusconnection.c:2541 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Onartu gabeko banderak aurkitu dira bezeroaren aldeko konexioa eraikitzean" + +#: gio/gdbusconnection.c:4269 gio/gdbusconnection.c:4623 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "Ez dago “org.freedesktop.DBus.Properties†interfazerik %s bide-izeneko objektuan" + +#: gio/gdbusconnection.c:4414 +#, c-format +msgid "No such property “%sâ€" +msgstr "Ez dago “%s†propietaterik" + +#: gio/gdbusconnection.c:4426 +#, c-format +msgid "Property “%s†is not readable" +msgstr "“%s†propietatea ez da irakurgarria" + +#: gio/gdbusconnection.c:4437 +#, c-format +msgid "Property “%s†is not writable" +msgstr "“%s†propietatea ez da idazgarria" + +#: gio/gdbusconnection.c:4457 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "Errorea “%s†propietatea ezartzean: “%s†mota espero zen, baina “%s†lortu da" + +#: gio/gdbusconnection.c:4562 gio/gdbusconnection.c:4777 +#: gio/gdbusconnection.c:6760 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Ez dago “%s†interfazerik" + +#: gio/gdbusconnection.c:4999 gio/gdbusconnection.c:7274 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Ez dago “%s†interfazerik %s bide-izeneko objektuan" + +#: gio/gdbusconnection.c:5100 +#, c-format +msgid "No such method “%sâ€" +msgstr "Ez dago “%s†metodorik" + +#: gio/gdbusconnection.c:5131 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "“%s†mezu mota ez dator bat espero zen “%s†motarekin" + +#: gio/gdbusconnection.c:5334 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Jadanik objektu bat esportatuta dago %s interfazearentzako %s(e)n" + +#: gio/gdbusconnection.c:5561 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Ezin da %s.%s propietatea eskuratu" + +#: gio/gdbusconnection.c:5617 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Ezin da %s.%s propietatea ezarri" + +#: gio/gdbusconnection.c:5796 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "“%s†metodoak “%s†mota itzuli du, baina “%s†espero zen" + +#: gio/gdbusconnection.c:6872 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "“%s†metodoa, “%s†interfazekoa eta “%s†sinadura duena, ez da existitzen" + +#: gio/gdbusconnection.c:6993 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Azpizuhaitza jadanik %s(e)ra esportatuta" + +#: gio/gdbusconnection.c:7282 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Objekturik ez da existitzen “%s†bide-izenean" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "mota baliogabea da" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL-en mezua: goiburuko PATH edo MEMBER eremua falta da" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN-en mezua: goiburuko REPLY_SERIAL eremua falta da" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR-en mezua: goiburuko REPLY_SERIAL edo ERROR_NAME eremua falta da" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL-en mezua: goiburuko PATH, INTERFACE edo MEMBER eremua falta da" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "SIGNAL-en mezua: goiburuko PATH eremua '/org/freedesktop/DBus/Local' balio erreserbatua erabiltzen ari da" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "SIGNAL-en mezua: goiburuko INTERFACE eremua '/org/freedesktop/DBus/Local' balio erreserbatua erabiltzen ari da" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "byte %lu irakurtzea nahi zen, baina soilik %lu lortu da" +msgstr[1] "%lu byte irakurtzea nahi ziren, baina %lu lortu da" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "NUL bytea espero zen “%s†katearen ondoren, baina “%d†bytea aurkitu da" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "Baliozko UTF-8 katea espero zen, baina baliogabeko byte batzuk aurkitu dira byteen %d desplazamenduan (katearen luzera: %d). Ordurarteko baliozko UTF-8 katea honakoa zen: “%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Balioa sakonegi habiaratuta dago" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Analizatutako “%s†balioa ez da baliozko D-Bus objektuaren bide-izen bat" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Analizatutako “%s†balioa ez da baliozko D-Bus sinadura" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "%u byte luzerako matrizea aurkituta. Gehieneko luzera 2<<26 byte da (64 MiB)." +msgstr[1] "%u byte luzerako matrizea aurkituta. Gehieneko luzera 2<<26 byte da (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "“a%c' motako matrizea aurkitu da, expected to have a length a multiple of %u byteko multiploko luzera edukitzea espero zen, baina %u byteko luzera du" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "D-Bus-en ez dira hutsik dauden egiturak (tuplak) onartzen" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Analizatutako “%s†balioa aldagaiarentzat ez da baliozko D-Bus sinadura bat" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "Errorea GVariant deserializatzean “%s†kate motarekin D-Bus konexioko formatutik" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "Baliogabeko endian balioa. 0x6c (“l“) edo 0x42 (“B“) espero zen, baina 0x%02x balioa aurkitu da." + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Protokoloaren bertsio nagusia baliogabea. 1 espero zen, baina %d aurkitu da" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Sinaduraren goiburua aurkitu da, baina ez da sinadura motakoa" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "Sinaduraren goiburua “%s†sinadurarekin aurkitu da, baina gorputza hutsik dago" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Analizatutako “%s†balioa ez da baliozko D-Bus sinadura (gorputzarentzako)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Ez dago sinaduraren goibururik mezuan, baina mezuaren gorputzak %u byte du" +msgstr[1] "Ez dago sinaduraren goibururik mezuan, baina mezuaren gorputzak %u byte ditu" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Ezin da mezua deserializatu: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "Errorea GVariant serializatzean “%s†kate motarekin D-Bus konexioaren formatura" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "Mezuko fitxategi-deskriptoreen kopurua (%d) goiburu-eremukoaren (%d) desberdina da" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Ezin da mezua serializatu: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Mezuaren gorputzak “%s†sinadura du, baina ez dago sinaduraren goibururik" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "Mezuaren gorputzak “%s†sinadura mota du, baina goiburuaren eremuko sinadura “%s†da" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Mezuaren gorputza hutsik dago, baina goiburuaren eremuko sinadura “(%s)“ da" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Errorearen itzulera “'%s†motako gorputzarekin" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Errorearen itzulera gorputz hutsarekin" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Sakatu edozer tekla leihoa ixteko)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Saioaren dbus ez da exekutatzen ari, eta abiarazte automatikoak huts egin du" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Ezin da hardwarearen profila eskuratu: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Ezin izan da %s edo %s kargatu: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Errorea %s(r)en StartServiceByName deia egitean: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Ustekabeko %d erantzuna StartServiceByName(“%sâ€) metodotik" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "Ezin da metodoari deitu: proxyak jaberik gabeko %s izen ezaguna du eta G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START banderarekin eraiki zen" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Izen abstraktuen lekua ez da onartzen" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Ezin da izendapeneko fitxategia zehaztu zerbitzari bat sortzean" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Errorea “%s†izendapeneko fitxategian idaztean: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "“%s†katea ez da baliozko D-Bus GUID bat" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Ezin da onartu gabeko “%s†garraioa entzun" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "Komandoak:\n" +" help Informazio hau erakusten du\n" +" introspect Urruneko objektu baten introspekzioa\n" +" monitor Urruneko objektu bat monitorizatzen du\n" +" call Urruneko objektu bateko metodo bati deitzen dio\n" +" emit Seinale bat igortzen du\n" +" wait Zain egon bus-izen bat agertu arte\n" +"\n" +"Erabili “%s KOMANDOA --help†komando bakoitzari dagokion laguntza lortzeko.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Errorea: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Errorea introspekzioko XMLa analizatzean: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Errorea: '%s' ez da baliozko izena\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Errorea: '%s' ez da objektuaren baliozko bide-izena\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Konektatu sistemako bus-arekin" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Konektatu saioko bus-arekin" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Konektatu emandako D-Bus helbidera" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Konexioaren amaierako puntuaren aukerak:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Aukerak konexioaren amaierako puntua zehaztuz" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Ez da konexioaren amaierako punturik zehaztu" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Konexioaren hainbat amaierako puntu zehaztu dira" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Abisua: introspekzioko datuen arabera, “%s†interfazea ez da existitzen\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "Abisua: introspekzioko datuen arabera, “%s†metodoa ez da existitzen “%s†interfazean\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Seinalearen aukerazko helburua (izen esklusiboa)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Objektuaren bide-izena bere gainera seinalea igortzeko" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Seinale eta interfazearen izena" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Igorri seinale bat." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Errorea konektatzean: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Errorea: '%s' ez da bus-aren baliozko izen esklusiboa\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Errorea: objektuaren bide-izena ez dago zehaztuta\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Errorea: seinalearen izena ez dago zehaztuta\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Errorea: “%s†seinalearen izena baliogabea da\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Errorea: '%s' ez da interfazearen baliozko izena\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Errorea: '%s' ez da kidearen baliozko izena\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Errorea %d parametroa analizatzean: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Errorea konexioa garbitzean: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Helburuaren izena metodoari deitzeko" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Objektuaren bide-izena metodoari deitzeko" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Metodo eta interfazearen izena" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Denbora-muga (segundotan)" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Onartu baimen dinamikoa" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Deitu metodo bati urruneko objektu batean." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Errorea: helburua ez dago zehaztuta\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Errorea: '%s' ez da busaren baliozko izena\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Errorea: metodoaren izena ez dago zehaztuta\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Errorea: “%s†metodoaren izena baliogabea da\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Errorea “%2$s†motako %1$d parametroa analizatzean: %3$s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Errorea %d heldulekua gehitzean: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Helburuko izena introspekzioa egiteko" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Objektuaren bide-izena introspekzioa egiteko" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Inprimatu XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Aztertu umeen barnean" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Soilik inprimatzeko propietateak" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Urruneko objektu baten introspekzioa egin." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Helburuko izena monitorizatzeko" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Objektuaren bide-izena monitorizatzeko" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitorizatu urruneko objektu bat." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Errorea: ezin da monitorizatu non-message-bus konexio bat\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Aktibatu beharreko zerbitzua bestearen (izen ezaguna) zain egon aurretik" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "Denbora-muga errore batekin irten aurretik zain egoteko (segundotan); 0 denbora-mugarik ez (lehenetsia)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[AUKERA…] BUS-IZENA" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Bus-izen bat agertzeko zain egon." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Errorea: zerbitzua zehaztu behar da aktibatzeko.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Errorea: zerbitzua zehaztu behar da haren zain egoteko.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Errorea: argumentu gehiegi.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Errorea: '%s' ez da busaren izen ezagun bat\n" + +#: gio/gdebugcontrollerdbus.c:357 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Ez duzu arazketa-ezarpenak aldatzeko baimenik" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Izengabea" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Mahaigaineko fitxategiak ez du Exec eremua zehaztu" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Ezin izan da aplikazioak eskatzen duen terminala aurkitu" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Ezin da erabiltzailearen aplikazioaren %s konfigurazio-karpeta sortu: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Ezin da erabiltzailearen MIMEren %s konfigurazio-karpeta sortu: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Aplikazioaren informazioari identifikatzaile bat falta zaio" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Ezin da erabiltzailearen mahaigaineko %s fitxategia sortu" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "%s(r)en definizio pertsonalizatua" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "gailuak ez dauka “egotzi†inplementatuta" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "gailuak ez dauka “egotzi†edo “egotzi eragiketarekin†inplementatuta" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "gailuak ez dauka euskarria eskaneatzeko inplementaziorik" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "gailuak ez dauka “abiatu†inplementatuta" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "gailuak ez dauka “gelditu†inplementatuta" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS motorrak ez du inplementatu TLS loturen atzitzea" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS euskarria ez dago erabilgarri" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS euskarria ez dago erabilgarri" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Ezin da GEmblem kodeketaren %d bertsioa kudeatu" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Gaizki osatutako token kopurua (%d) GEmblem kodeketan" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Ezin da GEmblemedIcon kodeketaren %d bertsioa kudeatu" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Gaizki osatutako token kopurua (%d) GEmblemedIcon kodeketan" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblen espero zen GEmblemedIcon-entzako" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Ontziaren muntaia ez da existitzen" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Ezin da direktorioaren gainean kopiatu" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Ezin da direktorioa kopiatu direktorio gainean" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Helburuko fitxategia existitzen da" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Ezin da direktorioa errekurtsiboki kopiatu" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Lotura ez da onartzen" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Errorea fitxategia batzean: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Muntaien artean kopiatzea (reflink/clone) ez dago onartuta" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopiatzea (reflink/clone) ez dago onartuta edo baliogabea da" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopiatzea (reflink/clone) ez dago onartuta edo ez du funtzionatzen" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Ezin da fitxategi berezia kopiatu" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Esteka sinbolikoaren baliogabeko balioa eman da" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Esteka sinbolikoak ez dira onartzen" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Zakarrontzira botatzea ez dago onartuta" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Fitxategi-izenek ezin dute “%c†eduki" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "bolumenak ez dauka muntatzea inplementatuta" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Ez da aplikaziorik erregistratu fitxategi hau kudeatzeko" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumeratzailea itxi da" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Fitxategiaren enumeratzaileak eragiketa bat du lanean" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Fitxategiaren enumeratzailea itxita dago jadanik" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Ezin da GFileIcon kodeketaren %d bertsioa kudeatu" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Gaizki osatutako sarrerako datuak GFileIcon-entzako" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Korronteak ez du query_info onartzen" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Ez da bilaketarik onartzen korrontean" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Trunkatzea ez da baimentzen sarrerako korrontean" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Trunkatzea ez da onartzen korrontean" + +# +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Ostalari-izen baliogabea" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "HTTP proxyaren okerreko erantzuna" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP proxyaren konexioa ez dago baimenduta" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP proxyaren autentifikazioak huts egin du" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP proxyaren autentifikazioa behar da" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP proxyaren konexioak huts egin du: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP proxyaren erantzuna handiegia da" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP proxy zerbitzariak konexioa ustekabean itxi du." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Okerreko token kopurua (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Ez dago %s klasearen izen motarik" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s motak ez du GIcon interfazea inplementatzen" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "%s mota ez du klaserik" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Gaizko osatutako bertsio zenbakia: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s motak ez du from_tokens() inplementatzen GIcon interfazean" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Ezin da ikonoaren kodeketaren emandako bertsioa kudeatu" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Ez da helbiderik zehaztu" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "%u luzera luzeegia da helbidearentzako" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Helbideak aurrizkiaren luzera baino harago bitak ditu ezarrita" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Ezin izan da “%s†analizatu IP helbide-maskara gisa" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Ez dago nahikoa lekurik socket helbideentzako" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Onartu gabeko socket helbidea" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Sarrerako korronteak ez dauka irakurtzea inplementatuta" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Korronteak eragiketa bat du lanean" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopiatu fitxategiarekin" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Mantendu fitxategiarekin lekuz aldatzean" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†ez du argumenturik hartzen" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Erabilera:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Erakutsi bertsioaren informazioa eta irten" + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Komandoak:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Kateatu fitxategiak irteera estandarrera" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopiatu fitxategi bat edo gehiago" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Erakutsi kokalekuei buruzko informazioa" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Abiarazi aplikazio bat mahaigaineko fitxategi batetik" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Zerrendatu kokalekuen edukia" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Lortu edo ezarri MIME mota baten maneiatzailea" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Sortu direktorioak" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitorizatu fitxategi eta direktorioen aldaketak" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Muntatu edo desmuntatu kokalekuak" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Aldatu fitxategi bat edo gehiago lekuz" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Ireki fitxategiak aplikazio lehenetsiarekin" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Aldatu fitxategi-izena" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Ezabatu fitxategi bat edo gehiago" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Irakurri sarrera estandarretik eta gorde" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Ezarri fitxategiaren atributua" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Bota fitxategi edo direktorioak zakarrontzira" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Zerrendatu kokalekuen edukia zuhaitz batean" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Erabili %s laguntza xehea lortzeko.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Errorea irteera arruntean (stdout) idaztean" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "KOKALEKUA" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Kateatu fitxategiak eta erakutsi irteera estandarrean" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "'cat' tresna bezala erabiltzen da 'gio cat', baina GIOren kokalekuak erabiliz lokaleko fitxategien ordez. Adibidez, honelako zerbait erabil dezakezu kokaleku gisa: smb://zerbitzaria/baliabidea/fitxategia.txt" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Ez da kokalekurik eman" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ez dago helburuko direktorioa" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Erakutsi jarraipena" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Galdetu gainidatzi aurretik" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Mantendu atributu guztiak" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Egin existitzen diren helburuko fitxategien babeskopia" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Inoiz ez jarraitu esteka sinbolikoak" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Erabili baimen lehenetsiak helbururako" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Transferituta: %s / %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ITURBURUA" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "HELBURUA" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopiatu fitxategi bat edo gehiago ITURBURUtik HELBURUra." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "'cp' tresna bezala erabiltzen da 'gio copy', baina GIOren kokalekuak erabiliz lokaleko fitxategien ordez. Adibidez, honelako zerbait erabil dezakezu kokaleku gisa: smb://zerbitzaria/baliabidea/fitxategia.txt" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "'%s' helburua ez da direktorio bat" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: gainidatzi “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Zerrendatu atributu idazgarriak" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Lortu fitxategi-sistemako informazioa" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Atributuak lortzeko" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTUAK" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ez jarraitu esteka sinbolikoak" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributuak:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "bistaratu izena: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "editatu izena: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "izena: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "mota: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "tamaina: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "ezkutukoa\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "URIa: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "bide-izen lokala: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix muntatzea: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atributu ezargarriak:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Atributu idazgarrien izen-espazioak:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Erakutsi kokalekuei buruzko informazioa." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "“ls†tresna bezala erabiltzen da “gio info“, baina GIOren kokalekuak erabiliz \n" +"lokaleko fitxategien ordez. Adibidez, honelako zerbait erabil dezakezu\n" +"kokaleku gisa: smb://zerbitzaria/baliabidea/fitxategia.txt. Fitxategiaren\n" +"atributuak haien GIO izenekin zehatz daiteke, adibidez, standard::icon edo\n" +"izen-espazioarekin, adib. unix edo “*“ (atributu guztiekin bat datorrelarik)." + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "MAHAIGAIN-FITXATEGIA [FITXATEGI-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "Abiarazi aplikazio bat mahaigaineko fitxategi batetik, fitxategi-izenaren aukerako argumentuak pasatuta." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Ez da mahaiganeko fitxategirik zehaztu" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Abiarazte-komandoa ez dago onartuta plataforma honetan" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Ezin izan da ‘%s‘ kargatu: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Ezin izan da aplikazio-informazioa kargatu honetarako: ‘%s‘" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Ezin izan da ‘%s’ aplikazioa abiarazi: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Erakutsi ezkutuko fitxategiak" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Erabili zerrenda luzeen formatua" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Inprimatu bistaratze-izenak" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Erakutsi URI osoak" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Zerrendatu kokalekuen edukia." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "'ls' tresna bezala erabiltzen da 'gio list', baina GIOren kokalekuak erabiliz \n" +"lokaleko fitxategien ordez. Adibidez, honelako zerbait erabil dezakezu\n" +"kokaleku gisa: smb://zerbitzaria/baliabidea/fitxategia.txt. Fixategiaren\n" +"atributuak haien GIO izenekin zehatz daiteke, adibidez, standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMEMOTA" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "MANEIATZAILEA" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Lortu edo ezarri MIME mota baten maneiatzailea." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "Ez bada maneiatzailerik ematen, MIME motarentzako erregistratutako\n" +"eta gomendatutako aplikazio guztiak zerrendatzen ditu. Maneiatzaile\n" +"bat ematen bada, MIME motaren maneiatzaile lehenetsi gisa ezarriko da." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "MIME mota bakarra zehaztu behar da, eta agian maneiatzaile bat" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Ez dago “%sâ€(r)en aplikazio lehenetsirik\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "“%sâ€(r)en aplikazio lehenetsia: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Erregistratutako aplikazioak:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Ez dago erregistratutako aplikaziorik\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Gomendatutako aplikazioak:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Ez dago gomendatutako aplikaziorik\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Huts egin du â€%s†maneiatzailearen informazioa kargatzean" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Huts egin du “%s†maneiatzaile lehenetsi gisa ezartzean “%sâ€(r)entzako: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Sortu direktorio gurasoak" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Sortu direktorioak." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "'mkdir' tresna bezala erabiltzen da 'gio mkdir', baina GIOren kokalekuak\n" +"erabiliz lokaleko fitxategien ordez Adibidez, honelako zerbait erabil dezakezu\n" +"kokaleku gisa: smb://zerbitzaria/baliabidea/fitxategia.txt" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitorizatu direktorio bat (lehenetsia: motaren arabera)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitorizatu direktorio bat (lehenetsia: motaren arabera)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Monitorizatu fitxategi bat (esteka gogorren bidez egindako aldaketaz ohartzen du)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitorizatu fitxategi bat zuzenean, baina ez eman aldaketen berri" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "Eman leku eta izen aldaketen berri ezabatutako/sortutako gertaera gisa" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Zaindu muntaketen gertaerak" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitorizatu fitxategi edo direktorioen aldaketak" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Muntatu muntagarri gisa" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Muntatu bolumena gailu-fitxategiarekin edo beste identifikatzaile batekin" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "IDa" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Desmuntatu" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Egotzi" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Gelditu unitatea gailu-fitxategiarekin" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "GAILUA" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Desmuntatu muntatze-puntu guztiak emandako eskemarekin" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ESKEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ez ikusi egin amaitu gabeko fitxategien eragiketei desmuntatzean edo egozketan" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Erabili erabiltzaile anonimoa autentifikatzean" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Zerrenda" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitorearen gertaerak" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Erakutsi informazio gehigarria" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Zenbakizko PIMa VeraCrypt bolumen bat desblokeatzean" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Muntatu TCRYPT bolumen ezkutu bat" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Muntatu TCRYPT sistema-bolumen bat" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonimoki atzitzea debekatua" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Ez dago unitaterik gailu-fitxategirako" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Ez dago bolumenik ID horretarako" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Muntatu edo desmuntatu kokalekuak." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ez erabili ordezkoaren kopia eta ezabatzea" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Aldatu fitxategi bat edo gehiago lekuz ITURBURUtik HELBURUra." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "'mv' tresna bezala erabiltzen da 'gio move', baina GIOren kokalekuak\n" +"erabiliz lokaleko fitxategien ordez Adibidez, honelako zerbait erabil\n" +"dezakezu kokaleku gisa: smb://zerbitzaria/baliabidea/fitxategia.txt" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "%s helburua ez da direktorioa" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "Ireki fitxategiak mota honetako fitxategiak kudeatzeko\n" +"erregistratuta dagoen aplikazio lehenetsiarekin." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ez ikusi egin existitzen ez diren fitxategiei, inoiz ere ez galdetu" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Ezabatu emandako fitxategiak" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "IZENA" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Aldatu fitxategi-izena." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Argumentua falta da" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Argumentu gehiegi" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Izenez ongi aldatu da. URI berria: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Sortu soilik ez bada existitzen" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Erantsi fitxategiaren amaieran" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Sortzean, murriztu uneko erabiltzailearen atzipena" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Ordeztean, ordeztu helburukoa existituko ez balitz bezala" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Inprimatu entitate-etiketa (etag) berria amaieran" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Fitxategiaren entitate-etiketa (etag) gainidazten ari da" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ENTITATE-ETIKETA (ETAG)" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Errorea sarrera arruntetik (stdin) irakurtzean" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Entitate-etiketa ez dago eskuragarri\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Irakurri sarrera estandarretik eta gorde HELBIDEAN." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Ez da helbururik eman" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Atributu mota" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "MOTA" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUTUA" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "BALIOA" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Ezarri fitxategiaren KOKALEKUA atributua" + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Ez da kokalekurik zehaztu" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Ez da atributurik zehaztu" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Ez da baliorik zehaztu" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Baliogabeko â€%s†atributu mota" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Hustu zakarrontzia" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Zakarrontziko fitxategiak zerrendatzen ditu, haien jatorrizko kokalekuekin" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "Leheneratu fitxategi bat zakarrontzitik bere jatorrizko kokalekura (posible bada, direktorioa birsortuta)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Ezin izan da jatorrizko bide-izena aurkitu" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Ezin izan da jatorrizko kokalekua birsortu: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Ezin izan da fitxategia bere jatorrizko kokalekura eraman: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Eraman/Leheneratu fitxategiak edo direktorioak zakarrontzira." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "Oharra: --restore aukera erabiltzeko, zakarrontziratutako fitxategiaren jatorrizko\n" +"kokalekua lehendik badago, ez da gainidatziko --force ezarrita ez badago." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Emandako kokalekua ez da trash:/// testuarekin hasten" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Jarraitu esteka sinbolikoak, muntatze-puntuak eta lasterbideak" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Zerrendatu direktorioen edukia zuhaitz baten bezalako formatuan." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> elementua ez da <%s>(r)en barruan onartzen" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> elementua ez da maila gorenean onartzen" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "%s fitxategia hainbat aldiz agertzen da baliabidean" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Huts egin du “%s†bilatzean edozein iturburuko direktoriotan" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Huts egin du “%s†bilatzean uneko direktorioan" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Prozesuaren “%s†aukera ezezaguna" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "%s aurreprozesatzea eskatu da, baina %s ez dago ezarrita eta %s ez dago BIDE-IZENA aukeran" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Errorea '%s' fitxategia irakurtzean: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Errorea %s fitxategia konprimatzean" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "testua ezin da <%s>(r)en barruan egon" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Erakutsi programaren bertsioa eta irten" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Irteerako fitxategiaren izena" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "FITXATEGIA atributuak erreferentziatutako fitxategiak kargatzeko direktorioak (lehenetsia: uneko direktorioa)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIREKTORIOA" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Sortu irteera hautatutako formatuan helburuko fitxategiaren luzapenaren arabera" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Sortu iturburuaren goiburua" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Sortu iturburu-kodea (baliabidearen fitxategia zure kodean estekatzeko erabilita)" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Sortu mendekotasunen zerrenda" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Sortuko den mendekotasun-fitxategiaren izena" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Sartu helburu faltsuak sortutako mendekotasun-fitxategian" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Ez sortu eta erregistratu baliabidea automatikoki" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ez esportatu funtzioak: deklaratu haiek G_GNUC_INTERNAL gisa" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "Ez kapsulatu baliabide-datuak C fitxategian; onartu kanpotik estekatuta dagoela" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C identifikatzailearen izena (sortutako iturburuaren kodean erabilita)" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Helburuko C konpilatzailea (balio lehenetsia: CC ingurumen-aldagaia)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "Konpilatu baliabidearen zehaztapen bat baliabideko fitxategi batean.\n" +"Baliabideen zehaztapenen fitxategiak .gresource.xml luzapena dute,\n" +"eta baliabideen fitxategiek berriz .gresource luzapena." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Fitxategi baten izena bakarrik eman behar duzu\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "goitizenak gutxienez 2 karaktere eduki behar ditu" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Baliogabeko zenbakizko balioa" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " jadanik zehaztuta" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "\"value='%s'\" jadanik zehaztuta" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "balioen banderek 1 bit ezarrita eduki behar dute" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s>(e)k gutxienez bat eduki behar du" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> ez dago zehaztutako barrutian" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> ez da zehaztutako zenbatutako motaren baliozko kidea" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s>(e)k badu katerik zehaztutako bandera motetan ez dagoena" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s>(e)k badu katerik -en ez dagoena" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " jadanik zehaztuta gako honentzat" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ez dago baimenduta “%s†motako gakoentzako" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " zehaztutako gutxienekoa gehienekoa baino handiagoa da" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "onartu gabeko l10n kategoria: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n eskatuta, baina ez da gettext-en domeinurik eman" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "balioaren emandako itzulpenaren testuingurua l10n gaitu gabe" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Huts egin du “%s†motaren balioa analizatzean " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "Ezin da zehaztu zenbatutako mota bat baluten bezalako etiketatutako gakoentzako" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " jadanik zehaztuta gakoarentzako" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ez dago baimenduta “%s†motako gakoentzako" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " jadanik emanda" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "-ek gutxienez bat eduki behar du" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " jadanik zehaztuta gako honentzako" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr " soilik zehatz daitezke zenbatuta edo banderak motetako gakoekin, edo ondoren" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr " eman da “%s†jadanik zenbatuta motako kide denean" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " eman da jadanik emanda dagoenean" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " jadanik zehaztuta" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "helburuko “%s†aliasa ez da zenbatuta motakoa" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "helburuko “%s†aliasa ez dagon -en" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "-ek gutxienez bat eduki behar du" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Izen hutsak ez daude baimenduta" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "“%s†izena baliogabea: izenak letra minuskula batekin hasi behar dira" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "“%s†izena baliogabea: “%c†karakterea baliogabea. soilik letra minuskulak, zenbakiak eta hipenazioa (“-“) onartzen dira." + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "“%s†izena baliogabea: bi hipenazio jarraian (“--“) ez dago onartuta." + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "“%s†izena baliogabea: azken karakterea ezin da hipenazioa (“-“) izan." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "“%s†izena baliogabea: gehieneko luzera 1024 da" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " jadanik zehaztuta" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Ezin zaio gakorik gehitu “list-of†eskema bati" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " jadanik zehaztuta" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "-ek iluntzen du -en; erabili balioa aldatzeko" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "-rentzako hauetariko bat zehaztu behar da atributu gisa: “type“, “enum“edo “flags“" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> ez dago (oraindik) definituta." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Baliogabeko GVariant motako “%s†katea" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " eman da, baina eskema ez da ezer hedatzen ari" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Ez dago (e)rik gainidazteko" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " jadanik zehaztuta" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " jadanik zehaztuta" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " oraindik existitzen ez den “%s†eskema hedatzen du" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " oraindik existitzen ez den “%s†eskemaren zerrenda da" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Ezin da bide-izena duen eskema baten zerrenda izan" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Ezin da eskema bat bide-izen batekin hedatu" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " zerrenda bat da, zerrenda ez den hedatzen duena" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "(e)k hedatzen du, baina “%sâ€(e)k ez du “%s†hedatzen" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Bide-izen bat ematen bada, barra batekin (/) hasi eta amaitu behar da" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Zerrenda bateko bide-izena “:/“-rekin amaitu behar da" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "Abisua: “%s†eskemak “%s†bide-izena du. \"/apps/\", \"/desktop/\" edo \"/system/\"-ekin hasten diren bide-izenak zaharkituta daude." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> jadanik zehaztuta" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Soilik <%s> elementu bakarra onartzen da <%s>(r)en barruan" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "<%s> elementua ez da maila gorenean onartzen" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr " elementua behar da -en" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Testua ezin da <%s>(r)en barruan egon" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Abisua: definitu gabeko erreferentzia -erako" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict zehaztu da; irteten." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Fitxategi oso honi ezikusi egin zaio." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Fitxategi honi ezikusi egiten." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "Ez dago “%s†gakorik “%s†eskeman, gainidazteko “%s†fitxategian ageri den bezala; gako honen gainidazteari ezikusi egiten." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "Ez dago “%s†gakorik “%s†eskeman, gainidazteko “%s†fitxategian ageri den bezala, eta --strict zehaztu da; irteten." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "Ezin dira mahaigainaren araberako gainidazteak hornitu “%s†gako lokalizatuetarako “%s†eskeman (gainidatzi “%s†fitxategia); gako honen gainidazteari ezikusi egiten." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "Ezin dira mahaigainaren araberako gainidazteak hornitu “%s†gako lokalizatuetarako “%s†eskeman (gainidatzi “%s†fitxategia), eta --strict zehaztu da; irteten." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "Errorea “%s†gakoa (“%s†eskemakoa) analizatzean “%s†gainidazte-fitxategian ageri den bezala: %s. Gako honen gainidazteari ezikusi egiten." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "Errorea “%s†gakoa (“%s†eskemakoa) analizatzean “%s†gainidazte-fitxategian ageri den bezala: %s. --strict zehaztu da; irteten." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "“%s†gakoaren gainidaztea (“%s†eskemakoa) “%s†gainidazte-fitxategian ageri den bezala, eskeman emandako barrutitik kanpo dago; gako honen gainidazteari ezikusi egiten." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "“%s†gakoaren gainidaztea (“%s†eskemakoa) “%s†gainidazte-fitxategian ageri den bezala, eskeman emandako barrutitik kanpo dago eta --strict zehaztu da; irteten." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "“%s†gakoaren gainidaztea (“%s†eskemakoa) “%s†gainidazte-fitxategian ageri den bezala, ez dago baliozko aukeren zerrendan; gako honen gainidazteari ezikusi egiten." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "“%s†gakoaren gainidaztea (“%s†eskemakoa) “%s†gainidazte-fitxategian ageri den bezala, ez dago baliozko aukeren zerrendan eta --strict zehaztu da; irteten." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Non gordeko den 'gschemas.compiled' fitxategia" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Abortatu eskemetan edozer motako erroreak agertzean" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Ez idatzi gschema.compiled fitxategia" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Ez derrigortu gako-izenen murriztapenik" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "Konpilatu GSettings eskemen fitxategi guztiak eskema-cache batean.\n" +"Eskemen fitxategiek .gschema.xml luzapena eduki behar dute,\n" +"eta cache-ko fitxategia gschemas.compiled deitzen da." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Direktorio baten izena bakarrik eman behar duzu" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Ez da eskemen fitxategirik aurkitu: ez da ezer egingo." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Ez da eskemen fitxategia aurkitu: lehendik dagoen irteera-fitxategia kendu da." + +# +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "%s fitxategi-izen baliogabea" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Errorea %s(r)en fitxategi-sistemako informazioa lortzean: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Ez da %s fitxategiaren muntatze-puntua aurkitzen" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Ezin da erroko direktorioa izenez aldatu" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Errorea '%s' fitxategia izenez aldatzean: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Ezin da fitxategia izenez aldatu, fitxategi-izena badago lehendik ere" + +# +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Fitxategi-izen baliogabea" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Errorea '%s' fitxategia irekitzean: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Errorea '%s' fitxategia kentzean: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Errorea '%s' fitxategia zakarrontzira botatzean: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Ezin izan da %s zakarrontzi-direktorioa sortu: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Ezin da '%s' zakarrontziaren goi-mailako direktorioa aurkitu" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Sistemaren barneko muntaietan ez da onartzen zakarrontzira botatzea" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Ezin izan da %s zakarrontzi-direktorioa aurkitu edo sortu %s zakarrontzian" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Ezin da '%s' fitxategiaren zakarrontzi-informazioa sortu: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Ezin da '%s' fitxategia fitxategi-sistemen arteko zakarrontzira bota" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Ezin da '%s' fitxategia zakarrontzira bota: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Ezin da '%s' fitxategia zakarrontzira bota" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Errorea '%s' direktorioa sortzean: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Fitxategi-sistemak ez ditu esteka sinbolikorik onartzen" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Errorea '%s' esteka sinbolikoa sortzean: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Errorea '%s' fitxategia lekuz aldatzean: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Ezin da direktorioa lekuz aldatu direktorioaren gainera" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Huts egin du babeskopia sortzean" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Errorea helburuko fitxategia kentzean: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Muntaien artean lekuz aldatzea ez dago onartuta" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ezin izan da '%s' diskoaren erabilpena zehaztu: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Atributuaren balioa NULL ezin da izan" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Atributu mota baliogabea (katea espero zen)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Atributu hedatuaren izen baliogabea" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Errorea “%s†atributu hedatua ezartzean: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (baliogabeko kodeketa)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Errorea “'%s†fitxategiaren informazioa eskuratzean: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Errorea fitxategiaren deskriptorearen informazioa irakurtzean: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Baliogabeko atributu mota (uint32 espero zen)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Baliogabeko atributu mota (uint64 espero zen)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Baliogabeko atributu mota (byte katea espero zen)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Ezin da baimenik ezarri esteka sinbolikoetan" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Errorea baimenak ezartzean: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Errorea jabea ezartzean: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "esteka sinbolikoak NULL-en desberdina izan behar du" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Errorea esteka sinbolikoa ezartzean: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Errorea esteka sinbolikoa ezartzean: fitxategia ez da esteka sinboliko bat" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "%d nanosegundo gehigarriak negatiboak dira %lld UNIX denbora-zigiluetarako" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "%d nanosegundo gehigarriak segundo 1 dira %lld UNIX denbora-zigiluetarako" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "%lld UNIX denbora-zigilua ez da sartzen 64 bit-etan" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "%lld UNIX denbora-zigilua Windowsen onartutako barrutitik kanpo dago" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "“%s†fitxategi-izena ezin da UTF-16 kodeketara bihurtu" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "“%s†fitxategia ezin da ireki: Windows errorea %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Errorea “%s†fitxategiaren aldaketa edo atzipen denbora ezartzean: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Errorea eraldaketa edo atzipen ordua ezartzean: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux testuinguruak NULL-en desberdina izan behar du" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux ez dago gaituta sistema honetan" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Errorea SELinux testuingurua ezartzean: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s atributuaren ezarpena ez dago onartuta" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Errorea fitxategitik irakurtzean: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Errorea fitxategia ixtean: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Errorea fitxategian bilatzean: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Ezin da lokaleko fitxategi lehenetsiaren monitorizazio mota aurkitu" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Errorea fitxategian idaztean: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Errorea babeskopiaren esteka zaharra kentzean: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Errorea babeskopiaren kopia sortzean: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Errorea aldi baterako fitxategia izenez aldatzean: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "Errorea fitxategia trunkatzean: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Errorea “%s†fitxategia irekitzean: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Helburuko fitxategia direktorio bat da" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Helburuko fitxategia ez da fitxategi arrunta" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Fitxategia kanpotik aldatu da" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Errorea fitxategi zaharra kentzean: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Baliogabeko GSeekType eman da" + +# +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Bilaketa-eskaera baliogabea" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ezin da GMemoryInputStream trunkatu" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Ezin da memoriaren irteeraren korrontea tamainaz aldatu" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Huts egin du memoriaren irteeraren korrontea tamainaz aldatzean" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "Idazketa lantzeko behar den memoria kopurua erabilgarri dagoen helbide-espazioa baino handiagoa da" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Bilaketa eskatu da korrontearen hasieraren aurretik" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Bilaketa eskatu da korrontearen amaieraren ondoren" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "muntaiak ez dauka “unmount†(desmuntatu) inplementatuta" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "muntaiak ez dauka “eject†(egotzi) inplementatuta" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "muntaiak ez dauka “unmount†(desmuntatzea) edo “unmount_with_operation†(desmuntatu eragiketarekin) inplementatuta" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "muntaiak ez dauka “eject†(egotzi) edo “eject_with_operation†(egotzi eragiketarekin) inplementatuta" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "muntaiak ez dauka “remount†(birmuntaketa) inplementatuta" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "muntaiak ez dauka eduki mota sinkronoa asmatzea inplementatuta" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "muntaiak ez dauka eduki mota sinkronoa asmatzea inplementatuta" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "“%s†ostalariak “[“dauka, baina ez “]“" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Sarea atziezina" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Ostalaria atziezina" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ezin izan da sareko monitorea sortu: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Ezin izan da sareko monitorea sortu: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Ezin izan da sarearen egoera eskuratu: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager ez dago abian" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager-en bertsioa zaharregia" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Irteerako korronteak ez dauka idaztea inplementatuta" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "%s(e)ri pasatutako bektoreen batuketa handiegia da" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Iturburuko korrontea jadanik itxi da" + +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Errorea “%s†ebaztean: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s ez dago inplementatuta" + +# +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Baliogabeko domeinua" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "“%sâ€(e)ko baliabidea ez da existitzen" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Huts egin du “%sâ€(e)ko baliabidea deskonprimatzean" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "“%sâ€(e)ko baliabidea ez da direktorio bat" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Sarrerako korronteak ez dauka bilaketa inplementatuta" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Zerrendatu baliabideak dituzten atalak elf fitxategi batean" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "Zerrendatu baliabideak\n" +"ATALA ematen bada, soilik atal honetako baliabideak zerrendatu\n" +"BIDE-IZENA ematen bada, bat datozen baliabideak soilik zerrendatu" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FITXATEGIA [BIDE-IZENA]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "ATALA" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "Zerrendatu baliabideak xehetasunez\n" +"ATALA ematen bada, soilik atal honetako baliabideak zerrendatu\n" +"BIDE-IZENA ematen bada, bat datozen baliabideak soilik zerrendatu\n" +"Xehetasunek atala, tamaina eta konpresioa daukate" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Erauzi baliabidearen fitxategia irteera estandarrean (stdout)" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FITXATEGIA BIDE-IZENA" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "Erabilera:\n" +" gresource [--section ATALA] KOMANDOA [ARGUMENTUAK…]\n" +"\n" +"Komandoak:\n" +" help Erakutsi informazio hau\n" +" sections Zerrendatu baliabidearen atalak\n" +" list Zerrendatu baliabideak\n" +" details Zerrendatu baliabideak xehetasunez\n" +" extract Erauzi baliabide bat\n" +"\n" +"Erabili “gresource help KOMANDOA“ laguntza xehea eskuratzeko.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "Erabilera:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " ATALA elf atalaren izena (aukerakoa)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMANDOA (aukerako) komandoa deskribatzeko\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FITXATEGIA Elf fitxategia (bitarra edo partekatutako liburutegia)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr " FITXATEGIA Elf fitxategia (bitarra edo partekatutako liburutegia)\n" +" edo konpilatutako baliabidearen fitxategi bat\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[BIDE-IZENA]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " BIDE-IZENA (aukerakoa) baliabidearen bide-izena (partziala izan daiteke)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "BIDE-IZENA" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " BIDE-IZENA Baliabidearen bide-izena\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Ez dago “%s†bezalako eskemarik\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "“%s†eskema ezin da lekuz aldatu (bide-izena ez da zehaztu behar)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "“%s†eskema lekuz alda daiteke (bide-izena zehaztu behar da)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Bide-izen hutsa eman da.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Bide-izena barra batekin (/) hasi behar da\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Bide-izena barra batekin (/) amaitu behar da\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Bide-izenak ezin ditu bi barra jarraian eduki (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Emandako balioa baliozko barrutitik kanpo dago\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Gakoa ez da idazgarria\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Zerrendatu instalatutako eskemak (lekuz ezin direnak aldatu)" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Zerrendatu instalatutako eskemak (lekuz alda daitezkeenak)" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Zerrendatu ESKEMAko gakoak" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "ESKEMA[:bide-izena]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Zerrendatu ESKEMAren haurrak" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "Zerrendatu gako eta balioak, errekurtsiboki\n" +"Ez bada ESKEMArik ematen, zerrendatu gako guztiak\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESKEMA[:BIDE-IZENA]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Lortu GAKOAren balioa" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESKEMA[:BIDE-IZENA] GAKOA" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Kontsultatu GAKOAren baliozko balioen barrutiari buruz" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Kontsultatu GAKOAren azalpena" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Ezarri GAKOAren balioa BALIOArekin" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESKEMA[:BIDE-IZENA] GAKOA BALIOA" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Berrezarri GAKOA bere balio lehenetsira" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Berrezarri ESKEMAko gako guztiak beraien balio lehenetsietara" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Begiratu GAKOA idazgarria den edo ez" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "Monitorizatu GAKOAren aldaketak.\n" +"Ez bada GAKOA zehazten, ESKEMAko gako guztiak monitorizatuko ditu.\n" +"Erabili ^C monitorizazioa gelditzeko.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESKEMA[:BIDE-IZENA] GAKOA" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "Erabilera:\n" +" gsettings --version\n" +" gsettings [--schemadir ESKEMA-DIREKTORIOA] KOMANDOA [ARGUMENTUAK…]\n" +"\n" +"Komandoak:\n" +" help Erakutsi informazio hau\n" +" list-schemas Zerrendatu instalatutako eskemak\n" +" list-relocatable-schemas Zerrendatu lekuz alda daitezkeen eskemak\n" +" list-keys Zerrendatu eskema bateko gakoak\n" +" list-children Zerrendatu eskema baten haurrak\n" +" list-recursively Zerrendatu gako eta balioak, \n" +" errekurtsiboki\n" +" range Kontsultatu gako baten barrutia\n" +" describe Kontsultatu gakoaren azalpena\n" +" get Lortu gako baten balioa\n" +" set Ezarri gako baten balioa\n" +" reset Berrezarri gako baten balioa\n" +" reset-recursively Berrezarri emandako eskema baten\n" +" balio guztiak\n" +" writable Begiratu gako bat idazgarria al den\n" +" monitor Behatu aldaketak\n" +"\n" +"Erabili “gsettings help KOMANDOA“ laguntza xehea lortzeko.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "Erabilera:\n" +" gsettings [--schemadir ESKEMA-DIREKTORIOA] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " ESKEMA-DIREKTORIOA Eskema gehigarriak bilatzeko direkotrioa\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr " ESKEMA Eskemaren izena\n" +" BIDE-IZENA Bide-izena, lekuz alda daitezkeen eskementzako\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " GAKOA Eskema barruko (aukerako) gakoa\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " GAKOA Eskema barruko gakoa\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " BALIOA Ezarriko den balioa\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Ezin izan dira eskemarik '%s'(e)ndik kargatu : %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Ez dago eskemarik instalatuta\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Eskemaren izen hutsa eman da\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Ez dago “%s†bezalako gakorik\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Baliogabeko socket-a, hasieratu gabe dago" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Baliogabeko socket-a, hasieratzeak huts egin du: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Socket-a jadanik itxita dago" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "S/Iko socketaren denbora-muga gaindituta" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "GSocket sortzen fd-tik: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ezin da socket-a sortu: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Familia ezezaguna zehaztu da" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Protokolo ezezaguna zehaztu da" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Ezin da datagramen eragiketarik erabili datagramak ez diren socket-etan." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "Ezin da datagramen eragiketarik erabili socket-etan iraungitze-denborarik ezarri gabe." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "ezin izan da lokaleko helbidea lortu: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "ezin izan da urruneko helbidea lortu: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "ezin izan da entzun: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Errorea %s helbidearekin lotzean: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Errorea multidifusioko taldean elkartzean: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Errorea multidifusioko taldea uztean: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Iturburu zehatzeko multidifusiorik ez da onartzen" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Onartzen ez den socket familia" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "Iturburu zehatzekoa ez IPv4 helbidea" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Interfaze-izena luzeegia da" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interfazea ez da aurkitu: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "IPv4 iturburu zehatzeko multidifusiorik ez da onartzen" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "IPv6 iturburu zehatzeko multidifusiorik ez da onartzen" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Errorea konexioa onartzean: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Konexioa lantzen" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Ezin da falta diren erroreak lortu: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Errorea datuak jasotzean: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Errorea datuak bidaltzean: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ezin da socket-a itzali: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Errorea socket-a ixtean: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Socket-aren baldintzen zai: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Ezin izan da mezua bidali: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Mezu-bektoreak luzeegiak dira" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Errorea mezua bidaltzean: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage ez da Windows sisteman onartzen" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Errorea mezua jasotzean: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Ezin da socket-aren kredentzialik irakurri: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials ez dago S.E. honetan inplementatuta" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ezin izan da %s proxy zerbitzariarekin konektatu: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ezin izan da %s(r)ekin konektatu: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Ezin izan da konektatu: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "TCP motakoak ez diren konexioen gainean proxya egitea ez dago onartuta." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proxy-aren “%s†protokoloa ez dago onartuta." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Entzulea jadanik itxita dago" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Gehitutako socket-a itxi da" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4-ek ez du “%s†IPv6 helbidea onartzen" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Erabiltzaile-izena luzeegia da SOCKSv4 protokoloarentzako" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "“%s†ostalari-izena luzeegia da SOCKSv4 protokoloarentzako" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Zerbitzaria ez da SOCKSv4 proxy zerbitzari bat." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 zerbitzariaren bidezko konexioa ukatu da" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Zerbitzaria ez da SOCKSv5 proxy zerbitzari bat." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 proxyak autentifikazioa eskatzen du." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5-ek autentifikatzeko metodo bat eskatzen du (Glib-ek onartzen ez duena)." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Erabiltzaile-izena edo pasahitza luzeegia da SOCKSv5 protokoloarentzako." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 autentifikazioak huts egin du erabiltzaile-izena edo pasahitza okerra delako." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "“%s†ostalari-izena luzeegia da SOCKSv5 protokoloarentzako" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 proxy zerbitzariak helbide mota ezezagunak erabiltzen ditu." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "SOCKSv5 proxyaren zerbitzariaren barneko errorea." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Arauen multzoak ez du SOCKSv5 konexioa baimentzen." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Ostalaria atziezina SOCKSv5 zerbitzariaren bidez." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Sarea atziezina SOCKSv5 proxyaren bidez." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Konexioa ukatuta SOCKSv5 proxyaren bidez." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 proxyak ez du “connect†komandoa onartzen." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 proxyak ez du emandako helbide mota onartzen." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "SOCKSv5 proxyaren errore ezezaguna." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Ezin izan da kanalizazioa sortu prozesu haurrarekin komunikatzeko (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Plataforma honetan ez dira kanalizazioak onartzen" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Ezin da GThemedIcon kodeketaren %d bertsioa kudeatu" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Ez da baliozko helbiderik aurkitu" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Errorea “%s†alderantziz ebaztean: %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Ez dago eskatutako motaren DNS erregistrorik “%sâ€(r)entzako" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Ezin da “%s†ebatzi aldi batean" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Errorea “%s†ebaztean" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Ez da PEMekin kodetutako ziurtagirik aurkitu" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ezin da PEMekin kodetutako gako pribatua deszifratu" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Ezin izan da PEMekin kodetutako gako pribatua analizatu" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Ez da PEMekin kodetutako ziurtagirik aurkitu" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ezin izan da PEMekin kodetutako ziurtagiririk analizatu" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Uneko TLS motorrak ez du PKCS #12 onartzen" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "GTlsBackend honek ez du onartzen PKCS #11 ziurtagiriak sortzeak" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "Hau azken aukera da pasahitza ongi sartzeko, zure sarbidetza blokeatu aurretik." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "Sartu diren hainbat pasahitz ez dira zuzenak, eta zure sarbidetza blokeatu egingo da hutsegite gehiagoren ondoren." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Sartutako pasahitza okerrekoa da." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "FD bidaltzea ez dago onartuta" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Kontroleko mezu 1 espero zen, %d lortu da" +msgstr[1] "Kontroleko mezu 1 espero zen, %d lortu da" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Ustekabeko datu-laguntzaile mota" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "fd bat espero zen, baina %d lortu da\n" +msgstr[1] "fd bat espero zen, baina %d lortu da\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Baliogabeko fd jasota" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "FD jasotzea ez dago onartuta" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Errorea kredentzialak bidaltzean: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Errorea SO_PASSCRED gaituta dagoen begiratzean socket-arentzako: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Errorea SO_PASSCRED gaitzean: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "Harrerako kredentzialentzako byte bakar bat irakurtzea espero zen, baina zero byte irakurri dira." + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ez zen kontroleko mezurik espero, baina %d lortu dira" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Errorea SO_PASSCRED desgaitzean: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Errorea fitxategiaren deskriptoretik irakurtzean: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Errorea fitxategiaren deskriptorea ixtean: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Fitxategi-sistemaren erroa" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Errorea fitxategiaren deskriptorean idaztean: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "UNIX-eko domeinuen socket helbide abstraktuak ez daude sistema honetan onartuta" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "bolumenak ez dauka “egotzi†inplementatuta" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "bolumenak ez dauka “egotzi†edo “egotzi eragiketarekin†inplementatuta" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Errorea heldulekutik irakurtzean: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Errorea heldulekua ixtean: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Errorea heldulekuan idaztean: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Ez dago nahikoa memoriarik" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Barneko errorea: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Sarrera gehiago behar dira" + +# +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Konprimatutako datu baliogabeak" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Helbidea entzuteko" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ez ikusi egin GTestDBus-ekin bateragarria izateko" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Erakutsi helbidea" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Erakutsi helbidea shell moduan" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Exekutatu dbus zerbitzua" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Okerreko argumentuak\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "“%2$s†elementuaren ustekabeko “%1$s†atributua" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "“%2$s†elementuaren “%1$s†atributua ez da aurkitu" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Ustekabeko “%s†etiketa, “%s†espero zen" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "“%2$s†barruan ustekabeko “%1$s†etiketa" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Baliogabeko ‘%s’ data/ordua laster-marken fitxategian" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Ezin izan da baliozko laster-marken fitxategia aurkitu datuen direktorioan" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "“%s†URIaren laster-marka badago lehendik ere" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Ez da “%s†URIaren laster-markarik aurkitu" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Ez dago “%s†URIaren laster-markan MIME motarik definituta" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "“%s†URIaren laster-markan ez dago bandera pribaturik definituta" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "“%s†URIaren laster-markan ez dago talderik ezarrita" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "“%s†izeneko aplikaziorik ez du erregistratu laster-markarik '%s'(e)n" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Huts egin du “%s†exekuzioko lerroa “%s†URIarekin hedatzean" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Adierazi ezin den karakterea bihurketa-sarreran" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Karaktere-sekuentzia partziala sarreraren amaieran" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Ezin da “%s†atzerapena “%s†kode-multzo bihurtu" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "NUL byte baliogabea bihurketa-sarreran" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "NUL byte kapsulatua bihurketa-sarreran" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "“%s†URIa ez da “fitxategi“-eskema erabiltzen duen URI absolutua" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Baliteke “%s†URI fitxategi lokalak “#“ ez edukitzea" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "“%s†URI baliogabea da" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "“%s†URIaren ostalari-izena baliogabea da" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "“%s†URIak ihes-karaktere baliogabeak ditu" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "“%s†bide-izena ez da bide-izen absolutua" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%y-%m-%d %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%y/%m/%d" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Urtarrila" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Otsaila" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Martxoa" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Apirila" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Maiatza" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Ekaina" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Uztaila" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Abuztua" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Iraila" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Urria" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Azaroa" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Abendua" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Urt." + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Ots." + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar." + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr." + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Maiatza" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Eka." + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Uzt." + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Abu." + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Ira." + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Urr." + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Aza." + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Abe." + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Astelehena" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Asteartea" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Asteazkena" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Osteguna" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Ostirala" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Larunbata" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Igandea" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Al." + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Ar." + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Az." + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Og." + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Or." + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Lr." + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Ig." + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Urtarrila" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Otsaila" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Martxoa" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "Apirila" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Maiatza" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Ekaina" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Uztaila" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "Abuztua" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Iraila" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Urria" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "Azaroa" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Abendua" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Urt." + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Ots." + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar." + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr." + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Maiatza" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Eka." + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Uzt." + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Abu." + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Ira." + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Urr." + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Aza." + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Abe." + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Errorea “%s†direktorioa irekitzean: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ezin izan da byte %lu esleitu “%s†fitxategia irakurtzeko" +msgstr[1] "Ezin izan dira %lu byte esleitu “%s†fitxategia irakurtzeko" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Errorea “%s†fitxategia irakurtzean: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "“%s†fitxategia handiegia da" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Ezin izan da “%s†fitxategitik irakurri: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Ezin izan da “%s†fitxategia ireki: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Ezin izan dira “%s†fitxategiko atributuak lortu, fstat() funtzioak huts egin du: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Ezin izan da “%s†fitxategia ireki, fdopen() funtzioak huts egin du: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Ezin izan da “%s†fitxategia “%s†gisa berrizendatu, g_rename() funtzioak huts egin du: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Huts egin du “%s†fitxategian idaztean: fwrite() funtzioak huts egin du: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Huts egin du “%s†fitxategia idaztean: fsync() funtzioak huts egin du: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Ezin izan da “%s†fitxategia sortu: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "“%s†fitxategia ezin izan da kendu, g_unlik() funtzioak huts egin du: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "“%s†txantiloia baliogabea da, ez luke “%s†eduki behar" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "“%s†txantiloiak ez dauka: XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Ezin izan da “%s†esteka sinbolikorik irakurri: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Ezin izan da “%sâ€(e)tik “%sâ€(e)rako bihurtzailea ireki: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Ezin dira datu gordinak irakurri “g_io_channel_read_line_string“-en" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Irakurketa-bufferrean geratu diren bihurtu gabeko datuak" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanala karaktere partzial batean bukatzen da" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Ezin dira datu gordinak irakurri “g_io_channel_read_to_end“-etik" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Ezin izan da baliozko gakoa datuen direktorioan aurkitu" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Ez da fitxategi arrunta" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "Gako-fitxategiak “%s†lerroa du, gako-balioa bikotea, taldea edo iruzkinik ez daukalarik" + +# +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Taldearen izen baliogabea: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Gako-fitxategiak ez da talde batekin hasten" + +# +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Gakoaren izen baliogabea: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Gako-fitxategiak onartzen ez den “%s†kodeketa du" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Gako-fitxategiak ez dauka “%s†taldea" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Gako-fitxategiak ez dauka “%s†gakoa (“%s†taldean)" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Gako-fitxategiak “%s†gakoa dauka (%s balioduna) baina ez da UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "Gako-fitxategiak “%s†gakoa dauka, baina ezin den interpretatu balio bat dauka." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "Gako-fitxategiak “%s†gakoa dauka ('%s taldean), baina dagokion balioa ezin da interpretatu." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "“%2$s†taldeko “%1$s†gakoaren balioa “%3$s†da, “%4$s†izan ordez." + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Gako-fitxategiak ihes-karakterea dauka lerro amaieran" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Gako-fitxategiak “%s†ihes-sekuentzia baliogabea dauka" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "“%s†balioa ezin da zenbaki gisa interpretatu" + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "“%s†osoko balioa barrutitik kanpo" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "“%s†balioa ezin da zenbaki mugikor gisa interpretatu." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "“%s†balioa ezin da boolear gisa interpretatu" + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Huts egin du “%s%s%s%s†fitxategiaren atributuak lortzean. fstat() funtzioak huts egin du: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Huts egin %s%s%s%s mapatzean. mmap() funtzioak huts egin du: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Ezin izan da “%s†fitxategia ireki, open() funtzioak huts egin du: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Errorea %d lerroko %d karakterean: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "UTF-8 gisa kodetutako testu baliogabea izenean - “%s†ez da baliozkoa" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†ez da baliozko izena" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†ez da baliozko izena: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Errorea %d lerroan: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "Ezin izan da “%-.*s†analizatu, digitu bat izan behar zuen karaktere-erreferentzia baten barruan (ê adibidez); agian digitua handiegia da" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "Karaktere-erreferentzia ez da puntu eta komaz bukatzen; ziurrenik & ikurra erabiliko zenuen entitatea hasteko asmorik gabe. Izendatu & karakterea & gisa" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "“%-.*s†karaktere-erreferentziak ez du baimendutako karaktere bat kodetzen" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "“&;†entitatea hutsik dago; baliozko entitateak hauek dira: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "“%-.*s†entitate-izena ezezaguna da" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "Entitatea ez da puntu eta komaz bukatzen; normalean & ikurra erabiltzen da entitatea hasteko asmorik gabe; izendatu & karakterea & gisa" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumentuak elementu batez hasi behar du (adibidez, )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "“%s†ez da baliozko karakterea '<' karakterearen atzetik; baliteke elementu baten izena ez hastea" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "“%s†karaktere bitxia, '>' karakterea espero zen “%s†elementuaren etiketa hutsa amaitzeko" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Atributu gehiegi “%s†elementuan" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "“%s†karaktere bitxia, '=' espero zen “%s†atributuaren ondoren “%s†elementuan" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "“%s†atributuaren ondoren karaktere bitxia, “>“ edo “/“ karakterea espero zen “%s†atributuaren ondoren elementuaren hasiera-etiketa bukatzeko, edo bestela atributu bat. Agian karaktere baliogabea erabili duzu atributu-izen batean" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "“%s†karaktere bitxia, komatxo irekia espero zen berdin ikurraren ondoren “%s†atributuari balioa ematean “%s†elementuan" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "“%s†ez da baliozko karakterea da “%s†itxiera-elementuaren izenaren atzetik; baimendutako karakterea “>“ da" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "“%s†elementua itxi egin da, unean ez dago elementurik irekita" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "“%s†elementua itxi egin da, baina unean “%s†elementua dago irekita" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumentua hutsik dago edo zuriuneak bakarrik ditu" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokumentua ustekabean itxi da “<“ angelu-parentesi ireki baten ondoren" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "Dokumentua ustekabean amaitu da oraindik irekita zeuden elementuekin. “%s†irekitako azken elementua da" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "Dokumentua ustekabean amaitu da, angelu-parentesi itxia ikustea espero zen <%s/> etiketa amaitzen" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumentua ustekabean amaitu da elementu-izen baten barruan" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumentua ustekabean amaitu da atributu-izen baten barruan" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumentua ustekabean amaitu da elementua irekitzeko etiketa baten barruan." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "Dokumentua ustekabean amaitu da atributu-izen baten ondorengo berdin ikurraren atzetik; ez dago atributu-baliorik" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumentua ustekabean amaitu da atributu-balio baten barruan" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokumentua ustekabean amaitu da “%s†elementuaren itxiera-etiketaren barruan" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "Dokumentua ustekabean amaitu da ireki gabeko elementu baten itxiera-etiketaren barruan" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokumentua ustekabean amaitu da iruzkin baten barruan edo prozesatzen ari zen instrukzio baten barruan" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[AUKERA…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Laguntzako aukerak:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Erakutsi laguntzako aukerak" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Erakutsi laguntzako aukera guztiak" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Aplikazio-aukerak:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Aukerak:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Ezin da “%2$s“(r)en “%1$s†osoko balioa analizatu" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "%2$s(r)en “%1$s†osoko balioa barrutitik kanpo" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Ezin da “%2$s“(r)en “%1$s†balio bikoitza analizatu" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "%2$s(r)en “%1$s†balio bikoitza barrutitik kanpo" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Errorea %s aukera analizatzean" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "%s(e)ko argumentua falta da" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "%s aukera ezezaguna" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "hondatutako objektua" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "barneko errorea edo hondatutako objektua" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "Memoriarik ez" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "atzera-jotzearen mugara gainditua" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "ereduak zenbait elementu ditu bat etortze partzialetan onartzen ez direnak" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "barneko errorea" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "aurreko erreferentziak baldintza gisa ez daude onartuta bat etortze partzialetan" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "errekurtsioaren muga gainditua" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "lerro-jauzien banderen baliogabeko konbinazioa" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "okerreko desplazamendua" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 laburra" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "errekurtsioaren begizta" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "errore ezezaguna" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ ereduaren amaieran" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c ereduaren amaieran" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "karaktere ezezagunak jarraitzen dio \\ karaktereari" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "zenbakiak barrutitik kanpo {} kuantifikatzailean" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "zenbaki handiegiak {} kuantifikatzaileak" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "karaktere-klasearen amaierako ] falta da" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "karaktere-klasean baliogabeko ihes sekuentzia" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "karaktere-klaseko barrutia barrutitik kanpo" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "ezer ez errepikatzeko" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "ustekabeko begizta" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "karaktere ezezaguna (? edo (?- karaktereen atzetik" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX izeneko klaseak soilik onartzen dira klase baten barruan" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "amaierako ) falta da" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "existitzen ez den azpieredu baten erreferentzia" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "iruzkinaren ondoren ) falta da" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "adierazpen erregularra luzeegia da" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "huts egin du memoria lortzean" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") dago irekierako ( gabe" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "kodea gainezkatua" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "karaktere ezezaguna (?< karaktereen atzetik" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "'lookbehind' baieztapenak ez du luzera finkorik" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "gaizki osatutako zenbakia edo izena (?(-ren atzetik" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "baldintza taldeak bi adar baino gehiago ditu" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "baieztapena espero zen (?)-ren atzetik" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R edo (?[+-] digituak )-rekin jarraitu behar dira" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "POSIX klasearen izen ezezaguna" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "Tartekatutako POSIX elementuak ez daude onartuta" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{…} sekuentziako karaktere-balioa luzeegia da" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "baliogabeko (?(0) baldintza" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C ez dago baimenduta 'lookbehind' baieztapenean" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "\\L, \\l, \\N{izena}, \\U, eta \\u ihes-karaktereak ez daude onartuta" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "dei errekurtsiboa amaierarik gabeko begiztan sar daiteke" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "karaktere ezezaguna (?P karaktereen atzetik" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "amaierako karakterea falta da azpiereduko izenean" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "bi azpiereduk izen berdina dute" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "gaizki osatutako \\P edo \\p sekuentzia" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "propietate-izen ezezaguna \\P edo \\p atzetik" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "azpiereduaren izena luzeegia (32 karaktere gehienez)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "izendun azpieredu gehiegi (10.000 gehienez)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "balio zortzitarra \\377 baino handiagoa" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "konpilazioaren laneko area gainezkatua" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "ez da aurrez egiaztatutako erreferentziatutako azpieredua aurkitu" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE taldeak adar bat baino gehiago ditu" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "NEWLINE aukera inkoherentea" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "\\g ez da parentesi, kortxete edo aipu motako izena edo zenbaki, edo zenbaki soil batekin jarraitzen" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "zenbatutako erreferentzia bat ezin du zero izan" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "argumentu bat ez dago onartuta (*ACCEPT), (*FAIL), edo (*COMMIT)-entzako" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ez da ezagutzen" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "zenbakia handiegia da" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "azpiereduaren izena falta da (?& ondoren" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "digitua espero zen (?+ ondoren" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] datuen baliogabeko karaktere bat da JavaScript-en bateragarritasun moduan" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "zenbaki berdinaren azpiereduen izen desberdinak ez daude onartuta" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) argumentu bat eduki behar du" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c ondoren ASCII karaktere bat behar da" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k ondoren ez dago parentesi, kortxete edo aipatutako izen bat" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N ez dago klase batean onartuta" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "aurreranzko erreferentzia gehiegi" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "izena luzeegia da (*MARK), (*PRUNE), (*SKIP), edo (*THEN)-en" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u sekuentziako karaktere-balioa luzeegia da" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Errorea %s adierazpen erregularra bilatzean: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE liburutegia UTF8 euskarri gabe konpilatua" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE liburutegia UTF8 propietateen euskarri gabe konpilatua" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE liburutegia aukera bateragarririk gabe konpilatua" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Errorea %s adierazpen erregularra optimizatzean: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Errorea %s adierazpen erregularra %d karakterean konpilatzean: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "digitu hamaseitarra edo “}“ espero zen" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "digitu hamaseitarra espero zen" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "“<“ falta da erreferentzia sinbolikoan" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "amaitu gabeko erreferentzia sinbolikoa" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "zero luzerako erreferentzia sinbolikoa" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "digitua espero zen" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "erreferentzia sinboliko ilegala" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "“\\“ katearen amaieran" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "ihes-sekuentzi ezezaguna" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Errorea ordezko “%s†testua analizatzean %lu karakterean: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Komatxo arteko testua ez da komatxoekin hasten" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Bat ez datozen komatxoak daude komando-lerroan edo shell-ak aipatutako beste testu batean" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Testua “\\“ karakterearen atzetik amaitu da (testua “%s†zen)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "Testua %c(r)en komatxoak aurkitu baino lehen amaitu da (testua “%s†zen)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Testua hutsik dago (edo zuriuneak bakarrik ditu)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Ezin izan da daturik irakurri prozesu umetik (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Ustekabeko errorea datuak prozesu umetik irakurtzean (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ustekabeko errorea waitpid()-en (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1431 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Prozesu haurra amaitu da %ld kodearekin" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Prozesu haurra %ld seinaleak hilda" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Prozesu haurra %ld seinaleak geldituta" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Prozesu haurra ustekabean amaituta" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Ezin izan da kanalizazio umetik irakurri (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Ezin izan da “%s†prozesu haurra abiarazi (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Ezin da sardetu (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Ezin izan da “%s†direktoriora aldatu (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Ezin izan da “%s†prozesu haurra exekutatu (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Huts egin du fitxategia irekitzeak fitxategi-deskribatzailea birmapatzeko (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Huts egin du prozesu umerako fitxategi-deskribatzailea bikoizteak (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Ezin izan da prozesu haurra sardetu (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Huts egin du prozesu umerako fitxategi-deskribatzailea ixteak (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Errore ezezaguna “%s†prozesu haurra exekutatzean" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Ezin izan da nahikoa datu irakurri pid kanalizazio umetik (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Ezin izan da daturik irakurri prozesu umetik" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Ezin izan da prozesu haurra exekutatu (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Huts egin du dup() komandoak prozesu haurrean (%s)" + +# +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Programaren izen baliogabea: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:800 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Kate baliogabea %d(e)ko bektorearen argumentuan: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:816 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Kate baliogabea ingurunean: %s" + +#: glib/gspawn-win32.c:796 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Laneko direktorio baliogabea: %s" + +# +#: glib/gspawn-win32.c:861 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Ezin izan da laguntza-programa exekutatu (%s)" + +#: glib/gspawn-win32.c:1089 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "Ustekabeko errorea gertatu da 'g_io_channel_win32_poll()'-en prozesu umetik datuak irakurtzean" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Kate hutsa ez da zenbaki bat" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†ez da zeinudun zenbaki bat" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "“%s†zenbakia barrutitik kanpo [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†ez da zeinurik gabeko zenbaki bat" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Baliogabeko %-kodeketa URIan" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Legez kanpoko karakterea URIan" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "UTF-8 ez diren karaktereak URIan" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Baliogabeko IPv6 helbidea ‘%.*s’ URIan" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Legez kanpoko IP helbide kodea ‘%.*s’ URIan" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Internazionalizatutako ostalari-izen baliogabea (‘%.*s’) URIan" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Ezin izan da ‘%.*s’ ataka analizatu URIan" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "URIko ‘%.*s’ ataka barrutitik kanpo dago" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "‘%s’ URIa ez da URI absolutua" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "‘%s’ URIak ez du ostalari-osagairik" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URIa ez da absolutua eta ez da oinarrizko URIrik eman" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "‘=’ eta parametro-balioa falta dira" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Huts egin du memoria esleitzeak" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Karakterea UTF-8 barrutitik kanpo" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Sekuentzia baliogabea bihurketa-sarreran" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Karakterea UTF-16 barrutitik kanpo" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "byte %u" +msgstr[1] "%u byte" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "bit %u" +msgstr[1] "%u bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "byte %s" +msgstr[1] "%s byte" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "bit %s" +msgstr[1] "%s byte" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Ezin da /var/lib/dbus/machine-id edo /etc/machine-id kargatu: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Errore ezezaguna konexioan" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Errorea “%s†helbidean — familiaren atributua gaizki osatuta dago" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s hemen muntatuta: %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; gainidazketari ezikusi egiten gako honentzako.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " eta --strict zehaztu da; irtetzen.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Gainidazketari ezikusi egiten gako honentzako.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "ezer ez da egiten ari.\n" diff --git a/po/fa.po b/po/fa.po new file mode 100644 index 0000000..5ff5e42 --- /dev/null +++ b/po/fa.po @@ -0,0 +1,6295 @@ +# Translation of glib to Persian. +# Copyright (C) 2002, 2004, 2005, 2006 Sharif FarsiWeb, Inc. +# Roozbeh Pournader , 2002, 2004, 2006. +# Hamed Malek , 2005. +# Meelad Zakaria , 2006 +# Arash Mousavi , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: glib HEAD\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2021-07-19 15:52+0000\n" +"PO-Revision-Date: 2021-09-27 18:46+0330\n" +"Last-Translator: eshagh \n" +"Language-Team: Persian <>\n" +"Language: fa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Poedit 3.0\n" + +#: gio/gapplication.c:500 +#, fuzzy +#| msgid "Application Options:" +msgid "GApplication options" +msgstr "گزینه‌های برنامه:" + +#: gio/gapplication.c:500 +#, fuzzy +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "گزینه‌های برنامه:" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 gio/gresource-tool.c:494 +#: gio/gsettings-tool.c:572 +msgid "Print help" +msgstr "چاپ راهنما" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "چاپ نگارش" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:578 +msgid "Print version information and exit" +msgstr "" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "سیاههٔ برنامه‌ها" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "راه‌اندازی یک برنامه" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMMAND" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:738 gio/glib-compile-resources.c:744 +#: gio/glib-compile-resources.c:772 gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FILE" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACTION" + +#: gio/gapplication-tool.c:75 +#, fuzzy +#| msgid "Destination name to monitor" +msgid "The action name to invoke" +msgstr "نام مقصد جهت پایش" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:664 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"ÙØ±Ù…ان ناشناس %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "کارکرد:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 gio/gsettings-tool.c:699 +msgid "Arguments:\n" +msgstr "متغییرها:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "دستورات:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:268 +#, fuzzy, c-format +#| msgid "Could not connect to %s: " +msgid "unable to connect to D-Bus: %s\n" +msgstr "نمی‌توان به %s متصل شد:" + +#: gio/gapplication-tool.c:288 +#, fuzzy, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "خطا در هنگام ارسال پیام: %s" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" + +#: gio/gapplication-tool.c:346 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "خطا در تجزیه پارامتر %Id: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "" + +#: gio/gapplication-tool.c:423 +#, fuzzy, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "نمی‌توان پایانه‌ی لازم برای این برنامه را پیدا کرد" + +#: gio/gapplication-tool.c:468 +#, fuzzy, c-format +#| msgid "" +#| "Unknown command %s\n" +#| "\n" +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"ÙØ±Ù…ان ناشناس %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 gio/ginputstream.c:179 +#: gio/ginputstream.c:379 gio/ginputstream.c:648 gio/ginputstream.c:1050 gio/goutputstream.c:223 +#: gio/goutputstream.c:1049 gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "مقدار شمارش بسیار بزرگی به %s ارسال شده است" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 gio/gdataoutputstream.c:562 +#, fuzzy +#| msgid "Splice not supported" +msgid "Seek not supported on base stream" +msgstr "اتصال پشتیبانی نمی‌شود" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "جریان از قبل بسته شده است" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +#, fuzzy +#| msgid "Trash not supported" +msgid "Truncate not supported on base stream" +msgstr "زباله پشتیبانی نمی‌شود" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1872 gio/gdbusprivate.c:1416 gio/gsimpleasyncresult.c:871 +#: gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "عملیات لغو شده" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "شیء نامعتبر، مقدار دهی اولیه نشد" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "دنبالهٔ بایتی نامعتبر در ورودی تبدیل" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "ÙØ¶Ø§ کاÙÛŒ در مقصد وجود ندارد" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 gio/gdatainputstream.c:1266 glib/gconvert.c:449 +#: glib/gconvert.c:879 glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 glib/gutf8.c:875 +#: glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "دنبالهٔ بایتی نامعتبر در ورودی تبدیل" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 glib/giochannel.c:1580 +#: glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "خطا در حین تبدیل: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1143 +msgid "Cancellable initialization not supported" +msgstr "مقداردهی‌های اولیه‌ی قابل لغو پشتیبانی نمی‌شود" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, fuzzy, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "تبدیل از مجموعه‌نویسهٔ «%s» به «%s» پشتیبانی نمی‌شود" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "نمی‌توان مبدل «%s» به «%s» را باز کرد" + +#: gio/gcontenttype.c:454 +#, c-format +msgid "%s type" +msgstr "نوع %s" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "نوع نامعلوم" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "نوع پرونده %s" + +#: gio/gcredentials.c:323 +msgid "GCredentials contains invalid data" +msgstr "" + +#: gio/gcredentials.c:383 gio/gcredentials.c:667 +msgid "GCredentials is not implemented on this OS" +msgstr "بر روی این سیستم عامل GCredentials توسعه داده نشده است" + +#: gio/gcredentials.c:538 gio/gcredentials.c:556 +msgid "There is no GCredentials support for your platform" +msgstr "پشتیبانی از GCredentials در Ù¾Ù„ØªÙØ±Ù… شما وجود ندارد" + +#: gio/gcredentials.c:607 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "GCredentials does not contain a process ID on this OS" +msgstr "بر روی این سیستم عامل GCredentials توسعه داده نشده است" + +#: gio/gcredentials.c:661 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "بر روی این سیستم عامل GCredentials توسعه داده نشده است" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:172 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:181 +#, c-format +msgid "Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract keys)" +msgstr "" + +#: gio/gdbusaddress.c:248 gio/gdbusaddress.c:259 gio/gdbusaddress.c:274 gio/gdbusaddress.c:337 +#: gio/gdbusaddress.c:348 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "" + +#: gio/gdbusaddress.c:418 gio/gdbusaddress.c:682 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:462 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "" + +#: gio/gdbusaddress.c:471 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:492 +#, c-format +msgid "Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal sign" +msgstr "" + +#: gio/gdbusaddress.c:503 +#, c-format +msgid "Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" + +#: gio/gdbusaddress.c:517 +#, c-format +msgid "Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:589 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys “path†or “abstract†to be set" +msgstr "" + +#: gio/gdbusaddress.c:625 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:639 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:653 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:674 +msgid "Error auto-launching: " +msgstr "خطا در راه‌اندازی خودکار: " + +#: gio/gdbusaddress.c:727 +#, fuzzy, c-format +#| msgid "Error opening nonce file '%s': %s" +msgid "Error opening nonce file “%sâ€: %s" +msgstr "خطا در بازکردن پرونده ÙØ¹Ù„ÛŒ «‎%s»â€: %s" + +#: gio/gdbusaddress.c:746 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s': %s" +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "خطا در خواندن از پروندهٔ ÙØ¹Ù„ÛŒ «‎%s»â€: %s" + +#: gio/gdbusaddress.c:755 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "خطا در خواندن از پروندهٔ ÙØ¹Ù„ÛŒ «‎%sÂ»â€ØŒ انتظار Û±Û¶ بایت Ù…ÛŒâ€ŒØ±ÙØª ولی %Id Ø¯Ø±ÛŒØ§ÙØª شد" + +#: gio/gdbusaddress.c:773 +#, fuzzy, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gdbusaddress.c:988 +msgid "The given address is empty" +msgstr "آدرس داده شده خالی است" + +#: gio/gdbusaddress.c:1101 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "" + +#: gio/gdbusaddress.c:1108 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: gio/gdbusaddress.c:1115 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: gio/gdbusaddress.c:1157 +#, fuzzy, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gdbusaddress.c:1226 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: gio/gdbusaddress.c:1397 gio/gdbusconnection.c:7261 +#, c-format +msgid "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable — unknown value “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:1406 gio/gdbusconnection.c:7270 +msgid "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment variable is not set" +msgstr "" + +#: gio/gdbusaddress.c:1416 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "گزینهٔ نامعلوم %s" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:298 +#, fuzzy, c-format +#| msgid "Error when getting information for directory '%s': %s" +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "خطا در هنگام Ú¯Ø±ÙØªÙ† اطلاعات برای شاخه «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:313 +#, c-format +msgid "Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory “%sâ€: %s" +msgstr "خطا در هنگام ساخت شاخه «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1062 gio/gfile.c:1300 gio/gfile.c:1438 gio/gfile.c:1676 +#: gio/gfile.c:1731 gio/gfile.c:1789 gio/gfile.c:1873 gio/gfile.c:1930 gio/gfile.c:1994 gio/gfile.c:2049 +#: gio/gfile.c:3754 gio/gfile.c:3809 gio/gfile.c:4102 gio/gfile.c:4572 gio/gfile.c:4983 gio/gfile.c:5068 +#: gio/gfile.c:5158 gio/gfile.c:5255 gio/gfile.c:5342 gio/gfile.c:5443 gio/gfile.c:8153 gio/gfile.c:8243 +#: gio/gfile.c:8327 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "عملیات پشتیبانی نمی‌شود" + +#: gio/gdbusauthmechanismsha1.c:402 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for reading: " +msgid "Error opening keyring “%s†for reading: " +msgstr "خطا در هنگام باز کردن دسته‌کلید «%s» برای خواندن: " + +#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761 +#, c-format +msgid "First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775 +#, c-format +msgid "Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:477 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:523 +#, fuzzy, c-format +#| msgid "Error creating lock file '%s': %s" +msgid "Error creating lock file “%sâ€: %s" +msgstr "خطا در هنگام ساخت پرونده Ù‚ÙÙ„ «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:587 +#, fuzzy, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gdbusauthmechanismsha1.c:626 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gdbusauthmechanismsha1.c:637 +#, fuzzy, c-format +#| msgid "Error unlinking lock file '%s': %s" +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "خطا در هنگام شکستن پیوند پرونده‌ی Ù‚ÙÙ„ «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:714 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for writing: " +msgid "Error opening keyring “%s†for writing: " +msgstr "خطا در هنگام باز کردن دسته‌کلید «%s» برای نوشتن: " + +#: gio/gdbusauthmechanismsha1.c:908 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" + +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2417 +msgid "The connection is closed" +msgstr "اتصال بسته شده است" + +#: gio/gdbusconnection.c:1902 +msgid "Timeout was reached" +msgstr "" + +#: gio/gdbusconnection.c:2540 +msgid "Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: gio/gdbusconnection.c:4189 gio/gdbusconnection.c:4536 +#, c-format +msgid "No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" + +#: gio/gdbusconnection.c:4331 +#, fuzzy, c-format +#| msgid "No such property '%s'" +msgid "No such property “%sâ€" +msgstr "همچین خصیصه‌ای وجود ندارد «%s»" + +#: gio/gdbusconnection.c:4343 +#, fuzzy, c-format +#| msgid "Property '%s' is not readable" +msgid "Property “%s†is not readable" +msgstr "خصیصه‌ی «%s» خواندنی نیست" + +#: gio/gdbusconnection.c:4354 +#, fuzzy, c-format +#| msgid "Property '%s' is not writable" +msgid "Property “%s†is not writable" +msgstr "خصیصه‌ی «%s» قابل نوشتن نیست" + +#: gio/gdbusconnection.c:4374 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:4479 gio/gdbusconnection.c:4687 gio/gdbusconnection.c:6689 +#, c-format +msgid "No such interface “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:4905 gio/gdbusconnection.c:7201 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "" + +#: gio/gdbusconnection.c:5003 +#, fuzzy, c-format +#| msgid "No such method '%s'" +msgid "No such method “%sâ€" +msgstr "همچین متدی وجود ندارد «%s»" + +#: gio/gdbusconnection.c:5034 +#, fuzzy, c-format +#| msgid "Type of message, '%s', does not match expected type '%s'" +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "نوع پیام، «%s»، با نوع مورد انتظار مطابقت ندارد «%s»" + +#: gio/gdbusconnection.c:5237 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "یک شیء از قبل برای واسط %s در %s صادر شده است" + +#: gio/gdbusconnection.c:5463 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to retrieve property %s.%s" +msgstr "نمی‌توان سوکت را ساخت: %s" + +#: gio/gdbusconnection.c:5519 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to set property %s.%s" +msgstr "نمی‌توان سوکت را ساخت: %s" + +#: gio/gdbusconnection.c:5698 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:6800 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "" + +#: gio/gdbusconnection.c:6921 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: gio/gdbusconnection.c:7209 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:1266 +msgid "type is INVALID" +msgstr "نوع INVALID است" + +#: gio/gdbusmessage.c:1277 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1288 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1300 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1313 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1321 +msgid "SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local" +msgstr "" + +#: gio/gdbusmessage.c:1329 +msgid "SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local" +msgstr "" + +#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" +msgstr[1] "" + +#: gio/gdbusmessage.c:1391 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" + +#: gio/gdbusmessage.c:1410 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). The valid " +"UTF-8 string up until that point was “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1620 +#, fuzzy, c-format +#| msgid "Error: %s is not a valid object path\n" +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "خطا: %s یک مسیر شیء معتبر نیست\n" + +#: gio/gdbusmessage.c:1642 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "" + +#: gio/gdbusmessage.c:1689 +#, c-format +msgid "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: gio/gdbusmessage.c:1709 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u bytes, but found to be %u " +"bytes in length" +msgstr "" + +#: gio/gdbusmessage.c:1895 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" + +#: gio/gdbusmessage.c:1936 +#, c-format +msgid "Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2121 +#, c-format +msgid "Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value 0x%02x" +msgstr "" + +#: gio/gdbusmessage.c:2134 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2200 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" + +#: gio/gdbusmessage.c:2215 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" + +#: gio/gdbusmessage.c:2247 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: gio/gdbusmessage.c:2257 +msgid "Cannot deserialize message: " +msgstr "" + +#: gio/gdbusmessage.c:2601 +#, c-format +msgid "Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2738 +#, c-format +msgid "Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2746 +msgid "Cannot serialize message: " +msgstr "" + +#: gio/gdbusmessage.c:2799 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" + +#: gio/gdbusmessage.c:2809 +#, c-format +msgid "Message body has type signature “%s†but signature in the header field is “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:2825 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" + +#: gio/gdbusmessage.c:3380 +#, fuzzy, c-format +#| msgid "Error return with body of type '%s'" +msgid "Error return with body of type “%sâ€" +msgstr "خطا در بازگردانی با بدنه‌ای از نوع «%s»" + +#: gio/gdbusmessage.c:3388 +msgid "Error return with empty body" +msgstr "" + +#: gio/gdbusprivate.c:2246 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: gio/gdbusprivate.c:2420 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: gio/gdbusprivate.c:2443 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to get Hardware profile: %s" +msgstr "نمی‌توان پرونده را به زباله‌دان ÙØ±Ø³ØªØ§Ø¯: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2494 +#, fuzzy, c-format +#| msgid "Unable to create trash dir %s: %s" +msgid "Unable to load %s or %s: " +msgstr "نمی‌توان شاخه زباله‌دان %s را ساخت: %s" + +#: gio/gdbusproxy.c:1569 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: gio/gdbusproxy.c:1592 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: gio/gdbusproxy.c:2699 gio/gdbusproxy.c:2834 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, and proxy was constructed " +"with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: gio/gdbusserver.c:767 +#, fuzzy +msgid "Abstract namespace not supported" +msgstr "پیوندهای نمادی پشتیبانی نمی‌شوند" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: gio/gdbusserver.c:942 +#, fuzzy, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 +#: gio/gdbus-tool.c:1236 gio/gdbus-tool.c:1724 +#, c-format +msgid "Error: %s\n" +msgstr "خطا: %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1740 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "خطا در تجزیهٔ گزینهٔ %s" + +#: gio/gdbus-tool.c:250 +#, fuzzy, c-format +#| msgid "Error: %s is not a valid member name\n" +msgid "Error: %s is not a valid name\n" +msgstr "خطا: %s یک نام عضو معتبر نیست\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1060 gio/gdbus-tool.c:1890 +#: gio/gdbus-tool.c:2130 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "خطا: %s یک مسیر شیء معتبر نیست\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" + +#: gio/gdbus-tool.c:531 +#, c-format +msgid "Warning: According to introspection data, method “%s†does not exist on interface “%sâ€\n" +msgstr "" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "" + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:997 gio/gdbus-tool.c:1827 gio/gdbus-tool.c:2059 +#: gio/gdbus-tool.c:2279 +#, c-format +msgid "Error connecting: %s\n" +msgstr "خطا در هنگام اتصال: %s\n" + +#: gio/gdbus-tool.c:703 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "نویسهٔ «%s» داخل نام نهادها مجاز نیست" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1870 +msgid "Error: Object path is not specified\n" +msgstr "خطا: مسیر شیء مشخص نشده است\n" + +#: gio/gdbus-tool.c:765 +#, fuzzy +#| msgid "Error: Method name is not specified\n" +msgid "Error: Signal name is not specified\n" +msgstr "خطا: نام متد مشخص نشده است\n" + +#: gio/gdbus-tool.c:779 +#, fuzzy, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Signal name “%s†is invalid\n" +msgstr "خطا: نام متد «%s» نامعتبر است\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "خطا: %s یم نام واسط معتبر نیست\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "خطا: %s یک نام عضو معتبر نیست\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1172 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "خطا در تجزیه پارامتر %Id: %s\n" + +#: gio/gdbus-tool.c:866 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "خطا در حین تبدیل: %s" + +#: gio/gdbus-tool.c:893 +msgid "Destination name to invoke method on" +msgstr "" + +#: gio/gdbus-tool.c:894 +msgid "Object path to invoke method on" +msgstr "" + +#: gio/gdbus-tool.c:895 +msgid "Method and interface name" +msgstr "نام متد Ùˆ واسط" + +#: gio/gdbus-tool.c:896 +msgid "Timeout in seconds" +msgstr "" + +#: gio/gdbus-tool.c:942 +msgid "Invoke a method on a remote object." +msgstr "" + +#: gio/gdbus-tool.c:1014 gio/gdbus-tool.c:1844 gio/gdbus-tool.c:2084 +msgid "Error: Destination is not specified\n" +msgstr "خطا: مقصد مشخص نشده است\n" + +#: gio/gdbus-tool.c:1025 gio/gdbus-tool.c:1861 gio/gdbus-tool.c:2095 +#, fuzzy, c-format +#| msgid "Error: %s is not a valid member name\n" +msgid "Error: %s is not a valid bus name\n" +msgstr "خطا: %s یک نام عضو معتبر نیست\n" + +#: gio/gdbus-tool.c:1075 +msgid "Error: Method name is not specified\n" +msgstr "خطا: نام متد مشخص نشده است\n" + +#: gio/gdbus-tool.c:1086 +#, fuzzy, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Method name “%s†is invalid\n" +msgstr "خطا: نام متد «%s» نامعتبر است\n" + +#: gio/gdbus-tool.c:1164 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d of type '%s': %s\n" +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "خطا در هنگام تجزیه پارامتر %Id از نوع «%s»: %s\n" + +#: gio/gdbus-tool.c:1190 +#, fuzzy, c-format +msgid "Error adding handle %d: %s\n" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gdbus-tool.c:1686 +msgid "Destination name to introspect" +msgstr "" + +#: gio/gdbus-tool.c:1687 +msgid "Object path to introspect" +msgstr "" + +#: gio/gdbus-tool.c:1688 +msgid "Print XML" +msgstr "چاپ XML" + +#: gio/gdbus-tool.c:1689 +msgid "Introspect children" +msgstr "" + +#: gio/gdbus-tool.c:1690 +msgid "Only print properties" +msgstr "تنها ترجیحات را چاپ Ú©Ù†" + +#: gio/gdbus-tool.c:1779 +msgid "Introspect a remote object." +msgstr "" + +#: gio/gdbus-tool.c:1985 +msgid "Destination name to monitor" +msgstr "نام مقصد جهت پایش" + +#: gio/gdbus-tool.c:1986 +msgid "Object path to monitor" +msgstr "مسیر شیء جهت پایش" + +#: gio/gdbus-tool.c:2011 +msgid "Monitor a remote object." +msgstr "پایش یک شیء دوردست." + +#: gio/gdbus-tool.c:2069 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: gio/gdbus-tool.c:2193 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2196 +msgid "Timeout to wait for before exiting with an error (seconds); 0 for no timeout (default)" +msgstr "" + +#: gio/gdbus-tool.c:2244 +msgid "[OPTION…] BUS-NAME" +msgstr "" + +#: gio/gdbus-tool.c:2245 +msgid "Wait for a bus name to appear." +msgstr "" + +#: gio/gdbus-tool.c:2321 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to activate for must be specified.\n" +msgstr "خطا: مسیر شیء مشخص نشده است.\n" + +#: gio/gdbus-tool.c:2326 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to wait for must be specified.\n" +msgstr "خطا: مسیر شیء مشخص نشده است.\n" + +#: gio/gdbus-tool.c:2331 +msgid "Error: Too many arguments.\n" +msgstr "" + +#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346 +#, fuzzy, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "نویسهٔ «%s» داخل نام نهادها مجاز نیست" + +#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4932 +msgid "Unnamed" +msgstr "بدون‌نام" + +#: gio/gdesktopappinfo.c:2516 +msgid "Desktop file didn’t specify Exec field" +msgstr "" + +#: gio/gdesktopappinfo.c:2801 +msgid "Unable to find terminal required for application" +msgstr "نمی‌توان پایانه‌ی لازم برای این برنامه را پیدا کرد" + +#: gio/gdesktopappinfo.c:3452 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" + +#: gio/gdesktopappinfo.c:3456 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" + +#: gio/gdesktopappinfo.c:3698 gio/gdesktopappinfo.c:3722 +msgid "Application information lacks an identifier" +msgstr "" + +#: gio/gdesktopappinfo.c:3958 +#, fuzzy, c-format +#| msgid "Failed to create temp file: %s" +msgid "Can’t create user desktop file %s" +msgstr "ساخت پرونده موقت شکست خورد: %s" + +#: gio/gdesktopappinfo.c:4094 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: gio/gdrive.c:417 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "drive doesn’t implement eject" +msgstr "جلد قابلیت eject ندارد" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "جلد قابلیت eject یا eject_with_operation را ندارد" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "" + +#: gio/gdrive.c:778 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "drive doesn’t implement start" +msgstr "جلد قابلیت eject ندارد" + +#: gio/gdrive.c:880 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "drive doesn’t implement stop" +msgstr "جلد قابلیت eject ندارد" + +#: gio/gdtlsconnection.c:1153 gio/gtlsconnection.c:920 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "" + +#: gio/gemblem.c:323 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "نمی‌توان با رمزنگاری نسخه %Id GThemedIcon را کار کرد" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: gio/gemblemedicon.c:362 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "نمی‌توان با رمزنگاری نسخه %Id GThemedIcon را کار کرد" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1561 +msgid "Containing mount does not exist" +msgstr "" + +#: gio/gfile.c:2608 gio/glocalfile.c:2477 +#, fuzzy +#| msgid "Can't copy over directory" +msgid "Can’t copy over directory" +msgstr "نمی‌توان بر روی شاخه رونوشت کرد" + +#: gio/gfile.c:2668 +#, fuzzy +#| msgid "Can't copy directory over directory" +msgid "Can’t copy directory over directory" +msgstr "نمي‌توان شاخه را بر روی شاخه رونوشت کرد" + +#: gio/gfile.c:2676 +msgid "Target file exists" +msgstr "پرونده مقصد وجود دارد" + +#: gio/gfile.c:2695 +#, fuzzy +#| msgid "Can't recursively copy directory" +msgid "Can’t recursively copy directory" +msgstr "نمی‌توان بطور پی‌درپی شاخه را رونوشت کرد" + +#: gio/gfile.c:2996 +msgid "Splice not supported" +msgstr "اتصال پشتیبانی نمی‌شود" + +#: gio/gfile.c:3000 +#, c-format +msgid "Error splicing file: %s" +msgstr "خطا در هنگام اتصال پرونده: %s" + +#: gio/gfile.c:3152 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" + +#: gio/gfile.c:3156 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: gio/gfile.c:3161 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" + +#: gio/gfile.c:3226 +#, fuzzy +#| msgid "Can't copy special file" +msgid "Can’t copy special file" +msgstr "نمی‌توان پرونده خاص را رونوشت کرد" + +#: gio/gfile.c:4035 +msgid "Invalid symlink value given" +msgstr "" + +#: gio/gfile.c:4045 glib/gfileutils.c:2354 +msgid "Symbolic links not supported" +msgstr "پیوندهای نمادی پشتیبانی نمی‌شوند" + +#: gio/gfile.c:4213 +msgid "Trash not supported" +msgstr "زباله پشتیبانی نمی‌شود" + +#: gio/gfile.c:4325 +#, fuzzy, c-format +#| msgid "File names cannot contain '%c'" +msgid "File names cannot contain “%câ€" +msgstr "نام پرونده نمی‌تواند حاوی «%c» باشد" + +#: gio/gfile.c:6806 gio/gvolume.c:364 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "volume doesn’t implement mount" +msgstr "جلد قابلیت eject ندارد" + +#: gio/gfile.c:6920 gio/gfile.c:6968 +msgid "No application is registered as handling this file" +msgstr "هیچ برنامه‌ای برای مار با این پرونده ثبت نشده است" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "" + +#: gio/gfileicon.c:250 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "نمی‌توان با رمزنگاری نسخه %Id GThemedIcon را کار کرد" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:596 glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "نام میزبان نامعتبر" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "" + +#: gio/ghttpproxy.c:159 +#, fuzzy +#| msgid "The connection is closed" +msgid "HTTP proxy connection not allowed" +msgstr "اتصال بسته شده است" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "" + +#: gio/ghttpproxy.c:171 +#, fuzzy, c-format +#| msgid "The connection is closed" +msgid "HTTP proxy connection failed: %i" +msgstr "اتصال بسته شده است" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: gio/gicon.c:469 +#, fuzzy +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "نمی‌توان با رمزنگاری نسخه %Id GThemedIcon را کار کرد" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "هیچ آدرسی مشخص نشده است" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: gio/ginetaddressmask.c:300 +#, fuzzy, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "نمی‌توان آدرس محلی را Ø¯Ø±ÛŒØ§ÙØª کرد: %s" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 gio/gnativesocketaddress.c:109 +#: gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "" + +#: gio/ginputstream.c:188 +#, fuzzy +msgid "Input stream doesn’t implement read" +msgstr "جلد قابلیت eject ندارد" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "رونوشت همراه پرونده" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "روش Ø§Ø³ØªÙØ§Ø¯Ù‡:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "" + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "دستورات:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: gio/gio-tool.c:235 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create directories" +msgstr "نمی‌توان شاخه را باز کرد" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "تغییر نام یک پرونده" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "حذ٠یک یا چند پرونده" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" + +#: gio/gio-tool-cat.c:87 +#, fuzzy +#| msgid "Error writing to file: %s" +msgid "Error writing to stdout" +msgstr "خطا در هنگام نوشتن در پرونده: %s" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 gio/gio-tool-mkdir.c:48 +#: gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 gio/gio-tool-remove.c:48 +#: gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +#, fuzzy +#| msgid "SECTION" +msgid "LOCATION" +msgstr "SECTION" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 gio/gio-tool-monitor.c:229 +#: gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +#, fuzzy +#| msgid "Target file is a directory" +msgid "No target directory" +msgstr "پرونده هد٠یک شاخه است" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "نمایش Ù¾ÛŒØ´Ø±ÙØª" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +#, fuzzy +#| msgid "Backup file creation failed" +msgid "Backup existing destination files" +msgstr "ساخت پرونده پشتیبان شکست خورد" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-copy.c:149 +#, fuzzy, c-format +#| msgid "Destination name to monitor" +msgid "Destination %s is not a directory" +msgstr "نام مقصد جهت پایش" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "" + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "" + +#: gio/gio-tool-info.c:38 +#, fuzzy +#| msgid "Error getting filesystem info: %s" +msgid "Get file system info" +msgstr "خطا در Ø¯Ø±ÛŒØ§ÙØª اطلاعات سیستم‌پرونده‌: %s" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "مشخصه‌ها:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, fuzzy, c-format +msgid "display name: %s\n" +msgstr "نام نمایش: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, fuzzy, c-format +msgid "edit name: %s\n" +msgstr "نام ویرایش: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "نام: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "گونه: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "اندازه: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "مخÙÛŒ\n" + +#: gio/gio-tool-info.c:166 +#, fuzzy, c-format +#| msgid "Error: %s\n" +msgid "uri: %s\n" +msgstr "خطا: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "" + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "" + +#: gio/gio-tool-launch.c:57 +msgid "Launch an application from a desktop file, passing optional filename arguments to it." +msgstr "" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "" + +#: gio/gio-tool-launch.c:85 +#, fuzzy +#| msgid "There is no GCredentials support for your platform" +msgid "The launch command is not currently supported on this platform" +msgstr "پشتیبانی از GCredentials در Ù¾Ù„ØªÙØ±Ù… شما وجود ندارد" + +#: gio/gio-tool-launch.c:98 +#, fuzzy, c-format +#| msgid "Unable to create trash dir %s: %s" +msgid "Unable to load ‘%s‘: %s" +msgstr "نمی‌توان شاخه زباله‌دان %s را ساخت: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "" + +#: gio/gio-tool-launch.c:119 +#, fuzzy, c-format +#| msgid "Error launching application: %s" +msgid "Unable to launch application ‘%s’: %s" +msgstr "خطا در راه‌اندازی برنامه: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "" + +#: gio/gio-tool-mime.c:129 +#, fuzzy +#| msgid "Can't find application" +msgid "No registered applications\n" +msgstr "نمی‌توان برنامه را پیدا کرد" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "" + +#: gio/gio-tool-mime.c:142 +#, fuzzy +#| msgid "Can't find application" +msgid "No recommended applications\n" +msgstr "نمی‌توان برنامه را پیدا کرد" + +#: gio/gio-tool-mime.c:162 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "خواندن از پروندهٔ «‎%s» شکست خورد: %s" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mkdir.c:31 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create parent directories" +msgstr "نمی‌توان شاخه را باز کرد" + +#: gio/gio-tool-mkdir.c:52 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create directories." +msgstr "نمی‌توان شاخه را باز کرد" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "شناسه" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "پیاده کردن" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "بیرون دادن" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "سیاهه" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "" + +#: gio/gio-tool-mount.c:74 +#, fuzzy +#| msgid "Show help options" +msgid "Show extra information" +msgstr "نمایش گزینه‌های راهنما" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +#, fuzzy +#| msgctxt "GDateTime" +#| msgid "PM" +msgid "PIM" +msgstr "ب‌ظ" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: gio/gio-tool-move.c:143 +#, fuzzy, c-format +#| msgid "Target file is a directory" +msgid "Target %s is not a directory" +msgstr "پرونده هد٠یک شاخه است" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "" + +#: gio/gio-tool-rename.c:70 +#, fuzzy +#| msgid "Missing argument for %s" +msgid "Missing argument" +msgstr "â€%s یک آرگومان Ú©Ù… دارد" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "" + +#: gio/gio-tool-save.c:113 +#, fuzzy +msgid "Error reading from standard input" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "" + +#: gio/gio-tool-set.c:113 +#, fuzzy +#| msgid "Error: Destination is not specified\n" +msgid "Location not specified" +msgstr "خطا: مقصد مشخص نشده است\n" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "" + +#: gio/gio-tool-set.c:130 +#, fuzzy +#| msgid "No address specified" +msgid "Value not specified" +msgstr "هیچ آدرسی مشخص نشده است" + +#: gio/gio-tool-set.c:180 +#, fuzzy, c-format +#| msgid "Invalid attribute type (string expected)" +msgid "Invalid attribute type “%sâ€" +msgstr "نوع مشخصه نامعتبر است (رشته مورد انتظار بود)" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "" + +#: gio/gio-tool-trash.c:36 +msgid "Restore a file from trash to its original location (possibly recreating the directory)" +msgstr "" + +#: gio/gio-tool-trash.c:106 +#, fuzzy +#| msgid "Unable to find terminal required for application" +msgid "Unable to find original path" +msgstr "نمی‌توان پایانه‌ی لازم برای این برنامه را پیدا کرد" + +#: gio/gio-tool-trash.c:123 +#, fuzzy +#| msgid "Unable to create socket: %s" +msgid "Unable to recreate original location: " +msgstr "نمی‌توان سوکت را ساخت: %s" + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "" + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "" + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: gio/glib-compile-resources.c:245 +#, fuzzy, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "تغییر به شاخهٔ «%s» شکست خورد (%s)" + +#: gio/glib-compile-resources.c:256 +#, fuzzy, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "تغییر به شاخهٔ «%s» شکست خورد (%s)" + +#: gio/glib-compile-resources.c:290 +#, fuzzy, c-format +msgid "Unknown processing option “%sâ€" +msgstr "گزینهٔ نامعلوم %s" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "خطا در خواندن پرونده %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "خطا در هنگام ÙØ´Ø±Ø¯Ù‡â€ŒØ³Ø§Ø²ÛŒ پرونده %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "" + +#: gio/glib-compile-resources.c:738 +#, fuzzy +#| msgid "name of the output file" +msgid "Name of the output file" +msgstr "نام پرونده خروجی" + +#: gio/glib-compile-resources.c:739 +msgid "The directories to load files referenced in FILE from (default: current directory)" +msgstr "" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: gio/glib-compile-resources.c:740 +msgid "Generate output in the format selected for by the target filename extension" +msgstr "" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "" + +#: gio/glib-compile-resources.c:742 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:746 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: gio/glib-compile-resources.c:747 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: gio/glib-compile-resources.c:748 +msgid "Don’t embed resource data in the C file; assume it's linked externally instead" +msgstr "" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, fuzzy, c-format +#| msgid "Invalid filename %s" +msgid "Invalid numeric value" +msgstr "نام‌پرونده نامعتبر: %s" + +#: gio/glib-compile-schemas.c:111 +#, fuzzy, c-format +#| msgid "<%s id='%s'> already specified" +msgid " already specified" +msgstr "<%s id='%s'> از قبل مشخص شده است" + +#: gio/glib-compile-schemas.c:119 +#, fuzzy, c-format +#| msgid "<%s id='%s'> already specified" +msgid "value='%s' already specified" +msgstr "<%s id='%s'> از قبل مشخص شده است" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "" + +#: gio/glib-compile-schemas.c:491 +msgid " cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +#, fuzzy +#| msgid "<%s id='%s'> already specified" +msgid " already specified for this key" +msgstr "<%s id='%s'> از قبل مشخص شده است" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr "" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +#, fuzzy +#| msgid "<%s id='%s'> already specified" +msgid " already specified for this key" +msgstr "<%s id='%s'> از قبل مشخص شده است" + +#: gio/glib-compile-schemas.c:561 +msgid " can only be specified for keys with enumerated or flags types or after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid " given when “%s†is already a member of the enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, fuzzy, c-format +#| msgid "<%s id='%s'> already specified" +msgid " already specified" +msgstr "<%s id='%s'> از قبل مشخص شده است" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +#, fuzzy +#| msgid "empty names are not permitted" +msgid "Empty names are not permitted" +msgstr "نام‌های خالی مجاز نیستند" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers and hyphen (“-â€) are permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid " shadows in ; use to modify value" +msgstr "" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute to " +msgstr "" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: gio/glib-compile-schemas.c:1017 +#, fuzzy, c-format +#| msgid "Invalid attribute type (string expected)" +msgid "Invalid GVariant type string “%sâ€" +msgstr "نوع مشخصه نامعتبر است (رشته مورد انتظار بود)" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1177 +#, fuzzy, c-format +#| msgid "Can not be a list of a schema with a path" +msgid "Cannot be a list of a schema with a path" +msgstr "نمی‌توان با یک مسیر Ùهرست یک Ø´Ùما بود" + +#: gio/glib-compile-schemas.c:1187 +#, fuzzy, c-format +#| msgid "Can not be a list of a schema with a path" +msgid "Cannot extend a schema with a path" +msgstr "نمی‌توان با یک مسیر Ùهرست یک Ø´Ùما بود" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid " is a list, extending which is not a list" +msgstr "" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid " extends but “%s†does not extend “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1224 +#, fuzzy, c-format +#| msgid "a path, if given, must begin and end with a slash" +msgid "A path, if given, must begin and end with a slash" +msgstr "یک مسیر، اگر داده شود، باید با یک خط مورب شروع Ùˆ خاتمه یابد" + +#: gio/glib-compile-schemas.c:1231 +#, fuzzy, c-format +#| msgid "the path of a list must end with ':/'" +msgid "The path of a list must end with “:/â€" +msgstr "مسیر یک Ùهرست باید با «:/» خاتمه پیدا کند" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/desktop/†or “/system/†are " +"deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> از قبل مشخص شده است" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1845 +#, fuzzy +#| msgid "This entire file has been ignored.\n" +msgid "This entire file has been ignored." +msgstr "تمام پرونده نادیده Ú¯Ø±ÙØªÙ‡ شده است.\n" + +#: gio/glib-compile-schemas.c:1908 +#, fuzzy +#| msgid "Ignoring this file.\n" +msgid "Ignoring this file." +msgstr "نادیده Ú¯Ø±ÙØªÙ† این پرونده.\n" + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema “%s†(override file “%sâ€); ignoring " +"override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema “%s†(override file “%sâ€) and --" +"strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: %s. Ignoring override for this " +"key." +msgstr "" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: %s. --strict was specified; " +"exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the range given in the schema; " +"ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the range given in the schema and --" +"strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the list of valid choices; ignoring " +"override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the list of valid choices and --" +"strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2173 +#, fuzzy +#| msgid "Do not write the gschema.compiled file" +msgid "Where to store the gschemas.compiled file" +msgstr "بر روی پرونده‌ی gschema.compiled ننویس" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "قطع کردن با رخداد٠هر نوع خطا در Ø´Ùماها" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "بر روی پرونده‌ی gschema.compiled ننویس" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: gio/glib-compile-schemas.c:2226 +#, fuzzy +#| msgid "You should give exactly one directory name\n" +msgid "You should give exactly one directory name" +msgstr "شما باید دقیقا نام یک دایرکتوری را بدهید\n" + +#: gio/glib-compile-schemas.c:2269 +#, fuzzy +#| msgid "No schema files found: " +msgid "No schema files found: doing nothing." +msgstr "هیچ پرونده شماای پیدا نشد:" + +#: gio/glib-compile-schemas.c:2271 +#, fuzzy +#| msgid "removed existing output file.\n" +msgid "No schema files found: removed existing output file." +msgstr "پرونده خروجی ÙØ¹Ù„ÛŒ حذ٠شد.\n" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "نام پرونده نامعتبر: %s" + +#: gio/glocalfile.c:982 +#, fuzzy, c-format +#| msgid "Error getting filesystem info: %s" +msgid "Error getting filesystem info for %s: %s" +msgstr "خطا در Ø¯Ø±ÛŒØ§ÙØª اطلاعات سیستم‌پرونده‌: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "" + +#: gio/glocalfile.c:1146 +#, fuzzy +#| msgid "Can't rename root directory" +msgid "Can’t rename root directory" +msgstr "نمی‌توان شاخه ریشه را نام‌گذاری مجدد کرد" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, fuzzy, c-format +#| msgid "Error reading file %s: %s" +msgid "Error renaming file %s: %s" +msgstr "خطا در خواندن پرونده %s: %s" + +#: gio/glocalfile.c:1171 +#, fuzzy +#| msgid "Can't rename file, filename already exists" +msgid "Can’t rename file, filename already exists" +msgstr "نمی‌توان پرونده را مجددا نام‌گذاری کرد، نام پرونده از قبل وجود دارد" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2371 gio/glocalfile.c:2399 gio/glocalfile.c:2538 +#: gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "نام پرونده نامعتبر" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, fuzzy, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file %s: %s" +msgstr "خطا در هنگام باز کردن پرونده «%s»: %s" + +#: gio/glocalfile.c:1488 +#, fuzzy, c-format +#| msgid "Error removing file: %s" +msgid "Error removing file %s: %s" +msgstr "خطا در حذ٠پرونده: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 +#, fuzzy, c-format +#| msgid "Error trashing file: %s" +msgid "Error trashing file %s: %s" +msgstr "خطا در انتقال پرونده به زباله‌دان: %s" + +#: gio/glocalfile.c:2031 +#, fuzzy, c-format +#| msgid "Unable to create trash dir %s: %s" +msgid "Unable to create trash directory %s: %s" +msgstr "نمی‌توان شاخه زباله‌دان %s را ساخت: %s" + +#: gio/glocalfile.c:2052 +#, fuzzy, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Unable to find toplevel directory to trash %s" +msgstr "تغییر به شاخهٔ «%s» شکست خورد (%s)" + +#: gio/glocalfile.c:2060 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" + +#: gio/glocalfile.c:2146 gio/glocalfile.c:2174 +#, fuzzy, c-format +#| msgid "Unable to create trash dir %s: %s" +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "نمی‌توان شاخه زباله‌دان %s را ساخت: %s" + +#: gio/glocalfile.c:2220 +#, fuzzy, c-format +#| msgid "Unable to create trashing info file: %s" +msgid "Unable to create trashing info file for %s: %s" +msgstr "نمی‌توان پرونده اطلاعات زباله‌دان را ایجاد کرد: %s" + +#: gio/glocalfile.c:2282 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "نمی‌توان پرونده را به زباله‌دان ÙØ±Ø³ØªØ§Ø¯: %s" + +#: gio/glocalfile.c:2286 gio/glocalfile.c:2342 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s: %s" +msgstr "نمی‌توان پرونده را به زباله‌دان ÙØ±Ø³ØªØ§Ø¯: %s" + +#: gio/glocalfile.c:2348 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s" +msgstr "نمی‌توان پرونده را به زباله‌دان ÙØ±Ø³ØªØ§Ø¯: %s" + +#: gio/glocalfile.c:2374 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory %s: %s" +msgstr "خطا در هنگام ساخت شاخه «%s»: %s" + +#: gio/glocalfile.c:2403 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "سیستم‌پرونده از پیوندهای نمادین پشتیبانی نمی‌کند" + +#: gio/glocalfile.c:2406 +#, fuzzy, c-format +#| msgid "Error making symbolic link: %s" +msgid "Error making symbolic link %s: %s" +msgstr "خطا در در هنگام ساخت پیوند نمادین: %s" + +#: gio/glocalfile.c:2449 gio/glocalfile.c:2484 gio/glocalfile.c:2541 +#, fuzzy, c-format +#| msgid "Error moving file: %s" +msgid "Error moving file %s: %s" +msgstr "خطا در هنگام جابجایی پرونده: %s" + +#: gio/glocalfile.c:2472 +#, fuzzy +#| msgid "Can't copy directory over directory" +msgid "Can’t move directory over directory" +msgstr "نمي‌توان شاخه را بر روی شاخه رونوشت کرد" + +#: gio/glocalfile.c:2498 gio/glocalfileoutputstream.c:1108 gio/glocalfileoutputstream.c:1122 +#: gio/glocalfileoutputstream.c:1137 gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "ساخت پرونده پشتیبان شکست خورد" + +#: gio/glocalfile.c:2517 +#, c-format +msgid "Error removing target file: %s" +msgstr "خطا در هنگام حذ٠پرونده هدÙ: %s" + +#: gio/glocalfile.c:2531 +msgid "Move between mounts not supported" +msgstr "" + +#: gio/glocalfile.c:2705 +#, fuzzy, c-format +#| msgid "could not get remote address: %s" +msgid "Could not determine the disk usage of %s: %s" +msgstr "نمی‌توان آدرس دوردست را Ø¯Ø±ÛŒØ§ÙØª کرد: %s" + +#: gio/glocalfileinfo.c:767 +#, fuzzy +msgid "Attribute value must be non-NULL" +msgstr "مقدار مشخصه نباید non-NULL باشد" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "نوع مشخصه نامعتبر است (رشته مورد انتظار بود)" + +#: gio/glocalfileinfo.c:781 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "نوشتار به‌طور غیرمنتظره‌ای داخل نام یک مشخصه به‌پایان رسید" + +#: gio/glocalfileinfo.c:821 +#, fuzzy, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "خطا در باز کردن شاخهٔ «‎%s»â€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (کدگذاری نامعتبر)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 gio/glocalfileoutputstream.c:995 +#, fuzzy, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "خطا در بازکردن پرونده ÙØ¹Ù„ÛŒ «‎%s»â€: %s" + +#: gio/glocalfileinfo.c:2134 +#, fuzzy, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "خطا در هنگام تنظیم توصیÙ‌گر پرونده: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "نوع مشخصه نامعتبر (uint32 مورد انتظار بود)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "نوع مشخصه نامعتبر بود (uint64 مورد انتظار بود)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "نوع مشخصه نامعتبر (رشته بایتی مورد انتظار بود)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "نمی‌توان اجازه‌های روی پیوند نمادین را تنظیم کرد" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "خطا در هنگام تنظیم اجازه‌ها: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "خطا در هنگام تنظیم مالک: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "خطا در تنظیم پیوند نمادین: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "" + +#: gio/glocalfileinfo.c:2602 +#, fuzzy, c-format +#| msgid "Error setting modification or access time: %s" +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "خطا در هنگام تنظیم کردن زمان دسترسی یا تغییر: %s" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "خطا در هنگام تنظیم کردن زمان دسترسی یا تغییر: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "سیستم SELinux بر روی این سیستم ÙØ¹Ø§Ù„ نشده است" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "خطا در تنظیم Ù…ÙØ§Ø¯ SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "تنظیم کردن مشخصه %s پشتیبانی نمی‌شود" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "خطا در هنگام خواندن از پرونده: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "خطا در هنگام بستن پرونده: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "خطا در هنگام جستجو در پرونده: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 gio/glocalfileoutputstream.c:334 +#: gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "خطا در هنگام نوشتن در پرونده: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "خطا در هنگام حذ٠کردن پیوند پشتیبانی قدیمی: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "خطا در هنگام رونشت از پشتیبان: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "خطا خطا در تغییر نام پرونده موقت: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "خطا در هنگام کوتاه کردن پرونده: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 gio/glocalfileoutputstream.c:1218 +#: gio/gsubprocess.c:226 +#, fuzzy, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file “%sâ€: %s" +msgstr "خطا در هنگام باز کردن پرونده «%s»: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "پرونده هد٠یک شاخه است" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "پرونده هد٠یک پرونده معمولی نیست" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "پرونده از خارج تغییر کرده است" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "خطا در هنگام حذ٠پرونده قدیمی: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "درخواست جستجو نامعتبر" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "" + +#: gio/gmemoryoutputstream.c:673 +msgid "Amount of memory required to process the write is larger than available address space" +msgstr "" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "mount doesn’t implement “unmountâ€" +msgstr "جلد قابلیت eject ندارد" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "mount doesn’t implement “ejectâ€" +msgstr "جلد قابلیت eject ندارد" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "جلد قابلیت eject یا eject_with_operation را ندارد" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "جلد قابلیت eject یا eject_with_operation را ندارد" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "mount doesn’t implement “remountâ€" +msgstr "جلد قابلیت eject ندارد" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "شبکه غیرقابل دسترس است" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "میزبان غیرقابل دسترسی است" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "نمی‌توان پایشگر شبکه را ساخت: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "نمی‌توان پایشگر شبکه را ساخت: " + +#: gio/gnetworkmonitornetlink.c:183 +#, fuzzy +msgid "Could not get network status: " +msgstr "نمی‌توان آدرس دوردست را Ø¯Ø±ÛŒØ§ÙØª کرد: %s" + +#: gio/gnetworkmonitornm.c:348 +#, c-format +msgid "NetworkManager not running" +msgstr "" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +#, fuzzy +msgid "Output stream doesn’t implement write" +msgstr "جلد قابلیت eject ندارد" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "جریان منبع از قبل بسته شده است" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, fuzzy, c-format +#| msgid "Error resolving '%s': %s" +msgid "Error resolving “%sâ€: %s" +msgstr "خطا در هنگام برطرÙ‌سازی «%s»: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:615 +#, c-format +msgid "%s not implemented" +msgstr "" + +#: gio/gresolver.c:984 gio/gresolver.c:1036 +#, fuzzy +#| msgid "Invalid filename" +msgid "Invalid domain" +msgstr "نام پرونده نامعتبر" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 gio/gresource.c:1107 gio/gresource.c:1179 +#: gio/gresource.c:1253 gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "" + +#: gio/gresourcefile.c:940 +#, fuzzy +msgid "Input stream doesn’t implement seek" +msgstr "جلد قابلیت eject ندارد" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECTION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:706 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[PATH]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr "" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:911 +#, fuzzy, c-format +#| msgid "No such schema '%s'\n" +msgid "No such schema “%sâ€\n" +msgstr "همجین Ø´Ùمایی وجود ندارد «%s»\n" + +#: gio/gsettings-tool.c:55 +#, fuzzy, c-format +#| msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Ø´Ùما «%s» قابل جابه‌جایی نیست (مسیر نباید مشخص شود)\n" + +#: gio/gsettings-tool.c:76 +#, fuzzy, c-format +#| msgid "Schema '%s' is relocatable (path must be specified)\n" +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Ø´Ùما «%s» قابل جابه‌جایی نیست (مسیر باید مشخص شود)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "مسیر خالی داده شده است.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "مسیر با یک خط مورب (/) باید آغاز شود\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "مسیر با یک خط مورب (/) باید پایان یابد\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: gio/gsettings-tool.c:541 +msgid "The provided value is outside of the valid range\n" +msgstr "مقدار ÙØ±Ø§Ù‡Ù… شده خارج از محدود مجاز است\n" + +#: gio/gsettings-tool.c:548 +#, fuzzy +#| msgid "Property '%s' is not writable" +msgid "The key is not writable\n" +msgstr "خصیصه‌ی «%s» قابل نوشتن نیست" + +#: gio/gsettings-tool.c:584 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: gio/gsettings-tool.c:590 +msgid "List the installed relocatable schemas" +msgstr "" + +#: gio/gsettings-tool.c:596 +msgid "List the keys in SCHEMA" +msgstr "لیست کلیدها درون SCHEMA" + +#: gio/gsettings-tool.c:597 gio/gsettings-tool.c:603 gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:602 +msgid "List the children of SCHEMA" +msgstr "Ùهرست کردن ÙØ±Ø²Ù†Ø¯Ø§Ù† SCHEMA" + +#: gio/gsettings-tool.c:608 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: gio/gsettings-tool.c:610 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:615 +msgid "Get the value of KEY" +msgstr "Ú¯Ø±ÙØªÙ† مقدار KEY" + +#: gio/gsettings-tool.c:616 gio/gsettings-tool.c:622 gio/gsettings-tool.c:628 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:621 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: gio/gsettings-tool.c:627 +msgid "Query the description for KEY" +msgstr "" + +#: gio/gsettings-tool.c:633 +msgid "Set the value of KEY to VALUE" +msgstr "تنظیم مقدار KEY به VALUE" + +#: gio/gsettings-tool.c:634 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:639 +msgid "Reset KEY to its default value" +msgstr "تنظیم مجدد KEY به مقدار Ù¾ÛŒØ´â€ŒÙØ±Ø¶" + +#: gio/gsettings-tool.c:645 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "تنظیم مجدد تمام کلیدها در SCHEMA به مقدار Ù¾ÛŒØ´â€ŒÙØ±Ø¶" + +#: gio/gsettings-tool.c:651 +msgid "Check if KEY is writable" +msgstr "بررسی اینکه KEY قابل نوشتن است" + +#: gio/gsettings-tool.c:657 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: gio/gsettings-tool.c:660 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: gio/gsettings-tool.c:672 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:696 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:702 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:710 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:715 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: gio/gsettings-tool.c:719 +msgid " KEY The key within the schema\n" +msgstr "" + +#: gio/gsettings-tool.c:723 +msgid " VALUE The value to set\n" +msgstr "" + +#: gio/gsettings-tool.c:778 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not load schemas from %s: %s\n" +msgstr "نمی‌توان مبدل «%s» به «%s» را باز کرد" + +#: gio/gsettings-tool.c:790 +#, fuzzy +#| msgid "No schema files found: " +msgid "No schemas installed\n" +msgstr "هیچ پرونده شماای پیدا نشد:" + +#: gio/gsettings-tool.c:869 +msgid "Empty schema name given\n" +msgstr "" + +#: gio/gsettings-tool.c:924 +#, fuzzy, c-format +#| msgid "No such key '%s'\n" +msgid "No such key “%sâ€\n" +msgstr "همچین کلیدی وجود ندارد «%s»\n" + +#: gio/gsocket.c:413 +msgid "Invalid socket, not initialized" +msgstr "" + +#: gio/gsocket.c:420 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: gio/gsocket.c:428 +msgid "Socket is already closed" +msgstr "سوکت از قبل بسته شده است" + +#: gio/gsocket.c:443 gio/gsocket.c:3190 gio/gsocket.c:4420 gio/gsocket.c:4478 +msgid "Socket I/O timed out" +msgstr "" + +#: gio/gsocket.c:578 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "درحال ساخت GSocket از طریق fd: %s" + +#: gio/gsocket.c:607 gio/gsocket.c:671 gio/gsocket.c:678 +#, c-format +msgid "Unable to create socket: %s" +msgstr "نمی‌توان سوکت را ساخت: %s" + +#: gio/gsocket.c:671 +#, fuzzy +#| msgid "Unknown protocol was specified" +msgid "Unknown family was specified" +msgstr "پروتکل ناشناسی مشخص شده است" + +#: gio/gsocket.c:678 +msgid "Unknown protocol was specified" +msgstr "پروتکل ناشناسی مشخص شده است" + +#: gio/gsocket.c:1169 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: gio/gsocket.c:1186 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: gio/gsocket.c:1993 +#, c-format +msgid "could not get local address: %s" +msgstr "نمی‌توان آدرس محلی را Ø¯Ø±ÛŒØ§ÙØª کرد: %s" + +#: gio/gsocket.c:2039 +#, c-format +msgid "could not get remote address: %s" +msgstr "نمی‌توان آدرس دوردست را Ø¯Ø±ÛŒØ§ÙØª کرد: %s" + +#: gio/gsocket.c:2105 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: gio/gsocket.c:2209 +#, fuzzy, c-format +msgid "Error binding to address %s: %s" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gsocket.c:2385 gio/gsocket.c:2422 gio/gsocket.c:2532 gio/gsocket.c:2557 gio/gsocket.c:2620 +#: gio/gsocket.c:2678 gio/gsocket.c:2696 +#, fuzzy, c-format +msgid "Error joining multicast group: %s" +msgstr "خطا در راه‌اندازی برنامه: %s" + +#: gio/gsocket.c:2386 gio/gsocket.c:2423 gio/gsocket.c:2533 gio/gsocket.c:2558 gio/gsocket.c:2621 +#: gio/gsocket.c:2679 gio/gsocket.c:2697 +#, fuzzy, c-format +msgid "Error leaving multicast group: %s" +msgstr "خطا در راه‌اندازی برنامه: %s" + +#: gio/gsocket.c:2387 +msgid "No support for source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2534 +msgid "Unsupported socket family" +msgstr "" + +#: gio/gsocket.c:2559 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2583 +#, c-format +msgid "Interface name too long" +msgstr "" + +#: gio/gsocket.c:2596 gio/gsocket.c:2646 +#, c-format +msgid "Interface not found: %s" +msgstr "" + +#: gio/gsocket.c:2622 +msgid "No support for IPv4 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2680 +msgid "No support for IPv6 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2889 +#, c-format +msgid "Error accepting connection: %s" +msgstr "خطا در هنگام Ù¾Ø°ÛŒØ±ÙØªÙ† اتصال: %s" + +#: gio/gsocket.c:3015 +msgid "Connection in progress" +msgstr "اتصال در حال پیشروی است" + +#: gio/gsocket.c:3066 +#, fuzzy +#| msgid "Unable to get pending error: %s" +msgid "Unable to get pending error: " +msgstr "ناتوان در Ø¯Ø±ÛŒØ§ÙØª خطای درانتظار: %s" + +#: gio/gsocket.c:3255 +#, c-format +msgid "Error receiving data: %s" +msgstr "خطا در Ø¯Ø±ÛŒØ§ÙØª داده: %s" + +#: gio/gsocket.c:3452 +#, c-format +msgid "Error sending data: %s" +msgstr "خطا در ارسال داده: %s" + +#: gio/gsocket.c:3639 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "نمی‌توان سوکت را خاموش کرد: %s" + +#: gio/gsocket.c:3720 +#, c-format +msgid "Error closing socket: %s" +msgstr "خط در هنگام بستن سوکت: %s" + +#: gio/gsocket.c:4413 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "در حال انتظار برای وضعیت سوکت: %s" + +#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833 +#, fuzzy, c-format +#| msgid "Error sending message: %s" +msgid "Unable to send message: %s" +msgstr "خطا در هنگام ارسال پیام: %s" + +#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834 +#, fuzzy +#| msgid "regular expression too large" +msgid "Message vectors too large" +msgstr "عبارت باقاعده بسیار بلند است" + +#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084 gio/gsocket.c:5262 +#: gio/gsocket.c:5302 gio/gsocket.c:5304 +#, c-format +msgid "Error sending message: %s" +msgstr "خطا در هنگام ارسال پیام: %s" + +#: gio/gsocket.c:5026 +#, fuzzy +#| msgid "association changes not supported on win32" +msgid "GSocketControlMessage not supported on Windows" +msgstr "تغییر ارتباط در win32 پشتیبانی نمی‌شود" + +#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797 +#, c-format +msgid "Error receiving message: %s" +msgstr "خطا در هنگام Ø¯Ø±ÛŒØ§ÙØª پیام: %s" + +#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to read socket credentials: %s" +msgstr "نمی‌توان سوکت را ساخت: %s" + +#: gio/gsocket.c:6136 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "نمی‌توان به %s متصل شد: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "" + +#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749 +#, fuzzy +#| msgid "Proxy protocol '%s' is not supported." +msgid "Proxying over a non-TCP connection is not supported." +msgstr "پروتکل پیشکار «%s» پیشتیبانی نمی‌شود." + +#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778 +#, fuzzy, c-format +#| msgid "Proxy protocol '%s' is not supported." +msgid "Proxy protocol “%s†is not supported." +msgstr "پروتکل پیشکار «%s» پیشتیبانی نمی‌شود." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "شنونده از قبل بسته شده است" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "سوکت اضاÙÙ‡ شده بسته است" + +#: gio/gsocks4aproxy.c:118 +#, fuzzy, c-format +#| msgid "SOCKSv4 does not support IPv6 address '%s'" +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "پیشکار SOCKSv4 از آدرس IPv6 «%s» پشتیبانی نمی‌کند" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "نام‌کاربری برای پروتکل SOCKSv4 بسیار بلند است" + +#: gio/gsocks4aproxy.c:153 +#, fuzzy, c-format +#| msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "نام میزبان «%s» برای پروتکل SOCKSv4 بسیار بلند است" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "این کارگزار، یک کارگزار پیشکار SOCKSv4 نیست." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "پیشکار SOCKSv5 به تصدیق هویت نیاز دارد." + +#: gio/gsocks5proxy.c:191 +msgid "The SOCKSv5 proxy requires an authentication method that is not supported by GLib." +msgstr "پیشکار SOCKSv5 به نوعی از تصدیق هویت نیاز دارد Ú©Ù‡ در GLib پشتیبانی نمی‌شود." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "نام‌کاربری یا گذرواژه برای پروتکل SOCKSv5 بسیار بزرگ است." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "تصدیق هویت SOCKSv5 با توجه به اشتباه بودن گذرواژه Ùˆ نام‌کاربری شکست خورد." + +#: gio/gsocks5proxy.c:300 +#, fuzzy, c-format +#| msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "نام میزبان «%s» برای پروتکل SOCKSv5 بسیار بزرگ است" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "کارگزار پیشکار SOCKSv5 از نوعی آدرس ناشناخته Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌کند." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "خطای داخلی کارگزار پیشکار SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "میزبان از طریق کارگزار SOCKSv5 در دسترس نیست." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "شبکه از طریق پیشکار SOCKSv5 غیرقابل دسترس است." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "اتصال از طریق پیشکار SOCKSv5 رد شد." + +#: gio/gsocks5proxy.c:400 +#, fuzzy +#| msgid "SOCKSv5 proxy does not support 'connect' command." +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "پیشکار SOCKSv5 از ÙØ±Ù…ان «connect» پشتیبانی نمی‌کند." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "پیشکار SOCKSv5 از نوع آدرس ارائه شده پشتیبانی نمی‌کند." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "خطا ناشناس پیشکار نسخه Ûµ SOCKS." + +#: gio/gthemedicon.c:595 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "نمی‌توان با رمزنگاری نسخه %Id GThemedIcon را کار کرد" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "" + +#: gio/gthreadedresolver.c:337 +#, fuzzy, c-format +#| msgid "Error reverse-resolving '%s': %s" +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "خطا در هنگام برطرÙ‌سازی معکوس «%s»: %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 gio/gthreadedresolver.c:853 +#: gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 gio/gthreadedresolver.c:973 +#, fuzzy, c-format +#| msgid "Error resolving '%s'" +msgid "Error resolving “%sâ€" +msgstr "خطا در هنگام برطرÙ‌سازی «%s»" + +#: gio/gtlscertificate.c:419 +msgid "No PEM-encoded private key found" +msgstr "هیچ کلید خصوصی رمز‌نگاری شده PEM پیدا نشد" + +#: gio/gtlscertificate.c:429 +#, fuzzy +msgid "Cannot decrypt PEM-encoded private key" +msgstr "نمی‌توان کلید خصوصی رمزنگاری شده PEM را تجزیه کرد" + +#: gio/gtlscertificate.c:440 +msgid "Could not parse PEM-encoded private key" +msgstr "نمی‌توان کلید خصوصی رمزنگاری شده PEM را تجزیه کرد" + +#: gio/gtlscertificate.c:467 +msgid "No PEM-encoded certificate found" +msgstr "هیچ گواهینامه رمزنگاری شده PEM پیدا نشد" + +#: gio/gtlscertificate.c:476 +msgid "Could not parse PEM-encoded certificate" +msgstr "نمی‌توان گواهینامه رمزنگاری شده PEM را پیدا کرد" + +#: gio/gtlscertificate.c:832 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" + +#: gio/gtlspassword.c:111 +msgid "This is the last chance to enter the password correctly before your access is locked out." +msgstr "این آخرین شانس برای وارد کردن گذرواژه بطور صحیح قبل از Ù‚ÙÙ„ شدن دسترسی شما است." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +#, fuzzy +#| msgid "" +#| "Several password entered have been incorrect, and your access will be locked out after further " +#| "failures." +msgid "" +"Several passwords entered have been incorrect, and your access will be locked out after further failures." +msgstr "تعدادی از گذرواژهای وارد شده نادرست بوده‌اند، Ùˆ دسترسی شما بعد از اشتباهات بعدی بسته خواهد شد." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "گذرواژه وارد شده نادرست است." + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, fuzzy, c-format +#| msgid "Expecting 1 control message, got %d" +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "انتظار Û± پیام کنترلی Ù…ÛŒâ€ŒØ±ÙØªØŒ %Id مورد Ø¯Ø±ÛŒØ§ÙØª شد" +msgstr[1] "انتظار Û± پیام کنترلی Ù…ÛŒâ€ŒØ±ÙØªØŒ %Id مورد Ø¯Ø±ÛŒØ§ÙØª شد" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "نوع داده Ú©Ù…Ú©ÛŒ غیرمنتظره" + +#: gio/gunixconnection.c:200 +#, fuzzy, c-format +#| msgid "Expecting one fd, but got %d\n" +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "انتظار یک fd Ù…ÛŒâ€ŒØ±ÙØªØŒ اما %Id مورد Ø¯Ø±ÛŒØ§ÙØª شد\n" +msgstr[1] "انتظار یک fd Ù…ÛŒâ€ŒØ±ÙØªØŒ اما %Id مورد Ø¯Ø±ÛŒØ§ÙØª شد\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "یک fd نامعتبر Ø¯Ø±ÛŒØ§ÙØª شد" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "خطا در زمان ارسال گواهینامه: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "خطا در هنگام بررسی اینکه آیا SO_PASSCRED f برای سوکت ÙØ¹Ø§Ù„ است یا خیر: %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "خطا در هنگام ÙØ¹Ø§Ù„ کردن SO_PASSCRED: %s" + +#: gio/gunixconnection.c:565 +msgid "Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "انتظار خواندن یک بایت برای Ø¯Ø±ÛŒØ§ÙØª گواهینامه Ù…ÛŒâ€ŒØ±ÙØª اما ØµÙØ± بایت خوانده شد" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "انتظار پیام کنترلی Ù†Ù…ÛŒâ€ŒØ±ÙØªØŒ اما %Id Ø¯Ø±ÛŒØ§ÙØª شد" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "خطا در هنگام ØºÛŒØ±ÙØ¹Ø§Ù„‌سازی SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, fuzzy, c-format +msgid "Error reading from file descriptor: %s" +msgstr "خطا در هنگام تنظیم توصیÙ‌گر پرونده: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 gio/gwin32inputstream.c:217 +#: gio/gwin32outputstream.c:204 +#, fuzzy, c-format +msgid "Error closing file descriptor: %s" +msgstr "خطا در هنگام تنظیم توصیÙ‌گر پرونده: %s" + +#: gio/gunixmounts.c:2785 gio/gunixmounts.c:2838 +msgid "Filesystem root" +msgstr "ریشه سیستم‌پرونده‌ها" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 gio/gunixoutputstream.c:464 +#: gio/gunixoutputstream.c:484 gio/gunixoutputstream.c:630 +#, fuzzy, c-format +msgid "Error writing to file descriptor: %s" +msgstr "خطا در هنگام تنظیم توصیÙ‌گر پرونده: %s" + +#: gio/gunixsocketaddress.c:244 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" + +#: gio/gvolume.c:438 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "volume doesn’t implement eject" +msgstr "جلد قابلیت eject ندارد" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "جلد قابلیت eject یا eject_with_operation را ندارد" + +#: gio/gwin32inputstream.c:185 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gwin32outputstream.c:172 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Ø­Ø§ÙØ¸Ù‡ کاÙÛŒ موجود نیست" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "خطا داخلی: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "ورودی بیشتر لازم است" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "داده ÙØ´Ø±Ø¯Ù‡ شده نامعتبر" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "چاپ آدرس" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "" + +#: glib/gbookmarkfile.c:777 +#, fuzzy, c-format +#| msgid "Unexpected attribute '%s' for element '%s'" +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "مشخصهٔ غیرمنتظرهٔ «%s» برای عنصر «%s»" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 glib/gbookmarkfile.c:991 +#, fuzzy, c-format +#| msgid "Attribute '%s' of element '%s' not found" +msgid "Attribute “%s†of element “%s†not found" +msgstr "مشخصهٔ «%s» برای عنصر «%s» پیدا نشد" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, fuzzy, c-format +#| msgid "Unexpected tag '%s', tag '%s' expected" +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "برچسب غیرمنتظرهٔ «%s»، برچسب «%s» انتظار Ù…ÛŒâ€ŒØ±ÙØª" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, fuzzy, c-format +#| msgid "Unexpected tag '%s' inside '%s'" +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "برچسب غیرمنتظرهٔ «%s» داخل «%s»" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "پروندهٔ چوب‌ال٠معتبری در شاخه‌های داده پیدا نمی‌شود" + +#: glib/gbookmarkfile.c:2037 +#, fuzzy, c-format +#| msgid "A bookmark for URI '%s' already exists" +msgid "A bookmark for URI “%s†already exists" +msgstr "چوب‌الÙÛŒ برای نشانی «‎%s» از قبل موجود است" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, fuzzy, c-format +#| msgid "No bookmark found for URI '%s'" +msgid "No bookmark found for URI “%sâ€" +msgstr "چوب‌الÙÛŒ برای نشانی «‎%s» پیدا نشد" + +#: glib/gbookmarkfile.c:2418 +#, fuzzy, c-format +#| msgid "No MIME type defined in the bookmark for URI '%s'" +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "هیچ نوع MIME در چوب‌ال٠برای نشانی «‎%s» تعری٠نشده است" + +#: glib/gbookmarkfile.c:2503 +#, fuzzy, c-format +#| msgid "No private flag has been defined in bookmark for URI '%s'" +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "پرچم خصوصی‌ای برای چوب‌ال٠برای نشانی «%s» تعری٠نشده است" + +#: glib/gbookmarkfile.c:3044 +#, fuzzy, c-format +#| msgid "No groups set in bookmark for URI '%s'" +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "گروهی در چوب‌ال٠برای نشانی «‎%s» تعیین نشده است" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, fuzzy, c-format +#| msgid "No application with name '%s' registered a bookmark for '%s'" +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "برنامه‌ای با نام «%s» چوب‌الÙÛŒ برای «‎%s» ثبت نکرده است" + +#: glib/gbookmarkfile.c:3743 +#, fuzzy, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "خواندن پیوند نمادی «‎%s» شکست خورد: %s" + +#: glib/gconvert.c:468 +#, fuzzy +#| msgid "Invalid sequence in conversion input" +msgid "Unrepresentable character in conversion input" +msgstr "دنبالهٔ نامعتبر در ورودی تبدیل" + +#: glib/gconvert.c:495 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "دنباله نویسهٔ ناتمام در انتهای ورودی" + +#: glib/gconvert.c:764 +#, fuzzy, c-format +#| msgid "Cannot convert fallback '%s' to codeset '%s'" +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "نمی‌توان عقب‌نشینی «%s» را به مجموعه کد «%s» تبدیل کرد" + +#: glib/gconvert.c:936 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "دنبالهٔ بایتی نامعتبر در ورودی تبدیل" + +#: glib/gconvert.c:957 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "دنبالهٔ بایتی نامعتبر در ورودی تبدیل" + +#: glib/gconvert.c:1688 +#, fuzzy, c-format +#| msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "نشانی «‎%s» یک نشانی اینترنتی مطلق با Ø´Ùمای «پرونده» نیست" + +#: glib/gconvert.c:1698 +#, fuzzy, c-format +#| msgid "The local file URI '%s' may not include a '#'" +msgid "The local file URI “%s†may not include a “#â€" +msgstr "نشانی پروندهٔ محلی «‎%s» نمی‌تواند «#» داشته باشد" + +#: glib/gconvert.c:1715 +#, fuzzy, c-format +#| msgid "The URI '%s' is invalid" +msgid "The URI “%s†is invalid" +msgstr "نشانی اینترنتی «%s» نامعتبر است" + +#: glib/gconvert.c:1727 +#, fuzzy, c-format +#| msgid "The hostname of the URI '%s' is invalid" +msgid "The hostname of the URI “%s†is invalid" +msgstr "نام میزبان نشانی اینترنتی «‎%s» نامعتبر است" + +#: glib/gconvert.c:1743 +#, fuzzy, c-format +#| msgid "The URI '%s' contains invalidly escaped characters" +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "نشانی اینترنتی «‎%s» نویسه‌های گریختهٔ نامعتبر دارد" + +#: glib/gconvert.c:1815 +#, fuzzy, c-format +#| msgid "The pathname '%s' is not an absolute path" +msgid "The pathname “%s†is not an absolute path" +msgstr "نام مسیر «‎%s» یک مسیر مطلق نیست" + +# Ø§Ø³ØªÙØ§Ø¯Ù‡ از نویسه‌های U+2266 Ùˆ U+2269 برای ایزوله‌کردن زمان، تا به درستی نمایش داده شود. +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %Oe %B %OyØŒ â¦%OH:%OM:%OSâ©" + +# Ø§Ø³ØªÙØ§Ø¯Ù‡ از نویسه‌های U+2266 Ùˆ U+2269 برای ایزوله‌کردن تاریخ، تا به درستی نمایش داده شود. +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "â©%Oy/%Om/%Odâ©" + +# Ø§Ø³ØªÙØ§Ø¯Ù‡ از نویسه‌های U+2266 Ùˆ U+2269 برای ایزوله‌کردن زمان، تا به درستی نمایش داده شود. +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "â¦%OH:%OM:%OSâ©" + +# Ø§Ø³ØªÙØ§Ø¯Ù‡ از نویسه‌های U+2266 Ùˆ U+2269 برای ایزوله‌کردن زمان، تا به درستی نمایش داده شود. +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "â¦%OI:%OM:%OSâ© %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "ژانویه" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Ùوریه" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "مارس" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "آوریل" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "مه" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "ژوئن" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "ژوئیه" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "آگوست" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "سپتامبر" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "اکتبر" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "نوامبر" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "دسامبر" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ژانویه" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Ùوریه" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "مارس" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "آوریل" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "مه" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ژوئن" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ژوئیه" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "آگوست" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "سپتامبر" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "اکتبر" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "نوامبر" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "دسامبر" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "دوشنبه" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "سه‌شنبه" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "چهارشنبه" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "پنجشنبه" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "جمعه" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "شنبه" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "یکشنبه" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "دوشنبه" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "سه‌شنبه" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "چهارشنبه" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "پنجشنبه" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "جمعه" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "شنبه" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "یکشنبه" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "ژانویه" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Ùوریه" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "مارس" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "آوریل" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "مه" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "ژوئن" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "ژوئیه" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "آگوست" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "سپتامبر" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "اکتبر" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "نوامبر" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "دسامبر" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ژانویه" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Ùوریه" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "مارس" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "آوریل" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "مه" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "ژوئن" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "ژوئیه" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "آگوست" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "سپتامبر" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "اکتبر" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "نوامبر" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "دسامبر" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "ق‌ظ" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "ب‌ظ" + +#: glib/gdir.c:156 +#, fuzzy, c-format +#| msgid "Error opening directory '%s': %s" +msgid "Error opening directory “%sâ€: %s" +msgstr "خطا در باز کردن شاخهٔ «‎%s»â€: %s" + +#: glib/gfileutils.c:737 glib/gfileutils.c:829 +#, fuzzy, c-format +#| msgid "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "نمی‌توان %Ilu بایت برای خواندن پروندهٔ «‎%s» تخصیص داد" +msgstr[1] "نمی‌توان %Ilu بایت برای خواندن پروندهٔ «‎%s» تخصیص داد" + +#: glib/gfileutils.c:754 +#, fuzzy, c-format +#| msgid "Error reading file %s: %s" +msgid "Error reading file “%sâ€: %s" +msgstr "خطا در خواندن پرونده %s: %s" + +#: glib/gfileutils.c:790 +#, c-format +msgid "File “%s†is too large" +msgstr "پروندهٔ «%s» بسیار بزرگ است" + +#: glib/gfileutils.c:854 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to read from file “%sâ€: %s" +msgstr "خواندن از پروندهٔ «‎%s» شکست خورد: %s" + +#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1468 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': %s" +msgid "Failed to open file “%sâ€: %s" +msgstr "باز کردن پروندهٔ «‎%s» شکست خورد: %s" + +#: glib/gfileutils.c:917 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Ú¯Ø±ÙØªÙ† مشخصه‌های پروندهٔ «‎%s» شکست خورد: fstat()‎ شکست خورد: %s" + +#: glib/gfileutils.c:948 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': fdopen() failed: %s" +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "باز کردن پروندهٔ «‎%s» شکست خورد: fdopen()‎ شکست خورد: %s" + +#: glib/gfileutils.c:1049 +#, fuzzy, c-format +#| msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "تغییر دادن نام پروندهٔ «‎%s» به «‎%s» شکست خورد: g_rename()‎ شکست خورد: %s" + +#: glib/gfileutils.c:1175 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': fwrite() failed: %s" +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "نوشتن پروندهٔ «‎%s» شکست خورد: fdwrite()‎ شکست خورد: %s" + +#: glib/gfileutils.c:1196 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': fsync() failed: %s" +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "نوشتن پروندهٔ «‎%s» شکست خورد: fsync()‎ شکست خورد: %s" + +#: glib/gfileutils.c:1357 glib/gfileutils.c:1772 +#, fuzzy, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to create file “%sâ€: %s" +msgstr "ایجاد پروندهٔ «‎%s» شکست خورد: %s" + +#: glib/gfileutils.c:1402 +#, fuzzy, c-format +#| msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "نمی‌توان پروندهٔ موجود «‎%s» را جذ٠کرد: g_unlink() شکست خورد: %s" + +#: glib/gfileutils.c:1737 +#, fuzzy, c-format +#| msgid "Template '%s' invalid, should not contain a '%s'" +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "قالب «%s» نامعتبر است، نباید «%s» داشته باشد" + +#: glib/gfileutils.c:1750 +#, fuzzy, c-format +#| msgid "Template '%s' doesn't contain XXXXXX" +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "قالب «%s» حاوی XXXXXX نیست" + +#: glib/gfileutils.c:2310 glib/gfileutils.c:2339 +#, fuzzy, c-format +#| msgid "Failed to read the symbolic link '%s': %s" +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "خواندن پیوند نمادی «‎%s» شکست خورد: %s" + +#: glib/giochannel.c:1405 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s': %s" +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "نمی‌توان مبدل «%s» به «%s» را باز کرد: %s" + +#: glib/giochannel.c:1758 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_line_string" +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "نمی‌توان در g_io_channel_read_line_string خوانش خام انجام داد" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "دادهٔ تبدیل‌نشده در میان‌گیر خواندن باقی مانده است" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "کانال با یک نویسهٔ ناتمام پایان می‌یابد" + +#: glib/giochannel.c:1949 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_to_end" +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "نمی‌توان در g_io_channel_read_to_end خوانش خام انجام داد" + +#: glib/gkeyfile.c:790 +msgid "Valid key file could not be found in search dirs" +msgstr "پروندهٔ کلید معتبر در شاخه‌های جست‌وجو ÛŒØ§ÙØª نمی‌شود" + +#: glib/gkeyfile.c:827 +msgid "Not a regular file" +msgstr "پرونده متعار٠نیست" + +#: glib/gkeyfile.c:1282 +#, fuzzy, c-format +#| msgid "Key file contains line '%s' which is not a key-value pair, group, or comment" +msgid "Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "پرونده کلید حاوی خط «%s» است Ú©Ù‡ Ø¬ÙØª کلیدâ€Ù…قدار، گروه یا توضیح نیست" + +#: glib/gkeyfile.c:1339 +#, c-format +msgid "Invalid group name: %s" +msgstr "نام گروه نامعتبر: %s" + +#: glib/gkeyfile.c:1361 +msgid "Key file does not start with a group" +msgstr "پروندهٔ کلید با یک گروه آغاز نمی‌شود" + +#: glib/gkeyfile.c:1387 +#, c-format +msgid "Invalid key name: %s" +msgstr "نام کلید نامعتبر: %s" + +#: glib/gkeyfile.c:1414 +#, fuzzy, c-format +#| msgid "Key file contains unsupported encoding '%s'" +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "پروندهٔ کلید حاوی کدگذاری پشتیبانی نشدهٔ «%s» است" + +#: glib/gkeyfile.c:1663 glib/gkeyfile.c:1836 glib/gkeyfile.c:3289 glib/gkeyfile.c:3353 glib/gkeyfile.c:3483 +#: glib/gkeyfile.c:3615 glib/gkeyfile.c:3761 glib/gkeyfile.c:3996 glib/gkeyfile.c:4063 +#, fuzzy, c-format +#| msgid "Key file does not have group '%s'" +msgid "Key file does not have group “%sâ€" +msgstr "پروندهٔ کلید گروه «%s» را ندارد" + +#: glib/gkeyfile.c:1791 +#, fuzzy, c-format +#| msgid "Key file does not have key '%s' in group '%s'" +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "پروندهٔ کلید، کلید «%s» در گروه «%s» را ندارد" + +#: glib/gkeyfile.c:1953 glib/gkeyfile.c:2069 +#, fuzzy, c-format +#| msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "پروندهٔ کلید حاوی کلید «%s» با مقدار «%s» است Ú©Ù‡ UTF-8 نیست" + +#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089 glib/gkeyfile.c:2531 +#, fuzzy, c-format +#| msgid "Key file contains key '%s' which has a value that cannot be interpreted." +msgid "Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "پروندهٔ کلید حاوی کلید «%s» است Ú©Ù‡ دارای مقداری است Ú©Ù‡ قابل ØªÙØ³ÛŒØ± نیست." + +#: glib/gkeyfile.c:2749 glib/gkeyfile.c:3118 +#, fuzzy, c-format +msgid "Key file contains key “%s†in group “%s†which has a value that cannot be interpreted." +msgstr "پروندهٔ کلید حاوی کلید «%s» در گروه «%s» است Ú©Ù‡ مقداری دارد Ú©Ù‡ قابل ØªÙØ³ÛŒØ± نیست" + +#: glib/gkeyfile.c:2827 glib/gkeyfile.c:2904 +#, fuzzy, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "پروندهٔ کلید حاوی کلید «%s» در گروه «%s» است Ú©Ù‡ مقداری دارد Ú©Ù‡ قابل ØªÙØ³ÛŒØ± نیست" + +#: glib/gkeyfile.c:4306 +msgid "Key file contains escape character at end of line" +msgstr "پرونده کلید شامل نویسهٔ گریز در انتهای خط است" + +#: glib/gkeyfile.c:4328 +#, fuzzy, c-format +#| msgid "Key file contains invalid escape sequence '%s'" +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "پروندهٔ کلید حاوی دنبالهٔ گریز نامعتبر «%s» است" + +#: glib/gkeyfile.c:4472 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a number." +msgid "Value “%s†cannot be interpreted as a number." +msgstr "مقدار «%s» را نمی‌توان به عدد ØªÙØ³ÛŒØ± کرد" + +#: glib/gkeyfile.c:4486 +#, fuzzy, c-format +#| msgid "Integer value '%s' out of range" +msgid "Integer value “%s†out of range" +msgstr "مقدار صحیح «%s» خارج از محدوده است" + +#: glib/gkeyfile.c:4519 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a float number." +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "مقدار «%s» را نمی‌توان به عدد اعشاری ØªÙØ³ÛŒØ± کرد" + +#: glib/gkeyfile.c:4558 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a boolean." +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "مقدار «%s» را نمی‌توان به مقدار بولی ØªÙØ³ÛŒØ± کرد" + +#: glib/gmappedfile.c:129 +#, fuzzy, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Ú¯Ø±ÙØªÙ† مشخصه‌های پروندهٔ «‎%s» شکست خورد: fstat()‎ شکست خورد: %s" + +#: glib/gmappedfile.c:195 +#, fuzzy, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "تهیهٔ نقشه از پروندهٔ «‎%s» شکست خورد: mmap()‎ شکست خورد: %s" + +#: glib/gmappedfile.c:262 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': open() failed: %s" +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "باز کردن پروندهٔ «‎%s» شکست خورد: open()‎ شکست خورد: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "خطا در سطر %Id نویسهٔ %Id:†" + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, fuzzy, c-format +#| msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "متن کدگذاری‌شدهٔ UTF-8 نامعتبر در نام - «%s» معتبر نیست" + +#: glib/gmarkup.c:473 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name " +msgid "“%s†is not a valid name" +msgstr "نام «%s» معتبر نیست" + +#: glib/gmarkup.c:489 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name: '%c' " +msgid "“%s†is not a valid name: “%câ€" +msgstr "نام «%s» معتبر نیست: «%c»" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "خطا در سطر %Id:†%s" + +#: glib/gmarkup.c:690 +#, fuzzy, c-format +#| msgid "" +#| "Failed to parse '%-.*s', which should have been a digit inside a character reference (ê for " +#| "example) - perhaps the digit is too large" +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character reference (ê for example) " +"— perhaps the digit is too large" +msgstr "" +"تجزیهٔ «‎%-.*s»، Ú©Ù‡ باید رقمی داخل یک ارجاع نویسه‌ای (مثل ‎ê‎) می‌بود شکست خورد - شاید رقم خیلی بزرگ است" + +#: glib/gmarkup.c:702 +#, fuzzy +#| msgid "" +#| "Character reference did not end with a semicolon; most likely you used an ampersand character without " +#| "intending to start an entity - escape ampersand as &" +msgid "" +"Character reference did not end with a semicolon; most likely you used an ampersand character without " +"intending to start an entity — escape ampersand as &" +msgstr "" +"ارجاع نویسه‌ای با نقطه‌ویرگول تمام نشده است؛ به احتمال زیاد بدون این Ú©Ù‡ بخواهید نهادی را آغاز کنید از نویسهٔ " +"& Ø§Ø³ØªÙØ§Ø¯Ù‡ کرده‌اید - برای نوشتن علامت & از ‎&‎ Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید" + +#: glib/gmarkup.c:728 +#, fuzzy, c-format +#| msgid "Character reference '%-.*s' does not encode a permitted character" +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "ارجاع نویسه‌ای «‎%-.*s» به نویسهٔ مجاز اشاره نمی‌کند" + +#: glib/gmarkup.c:766 +#, fuzzy +#| msgid "Empty entity '&;' seen; valid entities are: & " < > '" +msgid "Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "نهاد خالی «‎&;‎» مشاهده شد؛ نهادهای معتبر عبارتند از: ‎& " < > '‎" + +#: glib/gmarkup.c:774 +#, fuzzy, c-format +#| msgid "Entity name '%-.*s' is not known" +msgid "Entity name “%-.*s†is not known" +msgstr "نام نهاد «%-.*s» شناخته شده نیست" + +#: glib/gmarkup.c:779 +#, fuzzy +#| msgid "" +#| "Entity did not end with a semicolon; most likely you used an ampersand character without intending to " +#| "start an entity - escape ampersand as &" +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand character without intending to " +"start an entity — escape ampersand as &" +msgstr "" +"نهاد با یک نقطه‌ویرگول لاتین تمام نشده است؛ به احتمال زیاد بدون این Ú©Ù‡ بخواهید نهادی را آغاز کنید از نویسهٔ " +"& Ø§Ø³ØªÙØ§Ø¯Ù‡ کرده‌اید - برای نوشتن علامت & از ‎&‎ Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "نوشتار باید با یک عنصر (مثلاً ) شروع شود" + +#: glib/gmarkup.c:1233 +#, fuzzy, c-format +#| msgid "'%s' is not a valid character following a '<' character; it may not begin an element name" +msgid "“%s†is not a valid character following a “<†character; it may not begin an element name" +msgstr "â€Â«%s» پس از یک نویسهٔ '‎<‎' نویسهٔ مجازی نیست؛ نمی‌شود ابتدای نام یک عنصر باشد" + +#: glib/gmarkup.c:1276 +#, fuzzy, c-format +#| msgid "Odd character '%s', expected a '>' character to end the empty-element tag '%s'" +msgid "Odd character “%sâ€, expected a “>†character to end the empty-element tag “%sâ€" +msgstr "نویسهٔ غیرعادی «%s»، برای پایان دادن به برچسب عنصر خالی «%s» انتظار یک نویسهٔ «‎>‎» Ù…ÛŒâ€ŒØ±ÙØª" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1366 +#, fuzzy, c-format +#| msgid "Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgid "Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "نویسهٔ غیرعادی «%s»، بعد از نام مشخصهٔ «%s» عنصر «%s» انتظار یک نویسهٔ «=» Ù…ÛŒâ€ŒØ±ÙØª" + +#: glib/gmarkup.c:1408 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' or '/' character to end the start tag of element '%s', or " +#| "optionally an attribute; perhaps you used an invalid character in an attribute name" +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of element “%sâ€, or optionally " +"an attribute; perhaps you used an invalid character in an attribute name" +msgstr "" +"نویسهٔ غیرعادی «%s»، برای پایان دادن به برچسب شروع عنصر «%s»، همین‌طور یک مشخصه، انتظار یک نویسهٔ «‎>‎» یا «/» " +"Ù…ÛŒâ€ŒØ±ÙØªØ› شاید از یک نویسهٔ نامعتبر در نام مشخصه‌ای Ø§Ø³ØªÙØ§Ø¯Ù‡ کرده باشید" + +#: glib/gmarkup.c:1453 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected an open quote mark after the equals sign when giving value for attribute " +#| "'%s' of element '%s'" +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when giving value for attribute " +"“%s†of element “%sâ€" +msgstr "" +"نویسهٔ غیرعادی «%s»، هنگام مقدار دادن به مشخصهٔ «%s» از عنصر «%s» پس از علامت تساوی انتظار یک علامت نقل قول " +"باز Ù…ÛŒâ€ŒØ±ÙØª" + +#: glib/gmarkup.c:1587 +#, fuzzy, c-format +#| msgid "'%s' is not a valid character following the characters ''" +msgid "“%s†is not a valid character following the close element name “%sâ€; the allowed character is “>â€" +msgstr "â€Â«%s» نویسهٔ معتبری برای بستن نام عنصر «%s» نیست؛ نویسهٔ مجاز «‎>» است" + +#: glib/gmarkup.c:1637 +#, fuzzy, c-format +#| msgid "Element '%s' was closed, no element is currently open" +msgid "Element “%s†was closed, no element is currently open" +msgstr "عنصر «%s» بسته بود، در حال حاضر هیچ عنصری باز نیست" + +#: glib/gmarkup.c:1646 +#, fuzzy, c-format +#| msgid "Element '%s' was closed, but the currently open element is '%s'" +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "عنصر «%s» بسته بود، ولی عنصری Ú©Ù‡ در حال حاضر باز است «%s» است" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "نوشتار خالی است یا Ùقط ÙØ§ØµÙ„Ù‡Ù” خالی دارد" + +#: glib/gmarkup.c:1813 +#, fuzzy +#| msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "نوشتار به‌طور غیرمنتظره‌ای درست بعد از یک علامت کوچکتر '‎<‎' پایان ÛŒØ§ÙØª" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, fuzzy, c-format +#| msgid "Document ended unexpectedly with elements still open - '%s' was the last element opened" +msgid "Document ended unexpectedly with elements still open — “%s†was the last element opened" +msgstr "نوشتار وقتی Ú©Ù‡ هنوز عناصری باز بودند به‌طور غیرمنتظره‌ای پایان ÛŒØ§ÙØª †آخرین عنصر باز شده «%s» بود" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "Document ended unexpectedly, expected to see a close angle bracket ending the tag <%s/>" +msgstr "نوشتار به‌طور غیرمنتظره‌ای پایان ÛŒØ§ÙØªØŒ یک علامت بزرگتر برای بستن برچسب ‎<%s/>‎ انتظار Ù…ÛŒâ€ŒØ±ÙØª" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "نوشتار به‌طور غیرمنتظره‌ای داخل نام یک عنصر به‌پایان رسید" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "نوشتار به‌طور غیرمنتظره‌ای داخل نام یک مشخصه به‌پایان رسید" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "نوشتار به‌طور غیرمنتظره‌ای داخل یک برچسب عنصربازکن پایان ÛŒØ§ÙØª." + +#: glib/gmarkup.c:1852 +msgid "Document ended unexpectedly after the equals sign following an attribute name; no attribute value" +msgstr "" +"نوشتار به‌طور غیرمنتظره‌ای بعد از علامت تساوی‌ای Ú©Ù‡ پس از نام مشخصه‌ای آمده بود تمام شد؛ بدون مقدار برای مشخصه" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "نوشتار به‌طور غیرمنتظره‌ای داخل مقدار یک مشخصه به‌پایان رسید" + +#: glib/gmarkup.c:1876 +#, fuzzy, c-format +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "نوشتار به‌طور غیرمنتظره‌ای داخل برچسب بستن عنصر «%s» پایان ÛŒØ§ÙØª" + +#: glib/gmarkup.c:1880 +#, fuzzy +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for an unopened element" +msgstr "نوشتار به‌طور غیرمنتظره‌ای داخل برچسب بستن عنصر «%s» پایان ÛŒØ§ÙØª" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "نوشتار به‌طور غیرمنتظره‌ای داخل یک توضیح یا دستورالعمل پردازشی پایان ÛŒØ§ÙØª" + +#: glib/goption.c:873 +#, fuzzy +#| msgid "[OPTION...]" +msgid "[OPTION…]" +msgstr "[گزینه...]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "گزینه‌های راهنما:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "نمایش گزینه‌های راهنما" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "نمایش همهٔ گزینه‌های راهنما" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "گزینه‌های برنامه:" + +#: glib/goption.c:1061 +#, fuzzy +#| msgid "Help Options:" +msgid "Options:" +msgstr "گزینه‌های راهنما:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, fuzzy, c-format +#| msgid "Cannot parse integer value '%s' for %s" +msgid "Cannot parse integer value “%s†for %s" +msgstr "نمی‌توان مقدار صحیح «%s» برای %s را تجزیه کرد" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, fuzzy, c-format +#| msgid "Integer value '%s' for %s out of range" +msgid "Integer value “%s†for %s out of range" +msgstr "مقدار صحیح «%s» خارج از محدودهٔ %s است" + +#: glib/goption.c:1160 +#, fuzzy, c-format +#| msgid "Cannot parse double value '%s' for %s" +msgid "Cannot parse double value “%s†for %s" +msgstr "نمی‌توان مقدار صحیح با دقت مضاع٠«%s» برای %s را تجزیه کرد" + +#: glib/goption.c:1168 +#, fuzzy, c-format +#| msgid "Double value '%s' for %s out of range" +msgid "Double value “%s†for %s out of range" +msgstr "مقدار صحیح با دقت مضاع٠«%s» خارج از محدودهٔ %s است" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "خطا در تجزیهٔ گزینهٔ %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "â€%s یک آرگومان Ú©Ù… دارد" + +#: glib/goption.c:2185 +#, c-format +msgid "Unknown option %s" +msgstr "گزینهٔ نامعلوم %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "شیء ناقص" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "خطا داخلی یا شیء ناقص" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "Ø­Ø§ÙØ¸Ù‡ Ú©Ù… است" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "محدودیت backtracking ÙØ±Ø§Ø±Ø³ÛŒØ¯" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "الگو حاوی مواردی است Ú©Ù‡ برای مطابقت جزئی مناسب نیست" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "خطا داخلی" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "محدودیت تکرار ÙØ±Ø§Ø±Ø³ÛŒØ¯" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "ترکیب نادرست پرچم‌های خط جدید" + +#: glib/gregex.c:299 +#, fuzzy +msgid "bad offset" +msgstr "Ø§ÙØ³Øª نادرست" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 کوتاه" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "خطا نادرست" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ در پایان الگو" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c در پایان الگو" + +#: glib/gregex.c:333 +#, fuzzy +#| msgid "unrecognized character follows \\" +msgid "unrecognized character following \\" +msgstr "نویسه ناشناخته پس از \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "اعداد بدون ترتیل در کمیت‌سنج {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "اعداد در کمیت‌سنج {} بسیار بزرگ هستند" + +#: glib/gregex.c:342 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "کانال با یک نویسهٔ ناتمام پایان می‌یابد" + +#: glib/gregex.c:345 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "دنبالهٔ بایتی نامعتبر در ورودی تبدیل" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "محدوده در کلاس نویسه بدون ترتیب است" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "چیزی برای تکرار نیست" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "تکرار غیرمنتظره" + +#: glib/gregex.c:358 +#, fuzzy +#| msgid "unrecognized character after (?" +msgid "unrecognized character after (? or (?-" +msgstr "نویسه ناشناس بعد از (?" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "" + +#: glib/gregex.c:373 +#, fuzzy +#| msgid "regular expression too large" +msgid "regular expression is too large" +msgstr "عبارت باقاعده بسیار بلند است" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "Ú¯Ø±ÙØªÙ† Ø­Ø§ÙØ¸Ù‡ شکست خورد" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "نویسه ناشناس بعد از (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "نام کلاس POSIX ناشناخته" + +#: glib/gregex.c:413 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "پیوندهای نمادی پشتیبانی نمی‌شوند" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "نویسه ناشناس بعد از (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "خصیصه‌ی ناشناس پس از \\P یا \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: glib/gregex.c:474 +msgid "\\g is not followed by a braced, angle-bracketed, or quoted name or number, or by a plain number" +msgstr "" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "" + +#: glib/gregex.c:493 +#, fuzzy +#| msgid "digit expected" +msgid "digit expected after (?+" +msgstr "انتظار رقم Ù…ÛŒâ€ŒØ±ÙØª" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: glib/gregex.c:511 +#, fuzzy +#| msgid "URIs not supported" +msgid "\\N is not supported in a class" +msgstr "آدرس‌ها پشتیبانی نمی‌شود" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "خطا در هنگام منطبق کردن عبارت باقاعده %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "کتابخانه PCRE بدون پشتیبانی از UTF8 کامپایل شده است" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "کتابخانه PCRE بدون پشتیبانی از گزینه‌های UTF8 کامپایل شده است" + +#: glib/gregex.c:1333 +#, fuzzy +#| msgid "PCRE library is compiled without UTF8 properties support" +msgid "PCRE library is compiled with incompatible options" +msgstr "کتابخانه PCRE بدون پشتیبانی از گزینه‌های UTF8 کامپایل شده است" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "خطا در هنگام بهینه کردن عبارت باقاعده %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "خطا در هنگام کامپایل عبارت با قاعده %s در نویسه %Id: %s" + +#: glib/gregex.c:2427 +#, fuzzy +#| msgid "hexadecimal digit or '}' expected" +msgid "hexadecimal digit or “}†expected" +msgstr "رقم هگزادسیمال یا «}» مورد انتظار بود" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "رقم هگزادسیمال مورد انتظار بود" + +#: glib/gregex.c:2483 +#, fuzzy +#| msgid "unfinished symbolic reference" +msgid "missing “<†in symbolic reference" +msgstr "ارجاع نمادین ناتمام" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "ارجاع نمادین ناتمام" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "انتظار رقم Ù…ÛŒâ€ŒØ±ÙØª" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "ارجاع نمادین غیرقانونی" + +#: glib/gregex.c:2591 +#, fuzzy +#| msgid "stray final '\\'" +msgid "stray final “\\â€" +msgstr "«\\» پایانی سرگردان" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "" + +#: glib/gregex.c:2605 +#, fuzzy, c-format +#| msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "خطا در هنگام تجزیه کردن متن جایگزین «%s» در نویسه %lu: %s" + +#: glib/gshell.c:94 +#, fuzzy +#| msgid "Quoted text doesn't begin with a quotation mark" +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "متن نقل شده با علامت نقل قول شروع نمی‌شود" + +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "علامت نقل قول تکی در سطر دستور یا متون داخل پوستهٔ دیگر" + +#: glib/gshell.c:580 +#, fuzzy, c-format +#| msgid "Text ended just after a '\\' character. (The text was '%s')" +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "متن دقیقاً پس از یک نویسهٔ «\\» پایان ÛŒØ§ÙØª. (متن عبارت بود از «%s»)" + +#: glib/gshell.c:587 +#, fuzzy, c-format +#| msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "متن پیش از آن Ú©Ù‡ علامت نقل قول متناظر برای %c پیدا شود پایان ÛŒØ§ÙØª. (متن عبارت بود از «%s»)" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "متن خالی بود (یا Ùقط ÙØ§ØµÙ„Ù‡Ù” خالی داشت)" + +#: glib/gspawn.c:308 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "خواندن داده‌ها از ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ شکست خورد (%s)" + +#: glib/gspawn.c:458 +#, fuzzy, c-format +#| msgid "Unexpected error in select() reading data from a child process (%s)" +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "خطای غیرمنتظره در select()‎ هنگام خواندن داده‌ها از یک ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ (%s)" + +#: glib/gspawn.c:543 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "خطای غیرمنتظره در waitpid()‎ â€(%s)" + +#: glib/gspawn.c:1152 glib/gspawn-win32.c:1407 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: glib/gspawn.c:1160 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: glib/gspawn.c:1167 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: glib/gspawn.c:1174 +#, c-format +msgid "Child process exited abnormally" +msgstr "" + +#: glib/gspawn.c:1793 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "خواندن از لولهٔ ÙØ±Ø²Ù†Ø¯ شکست خورد (%s)" + +#: glib/gspawn.c:2095 +#, fuzzy, c-format +#| msgid "Failed to fork child process (%s)" +msgid "Failed to spawn child process “%s†(%s)" +msgstr "انشعاب ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ شکست خورد (%s)" + +#: glib/gspawn.c:2212 +#, c-format +msgid "Failed to fork (%s)" +msgstr "انشعاب شکست خورد (%s)" + +#: glib/gspawn.c:2372 glib/gspawn-win32.c:381 +#, fuzzy, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to change to directory “%s†(%s)" +msgstr "تغییر به شاخهٔ «%s» شکست خورد (%s)" + +#: glib/gspawn.c:2382 +#, fuzzy, c-format +#| msgid "Failed to execute child process \"%s\" (%s)" +msgid "Failed to execute child process “%s†(%s)" +msgstr "اجرای ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ «%s» شکست خورد (%s)" + +#: glib/gspawn.c:2392 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "تغییر مسیر خروجی یا ورودی ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ شکست خورد (%s)" + +#: glib/gspawn.c:2401 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "انشعاب ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ شکست خورد (%s)" + +#: glib/gspawn.c:2409 +#, fuzzy, c-format +#| msgid "Unknown error executing child process \"%s\"" +msgid "Unknown error executing child process “%sâ€" +msgstr "خطای ناشناخته هنگام اجرای ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ «%s»" + +#: glib/gspawn.c:2433 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "خواندن دادهٔ کاÙÛŒ از لولهٔ pid ÙØ±Ø²Ù†Ø¯ شکست خورد (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "خواندن داده‌ها از ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ شکست خورد" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ایجاد لوله برای ارتباط با ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ شکست خورد (%s)" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "اجرای ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯ شکست خورد (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "نام برنامهٔ نامعتبر: %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:779 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "رشتهٔ نامعتبر در بردار آرگومان درآیهٔ %Id: %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:794 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "رشتهٔ نامعتبر در محیط: %s" + +#: glib/gspawn-win32.c:775 +#, c-format +msgid "Invalid working directory: %s" +msgstr "شاخهٔ کاری نامعتبرâ€: %s" + +#: glib/gspawn-win32.c:837 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "اجرای برنامهٔ راهنما (‎%s) شکست خورد" + +#: glib/gspawn-win32.c:1064 +msgid "Unexpected error in g_io_channel_win32_poll() reading data from a child process" +msgstr "خطای غیرمنتظره در g_io_channel_win32_poll()‎ هنگام خواندن داده‌ها از یک ÙØ±Ø§Ø±ÙˆÙ†Ø¯ ÙØ±Ø²Ù†Ø¯" + +#: glib/gstrfuncs.c:3338 glib/gstrfuncs.c:3440 +msgid "Empty string is not a number" +msgstr "" + +#: glib/gstrfuncs.c:3362 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name " +msgid "“%s†is not a signed number" +msgstr "نام «%s» معتبر نیست" + +#: glib/gstrfuncs.c:3372 glib/gstrfuncs.c:3476 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: glib/gstrfuncs.c:3466 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name " +msgid "“%s†is not an unsigned number" +msgstr "نام «%s» معتبر نیست" + +#: glib/guri.c:315 +#, fuzzy, no-c-format +#| msgid " (invalid encoding)" +msgid "Invalid %-encoding in URI" +msgstr " (کدگذاری نامعتبر)" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, fuzzy, c-format +#| msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgid "URI ‘%s’ is not an absolute URI" +msgstr "نشانی «‎%s» یک نشانی اینترنتی مطلق با Ø´Ùمای «پرونده» نیست" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "" + +#: glib/guri.c:1435 +msgid "URI is not absolute, and no base URI was provided" +msgstr "" + +#: glib/guri.c:2213 +msgid "Missing ‘=’ and parameter value" +msgstr "" + +#: glib/gutf8.c:817 +#, fuzzy +#| msgid "failed to get memory" +msgid "Failed to allocate memory" +msgstr "Ú¯Ø±ÙØªÙ† Ø­Ø§ÙØ¸Ù‡ شکست خورد" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "نویسهٔ خارج از محدوده برای UTF-8" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 glib/gutf8.c:1338 +#: glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "دنبالهٔ نامعتبر در ورودی تبدیل" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "نویسهٔ خارج از محدوده برای UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2727 +#, c-format +msgid "%.1f kB" +msgstr "%I.1f کیلوبایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2729 +#, c-format +msgid "%.1f MB" +msgstr "%I.1f مگابایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2731 +#, c-format +msgid "%.1f GB" +msgstr "%I.1f گیگابایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2733 +#, c-format +msgid "%.1f TB" +msgstr "%I.1f ترابایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2735 +#, c-format +msgid "%.1f PB" +msgstr "%I.1f پتابایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2737 +#, c-format +msgid "%.1f EB" +msgstr "%I.1f اگزابایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2741 +#, c-format +msgid "%.1f KiB" +msgstr "%I.1f کیبی‌بایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2743 +#, c-format +msgid "%.1f MiB" +msgstr "%I.1f مبی‌بایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2745 +#, c-format +msgid "%.1f GiB" +msgstr "%I.1f گیبی‌بایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2747 +#, c-format +msgid "%.1f TiB" +msgstr "%I.1f تبی‌بایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2749 +#, c-format +msgid "%.1f PiB" +msgstr "%I.1f پبی‌بایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2751 +#, c-format +msgid "%.1f EiB" +msgstr "%I.1f اگزبی‌بایت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2755 +#, c-format +msgid "%.1f kb" +msgstr "%I.1f کیلوبیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2757 +#, c-format +msgid "%.1f Mb" +msgstr "%I.1f مگابیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2759 +#, c-format +msgid "%.1f Gb" +msgstr "%I.1f گیگابیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2761 +#, c-format +msgid "%.1f Tb" +msgstr "%I.1f ترابیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2763 +#, c-format +msgid "%.1f Pb" +msgstr "%I.1f پتابیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2765 +#, c-format +msgid "%.1f Eb" +msgstr "%I.1f اگزابیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2769 +#, c-format +msgid "%.1f Kib" +msgstr "%I.1f کیبی‌بیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2771 +#, c-format +msgid "%.1f Mib" +msgstr "%I.1f مبی‌بیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2773 +#, c-format +msgid "%.1f Gib" +msgstr "%I.1f گیبی‌بیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2775 +#, c-format +msgid "%.1f Tib" +msgstr "%I.1f تبی‌بیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2777 +#, c-format +msgid "%.1f Pib" +msgstr "%I.1f پبی‌بیت" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2779 +#, c-format +msgid "%.1f Eib" +msgstr "%I.1f اگزبی‌بیت" + +#: glib/gutils.c:2813 glib/gutils.c:2930 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%Iu بایت" +msgstr[1] "%Iu بایت" + +#: glib/gutils.c:2817 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%Iu بیت" +msgstr[1] "%Iu بیت" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2884 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s بایت" +msgstr[1] "%s بایت" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2889 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s بیت" +msgstr[1] "%s بیت" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2943 +#, c-format +msgid "%.1f KB" +msgstr "%I.1f کیلوبایت" + +#: glib/gutils.c:2948 +#, c-format +msgid "%.1f MB" +msgstr "%I.1f مگابایت" + +#: glib/gutils.c:2953 +#, c-format +msgid "%.1f GB" +msgstr "%I.1f گیگابایت" + +#: glib/gutils.c:2958 +#, c-format +msgid "%.1f TB" +msgstr "%I.1f ترابایت" + +#: glib/gutils.c:2963 +#, c-format +msgid "%.1f PB" +msgstr "%I.1f پتابایت" + +#: glib/gutils.c:2968 +#, c-format +msgid "%.1f EB" +msgstr "%I.1f اگزابایت" + +#~ msgid "doing nothing.\n" +#~ msgstr "هیچ‌کاری انجام نمی‌شود.\n" + +#~ msgid "Error renaming file: %s" +#~ msgstr "خطا در تغییر نام پرونده: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "خطا در هنگام باز کردن پرونده: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "خطا در هنگام ساخت شاخه: %s" + +#~ msgid "Unknown error on connect" +#~ msgstr "خطا ناشناخته در اتصال" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "ساخت ارتباط بر روی win32 پشتیبانی نمی‌شود" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "باز کردن پروندهٔ «‎%s» برای نوشتن شکست خورد: fdopen()‎ شکست خورد: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "نوشتن پروندهٔ «‎%s» شکست خورد: fflush()‎ شکست خورد: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "بستن پروندهٔ «‎%s» شکست خورد: fclose()‎ شکست خورد: %s" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "پروندهٔ کلید، کلید «%s» را ندارد" + +#~ msgid "File is empty" +#~ msgstr "پرونده خالی است" + +#~ msgid "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "پروندهٔ کلید حاوی کلید «%s» است Ú©Ù‡ مقداری دارد Ú©Ù‡ قابل ØªÙØ³ÛŒØ± نیست." + +#, fuzzy +#~ msgid "Error stating file '%s': %s" +#~ msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#~ msgid "Error connecting: " +#~ msgstr "خطا در هنگام برقراری ارتباط" + +#~ msgid "Error connecting: %s" +#~ msgstr "خطا در هنگام برقراری ارتباط: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "خطا در خواندن از یونیکس: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "خطا در هنگام بستن یونیکس: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "خطا در زمان نوشتن در یونیکس: %s" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "دنبالهٔ نامعتبر در ورودی تبدیل" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & character begins an entity; if this " +#~ "ampersand isn't supposed to be an entity, escape it as &" +#~ msgstr "" +#~ "نویسهٔ «%s» در ابتدای نام نهادها مجاز نیست؛ نویسهٔ & نهاد را آغاز می‌کند؛ اگر این علامت & قرار نیست نهاد " +#~ "شود، به‌جای آن از ‎&‎ Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "ارجاع نویسه‌ای خالی؛ باید یک رقم داشته باشد، مثل ‎dž‎" + +#~ msgid "Unfinished entity reference" +#~ msgstr "ارجاع نهادی ناتمام" + +#~ msgid "Unfinished character reference" +#~ msgstr "ارجاع نویسه‌ای ناتمام" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "متن کدگذاری‌شدهٔ UTF-8 نامعتبر" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "متن کدگذاری‌شدهٔ UTF-8 نامعتبر" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "نام میزبان نشانی اینترنتی «‎%s» نامعتبر است" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "خطا در خواندن پروندهٔ «‎%s»â€: %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "خطا در تجزیهٔ گزینهٔ %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "باز کردن پروندهٔ «%s» شکست خورد: fdopen()‎ شکست خورد: %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "باز کردن پروندهٔ «%s» شکست خورد: fdopen()‎ شکست خورد: %s" + +#~ msgid "Incorrect message size" +#~ msgstr "اندازهٔ پیغام نادرست است" + +#~ msgid "Socket error" +#~ msgstr "خطای سوکت" + +#~ msgid "Channel set flags unsupported" +#~ msgstr "نشان‌های تنظیم‌شده توسط کانال، پشتیبانی نمی‌شوند" diff --git a/po/fi.po b/po/fi.po new file mode 100644 index 0000000..678a36c --- /dev/null +++ b/po/fi.po @@ -0,0 +1,6861 @@ +# Finnish messages for glib. +# Copyright © 2009 Free Software Foundation, Inc. +# Lauri Nurmi , 2002-2004, +# Sami Pesonen , 2004-2005. +# Ilkka Tuohela , 2005-2009. +# Timo Jyrinki , 2008-2010. +# Harri Pitkänen , 2009. +# Tommi Vainikainen , 2009-2011. +# +# Sanasto: +# D-Bus-metodin â€signature†= tyyppimääritys +# +# Gnome 2012-03 Finnish translation sprint participants: +# Flammie Pirinen +# Niklas Laxström +# Jiri Grönroos , 2015, 2016, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2021-03-09 12:50+0000\n" +"PO-Revision-Date: 2021-03-13 14:38+0200\n" +"Last-Translator: Jiri Grönroos \n" +"Language-Team: suomi \n" +"Language: fi\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-POT-Import-Date: 2012-03-05 14:50:02+0000\n" +"X-Generator: Poedit 2.4.2\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication-valitsimet" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Näytä GApplication-valitsimet" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" + +#: gio/gapplication.c:557 +#, fuzzy +#| msgid "Can't find application" +msgid "Override the application’s ID" +msgstr "Ohjelmaa ei löydy" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:493 gio/gsettings-tool.c:567 +msgid "Print help" +msgstr "Tulosta ohje" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:494 gio/gresource-tool.c:562 +msgid "[COMMAND]" +msgstr "[KOMENTO]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Tulosta versio" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:573 +msgid "Print version information and exit" +msgstr "Tulosta ohjelman versio ja poistu" + +#: gio/gapplication-tool.c:53 +#, fuzzy +#| msgid "Can't find application" +msgid "List applications" +msgstr "Ohjelmaa ei löydy" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Käynnistä sovellus" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktivoi toiminto" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMENTO" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:500 gio/gresource-tool.c:566 +msgid "FILE" +msgstr "TIEDOSTO" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "TOIMINTO" + +#: gio/gapplication-tool.c:75 +#, fuzzy +#| msgid "Destination name to introspect" +msgid "The action name to invoke" +msgstr "Kohdenimi joka katsastetaan" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:531 gio/gsettings-tool.c:659 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Tuntematon komento %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Käyttö:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:556 +#: gio/gsettings-tool.c:694 +msgid "Arguments:\n" +msgstr "Argumentit:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Komennot:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:173 +#, fuzzy, c-format +#| msgid "invalid GVariant type string '%s'" +msgid "invalid application id: “%sâ€\n" +msgstr "virheellinen GVariant-tyyppimerkkijono â€%sâ€" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:268 +#, fuzzy, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "Muunninta merkistöstä â€%s†merkistöön â€%s†ei voitu avata: %s" + +#: gio/gapplication-tool.c:288 +#, fuzzy, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "Virhe lähetettäessä viestiä: %s" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" + +#: gio/gapplication-tool.c:346 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "Virhe jäsennettäessä parametriä %d: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "" + +#: gio/gapplication-tool.c:423 +#, fuzzy, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "Sovelluksen vaatimaa päätettä ei löydy" + +#: gio/gapplication-tool.c:468 +#, fuzzy, c-format +#| msgid "" +#| "Unknown command %s\n" +#| "\n" +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"Tuntematon komento %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:646 +#: gio/ginputstream.c:1048 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Liian suuri laskuriarvo välitetty kohteelle %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +#, fuzzy +#| msgid "Seek not supported on stream" +msgid "Seek not supported on base stream" +msgstr "Virta ei tue siirtymistä" + +#: gio/gbufferedinputstream.c:938 +#, fuzzy +#| msgid "Cannot truncate GMemoryInputStream" +msgid "Cannot truncate GBufferedInputStream" +msgstr "GMemoryInputStream-kohdetta ei voi kutistaa" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1237 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Virta on jo suljettu" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +#, fuzzy +#| msgid "Truncate not supported on stream" +msgid "Truncate not supported on base stream" +msgstr "Virta ei tue kutistamista" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1872 gio/gdbusprivate.c:1416 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Toiminto oli peruttu" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Virheellinen olio, alustamaton" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Virheellinen monitavusarja syötteessä" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Kohteessa ei ole tarpeeksi tilaa" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:448 glib/gconvert.c:878 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "Virheellinen tavusarja muunnettavassa syötteessä" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:456 glib/gconvert.c:792 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Virhe muunnoksen aikana: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1143 +msgid "Cancellable initialization not supported" +msgstr "Keskeytyskelpoinen alustus ei ole tuettu" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:321 glib/giochannel.c:1401 +#, fuzzy, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Muunnos merkistöstä â€%s†merkistöön â€%s†ei ole tuettu" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:325 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Muunninta merkistöstä â€%s†merkistöön â€%s†ei voitu avata" + +#: gio/gcontenttype.c:454 +#, c-format +msgid "%s type" +msgstr "%s-tyyppi" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Tuntematon tyyppi" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s-tiedostotyyppi" + +#: gio/gcredentials.c:323 +msgid "GCredentials contains invalid data" +msgstr "" + +#: gio/gcredentials.c:383 gio/gcredentials.c:667 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials ei ole toteutettu tälle käyttöjärjestelmälle" + +#: gio/gcredentials.c:538 gio/gcredentials.c:556 +msgid "There is no GCredentials support for your platform" +msgstr "Alustallesi ei ole GCredentials-tukea" + +#: gio/gcredentials.c:607 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials ei ole toteutettu tälle käyttöjärjestelmälle" + +#: gio/gcredentials.c:661 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "GCredentials ei ole toteutettu tälle käyttöjärjestelmälle" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Odottamaton aikainen virran loppu" + +#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322 +#, fuzzy, c-format +#| msgid "Unsupported key '%s' in address entry '%s'" +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Ei-tuettu avain â€%s†osoitekentässä â€%sâ€" + +#: gio/gdbusaddress.c:172 +#, fuzzy, c-format +#| msgid "Meaningless key/value pair combination in address entry '%s'" +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Merkityksetön avain/arvo-pariyhdistelmä osoitekentässä â€%sâ€" + +#: gio/gdbusaddress.c:181 +#, fuzzy, c-format +#| msgid "" +#| "Address '%s' is invalid (need exactly one of path, tmpdir or abstract " +#| "keys)" +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Osoite â€%s†on virheellinen (pitää olla täsmälleen näistä: yksi polku, " +"tilapäishakemisto tai abstraktit avaimet)" + +#: gio/gdbusaddress.c:248 gio/gdbusaddress.c:259 gio/gdbusaddress.c:274 +#: gio/gdbusaddress.c:337 gio/gdbusaddress.c:348 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the port attribute is malformed" +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Virhe osoitteessa â€%s†- porttiattribuutti on epämuodostunut" + +#: gio/gdbusaddress.c:418 gio/gdbusaddress.c:682 +#, fuzzy, c-format +#| msgid "Unknown or unsupported transport '%s' for address '%s'" +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Tuntematon tai ei-tuettu siirtotapa â€%s†osoitteelle â€%sâ€" + +#: gio/gdbusaddress.c:462 +#, fuzzy, c-format +#| msgid "Address element '%s', does not contain a colon (:)" +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Osoite-elementti â€%s†ei sisällä kaksoispistettä (:)" + +#: gio/gdbusaddress.c:471 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:492 +#, fuzzy, c-format +#| msgid "" +#| "Key/Value pair %d, '%s', in address element '%s', does not contain an " +#| "equal sign" +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Avain/Arvo-pari %d, â€%s†osoite-elementissä â€%s\" ei sisällä " +"yhtäsuuruusmerkkiä" + +#: gio/gdbusaddress.c:503 +#, fuzzy, c-format +#| msgid "" +#| "Key/Value pair %d, '%s', in address element '%s', does not contain an " +#| "equal sign" +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Avain/Arvo-pari %d, â€%s†osoite-elementissä â€%s\" ei sisällä " +"yhtäsuuruusmerkkiä" + +#: gio/gdbusaddress.c:517 +#, fuzzy, c-format +#| msgid "" +#| "Error unescaping key or value in Key/Value pair %d, '%s', in address " +#| "element '%s'" +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Virhe ohjausmerkeissä avaimessa tai arvossa Avain/Arvo-parissa %d, â€%s†" +"osoite-elementissä â€%sâ€" + +#: gio/gdbusaddress.c:589 +#, fuzzy, c-format +#| msgid "" +#| "Error in address '%s' - the unix transport requires exactly one of the " +#| "keys 'path' or 'abstract' to be set" +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Virhe osoitteessa â€%s†- unix-liikenne vaatii täsmälleen yhden avaimista " +"â€path†tai â€abstract†asetettuksi" + +#: gio/gdbusaddress.c:625 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the host attribute is missing or malformed" +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Virhe osoitteessa â€%s†- konenimiattribuutti puuttuu tai on epämuodostunut" + +#: gio/gdbusaddress.c:639 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the port attribute is missing or malformed" +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Virhe osoitteessa â€%s†- porttiattribuutti puuttuu tai on epämuodostunut" + +#: gio/gdbusaddress.c:653 +#, fuzzy, c-format +#| msgid "" +#| "Error in address '%s' - the noncefile attribute is missing or malformed" +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Virhe osoitteessa â€%s†- kertakäyttötiedostoattribuutti puuttuu tai on " +"epämuodostunut" + +#: gio/gdbusaddress.c:674 +msgid "Error auto-launching: " +msgstr "Virhe automaattikäynnistyksessä: " + +#: gio/gdbusaddress.c:727 +#, fuzzy, c-format +#| msgid "Error opening nonce file '%s': %s" +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Virhe avattaessa kertakäyttölukujen tiedostoa â€%sâ€: %s" + +#: gio/gdbusaddress.c:746 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s': %s" +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Virhe kertakäyttölukujen tiedoston â€%s†lukemisessa: %s" + +#: gio/gdbusaddress.c:755 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Virhe kertakäyttölukujen tiedoston â€%s†lukemisessa, odotettiin 16 tavua, " +"saatiin %d" + +#: gio/gdbusaddress.c:773 +#, fuzzy, c-format +#| msgid "Error writing contents of nonce file '%s' to stream:" +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Virhe kirjoitettaessa kertakäyttölukujen tiedoston â€%s†sisältöä virtaan:" + +#: gio/gdbusaddress.c:988 +msgid "The given address is empty" +msgstr "Annettu osoite on tyhjä" + +#: gio/gdbusaddress.c:1101 +#, fuzzy, c-format +#| msgid "Cannot spawn a message bus without a machine-id: " +msgid "Cannot spawn a message bus when setuid" +msgstr "Ei voida käynnistää viestiväylää ilman tietokonetunnistetta: " + +#: gio/gdbusaddress.c:1108 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ei voida käynnistää viestiväylää ilman tietokonetunnistetta: " + +#: gio/gdbusaddress.c:1115 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: gio/gdbusaddress.c:1157 +#, fuzzy, c-format +#| msgid "Error spawning command line '%s': " +msgid "Error spawning command line “%sâ€: " +msgstr "Virhe käynnistettäessä komentoriviä â€%sâ€: " + +#: gio/gdbusaddress.c:1226 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Ei voi päätellä istuntoväylän osoitetta (ei toteutettu tälle " +"käyttöjärjestelmälle)" + +#: gio/gdbusaddress.c:1397 gio/gdbusconnection.c:7241 +#, fuzzy, c-format +#| msgid "" +#| "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#| "variable - unknown value '%s'" +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Ei voitu päätellä väyläosoitetta DBUS_STARTER_BUS_TYPE-ympäristömuuttujasta " +"- tuntematon arvo â€%sâ€" + +#: gio/gdbusaddress.c:1406 gio/gdbusconnection.c:7250 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ei voitu päätellä väyläosoitetta, koska DBUS_STARTER_BUS_TYPE-" +"ympäristömuuttujaa ei ole asetettu" + +#: gio/gdbusaddress.c:1416 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tuntematon väylätyyppi %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Odottamaton sisällön puute yritettäessä lukea riviä" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Odottamaton sisällön puute yritettäessä (turvallisest) lukea riviä" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Kulutettu kaikki saatavilla olevat todennusmenetelmät (kokeiltu: %s) " +"(saatavilla: %s)" + +#: gio/gdbusauth.c:1170 +msgid "User IDs must be the same for peer and server" +msgstr "" + +#: gio/gdbusauth.c:1182 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" +"Peruutus kohteen GDBusAuthObserver::authorize-authenticated-peer kautta" + +#: gio/gdbusauthmechanismsha1.c:298 +#, fuzzy, c-format +#| msgid "Error when getting information for directory '%s': %s" +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Virhe haettaessa tietoja hakemistosta â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:313 +#, fuzzy, c-format +#| msgid "" +#| "Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Hakemiston â€%s†oikeudet ovat väärät. Odotettiin oikeuksia 0700, saatiin 0%o" + +#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory “%sâ€: %s" +msgstr "Virhe luotaessa hakemistoa â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1062 gio/gfile.c:1300 +#: gio/gfile.c:1438 gio/gfile.c:1676 gio/gfile.c:1731 gio/gfile.c:1789 +#: gio/gfile.c:1873 gio/gfile.c:1930 gio/gfile.c:1994 gio/gfile.c:2049 +#: gio/gfile.c:3754 gio/gfile.c:3809 gio/gfile.c:4102 gio/gfile.c:4572 +#: gio/gfile.c:4983 gio/gfile.c:5068 gio/gfile.c:5158 gio/gfile.c:5255 +#: gio/gfile.c:5342 gio/gfile.c:5443 gio/gfile.c:8153 gio/gfile.c:8243 +#: gio/gfile.c:8327 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Toiminto ei ole tuettu" + +#: gio/gdbusauthmechanismsha1.c:402 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for reading: " +msgid "Error opening keyring “%s†for reading: " +msgstr "Virhe avattaessa avainrengasta â€%s†lukua varten: " + +#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747 +#, fuzzy, c-format +#| msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Rivi %d avainrenkaassa polussa â€%s†sisällöllä â€%s†on epämuodostunut" + +#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761 +#, fuzzy, c-format +#| msgid "" +#| "First token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Ensimmäinen sana rivillä %d avainrenkaassa polussa â€%s†sisällöllä â€%s†on " +"epämuodostunut" + +#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775 +#, fuzzy, c-format +#| msgid "" +#| "Second token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Toinen sana rivillä %d avainrenkaassa polussa â€%s†sisällöllä â€%s†on " +"epämuodostunut" + +#: gio/gdbusauthmechanismsha1.c:477 +#, fuzzy, c-format +#| msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Ei löytynyt evästettä tunnisteella %d avainrenkaasta polusta â€%sâ€" + +#: gio/gdbusauthmechanismsha1.c:523 +#, fuzzy, c-format +#| msgid "Error creating lock file '%s': %s" +msgid "Error creating lock file “%sâ€: %s" +msgstr "Virhe luotaessa lukkotiedostoa â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:587 +#, fuzzy, c-format +#| msgid "Error deleting stale lock file '%s': %s" +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Virhe poistettaessa mätää lukkotiedostoa â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:626 +#, fuzzy, c-format +#| msgid "Error closing (unlinked) lock file '%s': %s" +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Virhe suljettaessa (linkitöntä) lukkotiedostoa â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:637 +#, fuzzy, c-format +#| msgid "Error unlinking lock file '%s': %s" +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Virhe epälinkitettäessä lukkotiedostoa â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:714 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for writing: " +msgid "Error opening keyring “%s†for writing: " +msgstr "Virhe avattaessa avainrengasta â€%s†kirjoitusta varten: " + +#: gio/gdbusauthmechanismsha1.c:908 +#, fuzzy, c-format +#| msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Lisäksi myös tiedoston â€%s†lukon vapauttaminen epäonnistui: %s) " + +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2405 +msgid "The connection is closed" +msgstr "Yhteys on suljettu" + +#: gio/gdbusconnection.c:1902 +msgid "Timeout was reached" +msgstr "Aikakatkaisu saavutettiin" + +#: gio/gdbusconnection.c:2528 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Ei-tuettuja lippuja kohdattu muodostettaessa asiakaspuolen yhteyttä" + +#: gio/gdbusconnection.c:4186 gio/gdbusconnection.c:4533 +#, fuzzy, c-format +#| msgid "" +#| "No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "Ei rajapintaa â€org.freedesktop.DBus.Properties†oliolla polussa %s" + +#: gio/gdbusconnection.c:4328 +#, fuzzy, c-format +#| msgid "No such property '%s'" +msgid "No such property “%sâ€" +msgstr "Ei ominaisuutta â€%sâ€" + +#: gio/gdbusconnection.c:4340 +#, fuzzy, c-format +#| msgid "Property '%s' is not readable" +msgid "Property “%s†is not readable" +msgstr "Ominaisuus â€%s†ei ole luettavissa" + +#: gio/gdbusconnection.c:4351 +#, fuzzy, c-format +#| msgid "Property '%s' is not writable" +msgid "Property “%s†is not writable" +msgstr "Ominaisuus â€%s†ei ole kirjoitettavissa" + +#: gio/gdbusconnection.c:4371 +#, fuzzy, c-format +#| msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Virhe asetettaessa ominaisuutta â€%sâ€: Odotettiin tyyppiä â€%s†mutta saatiin " +"â€%sâ€" + +#: gio/gdbusconnection.c:4476 gio/gdbusconnection.c:4684 +#: gio/gdbusconnection.c:6681 +#, fuzzy, c-format +#| msgid "No such interface '%s'" +msgid "No such interface “%sâ€" +msgstr "Ei rajapintaa â€%sâ€" + +#: gio/gdbusconnection.c:4902 gio/gdbusconnection.c:7190 +#, fuzzy, c-format +#| msgid "No such interface '%s' on object at path %s" +msgid "No such interface “%s†on object at path %s" +msgstr "Ei rajapintaa â€%s†oliolla polussa %s" + +#: gio/gdbusconnection.c:5000 +#, fuzzy, c-format +#| msgid "No such key “%sâ€\n" +msgid "No such method “%sâ€" +msgstr "Ei avainta “%sâ€\n" + +#: gio/gdbusconnection.c:5031 +#, fuzzy, c-format +#| msgid "Type of message, '%s', does not match expected type '%s'" +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Viestin tyyppi â€%s†ei täsmää odotettuun tyyppiin â€%sâ€" + +#: gio/gdbusconnection.c:5229 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Olio on jo viety rajapintana %s polussa %s" + +#: gio/gdbusconnection.c:5455 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to retrieve property %s.%s" +msgstr "Pistoketta ei voi luoda: %s" + +#: gio/gdbusconnection.c:5511 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to set property %s.%s" +msgstr "Pistoketta ei voi luoda: %s" + +#: gio/gdbusconnection.c:5690 +#, fuzzy, c-format +#| msgid "Method '%s' returned type '%s', but expected '%s'" +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metodi â€%s†palautti tyypin â€%s†mutta odotettiin â€%sâ€" + +#: gio/gdbusconnection.c:6792 +#, fuzzy, c-format +#| msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metodi â€%s†rajapinnassa â€%s†tyyppimäärittelyllä â€%s†ei ole olemassa" + +#: gio/gdbusconnection.c:6913 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Alipuu on jo viety polkuun %s" + +#: gio/gdbusmessage.c:1266 +msgid "type is INVALID" +msgstr "tyyppi on VIRHEELLINEN" + +#: gio/gdbusmessage.c:1277 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL-viesti: PATH- tai MEMBER-otsakekenttä puuttuu" + +#: gio/gdbusmessage.c:1288 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN-viesti: REPLY_SERIAL-otsakekenttä puuttuu" + +#: gio/gdbusmessage.c:1300 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR-viesti: REPLY_SERIAL- tai ERROR_NAME-otsakekenttä puuttuu" + +#: gio/gdbusmessage.c:1313 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL-viesti: PATH-, INTERFACE- tai MEMBER-otsakekenttä puuttuu" + +#: gio/gdbusmessage.c:1321 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL-viesti: PATH-otsakekenttä käyttää varattua arvoa /org/freedesktop/" +"DBus/Local" + +#: gio/gdbusmessage.c:1329 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL-viesti: INTERFACE-otsakekenttä käyttää varattua arvoa org.freedesktop." +"DBus.Local" + +#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437 +#, fuzzy, c-format +#| msgid "Wanted to read %lu byte but got EOF" +#| msgid_plural "Wanted to read %lu bytes but got EOF" +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Yritettiin lukea %lu tavu, mutta saatiin tiedostonloppumerkki EOF" +msgstr[1] "Yritettiin lukea %lu tavua, mutta saatiin tiedostonloppumerkki EOF" + +#: gio/gdbusmessage.c:1391 +#, fuzzy, c-format +#| msgid "Expected NUL byte after the string '%s' but found byte %d" +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"Odotettiin NUL-tavua merkkijonon â€%s†jälkeen, mutta löydettiin tavu %d" + +#: gio/gdbusmessage.c:1410 +#, fuzzy, c-format +#| msgid "" +#| "Expected valid UTF-8 string but found invalid bytes at byte offset %d " +#| "(length of string is %d). The valid UTF-8 string up until that point was " +#| "'%s'" +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Odotettiin eheää UTF-8-merkkijonoa, mutta löydettiin virheellisiä tavuja " +"kohdassa %d (merkkijonon pituus on %d). Eheä UTF-8-merkkijono tähän kohtaan " +"saakka oli â€%sâ€" + +#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1620 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus object path" +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Jäsennetty arvo â€%s†ei ole kelvollinen D-Bus-oliopolku" + +#: gio/gdbusmessage.c:1642 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus signature" +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Jäsennetty arvo â€%s†ei ole kelvollinen D-Bus-tyyppimäärittely" + +#: gio/gdbusmessage.c:1689 +#, fuzzy, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Kohdattiin %u tavua pitkä taulukko. Pituuden yläraja on 2<<26 tavua (64 MiB)." +msgstr[1] "" +"Kohdattiin %u tavua pitkä taulukko. Pituuden yläraja on 2<<26 tavua (64 MiB)." + +#: gio/gdbusmessage.c:1709 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: gio/gdbusmessage.c:1895 +#, fuzzy, c-format +#| msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"Jäsennetty arvo â€%s†variantille ei ole kelvollinen D-Bus-tyyppimäärittely" + +#: gio/gdbusmessage.c:1936 +#, fuzzy, c-format +#| msgid "" +#| "Error deserializing GVariant with type string '%s' from the D-Bus wire " +#| "format" +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Virhe GVariantin sarjamuodon tulkinnassa tyyppikoodilla â€%s†D-Bus-" +"piuhamuodosta" + +#: gio/gdbusmessage.c:2121 +#, fuzzy, c-format +#| msgid "" +#| "Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found " +#| "value 0x%02x" +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Virheellinen tavujärjestysarvo. Odotettiin joko 0x6c (’l’) tai 0x42 (’B’) " +"mutta löydettiin arvo 0x%02x" + +#: gio/gdbusmessage.c:2134 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"Virheellinen yhteyskäytännön pääversio. Odotettiin 1 mutta löydettiin %d" + +#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2200 +#, fuzzy, c-format +#| msgid "Signature header with signature '%s' found but message body is empty" +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Tyyppimääritysotsake tyyppimäärityksellä â€%s†löydettiin mutta viestin runko " +"oli tyhjä" + +#: gio/gdbusmessage.c:2215 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Jäsennetty arvo â€%s†ei ole kelvollinen D-Bus-tyyppimäärittely (rungolle)" + +#: gio/gdbusmessage.c:2247 +#, fuzzy, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Ei tyyppimääritysotsaketta viestissä mutta viestin runko on %u tavua" +msgstr[1] "" +"Ei tyyppimääritysotsaketta viestissä mutta viestin runko on %u tavua" + +#: gio/gdbusmessage.c:2257 +msgid "Cannot deserialize message: " +msgstr "Ei voitu tulkita viestiä sarjamuodosta: " + +#: gio/gdbusmessage.c:2601 +#, fuzzy, c-format +#| msgid "" +#| "Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Virhe GVariantin sarjallistamisessa tyyppikoodilla â€%s†D-Bus-piuhamuotoon" + +#: gio/gdbusmessage.c:2738 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2746 +msgid "Cannot serialize message: " +msgstr "Ei voitu sarjallistaa viestiä: " + +#: gio/gdbusmessage.c:2799 +#, fuzzy, c-format +#| msgid "Message body has signature '%s' but there is no signature header" +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Viestin rungossa on tyyppimääritys â€%s†mutta siellä ei ole " +"tyyppimääritysotsaketta" + +#: gio/gdbusmessage.c:2809 +#, fuzzy, c-format +#| msgid "" +#| "Message body has type signature '%s' but signature in the header field is " +#| "'%s'" +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Viestin rungossa on tyyppimääritys â€%s†mutta tyyppimääritys otsakekentässä " +"on â€%sâ€" + +#: gio/gdbusmessage.c:2825 +#, fuzzy, c-format +#| msgid "Message body is empty but signature in the header field is '(%s)'" +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Viestin runko on tyhjä mutta tyyppimääritys otsakekentässä on â€(%s)â€" + +#: gio/gdbusmessage.c:3378 +#, fuzzy, c-format +#| msgid "Error return with body of type '%s'" +msgid "Error return with body of type “%sâ€" +msgstr "Virhepaluu runkotyypillä â€%sâ€" + +#: gio/gdbusmessage.c:3386 +msgid "Error return with empty body" +msgstr "Virhepaluu tyhjällä rungolla" + +#: gio/gdbusprivate.c:2246 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: gio/gdbusprivate.c:2420 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: gio/gdbusprivate.c:2443 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to get Hardware profile: %s" +msgstr "Tiedosto ei voi siirtää roskakoriin: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2494 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to load %s or %s: " +msgstr "Tiedosto ei voi siirtää roskakoriin: %s" + +#: gio/gdbusproxy.c:1562 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Virhe kutsuttaessa StartServiceByName kohteelle %s: " + +#: gio/gdbusproxy.c:1585 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Odottamaton vastaus %d metodilta StartServiceByName(â€%sâ€)" + +#: gio/gdbusproxy.c:2688 gio/gdbusproxy.c:2823 +#, fuzzy, c-format +#| msgid "" +#| "Cannot invoke method; proxy is for a well-known name without an owner and " +#| "proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ei voitu kutsua metodia; välittäjä on hyvin tunnetuille nimille ilman " +"omistajaa ja välittäjä muodostettiin lipulla " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:763 +#, fuzzy +#| msgid "Abstract name space not supported" +msgid "Abstract namespace not supported" +msgstr "Abstrakti nimiavaruus ei ole tuettu" + +#: gio/gdbusserver.c:856 +msgid "Cannot specify nonce file when creating a server" +msgstr "Ei voi määrittää kertakäyttälukujen tiedostoa kun luodaan palvelinta" + +#: gio/gdbusserver.c:938 +#, fuzzy, c-format +#| msgid "Error writing nonce file at '%s': %s" +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Virhe kirjoitettaessa kertakäyttölukujen tiedostoon â€%sâ€: %s" + +#: gio/gdbusserver.c:1113 +#, fuzzy, c-format +#| msgid "The string '%s' is not a valid D-Bus GUID" +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Merkkijono â€%s†ei ole kelvollinen D-Bus GUID" + +#: gio/gdbusserver.c:1153 +#, fuzzy, c-format +#| msgid "Cannot listen on unsupported transport '%s'" +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Ei voida kuunnella tukemattomassa liikennemuodossa â€%sâ€" + +#: gio/gdbus-tool.c:111 +#, fuzzy, c-format +#| msgid "" +#| "Commands:\n" +#| " help Shows this information\n" +#| " introspect Introspect a remote object\n" +#| " monitor Monitor a remote object\n" +#| " call Invoke a method on a remote object\n" +#| " emit Emit a signal\n" +#| "\n" +#| "Use \"%s COMMAND --help\" to get help on each command.\n" +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Komennot:\n" +" help Näytä nämä tiedot\n" +" introspect Katsasta etäolio\n" +" monitor Monitoroi etäoliota\n" +" call Suorita metodi etäoliolla object\n" +" emit Lähetä signaali\n" +"\n" +"Käytä â€%s KOMENTO --help†saadaksesi ohjeen kustakin komennosta.\n" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1236 +#: gio/gdbus-tool.c:1724 +#, c-format +msgid "Error: %s\n" +msgstr "Virhe: %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1740 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Virhe jäsennettäessä introspektio-XML:ää: %s\n" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Virhe: %s ei ole kelvollinen nimi\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1060 +#: gio/gdbus-tool.c:1890 gio/gdbus-tool.c:2130 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Virhe: %s ei ole kelvollinen oliopolku\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "Yhdistä järjestelmäväylään" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "Yhdistä istuntoväylään" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "Yhdistä annettuun D-Bus-osoitteeseen" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "Yhteyden päätepisteen valitsimet:" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "Valitsimet määrittämään yhteyden päätepiste" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "Yhteyden päätepistettä ei määritetty" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Useita yhteyden päätepisteitä määritetty" + +#: gio/gdbus-tool.c:522 +#, fuzzy, c-format +#| msgid "" +#| "Warning: According to introspection data, interface '%s' does not exist\n" +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Varoitus: Katsastustietojen mukaan rajapintaa â€%s†ei ole olemassa\n" + +#: gio/gdbus-tool.c:531 +#, fuzzy, c-format +#| msgid "" +#| "Warning: According to introspection data, method '%s' does not exist on " +#| "interface '%s'\n" +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Varoitus: Katsastustietojen mukaan metodia â€%s†ei ole olemassa rajapinnassa " +"â€%sâ€\n" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "Valinnainen kohde signaalille (yksikäsitteinen nimi)" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "Oliopolku johon lähetetään signaali" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "Signaalin ja rajapinnan nimi" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "Lähetä signaali." + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:997 gio/gdbus-tool.c:1827 +#: gio/gdbus-tool.c:2059 gio/gdbus-tool.c:2279 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Virhe yhteydenotossa: %s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Virhe: %s ei ole kelvollinen yksikäsitteinen väylänimi\n" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1870 +msgid "Error: Object path is not specified\n" +msgstr "Virhe: Oliopolkua ei määritelty\n" + +#: gio/gdbus-tool.c:765 +#, fuzzy +#| msgid "Error: Method name is not specified\n" +msgid "Error: Signal name is not specified\n" +msgstr "Virhe: Metodin nimeä ei määritelty\n" + +#: gio/gdbus-tool.c:779 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Virhe: Signaalin nimi “%s†on virheellinen\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Virhe: %s ei ole kelvollinen rajapinnan nimi\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Virhe: %s ei ole kelvollinen jäsenen nimi\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1172 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Virhe jäsennettäessä parametriä %d: %s\n" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Virhe huuhdottaessa yhteyttä: %s\n" + +#: gio/gdbus-tool.c:893 +msgid "Destination name to invoke method on" +msgstr "Kohdenimi jossa metodia kutsutaan" + +#: gio/gdbus-tool.c:894 +msgid "Object path to invoke method on" +msgstr "Oliopolku jossa metodia kutsutaan" + +#: gio/gdbus-tool.c:895 +msgid "Method and interface name" +msgstr "Metodi ja rajapinnan nimi" + +#: gio/gdbus-tool.c:896 +msgid "Timeout in seconds" +msgstr "Aikakatkaisu sekunteina" + +#: gio/gdbus-tool.c:942 +msgid "Invoke a method on a remote object." +msgstr "Kutsu metodia etäoliolla" + +#: gio/gdbus-tool.c:1014 gio/gdbus-tool.c:1844 gio/gdbus-tool.c:2084 +msgid "Error: Destination is not specified\n" +msgstr "Virhe: Kohdetta ei määritelty\n" + +#: gio/gdbus-tool.c:1025 gio/gdbus-tool.c:1861 gio/gdbus-tool.c:2095 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Virhe: %s ei ole kelvollinen väylän nimi\n" + +#: gio/gdbus-tool.c:1075 +msgid "Error: Method name is not specified\n" +msgstr "Virhe: Metodin nimeä ei määritelty\n" + +#: gio/gdbus-tool.c:1086 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Virhe: Metodin nimi “%s†on virheellinen\n" + +#: gio/gdbus-tool.c:1164 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d of type '%s': %s\n" +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Virhe jäsennettäessä parametria %d tyyppiä â€%sâ€: %s\n" + +#: gio/gdbus-tool.c:1190 +#, fuzzy, c-format +#| msgid "Error reading from handle: %s" +msgid "Error adding handle %d: %s\n" +msgstr "Virhe luettaessa kahvasta: %s" + +#: gio/gdbus-tool.c:1686 +msgid "Destination name to introspect" +msgstr "Kohdenimi joka katsastetaan" + +#: gio/gdbus-tool.c:1687 +msgid "Object path to introspect" +msgstr "Oliopolku joka katsastetaan" + +#: gio/gdbus-tool.c:1688 +msgid "Print XML" +msgstr "Tulosta XML" + +#: gio/gdbus-tool.c:1689 +msgid "Introspect children" +msgstr "Katsasta lapset" + +#: gio/gdbus-tool.c:1690 +msgid "Only print properties" +msgstr "Tulosta vain ominaisuudet" + +#: gio/gdbus-tool.c:1779 +msgid "Introspect a remote object." +msgstr "Katsasta etäolio" + +#: gio/gdbus-tool.c:1985 +msgid "Destination name to monitor" +msgstr "Kohdenimi jota monitoroidaan" + +#: gio/gdbus-tool.c:1986 +msgid "Object path to monitor" +msgstr "Oliopolku jota monitoroidaan" + +#: gio/gdbus-tool.c:2011 +msgid "Monitor a remote object." +msgstr "Monitoroi etäoliota." + +#: gio/gdbus-tool.c:2069 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: gio/gdbus-tool.c:2193 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2196 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: gio/gdbus-tool.c:2244 +msgid "[OPTION…] BUS-NAME" +msgstr "" + +#: gio/gdbus-tool.c:2245 +msgid "Wait for a bus name to appear." +msgstr "" + +#: gio/gdbus-tool.c:2321 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to activate for must be specified.\n" +msgstr "Virhe: oliopolkua ei määritelty\n" + +#: gio/gdbus-tool.c:2326 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to wait for must be specified.\n" +msgstr "Virhe: oliopolkua ei määritelty\n" + +#: gio/gdbus-tool.c:2331 +msgid "Error: Too many arguments.\n" +msgstr "" + +#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346 +#, fuzzy, c-format +#| msgid "Error: %s is not a valid bus name\n" +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Virhe: %s ei ole kelvollinen väylän nimi\n" + +#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4932 +msgid "Unnamed" +msgstr "Nimeämätön" + +#: gio/gdesktopappinfo.c:2516 +#, fuzzy +#| msgid "Desktop file didn't specify Exec field" +msgid "Desktop file didn’t specify Exec field" +msgstr "Työpöytätiedosto ei määrittele Exec-kenttää" + +#: gio/gdesktopappinfo.c:2801 +msgid "Unable to find terminal required for application" +msgstr "Sovelluksen vaatimaa päätettä ei löydy" + +#: gio/gdesktopappinfo.c:3452 +#, fuzzy, c-format +#| msgid "Can't create user application configuration folder %s: %s" +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Käyttäjän sovellusten asetuskansiota %s ei voi luoda: %s" + +#: gio/gdesktopappinfo.c:3456 +#, fuzzy, c-format +#| msgid "Can't create user MIME configuration folder %s: %s" +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Käyttäjän MIME-asetusten kansiota %s ei voi luoda: %s" + +#: gio/gdesktopappinfo.c:3698 gio/gdesktopappinfo.c:3722 +msgid "Application information lacks an identifier" +msgstr "" + +#: gio/gdesktopappinfo.c:3958 +#, fuzzy, c-format +#| msgid "Can't create user desktop file %s" +msgid "Can’t create user desktop file %s" +msgstr "Käyttäjän työpöytätiedostoa %s ei voi luoda" + +#: gio/gdesktopappinfo.c:4094 +#, c-format +msgid "Custom definition for %s" +msgstr "Oma määrittely kohteelle %s" + +#: gio/gdrive.c:417 +#, fuzzy +#| msgid "drive doesn't implement eject" +msgid "drive doesn’t implement eject" +msgstr "asema ei toteuta aseman avausta" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +#, fuzzy +#| msgid "drive doesn't implement eject or eject_with_operation" +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "asema ei toteuta aseman avausta (eject tai eject_with_operation)" + +#: gio/gdrive.c:571 +#, fuzzy +#| msgid "drive doesn't implement polling for media" +msgid "drive doesn’t implement polling for media" +msgstr "asema ei toteuta median tarkkailua" + +#: gio/gdrive.c:778 +#, fuzzy +#| msgid "drive doesn't implement start" +msgid "drive doesn’t implement start" +msgstr "asema ei toteuta käynnistystä" + +#: gio/gdrive.c:880 +#, fuzzy +#| msgid "drive doesn't implement stop" +msgid "drive doesn’t implement stop" +msgstr "asema ei toteuta pysäytystä" + +#: gio/gdtlsconnection.c:1120 gio/gtlsconnection.c:921 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS-tukea ei ole saatavilla" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS-tukea ei ole saatavilla" + +#: gio/gemblem.c:323 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GEmblem encoding" +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "GEmblem-koodauksen versiota %d ei voi käsitellä" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Virheellinen määrä tunnisteita (%d) GEmblem-koodauksessa" + +#: gio/gemblemedicon.c:362 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GEmblemedIcon encoding" +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon-koodauksen versiota %d ei voi käsitellä" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Virheellinen määrä tunnisteita (%d) GEmblemedIcon-koodauksessa" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Oletettiin GEmblen kohteelle GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1561 +msgid "Containing mount does not exist" +msgstr "Yllä olevaa liitospistettä ei löydy" + +#: gio/gfile.c:2608 gio/glocalfile.c:2472 +#, fuzzy +#| msgid "Can't copy over directory" +msgid "Can’t copy over directory" +msgstr "Kansion päälle ei voi kopioida" + +#: gio/gfile.c:2668 +#, fuzzy +#| msgid "Can't copy directory over directory" +msgid "Can’t copy directory over directory" +msgstr "Kansiota ei voi kopioida kansion päälle" + +#: gio/gfile.c:2676 +msgid "Target file exists" +msgstr "Kohdetiedosto on olemassa" + +#: gio/gfile.c:2695 +#, fuzzy +#| msgid "Can't recursively copy directory" +msgid "Can’t recursively copy directory" +msgstr "Kansiota ei voi kopioida rekursiivisesti" + +#: gio/gfile.c:2996 +msgid "Splice not supported" +msgstr "Splice-operaatiota ei tueta" + +#: gio/gfile.c:3000 +#, c-format +msgid "Error splicing file: %s" +msgstr "Virhe suoritettaessa splice-operaatiota tiedostolle: %s" + +#: gio/gfile.c:3152 +#, fuzzy +#| msgid "Move between mounts not supported" +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Siirto liitospisteiden välillä ei ole tuettu" + +#: gio/gfile.c:3156 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: gio/gfile.c:3161 +#, fuzzy +#| msgid "Move between mounts not supported" +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Siirto liitospisteiden välillä ei ole tuettu" + +#: gio/gfile.c:3226 +msgid "Can’t copy special file" +msgstr "Erikoistiedostoa ei voi kopioida" + +#: gio/gfile.c:4035 +msgid "Invalid symlink value given" +msgstr "Saatiin virheellinen symbolisen linkin arvo" + +#: gio/gfile.c:4045 glib/gfileutils.c:2362 +msgid "Symbolic links not supported" +msgstr "Symbolisia linkkejä ei tueta" + +#: gio/gfile.c:4213 +msgid "Trash not supported" +msgstr "Roskakori ei ole tuettu" + +#: gio/gfile.c:4325 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Tiedostonimi ei voi sisältää merkkiä “%câ€" + +#: gio/gfile.c:6806 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "taltio ei toteuta liittämistä" + +#: gio/gfile.c:6920 gio/gfile.c:6968 +msgid "No application is registered as handling this file" +msgstr "Tiedoston käsittelyyn ei ole rekisteröity mitään sovellusta" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Numeraattori on suljettu" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Tiedoston numeraattorilla on odottavia toimintoja" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Numeraattori on jo suljettu" + +#: gio/gfileicon.c:250 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GFileIcon encoding" +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "GFileIcon-koodauksen versiota %d ei voi käsitellä" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Virheellistä syötetietoa GFileIcon-oliolle" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +#, fuzzy +#| msgid "Stream doesn't support query_info" +msgid "Stream doesn’t support query_info" +msgstr "Virta ei tue komentoa query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Virta ei tue siirtymistä" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Syötevirtaa ei voi kutistaa" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Virta ei tue kutistamista" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:596 +#: glib/gconvert.c:1778 +msgid "Invalid hostname" +msgstr "Virheellinen isäntänimi" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Virheellinen HTTP-välityspalvelimen vastaus" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP-välityspalvelimen yhteyttä ei sallittu" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP-välityspalvelimen tunnistautuminen epäonnistui" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP-välityspalvelin vaatii tunnistautumisen" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP-välityspalvelinyhteys epäonnistui: %i" + +#: gio/ghttpproxy.c:266 +#, fuzzy +#| msgid "HTTP proxy connection failed: %i" +msgid "HTTP proxy response too big" +msgstr "HTTP-välityspalvelinyhteys epäonnistui: %i" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP-välityspalvelin lopetti yhteyden yllättäen." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Väärä määrä tunnisteita (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Luokan nimelle %s ei ole tyyppiä" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Tyyppi %s ei toteuta GIcon-määritystä" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Tyyppi %s ei ole luokkatyyppi" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Virheellinen versionumero: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Tyyppi %s ei toteuta GIcon-määrityksen kutsua from_tokens()" + +#: gio/gicon.c:469 +#, fuzzy +#| msgid "Can't handle the supplied version the icon encoding" +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Annettua kuvakkeen koodauksen versiota ei voi käsitellä" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Osoitetta ei määritetty" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: gio/ginetaddressmask.c:300 +#, fuzzy, c-format +#| msgid "Could not parse '%s' as IP address mask" +msgid "Could not parse “%s†as IP address mask" +msgstr "Tekstiä %s ei voitu jäsentää IP-osoitepeitteeksi" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:220 +msgid "Not enough space for socket address" +msgstr "Pistokeosoitteelle ei ole tarpeeksi tilaa" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Ei-tuettu pistokeosoite" + +#: gio/ginputstream.c:188 +#, fuzzy +#| msgid "Input stream doesn't implement read" +msgid "Input stream doesn’t implement read" +msgstr "Syötevirta ei toteuta lukua" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1247 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Virrassa on toiminto odottamassa" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopioi tiedoston kanssa" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Käyttö:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Tulosta ohjelman versio ja poistu." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Komennot:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopioi yksi tai useampi tiedosto" + +#: gio/gio-tool.c:231 +#, fuzzy +#| msgid "Show GApplication options" +msgid "Show information about locations" +msgstr "Näytä GApplication-valitsimet" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Käynnistä sovellus työpöytätiedostosta" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: gio/gio-tool.c:235 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create directories" +msgstr "Kansiota ei voi avata" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Siirrä yksi tai useampi tiedosto" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Avaa tiedostoja oletussovelluksella" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Nimeä tiedosto uudelleen" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Poista yksi tai useampi tiedosto" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" + +#: gio/gio-tool-cat.c:87 +#, fuzzy +#| msgid "Error writing to file: %s" +msgid "Error writing to stdout" +msgstr "Virhe kirjoitettaessa tiedostoon: %s" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +#, fuzzy +#| msgid "Target file is a directory" +msgid "No target directory" +msgstr "Kohdetiedosto on kansio" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Näytä edistyminen" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +#, fuzzy +#| msgid "Backup file creation failed" +msgid "Backup existing destination files" +msgstr "Varmuuskopiotiedoston luonti epäonnistui" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Älä koskaan seuraa symbolisia linkkejä" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Siirretty %s/%s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "LÄHDE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "KOHDE" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Kohde %s ei ole kansio" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: korvataanko “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "" + +#: gio/gio-tool-info.c:38 +#, fuzzy +#| msgid "Error getting filesystem info: %s" +msgid "Get file system info" +msgstr "Virhe haettaessa tietoja tiedostojärjestelmästä: %s" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Älä seuraa symbolisia linkkejä" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nimi: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tyyppi: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "koko: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "piilotettu\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: gio/gio-tool-info.c:345 +#, fuzzy +#| msgid "Show GApplication options" +msgid "Show information about locations." +msgstr "Näytä GApplication-valitsimet" + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "" + +#: gio/gio-tool-launch.c:85 +#, fuzzy +#| msgid "There is no GCredentials support for your platform" +msgid "The launch command is not currently supported on this platform" +msgstr "Alustallesi ei ole GCredentials-tukea" + +#: gio/gio-tool-launch.c:98 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to load ‘%s‘: %s" +msgstr "Tiedosto ei voi siirtää roskakoriin: %s" + +#: gio/gio-tool-launch.c:107 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Unable to load application information for ‘%s‘" +msgstr "Tiedoston â€%s†lukeminen epäonnistui: %s" + +#: gio/gio-tool-launch.c:119 +#, fuzzy, c-format +#| msgid "Default application for “%sâ€: %s\n" +msgid "Unable to launch application ‘%s’: %s" +msgstr "Oletussovellus tyypille “%sâ€: %s\n" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Näytä piilotetut tiedostot" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Tyypille “%s†ei ole oletussovellusta\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Oletussovellus tyypille “%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Rekisteröidyt sovellukset:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Ei rekisteröityjä sovelluksia\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Suositellut sovellukset:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Ei suositeltuja sovelluksia\n" + +#: gio/gio-tool-mime.c:162 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "Tiedoston â€%s†lukeminen epäonnistui: %s" + +#: gio/gio-tool-mime.c:168 +#, fuzzy, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Tiedoston â€%s†luominen epäonnistui: %s" + +#: gio/gio-tool-mkdir.c:31 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create parent directories" +msgstr "Kansiota ei voi avata" + +#: gio/gio-tool-mkdir.c:52 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create directories." +msgstr "Kansiota ei voi avata" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "LAITE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Näytä lisätietoja" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +#, fuzzy +#| msgctxt "GDateTime" +#| msgid "PM" +msgid "PIM" +msgstr "ip." + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonyymikäyttö kielletty" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: gio/gio-tool-move.c:143 +#, fuzzy, c-format +#| msgid "Target file is a directory" +msgid "Target %s is not a directory" +msgstr "Kohdetiedosto on kansio" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NIMI" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Nimeä tiedosto uudelleen." + +#: gio/gio-tool-rename.c:70 +#, fuzzy +#| msgid "Missing argument for %s" +msgid "Missing argument" +msgstr "Puuttuva argumentti kohteelle %s" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Luo vain jos ei olemassa" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +#, fuzzy +#| msgid "Error reading from handle: %s" +msgid "Error reading from standard input" +msgstr "Virhe luettaessa kahvasta: %s" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +#, fuzzy +#| msgid "TLS support is not available" +msgid "Etag not available\n" +msgstr "TLS-tukea ei ole saatavilla" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYYPPI" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "ARVO" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "" + +#: gio/gio-tool-set.c:113 +#, fuzzy +#| msgid "No connection endpoint specified" +msgid "Location not specified" +msgstr "Yhteyden päätepistettä ei määritetty" + +#: gio/gio-tool-set.c:120 +#, fuzzy +#| msgid "Error: signal not specified.\n" +msgid "Attribute not specified" +msgstr "Virhe: signaalia ei määritetty.\n" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Arvoa ei määritetty" + +#: gio/gio-tool-set.c:180 +#, fuzzy, c-format +#| msgid "Invalid attribute type (string expected)" +msgid "Invalid attribute type “%sâ€" +msgstr "Virheellinen ominaisuustyyppi (piti olla merkkijono)" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Tyhjennä roskakori" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" + +#: gio/gio-tool-trash.c:106 +#, fuzzy +#| msgid "Unable to find terminal required for application" +msgid "Unable to find original path" +msgstr "Sovelluksen vaatimaa päätettä ei löydy" + +#: gio/gio-tool-trash.c:123 +#, fuzzy +#| msgid "Unable to create socket: %s" +msgid "Unable to recreate original location: " +msgstr "Pistoketta ei voi luoda: %s" + +#: gio/gio-tool-trash.c:136 +#, fuzzy +#| msgid "Unable to find terminal required for application" +msgid "Unable to move file to its original location: " +msgstr "Sovelluksen vaatimaa päätettä ei löydy" + +#: gio/gio-tool-trash.c:225 +#, fuzzy +#| msgid "Move files or directories to the trash." +msgid "Move/Restore files or directories to the trash." +msgstr "Siirrä tiedostoja tai kansioita roskakoriin." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Annettu sijainti ei ala skeemalla trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Seuraa symbolisia linkkejä, liitoksia ja pikakuvakkeita" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elementti <%s> ei ole sallittu elementin <%s> sisällä" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elementti <%s> ei ole sallittu päätasolla" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: gio/glib-compile-resources.c:245 +#, fuzzy, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Hakemistoon â€%s†siirtyminen epäonnistui (%s)" + +#: gio/glib-compile-resources.c:256 +#, fuzzy, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Hakemistoon â€%s†siirtyminen epäonnistui (%s)" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Tuntematon käsittelyvalinta “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Virhe lukiessa tiedostoa %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Virhe pakatessa tiedostoa %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "teksti ei voi esiintyä elementin <%s> sisällä" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Näytä ohjelman versio ja lopeta" + +#: gio/glib-compile-resources.c:738 +#, fuzzy +msgid "Name of the output file" +msgstr "Kuvakkeen nimi" + +#: gio/glib-compile-resources.c:739 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "HAKEMISTO" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "Luo lähdeotsake" + +#: gio/glib-compile-resources.c:742 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "Luo riippuvuusluettelo" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:746 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: gio/glib-compile-resources.c:747 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: gio/glib-compile-resources.c:775 +#, fuzzy +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Käännä kaikki GSettings-skeematiedostot skeema-välimuistiin.\n" +"Skeematiedostoilla tulee olla pääte .gschema.xml ja\n" +"välimuistitiedoston nimi on gschemas.compiled." + +#: gio/glib-compile-resources.c:797 +#, fuzzy +msgid "You should give exactly one file name\n" +msgstr "Sinun tulisi antaa täsmälleen yksi hakemistonimi\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Virheellinen numeerinen arvo" + +#: gio/glib-compile-schemas.c:111 +#, fuzzy, c-format +#| msgid "<%s id='%s'> already specified" +msgid " already specified" +msgstr "<%s id='%s'> on jo määritetty" + +#: gio/glib-compile-schemas.c:119 +#, fuzzy, c-format +#| msgid " already specified" +msgid "value='%s' already specified" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, fuzzy, c-format +#| msgid "No connection endpoint specified" +msgid "<%s> is not contained in the specified range" +msgstr "Yhteyden päätepistettä ei määritetty" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +#, fuzzy +#| msgid " already specified" +msgid " already specified for this key" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, fuzzy, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to parse value of type “%sâ€: " +msgstr "Tiedoston â€%s†luominen epäonnistui: %s" + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +#, fuzzy +#| msgid " already specified" +msgid " already specified for this key" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, fuzzy, c-format +#| msgid " already specified" +msgid " already given" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +#, fuzzy +#| msgid " already specified" +msgid " already specified for this key" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, fuzzy, c-format +#| msgid "<%s id='%s'> already specified" +msgid " already specified" +msgstr "<%s id='%s'> on jo määritetty" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Tyhjät nimet eivät ole sallittuja" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "virheellinen nimi “%sâ€: nimien täytyy alkaa pienellä kirjaimella" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"virheellinen nimi “%sâ€: virheellinen merkki “%câ€; vain pieniä kirjaimia, " +"numeroita sekä viiva (“-â€) sallitaan." + +#: gio/glib-compile-schemas.c:828 +#, fuzzy, c-format +#| msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"virheellinen nimi â€%sâ€: kaksi peräkkäistä viivaa (’--’) ei ole sallittu." + +#: gio/glib-compile-schemas.c:837 +#, fuzzy, c-format +#| msgid "invalid name '%s': the last character may not be a dash ('-')." +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "virheellinen nimi â€%sâ€: viimeinen merkki ei saa olla viiva (’-’)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "virheellinen nimi “%sâ€: pituuden yläraja on 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:943 +#, fuzzy +msgid "Cannot add keys to a “list-of†schema" +msgstr "ei voi lisätä avaimia â€list-ofâ€-skeemaan" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" peittää skeemassa ; laita " +" muokataksesi arvoa" + +#: gio/glib-compile-schemas.c:983 +#, fuzzy, c-format +#| msgid "" +#| "exactly one of 'type', 'enum' or 'flags' must be specified as an " +#| "attribute to " +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"täsmälleen yksi ’type’ (tyyppi), ’enum’ tai ’flags’ (liput) täytyy määrittää " +"attribuuttina kohdassa " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> ei ole (vielä) määritetty." + +#: gio/glib-compile-schemas.c:1017 +#, fuzzy, c-format +#| msgid "invalid GVariant type string '%s'" +msgid "Invalid GVariant type string “%sâ€" +msgstr "virheellinen GVariant-tyyppimerkkijono â€%sâ€" + +#: gio/glib-compile-schemas.c:1047 +#, fuzzy +#| msgid " given but schema isn't extending anything" +msgid " given but schema isn’t extending anything" +msgstr " annettu mutta skeema ei laajenna mitään" + +#: gio/glib-compile-schemas.c:1060 +#, fuzzy, c-format +#| msgid "no to override" +msgid "No to override" +msgstr "ei avainta joka syrjäytettäisiin" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " on jo määritetty" + +#: gio/glib-compile-schemas.c:1153 +#, fuzzy, c-format +#| msgid " extends not yet existing schema '%s'" +msgid " extends not yet existing schema “%sâ€" +msgstr " laajentaa ei vielä olemassaolevaa skeemaa â€%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, fuzzy, c-format +#| msgid " is list of not yet existing schema '%s'" +msgid " is list of not yet existing schema “%sâ€" +msgstr " on luettelo ei vielä olemassaolevista skeemoista â€%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, fuzzy, c-format +#| msgid "Can not be a list of a schema with a path" +msgid "Cannot be a list of a schema with a path" +msgstr "Ei voi olla luettelo skeemasta polun kera" + +#: gio/glib-compile-schemas.c:1187 +#, fuzzy, c-format +#| msgid "Can not extend a schema with a path" +msgid "Cannot extend a schema with a path" +msgstr "Ei voi laajentaa skeemaa polun kera" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" on luettelo laajentamassa skeemaa joka ei " +"ole luettelo" + +#: gio/glib-compile-schemas.c:1207 +#, fuzzy, c-format +#| msgid "" +#| " extends but " +#| "'%s' does not extend '%s'" +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" laajentaa skeemaa mutta â€%s†ei laajenna â€%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, fuzzy, c-format +#| msgid "a path, if given, must begin and end with a slash" +msgid "A path, if given, must begin and end with a slash" +msgstr "polku, jos annettu, täytyy aloittaa ja lopettaa kauttaviivalla" + +#: gio/glib-compile-schemas.c:1231 +#, fuzzy, c-format +#| msgid "the path of a list must end with ':/'" +msgid "The path of a list must end with “:/â€" +msgstr "luettelon polun täytyy alkaa ’:/’" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> on jo määritetty" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, fuzzy, c-format +#| msgid "Element <%s> not allowed inside <%s>" +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Elementti <%s> ei ole sallittu elementin <%s> sisällä" + +#: gio/glib-compile-schemas.c:1518 +#, fuzzy, c-format +#| msgid "Element <%s> not allowed at toplevel" +msgid "Element <%s> not allowed at the top level" +msgstr "Elementti <%s> ei ole sallittu päätasolla" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, fuzzy, c-format +#| msgid "text may not appear inside <%s>" +msgid "Text may not appear inside <%s>" +msgstr "teksti ei voi esiintyä elementin <%s> sisällä" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +#, fuzzy +#| msgid "--strict was specified; exiting.\n" +msgid "--strict was specified; exiting." +msgstr "--strict annettu; lopetetaan.\n" + +#: gio/glib-compile-schemas.c:1845 +#, fuzzy +#| msgid "This entire file has been ignored.\n" +msgid "This entire file has been ignored." +msgstr "Tämä koko tiedosto on ohitettu.\n" + +#: gio/glib-compile-schemas.c:1908 +#, fuzzy +#| msgid "Ignoring this file.\n" +msgid "Ignoring this file." +msgstr "Ohitetaan tämä tiedosto.\n" + +#: gio/glib-compile-schemas.c:1963 +#, fuzzy, c-format +#| msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Avainta â€%s†skeemassa â€%s†ei ole määritetty syrjäytystiedostossa â€%sâ€" + +#: gio/glib-compile-schemas.c:1971 +#, fuzzy, c-format +#| msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Avainta â€%s†skeemassa â€%s†ei ole määritetty syrjäytystiedostossa â€%sâ€" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s. " +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"virhe jäsennettäessä avainta â€%s†skeemassa â€%s†kuten määrittetty " +"syrjäytystiedostossa â€%sâ€: %s. " + +#: gio/glib-compile-schemas.c:2038 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s. " +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"virhe jäsennettäessä avainta â€%s†skeemassa â€%s†kuten määrittetty " +"syrjäytystiedostossa â€%sâ€: %s. " + +#: gio/glib-compile-schemas.c:2065 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is out of the " +#| "range given in the schema" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"syrjäytys avaimelle â€%s†skeemassa â€%s†syrjäytystiedostossa â€%s†on yli " +"skeemassa annettujen rajojen" + +#: gio/glib-compile-schemas.c:2075 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is out of the " +#| "range given in the schema" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"syrjäytys avaimelle â€%s†skeemassa â€%s†syrjäytystiedostossa â€%s†on yli " +"skeemassa annettujen rajojen" + +#: gio/glib-compile-schemas.c:2101 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"syrjäytys avaimelle â€%s†skeemassa â€%s†syrjäytystiedostossa â€%s†ei ole " +"sallittujen vaihtoehtojen listassa" + +#: gio/glib-compile-schemas.c:2111 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"syrjäytys avaimelle â€%s†skeemassa â€%s†syrjäytystiedostossa â€%s†ei ole " +"sallittujen vaihtoehtojen listassa" + +#: gio/glib-compile-schemas.c:2173 +#, fuzzy +#| msgid "where to store the gschemas.compiled file" +msgid "Where to store the gschemas.compiled file" +msgstr "mihin tallennetaan gschemas.compiled-tiedosto" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Keskeytä minkä tahansa virheen kohdalla skeemoissa" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Älä kirjoita gschema.compiled-tiedostoa" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Älä pakota avainnimirajoituksia" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Käännä kaikki GSettings-skeematiedostot skeema-välimuistiin.\n" +"Skeematiedostoilla tulee olla pääte .gschema.xml ja\n" +"välimuistitiedoston nimi on gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +#, fuzzy +#| msgid "You should give exactly one directory name\n" +msgid "You should give exactly one directory name" +msgstr "Sinun tulisi antaa täsmälleen yksi hakemistonimi\n" + +#: gio/glib-compile-schemas.c:2269 +#, fuzzy +#| msgid "No schema files found: " +msgid "No schema files found: doing nothing." +msgstr "Skeema-tiedostoja ei löytynyt: " + +#: gio/glib-compile-schemas.c:2271 +#, fuzzy +#| msgid "removed existing output file.\n" +msgid "No schema files found: removed existing output file." +msgstr "poistettiin olemassaoleva tulostetiedosto.\n" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Virheellinen tiedostonimi %s" + +#: gio/glocalfile.c:980 +#, fuzzy, c-format +#| msgid "Error getting filesystem info: %s" +msgid "Error getting filesystem info for %s: %s" +msgstr "Virhe haettaessa tietoja tiedostojärjestelmästä: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1121 +#, fuzzy, c-format +#| msgid "Containing mount does not exist" +msgid "Containing mount for file %s not found" +msgstr "Yllä olevaa liitospistettä ei löydy" + +#: gio/glocalfile.c:1144 +#, fuzzy +#| msgid "Can't rename root directory" +msgid "Can’t rename root directory" +msgstr "Juurikansiota ei voi nimetä uudestaan" + +#: gio/glocalfile.c:1162 gio/glocalfile.c:1185 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Virhe nimettäessä tiedostoa %s uudelleen: %s" + +#: gio/glocalfile.c:1169 +msgid "Can’t rename file, filename already exists" +msgstr "Tiedostoa ei voi nimetä uudestaan, tiedostonimi on jo olemassa" + +#: gio/glocalfile.c:1182 gio/glocalfile.c:2366 gio/glocalfile.c:2394 +#: gio/glocalfile.c:2533 gio/glocalfileoutputstream.c:650 +msgid "Invalid filename" +msgstr "Virheellinen tiedostonimi" + +#: gio/glocalfile.c:1350 gio/glocalfile.c:1361 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Virhe avattaessa tiedostoa %s: %s" + +#: gio/glocalfile.c:1486 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Virhe poistettaessa tiedostoa %s: %s" + +#: gio/glocalfile.c:1980 gio/glocalfile.c:1991 +#, fuzzy, c-format +#| msgid "Error trashing file: %s" +msgid "Error trashing file %s: %s" +msgstr "Virhe siirrettäessä tiedostoa roskakoriin: %s" + +#: gio/glocalfile.c:2029 +#, fuzzy, c-format +#| msgid "Unable to create trash dir %s: %s" +msgid "Unable to create trash directory %s: %s" +msgstr "Roskakorikansiota %s ei voi luoda: %s" + +#: gio/glocalfile.c:2050 +#, fuzzy, c-format +#| msgid "Unable to find toplevel directory for trash" +msgid "Unable to find toplevel directory to trash %s" +msgstr "Päätasoa roskakoria varten ei löydy" + +#: gio/glocalfile.c:2058 +#, fuzzy, c-format +#| msgid "Move between mounts not supported" +msgid "Trashing on system internal mounts is not supported" +msgstr "Siirto liitospisteiden välillä ei ole tuettu" + +#: gio/glocalfile.c:2141 gio/glocalfile.c:2169 +#, fuzzy, c-format +#| msgid "Unable to find or create trash directory" +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Roskakori kansiota ei löydy tai sitä ei voi luoda" + +#: gio/glocalfile.c:2215 +#, fuzzy, c-format +#| msgid "Unable to create trashing info file: %s" +msgid "Unable to create trashing info file for %s: %s" +msgstr "Roskakorin informaatiotiedostoa ei voi luoda: %s" + +#: gio/glocalfile.c:2277 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Tiedosto ei voi siirtää roskakoriin: %s" + +#: gio/glocalfile.c:2281 gio/glocalfile.c:2337 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s: %s" +msgstr "Tiedosto ei voi siirtää roskakoriin: %s" + +#: gio/glocalfile.c:2343 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s" +msgstr "Tiedosto ei voi siirtää roskakoriin: %s" + +#: gio/glocalfile.c:2369 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Virhe luotaessa hakemistoa %s: %s" + +#: gio/glocalfile.c:2398 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Tiedostojärjestelmä ei tue symbolisia linkkejä" + +#: gio/glocalfile.c:2401 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Virhe luotaessa symbolista linkkiä %s: %s" + +#: gio/glocalfile.c:2444 gio/glocalfile.c:2479 gio/glocalfile.c:2536 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Virhe siirrettäessä tiedostoa %s: %s" + +#: gio/glocalfile.c:2467 +#, fuzzy +#| msgid "Can't move directory over directory" +msgid "Can’t move directory over directory" +msgstr "Kansiota ei voi siirtää kansion päälle" + +#: gio/glocalfile.c:2493 gio/glocalfileoutputstream.c:1039 +#: gio/glocalfileoutputstream.c:1053 gio/glocalfileoutputstream.c:1068 +#: gio/glocalfileoutputstream.c:1085 gio/glocalfileoutputstream.c:1099 +msgid "Backup file creation failed" +msgstr "Varmuuskopiotiedoston luonti epäonnistui" + +#: gio/glocalfile.c:2512 +#, c-format +msgid "Error removing target file: %s" +msgstr "Virhe poistettaessa kohdetiedostoa: %s" + +#: gio/glocalfile.c:2526 +msgid "Move between mounts not supported" +msgstr "Siirto liitospisteiden välillä ei ole tuettu" + +#: gio/glocalfile.c:2700 +#, fuzzy, c-format +#| msgid "could not get remote address: %s" +msgid "Could not determine the disk usage of %s: %s" +msgstr "ei saatu etäosoitetta: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Ominaisuuden arvo ei voi olla NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Virheellinen ominaisuustyyppi (piti olla merkkijono)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Virheellinen laajennetun ominaisuuden nimi" + +#: gio/glocalfileinfo.c:821 +#, fuzzy, c-format +#| msgid "Error setting extended attribute '%s': %s" +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Virhe asetettaessa laajennettua ominaisuutta â€%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (virheellinen merkistökoodaus)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:915 +#, fuzzy, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Virhe avattaessa kertakäyttölukujen tiedostoa â€%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, fuzzy, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Virhe tarkkailtaessa tiedostokuvaajaa: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Virheellinen ominaisuuden tyyppi (piti olla uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Virheellinen ominaisuuden tyyppi (piti olla uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Virheellinen ominaisuuden tyyppi (piti olla tavujono)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Symbolisille linkeille ei voi asettaa oikeuksia" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Virhe asetettaessa oikeuksia: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Virhe asetettaessa omistajaa: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "symbolinen linkki ei voi olla NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Virhe asetettaessa symbolista linkkiä: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Virhe asetettaessa symbolista linkkiä: tiedosto ei ole symbolinen linkki" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2557 +#, fuzzy, c-format +#| msgid "Value “%s†cannot be interpreted as a number." +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Arvoa “%s†ei voida tulkita numeroksi." + +#: gio/glocalfileinfo.c:2576 +#, c-format +#| msgid "Value “%s†cannot be interpreted as a number." +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Tiedostoa “%s†ei voi avata: Windows-virhe %lu" + +#: gio/glocalfileinfo.c:2589 +#, fuzzy, c-format +#| msgid "Error setting modification or access time: %s" +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Virhe asetettaessa muokkaus- tai käyttöaikaa: %s" + +#: gio/glocalfileinfo.c:2690 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Virhe asetettaessa muokkaus- tai käyttöaikaa: %s" + +#: gio/glocalfileinfo.c:2713 +msgid "SELinux context must be non-NULL" +msgstr "SELinux-konteksti ei voi olla NULL" + +#: gio/glocalfileinfo.c:2720 +msgid "SELinux is not enabled on this system" +msgstr "SELinux ei ole käytössä tässä tietokoneessa" + +#: gio/glocalfileinfo.c:2730 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Virhe asetettaessa SELinux-kontekstia: %s" + +#: gio/glocalfileinfo.c:2823 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Ominaisuuden %s asetus ei ole tuettu" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:795 +#, c-format +msgid "Error reading from file: %s" +msgstr "Virhe luettaessa tiedostosta: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:347 +#: gio/glocalfileoutputstream.c:441 +#, c-format +msgid "Error closing file: %s" +msgstr "Virhe suljettaessa tiedostoa: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:557 +#: gio/glocalfileoutputstream.c:1117 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Virhe siirryttäessä tiedostossa: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Paikallisen tiedostomonitoroinnin oletustapaa ei voitu selvittää" + +#: gio/glocalfileoutputstream.c:214 gio/glocalfileoutputstream.c:292 +#: gio/glocalfileoutputstream.c:328 gio/glocalfileoutputstream.c:816 +#, c-format +msgid "Error writing to file: %s" +msgstr "Virhe kirjoitettaessa tiedostoon: %s" + +#: gio/glocalfileoutputstream.c:374 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Virhe poistettaessa vanhaa varmuuskopiolinkkiä: %s" + +#: gio/glocalfileoutputstream.c:388 gio/glocalfileoutputstream.c:401 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Virhe luotaessa varmuuskopiota: %s" + +#: gio/glocalfileoutputstream.c:419 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Virhe nimettäessä uudestaan väliaikaistiedostoa: %s" + +#: gio/glocalfileoutputstream.c:603 gio/glocalfileoutputstream.c:1168 +#, c-format +msgid "Error truncating file: %s" +msgstr "Virhe katkaistaessa tiedostoa: %s" + +#: gio/glocalfileoutputstream.c:656 gio/glocalfileoutputstream.c:894 +#: gio/glocalfileoutputstream.c:1149 gio/gsubprocess.c:226 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Virhe avattaessa tiedostoa “%sâ€: %s" + +#: gio/glocalfileoutputstream.c:928 +msgid "Target file is a directory" +msgstr "Kohdetiedosto on kansio" + +#: gio/glocalfileoutputstream.c:933 +msgid "Target file is not a regular file" +msgstr "Kohdetiedosto ei ole tavallinen tiedosto" + +#: gio/glocalfileoutputstream.c:945 +msgid "The file was externally modified" +msgstr "Tiedostoa muokattiin muualta" + +#: gio/glocalfileoutputstream.c:1133 +#, c-format +msgid "Error removing old file: %s" +msgstr "Virhe poistettaessa vanhaa tiedostoa: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Saatiin virheellinen GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Virheellinen siirtymispyyntö" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream-kohdetta ei voi kutistaa" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Muistin tulostevirran koko ei ole muutettavissa" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Muistin tulostevirran koon muutos epäonnistui" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Kirjoituksen käsittelemiseksi tarvittava muistinmäärä on suurempi kuin " +"käytettävissä oleva osoiteavaruus" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Pyydetty kelausta virtauksen alkua edeltävään kohtaan" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Pyydetty kelausta virtauksen lopun jälkeiseen kohtaan" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +#, fuzzy +#| msgid "mount doesn't implement \"unmount\"" +msgid "mount doesn’t implement “unmountâ€" +msgstr "Liitospiste ei toteuta â€unmountâ€-operaatiota (irrottamista)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +#, fuzzy +#| msgid "mount doesn't implement \"eject\"" +msgid "mount doesn’t implement “ejectâ€" +msgstr "Liitospiste ei toteuta â€ejectâ€-operaatiota (aseman avaamista)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +#, fuzzy +#| msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"Liitospiste ei toteuta irrottamista (â€unmount†tai â€unmount_with_operationâ€)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +#, fuzzy +#| msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"Liitospiste ei toteuta aseman avaamista (â€eject†tai â€eject_with_operationâ€)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +#, fuzzy +#| msgid "mount doesn't implement \"remount\"" +msgid "mount doesn’t implement “remountâ€" +msgstr "Liitospiste ei toteuta uudestaanliittämistä (â€remountâ€)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +#, fuzzy +#| msgid "mount doesn't implement content type guessing" +msgid "mount doesn’t implement content type guessing" +msgstr "mount ei toteuta sisältötyypin arvausta" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +#, fuzzy +#| msgid "mount doesn't implement synchronous content type guessing" +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "mount ei toteuta synkronista sisältötyypin arvausta" + +#: gio/gnetworkaddress.c:415 +#, fuzzy, c-format +#| msgid "Hostname '%s' contains '[' but not ']'" +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Isäntänimi â€%s†sisältää merkin â€[â€, mutta ei â€]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Verkko ei ole tavoitettavissa" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Isäntä ei ole tavoitettavissa" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, fuzzy, c-format +msgid "Could not create network monitor: %s" +msgstr "ei saatu etäosoitetta: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Verkon tilaa ei saatu:" + +#: gio/gnetworkmonitornm.c:348 +#, c-format +#| msgid "NetworkManager version too old" +msgid "NetworkManager not running" +msgstr "NetworkManager ei ole käynnissä" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManagerin versio on liian vanha" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +#, fuzzy +#| msgid "Output stream doesn't implement write" +msgid "Output stream doesn’t implement write" +msgstr "Tulostevirta ei toteuta kirjoitusta" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Lähdevirta on jo suljettu" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, fuzzy, c-format +#| msgid "Error resolving '%s': %s" +msgid "Error resolving “%sâ€: %s" +msgstr "Virhe selvitettäessä osoitetta â€%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:615 +#, c-format +msgid "%s not implemented" +msgstr "" + +#: gio/gresolver.c:984 gio/gresolver.c:1036 +#, fuzzy +#| msgid "Invalid hostname" +msgid "Invalid domain" +msgstr "Virheellinen isäntänimi" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Resurssia “%s†ei ole olemassa" + +#: gio/gresource.c:848 +#, fuzzy, c-format +#| msgid "The resource at '%s' does not exist" +msgid "The resource at “%s†failed to decompress" +msgstr "Resurssia '%s' ei ole olemassa" + +#: gio/gresourcefile.c:732 +#, fuzzy, c-format +#| msgid "Target file is a directory" +msgid "The resource at “%s†is not a directory" +msgstr "Kohdetiedosto on kansio" + +#: gio/gresourcefile.c:940 +#, fuzzy +msgid "Input stream doesn’t implement seek" +msgstr "Syötevirta ei toteuta lukua" + +#: gio/gresource-tool.c:499 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: gio/gresource-tool.c:505 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: gio/gresource-tool.c:508 gio/gresource-tool.c:518 +msgid "FILE [PATH]" +msgstr "TIEDOSTO [POLKU]" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 gio/gresource-tool.c:526 +msgid "SECTION" +msgstr "" + +#: gio/gresource-tool.c:514 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: gio/gresource-tool.c:524 +msgid "Extract a resource file to stdout" +msgstr "" + +#: gio/gresource-tool.c:525 +msgid "FILE PATH" +msgstr "TIEDOSTO POLKU" + +#: gio/gresource-tool.c:539 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:553 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Käyttö:\n" +" gsettings %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:560 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: gio/gresource-tool.c:564 gio/gsettings-tool.c:701 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMENTO (valinnainen) selitettävä komento\n" + +#: gio/gresource-tool.c:570 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: gio/gresource-tool.c:573 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: gio/gresource-tool.c:577 +msgid "[PATH]" +msgstr "[POLKU]" + +#: gio/gresource-tool.c:579 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: gio/gresource-tool.c:580 +msgid "PATH" +msgstr "" + +#: gio/gresource-tool.c:582 +msgid " PATH A resource path\n" +msgstr "" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:906 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Ei skeemaa “%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, fuzzy, c-format +#| msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Skeema â€%s†ei ole siirrettävä (polkua ei saa määrittää)\n" + +#: gio/gsettings-tool.c:76 +#, fuzzy, c-format +#| msgid "Schema '%s' is relocatable (path must be specified)\n" +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Skeema â€%s†on siirrettävä (polku täytyy määrittää)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Annettu tyhjä polku.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Polun täytyy alkaa kauttaviivalla (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Polun täytyy päättyä kauttaviivaan (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Polku ei saa sisältää kahta perättäistä kauttaviivaa (//)\n" + +#: gio/gsettings-tool.c:536 +msgid "The provided value is outside of the valid range\n" +msgstr "Annettu arvo on yli sallittujen rajojen\n" + +#: gio/gsettings-tool.c:543 +#, fuzzy +#| msgid "Property '%s' is not writable" +msgid "The key is not writable\n" +msgstr "Ominaisuus â€%s†ei ole kirjoitettavissa" + +#: gio/gsettings-tool.c:579 +msgid "List the installed (non-relocatable) schemas" +msgstr "Luettelo asennetuista (ei-siirrettävistä) skeemoista" + +#: gio/gsettings-tool.c:585 +msgid "List the installed relocatable schemas" +msgstr "Luettelo asennetuista siirrettävistä skeemoista" + +#: gio/gsettings-tool.c:591 +msgid "List the keys in SCHEMA" +msgstr "Luettelo avaimsta SKEEMAssa" + +#: gio/gsettings-tool.c:592 gio/gsettings-tool.c:598 gio/gsettings-tool.c:641 +msgid "SCHEMA[:PATH]" +msgstr "SKEEMA[:POLKU]" + +#: gio/gsettings-tool.c:597 +msgid "List the children of SCHEMA" +msgstr "Luettelo SKEEMAn lapsista" + +#: gio/gsettings-tool.c:603 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Luettelo avaimista ja arvoista rekursiivisesti\n" +"Jos SKEEMA ei annettu, luettele kaikki avaimet\n" + +#: gio/gsettings-tool.c:605 +msgid "[SCHEMA[:PATH]]" +msgstr "[SKEEMA[:POLKU]]" + +#: gio/gsettings-tool.c:610 +msgid "Get the value of KEY" +msgstr "Hae avaimen AVAIN arvo" + +#: gio/gsettings-tool.c:611 gio/gsettings-tool.c:617 gio/gsettings-tool.c:623 +#: gio/gsettings-tool.c:635 gio/gsettings-tool.c:647 +msgid "SCHEMA[:PATH] KEY" +msgstr "SKEEMA:[POLKU] AVAIN" + +#: gio/gsettings-tool.c:616 +msgid "Query the range of valid values for KEY" +msgstr "Kysy AVAIMEN sallittujen arvojen rajat" + +#: gio/gsettings-tool.c:622 +#, fuzzy +#| msgid "Query the range of valid values for KEY" +msgid "Query the description for KEY" +msgstr "Kysy AVAIMEN sallittujen arvojen rajat" + +#: gio/gsettings-tool.c:628 +msgid "Set the value of KEY to VALUE" +msgstr "Aseta avaimelle AVAIN arvoksi ARVO" + +#: gio/gsettings-tool.c:629 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SKEEMA[:POLKU] AVAIN ARVO" + +#: gio/gsettings-tool.c:634 +msgid "Reset KEY to its default value" +msgstr "Palauta AVAIN sen oletusarvoon" + +#: gio/gsettings-tool.c:640 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Palauta kaikki avaimet SKEEMAssa oletusarvoihin" + +#: gio/gsettings-tool.c:646 +msgid "Check if KEY is writable" +msgstr "Tarkista onko AVAIN kirjoitettavissa" + +#: gio/gsettings-tool.c:652 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitoroi avaimen AVAIN muutoksia.\n" +"Jos AVAIN ei ole määrietty, monitoroi kaikkia avaimia SKEEMAssa.\n" +"Paina ^C lopettaaksesi monitorointi.\n" + +#: gio/gsettings-tool.c:655 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SKEEMA:[POLKU] [AVAIN]" + +#: gio/gsettings-tool.c:667 +#, fuzzy +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Käyttö:\n" +" gsettings KOMENTO [ARGUMENTIT...]\n" +"\n" +"Komennot:\n" +" help Näytä tämä tieto\n" +" list-schemas Luettele asennetut skeemat\n" +" list-relocatable-schemas Luettele siirrettävät skeemat\n" +" list-keys Luettele avaimet skeemassa\n" +" list-children Luettele skeeman lapset\n" +" list-recursively Luettele avaimet ja arvot rekursiivisesti\n" +" range Kysy avaimen arvon rajat\n" +" get Hae avaimen arvo\n" +" set Aseta avaimen arvo\n" +" reset Palauta avaimen arvo oletukseksi\n" +" reset-recursively Palauta kaikki arvot annetussa skeemassa\n" +" writable Tarkista onko avain kirjoitettavissa\n" +" monitor Tarkkaile muutoksia\n" +"\n" +"Komenna â€gsettings help KOMENTO†saadaksesi tarkemman ohjeen.\n" +"\n" + +#: gio/gsettings-tool.c:691 +#, fuzzy, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Käyttö:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:697 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:705 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SKEEMA Skeeman nimi\n" +" POLKU Polku, uudelleensijoiteltaville skeemoille\n" + +#: gio/gsettings-tool.c:710 +msgid " KEY The (optional) key within the schema\n" +msgstr " AVAIN (Valinnainen) avain skeemassa\n" + +#: gio/gsettings-tool.c:714 +msgid " KEY The key within the schema\n" +msgstr " AVAIN Avain skeemassa\n" + +#: gio/gsettings-tool.c:718 +msgid " VALUE The value to set\n" +msgstr " ARVO Asetettava arvo\n" + +#: gio/gsettings-tool.c:773 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not load schemas from %s: %s\n" +msgstr "Muunninta merkistöstä â€%s†merkistöön â€%s†ei voitu avata" + +#: gio/gsettings-tool.c:785 +msgid "No schemas installed\n" +msgstr "Skeemoja ei ole asennettu\n" + +#: gio/gsettings-tool.c:864 +msgid "Empty schema name given\n" +msgstr "Annettu tyhjä skeemanimi\n" + +#: gio/gsettings-tool.c:919 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Ei avainta “%sâ€\n" + +#: gio/gsocket.c:413 +msgid "Invalid socket, not initialized" +msgstr "Virheellinen pistoke, alustamaton" + +#: gio/gsocket.c:420 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Virheellinen pistoke, alustus epäonnistui: %s" + +#: gio/gsocket.c:428 +msgid "Socket is already closed" +msgstr "Pistoke on jo suljettu" + +#: gio/gsocket.c:443 gio/gsocket.c:3190 gio/gsocket.c:4420 gio/gsocket.c:4478 +msgid "Socket I/O timed out" +msgstr "Pistoke I/O:n aikakatkaisu" + +#: gio/gsocket.c:578 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "luodaan GSocket tiedostokahvasta: %s" + +#: gio/gsocket.c:607 gio/gsocket.c:671 gio/gsocket.c:678 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Pistoketta ei voi luoda: %s" + +#: gio/gsocket.c:671 +#, fuzzy +#| msgid "Unknown protocol was specified" +msgid "Unknown family was specified" +msgstr "Tuntematon yhteyskäytäntö määritetty" + +#: gio/gsocket.c:678 +msgid "Unknown protocol was specified" +msgstr "Tuntematon yhteyskäytäntö määritetty" + +#: gio/gsocket.c:1169 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: gio/gsocket.c:1186 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: gio/gsocket.c:1993 +#, c-format +msgid "could not get local address: %s" +msgstr "ei saatu paikallista osoitetta: %s" + +#: gio/gsocket.c:2039 +#, c-format +msgid "could not get remote address: %s" +msgstr "ei saatu etäosoitetta: %s" + +#: gio/gsocket.c:2105 +#, c-format +msgid "could not listen: %s" +msgstr "ei voitu kuunnella: %s" + +#: gio/gsocket.c:2209 +#, fuzzy, c-format +#| msgid "Error binding to address: %s" +msgid "Error binding to address %s: %s" +msgstr "Virhe sidottaessa osoitetta: %s" + +#: gio/gsocket.c:2385 gio/gsocket.c:2422 gio/gsocket.c:2532 gio/gsocket.c:2557 +#: gio/gsocket.c:2620 gio/gsocket.c:2678 gio/gsocket.c:2696 +#, fuzzy, c-format +msgid "Error joining multicast group: %s" +msgstr "Virhe käynnistettäessä ohjelmaa: %s" + +#: gio/gsocket.c:2386 gio/gsocket.c:2423 gio/gsocket.c:2533 gio/gsocket.c:2558 +#: gio/gsocket.c:2621 gio/gsocket.c:2679 gio/gsocket.c:2697 +#, fuzzy, c-format +msgid "Error leaving multicast group: %s" +msgstr "Virhe käynnistettäessä ohjelmaa: %s" + +#: gio/gsocket.c:2387 +msgid "No support for source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2534 +#, fuzzy +#| msgid "Unsupported socket address" +msgid "Unsupported socket family" +msgstr "Ei-tuettu pistokeosoite" + +#: gio/gsocket.c:2559 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2583 +#, c-format +msgid "Interface name too long" +msgstr "" + +#: gio/gsocket.c:2596 gio/gsocket.c:2646 +#, c-format +msgid "Interface not found: %s" +msgstr "" + +#: gio/gsocket.c:2622 +msgid "No support for IPv4 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2680 +msgid "No support for IPv6 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2889 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Virhe hyväksyttäessä yhteyttä: %s" + +#: gio/gsocket.c:3015 +msgid "Connection in progress" +msgstr "Yhteydenotto meneillään" + +#: gio/gsocket.c:3066 +#, fuzzy +#| msgid "Unable to get pending error: %s" +msgid "Unable to get pending error: " +msgstr "Ei saatu tulossa olevaa virhettä: %s" + +#: gio/gsocket.c:3255 +#, c-format +msgid "Error receiving data: %s" +msgstr "Virhe vastaanotettaessa dataa: %s" + +#: gio/gsocket.c:3452 +#, c-format +msgid "Error sending data: %s" +msgstr "Virhe lähetettäessä dataa: %s" + +#: gio/gsocket.c:3639 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Pistoketta ei voi sammuttaa: %s" + +#: gio/gsocket.c:3720 +#, c-format +msgid "Error closing socket: %s" +msgstr "Virhe suljettaessa pistoketta: %s" + +#: gio/gsocket.c:4413 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Odotetaan pistoke-ehtoa: %s" + +#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833 +#, c-format +#| msgid "Error sending message: %s" +msgid "Unable to send message: %s" +msgstr "Viestiä ei voitu lähettää: %s" + +#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834 +msgid "Message vectors too large" +msgstr "" + +#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084 +#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304 +#, c-format +msgid "Error sending message: %s" +msgstr "Virhe lähetettäessä viestiä: %s" + +#: gio/gsocket.c:5026 +#| msgid "GSocketControlMessage not supported on windows" +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage ei ole tuettu Windowsissa" + +#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797 +#, c-format +msgid "Error receiving message: %s" +msgstr "Virhe vastaanotettaessa viestiä: %s" + +#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to read socket credentials: %s" +msgstr "Pistoketta ei voi luoda: %s" + +#: gio/gsocket.c:6136 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials ei ole toteutettu tälle käyttöjärjestemälle" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Yhteyttä välityspalvelimeen %s ei voitu muodostaa: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Yhteys kohteeseen %s ei onnistunut: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Yhdistäminen ei onnistunut:" + +#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749 +#, fuzzy +#| msgid "Trying to proxy over non-TCP connection is not supported." +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Yritys välittää muun kuin TCP-yhteyden yli ei ole tuettu." + +#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778 +#, fuzzy, c-format +#| msgid "Proxy protocol '%s' is not supported." +msgid "Proxy protocol “%s†is not supported." +msgstr "Välitysyhteyskäytäntö â€%s†ei ole tuettu." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Kuuntelija on jo suljettu" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Lisätty pistoke on suljettu" + +#: gio/gsocks4aproxy.c:118 +#, fuzzy, c-format +#| msgid "SOCKSv4 does not support IPv6 address '%s'" +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 ei tue IPv6-osoitetta â€%sâ€" + +#: gio/gsocks4aproxy.c:136 +#, fuzzy +msgid "Username is too long for SOCKSv4 protocol" +msgstr "" +"Liian pitkä käyttäjänimi tai salasana SOCKSv5-yhteyskäytäntöön (enintään %i)." + +#: gio/gsocks4aproxy.c:153 +#, fuzzy, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "" +"Tietokonenimi â€%s†on liian pitkä SOCKSv5-yhteyskäytäntöön (enintään %i " +"tavua)" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Palvelin ei ole SOCKSv4-välityspalvelin." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Yhteys SOCKSv4-palvelimen läpi hylättiin" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Palvelin ei ole SOCKSv5-välityspalvelin" + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5-välityspalvelin vaatii todennuksen." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5-välityspalvelin vaatii todennustapaa, jota GLib ei tue." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Liian pitkä käyttäjänimi tai salasana SOCKSv5-yhteyskäytäntöön." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5-todennus epäonnistui väärän käyttäjätunnuksen tai salasanan vuoksi." + +#: gio/gsocks5proxy.c:300 +#, fuzzy, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "" +"Tietokonenimi â€%s†on liian pitkä SOCKSv5-yhteyskäytäntöön (enintään %i " +"tavua)" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5-välityspalvelin käyttää tuntematonta osoitetyyppiä." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Sisäinen SOCKSv5-välityspalvelinvirhe." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5-yhteys ei ole sallittu sääntöjoukossa." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Laitetta ei tavoitettu SOCKSv5-palvelimen kautta." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Verkkoa ei tavoitettu SOCKSv5-välityspalvelimen kautta." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Yhteyden muodostus SOCKSv5-välityspalvelimen kautta evätty." + +#: gio/gsocks5proxy.c:400 +#, fuzzy +#| msgid "SOCKSv5 proxy does not support 'connect' command." +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5-välityspalvelin ei tue â€connectâ€-komentoa." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5-välityspalvelin ei tue annettua osoitetyyppiä." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Tuntematon SOCKSv5-välityspalvelinvirhe." + +#: gio/gthemedicon.c:595 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "GThemeIcon-koodauksen versiota %d ei voi käsitellä" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Kelvollisia osoitteita ei löytynyt" + +#: gio/gthreadedresolver.c:337 +#, fuzzy, c-format +#| msgid "Error reverse-resolving '%s': %s" +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Virhe selvitettäessä käänteisosoitetta â€%sâ€: %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, fuzzy, c-format +#| msgid "Temporarily unable to resolve '%s'" +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Tilapäisesti ei voida selvittää palvelua â€%sâ€" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, fuzzy, c-format +#| msgid "Error resolving '%s'" +msgid "Error resolving “%sâ€" +msgstr "Virhe selvitettäessä palvelua â€%sâ€" + +#: gio/gtlscertificate.c:298 +msgid "No PEM-encoded private key found" +msgstr "PEM-koodattua yksityistä avainta ei löytynyt" + +#: gio/gtlscertificate.c:308 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-koodatun yksityisen avaimen salauksen purkaminen ei onnistu" + +#: gio/gtlscertificate.c:319 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-koodattua yksityistä avainta ei voitu jäsentää" + +#: gio/gtlscertificate.c:346 +msgid "No PEM-encoded certificate found" +msgstr "PEM-koodattua varmennetta ei löytynyt" + +#: gio/gtlscertificate.c:355 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-koodattu varmennetta ei voitu jäsentää" + +#: gio/gtlscertificate.c:710 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Tämä on viimeinen mahdollisuus kirjoittaa salasana oikein, ennen kuin käyttö " +"estetään." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Syötetty salasana on väärä." + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, fuzzy, c-format +#| msgid "Expecting 1 control message, got %d" +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Odotettiin yhtä ohjausviestiä, saatiin %d" +msgstr[1] "Odotettiin yhtä ohjausviestiä, saatiin %d" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "Odottamaton lisädatan tyyppi" + +#: gio/gunixconnection.c:200 +#, fuzzy, c-format +#| msgid "Expecting one fd, but got %d\n" +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Odotettiin yhtä tiedostokahvaa, mutta saatiin %d\n" +msgstr[1] "Odotettiin yhtä tiedostokahvaa, mutta saatiin %d\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Vastaanotettiin kelvoton tiedostokahva" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "Virhe lähetettäessä valtuutusta: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Virhe tarkistettaessa onko SO_PASSCRED käytössä pistokkeelle: %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Virhe otettaessa käyttöön SO_PASSCRED-lippua: %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Odotettiin saada lukea yksi tavu vastaanottovaltuuksia mutta luettiin nolla " +"tavua" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ei odotetu ohjausviestiä, mutta saatiin %d" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Virhe kytkettäessä pois SO_PASSCRED-lippua: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Tiedostokahvasta lukeminen epäonnistui: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Tiedostokahvan sulkeminen epäonnistui: %s" + +#: gio/gunixmounts.c:2780 gio/gunixmounts.c:2833 +msgid "Filesystem root" +msgstr "Tiedostojärjestelmän juuri" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Tiedostokahvaan kirjoittaminen epäonnistui: %s" + +#: gio/gunixsocketaddress.c:243 +#, fuzzy +#| msgid "Abstract unix domain socket addresses not supported on this system" +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Abstraktit unix-domainin pistokeosoitteet eivät ole tuettuja tässä " +"järjestelmässä" + +#: gio/gvolume.c:438 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "volume doesn’t implement eject" +msgstr "taltio ei toteuta aseman avausta" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "taltio ei toteuta aseman avausta (eject tai eject_with_operation)" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Virhe luettaessa kahvasta: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Virhe suljettaessa kahvaa: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Virhe kirjoitettaessa kahvaan: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Muisti loppui" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Sisäinen virhe: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Tarvitaan lisää syötettä" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Virheellinen pakattu data" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: gio/tests/gdbus-daemon.c:20 +#, fuzzy +#| msgid "Print help" +msgid "Print address" +msgstr "Tulosta ohje" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Suorita dbus-palvelu" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "" + +#: glib/gbookmarkfile.c:768 +#, fuzzy, c-format +#| msgid "Unexpected attribute '%s' for element '%s'" +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Odottamaton ominaisuus â€%s†elementille â€%sâ€" + +#: glib/gbookmarkfile.c:779 glib/gbookmarkfile.c:859 glib/gbookmarkfile.c:869 +#: glib/gbookmarkfile.c:982 +#, fuzzy, c-format +#| msgid "Attribute '%s' of element '%s' not found" +msgid "Attribute “%s†of element “%s†not found" +msgstr "Ominaisuutta â€%s†elementille â€%s†ei löydy" + +#: glib/gbookmarkfile.c:1191 glib/gbookmarkfile.c:1256 +#: glib/gbookmarkfile.c:1320 glib/gbookmarkfile.c:1330 +#, fuzzy, c-format +#| msgid "Unexpected tag '%s', tag '%s' expected" +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Odottamaton merkintä â€%sâ€, odotettiin merkintää â€%sâ€" + +#: glib/gbookmarkfile.c:1216 glib/gbookmarkfile.c:1230 +#: glib/gbookmarkfile.c:1298 glib/gbookmarkfile.c:1344 +#, fuzzy, c-format +#| msgid "Unexpected tag '%s' inside '%s'" +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Odottamaton merkintä â€%s†kohdassa â€%sâ€" + +#: glib/gbookmarkfile.c:1624 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1827 +msgid "No valid bookmark file found in data dirs" +msgstr "Kelvollista kirjanmerkkitiedostoa ei löytynyt datahakemistoista" + +#: glib/gbookmarkfile.c:2028 +#, fuzzy, c-format +#| msgid "A bookmark for URI '%s' already exists" +msgid "A bookmark for URI “%s†already exists" +msgstr "URI:lle â€%s†on jo olemassa kirjanmerkki" + +#: glib/gbookmarkfile.c:2077 glib/gbookmarkfile.c:2235 +#: glib/gbookmarkfile.c:2320 glib/gbookmarkfile.c:2400 +#: glib/gbookmarkfile.c:2485 glib/gbookmarkfile.c:2619 +#: glib/gbookmarkfile.c:2752 glib/gbookmarkfile.c:2887 +#: glib/gbookmarkfile.c:2929 glib/gbookmarkfile.c:3026 +#: glib/gbookmarkfile.c:3147 glib/gbookmarkfile.c:3341 +#: glib/gbookmarkfile.c:3482 glib/gbookmarkfile.c:3701 +#: glib/gbookmarkfile.c:3790 glib/gbookmarkfile.c:3879 +#: glib/gbookmarkfile.c:3998 +#, fuzzy, c-format +#| msgid "No bookmark found for URI '%s'" +msgid "No bookmark found for URI “%sâ€" +msgstr "URI:lle â€%s†ei löydy kirjanmerkkiä" + +#: glib/gbookmarkfile.c:2409 +#, fuzzy, c-format +#| msgid "No MIME type defined in the bookmark for URI '%s'" +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "URI:n â€%s†kirjanmerkissä ei ole määritelty MIME-tyyppiä" + +#: glib/gbookmarkfile.c:2494 +#, fuzzy, c-format +#| msgid "No private flag has been defined in bookmark for URI '%s'" +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "URI:n â€%s†kirjanmerkissä ei ole määritelty yksityisyyslippua" + +#: glib/gbookmarkfile.c:3035 +#, fuzzy, c-format +#| msgid "No groups set in bookmark for URI '%s'" +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI:n â€%s†kirjanmerkissä ei ole asetettu ryhmiä" + +#: glib/gbookmarkfile.c:3503 glib/gbookmarkfile.c:3711 +#, fuzzy, c-format +#| msgid "No application with name '%s' registered a bookmark for '%s'" +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Sovellus nimeltä â€%s†ei rekisteröinyt kirjanmerkkiä kohteelle â€%sâ€" + +#: glib/gbookmarkfile.c:3734 +#, fuzzy, c-format +#| msgid "Failed to expand exec line '%s' with URI '%s'" +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Suoritettavaa riviä â€%s†ei voitu laajentaa URI:lla â€%sâ€" + +#: glib/gconvert.c:467 +#, fuzzy +#| msgid "Invalid sequence in conversion input" +msgid "Unrepresentable character in conversion input" +msgstr "Virheellinen sarja muunnettavassa syötteessä" + +#: glib/gconvert.c:494 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "Osittainen tavusarja syötteen lopussa" + +#: glib/gconvert.c:763 +#, fuzzy, c-format +#| msgid "Cannot convert fallback '%s' to codeset '%s'" +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Koodausmerkkijonoa â€%s†ei voi muuntaa merkistöön â€%sâ€" + +#: glib/gconvert.c:935 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "Virheellinen tavusarja muunnettavassa syötteessä" + +#: glib/gconvert.c:956 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "Virheellinen tavusarja muunnettavassa syötteessä" + +#: glib/gconvert.c:1641 +#, fuzzy, c-format +#| msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI â€%s†ei ole absoluuttinen URI â€fileâ€-muodossa" + +#: glib/gconvert.c:1651 +#, fuzzy, c-format +#| msgid "The local file URI '%s' may not include a '#'" +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Paikallinen tiedosto-URI â€%s†ei saa sisältää merkkiä â€#â€" + +#: glib/gconvert.c:1668 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI “%s†on virheellinen" + +#: glib/gconvert.c:1680 +#, fuzzy, c-format +#| msgid "The hostname of the URI '%s' is invalid" +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI:n â€%s†isäntänimi on virheellinen" + +#: glib/gconvert.c:1696 +#, fuzzy, c-format +#| msgid "The URI '%s' contains invalidly escaped characters" +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI â€%s†sisältää virheellisesti suojattuja merkkejä" + +#: glib/gconvert.c:1768 +#, fuzzy, c-format +#| msgid "The pathname '%s' is not an absolute path" +msgid "The pathname “%s†is not an absolute path" +msgstr "Polku â€%s†ei ole absoluuttinen" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e. %Bta %Y %H.%M.%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%-d.%-m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H.%M.%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "tammikuu" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "helmikuu" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "maaliskuu" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "huhtikuu" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "toukokuu" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "kesäkuu" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "heinäkuu" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "elokuu" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "syyskuu" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "lokakuu" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "marraskuu" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "joulukuu" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "tammi" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "helmi" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "maalis" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "huhti" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "touko" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "kesä" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "heinä" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "elo" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "syys" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "loka" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "marras" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "joulu" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "maanantai" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "tiistai" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "keskiviikko" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "torstai" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "perjantai" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "lauantai" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "sunnuntai" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ma" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ti" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ke" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "to" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "pe" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "la" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "su" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "tammikuu" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "helmikuu" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "maaliskuu" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "huhtikuu" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "toukokuu" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "kesäkuu" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "heinäkuu" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "elokuu" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "syyskuu" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "lokakuu" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "marraskuu" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "joulukuu" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "tammi" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "helmi" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "maalis" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "huhti" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "touko" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "kesä" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "heinä" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "elo" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "syys" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "loka" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "marras" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "joulu" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "ap." + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "ip." + +#: glib/gdir.c:154 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Virhe hakemiston “%s†avaamisessa: %s" + +#: glib/gfileutils.c:737 glib/gfileutils.c:829 +#, fuzzy, c-format +#| msgid "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ei voitu varata %lu tavua muistia tiedoston â€%s†lukemiseksi" +msgstr[1] "Ei voitu varata %lu tavua muistia tiedoston â€%s†lukemiseksi" + +#: glib/gfileutils.c:754 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Virhe lukiessa tiedostoa “%sâ€: %s" + +#: glib/gfileutils.c:790 +#, c-format +msgid "File “%s†is too large" +msgstr "Tiedosto “%s†on liian suuri" + +#: glib/gfileutils.c:854 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to read from file “%sâ€: %s" +msgstr "Tiedoston â€%s†lukeminen epäonnistui: %s" + +#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1476 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Tiedoston “%s†avaaminen epäonnistui: %s" + +#: glib/gfileutils.c:917 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Tiedoston â€%s†ominaisuuksien lukeminen epäonnistui: fstat() epäonnistui: %s" + +#: glib/gfileutils.c:948 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Tiedoston “%s†avaaminen epäonnistui: fdopen() epäonnistui: %s" + +#: glib/gfileutils.c:1049 +#, fuzzy, c-format +#| msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Tiedoston â€%s†uudelleen nimeäminen nimelle â€%s†epäonnistui: g_rename() " +"epäonnistui: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Tiedoston “%s†kirjoittaminen epäonnistui: write() epäonnistui: %s" + +#: glib/gfileutils.c:1196 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': fsync() failed: %s" +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Tiedoston â€%s†kirjoittaminen epäonnistui: fsync() epäonnistui: %s" + +#: glib/gfileutils.c:1365 glib/gfileutils.c:1780 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Tiedoston “%s†luominen epäonnistui: %s" + +#: glib/gfileutils.c:1410 +#, fuzzy, c-format +#| msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Olemassa olevan tiedoston â€%s†poisto epäonnistui: g_unlink epäonnistui: %s" + +#: glib/gfileutils.c:1745 +#, fuzzy, c-format +#| msgid "Template '%s' invalid, should not contain a '%s'" +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Malli â€%s†on virheellinen, se ei saa sisältää merkkijonoa â€%sâ€" + +#: glib/gfileutils.c:1758 +#, fuzzy, c-format +#| msgid "Template '%s' doesn't contain XXXXXX" +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Malli â€%s†ei sisällä merkkijonoa XXXXXX" + +#: glib/gfileutils.c:2318 glib/gfileutils.c:2347 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Symbolisen linkin “%s†lukeminen epäonnistui: %s" + +#: glib/giochannel.c:1405 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s': %s" +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Muunninta merkistöstä â€%s†merkistöön â€%s†ei voitu avata: %s" + +#: glib/giochannel.c:1758 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_line_string" +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Funktiossa g_io_channel_read_line_string ei voi suorittaa raakalukemista" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Jäljelle jäänyt muuntamaton data lukupuskurissa" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanava päättyy osittaiseen merkkiin" + +#: glib/giochannel.c:1949 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_to_end" +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Funktiossa g_io_channel_read_to_end ei voi suorittaa raakalukemista" + +#: glib/gkeyfile.c:789 +msgid "Valid key file could not be found in search dirs" +msgstr "Kelvollista avaintiedostoa ei löytynyt haetuista kansioista" + +#: glib/gkeyfile.c:826 +msgid "Not a regular file" +msgstr "Ei tavallinen tiedosto" + +#: glib/gkeyfile.c:1281 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains line '%s' which is not a key-value pair, group, or " +#| "comment" +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Avaintiedosto sisältää rivin â€%sâ€, joka ei ole avain-arvopari, ryhmä tai " +"kommentti" + +#: glib/gkeyfile.c:1338 +#, c-format +msgid "Invalid group name: %s" +msgstr "Virheellinen ryhmän nimi: %s" + +#: glib/gkeyfile.c:1360 +msgid "Key file does not start with a group" +msgstr "Avaintiedosto ei ala ryhmällä" + +#: glib/gkeyfile.c:1386 +#, c-format +msgid "Invalid key name: %s" +msgstr "Virheellinen avaimen nimi: %s" + +#: glib/gkeyfile.c:1413 +#, fuzzy, c-format +#| msgid "Key file contains unsupported encoding '%s'" +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Avaintiedosto sisältää ei-tuetun koodauksen â€%sâ€" + +#: glib/gkeyfile.c:1662 glib/gkeyfile.c:1835 glib/gkeyfile.c:3288 +#: glib/gkeyfile.c:3352 glib/gkeyfile.c:3482 glib/gkeyfile.c:3614 +#: glib/gkeyfile.c:3760 glib/gkeyfile.c:3995 glib/gkeyfile.c:4062 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Avaintiedostossa ei ole ryhmää “%sâ€" + +#: glib/gkeyfile.c:1790 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Avaintiedostossa ei ole avainta “%s†ryhmässä “%sâ€" + +#: glib/gkeyfile.c:1952 glib/gkeyfile.c:2068 +#, fuzzy, c-format +#| msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Avaintiedosto sisältää avaimen â€%s†arvolla â€%sâ€, joka ei ole UTF-8-" +"merkkijono" + +#: glib/gkeyfile.c:1972 glib/gkeyfile.c:2088 glib/gkeyfile.c:2530 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' which has a value that cannot be interpreted." +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Avaintiedosto sisältää avaimen â€%sâ€, jolla on arvo, jota ei voida tulkita." + +#: glib/gkeyfile.c:2748 glib/gkeyfile.c:3117 +#, fuzzy, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Avaintiedosto sisältää avaimen â€%sâ€, jolla on arvo, jota ei voida tulkita, " +"ryhmässä â€%sâ€." + +#: glib/gkeyfile.c:2826 glib/gkeyfile.c:2903 +#, fuzzy, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"Avaintiedosto sisältää avaimen â€%sâ€, jolla on arvo, jota ei voida tulkita, " +"ryhmässä â€%sâ€." + +#: glib/gkeyfile.c:4305 +msgid "Key file contains escape character at end of line" +msgstr "Avaintiedosto sisältää escape-jonon rivin lopussa" + +#: glib/gkeyfile.c:4327 +#, fuzzy, c-format +#| msgid "Key file contains invalid escape sequence '%s'" +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Avaintiedostossa on virheellinen escape-jono â€%sâ€" + +#: glib/gkeyfile.c:4471 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Arvoa “%s†ei voida tulkita numeroksi." + +#: glib/gkeyfile.c:4485 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Kokonaisluku “%s†on sallitun alueen ulkopuolella" + +#: glib/gkeyfile.c:4518 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Arvoa “%s†ei voida tulkita liukuluvuksi." + +#: glib/gkeyfile.c:4557 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Arvoa “%s†ei voida tulkita totuusarvoksi." + +#: glib/gmappedfile.c:129 +#, fuzzy, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Tiedoston â€%s†ominaisuuksien lukeminen epäonnistui: fstat() epäonnistui: %s" + +#: glib/gmappedfile.c:195 +#, fuzzy, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Tiedoston â€%s†mappaaminen epäonnistui: mmap() epäonnistui: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Tiedoston “%s†avaaminen epäonnistui: open() epäonnistui: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Virhe rivillä %d merkissä %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, fuzzy, c-format +#| msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Virheellinen UTF-8-koodattu teksti nimessä - epäkelpo â€%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +#| msgid "'%s' is not a valid name" +msgid "“%s†is not a valid name" +msgstr "“%s†ei ole kelvollinen nimi" + +#: glib/gmarkup.c:489 +#, c-format +#| msgid "'%s' is not a valid name: '%c'" +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†ei ole kelvollinen nimi: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Virhe rivillä %d: %s" + +#: glib/gmarkup.c:690 +#, fuzzy, c-format +#| msgid "" +#| "Failed to parse '%-.*s', which should have been a digit inside a " +#| "character reference (ê for example) - perhaps the digit is too large" +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Merkkijonon â€%-.*s†piti olla luku merkkiviitteen sisällä (esim. ê), " +"mutta sen jäsentäminen epäonnistui - ehkä luku on liian suuri" + +#: glib/gmarkup.c:702 +#, fuzzy +#| msgid "" +#| "Character reference did not end with a semicolon; most likely you used an " +#| "ampersand character without intending to start an entity - escape " +#| "ampersand as &" +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Merkkiviite ei päättynyt puolipisteeseen; todennäköisesti käytit &-merkkiä " +"aikomatta aloittaa entiteettiä - käytä merkintää &" + +#: glib/gmarkup.c:728 +#, fuzzy, c-format +#| msgid "Character reference '%-.*s' does not encode a permitted character" +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Merkkiviite â€%-.*s†ei ole sallitun merkin koodaus" + +#: glib/gmarkup.c:766 +#, fuzzy +#| msgid "" +#| "Empty entity '&;' seen; valid entities are: & " < > '" +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Havaittu tyhjä entiteetti â€&;â€; kelvolliset ovat: & " < > " +"'" + +#: glib/gmarkup.c:774 +#, fuzzy, c-format +#| msgid "Entity name '%-.*s' is not known" +msgid "Entity name “%-.*s†is not known" +msgstr "Entiteetin nimi â€%-.*s†on tuntematon" + +#: glib/gmarkup.c:779 +#, fuzzy +#| msgid "" +#| "Entity did not end with a semicolon; most likely you used an ampersand " +#| "character without intending to start an entity - escape ampersand as &" +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entiteetti ei päättynyt puolipisteeseen; todennäköisesti käytit &-merkkiä " +"aikomatta aloittaa entiteettiä - käytä merkintää &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Asiakirjan on alettava elementillä (esim. )" + +#: glib/gmarkup.c:1233 +#, fuzzy, c-format +#| msgid "" +#| "'%s' is not a valid character following a '<' character; it may not begin " +#| "an element name" +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"â€%s†ei ole kelvollinen merkki â€<â€-merkin jälkeen; se ei voi aloittaa " +"elementin nimeä" + +#: glib/gmarkup.c:1276 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' character to end the empty-element tag " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "Pariton merkki â€%sâ€, odotettiin â€>â€-merkkiä päättämään elementin â€%sâ€" + +#: glib/gmarkup.c:1346 +#, fuzzy, c-format +#| msgid "Unexpected attribute '%s' for element '%s'" +msgid "Too many attributes in element “%sâ€" +msgstr "Odottamaton ominaisuus â€%s†elementille â€%sâ€" + +#: glib/gmarkup.c:1366 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '=' after attribute name '%s' of element " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Pariton merkki â€%1$sâ€, odotettiin â€=â€-merkkiä elementin â€%3$s†ominaisuuden " +"â€%2$s†jälkeen" + +#: glib/gmarkup.c:1408 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' or '/' character to end the start tag " +#| "of element '%s', or optionally an attribute; perhaps you used an invalid " +#| "character in an attribute name" +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Pariton merkki â€%sâ€, odotettiin merkkiä â€>†tai â€/†päättämään elementin " +"â€%s†aloituslippu, tai mahdollista ominaisuutta; käytit ehkä ominaisuuden " +"nimessä siihen kelpaamatonta merkkiä" + +#: glib/gmarkup.c:1453 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected an open quote mark after the equals sign " +#| "when giving value for attribute '%s' of element '%s'" +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Pariton merkki â€%1$sâ€, odotettiin avaavaa lainausmerkkiä yhtäsuuruusmerkin " +"jälkeen annettaessa elementin â€%3$s†ominaisuuden â€%2$s†arvoa" + +#: glib/gmarkup.c:1587 +#, fuzzy, c-format +#| msgid "" +#| "'%s' is not a valid character following the characters ''" +msgid "" +"“%s†is not a valid character following the close element name “%sâ€; the " +"allowed character is “>â€" +msgstr "" +"â€%s†ei ole kelvollinen merkki sulkuelementin â€%s†jälkeen; sallittu merkki " +"on â€>â€" + +#: glib/gmarkup.c:1637 +#, fuzzy, c-format +#| msgid "Element '%s' was closed, no element is currently open" +msgid "Element “%s†was closed, no element is currently open" +msgstr "Elementti â€%s†on suljettu, ei avoimia elementtejä" + +#: glib/gmarkup.c:1646 +#, fuzzy, c-format +#| msgid "Element '%s' was closed, but the currently open element is '%s'" +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"Elementti â€%s†on suljettu, mutta tällä hetkellä on avoinna elementti â€%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Asiakirja oli tyhjä tai sisälsi vain tyhjiä merkkejä" + +#: glib/gmarkup.c:1813 +#, fuzzy +#| msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Asiakirja loppui odottamattomasti heti avoimen kulmasulkeen â€<†jälkeen" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, fuzzy, c-format +#| msgid "" +#| "Document ended unexpectedly with elements still open - '%s' was the last " +#| "element opened" +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Asiakirja loppui odottamattomasti elementtien ollessa sulkematta - â€%s†oli " +"viimeinen avattu elementti" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Asiakirja loppui odottamattomasti, odotettiin lipun <%s/> sulkevaa " +"kulmasuljetta" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Asiakirja loppui odottamattomasti elementin nimen kohdalla" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Asiakirja loppui odottamattomasti ominaisuuden nimen kohdalla" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Asiakirja loppui odottamattomasti elementin avauslipun kohdalla" + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Asiakirja loppui odottamattomasti ominaisuuden nimen jälkeisen " +"yhtäsuuruusmerkin jälkeen; ominaisuudella ei ole arvoa" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Asiakirja loppui odottamattomasti ominaisuuden arvon kohdalla" + +#: glib/gmarkup.c:1876 +#, fuzzy, c-format +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Asiakirja loppui odottamattomasti elementin â€%s†sulkulipun kohdalla" + +#: glib/gmarkup.c:1880 +#, fuzzy +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "Asiakirja loppui odottamattomasti elementin â€%s†sulkulipun kohdalla" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Asiakirja loppui odottamattomasti kommentin tai käsittelykomennon kohdalla" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[VALITSIN…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Ohjevalitsimet:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Näytä ohjevalitsimet" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Näytä kaikki ohjevalitsimet" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Sovelluksen valitsimet:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Valitsimet:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, fuzzy, c-format +#| msgid "Cannot parse integer value '%s' for %s" +msgid "Cannot parse integer value “%s†for %s" +msgstr "Kokonaislukua â€%s†ei voida tulkita kohteelle %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, fuzzy, c-format +#| msgid "Integer value '%s' for %s out of range" +msgid "Integer value “%s†for %s out of range" +msgstr "Kokonaisluku â€%s†kohteelle %s on ylittää sallitun alueen" + +#: glib/goption.c:1160 +#, fuzzy, c-format +#| msgid "Cannot parse double value '%s' for %s" +msgid "Cannot parse double value “%s†for %s" +msgstr "Kokonaislukua â€%s†ei voida tulkita kohteelle %s" + +#: glib/goption.c:1168 +#, fuzzy, c-format +#| msgid "Double value '%s' for %s out of range" +msgid "Double value “%s†for %s out of range" +msgstr "Double-arvo â€%s†kohteelle %s ylittää sallitun alueen" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Virhe käsiteltäessä valitsinta %s" + +#: glib/goption.c:1570 glib/goption.c:1683 +#, c-format +msgid "Missing argument for %s" +msgstr "Puuttuva argumentti kohteelle %s" + +#: glib/goption.c:2194 +#, c-format +msgid "Unknown option %s" +msgstr "Tuntematon valitsin %s" + +#: glib/gregex.c:257 +msgid "corrupted object" +msgstr "vioittunut kohde" + +#: glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "sisäinen virhe tai vioittunut kohde" + +#: glib/gregex.c:261 +msgid "out of memory" +msgstr "muisti loppui" + +#: glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "taakseviittausten raja saavutettu" + +#: glib/gregex.c:278 glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"malli sisältää kohtia, jotka eivät ole tuettu osittaisessa täsmäyksessä" + +#: glib/gregex.c:280 +msgid "internal error" +msgstr "sisäinen virhe" + +#: glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "takaisinviittaukset ehtoina eivät ole tuettu osittaisissa täsmäyksissä" + +#: glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "rekursion enimmäissyvyys saavutettiin" + +#: glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "virheellinen yhdistelmä rivinvaihtolippuja" + +#: glib/gregex.c:301 +msgid "bad offset" +msgstr "virheellinen siirros" + +#: glib/gregex.c:303 +msgid "short utf8" +msgstr "lyhyt utf8" + +#: glib/gregex.c:305 +msgid "recursion loop" +msgstr "" + +#: glib/gregex.c:309 +msgid "unknown error" +msgstr "tuntematon virhe" + +#: glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ mallin lopussa" + +#: glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c mallin lopussa" + +#: glib/gregex.c:335 +#, fuzzy +#| msgid "unrecognized character follows " +msgid "unrecognized character following \\" +msgstr "Tuntematon merkki \\:n jälkeen" + +#: glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "numerot epäjärjestyksessä {}-määreessä" + +#: glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "numerot liian suuria {}-määreessä" + +#: glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "merkkiluokasta puuttuu päättävä ]" + +#: glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "virheellinen escape-jono merkkiluokassa" + +#: glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "alue epäjärjestyksessä merkkijoukolle" + +#: glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "ei mitään toistettavaa" + +#: glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "odottamaton toisto" + +#: glib/gregex.c:360 +#, fuzzy +#| msgid "unrecognized character after (?" +msgid "unrecognized character after (? or (?-" +msgstr "tuntematon merkki (? jälkeen" + +#: glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX:in nimetyt luokat on tuettu vain luokan sisällä" + +#: glib/gregex.c:366 +msgid "missing terminating )" +msgstr "päättävä ) puuttuu" + +#: glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "viittaus olemattomaan alitäsmäykseen" + +#: glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "puuttuva ) kommentin jälkeen" + +#: glib/gregex.c:375 +#, fuzzy +#| msgid "regular expression too large" +msgid "regular expression is too large" +msgstr "säännöllinen lauseke on liian suuri" + +#: glib/gregex.c:378 +msgid "failed to get memory" +msgstr "muistia ei voitu varata" + +#: glib/gregex.c:382 +msgid ") without opening (" +msgstr ") ilman aloittavaa (-merkkiä" + +#: glib/gregex.c:386 +msgid "code overflow" +msgstr "koodin ylivuoto" + +#: glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "tuntematon merkki (?< jälkeen" + +#: glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind-tyyppinen assert-makro ei ole kiinteäpituinen" + +#: glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "virheellinen numero tai nimi (?( jälkeen" + +#: glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "ehdollisessa ryhmässä on enemmän kuin kaksi haaraa" + +#: glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "assert-makrotoiminto odotettu merkkien (?( jälkeen" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R tai (?[+-]numeroita täytyy seurata )" + +#: glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "tuntematon POSIX-luokan nimi" + +#: glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "POSIX-vertailuelementtejä ei tueta" + +#: glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "Merkin arvo sekvenssissä \\x{…} on liian suuri" + +#: glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "virheellinen ehto (?(0)" + +#: glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C ei ole sallittu lookbehind-tyyppisissä assert-makroissa" + +#: glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "rekursiivinen kutsu voisi olla päättymätön" + +#: glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "tuntematon merkki (?P jälkeen" + +#: glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "alimallin nimestä puuttuu päätösmerkki" + +#: glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "kahdella nimetyllä alimallilla on sama nimi" + +#: glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "väärin muotoiltu \\P- tai \\p-sekvenssi" + +#: glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "tuntematon ominaisuuden nimi \\P- tai \\p-sekvenssin jälkeen" + +#: glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "alimallin nimi on liian pitkä (enintään 32 merkkiä)" + +#: glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "liian monta nimettyä alimallia (enintään 10000)" + +#: glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "oktaaliarvo on suurempi kuin \\377" + +#: glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "käännöksen työalueen koko loppui kesken" + +#: glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "aiemmin tarkistettua ja viitattua alimallia ei löydy" + +#: glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE-ryhmä sisältää useampia kuin yhden haaran" + +#: glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "epäyhtenäisiä NEWLINE-valitsimia" + +#: glib/gregex.c:476 +#, fuzzy +#| msgid "" +#| "\\g is not followed by a braced name or an optionally braced non-zero " +#| "number" +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g:n jälkeen ei tule nimeä aaltosulkeissa tai nollasta poikkeavaa numeroa " +"valinnaisesti aaltosulkeissa" + +#: glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "" + +#: glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "" + +#: glib/gregex.c:489 +msgid "number is too big" +msgstr "numero on liian suuri" + +#: glib/gregex.c:492 +#, fuzzy +#| msgid "missing terminator in subpattern name" +msgid "missing subpattern name after (?&" +msgstr "alimallin nimestä puuttuu päätösmerkki" + +#: glib/gregex.c:495 +#, fuzzy +#| msgid "digit expected" +msgid "digit expected after (?+" +msgstr "odotettiin numeroa" + +#: glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: glib/gregex.c:501 +#, fuzzy +#| msgid "two named subpatterns have the same name" +msgid "different names for subpatterns of the same number are not allowed" +msgstr "kahdella nimetyllä alimallilla on sama nimi" + +#: glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "" + +#: glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: glib/gregex.c:510 +#, fuzzy +#| msgid "" +#| "\\g is not followed by a braced name or an optionally braced non-zero " +#| "number" +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\g:n jälkeen ei tule nimeä aaltosulkeissa tai nollasta poikkeavaa numeroa " +"valinnaisesti aaltosulkeissa" + +#: glib/gregex.c:513 +#, fuzzy +#| msgid "URIs not supported" +msgid "\\N is not supported in a class" +msgstr "URI:ja ei tueta" + +#: glib/gregex.c:516 +msgid "too many forward references" +msgstr "" + +#: glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: glib/gregex.c:522 +#, fuzzy +#| msgid "character value in \\x{...} sequence is too large" +msgid "character value in \\u.... sequence is too large" +msgstr "Merkin arvo sekvenssissä \\x{…} on liian suuri" + +#: glib/gregex.c:745 glib/gregex.c:1983 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Virhe täsmätessä säännöllistä lauseketta %s: %s" + +#: glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE-kirjasto on käännetty ilman UTF8-tukea" + +#: glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE-kirjasto on käännetty ilman UTF8-ominaisuuksien tukea" + +#: glib/gregex.c:1328 +#, fuzzy +#| msgid "PCRE library is compiled without UTF8 properties support" +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE-kirjasto on käännetty ilman UTF8-ominaisuuksien tukea" + +#: glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Virhe optimoitaessa säännöllistä lauseketta %s: %s" + +#: glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Virhe säännöllisessä lausekkeessa %s kohdassa %d: %s" + +#: glib/gregex.c:2419 +#, fuzzy +#| msgid "hexadecimal digit or '}' expected" +msgid "hexadecimal digit or “}†expected" +msgstr "odotettiin heksadesimaalista numeroa tai merkkiä â€}â€" + +#: glib/gregex.c:2435 +msgid "hexadecimal digit expected" +msgstr "odotettiin heksadesimaalista numeroa" + +#: glib/gregex.c:2475 +#, fuzzy +#| msgid "missing '<' in symbolic reference" +msgid "missing “<†in symbolic reference" +msgstr "merkki '<' puuttuu symbolisesta viitteestä" + +#: glib/gregex.c:2484 +msgid "unfinished symbolic reference" +msgstr "päättämätön symbolinen viite" + +#: glib/gregex.c:2491 +msgid "zero-length symbolic reference" +msgstr "nollan mittainen symbolinen viite" + +#: glib/gregex.c:2502 +msgid "digit expected" +msgstr "odotettiin numeroa" + +#: glib/gregex.c:2520 +msgid "illegal symbolic reference" +msgstr "virheellinen symbolinen viite" + +#: glib/gregex.c:2583 +#, fuzzy +#| msgid "stray final '\\'" +msgid "stray final “\\â€" +msgstr "ylimääräinen päättävä '\\'" + +#: glib/gregex.c:2587 +msgid "unknown escape sequence" +msgstr "tuntematon escape-jono" + +#: glib/gregex.c:2597 +#, fuzzy, c-format +#| msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Virhe tulkittaessa korvaavaa tekstiä â€%s†kohdassa %lu: %s" + +#: glib/gshell.c:94 +#, fuzzy +#| msgid "Quoted text doesn't begin with a quotation mark" +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Lainattu teksti ei ala lainausmerkillä" + +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Pariton lainausmerkki komentorivillä tai muussa kuorisuojatussa tekstissä" + +#: glib/gshell.c:580 +#, fuzzy, c-format +#| msgid "Text ended just after a '\\' character. (The text was '%s')" +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Teksti loppui aivan merkin â€\\†jälkeen. (Teksti oli â€%sâ€)" + +#: glib/gshell.c:587 +#, fuzzy, c-format +#| msgid "" +#| "Text ended before matching quote was found for %c. (The text was '%s')" +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Teksti loppui ennen kuin löytyi merkkiä %c vastaava lainausmerkki. (Teksti " +"oli â€%sâ€)" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Teksti oli tyhjä (tai sisälsi vain tyhjiä merkkejä)" + +#: glib/gspawn.c:318 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Datan lukeminen lapsiprosessilta epäonnistui (%s)" + +#: glib/gspawn.c:465 +#, fuzzy, c-format +#| msgid "Unexpected error in select() reading data from a child process (%s)" +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "" +"Odottamaton virhe funktiossa select() lapsiprosessilta dataa luettaessa (%s)" + +#: glib/gspawn.c:550 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Odottamaton virhe funktiossa waitpid() (%s)" + +#: glib/gspawn.c:1154 glib/gspawn-win32.c:1383 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Lapsiprosessi sulkeutui koodilla %ld" + +#: glib/gspawn.c:1162 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Lapsiprosessi tapettu signaalilla %ld" + +#: glib/gspawn.c:1169 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Lapsiprosessi pysäytetty signaalilla %ld" + +#: glib/gspawn.c:1176 +#, c-format +msgid "Child process exited abnormally" +msgstr "Lapsiprosessi sulkeutui epänormaalisti" + +#: glib/gspawn.c:1767 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Lukeminen lapsiprosessin putkesta epäonnistui (%s)" + +#: glib/gspawn.c:2069 +#, fuzzy, c-format +#| msgid "Failed to execute child process “%s†(%s)" +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Lapsiprosessin “%s†käynnistäminen epäonnistui (%s)" + +#: glib/gspawn.c:2186 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Haarauttaminen epäonnistui (%s)" + +#: glib/gspawn.c:2346 glib/gspawn-win32.c:381 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Hakemistoon “%s†siirtyminen epäonnistui (%s)" + +#: glib/gspawn.c:2356 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Lapsiprosessin “%s†käynnistäminen epäonnistui (%s)" + +#: glib/gspawn.c:2366 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Lapsiprosessin tulosteen tai syötteen uudelleenohjaus epäonnistui (%s)" + +#: glib/gspawn.c:2375 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Lapsiprosessin haarauttaminen epäonnistui (%s)" + +#: glib/gspawn.c:2383 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Tuntematon virhe käynnistettäessä lapsiprosessia “%sâ€" + +#: glib/gspawn.c:2407 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Lapsiprosessin pid-putkesta ei voitu lukea riittävästi dataa (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "Datan lukeminen lapsiprosessilta epäonnistui" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Putken luominen lapsiprosessin kanssa viestintää varten epäonnistui (%s)" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Lapsiprosessin käynnistys epäonnistui (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "Virheellinen ohjelman nimi: %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:757 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Virheellinen merkkijono argumenttivektorin kohdassa %d: %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:772 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Virheellinen merkkijono ympäristössä: %s" + +#: glib/gspawn-win32.c:753 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Virhe työhakemisto: %s" + +#: glib/gspawn-win32.c:815 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Apuohjelman suoritus epäonnistui (%s)" + +#: glib/gspawn-win32.c:1042 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Odottamaton virhe funktiossa g_io_channel_win32_poll() luettaessa dataa " +"lapsiprosessilta" + +#: glib/gstrfuncs.c:3338 glib/gstrfuncs.c:3440 +msgid "Empty string is not a number" +msgstr "" + +#: glib/gstrfuncs.c:3362 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name" +msgid "“%s†is not a signed number" +msgstr "'%s' ei ole kelvollinen nimi" + +#: glib/gstrfuncs.c:3372 glib/gstrfuncs.c:3476 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: glib/gstrfuncs.c:3466 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name" +msgid "“%s†is not an unsigned number" +msgstr "'%s' ei ole kelvollinen nimi" + +#: glib/guri.c:315 +#, fuzzy, no-c-format +#| msgid " (invalid encoding)" +msgid "Invalid %-encoding in URI" +msgstr " (virheellinen merkistökoodaus)" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:645 glib/guri.c:657 +#, fuzzy, c-format +#| msgid "Could not parse '%s' as IP address mask" +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Tekstiä %s ei voitu jäsentää IP-osoitepeitteeksi" + +#: glib/guri.c:664 +#, fuzzy, c-format +#| msgid "Double value '%s' for %s out of range" +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Double-arvo â€%s†kohteelle %s ylittää sallitun alueen" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, fuzzy, c-format +#| msgid "The pathname '%s' is not an absolute path" +msgid "URI ‘%s’ is not an absolute URI" +msgstr "Polku â€%s†ei ole absoluuttinen" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "" + +#: glib/guri.c:1435 +msgid "URI is not absolute, and no base URI was provided" +msgstr "" + +#: glib/guri.c:2209 +msgid "Missing ‘=’ and parameter value" +msgstr "" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "Muistia ei voitu varata" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "Merkki on sallitun UTF-8-välin ulkopuolella" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "Virheellinen sarja muunnettavassa syötteessä" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "Merkki on sallitun UTF-16-välin ulkopuolella" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2767 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kt" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2769 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mt" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2771 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Gt" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2773 +#, c-format +msgid "%.1f TB" +msgstr "%.1f Tt" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2775 +#, c-format +msgid "%.1f PB" +msgstr "%.1f Pt" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2777 +#, c-format +msgid "%.1f EB" +msgstr "%.1f Et" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2781 +#, c-format +#| msgid "%.1f KiB" +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2783 +#, c-format +#| msgid "%.1f MiB" +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2785 +#, c-format +#| msgid "%.1f GiB" +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2787 +#, c-format +#| msgid "%.1f TiB" +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2789 +#, c-format +#| msgid "%.1f PiB" +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2791 +#, c-format +#| msgid "%.1f EiB" +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2795 +#, c-format +#| msgid "%.1f kb" +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2797 +#, c-format +#| msgid "%.1f Mb" +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2799 +#, c-format +#| msgid "%.1f Gb" +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2801 +#, c-format +#| msgid "%.1f Tb" +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2803 +#, c-format +#| msgid "%.1f Pb" +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2805 +#, c-format +#| msgid "%.1f Eb" +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2809 +#, c-format +#| msgid "%.1f Kib" +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2811 +#, c-format +#| msgid "%.1f Mib" +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2813 +#, c-format +#| msgid "%.1f Gib" +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2815 +#, c-format +#| msgid "%.1f Tib" +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2817 +#, c-format +#| msgid "%.1f Pib" +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2819 +#, c-format +#| msgid "%.1f Eib" +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2853 glib/gutils.c:2970 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u tavu" +msgstr[1] "%u tavua" + +#: glib/gutils.c:2857 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bitti" +msgstr[1] "%u bittiä" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2924 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s tavu" +msgstr[1] "%s tavua" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2929 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bitti" +msgstr[1] "%s bittiä" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2983 +#, c-format +msgid "%.1f KB" +msgstr "%.1f kt" + +#: glib/gutils.c:2988 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mt" + +#: glib/gutils.c:2993 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Gt" + +#: glib/gutils.c:2998 +#, c-format +msgid "%.1f TB" +msgstr "%.1f Tt" + +#: glib/gutils.c:3003 +#, c-format +msgid "%.1f PB" +msgstr "%.1f Pt" + +#: glib/gutils.c:3008 +#, c-format +msgid "%.1f EB" +msgstr "%.1f Et" + +#, fuzzy +#~| msgid "Error in address '%s' - the family attribute is malformed" +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Virhe osoitteessa â€%s†- perheattribuutti on epämuodostunut" + +#~ msgid "No such method '%s'" +#~ msgstr "Ei metodia â€%sâ€" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Ei voitu päätellä väyläosoitetta DBUS_STARTER_BUS_TYPE-" +#~ "ympäristömuuttujasta - tuntematon arvo â€%sâ€" + +#, fuzzy +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Ei voitu ladata /var/lib/dbus/machine-id: " + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Väliaikaistiedoston luominen epäonnistui: %s" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; ohitetaan syrjäytys tälle avaimelle.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " ja --strict oli määritetty; lopetetaan.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Ohitetaan syrjäytys tälle avaimelle.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "ei tehdä mitään.\n" + +#~ msgid "Unknown error on connect" +#~ msgstr "Tuntematon virhe yhteydenotossa" + +#, fuzzy +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Viestissä on %d tiedostokahvaa mutta otsakekenttä ilmoittaa %d " +#~ "tiedostokahvaa" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Virhe: oliopolkua ei määritelty\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Virhe: signaalia ei määritetty.\n" + +#, fuzzy +#~| msgid "Error: signal not specified.\n" +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Virhe: signaalia ei määritetty.\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Virhe luotaessa hakemistoa â€%sâ€: %s" + +#~ msgid "No such interface" +#~ msgstr "Ei rajapintaa" + +#, fuzzy +#~| msgid "Error setting extended attribute '%s': %s" +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Virhe asetettaessa laajennettua ominaisuutta â€%sâ€: %s" + +#, fuzzy +#~| msgid "Error launching application: %s" +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Virhe käynnistettäessä ohjelmaa: %s" + +#, fuzzy +#~| msgid "Error connecting: %s\n" +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Virhe yhteydenotossa: %s\n" + +#, fuzzy +#~| msgid "Error closing socket: %s" +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Virhe suljettaessa pistoketta: %s" + +#, fuzzy +#~| msgid "Error setting owner: %s" +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Virhe asetettaessa omistajaa: %s" + +#, fuzzy +#~| msgid "Error connecting: %s\n" +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Virhe yhteydenotossa: %s\n" + +#, fuzzy +#~| msgid "Error setting extended attribute '%s': %s" +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Virhe asetettaessa laajennettua ominaisuutta â€%sâ€: %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Virhe avattaessa tiedostoa â€%sâ€: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Virhe tiedoston â€%s†lukemisessa: %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Virhe nimettäessä tiedostoa uudestaan: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Virhe avattaessa tiedostoa: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Virhe luotaessa kansiota: %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Paikallista kansiontarkkailun oletustyyppiä ei voi selvittää" + +#~ msgid "association changes not supported on win32" +#~ msgstr "assosiaation muutokset eivät ole tuettu win32-alustalla" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Assosiaation luonti ei ole tuettu win32-alustalla" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "" +#~ "Epänormaali ohjelman päättyminen käynnistettäessä komentoriviä â€%sâ€: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "Komentorivi â€%s†lopetti nollasta eroavaan lopetustilaan %d: %s" + +#, fuzzy +#~ msgid "Error processing input file with xmllint" +#~ msgstr "" +#~ "Virhe asetettaessa symbolista linkkiä: tiedosto ei ole symbolinen linkki" + +#~ msgid "No service record for '%s'" +#~ msgstr "Ei palvelutietuetta â€%sâ€" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Odottamaton valitsinpituus tarkistettaessa onko SO_PASSCRED käytössä " +#~ "pistokkeelle. Odotettiin %d tavua, saatiin %d" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "" +#~ "Tiedoston â€%s†avaaminen kirjoitettavaksi epäonnistui: fdopen() " +#~ "epäonnistui: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Tiedoston â€%s†kirjoittaminen epäonnistui: fflush() epäonnistui: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Tiedoston â€%s†sulkeminen epäonnistui: fclose() epäonnistui: %s" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Avaintiedostossa ei ole avainta â€%sâ€" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "työtilan raja tyhjille alamerkkijonoille saavutettiin" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "merkkikokoa muuttavia ohjaimia (\\l, \\L, \\u, \\U) ei sallita tässä" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE-ryhmän toisto ei ole sallittu" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..d7b5f55 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,6539 @@ +# French translation of glib. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# +# Christophe Merlet , 2001-2006. +# Benoît Dejean , 2005. +# Jonathan Ernst , 2006. +# Robert-André Mauchin , 2006-2008. +# Stéphane Raimbault , 2007. +# Claude Paroz , 2007-2021. +# Bruno Brouard , 2010-2012. +# Gérard Baylard , 2010. +# Alexandre Franke , 2012. +# Thibault Martin , 2020. +# Guillaume Bernard , 2021. +# Charles Monzat , 2016-2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-05-18 14:09+0000\n" +"PO-Revision-Date: 2022-05-21 23:04+0200\n" +"Last-Translator: Charles Monzat \n" +"Language-Team: GNOME French Team \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Gtranslator 40.0\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "" +"La définition des applications par défaut n’est pas encore prise en charge" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"La définition de l’application comme étant la dernière utilisée pour le type " +"n’est pas encore prise en charge" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Options GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Afficher les options GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Entrer dans le mode de service GApplication (utiliser à partir des fichiers " +"de service D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Remplacer l’identifiant d’application" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Remplacer l’instance en cours" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Afficher l’aide" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMMANDE]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Afficher la version" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Afficher les informations de version et quitter" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Lister les applications" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Afficher la liste des applications installées activables par D-Bus (par " +"fichiers .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Lancer une application" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Lancer l’application (avec d’éventuels fichiers à ouvrir)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "ID_APP [FICHIER…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Activer une action" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invoquer une action sur l’application" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ID_APP ACTION [PARAMÈTRE]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Afficher les actions disponibles" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"Afficher la liste des actions statiques d’une application (à partir du " +"fichier .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ID_APP" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMMANDE" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "La commande pour laquelle l’aide détaillée doit être affichée" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Identifiant d’application au format D-Bus (ex. : org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FICHIER" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Noms de fichiers relatifs ou absolus ou URI à ouvrir" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACTION" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Nom de l’action à invoquer" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMÈTRE" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Paramètre facultatif pour l’invocation de l’action, au format GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Commande inconnue %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Utilisation :\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Paramètres :\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[PARAMS…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Commandes :\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilisez « %s help COMMANDE » pour obtenir de l’aide détaillée.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"La commande %s exige un identifiant d’application à suivre directement\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "identifiant d’application non valide : « %s »\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"« %s » n’accepte aucun paramètre\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "impossible de se connecter à D-Bus : %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "erreur d’envoi du message %s à l’application : %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "un nom d’action doit être indiqué après l’identifiant d’application\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nom d’action non valide : « %s »\n" +"les noms d’actions ne peuvent contenir que des caractères alphanumériques, " +"« - » et « . »\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "erreur d’analyse du paramètre d’action : %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "les actions n’acceptent pas plus d’un paramètre\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "la commande list-actions n’accepte que l’identifiant de l’application" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "impossible de trouver le fichier desktop pour l’application %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"commande non reconnue : %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "La valeur de comptage fournie à %s est trop grande" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Le positionnement n’est pas pris en charge sur le flux de base" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Impossible de tronquer GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Le flux est déjà fermé" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "La troncature n’est pas prise en charge sur le flux de base" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "L’opération a été annulée" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Objet non valide, non initialisé" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Séquence multi-octet incomplète en entrée" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Espace insuffisant dans la destination" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Séquence d’octets incorrecte en entrée du convertisseur" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Erreur lors de la conversion : %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Initialisation annulable non prise en charge" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "" +"La conversion du jeu de caractères « %s » vers « %s » n’est pas prise en " +"charge" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Impossible d’ouvrir le convertisseur de « %s » vers « %s »" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "Type %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Type inconnu" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "Type de fichier %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials contient des données non valables" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials n’est pas implémenté sur ce système d’exploitation" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Il n’y a pas de prise en charge de GCredentials pour votre plate-forme" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"GCredentials ne contient pas d’identifiant de processus sur ce système " +"d’exploitation" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" +"L’usurpation d’identité n’est pas possible sur ce système d’exploitation" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Fin précoce de flux inattendue" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Clé « %s » non prise en charge dans l’élément d’adresse « %s »" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" +"Combinaison clé/valeur sans signification dans l’élément d’adresse « %s »" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"L’adresse « %s » n’est pas valide (nécessite exactement une des clés de " +"« path », « dir », « tmpdir » ou « abstract »)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Erreur dans l’adresse « %s » — l’attribut « %s » est mal formé" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transport « %s » inconnu ou non pris en charge pour l’adresse « %s »" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "" +"L’élément d’adresse « %s » ne comporte pas de caractère deux-points (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" +"Le nom de transport dans l’élément d’adresse « %s » ne doit pas être vide" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Le couple clé/valeur %d, « %s », dans l’élément d’adresse « %s » ne comporte " +"pas de signe égal" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Le couple clé/valeur %d, « %s », dans l’élément d’adresse « %s » ne doit pas " +"avoir une clé vide" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Erreur lors du décodage de la clé ou de la valeur dans le couple clé/valeur " +"%d, « %s », dans l’élément d’adresse « %s »" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Erreur dans l’adresse « %s » — le transport Unix requiert que soit " +"exactement définie une des clés « path » ou « abstract »" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Erreur dans l’adresse « %s » — l’attribut de l’hôte est manquant ou mal formé" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Erreur dans l’adresse « %s » — l’attribut du port est manquant ou mal formé" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Erreur dans l’adresse « %s » — l’attribut du fichier à dénomination unique " +"est manquant ou mal formé" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Erreur de lancement automatique :" + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "" +"Erreur lors de l’ouverture du fichier à dénomination unique « %s » : %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Erreur de lecture du fichier à dénomination unique « %s » : %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Erreur de lecture du fichier à dénomination unique « %s », 16 octets " +"attendus, %d reçus" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Erreur d’écriture du contenu du fichier à numérotation unique « %s » sur le " +"flux :" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "L’adresse indiquée est vide" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Impossible de générer dynamiquement un bus messages quand AT_SECURE est " +"défini" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Impossible de générer dynamiquement un bus messages sans identifiant " +"machine : " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Impossible de lancer automatiquement D-Bus sans $DISPLAY X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Erreur lors de la génération de la ligne de commande « %s » : " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Impossible de déterminer l’adresse du bus de session (non pris en charge " +"pour ce système d’exploitation)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Impossible de déterminer l’adresse du bus à partir de la variable " +"d’environnement DBUS_STARTER_BUS_TYPE — valeur inconnue « %s »" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Impossible de déterminer l’adresse du bus étant donné que la variable " +"d’environnement DBUS_STARTER_BUS_TYPE n’est pas définie" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Type de bus %d inconnu" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Manque de contenu imprévu lors de la tentative de lecture d’une ligne" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Manque de contenu imprévu lors de la tentative de lecture (sécurisée) d’une " +"ligne" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Tous les mécanismes d’authentification disponibles ont été épuisés (tentés : " +"%s) (disponibles : %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" +"Les identifiants des utilisateurs doivent être identiques pour le pair et le " +"serveur" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Annulé via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "" +"Erreur lors de la récupération d’information sur le répertoire « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Les droits d’accès au répertoire « %s » sont mal formés. Mode 0700 attendu, " +"0%o obtenu" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Erreur lors de la création du répertoire « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Opération non prise en charge" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Erreur lors de l’ouverture du trousseau de clés « %s » en lecture : " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"La ligne %d du trousseau de clés de « %s » avec le contenu « %s » est mal " +"formée" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Le premier jeton de la ligne %d du trousseau de clés de « %s » avec le " +"contenu « %s » est mal formé" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Le deuxième jeton de la ligne %d du trousseau de clés de « %s » avec le " +"contenu « %s » est mal formé" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" +"Impossible de trouver un cookie avec l’identifiant %d dans le trousseau de " +"clés de « %s »" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Erreur lors de la création du fichier verrou « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Erreur lors de la destruction de l’ancien fichier verrou « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Erreur lors de la fermeture du fichier verrou (non lié) « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "" +"Erreur lors de la suppression du lien avec le fichier verrou « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Erreur lors de l’ouverture du trousseau de clés « %s » en écriture : " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(en outre, le relèvement du verrou pour « %s » a aussi échoué : %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "La connexion est fermée" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Le délai d’attente est dépassé" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Marqueurs non pris en charge rencontrés lors de la construction d’une " +"connexion côté client" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Pas d’interface « org.freedesktop.DBus.Properties » pour l’objet à " +"l’emplacement %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "La propriété « %s » n’existe pas" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "La propriété « %s » ne peut pas être lue" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "La propriété « %s » ne peut pas être écrite" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Erreur lors de la définition de la propriété « %s » : type attendu « %s », " +"« %s » obtenu" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "L’interface « %s » n’existe pas" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "L’interface « %s » n’existe pas pour l’objet à l’emplacement %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "La méthode « %s » n’existe pas" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Le type du message, « %s », ne correspond pas au type attendu « %s »" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Un objet est déjà exporté pour l’interface « %s » en « %s »" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Impossible d’obtenir la propriété %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Impossible de définir la propriété %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "La méthode « %s » a renvoyé le type « %s », mais « %s » était attendu" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "" +"La méthode « %s » sur l’interface « %s » avec la signature « %s » n’existe " +"pas" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Une sous-arborescence est déjà exportée pour « %s »" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "L’objet n’existe pas à l’emplacement « %s »" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "le type est « INVALID »" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Message de METHOD_CALL : champ d’en-tête PATH ou MEMBER manquant" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Message de METHOD_RETURN : champ d’en-tête REPLY_SERIAL manquant" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Message d’ERREUR : champ d’en-tête REPLY_SERIAL ou ERROR_NAME manquant" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Message de SIGNAL : champ d’en-tête PATH, INTERFACE ou MEMBER manquant" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Message de SIGNAL : le champ d’en-tête PATH utilise la valeur réservée /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Message de SIGNAL : le champ d’en-tête INTERFACE utilise la valeur réservée " +"org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Lecture de %lu octet demandée, mais seulement %lu reçu(s)" +msgstr[1] "Lecture de %lu octets demandée, mais seulement %lu reçu(s)" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"Octet 00 (NUL) attendu à la fin de la chaîne « %s » mais un octet %d a été " +"trouvé" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Une chaîne UTF-8 valide est attendue mais des octets non valides sont " +"rencontrés à la position %d (longueur de la chaîne : %d octets). La chaîne " +"UTF-8 valide jusqu’à cet endroit est « %s »" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Valeur imbriquée trop profondément" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "" +"La valeur analysée « %s » n’est pas un chemin vers un objet D-Bus valide" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "La valeur analysée « %s » n’est pas une signature D-Bus valide" + +# 2<<26 donne 128 Mo, 2^26 donne 64 Mo, 1<<26 donne 64 Mo +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Un tableau de %u octet de long a été trouvé. La longueur maximale est de " +"2<<26 octets (64 Mo)." +msgstr[1] "" +"Un tableau de %u octets de long a été trouvé. La longueur maximale est de " +"2<<26 octets (64 Mo)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Un tableau de type « a%c » a été trouvé, avec une longueur attendue multiple " +"de %u octets, mais la longueur réelle est de %u octets" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Les structures vides (tuples) ne sont pas autorisées dans D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"La valeur « %s » analysée en tant que variant n’est pas une signature valide " +"de D-Bus" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Erreur en désérialisant le GVariant en chaîne de type « %s » à partir du " +"format de transmission D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valeur de boutisme non valide. 0x6c (« l ») ou 0x42 (« B ») attendus, mais " +"0x%02x trouvé" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Version majeure du protocole non valide. 1 attendu, %d trouvé" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "En-tête de signature trouvé mais n’est pas de type signature" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"En-tête de signature trouvé avec la signature « %s », mais le corps du " +"message est vide" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"La valeur analysée « %s » n’est pas une signature valide de D-Bus (pour le " +"corps)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Pas de signature d’en-tête dans le message, mais le corps du message est de " +"%u octet" +msgstr[1] "" +"Pas de signature d’en-tête dans le message, mais le corps du message est de " +"%u octets" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Impossible de désérialiser le message : " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Erreur en sérialisant le GVariant en chaîne de type « %s » dans le format de " +"transmission D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Le nombre de descripteurs de fichiers dans le message (%d) diffère de celui " +"du champ d’en-tête (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Impossible de sérialiser le message : " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Le corps du message a la signature « %s », mais il n’y a pas d’en-tête de " +"signature" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Le corps du message a une signature de type « %s », mais celle dans le champ " +"d’en-tête est « %s »" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"Le corps du message est vide mais sa signature dans le champ d’en-tête est " +"« (%s) »" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Retour d’erreur avec un corps de type « %s »" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Retour d’erreur avec un corps vide" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(saisissez n’importe quel caractère pour fermer cette fenêtre)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"La session dbus n’est pas lancée et autolaunch (le lancement automatique) a " +"échoué" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Impossible d’obtenir le profil matériel : %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Impossible de charger %s ou %s : " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Erreur lors de l’appel de StartServiceByName pour %s : " + +# Guillemets anglais laissés volontairement +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Réponse %d inattendue de la méthode StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Impossible d’appeler la méthode ; le serveur est mandataire d’un nom connu " +"%s sans propriétaire alors que le proxy a été construit avec le marqueur " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "L’espace de noms abstrait n’est pas pris en charge" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Impossible de définir un fichier à dénomination unique lors de la création " +"d’un serveur" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "" +"Erreur lors de l’écriture du fichier à dénomination unique à « %s » : %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "La chaîne « %s » n’est pas un GUID valide de D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Impossible d’écouter sur le transport « %s » non pris en charge" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Commandes :\n" +" help Affiche la présente information\n" +" introspect Inspecte la constitution d’un objet distant\n" +" monitor Surveille un objet distant\n" +" call Appelle une méthode sur un objet distant\n" +" emit Émet un signal\n" +" wait Attend l’apparition d’un nom de bus\n" +"\n" +"Utiliser « %s COMMANDE --help » pour obtenir une aide sur chaque commande.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Erreur : %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Erreur lors de l’analyse du XML d’introspection : %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Erreur : %s n’est pas un nom valide\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Erreur : « %s » n’est pas un chemin d’objet valide\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Connexion au bus système" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Connexion au bus de session" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Connexion à l’adresse D-Bus donnée" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Options de connexion au point terminal :" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Options définissant la connexion au point terminal" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Aucun point terminal de connexion défini" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Plusieurs points terminaux de connexion définis" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Avertissement : selon les données de l’examen interne, l’interface « %s » " +"n’existe pas\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Avertissement : selon les données de l’examen interne, la méthode « %s » " +"n’existe pas sur l’interface « %s »\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Destination facultative pour le signal (nom unique)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Chemin de l’objet sur lequel émettre le signal" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Noms de signal et d’interface" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Émet un signal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Erreur de connexion : %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Erreur : %s n’est pas un nom unique de bus valide.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Erreur : le chemin pour l’objet n’est pas précisé\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Erreur : le nom du signal n’est pas défini\n" + +# c-format +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Erreur : le nom de signal « %s » n’est pas valide\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Erreur : %s n’est pas un nom d’interface valide\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Erreur : %s n’est pas un nom de membre valide\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Erreur lors de l’analyse du paramètre %d : %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Erreur de purge de la connexion : %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nom de la destination sur laquelle appeler une méthode" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Chemin de l’objet sur lequel appeler une méthode" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Noms de méthode et d’interface" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Délai d’attente en secondes" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Permettre l’autorisation interactive" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Appeler une méthode sur un objet distant." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Erreur : la destination n’est pas précisée\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Erreur : %s n’est pas un nom de bus valide\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Erreur : le nom de la méthode n’est pas défini\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Erreur : le nom de méthode « %s » n’est pas valide\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Erreur d’analyse du paramètre %d de type « %s » : %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Erreur d’ajout de l’identificateur %d : %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nom de la destination à examiner en interne" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Chemin de l’objet à examiner en interne" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Imprimer le XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Examiner en interne les enfants" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "N’afficher que les propriétés" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Examiner en interne un objet distant." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nom de la destination à surveiller" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Chemin de l’objet à surveiller" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Surveiller un objet distant." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"Erreur : impossible de surveiller une connexion qui n’est pas un bus de " +"messages\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Service à activer avant d’attendre l’autre (nom bien connu)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Délai d’attente avant de quitter avec une erreur (secondes) ; 0 pour aucun " +"délai (par défaut)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPTION…] NOM-DE-BUS" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Attend l’apparition d’un nom de bus." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Erreur : un service à activer doit être indiqué.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Erreur : un service à attendre doit être indiqué.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Erreur : trop de paramètres.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Erreur : %s n’est pas un nom de bus bien connu valide\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Non autorisé à modifier les paramètres de débogage" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Sans nom" + +# Un fichier Desktop n’est pas forcément sur le bureau... +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Le fichier .desktop n’a pas précisé son champ Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Impossible de trouver le terminal requis par l’application" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Impossible de créer le dossier de configuration utilisateur d’application " +"%s : %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" +"Impossible de créer le dossier de configuration utilisateur MIME %s : %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Les informations de l’application ne comportent pas d’identifiant" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Impossible de créer le fichier .desktop utilisateur %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Définition personnalisée pour %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "le lecteur n’implémente pas l’éjection (« eject »)" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" +"le lecteur n’implémente pas l’éjection combinée ou non (« eject » ou " +"« eject_with_operation »)" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "le lecteur n’implémente pas la scrutation du média (« polling »)" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "le lecteur n’implémente pas le démarrage (« start »)" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "le lecteur n’implémente pas l’arrêt (« stop »)" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" +"Le moteur TLS n’implémente pas la récupération du couplage TLS (« TLS " +"binding retrieval »)" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "La prise en charge TLS n’est pas disponible" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "La prise en charge DTLS n’est pas disponible" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Impossible de gérer la version %d du codage GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Nombre de jetons incorrect (%d) dans le codage GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Impossible de gérer la version %d du codage GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Nombre de jetons incorrect (%d) dans le codage GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Un GEmblem est attendu pour le GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Le point de montage conteneur n’existe pas" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Impossible d’écraser un répertoire" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Impossible d’écraser un répertoire par un autre répertoire" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Le fichier cible existe" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Impossible de copier récursivement un répertoire" + +# http://en.wikipedia.org/wiki/Splice_(system_call) +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "L’opération « splice » n’est pas prise en charge" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Erreur lors de l’opération de « splicing » sur le fichier : %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"La copie (reflink/clone) entre points de montage n’est pas prise en charge" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "La copie (reflink/clone) n’est pas prise en charge ou n’est pas valide" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" +"La copie (reflink/clone) n’est pas prise en charge ou n’a pas fonctionné" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Impossible de copier le fichier spécial" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Valeur de lien symbolique donnée non valide" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Liens symboliques non pris en charge" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "La corbeille n’est pas prise en charge" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Les noms de fichiers ne peuvent comporter de « %c »" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "le volume n’implémente pas le montage" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Aucune application n’est enregistrée pour gérer ce fichier" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "L’énumérateur est fermé" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "L’énumérateur de fichiers est en cours d’opération" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "L’énumérateur de fichiers est déjà fermé" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Impossible de gérer la version %d du codage de GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Données d’entrée incorrectes pour GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Le flux ne prend pas en charge query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Le positionnement n’est pas pris en charge sur le flux" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "La troncature n’est pas autorisée sur un flux d’entrée" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "La troncature n’est pas prise en charge sur le flux" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Nom d’hôte non valide" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Mauvaise réponse du mandataire HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Connexion mandataire HTTP non autorisée" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "L’authentification auprès du mandataire HTTP a échoué" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Authentification obligatoire pour le mandataire HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "La connexion au mandataire HTTP a échoué : %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Réponse du serveur mandataire HTTP trop grande" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" +"Le serveur mandataire HTTP a terminé la connexion de manière inattendue." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nombre de jetons incorrect (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Aucun type pour le nom de classe %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Le type %s n’implémente pas l’interface GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Le type %s n’est pas classé" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Numéro de version incorrect : %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" +"Le type %s n’implémente pas la fonction from_tokens() de l’interface GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Impossible de gérer la version fournie du codage de l’icône" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Aucune adresse indiquée" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "La longueur %u est trop importante pour l’adresse" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "L’adresse possède des bits définis au-delà de la longueur du préfixe" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Impossible d’analyser « %s » comme masque d’adresse IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Espace insuffisant pour une adresse de connecteur réseau" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Adresse de connecteur réseau non prise en charge" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Le flux en entrée n’implémente pas « read »" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Le flux a une opération en cours" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copier avec le fichier" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Conserver avec le fichier lors du déplacement" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "« version » n’accepte aucun paramètre" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Utilisation :" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Afficher les informations de version et quitter." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Commandes :" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concaténer les fichiers vers la sortie standard" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copier un ou plusieurs fichiers" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Afficher des informations à propos des emplacements" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Démarrer une application depuis un fichier desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Énumérer le contenu des emplacements" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Obtenir ou définir le gestionnaire d’un type MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Créer des répertoires" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Surveiller les modifications de fichiers et de répertoires" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Monter ou démonter les emplacements" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Déplacer un ou plusieurs fichiers" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Ouvrir des fichiers avec l’application par défaut" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Renommer un fichier" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Supprimer un ou plusieurs fichiers" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Lire à partir de l’entrée standard et enregistrer" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Définir un attribut de fichier" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Déplacer des fichiers ou répertoires dans la corbeille" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Énumérer le contenu des emplacements dans une arborescence" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Utilisez %s pour obtenir de l’aide détaillée.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Erreur lors de l’écriture vers stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:91 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "EMPLACEMENT" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concaténer des fichiers et afficher vers la sortie standard." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat fonctionne comme l’utilitaire traditionnel cat, mais en\n" +"utilisant des emplacements GIO au lieu de fichiers locaux : par exemple,\n" +"on peut indiquer un emplacement comme smb://serveur/ressource/fichier.txt." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Aucun emplacement indiqué" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Aucun répertoire cible" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Afficher la progression" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Demander avant d’écraser" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Préserver tous les attributs" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Créer une sauvegarde des fichiers de destination existants" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Ne jamais suivre les liens symboliques" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Utiliser les permissions par défaut de la destination" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%s sur %s transférés (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SOURCE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINATION" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copier un ou plusieurs fichiers de SOURCE vers DESTINATION." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy fonctionne comme l’utilitaire traditionnel cp, mais en\n" +"utilisant des emplacements GIO au lieu de fichiers locaux : par exemple,\n" +"on peut indiquer un emplacement comme smb://serveur/ressource/fichier.txt." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "La destination « %s » n’est pas un répertoire" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s : écraser « %s » ? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Afficher les attributs en écriture" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Obtenir les informations du système de fichiers" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Les attributs à obtenir" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTS" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ne pas suivre les liens symboliques" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "attributs :\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nom d’affichage : %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "nom d’édition : %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nom : %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "type : %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "taille : " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "caché\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri : %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "chemin local : %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "montage unix : %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Attributs pouvant être définis :\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Espaces de noms des attributs en écriture :\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Afficher des informations à propos des emplacements." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info fonctionne comme l’utilitaire traditionnel ls, mais en\n" +"utilisant des emplacements GIO au lieu de fichiers locaux : par exemple,\n" +"on peut indiquer un emplacement comme smb://serveur/ressource/fichier.txt.\n" +"Les attributs de fichiers peuvent être indiqués par leur nom GIO (exemple :\n" +"standard::icon), par leur espace de nom (exemple : unix) ou par « * » qui\n" +"correspond à tous les attributs" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "FICHIER-DESKTOP [PARAMÈTRE-FICHIER]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Démarrer une application depuis un fichier desktop, en lui fournissant des " +"paramètres optionnels de nom de fichier." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Aucun fichier desktop indiqué" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" +"La commande d’exécution n’est pas prise en charge sur cette plate-forme pour " +"le moment" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Impossible de charger « %s » : %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Impossible de charger les détails de l’application pour « %s »" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Impossible de lancer l’application « %s » : %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Afficher les fichiers cachés" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Utiliser une mise en forme de liste étendue" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Afficher les noms d’affichage" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Afficher les URI complètes" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Énumérer le contenu des emplacements." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list fonctionne comme l’utilitaire traditionnel ls, mais en\n" +"utilisant des emplacements GIO au lieu de fichiers locaux : par exemple,\n" +"on peut indiquer un emplacement comme smb://serveur/ressource/fichier.txt.\n" +"Les attributs de fichiers peuvent être indiqués par leur nom GIO (exemple :\n" +"standard::icon)" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TYPE_MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "GESTIONNAIRE" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Obtient ou définit le gestionnaire d’un type MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Si aucun gestionnaire n’est indiqué, énumère les applications inscrites\n" +"et recommandées pour le type MIME. Si un gestionnaire est indiqué, il est\n" +"défini comme gestionnaire par défaut pour le type MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" +"Un seul type MIME doit être indiqué, et potentiellement un gestionnaire" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Aucune application par défaut pour « %s »\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Application par défaut pour « %s » : %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Applications inscrites :\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Aucune application inscrite\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Applications recommandées :\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Aucune application recommandée\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Le chargement des informations du gestionnaire « %s » a échoué" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"La définition de « %s » comme gestionnaire par défaut pour « %s » a échoué : " +"%s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Créer les répertoires parents" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Créer des répertoires." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir fonctionne comme l’utilitaire traditionnel mkdir, mais en\n" +"utilisant des emplacements GIO au lieu de fichiers locaux : par exemple,\n" +"on peut indiquer un emplacement comme smb://serveur/ressource/répertoire." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Surveille un répertoire (par défaut : en fonction du type)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Surveille un fichier (par défaut : en fonction du type)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Surveille un fichier directement (détecte les modifications par liens durs)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" +"Surveille un fichier directement, mais ne signale pas les modifications" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Signale les déplacements et les renommages comme simples évènements " +"suppression/création" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Surveille les évènements de montage" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Surveille les modifications de fichiers ou de répertoires." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Monter comme montable" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Monter le volume selon le fichier de périphérique ou autre identifiant" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Démonter" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Éjecter" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Arrêter le disque selon le fichier de périphérique" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "PÉRIPHÉRIQUE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Démonter tous les montages du protocole donné" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "PROTOCOLE" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Ignorer les opérations de fichier en cours lors du démontage ou de l’éjection" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Utiliser un utilisateur anonyme lors de l’authentification" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Énumérer" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Surveiller les évènements" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Afficher des informations supplémentaires" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "PIM numérique lors du déverrouillage du volume VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Monter un volume caché TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Monter un volume système TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Accès anonyme refusé" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Aucun disque correspondant au fichier de périphérique" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Aucun volume pour l’identifiant donné" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Monter ou démonter les emplacements." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ne pas utiliser la copie ou la suppression de repli" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Déplacer un ou plusieurs fichiers de SOURCE vers DEST." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move fonctionne comme l’utilitaire traditionnel mv, mais en\n" +"utilisant des emplacements GIO au lieu de fichiers locaux : par exemple,\n" +"on peut indiquer un emplacement comme smb://serveur/ressource/fichier.txt" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "La cible %s n’est pas un répertoire" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Ouvrir les fichiers avec l’application par défaut\n" +"inscrite pour gérer les fichiers de ce type." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignorer les fichiers non existants, ne jamais demander" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Supprimer les fichiers indiqués." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOM" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Renommer un fichier." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Paramètre manquant" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:139 +msgid "Too many arguments" +msgstr "Trop de paramètres" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Le renommage a réussi. Nouvelle uri : %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Créer seulement s’il n’existe pas" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Ajouter à la fin du fichier" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Lors de la création, limiter l’accès à l’utilisateur actuel" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" +"Lors d’un remplacement, remplacer comme si la destination n’existait pas" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Afficher le nouvel etag à la fin" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Le etag du fichier en cours d’écrasement" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Erreur de lecture à partir de l’entrée standard" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag non disponible\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Lire à partir de l’entrée standard et enregistrer vers DEST." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Aucune destination indiquée" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Type de l’attribut" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYPE" + +#: gio/gio-tool-set.c:91 +msgid "ATTRIBUTE" +msgstr "ATTRIBUT" + +#: gio/gio-tool-set.c:91 +msgid "VALUE" +msgstr "VALEUR" + +#: gio/gio-tool-set.c:95 +msgid "Set a file attribute of LOCATION." +msgstr "Définir un attribut de fichier de l’EMPLACEMENT." + +#: gio/gio-tool-set.c:115 +msgid "Location not specified" +msgstr "Emplacement non indiqué" + +#: gio/gio-tool-set.c:122 +msgid "Attribute not specified" +msgstr "Attribut non indiqué" + +#: gio/gio-tool-set.c:132 +msgid "Value not specified" +msgstr "Valeur non indiquée" + +#: gio/gio-tool-set.c:182 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Type d’attribut « %s » non valide" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Vider la corbeille" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "" +"Lister les fichiers de la corbeille ainsi que leur emplacement d’origine" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restaurer un fichier depuis la corbeille vers son emplacement d’origine " +"(peut recréer le répertoire)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Impossible de trouver l’emplacement d’origine" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Impossible de recréer l’emplacement d’origine : " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Impossible de déplacer le fichier vers son emplacement d’origine : " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "" +"Déplacer ou restaurer des fichiers ou des répertoires vers la corbeille." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Note : pour la commande --restore, si l'emplacement d'origine du fichier " +"corbeille\n" +"existe déjà, il ne sera pas écrasé à moins que --force soit précisé." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Le chemin indiqué ne commence pas par trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Suivre les liens symboliques, les montages et les raccourcis" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" +"Afficher la liste du contenu de répertoires dans un format arborescent." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Élément <%s> interdit dans <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Élément <%s> interdit au premier niveau" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Le fichier %s apparaît plusieurs fois dans la ressource" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "La localisation de « %s » dans tous les répertoires source a échoué" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "La localisation de « %s » dans le répertoire actuel a échoué" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Option de traitement inconnue « %s »" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Un prétraitement %s a été demandé, mais %s n’est pas défini et %s n’est pas " +"dans le chemin PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Erreur de lecture du fichier %s : %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Erreur à la compression du fichier %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s> ne peut pas contenir du texte" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Affiche la version du programme et quitte" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nom du fichier de sortie" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Les répertoires à partir desquels charger les fichiers référencés dans " +"FICHIER (par défaut le répertoire actuel)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "RÉPERTOIRE" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Générer la sortie dans le format sélectionné par l’extension du nom de " +"fichier cible" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Générer l’en-tête de la source" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Générer le code source utilisé pour lier vers le fichier ressource dans " +"votre code" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Générer la liste des dépendances" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nom du fichier de dépendances à générer" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Inclure les cibles « phony » dans le fichier de dépendances généré" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Ne pas créer et enregistrer automatiquement la ressource" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ne pas exporter les fonctions ; les déclarer G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Ne pas inclure les données de ressources dans le fichier C ; on suppose " +"plutôt qu’elles sont liées de façon externe" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Nom d’identifiant C utilisé pour le code source généré" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Le compilateur C cible (par défaut : la variable d’environnement CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compiler une spécification de ressource dans un fichier de ressource.\n" +"Les fichiers de spécification de ressource possèdent l’extension .gresource." +"xml\n" +"et le fichier de ressource possède l’extension .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Vous devez indiquer un et un seul nom de fichier\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "le pseudo doit contenir au minimum 2 caractères" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Valeur numérique non valide" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " est déjà défini" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' a déjà été défini" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "les valeurs de drapeaux doivent avoir au moins un bit défini" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> doit contenir au moins une " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> n’est pas contenu dans l’intervalle défini" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> n’est pas un membre valide du type énuméré défini" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> contient une chaîne absente du type drapeau défini" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> contient une chaîne absente de " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " a déjà été défini pour cette clé" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " non autorisé pour les clés de type « %s »" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "le minimum de est plus grand que son maximum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "catégorie l10n non prise en charge : %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n demandée, mais aucun domaine gettext indiqué" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "contexte de traduction donné pour une valeur sans activation de l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "L’analyse de la valeur de type « %s » a échoué : " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" ne peut pas être défini pour des clés marquées comme étant du type " +"énuméré" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " a déjà été défini pour cette clé" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " non autorisés pour des clés du type « %s »" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " a déjà été défini" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " doit contenir au moins un " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " a déjà été défini pour cette clé" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" ne peut être défini que pour des clés de type énuméré ou drapeau, " +"ou après " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" a été donné alors que « %s » est déjà un membre du type " +"énuméré" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" a été donné alors que est déjà " +"présent" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " est déjà défini" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "la cible d’alias « %s » n’est pas dans le type énuméré" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "la cible d’alias « %s » n’est pas dans " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " doit contenir au moins un " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Les noms vides ne sont pas autorisés" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" +"Nom « %s » non valide : les noms doivent commencer par une lettre minuscule" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nom « %s » non valide : caractère « %c » non valide ; seuls les minuscules, " +"les nombres et le tiret (« - ») sont autorisés" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Nom « %s » non valide : deux tirets successifs (« -- ») ne sont pas autorisés" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" +"Nom « %s » non valide : le dernier caractère ne peut pas être un tiret (« -" +" »)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nom « %s » non valide : la longueur maximale est 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " a déjà été défini" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Impossible d’ajouter des clés à un schéma « list-of »" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " a déjà été défini" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" masque dans  ; utilisez " +" pour modifier la valeur" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +" ne peut recevoir qu’un et un seul attribut parmi « type », « enum » ou " +"« flags »" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> pas (encore) défini." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Chaîne de type GVariant « %s » non valide" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "un est donné mais son schéma n’étend rien du tout" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Aucune à redéfinir" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " déjà défini" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " déjà défini" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " étend le schéma « %s » qui n’existe pas encore" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" +" est une liste du schéma « %s » qui n’existe pas encore" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Un schéma avec un chemin ne peut contenir de liste" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Impossible d’étendre un schéma avec un chemin" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" est une liste ; elle étend qui n’est pas " +"une liste" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" étend mais " +"« %s » n’étend pas « %s »" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"Si un chemin est indiqué, il doit commencer et finir par une barre oblique" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Le chemin d’une liste doit finir par « :/ »" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Attention : le schéma « %s » comporte le chemin « %s ». Les chemins " +"commençant par « /apps/ », « /desktop/ » ou « /system/ » sont obsolètes." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> est déjà défini" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Un seul élément <%s> est autorisé dans <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Élément <%s> interdit au premier niveau" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Élément obligatoire dans " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "<%s> ne peut pas contenir du texte" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Attention : référence indéfinie vers " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict a été spécifié ; sortie en cours." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Le fichier complet a été ignoré." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ce fichier est ignoré." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Aucune clé nommée « %s » dans le schéma « %s » comme défini dans le fichier " +"« %s » de redéfinition ; aucune redéfinition pour cette clé." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Aucune clé nommée « %s » dans le schéma « %s » comme défini dans le fichier " +"« %s » de redéfinition et --strict a été spécifié ; sortie en cours." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Impossible de fournir des redéfinitions par bureau pour la clé régionalisée " +"« %s » dans le schéma « %s » (fichier de redéfinition « %s ») ; aucune " +"redéfinition pour cette clé." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Impossible de fournir des redéfinitions par bureau pour la clé régionalisée " +"« %s » dans le schéma « %s » (fichier de redéfinition « %s ») et --strict a " +"été spécifié ; sortie en cours." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Erreur d’analyse de la clé « %s » dans le schéma « %s » comme défini dans le " +"fichier « %s » de redéfinition : %s. Aucune redéfinition pour cette clé." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Erreur d’analyse de la clé « %s » dans le schéma « %s » comme défini dans le " +"fichier « %s » de redéfinition : %s. --strict a été spécifié ; sortie en " +"cours." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"La redéfinition de la clé « %s » dans le schéma « %s » du fichier de " +"redéfinition « %s » n’est pas dans la plage indiquée par le schéma ; aucune " +"redéfinition pour cette clé." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"La redéfinition de la clé « %s » dans le schéma « %s » du fichier de " +"redéfinition « %s » n’est pas dans la plage indiquée par le schéma et --" +"strict a été spécifié ; sortie en cours." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"La redéfinition de la clé « %s » dans le schéma « %s » du fichier de " +"redéfinition « %s » n’est pas dans la liste des choix valides ; aucune " +"redéfinition pour cette clé." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"La redéfinition de la clé « %s » dans le schéma « %s » du fichier de " +"redéfinition « %s » n’est pas dans la liste des choix valides et --strict a " +"été spécifié ; sortie en cours." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Endroit où enregistrer le fichier gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Annulation en cas d’erreurs dans des schémas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Ne pas écrire de fichier gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Ne pas appliquer les limitations de nom de clé" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compiler tous les fichiers schémas GSettings dans un cache.\n" +"L’extension .gschema.xml est requise pour les fichiers schémas,\n" +"et le fichier cache est nommé gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Vous devez indiquer un et un seul nom de répertoire" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Aucun fichier schéma trouvé : aucune action effectuée." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Aucun fichier schéma trouvé : fichier de sortie existant supprimé." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Nom de fichier non valide : %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "" +"Erreur d’obtention des informations du système de fichiers pour %s : %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Le point de montage conteneur pour le fichier %s est introuvable" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Impossible de renommer le répertoire racine" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Erreur de renommage du fichier %s : %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Impossible de renommer le fichier car ce nom est déjà utilisé" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nom de fichier non valide" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Erreur lors de l’ouverture du fichier %s : %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Erreur lors de la suppression du fichier %s : %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Erreur lors de la mise à la corbeille du fichier %s : %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Impossible de créer le répertoire de la corbeille %s : %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "" +"Impossible de trouver le répertoire racine pour mettre %s à la corbeille" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"La mise à la corbeille sur des montages systèmes internes n’est pas prise en " +"charge" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "" +"Impossible de trouver ou créer le répertoire de la corbeille %s pour mettre " +"%s à la corbeille" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "" +"Impossible de créer le fichier d’informations de mise à la corbeille pour " +"%s : %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Impossible de mettre à la corbeille le fichier %s au-delà des limites du " +"système de fichiers" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Impossible de mettre à la corbeille le fichier %s : %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Impossible de mettre à la corbeille le fichier %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Erreur lors de la création du répertoire %s : %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Le système de fichiers ne gère pas les liens symboliques" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Erreur lors de la création du lien symbolique %s : %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Erreur lors du déplacement du fichier %s : %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Impossible de déplacer un répertoire par dessus un autre" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "La création du fichier de sauvegarde a échoué" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Erreur lors de la suppression du fichier cible : %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Le déplacement entre points de montage n’est pas pris en charge" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Impossible de déterminer l’utilisation disque de %s : %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "La valeur d’attribut ne doit pas être « NULL »" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Type d’attribut non valide (une chaîne est attendue)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nom d’attribut étendu non valide" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Erreur lors de la définition de l’attribut étendu « %s » : %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codage non valide)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Erreur lors de l’obtention des informations du fichier « %s » : %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" +"Erreur lors de l’obtention des informations du descripteur de fichier : %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Type d’attribut non valide (uint32 attendu)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Type d’attribut non valide (uint64 attendu)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Type d’attribut non valide (chaîne d’octets attendue)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Impossible de définir des permissions sur les liens symboliques" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Erreur lors de la définition des permissions : %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Erreur lors de la définition du propriétaire : %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "un lien symbolique ne doit pas être « NULL »" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Erreur lors de la définition du lien symbolique : %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Erreur lors de la définition du lien symbolique : le fichier n’est pas un " +"lien symbolique" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"Les nanosecondes supplémentaires %d pour l’horodatage UNIX %lld sont " +"négatives" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Les nanosecondes supplémentaires %d pour l’horodatage UNIX %lld atteignent 1 " +"seconde" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "L’horodatage UNIX %lld ne tient pas sur 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"L’horodatage UNIX %lld est hors de la plage prise en charge par Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Le nom de fichier « %s » ne peut être converti en UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Le fichier « %s » ne peut être ouvert : erreur Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Erreur lors de la définition de l’heure de modification ou d’accès pour le " +"fichier « %s » : %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" +"Erreur lors de la définition de l’heure de modification ou d’accès : %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Le contexte SELinux ne doit pas être « NULL »" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux n’est pas activé sur ce système" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Erreur lors de la définition du contexte SELinux : %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "La définition de l’attribut %s n’est pas prise en charge" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Erreur lors de la lecture du fichier : %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Erreur lors de la fermeture du fichier : %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Erreur de positionnement dans le fichier : %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Impossible de trouver le type de moniteur de fichier local par défaut" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Erreur lors de l’écriture du fichier : %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Erreur lors de la suppression de l’ancien lien de sauvegarde : %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Erreur lors de la création de la copie de sauvegarde : %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Erreur lors du renommage du fichier temporaire : %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Erreur lors de la troncature du fichier : %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Erreur lors de l’ouverture du fichier « %s » : %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Le fichier cible est un répertoire" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Le fichier cible n’est pas un fichier standard" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Le fichier a été modifié extérieurement" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Erreur à la suppression de l’ancien fichier : %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Le type GSeekType fourni n’est pas valide" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Requête « seek » non valide" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Impossible de tronquer GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Le flux de sortie mémoire n’est pas redimensionnable" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Le redimensionnement du flux de sortie mémoire a échoué" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"La quantité de mémoire nécessaire pour effectuer l’écriture est plus grande " +"que l’espace d’adressage disponible" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Positionnement demandé avant le début du flux" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Positionnement demandé après la fin du flux" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "mount n’implémente pas le démontage (« unmount »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount n’implémente pas l’éjection (« eject »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"mount n’implémente pas le démontage (« unmount » ou " +"« unmount_with_operation »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"mount n’implémente pas l’éjection (« eject » ou « eject_with_operation »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "mount n’implémente pas le remontage (« remount »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "mount n’implémente pas l’estimation du type de contenu" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "mount n’implémente pas la supposition d’un type de contenu synchrone" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Le nom d’hôte « %s » comporte « [ » mais pas « ] »" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Réseau inaccessible" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Hôte inaccessible" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Impossible de créer le moniteur de réseau : %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Impossible de créer le moniteur de réseau : " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Impossible d’obtenir le statut du réseau : " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager n’est pas lancé" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "La version de NetworkManager est trop ancienne" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Le flux de sortie n’implémente pas « write »" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Somme des vecteurs passés à %s trop grande" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Le flux source est déjà fermé" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Erreur de résolution de « %s » : %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s non implémentée" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Domaine non valide" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "La ressource dans « %s » n’existe pas" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "La décompression de la ressource dans « %s » n’a pas réussi" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "La ressource dans « %s » n’est pas un répertoire" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Le flux en entrée n’implémente pas « seek » (le positionnement)" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Énumère les sections contenant les ressources dans un fichier « elf »" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Énumère les ressources\n" +"Si SECTION est fournie, énumère seulement les ressources de cette section\n" +"Si CHEMIN est fourni, énumère seulement les ressources correspondantes" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FICHIER [CHEMIN]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECTION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Énumère les ressources en détail\n" +"Si SECTION est fournie, énumère seulement les ressources de cette section\n" +"Si CHEMIN est fourni, énumère seulement les ressources correspondantes\n" +"Les détails incluent la section, la taille et la compression" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extrait un fichier ressource vers la sortie standard" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "CHEMIN DU FICHIER" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilisation :\n" +" gresource [--section SECTION] COMMANDE [PARAMÈTRES…]\n" +"\n" +"Commandes :\n" +" help Affiche cette information\n" +" sections Énumère les sections de ressources\n" +" list Énumère les ressources\n" +" details Énumère les ressources en détail\n" +" extract Extrait une ressource\n" +"\n" +"Utilisez « gresource help COMMANDE » pour obtenir de l’aide détaillée.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilisation :\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION Un nom de section elf (facultatif)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMANDE La commande (facultative) à expliquer\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" FICHIER Un fichier elf (un binaire ou une bibliothèque partagée)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FICHIER Un fichier elf (un binaire ou une bibliothèque partagée)\n" +" ou un fichier ressource compilé\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[CHEMIN]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" +" CHEMIN Un chemin (facultatif) de ressource (peut être partiel)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CHEMIN" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " CHEMIN Un chemin de ressource\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Le schéma « %s » n’existe pas\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" +"Le schéma « %s » n’est pas réadressable (le chemin ne doit pas être " +"indiqué)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Le schéma « %s » est réadressable (le chemin doit être indiqué)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Chemin indiqué vide.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Un chemin doit commencer par une barre oblique (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Un chemin doit se terminer par une barre oblique (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Un chemin ne doit pas contenir deux barres obliques à la suite (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "La valeur donnée est en dehors du domaine de validité\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "La clé ne peut pas être écrite\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Lister les schémas (non-réadressables) installés" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Lister les schémas réadressables installés" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Lister les clés du SCHÉMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHÉMA[:CHEMIN]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Lister les enfants du SCHÉMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Lister les clés et les valeurs récursivement\n" +"Si aucun SCHÉMA n’est indiqué, lister toutes les clés\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHÉMA[:CHEMIN]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Obtenir la valeur de KEY" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHÉMA[:CHEMIN] CLÉ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Demander la plage de validité des valeurs de la CLÉ" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Demander la description pour la CLÉ" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Définir la valeur de CLÉ à VALEUR" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHÉMA[:CHEMIN] CLÉ VALEUR" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Rétablir CLÉ à sa valeur par défaut" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Réinitialiser toutes les clés de SCHÉMA à leurs valeurs par défaut" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Tester si CLÉ est inscriptible" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Contrôler les modifications de CLÉ.\n" +"Si CLÉ n’est pas défini, contrôle toutes les clés dans SCHÉMA.\n" +"Presser ^C pour mettre fin au contrôle.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHÉMA[:CHEMIN] [CLÉ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilisation :\n" +" gsettings --version\n" +" gsettings [--schemadir RÉPERTOIRE2SCHÉMA] COMMANDE [PARAMÈTRES…]\n" +"\n" +"Commandes :\n" +" help Affiche la présente information\n" +" list-schemas Liste les schémas installés\n" +" list-relocatable-schemas Liste les schémas réadressables\n" +" list-keys Liste les clés dans un schéma\n" +" list-children Liste les enfants d’un schéma\n" +" list-recursively Liste les clés et les valeurs, récursivement\n" +" range Demande le domaine de validité de la clé\n" +" describe Demande la description de la clé\n" +" get Renvoie la valeur d’une clé\n" +" set Définit la valeur d’une clé\n" +" reset Rétablit la valeur par défaut d’une clé\n" +" reset-recursively Rétablit toutes les valeurs dans un schéma " +"donné\n" +" writable Teste si la clé est inscriptible\n" +" monitor Contrôle les modifications\n" +"\n" +"Saisissez « gsettings help COMMANDE » pour une aide détaillée.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilisation :\n" +" gsettings [--schemadir RÉPERTOIRE2SCHÉMA] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" +" RÉPERTOIRE2SCHÉMA Un répertoire de recherche de schémas supplémentaires\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHÉMA Le nom du schéma\n" +" CHEMIN Le chemin, pour les schémas réadressables\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " CLÉ La clé (optionnelle) dans le schéma\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " CLÉ La clé dans le schéma\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALEUR La valeur à définir\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Impossible de charger les schémas depuis %s : %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Aucun schéma installé\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Nom de schéma fourni vide\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "La clé « %s » n’existe pas\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Connecteur non valide, non initialisé" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Connecteur non valide, l’initialisation a échoué en raison de : %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Le connecteur est déjà fermé" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Entrées/sorties hors délai sur le connecteur" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "création de GSocket à partir du descripteur de fichier : %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Impossible de créer le connecteur : %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Indication d’une famille inconnue" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Indication d’un protocole inconnu" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Impossible d’utiliser des opérations datagramme sur un connecteur non " +"datagramme." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Impossible d’utiliser des opérations datagramme sur un connecteur doté d’un " +"délai d’expiration." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "impossible d’obtenir l’adresse locale : %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "impossible d’obtenir l’adresse distante : %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "impossible d’écouter : %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Erreur lors de la liaison à l’adresse %s : %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Erreur lors de la connexion au groupe multicast : %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Erreur lors de la déconnexion du groupe multicast : %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Aucune prise en charge pour le multicast spécifique à la source" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Famille de connecteur réseau non prise en charge" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "source-specific n’est pas une adresse IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Nom d’interface trop long" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interface introuvable : %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Aucune prise en charge pour le multicast IPv4 spécifique à la source" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Aucune prise en charge pour le multicast IPv6 spécifique à la source" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Erreur d’acceptation de la connexion : %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Connexion en cours" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Impossible d’obtenir l’erreur actuelle : " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Erreur lors de la réception des données : %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Erreur lors de l’envoi des données : %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Impossible de fermer le connecteur : %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Erreur lors de la fermeture du connecteur : %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "En attente de l’état du connecteur : %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Impossible d’envoyer le message : %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vecteurs de messages trop grands" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Erreur d’envoi de message : %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage n’est pas pris en charge par Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Erreur lors de la réception du message : %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Impossible de lire les données d’authentification du connecteur : %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials n’est pas implémenté sur ce système d’exploitation" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Impossible de se connecter au serveur mandataire %s : " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Impossible de se connecter à %s : " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Impossible de se connecter : " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" +"L’usage d’un proxy n’est pas pris en charge dans une connexion non-TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Le protocole du proxy « %s » n’est pas pris en charge." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Le processus d’écoute est déjà fermé" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Le connecteur réseau ajouté est fermé" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 ne prend pas en charge l’adresse IPv6 « %s »" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Le nom d’utilisateur est trop long pour le protocole SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Le nom d’hôte « %s » est trop long pour le protocole SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Le serveur n’est pas un serveur mandataire SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "La connexion à travers le serveur SOCKSv4 a été rejetée" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Le serveur n’est pas un serveur mandataire SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Le serveur mandataire SOCKSv5 nécessite une authentification." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Le protocole SOCKSv5 nécessite une méthode d’authentification qui n’est pas " +"prise en charge par GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"Le nom d’utilisateur ou le mot de passe est trop long pour le protocole " +"SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"L’authentification SOCKSv5 a échoué à cause d’un mauvais nom d’utilisateur " +"ou mot de passe." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Le nom d’hôte « %s » est trop long pour le protocole SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Le serveur mandataire SOCKSv5 utilise un type d’adresse inconnu." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Erreur interne de serveur mandataire SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "La connexion SOCKSv5 n’est pas autorisée par la règle." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "L’hôte n’est pas accessible à travers le serveur SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Le réseau n’est pas accessible à travers le proxy SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Connexion à travers le serveur mandataire SOCKSv5 refusée." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "" +"Le serveur mandataire SOCKSv5 ne prend pas en charge la commande « connect »." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" +"Le serveur mandataire SOCKSv5 ne prend pas en charge le type d’adresse " +"fourni." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Erreur inconnue du serveur mandataire SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"La création du tube de communication avec le processus fils a échoué (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Les tubes ne sont pas pris en charge sur cette plate-forme" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Impossible de gérer la version %d du codage GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Aucune adresse valide n’a été trouvée" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Erreur de résolution inverse de « %s » : %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "" +"Erreur lors de l’analyse de l’enregistrement DNS %s : paquet DNS mal formé" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Aucun enregistrement DNS du type demandé pour « %s »" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Impossible temporairement de résoudre « %s »" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Erreur de résolution de « %s »" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Paquet DNS mal formé" + +#: gio/gthreadedresolver.c:886 +#, c-format +#| msgid "Failed to read from file “%sâ€: %s" +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Échec de l’analyse de la réponse DNS pour « %s » : " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Aucune clé privée codée PEM trouvée" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Impossible de déchiffrer la clé privée codée-PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Impossible d’analyser la clé privée codée-PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Aucun certificat codé-PEM trouvé" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Impossible d’analyser le certificat codé-PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Le moteur TLS actuel ne prend pas en charge PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" +"Ce GTlsBackend ne prend pas en charge la création de certificats PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ceci est votre dernière chance de saisir un mot de passe correct avant que " +"votre accès soit bloqué." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Plusieurs mots de passe saisis ont été incorrects, votre accès sera bloqué " +"après quelques échecs de plus." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Le mot de passe saisi est incorrect." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "L’envoi de descripteur de fichier n’est pas pris en charge" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 message de contrôle attendu, %d reçu" +msgstr[1] "1 message de contrôle attendu, %d reçus" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Type de données auxiliaires inattendu" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Un descripteur de fichier attendu, %d obtenu\n" +msgstr[1] "Un descripteur de fichier attendu, %d obtenus\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Le descripteur de fichier reçu n’est pas valide" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "La réception de descripteur de fichier n’est pas prise en charge" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Erreur lors de l’envoi de l’identification : " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"Erreur lors de la vérification de l’activation de SO_PASSCRED pour le " +"connecteur : %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Erreur lors de l’activation de SO_PASSCRED : %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Lecture d’un unique octet attendue à la réception de l’identification, mais " +"aucun octet lu" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Pas de message de contrôle attendu, %d reçu(s)" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Erreur lors de la désactivation de SO_PASSCRED : %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Erreur de lecture à partir du descripteur de fichier : %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Erreur de fermeture du descripteur de fichier : %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Racine du système de fichiers" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Erreur d’écriture vers le descripteur de fichier : %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Les adresses abstraites de connecteur réseau de domaine UNIX ne sont pas " +"prises en charge sur ce système" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "le volume n’implémente pas l’éjection (« eject »)" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" +"le volume n’implémente pas l’éjection (« eject » ou « eject_with_operation »)" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Erreur de lecture à partir de l’identificateur : %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Erreur de fermeture de l’identificateur : %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Erreur lors de l’écriture vers l’identificateur : %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Mémoire insuffisante" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Erreur interne : %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Entrée nécessitant plus de données" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Données compressées non valides" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresse à écouter" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignoré, pour compatibilité avec GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Imprimer l’adresse" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Imprimer l’adresse en mode shell" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Exécuter un service dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Paramètres incorrects\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Attribut « %s » inattendu pour l’élément « %s »" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "L’attribut « %s » de l’élément « %s » est introuvable" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Balise « %s » inattendue. La balise « %s » était attendue" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Balise « %s » inattendue à l’intérieur de « %s »" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Date et heure « %s » non valide dans le fichier de signets" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Impossible de trouver un fichier de signets valide dans les répertoires de " +"données" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Un signet pour l’URI « %s » existe déjà" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Aucun signet trouvé pour l’URI « %s »" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Aucun type MIME défini dans le signet pour l’URI « %s »" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Aucun indicateur privé n’est défini dans le signet pour l’URI « %s »" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Aucun groupe n’est défini dans le signet pour l’URI « %s »" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Aucune application nommée « %s » n’a enregistré un signet pour « %s »" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "" +"Échec du développement de la ligne de commande « %s » pour l’URI « %s »" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Caractère non affichable dans l’entrée du convertisseur" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Séquence de caractères incomplète en fin d’entrée" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" +"Impossible de convertir le caractère de repli « %s » dans le jeu de codes " +"« %s »" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Octet nul imbriqué dans l’entrée du convertisseur" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Octet nul imbriqué dans la sortie du convertisseur" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "L’URI « %s » n’est pas une URI absolue utilisant le protocole « file »" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "L’URI de fichier local « %s » ne peut pas inclure un caractère « # »" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "L’URI « %s » n’est pas valide" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Le nom d’hôte de l’URI « %s » n’est pas valide" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "L’URI « %s » contient des caractères d’échappement incorrects" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Le nom de chemin « %s » n’est pas un chemin absolu" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "janvier" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "février" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "mars" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "avril" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "mai" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "juin" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "juillet" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "août" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "septembre" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "octobre" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "novembre" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "décembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "janv." + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "févr." + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mars" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "avril" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "mai" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "juin" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "juil." + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "août" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "sept." + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "oct." + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov." + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "déc." + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "lundi" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "mardi" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "mercredi" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "jeudi" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "vendredi" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "samedi" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "dimanche" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "lun." + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "mar." + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "mer." + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "jeu." + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ven." + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sam." + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "dim." + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "janvier" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "février" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "mars" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "avril" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "mai" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "juin" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "juillet" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "août" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "septembre" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "octobre" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "novembre" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "décembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "janv." + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "févr." + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mars" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "avril" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "mai" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "juin" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "juil." + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "août" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sept." + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "oct." + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov." + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "déc." + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Erreur à l’ouverture du répertoire « %s » : %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Impossible d’allouer %lu octet pour lire le fichier « %s »" +msgstr[1] "Impossible d’allouer %lu octets pour lire le fichier « %s »" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Erreur de lecture du fichier « %s » : %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Le fichier « %s » est trop grand" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "La lecture depuis le fichier « %s » a échoué : %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "L’ouverture du fichier « %s » a échoué : %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"L’obtention des attributs du fichier « %s » a échoué : échec de fstat() : %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "L’ouverture du fichier « %s » a échoué : échec de fdopen() : %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Le renommage du fichier « %s » vers « %s » a échoué : échec de g_rename() : " +"%s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "L’écriture dans le fichier « %s » a échoué : échec de write() : %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "L’écriture dans le fichier « %s » a échoué : échec de fsync() : %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "La création du fichier « %s » a échoué : %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Le fichier existant « %s » ne peut pas être supprimé : échec de g_unlink() : " +"%s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "" +"Le modèle « %s » n’est pas valide, il ne devrait pas contenir un « %s »" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Le modèle « %s » ne contient pas XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "La lecture du lien symbolique « %s » a échoué : %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Impossible d’ouvrir le convertisseur de « %s » vers « %s » : %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Lecture de données brutes impossible dans g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Données restantes non converties dans le tampon de lecture" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "La canal se termine avec un caractère partiel" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Lecture de données brutes impossible dans g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Impossible de trouver un fichier de clés valide dans les répertoires de " +"recherche" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "N’est pas un fichier standard" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Le fichier de clés contient la ligne « %s » qui n’est ni une paire de " +"valeurs de clé, ni un groupe, ni un commentaire" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nom de groupe non valide : %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Le fichier de clés ne débute pas par un groupe" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nom de clé non valide : %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "" +"Le fichier de clés contient un codage de caractères non pris en charge « %s »" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Le fichier de clés n’a pas de groupe « %s »" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Le fichier de clés ne contient pas de clé « %s » dans le groupe « %s »" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Le fichier de clés contient la clé « %s » avec la valeur « %s » qui n’est " +"pas codé en UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Le fichier de clés contient la clé « %s » dont une valeur est impossible à " +"interpréter." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Le fichier de clés contient la clé « %s » dans le groupe « %s » qui a une " +"valeur impossible à interpréter." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"La clé « %s » dans le groupe « %s » a une valeur « %s » alors que %s était " +"attendu" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Le fichier de clés contient un caractère d’échappement en fin de ligne" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "" +"Le fichier de clés contient une séquence d’échappement non valide « %s »" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "La valeur « %s » ne peut pas être interprétée comme un nombre." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "La valeur entière « %s » est hors plage" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "" +"La valeur « %s » ne peut pas être interprétée comme un nombre à virgule " +"flottante." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "La valeur « %s » ne peut pas être interprétée comme un booléen." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"L’obtention des attributs du fichier « %s%s%s%s » a échoué : échec de " +"fstat() : %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Le mappage %s%s%s%s a échoué : échec de mmap() : %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "L’ouverture du fichier « %s » a échoué : échec de open() : %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Erreur à la ligne %d, caractère %d : " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Codage UTF-8 non valide dans le nom — « %s » n’est pas valide" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "« %s » n’est pas un nom valide" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "« %s » n’est pas un nom valide : « %c »" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Erreur à la ligne %d : %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Échec de l’analyse de « %-.*s » qui devrait être un nombre dans la plage de " +"référence des caractères (ê par exemple) — peut-être que le nombre est " +"trop grand" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"La référence du caractère ne se termine pas par un point-virgule ; vous avez " +"vraisemblablement utilisé une esperluette sans intention d’écrire une entité " +"— échappez l’esperluette avec &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "La référence au caractère « %-.*s » ne code pas un caractère autorisé" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Entité vide « &; » rencontrée ; les entités valides sont : & " < " +"> '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "L’entité nommée « %-.*s » est inconnue" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"L’entité ne se termine pas par un point-virgule ; vous avez probablement " +"utilisé une esperluette sans intention d’écrire une entité — échappez " +"l’esperluette avec &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Le document doit commencer avec un élément (par ex. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"« %s » n’est pas un caractère valide à la suite du caractère « < » ; il ne " +"semble pas commencer un nom d’élément" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Caractère anormal « %s », un caractère « > » est requis pour terminer la " +"balise d’élément vide « %s »" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Trop d’attributs dans l’élément « %s »" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Caractère anormal « %s », un caractère « = » est requis après le nom de " +"l’attribut « %s » de l’élément « %s »" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Caractère anormal « %s », il est requis un caractère « > » ou « / », ou " +"optionnellement un attribut, pour clore la balise de début de l’élément " +"« %s » ; peut-être avez-vous utilisé un caractère non valide dans un nom " +"d’attribut" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Caractère anormal « %s », un guillemet d’ouverture après le signe égal est " +"requis quand on affecte une valeur à l’attribut « %s » de l’élément « %s »" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"« %s » n’est pas un caractère valide à la suite du nom d’élément « %s » à " +"fermer ; le caractère autorisé est « > »" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "L’élément « %s » a été fermé, aucun élément n’est actuellement ouvert" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"L’élément « %s » a été fermé, mais l’élément actuellement ouvert est « %s »" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Le document était vide ou ne contenait que des espaces" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Le document s’est terminé de manière inattendue juste après un crochet " +"ouvrant « < »" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Le document s’est terminé de manière inattendue avec des éléments encore " +"ouverts — « %s » était le dernier élément ouvert" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Le document s’est terminé de manière inattendue, un crochet fermant pour la " +"balise <%s/> est requis" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "" +"Le document s’est terminé de manière inattendue à l’intérieur d’un nom " +"d’élément" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" +"Le document s’est terminé de manière inattendue à l’intérieur d’un nom " +"d’attribut" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Le document s’est terminé de manière inattendue à l’intérieur d’une balise " +"d’ouverture d’élément." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Le document s’est terminé de manière inattendue après le signe égal suivant " +"un nom d’attribut ; aucune valeur d’attribut" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"Le document s’est terminé de manière inattendue alors qu’il était à " +"l’intérieur d’une valeur d’attribut" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Le document s’est terminé de manière inattendue à l’intérieur de la balise " +"de fermeture pour l’élément « %s »" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Le document s’est terminé de manière inattendue à l’intérieur de la balise " +"de fermeture pour un élément non ouvert" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Le document s’est terminé de manière inattendue à l’intérieur d’un " +"commentaire ou d’une instruction de traitement" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPTION…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Options de l’aide :" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Affiche les options de l’aide" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Affiche toutes les options de l’aide" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Options de l’application :" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Options :" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Impossible d’analyser la valeur entière « %s » pour %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "La valeur entière « %s » pour %s est hors plage" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Impossible d’analyser la valeur double « %s » pour %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "La valeur double « %s » pour %s est hors plage" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Erreur lors de l’analyse de l’option %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Paramètre manquant pour %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Option inconnue %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "objet endommagé" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "erreur interne ou objet endommagé" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "mémoire insuffisante" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "limite de suivi arrière atteinte" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"le motif contient des éléments non pris en charge pour une correspondance " +"partielle" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "erreur interne" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"les références inverses utilisées comme conditions ne sont pas prises en " +"charge pour une correspondance partielle" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "limite de récursivité atteinte" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "combinaison de marqueurs de nouvelle ligne non valide" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "mauvais décalage" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 court" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "boucle récursive" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "erreur inconnue" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ à la fin du motif" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c à la fin du motif" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "un caractère non reconnu suit \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "nombres en désordre dans le quantificateur {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "nombre trop grand dans le quantificateur {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "caractère terminaison ] manquant pour la classe de caractère" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "séquence d’échappement non valide dans la classe de caractère" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "plage déclassée dans la classe de caractère" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "rien à répéter" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "répétition inattendue" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "caractère non reconnu après (? ou (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "" +"Les classes nommées selon la norme POSIX sont uniquement prises en charge " +"dans une classe" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr ") de terminaison manquante" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "référence à un sous-motif inexistant" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "« ) » manquante après un commentaire" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "l’expression régulière est trop grande" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "l’obtention de la mémoire a échoué" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") sans ( d’ouverture" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "dépassement de code" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "caractère non reconnu après (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "l’assertion « lookbehind » n’a pas de longueur fixe" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "nom ou nombre non conforme après (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "un groupe conditionnel contient plus de deux branches" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "une assertion est attendue après (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "« (?R » ou « (?[+-]chiffres » doivent être suivis d’une « ) »" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nom de classe POSIX inconnu" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "les éléments d’interclassement POSIX ne sont pas pris en charge" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "la valeur du caractère dans la séquence \\x{…} est trop grande" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condition (?(0) non valide" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C n’est pas autorisé dans l’assertion « lookbehind »" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" +"les échappements \\L, \\l, \\N{name}, \\U et \\u ne sont pas pris en charge" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "un appel récursif peut effectuer des boucles indéfiniment" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "caractère non reconnu après (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "terminaison manquante dans le nom du sous-motif" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "deux sous-motifs nommés possèdent le même nom" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "séquence \\P ou \\p mal formée" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nom de propriété inconnu après \\P ou \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "le nom du sous-motif est trop long (32 caractères maximum)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "trop de sous-motifs nommés (10 000 maximum)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "la valeur octale est plus grande que \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "dépassement de capacité en compilant l’espace de travail" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "un sous-motif référencé et précédemment vérifié n’a pas été trouvé" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "le groupe DEFINE contient plus d’une branche" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "options NEWLINE inconsistantes" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g n’est pas suivi d’un nom ou nombre entre accolades, chevrons, guillemets " +"simples ou d’un nombre simple" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "une référence numérotée ne doit pas être zéro" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "un paramètre n’est pas permis pour (*ACCEPT), (*FAIL) ou (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) non reconnu" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "le nombre est trop grand" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "nom de sous-motif manquant après (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "chiffre attendu après (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] est un caractère de données non valide en mode de compatibilité JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" +"il n’est pas permis d’avoir des noms différents pour des sous-motifs du même " +"nombre" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) doit avoir un paramètre" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c doit être suivi d’un caractère ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k n’est pas suivi d’un nom entre accolades, chevrons ou guillemets simples" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N n’est pas pris en charge dans une classe" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "trop de références en avant" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "le nom est trop long dans (*MARK), (*PRUNE), (*SKIP) ou (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "la valeur du caractère dans la séquence \\u.... est trop grande" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Erreur lors de la correspondance de l’expression régulière %s : %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "La bibliothèque PCRE est compilée sans la prise en charge UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"La bibliothèque PCRE est compilée sans la prise en charge des propriétés " +"UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "La bibliothèque PCRE est compilée avec des options incompatibles" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Erreur lors de l’optimisation de l’expression régulière %s : %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"Erreur à la compilation de l’expression régulière %s au caractère %d : %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "chiffre hexadécimal ou « } » attendu" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "chiffre hexadécimal attendu" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "« < » manquant dans la référence symbolique" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "référence symbolique non terminée" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "référence symbolique de longueur nulle" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "chiffre attendu" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "référence symbolique illégale" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "terminaison parasite « \\ »" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "séquence d’échappement inconnue" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Erreur lors de l’analyse du texte de substitution « %s » au caractère %lu : " +"%s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Le texte cité ne commence pas par des guillemets" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Guillemets de fermeture introuvables dans la ligne de commande ou autre " +"texte rapporté" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "" +"Le texte s’est terminé juste après un caractère « \\ » (le texte était " +"« %s »)." + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Le texte s’est terminé avant que des guillemets correspondants ne soient " +"rencontrés pour %c (le texte était « %s »)." + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Le texte était vide (ou ne contenait que des espaces)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "La lecture des données depuis le processus fils a échoué (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "" +"Erreur inattendue lors de la lecture de données depuis un processus fils (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Erreur inattendue dans waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Le processus fils s’est terminé avec le code %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Le processus fils a été tué par le signal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Le processus fils a été arrêté par le signal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Le processus fils s’est terminé anormalement" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "La lecture depuis un tube fils a échoué (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "L’exécution du processus fils « %s » a échoué (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Le clonage a échoué (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Le changement de répertoire « %s » a échoué (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "L’exécution du processus fils « %s » a échoué (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" +"L’ouverture du fichier pour réallouer le descripteur de fichier a échoué (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "" +"La duplication du descripteur de fichier pour le processus fils a échoué (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Le clonage du processus fils a échoué (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "" +"La fermeture du descripteur de fichier pour le processus fils a échoué (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Erreur inconnue à l’exécution du processus fils « %s »" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Impossible de lire suffisamment de données depuis le tube du processus fils " +"de pid (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "La lecture des données depuis le processus fils a échoué" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "L’exécution du processus fils a échoué (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "L’appel à dup() dans le processus fils a échoué (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nom de programme non valide : %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Chaîne non valide dans le vecteur de paramètre à %d : %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Chaîne non valide dans l’environnement : %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Répertoire de travail non valide : %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "L’exécution du programme d’aide a échoué (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Erreur inattendue dans g_io_channel_win32_poll() lors de la lecture des " +"données depuis un processus fils" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Une chaîne vide n’est pas un nombre" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "« %s » n’est pas un nom valide" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Le nombre « %s » est hors limites [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "« %s » n’est pas un nombre non signé" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-encoding non valide dans l’URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Caractère interdit dans l’URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caractère non-UTF-8 dans l’URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Adresse IPv6 invalide « %.*s » dans l’URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Adresse IP encodée interdite « %.*s » dans l’URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nom d’hôte internationalisé interdit « %.*s » dans l’URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Impossible d’analyser le port « %.*s » dans l’URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Le port « %.*s » de l’URI est en dehors de la plage" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "L’URI « %s » n’est pas une URI absolue" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "l’URI « %s » n’a pas de partie hôte" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "L’URI n’est pas absolue, et aucune URI de base n’a été fournie" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Caractère « = » et paramètre manquants" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Impossible d’allouer de la mémoire" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Caractère hors plage pour UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Séquence non valide dans l’entrée du convertisseur" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Caractère hors plage pour UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f ko" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mo" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Go" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f To" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f Po" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f Eo" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f Kio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f Mio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f Gio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f Tio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f Pio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f Eio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u octet" +msgstr[1] "%u octets" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s octet" +msgstr[1] "%s octets" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f Ko" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mo" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Go" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f To" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f Po" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f Eo" + +#~ msgid "Failed to redirect output or input of child process (%s)" +#~ msgstr "" +#~ "La redirection de la sortie ou de l’entrée du processus fils a échoué (%s)" + +#~ msgid "Unknown error on connect" +#~ msgstr "Erreur inconnue à la connexion" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "" +#~ "Erreur dans l’adresse « %s » — l’attribut de la famille est mal formé" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s a été monté sur %s\n" diff --git a/po/fur.po b/po/fur.po new file mode 100644 index 0000000..6a17610 --- /dev/null +++ b/po/fur.po @@ -0,0 +1,6199 @@ +# Friulian translation for glib. +# Copyright (C) 2017 glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the glib package. +# Fabio Tomat , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-07 18:49+0000\n" +"PO-Revision-Date: 2022-03-08 05:00+0000\n" +"Last-Translator: Fabio Tomat \n" +"Language-Team: Friulian \n" +"Language: fur\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-Editor: HaiPO 1.0 Release\n" +"X-Generator: Poedit 3.0\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "" +"No je ancjemò supuartade la pussibilitât di stabilî lis aplicazions " +"predefinidis" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"No je ancjemò supuartade la pussibilitât di stabilî la aplicazion come chê " +"ultime doprade pal gjenar." + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opzions GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Mostre lis opzions di GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Jentre in modalitât servizi GApplication (doprâ dai file di servizi D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Passe sore al ID de aplicazion" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Sostituìs la istance in esecuzion" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Stampe jutori" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 +#: gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMANT]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Stampe version" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Stampe informazions su la version e jes" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Liste aplicazions" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Liste lis aplicazion instaladis che si puedin ativâ di D-Bus (par file " +".desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Invie une aplicazion" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Invie la aplicazion (cun file opzionâi di vierzi)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FILE…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Ative une azion" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invoche une azion su la aplicazion" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID AZION [PARAMETRI]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Liste azions disponibilis" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Liste lis azions statichis par une aplicazion (dal file .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMANT" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Il comant che di chel stampâ il jutori detaiât" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identificadôr aplicazion tal formât D-Bus (p.e. org.esempli.visualizadôr)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FILE" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Nons di file assolûts o relatîfs opzionâi opûr URI di vierzi" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "AZION" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "La azion di invocâ" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETRI" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Parametri opzionâl pe invocazion de azion, in formât GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 +#: gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Comant no cognossût %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Ûs:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argoments:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Comants:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Dopre “%s help COMANT†par vê un jutori detaiât.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Il comant %s al domande un id di aplicazion di seguî in maniere direte\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "id aplicazion no valit: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†no si spiete nissun argoment\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "impussibil conetisi al D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "erôr tal inviâ il messaç %s ae aplicazion: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "si scugne furnî il non de azion dopo il id de aplicazion\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"non azion no valit: “%sâ€\n" +"i nons des azions a scugnin consisti nome di alfanumerics, “-†e “.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "erôr tal analizâ il parametri de azion: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "lis azions a acetin un massim di un parametri\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "il comant list-actions al vûl dome il id de aplicazion" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "impussibil cjatâ il file scritori pe aplicazion %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"comant no ricognossût: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Valôr di conte passât a %s masse grant" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Ricercje no supuartade sul flus di base" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Impussibil cjonçâ GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Il flus al è za sierât" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Cjonçâ no supuartât sul flus di base" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1873 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "La operazion e jere anulade" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Ogjet no valit, no inizializât" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Secuence multibyte incomplete tal input" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "No vonde spazi te destinazion" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Secuence byte no valide tal input di conversion" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Erôr dilunc la conversion: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Inizializazion anulabile no supuartade" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Conversion de cumbinazion di caratars “%s†a “%s†no je supuartade" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Impussibil vierzi il convertidôr di “%s†a “%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "gjenar %s" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Gjenar no cognossût" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "gjenar di file %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials al conten dâts no valits" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials nol è implementât in chest SO" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Nol esist il supuart par GCredentials pe tô plateforme" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials nol conten un ID di procès su chest SO" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Imbroi des credenziâls (spoofing) nol è pussibil su chest SO" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Fin-dal-flus premadûr inspietât" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Clâf “%s†no supuartade inte vôs di direzion “%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" +"Cumbinazion de cubie clâf/valôr cence significât inte vôs di direzion “%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Direzion “%s†no valide (e covente juste un tra une clâf astrate, tmpdir, " +"dir o percors)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Erôr te direzion “%s†— l'atribût “%s†al è malformât" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Traspuart “%s†no cognossût o no supuartât pe direzion “%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "L'element direzion “%s†nol conten un doi ponts (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" +"Il non dal traspuart intal element de direzion “%s†nol à di jessi vueit" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Cubie clâf/valôr %d, “%sâ€, intal element direzion “%s†no conten un segn " +"uguâl" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Cubie clâf/valôr %d, “%sâ€, intal element direzion “%s†nol à di contignî une" +" clâf vueide" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element" +" “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Erôr inte direzion “%s†— il traspuart unix al domande di stabilî juste une " +"des clâfs tra “path†o “abstractâ€" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Erôr inte direzion “%s†— l'atribût host al mancje o al è malformât" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Erôr inte direzion “%s†— l'atribût puarte al mancje o al è malformât" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "" +"Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Erôr te direzion “%s†— al mancje, o al è malformât, l'atribût dal file dal " +"numar doprât une sole volte" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Erôr tal inviâ in automatic: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Erôr tal vierzi il file dal numar doprât une sole volte “%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Erôr tal lei dal file dal numar doprât une sole volte “%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Erôr tal lei dal file dal numar doprât une sole volte “%sâ€, si spietavin 16 " +"byte, si à vût %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Erôr tal scrivi sul flus i contignûts dal file dal numar doprât une sole " +"volte “%sâ€:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "La direzion furnide e je vueide" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Impussibil inviâ in automatic D-Bus cence $DISPLAY X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "" + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Impussibil determinâ la direzion dal bus di session (no implementade par " +"chest SO)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7334 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable" +" — unknown value “%sâ€" +msgstr "" +"Impussibil determinâ la direzion dal bus de variabile di ambient " +"DBUS_STARTER_BUS_TYPE — valôr “%s†no cognossût" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7343 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Impussibil determinâ la direzion dal bus parcè che la variabile di ambient " +"DBUS_STARTER_BUS_TYPE no je stabilide" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Gjenar di bus %d no cognossût" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Mancjance di contignût inspietade cirint di lei une rie" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Mancjance di contignût inspietade cirint di lei (in sigurece) une rie" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: " +"%s)" +msgstr "" +"Esaurîts ducj i mecanisims di autenticazion disponibii (provâts: %s) " +"(disponibii: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Anulât vie GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Erôr tal vê informazions pe cartele “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"I permès su pe cartele “%s†no son valits. Si spietave modalitât 0700, vût " +"0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Erôr tal creâ la cartele “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operazion no supuartade" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Erôr tal lei il puarteclâfs “%s†pe leture: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "La rie %d dal puarteclâfs su “%s†cun contignût “%s†e je malformade" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Il prin token de rie %d dal puarteclâfs su “%s†cul contignût “%s†al è " +"malformât" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is " +"malformed" +msgstr "" +"Il secont token de rie %d dal puarteclâfs su “%s†cul contignût “%s†al è " +"malformât" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "No si à cjatât il cookie cul id %d intal puarteclâfs su “%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Erôr tal creâ il file di bloc “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Erôr tal eliminâ il file di bloc passât “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Erôr tal sierâ il file di bloc (cence colegament) “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Erôr tal discolegâ il file di bloc “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Erôr tal vierzi il puarteclâfs “%s†pe scriture: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(In plui no si è rivâts ancje a molâ il bloc par “%sâ€: %s) " + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2418 +msgid "The connection is closed" +msgstr "La conession e je sierade" + +#: gio/gdbusconnection.c:1903 +msgid "Timeout was reached" +msgstr "Si à passât il timp massim" + +#: gio/gdbusconnection.c:2541 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Si à intivât opzions no supuartadis cuant che si costruive une conession de " +"bande dal client" + +#: gio/gdbusconnection.c:4269 gio/gdbusconnection.c:4623 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Interface “org.freedesktop.DBus.Properties†inesistente sul ogjet tal " +"percors %s" + +#: gio/gdbusconnection.c:4414 +#, c-format +msgid "No such property “%sâ€" +msgstr "Proprietât “%s†inesistente" + +#: gio/gdbusconnection.c:4426 +#, c-format +msgid "Property “%s†is not readable" +msgstr "No si pues lei la proprietât “%sâ€" + +#: gio/gdbusconnection.c:4437 +#, c-format +msgid "Property “%s†is not writable" +msgstr "No si pues scrivi la proprietât “%sâ€" + +#: gio/gdbusconnection.c:4457 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Erôr tal configurâ la proprietât “%sâ€: si spietave il gjenar “%s†ma si à " +"vût “%sâ€" + +#: gio/gdbusconnection.c:4562 gio/gdbusconnection.c:4777 +#: gio/gdbusconnection.c:6760 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Interface “%s†inesistente" + +#: gio/gdbusconnection.c:4999 gio/gdbusconnection.c:7274 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Interface “%s†inesistente sul ogjet tal percors %s" + +#: gio/gdbusconnection.c:5100 +#, c-format +msgid "No such method “%sâ€" +msgstr "Metodi “%s†inesistent" + +#: gio/gdbusconnection.c:5131 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Il gjenar di messaç “%sâ€, nol corispuint al gjenar spietât “%sâ€" + +#: gio/gdbusconnection.c:5334 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Un ogjet al è za espuartât pe interface %s su %s" + +#: gio/gdbusconnection.c:5561 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Impussibil recuperâ la proprietât %s.%s" + +#: gio/gdbusconnection.c:5617 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Impussibil stabilî la proprietât %s.%s" + +#: gio/gdbusconnection.c:5796 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Il metodi “%s†al à tornât il gjenar “%sâ€, ma si spietave “%sâ€" + +#: gio/gdbusconnection.c:6872 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Il metodi “%s†su pe interface “%s†cun firme “%s†nol esist" + +#: gio/gdbusconnection.c:6993 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Un sot-arbul al è za espuartât par %s" + +#: gio/gdbusconnection.c:7282 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "il gjenar al è NO VALIT" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Messaç METHOD_CALL: il cjamp di intestazion PATH o MEMBER al mancje" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Messaç METHOD_RETURN: il cjamp di intestazion REPLY_SERIAL al mancje" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Messaç di ERÔR: il cjamp di intestazion REPLY_SERIAL o ERROR_NAME al mancje" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Messaç SIGNAL: il cjamp di intestazion PATH, INTERFACE o MEMBER al mancje" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value " +"/org/freedesktop/DBus/Local" +msgstr "" +"Messaç SIGNAL: il cjamp di intestazion PATH al sta doprant il valôr riservât" +" /org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value " +"org.freedesktop.DBus.Local" +msgstr "" +"Messaç SIGNAL: il cjamp di intestazion INTERFACE al sta doprant il valôr " +"riservât org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Si voleve lei %lu byte, ma si à vût dome %lu" +msgstr[1] "Si voleve lei %lu byte, ma si à vût dome %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"Si spietave un byte NUL dopo de stringhe “%s†ma si à cjatât il byte %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was " +"“%sâ€" +msgstr "" +"Si spietave une stringhe UTF-8 valide ma si à cjatât byte no valits al byte " +"offset %d (la lungjece de stringhe e je %d). La stringhe UTF-8 valide fin " +"chel pont e jere “%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Valôr nidificât masse in profonditât" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Il valôr “%s†analizât nol è un percors di ogjet D-Bus valit" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Il valôr “%s†analizât no je une firme D-Bus valide" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 " +"MiB)." +msgstr[0] "" +"Si à intivât un array lunc %u byte. La lungjece massime e je 2<<26 byte (64 " +"MiB)." +msgstr[1] "" +"Si à intivât un array lunc %u byte. La lungjece massime e je 2<<26 byte (64 " +"MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Si à intivât un array di gjenar “a%câ€, si veve di vê une lungjece multiple " +"di %u byte, ma si à cjatât che e jere di %u byte" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Il valôr “%s†analizât pal variant no je une firme D-Bus valide" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire " +"format" +msgstr "" +"Erôr tal deserializâ GVariant cu la stringhe di gjenar “%s†dal formât fîl " +"di D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valôr di endian no valit. Si spietave 0x6c (“lâ€) o 0x42 (“Bâ€) ma si à cjatât" +" il valôr 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Version maiôr dal protocol no valide. Si spietave 1 ma si à cjatât %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Cjatade intestazion di firme ma no je di gjenar firme" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Cjatade intestazion di firme cun firme “%s†ma il cuarp dal messaç al è " +"vueit" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Il valôr “%s†analizât no je une firme D-Bus valide (pal cuarp)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Nissune intestazion di firme tal messaç, ma il cuarp dal messaç al è di %u " +"byte" +msgstr[1] "" +"Nissune intestazion di firme tal messaç, ma il cuarp dal messaç al è di %u " +"byte" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Impussibil deserializâ il messaç: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Erôr tal serializâ GVariant cu la stringhe di gjenar “%s†al formât fîl di " +"D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Il numar dai descritôrs di file tal messaç (%d) al è diviers dal cjamp di " +"intestazion (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Impussibil serializâ il messaç: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Il cuarp dal messaç al à firme “%s†ma no je la intestazion de firme" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Il cuarp dal messaç al à une firme di gjenar “%sâ€, ma la firme tal cjamp de " +"intestazion e je “%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"Il cuarp dal messaç al è vueit ma la firme tal cjamp de intestazion e je " +"“(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Scrîf cualsisei caratar par sierâ chest barcon)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Session dbus no je in esecuzion e l'inviament automatic al è falît" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Impussibil otignî il profîl Hardware: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Impussibil cjariâ %s o %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Erôr tal clamâ StartServiceByName par %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Rispueste %d inspietade dal metodi StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Impussibil invocâ il metodi; il proxy al è pal no ben-cognossût %s cence un " +"proprietari e il proxy al jere costruît cu la opzion " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Spazi di non astrat no supuartât" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Impussibil specificâ il file dal numar doprât une sole volte cuant che si " +"creave un servidôr" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Erôr tal scrivi il file dal numar doprât une sole volte su “%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "La stringhe “%s†no je un valit GUID D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Impussibil scoltâ o traspuart “%s†no supuartât" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Comants:\n" +" help Mostre chestis informazions\n" +" introspect Introspezion di un ogjet lontan\n" +" monitor Monitorâ un ogjet lontan\n" +" call Invocâ un metodi suntun ogjet lontan\n" +" emit Emet un segnâl\n" +" wait Spiete che un non di bus al vegni fûr\n" +"\n" +"Dopre “%s COMANT --help†par vê jutori su ogni comant.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Erôr: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Erôr tal analizâ XML di introspezion: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Erôr: %s nol è un non valit\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Erôr: %s nol è un percors ogjet valit\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Conet al bus di sisteme" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Conet al bus di session" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Conet ae direzion D-Bus furnide" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opzions dal pont finâl de conession:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opzions che a specifichin il pont finâl (endpoint) de conession" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nissun pont finâl (endpoint) di conession specificât" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Plui ponts finâi (endpoint) di conession specificâts" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Avertiment: In acuardi cui dâts di introspezion, la interface “%s†no " +"esist\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Avertiment: In acuardi cui dâts di introspezion, il metodi “%s†nol esist su" +" pe interface “%sâ€\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Destinazion opzionâl pal segnâl (non univoc)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Percors ogjet dulà emeti il segnâl" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Segnâl e non interface" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emet un segnâl." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Erôr tal coneti: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Erôr: %s nol è un non bus univoc valit.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Erôr: il percors ogjet nol è specificât\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Erôr: il non dal segnâl nol è specificât\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Erôr: il non segnâl “%s†nol è valit\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Erôr: %s nol è un non interface valit\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Erôr: %s nol è un non membri valit\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Erôr tal analizâ il parametri %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Erôr tal resentâ la conession: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Il non di destinazion de invocazion dal metodi" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Percors dal ogjet de invocazion dal metodi" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Metodi e non interface" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Timp massim in seconts" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Permet autorizazion interative" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Invoche un metodi suntun ogjet lontan." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Erôr: Destinazion no specificade\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Erôr: %s nol è un non bus valit\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Erôr: il non dal metodi nol è specificât\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Erôr: il non dal metodi “%s†nol è valit\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Erôr tal analizâ il parametri %d di gjenar “%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Erôr tal zontâ il gjestôr %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Non di destinazion de introspezion" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Percors dal ogjet de introspezion" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Stampe XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Auto-esamine i fîs" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Dome stampe proprietâts" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Auto-esamine un ogjet lontan." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Non di destinazion di monitorâ" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Percors dal ogjet di monitorâ" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitore un ogjet lontan." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Erôr: impussibil monitorâ une conession non-message-bus\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Servizi di ativâ prime di spietâ par chel altri (non ben-cognossût)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout" +" (default)" +msgstr "" +"Timp di spietâ prime di jessi cuntun erôr (seconts); 0 par no vê scjadince " +"(predefinît)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPZION…] NON-BUS" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Spiete che al vegni fûr un non di bus." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Erôr: si scugne specificâ un servizi che si à di ativâ.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Erôr: si scugne specificâ un servizi che si à di spietâ.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Erôr: masse argoments.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Erôr: %s nol è un non di bus ben-cognossût valit\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Cence non" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Il file .desktop nol specifiche il cjamp Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Impussibil cjatâ il terminâl necessari pe aplicazion" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Impussibil creâ la cartele dal utent pe configurazion de aplicazion %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Impussibil creâ la cartele dal utent pe configurazion MIME %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "La informazion de aplicazion e mancje di un identificadôr" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Impussibil creâ il file .desktop %s dal utent" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Definizion personalizade par %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "la unitât no implemente eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "la unitât no implemente eject o eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "la unitât no implemente il control sistematic dai supuarts" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "la unitât no implemente la azion start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "la unitât no implemente la azion stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Il supuart TLS nol è disponibil" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Il supuart DTLS nol è disponibil" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Impussibil gjestî la version %d de codifiche GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Numar di token malformât (%d) inte codifiche GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Impussibil gjestî la version %d de codifiche GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Numar di token malformât (%d) inte codifiche GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Si spietave un GEmblem par GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Il montaç contignût nol esist" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Impussibil copiâ sore de cartele" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Impussibil copiâ la cartele sore de cartele" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Il file di destinazion al esist" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Impussibil copiâ in maniere ricorsive la cartele" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "La copie (reflink/clone) tra i montaçs no je supuartade" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "La copie (reflink/clone) no je supuartade o no je valide" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "La copie (reflink/clone) no je supuartade o no à funzionât" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Impussibil copiâ il file speciâl" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Furnît valôr di colegament simbolic no valit" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Colegaments simbolics no supuartâts" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Scovacere no supuartade" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "I nons dai file no puedin contignî “%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "il volum nol implemente la azion mount" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "No je regjistrade nissune aplicazion par gjestî chest file" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "L'enumeradôr al è sierât" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "L'enumeradôr dal file al è za sierât" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Impussibil gjestî la version %d de codifiche GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Dâts di input malformâts par GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Il flus nol supuarte la azion query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Ricercje no supuartade sul flus" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Cjonçâ no permetût sul flus di jentrade" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Cjonçâ no supuartât sul flus" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Non dal host no valit" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Rispueste dal proxy HTTP sbaliade" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Conession proxy HTTP no permetude" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Autenticazion proxy HTTP falide" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Domandade autenticazion proxy HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Conession proxy HTTP falide: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Rispueste masse grande dal proxy HTTP" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" +"Il servidôr proxy HTTP al à sierât la conession in maniere inspietade." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Numar di token sbaliât (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Nissun gjenar pal non de classe %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Il gjenar %s nol implemente la interface GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Il Gjenar %s nol à classe" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Numar di version malformât: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Il gjenar %s nol implemente from_tokens() su la interface GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Impussibil gjestî la version furnide de codifiche de icone" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nissune direzion specificade" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "La lungjece %u e je masse lungje pe direzion" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "La direzion e presente cualchi bit plui in là de lungjece dal prefìs" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Impussibil analizâ “%s†come mascare de direzion IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "No vonde spazi pe direzion dal socket" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Direzion dal socket no supuartade" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Il flus di jentrade nol implemente la leture" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Il flus al à une operazion ecezionâl" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copie cul file" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Ten adun cul file cuant che si sposte" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†no vûl nissun argoment" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Ûs:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Stampe informazions su la version e jes." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Comants:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Met dongje i file su la jessude standard (standard output)" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copie un o plui file" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Mostre informazions su lis posizions" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Invie une aplicazion di un file “desktopâ€" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Liste i contignûts des posizions" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Oten o stabilìs il gjestôr par un gjenar di mime" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Cree cartelis" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Ten di voli lis modifichis a file e cartelis" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Monte o dismonte lis posizions" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Sposte un o plui file" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Vierç i file cun la aplicazion predefinide" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Cambie non a un file" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Elimine un o plui file" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Lei de jentrade standard (standard input) e salve" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Stabilìs un atribût di file" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Sposte te scovacere file o cartelis" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Al liste intun arbul i contignûts des posizions" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Dopre %s par vê un jutori detaiât.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Erôr tal scrivi su stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "POSIZION" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" +"Met in cjadene i file e stampe su la jessude standard (standard output)." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat al funzione propite come la utilitât cat tradizionâl, ma doprant\n" +"lis posizions GIO al puest dai file locâi: par esempli tu puedis doprâ\n" +"alc come smb://servidôr/risorse/file.txt tant che posizion." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nissune posizion furnide" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nissune cartele di destinazion" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Mostre avanzament" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Domande prime di sorescrivi" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Preserve ducj i atribûts" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Fâs il backup dai file di destinazion esistents" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "No sta mai lâ daûr ai colegaments simbolics" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Dopre i permès predefinîts pe destinazion" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Trasferîts %s di %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SORZINT" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINAZION" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copie un o plui file de SORZINT ae DESTINAZION." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy al è simil ae utilitât cp tradizionâl, ma e dopre lis\n" +"posizions GIO al puest dai file locâi: par esempli tu puedis doprâ\n" +"alc come smb://servidôr/risorse/file.txt tant che posizion." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "La destinazion %s no je une cartele" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: sorescrivi “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Liste i atribûts scrivibii" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Oten informazions sul file-system" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "I atribûts di otignî" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBÛTS" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "No sta lâ daûr ai colegaments simbolics" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atribûts:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "non di mostrâ: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "non di modificâ: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "non: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "gjenar: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "dimension: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "platât\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "percors locâl: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "montaç unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atribûts che si pues configurâ:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Mostre informazions su lis posizions." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info al è simil ae utilitât ls tradizionâl, ma al dopre lis\n" +"posizions GIO al puest dai file locâi: par esempli tu puedis doprâ\n" +"alc come smb://servidôr/risorse/file.txt tant che posizion. I atribûts\n" +"dai file a puedin jessi specificâts cul lôr non GIO, p.e. standard::icon, \n" +"o dome cul spazi dai nons, p.e. unix, o cun “*â€, che al cjape ducj i atribûts" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "FILE-DESKTOP [ARG-FILE …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Invie une aplicazion di un file desktop, passantji argoments di nons di " +"files opzionâi." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nissun file “desktop†furnît" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" +"Il comant di inviament in chest moment nol è supuart su cheste plateforme" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Impussibil cjariâ “%sâ€: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Impussibil cjariâ lis informazions de aplicazion par “%sâ€" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Impussibil cjariâ la aplicazion ‘%s’: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Mostre file platâts" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Dopre un formât di liste prolìs" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Stampe nons dai visôrs" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Stampe i URI complets" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Liste i contignûts des posizions." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list al è simil ae utilitât ls tradizionâl, ma al dopre lis\n" +"posizions GIO al puest dai file locâi: par esmpli tu puedis doprâ\n" +"alc come smb://servidôr/risorse/file.txt tant che posizion. I atribûts\n" +"dai file a puedin jessi specificâts cul lôr non GIO, p.e. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "GJENARMIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "GJESTÔR" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Oten o stabilìs il gjestôr par un gjenar di mime." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Se nissun gjestôr al è furnît, al liste lis aplicazions regjistradis e conseadis\n" +"par un gjenar di mime. Se un gjestôr al ven furnît, chel al ven stabilît come gjestôr\n" +"predefinît pal gjenar mime." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Si scugne specificâ un singul gjenar mime e se si vûl un gjestôr" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Nissune aplicazion predefinide par “%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplicazion predefinide par “%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplicazions regjistradis:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nissune aplicazion regjistrade\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplicazions conseadis:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Nissune aplicazion conseade\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "No si è rivâts a cjariâ lis informazion pal gjestôr “%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "No si è rivâts a stabilî “%s†come gjestôr predefinît par “%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Cree cartelis superiôrs" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Cree cartelis." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir al è simil ae utilitât mkdir tradizionâl, ma al dopre lis\n" +"posizions GIO al puest dai file locâi: par esempli tu puedis doprâ alc\n" +"come smb://servidôr/risorse/mêcartele tant che posizion." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Ten di voli une cartele (predefinît: al dipent dal gjenar)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Ten di voli un file (predefinît: al dipent dal gjenar)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Ten di voli un file in maniere direte (si vise des modifichis fatis par mieç" +" di colegaments permanents)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Al monitore un file in maniere direte, ma nol segnale modifichis" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Segnale spostaments e cambiaments di non come sempliçs events eliminât/creât" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Ten di voli i events di montaç" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitore i file o lis cartelis pes modifichis." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Monte come montabil" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Monte il volum cul file dal dispositîf o altri identificadôr" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Dismonte" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Pare fûr" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Ferme la unitât cul file dal dispositîf" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DISPOSITÃŽF" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Dismonte ducj i montaçs cul scheme indicât" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEME" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Ignore lis operazions ecezionâls sui file cuant che si dismonte o si pare " +"fûr" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Dopre un utent anonim cuant che si fâs la autenticazion" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Liste" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitore events" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Mostre informazions adizionâls" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Il PIM numeric cuant che si sbloche un volum VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Monte un volum platât TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Monte un volum di sisteme TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Acès anonim dineât" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Nissune unitât pal file di dispositîf" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Nissun volum pal ID indicât" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Monte o dismonte lis posizions." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "No sta doprâ i copie e elimine di repeç" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Sposte un o plui file di SORZINT a DESTINAZION." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move al è simil ae utilitât mv tradizionâl, ma e dopre lis\n" +"posizions GIO al puest dai file locâi: par esempli tu puedis doprâ\n" +"alc come smb://servidôr/risorse/file.txt tant che posizion" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "La destinazion %s no je une cartele" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Vierç i file cu la aplicazion definitive che\n" +"e je regjistrade par gjestî i file di chest gjenar." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignore i file inesistents, no sta domandâ mai" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Elimine i file furnîts." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NON" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Cambie non a un file." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Argoment mancjant" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Masse argoments" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Cambiâ di non lât ben. Gnûf uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Cree dome se nol esist" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Zonte ae fin dal file" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Cuant che si cree, limite l'acès al utent atuâl" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Cuant che si sostituìs, sostituìs come che la destinazion no esisti" + +#. Translators: The "etag" is a token allowing to verify whether a file has +#. been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Stampe gnûf etag ae fin" + +#. Translators: The "etag" is a token allowing to verify whether a file has +#. been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Il etag dal file che si sta par sorescrivi" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Erôr tal lei dal standard input" + +#. Translators: The "etag" is a token allowing to verify whether a file has +#. been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag no disponibil\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Lei de jentrade standard (standard input) e salve su DESTINAZION." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nissune destinazion furnide" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Gjenar dal atribût" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "GJENAR" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBÛT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALÔR" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Stabilìs un atribût di file di POSIZION." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Posizion no specificade" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atribût no specificât" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Valôr no specificât" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Gjenar di atribût “%s†no valit" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Disvuede la scovacere" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Liste i files te scovacere cu lis lôr posizions origjinâls" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Ripristine un file de scovacere te sô posizion origjinâl (se pussibil " +"tornant a creâ la cartele)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Impussibil cjatâ il percors origjinâl" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Impussibil tornâ a creâ la posizion origjinâl:" + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Impussibil spostâ il file te sô posizion origjinâl:" + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Sposte/Ripristine i files o lis cartelis te scovacere." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "La posizion indicade no scomence cun trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Seguìs i colegaments simbolics, i montaçs e lis scurtis" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Liste i contignûts des cartelis intun formât a arbul." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "L'element <%s> nol è permetût dentri di <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "L'element <%s> nol è permetût a nivel primari" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Il file %s al ven fûr plui voltis inte risorse" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "No si è rivâts a localizâ “%s†in nissune cartele sorzint" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "No si è rivâts a localizâ “%s†inte cartele atuâl" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Opzion di elaborazion “%s†no cognossude" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Pre-elaborazion %s domandade, ma %s nol è stabilît e %s nol è in PERCORS" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Erôr tal lei il file %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Erôr tal comprimi il file %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "il test al podarès no aparî dentri di <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Mostre la version dal program e jes" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Non dal file di jessude" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "CARTELE" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Gjenere la jessude intal formât selezionât pe estension dal non di file di " +"destinazion" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Gjenere intestazion sorzint" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Gjenere il codiç sorzint doprât par colegâ il file des risorsis dentri dal " +"to codiç" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Gjenere la liste des dipendencis" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Non dal file des dipendencis di gjenerâ" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Inclût lis destinazions falsis tal file des dipendencis gjenerât" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "No sta creâ in automatic e regjistrâ la risorse" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "No sta espuartâ lis funzions; declarilis G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"No sta incorporâ i dâts de risorse intal file C; assum invezit che al sedi " +"colegât par difûr" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Non identificadôr di C doprât pal codiç sorzint gjenerât" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compile une specifiche di risorse intun file di risorse.\n" +"I file de specifiche di risorse a àn la estension .gresource.xml\n" +"e i file de risorse a àn la estension clamade .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Si scugne dâ juste un non di file\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "il nick al scugne jessi di almancul 2 caratars" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Valôr numeric no valit" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " za specificât" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "valôr='%s' za specificât" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "i valôrs des opzions a scugnin vê stabilît al massim 1 bit" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> al à di contignî almancul un " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> nol è contignût intal interval specificât" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nol è un membri valit dal gjenar enumerât specificât" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" +"<%s> al conten stringhis che no son tal gjenar di opzions specificadis" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> al conten une stringhe che no je tes " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " za specificât par cheste clâf" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " no permetût pes clâfs di gjenar “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "il minim specificât di al è plui grant dal massim" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categorie l10n no supuartade: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n domandât, ma nissun domini gettext furnît" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "contest di traduzion furnît pal valôr cence l10n abilitât" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "No si è rivâts a analizâ il valôr di gjenar “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" nol pues jessi specificât pes clâfs etichetadis come clâfs che a " +"àn un gjenar enumerât" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " za specificât par cheste clâf" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr "" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "No son ametûts nons vueits" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Non “%s†no valit: i nons a scugnin scomençâ cuntune letare minuscule" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Non “%s†no valit: caratar “%c†no valit; a son permetûts dome letaris " +"minusculis, numars e il tratut (“-â€)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Non “%s†no valit: no son ametûts doi tratuts sucessivis (“--â€)" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Non “%s†no valit: l'ultin caratar nol pues jessi un tratut (“-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Non “%s†no valit: la lungjece massime e je 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> no (ancjemò) definît." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Stringhe di gjenar GVariant “%s†no valide" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%sâ€" +" does not extend “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Un percors, se indicât, al scugne scomençâ e finî cuntune sbare" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Il percors di une liste al scugne finî cun “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, " +"“/desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Al è permetût dome un element <%s> dentri <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Il test al podarès no aparî dentri di <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict al jere specificât; si jes." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Chest file intîr al è stât ignorât." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Si ignore chest file." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring" +" override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and " +"--strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema “%s†" +"(override file “%sâ€); ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema “%s†" +"(override file “%sâ€) and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Dulà archiviâ il file gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Interomp su cualsisei erôr tai schemis" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "No sta scrivi il file gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "No sta sfuarçâ lis restrizions dai nons des clâfs" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compile ducj i file scheme di GSettings intune cache di schemis.\n" +"I files di scheme a scugnin vê la estension .gschema.xml,\n" +"e il file cache al ven clamât gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Si scugne dâ juste un non di cartele" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nissun file di scheme cjatât: no si fâs nuie." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Nissun file di scheme cjatât: file di jessude esistent gjavât." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Non file %s no valit" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Erôr tal otignî lis informazion dal filesystem par %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Il montaç che al conten il file %s nol è stât cjatât" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Impussibil cambiâ il non de cartele lidrîs" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Erôr tal cambiâ non al file %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Impussibil cambiâ non al file, il non dal file al esist za" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Non file no valit" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Erôr tal vierzi il file %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Erôr tal gjavâ il file %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Erôr tal butâ te scovacere il file %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Impussibil creâ la cartele scovacere %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "" +"Impussibil cjatâ la cartele di nivel superiôr par butâ tes scovacis %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Nol è supuartât il butâ te scovacere su montaçs internis dal sisteme" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Impussibil cjatâ o creâ la cartele %s te scovacere %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "" +"Impussibil creâ il file des informazions de butade tes scovacis par %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Impussibil butâ tes scovacis il file %s jenfri i limits dal filesystem" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Impussibil butâ te scovacere il file %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Impussibil butâ te scovacere il file %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Erôr tal creâ la cartele %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Il filesystem nol supuarte i colegaments simbolics" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Erôr tal creâ il colegament simbolic %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Erôr tal spostâ il file %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Impussibil spostâ la cartele sore de cartele" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Creazion dal file di backup falide" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Erôr tal gjavâ il file di destinazion: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Spostament tra montaçs no supuartât" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Impussibil determinâ la utilizazion dal disc di %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Il valôr dal atribût al scugne jessi diviers di NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Gjenar di atribût no valit (si spietave une stringhe)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codifiche no valide)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Erôr dilunc il recupar des informazions pal file “%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Erôr dilunc il recupar des informazions pal descritôr dal file: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Gjenar di atribût no valit (si spietave uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Gjenar di atribût no valit (si spietave uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Gjenar di atribût no valit (si spietave une stringhe di byte)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Impussibil stabilî i permès sui colegaments simbolics" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Erôr tal stabilî i permès: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Erôr tal stabilî il proprietari: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Erôr tal stabilî il colegament simbolic: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Erôr tal stabilî il colegament simbolic: il file nol è un colegament " +"simbolic" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "La marche temporâl di UNIX %lld no sta tai 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"La marche temporâl di UNIX %lld e sta fûr dal interval supuartât di Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Nol è pussibil convertî a UTF-16 il non dal file “%sâ€" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Nol è pussibil vierzi il file “%sâ€: erôr di Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Erôr tal stabilî la ore di modifiche o di acès pal file “%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Erôr tal stabilî la ore di modifiche o acès: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Il contest SELinux al scugne jessi diviers di NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nol è abilitât su chest sisteme" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Erôr tal stabilî il contest SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "La configurazion dal atribût %s no je supuartade" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Erôr tal lei dal file: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Erôr tal sierâ il file: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Erôr tal cirî tal file: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Erôr tal scrivi sul file: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Erôr tal gjavâ il colegament dal backup vecjo: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Erôr tal creâ une copie di backup: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Erôr tal cambiâ non al file temporani: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "Erôr tal cjonçâ il file: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Erôr tal vierzi il file “%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Il file di destinazion al è une cartele" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Il file di destinazion nol è un file regolâr" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Il file al è stât modificât di difûr di chi" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Erôr tal gjavâ il file vecjo: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Furnît GSeekType no valit" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Richieste di ricercje no valide" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Impussibil cjonçâ GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Nol è pussibil ridimensionâ il flus di jessude de memorie" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "No si è rivâts a ridimensionâ il flus di jessude de memorie" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"La cuantitât de memorie necessarie par elaborâ la scriture e je plui grande " +"dal spazi di indreçament disponibil" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Domandât posizionament prime dal inizi dal flus" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Domandât posizionament plui in là de fin dal flus" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "il montaç nol implemente la azion par dismontâ “unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "il montaç nol implemente la azion par parâ fûr “ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Il non host “%s†al conten “[†ma no “]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Impussibil otignî il stât de rêt: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager nol è in esecuzion" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Version di NetworkManager masse vecje" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Il flus di jessude nol implemente la scriture" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Il flus sorzint al è za sierât" + +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Erôr tal risolvi “%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Domini no valit" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "La risorse lì di “%s†no esist" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "La risorse lì di “%s†no je rivade a decomprimisi" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "La risorse lì di “%s†no je une cartele" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FILE [PERCORS]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEZION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "PERCORS FILE" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr "" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Percors vueit furnît.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEME[:PERCORS]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEME[:PERCORS]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEME[:PERCORS] CLÂF" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEME[:PERCORS] CLÂF VALÔR" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEME[:PERCORS] [CLÂF]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr "" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr "" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nissun scheme instalât\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Furnît non di scheme vueit\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Clâf “%s†inesistente\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Il socket al è za sierât" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "I/O dal socket scjadût" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "E je stade specificade une famee no cognossude" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Al è stât specificât un protocol no cognossût" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "impussibil scoltâ: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Erôr tal leâ ae direzion %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Famee dal socket no supuartade" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Non interface masse lunc" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interface no cjatade: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Erôr tal acetâ la conession: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Conession in vore" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "" + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Erôr tal ricevi dâts: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Erôr tal inviâ dâts: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Impussibil distudâ il socket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Erôr tal sierâ il socket: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Impussibil inviâ il messaç: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Erôr tal inviâ il messaç: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Erôr tal ricevi il messaç: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Impussibil conetisi a %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Impussibil conetisi: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "" + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Non utent masse lunc pal protocol SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Il non host “%sâ€al è masse lunc pal protocol SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Il servidôr nol è un servidôr proxy SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Il servidôr nol è un servidôr proxy SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by" +" GLib." +msgstr "" + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Non utent o password masse luncs pal protocol SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "" + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "No si è rivâts a creâ il condot par comunicâ cul procès fi (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "I condots no son supuartâts in cheste plateforme" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "" + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "L'inviâ FD nol è supuartât" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "" +msgstr[1] "" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "" +msgstr[1] "" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "La ricezion di FD no je supuartade" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "" + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero " +"bytes" +msgstr "" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Lidrîs dal filesystem" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "No vonde memorie" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Erôr interni: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "A coventin plui dâts in ingrès" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Dâts comprimûts no valits" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Caratar che no si pues rapresentâ tal input di conversion" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Byte NUL incorporât tal input di conversion" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Byte NUL incorporât tal output di conversion" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the +#. time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %H:%M:%S, %e di %B dal %Y" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Zenâr" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Fevrâr" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Març" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Avrîl" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Jugn" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Lui" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Avost" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Setembar" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Otubar" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Novembar" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Dicembar" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Zen" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Fev" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Avr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jug" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Lui" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Avo" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Set" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Otu" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dic" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Lunis" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Martars" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Miercus" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Joibe" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Vinars" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sabide" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Domenie" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Lun" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Mar" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mie" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Joi" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Vin" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sab" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Dom" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Zenâr" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Fevrâr" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Març" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "Avrîl" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Jugn" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Lui" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "Avost" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Setembar" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Otubar" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "Novembar" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Dicembar" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Zen" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Fev" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Avr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jug" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Lui" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Avo" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Set" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Otu" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dic" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "" +msgstr[1] "" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Erôr tal lei il file “%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Il file “%s†al è masse larc" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "No si è rivâts a vierzi il file “%sâ€: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Nol è un file regolâr" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Non de clâf no valit: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "" + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "" + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "" + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†nol è un non valit" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†nol è un non valit: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an" +" element name" +msgstr "" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Masse atribûts tal element “%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPZION…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opzions aplicazion:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opzions:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Opzion %s no cognossude" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "ogjet ruvinât" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "erôr interni o ogjet ruvinât" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "memorie finide" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "erôr interni" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "erôr no cognossût" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nuie di ce ripeti" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "la espression regolâr e je masse largje" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "caratar no ricognossût dopo (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "non o numar malformât dopo (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "non di classe POSIX no cognossût" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condizion no valide (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "caratar no ricognossût dopo (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "secuence \\P o \\p malformade" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "il valôr otâl al è plui grant di \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "un riferiment numerât nol pues jessi zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "il numar al è masse grant" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N nol è supuartât intune classe" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "masse riferiments intal indenant" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "non masse lunc in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "valôr dal caratar inte secuence \\u.... al è masse grant" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Erôr intal otimizâ la espression regolâr %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Erôr intal compilâ la espression regolâr %s al caratar %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "al mancje “%†intal riferiment simbolic" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "riferiment simbolic no finît" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "riferiment simbolic di lungjece zero" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "riferiment simbolic ilegâl" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "secuence di escape no cognossude" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Erôr tal analizâ il test di sostituzion “%s†al caratar %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Il test citât nol tache cuntun segn di citazion" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Segn di citazion no cubiât inte rie di comant o altri test citât de shell" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Il test al è finît juste dopo un caratar “/â€. (Il test al jere “%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Test finît prime di cjatâ la citazion corispondent par %c. (Il test al jere " +"“%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Il test al jere vueit (o al contignive dome spazis vueits)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "No si è rivâts a lei dâts dal procès fi (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Erôr inspietât tai dâts di leture di un procès fi (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Erôr inspietât in waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Procès fi jessût cul codiç %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Procès fi copât dal segnâl %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Procès fi fermât dal segnâl %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Il procès fi al è jessût in maniere anormâl" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "No si è rivâts a lei dal condot dal fi (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "No si è rivâts a creâ il procès fi “%s†(%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "No si è rivâts a inglovâ (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "No si è rivâts a lâ ae cartele “%s†(%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "No si è rivâts a eseguî il procès fi “%s†(%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Impussibil vierzi il file par tornâ a mapâ il descritôr dal file (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Impussibil duplicâ il descritôr dal file pal procès fi (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "No si è rivâts a inglovâ il procès fi (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Impussibil sierâ il descritôr dal file pal procès fi (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Erôr no cognossût tal eseguî il procès fi “%sâ€" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "No si è rivâts a lei vonde dâts dal condot dal pid dal fi (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "No si è rivâts a lei dâts dal procès fi" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "No si è rivâts a eseguî il procès fi (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Impussibil fâ il dup() tal procès fi (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Non dal program no valit: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Stringhe no valide intal vetôr dal argoment su %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Stringhe no valide intal ambient: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Cartele di lavôr no valide: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "No si è rivâts a eseguî il program judant (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Erôr inspietât in g_io_channel_win32_poll() leint dâts di un procès fi" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "La stringhe vueide no je un numar" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†nol è un numar cun segn" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Il numar “%s†al è fûr dai limits [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†nol è un numar cence segn" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-encoding no valit tal URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Non ilegjitim dal host internazionalizât ‘%.*s’ tal URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Impussibil analizâ la puarte ‘%.*s’ tal URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "L'URI ‘%s’ nol è un URI assolût" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "No si è rivâts a assegnâ la memorie" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Caratar fûr dal limit par UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Secuence no valide intal input di conversion" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Caratar fûr dal limit par UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u byte" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s byte" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bit" + +#. Translators: this is from the deprecated function +#. g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been +#. preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using +#. this deprecated function. +#. * Please translate as literally as possible. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Impussibil cjariâ /var/lib/dbus/machine-id o /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Erôr no cognossût tal coneti" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Erôr inte direzion “%s†— l'atribût famee al è malformât" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " e --strict al jere specificât; si jes.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "no si fâs nuie.\n" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable" +#~ " - unknown value '%s'" +#~ msgstr "" +#~ "Impussibil determinâ la direzion dal bus de variabile di ambient " +#~ "DBUS_STARTER_BUS_TYPE — valôr '%s' no cognossût" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGS...]" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Erôr: percors ogjet no specificât.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Erôr: segnâl no specificât.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Erôr: il segnâl al scugne jessi il non cualificât ad implen.\n" + +#~ msgid "No files to open" +#~ msgstr "Nissun file di vierzi" + +#~ msgid "No files to delete" +#~ msgstr "Nissun file di eliminâ" diff --git a/po/ga.po b/po/ga.po new file mode 100644 index 0000000..1bad94d --- /dev/null +++ b/po/ga.po @@ -0,0 +1,3840 @@ +# Irish translations for glib package. +# Copyright (C) 2002-2011 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Alastair McKinstry , 2003. +# Seán de Búrca , 2007-2011. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2011-05-22 08:14-0600\n" +"Last-Translator: Seán de Búrca \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : (n%10==1 || n%10==2) ? 1 : (n" +"%10>=3 && n%10<= 6) ? 2 : ((n%10>=7 && n%10<=9) || n==10) ? 3 : 4;\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Theip ar leathnú líne reatha '%s' le URI '%s'" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Earráid le linn cumarsáide: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "Is neamhbhailí an URI '%s'" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Is neamhbhailí an t-óstainm an URI '%s'" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Óstainm neamhbhailí" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +#, fuzzy +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%H:%M:%S" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Eanáir" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Feabhra" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Márta" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "Aibreán" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Bealtaine" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Meitheamh" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Iúil" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "Lúnasa" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "Meán Fómhair" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "Deireadh Fómhair" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "Samhain" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "Nollaig" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Ean" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feabh" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Márta" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Aib" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Beal" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Meith" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Iúil" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Lún" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "MFómh" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "DFómh" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Samh" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Noll" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Dé Luain" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Dé Máirt" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Dé Céadaoin" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Déardaoin" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Dé hAoine" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Dé Sathairn" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Dé Domhnaigh" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Luan" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Máirt" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Céad" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Déar" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Aoine" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sath" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Domh" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Earráid agus comhadlann '%s' á oscailt: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Earráid agus comhad '%s' á léamh: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Tá comhad \"%s\" ró-mhór" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Theip ar léamh ó chomhad '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Theip ar oscailt comhaid '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Theip ar fháil tréithe comhaid '%s': theip fstat(): %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Theip ar oscailt comhaid '%s': theip fdopen(): %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Theip ar athainmniú comhaid '%s' go '%s': theip g_rename(): %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Theip ar chruthú comhaid '%s': %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Theip ar oscailt comhaid '%s' le haghaidh scríofa: theip fdopen(): %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Theip ar scríobh comhaid '%s': theip fwrite(): %s" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Theip ar scríobh comhaid '%s': theip fflush(): %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Theip ar scríobh comhaid '%s': theip fsync(): %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Theip ar dhúnadh comhaid '%s': theip fclose(): %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Níl XXXXXX ann sa teimpléad '%s'" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f EB" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Theip ar léamh nasc siombalach '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Theip ar oscailt comhad '%s': theip open(): %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Theip ar mapáil comhad '%s': theip mmap(): %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Earraidh ar líne %d carachtar %d:" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Téacs UTF-8-ionchódaithe neamhbhailí san ainm - níl '%s' bailí" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Earráid ar líne %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "réad truaillithe" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "earráid inmheánach nó réad truaillithe" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "cuimhne ídithe" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "earráid inmheánach" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "earráid anaithnid" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") gan ( tosaigh" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "theip ar fháil cuimhne" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Earráid agus slonn ionadaíochta %s á thiomsú ag carachtar %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "bhíothas ag súil le digit" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Theip ar léamh sonraí ó mhacphróiseas" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Theip ar léamh ó mhacphíopa (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ainm cláir neamhbhailí: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Comhadlann oibre neamhbhailí: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Theip ar rith cláir cabhrach (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Theip ar dhéanamh forc (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Earráid anaithnid agus macphróiseas \"%s\" á rith" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Úsáid:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[ROGHA...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Roghanna Cabhrach:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Taispeáin roghanna cabhrach" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Taispeáin gach rogha cabhrach" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Roghanna Feidhmchláir:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Earráid agus rogha %s á pharsáil" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Rogha anaithnid %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Ní gnáthchomhad é" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Is folamh é an comhad" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ainm grúpa neamhbhailí: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Ainm eocrach neamhbhailí: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Cineál anaithnid" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "cineál comhaid %s" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "cineál %s" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Earráid agus á nasc: " + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Earráid agus comhad '%s' á oscailt: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Earráid agus comhad '%s' á léamh: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Earráid agus comhad '%s' á léamh: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Earráid agus comhad á scríobh: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Earráid agus comhad '%s' á léamh: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Cineál anaithnid" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Earráid agus comhadlann '%s' á oscailt: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Earráid agus comhadlann á cruthú: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Earráid agus comhad '%s' á oscailt: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Earráid agus comhad '%s' á léamh: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Earráid agus comhad '%s' á léamh: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Earráid agus comhad á dhúnadh: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Earráid agus comhad '%s' á oscailt: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Earráid agus comhad '%s' á oscailt: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Earráid agus comhad á scríobh: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Ní thaicaítear leis na URIanna" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Earráid agus comhad á scríobh: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Earráid ar líne %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Earráid agus rogha %s á pharsáil" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Earráid agus á nasc: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:646 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Earráid agus rogha %s á pharsáil" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Earráid agus ag glacadh leis an gceangal: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Earráid agus comhadlann '%s' á oscailt: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "réad truaillithe" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Gan ainm" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Ní thaicaítear leis na URIanna" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Earráid agus comhad á oscailt: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Ní thaicaítear leis na URIanna" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Ainm comhaid %s neamhbhailí" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Earráid agus eolas chóras comhad á fháil: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Earráid agus comhad á athainmniú: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Ainm comhaid neamhbhailí" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Earráid agus comhad á oscailt: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Earráid agus comhad á bhaint: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "Earráid agus comhad á chur sa bhruscar: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Ní féidir comhadlann bhruscair %s a chruthú: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Ní féidir comhad eolas bruscair a chruthú: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Ní féidir comhad a chur sa bhruscar: %s" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "Earráid agus comhadlann á cruthú: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Theip ar léamh nasc siombalach '%s': %s" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Earráid agus nasc siombalach á dhéanamh: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Earráid agus comhad á bhogadh: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "Earráid agus spriocchomhad á bhaint: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Earráid agus tréith bhreisithe '%s' á shocrú: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "Earráid agus staid chomhaid '%s' á fáil: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (ionchódú neamhbhailí)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "Earráid agus staid tuairisceora comhaid á fáil: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Earráid agus ceadanna á socrú: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Earráid agus ceadanna á socrú: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "Earráid agus úinéir á shocrú: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "ní mór an nasc siombalach bheith neamh-NULL" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Earráid agus nasc siombalach á shocrú: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Earráid agus am athraithe nó rochtana á shocrú: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Earráid agus comhthéacs SELinux á shocrú: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Earráid agus comhad á léamh: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Earráid agus ag cuardach i gcomhad: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Earráid agus comhad á dhúnadh: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Earráid agus comhad á scríobh: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Earráid agus sean-nasc cúltaca á bhaint: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Earráid agus cóip cúltaca á chruthú: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Earráid agus comhad sealadach á athainmniú: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "Earráid agus comhad á theascadh: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Earráid agus comhad '%s' á oscailt: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "Earráid agus seanchomhad á bhaint: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Iarratas cuardaigh neamhbhailí" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "Earráid agus '%s' á réiteach: %s" + +#: ../gio/gresolver.c:829 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Earráid agus '%s' á réiteach aisiompaithe: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, c-format +msgid "Error resolving '%s'" +msgstr "Earráid agus '%s' á réiteach" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Rogha anaithnid %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "GSocket á chruthú ó fd: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ní féidir soicéad a chruthú: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, c-format +msgid "Error binding to address: %s" +msgstr "Earráid agus á cheangal le seoladh: %s" + +#: ../gio/gsocket.c:1566 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Earráid agus ag glacadh leis an gceangal: %s" + +#: ../gio/gsocket.c:1683 +msgid "Error connecting: " +msgstr "Earráid agus á nasc: " + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, c-format +msgid "Error connecting: %s" +msgstr "Earráid agus á nasc: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "Ní féidir earráid ar feitheamh a fháil: %s" + +#: ../gio/gsocket.c:1875 +#, c-format +msgid "Error receiving data: %s" +msgstr "Earráid agus sonraí á bhfáil: %s" + +#: ../gio/gsocket.c:2050 +#, c-format +msgid "Error sending data: %s" +msgstr "Earráid agus sonraí á seoladh: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ní féidir soicéad a chruthú: %s" + +#: ../gio/gsocket.c:2242 +#, c-format +msgid "Error closing socket: %s" +msgstr "Earráid agus soicéad á dhúnadh: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, c-format +msgid "Error sending message: %s" +msgstr "Earráid agus teachtaireacht á seoladh: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, c-format +msgid "Error receiving message: %s" +msgstr "Earráid agus teachtaireacht á fáil: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "Earráid anaithnid ag am naisc" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Earráid agus sonraí á seoladh: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Earráid agus comhad á athainmniú: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "Earráid agus unix á léamh: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "Earráid agus unix á dhúnadh: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "Fréamh an chóras comhad" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "Earráid agus unix á scríobh: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "Ní féidir feidhmchlár a aimsiú" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "Earráid agus feidhmchlár á thosú: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "Ní thaicaítear leis na URIanna" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Earráid agus comhad á léamh: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Earráid agus comhad á dhúnadh: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Earráid agus comhad á scríobh: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "cuimhne ídithe" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "earráid inmheánach" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Óstainm neamhbhailí" + +msgctxt "full month name with day" +msgid "January" +msgstr "Eanáir" + +msgctxt "full month name with day" +msgid "February" +msgstr "Feabhra" + +msgctxt "full month name with day" +msgid "March" +msgstr "Márta" + +msgctxt "full month name with day" +msgid "April" +msgstr "Aibreán" + +msgctxt "full month name with day" +msgid "May" +msgstr "Bealtaine" + +msgctxt "full month name with day" +msgid "June" +msgstr "Meitheamh" + +msgctxt "full month name with day" +msgid "July" +msgstr "Iúil" + +msgctxt "full month name with day" +msgid "August" +msgstr "Lúnasa" + +msgctxt "full month name with day" +msgid "September" +msgstr "Meán Fómhair" + +msgctxt "full month name with day" +msgid "October" +msgstr "Deireadh Fómhair" + +msgctxt "full month name with day" +msgid "November" +msgstr "Samhain" + +msgctxt "full month name with day" +msgid "December" +msgstr "Nollaig" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Ean" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feabh" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Márta" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Aib" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Beal" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Meith" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Iúil" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Lún" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "MFómh" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "DFómh" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Samh" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Noll" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "am" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" + +#, fuzzy +#~ msgid "Failed to set value\n" +#~ msgstr "theip ar fháil cuimhne" diff --git a/po/gd.po b/po/gd.po new file mode 100644 index 0000000..f023cee --- /dev/null +++ b/po/gd.po @@ -0,0 +1,5457 @@ +# Scottish Gaelic translation for glib. +# Copyright (C) 2015 glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the glib package. +# GunChleoc , 2015, 2018. +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=glib&" +"keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-09-11 18:30+0000\n" +"PO-Revision-Date: 2018-03-01 10:36+0100\n" +"Last-Translator: GunChleoc \n" +"Language-Team: Fòram na Gàidhlig\n" +"Language: gd\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : " +"(n > 2 && n < 20) ? 2 : 3;\n" +"X-Generator: Virtaal 0.7.1\n" +"X-Project-Style: gnome\n" + +#: ../gio/gapplication.c:490 +msgid "GApplication options" +msgstr "Roghainnean GApplication" + +#: ../gio/gapplication.c:490 +msgid "Show GApplication options" +msgstr "Seall roghainnean GApplication" + +#: ../gio/gapplication.c:535 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Rach a-steach dha mhodh frithealaidh GApplication (cleachd o fhaidhlichean " +"seirbheis D-Bus)" + +#: ../gio/gapplication.c:547 +#| msgid "List applications" +msgid "Override the application’s ID" +msgstr "Tar-àithn ID na h-aplacaid" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gio-tool.c:227 ../gio/gresource-tool.c:488 +#: ../gio/gsettings-tool.c:522 +msgid "Print help" +msgstr "Seall a’ chobhair" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:489 +#: ../gio/gresource-tool.c:557 +msgid "[COMMAND]" +msgstr "[ÀITHNE]" + +#: ../gio/gapplication-tool.c:49 ../gio/gio-tool.c:228 +msgid "Print version" +msgstr "Seall an tionndadh" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:528 +msgid "Print version information and exit" +msgstr "Seall fiosrachadh an tionndaidh is fàg an-seo" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Seall liosta dhe na h-aplacaidean" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Seall liosta dhe na h-aplacaidean D-Bus air an stàladh a ghabhas " +"gnìomhachadh (le faidhlichean .desktop)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "Tòisich aplacaid" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "Tòisich an aplacaid (le faidhlichean roghainneil ri am fosgladh)" + +#: ../gio/gapplication-tool.c:57 +#| msgid "APPID [FILE...]" +msgid "APPID [FILE…]" +msgstr "ID-APLACAIDE [FAIDHLE…]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "Gnìomhaich gnìomh" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "Dèan gnìomh air an aplacaid" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "ID-APLACAIDE GNÃŒOMH [PARAMADAIR]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Seall liosta dhe na gnìomhan ri am faighinn" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"Seall liosta dhe na gnìomhan stadaigeach airson aplacaid (o fhaidhle ." +"desktop)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "ID-APLACAIDE" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 ../gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "ÀITHNE" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "An t-àithne gus cobhair mhionaideach a shealltainn airson" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Aithnichear na h-aplacaid ann am fòrmat D-Bus (m.e. org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:665 +#: ../gio/glib-compile-resources.c:671 ../gio/glib-compile-resources.c:698 +#: ../gio/gresource-tool.c:495 ../gio/gresource-tool.c:561 +msgid "FILE" +msgstr "FAIDHLE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Ainmean-faidhle absaloideach no dàimheach no URIean ris am fosgladh gu " +"roghainneil" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "GNÃŒOMH" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "Ainm a’ ghnìomh ri dhèanamh" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARAMADAIR" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" +"Paramadair roghainneil airson dèanamh a' ghnìomha, ann am fòrmat GVariant" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:526 +#: ../gio/gsettings-tool.c:614 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Àithne nach aithne dhuinn %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "Cleachdadh:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:551 +#: ../gio/gsettings-tool.c:649 +msgid "Arguments:\n" +msgstr "Argamaidean:\n" + +#: ../gio/gapplication-tool.c:133 +#| msgid "[ARGS...]" +msgid "[ARGS…]" +msgstr "[ARGAMAIDEAN…]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Àitheantan:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +#| msgid "" +#| "Use '%s help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Cleachd “%s help ÀITHNE†gus cobhair mhionaideach fhaighinn.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"feumaidh id aplacaide leantainn ris an àithne %s\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +#| msgid "invalid application id: '%s'\n" +msgid "invalid application id: “%sâ€\n" +msgstr "id aplacaide mì-dhligheach: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +#| msgid "" +#| "'%s' takes no arguments\n" +#| "\n" +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"cha ghabh “%s†ri argamaid\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "cha deach leinn ceangal ri D-Bus: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "mearachd a' cur teachdaireachd %s gu aplacaid: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "feumaidh tu ainm a’ ghnìomh a thoirt seachad às dèidh id na h-aplacaide\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +#| msgid "" +#| "invalid action name: '%s'\n" +#| "action names must consist of only alphanumerics, '-' and '.'\n" +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"ainm gnìomha mì-dhligheach: “%sâ€\n" +"chan fhaod ach litrichean gun sràcan is àireamhan, “-†agus “.†a bhith ann " +"an ainm gnìomha\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "cha deach leinn paramadair gnìomha a pharsadh: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "cha ghabh gnìomhan ach ri aon pharamadair air a char as motha\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "cha ghabh an àithne list-actions ach ri is na h-aplacaide" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "cha deach leinn faidhle desktop a lorg airson aplacaid %s\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"àithne nach aithne dhuinn: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:179 ../gio/ginputstream.c:379 +#: ../gio/ginputstream.c:617 ../gio/ginputstream.c:1019 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:834 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Chaidh luach cunntaidh ro mhòr a chur gu %s" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Chan eil taic ri sireadh air bun-shruth" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1208 +#: ../gio/giostream.c:300 ../gio/goutputstream.c:1660 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1849 +#: ../gio/gdbusprivate.c:1402 ../gio/gsimpleasyncresult.c:870 +#: ../gio/gsimpleasyncresult.c:896 +#, c-format +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1257 ../glib/gconvert.c:438 ../glib/gconvert.c:845 +#: ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:866 ../glib/gutf8.c:1319 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 ../glib/gconvert.c:770 +#: ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "" + +#: ../gio/gcharsetconverter.c:445 ../gio/gsocket.c:1096 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcharsetconverter.c:456 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "" + +#: ../gio/gcharsetconverter.c:460 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "" + +#: ../gio/gcontenttype.c:358 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcontenttype-win32.c:177 +msgid "Unknown type" +msgstr "" + +#: ../gio/gcontenttype-win32.c:179 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:155 ../gio/gdbusaddress.c:243 +#: ../gio/gdbusaddress.c:324 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:195 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:258 ../gio/gdbusaddress.c:339 +#, c-format +msgid "Error in address “%s†— the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:269 ../gio/gdbusaddress.c:350 +#, c-format +msgid "Error in address “%s†— the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:460 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:573 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:658 +msgid "Error auto-launching: " +msgstr "" + +#: ../gio/gdbusaddress.c:666 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:704 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:723 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:732 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" + +#: ../gio/gdbusaddress.c:750 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" + +#: ../gio/gdbusaddress.c:959 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1072 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "" + +#: ../gio/gdbusaddress.c:1079 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1086 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: ../gio/gdbusaddress.c:1128 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "" + +#: ../gio/gdbusaddress.c:1345 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: ../gio/gdbusaddress.c:1499 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: ../gio/gdbusaddress.c:1510 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1648 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" + +#: ../gio/gdbusaddress.c:1657 ../gio/gdbusconnection.c:7155 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1667 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1174 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:262 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:274 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:296 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:379 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:403 ../gio/gdbusauthmechanismsha1.c:721 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:417 ../gio/gdbusauthmechanismsha1.c:735 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:432 ../gio/gdbusauthmechanismsha1.c:749 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:456 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:569 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:600 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:611 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:688 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:885 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2378 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1879 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2500 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:4124 ../gio/gdbusconnection.c:4471 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4266 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4278 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:4289 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4309 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4414 ../gio/gdbusconnection.c:4622 +#: ../gio/gdbusconnection.c:6586 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4840 ../gio/gdbusconnection.c:7095 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4938 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4969 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5167 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:5393 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "" + +#: ../gio/gdbusconnection.c:5449 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "" + +#: ../gio/gdbusconnection.c:5625 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:6697 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6818 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusconnection.c:7146 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" + +#: ../gio/gdbusmessage.c:3285 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "" + +#: ../gio/gdbusmessage.c:3293 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:2066 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "" + +#: ../gio/gdbusprivate.c:2111 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1611 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1634 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2719 ../gio/gdbusproxy.c:2853 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:876 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "" + +#: ../gio/gdbusserver.c:1047 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1087 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:165 ../gio/gdbus-tool.c:227 ../gio/gdbus-tool.c:299 +#: ../gio/gdbus-tool.c:323 ../gio/gdbus-tool.c:725 ../gio/gdbus-tool.c:1068 +#: ../gio/gdbus-tool.c:1510 +#, c-format +msgid "Error: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:176 ../gio/gdbus-tool.c:240 ../gio/gdbus-tool.c:1526 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:209 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:357 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:358 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:359 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:369 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:370 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:392 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:402 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:481 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" + +#: ../gio/gdbus-tool.c:543 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:544 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:545 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:579 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:613 ../gio/gdbus-tool.c:858 ../gio/gdbus-tool.c:1616 +#: ../gio/gdbus-tool.c:1851 ../gio/gdbus-tool.c:2067 +#, c-format +msgid "Error connecting: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:630 ../gio/gdbus-tool.c:925 ../gio/gdbus-tool.c:1681 +#: ../gio/gdbus-tool.c:1917 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:636 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:643 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:651 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:657 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:663 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:700 ../gio/gdbus-tool.c:1037 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:732 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:759 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:760 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:761 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:762 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:803 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:878 ../gio/gdbus-tool.c:1635 ../gio/gdbus-tool.c:1870 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:890 ../gio/gdbus-tool.c:1652 ../gio/gdbus-tool.c:1882 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:905 ../gio/gdbus-tool.c:1661 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:940 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:951 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:1029 +#, c-format +#| msgid "error parsing action parameter: %s\n" +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Mearachd le parsadh paramadair %d dhen t-seòrsa “%sâ€: %s\n" + +#: ../gio/gdbus-tool.c:1473 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1474 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1475 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1476 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1477 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1568 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1773 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1774 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1803 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1980 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: ../gio/gdbus-tool.c:1983 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: ../gio/gdbus-tool.c:2031 +msgid "[OPTION…] BUS-NAME" +msgstr "" + +#: ../gio/gdbus-tool.c:2033 +msgid "Wait for a bus name to appear." +msgstr "" + +#: ../gio/gdbus-tool.c:2109 +#, c-format +msgid "Error: A service to activate for must be specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:2114 +#, c-format +msgid "Error: A service to wait for must be specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:2119 +#, c-format +msgid "Error: Too many arguments.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:2127 ../gio/gdbus-tool.c:2134 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4531 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2411 +msgid "Desktop file didn’t specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2694 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3127 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3131 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3371 ../gio/gdesktopappinfo.c:3395 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3763 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:776 +msgid "drive doesn’t implement start" +msgstr "" + +#: ../gio/gdrive.c:878 +msgid "drive doesn’t implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:195 ../gio/gdummytlsbackend.c:317 +#: ../gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:969 ../gio/gfile.c:1207 ../gio/gfile.c:1345 +#: ../gio/gfile.c:1583 ../gio/gfile.c:1638 ../gio/gfile.c:1696 +#: ../gio/gfile.c:1780 ../gio/gfile.c:1837 ../gio/gfile.c:1901 +#: ../gio/gfile.c:1956 ../gio/gfile.c:3602 ../gio/gfile.c:3657 +#: ../gio/gfile.c:3893 ../gio/gfile.c:3935 ../gio/gfile.c:4403 +#: ../gio/gfile.c:4814 ../gio/gfile.c:4899 ../gio/gfile.c:4989 +#: ../gio/gfile.c:5086 ../gio/gfile.c:5173 ../gio/gfile.c:5274 +#: ../gio/gfile.c:7815 ../gio/gfile.c:7905 ../gio/gfile.c:7989 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: ../gio/gfile.c:1468 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2515 ../gio/glocalfile.c:2377 +msgid "Can’t copy over directory" +msgstr "" + +#: ../gio/gfile.c:2575 +msgid "Can’t copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2583 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2602 +msgid "Can’t recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2877 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2881 +#, c-format +msgid "Error splicing file: %s" +msgstr "" + +#: ../gio/gfile.c:3013 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" + +#: ../gio/gfile.c:3017 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: ../gio/gfile.c:3022 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" + +#: ../gio/gfile.c:3085 +msgid "Can’t copy special file" +msgstr "" + +#: ../gio/gfile.c:3883 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:4044 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:4156 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "" + +#: ../gio/gfile.c:6602 ../gio/gvolume.c:363 +msgid "volume doesn’t implement mount" +msgstr "" + +#: ../gio/gfile.c:6711 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/ghttpproxy.c:91 ../gio/gresolver.c:410 ../gio/gresolver.c:476 +#: ../glib/gconvert.c:1650 +msgid "Invalid hostname" +msgstr "Ainm òstair mì-dhligheach" + +#: ../gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "" + +#: ../gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "" + +#: ../gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "" + +#: ../gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "" + +#: ../gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "" + +#: ../gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:461 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "" + +#: ../gio/ginetsocketaddress.c:203 ../gio/ginetsocketaddress.c:220 +#: ../gio/gnativesocketaddress.c:106 ../gio/gunixsocketaddress.c:218 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1218 ../gio/giostream.c:310 +#: ../gio/goutputstream.c:1670 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "" + +#: ../gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "" + +#: ../gio/gio-tool.c:205 +#| msgid "" +#| "'%s' takes no arguments\n" +#| "\n" +msgid "“version†takes no arguments" +msgstr "cha ghabh “version†ri argamaid" + +#: ../gio/gio-tool.c:207 ../gio/gio-tool.c:223 ../glib/goption.c:857 +msgid "Usage:" +msgstr "" + +#: ../gio/gio-tool.c:210 +#| msgid "Print version information and exit" +msgid "Print version information and exit." +msgstr "Seall fiosrachadh an tionndaidh is fàg an-seo." + +#: ../gio/gio-tool.c:224 +msgid "[ARGS...]" +msgstr "[ARGAMAIDEAN…]" + +#: ../gio/gio-tool.c:226 +#| msgid "Commands:\n" +msgid "Commands:" +msgstr "Àitheantan:" + +#: ../gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: ../gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "" + +#: ../gio/gio-tool.c:231 +#| msgid "Show GApplication options" +msgid "Show information about locations" +msgstr "Seall fiosrachadh air na h-ionadan" + +#: ../gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "" + +#: ../gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: ../gio/gio-tool.c:234 +msgid "Create directories" +msgstr "" + +#: ../gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "" + +#: ../gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "" + +#: ../gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "" + +#: ../gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "" + +#: ../gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "" + +#: ../gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "" + +#: ../gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "" + +#: ../gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "" + +#: ../gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "" + +#: ../gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: ../gio/gio-tool.c:246 +#, c-format +#| msgid "" +#| "Use '%s help COMMAND' to get detailed help.\n" +#| "\n" +msgid "Use %s to get detailed help.\n" +msgstr "" +"Cleachd %s gus cobhair mhionaideach fhaighinn.\n" +"\n" + +#: ../gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-cat.c:133 ../gio/gio-tool-info.c:282 +#: ../gio/gio-tool-list.c:165 ../gio/gio-tool-mkdir.c:48 +#: ../gio/gio-tool-monitor.c:37 ../gio/gio-tool-monitor.c:39 +#: ../gio/gio-tool-monitor.c:41 ../gio/gio-tool-monitor.c:43 +#: ../gio/gio-tool-monitor.c:203 ../gio/gio-tool-mount.c:1141 +#: ../gio/gio-tool-open.c:45 ../gio/gio-tool-remove.c:48 +#: ../gio/gio-tool-rename.c:45 ../gio/gio-tool-set.c:89 +#: ../gio/gio-tool-trash.c:81 ../gio/gio-tool-tree.c:239 +#| msgid "ACTION" +msgid "LOCATION" +msgstr "IONAD" + +#: ../gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" + +#: ../gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: ../gio/gio-tool-cat.c:162 ../gio/gio-tool-info.c:313 +#: ../gio/gio-tool-mkdir.c:76 ../gio/gio-tool-monitor.c:228 +#: ../gio/gio-tool-open.c:71 ../gio/gio-tool-remove.c:72 +msgid "No locations given" +msgstr "" + +#: ../gio/gio-tool-copy.c:42 ../gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "" + +#: ../gio/gio-tool-copy.c:43 ../gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "" + +#: ../gio/gio-tool-copy.c:44 ../gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "" + +#: ../gio/gio-tool-copy.c:45 +msgid "Preserve all attributes" +msgstr "" + +#: ../gio/gio-tool-copy.c:46 ../gio/gio-tool-move.c:41 +#: ../gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "" + +#: ../gio/gio-tool-copy.c:47 +msgid "Never follow symbolic links" +msgstr "" + +#: ../gio/gio-tool-copy.c:72 ../gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +#: ../gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "" + +#: ../gio/gio-tool-copy.c:103 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" + +#: ../gio/gio-tool-copy.c:105 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: ../gio/gio-tool-copy.c:147 +#, c-format +msgid "Destination %s is not a directory" +msgstr "" + +#: ../gio/gio-tool-copy.c:192 ../gio/gio-tool-move.c:185 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "" + +#: ../gio/gio-tool-info.c:34 +#| msgid "List available actions" +msgid "List writable attributes" +msgstr "Seall liosta dhe na buaidhean a ghabhas sgrìobhadh" + +#: ../gio/gio-tool-info.c:35 +msgid "Get file system info" +msgstr "" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "The attributes to get" +msgstr "" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "ATTRIBUTES" +msgstr "" + +#: ../gio/gio-tool-info.c:37 ../gio/gio-tool-list.c:38 ../gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "" + +#: ../gio/gio-tool-info.c:75 +#, c-format +msgid "attributes:\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:138 +#, c-format +msgid "name: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:151 +#, c-format +msgid "size: " +msgstr "" + +#: ../gio/gio-tool-info.c:156 +#, c-format +msgid "hidden\n" +msgstr "" + +#: ../gio/gio-tool-info.c:159 +#, c-format +msgid "uri: %s\n" +msgstr "" + +#: ../gio/gio-tool-info.c:228 +#, c-format +msgid "Settable attributes:\n" +msgstr "" + +#: ../gio/gio-tool-info.c:252 +#, c-format +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: ../gio/gio-tool-info.c:287 +#| msgid "Show GApplication options" +msgid "Show information about locations." +msgstr "Seall fiosrachadh air na h-ionadan." + +#: ../gio/gio-tool-info.c:289 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#: ../gio/gio-tool-list.c:36 ../gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "" + +#: ../gio/gio-tool-list.c:37 +msgid "Use a long listing format" +msgstr "" + +#: ../gio/gio-tool-list.c:39 +msgid "Print full URIs" +msgstr "" + +#: ../gio/gio-tool-list.c:170 +msgid "List the contents of the locations." +msgstr "" + +#: ../gio/gio-tool-list.c:172 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: ../gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: ../gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: ../gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: ../gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: ../gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "" + +#: ../gio/gio-tool-mime.c:122 +#, c-format +#| msgid "invalid application id: '%s'\n" +msgid "Default application for “%sâ€: %s\n" +msgstr "An aplacaid thùsail airson “%sâ€: %s\n" + +#: ../gio/gio-tool-mime.c:127 +#, c-format +#| msgid "List applications" +msgid "Registered applications:\n" +msgstr "Na h-aplacaidean clàraichte:\n" + +#: ../gio/gio-tool-mime.c:129 +#, c-format +#| msgid "List applications" +msgid "No registered applications\n" +msgstr "Chan eil aplacaid chlàraichte ann\n" + +#: ../gio/gio-tool-mime.c:140 +#, c-format +#| msgid "List applications" +msgid "Recommended applications:\n" +msgstr "Aplacaidean a mholamaid:\n" + +#: ../gio/gio-tool-mime.c:142 +#, c-format +msgid "No recommended applications\n" +msgstr "Chan eil aplacaid a mholamaid ann\n" + +#: ../gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "" + +#: ../gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" + +#: ../gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "" + +#: ../gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "" + +#: ../gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: ../gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: ../gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: ../gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: ../gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: ../gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "" + +#: ../gio/gio-tool-mount.c:58 +msgid "Mount as mountable" +msgstr "" + +#: ../gio/gio-tool-mount.c:59 +msgid "Mount volume with device file" +msgstr "" + +#: ../gio/gio-tool-mount.c:59 +msgid "DEVICE" +msgstr "" + +#: ../gio/gio-tool-mount.c:60 +msgid "Unmount" +msgstr "" + +#: ../gio/gio-tool-mount.c:61 +msgid "Eject" +msgstr "" + +#: ../gio/gio-tool-mount.c:62 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: ../gio/gio-tool-mount.c:62 +msgid "SCHEME" +msgstr "" + +#: ../gio/gio-tool-mount.c:63 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: ../gio/gio-tool-mount.c:64 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: ../gio/gio-tool-mount.c:66 +msgid "List" +msgstr "" + +#: ../gio/gio-tool-mount.c:67 +msgid "Monitor events" +msgstr "" + +#: ../gio/gio-tool-mount.c:68 +msgid "Show extra information" +msgstr "" + +#: ../gio/gio-tool-mount.c:246 ../gio/gio-tool-mount.c:276 +msgid "Anonymous access denied" +msgstr "" + +#: ../gio/gio-tool-mount.c:897 +#, c-format +msgid "Mounted %s at %s\n" +msgstr "" + +#: ../gio/gio-tool-mount.c:950 +msgid "No volume for device file" +msgstr "" + +#: ../gio/gio-tool-mount.c:1145 +msgid "Mount or unmount the locations." +msgstr "" + +#: ../gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: ../gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: ../gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: ../gio/gio-tool-move.c:142 +#, c-format +msgid "Target %s is not a directory" +msgstr "" + +#: ../gio/gio-tool-open.c:50 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: ../gio/gio-tool-remove.c:31 ../gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: ../gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "" + +#: ../gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "" + +#: ../gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "" + +#: ../gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "" + +#: ../gio/gio-tool-rename.c:76 ../gio/gio-tool-save.c:190 +#: ../gio/gio-tool-set.c:137 +#| msgid "" +#| "'%s' takes no arguments\n" +#| "\n" +msgid "Too many arguments" +msgstr "Tha cus argamaidean ann" + +#: ../gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: ../gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "" + +#: ../gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "" + +#: ../gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: ../gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: ../gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "" + +#: ../gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:139 +#, c-format +msgid "Etag not available\n" +msgstr "" + +#: ../gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: ../gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "" + +#: ../gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "" + +#: ../gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "" + +#: ../gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "" + +#: ../gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "" + +#: ../gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "" + +#: ../gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "" + +#: ../gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "" + +#: ../gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "" + +#: ../gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "" + +#: ../gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "" + +#: ../gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "" + +#: ../gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" + +#: ../gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1501 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-resources.c:237 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:248 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "" + +#: ../gio/glib-compile-resources.c:259 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "" + +#: ../gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "" + +#: ../gio/glib-compile-resources.c:308 ../gio/glib-compile-resources.c:354 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:382 +#, c-format +msgid "Error reading file %s: %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:402 +#, c-format +msgid "Error compressing file %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:469 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:664 ../gio/glib-compile-schemas.c:2067 +msgid "Show program version and exit" +msgstr "" + +#: ../gio/glib-compile-resources.c:665 +msgid "name of the output file" +msgstr "" + +#: ../gio/glib-compile-resources.c:666 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" + +#: ../gio/glib-compile-resources.c:666 ../gio/glib-compile-schemas.c:2068 +#: ../gio/glib-compile-schemas.c:2096 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-resources.c:667 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: ../gio/glib-compile-resources.c:668 +msgid "Generate source header" +msgstr "" + +#: ../gio/glib-compile-resources.c:669 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" + +#: ../gio/glib-compile-resources.c:670 +msgid "Generate dependency list" +msgstr "" + +#: ../gio/glib-compile-resources.c:671 +msgid "name of the dependency file to generate" +msgstr "" + +#: ../gio/glib-compile-resources.c:672 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: ../gio/glib-compile-resources.c:673 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:674 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: ../gio/glib-compile-resources.c:675 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: ../gio/glib-compile-resources.c:701 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: ../gio/glib-compile-resources.c:723 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:95 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: ../gio/glib-compile-schemas.c:106 +#, c-format +msgid "Invalid numeric value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:114 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:122 +#, c-format +msgid "value='%s' already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:136 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: ../gio/glib-compile-schemas.c:161 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: ../gio/glib-compile-schemas.c:315 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "" + +#: ../gio/glib-compile-schemas.c:327 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:333 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:339 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:373 +msgid " already specified for this key" +msgstr "" + +#: ../gio/glib-compile-schemas.c:391 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:408 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: ../gio/glib-compile-schemas.c:433 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: ../gio/glib-compile-schemas.c:441 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: ../gio/glib-compile-schemas.c:453 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: ../gio/glib-compile-schemas.c:475 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:492 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:501 +msgid " already specified for this key" +msgstr "" + +#: ../gio/glib-compile-schemas.c:513 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:529 +#, c-format +msgid " already given" +msgstr "" + +#: ../gio/glib-compile-schemas.c:544 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: ../gio/glib-compile-schemas.c:558 +msgid " already specified for this key" +msgstr "" + +#: ../gio/glib-compile-schemas.c:562 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: ../gio/glib-compile-schemas.c:581 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:587 +#, c-format +msgid " given when was already given" +msgstr "" + +#: ../gio/glib-compile-schemas.c:595 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:606 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:621 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: ../gio/glib-compile-schemas.c:786 +msgid "Empty names are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:796 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:808 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:817 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" + +#: ../gio/glib-compile-schemas.c:834 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:904 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:930 +msgid "Cannot add keys to a “list-of†schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:941 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:959 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:970 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1004 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1034 +msgid " given but schema isn’t extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1047 +#, c-format +msgid "No to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1055 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1128 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1140 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1156 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1164 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1174 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1184 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1211 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1218 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1227 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1257 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1407 ../gio/glib-compile-schemas.c:1423 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1505 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1523 +msgid "Element is required in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1613 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1681 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1820 ../gio/glib-compile-schemas.c:1894 +#: ../gio/glib-compile-schemas.c:1970 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1830 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1930 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1936 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2022 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 ../gio/glib-compile-schemas.c:1998 +#: ../gio/glib-compile-schemas.c:2026 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1966 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1984 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2012 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2068 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2069 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2070 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2071 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2099 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:2120 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2162 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2165 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2168 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocalfile.c:643 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "" + +#: ../gio/glocalfile.c:1037 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: ../gio/glocalfile.c:1176 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "" + +#: ../gio/glocalfile.c:1199 +msgid "Can’t rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1217 ../gio/glocalfile.c:1240 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1224 +msgid "Can’t rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1237 ../gio/glocalfile.c:2253 ../gio/glocalfile.c:2281 +#: ../gio/glocalfile.c:2438 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "" + +#: ../gio/glocalfile.c:1404 ../gio/glocalfile.c:1419 +#, c-format +msgid "Error opening file %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1544 +#, c-format +msgid "Error removing file %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1928 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1951 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1971 +#, c-format +#| msgid "unable to find desktop file for application %s\n" +msgid "Unable to find toplevel directory to trash %s" +msgstr "Cha do lorg sinn pasgan freumha gus %s a chur dhan sgudal" + +#: ../gio/glocalfile.c:2050 ../gio/glocalfile.c:2070 +#, c-format +msgid "Unable to find or create trash directory for %s" +msgstr "" + +#: ../gio/glocalfile.c:2105 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:2164 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" + +#: ../gio/glocalfile.c:2168 ../gio/glocalfile.c:2224 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:2230 +#, c-format +msgid "Unable to trash file %s" +msgstr "" + +#: ../gio/glocalfile.c:2256 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:2285 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "" + +#: ../gio/glocalfile.c:2288 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:2294 ../glib/gfileutils.c:2077 +msgid "Symbolic links not supported" +msgstr "" + +#: ../gio/glocalfile.c:2349 ../gio/glocalfile.c:2384 ../gio/glocalfile.c:2441 +#, c-format +msgid "Error moving file %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:2372 +msgid "Can’t move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2398 ../gio/glocalfileoutputstream.c:933 +#: ../gio/glocalfileoutputstream.c:947 ../gio/glocalfileoutputstream.c:962 +#: ../gio/glocalfileoutputstream.c:979 ../gio/glocalfileoutputstream.c:993 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2417 +#, c-format +msgid "Error removing target file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2431 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfile.c:2622 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:731 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:738 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:745 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:785 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1586 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1777 ../gio/glocalfileoutputstream.c:811 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2028 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2073 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2091 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2110 ../gio/glocalfileinfo.c:2129 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2164 +msgid "Cannot set permissions on symlinks" +msgstr "" + +#: ../gio/glocalfileinfo.c:2180 +#, c-format +msgid "Error setting permissions: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2231 +#, c-format +msgid "Error setting owner: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2254 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2264 ../gio/glocalfileinfo.c:2283 +#: ../gio/glocalfileinfo.c:2294 +#, c-format +msgid "Error setting symlink: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2273 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2399 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2422 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2437 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2444 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2536 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1011 +#, c-format +msgid "Error seeking in file: %s" +msgstr "" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "" + +#: ../gio/glocalfilemonitor.c:840 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1062 +#, c-format +msgid "Error truncating file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:793 +#: ../gio/glocalfileoutputstream.c:1043 ../gio/gsubprocess.c:380 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:824 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:829 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:841 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1027 +#, c-format +msgid "Error removing old file: %s" +msgstr "" + +#: ../gio/gmemoryinputstream.c:474 ../gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "" + +#: ../gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn’t implement “unmountâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn’t implement “ejectâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn’t implement “remountâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn’t implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:378 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "" + +#: ../gio/gnetworkmonitorbase.c:206 ../gio/gnetworkmonitorbase.c:310 +msgid "Network unreachable" +msgstr "" + +#: ../gio/gnetworkmonitorbase.c:244 ../gio/gnetworkmonitorbase.c:274 +msgid "Host unreachable" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "" + +#: ../gio/gnetworkmonitornm.c:329 +#, c-format +msgid "NetworkManager version too old" +msgstr "" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:560 +msgid "Output stream doesn’t implement write" +msgstr "" + +#: ../gio/goutputstream.c:521 ../gio/goutputstream.c:1224 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:342 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "" + +#: ../gio/gresource.c:606 ../gio/gresource.c:857 ../gio/gresource.c:874 +#: ../gio/gresource.c:998 ../gio/gresource.c:1070 ../gio/gresource.c:1143 +#: ../gio/gresource.c:1213 ../gio/gresourcefile.c:453 +#: ../gio/gresourcefile.c:576 ../gio/gresourcefile.c:713 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "" + +#: ../gio/gresource.c:771 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "" + +#: ../gio/gresourcefile.c:709 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "" + +#: ../gio/gresourcefile.c:917 +msgid "Input stream doesn’t implement seek" +msgstr "" + +#: ../gio/gresource-tool.c:494 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: ../gio/gresource-tool.c:500 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: ../gio/gresource-tool.c:503 ../gio/gresource-tool.c:513 +msgid "FILE [PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:504 ../gio/gresource-tool.c:514 +#: ../gio/gresource-tool.c:521 +msgid "SECTION" +msgstr "" + +#: ../gio/gresource-tool.c:509 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: ../gio/gresource-tool.c:519 +msgid "Extract a resource file to stdout" +msgstr "" + +#: ../gio/gresource-tool.c:520 +msgid "FILE PATH" +msgstr "" + +#: ../gio/gresource-tool.c:534 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:548 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:555 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: ../gio/gresource-tool.c:559 ../gio/gsettings-tool.c:656 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gresource-tool.c:565 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: ../gio/gresource-tool.c:568 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: ../gio/gresource-tool.c:572 +msgid "[PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:574 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: ../gio/gresource-tool.c:575 +msgid "PATH" +msgstr "" + +#: ../gio/gresource-tool.c:577 +msgid " PATH A resource path\n" +msgstr "" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#: ../gio/gsettings-tool.c:853 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:491 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:498 +#, c-format +msgid "The key is not writable\n" +msgstr "" + +#: ../gio/gsettings-tool.c:534 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:540 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:546 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:547 ../gio/gsettings-tool.c:553 +#: ../gio/gsettings-tool.c:596 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:552 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:558 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:560 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:566 ../gio/gsettings-tool.c:572 +#: ../gio/gsettings-tool.c:578 ../gio/gsettings-tool.c:590 +#: ../gio/gsettings-tool.c:602 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:577 +msgid "Query the description for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:584 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:589 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:595 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:601 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:607 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:610 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:622 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:646 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:660 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:673 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:728 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "" + +#: ../gio/gsettings-tool.c:740 +#, c-format +msgid "No schemas installed\n" +msgstr "" + +#: ../gio/gsettings-tool.c:811 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsettings-tool.c:866 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "" + +#: ../gio/gsocket.c:379 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:386 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:394 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:409 ../gio/gsocket.c:2765 ../gio/gsocket.c:3950 +#: ../gio/gsocket.c:4008 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:541 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "" + +#: ../gio/gsocket.c:570 ../gio/gsocket.c:624 ../gio/gsocket.c:631 +#, c-format +msgid "Unable to create socket: %s" +msgstr "" + +#: ../gio/gsocket.c:624 +msgid "Unknown family was specified" +msgstr "" + +#: ../gio/gsocket.c:631 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1122 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: ../gio/gsocket.c:1139 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: ../gio/gsocket.c:1943 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1986 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:2052 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:2151 +#, c-format +msgid "Error binding to address: %s" +msgstr "" + +#: ../gio/gsocket.c:2266 ../gio/gsocket.c:2303 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "" + +#: ../gio/gsocket.c:2267 ../gio/gsocket.c:2304 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "" + +#: ../gio/gsocket.c:2268 +msgid "No support for source-specific multicast" +msgstr "" + +#: ../gio/gsocket.c:2488 +#, c-format +msgid "Error accepting connection: %s" +msgstr "" + +#: ../gio/gsocket.c:2609 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:2658 +msgid "Unable to get pending error: " +msgstr "" + +#: ../gio/gsocket.c:2828 +#, c-format +msgid "Error receiving data: %s" +msgstr "" + +#: ../gio/gsocket.c:3023 +#, c-format +msgid "Error sending data: %s" +msgstr "" + +#: ../gio/gsocket.c:3210 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "" + +#: ../gio/gsocket.c:3291 +#, c-format +msgid "Error closing socket: %s" +msgstr "" + +#: ../gio/gsocket.c:3943 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:4417 ../gio/gsocket.c:4497 ../gio/gsocket.c:4675 +#, c-format +msgid "Error sending message: %s" +msgstr "" + +#: ../gio/gsocket.c:4441 +msgid "GSocketControlMessage not supported on Windows" +msgstr "" + +#: ../gio/gsocket.c:4894 ../gio/gsocket.c:4967 ../gio/gsocket.c:5193 +#, c-format +msgid "Error receiving message: %s" +msgstr "" + +#: ../gio/gsocket.c:5465 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "" + +#: ../gio/gsocket.c:5474 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "" + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "" + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "" + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "" + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "" + +#: ../gio/gthreadedresolver.c:213 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "" + +#: ../gio/gthreadedresolver.c:550 ../gio/gthreadedresolver.c:630 +#: ../gio/gthreadedresolver.c:728 ../gio/gthreadedresolver.c:778 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: ../gio/gthreadedresolver.c:555 ../gio/gthreadedresolver.c:733 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "" + +#: ../gio/gthreadedresolver.c:560 ../gio/gthreadedresolver.c:738 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: ../gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:563 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:575 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "" + +#: ../gio/gunixconnection.c:504 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:520 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixconnection.c:549 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:589 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:614 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:372 ../gio/gunixinputstream.c:393 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:426 ../gio/gunixoutputstream.c:411 +#: ../gio/gwin32inputstream.c:217 ../gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "" + +#: ../gio/gunixmounts.c:2430 ../gio/gunixmounts.c:2483 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:358 ../gio/gunixoutputstream.c:378 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "" + +#: ../gio/gunixsocketaddress.c:241 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:437 +msgid "volume doesn’t implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "" + +#: ../gio/gwin32inputstream.c:232 ../gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "" + +#: ../gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "" + +#: ../glib/gbookmarkfile.c:754 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "" + +#: ../glib/gbookmarkfile.c:765 ../glib/gbookmarkfile.c:836 +#: ../glib/gbookmarkfile.c:846 ../glib/gbookmarkfile.c:953 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1123 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1252 ../glib/gbookmarkfile.c:1262 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1148 ../glib/gbookmarkfile.c:1162 +#: ../glib/gbookmarkfile.c:1230 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:862 ../glib/gutf8.c:1074 +#: ../glib/gutf8.c:1211 ../glib/gutf8.c:1315 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" + +#: ../glib/gconvert.c:1513 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" + +#: ../glib/gconvert.c:1523 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "" + +#: ../glib/gconvert.c:1540 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "" + +#: ../glib/gconvert.c:1552 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "" + +#: ../glib/gconvert.c:1568 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:1640 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %b %e %H:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:208 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:211 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:224 +msgctxt "full month name" +msgid "January" +msgstr "Am Faoilleach" + +#: ../glib/gdatetime.c:226 +msgctxt "full month name" +msgid "February" +msgstr "An Gearran" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "March" +msgstr "Am Màrt" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "April" +msgstr "An Giblean" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "May" +msgstr "An Cèitean" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "June" +msgstr "An t-Ã’gmhios" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "July" +msgstr "An t-Iuchar" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "August" +msgstr "An Lùnastal" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "September" +msgstr "An t-Sultain" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "October" +msgstr "An Dàmhair" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "November" +msgstr "An t-Samhain" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "December" +msgstr "An Dùbhlachd" + +#: ../glib/gdatetime.c:261 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Faoi" + +#: ../glib/gdatetime.c:263 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Gearr" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Màrt" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Gibl" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Cèit" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Ã’gmh" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Iuch" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Lùna" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sult" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Dàmh" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Samh" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dùbh" + +#: ../glib/gdatetime.c:298 +msgctxt "full weekday name" +msgid "Monday" +msgstr "DiLuain" + +#: ../glib/gdatetime.c:300 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "DiMàirt" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "DiCiadain" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "DiarDaoin" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Friday" +msgstr "DihAoine" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "DiSathairne" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "DiDòmhnaich" + +#: ../glib/gdatetime.c:325 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "DiL" + +#: ../glib/gdatetime.c:327 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "DiM" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "DiC" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Dia" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Dih" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "DiS" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "DiD" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:354 +msgctxt "GDateTime" +msgid "AM" +msgstr "m" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:357 +msgctxt "GDateTime" +msgid "PM" +msgstr "f" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "" + +#: ../glib/gfileutils.c:706 ../glib/gfileutils.c:798 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#: ../glib/gfileutils.c:723 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "" + +#: ../glib/gfileutils.c:759 +#, c-format +msgid "File “%s†is too large" +msgstr "" + +#: ../glib/gfileutils.c:823 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "" + +#: ../glib/gfileutils.c:871 ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "" + +#: ../glib/gfileutils.c:883 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:913 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1012 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1047 ../glib/gfileutils.c:1554 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "" + +#: ../glib/gfileutils.c:1074 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1117 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1241 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1520 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "" + +#: ../glib/gfileutils.c:1533 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "" + +#: ../glib/gfileutils.c:2058 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "" + +#: ../glib/giochannel.c:1734 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1925 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gkeyfile.c:736 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:773 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:1218 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:1275 +#, c-format +msgid "Invalid group name: %s" +msgstr "" + +#: ../glib/gkeyfile.c:1297 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Invalid key name: %s" +msgstr "" + +#: ../glib/gkeyfile.c:1350 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "" + +#: ../glib/gkeyfile.c:1593 ../glib/gkeyfile.c:1766 ../glib/gkeyfile.c:3146 +#: ../glib/gkeyfile.c:3209 ../glib/gkeyfile.c:3339 ../glib/gkeyfile.c:3469 +#: ../glib/gkeyfile.c:3613 ../glib/gkeyfile.c:3842 ../glib/gkeyfile.c:3909 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "" + +#: ../glib/gkeyfile.c:1721 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "" + +#: ../glib/gkeyfile.c:1883 ../glib/gkeyfile.c:1999 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1903 ../glib/gkeyfile.c:2019 ../glib/gkeyfile.c:2388 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2606 ../glib/gkeyfile.c:2975 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2684 ../glib/gkeyfile.c:2761 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" + +#: ../glib/gkeyfile.c:4149 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:4171 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "" + +#: ../glib/gkeyfile.c:4315 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:4329 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "" + +#: ../glib/gkeyfile.c:4362 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:4401 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "" + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "" + +#: ../glib/gmarkup.c:675 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:687 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:713 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:751 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:759 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:764 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1170 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1210 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1252 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1333 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1374 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1418 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1551 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1598 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1607 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1760 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: ../glib/gmarkup.c:1774 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1782 ../glib/gmarkup.c:1827 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1790 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1796 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1802 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1807 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1813 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1820 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1836 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1842 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/goption.c:861 +msgid "[OPTION…]" +msgstr "" + +#: ../glib/goption.c:977 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:978 +msgid "Show help options" +msgstr "" + +#: ../glib/goption.c:984 +msgid "Show all help options" +msgstr "" + +#: ../glib/goption.c:1047 +msgid "Application Options:" +msgstr "" + +#: ../glib/goption.c:1049 +msgid "Options:" +msgstr "" + +#: ../glib/goption.c:1113 ../glib/goption.c:1183 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "" + +#: ../glib/goption.c:1123 ../glib/goption.c:1191 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "" + +#: ../glib/goption.c:1148 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "" + +#: ../glib/goption.c:1156 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "" + +#: ../glib/goption.c:1448 ../glib/goption.c:1527 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: ../glib/goption.c:1558 ../glib/goption.c:1671 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:2132 +#, c-format +msgid "Unknown option %s" +msgstr "" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1977 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "" + +#: ../glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: ../glib/gregex.c:2413 +msgid "hexadecimal digit or “}†expected" +msgstr "" + +#: ../glib/gregex.c:2429 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2469 +msgid "missing “<†in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2478 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2485 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2496 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2514 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2576 +msgid "stray final “\\â€" +msgstr "" + +#: ../glib/gregex.c:2580 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2590 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "" + +#: ../glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" + +#: ../glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn.c:250 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:394 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:479 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:886 ../glib/gspawn-win32.c:1231 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: ../glib/gspawn.c:894 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:901 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:908 +#, c-format +msgid "Child process exited abnormally" +msgstr "" + +#: ../glib/gspawn.c:1313 ../glib/gspawn-win32.c:337 ../glib/gspawn-win32.c:345 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: ../glib/gspawn.c:1532 ../glib/gspawn-win32.c:368 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "" + +#: ../glib/gspawn.c:1542 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "" + +#: ../glib/gspawn.c:1552 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1561 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1569 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "" + +#: ../glib/gspawn.c:1593 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:281 +msgid "Failed to read data from child process" +msgstr "" + +#: ../glib/gspawn-win32.c:298 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:374 ../glib/gspawn-win32.c:493 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:443 +#, c-format +msgid "Invalid program name: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:453 ../glib/gspawn-win32.c:720 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:464 ../glib/gspawn-win32.c:735 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:716 +#, c-format +msgid "Invalid working directory: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:781 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:995 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gstrfuncs.c:3247 ../glib/gstrfuncs.c:3348 +msgid "Empty string is not a number" +msgstr "" + +#: ../glib/gstrfuncs.c:3271 +#, c-format +msgid "“%s†is not a signed number" +msgstr "" + +#: ../glib/gstrfuncs.c:3281 ../glib/gstrfuncs.c:3384 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: ../glib/gstrfuncs.c:3374 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "" + +#: ../glib/gutf8.c:808 +msgid "Failed to allocate memory" +msgstr "" + +#: ../glib/gutf8.c:941 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1042 ../glib/gutf8.c:1051 ../glib/gutf8.c:1181 +#: ../glib/gutf8.c:1190 ../glib/gutf8.c:1329 ../glib/gutf8.c:1426 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1340 ../glib/gutf8.c:1437 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/gutils.c:2209 ../glib/gutils.c:2236 ../glib/gutils.c:2342 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bhaidht" +msgstr[1] "%u bhaidht" +msgstr[2] "%u baidht" +msgstr[3] "%u baidht" + +#: ../glib/gutils.c:2215 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2217 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2220 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2223 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2226 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2229 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2242 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2245 ../glib/gutils.c:2360 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2248 ../glib/gutils.c:2365 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2250 ../glib/gutils.c:2370 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2253 ../glib/gutils.c:2375 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2256 ../glib/gutils.c:2380 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2293 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bhaidht" +msgstr[1] "%s bhaidht" +msgstr[2] "%s baidht" +msgstr[3] "%s baidht" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2355 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "dhen Fhaoilleach" + +msgctxt "full month name with day" +msgid "February" +msgstr "dhen Ghearran" + +msgctxt "full month name with day" +msgid "March" +msgstr "dhen Mhàrt" + +msgctxt "full month name with day" +msgid "April" +msgstr "dhen Ghiblean" + +msgctxt "full month name with day" +msgid "May" +msgstr "dhen Chèitean" + +msgctxt "full month name with day" +msgid "June" +msgstr "dhen Ã’gmhios" + +msgctxt "full month name with day" +msgid "July" +msgstr "dhen Iuchar" + +msgctxt "full month name with day" +msgid "August" +msgstr "dhen Lùnastal" + +msgctxt "full month name with day" +msgid "September" +msgstr "dhen t-Sultain" + +msgctxt "full month name with day" +msgid "October" +msgstr "dhen Dàmhair" + +msgctxt "full month name with day" +msgid "November" +msgstr "dhen t-Samhain" + +msgctxt "full month name with day" +msgid "December" +msgstr "dhen Dùbhlachd" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Faoi" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Gearr" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Màrt" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Gibl" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Cèit" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Ã’gmh" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Iuch" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Lùna" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sult" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Dàmh" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Samh" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dùbh" diff --git a/po/gl.po b/po/gl.po new file mode 100644 index 0000000..4228c59 --- /dev/null +++ b/po/gl.po @@ -0,0 +1,6423 @@ +# Galician translation of GLib. +# Copyright (C) 2001, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# Proxecto Trasno - Adaptación do software libre á lingua galega: Se desexas +# colaborar connosco, podes atopar máis información en http://www.trasno.net +# +# Manuel A. Fernández Montecelo , 2001, 2005. +# Ignacio Casal Quinteiro , 2005, 2006. +# Ignacio Casal Quinteiro , 2007. +# Ignacio Casal Quinteiro , 2008. +# Mancomún - Centro de Referencia e Servizos de Software Libre , 2009. +# Suso Baleato ,2009. +# Antón Méixome , 2009. +# Leandro Regueiro , 2012. +# Fran Diéguez , 2009-2022. +# Fran Dieguez , 2012-2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-18 17:24+0000\n" +"PO-Revision-Date: 2022-04-19 08:02+0200\n" +"Last-Translator: Fran Dieguez \n" +"Language-Team: Galician >\n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Gtranslator 40.0\n" +"X-Project-Style: gnome\n" +"X-DL-Team: gl\n" +"X-DL-Module: glib\n" +"X-DL-Branch: glib-2-72\n" +"X-DL-Domain: po\n" +"X-DL-State: Translating\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Estabelecer as aplicacións predeterminadas non se soporta aínda" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Establecer aplicación como última usada para o tipo non se soporta aínda" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opcións de GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Mostrar as opcións de GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Escriba o modo de servizo de GApplication (usar desde os ficheiros de " +"servizo D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Omitir o ID da aplicación" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Substituír a instancia en execución" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Imprimir axuda" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[ORDE]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Mostrar versión" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Mostrar información da versión e saír" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Listar aplicacións" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Lista as aplicacións activábeis por D-Bus instalados (por ficheiros .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Iniciar unha aplicación" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Inicia unha aplicación (con ficheiros opcionais a abrir)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FICHEIRO...]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Activar unha acción" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invocar unha acción na aplicación" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACCIÓN [PARAMETRO]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Listar as accións dispoñíbeis" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"Listar as accións estáticas para unha aplicación (desde un ficheiro .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "ORDE" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "A orde para imprimir a axuda detallada" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identificador de aplicacións en formato D-Bus (p.ex.: org.exemplo.visor)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FICHEIRO" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Nomes de ficheiros relativos ou relativos opcionais, ou URIs a abrir" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACCIÓN" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "O nome de acción a invocar" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARÃMETRO" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Parámetro opcional para a invocación da acción, en formato GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Orde «%s» descoñecida\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Uso:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumentos:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS...]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Ordes:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Use «%s help ORDE» para obter axuda detallada.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"A orde %s require un id de aplicación ao que seguir directamente\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "id de aplicación non válido: «%s»\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"«%s» non recolle argumentos\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "non foi posíbel conectar ao D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "produciuse un erro ao enviar a mensaxe %s á aplicación: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "o nome da acción debe fornecerse logo do id de aplicación\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nome da acción non válido: «%s»\n" +"os nomes de acción deben consistir só de alfanuméricos, «-» e «.»\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "produciuse un erro ao analizar o parámetro da acción: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "as accións aceptan un máximo dun parámetro\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "a orde list-actions recolle só o id de aplicación" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "non é posíbel atopar o ficheiro desktop para a aplicación %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"orde descoñecida: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "O valor de conta pasado a %s é demasiado longo" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Non se permite buscar no fluxo base" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Non é posíbel truncar GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "O fluxo xa se pechou" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Non se permite truncar no fluxo base" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "A operación foi cancelada" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "O socket non é válido, non se inicializou" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "A secuencia de bytes non é válida na entrada da conversión" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Non hai espazo abondo para o enderezo do socket" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "A secuencia de bytes non é válida na entrada da conversión" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Produciuse un erro durante a conversión: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Non se permite a inicialización cancelábel" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Non se admite a conversión do conxunto de caracteres «%s» a «%s»" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Non foi posíbel abrir o conversor de «%s» a «%s»" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "tipo %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Tipo descoñecido" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "tipo de ficheiro %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials contén datos non válidos" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials non está implementado neste SO" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "A súa plataforma non ten compatibilidade con GCredentials" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials non contén un ID de proceso para este SO" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Non é posíbel burlar as credenciais neste SO" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Final de fluxo inesperadamente prematuro" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Clave «%s» non admitida na entrada do enderezo «%s»" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Combinación de par clave/valor sen sentido na entrada do enderezo «%s»" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"O enderezo «%s» non é válido (necesítase exactamente unha ruta, directorio, " +"directorio temporal ou claves abstractas)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Erro no enderezo «%s» — o atributo «%s» está mal formado" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transporte «%s» descoñecido ou non compatíbel para o enderezo «%s»" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "O elemento do enderezo «%s» non contén un carácter dous puntos (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" +"O nome de transporte do elemento de enderezo «%s» non pode estar baleiro" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"O par clave/valor %d, «%s» no elemento do enderezo «%s» non contén un signo " +"de igual" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"O par clave/valor %d, «%s» no elemento do enderezo «%s» non debe ter unha " +"chave baleira" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Produciuse un erro ao desescapar a clave ou o valor no par clave/valor %d, " +"«%s», no elemento de enderezo «%s»" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Erro no enderezo «%s» — o transporte unix require que se estabeleza " +"exactamente unha das claves «path» ou «abstract»" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Erro no enderezo «%s» — falta o atributo do equipo ou está mal formado" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Erro no enderezo «%s» — falta o atributo do porto ou está mal formado" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Erro no enderezo «%s» — falta o atributo do ficheiro de uso de unha vez ou " +"está mal formado" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Produciuse un erro ao autoiniciar: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Produciuse un erro ao abrir o ficheiro de uso de unha vez «%s»: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Produciuse un erro ao ler o ficheiro de uso de unha vez «%s»: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Produciuse un erro ao ler o ficheiro de uso de unha vez «%s»:, esperábanse " +"16 bytes, obtivéronse %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Produciuse un erro ao gravar os contidos do ficheiro de uso de unha vez «%s» " +"ao fluxo:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "O enderezo fornecido está baleiro" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Non é posíbel iniciar («spawn») unha bus de mensaxe cando AT_SECURE está " +"estabelecido" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Non é posíbel iniciar («spawn») unha mensaxe ao bus sen un ID de máquina: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Non é posíbel autoiniciar D-Bus sen un $DISPLAY X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Produciuse un erro ao iniciar («spawn») a orde «%s»: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Non é posíbel determinar o enderezo do bus de sesión (non está implementado " +"para este SO)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Non é posíbel determinar o enderezo do bus desde a variábel de ambiente " +"DBUS_STARTER_BUS_TYPE - valor descoñecido «%s»" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Non é posíbel determinar o enderezo do bus xa que a variábel de ambiente " +"DBUS_STARTER_BUS_TYPE non está estabelecida" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipo de bus %d descoñecido" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Falta o contido inesperada ao tentar ler unha liña" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Falta de contido inesperada ao tentar ler (de forma segura) unha liña" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Esgotáronse todos os mecanismos de autenticación dispoñíbel (tentáronse: %s) " +"(dispoñíbeis: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Os IDs de usuario deben ser os mesmos para o par e o servidor" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Cancelando mediante GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Produciuse un erro ao obter a información do directorio «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Os permisos no directorio «%s» están malformados. Esperábase o modo 0700 e " +"obtívose 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Produciuse un erro ao crear o directorio %s: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operación non permitida" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Produciuse un erro ao abrir o anel de chaves «%s» para a súa lectura: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "A liña %d do anel de chaves en «%s» con contido «%s» está malformada" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"O primeiro token da liña %d no anel de chaves en «%s» co contido «%s» está " +"malformado" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"O segundo token da liña %d no anel de chaves en «%s» co contido «%s» estaÌ " +"malformado" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Non foi posíbel atopar a cookie co id %d no anel de chave en «%s»" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Produciuse un erro ao crear o ficheiro de bloqueo «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Produciuse un erro ao eliminar o ficheiro de bloqueo antigo «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Produciuse un erro ao pechar o ficheiro de bloqueo «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Produciuse un erro ao abrir o ficheiro de bloqueo «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Produciuse un erro ao abrir o anel de chaves «%s» para escribir: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Ademais, a liberación do bloqueo para «%s» tamén fallou: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "A conexión está pechado" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Tempo de espera máximo alcanzado" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Atopáronse opcións non compatíbeis ao construír a conexión da parte cliente" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Non existe a interface «org.freedesktop.DBus.Properties» no obxecto coa ruta " +"%s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Non existe a propiedade «%s»" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Non é posíbel escribir a propiedade «%s»" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Non é posíbel escribir a propiedade «%s»" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Produciuse un erro ao estabelecer a propiedade «%s»: Esperábase o tipo «%s» " +"pero obtívose «%s»" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Non existe a interface «%s»" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Non existe a interface «%s» no obxecto coa ruta %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Non existe a clave «%s»" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "O tipo da mensaxe, «%s», non coincide co tipo «%s» esperado" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Xa hai un obxecto exportado para a interface %s en %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Non é posíbel obter a propiedade %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Non é posíbel estabelecer a propiedade %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "O método «%s» devolveu un tipo «%s» máis esperábase «%s»" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "O método «%s» na interface «%s» coa sinatura «%s» non existe" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Xa se exportou un subárbore para %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "O obxecto non existe na ruta «%s»" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "o tipo é INVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Mensaxe METHOD_CALL: falta o campo da cabeceira PATH ou MEMBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Mensaxe METHOD_RETURN: falta o campo da cabeceira REPLY_SERIAL" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Mensaxe ERROR: falta o campo da cabeceira REPLY_SERIAL ou ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Mensaxe SIGNAL: falta o campo da cabeceira PATH, INTERFACE ou MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Mensaxe SIGNAL: o campo da cabeceira PATH está usando un valor reservado /" +"org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Mensaxe SIGNAL: O campo da cabeceira INTERFACE está usando un valor " +"reservado org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Quíxose ler %lu byte pero obtívose un %lu" +msgstr[1] "Quixéronse ler %lu bytes pero obtívose un %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Esperábase un byte NUL despois da cadea «%s» pero atopouse o byte %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Esperábase unha cadea UTF-8 correcta pero atopáronse bytes non válidos no " +"byte desvío %d (a lonxitude da cadea é %d). A cadea UTF-8 correcta até ese " +"punto foi «%s»" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Valor aniñado demasiado profundo" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "O valor analizado «%s» non é unha ruta de obxecto D-Bus correcta" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "O valor analizado «%s» non é unha sinatura D-Bus correcta" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Atopouse unha matriz cunha lonxitude de %u byte. A lonxitude máxima é 2<<26 " +"bytes (64 MiB)." +msgstr[1] "" +"Atopouse unha matriz cunha lonxitude de %u bytes. A lonxitude máxima é 2<<26 " +"bytes (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Atopouse unha matriz de tipo «a%c», agardábase ter unha de lonxitude de " +"varios %u bytes, aínda que se atopou unha de %u bytes" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Non se permiten as estruturas baleiras (tuplas) en D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"O valor «%s» analizado para a variante non é unha sinatura de D-Bus correcta" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Produciuse un erro ao deserializar o GVariant co tipo cadea «%s» desde o " +"formato ligado D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valor de «endianness» non válido. Esperábase 0x6c («|») ou 0x42 («B») pero " +"atopouse 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"A versión maior do protocolo non é válida. Esperábase 1 pero atopouse a %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Atopouse a cabeceira da sinatura pero non é do tipo sinatura" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Atopouse a cabeceira de sinatura coa sinatura «%s» máis o corpo da mensaxe " +"está baleiro" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"O valor analizado «%s» non é unha sinatura D-Bus correcta (para o corpo)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Non hai unha cabeceira da sinatura na mensaxe pero o corpo da mensaxe ten %u " +"byte" +msgstr[1] "" +"Non hai unha cabeceira da sinatura na mensaxe pero o corpo da mensaxe ten %u " +"bytes" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Non foi posíbel deserializar a mensaxe: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Produciuse un erro ao serializar o GVariant co tipo cadea «%s» desde o " +"formato ligado D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"O número de descritores de ficheiro no mensaxe (%d) difire do campo " +"cabeceira (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Non foi posíbel serializar a mensaxe: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"O corpo da mensaxe ten a sinatura «%s» máis non está presente a cabeceira de " +"sinatura" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"O corpo da mensaxe ten a sinatura de tipo «%s» pero a sinatura no campo da " +"cabeceira é «%s»" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"O corpo da mensaxe está baleiro máis a sinatura do campo da cabeceira é " +"«(%s)»" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Produciuse un erro ao devolver co corpo de tipo «%s»" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Produciuse un erro ao devolver co corpo baleiro" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Prema calquera carácter para pechar esta xanela)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "O DBus de sesión non está executándose e o autoiniciado fallou" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Non é posíbel obter o perfil de hardware: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Non foi posíbel cargar %s ou %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Produciuse un erro ao chamar a StartServiceByName para %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Resposta %d non esperada desde o método StartServiceByName(«%s»)" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Non é posíbel invocar ao método; o proxy non ten dono para un nome coñecido " +"%s e o proxy construíuse coa opción G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Non se admite un espazo de nomes abstracto" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Non é posíbel especificar o ficheiro de uso de unha vez ao crear un servidor" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "" +"Produciuse un erro ao escribir no ficheiro de uso de unha vez en «%s»: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "A cadea «%s» non é un GUID de D-BUS correcta" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Non é posíbel escoitar nun transporte «%s» non admitido" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Ordes:\n" +" help Mostra esta axuda\n" +" introspect Instrospecciona un obxecto remoto\n" +" monitor Monitorizar un obxecto remoto\n" +" call Invoca un método nun obxecto remoto\n" +" emit Emite un sinal\n" +" wait Agarda que apareza un nome de bus\n" +"\n" +"Use '%s ORDE --help' para obter axuda sobre cada orde.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Erro: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Produciuse un erro ao analizar o XML de introspección: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Erro: %s non é un nome válido\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Erro: %s non é unha ruta a un obxecto correcta\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Conectar ao bus do sistema" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Conectar ao bus de sesión" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Conectar a un enderezo D-Bus fornecido" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opcións da conexión do extremo:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opción para especificar a conexión do extremo" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Non se especificou o punto final da conexión" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Especificáronse varios puntos finais da conexión" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Aviso: segundo os datos de introspección a interface «%s» non existe\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Aviso: segundo os datos de introspección o método «%s» non existe na " +"interface «%s»\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Destino opcional para o sinal (nome único)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Ruta do obxecto sobre o que emitir o sinal" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Nomes da interface e sinal" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emitir un sinal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Produciuse un erro ao conectar: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Erro: %s non é un nome de bus único correcto.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Erro: non se especificou unha ruta de obxecto\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Erro: non se especificou o nome do sinal\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Erro: o nome do sinal «%s» non é válido\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Erro: %s non é un nome de interface correcto\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Erro: %s non é un nome de membro correcto\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Produciuse un erro ao analizar a opción %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Produciuse un erro ao limpar a conexión: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nome do destino onde invocar o método" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Ruta ao obxecto onde invocar o método" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Método e nome da interface" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Tempo de expiración en segundos" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Permitir autorización interactiva" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Invocar un método nun obxecto remoto." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Erro: non se especificou un destino\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Erro: %s non é un nome de bus válido\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Erro: non se especificou o nome do método\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Erro: o nome do método «%s» non é válido\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Produciuse un erro ao analizar o parámetro %d do tipo «%s»: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Produciuse un erro ao engadir o manexador %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nome de destino a introspeccionar" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Ruta do obxecto a introspeccionar" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Imprimir XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Introspeccionar fillo" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Só mostrar propiedades" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspecciona un obxecto remoto." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nome de destino a monitorizar" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Ruta do obxecto a monitorizar" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitoriza un obxecto remoto." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Erro: non é posíbel monitorizar unha conexión non-message-bus\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Servizo a activar antes de agardar polo outro (nome coñecido)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Tempo de espera máximo a agardar antes de saír con un erro (segundos); 0 " +"para non ter tempo de espera (valor por omisión)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPCIÓN…] NOME-BUS" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Agardar que apareza un nome de bus." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Erro: Debe especificar un servizo a activar.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Erro: Debe especificar un servizo a agardar.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Erro: Demasiados argumentos.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Erro: %s non é un nome de bus válido e coñecido.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Non está autorizado para cambiar as preferencias de depuración" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Sen nome" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "O ficheiro de escritorio non especificou o campo Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Non é posíbel atopar o terminal requirido pola aplicación" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Non é posíbel crear o directorio de configuración da aplicación de usuario " +"%s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" +"Non é posíbel crear o directorio de configuración MIME %s do usuario: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "A información da aplicación carece dun identificador" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Non é posíbel crear o ficheiro de escritorio %s do usuario" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Definición personalizada para %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "a unidade non implementa a expulsión" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "a unidade non implementa eject ou eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "a unidade non implementa a consulta para medios" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "a unidade non implementa o inicio" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "a unidade non implementa a detención" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "A infraestrutura de TLS non implementa a obtención da ligazón TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "A compatibilidade de TLS non está dispoñíbel" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "A compatibilidade de DTLS non está dispoñíbel" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Non é posíbel manipular a versión %d da codificación de GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" +"Número formado incorrectamente de tokens (%d) na codificación de GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Non é posíbel manipular a versión %d da codificación de GEmblemedicon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" +"Número formado incorrectamente de tokens (%d) na codificación de " +"GEmblemedicon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Esperábase un GEmblem para o GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "O punto de montaxe contido non existe" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Non é posíbel copiar sobre o directorio" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Non é posíbel copiar un directorio sobre o directorio" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "O ficheiro de destino xa existe" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Non é posíbel copiar o directorio recursivamente" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Non se admite a unión" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Produciuse un erro ao empalmar o ficheiro: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Copiar (reflink/clonar) entre montaxes non é compatíbel" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Copiar (reflink/clone) non é compatíbel ou non é válido" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Copiar (reflink/clone) non é compatíbel ou non funciona" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Non é posíbel copiar o ficheiro especial" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "O valor da ligazón simbólica dada non é válido" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "As ligazóns simbólicas non se admiten" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "O Lixo non é compatíbel" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Os nomes de ficheiro non poden conter «%c»" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "o volume non implementa o montado" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Non hai ningunha aplicación rexistrado para manexar este ficheiro" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "O enumerador está pechado" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "O enumerador do ficheiro ten unha operación excepcional" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "O enumerador do ficheiro xa está pechado" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Non é posíbel manipular a versión %d da codificación de GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Datos de entrada formados incorrectamente para o GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "O fluxo non permite query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Non se permite buscar no fluxo" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Non se permite truncar no fluxo de entrada" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Non se permite truncar no fluxo" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "O nome do host non é válido" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Resposta do proxy HTTP incorrecta" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Non se permite a conexión co proxy HTTP" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Produciuse un fallo na autenticación co proxy HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Requírese autenticación no proxy HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Produciuse un fallo na conexión co proxy HTTP: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "A resposta do proxy HTTP é demasiado grande" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "A conexión co servidor proxy HTTP pechouse de forma non esperada." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Número incorrecto de tokens (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Non hai un tipo para o nome de clase %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "O tipo %s non implementa unha interface GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "O tipo %s non ten unha clase" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Número de versión formado incorrectamente: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "O tipo %s non implementa from_tokens() na interface do GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Non é posíbel manipular a versión fornecida da codificación da icona" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Non se especificou ningún enderezo" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "A lonxitude %u é demasiado longa para un enderezo" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "O enderezo ten bits máis aló da lonxitude do prefixo" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Non foi posíbel analizar «%s» como unha máscara dun enderezo IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Non hai espazo abondo para o enderezo do socket" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Non se admite o enderezo do socket" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "O fluxo de entrada non implementa a lectura" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "O fluxo ten unha operación excepcional" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copiar co ficheiro" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Manter co ficheiro ao mover" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "«version» non recolle argumentos" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Uso:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Mostrar información da versión e saír." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Ordes:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatenar ficheiros á saída estándar" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copiar un ou máis ficheiros" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Mostrar información sobre as localizacións" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Iniciar unha aplicación desde un ficheiro .desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Lista os contidos das localizacións" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Obtén ou estabelece o xestor para o tipo mime" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Crear cartafoles" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitorizar cambios en ficheiros ou cartafoles" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montar ou desmontar as localizacións" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Mover un ou máis ficheiros" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Abrir ficheiros con unha aplicación predeterminado" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Renomear un ficheiro" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Eliminar un ou máis ficheiros" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Ler da entrada en estándar e gardar" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Estabelecer un atributo de ficheiro" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Mover ficheiros ou directorios ao lixo" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Lista os contidos da localización nunha árbore" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Use '%s help ORDE' para obter axuda detallada.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Produciuse un erro ao escribir ao stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCALIZACIÓN" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatenar ficheiros e imprimir á saída estándar." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio pode traballar como a utilidade cat tradicional, pero usando " +"localizacións\n" +"GIO no lugar de ficheiros locais: por exemplo, pode usar algo así como \n" +"smb:////server/resource/file.txt como localización." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Non se forneceron localizacións" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Non hai un directorio obxectivo" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Mostrar progreso" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Preguntar antes de sobrescribir" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Manter todos os atributos" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Facer unha copia de respaldo para os ficheiros de destino" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Non mostrar nunha as ligazóns simbólicas" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Usar os permisos predeterminados para o destino" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Transferíronse %s de %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ORIXE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINO" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copia un ou máis ficheiros desde ORIXE a DESTINO." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy é similar á utilidade cp tradicional, pero usando localizacións\n" +"GIO no lugar de ficheiros locais: por exemplo, pode usar algo así como \n" +"smb:////server/resource/file.txt como localización." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "O destino %s non é un cartafol" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: sobrescribir «%s»? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Lista de atributos escribíbeis" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Obter a información do sistema de ficheiros" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Os atributos a obter" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTOS" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Non seguir as ligazóns simbólicas" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributos:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nome en pantalla: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "nome de edición: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nome: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipo: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "tamaño: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "oculto\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "ruta local: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "montaxe unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atributos estabelecíbeis:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Espazos de nomes de atributo escribíbeis:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Mostrar información sobre as localizacións." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info é similar á utilidade ls tradicional, pero usando localizacións\n" +"GIO no lugar de ficheiros locais: por exemplo, pode usar algo así como \n" +"smb:////server/resource/file.txt como localización. Os atributos de\n" +"ficheiro poden especificarse como un nome GIO, p.ex. standard::icon,\n" +"ou simplemente polo espazo de nomes, p.ex. unix. ou por «*», que\n" +"coincide con todos os atributos" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "FICHEIRO-DESKTOP [ARG-FICHEIRO …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Iniciar unha aplicación desde un ficheiro desktop, pasando argumentos do " +"nome do ficheiro opcionais a el." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Non se forneceu un ficheiro desktop" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Esta plataforma non ten compatibilidade coa orde de inicio" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Non foi posíbel cargar «%s»: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Produciuse un erro ao cargar a información de aplicación para «%s»" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Non foi posíbel iniciar a aplicación «%s»: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Mostrar os ficheiros ocultos" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Usar un formato de listado longo" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Imprimir nomes que mostrar" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Mostrar os URIs completos" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Lista os contidos das localizacións." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list é similar á utilidade ls tradicional, pero usando localizacións\n" +"GIO no lugar de ficheiros locais: por exemplo, pode usar algo así como \n" +"smb:////server/resource/file.txt como localización. Os atributos de " +"ficheiro\n" +"poden especificarse co nome GIO, p.ex. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TIPOMIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "XESTOR" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Obtén ou estabelece o xestor para o tipo mime." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Se non se fornece un xestor, mostra as aplicacións rexistrados e\n" +"recomendados para o tipo mime. Se se fornece o xestor, estabelecese\n" +"o xestor predeterminado para o tipo mime." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Debe especificar un tipo mime único, e pode que un xestor" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Non hai ningunha aplicación predeterminado para «%s»\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplicación predeterminada para «%s»: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplicacións rexistradas:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Non hai aplicacións rexistrados\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplicacións recomendadas:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Non hai aplicacións recomendadas\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Produciuse un erro ao ler a información do xestor «%s»" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"Produciuse un erro ao estabelecer «%s» como xestor predeterminado para «%s»: " +"%s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Crear directorios pais" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Crear cartafoles." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir é similar á utilidade mkdir tradicional, pero usando " +"localizacións\n" +"GIO no lugar de ficheiros locais: por exemplo, pode usar algo así como \n" +"smb:////server/resource/file.txt como localización." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitorizar un directorio (predeterminado: depende do tipo)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitorizar un ficheiro (predeterminado: depende do tipo)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Monitorizar un ficheiro directamente (detecta os cambios feitos mediante " +"ligazóns duras)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitoriza un ficheiro directamente, pero non informa dos cambios" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Informa dos movementos e renomeados como eventos de eliminación/creación " +"simples" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Seguir os eventos de montaxe" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitorizar os cambios en ficheiros e cartafoles." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Monitorizar como montábel" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Montar volume como ficheiro de dispositivo, ou outro identificador" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Desmontar" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Expulsar" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Deter a unidade con ficheiro de dispositivo" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DISPOSITIVO" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Desmonta todos os puntos de montaxe co esquema fornecido" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ESQUEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignorar operacións de ficheiro non resoltas ao desmontar ou expulsar" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Usar un usuario anónimo ao autenticarse" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Listar" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitorizar eventos" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Mostrar información adicional" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "O PIM numérico ao desbloquear o volume VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montar un volume TCRYPT oculto" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montar un volume de sistema TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Acceso anónimo denegado" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Non hai unha unidade para o ficheiro de dispositivo" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Non hai un volume para o ID fornecido" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montar ou desmontar as localizacións." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Non usar a copia e eliminación alternativas" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Move un ou máis ficheiros desde ORIXE a DESTINO." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move é similar á utilidade mv tradicional, pero usando localizacións\n" +"GIO no lugar de ficheiros locais: por exemplo, pode usar algo así como \n" +"smb:////server/resource/file.txt como localización" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "O destino %s non é un directorio" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Abrir os ficheiros coa aplicación predeterminada\n" +"que está rexistrada para xestionar ficheiros\n" +"deste tipo." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignorar os ficheiros non existentes, non preguntar nunca" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Eliminar os ficheiros fornecidos." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Renomear un ficheiro." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Falta un argumento" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Demasiados argumentos" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Renomeado con éxito. Nova uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Só crear se non existe" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Engadir ao final do ficheiro" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Ao crear, restrinxir o acceso ao usuario actual" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Ao substituír, substituír se o destino non existe" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Imprimir novo etag ao final" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "O etag do ficheiro foi sobrescrito" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Produciuse un erro ao ler da entrada estándar" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "ETAG non dispoñíbel\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Ler da entrada en estándar e gardar en DEST." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Non se forneceu un destino" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Tipo do atributo" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPO" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUTO" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALOR" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Estabelece un atributo de ficheiro da LOCALIZACIÓN." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Localización non especificada" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atributo non especificado" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Valor non especificado" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Tipo de atributo %s non válido" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Baleirar o lixo" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Lista os ficheiros no lixo coas súas localizacións orixinais." + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restaura un ficheiro desde o lixo á súa localización orixinal (posiblemente " +"recreando o directorio)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Non é posíbel atopar a ruta orixinal" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Non é posíbel recrear a localización orixinal: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "non é posíbel mover o ficheiro á súa localización orixinal:" + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Move/restaurar os ficheiros ou directorios ao lixo." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Nota: para o trocador --restore, se a localización orixinal dun ficheiro\n" +"no lixo xa existe, non se sobrescribirá a non ser que se estabeleza --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "A localización fornecida non comeza por trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Seguir as ligazóns simbólicas, montaxes e atallos" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Lista os contidos dos directorios nun formato árbore." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Non se permite o elemento <%s> dentro de <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Non se permite o elemento <%s> non nivel superior" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "O ficheiro %s aparece varias veces no recurso" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Produciuse un erro ao buscar «%s» en calquera directorio fonte" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Produciuse un erro ao buscar «%s» no directorio actual" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Opción de procesado descoñecida «%s»" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"%s de preprocesado requirida, pero %s non está estabelecida, e %s non está " +"no PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Produciuse un erro ao ler o ficheiro %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Produciuse un erro ao comprimir o ficheiro: %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "o texto non debe aparecer dentro de <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Mostrar a versión do programa e saír" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nome do ficheiro de saída" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Os directorios dos que ler ficheiros referenciados en FILE (por omisión: o " +"directorio actual)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIRECTORIO" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Xerar saída no formato seleccionado pola extensión do nome do ficheiro " +"obxectivo" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Xerar unha cabeceira de orixe" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Xera o código fonte usado para ligar o ficheiro do recurso no seu código" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Xerar lista de dependencias" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nome do ficheiro de dependencia a xerar" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Inclúe obxectivos phony no ficheiro de dependencias xerado" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Non crear e rexistrar o recurso automaticamente" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Non exporte as funcións; decláreas en G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Non incrustar os datos do recurso no ficheiro C; asúmese que é ligado " +"externamente no lugar" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "O nome de identificador C usado para xerar o código fonte" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "" +"O compilador de C obxectivo (predetermiando: a variábel de ambiente CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compila unha especificación de recurso nun ficheiro de recurso.\n" +"Os ficheiros de especificación de recursos teñen a extensión .gresource." +"xml,\n" +"e o ficheiro do recurso ten a extensión .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Debería fornecer exactamente un nome de ficheiro\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "o alcume debe ter cando menos 2 caracteres" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Valor numérico non válido" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " xa especificado" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' xa especificado" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "os balores das bandeiras deben ter cando menos un bit estabelecido" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> debe conter cando menos un " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> non está no rango especificado" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> non é un membro válido do enumerado especificado" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> contén unha cadea que non está especificada no tipo das bandeiras" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> contén unha cadea que non está en " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " xa está especificado para esta chave" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " non permitido para as chaves do tipo «%s»" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "o mínimo especificado é maior que o máximo" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categoría l10n no admitida: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n solicitado, pero non existe o dominio gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "contexto de tradución fornecido para o valor sen ter l10n activado" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Produciuse un erro ao analizar o valor do tipo «%s»: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" non pode especificarse para as chaves etiquetadas como un tipo " +"enumerado" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " xa especificadas para esta chave" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " non permitidas para as chaves do tipo “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " xa fornecido" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " debe conter cando menos unha " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " xa especificado para esta chave" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" só pode ser especificado para as chaves con enumerados ou " +"bandeiras de tipos ou despois de " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" fornecido cando «%s» xa é un membro do tipo enumerado" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" fornecido cando xa foi fornecido" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " xa especificado" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "o alias do obxectivo «%s» non é un tipo enumerado" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "o alias do obxectivo «%s» non está en " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " debe conter cando menos un " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Non se permiten nomes baleiros" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Nome «%s» non válido: os nomes deben comezar por unha letra minúscula" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nome «%s» non válido: o carácter «%c» non é válido; só se permiten letras en " +"minúsculas, números e guións («-»)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Nome «%s» non válido: non se permiten dous guións seguidos («--»)" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Nome «%s» non válido: o último carácter non pode ser un guión («-»)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nome «%s» non válido: a lonxitude máxima é 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " xa especificado" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Non é posíbel engadir claves a un esquema «lista-de»" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " xa especificada" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" enmascara a en ; use " +" para modificar o valor" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Debe especificar exactamente un de «type», «enum» ou «flags» como un " +"atributo de " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> aínda non especificado." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Tipo de cadea GVarian «%s» non válida" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " fornecido pero o esquema non estende nada" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Non existe para sobrescribir" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " xa foi especificada" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " xa especificado" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " estende ao aínda esquema inexistente «%s»" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " é unha lista de esquemas aínda non existentes «%s»" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Non é posíbel que sexa unha lista de esquemas con unha ruta" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Non é posíbel estender un esquema con unha ruta" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" é unha lista, estase estendendo que non é " +"unha lista" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" estende pero " +"«%s» non estende a «%s»" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Unha ruta, se se especifica, debe comezar e rematar con unha barra" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "A ruta dunha lista debe rematar con «:/»" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Aviso: O esquema «%s» ten unha ruta «%s». As rutas que comezan con «/" +"apps/», «/desktop/» ou «/system/» están obsoletas." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> xa especificado" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Non se permite un elemento <%s> dentro de <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Non se permite o elemento <%s> no nivel superior" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Requírense os elementos en " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "O texto non debe aparecer dentro de <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Aviso: referencia non definida a " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict foi especificado; saíndo." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Ignorouse este ficheiro completamente." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignorando este ficheiro." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Non existe a clave «%s» no esquema «%s» como se especificou no ficheiro de " +"sobrescrita «%s»; ignorando a sobrescrita para esta chave." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Non existe a clave «%s» no esquema «%s» como se especificou no ficheiro de " +"sobrescrita «%s» e --strict foi especificado; saíndo." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Non se poden fornecer sobrescritas por escritorio para as chaves localizadas " +"«%s» no esquema «%s» (ficheiro de sobrescrita «%s»); ignorando a sobrescrita " +"para esta chave." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Non se poden fornecer sobrescritas por escritorio para as chaves localizadas " +"«%s» no esquema «%s» (ficheiro de sobrescrita «%s») e --strict foi " +"especificado; saíndo." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Produciuse un erro ao analizar a clave «%s» no esquema «%s» como se " +"especificou no ficheiro de sobrescrita «%s»: %s. Ignorando a sobrescrita " +"para esta chave." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Produciuse un erro ao analizar a clave «%s» no esquema «%s» como se " +"especificou no ficheiro de sobrescrita «%s»: %s. --strict foi especificado; " +"saíndo." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"A clave de sobrescrita «%s» no esquema «%s» no ficheiro de sobrescrita «%s» " +"está fora do intervalo indicado no esquema; ignorando a sobrescrita para " +"esta chave." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"A clave de sobrescrita «%s» no esquema «%s» no ficheiro de sobrescrita «%s» " +"está fora do intervalo indicado no esquema e --strict foi especificado; " +"saíndo." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"A clave de sobrescrita «%s» no esquema «%s» no ficheiro de sobrescrita «%s» " +"non está na lista de opcións válidas; ignorando a sobrescrita para esta " +"chave." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"A clave de sobrescrita «%s» no esquema «%s» no ficheiro de sobrescrita «%s» " +"non está na lista de opcións válidas e --strict foi especificado; saíndo." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Onde almacenar o ficheiro gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Interromper ao atopar calquera erro nos esquemas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Non escribir o ficheiro compilado de gschema" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Non respectar as restricións de nome de clave" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compilar todos os ficheiros de esquema GSettings nunha caché\n" +"de esquemas. Os ficheiros de esquema deben ter a extensión\n" +".gschema.xml e o ficheiro de caché chámase gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Debería fornecer exactamente un nome de cartafol" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Non se atoparon ficheiros de esquema: non se fai nada." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Non se atopou ningún ficheiro de esquemas: eliminouse o ficheiro de saída " +"existente." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "O nome do ficheiro non é válido %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "" +"Produciuse un erro ao obter a información do sistema de ficheiros %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Non se atopa o punto de montaxe que contén o ficheiro %s" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Non é posíbel renomear o directorio raíz" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Produciuse un erro ao renomear o ficheiro %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Non é posíbel renomear o ficheiro, o ficheiro xa existe" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "O nome do ficheiro non é válido" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Produciuse un erro ao abrir o ficheiro %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Produciuse un erro ao eliminar o ficheiro %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Produciuse un erro ao mover ao lixo o ficheiro %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Non é posíbel crear o directorio do lixo %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "" +"Non é posíbel atopar o directorio de nivel superior para mover ao lixo %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Enviar ao lixo en montaxes internos do sistema non se admite" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Non é posíbel atopar ou crear o directorio do lixo para %s ao lixo %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Non é posíbel crear a información de lixo para o ficheiro %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Non é posíbel mover ao lixo o ficheiro %s a través dos límites do sistema de " +"ficheiros" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Non é posíbel mover ao lixo o ficheiro %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Non é posíbel mover ao lixo o ficheiro %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Produciuse un erro ao crear o directorio %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "O sistema de ficheiros non é compatíbel coas ligazóns simbólicas" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Produciuse un erro ao crear a ligazón simbólica %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Produciuse un erro ao mover o ficheiro %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Non é posíbel mover o directorio sobre un directorio" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Fallou a creación do ficheiro de seguranza" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Produciuse un erro ao retirar o ficheiro obxectivo: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Non se permite mover entre puntos de montaxe" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Non foi posíbel determinar o uso de disco de %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "O valor do atributo debe ser non nulo" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tipo de atributo non válido (esperábase unha cadea)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nome estendido do atributo non válido" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Produciuse un erro ao estabelecer o atributo estendido «%s»: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codificación non válida)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Produciuse un erro ao obter a información do ficheiro «%s»: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Produciuse un erro ao obter información do descritor do ficheiro: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "O tipo de atributo non é válido (esperábase uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "O tipo de atributo non é válido (esperábase uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "O tipo de atributo non é válido (esperábase unha cadea de bytes)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Non foi posíbel estabelecer os permisos nas ligazóns simbólicas" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Produciuse un erro ao estabelecer os permisos: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Produciuse un erro ao estabelecer o propietario: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "a ligazón simbólica debe ser non nula" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Produciuse un erro ao estabelecer a ligazón simbólica: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Produciuse un erro ao estabelecer a ligazón simbólica: o ficheiro non é unha " +"ligazón" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"Os nanosegundos %d adicionais en marcas de tempo UNIX %lld son negativas" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Os nanosegundos %d adicionais en marcas de tempo UNIX %lld alcanzan 1 segundo" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "A marca de tempo UNIX %lld non colle nos 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "A marca de tempo %lld está fóra do rango admitido por Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Non é posíbel converter o nome de ficheiro «%s» a UTF-16." + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Non é posíbel abrir o ficheiro «%s»: Erro de Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Produciuse un erro ao estabelecer a data de modificación ou acceso para o " +"ficheiro «%s»: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" +"Produciuse un erro ao modificar a configuración ou o tempo de acceso: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "O contexto SELinux debe ser non-NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux non está activado neste sistema" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Produciuse un erro ao estabelecer o contexto SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Non se permite estabelecer o atributo %s" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Produciuse un erro ao ler do ficheiro: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Produciuse un erro ao pechar o ficheiro: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Produciuse un erro ao buscar no ficheiro: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "" +"Non é posíbel atopar o tipo de monitorización do ficheiro local " +"predeterminado" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Produciuse un erro ao escribir no ficheiro: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" +"Produciuse un erro ao retirar a ligazón da copia de seguranza antiga: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Produciuse un erro ao crear a copia de seguranza: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Produciuse un erro ao renomear o ficheiro temporal: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Produciuse un erro ao truncar o ficheiro: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Produciuse un erro ao abrir o ficheiro %s: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "O ficheiro destino é un directorio" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "O ficheiro destino non é un ficheiro normal" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "O ficheiro foi modificado externamente" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Produciuse un erro ao retirar o ficheiro antigo: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Proporcionouse un GSeekType non válido" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Petición de busca non válida" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Non é posíbel truncar GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "O fluxo de saída da memoria non é redimensionábel" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Produciuse un erro ao redimensionar o fluxo de saída da memoria" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"A cantidade de memoria requirida para procesar a escrita é máis grande que o " +"espazo de enderezos dispoñíbel" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Solicitouse unha busca antes do inicio do fluxo" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Solicitouse unha busca máis aló do final do fluxo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "montaxe non implementa «desmontaxe»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount non implementa «extraer»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "a montaxe non implementa o «unmount» ou a «unmount_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "a montaxe non implementa a «eject» ou a \"eject_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "a montaxe non implementa \"remount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "a montaxe non implementa o descubrimento do tipo de contido" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "a montaxe non implementa o descubrimento síncrono do tipo de contido" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "O nome do host «%s» contén «[» mais non «]»" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "A rede non é atinxíbel" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Equipo non atinxíbel" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Non foi posíbel crear un monitor de rede: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Non foi posíbel crear un monitor de rede: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Non foi posíbel obter o estado da rede: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager non está executándose" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "A versión NetworkManager é demasiado antiga" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "O fluxo de saída non implementa a escritura" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "A suma de vectores pasados a %s é demasiado longa" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "O fluxo de orixe xa está pechado" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Produciuse un erro ao resolver «%s»: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s non implementado" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Dominio non válido" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Non existe o recurso en «%s»" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Produciuse un erro ao descomprimir o recurso en «%s»" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "O recurso en «%s» non é un cartafol" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "O fluxo de entrada non implementa seek" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Lista as seccións que conteñen recursos nun ficheiro elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Listar os recursos\n" +"Se se fornece SECCIÓN, só se listarán os recursos desta sección\n" +"Se se fornece RUTA, só se listarán os recursos que coincidan" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FICHEIRO [RUTA]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECCIÓN" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Listar os recursos con detalles\n" +"Se se fornece SECCIÓN, só se listarán os recursos desta sección\n" +"Se se fornece RUTA, só se listarán os recursos que coincidan\n" +"Os detalles inclúen a sección, tamaño e compresión" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extraer un ficheiro de recurso a stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FICHEIRO RUTA" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gresource [--section SECCIÓN] ORDE [ARGS...]\n" +"\n" +"Ordes:\n" +" help Mostra esta información\n" +" sections Mostra as seccións do recurso\n" +" list Mostra os recursos\n" +" details Mostra os recursos con detalles\n" +" extract Extraer un recurso\n" +"\n" +"Use 'gresource help ORDE' para obter axuda detallada.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECCIÓN Un nome de sección elf (opcional)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " ORDE A orde que explicar (opcional)\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" FICHEIRO Un ficheiro elf (un binario ou biblioteca compartida)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FICHEIRO Un ficheiro elf (un binario ou unha biblioteca compartida)\n" +" ou un ficheiro de recurso compilado\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[RUTA]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " RUTA Unha ruta (optional) de recurso (pode ser parcial)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CAMIÑO" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " RUTA Unha ruta dun recurso\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Non existe o esquema «%s»\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "O esquema «%s» non pode reposicionarse (non debe especificar a ruta)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "O esquema «%s» pode reposicionarse (debe especificarse a ruta)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Forneceuse unha ruta baleira.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "A ruta debe comezar cunha barra (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "A ruta debe rematar cunha barra (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "A ruta non debe conter dúas barras adxacentes (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "O valor fornecido está fora do intervalo válido\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Esta chave non é escribíbel\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Lista dos esquemas instalados (non reposicionábeis)" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Lista dos esquemas instalados reposicionábeis" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Lista das claves de ESQUEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "ESQUEMA[:RUTA]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Lista dos fillos do SCHEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Lista as clave e valores, recursivamente\n" +"Se non se fornece un ESQUEMA, lista todas as claves\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESQUEMA[:RUTA]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Obtén o valor de CLAVE" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESQUEMA[:RUTA] CLAVE" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Consulta o intervalo de valores válidos de CLAVE" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Consulta a descrición para a CLAVE" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Estabelece o valor de CLAVE a VALOR" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESQUEMA[:RUTA] CLAVE VALOR" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Estabelece a CLAVE ao seu valor predeterminado" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" +"Restabelecer todas as claves nun ESQUEMA aos seus valores predeterminados" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Comproba se a CLAVE é escribíbel" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitorizar os cambios da CLAVE.\n" +"Se non se especifica a CLAVE, monitoriza todos os cambios en ESQUEMA.\n" +"Use ^C para deter a monitorización.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESQUEMA[:RUTA] [CLAVE]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings --version\n" +" gsettings [--schemadir CARTAFOL_ESQUEMA] COMANDO [ARGS…]\n" +"\n" +"Ordes:\n" +" help Mostra esta información\n" +" list-schemas Mostra os esquemas instalados\n" +" list-relocatable-schemas Mostra os esquemas instalados relocalizábeis\n" +" list-keys Mostra as claves dun esquema\n" +" list-children Mostra os fillos nun esquema\n" +" list-recursively Lista claves e valores, recursivamente\n" +" range Consulta o rango dunha chave\n" +" describe Consulta a descrición dunha chave\n" +" get Obtén os valores dunha clave\n" +" set Estabelece o valor dunha clave\n" +" reset Restabelece o valor dunha clave\n" +" reset-recursively Restabelecer todos os valores dun esquema " +"fornecido\n" +" writable Comproba se a clave é escribíbel\n" +" monitor Monitoriza cambios\n" +"\n" +"Use 'gsettings help ORDE' para obter máis axuda.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings [--schemadir DIRECTORIO_ESQUEMA] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " CARTAFOL_ESQUEMA: un directorio para buscar esquemas adicionais\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA O nome do esquema\n" +" KEY A ruta, para os esquemas reposicionábeis\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY A clave (opcional) no esquema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KEY A clave nun esquema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALUE O valor a estabelecer\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Non foi posíbel cargar os esquemas desde %s a %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Non hai esquemas instalados\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Forneceuse un nome de esquema baleiro\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Non existe a clave «%s»\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "O socket non é válido, non se inicializou" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "O socket non é válido, a inicialización fallou debido a: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "O fluxo de orixe xa está pechado" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Tempo de espera do Socket de E/S superado" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "creando o GSocket a partir de fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Non é posíbel crear o socket: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Especificouse unha familia descoñecida" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Especificouse un protocolo descoñecido" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Non é posíbel usar as operacións de datagramas nun socket que non é de " +"datagramas." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Non é posíbel usar operacións de datagramas nun socket con un tempo de " +"espera máximo estabelecido." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "non foi posíbel obter un enderezo local: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "non foi posíbel obter un enderezo remoto: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "non foi posíbel escoitar: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Produciuse un erro ao ligar co enderezo %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Produciuse un erro ao unirse ao grupo multicast: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Produciuse un erro ao deixar o grupo multicast: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Non se admite o multicast específico da fonte" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Familia de socket non admitida" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "o source-specific non é un enderezo IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Nome da interface demasiado larga" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interface non atopada: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Non se admite o multicast IPv4 específico da fonte" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Non se admite o multicast IPv6 específico da fonte" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Produciuse un erro ao aceptar a conexión: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Conexión en marcha" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Non é posíbel obter o erro pendente: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Produciuse un erro ao recibir datos: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Produciuse un erro ao enviar datos: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Non é posíbel desconectar o socket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Produciuse un erro ao pechar o socket: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Agardando pola situación do socket: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Non foi posíbel enviar a mensaxe: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Os vectores de mensaxes son moi largos" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Produciuse un erro ao enviar a mensaxe: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "O GSocketControlMessage non está permitido en Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Produciuse un erro ao recibir a mensaxe: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Non é posíbel ler as credenciais do socket: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials non está implementado para este sistema operativo" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Non foi posíbel conectarse ao servidor proxy %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Non foi posíbel conectar a %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Non foi posíbel conectar: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" +"Non se permite a conexión ao proxy mediante unha conexión que non sexa TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Non é posíbel usar o proxy co protocolo «%s»." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "O porto de escoita xa está pechado" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "O socket engadido está pechado" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 non ten compatibilidade para enderezos IPv6 «%s»" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "O nome de usuario é demasiado longo para o protocolo SOCKSv5" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "O nome do equipo «%s» é demasiado longo para o protocolo SOCKSv5" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "O servidor non é un servidor proxy SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "A conexión a través do servidor SOCKSv4 foi rexeitada" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "O servidor non é un servidor proxy SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "O proxy SOCKSv5 require autenticación." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 require un método de autenticación que non é compatíbel con GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"O nome de usuario ou contrasinal son demasiado longos para o protocolo " +"SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"A autenticación SOCKSv5 fallou debido a un nome de usuario ou contrasinal " +"incorrectos." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "O nome do equipo «%s» é demasiado longo para o protocolo SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "O servidor proxy SOCKSv5 usa un tipo de enderezo descoñecido." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Produciuse un erro interno no servidor proxy SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Non se permite a conexión SOCKSv5 debido ao conxunto de regras." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "O equipo non é atinxíbel mediante o servidor SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "A rede non é atinxíbel mediante o proxy SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Rexeitouse a conexión mediante o proxy SOCKSv5." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "O proxy SOCKSv5 non é compatíbel coa orde «connect»." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "O proxy SOCKSv5 non é compatíbel co tipo de enderezo fornecido." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Erro no proxy SOCKSv5 descoñecido." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Produciuse un erro ao crear a canalización para comunicarse co proceso fillo " +"(%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "As tuberías non están soportadas nesta plataforma" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Non é posíbel manipular a versión %d da codificación de GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Non se atopou ningún enderezo válido" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Produciuse un erro ao resolver inversamente «%s»: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "" +"Produciuse un erro ao analizar o rexistro DNS %s: paquete DNS mal formado" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Non hai un rexistro de DNS do tipo solicitado para «%s»" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Non é posíbel resolver temporalmente «%s»" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Produciuse un erro ao resolver «%s»" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Paquete DNS mal formado" + +#: gio/gthreadedresolver.c:886 +#, c-format +#| msgid "Failed to read from file “%sâ€: %s" +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Produciuse un erro ao analizar a resposta DNS para «%s»: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Non se atopou ningún certificado PEM codificado" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Non foi posíbel descifrar a chave privada codificada con PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Non foi posíbel analizar a chave privada PEM codificada" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Non se atopou ningún certificado PEM codificado" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Non foi posíbel analizar o certificado PEM codificado" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "O backend TLS actual non é admite PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Este GTlsBackend non admite a creación de certificados PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Esta é a última oportunidade para escribir o contrasinal correctamente antes " +"de que se bloquee o acceso." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Escribiu varias veces o contrasinal incorrecto, se falla de novo bloquearase " +"o acceso." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "O contrasinal introducido é incorrecto." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Non se permite enviar o FD" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Esperando 1 mensaxe de control, obtívose %d" +msgstr[1] "Esperando 1 mensaxe de control, obtivéronse %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Tipo de datos subsidiarios inesperados" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Esperando un descritor de ficheiro (fd), pero obtívose %d\n" +msgstr[1] "Esperando un descritor de ficheiro (fd), pero obtivéronse %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Recibiuse un descritor de ficheiro (fd) incorrecto" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Non se permite a recepción de FD" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Produciuse un erro ao enviar as credenciais: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"Produciuse un erro ao comprobar se SO_PASSCRED está activado para o socket: " +"%s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Produciuse un erro ao activar SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Esperábase ler un só byte para recibir as credenciais pero léronse creo bytes" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Non se esperaba unha mensaxe de control, pero obtívose %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Produciuse un erro ao desactivar SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Produciuse un erro ao ler do descritor do ficheiro: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Produciuse un erro ao pechar o descritor do ficheiro: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Raíz do sistema de ficheiros" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Produciuse un erro ao escribir no descritor do ficheiro: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Neste sistema non se permiten enderezos de socket de dominios UNIX abstractos" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "o volume non implementa a expulsión" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "o volume non implementa a «eject» ou «eject_with_operation»" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Produciuse un erro ao ler do manexador: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Produciuse un erro ao pechar o manexador: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Produciuse un erro ao escribir no manexador: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Sen memoria dabondo" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Erro interno: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Necesítase máis entrada" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Datos comprimidos incorrectos" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Enderezo no que escoitar" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorado, para compatibilidade con GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Imprimir enderezo" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Imprimir enderezo en modo consola" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Executar servizo dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Argumentos incorrectos\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Atributo «%s» inesperado para o elemento «%s»" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Non se atopou o atributo «%s» do elemento «%s»" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Etiqueta «%s» inesperada, esperábase a etiqueta «%s»" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Etiqueta «%s» inesperada dentro de «%s»" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Data/Hora «%s» non válida no ficheiro de marcador" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Non foi posíbel atopar un ficheiro de marcadores válido nos directorios de " +"datos" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Xa existe un marcador para o URI «%s»" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Non se atopou ningún marcador para o URI «%s»" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Non hai ningún tipo MIME definido no marcador para o URI «%s»" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Non se definiu ningún parámetro privado no marcador para o URI «%s»" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Non existe ningún grupo definido no marcador para o URI «%s»" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Ningunha aplicación denominada «%s» rexistrou un marcador para «%s»" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Produciuse un erro ao expandir a liña executábel «%s» co URI «%s»" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Carácter non representábel na entrada da conversión" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Hai unha secuencia de carácter parcial ao final da entrada" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" +"Non é posíbel converter o modo de emerxencia «%s» na codificación de " +"caracteres «%s»" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Byte NUL incrustado na entrada de conversión" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Byte NUL incrustado na saída de conversión" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "O URI «%s» non é un URI absoluto usando o esquema «file»" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "O URI do ficheiro local «%s» non pode incluír un «#»" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "O URI «%s» non é válido" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "O nome de host do URI «%s» non é válido" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "O URI «%s» contén caracteres de escape non válidos" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "O nome da ruta «%s» non é un camiño absoluto" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %H:%M:%S, %e de %B de %Y" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Xaneiro" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Febreiro" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Marzo" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Abril" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Maio" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Xuño" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Xullo" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Agosto" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Setembro" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Outubro" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Novembro" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Decembro" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Xan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Abr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Maio" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Xuño" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Xul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ago" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Out" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Luns" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Martes" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Mércores" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Xoves" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Venres" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sábado" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Domingo" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Lun" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Mar" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mer" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Xov" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Ven" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sáb" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Dom" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Xaneiro" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Febreiro" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Marzo" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "Abril" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Maio" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Xuño" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Xullo" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "Agosto" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Setembro" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Outubro" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "Novembro" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Decembro" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Xan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Abr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Xuñ" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Xul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ago" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Out" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dec" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Produciuse un erro ao abrir o directorio «%s»: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Non foi posíbel asignar %lu byte para ler o ficheiro «%s»" +msgstr[1] "Non foi posíbel asignar %lu bytes para ler o ficheiro «%s»" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Produciuse un erro ao ler o ficheiro «%s»: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "O ficheiro «%s» é demasiado grande" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Produciuse un erro ao ler desde o ficheiro «%s»: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Produciuse un erro ao abrir o ficheiro «%s»: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Produciuse un erro ao obter os atributos do ficheiro «%s»: fstat() fallou: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Produciuse un erro ao abrir o ficheiro «%s»: fdopen() fallou: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Produciuse un erro ao renomear o ficheiro «%s» como «%s»: g_rename() fallou: " +"%s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Produciuse un erro ao escribir o ficheiro «%s»: write() fallou: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Produciuse un erro ao escribir o ficheiro «%s»: fsync() fallou: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Produciuse un erro ao crear o ficheiro «%s»: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Non foi posíbel retirar o ficheiro existente «%s»: g_unlink() fallou: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "O modelo «%s» non é válido, non debería conter «%s»" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "O modelo «%s» non contén XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Produciuse un erro ao ler a ligazón simbólica «%s»: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Non foi posíbel abrir o conversor de «%s» a «%s»: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Non é posíbel facer unha lectura en bruto en g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Datos restantes non convertidos no búfer de lectura" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "O canal termina nun carácter parcial" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Non é posíbel facer unha lectura en bruto en g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Non é posíbel atopar un ficheiro de clave correcto nos directorios de busca" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Non é un ficheiro normal" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"O ficheiro clave contén a liña «%s» que non é un par valor-clave, grupo ou " +"comentario" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nome de grupo non válido: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "O ficheiro clave non comeza cun grupo" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nome de chave non válido: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "O ficheiro clave contén unha codificación non permitida «%s»" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "O ficheiro clave non ten un grupo «%s»" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "O ficheiro clave non ten a clave «%s» no grupo «%s»" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "O ficheiro clave contén a clave «%s» co valor «%s» que non é UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"O ficheiro clave contén a clave «%s» que ten un valor que non é posíbel " +"interpretar." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"O ficheiro clave contén a clave «%s» no grupo «%s» que ten un valor que non " +"é posíbel interpretar." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "A clave «%s» do grupo «%s» ten o valor «%s», pero agardábase %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "O ficheiro clave contén un carácter de escape ao final da liña" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "O ficheiro clave contén a secuencia de escape non válida «%s»" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Non é posíbel interpretar o valor «%s» como un número." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "O valor enteiro «%s» está fóra do intervalo" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Non é posíbel interpretar o valor «%s» como un número flotante." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Non é posíbel interpretar o valor «%s» como un booleano." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Produciuse un erro ao obter os atributos do ficheiro «%s%s%s%s»: fstat() " +"fallou: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Produciuse un erro ao mapear «%s%s%s%s»: mmap() fallou: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Produciuse un erro ao abrir o ficheiro «%s»: open() fallou: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Erro na liña %d carácter %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "O texto do nome codificado en UTF-8 non é válido - «%s» non válido" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "«%s» non é un nome válido" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "«%s» non é un nome válido: '%c'" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Erro na liña %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Produciuse un erro ao analizar '%-.*s', que debería ser un díxito dentro " +"dunha referencia de carácter (por exemplo ê) - pode que o díxito sexa " +"grande de máis" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"A referencia de carácter non remataba con punto e coma, probabelmente " +"utilizou un carácter & sen intención de comezar unha entidade - escape o & " +"como &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "A referencia de carácter «%-.*s» non codifica un carácter permitido" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Detectada unha entidade baleira «&;»; as entidades válidas son: & " " +"< > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Non se coñece o nome de entidade «%-.*s»" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"A entidade non remata cun punto e coma, probabelmente usou o carácter & sen " +"a intención de comezar unha entidade, escriba o & como &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "O documento debe comezar cun elemento (por exemplo )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"«%s» non é un carácter válido despois dun carácter «<»; non pode iniciar un " +"nome de elemento" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Carácter estraño «%s», esperábase un carácter «>» para pechar a etiqueta de " +"elemento baleiro «%s»" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Hai demasiados atributos no elemento «%s»" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Carácter estraño «%s», esperábase un «=» despois do nome do atributo «%s» do " +"elemento «%s»" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Carácter estraño «%s», esperábase un carácter «>» ou «/» para pechar a " +"etiqueta de comezo do elemento «%s» ou opcionalmente un atributo; quizais " +"usou un carácter non válido no nome dun atributo" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Carácter estraño «%s», esperábase unhas comiñas de apertura despois do signo " +"igual para dar un valor ao atributo «%s» do elemento «%s»" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"«%s» non é un carácter válido despois do nome de elemento de peche «%s»; o " +"carácter permitido é «>»" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Pechouse o elemento «%s», actualmente non hai ningún elemento aberto" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Pechouse o elemento «%s», mais o elemento aberto actualmente é «%s»" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "O documento estaba baleiro ou só contiña espazos en branco" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "O documento rematou inesperadamente despois dun símbolo menor que «<»" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"O documento rematou inesperadamente con elementos aínda abertos - «%s» foi o " +"último elemento aberto" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"O documento rematou inesperadamente, esperábase ver un símbolo maior que '>' " +"que pechase a etiqueta <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "O documento rematou inesperadamente dentro dun nome de elemento" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "O documento rematou inesperadamente dentro dun nome de atributo" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"O documento rematou inesperadamente dentro dunha etiqueta de comezo de " +"elemento." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"O documento rematou inesperadamente despois do signo igual que segue a un " +"nome de atributo; non hai valor de atributo" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "O documento rematou inesperadamente dentro dun valor de atributo" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"O documento rematou inesperadamente dentro da etiqueta que pechaba o " +"elemento «%s»" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"O documento rematou inesperadamente dentro da etiqueta que pechaba o " +"elemento «%s»" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"O documento rematou inesperadamente dentro dun comentario ou instrución de " +"procesamento" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPCIÓN…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opcións de axuda:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Mostrar as opcións de axuda" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Mostrar todas as opcións de axuda" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opcións da aplicación:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opcións:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Non é posíbel analizar o valor enteiro «%s» para %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "O valor enteiro «%s» para %s está fóra do intervalo" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Non é posíbel analizar o valor \"double\" «%s» para %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "O valor \"double\" «%s» para %s está fóra do intervalo" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Produciuse un erro ao analizar a opción %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Argumento que falta para %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Opción %s descoñecida" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "obxecto danado" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "erro interno ou obxecto danado" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "sen memoria" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "alcanzouse o límite de \"backtracking\"" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "o patrón contén elementos non permitidos na coincidencia parcial" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "erro interno" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"as referencias anteriores como condicións non se permiten na coincidencia " +"parcial" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "atinxiuse o límite de recursividade" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "combinación non válida de marcas de liña nova" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "desprazamento erróneo" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "UTF8 curto" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "bucle de repetición" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "erro descoñecido" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ ao final do patrón" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c ao final do patrón" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "carácter non recoñecido despois de \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "números fóra do intervalo no cuantificador {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "número demasiado grande no cuantificador {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "falta a terminación ] para a clase de carácter" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "secuencia de escape non válida na clase de carácter" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "intervalo fóra de orde na clase de carácter" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nada que repetir" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "repetición inesperada" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "carácter non recoñecido despois de (? ou (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "As clases de nomes POSIX só se permiten dentro dunha clase" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "falta o ) de terminación" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referencia a un subpatrón non existente" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "falta un ) despois do comentario" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "a expresión regular é demasiado longa" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "produciuse un erro ao obter a memoria" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") sen ( que o abra" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "desbordamento de código" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "carácter non recoñecido despois de (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "a aserción lockbehind non ten unha lonxitude fixa" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "número ou nome formado incorrectamente despois de (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "o grupo condicional contén máis de dúas ramas" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "esperábase unha aserción despois de (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ou os díxitos (?[+-] deben estar seguidos por )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nome de clase POSIX descoñecida" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "Os elementos de colación POSIX non se admiten" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "o valor do carácter na secuencia \\x{…} é demasiado longo" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condición non válida (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "non se permite \\C en asercións lookbehind" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "as secuencias de escape \\L, \\l, \\N{nome}, \\U, e \\u non se admiten" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "unha chamada recursiva pode crear un bucle infinito" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "carácter non recoñecido despois de (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "falta a terminación no nome do subpatrón" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dous subpatróns teñen o mesmo nome" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "secuencia \\P ou \\p formada incorrectamente" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nome de propiedade descoñecido despois de \\P ou \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "o nome do subpatrón é demasiado longo (máximo 32 caracteres)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "demasiados subpatróns con nome (máximo 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "o valor octal é maior que \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "desbordouse o espazo de traballo de compilación" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "non se atopou o subpatrón referenciado comprobado previamente" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "O grupo DEFINE contén máis dunha rama" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opcións NEWLINE inconsistentes" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g non está seguido por un nome entre chaves, corchetes angulares ou un " +"número entre comiñas, ou por un número simple" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "unha referencia co número non pode ser cero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "non se permite un argumento para (*ACCEPT), (*FAIL), ou (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) no recoñecido" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "o número é demasiado grande" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "falta o nome do subpatrón despois de (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "agardábase un díxito despois de (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] é un carácter de datos non válido no modo de compatibilidade de JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "non se permiten diferentes nomes para subpatróns do mesmo número" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) debe ter un argumento" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c debe estar seguido dun carácter ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k non está seguido por un nome entre chaves, corchetes angulares ou entre " +"comiñas" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "non se permite \\N nunha clase" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "demasiadas referencias cara adiante" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "o nome é demasiado longo en (*MARK), (*PRUNE), (*SKIP), ou (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "o valor do carácter na secuencia \\u.... é demasiado longo" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" +"Produciuse un erro ao estabelecer a equivalencia da expresión regular %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "A biblioteca PCRE está compilada sen compatibilidade con UTF8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"A biblioteca PCRE está compilada sen compatibilidade con propiedades UTF8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "A biblioteca PCRE está compilada con opcións non compatíbeis" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Produciuse un erro ao optimizar a expresión regular %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"Produciuse un erro ao compilar a expresión regular %s no carácter %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "esperábase un díxito hexadecimal ou '}'" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "esperábase un díxito hexadecimal" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "falta «<» na referencia simbólica" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "referencia simbólica sen finalizar" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "referencia simbólica de lonxitude cero" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "esperábase un díxito" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "referencia simbólica ilegal" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "«\\» final perdido" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "secuencia de escape descoñecida" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Produciuse un erro ao analizar o texto de substitución «%s» no carácter %lu: " +"%s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "O texto citado non comeza con comiñas" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Comiñas non pechadas na liña de ordes ou noutro texto citado nun intérprete " +"de ordes" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "O texto rematou despois dun carácter «\\». (O texto era «%s»)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"O texto rematou antes de atopar a comiña final para %c. (O texto era «%s»)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "O texto estaba baleiro (ou só contiña espazos en branco)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Produciuse un erro ao ler datos desde un proceso fillo (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Produciuse un erro ao ler os datos dun proceso fillo (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Erro inesperado en waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "O proceso fillo rematou co código %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "O proceso fillo rematou polo sinal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "O proceso fillo detívose polo sinal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "O proceso fillo rematou de forma anormal" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Produciuse un erro ao ler desde a canalización filla (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Produciuse un erro ao executar o proceso fillo «%s» (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Produciuse un erro ao facer fork (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Produciuse un erro ao cambiar ao directorio «%s» (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Produciuse un erro ao executar o proceso fillo «%s» (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" +"Produciuse un erro ao abrir o ficheiro para remapear o descritor de ficheiro " +"(%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "" +"Produciuse un erro ao duplicar o descritor de ficheiro para o proceso fillo " +"(%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Produciuse un erro ao facer fork ao proceso fillo (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "" +"Produciuse un erro ao pechar o descritor de ficheiro para o proceso fillo " +"(%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Produciuse un erro descoñecido ao executar o proceso fillo «%s»" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Fallo de lectura de suficientes datos desde a canalización filla co PID (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Produciuse un erro ao ler datos desde un proceso fillo" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Produciuse un erro ao executar o proceso fillo (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Produciuse un erro ao facer dup() no proceso fillo (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nome de programa non válido: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Cadea non válida no vector de argumento en %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Cadea non válida no ambiente: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Directorio de traballo non válido: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Produciuse un erro ao executar o programa asistente (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Erro inesperado en g_io_channel_win32_poll() ao ler datos desde un proceso " +"fillo" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "A cadea baleira non é un número" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "«%s» non é un número con signo" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "O número «%s» está fóra de rango [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "«%s» non é un número sen signo" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-encoding non válida na URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Carácter ilegal na URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caracteres non UTF-8 na URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Enderezo IPv6 non válido «%.*s» na URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Enderezo IP codificado ilegal «%.*s» na URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nome de equipo internacionalizado ilegal «%.*s» na URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Non foi posíbel analizar «%.*s» como unha URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "O porto «%.*s» na URI está fóra do intervalo" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "A URI «%s» non é unha URI absoluta" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "A URI «%s» non ten o compoñente de equipo" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "A URI non é absoluta, e non se forneceu unha URI base" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Falta «=» e o valor de parámetro" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Produciuse un erro ao reservar memoria" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Carácter fóra do intervalo para UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Secuencia non válida na entrada da conversión" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Carácter fóra de intervalo para UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bit" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Non é posíbel ler /var/lib/dbus/machine-id ou /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Erro descoñecido ao conectar" diff --git a/po/gu.po b/po/gu.po new file mode 100644 index 0000000..e84ae57 --- /dev/null +++ b/po/gu.po @@ -0,0 +1,4666 @@ +# translation of gu.po to Gujarati +# Ankit Patel , 2005, 2006. +# Ankit Patel , 2007, 2008. +# Sweta Kothari , 2009, 2010, 2011, 2012, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: gu\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug." +"cgi?product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-12-10 18:43+0000\n" +"PO-Revision-Date: 2014-12-11 09:29+0530\n" +"Last-Translator: \n" +"Language-Team: American English \n" +"Language: gu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" + +#: ../gio/gapplication.c:520 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication સેવા સà«àª¥àª¿àª¤àª¿àª¨à«‡ દાખલ કરો (D-Bus સેવા ફાઇલોમાંથી વાપરો)" + +#: ../gio/gapplication.c:525 +msgid "GApplication options" +msgstr "GApplication વિકલà«àªªà«‹" + +#: ../gio/gapplication.c:525 +msgid "Show GApplication options" +msgstr "GApplication વિકલà«àªªà«‹àª¨à«‡ બતાવો" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:485 ../gio/gsettings-tool.c:521 +msgid "Print help" +msgstr "મદદને છાપો" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:486 +#: ../gio/gresource-tool.c:554 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "આવૃતà«àª¤àª¿àª¨à«‡ છાપો" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:527 +msgid "Print version information and exit" +msgstr "આવૃતà«àª¤àª¿ જાણકારીને છાપો અને બહાર નીકળો" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "કારà«àª¯àª•à«àª°àª®à«‹àª¨à«€ યાદી" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"સà«àª¥àª¾àªªàª¿àª¤ થયેલ D-Bus સકà«àª°àª¿àª¯ કરી શકાય તેવાં કારà«àª¯àª•à«àª°àª®à«‹àª¨à«€ યાદી કરો (.desktop ફાઇલો " +"દà«àª¦àª¾àª°àª¾)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "કારà«àª¯àª•à«àª°àª®àª¨à«‡ શરૂ કરો" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "કારà«àª¯àª•à«àª°àª®àª¨à«‡ શરૂ કરો (ખોલવા માટે વૈકલà«àªªàª¿àª• ફાઇલો સાથે)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "કà«àª°àª¿àª¯àª¾àª¨à«‡ સકà«àª°àª¿àª¯ કરો" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "કારà«àª¯àª•à«àª°àª® પર કà«àª°àª¿àª¯àª¾àª¨à«‡ બોલાવો" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "ઉપલબà«àª§ કà«àª°àª¿àª¯àª¾àª“ની યાદી કરો" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "કારà«àª¯àª•à«àª°àª® માટે સà«àª¥àª¿àª° કà«àª°àª¿àª¯àª¾àª“ની યાદી (.desktop ફાઇલ માંથી)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "તેની માટે વિગત થયેલ મદદને છાપવા માટે આદેશ" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus બંધારણમાં કારà«àª¯àª•à«àª°àª® ઓળખકરà«àª¤àª¾(દાત: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:492 +#: ../gio/gresource-tool.c:558 +msgid "FILE" +msgstr "FILE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "વૈકલà«àªªàª¿àª• સંબંધિ અથવા સંબંધી ફાઇલનામો, અથવા ખોલવા માટે URIs" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "કà«àª°àª¿àª¯àª¾" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "બોલાવા માટે કà«àª°àª¿àª¯àª¾ નામ" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "પરિમાણ" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "કà«àª°àª¿àª¯àª¾àª¨à«‡ બોલાવા માટે વૈકલà«àªªàª¿àª• પરિમાણ, GVarian બંધારણમાં" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:523 +#: ../gio/gsettings-tool.c:607 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"અજà«àªžàª¾àª¤ આદેશ %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "વપરાશ:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:548 +#: ../gio/gsettings-tool.c:641 +msgid "Arguments:\n" +msgstr "દલીલો:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "આદેશો:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"વિગત થયેલ મદદને મેળવવા માટે '%s help COMMAND' વાપરો.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"સીધૠઅનૂસરવા માટે %s આદેશને કારà«àª¯àª•à«àª°àª® id ની જરૂરિયાત છે\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "અયોગà«àª¯ કારà«àª¯àª•à«àª°àª® id: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' દલીલો લેતૠનથી\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus ને જોડાવાનà«àª‚ અસમરà«àª¥: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "કારà«àª¯àª•à«àª°àª®àª®àª¾àª‚ %s સંદેશાને મોકલતી વખતે ભૂલ: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "કà«àª°àª¿àª¯àª¾ નામ ઠકારà«àª¯àª•à«àª°àª® id પછી આપેલ હોવૠજ જોઇàª\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"અયોગà«àª¯ કà«àª°àª¿àª¯àª¾ નામ: '%s'\n" +"કà«àª°àª¿àª¯àª¾ નામો ફકà«àª¤ આલà«àª«àª¾àª¨à«àª¯à«‚મેરિક, '-' and '.' ને સમાવવૠજ જોઇàª\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "કà«àª°àª¿àª¯àª¾ પરિમાણને પદચà«àª›à«‡àª¦àª¨ કરતી વખતે ભૂલ: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "કà«àª°àª¿àª¯àª¾àª“ મહતà«àª¤àª® àªàª• પરિમાણને સà«àªµà«€àª•ારે છે\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "list-actions આદેશ ઠફકà«àª¤ કારà«àª¯àª•à«àª°àª® id ને લે છે" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "કારà«àª¯àª•à«àª°àª® %s માટે ડેસà«àª•ટોપ ફાઇલને શોધવામાં અસમરà«àª¥\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"અજà«àªžàª¾àª¤ આદેશ: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:376 +#: ../gio/ginputstream.c:614 ../gio/ginputstream.c:1013 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:830 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s ને ખૂબ મોટી ગણક કિંમત પસાર કરેલ છે" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "સીક ઠમૂળ સà«àªŸà«àª°à«€àª® પર આધારભૂત નથી" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream કાપી શકાતૠનથી" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1202 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1654 +msgid "Stream is already closed" +msgstr "સà«àªŸà«àª°à«€àª® પહેલાથી જ બંધ થઈ ગયેલ છે" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "ટà«àª°àª¨à«àª•ેટ ઠમૂળ સà«àªŸà«àª°à«€àª® પર આધારભૂત નથી" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "પà«àª°àª•à«àª°àª¿àª¯àª¾ રદ થઈ ગઈ હતી" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "અયોગà«àª¯ ઓબà«àªœà«‡àª•à«àªŸ, પà«àª°àª¾àª°àª‚ભ થયેલ નથી" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "ઇનપà«àªŸàª®àª¾àª‚ અસંપૂરà«àª£ મલà«àªŸà«€àª¬àª¾àª‡àªŸ કતાર" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "લકà«àª·à«àª¯àª®àª¾àª‚ પૂરતી જગà«àª¯àª¾ નથી" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "રà«àªªàª¾àª‚તર ઈનપà«àªŸàª¨à«€ બાઇડ શà«àª°à«‡àª£à«€ અપà«àª°àª®àª¾àª£à«€àª¤ છે" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "રà«àªªàª¾àª‚તર વખતે ભૂલ: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "રદ કરી શકાય તેવૠપà«àª°àª¾àª°àª‚ભ આધારભૂત નથી" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "'%s' અકà«àª·àª° સમૂહમાંથી '%s' માં રà«àªªàª¾àª‚તરણ માટે આધાર નથી" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' માંથી '%s' માટેનો પરીવરà«àª¤àª• ખોલી શકતો નથી" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s પà«àª°àª•ાર" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "અજà«àªžàª¾àª¤ પà«àª°àª•ાર" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s ફાઈલપà«àª°àª•ાર" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials ઠઆ OS પર અમલીકરણ થયેલ નથી" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "તમારાં પà«àª²à«‡àªŸàª«à«‹àª°à«àª® માટે GCredentials આધાર નથી" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials ઠઆ OS પર પà«àª°àª•à«àª°àª¿àª¯àª¾ ID ને સમાવતૠનથી" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "શà«àª°à«‡àª¯ સà«àªªà«àª«à«€àª‚ગ આ OS પર શકà«àª¯àª¾ નથી" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "સà«àªŸà«àª°à«€àª®àª¨à«‹-અંત અનિચà«àª›àª¨à«€àª¯ રીતે જલદી" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "સરનામાં નોંધણી '%s' માં બિનઆધારભૂત કી '%s'" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "સરનામà«àª‚ '%s' અમાનà«àª¯ છે (ફકà«àª¤ àªàª• પાથની જરૂર છે, tmpdir અથવા àªàª¬àª¸à«àªŸà«àª°à«‡àª• કી)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "સરનામાં નોંધણી '%s' માં મતલબવગરની કી/કિંમત જોડી સંયોજન" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "સરનામà«àª‚ '%s' માં ભૂલ - પોરà«àªŸ ગà«àª£àª§àª°à«àª® મેલફોરà«àª® થયેલ છે" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "સરનામà«àª‚ '%s' માં ભૂલ - કà«àªŸà«àª‚બ ગà«àª£àª§àª°à«àª® મેલફોરà«àª® થયેલ છે" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "સરનામાં ઘટક '%s' વિરામચિહà«àª¨ (:) ને સમાવતૠનથી" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "કી/કિંમત જોડી %d, '%s', સરનામાં ઘટક '%s' માં સરખા ચિહà«àª¨àª¨à«‡ સમાવાતૠનથી" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "કી/કિંમત જોડી %d, '%s', સરનામાં ઘટક '%s' માં કી અથવા કિંમતને નીકાળતી ન વખતે ભૂલ" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"સરનામાં '%s' માં ભૂલ - unix પરિવહન સà«àª¯à«‹àªœàª¿àª¤ કરવા માટે 'path' અથવા 'abstract' નાં " +"àªàª•ની જરૂર છે" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "સરનામાં '%s' માં ભૂલ - યજમાન ગà«àª£àª§àª°à«àª® ગેરહાજર અથવા મેલફોરà«àª® થયેલ છે" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "સરનામાં '%s' માં ભૂલ - પોરà«àªŸ ગà«àª£àª§àª°à«àª® ગેરહાજર અથવા મેલફોરà«àª® થયેલ છે" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "સરનામાં '%s' માં ભૂલ - noncefile ગà«àª£àª§àª°à«àª® ગેરહાજર અથવા મેલફોરà«àª® થયેલ છે" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "સà«àªµàª¯àª‚ શરૂ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: " + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "સરનામà«àª‚ '%s' માટે અજà«àªžàª¾àª¤ અથવા બિનઆધારભૂત ટà«àª°àª¾àª¨à«àª¸àªªà«‹àª°à«àªŸ '%s'" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "nonce ફાઇલ '%s' ને ખોલી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "nonce ફાઇલ '%s' માંથી વાંચી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "nonce ફાઇલ '%s' માંથી વાંચી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ, ઇચà«àª›àª¿àª¤ 16 બાઇટ છે, %d મળà«àª¯à«" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "સà«àªŸà«àª°à«€àª®àª®àª¾àª‚ nonce ફાઇલ '%s' નાં સમાવિષà«àªŸà«‹àª¨à«‡ લખી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "આપેલ સરનામà«àª‚ ખાલી છે" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "સંદેશા બસ સà«àªªà«‰àª¨ કરી શકાતૠનથી જà«àª¯àª¾àª°à«‡ setuid છે" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "મશીન-id વગર સંદેશા બસ સà«àªªà«‰àª¨ કરી શકાતૠનથી: " + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "આદેશ વાકà«àª¯ '%s' સà«àªªà«‰àª¨ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: " + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(આ વિનà«àª¡à«‹àª¨à«‡ બંધ કરવા માટે કોઇપણ અકà«àª·àª°àª¨à«‡ ટાઇપ કરો)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "સતà«àª° dbus ચાલી રહà«àª¯à« નથી, અને autolaunch નિષà«àª«àª³" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "સતà«àª° બસ સરનામાંને નકà«àª•à«€ કરી શકાતૠનથી (આ OS માટે અમલીકરણ થયેલ નથી)" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"DBUS_STARTER_BUS_TYPE પરà«àª¯àª¾àªµàª°àª£ ચલમાંથી બસ સરનામà«àª‚ નકà«àª•à«€ કરી શકાતૠનથી - અજà«àªžàª¾àª¤ કિંમત " +"'%s'" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "બસ સરનામà«àª‚ નકà«àª•à«€ કરી શકાતૠનથી કારણ કે DBUS_STARTER_BUS_TYPE પરà«àª¯àª¾àªµàª°àª£ ચલ સà«àª¯à«‹àªœàª¿àª¤ નથી" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "અજà«àªžàª¾àª¤ બસ પà«àª°àª•ાર %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "વાકà«àª¯àª¨à«‡ વાંચવાનો પà«àª°àª¯àª¤à«àª¨ કરવા અનિચà«àª›àª¿àª¤ ઓછા સમાવિષà«àªŸ" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "વાકà«àª¯àª¨à«‡ (સલામત) રીતે વાંચવાનો પà«àª°àª¯àª¤à«àª¨ કરવા અનિચà«àª›àª¿àª¤ ઓછા સમાવિષà«àªŸ" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "બધી ઉપલબà«àª§ સતà«àª¤àª¾àª§àª¿àª•રણ પદà«àª§àª¤àª¿àª“ ફેંકી દીધી (પà«àª°àª¯àª¤à«àª¨ થયેલ છે: %s) (ઉપલબà«àª§: %s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer મારફતે રદ થયેલ છે" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "જà«àª¯àª¾àª°à«‡ ડિરેકà«àªŸàª°à«€ '%s' માટે જાણકારીને મેળવી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ : %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "ડિરેકà«àªŸàª°à«€ '%s' પર પરવાનગીઓ મેલફોરà«àª® થયેલ છે. ઇચà«àª›àª¿àª¤ સà«àª¥àª¿àª¤àª¿ 0700, 0%o મળà«àª¯à«" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "ડિરેકà«àªŸàª°à«€ '%s' ને બનાવી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "વાંચવા માટે કીરીંગ '%s' ને ખોલી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "કીરીંગનà«àª‚ વાકà«àª¯ %d ઠસમાવિષà«àªŸ '%s' સાથે '%s' પર મેલફોરà«àª® થયેલ છે" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "કીરીંગના વાકà«àª¯ %d ની પà«àª°àª¥àª® ટોકન ઠસમાવિષà«àªŸ '%s' સાથે '%s' પર મેલફોરà«àª® થયેલ છે" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "કીરીંગનà«àª‚ વાકà«àª¯ %d ની બીજી ટોકન સમાવિષà«àªŸ '%s' સાથે '%s' પર મેલફોરà«àª® થયેલ છે" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "id %d સાથે '%s' પર કીરીંગમાં કà«àª•à«€ શોધી ન હતી" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "સà«àªŸà«…લ તાળૠફાઇલ '%s' ને કાઢી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "તાળૠફાઇલ '%s' ને બનાવી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "(કડી ન થયેલ) તાળૠફાઇલ '%s' ને બંધ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "તાળૠફાઇલ '%s' કડી ન કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "લખવા માટે કીરીંગ '%s' ને ખોલી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(વધà«àª®àª¾àª‚, '%s' માટે તાળૠખોલી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ પણ નિષà«àª«àª³àª¤àª¾: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "જોડાણ બંધ થયેલ છે" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "સમયસમાપà«àª¤àª¿ પહોંચી ગઇ" + +#: ../gio/gdbusconnection.c:2577 +msgid "Unsupported flags encountered when constructing a client-side connection" +msgstr "બિનઆધારભૂત ફà«àª²à«‡àª— મળà«àª¯à«‹ જà«àª¯àª¾àª°à«‡ કà«àª²àª¾àª‡àª¨à«àªŸ બાજà«àª¨à«àª‚ જોડાણને બંધારિત કરી રહà«àª¯àª¾ હોય" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "પાથ %s પર ઓબà«àªœà«‡àª•à«àªŸ પર આવો ઇનà«àªŸàª°àª«à«‡àª¸ 'org.freedesktop.DBus.Properties' નથી" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "આવો પà«àª°à«‰àªªàª°à«àªŸà«€ '%s' નથી" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "ગà«àª£àª§àª°à«àª® '%s' વાંચી શકાય તેમ નથી" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "ગà«àª£àª§àª°à«àª® '%s' લખી શકાય તેમ નથી" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "ગà«àª£àª§àª°à«àª® '%s' સà«àª¯à«‹àªœàª¿àª¤ કરતી વખતે ભૂલ: ઇચà«àª›àª¿àª¤ પà«àª°àª•ાર '%s' પરંતà«t '%s' મળà«àª¯à«" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "આવો ઇનà«àªŸàª°àª«à«‡àª¸ '%s' નથી" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "આવો ઇનà«àªŸàª°àª«à«‡àª¸ નથી" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "પાથ %s પર ઑબà«àªœà«‡àª•à«àªŸ પર આવો ઇનà«àªŸàª°àª«à«‡àª¸ '%s' નથી" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "આવી પદà«àª¦àª¤àª¿ '%s' નથી" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "સંદેશા '%s' નો પà«àª°àª•ાર, ઇચà«àª›àª¿àª¤ પà«àª°àª•ાર '%s' બંધબેસતૠનથી" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "ઓબà«àªœà«‡àª•à«àªŸ ઠ%s પર ઇનà«àªŸàª°àª«à«‡àª¸ %s માટે પહેલેથી જ નિકાસ થયેલ છે" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "પદà«àª¦àª¤àª¿ '%s' ને પà«àª°àª•ાર '%s' પાછો મળેલ થે, પરંતૠઇચà«àª›àª¿àª¤ '%s' છે" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "હસà«àª¤àª¾àª•à«àª·àª° '%s' સાથે ઇનà«àªŸàª°àª«à«‡àª¸ '%s' પર પદà«àª¦àª¤àª¿ '%s' અસà«àª¤àª¿àª¤à«àªµ ધરાવતૠનથી" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "સબટà«àª°à«€ પહેલેથી %s માટે નિકાસ થયેલ છે" + +#: ../gio/gdbusmessage.c:1244 +msgid "type is INVALID" +msgstr "પà«àª°àª•ાર INVALID છે" + +#: ../gio/gdbusmessage.c:1255 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL સંદેશો: PATH અથવા MEMBER હેડર કà«àª·à«‡àª¤à«àª° ગેરહાજર છે" + +#: ../gio/gdbusmessage.c:1266 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN સંદેશો: REPLY_SERIAL હેડર કà«àª·à«‡àª¤à«àª° ગેરહાજર છે" + +#: ../gio/gdbusmessage.c:1278 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR સંદેશો: REPLY_SERIAL અથવા ERROR_NAME હેડર કà«àª·à«‡àª¤à«àª° ગેરહાજર છે" + +#: ../gio/gdbusmessage.c:1291 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL સંદેશો: PATH, INTERFACE અથવા MEMBER હેડર કà«àª·à«‡àª¤à«àª° ગેરહાજર છે" + +#: ../gio/gdbusmessage.c:1299 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL સંદેશો: PATH હેડર કà«àª·à«‡àª¤à«àª° આરકà«àª·àª¿àª¤ કિંમત /org/freedesktop/DBus/Local ને વાપરી " +"રહà«àª¯àª¾ છે" + +#: ../gio/gdbusmessage.c:1307 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL સંદેશો: INTERFACE હેડર કà«àª·à«‡àª¤à«àª° ઠઆરકà«àª·àª¿àª¤ કિંમત org.freedesktop.DBus.Local ને " +"વાપરી રહà«àª¯àª¾ છે" + +#: ../gio/gdbusmessage.c:1355 ../gio/gdbusmessage.c:1415 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu બાઇટને વાંચવાની ઇચà«àª›àª¾ રાખેલ છે પરંતૠ%lu મળà«àª¯à«" +msgstr[1] "%lu બાઇટને વાંચવાની ઇચà«àª›àª¾ રાખેલ છે પરંતૠ%lu મળà«àª¯à«" + +#: ../gio/gdbusmessage.c:1369 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "શબà«àª¦àª®àª¾àª³àª¾ '%s' પછી ઇચà«àª›àª¿àª¤ NUL બાઇટ પરંતૠબાઇટ %d મળà«àª¯à«" + +#: ../gio/gdbusmessage.c:1388 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"ઇચà«àª›àª¿àª¤ માનà«àª¯ UTF-8 શબà«àª¦àª®àª¾àª³àª¾ પરંતૠબાઇટ ઓફસેટ %d પર અમાનà«àª¯ બાઇટ મળà«àª¯à« (શબà«àª¦àª®àª¾àª³àª¾àª¨à«€ લંબાઇ " +"%d છે). માનà«àª¯ UTF-8 શબà«àª¦àª®àª¾àª³àª¾ તà«àª¯àª¾àª‚ સà«àª§à«€ છે કે બિંદૠ'%s' હતà«" + +#: ../gio/gdbusmessage.c:1587 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "પદચà«àª›à«‡àª¦àª¨ થયેલ કિંમત '%s' ઠયોગà«àª¯ D-Bus ઓબà«àªœà«‡àª•à«àªŸ પાથ નથી" + +#: ../gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "પદચà«àª›à«‡àª¦àª¨ થયેલ '%s' ઠયોગà«àª¯ D-Bus હસà«àª¤àª¾àª•à«àª·àª° નથી" + +#: ../gio/gdbusmessage.c:1656 +#, c-format +msgid "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "લંબાઇ %u બાઇટની મળેલ àªàª°à«‡. મહતà«àª¤àª® લંબાઇ 2<<26 બાઇટ (64 MiB) છે." +msgstr[1] "લંબાઇ %u બાઇટની મળેલ àªàª°à«‡. મહતà«àª¤àª® લંબાઇ 2<<26 બાઇટ (64 MiB) છે" + +#: ../gio/gdbusmessage.c:1676 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"પà«àª°àª•ાર 'a%c' ની શોધાયેલ àªàª°à«‡, %u બાઇટને બહà«àªµàª¿àª§ લંબાઇ હોય તેવી અપેકà«àª·àª¾ રાખેલ છે, પરંતૠ" +"લંબાઇમાં %u બાઇટ મળી" + +#: ../gio/gdbusmessage.c:1843 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "પદચà«àª›à«‡àª¦àª¨ કિંમત '%s' ભિનà«àª¨àª¤àª¾ માટે માનà«àª¯ D-Bus હસà«àª¤àª¾àª•à«àª·àª° નથી" + +#: ../gio/gdbusmessage.c:1867 +#, c-format +msgid "Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"D-Bus વાયર બંધારણમાં શબà«àª¦àª®àª¾àª³àª¾ પà«àª°àª•ાર '%s' સાથે GVariant ને કà«àª°àª®àª®àª¾àª‚ ન કરી રહà«àª¯àª¾ હોય " +"તà«àª¯àª¾àª°à«‡ ભૂલ" + +#: ../gio/gdbusmessage.c:2051 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "અયોગà«àª¯ endianness કિંમત. ઇચà«àª›àª¿àª¤ 0x6c ('l') અથવા 0x42 ('B') પરંતૠકિંમત 0x%02x મળી" + +#: ../gio/gdbusmessage.c:2064 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "અયોગà«àª¯ મà«àª–à«àª¯ પà«àª°à«‹àªŸà«‹àª•ોલ આવૃતà«àª¤àª¿. ઇચà«àª›àª¿àª¤ 1 પરંતૠ%d મળà«àª¯à«" + +#: ../gio/gdbusmessage.c:2120 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "હસà«àª¤àª¾àª•à«àª·àª° '%s' સાથે હસà«àª¤àª¾àª•à«àª·àª° હેડર મળà«àª¯à« પરંતૠસંદેશા બૉડી ખાલી છે" + +#: ../gio/gdbusmessage.c:2134 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "પદચà«àª›à«‡àª¦àª¨ કિંમત '%s' ઠમાનà«àª¯ D-Bus હસà«àª¤àª¾àª•à«àª·àª° નથી (બૉડી માટે)" + +#: ../gio/gdbusmessage.c:2164 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "સંદેશામાં હસà«àª¤àª¾àª•à«àª·àª° હેડર નથી પરંતૠસંદેશા બૉડી ઠ%u બાઇટ છે" +msgstr[1] "સંદેશામાં હસà«àª¤àª¾àª•à«àª·àª° હેડર નથી પરંતૠસંદેશા બૉડી ઠ%u બાઇટ છે" + +#: ../gio/gdbusmessage.c:2174 +msgid "Cannot deserialize message: " +msgstr "સંદેશા કà«àª°àª®àª®àª¾àª‚ કરી શકાતૠનથી:" + +#: ../gio/gdbusmessage.c:2515 +#, c-format +msgid "Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"D-Bus વાયર બંધારણમાં શબà«àª¦àª®àª¾àª³àª¾ પà«àª°àª•ાર '%s' સાથે GVariant ને કà«àª°àª®àª®àª¾àª‚ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ " +"ભૂલ" + +#: ../gio/gdbusmessage.c:2652 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"સંદેશા પાસે %d ફાઇલ વરà«àª£àª¨àª•રà«àª¤àª¾ છે પરંતૠહેડર કà«àª·à«‡àª¤à«àª° ઠ%d ફાઇલ વરà«àª£àª¨àª•રà«àª¤àª¾àª¨à«‡ સૂચિત કરે છે" + +#: ../gio/gdbusmessage.c:2660 +msgid "Cannot serialize message: " +msgstr "સંદેશાને કà«àª°àª®àª®àª¾àª‚ કરી શકાતૠનથી: " + +#: ../gio/gdbusmessage.c:2704 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "સંદેશા બૉડી પાસે હસà«àª¤àª¾àª•à«àª·àª° '%s' છે પરંતૠતà«àª¯àª¾àª‚ હસà«àª¤àª¾àª•à«àª·àª° હેડર નથી" + +#: ../gio/gdbusmessage.c:2714 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "સંદેશા બૉડી પાસે હસà«àª¤àª¾àª•à«àª·àª° પà«àª°àª•ાર '%s' છે પરંતૠહેડર કà«àª·à«‡àª¤à«àª°àª®àª¾àª‚ હસà«àª¤àª¾àª•à«àª·àª° '%s' છે" + +#: ../gio/gdbusmessage.c:2730 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "સંદેશા બૉડી ઠખાલી છે પરંતૠહેડર કà«àª·à«‡àª¤à«àª°àª®àª¾àª‚ હસà«àª¤àª¾àª•à«àª·àª° '(%s)' છે" + +#: ../gio/gdbusmessage.c:3280 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "પà«àª°àª•ાર '%s' નાં બૉડી સાથે પાછૠલાવતી વખતે ભૂલ" + +#: ../gio/gdbusmessage.c:3288 +msgid "Error return with empty body" +msgstr "ખાલી બૉડી સાથે ભૂલ પાછી આવી" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "હારà«àª¡àªµà«‡àª° રૂપરેખાને મેળવવાનૠઅસમરà«àª¥: %s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "/var/lib/dbus/machine-id અથવા /etc/machine-id લાવવાનà«àª‚ અસમરà«àª¥: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s માટે StartServiceByName કોલ કરતી વખતે ભૂલ: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "અનિચà«àª›àª¨à«€àª¯ જવાબ %d StartServiceByName(\"%s\") પદà«àª¦àª¤àª¿àª®àª¾àª‚થી" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"પદà«àª¦àª¤àª¿àª¨à«‡ બોલાવી શકાતી નથી; પà«àª°à«‹àª•à«àª¸à«€ ઠમાલિક વગર સારી રીતે જાણીતી છે અને પà«àª°à«‹àª•à«àª¸à«€ " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START ફà«àª²à«‡àª— સાથે બંધારિત થયેલ હતà«" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "àªàª¬à«àª¸à«àªŸà«àª°à«‡àª• નામ જગà«àª¯àª¾ આધારભૂત નથી" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "nonce ફાઇલને સà«àªªàª·à«àªŸ કરી શકાતૠનથી જà«àª¯àª¾àª°à«‡ સરà«àªµàª°àª¨à«‡ બનાવી રહà«àª¯àª¾ છે" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' પર nonce ફાઇલને લખી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "શબà«àª¦àª®àª¾àª³àª¾ '%s' ઠયોગà«àª¯ D-Bus GUID નથી" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "બિનઆધારભૂત ટà«àª°àª¾àª¨à«àª¸àªªà«‹àª°à«àªŸ '%s' પર સાંભળી શકાતૠનથી" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"આદેશ:\n" +" help આ જાણકારીને બતાવે છે\n" +" introspect દૂરસà«àª¥ ઑબà«àªœà«‡àª•à«àªŸàª¨à«àª‚ આતà«àª®àª¨àª¿àª°à«€àª•à«àª·àª£ કરે છે\n" +" monitor દૂરસà«àª¥ ઑબà«àªœà«‡àª•à«àªŸàª¨à«àª‚ મોનિટર કરે છે\n" +" call દૂરસà«àª¥ ઑબà«àªœà«‡àª•à«àªŸ પર પદà«àª¦àª¤àª¿àª¨à«‡ બોલાવે છે\n" +" emit સંકેતને કાઢે છે\n" +"\n" +"દરેક આદેશ પર મદદને મેળવવા માટે \"%s COMMAND --help\" વાપરો.\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "ભૂલ: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "આતà«àª®àª¨àª¿àª°à«€àª•à«àª·àª£ XML નà«àª‚ પદચà«àª›à«‡àª¦àª¨ કરતી વખતે ભૂલ: %s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "સિસà«àªŸàª® બસ સાથે જોડાવો" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "સતà«àª° બસ સાથે જોડાવો" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "આપેલ D-Bus સરનામાં જોડાવ" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "àªàª¨à«àª¡àªªà«‹àª‡àª‚ટ વિકલà«àªªà«‹àª¨à«àª‚ જોડાણ:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "વિકલà«àªªà«‹ જોડાણ અંતિમબિંદà«àª¨à«‡ સà«àªªàª·à«àªŸ કરી રહà«àª¯àª¾ છે" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "જોડાણ àªàª¨à«àª¡àªªà«‹àª‡àª‚ટ સà«àªªàª·à«àªŸ થયેલ નથી" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "ઘણાં જોડાણ àªàª¨à«àª¡àªªà«‹àª‡àª‚ટ સà«àªªàª·à«àªŸ થયેલ છે" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "ચેતવણી: આતà«àª®àª¨àª¿àª°à«€àª•à«àª·àª£ માહિતીને અનà«àª¸àª¾àª°, ઇનà«àªŸàª°àª«à«‡àª¸ '%s' અસà«àª¤àª¿àª¤à«àªµàª®àª¾àª‚ નથી\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"ચેતવણી: આતà«àª®àª¨àª¿àª°à«€àª•à«àª·àª£ માહિતીને અનà«àª¸àª¾àª°, પદà«àª¦àª¤àª¿ '%s' ઠઇનà«àªŸàª°àª«à«‡àª¸ '%s' પર અસà«àª¤àª¿àª¤à«àªµàª®àª¾àª‚ નથી\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "સંકેત માટે વૈકલà«àªªàª¿àª• લકà«àª·à«àª¯ (અનનà«àª¯ નામ)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "તેની પર સંકેતને કાઢવા માટે ઑબà«àªœà«‡àª•à«àªŸ પાથ" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "સંકેત અને ઇનà«àªŸàª°àª«à«‡àª¸ નામ" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "સંકેતને બહાર કાઢે છે." + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "જોડાઇ રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "ભૂલ: ઑબà«àªœà«‡àª•à«àªŸ પાથ સà«àªªàª·à«àªŸ થયેલ નથી.\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "ભૂલ: %s ઠયોગà«àª¯ ઑબà«àªœà«‡àª•à«àªŸ પાથ નથી\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "ભૂલ: સંકેત સà«àªªàª·à«àªŸ થયેલ નથી.\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "ભૂલ: સંકેત સંપૂરà«àª£ ગà«àª£àªµàª¤à«àª¤àª¾àªµàª¾àª³à«àª‚ નામ હોવૠજ જોઇàª.\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "ભૂલ: %s ઠયોગà«àª¯ ઇનà«àªŸàª°àª«à«‡àª¸ નામ નથી\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "ભૂલ: %s ઠયોગà«àª¯ સભà«àª¯ નામ નથી\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "ભૂલ: %s ઠયોગà«àª¯ અનનà«àª¯ બસ નામ નથી.\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "પરિમાણ %d ને પદચà«àª›à«‡àª¦àª¨ કરતી વખતે ભૂલ: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "જોડાણને કાઢી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "તેની પર પદà«àª¦àª¤àª¿ બોલાવવા માટે લકà«àª·à«àª¯ નામ" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "તેની પર પદà«àª¦àª¤àª¿àª¨à«‡ બોલાવવા માટે ઓબà«àªœà«‡àª•à«àªŸ પાથ" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "પદà«àª¦àª¤àª¿ અને ઇનà«àªŸàª°àª«à«‡àª¸ નામ" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "સેકંડોમાં સમયસમાપà«àª¤àª¿" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "દૂરસà«àª¥ ઓબà«àªœà«‡àª•à«àªŸ પર પદà«àª¦àª¤àª¿àª¨à«‡ બોલાવો." + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "ભૂલ: લકà«àª·à«àª¯ સà«àªªàª·à«àªŸ થયેલ નથી\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "ભૂલ: ઑબà«àªœà«‡àª•à«àªŸ પાથ સà«àªªàª·à«àªŸ થયેલ નથી\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "ભૂલ: પદà«àª¦àª¤àª¿ નામ સà«àªªàª·à«àªŸ થયેલ નથી\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "ભૂલ: પદà«àª¦àª¤àª¿ નામ '%s' અયોગà«àª¯ છે\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "પરિમાણ %d પà«àª°àª•ાર '%s' નાં પદચà«àª›à«‡àª¦àª¨ કરતી વખતે ભૂલ: %s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "નિરીકà«àª·àª¾ કરવા માટે લકà«àª·à«àª¯ નામ" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "નિરીકà«àª·àª¾ કરવા માટે ઓબà«àªœà«‡àª•à«àªŸ પાથ" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "XML છાપો" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "બાળકનà«àª‚ આતà«àª®àª¨àª¿àª°à«€àª•à«àª·àª£ કરે છે" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "ફકà«àª¤ પà«àª°àª¿àª¨à«àªŸ ગà«àª£àª§àª°à«àª®à«‹" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "દૂરસà«àª¥ ઓબà«àªœà«‡àª•à«àªŸàª¨à«àª‚ નિરીકà«àª·àª£ કરો." + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "મોનિટર કરવા માટે લકà«àª·à«àª¯ પાથ" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "મોનિટર કરવા માટે ઑબà«àªœà«‡àª•à«àªŸ પાથ" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "દૂરસà«àª¥ ઑબà«àªœà«‡àª•à«àªŸàª¨à«‡ મોનિટર કરો." + +#: ../gio/gdesktopappinfo.c:1999 ../gio/gdesktopappinfo.c:4523 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "શીરà«àª·àª•વીહિન" + +#: ../gio/gdesktopappinfo.c:2408 +msgid "Desktop file didn't specify Exec field" +msgstr "ડેસà«àª•ટોપ ફાઈલે Exec કà«àª·à«‡àª¤à«àª° સà«àªªàª·à«àªŸ કરેલ નથી" + +#: ../gio/gdesktopappinfo.c:2693 +msgid "Unable to find terminal required for application" +msgstr "કારà«àª¯àª•à«àª°àª® માટે જરૂરી ટરà«àª®àª¿àª¨àª² શોધવામાં અસમરà«àª¥" + +#: ../gio/gdesktopappinfo.c:3114 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "વપરાશકરà«àª¤àª¾ કારà«àª¯àª•à«àª°àª® રૂપરેખાંકન ફોલà«àª¡àª° %s બનાવી શકà«àª¯àª¾ નહિં: %s" + +#: ../gio/gdesktopappinfo.c:3118 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "વપરાશકરà«àª¤àª¾ MIME રૂપરેખાંકન ફોલà«àª¡àª° %s બનાવી શકà«àª¯àª¾ નહિં: %s" + +#: ../gio/gdesktopappinfo.c:3358 ../gio/gdesktopappinfo.c:3382 +msgid "Application information lacks an identifier" +msgstr "કારà«àª¯àª•à«àª°àª® જાણકારીને ઓળખકરà«àª¤àª¾àª¨à«‹ અભાવ છે" + +#: ../gio/gdesktopappinfo.c:3615 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "વપરાશકરà«àª¤àª¾ ડેસà«àª•ટોપ ફાઈલ %s બનાવી શકતા નથી" + +#: ../gio/gdesktopappinfo.c:3749 +#, c-format +msgid "Custom definition for %s" +msgstr "%s માટે વૈવિધà«àª¯àªªà«‚રà«àª£ વà«àª¯àª¾àª–à«àª¯àª¾" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "ડà«àª°àª¾àªˆàªµàª° બહાર કાઢો અમલમાં મૂકતà«àª‚ નથી" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "ડà«àª°àª¾àª‡àªµ ઠeject અથવા eject_with_operation નà«àª‚ અમલીકરણ કરતૠનથી" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "ડà«àª°àª¾àªˆàªµ મીડિયા માટે પોલીંગને અમલમાં મૂકતà«àª‚ નથી" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "ડà«àª°àª¾àªˆàªµ શરૂ કરો નà«àª‚ અમલીકરમ કરતૠનથી" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "ડà«àª°àª¾àª‡àªµ ઠબંધ કરોનà«àª‚ અમલીકરણ કરતૠનથી" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS આધાર ઉપલબà«àª§ નથી" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem àªàª¨àª•ોડીંગ ની આવૃતà«àª¤àª¿ %d ને સંભાળી શકાતી નથી" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem àªàª¨àª•ોડીંગ માં ટોકનો (%d) ની મેલફોરà«àª® થયેલ નંબર" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon àªàª¨àª•ોડીંગ નાં આવૃતà«àª¤àª¿ %d ને સંભાળી શકાતી નથી" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon àªàª¨àª•ોડીંગ માં ટોકનો (%d) ની મેલફોરà«àª® થયેલ નંબર" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon માટે GEmblem ઠઅપેકà«àª·àª¿àª¤ છે" + +#: ../gio/gfile.c:962 ../gio/gfile.c:1200 ../gio/gfile.c:1338 +#: ../gio/gfile.c:1576 ../gio/gfile.c:1631 ../gio/gfile.c:1689 +#: ../gio/gfile.c:1773 ../gio/gfile.c:1830 ../gio/gfile.c:1894 +#: ../gio/gfile.c:1949 ../gio/gfile.c:3597 ../gio/gfile.c:3652 +#: ../gio/gfile.c:3859 ../gio/gfile.c:3901 ../gio/gfile.c:4364 +#: ../gio/gfile.c:4775 ../gio/gfile.c:4860 ../gio/gfile.c:4950 +#: ../gio/gfile.c:5047 ../gio/gfile.c:5134 ../gio/gfile.c:5235 +#: ../gio/gfile.c:7754 ../gio/gfile.c:7844 ../gio/gfile.c:7928 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "પà«àª°àª•à«àª°àª¿àª¯àª¾ આધારભૂત નથી" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1461 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "સમાવનાર માઉનà«àªŸ અસà«àª¤àª¿àª¤à«àªµàª®àª¾àª‚ નથી" + +#: ../gio/gfile.c:2508 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "ડિરેકà«àªŸàª°à«€ ઉપર નકલ કરી શકતા નથી" + +#: ../gio/gfile.c:2568 +msgid "Can't copy directory over directory" +msgstr "ડિરેકà«àªŸàª°à«€àª¨à«‡ ડિરેકà«àªŸàª°à«€ ઉપર નકલ કરી શકતા નથી" + +#: ../gio/gfile.c:2576 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "લકà«àª·à«àª¯ ફાઈલ અસà«àª¤àª¿àª¤à«àªµàª®àª¾àª‚ નથી" + +#: ../gio/gfile.c:2595 +msgid "Can't recursively copy directory" +msgstr "પà«àª¨àª°àª¾àªµàª°à«àª¤àª¿àª¤ રીતે ડિરેકà«àªŸàª°à«€àª¨à«€ નકલ કરી શકતા નથી" + +#: ../gio/gfile.c:2877 +msgid "Splice not supported" +msgstr "જોડવાનà«àª‚ આધારભૂત નથી" + +#: ../gio/gfile.c:2881 +#, c-format +msgid "Error splicing file: %s" +msgstr "ફાઈલ ને જોડવામાં ભૂલ: %s" + +#: ../gio/gfile.c:3012 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "નકલ (સંદરà«àª­àª•ડી/કà«àª²à«‹àª¨) માઉનà«àªŸ વચà«àªšà«‡ આધારભૂત નથી" + +#: ../gio/gfile.c:3016 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "નકલ (સંદરà«àª­àª•ડી/કà«àª²à«‹àª¨) આધારભૂત નથી અથવા અયોગà«àª¯ છે" + +#: ../gio/gfile.c:3021 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "નકલ (સંદરà«àª­àª•ડી/કà«àª²à«‹àª¨) આધારભૂત નથી અથવા કામ કરતી નથી" + +#: ../gio/gfile.c:3084 +msgid "Can't copy special file" +msgstr "વિશિષà«àªŸ ફાઇલ ની નકલ કરી શકતા નથી" + +#: ../gio/gfile.c:3849 +msgid "Invalid symlink value given" +msgstr "અયોગà«àª¯ સાંકેતિક કડી કિંમત અપાયેલ છે" + +#: ../gio/gfile.c:4010 +msgid "Trash not supported" +msgstr "કચરાપેટી આધારભૂત નથી" + +#: ../gio/gfile.c:4122 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ફાઈલ નામો '%c' સમાવી શકતા નથી" + +#: ../gio/gfile.c:6546 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "વોલà«àª¯à«àª® માઉનà«àªŸ અમલમાં મૂકતà«àª‚ નથી" + +#: ../gio/gfile.c:6655 +msgid "No application is registered as handling this file" +msgstr "આ ફાઈલ સંભાળવા માટે કોઈ કારà«àª¯àª•à«àª°àª® રજીસà«àªŸàª° થયેલ નથી" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "ઈનà«àª¯à«‚મેરેટર બંધ થયેલ છે" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ફાઈલ ઈનà«àª¯à«‚મેરેટરને ભરપૂર પà«àª°àª•à«àª°àª¿àª¯àª¾ છે" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ફાઈલ ઈનà«àª¯à«‚મેરેટર પહેલાથી જ બંધ થયેલ છે" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon àªàª¨àª•ોડીંગ ની આવૃતà«àª¤àª¿ %d ને સંભાળી શકાતી નથી" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon માટે મેલફોરà«àª® થયેલ ઇનપà«àªŸ માહિતી" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "સà«àªŸà«àª°à«€àª® query_info ને આધાર આપતà«àª‚ નથી" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "સà«àªŸà«àª°à«€àª® પર પહોંચવાનà«àª‚ આધારભૂત નથી" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ઈનપà«àªŸ સà«àªŸà«àª°à«€àª® પર કાપવાનà«àª‚ માનà«àª¯ નથી" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "સà«àªŸà«àª°à«€àª® પર કાપવાનà«àª‚ માનà«àª¯ નથી" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "ટોકનો (%d) નાં ખોટા નંબર" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "વરà«àª— નામ %s માટે પà«àª°àª•ાર નથી" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "પà«àª°àª•ાર %s ઠGIcon ઇનà«àªŸàª°àª«à«‡àª¸ ને અમલમાં મૂકતો નથી" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "પà«àª°àª•ાર %s ઠવરà«àª— થયેલ નથી" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "મેલફોરà«àª® થયેલ આવૃતà«àª¤àª¿ નંબર: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "પà«àª°àª•ાર %s ઠGIcon ઇનà«àªŸàª°àª«à«‡àª¸ પર tokens() માંથી અમલીકરણ થતૠનથી (_t)" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "આઇકોન àªàª¨àª•ોડીંગ ની પૂરી પાડેલ આવૃતà«àª¤àª¿ ને સંભાળી શકાતી નથી" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "સરનામà«àª‚ સà«àªªàª·à«àªŸ થયેલ નથી" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "લંબાઇ %u સરનામાં માટે ઘણૠલાંબૠછે" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "પૂરà«àªµàª— લંબાઇ બહાર સરનામાં પાસે બીટ સà«àª¯à«‹àªœàª¨ છે" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "IP સરનામાં માસà«àª• તરીકે '%s' નૠપદચà«àª›à«‡àª¦àª¨ કરી શકà«àª¯àª¾ નહિં" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "સોકેટ સરનામાં માટે પૂરતી જગà«àª¯àª¾ નથી" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "બિનઆધારિત સોકેટ સરનામà«àª‚" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "ઈનપà«àªŸ સà«àªŸà«àª°à«€àª® વાંચનને અમલમાં મૂકતà«àª‚ નથી" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1212 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1664 +msgid "Stream has outstanding operation" +msgstr "સà«àªŸà«àª°à«€àª®àª¨à«‡ ભરપૂર પà«àª°àª•à«àª°àª¿àª¯àª¾ છે" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "ઘટક <%s> અંદર પરવાનગી થયેલ નથી <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "ઘટક <%s> ઊંચા સà«àª¤àª°à«‡ પરવાનગી થયેલ નથી" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "ફાઇલ %s ઠસà«àª¤à«àª°à«‹àª¤àª®àª¾àª‚ ઘણો સમય દેખાય છે" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "કોઇપણ સà«àª¤à«àª°à«‹àª¤ ડિરેકà«àªŸàª°à«€àª®àª¾àª‚ '%s' ને સà«àª¥àª¿àª¤ કરવામાં નિષà«àª«àª³àª¤àª¾" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "વરà«àª¤àª®àª¾àª¨ ડિરેકà«àªŸàª°à«€àª®àª¾àª‚ '%s' ને સà«àª¥àª¿àª¤ કરવામાં નિષà«àª«àª³àª¤àª¾" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "અજà«àªžàª¾àª¤ પà«àª°àª•à«àª°àª¿àª¯àª¾ વિકલà«àªª \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "temp ફાઇલને બનાવવામાં નિષà«àª«àª³àª¤àª¾: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "ફાઇલ %s ને વાંચી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "ફાઇલ %s ને સંકોચી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "લખાણ કદાચ <%s> માં દેખાશે નહિં" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "આઉટપà«àªŸ ફાઇલનૠનામ" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "ડિરેકà«àªŸàª°à«€àª“ જà«àª¯àª¾àª‚ ફાઇલો ઓ તેમાંથી વંચાય છે (હાલની ડિરેકà«àªŸàª°à«€ માટે મૂળભૂત)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:591 +msgid "Generate output in the format selected for by the target filename extension" +msgstr "લકà«àª·à«àª¯ ફાઇલનામ àªàª•à«àª¸àªŸà«‡àª¨à«àª¶àª¨ દà«àª¦àª¾àª°àª¾ પસંદ થયેલ બંધારણમાં આઉટપà«àªŸ ઉતà«àªªàª¨à«àª¨ કરો" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "સà«àª¤à«àª°à«‹àª¤ હેડરને ઉતà«àªªàª¨à«àª¨ કરો" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "તમારા કોડમાં સà«àª¤à«àª°à«‹àª¤ ફાઇલમાં કડી કરવા માટે વાપરેલ સà«àª¤à«àª°à«‹àª¤àª•ોડને ઉતà«àªªàª¨à«àª¨ કરો" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "નિરà«àª­àª°àª¤àª¾ યાદી બનાવો" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "સà«àª¤à«àª°à«‹àª¤àª¨à«‡ આપમેળે બનાવી અને રજીસà«àªŸàª° કરà«àª¯à« નહિં" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "વિધેયોનો નિકાસ કરો નહિં; તેઓને G_GNUC_INTERNAL રજૂ કરો" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "ઉતà«àªªàª¨à«àª¨ થયેલ સà«àª¤à«àª°à«‹àª¤ કરો માટે વાપરેલ C ઓળખકરà«àª¤àª¾ નામ" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"સà«àª¤à«àª°à«‹àª¤ ફાઇલમાં સà«àª¤à«àª°à«‹àª¤ સà«àªªàª·à«àªŸà«€àª•રણને કમà«àªªàª¾àª‡àª² કરો.\n" +"સà«àª¤à«àª°à«‹àª¤ સà«àªªàª·à«àªŸà«€àª•રણ ફાઇલો પાસે àªàª•à«àª¸àªŸà«‡àª¨à«àª¶àª¨ .gresource.xml છે,\n" +"અને સà«àª¤à«àª°à«‹àª¤ ફાઇલ પાસે .gresource કહેવાતૠàªàª•à«àª¸àªŸà«‡àª¨à«àª¶àª¨ છે." + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "તમારે àªàª• ડિરેકà«àªŸàª°à«€ નામ આપવૠજ જોઇàª\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "ખાલી નામોને પરવાનગી આપેલ નથી" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "અયોગà«àª¯ નામ '%s': નામો નાનાં અકà«àª·àª°à«‹àª¥à«€ જ શરૂ થવા જોઇàª" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"અયોગà«àª¯ નામ '%s': અયોગà«àª¯ અકà«àª·àª° '%c'; ફકà«àª¤ નાનાં અકà«àª·àª°à«‹, નંબરોઅને હાઇફન ('-') ની " +"પરવાનગી મળેલ છે." + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "અમાનà«àª¯ નામ '%s': બે હાઇફન ('--') પરવાનગી મળેલ નથી." + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "અમાનà«àª¯ નામ '%s': છેલà«àª²à«‹ અકà«àª·àª° હાઇફન ('-') હોઇ શકે નહિં." + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "અયોગà«àª¯ નામ '%s': મહતà«àª¤àª® લંબાઇ 1024 છે" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " પહેલેથી જ સà«àªªàª·à«àªŸ થયેલ છે" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "'list-of' યોજનામાં કીઓને ઉમેરી શકાતી નથી" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " પહેલેથી સà«àªªàª·à«àªŸ થયેલ છે" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" માં શૅડો ; કિંમતને બદલવા માટે " +" વાપરો" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "'type', 'enum' અથવા 'flags' માનો àªàª• માં ગà«àª£àª§àª°à«àª® તરીકે સà«àªªàª·à«àªŸ થયેલ હોવો જ જોઇàª" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> હજૠવà«àª¯àª¾àª–à«àª¯àª¾àª¯àª¿àª¤ નથી." + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "અમાનà«àª¯ GVariant પà«àª°àª•ાર શબà«àª¦àª®àª¾àª³àª¾ '%s'" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " આપેલ છે પરંતૠયોજના કંઇપણ વિસà«àª¤àª¾àª°àª¤à« નથી" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "ઉપર લખવા માટે નથી" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " પહેલેથી સà«àªªàª·à«àªŸ થયેલ છે" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " પહેલેથી સà«àªªàª·à«àªŸ થયેલ છે" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " àªàª•à«àª¸àªŸà«‡àª¨à«àª¡ હજૠહાલની યોજના '%s' નથી" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " ઠહજૠહાલની યોજના '%s' ની યાદી નથી" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "પાથ સાથે યોજનાની યાદી કરી શકાતી નથી" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "પાથ સાથે યોજનાને વિસà«àª¤àª¾àª°à«€ શકાતૠનથી" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid " is a list, extending which is not a list" +msgstr " àªàª• યાદી છે, ને વિસà«àª¤àª¾àª°à«€ રહà«àª¯àª¾ છે કે જે યાદી નથી" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" ઠને વિસà«àª¤àª¾àª°à«‡ છે પરંતૠ" +"'%s' ઠ'%s' ને વિસà«àª¤àª¾àª°àª¤à« નથી" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "પાથ જો આપેલ હોય તો સà«àª²à«‡àª¶ સાથે શરૂ અને અંત હોવો જોઇàª" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "યાદીનો પાથે ':/' સાથે અંત થવો જ જોઇàª" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> પહેલેથી જ સà«àªªàª·à«àªŸ થયેલ છે" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "ટોચ સà«àª¤àª°à«‡ ઘટક <%s> પરવાનગી મળેલ નથી" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict સà«àªªàª·à«àªŸ થયેલ હતà«; અસà«àª¤àª¿àª¤à«àªµàª®àª¾àª‚ છે.\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "આખી ફાઇલને અવગણી દેવામાં આવી છે.\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "આ ફાઇલને અવગણી રહà«àª¯àª¾ છે.\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "ફાઇલ '%s' માં સà«àªªàª·à«àªŸ થયેલ પà«àª°àª®àª¾àª£à«‡ યોજના '%s' માં આવી કી '%s' નથી" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; આ કી માટે ઉપર લખવાનà«àª‚ અવગણી રહà«àª¯àª¾ છે.\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " અને --strict સà«àªªàª·à«àªŸ થયેલ હતà«; અસà«àª¤àª¿àª¤à«àªµàª®àª¾àª‚ છે.\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"ઓવરરાઇડ ફાઇલ '%s' માં સà«àªªàª·à«àªŸ થયેલ પà«àª°àª®àª¾àª£à«‡ યોજના '%s' માં કી '%s'નà«àª‚ પદચà«àª›à«‡àª¦àª¨ કરી રહà«àª¯àª¾ " +"હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s." + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "આ કી માટે ઉપર લખવાનà«àª‚ અવગણી રહà«àª¯àª¾ છે.\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"ઓવરરાઇડ ફાઇલ '%s' માં યોજના '%s' માં કી '%s' માટે ઓવરરાઇડ યોજનામાં આપેલ સીમાની " +"બહાર છે" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "ઓવરરાઇડ ફાઇલ '%s' માં યોજના '%s' માં કી '%s' માટે ઓવરરાઇડ માનà«àª¯ પસંદગીની યાદીમાં છે" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled ફાઇલને કà«àª¯àª¾àª‚ સંગà«àª°àª¹àªµà«" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "યોજનાઓમાં કોઇપણ ભૂલો પર કાઢી નાંખો" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled ફાઇલને લખો નહિં" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "કી નામ મરà«àª¯àª¾àª¦àª¾àª“ને દબાણ કરો નહિં" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"યોજના કેશમાં બધી GSettings યોજનાને કમà«àªªàª¾àª‡àª² કરો.\n" +"યોજના ફાઇલો પાસે àªàª•à«àª¸àªŸà«‡àª¨à«àª¶àª¨ .gschema.xml હોવૠજરૂરી છે અને કેશ ફાઇલ ઠgschemas." +"compiled તરીકે બોલાવાય છે." + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "તમારે àªàª• ડિરેકà«àªŸàª°à«€ નામ આપવૠજ જોઇàª\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "યોજના ફાઇલો મળી નથી: " + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "કઇ જ કરી રહà«àª¯àª¾ નથી.\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "હાલની આઉટપà«àªŸ ફાઇલને દૂર કરેલ છે.\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "મૂળભૂત સà«àª¥àª¾àª¨àª¿àª• ડિરેકà«àªŸàª°à«€ મોનીટર પà«àª°àª•ાર શોધવામાં અસમરà«àª¥" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "અયોગà«àª¯ ફાઈલનામ %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ફાઈલસિસà«àªŸàª® જાણકારી મેળવવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "રà«àªŸ ડિરેકà«àªŸàª°à«€àª¨à«àª‚ નામ બદલી શકતા નથી" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "ફાઈલનà«àª‚ નામ બદલવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "ફાઈલનà«àª‚ નામ બદલી શકતા નથી, ફાઈલનામ પહેલાથી જ હાજર છે" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "અયોગà«àª¯ ફાઈલનામ" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "ડિરેકà«àªŸàª°à«€ ખોલી શકતા નથી" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "ફાઈલ ખોલવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "ફાઈલ દૂર કરવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "ફાઈલને કચરાપેટીમાં નાંખવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "કચરાપેટી ડિરેકà«àªŸàª°à«€ %s બનાવવામાં અસમરà«àª¥: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "કચરાપેટી માટે ટોચસà«àª¤àª°àª¨à«€ ડિરેકà«àªŸàª°à«€ શોધવામાં અસમરà«àª¥" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "કચરાપેટી ડિરેકà«àªŸàª°à«€ શોધવામાં કે બનાવવામાં અસમરà«àª¥" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "કચરાપેટી જાણકારી ફાઈલ બનાવવામાં અસમરà«àª¥: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ફાઈલને કચરાપેટીમાં મોકલવામાં અસમરà«àª¥: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "આંતરિક ભૂલ" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "ડિરેકà«àªŸàª°à«€ બનાવવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ફાઇલસિસà«àªŸàª® ઠસાંકેતિક કડીને આધાર આપતૠનથી" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "સાંકેતિક કડી બનાવવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "ફાઈલ ખસેડવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "ડિરેકà«àªŸàª°à«€àª¨à«‡ ડિરેકà«àªŸàª°à«€ ઉપર ખસેડી શકતા નથી" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "બેકઅપ ફાઈલ બનાવટ નિષà«àª«àª³" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "લકà«àª·à«àª¯ ફાઈલ દૂર કરવામાં ભૂલ: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "માઉનà«àªŸà«‹ વચà«àªšà«‡ ખસેડવાનà«àª‚ આધારભૂત નથી" + +#: ../gio/glocalfile.c:2603 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s નાં ડિસà«àª• વપરાશને નકà«àª•à«€ કરી શકà«àª¯àª¾ નહિંય: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "લકà«àª·àª£ કિંમત બિન-શૂનà«àª¯ જ હોવી જોઈàª" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "અયોગà«àª¯ લકà«àª·àª£ પà«àª°àª•ાર (શબà«àª¦àª®àª¾àª³àª¾ ઈચà«àª›àª¿àª¤)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "અયોગà«àª¯ વિસà«àª¤à«ƒàª¤ લકà«àª·àª£ નામ" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "વિસà«àª¤à«ƒàª¤ લકà«àª·àª£ '%s' સà«àª¯à«‹àªœà«€àª¤ કરવામાં ભૂલ: %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (અયોગà«àª¯ સંગà«àª°àª¹àªªàª¦à«àª§àª¤àª¿)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "જà«àª¯àª¾àª°à«‡ ફાઇલ '%s' માટે જાણકારીને મેળવી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ : %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "જà«àª¯àª¾àª°à«‡ ફાઇલ વરà«àª£àª¨àª•રà«àª¤àª¾ માટે જાણકારીને મેળવી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "અયોગà«àª¯ લકà«àª·àª£ પà«àª°àª•ાર (uint32 ઈચà«àª›àª¿àª¤)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "અયોગà«àª¯ લકà«àª·àª£ પà«àª°àª•ાર (uint64 ઈચà«àª›àª¿àª¤)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "અયોગà«àª¯ લકà«àª·àª£ પà«àª°àª•ાર (બાઈટ શબà«àª¦àª®àª¾àª³àª¾ ઈચà«àª›àª¿àª¤)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "સંકેત કડીઓ પર પરવાનગીઓને સà«àª¯à«‹àªœàª¿àª¤ કરી શકાતી નથી" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "પરવાનગીઓ સà«àª¯à«‹àªœà«€àª¤ કરવામાં ભૂલ: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "માલિક સà«àª¯à«‹àªœà«€àª¤ કરવામાં ભૂલ: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "સાંકેતિક કડી non-NULL જ હોવી જોઈàª" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "સાંકેતિક કડી સà«àª¯à«‹àªœà«€àª¤ કરવામાં ભૂલ: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "સાંકેતિક કડી સà«àª¯à«‹àªœà«€àª¤ કરવામાં ભૂલ: ફાઈલ સાંકેતિક કડી નથી" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "બદલાવ અથવા પà«àª°àªµà«‡àª¶ સમય ને સà«àª¯à«‹àªœàª¨ કરતી વખતે ભૂલ: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux સંદરà«àª­ non-NULL જ હોવી જોઈàª" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux સંદરà«àª­ ને સà«àª¯à«‹àªœàª¨ કરવામાં ભૂલ: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "SELinux ઠઆ સિસà«àªŸàª® પર સકà«àª°àª¿àª¯ થયેલ નથી" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "લકà«àª·àª£ %s સà«àª¯à«‹àªœà«€àª¤ કરવાનà«àª‚ આધારભૂત નથી" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "ફાઈલમાંથી વાંચવામાં ભૂલ: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ફાઈલમાં પહોંચવામાં ભૂલ: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "ફાઈલ બંધ કરવામાં ભૂલ: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "મૂળભૂત સà«àª¥àª¾àª¨àª¿àª• ફાઈલ મોનીટર પà«àª°àª•ાર શોધવામાં અસમરà«àª¥" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "ફાઈલમાં લખવામાં ભૂલ: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "જૂની બેકઅપ કડી દૂર કરવામાં ભૂલ: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "બેકઅપ નકલ બનાવવામાં ભૂલ: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "કામચલાઉ ફાઈલનà«àª‚ નામ બદલવામાં ભૂલ: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "ફાઈલ કાપવામાં ભૂલ: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "ફાઈલ '%s' ખોલવામાં ભૂલ: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "લકà«àª·à«àª¯ ફાઈલ ડિરેકà«àªŸàª°à«€ છે" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "લકà«àª·à«àª¯ ફાઈલ નિયમિત ફાઈલ નથી" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "ફાઈલ બાહà«àª¯ રીતે સà«àª§àª¾àª°à«‡àª² હતી" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "જૂની ફાઇલને દૂર કરવા દરમà«àª¯àª¾àª¨ ભૂલ: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:769 +msgid "Invalid GSeekType supplied" +msgstr "અયોગà«àª¯ GSeekType પૂરà«àª‚ પાડેલ" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "અયોગà«àª¯ પહોંચ અરજી" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream કાપી શકતા નથી" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "મેમરી આઉટપà«àªŸ સà«àªŸà«àª°à«€àª®àª¨à«àª‚ માપ બદલી શકાય તેમ નથી" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "મેમરી આઉટપà«àªŸ સà«àªŸà«àª°à«€àª®àª¨à«àª‚ માપ બદલવામાં નિષà«àª«àª³" + +#: ../gio/gmemoryoutputstream.c:671 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "લખવાની પà«àª°àª•à«àª°àª¿àª¯àª¾ કરવા માટે જરૂરી મેમરી ઉપલબà«àª§ જગà«àª¯àª¾ કરતા વધારે છે" + +#: ../gio/gmemoryoutputstream.c:779 +msgid "Requested seek before the beginning of the stream" +msgstr "સà«àªŸà«àª°à«€àª®àª¨à«‡ શરૂ કરતા પહેલાં સીક સૂચના શોધેલ છે" + +#: ../gio/gmemoryoutputstream.c:794 +msgid "Requested seek beyond the end of the stream" +msgstr "સà«àªŸà«àª°à«€àª®àª¨àª¾àª‚ તળિયે સૂચના શોધેલ છે" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "માઉનà«àªŸ ઠ\"unmount\" ને અમલમાં મૂકતà«àª‚ નથી" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "માઉનà«àªŸ ઠ\"eject\" યને અમલમાં મૂકતà«àª‚ નથી" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "માઉનà«àªŸ ઠ\"unmount\" અથવા \"unmount_with_operation\" નà«àª‚ અમલીકરણ કરતૠનથી" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "માઉનà«àªŸ \"eject\" અથવા \"eject_with_operation\" નà«àª‚ અમલીકરણ કરતૠનથી" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "માઉનà«àªŸ \"remount\" ને અમલીકરણાં કરતૠનથી" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "માઉનà«àªŸ ઠસમાવિષà«àªŸ પà«àª°àª•ાર અંદાજિત કરવાનà«àª‚ અમલીકરણ કરતૠનથી" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "માઉનà«àªŸ ઠસમાવિષà«àªŸ પà«àª°àª•ાર અંદાજિત કરવાનà«àª‚ àªàª•à«€ સાથે અમલીકરણ કરતૠનથી" + +#: ../gio/gnetworkaddress.c:383 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "યજમાનનામ '%s' સમાવે છે '[' પરંતૠનથી ']'" + +#: ../gio/gnetworkmonitorbase.c:199 ../gio/gnetworkmonitorbase.c:302 +msgid "Network unreachable" +msgstr "નેટવરà«àª• પહોંચી શકે તેમ નથી" + +#: ../gio/gnetworkmonitorbase.c:237 ../gio/gnetworkmonitorbase.c:267 +msgid "Host unreachable" +msgstr "યજમાન પહોંચી શકે તેમ નથી" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "નેટવરà«àª• મોનિટરને બનાવી શકà«àª¯àª¾ નહિં: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "નેટવરà«àª• મોનિટરને બનાવી શકà«àª¯àª¾ નહિં: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "નેટવરà«àª• પરિસà«àª¥àª¿àª¤àª¿àª¨à«‡ મેળવી શકà«àª¯àª¾ નહિં: " + +#: ../gio/gnetworkmonitornm.c:263 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager આવૃતà«àª¤àª¿ ઘણી જૂની છે" + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:557 +msgid "Output stream doesn't implement write" +msgstr "આઉટપà«àªŸ સà«àªŸà«àª°à«€àª® લેખનને અમલમાં મૂકતà«àª‚ નથી" + +#: ../gio/goutputstream.c:518 ../gio/goutputstream.c:1218 +msgid "Source stream is already closed" +msgstr "સà«àª°à«‹àª¤ સà«àªŸà«àª°à«€àª® પહેલાથી જ બંધ થઈ ગયેલ છે" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' ને સà«àª§àª¾àª°à«€ રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' પર સà«àª¤à«àª°à«‹àª¤ અસà«àª¤àª¿àª¤à«àªµ ધરાવતૠનથી" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "સંકોચવા માટે '%s' પર સà«àª¤à«àª°à«‹àª¤ નિષà«àª«àª³ ગયà«" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "'%s' પર સà«àª¤à«àª°à«‹àª¤ ડિરેકà«àªŸàª°à«€ નથી" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "ઈનપà«àªŸ સà«àªŸà«àª°à«€àª® વાંચનને અમલમાં મૂકતà«àª‚ નથી" + +#: ../gio/gresource-tool.c:491 +msgid "List sections containing resources in an elf FILE" +msgstr "elf FILE માં સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«‡ સમાવતી વિભાગોની યાદી" + +#: ../gio/gresource-tool.c:497 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«€ યાદી\n" +"જો SECTION આપેલ છે તો, ફકà«àª¤ આ વિભાગમાં સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«€ યાદી\n" +"જો PATH આપેલ હોય તો, ફકà«àª¤ સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«‡ બંધબેસતાની યાદી" + +#: ../gio/gresource-tool.c:500 ../gio/gresource-tool.c:510 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:501 ../gio/gresource-tool.c:511 +#: ../gio/gresource-tool.c:518 +msgid "SECTION" +msgstr "SECTION" + +#: ../gio/gresource-tool.c:506 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"વિગતો સાથે સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«€ યાદી\n" +"જો SECTION આપેલ હોય તો, ફકà«àª¤ આ વિભાગમાં સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«€ યાદી\n" +"જો PATH આપેલ હોય તો, ફકà«àª¤ બંધબેસતા સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«€ યાદી\n" +"વિગતો ઠવિભાગ, માપ અને સંકોચનને સમાવે છે" + +#: ../gio/gresource-tool.c:516 +msgid "Extract a resource file to stdout" +msgstr "stdout માં સà«àª¤à«àª°à«‹àª¤ ફાઇલનો અરà«àª• કાઢો" + +#: ../gio/gresource-tool.c:517 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: ../gio/gresource-tool.c:531 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"વપરાશ:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"આદેશો:\n" +" help આ જાણકારી બતાવો\n" +" sections સà«àª¤à«àª°à«‹àª¤ વિભાગોની યાદી\n" +" list સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«€ યાદી\n" +" details વિગતો સાથે સà«àª¤à«àª°à«‹àª¤à«‹àª¨à«€ યાદી\n" +" extract સà«àª¤à«àª°à«‹àª¤àª¨à«‡ કાઢો\n" +"\n" +"વિગત થયેલ મદદને મેળવવા માટે 'gresource help COMMAND' વાપરો.\n" +"\n" + +#: ../gio/gresource-tool.c:545 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"વપરાશ:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:552 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION (વૈકલà«àªªàª¿àª•) elf વિભાગ નામ\n" + +#: ../gio/gresource-tool.c:556 ../gio/gsettings-tool.c:648 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND વરà«àª£àª¨ કરવા માટે (વૈકલà«àªªàª¿àª•) આદેશ\n" + +#: ../gio/gresource-tool.c:562 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE elf ફાઇલ (બાઇનરી અથવા વહેંચેલ લાઇબà«àª°à«‡àª°à«€)\n" + +#: ../gio/gresource-tool.c:565 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE elf ફાઇલ (બાઇનરી અથવા વહેંચેલ લાઇબà«àª°à«‡àª°à«€)\n" +" અથવા કમà«àªªàª¾àª‡àª² થયેલ સà«àª¤à«àª°à«‹àª¤ ફાઇલ\n" + +#: ../gio/gresource-tool.c:569 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:571 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH (વૈકલà«àªªàª¿àª•) સà«àª¤à«àª°à«‹àª¤ પાથ (શરૂઆતનà«àª‚ હોઇ શકે છે)\n" + +#: ../gio/gresource-tool.c:572 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:574 +msgid " PATH A resource path\n" +msgstr " PATH સà«àª¤à«àª°à«‹àª¤ પાથ\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "આવી યોજના '%s' નથી\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "યોજના '%s' પà«àª¨:સà«àª¥àª¿àª¤ કરાતૠનથી (પાથને સà«àªªàª·à«àªŸ કરવો જોઇઠનહિં)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "યોજના '%s' પà«àª¨:સà«àª¥àª¿àª¤ કરાતૠનથી (પાથને સà«àªªàª·à«àªŸ કરવો જોઇàª)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "ખાલી પાથ આપેલ છે.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "પાથ સà«àª²à«‡àª¶ (/) સાથે શરૂ થવૠજ જોઇàª\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "પાથ સà«àª²à«‡àª¶ (/) સાથે બંધ થવો જ જોઇàª\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "પાથ ઠબે નજીક સà«àª²à«…શ (//) ને સમાવતૠજ નથી\n" + +#: ../gio/gsettings-tool.c:490 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "પૂરી પાડેલ કિંમત માનà«àª¯ સીમાની બહાર છે\n" + +#: ../gio/gsettings-tool.c:497 +#, c-format +msgid "The key is not writable\n" +msgstr "કી લખી શકાય તેમ નથી\n" + +#: ../gio/gsettings-tool.c:533 +msgid "List the installed (non-relocatable) schemas" +msgstr "સà«àª¥àª¾àªªàª¿àª¤ થયેલ (પà«àª¨:સà«àª¥àª¿àª¤ ન કરાય) તેવી યોજનાની યાદી" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed relocatable schemas" +msgstr "સà«àª¥àª¾àªªàª¿àª¤ થયેલ પà«àª¨:સà«àª¥àª¿àª¤ કરી શકાય તેવી યોજનાની યાદી કરો" + +#: ../gio/gsettings-tool.c:545 +msgid "List the keys in SCHEMA" +msgstr "SCHEMA માં કીઓની યાદી કરો" + +#: ../gio/gsettings-tool.c:546 ../gio/gsettings-tool.c:552 +#: ../gio/gsettings-tool.c:589 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:551 +msgid "List the children of SCHEMA" +msgstr "SCHEMA નાં બાળકોની યાદી કરો" + +#: ../gio/gsettings-tool.c:557 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"કીઓ અને કિંમતોની યાદી, પà«àª¨àª°àª¾àªµàª°à«àª¤à«€àª¤\n" +"જો SCHEMA આપેલ ન હોય તો, બધી કીઓની યાદી કરો\n" + +#: ../gio/gsettings-tool.c:559 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:564 +msgid "Get the value of KEY" +msgstr "KEY ની કિંમતને મેળવો" + +#: ../gio/gsettings-tool.c:565 ../gio/gsettings-tool.c:571 +#: ../gio/gsettings-tool.c:583 ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:570 +msgid "Query the range of valid values for KEY" +msgstr "KEY માટે માનà«àª¯ કિંમતોની સીમાની કà«àªµà«‡àª°à«€ કરો" + +#: ../gio/gsettings-tool.c:576 +msgid "Set the value of KEY to VALUE" +msgstr "VALUE માટે KEY ની કિંમત સà«àª¯à«‹àªœàª¿àª¤ કરો" + +#: ../gio/gsettings-tool.c:577 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:582 +msgid "Reset KEY to its default value" +msgstr "તેની મૂળભૂત કિંમતમાં KEY ને પà«àª¨:સà«àª¯à«‹àªœàª¿àª¤ કરો" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "તેનાં મૂળભૂતોમાં SCHEMA માં બધા કીઓને પà«àª¨:સà«àª¯à«‹àªœàª¿àª¤ કરો" + +#: ../gio/gsettings-tool.c:594 +msgid "Check if KEY is writable" +msgstr "ચકાસો જો KEY લખી શકાય તેમ છે" + +#: ../gio/gsettings-tool.c:600 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"ફેરફારો માટે મોનિટર KEY.\n" +"જો KEY સà«àªªàª·à«àªŸ થયેલ ન હોય તો, SCHEMA માં બધી કીઓને મોનિટર કરો.\n" +"મોનિટર કરવાનà«àª‚ બંધ રાખવા માટે ^C વાપરો.\n" + +#: ../gio/gsettings-tool.c:603 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:615 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"વપરાશ:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"\n" +"આદેશો:\n" +" help આ જાણકારી બતાવો\n" +" list-schemas સà«àª¥àª¾àªªàª¿àª¤ થયેલ યોજનાની યાદી\n" +" list-relocatable-schemas પà«àª¨:સà«àª¥àª¿àª¤ કરી શકાય તેવી યોજનાની યાદી\n" +" list-keys યોજનામાં કીઓની યાદી\n" +" list-children યોજનામાં બાળની યાદી\n" +" list-recursively કીઓ અને કિંમતોની યાદી\n" +" range કીની સીમાની કà«àªµà«‡àª°à«€\n" +" get કીની કિંમતને મેળવો\n" +" set કીની કિંમતને સà«àª¯à«‹àªœàª¿àª¤ કરો\n" +" reset કીની કિંમતને પà«àª¨:સà«àª¯à«‹àªœàª¿àª¤ કરો\n" +" reset-recursively આપેલ યોજનામાં બધી કિંમતોને પà«àª¨:સà«àª¯à«‹àªœàª¿àª¤ કરો\n" +" writable ચકાસો જો કી લખી શકાય તેવી છે\n" +" monitor ફેરફારો માટે ધà«àª¯àª¾àª¨ રાખો\n" +"\n" +"વિગત થયેલ મદદને મેળવવા માટે 'gsettings help COMMAND' વાપરો.\n" +"\n" + +#: ../gio/gsettings-tool.c:638 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"વપરાશ:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:644 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " વધારાની યોજના શોધવા માટે SCHEMADIR ડિરેકà«àªŸàª°à«€\n" + +#: ../gio/gsettings-tool.c:652 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA યોજનાનà«àª‚ નામ\n" +" PATH પà«àª¨:સà«àª¥àª¿àª¤ યોજનાઓ માટે પાથ\n" + +#: ../gio/gsettings-tool.c:657 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY યોજનામાં (વૈકલà«àªªàª¿àª•) કી\n" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The key within the schema\n" +msgstr " KEY યોજનામાં કી\n" + +#: ../gio/gsettings-tool.c:665 +msgid " VALUE The value to set\n" +msgstr " VALUE સà«àª¯à«‹àªœàª¿àª¤ કરવા માટે કિંમત\n" + +#: ../gio/gsettings-tool.c:720 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s માંથી યોજનાને લાવી શકà«àª¯àª¾ નહિં: %s\n" + +#: ../gio/gsettings-tool.c:782 +#, c-format +msgid "Empty schema name given\n" +msgstr "ખાલી યોજના નામ આપેલ છે\n" + +#: ../gio/gsettings-tool.c:811 +#, c-format +msgid "No such key '%s'\n" +msgstr "આવી કી '%s' નથી\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "અયોગà«àª¯ સોકેટ, પà«àª°àª¾àª°àª‚ભ થયેલ નથી" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "અયોગà«àª¯ સોકેટ, દરમà«àª¯àª¾àª¨ પà«àª°àª¾àª°àª‚ભ નિષà«àª«àª³: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "સોકેટ પહેલેથી જ બંધ થયેલ છે" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "સોકેટ I/O સમય સમાપà«àª¤àª¿" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd માંથી GSocket ને બનાવી રહà«àª¯àª¾ છે: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "સોકેટ ને બનાવવામાં અસમરà«àª¥: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "અજà«àªžàª¾àª¤ કà«àªŸà«àª‚બ સà«àªªàª·à«àªŸ થયેલ ન હતà«" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "અજà«àªžàª¾àª¤ પà«àª°à«‹àªŸà«‹àª•ોલ સà«àªªàª·à«àªŸ થયેલ હતà«" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "સà«àª¥àª¾àª¨àª¿àª¯ સરનામાંને મેળવી શકાયૠનહિં: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "દૂરસà«àª¥ સરનામાંને મેળવી શકાયૠનહિં: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "સાંભળી શકાયૠનહિં: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "સરનામાંને બાઇનà«àª¡ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "મલà«àªŸà«€àª•ાસà«àªŸ જૂથને જોડી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "મલà«àªŸà«€àª•ાસà«àªŸ જૂથને છોડી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "સà«àª¤à«àª°à«‹àª¤ ખાસ મલà«àªŸà«€àª•ાસà«àªŸ માટે આધાર નથી" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "જોડાણને સà«àªµà«€àª•ારી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "જોડાણ પà«àª°àª—તિમાં છે" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "પેનà«àª¡àª¿àª‚ગ ભૂલ ને મેળવવામાં અસમરà«àª¥: " + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "માહિતી મેળવી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "માહિતી મોકલી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "સોકેટને બંધ કરવાનà«àª‚ અમસરà«àª¥: %s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "સોકેટને બંધ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "સોકેટ શરત માટે રાહ જોઇ રહà«àª¯àª¾ છે: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "સંદેશો મોકલી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage ઠWindows પર આધારભૂત નથી" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "ભૂલ મેળવી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gsocket.c:4516 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "સોકેટ શà«àª°à«‡àª¯àª¨à«‡ વાંચવાનà«àª‚ અસમરà«àª¥: %s" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials આ OS માટે અમલીકરણ થયેલ નથી" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª° %s સાથે જોડી શકà«àª¯àª¾ નહિં: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s સાથે જોડી શકà«àª¯àª¾ નહિં: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "જોડી શકà«àª¯àª¾ નહિં: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1603 +msgid "Unknown error on connect" +msgstr "જોડાણ પર અજà«àªžàª¾àª¤ ભૂલ" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1538 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "બિન-TCP જોડાણ પર પà«àª°à«‹àª•à«àª¸à«€àª‚ગ આધારભૂત નથી." + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1559 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "પà«àª°à«‹àª•à«àª¸à«€ પà«àª°à«‹àªŸà«‹àª•ોલ '%s' આધારભૂત નથી." + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "સાંભળનાર પહેલાથી જ બંધ થઈ ગયેલ છે" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "ઉમેરાયેલ સોકેટ બંધ થયેલ છે" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 ઠIPv6 સરનામà«àª‚ '%s' ને આધાર આપતૠનથી" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 પà«àª°à«‹àªŸà«‹àª•ોલ માટે વપરાશકરà«àª¤àª¾àª¨àª¾àª® ઘણà«àª‚ લાંબૠછે." + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 પà«àª°à«‹àªŸà«‹àª•ોલ માટે યજમાનનામ '%s' ઘણૠલાંબૠછે" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "સરà«àªµàª° SOCKSv4 પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª° નથી." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 સરà«àªµàª° મારફેત જોડાણ રદ કરેલ હતà«" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "સરà«àªµàª° SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª° નથી." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€àª¨à«‡ સતà«àª¤àª¾àª§àª¿àª•રણની જરૂર છે." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€àª¨à«‡ સતà«àª¤àª¾àª§àª¿àª•રણ પદà«àª¦àª¤àª¿àª¨à«€ જરૂર છે કે જે GLib દà«àª¦àª¾àª°àª¾ આધારભૂત નથી." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 પà«àª°à«‹àªŸà«‹àª•ોલ માટે વપરાશકરà«àª¤àª¾àª¨àª¾àª® અથવા પાસવરà«àª¡ ઘણૠલાંબૠછે." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "ખોટો વપરાશકરà«àª¤àª¾àª¨àª¾àª® અથવા પાસવરà«àª¡ આપવા દરમà«àª¯àª¾àª¨ SOCKSv5 સતà«àª¤àª¾àª§àª¿àª•રણ નિષà«àª«àª³." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "SOCKSv5 પà«àª°à«‹àªŸà«‹àª•ોલ માટે યજમાનનામ '%s' ઘણૠલાંબૠછે" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª° અજà«àªžàª¾àª¤ સરનામાં પà«àª°àª•ારને વાપરે છે." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "આંતરિક SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª° ભૂલ." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 જોડાણ ruleset દà«àª¦àª¾àª°àª¾ પરવાનગી થયેલ નથી." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 સરà«àªµàª° મારફતે પહોંચી ન શકાય તેવૠયજમાનનામ." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€ મારફતે ન પહોંચી શકાય તેવૠનેટવરà«àª•." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€ મારફતે રદ કરાયેલ જોડાણ." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€ 'connect' આદેશને આધાર આપતૠનથી." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€ પૂરૠપાડેલ સરનામાં પà«àª°àª•ારને આધાર આપતૠનથી." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "અજà«àªžàª¾àª¤ SOCKSv5 પà«àª°à«‹àª•à«àª¸à«€ ભૂલ." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon àªàª¨àª•ોડીંગ ની આવૃતà«àª¤àª¿ %d ને સંભાળી શકાતૠનથી" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "યોગà«àª¯ સરનામાં મળà«àª¯àª¾ ન હતા" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' ને વિપરીત-સà«àª§àª¾àª°à«€ રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "'%s' માટે સૂચિત પà«àª°àª•ારનો DNS અહેવાલ નથી" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "'%s' ને સà«àª§àª¾àª°àªµàª¾ માટે થોડા વખત અસમરà«àª¥" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "'%s' ને સà«àª§àª¾àª°à«€ રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-àªàª¨àª•ોડ થયેલ ખાનગી કીને ડિકà«àª°àª¿àªªà«àªŸ કરી શકાતૠનથી" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "PEM-àªàª¨àª•ોડ થયેલ ખાનગી કી મળી નથી" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-àªàª¨àª•ોડ થયેલ ખાનગી કીનà«àª‚ પદચà«àª›à«‡àª¦àª¨ કરી શકà«àª¯àª¾ નહિં" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "PEM-àªàª¨àª•ોડ થયેલ પà«àª°àª®àª¾àª£àªªàª¤à«àª° મળà«àª¯à« નથી" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-àªàª¨àª•ોડ થયેલ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«àª‚ પદચà«àª›à«‡àª¦àª¨ કરી શકà«àª¯àª¾ નહિં" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"તમારા પà«àª°àªµà«‡àª¶àª¨à«àª‚ તાળૠથઇ જાય તે પહેલાં યોગà«àª¯ રીતે પાસવરà«àª¡àª¨à«‡ દાખલ કરવા માટે છેલà«àª²à«€ અપેકà«àª·àª¾ છે." + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"દાખલ થયેલ ઘણાં પાસવરà«àª¡ અયોગà«àª¯ થઇ ગયા છે, અને તમારો પà«àª°àªµà«‡àª¶ આગળની નિષà«àª«àª³àª¤àª¾ પછી તાળૠમારેલ " +"હશે." + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "દાખલ થયેલ પાસવરà«àª¡ ખોટો છે." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "à«§ નિયંતà«àª°àª£ સંદેશાની ઇચà«àª›àª¾ રાખી રહà«àª¯àª¾ છે, %d મળà«àª¯à«" +msgstr[1] "à«§ નિયંતà«àª°àª£ સંદેશાની ઇચà«àª›àª¾ રાખી રહà«àª¯àª¾ છે, %d મળà«àª¯à«" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "ગૌણ માહિતીનો અનચà«àª›àª¿àª¨à«€àª¯ પà«àª°àª•ાર" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "àªàª• fd ની ઇચà«àª›àª¾ રાખી રહà«àª¯àª¾ છે, પરંતૠ%d મળà«àª¯à«\n" +msgstr[1] "àªàª• fd ની ઇચà«àª›àª¾ રાખી રહà«àª¯àª¾ છે, પરંતૠ%d મળà«àª¯à«\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "મેળવેલ અયોગà«àª¯ fd" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "શà«àª°à«‡àª¯àª¨à«‡ મોકલતી વખતે ભૂલ: " + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "ચકાસી કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ જો SO_PASSCRED સોકેટ માટે સકà«àª°àª¿àª¯ થયેલ છે: %s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED ને સકà«àª°àª¿àª¯ કરતી વખતે ભૂલ: %s" + +#: ../gio/gunixconnection.c:540 +msgid "Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"શà«àª°à«‡àª¯àª¨à«‡ પà«àª°àª¾àªªà«àª¤ કરવા માટે àªàª•જ બાઇટને વાંચવાની ઇચà«àª›àª¾ રાખી રહà«àª¯àª¾ છે પરંતૠશૂનà«àª¯ બાઇટ વાંચે છે" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "નિયંતà«àª°àª£ સંદેશાની ઇચà«àª›àª¾ રાખી રહà«àª¯àª¾ નથી, પરંતૠ%d મળà«àª¯à«" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "જà«àª¯àª¾àª°à«‡ SO_PASSCRED નિષà«àª•à«àª°àª¿àª¯ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ફાઇલ વરà«àª£àª¨àª•રà«àª¤àª¾àª®àª¾àª‚થી વાંચી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ફાઈલ વરà«àª£àª¨àª•રà«àª¤àª¾àª¨à«‡ બંધ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gunixmounts.c:2054 ../gio/gunixmounts.c:2107 +msgid "Filesystem root" +msgstr "ફાઈલસિસà«àªŸàª® રà«àªŸ" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ફાઈલ વરà«àª£àª¨àª•રà«àª¤àª¾àª®àª¾àª‚ લખી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Abstract unix ડોમેઇન સરનામાંઓ આ સિસà«àªŸàª® પર આધારભૂત નથી" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "વોલà«àª¯à«àª® બહાર કાઢોને અમલમાં મૂકતà«àª‚ નથી" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "વોલà«àª¯à«àª® ઠeject અથવા eject_with_operation ને અમલીકરણ કરતૠનથી" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "કારà«àª¯àª•à«àª°àª® શોધી શકતા નથી" + +#: ../gio/gwin32appinfo.c:303 +#, c-format +msgid "Error launching application: %s" +msgstr "કારà«àª¯àª•à«àª°àª® લાવતી વખતે ભૂલ: %s" + +#: ../gio/gwin32appinfo.c:378 +msgid "association changes not supported on win32" +msgstr "સંડોવણી ફેરફારો win32 પર આધારભૂત નથી" + +#: ../gio/gwin32appinfo.c:390 +msgid "Association creation not supported on win32" +msgstr "સંડોવણી બનાવટ win32 પર આધારભૂત નથી" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "સંચાલનમાંથી વાંચી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "સંચાલનને બંધ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "સંચાલન માટે લખી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "પૂરતી મેમરી નથી" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "આંતરિક ભૂલ: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "વધારે ઇનપà«àªŸàª¨à«€ જરૂર" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "અયોગà«àª¯ સંકોચાયેલ માહિતી" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "તેની પર સાંભળવા માટે સરનામà«àª‚" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "અવગણેલ, GTestDbus સાથે કૉમà«àªªà«‡àªŸ માટે" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "સરનામà«àª‚ છાપો" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "શેલ સà«àª¥àª¿àª¤àª¿àª®àª¾àª‚ સરનામાંને છાપો" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "dbus સેવાને ચલાવો" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "ખોટી દલીલો\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "ઘટક '%s' માટે અનિચà«àª›àª¨à«€àª¯ લકà«àª·àª£ '%s'" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "ઘટક '%s' નà«àª‚ લકà«àª·àª£ '%s' મળà«àª¯à«àª‚ નહિં" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "અનિચà«àª›àª¨à«€àª¯ ટેગ '%s', ટેગ '%s' ઈચà«àª›àª¿àª¤" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "અનિચà«àª›àª¨à«€àª¯ ટેગ '%s' ઠ'%s' માં" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "માહિતી ડિરેકà«àªŸàª°à«€àª“ માટે કોઈ માનà«àª¯ બà«àª•મારà«àª• ફાઈલ મળી નહિં" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s' માટેની બà«àª•મારà«àª• પહેલાથી જ હાજર છે" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s' માટે કોઈ બà«àª•મારà«àª• મળી નહિં" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s' માટે બà«àª•મારà«àª•માં કોઈ MIME પà«àª°àª•ાર વà«àª¯àª¾àª–à«àª¯àª¾àª¯àª¿àª¤ નથી" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s' માટે બà«àª•મારà«àª•માં કોઈ ખાનગી ફà«àª²à«‡àª— વà«àª¯àª¾àª–à«àª¯àª¾àª¯àª¿àª¤ થયેલ નથી" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s' માટે બà«àª•મારà«àª•માં કોઈ જૂથો સà«àª¯à«‹àªœàª¿àª¤ નથી" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "'%s' નામવાળા કોઈ કારà«àª¯àª•à«àª°àª®à«‡ '%s' માટે બà«àª•મારà«àª• રજીસà«àªŸàª° કરી નથી" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "exec લીટી '%s' ને URI '%s' સાથે વિસà«àª¤àª¾àª°àªµàª¾àª®àª¾àª‚ નિષà«àª«àª³" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "ઈનપà«àªŸ ના છેડા પર અપૂરà«àª£ અકà«àª·àª° શà«àª°à«‡àª£à«€ છે" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "ફૈલબેક '%s' ને '%s' કોડના સમૂહમાં પરીવરà«àª¤àª¿àª¤ કરી શકાતà«àª‚ નથી " + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s' કે જે \"ફાઈલ\" યોજના વાપરે છે તે ચોકà«àª•સ URI નથી" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "સà«àª¥àª¾àª¨à«€àª¯ ફાઈલ URI '%s' માં કદાય '#' સમાવિષà«àªŸ નથી" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "'%s' URI અયોગà«àª¯ છે" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "'%s' URIનà«àª‚ યજમાનનૠનામ અયોગà«àª¯ છે" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "'%s' URI અયોગà«àª¯ બહાર નીકળવાના અકà«àª·àª°à«‹ ધરાવે છે " + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s' પથ નામ ઠચોકà«àª•સ પથ નથી" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "અયોગà«àª¯ યજમાન નામ" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "જાનà«àª¯à«àª†àª°à«€" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "ફેબà«àª°à«àª†àª°à«€" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "મારà«àªš" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "àªàªªà«àª°àª¿àª²" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "મે" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "જà«àª¨" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "જà«àª²àª¾àª‡" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "ઑગસà«àªŸ" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "સેપà«àªŸà«‡àª®à«àª¬àª°" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "ઑકà«àªŸà«‹àª¬àª°" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "નવેમà«àª¬àª°" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "ડિસેમà«àª¬àª°" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "જાનà«àª¯à«àª†àª°à«€" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ફેબà«àª°à«àª†àª°à«€" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "મારà«àªš" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "àªàªªà«àª°àª¿àª²" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "મે" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "જà«àª¨" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "જà«àª²àª¾àª‡" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ઑગસà«àªŸ" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "સેપà«àªŸà«‡àª®à«àª¬àª°" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "ઑકà«àªŸà«‹" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "નવેમà«àª¬àª°" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ડિસેમà«àª¬àª°" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "સોમવાર" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "મંગળવાર" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "બà«àª§àªµàª¾àª°" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ગà«àª°à«àªµàª¾àª°" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "શà«àª•à«àª°àªµàª¾àª°" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "શનિવાર" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "રવિવાર" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "સોમ" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "મંગળ" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "બà«àª§" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ગà«àª°à«" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "શà«àª•à«àª°" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "શનિ" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "રવિ" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "'%s' ડિરેકà«àªŸàª°à«€ ખોલતા ભૂલ: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "%lu બાઈટ \"%s\" ફાઈલ વાંચવા માટે ફાળવી શકà«àª¯àª¾ નહિં" +msgstr[1] "%lu બાઈટ \"%s\" ફાઈલો વાંચવા માટે ફાળવી શકà«àª¯àª¾ નહિં" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' ફાઈલ વાંચતી વખતની ભૂલ: %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "ફાઇલ \"%s\" ઠઘણી વિશાળ છે" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' ફાઈલમાંથી વાંચવામા નિષà«àª«àª³àª¤àª¾: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' ફાઈલ ખોલવામાં નિષà«àª«àª³àª¤àª¾ : %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' ફાઈલની લાકà«àª·àª£àª¿àª•તા મેળવતી વખતે નિષà«àª«àª³àª¤àª¾: fstate() નિષà«àª«àª³: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' ફાઈલ ખોલવામાં નિષà«àª«àª³àª¤àª¾: fdopen() નિષà«àª«àª³: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "ફાઈલ '%s' નà«àª‚ નામ '%s' માં બદલવામાં નિષà«àª«àª³: g_rename() નિષà«àª«àª³: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' ફાઈલ બનાવવામાં નિષà«àª«àª³àª¤àª¾ : %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "ફાઈલ '%s' પર લખવામાં નિષà«àª«àª³: write() નિષà«àª«àª³: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "ફાઈલ '%s' પર લખવામાં નિષà«àª«àª³: fsync() નિષà«àª«àª³: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "વરà«àª¤àª®àª¾àª¨ ફાઈલ '%s' દૂર કરી શકાઈ નહિં: g_unlink() નિષà«àª«àª³: %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr " '%s' ટેમà«àªªàª²à«‡àªŸ અયોગà«àª¯ છે, તે '%s' ધરાવતà«àª‚ નથી" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "ટેમà«àªªàª²à«‡àªŸ '%s' ઠXXXXXX સમાવતà«àª‚ નથી" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "'%s' સાંકેતિક કડી વાંચવામાં નિષà«àª«àª³àª¤àª¾: %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "સાંકેતિક કડી આધાર આપતી નથી" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' માંથી '%s' માટેનà«àª‚ રà«àªªàª¾àª‚તરક ખોલી શકાયà«àª‚ નહિં: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_10_channe_lread_line_string માં આડી હરોળ માં વાંચી શકાતà«àª‚ નથી" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "" +"વાંચવા માટેના બફર(થોડા સમય માટેનà«àª‚ સંગà«àª°àª¹àª¸à«àª¥àª¾àª¨) માં ઢાંકેલી ન હોય તે માહિતી છોડી દીધેલ છે" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "માધà«àª¯àª® અપà«àª°à«àª£ અકà«àª·àª°àª¥à«€ અંત પામે છે" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end માં આડી હરોળ વાંચી શકાતી નથી" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "શોધ ડિરેકà«àªŸàª°à«€àª“માં માનà«àª¯ કી ફાઈલ શોધી શકà«àª¯àª¾ નહિં" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "નિયમિત ફાઈલ નથી" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "કી ફાઈલ વાકà«àª¯ '%s' સમાવે છે કે જે કી-કિંમત જોડ, જૂથ, અથવા ટિપà«àªªàª£à«€ નથી" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "અયોગà«àª¯ જૂથ નામ: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "કી ફાઈલ જૂથ સાથે શરૂ થતી નથી" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "અયોગà«àª¯ કી નામ: %s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "કી ફાઈલ બિનઆધારભૂત અકà«àª·àª° સંગà«àª°àª¹àªªàª¦à«àª§àª¤àª¿ '%s' સમાવે છે" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1703 ../glib/gkeyfile.c:3081 +#: ../glib/gkeyfile.c:3144 ../glib/gkeyfile.c:3270 ../glib/gkeyfile.c:3400 +#: ../glib/gkeyfile.c:3542 ../glib/gkeyfile.c:3771 ../glib/gkeyfile.c:3838 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "કી ફાઈલ પાસે જૂથ '%s' નથી" + +#: ../glib/gkeyfile.c:1658 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "કી ફાઈલ પાસે કી '%s' ઠજૂથ '%s' માં નથી" + +#: ../glib/gkeyfile.c:1820 ../glib/gkeyfile.c:1936 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "કી ફાઈલ '%s' કીને કિંમત '%s' સાથે સમાવે છે કે જે UTF-8 નથી" + +#: ../glib/gkeyfile.c:1840 ../glib/gkeyfile.c:1956 ../glib/gkeyfile.c:2325 +#, c-format +msgid "Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "કી ફાઈલ '%s' કી સમાવે છે કે જેની પાસે કિંમત છે જે ઈનà«àªŸàª°àªªà«àª°à«€àªŸ કરી શકાતી નથી." + +#: ../glib/gkeyfile.c:2542 ../glib/gkeyfile.c:2910 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"કી ફાઈલ '%s' કી જૂથ '%s' માં સમાવે છે કે જેની પાસે કિંમત છે કે જે ઈનà«àªŸàª°àªªà«àª°à«€àªŸ કરી શકાતી " +"નથી." + +#: ../glib/gkeyfile.c:2620 ../glib/gkeyfile.c:2697 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" +"કી '%s' કી જૂથ '%s'પાસે કિંમત '%s'છે કે જà«àª¯àª¾àª‚ %s ઇચà«àª›àª¾ રાખી રહà«àª¯à« હતૠઈનà«àªŸàª°àªªà«àª°à«€àªŸ કરી " +"શકાતી ." + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "કી ફાઈલ àªàª¸à«àª•ેપ અકà«àª·àª° વાકà«àª¯àª¨àª¾ અંતે સમાવે છે" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "કી ફાઈલ અયોગà«àª¯ àªàª¸à«àª•ેપ કà«àª°àª® '%s' સમાવે છે" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "કિંમત '%s' નંબર તરીકે ઈનà«àªŸàª°àªªà«àª°à«€àªŸ કરી શકાતà«àª‚ નથી." + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "પૂરà«àª£àª¾àª‚ક કિંમત '%s' ઠમરà«àª¯àª¾àª¦àª¾àª¨à«€ બહાર છે" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "કિંમત '%s' ઠઅપૂરà«àª£àª¾àª‚ક સંખà«àª¯àª¾ તરીકે ઈનà«àªŸàª°àªªà«àª°à«€àªŸ કરી શકાતà«àª‚ નથી." + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "કિંમત '%s' બà«àª²àª¿àª¯àª¨ તરીકે ઈનà«àªŸàª°àªªà«àª°à«€àªŸ કરી શકાતà«àª‚ નથી." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "ફાઇલ '%s%s%s%s' નાં ગà«àª£àª§àª°à«àª®àª¨à«‡ મેળવવામાં નિષà«àª«àª³àª¤àª¾: fstat() નિષà«àª«àª³: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s નà«àª‚ માપન કરવામાં નિષà«àª«àª³àª¤àª¾: mmap() નિષà«àª«àª³: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "ફાઈલ '%s' ખોલવામાં નિષà«àª«àª³: open() નિષà«àª«àª³: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "%d લીટી પર %d અકà«àª·àª°àª®àª¾àª‚ ભૂલ: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "નામ માં અયોગà«àª¯ UTF-8 સંગà«àª°àª¹àªªàª¦à«àª§àª¤àª¿àªµàª¾àª³à«àª‚ લખાણ - માનà«àª¯ '%s' નથી" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' ઠયોગà«àª¯ નામ નથી" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' ઠયોગà«àª¯ નામ નથી: '%c'" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d લીટી પર ભૂલ: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' નà«àª‚ પદચà«àª›à«‡àª¦àª¨ કરવામાં નિષà«àª«àª³, કે જે અકà«àª·àª° સંદરà«àª­àª®àª¾àª‚ અંક હોવો જોઈઠ(ê ઉદાહરણ " +"તરીકે) - કદાચ અંક ખૂબ લાંબો હોય" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"અકà«àª·àª° સંદરà«àª­ અરà«àª§àªµàª¿àª°àª¾àª® થી અંત થતો નથી; તમે વસà«àª¤à« શરૠકરવા àªàª®àªªàª°àª¸àª‚ડ અકà«àª·àª° ને વાપરો àªàª®àªªàª°àª¸àª‚ડ " +"ને & તરીકે લો" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "અકà«àª·àª° સંદરà«àª­ '%-.*s' પરવાનગી આપેલ અકà«àª·àª°àª¨à«‡ àªàª¨àª•ોડ કરતો નથી" + +#: ../glib/gmarkup.c:759 +msgid "Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "'&;' વસà«àª¤à« ખાલી દેખાય છે: યોગà«àª¯ વસà«àª¤à«àª“ છે:& " < > '" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Entity નામ '%-.*s' જાણીતૠનથી" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"વસà«àª¤à« નો સેમીકોલન સાથે અંત થતો નથી; ઘણી વખતે àªàª®àªªàª°àª¸àª‚ડ (&) અકà«àª·àª° ચિનà«àª¹ વગર તમે વસà«àª¤à« વાપરી " +"શકો છો - àªàª®àªªàª°àª¸àª‚ડ & તરીકે લો" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "દસà«àª¤àª¾àªµà«‡àªœ કોઈ વસà«àª¤à« સાથે શરૠથાય તે જરà«àª°à«€ છે(ઉદાહરણ )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "'%s' ઠ'<' અકà«àª·àª° પછી આવતો યોગà«àª¯ અકà«àª·àª° નથી; તે કોઈ વસà«àª¤à«àª¨àª¾ નામથી શરૠથતૠનથી" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "અસંગત અકà«àª·àª° '%s', વસà«àª¤à« ટેગ '%s' નાં ખાલી ઘટક ને સમાપà«àª¤ કરવા '>' અકà«àª·àª° ની આશા છે" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "અસંગત અકà«àª·àª° '%s', '%s' વસà«àª¤à«àª¨àª¾ '%s' લાકà«àª·àª£àª¿àª•તા નામ પછી '=' જરà«àª°à«€ છે" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"અસંગત અકà«àª·àª° '%s': '%s' વસà«àª¤à«àª¨àª¾ અંતમાં '>' અથવા '/' અથવા પરીમાણનો વિકલà«àªª જરà«àª°à«€ છે; તમે " +"કદાય અયોગà«àª¯ અકà«àª·àª° લાકà«àª·àª£àª¿àª•તાના નામો વાપરà«àª¯à«‹ છે" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"અસંગત અકà«àª·àª° '%s, '%s' વસà«àª¤à« માટે '%s' લાકà«àª·àª£àª¿àª•તાના મà«àª²à«àª¯ આપતી વખતે બરાબરની નિશાની " +"પછી શરૠથતો અવતરણ ચિહà«àª¨ જરà«àª°à«€ છે" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "'%s' ઠ'%s' વસà«àª¤à«àª¨àª¾àª® પછીનો બંધ કરવાનો યોગà«àª¯ અકà«àª·àª° નથી; '>' ઠયોગà«àª¯ અકà«àª·àª° છે. " + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "'%s' વસà«àª¤à« બંધ હતી, અતà«àª¯àª¾àª°à«‡ àªàª• પણ વસà«àª¤à« ખà«àª²à«àª²à«€ નથી" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "'%s' વસà«àª¤à« બંધ હતી, પણ અતà«àª¯àª¾àª°à«‡ '%s'ઠખà«àª²à«àª²à«€ વસà«àª¤à« છે" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "દસà«àª¤àª¾àªµà«‡àªœ ખાલી છે અથવા ફકà«àª¤ ખાલી જà«àª—à«àª¯àª¾ ધરાવે છે" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "'<' ચિનà«àª¹ વાપરતા પછી દસà«àª¤àª¾àªµà«‡àªœàª¨à«‹ અણધારી રીતે અંત આવે છે" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "વસà«àª¤à« ખà«àª²à«àª²à«€ હોવા છતાં દસà«àª¤àª¾àªµà«‡àªœàª¨à«‹ અણધારી રીતે અંત આવે છે- છેલà«àª²à«‡ ખોલેલ વસà«àª¤à« '%s' છે" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"દસà«àª¤àª¾àªµà«‡àªœàª¨à«‹ અણધારી રીતે અંત થાય છે, તે અંતિમ ટેગ <%s/> માં કૌંસને બંધ કરતૠખૂણાનૠચિનà«àª¹ " +"જોવા માગે છે" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "વસà«àª¤à« નામની અંદર દસà«àª¤àª¾àªµà«‡àªœàª¨à«‹ અણધારી રીતે અંત થાય છે" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "લાકà«àª·àª£àª¿àª•તાના નામની અંદર દસà«àª¤àª¾àªµà«‡àªœàª¨à«‹ અણધારી રીતે અંત થાય છે" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "વસà«àª¤à«àª¨à«€ શરà«àª†àª¤àª¨à«€ ટેગમા દસà«àª¤àª¾àªµà«‡àªœàª¨à«‹ અણધારી રીતે અંત થાય છે." + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"લાકà«àª·àª£àª¿àª•તા નામ પછીની બરાબરની નિશાની પછી દસà«àª¤àª¾àªµà«‡àªœ નો અણધારી રીતે અંત થાય છે. " +"લાકà«àª·àª£àª¿àª•તાના મà«àª²à«àª¯ નથી" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "લાકà«àª·àª£àª¿àª•તા મà«àª²à«àª¯ અંદર હોવા છતાં દસà«àª¤àª¾àªµà«‡àªœ નો અણધારી રીતે અંત થાય છે" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "'%s' વસà«àª¤à«àª¨àª¾ બંદ ટેગની અંદર દસà«àª¤àª¾àªµà«‡àªœàª¨à«‹ અણધારી રીતે અંત થાય છે" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "ટિપà«àªªàª£à«€ અથવા પà«àª°àª•à«àª°àª¿àª¯àª¾ સà«àªšàª¨àª¾àª¨à«€ અંદર અણધારી રીતે દસà«àª¤àª¾àªµà«‡àªœàª¨à«‹ અંત થાય છે" + +#: ../glib/goption.c:855 +msgid "Usage:" +msgstr "વપરાશ:" + +#: ../glib/goption.c:855 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:971 +msgid "Help Options:" +msgstr "મદદ વિકલà«àªªà«‹:" + +#: ../glib/goption.c:972 +msgid "Show help options" +msgstr "મદદ વિકલà«àªªà«‹ બતાવો" + +#: ../glib/goption.c:978 +msgid "Show all help options" +msgstr "બધા મદદ વિકલà«àªªà«‹ બતાવો" + +#: ../glib/goption.c:1040 +msgid "Application Options:" +msgstr "કારà«àª¯àª•à«àª°àª® વિકલà«àªªà«‹:" + +#: ../glib/goption.c:1104 ../glib/goption.c:1174 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "પૂરà«àª£àª¾àª‚ક કિંમત '%s' ને %s માટે પદચà«àª›à«‡àª¦àª¨ કરી શકતા નથી" + +#: ../glib/goption.c:1114 ../glib/goption.c:1182 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "પૂરà«àª£àª¾àª‚ક કિંમત '%s' ઠ%s માટે મરà«àª¯àª¾àª¦àª¾ બહાર છે" + +#: ../glib/goption.c:1139 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "બમણી કિંમત '%s' ને %s માટે પદચà«àª›à«‡àª¦àª¿àª¤ કરી શકતા નથી" + +#: ../glib/goption.c:1147 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "બમણી કિંમત '%s' જે %s માટે છે તે વિસà«àª¤àª¾àª°àª¨à«€ બહાર છે" + +#: ../glib/goption.c:1433 ../glib/goption.c:1512 +#, c-format +msgid "Error parsing option %s" +msgstr "ભૂલ પદચà«àª›à«‡àª¦àª¨ વિકલà«àªª %s" + +#: ../glib/goption.c:1543 ../glib/goption.c:1656 +#, c-format +msgid "Missing argument for %s" +msgstr "%s માટેની દલીલ ગà«àª® થયેલ છે" + +#: ../glib/goption.c:2117 +#, c-format +msgid "Unknown option %s" +msgstr "અજà«àªžàª¾àª¤ વિકલà«àªª %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "ભાંગી પડેલ ઓબà«àªœà«‡àª•à«àªŸ" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "આંતરિક ભૂલ અથવા બગડેલ ઓબà«àªœà«‡àª•à«àªŸ" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "મેમરી બહાર" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "પાછળ જવાની મરà«àª¯àª¾àª¦àª¾àª પહોંચી ગયા" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "ભાત અંશતઃ જોડણી માટે આધારભૂત વસà«àª¤à«àª“ સમાવતી નથી" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "શરતો તરીકે પાછળના સંદરà«àª­à«‹ અંશતઃ સરખામણી માટે આધારભૂત નથી" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "પà«àª¨àª°àª¾àªµàª°à«àª¤àª¨ મરà«àª¯àª¾àª¦àª¾àª પહોંચી ગયà«àª‚" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "નવીલીટી ફà«àª²à«‡àª—ોનà«àª‚ અયોગà«àª¯ જોડકà«àª‚" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "ખરાબ ઓફસેટ" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "ટૂંકૠutf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "રિકરà«àªàª¨ લૂપ" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "અજà«àªžàª¾àª¤ ભૂલ" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ ભાતના અંતે" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c ભાતના અંતે" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "નહિં ઓળખાયેલ અકà«àª·àª° અનà«àª¸àª°à«‡ છે \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} ગણકમાં નંબરો હદ બહાર છે" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} ગણકમાં ખૂબ મોટી સંખà«àª¯àª¾" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "અકà«àª·àª° વરà«àª— માટે અંત કરતો ] ગà«àª® છે" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "અકà«àª·àª° વરà«àª—માં અયોગà«àª¯ àªàª¸à«àª•ેપ કà«àª°àª®" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "અકà«àª·àª° વરà«àª—માં કà«àª°àª® વિસà«àª¤àª¾àª°àª¨à«€ બહાર છે" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "પà«àª¨àª°àª¾àªµàª°à«àª¤àª¨ કરવા માટે કંઈ નથી" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "અનિચà«àª›àª¨àª¿àª¯ પà«àª¨àª°àª¾àªµàª°à«àª¤àª¨" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? અથવા (?- પછી નહિં ઓળખાતો અકà«àª·àª°" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX named વરà«àª—à«‹ માતà«àª° વરà«àª—માં જ આધારભૂત છે" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "અંત કરતો ) ગà«àª® છે" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "બિન-હયાત ઉપભાતનો સંદરà«àª­" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "ટિપà«àªªàª£à«€ પછી ગà«àª® થયેલ )" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "નિયમિત સમીકરણ ખૂબ મોટà«àª‚ છે" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "મેમરી મેળવવામાં નિષà«àª«àª³" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") ઠખૂલતા ( વિના છે" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "કોડ ઉભરાટ" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "(?< પછી નહિં ઓળખાતો અકà«àª·àª°" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind ગોઠવણ ઠનિયમિત લંબાઈ નથી" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "(?( પછી મલીન નંબર અથવા નામ" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "શરતી જૂથ બે કરતાં વધૠશાખાઓ સમાવે છે" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "(?( પછી ઉમેરો ઈચà«àª›àª¿àª¤ છે" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R અથવા (?[+-]અંકો ) ને અનà«àª¸àª°àª¤àª¾ જ હોવા જોઈàª" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "અજà«àªžàª¾àª¤ POSIX વરà«àª— નામ" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "POSIX કà«àª°àª®àª¾àª‚કિત ઘટકો આધારભૂત નથી" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} કà«àª°àª®àª®àª¾àª‚ની અકà«àª·àª° કિંમત ખૂબ મોટી છે" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "અયોગà«àª¯ શરત (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C lookbehind ગોઠવણીમાં માનà«àª¯ નથી" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, અને \\u આધારભૂત નથી" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "પà«àª¨àª°àª¾àªµàª°à«àª¤à«€ કોલ અવà«àª¯àª¾àª–à«àª¯àª¾àª¯àª¿àª¤ લà«àªªàª®àª¾àª‚ જઈ શકે" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "(?P પછી નહિં ઓળખાતો અકà«àª·àª°" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "ઉપભાત નામમાં ગà«àª® થયેલ અંત કરનાર" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "બે નામવાળી ઉપભાતોને àªàª• જ નામ હોય છે" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "મલીન \\P અથવા \\p કà«àª°àª®" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "\\P અથવા \\p પછી અજà«àªžàª¾àª¤ ગà«àª£àª§àª°à«àª® નામ" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ઉપભાત નામ ખૂબ લાંબૠછે (મહતà«àª¤àª® ૩૨ અકà«àª·àª°à«‹)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ઘણાબધા નામવાળી ઉપભાતો (મહતà«àª¤àª® ૧૦,૦૦૦)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "અષà«àªŸàª¾àª‚ક કિંમત \\377 કરતાં મોટી છે" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "વધૠપડતà«àª‚ કમà«àªªàª¾àªˆàª²à«€àª‚ગ કારà«àª¯àª¸à«àª¥àª³" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "પહેલાં-ચકાસાયેલ સંદરà«àª­àªµàª¾àª³à«€ ભાત મળી નહિં" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE જૂથ àªàª• શાખા કરતાં વધૠસમાવે છે" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "વિચલ NEWLINE વિકલà«àªªà«‹" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ઠકૌંસવાળા નામ દà«àªµàª¾àª°àª¾ અનà«àª¸àª°àªµàª¾àª®àª¾àª‚ આવતà«àª‚ નથી કે વૈકલà«àªªàª¿àª• રીતે કૌંસવાળા બિન-શૂનà«àª¯ નંબરથી" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "કà«àª°àª®àª¾àª‚કિત થયેલ સંદરà«àª­ શૂનà«àª¯ ન હોવૠજ જોઇàª" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "દલીલને (*ACCEPT), (*FAIL), અથવા (*COMMIT) માટે પરવાનગી મળેલ નથી" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ઓળખાયેલ નથી" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "નંબર ઘણો મોટો છે" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& પછી ગà«àª® થયેલ ઉપભાત નામ" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ પછી ઈચà«àª›àª¿àª¤ અંક" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "JavaScript સà«àª¸àª‚ગત સà«àª¥àª¿àª¤àª¿àª®àª¾àª‚ ] ઠઅયોગà«àª¯ માહિતી અકà«àª·àª° છે" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "àªàªœ નંબરનાં ઉપભાત માટે વિવિધ નામોને પરવાનગી આપેલ નથી" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) પાસે દલીલ હોવી જ જોઇàª" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c ઠASCII અકà«àª·àª° દà«àª¦àª¾àª°àª¾ અનà«àª¸àª°àªµà« જ જોઇàª" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\g ઠકૌંસવાળા નામ દà«àªµàª¾àª°àª¾ અનà«àª¸àª°àªµàª¾àª®àª¾àª‚ આવતà«àª‚ નથી કે વૈકલà«àªªàª¿àª• રીતે કૌંસવાળા બિન-શૂનà«àª¯ નંબરથી" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N ઠવરà«àª—માં આધારભૂત નથી" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "ઘણી આગળ સંદરà«àª­ આપે છે" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), અથવા (*THEN) માં નામ ઘણૠલાંબૠછે" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u માં અકà«àª·àª° કિંમત.... કà«àª°àª®àª¾àª‚કન ઘણૠલાંબૠછે" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "નિયમિત સમીકરણ %s સરખાવતી વખતે ભૂલ: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE લાઈબà«àª°à«‡àª°à«€ UTF8 આધાર વિના કમà«àªªàª¾àªˆàª² થયેલ છે" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE લાઈબà«àª°à«‡àª°à«€ UTF8 ગà«àª£àª§àª°à«àª®à«‹ આધાર વિના કમà«àªªàª¾àªˆàª² થયેલ છે" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE લાઈબà«àª°à«‡àª°à«€ અસà«àª¸àª‚ગત વિકલà«àªªà«‹ સાથે કમà«àªªàª¾àªˆàª² થયેલ છે" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "નિયમિત સમીકરણ %s ને કમà«àªªàª¾àªˆàª² કરવામાં અકà«àª·àª° %d આગળ ભૂલ: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "નિયમિત સમીકરણ %s શà«àª°à«‡àª·à«àª  બનાવતી વખતે ભૂલ: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "હેકà«àªàª¾àª¡à«‡àª¸à«€àª®àª² અંક અથવા '}' ઈચà«àª›àª¿àª¤ છે" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "હેકà«àªàª¾àª¡à«‡àª¸à«€àª®àª² અંક ઈચà«àª›àª¿àª¤ છે" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "સંજà«àªžàª¾àª•ીય સંદરà«àª­àª®àª¾àª‚ '<' ગà«àª® થયેલ છે" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "અપૂરà«àª£ સંજà«àªžàª¾àª•ીય સંદરà«àª­" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "શૂનà«àª¯-લંબાઈ સંજà«àªžàª¾àª•ીય સંદરà«àª­" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "અંક ઈચà«àª›àª¿àª¤" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "અયોગà«àª¯ સંજà«àªžàª¾àª•ીય સંદરà«àª­" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "સà«àªŸà«àª°à«‡ અંત '\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "અજà«àªžàª¾àª¤ àªàª¸à«àª•ેપ કà«àª°àª®" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "બદલી લખાણ \"%s\" નà«àª‚ પદચà«àª›à«‡àª¦àª¨ કરતી વખતે અકà«àª·àª° %lu આગળ ભૂલ: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "અવતરણ ચિહà«àª¨àªµàª¾àª³à« વાકà«àª¯ અવતરણ ચિહà«àª¨àª¥à«€ શરૠથતૠનથી" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "આદેશ વાકà«àª¯àª®àª¾àª‚ અથવા બીજા શેલ ચિહà«àª¨àª¿àª¤ બંધબેસતા ન હોય તેવા અવતરણ ચિહà«àª¨" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "લખાણનો '\\' અકà«àª·àª° પછી તરત જ અંત આવે છે (લખાણનો '%s' હતà«)" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "%c માટે અવતરણ ચિહà«àª¨ મળે તે પહેલા લખાણનો અંત થાય છે(લખાણ '%s' હતà«)" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "વાકà«àª¯ ખાલી છે (અથવા તેમાં ફકà«àª¤ ખાલી જગà«àª¯àª¾ છે)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "(%s) બાળપà«àª°àª•à«àª°àª¿àª¯àª¾àª®àª¾àª‚થી માહિતી વાંચવામાં નિષà«àª«àª³" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "(%s)બાળપà«àª°àª•à«àª°àª¿àª¯àª¾àª®àª¾àª‚થી માહિતી વાંચતી વખતે select() માં આવતી અણધારી ભૂલ" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "(%s) waitpid() માં અાવતી અણાધારી ભૂલ" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "કોડ %ld સાથે બાળ પà«àª°àª•à«àª°àª¿àª¯àª¾ બહાર નીકળી ગઇ" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "બાળ પà«àª°àª•à«àª°àª¿àª¯àª¾ સંકેત %ld દà«àª¦àª¾àª°àª¾ મરેલ છે" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "બાળ પà«àª°àª•à«àª°àª¿àª¯àª¾ સંકેત %ld દà«àª¦àª¾àª°àª¾ બંધ થયેલ છે" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "બાળ પà«àª°àª•à«àª°àª¿àª¯àª¾ અસાધારણ રીતે બહાર નીકળી ગઇ" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "બાળ પાઈપ (%s)માંથી વાંચવામાં નિષà«àª«àª³" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) બાળપà«àª°àª•à«àª°àª¿àª¯àª¾ બનાવવામાં નિષà«àª«àª³" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "'%s' ડિરેકà«àªŸàª°à«€ બદલવામાં નિષà«àª«àª³(%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "\"%s\"બાળપà«àª°àª•à«àª°àª¿àª¯àª¾ ચલાવવામાં નિષà«àª«àª³ (%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "બાળપà«àª°àª•à«àª°àª¿àª¯àª¾ (%s)ના ઈનપà«àªŸ અથવા આઉટપà«àªŸàª¨à«‡ ફરીથી દિશા આપવામાં નિષà«àª«àª³" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "બાળપà«àª°àª•à«àª°àª¿àª¯àª¾ (%s)ની બાળપà«àª°àª•à«àª°àª¿àª¯àª¾ બનાવવામાં નિષà«àª«àª³" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "\"%s\" બાળપà«àª°àª•à«àª°àª¿àª¯àª¾ ચલાવતી વખતની અજà«àªžàª¾àª¤ ભૂલ" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "(%s)બાળ pid પાઈપમાંથી જરà«àª°à«€ માહિતી વાંચવામાં નિષà«àª«àª³" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "બાળ-પà«àª°àª•à«àª°àª¿àª¯àª¾ માંથી માહિતી વાંચવા માં નિષà«àª«àª³ છે" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr " (%s) બાળપà«àª°àª•à«àª°àª¿àª¯àª¾ સાથે સંપરà«àª• માટે પાઈપ બનાવવામાં નિષà«àª«àª³" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr " (%s) બાળપà«àª°àª•à«àª°àª¿àª¯àª¾ ચલાવવામાં નિષà«àª«àª³" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "અયોગà«àª¯ કારà«àª¯àª•à«àª°àª® નામ: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "દલીલ વેકà«àªŸàª°àª®àª¾àª‚ %d આગળ અયોગà«àª¯ શબà«àª¦àª®àª¾àª³àª¾: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "પરà«àª¯àª¾àªµàª°àª£àª®àª¾àª‚ અયોગà«àª¯ શબà«àª¦àª®àª¾àª³àª¾: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "અયોગà«àª¯ કામ આપતી ડિરેકà«àªŸàª°à«€: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "મદદગાર કારà«àª¯àª•à«àª°àª® (%s) ચલાવવામાં નિષà«àª«àª³" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "બાળ-પà«àª°àª•à«àª°àª¿àª¯àª¾àª®àª¾àª‚થી માહિતી વાંચતી વખતે g_io_channel_win32_poll() માં આવતી અણધારી ભૂલ" + +#: ../glib/gutf8.c:780 +msgid "Failed to allocate memory" +msgstr "મેમરીની ફાળવણી કરવામાં નિષà«àª«àª³" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "અકà«àª·àª° UTF-à«® ની સીમાની બહાર" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "પરીવરà«àª¤àª¿àª¤ ઈનપà«àªŸàª¨à«€ અંદર અયોગà«àª¯ શà«àª°à«‡àª£à«€" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "UTF-૧૬ ની સીમાની બહાર નો અકà«àª·àª°" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u બાઇટ" +msgstr[1] "%u બાઇટ" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s બાઇટ" +msgstr[1] "%s બાઇટ" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "જાનà«àª¯à«àª†àª°à«€" + +msgctxt "full month name with day" +msgid "February" +msgstr "ફેબà«àª°à«àª†àª°à«€" + +msgctxt "full month name with day" +msgid "March" +msgstr "મારà«àªš" + +msgctxt "full month name with day" +msgid "April" +msgstr "àªàªªà«àª°àª¿àª²" + +msgctxt "full month name with day" +msgid "May" +msgstr "મે" + +msgctxt "full month name with day" +msgid "June" +msgstr "જà«àª¨" + +msgctxt "full month name with day" +msgid "July" +msgstr "જà«àª²àª¾àª‡" + +msgctxt "full month name with day" +msgid "August" +msgstr "ઑગસà«àªŸ" + +msgctxt "full month name with day" +msgid "September" +msgstr "સેપà«àªŸà«‡àª®à«àª¬àª°" + +msgctxt "full month name with day" +msgid "October" +msgstr "ઑકà«àªŸà«‹àª¬àª°" + +msgctxt "full month name with day" +msgid "November" +msgstr "નવેમà«àª¬àª°" + +msgctxt "full month name with day" +msgid "December" +msgstr "ડિસેમà«àª¬àª°" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "જાનà«àª¯à«àª†àª°à«€" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ફેબà«àª°à«àª†àª°à«€" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "મારà«àªš" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "àªàªªà«àª°àª¿àª²" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "મે" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "જà«àª¨" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "જà«àª²àª¾àª‡" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ઑગસà«àªŸ" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "સેપà«àªŸà«‡àª®à«àª¬àª°" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "ઑકà«àªŸà«‹" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "નવેમà«àª¬àª°" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ડિસેમà«àª¬àª°" + +#~ msgid "URIs not supported" +#~ msgstr "URIs આધારભૂત નથી" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "કી ફાઈલ પાસે કી '%s' નથી" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "xmllint સાથે ઇનપà«àªŸ ફાઇલની પà«àª°àª•à«àª°àª¿àª¯àª¾ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata સાથે ઇનપà«àªŸ ફાઇલની પà«àª°àª•à«àª°àª¿àª¯àª¾ કરી રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "પેનà«àª¡àª¿àª‚ગ ભૂલ ને મેળવવામાં અસમરà«àª¥: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "ફાઈલ '%s' ને લખવા માટે ખોલવામાં નિષà«àª«àª³: fdopen() નિષà«àª«àª³: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "ફાઈલ '%s' પર લખવામાં નિષà«àª«àª³: fflush() નિષà«àª«àª³: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "ફાઈલ '%s' બંધ કરવામાં નિષà«àª«àª³: fclose() નિષà«àª«àª³: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "'%s' માટે અપૂરતી માહિતી મળેલ છે" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "અનિચà«àª›àª¨à«€àª¯ વિકલà«àªª લંબાઇ જà«àª¯àª¾àª°à«‡ ચકાસી રહà«àª¯àª¾ હોય જો SO_PASSCRED સોકેટ માટે સકà«àª°àª¿àª¯ થયેલ " +#~ "છે. ઇચà«àª›àª¿àª¤ %d bytes, %d મળà«àª¯à«àª‚" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "ખાલી શબà«àª¦àª®àª¾àª³àª¾àª“ માટે કારà«àª¯àª¸à«àª¥àª³ મરà«àª¯àª¾àª¦àª¾àª પહોંચી ગયા" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "કેસ-બદલતા àªàª¸à«àª•ેપો (\\l, \\L, \\u, \\U) અંહિ માનà«àª¯ નથી" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE જૂથનà«àª‚ પà«àª¨àª°àª¾àªµàª°à«àª¤àª¨ કરવાનà«àª‚ માનà«àª¯ નથી" + +#~ msgid "File is empty" +#~ msgstr "ફાઈલ ખાલી છે" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "કી ફાઈલ '%s' કી સમાવે છે કે જેની પાસે કિંમત છે જે ઈનà«àªŸàª°àªªà«àª°à«€àªŸ કરી શકાતી નથી." + +#~ msgid "This option will be removed soon." +#~ msgstr "આ વિકલà«àªª àªàª²à«àª¦à«€àª¥à«€ દૂર થઇ જશે." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "ફાઈલ '%s' કહેવામાં ભૂલ: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' માટે સેવાનો અહેવાલ નથી" + +#~ msgid "Error connecting: " +#~ msgstr "જોડાઇ રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: " + +#~ msgid "Error connecting: %s" +#~ msgstr "જોડાઇ રહà«àª¯àª¾ હોય તà«àª¯àª¾àª°à«‡ ભૂલ: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "unix માંથી વાંચતી વખતે ભૂલ: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "unix બંધ કરતી વખતે ભૂલ: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "unix માં લખતી વખતે ભૂલ: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "am" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" diff --git a/po/he.po b/po/he.po new file mode 100644 index 0000000..2870125 --- /dev/null +++ b/po/he.po @@ -0,0 +1,6267 @@ +# translation of glib.HEAD.he.po to Hebrew +# translation of glib.HEAD.po to Hebrew +# translation of glib.HEAD.po to +# translation of glib.HEAD.po to +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) 2006 THE PACKAGE'S COPYRIGHT HOLDER. +# Meir Kriheli , 2002. +# Gil 'Dolfin' Osher , 2002. +# Gil Osher , 2004. +# Yaron Shahrabani , 2010. +# Yosef Or Boczko , 2014-2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD.he\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-07 09:24+0000\n" +"PO-Revision-Date: 2022-03-07 20:46+0200\n" +"Last-Translator: Yosef Or Boczko \n" +"Language-Team: Hebrew \n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n%10==0 ? " +"2 : 3)\n" +"X-Generator: Gtranslator 40.0\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Setting default applications not supported yet" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "Setting application as last used for type not supported yet" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication options" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Show GApplication options" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Enter GApplication service mode (use from D-Bus service files)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Override the application’s ID" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Replace the running instance" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Print help" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Print version" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Print version information and exit" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "List applications" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "List the installed D-Bus activatable applications (by .desktop files)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Launch an application" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Launch the application (with optional files to open)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FILE…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Activate an action" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invoke an action on the application" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "List available actions" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "List static actions for an application (from .desktop file)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMMAND" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "The command to print detailed help for" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Application identifier in D-Bus format (eg: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FILE" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Optional relative or absolute filenames, or URIs to open" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACTION" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "The action name to invoke" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Optional parameter to the action invocation, in GVariant format" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Unknown command %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Usage:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Arguments:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Commands:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s command requires an application id to directly follow\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "invalid application id: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†takes no arguments\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "unable to connect to D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "error sending %s message to application: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "action name must be given after application id\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "error parsing action parameter: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "actions accept a maximum of one parameter\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions command takes only the application id" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "unable to find desktop file for application %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"unrecognised command: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Too large count value passed to %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Seek not supported on base stream" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Cannot truncate GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Stream is already closed" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Truncate not supported on base stream" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1873 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operation was cancelled" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Invalid object, not initialized" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Incomplete multibyte sequence in input" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Not enough space in destination" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Invalid byte sequence in conversion input" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Error during conversion: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Cancellable initialization not supported" + +# *** This file should not be translated to hebrew, please only copy the english text *** +# *** Old hebrew ranslation is commented for backup sake *** +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Conversion from character set “%s†to “%s†is not supported" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Could not open converter from “%s†to “%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s type" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Unknown type" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s filetype" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials contains invalid data" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials is not implemented on this OS" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "There is no GCredentials support for your platform" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials does not contain a process ID on this OS" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Credentials spoofing is not possible on this OS" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Unexpected early end-of-stream" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Unsupported key “%s†in address entry “%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Meaningless key/value pair combination in address entry “%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Error in address “%s†— the “%s†attribute is malformed" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Unknown or unsupported transport “%s†for address “%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Address element “%s†does not contain a colon (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Transport name in address element “%s†must not be empty" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Error in address “%s†— the host attribute is missing or malformed" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Error in address “%s†— the port attribute is missing or malformed" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Error in address “%s†— the noncefile attribute is missing or malformed" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Error auto-launching: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Error opening nonce file “%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Error reading from nonce file “%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Error writing contents of nonce file “%s†to stream:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "The given address is empty" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "×œ× × ×™×ª×Ÿ לפצל ×פיק הודעה כש־AT_SECURE מוגדר" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Cannot spawn a message bus without a machine-id: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Cannot autolaunch D-Bus without X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Error spawning command line “%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "Cannot determine session bus address (not implemented for this OS)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7334 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7343 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Unknown bus type %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Unexpected lack of content trying to read a line" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Unexpected lack of content trying to (safely) read a line" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "User IDs must be the same for peer and server" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Error when getting information for directory “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Error creating directory “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operation not supported" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Error opening keyring “%s†for reading: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Line %d of the keyring at “%s†with content “%s†is malformed" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Didn’t find cookie with id %d in the keyring at “%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Error creating lock file “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Error deleting stale lock file “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Error closing (unlinked) lock file “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Error unlinking lock file “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Error opening keyring “%s†for writing: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Additionally, releasing the lock for “%s†also failed: %s) " + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2418 +msgid "The connection is closed" +msgstr "The connection is closed" + +#: gio/gdbusconnection.c:1903 +msgid "Timeout was reached" +msgstr "Timeout was reached" + +#: gio/gdbusconnection.c:2541 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Unsupported flags encountered when constructing a client-side connection" + +#: gio/gdbusconnection.c:4269 gio/gdbusconnection.c:4623 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" + +#: gio/gdbusconnection.c:4414 +#, c-format +msgid "No such property “%sâ€" +msgstr "No such property “%sâ€" + +#: gio/gdbusconnection.c:4426 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Property “%s†is not readable" + +#: gio/gdbusconnection.c:4437 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Property “%s†is not writable" + +#: gio/gdbusconnection.c:4457 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" + +#: gio/gdbusconnection.c:4562 gio/gdbusconnection.c:4777 +#: gio/gdbusconnection.c:6760 +#, c-format +msgid "No such interface “%sâ€" +msgstr "No such interface “%sâ€" + +#: gio/gdbusconnection.c:4999 gio/gdbusconnection.c:7274 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "No such interface “%s†on object at path %s" + +#: gio/gdbusconnection.c:5100 +#, c-format +msgid "No such method “%sâ€" +msgstr "No such method “%sâ€" + +#: gio/gdbusconnection.c:5131 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Type of message, “%sâ€, does not match expected type “%sâ€" + +#: gio/gdbusconnection.c:5334 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "An object is already exported for the interface %s at %s" + +#: gio/gdbusconnection.c:5561 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Unable to retrieve property %s.%s" + +#: gio/gdbusconnection.c:5617 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Unable to set property %s.%s" + +#: gio/gdbusconnection.c:5796 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Method “%s†returned type “%sâ€, but expected “%sâ€" + +#: gio/gdbusconnection.c:6872 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Method “%s†on interface “%s†with signature “%s†does not exist" + +#: gio/gdbusconnection.c:6993 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "A subtree is already exported for %s" + +#: gio/gdbusconnection.c:7282 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Object does not exist at path “%sâ€" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "type is INVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL message: PATH or MEMBER header field is missing" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN message: REPLY_SERIAL header field is missing" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "‫Wanted to read %lu byte but only got %lu" +msgstr[1] "‫Wanted to read %lu bytes but only got %lu" +msgstr[2] "‫Wanted to read %lu bytes but only got %lu" +msgstr[3] "‫Wanted to read %lu bytes but only got %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Expected NUL byte after the string “%s†but found byte %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Value nested too deeply" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Parsed value “%s†is not a valid D-Bus object path" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Parsed value “%s†is not a valid D-Bus signature" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[1] "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[2] "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[3] "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Empty structures (tuples) are not allowed in D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Parsed value “%s†for variant is not a valid D-Bus signature" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Invalid major protocol version. Expected 1 but found %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Signature header found but is not of type signature" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "Signature header with signature “%s†found but message body is empty" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Parsed value “%s†is not a valid D-Bus signature (for body)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "‫No signature header in message but the message body is %u byte" +msgstr[1] "‫No signature header in message but the message body is %u bytes" +msgstr[2] "‫No signature header in message but the message body is %u byte" +msgstr[3] "‫No signature header in message but the message body is %u byte" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Cannot deserialize message: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Number of file descriptors in message (%d) differs from header field (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Cannot serialize message: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Message body has signature “%s†but there is no signature header" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Message body is empty but signature in the header field is “(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Error return with body of type “%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Error return with empty body" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Type any character to close this window)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Session dbus not running, and autolaunch failed" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Unable to get Hardware profile: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Unable to load %s or %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Error calling StartServiceByName for %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Unexpected reply %d from StartServiceByName(\"%s\") method" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstract namespace not supported" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Cannot specify nonce file when creating a server" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Error writing nonce file at “%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "The string “%s†is not a valid D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Cannot listen on unsupported transport “%sâ€" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Error: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Error parsing introspection XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Error: %s is not a valid name\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Error: %s is not a valid object path\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Connect to the system bus" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Connect to the session bus" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Connect to given D-Bus address" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Connection Endpoint Options:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Options specifying the connection endpoint" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "No connection endpoint specified" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Multiple connection endpoints specified" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Warning: According to introspection data, interface “%s†does not exist\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Optional destination for signal (unique name)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Object path to emit signal on" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Signal and interface name" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emit a signal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Error connecting: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Error: %s is not a valid unique bus name.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Error: Object path is not specified\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Error: Signal name is not specified\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Error: Signal name “%s†is invalid\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Error: %s is not a valid interface name\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Error: %s is not a valid member name\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Error parsing parameter %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Error flushing connection: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Destination name to invoke method on" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Object path to invoke method on" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Method and interface name" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Timeout in seconds" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Allow interactive authorization" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Invoke a method on a remote object." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Error: Destination is not specified\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Error: %s is not a valid bus name\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Error: Method name is not specified\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Error: Method name “%s†is invalid\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Error parsing parameter %d of type “%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Error adding handle %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Destination name to introspect" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Object path to introspect" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Print XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Introspect children" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Only print properties" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspect a remote object." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Destination name to monitor" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Object path to monitor" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitor a remote object." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Error: can’t monitor a non-message-bus connection\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Service to activate before waiting for the other one (well-known name)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPTION…] BUS-NAME" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Wait for a bus name to appear." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Error: A service to activate for must be specified.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Error: A service to wait for must be specified.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Error: Too many arguments.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Error: %s is not a valid well-known bus name.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Not authorized to change debug settings" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Unnamed" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Desktop file didn’t specify Exec field" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Unable to find terminal required for application" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Can’t create user application configuration folder %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Can’t create user MIME configuration folder %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Application information lacks an identifier" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Can’t create user desktop file %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Custom definition for %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "drive doesn’t implement eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "drive doesn’t implement eject or eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "drive doesn’t implement polling for media" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "drive doesn’t implement start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "drive doesn’t implement stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS backend does not implement TLS binding retrieval" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS support is not available" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS support is not available" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Can’t handle version %d of GEmblem encoding" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Malformed number of tokens (%d) in GEmblem encoding" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Can’t handle version %d of GEmblemedIcon encoding" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Malformed number of tokens (%d) in GEmblemedIcon encoding" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Expected a GEmblem for GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Containing mount does not exist" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Can’t copy over directory" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Can’t copy directory over directory" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Target file exists" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Can’t recursively copy directory" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Symbolic links not supported" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Error opening file: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Copy (reflink/clone) between mounts is not supported" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Copy (reflink/clone) is not supported or invalid" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Copy (reflink/clone) is not supported or didn’t work" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Can’t copy special file" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Invalid symlink value given" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Symbolic links not supported" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Trash not supported" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "File names cannot contain “%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "volume doesn’t implement mount" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "No application is registered as handling this file" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator is closed" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "File enumerator has outstanding operation" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "File enumerator is already closed" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Can’t handle version %d of GFileIcon encoding" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Malformed input data for GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Stream doesn’t support query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Seek not supported on stream" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Truncate not allowed on input stream" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Truncate not supported on stream" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Invalid hostname" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Bad HTTP proxy reply" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP proxy connection not allowed" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP proxy authentication failed" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP proxy authentication required" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP proxy connection failed: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP proxy response too big" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP proxy server closed connection unexpectedly." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Wrong number of tokens (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "No type for class name %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Type %s does not implement the GIcon interface" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Type %s is not classed" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Malformed version number: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Type %s does not implement from_tokens() on the GIcon interface" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Can’t handle the supplied version of the icon encoding" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "No address specified" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Length %u is too long for address" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Address has bits set beyond prefix length" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Could not parse “%s†as IP address mask" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Not enough space for socket address" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Unsupported socket address" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Input stream doesn’t implement read" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Stream has outstanding operation" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copy with file" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Keep with file when moved" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†takes no arguments" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Usage:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Print version information and exit." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Commands:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatenate files to standard output" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copy one or more files" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Show information about locations" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Launch an application from a desktop file" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "List the contents of locations" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Get or set the handler for a mimetype" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Create directories" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitor files and directories for changes" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Mount or unmount the locations" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Move one or more files" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Open files with the default application" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Rename a file" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Delete one or more files" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Read from standard input and save" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Set a file attribute" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Move files or directories to the trash" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Lists the contents of locations in a tree" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Use %s to get detailed help.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Error writing to stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCATION" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatenate files and print to standard output." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "No locations given" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "No target directory" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Show progress" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Prompt before overwrite" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Preserve all attributes" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Backup existing destination files" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Never follow symbolic links" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Use default permissions for the destination" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Transferred %s out of %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SOURCE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINATION" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copy one or more files from SOURCE to DESTINATION." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Destination %s is not a directory" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: overwrite “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "List writable attributes" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Get file system info" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "The attributes to get" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTES" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Don’t follow symbolic links" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "attributes:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "display name: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "edit name: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "name: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "type: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "size: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "hidden\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "local path: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix mount: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Settable attributes:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Writable attribute namespaces:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Show information about locations." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-FILE [FILE-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "No desktop file given" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "The launch command is not currently supported on this platform" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Unable to load ‘%s‘: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Unable to load application information for ‘%s‘" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Unable to launch application ‘%s’: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Show hidden files" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Use a long listing format" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Print display names" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Print full URIs" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "List the contents of the locations." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "HANDLER" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Get or set the handler for a mimetype." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Must specify a single mimetype, and maybe a handler" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "No default applications for “%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Default application for “%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registered applications:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "No registered applications\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Recommended applications:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "No recommended applications\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Failed to load info for handler “%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Failed to set “%s†as the default handler for “%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Create parent directories" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Create directories." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitor a directory (default: depends on type)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitor a file (default: depends on type)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Monitor a file directly (notices changes made via hardlinks)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitors a file directly, but doesn’t report changes" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "Report moves and renames as simple deleted/created events" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Watch for mount events" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitor files or directories for changes." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Mount as mountable" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Mount volume with device file, or other identifier" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Unmount" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Eject" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Stop drive with device file" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DEVICE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Unmount all mounts with the given scheme" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEME" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignore outstanding file operations when unmounting or ejecting" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Use an anonymous user when authenticating" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "List" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitor events" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Show extra information" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "The numeric PIM when unlocking a VeraCrypt volume" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Mount a TCRYPT hidden volume" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Mount a TCRYPT system volume" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonymous access denied" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "No drive for device file" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "No volume for given ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Mount or unmount the locations." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Don’t use copy and delete fallback" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Move one or more files from SOURCE to DEST." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Target %s is not a directory" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Open files with the default application that\n" +"is registered to handle files of this type." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignore nonexistent files, never prompt" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Delete the given files." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Rename a file." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Missing argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Too many arguments" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Rename successful. New uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Only create if not existing" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Append to end of file" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "When creating, restrict access to the current user" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "When replacing, replace as if the destination did not exist" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Print new etag at end" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "The etag of the file being overwritten" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Error reading from standard input" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag not available\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Read from standard input and save to DEST." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "No destination given" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Type of the attribute" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATTRIBUTE" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALUE" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Set a file attribute of LOCATION." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Location not specified" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Attribute not specified" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Value not specified" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Invalid attribute type “%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Empty the trash" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "List files in the trash with their original locations" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Unable to find original path" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Unable to recreate original location: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Unable to move file to its original location: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Move/Restore files or directories to the trash." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Location given doesn't start with trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Follow symbolic links, mounts and shortcuts" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "List contents of directories in a tree-like format." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> not allowed inside <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> not allowed at toplevel" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "File %s appears multiple times in the resource" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Failed to locate “%s†in any source directory" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Failed to locate “%s†in current directory" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Unknown processing option “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "%s preprocessing requested, but %s is not set, and %s is not in PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Error reading file %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Error compressing file %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "text may not appear inside <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Show program version and exit" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Name of the output file" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"The directories to load files referenced in FILE from (default: current " +"directory)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Generate output in the format selected for by the target filename extension" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Generate source header" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Generate source code used to link in the resource file into your code" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Generate dependency list" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Name of the dependency file to generate" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Include phony targets in the generated dependency file" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Don’t automatically create and register resource" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Don’t export functions; declare them G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C identifier name used for the generated source code" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "The target C compiler (default: the CC environment variable)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "You should give exactly one file name\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "nick must be a minimum of 2 characters" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Invalid numeric value" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' already specified" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "flags values must have at most 1 bit set" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> must contain at least one " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> is not contained in the specified range" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> is not a valid member of the specified enumerated type" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> contains string not in the specified flags type" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> contains a string not in " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " already specified for this key" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " not allowed for keys of type “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " specified minimum is greater than maximum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "unsupported l10n category: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n requested, but no gettext domain given" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "translation context given for value without l10n enabled" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Failed to parse value of type “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" cannot be specified for keys tagged as having an enumerated type" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " already specified for this key" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " not allowed for keys of type “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " already given" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " must contain at least one " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " already specified for this key" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" can only be specified for keys with enumerated or flags types or " +"after " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" given when “%s†is already a member of the enumerated " +"type" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " given when was already given" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "alias target “%s†is not in enumerated type" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "alias target “%s†is not in " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " must contain at least one " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Empty names are not permitted" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Invalid name “%sâ€: names must begin with a lowercase letter" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Invalid name “%sâ€: maximum length is 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Cannot add keys to a “list-of†schema" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" shadows in ; use " +"to modify value" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> not (yet) defined." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Invalid GVariant type string “%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " given but schema isn’t extending anything" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "No to override" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " already specified" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " extends not yet existing schema “%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " is list of not yet existing schema “%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Cannot be a list of a schema with a path" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Cannot extend a schema with a path" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" is a list, extending which is not a list" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" extends but “%s†" +"does not extend “%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "A path, if given, must begin and end with a slash" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "The path of a list must end with “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> already specified" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Only one <%s> element allowed inside <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> not allowed at the top level" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Element is required in " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Text may not appear inside <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Warning: undefined reference to " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict was specified; exiting." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "This entire file has been ignored." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignoring this file." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Where to store the gschemas.compiled file" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Abort on any errors in schemas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Do not write the gschema.compiled file" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Do not enforce key name restrictions" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "You should give exactly one directory name" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "No schema files found: doing nothing." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "No schema files found: removed existing output file." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Invalid filename %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Error getting filesystem info for %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Containing mount for file %s not found" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Can’t rename root directory" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Error renaming file %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Can’t rename file, filename already exists" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Invalid filename" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Error opening file %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Error removing file %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Error trashing file %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Unable to create trash directory %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Unable to find toplevel directory to trash %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Trashing on system internal mounts is not supported" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Unable to find or create trash directory %s to trash %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Unable to create trashing info file for %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Unable to trash file %s across filesystem boundaries" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Unable to trash file %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Unable to trash file %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Error creating directory %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Filesystem does not support symbolic links" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Error making symbolic link %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Error moving file %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Can’t move directory over directory" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Backup file creation failed" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Error removing target file: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Move between mounts not supported" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Could not determine the disk usage of %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Attribute value must be non-NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Invalid attribute type (string expected)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Invalid extended attribute name" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Error setting extended attribute “%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (invalid encoding)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Error when getting information for file “%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Error when getting information for file descriptor: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Invalid attribute type (uint32 expected)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Invalid attribute type (uint64 expected)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Invalid attribute type (byte string expected)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Cannot set permissions on symlinks" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Error setting permissions: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Error setting owner: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "symlink must be non-NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Error setting symlink: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Error setting symlink: file is not a symlink" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Extra nanoseconds %d for UNIX timestamp %lld are negative" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX timestamp %lld does not fit into 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "UNIX timestamp %lld is outside of the range supported by Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "File name “%s†cannot be converted to UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "File “%s†cannot be opened: Windows Error %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Error setting modification or access time for file “%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Error setting modification or access time: %s" + +# c-format +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux context must be non-NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux is not enabled on this system" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Error setting SELinux context: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Setting attribute %s not supported" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Error reading from file: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Error closing file: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Error seeking in file: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Unable to find default local file monitor type" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Error writing to file: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Error removing old backup link: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Error creating backup copy: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Error renaming temporary file: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "Error truncating file: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Error opening file “%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Target file is a directory" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Target file is not a regular file" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "The file was externally modified" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Error removing old file: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Invalid GSeekType supplied" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Invalid seek request" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Cannot truncate GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Memory output stream not resizable" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Failed to resize memory output stream" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Amount of memory required to process the write is larger than available " +"address space" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Requested seek before the beginning of the stream" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Requested seek beyond the end of the stream" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "mount doesn’t implement “unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount doesn’t implement “ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "mount doesn’t implement “unmount†or “unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "mount doesn’t implement “eject†or “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "mount doesn’t implement “remountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "mount doesn’t implement content type guessing" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "mount doesn’t implement synchronous content type guessing" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Hostname “%s†contains “[†but not “]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Network unreachable" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Host unreachable" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Could not create network monitor: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Could not create network monitor: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Could not get network status: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager not running" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager version too old" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Output stream doesn’t implement write" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Sum of vectors passed to %s too large" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Source stream is already closed" + +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Error resolving “%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s not implemented" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Invalid domain" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "The resource at “%s†does not exist" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "The resource at “%s†failed to decompress" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "The resource at “%s†is not a directory" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Input stream doesn’t implement seek" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "List sections containing resources in an elf FILE" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECTION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extract a resource file to stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION An (optional) elf section name\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND The (optional) command to explain\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE An elf file (a binary or a shared library)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[PATH]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH An (optional) resource path (may be partial)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "PATH" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " PATH A resource path\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "No such schema “%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Schema “%s†is not relocatable (path must not be specified)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schema “%s†is relocatable (path must be specified)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Empty path given.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Path must begin with a slash (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Path must end with a slash (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Path must not contain two adjacent slashes (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "The provided value is outside of the valid range\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "The key is not writable\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "List the installed (non-relocatable) schemas" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "List the installed relocatable schemas" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "List the keys in SCHEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "List the children of SCHEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Get the value of KEY" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Query the range of valid values for KEY" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Query the description for KEY" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Set the value of KEY to VALUE" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Reset KEY to its default value" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Reset all keys in SCHEMA to their defaults" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Check if KEY is writable" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR A directory to search for additional schemas\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY The (optional) key within the schema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KEY The key within the schema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALUE The value to set\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Could not load schemas from %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "No schemas installed\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Empty schema name given\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "No such key “%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Invalid socket, not initialized" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Invalid socket, initialization failed due to: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Socket is already closed" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Socket I/O timed out" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "creating GSocket from fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Unable to create socket: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Unknown family was specified" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Unknown protocol was specified" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Cannot use datagram operations on a non-datagram socket." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "Cannot use datagram operations on a socket with a timeout set." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "could not get local address: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "could not get remote address: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "could not listen: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Error binding to address %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Error joining multicast group: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Error leaving multicast group: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "No support for source-specific multicast" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Unsupported socket family" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "source-specific not an IPv4 address" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Interface name too long" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interface not found: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "No support for IPv4 source-specific multicast" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "No support for IPv6 source-specific multicast" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Error accepting connection: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Connection in progress" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Unable to get pending error: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Error receiving data: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Error sending data: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Unable to shutdown socket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Error closing socket: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Waiting for socket condition: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Unable to send message: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Message vectors too large" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Error sending message: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage not supported on Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Error receiving message: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Unable to read socket credentials: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials not implemented for this OS" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Could not connect to proxy server %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Could not connect to %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Could not connect: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Proxying over a non-TCP connection is not supported." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proxy protocol “%s†is not supported." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Listener is already closed" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Added socket is closed" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 does not support IPv6 address “%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Username is too long for SOCKSv4 protocol" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Hostname “%s†is too long for SOCKSv4 protocol" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "The server is not a SOCKSv4 proxy server." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Connection through SOCKSv4 server was rejected" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "The server is not a SOCKSv5 proxy server." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "The SOCKSv5 proxy requires authentication." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Username or password is too long for SOCKSv5 protocol." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 authentication failed due to wrong username or password." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Hostname “%s†is too long for SOCKSv5 protocol" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "The SOCKSv5 proxy server uses unknown address type." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Internal SOCKSv5 proxy server error." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 connection not allowed by ruleset." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Host unreachable through SOCKSv5 server." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Network unreachable through SOCKSv5 proxy." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Connection refused through SOCKSv5 proxy." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 proxy does not support “connect†command." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 proxy does not support provided address type." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Unknown SOCKSv5 proxy error." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Failed to create pipe for communicating with child process (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Pipes are not supported in this platform" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Can’t handle version %d of GThemedIcon encoding" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "No valid addresses were found" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Error reverse-resolving “%sâ€: %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "No DNS record of the requested type for “%sâ€" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Temporarily unable to resolve “%sâ€" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Error resolving “%sâ€" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "No PEM-encoded private key found" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Cannot decrypt PEM-encoded private key" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Could not parse PEM-encoded private key" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "No PEM-encoded certificate found" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Could not parse PEM-encoded certificate" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "The current TLS backend does not support PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "This GTlsBackend does not support creating PKCS #11 certificates" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"This is the last chance to enter the password correctly before your access " +"is locked out." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "The password entered is incorrect." + +#: gio/gunixconnection.c:125 +#| msgid "Setting attribute %s not supported" +msgid "Sending FD is not supported" +msgstr "Sending FD is not supported" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "‫Expecting 1 control message, got %d" +msgstr[1] "‫Expecting 1 control message, got %d" +msgstr[2] "‫Expecting 1 control message, got %d" +msgstr[3] "‫Expecting 1 control message, got %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Unexpected type of ancillary data" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "" +"‫Expecting one fd, but got %d\n" +"‬\n" +msgstr[1] "" +"‫Expecting one fd, but got %d\n" +"‬\n" +msgstr[2] "" +"‫Expecting one fd, but got %d\n" +"‬\n" +msgstr[3] "" +"‫Expecting one fd, but got %d\n" +"‬\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Received invalid fd" + +#: gio/gunixconnection.c:238 +#| msgid "Setting attribute %s not supported" +msgid "Receiving FD is not supported" +msgstr "Receiving FD is not supported" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Error sending credentials: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Error checking if SO_PASSCRED is enabled for socket: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Error enabling SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Expecting to read a single byte for receiving credentials but read zero bytes" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Not expecting control message, but got %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Error while disabling SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Error reading from file descriptor: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Error closing file descriptor: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Filesystem root" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Error writing to file descriptor: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Abstract UNIX domain socket addresses not supported on this system" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "volume doesn’t implement eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volume doesn’t implement eject or eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Error reading from file: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Error closing file: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Error writing to file: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Not enough memory" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Internal error: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Need more input" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Invalid hostname" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Address to listen on" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignored, for compat with GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Print address" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Print address in shell mode" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Run a dbus service" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Wrong args\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Unexpected attribute “%s†for element “%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Attribute “%s†of element “%s†not found" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Unexpected tag “%sâ€, tag “%s†expected" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Unexpected tag “%s†inside “%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Invalid date/time ‘%s’ in bookmark file" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "No valid bookmark file found in data dirs" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "A bookmark for URI “%s†already exists" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "No bookmark found for URI “%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "No MIME type defined in the bookmark for URI “%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "No private flag has been defined in bookmark for URI “%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "No groups set in bookmark for URI “%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "No application with name “%s†registered a bookmark for “%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Failed to expand exec line “%s†with URI “%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Unrepresentable character in conversion input" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Partial character sequence at end of input" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Cannot convert fallback “%s†to codeset “%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Embedded NUL byte in conversion input" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Embedded NUL byte in conversion output" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "The URI “%s†is not an absolute URI using the “file†scheme" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "The local file URI “%s†may not include a “#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "The URI “%s†is invalid" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "The hostname of the URI “%s†is invalid" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "The URI “%s†contains invalidly escaped characters" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "The pathname “%s†is not an absolute path" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Z %H:%M:%S %Y %b %d %a" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %P" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "ינו×ר" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "פברו×ר" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "מרץ" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "×פריל" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "מ××™" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "יוני" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "יולי" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "×וגוסט" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "ספטמבר" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "×וקטובר" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "נובמבר" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "דצמבר" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ינו" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "פבר" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "מרץ" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "×פר" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "מ××™" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "יונ" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "יול" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "×וג" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "ספט" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "×וק" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "נוב" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "דצמ" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "×™×•× ×©× ×™" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "×™×•× ×©×œ×™×©×™" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "×™×•× ×¨×‘×™×¢×™" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "×™×•× ×—×ž×™×©×™" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "×™×•× ×©×™×©×™" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "שבת" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "×™×•× ×¨×שון" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ב׳" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ג׳" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ד׳" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "×”" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ו׳" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ש׳" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "×׳" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "ינו×ר" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "פברו×ר" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "מרץ" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "×פריל" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "מ××™" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "יוני" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "יולי" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "×וגוסט" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "ספטמבר" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "×וקטובר" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "נובמבר" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "דצמבר" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ינו" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "פבר" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "מרץ" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "×פר" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "מ××™" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "יונ" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "יול" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "×וג" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "ספט" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "×וק" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "נוב" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "דצמ" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Error opening directory “%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "‫Could not allocate %lu byte to read file “%sâ€" +msgstr[1] "‫Could not allocate %lu bytes to read file “%sâ€" +msgstr[2] "‫Could not allocate %lu bytes to read file “%sâ€" +msgstr[3] "‫Could not allocate %lu bytes to read file “%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Error reading file “%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "File “%s†is too large" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Failed to read from file “%sâ€: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Failed to open file “%sâ€: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Failed to get attributes of file “%sâ€: fstat() failed: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Failed to open file “%sâ€: fdopen() failed: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Failed to write file “%sâ€: write() failed: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Failed to write file “%sâ€: fsync() failed: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Failed to create file “%sâ€: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Existing file “%s†could not be removed: g_unlink() failed: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Template “%s†invalid, should not contain a “%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Template “%s†doesn’t contain XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Failed to read the symbolic link “%sâ€: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Could not open converter from “%s†to “%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Can’t do a raw read in g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Left over unconverted data in read buffer" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Channel terminates in a partial character" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Can’t do a raw read in g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Valid key file could not be found in search dirs" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Not a regular file" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Invalid group name: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Key file does not start with a group" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "×©× ×”×ž×¤×ª×— שגוי: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Key file contains unsupported encoding “%sâ€" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Key file does not have group “%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Key file does not have key “%s†in group “%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Key file contains key “%s†with value “%s†which is not UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Key file contains key “%s†which has a value that cannot be interpreted." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Key “%s†in group “%s†has value “%s†where %s was expected" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Key file contains escape character at end of line" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Key file contains invalid escape sequence “%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Value “%s†cannot be interpreted as a number." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Integer value “%s†out of range" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Value “%s†cannot be interpreted as a float number." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Value “%s†cannot be interpreted as a boolean." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Failed to map %s%s%s%s: mmap() failed: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Failed to open file “%sâ€: open() failed: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Error on line %d char %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Invalid UTF-8 encoded text in name — not valid “%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†is not a valid name" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†is not a valid name: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Error on line %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Character reference “%-.*s†does not encode a permitted character" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Empty entity “&;†seen; valid entities are: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Entity name “%-.*s†is not known" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Document must begin with an element (e.g. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" + +# c-format +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Too many attributes in element “%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%s†is not a valid character following the close element name “%sâ€; the " +"allowed character is “>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Element “%s†was closed, no element is currently open" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Element “%s†was closed, but the currently open element is “%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Document was empty or contained only whitespace" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Document ended unexpectedly just after an open angle bracket “<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Document ended unexpectedly inside an element name" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Document ended unexpectedly inside an attribute name" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Document ended unexpectedly inside an element-opening tag." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Document ended unexpectedly while inside an attribute value" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Document ended unexpectedly inside the close tag for element “%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Document ended unexpectedly inside the close tag for an unopened element" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Document ended unexpectedly inside a comment or processing instruction" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPTION…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Help Options:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Show help options" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Show all help options" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Application Options:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Options:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Cannot parse integer value “%s†for %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Integer value “%s†for %s out of range" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Cannot parse double value “%s†for %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Double value “%s†for %s out of range" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Error parsing option %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Missing·argument·for·%s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Unknown option %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "corrupted object" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "internal error or corrupted object" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "out of memory" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "backtracking limit reached" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "the pattern contains items not supported for partial matching" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "internal error" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "back references as conditions are not supported for partial matching" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "recursion limit reached" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "invalid combination of newline flags" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "bad offset" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "short utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "recursion loop" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "unknown error" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ at end of pattern" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c at end of pattern" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "unrecognized character following \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "numbers out of order in {} quantifier" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "number too big in {} quantifier" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "missing terminating ] for character class" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "invalid escape sequence in character class" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "range out of order in character class" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nothing to repeat" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "unexpected repeat" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "unrecognized character after (? or (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX named classes are supported only within a class" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "missing terminating )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "reference to non-existent subpattern" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "missing ) after comment" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "regular expression is too large" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "failed to get memory" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") without opening (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "code overflow" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "unrecognized character after (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind assertion is not fixed length" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "malformed number or name after (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "conditional group contains more than two branches" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "assertion expected after (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R or (?[+-]digits must be followed by )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "unknown POSIX class name" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX collating elements are not supported" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "character value in \\x{...} sequence is too large" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "invalid condition (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C not allowed in lookbehind assertion" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "recursive call could loop indefinitely" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "unrecognized character after (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "missing terminator in subpattern name" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "two named subpatterns have the same name" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "malformed \\P or \\p sequence" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "unknown property name after \\P or \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "subpattern name is too long (maximum 32 characters)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "too many named subpatterns (maximum 10,000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "octal value is greater than \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "overran compiling workspace" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "previously-checked referenced subpattern not found" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE group contains more than one branch" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "inconsistent NEWLINE options" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "a numbered reference must not be zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) not recognized" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "number is too big" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "missing subpattern name after (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "digit expected after (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] is an invalid data character in JavaScript compatibility mode" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "different names for subpatterns of the same number are not allowed" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) must have an argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c must be followed by an ASCII character" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k is not followed by a braced, angle-bracketed, or quoted name" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N is not supported in a class" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "too many forward references" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "character value in \\u.... sequence is too large" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Error while matching regular expression %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE library is compiled without UTF8 support" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE library is compiled without UTF8 properties support" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE library is compiled with incompatible options" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Error while optimizing regular expression %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Error while compiling regular expression %s at char %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "hexadecimal digit or “}†expected" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "hexadecimal digit expected" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "missing “<†in symbolic reference" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "unfinished symbolic reference" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "zero-length symbolic reference" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "digit expected" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "illegal symbolic reference" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "stray final “\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "unknown escape sequence" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Error while parsing replacement text “%s†at char %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Quoted text doesn’t begin with a quotation mark" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Unmatched quotation mark in command line or other shell-quoted text" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Text ended just after a “\\†character. (The text was “%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "Text ended before matching quote was found for %c. (The text was “%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Text was empty (or contained only whitespace)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Failed to read data from child process (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Unexpected error in reading data from a child process (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Unexpected error in waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Child process exited with code %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Child process killed by signal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Child process stopped by signal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Child process exited abnormally" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Failed to read from child pipe (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Failed to spawn child process “%s†(%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Failed to fork (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Failed to change to directory “%s†(%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Failed to execute child process “%s†(%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Failed to open file to remap file descriptor (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Failed to duplicate file descriptor for child process (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Failed to fork child process (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Failed to close file descriptor for child process (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Unknown error executing child process “%sâ€" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Failed to read enough data from child pid pipe (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Failed to read data from child process" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Failed to execute child process (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +#| msgid "Failed to fork child process (%s)" +msgid "Failed to dup() in child process (%s)" +msgstr "Failed to dup() in child process (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Invalid program name: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Invalid string in argument vector at %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Invalid string in environment: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Invalid working directory: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Failed to execute helper program (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Empty string is not a number" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†is not a signed number" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Number “%s†is out of bounds [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†is not an unsigned number" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Invalid %-encoding in URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Illegal character in URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Non-UTF-8 characters in URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Invalid IPv6 address ‘%.*s’ in URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Illegal encoded IP address ‘%.*s’ in URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Illegal internationalized hostname ‘%.*s’ in URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Could not parse port ‘%.*s’ in URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Port ‘%.*s’ in URI is out of range" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI ‘%s’ is not an absolute URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI ‘%s’ has no host component" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI is not absolute, and no base URI was provided" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "×—×¡×¨×™× â€š=’ וערך משתנה" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "הקצ×ת זיכרון נכשלה" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "התו מחוץ לטווח עבור UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "רצף שגוי בקלט ההמרה" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "התו מחוץ לטווח עבור UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f ק״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f מ״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ג״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ט״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f פ״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ×״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f קי״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f מבי״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f גיב״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f טבי״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f פבי״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f ×ק״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f ק״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f מ״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f ג״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f ט״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f פ״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f ×״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f ק״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f מ״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f ג״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f ט״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f פ״ב" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f ×״ב" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "בית ×חד" +msgstr[1] "שני בתי×" +msgstr[2] "‫%u בתי×" +msgstr[3] "‫%u בתי×" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "סיבית ×חת" +msgstr[1] "שתי סיביות" +msgstr[2] "‫%u סיביות" +msgstr[3] "‫%u סיביות" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "בית ×חד" +msgstr[1] "שני בתי×" +msgstr[2] "‫%s בתי×" +msgstr[3] "‫%s בתי×" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "סיבית ×חת" +msgstr[1] "שתי סיביות" +msgstr[2] "‫%s סיביות" +msgstr[3] "‫%s סיביות" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f ק״ב" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f מ״ב" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ג״ב" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ט״ב" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f פ״ב" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ×״ב" diff --git a/po/hi.po b/po/hi.po new file mode 100644 index 0000000..b8630ce --- /dev/null +++ b/po/hi.po @@ -0,0 +1,4828 @@ +# translation of glib.master.po to Hindi +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# +# +# Ravishankar Shrivastava , 2004. +# Rajesh Ranjan , 2005, 2006, 2008, 2009. +# Rajesh Ranjan , 2009. +# chandankumar(ciypro) , 2012. +# rajesh , 2012, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: glib.master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-20 05:58+0000\n" +"PO-Revision-Date: 2014-09-21 09:42+0630\n" +"Last-Translator: rajesh \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" + +#: ../gio/gapplication.c:514 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication सरà¥à¤µà¤¿à¤¸ मोड डालें (use from D-Bus service files)" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "GApplication options" +msgstr "GApplication विकलà¥à¤ª:" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "GApplication विकलà¥à¤ª दिखाà¤à¤:" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:485 ../gio/gsettings-tool.c:508 +msgid "Print help" +msgstr "छपाई मदद" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:486 +#: ../gio/gresource-tool.c:554 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gapplication-tool.c:49 +#| msgid "Print address" +msgid "Print version" +msgstr "मà¥à¤¦à¥à¤°à¤£ संसà¥à¤•रण" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:514 +msgid "Print version information and exit" +msgstr "छपाई संसà¥à¤•रण सूचना और निकास" + +#: ../gio/gapplication-tool.c:52 +#| msgid "Can't find application" +msgid "List applications" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— सूचीबदà¥à¤§ करें" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"संसà¥à¤¥à¤¾à¤ªà¤¿à¤¤ D-Bus सकà¥à¤°à¤¿à¤¯à¤•रने योगà¥à¤¯ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— की सूची दें (by .desktop files)" + +#: ../gio/gapplication-tool.c:55 +#| msgid "Can't find application" +msgid "Launch an application" +msgstr "कोई अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— लॉनà¥à¤š करें" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— लॉनà¥à¤š करें (खोलने के लिठवैकलà¥à¤ªà¤¿à¤• फ़ाइल के साथ)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "कà¥à¤°à¤¿à¤¯à¤¾ सकà¥à¤°à¤¿à¤¯ करें" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— पर किसी कà¥à¤°à¤¿à¤¯à¤¾ को लाà¤à¤" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "उपलबà¥à¤§ कारà¥à¤¯ सूचीबदà¥à¤§ करें" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"किसी अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— के लिठसà¥à¤¥à¥ˆà¤¤à¤¿à¤• कà¥à¤°à¤¿à¤¯à¤¾ सूचीबदà¥à¤§ करें (from .desktop file)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "कमांड" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "कमांड जिससे विसà¥à¤¤à¥ƒà¤¤ मदद लिया जाना है" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus पà¥à¤°à¤¾à¤°à¥‚प में अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— पहचानकरà¥à¤¤à¤¾ (उदाहरण: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:492 +#: ../gio/gresource-tool.c:558 +msgid "FILE" +msgstr "फ़ाइल" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "वैकलà¥à¤ªà¤¿à¤• सापेकà¥à¤·à¤¿à¤• या सापेकà¥à¤·à¤¿à¤• फ़ाइलनाम, या URIs खोलने के लिà¤" + +#: ../gio/gapplication-tool.c:73 +#| msgid "SECTION" +msgid "ACTION" +msgstr "कà¥à¤°à¤¿à¤¯à¤¾" + +#: ../gio/gapplication-tool.c:73 +#| msgid "Destination name to introspect" +msgid "The action name to invoke" +msgstr "लाने के लिठकà¥à¤°à¤¿à¤¯à¤¾ नाम" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "पैरामीटर" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "वैकलà¥à¤ªà¤¿à¤• पैरामीटर à¤à¤•à¥à¤¶à¤¨ इनवोक करने के लिà¤, GVariant पà¥à¤°à¤¾à¤°à¥‚प में" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:523 +#: ../gio/gsettings-tool.c:594 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"अजà¥à¤žà¤¾à¤¤ कमांड %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +#| msgid "Usage:" +msgid "Usage:\n" +msgstr "पà¥à¤°à¤¯à¥‹à¤—:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:548 +#: ../gio/gsettings-tool.c:628 +msgid "Arguments:\n" +msgstr "आरà¥à¤—à¥à¤®à¥‡à¤‚ट:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "कमांड:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"'%s help COMMAND' को विसà¥à¤¤à¥ƒà¤¤ मदद पाने के लिठउपयोग करें.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s कमांड को सीधे फॉलो करने के लिठà¤à¤• अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— आईडी\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +#| msgid "invalid GVariant type string '%s'" +msgid "invalid application id: '%s'\n" +msgstr "अवैध अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— आईडी: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' के लिठकोई वितरà¥à¤• नहीं\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +#| msgid "Could not connect to %s: " +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus में कनेकà¥à¤Ÿ करने में असमरà¥à¤¥: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "%s संदेश को अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— को भेजने में तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— id के बाद कà¥à¤°à¤¿à¤¯à¤¾ नाम जरूर दिया जाना चाहिà¤\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"अवैध कà¥à¤°à¤¿à¤¯à¤¾ नाम: '%s'\n" +"कà¥à¤°à¤¿à¤¯à¤¾ नाम को जरूर वरà¥à¤£à¤¾à¤‚किक, '-' और '.' होना चाहिà¤\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "कà¥à¤°à¤¿à¤¯à¤¾ पैरामीटर पारà¥à¤¸ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "कà¥à¤°à¤¿à¤¯à¤¾ अधिकतम à¤à¤• पैरामीटर सà¥à¤µà¥€à¤•ार करता है\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "list-actions कमांड केवल अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— आईडी लेता है" + +#: ../gio/gapplication-tool.c:421 +#, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— %s के लिठडेसà¥à¤•टॉप फ़ाइल ढूà¤à¤¢à¤¼à¤¨à¥‡ में असमरà¥à¤¥\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +#| msgid "" +#| "Unknown command %s\n" +#| "\n" +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"अपरिचित कमांड: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:370 +#: ../gio/ginputstream.c:608 ../gio/ginputstream.c:828 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:823 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "बड़ी गणना मान को %s में भेजा गया" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "खोज बेस सà¥à¤Ÿà¥à¤°à¥€à¤® पर समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream काट नहीं सकता है" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1017 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1464 +msgid "Stream is already closed" +msgstr "धारा पहले से बंद है" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "बेस सà¥à¤Ÿà¥à¤°à¥€à¤® पर कटान समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gcancellable.c:310 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "ऑपरेशन रदà¥à¤¦ था" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "अवैध वसà¥à¤¤à¥, आरंभीकृत नहीं" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "इनपà¥à¤Ÿ में अधूरा multibyte अनà¥à¤•à¥à¤°à¤®" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "गंतवà¥à¤¯ में परà¥à¤¯à¤¾à¤ªà¥à¤¤ सà¥à¤¥à¤¾à¤¨ नहीं" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "परिवरà¥à¤¤à¤¨ इनपà¥à¤Ÿ में अवैध बाइट अनà¥à¤•à¥à¤°à¤®" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "परिवरà¥à¤¤à¤¨ के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "रदà¥à¤¦ करने योगà¥à¤¯ आरंभीकरण समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "वरà¥à¤£ समूह '%s' से '%s' में परिवरà¥à¤¤à¤¨ समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' से '%s' परिवरà¥à¤¤à¤• नहीं खोला जा सका" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s पà¥à¤°à¤•ार" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "अजà¥à¤žà¤¾à¤¤ पà¥à¤°à¤•ार" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s फ़ाइल पà¥à¤°à¤•ार" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials इस OS पर लागू नहीं है" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "आपके पà¥à¤²à¥‡à¤Ÿà¤«à¤¼à¤¾à¤°à¥à¤® के लिठकोई GCredentials समरà¥à¤¥à¤¨ नहीं है" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials में पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ आईडी इस OS पर समाहित नहीं है" + +#: ../gio/gcredentials.c:565 +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल सà¥à¤ªà¥‚फिंग इस OS पर संभव नहीं है" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ सà¥à¤Ÿà¥à¤°à¥€à¤® का समय से पहले अंत" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "पता पà¥à¤°à¤µà¤¿à¤·à¥à¤ à¤¿ '%s' में असमरà¥à¤¥à¤¿à¤¤ कà¥à¤‚जी '%s'" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"पता '%s' अमानà¥à¤¯ है (वासà¥à¤¤à¤µ में à¤à¤• पथ, tmpdir, या सार कà¥à¤‚जी की जरूरत है)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "पता पà¥à¤°à¤µà¤¿à¤·à¥à¤ à¤¿ '%s' में अरà¥à¤¥à¤¹à¥€à¤¨ कà¥à¤‚जी/मान जोड़े का संयोजन" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "पता '%s' में तà¥à¤°à¥à¤Ÿà¤¿ - पोरà¥à¤Ÿ की विशेषता सही नहीं हैं." + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "पता '%s' में तà¥à¤°à¥à¤Ÿà¤¿ - परिवार की विशेषता सही नहीं हैं." + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "पता ततà¥à¤µ '%s' किसी कॉलन (:) समाहित नहीं करता है" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "कà¥à¤‚जी/मान यà¥à¤—à¥à¤® %d, '%s', पता ततà¥à¤µ '%s' में समान चिहà¥à¤¨ नहीं समाहित है" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +" unescaping या कà¥à¤‚जी मान तà¥à¤°à¥à¤Ÿà¤¿ कà¥à¤‚जी/मान यà¥à¤—à¥à¤® %d में, '%s', पता ततà¥à¤µ '%s' " +"में" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"तà¥à¤°à¥à¤Ÿà¤¿ पता '%s' में - इस यूनिकà¥à¤¸ परिवहन कà¥à¤‚जी 'पथ' या 'सार' में से à¤à¤• को " +"वासà¥à¤¤à¤µ में सेट करने " +"की आवशà¥à¤¯à¤•ता है" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "पता '%s' में तà¥à¤°à¥à¤Ÿà¤¿ - होसà¥à¤Ÿ गà¥à¤£ नहीं है या विरूपित है" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "पता '%s' में तà¥à¤°à¥à¤Ÿà¤¿ - पोरà¥à¤Ÿ गà¥à¤£ नहीं है या विरूपित है" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "पता '%s' में तà¥à¤°à¥à¤Ÿà¤¿ - noncefile गà¥à¤£ नहीं है या विरूपित है" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "कनेकà¥à¤Ÿ करने में तà¥à¤°à¥à¤Ÿà¤¿: " + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "अजà¥à¤žà¤¾à¤¤ या असमरà¥à¤¥à¤¿à¤¤ परिवहन '%s' पता '%s' के लिà¤" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "'%s' फ़ाइल खोलने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "'%s' फ़ाइल को पढ़ने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "'%s' फ़ाइल को पढ़ने में तà¥à¤°à¥à¤Ÿà¤¿, अपेकà¥à¤·à¤¿à¤¤ 16 बाइटà¥à¤¸, पà¥à¤°à¤¾à¤ªà¥à¤¤ %d" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "फ़ाइल में लिखने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "दिठगठपते रिकà¥à¤¤ है" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "जब setuid होता है तो à¤à¤• संदेश बस का विसà¥à¤¤à¤¾à¤° नहीं कर सकता है" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "मशीन आईडी के बिना à¤à¤• संदेश बस संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ जनन नहीं कर सकते:" + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "'%s' कमांड लाइन सà¥à¤ªà¥‰à¤¨ करने में तà¥à¤°à¥à¤Ÿà¤¿:" + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(इस विंडो को बंद करने के लिठकिसी वरà¥à¤£ को टाइप करें)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "सतà¥à¤° dbus चल नहीं रहा है, और सà¥à¤µà¤¤à¤ƒ लॉनà¥à¤š विफल" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "सतà¥à¤° बस पता (इस ओà¤à¤¸ के लिठलागू नहीं) निरà¥à¤§à¤¾à¤°à¤¿à¤¤ नहीं कर सकते" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"DBUS_STARTER_BUS_TYPE परिवेश चर से बस पता नहीं निरà¥à¤§à¤¾à¤°à¤¿à¤¤ कर सकते हैं - अजà¥à¤žà¤¾à¤¤ " +"मान " +"'%s'" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"बस पता निरà¥à¤§à¤¾à¤°à¤¿à¤¤ नहीं कर सकते है कà¥à¤¯à¥‹à¤‚कि DBUS_STARTER_BUS_TYPE वातावरण चर सेट " +"नहीं है" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "अजà¥à¤žà¤¾à¤¤ बस पà¥à¤°à¤•ार %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr " पंकà¥à¤¤à¤¿ को पढ़ने की कोशिश कर रहे सामगà¥à¤°à¥€ की अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ कमी" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "पंकà¥à¤¤à¤¿ को (सà¥à¤°à¤•à¥à¤·à¤¿à¤¤) पढ़ने की कोशिश कर रहे सामगà¥à¤°à¥€ की अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ कमी" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "सभी उपलबà¥à¤§ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण तंतà¥à¤° समापà¥à¤¤ (कोशिश: %s) (उपलबà¥à¤§: %s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver के माधà¥à¤¯à¤® से रदà¥à¤¦ :: अधिकृत पà¥à¤°à¤®à¤¾à¤£à¥€à¤•ृत - सहकरà¥à¤®à¥€ " + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' को खोलने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' पर अनà¥à¤®à¤¤à¤¿à¤¯à¤¾à¤ विरूपित कर रहे हैं. उमà¥à¤®à¥€à¤¦ मोड 0700, 0%o पाया" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' बनाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "पढ़ने के लिठ'%s' कीरिंग खोलने में तà¥à¤°à¥à¤Ÿà¤¿: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "लाइन %d का टोकन विरूपित है सामगà¥à¤°à¥€ '%s' के साथ '%s' पर कीरिंग के " + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "लाइन %d का पहले टोकन विरूपित है सामगà¥à¤°à¥€ '%s' के साथ '%s' पर कीरिंग के" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"लाइन %d का दूसरी टोकन विरूपित है सामगà¥à¤°à¥€ '%s' के साथ '%s' पर कीरिंग के " + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "आईडी %d के साथ कà¥à¤•ी नहीं मिला '%s' पर कीरिंग में " + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "'%s' पà¥à¤°à¤¾à¤¨à¤¾ लॉक फ़ाइल को मिटाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "फाइल '%s लॉक बनाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "(unlinked) लॉक फ़ाइल '%s' बंद करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "'%s' लॉक फ़ाइल unlinking में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "लिखने के लिठ'%s' कीरिंग खोलने में तà¥à¤°à¥à¤Ÿà¤¿: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(इसके अतिरिकà¥à¤¤, '%s' के लिठलॉक जारी करने में विफल: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "कनेकà¥à¤¶à¤¨ बंद है" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "समय समापà¥à¤¤à¤¿ तक पहà¥à¤à¤š गया था" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"कà¥à¤²à¤¾à¤‡à¤‚ट-साइड कनेकà¥à¤¶à¤¨ का निरà¥à¤®à¤¾à¤£ के दौरान असमरà¥à¤¥à¤¿à¤¤ धà¥à¤µà¤œà¥‹à¤‚ का सामना करना पड़ा" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"à¤à¤¸à¤¾ कोई अंतरफलक 'org.freedesktop.DBus.Properties' पथ %s पर वसà¥à¤¤à¥ पर नही" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "à¤à¤¸à¥€ कोई गà¥à¤£ '%s' नही" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "'%s' गà¥à¤£ पढ़ने योगà¥à¤¯ नहीं है" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "'%s' गà¥à¤£ लिखने योगà¥à¤¯ नहीं है" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿ सेटिंग गà¥à¤£ '%s': अपेकà¥à¤·à¤¿à¤¤ पà¥à¤°à¤•ार '%s' लेकिन '%s' मिल गया" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "कोई अंतरफलक '%s' नहीं" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "कोई अंतरफलक नहीं" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "à¤à¤¸à¤¾ कोई अंतरफलक '%s' पथ %s पर वसà¥à¤¤à¥ पर नही" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "à¤à¤¸à¥€ कोई विधि '%s' नहीं है" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "संदेश का पà¥à¤°à¤•ार, '%s', का मेल उमà¥à¤®à¥€à¤¦ पà¥à¤°à¤•ार '%s' से नहीं है" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ पहले से ही %s पर अंतरफलक %s के लिठनिरà¥à¤¯à¤¾à¤¤ किया गया है." + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "विधि '%s' लौटा पà¥à¤°à¤•ार '%s', लेकिन '%s' की आशा" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "विधि '%s' अंतराफलक '%s' पर हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° '%s' के साथ मौजूद नहीं है" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "उपतरू %s के लिठपहले से ही निरà¥à¤¯à¤¾à¤¤ किया जाता है" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "छवि अवैध है" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL संदेश: PATH या MEMBER शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° गà¥à¤® है" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN संदेश: REPLY_SERIAL शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° गà¥à¤® है" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR संदेशशीरà¥à¤·à¤•: REPLY_SERIAL या ERROR_NAME शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° गà¥à¤® है" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL संदेश: PATH, INTERFACE या MEMBER शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° गà¥à¤® है" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL संदेश: पथ शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° आरकà¥à¤·à¤¿à¤¤ मान /org/freedesktop/DBus/Localका " +"उपयोग कर " +"रहा है " + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL संदेश: The INTERFACE शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° आरकà¥à¤·à¤¿à¤¤ मान " +"org.freedesktop.DBus.Local " +"का उपयोग कर रहा है" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu बाइट पढ़ना चाहता था, लेकिन केवल %lu मिला है" +msgstr[1] "%lu बाइट पढ़ना चाहता था, लेकिन केवल %lu मिला है" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "अपेकà¥à¤·à¤¿à¤¤ NUL बाइट सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s' के बाद लेकिन बाइट %d पाया है" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"अपेकà¥à¤·à¤¿à¤¤ मानà¥à¤¯ UTF-8 सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग लेकिन बाइट ऑफसेट %d (सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग की लंबाई %d है) " +"पर अवैध बाइट " +"पाया. वैध UTF-8 सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग उस बिंदॠतक '%s' था." + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "विशà¥à¤²à¥‡à¤·à¤¿à¤¤ मान '%s' à¤à¤• वैध ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ डी बस पथ नहीं है" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "विशà¥à¤²à¥‡à¤·à¤¿à¤¤ मान '%s' à¤à¤• वैध हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° डी बस नहीं है" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"लमà¥à¤¬à¤¾à¤ˆ %u बाइट की आकसà¥à¤®à¤¿à¤• सरणी. अधिकतम लंबाई 2<<26 बाइटà¥à¤¸ (64 मेबा) है." +msgstr[1] "" +"लमà¥à¤¬à¤¾à¤ˆ %u बाइट की आकसà¥à¤®à¤¿à¤• सरणी. अधिकतम लंबाई 2<<26 बाइटà¥à¤¸ (64 मेबा) है." + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +" Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "विशà¥à¤²à¥‡à¤·à¤¿à¤¤ मान '%s' संसà¥à¤•रण के लिठà¤à¤• मानà¥à¤¯ हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° डी बस नहीं है" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"डी-बस तार पà¥à¤°à¤¾à¤°à¥‚प से पà¥à¤°à¤•ार सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s' के साथ GVariant deserializing में " +"तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +" अवैध endianness मान. अपेकà¥à¤·à¤¿à¤¤ 0x6c ('l') or 0x42 ('B') लेकिन पà¥à¤°à¤¾à¤ªà¥à¤¤ मान0x%" +"02x" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "अवैध पà¥à¤°à¤®à¥à¤– पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल संसà¥à¤•रण. अपेकà¥à¤·à¤¿à¤¤ 1 लेकिन %d पाया" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" +"हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° '%s' के साथ हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° शीरà¥à¤·à¤• लेकिन संदेश के मà¥à¤–à¥à¤¯ भाग खाली है" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "विशà¥à¤²à¥‡à¤·à¤¿à¤¤ मान '%s' à¤à¤• वैध हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° डी बस (शरीर के लिà¤) नहीं है" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"कोई हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° शीरà¥à¤·à¤• संदेश में नहीं लेकिन संदेश के मà¥à¤–à¥à¤¯ भाग %u बाइट का है" +msgstr[1] "" +"कोई हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° शीरà¥à¤·à¤• संदेश में नहीं लेकिन संदेश के मà¥à¤–à¥à¤¯ भाग %u बाइट का है" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "संदेश डीसीरियलाइज़ नहीं कर सकते हैं:" + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"पà¥à¤°à¤•ार सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग'%s' के साथ डी बस तार पà¥à¤°à¤¾à¤°à¥‚प का कà¥à¤°à¤®à¤¾à¤—त GVariant तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"संदेश में %d फाइल विवरणकरà¥à¤¤à¤¾ है, लेकिन शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° में %d फाइल विवरणकरà¥à¤¤à¤¾ " +"इंगित है" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "संदेश को कà¥à¤°à¤®à¤¾à¤—त नहीं कर सकते हैं:" + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" +"संदेश का शरीर हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° '%s' है लेकिन वहाठकोई हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° शीरà¥à¤·à¤• नहीं है" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "" +"संदेश शरीर के पà¥à¤°à¤•ार हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° '%s' है लेकिन शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° में हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° '% " +"s' है" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "संदेश शरीर रिकà¥à¤¤ है, लेकिन शीरà¥à¤·à¤• कà¥à¤·à¥‡à¤¤à¥à¤° में हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° '(%s)' है" + +#: ../gio/gdbusmessage.c:3282 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' पà¥à¤°à¤•ार के शरीर के साथ तà¥à¤°à¥à¤Ÿà¤¿ लौटा" + +#: ../gio/gdbusmessage.c:3290 +msgid "Error return with empty body" +msgstr "रिकà¥à¤¤ शरीर के साथ तà¥à¤°à¥à¤Ÿà¤¿ वापसी" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "हारà¥à¤¡à¤µà¥‡à¤¯à¤° पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² पाने में विफल: %s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr " /var/lib/dbus/machine-id or /etc/machine-id लोड करने में असमरà¥à¤¥: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "StartServiceByName के आहà¥à¤µà¤¾à¤¨ में तà¥à¤°à¥à¤Ÿà¤¿ %s के लिà¤: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ जवाब %d StartServiceByName(\"%s\") विधि से" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"विधि का आहà¥à¤µà¤¾à¤¨ नहीं कर सकते; पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ à¤à¤• मालिक के बिना à¤à¤• जाने - माने नाम के " +"लिठहै " +"औरपà¥à¤°à¥‰à¤•à¥à¤¸à¥€ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START धà¥à¤µà¤œ के साथ निरà¥à¤®à¤¾à¤£ किया गया " +"था" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "सार नामसà¥à¤¥à¤¾à¤¨ समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "सरà¥à¤µà¤° का निरà¥à¤®à¤¾à¤£ के दौरान असà¥à¤¥à¤¾à¤¯à¥€ फ़ाइल निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं करें" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' पर असà¥à¤¥à¤¾à¤¯à¥€ फाइल लिखने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s' à¤à¤• वैध डी बस GUID नहीं है" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "असमरà¥à¤¥à¤¿à¤¤ परिवहन '%s' पर नहीं सà¥à¤¨ सकते हैं " + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"आदेशों:\n" +" मदद यह जानकारी दिखाता है\n" +" आतà¥à¤® - निरीकà¥à¤·à¤£ दूरसà¥à¤¥ वसà¥à¤¤à¥ का आतà¥à¤®à¤¨à¤¿à¤°à¥€à¤•à¥à¤·à¤£ करें\n" +" निगरानी दूरसà¥à¤¥ वसà¥à¤¤à¥ की निगरानी करें\n" +" कॉल दूरसà¥à¤¥ वसà¥à¤¤à¥ पर à¤à¤• विधि का आहà¥à¤µà¤¾à¤¨\n" +" उतà¥à¤¸à¤°à¥à¤œà¤¨ संकेत का उतà¥à¤¸à¤°à¥à¤œà¤¨ करें\n" +"\n" +"पà¥à¤°à¤¯à¥‹à¤— करें \"%s COMMAND --help\" पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• कमांड पर मदद पाने के लिà¤.\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "आतà¥à¤®à¤¨à¤¿à¤°à¥€à¤•à¥à¤·à¤£ XML विशà¥à¤²à¥‡à¤·à¤£ में तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "तंतà¥à¤° बस से कनेकà¥à¤Ÿ करें" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "सतà¥à¤° बस से कनेकà¥à¤Ÿ करें" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "दिठगठडी बस पते से कनेकà¥à¤Ÿ करें" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "कनेकà¥à¤¶à¤¨ समापन बिंदॠविकलà¥à¤ª:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "कनेकà¥à¤¶à¤¨ समापन बिंदॠनिरà¥à¤¦à¤¿à¤·à¥à¤Ÿ विकलà¥à¤ª" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "कोई कनेकà¥à¤¶à¤¨ अंतबिंदॠनिरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "à¤à¤•ाधिक कनेकà¥à¤¶à¤¨ अंतबिंदॠनिरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "चेतावनी: आतà¥à¤®à¤¨à¤¿à¤°à¥€à¤•à¥à¤·à¤£ डेटा के अनà¥à¤¸à¤¾à¤°, अंतरफलक '%s' मौजूद नहीं है\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"चेतावनी: आतà¥à¤®à¤¨à¤¿à¤°à¥€à¤•à¥à¤·à¤£ डेटा के अनà¥à¤¸à¤¾à¤°, विधि '%s' अंतरफलक '%s' पर मौजूद नहीं " +"नहीं है\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "संकेत के लिठवैकलà¥à¤ªà¤¿à¤• गंतवà¥à¤¯ (अदà¥à¤µà¤¿à¤¤à¥€à¤¯ नाम)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "वसà¥à¤¤à¥ पथ पर संकेत उतà¥à¤¸à¤°à¥à¤œà¤¨" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "संकेत और अंतरफलक नाम" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "संकेत का उतà¥à¤¸à¤°à¥à¤œà¤¨." + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "कनेकà¥à¤Ÿ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: वसà¥à¤¤à¥ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ पथ नहीं.\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s à¤à¤• मानà¥à¤¯ वसà¥à¤¤à¥ पथ नहीं है\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: संकेत निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं.\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: संकेत जरूर पूरà¥à¤£ गà¥à¤£à¤µà¤¤à¥à¤¤à¤¾ वाला नाम होना चाहिà¤.\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s à¤à¤• वैध अंतरफलक नाम नहीं है\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s à¤à¤• मानà¥à¤¯ सदसà¥à¤¯ नाम नहीं है\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s à¤à¤• वैध अदà¥à¤µà¤¿à¤¤à¥€à¤¯ बस नाम नहीं है.\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "पैरामीटर %d पारà¥à¤¸ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "कनेकà¥à¤¶à¤¨ निसà¥à¤¤à¤¬à¥à¤§à¤¤à¤¾ में तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "गंतवà¥à¤¯ नाम पर विधि आहà¥à¤µà¤¾à¤¨" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "वसà¥à¤¤à¥ पथ पर विधि आहà¥à¤µà¤¾à¤¨" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "विधि और अंतरफलक नाम" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "सेकणà¥à¤¡ में समयसीमा" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr " दूरसà¥à¤¥ वसà¥à¤¤à¥ पर à¤à¤• विधि आहà¥à¤µà¤¾à¤¨." + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: गंतवà¥à¤¯ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं है\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ पथ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं है\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: विधि नाम निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं है\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: विधि नाम '%s' अमानà¥à¤¯ है\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "पैरामीटर %d पारà¥à¤¸ करने में तà¥à¤°à¥à¤Ÿà¤¿ '%s' पà¥à¤°à¤•ार का: %s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "आतà¥à¤®à¤µà¤¿à¤¶à¥à¤²à¥‡à¤·à¤£ के लिठगंतवà¥à¤¯ नाम" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "वसà¥à¤¤à¥ आतà¥à¤®à¤µà¤¿à¤¶à¥à¤²à¥‡à¤·à¤£ करने के लिठपथ" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "छापें XML" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "आतà¥à¤®à¤¨à¤¿à¤°à¥€à¤•à¥à¤·à¤£ शिशà¥" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "केवल गà¥à¤£ मà¥à¤¦à¥à¤°à¤¿à¤¤" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "दूरसà¥à¤¥ वसà¥à¤¤à¥ का आतà¥à¤®à¤¨à¤¿à¤°à¥€à¤•à¥à¤·à¤£." + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "गंतवà¥à¤¯ नाम की निगरानी करने के लिà¤" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "वसà¥à¤¤à¥ पथ पर नजर रखने के लिà¤" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "दूरसà¥à¤¥ वसà¥à¤¤à¥ का मॉनिटर करें." + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4525 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "बेनाम" + +#: ../gio/gdesktopappinfo.c:2410 +msgid "Desktop file didn't specify Exec field" +msgstr "डेसà¥à¤•टॉप फ़ाइल à¤à¤•à¥à¤¸ कà¥à¤·à¥‡à¤¤à¥à¤° को निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं करता है" + +#: ../gio/gdesktopappinfo.c:2695 +msgid "Unable to find terminal required for application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— के लिठजरूरी टरà¥à¤®à¤¿à¤¨à¤² ढूà¤à¤¢à¤¼à¤¨à¥‡ में असमरà¥à¤¥" + +#: ../gio/gdesktopappinfo.c:3116 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "उपयोकà¥à¤¤à¤¾ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— विनà¥à¤¯à¤¾à¤¸ फ़ोलà¥à¤¡à¤° %s नहीं बना सकता है: %s" + +#: ../gio/gdesktopappinfo.c:3120 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "MIME विनà¥à¤¯à¤¾à¤¸ फ़ोलà¥à¤¡à¤° %s नहीं बना सकता है: %s" + +#: ../gio/gdesktopappinfo.c:3360 ../gio/gdesktopappinfo.c:3384 +msgid "Application information lacks an identifier" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— जानकारी में पहचानकरà¥à¤¤à¤¾ का अभाव है" + +#: ../gio/gdesktopappinfo.c:3617 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "उपयोकà¥à¤¤à¤¾ डेसà¥à¤•टॉप फ़ाइल %s नहीं बना सकता है" + +#: ../gio/gdesktopappinfo.c:3751 +#, c-format +msgid "Custom definition for %s" +msgstr "%s के लिठमनपसंग परिभाषा" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "डà¥à¤°à¤¾à¤‡à¤µ बाहर करें कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ नहीं करता है" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "डà¥à¤°à¤¾à¤‡à¤µ बाहर निकालने या eject_with_operation को लागू नहीं करता है" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "डà¥à¤°à¤¾à¤‡à¤µ मीडिया पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²à¤¿à¤‚ग कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ नहीं करता है" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "डà¥à¤°à¤¾à¤‡à¤µ आरंभ करें कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ नहीं करता है" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "डà¥à¤°à¤¾à¤‡à¤µ रोकें को कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ नहीं करता है" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS समरà¥à¤¥à¤¨ उपलबà¥à¤§ नहीं है" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem à¤à¤¨à¥à¤•ोडिंग का %d संसà¥à¤•रण नियंतà¥à¤°à¤¿à¤¤ नहीं कर सकता है" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem à¤à¤¨à¥à¤•ोडिंग में (%d) टोकन की विरूपित संखà¥à¤¯à¤¾" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon à¤à¤¨à¥à¤•ोडिंग का %d संसà¥à¤•रण नियंतà¥à¤°à¤¿à¤¤ नहीं कर सकता है" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon à¤à¤¨à¥à¤•ोडिंग में (%d) टोकन की विरूपित संखà¥à¤¯à¤¾" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon के लिठà¤à¤• GEmblem पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../gio/gfile.c:956 ../gio/gfile.c:1194 ../gio/gfile.c:1332 +#: ../gio/gfile.c:1570 ../gio/gfile.c:1625 ../gio/gfile.c:1683 +#: ../gio/gfile.c:1767 ../gio/gfile.c:1824 ../gio/gfile.c:1888 +#: ../gio/gfile.c:1943 ../gio/gfile.c:3591 ../gio/gfile.c:3646 +#: ../gio/gfile.c:3853 ../gio/gfile.c:3895 ../gio/gfile.c:4358 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7748 ../gio/gfile.c:7838 ../gio/gfile.c:7922 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "ऑपरेशन समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1455 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "समाहित करने वाला माउंट मौजूद नहीं है" + +#: ../gio/gfile.c:2502 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पर नक़ल नहीं कर सकता है" + +#: ../gio/gfile.c:2562 +msgid "Can't copy directory over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पर निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा नक़ल नहीं कर सकता है" + +#: ../gio/gfile.c:2570 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "लकà¥à¤·à¥à¤¯ फ़ाइल मौजूद है" + +#: ../gio/gfile.c:2589 +msgid "Can't recursively copy directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पà¥à¤¨à¤°à¤¾à¤µà¤°à¥à¤¤à¥€ रूप से नक़ल नहीं कर सकता है" + +#: ../gio/gfile.c:2871 +msgid "Splice not supported" +msgstr "जोडना समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/gfile.c:2875 +#, c-format +msgid "Error splicing file: %s" +msgstr "फ़ाइल जोड़ने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gfile.c:3006 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "माउंट के बीच नक़ल (रेफà¥à¤²à¤¿à¤‚क/कà¥à¤²à¥‹à¤¨) समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/gfile.c:3010 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "नक़ल (रेफà¥à¤²à¤¿à¤‚क/कà¥à¤²à¥‹à¤¨) समरà¥à¤¥à¤¿à¤¤ नहीं है या अमानà¥à¤¯ है" + +#: ../gio/gfile.c:3015 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "नक़ल (रेफà¥à¤²à¤¿à¤‚क/कà¥à¤²à¥‹à¤¨) समरà¥à¤¥à¤¿à¤¤ नहीं है या काम नहीं करता है" + +#: ../gio/gfile.c:3078 +msgid "Can't copy special file" +msgstr "विशेष फ़ाइल नक़ल नहीं कर सकता है" + +#: ../gio/gfile.c:3843 +msgid "Invalid symlink value given" +msgstr "अवैध सांकेतिक कड़ी पà¥à¤°à¤¦à¤¤à¥à¤¤ मान" + +#: ../gio/gfile.c:4004 +msgid "Trash not supported" +msgstr "रदà¥à¤¦à¥€ समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gfile.c:4116 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "फ़ाइल नाम में '%c' नहीं हो सकता है" + +#: ../gio/gfile.c:6540 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "आवाज माउंट लागू नहीं कर सकता है" + +#: ../gio/gfile.c:6649 +msgid "No application is registered as handling this file" +msgstr "इस फ़ाइल के नियंतà¥à¤°à¤£ के रूप में कोई अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— पंजीकृत नहीं है" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "इनà¥à¤¯à¥‚मेरेटर बंद है" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "फ़ाइल इनà¥à¤¯à¥‚मेरेटर में बचा ऑपरेशन है" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "फ़ाइल इनà¥à¤¯à¥‚मेरेटर पहले से बंद है" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon à¤à¤¨à¥à¤•ोडिंग का %d संसà¥à¤•रण नियंतà¥à¤°à¤¿à¤¤ नहीं कर सकता है" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon के लिठविरूपित इनपà¥à¤Ÿ आà¤à¤•ड़ा" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤® query_info का समरà¥à¤¥à¤¨ नहीं करती है" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "पà¥à¤°à¤¾à¤ªà¥à¤¤à¤¿ सà¥à¤Ÿà¥à¤°à¥€à¤® पर समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "कटान इनपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤® पर समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "कटान सà¥à¤Ÿà¥à¤°à¥€à¤® पर समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "(%d) टोकन की गलत संखà¥à¤¯à¤¾" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "%s वरà¥à¤— नाम के लिठकोई पà¥à¤°à¤•ार नहीं" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s पà¥à¤°à¤•ार GIcon अंतरफलक लागू नहीं करता है" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "%s पà¥à¤°à¤•ार वरà¥à¤—ीकृत नहीं है" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "विरूपित संसà¥à¤•ण संखà¥à¤¯à¤¾: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s पà¥à¤°à¤•ार from_tokens() को GIcon अंतरफलक पर लागू नहीं करता है" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "चिहà¥à¤¨ à¤à¤¨à¥à¤•ोडिंग का आपूरà¥à¤¤à¤¿ संसà¥à¤•रण को नियंतà¥à¤°à¤¿à¤¤ नहीं कर सकता है" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "कोई पता उलà¥à¤²à¥‡à¤–ित नहीं" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "लमà¥à¤¬à¤¾à¤ˆ %u पते के लिठबहà¥à¤¤ लंबा है" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "पता उपसरà¥à¤— लमà¥à¤¬à¤¾à¤ˆ से बाहर सेट बिटà¥à¤¸ है" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "आईपी ​​पता मासà¥à¤• की तरह '%s' वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ नहीं कर सका" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "सॉकेट पता के लिठपरà¥à¤¯à¤¾à¤ªà¥à¤¤ सà¥à¤¥à¤¾à¤¨ नहीं" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "असमरà¥à¤¥à¤¿à¤¤ सॉकेट पता" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "इनपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤® पठन लागू नहीं कर सकता है" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1027 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1474 +msgid "Stream has outstanding operation" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤® के पास बची ऑपरेशन है" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "ततà¥à¤µ <%s> इसके अंदर सà¥à¤µà¥€à¤•ारà¥à¤¯ नहीं है <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "ततà¥à¤µ <%s> शीरà¥à¤·à¤¸à¥à¤¤à¤° पर अनà¥à¤®à¤¤à¤¿à¤ªà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं है" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "%s फाइल संसाधन में कई बार पà¥à¤°à¤•ट होता है" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "किसी भी सà¥à¤°à¥‹à¤¤ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा में '%s' का पता लगाने में विफल" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा में '%s' का पता लगाने में विफल" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "अजà¥à¤žà¤¾à¤¤ पà¥à¤°à¤¸à¤‚सà¥à¤•रण विकलà¥à¤ª \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "temp फ़ाइल बनाने में विफल: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s फाइल पढ़ने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "%s फाइल संपीड़ित करने में तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "पाठ इसके अंदर पà¥à¤°à¤•ट नहीं हो सकता है <%s>" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "आउटपà¥à¤Ÿ फ़ाइल का नाम" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा जहाठफ़ाइलों (वरà¥à¤¤à¤®à¤¾à¤¨ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा का डिफ़ॉलà¥à¤Ÿ) के लिठपढ़ा जा रहे " +"हैं" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "लकà¥à¤·à¥à¤¯ फ़ाइल नाम à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन के लिठचयनित पà¥à¤°à¤¾à¤°à¥‚प में आउटपà¥à¤Ÿ उतà¥à¤ªà¤¨ करें " + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "सà¥à¤°à¥‹à¤¤ शीरà¥à¤·à¤• उतà¥à¤ªà¤¨à¥à¤¨ करें" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" +"सà¥à¤°à¥‹à¤¤ कोड उतà¥à¤ªà¤¨à¥à¤¨ करें अपने कोड में संसाधन फ़ाइल में लिंक का उपयोग करने के " +"लिठ" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "निरà¥à¤­à¤°à¤¤à¤¾ सूची उतà¥à¤ªà¤¨à¥à¤¨ करें" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ रूप से संसाधन पंजीकृत और निरà¥à¤®à¤¾à¤£ नहीं करें" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "फंकà¥à¤¶à¤¨ निरà¥à¤¯à¤¾à¤¤ मत करें; उनà¥à¤¹à¥‡à¤‚ G_GNUC_INTERNAL घोषित करें" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "सी पहचानकरà¥à¤¤à¤¾ नाम उतà¥à¤ªà¤¨à¥à¤¨ किया गठसà¥à¤°à¥‹à¤¤ कोड के लिठइसà¥à¤¤à¥‡à¤®à¤¾à¤² किया" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"संसाधन फ़ाइल में à¤à¤• संसाधन विनिरà¥à¤¦à¥‡à¤¶ संकलित.\n" +"संसाधन विनिरà¥à¤¦à¥‡à¤¶ फाइल à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन .gresource.xml है,\n" +"और संसाधन का फ़ाइल à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन .gresource से कहा जाता है." + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "आपको वासà¥à¤¤à¤µ में à¤à¤• फ़ाइल नाम देना चाहिà¤\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "खाली नाम की अनà¥à¤®à¤¤à¤¿ नहीं हैं" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "अवैध नाम '%s': नाम लोअरकेस अकà¥à¤·à¤° के साथ शà¥à¤°à¥‚ करना चाहिà¤" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"अमानà¥à¤¯ नाम '%s': अमानà¥à¤¯ वरà¥à¤£ '%c'; केवल लोअरकेस अकà¥à¤·à¤°, संखà¥à¤¯à¤¾ और योजक चिहà¥à¤¨ " +"('-') ही " +"सà¥à¤µà¥€à¤•ृत हैं." + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "अवैध नाम '%s': दो लगातार योजक चिहà¥à¤¨ ('--') की अनà¥à¤®à¤¤à¤¿ नहीं है." + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "अवैध नाम '%s': अंतिम वरà¥à¤£ à¤à¤• डैश ('-') नहीं हो सकता है." + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "अवैध नाम '%s': अधिकतम लमà¥à¤¬à¤¾à¤ˆ 1024 है" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " हले से निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया जा चà¥à¤•ा है" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "'सूची के' सà¥à¤•ीमा के लिठकà¥à¤‚जी नहीं जोड़ सकते हैं" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " हले से निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया जा चà¥à¤•ा है" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" छाया है में; पà¥à¤°à¤¯à¥‹à¤— करें " +" मान को संशोधित करने के लिà¤" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"वासà¥à¤¤à¤µ में 'पà¥à¤°à¤•ार', 'enum' या ;धà¥à¤µà¤œà¥‹à¤‚ ' को किसी विशेषता के रूप में " +"निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया " +"जाना चाहिà¤" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> पारिभाषित (अभी तक) नहीं." + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "अवैध GVariant पà¥à¤°à¤•ार सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s'" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " दी लेकिन सà¥à¤•ीमा कà¥à¤› भी नहीं पà¥à¤°à¤¦à¤¾à¤¨ कर रहा है" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "कोई ओवरराइड करने के लिठनहीं" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " पहले से निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया जा चà¥à¤•ा है" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " पहले से निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया जा चà¥à¤•ा है" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +#| msgid " extends not-yet-existing schema '%s'" +msgid " extends not yet existing schema '%s'" +msgstr " का विसà¥à¤¤à¤¾à¤° मौजूदा सà¥à¤•ीमा '%s' अभी तक नहीं है" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +#| msgid " is list of not-yet-existing schema '%s'" +msgid " is list of not yet existing schema '%s'" +msgstr " का मौजूदा सà¥à¤•ीमा '%s' अभी तक की सूची नहीं है." + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr " पथ के साथ सà¥à¤•ीमा की à¤à¤• सूची नहीं हो सकता है " + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "थ के साथ à¤à¤• सà¥à¤•ीमा का विसà¥à¤¤à¤¾à¤° नहीं कर सकते हैं" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" à¤à¤• सूची है, विसà¥à¤¤à¤¾à¤° जो à¤à¤• सूची नहीं है" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" का विसà¥à¤¤à¤¾à¤° लेकिन " +"'%s' का विसà¥à¤¤à¤¾à¤° '%s' नहीं करता है" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "पथ, अगर दिया, शà¥à¤°à¥‚ करने के लिठऔर à¤à¤• सà¥à¤²à¥‡à¤¶ के साथ अंत करना चाहिà¤" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "सूची के पथ ':/' के साथ समापà¥à¤¤ होना चाहिà¤" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> पहले से निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया जा चà¥à¤•ा है" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "ततà¥à¤µ <%s> शीरà¥à¤·à¤¸à¥à¤¤à¤° पर अनà¥à¤®à¤¤à¤¿à¤ªà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं है" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--सखà¥à¤¤ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया गया था, बाहर निकल रहा है.\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "इस पूरे फ़ाइल को नजरअंदाज कर दिया गया है.\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "इस फ़ाइल की उपेकà¥à¤·à¤¾ करें.\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"à¤à¤¸à¤¾ कोई कà¥à¤‚जी '%s' सà¥à¤•ीमा में '%s' रूप ओवरराइड फ़ाइल '%s' में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं " + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; इस कà¥à¤‚जी के लिठओवरराइड की अनदेखी करें.\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " और --सखà¥à¤¤ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया गया था, बाहर निकल रहा है.\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"पारà¥à¤¸à¤¿à¤‚ग के दौरान तà¥à¤°à¥à¤Ÿà¤¿ कà¥à¤‚जी '%s' सà¥à¤•ीमा में '%s' के रूप इस ओवरराइड फ़ाइल '%" +"s' में " +"निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ: %s." + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "इस कà¥à¤‚जी के लिठओवरराइड की अनदेखी करें.\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"कà¥à¤‚जी '%s' के लिठओवरराइड ओवरराइड फ़ाइल '%s' सà¥à¤•ीमा में '%s' सà¥à¤•ीमा में दी गई " +"शà¥à¤°à¥ƒà¤‚खला के " +"बाहर है" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"कà¥à¤‚जी '%s' के लिठओवरराइड ओवरराइड फ़ाइल'%s' में सà¥à¤•ीमा '%s' में वैध विकलà¥à¤ªà¥‹à¤‚ " +"की सूची में " +"नहीं है" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled फ़ाइल को संगà¥à¤°à¤¹à¥€à¤¤ कहाठकरें " + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "सà¥à¤•ीमा में किसी भी तà¥à¤°à¥à¤Ÿà¤¿ पर विफल" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "Gschema.compiled फ़ाइल नहीं लिखना है " + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "कà¥à¤‚जी नाम पà¥à¤°à¤¤à¤¿à¤¬à¤‚ध लागू नहीं करेगी" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"सà¥à¤•ीमा कैश में सभी GSettings सà¥à¤•ीमा फ़ाइलों को संकलित करें.\n" +"सà¥à¤•ीमा फ़ाइलों के लिठविसà¥à¤¤à¤¾à¤° करने के लिठआवशà¥à¤¯à¤• हैं .gschema.xml,\n" +"और कैश फ़ाइल नामक gschemas.compiled है." + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "आपको वासà¥à¤¤à¤µ में à¤à¤• निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा नाम देना चाहिà¤\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "कोई सà¥à¤•ीमा फाइल नहीं मिली: " + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "कà¥à¤› नहीं कर रही.\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "मौजूदा आउटपà¥à¤Ÿ फ़ाइल हटा दिया.\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "तयशà¥à¤¦à¤¾ सà¥à¤¥à¤¾à¤¨à¥€à¤¯ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा मॉनिटर पà¥à¤°à¤•ार ढूà¤à¤¢à¤¼à¤¨à¥‡ में असमरà¥à¤¥" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "अवैध फ़ाइलनाम: %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "फ़ाइलतंतà¥à¤° सूचना पाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "रूट निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा का नाम नहीं बदल सकता है" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "फ़ाइल का नाम बदलने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "फ़ाइल का नाम नहीं बदल सकता है, फ़ाइलनाम पहले से मौजूद है" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "अवैध फ़ाइलनाम" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "डैरकà¥à¤Ÿà¤°à¥€ नहीं खोल सकते है" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "फ़ाइल खोलने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "फ़ाइल हटाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "फ़ाइल रदà¥à¤¦à¥€ में भेजने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "रदà¥à¤¦à¥€ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा %s बनाने में असमरà¥à¤¥: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "रदà¥à¤¦à¥€ के लिठउचà¥à¤š सà¥à¤¤à¤°à¤¯à¥€ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा ढूà¤à¤¢à¤¼à¤¨à¥‡ में असमरà¥à¤¥" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "रदà¥à¤¦à¥€ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा ढूà¤à¤¢à¤¼à¤¨à¥‡ और बनाने में असमरà¥à¤¥" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "रदà¥à¤¦à¥€ सूचना फ़ाइल बनाने में असमरà¥à¤¥: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "फ़ाइल रदà¥à¤¦à¥€ में भेजने में असमरà¥à¤¥: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "आंतरिक तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा बनाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "फ़ाइलतंतà¥à¤° पà¥à¤°à¤¤à¥€à¤•ातà¥à¤®à¤• लिंक का समरà¥à¤¥à¤¨ नहीं करता है" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "सांकेतिक कड़ी बनाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "फ़ाइल खिसकाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पर निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा नहीं खिसका सकता है" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "बैकअप फ़ाइल निरà¥à¤®à¤¾à¤£ विफल" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "लकà¥à¤·à¥à¤¯ फ़ाइल हटाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "माउंट के बीच खिसकाना समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/glocalfile.c:2603 +#, c-format +#| msgid "Could not load schemas from %s: %s\n" +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s के डिसà¥à¤• पà¥à¤°à¤¯à¥‹à¤— को निरà¥à¤§à¤¾à¤°à¤¿à¤¤ नहीं कर सका: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "विशेषता मान को जरूर रिकà¥à¤¤ होना चाहिà¤" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार (सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "अवैध विसà¥à¤¤à¤¾à¤°à¤¿à¤¤ विशेषता नाम" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "विसà¥à¤¤à¤¾à¤°à¤¿à¤¤ विशेषता '%s' सेट करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (अवैध à¤à¤¨à¥à¤•ोडिंग)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "फाइल '%s' के लिठजानकारी पà¥à¤°à¤¾à¤ªà¥à¤¤ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "फ़ाइल विवरणक के लिठजानकारी पà¥à¤°à¤¾à¤ªà¥à¤¤ करने के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार (uint32 पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार (uint64 पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार (बाइट सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "सिमलिंक पर अनà¥à¤®à¤¤à¤¿ सेट नहीं कर सकता है" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "अनà¥à¤®à¤¤à¤¿ सेट करने के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "सà¥à¤µà¤¾à¤®à¥€ सेट करने के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "सांकेतिक कड़ी जरूर रिकà¥à¤¤ होनी चाहिà¤" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "सांकेतिक कड़ी की सेटिंग में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "सांकेतिक कड़ी की सेटिंग में तà¥à¤°à¥à¤Ÿà¤¿: फ़ाइल à¤à¤• सांकेतिक कड़ी नहीं है" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "रूपांतरण या पहà¥à¤à¤š समय सेट करने के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux संदरà¥à¤­ जरूर शूनà¥à¤¯à¥‡à¤¤à¤° होना चाहिà¤" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux संदरà¥à¤­ सेटिंग के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "SELinux इस तंतà¥à¤° पर समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "विशेषता %s की सेटिंग समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "फ़ाइल से पढ़ने के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "फ़ाइल से पà¥à¤°à¤¾à¤ªà¥à¤¤ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "फ़ाइल बंद करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "तयशà¥à¤¦à¤¾ सà¥à¤¥à¤¾à¤¨à¥€à¤¯ फ़ाइल मॉनिटर पà¥à¤°à¤•ार ढूà¤à¤¢à¤¼à¤¨à¥‡ में असमरà¥à¤¥" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "फ़ाइल में लिखने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "पà¥à¤°à¤¾à¤¨à¥‡ बैकअप कड़ी हटाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "बैकअप की नक़ल बनाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "असà¥à¤¥à¤¾à¤ˆ फ़ाइल का नाम बदलने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "फ़ाइल काटने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "'%s' फ़ाइल खोलने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "लकà¥à¤·à¥à¤¯ फ़ाइल à¤à¤• निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा है" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "लकà¥à¤·à¥à¤¯ फ़ाइल à¤à¤• सामानà¥à¤¯ फ़ाइल नहीं है" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "यह फ़ाइल बाहà¥à¤¯ सà¥à¤¤à¤° पर रूपांतरित था" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "पà¥à¤°à¤¾à¤¨à¥€ फ़ाइल हटाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "अवैध GSeekType की आपूरà¥à¤¤à¤¿" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "अवैध पà¥à¤°à¤¾à¤ªà¥à¤¤à¤¿ आगà¥à¤°à¤¹" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream काट नहीं सकता है" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ आउटपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤® का आकार बदलना संभव हीं" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ आउटपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤® का आकार बदलने में विफल" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"लिखने की पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ के लिठआवशà¥à¤¯à¤• सà¥à¤®à¥ƒà¤¤à¤¿ की मातà¥à¤°à¤¾ उपलबà¥à¤§ पता सà¥à¤¥à¤¾à¤¨ से बड़ा है" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "अनà¥à¤°à¥‹à¤§à¤¿à¤¤ तलाश सà¥à¤Ÿà¥à¤°à¥€à¤® की शà¥à¤°à¥à¤†à¤¤ से पहले" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "अनà¥à¤°à¥‹à¤§à¤¿à¤¤ सà¥à¤Ÿà¥à¤°à¥€à¤® के अंत से परे की तलाश" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "आरोह \"unmount\" लागू नहीं करता है" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "आरोह \"इजेकà¥à¤Ÿ\" लागू नहीं करता है" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "आरोह \"unmount\" या \"unmount_with_operation\" लागू नहीं करता है" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "आरोह \"इजेकà¥à¤Ÿ\" या \"eject_with_operation\" लागू नहीं करता है" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "आरोह\"remount\" लागू नहीं करता है" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "माउंट अंतरà¥à¤µà¤¸à¥à¤¤à¥ पà¥à¤°à¤•ार गेसिंग लागू नहीं करता है" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "माउंट तà¥à¤²à¥à¤¯à¤•ालित अंतरà¥à¤µà¤¸à¥à¤¤à¥ पà¥à¤°à¤•ार गेसिंग लागू नहीं करता है" + +#: ../gio/gnetworkaddress.c:338 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "मेजबाननाम में '%s' शामिल है '[' but not ']'" + +#: ../gio/gnetworkmonitorbase.c:189 ../gio/gnetworkmonitorbase.c:292 +msgid "Network unreachable" +msgstr "संजाल तक पहà¥à¤à¤š समà¥à¤­à¤µ नहीं है" + +#: ../gio/gnetworkmonitorbase.c:227 ../gio/gnetworkmonitorbase.c:257 +msgid "Host unreachable" +msgstr "होसà¥à¤Ÿ तक पहà¥à¤à¤š समà¥à¤­à¤µ नहीं है" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "नेटवरà¥à¤• मॉनिटर नहीं बना सका: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "नेटवरà¥à¤• मॉनिटर नहीं बना सका:" + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "नेटवरà¥à¤• सà¥à¤¥à¤¿à¤¤à¤¿ पà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं किया जा सका:" + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:550 +msgid "Output stream doesn't implement write" +msgstr "आउटपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤® लेखन लागू नहीं करता है" + +#: ../gio/goutputstream.c:511 ../gio/goutputstream.c:1028 +msgid "Source stream is already closed" +msgstr "सà¥à¤°à¥‹à¤¤ सà¥à¤Ÿà¥à¤°à¥€à¤® पहले से बंद है" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' को हल करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' में संसाधन मौजूद नहीं है" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "'%s' में संसाधन के लिठअसंपीड़ित करने में विफल रहा है" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "संसाधन '%s' पर à¤à¤• निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा नहीं है" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "इनपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤® की तलाश लागू नहीं करता है" + +#: ../gio/gresource-tool.c:491 +msgid "List sections containing resources in an elf FILE" +msgstr "सूची वरà¥à¤—ों से यà¥à¤•à¥à¤¤ elf फ़ाइल में संसाधनों" + +#: ../gio/gresource-tool.c:497 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"सूची संसाधन\n" +"यदि अनà¥à¤­à¤¾à¤— दिया है, केवल इस अनà¥à¤­à¤¾à¤— में संसाधनों की सूची\n" +"यदि पथ दिया जाता है, केवल मेल खाते संसाधनों की सूची" + +#: ../gio/gresource-tool.c:500 ../gio/gresource-tool.c:510 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:501 ../gio/gresource-tool.c:511 +#: ../gio/gresource-tool.c:518 +msgid "SECTION" +msgstr "भाग" + +#: ../gio/gresource-tool.c:506 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"विवरण के साथ सूची संसाधनों\n" +"यदि अनà¥à¤­à¤¾à¤— दिया है, केवल इस अनà¥à¤­à¤¾à¤— में संसाधनों की सूची\n" +"यदि पथ दिया जाता है, केवल मेल खाते संसाधनों की सूची\n" +"विवरण में अनà¥à¤­à¤¾à¤—, आकार और संपीड़न शामिल हैं" + +#: ../gio/gresource-tool.c:516 +msgid "Extract a resource file to stdout" +msgstr "Stdout में संसाधन फ़ाइल को निकालें" + +#: ../gio/gresource-tool.c:517 +msgid "FILE PATH" +msgstr "फ़ाइल पथ" + +#: ../gio/gresource-tool.c:531 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"पà¥à¤°à¤¯à¥‹à¤—:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"आदेशों:\n" +" मदद यह जानकारी दिखाà¤à¤\n" +" अनà¥à¤­à¤¾à¤—ों सूची संसाधन अनà¥à¤­à¤¾à¤—ों\n" +" सूची सूची संसाधन\n" +" विवरण विवरण के साथ सूची संसाधनों\n" +" उदà¥à¤§à¤°à¤£ संसाधन को निकालें\n" +"\n" +"पà¥à¤°à¤¯à¥‹à¤— करें 'gresource help COMMAND' विसà¥à¤¤à¥ƒà¤¤ मदद पाने के लिà¤.\n" +"\n" + +#: ../gio/gresource-tool.c:545 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"पà¥à¤°à¤¯à¥‹à¤—:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:552 +msgid " SECTION An (optional) elf section name\n" +msgstr " अनà¥à¤­à¤¾à¤— à¤à¤• (वैकलà¥à¤ªà¤¿à¤•) elf अनà¥à¤­à¤¾à¤— नाम\n" + +#: ../gio/gresource-tool.c:556 ../gio/gsettings-tool.c:635 +msgid " COMMAND The (optional) command to explain\n" +msgstr " आदेश (वैकलà¥à¤ªà¤¿à¤•) की वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ के लिठआदेश\n" + +#: ../gio/gresource-tool.c:562 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " फ़ाइल elf फ़ाइल (à¤à¤• दà¥à¤µà¤¿à¤†à¤§à¤¾à¤°à¥€ या à¤à¤• साà¤à¤¾ पà¥à¤¸à¥à¤¤à¤•ालय)\n" + +#: ../gio/gresource-tool.c:565 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" फ़ाइल elf फ़ाइल (à¤à¤• दà¥à¤µà¤¿à¤†à¤§à¤¾à¤°à¥€ या à¤à¤• साà¤à¤¾ पà¥à¤¸à¥à¤¤à¤•ालय)\n" +" या संकलित संसाधन फ़ाइल\n" + +#: ../gio/gresource-tool.c:569 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:571 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " पथ (वैकलà¥à¤ªà¤¿à¤•) संसाधन पथ (आंशिक हो सकता है)\n" + +#: ../gio/gresource-tool.c:572 +msgid "PATH" +msgstr "पथ" + +#: ../gio/gresource-tool.c:574 +msgid " PATH A resource path\n" +msgstr " पथ संसाधन पथ\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "à¤à¤¸à¤¾ कोई सà¥à¤•ीमा '%s' नहीं\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" +"सà¥à¤•ीमा '%s' पà¥à¤¨à¤°à¥à¤¨à¤¿à¤§à¤¾à¤°à¤£à¥€à¤¯ (पथ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं किया जाना चाहिà¤) नहीं है\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "सà¥à¤•ीमा '%s' पà¥à¤¨à¤°à¥à¤¨à¤¿à¤§à¤¾à¤°à¤£à¥€à¤¯ (पथ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया जाना चाहिà¤)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "पथ खाली दिठगà¤.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "पथ à¤à¤• सà¥à¤²à¥ˆà¤¶ (/) के साथ शà¥à¤°à¥‚ करना चाहिà¤\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "पथ à¤à¤• सà¥à¤²à¥ˆà¤¶ (/) के साथ समापà¥à¤¤ होना चाहिà¤\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "पथ दो आसनà¥à¤¨ सà¥à¤²à¥ˆà¤¶ (/ /) नहीं होना चाहिà¤\n" + +#: ../gio/gsettings-tool.c:477 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "उपलबà¥à¤§ कराई मान मानà¥à¤¯ सीमा के बाहर है\n" + +#: ../gio/gsettings-tool.c:484 +#, c-format +msgid "The key is not writable\n" +msgstr "कà¥à¤à¤œà¥€ लिखने योगà¥à¤¯ नहीं है\n" + +#: ../gio/gsettings-tool.c:520 +msgid "List the installed (non-relocatable) schemas" +msgstr "सूची में सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ (गैर पà¥à¤¨à¤°à¥à¤¨à¤¿à¤§à¤¾à¤°à¤£à¥€à¤¯) सà¥à¤•ीमा " + +#: ../gio/gsettings-tool.c:526 +msgid "List the installed relocatable schemas" +msgstr "पà¥à¤¨à¤°à¥à¤¨à¤¿à¤§à¤¾à¤°à¤£à¥€à¤¯ सà¥à¤•ीमा सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ सूची" + +#: ../gio/gsettings-tool.c:532 +msgid "List the keys in SCHEMA" +msgstr "सà¥à¤•ीमा में कà¥à¤‚जी की सूची" + +#: ../gio/gsettings-tool.c:533 ../gio/gsettings-tool.c:539 +#: ../gio/gsettings-tool.c:576 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:538 +msgid "List the children of SCHEMA" +msgstr "सà¥à¤•ीमा के बचà¥à¤šà¥‹à¤‚ की सूची" + +#: ../gio/gsettings-tool.c:544 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"सूची कà¥à¤‚जी और मूलà¥à¤¯à¥‹à¤‚, बारी बारी से\n" +"यदि कोई सà¥à¤•ीमा नहीं दिया जाता है, सभी कà¥à¤‚जी की सूची\n" + +#: ../gio/gsettings-tool.c:546 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:551 +msgid "Get the value of KEY" +msgstr "कà¥à¤‚जी का मान पाया" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:570 ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] कà¥à¤‚जी" + +#: ../gio/gsettings-tool.c:557 +msgid "Query the range of valid values for KEY" +msgstr "कà¥à¤‚जी के लिठमानà¥à¤¯ मानों की शà¥à¤°à¥ƒà¤‚खला कà¥à¤µà¥‡à¤°à¥€" + +#: ../gio/gsettings-tool.c:563 +msgid "Set the value of KEY to VALUE" +msgstr "मान के लिठकà¥à¤‚जी का मान निरà¥à¤§à¤¾à¤°à¤¿à¤¤" + +#: ../gio/gsettings-tool.c:564 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] कà¥à¤‚जी का मान" + +#: ../gio/gsettings-tool.c:569 +msgid "Reset KEY to its default value" +msgstr "अपने डिफ़ॉलà¥à¤Ÿ मान के लिठकà¥à¤‚जी रीसेट करें" + +#: ../gio/gsettings-tool.c:575 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "सà¥à¤•ीमा में अपने मूलभूत के लिठसभी कà¥à¤‚जी रीसेट करें" + +#: ../gio/gsettings-tool.c:581 +msgid "Check if KEY is writable" +msgstr "जाà¤à¤šà¥‡à¤‚ अगर कà¥à¤‚जी लिखने योगà¥à¤¯ है" + +#: ../gio/gsettings-tool.c:587 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"परिवरà¥à¤¤à¤¨ के लिठकà¥à¤‚जी मॉनिटर.\n" +"यदि कोई कà¥à¤‚जी निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया जाता है, सà¥à¤•ीमा में सभी कà¥à¤‚जी की निगरानी.\n" +"^C का उपयोग कर निगरानी रोके.\n" + +#: ../gio/gsettings-tool.c:590 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:602 +#| msgid "" +#| "Usage:\n" +#| " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " list-schemas List installed schemas\n" +#| " list-relocatable-schemas List relocatable schemas\n" +#| " list-keys List keys in a schema\n" +#| " list-children List children of a schema\n" +#| " list-recursively List keys and values, recursively\n" +#| " range Queries the range of a key\n" +#| " get Get the value of a key\n" +#| " set Set the value of a key\n" +#| " reset Reset the value of a key\n" +#| " reset-recursively Reset all values in a given schema\n" +#| " writable Check if a key is writable\n" +#| " monitor Watch for changes\n" +#| "\n" +#| "Use 'gsettings help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" + +#: ../gio/gsettings-tool.c:625 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"पà¥à¤°à¤¯à¥‹à¤—:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:631 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR अतिरिकà¥à¤¤ सà¥à¤•ीमा के लिठखोज निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा\n" + +#: ../gio/gsettings-tool.c:639 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA सà¥à¤•ीमा का नाम\n" +" PATH पà¥à¤¨à¤°à¥à¤¨à¤¿à¤§à¤¾à¤°à¤£à¥€à¤¯ सà¥à¤•ीमा के लिठपथ\n" + +#: ../gio/gsettings-tool.c:644 +msgid " KEY The (optional) key within the schema\n" +msgstr " कà¥à¤‚जी सà¥à¤•ीमा के भीतर कà¥à¤‚जी (वैकलà¥à¤ªà¤¿à¤•)\n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The key within the schema\n" +msgstr " कà¥à¤‚जी सà¥à¤•ीमा के भीतर कà¥à¤‚जी\n" + +#: ../gio/gsettings-tool.c:652 +msgid " VALUE The value to set\n" +msgstr " मान निरà¥à¤§à¤¾à¤°à¤¿à¤¤ के लिठमान\n" + +#: ../gio/gsettings-tool.c:707 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s से सà¥à¤•ीमा लोड नहीं कर सका: %s\n" + +#: ../gio/gsettings-tool.c:769 +#, c-format +msgid "Empty schema name given\n" +msgstr "खाली सà¥à¤•ीमा नाम दिठगठ\n" + +#: ../gio/gsettings-tool.c:798 +#, c-format +msgid "No such key '%s'\n" +msgstr "à¤à¤¸à¤¾ कोई कà¥à¤‚जी '%s' नहीं\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "अवैध सॉकेट, आरंभीकृत नहीं" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "अवैध सॉकेट, इसके कारण आरंभीकरण विफल: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "सॉकेट पहले से बंद है" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "सॉकेट I/O टाइम आउट हो गया" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd से GSocket बना रहा है: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "सॉकेट बनाने में असमरà¥à¤¥: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "अजà¥à¤žà¤¾à¤¤ परिवार निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया गया था." + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "अजà¥à¤žà¤¾à¤¤ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया गया था" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "सà¥à¤¥à¤¾à¤¨à¥€à¤¯ पता नहीं पा सका: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "दूरसà¥à¤¥ पता नहीं पा सका: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "सà¥à¤¨ नहीं सका: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "पता में बांधने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "मलà¥à¤Ÿà¥€à¤•ासà¥à¤Ÿ समूह में शामिल होने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "मलà¥à¤Ÿà¥€à¤•ासà¥à¤Ÿ समूह छोड़ने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "सà¥à¤°à¥‹à¤¤ - विशिषà¥à¤Ÿ बहà¥à¤¸à¥à¤¤à¥à¤°à¥à¤ªà¥€à¤¯ के लिठकोई समरà¥à¤¥à¤¨ नहीं" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "कनेकà¥à¤¶à¤¨ सà¥à¤µà¥€à¤•ार करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "कनेकà¥à¤¶à¤¨ पà¥à¤°à¤—ति में" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "सà¥à¤¥à¤—ित तà¥à¤°à¥à¤Ÿà¤¿ पाने में असमरà¥à¤¥:" + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "आंकड़ा पाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "आंकड़ा भेजने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "सॉकेट बंद करने में असमरà¥à¤¥: %s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "सॉकेट बंद करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "सॉकेट सà¥à¤¥à¤¿à¤¤à¤¿ के लिठपà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾à¤°à¤¤: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "संदेश भेजने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage विंडोज़ पर समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "संदेश पाने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:4516 +#, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to read socket credentials: %s" +msgstr "सॉकेट शà¥à¤°à¥‡à¤¯ पढ़ने में असमरà¥à¤¥: %s" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials निरà¥à¤§à¤¾à¤°à¤¿à¤¤ नहीं कर सकते इस ओà¤à¤¸ के लिà¤" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° %s से कनेकà¥à¤Ÿ नहीं हो सका: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s से कनेकà¥à¤Ÿ नहीं हो सका: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "कनेकà¥à¤Ÿ नहीं हो सका:" + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1603 +msgid "Unknown error on connect" +msgstr "कनेकà¥à¤Ÿ करने पर अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1538 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "गैर-TCP कनेकà¥à¤¶à¤¨ पर पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1559 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल '%s' समरà¥à¤¥à¤¿à¤¤ नहीं है." + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "शà¥à¤°à¥‹à¤¤à¤¾ पहले से बंद है" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "जोड़ा गया सॉकेट बंद है" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 IPv6 पते '%s' समरà¥à¤¥à¤¨ नहीं करता है" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "उपयोगकरà¥à¤¤à¤¾ नाम SOCKSv4 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल के लिठभी लंबे है" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "होसà¥à¤Ÿà¤¨à¤¾à¤® '%s' SOCKSv4 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल के लिठभी लंबे है" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "सरà¥à¤µà¤° à¤à¤• SOCKSv4 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° नहीं है." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 सरà¥à¤µà¤° के माधà¥à¤¯à¤® से कनेकà¥à¤¶à¤¨ असà¥à¤µà¥€à¤•ार कर दिया था" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "सरà¥à¤µà¤° à¤à¤• SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° नहीं है." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण की आवशà¥à¤¯à¤•ता है." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण पदà¥à¤§à¤¤à¤¿ की आवशà¥à¤¯à¤•ता है जो glib दà¥à¤µà¤¾à¤°à¤¾ समरà¥à¤¥à¤¨ नहीं " +"पà¥à¤°à¤¾à¤ªà¥à¤¤ है." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "उपयोगकरà¥à¤¤à¤¾ नाम या कूटशबà¥à¤¦ SOCKSv5 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल के लिठबहà¥à¤¤ लंबा है." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण गलत उपयोगकरà¥à¤¤à¤¾ नाम या कूटशबà¥à¤¦ के कारण विफल रहा है." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "होसà¥à¤Ÿà¤¨à¤¾à¤® '%s' SOCKSv5 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल के लिठभी लंबे है" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° अजà¥à¤žà¤¾à¤¤ पते पà¥à¤°à¤•ार का उपयोग करता है." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "आंतरिक SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° तà¥à¤°à¥à¤Ÿà¤¿." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Ruleset दà¥à¤µà¤¾à¤°à¤¾ SOCKSv5 कनेकà¥à¤¶à¤¨ की अनà¥à¤®à¤¤à¤¿ नहीं है." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 सरà¥à¤µà¤° के माधà¥à¤¯à¤® से होसà¥à¤Ÿ तक पहà¥à¤à¤š समà¥à¤­à¤µ नहीं." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ के माधà¥à¤¯à¤® से संजाल तक पहà¥à¤à¤š समà¥à¤­à¤µ नहीं." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ के माधà¥à¤¯à¤® से कनेकà¥à¤¶à¤¨ से इनकार कर दिया." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ 'कनेकà¥à¤Ÿ' कमांड समरà¥à¤¥à¤¨ नहीं करता है." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ पते पà¥à¤°à¤•ार का समरà¥à¤¥à¤¨ पà¥à¤°à¤¦à¤¾à¤¨ नहीं करता है." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "अजà¥à¤žà¤¾à¤¤ SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ तà¥à¤°à¥à¤Ÿà¤¿." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon à¤à¤¨à¥à¤•ोडिंग का %d संसà¥à¤•रण नियंतà¥à¤°à¤¿à¤¤ नहीं कर सकता है" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "कोई वैध पता नहीं मिला" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' के विलोम समाधान में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "'%s' के लिठअनà¥à¤°à¥‹à¤§à¤¿à¤¤ पà¥à¤°à¤•ार की कोई DNS रिकॉरà¥à¤¡ नहीं" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "असà¥à¤¥à¤¾à¤¯à¥€ रूप से '%s' हल करने में असमरà¥à¤¥" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "'%s' हल करने में तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/gtlscertificate.c:247 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "पीईà¤à¤® इनकोडिंग निजी कà¥à¤‚जी डिकà¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं कर सकते" + +#: ../gio/gtlscertificate.c:252 +msgid "No PEM-encoded private key found" +msgstr "पीईà¤à¤® इनकोडिंग निजी कà¥à¤‚जी नहीं पाया" + +#: ../gio/gtlscertificate.c:262 +msgid "Could not parse PEM-encoded private key" +msgstr "पीईà¤à¤® इनकोडिंग निजी कà¥à¤‚जी नहीं विशà¥à¤²à¥‡à¤·à¤¿à¤¤ कर सकता है" + +#: ../gio/gtlscertificate.c:287 +msgid "No PEM-encoded certificate found" +msgstr "पीईà¤à¤® इनकोडिंग पà¥à¤°à¤®à¤¾à¤£ पतà¥à¤° नहीं पाया" + +#: ../gio/gtlscertificate.c:296 +msgid "Could not parse PEM-encoded certificate" +msgstr "पीईà¤à¤® - इनकोडिंग पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° नहीं विशà¥à¤²à¥‡à¤·à¤¿à¤¤ कर सकता है" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"आपकी पहà¥à¤à¤š से आउट लॉक होने से पहले पासवरà¥à¤¡ सही ढंग से पà¥à¤°à¤µà¥‡à¤¶ करने का यह आखिरी " +"मौका है." + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"अनेक दाखिल पासवरà¥à¤¡ गलत कर दिया गया है, और अपने à¤à¤•à¥à¤¸à¥‡à¤¸ आगे विफलताओं के बाद " +"लॉक आउट हो " +"जाà¤à¤—ा." + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "दाखिल कूटशबà¥à¤¦ गलत है." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +#| msgid "Expecting 1 control message, got %d" +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 नियंतà¥à¤°à¤£ संदेश की आशा कर रहा है, %d पाया" +msgstr[1] "1 नियंतà¥à¤°à¤£ संदेश की आशा कर रहा है, %d पाया" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "सहायक आंकड़ा का अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ पà¥à¤°à¤•ार" + +#: ../gio/gunixconnection.c:193 +#, c-format +#| msgid "Expecting one fd, but got %d\n" +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "किसी à¤à¤• fd की आशा कर रहा है, लेकिन %d पाया\n" +msgstr[1] "किसी à¤à¤• fd की आशा कर रहा है, लेकिन %d पाया\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "अवैध fd पाया" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियलà¥à¤¸ भेजने में तà¥à¤°à¥à¤Ÿà¤¿: " + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿ जाà¤à¤š कर रहा है अगर SO_PASSCRED गरà¥à¤¤à¤¿à¤•ा के लिठसकà¥à¤·à¤® है: %s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "फ़ाइल का नाम बदलने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियलà¥à¤¸ पà¥à¤°à¤¾à¤ªà¥à¤¤ करने के लिठà¤à¤• à¤à¤•ल बाइट पढ़ा है, लेकिन शूनà¥à¤¯ बाइटà¥à¤¸ " +"पढ़ने की उमà¥à¤®à¥€à¤¦ थी" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "1 नियंतà¥à¤°à¤£ संदेश की आशा कर रहा है, %d पाया" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED अकà¥à¤·à¤® के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "फ़ाइल विवरणकरà¥à¤¤à¤¾ वà¥à¤¯à¤•à¥à¤¤ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "फ़ाइल विवरणकरà¥à¤¤à¤¾ वà¥à¤¯à¤•à¥à¤¤ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixmounts.c:2054 ../gio/gunixmounts.c:2107 +msgid "Filesystem root" +msgstr "फ़ाइलतंतà¥à¤° रूट" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "फ़ाइल विवरणकरà¥à¤¤à¤¾ वà¥à¤¯à¤•à¥à¤¤ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "अमूरà¥à¤¤à¤¿ UNIX डोमेन सॉकेट पता इस तंतà¥à¤° पर समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "आवाज बाहर करें लागू नहीं करता है" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "आयतन बाहर करें या eject_with_operation को लागू नहीं करता है" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— ढूà¤à¤¢à¤¼ नहीं सकता है" + +#: ../gio/gwin32appinfo.c:306 +#, c-format +msgid "Error launching application: %s" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— लॉनà¥à¤š करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gwin32appinfo.c:342 +msgid "URIs not supported" +msgstr "यूआरआई समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/gwin32appinfo.c:364 +msgid "association changes not supported on win32" +msgstr "win32 पर संगठन परिवरà¥à¤¤à¤¨ समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/gwin32appinfo.c:376 +msgid "Association creation not supported on win32" +msgstr "win32 पर संगठन निरà¥à¤®à¤¾à¤£ समरà¥à¤¥à¤¿à¤¤ नहीं" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "फ़ाइल से पढ़ने के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "फ़ाइल बंद करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "फ़ाइल में लिखने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ के बाहर" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "आंतरिक तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "अधिक इनपà¥à¤Ÿ की जरूरत है" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "अवैध होसà¥à¤Ÿ-नाम" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "पता जिसपर सà¥à¤¨à¤¨à¤¾ है" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "अनदेखा किया गया, GTestDbus के साथ संहत" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "पता छापें" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "शेल अवसà¥à¤¥à¤¾ में पता छापें" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "कोई डीबस सेवा चलाà¤à¤" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "गलत तरà¥à¤•\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "'%s' अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ गà¥à¤£ '%s' ततà¥à¤µ के लिà¤" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' ततà¥à¤µ '%s' का गà¥à¤£ नहीं मिला" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "'%s' अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ टैग, '%s' टैग पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ टैग '%s' '%s' के अंदर" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "कोई वैध पà¥à¤¸à¥à¤¤à¤šà¤¿à¤¹à¥à¤¨ आà¤à¤•ड़ा निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा में नहीं मिला" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "यूआरआई '%s' के लिठपà¥à¤¸à¥à¤¤à¤šà¤¿à¤¹à¥à¤¨ पहले से मौजूद है" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "यूआरआई '%s' के लिठकोई पà¥à¤¸à¥à¤¤à¤šà¤¿à¤¹à¥à¤¨ नहीं मिला" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "कोई MIME पà¥à¤°à¤•ार यूआरआई '%s' के लिठपà¥à¤¸à¥à¤¤à¤šà¤¿à¤¹à¥à¤¨ में परिभाषित नहीं है" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "यूआरआई '%s' के लिठपà¥à¤¸à¥à¤¤à¤šà¤¿à¤¹à¥à¤¨ में कोई निजी फà¥à¤²à¥ˆà¤— परिभाषित नहीं है" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "यूआरआई '%s' के लिठपà¥à¤¸à¥à¤¤à¤šà¤¿à¤¹à¥à¤¨ में कोई समूह सेट नहीं है" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "'%s' के नाम से कोई अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— ने '%s' के लिठपà¥à¤¸à¥à¤¤à¤šà¤¿à¤¹à¥à¤¨ पंजीकृत नहीं है" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "'%s' à¤à¤•à¥à¤¸ पंकà¥à¤¤à¤¿ यूआरआई '%s' से फैलाने में विफल रहा" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "इनपà¥à¤Ÿ के अंत में आंशिक वरà¥à¤£ अनà¥à¤•à¥à¤°à¤®" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "फालबैक '%s' को कोड सेट '%s' में परिवरà¥à¤¤à¤¿à¤¤ नहीं कर सका" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" +"\"file\" योजना का उपयोग करने वाली यूआरआई '%s' à¤à¤• निरपेकà¥à¤· यूआरआई नहीं है" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "सà¥à¤¥à¤¾à¤¨à¥€à¤¯ फ़ाइल यूआरआई '%s' में à¤à¤• '#' समà¥à¤®à¤¿à¤²à¤¿à¤¤ नहीं है" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "यूआरआई '%s' अवैध है" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "यूआरआई '%s' का मेजबाननाम अवैध है" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "यूआरआई '%s' में अवैध à¤à¤¸à¥à¤•ेपà¥à¤¡ वरà¥à¤£ समà¥à¤®à¤¿à¤²à¤¿à¤¤ हैं" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "पथनाम '%s' à¤à¤• निरपेकà¥à¤· पथ नहीं है" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "अवैध होसà¥à¤Ÿ-नाम" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "पूरà¥à¤µà¤¾à¤¹à¥à¤¨" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "अपराहà¥à¤¨" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%A %d %b %Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%I:%M:%S %Z" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "जनवरी" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "फ़रवरी" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "मारà¥à¤š" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "अपà¥à¤°à¥‡à¤²" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "मई" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "जून" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "अगसà¥à¤¤" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "सितमà¥à¤¬à¤°" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "अकà¥à¤Ÿà¥‚बर" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "नवमà¥à¤¬à¤°" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "दिसमà¥à¤¬à¤°" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "जनवरी" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "फ़रवरी" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "मारà¥à¤š" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "अपà¥à¤°à¥‡à¤²" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "मई" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "जून" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "अग." + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "सित." + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "अकà¥à¤¤à¥‚." + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "नवं." + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "दिसं." + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "सोमवार " + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "मंगलवार " + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "बà¥à¤§à¤µà¤¾à¤° " + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "गà¥à¤°à¥à¤µà¤¾à¤° " + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "शà¥à¤•à¥à¤°à¤µà¤¾à¤° " + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "शनिवार" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "रविवार " + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "सोम " + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "मंगल " + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "बà¥à¤§ " + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "गà¥à¤°à¥ " + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "शà¥à¤•à¥à¤° " + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "शनि" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "रवि " + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' को खोलने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "%lu बाइट आबंटित नहीं किया जा सकता फ़ाइल \"%s\" को पढ़ने हेतà¥" +msgstr[1] "%lu बाइटों आबंटित नहीं किया जा सकता फ़ाइल \"%s\" को पढ़ने हेतà¥" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' फ़ाइल को पढ़ने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "\"%s\" फ़ाइल काफी बड़ी है" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "फ़ाइल '%s' से पढ़ने में असफल: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' फ़ाइल खोलने में असफल :%s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "फ़ाइल '%s' की विशेषता जà¥à¤žà¤¾à¤¤ करने में असफल: fstat() असफल: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "फ़ाइल '%s': fdopen() खोलने में असफल: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "फ़ाइल '%s' को '%s' में नाम बदलने में विफल: g_rename() विफल: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "फ़ाइल '%s' बनाने में असफल: %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +#| msgid "Failed to write file '%s': fwrite() failed: %s" +msgid "Failed to write file '%s': write() failed: %s" +msgstr "'%s' फ़ाइल को लिखने में विफल: write() विफल: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' फ़ाइल में लिखने में विफल: fwrite() विफल: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "'%s' मौजूदा फ़ाइल हटाया नहीं जा सकता: g_unlink() विफल: %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "टैमà¥à¤ªà¤²à¥‡à¤Ÿ '%s' अवैध है, इसमें '%s' शामिल नहीं है" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "टैमà¥à¤ªà¤²à¥‡à¤Ÿ '%s' में XXXXXX समाहित नहीं है" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "सिंबालिक लिंक '%s' से पà¥à¤°à¤¸à¤‚ग पढ़ने में असफल %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "सिंबालिक लिंक समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' से '%s' परिवरà¥à¤¤à¤• नहीं खोला जा सका: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "यहाठà¤à¤• रॉ रीड नहीं कर सकता g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "रीड बफ़र में शेष है अपरिवरà¥à¤¤à¤¿à¤¤ बचा हà¥à¤† डेटा" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "आंशिक वरà¥à¤£ में चैनल समापà¥à¤¤ होता है" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "यहाठà¤à¤• रॉ रीड नहीं कर सकता - g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "खोज निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा में वैध कà¥à¤‚जी फ़ाइल नहीं मिल सका" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "à¤à¤• सामानà¥à¤¯ फ़ाइल नहीं" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"कà¥à¤‚जी फ़ाइल में '%s' पंकà¥à¤¤à¤¿ समाहित है जो कि à¤à¤• कà¥à¤‚जी मान जोड़ा, समूह, या " +"टिपà¥à¤ªà¤£à¥€ नहीं है" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "अवैध समूह नाम: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "कà¥à¤‚जी फ़ाइल à¤à¤• समूह के साथ शà¥à¤°à¥‚ नहीं होता" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "अवैध कà¥à¤‚जी नाम: %s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "कà¥à¤‚जी फ़ाइल में असमरà¥à¤¥à¤¿à¤¤ à¤à¤¨à¤•ोडिंग '%s' समाहित है" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1692 ../glib/gkeyfile.c:3072 +#: ../glib/gkeyfile.c:3138 ../glib/gkeyfile.c:3264 ../glib/gkeyfile.c:3397 +#: ../glib/gkeyfile.c:3539 ../glib/gkeyfile.c:3768 ../glib/gkeyfile.c:3835 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "कà¥à¤‚जी फ़ाइल में '%s' समूह नहीं है" + +#: ../glib/gkeyfile.c:1704 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "कà¥à¤‚जी फ़ाइल में '%s' कà¥à¤‚जी नहीं है" + +#: ../glib/gkeyfile.c:1811 ../glib/gkeyfile.c:1927 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "कà¥à¤‚जी फ़ाइल में '%s' कà¥à¤‚जी समाहित है '%s' मान के साथ जो UTF-8 नहीं है" + +#: ../glib/gkeyfile.c:1831 ../glib/gkeyfile.c:1947 ../glib/gkeyfile.c:2316 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"कà¥à¤‚जी फ़ाइल में '%s' कà¥à¤‚जी है जिसमें सà¥à¤¥à¤¿à¤¤ मान का विशà¥à¤²à¥‡à¤·à¤£ नहीं किया जा सकता " +"है." + +#: ../glib/gkeyfile.c:2533 ../glib/gkeyfile.c:2901 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"कà¥à¤‚जी फ़ाइल में '%s' कà¥à¤‚जी है '%s' समूह में जिसके मान का विशà¥à¤²à¥‡à¤·à¤£ नहीं किया " +"जा सकता." + +#: ../glib/gkeyfile.c:2611 ../glib/gkeyfile.c:2688 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "कà¥à¤‚जी '%s' का मान '%s' है '%s' समूह में जहाठ%s अपेकà¥à¤·à¤¿à¤¤ था" + +#: ../glib/gkeyfile.c:3087 ../glib/gkeyfile.c:3279 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "कà¥à¤‚जी फ़ाइल में '%s' कà¥à¤‚जी नहीं है '%s' समूह में" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "कà¥à¤‚जी फ़ाइल में पंकà¥à¤¤à¤¿ के अंत में à¤à¤¸à¥à¤•ेप संपà¥à¤°à¤¤à¥€à¤• रहता है" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "कà¥à¤‚जी फ़ाइल में '%s' अमानà¥à¤¯ शृंखला समाहित है" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "मानà¥à¤¯ '%s' को à¤à¤• संखà¥à¤¯à¤¾ की तरह नहीं विशà¥à¤²à¥‡à¤·à¤¿à¤¤ किया जा सकता." + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "पूरà¥à¤£à¤¾à¤‚क मान '%s' दायरा के बाहर है" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "मान '%s' को à¤à¤• फà¥à¤²à¥‹à¤Ÿ संखà¥à¤¯à¤¾ की तरह नहीं विशà¥à¤²à¥‡à¤·à¤¿à¤¤ किया जा सकता." + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "मान '%s' को बà¥à¤²à¤¿à¤¯à¤¨ के तौर पर विशà¥à¤²à¥‡à¤·à¤¿à¤¤ नहीं किया जा सकता." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "फ़ाइल'%s%s%s%s' की विशेषता जà¥à¤žà¤¾à¤¤ करने में असफल: fstat() असफल: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr " %s%s%s%s फ़ाइल चितà¥à¤°à¤¿à¤¤ करने में विफल: mmap() विफल: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "फ़ाइल '%s' खोलने में असफल: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "पंकà¥à¤¤à¤¿ %d वरà¥à¤£ %d पर तà¥à¤°à¥à¤Ÿà¤¿:" + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "नाम में अवैध यूटीà¤à¤«à¤¼-8 à¤à¤¨à¤•ोडेड पाठ - वैध '%s' नहीं" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' कोई वैध नाम नहीं है" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' कोई वैध नाम नहीं है: '%c'" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "पंकà¥à¤¤à¤¿ %d: पर तà¥à¤°à¥à¤Ÿà¤¿ %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' के विशà¥à¤²à¥‡à¤·à¤£ करने में असफल, जो कि वरà¥à¤£ संदरà¥à¤­ के भीतर à¤à¤• अंक होना " +"चाहिठ(उदाहरण " +"के लिà¤, ê) - शायद अंक काफी बड़ा है" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"वरà¥à¤£ संदरà¥à¤­ अरà¥à¤§à¤µà¤¿à¤°à¤¾à¤® चिनà¥à¤¹ के साथ समापà¥à¤¤ नहीं होता है; बहà¥à¤¤ संभव है कि आपने " +"à¤à¤• à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड " +"वरà¥à¤£ का उपयोग किया है पर à¤à¤• à¤à¤‚टिटी को पà¥à¤°à¤¾à¤°à¤‚भ करना नहीं चाहते - à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड को " +"à¤à¤¸à¥à¤•ेप करें " +"à¤à¤¸à¥‡ &" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "संपà¥à¤°à¤¤à¥€à¤• संदरà¥à¤­ '%-.*s' à¤à¤• अनà¥à¤®à¤¤à¤¿ पà¥à¤°à¤¾à¤ªà¥à¤¤ संपà¥à¤°à¤¤à¥€à¤• को à¤à¤¨à¤•ोड नहीं करता" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "खाली à¤à¤‚टिटी '&;' देखा; वैध à¤à¤‚टिटी हैं: & " < > '" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "à¤à¤‚टिटी नाम '%-.*s' जà¥à¤žà¤¾à¤¤ नहीं है" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"à¤à¤‚टिटी अरà¥à¤§à¤µà¤¿à¤°à¤¾à¤® पर समापà¥à¤¤ नहीं होता, बहà¥à¤¤ संभव है कि आपने à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤¨à¥à¤¡ वरà¥à¤£ का " +"पà¥à¤°à¤¯à¥‹à¤— किया " +"है और à¤à¤• à¤à¤‚टिटी पà¥à¤°à¤¾à¤°à¤‚भ नहीं करना चाहते- à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड को à¤à¤¸à¥‡ à¤à¤¸à¥à¤•ेप करें: &" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "" +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ à¤à¤• अवयव के नाम से पà¥à¤°à¤¾à¤°à¤‚भ होना चाहिठ(उदाहरण के लिà¤- <पà¥à¤¸à¥à¤¤à¤•>)" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"< के पशà¥à¤šà¤¾à¤¤ आया '%s' à¤à¤• वैध वरà¥à¤£ नहीं है; यह अवयव नाम से पà¥à¤°à¤¾à¤°à¤‚भ नहीं होता" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"'%s' विसम वरà¥à¤£, à¤à¤• '>' संपà¥à¤°à¤¤à¥€à¤• पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रिकà¥à¤¤ ततà¥à¤µ टैग '%s' समापà¥à¤¤ करने के " +"लिà¤" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"विसम वरà¥à¤£ '%s', पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ है à¤à¤• '=' लकà¥à¤·à¤£ नाम '%s' अवयव '%s' के पशà¥à¤šà¤¾à¤¤à¥" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"'%s' विसम संपà¥à¤°à¤¤à¥€à¤•, à¤à¤• '>' या '/' संपà¥à¤°à¤¤à¥€à¤• को '%s' ततà¥à¤µ के आरंभ टैग को खतà¥à¤® " +"करना " +"पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤, या विकलà¥à¤ªà¤¤à¤ƒ à¤à¤• गà¥à¤£; शायद आपने गà¥à¤£ नाम में à¤à¤• अमानà¥à¤¯ संपà¥à¤°à¤¤à¥€à¤• का " +"पà¥à¤°à¤¯à¥‹à¤— किया है" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"पà¥à¤°à¤¾à¤¨à¤¾ वरà¥à¤£ '%s', जब विशेषता '%s', अवयव '%s' का मान दिया जाता है तो बराबर " +"चिहà¥à¤¨ के " +"बाद à¤à¤• खà¥à¤²à¤¾ कोट चिहà¥à¤¨ वांछित है" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' à¤à¤• वैध वरà¥à¤£ नहीं है कà¥à¤²à¥‹à¤œà¤¼ अवयव नाम '%s' के बाद; सà¥à¤µà¥€à¤•ारà¥à¤¯ वरà¥à¤£ है '>'" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "अवयव '%s' बनà¥à¤¦ था, कोई अवयव वरà¥à¤¤à¤®à¤¾à¤¨ में खà¥à¤²à¤¾ नहीं है" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ '%s' बनà¥à¤¦ था, परनà¥à¤¤à¥ वरà¥à¤¤à¤®à¤¾à¤¨ खà¥à¤²à¤¾ अवयव है '%s'" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ खाली था या उसमें सिरà¥à¤« शà¥à¤µà¥‡à¤¤ रिकà¥à¤¤à¤¿ ही था" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से à¤à¤• खà¥à¤²à¤¾ à¤à¤‚गल बà¥à¤°à¥‡à¤•ेट '<' के पशà¥à¤šà¤¾à¤¤ ही हो " +"गया" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से अवयवों के खà¥à¤²à¤¾ होने पर भी हो गया - '%s' " +"अंतिम खà¥à¤²à¤¾ हà¥à¤† " +"अवयव था" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से हो गया, वांछित था देखना à¤à¤• कà¥à¤²à¥‹à¤œà¤¼ à¤à¤‚गल " +"बà¥à¤°à¥‡à¤•ेट टैग को बनà¥à¤¦ " +"करता हà¥à¤† <%s/>" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से अवयव नाम के भीतर हो गया" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से विशेषता नाम के भीतर हो गया" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से अवयव-खोलने के टैग के भीतर हो गया." + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से बराबर के चिहà¥à¤¨ के बाद à¤à¤• विशेषता नाम के " +"पशà¥à¤šà¤¾à¤¤à¥ हो गया; " +"कोई विशेषता मूलà¥à¤¯ नहीं" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से विशेषता मान के भीतर हो गया" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से अवयव '%s' हेतॠबनà¥à¤¦ टैग के भीतर हो गया" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ का अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप से टिपà¥à¤ªà¤£à¥€ या पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ निरà¥à¤¦à¥‡à¤¶ के भीतर हो " +"गया" + +#: ../glib/goption.c:795 +msgid "Usage:" +msgstr "पà¥à¤°à¤¯à¥‹à¤—:" + +#: ../glib/goption.c:795 +msgid "[OPTION...]" +msgstr "[विकलà¥à¤ª...]" + +#: ../glib/goption.c:911 +msgid "Help Options:" +msgstr "मदद विकलà¥à¤ª:" + +#: ../glib/goption.c:912 +msgid "Show help options" +msgstr "मदद विकलà¥à¤ª दिखाà¤à¤" + +#: ../glib/goption.c:918 +msgid "Show all help options" +msgstr "सभी मदद विकलà¥à¤ª दिखाà¤à¤" + +#: ../glib/goption.c:980 +msgid "Application Options:" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— विकलà¥à¤ª:" + +#: ../glib/goption.c:1044 ../glib/goption.c:1114 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "पूरà¥à¤£à¤¾à¤‚क मान '%s' को %s के लिठविशà¥à¤²à¥‡à¤·à¤£ नहीं कर सकता" + +#: ../glib/goption.c:1054 ../glib/goption.c:1122 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "पूरà¥à¤£à¤¾à¤‚क मान '%s' %s के लिठदायरा के बाहर है" + +#: ../glib/goption.c:1079 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "'%s' दोहरे मान का विशà¥à¤²à¥‡à¤·à¤£ %s के लिठनहीं कर सकता है" + +#: ../glib/goption.c:1087 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "'%s' दोहरा मान %s के लिठपरिसर से बाहर है" + +#: ../glib/goption.c:1373 ../glib/goption.c:1452 +#, c-format +msgid "Error parsing option %s" +msgstr "%s विकलà¥à¤ª विशà¥à¤²à¥‡à¤·à¤£ में तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/goption.c:1483 ../glib/goption.c:1596 +#, c-format +msgid "Missing argument for %s" +msgstr "%s के लिठगà¥à¤® तरà¥à¤•" + +#: ../glib/goption.c:2057 +#, c-format +msgid "Unknown option %s" +msgstr "अनजान विकलà¥à¤ª %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "खराब वसà¥à¤¤à¥" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "आंतरिक तà¥à¤°à¥à¤Ÿà¤¿ या खराब वसà¥à¤¤à¥" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ के बाहर" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "बैकटà¥à¤°à¥ˆà¤•िंग सीमा पहà¥à¤à¤š गई" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"पà¥à¤°à¤¾à¤°à¥‚प में वे वसà¥à¤¤à¥à¤à¤ समाहित हैं जो आंशिक मिलान के लिठसमरà¥à¤¥à¤¿à¤¤ नहीं हैं" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "पà¥à¤°à¤¤à¤¿ संदरà¥à¤­ कà¥à¤¯à¥‹à¤‚कि परिसà¥à¤¥à¤¿à¤¤à¤¿ आंशिक मिलान के लिठसमरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "रिकरà¥à¤¸à¤¨ सीमा समापà¥à¤¤" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "नà¥à¤¯à¥‚लाइन फà¥à¤²à¥ˆà¤— का अवैध संयोग" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "खराब ऑफसेट" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "छोटा utf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "रिकरà¥à¤¸à¤¨ लूप" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ पà¥à¤°à¤¾à¤°à¥‚प के अंत में" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c पà¥à¤°à¤¾à¤°à¥‚प के अंत में" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "अपरिचित वरà¥à¤£ \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} कà¥à¤µà¤¾à¤‚टिफाइर में संखà¥à¤¯à¤¾ कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ नहीं" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} कà¥à¤µà¤¾à¤‚टिफायर में संखà¥à¤¯à¤¾ बहà¥à¤¤ बड़ी" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "अनà¥à¤ªà¤¸à¥à¤¥à¤¿à¤¤ समापà¥à¤¤ करता ] वरà¥à¤£ वरà¥à¤— के लिà¤" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "वरà¥à¤£ वरà¥à¤— में अवैध à¤à¤¸à¥à¤•ेप शृंखला" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "वरà¥à¤£ वरà¥à¤— में दायरा कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ नहीं" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "दà¥à¤¹à¤°à¤¾à¤¨à¥‡ के लिठकà¥à¤› नहीं" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ दà¥à¤¹à¤°à¤¾à¤µ" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? या (?- के बाद अपरिचित वरà¥à¤£" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "पोसिकà¥à¤¸ नामित वरà¥à¤— केवल वरà¥à¤— के अंदर समरà¥à¤¥à¤¿à¤¤ है" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "समापà¥à¤¤à¤¿ चिहà¥à¤¨ अनà¥à¤ªà¤¸à¥à¤¥à¤¿à¤¤ है )" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "गैर मौजूद उप पà¥à¤°à¤¾à¤°à¥‚प का संदरà¥à¤­" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "अनà¥à¤ªà¤¸à¥à¤¥à¤¿à¤¤ ) टिपà¥à¤ªà¤£à¥€ के बाद" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "नियमित अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ काफी बड़ी है" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ पाने में विफल" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") बिना दà¥à¤µà¤¾à¤° के (" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "कोड अतिपà¥à¤°à¤µà¤¾à¤¹" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "(?< के बाद अपरिचित वरà¥à¤£" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "लà¥à¤•बिहाइंड तथà¥à¤¯ सà¥à¤¥à¤¿à¤° लंबाई की नहीं है" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "विरूपित संखà¥à¤¯à¤¾ या नाम के बाद (?(" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "गोपनीय समूह में दो शाखाओं से अधिक समाहित है" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "तथà¥à¤¯ इसके बाद पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R या (?[+-]अंक को जरूर इसके साथ आना चाहिठ)" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "अजà¥à¤žà¤¾à¤¤ पोसिकà¥à¤¸ वरà¥à¤— नाम" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "पोसिकà¥à¤¸ कोलेटिंग ततà¥à¤µ समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} में वरà¥à¤£ शृंखला काफी बड़ी है" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "अवैध परिसà¥à¤¥à¤¿à¤¤à¤¿ (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C लà¥à¤•बिहाइंड तथà¥à¤¯ में सà¥à¤µà¥€à¤•ृत नहीं है" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, और \\u समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "पà¥à¤¨à¤°à¤¾à¤µà¤°à¥à¤¤à¥€ आहà¥à¤µà¤¾à¤¨ अनिशà¥à¤šà¤¿à¤¤ काल के लिठलूप कर सकता है" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "(?P के बाद अपरिचित वरà¥à¤£" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "उप पà¥à¤°à¤¾à¤°à¥‚प नाम में अनà¥à¤ªà¤¸à¥à¤¥à¤¿à¤¤ टरà¥à¤®à¤¿à¤¨à¥‡à¤Ÿà¤°" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "दो नाम उप पà¥à¤°à¤¾à¤°à¥‚प के पास समान नाम हैं" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "विरूपित \\P या \\p शृंखला" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "\\P या \\p के बाद अजà¥à¤žà¤¾à¤¤ गà¥à¤£ नाम" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "उप पà¥à¤°à¤¾à¤°à¥‚प नाम काफी बड़ा है (अधिकतम 32 वरà¥à¤£ का)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "कई नामित उप पà¥à¤°à¤¾à¤°à¥‚प (अधिकतम 10,000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "ओकà¥à¤Ÿà¤² मान से बड़ा है \\377" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "ओवररैन कंपाइलिंग कारà¥à¤¯à¤¸à¥à¤¥à¤¾à¤¨" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "पहले से जाà¤à¤šà¥‡ गठसंदरà¥à¤­à¤¿à¤¤ उप पà¥à¤°à¤¾à¤°à¥‚प नहीं मिला" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "परिभाषा समूह में à¤à¤• से अधिक शाखाà¤à¤ हैं" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "असंगत नà¥à¤¯à¥‚लाइन विकलà¥à¤ª" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g कोषà¥à¤ à¤•, सरà¥à¤ªà¤¿à¤² कोषà¥à¤ à¤•, उदà¥à¤§à¤°à¤¿à¤¤ नाम या संखà¥à¤¯à¤¾ या बस संखà¥à¤¯à¤¾ के बाद नहीं आता " +"है" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "à¤à¤• संखà¥à¤¯à¤¾ संदरà¥à¤­ जरूर शूनà¥à¤¯ होना चाहिà¤" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" +"(*ACCEPT), (*FAIL), या (*COMMIT) के लिठकोई तरà¥à¤• नहीं पालन किया जाता है" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) परिचित नहीं है" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "संखà¥à¤¯à¤¾ काफी बड़ी है" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& के बाद अनà¥à¤ªà¤¸à¥à¤¥à¤¿à¤¤ उपपà¥à¤°à¤¾à¤°à¥‚प नाम" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ के बाद पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ अंक" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] अवैध आà¤à¤•ड़ा वरà¥à¤£ है जावासà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ सà¥à¤¸à¤‚गतता अवसà¥à¤¥à¤¾ में" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "समान संखà¥à¤¯à¤¾ के उप पà¥à¤°à¤¾à¤°à¥‚प के लिठभिनà¥à¤¨ नाम की अनà¥à¤®à¤¤à¤¿ नहीं है" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) को जरूर वितरà¥à¤• होना चाहिà¤" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c को किसी ASCII वरà¥à¤£ के बाद आना चाहिà¤" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k कोषà¥à¤ à¤•, सरà¥à¤ªà¤¿à¤² कोषà¥à¤ à¤• या उदà¥à¤§à¤°à¤¿à¤¤ नाम के बाद नहीं पालन किया जाता है" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N किसी वरà¥à¤— में समरà¥à¤¥à¤¿à¤¤ नहीं है" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "कई अगà¥à¤°à¤¸à¤¾à¤°à¤¿à¤¤ संदरà¥à¤­" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), या (*THEN) में नाम काफी लंबा है" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... शृंखला में वरà¥à¤£ मान काफी बड़ा है" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "नियमित अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ %s मिलान के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE लाइबà¥à¤°à¥‡à¤°à¥€ को बिना UTF8 समरà¥à¤¥à¤¨ के कंपाइल किया गया है" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE लाइबà¥à¤°à¥‡à¤°à¥€ को बिना UTF8 गà¥à¤£ समरà¥à¤¥à¤¨ के कंपाइल किया गया है" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE लाइबà¥à¤°à¥‡à¤°à¥€ को असंगत विकलà¥à¤ª के साथ कंपाइल किया गया है" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "नियमित अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ %s को वरà¥à¤£ %d पर कंपाइल करने के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "नियमित अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ %s के अनà¥à¤•ूलित किठजाने के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "हेसà¥à¤•ाडेसीमल अंक या '}' पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "हेसà¥à¤•ाडेसीमल अंक पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "अनà¥à¤ªà¤¸à¥à¤¥à¤¿à¤¤ '<' सांकेतिक संदरà¥à¤­ में" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "अपूरà¥à¤£ सांकेतिक संदरà¥à¤­" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "शूनà¥à¤¯ लंबाई सांकेतिक संदरà¥à¤­" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "अंक पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "अवैध सांकेतिक संदरà¥à¤­" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "सà¥à¤Ÿà¥à¤°à¥‡ फाइनल '\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "अजà¥à¤žà¤¾à¤¤ à¤à¤¸à¥à¤•ेप शृंखला" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "पà¥à¤°à¤¤à¤¿à¤¸à¥à¤¥à¤¾à¤ªà¤¨ पाठ \"%s\" को %lu पर विशà¥à¤²à¥‡à¤·à¤£ के दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "कोटेड पाठ कोटेशन चिहà¥à¤¨ के साथ पà¥à¤°à¤¾à¤°à¤‚भ नहीं होता" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "कमांड पंकà¥à¤¤à¤¿ में मेल नहीं खाते कोटेशन चिहà¥à¤¨ या अनà¥à¤¯ शैल-कोटेड पाठ" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "पाठ का अंत सिरà¥à¤« '\\' वरà¥à¤£ के बाद हो गया. (पाठ था '%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr " %c हेतॠमैचिंग कोट से पहले पाठ अंत पाया. (पाठ था '%s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "पाठ खाली था (या उसमें सिरà¥à¤« शà¥à¤µà¥‡à¤¤ रिकà¥à¤¤à¤¿ ही था)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) से डेटा पढ़ने में असफल" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"à¤à¤• संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) से चà¥à¤¨à¥‡à¤‚() पढ़ने का डेटा में अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() (%s) में अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ %ld से बाहर निकल गया" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ %ld के दà¥à¤µà¤¾à¤°à¤¾ समापà¥à¤¤ किया गया" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ %ld संकेत के दà¥à¤µà¤¾à¤°à¤¾ रोका गया" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ असामानà¥à¤¯ रूप से बाहर निकल गया" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "संतति पाइप (%s) से पढ़ने में असफल" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) फॉरà¥à¤• करने में असफल" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' (%s) पर बदलने में असफल" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ \"%s\" (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करने में असफल" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "आउटपà¥à¤Ÿ या संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) के इनपà¥à¤Ÿ को अनà¥à¤ªà¥à¤°à¥‡à¤·à¤¿à¤¤ करने में असफल" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) फॉरà¥à¤• करने में असफल" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ \"%s\" कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करने में अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "संतति पीआईडी पाइप (%s) से परà¥à¤¯à¤¾à¤ªà¥à¤¤ डेटा पढ़ने में असफल" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ से डेटा पढ़ने में असफल" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) से संचारण हेतॠपाइप बनाने में असफल" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करने में असफल" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "अवैध पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® नाम: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d पर तरà¥à¤• सदिश में अवैध सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "वातावरण में अवैध सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "अवैध कारà¥à¤¯à¤¶à¥€à¤² निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "हेलà¥à¤ªà¤° पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करने में असफल" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"à¤à¤• संतति पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ से डेटा पढ़ने में g_io_channel_win32_poll() में " +"अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/gutf8.c:780 +#| msgid "failed to get memory" +msgid "Failed to allocate memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ संभाजित करने में विफल" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "यूटीà¤à¤«-8 हेतॠवरà¥à¤£ सीमा से बाहर" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "परिवरà¥à¤¤à¤¨ इनपà¥à¤Ÿ में अवैध अनà¥à¤•à¥à¤°à¤®" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "यूटीà¤à¤«-16 हेतॠवरà¥à¤£ सीमा से बाहर" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u बाइट" +msgstr[1] "%u bytes" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f कि.बा." + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f मे.बा." + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f गी.बा." + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f कि.बा." + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f कि.बा." + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f कि.बा." + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f कि.बा." + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f मे.बा." + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f गी.बा." + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f कि.बा." + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f कि.बा." + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f कि.बा." + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s बाइट" +msgstr[1] "%s बाइटà¥à¤¸" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f कि.बा." + +msgctxt "full month name with day" +msgid "January" +msgstr "जनवरी" + +msgctxt "full month name with day" +msgid "February" +msgstr "फ़रवरी" + +msgctxt "full month name with day" +msgid "March" +msgstr "मारà¥à¤š" + +msgctxt "full month name with day" +msgid "April" +msgstr "अपà¥à¤°à¥‡à¤²" + +msgctxt "full month name with day" +msgid "May" +msgstr "मई" + +msgctxt "full month name with day" +msgid "June" +msgstr "जून" + +msgctxt "full month name with day" +msgid "July" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +msgctxt "full month name with day" +msgid "August" +msgstr "अगसà¥à¤¤" + +msgctxt "full month name with day" +msgid "September" +msgstr "सितमà¥à¤¬à¤°" + +msgctxt "full month name with day" +msgid "October" +msgstr "अकà¥à¤Ÿà¥‚बर" + +msgctxt "full month name with day" +msgid "November" +msgstr "नवमà¥à¤¬à¤°" + +msgctxt "full month name with day" +msgid "December" +msgstr "दिसमà¥à¤¬à¤°" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "जनवरी" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "फ़रवरी" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "मारà¥à¤š" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "अपà¥à¤°à¥‡à¤²" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "मई" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "जून" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "अग." + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "सित." + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "अकà¥à¤¤à¥‚." + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "नवं." + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "दिसं." + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "xmllint के साथ इनपà¥à¤Ÿ फ़ाइल की पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ में तà¥à¤°à¥à¤Ÿà¤¿:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata के साथ इनपà¥à¤Ÿ फ़ाइल की पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ में तà¥à¤°à¥à¤Ÿà¤¿:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "सà¥à¤¥à¤—ित तà¥à¤°à¥à¤Ÿà¤¿ पाने में असमरà¥à¤¥: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "फ़ाइल '%s' को लिखने के लिठखोलने में विफल: fdopen() विफल: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "'%s' फ़ाइल में लिखने में विफल: fflush() विफल: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "'%s' फ़ाइल बंद करने में विफल: fclose() विफल: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "'%s' के लिठअपूरà¥à¤£ आà¤à¤•ड़ा पà¥à¤°à¤¾à¤ªà¥à¤¤" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ " जाà¤à¤š के दौरान अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ विकलà¥à¤ª लंबाई अगर SO_PASSCRED सॉकेट के लिठसकà¥à¤·à¤® है. " +#~ "अपेकà¥à¤·à¤¿à¤¤ %d बाइटà¥à¤¸, पà¥à¤°à¤¾à¤ªà¥à¤¤ %d" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "असामानà¥à¤¯ पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® समापन सà¥à¤ªà¥‰à¤¨à¤¿à¤‚ग कमांड लाइन '%s': %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "कमांड लाइन '%s' गैर शूनà¥à¤¯ निकास सà¥à¤¥à¤¿à¤¤à¤¿ %d के साथ बाहर निकल गया: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "रिकà¥à¤¤ उपसà¥à¤Ÿà¥à¤°à¤¿à¤‚ग के लिठकारà¥à¤¯ सà¥à¤¥à¤¾à¤¨ सीमा समापà¥à¤¤" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "केस परिवरà¥à¤¤à¤¨ à¤à¤¸à¥à¤•ेप (\\l, \\L, \\u, \\U) यहाठअनà¥à¤®à¤¤à¤¿ पà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं है" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "किसी परिभाषा समूह को दà¥à¤¹à¤°à¤¾à¤¨à¤¾ सà¥à¤µà¥€à¤•ृत नहीं है" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' के लिठकोई सेवा रिकारà¥à¤¡ नहीं" + +#~ msgid "File is empty" +#~ msgstr "फ़ाइल खाली है" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "कà¥à¤‚जी फ़ाइल में '%s' कà¥à¤‚जी है जिसके मान का विशà¥à¤²à¥‡à¤·à¤£ नहीं किया जा सकता." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "'%s' फ़ाइल वà¥à¤¯à¤•à¥à¤¤ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#~ msgid "Error connecting: " +#~ msgstr "कनेकà¥à¤Ÿ करने में तà¥à¤°à¥à¤Ÿà¤¿: " + +#~ msgid "Error connecting: %s" +#~ msgstr "कनेकà¥à¤Ÿ करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "यूनिकà¥à¤¸ से पढ़ने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "यूनिकà¥à¤¸ बंद करने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "यूनिकà¥à¤¸ में लिखने में तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पर निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा नहीं खिसका सकता है" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "परिवरà¥à¤¤à¤¨ इनपà¥à¤Ÿ में अवैध अनà¥à¤•à¥à¤°à¤®" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "अधिकतम आà¤à¤•ड़ा सरणी सीमा पर पहà¥à¤à¤šà¤¾" + +#~ msgid "do not hide entries" +#~ msgstr "पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¤¿ मत छà¥à¤ªà¤¾à¤à¤" + +#~ msgid "use a long listing format" +#~ msgstr "लंबी सूची पà¥à¤°à¤¾à¤°à¥‚प का पà¥à¤°à¤¯à¥‹à¤— करें" diff --git a/po/hr.po b/po/hr.po new file mode 100644 index 0000000..42c66ef --- /dev/null +++ b/po/hr.po @@ -0,0 +1,6291 @@ +# Translation of glib to Croatiann +# Copyright (C) Croatiann team +# Translators: Denis Lackovic ,Robert Sedak , +msgid "" +msgstr "" +"Project-Id-Version: glib 0\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-19 06:05+0000\n" +"PO-Revision-Date: 2022-04-20 19:44+0200\n" +"Last-Translator: gogo \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Launchpad-Export-Date: 2021-10-27 14:24+0000\n" +"X-Generator: Poedit 2.3\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Postavljanje zadanih aplikacija joÅ¡ nije podržano" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Postavljanje aplikacije kao posljednju koriÅ¡tenu za vrstu joÅ¡ nije podržano" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Mogućnosti GAplikacije" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Prikaži mogućnosti GAplikacije" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "UÄ‘i u servisni naÄin GAplikacije (koristi se iz datoteka D-Bus usluge)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "ZaobiÄ‘i ID aplikacije" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Zamijeni pokrenuti primjerak" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Prikaži pomoć" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[NAREDBA]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Prikaži inaÄicu" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Prikaži informaciju inaÄice i izaÄ‘i" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Prikaži apliakcije" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Prikaži instalirane aplikacije koje se pokreću D-Bus aktivacijom (po ." +"desktop datotekama)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Pokreni aplikaciju" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Pokreni aplikaciju (s neobaveznim datotekama za otvaranje)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "IDAPLIKACIJE [DATOTEKA…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktiviraj radnju" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Pokreni radnju na aplikaciji" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ID APLIKACIJE RADNJE [PARAMETAR]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Prikaži dostupne radnje" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Prikaži nepromjenjive radnje za aplikaciju (iz .desktop datoteke)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ID APLIKACIJE" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "NAREDBA" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Naredba za prikaz opÅ¡irnije pomoći za" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Identifikator aplikacije u D-Bus formatu (npr: org.primjer.preglednik)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "DATOTEKA" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Neobavezni relativni ili apsolutni nazivi datoteka ili URI-ji za otvoriti" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "RADNJA" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Naziv radnje za pokrenuti" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETAR" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Neobavezni parametri za pokretanje radnje u GVariant formatu" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Nepoznata naredba %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Upotreba:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumenti:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTI…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Naredbe:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Koristite “%s help NAREDBU†za opÅ¡irniju pomoć.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s naredba zahtijeva id aplikacije za izravno slijeÄ‘enje\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "nevaljani id aplikacije: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†ne prihvaća argumente\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "nemoguće povezivanje sa D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "greÅ¡ka slanja %s poruke u aplikaciju: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "naziv radnje mora biti naveden nakon id-a aplikacije\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nevaljan naziv radnje: “%sâ€\n" +"naziv radnje mora sadržavati brojÄano-slovne znakove, “-†i “.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "greÅ¡ka obrade parametara radnje: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "radnja prihvaća najviÅ¡e jedan parametar\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions naredba prihvaća samo id aplikacije" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "" +"nemoguće pronalazak datoteke radne povrÅ¡ine (.desktop) za aplikaciju %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"nepoznata naredba: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Prevelika brojÄana vrijednost proslijeÄ‘ena u %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Premotavanje nije podržano na osnovnom strujanju" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Nemoguće skraćivanje GBufferedInputStreama" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Strujanje je već zatvoreno" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Skraćivanje nije podržano na osnovnom strujanju" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Radnja je prekinuta" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Neispravni objekt, nije pokrenut" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Nepotpun viÅ¡ebajtni niz na ulazu" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Nedovoljno prostora u odrediÅ¡tu" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Neispravan niz bajta na ulazu pretvorbe" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "GreÅ¡ka tijekom pretvorbe: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Prekidanje pokretanja nije podržano" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Pretvaranje iz znakovnog skupa “%s†u “%s†nije podržano" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Nemoguće je otvoriti pretvornik iz “%s†u “%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s vrsta" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Nepoznata vrsta" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s vrsta datoteke" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GVjerodajnice sadrže nevaljane podatke" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GVjerodajnice nisu implementirane na ovom OS-u" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Nema podrÅ¡ke GVjerodajnica za vaÅ¡u platformu" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GVjerodajnice ne sadrže ID procesa na ovom OS-u" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Podvala vjerodajnica nije moguća na ovom OS-u" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "NeoÄekivani prerani zavrÅ¡etak strujanja" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nepodržani kljuÄ â€œ%s†u unosu adrese “%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Besmislena kombinacija para kljuÄa/vrijednosti u unosu adrese “%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adresa “%s†je nevaljana (potrebna je toÄno jedna putanja, dir, privremeni " +"dir ili apstraktni kljuÄ)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "GreÅ¡ka u adresi “%s†— “%s†svojstvo je oÅ¡tećeno" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Nepoznati ili nepodržani prijenos “%s†za adresu “%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Element adrese “%s†ne sadrži dvotoÄku (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Naziv prijenosa u elementu adrese “%s†ne može biti prazan" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Par kljuÄa/vrijednosti %d, “%sâ€, u elementu adrese “%s†ne sadrže znak " +"jednakosti" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Par kljuÄa/vrijednosti %d, “%sâ€, u elementu adrese “%s†ne mogu sadržavati " +"prazan kljuÄ" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"GreÅ¡ka neizbjegavanja kljuÄa ili vrijednosti u paru kljuÄa/vrijednosti %d, " +"“%sâ€, u elementu adrese “%sâ€" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"GreÅ¡ka u adresi “%s†— unix prijenos zahtijeva toÄno postavljeno jedno " +"kljuÄevo “path†ili “abstract†svojstvo" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "GreÅ¡ka u adresi “%s†— svojstvo poslužitelja nedostaje ili je oÅ¡tećeno" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "GreÅ¡ka u adresi “%s†— svojstvo ulaza nedostaje ili je oÅ¡tećeno" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"GreÅ¡ka u adresi “%s†— svojstvo jednokratne datoteke nedostaje ili je " +"oÅ¡tećeno" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "GreÅ¡ka automatskog pokretanja: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "GreÅ¡ka otvaranja jednokratne datoteke “%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "GreÅ¡ka Äitanja iz jednokratne datoteke “%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"GreÅ¡ka Äitanja iz jednokratne datoteke “%sâ€, oÄekivano je 16 bajta, dobiveno " +"je %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "GreÅ¡ka zapisivanja sadržaja jednokratne datoteke “%s†u strujanje:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Navedena adresa je prazna" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Nemoguće pokretanje sabirnice poruke kada je AT_SECURE postavljen" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Nemoguće pokretanje sabirnice poruke bez id-raÄunala: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Nemoguće automatsko pokretanje bez X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "GreÅ¡ka pokretanja naredbenog redka “%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Nemoguće otkrivanje adrese sabirnice sesije (nije implementirano za ovaj OS)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Nemoguće otkrivanje adrese sabirnice iz DBUS_STARTER_BUS_TYPE varijable " +"okruženja — nepoznata vrijednost “%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Nemoguće otkrivanje adrese sabirnice zato jer DBUS_STARTER_BUS_TYPE " +"varijabla okruženja nije postavljena" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Nepoznata vrsta sabirnice %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "NeoÄekivani nedostatak sadržaja pri Äitanju redka" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "NeoÄekivani nedostatak sadržaja pri (sigurnom ) Äitanju redka" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Iscrpljeni su svi dostupni mehanizmi ovjere (isprobano: %s) (dostupno: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "KorisniÄki ID mora biti isti za toÄku ili poslužitelj" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "PoniÅ¡teno putem GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "GreÅ¡ka dobivanja informacija za direktorij “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Dozvole na direktoriju “%s†su oÅ¡tećene. OÄekivana dozvola 0700, dobivena je " +"0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "GreÅ¡ka stvaranja direktorija “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Radnja nije podržana" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "GreÅ¡ka otvaranja skupa kljuÄeva “%s†za Äitanje: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Redak %d skupa kljuÄeva na “%s†sa sadržajem “%s†je oÅ¡tećen" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Prvi token redka %d skupa kljuÄeva na “%s†sa sadržajem “%s†je oÅ¡tećen" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Drugi token redka %d skupa kljuÄeva na “%s†sa sadržajem “%s†je oÅ¡tećen" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Nije pronaÄ‘en kolaÄić s ID %d u skupu kljuÄeva na “%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "GreÅ¡ka stvaranja datoteke zakljuÄavanja “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "GreÅ¡ka brisanja zaostale datoteke zakljuÄavanja “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "GreÅ¡ka zatvaranja (nepovezane) datoteke zakljuÄavanja “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "GreÅ¡ka uklanjanja poveznice datoteke zakljuÄavanja “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "GreÅ¡ka otvaranja skupa kljuÄeva “%s†za zapisivanje: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Dodatno, oslobaÄ‘anje zakljuÄavanja za “%s†je isto neuspjelo: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Povezivanje je zatvoreno" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Vrijeme isteka dostignuto" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Nepodržane oznake pronaÄ‘ene pri izgradnje povezivanja od strane klijenta" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Nema takvog suÄelja “org.freedesktop.DBus.Properties†na putanji objekta %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Nema takvog svojstva “%sâ€" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Svojstvo “%s†nije Äitljivo" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Svojstvo “%s†nije zapisivo" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"GreÅ¡ka postavljanja svojstva “%sâ€: OÄekivana je vrsta “%s†ali je dobivena " +"“%sâ€" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Nema takvog suÄelja “%sâ€" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Nema takvog suÄelja “%s†na putanji objekta %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Nema takvog naÄina “%sâ€" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Vrsta poruke, “%sâ€, ne podudara se s oÄekivanom vrstom “%sâ€" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Objekt je već izvezen za suÄelje %s na %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Nemoguće dobivanju svojstva %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Nemoguće postavljanje svojstva %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "NaÄin “%s†je vratio vrstu “%sâ€, ali je oÄekivano “%sâ€" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "NaÄin “%s†na suÄelju “%s†s potpisom “%s†ne posoji" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Podstablo je već izvezeno za %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Objekt ne postoji na putanji “%sâ€" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "vrsta je NEVALJANA" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL poruka: PATH ili MEMBER polja zaglavlja nedostaju" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN poruka: REPLY_SERIAL polja zaglavlja nedostaju" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR poruka: REPLY_SERIAL ili ERROR_NAME polja zaglavlja nedostaju" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL poruka: PATH, INTERFACE ili MEMBER polja zaglavlja nedostaju" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL poruka: PATH polje zaglavlja koristi rezerviranu vrijednost /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL poruka: INTERFACE polje zaglavlja koristi rezerviranu vrijednost org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "PokuÅ¡aj Äitanja %lu bajta, ali je dobiven samo %lu" +msgstr[1] "PokuÅ¡aj Äitanja %lu bajta, ali je dobiven samo %lu" +msgstr[2] "PokuÅ¡aj Äitanja %lu bajta, ali je dobiven samo %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "OÄekivan je nula bajt nakon izraza “%sâ€, ali je pronaÄ‘en bajt %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"OÄekivan je valjani UTF-8 niz ali su pronaÄ‘eni nevaljani bajti u pomaku " +"bajta %d (duljina niza je %d). Valjani UTF-8 niz do te toÄke je bio “%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Vrijednost je ugniježđena preduboko" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "ObraÄ‘ena vrijednost “%s†nije valjana D-Bus putanja objekta" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "ObraÄ‘ena vrijednost “%s†nije valjani D-Bus potpis" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"PronaÄ‘en je niz duljine %u bajta. Najveća duljina je is 2<<26 bajta (64 MiB)." +msgstr[1] "" +"PronaÄ‘en je niz duljine %u bajta. Najveća duljina je is 2<<26 bajta (64 MiB)." +msgstr[2] "" +"PronaÄ‘en je niz duljine %u bajta. Najveća duljina je is 2<<26 bajta (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"PronaÄ‘en je niz vrste “a%câ€, oÄekivano je da ima duljinu umnoÅ¡ka od %u " +"bajta, ali je pronaÄ‘eno da je duljina %u bajta" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Prazne strukture (tuples) nisu dopuÅ¡tene u D-Bus-u" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "ObraÄ‘ena vrijednost “%s†za varijantu nije valjan D-Bus potpis" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"GreÅ¡ka pri deserijalizaciji GVariante s nizom vrste \"% s\" iz D-Bus formata " +"provodnika" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Nevaljana endian vrijednost. OÄekivana je 0x6c (“lâ€) ili 0x42 (“Bâ€) ali je " +"pronaÄ‘ena vrijednost 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"Nevaljana inaÄica glavnog protokola. OÄekivana je 1 ali je pronaÄ‘ena %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Zaglavlje potpisa je pronaÄ‘eno ali nije prikladna vrsta potpisa" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Zaglavlje potpisa s potpisom “%s†je pronaÄ‘eno ali tijelo poruke je prazno" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "ObraÄ‘ena vrijednost “%s†nije valjan D-Bus potpis (za tijelo)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Nema zaglavlja potpisa u poruci ali tijelo poruke je %u bajt" +msgstr[1] "Nema zaglavlja potpisa u poruci ali tijelo poruke je %u bajta" +msgstr[2] "Nema zaglavlja potpisa u poruci ali tijelo poruke je %u bajta" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Nemoguća deserijalizacija poruke: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"GreÅ¡ka serijalizacije GVariante s nizom vrste “%s†u D-Bus formata provodnika" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Broj opisnika datoteke u poruci (%d) razlikuje se od polja zaglavlja (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Nemoguća serijalizacija poruke: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Tijelo poruke ima potpis “%sâ€, ali ne sadrži zaglavlje potpisa" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Tijelo poruke ima vrstu potpisa “%sâ€, ali potpis u polju zaglavlja je “%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Tijelo poruke je prazno, ali potpis u polju zaglavlja je “(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Vraćena je greÅ¡ka s tijelom vrste “%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Vraćena je greÅ¡ka s praznim tijelom" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(UpiÅ¡ite bilo kakav znak za zatvaranje ovog prozora)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Dbus sesije nije pokrenut, automatsko pokretanje neuspjelo" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Neuspjelo dobivanje profila hardvera: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Nemoguće uÄitavanje %s ili %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "GreÅ¡ka poziva StartServiceByName za %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "NeoÄekivan odgovor %d od StartServiceByName(\"%s\") naÄina" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Nemoguć poziv naÄina; proxy je za dobro poznati naziv %s bez vlasnika, a " +"proxy je konstruiran sa G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START oznakom" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Apstraktan prostor naziva nije podržan" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Nemoguće odreÄ‘ivanje jednokratne datoteke pri stvaranju poslužitelja" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "GreÅ¡ka zapisivanja jednokratne datoteke na “%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Izraz “%s†nije valjan D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Nemoguće osluÅ¡kivanje nepodržanog prijenosa “%sâ€" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Naredbe:\n" +" help Prikazuje ove informacije pomoći\n" +" introspect Preispituje udaljeni objekt\n" +" monitor Nadgleda udaljeni objekt\n" +" call Poziva naÄin na udaljenom objektu\n" +" emit Emitira signal\n" +" wait ÄŒekaj da se pojavi naziv sabirnice\n" +"\n" +"Koristite “%s NAREDBA --help†za dobivanje pomoći pojedine naredbe.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "GreÅ¡ka: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "GreÅ¡ka preispitivanja XML-a: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "GreÅ¡ka: %s nije valjani naziv\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "GreÅ¡ka: %s nije valjana putanja objekta\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Povezivanje sa sabirnicom sustava" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Povezivanje sa sabirnicom sesije" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Povezivanje sa zadanom D-Bus adresom" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Mogućnosti krajnje toÄke povezivanja:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Mogućnosti koje odreÄ‘uju krajnje toÄke povezivanja" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Krajnja toÄka povezivanja nije odreÄ‘ena" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "ViÅ¡e krajnjih toÄka povezivanja je odreÄ‘eno" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Upozorenje: Prema podacima preispitivanja, suÄelje “%s†ne postoji\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Upozorenje: Prema podacima preispitivanja, naÄin “%s†ne postoji na suÄelju " +"“%sâ€\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Dodatno odrediÅ¡te za signal (jedinstveni naziv)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Putanja objekta na koje se emitira signal" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Naziv signala i suÄelja" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emitiraj signal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "GreÅ¡ka povezivanja: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "GreÅ¡ka: %s nije valjan jedinstven naziv sabirnice.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "GreÅ¡ka: Putanja objekta nije navedena\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "GreÅ¡ka: Naziv signala nije naveden\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "GreÅ¡ka: Naziv signala “%s†nije valjan\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "GreÅ¡ka: %s nije valjani naziv suÄelja\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "GreÅ¡ka: %s nije valjani naziv Älana\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "GreÅ¡ka obrade parametra %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "GreÅ¡ka pražnjenja povezivanja: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Naziv odrediÅ¡ta za poziv naÄina" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Putanja objekta za poziv naÄina" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Naziv naÄina i suÄelja" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Vrijeme Äekanja u sekundama" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Dopusti interaktivnu ovjeru" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Pozovi naÄin na udaljenom objektu." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "GreÅ¡ka: OdrediÅ¡te nije navedeno\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "GreÅ¡ka: %s nije valjan naziv sabirnice\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "GreÅ¡ka: Naziv naÄina nije naveden\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "GreÅ¡ka: Naziv naÄina “%s†je nevaljan\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "GreÅ¡ka obrade parametra %d vrste “%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "GreÅ¡ka dodavanja rukovanja %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Naziv odrediÅ¡ta za preispitivanje" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Putanja objekta za preispitivanje" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Prikaži XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Preispitivanje podsadržaja" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Samo prikaži svojstva" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Preispitivanje udaljenog objekta." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Naziv odrediÅ¡ta za nadgledanje" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Putanja objekta za nadgledanje" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Nadgledaj udaljeni objekt." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"GreÅ¡ka: nemoguće nadgledanje povezivanja sabirnice koja nije za poruke\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Usluga za aktiviranje prije Äekanja druge usluge (dobro poznat naziv)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Vrijeme Äekanja prije zatvaranja s greÅ¡kom (sekunde), O za vrijeme Äekanja " +"(zadano)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[MOGUĆNOST...] NAZIV-SABIRNICE" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "ÄŒekaj pojavljivanje naziva sabirnice." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "GreÅ¡ka: Usluga za aktiviranje mora biti navedena.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "GreÅ¡ka: Usluga koja se Äeka mora biti navedena.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "GreÅ¡ka: previÅ¡e argumenata.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "GreÅ¡ka: %s nije valjan dobro poznat naziv sabirnice\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Niste ovlaÅ¡teni za promjenu postavki otklanjanja greÅ¡aka" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Neimenovano" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Datoteka radne povrÅ¡ine (.desktop) nema navedeno Exec polje" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Nemoguć pronalazak potrebnog terminala za aplikaciju" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Nemoguće stvaranje mape podeÅ¡avanja aplikacije korisnika %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Nemoguće stvaranje mape MIME podeÅ¡avanja korisnika %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Informacijama aplikacije nedostaje identifikator" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Nemoguće stvaranje datoteke radne povrÅ¡ine (.desktop) korisnika %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "PrilagoÄ‘ena definicija za %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "ureÄ‘aj nema implementirano izbacivanje" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "ureÄ‘aj nema implementirano izbacivanje ili izbacivanje_s_radnjom" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "ureÄ‘aj nema implementirano bilježenje medija" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "ureÄ‘aj nema implementirano pokretanje" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "ureÄ‘aj nema implementirano zaustavljanje" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS pozadinski program nema implementirano primanje TLS povezivanja" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS podrÅ¡ka nije dostupna" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS podrÅ¡ka nije dostupna" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Nemoguće rukovanje %d inaÄicom GEmblem kôdiranja" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "OÅ¡tećeni broj tokena (%d) u GEmblem kôdiranju" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Nemoguće rukovanje %d inaÄicom GEmblemedIcon kôdiranja" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "OÅ¡tećeni broj tokena (%d) u GEmblemedIcon kôdiranju" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "OÄekivani GEmblem za GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Sadržano montiranje ne postoji" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Nemoguće kopiranje preko direktorija" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Nemoguće kopiranje direktorija preko direktorija" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "OdrediÅ¡na datoteka već postoji" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Nemoguće rekruzivno kopiranje direktorija" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Spajanje nije podržano" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "GreÅ¡ka spajanja datoteke: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"Kopiranje (referentne poveznice/kloniranje) izmeÄ‘u montiranja nije podržano" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" +"Kopiranje (referentne poveznice/kloniranje) nije podržano ili je nevaljano" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopiranje (referentne poveznice/kloniranje) nije podržano ili ne radi" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Nemoguće kopiranje posebne datoteke" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Zadana je nevaljana vrijednost simboliÄke poveznice" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "SimboliÄke poveznice nisu podržane" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Smeće nije podržano" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Nazivi datoteka ne mogu sadržavati “%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "ureÄ‘aj nema implementirano montiranje" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Nema registriranih aplikacija za rukovanje ovom datotekom" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "PopisivaÄ je zatvoren" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "PopisivaÄ datoteka ima izvanrednu radnju" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "PopisivaÄ datoteka je već zatvoren" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Nemoguće rukovanje %d inaÄicom GFileIcon kôdiranja" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "OÅ¡tećeni su ulazni podaci za GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Strujanje ne podaržava informacije_upita" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Premotavanje nije podržano na strujanju" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "SkraÄivanje nije dopuÅ¡teno na ulaznom strujanju" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "SkraÄivanje nije podržano na strujanju" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Neispravan naziv raÄunala" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Neispravan HTTP proxy odgovor" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP proxy povezivanje nije dopuÅ¡teno" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP proxy ovjera je neuspjela" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP proxy ovjera je potrebna" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP proxy povezivanje je neuspjelo: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP proxy odgovor je prevelik" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP proxy poslužitelj je neoÄekivano prekinuo povezivanje." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "PogreÅ¡an broj tokena (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Nema vrste za naziv klase %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Vrsta %s ne implementira GIcon suÄelje" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Vrsta %s nije klasificirana" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "OÅ¡tećen broj inaÄice: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Vrsta %s ne implementira from_tokens() na GIcon suÄelju" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Nemoguće rukovanje pružanom inaÄicom kôdiranja ikona" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Adresa nije navedena" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Duljina %u je predugaÄka za adresu" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adresa ima postavljene bitove izvan duljine prefiksa" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Nemoguća obrada “%s†kao IP adresne maske" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Nedovoljno prostora za prikljuÄnicu adrese" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nepodržana prikljuÄnica adrese" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Ulazno strujanje nema implementirano Äitanje" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Strujanje ima izvanrednu radnju" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopiraj s datotekom" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Zadrži s datotekom kada je premjeÅ¡tena" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†ne prihvaća argumente" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Upotreba:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Prikaži informaciju inaÄice i izaÄ‘i." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Naredbe:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Spoji datoteke na standardan izlaz" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopiraj jednu ili viÅ¡e datoteka" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Prikaži informacije o lokacijama" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Pokreni aplikaciju s datotekom radne povrÅ¡ine (.desktop)" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Prikaži sadržaj lokacija" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Nabavi ili postavi rukovatelja za mimevrste" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Stvori direktorije" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Nadgledaj promjene za datoteke i direktorije" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montiraj ili odmontiraj lokacije" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Premjesti jednu ili viÅ¡e datoteka" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Otvori datoteke sa zadanom aplikacijom" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Preimenuj datoteku" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "ObriÅ¡i jednu ili viÅ¡e datoteka" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "ÄŒitaj sa standardnog ulaza i spremi" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Postavi svojstvo datoteke" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Premjesti datoteke ili direktorije u smeće" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Prikaži sadržaj lokacije u stablu" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Koristi %s za dobivanje opÅ¡irnije pomoći.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "GreÅ¡ka zapisivanja u stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOKACIJA" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Spoji datoteke i ispiÅ¡i na standardan izlaz." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat radi poput tradicionalnog cat pomagala, ali korisit GIO\n" +"lokacije umjesto lokalnih datoteka: na primjer, možete koristiti\n" +"neÅ¡to poput smb://poslužitelj/resurs/datoteka.txt kao lokaciju." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Lokacija nije zadana" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nema odrediÅ¡nog direktorija" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Prikaži napredak" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Upitaj prije prebrisivanja" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "OÄuvaj sva svojstva" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Sigurnosno kopiraj postojeće odrediÅ¡ne datoteke" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nikada ne slijedi simboliÄke poveznice" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Koristi zadane dozvole za odrediÅ¡te" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Preneseno %s od %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "IZVOR" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ODREDIÅ TE" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopiraj jednu ili viÅ¡e datoteka iz IZVORA u ODREDIÅ TE." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy radi poput tradicionalnog cp pomagala, ali korisit GIO\n" +"lokacije umjesto lokalnih datoteka: na primjer, možete koristiti\n" +"neÅ¡to poput smb://poslužitelj/resurs/datoteka.txt kao lokaciju." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "OdrediÅ¡te nije %s direktorij" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: prebriÅ¡i “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Prikaži zapisiva svojstva" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Dobivanje informacija datoteke sustava" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Svojstva koja treba dobiti" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "SVOJSTVA" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ne slijedi simboliÄke poveznice" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "svojstva:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "prikaži naziv: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "uredi naziv: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "naziv: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "vrsta: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "veliÄina: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "skriveno\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "lokalna putanja: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix montiranje: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Postavljiva svojstva:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Zapisiva svojstva naziva prostora:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Prikaži informacije o lokacijama." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info radi poput tradicionalnog ls pomagala, ali korisit GIO\n" +"lokacije umjesto lokalnih datoteka: na primjer, možete koristiti\n" +"neÅ¡to poput smb://poslužitelj/resurs/datoteka.txt kao lokaciju.\n" +"Svojstva datoteka mogu biti navedena s njihovim GIO nazivima,\n" +"npr. standard::icon, ili jednostavno samo s nazivom prostora,\n" +"npr. unix, ili sa “*â€, Å¡to odgovara svim svojstvima" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-DATOTEKA [DATOTEKA-ARGUMENT…]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Pokreni aplikaciju s datotekom radne povrÅ¡ine (.desktop), prosljeÄ‘ujući joj " +"neobavezni naziv datoteke." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nema zadane datoteke radne povrÅ¡ine (.desktop)" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Naredba pokretanja trenutno nije podržana na ovoj platformi" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Nemoguće uÄitavanje ‘%s‘: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Nemoguće uÄitavanje informacija aplikacije za ‘%s‘" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Nemoguće pokretanje aplikacije ‘%s’: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Prikaži skrivene datoteke" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Koristi format duljeg prikaza" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Prikaži nazive prikaza" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Prikaži potpune URI-je" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Prikaži sadržaje lokacija." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list radi poput tradicionalnog ls pomagala, ali korisit GIO\n" +"lokacije umjesto lokalnih datoteka: na primjer, možete koristiti\n" +"neÅ¡to poput smb://poslužitelj/resurs/datoteka.txt kao lokaciju.\n" +"Svojstva datoteka mogu biti navedena s njihovim GIO nazivima,\n" +"npr. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMEVRSTA" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "RUKOVATELJ" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Nabavi ili postavi rukovatelj za mimevrste." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Ako rukovatelj nije zadan, prikaži registrirane i preporuÄene aplikacije\n" +"za mimevrste. Ako je rukovatelj zadan, postavljen je kao zadan\n" +"rukovatelj za mimevrstu." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Mora biti navedena jedna mimevrsta i možda rukovatelj" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Nema zadane aplikacije za “%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Zadana aplikacija za “%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registrirane aplikacije:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nema registriranih aplikacija\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "PreporuÄene aplikacije:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Nema preporuÄenih aplikacija\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Neuspjelo uÄitavanje informacija za rukovatelja “%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Neuspjelo postavljanje “%s†kao zadanog rukovatelja za “%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Stvori sadržajne direktorije" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Stvori direktorije." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir radi poput tradicionalnog mkdir pomagala, ali korisit GIO\n" +"lokacije umjesto lokalnih datoteka: na primjer, možete koristiti\n" +"neÅ¡to poput smb://poslužitelj/resurs/datoteka.txt kao lokaciju." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Nadgledaj direktorij (zadano: ovisi o vrsti)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Nadgledaj datoteku (zadano: ovisi o vrsti)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Nadgledaj datoteku izravno (bilježi promjene naÄinjene putem Ävrstih " +"poveznica)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Nadgleda datoteke izravno, ali ne prijavljuje promjene" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Prijavi premjeÅ¡tanja i preimenovanja kao jednostavne obrisane/stvorene " +"dogaÄ‘aje" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Nadgledaj dogaÄ‘aje montiranja" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Nadgledaj promjene datoteka ili direktorija." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Montiraj kao montirljivo" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Montiraj ureÄ‘aj s datotekom ureÄ‘aja ili drugim identifikatorom" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Odmontiraj" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Izbaci" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Zaustavi ureÄ‘aj s datotekom ureÄ‘aja" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "UREÄAJ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Odmontiraj sva montiranja sa zadanom shemom" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Zanemari izvanredne radnje datoteke pri odmontiravanju ili izbacivanju" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Koristi anonimnog korisnika pri ovjeri" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Popis" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Nadgledaj dogaÄ‘aje" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Prikaži dodatne informacije" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "BrojÄani PIM pri otkljuÄavanju VeraCrypt ureÄ‘aja" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montiraj TCRYPT skriven ureÄ‘aj" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montiraj TCRYPT ureÄ‘aj sustava" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anoniman pristup nije dopuÅ¡ten" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Nema ureÄ‘aja za datoteku ureÄ‘aja" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Nema ureÄ‘aja za zadan ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montiraj ili odmontiraj lokacije." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ne koristi priÄuvno kopiranje ili brisanje" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Premjesti jednu ili viÅ¡e datoteka iz IZVORA u ODREDIÅ TE." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move radi poput tradicionalnog mv pomagala, ali korisit GIO\n" +"lokacije umjesto lokalnih datoteka: na primjer, možete koristiti\n" +"neÅ¡to poput smb://poslužitelj/resurs/datoteka.txt kao lokaciju" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "OdrediÅ¡te %s nije direktorij" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Otvori datoteke sa zadanom aplikacijom koja je\n" +"registrirana za rukovanje s datotekama ove vrste." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Zanemari nepostojeće datoteke, nikada ne upitaj" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "ObriÅ¡i zadane datoteke." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAZIV" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Preimenuj datoteku." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Nedostaje argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "PreviÅ¡e argumenata" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Preimenovanje uspjeÅ¡no. Novi uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Stvori samo ako ne postoji" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Dodaj na kraj datoteke" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Pri stvaranju, ograniÄi pristup trenutnom korisniku" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Pri zamjeni, zamijeni kao da odrediÅ¡te ne postoji" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Prikaži novi etag na zavrÅ¡etku" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Etag datoteke je prebrisan" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "GreÅ¡ka pri Äitanju iz standardnog ulaza" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag nije dostupan\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "ÄŒitaj iz standardnog izlaza i spremi u ODREDIÅ TE." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "OdrediÅ¡te nije zadano" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Vrsta svojstva" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "VRSTA" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "SVOJSTVO" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VRIJEDNOST" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Postavi svojstvo datoteke LOKACIJE." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Lokacija nije navedena" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Svojstvo nije navedeno" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Vrijednost nije navedena" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Nevaljana vrsta svojstva “%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Isprazni smeće" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Prikaži datoteke u smeću s njihovim izvornim lokacijama" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Vrati datoteku iz smeća na njegovu izvornu lokaciju (moguće ponovno " +"stvaranje direktorija)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Nemoguće pronalazak izvorne putanje" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Nemoguće ponovno stvaranje izvorne lokacije: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Nemoguće premjeÅ¡tanje datoteke na njegovu izvornu lokaciju: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Premjesti/Vrati datoteke ili direktorije u smeće." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Napomena: za --restore preklopnik, ako izvorna lokacija ili datoteka iz " +"smeća \n" +"već postoje, neće biti prebrisani osim ako nije --force postavljen." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Zadana lokacija ne zapoÄinje sa trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Slijedi simboliÄke poveznice, montiranja i preÄace" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Prikaži sadržaj direktorija u obliku stabla." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> nije dopuÅ¡ten unutar <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> nije dopuÅ¡ten na najviÅ¡oj razini" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Datoteka %s se pojavljuje viÅ¡e puta u resursu" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Nemoguće je locirati “%s†u bilo kojem izvornom direktoriju" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Nemoguće je locirati “%s†u trenutnom direktoriju" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Nepoznata mogućnost obrade “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "%s zahtijeva predobradu, ali %s nije postavljena, a %s nije PUTANJA" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "GreÅ¡ka Äitanja datoteke %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "GreÅ¡ka sažimanja datoteke %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "tekst se možda neće pojaviti unutar <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Prikaži inaÄicu programa i izaÄ‘i" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Naziv izlazne datoteke" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Direktoriji za uÄitavanje datoteka navedenih u DATOTECI (zadano: trenutni " +"direktorij)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIREKTORIJ" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Stvori izlaz u formatu odabranom od strane proÅ¡irenja odrediÅ¡ta naziva " +"datoteke" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Stvori zaglavlje izvora" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Stvori izvorni kôd koriÅ¡ten za povezivanje datoteke resursa u vaÅ¡ kôd" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Stvori popis zavisnosti" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Naziv datoteke zavisnosti za stvaranje" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "UkljuÄi lažna odrediÅ¡ta u stvorenu datoteku zavisnosti" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Nemoj automatski stvoriti i registrirati resurs" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ne izvažaj funkcije; proglasi ih G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Ne ugraÄ‘uj podatak resursa u C datoteku; pretpostavi da je umjesto povezana " +"izvana" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Naziv C identifikatora koriÅ¡ten za stvoreni izvorni kôd" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Ciljani C kompilator (zadana: CC varijabla okruženja)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompiliraj specifikacije resursa u datoteku resursa.\n" +"Datoteka specifikacije resursa ima nastavak vrste\n" +"datoteke .gresource.xml, i datoteka resursa ima\n" +"nastavak vrste datoteke .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Trebali bi zadati najmanje jedan naziv datoteke\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "nadimak mora sadržavati najmanje 2 znaka" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Nevaljana brojÄana vrijednost" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " je već naveden" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' je već naveden" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "vrijednosti oznaka moraju imati najviÅ¡e postavljen 1 bit" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> mora sadržavati najmanje jedan " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> nije sadržan u navedenom rasponu" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nije valjan Älan navedene popisane vrste" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> sadrži niz koji nije u navedenoj vrsti oznake" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> sadrži niz koji nije u " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " je već odreÄ‘en za ovaj kljuÄ" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nije dopuÅ¡ten za kljuÄeve ove vrste “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " odreÄ‘eni minimum je veći od maksimuma" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "nepodržana l10n kategorija: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n je potreban, ali nema zadane gettext domene" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "sadržaj prijevoda zadan za vrijednosti bez l10n je omogućen" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Nemoguća obrada vrijednosti vrste “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" ne može biti odreÄ‘en za kljuÄeve oznaÄene da imaju popisanu vrstu" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " je već odreÄ‘en za ovaj kljuÄ" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nije dopuÅ¡ten za kljuÄ vrste “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " je već zadan" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " mora sadržavati najmanje jedan " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " je već odreÄ‘en za ovaj kljuÄ" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" može biti odreÄ‘en za kljuÄeve s popisanim ili oznaÄenim vrstama " +"ili nakon " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr " je zadan kada je “%s†već Älan popisane vrste" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " je zadan kada je već zadan" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " je već odreÄ‘en" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "alias odrediÅ¡te “%s†nije popisana vrste" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "alias odrediÅ¡te “%s†nije " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " mora sadržavati najmanje jedan " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Prazni nazivi nisu dopuÅ¡teni" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Nevaljani naziv “%sâ€: nazivi moraju zapoÄeti s malim slovom" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nevaljani naziv “%sâ€: nevaljani znak “%câ€; samo mala slova, brojevi i " +"spojnica (“-â€) su dopuÅ¡teni" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Nevaljani naziv “%sâ€: dvije uzastopne spojnice (“--â€) nisu dopuÅ¡tene" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Nevaljani naziv “%sâ€: posljednji znak ne može biti spojnica (“-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nevaljani naziv “%sâ€: najveća duljina je 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " je već odreÄ‘en" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Nemoguće dodavanje kljuÄeva u “list-off†shemu" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " je već odreÄ‘en" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" shadows u ; koristi " +" za promjenu vrijednosti" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"ToÄno jedan od “typeâ€, “enum†ili “flags†mora biti odreÄ‘en kao svojstvo " +"" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> nije (joÅ¡) odreÄ‘en." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Nevaljana GVariant vrsta niza “%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " je zadan ali shema niÅ¡ta ne proÅ¡iruje" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Nema za zaobilaženje" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " je već odreÄ‘en" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " je već odreÄ‘en" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " joÅ¡ ne proÅ¡iruje postojeću shemu “%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " je popis joÅ¡ nepostojeće sheme “%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Ne može biti popis sheme s putanjom" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Ne može proÅ¡iriti shemu s putanjom" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " je popis, proÅ¡iruje koji nije popis" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" proÅ¡iruje ali " +"“%s†ne proÅ¡iruje “%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Putanja, ako je zadana, mora zapoÄeti i zavrÅ¡iti kosom crtom" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Putanja popisa mora zavrÅ¡iti sa “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Upozorenje: Shema “%s†ima putanju “%sâ€. Putanje koje zapoÄinje sa “/" +"apps/â€, “/desktop/†ili “/system/†su zastarjele." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> je već odreÄ‘en" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Samo jedan <%s> element je dopuÅ¡ten unutar <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> nije dopuÅ¡ten na najviÅ¡oj razini" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Element je potreban u " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Tekst se možda neće pojaviti unutar <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Upozorenje: neodreÄ‘ena napomena u " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict je naveden; izlazim." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Ova cijela datoteka je zanemarena." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Zanemarivanje ove datoteke." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Nema takvog kljuÄa “%s†u shemi “%s†kao Å¡to je navedeno u datoteci " +"zaobilaženja “%sâ€; zanemarujem zaobilaženje ovog kljuÄa." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Nema takvog kljuÄa “%s†u shemi “%s†kao Å¡to je navedeno u datoteci " +"zaobilaženja “%s†i --strict je naveden; izlazim." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Nemoguće je pružiti zaobilaženje po radnoj povrÅ¡ini za lokalizirani kljuÄ " +"“%s†u shemi “%s†(datoteka zaobilaženja “%sâ€); zanemarujem zaobilaženje za " +"ovaj kljuÄ." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Nemoguće je pružiti zaobilaženje po radnoj povrÅ¡ini za lokalizirani kljuÄ " +"“%s†u shemi “%s†(datoteka zaobilaženja “%sâ€) i --strict su navedni; " +"izlazim." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"GreÅ¡ka obrade kljuÄa “%s†u shemi “%s†kao Å¡to je navedeno u datoteci " +"zaobilaženja “%sâ€: %s. Zanemarujem zaobilaženje za ovaj kljuÄ." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"GreÅ¡ka obrade kljuÄa “%s†u shemi “%s†kao Å¡to je navedeno u datoteci " +"zaobilaženja “%sâ€: %s. --strict je naveden; izlazim." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Zaobilaženje za kljuÄ â€œ%s†u shemi “%s†u datoteci zaobilaženja “%s†je " +"izvan raspona zadanom u shemi; zanemarujem zaobilaženje za ovaj kljuÄ." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Zaobilaženje za kljuÄ â€œ%s†u shemi “%s†u datoteci zaobilaženja “%s†je " +"izvan raspona zadanom u shemi i --strict je naveden; izlazim." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Zaobilaženje za kljuÄ â€œ%s†u shemi “%s†u datoteci zaobilaženja “%s†nije na " +"popisu valjanih odabira; zanemarujem zaobilaženje za ovaj kljuÄ." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Zaobilaženje za kljuÄ â€œ%s†u shemi “%s†u datoteci zaobilaženja “%s†nije na " +"popisu valjanih odabira --strict je naveden; izlazim." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Gdje treba spremiti gschemas.compiled datoteku" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Prekini na svim greÅ¡kama u shemama" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Ne zapisuj gschema.compiled datoteku" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Ne primijenjuj ograniÄenja naziva kljuÄeva" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompiliraj sve GSettings shema datoteke u predmemoriju sheme.\n" +"Datoteke shemes su potrebne za nastavak vrste datoteke .gschema.xml,\n" +"a datoteka predmemorije se naziva gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Treba li bi navesti najmanje jedan naziv direktorija" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nema pronaÄ‘ene datoteke sheme: niÅ¡ta za uÄiniti." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Nema pronaÄ‘ene datoteke sheme: uklanjanje postojeće datoteke izlaza." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Neispravan naziv datoteke %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "GreÅ¡ka dobivanja informacija datoteÄnog sustava za %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Sadržano montiranje za datoteku %s nije pronaÄ‘eno" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Nemoguće preimenovanje korijenskog direktorija" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "GreÅ¡ka peimenovanja datoteke %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Nemoguće preimenovanje datoteke, naziv datoteke već postoji" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Neispravni naziv datoteke" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "GreÅ¡ka otvaranja datoteke %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "GreÅ¡ka uklanjanja datoteke %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "GreÅ¡ka premjeÅ¡tanja datoteke u smeće %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Nemoguće stvaranje direktorija smeća %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Nemogući pronalazak direktorija najviÅ¡e razine u smeću %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "PremjeÅ¡tanje u smeće na unutraÅ¡njim montiranjima sustava nije podržano" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Nemoguć pronalazak ili stvaranje direktorija smeća %s u smeću %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Nemoguće stvaranje datoteke informacija premjeÅ¡tanja u smeće za %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Nemoguće premjeÅ¡tanje datoteke %s u smeće izvan granica datoteÄnog sustava" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Nemoguće premjeÅ¡tanje datoteke %s: %s u smeće" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Nemoguće premjeÅ¡tanje datoteke %s u smeće" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "GreÅ¡ka stvaranja direktorija %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "DatoteÄni sustav ne podržava simboliÄke poveznice" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "GreÅ¡ka stvaranja simboliÄke poveznice %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "GreÅ¡ka premjeÅ¡tanja datoteke %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Nemoguće je premjeÅ¡tanje direktorija preko direktorija" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Neuspjelo stvaranje datoteke sigurnosne kopije" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "GreÅ¡ka uklanjanja odrediÅ¡ne datoteke: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "PremjeÅ¡tanje izmeÄ‘u montiranja nije podržano" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Nemoguće odreÄ‘ivanje upotrebe diska za %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Vrijednost svojstva ne smije biti nula" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Nevaljana vrsta svojstva (oÄekivan je izraz)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nevaljani naziv proÅ¡irenog svojstva" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "GreÅ¡ka postavljanja proÅ¡irenog svojstva “%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (neispravno kôdiranje)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "GreÅ¡ka dobivanja informacija za datoteku “%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "GreÅ¡ka dobivanja informacija za opisnik datoteke: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Neispravna vrsta svojstva (uint32 je oÄekivano)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Neispravna vrsta svojstva (uint64 je oÄekivano)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Neispravna vrsta svojstva (izraz u bajtima je oÄekivan)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Nemoguće postavljanje dozvole za simboliÄke poveznice" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "GreÅ¡ka postavljanja dozvola: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "GreÅ¡ka postavljanja vlasnika: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "simboliÄka poveznice ne može biti nula" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "GreÅ¡ka postavljanja simboliÄke poveznice: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"GreÅ¡ka postavljanja simboliÄke poveznice: datoteka nije simboliÄka poveznica" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Dodatne nanosekunde %d za UNIX vremensku oznaku %lld su negativne" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Dodatne nanosekunde %d za UNIX vremensku oznaku %lld su dosegle 1 sekundu" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX vremenska oznaka %lld ne pristaje u 64 bita" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"UNIX vremenska oznaka %lld je izvan raspona podržanim od strane Windowsa" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Naziv datoteke “%s†ne može biti pretvoren u UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Datoteka “%s†se ne može otvoriti: Windows greÅ¡ka %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"GreÅ¡ka postavljanja promjene ili vremena pristupa za datoteku “%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "GreÅ¡ka postavljanja promjene ili vremena pristupa: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux sadržaj ne smije biti nula" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nije omogućen na ovom sustavu" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "GreÅ¡ka postavljanja SELinux sadržaja: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Postavljanje svojstva %s nije podržano" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "GreÅ¡ka Äitanja iz datoteke:%s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "GreÅ¡ka zatvaranja datoteke: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "GreÅ¡ka premotavanja u datoteci: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Nemoguć pronalazak zadane lokalne datoteke vrste monitora" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "GreÅ¡ka zapisivanja datoteke: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "GreÅ¡ka uklanjanja poveznice stare sigurnosne kopije: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "GreÅ¡ka stvaranja kopije sigurnosnog kopiranja: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "GreÅ¡ka preimenovanja privremene datoteke: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "GreÅ¡ka skraćivanja datoteke: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "GreÅ¡ka otvaranja datoteke “%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "OdrediÅ¡na datoteka je direktorij" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "OdrediÅ¡na datoteka nije obiÄna datoteka" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Datoteka je promijenjena izvana" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "GreÅ¡ka uklanjanja stare datoteke: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Nevaljana GSeekType je pružana" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Neispravan zahtjev premotavanja" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Nemoguće je skratiti GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Memoriji izlaznog strujanja ne može se mijenjati veliÄina" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Nemoguća promjena veliÄine memorije izlaznog strujanja" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"KoliÄina memorije potrebna za obradu zapisa većeg od dostupnog adresiranog " +"prostora" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Zatraženo premotavanje prije poÄetka strujanja" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Zatraženo premotavanje izvan zavrÅ¡etka strujanja" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "montiranje nema implementirano “unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "montiranje nema implementirano “ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "montiranje nema implementirano “unmount†ili “unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "montiranje nema implementirano “eject†ili “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "montiranje nema implementirano “remountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "montiranje nema implementirano pogaÄ‘anje vrste sadržaja" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "montiranje nema implementirano sinkrono pogaÄ‘anje vrste sadržaja" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Naziv raÄunala “%s†sadrži “[†ali ne i “]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Mreža je nedostupna" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Poslužitelj je nedostupan" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Nemoguće stvaranje nadgledanja mreže: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Nemoguće stvaranje nadgledanja mreže: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Nemoguće dobivanje stanja mreže: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "Mrežni upravitelj nije pokrenut" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "InaÄica Mrežnog upravitelja je prestara" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Izlazno strujanje nema implementirano zapisivanje" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Zbroj vektora proslijeÄ‘enih u %s je prevelik" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Izvor strujanja je već zatvoren" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "GreÅ¡ka razrjeÅ¡avanja “%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s nije impelmentiran" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Neispravna domena" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Resurs na “%s†ne postoji" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Resurs na “%s†se nije uspio raspakirati" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Resurs na “%s†nije direktorij" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Ulazno strujanje nema implementirano premotavanje" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Prikaži odjeljke koji sadrže resurse u elf DATOTECI" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Prikaži resurse\n" +"Ako je ODJELJAK zadan, samo prikaži resurse u ovom odjeljku\n" +"Ako je PUTANJA zadana, samo prikaži podudarajuće resurse" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "DATOTEKA [PUTANJA]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "ODJELJAK" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Prikaži resurse s pojedinostima\n" +"Ako je ODJELJAK zadan, samo prikaži resurse u ovom odjeljku\n" +"Ako je PUTANJA zadana, samo prikaži podudarajuće resurse\n" +"Pojedinosti ukljuÄuju odjeljak, veliÄinu i sažimanje" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Raspakiraj datoteku resursa u stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "PUTANJA DATOTEKE" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Upotreba:\n" +" gresource [--section ODJELJAK] NAREDBA [ARGUMENTI…]\n" +"\n" +"Commands:\n" +" help Prikaži ove informacije\n" +" sections Prikaži odjeljke resursa\n" +" list Prikaži resurse\n" +" details Prikaži resurse s pojedinostima\n" +" extract Raspakiraj resurs\n" +"\n" +"Koristite “gresource help NAREDBU†za dobivanje opÅ¡irnije pomoći.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Upotreba:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " ODJELJAK (Neobavezni) elf naziv odjeljka\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " Naredba (Neobavezna) naredba objaÅ¡njenja\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " DATOTEKA elf datoteka (binarna ili dijeljena biblioteka)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" DATOTEKA elf datoteka (binarna ili dijeljena biblioteka)\n" +" ili kompilirana datoteka resursa\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[PUTANJA]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PUTANJA (Neobavezna) putanja resursa (može biti djelomiÄna)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "PUTANJA" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " PUTANJA Putanja resursa\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Nema takve sheme “%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Shema “%s†se ne može premjeÅ¡tati (putanja ne smije biti navedena)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Shema “%s†se može premjeÅ¡tati (putanja mora biti navedena)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Navedena je prazna putanja.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Putanja mora zapoÄet s kosom crtom (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Putanja mora zavrÅ¡avati s kosom crtom (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Putanja ne smije sadržavati dvije uzastopne kose crte (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Navedene vrijednosti su izvan valjanog raspona\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "KljuÄ nije zapisiv\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Prikaži instalirane (nepremjestive) sheme" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Prikaži instalirane premjestive sheme" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Prikaži kljuÄeve U SHEMI" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SHEMA[:PUTANJA]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Prikaži podsadržaj SHEME" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Prikaži kljuÄeve i vrijednosti, rekruzivno\n" +"Ako nema zadane SHEME, prikaži sve kljuÄeve\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SHEMA[:PUTANJA]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Nabavi vrijednost KLJUÄŒA" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SHEMA[:PUTANJA] KLJUÄŒ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Upitaj za raspon valjanih vrijednosti KLJUÄŒA" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Upitaj za opis KLJUÄŒA" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Postavi vrijednost KLJUÄŒA u VRIJEDNOST" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SHEMA[:PUTANJA] VRIJEDNOST KLJUÄŒA" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Vrati KLJUÄŒ na njegovu zadanu vrijednost" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Vrati sve kljuÄeve u SHEMI na njihove zadane vrijednosti" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Provjeri je li KLJUÄŒ zapisiv" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Nadgledaj KLJUÄŒ za promjene.\n" +"Ako KLJUÄŒ nije naveden, nadgledaj sve kljuÄeve u SHEMI.\n" +"Koristite ^C za zaustavljanje nadgledanja.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SHEMA[:PUTANJA] [KLJUÄŒ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Upotreba:\n" +" gsettings --version\n" +" gsettings [--schemadir DIREKTORIJ SHEME] NAREDBA [ARGUMENTI…]\n" +"\n" +"Naredbe:\n" +" help Prikaži ove informacije\n" +" list-schemas Prikaži instalirane sheme\n" +" list-relocatable-schemas Prikaži premjestive sheme\n" +" list-keys Prikaži kljuÄeve u shemi\n" +" list-children Prikaži podsadržaj scheme\n" +" list-recursively Prikaži kljuÄeve i vrijednosti, rekruzivno\n" +" range Upitaj za raspon kljuÄa\n" +" describe Upitaj za opis kljuÄa\n" +" get Nabavi vrijednost kljuÄa\n" +" set Postavi vrijednost kljuÄa\n" +" reset Vrati izvornu vrijednost kljuÄa\n" +" reset-recursively Vrati izvorne sve vrijednosti u zadanoj shemi\n" +" writable Provjeri je li kljuÄ zapisiv\n" +" monitor Nadgledaj promjene\n" +"\n" +"Koristite “gsettings help NAREDBA†za opÅ¡irniju pomoć.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Upotreba:\n" +" gsettings [--schemadir DIREKTORIJ SHEME] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " DIREKTORIJ SHEME Direktorij za pretragu dodatnih shema\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SHEMA Naziv sheme\n" +" PUTANJA Putanja, za premjestive sheme\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KLJUÄŒ (Neobavezno) kljuÄ sadržan unutar sheme\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KLJUÄŒ KljuÄ sadržan unutar sheme\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VRIJEDNOST Vrijednost za postaviti\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Nemoguće uÄitavanje sheme iz %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nema instaliranih shema\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Zadan je prazan naziv sheme\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Nema takvog kljuÄa “%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Nevaljana prikljuÄnica, nije pokrenuto" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Nevaljana prikljuÄnica, neuspjelo pokretanje zbog: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "PrikljuÄnica je već zatvorena" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Istek vremena U/I prikljuÄnice" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "stvaranje GSocketa iz fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Nemoguće stvaranje prikljuÄnice: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Navedena je nepoznata obitelj" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Naveden je nepoznat protokol" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Nemoguće koriÅ¡tenje datagram radnji na ne-datagram prikljuÄnici." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Nemoguće koriÅ¡tenje datagram radnji na prikljuÄnici s postavljenim istekom " +"vremena." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "nemoguće dobivanje lokalne adrese: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "nemoguće dobivanje udaljene adrese: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "nemoguće osluÅ¡kivanje: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "GreÅ¡ka povezivanja s adresom %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "GreÅ¡ka pridruživanja multicast grupi: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "GreÅ¡ka napuÅ¡tanja multicast grupe: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Nema podrÅ¡ke za izvorom-odreÄ‘eni multicast" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Nepodržana obitelj prikljuÄnice" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "izvorom-odreÄ‘eno nije IPv4 adresa" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Naziv suÄelja je predugaÄak" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "SuÄelje nije pronaÄ‘eno: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Nema podrÅ¡ke za IPv4 izvorom-odreÄ‘eni multicast" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Nema podrÅ¡ke za IPv6 izvorom-odreÄ‘eni multicast" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "GreÅ¡ka prihvaćanja povezivanja: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Povezivanje u tijeku" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Nemoguće dobivanje greÅ¡ke Äekanja: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "GreÅ¡ka primanja podataka: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "GreÅ¡ka slanja podataka: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Nemoguće iskljuÄivanje prikljuÄnice: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "GreÅ¡ka zatvaranja prikljuÄnice: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ÄŒekanje stanja prikljuÄnice: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Nemoguće slanje poruke: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vektori poruke su preveliki" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "GreÅ¡ka slanja poruke: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage nije podržano na Windowsima" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "GreÅ¡ka primanja poruke: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Nemoguće Äitanje vjerodajnice prikljuÄnice: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials nije implemetirano za ovaj OS" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Nemoguće povezivanje sa proxy poslužiteljem %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Nemoguće povezivanje sa %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Nemoguće povezivanje: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Proxyiranje putem ne-TCP povezivanja nije podržano." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proxy protokol “%s†joÅ¡ nije podržan." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "SluÅ¡atelj je već zatvoren" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Dodana prikljuÄnica je zatvorena" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 ne podržava IPv6 adresu “%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "KorisniÄko ime je predugaÄko za SOCKSv4 protokol" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Naziv raÄunala “%s†je predugaÄak za SOCKSv4 protokol" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Poslužitelj nije SOCKSv4 proxy poslužitelj." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Povezivanje putem SOCKSv4 poslužitelja je odbijeno" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Poslužitelj nije SOCKSv5 proxy poslužitelj." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 proxy zahtijeva ovjeru." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 proxy zahtijeva naÄin ovjere koji nije podržan od GLib strane." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "KorisniÄko ime ili lozinka su predugaÄki za SOCKSv5 protokol." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5 ovjera je neuspjela zbog netoÄnog korisniÄkog imena ili lozinke." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Naziv raÄunala “%s†je predugaÄak za SOCKSv5 protokol" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 proxy poslužitelj koristi nepoznatu vrstu adrese." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "UnutraÅ¡nja greÅ¡ka SOCKSv5 proxy poslužitelja." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 povezivanje nije dopuÅ¡teno postavljenim pravilima." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Poslužitelj je nedostupsn putem SOCKSv5 poslužitelja." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Mreža je nedostupna putem SOCKSv5 proxya." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Povezivanje je odbijeno putem SOCKSv5 proxya." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 proxy ne podržava “connect†naredbu." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 proxy ne podržava navedenu vrstu adrese." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Nepoznata SOCKSv5 proxy greÅ¡ka." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Neuspjelo stvaranje slivnika za komunikaciju s podreÄ‘enim procesom (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Slivnici nisu podržani na ovoj platformi" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Nemoguće rukovanje %d inaÄicom GThemedIcon kôdiranja" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Nema pronaÄ‘enih valjanih adresa" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "GreÅ¡ka obrnutog razrjeÅ¡avanja “%sâ€: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "GreÅ¡ka obrade DNS %s zapisa: oÅ¡tećen DNS paket" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Nema DNS zapisa zahtijevane vrste za “%sâ€" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Privremeno nedostupno za razrjeÅ¡avanje “%sâ€" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "GreÅ¡ka razrjeÅ¡avanja “%sâ€" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "OÅ¡tećen DNS paket" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Neuspjela obrada DNS odgovora za “%sâ€: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Nema pronaÄ‘enog PEM-kôdiranog privatnog kljuÄa" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Nemoguće deÅ¡ifriranje PEM-kôdiranog privatnog kljuÄa" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Nemoguća obrada PEM-kôdiranog privatnog kljuÄa" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Nema pronaÄ‘ene PEM-kôdirane vjerodajnice" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Nemoguća obrada PEM-kôdirane vjerodajnice" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Trenutni TLS pozadinski program ne podržava PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "GTlsBackend ne podržava stvaranje PKCS #11 vjerodajnica" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ovo je posljednja Å¡ansa za ispravno upisivanje lozinke prije nego Å¡to se vaÅ¡ " +"pristup zakljuÄa." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Nekoliko lozinki je neispravno upisano i vaÅ¡ pristup će se zakljuÄati nakon " +"budućih neuspjelih upisa." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Upisana lozinka je neispravna." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "FD slanje nije podržano" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "OÄekivana je 1 kontrolna poruka, dobivena je %d" +msgstr[1] "OÄekivana je 1 kontrolna poruka, dobivene su %d" +msgstr[2] "OÄekivana je 1 kontrolna poruka, dobiveno je %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "NeoÄekivana vrsta pomoćnih podataka" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "OÄekivan je jedan fd, ali dobiven je %d\n" +msgstr[1] "OÄekivan je jedan fd, ali dobivena su %d\n" +msgstr[2] "OÄekivan je jedan fd, ali dobiveno je %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Primljen je nevaljani fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "FD primanje nije podržano" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "GreÅ¡ka slanja vjerodajnica: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "GreÅ¡ka provjere je li SO_PASSCRED omogućen za prikljuÄnicu: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "GreÅ¡ka omgućavanja SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"OÄekivano Äitanje je jedan bajt primljenih vjerodajnica ali oÄitano je nula " +"bajta" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ne oÄekuje se kontrolna poruka, ali dobivena je %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "GreÅ¡ka onemogućavanja SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "GreÅ¡ka Äitanja iz opisnika datoteke: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "GreÅ¡ka zatvaranja opisnika datoteke: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Korijenski datoteÄni sustav" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "GreÅ¡ka zapisivanja u opisnik datoteke: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Sažeta UNIX domena prikljuÄnice adrese nije podržana na ovom sustavu" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "ureÄ‘aj nema implementirano izbacivanje" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "ureÄ‘aj nema implementirano izbacivanje ili izbacivanje_s_radnjom" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "GreÅ¡ka Äitanja iz rukovanja: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "GreÅ¡ka zatvaranja rukovanja: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "GreÅ¡ka zapisivanja u rukovanje: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nedovoljno memorije" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Unutarnja greÅ¡ka: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Treba viÅ¡e unosa" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Neispravno sažeti podaci" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresa za osluÅ¡kivanje" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Zanemareno, zbog kompatibilnosti sa GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Prikaži adresu" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Prikaži adresu u naÄnu rada ljuske" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Pokreni dbus uslugu" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "PogreÅ¡ni argumenti\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "NeoÄekivano svojstvo “%s†za element “%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Svojstvo “%s†od elementa “%s†nije pronaÄ‘eno" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "NeoÄekivana oznaka “%sâ€, oÄekivana je “%s†oznaka" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "NeoÄekivana oznaka “%s†unutar “%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Nevaljani datum/vrijeme ‘%s’ u datoteci zabiljeÅ¡ke" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Nema pronaÄ‘ene valjane datoteke zabiljeÅ¡ke u direktoriju podataka" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "ZabiljeÅ¡ka za URI “%s†već postoji" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nema pronaÄ‘ene zabiljeÅ¡ke za URI “%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Nema MIME vrste odreÄ‘ene u zabiljeÅ¡ki za URI “%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Nema odreÄ‘ene privatne oznake u zabiljeÅ¡ki za URI “%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Nema postavljenih grupa u zabiljeÅ¡ki za URI “%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Nema aplikacije naziva “%s†registrirane zabiljeÅ¡ke za “%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Neuspjelo proÅ¡irivanje redka izvrÅ¡avanja “%s†sa URI-jem “%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Nereprezentativni znak u ulazu pretvorbe" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "NedovrÅ¡eni niz znakova na kraju ulaza" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Nemoguća pretvorba zamjenskog \"%s\" u skup kôda \"%s\"" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "UgraÄ‘eni NULA bajt u ulazu pretvorbe" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "UgraÄ‘eni NULA bajt u izlazu pretvorbe" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI “%s†nije apsolutan URI pri koriÅ¡tenju “datoteka†sheme" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "URI “%s†lokalne datoteke možda ne ukljuÄuje “#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI “%s†je nevaljan" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Naziv raÄunala URI-ja “%s†je nevaljan" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI “%s†sadrži nevaljane escape znakove" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Naziv putanje “%s†nije apsolutna putanja" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y." + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%H:%M:%S" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "SijeÄanj" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "VeljaÄa" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Ožujak" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Travanj" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Svibanj" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Lipanj" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Srpanj" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Kolovoz" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Rujan" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Listopad" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Studeni" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Prosinac" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Sij" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Vel" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Ožu" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Tra" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Svi" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Lip" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Srp" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Kol" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Ruj" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Lis" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Stu" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Pro" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Ponedjeljak" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Utorak" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Srijeda" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ÄŒetvrtak" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Petak" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Subota" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Nedjelja" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Pon" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Uto" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Sri" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ÄŒet" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Pet" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sub" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Ned" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "sijeÄanj" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "veljaÄa" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "ožujak" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "travanj" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "svibanj" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "lipanj" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "srpanj" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "kolovoz" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "rujan" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "listopad" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "studeni" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "prosinac" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "sij" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "vel" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "ožu" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "tra" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "svi" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "lip" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "srp" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "kol" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "ruj" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "lis" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "stu" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "pro" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "GreÅ¡ka otvaranja direktorija “%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Nemoguće dodjeljivanje %lu bajta u datoteku Äitanja “%sâ€" +msgstr[1] "Nemoguće dodjeljivanje %lu bajta u datoteku Äitanja “%sâ€" +msgstr[2] "Nemoguće dodjeljivanje %lu bajta u datoteku Äitanja “%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "GreÅ¡ka Äitanja datoteke “%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Datoteka “%s†je prevelika" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Neuspjelo Äitanje iz datoteke “%sâ€: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Nemoguće otvaranje datoteke “%s“: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Neuspjelo dobivanje svojstva datoteke “%sâ€: fstat() neuspio: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Neuspjelo otvaranje datoteke “%sâ€: fdopen() neuspio: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Neuspjelo preimenovanje datoteke “%s†u “%sâ€: g_rename() neuspio: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Neuspjelo zapisivanje datoteke “%sâ€: write() neuspio: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Neuspjelo zapisivanje datoteke “%sâ€: fsync() neuspio: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Neuspjelo stvaranje datoteke \"%s\": %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Postojeća datoteka “%s†se ne može ukloniti: g_unlink() neuspio: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Predložak “%s†je nevaljan, ne smije sadržavati “%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Predložak “%s†ne sadrži XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Neuspjelo Äitanje simboliÄke poveznice “%sâ€: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Neuspjelo otvaranje pretvornika iz “%s†u “%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Neuspjelo neobraÄ‘eno Äitanje u g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Postoji ostatak nepretvorenih podataka u meÄ‘uspremniku Äitanja" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanal zavrÅ¡ava sa nedovrÅ¡enim znakom" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Neuspjelo neobraÄ‘eno Äitanje u g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Valjana datoteka kljuÄa se ne može pronaći u direktorijima pretrage" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Nije uobiÄajena datoteka" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Datoteka kljuÄa sadrži redak “%s†koji nije par kljuÄ-vrijednost, grupa ili " +"komentar" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nevaljani naziv grupe: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Datoteka kljuÄa ne zapoÄinje s grupom" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nevaljani naziv kljuÄa: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Datoteka kljuÄa sadrži nepodržano kôdiranje “%sâ€" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Datoteka kljuÄa nema grupe “%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Datoteka kljuÄa nema kljuÄ â€œ%s†u grupi “%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Datoteka kljuÄa sadrži kljuÄ â€œ%s†s vrijednošću “%s†koja nije UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Datoteka kljuÄa sadrži kljuÄ â€œ%s†s vrijednošću koja se ne može " +"interperetirati." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Datoteka kljuÄa sadrži kljuÄ â€œ%s†u grupi “%s†s vrijednošću koja se ne može " +"interperetirati." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "KljuÄ â€œ%s†u grupi “%s†ima vrijednost “%s†gdje je %s oÄekivan" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Datoteka kljuÄa sadrži escape znak na kraju redka" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Datoteka kljuÄa sadrži nevaljani escape niz “%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Vrijednost “%s†se ne može tumaÄiti kao broj." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Cjelobrojna vrijednost \"%s\" je izvan raspona" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Vrijednost \"%s\" ne može se tumaÄiti kao decimalni broj." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Vrijednost \"%s\" ne može se tumaÄiti kao bool varijable." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Neuspjelo dobivanje svojstava datoteke “%s%s%s%sâ€: fstat() neuspio: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Neuspjelo mapiranje %s%s%s%s: mmap() neuspio: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Neuspjelo otvaranje “%sâ€: open() neuspio: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "GreÅ¡ka u retku %d znak %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Nevaljani UTF-8 kôdirani tekst u nazivu — nije valjan “%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†nije valjani naziv" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†nije valjani naziv: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "GreÅ¡ka u retku %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Neuspjela obrada “%-.*sâ€, mora biti broj unutar reference znaka (ê na " +"primjer) — možda je broj prevelik" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Referenca znakova nije zavrÅ¡ila toÄka-zarezom; najvjerojatnije ste koristili " +"znak ampersand bez namjere pokretanja entiteta — escape ampersand kao &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Referenca znakova “%-.*s†ne kôdira dopuÅ¡teni znak" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Prazan entitet “&;†viÄ‘en; valjani entiteti su: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Naziv entiteta “%-.*s†nije poznat" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entitet nije zavrÅ¡io toÄka-zarezom; najvjerojatnije ste koristili znak " +"ampersand bez namjere pokretanja entiteta — escape ampersand kao &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument mora zapoÄinjati elementom (npr. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%s†nije valjan znak nakon “<†znaka; možda ne zapoÄinje s nazivom elementa" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Neparan znak “%sâ€, oÄekivan je “>†znak na kraju empty-element oznake “%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "PreviÅ¡e svojstava u elementu “%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Neparan znak “%sâ€, oÄekivan je “=†nakon naziva svojstva “%s†elementa “%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Neparan znak “%sâ€, oÄekivan je “>†ili “/†znak na kraju poÄetka oznake " +"elementa “%sâ€, ili neobaveznog svojstva; možda ste koristili nevaljani znak " +"u nazivu svojstva" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Neparni znak \"%s\", oÄekivan je otvoreni navodnik nakon znaka jednakosti " +"pri davanju vrijednosti za svojstvo \"%s\" elementa \"%s\"" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%s†nije valjan znak nakon najbližeg naziva elementa “%sâ€; dopuÅ¡teni znak " +"je “>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Element “%s†je zatvoren, trenutno nema otvorenih elemenata" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Element “%s†je zatvoren, ali trenutno otvoreni element je “%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument je bio prazan ili je sadržavao samo razmake" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokument je neoÄekivano zavrÅ¡io nakon otvorene kutne zagrade “<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokument je neoÄekivano zavrÅ¡io s joÅ¡ otvorenim elementima — “%s†je " +"posljednji otvoreni element" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokument je neoÄekivano zavrÅ¡io, oÄekivana je zatvorena kutna zagrada na " +"zavrÅ¡etku oznake <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokument je neoÄekivano zavrÅ¡io unutar naziva elementa" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokument je neoÄekivano zavrÅ¡io unutar naziva svojstva" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokument je neoÄekivano zavrÅ¡io unutar element-opening oznake." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokument je neoÄekivano zavrÅ¡io nakon Å¡to je znak jednakosti iza naziva " +"svojstva; nema vrijednosti svojstva" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokument je neoÄekivano zavrÅ¡io unutar vrijednosti svojstva" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokument je neoÄekivano zavrÅ¡io unutar zavrÅ¡ne oznake za element “%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Dokument je neoÄekivano zavrÅ¡io unutar zavrÅ¡ne oznake za neotvoreni element" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokument je neoÄekivano zavrÅ¡io unutar komentara ili procesne naredbe" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[MOGUĆNOST…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Mogućnosti pomoći:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Prikaži mogućnosti pomoći" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Prikaži sve mogućnosti pomoći" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Mogućnosti aplikacije:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Mogućnosti:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Nemoguća obrada cjelobrojne vrijednosti “%s†za %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Cjelobrojna vrijednost “%s†za %s je izvan raspona" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Nemoguća obrada dvostruke vrijednosti “%s†za %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Dvostruka vrijednost “%s†za %s je izvan raspona" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "GreÅ¡ka obrade mogućnosti %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Nedostaje parametar za %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Nepoznata mogućnost %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "oÅ¡tećeni objekt" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "unutarnja greÅ¡ka ili oÅ¡tećeni objekt" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "ponestalo memorije" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "dosegnuto ograniÄenje vraćanja" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "uzorak sadržava stavke koje nisu podržane za djelomiÄno podudaranje" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "unutarnja greÅ¡ka" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "povratne reference kao uvjeti nisu podržane za djelomiÄno podudaranje" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "dostignuta je ograniÄenje rekurzije" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "nevaljana kombinacija oznaka novog redka" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "loÅ¡ pomak" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "kratak utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "petlja rekurzije" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "nepoznata greÅ¡ka" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ na kraju uzorka" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c na kraju uzorka" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "neprepoznati znak nakon \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "brojevi izvan poredka u {} kvantifikatoru" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "prevelik broj u {} kvantifikatoru" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "nedostaje zavrÅ¡etak ] za klasu znakova" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "nevaljani escape nakon klase znaka" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "raspon izvan poredka u klasi znakova" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "niÅ¡ta za ponavljanje" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "neoÄekivano ponavljanje" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "neprepoznati znak nakon (? ili (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX nazvane klase podržane su samo unutar klase" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "nedostaje zavrÅ¡etak )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referenca na nepostojeći poduzorak" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "nedostaje ) nakon komentara" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "uobiÄajen izraz je prevelik" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "neuspjelo dobivanje memorije" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") bez otvaranja (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "prekoraÄenje kôda" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "neprepoznati znak nakon (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind navod nije nepromjenjive duljine" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "oÅ¡tećeni broj ili naziv nakon (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "uvjetovana grupa sadrži viÅ¡e od dva ogranka" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "navod se oÄekuje nakon (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ili (?[+-]znamenka mora biti nakon )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nepoznat POSIX naziva klase" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX elementi razvrstavanja nisu podržani" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "vrijednost znaka u \\x{...} slijedu je prevelika" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "nevaljani uvjet (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C nije dopuÅ¡ten u lookbehind navodu" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{naziv}, \\U, i \\u nisu podržani" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "rekruzivni poziv bi se mogao neograniÄeno ponavljati" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "neprepoznati znak nakon (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "nedostaje zavrÅ¡etak u nazivu poduzorka" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dva imenovana poduzorka imaju isti naziv" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "oÅ¡tećni \\P ili \\p slijed" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nepoznat naziv svojstva nakon \\P ili \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "naziv poduzorka je predugaÄak (najviÅ¡e 32 znaka)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "previÅ¡e imenovanih poduzorka (najviÅ¡e 10,000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "oktalana vrijednost je veća od \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "prekoraćenje sastavljanja radnog prostora" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "prije provjereni referentni poduzorak nije pronaÄ‘en" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE grupa sadrži viÅ¡e od jednog ogranka" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "nedosljedna NEWLINE mogućnost" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ne zavrÅ¡ava sa zagradom, kutnom zagradom, ili citiranim nazivom ili " +"brojem, ili obiÄnim brojem" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "brojÄana referenca ne može biti nula" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "argument nije dopuÅ¡ten za (*ACCEPT), (*FAIL), ili (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) nije prepoznat" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "broj je prevelik" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "nedostaje naziv poduzorka nakon (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "oÄekuje se znamenka nakon (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] je nevaljani znak podatka u JavaScript naÄinu kompatibilnosti" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "razliÄiti nazivi za poduzorke istog broja nisu dopuÅ¡teni" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) mora sadržavati argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c mora slijediti ASCII znak" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k ne mora slijediti zagrade, kutne zagrade ili citirani naziv" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N nije podržan u klasi" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "previÅ¡e proslijeÄ‘enih referenci" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "naziv je predugaÄak u (*MARK), (*PRUNE), (*SKIP), ili (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "vrijednost znaka u \\u.... slijedu je prevelika" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "GreÅ¡ka usporedbe obiÄnog izraza %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE biblioteka je kompilirana bez UTF8 podrÅ¡ke" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE biblioteka je kompilirana bez podrÅ¡ke UTF8 svojstava" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE biblioteka je kompilirana s nekompatibilnom mogućnosti" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "GreÅ¡ka optimizacije obiÄnog izraza %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "GreÅ¡ka kompiliranja obiÄnog izraza %s pri znaku %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "heksadecimalna znamenka ili “}†je oÄekivano" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "heksadecimalna znamenka je oÄekivana" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "nedostaje “<†u simboliÄkoj referenci" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "nedovrÅ¡ena simboliÄka referenca" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "simboliÄka referenca nulte duljine" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "oÄekivana je znamenka" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "nevažeća simboliÄka referenca" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "zavrÅ¡no zalutali “\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "nepoznati escape slijed" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "GreÅ¡ka obrade zamjenskog teksta “%s†pri znaku %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Citirani tekst ne poÄinje sa navodnikom" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Navodnik nije uparen u naredbenom redku ili drugom tekstu ljuske" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Tekst je zavrÅ¡io nakon “\\†znaka (Tekst je bio “%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Tekst je zavrÅ¡io prije nego Å¡to je pronaÄ‘en zavrÅ¡ni navodnik %c. (Tekst je " +"bio “%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Tekst je bio prazan (ili je sadržavao samo razmake)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Neuspjelo Äitanje podataka iz podreÄ‘enog procesa (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "NeoÄekivana greÅ¡ka u Äitanju podataka podreÄ‘enog procesa (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NeoÄekivana greÅ¡ka u waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "PodreÄ‘eni proces se zatvorio s kôdom %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "PodreÄ‘eni proces je ubio signal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "PodreÄ‘eni proces je zaustavio signal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "PodreÄ‘eni proces se zatvorio abnormalno" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Neuspjelo Äitanje iz podreÄ‘enog slivnika (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Neuspjelo pokretanje podreÄ‘enog procesa “%s†(%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Neuspjelo grananje (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Neuspjela promjena direktorija “%s†(%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Neuspjelo pokretanje podreÄ‘enog procesa “%s†(%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" +"Neuspjelo otvaranje datoteke za ponovno mapiranje opisnika datoteke (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Neuspjelo udvostruÄavanje opisnika datoteke za podreÄ‘eni proces (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Neuspjelo grananje podreÄ‘enog procesa (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Neuspjelo zatvaranje opisnika datoteke za podreÄ‘eni proces (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Nepoznata greÅ¡ka pokretanja podreÄ‘enog procesa “%sâ€" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Neuspjelo Äitanje dovoljno podataka iz id procesa podreÄ‘enog slivnika (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Neuspjelo Äitanje podataka iz podreÄ‘enog procesa" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Neuspjelo pokretanje podreÄ‘enog procesa (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Neuspio dup() u podreÄ‘enom procesu (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nevaljani naziv programa: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Nevaljan niz znakova u vektoru argumenta na %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Nevaljan niz znakova u okružju: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Nevaljan radni direktorij: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Neuspjelo pokretanje programa pomoći (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"NeoÄekivana greÅ¡ka u g_io_channel_win32_poll() Äitanju podataka podreÄ‘enog " +"procesa" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Prazan niz znakova nije broj" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†nije potpisani broj" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Broj “%s†je izvan granica [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†nije nepotpisani broj" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Nevaljano %-kôdiranje u URI-ju" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "NedopuÅ¡ten znak u URI-ju" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Ne-UTF-8 znak u URI-ju" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Nevaljana IPv6 adresa ‘%.*s’ u URI-ju" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Nevaljano kôdirana IP adresa ‘%.*s’ u URI-ju" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "NedopuÅ¡teni internacionalizirani naziv raÄunala ‘%.*s’ u URI-ju" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Nemoguća obrada ulaza ‘%.*s’ u URI-ju" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Ulaz ‘%.*s’ u URI-ju je izvan raspona" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI '%s' nije apsolutni URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI ‘%s’ nema komponentu poslužitelja" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI nije apsolutan, i nema navednog osnovnog URI-ja" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Nedostaje ‘=’ i vrijednost parametra" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Neuspjela preraspodjela memorije" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Znak je izvan raspona za UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Neispravan niz u ulazu pretvorbe" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Znak je izvan raspona za UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajt" +msgstr[1] "%u bajta" +msgstr[2] "%u bajtova" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bita" +msgstr[2] "%u bitova" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bajt" +msgstr[1] "%s bajta" +msgstr[2] "%s bajtova" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bita" +msgstr[2] "%s bitova" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 0000000..0e81243 --- /dev/null +++ b/po/hu.po @@ -0,0 +1,6348 @@ +# Hungarian translation for glib. +# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# +# Szabolcs Varga , 2005. +# Gabor Kelemen , 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017. +# Balázs Úr , 2013, 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022. +# Balázs Meskó , 2017, 2018, 2020, 2021. +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-08-29 08:50+0000\n" +"PO-Revision-Date: 2022-09-01 01:27+0200\n" +"Last-Translator: Balázs Úr \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 19.12.3\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Az alapértelmezett alkalmazások beállítása még nem támogatott" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Az alkalmazás legutóbb használtként beállítása egy adott típushoz még nem " +"támogatott" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication kapcsolói" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "A GApplication kapcsolóinak megjelenítése" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Belépés GApplication szolgáltatásmódba (használja D-Bus " +"szolgáltatásfájlokból)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Alkalmazások azonosítójának felülbírálása" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "A futó példány cseréje" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Súgó kiírása" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[PARANCS]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Verzió kiírása" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Verzióinformációk kiírása és kilépés" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Alkalmazások felsorolása" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"A telepített, (.desktop fájlok által) D-Bus-on aktiválható alkalmazások " +"felsorolása" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Alkalmazás indítása" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Az alkalmazás indítása (megnyitandó fájlokkal)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "ALKALMAZÃSAZONOSÃTÓ [FÃJL…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Egy művelet aktiválása" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Művelet meghívása az alkalmazáson" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ALKALMAZÃSAZONOSÃTÓ MŰVELET [PARAMÉTER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "ElérhetÅ‘ műveletek felsorolása" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Egy alkalmazás statikus műveleteinek felsorolása (.desktop fájlból)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ALKALMAZÃSAZONOSÃTÓ" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "PARANCS" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Részletes súgó kiírása ezen parancshoz" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Alkalmazásazonosító D-Bus formátumban (például: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FÃJL" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Megnyitandó, elhagyható relatív vagy abszolút fájlnevek, illetve URI-k" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "MŰVELET" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "A meghívandó művelet neve" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMÉTER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "A művelethívás elhagyható paramétere GVariant formátumban" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Ismeretlen parancs: %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Használat:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumentumok:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTUMOK…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Parancsok:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Részletes segítségért adja ki a „%s help PARANCS†parancsot.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s parancs után közvetlenül egy alkalmazásazonosító szükséges\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "érvénytelen alkalmazásazonosító: „%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"„%s†nem vár argumentumot\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "nem sikerült kapcsolódni a D-Bushoz: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "hiba %s üzenet küldésekor az alkalmazásnak: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "a műveletnevet meg kell adni az alkalmazásazonosító után\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"érvénytelen műveletnév: „%sâ€\n" +"a műveletnevek csak betűket, számokat, „-†és „.†karaktereket " +"tartalmazhatnak\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "hiba a műveletparaméter feldolgozásakor: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "a műveletek legfeljebb egy paramétert várnak\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "a list-actions parancs csak az alkalmazásazonosítót várja" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "nem található desktop fájl a(z) %s alkalmazáshoz\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"ismeretlen parancs: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Túl nagy számérték került átadásra ennek: %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Az alap adatfolyam nem támogatja a pozicionálást" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "A GBufferedInputStream nem csonkítható" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Az adatfolyam már le van zárva" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Az alap adatfolyam csonkítása nem engedélyezett" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "A művelet megszakítva" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Érvénytelen objektum, nincs elÅ‘készítve" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Érvénytelen több bájtos sorozat a bemenetben" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Nincs elég hely a célon" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Érvénytelen bájtsorrend az átalakítás bemenetében" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Hiba az átalakításkor: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "A megszakítható elÅ‘készítés nem támogatott" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "A(z) „%s†és „%s†karakterkészletek közötti átalakítás nem támogatott" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "" +"A(z) „%s†karakterkészletrÅ‘l „%s†karakterkészletre átalakító nem nyitható " +"meg" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s típus" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Ismeretlen típus" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s fájltípus" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "A GCredentials érvénytelen adatot tartalmaz" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "A GCredentials nincs megvalósítva ezen a rendszeren" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "A platformhoz nincs GCredentials támogatás" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "A GCredentials nem tartalmaz folyamatazonosítót ezen a rendszeren" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "A hitelesítési adatok hamisítása nincs megvalósítva ezen a rendszeren" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Váratlan korai adatfolyam vége" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nem támogatott „%s†kulcs a(z) „%s†címbejegyzésben" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Értelmetlen kulcs-érték pár kombináció a(z) „%s†címbejegyzésben" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"A(z) „%s†cím érvénytelen (csak az útvonal, könyvtár, tmp könyvtár vagy " +"absztrakt kulcsok egyike lehet)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Hiba a(z) „%s†címben – a(z) „%s†attribútum rosszul formázott" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Ismeretlen vagy nem támogatott szállítás („%sâ€) a címhez („%sâ€)" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "A(z) „%s†címelem nem tartalmaz kettÅ‘spontot (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Az átvitel neve a(z) „%s†címelemben nem lehet üres" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"%d. kulcs-érték pár: „%s†a(z) „%s†címelemben nem tartalmaz egyenlÅ‘ségjelet" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"%d. kulcs-érték pár: „%s†a(z) „%s†címelemben nem tartalmazhat üres kulcsot" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Hiba a(z) „%3$s†címelemben található a(z) %1$d. kulcs-érték párban lévÅ‘ " +"„%2$s†kulcs vagy érték értelmezésekor" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Hiba a(z) „%s†címben – a unix szállítás a „path†vagy „abstract†kulcsok " +"pontosan egyikének jelenlétét igényli" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Hiba a(z) „%s†címben – a host attribútum hiányzik vagy rosszul formázott" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Hiba a(z) „%s†címben – a port attribútum hiányzik vagy rosszul formázott" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Hiba a(z) „%s†címben – a noncefile attribútum hiányzik vagy rosszul " +"formázott" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Hiba az automatikus indításkor: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Hiba a(z) „%s†ideiglenes fájl megnyitásakor: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Hiba a(z) „%s†ideiglenes fájl olvasásakor: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Hiba a(z) „%s†ideiglenes fájl olvasásakor, a várt 16 bájt helyett %d " +"érkezett" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Hiba az ideiglenes fájl („%sâ€) tartalmának írásakor az adatfolyamba:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "A megadott cím üres" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Nem indítható üzenetbusz, ha az AT_SECURE be van állítva" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Nem indítható üzenetbusz gépazonosító nélkül: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Nem indítható automatikusan a D-Bus X11 $DISPLAY nélkül" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Hiba a(z) „%s†parancssor indításakor: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Nem határozható meg a munkamenetbusz címe (nincs megvalósítva erre az OS-re)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Nem határozható meg a busz címe a DBUS_STARTER_BUS_TYPE környezeti " +"változóból – ismeretlen „%s†érték" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Nem határozható meg a busz címe, mivel a DBUS_STARTER_BUS_TYPE környezeti " +"változó nincs beállítva" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Ismeretlen busztípus: %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "A tartalom váratlanul hiányzik a sor olvasásakor" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "A tartalom váratlanul hiányzik a sor (biztonságos) olvasásakor" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Minden elérhetÅ‘ hitelesítési mechanizmus kimerítve (próbálva: %s, elérhetÅ‘: " +"%s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" +"A felhasználói azonosítóknak ugyanannak kell lenniük a partnernél és a " +"kiszolgálónál" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" +"Megszakítva a GDBusAuthObserver::authorize-authenticated-peer használatával" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Hiba a(z) „%s†könyvtár információinak lekérésekor: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"A(z) „%s†könyvtár jogosultságai rosszul formázottak. A várt 0700 mód " +"helyett 0%o érkezett." + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Hiba a(z) %s könyvtár létrehozásakor: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "A művelet nem támogatott" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Hiba a(z) „%s†kulcstartó megnyitásakor olvasásra: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "A(z) „%2$s†kulcstartó „%3$s†tartalmú „%1$dâ€. sora rosszul formázott" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"A(z) „%2$s†kulcstartó „%3$s†tartalmú „%1$dâ€. sorának elsÅ‘ egysége rosszul " +"formázott" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"A(z) „%2$s†kulcstartó „%3$s†tartalmú „%1$dâ€. sorának második egysége " +"rosszul formázott" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Nem található %d azonosítójú süti a kulcstartóban itt: „%s â€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Hiba a(z) „%s†zárolási fájl létrehozásakor: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Hiba az elavult „%s†zárolásfájl törlésekor: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Hiba a (törölt) „%s†zárolási fájl lezárásakor: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Hiba a(z) „%s†zárolási fájl törlésekor: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Hiba a(z) „%s†kulcstartó írásra való megnyitásakor: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Ezen kívül a(z) „%s†zárolásának feloldása is meghiúsult: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "A kapcsolat le van zárva" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Az idÅ‘korlát elérve" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Nem támogatott jelzÅ‘k találhatók a kliensoldali kapcsolat létrehozásakor" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Nincs „org.freedesktop.DBus.Properties†interfész a(z) %s útvonalon lévÅ‘ " +"objektumon" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Nincs „%s†tulajdonság" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "A(z) „%s†tulajdonság nem olvasható" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "A(z) „%s†tulajdonság nem írható" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Hiba a(z) „%s†tulajdonság beállításakor: a várt „%s†típus helyett „%s†" +"érkezett" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Nincs ilyen interfész: „%sâ€" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Nincs „%s†interfész a(z) %s útvonalon lévÅ‘ objektumon" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Nincs „%s†metódus" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Az üzenet „%s†típusa nem felel meg a várt „%s†típusnak" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Már exportálva van egy objektum a(z) %s interfészhez itt: %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Nem sikerült lekérni a tulajdonságot: %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Nem sikerült beállítani a tulajdonságot: %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "A(z) „%s†metódus a(z) „%s†típust adta vissza a várt „%s†helyett" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "A(z) „%s†metódus nem létezik a(z) „%s†interfészen „%s†aláírással" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Egy részfa már exportálva van a következÅ‘höz: %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Az objektum nem létezik a(z) „%s†útvonalon" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "a típus érvénytelen" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL üzenet: a PATH vagy MEMBER fejlécmezÅ‘ hiányzik" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN üzenet: a REPLY_SERIAL fejlécmezÅ‘ hiányzik" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR üzenet: a REPLY_SERIAL vagy ERROR_NAME fejlécmezÅ‘ hiányzik" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL üzenet: a PATH, INTERFACE vagy MEMBER fejlécmezÅ‘ hiányzik" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL üzenet: a PATH fejlécmezÅ‘ a fenntartott /org/freedesktop/DBus/Local " +"értéket használja" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL üzenet: az INTERFACE fejlécmezÅ‘ a fenntartott value org.freedesktop." +"DBus.Local értéket használja" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Az olvasandó %lu bájt helyett csak %lu érkezett" +msgstr[1] "Az olvasandó %lu bájt helyett csak %lu érkezett" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "A(z) „%s†karakterlánc után várt NULL bájt helyett %d bájt található" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"A várt érvényes UTF-8 karakterlánc helyett érvénytelen bájtok találhatók " +"a(z) %d bájteltolásnál (a karakterlánc hossza: %d). Az érvényes UTF-8 " +"karakterlánc az adott pontig: „%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Az érték túl mélyen van egymásba ágyazva" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "A feldolgozott „%s†érték nem érvényes D-Bus objektumútvonal" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "A feldolgozott „%s†érték nem érvényes D-Bus aláírás" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"%u bájt hosszú tömb található. A maximális hossz 2<<26 bájt (64 MiB)." +msgstr[1] "" +"%u bájt hosszú tömb található. A maximális hossz 2<<26 bájt (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Egy „a%c†típusú tömb található, az elvárt hossz a(z) %u bájt többszöröse, " +"de %u bájt hosszú található" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Üres szerkezetek (rekordok) nem engedélyezettek a D-Buson" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "A változat feldolgozott „%s†értéke nem érvényes D-Bus aláírás" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Hiba a(z) „%s†típusú GVariant visszafejtésekor a D-Bus átviteli formátumból" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Érvénytelen bájtsorrend-érték. A várt 0x6c („lâ€) vagy 0x42 („Bâ€) helyett 0x" +"%02x érték található" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Érvénytelen fÅ‘ protokollverzió. A várt 1 helyett %d található" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Aláírásfejléc található, de nem aláírás típusú" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "Aláírásfejléc található „%s†aláírással, de az üzenettörzs üres" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "A feldolgozott „%s†érték nem érvényes D-Bus aláírás (a törzshöz)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Nincs aláírásfejléc az üzenetben, de az üzenettörzs %u bájt" +msgstr[1] "Nincs aláírásfejléc az üzenetben, de az üzenettörzs %u bájt" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Nem fejthetÅ‘ sorba az üzenet: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Hiba a(z) „%s†típusú GVariant sorbafejtésekor a D-Bus átviteli formátumba" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Az üzenetben található fájlleírók száma (%d) eltér a fejléc mezÅ‘tÅ‘l (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Az üzenet nem fejthetÅ‘ sorba: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Az üzenettörzs „%s†aláírással rendelkezik, de nincs aláírásfejléc" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Az üzenettörzs „%s†típusaláírással rendelkezik, de az aláírásfejlécben lévÅ‘ " +"aláírás: „%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Az üzenettörzs üres, de az aláírásfejlécben lévÅ‘ aláírás: „%sâ€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Hiba került visszaadásra a(z) „%s†típusú törzzsel" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Hiba került visszaadásra az üres törzzsel" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Az ablak bezárásához nyomjon le egy gombot)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "A munkamenet D-Bus nem fut, és az automatikus indítás sikertelen" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Nem kérhetÅ‘ le hardverprofil: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "A(z) %s vagy a(z) %s nem tölthetÅ‘ be: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Hiba a StartServiceByName hívásakor ehhez: %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Váratlan válasz (%d) a StartServiceByName(\"%s\") metódustól" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"A metódus nem hívható; a proxy a jól ismert %s névhez tartozik tulajdonos " +"nélkül, és a proxy a G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START jelzÅ‘vel készült" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Az absztrakt névtér nem támogatott" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Kiszolgáló létrehozásakor nem adható meg az ideiglenes fájl" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Hiba az ideiglenes fájl („%sâ€) írásakor: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "A(z) „%s†karakterlánc nem érvényes D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Nem figyelhetÅ‘ a nem támogatott „%s†szállítás" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Parancsok:\n" +" help Ezen súgó megjelenítése\n" +" introspect Betekintés távoli objektumba\n" +" monitor Távoli objektum figyelése\n" +" call Metódushívás távoli objektumon\n" +" emit Szignál kibocsátása\n" +"\n" +"Az egyes parancsok súgója a „%s PARANCS --help†kiadásával érhetÅ‘ el.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Hiba: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Hiba a betekintési XML feldolgozásakor: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Hiba: a(z) %s nem érvényes név\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Hiba: a(z) %s nem érvényes objektumútvonal\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Csatlakozás a rendszerbuszhoz" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Csatlakozás a munkamenetbuszhoz" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Csatlakozás a megadott D-Bus címhez" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Kapcsolatvégpont beállításai:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "A kapcsolat végpontját megadó beállítások" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nincs megadva kapcsolatvégpont" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Több kapcsolatvégpontot adott meg" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Figyelmeztetés: a betekintési adatok szerint a(z) „%s†interfész nem " +"létezik\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Figyelmeztetés: a betekintési adatok szerint a(z) „%2$s†interfészen nem " +"létezik „%1$s†metódus\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "A szignál elhagyható célja (egyedi név)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Szignál kibocsátása ezen az objektumútvonalon" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Szignál és interfész neve" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Szignál kibocsátása." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Hiba a csatlakozáskor: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Hiba: a(z) %s nem érvényes egyedi busznév.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Hiba: az objektumútvonal nincs megadva\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Hiba: a szignálnév nincs megadva\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Hiba: a szignálnév („%sâ€) érvénytelen\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Hiba: a(z) %s nem érvényes interfésznév\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Hiba: a(z) %s nem érvényes tagnév\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Hiba a(z) %d. paraméter feldolgozásakor: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Hiba a kapcsolat kiürítésekor: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "A cél neve a metódushíváshoz" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Objektum útvonala a metódushíváshoz" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Metódus és interfész neve" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "IdÅ‘korlát másodpercben" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Interaktív engedélyezés bekapcsolása" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Metódus hívása távoli objektumon." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Hiba: a cél nincs megadva\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Hiba: a(z) %s nem érvényes busznév\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Hiba: a metódusnév nincs megadva\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Hiba: a metódusnév („%sâ€) érvénytelen\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Hiba a(z) „%2$s†típusú %1$d. paraméter feldolgozásakor: %3$s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Hiba a(z) „%d†leíró hozzáadásakor: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "A cél neve a betekintéshez" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Az objektumútvonal a betekintéshez" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "XML kiírása" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Betekintés gyermekekbe" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Csak a tulajdonságok kiírása" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Betekintés távoli objektumba." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "MegfigyelendÅ‘ cél neve" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "MegfigyelendÅ‘ objektumútvonal" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Távoli objektum megfigyelése." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Hiba: nem figyelhetÅ‘ meg a nem üzenetbusz kapcsolat\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Az aktiválandó szolgáltatás, mielÅ‘tt a másikra várna (ismert név)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Az idÅ‘túllépés, mielÅ‘tt hibával kilépne (másodpercben); 0, ha nincs " +"idÅ‘túllépés (alapértelmezett)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[KAPCSOLÓ…] BUSZNÉV" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Várakozás egy busznévre." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Hiba: az objektumútvonal nincs megadva.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Hiba: az objektumútvonal nincs megadva.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Hiba: Túl sok argumentum.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Hiba: a(z) %s nem érvényes busznév\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Nincs felhatalmazva a hibakeresési beállítások megváltoztatására" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Névtelen" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "A desktop fájl nem adta meg az Exec mezÅ‘t" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Nem található az alkalmazáshoz szükséges terminál" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Nem hozható létre a(z) %s felhasználói alkalmazáskonfigurációs mappa: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Nem hozható létre a(z) %s felhasználói MIME konfigurációs mappa: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Az alkalmazásinformációkból hiányzik az azonosító" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Nem hozható létre a felhasználói desktop fájl (%s)" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "%s egyéni meghatározása" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "a meghajtó nem valósítja meg a kiadást" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" +"a meghajtó nem valósítja meg a kiadást vagy az eject_with_operation függvényt" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "a meghajtó nem valósítja meg a média lekérdezését" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "a meghajtó nem valósítja meg a indítást" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "a meghajtó nem valósítja meg a leállítást" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "A TLS háttérszolgáltatás nem valósítja meg a TLS kötéslekérdezést" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "A TLS-támogatás nem érhetÅ‘ el" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "A DTLS-támogatás nem érhetÅ‘ el" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "A GEmblem kódolás %d. verziója nem kezelhetÅ‘" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "A GEmblem kódolásban a jelsorok száma (%d) hibásan formált" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "A GEmblemedIcon kódolás %d. verziója nem kezelhetÅ‘" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "A GEmblemedIcon kódolásban a jelsorok száma (%d) hibásan formált" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Egy GEmblem kellene a GEmblemedIconhoz" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "A tartalmazó csatolás nem létezik" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Nem lehet a könyvtárra másolni" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "A könyvtár nem másolható könyvtárba" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "A célfájl létezik" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "A könyvtár nem másolható rekurzívan" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "A fájlillesztés nem támogatott" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Hiba a fájl illesztésekor: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "A csatolások közti másolás (reflink/clone) nem támogatott" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "A másolás (reflink/clone) nem támogatott vagy érvénytelen" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "A másolás (reflink/clone) nem támogatott vagy nem működött" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "A speciális fájl nem másolható" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Érvénytelen szimbolikus link érték került megadásra" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "A szimbolikus linkek használata nem támogatott" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "A Kuka nem támogatott" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "A fájlnevek nem tartalmazhatnak „%c†karaktert" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "a kötet nem valósítja meg a csatolást" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Nincs alkalmazás regisztrálva a fájl kezeléséhez" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Az enumerátor le van zárva" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "A fájlenumerátor hátralévÅ‘ művelettel rendelkezik" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "A fájlenumerátor már le van zárva" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "A GFileIcon kódolás %d. verziója nem kezelhetÅ‘" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "A GFileIcon bemeneti adatai rosszul formáltak" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Az adatfolyam nem támogatja a query_info-t" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Az adatfolyam nem támogatja a pozicionálást" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "A bemeneti adatfolyam csonkítása nem engedélyezett" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Az adatfolyam csonkítása nem engedélyezett" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Érvénytelen gépnév" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Rossz HTTP proxy válasz" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "A HTTP proxykapcsolat nem engedélyezett" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "A HTTP proxyhitelesítés meghiúsult" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP proxyhitelesítés szükséges" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "A HTTP proxykapcsolat meghiúsult: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "A HTTP proxy válasza túl nagy" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "A HTTP proxykiszolgáló váratlanul lezárta a kapcsolatot." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "A jelsorok száma hibás (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Nincs típus az osztálynévhez: %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "A(z) %s típus nem valósítja meg a GIcon interfészt" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "A típus (%s) nem tartalmaz osztályokat" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Rosszul formált verziószám: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" +"A(z) %s típus nem valósítja meg a from_tokens() függvényt a GIcon interfészen" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Az ikonkódolás megadott verziója nem kezelhetÅ‘" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nincs megadva cím" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "A(z) %u cím túl rövid a címhez" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "A címben az elÅ‘tag hosszán túl is be vannak állítva bitek" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Nem dolgozható fel a(z) „%s†IP-cím maszkként" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Nincs elég hely a foglalat címének" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nem támogatott foglalatcím" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "A bemeneti adatfolyam nem valósítja meg az olvasást" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Az adatfolyam hátralévÅ‘ művelettel rendelkezik" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Másolás fájllal" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Megtartás a fájllal áthelyezéskor" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "a „version†nem vár argumentumot" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Használat:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Verziószám kiírása és kilépés." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Parancsok:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Fájlok összefűzése a szabványos kimenetre" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Fájlok másolása" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Információk megjelenítése helyekrÅ‘l" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Alkalmazás indítása egy desktop fájlból" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "A helyek tartalmának felsorolása" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "A MIME-típus kezelÅ‘jének lekérése vagy beállítása" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Könyvtárak létrehozása" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Fájlok és könyvtárak változásainak figyelése" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "A helyek csatolása vagy leválasztása" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Fájlok áthelyezése" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Fájlok megnyitása az alapértelmezett alkalmazással" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Fájl átnevezése" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Fájlok törlése" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Szabványos bemenet olvasása és mentése" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Egy fájlattribútum beállítása" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Fájlok vagy könyvtárak áthelyezése a Kukába" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "A helyek tartalmának felsorolása egy fában" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Részletes segítségért adja ki a %s parancsot.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Hiba a szabványos kimenetre íráskor" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:91 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "HELY" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Fájlok összefűzése és kiírása a szabványos kimenetre." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"A gio cat a hagyományos cat segédprogramhoz hasonlóan működik, de helyi\n" +"fájlok helyett GIO helyeket használ: megadható például helyként az\n" +"smb://kiszolgáló/erÅ‘forrás/fájl.txt." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nincsenek megadva helyek" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nincs célkönyvtár" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Folyamat megjelenítése" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Kérdés felülírás elÅ‘tt" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Minden attribútum megÅ‘rzése" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "MeglévÅ‘ célfájlok biztonsági mentése" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Soha ne kövesse a szimbolikus linkeket" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Alapértelmezett jogosultságok használata a célnál" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%s / %s átvitele kész (%s/mp)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "FORRÃS" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "CÉL" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Fájlok áthelyezése a FORRÃSBÓL a CÉLBA." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"A gio copy a hagyományos cp segédprogramhoz hasonlóan működik, de helyi\n" +"fájlok helyett GIO helyeket használ: megadható például helyként az\n" +"smb://kiszolgáló/erÅ‘forrás/fájl.txt." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "%s cél nem könyvtár" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: felülírja a(z) „%s†fájlt? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Ãrható attribútumok felsorolása" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Fájlrendszer-információk lekérése" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "A lekérendÅ‘ attribútumok" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBÚTUMOK" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ne kövesse a szimbolikus linkeket" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "attribútumok:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "megjelenített név: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "szerkeszthetÅ‘ név: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "név: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "típus: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "méret: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "rejtett\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "URI: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "helyi útvonal: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix csatolás: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Beállítható attribútumok:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Ãrható attribútumnévterek:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Információk megjelenítése helyekrÅ‘l." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"A gio info a hagyományos ls segédprogramhoz hasonlóan működik, de helyi\n" +"fájlok helyett GIO helyeket használ: megadható például helyként az\n" +"smb://kiszolgáló/erÅ‘forrás/fájl.txt. A fájlattribútumok a GIO nevükkel\n" +"adhatók meg, például: standard::icon, vagy egyszerűen névtér szerint,\n" +"például unix vagy „*â€, ami minden attribútumra illeszkedik." + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-FÃJL [FÃJL-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Alkalmazás indítása egy desktop fájlból, nem kötelezÅ‘ fájlnév argumentumok " +"átadásával." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nincs megadva desktop fájl" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Az indítási parancs jelenleg nem támogatott ezen a platformon" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "A(z) „%s†nem tölthetÅ‘ be: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "A(z) „%s†alkalmazásinformációi nem tölthetÅ‘k be" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "A(z) „%s†alkalmazás nem indítható el: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Rejtett fájlok megjelenítése" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Hosszú kiírási formátum használata" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Megjelenített nevek kiírása" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Teljes URI-k kiírása" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "A helyek tartalmának felsorolása." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"A gio list a hagyományos ls segédprogramhoz hasonlóan működik, de helyi\n" +"fájlok helyett GIO helyeket használ: megadható például helyként az\n" +"smb://kiszolgáló/erÅ‘forrás/fájl.txt. A fájlattribútumok a GIO nevükkel\n" +"adhatók meg, például: standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIME-TÃPUS" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "KEZELÅ" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "A MIME-típus kezelÅ‘jének lekérése vagy beállítása." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Ha nincs megadva kezelÅ‘, akkor felsorolja a regisztrált és ajánlott\n" +"alkalmazásokat a MIME-típushoz. Ha meg van adva kezelÅ‘, akkor az " +"beállításra\n" +"kerül a MIME-típus alapértelmezett kezelÅ‘jeként." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Csak egy MIME-típus adható meg, esetleg egy kezelÅ‘" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Nincs alapértelmezett alkalmazás a következÅ‘höz: „%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "A(z) „%s†alapértelmezett alkalmazása: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Regisztrált alkalmazások:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nincsenek regisztrált alkalmazások\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Javasolt alkalmazások:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Nincsenek javasolt alkalmazások\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "A(z) „%s†kezelÅ‘ információinak lekérése meghiúsult" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"A(z) „%s†beállítása a(z) „%s†alapértelmezett kezelÅ‘jeként meghiúsult: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "SzülÅ‘könyvtárak létrehozása" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Könyvtárak létrehozása." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"A gio mkdir a hagyományos mkdir segédprogramhoz hasonlóan működik, de helyi\n" +"fájlok helyett GIO helyeket használ: megadható például helyként az\n" +"smb://kiszolgáló/erÅ‘forrás/könyvtár." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Könyvtár figyelése (alapértelmezés: típusfüggÅ‘)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Fájl figyelése (alapértelmezés: típusfüggÅ‘)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Fájl közvetlen figyelése (észleli a hard linkeken keresztüli változásokat)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Fájl közvetlen figyelése, de nem jelenti a változásokat" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Ãthelyezések és átnevezések jelentése egyszerű törölve/létrehozva " +"eseményekként" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Csatolási események figyelése" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Fájlok vagy könyvtárak változásainak figyelése." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Csatolás csatolhatóként" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Kötet csatolása eszközfájllal vagy egyéb azonosítóval" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "Azonosító" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Leválasztás" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Kiadás" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Meghajtó leállítása az eszközfájllal" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ESZKÖZ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Az adott sémájú összes csatolás leválasztása" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SÉMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Az elmaradt fájlműveletek mellÅ‘zése leválasztáskor vagy kiadáskor" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Névtelen felhasználó használata a hitelesítéskor" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Listázás" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Események figyelése" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "További információk megjelenítése" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "A VeraCrypt kötet feloldásához használt numerikus PIM" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "TCRYPT rejtett kötet csatolása" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "TCRYPT rendszerkötet csatolása" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Névtelen hozzáférés megtagadva" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Nincs meghajtó az eszközfájlhoz" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Nincs kötet a megadott azonosítóhoz" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "A helyek csatolása vagy leválasztása." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ne használjon másolást és a tartalék törlését" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Fájlok áthelyezése a FORRÃSBÓL a CÉLBA." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"A gio move a hagyományos mv segédprogramhoz hasonlóan működik, de helyi\n" +"fájlok helyett GIO helyeket használ: megadható például helyként az\n" +"smb://kiszolgáló/erÅ‘forrás/fájl.txt" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "A megadott cél (%s) nem könyvtár" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Fájlok megnyitása az adott fájltípus kezelésére bejegyzett\n" +"alapértelmezett alkalmazással." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Nem létezÅ‘ fájlok figyelmen kívül hagyása, soha ne kérdezzen" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "A megadott fájlok törlése." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NÉV" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Fájl átnevezése." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Hiányzó argumentum" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:139 +msgid "Too many arguments" +msgstr "Túl sok argumentum" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Az átnevezés sikeres. Az új URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Létrehozás csak ha még nem létezik" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Hozzáfűzés a fájl végéhez" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Létrehozáskor hozzáférés korlátozása az aktuális felhasználóra" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Cserekor úgy cserélje, mintha a cél nem létezett volna" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Új etag kiírása befejezéskor" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "A felülírt fájl etagja" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ECÃMKE" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Hiba a szabványos bemenetrÅ‘l olvasáskor" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Az etag nem érhetÅ‘ el\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Szabványos bemenet olvasása és a CÉLBA mentése." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nincs megadva cél" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Az attribútum típusa" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "Típus" + +#: gio/gio-tool-set.c:91 +msgid "ATTRIBUTE" +msgstr "ATTRIBÚTUM" + +#: gio/gio-tool-set.c:91 +msgid "VALUE" +msgstr "ÉRTÉK" + +#: gio/gio-tool-set.c:95 +msgid "Set a file attribute of LOCATION." +msgstr "A HELY fájl attribútumának beállítása." + +#: gio/gio-tool-set.c:115 +msgid "Location not specified" +msgstr "Nincs megadva hely" + +#: gio/gio-tool-set.c:122 +msgid "Attribute not specified" +msgstr "Nincs megadva attribútum" + +#: gio/gio-tool-set.c:132 +msgid "Value not specified" +msgstr "Nincs megadva érték" + +#: gio/gio-tool-set.c:182 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Érvénytelen attribútumtípus (%s)" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "A Kuka ürítése" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "A kukában lévÅ‘ fájlok felsorolása az eredeti helyükkel" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Fájl visszaállítása a kukából az eredeti helyére (elÅ‘fordul, hogy a " +"könyvtára is újra létrejön)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Az eredeti útvonal nem található" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Az eredeti hely nem hozható újra létre: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "A fájl nem helyezhetÅ‘ át az eredeti helyére: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Fájlok vagy könyvtárak áthelyezése vagy visszaállítása a Kukába." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Megjegyzés: a --restore kapcsoló esetén, ha a kukába dobott fájl eredeti\n" +"helyén már létezik fájl, akkor nem lesz felülírva, hacsak nincs megadva a\n" +"--force kapcsoló." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "A megadott hely nem ezzel kezdÅ‘dik: trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Szimbolikus linkek, csatolások és indítóikonok követése" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Könyvtárak tartalmának felsorolása fa-szerű formátumban." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> elem nem engedélyezett ezen belül: <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> elem nem engedélyezett a felsÅ‘ szinten" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "A(z) %s fájl többször is megjelenik az erÅ‘forrásban" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "A(z) „%s†nem található egyik forráskönyvtárban sem" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "A(z) „%s†nem található a jelenlegi könyvtárban" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Ismeretlen feldolgozási kapcsoló: „%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"A(z) %s elÅ‘feldolgozása szükséges, de a(z) %s nincs beállítva, és a(z) %s " +"nincs a PATH környezeti változóban" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Hiba a(z) %s fájl olvasásakor: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Hiba a fájl tömörítésekor: %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "nem jelenhet meg szöveg ezen belül: <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "A programverzió megjelenítése és kilépés" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "A kimeneti fájl neve" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"A FILE-ban megadott fájlok olvasása ebbÅ‘l a könyvtárból (alapértelmezett: " +"aktuális könyvtár)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "KÖNYVTÃR" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Kimenet előállítása a célfájl kiterjesztése által kiválasztott formátumban" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Forrásfejléc előállítása" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Az erÅ‘forrásfájl kódba linkelésére használt forráskód előállítása" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "FüggÅ‘séglista előállítása" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Az előállítandó függÅ‘ségfájl neve" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "A „phony†célok bevétele a generált függÅ‘ségi fájlba" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Ne hozza létre és ne regisztrálja automatikusan az erÅ‘forrást" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ne exportáljon függvényeket; deklarálja azokat G_GNUC_INTERNAL-ként" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Ne ágyazzon be erÅ‘forrásadatokat a C fájlba, tekintse inkább úgy, hogy " +"külsÅ‘leg hivatkozott" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Az előállított forráskódhoz használt C azonosító neve" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "A cél C fordító (alapértelmezett: a CC környezeti változó)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"ErÅ‘forrás-specifikáció erÅ‘forrásfájlba fordítása.\n" +"Az erÅ‘forrás-specifikációs fájlok kiterjesztése .gresource.xml,\n" +"az erÅ‘forrásfájl kiterjesztése pedig .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Pontosan egy fájlnevet kell megadnia\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "az álnévnek legalább 2 karakternek kell lennie" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Érvénytelen számérték" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " már meg van adva" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' már meg van adva" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "a jelzÅ‘k értékeinek legfeljebb 1 bitje lehet beállítva" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> legalább egy címkét kell tartalmazzon" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> nincs a megadott tartományon belül" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nem a megadott felsorolt típus érvényes tagja" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> nem a megadott jelzÅ‘ típusú karakterláncot tartalmaz" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> nem a közti karakterláncot tartalmaz" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " már meg van adva ehhez a kulcshoz" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nem engedélyezett ezen típusú kulcshoz: „%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " megadott minimuma nagyobb a maximumánál" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "nem támogatott lokalizációs kategória: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n kérve, de nincs megadva gettext tartomány" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "fordítási kontextus megadva egy lokalizáció nélküli értékhez" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Nem sikerült feldolgozni a(z) „%s†típusú értéket: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "a nem adható meg felsorolás típusúként megjelölt kulcsokhoz" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " már meg van adva ehhez a kulcshoz" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nem engedélyezett ezen típusú kulcshoz: „%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " már meg van adva" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " legalább egy címkét kell tartalmazzon" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " már meg van adva ehhez a kulcshoz" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" csak felsorolás vagy jelzÅ‘ típusú kulcsokhoz, vagy után " +"adható meg" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" van megadva, miközben „%s†már a felsorolás típus tagja" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" van megadva, miközben már meg van adva " + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " már meg van adva" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "„%s†álnév célja nem felsorolás típusban van" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "„%s†álnév célja nem címkében van" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " legalább egy címkét kell tartalmazzon" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Az üres nevek nem engedélyezettek" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Érvénytelen név („%sâ€): a neveknek kisbetűvel kell kezdÅ‘dniük" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Érvénytelen név („%sâ€): érvénytelen karakter: „%câ€. Csak kisbetűk, számok és " +"kötÅ‘jel („-â€) engedélyezettek" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Érvénytelen név („%sâ€): két egymást követÅ‘ kötÅ‘jel („--â€) nem engedélyezett" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Érvénytelen név („%sâ€): az utolsó karakter nem lehet kötÅ‘jel („-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Érvénytelen név („%sâ€): a maximális hossz 1024 karakter" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " már meg van adva" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Nem adhatók kulcsok „list-of†sémához" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " már meg van adva" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" leárnyékolja ezt: ebben: ; " +"az érték módosításához használja az címkét" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"A attribútumaként csak a „typeâ€, „enum†vagy „flags†egyike adható meg" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (még) nincs megadva." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Érvénytelen GVariant típuskarakterlánc: „%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "Az megadva, de a séma nem terjeszt ki semmit" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Nincs felülírandó " + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " már megadva" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " már megadva" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "A a még nem létezÅ‘ „%s†sémát terjeszti ki" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "A a még nem létezÅ‘ „%s†séma listája" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Nem lehet séma listája útvonallal" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Nem terjeszthet ki sémát útvonallal" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +"a lista a nem lista sémát terjeszti ki" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +"A kiterjeszti ezt: , de „%s†nem terjeszti ki ezt: „%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"Ha meg van adva útvonal, akkor osztásjellel kell kezdÅ‘dnie és végzÅ‘dnie" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "A lista útvonalának „:/†karakterekkel kell végzÅ‘dnie" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Figyelmeztetés: „%s†sémához „%s†útvonal tartozik. Az „/apps/â€, \"/" +"desktop/†vagy „/system/†kezdetű útvonalak elavultak." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> már meg van adva" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Csak egy <%s> elem engedélyezett ezen belül: <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "<%s> elem nem engedélyezett a felsÅ‘ szinten" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "A elem kötelezÅ‘ a -ben" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Nem jelenhet meg szöveg ezen belül: <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Figyelmeztetés: nem definiált hivatkozás erre: " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "a --strict meg lett adva, kilépés." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Ez az egész fájl figyelmen kívül marad." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Fájl figyelmen kívül hagyása." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Nincs „%s†kulcs a(z) „%s†sémában a(z) „%s†felülbírálási fájlban megadott " +"módon. Felülbírálás figyelmen kívül hagyása ennél a kulcsnál." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Nincs „%s†kulcs a(z) „%s†sémában a(z) „%s†felülbírálási fájlban megadott " +"módon és --strict lett megadva. Kilépés." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Nem képes asztalonkénti felülírás biztosítására a(z) „%s†lokalizált kulcs " +"esetén a(z) „%s†sémában („%s†fájl felülírás). Felülbírálás figyelmen kívül " +"hagyása ennél a kulcsnál." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Nem képes asztalonkénti felülírás biztosítására a(z) „%s†lokalizált kulcs " +"esetén a(z) „%s†sémában („%s†fájl felülírás) és --strict lett megadva. " +"Kilépés." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Hiba a(z) „%s†kulcs feldolgozásakor a(z) „%s†sémában a(z) „%s†" +"felülbírálási fájlban megadott módon: %s. Felülbírálás figyelmen kívül " +"hagyása ennél a kulcsnál." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Hiba a(z) „%s†kulcs feldolgozásakor a(z) „%s†sémában a(z) „%s†" +"felülbírálási fájlban megadott módon: %s. A --strict meg lett adva. Kilépés." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"A(z) „%2$s†séma „%1$s†kulcsának felülbírálása a(z) „%3$s†felülbírálási " +"fájlban a sémában megadott tartományon kívül esik. Felülbírálás figyelmen " +"kívül hagyása ennél a kulcsnál." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"A(z) „%2$s†séma „%1$s†kulcsának felülbírálása a(z) „%3$s†felülbírálási " +"fájlban a sémában megadott tartományon kívül esik és a --strict lett " +"megadva. Kilépés." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"A(z) „%2$s†séma „%1$s†kulcsának felülbírálása a(z) „%3$s†felülbírálási " +"fájlban nincs az érvényes lehetÅ‘ségek listájában. Felülbírálás figyelmen " +"kívül hagyása ennél a kulcsnál." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"A(z) „%2$s†séma „%1$s†kulcsának felülbírálása a(z) „%3$s†felülbírálási " +"fájlban nincs az érvényes lehetÅ‘ségek listájában és a --strict lett megadva. " +"Kilépés." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "A gschemas.compiled fájl tárolási helye" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Megszakítás a sémák bármely hibája esetén" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Ne írja ki a gschema.compiled fájlt" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Ne kényszerítse ki a kulcsnévmegszorításokat" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Minden GSettings sémafájl sémagyorsítótárba fordítása.\n" +"A sémafájloknak .gschema.xml kiterjesztéssel kell rendelkezniük,\n" +"és a gyorsítótárfájl neve gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Pontosan egy könyvtárnevet kell megadnia" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nem találhatók sémafájlok: nincs mit tenni." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Nem találhatók sémafájlok: meglévÅ‘ kimeneti fájl eltávolítva." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Érvénytelen fájlnév: %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Hiba a(z) %s fájlrendszer-információinak lekérésekor: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "A(z) %s fájlt tartalmazó csatolás nem található" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Nem nevezhetÅ‘ át a gyökérkönyvtár" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Hiba a(z) %s fájl átnevezésekor: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "A fájl nem nevezhetÅ‘ át, a fájlnév már létezik" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Érvénytelen fájlnév" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Hiba a(z) %s fájl megnyitásakor: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Hiba a(z) %s fájl eltávolításakor: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Hiba a(z) %s fájl Kukába dobásakor: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Nem sikerült létrehozni a(z) %s Kuka könyvtárat: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Nem található a felsÅ‘ szintű könyvtár a(z) %s kidobásához" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "A rendszer belsÅ‘ csatolásain a Kukába dobás nem támogatott" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "" +"Nem található vagy nem hozható létre a(z) %s Kuka könyvtár a(z) %s " +"kidobásához" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Nem sikerült létrehozni a(z) %s kukainformációs fájlját: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Nem lehet fájlrendszer-határokon át Kukába dobni a(z) %s fájlt" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Nem lehet a Kukába dobni a(z) %s fájlt: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Nem lehet a Kukába dobni a(z) %s fájlt" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Hiba a(z) %s könyvtár létrehozásakor: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "A fájlrendszer nem támogatja a szimbolikus linkeket" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Hiba a(z) %s szimbolikus link létrehozásakor: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Hiba a(z) %s fájl áthelyezésekor: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "A könyvtár nem helyezhetÅ‘ át könyvtárba" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "A mentési fájl létrehozása meghiúsult" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Hiba a célfájl eltávolításakor: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "A csatolások közti áthelyezés nem támogatott" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Nem lehet meghatározni %s lemezhasználatát: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Az attribútum értéke nem lehet NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Érvénytelen attribútumtípus (a várt karakterlánc helyett)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Érvénytelen kiterjesztett attribútumnév" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Hiba a(z) „%s†kiterjesztett attribútum beállításakor: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (érvénytelen kódolás)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Hiba a(z) „%s†fájl információinak lekérésekor: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Hiba a fájlleíró információinak lekérésekor: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Érvénytelen attribútumtípus (a várt uint32 helyett)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Érvénytelen attribútumtípus (a várt uint64 helyett)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Érvénytelen attribútumtípus (a várt bájtkarakterlánc helyett)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Nem állíthatók be a szimbolikus linkek jogosultságai" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Hiba a jogosultságok beállításakor: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Hiba a tulajdonos beállításakor: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "a szimbolikus link nem lehet NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Hiba a szimbolikus link beállításakor: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Hiba a szimbolikus link beállításakor: a fájl nem szimbolikus link" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"A(z) %2$lld UNIX idÅ‘bélyeghez tartozó további %1$d nanoszekundum negatív" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"A(z) %2$lld UNIX idÅ‘bélyeghez tartozó további %1$d nanoszekundum eléri az 1 " +"másodpercet" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "A(z) %lld UNIX idÅ‘bélyeg nem fér el 64 biten" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"A(z) %lld UNIX idÅ‘bélyeg kívül esik a Windows által támogatott tartományon" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "A(z) „%s†fájlnév nem alakítható át UTF-16-as kódolásúra" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "A(z) „%s†fájl nem nyitható meg: Windows hiba %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Hiba a(z) „%s†fájl módosítási vagy hozzáférési idejének beállításakor: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Hiba a módosítási vagy hozzáférési idÅ‘ beállításakor: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "A SELinux környezet nem lehet NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "A SELinux nem engedélyezett ezen rendszeren" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Hiba a SELinux környezet beállításakor: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "A(z) %s attribútum beállítása nem támogatott" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Hiba a fájl olvasásakor: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Hiba a fájl lezárásakor: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Hiba a fájlban kereséskor: %s" + +#: gio/glocalfilemonitor.c:879 +msgid "Unable to find default local file monitor type" +msgstr "Nem található az alapértelmezett helyi fájlfigyelÅ‘ típus" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Hiba a fájl írásakor: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Hiba a régi mentési link eltávolításakor: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Hiba a mentés létrehozásakor: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Hiba az ideiglenes fájl átnézésekor: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Hiba a fájl csonkításakor: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Hiba a(z) %s fájl megnyitásakor: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "A célfájl egy könyvtár" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "A célfájl nem szabályos fájl" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "A fájlt külsÅ‘ program módosította" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Hiba a régi fájl eltávolításakor: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "A megadott GSeekType nem támogatott" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Érvénytelen keresési kérés" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "A GMemoryInputStream nem csonkítható" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "A memóriakimeneti adatfolyam nem méretezhetÅ‘ át" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "A memóriakimeneti adatfolyam átméretezése meghiúsult" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Az írás feldolgozásához szükséges memória mérete nagyobb, mint az elérhetÅ‘ " +"címtér" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Pozicionálási kérés az adatfolyam eleje elé" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Pozicionálási kérés az adatfolyam vége mögé" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "A csatolás nem valósítja meg az „unmount†függvényt" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "A csatolás nem valósítja meg az „eject†függvényt" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"A csatolás nem valósítja meg az „unmount†vagy az „unmount_with_operation†" +"függvényt" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"A csatolás nem valósítja meg az „eject†vagy az „eject_with_operation†" +"függvényt" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "A csatolás nem valósítja meg a „remount†függvényt" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "A csatolás nem valósítja meg a tartalomtípus meghatározását" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "A csatolás nem valósítja meg a tartalomtípus szinkron meghatározását" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "A gépnév („%sâ€) „[†karaktert tartalmaz „]†nélkül" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "A hálózat elérhetetlen" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "A gép elérhetetlen" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Nem hozható létre a hálózatfigyelÅ‘: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Nem hozható létre a hálózatfigyelÅ‘: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Nem kérhetÅ‘ le a hálózat állapota: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "A HálózatkezelÅ‘ nem fut" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "A HálózatkezelÅ‘ verziója túl régi" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "A kimeneti adatfolyam nem valósítja meg az írást" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "A(z) %s részére átadott vektorok összege túl nagy" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "A forrás adatfolyam már le van zárva" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Hiba a(z) „%s†feloldásakor: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "A(z) %s nincs megvalósítva" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Érvénytelen tartomány" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Az erÅ‘forrás nem létezik itt: „%sâ€" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Az erÅ‘forrás kicsomagolása meghiúsult itt: „%sâ€" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Az erÅ‘forrás nem könyvtár itt: „%sâ€" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "A bemeneti adatfolyam nem valósítja meg a pozicionálást" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Elf FÃJLBAN erÅ‘forrásokat tartalmazó szakaszok felsorolása" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"ErÅ‘források felsorolása\n" +"Ha a SZAKASZ meg van adva, akkor csak az adott szakasz erÅ‘forrásainak " +"felsorolása\n" +"Ha az ÚTVONAL meg van adva, akkor csak az illeszkedÅ‘ erÅ‘források felsorolása" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FÃJL [ÚTVONAL]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SZAKASZ" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"ErÅ‘források felsorolása részletekkel együtt\n" +"Ha a SZAKASZ meg van adva, akkor csak az adott szakasz erÅ‘forrásainak " +"felsorolása\n" +"Ha az ÚTVONAL meg van adva, akkor csak az illeszkedÅ‘ erÅ‘források " +"felsorolása\n" +"A részletek közé a szakasz, méret és tömörítés tartozik" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "ErÅ‘forrásfájl kibontása a szabványos kimenetre" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FÃJL ÚTVONAL" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Használat:\n" +" gresource [--section SZAKASZ] PARANCS [ARG…]\n" +"\n" +"Parancsok:\n" +" help Ezen súgó kiírása\n" +" sections ErÅ‘forrásszakaszok felsorolása\n" +" list ErÅ‘források felsorolása\n" +" details ErÅ‘források felsorolása részletekkel együtt\n" +" extract ErÅ‘forrás kibontása\n" +"\n" +"Részletes segítségért adja ki a „gresource help PARANCS†parancsot.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Használat:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SZAKASZ Egy elhagyható elf szakasznév\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " PARANCS A megmagyarázandó (elhagyható) parancs\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FÃJL Egy elf fájl (bináris vagy megosztott programkönyvtár)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FÃJL Egy elf fájl (bináris vagy megosztott programkönyvtár)\n" +"\n" +" vagy lefordított erÅ‘forrásfájl\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[ÚTVONAL]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " ÚTVONAL Egy elhagyható erÅ‘forrás-útvonal (részleges is lehet)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "ÚTVONAL" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " ÚTVONAL Egy erÅ‘forrás-útvonal\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Nincs „%s†séma\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "A(z) „%s†séma nem helyezhetÅ‘ át (az útvonal nem adható meg)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "A(z) „%s†séma áthelyezhetÅ‘ (az útvonalat meg kell adni)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "A megadott útvonal üres.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Az útvonalnak osztásjellel (/) kell kezdÅ‘dnie\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Az útvonalnak osztásjellel (/) kell végzÅ‘dnie\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Az útvonal nem tartalmazhat két szomszédos osztásjelet (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "A megadott érték kívül esik az érvényes tartományon\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "A kulcs nem írható\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "A telepített (át nem helyezhetÅ‘) sémák felsorolása" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "A telepített áthelyezhetÅ‘ sémák felsorolása" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "A SÉMA kulcsainak felsorolása" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SÉMA[:ÚTVONAL]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "A SÉMA gyermekeinek felsorolása" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Kulcsok és értékek rekurzív felsorolása\n" +"Ha nincs megadva SÉMA, az összes kulcs felsorolása\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SÉMA[:ÚTVONAL]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "A KULCS értékének lekérése" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SÉMA[:ÚTVONAL] KULCS" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "A KULCS érvényes értékei tartományának lekérése" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "A KULCS leírásának lekérése" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "A KULCS értékének beállítása az ÉRTÉKRE" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SÉMA[:ÚTVONAL] KULCS ÉRTÉK" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "A KULCS visszaállítása az alapértékére" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "A SÉMA minden kulcsának visszaállítása az alapértékekre" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "A KULCS írhatóságának ellenÅ‘rzése" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"A KULCS változásainak figyelése.\n" +"Ha nincs megadva KULCS, akkor a SÉMA összes kulcsának figyelése.\n" +"A figyelés befejezéséhez nyomja meg a ^C kombinációt.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SÉMA[:ÚTVONAL] [KULCS]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Használat:\n" +" gsettings --version\n" +" gsettings [--schemadir SÉMAKVT] PARANCS [ARGUMENTUMOK…]\n" +"\n" +"Parancsok:\n" +" help Ez a súgó\n" +" list-schemas Telepített sémák felsorolása\n" +" list-relocatable-schemas ÃthelyezhetÅ‘ sémák felsorolása\n" +" list-keys Séma kulcsainak felsorolása\n" +" list-children Séma gyermekeinek felsorolása\n" +" list-recursively Kulcsok és értékek rekurzív felsorolása\n" +" range Kulcs tartományának lekérése\n" +" describe Kulcs leírásának lekérése\n" +" get Kulcs értékének lekérése\n" +" set Kulcs értékének beállítása\n" +" reset Kulcs értékének visszaállítása\n" +" reset-recursively Az összes érték visszaállítása egy adott " +"sémában\n" +" writable Kulcs írhatóságának ellenÅ‘rzése\n" +" monitor Változások figyelése\n" +"\n" +"Részletes segítségért adja ki a „gsettings help PARANCS†parancsot.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Használat:\n" +" gsettings [--schemadir SÉMAKVT] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SÉMAKVT További sémák keresése ebben a könyvtárban\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SÉMA A séma neve\n" +" ÚTVONAL Az áthelyezhetÅ‘ sémák útvonala\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KULCS A sémán belüli (elhagyható) kulcs\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KULCS A sémán belüli kulcs\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " ÉRTÉK A beállítandó érték\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Nem lehet sémákat betölteni ebbÅ‘l: %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nincsenek telepítve sémák\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Üres sémanevet adott meg\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Nincs „%s†kulcs\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Érvénytelen foglalat, nincs elÅ‘készítve" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Érvénytelen foglalat, az elÅ‘készítés meghiúsulásának oka: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "A foglalat már le van zárva" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "A foglalat I/O túllépte az idÅ‘korlátot" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "GSocket létrehozása fájlleíróból: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Nem sikerült létrehozni foglalatot: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Ismeretlen családot adtak meg" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Ismeretlen protokollt adtak meg" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "A datagram műveletek nem használhatóak nem-datagram foglalaton." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"A datagram műveletek nem használhatóak olyan foglalaton, amelyre idÅ‘túllépés " +"van beállítva." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "nem kérhetÅ‘ le a helyi cím: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "nem kérhetÅ‘ le a távoli cím: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "nem lehet figyelni: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Hiba a(z) %s címhez csatlakozáskor: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Hiba a multicast csoporthoz csatlakozáskor: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Hiba a multicast csoport elhagyásakor: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "A forrásspecifikus multicast nem támogatott" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Nem támogatott foglalatcsalád" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "A forrásspecifikus nem egy IPv4-cím" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Az interfésznév túl hosszú" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interfész nem található: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Az IPv4 forrásspecifikus multicast nem támogatott" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Az IPv6 forrásspecifikus multicast nem támogatott" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Hiba a kapcsolat elfogadásakor: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Csatlakozás folyamatban" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Nem lehet lekérni a függÅ‘ben lévÅ‘ hibát: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Hiba az adatok fogadásakor: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Hiba az adatok küldésekor: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Nem sikerült leállítani a foglalatot: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Hiba a foglalat lezárásakor: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Várakozás a foglalat állapotára: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Nem sikerült elküldeni az üzenetet: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Az üzenetvektorok túl nagyok" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Hiba az üzenet küldésekor: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "A GSocketControlMessage nem támogatott Windowson" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Hiba az üzenet fájl eltávolítása fogadásakor: %s" + +#: gio/gsocket.c:6092 gio/gsocket.c:6103 gio/gsocket.c:6166 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Nem sikerült olvasni a foglalat hitelesítési adatait: %s" + +#: gio/gsocket.c:6175 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "a g_socket_get_credentials nincs megvalósítva erre az OS-re" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Nem sikerült kapcsolódni a(z) %s proxy kiszolgálóhoz: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Nem sikerült kapcsolódni a következÅ‘höz: %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Nem sikerült kapcsolódni: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1805 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "A proxyzás nem TCP kapcsolaton keresztül nem támogatott." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1834 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "A proxyprotokoll („%sâ€) nem támogatott." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "A figyelÅ‘ már le van zárva" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "A hozzáadott foglalat le van zárva" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "A SOCKSv4 nem támogatja ezt az IPv6 címet: „%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "A felhasználónév túl hosszú a SOCKSv4 protokollhoz" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "A gépnév („%sâ€) túl hosszú a SOCKSv4 protokollhoz" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "A kiszolgáló nem SOCKSv4 proxy kiszolgáló." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "A SOCKSv4 kiszolgálón keresztüli kapcsolat visszautasítva" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "A kiszolgáló nem SOCKSv5 proxy kiszolgáló." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "A SOCKSv5 proxy hitelesítést igényel." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "A SOCKSv5 a GLib által nem támogatott hitelesítési módszert igényel." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "A felhasználónév vagy jelszó túl hosszú a SOCKSv5 protokollhoz." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"A SOCKSv5 hitelesítés hibás felhasználónév vagy jelszó miatt meghiúsult." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "A gépnév („%sâ€) túl hosszú a SOCKSv5 protokollhoz" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "A SOCKSv5 proxy kiszolgáló ismeretlen címtípust használ." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "BelsÅ‘ SOCKSv5 proxy kiszolgáló hiba." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "A SOCKSv5 kapcsolatot a szabálykészlet nem engedélyezi." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "A gép nem érhetÅ‘ el a SOCKSv5 kiszolgálón keresztül." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "A hálózat nem érhetÅ‘ el a SOCKSv5 proxyn keresztül." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "A kapcsolat visszautasítva a SOCKSv5 proxyn keresztül." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "A SOCKSv5 proxy nem támogatja a „connect†parancsot." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "A SOCKSv5 proxy nem támogatja a megadott címtípust." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Ismeretlen SOCKSv5 proxy hiba." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Nem sikerült csÅ‘vezetéket készíteni a gyermekfolyamattal (%s) való " +"kommunikációhoz" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "A csÅ‘vezetékek nem támogatottak ezen a platformon" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "A GThemedIcon kódolás %d. verziója nem kezelhetÅ‘" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Nem találhatók érvényes címek" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Hiba a(z) „%s†fájl fordított feloldásakor: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "" +"Hiba a(z) %s DNS-rekord feldolgozásakor: helytelenül formázott DNS-csomag" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Nincs kért típusú DNS-rekord ehhez: „%sâ€" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Ideiglenesen nem oldható fel: „%sâ€" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Hiba a(z) „%s†feloldásakor" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Helytelenül formázott DNS-csomag" + +#: gio/gthreadedresolver.c:886 +#, c-format +#| msgid "Failed to read from file “%sâ€: %s" +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Nem sikerült feldolgozni a(z) „%s†DNS válaszát: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Nem található PEM-kódolású személyes kulcs" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Nem fejthetÅ‘ vissza a PEM-kódolású személyes kulcs" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Nem dolgozható fel a PEM-kódolású személyes kulcs" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Nem található PEM-kódolású tanúsítvány" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Nem dolgozható fel a PEM-kódolású tanúsítvány" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "A jelenlegi TLS háttérprogram nem támogatja a PKCS #12 tanúsítványokat" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Ez a GTlsBackend nem támogatja a PKCS #11 tanúsítványok létrehozását" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ez az utolsó lehetÅ‘sége a helyes jelszó megadására, mielÅ‘tt hozzáférése " +"zárolásra kerül. " + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Több helytelen jelszót adott meg, és a további sikertelen próbálkozások után " +"hozzáférése zárolásra kerül." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "A megadott jelszó helytelen." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Az FL küldése nem támogatott" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "A várt 1 vezérlőüzenet helyett %d érkezett" +msgstr[1] "A várt 1 vezérlőüzenet helyett %d érkezett" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Váratlan típusú kiegészítÅ‘ adatok" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "A várt egy fájlleíró helyett %d érkezett\n" +msgstr[1] "A várt egy fájlleíró helyett %d érkezett\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Érvénytelen fájlleíró érkezett" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Az FL fogadása nem támogatott" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Hiba a hitelesítési adatok küldésekor: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"Hiba a SO_PASSCRED engedélyezettségének ellenÅ‘rzésekor a foglalathoz: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Hiba a SO_PASSCRED engedélyezésekor: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"A hitelesítési adatok fogadásához várt egyetlen bájt helyett nulla bájt lett " +"beolvasva" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "A program nem várt vezérlőüzenetet, de %d érkezett" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Hiba a SO_PASSCRED letiltásakor: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Hiba a fájlleíróból olvasáskor: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Hiba a fájlleíró lezárásakor: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Fájlrendszer gyökere" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Hiba a fájlleíróba íráskor: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Az absztrakt UNIX tartományfoglalat-címek nem támogatottak ezen a rendszeren" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "a kötet nem valósítja meg a kiadást" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" +"a kötet nem valósítja meg a kiadást vagy a eject_with_operation függvényt" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Hiba a leíróból való olvasáskor: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Hiba a leíró lezárásakor: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Hiba a leíróba íráskor: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nincs elég memória" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "BelsÅ‘ hiba: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "További bemenet szükséges" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Érvénytelen tömörített adatok" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Ezen cím figyelése" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Figyelmen kívül marad, csak a GTestDbus-kompatibilitás miatt" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Cím kiírása" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Cím kiírása shell módban" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "D-Bus szolgáltatás futtatása" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Hibás argumentumok\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Váratlan attribútum („%sâ€) a(z) „%s†elemhez" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "A(z) „%2$s†elem „%1$s†attribútuma nem található" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Váratlan címke: „%s†a várt „%s†helyett" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Váratlan címke: „%s†a következÅ‘n belül: „%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Érvénytelen „%s†dátum vagy idÅ‘ a könyvjelzÅ‘fájlban" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Az adatkönyvtárakban nem található érvényes könyvjelzÅ‘fájl" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Már létezik könyvjelzÅ‘ a következÅ‘ URI címhez: „%sâ€" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nem található könyvjelzÅ‘ a következÅ‘ URI címhez: „%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Nincs MIME típus meghatározva a következÅ‘ URI könyvjelzÅ‘jéhez: „%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Nincs magán jelzÅ‘ meghatározva a következÅ‘ URI könyvjelzÅ‘jéhez: „%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Nincsenek csoportok beállítva a következÅ‘ URI könyvjelzÅ‘jéhez: „%sâ€" + +# FIXME: hol jön ez elÅ‘? +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" +"Nincs „%s†nevű alkalmazás regisztrálva a következÅ‘ könyvjelzÅ‘jéhez: „%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "" +"Nem sikerült kiterjeszteni a(z) „%s†végrehajtási sort a(z) „%s†URL címmel" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Nem ábrázolható karakter az átalakítási bemenetben" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Részleges karaktersorozat a bemenet végén" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Nem alakítható át a tartalék „%s†a(z) „%s†kódkészletre" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Beágyazott NUL bájt az átalakítás bemenetében" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Beágyazott NUL bájt az átalakítás kimenetében" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "A(z) „%s†URI nem abszolút, a „file†sémát használó URI" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "A(z) „%s†helyi fájl URI nem tartalmazhat „#†karaktert" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "A(z) „%s†URI érvénytelen" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "A(z) „%s†gépneve érvénytelen" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "" +"A(z) „%s†URI érvénytelen, escape sorozatként megadott karaktereket tartalmaz" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "A(z) „%s†elérési út neve nem abszolút útvonal" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Y. %b. %-e. %a. %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%Y. %m. %d." + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%H:%M:%S" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Január" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Február" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Március" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Ãprilis" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Május" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Június" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Július" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Augusztus" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Szeptember" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Október" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "December" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Febr" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Már" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Ãpr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Máj" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jún" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Júl" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Szept" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "HétfÅ‘" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Kedd" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Szerda" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Csütörtök" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Péntek" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Szombat" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Vasárnap" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Hé" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Ke" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Sze" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Csü" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Pé" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Szo" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Va" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "január" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "február" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "március" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "április" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "május" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "június" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "július" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "augusztus" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "szeptember" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "október" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "febr" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "márc" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "ápr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "máj" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jún" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "júl" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "aug" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "szept" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "DE" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "DU" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Hiba a(z) „%s†könyvtár megnyitásakor: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Nem sikerült %lu bájtot lefoglalni a(z) „%s†fájl olvasásához" +msgstr[1] "Nem sikerült %lu bájtot lefoglalni a(z) „%s†fájl olvasásához" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Hiba a(z) „%s†fájl olvasásakor: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "A fájl („%sâ€) túl nagy" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Nem sikerült olvasni a(z) „%s†fájlból: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Nem sikerült megnyitni a(z) „%s†fájlt: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Nem sikerült lekérni a(z) „%s†fájl attribútumait. Az fstat() sikertelen: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Nem sikerült megnyitni a(z) „%s†fájlt. Az fdopen() sikertelen: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Nem sikerült átnevezni a(z) „%s†fájlt erre: „%sâ€. A g_rename() sikertelen: " +"%s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Nem sikerült írni a(z) „%s†fájlt: a write() sikertelen: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Nem sikerült írni a(z) „%s†fájlt: az fsync() sikertelen: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Nem sikerült létrehozni a(z) „%s†fájlt: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "A létezÅ‘ „%s†fájl nem távolítható el: a g_unlink() sikertelen: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "A(z) „%s†sablon érvénytelen, „%s†nem lehet benne" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "A(z) „%s†sablon nem tartalmaz XXXXXX karaktersorozatot" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Nem sikerült kiolvasni a(z) „%s†szimbolikus linket: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Az átalakító a(z) „%s†elemrÅ‘l „%s†elemre nem nyitható meg: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Nem lehet nyers (raw) olvasást végezni a g_io_channel_read_line_string-ben" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Ãt nem alakított adatok maradtak az olvasási pufferben" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "A csatorna töredék karakterrel ér véget" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Nem lehet nyers (raw) olvasást végezni a g_io_channel_read_to_end-ben" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "A keresési könyvtárakban nem található érvényes kulcsfájl" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Nem szabályos fájl" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"A kulcsfájl tartalmazza a(z) „%s†sort, amelyik nem egy kulcs-érték pár, " +"csoport, vagy megjegyzés" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Érvénytelen csoportnév: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "A kulcsfájl nem csoporttal kezdÅ‘dik" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Érvénytelen kulcsnév: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "A kulcsfájl a nem támogatott „%s†kódolást tartalmazza" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "A kulcsfájlból hiányzik a(z) „%s†csoport" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "A kulcsfájl nem tartalmazza a(z) „%s†kulcsot a(z) „%s†csoportban." + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"A kulcsfájl tartalmazza a(z) „%s†kulcsot „%s†értékkel, amelyik azonban nem " +"UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"A kulcsfájl tartalmazza a(z) „%s†kulcsot, amelynek értéke nem értelmezhetÅ‘." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"A kulcsfájl tartalmazza a(z) „%s†kulcsot a(z) „%s†csoportban, amelynek " +"értéke nem értelmezhetÅ‘." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"A(z) „%s†kulcs a(z) „%s†csoportban „%s†értékkel rendelkezik a várt %s " +"helyett" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "A kulcsfájl escape sorozattal megadott karaktert tartalmaz a sor végén" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "A kulcsfájl érvénytelen escape sorozatot tartalmaz („%sâ€)" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "A(z) „%s†érték nem értelmezhetÅ‘ számként." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "A(z) „%s†egész érték a tartományon kívülre esik" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "A(z) „%s†érték nem értelmezhetÅ‘ lebegÅ‘pontos számként." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "A(z) „%s†érték nem értelmezhetÅ‘ logikai értékként." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Nem sikerült lekérni a(z) „%s%s%s%s†fájl attribútumait. Az fstat() " +"sikertelen: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Nem sikerült leképezni a(z) %s%s%s%s fájlt: Az mmap() sikertelen: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Nem sikerült megnyitni a(z) „%s†fájlt: az open() sikertelen: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Hiba a(z) %d. sor %d. karakterénél: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Érvénytelen UTF-8 kódolású szöveg a névben - nem érvényes „%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "A(z) „%s†nem érvényes név" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "A(z) „%s†nem érvényes név: „%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Hiba a(z) %d. sorban: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Nem sikerült feldolgozni ezt: „%-.*sâ€. Valószínűleg számjegy lett volna egy " +"karakterhivatkozáson (mint az ê) belül - lehet, hogy túl nagy a számjegy" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"A karakterhivatkozás nem pontosvesszÅ‘vel ért véget; valószínűleg egy &-jelet " +"használt anélkül, hogy entitást akart volna kezdeni - írja & formában." + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "A(z) „%-.*s†karakterhivatkozás nem engedélyezett karaktert kódol" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Üres „&;†entitás; az érvényes entitások: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "A(z) „%-.*s†entitásnév ismeretlen" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Az entitás neve nem pontosvesszÅ‘vel ért véget; valószínűleg egy &-jelet " +"használt anélkül, hogy entitást akart volna kezdeni - írja & formában." + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "A dokumentumnak egy elemmel kell kezdÅ‘dnie (például: )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"A(z) „%s†nem érvényes karakter a „<†karakter után; elem neve nem kezdÅ‘dhet " +"vele" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Furcsa karakter („%sâ€), „>†karakternek kellett volna jönnie, hogy lezárja " +"a(z) „%s†üres elemcímkét" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Túl sok attribútum a(z) „%s†elemben" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Furcsa karakter („%sâ€), „=†karakternek kellett volna jönnie a(z) „%s†elem " +"„%s†attribútumneve után" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Furcsa „%s†karakter - „>†vagy „/†karakternek kellett volna jönnie a(z) " +"„%s†elem kezdÅ‘ címkéje után, esetleg egy attribútumnak; lehet, hogy " +"érvénytelen karaktert használt az attribútum nevében" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Furcsa karakter („%sâ€), egy nyitó idézÅ‘jelnek kellene jönnie az " +"egyenlÅ‘ségjel után, ha értéket ad a(z) „%s†attribútumnak „%s†elemben" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"A(z) „%s†nem érvényes karakter a(z) „%s†lezáró elemnév után; az " +"engedélyezett karakter egyedül a „>â€." + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "A(z) „%s†elem le lett lezárva, jelenleg egy elem sincs nyitva" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "A(z) „%s†elem le lett lezárva, de a jelenleg nyitott elem a(z) „%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "A dokumentum üres volt, vagy csak üres hely karaktereket tartalmazott" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"A dokumentum váratlanul véget ért egy nyitott hegyes zárójel („<â€) után" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"A dokumentum váratlanul véget ért, pedig még nyitva vannak elemek - „%s†az " +"utoljára megnyitott elem" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"A dokumentum váratlanul véget ért; a(z) <%s/> elemet lezáró hegyes " +"zárójelnek kellett volna következnie" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "A dokumentum váratlanul véget ért egy elemnéven belül" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "A dokumentum váratlanul véget ért egy attribútumnéven belül" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "A dokumentum váratlanul véget ért egy elemnyitó címkén belül" + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"A dokumentum váratlanul véget ért egy az attribútumnevet követÅ‘ " +"egyenlÅ‘ségjel után; az attribútum értéke nem lett megadva" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "A dokumentum váratlanul véget ért egy attribútumértéken belül" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "A dokumentum váratlanul véget ért a(z) „%s†elem lezáró címkéjén belül" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"A dokumentum váratlanul véget ért egy nem nyitott elem lezáró címkéjén belül" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"A dokumentum váratlanul véget ért egy megjegyzésen vagy feldolgozási " +"utasításon belül" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[KAPCSOLÓ…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "SúgólehetÅ‘ségek:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "SúgólehetÅ‘ségek megjelenítése" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Minden súgólehetÅ‘ség megjelenítése" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Alkalmazás kapcsolói:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Kapcsolók:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Nem dolgozható fel a(z) „%s†egész érték a következÅ‘höz: %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "A(z) „%s†egész érték a tartományon kívülre esik a következÅ‘höz: %s" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Nem dolgozható fel a(z) „%s†dupla hosszúságú érték a következÅ‘höz: %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "" +"A(z) „%s†dupla hosszúságú érték a tartományon kívülre esik a következÅ‘höz: " +"%s" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Hiba a kapcsoló feldolgozásakor: %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Hiányzó paraméter a következÅ‘höz: %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Ismeretlen kapcsoló: %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "sérült objektum" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "belsÅ‘ hiba vagy sérült objektum" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "elfogyott a memória" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "a visszakövetési korlát elérve" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"a minta a részleges mintaillesztés esetén nem támogatott elemeket tartalmaz" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "belsÅ‘ hiba" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"a visszahivatkozások használata feltételekként nem támogatott a részleges " +"mintaillesztéshez" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "az ismétlési korlát elérve" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "újsor-jelzÅ‘k érvénytelen kombinációja" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "hibás eltolás" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "rövid utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "rekurzív ciklus" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "ismeretlen hiba" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ a minta végén" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c a minta végén" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "ismeretlen karakter következik a \\ után" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "a számok nincsenek sorrendben a {} kvantálóban" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "a szám túl nagy a a {} kvantálóban" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "a karakterosztály befejezÅ‘ ] jele hiányzik" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "érvénytelen escape-sorozat a karakterosztályban" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "a tartomány kívül esik a karakterosztály nagyságán" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nincs mit ismételni" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "váratlan ismétlés" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "ismeretlen karakter a (? vagy (?- után" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "a POSIX elnevezett osztályok csak osztályon belül támogatottak" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "hiányzó befejezÅ‘ )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "hivatkozás nem létezÅ‘ almintára" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "a megjegyzés utáni ) hiányzik" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "a reguláris kifejezés túl nagy" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "a memóriakérés meghiúsult" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") nyitó ( nélkül" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "kódtúlcsordulás" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "ismeretlen karakter a (?< után" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "a lookbehind kijelentés nem rögzített hosszúságú" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "hibásan formázott szám vagy név a (?( után" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "a feltételes csoport kettÅ‘nél több ágat tartalmaz" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "a (?( után kijelentésnek kellene állnia" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "a (?R vagy (?[+-]számjegyek elemeket )-nek kell követnie" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "ismeretlen POSIX osztálynév" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "a POSIX leválogató elemek nem támogatottak" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "a \\x{...} sorozaton belüli karakterérték túl nagy" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "érvénytelen feltétel: (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "A \\C nem engedélyezett a lookbehind kijelentésben" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "a \\L, \\l, \\N{name}, \\U és \\u escape-sorozatok nem támogatottak" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "a rekurzív hívás végtelen ciklushoz vezethet" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "ismeretlen karakter a (?P után" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "hiányzó befejezÅ‘ az alminta nevében" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "két elnevezett alminta neve azonos" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "rosszul formázott \\P vagy \\p sorozat" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "ismeretlen tulajdonságnév a \\P vagy \\p után" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "az alminta neve túl hosszú (legfeljebb 32 karakter)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "túl sok elnevezett alminta (legfeljebb 10 000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "az oktális érték nagyobb, mint \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "a fordítási munkaterület túlcsordult" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "a korábban ellenÅ‘rzött hivatkozott alminta nem található" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "a DEFINE csoport több ágat tartalmaz" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "inkonzisztens NEWLINE beállítások" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"a \\g után nem egy (szögletes) zárójelezett név, idézÅ‘jelezett név vagy szám " +"vagy egyszerű szám áll" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "számozott hivatkozás nem lehet nulla" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" +"nem engedélyezett argumentum a (*ACCEPT), (*FAIL) vagy (*COMMIT) egyikéhez " +"sem" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ismeretlen" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "a szám túl nagy" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "hiányzó almintanév a (?& után" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "a rendszer számjegyet várt a (?+ után" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "a ] érvénytelen adatkarakter JavaScript kompatibilitási módban" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ugyanazon szám almintáihoz nem engedélyezettek különbözÅ‘ nevek" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "a (*MARK) után argumentumnak kell állnia" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "a \\c után ASCII karakternek kell állnia" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "a \\k után nem egy (szögletes) zárójelezett vagy idézÅ‘jelezett név áll" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "a \\N nem támogatott osztályban" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "túl sok elÅ‘re hivatkozás" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "a név túl hosszú a (*MARK), (*PRUNE), (*SKIP) vagy (*THEN) egyikében" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "a \\u.... sorozaton belüli karakterérték túl nagy" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Hiba a(z) %s reguláris kifejezés illesztésekor: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "A PRCE programkönyvtár UTF-8 támogatás nélkül lett fordítva" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"A PRCE programkönyvtár az UTF-8 tulajdonságok támogatása nélkül lett fordítva" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "A PRCE programkönyvtár inkompatibilis beállításokkal lett fordítva" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Hiba a(z) %s reguláris kifejezés optimalizálásakor: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"Hiba a(z) „%s†reguláris kifejezés fordításakor a(z) %d. karakternél: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "a program hexadecimális számjegyet vagy „}†jelet várt" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "a program hexadecimális számjegyet várt" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "hiányzó „<†jel a szimbolikus hivatkozásban" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "befejezetlen szimbolikus hivatkozás" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "nulla hosszúságú szimbolikus hivatkozás" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "re rendszer számjegyet várt" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "illegális szimbolikus hivatkozás" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "a záró „\\†helye nem megfelelÅ‘" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "ismeretlen escape sorozat" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Hiba a(z) „%s†helyettesítÅ‘szöveg elemzésekor a(z) %lu. karakternél: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Az idézett szöveg nem idézÅ‘jellel kezdÅ‘dik" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Pár nélküli idézÅ‘jel a parancssorban vagy más, parancsértelmezÅ‘bÅ‘l idézett " +"szövegben" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "A szöveg egy „\\†karakter után véget ért. (A szöveg: „%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"A szöveg véget ért, mielÅ‘tt %c idézÅ‘jelpárja meglett volna. (A szöveg: „%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "" +"A szöveg üres volt (vagy legfeljebb üres hely karaktereket tartalmazott)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Nem sikerült adatokat olvasni a gyermekfolyamatból (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Váratlan hiba egy gyermekfolyamatból történÅ‘ adatolvasás közben (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Váratlan hiba a waitpid()-ben (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "A gyermekfolyamat a következÅ‘ kóddal lépett ki: %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "A gyermekfolyamat kilÅ‘ve %ld szignállal" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "A gyermekfolyamat megállítva %ld szignállal" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "A gyermekfolyamat abnormálisan lépett ki" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Nem sikerült olvasni a gyermek csÅ‘vezetékbÅ‘l (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Nem sikerült a(z) „%s†gyermekfolyamat végrehajtása (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Nem sikerült folyamatot indítani (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Nem sikerült átváltani a(z) „%s†könyvtárra (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Nem sikerült a gyermekfolyamat („%sâ€) végrehajtása (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Nem sikerült megnyitni a fájlt a fájlleíró ismételt leképezéséhez (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Nem sikerült kettÅ‘zni a gyermekfolyamat fájlleíróját (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Nem sikerült a gyermekfolyamat elindítása (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Nem sikerült lezárni a gyermekfolyamat fájlleíróját (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Ismeretlen hiba a gyermekfolyamat („%sâ€) végrehajtásakor" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Nem sikerült elég adatot kiolvasni a gyermek pid csÅ‘vezetékbÅ‘l (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Nem sikerült adatokat kiolvasni a gyermekfolyamatból" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Nem sikerült végrehajtani a gyermekfolyamatot (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Nem sikerült a dup() hívás a gyermekfolyamatban (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Érvénytelen programnév: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Érvénytelen karaktersorozat a paraméterben a következÅ‘ helyen: %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Érvénytelen karaktersorozat a környezetben: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Érvénytelen munkakönyvtár: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Nem sikerült végrehajtani a segítÅ‘ programot (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Váratlan hiba, miközben a g_io_channel_win32_poll() adatokat olvasott egy " +"gyermekfolyamatból" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Az üres karakterlánc nem szám" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s†nem érvényes név" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "A(z) „%s†a(z) [%s, %s] intervallumon kívül esik." + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s†nem érvényes név" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Érvénytelen %-kódolás az URI-ban" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Nem megengedett karakter az URI-ban" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Nem UTF-8 karakterek az URI-ban" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Érvénytelen „%.*s†IPv6-cím az URI-ban" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Nem megengedett „%.*s†kódolt IP-cím az URI-ban" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nem megengedett „%.*s†nemzetköziesített gépnév az URI-ban" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "A(z) „%.*s†port nem dolgozható fel az URI-ban" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Az URI-ban lévÅ‘ „%.*s†port a tartományon kívülre esik" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "A(z) „%s†URI nem abszolút URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "A(z) „%s†URI-ban nincs gép összetevÅ‘" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "Az URI nem abszolút, és alap URI nem lett megadva" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Hiányzó „=†és paraméterérték" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Nem sikerült memóriát lefoglalni" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "A karakter az UTF-8 tartományon kívülre esik" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Érvénytelen sorozat az átalakítási bemenetben" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "A karakter az UTF-16 tartományon kívülre esik" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bájt" +msgstr[1] "%u bájt" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bájt" +msgstr[1] "%s bájt" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bit" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" diff --git a/po/hy.po b/po/hy.po new file mode 100644 index 0000000..ef07051 --- /dev/null +++ b/po/hy.po @@ -0,0 +1,3956 @@ +# Translation of glib to Armenian +# This file is distributed under the same license as the glib package. +# Copyright (C) 2010, Karo Mkrtchyan +# Karo Mkrtchyan <020113@mail.ru> +# +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2010-08-31 16:47+0400\n" +"Last-Translator: Nune \n" +"Language-Team: Armenian \n" +"Language: hy\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" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "'%s' Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿ '%s' Õ¿Õ¡Ö€Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Õ‰Õ£Õ¿Õ¶Õ¾Õ¥Ö '%s' Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿ %s' Õ¿Õ¡Ö€Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Ô±Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« '%s' Õ¿Õ¥Õ£, Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ '%s Õ¿Õ¥Õ£Õ¨" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Ô±Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« '%s' Õ¿Õ¥Õ£ '%s' -Õ« Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ£Õ¿Õ¶Õ¥Õ¬ Õ§Õ»Õ¡Õ¶Õ«Õ· Ö†Õ¡ÕµÕ¬ Õ¸Ö€Õ¸Õ¶Õ´Õ¡Õ¶ ÕºÕ¡Õ¶Õ¡Õ¯Õ¶Õ¥Ö€Õ¸Ö‚Õ´" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s' -Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ¡Ö€Õ¤Õ¥Õ¶ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¸Ö‚Õ¶Õ« Õ§Õ»Õ¡Õ¶Õ«Õ·" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s' -Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ§Õ»Õ¡Õ¶Õ«Õ· Õ£Õ¿Õ¶Õ¾Õ¡Õ® Õ¹Õ§" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s' Õ« Õ§Õ»Õ¡Õ¶Õ«Õ·Õ¸Ö‚Õ´ Õ£Õ¿Õ¶Õ¾Õ¡Õ® Õ¹Õ§ MIME Õ¿Õ¥Õ½Õ¡Õ¯" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s' Õ« Õ§Õ»Õ¡Õ¶Õ«Õ·Õ¸Ö‚Õ´ Õ£Õ¿Õ¶Õ¾Õ¡Õ® Õ¹Õ§ Õ¶Õ·Õ¸Ö‚Õ´ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ« Õ£Õ¡Õ¿Õ²Õ¶Õ«Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¡Õ½Õ«Õ¶" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s' Õ« Õ§Õ»Õ¡Õ¶Õ«Õ·Õ¸Ö‚Õ´ Õ£Õ¿Õ¶Õ¾Õ¡Õ® Õ¹Õ§ Õ­Õ´Õ¢Õ¥Ö€Õ« Õ¢Õ¡Õ¦Õ´Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ " + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" +"Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ¡Õ¶Õ¸Ö‚Õ¶Õ¸Õ¾ Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ®Ö€Õ¡Õ£Õ«Ö€Õ Õ¸Ö€Õ¶ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ§Õ»Õ¡Õ¶Õ«Õ· '%s' -Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¬Ö€Õ¡ÖÕ¶Õ¥Õ¬'%s' Õ¯Õ¡Õ¿Õ¡Ö€Õ´Õ¡Õ¶ Õ¿Õ¸Õ²Õ¨ %s URI -Õ« Õ´Õ«Õ»Õ¸ÖÕ¸Õ¾" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Õ†Õ·Õ¡Õ¶Õ¶Õ¥Ö€Õ« '%s' Õ¢Õ¡Õ¦Õ´Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ«Ö '%s' ÖƒÕ¸Õ­Õ¡Ö€Õ¯Õ¸Ö‚Õ´ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´Ö‰" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ¢Õ¡ÖÕ¥Õ¬ '%s' -Õ«Ö '%s' ÖƒÕ¸Õ­Õ¡Ö€Õ¯Õ«Õ¹" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Õ“Õ¸Õ­Õ¡Ö€Õ¯Õ´Õ¡Õ¶ Õ´Õ¸Ö‚Õ¿Ö„Õ¸Ö‚Õ´ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¢Õ¡ÕµÕ©Õ¥Ö€Õ« Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ " + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "ÕÕ­Õ¡Õ¬ ÖƒÕ¸Õ­Õ¡Ö€Õ¯Õ´Õ¡Õ¶ Õ¨Õ¶Õ©Õ¡Öքում․ %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Õ„Õ¸Ö‚Õ¿Ö„Õ« Õ¾Õ¥Ö€Õ»Õ¸Ö‚Õ´ Õ¶Õ·Õ¡Õ¶Õ¶Õ¥Ö€Õ« Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ« Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ³Õ·Õ£Ö€Õ«Õ¿ ÖƒÕ¸Õ­Õ¡Ö€Õ¯Õ¥Õ¬ «%s» Õ¶Õ«Õ·Õ¨ «%s» Õ¶Õ«Õ·Õ¥Ö€Õ« Õ°Õ¡Õ¾Õ¡Ö„Õ¡Õ®Õ¸Ö‚Õ« Õ¸Ö€Ö‡Õ§ Õ¶Õ«Õ·Õ«" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" +"URI '%s' Õ¹Õ« Õ°Õ¡Õ¶Õ¤Õ«Õ½Õ¡Õ¶Õ¸Ö‚Õ´ Õ¢Õ¡ÖÕ¡Ö€Õ±Õ¡Õ¯ URI \"file\" Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ« Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "'%s' Õ¿Õ¥Õ²Õ¡ÕµÕ«Õ¶ Ö†Õ¡ÕµÕ¬Õ« URI -Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥Õ¬ '#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ°Õ¸Õ½Õ©Õ« Õ¡Õ¶Õ¸Ö‚Õ¶ '%s' -Õ¸Ö‚Õ´" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ§Õ¯Ö€Õ¡Õ¶Õ¡Õ¾Õ¸Ö€Õ¸Õ² Õ¶Õ«Õ·Õ¥Ö€" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "ÕƒÕ¡Õ¶Õ¡ÕºÕ¡Ö€Õ°Õ« '%s' Õ¡Õ¶Õ¾Õ¡Õ¶Õ¸Ö‚Õ´Õ¨ Õ¢Õ¡ÖÕ¡Ö€Õ±Õ¡Õ¯ Õ¹Õ§" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ°Õ¸Õ½Õ©Õ« Õ¡Õ¶Õ¸Ö‚Õ¶ " + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %r %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%r" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Õ€Õ¸Ö‚Õ¶Õ¾Õ¡Ö€Õ«" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Õ“Õ¥Õ¿Ö€Õ¾Õ¡Ö€Õ«" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Õ„Õ¡Ö€Õ¿Õ«" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "Ô±ÕºÖ€Õ«Õ¬Õ«" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Õ„Õ¡ÕµÕ«Õ½Õ«" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Õ€Õ¸Ö‚Õ¶Õ«Õ½Õ«" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Õ€Õ¸Ö‚Õ¬Õ«Õ½Õ«" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Õ€Õ¶Õ¾" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Õ“Õ¿Ö€" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Õ„Õ¡Ö€" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Ô±ÕºÖ€" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Õ„Õ¡Õµ" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Õ€Õ¶Õ½" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Õ€Õ¬Õ½" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "ÔµÖ€Õ¯Õ¸Ö‚Õ·Õ¡Õ¢Õ©Õ«" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "ÔµÖ€Õ¥Ö„Õ·Õ¡Õ¢Õ©Õ«" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Õ‰Õ¸Ö€Õ¥Ö„Õ·Õ¡Õ¢Õ©Õ«" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Õ€Õ«Õ¶Õ£Õ·Õ¡Õ¢Õ©Õ«" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "ÕˆÖ‚Ö€Õ¢Õ¡Õ©" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Õ‡Õ¡Õ¢Õ¡Õ©" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Ô¿Õ«Ö€Õ¡Õ¯Õ«" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ÔµÖ€Õ¯" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ÔµÖ€Ö„" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Õ‰Ö€Ö„" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Õ€Õ¶Õ£" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ÕˆÖ‚Ö€" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Õ‡Õ¢Õ©" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Ô¿Ö€Õ¯" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "'%s' ÕºÕ¡Õ¶Õ¡Õ¯Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ¸Ö‚ Õ½Õ­Õ¡Õ¬Õ %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ¾Õ¸Ö‚Õ´ Õ°Õ¡Õ¿Õ¯Õ¡ÖÕ¶Õ¥Õ¬ %lu Õ¢Õ¡ÕµÕ© \"%s\" Ö†Õ¡ÕµÕ¬Õ¨ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ Õ½Õ­Õ¡Õ¬Õ %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "\"%s\" Ö†Õ¡ÕµÕ¬Õ¨ Õ¹Õ¡ÖƒÕ¡Õ¦Õ¡Õ¶Ö Õ´Õ¥Õ® Õ§" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¸Ö‚Õ´ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ«ÖÕ %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¢Õ¡ÖÕ¥Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ¨Õ %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" +"Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ½Õ¿Õ¡Õ¶Õ¡Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ« Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ¶Õ¥Ö€Õ¨ ․ ÕÕ¡Õ­Õ¸Õ²Õ¸Ö‚Õ´ fstat() Ö†Õ¸Ö‚Õ¶Õ¯Öիայում․ %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¢Õ¡ÖÕ¥Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ¨Õ fdopen() Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥ÖÕ %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¾Õ¥Ö€Õ¡Õ¶Õ¾Õ¡Õ¶Õ¥Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ¸Ö€ÕºÕ¥Õ½ '%s'Õ g_rename() Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥ÖÕ %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ Ö†Õ¡ÕµÕ¬ '%s'Õ %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¢Õ¡ÖÕ¥Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ£Ö€Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€Õ fdopen() Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥Õ¬ Õ§Õ %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ¸Õ²Õ¾Õ¥Õ¬ Õ£Ö€Õ¥Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ fwrite() Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥ÖÕ %s" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ£Ö€Õ¥Õ¬ '%s' ֆայլը․ fflush() -Õ¨ Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥Ö․ %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ£Ö€Õ¥Õ¬ '%s' ֆայլը․ fsync() -Õ¨ Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥Ö․ %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ¾Õ¥Õ¬ ÖƒÕ¡Õ¯Õ¥Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ¨Õ fclose() Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥ÖÕ %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "'%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¾Õ¥Ö€Õ¡ÖÕ¾Õ¥Õ¬Õ g_unlink() Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥ÖÕ %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "'%s' Õ±Ö‡Õ¡Õ¶Õ´Õ¸Ö‚Õ·Õ¨ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§, Õ¡ÕµÕ¶ ÕºÕ¥Õ¿Ö„ Õ§ Õ¹ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ« '%s'" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "'%s' Õ±Ö‡Õ¡Õ¶Õ´Õ¸Ö‚Õ·Õ¨ Õ¹Õ« ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f Ô¿Ô²" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f Õ„Ô²" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f Ô³Ô²" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f ÕÔ²" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f ÕŠÔ²" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f ÔµÔ²" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f Ô¿Ô²" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Õ„Ô²" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Ô³Ô²" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ÕÔ²" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ÕŠÔ²" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ÔµÔ²" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f Ô¿Ô²" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ '%s' Õ½Õ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ¸Ö‚Õ´Õ¨Õ %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "ÕÕ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¨ Õ¹Õ¥Õ¶ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ¢Õ¡ÖÕ¥Õ¬ '%s' Õ«Ö '%s' ÖƒÕ¸Õ­Õ¡Ö€Õ¯Õ«Õ¹: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string Ö†Õ¸Ö‚Õ¶Õ¯ÖÕ«Õ¡ÕµÕ¸Ö‚Õ´ Õ¸Ö‚Õ²Õ²Õ¡Õ¯Õ« Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ Õ°Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ¹Õ§ " + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Ô¿Õ¡Ö€Õ¤Õ¡ÖÕ¸Õ² Õ¢Õ¸Ö‚Ö†Õ¥Ö€Õ¸Ö‚Õ´ Õ´Õ¶Õ¡ÖÕ¥Õ¬ Õ¥Õ¶ Õ¹ÖƒÕ¸Õ­Õ¡Ö€Õ¯Õ¾Õ¡Õ® Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Ô¿Õ¡ÕºÕ¸Ö‚Õ²Õ«Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¸Ö‚Õ´ Õ§ Õ©Õ¥Ö€Õ« Õ¶Õ«Õ·Õ¸Õ¾" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end Ö†Õ¸Ö‚Õ¶Õ¯ÖÕ«Õ¡ÕµÕ¸Ö‚Õ´ Õ¸Ö‚Õ²Õ²Õ¡Õ¯Õ« Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ Õ°Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ¹Õ§ " + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¢Õ¡ÖÕ¥Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ¨Õ open() Õ­Õ¡ÖƒÕ¡Õ¶Õ¾Õ¥ÖÕ %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö ÖÕ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ '%s' Ö†Õ¡ÕµÕ¬Õ¨ ․ ÕÕ¡Õ­Õ¸Õ²Õ¸Ö‚Õ´ mmap() Ö†Õ¸Ö‚Õ¶Õ¯Öիայում․ %s " + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "ÕÕ­Õ¡Õ¬ %d Õ¿Õ¸Õ²Õ« %d նիշում․" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "ÕÕ­Õ¡Õ¬ UTF-8 Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ¾Õ¡Õ® Õ¿Õ¥Ö„Õ½Õ¿ Õ¡Õ¶Õ¾Õ¡Õ¶ Õ´Õ¥Õ» - Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ '%s'" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "'%s' Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶ " + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "'%s' Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶ ․ '%c' " + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "ÕÕ­Õ¡Õ¬ %d Õ¿Õ¸Õ²Õ¸Ö‚Õ´Õ %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¥Õ¬ '%-.*s' -Õ¨, Õ¸Ö€Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ¬Õ«Õ¶Õ« Õ©Õ«Õ¾Õ Õ¶Õ«Õ·Õ« Õ¾Ö€Õ¡ Õ°Õ²Õ´Õ¡Õ¶ Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´ " +"(Õ•Ö€Õ«Õ¶Õ¡Õ¯Õ ê) -" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Õ†Õ«Õ·Õ« Õ°Õ²Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¸Ö‚Õ´ Õ¯Õ¥Õ¿-Õ½Õ¿Õ¸Ö€Õ¡Õ¯Õ¥Õ¿Õ¸Õ¾; Õ¡Õ´Õ¥Õ¶Õ¡ÕµÕ¶ Õ°Õ¡Õ¾Õ¡Õ¶Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ¤Õ¸Ö‚Ö„ " +"Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ¥Ö„" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "'%-.*s' Õ¶Õ«Õ·Õ« Õ¾Ö€Õ¡ Õ°Õ²Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ¡ÕµÕ¬Õ¡Õ£Ö€Õ¸Ö‚Õ´ Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¶Õ«Õ·" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Õ€Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¥Õ¬ Õ§ Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ¯Õ¡Õ¼Õ¸Ö‚ÖÕ¾Õ¡Õ®Ö„ '&;' , Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¯Õ¡Õ¼Õ¸Ö‚ÖÕ¾Õ¡Õ®Ö„Õ¶Õ¥Ö€Õ¶ են․ " +"& " < > '" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "'%-.*s' Õ¯Õ¡Õ¼Õ¸Ö‚ÖÕ¾Õ¡Õ®Ö„Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ°Õ¡ÕµÕ¿Õ¶Õ« Õ¹Õ§" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Ô¿Õ¡Õ¼Õ¸Ö‚ÖÕ¾Õ¡Õ®Ö„Õ¨ Õ¹Õ« Õ¾Õ¥Ö€Õ»Õ¡Õ¶Õ¸Ö‚Õ´ Õ¯Õ¥Õ¿-Õ½Õ¿Õ¸Ö€Õ¡Õ¯Õ¥Õ¿Õ¸Õ¾; Õ°Õ¡Õ¾Õ¡Õ¶Õ¡Õ¢Õ¡Ö€ «&» Õ¶Õ«Õ·Õ¨ Õ¹Õ« Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¾Õ¥Õ¬ " +"Õ¯Õ¡Õ¼Õ¸Ö‚ÖÕ¾Õ¡Õ®Ö„Õ«" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ½Õ¯Õ½Õ¾Õ« Õ¸Ö€Ö‡Õ§ Õ§Õ¬Õ§Õ´Õ¥Õ¶Õ¿Õ¸Õ¾ (Ö…Ö€Õ«Õ¶Õ¡Õ¯ )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' Õ¶Õ«Õ·Õ¨ Õ°Õ¡Õ¶Õ¤Õ«Õ½Õ¡Õ¶Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ '<' Õ¶Õ«Õ·Õ«Ö Õ°Õ¥Õ¿Õ¸; Õ¿Õ¡Ö€Ö€Õ« Õ¡Õ¶Õ¾Õ¡Õ¶Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² " +"Õ½Õ¯Õ½Õ¾Õ¥Õ¬ Õ¡ÕµÕ¤ Õ¶Õ«Õ·Õ¸Õ¾" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Õ€Õ¡Õ¶Õ¤Õ«ÕºÕ¥Ö '%s' Õ¡Õ¾Õ¥Õ¬Õ¸Ö€Õ¤ Õ¶Õ«Õ·Õ¨, Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ '>' Õ¶Õ«Õ·Õ¨ '%s' Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ¿Õ¥Õ£Õ« ÖƒÕ¡Õ¯Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Õ€Õ¡Õ¶Õ¤Õ«ÕºÕ¥Ö '%s' Õ¡Õ¾Õ¥Õ¬Õ¸Ö€Õ¤ Õ¶Õ«Õ·Õ¨ , Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ '=' Õ¶Õ«Õ·Õ¨ '%s' Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¾Õ¡Õ¶Õ¸Ö‚Õ´Õ«Ö " +"Õ°Õ¥Õ¿Õ¸, Õ¸Ö€Õ¨ ÕºÕ¡Õ¿Õ¯Õ¡Õ¶Õ¸Ö‚Õ´ Õ§ '%s' Õ¿Õ¡Ö€Ö€Õ«Õ¶" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Õ€Õ¡Õ¶Õ¤Õ«ÕºÕ¥Ö '%s' Õ¡Õ¾Õ¥Õ¬Õ¸Ö€Õ¤ Õ¶Õ«Õ·Õ¨, Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ '>' Õ¯Õ¡Õ´ '/' Õ¶Õ«Õ·Õ¨ '%s' Õ¿Õ¡Ö€Ö€Õ« Õ¢Õ¡ÖÕ¾Õ¸Õ² " +"Õ¿Õ¥Õ£Õ« ÖƒÕ¡Õ¯Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€," + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Õ€Õ¡Õ¶Õ¤Õ«ÕºÕ¥Ö '%s' Õ¡Õ¾Õ¥Õ¬Õ¸Ö€Õ¤ Õ¶Õ«Õ·Õ¨, Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ Õ¢Õ¡ÖÕ¾Õ¸Õ² Õ¹Õ¡Õ¯Õ¥Ö€Õ¿ Õ°Õ¡Õ¾Õ¡Õ½Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¶Õ·Õ¡Õ¶Õ«Ö " +"Õ°Õ¥Õ¿Õ¸, Õ¥Ö€Õ¢ '%s' Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ«Õ¶ Õ¿Ö€Õ¾Õ¸Ö‚Õ´ Õ§ Õ¡Ö€ÕªÕ¥Ö„ «%s» Õ¿Õ¡Ö€Ö€Õ¸Ö‚Õ´" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' Õ¶Õ«Õ·Õ¨ Õ°Õ¡Õ¶Õ¤Õ«Õ½Õ¡Õ¶Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ ÖƒÕ¡Õ¯Õ¸Õ² Õ¿Õ¡Ö€Ö€Õ« «%s» Õ¡Õ¶Õ¾Õ¡Õ¶Õ¸Ö‚Õ´Õ«Ö Õ°Õ¥Õ¿Õ¸; " +"Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¡Ö€ÕªÕ¥Ö„Õ¶ Õ§ '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "'%s' Õ¿Õ¡Ö€Ö€Õ¨ ÖƒÕ¡Õ¯Õ¾Õ¡Õ® Õ§, Õ¶Õ¥Ö€Õ¯Õ¡ ÕºÕ¡Õ°Õ«Õ¶ Õ¸Õ¹ Õ´Õ« Õ¿Õ¡Ö€Ö€ Õ¢Õ¡ÖÕ¾Õ¡Õ® Õ§Õ¹" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "'%s' Õ¿Õ¡Ö€Ö€Õ¨ ÖƒÕ¡Õ¯Õ¾Õ¡Õ® Õ§, Õ¢Õ¡ÕµÖ Õ¶Õ¥Ö€Õ¯Õ¡ ÕºÕ¡Õ°Õ«Õ¶ Õ¢Õ¡ÖÕ¾Õ¡Õ® Õ°Õ¡Õ´Õ¡Ö€Õ¾Õ¸Ö‚Õ´ Õ§ '%s' Õ¿Õ¡Ö€Ö€Õ¨ " + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ§Ö€ Õ¯Õ¡Õ´ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§Ö€ Õ´Õ«Õ¡ÕµÕ¶ Õ¢Õ¡ÖÕ¡Õ¿Õ¶Õ¥Ö€" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö Õ¡Õ¶Õ´Õ«Õ»Õ¡ÕºÕ¥Õ½ Õ¡Õ¶Õ¯ÕµÕ¸Ö‚Õ¶Õ¡Õ±Ö‡ Õ¢Õ¡ÖÕ¸Õ² ÖƒÕ¡Õ¯Õ¡Õ£Õ®Õ«Ö Õ°Õ¥Õ¿Õ¸ " +"'<'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö, Õ¥Ö€Õ¢ Õ¤Õ¥Õ¼ Õ¢Õ¡ÖÕ¾Õ¡Õ® Õ§Õ«Õ¶ Õ¿Õ¡Ö€Ö€Õ¥Ö€Õ¨ - '%s' -Õ¨ " +"Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ¢Õ¡ÖÕ¾Õ¡Õ® Õ¿Õ¡Ö€Ö€Õ¶ Õ§" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö, Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ <%s/> Õ¿Õ¥Õ£Õ« Õ¡Õ¾Õ¡Ö€Õ¿Õ¨ Õ¶Õ·Õ¸Õ² ÖƒÕ¡Õ¯Õ¸Õ² " +"Õ¡Õ¶Õ¯ÕµÕ¸Ö‚Õ¶Õ¡Õ±Ö‡ ÖƒÕ¡Õ¯Õ¡Õ£Õ«Õ®" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö Õ¿Õ¡Ö€Ö€Õ« Õ¡Õ¶Õ¾Õ¡Õ¶ Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¾Õ¡Õ¶ Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö Õ§Õ¬Õ¥Õ´Õ¥Õ¶Õ¿Õ¨ Õ¢Õ¡ÖÕ¸Õ² Õ¿Õ¥Õ£Õ« Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¾Õ¡Õ¶Õ¨ Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¸Õ² Õ°Õ¡Õ¾Õ¡Õ½Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ " +"Õ¶Õ·Õ¡Õ¶Õ«Ö Õ°Õ¥Õ¿Õ¸ ;Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¸Ö€Õ¸Õ·Õ¾Õ¡Õ® Õ¹Õ§" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Ö€ÕªÕ¥Ö„Õ« Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö '%s' Õ¿Õ¡Ö€Ö€Õ¨ ÖƒÕ¡Õ¯Õ¸Õ² Õ¿Õ¥Õ£Õ« Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ«Õ¸Ö€Õ¥Õ¶ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Ö Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¯Õ¡Õ´ Õ°Ö€Õ¡Õ°Õ¡Õ¶Õ£Õ« Õ´Õ·Õ¡Õ¯Õ´Õ¡Õ¶ " +"Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "Õ¾Õ¶Õ¡Õ½Õ¾Õ¡Õ® Ö…Õ¢ÕµÕ¥Õ¯Õ¿" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "Ô±Ö€Õ¿Õ¡Ö„Õ« Õ½Õ­Õ¡Õ¬ Õ¯Õ¡Õ´ Õ¾Õ¶Õ¡Õ½Õ¾Õ¡Õ® Ö…Õ¢ÕµÕ¥Õ¯Õ¿" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "Õ°Õ«Õ·Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¾Õ¥Ö€Õ»Õ¡ÖÕ¡Õ¾" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "Õ€Õ¡Õ½Õ¥Õ¬ Õ§ Õ°Õ¥Õ¿Õ¡Õ¤Õ¡Ö€Õ± Õ¾Õ¥Ö€Õ¡Õ°Õ½Õ¯Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ«Õ¶" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"Ö…Ö€Õ«Õ¶Õ¡Õ¯Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ¿Õ¡Ö€Ö€Õ¥Ö€, Õ¸Ö€Õ¸Õ¶Ö„ Õ¹Õ¥Õ¶ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´ Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ« Õ°Õ¡Õ´Õ¨Õ¶Õ¯Õ¶Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ« " +"Õ°Õ¡Õ´Õ¡Ö€ " + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "Õ¶Õ¥Ö€Ö„Õ«Õ¶ Õ½Õ­Õ¡Õ¬ " + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"Õ¥Õ¿ Õ°Õ²Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¨, Õ«Õ¶Õ¹ÕºÕ¥Õ½ ÕºÕ¡ÕµÕ´Õ¡Õ¶Õ¶Õ¥Ö€Õ¨ Õ¹Õ¥Õ¶ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´ Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ« Õ°Õ¡Õ´Õ¨Õ¶Õ¯Õ¶Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ " + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "Õ°Õ¡Õ½Õ¥Õ¬ Õ§ Õ¼Õ¥Õ¯Õ¸Ö‚Ö€Õ½Õ«Õ¡ÕµÕ« Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ«Õ¶" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ¥Õ¶Õ©Õ¡Õ¿Õ¸Õ²Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ¿Õ¡Ö€Õ¡Õ®Ö„Õ« Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¨ " + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "Õ¿Õ¸Õ²Õ¡Õ¤Õ¡Ö€Õ±Õ« Õ¤Ö€Õ¸Õ·Õ¶Õ¥Ö€Õ« Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ°Õ¡Õ´Õ¡Õ¯ÖÕ¸Ö‚Õ´" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "Õ‰Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® Õ½Õ­Õ¡Õ¬ " + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ Õ·Õ¡Õ¢Õ¬Õ¸Õ¶Õ« Õ¾Õ¥Ö€Õ»Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c Õ·Õ¡Õ¢Õ¬Õ¸Õ¶Õ« Õ¾Õ¥Ö€Õ»Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ³Õ¡Õ¶Õ¡Õ¹Õ¥Õ¬Õ« Õ¿Õ¡Ö€Ö€ \\" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" +"Õ¼Õ¥Õ£Õ«Õ½Õ¿Ö€Õ« ÖƒÕ¸ÖƒÕ¸Õ­Õ´Õ¡Õ¶ Õ§Õ¯Ö€Õ¡Õ¶Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´Õ¶ (\\l, \\L, \\u, \\U) Õ¡ÕµÕ½Õ¿Õ¥Õ² Õ¡Ö€Õ£Õ¥Õ¬Õ¾Õ¡Õ® Õ§ " + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "Ô¹Õ¾Õ¥Ö€Õ« Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ {} Ö„Õ¾Õ¡Õ¶Õ¿Õ¸Ö€Õ¸Ö‚Õ´ Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "Õ‰Õ¡Õ±Õ¡Õ¦Õ¡Õ¶Ö Õ´Õ¥Õ® Õ©Õ«Õ¾ Ö„Õ¾Õ¡Õ¶Õ¿Õ¸Ö€Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ ÖƒÕ¡Õ¯Õ¸Õ² ] Õ¶Õ«Õ·Õ¥Ö€Õ« Õ¤Õ¡Õ½Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§Õ¯Ö€Õ¡Õ¶Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´ Õ¿Õ¡Ö€Ö€Õ¥Ö€Õ« Õ¤Õ¡Õ½Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "ÕÕ¡Ö€Ö€Õ¥Ö€Õ« Õ¤Õ¡Õ½Õ¸Ö‚Õ´ Õ´Õ«Õ»Õ¡Õ¯Õ¡ÕµÖ„Õ¨ Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "Õ¸Õ¹Õ«Õ¶Õ¹ Õ¹Õ¯Õ¡ Õ¯Ö€Õ¯Õ¶Õ¥Õ¬Õ¸Ö‚" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "Õ¡Õ¶Õ³Õ¡Õ¶Õ¡Õ¹Õ¥Õ¬Õ« Õ¿Õ¡Ö€Ö€ (? -Õ«Ö Õ°Õ¥Õ¿Õ¸" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "Õ¡Õ¶Õ³Õ¡Õ¶Õ¡Õ¹Õ¥Õ¬Õ« Õ¿Õ¡Ö€Ö€ (?< -Õ«Ö Õ°Õ¥Õ¿Õ¸" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "Õ¡Õ¶Õ³Õ¡Õ¶Õ¡Õ¹Õ¥Õ¬Õ« Õ¿Õ¡Ö€Ö€ (?P -Õ«Ö Õ°Õ¥Õ¿Õ¸" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX Õ¤Õ¡Õ½Õ« ÖƒÕ¸ÖƒÕ¸Õ­Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¡Õ® Õ§ Õ´Õ«Õ¡ÕµÕ¶ Õ¤Õ¡Õ½Õ« Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ ÖƒÕ¡Õ¯Õ¾Õ¸Õ² ÖƒÕ¡Õ¯Õ¡Õ£Õ«Õ®Õ¨ )" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") Õ¡Õ¼Õ¡Õ¶Ö Õ¢Õ¡ÖÕ¾Õ¸Õ² ÖƒÕ¡Õ¯Õ¡Õ£Õ®Õ« (" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R Õ¯Õ¡Õ´ (?[+-] Õ©Õ¾Õ¥Ö€Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¥Õ¶ )-Õ«Õ¶" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "Õ€Õ²Õ¸Ö‚Õ´ Õ¤Õ¥ÕºÕ« Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ¥ÖÕ¸Õ² Õ¥Õ¶Õ©Õ¡Õ·Õ¡Õ¢Õ¬Õ¸Õ¶" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ ) Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ«Ö Õ°Õ¥Õ¿Õ¸" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "Õ¡Õ¶Õ¹Õ¡Öƒ Õ´Õ¥Õ® Õ¯Õ¡Õ¶Õ¸Õ¶Õ¡Õ¾Õ¸Ö€ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "Õ¹Õ½Õ¿Õ¡ÖÕ¾Õ¥Ö Õ½Õ¿Õ¡Õ¶Õ¡Õ¬ Õ°Õ«Õ·Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind - Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¸Ö‚Õ´Õ¨ Õ¹Õ¸Ö‚Õ¶Õ« Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¸Ö‚Õ¶ Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "ÕÕ­Õ¡Õ¬ Õ©Õ«Õ¾ Õ¯Õ¡Õ´ Õ¡Õ¶Õ¸Ö‚Õ¶ (?( -Õ«Ö Õ°Õ¥Õ¿Õ¸" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "ÕŠÕ¡ÕµÕ´Õ¡Õ¶Õ¡Õ¯Õ¡Õ¶ Õ­Õ¸Ö‚Õ´Õ¢Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ¥Ö€Õ¯Õ¸Ö‚Õ½Õ«Ö Õ¡Õ¾Õ¥Õ¬ Õ³ÕµÕ¸Ö‚Õ²Õ¥Ö€" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¸Ö‚Õ´ (?( -Õ«Ö Õ°Õ¥Õ¿Õ¸" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "Õ‰Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® POSIX Õ¤Õ¡Õ½Õ« Õ¡Õ¶Õ¸Ö‚Õ¶ " + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "POSIX Õ¿Õ¥Õ½Õ¡Õ¯Õ¡Õ¾Õ¸Ö€Õ¸Õ² Õ¿Õ¡Ö€Ö€Õ¥Ö€Õ¨ Õ¹Õ¥Õ¶ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "Õ¶Õ«Õ·Õ« Õ¡Ö€ÕªÕ¥Ö„ \\x{...} Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¸Ö‚Õ´ Õ¹Õ¡ÖƒÕ¡Õ¦Õ¡Õ¶Ö Õ´Õ¥Õ® Õ§" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "Õ½Õ­Õ¡Õ¬ ÕºÕ¡ÕµÕ´Õ¡Õ¶ (?(0)" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "lookbehind - Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¸Ö‚Õ´ Õ¹Õ« Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¾Õ¸Ö‚Õ´ \\C" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "Õ¼Õ¥Õ¯Õ¸Ö‚Ö€Õ½Õ«Õ¾ Õ¯Õ¡Õ¶Õ¹Õ¨ Õ¯Õ¡Ö€Õ¸Õ² Õ§ Õ¯Ö€Õ¯Õ¶Õ¾Õ¥Õ¬ Õ¡Õ¶Õ½Õ¡Õ°Õ´Õ¡Õ¶ Ö„Õ¡Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "Õ¥Õ¶Õ©Õ¡Õ·Õ¡Õ¢Õ¬Õ¸Õ¶Õ« Õ¡Õ¶Õ¾Õ¡Õ¶ Õ´Õ¥Õ» Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ ÖƒÕ¡Õ¯Õ¸Õ² Õ¶Õ«Õ·Õ¨" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "Õ¥Ö€Õ¯Õ¸Ö‚ Õ¡Õ¶Õ¾Õ¡Õ¶Õ¾Õ¡Õ® Õ¥Õ¶Õ©Õ¡Õ·Õ¡Õ¢Õ¬Õ¸Õ¶Õ¶Õ¥Ö€ Õ¸Ö‚Õ¶Õ¥Õ¶ Õ´Õ«Ö‡Õ¶Õ¸Ö‚ÕµÕ¶ Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨v" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "Õ½Õ­Õ¡Õ¬ Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ \\P Õ¯Õ¡Õ´ \\p" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "Õ¹Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¡Õ¶Õ¸Ö‚Õ¶ \\P -Õ«Ö Õ¯Õ¡Õ´ \\p -Õ«Ö Õ°Õ¥Õ¿Õ¸" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "Õ¥Õ¶Õ©Õ¡Õ·Õ¡Õ¢Õ¬Õ¸Õ¶Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ¹Õ¡ÖƒÕ¡Õ¦Õ¡Õ¶Ö Õ¥Ö€Õ¯Õ¡Ö€ Õ§ (32 Õ¶Õ«Õ·Õ«Ö Õ¡Õ¾Õ¥Õ¬ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¬Õ«Õ¶Õ¥Õ¬)" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "Õ¹Õ¡ÖƒÕ¡Õ¦Õ¡Õ¶Ö Õ·Õ¡Õ¿ Õ¡Õ¶Õ¾Õ¡Õ¶Õ¾Õ¡Õ® Õ¥Õ¶Õ©Õ¡Õ·Õ¡Õ¢Õ¬Õ¸Õ¶Õ¶Õ¥Ö€ (Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¬Õ«Õ¶Õ¥Õ¬ 10,000 -Õ«Ö Õ¡Õ¾Õ¥Õ¬Õ«)" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "Õ¸Ö‚Õ©Õ¡Õ¯Õ¡Õ¶ Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ£Õ¥Ö€Õ¡Õ¦Õ¡Õ¶ÖÕ¸Ö‚Õ´ Õ§ \\377" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE Õ­Õ¸Ö‚Õ´Õ¢Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ´Õ¥Õ¯Õ«Ö Õ¡Õ¾Õ¥Õ¬Õ« Õ³ÕµÕ¸Ö‚Õ²Õ¥Ö€ " + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "Ô±Ö€Õ£Õ¥Õ¬Õ¾Õ¡Õ® Õ§ Õ¯Ö€Õ¯Õ¶Õ¥Õ¬ DEFINE Õ­Õ¸Ö‚Õ´Õ¢Õ¨" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "Ô±Õ¶Õ°Õ¡Õ´Õ¡Õ¿Õ¥Õ²Õ¥Õ¬Õ« NEWLINE Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ¶Õ¥Ö€" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" +"\\g -Õ«Õ¶ Õ¹Õ« Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¸Ö‚Õ´ Õ¡Õ¶Õ¸Ö‚Õ¶ ÖƒÕ¡Õ¯Õ¡Õ£Õ®Õ¥Ö€Õ« Õ´Õ¥Õ» Õ¯Õ¡Õ´ Õ¸Õ¹ Õ¢Õ¡ÖÕ¡Õ½Õ¡Õ¯Õ¡Õ¶ Õ©Õ«Õ¾ (Õ°Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ§ " +"ÖƒÕ¡Õ¯Õ¡Õ£Õ®Õ¥Ö€Õ¸Ö‚Õ´)" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "Õ¹Õ½ÕºÕ¡Õ½Õ¾Õ¡Õ® Õ¯Ö€Õ¯Õ¶Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "Õ¯Õ¸Õ¤Õ« Õ£Õ¥Ö€Õ¬ÖÕ¸Ö‚Õ´" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "Õ¯Õ¡Õ¦Õ´Õ¡Õ¯Õ¾Õ¸Õ² Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ¿Õ«Ö€Õ¸Ö‚ÕµÕ©Õ« Õ£Õ¥Ö€Õ¡Õ®Õ¡Õ­Õ½ " + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "Õ¡Ö€Õ¤Õ¥Õ¶ Õ½Õ¿Õ¸Ö‚Õ£Õ¾Õ¡Õ® Õ°Õ²Õ¸Ö‚Õ´Õ¸Õ¾ Õ¥Õ¶Õ©Õ¡Õ·Õ¡Õ¢Õ¬Õ¸Õ¶Õ¨ Õ£Õ¿Õ¶Õ¾Õ¡Õ® Õ¹Õ§" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" +"%s Õ¯Õ¡Õ¶Õ¸Õ¶Õ¡Õ¾Õ¸Ö€ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¥Õ¿ Õ°Õ¡Õ´Õ¨Õ¶Õ¯Õ¶Õ´Õ¡Õ¶ Õ¸Ö€Õ¸Õ¶Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¥Õ¬Õ¥ Õ§ սխալ․ " +"%s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE Õ£Ö€Õ¡Õ¤Õ¡Ö€Õ¡Õ¶Õ¨ Õ¯Õ¡Õ¦Õ´Õ¡Ö€Õ¯Õ¾Õ¡Õ® Õ§ Õ¡Õ¼Õ¡Õ¶Ö UTF8 -Õ« Õ¡Õ»Õ¡Õ¯ÖÕ´Õ¡Õ¶" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE Õ£Ö€Õ¡Õ¤Õ¡Ö€Õ¡Õ¶Õ¨ Õ¯Õ¡Õ¦Õ´Õ¡Ö€Õ¯Õ¾Õ¡Õ® Õ§ Õ¡Õ¼Õ¡Õ¶Ö UTF8 -Õ« Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ´Õ¡Õ¶" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® %s Õ¯Õ¡Õ¶Õ¸Õ¶Õ¡Õ¾Õ¸Ö€ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¯Õ¡Õ¦Õ´Õ¡Ö€Õ¯Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ %d նիշում․ %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "%s Õ¯Õ¡Õ¶Õ¸Õ¶Õ¡Õ¾Õ¸Ö€ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Ö…ÕºÕ¿Õ«Õ´Õ«Õ¦Õ¡ÖÕ´Õ¡Õ¶ սխալ․ %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ Õ¿Õ¡Õ½Õ¶Õ¾Õ¥ÖÕ¡Õ¯Õ¡Õ¶ Õ©Õ«Õ¾ Õ¯Õ¡Õ´ '}' Õ¶Õ«Õ·" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ Õ¿Õ¡Õ½Õ¶Õ¾Õ¥ÖÕ¡Õ¯Õ¡Õ¶ Õ©Õ«Õ¾" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "Õ¶Õ«Õ·Õ¡ÕµÕ«Õ¶ Õ°Õ²Õ¸Ö‚Õ´Õ¸Ö‚Õ´ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ '<'" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "Õ¹Õ¾Õ¥Ö€Õ»Õ¡ÖÕ¡Õ® Õ¶Õ«Õ·Õ¡ÕµÕ«Õ¶ Õ°Õ²Õ¸Ö‚" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "Õ¦Ö€Õ¸ÕµÕ¡Õ¯Õ¡Õ¶ Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ¶Õ«Õ·Õ¡ÕµÕ«Õ¶ Õ°Õ²Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ Õ©Õ«Õ¾" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "Õ¹Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¾Õ¡Õ® Õ¶Õ«Õ·Õ¡ÕµÕ«Õ¶ Õ°Õ²Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "Õ¡Õ¾Õ¥Õ¬Õ¸Ö€Õ¤ '\\' Õ¾Õ¥Ö€Õ»Õ¸Ö‚Õ´" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "Ô±Õ¶Õ°Õ¡ÕµÕ¿ Õ§Õ¯Ö€Õ¡Õ¶Õ¡Õ¾Õ¸Ö€Õ¸Õ² Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" +"ÕÕ¥Õ²Õ« Õ§ Õ¸Ö‚Õ¶Õ¥ÖÕ¥Õ¬ Õ½Õ­Õ¡Õ¬ \"%s\" ÖƒÕ¸Õ­Õ¡Ö€Õ«Õ¶Õ¾Õ¸Õ² Õ¿Õ¥Ö„Õ½Õ¿Õ« Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¥Õ» %lu Õ°Õ¡Õ´Õ¡Ö€Õ« " +"նիշում․ %s " + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" +"ÕÕ¥Õ²Õ« Õ§ Õ¸Ö‚Õ¶Õ¥ÖÕ¥Õ¬ Õ½Õ­Õ¡Õ¬ \"%s\" ÖƒÕ¸Õ­Õ¡Ö€Õ«Õ¶Õ¾Õ¸Õ² Õ¿Õ¥Ö„Õ½Õ¿Õ« Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¥Õ» %lu Õ°Õ¡Õ´Õ¡Ö€Õ« " +"նիշում․ %s " + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Õ€Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® Õ§ Õ¹ÖƒÕ¡Õ¯Õ¾Õ¡Õ® Õ¹Õ¡Õ¯Õ¥Ö€Õ¿ Õ°Ö€Õ¡Õ´Õ¡Õ¶Õ¡Õ¿Õ¸Õ²Õ¸Ö‚Õ´ Õ¯Õ¡Õ´ Õ©Õ¡Õ²Õ¡Õ¶Õ©Õ« Õ¡ÕµÕ¬ Õ¿Õ¥Ö„Õ½Õ¿Õ¸Ö‚Õ´" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" +"ÕÕ¥Ö„Õ½Õ¿Õ¨ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Õ¬ Õ§ '\\' Õ¶Õ«Õ·Õ«Ö Õ¡Õ¶Õ´Õ«Õ»Õ¡ÕºÕ¥Õ½ Õ°Õ¥Õ¿Õ¸Ö‰ (ÕÕ¥Ö„Õ½Õ¿Õ¨ Õ°Õ¥Õ¿Ö‡ÕµÕ¡Õ¬Õ¶ Õ§Ö€ '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"ÕÕ¥Ö„Õ½Õ¿Õ¨ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Õ¬ Õ§ %c -Õ« Õ°Õ¡Õ´Õ¡Ö€ ÖƒÕ¡Õ¯Õ¾Õ¸Õ² ÖƒÕ¡Õ¯Õ¡Õ£Õ«Õ®Õ¨ Õ£Õ¿Õ¶Õ¥Õ¬Õ¸Ö‚Ö Õ¡Õ¼Õ¡Õ»Ö‰ (ÕÕ¥Ö„Õ½Õ¿Õ¨ " +"Õ°Õ¥Õ¿Ö‡ÕµÕ¡Õ¬Õ¶ Õ§Ö€ '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "ÕÕ¥Ö„Õ½Õ¿Õ¨ Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ§Ö€ (Õ¯Õ¡Õ´ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ´Õ«Õ¡ÕµÕ¶ Õ¢Õ¡ÖÕ¡Õ¿Õ¶Õ¥Ö€) " + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ¨ Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ«Ö" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ (%s) Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ« Õ°Õ¥Õ¿ Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ« Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ¨" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ Õ¦Õ¡Õ¾Õ¡Õ¯Õ« (%s) Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ¸Ö‚Ö" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¿Õ¥Õ²Õ¡ÖƒÕ¸Õ­Õ¾Õ¥Õ¬ '%s' ÕºÕ¡Õ¶Õ¡Õ¯ (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¡Õ·Õ­Õ¡Õ¿Õ¡ÖÕ¶Õ¥Õ¬ (%s) Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ¨" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ®Ö€Õ¡Õ£Ö€Õ« անուն․ %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ô±Õ¶Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¿Õ¸Õ² Õ¡Ö€Õ£Õ¸Ö‚Õ´Õ¥Õ¶Õ¿Õ¶Õ¥Ö€Õ« Õ¾Õ¥Õ¯Õ¿Õ¸Ö€Õ« %d Õ°Õ¡Õ´Õ¡Ö€Õ¸Õ¾ տողում․ %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ô±Õ¶Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¿Õ¸Õ² միջավայրում․ %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ô±Õ¶Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ¶Ö„Õ¡ÕµÕ«Õ¶ պանակ․ %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¡Õ·Õ­Õ¡Õ¿Õ¥ÖÕ¶Õ¥Õ¬ (%s) Ö…Õ£Õ¶Õ¡Õ¯Õ¡Õ¶ Õ®Ö€Õ¡Õ£Õ«Ö€Õ¨" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Õ‰Õ¶Õ¡Õ­Õ¡Õ¿Õ¥Õ½Õ¾Õ¡Õ® Õ½Õ­Õ¡Õ¬ g_io_channel_win32_poll()-Õ¸Ö‚Õ´ Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ«Ö Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ«Õ½" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ¨ (%s) Õ¥Õ¶Õ©Õ¡ÕºÕ¸ÖÕ¥Õ½Õ«Ö" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Õ‰Õ¶Õ¡Õ­Õ¡Õ¿Õ¥Õ½Õ¾Õ¡Õ® Õ½Õ­Õ¡Õ¬ select()-Õ¸Ö‚Õ´ (%s) Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ«Ö Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ«Õ½" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Õ‰Õ¶Õ¡Õ­Õ¡Õ¿Õ¥Õ½Õ¾Õ¡Õ® Õ½Õ­Õ¡Õ¬ waitpid()-Õ¸Ö‚Õ´ (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork Ö†Õ¸Ö‚Õ¶Õ¯ÖÕ«Õ¡Õ¶ Õ¡Õ¶Õ°Õ¡Õ»Õ¸Õ² Õ§ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Õ¬ (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¡Õ·Õ­Õ¡Õ¿Õ¥ÖÕ¶Õ¥Õ¬ \"%s\" Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ¨ (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¾Õ¥Ö€Õ¡Õ¸Ö‚Õ²Õ²Õ¸Ö€Õ¤Õ¥Õ¬ (%s) Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ« Õ¶Õ¥Ö€Õ¡Õ®Õ¸Ö‚Õ´Õ¨ Õ¯Õ¡Õ´ Õ¡Ö€Õ¿Õ¡Õ®Õ¸Ö‚Õ´Õ¨" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "fork Ö†Õ¸Ö‚Õ¶ÖÕ«Õ¡ÕµÕ« Õ±Õ¡Õ­Õ¸Õ²Õ¸Ö‚Õ´ Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ« Õ½Õ¿Õ¥Õ²Õ®Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Õ‰Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® Õ½Õ­Õ¡Õ¬ \"%s\" Õ¥Õ¶Õ©Õ¡ÕºÖ€Õ¸ÖÕ¥Õ½Õ« Õ¯Õ¡Õ¿Õ¡Ö€Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ " + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¢Õ¡Õ¾Õ¡Õ¯Õ¡Õ¶Õ¡Õ¹Õ¡Öƒ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ Õ¦Õ¡Õ¾Õ¡Õ¯Õ« Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ¸Ö‚Ö (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Õ†Õ«Õ·Õ¨ Õ¤Õ¸Ö‚Ö€Õ½ Õ§ UTF-8-Õ« Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ«Ö" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Õ“Õ¸Õ­Õ¡Õ¯Õ¥Ö€ÕºÕ´Õ¡Õ¶ Õ´Õ¸Ö‚Õ¿Ö„Õ« Õ¿Õ¸Õ²Õ¸Ö‚Õ´ Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¥Õ¬ Õ§ Õ¡Õ¶Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¿Õ¸Õ²" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Õ†Õ«Õ·Õ¨ Õ¤Õ¸Ö‚Ö€Õ½ Õ§ UTF-16-Õ« Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ«Ö" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Ô¿Õ«Ö€Õ¡Õ¼Õ¸Ö‚Õ´Õ" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Õ•Õ£Õ¶Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Ընտրանքներ․" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ ÕÕ¥Õ¼Õ¶Õ¡Ö€Õ¯Õ« Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Õ‘Õ¸Ö‚ÕµÖ Õ¿Õ¡Õ¬ Ö…Õ£Õ¶Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ¶Õ¥Ö€Õ¨" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Ô±Õ·Õ­Õ¡Õ¿Õ¡Õ®Ö€Õ¡Õ£Ö€Õ« ընտրանքները․" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Õ‰Õ« Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¥Õ¬ '%s' Õ¡Õ´Õ¢Õ¸Õ²Õ»Õ« Õ¡Ö€ÕªÕ¥Ö„Õ¨ %s Õ°Õ¡Õ´Õ¡Ö€" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "'%s' Õ¡Õ´Õ¢Õ¸Õ²Õ» Õ¡Ö€ÕªÕ¥Ö„Õ¨ %s Õ°Õ¡Õ´Õ¡Ö€ Õ¤Õ¸Ö‚Ö€Õ½ Õ§ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ«Ö " + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Õ‰Õ« Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¥Õ¬ '%s' Õ¯Õ¸Õ¿Õ¸Ö€Õ¡Õ¯Õ¡ÕµÕ«Õ¶ Õ¡Ö€ÕªÕ¥Ö„Õ¨ %s Õ°Õ¡Õ´Õ¡Ö€" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "'%s' Õ¯Õ¸Õ¿Õ¸Ö€Õ¡Õ¯Õ¡ÕµÕ«Õ¶ Õ¡Ö€ÕªÕ¥Ö„Õ¨ %s Õ°Õ¡Õ´Õ¡Ö€ Õ¤Õ¸Ö‚Ö€Õ½ Õ§ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ«Ö " + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Ô¸Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ« Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ½Õ­Õ¡Õ¬ %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Ô²Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ %s-Õ« Õ¡Ö€Õ£Õ¸Ö‚Õ´Õ¥Õ¶Õ¿Õ¨" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Ô±Õ¶Õ°Õ¡ÕµÕ¿ Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„ %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "Ô¹Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ Õ¹Õ« Õ£Õ¿Õ¶Õ¾Õ¥Õ¬ Õ¸Ö€Õ¸Õ¶Õ´Õ¡Õ¶ ÕºÕ¡Õ¶Õ¡Õ¯Õ¶Õ¥Ö€Õ¸Ö‚Õ´" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ Õ¯Õ¡Õ¶Õ¸Õ¶Õ¡Õ¾Õ¸Ö€ Õ¹Õ«" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ§" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ '%s' Õ¿Õ¸Õ²Õ¨ , Õ¸Ö€Õ¨ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«-Õ¡Ö€ÕªÕ¥Ö„ Õ¦Õ¸Ö‚ÕµÕ£, Õ­Õ¸Ö‚Õ´Õ¢ " +"Õ¯Õ¡Õ´ Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ§" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ô½Õ´Õ¢Õ« Õ¡Õ¶Õ¾Õ¡Õ¾Õ¡Ö€ անվանում․ %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Ô²Õ¡Õ¶Õ¡Õ¬Õ¶Õ¥Ö€Õ«Õ« Ö†Õ¡ÕµÕ¬Õ¨ Õ¹Õ« Õ½Õ¯Õ½Õ¾Õ¥Õ¬ Õ­Õ´Õ¢Õ« Õ°Õ¥Õ¿" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ անուն․ %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ¹Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Õ² '%s' Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ­Õ¸Ö‚Õ´Õ¢Õ¨" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ«" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ '%s' Õ¡Ö€ÕªÕ¥Ö„Õ¸Õ¾, Õ¸Ö€Õ¨ UTF-8 Õ¹Õ«" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" +"Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ«, Õ¸Ö€Õ« Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¾Õ¥Õ¬Ö‰" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ«, Õ¸Ö€Õ« Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¾Õ¥Õ¬Ö‰" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ« '%s' Õ­Õ´Õ¢Õ¸Ö‚Õ´, Õ¸Ö€Õ« Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² " +"Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¾Õ¥Õ¬Ö‰" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ Õ¹Õ« ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ« '%s' Õ­Õ´Õ¢Õ¸Ö‚Õ´" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ escape Õ¶Õ«Õ· Õ¿Õ¸Õ²Õ« Õ¾Õ¥Ö€Õ»Õ¸Ö‚Õ´" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" +"Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« escape Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ '%s'" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "'%s' Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¾Õ¥Õ¬ Õ¸Ö€ÕºÕ¥Õ½ Õ©Õ«Õ¾Ö‰" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "'%s' Õ¡Õ´Õ¢Õ¸Õ¦Õ» Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¤Õ¸Ö‚Ö€Õ½ Õ§ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ«Ö" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "%s' Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¾Õ¥Õ¬ Õ¸Ö€ÕºÕ¥Õ½ Õ½Õ¡Õ°Õ¸Õ² Õ½Õ¿Õ¸Ö€Õ¡Õ¯Õ¸Õ¿Õ¸Õ¾ Õ©Õ«Õ¾Ö‰" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "%s' Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¾Õ¥Õ¬ Õ¸Ö€ÕºÕ¥Õ½ Õ¿Ö€Õ¡Õ´Õ¡Õ¢Õ¡Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¡Ö€ÕªÕ¥Ö„Ö‰" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Õ”Õ¡Õ¶Õ¡Õ¯Õ« Õ¹Õ¡ÖƒÕ¡Õ¦Õ¡Õ¶Ö Õ´Õ¥Õ® Õ¡Ö€ÕªÕ¥Ö„ Õ§ ÖƒÕ¸Õ­Õ¡Õ¶ÖÕ¾Õ¥Õ¬ %s-Õ«Õ¶" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "Õ€Õ¸Õ½Ö„Õ¶ Õ¡Ö€Õ¤Õ¥Õ¶ ÖƒÕ¡Õ¯ Õ§" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "Ô³Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¹Õ¥Õ²ÕµÕ¡Õ¬ Õ§ Õ°Õ¡ÕµÕ¿Õ¡Ö€Õ¡Ö€Õ¾Õ¥Õ¬" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Ö…Õ¢ÕµÕ¥Õ¯Õ¿, Õ¹Õ« Õ½Õ¯Õ¦Õ¢Õ¶Õ¡Ö€ÕªÕ¥Ö„Õ¡Õ¾Õ¸Ö€Õ¾Õ¥Õ¬" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "ÕˆÕ¹ Õ¬Ö€Õ«Õ¾ Õ¢Õ¡Õ¦Õ´Õ¡Õ¢Õ¡ÕµÕ© Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ´Õ¸Ö‚Õ¿Ö„Õ¡ÕµÕ«Õ¶ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ¸Ö‚Õ´" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "ÕÕ¡Ö€Õ¡Õ®Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¢Õ¡Õ¾Õ¡Ö€Õ¡Ö€ Õ¹Õ§ Õ¡Ö€Õ¤ÕµÕ¸Ö‚Õ¶Ö„Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "Ô¸Õ¶Õ¤Õ°Õ¡Õ¿Õ¾Õ¸Õ² Õ½Õ¯Õ¦Õ¢Õ¶Õ¡Ö€ÕªÕ¥Ö„Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Õ‰Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® Õ¿Õ«Õº" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s Ö†Õ¡ÕµÕ¬Õ« Õ¿Õ«Õº" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s Õ¿Õ«Õº" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials-Õ¨ Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¾Õ¡Õ® Õ¹Õ§ Õ¡ÕµÕ½ Õ•Õ€-Õ« Õ¾Ö€Õ¡" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« GCredentials Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ´ Õ±Õ¥Ö€ ÕºÕ¬Õ¡Õ¿Ö†Õ¸Ö€Õ´Õ¡ÕµÕ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "Õ€Õ¸Õ½Ö„Õ« Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« Õ¾Õ¡Õ²Õ¡ÕªÕ¡Õ´ Õ¡Õ¾Õ¡Ö€Õ¿" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "Õ‰Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Õ² '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ« '%s' Õ°Õ¡Õ½ÖÕ¥Õ¸Ö‚Õ´" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"'%s' Õ°Õ¡Õ½ÖÕ¥Õ¶ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§ (ÕºÕ¥Õ¿Ö„ Õ§ Õ¸Ö‚Õ²Õ«Õ¶Õ¥Ö€Õ«Ö Õ³Õ«Õ·Õ¿ Õ´Õ¥Õ¯Õ¨, tmpdir Õ¯Õ¡Õ´ Õ¡Õ¢Õ½Õ¿Ö€Õ¡Õ¯Õ¿ " +"Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€)" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "Ô²Õ¡Õ¶Õ¡Õ¬Õ«/Õ¡Ö€ÕªÕ¥Ö„ Õ¦Õ¸Ö‚ÕµÕ£Õ« Õ¡Õ¶Õ«Õ´Õ¡Õ½Õ¿ Õ°Õ¡Õ´Õ¡Õ¤Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ '%s' Õ°Õ¡Õ½ÖÕ¥Õ¸Ö‚Õ´" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "ÕÕ­Õ¡Õ¬ '%s' Õ°Õ¡Õ½ÖÕ¥Õ¸Ö‚Õ´ - port-Õ« Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ¨ Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "ÕÕ­Õ¡Õ¬ '%s' Õ°Õ¡Õ½ÖÕ¥Õ¸Ö‚Õ´ - family-Õ« Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ¨ Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "'%s' Õ°Õ¡Õ½ÖÕ¥Õ« Õ§Õ¬Õ¥Õ´Õ¥Õ¶Õ¿Õ¨ Õ¹Õ« ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ (:) Õ¥Ö€Õ¯Õ¸Ö‚ Õ¯Õ¥Õ¿" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" +"%d, '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ«/Õ¡Ö€ÕªÕ¥Ö„ Õ¦Õ¸Ö‚ÕµÕ£Õ¨ '%s' Õ°Õ¡Õ½ÖÕ¥Õ« Õ¿Õ¡Ö€Ö€Õ¸Ö‚Õ´ Õ¹Õ« ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ°Õ¡Õ¾Õ¡Õ½Õ¡Ö€Õ´Õ¡Õ¶ " +"Õ¶Õ·Õ¡Õ¶" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"Ô²Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¯Õ¡Õ´ Õ¡Ö€ÕªÕ¥Ö„Õ« Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ Õ½Õ­Õ¡Õ¬ %d Ô²Õ¡Õ¶Õ¡Õ¬Õ«/Ô±Ö€ÕªÕ¥Ö„ Õ¦Õ¸Ö‚ÕµÕ£Õ¸Ö‚Õ´, '%s', '%s' " +"Õ°Õ¡Õ½ÖÕ¥Õ« Õ¿Õ¡Ö€Ö€Õ¸Ö‚Õ´" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"ÕÕ­Õ¡Õ¬ '%s' Õ°Õ¡Õ½ÖÕ¥Õ¸Ö‚Õ´ - unix-Õ« ÖƒÕ¸Õ­Õ¡Õ¤Ö€Õ¸Ö‚Õ´Õ¨ ÕºÕ¡Õ°Õ¡Õ¶Õ»Õ¸Ö‚Õ´ Õ§ Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ¾Õ¡Õ® Õ¬Õ«Õ¶Õ« " +"Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ«Ö Õ³Õ«Õ·Õ¿ Õ´Õ¥Õ¯Õ¨Õ 'path' Õ¯Õ¡Õ´ 'abstract'" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "ÕÕ­Õ¡Õ¬ '%s' Õ°Õ¡Õ½ÖÕ¥Õ¸Ö‚Õ´ - host Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ¨ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ Õ¯Õ¡Õ´ Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "ÕÕ­Õ¡Õ¬ '%s' Õ°Õ¡Õ½ÖÕ¥Õ¸Ö‚Õ´ - port Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ¨ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ Õ¯Õ¡Õ´ Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "ÕÕ­Õ¡Õ¬ '%s' Õ°Õ¡Õ½ÖÕ¥Õ¸Ö‚Õ´ - noncefile Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ¨ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ Õ¯Õ¡Õ´ Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../gio/gdbusaddress.c:644 +msgid "Error auto-launching: " +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ¡Õ¾Õ¿Õ¸Õ´Õ¡Õ¿ Õ¯Õ¥Ö€ÕºÕ¸Õ¾ Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¥Õ¬ կապ․" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "Õ‰Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® Õ¯Õ¡Õ´ Õ¹Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Õ² '%s' ÖƒÕ¸Õ­Õ¡Õ¤Ö€Õ¸Ö‚Õ´ '%s' Õ°Õ¡Õ½ÖÕ¥Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gdbusaddress.c:688 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "'%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/gdbusaddress.c:706 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "'%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ Õ½Õ­Õ¡Õ¬ %s․" + +#: ../gio/gdbusaddress.c:715 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "'%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ Õ½Õ­Õ¡Õ¬, Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ 16 Õ¢Õ¡ÕµÕ©, Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ %d" + +#: ../gio/gdbusaddress.c:733 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ£Ö€Õ¥Õ¬ '%s' file-Õ« ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ հոսքում․" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "ÕÖ€Õ¾Õ¡Õ® Õ°Õ¡Õ½ÖÕ¥Õ¶ Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ§" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¢Õ¡Õ¦Õ´Õ¡ÖÕ¶Õ¥Õ¬ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ«Õ¶ Õ¡Õ¼Õ¡Õ¶Ö Õ´Õ¥Ö„Õ¥Õ¶Õ¡ÕµÕ« Õ«Õ¤Õ¥Õ¶Õ¿Õ«Ö†Õ«Õ¯Õ¡Õ¿Õ¸Ö€Õ«" + +#: ../gio/gdbusaddress.c:1057 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "'%s' Õ°Ö€Õ¡Õ´Õ¡Õ¶Õ¡ÕµÕ«Õ¶ Õ¿Õ¸Õ²Õ« Õ¢Õ¡Õ¦Õ´Õ¡ÖÕ´Õ¡Õ¶ սխալ․" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "Ô¾Ö€Õ¡Õ£Ö€Õ« Õ¸Õ¹ Õ¶Õ¸Ö€Õ´Õ¡Õ¬ Õ¡Õ¾Õ¡Ö€Õ¿ '%s' Õ°Ö€Õ¡Õ´Õ¡Õ¶Õ¡ÕµÕ«Õ¶ Õ¿Õ¸Õ²Õ¨ Õ¢Õ¡Õ¦Õ´Õ¡Öնելիս․ %s" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "'%s' Õ°Ö€Õ¡Õ´Õ¡Õ¶Õ¡ÕµÕ«Õ¶ Õ¿Õ¸Õ²Õ¨ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ¥Õ¬ Õ§ Õ¸Õ¹ Õ¦Ö€Õ¸ÕµÕ¡Õ¯Õ¡Õ¶ %d կարգավիճակով․ %s" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¸Ö€Õ¸Õ·Õ¥Õ¬ Õ½Õ¥Õ½Õ«Õ¡ÕµÕ« Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ¸Ö‚ Õ°Õ¡Õ½ÖÕ¥Õ¶ (Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¾Õ¡Õ® Õ¹Õ§ Õ¡ÕµÕ½ Ö…ÕºÕ¥Ö€Õ¡ÖÕ«Õ¸Õ¶ " +"Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ¸Ö‚Õ´)" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¸Ö€Õ¸Õ·Õ¥Õ¬ Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ¸Ö‚ Õ°Õ¡Õ½ÖÕ¥Õ¶ DBUS_STARTER_BUS_TYPE Õ´Õ«Õ»Õ¡Õ¾Õ¡ÕµÖ€Õ¡ÕµÕ«Õ¶ " +"ÖƒÕ¸ÖƒÕ¸Õ­Õ¡Õ¯Õ¡Õ¶Õ«Ö - Õ¡Õ¶Õ°Õ¡ÕµÕ¿ Õ¡Ö€ÕªÕ¥Ö„ '%s'" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¸Ö€Õ¸Õ·Õ¥Õ¬ Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ¸Ö‚ Õ°Õ¡Õ½ÖÕ¥Õ¶, Ö„Õ¡Õ¶Õ« Õ¸Ö€ DBUS_STARTER_BUS_TYPE " +"Õ´Õ«Õ»Õ¡Õ¾Õ¡ÕµÖ€Õ¡ÕµÕ«Õ¶ ÖƒÕ¸ÖƒÕ¸Õ­Õ¡Õ¯Õ¡Õ¶Õ¨ Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ¾Õ¡Õ® Õ¹Õ§" + +#: ../gio/gdbusaddress.c:1273 +#, c-format +msgid "Unknown bus type %d" +msgstr "%d Õ¹Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® bus - Õ« Õ¿Õ«Õº" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "ÕŠÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« ÕºÕ¡Õ¯Õ¡Õ½ Õ¿Õ¸Õ²Õ¨ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ ÖƒÕ¸Ö€Õ± Õ¯Õ¡Õ¿Õ¡Ö€Õ¥Õ¬Õ«Õ½" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "ÕŠÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« ÕºÕ¡Õ¯Õ¡Õ½ Õ¿Õ¸Õ²Õ¨ (Õ¡ÕºÕ¡Õ°Õ¸Õ¾) Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ ÖƒÕ¸Ö€Õ± Õ¯Õ¡Õ¿Õ¡Ö€Õ¥Õ¬Õ«Õ½" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"ÕŽÕ¡Õ¾Õ¥Ö€Õ¡ÖÕ´Õ¡Õ¶ Õ¢Õ¸Õ¬Õ¸Ö€ Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ´Õ¥Õ­Õ¡Õ¶Õ«Õ¦Õ´Õ¶Õ¥Ö€Õ¨ Õ½ÕºÕ¡Õ¼Õ¾Õ¥Õ¬ Õ¥Õ¶ (ÖƒÕ¸Ö€Õ±Õ¾Õ¥Õ¬ են․ %s) (Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« " +"են․ %s)" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Ô±Õ¶Õ»Õ¡Õ¿Õ¾Õ¥Õ¬ Õ§ GDBusAuthObserver -Õ¸Õ¾Ö‰Ö‰Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¾Õ¡Õ®-Õ¾Õ¡Õ¾Õ¥Ö€Õ¡ÖÕ¾Õ¡Õ®-Õ°Õ¡Õ¾Õ¡Õ½Õ¡Ö€Õ¡Õ¦Õ¸Ö€" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, c-format +msgid "Error statting directory '%s': %s" +msgstr "'%s' ÕºÕ¡Õ¶Õ¡Õ¯Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ¸Ö‚ Õ½Õ­Õ¡Õ¬. %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"'%s' ÕºÕ¡Õ¶Õ¡Õ¯Õ« Õ©Õ¸Ö‚ÕµÕ¬Õ¿Õ¾Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨ Õ½Õ­Õ¡Õ¬ Õ¥Õ¶Ö‰ ÕÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ 0700 Õ¼Õ¥ÕªÕ«Õ´, Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "'%s' ÕºÕ¡Õ¶Õ¡Õ¯ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Ô¿Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ Õ¶Õ¡Õ­Õ¡Õ¿Õ¥Õ½Õ¾Õ¡Õ® '%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ¸Ö‚ սխալ․" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "keyring-Õ« %d Õ¿Õ¸Õ²Õ¨ '%s' -Õ¸Ö‚Õ´, Õ¸Ö€Õ« ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ '%s' Õ§, Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"%d Õ¿Õ¸Õ²Õ« Õ¡Õ¼Õ¡Õ»Õ«Õ¶ Õ¢Õ¡Õ¼Õ¡Õ¶Õ«Õ·Õ¨ '%s' - Õ¸Ö‚Õ´, Õ¸Ö€Õ« ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ '%s' Õ§, Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"keyring-Õ« %d Õ¿Õ¸Õ²Õ« Õ¥Ö€Õ¯Ö€Õ¸Ö€Õ¤ Õ¢Õ¡Õ¼Õ¡Õ¶Õ«Õ·Õ¨ '%s' -Õ¸Ö‚Õ´, Õ¸Ö€Õ« ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ '%s' Õ§, " +"Õ½Õ­Õ¡Õ¬ Õ§" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "Õ‰Õ« Õ£Õ¿Õ¶Õ¾Õ¥Õ¬ %d id-Õ¸Õ¾ cookie '%s' keyring-Õ¸Ö‚Õ´" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "'%s' Õ¡Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ´Õ¡Õ¶ Ö†Õ¡ÕµÕ¬Õ¨ Õ»Õ¶Õ»Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "'%s' Õ¡Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ´Õ¡Õ¶ Ö†Õ¡ÕµÕ¬Õ« Õ½Õ¿Õ¥Õ²Õ®Õ´Õ¡Õ¶ սխալ․ %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "" +"'%s' Õ¡Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ´Õ¡Õ¶ (Õ°Õ²Õ¸Ö‚Õ´ Õ¹ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Õ²) Ö†Õ¡ÕµÕ¬Õ« ÖƒÕ¡Õ¯Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® սխալ․ %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "'%s' Õ¡Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ´Õ¡Õ¶ Ö†Õ¡ÕµÕ¬Õ« Õ¯Õ¡ÕºÕ¥Ö€Õ¶ Õ¡Õ¶Õ»Õ¡Õ¿Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Ô³Ö€Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ Õ¶Õ¡Õ­Õ¡Õ¿Õ¥Õ½Õ¾Õ¡Õ® '%s' Ö†Õ¡ÕµÕ¬Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ¸Ö‚ սխալ․" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(Ô¼Ö€Õ¡ÖÕ¸Ö‚ÖÕ«Õ¹, '%s' - Õ« Õ¡Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ´Õ¡Õ¶ Õ©Õ¸Õ²Õ¡Ö€Õ¯Õ¸Ö‚Õ´Õ¨ Ö‡Õ½ Õ±Õ¡Õ­Õ¸Õ²Õ¾Õ¥Õ¬ է․ %s)" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "Ô¿Õ¡ÕºÕ¨ ÖƒÕ¡Õ¯ Õ§" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "Õ€Õ¡Õ½Õ¥Õ¬ Õ§ timeout" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Õ€Õ¡Õ¶Õ¤Õ«ÕºÕ¥Õ¬ Õ¥Õ¶ Õ¹Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Õ² Õ¤Ö€Õ¸Õ·Õ¶Õ¥Ö€ client-side Õ´Õ«Õ¡ÖÕ¸Ö‚Õ´Õ¨ Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¥Õ¬Õ«Õ½" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« 'org.freedesktop.DBus.Properties' Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½ %s Õ¸Ö‚Õ²Õ¸Ö‚ Õ¾Ö€Õ¡ " +"Õ£Õ¿Õ¶Õ¾Õ¸Õ² Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"ÕÕ¥Õ²Õ« Õ§ Õ¸Ö‚Õ¶Õ¥ÖÕ¥Õ¬ Õ½Õ­Õ¡Õ¬'%s' Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ սահմանելիս․ ÕÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ '%s' Õ¿Õ«ÕºÕ¨ , " +"Õ¢Õ¡ÕµÖ Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§'%s'" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "'%s' Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« " + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "'%s' Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¯Õ¡Ö€Õ¤Õ¡ÖÕ¾Õ¸Õ² Õ¹Õ§" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "'%s' Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ£Ö€Õ¾Õ¸Õ² Õ¹Õ§" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "Ô±ÕµÕ¤ÕºÕ«Õ½Õ« Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ«" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½ %s Õ¸Ö‚Õ²Õ¸Ö‚ Õ¾Ö€Õ¡ Õ£Õ¿Õ¶Õ¾Õ¸Õ² Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "Ô±ÕµÕ¤ÕºÕ«Õ½Õ« '%s' Õ´Õ¥Õ©Õ¸Õ¤ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« " + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "'%s' Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¿Õ«ÕºÕ¨ Õ¹Õ« Õ°Õ¡Õ´Õ¡ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¸Ö‚Õ´ '%s' Õ½ÕºÕ¡Õ½Õ¾Õ¸Õ² Õ¿Õ«ÕºÕ«Õ¶" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Õ•Õ¢ÕµÕ¥Õ¯Õ¿Õ¨ Õ¡Ö€Õ¤Õ¥Õ¶ Õ¡Ö€Õ¿Õ¡Õ®Õ¾Õ¥Õ¬ Õ§ %s Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ« Õ°Õ¡Õ´Õ¡Ö€ %s Õ¸Ö‚Õ´" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "'%s'Õ´Õ¥Õ©Õ¥Õ¤Õ¨ Õ¾Õ¥Ö€Õ¡Õ¤Õ¡Ö€Õ±Õ¶Õ¸Ö‚Õ´ Õ§ '%s' Õ¿Õ«ÕºÕ¨, Õ¢Õ¡ÕµÖ Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ '%s'" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "'%s' Õ´Õ¥Õ©Õ¸Õ¤Õ¨ '%s' Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ« Õ¾Ö€Õ¡ '%s' Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ«" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "ÔµÕ¶Õ©Õ¡Õ®Õ¡Õ¼Õ¶ Õ¡Ö€Õ¤Õ¥Õ¶ Õ¡Ö€Õ¿Õ¡Õ®Õ¾Õ¥Õ¬ Õ§ %s Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "Õ¿Õ«ÕºÕ¨ Ô±Õ†ÕŽÔ±ÕŽÔ±ÔµÕ Ô·" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" +"METHOD_CALL հաղորդագրություն․ PATH Õ¯Õ¡Õ´ MEMBER Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¡ÕµÕ«Õ¶ Õ¤Õ¡Õ·Õ¿Õ¨ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" +"METHOD_RETURN հաղորդագրություն․ REPLY_SERIAL Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¡ÕµÕ«Õ¶ Õ¤Õ¡Õ·Õ¿Õ¨ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"ÕÔ½Ô±Ô¼Ô» հաղորդագրություն․ REPLY_SERIAL Õ¯Õ¡Õ´ ERROR_NAME Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¡ÕµÕ«Õ¶ Õ¤Õ¡Õ·Õ¿Õ¨ " +"Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"SIGNAL հաղորդագրություն․ PATH, INTERFACE Õ¯Õ¡Õ´ MEMBER Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¡ÕµÕ«Õ¶ Õ¤Õ¡Õ·Õ¿Õ¥Ö€Õ¨ " +"Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ¥Õ¶" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL հաղորդագրություն․ PATH Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¡ÕµÕ«Õ¶ Õ¤Õ¡Õ·Õ¿Õ¨ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´ Õ§ /org/" +"freedesktop/DBus/Local Õ¼Õ¥Õ¦Õ¥Ö€Õ¾Õ¡ÖÕ¾Õ¡Õ® Õ¡Ö€ÕªÕ¥Ö„Õ¨" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL հաղորդագրություն․ INTERFACE Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¡ÕµÕ«Õ¶ Õ¤Õ¡Õ·Õ¿Õ¨ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´ Õ§ org." +"freedesktop.DBus.Local Õ¼Õ¥Õ¦Õ¥Ö€Õ¾Õ¡ÖÕ¾Õ¡Õ® Õ¡Ö€ÕªÕ¥Ö„Õ¨" + +#: ../gio/gdbusmessage.c:998 +#, fuzzy, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "Õ‘Õ¡Õ¶Õ¯Õ¡Õ¶Õ¸Ö‚Õ´ Õ§ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ %lu Õ¢Õ¡ÕµÕ©, Õ¢Õ¡ÕµÖ Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ EOF" +msgstr[1] "Õ‘Õ¡Õ¶Õ¯Õ¡Õ¶Õ¸Ö‚Õ´ Õ§ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ %lu Õ¢Õ¡ÕµÕ©, Õ¢Õ¡ÕµÖ Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ EOF" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"ÕÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ Õ¾Õ¡Õ¾Õ¥Ö€Õ¡Õ¯Õ¡Õ¶ UTF-8 Õ¿Õ¸Õ², Õ¢Õ¡ÕµÖ Õ£Õ¿Õ¶Õ¾Õ¥Õ¬ Õ§ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¢Õ¡ÕµÕ©Õ¥Ö€ %d Õ¿Õ¥Õ²Õ¡Õ·Õ¡Ö€ÕªÕ« " +"Õ¾Ö€Õ¡ (Õ¿Õ¸Õ²Õ« Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ %d Õ§)Ö‰ ÕŽÕ¡Õ¾Õ¥Ö€Õ¡Õ¯Õ¡Õ¶ UTF-8 Õ¿Õ¸Õ², Õ¸Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ´Õ«Õ¶Õ¹ Õ¡ÕµÕ¤ Õ¯Õ¥Õ¿Õ¨ '" +"%s' Õ§Ö€Ö‰" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "'%s' Õ¿Õ¸Õ²Õ«Ö Õ°Õ¥Õ¿Õ¸ Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ NUL Õ¢Õ¡ÕµÕ©, Õ¢Õ¡ÕµÖ Õ£Õ¿Õ¶Õ¾Õ¥Õ¬ Õ§ %d" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "'%s' Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¾Õ¡Õ® Õ¡Ö€ÕªÕ¥Ö„Õ¨ D-Bus Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¾Õ¡Õ¾Õ¥Ö€ Õ³Õ¡Õ¶Õ¡ÕºÕ¡Ö€Õ° Õ¹Õ§" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "'%s' Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¾Õ¡Õ® Õ¡Ö€ÕªÕ¥Ö„Õ¨ D-Bus Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¾Õ¡Õ¾Õ¥Ö€ Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ§" + +#: ../gio/gdbusmessage.c:1324 +#, fuzzy, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Õ€Õ¡Õ·Õ¾Õ¾Õ¥Õ¬ Õ§ %u Õ¢Õ¡ÕµÕ©Õ¥Ö€Õ« Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¦Õ¡Õ¶Õ£Õ¾Õ¡Õ®Õ¨Ö‰ Ô±Õ¼Õ¡Õ¾Õ¥Õ¬Õ¡Õ£Õ¸Ö‚ÕµÕ¶ Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ 2<<26 " +"Õ¢Õ¡ÕµÕ© Õ§ (64 MiB)Ö‰" +msgstr[1] "" +"Õ€Õ¡Õ·Õ¾Õ¾Õ¥Õ¬ Õ§ %u Õ¢Õ¡ÕµÕ©Õ¥Ö€Õ« Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¦Õ¡Õ¶Õ£Õ¾Õ¡Õ®Õ¨Ö‰ Ô±Õ¼Õ¡Õ¾Õ¥Õ¬Õ¡Õ£Õ¸Ö‚ÕµÕ¶ Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ 2<<26 " +"Õ¢Õ¡ÕµÕ© Õ§ (64 MiB)Ö‰" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" +"'%s' Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¾Õ¡Õ® Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ« Õ°Õ¡Õ´Õ¡Ö€ D-Bus Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¾Õ¡Õ¾Õ¥Ö€ Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ§" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"ÕÕ­Õ¡Õ¬ D-Bus Õ¬Õ¡Ö€Õ« Ö†Õ¸Ö€Õ´Õ¡Õ¿Õ«Ö '%s' Õ¿Õ«ÕºÕ« Õ¿Õ¸Õ²Õ¸Õ¾ GVariant-Õ« Õ¦Õ¸Ö‚Õ£Õ¡Õ°Õ¥Õ¼Õ¡ÖÕ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ endianness Õ¡Ö€ÕªÕ¥Ö„Ö‰ ÕÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ 0x6c ('l') Õ¯Õ¡Õ´ 0x42 ('B') ', Õ¢Õ¡ÕµÖ " +"Õ£Õ¿Õ¶Õ¾Õ¥Õ¬ Õ§ 0x%02x Õ¡Ö€ÕªÕ¥Ö„Õ¨" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Õ€Õ«Õ´Õ¶Õ¡Õ¯Õ¡Õ¶ ÕºÖ€Õ¸Õ¿Õ¸Õ¯Õ¸Õ¬Õ« Õ¡Õ¾Õ¡Õ¾Õ¥Ö€ Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Ö‰ ÕÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ 1, Õ¢Õ¡ÕµÖ Õ£Õ¿Õ¶Õ¾Õ¥Õ¬ Õ§ %d" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" +"Ô³Õ¿Õ¶Õ¾Õ¥Õ¬ Õ§ '%s' Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¨, Õ¢Õ¡ÕµÖ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ " +"Õ´Õ¡Ö€Õ´Õ«Õ¶Õ¨ Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ§" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" +"ÕŽÕ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¾Õ¡Õ® '%s' Õ¡Ö€ÕªÕ¥Ö„Õ¨ Õ¾Õ¡Õ¾Õ¥Ö€ D-Bus Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ§ (Õ´Õ¡Ö€Õ´Õ¶Õ« Õ°Õ¡Õ´Õ¡Ö€)" + +#: ../gio/gdbusmessage.c:1821 +#, fuzzy, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Õ€Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¥Õ» Õ¹Õ¯Õ¡ Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½, Õ¢Õ¡ÕµÖ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¡Ö€Õ´Õ«Õ¶Õ¨ " +"%u Õ¢Õ¡ÕµÕ© Õ§" +msgstr[1] "" +"Õ€Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¥Õ» Õ¹Õ¯Õ¡ Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½, Õ¢Õ¡ÕµÖ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¡Ö€Õ´Õ«Õ¶Õ¨ " +"%u Õ¢Õ¡ÕµÕ© Õ§" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¦Õ¸Ö‚Õ£Õ¡Õ°Õ¥Õ¼Õ¡ÖÕ¶Õ¥Õ¬ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "ÕÕ­Õ¡Õ¬ '%s' Õ¿Õ«ÕºÕ« Õ¿Õ¸Õ²Õ¸Õ¾ GVariant-Õ¨ D-Bus Õ¬Õ¡Ö€Õ« Ö†Õ¸Ö€Õ´Õ¡Õ¿Õ« ÖƒÕ¸Õ­Õ¥Õ¬Õ«Õ½" + +#: ../gio/gdbusmessage.c:2303 +#, fuzzy, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "Õ€Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¸Ö‚Õ¶Õ¥Ö€ %d fds, Õ¢Õ¡ÕµÖ header Õ¤Õ¡Õ·Õ¿Õ¨ ÖÕ¸Ö‚ÕµÖ Õ§ Õ¿Õ¡Õ¬Õ«Õ½ %d fds" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶ Õ±Ö‡Õ¸Õ¾ Õ¶Õ¥Ö€Õ¯Õ¡ÕµÕ¡ÖÕ¶Õ¥Õ¬ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" +"Õ€Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¡Ö€Õ´Õ«Õ¶Õ¶ Õ¸Ö‚Õ¶Õ« '%s' Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶, Õ¢Õ¡ÕµÖ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« " +"Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" +"Õ€Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¡Ö€Õ´Õ«Õ¶Õ¶ Õ¸Ö‚Õ¶Õ« Õ¿Õ«ÕºÕ« '%s' Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶, Õ¢Õ¡ÕµÖ Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ " +"Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¡ÕµÕ«Õ¶ Õ¤Õ¡Õ·Õ¿Õ¸Ö‚Õ´ '%s' Õ§" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" +"Õ€Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¡Ö€Õ´Õ«Õ¶Õ¨ Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ§, Õ¢Õ¡ÕµÖ Õ¶Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ£Õ¬Õ­Õ¡Õ´Õ¡Õ½Õ¡ÕµÕ«Õ¶ Õ¤Õ¡Õ·Õ¿Õ¸Ö‚Õ´ " +"('%s') Õ§" + +#: ../gio/gdbusmessage.c:2938 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' Õ¿Õ«ÕºÕ« Õ´Õ¡Ö€Õ´Õ¶Õ¸Õ¾ Ö†Õ¡ÕµÕ¬Õ« Õ¾Õ¥Ö€Õ¡Õ¤Õ¡Ö€Õ±Õ´Õ¡Õ¶ Õ½Õ­Õ¡Õ¬" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "ÕÕ­Õ¡Õ¬ Õ¾Õ¥Ö€Õ¡Õ¤Õ¡Ö€Õ± Õ¤Õ¡Õ¿Õ¡Ö€Õ¯ Õ´Õ¡Ö€Õ´Õ¶Õ¸Õ¾" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¢Õ¥Õ¼Õ¶Õ¥Õ¬ /var/lib/dbus/machine-id․" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s - Õ« Õ°Õ¡Õ´Õ¡Ö€ StartServiceByName-Õ« Õ¯Õ¡Õ¶Õ¹Õ´Õ¡Õ¶ սխալ․ " + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Õ‰Õ½ÕºÕ¡Õ½Õ¾Õ¡Õ® ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶ %d StartServiceByName(\"%s\") Õ´Õ¥Õ©Õ¸Õ¤Õ«Ö" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¯Õ¡Õ¶Õ¹Õ¥Õ¬ մեթոդ․ ÕºÖ€Õ¸Ö„Õ½Õ«Õ¶ Õ¡Õ¼Õ¡Õ¶Ö Õ¿Õ«Ö€Õ¸Õ» Õ¬Õ¡Õ¾ Õ°Õ¡ÕµÕ¿Õ¶Õ« Õ¡Õ¶Õ¾Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€ Õ§ Ö‡ " +"ÕºÖ€Õ¸Ö„Õ½Õ«Õ¶ Õ¯Õ¡Õ¼Õ¸Ö‚ÖÕ¾Õ¡Õ® Õ§ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START Õ¤Ö€Õ¸Õ·Õ« Õ´Õ«Õ»Õ¸ÖÕ¸Õ¾" + +#: ../gio/gdbusserver.c:711 +msgid "Abstract name space not supported" +msgstr "Ô±Õ¢Õ½Õ¿Ö€Õ¡Õ¯Õ¿ Õ¡Õ¶Õ¾Õ¡Õ¶Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ« Õ¿Õ«Ö€Õ¸Ö‚ÕµÕ©Õ¶Õ¥Ö€Õ¨ Õ¹Õ¥Õ¶ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¶Õ·Õ¥Õ¬ nonce Ö†Õ¡ÕµÕ¬ Õ½Õ¥Ö€Õ¾Õ¥Ö€ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ«Õ½" + +#: ../gio/gdbusserver.c:875 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ Õ£Ö€Õ¥Õ¬Õ¸Ö‚ Õ½Õ­Õ¡Õ¬ '%s' - ում․ %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' Õ¿Õ¸Õ²Õ¨ Õ¾Õ¡Õ¾Õ¥Ö€ D-Bus GUID Õ¹Õ§" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "Õ‰Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¬Õ½Õ¥Õ¬ '%s' Õ¹Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Õ² ÖƒÕ¸Õ­Õ¡Õ¤Ö€Õ¸Ö‚Õ´Õ¨" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "Õ€Ö€Õ¡Õ´Õ¡Õ¶" + +#: ../gio/gdbus-tool.c:93 +#, fuzzy, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"Հրամաններ․ \n" +" Ö…Õ£Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¸Ö‚Õ´ Õ§ Õ¡ÕµÕ½ Õ¿Õ¥Õ²Õ¥Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨\n" +" Õ¦Õ¶Õ¶Õ¥Õ¬ Ô¶Õ¶Õ¶Õ¸Ö‚Õ´ Õ§ Õ°Õ¥Õ¼Õ¡Õ¤Õ«Ö€ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ¨\n" +" Õ°Õ¥Õ¿Ö‡Õ¥Õ¬ Õ€Õ¥Õ¿Ö‡Õ¸Ö‚Õ´ Õ§ Õ°Õ¥Õ¼Õ¡Õ¯Õ¡ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ¨\n" +" Õ¯Õ¡Õ¶Õ¹ Ô¿Õ¡Õ¶Õ¹Õ¸Ö‚Õ´ Õ§ Õ´Õ¥Õ©Õ¸Õ¤Õ Õ°Õ¥Õ¼Õ¡ÖÕ¾Õ¡Õ® Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¾Ö€Õ¡\n" +"\n" +"Õ•Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ \"%s Õ€ÕÔ±Õ„Ô±Õ† --Ö…Õ£Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶\" ÕµÕ¸Ö‚Ö€Õ¡Ö„Õ¡Õ¶Õ¹ÕµÕ¸Ö‚Ö€ Õ°Ö€Õ¡Õ´Õ¡Õ¶Õ« Ö…Õ£Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶ " +"Õ½Õ¿Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€Ö‰\n" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, c-format +msgid "Error: %s\n" +msgstr "Õխալ․ %s\n" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "XML Õ¦Õ¶Õ¶Õ¸Ö‚Õ´Õ¨ Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ¥Õ¬Õ¸Ö‚ սխալ․ %s\n" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "Õ„Õ«Õ¡Õ¶Õ¸Ö‚Õ´ Õ§ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ« Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ¸Ö‚Õ¶" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "Ô¿Õ¡ÕºÕ¾Õ¸Ö‚Õ´ Õ§ Õ½Õ¥Õ½Õ«Õ¡ÕµÕ« Õ¯Õ¡ÕºÕ¸Ö‚Õ²Õ¸Ö‚Õ¶" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "Ô¿Õ¡ÕºÕ¾Õ¸Ö‚Õ´ Õ§ Õ¿Ö€Õ¾Õ¡Õ® D-Bus Õ°Õ¡Õ½ÖÕ¥Õ«Õ¶" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "Ô¿Õ¡ÕºÕ« ÕŽÕ¥Ö€Õ»Õ¶Õ¡Õ¯Õ¥Õ¿Õ« Ընտրանքներ․" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "Ô¿Õ¡ÕºÕ« Õ¾Õ¥Ö€Õ»Õ¶Õ¡Õ¯Õ¥Õ¿Õ¨ Õ¶Õ·Õ¥Õ¬Õ¸Ö‚ Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ¶Õ¥Ö€" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "Ô¿Õ¡ÕºÕ« Õ¾Õ¥Ö€Õ»Õ¯Õ¡Õ¯Õ¥Õ¿Õ¨ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ§" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Õ†Õ·Õ¾Õ¡Õ® Õ¥Õ¶ Õ¯Õ¡ÕºÕ« Õ¢Õ¡Õ¦Õ´Õ¡Õ¯Õ« Õ¾Õ¥Ö€Õ»Õ¶Õ¡Õ¯Õ¥Õ¿Õ¥Ö€" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" +"Ô¶Õ£Õ¸Ö‚Õ·Õ¡Öում․ Õ€Õ¡Õ·Õ¾Õ« Õ¡Õ¼Õ¶Õ¥Õ¬Õ¸Õ¾ Õ¦Õ¶Õ¶Õ¸Ö‚Õ´ Õ¿Õ¾ÕµÕ¡Õ¬Õ¨, '%s' Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ¨ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ«\n" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"Ô¶Õ£Õ¸Ö‚Õ·Õ¡Öում․ Õ€Õ¡Õ·Õ¾Õ« Õ¡Õ¼Õ¶Õ¥Õ¬Õ¸Õ¾ Õ¦Õ¶Õ¶Õ¸Ö‚Õ´ Õ¿Õ¾ÕµÕ¡Õ¬Õ¨, '%s'Õ´Õ¥Õ©Õ¸Õ¤Õ¨ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« '%s' " +"Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ« Õ°Õ¡Õ´Õ¡Ö€\n" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +#, fuzzy +msgid "Object path to emit signal on" +msgstr "Õ•Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¸Ö‚Õ²Õ«Õ¶, Õ¸Ö€Õ«Õ¶ ÕºÕ¥Õ¿Ö„ Õ§ Õ°Õ¥Õ¿Ö‡Õ¥Õ¬" + +#: ../gio/gdbus-tool.c:536 +#, fuzzy +msgid "Signal and interface name" +msgstr "Õ„Õ¥Õ©Õ¸Õ¤Õ« Ö‡ Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Õ„Õ«Õ¡ÖÕ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® սխալ․ %s\n" + +#: ../gio/gdbus-tool.c:614 +#, fuzzy, c-format +msgid "Error: object path not specified.\n" +msgstr "Õխալ․ Õ•Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¸Ö‚Õ²Õ«Õ¶ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Õխալ․ %s - Õ¨ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¾Õ¡Õ¾Õ¥Ö€ Õ¸Ö‚Õ²Õ« Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:625 +#, fuzzy, c-format +msgid "Error: signal not specified.\n" +msgstr "Õխալ․ Õ†ÕºÕ¡Õ¿Õ¡Õ¯Õ¡Õ¯Õ¥Õ¿Õ¨ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Õխալ․ %s - Õ¨ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¾Õ¡Õ¾Õ¥Ö€ Õ¸Ö‚Õ²Õ« Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Õխալ․ %s - Õ¨ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¾Õ¡Õ¾Õ¥Ö€ Õ¸Ö‚Õ²Õ« Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Õխալ․ %s - Õ¨ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¾Õ¡Õ¾Õ¥Ö€ Õ¸Ö‚Õ²Õ« Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%d ÕºÕ¡Ö€Õ¡Õ´Õ¥Õ¿Ö€Õ« Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ´Õ¡Õ¶ սխալ․ %s\n" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ¯Õ¡ÕºÕ« Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¸Ö‚Õ´Õ¨ Õ¨Õ¶Õ¤Õ¸Ö‚Õ¶Õ¥Õ¬Õ %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "Õ†ÕºÕ¡Õ¿Õ¡Õ¯Õ¥Õ¿Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨, Õ¸Ö€Õ« Õ¾Ö€Õ¡ ÕºÕ¥Õ¿Ö„ Õ§ Õ¯Õ¡Õ¶Õ¹Õ¾Õ« Õ´Õ¥Õ©Õ¸Õ¤Õ¨" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "Õ•Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¸Ö‚Õ²Õ«Õ¶, Õ¸Ö€Õ« Õ¾Ö€Õ¡ ÕºÕ¥Õ¿Ö„ Õ§ Õ¯Õ¡Õ¶Õ¹Õ¾Õ« Õ´Õ¥Õ©Õ¸Õ¤Õ¨" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "Õ„Õ¥Õ©Õ¸Õ¤Õ« Ö‡ Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨" + +#: ../gio/gdbus-tool.c:728 +#, fuzzy +msgid "Timeout in seconds" +msgstr "Õ€Õ¡Õ½Õ¥Õ¬ Õ§ timeout" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "Ô¿Õ¡Õ¶Õ¹Õ¥Õ¬ Õ´Õ¥Õ©Õ¸Õ¤Õ¨ Õ°Õ¥Õ¼Õ¡Õ¤Õ«Ö€ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "Õխալ․ Õ†ÕºÕ¡Õ¿Õ¡Õ¯Õ¡Õ¯Õ¥Õ¿Õ¨ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "Õխալ․ Õ•Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¸Ö‚Õ²Õ«Õ¶ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "Õխալ․ Õ„Õ¥Õ©Õ¸Õ¤Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ§\n" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "Õխալ․ Õ„Õ¥Õ©Õ¸Õ¤Õ« '%s' Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§\n" + +#: ../gio/gdbus-tool.c:974 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "%d ÕºÕ¡Ö€Õ¡Õ´Õ¥Õ¿Ö€Õ« Õ¾Õ¥Ö€Õ¬Õ¸Ö‚Õ®Õ´Õ¡Õ¶ Õ½Õ­Õ¡Õ¬, Õ¸Ö€Õ¨ '%s' Õ¿Õ«ÕºÕ« է․ %s\n" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "Õ†ÕºÕ¡Õ¿Õ¡Õ¯Õ¥Õ¿Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨, Õ¸Ö€Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ¦Õ¶Õ¶Õ¥Õ¬" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "Õ•Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¸Ö‚Õ²Õ«Õ¶, Õ¸Ö€Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ¦Õ¶Õ¶Õ¥Õ¬" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "ÕÕºÕ¥Õ¬ XML" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "Ô¶Õ¶Õ¶Õ¥Õ¬ Õ°Õ¥Õ¼Õ¡Õ¤Õ«Ö€ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ¨Ö‰" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "Õ†ÕºÕ¡Õ¿Õ¡Õ¯Õ¡Õ¯Õ¥Õ¿Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨, Õ¸Ö€Õ«Õ¶ ÕºÕ¥Õ¿Ö„ Õ§ Õ°Õ¥Õ¿Ö‡Õ¥Õ¬" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "Õ•Õ¢ÕµÕ¥Õ¯Õ¿Õ« Õ¸Ö‚Õ²Õ«Õ¶, Õ¸Ö€Õ«Õ¶ ÕºÕ¥Õ¿Ö„ Õ§ Õ°Õ¥Õ¿Ö‡Õ¥Õ¬" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "Õ€Õ¥Õ¿Ö‡Õ¥Õ¬ Õ°Õ¥Õ¼Õ¡Õ¤Õ«Ö€ Ö…Õ¢ÕµÕ¥Õ¯Õ¿Õ¨" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Ô±Õ¶Õ¡Õ¶Õ¸Ö‚Õ¶" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "Desktop Ö†Õ¡ÕµÕ¬Õ¸Ö‚Õ´ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ« Exec Õ¤Õ¡Õ·Õ¿Õ¨" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ®Ö€Õ¡Õ£Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ ÕºÕ¡Õ°Õ¡Õ¶Õ»Õ¾Õ¡Õ® Õ¿Õ¥Ö€Õ´Õ«Õ¶Õ¡Õ¬Õ¨ Õ£Õ¿Õ¶Õ¥Õ¬" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" +"Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ %s Õ¯Õ¸Õ¶Ö†Õ«Õ£Õ¸Ö‚Ö€Õ¡ÖÕ«Õ¸Õ¶ ÕºÕ¡Õ¶Õ¡Õ¯ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Õ²Õ« Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ®Ö€Õ¡Õ£Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€. " +"%s" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "Õ•Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Õ²Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ¹Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ %s MIME Õ¯Õ¸Õ¶Ö†Õ«Õ£Õ¸Ö‚Ö€Õ¡ÖÕ«Õ¸Õ¶ ÕºÕ¡Õ¶Õ¡Õ¯. %s" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Õ²Õ« desktop Ö†Õ¡ÕµÕ¬ %s" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "ÕŠÕ¡Õ¿Õ¾Õ«Ö€Õ¾Õ¡Õ® Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¸Ö‚Õ´ %s Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "ÕÕ¡Ö€Ö„Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¸Ö‚Õ´Õ¨" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" +"ÕÕ¡Ö€Ö„Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ \"Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¸Ö‚Õ´\" Õ¯Õ¡Õ´ \"Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¸Ö‚Õ´ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢\"" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "ÕÕ¡Ö€Ö„Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ Õ¯Ö€Õ«Õ¹Õ« Õ¯Õ¸Õ²Õ´Õ«Ö Õ°Õ¡ÕµÖÕ¨" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "ÕÕ¡Ö€Ö„Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ Õ½Õ¯Õ«Õ¦Õ¢Õ¨" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "ÕÕ¡Ö€Ö„Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ Õ¡Õ¾Õ¡Ö€Õ¿Õ¨" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ´Õ·Õ¡Õ¯Õ¥Õ¬ GEmblem Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ %d Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ Õ´Õ¥Õ» Õ½Õ­Õ¡Õ¬ Ö„Õ¡Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ¢Õ¡Õ¼Õ¡Õ¶Õ«Õ·Õ¥Ö€ (%d)" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ´Õ·Õ¡Õ¯Õ¥Õ¬ GEmblemedIcon Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ %d Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ Õ´Õ¥Õ» Õ½Õ­Õ¡Õ¬ Ö„Õ¡Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ¶Õ´ Õ¢Õ¡Õ¼Õ¡Õ¶Õ«Õ·Õ¥Ö€ (%d)" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon-Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ GEmblem" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Ô³Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¡Õ® Õ¹Õ§" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "Ô´Õ«Õ¿Õ´Õ¡Õ¶ Õ¯Õ¥Õ¿ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Õ² Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ«" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "Õ‰Õ« Õ½Õ¿Õ¡ÖÕ¾Õ¸Ö‚Õ´ ÕºÕ¡Õ¿Õ³Õ¥Õ¶Õ¥Õ¬ ÕºÕ¡Õ¶Õ¡Õ¯Õ«Ö Õ¾Õ¥Ö€Ö‡ " + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "Õ‰Õ« Õ½Õ¿Õ¡ÖÕ¾Õ¸Ö‚Õ´ ÕºÕ¡Õ¿Õ³Õ¥Õ¶Õ¥Õ¬ ÕºÕ¡Õ¶Õ¡Õ¯Õ¨ ÕºÕ¡Õ¶Õ¡Õ¯Õ« Õ¾Ö€Õ¡ÕµÕ«Ö " + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¸Ö‚Õ¶Õ« Õ¶ÕºÕ¡Õ¿Õ¡Õ¯Õ¡Õ¯Õ¡Õ¯Õ¥Õ¿Õ« Ö†Õ¡ÕµÕ¬" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "Õ‰Õ« Õ½Õ¿Õ¡ÖÕ¾Õ¸Ö‚Õ´ Õ¼Õ¥Õ¯Õ¸Ö‚Ö€Õ½Õ«Õ¾ ÕºÕ¡Õ¿Õ³Õ¥Õ¶Õ¥Õ¬ ÕºÕ¡Õ¶Õ¡Õ¯Õ¨" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "Õ„Õ«Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´Õ¶ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¡Õ® Õ¹Õ§" + +#: ../gio/gfile.c:2762 +#, c-format +msgid "Error splicing file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ Õ´Õ«Õ¡Õ¾Õ¸Ö€Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "Õ‰Õ« Õ½Õ¿Õ¡ÖÕ¾Õ¸Ö‚Õ´ ÕºÕ¡Õ¿Õ³Õ¥Õ¶Õ¥Õ¬ Õ°Õ¡Õ¿Õ¸Ö‚Õ¯ ÕºÕ¡Õ¶Õ¡Õ¯Õ¨" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "ÕÖ€Õ¾Õ¡Õ® Õ§ Õ½Õ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ´Õ¡Õ¶ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Ö€ÕªÕ¥Ö„" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "Ô±Õ¦Õ¢Õ¡Õ´Õ¡Õ¶Õ¨ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¡Õ® Õ¹Õ§" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Õ–Õ¡ÕµÕ¬Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥Õ¬ '%c'" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "Õ€Õ¡Õ¿Õ¸Ö€Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¥Õ¬ Õ´Õ«Õ¡ÖÕ¸Ö‚Õ´Õ¨" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "Ô±ÕµÕ½ Ö†Õ¡ÕµÕ¬Õ« Õ´Õ·Õ¡Õ¯Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€ Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ®Ö€Õ¡Õ£Õ«Ö€ Õ£Ö€Õ¡Õ¶ÖÕ¾Õ¡Õ® Õ¹Õ«" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "Õ€Õ¡Õ·Õ¾Õ«Õ¹Õ¨ ÖƒÕ¡Õ¯ Õ§" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "Õ–Õ¡ÕµÕ¬Õ« Õ°Õ¡Õ·Õ¾Õ«Õ¹Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ¡Õ¾Õ¡Ö€Õ¿ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "Õ–Õ¡ÕµÕ¬Õ« Õ°Õ¡Õ·Õ¾Õ«Õ¹Õ¨ Õ¡Ö€Õ¤Õ¥Õ¶ ÖƒÕ¡Õ¯ Õ§" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ ÖƒÕ¸Õ­Õ¥Õ¬ GFileIcon Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ %d Õ¿Õ¥Õ½Õ¡Õ¯Õ¨" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "ÕÕ­Õ¡Õ¬ Õ±Ö‡Õ¡Õ¾Õ¸Ö€Õ¾Õ¡Õ® Õ´Õ¸Ö‚Õ¿Ö„Õ¡ÕµÕ«Õ¶ Õ¿Õ¾ÕµÕ¡Õ¬ GFileIcon Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "Õ€Õ¸Õ½Ö„Õ¨ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¸Ö‚Õ´ query_info" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "Õ€Õ¸Õ½Ö„Õ¸Õ¾ Õ¿Õ¥Õ²Õ¡Õ·Õ¡Ö€ÕªÕ¾Õ¥Õ¬Õ¨ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "ÕŽÕ¶Õ¡Õ½Õ¸Ö‚Õ´ Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¾Õ¡Õ® Õ¹Õ« Õ¥Õ¬Ö„Õ¡ÕµÕ«Õ¶ Õ°Õ¸Õ½Ö„Õ¸Ö‚Õ´" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "ÕŽÕ¶Õ¡Õ½Õ¸Ö‚Õ´ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´ Õ°Õ¸Õ½Ö„Õ¸Ö‚Õ´" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Ô²Õ¡Õ¼Õ¡Õ¶Õ«Õ·Õ¥Ö€Õ« Õ½Õ­Õ¡Õ¬ Ö„Õ¡Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ (%d)" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "%s Õ¤Õ¡Õ½Õ« Õ¡Õ¶Õ¾Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€ Õ¿Õ«Õº Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ«" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s Õ¿Õ«ÕºÕ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡Õ¾Õ¶Õ¸Ö‚Õ´ GIcon Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ¨" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "%s Õ¿Õ«ÕºÕ¨ Õ¹Õ« Õ°Õ¡Õ´Õ¡Ö€Õ¾Õ¸Ö‚Õ´ Õ¤Õ¡Õ½Õ¡Õ¯Õ¡Ö€Õ£Õ¾Õ¡Õ®" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "ÕŽÕ¡Õ¿ Õ±Ö‡Õ¡Õ¾Õ¸Ö€Õ¾Õ¡Õ® Õ¿Õ¥Õ½Õ¡Õ¯Õ« անուն․ %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s Õ¿Õ«ÕºÕ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ GIcon Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ« from_tokens()-Õ¨" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ´Õ·Õ¡Õ¯Õ¥Õ¬ ÕºÕ¡Õ¿Õ¯Õ¥Ö€Õ¡Õ¯Õ« Õ¿Õ¥Ö„Õ½Õ¿Õ¡ÕµÕ«Õ¶ Õ¶Õ¥Ö€Õ¯Õ¡ÕµÕ¡ÖÕ´Õ¡Õ¶ Õ¿Õ¾ÕµÕ¡Õ¬ Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "Õ„Õ¸Ö‚Õ¿Ö„Õ¡ÕµÕ«Õ¶ Õ°Õ¸Õ½Ö„Õ¨ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¸Ö‚Õ´ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¨ " + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "Õ€Õ¸Õ½Ö„Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ¡Õ¾Õ¡Ö€Õ¿ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "ÕÕ¸Õ¯Õ¥Õ¿Õ« Õ°Õ¡Õ½ÖÕ¥Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ¢Õ¡Õ¾Õ¡Õ¯Õ¡Õ¶Õ¡Õ¹Õ¡Öƒ Õ¿Õ¥Õ² Õ¹Õ¯Õ¡" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "ÕÕ¸Õ¯Õ¥Õ¿Õ« Õ¹Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Õ² Õ¡Õ¶Õ¸Ö‚Õ¶" + +#: ../gio/glib-compile-schemas.c:741 +msgid "empty names are not permitted" +msgstr "Ô´Õ¡Õ¿Õ¡Ö€Õ¯ Õ¡Õ¶Õ¾Õ¡Õ¶Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¨ Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¹Õ¥Õ¶" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶ '%s'․ Ô±Õ¶Õ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ½Õ¯Õ½Õ¾Õ¥Õ¶ ÖƒÕ¸Ö„Ö€Õ¡Õ¿Õ¡Õ¼Õ¸Õ¾" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" +"Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶ '%s'․ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¶Õ«Õ· '%c'; Õ´Õ«Õ¡ÕµÕ¶ ÖƒÕ¸Ö„Ö€Õ¡Õ¿Õ¡Õ¼Õ¥Ö€, Õ©Õ¾Õ¥Ö€ Ö‡ Õ£Õ®Õ«Õ¯Õ¶Õ¥Ö€ ('-') " +"Õ¥Õ¶ Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¾Õ¸Ö‚Õ´Ö‰" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶ '%s': Õ¸Ö€Õ¯Õ¸Ö‚ Õ°Õ¡Õ»Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Õ¶ Õ£Õ®Õ«Õ¯Õ¶Õ¥Ö€ ('--') Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¥Õ¬Õ« Õ¹Õ¥Õ¶Ö‰" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶ '%s'․ Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ¶Õ«Õ·Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¬Õ«Õ¶Õ¥Õ¬Õ£Õ®Õ«Õ¯ ('-')Ö‰" + +#: ../gio/glib-compile-schemas.c:789 +#, fuzzy, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶ '%s'․ Õ¡Õ¼Õ¡Õ¾Õ¥Õ¬Õ¡Õ£Õ¸Ö‚ÕµÕ¶ Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ 32 Õ§" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "<Õ¥Õ¶Õ©Õ¡Õ¿Õ¡Ö€Ö€Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨='%s'> Õ¡Ö€Õ¤Õ¥Õ¶ Õ¶Õ·Õ¾Õ¡Õ® Õ§" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "Õ¹Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¡Õ¾Õ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€ 'list-of' Õ½Õ­Õ¥Õ´Õ¡ÕµÕ«Õ¶" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "<Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Õ¶Õ¸Ö‚Õ¶='%s'> Õ¡Ö€Õ¤Õ¥Õ¶ Õ¶Õ·Õ¾Õ¡Õ® Õ§" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +"<Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Õ¶Õ¸Ö‚Õ¶='%s'> Õ®Õ¡Õ®Õ¯Õ¸Ö‚Õ´ Õ§ <Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Õ¶Õ¸Ö‚Õ¶='%s'> <Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« id='%s'> -Õ¸Ö‚Õ´; " +"Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ¡Ö€ÕªÕ¥Ö„Õ¨ ÖƒÕ¸ÖƒÕ¸Õ­Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"Õ³Õ«Õ·Õ¿ Õ´Õ¥Õ¯Õ¨ Õ°Õ¥Õ¿Ö‡ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ«ÖÕ 'Õ¿Õ«Õº', 'enum' Õ¯Õ¡Õ´ 'Õ¤Ö€Õ¸Õ·Õ¶Õ¥Ö€', ÕºÕ¥Õ¿Ö„ Õ§ Õ¶Õ·Õ¾Õ¡Õ® Õ¬Õ«Õ¶Õ« Õ¸Ö€ÕºÕ¥Õ½ " +"<Õ¢Õ¡Õ¶Õ¡Õ¬Õ«> Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> Õ¤Õ¥Õ¼Ö‡Õ½ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¾Õ¡Õ® Õ¹Õ§Ö‰" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ GVariant Õ¿Õ«ÕºÕ« Õ¿Õ¸Õ²Õ« Õ¡Õ¶Õ¸Ö‚Õ¶ '%s'" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr " Õ¿Ö€Õ¾Õ¡Õ® Õ§, Õ¢Õ¡ÕµÖ Õ½Õ­Õ¥Õ´Õ¡Õ¶ Õ¹Õ« Õ¨Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ¸Ö‚Õ´ Õ¸Ö€Ö‡Õ§ Õ¢Õ¡Õ¶" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« <Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Õ¶Õ¸Ö‚Õ¶='%s'> Õ¾Õ¥Ö€Õ¡Õ£Ö€Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr " Õ¡Ö€Õ¤Õ¥Õ¶ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¾Õ¡Õ® Õ§" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "<Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« id='%s'> Õ¡Ö€Õ¤Õ¥Õ¶ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¾Õ¡Õ® Õ§" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "<Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« id='%s'> Õ¨Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ¸Ö‚Õ´ Õ§ Õ¤Õ¥Õ¼Ö‡Õ½ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ¥ÖÕ¸Õ² Õ½Õ­Õ¥Õ´Õ¡Õ¶ '%s'" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "<Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« id='%s'> Õ¤Õ¥Õ¼Ö‡Õ½ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ¥ÖÕ¸Õ² '%s' Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« ÖÕ¸Ö‚ÖÕ¡Õ¯ Õ§" + +#: ../gio/glib-compile-schemas.c:1116 +#, fuzzy, c-format +msgid "Can not be a list of a schema with a path" +msgstr "Õ¹Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¡Õ¾Õ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€ 'list-of' Õ½Õ­Õ¥Õ´Õ¡ÕµÕ«Õ¶" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +"<Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« id='%s'> ÖÕ¸Ö‚ÖÕ¡Õ¯ Õ§, Õ¸Ö€Õ¶ Õ¨Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ¸Ö‚Õ´ Õ§ <Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« id='%s'>, Õ¸Ö€Õ¨ ÖÕ¸Ö‚ÖÕ¡Õ¯ Õ¹Õ§" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +"<Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« id='%s' list-of='%s'> Õ¨Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ¸Ö‚Õ´ Õ§ <Õ½Õ­Õ¥Õ´Õ¡ÕµÕ« id='%s' list-of='%s'> " +"Õ¢Õ¡ÕµÖ '%s' Õ¹Õ« Õ¨Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ¸Ö‚Õ´ '%s'" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "Õ³Õ¡Õ¶Õ¡ÕºÕ¡Ö€Õ°Õ¨, Õ¥Õ©Õ¥ Õ¿Ö€Õ¾Õ¡Õ® Õ§, ÕºÕ¥Õ¿Ö„ Õ§ Õ½Õ¯Õ½Õ¾Õ« Ö‡ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ« Õ©Õ¥Ö„ Õ£Õ®Õ¸Õ¾" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> Õ¡Ö€Õ¤Õ¥Õ¶ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¾Õ¡Õ® Õ§" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> Õ¿Õ¡Ö€Ö€Õ¨Õ¨ Õ¹Õ« Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¾Õ¸Ö‚Õ´ <%s> -Õ« Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> Õ¿Õ¡Ö€Ö€Õ¨ Õ¹Õ« Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¾Õ¸Ö‚Õ´ Õ¾Õ¥Ö€Õ«Õ¶ Õ´Õ¡Õ¯Õ¡Ö€Õ¤Õ¡Õ¯Õ¸Ö‚Õ´" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "Õ¿Õ¥Ö„Õ½Õ¿Õ¨ Õ¯Õ¡Ö€Õ¸Õ² Õ§ Õ¹Õ°Õ¡Õ¶Õ¤Õ«ÕºÕ¥Õ¬ <%s> -Õ« Õ¶Õ¥Ö€Õ½Õ¸Ö‚Õ´" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ« '%s' Õ½Õ­Õ¥Õ´Õ¡ÕµÕ¸Ö‚Õ´, Õ«Õ¶Õ¹ÕºÕ¥Õ½ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¾Õ¡Õ® Õ§ Õ¶Õ¸Ö€Õ«Ö " +"Õ¾Õ¥Ö€Õ¡Õ£Ö€Õ¾Õ¸Õ² '%s' Ö†Õ¡ÕµÕ¬Õ¸Ö‚Õ´" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, fuzzy, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" +"Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ« '%s' Õ½Õ­Õ¥Õ´Õ¡ÕµÕ¸Ö‚Õ´, Õ«Õ¶Õ¹ÕºÕ¥Õ½ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¾Õ¡Õ® Õ§ Õ¶Õ¸Ö€Õ«Ö " +"Õ¾Õ¥Ö€Õ¡Õ£Ö€Õ¾Õ¸Õ² '%s' Ö†Õ¡ÕµÕ¬Õ¸Ö‚Õ´" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" +"Õ¾Õ¥Ö€Õ¡Õ£Ö€Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ '%s' Õ½Õ­Õ¥Õ´Õ¡ÕµÕ¸Ö‚Õ´ '%s' Õ¾Õ¥Ö€Õ¡Õ£Ö€Õ¾Õ¸Õ² Ö†Õ¡ÕµÕ¬Õ¸Ö‚Õ´ " +"Õ½Õ­Õ¥Õ´Õ¡ÕµÕ¸Ö‚Õ´ Õ¿Ö€Õ¾Õ¡Õ® Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¶Õ¥Ö€Õ«Ö Õ¤Õ¸Ö‚Ö€Õ½ Õ§" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"Õ¾Õ¥Ö€Õ¡Õ£Ö€Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ '%s' Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ '%s' Õ½Õ­Õ¥Õ´Õ¡ÕµÕ¸Ö‚Õ´ '%s' Õ¾Õ¥Ö€Õ¡Õ£Ö€Õ¾Õ¸Õ² Ö†Õ¡ÕµÕ¬Õ¸Ö‚Õ´ Õ¾Õ¡Õ¾Õ¥Ö€ " +"Õ¨Õ¶Õ¿Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ« ÖÕ¸Ö‚ÖÕ¡Õ¯Õ¸Ö‚Õ´ Õ¹Õ§" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "ÕˆÖ€Õ¿Õ¥Õ² Õ¿Õ¥Õ²Õ¡Õ¾Õ¸Ö€Õ¥Õ¬ gschemas.compiled Ö†Õ¡ÕµÕ¬Õ¨" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "ÕŠÕ¡Õ¶Õ¡Õ¯" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "Õ‰Õ£Ö€Õ¥Õ¬ gschemas.compiled Ö†Õ¡ÕµÕ¬Õ¨" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "Ô±ÕµÕ½ Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ¨ Õ·Õ¸Ö‚Õ¿Õ¸Õ¾ Õ¯Õ°Õ¥Õ¼Õ¡ÖÕ¾Õ«" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "Õ‰ÕºÕ¡Ö€Õ¿Õ¡Õ¤Ö€Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Õ¶Õ¾Õ¡Õ¶ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¡ÕºÕ¡Õ¯Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¨" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Ô¿Õ¡Õ¦Õ´Õ¡Ö€Õ¯Õ¥Õ¬ Õ¢Õ¸Õ¬Õ¸Ö€ GSettings schema Ö†Õ¡ÕµÕ¬Õ¥Ö€Õ¨ schema cache-Õ¸Ö‚Õ´Ö‰\n" +"Schema Ö†Õ¡ÕµÕ¬Õ¥Ö€Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ¸Ö‚Õ¶Õ¥Õ¶Õ¡Õ¶ .gschema.xml Õ¨Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ¸Ö‚Õ´,\n" +"Ö‡ cache Ö†Õ¡ÕµÕ¬Õ¨ Õ¯Õ¸Õ¹Õ¾Õ¸Ö‚Õ´ Õ§ gschemas.compiledÖ‰" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "ÕŠÕ¥Õ¿Ö„ Õ§ Õ¶Õ·Õ¥Õ¬ Õ³Õ«Õ·Õ¿ Õ´Õ¥Õ¯ ÕºÕ¡Õ¶Õ¡Õ¯Õ« Õ¡Õ¶Õ¸Ö‚Õ¶\n" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "schema Ö†Õ¡ÕµÕ¬ Õ¹Õ« գտնվել․" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "Õ¸Õ¹Õ«Õ¶Õ¹ Õ¹Õ¡Õ¶Õ¥Õ¬Ö‰\n" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "Õ°Õ¥Õ¼Õ¡ÖÕ¾Õ¥Õ¬ Õ§ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¸Ö‚Õ¶Õ¥ÖÕ¸Õ² Õ¥Õ¬Ö„Õ¡ÕµÕ«Õ¶ Ö†Õ¡ÕµÕ¬Õ¨Ö‰\n" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¸Ö‚Õ´ Õ¬Õ¼Õ¥Õ¬ÕµÕ¡ÕµÕ¶ Õ¿Õ¥Õ²Õ¡ÕµÕ«Õ¶ ÕºÕ¡Õ¶Õ¡Õ¯Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ£Õ¿Õ¶Õ¥Õ¬ ÖÕ¸Ö‚ÖÕ¡Ö€Õ¯Õ¹Õ« Õ¿Õ«ÕºÕ¨" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ« %s Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Ö†Õ¡ÕµÕ¬Õ¡ÕµÕ«Õ¶ Õ°Õ¡Õ´Õ¡Õ¯Ö€Õ£Õ« Õ´Õ¡Õ½Õ«Õ¶ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿Õ¾Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ ստանալիս․ %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¸Ö‚Õ´ Õ¾Õ¥Ö€Õ¡Õ¶Õ¾Õ¡Õ¶Õ¥Õ¬ root ÕºÕ¡Õ¶Õ¡Õ¯Õ¨" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ Õ¡Õ¶Õ¾Õ¡Õ¶Õ¡ÖƒÕ¸Õ­Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¸Ö‚Õ´ Õ¾Õ¥Ö€Õ¡Õ¶Õ¾Õ¡Õ¶Õ¥Õ¬ Ö†Õ¡ÕµÕ¬Õ¨, Ö†Õ¡ÕµÕ¬Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¶ Õ¡Ö€Õ¤Õ¥Õ¶ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¸Ö‚Õ¶Õ«" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Ö†Õ¡ÕµÕ¬Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Õ–Õ¡ÕµÕ¬ Õ¢Õ¡ÖÕ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "Õ‰Õ« Õ½Õ¿Õ¡ÖÕ¾Õ¸Ö‚Õ´ Õ¢Õ¡ÖÕ¥Õ¬ ÕºÕ¡Õ¶Õ¡Õ¯" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Õ–Õ¡ÕµÕ¬ Õ»Õ¶Õ»Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ Õ¡Õ²Õ¢Õ¡Õ´Õ¡Õ¶Õ« Õ´Õ¥Õ» Õ¸Ö‚Õ²Õ¡Ö€Õ¯Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ '%s' Õ¡Õ²Õ¢Õ¡Õ´Õ¡Õ¶ պանակ․ %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ£Õ¿Õ¶Õ¥Õ¬ Õ¾Õ¥Ö€Õ«Õ¶ Õ´Õ¡Õ¯Õ¡Ö€Õ¤Õ¡Õ¯Õ« ÕºÕ¡Õ¶Õ¡Õ¯ Õ¡Õ²Õ¢Õ¡Õ´Õ¡Õ¶Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr " Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ£Õ¿Õ¶Õ¥Õ¬ Õ¯Õ¡Õ´ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ¡Õ²Õ¢Õ¡Õ´Õ¡Õ¶ ÕºÕ¡Õ¶Õ¡Õ¯Õ¨" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ«Õ¶Ö†Õ¸Ö€Õ´Õ¡ÖÕ«Õ¡ Õ¡Õ²Õ¢Õ¡Õ´Õ¡Õ¶Õ¸Ö‚Õ´ Õ£Õ¿Õ¶Õ¾Õ¸Õ² Ö†Õ¡ÕµÕ¬Õ« մասին․ %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ¸Ö‚Õ²Õ¡Ö€Õ¯Õ¥Õ¬ Ö†Õ¡ÕµÕ¬Õ¨ Õ¡Õ²Õ¢Õ¡Õ´Õ¡Õ¶Õ« մեջ․ %s" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "ÕŠÕ¡Õ¶Õ¡Õ¯ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Õ–Õ¡ÕµÕ¬Õ¡ÕµÕ«Õ¶ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ¨ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¸Ö‚Õ´ Õ½Õ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ¸Ö‚Õ´Õ¶Õ¥Ö€" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "ÕÕ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ¸Ö‚Õ´ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ« Õ¿Õ¥Õ²Õ¡ÖƒÕ¸Õ­Õ´Õ¡Õ¶ սխալ․ %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "Õ€Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ¹Õ§ Õ¿Õ¥Õ²Õ¡ÖƒÕ¸Õ­Õ¥Õ¬ ÕºÕ¡Õ¶Õ¡Õ¯Õ¨ ÕºÕ¡Õ¶Õ¡Õ¯Õ« Õ¾Ö€Õ¡ÕµÕ¸Õ¾" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ ÕºÕ¡Õ°Õ¸Ö‚Õ½Õ¿Õ¡ÕµÕ«Õ¶ Ö†Õ¡ÕµÕ¬" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "Õ†ÕºÕ¡Õ¿Õ¡Õ¯Õ¡Õ¯Õ¥Õ¿Õ« Ö†Õ¡ÕµÕ¬Õ¨ Õ°Õ¥Õ¼Õ¡ÖÕ¶Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "ÕÕ¥Õ²Õ¡Õ¤Ö€Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ« Õ¯Õ¥Õ¿Õ¥Ö€Õ« Õ´Õ«Õ»Ö‡ Õ¿Õ¥Õ²Õ¡ÖƒÕ¸Õ­Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Ö‚Õ´" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "Ô±Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ¹ÕºÕ¥Õ¿Ö„ Õ§ Õ¬Õ«Õ¶Õ« NULL" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "Ô±Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶ (Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ Õ¿Õ¸Õ²)" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "Ô¸Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ¾Õ¡Õ® Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Õ¶Õ¸Ö‚Õ¶" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "'%s' Õ¨Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ¾Õ¡Õ® Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ¨ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "'%s' Ö†Õ¡ÕµÕ¬Õ« Õ´Õ¡Õ½Õ«Õ¶ Õ¿Õ¥Õ²Õ¥Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€ Õ½Õ¿Õ¡Õ¶Õ¡Õ¬Õ«Õ½ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® սխալ․ %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "(Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ« Õ¤Õ¥Õ½Õ¯Ö€Õ«ÕºÕ¿Õ¸Ö€Õ¨ Õ½Õ¿Õ¡Õ¶Õ¡Õ¬Õ«Õ½ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® սխալ․ %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ô±Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¿Õ¥Õ½Õ¡Õ¯ (Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ uint32)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ô±Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¿Õ¥Õ½Õ¡Õ¯ (Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ uint64)" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ô±Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¿Õ¥Õ½Õ¡Õ¯ (Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ byte Õ¿Õ¸Õ²)" + +#: ../gio/glocalfileinfo.c:1904 +msgid "Cannot set permissions on symlinks" +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¥Õ¬ Õ¡Ö€Õ¿Õ¸Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€ Õ½Õ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ´Õ¡Õ¶ համար․ %s" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Ô±Ö€Õ¿Õ¸Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "ÕÕ­Õ¡Õ¬ Õ½Õ¥ÖƒÕ¡Õ¯Õ¡Õ¶Õ¡Õ¿Õ¥Ö€ սահմանելիս․ %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "ÕÕ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ¸Ö‚Õ´Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ¬Õ«Õ¶Õ« Õ¸Õ¹ NULL" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "ÕÕ­Õ¡Õ¬ Õ½Õ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ¸Ö‚Õ´ սահմանելիս․ %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ½Õ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ հղում․ Ö†Õ¡ÕµÕ¬Õ¨ Õ½Õ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ¸Ö‚Õ´ Õ¹Õ§" + +#: ../gio/glocalfileinfo.c:2139 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" +"ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® ÖƒÕ¸ÖƒÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€ Õ¯Õ¡Õ´ Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ«Õ¸Ö‚Õ©ÕµÕ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯Õ¨ սահմանելիս․ %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "SELinux Õ¯Õ¸Õ¶Õ¿Õ¥Ö„Õ½Õ¿Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ¬Õ«Õ¶Õ« Õ¸Õ¹ NULL" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux Õ¯Õ¸Õ¶Õ¿Õ¥Ö„Õ½Õ¿Õ« Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ´Õ¡Õ¶ սխալ․ %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "SELinux Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ¹Õ§ Õ¡ÕµÕ½ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ¸Ö‚Õ´" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s Õ¡Õ¿Ö€Õ«Õ¢Õ¸Ö‚Õ¿Õ« Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ«Ö Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ« Õ¾Ö€Õ¡ÕµÕ¸Õ¾ Õ¡Õ¶ÖÕ¶Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ ÖƒÕ¡Õ¯Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ£Õ¿Õ¶Õ¥Õ¬ Õ¬Õ¼Õ¥Õ¬ÕµÕ¡ÕµÕ¶ Õ¿Õ¥Õ²Õ¡ÕµÕ«Õ¶ Ö†Õ¡ÕµÕ¬Õ¥Ö€Õ« Õ´Õ¸Õ¶Õ«Õ¿Õ¸Ö€Õ« Õ¿Õ«ÕºÕ¨ " + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ¸Ö‚Õ´ Õ£Ö€Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ»Õ¶Õ»Õ¥Õ¬ Õ°Õ«Õ¶ ÕºÕ¡Õ°Õ¸Ö‚Õ½Õ¿Õ¡ÕµÕ«Õ¶ ֆայլերը․ %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "ÕŠÕ¡Õ°Õ¥Õ½Õ¿Õ¡ÕµÕ«Õ¶ Õ¯Ö€Õ¯Õ¶Ö…Ö€Õ«Õ¶Õ¡Õ¯ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ«Õ½ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® սխալ․ %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "ÔºÕ¡Õ´Õ¡Õ¶Õ¡Õ¯Õ¡Õ¾Õ¸Ö€ Ö†Õ¡ÕµÕ¬Õ¶ Õ¡Õ¶Õ¾Õ¡Õ¶Õ¡ÖƒÕ¸Õ­Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ Õ¯Õ¿Ö€Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "'%s' Õ–Õ¡ÕµÕ¬Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "Õ†ÕºÕ¡Õ¿Õ¡Õ¯Õ¡Õ¯Õ¥Õ¿Õ« Ö†Õ¡ÕµÕ¬Õ¨ ÕºÕ¡Õ¶Õ¡Õ¯ Õ§" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "Õ†ÕºÕ¡Õ¿Õ¡Õ¯Õ¡Õ¯Õ¥Õ¿Õ« Ö†Õ¡ÕµÕ¬Õ¨ Õ¯Õ¡Õ¶Õ¸Õ¶Õ¡Õ¾Õ¸Ö€ Ö†Õ¡ÕµÕ¬ Õ¹Õ§" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "Õ–Õ¡ÕµÕ¬Õ¨ Õ¡Ö€Õ¿Õ¡Ö„Õ«Õ¶Õ«Ö ÖƒÕ¸ÖƒÕ¸Õ­Õ¾Õ¥Õ¬ Õ§" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "Õ€Õ«Õ¶ Ö†Õ¡ÕµÕ¬Õ¨ Õ»Õ¶Õ»Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "Õ“Õ¸Õ­Õ¡Õ¶ÖÕ¾Õ¡Õ® Õ§ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ GSeekType" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Õ‰Õ« Õ¯Õ¡Ö€Õ¥Õ¬Õ« Õ¾Õ¶Õ¡Õ½Õ¥Õ¬ GMemoryInputStream-Õ¨" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Õ‰Õ« Õ¯Õ¡Ö€Õ¥Õ¬Õ« Õ¾Õ¶Õ¡Õ½Õ¥Õ¬ GMemoryInputStream-Õ¨" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "ÔµÕ¬Ö„Õ¡ÕµÕ«Õ¶ Õ°Õ¸Õ½Ö„Õ« Õ¹Õ¡ÖƒÕ¨ Õ°Õ«Õ·Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¥Õ» ÖƒÕ¸ÖƒÕ¸Õ­Õ¥Õ¬Õ« Õ¹Õ§" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ ÖƒÕ¸ÖƒÕ¸Õ­Õ¥Õ¬ Õ¥Õ¬Ö„Õ¡ÕµÕ«Õ¶ Õ°Õ¸Õ½Ö„Õ« Õ¹Õ¡ÖƒÕ¨ Õ°Õ«Õ·Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¥Õ»" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Ô³Ö€Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ ÕºÕ¡Õ°Õ¡Õ¶Õ»Õ¾Õ¸Õ² Õ°Õ«Õ·Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¹Õ¡ÖƒÕ¨ Õ¡Õ¾Õ¥Õ¬Õ« Õ´Õ¥Õ® Õ§ Ö„Õ¡Õ¶ Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€Õ« " +"Õ¿Õ«Ö€Õ¸Ö‚ÕµÕ©Õ¨" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "ÕŠÕ¡Õ°Õ¡Õ¶Õ»Õ¾Õ¥Õ¬ Õ§ Õ¿Õ¥Õ²Õ¡ÖƒÕ¸Õ­Õ¸Ö‚Õ´ Õ°Õ¸Õ½Ö„Õ¨ Õ½Õ¯Õ½Õ¾Õ¥Õ¬Õ¸Ö‚Ö Õ¡Õ¼Õ¡Õ»" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "ÕŠÕ¡Õ°Õ¡Õ¶Õ»Õ¾Õ¥Õ¬ Õ§ Õ¿Õ¥Õ²Õ¡ÖƒÕ¸Õ­Õ¸Ö‚Õ´ Õ°Õ¸Õ½Ö„Õ« Õ¡Õ¾Õ¡Ö€Õ¿Õ«Õ¶" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "ÕÕ¥Õ²Õ¡Õ¤Ö€Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÖ€Õ¥Õ¬ \"Õ¡ÕºÕ¡Õ´Õ¸Õ¶Õ¿Õ¡ÕªÕ¸Ö‚Õ´Õ¨\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "ÕÕ¥Õ²Õ¡Õ¤Ö€Ö‚Õ´Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÖ€Õ¥Õ¬ \"Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¥Õ¬Õ¨ \"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"ÕÕ¥Õ²Õ¡Õ¤Ö€Ö‚Õ´Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÖ€Õ¥Õ¬ \"Õ¡ÕºÕ¡Õ´Õ¸Õ¶Õ¿Õ¡ÕªÕ¸Ö‚Õ´Õ¨\" Õ¯Õ¡Õ´ \"Õ¡ÕºÕ¡Õ´Õ¸Õ¶Õ¿Õ¡ÕªÕ¸Ö‚Õ´ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢" +"\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"ÕÕ¥Õ²Õ¡Õ¤Ö€Ö‚Õ´Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÖ€Õ¥Õ¬ \"Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¥Õ¬\" Õ¯Õ¡Õ´ \"Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¥Õ¬ Õ£Õ¸Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "ÕÕ¥Õ²Õ¡Õ¤Ö€Ö‚Õ´Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÖ€Õ¥Õ¬ \"Õ¾Õ¥Ö€Õ¡Õ´Õ¸Õ¶Õ¿Õ¡ÕªÕ¸Ö‚Õ´Õ¨\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "ÕÕ¥Õ²Õ¡Õ¤Ö€Ö‚Õ´Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¿Õ«ÕºÕ« Õ¸Ö€Õ¸Õ·Õ¸Ö‚Õ´Õ¨" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "ÕÕ¥Õ²Õ¡Õ¤Ö€Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¿Õ«ÕºÕ« Õ½Õ«Õ¶Õ­Ö€Õ¸Õ¶ Õ¸Ö€Õ¸Õ·Õ¸Ö‚Õ´Õ¨ " + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "'%s' Hostname-Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ '[' Õ¢Õ¡ÕµÖ Õ¸Õ¹ ']' " + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "ÔµÕ¬Ö„Õ¡ÕµÕ«Õ¶ Õ°Õ¸Õ½Ö„Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ Õ£Ö€Õ¥Õ¬Õ¨" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "ÕÕ¯Õ¦Õ¢Õ¶Õ¡Õ¯Õ¡Õ¶ Õ°Õ¸Õ½Ö„Õ¨ Õ¡Ö€Õ¤Õ¥Õ¶ ÖƒÕ¡Õ¯ Õ§" + +#: ../gio/gresolver.c:779 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' - Õ« Õ¬Õ¸Ö‚Õ®Õ´Õ¡Õ¶ սխալ․ %s" + +#: ../gio/gresolver.c:829 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' - Õ« Õ°Õ¡Õ¯Õ¡Õ¤Õ¡Ö€Õ± Õ¬Õ¸Ö‚Õ®Õ´Õ¡Õ¶ սխալ․ %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« Õ®Õ¡Õ¼Õ¡ÕµÕ¸Õ²Õ¡Õ¯Õ¡Õ¶ Õ£Ö€Õ¡Õ¼Õ¸Ö‚Õ´ '%s' -Õ« Õ°Õ¡Õ´Õ¡Ö€" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "ÔºÕ¡Õ´Õ¡Õ¶Õ¡Õ¯Õ¡Õ¾Õ¸Ö€Õ¡ÕºÕ¥Õ½ Õ°Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ¹Õ§ Õ¬Õ¸Ö‚Õ®Õ¥Õ¬ '%s'" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, c-format +msgid "Error resolving '%s'" +msgstr "Ô¼Õ¸Ö‚Õ®Õ´Õ¡Õ¶ սխալ․ %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, fuzzy, c-format +msgid "No such schema '%s'\n" +msgstr "Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, fuzzy, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "Õ³Õ¡Õ¶Õ¡ÕºÕ¡Ö€Õ°Õ¨, Õ¥Õ©Õ¥ Õ¿Ö€Õ¾Õ¡Õ® Õ§, ÕºÕ¥Õ¿Ö„ Õ§ Õ½Õ¯Õ½Õ¾Õ« Ö‡ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ« Õ©Õ¥Ö„ Õ£Õ®Õ¸Õ¾" + +#: ../gio/gsettings-tool.c:104 +#, fuzzy, c-format +msgid "Path must end with a slash (/)\n" +msgstr "Õ³Õ¡Õ¶Õ¡ÕºÕ¡Ö€Õ°Õ¨, Õ¥Õ©Õ¥ Õ¿Ö€Õ¾Õ¡Õ® Õ§, ÕºÕ¥Õ¿Ö„ Õ§ Õ½Õ¯Õ½Õ¾Õ« Ö‡ Õ¡Õ¾Õ¡Ö€Õ¿Õ¾Õ« Õ©Õ¥Ö„ Õ£Õ®Õ¸Õ¾" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, fuzzy, c-format +msgid "No such key '%s'\n" +msgstr "'%s' Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« " + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +#, fuzzy +msgid "Print help" +msgstr "ÕÕºÕ¥Õ¬ XML" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "ÕÕ¿Õ¡Õ¶Õ¡Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Ö€ÕªÕ¥Ö„Õ¨" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +#, fuzzy +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA-Ô» Ô²Ô±Õ†Ô±Ô¼Ô»" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +#, fuzzy +msgid "Set the value of KEY to VALUE" +msgstr "ÕÕ¥Õ²Õ¡Õ¤Ö€Õ¥Õ¬ Ô²Ô±Õ†Ô±Ô¼ÕˆÕ’ Õ¡Ö€ÕªÕ¥Ö„Õ¨" + +#: ../gio/gsettings-tool.c:583 +#, fuzzy +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ÕÔ½ÔµÕ„Ô±Õ…Ô» Ô²Ô±Õ†Ô±Ô¼ÕˆÕ’ Ô±ÕÔºÔµÕ”" + +#: ../gio/gsettings-tool.c:588 +#, fuzzy +msgid "Reset KEY to its default value" +msgstr "ÕÕ¡Õ°Õ´Õ¡Õ¶Õ¸Ö‚Õ´ Õ§ Ô²Ô±Õ†Ô±Ô¼Ô»Õ† Õ«Ö€ Õ¬Õ¼Õ¥Õ¬ÕµÕ¡ÕµÕ¶ Õ¡Ö€ÕªÕ¥Ö„Õ¸Õ¾" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +#, fuzzy +msgid "Check if KEY is writable" +msgstr "ÕŠÕ¡Ö€Õ¦Õ¥Õ¬ Õ¡Ö€Õ¤ÕµÕ¸Ö„ Ô²Ô±Õ†Ô±Ô¼Ô»Õ† Õ£Ö€Õ¾Õ¸Õ² Õ§" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +#, fuzzy +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA-Ô» Ô²Ô±Õ†Ô±Ô¼Ô»" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Ô±Õ¶Õ°Õ¡ÕµÕ¿ Õ°Ö€Õ¡Õ´Õ¡Õ¶ '%s'\n" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +#, fuzzy +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +"Արգումենտներ․\n" +" ÕÔ½ÔµÕ„Ô± ÕÕ­Õ¥Õ´Õ¡ÕµÕ« id\n" +" Ô²Ô±Õ†Ô±Ô¼Ô» Ô²Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Õ¶Õ¸Ö‚Õ¶\n" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ½Õ¸Õ¯Õ¥Õ¿, Õ½Õ¯Õ¦Õ¢Õ¶Õ¡Ö€ÕªÕ¥Ö„Õ¡Õ¾Õ¸Ö€Õ¾Õ¡Õ® Õ¹Õ§" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ½Õ¸Õ¯Õ¥Õ¿, Õ½Õ¯Õ¦Õ¢Õ¶Õ¡Ö€ÕªÕ¥Ö„Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¾Õ¥Õ¬ Õ°Õ¥Õ¿Ö‡ÕµÕ¡Õ¬ պատճառով․ %s" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "ÕÕ¸Õ¯Õ¥Õ¿Õ¨ Õ¡Ö€Õ¤Õ¥Õ¶ ÖƒÕ¡Õ¯ Õ§" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "I/O Õ½Õ¸Õ¯Õ¥Õ¿Õ« ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯Õ¨ Õ¬Ö€Õ¡ÖÕ¥Õ¬ Õ§" + +#: ../gio/gsocket.c:464 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ÕÕ¿Õ¥Õ²Õ®Õ¥Õ¬ GSocket fd-Õ«Ö․ %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ սոկետ․ %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "Õ†Õ·Õ¾Õ¡Õ® Õ§ Õ¡Õ¶Õ°Õ¡ÕµÕ¿ ÕºÖ€Õ¸Õ¿Õ¸Õ¯Õ¸Õ¬" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "Õ‰Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ½Õ¿Õ¡Õ¶Õ¡Õ¬ Õ¿Õ¥Õ²Õ¡ÕµÕ«Õ¶ Õ°Õ¡Õ½Öեն․ %s" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "Õ‰Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ½Õ¿Õ¡Õ¶Õ¡Õ¬ Õ°Õ¥Õ¼Õ¡Õ¤Õ«Ö€ Õ°Õ¡Õ½Öեն․ %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "Õ‰Õ« Õ¯Õ¡Ö€Õ¸Õ² լսել․ %s" + +#: ../gio/gsocket.c:1446 +#, c-format +msgid "Error binding to address: %s" +msgstr "Õ€Õ¡Õ½ÖÕ¥Õ«Õ¶ Õ¯Õ¡ÕºÕ¾Õ¥Õ¬Õ¸Ö‚ սխալ․ %s" + +#: ../gio/gsocket.c:1566 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ¯Õ¡ÕºÕ« Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¸Ö‚Õ´Õ¨ Õ¨Õ¶Õ¤Õ¸Ö‚Õ¶Õ¥Õ¬Õ %s" + +#: ../gio/gsocket.c:1683 +msgid "Error connecting: " +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¥Õ¬ կապ․" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "Ô¿Õ¡Õ¿Õ¡Ö€Õ¾Õ¸Ö‚Õ´ Õ§ Õ´Õ«Õ¡ÖÕ¸Ö‚Õ´" + +#: ../gio/gsocket.c:1695 +#, c-format +msgid "Error connecting: %s" +msgstr "Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¥Õ¬ կապ․ %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¡Õ¶Õ¡Õ¬ Õ½ÕºÕ¡Õ½Õ¾Õ¡Õ® սխալը․ %s" + +#: ../gio/gsocket.c:1875 +#, c-format +msgid "Error receiving data: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ¶ ստանալիս․ %s" + +#: ../gio/gsocket.c:2050 +#, c-format +msgid "Error sending data: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ¶ ուղարկելիս․ %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ սոկետ․ %s" + +#: ../gio/gsocket.c:2242 +#, c-format +msgid "Error closing socket: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® Õ½Õ¸Õ¯Õ¥Õ¿Õ¨ փակելիս․ %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ÕÕºÕ¡Õ½Õ¸Ö‚Õ´ Õ§ Õ½Õ¸Õ¯Õ¥Õ¿Õ« վիճակին․ %s" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, c-format +msgid "Error sending message: %s" +msgstr "Õ€Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¸Ö‚Õ²Õ¡Ö€Õ¯Õ´Õ¡Õ¶ սխալ․ %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "SocketControlMessage-Õ¨ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Ö‚Õ´ windows-Õ¸Ö‚Õ´ " + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, c-format +msgid "Error receiving message: %s" +msgstr "Õ€Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ½Õ¿Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® սխալ․ %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials-Õ¨ Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¾Õ¡Õ® Õ¹Õ§ Õ¡ÕµÕ½ Õ•Õ€-Õ« Õ¾Ö€Õ¡" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "Õ‰Õ°Õ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥Ö€Õ¾Õ¡Õ® Õ½Õ­Õ¡Õ¬ Õ¯Õ¡ÕºÕ« ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "ÕˆÕ¹ TCP Õ¯Õ¡ÕºÕ« Õ´Õ«Õ»Õ¸ÖÕ¸Õ¾ ÖƒÕ¸Ö€Õ±Õ¥Õ¬ ÕºÖ€Õ¸Ö„Õ½Õ«Õ« Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Ö‚Õ´" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "'%s' ÕºÖ€Õ¸Ö„Õ½Õ« ÕºÖ€Õ¸Õ¿Õ¸Õ¯Õ¸Õ¬Õ¨ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Ö‚Õ´" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "Ô¼Õ½Õ¸Õ²Õ¨ Õ¡Ö€Õ¤Õ¥Õ¶ ÖƒÕ¡Õ¯ Õ§" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "Ô±Õ¾Õ¥Õ¬Õ¡ÖÕ¾Õ¡Õ® Õ½Õ¸Õ¯Õ¥Õ¿Õ¨ ÖƒÕ¡Õ¯ Õ§" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ´ IPv6 '%s' Õ°Õ¡Õ½ÖÕ¥Õ¶" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" +"SOCKSv4 Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¸Ö‚Õ´Õ¨ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¡ÖƒÕ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ›Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Õ²Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨Õ› Õ´Õ«Õ¶Õ¹Ö‡ %i Õ¶Õ«Õ·Õ«" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "SOCKSv4a Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¸Ö‚Õ´Õ¨ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¡ÖƒÕ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ°Õ¸Õ½Õ©Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ´Õ«Õ¶Õ¹Ö‡ %i Õ¶Õ«Õ·Õ«" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "ÕÕ¥Ö€Õ¾Õ¥Ö€Õ¨ SOCKSv4 ÕºÖ€Õ¸Ö„Õ½Õ« Õ½Õ¥Ö€Õ¾Õ¥Ö€ Õ¹Õ§Ö‰" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 Õ½Õ¥Ö€Õ¾Õ¥Ö€Õ« Õ´Õ«Õ»Õ¸ÖÕ¸Õ¾ Õ¯Õ¡ÕºÕ¨ Õ´Õ¥Ö€ÕªÕ¾Õ¥Õ¬ Õ§" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "ÕÕ¥Ö€Õ¾Õ¥Ö€Õ¨ SOCKSv5 ÕºÖ€Õ¸Ö„Õ½Õ« Õ½Õ¥Ö€Õ¾Õ¥Ö€ Õ¹Õ§Ö‰" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 ÕºÖ€Õ¸Ö„Õ½Õ«Õ¶ ÕºÕ¡Õ°Õ¡Õ¶Õ»Õ¸Ö‚Õ´ Õ§ Õ¾Õ¡Õ¾Õ¥Ö€Õ¡ÖÕ¸Ö‚Õ´" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 ÕºÕ¡Õ°Õ¡Õ¶Õ»Õ¸Ö‚Õ´ Õ§ Õ¾Õ¡Õ¾Õ¥Ö€Õ¡ÖÕ´Õ¡Õ¶ Õ´Õ¥Õ©Õ¸Õ¤, Õ¸Ö€Õ¨ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Ö‚Õ´ GLib-Õ« Õ¯Õ¸Õ²Õ´Õ«ÖÖ‰" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" +"Õ•Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Õ²Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ¯Õ¡Õ´ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¨ Õ¹Õ¡ÖƒÕ¡Õ¦Õ¡Õ¶Ö Õ¥Ö€Õ¯Õ¡Ö€ Õ§ SOCKSv5 ÕºÖ€Õ¸Õ¿Õ¸Õ¯Õ¸Õ¬Õ« Õ°Õ¡Õ´Õ¡Ö€ " +"(Õ¡Õ¼Õ¡Õ¾Õ¥Õ¬Õ¡Õ£Õ¸Ö‚ÕµÕ¶Õ¨ %i)Ö‰" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5 Õ¾Õ¡Õ¾Õ¥Ö€Õ¡ÖÕ¸Ö‚Õ´Õ¨ Õ±Õ¡Õ­Õ¸Õ²Õ¾Õ¥Õ¬ Õ§ Õ½Õ­Õ¡Õ¬ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Õ²Õ« Õ¡Õ¶Õ¾Õ¡Õ¶ Õ¯Õ¡Õ´ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ« " +"ÕºÕ¡Õ¿Õ³Õ¡Õ¼Õ¸Õ¾Ö‰" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" +"'%s' Õ°Õ¸Õ½Õ©Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨ Õ¹Õ¡ÖƒÕ¡Õ¦Õ¡Õ¶Ö Õ¥Ö€Õ¯Õ¡Ö€ Õ§ SOCKSv5 ÕºÖ€Õ¸Õ¿Õ¸Õ¯Õ¸Õ¬Õ« Õ°Õ¡Õ´Õ¡Ö€ (Õ¡Õ¼Õ¡Õ¾Õ¥Õ¬Õ¡Õ£Õ¸Ö‚ÕµÕ¶Õ¨ %i " +"Õ¢Õ¡ÕµÕ©)" + +#: ../gio/gsocks5proxy.c:352 +#, fuzzy +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 ÕºÖ€Õ¸Ö„Õ½Õ« Õ½Õ¥Ö€Õ¾Õ¥Ö€Õ¨ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ°Õ¡ÕµÕ¿ Õ°Õ¡Õ½ÖÕ¥Õ« Õ¿Õ«ÕºÖ‰" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Ô»Õ¶Õ¿Õ¥Ö€Õ¶Õ¡Õ¬ SOCKSv5 ÕºÖ€Õ¸Ö„Õ½Õ« Õ½Õ¥Ö€Õ¾Õ¥Ö€Õ« Õ½Õ­Õ¡Õ¬Ö‰" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 Õ¯Õ¡ÕºÕ¨ Õ¹Õ« Õ©Õ¸Ö‚ÕµÕ¬Õ¡Õ¿Ö€Õ¾Õ¸Ö‚Õ´ Õ¯Õ¡Õ¶Õ¸Õ¶Õ¶Õ¥Ö€Õ¨ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¸Õ²Õ« Õ¯Õ¸Õ²Õ´Õ«ÖÖ‰" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Õ€Õ¸Õ½Õ©Õ¨ Õ¡Õ¶Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ§ SOCKSv Õ½Õ¥Ö€Õ¾Õ¥Ö€Õ« Õ´Õ«Õ»Õ¸ÖÕ¸Õ¾Ö‰" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Õ‘Õ¡Õ¶ÖÕ¨ Õ¡Õ¶Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ§ SOCKSv ÕºÖ€Õ¸Ö„Õ½Õ«Õ« Õ´Õ«Õ»Õ¸ÖÕ¸Õ¾Ö‰" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 ÕºÖ€Õ¸Ö„Õ½Õ«Õ« Õ´Õ«Õ»Õ¸ÖÕ¸Õ¾ Õ¯Õ¡ÕºÕ¨ Õ´Õ¥Ö€ÕªÕ¾Õ¥Õ¬ Õ§Ö‰" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 ÕºÖ€Õ¸Ö„Õ½Õ«Õ¶ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ´ 'Õ´Õ«Õ¡ÖÕ¶Õ¥Õ¬' Õ°Ö€Õ¡Õ´Õ¡Õ¶Õ¨Ö‰" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 ÕºÖ€Õ¸Ö„Õ½Õ«Õ¶ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ´ Õ¿Ö€Õ¾Õ¡Õ® Õ°Õ¡Õ½ÖÕ¥Õ« Õ¿Õ«ÕºÕ¨Ö‰" + +#: ../gio/gsocks5proxy.c:402 +#, fuzzy +msgid "Unknown SOCKSv5 proxy error." +msgstr "Ô±Õ¶Õ°Õ¡ÕµÕ¿ SOCKSv5 ÕºÖ€Õ¸Ö„Õ½Õ« Õ½Õ­Õ¡Õ¬Ö‰" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ´Õ·Õ¡Õ¯Õ¥Õ¬ GThemedIcon Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ %d Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "ÕÕºÕ¡Õ½Õ¾Õ¸Õ´ Õ§ 1 Õ°Õ½Õ¯Õ«Õ¹ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶, Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ %d" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "Ô¼Ö€Õ¡ÖÕ¸Ö‚ÖÕ«Õ¹ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ« Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« Õ¿Õ«Õº" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "ÕÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§ Õ´Õ¥Õ¯ Ö†Õ¡ÕµÕ¬Õ« Õ¤Õ¥Õ½Õ¯Ö€Õ«ÕºÕ¿Õ¸Ö€, Õ¢Õ¡ÕµÖ Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ %d\n" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "ÕÕ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Ö†Õ¡ÕµÕ¬Õ« Õ¤Õ¥Õ½Õ¯Ö€Õ«ÕºÕ¿Õ¸Ö€" + +#: ../gio/gunixconnection.c:371 +msgid "Error sending credentials: " +msgstr "ÕÕ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ¶ Õ¸Ö‚Õ²Õ¡Ö€Õ¯Õ¥Õ¬Õ¸Ö‚ սխալ․" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Õ½Õ¿Õ¸Ö‚Õ£Õ¥Õ¬Õ«Õ½ Õ¡Ö€Õ¤ÕµÕ¸Ö„ SO_PASSCRED-Õ¨ Õ´Õ«Õ¡ÖÕ¾Õ¡Õ® Õ§ սոկետին․ %s" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" +"Õ€Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¥Ö€Õ¯Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ Õ½Õ¿Õ¸Ö‚Õ£Õ¥Õ¬Õ«Õ½, Õ¡Ö€Õ¤ÕµÕ¸Ö„ SO_PASSCRED-Õ¨ Õ½Õ¸Õ¯Õ¥Õ¿Õ« " +"Õ°Õ¡Õ´Õ¡Ö€ Õ´Õ«Õ¡ÖÕ¾Õ¡Õ® Õ§Ö‰ ÕÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ %d Õ¢Õ¡ÕµÕ©, Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ %d" + +#: ../gio/gunixconnection.c:478 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® SO_PASSCRED - Õ¨ Õ´Õ«Õ¡ÖÕ¶Õ¥Õ¬Õ¸Ö‚ ժամանակ․ %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"ÕÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ Õ¯Õ¡Ö€Õ¤Õ¡Õ¬ Õ´Õ¥Õ¯ Õ¢Õ¡ÕµÕ© Õ½Õ¿Õ¡ÖÕ¾Õ¡Õ® Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ«Ö, Õ¢Õ¡ÕµÖ Õ¯Õ¡Ö€Õ¤Õ¡ÖÕ¾Õ¥Õ¬ Õ§ Õ¦Ö€Õ¸ Õ¢Õ¡ÕµÕ©" + +#: ../gio/gunixconnection.c:545 +#, fuzzy, c-format +msgid "Not expecting control message, but got %d" +msgstr "ÕÕºÕ¡Õ½Õ¾Õ¸Õ´ Õ§ 1 Õ°Õ½Õ¯Õ«Õ¹ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶, Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ %d" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "ÕÕ­Õ¡Õ¬ SO_PASSCRED անջատելիս․ %s" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® unix - Õ«Ö Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ¸Ö‚ ժամանակ․ %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® unix - Õ¨ ÖƒÕ¡Õ¯Õ¥Õ¬Õ¸Ö‚ ժամանակ․ %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "Õ–Õ¡ÕµÕ¬Õ¡Õ¬Õ«Õ¶ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ« Õ¡Ö€Õ´Õ¡Õ¿Õ¨" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¡Õ® unix - Õ¸Ö‚Õ´ գրելիս․ %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "Ô±ÕµÕ½ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ¨ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ´ unix domain Õ½Õ¸Õ¯Õ¥Õ¿Õ¶Õ¥Ö€Õ« Õ¡Õ¢Õ½Õ¿Ö€Õ¡Õ¯Õ¿ Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€Õ¨" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "ÕÕ¡Ö€Ö„Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¸Ö‚Õ´Õ¨" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "ÕÕ¡Ö€Ö„Õ¨ Õ¹Õ« Õ«Ö€Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¸Ö‚Õ´ Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¸Ö‚Õ´Õ¨ Õ¯Õ¡Õ´ Õ¤Õ¸Ö‚Ö€Õ½ Õ°Õ¡Õ¶Õ¸Ö‚Õ´Õ¨ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "Õ‰Õ« Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Õ¬ Õ£Õ¿Õ¶Õ¥Õ¬ Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ®Ö€Õ¡Õ£Õ«Ö€Õ¨" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "Ô±Õ·Õ­Õ¡Õ¿Õ¡Õ®Ö€Õ¡Õ£Ö€Õ« Õ©Õ¸Õ²Õ¡Ö€Õ¯Õ´Õ¡Õ¶ սխալ․ %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "ÕÕ«Õ´Õ¾Õ¸Õ¬Õ«Õ¯ Õ°Õ²Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¶ Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¡Õ® Õ¹Õ¥Õ¶" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "Õ€Õ¡Õ´Õ¡Õ¤Ö€Õ´Õ¡Õ¶ ÖƒÕ¸ÖƒÕ¸Õ­Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨ Õ¹Õ¥Õ¶ Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Ö‚Õ´ win32-Õ¸Ö‚Õ´" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "Õ€Õ¡Õ´Õ¡Õ¤Ö€Õ´Õ¡Õ¶ Õ½Õ¿Õ¥Õ²Õ®Õ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Ö‚Õ´ win32-Õ¸Ö‚Õ´ " + +#: ../gio/gwin32inputstream.c:318 +#, c-format +msgid "Error reading from handle: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Ö†Õ¡ÕµÕ¬Õ«Ö Õ¯Õ¡Ö€Õ¤Õ¡Õ¬Õ«Õ½â€¤ %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, c-format +msgid "Error closing handle: %s" +msgstr "ÕÕ­Õ¡Õ¬Õ Ö†Õ¡ÕµÕ¬Õ¨ փակելիս․ %s" + +#: ../gio/gwin32outputstream.c:318 +#, c-format +msgid "Error writing to handle: %s" +msgstr "ÕÕ¥Õ²Õ« Õ§ Õ¸Ö‚Õ¶Õ¥ÖÕ¥Õ¬ Õ½Õ­Õ¡Õ¬ Ö†Õ¡ÕµÕ¬Õ¸Ö‚Õ´ Õ£Ö€Õ¥Õ¬Õ¸Ö‚ ժամանակ․ %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "Õ€Õ«Õ·Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¢Õ¡Õ¾Õ¡Õ¯Õ¡Õ¶ Õ¹Õ§" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "Õ†Õ¥Ö€Ö„Õ«Õ¶ սխալ․ %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "Ô±Õ¾Õ¥Õ¬Õ« Õ·Õ¡Õ¿ Õ´Õ¸Ö‚Õ¿Ö„Õ¡ÕµÕ«Õ¶ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ« Õ¯Õ¡Ö€Õ«Ö„ Õ¯Õ¡" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "Ô±Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ½Õ¥Õ²Õ´Õ¾Õ¡Õ® Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "ÕŽÕ¥Ö€Õ¡Õ¤Õ¡Ö€Õ±Õ¾Õ¸Õ² Õ¡Ö€ÕªÕ¥Ö„Õ« Õ¿Õ«ÕºÕ¨ Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§, Õ½Õ¿Õ¡ÖÕ¾Õ¥Õ¬ Õ§ '%s', Õ½ÕºÕ¡Õ½Õ¾Õ¸Ö‚Õ´ Õ§Ö€ '%s'" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "Õ“Õ¸Ö€Õ±Õ¸Ö‚Õ´ Õ§ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¥Õ¬ %s Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ %s Õ¿Õ«ÕºÕ¸Ö‚Õ´, Õ¢Õ¡ÕµÖ Õ°Õ¡Õ·Õ¾Õ« Õ¡Õ¼Õ¶Õ¥Õ¬Õ¸Õ¾ Õ½Õ¿Õ¡ÖÕ¾Õ¡Õ® " +#~ "Õ«Õ¶Õ¿Õ¥Ö€Ö†Õ¥ÕµÕ½Õ¨ Õ¿Õ«ÕºÕ¨ %s Õ§" + +#~ msgid "No such schema '%s' specified in override file '%s'" +#~ msgstr "Ô³Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« '%s' Õ½Õ­Õ¥Õ´Õ¡ Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¾Õ¡Õ® Õ¾Õ¥Ö€Õ¡Õ£Ö€Õ¾Õ¸Õ² '%s' Ö†Õ¡ÕµÕ¬Õ¸Ö‚Õ´" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "Հրամաններ․\n" +#~ " Ö…Õ£Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¸Ö‚Õ´ Õ§ Õ¡ÕµÕ½ Õ¿Õ¥Õ²Õ¥Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨\n" +#~ " Õ½Õ¿Õ¡Õ¶Õ¡Õ¬ ÕÕ¿Õ¡Õ¶Õ¸Ö‚Õ´ Õ§ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Ö€ÕªÕ¥Ö„Õ¨\n" +#~ " Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ¥Õ¬ ÕÕ¥Õ²Õ¡Õ¤Ö€Õ¸Ö‚Õ´ Õ§ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Ö€ÕªÕ¥Ö„Õ¨\n" +#~ " Õ¾Õ¥Ö€Õ¡Õ¤Õ¶Õ¥Õ¬ ÕŽÕ¥Ö€Õ¡Õ¤Õ¶Õ¸Ö‚Õ´ Õ§ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Ö€ÕªÕ¥Ö„Õ¨\n" +#~ " Õ°Õ¥Õ¿Ö‡Õ¥Õ¬ Õ€Õ¥Õ¿Ö‡Õ¸Ö‚Õ´ Õ§ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ÖƒÕ¸ÖƒÕ¸Õ­Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨\n" +#~ " Õ£Ö€Õ¾Õ¸Õ² ÕÕ¿Õ¸Ö‚Õ£Õ¸Ö‚Õ´ Õ§ Õ¡Ö€Õ¤ÕµÕ¸Ö„ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ Õ£Ö€Õ¾Õ¸Õ² Õ§\n" +#~ "\n" +#~ "Õ•Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ '%s Õ€ÕÔ±Õ„Ô±Õ† --Ö…Õ£Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶' ÕµÕ¸Ö‚Ö€Õ¡Ö„Õ¡Õ¶Õ¹ÕµÕ¸Ö‚Ö€ Õ°Ö€Õ¡Õ´Õ¡Õ¶Õ« Õ´Õ¡Õ½Õ«Õ¶ " +#~ "Ö…Õ£Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ½Õ¿Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "Õ†Õ·Õ¥Õ¬ schema-Õ« Õ¸Ö‚Õ²Õ«Õ¶" + +#~ msgid "PATH" +#~ msgstr "ÕˆÕ’Õ‚Ô»" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "Արգումենտներ․\n" +#~ " ÕÔ½ÔµÕ„Ô± ÕÕ­Õ¥Õ´Õ¡ÕµÕ« id\n" +#~ " Ô²Ô±Õ†Ô±Ô¼Ô» Ô²Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Õ¶Õ¸Ö‚Õ¶\n" +#~ " Ô±Ö€ÕªÕ¥Ö„ Ô²Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¡Ö€ÕªÕ¥Ö„, Õ¸Ö€Õ¨ ÕºÕ¥Õ¿Ö„ Õ§ Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ¾Õ«, Õ¸Ö€ÕºÕ¥Õ½ Õ½Õ¥Ö€Õ«Õ¡Õ¬Õ«Õ¦Õ¡ÖÕ¾Õ¡Õ® " +#~ "GVariant\n" + +#~ msgid "Key %s is not writable\n" +#~ msgstr "%s Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ Õ£Ö€Õ¾Õ¸Õ² Õ¹Õ§\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "Õ€Õ¥Õ¿Ö‡Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ÖƒÕ¸ÖƒÕ¸Õ­Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ«Õ¶ Ö‡ Õ¿ÕºÕ¥Õ¬ ÖƒÕ¸ÖƒÕ¸Õ­Õ¾Õ¡Õ® Õ¡Ö€ÕªÕ¥Ö„Õ¶Õ¥Ö€Õ¨Ö‰\n" +#~ "Õ€Õ¥Õ¿Ö‡Õ¥Õ¬Õ¨ Õ¯Õ·Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¾Õ« Õ´Õ«Õ¶Õ¹Ö‡ ÕºÖ€Õ¸ÖÕ¥Õ½Õ« Õ¡Õ¾Õ¡Ö€Õ¿Õ¨Ö‰" diff --git a/po/id.po b/po/id.po new file mode 100644 index 0000000..e50baae --- /dev/null +++ b/po/id.po @@ -0,0 +1,6297 @@ +# Indonesian translation of glib. +# Copyright (C) 2005 THE glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the glib package. +# +# Mohammad DAMT , 2005. +# Dirgita , 2010, 2012. +# Andika Triwidada , 2010-2013, 2015, 2018. +# Kukuh Syafaat , 2017-2022. +msgid "" +msgstr "" +"Project-Id-Version: glib main\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-09 15:36+0000\n" +"PO-Revision-Date: 2022-04-11 16:07+0700\n" +"Last-Translator: Kukuh Syafaat \n" +"Language-Team: Indonesian \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 3.0.1\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Menata aplikasi baku belum didukung" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Menata aplikasi sebagai yang terakhir digunakan untuk tipe belum didukung" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opsi GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Tunjukkan opsi GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Masuk mode layanan GApplication (pakai dari berkas layanan D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Timpa ID aplikasi" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Ganti instance yang berjalan" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Cetak bantuan" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[PERINTAH]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Cetak versi" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Cetak informasi versi dan keluar" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Tampilkan daftar aplikasi" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Buat daftar aplikasi yang dapat diaktifkan D-Bus yang terpasang (menurut " +"berkas .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Luncurkan aplikasi" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Meluncurkan aplikasi (dengan berkas opsional yang akan dibuka)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [BERKAS…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktifkan suatu aksi" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Panggil suatu aksi pada aplikasi" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID AKSI [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Buat daftar aksi yang tersedia" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Buat daftar aksi statik bagi suatu aplikasi (dari berkas .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "PERINTAH" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Perintah yang ingin dicetak bantuan terrincinya" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Identifier aplikasi dalam format D-Bus (mis: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "BERKAS" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Nama berkas relatif atau absolut, atau URI opsional yang akan dibuka" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "AKSI" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Nama aksi yang akan dipanggil" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Parameter opsional untuk pemanggilan aksi, dalam format GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Perintah tidak dikenal %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Cara pakai:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumen:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARG...]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Perintah:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Gunakan \"%s help PERINTAH\" untuk memperoleh bantuan terrinci.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Perintah %s memerlukan id aplikasi langsung setelahnya\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "id aplikasi tak valid: \"%s\"\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"\"%s\" tak menerima argumen\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "tak bisa menyambung ke D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "galat saat mengirim pesan %s ke aplikasi: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "nama aksi mesti diberikan setelah id aplikasi\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nama aksi tak valid: \"%s\"\n" +"nama mesti hanya terdiri dari alfanumerik, \"-\", dan \".\"\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "galat saat mengurai parameter aksi: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "aksi menerima maksimum satu parameter\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "perintah list-actions hanya menerima id aplikasi" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "tak bisa temukan berkas desktop bagi aplikasi %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"perintah tak dikenal: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Nilai cacah yang dilewatkan ke %s terlalu besar" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Seek tak didukung pada stream basis" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Tak bisa memenggal GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Stream telah ditutup" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Pemenggalan tak didukung pada stream basis" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operasi dibatalkan" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Objek tak valid, tak diinisialisasi" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Rangkaian bita tak lengkap dalam input" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Tak cukup ruang di tujuan" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Rangkaian bita dalam input konversi tidak benar" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Galat ketika konversi: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Inisialisasi yang dapat dibatalkan tak didukung" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Konversi dari gugus karakter \"%s\" ke \"%s\" tak didukung" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Tak bisa membuka pengubah dari \"%s\" ke \"%s\"" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "tipe %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Tipe tak dikenal" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "tipe berkas %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials berisi data yang tidak valid" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials tak diimplementasikan di OS ini" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Tidak ada dukungan GCredentials bagi platform Anda" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials tak memuat suatu ID proses di OS ini" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Pemalsuan kredensial tak diimplementasikan di OS ini" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Akhir stream terlalu dini, tak diharapkan" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Kunci \"%s\" tak didukung pada entri alamat \"%s\"" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Kombinasi pasangan kunci/nilai tanpa arti di entri alamat \"%s\"" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Alamat \"%s\" tak valid (perlu hanya salah satu dari path, dir, tmpdir, atau " +"kunci abstrak)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Galat dalam alamat \"%s\" — atribut \"%s\" salah bentuk" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transport \"%s\" tak dikenal atau tak didukung bagi alamat \"%s\"" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Elemen alamat \"%s\" tak memuat titik dua (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Nama transport dalam elemen alamat “%s†tidak boleh kosong" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Pasangan kunci/nilai %d, \"%s\", dalam elemen alamat \"%s\" tak memuat tanda " +"sama dengan" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Pasangan kunci/nilai %d, \"%s\", dalam elemen alamat \"%s\" tak boleh " +"memiliki kunci kosong" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Galat saat membongkar kunci atau nilai dalam pasangan Key/Value %d, \"%s\", " +"dalam elemen alamat \"%s\"" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Galat dalam alamat \"%s\" — transport unix memerlukan hanya satu dari kunci " +"\"path\" atau \"abstract\" untuk ditata" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Galat dalam alamat \"%s\" — atribut host kurang atau salah bentuk" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Galat dalam alamat \"%s\" — atribut portt kurang atau salah bentuk" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "Galat di alamat \"%s\" — atribut berkas nonce kurang atau salah bentuk" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Galat saat meluncurkan otomatis: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Galat saat membuka berkas nonce \"%s\": %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Galat saat membaca berkas nonce \"%s\": %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Galat saat membaca berkas nonce \"%s\", berharap 16 bita, mendapat %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Galat saat menulis isi dari berkas nonce \"%s\" ke stream:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Tidak ada alamat yang diberikan" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Tak bisa spawn suatu bus pesan ketika AT_SECURE ditata" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Tak bisa spawn suatu bus pesan tanpa id-mesin: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Tak bisa meluncurkan mandiri D-Bus tanpa $DISPLAY X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Galat saat spawn baris perintah \"%s\": " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "Tak bisa menentukan alamat bus sesi (tidak diimplementasi bagi OS ini)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Tak bisa menentukan alamat bus dari variabel lingkungan " +"DBUS_STARTER_BUS_TYPE — nilai tak dikenal \"%s\"" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Tak bisa menentukan alamat bus karena variabel lingkungan " +"DBUS_STARTER_BUS_TYPE tak diisi" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipe bus %d tak dikenal" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Ketiadaan isi yang tak diharapkan ketika membaca suatu baris" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Ketiadaan isi yang tak diharapkan ketika membaca suatu baris (secara aman)" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Menghabiskan semua mekanisme autentikasi yang tersedia (dicoba: %s) " +"(tersedia: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "ID Pengguna harus sama untuk rakan (peer) dan peladen" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Dibatalkan melalui GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Galat ketika mengambil informasi untuk direktori \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Izin pada direktori \"%s\" salah bentuk. Diharapkan mode 0700, diperoleh 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Galat saat membuat direktori \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operasi tak didukung" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Galat saat membuka ring kunci \"%s\" untuk dibaca: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Baris %d dari ring kunci pada \"%s\" dengan isi \"%s\" salah bentuk" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Token pertama dari baris %d dari ring kunci pada \"%s\" dengan isi \"%s\" " +"salah bentuk" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Token kedua dari baris %d dari ring kunci pada \"%s\" dengan isi \"%s\" " +"salah bentuk" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Tak menemukan cookie dengan id %d dalam gantungan kunci pada \"%s\"" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Galat saat membuat berkas kunci \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Galat saat menghapus berkas kunci yang basi \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Galat saat menutup berkas kunci (tak terkait) \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Galat saat membuka kait berkas kunci \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Galat saat membuka gantungan kunci \"%s\" untuk ditulisi: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Selain itu, melepas kunci bagi \"%s\" juga gagal: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Sambungan tertutup" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Kehabisan waktu" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Ditemui tanda yang tak didukung ketika membangun sambungan di sisi klien" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Tidak ada antarmuka \"org.freedesktop.DBus.Properties\" pada objek pada path " +"%s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Tak ada properti \"%s\"" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Properti \"%s\" tidak dapat dibaca" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Properti \"%s\" tidak dapat ditulisi" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Galat menata properti \"%s\": Tipe yang diharapkan \"%s\" tapi diperoleh \"%s" +"\"" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Tak ada antarmuka \"%s\"" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Tak ada antarmuka \"%s\" pada objek di lokasi %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Tidak ada metode seperti \"%s\"" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Tipe pesan \"%s\" tak cocok dengan tipe yang diharapkan \"%s\"" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Suatu objek telah diekspor bagi antar muka %s pada %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Tak bisa mengambil properti %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Tak bisa menata properti %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metode \"%s\" mengembalikan tipe \"%s\", tapi yang diharapkan \"%s\"" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "" +"Metode \"%s\" pada antar muka \"%s\" dengan tanda tangan \"%s\"' tak ada" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Subtree telah diekspor bagi %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Objek tidak ada di path \"%s\"" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "jenisnya INVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Pesan METHOD_CALL: ruas header PATH atau MEMBER hilang" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Pesan METHOD_RETURN: ruas header REPLY_SERIAL hilang" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Pesan ERROR: ruas header REPLY_SERIAL atau ERRORN_NAME hilang" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Pesan SIGNAL: ruas header PATH, INTERFACE, atau MEMBER hilang" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Pesan SIGNAL: ruas header PATH memakai nilai khusus /org/freedesktop/DBus/" +"Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Pesan SIGNAL: ruas header INTERFACE memakai nilai khusus org.freedesktop." +"DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Ingin membaca %lu bita tapi hanya memperoleh %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Mengharapkan bita NUL setelah string \"%s\" tapi menemui bita %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Berharap string UTF-8 yang valid tapi menjumpai bita tak valid pada lokasi " +"%d (panjang string adalah %d). String UTF-8 yang valid sampai titik itu " +"adalah \"%s\"" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Nilai bersarang terlalu dalam" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Nilai terurai \"%s\" bukan lokasi objek D-Bus yang valid" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Nilai terurai \"%s\" bukan tanda tangan D-Bus yang valid" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Menjumpai larik dengan panjang %u bita. Panjang maksimal adalah 2<<26 bita " +"(64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Menemui larik bertipe \"a%c\", mengharapkan punya panjang kelipatan %u bita, " +"tapi menemui panjang %u bita" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Struktur kosong (tuple) tidak diperbolehkan di D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Nilai terurai \"%s\" bagi varian bukan tanda tangan D-Bus yang valid" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Galat saat deserialisasi GVariant dengan type string \"%s\" dari format " +"kabel D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Nilai ke-endian-an tak valid. Berharap 0x6c (\"l\") atau (0x42) \"B\" tapi " +"menemui 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Versi protokol mayor tak valid. Berharap 1 tapi menemui %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Tajuk tanda tangan ditemukan tetapi bukan tipe tanda tangan" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Header tanda tangan dengan tanda tangan \"%s\" ditemukan tapi body pesan " +"kosong" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Nilai terurai \"%s\" bukan tanda tangan D-Bus yang valid (bagi body)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Tidak terdapat tajuk tanda tangan pada pesan, tetapi panjang badan pesan " +"adalah %u bita" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Tak bisa men-deserialisasi pesan: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Kesalahan serialisasi GVariant dengan type string \"%s\" ke format kabel D-" +"Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Jumlah deskriptor berkas dalam pesan (%d) berbeda dari field header (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Tak bisa men-serialisasi pesan: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Body pesan punya tanda tangan \"%s\" tapi tak ada header tanda tangan" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Tubuh pesan memiliki tanda tangan tipe \"%s\" tapi tanda tangan di ruas " +"header adalah \"(%s)\"" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Tubuh pesan kosong tapi tanda tangan pada ruas header adalah \"(%s)\"" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Galat balikan dengan tubuh bertipe \"%s\"" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Galat balikan dengan body kosong" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Ketikkan karakter apapun untuk menutup jendela ini)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "dbus sesi tak sedang berjalan, dan peluncuran-otomatis gagal" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Tak bisa mendapat profil perangkat keras: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Tak bisa memuat %s or %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Galat sewaktu memanggil StartServiceByName untuk %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Balasan tak diharapkan %d dari metode StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Tak bisa menjalankan metode; proksi adalah nama terkenal %s tanpa pemilik " +"dan proksi dibangun dengan tanda G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Ruang nama abstrak tak didukung" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Tak bisa menyatakan berkas nonce ketika membuat suatu peladen" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Galat saat menulis berkas nonce pada \"%s\": %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "String \"%s\" bukan suatu GUID D-Bus yang valid" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Tak bisa mendengarkan pada transport yang tak didukung \"%s\"" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Perintah:\n" +" help Tampilkan informasi ini\n" +" introspect Introspeksi suatu objek jauh\n" +" monitor Pantau suatu objek jauh\n" +" call Jalankan suatu metode pada suatu objek jauh\n" +" emit Pancarkan sinyal\n" +" wait Tunggu sebuah nama bus muncul\n" +"\n" +"Gunakan \"%s PERINTAH --help\" untuk memperoleh bantuan pada setiap " +"perintah.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Galat: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Galat saat mengurai XML introspeksi: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Galat: %s bukan nama yang valid\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Galat: '%s' bukan suatu lokasi objek yang valid\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Menyambung ke bus sistem" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Menyambung ke bus sesi" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Menyambung ke alamat D-Bus yang diberikan" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opsi Titik Ujung Sambungan:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opsi yang menyatakan titik ujung sambungan" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Titik ujung sambungan tak dinyatakan" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Telah dinyatakan titik ujung sambungan berganda" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Peringatan: Menurut data introspeksi, antar muka \"%s\" tak ada\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Peringatan: Menurut data introspeksi, metode \"%s\" tak ada pada antar muka " +"\"%s\"\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Tujuan opsional bagi sinyal (nama unik)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Path objek untuk dipancari sinyal" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Nama antar muka dan sinyal" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Pancarkan sinyal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Galat saat menyambung: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Galat: '%s' bukan nama bus unik yang valid\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Galat: Lokasi objek tak dinyatakan\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Galat: Nama sinyal tak dinyatakan\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Galat: Nama sinyal \"%s\" tak valid\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Galat: '%s' bukan nama antar muka yang valid\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Galat: '%s' bukan nama anggota yang valid\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Galat saat mengurai parameter %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Galat saat menggelontor sambungan: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nama tujuan tempat menjalankan metode" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Lokasi objek tempat menjalankan metode" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Nama metode dan antar muka" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Tenggat waktu dalam detik" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Perbolehkan otorisasi interaktif" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Jalankan suatu metode pada suatu objek jauh." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Galat: Tujuan tak dinyatakan\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Galat: %s bukan nama bus yang valid\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Galat: Nama metode tak dinyatakan\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Galat: Nama metode \"%s\" tak valid\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Galat ketika mengurai parameter ke-%d bertipe \"%s\": %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Galat saat menambahkan %d handle: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nama tujuan untuk introspeksi" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Lokasi objek untuk introspeksi" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Cetak XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Introspeksi anak" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Hanya cetak properti" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspeksi suatu objek jauh." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nama tujuan untuk dipantau" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Lokasi objek untuk dipantau" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Memantau suatu objek jauh." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Galat: tidak dapat memonitor koneksi non bus pesan\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" +"Layanan yang akan diaktifkan sebelum menunggu yang lain (nama yang dikenal " +"baik)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Tenggat waktu menunggu sebelum keluar dengan suatu kesalahan (detik); 0 " +"untuk tanpa tenggat (baku)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPSI…] NAMA-BUS" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Tunggu suatu nama bus muncul." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Galat: Suatu layanan yang akan diaktifkan mesti dinyatakan\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Galat: Suatu layanan yang mesti ditunggu harus dinyatakan\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Galat: Terlalu banyak argumen.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Galat: %s bukan nama bus yang dikenal baik dan valid\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Tidak berwenang untuk mengubah pengaturan awakutu" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Tanpa nama" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Berkas desktop tak menyatakan ruas Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Tak bisa temukan terminal yang diperlukan bagi aplikasi" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Tak bisa membuat folder %s untuk konfigurasi aplikasi bagi pengguna: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Tak bisa membuat folder %s untuk konfigurasi MIME bagi pengguna: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Informasi aplikasi tak punya identifier" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Tak bisa membuat berkas desktop pengguna %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Definisi gubahan bagi %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "kandar tidak mengimplementasikan eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "kandar tidak mengimplementasikan eject atau eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "kandar tidak mengimplementasi poll bagi media" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "kandar tidak mengimplementasi start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "kandar tidak mengimplementasi stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "Backend TLS tidak menerapkan pengambilan pengikatan TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Dukungan TLS tak tersedia" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Dukungan DTLS tak tersedia" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Tak bisa menangani pengkodean GEmblem versi %d" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Cacah token (%d) salah bentuk di pengkodean GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Tak bisa menangani pengkodean versi %d dari GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Cacah token (%d) salah bentuk di pengkodean GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Berharap suatu GEmblem bagi GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Kait yang memuat tak ada" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Tak bisa menyalin direktori atas direktori" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Tak bisa menyalin direktori atas direktori" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Berkas tujuan telah ada" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Tak bisa menyalin direktori secara rekursif" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Splice tidak didukung" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Galat saat men-splice berkas: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Menyalin (reflink/clone) antar kait tak didukung" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Menyalin (reflink/clone) tak didukung atau tak valid" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Menyalin (reflink/clone) tak didukung atau tak bekerja" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Tak bisa menyalin berkas spesial" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Diberikan nilai link simbolik yang tak valid" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Taut simbolik tidak didukung" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Tong sampah tak didukung" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Nama berkas tak boleh mengandung \"%c\"" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "volume tak mengimplementasi pengaitan" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Tak ada aplikasi terdaftar yang menangani berkas ini" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator ditutup" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Enumerator berkas memiliki operasi tertunda" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Enumerator berkas telah ditutup" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Tak bisa menangani pengkodean versi %d dari GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Data masukan salah bentuk bagi GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Stream tak mendukung query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Seek tak didukung pada stream" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Pemenggalan tak diijinkan pada stream masukan" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Pemenggalan tak didukung pada stream" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Nama host salah" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Jawaban proksi HTTP buruk" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Sambungan proksi HTTP tak diizinkan" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Autentikasi proksi HTTP gagal" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Autentikasi proksi HTTP diperlukan" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Sambungan proksi HTTP gagal: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Respons proksi HTTP terlalu besar" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Peladen proksi HTTP menutup koneksi secara tak terduga." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Cacah token yang salah (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Tak ada tipe bagi nama kelas %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Tipe %s tak mengimplementasi antar muka GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Tipe %s tak dikelaskan" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Nomor versi salah bentuk: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Tipe %s tak mengimplementasi from_tokens() pada antar muka GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Tak bisa menangani versi pengkodean ikon yang diberikan" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Tak ada alamat yang dinyatakan" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Panjang %u terlalu panjang bagi alamat" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Alamat memiliki bit yang ditata diluar panjang prefiks" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Tak bisa mengurai \"%s\" sebagai mask alamat IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Tak cukup ruang bagi alamat soket" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Alamat soket tak didukung" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Stream masukan tak mengimplementasi pembacaan" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Stream memiliki operasi tertunda" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Salin dengan berkas" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Pertahankan dengan berkas ketika dipindah" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "\"version\" tak menerima argumen" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Penggunaan:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Cetak informasi versi dan keluar." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Perintah:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Sambung berkas berurutan ke keluaran standar" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Salin satu berkas atau lebih" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Tunjukkan informasi tentang lokasi" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Luncurkan aplikasi dari berkas destop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Tampilkan daftar isi lokasi" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Ambil atau atur penangan bagi suatu mimetype" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Buat direktori" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Pantau perubahan berkas dan direktori" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Kait atau lepas kait lokasi" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Pindah satu berkas atau lebih" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Buka berkas dengan aplikasi baku" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Ubah nama suatu berkas" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Hapus satu berkas atau lebih" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Baca dari masukan standar dan simpan" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Atur atribut berkas" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Pindahkan berkas atau direktori ke tempat sampah" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Lihat daftar lokasi dalam suatu pohon" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Gunakan %s untuk memperoleh bantuan terrinci.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Galat saat menulis ke stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOKASI" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Sambung berkas berurutan dan cetak ke keluaran standar." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat bekerja seperti utilitas cat tradisional, tapi memakai lokasi GIO\n" +"sebagai ganti berkas lokal: sebagai contoh Anda dapat memakai\n" +"seperti smb://peladen/sumberdaya/berkas.txt sebagai lokasi." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Tidak ada lokasi yang diberikan" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Tidak ada direktori tujuan" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Tampilkan kemajuan" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Tanya sebelum menimpa" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Pertahankan semua atribut" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Buat cadangan berkas tujuan yang telah ada" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Jangan pernah ikut taut simbolik" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Gunakan izin bawaan untuk tujuan" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Ditransfer %s dari %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SUMBER" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "TUJUAN" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Salin satu berkas atau lebih dari SUMBER ke TUJUAN." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy mirip dengan utilitas cp tradisional, tapi memakai lokasi GIO\n" +"sebagai ganti berkas lokal: sebagai contoh Anda dapat memakai\n" +"smb://peladen/sumberdaya/berkas.txt sebagai lokasi." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Tujuan %s bukan suatu direktori" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: timpa \"%s\"? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Buat daftar atribut yang dapat ditulisi" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Ambil info sistem berkas" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Atribut yang akan diambil" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUT" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Jangan ikuti taut simbolik" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atribut:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nama tampilan: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "sunting nama: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nama: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipe: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "ukuran: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "tersembunyi\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "path lokal: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "kait unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atribut yang dapat ditata:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Namespace atribut yang dapat ditulis:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Tunjukkan informasi tentang lokasi." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info mirip dengan utilitas ls tradisional, tapi memakai lokasi GIO\n" +"sebagai ganti berkas lokal: sebagai contoh Anda dapat memakai\n" +"smb://peladen/sumberdaya/berkas.txt sebagai lokasi. Atribut berkas dapat\n" +"ditentukan dengan nama GIO mereka, misalnya standard::icon, atau hanya " +"dengan\n" +"namespace, misalnya unix, atau dengan \"*\", yang cocok dengan semua atribut" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "BERKAS-DESTOP [ARG-BERKAS …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Luncurkan aplikasi dari berkas destop, lewati argumen nama berkas opsional " +"ke berkas tersebut." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Tidak ada berkas destop yang diberikan" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Perintah peluncuran saat ini tidak didukung pada platform ini" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Tak bisa memuat '%s': %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Tak bisa memuat informasi aplikasi untuk '%s'" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Tak bisa meluncurkan aplikasi '%s': %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Tampilkan berkas tersembunyi" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Gunakan format daftar panjang" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Cetak nama tampilan" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Cetak URI lengkap" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Tampilkan daftar isi lokasi." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list mirip dengan utilitas ls tradisional, tapi memakai lokasi GIO\n" +"sebagai ganti berkas lokal: sebagai contoh Anda dapat memakai\n" +"smb://peladen/sumberdaya/berkas.txt sebagai lokasi. Atribut berkas dapat\n" +"ditentukan dengan nama GIO mereka, misalnya standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "HANDLER" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Ambil atau atur penangan bagi suatu mimetype." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Jika tidak ada penangan yang diberikan, daftar aplikasi terdaftar dan\n" +"direkomendasikan untuk mimetype. Jika penangan diberikan, ini disetel\n" +"sebagai penangan bawaan untuk mimetype." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Harus menentukan mimetype tunggal, dan mungkin penangan" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Tidak ada aplikasi baku bagi \"%s\"\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplikasi baku bagi \"%s\": %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplikasi terdaftar:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Tak ada aplikasi terdaftar\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplikasi yang direkomendasikan:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Tidak ada aplikasi yang direkomendasikan\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Gagal memuat info bagi penangan \"%s\"" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Gagal menata \"%s\" sebagai penangan baku bagi \"%s\": %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Buat direktori induk" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Buat direktori." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir mirip dengan utilitas mkdir tradisional, tapi memakai lokasi GIO\n" +"sebagai ganti berkas lokal: sebagai contoh Anda dapat memakai\n" +"smb://peladen/sumberdaya/direktorisaya sebagai lokasi." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Pantau suatu direktori (baku: bergantung kepada tipe)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Memantau suatu direktori (baku: bergantung kepada tipe)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Pantau berkas secara langsung (pemberitahuan perubahan yang dilakukan " +"melalui hardlinks)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" +"Memantau sebuah berkas secara langsung, tapi tidak melaporkan perubahan" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Laporkan pergerakan dan mengganti nama menjadi kejadian sederhana yang " +"dihapus/dibuat" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Mengamati kejadian pengaitan" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Memantau perubahan berkas atau direktori." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Kait sebagai yang dapat dikait" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Kait volume dengan berkas perangkat, atau pengidentifikasi lainnya" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Lepaskan Kaitan" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Keluarkan Media" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Hentikan kandar dengan berkas perangkat" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "PERANGKAT" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Lepas kaitan semua kait dengan skema yang diberikan" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SKEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Mengabaikan operasi berkas yang tertunda saat melepas kait atau mengeluarkan" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Gunakan suatu pengguna anonim ketika mengautentikasi" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Daftar" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Pantau kejadian" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Tampilkan informasi ekstra" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "PIM numerik saat membuka volume VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Kaitkan volume tersembunyi TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Kaitkan volume sistem TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Akses anonim ditolak" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Tidak ada kandar bagi berkas perangkat" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Tidak ada volume untuk ID yang diberikan" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Kait atau lepas kait lokasi." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Jangan gunakan fallback salin dan hapus" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Memindahkan satu atau lebih berkas dari SUMBER ke TUJUAN." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move mirip dengan utilitas mv tradisional, tapi memakai lokasi GIO\n" +"sebagai ganti berkas lokal: sebagai contoh Anda dapat memakai\n" +"smb://peladen/sumberdaya/berkas.txt sebagai lokasi" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Target %s bukan suatu direktori" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Membuka berkas dengan aplikasi baku yang\n" +"terdaftar untuk menangani jenis berkas ini." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Abaikan berkas yang tidak ada, jangan pernah bertanya" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Menghapus berkas yang diberikan." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAMA" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Ubah nama berkas." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Kurang argumen" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Terlalu banyak argumen" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Ubah nama sukses. Uri baru: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Hanya buat bila belum ada" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Tambahkan ke akhir berkas" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Ketika membuat, batasi akses hanye ke pengguna kini" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Ketika menggantikan, gantikan seperti seolah tujuan tidak ada" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Cetak etag baru di akhir" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Etag berkas sedang ditimpa" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Galat saat membaca dari masukan standar" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag tak tersedia\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Baca dari masukan standar dan simpan ke TUJUAN." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Tidak ada tujuan yang diberikan" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Tipe atribut" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "NILAI" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Atur atribut berkas dari LOKASI." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Lokasi tak dinyatakan" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atribut tak dinyatakan" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Nilai tak dinyatakan" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Tipe atribut tidak valid \"%s\"" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Mengosongkan tempat sampah" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Daftar berkas di tempat sampah dengan lokasi aslinya" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Pulihkan berkas dari sampah ke lokasi aslinya (mungkin membuat ulang " +"direktori)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Tak bisa menemukan path asli" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Tak bisa membuat ulang lokasi asli: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Tak bisa memindahkan berkas ke lokasi semula: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Pindahkan/Pulihkan berkas atau direktori ke tempat sampah." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Catatan: untuk sakelar --restore, jika lokasi asli dari berkas sampah\n" +"sudah ada, ini tidak akan ditimpa kecuali --force disetel." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Lokasi yang diberikan tidak dimulai dengan trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Ikuti taut simbolik, kait, dan pintasan" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Tampilkan daftar isi direktori dalam format mirip pohon." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elemen <%s> tidak diijinkan di dalam <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elemen <%s> tidak diijinkan pada aras puncak" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Berkas %s muncul beberapa kali dalam sumber daya" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Gagal menemukan \"%s\" dalam direktori sumber manapun" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Gagal menemukan \"%s\" di direktori saat ini" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Opsi pemrosesan \"%s\" tidak dikenal" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "praproses %s diminta, tetapi %s tidak diatur, dan %s tidak dalam PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Galat saat membaca berkas %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Galat saat memampatkan berkas %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "teks tidak boleh muncul di dalam <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Tampilkan versi program dan keluar" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nama berkas keluaran" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Direktori untuk memuat berkas yang direferensikan dalam FILE darinya " +"(bawaan: direktori saat ini)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIREKTORI" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Buat keluaran dalam format yang dipilih bagi ekstensi nama berkas target" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Buat tajuk sumber" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Buat kode sumber yang dipakai untutk menaut berkas sumber daya ke dalam kode " +"Anda" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Buat daftar kebergantungan" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nama berkas kebergantungan yang akan dibuat" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Sertakan target palsu pada berkas dependensi yang dihasilkan" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Jangan buat dan daftarkan sumber daya secara otomatis" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Jangan ekspor fungsi; deklarasikan mereka G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Jangan menyematkan data sumber daya dalam berkas C; anggap itu terhubung " +"secara eksternal sebagai gantinya" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Nama identifier C yang dipakai bagi kode sumber yang dibuat" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Kompiler target C (bawaan: variabel lingkungan CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompail spesifikasi sumber daya ke dalam berkas sumber daya.\n" +"Berkas spesifikasi sumber daya memiliki ekstensi .gresource.xml,\n" +"dan berkas sumber daya memiliki ekstensi bernama .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Anda mesti memberikan hanya satu nama berkas\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "nick minimal harus 2 karakter" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Nilai numerik tidak valid" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " sudah ditentukan" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' sudah ditentukan" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "nilai tanda harus paling banyak diset 1 bit" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> harus berisi setidaknya satu " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> tidak terdapat dalam jangkauan yang ditentukan" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> bukan anggota yang valid dari tipe enumerasi yang ditentukan" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> berisi string tidak dalam jenis tanda yang ditentukan" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> berisi string yang tidak ada dalam " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " sudah ditentukan untuk kunci ini" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " tidak diizinkan untuk kunci tipe \"%s\"" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " minimum yang ditentukan lebih besar dari maksimum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "kategori l10n tidak didukung: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n diminta, tapi tidak ada domain gettext yang diberikan" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "konteks terjemahan diberikan untuk nilai tanpa l10n diaktifkan" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Gagal mengurai nilai jenis \"%s\": " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" tidak dapat ditentukan untuk kunci yang ditandai sebagai memiliki " +"tipe enumerasi" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " sudah ditentukan untuk kunci ini" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " tidak diizinkan untuk kunci tipe \"%s\"" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " sudah ditentukan" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " harus mengandung setidaknya satu " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " sudah ditentukan untuk kunci ini" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" hanya bisa ditentukan untuk kunci dengan tipe enumerasi atau tanda " +"atau setelah " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" diberikan saat \"%s\" sudah menjadi anggota tipe " +"enumerasi" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" diberikan ketika sudah diberikan" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " sudah ditentukan" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "target alias \"%s\" bukan bilangan bertanda" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "alias target \"%s\" tidak ada di " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " harus berisi setidaknya satu " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Nama yang kosong tidak diperbolehkan" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Nama \"%s\" tak valid: nama mesti diawali dengan huruf kecil" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nama \"%s\" tak valid: karakter \"%c\" tak valid; hanya huruf kecil, angka, " +"dan tanda hubung (\"-\") yang diijinkan" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Nama \"%s\" tak valid: dua tanda hubung berturutan (\"--\") tak diijinkan" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" +"Nama \"%s\" tak valid: karakter terakhir tak boleh tanda hubung (\"-\")." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nama \"%s\" tak valid: panjang maksimum 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " telah dinyatakan" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Tak bisa menambah kunci ke skema \"list-of\"" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " telah dinyatakan" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" membayangi di ; gunakan " +" untuk mengubah nilai" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Persis satu dari 'type', 'enum', atau 'flags' mesti dinyatakan sebagai " +"atribut dari " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> belum didefinisikan." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "String jenis GVariant \"%s\" tidak sah" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " diberikan tapi skema tak memperluas apapun" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Tak ada untuk ditimpa" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " telah dinyatakan" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " sudah ditentukan" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " memperluas skema \"%s\" yang belum ada" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " adalah daftar dari skema \"%s\"' yang belum ada" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Tak mungkin berupa suatu daftar skema dengan path" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Tak bisa memperluas suatu skema dengan path" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" adalah daftar, memperluas yang bukan daftar" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" memperluas tapi " +"\"%s\" tak memperluas \"%s\"" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"Suatu path, bila diberikan, harus dimulai dan diakhiri dengan garis miring" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Path dari suatu daftar mesti diakhiri dengan “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Peringatan: Skema \"%s\" memiliki path \"%s\". Path yang dimulai dengan \"/" +"apps/\", \"/desktop/\" atau \"/system/\" tidak digunakan lagi." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> sudah ditentukan" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Hanya satu elemen <%s> diizinkan di dalam <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Elemen <%s> tidak diijinkan pada aras puncak" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Elemen diperlukan di " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Teks tidak boleh muncul di dalam <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Peringatan: referensi terdefinisi ke " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Seluruh berkas telah diabaikan." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Mengabaikan berkas ini." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Tak ada kunci “%s†dalam skema “%s†sebagaimana dinyatakan di berkas penimpa " +"“%sâ€; mengabaikan penimpa untuk kunci ini." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Tak ada kunci “%s†dalam skema “%s†sebagaimana dinyatakan di berkas penimpa " +"“%s†dan --strict dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Tak bisa menyediakan penimpa per-destop untuk kunci \"%s\" yang dilokalkan " +"dalam skema \"%s\" (menimpa berkas \"%s\"); mengabaikan penimpa untuk kunci " +"ini." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Tak bisa menyediakan penimpa per-destop untuk kunci \"%s\" yang dilokalkan " +"dalam skema \"%s\" (menimpa berkas \"%s\") dan --strict dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Galat saat mengurai kunci “%s†dalam skema “%s†sebagaimana dinyatakan di " +"berkas penimpa “%sâ€: %s. Mengabaikan penimpa untuk kunci ini." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Galat saat mengurai kunci “%s†dalam skema “%s†sebagaimana dinyatakan di " +"berkas penimpa “%sâ€: %s. dan --strict dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Penimpa bagi kunci “%s†dalam skema “%s†di berkas penimpa “%s†di luar " +"jangkauan yang diberikan di dalam skema; mengabaikan penimpa untuk kunci ini." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Penimpa bagi kunci “%s†dalam skema “%s†di berkas penimpa “%s†di luar " +"jangkauan yang diberikan di dalam skema dan --strict dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Penimpa bagi kunci “%s†dalam skema “%s†di berkas penimpa “%s†tak ada di " +"dalam daftar pilihan yang valid; mengabaikan penimpa untuk kunci ini." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Penimpa bagi kunci “%s†dalam skema “%s†di berkas penimpa “%s†tak ada di " +"dalam daftar pilihan yang valid dan --strict dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Dimana menyimpan berkas gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Gugurkan pada sebarang galat dalam skema" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Jangan menulis berkas gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Jangan paksakan pembatasan nama kunci" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompail semua berkas skema GSettings into suatu singgahan skema.\n" +"Berkas skema diharuskan memiliki ekstensi .gschema.xml,\n" +"dan berkas singgahan dinamai gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Anda mesti memberikan hanya satu nama direktori" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Tidak ada berkas skema yang ditemukan: tidak melakukan apa pun." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Tidak ada berkas skema yang ditemukan: menghapus berkas keluaran yang telah " +"ada." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Nama berkas tak valid: %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Galat saat mengambil info sistem berkas bagi %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Kait wadah bagi berkas %s tak ditemukan" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Tak bisa mengubah nama direktori root" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Galat saat mengubah nama berkas %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Tak bisa mengubah nama berkas, nama telah dipakai" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nama berkas tak valid" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Galat saat membuka berkas %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Galat saat menghapus berkas %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Galat saat memindah berkas %s ke tempat sampah: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Tak bisa membuat direktori tempat sampah %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "" +"Tak bisa menemukan direktori puncak %s yang akan dibuang ke tempat sampah" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Penyampahan pada kandar internal sistem tidak didukung" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Tak bisa menemukan atau membuat direktori %s ke tempat %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Tak bisa membuat berkas info pembuangan ke tempat sampah bagi %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Tak bisa membuang berkas %s ke tempat sampah menyeberang batas sistem berkas" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Tak bisa membuang berkas %s ke tempat sampah: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Tak bisa membuang berkas ke tempat sampah %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Galat saat membuat direktori %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Sistem berkas tak mendukung taut simbolik" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Galat saat membuat taut simbolis %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Galat saat memindah berkas %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Tak bisa memindah direktori atas direktori" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Pembuatan berkas cadangan gagal" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Galat saat menghapus berkas tujuan: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Perpindahan antar kait tak didukung" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Tak bisa menentukan penggunaan diska dari %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Nilai atribut tak boleh NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tipe atribut tak valid (diharapkan string)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nama atribut tambahan yang tak valid" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Galat saat menata atribut yang diperluas \"%s\": %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (pengkodean tak valid)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Galat saat mengambil informasi bagi berkas \"%s\": %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Galat saat mengambil informasi bagi descriptor berkas: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tipe atribut tak valid (diharapkan uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tipe atribut tak valid (diharapkan uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Jenis atribut tidak sah (diharapkan bita berjenis string)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Tak bisa menata ijin pada taut simbolik" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Galat saat menata ijin: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Galat saat menata pemilik: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "symlink tak boleh NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Galat saat menata taut simbolis: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Galat saat menata symlink: berkas bukan suatu link simbolik" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Nanodetik ekstra %d untuk stempel waktu UNIX %lld negatif" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Nanodetik ekstra %d untuk stempel waktu UNIX %lld mencapai 1 detik" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "Stempel waktu UNIX %lld tidak muat ke dalam 64 bit" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"Stempel waktu UNIX %lld berada di luar rentang yang didukung oleh Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Nama berkas \"%s\" tidak dapat dikonversi ke UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Berkas “%s†tidak dapat dibuka: Galat Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Galat saat menata waktu modifikasi atau akses untuk berkas “%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Galat saat menata waktu modifikasi atau akses: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Konteks SELinux tak boleh NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux tak diaktifkan di sistem ini" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Galat saat menata konteks SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Penataan atribut %s tak didukung" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Galat saat membaca dari berkas: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Galat saat menutup berkas: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Galat saat men-seek di berkas: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Tak bisa temukan tipe pemantauan berkas lokal baku" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Galat saat menulis ke berkas: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Galat saat menghapus taut cadangan lama: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Galat saat membuat salinan cadangan: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Galat saat mengubah nama berkas sementara: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Galat saat memenggal berkas: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Galat saat membuka berkas \"%s\": %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Berkas tujuan adalah suatu direktori" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Berkas tujuan bukan berkas biasa" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Berkas telah diubah secara eksternal" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Galat saat menghapus berkas lama: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "GSeekType yang tak valid diberikan" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Permintaan seek yang tak valid" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Tak bisa memenggal GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Memori stream keluaran tak bisa diubah ukuran" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Gagal mengubah ukuran memori stream keluaran" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Banyaknya memori yang diperlukan untuk memroses penulisan lebih besar " +"daripada ruang tersedia" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Seek yang diminta sebelum awal stream" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Seek yang diminta setelah akhir stream" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "mount tak mengimplementasi \"unmount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount tak mengimplementasi \"eject\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "mount tak mengimplementasi \"unmount\" atau \"unmount_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "mount tak mengimplementasi \"eject\" atau \"eject_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "mount tak mengimplementasi \"remount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "mount tak mengimplementasi penebakan jenis isi" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "mount tak mengimplementasi penebakan sinkron jenis isi" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Nama host \"%s\" mengandung \"[\" tapi tanpa \"]\"" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Jaringan tak dapat dijangkau" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Host tak dapat dihubungi" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Tak bisa membuat pemantau jaringan: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Tak bisa membuat pemantau jaringan: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Tak bisa mendapat status jaringan: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager tidak berjalan" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Versi NetworkManager terlalu tua" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Stream keluaran tidak mengimplementasikan penulisan" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Jumlah vektor yang dilewatkan ke %s terlalu besar" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Stream sumber telah ditutup" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Galat saat mengurai \"%s\": %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s tidak diterapkan" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Domain tidak valid" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Sumber daya pada \"%s\" tidak ada" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Sumber daya di \"%s\" gagal didekompresi" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Sumber daya pada \"%s\" bukan suatu direktori" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Stream masukan tidak mengimplementasikan seek" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Seksi daftar memuat sumber daya dalam BERKAS elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Daftar sumber daya\n" +"Bila SEKSI diberikan, hanya mendaftar sumber daya dalam seksi ini\n" +"Bila PATH diberikan, hanya mendaftar sumber daya yang cocok" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "BERKAS [PATH]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEKSI" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Daftar sumber daya dengan rincian\n" +"Bila SEKSI diberikan, hanya mendaftar sumber daya dalam seksi ini\n" +"Bila PATH diberikan, hanya mendaftar sumber daya yang cocok\n" +"Rincian termasuk seksi, ukuran, dan kompresi" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Ekstrak berkas sumber daya ke stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "BERKAS PATH" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Cara pakai:\n" +" gresource [--section SEKSI] PERINTAH [ARG…]\n" +"\n" +"Perintah:\n" +" help Tampilkan informasi ini\n" +" sections Lihat daftar seksi sumber daya\n" +" list Lihat daftar sumber daya\n" +" details Lihat daftar sumber daya dengan rincian\n" +" extract Ekstrak sumber daya\n" +"\n" +"Gunakan 'gresource help PERINTAH' untuk memperoleh bantuan terrinci.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Cara pakai:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEKSI Nama seksi elf (opsional)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " PERINTAH Perintah (opsional) untuk dijelaskan\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " BERKAS Berkas elf (biner atau pustaka bersama)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" BERKAS Berkas elf (biner atau pustaka bersama)\n" +" atau berkas sumber daya terkompail\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[PATH]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH Path sumber daya (opsional, mungkin parsial)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "PATH" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " PATH Path sumber daya\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Tidak ada skema \"%s\"\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" +"Skema \"%s\" bukan yang dapat dipindahkan (path tak boleh dinyatakan)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Skema \"%s\" bukan yang dapat dipindahkan (path mesti dinyatakan)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Path yang diberikan kosong.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Path harus dimulai dengan garis miring (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Path harus diakhiri dengan garis miring (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Path tak boleh memuat dua slash berturutan (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Nilai yang diberikan diluar rentang yang valid\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Kunci tidak dapat ditulisi\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Daftar skema (yang tak bisa dipindah) yang terpasang" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Daftar skema yang dapat dipindah yang terpasang" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Daftar kunci di SKEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SKEMA[:PATH]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Daftar anak dari SKEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Daftar kunci dan nilai, secara rekursif\n" +"Bila tak ada SKEMA diberikan, daftar semua kunci\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SKEMA[:PATH]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Ambil nilai dari KUNCI" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SKEMA[:PATH] KUNCI" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Kueri rentang nilai yang valid bagi KUNCI" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Kueri deskripsi bagi KUNCI" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Menata nilai KUNCI ke NILAI" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SKEMA[:PATH] KUNCI NILAI" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Menata KUNCI ke nilai bawaannya" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Tata ulang semua kunci dalam SKEMA ke nilai baku" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Periksa apakah KUNCI dapat ditulisi" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Pantau perubahan atas KUNCI.\n" +"Bila tak ada KUNCI yang dinyatakan, memantau semua kunci dalam SKEMA.\n" +"Gunakan ^C untuk berhenti memantau.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SKEMA[:PATH] [KUNCI]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Cara pakai:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] PERINTAH [ARG…]\n" +"\n" +"Perintah:\n" +" help Tampilkan informasi ini\n" +" list-schemas Tampilkan daftar skema yang terpasang\n" +" list-relocatable-schemas Tampilkan skema yang bisa direlokasi\n" +" list-keys Tampilkan daftar kunci dalam suatu skema\n" +" list-children Tampilkan daftar anak dari suatu skema\n" +" list-recursively Tampilkan kunci dan nilai, secara rekursif\n" +" range Mengkuiri jangkauan dari suatu kunci\n" +" get Mengambil nilai dari suatu kunci\n" +" set Menata nilai dari suatu kunci\n" +" reset Mereset nilai dari suatu kunci\n" +" reset-recursively Reset semua nilai dalam skema yang diberikan\n" +" writable Periksa apakah suatu kunci dapat ditulisi\n" +" monitor Amati perubahan\n" +"\n" +"Pakai 'gsettings help PERINTAH' untuk mendapat bantuan terrinci.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Cara pakai:\n" +" gsettings [--schemadir DIRSKEMA] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " DIRSKEMA Adalah direktori tempat mencari skema tambahan\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SKEMA Nama skema\n" +" PATH Path, bagi skema yang dapat dipindah\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KUNCI Kunci (opsional) dalam skema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KUNCI Kunci dalam skema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " NILAI Tatanan nilai\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Tak bisa memuat skema dari %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Tidak ada skema yang terpasang\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Nama skema yang diberikan kosong\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Tidak ada kunci seperti \"%s\"\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Soket tak valid, tak diinisialisasi" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Soket tak valid, inisialisasi gagal karena: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Soket telah ditutup" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "I/O soket kehabisan waktu" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "membuat GSocket dari fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Tak bisa membuat soket: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Famili tak dikenal dinyatakan" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Protokol tak dikenal dinyatakan" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Tak bisa memakai operasi datagram pada suatu soket bukan datagram." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Tak bisa memakai operasi datagram pada suatu soket yang tenggang waktunya " +"ditata." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "tak bisa mendapat alamat lokal: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "tak bisa mendapat alamat jauh: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "tak bisa mendengarkan: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Galat saat mengikat ke alamat %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Galat saat bergabung dengan grup multicast: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Galat saat meninggalkan grup multicast: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Tak ada dukungan bagi multicast spesifik sumber" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Keluarga soket tak didukung" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "spesifik sumber bukan alamat IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Nama antarmuka terlalu panjang" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Antarmuka tidak ditemukan: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Tak ada dukungan bagi multicast spesifik sumber IPV4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Tak ada dukungan bagi multicast spesifik sumber IPV6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Galat saat menerima sambungan: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Penyambungan tengah berlangsung" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Tak bisa mendapat kesalahan yang tertunda: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Galat saat menerima data: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Galat saat mengirim data: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Tak bisa mematikan soket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Galat saat menutup soket: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Menunggu kondisi soket: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Tak bisa mengirim pesan: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vektor pesan terlalu besar" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Galat saat menerima pesan: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage tak didukung pada Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Galat saat menerima pesan: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Tak bisa membaca kredensial soket: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials tidak diimplementasikan untuk OS ini" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Tak bisa menyambung ke peladen proksi %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Tak bisa menyambung ke %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Tak bisa menyambung: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Proksi melalui koneksi bukan TCP tidak didukung." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Protokol proksi \"%s\" tidak didukung." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Pendengar telah ditutup" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Soket yang ditambahkan tertutup" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 tidak mendukung alamat IPv6 \"%s\"" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Nama pengguna terlalu panjang bagi protokol SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Nama host \"%s\" terlalu panjang bagi protokol SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Peladen bukan peladen proksi SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Koneksi melalui peladen SOCKSv4 ditolak" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Peladen bukan peladen proksi SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Proksi SOCKv5 memerlukan autentikasi." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 memerlukan metode autentikasi yang tidak didukung oleh GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Nama pengguna atau kata sandi terlalu panjang bagi protokol SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "Autentikasi SOCKSv5 gagal karena nama pengguna atau kata sandi salah." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Nama host \"%s\" terlalu panjang bagi protokol SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Peladen proksi SOCKSv5 memakai jenis alamat yang tidak dikenal." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Galat internal peladen proksi SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Koneksi SOCKSv5 tidak diijinkan oleh ruleset." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Host tidak dapat dijangkau melalui peladen SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Jaringan tidak dapat dijangkau melalui proksi SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Koneksi melalui proksi SOCKSv5 ditolak." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Proksi SOCSKv5 tidak mendukung perintah \"connect\"." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Proksi SOCSKv5 tidak mendukung jenis alamat yang diberikan." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Galat tak dikenal pada proksi SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Gagal saat membuat pipe untuk sarana komunikasi dengan proses anak (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Pipa tak didukung pada platform ini" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Tak bisa menangani pengkodean versi %d dari GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Tak ada alamat valid yang ditemukan" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Galat saat mengurai balik \"%s\": %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Galat saat mengurai record %s DNS: paket DNS salah bentuk" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Tidak ada record DNS dengan tipe yang diminta bagi \"%s\"" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Sementara tidak dapat mengurai \"%s\"" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Galat saat mengurai \"%s\"" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Paket DNS salah bentuk" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Gagal mengurai respon DNS untuk \"%s\": " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Tak ditemukan sertifikat terenkode-PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Tak bisa mendekripsi kunci privat terenkode-PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Tak bisa mengurai kunci privat terenkode-PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Tak ditemukan sertifika terenkode-PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Tak bisa mengurai sertifikat terenkode-PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Backend TLS saat ini tidak mendukung PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "GTlsBackend ini tidak mendukung pembuatan sertifikat PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ini adalah kesempatan terakhir untuk memasukkan sandi secara benar sebelum " +"akses Anda diblokir." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Beberapa kata sandi yang dimasukkan salah, dan akses Anda akan terkunci " +"setelah gagal lagi." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Sandi yang dimasukkan salah." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Mengirim FD tidak didukung" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Mengharapkan 1 pesan kendali, memperoleh %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Tipe yang tak diharapkan dari data ancillary" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Mengharapkan satu fd, tapi mendapat %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Menerima fd yang tak valid" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Menerima FD tidak didukung" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Galat saat mengirim kredensial: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Galat ketika memeriksa apakah SO_PASSCRED diaktifkan bagi soket: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Galat saat mengaktifkan SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Berharap membaca bita tunggal untuk penerimaan kredensial tapi membaca nol " +"bita" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Tak mengharapkan pesan kendali, tapi memperoleh %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Galat ketika mematikan SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Galat saat membaca dari descriptor berkas: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Galat saat menutup descriptor berkas: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Akar sistem berkas" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Galat saat menulis ke descriptor berkas: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Alamat soket domain UNIX abstrak tak didukung pada sistem ini" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "volume tidak mengimplementasikan eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volume tidak mengimplementasikan eject atau eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Galat saat membaca dari handle: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Galat saat menutup handle: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Galat saat menulis ke handle: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Tidak cukup memori" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Galat internal: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Perlu masukan lagi" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Data terkompresi tak valid" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Alamat tempat mendengarkan" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Diabaikan, bagi kompatibilitas dengan GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Cetak alamat" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Cetak alamat dalam mode shell" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Jalankan layanan dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Arg salah\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Atribut \"%s\" yang tidak diharapkan untuk elemen \"%s\"" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atribut \"%s\" dari elemen \"%s\" tak ditemukan" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Tag \"%s\" yang tak diharapkan, diharapkan tag \"%s\"" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Tag \"%s\" yang tak diharapkan di dalam \"%s\"" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Tanggal/waktu ‘%s’ tidak valid dalam berkas markah" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Tak ditemukan markah yang valid di direktori data" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Markah untuk URI \"%s\" telah ada" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Tak ditemukan markah untuk URI \"%s\"" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Tidak ada jenis MIME yang didefinisikan pada markah untuk URI \"%s\"" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Tidak ada tanda privat yang ditetapkan dalam markah untuk URI \"%s\"" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Tidak ada grup yang ditetapkan dalam markah untuk URI \"%s\"" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Tak ditemukan aplikasi terdaftar dengan nama \"%s\" bagi markah \"%s\"" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Gagal mengembangkan baris eksekusi \"%s\" dengan URI \"%s\"" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Karakter yang tidak dapat diterima dalam masukan konversi" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Rangkaian karakter sebagian pada akhir input" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Tak bisa mengonversi fallback \"%s\" menjadi codeset \"%s\"" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "NUL bita tertanam dalam masukan konversi" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "NUL bita tertanam dalam keluaran konversi" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI \"%s\" bukanlah URI absolut dengan menggunakan skema \"file\"" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "URI berkas lokal \"%s\" tak boleh mengandung \"#\"" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI \"%s\" tidak valid" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Nama host dari URI \"%s\" tidak valid" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI \"%s\" mengandung karakter yang di-escape secara tidak valid" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Nama path \"%s\" bukan lokasi absolut" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %r %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Januari" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Februari" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Maret" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Mei" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Juni" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Juli" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Agustus" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Oktober" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Desember" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mei" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ags" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Des" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Senin" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Selasa" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Rabu" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Kamis" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Jumat" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sabtu" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Minggu" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Sen" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Sel" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Rab" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Kam" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Jum" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sab" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Min" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Januari" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Februari" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Maret" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Mei" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Juni" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Juli" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "Agustus" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Oktober" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Desember" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mei" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ags" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Okt" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Des" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Galat saat membuka direktori \"%s\": %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Tak bisa mengalokasikan %lu bita untuk membaca berkas \"%s\"" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Galat saat membaca berkas \"%s\": %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Berkas \"%s\" terlalu besar" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Gagal membaca dari berkas \"%s\": %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Gagal membuka berkas \"%s\": %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Gagal mendapat atribut berkas \"%s\": fstat() gagal: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Gagal membuka berkas \"%s\": fdopen() gagal: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Gagal mengubah nama berkas \"%s\" menjadi \"%s\": g_rename() gagal: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Gagal menulis berkas \"%s\": write() gagal: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Gagal menulis berkas \"%s\": fsync() gagal: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Gagal membuat berkas \"%s\": %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Berkas \"%s\" yang ada tidak dapat dibuang: g_unlink() gagal: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Templat \"%s\" tidak valid, tidak boleh mengandung \"%s\"" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Templat \"%s\" tidak memuat XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Gagal membaca taut simbolik \"%s\": %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Tak bisa membuka pengubah dari \"%s\" menjadi \"%s\": %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Tak bisa melakukan pembacaan mentah dalam g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Ada data tersisa yang belum dikonversi pada penyangga read" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanal terputus pada karakter sebagian" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Tak bisa melakukan pembacaan mentah dalam g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Berkas kunci yang valid tak ditemukan pada direktori yang dicari" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Bukan berkas biasa" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Berkas kunci mengandung baris \"%s\" yang bukan suatu pasangan kunci-nilai, " +"kelompok, atau komentar" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nama grup tak valid: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Berkas kunci tidak mulai dengan sebuah kelompok" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nama kunci tak valid: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Berkas kunci mengandung enkoding \"%s\" yang tidak didukung" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Berkas kunci tidak memiliki grup \"%s\"" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Berkas kunci tidak memiliki kunci \"%s\" dalam kelompok \"%s\"" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Berkas kunci mengandung kunci \"%s\" dengan nilai \"%s\" yang bukan UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Berkas kunci mengandung kunci \"%s\" yang nilainya tidak dapat diterjemahkan." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Berkas kunci mengandung kunci \"%s\" dalam grup \"%s\" yang nilainya tidak " +"dapat diterjemahkan." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Kunci \"%s\" dalam grup \"%s\" bernilai \"%s\" padahal diharapkan %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Berkas kunci mengandung karakter escape pada akhir baris" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Berkas kunci memuat urutan escape \"%s\" yang tidak valid" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Nilai \"%s\" tidak bisa diterjemahkan sebagai sebuah bilangan." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Nilai bilangan bulat \"%s\" di luar jangkauan" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Nilai \"%s\" tidak dapat diterjemahkan sebagai sebuah bilangan float." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Nilai \"%s\" tidak dapat diterjemahkan sebagai sebuah boolean." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Gagal mengambil atribut berkas \"%s%s%s%s\": fstat() gagal: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Gagal memetakan %s%s%s%s: mmap() gagal: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Gagal membuka berkas \"%s\": open() gagal: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Galat pada baris %d karakter ke-%d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Teks UTF-8 dalam nama tak valid — bukan “%s†yang valid" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†bukan suatu nama yang valid" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†bukan suatu nama yang valid: \"%c\"" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Galat pada baris ke-%d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Gagal saat mengurai \"%-.*s\", yang seharusnya sebuah digit dalam referensi " +"karakter (misalnya ê) — mungkin digitnya terlalu besar" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Referensi karakter tidak diakhiri dengan titik koma; mungkin Anda sedang " +"menggunakan karakter ampersand tanpa bermaksud menjadikannya sebagai entitas " +"— escape ampersand sebagai &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "" +"Referensi karakter \"%-.*s\" tidak mengenkode karakter yang diperbolehkan" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Ada entitas \"&;\" yang kosong; entitas yang benar antara lain adalah: & " +"" < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Nama entitas \"%-.*s\" tak dikenal" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entitas tidak diakhiri dengan titik koma; mungkin Anda menggunakan karakter " +"ampersand tanpa bermaksud menjadikannya sebagai entitas — escape ampersand " +"sebagai &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumen harus dimulai dengan elemen (misalnya )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%s†bukanlah karakter yang benar bila diikuti dengan karakter \"<\". Ini " +"tidak boleh menjadi nama elemen" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Ada karakter aneh “%sâ€, seharusnya ada \">\" untuk mengakhiri tag elemen " +"kosong “%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Terlalu banyak atribut dalam elemen \"%s\"" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Ada karakter aneh “%sâ€. Seharusnya ada karakter '=' setelah nama atribut " +"“%s†pada elemen “%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Ada karakter aneh “%sâ€. Seharusnya ada \">\" atau \"/\" untuk mengakhiri tag " +"padaelemen “%sâ€, atau bisa juga ada atribut lain. Mungkin Anda menggunakan " +"karakter yang tidak diperbolehkan pada nama atribut" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Ada karakter aneh “%sâ€. Seharusnya ada tanda kutip buka setelah tanda sama " +"dengan saat memberikan nilai atribut “%s†pada elemen “%sâ€" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%s†bukan karakter yang benar bila diikuti elemen penutup “%sâ€. Karakter " +"yang diperbolehkan adalah \">\"" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Elemen “%s†sudah ditutup, tidak ada elemen yang masih terbuka" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Elemen “%s†sudah ditutup, tapi elemen yang masih terbuka adalah “%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumen kosong atau berisi whitespace saja" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Dokumen terpotong tidak sempurna sesaat setelah membuka kurung siku \"<\"" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokumen terpotong tidak sempurna dengan elemen yang masih terbuka — “%s†" +"adalah elemen terakhir yang dibuka" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokumen terpotong tidak sempurna, seharusnya ada kurung siku penutup untuk " +"mengakhiri tag <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumen terpotong tidak sempurna pada dalam nama elemen" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumen terpotong tidak sempurna di dalam nama atribut" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumen terpotong tidak sempurna di dalam tag pembukaan elemen." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokumen terpotong tidak sempurna setelah tanda sama dengan mengikuti nama " +"atribut. Tidak ada nilai atribut yang diperoleh" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumen tidak sempura saat ada dalam nilai atribut" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokumen terpotong tidak sempurna di dalam tag penutup elemen “%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Dokumen terpotong tidak sempurna di dalam tag penutup untuk elemen yang " +"belum dibuka" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokumen terpotong tidak sempurna di dalam keterangan atau instruksi " +"pemrosesan" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPSI…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opsi Bantuan:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Menampilkan opsi bantuan" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Menampilkan semua opsi bantuan" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opsi Aplikasi:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opsi:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Tak bisa mengurai nilai bilangan bulat \"%s\" untuk \"%s\"" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Nilai bilangan bulat \"%s\" untuk %s di luar jangkauan" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Tak bisa mengurai nilai double \"%s\" bagi %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Nilai double \"%s\" untuk %s di luar jangkauan" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Galat saat mengurai opsi %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Argumen untuk %s tidak lengkap" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Pilihan tidak diketahui %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "objek rusak" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "kesalahan internal atau objek rusak" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "kehabisan memori" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "batas pelacakan balik tercapai" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "pola memuat butir yang tak didukung bagi pencocokan sebagian" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "kesalahan internal" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "acuan balik sebagai persyaratan tak didukung bagi pencocokan sebagian" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "batas rekursi dicapai" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "kombinasi tanda baris baru yang tak valid" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "nilai offset salah" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 pendek" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "pengulangan rekursi" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "galat tak dikenal" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ di akhir pola" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c di akhir pola" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "karakter tak dikenal setelah \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "angka tak urut di quantifier {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "angka terlalu besar di quantifier {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "pengakhiran ] hilang bagi kelas karakter" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "rangkaian escape tak valid dalam kelas karakter" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "jangkauan tak terurut dalam kelas karakter" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "tak ada yang dapat diulang" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "pengulangan yang tak diharapkan" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "karakter tak dikenal setelah (? atau (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "kelas POSIX yang bernama hanya didukung di dalam suatu kelas" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "pengakhiran ) hilang" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "acuan ke sub pola yang tak ada" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "tak ada ) setelah komentar" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "ekspresi reguler terlalu besar" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "gagal memperoleh memori" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") tanpa pembuka (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "kode tumpah (overflow)" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "karakter tak dikenal setelah (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "panjang asersi lookbehind tak tetap" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "angka atau nama salah bentuk setelah (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "grup bersyarat mengandung lebih dari dua cabang" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "berharap asersi setelah (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R atau (?[+-]digit mesti diikuti oleh )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nama kelas POSIX tak dikenal" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "elemen kolasi POSIX tak didukung" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "nilai karakter dalam urutan \\x{...} terlalu besar" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "kondisi tak valid (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C tak diijinkan di asersi lookbehind" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escape \\L, \\l, \\N{name}, \\U, dan \\u tak didukung" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "pemanggilan rekursif bisa berulang tak terhingga" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "karakter tak dikenal setelah (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "terminator di nama sub pola hilang" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dua sub pola yang bernama memiliki nama sama" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "urutan \\P atau \\p salah bentuk" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nama properti tak dikenal setelah \\P atau \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "nama sub pola terlalu panjang (maksimum 32 karakter)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "terlalu banyak sub pola yang dinamai (maksimum 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "nilai oktal lebih dari \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "menimpa ruang kerja kompilasi" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "sub pola yang diacu yang sebelumnya diperiksa tak ditemukan" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "grup DEFINE mengandung lebih dari satu cabang" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opsi NEWLINE tak konsisten" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g tak diikuti oleh bilangan atau nama dalam tanda kutip, kurung siku, atau " +"kurung kurawal, atau bilangan polos" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "acuan bernomor tak boleh nol" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "argumen tak diijinkan bagi (*ACCEPT), (*FAIL), atau (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) tak dikenal" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "angka terlalu besar" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "kurang nama sub pola setelah (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "diharapkan digit setelah (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] adalah karakter data tak valid dalam mode kompatibilitas JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "nama-nama berbeda bagi sub pola dari bilangan yang sama tak diijinkan" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) mesti punya argumen" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c mesti diikuti oleh sebuah karakter ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k tak diikuti oleh nama yang diapit tanda kutip, kurung siku, atau kurung " +"kurawal" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N tak didukung dalam suatu kelas" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "terlalu banyak acuan maju" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "nama terlalu panjang dalam (*MARK), (*PRUNE), (*SKIP), atau (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "nilai karakter dalam urutan \\u.... terlalu besar" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Galat saat mencocokkan ekspresi reguler %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Pustaka PCRE dikompail tanpa dukungan UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Pustaka PCRE dikompail tanpa dukungan properti UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Pustaka PCRE dikompail dengan opsi yang tak kompatibel" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Galat saat mengoptimasi ekspresi reguler %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Galat saat mengkompail ekspresi reguler %s pada karakter %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "digit heksadesimal atau \"}\" diharapkan" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "digit heksadesimal diharapkan" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "kurang \"<\" dalam acuan simbolis" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "acuan simbolis yang belum selesai" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "acuan simbolis dengan panjang nol" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "diharapkan digit" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "acuan simbolis yang tak legal" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "\"\\\" akhir yang tersesat" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "urutan escape tak dikenal" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Galat saat mengurai teks pengganti \"%s\" pada karakter %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Teks yang dikutip tidak dimulai dengan tanda kutip" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Tanda kutip kurang satu pada perintah atau pada teks yang dikutip dari shell " +"lain" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Teks berakhir tepat setelah karakter \"\\\". (Teksnya adalah \"%s\")" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Teks berakhir sebelum tanda kutip pasangannya ditemukan untuk %c. (Teksnya " +"adalah \"%s\")" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Teksnya kosong (atau hanya berisi whitespace)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Gagal saat membaca data dari proses anak (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Galat tak terduga dalam membaca data dari proses anak (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Terjadi galat pada fungsi waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Proses anak keluar dengan kode %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Proses anak dimatikan oleh sinyal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Proses anak dihentikan oleh sinyal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Proses anak keluar secara tak normal" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Gagal saat membaca dari pipe anak (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Gagal menelurkan proses anak \"%s\" (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Gagal saat fork (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Gagal pindah ke direktori \"%s\" (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Gagal menjalankan proses anak \"%s\" (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Gagal membuka berkas untuk memetakan ulang deskriptor berkas (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Gagal menduplikasi deskriptor berkas untuk proses anak (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Gagal saat fork proses anak (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Gagal menutup deskriptor berkas untuk proses anak (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Galat tak dikenal ketika menjalankan proses anak \"%s\"" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Gagal saat membaca data yang dibutuhkan dai pipe pid anak (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Gagal untuk membaca data dari proses anak" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Gagal saat menjalankan proses anak (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Gagal dup() dalam proses anak (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nama program salah: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "String tidak benar pada vektor argumen pada %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "String tidak benar pada variabel lingkungan: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Direktori aktif salah: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Gagal saat menjalankan program bantuan (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Terjadi galat pada g_io_channel_win32_poll() ketika membaca data dari anak " +"proses" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "String kosong bukan angka" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "\"%s\" bukan bilangan bertanda" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Nomor \"%s\" berada di luar batas [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "\"%s\" bukan bilangan tak bertanda" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-encode dalam URI tidak valid" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Karakter ilegal dalam URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Karakter non-UTF-8 dalam URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Alamat IPv6 tidak valid ‘%.*s’ dalam URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Alamat IP dikodekan ilegal ‘%.*s’ dalam URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nama host internasional ilegal '%.*s' di URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Tak bisa menguraikan port ‘%.*s’ dalam URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Port ‘%.*s’ dalam URI di luar jangkauan" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI ‘%s’ bukan URI absolut" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI ‘%s’ tidak memiliki komponen host" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI tidak absolut, dan tidak ada dasar URI yang disediakan" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "'=' dan nilai parameter tidak ada" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Gagal mengalokasikan memori" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Karakter di luar jangkauan UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Rangkaian input konversi salah" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Karakter di luar jangkauan UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bita" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bita" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bita" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bita" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" diff --git a/po/is.po b/po/is.po new file mode 100644 index 0000000..06f7549 --- /dev/null +++ b/po/is.po @@ -0,0 +1,4628 @@ +# Icelandic translation of glib +# Copyright (C) 2003 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# +# Richard Allen , 2003. +# Sveinn í Felli , 2015. +msgid "" +msgstr "" +"Project-Id-Version: glib 2.2\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2015-04-24 06:02+0000\n" +"PO-Revision-Date: 2015-04-24 14:35+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#: ../gio/gapplication.c:531 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" + +#: ../gio/gapplication.c:536 +msgid "GApplication options" +msgstr "" + +#: ../gio/gapplication.c:536 +msgid "Show GApplication options" +msgstr "" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:485 ../gio/gsettings-tool.c:521 +msgid "Print help" +msgstr "" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:486 +#: ../gio/gresource-tool.c:554 +msgid "[COMMAND]" +msgstr "" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:527 +msgid "Print version information and exit" +msgstr "" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" + +#: ../gio/gapplication-tool.c:55 +#, fuzzy +msgid "Launch an application" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:492 +#: ../gio/gresource-tool.c:558 +msgid "FILE" +msgstr "" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:523 +#: ../gio/gsettings-tool.c:607 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:548 +#: ../gio/gsettings-tool.c:641 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:171 +#, fuzzy, c-format +msgid "invalid application id: '%s'\n" +msgstr "Villa við umbreytingu: %s" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" + +#: ../gio/gapplication-tool.c:266 +#, fuzzy, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/gapplication-tool.c:286 +#, fuzzy, c-format +msgid "error sending %s message to application: %s\n" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" + +#: ../gio/gapplication-tool.c:344 +#, fuzzy, c-format +msgid "error parsing action parameter: %s\n" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:376 +#: ../gio/ginputstream.c:614 ../gio/ginputstream.c:1013 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:830 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +#, fuzzy +msgid "Seek not supported on base stream" +msgstr "Tákntengi eru ekki studd" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1202 +#: ../gio/giostream.c:278 ../gio/goutputstream.c:1654 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +#, fuzzy +msgid "Truncate not supported on base stream" +msgstr "Tákntengi eru ekki studd" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1858 +#: ../gio/gdbusprivate.c:1375 ../gio/glocalfile.c:2212 +#: ../gio/gsimpleasyncresult.c:870 ../gio/gsimpleasyncresult.c:896 +#, c-format +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Ógild bætaruna í ílagi umbreytingar" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1556 ../glib/giochannel.c:1598 +#: ../glib/giochannel.c:2442 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "Ógild bætaruna í ílagi umbreytingar" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1563 ../glib/giochannel.c:2454 +#, c-format +msgid "Error during conversion: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:990 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Tákntengi eru ekki studd" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1384 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Umbreyting úr stafasettinu '%s' í '%s' er ekki stutt" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Gat ekki opnað umbreyti úr '%s' í '%s': %s" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:650 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:694 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusaddress.c:712 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusaddress.c:721 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusaddress.c:739 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusaddress.c:945 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1015 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "" + +#: ../gio/gdbusaddress.c:1022 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1064 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusaddress.c:1281 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: ../gio/gdbusaddress.c:1412 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: ../gio/gdbusaddress.c:1433 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1533 ../gio/gdbusconnection.c:6825 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1542 ../gio/gdbusconnection.c:6834 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1552 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, fuzzy, c-format +#| msgid "Error opening directory '%s': %s" +msgid "Error when getting information for directory '%s': %s" +msgstr "Villa við að opna möppuna '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Villa við að opna möppuna '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2359 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1888 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2481 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:4061 ../gio/gdbusconnection.c:4408 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4203 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4215 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:4226 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4246 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4351 ../gio/gdbusconnection.c:6265 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4559 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4777 ../gio/gdbusconnection.c:6774 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4875 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4906 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5104 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:5303 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:6376 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6497 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:1244 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:1255 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1266 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1278 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1291 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1299 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1307 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1355 ../gio/gdbusmessage.c:1415 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1369 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1388 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1587 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1656 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1676 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: ../gio/gdbusmessage.c:1843 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1867 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2051 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:2064 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:2120 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:2134 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:2164 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:2174 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2515 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2652 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2660 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2704 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2714 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2730 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:3283 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusmessage.c:3291 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:2036 +#, fuzzy, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/gdbusprivate.c:2081 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1610 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1633 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2708 ../gio/gdbusproxy.c:2842 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:708 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Tákntengi eru ekki studd" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:873 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:226 ../gio/gdbus-tool.c:298 +#: ../gio/gdbus-tool.c:322 ../gio/gdbus-tool.c:711 ../gio/gdbus-tool.c:1043 +#: ../gio/gdbus-tool.c:1477 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Villa á línu %d: %s" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:239 ../gio/gdbus-tool.c:1493 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gdbus-tool.c:208 +#, fuzzy, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Táknið '%s' er ekki gilt í heitum viðfanga" + +#: ../gio/gdbus-tool.c:356 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:357 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:358 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:368 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:369 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:391 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:401 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:471 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:480 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:542 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:543 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:544 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:576 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:610 ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1583 +#: ../gio/gdbus-tool.c:1818 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gdbus-tool.c:622 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:627 ../gio/gdbus-tool.c:909 ../gio/gdbus-tool.c:1648 +#: ../gio/gdbus-tool.c:1884 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:633 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:648 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Táknið '%s' er ekki gilt í heitum viðfanga" + +#: ../gio/gdbus-tool.c:654 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Táknið '%s' er ekki gilt í heitum viðfanga" + +#: ../gio/gdbus-tool.c:660 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Táknið '%s' er ekki gilt í heitum viðfanga" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:687 ../gio/gdbus-tool.c:1011 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gdbus-tool.c:718 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gdbus-tool.c:745 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:746 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:747 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:748 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:787 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:862 ../gio/gdbus-tool.c:1602 ../gio/gdbus-tool.c:1837 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:874 ../gio/gdbus-tool.c:1619 ../gio/gdbus-tool.c:1849 +#, fuzzy, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Táknið '%s' er ekki gilt í heitum viðfanga" + +#: ../gio/gdbus-tool.c:889 ../gio/gdbus-tool.c:1628 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:924 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:935 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:1003 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Villa við að opna möppuna '%s': %s" + +#: ../gio/gdbus-tool.c:1440 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1441 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1442 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1443 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1444 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1535 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1740 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1741 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1770 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:1993 ../gio/gdesktopappinfo.c:4511 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2402 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2687 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3108 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3112 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3352 ../gio/gdesktopappinfo.c:3376 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3609 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:3743 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:968 ../gio/gfile.c:1206 ../gio/gfile.c:1344 +#: ../gio/gfile.c:1582 ../gio/gfile.c:1637 ../gio/gfile.c:1695 +#: ../gio/gfile.c:1779 ../gio/gfile.c:1836 ../gio/gfile.c:1900 +#: ../gio/gfile.c:1955 ../gio/gfile.c:3603 ../gio/gfile.c:3658 +#: ../gio/gfile.c:3893 ../gio/gfile.c:3935 ../gio/gfile.c:4398 +#: ../gio/gfile.c:4809 ../gio/gfile.c:4894 ../gio/gfile.c:4984 +#: ../gio/gfile.c:5081 ../gio/gfile.c:5168 ../gio/gfile.c:5269 +#: ../gio/gfile.c:7788 ../gio/gfile.c:7878 ../gio/gfile.c:7962 +#: ../gio/win32/gwinhttpfile.c:437 +#, fuzzy +msgid "Operation not supported" +msgstr "Tákntengi eru ekki studd" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1467 ../gio/glocalfile.c:1134 ../gio/glocalfile.c:1145 +#: ../gio/glocalfile.c:1158 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2514 ../gio/glocalfile.c:2368 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2574 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2582 ../gio/glocalfile.c:2377 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2601 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2883 +#, fuzzy +msgid "Splice not supported" +msgstr "Tákntengi eru ekki studd" + +#: ../gio/gfile.c:2887 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gfile.c:3018 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" + +#: ../gio/gfile.c:3022 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: ../gio/gfile.c:3027 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "" + +#: ../gio/gfile.c:3090 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3883 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:4044 +#, fuzzy +msgid "Trash not supported" +msgstr "Tákntengi eru ekki studd" + +#: ../gio/gfile.c:4156 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6580 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6689 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/ghttpproxy.c:136 +msgid "Bad HTTP proxy reply" +msgstr "" + +#: ../gio/ghttpproxy.c:152 +msgid "HTTP proxy connection not allowed" +msgstr "" + +#: ../gio/ghttpproxy.c:157 +msgid "HTTP proxy authentication failed" +msgstr "" + +#: ../gio/ghttpproxy.c:160 +msgid "HTTP proxy authentication required" +msgstr "" + +#: ../gio/ghttpproxy.c:164 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "" + +#: ../gio/ghttpproxy.c:260 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1212 ../gio/giostream.c:288 +#: ../gio/goutputstream.c:1664 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1484 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "" + +#: ../gio/glib-compile-resources.c:260 +#, fuzzy, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to locate '%s' in current directory" +msgstr "Gat ekki farið í möppuna '%s' (%s)" + +#: ../gio/glib-compile-resources.c:288 +#, fuzzy, c-format +msgid "Unknown processing option \"%s\"" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, fuzzy, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to create temp file: %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/glib-compile-resources.c:380 +#, fuzzy, c-format +#| msgid "Error reading file '%s': %s" +msgid "Error reading file %s: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glib-compile-resources.c:400 +#, fuzzy, c-format +msgid "Error compressing file %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1596 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:589 +#, fuzzy +msgid "name of the output file" +msgstr "Vélarheitið í URI '%s' er ógilt" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:2027 +#: ../gio/glib-compile-schemas.c:2056 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:777 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Tákntengi eru ekki studd" + +#: ../gio/glib-compile-schemas.c:787 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:799 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:808 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:817 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:825 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:894 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:920 +msgid "cannot add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:931 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:949 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:960 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:979 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:994 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1024 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1037 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1045 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1118 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1130 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1154 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1164 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1174 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1184 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1208 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1240 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1390 ../gio/glib-compile-schemas.c:1406 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1488 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1785 ../gio/glib-compile-schemas.c:1856 +#: ../gio/glib-compile-schemas.c:1932 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1793 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1852 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1892 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1898 ../gio/glib-compile-schemas.c:1956 +#: ../gio/glib-compile-schemas.c:1984 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1902 ../gio/glib-compile-schemas.c:1960 +#: ../gio/glib-compile-schemas.c:1988 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1918 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1928 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1946 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1974 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2027 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2029 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2030 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2059 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:2075 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2114 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2117 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2120 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocalfile.c:635 ../gio/win32/gwinhttpfile.c:420 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Ógilt vélarheiti" + +#: ../gio/glocalfile.c:1012 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfile.c:1180 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1200 ../gio/glocalfile.c:1226 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfile.c:1209 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1222 ../gio/glocalfile.c:2241 ../gio/glocalfile.c:2270 +#: ../gio/glocalfile.c:2430 ../gio/glocalfileoutputstream.c:549 +#, fuzzy +msgid "Invalid filename" +msgstr "Ógilt vélarheiti" + +#: ../gio/glocalfile.c:1389 ../gio/glocalfile.c:1413 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1397 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfile.c:1538 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfile.c:1918 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfile.c:1941 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/glocalfile.c:1962 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:2041 ../gio/glocalfile.c:2061 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:2095 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/glocalfile.c:2126 ../gio/glocalfile.c:2131 ../gio/glocalfile.c:2211 +#: ../gio/glocalfile.c:2218 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/glocalfile.c:2219 ../glib/gregex.c:281 +msgid "internal error" +msgstr "" + +#: ../gio/glocalfile.c:2245 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Villa við að opna möppuna '%s': %s" + +#: ../gio/glocalfile.c:2274 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "gat ekki lesið tákntengið '%s': %s" + +#: ../gio/glocalfile.c:2278 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/glocalfile.c:2340 ../gio/glocalfile.c:2434 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfile.c:2363 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2390 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2409 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfile.c:2423 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfile.c:2615 +#, fuzzy, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Gat ekki frátekið %lu bæti til að lesa skrána \"%s\"" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:735 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "Skjalið endar óvænt inn í heiti eiginleika" + +#: ../gio/glocalfileinfo.c:775 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Villa við að opna möppuna '%s': %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, fuzzy, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileinfo.c:1998 +#, fuzzy, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2134 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/glocalfileinfo.c:2150 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "Villa á línu %d: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2369 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2407 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2506 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Tákntengi eru ekki studd" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfilemonitor.c:838 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1018 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:769 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:481 +#, fuzzy +msgid "Invalid seek request" +msgstr "Ógilt vélarheiti" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:671 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:779 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:794 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:383 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/gnetworkmonitorbase.c:199 ../gio/gnetworkmonitorbase.c:302 +msgid "Network unreachable" +msgstr "" + +#: ../gio/gnetworkmonitorbase.c:237 ../gio/gnetworkmonitorbase.c:267 +msgid "Host unreachable" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, fuzzy, c-format +msgid "Could not create network monitor: %s" +msgstr "Gat ekki frátekið %lu bæti til að lesa skrána \"%s\"" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:175 +#, fuzzy +msgid "Could not get network status: " +msgstr "Gat ekki frátekið %lu bæti til að lesa skrána \"%s\"" + +#: ../gio/gnetworkmonitornm.c:278 +#, c-format +msgid "NetworkManager version too old" +msgstr "" + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:557 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:518 ../gio/goutputstream.c:1218 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:331 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gresource.c:298 ../gio/gresource.c:546 ../gio/gresource.c:563 +#: ../gio/gresource.c:684 ../gio/gresource.c:753 ../gio/gresource.c:814 +#: ../gio/gresource.c:894 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "" + +#: ../gio/gresource.c:463 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "" + +#: ../gio/gresource-tool.c:491 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: ../gio/gresource-tool.c:497 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: ../gio/gresource-tool.c:500 ../gio/gresource-tool.c:510 +msgid "FILE [PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:501 ../gio/gresource-tool.c:511 +#: ../gio/gresource-tool.c:518 +msgid "SECTION" +msgstr "" + +#: ../gio/gresource-tool.c:506 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: ../gio/gresource-tool.c:516 +msgid "Extract a resource file to stdout" +msgstr "" + +#: ../gio/gresource-tool.c:517 +msgid "FILE PATH" +msgstr "" + +#: ../gio/gresource-tool.c:531 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:545 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:552 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: ../gio/gresource-tool.c:556 ../gio/gsettings-tool.c:648 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gresource-tool.c:562 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: ../gio/gresource-tool.c:565 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: ../gio/gresource-tool.c:569 +msgid "[PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:571 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: ../gio/gresource-tool.c:572 +msgid "PATH" +msgstr "" + +#: ../gio/gresource-tool.c:574 +msgid " PATH A resource path\n" +msgstr "" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:490 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:497 +#, c-format +msgid "The key is not writable\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:546 ../gio/gsettings-tool.c:552 +#: ../gio/gsettings-tool.c:589 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:559 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:564 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:565 ../gio/gsettings-tool.c:571 +#: ../gio/gsettings-tool.c:583 ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:577 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:603 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:615 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:638 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:644 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:657 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:720 +#, fuzzy, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Gat ekki opnað umbreyti úr '%s' í '%s': %s" + +#: ../gio/gsettings-tool.c:782 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsettings-tool.c:811 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsocket.c:271 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:278 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:286 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:301 ../gio/gsocket.c:3630 ../gio/gsocket.c:3685 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:448 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gsocket.c:476 ../gio/gsocket.c:530 ../gio/gsocket.c:537 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/gsocket.c:530 +msgid "Unknown family was specified" +msgstr "" + +#: ../gio/gsocket.c:537 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1730 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1773 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "Gat ekki frátekið %lu bæti til að lesa skrána \"%s\"" + +#: ../gio/gsocket.c:1834 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1933 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gsocket.c:2048 ../gio/gsocket.c:2085 +#, fuzzy, c-format +msgid "Error joining multicast group: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gsocket.c:2049 ../gio/gsocket.c:2086 +#, fuzzy, c-format +msgid "Error leaving multicast group: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gsocket.c:2050 +msgid "No support for source-specific multicast" +msgstr "" + +#: ../gio/gsocket.c:2272 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gsocket.c:2395 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:2445 +#, fuzzy +msgid "Unable to get pending error: " +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/gsocket.c:2648 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gsocket.c:2823 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gsocket.c:2937 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/gsocket.c:3016 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gsocket.c:3623 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3910 ../gio/gsocket.c:3993 ../gio/gsocket.c:4221 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gsocket.c:3935 +msgid "GSocketControlMessage not supported on Windows" +msgstr "" + +#: ../gio/gsocket.c:4549 ../gio/gsocket.c:4687 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gsocket.c:4809 +#, fuzzy, c-format +msgid "Unable to read socket credentials: %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../gio/gsocket.c:4818 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: ../gio/gsocketclient.c:190 +#, fuzzy, c-format +msgid "Could not connect to %s: " +msgstr "Gat ekki opnað umbreyti úr '%s' í '%s': %s" + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "" + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +#, fuzzy +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Tákntengi eru ekki studd" + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Tákntengi eru ekki studd" + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "" + +#: ../gio/gthreadedresolver.c:211 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:561 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:573 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:355 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gunixconnection.c:503 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:518 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gunixconnection.c:547 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:587 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:611 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, fuzzy, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, fuzzy, c-format +msgid "Error closing file descriptor: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gunixmounts.c:2099 ../gio/gunixmounts.c:2152 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, fuzzy, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:303 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Villa við umbreytingu: %s" + +#: ../gio/gwin32appinfo.c:378 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:390 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:344 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gwin32outputstream.c:331 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:340 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Ógilt vélarheiti" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "" + +#: ../glib/gbookmarkfile.c:755 +#, fuzzy, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" +"Undarlegt tákn '%s', átti von á '=' eftir heiti eiginleika '%s' af mengi '%s'" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3377 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "gat ekki lesið tákntengið '%s': %s" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "Ókláruð stafaruna í enda ílags" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Gat ekki umbreytt '%s' í stafatöflu '%s'" + +#: ../glib/gconvert.c:1566 +#, fuzzy, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s' er ekki fullt URI sem notar 'file' skemuna" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "Skráar-URI '%s' má ekki innihalda '#'" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' er ógilt" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Vélarheitið í URI '%s' er ógilt" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' inniheldur ógild sértákn" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Slóðin '%s' er ekki full slóð" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "Ógilt vélarheiti" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "fh" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "eh" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e.%b %Y, %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "janúar" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "febrúar" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "mars" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "apríl" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "maí" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "júní" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "júlí" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "ágúst" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "september" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "október" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "nóvember" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "desember" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "jan" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "apr" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "maí" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jún" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "júl" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ágú" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "sep" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "okt" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nóv" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "des" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "mánudagur" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "þriðjudagur" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "miðvikudagur" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "fimmtudagur" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "föstudagur" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "laugardagur" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "sunnudagur" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "mán" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "þri" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "mið" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "fim" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "fös" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "lau" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "sun" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Villa við að opna möppuna '%s': %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, fuzzy, c-format +#| msgid "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "Gat ekki frátekið %lu bæti til að lesa skrána \"%s\"" +msgstr[1] "Gat ekki frátekið %lu bæti til að lesa skrána \"%s\"" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Villa við lestur skráarinnar '%s': %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Skráin \"%s\" er of stór" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Gat ekki lesið úr skránni '%s': %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Gat ekki opnað skrána '%s': %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "gat ekki lesið eiginleika skráarinnar '%s': fstat() brást: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "gat ekki búið til skrána '%s': %s" + +#: ../glib/gfileutils.c:1068 +#, fuzzy, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#: ../glib/gfileutils.c:1111 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Sniðmátið '%s' er ógilt og ætti ekki að innihalda '%s'" + +#: ../glib/gfileutils.c:1519 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Sniðmátið '%s' endar ekki á XXXXXX" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "gat ekki lesið tákntengið '%s': %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "Tákntengi eru ekki studd" + +#: ../glib/giochannel.c:1388 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Gat ekki opnað umbreyti úr '%s' í '%s': %s" + +#: ../glib/giochannel.c:1733 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Gat ekki lesið í g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1780 ../glib/giochannel.c:2038 +#: ../glib/giochannel.c:2125 +msgid "Leftover unconverted data in read buffer" +msgstr "Það eru eftir óumbreytt gögn í lesminninu" + +#: ../glib/giochannel.c:1861 ../glib/giochannel.c:1938 +msgid "Channel terminates in a partial character" +msgstr "Rásin endar á hluta úr tákni" + +#: ../glib/giochannel.c:1924 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Gat ekki lesið í g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:737 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:773 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:1173 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:1230 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "Ógilt vélarheiti" + +#: ../glib/gkeyfile.c:1252 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:1278 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "Ógilt vélarheiti" + +#: ../glib/gkeyfile.c:1305 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1548 ../glib/gkeyfile.c:1721 ../glib/gkeyfile.c:3099 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3288 ../glib/gkeyfile.c:3418 +#: ../glib/gkeyfile.c:3560 ../glib/gkeyfile.c:3789 ../glib/gkeyfile.c:3856 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1676 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1838 ../glib/gkeyfile.c:1954 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1858 ../glib/gkeyfile.c:1974 ../glib/gkeyfile.c:2343 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2560 ../glib/gkeyfile.c:2928 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2638 ../glib/gkeyfile.c:2715 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" + +#: ../glib/gkeyfile.c:4096 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:4118 +#, fuzzy, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "URI '%s' inniheldur ógild sértákn" + +#: ../glib/gkeyfile.c:4260 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:4274 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:4307 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:4331 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../glib/gmappedfile.c:129 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "gat ekki lesið eiginleika skráarinnar '%s': fstat() brást: %s" + +#: ../glib/gmappedfile.c:195 +#, fuzzy, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#: ../glib/gmappedfile.c:261 +#, fuzzy, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "Villa á línu %d tákn %d: %s" + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Ógildur UTF-8 þýddur texti" + +#: ../glib/gmarkup.c:473 +#, fuzzy, c-format +msgid "'%s' is not a valid name" +msgstr "Táknið '%s' er ekki gilt í heitum viðfanga" + +#: ../glib/gmarkup.c:489 +#, fuzzy, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "Táknið '%s' er ekki gilt í heitum viðfanga" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "Villa á línu %d: %s" + +#: ../glib/gmarkup.c:683 +#, fuzzy, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Gat ekki þáttað '%s' sem ætti að vera tölustafur innan í tilvísun í tákn " +"(til dæmis ê). Ef til vill er talan of stór" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Viðfangið endar ekki á semikommu; líklega notaðir þú og-merkið án þess að " +"ætla að byrja viðfang. Ritaðu það sem &" + +#: ../glib/gmarkup.c:721 +#, fuzzy, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Tákntilvísunin '%s' vísar ekki í leyfilegt tákn" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Tómt viðfang '&;' fannst; gild viðföng eru: & " < > '" + +#: ../glib/gmarkup.c:767 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Viðfangið '%s' er óþekkt" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Viðfangið endar ekki á semikommu; líklega notaðir þú og-merkið án þess að " +"ætla að byrja viðfang. Ritaðu það sem &" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "Skjalið verður að byrja á viðfangi (t.d. )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' er ekki gilt tákn strax á eftir '<' tákninu; það má ekki byrja á heiti " +"viðfangs" + +#: ../glib/gmarkup.c:1260 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "Undarlegt tákn '%s', átti von á '>' tákninu til að enda viðfangið '%s'" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Undarlegt tákn '%s', átti von á '=' eftir heiti eiginleika '%s' af mengi '%s'" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Undarlegt tákn '%s', átti von á '>' eða '/' tákni rtil þess að enda upphafs " +"viðfangi '%s', eða eiginleika; Þú notaðir ef til vill ógilt tákn í heiti " +"eiginleika" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Undarlegt tákn '%s', átti von á tilvísunarmerki eftir samasem merkinu þegar " +"gildi er gefið með eiginleikanum '%s' af menginu '%s'" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' er ekki gilt tákn strax á eftir lokun mengis '%s'. Leyfilegt tákn er '>'" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Mengið '%s' var lokað og engin önnur mengi eru opin" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Mengið '%s' var lokað en mengið sem nú er opið er '%s'" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "Skjalið var tómt eða innihélt einungis orðabil" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Skjalið endar óvænt rétt eftir opið minna en merki '<'" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Skjalið endar óvænt með mengi sem enn eru opin. '%s' var mengið sem síðast " +"var opnað" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Skjalið endar óvænt. Ãtti von á að sjá stærraen merki sem lokar taginu <%s/>" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "Skjalið endar óvænt inn í heiti mengis" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Skjalið endar óvænt inn í heiti eiginleika" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Skjalið endar óvænt inn í tagi sem opnar mengi." + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Skjalið endar óvænt eftir samasem merkið sem fylgir heiti eiginleika og það " +"er ekkert gildi" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Skjalið endar óvænt inn í gildi eiginleika" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Skjalið endar óvænt inni í lokunartagi fyrir mengið '%s'" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Skjalið endar óvænt inni í athugasemd eða í miðri skipun" + +#: ../glib/goption.c:858 +msgid "Usage:" +msgstr "Notkun:" + +#: ../glib/goption.c:858 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:974 +msgid "Help Options:" +msgstr "Hjálparvalmöguleikar:" + +#: ../glib/goption.c:975 +msgid "Show help options" +msgstr "Birta hjálparmöguleika" + +#: ../glib/goption.c:981 +msgid "Show all help options" +msgstr "Birta alla hjálparmöguleika" + +#: ../glib/goption.c:1043 +msgid "Application Options:" +msgstr "Valmöguleikar forrits:" + +#: ../glib/goption.c:1107 ../glib/goption.c:1177 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1117 ../glib/goption.c:1185 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1142 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1150 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1436 ../glib/goption.c:1515 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "Villa við umbreytingu: %s" + +#: ../glib/goption.c:1546 ../glib/goption.c:1659 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:2120 +#, c-format +msgid "Unknown option %s" +msgstr "" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:336 +#, fuzzy +msgid "unrecognized character following \\" +msgstr "Hálfkláruð tákntilvísun" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:345 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "Rásin endar á hluta úr tákni" + +#: ../glib/gregex.c:348 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "Ógild bætaruna í ílagi umbreytingar" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:361 +#, fuzzy +msgid "unrecognized character after (? or (?-" +msgstr "Hálfkláruð tákntilvísun" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr "" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:391 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "Hálfkláruð tákntilvísun" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:416 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Tákntengi eru ekki studd" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:439 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "Hálfkláruð tákntilvísun" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: ../glib/gregex.c:514 +#, fuzzy +msgid "\\N is not supported in a class" +msgstr "Tákntengi eru ekki studd" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "" + +#: ../glib/gregex.c:1383 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Villa á línu %d tákn %d: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2412 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "Hálfkláruð viðfangatilvísun" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Tilvísunin byrjar ekki á spurningarmerki" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Tilvísunarmerki stemma ekki í skipanalínunni eða öðrum texta" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Textinn endaði eftir '\\' tákn. (Textinn var '%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "Textinn endaði áður en samstaða við %c fannst. (Textinn var '%s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "Textinn var tómur (eða innihélt eingöngu orðabil)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Gat ekki lesið gögn frá undirferli (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Óvæn villa í select() við lestur gagna frá undirferli (%s)" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Óvæn villa í waitpid() (%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Gat ekki lesið úr undirferlispípu (%s)" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Gat ekki ræst (%s)" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Gat ekki farið í möppuna '%s' (%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Gat ekki ræst undirferli \"%s\" (%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Gat ekki sent frálag eða ílag underferlis annað (%s)" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Gat ekki ræst undirferli (%s)" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Óþekkt villa við keyrslu undirferlis \"%s\"" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Gat ekki lesið nægjanleg gögn úr pípunni til undirferlisins (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "Gat ekki lesið gögn frá undirferli" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Gat ekki búið til pípu til samskipta við undirferli (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Gat ekki keyrt undirferli (%s)" + +#: ../glib/gspawn-win32.c:445 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "Ógilt vélarheiti" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ógildur strengur í frumgildi vektors í %d: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, fuzzy, c-format +msgid "Invalid string in environment: %s" +msgstr "Ógild runa í ílagi umbreytingar" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, fuzzy, c-format +msgid "Invalid working directory: %s" +msgstr "Villa við að opna möppuna '%s': %s" + +#: ../glib/gspawn-win32.c:783 +#, fuzzy, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Gat ekki keyrt hjálparforrit" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "Óvænt villa í g_io_channel_win32_poll() við lestur úr undirferli" + +#: ../glib/gutf8.c:780 +msgid "Failed to allocate memory" +msgstr "Mistókst að úthluta minni" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "Táknið er utan UTF-8 sviðsins" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "Ógild runa í ílagi umbreytingar" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "Táknið er utan UTF-16 sviðsins" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bæti" +msgstr[1] "%u bæti" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bæti" +msgstr[1] "%s bæti" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "janúar" + +msgctxt "full month name with day" +msgid "February" +msgstr "febrúar" + +msgctxt "full month name with day" +msgid "March" +msgstr "mars" + +msgctxt "full month name with day" +msgid "April" +msgstr "apríl" + +msgctxt "full month name with day" +msgid "May" +msgstr "maí" + +msgctxt "full month name with day" +msgid "June" +msgstr "júní" + +msgctxt "full month name with day" +msgid "July" +msgstr "júlí" + +msgctxt "full month name with day" +msgid "August" +msgstr "ágúst" + +msgctxt "full month name with day" +msgid "September" +msgstr "september" + +msgctxt "full month name with day" +msgid "October" +msgstr "október" + +msgctxt "full month name with day" +msgid "November" +msgstr "nóvember" + +msgctxt "full month name with day" +msgid "December" +msgstr "desember" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "maí" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jún" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "júl" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ágú" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sep" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nóv" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "des" + +#, fuzzy +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#, fuzzy +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#, fuzzy +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#, fuzzy +#~ msgid "Error statting directory '%s': %s" +#~ msgstr "Villa við að opna möppuna '%s': %s" + +#, fuzzy +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Villa við lestur skráarinnar '%s': %s" + +#, fuzzy +#~ msgid "Error connecting: " +#~ msgstr "Villa við lestur skráarinnar '%s': %s" + +#, fuzzy +#~ msgid "Error connecting: %s" +#~ msgstr "Villa við lestur skráarinnar '%s': %s" + +#, fuzzy +#~ msgid "Error reading from unix: %s" +#~ msgstr "Villa við lestur skráarinnar '%s': %s" + +#, fuzzy +#~ msgid "Error closing unix: %s" +#~ msgstr "Villa á línu %d: %s" + +#, fuzzy +#~ msgid "Error writing to unix: %s" +#~ msgstr "Villa við umbreytingu: %s" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Ógild runa í ílagi umbreytingar" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Táknið '%s' er ógilt í upphafi heiti viðfanga; & táknið byrjar viðfang; " +#~ "ef Þetta og-merki á ekki að vera byrjun viðfangs ættir þú að rita það sem " +#~ "&" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Tóm tákntilvísun; hún ætti að innihalda tölur eins og dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Hálfkláruð viðfangatilvísun" + +#~ msgid "Unfinished character reference" +#~ msgstr "Hálfkláruð tákntilvísun" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Ógildur UTF-8 þýddur texti" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Ógildur UTF-8 þýddur texti" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Vélarheitið í URI '%s' er ógilt" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Villa við lestur skráarinnar '%s': %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Villa við umbreytingu: %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Gat ekki opnað skrána '%s': fdopen() brást: %s" diff --git a/po/it.po b/po/it.po new file mode 100644 index 0000000..ec582fc --- /dev/null +++ b/po/it.po @@ -0,0 +1,6486 @@ +# Italian translation for glib. +# This file is distributed under the same license as glib package +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc. +# Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc. +# Christopher R. Gabriel 2002. +# +# Nota sull'uso delle virgolette: +# "" --> usate nei messaggi di errore che appaiono solo su terminale +# «» --> usate nei messaggi di errore che appaiono nei dialoghi +# +# Stream rimane stream (consultare le API reference di GIO) +# Seek è tradotto posizionare +# Polling - proviamo con controllo sistematico (MS lo lascia non tradotto) +# Luca Ferretti , 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. +# Milo Casagrande , 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 15:19+0000\n" +"PO-Revision-Date: 2022-03-22 17:13+0100\n" +"Last-Translator: Milo Casagrande \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Poedit 3.0.1\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "L'impostazione di applicazioni predefinite non è ancora supportata" + +# %s è l'attributo +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"L'impostazione dell'applicazione come ultima utilizzata per tipo non è " +"ancora supportata" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opzioni GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Mostra opzioni GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Avvia modalità di servizio GApplication (da file di servizio D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Soprascrive l'ID dell'applicazione" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Sostituisce l'istanza in esecuzione" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Stampa l'aiuto" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMANDO]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Stampa la versione" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Stampa informazioni di versione ed esce" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Elenca le applicazioni" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Elenca le applicazioni installate attivabili da D-Bus (per file .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Lancia un'applicazione" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Lancia l'applicazione (con gli opzionali file da aprire)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "IDAPP [FILE…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Attiva un'azione" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invoca un'azione sull'applicazione" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "IDAPP AZIONE [PARAMETRO]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Elenca le azioni disponibili" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Elenca le azioni statiche di un'applicazione (dal file .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "IDAPP" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMANDO" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Il comando di cui stampare istruzioni dettagliate" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Identificatore dell'applicazione in formato D-Bus (org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FILE" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Nomi di file relativi o assoluti oppure URI da aprire" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "AZIONE" + +# predicato > sostantivo per introspezione, direi che funziona +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Il nome dell'azione da invocare" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETERO" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Parametro opzioni per l'azione da invocare, in formato GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Comando «%s» sconosciuto\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Uso:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argomenti:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARG…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Comandi:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Per maggiori informazioni, usare «%s help COMANDO».\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"il comando %s richiede l'id di un'applicazione\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "id dell'applicazione non valido: «%s»\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"«%s» non accetta alcun argomento\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "impossibile connettersi a D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "errore nell'inviare il messaggio %s all'applicazione: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "" +"è necessario fornire il nome di un'azione dopo l'id dell'applicazione\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nome dell'azione non valido: «%s»\n" +"i nomi delle azioni devo essere composti da lettere, cifre, «-» e «.»\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "errore nell'analizzare il parametro dell'azione: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "le azioni accettano al massimo un parametro\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "il comando list-action accetta solo l'id dell'applicazione" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "impossibile trovare il file desktop per l'applicazione %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"comando sconosciuto: %s\n" +"\n" + +# count (gssize) è un parametro delle funzione +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Valore count troppo grande passato a %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Posizionamento non supportato sullo stream di base" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Impossibile troncare GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Lo stream è già chiuso" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Troncamento non supportato sullo stream di base" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "L'operazione è stata annullata" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Oggetto non valido, non inizializzato" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Sequenza multi-byte non valida in ingresso" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Spazio non sufficiente nella destinazione" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Sequenza di byte non valida nell'ingresso per la conversione" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Errore durante la conversione: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Inizializzazione annullabile non supportata" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "La conversione del set di caratteri da «%s» a «%s» non è supportata" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Impossibile aprire il convertitore da «%s» a «%s»" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "Tipo %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Tipo sconosciuto" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "Tipo di file %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials contiene data non validi" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials non è implementato su questo SO" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Non c'è alcun supporto a GCredentials per la piattaforma in uso" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials non contiene un ID di processo su questo SO" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" +"La falsificazione delle identità non è consentita su questo sistema operativo" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "End-of-stream prematuro inatteso" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "La chiave «%s» non è valida nella voce indirizzo «%s»" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" +"Combinazione coppia chiave/valore senza significato nella voce indirizzo «%s»" + +# Come chiarito in un messaggio seguente, path, tmpdir e abstract sono nomi chi chiavi (NdT) +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"L'indirizzo «%s» non è valido (necessario esattamente una tra le chiavi " +"path, tmpdir o abstract)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Errore nell'indirizzo «%s» — l'attributo «%s» non è valido" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Trasporto «%s» sconosciuto o non supportato per l'indirizzo «%s»" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "L'elemento indirizzo «%s» non contiene due punti (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" +"Il nome del trasporto nell'elemento indirizzo «%s» non deve essere vuoto" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"La coppia chiave/valore %d, «%s», nell'elemento indirizzo «%s», non contiene " +"un segno di uguale" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"La coppia chiave/valore %d, «%s», nell'elemento indirizzo «%s», non deve " +"avere una chiave vuota" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Errore nell'eseguire l'unescaping sulla chiave o sul valore nella coppia " +"chiave/valore %d, «%s», nell'elemento di indirizzo «%s»" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Errore nell'indirizzo «%s» — il trasporto unix richiede espressamente " +"l'impostazione di una tra le chiavi «path» o «abstract»" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Errore nell'indirizzo «%s» — manca l'attributo «host» oppure non è valido" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Errore nell'indirizzo «%s» — manca l'attributo «port» oppure non è valido" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Errore nell'indirizzo «%s» — manca l'attributo «noncefile» oppure non è " +"valido" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Errore nell'avvio automatico: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Errore nell'aprire il file nonce «%s»: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Errore nel leggere dal file nonce «%s»: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Errore nel leggere dal file nonce «%s»: attesi 16 byte, ottenuti %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Errore nello scrivere i contenuti del file nonce «%s» sullo stream:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "L'indirizzo fornito è vuoto" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Impossibile eseguire lo spawn di un bus di messaggi quando AT_SECURE è " +"impostato" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Impossibile eseguire lo spawn di un bus di messaggi senza un machine-id: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Impossibile lanciare automaticamente D-Bus senza $DISPLAY X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Errore nell'eseguire lo spawn della riga di comando «%s»: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Impossibile determinare l'indirizzo del bus di sessione (non implementato " +"per questo S.O.)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Impossibile determinare l'indirizzo del bus dalla variabile d'ambiente " +"DBUS_STARTER_BUS_TYPE — valore «%s» sconosciuto" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Impossibile determinare l'indirizzo del bus poiché la variabile d'ambiente " +"DBUS_STARTER_BUS_TYPE non è impostata" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipo di bus %d sconosciuto" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Assenza di contenuto inattesa nel tentativo di leggere una riga" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Assenza di contenuto inattesa nel tentativo di leggere (in modo sicuro) una " +"riga" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Esauriti tutti i meccanismi di autenticazione disponibili (provati: %s) " +"(disponibili: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Gli ID utente devono essere gli stessi per nodo e server" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Annullato attraverso GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Errore nell'ottenere informazioni per la directory «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"I permessi sulla directory «%s» non sono validi: attesa la modalità 0700, " +"ottenuta 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Errore nel creare la directory «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operazione non supportata" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Errore nell'aprire il portachiavi «%s» in lettura: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "La riga %d del portachiavi su «%s» con contenuto «%s» non è corretta" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Il primo token della riga %d del portachiavi su «%s» con contenuto «%s» non " +"è corretto" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Il secondo token della riga %d del portachiavi su «%s» con contenuto «%s» " +"non è corretto" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Non è stato trovato il cookie con ID %d nel portachiavi su «%s»" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Errore nel creare il file di blocco «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Errore nell'eliminare il vecchio file di blocco «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Errore nel chiudere il file di blocco «%s» (unlinked): %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Errore nell'eseguire l'unlink del file di blocco «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Errore nell'aprire il portachiavi «%s» in scrittura: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(inoltre non è riuscito il rilascio del blocco per «%s»: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "La connessione è chiusa" + +# Sarebbe anche "il tempo è scaduto", ma non so +# se la forma in cui l'hanno messo ha un particolare +# senso, per cui la mantengo assieme a timeout +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "È stato raggiunto il timeout" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Incontrate flag non supportate durante la costruzione di una connessione " +"client-side" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Interfaccia «org.freedesktop.DBus.Properties» inesistente sull'oggetto nel " +"percorso %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Proprietà «%s» inesistente" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "La proprietà «%s» non è leggibile" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "La proprietà «%s» non è scrivibile" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Errore nell'impostare la proprietà «%s»: atteso il tipo «%s», ottenuto «%s»" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Interfaccia «%s» inesistente" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Interfaccia «%s» inesistente sull'oggetto nel percorso %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Metodo «%s» inesistente" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Il tipo di messaggio «%s» non corrisponde al tipo atteso «%s»" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Risulta già esportato un oggetto per l'interfaccia %s su %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Impossibile recuperare la proprietà %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Impossibile impostare la proprietà %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Il metodo «%s» ha restituito il tipo «%s», ma era atteso «%s»" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Il metodo «%s» sull'interfaccia «%s» con firma «%s» non esiste" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Un sottoalbero per %s è già esportato" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "L'oggetto non esiste nel percorso «%s»" + +# suppongo INVALID sia parola chiave +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "il tipo è INVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "messaggio METHOD_CALL: manca il campo header PATH o MEMBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "messaggio METHOD_RETURN: manca il campo header REPLY_SERIAL" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "messaggio ERROR: manca il campo header REPLY_SERIAL o ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "messaggio SIGNAL: manca il campo header PATH, INTERFACE o MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"messaggio SIGNAL: il campo header PATH sta usando il valore riservato /org/" +"freedestkop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"messaggio SIGNAL: il campo header INTERFACE sta usando il valore riservato " +"org.freedestkop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Si voleva leggere %lu byte, ma ne sono stati ottenuti %lu" +msgstr[1] "Si volevano leggere %lu byte, ma ne sono stati ottenuti %lu" + +# FIXME? plurale? +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Atteso byte NUL dopo la stringa «%s», ma trovato %d byte" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Attesa stringa UTF-8 valida, ma trovati byte non validi a %d byte di offset " +"(la lunghezza della stringa è %d). La stringa UTF-8 valida fino a quel punto " +"era «%s»" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Valori troppo annidati" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Il valore «%s» analizzato non è un percorso oggetto D-Bus valido" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Il valore «%s» analizzato non è una firma D-Bus valida" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Incontrato un array lungo %u byte. La lunghezza massima è 2<<26 byte (64 " +"MiB)." +msgstr[1] "" +"Incontrato un array lungo %u byte. La lunghezza massima è 2<<26 byte (64 " +"MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Incontrato un array di tipo «a%c» la cui lunghezza attesa era di %u byte, ma " +"la lunghezza reale era di %u byte" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Le strutture vuote (tuple) non sono ammesse in D-Bus" + +# VARIANT è uno dei container type di D-Bus +# anche signature sono cose specifiche del protocollo +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Il valore «%s» analizzato per il variant non è una firma D-Bus valida" + +# eeeehh????? +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Errore nel deserializzare il GVariant con la stringa di tipo «%s» dal " +"formato wire D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valore endianness non valido. Atteso 0x6c («l») o 0x42 («B»), trovato invece " +"il valore 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Versione major del protocollo non valida. Atteso 1, ma trovato %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Trovato header firma, ma non è di tipo firma" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "Trovato header firma con firma «%s», ma il corpo del messaggio è vuoto" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Il valore «%s» analizzato non è una firma D-Bus valida (per il corpo)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Nessun signature header nel messaggio, ma il corpo del messaggio è di %u byte" +msgstr[1] "" +"Nessun signature header nel messaggio, ma il corpo del messaggio è di %u byte" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Impossibile deserializzare il messaggio: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Errore nel serializzare il GVariant con la stringa di tipo «%s» al formato " +"wire D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Il numero di descrittori file nel messaggio (%d) è diverso da quello del " +"campo header (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Impossibile serializzare il messaggio: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Il corpo del messaggio presenta la firma «%s», ma non c'è alcun header firma" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Il corpo del messaggio presenta la firma «%s», ma la firma nel campo header " +"è «%s»" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Il corpo del messaggio è vuoto, ma la firma nel campo header è «(%s)»" + +# non mi convincono "di ritorno" e "corpo" +# ma altrove corpo non ci stava male +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Errore di ritorno con corpo di tipo «%s»" + +# come sopra +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Errore di ritorno con corpo vuoto" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(digitare un carattere qualsiasi per chiudere questa finestra)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "dbus di sessione non in esecuzione e autolaunch non riuscito" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Impossibile ottenere profilo hardware: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "impossibile caricare %s o %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Errore nel chiamare StartServiceByName per %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Risposta %d inattesa dal metodo StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Impossibile invocare il metodo; il proxy è per un nome well-known %s senza " +"un proprietario e il proxy è stato costruito con il flag " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Spazio nome astratto non supportato" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Impossibile specificare il file nonce quando si crea un server" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Errore nello scrivere il file nonce su «%s»: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "La stringa «%s» non è un GUID D-Bus valido" + +# anche transport sono cose specifiche di D-Bus +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Impossibile ascoltare sul transport «%s» non supportato" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Comandi:\n" +" help Mostra queste informazioni\n" +" introspect Introspezione di un oggetto remoto\n" +" monitor Monitoraggio di un oggetto remoto\n" +" call Invoca di un metodo su un oggetto remoto\n" +" emit Emette un segnale\n" +" wait Attende la comparsa del nome di un bus\n" +"\n" +"Usare «%s COMANDO --help» per informazioni su ciascun comando.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Errore: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Errore nell'analizzare XML introspection: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Errore: «%s» non è un nome valido\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Errore: «%s» non è un percorso di oggetto valido\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Connette al bus di sistema" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Connette al bus di sessione" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Connette all'indirizzo D-Bus fornito" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opzioni endpoint connessione:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opzioni per specificare gli endpoint di connessione" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nessun endpoint di connessione specificato" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Specificati endpoint di connessione multipli" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Attenzione: secondo dati di introspezione, l'interfaccia «%s» non esiste\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Attenzione: secondi dati di introspezione, il metodo «%s» non esiste " +"sull'interfaccia «%s»\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Destinazione opzionale per il segnale (nome univoco)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Percorso oggetto su cui emettere il segnale" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Segnale e nome dell'interfaccia" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emette un segnale." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Errore nel connettersi: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Errore: «%s» non è un nome di bus univoco valido.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Errore: non è specificato il percorso dell'oggetto\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Errore: non è specificato il nome del segnale\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Errore: il nome del segnale «%s» non è valido\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Errore: «%s» non è un nome di interfaccia valido\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Errore: «%s» non è un nome di membro valido\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Errore nell'analizzare il parametro %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Errore nell'eseguire il flush della connessione: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nome della destinazione su cui invocare il metodo" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Percorso dell'oggetto su cui invocare il metodo" + +# oppure "Nome del metodo e dell'interfaccia" ??? +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Metodo e nome dell'interfaccia" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Timeout in secondi" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Consenti autorizzazione interattiva" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Invoca un metodo su un oggetto remoto." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Errore: non è specificata la destinazione\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Errore: «%s» non è un nome di bus valido\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Errore: non è specificato il nome del metodo\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Errore: il nome di metodo «%s» non è valido\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Errore nell'analizzare il parametro %d di tipo «%s»: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Errore nell'aggiungere l'handle %d: %s\n" + +# predicato > sostantivo per introspezione, direi che funziona +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nome destinazione per l'introspezione" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Percorso oggetto per l'introspezione" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Stampa XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Figli introspezione" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Stampa solo le proprietà" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Esegue l'introspezione su un oggetto remoto." + +# predicato > sostantivo per monitor, direi che funziona +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nome destinazione per il monitoraggio" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Percorso oggetto per il monitoraggio" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Esegue il monitoraggio su un oggetto remoto." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Errore: impossibile monitorare una connessione non-message-bus\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Servizio da attivare prima di attendere l'altro (nome well-known)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Tempo da attendere prima di terminare con un errore (secondi); 0 per nessun " +"tempo di attesa (predefinito)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPZIONE…] NOME-BUS" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Attende la comparsa del nome di un bus" + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Errore: è necessario specificare un servizio da attivare.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "" +"Errore: è necessario specificare un servizio da attendere.\n" +"\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Errore: troppi argomenti\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Errore: %s non è un nome di bus well-known.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Non autorizzato a modificare le impostazioni di debug" + +# NdT: nome di applicazione (quando manca) +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Senza nome" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Il file .desktop non specifica il campo Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Impossibile trovare il terminale richiesto per l'applicazione" + +# NdT il primo %s è il percorso alla cartella .local/share/application +# messo tra parentesi per scelta stilistica... +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Impossibile creare la cartella utente di configurazione applicazioni (%s): %s" + +# NdT il primo %s è il percorso alla cartella .local/share/application +# messo tra parentesi per scelta stilistica... +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Impossibile creare la cartella utente di configurazione MIME (%s): %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Manca un identificatore nelle informazioni dell'applicazione" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Impossibile creare il file .desktop utente %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Definizione personalizzata per %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "l'unità non implementa l'azione eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "l'unità non implementa l'azione eject o eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "l'unità non implementa il controllo sistematico dei supporti" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "l'unità non implementa l'azione start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "l'unità non implementa l'azione stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "il backend TLS non implementa il recupero del binding TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Non è disponibile il supporto a TLS" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Non è disponibile il supporto a DTLS" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Impossibile gestire la versione %d della codifica GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Numero di token non valido (%d) nella codifica GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Impossibile gestire la versione %d della codifica GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Numero di token non valido (%d) nella codifica GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Atteso un GEmblem per GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "L'oggetto mount contenuto non esiste" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Impossibile copiare sopra la directory" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Impossibile copiare la directory sopra la directory" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Il file destinazione esiste" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Impossibile copiare la directory ricorsivamente" + +# see man splice(2) :) +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Splice non supportato" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Errore nell'eseguire lo splice del file: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Copia (reflink/clone) tra oggetti mount non supportata" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Copia (reflink/clone) non supportata o non valida" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Copia (reflink/clone) non supportata o non ha funzionato" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Impossibile copiare il file speciale" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Fornito valore di collegamento simbolico non valido" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Collegamenti simbolici non supportati" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Cestino non supportato" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "I nomi di file non possono contenere «%c»" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "il volume non implementa l'azione mount" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Non risulta registrata alcuna applicazione per gestire questo file" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "L'enumeratore è chiuso" + +# una sola ???? +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "L'enumeratore di file presenta un'operazione in sospeso" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "L'enumeratore di file è già chiuso" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Impossibile gestire la versione %d della codifica GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Dati di input malformati per GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Lo stream non supporta query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Posizionamento non supportato sullo stream" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Troncamento non consentito sullo stream di input" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Troncamento non supportato sullo stream" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Nome host non valido" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Risposta proxy HTTP errata" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Connessione proxy HTTP non consentita" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Autenticazione proxy HTTP non riuscita" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Richiesta autenticazione proxy HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Connessione proxy HTTP non riuscita: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Risposta proxy HTTP troppo grande" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Il server proxy HTTP ha chiuso la connessione in modo inatteso." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Numero di token errato (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Nessun tipo per il nome di classe %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Il tipo %s non implementa l'interfaccia GIcon" + +# o non è classificato ?? ma credo classificato abbia una diversa valenza... +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Il tipo %s non presenta una classe" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Numero di versione malformato: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Il tipo %s non implementa from_tokens() sull'interfaccia GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Impossibile gestire la versione fornita della codifica di icona" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nessun indirizzo specificato" + +# eh... miglorabile? +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "La lunghezza %u è troppo lunga per l'indirizzo" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "L'indirizzo presenta bit impostati oltre la lunghezza del prefisso" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Impossibile analizzare «%s» come maschera di indirizzo IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Spazio non sufficiente per l'indirizzo del socket" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Indirizzo del socket non supportato" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Lo stream di input non implementa la lettura" + +# solo una?? +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Lo stream presenta un'operazione in sospeso" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copia con il file" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Tieni assieme al file quando spostato" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "«version» non accetta alcun argomento" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Uso:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Stampa informazioni di versione ed esce" + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Comandi:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatena i file sullo standard output" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copia uno o più file" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Mostra informazioni riguardo alle posizioni" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Avvia un'applicazione da un file desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Elenca il contenuto delle posizioni" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Ottiene o imposta il gestore per un tipo mime" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Crea directory" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitora le modifiche a file e directory" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Monta o smonta le posizioni" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Sposta uno o più file" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Apre i file con l'applicazione predefinita" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Rinomina un file" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Elimina uno o più file" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Legge dallo standard input e salva" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Imposta l'attributo di un file" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Sposta file o directory nel cestino" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Elenca il contenuto delle posizioni in un formato ad albero" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" +"Usare %s per maggiori informazioni d'aiuto.\n" +"\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Errore nello scrivere sullo stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "POSIZIONE" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatena i file e stampa sullo standard output" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat funziona esattamente come lo strumento cat, ma utilizzando\n" +"posizioni GIO al posto di file locali. È possibile, per esempio, usare\n" +"smb://server/risorsa/file.txt come posizione." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nessuna posizione fornita" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nessuna directory destinazione" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Mostra avanzamento" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Chiede prima di sovrascrivere" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Preserva tutti gli attributi" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Backup dei file destinazione esistenti" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Non segue mai i collegamenti simbolici" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Usa permessi predefiniti per la destinazione" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Trasferiti %s di %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SORGENTE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINAZIONE" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copia uno o più file da SORGENTE a DESTINAZIONE" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy funziona esattamente come lo strumento cp, ma utilizzando\n" +"posizioni GIO al posto di file locali. È possibile, per esempio, usare\n" +"smb://server/risorsa/file.txt come posizione." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "La destinazione %s non è una directory" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: sovrascrivere «%s»? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Elenca gli attributi scrivibili" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Ottiene informazioni sul file system" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Gli attributi da ottenere" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTI" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Non segue i collegamenti simbolici" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "attributi:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nome visibile: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "nome modificabile: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nome: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipo: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "dimensione: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "nascosto\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "percorso locale: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "mount unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Attributi impostabili:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Namespace attributi scrivibili:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Mostra informazioni riguardo alle posizioni" + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info funziona esattamente come lo strumento ls, ma utilizzando\n" +"posizioni GIO al posto di file locali. È possibile, per esempio, usare\n" +"smb://server/risorsa/file.txt come posizione. Gli attributi dei file\n" +"possono essere specificati attraverso il loro nome GIO (standard::icon),\n" +"utilizzando il namespace (unix) o con «*» che corrisponde a tutti gli\n" +"attributi" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "FILE-DESKTOP [ARG-FILE …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Avvia un'applicazione da un file desktop, passando argomenti facoltativi " +"relativi ai nomi di file" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nessun file desktop specificato" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Il comando di avvio non è attualmente supportato su questa piattaforma" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "impossibile caricare «%s»: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Impossibile caricare le informazioni sull'applicazione per «%s»" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Impossibile avviare l'applicazione «%s»: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Mostra file nascosti" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Usa un formato di elenco prolisso" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Stampa i nomi" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Stampa URI completi" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Elenca il contenuto delle posizioni" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list funziona esattamente come lo strumento ls, ma utilizzando\n" +"posizioni GIO al posto di file locali. È possibile, per esempio, usare\n" +"smb://server/risorsa/file.txt come posizione. Gli attributi dei file\n" +"possono essere specificati attraverso il loro nome GIO (standard:icon)." + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TIPOMIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "GESTORE" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Ottiene o imposta il gestore per un tipo mime" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Se non viene fornito alcun gestore, elenca quelli registrati e le\n" +"applicazioni consigliato per il tipo mime. Se viene fornito un\n" +"gestore, questo è impostato come gestore predefinito per quel\n" +"tipo mime." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Necessario specificare un solo tipo mime e possibilmente un gestore" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Nessuna applicazione predefinita per «%s»\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Applicazione predefinita per «%s»: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Applicazioni registrate:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nessuna applicazione registrata\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Applicazioni consigliate:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Nessuna applicazione consigliata\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Caricamento delle informazioni per il gestore «%s» non riuscito" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"Impostazione di «%s» come gestore predefinito per «%s» non riuscita: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Crea le directory genitore" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Crea directory" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir funziona esattamente come lo strumento mkdir, ma utilizzando\n" +"posizioni GIO al posto di file locali. È possibile, per esempio, usare\n" +"smb://server/risorsa/directory come posizione." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitora una directory (predefinito: dipende dal tipo)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitora un file (predefinito: dipende dal tipo)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Monitora un file direttamente (rileva modifiche fatte con collegamenti " +"permanenti)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitora un file direttamente, ma non riporta le modifiche" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Segnala spostamenti e azioni di rinomina come eventi di rimozione/creazione" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Resta in ascolto di eventi mount" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitora le modifiche a file e directory" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Monta come oggetto montabile" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Monta il volume con file device o con altro identificatore" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Smonta" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Espelli" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Ferma l'unità con file device" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DEVICE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Smonta tutti i mount con lo schema fornito" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignora le rimanenti operazioni sui file quando smonta o espelle" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Usa un utente anonimo durante l'autenticazione" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Elenca" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitoraggio degli eventi" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Mostra informazioni aggiuntive" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Il PIM numerico quando viene sbloccato un volume VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Monta un volume nascosto TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Monta un volume TCRYPT di sistema" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Accesso anonimo non consentito" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Nessuna unità per il file device" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Nessun volume per l'ID fornito" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Monta o smonta le posizioni" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Non usa i ripieghi di copia ed elimina" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Sposta uno o più file da SORGENTE a DESTINAZIONE" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move funziona esattamente come lo strumento mv, ma utilizzando\n" +"posizioni GIO al posto di file locali. È possibile, per esempio, usare\n" +"smb://server/risorsa/file.txt come posizione." + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "La destinazione %s non è una directory" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Apre i file con l'applicazione predefinita\n" +"registrata per gestire questo tipo di file." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignora i file non esistenti, senza chiedere" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Elimina i file dati" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Rinomina un file" + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Argomento mancante" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Troppi argomenti" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Cambio di nome riuscito. Nuovo URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Crea solo se non esistente" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Accoda alla fine del file" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Quando si crea un file, limita l'accesso al solo utente corrente" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" +"Quando si sostituisce, sostituisce come se la destinazione non esistesse" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Al termine stampa il nuovo etag" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "L'etag del file che sta per essere sovrascritto" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Errore nel leggere dallo stdin" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag non disponibile\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Legge dallo standard input e salva su DESTINAZIONE" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nessuna destinazione fornita" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Tipologia dell'attributo" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPO" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATTRIBUTO" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALORE" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Imposta l'attributo di un file di POSIZIONE" + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Posizione non specificata" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Attributo non specificato" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Valore non specificato" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Tipo di attributo «%s» non valido" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Svuota il cestino" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Elenca i file nel cestino con le loro posizioni originali" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Ripristinare un file dal cestino al percorso originale (eventualmente " +"ricreando la directory)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Impossibile trovare il percorso originale" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Impossibile ricreare la posizione originale: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Impossibile spostare il file nella posizione originale: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Sposta/Ripristina file o directory nel cestino" + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Nota: per l'opzione --restore, se il percorso originale del file rimosso \n" +"esiste già, non verrà sovrascritto a meno che --force non sia impostato." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Location given doesn't start with trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Segue i collegamenti simbolici, i mount e le scorciatoie" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Elenca il contenuto delle directory in un formato ad albero" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elemento <%s> non ammesso dentro <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elemento <%s> non ammesso come primo livello" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Il file %s appare diverse volte nella risorsa" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Localizzazione di «%s» non riuscita in alcuna directory sorgente" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Localizzazione di «%s» non riuscita nella directory corrente" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Opzione di elaborazione «%s» sconosciuta" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Richiesta pre-elaborazione di %s, ma %s non è impostata e %s non si trova " +"nel PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Errore nel leggere il file %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Errore nel comprimere il file %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "il testo non può apparire all'interno di <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Mostra la versione del programma ed esce" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nome del file di output" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Le directory da cui caricare i file indicati in FILE (predefinito: directory " +"corrente)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Genera l'output nel formato selezionato in base all'estensione del nome di " +"file della destinazione" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Genera header sorgente" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Genera codice sorgente usato per collegare il file risorsa all'interno del " +"codice" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Genera elenco delle dipendenze" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nome del file dipendenza da generare" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Include le destinazioni phony nel file delle dipendenze" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Non crea e registra automaticamente la risorsa" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Non esporta le funzioni, le dichiara G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Non incorpora i dati delle risorse nel file C, assume sia collegato " +"esternamente" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Nome identificatore C usato per il codice sorgente generato" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "" +"Il compilatore C da usare (impostazione predefinita: la variabile di " +"ambiente CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compila una specifica di risorsa in un file risorsa.\n" +"I file di specifica di risorsa hanno estensione .gresource.xml\n" +"e i file risorsa hanno estensione .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "È necessario indicare esattamente un nome di file\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "nick deve essere lungo almeno 2 caratteri" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Valore numerico non valido" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " già specificato" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' già specificato" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "valori flag devono avere almeno 1 bit impostato" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> deve contenere almeno un " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> non è contenuto nell'intervallo specificato" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> non è un membro valido del tipo enumerazione specificato" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> contiene una stringa non presente nei tipi di flag specificati" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> contiene una stringa non in " + +# maschile, inteso come elemento +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " già specificato per questa chiave" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " non consentito per chiavi di tipo «%s»" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "il valore minimo specificato da è maggiore del valore massimo" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categoria l10n non supportata: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "richiesto l10n, ma dominio gettext non fornito" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" +"fornito un contesto di traduzione per il valore, ma l10n non è abilitato" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Analisi del valore di tipo «%s» non riuscita: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" non può essere specificato per chiavi marcate come tipo " +"enumerazione" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " già specificato per questa chiave" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " non consentito per chiavi di tipo «%s»" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " già fornito" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " deve contenere almeno una " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " già specificato per questa chiave" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" può essere specificato solo per chiavi di tipo enumerazione o flag " +"oppure dopo un " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" fornito quando «%s» è già un membro del tipo enumerazione" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " fornito quando è già presente" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " già specificato" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "obiettivo alias «%s» non è in un tipo enumerazione" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "obiettivo alias «%s» non presente in " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " deve contenere almeno un " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Non sono permessi nomi vuoti" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" +"Nome «%s» non valido: i nomi devono cominciare con una lettera minuscola" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nome «%s» non valido: carattere «%c» non valido; sono permessi sono lettere " +"minuscole, numeri e trattino («-»)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Nome «%s» non valido: non sono permessi due trattini consecutivi («--»)" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" +"Nome «%s» non valido: l'ultimo carattere non può essere un trattino («-»)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nome «%s» non valido: la lunghezza massima è 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " già specificato" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Impossibile aggiungere chiavi a uno schema «list-of»" + +# maschile, inteso come elemento +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " già specificato" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" esegue lo shadow di in ; " +"usare per modificare il valore" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"È necessario specificare come un attributo per solo uno tra «type», " +"«enum» o «flags»" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> non (ancora) definito." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Stringa tipo GVariant «%s» non valida" + +# direi che la doppia negazione qui possiamo lasciarla +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " indicato, ma lo schema non sta estendendo nulla" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Nessun da scavalcare" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " già specificato" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " già specificato" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " estende lo schema «%s» non ancora esistente" + +# o esistenti?? +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " è un elenco di schema «%s» non ancora esistente" + +# diciamocelo, gira roba forte... +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Non può essere un elenco di uno schema con un percorso" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Non può estendere uno schema con un percorso" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" è un elenco, che estende che non è un " +"elenco" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" estende , ma «%s» " +"non estende «%s»" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Un percorso, se fornito, deve iniziare e terminare con uno slash" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Il percorso di una list deve terminare con «:/»" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Attenzione: lo schema «%s» ha un percorso «%s»; i percorsi che iniziano con " +"«/apps/», «/desktop/» o «/system/» non sono più supportati." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> già specificato" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Solo un elemento <%s> ammesso dentro <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Elemento <%s> non ammesso come primo livello" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "L'elemento è richiesto in " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Il testo non può apparire all'interno di <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Attenzione: riferimento non definito a " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "è stato specificato --strict, uscita." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Questo intero file è stato ignorato." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignorato questo file." + +# override... +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Nessuna chiave «%s» nello schema «%s» come specificato nel file di override " +"«%s»; override ignorato per questa chiave." + +# override... +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Nessuna chiave «%s» nello schema «%s» come specificato nel file di override " +"«%s» ed è stato specificato --strict; uscita." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Impossibile fornire override per-desktop per la chiave localizzata «%s» " +"nello schema «%s» (file di override «%s»); override ignorato per questa " +"chiave." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Impossibile fornire override per-desktop per la chiave localizzata «%s» " +"nello schema «%s» (file di override «%s») ed è stato specificato --strict; " +"uscita." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Errore nell'analizzare la chiave «%s» nello schema «%s» come specificato nel " +"file di override «%s»: %s. Override ignorato per questa chiave." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Errore nell'analizzare la chiave «%s» nello schema «%s» come specificato nel " +"file di override «%s»: %s. È stato specificato --strict; uscita." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"L'override per la chiave «%s» nello schema «%s» nel file di override «%s» è " +"fuori dall'intervallo indicato nello schema; override ignorato per questa " +"chiave." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"L'override per la chiave «%s» nello schema «%s» nel file di override «%s» è " +"fuori dall'intervallo indicato nello schema ed è stato specificato --strict; " +"uscita." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"L'override per la chiave «%s» nello schema «%s» nel file di override «%s» " +"non è nell'elenco delle scelte valide; override ignorato per questa chiave." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"L'override per la chiave «%s» nello schema «%s» nel file di override «%s» " +"non è nell'elenco delle scelte valide ed è stato specificato --strict; " +"uscita." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Dove memorizzare il file gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Interrompe l'esecuzione per ogni errore negli schemas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Non scrive il file gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Non forza le limitazioni sui nomi di chiave" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compila tutti i file schema GSettings in una cache schema.\n" +"I file schema devo avere estensione .gschema.xml,\n" +"e il file cache è chiamato gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "È necessario indicare esattamente un nome di directory" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nessun file schema trovato: nessuna azione eseguita." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Nessun file schema trovato: rimosso il file di output preesistente." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Nome di file %s non valido" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Errore nell'ottenere informazioni sul file system per %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "L'oggetto mount contenuto per il file %s non esiste" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Impossibile rinominare la directory root" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Errore nel rinominare il file %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Impossibile rinominare il file, il nome di file esiste già" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nome di file non valido" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Errore nell'aprire il file %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Errore nel rimuovere il file %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Errore nel cestinare il file %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Impossibile creare la directory cestino %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Impossibile trovare la directory di livello superiore per cestinare %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"Lo spostamento nel cestino sui montaggi interni di sistema non è supportato" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Impossibile trovare o creare la directory cestino %s per rimuovere %s" + +# consultare la specifica del cestino di freedesktop.org +# (in breve per ogni file cestinato viene creata una copia +# del file e un file di informazioni - data, posizione originaria...) +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Impossibile creare il file informazioni cestinamento per %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Impossibile cestinare il file %s tra livelli di file system" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Impossibile cestinare il file %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Impossibile cestinare il file %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Errore nel creare la directory %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Il file system non supporta i collegamenti simbolici" + +# FIXME: all other occurrences are "symlink" +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Errore nel creare il collegamento simbolico %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Errore nello spostare il file %s: %s" + +# ma che senso ha??? +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Impossibile spostare la directory sopra la directory" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Creazione del file backup non riuscita" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Errore nel rimuovere il file destinazione: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Spostamento tra oggetti mount non supportato" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Impossibile determinare l'utilizzo del disco di %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Il valore dell'attributo deve essere non-NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tipo di attributo non valido (attesa stringa)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nome di attributo esteso non valido" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Errore nell'impostare l'attributo esteso «%s»: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codifica non valida)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Errore nel recuperare informazioni per il file «%s»: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Errore nel recuperare informazioni per il descrittore di file: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tipo di attributo non valido (atteso unit32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tipo di attributo non valido (atteso uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Tipo di attributo non valido (attesa stringa di byte)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Impossibile impostare i permessi sui collegamenti simbolici" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Errore nell'impostare i permessi: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Errore nell'impostare il proprietario: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "il collegamento simbolico deve essere non-NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Errore nell'impostare il collegamento simbolico: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Errore nell'impostare il collegamento simbolico: il file non è un " +"collegamento" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"%d nanosecondi aggiuntivi per la marcatura temporale UNIX %lld sono negativi" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"%d nanosecondi aggiuntivi per la marcatura temporale UNIX %lld raggiungono 1 " +"secondo" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "La marcatura temporale UNIX %lld non può essere contenuta in 64-bit" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"La marcatura temporale %lld è al di fuori dell'intervallo supportato da " +"Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Impossibile convertire il nome file «%s» a UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Impossibile aprire il file «%s»: Errore Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Errore nell'impostare l'ora di modifica o accesso del file «%s»: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Errore nell'impostare l'ora di modifica o accesso: %s" + +# lasciata minuscola come per precedente messaggio +# "symlink must be non-NULL" +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "il contesto SELinux deve essere non-NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux non è abilitato su questo sistema" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Errore nell'impostare il contesto SELinux: %s" + +# %s è l'attributo +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Impostazione dell'attributo %s non supportata" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Errore nel leggere dal file: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Errore nel chiudere il file: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Errore nel posizionarsi all'interno del file: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Impossibile trovare il tipo di monitor predefinito per file locali" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Errore nello scrivere sul file: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Errore nel rimuovere il vecchio collegamento di backup: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Errore nel creare la copia di backup: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Errore nel rinominare il file temporaneo: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Errore nel troncare il file: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Errore nell'aprire il file «%s»: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Il file destinazione è una directory" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Il file destinazione non è un file normale" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Il file è stato modificato dall'esterno" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Errore nel rimuovere il vecchio file: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Fornito GSeekType non valido" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Richiesta di posizionamento non valida" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Impossibile troncare GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Stream di output di memoria non ridimensionabile" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Ridimensionamento dello stream di output di memoria non riuscito" + +# spero sia write -> scrittura e non write -> write +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"La quantità di memoria necessaria per elaborare la scrittura è più grande " +"dello spazio di indirizzamento disponibile" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Richiesto posizionamento prima dell'inizio dello stream" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Richiesto posizionamento oltre la fine dello stream" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "l'oggetto mount non implementa l'azione «unmount»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "l'oggetto mount non implementa l'azione «eject»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"l'oggetto mount non implementa l'azione «unmount» o «unmount_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"l'oggetto mount non implementa l'azione «eject» o «eject_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "l'oggetto mount non implementa l'azione «remount»" + +# ok, lo so, un filesystem non può fare congetture.. +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "l'oggetto mount non implementa la supposizione del tipo di contenuto" + +# ok, lo so, un filesystem non può fare congetture.. +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" +"l'oggetto mount non implementa la supposizione sincrona del tipo di contenuto" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Il nome host «%s» contiene «[» ma non «]»" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Rete irraggiungibile" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Host irraggiungibile" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Impossibile creare il monitor di rete: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Impossibile creare il monitor di rete: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "impossibile ottenere lo stato della rete: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager non è in esecuzione" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Version di NetworkManager troppo datata" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Lo stream di output non implementa la scrittura" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Somma dei vettori troppo grande passata a %s" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Lo stream sorgente è già chiuso" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Errore nel risolvere «%s»: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s non è implementata" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Dominio non valido" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "La risorsa presso «%s» non esiste" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Decompressione della risorsa presso «%s» non riuscita" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "La risorsa presso «%s» non è una directory" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Lo stream di input non implementa il posizionamento" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Elenca le sezioni che contengono risorse in un FILE elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Elenca le risorse\n" +"Se è indicato SEZIONE, elenca solo le risorse in quella sezione\n" +"Se è indicato PERCORSO, elenca solo le risorse che corrispondono" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FILE [PERCORSO]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEZIONE" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Elenca le risorse con i dettagli\n" +"Se è indicato SEZIONE, elenca solo le risorse in quella sezione\n" +"Se è indicato PERCORSO, elenca solo le risorse che corrispondono\n" +"I dettagli includono la sezione, la dimensione e la compressione" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Estrare un file risorsa su stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FILE PERCORSO" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gresource [--section SEZIONE] COMANDO [ARGOMENTO...]\n" +"\n" +"Comandi:\n" +" help Mostra queste informazioni\n" +" sections Elenca le sezioni risorse\n" +" list Elenca le risorse\n" +" details Elenca le risorse coi dettagli\n" +" extract Estrae una risorsa\n" +"\n" +"Usare «gresource help COMANDO» per ottenere un aiuto dettagliato.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEZIONE Un nome sezione elf (opzionale)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" +" COMANDO Il comando (opzionale) da spiegare\n" +"\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE Un file elf (un binario o una libreria condivisa)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE Un file elf (un binario o una libreria condivisa)\n" +" o un file risorsa compilato\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[PERCORSO]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PERCORSO Un (opzionale) percorso risorsa (può essere parziale)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "PERCORSO" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " PERCORSO Un percorso risorsa\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Schema «%s» inesistente\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" +"Lo schema «%s» non è rilocabile (non deve essere specificato il percorso)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Lo schema «%s» è rilocabile (deve essere specificato il percorso)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Indicato percorso vuoto.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Il percorso deve cominciare con uno slash (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Il percorso deve terminare con uno slash (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Il percorso non deve contenere due slash adiacenti (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Il valore fornito è fuori dell'intervallo valido\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "La chiave non è scrivibile\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Elenca gli schemi (non rilocabili) installati" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Elenca gli schemi rilocabili installati" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Elenca le chiavi in SCHEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PERCORSO]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Elenca i figli di SCHEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Elenca chiavi e valori, ricorsivamente\n" +"Se non è fornito alcuno SCHEMA elenca tutte le chiavi\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PERCORSO]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Ottiene il valore di CHIAVE" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PERCORSO] CHIAVE" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Interroga l'intervallo di valori ammessi per CHIAVE" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Interroga la descrizione per CHIAVE" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Imposta il valore di CHIAVE a VALORE" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PERCORSO] CHIAVE VALORE" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Azzera CHIAVE al suo valore predefinito" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Azzera tutte le chiavi in SCHEMA ai rispettivi valori predefiniti" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Verifica se CHIAVE è scrivibile" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitorizza le modifiche a CHIAVE.\n" +"Se CHIAVE non è specificato, monitorizza tutte le chiavi in SCHEMA.\n" +"Usare ^C per fermare il monitoraggio.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PERCORSO] [CHIAVE]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings --version\n" +" gsettings [--schemadir DIR_SCHEMA] COMANDO [ARGOMENTI...]\n" +"\n" +"Comandi:\n" +" help Mostra queste informazioni\n" +" list-schemas Elenca gli schemi installati\n" +" list-relocatable-schemas Elenca gli schemi trasferibili\n" +" list-keys Elenca le chiavi in uno schema\n" +" list-children Elenca i figli di uno schema\n" +" list-recursively Elenca chiavi e valori, ricorsivamente\n" +" range Interroga l'intervallo di una chiave\n" +" describe Interroga la descrizioni di una chiave\n" +" get Ottiene il valore di una chiave\n" +" set Imposta il valore di una chiave\n" +" reset Azzera il valore di una chiave\n" +" reset-recursively Azzera tutti i valori di uno schema fornito\n" +" writable Verifica se una chiave è scrivibile\n" +" monitor Controlla le modifiche\n" +"\n" +"Usare «gsettings help COMANDO» per ottenere un aiuto dettagliato.\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings [--schemadir DIR_SCHEMA] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " DIR_SCHEMA Una directory in cui cercare schemi aggiuntivi\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA Il nome dello schema\n" +" PERCORSO Il percorso, per gli schemi rilocabili\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " CHIAVE La chiave (opzionale) all'interno dello schema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " CHIAVE La chiave all'interno dello schema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALORE Il valore da impostare\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Impossibile aprire i file schema da %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nessun file schema installato\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Fornito un nome di schema vuoto\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Chiave «%s» inesistente\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Socket non valido, non inizializzato" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Socket non valido, inizializzazione non riuscita a causa di: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Il socket è già chiuso" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "I/O sul socket scaduto" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "creazione di GSocket da FD: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Impossibile creare il socket: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "È stata specificata una famiglia sconosciuta" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "È stato specificato un protocollo sconosciuto" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Impossibile utilizzare operazioni datagram su un socket non-datagram." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Impossibile utilizzare operazioni datagram su un socket con impostato un " +"timeout." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "impossibile ottenere l'indirizzo locale: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "impossibile ottenere l'indirizzo remoto: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "impossibile restare in ascolto: %s" + +# oppure "nell'eseguire il binding" ?? +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Errore nell'eseguire il bind all'indirizzo %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Errore nel fare il join al gruppo multicast: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Errore nel lasciare il gruppo multicast: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Nessun supporto per multicast source-specific" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Famiglia socket non supportato" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "source-specific non è un indirizzo IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Nome interfaccia troppo lungo" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interfaccia non trovata: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Nessun supporto per multicast IPv4 source-specific" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Nessun supporto per multicast IPv6 source-specific" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Errore nell'accettare la connessione: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Connessione in corso" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Impossibile ottenere l'errore in sospeso: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Errore nel ricevere i dati: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Errore nell'inviare i dati: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Impossibile arrestare il socket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Errore nel chiudere il socket: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "In attesa della condizione del socket: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Impossibile inviare un messaggio: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vettori di messaggi troppo grandi" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Errore nell'inviare il messaggio: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage non supportato su Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Errore nel ricevere il messaggio: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Impossibile reggere le credenziali del socket: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials non implementata per questo SO" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Impossibile connettersi al server proxy %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Impossibile connettersi a %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Impossibile connettersi: " + +# FIXME: il tentativo o la connessione? +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "L'esecuzione del proxy su una connessione non-TCP non è supportato." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Il protocollo proxy «%s» non è supportato." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Il listener è già chiuso" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Il socket aggiunto è chiuso" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 non supporta l'indirizzo IPv6 «%s»" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Il nome utente è troppo lungo per il protocollo SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Il nome host «%s» è troppo lungo per il protocollo SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Il server non è un server proxy SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "La connessione attraverso il server SOCKSv3 è stata rifiutata" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Il server non è un server proxy SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Il proxy SOCKSv5 richiede l'autenticazione." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Il proxy SOCKSv5 richiede un metodo di autenticazione che non è supportato " +"da GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"Il nome utente o la password sono troppo lunghi per il protocollo SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"L'autenticazione SOCKSv5 non è riuscita a causa di un nome utente o password " +"errati." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Il nome host «%s» è troppo lungo per il protocollo SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Il proxy server SOCKSv5 utilizza un tipo di indirizzo sconosciuto." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Errore interno del server proxy SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "La connessione SOCKSv5 non è consentita dal ruleset." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Host irraggiungibile attraverso il server SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Rete irraggiungibile attraverso il proxy SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Connessione rifiutata attraverso il proxy SOCKSv5." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Il proxy SOCKSv5 non supporta il comando «connect»." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Il proxy SOCKSv5 non supporta il tipo di indirizzo fornito." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Errore sconosciuto del proxy SOCKSv5." + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Creazione della pipe per comunicare con il processo figlio non riuscita (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Le pipe non sono supportate su questa piattaforma" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Impossibile gestire la versione %d della codifica GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Non è stato trovato alcun indirizzo valido" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Errore nella risoluzione inversa di «%s»: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Errore nell'analizzare il record DNS %s: pacchetto DNS non valido" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Nessun record DNS del tipo richiesto per «%s»" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Momentaneamente impossibile risolvere «%s»" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Errore nel risolvere «%s»" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Pacchetto DNS non valido" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Analisi della risposta DNS per «%s» non riuscita: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Non è stato trovata alcuna chiave privata codificata con PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Impossibile decifrare la chiave privata codificata con PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Impossibile analizzare la chiave privata codificata con PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Non è stato trovato alcun certificato codificato con PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Impossibile analizzare il certificato codificato con PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "L'attuale sistema TLS non supporta PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Questo GTlsBackend non supporta la creazione di certificati PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Questa è l'ultima opportunità di inserire la password correta prima che " +"venga bloccato l'accesso." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Sono state inserite diverse password non corrette: altri errori e l'accesso " +"verrà bloccato." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "La password inserita non è corretta." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "L'invio di FD non è supportato" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Atteso 1 messaggio di controllo, ottenuto %d" +msgstr[1] "Atteso 1 messaggio di controllo, ottenuti %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Tipo di dati ausiliari inatteso" + +# tolto il "but" per omogeneità con l'altro simile +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Atteso un FD, ottenuto %d\n" +msgstr[1] "Atteso un FD, ottenuti %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Ricevuto FD non valido" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "La ricezione di FD non è supportata" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Errore nell'inviare le credenziali: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Errore nel verificare se SO_PASSCRED è abilitato per il socket: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Errore nell'abilitare SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Attesa la lettura di un singolo byte per la ricezione delle credenziali, ma " +"sono stati letti zero byte" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Messaggio di controllo inatteso, ottenuti %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Errore durante la disabilitazione di SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Errore nel leggere dal descrittore di file: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Errore nel chiudere il descrittore di file: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "File system radice" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Errore nello scrivere sul descrittore di file: %s" + +# a chi è riferito abstract?? +# a addresses o a domain? +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Indirizzi di socket di dominio UNIX astratto non supportati su questo sistema" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "il volume non implementa l'azione eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "il volume non implementa l'azione eject o eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Errore nel leggere dall'handle: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Errore nel chiudere l'handle: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Errore nello scrivere sull'handle: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Memoria non sufficiente" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Errore interno: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Necessario ulteriore input" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Dati compressi non validi" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Indirizzi su cui ascoltare" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorato, per compatibilità con GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Stampa l'indirizzo" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Stampa l'indirizzo in modalità shell" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Esegue un servizio dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Argomenti errati\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Attributo «%s» inatteso per l'elemento «%s»" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Attributo «%s» dell'elemento «%s» non trovato" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Tag «%s» inatteso, atteso il tag «%s»" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Tag «%s» inatteso all'interno di «%s»" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Data/Ora «%s» non valida nel file di segnalibro" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Non è stato trovato alcun file di segnalibri valido nelle directory dei dati" + +# usate le «» perché forse questa compare nella UI +# +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Esiste già un segnalibro per l'URI «%s»" + +# vedi sopra per «» +# +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Non è stato trovato alcun segnalibro per l'URI «%s»" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Non risulta definito alcun tipo MIME nel segnalibro per l'URI «%s»" + +# o private è il nome della flag (che quindi diventa opzione)? +# cercare nel codice... -Luca +# +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Non è stata definita alcuna flag privata nel segnalibro per l'URI «%s»" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Non risulta impostato alcun gruppo nel segnalibro per l'URI «%s»" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Nessuna applicazione di nome «%s» ha registrato un segnalibro per «%s»" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Espansione della riga exec «%s» con l'URI «%s» non riuscita" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Carattere non rappresentabile nell'ingresso per la conversione" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Sequenza di caratteri parziale al termine dei dati in ingresso" + +# il primo %s è una 'fallback string' come recita il commento nel codice +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Impossibile convertire «%s» nel set di caratteri «%s»" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Byte NUL integrato nell'ingresso per la conversione" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Byte NUL integrato nell'uscita per la conversione" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "L'URI «%s» non è un URI assoluto che utilizza lo schema «file»" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "L'URI per il file locale «%s» non può includere un «#»" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "L'URI «%s» non è valido" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Il nome dell'host nell'URI «%s» non è valido" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "L'URI «%s» contiene sequenze di escape non valide" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Il nome di percorso «%s» non è un percorso assoluto" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e %b %Y %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %P" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Gennaio" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Febbraio" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Marzo" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Aprile" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Maggio" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Giugno" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Luglio" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Agosto" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Settembre" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Ottobre" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Novembre" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Dicembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Gen" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mag" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Giu" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Lug" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ago" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Set" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Ott" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dic" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Lunedì" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Martedì" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Mercoledì" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Giovedì" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Venerdì" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sabato" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Domenica" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Lun" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Mar" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mer" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Gio" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Ven" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sab" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Dom" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "gennaio" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "febbraio" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "marzo" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "aprile" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "maggio" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "giugno" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "luglio" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "agosto" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "settembre" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "ottobre" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "novembre" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "dicembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "gen" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "mag" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "giu" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "lug" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ago" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "set" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "ott" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dic" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "am" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "pm" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Errore nell'aprire la directory «%s»: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Impossibile allocare %lu byte per leggere il file «%s»" +msgstr[1] "Impossibile allocare %lu byte per leggere il file «%s»" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Errore nel leggere il file «%s»: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Il file «%s» è troppo grande" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Lettura dal file «%s» non riuscita: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Apertura del file «%s» non riuscita: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Lettura degli attributi del file «%s» non riuscita: fstat() non riuscita: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Apertura del file «%s» non riuscita: fdopen() non riuscita: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Cambio di nome del file «%s» in «%s» non riuscito: g_rename() non riuscita: " +"%s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Scrittura del file «%s» non riuscita: write() non riuscita: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Scrittura del file «%s» non riuscita: fsync() non riuscita: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Creazione del file «%s» non riuscita: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Il file «%s» non può essere rimosso pur esistendo: g_unlink() non riuscita: " +"%s" + +# Il secondo %s è qualcosa tipo +# +# char c[2]; +# c[1] = dir_separator; +# c[2] = '\0'; +# +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Il modello «%s» non è valido, non dovrebbe contenere un «%s»" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Il modello «%s» non contiene XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Lettura del collegamento simbolico «%s» non riuscita: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Impossibile aprire il convertitore da «%s» a «%s»: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Impossibile leggere i dati grezzi in g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Sono rimasti dei dati non convertiti nel buffer di lettura" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Il canale termina in un carattere parziale" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Impossibile eseguire una lettura grezza in g_io_channel_read_to_end" + +# key files sono, per glib, file di impostazioni in stile Windows INI +# +# Ad esempio i file .themes per i temi del desktop e delle icone. +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Impossibile trovare un file chiavi valido nelle directory di ricerca" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Non è un file normale" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Il file chiavi contiene la riga «%s» che non è una coppia chiave/valore, un " +"gruppo o un commento valido" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nome gruppo non valido: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Il file chiavi non inizia con un gruppo" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nome chiave non valido: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Il file chiavi contiene la codifica non supportata «%s»" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Il file chiavi non presenta il gruppo «%s»" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Il file chiavi non presenta alcuna chiave «%s» nel gruppo «%s»" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Il file chiavi contiene la chiave «%s» con il valore «%s» che non è UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Il file chiavi contiene la chiave «%s» che presenta un valore che non può " +"essere interpretato." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Il file chiavi contiene la chiave «%s» nel gruppo «%s» che presenta un " +"valore che non può essere interpretato." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"La chiave «%s» nel gruppo «%s» presenta il valore «%s» mentre era atteso %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Il file chiavi contiene un carattere di escape alla fine della riga" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Il file chiavi contiene la sequenza di escape non valida «%s»" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Impossibile interpretare il valore «%s» come un numero." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Il valore intero «%s» è fuori dall'intervallo" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Impossibile interpretare il valore «%s» come un numero float." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Impossibile interpretare il valore «%s» come un booleano." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Recupero degli attributi del file «%s%s%s%s» non riuscito: fstat() non " +"riuscita: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Mappatura del file «%s%s%s%s» non riuscita: mmap() non riuscita: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Apertura del file «%s» non riuscita: open() non riuscita: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Errore alla riga %d carattere %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Testo in codifica UTF-8 non valido nel nome — «%s» non valido" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "«%s» non è un nome valido" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "«%s» non è un nome valido: «%c»" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Errore alla riga %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Analisi di «%-.*s» non riuscita: dovrebbe presentare un numero all'interno " +"di un riferimento a carattere (es. ê) — probabilmente il numero è " +"troppo grande" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Il riferimento a carattere non termina con un punto e virgola; probabilmente " +"si è utilizzato un carattere \"e commerciale\" senza l'intenzione di " +"iniziare una nuova entità — usare &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Il riferimento a carattere «%-.*s» non codifica un carattere permesso" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Rilevata entità vuota «&;» (entità valide: & " < > ')" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Il nome di entità «%-.*s» è sconosciuto" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"L'entità non termina con un punto e virgola; probabilmente è stata " +"utilizzata una \"e commerciale\" senza l'intento di iniziare una entità — " +"usare &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Il documento deve iniziare con un elemento (es. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"«%s» non è un carattere valido dopo un carattere «<»; non può dare inizio a " +"un nome di elemento" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Carattere «%s» spaiato, era atteso un carattere «>» per terminare il tag " +"dell'elemento-vuoto «%s»" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Troppi attributi nell'elemento «%s»" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Carattere «%s» spaiato, era atteso un carattere «=» dopo il nome " +"dell'attributo «%s» dell'elemento «%s»" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Carattere «%s» spaiato, era atteso un carattere «>» oppure «/» per terminare " +"il tag di partenza dell'elemento «%s», oppure opzionalmente un attributo. " +"Probabilmente è stato usato un carattere non valido in un nome di attributo" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Carattere «%s» spaiato, era atteso un simbolo di quoting aperto dopo il " +"segno di uguale per attribuire un valore all'attributo «%s» dell'elemento " +"«%s»" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"«%s» non è un carattere valido dopo la chiusura del nome dell'elemento «%s»; " +"il carattere permesso è «>»" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "" +"È stato chiuso l'elemento «%s», nessun elemento risulta correntemente aperto" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"È stato chiuso l'elemento «%s», ma l'elemento correntemente aperto è «%s»" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Il documento era vuoto oppure conteneva unicamente spazi" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Il documento è terminato in modo inatteso subito dopo una parentesi angolare " +"d'apertura «<»" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Il documento è terminato in modo inatteso con elementi ancora aperti — «%s» " +"era l'ultimo elemento aperto" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Il documento è terminato in modo inatteso, mancando la parentesi angolare di " +"chiusura per il tag <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "" +"Il documento è terminato in modo inatteso all'interno di un nome di elemento" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" +"Il documento è terminato in modo inatteso all'interno di un nome di attributo" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Il documento è terminato in modo inatteso all'interno di un tag di apertura " +"elemento." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Il documento è terminato in modo inatteso dopo il segno di uguale che segue " +"un nome di attributo; nessun valore per l'attributo" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"Il documento è terminato in modo inatteso all'interno di un valore di " +"attributo" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Il documento è terminato in modo inatteso all'interno del tag di chiusura " +"per l'elemento «%s»" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Il documento è terminato in modo inatteso all'interno del tag di chiusura " +"per un elemento non aperto" + +# di elaborazione? in elaborazione ? +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Il documento è terminato in modo inatteso all'interno di un commento o " +"istruzione di elaborazione" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPZIONE…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opzioni di aiuto:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Mostra le opzioni di aiuto" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Mostra tutte le opzioni di aiuto" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opzioni dell'applicazione:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opzioni:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Impossibile analizzare il valore intero «%s» per %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Il valore intero «%s» per %s è fuori dall'intervallo" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Impossibile analizzare il valore double «%s» per %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Il valore double «%s» per %s è fuori dall'intervallo" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Errore nell'analizzare l'opzione %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Argomento mancante per %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Opzione %s sconosciuta" + +# corrotto sembrava brutto, cfr revisione su TP +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "oggetto non attendibile" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "errore interno oppure oggetto non attendibile" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "memoria esaurita" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "raggiunto limite di backtracking" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"il modello contiene elementi non supportati per la corrispondenza parziale" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "errore interno" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"per la corrispondenza parziale non sono supportati i riferimenti " +"all'indietro come condizioni" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "raggiunto limite di ricorsione" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "combinazione non valida di flag di fine riga" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "offset errato" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 corto" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "ciclo ricorsivo" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "errore sconosciuto" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ alla fine del modello" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c alla fine del modello" + +# che differenza c'è tra "follows" e gli "after" qualche messaggio dopo? +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "carattere non riconosciuto dopo \\" + +# quantificatore: esiste come termine per log. mat. e gramm. +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "numeri fuori ordine nel quantificatore {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "numero troppo grande nel quantificatore {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "] terminante mancante per classe di caratteri" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "sequenza di escape non valida nella classe di caratteri" + +# to put out of order --> guastare, mettere in disordine +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "intervallo disordinato nella classe di caratteri" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nulla da ripetere" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "ripetizione inattesa" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "carattere non riconosciuto dopo (? o (?-" + +# classi nominate?? +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "" +"le classi POSIX nominate sono supportate solo all'interno di una classe" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr ") terminante mancante" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "riferimento a sotto-modello non esistente" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr ") mancante dopo il commento" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "l'espressione regolare è troppo grande" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "recupero della memoria non riuscito" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") senza ( di apertura" + +# secondo garzantilinguistica.it eccedenza (di dati) è la +# traduzione di overflow secondo IBM. La traduzione generica +# per ambito infomatico è superamento di capacità +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "eccedenza di codice" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "carattere non riconosciuto dopo (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "l'asserzione lookbehind non ha lunghezza fissata" + +# malformato si riferisce a entrambi???? +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "numero o nome malformato dopo (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "il gruppo condizionale contiene più di due diramazioni" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "asserzione attesa dopo (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R o (?[+-]cifre deve essere seguito da )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nome di classe POSIX sconosciuto" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "gli elementi di collazione POSIX non sono supportati" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "il valore del carattere nella sequenza \\x{...} è troppo grande" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condizione (?(0) non valida" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C non consentito in asserzione lookbehind" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "gli escape \\L, \\l \\N{name}, \\U, e \\u non sono supportati" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "la chiamata ricorsiva potrebbe entrare in ciclo infinito" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "carattere non riconosciuto dopo (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "terminatore mancante nel nome di sotto-modello" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "due sotto-modelli nominati presentano lo stesso nome" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "sequenza \\P o \\p malformata" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nome di proprietà sconosciuto dopo \\P o \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "il nome di sotto-modello è troppo lungo (massimo 32 caratteri)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "troppi sotto-modelli nominati (massimo 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "il valore ottale è maggiore di \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "sconfinamento compilando l'area di lavoro" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "sotto-modello referenziato precedentemente controllato non trovato" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "il gruppo DEFINE contiene più di una diramazione" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opzioni NEWLINE incoerenti" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g non è seguito da un nome o un numero tra parentesi, parentesi angolari, " +"tra virgolette o da un numero semplice" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "un riferimento numerato deve essere diverso da zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "non è consentito un argomento per (*ACCEPT), (*FAIL) o (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) non riconosciuto" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "il numero è troppo grande" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "nome di sotto-modello mancante dopo (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "attesa cifra dopo (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] è un caratteri dati non valido in modalità compatibilità JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "non sono ammessi diversi nomi per sotto-modelli dello stesso numero" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) deve avere un argomento" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c deve essere seguito da un carattere ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\g non è seguito da un nome tra parentesi, parentesi angolari o virgolette" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N non è supportato in una classe" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "troppi riferimenti anteriori" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "nome troppo lungo in (*MARK), (*PRUNE), (*SKIP) o (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "il valore del carattere nella sequenza \\u.... è troppo grande" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" +"Errore durante la ricerca di corrispondenza per l'espressione regolare %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "La libreria PCRE è compilata senza supporto per UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "La libreria PCRE è compilata senza supporto per le proprietà UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "La libreria PCRE è compilata con opzioni incompatibili" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Errore durante l'ottimizzazione dell'espressione regolare %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"Errore durante la compilazione dell'espressione regolare %s al carattere %d: " +"%s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "attesa cifra esadecimale o «}»" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "attesa cifra esadecimale" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "«<» mancante nel riferimento simbolico" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "riferimento simbolico non terminato" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "riferimento simbolico di lunghezza zero" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "attesa cifra" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "riferimento simbolico non lecito" + +# significa che il testo finisce con una barra rovesciata, è il +# carattere successivo che manca +# +# Quindi "isolato" o "staccato" o al limite "accindetale", "casuale" +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "«\\» finale isolato" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "sequenza di escape sconosciuta" + +# da sostituire crea confusione... +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Errore durante l'analisi del testo di sostituzione «%s» al carattere %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Il testo citato non inizia con un carattere di citazione" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Carattere di quoting non accoppiato nella riga di comando o nel testo con " +"quoting di shell" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Il testo è finito subito dopo un carattere «\\» (il testo era «%s»)." + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Il testo è finito prima di trovare il carattere di citazione corrispondente " +"per %c (il testo era «%s»)." + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Il testo era vuoto (oppure conteneva unicamente spazi bianchi)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Lettura dei dati dal processo figlio non riuscita (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Errore inatteso nel leggere i dati da un processo figlio (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Errore inatteso in waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Processo figlio uscito con codice %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Processo figlio ucciso dal segnale %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Processo figlio fermato dal segnale %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Il processo figlio è uscito in modo anomalo" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Lettura dalla pipe figlia non riuscita (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Esecuzione del processo figlio «%s» non riuscita (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Esecuzione di fork non riuscita (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Cambio della directory in «%s» non riuscito (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Esecuzione del processo figlio «%s» non riuscita (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Apertura del file per rimappare il descrittore file non riuscita (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "" +"Duplicazione del descrittore file per il processo figlio non riuscita (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Esecuzione del fork per processo figlio non riuscita (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Chiusura del descrittore file per il processo figlio non riuscita (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Errore sconosciuto nell'eseguire il processo figlio «%s»" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Lettura di una quantità di dati sufficiente dalla pipe del processo figlio " +"non riuscita (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Lettura di dati dal processo figlio non riuscita" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Esecuzione del processo figlio non riuscita (%s)" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Esecuzione di dup() nel processo figlio non riuscita (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nome programma non valido: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Stringa non valida nel vettore di argomenti alla posizione %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Stringa non valida nell'ambiente: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Directory di lavoro non valida: %s" + +# (%s) è in fondo perché risolto in g_strerror (gint) +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Esecuzione del programma helper non riuscita (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Errore inatteso in g_io_channel_win32_poll() nel leggere i dati da un " +"processo figlio" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "La stringa vuota non è un numero" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "«%s» non è un numero con segno" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Numero «%s» oltre i limiti [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "«%s» non è un numero senza segno" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-encoding non valido nell'URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Carattere non valido nell'URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caratteri non UTF-8 nell'URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Indirizzo IPv6 «%.*s» non valido nell'URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Codifica indirizzo IP «%.*s» non valida nell'URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nome host internazionalizzato non valido «%.*s» nell'URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Impossibile analizzare la porta «%.*s» nell'URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "La porta «%.*s» nell'URI fuori dall'intervallo" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "L'URI «%s» non è un URI assoluto" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "L'URI «%s» non ha un componente host" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "L'URI non è assoluto e non è stato fornito un URI di base" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Manca il simbolo «=» e il valore" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Allocazione della memoria non riuscita" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Carattere fuori dall'intervallo per UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Sequenza non valida in ingresso per la conversione" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Carattere fuori dall'intervallo per UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u byte" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s byte" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bit" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f kB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000..4e6b492 --- /dev/null +++ b/po/ja.po @@ -0,0 +1,6278 @@ +# Japanese translation of glib message catalog. +# Copyright (C) 2001-2013, 2020, 2022 glib's COPYRIGHT HOLDER +# Takayuki KUSANO , 2001-2002, 2009-2010. +# KAMAGASAKO Masatoshi , 2003. +# Takeshi AIHANA , 2004-2009. +# Ryoichi INAGAKI , 2004. +# OKANO Takayoshi , 2011. +# Jiro Matsuzawa , 2012-2013. +# sicklylife , 2020, 2022. +# +# 訳語: +# be malformed: 䏿­£ã§ã™ +# bus: ãƒã‚¹ +# bus address: ãƒã‚¹ã‚¢ãƒ‰ãƒ¬ã‚¹ +# object path: オブジェクトパス (D-Bus 関連) +# serialize: シリアライズ +# deserialize: デシリアライズ +# signature: ã‚·ã‚°ãƒãƒãƒ£ +# D-Bus write format: D-Bus 書ã出ã—å½¢å¼ +# type: åž‹ ã‚ã‚‹ã„㯠種類 +# abstract key: 抽象キー +# message body: メッセージボディ +# list: 一覧 +# リスト (schema 関連) +# +msgid "" +msgstr "" +"Project-Id-Version: glib glib-2-28\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-01-26 14:31+0000\n" +"PO-Revision-Date: 2022-01-30 21:00+0900\n" +"Last-Translator: sicklylife \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication ã®ã‚ªãƒ—ション" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "GApplication ã®ã‚ªãƒ—ションを表示ã™ã‚‹" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication サービスモードã«å…¥ã‚‹ (D-Bus サービスファイル使用)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "アプリケーション㮠ID をオーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã™ã‚‹" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "実行中ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’ç½®ãæ›ãˆã‚‹" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:572 +msgid "Print help" +msgstr "ヘルプを表示ã™ã‚‹" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[コマンド]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã™ã‚‹" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:578 +msgid "Print version information and exit" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦çµ‚了ã™ã‚‹" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "アプリケーション一覧を表示ã™ã‚‹" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +".desktop ファイルãŒã‚り D-Bus を利用ã™ã‚‹ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«æ¸ˆã¿ã‚¢ãƒ—リケーションã®ä¸€" +"覧を表示ã™ã‚‹" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "アプリケーションを起動ã™ã‚‹" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "アプリケーションを起動ã™ã‚‹ (é–‹ãファイルを指定)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [ファイル…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "詳細ãªãƒ˜ãƒ«ãƒ—を表示ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus å½¢å¼ã®ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³è­˜åˆ¥å­ (例: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "é–‹ã URI ã¾ãŸã¯ãƒ•ァイルã®ç›¸å¯¾/絶対パス" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "呼ã³å‡ºã™ã‚¢ã‚¯ã‚·ãƒ§ãƒ³å" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "アクションを呼ã³å‡ºã™è¿½åŠ ã®ãƒ‘ラメーター (GVariant å½¢å¼)" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:664 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"%s ã¯ä¸æ˜Žãªã‚³ãƒžãƒ³ãƒ‰ã§ã™\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "用法:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:699 +msgid "Arguments:\n" +msgstr "引数:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[引数…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "コマンド:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"“%s help COMMANDâ€ã§è©³ç´°ãªãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s コマンドã¯ã‚¢ãƒ—リケーション ID ã‚’ç›´ã«ç¶šã‘ã¦æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "䏿­£ãªã‚¢ãƒ—リケーション ID ã§ã™: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%sâ€ã¯å¼•æ•°ã‚’å–りã¾ã›ã‚“\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus ã«æŽ¥ç¶šã§ãã¾ã›ã‚“: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "" +"%s ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’アプリケーションã¸é€ä¿¡ã™ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "アクションåã¯ã‚¢ãƒ—リケーション ID ã«ç¶šã‘ã¦æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"䏿­£ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³åã§ã™: “%sâ€\n" +"アクションåã¯è‹±æ•°å­—ã¨â€œ-â€ã€â€œ.â€ã®ã¿ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "アクションã®ãƒ‘ラメーター解æžä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "アクションã¯ãƒ‘ラメーターを一ã¤å—ã‘å–りã¾ã™\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions コマンドã¯ã‚¢ãƒ—リケーション ID ã—ã‹å—ã‘å–りã¾ã›ã‚“" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "アプリケーション %s ã®ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"èªè­˜ã§ããªã„コマンドã§ã™: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s ã«å¼•ãæ¸¡ã—ãŸå€¤ãŒå¤§ãã™ãŽã¾ã™" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "ベースストリームã®ã‚·ãƒ¼ã‚¯ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream を切りã¤ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "ストリームã¯ã™ã§ã«é–‰ã˜ã¦ã„ã¾ã™" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "ベースストリームã®åˆ‡ã‚Šã¤ã‚ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1873 gio/gdbusprivate.c:1416 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "æ“作ãŒã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "åˆæœŸåŒ–ã—ã¦ã„ãªã„䏿­£ãªã‚ªãƒ–ジェクトã§ã™" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "入力ã«ä¸å®Œå…¨ãªãƒã‚¤ãƒˆã®ä¸¦ã³ãŒã‚りã¾ã™" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "変æ›å…ˆã«å分ãªç©ºããŒã‚りã¾ã›ã‚“" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "変æ›ã™ã‚‹å…¥åŠ›ã«ç„¡åйãªãƒã‚¤ãƒˆã®ä¸¦ã³ãŒã‚りã¾ã™" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "変æ›ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1143 +msgid "Cancellable initialization not supported" +msgstr "キャンセルå¯èƒ½ãªåˆæœŸåŒ–ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "“%sâ€ã‹ã‚‰â€œ%sâ€ã¨ã„ã†æ–‡å­—集åˆã¸ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "“%sâ€ã‹ã‚‰â€œ%sâ€ã¸ã®å¤‰æ›å‡¦ç†ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gcontenttype.c:454 +#, c-format +msgid "%s type" +msgstr "%s (情報)" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "䏿˜Žãªç¨®é¡ž" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s (ファイルã®ç¨®é¡ž)" + +#: gio/gcredentials.c:323 +msgid "GCredentials contains invalid data" +msgstr "GCredentials ãŒä¸æ­£ãªãƒ‡ãƒ¼ã‚¿ã‚’å«ã‚“ã§ã„ã¾ã™" + +#: gio/gcredentials.c:383 gio/gcredentials.c:667 +msgid "GCredentials is not implemented on this OS" +msgstr "ã“ã® OS ã§ã¯ GCredentials ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" + +#: gio/gcredentials.c:538 gio/gcredentials.c:556 +msgid "There is no GCredentials support for your platform" +msgstr "ã“ã®ãƒ—ラットフォーム㯠GCredentials をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gcredentials.c:607 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials ãŒã“ã® OS ã®ãƒ—ロセス ID ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: gio/gcredentials.c:661 +msgid "Credentials spoofing is not possible on this OS" +msgstr "ã“ã® OS ã§ã¯è³‡æ ¼æƒ…å ±ã®ãªã‚Šã™ã¾ã—ã¯ã§ãã¾ã›ã‚“" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "想定ã—ã¦ã„ãŸã‚ˆã‚Šã‚‚æ—©ãã‚¹ãƒˆãƒªãƒ¼ãƒ ã®æœ€å¾Œã«åˆ°é”ã—ã¾ã—ãŸ" + +#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„キー“%sâ€ãŒã‚¢ãƒ‰ãƒ¬ã‚¹ã‚¨ãƒ³ãƒˆãƒªãƒ¼â€œ%sâ€ã«ã‚りã¾ã™" + +#: gio/gdbusaddress.c:172 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "アドレスエントリー“%sâ€ã«æ„味ã®ãªã„キー/値ã®ãƒšã‚¢ã®çµ„ã¿åˆã‚ã›ãŒã‚りã¾ã™" + +#: gio/gdbusaddress.c:181 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"アドレス“%sâ€ã¯æ­£ã—ãã‚りã¾ã›ã‚“ (パスã€dirã€tmpdirã€æŠ½è±¡ã‚­ãƒ¼ã®ã„ãšã‚Œã‹ä¸€ã¤ãŒå¿…" +"è¦)" + +#: gio/gdbusaddress.c:248 gio/gdbusaddress.c:259 gio/gdbusaddress.c:274 +#: gio/gdbusaddress.c:337 gio/gdbusaddress.c:348 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "アドレス“%sâ€ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™ — “%sâ€å±žæ€§ãŒä¸æ­£ã§ã™" + +#: gio/gdbusaddress.c:418 gio/gdbusaddress.c:682 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "アドレス“%2$sâ€ã«ä¸æ˜Žã¾ãŸã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„トランスãƒãƒ¼ãƒˆâ€œ%1$sâ€" + +#: gio/gdbusaddress.c:462 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "アドレスè¦ç´ â€œ%sâ€ãŒã‚³ãƒ­ãƒ³ (:) ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: gio/gdbusaddress.c:471 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "アドレスè¦ç´ â€œ%sâ€ã®ãƒˆãƒ©ãƒ³ã‚¹ãƒãƒ¼ãƒˆåã¯ç©ºã«ã§ãã¾ã›ã‚“" + +#: gio/gdbusaddress.c:492 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"アドレスè¦ç´ â€œ%3$sâ€ã® %1$d 番目ã®ã‚­ãƒ¼/値ã®ãƒšã‚¢â€œ%2$sâ€ãŒç­‰å·è¨˜å·ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: gio/gdbusaddress.c:503 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"アドレスè¦ç´ â€œ%3$sâ€ã® %1$d 番目ã®ã‚­ãƒ¼/値ã®ãƒšã‚¢â€œ%2$sâ€ã¯ç©ºã®ã‚­ãƒ¼ã‚’æŒã¦ã¾ã›ã‚“" + +#: gio/gdbusaddress.c:517 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"アドレスè¦ç´ â€œ%3$sâ€ã® %1$d 番目ã®ã‚­ãƒ¼/値ã®ãƒšã‚¢â€œ%2$sâ€ã®ã‚­ãƒ¼ã¾ãŸã¯å€¤ã®ã‚¢ãƒ³ã‚¨ã‚¹" +"ケープ中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#: gio/gdbusaddress.c:589 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"アドレス“%sâ€ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™ — UNIX トランスãƒãƒ¼ãƒˆã¯ã‚­ãƒ¼â€œpathâ€ã¾ãŸ" +"ã¯â€œabstractâ€ã®ã©ã¡ã‚‰ã‹ãŒè¨­å®šã•れã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: gio/gdbusaddress.c:625 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "アドレス“%sâ€ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™ — host 属性ãŒãªã„ã‹ä¸æ­£ã§ã™" + +#: gio/gdbusaddress.c:639 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "アドレス“%sâ€ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™ — port 属性ãŒãªã„ã‹ä¸æ­£ã§ã™" + +#: gio/gdbusaddress.c:653 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "アドレス“%sâ€ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™ — noncefile 属性ãŒãªã„ã‹ä¸æ­£ã§ã™" + +#: gio/gdbusaddress.c:674 +msgid "Error auto-launching: " +msgstr "自動起動中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: " + +#: gio/gdbusaddress.c:727 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "nonce ファイル“%sâ€ã‚’é–‹ãã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusaddress.c:746 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "nonce ファイル“%sâ€ã®èª­ã¿å–り中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusaddress.c:755 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"nonce ファイル“%sâ€ã®èª­ã¿å–り中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—㟠(16 ãƒã‚¤ãƒˆã‚’期待ã—ã¾ã—ãŸ" +"㌠%d ãƒã‚¤ãƒˆã§ã—ãŸ)" + +#: gio/gdbusaddress.c:773 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"nonce ファイル“%sâ€ã®å†…å®¹ã‚’ã‚¹ãƒˆãƒªãƒ¼ãƒ ã«æ›¸ã込むã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ:" + +#: gio/gdbusaddress.c:988 +msgid "The given address is empty" +msgstr "与ãˆã‚‰ã‚ŒãŸã‚¢ãƒ‰ãƒ¬ã‚¹ãŒç©ºã§ã™" + +#: gio/gdbusaddress.c:1101 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "setuid 時ã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒã‚¹ã‚’ spawn ã§ãã¾ã›ã‚“" + +#: gio/gdbusaddress.c:1108 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "machine-id ãªã—ã§ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒã‚¹ã‚’ spawn ã§ãã¾ã›ã‚“: " + +#: gio/gdbusaddress.c:1115 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "X11 $DISPLAY ãªã—ã§ D-Bus を自動起動ã§ãã¾ã›ã‚“" + +#: gio/gdbusaddress.c:1157 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "コマンドライン“%sâ€ã® spawn 中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: " + +#: gio/gdbusaddress.c:1226 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"セッションãƒã‚¹ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’決定ã§ãã¾ã›ã‚“ (ã“ã® OS ã§ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“)" + +#: gio/gdbusaddress.c:1375 gio/gdbusconnection.c:7334 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"DBUS_STARTER_BUS_TYPE 環境変数ã‹ã‚‰ãƒã‚¹ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’決定ã§ãã¾ã›ã‚“ — “%sâ€ã¯ä¸æ˜Žãª" +"値ã§ã™" + +#: gio/gdbusaddress.c:1384 gio/gdbusconnection.c:7343 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"DBUS_STARTER_BUS_TYPE 環境変数ãŒè¨­å®šã•れã¦ã„ãªã„ãŸã‚ã€ãƒã‚¹ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’決定ã§ã" +"ã¾ã›ã‚“" + +#: gio/gdbusaddress.c:1394 +#, c-format +msgid "Unknown bus type %d" +msgstr "䏿˜Žãªãƒã‚¹ã®ç¨®é¡ž %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "行を読ã¿ã“ã‚‚ã†ã¨ã—ã¾ã—ãŸãŒå†…å®¹ãŒæ„図ã›ã𿬠è½ã—ã¦ã„ã¾ã™" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "行を (安全ã«) 読ã¿ã“ã‚‚ã†ã¨ã—ã¾ã—ãŸãŒå†…å®¹ãŒæ„図ã›ã𿬠è½ã—ã¦ã„ã¾ã™" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"ã™ã¹ã¦ã®åˆ©ç”¨å¯èƒ½ãªèªè¨¼ãƒ¡ã‚«ãƒ‹ã‚ºãƒ ã‚’試ã—å°½ãã—ã¾ã—㟠(試行: %s) (利用å¯èƒ½: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" +"GDBusAuthObserver::authorize-authenticated-peer 経由ã§ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" + +#: gio/gdbusauthmechanismsha1.c:298 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "ディレクトリ“%sâ€ã®æƒ…å ±å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusauthmechanismsha1.c:313 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"ディレクトリ“%sâ€ã®ãƒ‘ーミッションãŒä¸æ­£ã§ã™ (0700 モードを期待ã—ã¾ã—ãŸãŒ 0%o " +"ã§ã—ãŸ)" + +#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "ディレクトリ“%sâ€ã®ä½œæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1062 gio/gfile.c:1300 +#: gio/gfile.c:1438 gio/gfile.c:1676 gio/gfile.c:1731 gio/gfile.c:1789 +#: gio/gfile.c:1873 gio/gfile.c:1930 gio/gfile.c:1994 gio/gfile.c:2049 +#: gio/gfile.c:3754 gio/gfile.c:3809 gio/gfile.c:4102 gio/gfile.c:4572 +#: gio/gfile.c:4983 gio/gfile.c:5068 gio/gfile.c:5158 gio/gfile.c:5255 +#: gio/gfile.c:5342 gio/gfile.c:5443 gio/gfile.c:8153 gio/gfile.c:8243 +#: gio/gfile.c:8327 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„æ“作ã§ã™" + +#: gio/gdbusauthmechanismsha1.c:402 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "キーリング“%sâ€ã‚’読ã¿å–り用ã«é–‹ãã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: " + +#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%2$sâ€ã®ã‚­ãƒ¼ãƒªãƒ³ã‚°ã®ã€å†…容ãŒâ€œ%3$sâ€ã® %1$d 行目ãŒä¸æ­£ã§ã™" + +#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"“%2$sâ€ã®ã‚­ãƒ¼ãƒªãƒ³ã‚°ã®ã€å†…容ãŒâ€œ%3$sâ€ã® %1$d è¡Œç›®ã®æœ€åˆã®ãƒˆãƒ¼ã‚¯ãƒ³ãŒä¸æ­£ã§ã™" + +#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"“%2$sâ€ã®ã‚­ãƒ¼ãƒªãƒ³ã‚°ã®ã€å†…容ãŒâ€œ%3$sâ€ã® %1$d 行目㮠2 番目ã®ãƒˆãƒ¼ã‚¯ãƒ³ãŒä¸æ­£ã§ã™" + +#: gio/gdbusauthmechanismsha1.c:477 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "“%2$sâ€ã®ã‚­ãƒ¼ãƒªãƒ³ã‚°ã® id %1$d ã®ã‚¯ãƒƒã‚­ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gdbusauthmechanismsha1.c:523 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "ロックファイル“%sâ€ã®ä½œæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusauthmechanismsha1.c:587 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "stale ã—ãŸãƒ­ãƒƒã‚¯ãƒ•ァイル“%sâ€ã®å‰Šé™¤ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusauthmechanismsha1.c:626 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "(unlink ã—ãŸ) ロックファイル“%sâ€ã‚’é–‰ã˜ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusauthmechanismsha1.c:637 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "ロックファイル“%sâ€ã® unlink 中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "キーリング“%sâ€ã‚’書ãè¾¼ã¿ç”¨ã«é–‹ãã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: " + +#: gio/gdbusauthmechanismsha1.c:908 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(ã•らã«â€œ%sâ€ã®ãƒ­ãƒƒã‚¯è§£æ”¾ã‚‚失敗ã—ã¾ã—ãŸ: %s) " + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2418 +msgid "The connection is closed" +msgstr "接続ãŒé–‰ã˜ã¦ã„ã¾ã™" + +#: gio/gdbusconnection.c:1903 +msgid "Timeout was reached" +msgstr "タイムアウトã—ã¾ã—ãŸ" + +#: gio/gdbusconnection.c:2541 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã‚µã‚¤ãƒ‰ã®æŽ¥ç¶šã‚’ä½œæˆã—よã†ã¨ã—ã¾ã—ãŸãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„フラグã«é­" +"é‡ã—ã¾ã—ãŸ" + +#: gio/gdbusconnection.c:4269 gio/gdbusconnection.c:4623 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"パス %s ã®ã‚ªãƒ–ジェクトã«ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェース“org.freedesktop.DBus.Propertiesâ€ãŒã‚" +"りã¾ã›ã‚“" + +#: gio/gdbusconnection.c:4414 +#, c-format +msgid "No such property “%sâ€" +msgstr "プロパティ“%sâ€ãŒã‚りã¾ã›ã‚“" + +#: gio/gdbusconnection.c:4426 +#, c-format +msgid "Property “%s†is not readable" +msgstr "プロパティ“%sâ€ãŒèª­ã¿å–りå¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gdbusconnection.c:4437 +#, c-format +msgid "Property “%s†is not writable" +msgstr "プロパティ“%sâ€ãŒæ›¸ãè¾¼ã¿å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gdbusconnection.c:4457 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"プロパティ“%sâ€ã®è¨­å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: 期待ã—ãŸåž‹ã¯â€œ%sâ€ã§ã™ãŒâ€œ%sâ€ã§ã—" +"ãŸ" + +#: gio/gdbusconnection.c:4562 gio/gdbusconnection.c:4777 +#: gio/gdbusconnection.c:6760 +#, c-format +msgid "No such interface “%sâ€" +msgstr "インターフェース“%sâ€ãŒã‚りã¾ã›ã‚“" + +#: gio/gdbusconnection.c:4999 gio/gdbusconnection.c:7274 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "パス %2$s ã®ã‚ªãƒ–ジェクトã«ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェース“%1$sâ€ãŒã‚りã¾ã›ã‚“" + +#: gio/gdbusconnection.c:5100 +#, c-format +msgid "No such method “%sâ€" +msgstr "メソッド“%sâ€ãŒã‚りã¾ã›ã‚“" + +#: gio/gdbusconnection.c:5131 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "メッセージã®åž‹â€œ%sâ€ãŒæœŸå¾…ã—ãŸåž‹â€œ%sâ€ã«ä¸€è‡´ã—ã¾ã›ã‚“" + +#: gio/gdbusconnection.c:5334 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" +"オブジェクトã¯ã™ã§ã« %2$s ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェース %1$s ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" + +#: gio/gdbusconnection.c:5561 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "プロパティ %s.%s ã‚’å–å¾—ã§ãã¾ã›ã‚“" + +#: gio/gdbusconnection.c:5617 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "プロパティ %s.%s を設定ã§ãã¾ã›ã‚“" + +#: gio/gdbusconnection.c:5796 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "メソッド“%sâ€ã¯â€œ%sâ€åž‹ã‚’è¿”ã—ã¾ã—ãŸãŒã€â€œ%sâ€ã‚’期待ã—ã¦ã„ã¾ã—ãŸ" + +#: gio/gdbusconnection.c:6872 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "" +"ã‚·ã‚°ãƒãƒãƒ£â€œ%3$sâ€ã‚’æŒã£ãŸã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェース“%2$sâ€ã«ãƒ¡ã‚½ãƒƒãƒ‰â€œ%1$sâ€ãŒå­˜åœ¨ã—ã¾ã›ã‚“" + +#: gio/gdbusconnection.c:6993 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "サブツリーã¯ã™ã§ã« %s ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" + +#: gio/gdbusconnection.c:7282 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "パス“%sâ€ã«ã‚ªãƒ–ジェクトãŒå­˜åœ¨ã—ã¾ã›ã‚“" + +#: gio/gdbusmessage.c:1311 +msgid "type is INVALID" +msgstr "型㌠INVALID" + +#: gio/gdbusmessage.c:1322 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" +"METHOD_CALL メッセージ: PATH ã¾ãŸã¯ MEMBER ヘッダーフィールドãŒã‚りã¾ã›ã‚“" + +#: gio/gdbusmessage.c:1333 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN メッセージ: REPLY_SERIAL ヘッダーフィールドãŒã‚りã¾ã›ã‚“" + +#: gio/gdbusmessage.c:1345 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"ERROR メッセージ: REPLY_SERIAL ã¾ãŸã¯ ERROR_NAME ヘッダーフィールドãŒã‚りã¾ã›" +"ã‚“" + +#: gio/gdbusmessage.c:1358 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"SIGNAL メッセージ: PATHã€INTERFACE ã‚ã‚‹ã„㯠MEMBER ヘッダーフィールドãŒã‚りã¾" +"ã›ã‚“" + +#: gio/gdbusmessage.c:1366 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL メッセージ: PATH ヘッダーフィールドãŒäºˆç´„ã•れãŸå€¤ /org/freedesktop/" +"DBus/Local を使用ã—ã¦ã„ã¾ã™" + +#: gio/gdbusmessage.c:1374 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL メッセージ: INTERFACE ヘッダーフィールドãŒäºˆç´„ã•れãŸå€¤ org." +"freedesktop.DBus.Local を使用ã—ã¦ã¾ã™" + +#: gio/gdbusmessage.c:1422 gio/gdbusmessage.c:1482 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu ãƒã‚¤ãƒˆèª­ã‚‚ã†ã¨ã—ã¾ã—ãŸãŒ %lu ãƒã‚¤ãƒˆã—ã‹èª­ã‚ã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gdbusmessage.c:1436 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "“%sâ€æ–‡å­—列ã®å¾Œã« NUL を期待ã—ã¦ã„ã¾ã—ãŸãŒ %d ãŒã‚りã¾ã—ãŸ" + +#: gio/gdbusmessage.c:1455 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"UTF-8 文字列を期待ã—ã¾ã—ãŸãŒã€æ­£ã—ããªã„ãƒã‚¤ãƒˆåˆ—ãŒã‚ªãƒ•セット %d ã«ã‚りã¾ã—㟠" +"(文字列ã®é•·ã•㯠%d ã§ã™)。正ã—ã„ UTF-8 文字列ã¯â€œ%sâ€ã¾ã§ã§ã™ã€‚" + +#: gio/gdbusmessage.c:1519 gio/gdbusmessage.c:1795 gio/gdbusmessage.c:2006 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1687 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "è§£æžã—ãŸå€¤â€œ%sâ€ã¯æ­£ã—ã„ D-Bus オブジェクトパスã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gdbusmessage.c:1711 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "è§£æžã—ãŸå€¤â€œ%sâ€ã¯æ­£ã—ã„ D-Bus ã‚·ã‚°ãƒãƒãƒ£ã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gdbusmessage.c:1762 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"é•·ã•㌠%u ãƒã‚¤ãƒˆã®é…列ãŒã‚りã¾ã—ãŸã€‚最大長㯠2<<26 ãƒã‚¤ãƒˆ (64 MiB) ã§ã™ã€‚" + +#: gio/gdbusmessage.c:1782 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: gio/gdbusmessage.c:1936 gio/gdbusmessage.c:2655 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "" + +#: gio/gdbusmessage.c:1990 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Variant åž‹ã¨ã—ã¦è§£æžã—ãŸå€¤â€œ%sâ€ã¯æ­£ã—ã„ D-Bus ã‚·ã‚°ãƒãƒãƒ£ã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gdbusmessage.c:2031 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2216 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"エンディアンã«ã¤ã„ã¦ã®å€¤ãŒæ­£ã—ãã‚りã¾ã›ã‚“ (0x6c (“lâ€) ã‚„ 0x42 (“Bâ€) を期待ã—" +"ã¾ã—ãŸãŒ 0x%02x ã§ã—ãŸ)" + +#: gio/gdbusmessage.c:2235 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"プロトコルã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒæ­£ã—ãã‚りã¾ã›ã‚“ (1 を期待ã—ã¾ã—ãŸãŒ %d ã§ã—" +"ãŸ)" + +#: gio/gdbusmessage.c:2293 gio/gdbusmessage.c:2891 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2305 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"ã‚·ã‚°ãƒãƒãƒ£â€œ%sâ€ã®ã‚·ã‚°ãƒãƒãƒ£ãƒ˜ãƒƒãƒ€ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸãŒã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒœãƒ‡ã‚£ãŒç©ºã§" +"ã™" + +#: gio/gdbusmessage.c:2320 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"値“%sâ€ã‚’è§£æžã—ã¾ã—ãŸãŒ D-Bus ã®ã‚·ã‚°ãƒãƒãƒ£ã¨ã—ã¦æ­£ã—ãã‚りã¾ã›ã‚“ (ボディ)" + +#: gio/gdbusmessage.c:2352 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"メッセージ中ã«ã‚·ã‚°ãƒãƒãƒ£ãƒ˜ãƒƒãƒ€ãƒ¼ãŒã‚りã¾ã›ã‚“ãŒã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒœãƒ‡ã‚£ãŒ %u ãƒã‚¤ãƒˆ" +"ã‚りã¾ã™" + +#: gio/gdbusmessage.c:2362 +msgid "Cannot deserialize message: " +msgstr "メッセージをデシリアライズã§ãã¾ã›ã‚“: " + +#: gio/gdbusmessage.c:2708 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2845 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2853 +msgid "Cannot serialize message: " +msgstr "メッセージをシリアライズã§ãã¾ã›ã‚“: " + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"メッセージボディã«ã¯ã‚·ã‚°ãƒãƒãƒ£â€œ%sâ€ãŒã‚りã¾ã™ãŒã€ã‚·ã‚°ãƒãƒãƒ£ãƒ˜ãƒƒãƒ€ãƒ¼ãŒã‚りã¾ã›" +"ã‚“" + +#: gio/gdbusmessage.c:2916 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"メッセージボディã«ã¯åž‹ã‚·ã‚°ãƒãƒãƒ£â€œ%sâ€ãŒã‚りã¾ã™ãŒã€ãƒ˜ãƒƒãƒ€ãƒ¼ãƒ•ィールドã®ã‚·ã‚°ãƒ" +"ãƒãƒ£ã¯â€œ%sâ€ã§ã™" + +#: gio/gdbusmessage.c:2932 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "メッセージボディã¯ç©ºã§ã™ãŒã€ãƒ˜ãƒƒãƒ€ãƒ¼ãƒ•ィールドã®ã‚·ã‚°ãƒãƒãƒ£ã¯â€œ(%s)â€ã§ã™" + +#: gio/gdbusmessage.c:3487 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "型“%sâ€ã®ãƒœãƒ‡ã‚£ã§ã‚¨ãƒ©ãƒ¼ãŒè¿”りã¾ã—ãŸ" + +#: gio/gdbusmessage.c:3495 +msgid "Error return with empty body" +msgstr "空ã®ãƒœãƒ‡ã‚£ã§ã‚¨ãƒ©ãƒ¼ãŒè¿”りã¾ã—ãŸ" + +#: gio/gdbusprivate.c:2246 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(ã“ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‰ã˜ã‚‹ã«ã¯ã€ä½•ã‹æ–‡å­—を入力ã—ã¦ãã ã•ã„)\n" + +#: gio/gdbusprivate.c:2420 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: gio/gdbusprivate.c:2443 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãƒ—ロファイルをå–å¾—ã§ãã¾ã›ã‚“: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2494 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "%s ã¾ãŸã¯ %s を読ã¿è¾¼ã‚ã¾ã›ã‚“: " + +#: gio/gdbusproxy.c:1569 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s ã‚’ StartServiceByName ã§å‘¼ã³å‡ºã™ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: " + +#: gio/gdbusproxy.c:1592 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "StartServiceByName(\"%2$s\") メソッドã‹ã‚‰æœŸå¾…ã—ã¦ãªã„応答 %1$d" + +#: gio/gdbusproxy.c:2699 gio/gdbusproxy.c:2834 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"メソッドを起動ã§ãã¾ã›ã‚“: proxy ãŒã‚ªãƒ¼ãƒŠãƒ¼ã®ãªã„既知ã®åå‰ %s ã§ã€" +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START フラグ㧠proxy ãŒä½œæˆã•れã¦ã„ã¾ã—ãŸ" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "抽象åå‰ç©ºé–“ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "サーãƒãƒ¼ä½œæˆæ™‚ã« nonce ファイルを指定ã§ãã¾ã›ã‚“" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "nonce ファイルを“%sâ€ã«æ›¸ã込むã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "“%sâ€ã¯æ­£ã—ã„ D-Bus GUID ã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„トランスãƒãƒ¼ãƒˆâ€œ%sâ€ã§ listen ã§ãã¾ã›ã‚“" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"コマンド:\n" +" help ã“ã®æƒ…報を表示ã™ã‚‹\n" +" introspect リモートオブジェクトをイントロスペクトã™ã‚‹\n" +" monitor リモートオブジェクトを監視ã™ã‚‹\n" +" call リモートオブジェクトã§ãƒ¡ã‚½ãƒƒãƒ‰ã‚’èµ·å‹•ã™ã‚‹\n" +" emit シグナルをé€ã‚‹\n" +" wait ãƒã‚¹åã®è¡¨ç¤ºã‚’å¾…ã¤\n" +"\n" +"“%s COMMAND --helpâ€ã§å„コマンドã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1236 +#: gio/gdbus-tool.c:1724 +#, c-format +msgid "Error: %s\n" +msgstr "エラー: %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1740 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "イントロスペクション XML ã®è§£æžä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s\n" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "エラー: %s ã¯æ­£ã—ã„åå‰ã§ã¯ã‚りã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1060 +#: gio/gdbus-tool.c:1890 gio/gdbus-tool.c:2130 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "エラー: %s ã¯æ­£ã—ã„オブジェクトパスã§ã¯ã‚りã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "システム bus ã«æŽ¥ç¶š" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "セッション bus ã«æŽ¥ç¶š" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "指定ã•れ㟠D-Bus ã‚¢ãƒ‰ãƒ¬ã‚¹ã«æŽ¥ç¶š" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "接続ã®çµ‚端ã®ã‚ªãƒ—ション:" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "接続ã®çµ‚端を指定ã™ã‚‹ã‚ªãƒ—ション" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "接続ã®çµ‚ç«¯ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "è¤‡æ•°ã®æŽ¥ç¶šã®çµ‚ç«¯ãŒæŒ‡å®šã•れã¦ã„ã¾ã™" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"警告: イントロスペクションã®ãƒ‡ãƒ¼ã‚¿ã«ã‚ˆã‚Œã°ã€ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェース“%sâ€ã¯å­˜åœ¨ã—ã¾ã›" +"ã‚“\n" + +#: gio/gdbus-tool.c:531 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"警告: イントロスペクションã®ãƒ‡ãƒ¼ã‚¿ã«ã‚ˆã‚Œã°ã€ãƒ¡ã‚½ãƒƒãƒ‰â€œ%sâ€ã¯ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェー" +"ス“%sâ€ã«å­˜åœ¨ã—ã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "" + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:997 gio/gdbus-tool.c:1827 +#: gio/gdbus-tool.c:2059 gio/gdbus-tool.c:2279 +#, c-format +msgid "Error connecting: %s\n" +msgstr "接続中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "エラー: %s ã¯æ­£ã—ã„ユニークãªãƒã‚¹åã§ã¯ã‚りã¾ã›ã‚“。\n" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1870 +msgid "Error: Object path is not specified\n" +msgstr "エラー: ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãƒ‘ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:765 +msgid "Error: Signal name is not specified\n" +msgstr "エラー: シグナルåを指定ã—ã¦ã„ã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:779 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "エラー: シグナルå“%sâ€ã¯æ­£ã—ãã‚りã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "エラー: %s ã¯æ­£ã—ã„インターフェースåã§ã¯ã‚りã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "エラー: %s ã¯æ­£ã—ã„メンãƒãƒ¼åã§ã¯ã‚りã¾ã›ã‚“\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1172 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "パラメーター %d ã®è§£æžä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s\n" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "接続ã®ãƒ•ラッシュ中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s\n" + +#: gio/gdbus-tool.c:893 +msgid "Destination name to invoke method on" +msgstr "メソッドを起動ã™ã‚‹å¯¾è±¡ã®åå‰" + +#: gio/gdbus-tool.c:894 +msgid "Object path to invoke method on" +msgstr "メソッドを起動ã™ã‚‹ã‚ªãƒ–ジェクトパス" + +#: gio/gdbus-tool.c:895 +msgid "Method and interface name" +msgstr "メソッドã¨ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェースã®åå‰" + +#: gio/gdbus-tool.c:896 +msgid "Timeout in seconds" +msgstr "" + +#: gio/gdbus-tool.c:942 +msgid "Invoke a method on a remote object." +msgstr "リモートオブジェクトã§ãƒ¡ã‚½ãƒƒãƒ‰ã‚’èµ·å‹•ã—ã¾ã™ã€‚" + +#: gio/gdbus-tool.c:1014 gio/gdbus-tool.c:1844 gio/gdbus-tool.c:2084 +msgid "Error: Destination is not specified\n" +msgstr "エラー: 対象を指定ã—ã¦ã„ã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:1025 gio/gdbus-tool.c:1861 gio/gdbus-tool.c:2095 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "エラー: %s ã¯æ­£ã—ã„ãƒã‚¹åã§ã¯ã‚りã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:1075 +msgid "Error: Method name is not specified\n" +msgstr "エラー: メソッドåを指定ã—ã¦ã„ã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:1086 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "エラー: メソッドå“%sâ€ã¯æ­£ã—ãã‚りã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:1164 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "型“%2$sâ€ã®ãƒ‘ラメーター %1$d ã®è§£æžä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %3$s\n" + +#: gio/gdbus-tool.c:1190 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "ãƒãƒ³ãƒ‰ãƒ« %d を追加ã™ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s\n" + +#: gio/gdbus-tool.c:1686 +msgid "Destination name to introspect" +msgstr "イントロスペクト先ã®åå‰" + +#: gio/gdbus-tool.c:1687 +msgid "Object path to introspect" +msgstr "イントロスペクトã™ã‚‹ã‚ªãƒ–ジェクトパス" + +#: gio/gdbus-tool.c:1688 +msgid "Print XML" +msgstr "XML を表示ã™ã‚‹" + +#: gio/gdbus-tool.c:1689 +msgid "Introspect children" +msgstr "å­ã‚’イントロスペクトã™ã‚‹" + +#: gio/gdbus-tool.c:1690 +msgid "Only print properties" +msgstr "プロパティã®ã¿è¡¨ç¤ºã™ã‚‹" + +#: gio/gdbus-tool.c:1779 +msgid "Introspect a remote object." +msgstr "リモートオブジェクトをイントロスペクトã—ã¾ã™ã€‚" + +#: gio/gdbus-tool.c:1985 +msgid "Destination name to monitor" +msgstr "監視先ã®åå‰" + +#: gio/gdbus-tool.c:1986 +msgid "Object path to monitor" +msgstr "監視ã™ã‚‹ã‚ªãƒ–ジェクトパス" + +#: gio/gdbus-tool.c:2011 +msgid "Monitor a remote object." +msgstr "リモートオブジェクトを監視ã—ã¾ã™ã€‚" + +#: gio/gdbus-tool.c:2069 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "エラー: non-message-bus 接続を監視ã§ãã¾ã›ã‚“\n" + +#: gio/gdbus-tool.c:2193 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2196 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: gio/gdbus-tool.c:2244 +msgid "[OPTION…] BUS-NAME" +msgstr "[オプション…] BUS-NAME" + +#: gio/gdbus-tool.c:2245 +msgid "Wait for a bus name to appear." +msgstr "ãƒã‚¹åã®è¡¨ç¤ºã‚’å¾…ã¡ã¾ã™ã€‚" + +#: gio/gdbus-tool.c:2321 +msgid "Error: A service to activate for must be specified.\n" +msgstr "" + +#: gio/gdbus-tool.c:2326 +msgid "Error: A service to wait for must be specified.\n" +msgstr "" + +#: gio/gdbus-tool.c:2331 +msgid "Error: Too many arguments.\n" +msgstr "エラー: 引数ãŒå¤šã™ãŽã¾ã™ã€‚\n" + +#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "エラー: %s ã¯æ­£ã—ã„æ—¢çŸ¥ã®ãƒã‚¹åã§ã¯ã‚りã¾ã›ã‚“。\n" + +#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4935 +msgid "Unnamed" +msgstr "åå‰ãªã—" + +#: gio/gdesktopappinfo.c:2516 +msgid "Desktop file didn’t specify Exec field" +msgstr "デスクトップファイル㧠Exec フィールドを指定ã—ã¦ã„ã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gdesktopappinfo.c:2804 +msgid "Unable to find terminal required for application" +msgstr "アプリケーションã§å¿…è¦ãªç«¯æœ«ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" + +#: gio/gdesktopappinfo.c:3455 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "ユーザーã®ã‚¢ãƒ—リケーション設定フォルダー %s を作æˆã§ãã¾ã›ã‚“: %s" + +#: gio/gdesktopappinfo.c:3459 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "ユーザー㮠MIME 型設定フォルダー %s を作æˆã§ãã¾ã›ã‚“: %s" + +#: gio/gdesktopappinfo.c:3701 gio/gdesktopappinfo.c:3725 +msgid "Application information lacks an identifier" +msgstr "" + +#: gio/gdesktopappinfo.c:3961 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "ユーザーã®ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—ファイル %s を作æˆã§ãã¾ã›ã‚“" + +#: gio/gdesktopappinfo.c:4097 +#, c-format +msgid "Custom definition for %s" +msgstr "%s ã«å¯¾ã™ã‚‹ç‹¬è‡ªã®è¨­å®š" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "ドライブ㯠eject を実装ã—ã¦ã„ã¾ã›ã‚“" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "ドライブ㯠eject ã¾ãŸã¯ eject_with_operation を実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "ドライブã¯ãƒãƒ¼ãƒªãƒ³ã‚°ã«ã‚ˆã‚‹ãƒ¡ãƒ‡ã‚£ã‚¢ã®æ¤œå‡ºã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "ドライブ㯠start を実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "ドライブ㯠stop を実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gdtlsconnection.c:1153 gio/gtlsconnection.c:920 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS サãƒãƒ¼ãƒˆã¯åˆ©ç”¨ã§ãã¾ã›ã‚“" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS サãƒãƒ¼ãƒˆã¯åˆ©ç”¨ã§ãã¾ã›ã‚“" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã® GEmblem ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã«ã‚るトークン数 (%d) ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "" +"ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã® GEmblemedIcon ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã«ã‚るトークン数 (%d) ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon ã«å¯¾ã™ã‚‹ GEmblem を想定ã—ã¦ã„ã¾ã—ãŸ" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1561 +msgid "Containing mount does not exist" +msgstr "マウントをå«ã‚“ã§ã„ã‚‹ã‚‚ã®ã¯ã‚りã¾ã›ã‚“" + +#: gio/gfile.c:2608 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "ディレクトリ全体をコピーã§ãã¾ã›ã‚“" + +#: gio/gfile.c:2668 +msgid "Can’t copy directory over directory" +msgstr "ディレクトリã‹ã‚‰ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¸ã‚³ãƒ”ーã§ãã¾ã›ã‚“" + +#: gio/gfile.c:2676 +msgid "Target file exists" +msgstr "対象ã®ãƒ•ァイルãŒå­˜åœ¨ã—ã¾ã™" + +#: gio/gfile.c:2695 +msgid "Can’t recursively copy directory" +msgstr "ディレクトリをå†å¸°çš„ã«ã‚³ãƒ”ーã§ãã¾ã›ã‚“" + +#: gio/gfile.c:2996 +msgid "Splice not supported" +msgstr "splice ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gfile.c:3000 +#, c-format +msgid "Error splicing file: %s" +msgstr "ファイル㮠splice 中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gfile.c:3152 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "マウント間ã®ã‚³ãƒ”ー (reflink/clone) ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gfile.c:3156 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "コピー (reflink/clone) ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„ã‹ç„¡åйã§ã™" + +#: gio/gfile.c:3161 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "コピー (reflink/clone) ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„ã‹å‹•作ã—ã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gfile.c:3226 +msgid "Can’t copy special file" +msgstr "スペシャルファイルã¯ã‚³ãƒ”ーã§ãã¾ã›ã‚“" + +#: gio/gfile.c:4035 +msgid "Invalid symlink value given" +msgstr "指定ã—ãŸã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã¯é–“é•ã£ã¦ã„ã¾ã™" + +#: gio/gfile.c:4045 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "シンボリックリンクã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gfile.c:4213 +msgid "Trash not supported" +msgstr "ゴミ箱ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gfile.c:4325 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "ファイルåã«â€œ%câ€ã‚’å«ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: gio/gfile.c:6806 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "ボリュームã¯ãƒžã‚¦ãƒ³ãƒˆã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gfile.c:6920 gio/gfile.c:6968 +msgid "No application is registered as handling this file" +msgstr "ã“ã®ãƒ•ァイルを扱ã†ã‚¢ãƒ—リケーションãŒç™»éŒ²ã•れã¦ã„ã¾ã›ã‚“" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator ã¯é–‰ã˜ã¦ã„ã¾ã™" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ファイル㮠Enumerator ã¯ã™ã§ã«é–‰ã˜ã¦ã„ã¾ã™" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã® GFileIcon ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon ã®å…¥åŠ›ãƒ‡ãƒ¼ã‚¿ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "ストリーム㌠query_info をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ストリームã®ã‚·ãƒ¼ã‚¯ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "入力ストリームを切りã¤ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "ストリームã®åˆ‡ã‚Šã¤ã‚ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:596 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "無効ãªãƒ›ã‚¹ãƒˆåã§ã™" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP プロキシ接続ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP プロキシèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP プロキシèªè¨¼ãŒå¿…è¦ã§ã™" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP プロキシ接続ã«å¤±æ•—ã—ã¾ã—ãŸ: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP プロキシレスãƒãƒ³ã‚¹ãŒå¤§ãã™ãŽã¾ã™" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP プロキシサーãƒãƒ¼ãŒäºˆæœŸã›ãšæŽ¥ç¶šã‚’é–‰ã˜ã¾ã—ãŸã€‚" + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "トークン数 (%d) ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "%s ã¨ã„ã†ã‚¯ãƒ©ã‚¹åã®åž‹ãŒã‚りã¾ã›ã‚“" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s ã¨ã„ã†åž‹ã¯ GIcon ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェースを実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "%s ã¨ã„ã†åž‹ãŒã‚¯ãƒ©ã‚¹ã«ãªã£ã¦ã„ã¾ã›ã‚“" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç•ªå·ãŒé–“é•ã£ã¦ã„ã¾ã™: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" +"%s ã¨ã„ã†åž‹ã¯ GIcon ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェース㧠from_tokens() を実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "æä¾›ã—ãŸã‚¢ã‚¤ã‚³ãƒ³ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "アドレスを指定ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "é•·ã• %u ã¯ã‚¢ãƒ‰ãƒ¬ã‚¹ã«ã¯é•·ã™ãŽã¾ã™" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "IP アドレスマスク“%sâ€ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "ソケットアドレスを作æˆã™ã‚‹ãŸã‚ã®å分ãªç©ºããŒã‚りã¾ã›ã‚“" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„ソケットアドレスã§ã™" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "入力ストリームã¯èª­ã¿è¾¼ã¿ã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "ファイルã¨å…±ã«ã‚³ãƒ”ー" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "ファイルãŒç§»å‹•時ã«ä¿æŒ" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“versionâ€ã¯å¼•æ•°ã‚’å–りã¾ã›ã‚“" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "用法:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦çµ‚了ã™ã‚‹ã€‚" + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "コマンド:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "ファイルを標準出力ã«çµåˆã™ã‚‹" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "一ã¤ä»¥ä¸Šã®ãƒ•ァイルをコピーã™ã‚‹" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "場所ã«ã¤ã„ã¦ã®æƒ…報を表示ã™ã‚‹" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "デスクトップファイルã‹ã‚‰ã‚¢ãƒ—リケーションを起動ã™ã‚‹" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "場所ã®å†…容を一覧表示ã™ã‚‹" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "MIME タイプã®ãƒãƒ³ãƒ‰ãƒ©ã‚’設定ã¾ãŸã¯å–å¾—ã™ã‚‹" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "ディレクトリを作æˆã™ã‚‹" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "ファイルやディレクトリã®å¤‰æ›´ã‚’監視ã™ã‚‹" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "場所をマウントã¾ãŸã¯ã‚¢ãƒ³ãƒžã‚¦ãƒ³ãƒˆã™ã‚‹" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "一ã¤ä»¥ä¸Šã®ãƒ•ァイルを移動ã™ã‚‹" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "デフォルトã®ã‚¢ãƒ—リケーションã§ãƒ•ァイルを開ã" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "ファイルåを変更ã™ã‚‹" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "一ã¤ä»¥ä¸Šã®ãƒ•ァイルを削除ã™ã‚‹" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "標準入力ã‹ã‚‰èª­ã¿å–りä¿å­˜ã™ã‚‹" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "ファイル属性を設定ã™ã‚‹" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "ファイルやディレクトリをゴミ箱ã¸ç§»å‹•ã™ã‚‹" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "ツリー形å¼ã§å ´æ‰€ã®å†…容を一覧表示ã™ã‚‹" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "%s ã§è©³ç´°ãªãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "標準出力ã¸ã®æ›¸ãè¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "ファイルをçµåˆã—ã¦æ¨™æº–出力ã«å‡ºåŠ›ã—ã¾ã™ã€‚" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat ã¯ä¼çµ±çš„㪠cat ユーティリティã®ã‚ˆã†ã«å‹•作ã™ã‚‹ãƒ„ールã§ã€ãƒ­ãƒ¼ã‚«ãƒ«ãƒ•ァイ" +"ルã®ä»£ã‚り㫠GIO ロケーションを使用ã§ãã¾ã™ (例: smb://server/resource/file." +"txt)。" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "場所を指定ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "ディレクトリを対象ã«ã—ãªã„" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "進æ—を表示ã™ã‚‹" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "上書ãã™ã‚‹å‰ã«ç¢ºèªã™ã‚‹" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "ã™ã¹ã¦ã®å±žæ€§ã‚’ä¿æŒã™ã‚‹" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "既存ã®å¯¾è±¡ãƒ•ァイル (DEST) ã‚’ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã™ã‚‹" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "シンボリックリンクをãŸã©ã‚‰ãªã„" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%s / %s è»¢é€ (%s/ç§’)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SOURCE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINATION" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "一ã¤ä»¥ä¸Šã®ãƒ•ァイルを SOURCE ã‹ã‚‰ DESTINATION ã«ã‚³ãƒ”ーã—ã¾ã™ã€‚" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy ã¯ä¼çµ±çš„㪠cp ユーティリティã«ä¼¼ãŸãƒ„ールã§ã€ãƒ­ãƒ¼ã‚«ãƒ«ãƒ•ァイルã®ä»£ã‚り" +"ã« GIO ロケーションを使用ã§ãã¾ã™ (例: smb://server/resource/file.txt)。" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "%s ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: “%sâ€ã‚’上書ãã—ã¾ã™ã‹? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "書込ã¿å¯èƒ½ãªå±žæ€§ä¸€è¦§ã‚’表示ã™ã‚‹" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ã®æƒ…報をå–å¾—ã™ã‚‹" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "å–å¾—ã™ã‚‹å±žæ€§" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "シンボリックリンクをãŸã©ã‚‰ãªã„" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "属性:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "表示å: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "編集å: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "åå‰: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "種類: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "サイズ: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "éžè¡¨ç¤º\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "URI: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "ローカルパス: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "設定å¯èƒ½ãªå±žæ€§:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "書込ã¿å±žæ€§ã®åå‰ç©ºé–“:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "場所ã«ã¤ã„ã¦ã®æƒ…報を表示ã—ã¾ã™ã€‚" + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "デスクトップファイルを指定ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "ã“ã®ãƒ—ラットフォームã¯ç¾åœ¨èµ·å‹•コマンドをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "‘%s’を読ã¿è¾¼ã‚ã¾ã›ã‚“: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "‘%s’ã®ã‚¢ãƒ—リケーション情報を読ã¿è¾¼ã‚ã¾ã›ã‚“" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "アプリケーション‘%s’を起動ã§ãã¾ã›ã‚“: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "éš ã—ファイルを表示ã™ã‚‹" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "é•·ã„å½¢å¼ã§ä¸€è¦§ã‚’表示ã™ã‚‹" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "表示åを表示ã™ã‚‹" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "完全㪠URI を表示ã™ã‚‹" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "場所ã®å†…容を一覧表示ã—ã¾ã™ã€‚" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "MIME タイプã®ãƒãƒ³ãƒ‰ãƒ©ã‚’設定ã¾ãŸã¯å–å¾—ã—ã¾ã™ã€‚" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"ãƒãƒ³ãƒ‰ãƒ©ã‚’指定ã—ãªã„å ´åˆã€MIME タイプã«ç™»éŒ²ã•れã¦ã„ã‚‹ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã¨æŽ¨å¥¨ã•" +"れã¦ã„るアプリケーションã®ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚ãƒãƒ³ãƒ‰ãƒ©ã‚’指定ã—ãŸå ´åˆã€ãã®ãƒãƒ³" +"ドラを MIME タイプã®ãƒ‡ãƒ•ォルトã®ãƒãƒ³ãƒ‰ãƒ©ã¨ã—ã¦è¨­å®šã—ã¾ã™ã€‚" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "å˜ä¸€ã® MIME タイプ (ã¨ã€ãŠãらããƒãƒ³ãƒ‰ãƒ©) を指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "“%sâ€ã®ãƒ‡ãƒ•ォルトã®ã‚¢ãƒ—リケーションãŒã‚りã¾ã›ã‚“\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "“%sâ€ã®ãƒ‡ãƒ•ォルトã®ã‚¢ãƒ—リケーション: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "登録ã•れã¦ã„るアプリケーション:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "登録ã•れã¦ã„るアプリケーションã¯ã‚りã¾ã›ã‚“\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "推奨ã•れã¦ã„るアプリケーション:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "推奨ã•れã¦ã„るアプリケーションã¯ã‚りã¾ã›ã‚“\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "ãƒãƒ³ãƒ‰ãƒ©â€œ%sâ€ã®æƒ…報読ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "“%sâ€ã‚’“%sâ€ã®ãƒ‡ãƒ•ォルトãƒãƒ³ãƒ‰ãƒ©ã¨ã—ã¦è¨­å®šã™ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "親ディレクトリを作æˆã™ã‚‹" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "ディレクトリを作æˆã—ã¾ã™ã€‚" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir ã¯ä¼çµ±çš„㪠mkdir ユーティリティã«ä¼¼ãŸãƒ„ールã§ã€ãƒ­ãƒ¼ã‚«ãƒ«ãƒ•ァイルã®ä»£" +"ã‚り㫠GIO ロケーションを使用ã§ãã¾ã™ (例: smb://server/resource/mydir)。" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "ディレクトリを監視ã™ã‚‹ (デフォルト: 種類ã«ä¾å­˜)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "ファイルを監視ã™ã‚‹ (デフォルト: 種類ã«ä¾å­˜)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "ファイルを直接監視ã™ã‚‹ (変更を報告ã—ãªã„)" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "ファイルやディレクトリã®å¤‰æ›´ã‚’監視ã—ã¾ã™ã€‚" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "マウントå¯èƒ½ã¨ã—ã¦ãƒžã‚¦ãƒ³ãƒˆã™ã‚‹" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "デãƒã‚¤ã‚¹ãƒ•ァイルã¾ãŸã¯ä»–ã®è­˜åˆ¥å­ã§ãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚’マウントã™ã‚‹" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "アンマウントã™ã‚‹" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "å–り出ã™" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "デãƒã‚¤ã‚¹ãƒ•ァイルã§ãƒ‰ãƒ©ã‚¤ãƒ–ã‚’åœæ­¢ã™ã‚‹" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "指定ã—ãŸã‚¹ã‚­ãƒ¼ãƒ ã§ã™ã¹ã¦ã®ãƒžã‚¦ãƒ³ãƒˆã‚’アンマウントã™ã‚‹" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "アンマウントã¾ãŸã¯å–り出ã™ã¨ãã«æœªå‡¦ç†ã®ãƒ•ァイルæ“作を無視ã™ã‚‹" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "èªè¨¼ã«åŒ¿åユーザーを使用ã™ã‚‹" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "一覧を表示ã™ã‚‹" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "イベントを監視ã™ã‚‹" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "ãã®ä»–ã®æƒ…報を表示ã™ã‚‹" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "VeraCrypt ボリュームã®ãƒ­ãƒƒã‚¯ã‚’解除ã™ã‚‹ PIM 値" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "TCRYPT ã®éš ã—ボリュームをマウントã™ã‚‹" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "TCRYPT ã®ã‚·ã‚¹ãƒ†ãƒ ãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚’マウントã™ã‚‹" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "匿åã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "デãƒã‚¤ã‚¹ãƒ•ァイルã®ãƒ‰ãƒ©ã‚¤ãƒ–ãŒã‚りã¾ã›ã‚“" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "指定ã—㟠ID ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ãŒã‚りã¾ã›ã‚“" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "場所をマウントã¾ãŸã¯ã‚¢ãƒ³ãƒžã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "一ã¤ä»¥ä¸Šã®ãƒ•ァイルを SOURCE ã‹ã‚‰ DEST ã¸ç§»å‹•ã—ã¾ã™ã€‚" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move ã¯ä¼çµ±çš„㪠mv ユーティリティã«ä¼¼ãŸãƒ„ールã§ã€ãƒ­ãƒ¼ã‚«ãƒ«ãƒ•ァイルã®ä»£ã‚り" +"ã« GIO ロケーションを使用ã§ãã¾ã™ (例: smb://server/resource/file.txt)" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "%s ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"ã“ã®ç¨®é¡žã®ãƒ•ァイルを扱ã†ã‚ˆã†ç™»éŒ²ã•れãŸã€\n" +"デフォルトã®ã‚¢ãƒ—リケーションã§ãƒ•ァイルを開ãã¾ã™ã€‚" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "存在ã—ãªã„ファイルを無視ã™ã‚‹ (プロンプトを表示ã—ãªã„)" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "指定ã—ãŸãƒ•ァイルを削除ã—ã¾ã™ã€‚" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "ファイルåを変更ã—ã¾ã™ã€‚" + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "引数ãŒã‚りã¾ã›ã‚“" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "引数ãŒå¤šã™ãŽã¾ã™" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "åå‰ã‚’変更ã§ãã¾ã—ãŸã€‚æ–°ã—ã„ URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "存在ã—ãªã„å ´åˆã®ã¿ä½œæˆã™ã‚‹" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ«å°¾ã«è¿½è¨˜ã™ã‚‹" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "ファイルを作æˆã™ã‚‹ã¨ãã«ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã¿ã«ã‚¢ã‚¯ã‚»ã‚¹ã‚’制é™ã™ã‚‹" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "ç½®æ›æ™‚ã«ç½®æ›å…ˆãŒå­˜åœ¨ã—ãªã„ã‹ã®ã‚ˆã†ã«ç½®æ›ã™ã‚‹" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "æ–°ã—ã„ etag を最後ã«å‡ºåŠ›ã™ã‚‹" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "上書ã対象ã®ãƒ•ァイル㮠etag" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "標準入力ã‹ã‚‰ã®èª­ã¿å–り中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "etag ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "標準入力ã‹ã‚‰èª­ã¿å–ã£ã¦ DEST ã«ä¿å­˜ã—ã¾ã™ã€‚" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "対象を指定ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "属性ã®ç¨®é¡ž" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "場所ã®ãƒ•ァイル属性を設定ã—ã¾ã™ã€‚" + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "場所を指定ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "属性を指定ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "値を指定ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "属性ã®ç¨®é¡žâ€œ%sâ€ã¯ä¸æ­£ã§ã™" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "ゴミ箱を空ã«ã™ã‚‹" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "ゴミ箱ã«ã‚るファイルã®åå‰ã¨å…ƒã®å ´æ‰€ã‚’一覧表示ã™ã‚‹" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "ファイルをゴミ箱ã‹ã‚‰å…ƒã®å ´æ‰€ã«æˆ»ã™ (å¯èƒ½ãªã‚‰ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚‚å†ä½œæˆã•れる)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "å…ƒã®ãƒ‘スãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "å…ƒã®å ´æ‰€ã‚’å†ä½œæˆã§ãã¾ã›ã‚“: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "ファイルを元ã®å ´æ‰€ã¸ç§»å‹•ã§ãã¾ã›ã‚“: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "" +"ファイルやディレクトリをゴミ箱ã¸ç§»å‹•ã¾ãŸã¯ã‚´ãƒŸç®±ã‹ã‚‰æˆ»ã—ã¾ã™ã€‚" + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "trash:/// ã‹ã‚‰å§‹ã¾ã‚‹å ´æ‰€ã‚’指定ã—ã¦ãã ã•ã„" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "シンボリックリンクã€ãƒžã‚¦ãƒ³ãƒˆã€ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆã‚’ãŸã©ã‚‹" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "ディレクトリã®å†…容をツリー形å¼ã§ä¸€è¦§è¡¨ç¤ºã—ã¾ã™ã€‚" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "è¦ç´  <%s> 㯠<%s> 内ã«å«ã‚られã¾ã›ã‚“" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "è¦ç´  <%s> ã¯ãƒˆãƒƒãƒ—レベルã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "リソース内ã«ãƒ•ァイル %s ãŒè¤‡æ•°å›žå‡ºç¾ã—ã¦ã„ã¾ã™" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "ソースディレクトリã«â€œ%sâ€ãŒã‚りã¾ã›ã‚“" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«â€œ%sâ€ãŒã‚りã¾ã›ã‚“" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "“%sâ€ã¯ä¸æ˜Žãªã‚ªãƒ—ションã§ã™" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "%s ã®å‰å‡¦ç†ãŒè¦æ±‚ã•れã¾ã—ãŸãŒ %s ã®è¨­å®šãŒãªã %s ã‚‚ PATH ã«ã‚りã¾ã›ã‚“" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "ファイル %s ã®èª­ã¿å–り中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "ファイル %s ã®åœ§ç¸®ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "文字列㯠<%s> 内ã«å«ã‚られã¾ã›ã‚“" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "プログラムã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã—ã¦çµ‚了ã™ã‚‹" + +#: gio/glib-compile-resources.c:738 +msgid "Name of the output file" +msgstr "出力ファイルå" + +#: gio/glib-compile-resources.c:739 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"対象ã®ãƒ•ァイル (FILE) を読ã¿è¾¼ã‚€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª (デフォルト: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª)" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "" + +#: gio/glib-compile-resources.c:742 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:746 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: gio/glib-compile-resources.c:747 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "関数をエクスãƒãƒ¼ãƒˆã—ãªã„ (G_GNUC_INTERNAL を使用ã—ã¦ãã ã•ã„)" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"リソース仕様をコンパイルã—ã¦ã€ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイルを生æˆã—ã¾ã™ã€‚\n" +"ãƒªã‚½ãƒ¼ã‚¹ä»•æ§˜ãƒ•ã‚¡ã‚¤ãƒ«ã®æ‹¡å¼µå­ã¯ .gresource.xmlã€\n" +"ãƒªã‚½ãƒ¼ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã®æ‹¡å¼µå­ã¯ .gresource ã§ã™ã€‚" + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "ファイルåを一ã¤ã ã‘指定ã—ã¦ãã ã•ã„\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "䏿­£ãªæ•°å€¤ã§ã™" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " ã¯ã™ã§ã«ã“ã®ã‚­ãƒ¼ã§å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "サãƒãƒ¼ãƒˆã—ã¦ã„ãªã„ l10n ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã§ã™: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n ãŒè¦æ±‚ã•れã¾ã—ãŸãŒ gettext ãƒ‰ãƒ¡ã‚¤ãƒ³ã®æŒ‡å®šãŒã‚りã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "“%sâ€ã® 値ã®è§£æžã«å¤±æ•—ã—ã¾ã—ãŸ: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " ã¯ã™ã§ã«ã“ã®ã‚­ãƒ¼ã§å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr "" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " ã¯ã™ã§ã«ã“ã®ã‚­ãƒ¼ã§å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "空ã®åå‰ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "åå‰â€œ%sâ€ã¯ä¸æ­£ã§ã™: åå‰ã®å…ˆé ­ã¯å°æ–‡å­—ã®ã¿ãŒä½¿ç”¨ã§ãã¾ã™" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"åå‰â€œ%sâ€ã®â€œ%câ€ã¯ä¸æ­£ã§ã™: å°æ–‡å­—ã€æ•°å­—ã€ãƒã‚¤ãƒ•ン (“-â€) ã®ã¿ãŒä½¿ç”¨ã§ãã¾ã™" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "åå‰â€œ%sâ€ã¯ä¸æ­£ã§ã™: 連続ã™ã‚‹ãƒã‚¤ãƒ•ン (“--â€) ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "åå‰â€œ%sâ€ã¯ä¸æ­£ã§ã™: ãƒã‚¤ãƒ•ン (“-â€) ã¯åå‰ã®æœ«å°¾ã«ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "åå‰â€œ%sâ€ã¯ä¸æ­£ã§ã™: 最大長㯠1024 ã§ã™" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "“list-ofâ€å±žæ€§ã‚’æŒã¤ã‚¹ã‚­ãƒ¼ãƒžã«ã‚­ãƒ¼ã‚’追加ã§ãã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" 㯠中㮠を隠ã—ã¦ã—ã¾ã„" +"ã¾ã™ã€‚値ã®å¤‰æ›´ã¯ を使用ã—ã¦ãã ã•ã„" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +" ã®å±žæ€§ã¨ã—ã¦ã¯ã€â€œtypeâ€ã€â€œenumâ€ã€â€œflagsâ€ã®ã©ã‚Œã‹ä¸€ã¤ã ã‘ãŒæŒ‡å®šã§ãã¾ã™" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> 㯠(ã¾ã ) 定義ã•れã¦ã„ã¾ã›ã‚“。" + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "“%sâ€ã¯ä¸æ­£ãª GVariant åž‹ã®æ–‡å­—列ã§ã™" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " ãŒæŒ‡å®šã•れã¾ã—ãŸãŒã€ã‚¹ã‚­ãƒ¼ãƒžã¯ä½•ã‚‚æ‹¡å¼µã—ã¦ã„ã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã™ã‚‹ ãŒã‚りã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " ã¯ã¾ã å­˜åœ¨ã—ã¦ã„ãªã„スキーマ“%sâ€ã‚’æ‹¡å¼µã—ã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " ã¯ã¾ã å­˜åœ¨ã—ã¦ã„ãªã„スキーマ“%sâ€ã®ãƒªã‚¹ãƒˆã§ã™" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "path 属性をæŒã¤ã‚¹ã‚­ãƒ¼ãƒžã®ãƒªã‚¹ãƒˆã«ã¯ãªã‚Œã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "path 属性をæŒã¤ã‚¹ã‚­ãƒ¼ãƒžã‚’æ‹¡å¼µã§ãã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ã¯ãƒªã‚¹ãƒˆã§ã™ãŒã€ãƒªã‚¹ãƒˆã§ã¯ãªã„ ã‚’æ‹¡å¼µã—ã¦ã„" +"ã¾ã™" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" 㯠を拡張ã—ã¦ã„ã¾" +"ã™ãŒã€â€œ%sâ€ã¯â€œ%sâ€ã‚’æ‹¡å¼µã—ã¦ã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "パスを指定ã™ã‚‹å ´åˆã€ãã®å…ˆé ­ãŠã‚ˆã³æœ«å°¾ã¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "リストã®ãƒ‘ã‚¹ã®æœ«å°¾ã¯â€œ:/â€ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "è¦ç´  <%s> ã¯ãƒˆãƒƒãƒ—レベルã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr " 内ã«è¦ç´  ãŒå¿…è¦ã§ã™" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "文字列㯠<%s> 内ã«å«ã‚られã¾ã›ã‚“" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "警告: ã¸ã®å®šç¾©ã•れã¦ã„ãªã„å‚ç…§ã§ã™" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict ãŒæŒ‡å®šã•れã¾ã—ãŸã€‚終了ã—ã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "ã“ã®ãƒ•ァイルを無視ã—ã¾ã—ãŸã€‚" + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "ã“ã®ãƒ•ァイルを無視ã—ã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ãƒ•ァイル“%3$sâ€ã§æŒ‡å®šã•れãŸã‚¹ã‚­ãƒ¼ãƒžâ€œ%2$sâ€ã®ã‚­ãƒ¼â€œ%1$sâ€ãŒã‚りã¾ã›" +"ん。ã“ã®ã‚­ãƒ¼ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã‚’無視ã—ã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ãƒ•ァイル“%3$sâ€ã§æŒ‡å®šã•れãŸã‚¹ã‚­ãƒ¼ãƒžâ€œ%2$sâ€ã®ã‚­ãƒ¼â€œ%1$sâ€ãŒã‚りã¾ã›" +"ん。--strict ãŒæŒ‡å®šã•れãŸãŸã‚終了ã—ã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ãƒ•ァイル“%3$sâ€ã§æŒ‡å®šã•れãŸã‚¹ã‚­ãƒ¼ãƒžâ€œ%2$sâ€ã®ã‚­ãƒ¼â€œ%1$sâ€ã®è§£æžä¸­ã«" +"エラーãŒç™ºç”Ÿã—ã¾ã—ãŸ: %4$s: ã“ã®ã‚­ãƒ¼ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã‚’無視ã—ã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ãƒ•ァイル“%3$sâ€ã§æŒ‡å®šã•れãŸã‚¹ã‚­ãƒ¼ãƒžâ€œ%2$sâ€ã®ã‚­ãƒ¼â€œ%1$sâ€ã®è§£æžä¸­ã«" +"エラーãŒç™ºç”Ÿã—ã¾ã—ãŸ: %4$s: --strict ãŒæŒ‡å®šã•れãŸãŸã‚終了ã—ã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ãƒ•ァイル“%3$sâ€ã§æŒ‡å®šã•れãŸã‚¹ã‚­ãƒ¼ãƒžâ€œ%2$sâ€ã®ã‚­ãƒ¼â€œ%1$sâ€ã®ã‚ªãƒ¼ãƒãƒ¼" +"ライド値ãŒã€ã‚¹ã‚­ãƒ¼ãƒžã§å®šç¾©ã•ã‚ŒãŸæœ‰åйãªç¯„囲内ã«ã‚りã¾ã›ã‚“。ã“ã®ã‚­ãƒ¼ã®ã‚ªãƒ¼ãƒãƒ¼" +"ライドを無視ã—ã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ãƒ•ァイル“%3$sâ€ã§æŒ‡å®šã•れãŸã‚¹ã‚­ãƒ¼ãƒžâ€œ%2$sâ€ã®ã‚­ãƒ¼â€œ%1$sâ€ã®ã‚ªãƒ¼ãƒãƒ¼" +"ライド値ãŒã€ã‚¹ã‚­ãƒ¼ãƒžã§å®šç¾©ã•ã‚ŒãŸæœ‰åйãªç¯„囲内ã«ã‚りã¾ã›ã‚“。--strict ãŒæŒ‡å®šã•れ" +"ãŸãŸã‚終了ã—ã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "gschemas.compiled ファイルã®å‡ºåŠ›å…ˆ" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "スキーマ内ã«ã‚¨ãƒ©ãƒ¼ã‚’検出ã—ãŸã‚‰å‡¦ç†ã‚’中止ã™ã‚‹" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled を生æˆã—ãªã„" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "キーåã®åˆ¶ç´„を強制ã—ãªã„" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"ã™ã¹ã¦ã® GSettings スキーマファイルをコンパイルã—ã¦ã€ã‚¹ã‚­ãƒ¼ãƒžã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’生æˆ" +"ã—ã¾ã™ã€‚\n" +"ã‚¹ã‚­ãƒ¼ãƒžãƒ•ã‚¡ã‚¤ãƒ«ã®æ‹¡å¼µå­ã¯ .gschema.xml ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" +"キャッシュファイルã®å称㯠gschemas.compiled ã¨ãªã‚Šã¾ã™ã€‚" + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "ディレクトリåを一ã¤ã ã‘指定ã—ã¦ãã ã•ã„" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "スキーマファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: 何もã—ã¾ã›ã‚“。" + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "スキーマファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: 既存ã®å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å‰Šé™¤ã—ã¾ã—ãŸã€‚" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "%s ã¯ä¸æ­£ãªãƒ•ァイルåã§ã™" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "%s ã®ãƒ•ァイルシステム情報å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "ルートディレクトリã®åå‰ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "ファイル %s ã®åå‰å¤‰æ›´ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "ファイルåを変更ã§ãã¾ã›ã‚“ (ã™ã§ã«å­˜åœ¨ã—ã¦ã„ã‚‹ãŸã‚)" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "䏿­£ãªãƒ•ァイルåã§ã™" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "ファイル %s ã‚’é–‹ãã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "ファイル %s ã®å‰Šé™¤ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "ファイル %s をゴミ箱ã¸ç§»å‹•ã™ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "ゴミ箱ディレクトリ %s を作æˆã§ãã¾ã›ã‚“: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "%s ã®ã‚´ãƒŸç®±ã®ãŸã‚ã®ãƒˆãƒƒãƒ—レベルディレクトリãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "%2$s ã®ç§»å‹•å…ˆã®ã‚´ãƒŸç®±ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª %1$s ãŒå­˜åœ¨ã—ãªã„ã‹ä½œæˆã§ãã¾ã›ã‚“" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "%s ã®ã‚´ãƒŸç®±æƒ…報ファイルを作æˆã§ãã¾ã›ã‚“: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "ファイル %s を別ã®ãƒ•ァイルシステムã®ã‚´ãƒŸç®±ã¸ç§»å‹•ã§ãã¾ã›ã‚“" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "ファイル %s をゴミ箱ã¸ç§»å‹•ã§ãã¾ã›ã‚“: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "ファイル %s をゴミ箱ã¸ç§»å‹•ã§ãã¾ã›ã‚“" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "ディレクトリ %s ã®ä½œæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "シンボリックリンクをファイルシステムãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "シンボリックリンク %s ã®ä½œæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "ファイル %s ã®ç§»å‹•中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "ディレクトリã‹ã‚‰ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¸ç§»å‹•ã§ãã¾ã›ã‚“" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "対象ファイルã®å‰Šé™¤ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "マウント間ã®ç§»å‹•ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s ã®ãƒ‡ã‚£ã‚¹ã‚¯ä½¿ç”¨é‡ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "属性値を NULL ã«ã—ãªã„ã§ãã ã•ã„" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "属性ã®ç¨®é¡žãŒä¸æ­£ã§ã™ (文字列を想定ã—ã¦ã„ãŸ)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "拡張属性ã®åå‰ãŒä¸æ­£ã§ã™" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "拡張属性“%sâ€ã®è¨­å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (䏿­£ãªã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "ファイル“%sâ€ã®æƒ…å ±å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‡ã‚£ã‚¹ã‚¯ãƒªãƒ—ã‚¿ãƒ¼ã®æƒ…å ±å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "属性ã®ç¨®é¡žãŒä¸æ­£ã§ã™ (uint32 型を想定ã—ã¦ã„ãŸ)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "属性ã®ç¨®é¡žãŒä¸æ­£ã§ã™ (uint64 型を想定ã—ã¦ã„ãŸ)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "属性ã®ç¨®é¡žãŒä¸æ­£ã§ã™ (ãƒã‚¤ãƒˆåž‹ã®æ–‡å­—列を想定ã—ã¦ã„ãŸ)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "シンボリックリンクã«ã¯ã‚¢ã‚¯ã‚»ã‚¹æ¨©ã‚’設定ã§ãã¾ã›ã‚“" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "アクセス権ã®è¨­å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "所有者ã®è¨­å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "シンボリックリンクを NULL ã«ã—ãªã„ã§ãã ã•ã„" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "シンボリックリンクã®è¨­å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"シンボリックリンクã®è¨­å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: ファイルãŒãƒªãƒ³ã‚¯ã§ã¯ã‚りã¾" +"ã›ã‚“" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "ファイルå“%sâ€ã‚’ UTF-16 ã«å¤‰æ›ã§ãã¾ã›ã‚“" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "“%sâ€ã‚’é–‹ã‘ã¾ã›ã‚“: Windows エラー %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"“%sâ€ã®æœ€çµ‚更新日時ã¾ãŸã¯æœ€çµ‚アクセス日時ã®è¨­å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "最終更新日時ã¾ãŸã¯æœ€çµ‚アクセス日時ã®è¨­å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux ã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã‚’ NULL ã«ã—ãªã„ã§ãã ã•ã„" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "ã“ã®ã‚·ã‚¹ãƒ†ãƒ ã§ã¯ SELinux ãŒæœ‰åйã«ãªã£ã¦ã„ã¾ã›ã‚“" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux ã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆæŒ‡å®šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s ã¨ã„ã†å±žæ€§å€¤ã¯è¨­å®šã§ãã¾ã›ã‚“" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "ファイルã‹ã‚‰ã®èª­ã¿å–り中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "ファイルを閉ã˜ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ファイルã§ã‚·ãƒ¼ã‚¯ã™ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "ローカルファイルを監視ã™ã‚‹ãƒ‡ãƒ•ォルトモニターã®ç¨®é¡žãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "ファイルã¸ã®æ›¸ãè¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "å¤ã„ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—リンクã®å‰Šé™¤ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã®ã‚³ãƒ”ー作æˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "一時ファイルã®åå‰å¤‰æ›´ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "ファイルã®åˆ‡ã‚Šã¤ã‚中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:226 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "ファイル“%sâ€ã‚’é–‹ãã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "対象ã¨ãªã‚‹ãƒ•ァイルã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "対象ã¨ãªã‚‹ãƒ•ァイルã¯é€šå¸¸ã®ãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "ファイルãŒå¤–部ã§å¤‰æ›´ã•れã¾ã—ãŸ" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "å¤ã„ファイルã®å‰Šé™¤ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "䏿­£ãª GSeekType ãŒæŒ‡å®šã•れã¾ã—ãŸ" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "䏿­£ãªã‚·ãƒ¼ã‚¯è¦æ±‚ã§ã™" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream を切りã¤ã‚られã¾ã›ã‚“" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "メモリ出力ストリームã®å¤§ãã•ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "メモリ出力ストリームã®å¤§ãã•変更ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"書ã込むプロセスã«å¿…è¦ãªãƒ¡ãƒ¢ãƒªã®é‡ãŒåˆ©ç”¨å¯èƒ½ãªã‚¢ãƒ‰ãƒ¬ã‚¹ã‚¹ãƒšãƒ¼ã‚¹ã‚ˆã‚Šå¤§ãã„ã§ã™" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "ストリームã®å…ˆç«¯ã‚ˆã‚Šå‰ã¸ã‚·ãƒ¼ã‚¯ã™ã‚‹ã‚ˆã†ãƒªã‚¯ã‚¨ã‚¹ãƒˆã•れã¾ã—ãŸ" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "ã‚¹ãƒˆãƒªãƒ¼ãƒ ã®æœ€å¾Œã‚’è¶Šãˆã¦ã‚·ãƒ¼ã‚¯ã™ã‚‹ã‚ˆã†ãƒªã‚¯ã‚¨ã‚¹ãƒˆã•れã¾ã—ãŸ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "mount ã¯â€œunmountâ€ã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount ã¯â€œejectâ€ã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +# +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "mount ã¯â€œunmountâ€ã¾ãŸã¯â€œunmount_with_operationâ€ã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "mount ã¯â€œejectâ€ã¾ãŸã¯â€œeject_with_operationâ€ã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "mount ã¯â€œremountâ€ã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "mount ã«ã¯ãƒ¡ãƒ‡ã‚£ã‚¢ã®ç¨®é¡žã‚’推測ã™ã‚‹ã‚ˆã†ãªå®Ÿè£…ã¯ã‚りã¾ã›ã‚“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "mount ã«ã¯åŒæœŸã•ã›ã¦ãƒ¡ãƒ‡ã‚£ã‚¢ã®ç¨®é¡žã‚’推測ã™ã‚‹ã‚ˆã†ãªå®Ÿè£…ã¯ã‚りã¾ã›ã‚“" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "ホストå“%sâ€ã«â€œ[â€ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒâ€œ]â€ãŒã‚りã¾ã›ã‚“" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãŒåˆ°é”ä¸èƒ½ã§ã™" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "ホストãŒåˆ°é”ä¸èƒ½ã§ã™" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãƒ¢ãƒ‹ã‚¿ãƒ¼ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãƒ¢ãƒ‹ã‚¿ãƒ¼ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager ãŒèµ·å‹•ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒå¤ã™ãŽã¾ã™" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "å‡ºåŠ›ã‚¹ãƒˆãƒªãƒ¼ãƒ ã¯æ›¸ãè¾¼ã¿ã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "ソースストリームã¯ã™ã§ã«é–‰ã˜ã¦ã„ã¾ã™" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "“%sâ€ã®è§£æ±ºä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:615 +#, c-format +msgid "%s not implemented" +msgstr "%s ã¯å®Ÿè£…ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gresolver.c:984 gio/gresolver.c:1036 +msgid "Invalid domain" +msgstr "䏿­£ãªãƒ‰ãƒ¡ã‚¤ãƒ³ã§ã™" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "“%sâ€ã®ãƒªã‚½ãƒ¼ã‚¹ãŒå­˜åœ¨ã—ã¾ã›ã‚“" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "“%sâ€ã®ãƒªã‚½ãƒ¼ã‚¹ã®å±•é–‹ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "“%sâ€ã®ãƒªã‚½ãƒ¼ã‚¹ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "入力ストリームã¯ã‚·ãƒ¼ã‚¯ã‚’実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"用法:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:706 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND 対象ã®ã‚³ãƒžãƒ³ãƒ‰ (ä»»æ„)\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[パス]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr "" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:911 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "スキーマ“%sâ€ãŒã‚りã¾ã›ã‚“\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "スキーマ“%sâ€ã¯å†é…ç½®å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“ (ãƒ‘ã‚¹ã¯æŒ‡å®šã§ãã¾ã›ã‚“)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "スキーマ“%sâ€ã¯å†é…ç½®å¯èƒ½ã§ã™ (パスを指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "パスãŒç©ºã§ã™ã€‚\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "パスã®å…ˆé ­ã¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ (/) ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "ãƒ‘ã‚¹ã®æœ«å°¾ã¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ (/) ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "パスã«ã¯é€£ç¶šã™ã‚‹ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ (//) ã‚’å«ã‚られã¾ã›ã‚“\n" + +#: gio/gsettings-tool.c:541 +msgid "The provided value is outside of the valid range\n" +msgstr "指定ã—ãŸå€¤ã¯æœ‰åйãªç¯„囲内ã«ã‚りã¾ã›ã‚“\n" + +#: gio/gsettings-tool.c:548 +msgid "The key is not writable\n" +msgstr "指定ã®ã‚­ãƒ¼ã¯æ›¸ãè¾¼ã¿å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“\n" + +#: gio/gsettings-tool.c:584 +msgid "List the installed (non-relocatable) schemas" +msgstr "インストール済ã¿ã® (å†é…ç½®å¯èƒ½ã§ãªã„) スキーマã®ä¸€è¦§ã‚’表示ã™ã‚‹" + +#: gio/gsettings-tool.c:590 +msgid "List the installed relocatable schemas" +msgstr "インストール済ã¿ã®å†é…ç½®å¯èƒ½ãªã‚¹ã‚­ãƒ¼ãƒžã®ä¸€è¦§ã‚’表示ã™ã‚‹" + +#: gio/gsettings-tool.c:596 +msgid "List the keys in SCHEMA" +msgstr "SCHEMA 内ã®ã‚­ãƒ¼ã®ä¸€è¦§ã‚’表示ã™ã‚‹" + +#: gio/gsettings-tool.c:597 gio/gsettings-tool.c:603 gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:602 +msgid "List the children of SCHEMA" +msgstr "SCHEMA ã®ã‚µãƒ–スキーマã®ä¸€è¦§ã‚’表示ã™ã‚‹" + +#: gio/gsettings-tool.c:608 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"キーã¨å€¤ã®ä¸€è¦§ã‚’å†å¸°çš„ã«è¡¨ç¤ºã™ã‚‹\n" +"SCHEMA を指定ã—ãªã„å ´åˆã€ã™ã¹ã¦ã®ã‚­ãƒ¼ã«å¯¾ã—ã¦ä¸€è¦§ã‚’表示ã™ã‚‹\n" + +#: gio/gsettings-tool.c:610 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:615 +msgid "Get the value of KEY" +msgstr "KEY ã®å€¤ã‚’å–å¾—ã™ã‚‹" + +#: gio/gsettings-tool.c:616 gio/gsettings-tool.c:622 gio/gsettings-tool.c:628 +#: gio/gsettings-tool.c:640 gio/gsettings-tool.c:652 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:621 +msgid "Query the range of valid values for KEY" +msgstr "KEY ã®å€¤ã®æœ‰åйãªç¯„囲を確èªã™ã‚‹" + +#: gio/gsettings-tool.c:627 +msgid "Query the description for KEY" +msgstr "KEY ã®èª¬æ˜Žã‚’確èªã™ã‚‹" + +#: gio/gsettings-tool.c:633 +msgid "Set the value of KEY to VALUE" +msgstr "KEY ã®å€¤ã‚’ VALUE ã«è¨­å®šã™ã‚‹" + +#: gio/gsettings-tool.c:634 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:639 +msgid "Reset KEY to its default value" +msgstr "KEY をデフォルト値ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹" + +#: gio/gsettings-tool.c:645 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "SCHEMA 内ã®ã™ã¹ã¦ã®ã‚­ãƒ¼ã‚’デフォルト値ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹" + +#: gio/gsettings-tool.c:651 +msgid "Check if KEY is writable" +msgstr "KEY ãŒæ›¸ãè¾¼ã¿å¯èƒ½ã‹ç¢ºèªã™ã‚‹" + +#: gio/gsettings-tool.c:657 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"KEY ã®å€¤ãŒå¤‰æ›´ã•れるã®ã‚’監視ã—ã¾ã™ã€‚\n" +"KEY を指定ã—ãªã„å ´åˆã€SCHEMA 内ã®ã™ã¹ã¦ã®ã‚­ãƒ¼ã‚’監視ã—ã¾ã™ã€‚\n" +"^C ã§ç›£è¦–ã‚’æ­¢ã‚ã¾ã™ã€‚\n" + +#: gio/gsettings-tool.c:660 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: gio/gsettings-tool.c:672 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"用法:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"コマンド:\n" +" help ã“ã®æƒ…報を表示ã™ã‚‹\n" +" list-schemas インストール済ã¿ã®ã‚¹ã‚­ãƒ¼ãƒžã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +" list-relocatable-schemas å†é…ç½®å¯èƒ½ãªã‚¹ã‚­ãƒ¼ãƒžã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +" list-keys スキーマ内ã®ã‚­ãƒ¼ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +" list-children 指定ã—ãŸã‚¹ã‚­ãƒ¼ãƒžã®ã‚µãƒ–スキーマã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +" list-recursively キーã¨å€¤ã®ä¸€è¦§ã‚’å†å¸°çš„ã«è¡¨ç¤ºã™ã‚‹\n" +" range キーã®å€¤ã®æœ‰åйãªç¯„囲を確èªã™ã‚‹\n" +" describe キーã®èª¬æ˜Žã‚’確èªã™ã‚‹\n" +" get キーã®å€¤ã‚’å–å¾—ã™ã‚‹\n" +" set キーã®å€¤ã‚’設定ã™ã‚‹\n" +" reset キーã®å€¤ã‚’リセットã™ã‚‹\n" +" reset-recursively 指定ã—ãŸã‚¹ã‚­ãƒ¼ãƒžã®ã™ã¹ã¦ã®å€¤ã‚’リセットã™ã‚‹\n" +" writable ã‚­ãƒ¼ãŒæ›¸ãè¾¼ã¿å¯èƒ½ã‹ç¢ºèªã™ã‚‹\n" +" monitor 変更を監視ã™ã‚‹\n" +"\n" +"“gsettings help COMMANDâ€ã§è©³ç´°ãªãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" +"\n" + +#: gio/gsettings-tool.c:696 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"用法:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:702 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR 追加スキーマを検索ã™ã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n" + +#: gio/gsettings-tool.c:710 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA スキーマå\n" +" PATH å†é…ç½®å¯èƒ½ãªã‚¹ã‚­ãƒ¼ãƒžã®å ´åˆã€ãã®ãƒ‘ス\n" + +#: gio/gsettings-tool.c:715 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY スキーマ内ã®ã‚­ãƒ¼ (ä»»æ„)\n" + +#: gio/gsettings-tool.c:719 +msgid " KEY The key within the schema\n" +msgstr " KEY スキーマ内ã®ã‚­ãƒ¼\n" + +#: gio/gsettings-tool.c:723 +msgid " VALUE The value to set\n" +msgstr " VALUE 設定ã™ã‚‹å€¤\n" + +#: gio/gsettings-tool.c:778 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "'%s' ã‹ã‚‰ã‚¹ã‚­ãƒ¼ãƒžã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: gio/gsettings-tool.c:790 +msgid "No schemas installed\n" +msgstr "スキーマãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“\n" + +#: gio/gsettings-tool.c:869 +msgid "Empty schema name given\n" +msgstr "スキーマåãŒç©ºã§ã™\n" + +#: gio/gsettings-tool.c:924 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "キー“%sâ€ãŒã‚りã¾ã›ã‚“\n" + +#: gio/gsocket.c:413 +msgid "Invalid socket, not initialized" +msgstr "åˆæœŸåŒ–ã•れã¦ã„ãªã„䏿­£ãªã‚½ã‚±ãƒƒãƒˆã§ã™" + +#: gio/gsocket.c:420 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "䏿­£ãªã‚½ã‚±ãƒƒãƒˆã§ã™ã€‚åˆæœŸåŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:428 +msgid "Socket is already closed" +msgstr "ソースã¯ã™ã§ã«é–‰ã˜ã‚‰ã‚Œã¦ã„ã¾ã™" + +#: gio/gsocket.c:443 gio/gsocket.c:3190 gio/gsocket.c:4420 gio/gsocket.c:4478 +msgid "Socket I/O timed out" +msgstr "ソケット I/O ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ" + +#: gio/gsocket.c:578 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ファイルディスクリプター GSocket を作æˆ: %s" + +#: gio/gsocket.c:607 gio/gsocket.c:671 gio/gsocket.c:678 +#, c-format +msgid "Unable to create socket: %s" +msgstr "ソケットを作æˆã§ãã¾ã›ã‚“: %s" + +#: gio/gsocket.c:671 +msgid "Unknown family was specified" +msgstr "" + +#: gio/gsocket.c:678 +msgid "Unknown protocol was specified" +msgstr "䏿˜Žãªãƒ—ãƒ­ãƒˆã‚³ãƒ«ãŒæŒ‡å®šã•れã¾ã—ãŸ" + +#: gio/gsocket.c:1169 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: gio/gsocket.c:1186 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: gio/gsocket.c:1993 +#, c-format +msgid "could not get local address: %s" +msgstr "ローカルã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: gio/gsocket.c:2039 +#, c-format +msgid "could not get remote address: %s" +msgstr "リモートã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: gio/gsocket.c:2105 +#, c-format +msgid "could not listen: %s" +msgstr "listen ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: gio/gsocket.c:2209 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "アドレス %s ã¸ã® bind 中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:2385 gio/gsocket.c:2422 gio/gsocket.c:2532 gio/gsocket.c:2557 +#: gio/gsocket.c:2620 gio/gsocket.c:2678 gio/gsocket.c:2696 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "マルãƒã‚­ãƒ£ã‚¹ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ã¸ã® join 中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:2386 gio/gsocket.c:2423 gio/gsocket.c:2533 gio/gsocket.c:2558 +#: gio/gsocket.c:2621 gio/gsocket.c:2679 gio/gsocket.c:2697 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "マルãƒã‚­ãƒ£ã‚¹ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰ã® leave 中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:2387 +msgid "No support for source-specific multicast" +msgstr "SSM (é€ä¿¡å…ƒç‰¹å®šãƒžãƒ«ãƒã‚­ãƒ£ã‚¹ãƒˆ) ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gsocket.c:2534 +msgid "Unsupported socket family" +msgstr "" + +#: gio/gsocket.c:2559 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2583 +#, c-format +msgid "Interface name too long" +msgstr "インターフェースåãŒé•·ã™ãŽã¾ã™" + +#: gio/gsocket.c:2596 gio/gsocket.c:2646 +#, c-format +msgid "Interface not found: %s" +msgstr "インターフェースãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: gio/gsocket.c:2622 +msgid "No support for IPv4 source-specific multicast" +msgstr "IPv4 SSM (é€ä¿¡å…ƒç‰¹å®šãƒžãƒ«ãƒã‚­ãƒ£ã‚¹ãƒˆ) ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gsocket.c:2680 +msgid "No support for IPv6 source-specific multicast" +msgstr "IPv6 SSM (é€ä¿¡å…ƒç‰¹å®šãƒžãƒ«ãƒã‚­ãƒ£ã‚¹ãƒˆ) ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gsocket.c:2889 +#, c-format +msgid "Error accepting connection: %s" +msgstr "接続を accept ã™ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:3015 +msgid "Connection in progress" +msgstr "接続中" + +#: gio/gsocket.c:3066 +msgid "Unable to get pending error: " +msgstr "エラーをペンディングã§ãã¾ã›ã‚“: " + +#: gio/gsocket.c:3255 +#, c-format +msgid "Error receiving data: %s" +msgstr "データå—信中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:3452 +#, c-format +msgid "Error sending data: %s" +msgstr "データé€ä¿¡ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:3639 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "" + +#: gio/gsocket.c:3720 +#, c-format +msgid "Error closing socket: %s" +msgstr "ソケットを閉ã˜ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:4413 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ã‚½ã‚±ãƒƒãƒˆã®æŒ‡å®šã•れãŸçŠ¶æ…‹ã‚’ wait: %s" + +#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833 +#, c-format +msgid "Unable to send message: %s" +msgstr "メッセージをé€ä¿¡ã§ãã¾ã›ã‚“: %s" + +#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834 +msgid "Message vectors too large" +msgstr "" + +#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084 +#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304 +#, c-format +msgid "Error sending message: %s" +msgstr "メッセージã®é€ä¿¡ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:5026 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage 㯠Windows ã§ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797 +#, c-format +msgid "Error receiving message: %s" +msgstr "メッセージã®å—信中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "" + +#: gio/gsocket.c:6136 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "ã“ã® OS ã§ã¯ g_socket_get_credentials ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "プロキシサーãƒãƒ¼ %s ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "接続ã§ãã¾ã›ã‚“ã§ã—ãŸ: " + +#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" + +#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "プロキシã®ãƒ—ロトコル“%sâ€ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。" + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "å—信を待㤠Listener ã¯ã™ã§ã«é–‰ã˜ã¦ã„ã¾ã™" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "追加ã•れãŸã‚½ã‚±ãƒƒãƒˆã¯é–‰ã˜ã¦ã„ã¾ã™" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 㯠IPv6 アドレス“%sâ€ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 プロトコルã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åãŒé•·ã™ãŽã¾ã™" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 プロトコルã®ãƒ›ã‚¹ãƒˆå“%sâ€ãŒé•·ã™ãŽã¾ã™" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "サーãƒãƒ¼ãŒ SOCKSv4 プロキシサーãƒãƒ¼ã§ã¯ã‚りã¾ã›ã‚“。" + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "サーãƒãƒ¼ãŒ SOCKSv5 プロキシサーãƒãƒ¼ã§ã¯ã‚りã¾ã›ã‚“。" + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 プロキシã¯èªè¨¼ãŒå¿…è¦ã§ã™ã€‚" + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 プロキシ㯠GLib ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„èªè¨¼æ–¹å¼ãŒå¿…è¦ã§ã™ã€‚" + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 プロトコルã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åã¾ãŸã¯ãƒ‘スワードãŒé•·ã™ãŽã¾ã™ã€‚" + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"ユーザーåã¾ãŸã¯ãƒ‘スワードã«èª¤ã‚ŠãŒã‚ã‚‹ãŸã‚ã€SOCKSv5 èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "SOCKSv5 プロトコルã®ãƒ›ã‚¹ãƒˆå“%sâ€ãŒé•·ã™ãŽã¾ã™" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 プロキシサーãƒãƒ¼ãŒä¸æ˜Žãªã‚¢ãƒ‰ãƒ¬ã‚¹å½¢å¼ã‚’使用ã—ã¦ã„ã¾ã™ã€‚" + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "SOCKSv5 プロキシサーãƒãƒ¼ã®å†…部エラーã§ã™ã€‚" + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "ルールセット㧠SOCKSv5 接続ãŒè¨±å¯ã•れã¦ã„ã¾ã›ã‚“。" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 プロキシãŒâ€œconnectâ€ã‚³ãƒžãƒ³ãƒ‰ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。" + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 ãƒ—ãƒ­ã‚­ã‚·ãŒæŒ‡å®šã—ãŸã‚¢ãƒ‰ãƒ¬ã‚¹å½¢å¼ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。" + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "䏿˜Žãª SOCKSv5 プロキシエラーã§ã™ã€‚" + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "å­ãƒ—ロセスã¨ã®é€šä¿¡ç”¨ãƒ‘イプã®ä½œæˆã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "ã“ã®ãƒ—ラットフォームã¯ãƒ‘イプをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã® GThemedIcon ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "æ­£ã—ã„アドレスãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "“%sâ€ã®é€†å¼•ã中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "一時的ã«â€œ%sâ€ã‚’解決ã§ãã¾ã›ã‚“" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "“%sâ€ã®è§£æ±ºä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#: gio/gtlscertificate.c:431 +msgid "No PEM-encoded private key found" +msgstr "PEM ã§ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã•れãŸç§˜å¯†éµãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gtlscertificate.c:441 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM ã§ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã•れãŸç§˜å¯†éµã‚’復å·ã§ãã¾ã›ã‚“" + +#: gio/gtlscertificate.c:452 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM ã§ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã•れãŸç§˜å¯†éµã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gtlscertificate.c:479 +msgid "No PEM-encoded certificate found" +msgstr "PEM ã§ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã•れãŸè¨¼æ˜Žæ›¸ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gtlscertificate.c:488 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM ã§ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã•れãŸè¨¼æ˜Žæ›¸ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: gio/gtlscertificate.c:844 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"ã“れã¯ã€ã‚ãªãŸã®ã‚¢ã‚¯ã‚»ã‚¹ãŒãƒ­ãƒƒã‚¯ã‚¢ã‚¦ãƒˆã•れるå‰ã®ã€æ­£ã—ã„パスワードを入力ã™ã‚‹" +"æœ€å¾Œã®æ©Ÿä¼šã§ã™ã€‚" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"ã“れã¾ã§å…¥åŠ›ã—ãŸãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã¯æ­£ã—ãã‚りã¾ã›ã‚“。ã“ã®ã¾ã¾æ­£ã—ããªã„パスワードを" +"入力ã—ç¶šã‘ã‚‹ã¨ã€ã‚¢ã‚¯ã‚»ã‚¹ãŒãƒ­ãƒƒã‚¯ã‚¢ã‚¦ãƒˆã•れã¾ã™ã€‚" + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "入力ã—ãŸãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã¯æ­£ã—ãã‚りã¾ã›ã‚“。" + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "コントロールメッセージを一ã¤å¾…ã¡å—ã‘ã¦ã„ã¾ã—ãŸãŒã€%d 個å—ä¿¡ã—ã¾ã—ãŸ" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "想定ã—ã¦ã„ãªã„種類ã®è£œåŠ©ãƒ‡ãƒ¼ã‚¿ã§ã™" + +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "" +"ファイルディスクリプターを一ã¤å¾…ã¡å—ã‘ã¦ã„ã¾ã—ãŸãŒã€%d 個å—ä¿¡ã—ã¾ã—ãŸ\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "䏿­£ãªãƒ•ァイルディスクリプターをå—ã‘ã¨ã‚Šã¾ã—ãŸ" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "クレデンシャルé€ä¿¡ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"ソケット㮠SO_PASSCRED ãŒæœ‰åйã«ãªã£ã¦ã„ã‚‹ã‹ã©ã†ã‹ç¢ºèªä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—" +"ãŸ: %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED を有効ã«ã™ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "コントロールメッセージを待ã¡å—ã‘ã¦ã„ã¾ã›ã‚“ã§ã—ãŸãŒã€%d 個å—ä¿¡ã—ã¾ã—ãŸ" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED ã®ç„¡åŠ¹åŒ–ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ファイルディスクリプターã®èª­ã¿å–り中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ファイルディスクリプターを閉ã˜ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gunixmounts.c:2785 gio/gunixmounts.c:2838 +msgid "Filesystem root" +msgstr "ファイルシステムã®ãƒ«ãƒ¼ãƒˆ" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ファイルディスクリプターã¸ã®æ›¸ãè¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gunixsocketaddress.c:244 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"抽象化ã•れ㟠UNIX ドメインソケットã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯ã“ã®ã‚·ã‚¹ãƒ†ãƒ ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦" +"ã„ã¾ã›ã‚“" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "ボリューム㯠eject を実装ã—ã¦ã„ã¾ã›ã‚“" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "ボリューム㯠eject ã¾ãŸã¯ eject_with_operation を実装ã—ã¦ã„ã¾ã›ã‚“" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "ãƒãƒ³ãƒ‰ãƒ«ã‹ã‚‰èª­ã¿è¾¼ã‚€ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "ãƒãƒ³ãƒ‰ãƒ«ã‚’é–‰ã˜ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "ãƒãƒ³ãƒ‰ãƒ«ã«æ›¸ã込むã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "メモリãŒè¶³ã‚Šã¾ã›ã‚“" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "内部エラー: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "無効ãªåœ§ç¸®ãƒ‡ãƒ¼ã‚¿ã§ã™" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "アドレスを表示ã™ã‚‹" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "シェルモードã§ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’表示ã™ã‚‹" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "dbus サービスを実行ã™ã‚‹" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "引数ãŒé–“é•ã£ã¦ã„ã¾ã™\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "“%sâ€ã¯â€œ%sâ€ã¨ã„ã†è¦ç´ ã«å¯¾ã—ã¦æƒ³å®šå¤–ã®å±žæ€§ã§ã™" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "“%sâ€ã¨ã„ã†å±žæ€§ã¯â€œ%sâ€ã¨ã„ã†è¦ç´ ã«ã¯ã‚りã¾ã›ã‚“" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "“%sâ€ã¯æƒ³å®šå¤–ã®ã‚¿ã‚°ã§ã™ (想定ã—ã¦ã„ãŸã‚¿ã‚°ã¯â€œ%sâ€)" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "“%sâ€ã¯â€œ%sâ€ã®ä¸­ã§ã¯æƒ³å®šå¤–ã®ã‚¿ã‚°ã§ã™" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "ãƒ–ãƒƒã‚¯ãƒžãƒ¼ã‚¯ãƒ•ã‚¡ã‚¤ãƒ«ã®æ—¥ä»˜/時間‘%s’ã¯ä¸æ­£ã§ã™" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ­£ã—ã„ブックマークファイルãŒã‚りã¾ã›ã‚“" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "URI “%sâ€ã®ãƒ–ックマークã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "URI “%sâ€ã®ãƒ–ックマークãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "URI “%sâ€ã®ãƒ–ックマーク㧠MIME åž‹ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "URI “%sâ€ã®ãƒ–ックマークã«ã¯ãƒ—ライベートã§ã¯ãªã„フラグãŒå®šç¾©ã•れã¦ã„ã¾ã™" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI “%sâ€ã®ãƒ–ックマークã«ã‚°ãƒ«ãƒ¼ãƒ—ãŒã‚りã¾ã›ã‚“" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "アプリケーション“%sâ€ã¯â€œ%sâ€ã¨ã„ã†ãƒ–ックマークを登録ã—ã¦ã„ã¾ã›ã‚“" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "コマンドラインã®â€œ%sâ€ã‚’“%sâ€ã¨ã„ㆠURI ã«å±•é–‹ã§ãã¾ã›ã‚“" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "変æ›ã™ã‚‹å…¥åŠ›ã«è¡¨ç¾ã§ããªã„文字ãŒã‚りã¾ã™" + +#: glib/gconvert.c:495 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "å…¥åŠ›ã®æœ€å¾Œã«ä¸å®Œå…¨ãªæ–‡å­—シーケンスãŒã‚りã¾ã™" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "フォールãƒãƒƒã‚¯â€œ%sâ€ã‚’“%sâ€ã¨ã„ã†æ–‡å­—集åˆã«å¤‰æ›ã§ãã¾ã›ã‚“" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "変æ›ã™ã‚‹å…¥åŠ›ã«åŸ‹ã‚è¾¼ã¾ã‚ŒãŸ NUL ãƒã‚¤ãƒˆãŒã‚りã¾ã™" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "変æ›ã™ã‚‹å‡ºåŠ›ã«åŸ‹ã‚è¾¼ã¾ã‚ŒãŸ NUL ãƒã‚¤ãƒˆãŒã‚りã¾ã™" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "“%sâ€ã¯â€œfileâ€ã‚¹ã‚­ãƒ¼ãƒ ã®çµ¶å¯¾ URI ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "“#â€ã‚’å«ã‚“ã â€œ%sâ€ã¯æ­£ã—ã„ローカルファイル URI ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI “%sâ€ã¯æ­£ã—ãã‚りã¾ã›ã‚“" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI “%sâ€ã®ãƒ›ã‚¹ãƒˆåã¯æ­£ã—ãã‚りã¾ã›ã‚“" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI “%sâ€ã¯ä¸æ­£ãªã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字をå«ã‚“ã§ã„ã¾ã™" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "“%sâ€ã¯çµ¶å¯¾ãƒ‘スã§ã¯ã‚りã¾ã›ã‚“" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Yå¹´%m月%dæ—¥ %H時%M分%Sç§’" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%Y/%m/%d" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%p%I時%M分%Sç§’" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "1月" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "2月" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "3月" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "4月" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "5月" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "6月" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "7月" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "8月" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "9月" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "10月" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "11月" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "12月" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr " 1月" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr " 2月" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr " 3月" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr " 4月" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr " 5月" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr " 6月" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr " 7月" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr " 8月" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr " 9月" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "10月" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "11月" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "12月" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "月曜日" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "ç«æ›œæ—¥" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "水曜日" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "木曜日" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "金曜日" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "土曜日" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "日曜日" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "月" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ç«" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "æ°´" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "木" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "金" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "土" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "æ—¥" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "1月" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "2月" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "3月" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "4月" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "5月" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "6月" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "7月" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "8月" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "9月" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "10月" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "11月" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "12月" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr " 1月" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr " 2月" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr " 3月" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr " 4月" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr " 5月" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr " 6月" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr " 7月" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr " 8月" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr " 9月" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "10月" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "11月" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "12月" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "åˆå‰" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "åˆå¾Œ" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "ディレクトリ“%sâ€ã‚’é–‹ãã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "%lu ãƒã‚¤ãƒˆã‚’確ä¿ã§ãã¾ã›ã‚“ã§ã—㟠(ファイル“%sâ€ã®èª­ã¿è¾¼ã¿ã«å¿…è¦)" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "ファイル“%sâ€ã®èª­ã¿å–り中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "ファイル“%sâ€ã®ã‚µã‚¤ã‚ºãŒå¤§ãã™ãŽã¾ã™" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "ファイル“%sâ€ã‹ã‚‰ã®èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "ファイル“%sâ€ã‚’é–‹ãã®ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "ファイル“%sâ€ã®å±žæ€§ã‚’å–å¾—ã§ãã¾ã›ã‚“: fstat() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "ファイル“%sâ€ã‚’é–‹ã‘ã¾ã›ã‚“: fdopen() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"“%sâ€ã‹ã‚‰â€œ%sâ€ã«ãƒ•ァイルåを変更ã§ãã¾ã›ã‚“: g_rename() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "ファイル“%sâ€ã¸æ›¸ãè¾¼ã‚ã¾ã›ã‚“: write() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "ファイル“%sâ€ã¸æ›¸ãè¾¼ã‚ã¾ã›ã‚“: fsync() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "ファイル“%sâ€ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"既存ã®ãƒ•ァイル“%sâ€ã‚’削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: g_unlink() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "テンプレート“%sâ€ã¯ä¸æ­£ã§ã™ (“%sâ€ã‚’å«ã‚ãªã„ã“ã¨)" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "テンプレート“%sâ€ã« XXXXXX ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "シンボリックリンク“%sâ€ã®èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "“%sâ€ã‹ã‚‰â€œ%sâ€ã¸å¤‰æ›ã™ã‚‹ã‚³ãƒ³ãƒãƒ¼ã‚¿ãƒ¼ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string ã§ã¯ raw モードã§èª­ã¿å–れã¾ã›ã‚“" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "変æ›ã•れã¦ã„ãªã„データãŒèª­ã¿è¾¼ã¿ãƒãƒƒãƒ•ã‚¡ãƒ¼ã«æ®‹ã£ã¦ã„ã¾ã™" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "ãƒãƒ£ãƒ³ãƒãƒ«ãŒä¸å®Œå…¨ãªæ–‡å­—ã§çµ‚ã‚ã£ã¦ã„ã¾ã™" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end ã§ã¯ raw モードã§èª­ã¿å–れã¾ã›ã‚“" + +#: glib/gkeyfile.c:791 +msgid "Valid key file could not be found in search dirs" +msgstr "æ¤œç´¢ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ­£ã—ã„キーファイルãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" + +#: glib/gkeyfile.c:828 +msgid "Not a regular file" +msgstr "通常ã®ãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gkeyfile.c:1283 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"キーファイルã®è¡Œâ€œ%sâ€ãŒã‚­ãƒ¼/値ã®ãƒšã‚¢ã€ã‚°ãƒ«ãƒ¼ãƒ—ã€ã¾ãŸã¯ã‚³ãƒ¡ãƒ³ãƒˆã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gkeyfile.c:1340 +#, c-format +msgid "Invalid group name: %s" +msgstr "グループåãŒä¸æ­£ã§ã™: %s" + +#: glib/gkeyfile.c:1362 +msgid "Key file does not start with a group" +msgstr "キーファイルãŒã‚°ãƒ«ãƒ¼ãƒ—ã§å§‹ã¾ã£ã¦ã„ã¾ã›ã‚“" + +#: glib/gkeyfile.c:1388 +#, c-format +msgid "Invalid key name: %s" +msgstr "キーã®åå‰ãŒä¸æ­£ã§ã™: %s" + +#: glib/gkeyfile.c:1415 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "キーファイルã«ã‚µãƒãƒ¼ãƒˆã—ã¦ãªã„エンコーディング“%sâ€ãŒã‚りã¾ã™" + +#: glib/gkeyfile.c:1664 glib/gkeyfile.c:1837 glib/gkeyfile.c:3287 +#: glib/gkeyfile.c:3351 glib/gkeyfile.c:3481 glib/gkeyfile.c:3613 +#: glib/gkeyfile.c:3759 glib/gkeyfile.c:3994 glib/gkeyfile.c:4061 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "キーファイルã«ã‚°ãƒ«ãƒ¼ãƒ—“%sâ€ãŒã‚りã¾ã›ã‚“" + +#: glib/gkeyfile.c:1792 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "キーファイルã«ã‚°ãƒ«ãƒ¼ãƒ—“%2$sâ€ã®ã‚­ãƒ¼â€œ%1$sâ€ãŒã‚りã¾ã›ã‚“" + +#: glib/gkeyfile.c:1954 glib/gkeyfile.c:2070 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "キーファイルã®ã‚­ãƒ¼â€œ%sâ€ã®å€¤â€œ%sâ€ãŒ UTF-8 ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gkeyfile.c:1974 glib/gkeyfile.c:2090 glib/gkeyfile.c:2529 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "キーファイルã«è§£é‡ˆã§ããªã„値をæŒã¤ã‚­ãƒ¼â€œ%sâ€ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚" + +#: glib/gkeyfile.c:2747 glib/gkeyfile.c:3116 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"グループ“%2$sâ€ã®ã‚­ãƒ¼ãƒ•ァイルã«è§£é‡ˆã§ããªã„値をæŒã¤ã‚­ãƒ¼â€œ%1$sâ€ãŒå«ã¾ã‚Œã¦ã„ã¾" +"ã™ã€‚" + +#: glib/gkeyfile.c:2825 glib/gkeyfile.c:2902 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" + +#: glib/gkeyfile.c:4304 +msgid "Key file contains escape character at end of line" +msgstr "キーファイルã®è¡Œæœ«ã«ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字ãŒå«ã¾ã‚Œã¦ã„ã¾ã™" + +#: glib/gkeyfile.c:4326 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "キーファイルã«ä¸æ­£ãªã‚¨ã‚¹ã‚±ãƒ¼ãƒ—シーケンス“%sâ€ãŒå«ã¾ã‚Œã¦ã„ã¾ã™" + +#: glib/gkeyfile.c:4470 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "値“%sâ€ã‚’数値ã¨ã—ã¦è§£é‡ˆã§ãã¾ã›ã‚“。" + +#: glib/gkeyfile.c:4484 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Integer 値“%sâ€ã¯ç¯„囲外ã®å€¤ã§ã™" + +#: glib/gkeyfile.c:4517 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "値“%sâ€ã‚’ Float ã¨ã—ã¦è§£é‡ˆã§ãã¾ã›ã‚“。" + +#: glib/gkeyfile.c:4556 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "値“%sâ€ã‚’è«–ç†å€¤ã¨ã—ã¦è§£é‡ˆã§ãã¾ã›ã‚“。" + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "ファイル“%s%s%s%sâ€ã®å±žæ€§ã‚’å–å¾—ã§ãã¾ã›ã‚“: fstat() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s をマップã§ãã¾ã›ã‚“: mmap() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "ファイル“%sâ€ã‚’é–‹ã‘ã¾ã›ã‚“: open() ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "%d 行㮠%d 文字目ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "åå‰ã« UTF-8 ã¨ã—ã¦æ­£ã—ããªã„文字列ãŒã‚りã¾ã™ — “%sâ€ã¯ä¸æ­£ã§ã™" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%sâ€ã¯æ­£ã—ã„åå‰ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%sâ€ã¯æ­£ã—ã„åå‰ã§ã¯ã‚りã¾ã›ã‚“: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d 行目ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"“%-.*sâ€ã‚’è§£æžã§ãã¾ã›ã‚“。文字å‚ç…§ã®ç¯„å›²å†…ã®æ•°å­—ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ (例: " +"ê) æ•°å­—ãŒå¤§ãã™ãŽã‚‹å¯èƒ½æ€§ã‚‚ã‚りã¾ã™" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"文字å‚ç…§ãŒã‚»ãƒŸã‚³ãƒ­ãƒ³ã§çµ‚ã‚ã£ã¦ã„ã¾ã›ã‚“。エンティティã§ã‚‚ãªã„ã®ã«ã‚¢ãƒ³ãƒ‘サンド" +"を使用ã—ãŸã®ã§ã¯ãªã„ã§ã—ょã†ã‹ã€‚アンパサンド㯠& ã®ã‚ˆã†ã«ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã—ã¦ã" +"ã ã•ã„" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "文字å‚照“%-.*sâ€ãŒä½¿ç”¨å¯èƒ½ãªæ–‡å­—をエンコードã—ã¦ã„ã¾ã›ã‚“" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"空ã®ã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£â€œ&;â€ãŒã‚りã¾ã™ã€‚æ­£ã—ã„エンティティ: & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "エンティティå“%-.*sâ€ã¯ä¸æ˜Žã§ã™" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"エンティティãŒã‚»ãƒŸã‚³ãƒ­ãƒ³ã§çµ‚ã‚ã£ã¦ã¾ã›ã‚“。エンティティã§ã‚‚ãªã„ã®ã«ã‚¢ãƒ³ãƒ‘サン" +"ドを使用ã—ãŸã®ã§ã¯ãªã„ã§ã—ょã†ã‹ã€‚アンパサンド㯠& ã®ã‚ˆã†ã«ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã—ã¦" +"ãã ã•ã„" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "ドキュメントã¯è¦ç´  (例 ) ã§å§‹ã¾ã£ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%sâ€ã¯â€œ<â€ã«ç¶šã文字ã¨ã—ã¦æ­£ã—ãã‚りã¾ã›ã‚“。ãŠãらãè¦ç´ åã®é–‹å§‹ã«ãªã£ã¦ã„ã¾ã›" +"ã‚“" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"ãŠã‹ã—ãªæ–‡å­—“%sâ€ãŒã‚りã¾ã™ã€‚空ã®è¦ç´ ã®ã‚¿ã‚°â€œ%sâ€ã®æœ€å¾Œã¯â€œ>â€ã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "è¦ç´ â€œ%sâ€ã®å±žæ€§ãŒå¤šã™ãŽã¾ã™" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "ãŠã‹ã—ãªæ–‡å­—“%sâ€ã§ã™ã€‚属性å“%s†(è¦ç´ â€œ%sâ€) ã®å¾Œã«ã¯â€œ=â€ãŒå¿…è¦ã§ã™" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ãŠã‹ã—ãªæ–‡å­—“%sâ€ã§ã™ã€‚è¦ç´ â€œ%sâ€ã®é–‹å§‹ã‚¿ã‚°ã®æœ«å°¾ã¯â€œ>â€ã¾ãŸã¯â€œ/â€ã§ãªãã¦ã¯ãªã‚Šã¾" +"ã›ã‚“。ã‚ã‚‹ã„ã¯å±žæ€§ã«ãªã‚Šã¾ã™ã€‚ãŠã‹ã—ãªæ–‡å­—を属性åã«ä½¿ç”¨ã—ãŸã®ã‹ã‚‚ã—れã¾ã›ã‚“" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"ãŠã‹ã—ãªæ–‡å­—“%sâ€ã§ã™ã€‚属性“%s†(è¦ç´ â€œ%sâ€) ã®å€¤ã‚’設定ã™ã‚‹ã«ã¯ç­‰å·è¨˜å·ã®å¾Œã¯å¼•" +"用記å·ã§å§‹ã¾ã£ã¦ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%sâ€ã¯é–‰ã˜è¦ç´ å“%sâ€ã«ç¶šã文字ã¨ã—ã¦ã¯æ­£ã—ãã‚りã‚ã¾ã›ã‚“。“>â€ã®ã¿ãŒä½¿ç”¨ã§ãã¾" +"ã™" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "è¦ç´ â€œ%sâ€ã¯é–‰ã˜ã¦ã„ã¾ã™ã€‚è¦ç´ ã¯ä½•ã‚‚é–‹ã‹ã‚Œã¦ã¾ã›ã‚“" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "è¦ç´ â€œ%sâ€ãŒé–‰ã˜ã¾ã—ãŸã€‚ã—ã‹ã—ç¾åœ¨é–‹ã„ã¦ã„ã‚‹è¦ç´ ã¯â€œ%sâ€ã§ã™" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "ドキュメントãŒç©ºã‹ã€ç©ºç™½ã ã‘ãŒå«ã¾ã‚Œã¦ã„ã¾ã™" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "ドキュメントãŒé–‹ãカギカッコ“<â€ã®ç›´å¾Œã§çµ‚了ã—ã¦ã„ã¾ã™" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"ドキュメントãŒçªç„¶çµ‚了ã—ã¦ã„ã¾ã™ã€‚è¦ç´ ãŒé–‹ã„ãŸã¾ã¾ã§ã™ã€‚最後ã«é–‹ã„ãŸè¦ç´ " +"ã¯â€œ%sâ€ã§ã™" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ドキュメントã¯ã‚¿ã‚° <%s/> ã§çµ‚了ã—ã¦ã„ã‚‹ã‚‚ã®ã¨æƒ³å®šã—ã¦ã„ã¾ã—ãŸãŒã€çªç„¶çµ‚了ã—ã¦" +"ã„ã¾ã™" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "è¦ç´ åã®é€”中ã§ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆãŒçªç„¶çµ‚了ã—ã¦ã„ã¾ã™" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "属性åã®é€”中ã§ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆãŒçªç„¶çµ‚了ã—ã¦ã„ã¾ã™" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "è¦ç´ ã®é–‹å§‹ã‚¿ã‚°ã®é€”中ã§ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆãŒçªç„¶çµ‚了ã—ã¦ã„ã¾ã™" + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"属性åã®å¾Œã«ã‚ã‚‹ç­‰å·è¨˜å·ã®æ¬¡ã§ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆãŒçªç„¶çµ‚了ã—ã¦ã„ã¾ã™: 属性値ãŒã‚り" +"ã¾ã›ã‚“" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ドキュメントãŒå±žæ€§å€¤ã®é€”中ã§çªç„¶çµ‚了ã—ã¦ã„ã¾ã™" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "ドキュメントãŒè¦ç´ â€œ%sâ€ã®é–‰ã˜ã‚¿ã‚°ã®é€”中ã§çªç„¶çµ‚了ã—ã¦ã„ã¾ã™" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "ドキュメントãŒé–‹ã‹ã‚Œã¦ã„ãªã„è¦ç´ ã®é–‰ã˜ã‚¿ã‚°ã®é€”中ã§çªç„¶çµ‚了ã—ã¦ã„ã¾ã™" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"ドキュメントãŒã‚³ãƒ¡ãƒ³ãƒˆã¾ãŸã¯ãƒ—ロセシング指示å­ã®é€”中ã§çªç„¶çµ‚了ã—ã¦ã„ã¾ã™" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[オプション…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "ヘルプã®ã‚ªãƒ—ション:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "ヘルプã®ã‚ªãƒ—ションを表示ã™ã‚‹" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "ヘルプã®ã‚ªãƒ—ションをã™ã¹ã¦è¡¨ç¤ºã™ã‚‹" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "アプリケーションã®ã‚ªãƒ—ション:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "オプション:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "%2$s ã®æ•´æ•°å€¤â€œ%1$sâ€ã‚’è§£æžã§ãã¾ã›ã‚“" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "%2$s ã®æ•´æ•°å€¤â€œ%1$sâ€ã¯ç¯„囲外ã®å€¤ã§ã™" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "%2$s ã®å®Ÿæ•°å€¤â€œ%1$sâ€ã‚’è§£æžã§ãã¾ã›ã‚“" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "%2$s ã®å®Ÿæ•°å€¤â€œ%1$sâ€ã¯ç¯„囲外ã®å€¤ã§ã™" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "オプション %s ã®è§£æžä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "%s ã®å¼•æ•°ãŒã‚りã¾ã›ã‚“" + +#: glib/goption.c:2185 +#, c-format +msgid "Unknown option %s" +msgstr "%s ã¯ä¸æ˜Žãªã‚ªãƒ—ションã§ã™" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "䏿­£ãªã‚ªãƒ–ジェクトã§ã™" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "内部エラーã¾ãŸã¯ä¸æ­£ãªã‚ªãƒ–ジェクトã§ã™" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "メモリãŒè¶³ã‚Šã¾ã›ã‚“" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "ãƒãƒƒã‚¯ãƒˆãƒ©ãƒƒã‚¯å‡¦ç†ã®ä¸Šé™ã«é”ã—ã¾ã—ãŸ" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "パターンã«å«ã¾ã‚Œã¦ã„るアイテムã¯éƒ¨åˆ†ãƒžãƒƒãƒãƒ³ã‚°ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "内部エラー" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "æ¡ä»¶ã®å¾Œæ–¹å‚ç…§ã¯éƒ¨åˆ†ãƒžãƒƒãƒãƒ³ã‚°ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "å†å¸°ã®ä¸Šé™ã«é”ã—ã¾ã—ãŸ" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "改行フラグã®é€£æºãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "䏿­£ãªã‚ªãƒ•セットã§ã™" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "å†å¸°ã®ãƒ«ãƒ¼ãƒ—ã§ã™" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "åŽŸå› ä¸æ˜Žã®ã‚¨ãƒ©ãƒ¼" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "パターンã®çµ‚端㫠\\ ãŒã‚りã¾ã™" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "パターンã®çµ‚端㫠\\c ãŒã‚りã¾ã™" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "\\ ã®å¾Œã«èªè­˜ã§ããªã„文字ãŒã‚りã¾ã™" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "釿Œ‡å®šå­ '{}' ã®ä¸­ã«ã‚る数値ã®é †ç•ªãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "釿Œ‡å®šå­ '{}' ã®ä¸­ã«ã‚る数値ãŒå¤§ãã™ãŽã¾ã™" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "文字クラスを表ã™çµ‚端文字 ']' ãŒã‚りã¾ã›ã‚“" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "文字クラスã®ä¸­ã«ç„¡åйãªã‚¨ã‚¹ã‚±ãƒ¼ãƒ—シーケンスãŒã‚りã¾ã™" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "æ–‡å­—ã‚¯ãƒ©ã‚¹ã§æ–‡å­—ã®é †ç•ªãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "繰り返ã™ã‚‚ã®ãŒã‚りã¾ã›ã‚“" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "想定外ã®ç¹°ã‚Šè¿”ã—ã§ã™" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "'(?' ã¾ãŸã¯ '(?-' ã®å¾Œã«èªè­˜ã§ããªã„文字ãŒã‚りã¾ã™" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX ã®åå‰ä»˜ãクラスã¯ã‚¯ãƒ©ã‚¹ã®å†…部ã§ã®ã¿åˆ©ç”¨ã§ãã¾ã™" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "終端文字㮠')' ãŒã‚りã¾ã›ã‚“" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "存在ã—ãªã„サブパターンã¸ã®å‚ç…§ã§ã™" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "コメントã®å¾Œã« ')' ãŒã‚りã¾ã›ã‚“" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "æ­£è¦è¡¨ç¾ãŒé•·ã™ãŽã¾ã™" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "メモリã®ç¢ºä¿ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "開始文字 '(' ãŒç„¡ã„終端文字 ')' ã§ã™" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "コードãŒã‚ªãƒ¼ãƒãƒ¼ãƒ•ローã—ã¾ã—ãŸ" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "'(?<' ã®å¾Œã«èªè­˜ã§ããªã„文字ãŒã‚りã¾ã™" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "後読㿠(lookbehind assertion) ãŒå›ºå®šé•·ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "'(?(' ã®å¾Œã«ä¸æ­£ãªå½¢å¼ã®æ•°å€¤ã¾ãŸã¯åå‰ãŒã‚りã¾ã™" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "æ¡ä»¶ã‚°ãƒ«ãƒ¼ãƒ—ã«äºŒã¤ä»¥ä¸Šã®ãƒ–ランãƒãŒã‚りã¾ã™" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "'(?R' ã¾ãŸã¯ '(?[+-]数値' ã®å¾Œã«ã¯ ')' ãŒç¶šãå¿…è¦ãŒã‚りã¾ã™" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "䏿˜Žãª POSIX ã®ã‚¯ãƒ©ã‚¹åã§ã™" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX ã§ã¯ç…§åˆé †åºã®è¦ç´ ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} ã®ä¸­ã«ã‚る文字値ãŒå¤§ãã™ãŽã¾ã™" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "æ¡ä»¶ã® '(?(0)' ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "後読ã¿ã®ã‚¢ã‚µãƒ¼ã‚·ãƒ§ãƒ³ã§ã¯ \\C を指定ã§ãã¾ã›ã‚“" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "次ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“: \\L, \\l, \\N{name}, \\U, \\u" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "繰り返ã—ã®å‘¼ã³å‡ºã—ãŒç„¡é™ãƒ«ãƒ¼ãƒ—ã«ãªã£ã¦ã„ã¾ã™" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "(?P ã®å¾Œã«èªè­˜ã§ããªã„文字ãŒã‚りã¾ã™" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "サブパターンã®åå‰ã«çµ‚端文字ãŒã‚りã¾ã›ã‚“" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "二ã¤ã‚ã‚‹åå‰ä»˜ãサブパターンãŒåŒã˜åå‰ã§ã™" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "䏿­£ãª \\P ã¾ãŸã¯ \\p ã®ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã§ã™" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "\\P ã¾ãŸã¯ \\p ã®å¾Œã«ä¸æ˜Žãªãƒ—ロパティåãŒã‚りã¾ã™" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "サブパターンã®åå‰ãŒé•·ã™ãŽã¾ã™ (32 文字以下ã«ã—ã¦ãã ã•ã„)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "åå‰ä»˜ãサブパターンãŒå¤šã™ãŽã¾ã™ (10,000 個以下ã«ã—ã¦ãã ã•ã„)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "8 進数値㌠\\377 よりも大ãã„ã§ã™" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "æ­£è¦è¡¨ç¾ã‚’コンパイルã™ã‚‹é ˜åŸŸã§ä¸Šé™ã‚’è¶…ãˆã¾ã—ãŸ" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "ç›´å‰ã«ãƒã‚§ãƒƒã‚¯ã—ãŸã‚µãƒ–パターンã®ãƒªãƒ•ァレンスãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE グループã«ä¸€ã¤ä»¥ä¸Šã®ãƒ–ランãƒãŒå«ã¾ã‚Œã¦ã„ã¾ã™" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "NEWLINE オプションã«çŸ›ç›¾ãŒã‚りã¾ã™" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "数値ã§ã®å‚照㯠0 ã«ã§ãã¾ã›ã‚“" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "(*ACCEPT)ã€(*FAIL)ã€(*COMMIT) ã®å¼•æ•°ã¯ä¸€ã¤ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ã‚’èªè­˜ã§ãã¾ã›ã‚“" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "数値ãŒå¤§ãã™ãŽã¾ã™" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "(?& ã®å¾Œã«ã‚µãƒ–パターンã®åå‰ãŒã‚りã¾ã›ã‚“" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "(?+ ã®å¾Œã¯æ•°å€¤ã‚’想定ã—ã¦ã„ã¾ã—ãŸ" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "JavaScript 互æ›ãƒ¢ãƒ¼ãƒ‰ã§ã¯ ']' ã¯ä¸æ­£ãªãƒ‡ãƒ¼ã‚¿æ–‡å­—ã§ã™" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "åŒã˜ç•ªå·ã®ã‚µãƒ–パターンを異ãªã‚‹åå‰ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) ã¯å¼•æ•°ãŒä¸€ã¤å¿…è¦ã§ã™" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c ã®å¾Œã«ã¯ ASCII 文字ãŒç¶šãå¿…è¦ãŒã‚りã¾ã™" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "クラスã§ã¯ \\N ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "剿–¹å‚ç…§ãŒå¤šã™ãŽã¾ã™" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK)ã€(*PRUNE)ã€(*SKIP)ã€(*THEN) ã®åå‰ãŒé•·ã™ãŽã¾ã™" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®æ–‡å­—値ãŒå¤§ãã™ãŽã¾ã™" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "æ­£è¦è¡¨ç¾ %s ã®ãƒžãƒƒãƒãƒ³ã‚°ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "ãŠä½¿ã„ã® PCRE ライブラリ㯠UTF-8 をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "ãŠä½¿ã„ã® PCRE ライブラリ㯠UTF-8 ã®ãƒ—ロパティをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "" +"ãŠä½¿ã„ã® PCRE ライブラリã¯äº’æ›æ€§ã®ãªã„オプションã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "æ­£è¦è¡¨ç¾ %s ã®æœ€é©åŒ–中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "æ­£è¦è¡¨ç¾ %s ã®ã‚³ãƒ³ãƒ‘イル中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—㟠(%d 文字目): %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "16 é€²æ•°ã®æ•°å€¤ã¾ãŸã¯â€œ}â€ã‚’想定ã—ã¦ã„ã¾ã—ãŸ" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "16 é€²æ•°ã®æ•°å€¤ã‚’想定ã—ã¦ã„ã¾ã—ãŸ" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "シンボルå‚ç…§ã«â€œ<â€ãŒã‚りã¾ã›ã‚“" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "中途åŠç«¯ãªã‚·ãƒ³ãƒœãƒ«å‚ç…§ã§ã™" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "サイズ㌠0 ã®ã‚·ãƒ³ãƒœãƒ«å‚ç…§ã§ã™" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "数値を想定ã—ã¦ã„ã¾ã—ãŸ" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "シンボルå‚ç…§ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "最後ã®â€œ\\â€ã«å¯¾å¿œã™ã‚‹ã‚·ãƒ³ãƒœãƒ«ãŒã‚りã¾ã›ã‚“" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "䏿˜Žãªã‚¨ã‚¹ã‚±ãƒ¼ãƒ—シーケンスã§ã™" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "代替文字列“%sâ€ã® %lu 文字目ã®è§£æžä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "引用テキストãŒå¼•用記å·ã§å§‹ã¾ã£ã¦ã„ã¾ã›ã‚“" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"コマンドラインã€ã¾ãŸã¯ã‚·ã‚§ãƒ«ã®å¼•用テキストã«ãŠã„ã¦å¼•用記å·ã®å¯¾å¿œãŒå–れã¦ã„ã¾" +"ã›ã‚“" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "テキストãŒâ€œ\\â€æ–‡å­—ã®ç›´å¾Œã§çµ‚了ã—ã¦ã„ã¾ã™ (テキストã¯â€œ%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "%c ã«å¯¾å¿œã™ã‚‹å¼•用記å·ã®å‰ã§ãƒ†ã‚­ã‚¹ãƒˆãŒçµ‚了ã—ã¦ã„ã¾ã™ (テキストã¯â€œ%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "テキストãŒç©ºã§ã™ (ã¾ãŸã¯ç©ºç™½ã®ã¿)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "å­ãƒ—ロセスã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ã‚’読ã¿å–れã¾ã›ã‚“ (%s)" + +#: glib/gspawn.c:461 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "å­ãƒ—ロセスã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿èª­ã¿å–ã‚Šä¸­ã«æƒ³å®šå¤–ã®ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:546 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() ã§æƒ³å®šå¤–ã®ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:1166 glib/gspawn-win32.c:1407 +#, c-format +msgid "Child process exited with code %ld" +msgstr "å­ãƒ—ロセスãŒã‚³ãƒ¼ãƒ‰ %ld ã§çµ‚了ã—ã¾ã—ãŸ" + +#: glib/gspawn.c:1174 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ« %ld ã§å¼·åˆ¶çµ‚了ã•れã¾ã—ãŸ" + +#: glib/gspawn.c:1181 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ« %ld ã§åœæ­¢ã•れã¾ã—ãŸ" + +#: glib/gspawn.c:1188 +#, c-format +msgid "Child process exited abnormally" +msgstr "å­ãƒ—ロセスãŒç•°å¸¸çµ‚了ã—ã¾ã—ãŸ" + +#: glib/gspawn.c:1864 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "å­ã®ãƒ‘イプã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:2166 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "å­ãƒ—ロセス“%sâ€ã® spawn ã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:2283 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork ã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:2443 glib/gspawn-win32.c:381 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "ディレクトリ“%sâ€ã¸ã®ç§»å‹•ã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:2453 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "å­ãƒ—ロセス“%sâ€ã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:2463 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "å­ãƒ—ロセスã®å‡ºåŠ›ã¾ãŸã¯å…¥åŠ›ã®ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:2472 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "å­ãƒ—ロセス㮠fork ã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn.c:2480 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "å­ãƒ—ロセスã®ãƒ•ァイルディスクリプターを閉ã˜ã‚‰ã‚Œã¾ã›ã‚“ (%s)" + +#: glib/gspawn.c:2488 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "å­ãƒ—ロセスã®èµ·å‹•時ã«ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸâ€œ%sâ€" + +#: glib/gspawn.c:2512 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "å­ãƒ—ロセスã®ãƒ‘イプã‹ã‚‰å分ãªãƒ‡ãƒ¼ã‚¿ã‚’å–å¾—ã§ãã¾ã›ã‚“ (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "å­ãƒ—ロセスã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "å­ãƒ—ロセスã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "䏿­£ãªãƒ—ログラムåã§ã™: %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:779 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d ã®å¼•数ベクターã«ä¸æ­£ãªæ–‡å­—列ãŒã‚りã¾ã™: %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:794 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "環境変数ã«ä¸æ­£ãªæ–‡å­—列ãŒã‚りã¾ã™: %s" + +#: glib/gspawn-win32.c:775 +#, c-format +msgid "Invalid working directory: %s" +msgstr "作業ディレクトリãŒä¸æ­£ã§ã™: %s" + +#: glib/gspawn-win32.c:837 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ヘルパープログラムã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—㟠(%s)" + +#: glib/gspawn-win32.c:1064 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"g_io_channel_win32_poll() ãŒå­ãƒ—ロセスã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ã‚’読ã¿å‡ºã™ã¨ãã«æƒ³å®šå¤–ã®ã‚¨" +"ラーãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#: glib/gstrfuncs.c:3345 glib/gstrfuncs.c:3447 +msgid "Empty string is not a number" +msgstr "ç©ºæ–‡å­—åˆ—ã¯æ•°å€¤ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gstrfuncs.c:3369 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%sâ€ã¯ç¬¦å·ä»˜ã数値ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/gstrfuncs.c:3379 glib/gstrfuncs.c:3483 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "数値“%sâ€ã¯æ¬¡ã®ç¯„囲を超ãˆã¦ã„ã¾ã™: [%s, %s]" + +#: glib/gstrfuncs.c:3473 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%sâ€ã¯ç¬¦å·ãªã—数値ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "URI ã«ä¸æ­£ãª % エンコーディングãŒã‚りã¾ã™" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "URI ã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã™" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "URI ã« UTF-8 ã§ã¯ãªã„文字ãŒã‚りã¾ã™" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "URI ã«ä¸æ­£ãª IPv6 アドレス‘%.*s’ãŒã‚りã¾ã™" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "URI ã«æ­£ã—ããªã„エンコード㮠IP アドレス‘%.*s’ãŒã‚りã¾ã™" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "URI ã«æ­£ã—ããªã„国際化ホストå‘%.*s’ãŒã‚りã¾ã™" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "URI ã®ãƒãƒ¼ãƒˆâ€˜%.*s’を解æžã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "URI ã®ãƒãƒ¼ãƒˆâ€˜%.*s’ã¯ç¯„囲外ã®å€¤ã§ã™" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "‘%s’ã¯çµ¶å¯¾ URI ã§ã¯ã‚りã¾ã›ã‚“" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI ‘%s’ã«ã¯ãƒ›ã‚¹ãƒˆè¦ç´ ãŒã‚りã¾ã›ã‚“" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI ãŒçµ¶å¯¾ URI ã§ã¯ãªã基本 URI ãŒã‚りã¾ã›ã‚“" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "‘=’ã¨ãƒ‘ラメーター値ãŒã‚りã¾ã›ã‚“" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "メモリã®ç¢ºä¿ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 ã®ç¯„å›²å¤–ã®æ–‡å­—ã§ã™" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "変æ›ã™ã‚‹å…¥åŠ›ã«ä¸æ­£ãªã‚·ãƒ¼ã‚±ãƒ³ã‚¹ãŒã‚りã¾ã™" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 ã®ç¯„å›²å¤–ã®æ–‡å­—ã§ã™" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2770 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2772 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2774 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2776 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2778 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2780 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2784 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2786 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2788 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2790 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2792 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2794 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2798 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2800 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2802 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2804 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2806 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2808 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2812 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2814 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2816 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2818 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2820 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2822 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2856 glib/gutils.c:2973 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ãƒã‚¤ãƒˆ" + +#: glib/gutils.c:2860 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u ビット" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2927 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ãƒã‚¤ãƒˆ" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2932 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s ビット" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2986 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:2991 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2996 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3001 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3006 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3011 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "/var/lib/dbus/machine-id ã¾ãŸã¯ /etc/machine-id を読ã¿è¾¼ã‚ã¾ã›ã‚“: " + +#~ msgid "Unknown error on connect" +#~ msgstr "接続時ã«åŽŸå› ä¸æ˜Žã®ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#~ msgid "Error in address '%s' - the family attribute is malformed" +#~ msgstr "アドレス '%s' 中ã«ã‚¨ãƒ©ãƒ¼ - family 属性ãŒä¸æ­£ã§ã™" + +#~ msgid "No such interface" +#~ msgstr "ãã®ã‚ˆã†ãªã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェースã¯ã‚りã¾ã›ã‚“" + +#, fuzzy +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "メッセージã«ã¯ %d 個㮠fd ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ãƒ˜ãƒƒãƒ€ãƒ¼ãƒ•ィールドã§ã¯ %d 個" +#~ "ã® fd ãŒã‚ã‚‹ã“ã¨ã«ãªã£ã¦ã¾ã™" + +#~ msgid "doing nothing.\n" +#~ msgstr "何もã—ã¾ã›ã‚“。\n" + +#~ msgid "association changes not supported on win32" +#~ msgstr "win32 ã§çµ„ã¿åˆã‚ã›ã®å¤‰æ›´ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "win32 ã§çµ„ã¿åˆã‚ã›ã®ç”Ÿæˆã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "エラーをペンディングã§ãã¾ã›ã‚“: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "コマンドライン '%s' ãŒéžã‚¼ãƒ­ã®çµ‚了コード %d ã§çµ‚了ã—ã¾ã—ãŸ: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' ã«å¯¾å¿œã™ã‚‹ã‚µãƒ¼ãƒ“スレコードãŒã‚りã¾ã›ã‚“" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "空ã®éƒ¨åˆ†æ–‡å­—列ã«å¯¾ã™ã‚‹ä½œæ¥­é ˜åŸŸã®ä¸Šé™ã«é”ã—ã¾ã—ãŸ" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE グループã¯ç¹°ã‚Šè¿”ã›ã¾ã›ã‚“" + +#~ msgid "File is empty" +#~ msgstr "ファイルãŒç©ºã§ã™" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "åˆå‰" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "åˆå¾Œ" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "コマンド:\n" +#~ " help ã“ã®æƒ…報を表示\n" +#~ " get キーã®å€¤ã‚’å–å¾—\n" +#~ " set キーã®å€¤ã‚’設定\n" +#~ " reset キーã®å€¤ã‚’リセット\n" +#~ " monitor キーã®å¤‰æ›´ã‚’監視\n" +#~ " writable ã‚­ãƒ¼ãŒæ›¸ãè¾¼ã¿å¯èƒ½ã‹ã©ã†ã‹ç¢ºèª\n" +#~ "\n" +#~ "'%s COMMAND --help' ã§ã“ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã®ãƒ˜ãƒ«ãƒ—を表示ã§ãã¾ã™ã€‚\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "スキーマã®ãƒ‘スを指定ã—ã¦ãã ã•ã„" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "データé…列ã®ä¸Šé™ã«åˆ°é”ã—ã¾ã—ãŸ" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "文字 '%s' ã¯ã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£åã®æœ€åˆã«ã¯ä½¿ãˆã¾ã›ã‚“。文字 & ã¯ã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£ã®é–‹" +#~ "始を表ã‚ã—ã¾ã™ã€‚ã‚‚ã—アンパサンドãŒã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£ã§ãªã‘れã°ã€& ã®ã‚ˆã†ã«ã‚¨" +#~ "スケープã—ã¦ãã ã•ã„" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "文字 '%s' ã¯ã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£åã¨ã—ã¦ä½¿ãˆã¾ã›ã‚“" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "ç©ºã®æ–‡å­—å‚ç…§ã§ã™ã€‚dž ã®ã‚ˆã†ã«æ•°å­—ãŒãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#~ msgid "Unfinished entity reference" +#~ msgstr "中途åŠç«¯ãªå®Ÿä½“å‚ç…§ã§ã™" + +#~ msgid "Unfinished character reference" +#~ msgstr "中途åŠç«¯ãªæ–‡å­—å‚ç…§ã§ã™" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "UTF-8 ã¨ã—ã¦æ­£ã—ããªã„文字列ã§ã™ (シーケンスãŒé•·ã™ãŽã¾ã™)" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "UTF-8 ã¨ã—ã¦æ­£ã—ããªã„文字列ã§ã™ (文字ã§å§‹ã¾ã£ã¦ã„ã¾ã›ã‚“)" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "'-' ã¨ã„ã†ä»£æ›¿ãˆæ–‡å­—ã§åå‰ã‚’çœç•¥ã™ã‚‹ãƒ‡ãƒ•ォルトã®ãƒ•ォールãƒãƒƒã‚¯ã‚’使用ã™ã‚‹ã‹" +#~ "ã©ã†ã‹ã§ã™ (複数ã®åå‰ã‚’指定ã™ã‚‹ã¨ä¸€ç•ªæœ€åˆã®åå‰ã‚ˆã‚Šå¾Œã®åå‰ã‚’ã™ã¹ã¦ç„¡è¦–ã—" +#~ "ã¾ã™)" diff --git a/po/ka.po b/po/ka.po new file mode 100644 index 0000000..a5e350f --- /dev/null +++ b/po/ka.po @@ -0,0 +1,6035 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-08-08 10:41+0000\n" +"PO-Revision-Date: 2022-08-15 21:43+0200\n" +"Last-Translator: Temuri Doghonadze \n" +"Language-Team: \n" +"Language: ka\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.1.1\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication-ის მáƒáƒ áƒ’ებáƒ" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "GApplication პáƒáƒ áƒáƒ›áƒ”ტრების ჩვენებáƒ" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "გáƒáƒ¨áƒ•ებული ინტერფეისის შეცვლáƒ" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "დáƒáƒ®áƒ›áƒáƒ áƒ”ბის ჩვენებáƒ" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[ბრძáƒáƒœáƒ”ბáƒ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "მიმდინáƒáƒ áƒ” ვერსიის დáƒáƒ‘ეჭდვáƒ" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "ვერსიის ჩვენებრდრგáƒáƒ¡áƒ•ლáƒ" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "áƒáƒžáƒšáƒ˜áƒ™áƒáƒªáƒ˜áƒ”ბის სიáƒ" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "áƒáƒžáƒšáƒ˜áƒ™áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¨áƒ•ებáƒ" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "ქმედების áƒáƒ¥áƒ¢áƒ˜áƒ•áƒáƒªáƒ˜áƒ" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "áƒáƒžáƒ˜áƒ¡ID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "ბრძáƒáƒœáƒ”ბáƒ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "[ქმედებáƒ]" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "პáƒáƒ áƒáƒ›áƒ”ტრი" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"უცნáƒáƒ‘ი ბრძáƒáƒœáƒ”ბáƒ: %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "გáƒáƒ›áƒáƒ§áƒ”ნებáƒ:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "áƒáƒ áƒ’უმენტები:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[áƒáƒ áƒ’უმენტები…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "ბრძáƒáƒœáƒ”ბები:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "d-bus-თáƒáƒœ მიერთების შეცდáƒáƒ›áƒ: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"უცნáƒáƒ‘ი ბრძáƒáƒœáƒ”ბáƒ: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "ნáƒáƒ™áƒáƒ“ი უკვე დáƒáƒ®áƒ£áƒ áƒ£áƒšáƒ˜áƒ" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "áƒáƒžáƒ”რáƒáƒªáƒ˜áƒ გáƒáƒ£áƒ¥áƒ›áƒ“áƒ" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "áƒáƒ‘იექტი áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜áƒ. ინიციáƒáƒšáƒ˜áƒ–ებული áƒáƒ áƒáƒ" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "შეტáƒáƒœáƒ˜áƒš ტექსტში ბáƒáƒ˜áƒ¢áƒ”ბის მიმდევრáƒáƒ‘რმცდáƒáƒ áƒ˜áƒ" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "დáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ”ბის წერტილში სáƒáƒ™áƒ›áƒáƒ áƒ˜áƒ¡áƒ˜ áƒáƒ“გილი áƒáƒ áƒáƒ" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "შეტáƒáƒœáƒ˜áƒš ტექსტში ბáƒáƒ˜áƒ¢áƒ”ბის მიმდევრáƒáƒ‘რმცდáƒáƒ áƒ˜áƒ" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ˜áƒ¡ შეცდáƒáƒ›áƒ: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "გáƒáƒ£áƒ¥áƒ›áƒ”ბáƒáƒ“ი ინიციáƒáƒšáƒ˜áƒ–áƒáƒªáƒ˜áƒ მხáƒáƒ áƒ“áƒáƒ­áƒ”რილი áƒáƒ áƒáƒ" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "კáƒáƒ“ური გვერდის \"%s\" გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ \"%s\" კáƒáƒ“ირებáƒáƒ¨áƒ˜ მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "ვერ ხერხდებრ\"%s\" - \"%s\" გáƒáƒ áƒ“áƒáƒ›áƒ¥áƒ›áƒœáƒ”ლის გáƒáƒ®áƒ¡áƒœáƒ" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "ტიპი %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "უცნáƒáƒ‘ი ტიპი" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ ტიპი %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "áƒáƒ•ტáƒáƒ›áƒáƒ¢áƒ£áƒ áƒáƒ“ გáƒáƒ¨áƒ•ების შეცდáƒáƒ›áƒ: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "ერთჯერáƒáƒ“ი ფáƒáƒ˜áƒšáƒ˜áƒ¡ (%s) გáƒáƒ®áƒ¡áƒœáƒ˜áƒ¡ შეცდáƒáƒ›áƒ: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "ერთჯერáƒáƒ“ი ფáƒáƒ˜áƒšáƒ˜áƒ“áƒáƒœ (%s) წáƒáƒ™áƒ˜áƒ—ხვის შეცდáƒáƒ›áƒ: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "მითითებული მისáƒáƒ›áƒáƒ áƒ—ი ცáƒáƒ áƒ˜áƒ”ლიáƒ" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "" + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "მáƒáƒ¢áƒáƒ áƒ”ბლის უცნáƒáƒ‘ი ტიპი %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "áƒáƒžáƒ”რáƒáƒªáƒ˜áƒ მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "შეერთებრáƒáƒ  დáƒáƒ®áƒ£áƒ áƒ£áƒšáƒ" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "თვისების შექმნის შეცდáƒáƒ›áƒ: %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "თვისების დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "ტიპი áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜áƒ" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" +msgstr[1] "" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "" + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "" + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(ფáƒáƒœáƒ¯áƒ áƒ˜áƒ¡ დáƒáƒ¡áƒáƒ®áƒ£áƒ áƒáƒ“ დáƒáƒáƒ­áƒ˜áƒ áƒ”თ ნებისმიერ კლáƒáƒ•იშáƒáƒ¡)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "áƒáƒžáƒáƒ áƒáƒ¢áƒ£áƒ áƒ˜áƒ¡ პრáƒáƒ¤áƒ˜áƒšáƒ˜áƒ¡ მიღების შეცდáƒáƒ›áƒ: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "%s-ის áƒáƒœ %s-ის ჩáƒáƒ¢áƒ•ირთვის შეცდáƒáƒ›áƒ: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "შეცდáƒáƒ›áƒ: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "შეცდáƒáƒ›áƒ: áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სáƒáƒ®áƒ”ლი: \"%s\"\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "" + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "შეერთების შეცდáƒáƒ›áƒ: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "შეცდáƒáƒ›áƒ: %s მáƒáƒ¢áƒáƒ áƒ”ბლის უნიკáƒáƒšáƒ£áƒ  სáƒáƒ®áƒ”ლს áƒáƒ  წáƒáƒ áƒ›áƒáƒáƒ“გენს.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "შეცდáƒáƒ›áƒ: %s ინტერფეისის სწáƒáƒ  სáƒáƒ®áƒ”ლს áƒáƒ  წáƒáƒ áƒ›áƒáƒáƒ“გენს\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "შეცდáƒáƒ›áƒ: %s წევრის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სáƒáƒ®áƒ”ლიáƒ\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "შეერთების მáƒáƒªáƒ˜áƒšáƒ”ბის შეცდáƒáƒ›áƒ: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "ვáƒáƒ“რწáƒáƒ›áƒ”ბში" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "" + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "შეცდáƒáƒ›áƒ: %s მáƒáƒ¢áƒáƒ áƒ”ბლის სწáƒáƒ  სáƒáƒ®áƒ”ლს áƒáƒ  წáƒáƒ áƒ›áƒáƒáƒ“გენს.\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ \"%d\" წáƒáƒ™áƒ˜áƒ—ხვის შეცდáƒáƒ›áƒ: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "XML-ის დáƒáƒ‘ეჭდვáƒ" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "" + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "დáƒáƒ¨áƒáƒ áƒ”ბული áƒáƒ‘იექტის მáƒáƒœáƒ˜áƒ¢áƒáƒ áƒ˜áƒœáƒ’ი." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "" + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "შეცდáƒáƒ›áƒ: %s მáƒáƒ¢áƒáƒ áƒ”ბლის ცნáƒáƒ‘ილ სáƒáƒ®áƒ”ლს áƒáƒ  წáƒáƒ áƒ›áƒáƒáƒ“გენს.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "უსáƒáƒ®áƒ”ლáƒ" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ეზე კáƒáƒžáƒ˜áƒ áƒ”ბრშეუძლებელიáƒ" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "სáƒáƒ›áƒ˜áƒ–ნე ფáƒáƒ˜áƒšáƒ˜ უკვე áƒáƒ áƒ¡áƒ”ბáƒáƒ‘ს" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის რეკურსიულáƒáƒ“ კáƒáƒžáƒ˜áƒ áƒ”ბრშეუძლებელიáƒ" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "სიმბáƒáƒšáƒ£áƒ áƒ˜ ბმების გáƒáƒ›áƒáƒ§áƒ”ნებრáƒáƒ áƒáƒ რეáƒáƒšáƒ˜áƒ–ებული" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "ნáƒáƒ’áƒáƒ•ი მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "áƒáƒ› ფáƒáƒ˜áƒšáƒ˜áƒ¡ გáƒáƒ¡áƒáƒ®áƒ¡áƒœáƒ”ლი პრáƒáƒ’რáƒáƒ›áƒ დáƒáƒ áƒ”გისტრირებული áƒáƒ áƒáƒ" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ნáƒáƒ™áƒáƒ“ში გáƒáƒ“áƒáƒ®áƒ•ევრმხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "ნáƒáƒ™áƒáƒ“ის მáƒáƒ™áƒ•ეთრმხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "ჰáƒáƒ¡áƒ¢áƒ˜áƒ¡ áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სáƒáƒ®áƒ”ლი" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "\"version\"-ს áƒáƒ áƒ’უმენტები áƒáƒ  áƒáƒ¥áƒ•ს" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "გáƒáƒ›áƒáƒ§áƒ”ნებáƒ:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "" + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "ბრძáƒáƒœáƒ”ბები:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ეების შექმნáƒ" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:91 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "სáƒáƒ›áƒ˜áƒ–ნე სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის გáƒáƒ áƒ”შე" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "" + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "სისტემის ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ მიღების შეცდáƒáƒ›áƒ" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "áƒáƒ¢áƒ áƒ˜áƒ‘უტები:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "სáƒáƒ©áƒ•ენებელი სáƒáƒ®áƒ”ლი :%s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "სáƒáƒ®áƒ”ლი: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "ტიპი : %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "ზáƒáƒ›áƒ: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "დáƒáƒ›áƒáƒšáƒ£áƒšáƒ˜\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "ლáƒáƒ™áƒáƒšáƒ£áƒ áƒ˜ ბილიკი: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "" + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "%s-ის ჩáƒáƒ¢áƒ•ირთვის შეცდáƒáƒ›áƒ: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "áƒáƒ˜áƒ“ი" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "მáƒáƒ®áƒ¡áƒœáƒ" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "მáƒáƒ®áƒ¡áƒœáƒ" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "მáƒáƒ¬áƒ§áƒáƒ‘ილáƒáƒ‘áƒ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "სიáƒ" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "დáƒáƒ›áƒáƒ¢áƒ”ბითი ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ ჩვენებáƒ" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "სáƒáƒ›áƒ˜áƒ–ნე %s სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ეს áƒáƒ  წáƒáƒ áƒ›áƒáƒáƒ“გენს" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "" + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "ნáƒáƒ™áƒšáƒ£áƒšáƒ˜ áƒáƒ áƒ’უმენტი" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:139 +msgid "Too many arguments" +msgstr "მეტისმეტáƒáƒ“ ბევრი áƒáƒ áƒ’უმენტი" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "" + +#: gio/gio-tool-set.c:91 +msgid "ATTRIBUTE" +msgstr "" + +#: gio/gio-tool-set.c:91 +msgid "VALUE" +msgstr "მნიშვნელáƒáƒ‘áƒ" + +#: gio/gio-tool-set.c:95 +msgid "Set a file attribute of LOCATION." +msgstr "" + +#: gio/gio-tool-set.c:115 +msgid "Location not specified" +msgstr "მდებáƒáƒ áƒ”áƒáƒ‘რმითითებული áƒáƒ áƒáƒ" + +#: gio/gio-tool-set.c:122 +msgid "Attribute not specified" +msgstr "" + +#: gio/gio-tool-set.c:132 +msgid "Value not specified" +msgstr "" + +#: gio/gio-tool-set.c:182 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "áƒáƒ¢áƒ áƒ˜áƒ‘უტის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ტიპი: %s" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ˜ მდებáƒáƒ áƒ”áƒáƒ‘ის თáƒáƒ•იდáƒáƒœ შექმნის შეცდáƒáƒ›áƒ: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "" + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "" + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "ელემენტი <%s> <%s>-ის შიგნით დáƒáƒ£áƒ¨áƒ•ებელიáƒ" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "ელემენტი <%s> შეუძლებელიáƒ, სიის თáƒáƒ•ში იყáƒáƒ¡" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "დáƒáƒ›áƒ£áƒ¨áƒáƒ•ების უცნáƒáƒ‘ი პáƒáƒ áƒáƒ›áƒ”ტრი %s" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ რიცხვითი მნიშვნელáƒáƒ‘áƒ" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "" + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr "" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "ცáƒáƒ áƒ”ლი სáƒáƒ®áƒ”ლები დáƒáƒ£áƒ¨áƒ•ებელიáƒ" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "<%s>-ის შიგნით შეუძლებელიáƒ, ტექსტი გáƒáƒ›áƒáƒ©áƒœáƒ“ეს" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "" + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "" + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "" + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სáƒáƒ®áƒ”ლი: %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სáƒáƒ®áƒ”ლი" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "სáƒáƒœáƒáƒ’ვის სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის (%s) შექმნის შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "%s-ის წáƒáƒ¡áƒáƒ¨áƒšáƒ”ლáƒáƒ“ ზედრსáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის პáƒáƒ•ნრშეუძლებელი იყáƒ" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "სáƒáƒœáƒáƒ’ვე სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის (%s) შექმნრშეუძლებელირ%s-ის წáƒáƒ¡áƒáƒ¨áƒšáƒ”ლáƒáƒ“" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "წáƒáƒ¨áƒšáƒ˜áƒ¡ ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ ფáƒáƒ˜áƒšáƒ˜áƒ¡ (%s) შექმნის შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ (%s) წáƒáƒ¨áƒšáƒ ფáƒáƒ˜áƒšáƒ£áƒ áƒ˜ სისტემის სáƒáƒ–ღვრებს მიღმრშეუძლებელიáƒ" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ (%s) წáƒáƒ¨áƒšáƒ შეუძლებელიáƒ: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ (%s) წáƒáƒ¨áƒšáƒ შეუძლებელიáƒ" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის (%s) შექმნის შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ფáƒáƒ˜áƒšáƒ£áƒ  სისტემáƒáƒ¡ სიმბმულების მხáƒáƒ áƒ“áƒáƒ­áƒ”რრáƒáƒ  გáƒáƒáƒ©áƒœáƒ˜áƒ" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ეზე გáƒáƒ“áƒáƒ¢áƒáƒœáƒ შეუძლებელიáƒ" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "მáƒáƒ áƒ¥áƒáƒ¤áƒ˜áƒ¡ ფáƒáƒ˜áƒšáƒ˜áƒ¡ შექმნის შეცდáƒáƒ›áƒ" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "დისკზე %s-ის მიერ დáƒáƒ™áƒáƒ•ებული áƒáƒ“გილის გáƒáƒ›áƒáƒ—ვლის შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "გáƒáƒ¤áƒáƒ áƒ—áƒáƒ”ბული áƒáƒ¢áƒ áƒ˜áƒ‘უტის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სáƒáƒ®áƒ”ლი" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ კáƒáƒ“ირებáƒ)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "áƒáƒ¢áƒ áƒ˜áƒ‘უტის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ტიპი (მáƒáƒ•ელáƒáƒ“ი uint32-ს)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "სიმბმულებზე წვდáƒáƒ›áƒ”ბის დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "წვდáƒáƒ›áƒ˜áƒ¡ დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "მფლáƒáƒ‘ლის დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "სიმბმულის დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "%s-ისთვის შეცვლის áƒáƒœ წვდáƒáƒ›áƒ˜áƒ¡ დრáƒáƒ˜áƒ¡ დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "ცვლილების áƒáƒœ წვდáƒáƒ›áƒ˜áƒ¡ დრáƒáƒ˜áƒ¡ დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux-ის კáƒáƒœáƒ¢áƒ”ქსტის დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "áƒáƒ¢áƒ áƒ˜áƒ‘უტის (%s) დáƒáƒ§áƒ”ნებრმხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ (%s) დáƒáƒ®áƒ£áƒ áƒ•ის შეცდáƒáƒ›áƒ" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "" + +#: gio/glocalfilemonitor.c:879 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "სáƒáƒ›áƒ˜áƒ–ნე ფáƒáƒ˜áƒšáƒ˜ სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ეáƒ" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "სáƒáƒ›áƒ˜áƒ–ნე სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ე ჩვეულებრივი áƒáƒ áƒáƒ" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "ფáƒáƒ˜áƒšáƒ˜ გáƒáƒ áƒ”დáƒáƒœ შეიცვáƒáƒšáƒ" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "გáƒáƒ“áƒáƒ®áƒ•ევის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ მáƒáƒ—ხáƒáƒ•ნáƒ" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "ქსელი მიუწვდáƒáƒ›áƒ”ლიáƒ" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "ჰáƒáƒ¡áƒ¢áƒ˜ მიუწვდáƒáƒ›áƒ”ლიáƒ" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "" + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager-ი გáƒáƒ¨áƒ•ებული áƒáƒ áƒáƒ" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "დáƒáƒ›áƒ”ნის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სáƒáƒ®áƒ”ლი" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[ბილიკი]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "ბილიკი" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr "" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr "" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr "" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s-დáƒáƒœ სქემების ჩáƒáƒ¢áƒ•ირთვის შეცდáƒáƒ›áƒ: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "სáƒáƒ™áƒ”ტის I/O ვáƒáƒ“რგáƒáƒ•იდáƒ" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "სáƒáƒ™áƒ”ტის შექმნის შეცდáƒáƒ›áƒ: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "შეერთების მიღების შეცდáƒáƒ›áƒ: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "დáƒáƒ áƒ©áƒ”ნილი შეცდáƒáƒ›áƒ˜áƒ¡ მიღებრშეუძლებელიáƒ: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "სáƒáƒ™áƒ”ტის გáƒáƒ›áƒáƒ áƒ—ვის შეცდáƒáƒ›áƒ: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "შეუძლებელირშეტყáƒáƒ‘ინების გáƒáƒ’ზáƒáƒ•ნáƒ: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "" + +#: gio/gsocket.c:6092 gio/gsocket.c:6103 gio/gsocket.c:6166 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "სáƒáƒ™áƒ”ტის მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის/პáƒáƒ áƒáƒšáƒ˜áƒ¡ წáƒáƒ™áƒ˜áƒ—ხვის შეცდáƒáƒ›áƒ: %s" + +#: gio/gsocket.c:6175 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s-სთáƒáƒœ მიერთების შეცდáƒáƒ›áƒ: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "" + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1805 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "áƒáƒ áƒ-TCP შეერთების ზემáƒáƒ“áƒáƒœ პრáƒáƒ¥áƒ¡áƒ˜ მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1834 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "პრáƒáƒ¥áƒ¡áƒ˜ პრáƒáƒ¢áƒáƒ™áƒáƒšáƒ˜ \"%s\" მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "" + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "áƒáƒ áƒ®áƒ˜áƒ¡ შექმნრქვეპრáƒáƒªáƒ”სთáƒáƒœ დáƒáƒ¡áƒáƒ™áƒáƒ•შირებლáƒáƒ“ ვერ მáƒáƒ®áƒ”რხდრ(%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ DNS პáƒáƒ™áƒ”ტი" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "" + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "FD-ის გáƒáƒ’ზáƒáƒ•ნრმხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "" +msgstr[1] "" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "" +msgstr[1] "" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "FD-ის მიღებრმხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "" + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "ფáƒáƒ˜áƒšáƒ£áƒ áƒ˜ სისტემის სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ˜ სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ე" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "მეხსიერებრსáƒáƒ™áƒ›áƒáƒ áƒ˜áƒ¡áƒ˜ áƒáƒ  áƒáƒ áƒ˜áƒ¡" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "შიდრშეცდáƒáƒ›áƒ: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "სáƒáƒ­áƒ˜áƒ áƒáƒ მეტი შეტáƒáƒœáƒ" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ შეკუმშული მáƒáƒœáƒáƒªáƒ”მები" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "მáƒáƒ¡áƒáƒ¡áƒ›áƒ”ნი მისáƒáƒ›áƒáƒ áƒ—ი" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "მისáƒáƒ›áƒáƒ áƒ—ის დáƒáƒ‘ეჭდვáƒ" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "D-Bus სერვისის გáƒáƒ¨áƒ•ებáƒ" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ áƒáƒ áƒ’უმენტები\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "მáƒáƒ£áƒšáƒáƒ“ნელი áƒáƒ¢áƒ áƒ˜áƒ‘უტი '%s' ელემენტ '%s'-თვის" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "áƒáƒ¢áƒ áƒ˜áƒ‘უტი'%s' ელემენტისთვის '%s' ვერ მáƒáƒ˜áƒ«áƒ”ბნáƒ" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "უცნáƒáƒ‘ი ჭდე '%s', მáƒáƒ¡áƒáƒšáƒáƒ“ნელი იყრ'%s'" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "უცნáƒáƒ‘ი ჭდე '%s' - '%s'-ში" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "მáƒáƒœáƒáƒªáƒ”მთრდáƒáƒ¡áƒ¢áƒ”ბში მáƒáƒ áƒ—ებული სáƒáƒ™áƒ•áƒáƒœáƒ«áƒ ფáƒáƒ˜áƒšáƒ˜ ვერ მáƒáƒ˜áƒ«áƒ”ბნáƒ" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "სáƒáƒœáƒ˜áƒ¨áƒœáƒ” URI-სთვის '%s' უკვე áƒáƒ áƒ¡áƒ”ბáƒáƒ‘ს" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "URI '%s'-თვის სáƒáƒœáƒ˜áƒ¨áƒœáƒ” ვერ მáƒáƒ˜áƒ«áƒ”ბნáƒ" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "URI '%s' სáƒáƒœáƒ˜áƒ¨áƒœáƒ”ში MIME ტიპი მითითებული áƒáƒ áƒáƒ" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "URI '%s' სáƒáƒœáƒ˜áƒ¨áƒœáƒ”ში პირáƒáƒ“ი áƒáƒšáƒáƒ›áƒ˜ áƒáƒ  მითითებულáƒ" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI '%s' სáƒáƒœáƒ˜áƒ¨áƒœáƒ”ში ჯგუფები დáƒáƒ§áƒ”ნებული áƒáƒ áƒáƒ" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "პრáƒáƒ’რáƒáƒ›áƒáƒ¡ სáƒáƒ®áƒ”ლით \"%s\" სáƒáƒœáƒ˜áƒ¨áƒœáƒ” \"%s\" áƒáƒ  დáƒáƒ£áƒ áƒ”გისტრირებიáƒ" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "áƒáƒ áƒáƒ¡áƒ áƒ£áƒšáƒ˜ სიმბáƒáƒšáƒ შეტáƒáƒœáƒ˜áƒ¡ ტექსტის ბáƒáƒšáƒáƒ¡" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "ვერ ხერხდებრ\"%s\" სიმბáƒáƒšáƒáƒ¡ გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ კáƒáƒ“ირებáƒáƒ¨áƒ˜ \"%s\"" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "გáƒáƒ“áƒáƒ§áƒ•áƒáƒœáƒ˜áƒ¡áƒáƒ¡ შეყვáƒáƒœáƒáƒ¨áƒ˜ ჩáƒáƒ¨áƒ”ნებული NUL ბáƒáƒ˜áƒ¢áƒ˜" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "გáƒáƒ“áƒáƒ§áƒ•áƒáƒœáƒ˜áƒ¡áƒáƒ¡ გáƒáƒ›áƒáƒ¢áƒáƒœáƒáƒ¨áƒ˜ ჩáƒáƒ¨áƒ”ნებული NUL ბáƒáƒ˜áƒ¢áƒ˜" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" +"URI \"%s\" áƒáƒ  გáƒáƒ®áƒšáƒáƒ•თ áƒáƒ‘სáƒáƒšáƒ£áƒ¢áƒ£áƒ áƒ˜ იდენტიფიკáƒáƒ¢áƒáƒ áƒ˜ \"file\" სქემის გáƒáƒ›áƒáƒ§áƒ”ნებისáƒáƒ¡" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "" +"ლáƒáƒ™áƒáƒšáƒ£áƒ áƒ˜ ფáƒáƒ˜áƒšáƒ˜áƒ¡ URI იდენტიფიკáƒáƒ¢áƒáƒ áƒ˜ \"%s\" áƒáƒ  შეიძლებრშეიცáƒáƒ•დეს სიმბáƒáƒšáƒáƒ¡ \"#" +"\"" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI იდენტიფიკáƒáƒ¢áƒáƒ áƒ˜ \"%s\" მცდáƒáƒ áƒ˜áƒ" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI იდენტიფიკáƒáƒ¢áƒáƒ áƒ˜áƒ¡ \"%s\" ჰáƒáƒ¡áƒ¢áƒ˜áƒ¡ სáƒáƒ®áƒ”ლი მცდáƒáƒ áƒ˜áƒ" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI იდენტიფიკáƒáƒ¢áƒáƒ áƒ˜ \"%s\" შეიცáƒáƒ• მცდáƒáƒ  სáƒáƒ™áƒáƒœáƒ¢áƒ áƒáƒšáƒ სიმბáƒáƒšáƒáƒ”ბს" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "ბილიკი \"%s\" áƒáƒ‘სáƒáƒšáƒ£áƒ¢áƒ£áƒ áƒ˜ áƒáƒ  გáƒáƒ®áƒšáƒáƒ•თ" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Y წლის %d %B, %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "იáƒáƒœáƒ•áƒáƒ áƒ˜" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "თებერვáƒáƒšáƒ˜" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "მáƒáƒ áƒ¢áƒ˜" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "áƒáƒžáƒ áƒ˜áƒšáƒ˜" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "მáƒáƒ˜áƒ¡áƒ˜" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "ივნისი" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "ივლისი" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "áƒáƒ’ვისტáƒ" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "სექტემბერი" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "áƒáƒ¥áƒ¢áƒáƒ›áƒ‘ერი" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "ნáƒáƒ”მბერი" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "დეკემბერი" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "იáƒáƒœ" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "თებ" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "მáƒáƒ " + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "áƒáƒžáƒ " + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "მáƒáƒ˜áƒ¡áƒ˜" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ივნ" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ივლ" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "áƒáƒ’ვ" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "სექ" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "áƒáƒ¥áƒ¢" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ნáƒáƒ”" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "დეკ" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "áƒáƒ áƒ¨áƒáƒ‘áƒáƒ—ი" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "სáƒáƒ›áƒ¨áƒáƒ‘áƒáƒ—ი" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "áƒáƒ—ხშáƒáƒ‘áƒáƒ—ი" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ხუთშáƒáƒ‘áƒáƒ—ი" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "პáƒáƒ áƒáƒ¡áƒ™áƒ”ვი" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "შáƒáƒ‘áƒáƒ—ი" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "კვირáƒ" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "áƒáƒ áƒ¨" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "სáƒáƒ›" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "áƒáƒ—ხ" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ხუთ" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "პáƒáƒ " + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "შáƒáƒ‘" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "კვი" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "იáƒáƒœáƒ•áƒáƒ áƒ˜" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "თებერვáƒáƒšáƒ˜" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "მáƒáƒ áƒ¢áƒ˜" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "áƒáƒžáƒ áƒ˜áƒšáƒ˜" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "მáƒáƒ˜áƒ¡áƒ˜" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "ივნისი" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "ივლისი" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "áƒáƒ’ვისტáƒ" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "სექტემბერი" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "áƒáƒ¥áƒ¢áƒáƒ›áƒ‘ერი" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "ნáƒáƒ”მბერი" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "დეკემბერი" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "იáƒáƒœ" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "თებ" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "მáƒáƒ " + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "áƒáƒžáƒ " + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "მáƒáƒ˜áƒ¡áƒ˜" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "ივნ" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "ივლ" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "áƒáƒ’ვ" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "სექ" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "áƒáƒ¥áƒ¢" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ნáƒáƒ”" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "დეკ" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "ვერ ხერხდებრ%lu ბáƒáƒ˜áƒ¢áƒ˜áƒ¡ გáƒáƒ›áƒáƒ§áƒáƒ¤áƒ \"%s\" ფáƒáƒ˜áƒšáƒ˜áƒ¡ წáƒáƒ¡áƒáƒ™áƒ˜áƒ—ხáƒáƒ“" +msgstr[1] "ვერ ხერხდებრ%lu ბáƒáƒ˜áƒ¢áƒ˜áƒ¡ გáƒáƒ›áƒáƒ§áƒáƒ¤áƒ \"%s\" ფáƒáƒ˜áƒšáƒ˜áƒ¡ წáƒáƒ¡áƒáƒ™áƒ˜áƒ—ხáƒáƒ“" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ (%s) გáƒáƒ®áƒ¡áƒœáƒ შეუძლებელიáƒ: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "ვერ მáƒáƒ®áƒ”რხდრ'%s' ფáƒáƒ˜áƒšáƒ˜áƒ¡ გáƒáƒ“áƒáƒ áƒ¥áƒ›áƒ”ვრ- '%s': g_rename() ვერ შედგáƒ: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "ვერ ვწერ '%s' ფáƒáƒ˜áƒšáƒ¡: fwrite() ვერ შედგáƒ: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "ვერ ვწერ '%s' ფáƒáƒ˜áƒšáƒ¡: fsync() ვერ შედგáƒ: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "ვერ ვქმნი '%s' ფáƒáƒ˜áƒšáƒ¡: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "áƒáƒ áƒ¡áƒ”ბული '%s' ფáƒáƒ˜áƒšáƒ˜ ვერ áƒáƒ›áƒáƒ˜áƒ¨áƒšáƒ”ბáƒ: g_unlink() ვერ შედგáƒ: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "შáƒáƒ‘ლáƒáƒœáƒ˜ '%s' მცდáƒáƒ áƒ˜áƒ დრ'%s'-ს áƒáƒ  უნდრშეიცáƒáƒ•დეს" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "შáƒáƒ‘ლáƒáƒœáƒ˜ '%s' áƒáƒ  შეიცáƒáƒ•ს XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "სიმბáƒáƒšáƒ£áƒ áƒ˜ ბმის \"%s\" წáƒáƒ™áƒ˜áƒ—ხვის შეცდáƒáƒ›áƒ: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "ვერ ხერხდებრგáƒáƒ áƒ“áƒáƒ›áƒ¥áƒ›áƒœáƒ”ლის გáƒáƒ®áƒ¡áƒœáƒ '%s' - '%s': %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "უშუáƒáƒšáƒáƒ“ წáƒáƒ™áƒ˜áƒ—ხვრფუნქციáƒáƒ¨áƒ˜ g_io_channel_read_line_string ვერ ხერხდებáƒ" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "გáƒáƒ áƒ“áƒáƒ£áƒ¥áƒ›áƒœáƒ”ლი მáƒáƒœáƒáƒªáƒ”მები წáƒáƒ™áƒ˜áƒ—ხვის ბუფერში დáƒáƒ áƒ©áƒ" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "áƒáƒ áƒ®áƒ˜ áƒáƒ áƒáƒ¡áƒ áƒ£áƒšáƒ˜ სიმბáƒáƒšáƒáƒ—ი იხურებáƒ" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "უშუáƒáƒšáƒáƒ“ წáƒáƒ™áƒ˜áƒ—ხვრფუნქციáƒáƒ¨áƒ˜ g_io_channel_read_to_end ვერ ხერხდებáƒ" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "ძიების კáƒáƒ¢áƒáƒšáƒáƒ’ებში შეუძლებელირდáƒáƒ›áƒáƒ¬áƒ›áƒ”ბული გáƒáƒ¡áƒáƒ¦áƒ”ბის პáƒáƒ•ნáƒ" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "ფáƒáƒ˜áƒšáƒ˜ ჩვეულებრივი áƒáƒ áƒáƒ" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"გáƒáƒ¡áƒáƒ¦áƒ”ბის ფáƒáƒ˜áƒšáƒ˜ '%s' შეიცáƒáƒ•ს სტრიქáƒáƒœáƒ¡, რáƒáƒ›áƒ”ლიც áƒáƒ  წáƒáƒ áƒ›áƒáƒáƒ“გენს გáƒáƒ¡áƒáƒ¦áƒ”ბი-" +"მნიშვნელáƒáƒ‘áƒáƒ¡, ჯგუფს áƒáƒœ კáƒáƒ›áƒ”ნტáƒáƒ áƒ¡" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "ჯგუფის მიუღებელი სáƒáƒ®áƒ”ლი: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "სáƒáƒ™áƒ•áƒáƒœáƒ«áƒ ფáƒáƒ˜áƒšáƒ˜ ჯგუფით áƒáƒ  იწყებáƒ" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "გáƒáƒ¡áƒáƒ¦áƒ”ბის მიუღებელი სáƒáƒ®áƒ”ლი: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "გáƒáƒ¡áƒáƒ¦áƒ”ბის ფáƒáƒ˜áƒšáƒ˜ შეიცáƒáƒ•ს მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელ კáƒáƒ“ირებáƒáƒ¡ '%s'" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "გáƒáƒ¡áƒáƒ¦áƒ”ბის ფáƒáƒ˜áƒšáƒ˜ áƒáƒ  შეიცáƒáƒ•ს ჯგუფს '%s'" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "გáƒáƒ¡áƒáƒ¦áƒ”ბის ფáƒáƒ˜áƒšáƒ˜ áƒáƒ  შეიცáƒáƒ•ს გáƒáƒ¡áƒáƒ¦áƒ”ბს '%s' ჯგუფში '%s'" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"ფáƒáƒ˜áƒšáƒ˜ შეიცáƒáƒ•ს გáƒáƒ¡áƒáƒ¦áƒ”ბს '%s', რáƒáƒ›áƒšáƒ˜áƒ¡ მნიშვნელáƒáƒ‘áƒáƒª '%s' UTF-8 კáƒáƒ“ირებáƒáƒ¨áƒ˜ áƒáƒ áƒáƒ" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "ფáƒáƒ˜áƒšáƒ˜ შეიცáƒáƒ•ს გáƒáƒ¡áƒáƒ¦áƒ”ბს '%s', რáƒáƒ›áƒšáƒ˜áƒ¡ მნიშვნელáƒáƒ‘áƒáƒª ვერ იშიფრებáƒ." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"ფáƒáƒ˜áƒšáƒ˜ შეიცáƒáƒ•ს გáƒáƒ¡áƒáƒ¦áƒ”ბს '%s' ჯგუფში '%s', რáƒáƒ›áƒšáƒ˜áƒ¡ მნიშვნელáƒáƒ‘áƒáƒª ვერ იშიფრებáƒ." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "გáƒáƒ¡áƒáƒ¦áƒ”ბის ფáƒáƒ˜áƒšáƒ˜ სტრიქáƒáƒœáƒ˜áƒ¡ ბáƒáƒšáƒáƒ¡ escape სიმბáƒáƒšáƒáƒ¡ შეიცáƒáƒ•ს" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "გáƒáƒ¡áƒáƒ¦áƒ”ბის ფáƒáƒ˜áƒšáƒ˜ მცდáƒáƒ  escape მიმდევრáƒáƒ‘áƒáƒ¡ '%s' შეიცáƒáƒ•ს" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "მნიშვნელáƒáƒ‘რ'%s' ვერ áƒáƒ¦áƒ˜áƒ¥áƒ›áƒ”ბáƒ, რáƒáƒ’áƒáƒ áƒª რიცხვი." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "მთელი მნიშვნელáƒáƒ‘რ'%s' დიáƒáƒžáƒáƒ–áƒáƒœáƒ¡ გáƒáƒ áƒ”თáƒáƒ" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "მნიშვნელáƒáƒ‘რ'%s' ვერ áƒáƒ¦áƒ˜áƒ¥áƒ›áƒ”ბáƒ, რáƒáƒ’áƒáƒ áƒª წილáƒáƒ“ი." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "მნიშვნელáƒáƒ‘რ'%s' ვერ áƒáƒ¦áƒ˜áƒ¥áƒ›áƒ”ბáƒ, რáƒáƒ’áƒáƒ áƒª ლáƒáƒ’იკური áƒáƒžáƒ”რáƒáƒ¢áƒáƒ áƒ˜." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "ვერ მáƒáƒ®áƒ”რხდრ'%s%s%s%s:' ფáƒáƒ˜áƒšáƒ˜áƒ¡ გáƒáƒœáƒ—áƒáƒ•სებáƒ: mmap() ვერ შედგáƒ: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "ვერ მáƒáƒ®áƒ”რხდრ'%s' ფáƒáƒ˜áƒšáƒ˜áƒ¡ გáƒáƒ®áƒ¡áƒœáƒ: open() ვერ შედგáƒ: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "ტექსტი მიუღებელი UTF-8 კáƒáƒ“ირებით - მიუღებელი '%s'" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სáƒáƒ®áƒ”ლი: %s" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "შეცდáƒáƒ›áƒ სტრიქáƒáƒœáƒ¨áƒ˜ %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"ვერ მუშáƒáƒ•დებრსტრიქáƒáƒœáƒ˜ '%-.*s', რáƒáƒ›áƒ”ლშიც უნდრიყáƒáƒ¡ სიმბáƒáƒšáƒáƒ¡ ნáƒáƒ›áƒ”რი " +"(მáƒáƒ’áƒáƒšáƒ˜áƒ—áƒáƒ“, ê): შესáƒáƒ«áƒšáƒáƒ რიცხვი მეტისმეტáƒáƒ“ დიდიáƒ" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"ცáƒáƒ áƒ˜áƒ”ლი ერთეული \"&;\"; შესáƒáƒ«áƒšáƒ ერთეულებიáƒ: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "ერთეულის სáƒáƒ®áƒ”ლი \"%-.*s\" უცნáƒáƒ‘იáƒ" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"ერთეული áƒáƒ  მთáƒáƒ•რდებრწერტილ-მძიმით; რáƒáƒ’áƒáƒ áƒª ჩáƒáƒœáƒ¡, სáƒáƒ®áƒ”ლის დáƒáƒ¡áƒáƒ¬áƒ§áƒ˜áƒ¡áƒ¨áƒ˜ " +"გáƒáƒ›áƒáƒ§áƒ”ნებულირსიმბáƒáƒšáƒ \"&\". გáƒáƒ›áƒáƒ¡áƒáƒ®áƒ”თ იგი, რáƒáƒ’áƒáƒ áƒª &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი უნდრდáƒáƒ˜áƒ¬áƒ§áƒáƒ¡ ელემეტით (მáƒáƒ’áƒáƒšáƒ˜áƒ—áƒáƒ“ )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"სიმბáƒáƒšáƒ \"%s\" დáƒáƒ£áƒ¨áƒ•ებელირ\"<\" სიმბáƒáƒšáƒáƒ¡ შემდეგ; áƒáƒ› სიმბáƒáƒšáƒáƒ—ი ელემენტის " +"სáƒáƒ®áƒ”ლის დáƒáƒ¬áƒ§áƒ”ბრáƒáƒ  შეიძლებáƒ" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"უცნáƒáƒ£áƒ áƒ˜ სიმბáƒáƒšáƒ \"%s\". მáƒáƒ•ელáƒáƒ“ი სიმბáƒáƒšáƒáƒ¡ \">\" ცáƒáƒ áƒ˜áƒ”ლი ელემენტის ჭდის (%s) " +"დáƒáƒ¡áƒáƒ¡áƒ áƒ£áƒšáƒ”ბლáƒáƒ“" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"უცნáƒáƒ£áƒ áƒ˜ სიმბáƒáƒšáƒ \"%s\". მáƒáƒ•ელáƒáƒ“ი \"=\"-ს áƒáƒ¢áƒ áƒ˜áƒ‘უტის (%s) სáƒáƒ®áƒ”ლის შემდეგ " +"ელემენტისთვის \"%s\"" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"უცნáƒáƒ£áƒ áƒ˜ სიმბáƒáƒšáƒ \"%s\". მáƒáƒ•ელáƒáƒ“ი \">\" áƒáƒœ \"/\" სიმბáƒáƒšáƒáƒ¡ ელემენტის(%s) " +"სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ˜ ჭდის დáƒáƒ¡áƒáƒ¡áƒ áƒ£áƒšáƒ”ბლáƒáƒ“, áƒáƒœ áƒáƒ¢áƒ áƒ˜áƒ‘უტს. áƒáƒšáƒ‘áƒáƒ— áƒáƒ¢áƒ áƒ˜áƒ‘უტის სáƒáƒ®áƒ”ლში áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ " +"სიმბáƒáƒšáƒ გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნეთ" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"ზედმეტი სიმბáƒáƒšáƒ \"%s\", მáƒáƒ¡áƒáƒšáƒáƒ“ნელირგáƒáƒ®áƒ¡áƒœáƒ˜áƒšáƒ˜ ბრჭყáƒáƒšáƒ”ბი ტáƒáƒšáƒáƒ‘ის ნიშნის " +"შემდეგ áƒáƒ¢áƒ áƒ˜áƒ‘უტისთვის \"%s\" მნიშვნელáƒáƒ‘ის მისáƒáƒœáƒ˜áƒ­áƒ”ბლáƒáƒ“ ელემენტისთვის \"%s\"" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"სიმბáƒáƒšáƒ \"%s\" დáƒáƒ£áƒ¨áƒ•ებელირელემენტის \"%s\" დáƒáƒ®áƒ£áƒ áƒ•ის ჭდის შემდეგ; დáƒáƒ¡áƒáƒ¨áƒ•ები " +"სიმბáƒáƒšáƒáƒ \">\"" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "ელემენტი \"%s\" დáƒáƒ˜áƒ®áƒ£áƒ áƒ, áƒáƒ áƒªáƒ”რთი ელემენტი áƒáƒ áƒáƒ გáƒáƒ®áƒ¡áƒœáƒ˜áƒšáƒ˜" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "ელემენტი \"%s\" დáƒáƒ˜áƒ®áƒ£áƒ áƒ, მáƒáƒ’რáƒáƒ› გáƒáƒ®áƒ¡áƒœáƒ˜áƒšáƒ˜áƒ ელემენტი \"%s\"" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი ცáƒáƒ áƒ˜áƒ”ლირáƒáƒœ მხáƒáƒšáƒáƒ“ ხáƒáƒ áƒ”ებს შეიცáƒáƒ•ს" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი დáƒáƒ¡áƒ áƒ£áƒšáƒ“რუშუáƒáƒšáƒáƒ“ კუთხáƒáƒ•áƒáƒœáƒ˜ ფრჩხილის \"<\" შემდეგ" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რგáƒáƒ®áƒ¡áƒœáƒ˜áƒšáƒ˜ ელემენტებით - \"%s\" ბáƒáƒšáƒ გáƒáƒ®áƒ¡áƒœáƒ˜áƒšáƒ˜ " +"ელემენტიáƒ" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“áƒ, მáƒáƒ¡áƒáƒšáƒáƒ“ნელირჩáƒáƒ›áƒ™áƒ”ტი კუთხáƒáƒ•áƒáƒœáƒ˜ ფრჩხილი <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რელემენტის სáƒáƒ®áƒ”ლის შიგნით" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რáƒáƒ¢áƒ áƒ˜áƒ‘უტის სáƒáƒ®áƒ”ლის შიგნით" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რელემენტის გáƒáƒ›áƒ®áƒ¡áƒœáƒ”ლი ჭდის შიგნით." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რáƒáƒ¢áƒ áƒ˜áƒ‘უტის სáƒáƒ®áƒ”ლის შემდგáƒáƒ›áƒ˜ ტáƒáƒšáƒáƒ‘ის ნიშნის " +"შემდეგ; áƒáƒ¢áƒ áƒ˜áƒ‘უტის მნიშვნელáƒáƒ‘რáƒáƒ  მითითებულáƒ" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რáƒáƒ¢áƒ áƒ˜áƒ‘უტის მნიშვნელáƒáƒ‘ის შიგნით" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რელემენტის \"%s\" ჩáƒáƒ›áƒ™áƒ”ტი ჭდის შიგნით" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რგáƒáƒ£áƒ®áƒ¡áƒœáƒ”ლი ელემენტის ჩáƒáƒ›áƒ™áƒ”ტი ჭდის შიგნით" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"დáƒáƒ™áƒ£áƒ›áƒ”ნტი მáƒáƒ£áƒšáƒáƒ“ნელáƒáƒ“ დáƒáƒ¡áƒ áƒ£áƒšáƒ“რკáƒáƒ›áƒ”ნტáƒáƒ áƒ˜áƒ¡ áƒáƒœ დáƒáƒ›áƒ£áƒ¨áƒáƒ•ების ინსტრუქციის შიგნით" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[პáƒáƒ áƒáƒ›áƒ”ტრი...]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "დáƒáƒ®áƒ›áƒáƒ áƒ”ბის პáƒáƒ áƒáƒ›áƒ”ტრები:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "დáƒáƒ®áƒ›áƒáƒ áƒ”ბის პáƒáƒ áƒáƒ›áƒ”ტრების ჩვენებáƒ" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "დáƒáƒ®áƒ›áƒáƒ áƒ”ბის ყველრპáƒáƒ áƒáƒ›áƒ”ტრის ჩვენებáƒ" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "პრáƒáƒ’რáƒáƒ›áƒ˜áƒ¡ პáƒáƒ áƒáƒ›áƒ”ტრები:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "მთელი მნიშვნელáƒáƒ‘ის \"%s\" დáƒáƒ›áƒ£áƒ¨áƒáƒ•ების შეცდáƒáƒ›áƒ %s-თვის" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "მთელი მნიშვნელáƒáƒ‘რ'%s' ელემენტისთვის %s დიáƒáƒžáƒáƒ–áƒáƒœáƒ¡ გáƒáƒ áƒ”თáƒáƒ" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "áƒáƒ áƒ›áƒáƒ’ი მნიშვნელáƒáƒ‘ის \"%s\" დáƒáƒ›áƒ£áƒ¨áƒáƒ•ების შეცდáƒáƒ›áƒ %s-თვის" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "áƒáƒ áƒ›áƒáƒ’ი მნიშვნელáƒáƒ‘რ'%s' ელემენტისთვის %s დიáƒáƒžáƒáƒ–áƒáƒœáƒ¡ გáƒáƒ áƒ”თáƒáƒ" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "შეცდáƒáƒ›áƒ˜áƒ¡ გáƒáƒáƒœáƒáƒšáƒ˜áƒ–ების პáƒáƒ áƒáƒ›áƒ”ტრი: %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "áƒáƒ  áƒáƒ áƒ¡áƒ”ბული áƒáƒ áƒ’უმენტი - %s-თვის" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "უცნáƒáƒ‘ი პáƒáƒ áƒáƒ›áƒ”ტრი %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "დáƒáƒ–იáƒáƒœáƒ”ბული áƒáƒ‘იექტი" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "შიდრშეცდáƒáƒ›áƒ áƒáƒœ დáƒáƒ–იáƒáƒœáƒ”ბული áƒáƒ‘იექტი" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "მეხსიერებáƒáƒ¡ გáƒáƒ áƒ”თ" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "უკáƒáƒœ დáƒáƒ‘რუნების ლიმიტი áƒáƒ›áƒáƒ¬áƒ£áƒ áƒ£áƒšáƒ˜áƒ" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "თáƒáƒ áƒ’ი შეიცáƒáƒ•ს ნáƒáƒ¬áƒ˜áƒšáƒáƒ‘რივი დáƒáƒ›áƒ—ხვევისთვის მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელ ელემეტებს" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "შიდრშეცდáƒáƒ›áƒ" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "უკუ მიმáƒáƒ áƒ—ვრპირáƒáƒ‘ების სáƒáƒ®áƒ˜áƒ— მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელირნáƒáƒ¬áƒ˜áƒšáƒáƒ‘რივი დáƒáƒ›áƒ—ხვევისთვის" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "რეკურსიის ლიმიტი მიღწეულიáƒ" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "სტრიქáƒáƒœáƒ”ბის გáƒáƒ“áƒáƒ§áƒ•áƒáƒœáƒ˜áƒ¡ áƒáƒšáƒ›áƒ”ბის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ კáƒáƒ›áƒ‘ინáƒáƒªáƒ˜áƒ" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "უცნáƒáƒ‘ი შეცდáƒáƒ›áƒ" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ ნიმუშის ბáƒáƒšáƒáƒ¨áƒ˜" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c ნიმუშის ბáƒáƒšáƒáƒ¨áƒ˜" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "მთვლელში რიცხვები დáƒáƒ£áƒšáƒáƒ’ებელირ{}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "მთვლელში {} რიცხვები ძáƒáƒšáƒ˜áƒáƒœ დიდიáƒ" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "სიმბáƒáƒšáƒáƒ”ბის კლáƒáƒ¡áƒ¡ დáƒáƒ›áƒáƒ‘áƒáƒšáƒáƒ”ბელი ] áƒáƒ™áƒšáƒ˜áƒ" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "სიმბáƒáƒšáƒáƒ”ბის კლáƒáƒ¡áƒ˜áƒ¡ áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ დáƒáƒ›áƒáƒ‘áƒáƒšáƒáƒ”ბელი თáƒáƒœáƒáƒ›áƒ˜áƒ›áƒ“ევრáƒáƒ‘áƒ" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "სიმბáƒáƒšáƒáƒ”ბის კლáƒáƒ¡áƒ˜áƒ¡ დიáƒáƒžáƒáƒ–áƒáƒœáƒ˜ მიმდევრáƒáƒ‘ის გáƒáƒ áƒ”თáƒáƒ" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "გáƒáƒ¡áƒáƒ›áƒ”áƒáƒ áƒ”ბელი áƒáƒ áƒáƒ¤áƒ”რიáƒ" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "უცნáƒáƒ‘ი სიმბლáƒáƒ”ბი (? áƒáƒœ (?- ის შემდეგ" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX-ის დáƒáƒ¡áƒáƒ®áƒ”ლებული კლáƒáƒ¡áƒ”ბი მხáƒáƒšáƒáƒ“ კლáƒáƒ¡áƒ˜áƒ¡ შიგნითáƒáƒ ხელმისáƒáƒ¬áƒ•დáƒáƒ›áƒ˜" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "ბმრáƒáƒ áƒáƒ áƒ¡áƒ”ბულ ქვეშáƒáƒ‘ლáƒáƒœáƒ—áƒáƒœ" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "კáƒáƒ›áƒ”ნტáƒáƒ áƒ˜áƒ¡ შემდეგ ) áƒáƒ™áƒšáƒ˜áƒ" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "რეგულáƒáƒ áƒ£áƒšáƒ˜ გáƒáƒ›áƒáƒ¡áƒáƒ®áƒ£áƒšáƒ”ბრძáƒáƒšáƒ˜áƒáƒœ გრძელიáƒ" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "მეხსიერებს მიღებრშეუძლეებლიáƒ" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "(?< ის შემდეგ უცნáƒáƒ‘ი სიმბáƒáƒšáƒáƒ" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "(?(-ის შემდეგ áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ რიცხვი áƒáƒœ სáƒáƒ®áƒ”ლიáƒ" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "პირáƒáƒ‘ითი ჯგუფი áƒáƒ  ბრენჩზე მეტს შეიცáƒáƒ•ს" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "assertion expected after (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R or (?[+-]digits must be followed by )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "posix-ის უცნáƒáƒ‘ი კლáƒáƒ¡áƒ˜áƒ¡ სáƒáƒ®áƒ”ლი" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX-ის გáƒáƒ“áƒáƒ¤áƒáƒ áƒ•áƒáƒ“ი ელემენტები მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "character value in \\x{...} sequence is too large" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ პირáƒáƒ‘რ(?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "რეკურსიული გáƒáƒ›áƒáƒ«áƒáƒ®áƒ”ბრშეიძლებრუსáƒáƒ¡áƒ áƒ£áƒšáƒáƒ“ გáƒáƒ’რძელდეს" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "უცნáƒáƒ‘ი სიმბáƒáƒšáƒ (?P-ის შემდეგ" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "áƒáƒ  სხვáƒáƒ“áƒáƒ¡áƒ®áƒ•რქვეშáƒáƒ‘ლáƒáƒœáƒ¡ ერთი დრიგივე სáƒáƒ®áƒ”ლი áƒáƒ¥áƒ•თ" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "რიცხვი ძáƒáƒšáƒ˜áƒáƒœ დიდიáƒ" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "(?+ -ის შემდეგ მáƒáƒ•ელáƒáƒ“ი ციფრს" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "კლáƒáƒ¡áƒ¨áƒ˜ \\N მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "დáƒáƒ˜áƒ¨áƒ•რშეცდáƒáƒ›áƒ სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ გáƒáƒ›áƒáƒ¡áƒáƒ®áƒ£áƒšáƒ”ბის %s დáƒáƒ›áƒ—ხვევის ძიების დრáƒáƒ¡: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "ბიბლიáƒáƒ—ეკრPCRE-ს áƒáƒ  გáƒáƒáƒ©áƒœáƒ˜áƒ UTF8-ის მხáƒáƒ áƒ“áƒáƒ­áƒ”რáƒ" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"PCRE ბიბლიáƒáƒ—ეკრკáƒáƒ›áƒžáƒ˜áƒšáƒ˜áƒ áƒ”ბულირUTF8 კáƒáƒ“ირების პáƒáƒ áƒáƒ›áƒ”ტრების მხáƒáƒ áƒ“áƒáƒ­áƒ”რის გáƒáƒ áƒ”შე" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE ბიბლიáƒáƒ—ეკრკáƒáƒ›áƒžáƒ˜áƒšáƒ˜áƒ áƒ”ბულირშეუთáƒáƒ•სებელი პáƒáƒ áƒáƒ›áƒ”ტრებით" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "შეცდáƒáƒ›áƒ სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ გáƒáƒ›áƒáƒ¡áƒáƒ®áƒ£áƒšáƒ”ბის áƒáƒžáƒ¢áƒ˜áƒ›áƒ˜áƒ–ირებისáƒáƒ¡ %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"შეცდáƒáƒ›áƒ სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ გáƒáƒ›áƒáƒ¡áƒáƒ®áƒ£áƒšáƒ”ბრ%s-ის კáƒáƒ›áƒžáƒ˜áƒšáƒ˜áƒ áƒ”ბისáƒáƒ¡, სიმბáƒáƒšáƒ ნáƒáƒ›áƒ áƒ˜áƒ— %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "მáƒáƒ¡áƒáƒšáƒáƒ“ნელირთექვსმეტáƒáƒ‘ითი რიცხვი, áƒáƒœ '}'" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "მáƒáƒ¡áƒáƒšáƒáƒ“ნელირთექვსმეტáƒáƒ‘ითი სიმბáƒáƒšáƒ" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "áƒáƒ  მáƒáƒ˜áƒ«áƒ”ბნრ'<', სიმბáƒáƒšáƒ£áƒ  მითითებáƒáƒ¨áƒ˜" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "დáƒáƒ£áƒ¡áƒ áƒ£áƒšáƒ”ბელი სიმბáƒáƒšáƒ£áƒ áƒ˜ მითითებáƒ" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "ნულáƒáƒ•áƒáƒœáƒ˜ სიგრძის სიმბáƒáƒšáƒ£áƒ áƒ˜ მითითებáƒ" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "მáƒáƒ•ელáƒáƒ“ი ციფრს" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "მიუღებელი სიმბáƒáƒšáƒ£áƒ áƒ˜ მითითებáƒ" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "უცნáƒáƒ‘ი escape სეკვენციáƒ" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "ციტირებული ტექსტი ბრჭყáƒáƒšáƒ”ბით áƒáƒ  იწყებáƒ" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "უმáƒáƒ áƒ—ებლრბრჭყáƒáƒšáƒ˜ ბრძáƒáƒœáƒ”ბáƒáƒ¨áƒ˜ áƒáƒœ სხვრტექსტურ გáƒáƒ áƒ¡áƒ¨áƒ˜" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "ტექსტი დáƒáƒ¡áƒ áƒ£áƒšáƒ“რუშუáƒáƒšáƒáƒ“ \"\\\" სიმბáƒáƒšáƒáƒ¡ შემდეგ. (ტექსტი - \"%s\")" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "ტექსტი დáƒáƒ¡áƒ áƒ£áƒšáƒ“რ%c შესáƒáƒ‘áƒáƒ›áƒ˜áƒ¡áƒ˜ ბრჭყáƒáƒšáƒ˜áƒ¡ წინ. (ტექსტი - \"%s\")" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "ტექსტი ცáƒáƒ áƒ˜áƒ”ლი იყრ(áƒáƒœ მხáƒáƒšáƒáƒ“ ხáƒáƒ áƒ”ებს შეიცáƒáƒ•დáƒ)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "მáƒáƒœáƒáƒªáƒ”მთრწáƒáƒ™áƒ˜áƒ—ხვრქვეპრáƒáƒªáƒ”სიდáƒáƒœ ვერ მáƒáƒ®áƒ”რხდრ(%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "შვილეული პრáƒáƒªáƒ”სიდáƒáƒœ (%s) მáƒáƒœáƒáƒªáƒ”მების წáƒáƒ™áƒ˜áƒ—ხვის შეცდáƒáƒ›áƒ" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "მáƒáƒ£áƒšáƒáƒ“ნელი შეცდáƒáƒ›áƒ ფუნქციáƒáƒ¨áƒ˜ waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "მáƒáƒœáƒáƒªáƒ”მთრწáƒáƒ™áƒ˜áƒ—ხვრქვეპრáƒáƒªáƒ”სის áƒáƒ áƒ®áƒ˜áƒ“áƒáƒœ ვერ მáƒáƒ®áƒ”რხდრ(%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "ქვეპრáƒáƒªáƒ”სის (%s) გáƒáƒœáƒ¢áƒáƒ¢áƒ•ის შეცდáƒáƒ›áƒ (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "პრáƒáƒªáƒ”სის გáƒáƒœáƒ¢áƒáƒ¢áƒ•ის შეცდáƒáƒ›áƒ (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის ცვლილების შეცდáƒáƒ›áƒ \"%s\" (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "შვილáƒáƒ‘ილი პრáƒáƒªáƒ”სის %s გáƒáƒ¨áƒ•ების შეცდáƒáƒ›áƒ %s" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "დესკრიპტáƒáƒ áƒ˜áƒ¡áƒ—ვის ფáƒáƒ˜áƒšáƒ˜áƒ¡ გáƒáƒ“áƒáƒ›áƒáƒ’რების შეცდáƒáƒ›áƒ (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "შვილეული პრáƒáƒªáƒ”სისთვის (%s) ფáƒáƒ˜áƒšáƒ˜áƒ¡ დესკრიპტáƒáƒ áƒ˜áƒ¡ დუბლირების შეცდáƒáƒ›áƒ" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "დáƒáƒ›áƒ®áƒ›áƒáƒ áƒ” პრáƒáƒªáƒ”სის გáƒáƒ¨áƒ•ების შეცდáƒáƒ›áƒ (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "შვილეული პრáƒáƒªáƒ”სის (%s) ფáƒáƒ˜áƒšáƒ˜áƒ¡ დესკრიპტáƒáƒ áƒ˜áƒ¡ დáƒáƒ®áƒ£áƒ áƒ•ის შეცდáƒáƒ›áƒ" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "შეცდáƒáƒ›áƒ შვილეული პრáƒáƒªáƒ”სის (%s) შესრულებისáƒáƒ¡" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "ქვეპრáƒáƒªáƒ”სის áƒáƒ áƒ®áƒ˜áƒ“áƒáƒœ სáƒáƒ™áƒ›áƒáƒ áƒ˜áƒ¡ მáƒáƒœáƒáƒªáƒ”მთრწáƒáƒ™áƒ˜áƒ—ხვრვერ მáƒáƒ®áƒ”რხდრ(%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "მáƒáƒœáƒáƒªáƒ”მთრწáƒáƒ™áƒ˜áƒ—ხვრქვეპრáƒáƒªáƒ”სიდáƒáƒœ ვერ მáƒáƒ®áƒ”რხდáƒ" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ქვეპრáƒáƒªáƒ”სის გáƒáƒ›áƒáƒ§áƒ”ნებრვერ მáƒáƒ®áƒ”რხდრ(%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "ქვეპრáƒáƒªáƒ”სში dup()-ის შეცდáƒáƒ›áƒ (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "პრáƒáƒ’რáƒáƒ›áƒ˜áƒ¡ მცდáƒáƒ áƒ˜ სáƒáƒ®áƒ”ლი: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "მცდáƒáƒ áƒ˜ სტრიქáƒáƒœáƒ˜ áƒáƒ áƒ’უმენტის ვექტáƒáƒ áƒ¨áƒ˜ - %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "მცდáƒáƒ áƒ˜ სტრიქáƒáƒœáƒ˜ გáƒáƒ áƒ”მáƒáƒ¨áƒ˜: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "უმáƒáƒ áƒ—ებლრსáƒáƒ›áƒ£áƒ¨áƒáƒ დáƒáƒ¡áƒ¢áƒ: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "დáƒáƒ®áƒ›áƒáƒ áƒ”ბის პრáƒáƒ’რáƒáƒ›áƒ˜áƒ¡ (%s) გáƒáƒ›áƒáƒ§áƒ”ნებრვერ მáƒáƒ®áƒ”რხდáƒ" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"მáƒáƒ£áƒšáƒáƒ“ნელი შეცდáƒáƒ›áƒ ფუნქციáƒáƒ¨áƒ˜ g_io_channel_win32_poll() ქვეპრáƒáƒªáƒ”სიდáƒáƒœ " +"მáƒáƒœáƒáƒªáƒ”მთრწáƒáƒ™áƒ˜áƒ—ხვისáƒáƒ¡" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI \"%s\" áƒáƒ‘სáƒáƒšáƒ£áƒ¢áƒ£áƒ áƒ˜ იდენტიფიკáƒáƒ¢áƒáƒ áƒ˜ áƒáƒ  გáƒáƒ®áƒšáƒáƒ•თ" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "სიმბáƒáƒšáƒ UTF-8 რáƒáƒœáƒ’ს გáƒáƒ áƒ”თáƒáƒ" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "შეტáƒáƒœáƒ˜áƒ¡ ტექსტის გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ˜áƒ¡ მცდáƒáƒ áƒ˜ მიმდევრáƒáƒ‘áƒ" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "სიმბáƒáƒšáƒ UTF-16 რáƒáƒœáƒ’ს გáƒáƒ áƒ”თáƒáƒ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ბáƒáƒ˜áƒ¢áƒ˜" +msgstr[1] "%u ბáƒáƒ˜áƒ¢áƒ˜" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "" +msgstr[1] "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ბáƒáƒ˜áƒ¢áƒ˜" +msgstr[1] "%s ბáƒáƒ˜áƒ¢áƒ˜" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s ბიტი" +msgstr[1] "%s ბიტი" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f კბ" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f მბ" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f გბ" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ტბ" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f პბ" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ებ" diff --git a/po/kk.po b/po/kk.po new file mode 100644 index 0000000..988e2d0 --- /dev/null +++ b/po/kk.po @@ -0,0 +1,6017 @@ +# glib to kazakh. +# Copyright (C) 2010 HZ +# This file is distributed under the same license as the glib package. +# Baurzhan Muftakhidinov , 2010-2021. +# +msgid "" +msgstr "" +"Project-Id-Version: master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-02-14 13:48+0000\n" +"PO-Revision-Date: 2022-03-12 22:39+0500\n" +"Last-Translator: Baurzhan Muftakhidinov \n" +"Language-Team: Kazakh \n" +"Language: kk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 3.0.1\n" + +#: gio/gappinfo.c:333 +#| msgid "Cancellable initialization not supported" +msgid "Setting default applications not supported yet" +msgstr "" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" + +#: gio/gapplication.c:497 +msgid "GApplication options" +msgstr "GApplication опциÑлары" + +#: gio/gapplication.c:497 +msgid "Show GApplication options" +msgstr "GApplication опциÑларын көрÑету" + +#: gio/gapplication.c:542 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" + +#: gio/gapplication.c:554 +msgid "Override the application’s ID" +msgstr "" + +#: gio/gapplication.c:566 +msgid "Replace the running instance" +msgstr "" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Көмекті шығару" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[КОМÐÐДÐ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "ÐÒ±Ñқа ақпаратын шығару" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "ÐÒ±Ñқа ақпаратын шығару және шығу" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Қолданбаларды тізіп шығару" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Қолданбаны жөнелту" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [ФÐЙЛ…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Әрекетті белÑендіру" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ӘРЕКЕТ [ПÐРÐМЕТР]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Қолжетерлік әрекеттерді тізіп шығару" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "КОМÐÐДÐ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "ФÐЙЛ" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ӘРЕКЕТ" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "ПÐРÐМЕТР" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Қолданылуы:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Ðргументтер:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ÐРГУМЕÐТТЕР…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Командалар:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"\"%s\" аргументтерді қабылдамайды\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"команда танылмады: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1873 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Әрекеттен Ð±Ð°Ñ Ñ‚Ð°Ñ€Ñ‚Ñ‹Ð»Ð´Ñ‹" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "МақÑат жерінде жеткілікті орын жоқ" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Түрлендіру кіріÑінде жарамÑыз байттар тізбегі анықталды" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Ð‘Ð°Ñ Ñ‚Ð°Ñ€Ñ‚ÑƒÒ“Ð° болатын инициализациÑға қолдау жоқ" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s түрі" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "БелгіÑіз түрі" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s файл түрі" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "" + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "\"%s\" файлын ашу қатеÑÑ–: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "\"%s\" nonce файлынан оқу қатеÑÑ–: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "" + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7334 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7343 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "\"%s\" бума ақпаратын алу қатеÑÑ–: %s" + +#: gio/gdbusauthmechanismsha1.c:314 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:347 gio/gdbusauthmechanismsha1.c:358 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "\"%s\" бумаÑын жаÑау қатеÑÑ–: %s" + +#: gio/gdbusauthmechanismsha1.c:360 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Әрекетке қолдау жоқ" + +#: gio/gdbusauthmechanismsha1.c:403 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:426 gio/gdbusauthmechanismsha1.c:748 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:440 gio/gdbusauthmechanismsha1.c:762 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:454 gio/gdbusauthmechanismsha1.c:776 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:478 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:524 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:588 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:627 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:638 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:715 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:909 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2418 +msgid "The connection is closed" +msgstr "Ð‘Ð°Ð¹Ð»Ð°Ð½Ñ‹Ñ Ð¶Ð°Ð±Ñ‹Ð»Ò“Ð°Ð½" + +#: gio/gdbusconnection.c:1903 +msgid "Timeout was reached" +msgstr "" + +#: gio/gdbusconnection.c:2541 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: gio/gdbusconnection.c:4269 gio/gdbusconnection.c:4623 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" + +#: gio/gdbusconnection.c:4414 +#, c-format +msgid "No such property “%sâ€" +msgstr "\"%s\" қаÑиеті табылмады" + +#: gio/gdbusconnection.c:4426 +#, c-format +msgid "Property “%s†is not readable" +msgstr "\"%s\" қаÑиетін оқу мүмкін емеÑ" + +#: gio/gdbusconnection.c:4437 +#, c-format +msgid "Property “%s†is not writable" +msgstr "\"%s\" қаÑиетін жазу мүмкін емеÑ" + +#: gio/gdbusconnection.c:4457 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:4562 gio/gdbusconnection.c:4777 +#: gio/gdbusconnection.c:6760 +#, c-format +msgid "No such interface “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:4999 gio/gdbusconnection.c:7274 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "" + +#: gio/gdbusconnection.c:5100 +#, c-format +msgid "No such method “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:5131 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:5334 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: gio/gdbusconnection.c:5561 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "" + +#: gio/gdbusconnection.c:5617 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "%s қаÑиетін орнату мүмкін емеÑ.%s" + +#: gio/gdbusconnection.c:5796 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "" + +#: gio/gdbusconnection.c:6872 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "" + +#: gio/gdbusconnection.c:6993 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: gio/gdbusconnection.c:7282 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "" + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "" + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "" + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "\"%s\" үшін nonce файлын жазу қатеÑÑ–: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1244 +#: gio/gdbus-tool.c:1732 +#, c-format +msgid "Error: %s\n" +msgstr "Қате: %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1748 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1063 +#: gio/gdbus-tool.c:1898 gio/gdbus-tool.c:2138 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" + +#: gio/gdbus-tool.c:531 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "Сигналды жіберу." + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:1000 gio/gdbus-tool.c:1835 +#: gio/gdbus-tool.c:2067 gio/gdbus-tool.c:2287 +#, c-format +msgid "Error connecting: %s\n" +msgstr "БайланыÑу қатеÑÑ–: %s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1043 gio/gdbus-tool.c:1878 +msgid "Error: Object path is not specified\n" +msgstr "" + +#: gio/gdbus-tool.c:765 +msgid "Error: Signal name is not specified\n" +msgstr "Қате: Ñигнал көрÑетілмеген.\n" + +#: gio/gdbus-tool.c:779 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1175 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "" + +#: gio/gdbus-tool.c:894 +msgid "Destination name to invoke method on" +msgstr "" + +#: gio/gdbus-tool.c:895 +msgid "Object path to invoke method on" +msgstr "" + +#: gio/gdbus-tool.c:896 +msgid "Method and interface name" +msgstr "" + +#: gio/gdbus-tool.c:897 +msgid "Timeout in seconds" +msgstr "" + +#: gio/gdbus-tool.c:898 +#| msgid "Show information about locations" +msgid "Allow interactive authorization" +msgstr "" + +#: gio/gdbus-tool.c:945 +msgid "Invoke a method on a remote object." +msgstr "" + +#: gio/gdbus-tool.c:1017 gio/gdbus-tool.c:1852 gio/gdbus-tool.c:2092 +msgid "Error: Destination is not specified\n" +msgstr "" + +#: gio/gdbus-tool.c:1028 gio/gdbus-tool.c:1869 gio/gdbus-tool.c:2103 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "" + +#: gio/gdbus-tool.c:1078 +msgid "Error: Method name is not specified\n" +msgstr "" + +#: gio/gdbus-tool.c:1089 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "" + +#: gio/gdbus-tool.c:1167 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "" + +#: gio/gdbus-tool.c:1193 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "" + +#: gio/gdbus-tool.c:1694 +msgid "Destination name to introspect" +msgstr "" + +#: gio/gdbus-tool.c:1695 +msgid "Object path to introspect" +msgstr "" + +#: gio/gdbus-tool.c:1696 +msgid "Print XML" +msgstr "XML баÑпаға шығару" + +#: gio/gdbus-tool.c:1697 +msgid "Introspect children" +msgstr "" + +#: gio/gdbus-tool.c:1698 +msgid "Only print properties" +msgstr "Тек қаÑиеттерін баÑпаға шығару" + +#: gio/gdbus-tool.c:1787 +msgid "Introspect a remote object." +msgstr "" + +#: gio/gdbus-tool.c:1993 +msgid "Destination name to monitor" +msgstr "Бақылау үшін мақÑат атауы" + +#: gio/gdbus-tool.c:1994 +msgid "Object path to monitor" +msgstr "" + +#: gio/gdbus-tool.c:2019 +msgid "Monitor a remote object." +msgstr "" + +#: gio/gdbus-tool.c:2077 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: gio/gdbus-tool.c:2201 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2204 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: gio/gdbus-tool.c:2252 +msgid "[OPTION…] BUS-NAME" +msgstr "[ОПЦИЯ…] ШИÐÐ-ÐТЫ" + +#: gio/gdbus-tool.c:2253 +msgid "Wait for a bus name to appear." +msgstr "" + +#: gio/gdbus-tool.c:2329 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Қате: белÑендіру үшін қызмет көрÑетілуі керек.\n" + +#: gio/gdbus-tool.c:2334 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Қате: күту үшін қызмет көрÑетілуі керек.\n" + +#: gio/gdbus-tool.c:2339 +msgid "Error: Too many arguments.\n" +msgstr "" + +#: gio/gdbus-tool.c:2347 gio/gdbus-tool.c:2354 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Қате: \"%s\" - кеңінен белгілі шина аты емеÑ.\n" + +#: gio/gdebugcontrollerdbus.c:203 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "" + +#: gio/gdesktopappinfo.c:2174 gio/gdesktopappinfo.c:5099 +msgid "Unnamed" +msgstr "ÐтауÑыз" + +#: gio/gdesktopappinfo.c:2584 +msgid "Desktop file didn’t specify Exec field" +msgstr "" + +#: gio/gdesktopappinfo.c:2892 +msgid "Unable to find terminal required for application" +msgstr "" + +#: gio/gdesktopappinfo.c:3619 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" + +#: gio/gdesktopappinfo.c:3623 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" + +#: gio/gdesktopappinfo.c:3865 gio/gdesktopappinfo.c:3889 +msgid "Application information lacks an identifier" +msgstr "" + +#: gio/gdesktopappinfo.c:4125 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "%s пайдаланушы Ð¶Ò±Ð¼Ñ‹Ñ Ò¯Ñтел файлын жаÑау мүмкін емеÑ" + +#: gio/gdesktopappinfo.c:4261 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS қолдауы қолжетерÑіз" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS қолдауы қолжетерÑіз" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Бума Ò¯Ñтіне көшіру мүмкін емеÑ" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Буманы бума Ò¯Ñтіне көшіру мүмкін емеÑ" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "МақÑат файлы бар болып тұр" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Буманы рекурÑивті көшіру мүмкін емеÑ" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Ðрнайы файлды көшіру мүмкін емеÑ" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Символдық Ñілтемелерге қолдау жоқ" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "ÒšÐ¾Ò›Ñ‹Ñ ÑˆÐµÐ»ÐµÐ³Ñ–Ð½Ðµ қолдау жоқ" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "том тіркеуді жүзеге аÑырмайды" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "ХоÑÑ‚ аты қате" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "HTTP прокÑи жауабы қате" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP прокÑи байланыÑÑ‹ Ñ€Ò±Ò›Ñат етілмеген" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP прокÑи аутентификациÑÑÑ‹ ÑәтÑіз" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP прокÑи аутентификациÑÑÑ‹ керек" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP прокÑи байланыÑÑ‹ ÑәтÑіз аÑқталды: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP прокÑи жауабы тым үлкен" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP прокÑи Ñервері күтпегенде байланыÑты үзді." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "\"version\" аргументтерді қабылдамайды" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Қолданылуы:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "ÐÒ±Ñқа ақпаратын шығару және шығу." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Командалар:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Бір немеÑе бірнеше файлды көшіру" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "ОрналаÑулар жөнінде ақпаратты көрÑету" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Қолданбаны desktop файлынан жөнелту" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Бумаларды жаÑау" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Файлдар және бумаларды өзгеріÑтерге бақылау" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "ОрналаÑуларды тіркеу немеÑе тіркеуден боÑату" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Бір немеÑе бірнеше файлды жылжыту" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Файлдарды үнÑіз келіÑім қолданбаÑымен ашу" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Файл атын ауыÑтыру" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Бір немеÑе бірнеше файлды өшіру" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Қалыпты кіріÑтен оқу және Ñақтау" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Файл атрибутын орнату" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Файлдар немеÑе бумаларды Ò›Ð¾Ò›Ñ‹Ñ ÑˆÐµÐ»ÐµÐ³Ñ–Ð½Ðµ таÑтау" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Қалыпты шығыÑқа жазу қатеÑÑ–" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "ОРÐÐЛÐСУ" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Файлдарды біріктіріп, қалыпты шығыÑқа шығару." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "МақÑат бумаÑÑ‹ жоқ" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Орындалу барыÑын көрÑету" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Ò®Ñтінен жазу алдында Ñұрау" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Барлық атрибуттарды Ñақтап қалу" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Бар болып тұрған мақÑат файлдардың қор көшірмелерін жаÑау" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Символдық Ñілтемелер Ñоңынан ермеу" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ÒšÐЙÐÐР_КӨЗІ" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "МÐҚСÐТЫ" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "%s мақÑаты бума емеÑ" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: \"%s\" Ò¯Ñтінен жазу керек пе? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Файлдық жүйе ақпаратын алу" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ÐТРИБУТТÐР" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "атрибуттар:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "аты: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "түрі: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "өлшемі: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "жаÑырын\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Орнатуға болатын атрибуттар:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "ОрналаÑулар жөнінде ақпаратты көрÑету." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "‘%s‘ жүктеу мүмкін емеÑ: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "‘%s’ қолданбаÑын жөнелту мүмкін емеÑ: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "ЖаÑырын файлдарды көрÑету" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Толық URI шығару" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "ОрналаÑулар құрамаларын тізіп шығару." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIME_ТҮРІ" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Тіркелген қолданбалар:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Тіркелген қолданбалар жоқ\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Ò°Ñынылатын қолданбалар:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Ò°Ñынылатын қолданбалар жоқ\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Ðталық бумаларын жаÑау" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Бумаларды жаÑау." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Тіркелетін ретінде тіркеу" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Тіркеуден боÑату" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Шығару" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ҚҰРЫЛҒЫ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "СХЕМÐ" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Тізім" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Оқиғаларды бақылау" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "ҚоÑымша ақпаратты көрÑету" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "VeraCrypt томын ашу кезіндегі Ñандық PIM" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "ОрналаÑуларды тіркеу немеÑе тіркеуден шығару." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "%s мақÑаты бума ÐµÐ¼ÐµÑ Ð±Ð¾Ð»Ñ‹Ð¿ тұр" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "КөрÑетілген файлдарды өшіру." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "ÐТЫ" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Файл атын ауыÑтыру." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Ðргумент жетіÑпейді" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Жоқ болÑа ғана жаÑау" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Файл Ñоңына жалғау" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "ЖаÑау кезінде, Ñ€Ò±Ò›Ñатты ағымдағы пайдаланушымен шектеу" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "ÐлмаÑтыру кезінде, мақÑат жоқ болып тұрғандай алмаÑтыру" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Қалыпты кіріÑтен оқу қатеÑÑ–" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag қолжетерÑіз\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Стандартты кіріÑтен оқу және МÐҚСÐТҚРÑақтау." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Ðтрибут түрі" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "ТҮРІ" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ÐТРИБУТ" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "МӘÐІ" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "ОРÐÐЛÐСУДЫҢ файл атрибутын орнату." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "ОрналаÑу көрÑетілмеген" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Қате атрибут түрі \"%s\"" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "ÒšÐ¾Ò›Ñ‹Ñ ÑˆÐµÐ»ÐµÐ³Ñ–Ð½ тазарту" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "" +"ÒšÐ¾Ò›Ñ‹Ñ ÑˆÐµÐ»ÐµÐ³Ñ–Ð½Ð´ÐµÐ³Ñ– файлдарды олардың баÑтапқы орналаÑулармен бірге тізіп " +"шығару" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "" + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "" + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Файлдар немеÑе бумаларды Ò›Ð¾Ò›Ñ‹Ñ ÑˆÐµÐ»ÐµÐ³Ñ–Ð½Ðµ таÑтау немеÑе қалпына келтіру." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Символдық Ñілтемелер, тіркеулер және жарлықтар Ñоңынан еру" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Бумалар құрамаларын ағаш Ñ‚ÐµÐºÑ‚ÐµÑ Ð¿Ñ–ÑˆÑ–Ð¼Ð´Ðµ шығару." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> Ñлементін <%s> ішінде орналаÑтыру Ñ€Ò±Ò›Ñат етілмеген" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> Ñлементі жоғары деңгейде орналаÑуы Ñ€Ò±Ò›Ñат етілмеген" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "БелгіÑіз өңдеу опциÑÑÑ‹ \"%s\"" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s файлын оқу қатеÑÑ–: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "%s файлын Ñығу қатеÑÑ–" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "мәтін <%s> ішінде болмауы мүмкін" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "БУМÐ" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "" + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr "" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "<%s> ішінде тек бір <%s> Ñлементіне Ñ€Ò±Ò›Ñат етілген" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Мәтін <%s> ішінде көрÑетілмеуі керек" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "" + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "" + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "" + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Қате файл аты %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "%s үшін файлдық жүйе ақпаратын алу қатеÑÑ–: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Түбірлік буманың атын ауыÑтыру мүмкін емеÑ" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "%s файл атын ауыÑтыру қатеÑÑ–: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Файл атын ауыÑтыру мүмкін емеÑ, ондай файл бар болып тұр" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Файл аты қате" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "%s файлын ашу қатеÑÑ–: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "%s файлын өшіру қатеÑÑ–: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "%s файлын қоқыÑқа таÑтау қатеÑÑ–: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "%s Ò›Ð¾Ò›Ñ‹Ñ ÑˆÐµÐ»ÐµÐ³Ñ–Ð½ жаÑау мүмкін емеÑ: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "%s файлын қоқыÑқа таÑтау мүмкін емеÑ: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "%s файлын қоқыÑқа таÑтау мүмкін емеÑ" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "%s бумаÑын жаÑау қатеÑÑ–: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "%s Ñимволдық ÑілтемеÑін жаÑау қатеÑÑ–: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "%s файлын жылжыту қатеÑÑ–: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Буманы бума Ò¯Ñтіне жылжыту мүмкін емеÑ" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Қор көшірме файлын жаÑау ÑәтÑіз аÑқталды" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "МақÑат файлын өшіру қатеÑÑ–: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "\"%s\" кеңейтілген атрибутын орнату қатеÑÑ–: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (кодталуы қате)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "\"%s\" файлы ақпаратын алу қатеÑÑ–: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ðтрибут түрі жарамÑыз (uint64 күтілген)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "РұқÑаттарды орнату қатеÑÑ–: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "ИеÑін орнату қатеÑÑ–: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Файлдан оқу қатеÑÑ–: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Файлды жабу қатеÑÑ–: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Файлдан іздеу қатеÑÑ–: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Файлға жазу қатеÑÑ–: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "\"%s\" файлын ашу қатеÑÑ–: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "МақÑат файлы бума болып тұр" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "МақÑат файлы қалыпты файл ÐµÐ¼ÐµÑ Ð±Ð¾Ð»Ñ‹Ð¿ тұр" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Файл Ñыртқы түрде өзгертілді" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "ЕÑкі файлды өшіру қатеÑÑ–: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Желі қолжетерÑіз" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "ХоÑÑ‚ қолжетерÑіз" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "" + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager орындалы тұрған жоқ" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager нұÑқаÑÑ‹ тым еÑкі" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "" + +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "ХоÑÑ‚ аты қате" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "ЖОЛ" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr "" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr "" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr "" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Сокет Е/Ш күту мерзімі аÑқталған" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "" + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Хабарламаны жіберу мүмкін емеÑ: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Хабарламаны жіберу ÑәтÑіз: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "" + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "БайланыÑу мүмкін емеÑ: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "" + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "" + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Қатынау Ñ€Ò±Ò›Ñаты блокталуға дейінгі парольді енгізудің Ñоңғы мүмкіндігі қалды." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Парольді енгізудің бірнеше талабы ÑәтÑіз болды, қатынау Ñ€Ò±Ò›Ñаты келеÑÑ– " +"ÑәтÑіз енгізулерде блокталатын болады." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "" + +#: gio/gunixconnection.c:125 +#| msgid "Symbolic links not supported" +msgid "Sending FD is not supported" +msgstr "" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "" + +#: gio/gunixconnection.c:238 +#| msgid "Operation not supported" +msgid "Receiving FD is not supported" +msgstr "" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "" + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "" + +#: gio/gunixmounts.c:2782 gio/gunixmounts.c:2835 +msgid "Filesystem root" +msgstr "Файлдық жүйе түбірі" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Жады жеткілікÑіз" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Ішкі қате: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Көбірек ÐºÑ–Ñ€Ñ–Ñ ÐºÐµÑ€ÐµÐº" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "ЖарамÑыз Ñығылған деректер" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI \"%s\" қате" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Қаңтар" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Ðқпан" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Ðаурыз" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Сәуір" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Мамыр" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "МауÑым" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Шілде" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Тамыз" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Қыркүйек" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Қазан" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Қараша" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "ЖелтоқÑан" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Қаң" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Ðқп" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Ðау" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Сәу" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Мам" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Мау" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Шіл" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Там" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Қыр" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Қаз" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Қар" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Жел" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "ДүйÑенбі" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "СейÑенбі" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "СәрÑенбі" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "БейÑенбі" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Жұма" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Сенбі" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ЖекÑенбі" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ДÑ" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "СÑ" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ср" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "БÑ" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Жм" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Сн" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Жк" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Қаңтар" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Ðқпан" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Ðаурыз" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "Сәуір" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Мамыр" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "МауÑым" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Шілде" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "Тамыз" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Қыркүйек" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Қазан" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "Қараша" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "ЖелтоқÑан" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Қаң" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Ðқп" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Ðау" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Сәу" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Мам" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Мау" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Шіл" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Там" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Қыр" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Қаз" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Қар" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Жел" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "\"%s\" бумаÑын ашу қатеÑÑ–: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "\"%s\" файлын оқу қатеÑÑ–: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "\"%s\" файлы тым үлкен" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "\"%s\" файлынан оқу қатеÑÑ–: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "\"%s\" файлын ашу қатеÑÑ–: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "\"%s\" файлын жазу ÑәтÑіз: write() ÑәтÑіз аÑқталды: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "\"%s\" файлын жазу ÑәтÑіз: fsync() ÑәтÑіз аÑқталды: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "\"%s\" файлын жаÑау ÑәтÑіз: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Қалыпты файл емеÑ" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Қате топ аты: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "" + +#: glib/gkeyfile.c:1394 +#, c-format +#| msgid "Invalid filename %s" +msgid "Invalid key name: %.*s" +msgstr "" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "" + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "" + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "" + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "\"%s\" файлын ашу ÑәтÑіз: open() аÑқталды: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "\"%s\" Ð´Ò±Ñ€Ñ‹Ñ Ð°Ñ‚Ð°Ñƒ емеÑ" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "\"%s\" Ð´Ò±Ñ€Ñ‹Ñ Ð°Ñ‚Ð°Ñƒ емеÑ: \"%c\"" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[ОПЦИЯ…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Көмек опциÑлары:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Көмек опциÑларын көрÑету" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Барлық көмек опциÑларын көрÑету" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Қолданба опциÑлары:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "ОпциÑлар:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "БелгіÑіз Ð¾Ð¿Ñ†Ð¸Ñ %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "жады жеткілікÑіз" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "ішкі қате" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "қате шегініÑ" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "қыÑқа utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "белгіÑіз қате" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) танылмады" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "Ñан тым үлкен" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "(?+ кейін Ñан күтілген" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "Ñан күтілген" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "белгіÑіз escape тізбегі" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Мәтін Ð±Ð¾Ñ Ð±Ð¾Ð»Ð´Ñ‹ (немеÑе тек Ð±Ð¾Ñ Ð°Ñ€Ð°Ð»Ñ‹Ò›Ñ‚Ð°Ð½ тұрды)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: glib/gspawn.c:461 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "" + +#: glib/gspawn.c:546 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: glib/gspawn.c:1168 glib/gspawn-win32.c:1426 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: glib/gspawn.c:1176 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process exited abnormally" +msgstr "" + +#: glib/gspawn.c:1881 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: glib/gspawn.c:2241 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "" + +#: glib/gspawn.c:2358 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: glib/gspawn.c:2518 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "\"%s\" бумаÑына ауыÑу ÑәтÑіз аÑқталды (%s)" + +#: glib/gspawn.c:2528 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "" + +#: glib/gspawn.c:2538 +#, c-format +#| msgid "Failed to open file “%sâ€: open() failed: %s" +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" + +#: glib/gspawn.c:2546 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "" + +#: glib/gspawn.c:2555 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: glib/gspawn.c:2563 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "" + +#: glib/gspawn.c:2571 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "" + +#: glib/gspawn.c:2595 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:519 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: glib/gspawn-win32.c:400 +#, c-format +#| msgid "Failed to execute helper program (%s)" +msgid "Failed to dup() in child process (%s)" +msgstr "" + +#: glib/gspawn-win32.c:469 +#, c-format +msgid "Invalid program name: %s" +msgstr "Бағдарлама аты қате: %s" + +#: glib/gspawn-win32.c:479 glib/gspawn-win32.c:797 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: glib/gspawn-win32.c:490 glib/gspawn-win32.c:813 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: glib/gspawn-win32.c:793 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ð–Ò±Ð¼Ñ‹Ñ Ð±ÑƒÐ¼Ð°ÑÑ‹ қате: %s" + +#: glib/gspawn-win32.c:858 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Көмекші бағдарламаны орындау қатеÑÑ– (%s)" + +#: glib/gspawn-win32.c:1086 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "\"%s\" таңбаÑÑ‹ бар Ñан емеÑ" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "\"%s\" таңбаÑÑ‹ жоқ Ñан емеÑ" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Жадыны бөлу ÑәтÑіз" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f КБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ТБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ПБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ЭБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f КиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f МиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f ГиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f ТиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f ПиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f ЭиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f кб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Мб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Гб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Тб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Пб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Эб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Киб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Миб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Гиб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Тиб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Пиб" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Эиб" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u байт" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u бит" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s байт" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s бит" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f КБ" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ТБ" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ПБ" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ЭБ" + +#~ msgid "Unknown error on connect" +#~ msgstr "БайланыÑты орнату кезіндегі белгіÑіз қате" + +#~ msgid "[ARGS...]" +#~ msgstr "[ÐРГУМЕÐТТЕР...]" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "ОрналаÑуды тіркеу қатеÑÑ–: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Тіркеуден боÑату қатеÑÑ–: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "%s тіркеу қатеÑÑ–: %s\n" + +#~ msgid "No files to open" +#~ msgstr "Ðшу үшін файлдар жоқ" + +#~ msgid "No files to delete" +#~ msgstr "Өшіру үшін файлдар жоқ" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Ðтрибутты орнату қатеÑÑ–: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "'%s' бумаÑын жаÑау қатеÑÑ–: %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "'%s' файлын ашу қатеÑÑ–: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Файлды ашу қатеÑÑ–: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Буманы жаÑау қатеÑÑ–: %s" + +#~ msgid "File is empty" +#~ msgstr "Файл боÑ" diff --git a/po/kn.po b/po/kn.po new file mode 100644 index 0000000..fea7fe8 --- /dev/null +++ b/po/kn.po @@ -0,0 +1,4764 @@ +# translation of glib.master.kn.po to Kannada +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Shankar Prasad , 2007, 2008, 2009, 2010, 2012, 2013, 2014. +# Shankar , 2013. #zanata. +msgid "" +msgstr "" +"Project-Id-Version: glib.master.kn\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-12-12 06:46+0000\n" +"PO-Revision-Date: 2014-12-12 17:24+0530\n" +"Last-Translator: Shankar Prasad \n" +"Language-Team: American English \n" +"Language: kn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.5\n" + +#: ../gio/gapplication.c:520 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication ಸೇವೆಯ ಕà³à²°à²®à²µà²¨à³à²¨à³ ನಮೂದಿಸಿ (D-Bus ಸೇವೆ ಕಡತಗಳಿಂದ ಬಳಸà³)" + +#: ../gio/gapplication.c:525 +msgid "GApplication options" +msgstr "GApplication ಆಯà³à²•ೆಗಳà³" + +#: ../gio/gapplication.c:525 +msgid "Show GApplication options" +msgstr "GApplication ಆಯà³à²•ೆಗಳನà³à²¨à³ ತೋರಿಸà³" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:485 ../gio/gsettings-tool.c:521 +msgid "Print help" +msgstr "ಮà³à²¦à³à²°à²£ ಸಹಾಯ" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:486 +#: ../gio/gresource-tool.c:554 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "ಮà³à²¦à³à²°à²£à²¦ ಆವೃತà³à²¤à²¿" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:527 +msgid "Print version information and exit" +msgstr "ಆವೃತà³à²¤à²¿à²¯ ಮಾಹಿತಿಯನà³à²¨à³ ಮà³à²¦à³à²°à²¿à²¸à²¿ ನಿರà³à²—ಮಿಸà³à²¤à³à²¤à²¦à³†" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "ಅನà³à²µà²¯à²—ಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"ಅನà³à²¸à³à²¥à²¾à²ªà²¿à²¸à²²à²¾à²¦ D-Bus ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸಬಹà³à²¦à²¾à²¦ ಅನà³à²µà²¯à²—ಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡೠ(.desktop " +"ಕಡತಗಳಿಂದ)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "ಅನà³à²µà²¯à²µà²¨à³à²¨à³ ಆರಂಭಿಸà³" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "ಅನà³à²µà²¯à²µà²¨à³à²¨à³ ಆರಂಭಿಸೠ(ತೆರೆಯಬೇಕಿರà³à²µ à²à²šà³à²›à²¿à²• ಕಡತಗಳೊಂದಿಗೆ)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "ಒಂದೠಕà³à²°à²¿à²¯à³†à²¯à²¨à³à²¨à³ ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸà³" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "ಅನà³à²µà²¯à²¦à²²à³à²²à²¿ ಒಂದೠಕà³à²°à²¿à²¯à³†à²¯à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸà³" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "ಲಭà³à²¯à²µà²¿à²°à³à²µ ಆಯà³à²•ೆಗಳ ಪಟà³à²Ÿà²¿" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "ಒಂದೠಅನà³à²µà²¯à²•à³à²•ಾಗಿ ಸà³à²¥à²¿à²° ಕà³à²°à²¿à²¯à³†à²—ಳ ಪಟà³à²Ÿà²¿ (.desktop ಕಡತದಿಂದ)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "ವಿವರವಾದ ನೆರವಿಗಾಗಿ ಮà³à²¦à³à²°à²¿à²¸à²¬à³‡à²•ಿರà³à²µ ಆದೇಶ" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus ವಿನà³à²¯à²¾à²¸à²¦à²²à³à²²à²¿ ಅನà³à²µà²¯ ಗà³à²°à³à²¤à³ (ಉದಾ: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:492 +#: ../gio/gresource-tool.c:558 +msgid "FILE" +msgstr "FILE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "ತೆರೆಯಬೇಕಿರà³à²µ à²à²šà³à²›à²¿à²• ಹೋಲಿಕೆಯ ಅಥವ ಹೋಲಿಕೆಯ ಕಡತದ ಹೆಸರà³à²—ಳà³, ಅಥವ URIಗಳà³" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "ACTION" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "ರದà³à²¦à³à²®à²¾à²¡à²¬à³‡à²•ಿರà³à²µ ಕà³à²°à²¿à²¯à³†à²¯ ಹೆಸರà³" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "GVariant ನಲà³à²²à²¿ ರದà³à²§à²¤à²¿à²¯ ಕಾರà³à²¯à²¦ à²à²šà³à²›à²¿à²• ನಿಯತಾಂಕ" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:523 +#: ../gio/gsettings-tool.c:607 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"ಗೊತà³à²¤à²¿à²°à²¦ ಆದೇಶ %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "ಬಳಕೆ:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:548 +#: ../gio/gsettings-tool.c:641 +msgid "Arguments:\n" +msgstr "ಆರà³à²—à³à²¯à³à²®à³†à²‚ಟà³à²—ಳà³:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "ಆದೇಶಗಳà³:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"ವಿವರವಾದ ನೆರವನà³à²¨à³ ಪಡೆಯಲೠ'%s help COMMAND' ಅನà³à²¨à³ ಬಳಸಿ.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s ಆದೇಶಕà³à²•ಾಗಿ ನೇರವಾಗಿ ಅನà³à²¸à²°à²¿à²¸à²²à³ ಒಂದೠಅನà³à²µà²¯ id ಯ ಅಗತà³à²¯à²µà²¿à²¦à³†\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಅನà³à²µà²¯ id: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' ಯಾವà³à²¦à³† ಆರà³à²—à³à²¯à³à²®à³†à²‚ಟೠಅನà³à²¨à³ ತೆಗೆದà³à²•ೊಳà³à²³à³à²µà³à²¦à²¿à²²à³à²²\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus ಗೆ ಸಂಪರà³à²• ಹೊಂದಲಾಗಿಲà³à²²: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "ಅನà³à²µà²¯à²•à³à²•ೆ %s ಸಂದೇಶವನà³à²¨à³ ಕಳà³à²¹à²¿à²¸à³à²µà²²à³à²²à²¿ ದೋಷ: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "ಕà³à²°à²¿à²¯à³†à²¯ ಹೆಸರನà³à²¨à³ ಅನà³à²µà²¯ idಯ ನಂತರ ನೀಡಬೇಕà³\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"ಅಮಾನà³à²¯à²µà²¾à²¦ ಕà³à²°à²¿à²¯à³†à²¯ ಹೆಸರà³: '%s'\n" +"ಕà³à²°à²¿à²¯à³†à²¯ ಹೆಸರೠಕೇವಲ ಅಕà³à²·à²°à²…ಂಕಿಗಳà³, '-' ಮತà³à²¤à³ '.' ಅನà³à²¨à³ ಮಾತà³à²° ಹೊಂದಿರಬೇಕà³\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "ಕà³à²°à²¿à²¯à³†à²¯ ನಿಯತಾಂಕವನà³à²¨à³ ಪಾರà³à²¸à³ ಮಾಡà³à²µà²²à³à²²à²¿ ದೋಷ: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "ಕà³à²°à²¿à²¯à³†à²—ಳೠಗರಿಷà³à²Ÿ ಒಂದೠನಿಯತಾಂಕವನà³à²¨à³ ಮಾತà³à²° ತೆಗೆದà³à²•ೊಳà³à²³à²¬à²²à³à²²à²¦à³\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "ಪಟà³à²Ÿà²¿-ಕà³à²°à²¿à²¯à³†à²—ಳ ಆದೇಶವೠಕೇವಲ ಅನà³à²µà²¯ id ಅನà³à²¨à³ ಮಾತà³à²° ತೆಗೆದà³à²•ೊಳà³à²³à³à²¤à³à²¤à²¦à³†" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "%s ಅನà³à²µà²¯à²•à³à²•ಾಗಿ ಅಗತà³à²¯à²µà²¿à²°à³à²µ ಗಣಕತೆರೆ ಕಡತವೠಕಂಡà³à²¬à²‚ದಿಲà³à²²\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"ಗà³à²°à³à²¤à²¿à²¸à²²à²¾à²—ದ ಆದೇಶ: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:376 +#: ../gio/ginputstream.c:614 ../gio/ginputstream.c:1013 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:830 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s ಗೆ ಬಹಳ ದೊಡà³à²¡à²¦à²¾à²¦ ಎಣಿಕೆ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ರವಾನಿಸಲಾಗಿದೆ" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "ಮೂಲ ಸà³à²Ÿà³à²°à³€à²®à³â€à²¨à²²à³à²²à²¿ ಕೋರà³à²µà²¿à²•ೆಗೆ ಬೆಂಬಲವಿಲà³à²²" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream ಅನà³à²¨à³ ಕಡಿತಗೊಳಿಸಲಾಗಿಲà³à²²" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1202 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1654 +msgid "Stream is already closed" +msgstr "ಸà³à²Ÿà³à²°à³€à²®à³ ಈಗಾಗಲೆ ಮà³à²šà³à²šà²²à³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "ಮೂಲ ಸà³à²Ÿà³à²°à³€à²®à³â€à²¨à²²à³à²²à²¿ ಕಡಿತಗೊಳಿಸಲೠಅನà³à²®à²¤à²¿à²¯ ಇಲà³à²²" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "ಕಾರà³à²¯à²µà³ ರದà³à²¦à³à²—ೊಂಡಿದೆ" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ವಸà³à²¤à³, ಆರಂಭಿಸಲಾಗಿಲà³à²²" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "ಆದಾನದಲà³à²²à²¿à²¨ ಅಪೂರà³à²£à²µà²¾à²¦ ಮಲà³à²Ÿà²¿à²¬à³ˆà²Ÿà³ ಅನà³à²•à³à²°à²®" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "ಗà³à²°à²¿à²¯à²²à³à²²à²¿ ಸಾಕಷà³à²Ÿà³ ಸà³à²¥à²³à²µà²¿à²²à³à²²" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "ಪರಿವರà³à²¤à²¿à²¤ ಆದಾನದಲà³à²²à²¿à²¨ ಬೈಟೠಅನà³à²•à³à²°à²® ಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "ಪರಿವರà³à²¤à²¿à²¸à³à²µà²¾à²— ದೋಷ: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "ರದà³à²¦à³à²—ೊಳಿಸಬಹà³à²¦à²¾à²¦ ಆರಂಭಕà³à²•ೆ ಬೆಂಬಲವಿಲà³à²²" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "'%s' ಅಕà³à²·à²°à²—ಳಿಂದ '%s' ಗೆ ಪರಿವರà³à²¤à²¿à²¸à³à²µà³à²¦à³ ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' ನಿಂದ '%s'ಗೆ ಪರಿವರà³à²¤à²•ವನà³à²¨à³ ತೆರೆಯಲಾಗà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s ಬಗೆ" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "ಗೊತà³à²¤à²¿à²°à²¦ ಬಗೆ" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s ಕಡತದ ಬಗೆ" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "ಈ OS ನಲà³à²²à²¿ GCredentials ಅನà³à²¨à³ ಅಳವಡಿಸಲಾಗಿಲà³à²²" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "ನಿಮà³à²® ಪà³à²²à²¾à²Ÿà³â€Œà²«à²¾à²°à³à²®à²¿à²—ೆ GCredentials ಬೆಂಬಲವಿಲà³à²²" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "ಈ OS ನಲà³à²²à²¿ GCredentials ಒಂದೠಪà³à²°à²•à³à²°à²¿à²¯à³† ID ಯನà³à²¨à³ ಹೊಂದಿಲà³à²²" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "ಈ OS ನಲà³à²²à²¿ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಕದಿಯà³à²µà³à²¦à³ ಸಾಧà³à²¯à²µà²¿à²°à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "ಸà³à²Ÿà³à²°à³€à²®à³â€à²¨ ಅನಿರೀಕà³à²·à²¿à²¤ ಕà³à²·à²¿à²ªà³à²° ಅಂತà³à²¯" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "ಬೆಂಬಲವಿರದ '%s' ಕೀಲಿ, '%s' ಎಂಬ ವಿಳಾಸ ನಮೂದಿನಲà³à²²à²¿" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"'%s' ವಿಳಾಸವೠಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ (ನಿಖರವಾಗಿ ಒಂದೠಮಾರà³à²—, tmpdir ಅಥವ ಅಬà³â€Œà²¸à³à²Ÿà³à²°à²¾à²•à³à²Ÿà³â€ " +"ಕೀಲಿಗಳ " +"ಅಗತà³à²¯à²µà²¿à²¦à³†)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "'%s' ವಿಳಾಸ ನಮೂದಿನಲà³à²²à²¿ ಅರà³à²¥à²µà²¿à²²à³à²²à²¦ ಕೀಲಿ/ಮೌಲà³à²¯à²¦ ಜೋಡಿಯ ಸಂಯೋಜನೆ" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "'%s' ಎಂಬ ವಿಳಾಸದಲà³à²²à²¿ ದೋಷ - ಸಂಪರà³à²•ಸà³à²¥à²¾à²¨ ಗà³à²£à²µà²¿à²¶à³‡à²·à²µà³ ತಪà³à²ªà²¾à²—ಿದೆ" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "'%s' ಎಂಬ ವಿಳಾಸದಲà³à²²à²¿ ದೋಷ - ಕà³à²²à²¦ ಗà³à²£à²µà²¿à²¶à³‡à²·à²µà³ ತಪà³à²ªà²¾à²—ಿದೆ" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "'%s' ಎಂಬ ವಿಳಾಸದ ಘಟಕವೠಒಂದೠವಿವರಣೆ ಚಿಹà³à²¨à³†à²¯à²¨à³à²¨à³ (:) ಹೊಂದಿಲà³à²²" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" +"ಕೀಲಿ/ಮೌಲà³à²¯ ಜೋಡಿ %d, '%s', '%s' ವಿಳಾಸ ಪà³à²¸à³à²¤à²•ದಲà³à²²à²¿ ಒಂದೠಸಮಚಿಹà³à²¨à³†à²¯à²¨à³à²¨à³ ಹೊಂದಿಲà³à²²" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"%d,'%s', ಕೀಲಿ ಅಥವ ಕೀಲಿ/ಮೌಲà³à²¯ ಜೋಡಿಯ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಅನà³â€Œà²Žà²¸à³à²•ೇಪà³â€Œ ಮಾಡà³à²µà²²à³à²²à²¿ ದೋಷ ('%" +"s' ಎಂಬ " +"ವಿಳಾಸದ ಘಟಕದಲà³à²²à²¿)" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"'%s' ವಿಳಾಸದಲà³à²²à²¿ ದೋಷ - ಯà³à²¨à²¿à²•à³à²¸à³ ವರà³à²—ಾವಣೆಗಾಗಿ `path' ಅಥವ `abstract' ನಲà³à²²à²¿ " +"ಕನಿಷà³à²Ÿ " +"ಒಂದೠಕೀಲಿಯನà³à²¨à³ ಹೊಂದಿಸಬೇಕಾಗà³à²¤à³à²¤à²¦à³†" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "'%s' ಎಂಬ ವಿಳಾಸದಲà³à²²à²¿ ದೋಷ - ಆತಿಥೇಯ ಗà³à²£à²µà²¿à²¶à³‡à²·à²µà³ ಇಲà³à²² ಅಥವ ತಪà³à²ªà²¾à²—ಿದೆ" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "'%s' ಎಂಬ ವಿಳಾಸದಲà³à²²à²¿ ದೋಷ - ಸಂಪರà³à²•ಸà³à²¥à²¾à²¨ ಗà³à²£à²µà²¿à²¶à³‡à²·à²µà³ ಇಲà³à²² ಅಥವ ತಪà³à²ªà²¾à²—ಿದೆ" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "'%s' ಎಂಬ ವಿಳಾಸದಲà³à²²à²¿ ದೋಷ - noncefile ಗà³à²£à²µà²¿à²¶à³‡à²·à²µà³ ಇಲà³à²² ಅಥವ ತಪà³à²ªà²¾à²—ಿದೆ" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "ಸà³à²µà²¯à²‚-ಆರಂಭಗೊಳಿಕೆ ದೋಷ: " + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "ಅಜà³à²žà²¾à²¤à²µà²¾à²¦ ಅಥವ ಬೆಂಬಲವಿರದ ವರà³à²—ಾವಣೆ '%s', '%s' ವಿಳಾಸಕà³à²•ಾಗಿ" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "nonce '%s' ಕಡತವನà³à²¨à³ ತೆರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "nonce '%s' ಕಡತವನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "" +"nonce '%s' ಕಡತವನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ದೋಷ: 16 ಬೈಟà³â€Œà²—ಳನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, %d ಅನà³à²¨à³ " +"ಪಡೆಯಲಾಗಿದೆ" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "nonce ಕಡತ '%s' ದಲà³à²²à²¿à²¨ ವಿಷಯಗಳನà³à²¨à³ ಸà³à²Ÿà³à²°à³€à²®à³â€Œà²—ೆ ಬರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "ಆಯà³à²•ೆ ಮಾಡಲಾದ ವಿಳಾಸವೠಖಾಲಿ ಇದೆ" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "setuid ಇದà³à²¦à²¾à²— ಒಂದೠಸಂದೇಶ ಬಸೠಅನà³à²¨à³ ಸà³à²ªà²¾à²¨à³ ಮಾಡಲಾಗಿಲà³à²²" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "ಗಣಕ-id ಇಲà³à²²à²¦à³† ಸಂದೇಶ ಬಸೠಅನà³à²¨à³ ಸà³à²ªà²¾à²¨à³ ಮಾಡಲಾಗಿಲà³à²²: " + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "ಆದೇಶ ಸಾಲೠ'%s' ಅನà³à²¨à³ ಸà³à²ªà²¾à²¨à³ ಮಾಡಲಾಗಿಲà³à²²: " + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(ಈ ಕಿಟಕಿಯನà³à²¨à³ ಮà³à²šà³à²šà²²à³ ಯಾವà³à²¦à³† ಅಕà³à²·à²°à²µà²¨à³à²¨à³ ನಮೂದಿಸಿ)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "ಅಧಿವೇಶನ dbus ಚಾಲನೆಯಲà³à²²à²¿à²²à³à²², ಮತà³à²¤à³ ಸà³à²µà²¯à²‚ಆರಂಭವೠವಿಫಲಗೊಂಡಿದೆ" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"ಅಧಿವೇಶನ ಬಸೠವಿಳಾಸವನà³à²¨à³ ನಿರà³à²§à²°à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²² (ಈ OS ಗಾಗಿ ಅನà³à²µà²¯à²¿à²¸à²²à³ " +"ಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²)" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"DBUS_STARTER_BUS_TYPE ಪರಿಸರ ಚರಮೌಲà³à²¯à²¦à²¿à²‚ದ ಬಸೠವಿಳಾಸವನà³à²¨à³ ನಿರà³à²§à²°à²¿à²¸à²²à³ " +"ಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²- " +"ಗೊತà³à²¤à²¿à²°à²¦ ಮೌಲà³à²¯ '%s'" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"ಬಸೠವಿಳಾಸವನà³à²¨à³ ನಿರà³à²§à²°à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²² à²à²•ೆಂದರೆ DBUS_STARTER_BUS_TYPE ಪರಿಸರ " +"ಚರಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಹೊಂದಿಸಲಾಗಿಲà³à²²" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "ಗೊತà³à²¤à²¿à²°à²¦ ಬಸೠಬಗೆ %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "ವಿಷಯದಲà³à²²à²¿à²¨ ಅನಿರೀಕà³à²·à²¿à²¤ ಕೊರತೆಯೠಒಂದೠಸಾಲನà³à²¨à³ ಓದಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²¦à³†" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"ವಿಷಯದಲà³à²²à²¿à²¨ ಅನಿರೀಕà³à²·à²¿à²¤ ಕೊರತೆಯೠಒಂದೠಸಾಲನà³à²¨à³ ಓದಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²¦à³† " +"(ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿ)" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"ಎಲà³à²²à²¾ ಲಭà³à²¯à²µà²¿à²°à³à²µ ದೃಢೀಕರಣ ರಚನಾವà³à²¯à²µà²¸à³à²¥à³†à²¯à³ ಮà³à²—ಿದಿವೆ (ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²¦à³à²¦à³: %s) " +"(ಲಭà³à²¯à²µà²¿à²°à³à²µà³à²¦à³: " +"%s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer ಮೂಲಕ ರದà³à²¦à³à²—ೊಳಿಸಲಾಗಿದೆ" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "'%s' ಎಂಬ ಕಡತ ಕೋಶಕà³à²•ಾಗಿ ಮಾಹಿತಿಯನà³à²¨à³ ಪಡೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"'%s' ಎಂಬ ಕೋಶದ ಅನà³à²®à²¤à²¿à²—ಳೠತಪà³à²ªà²¾à²—ಿವೆ. 0700 ಅನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, 0%o " +"ಕಂಡà³à²¬à²‚ದಿದೆ" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "'%s' ಎಂಬ ಕಡತಕೋಶವನà³à²¨à³ ರಚಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "'%s' ಕೀರಿಂಗೠಅನà³à²¨à³ ಓದà³à²µà³à²¦à²•à³à²•ಾಗಿ ತೆರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ:" + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"ಕೀರಿಂಗà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ %d ಸಾಲೠತಪà³à²ªà²¾à²—ಿದೆ, ('%s' ಎಂಬಲà³à²²à²¿, '%s' ವಿಷಯವನà³à²¨à³ ಹೊಂದಿರà³à²µ)" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"ಕೀರಿಂಗà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ %d ಸಾಲಿನ ಮೊದಲ ಟೋಕನೠತಪà³à²ªà²¾à²—ಿದೆ ('%s' ಎಂಬಲà³à²²à²¿à²°à³à²µ, '%s' " +"ವಿಷಯವನà³à²¨à³ " +"ಹೊಂದಿರà³à²µ)" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"ಕೀರಿಂಗà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ %d ಸಾಲಿನ ಎರಡನೆಯ ಟೋಕನೠತಪà³à²ªà²¾à²—ಿದೆ ('%s' ಎಂಬಲà³à²²à²¿à²°à³à²µ, '%s' " +"ವಿಷಯವನà³à²¨à³ " +"ಹೊಂದಿರà³à²µ)" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "ಕೀರಿಂಗà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ %d id ಯನà³à²¨à³ ಹೊಂದಿರà³à²µ ಕà³à²•ಿ ಕಂಡà³à²¬à²‚ದಿಲà³à²² ('%s' ನಲà³à²²à²¿à²°à³à²µ)" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "'%s' ಎಂಬ ಹಳೆಯ ಲಾಕೠಕಡತವನà³à²¨à³ ಅಳಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "'%s' ಎಂಬ ಲಾಕೠಕಡತವನà³à²¨à³ ರಚಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "'%s' ಎಂಬ ಲಾಕೠಕಡತವನà³à²¨à³ ಮà³à²šà³à²šà³à²µà²²à³à²²à²¿ (ಸಂಪರà³à²• ತಪà³à²ªà²¿à²¸à²²à³) ದೋಷ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "'%s' ಎಂಬ ಲಾಕೠಕಡತವನà³à²¨à³ ಸಂಪರà³à²• ತಪà³à²ªà²¿à²¸à³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "'%s' ಕೀರಿಂಗà³â€Œ ಅನà³à²¨à³ ಬರೆಯಲೠತೆರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(ಜೊತೆಗೆ, '%s' ಗಾಗಿ ಲಾಕೠಅನà³à²¨à³ ಮà³à²•à³à²¤à²—ೊಳಿಸà³à²µà³à²¦à³‚ ಸಹ ವಿಫಲಗೊಂಡಿದೆ: %s)" + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "ಸಂಪರà³à²•ವನà³à²¨à³ ಮà³à²šà³à²šà²²à²¾à²—ಿದೆ" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "ಕಾಲಾವಕಾಶ ಮà³à²—ಿಯೠಹಂತ ತಲà³à²ªà²¿à²¦à³†" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"ಕà³à²²à³ˆà²‚ಟà³-ಸೈಡೠಸಂಪರà³à²•ವನà³à²¨à³ ರಚಿಸà³à²µà²¾à²— ಒಂದೠಬೆಂಬಲವಿರದ ಫà³à²²à³à²¯à²¾à²—à³â€Œà²—ಳೠಕಂಡಬಂದಿವೆ" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"%s ಮಾರà³à²—ದಲà³à²²à²¿à²¨ ಆಬà³à²œà³†à²•à³à²¸à²¿à²¨à²²à³à²²à²¿ ಅಂತಹ ಯಾವà³à²¦à³† ಸಂಪರà³à²•ಸಾಧನ 'org.freedesktop.DBus." +"Properties' ಲಭà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "'%s' ಅಂತಹ ಯಾವà³à²¦à³† ಗà³à²£à²µà²¿à²²à³à²²" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "'%s' ಎಂಬ ಗà³à²£à²µà²¨à³à²¨à³ ಓದಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "'%s' ಎಂಬ ಗà³à²£à²µà²¨à³à²¨à³ ಬರೆಯಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"'%s' ಗà³à²£à²µà²¨à³à²¨à³ ಹೊಂದಿಸà³à²µà²¾à²— ದೋಷ ಎದà³à²°à²¾à²—ಿದೆ: ನಿರೀಕà³à²·à²¿à²¤ ಬಗೆ '%s' ಆಗಿದೆ ಆದರೆ '%s' " +"ಅನà³à²¨à³ ಪಡೆಯಲಾಗಿದೆ" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "'%s' ಅಂತಹ ಯಾವà³à²¦à³† ಸಂಪರà³à²•ಸಾಧನವಿಲà³à²²" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "ಅಂತಹ ಯಾವà³à²¦à³† ಸಂಪರà³à²•ಸಾಧನವಿಲà³à²²" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "'%s' ಅಂತಹ ಯಾವà³à²¦à³† ಸಂಪರà³à²•ಸಾಧನವಿಲà³à²² (%s ಮಾರà³à²—ದಲà³à²²à²¿à²¨ ವಸà³à²¤à³à²µà²¿à²¨à²²à³à²²à²¿)" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "'%s' ಅಂತಹ ಯಾವà³à²¦à³† ವಿಧಾನವಿಲà³à²²" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "ಸಂದೇಶದ ಬಗೆ, '%s', '%s' ಎಂಬ ನಿರೀಕà³à²·à²¿à²¤ ಬಗೆಗೆ ಹೊಂದಿಕೆಯಾಗà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "%s ಸಂಪರà³à²•ಸಾಧನಕà³à²•ಾಗಿ ಒಂದೠವಸà³à²¤à³à²µà³ %s ಎಂಬಲà³à²²à²¿ ಈಗಾಗಲೆ ಕಂಡà³à²¬à²‚ದಿದೆ" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "'%s' ವಿಧಾನವೠ'%s' ಬಗೆಯನà³à²¨à³ ಮರಳಿಸಿದೆ, ಆದರೆ '%s' ಅನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" +"'%s' ವಿಧಾನವೠಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²²à³à²² ('%s' ಸಂಪರà³à²•ಸಾಧನದಲà³à²²à²¿à²°à³à²µ ಮತà³à²¤à³ '%s' ಸಹಿಯನà³à²¨à³ " +"ಹೊಂದಿರà³à²µ)" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "ಒಂದೠಉಪವೃಕà³à²·à²µà²¨à³à²¨à³ ಈಗಾಗಲೆ %s ಗಾಗಿ ರಫà³à²¤à³ ಮಾಡಲಾಗಿದೆ" + +#: ../gio/gdbusmessage.c:1244 +msgid "type is INVALID" +msgstr "ಬಗೆಯೠINVALID ಆಗಿದೆ" + +#: ../gio/gdbusmessage.c:1255 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL ಸಂದೇಶ: PATH ಅಥವ MEMBER ತಲೆಬರಹದ ಸà³à²¥à²³à²µà³ ಕಾಣಿಸà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../gio/gdbusmessage.c:1266 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN ಸಂದೇಶ: REPLY_SERIAL ತಲೆಬರಹದ ಸà³à²¥à²³à²µà³ ಕಾಣಿಸà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../gio/gdbusmessage.c:1278 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR ಸಂದೇಶ: REPLY_SERIAL ಅಥವ ERROR_NAME ತಲೆಬರಹದ ಸà³à²¥à²³à²µà³ ಕಾಣಿಸà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../gio/gdbusmessage.c:1291 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL ಸಂದೇಶ: PATH, INTERFACE ಅಥವ MEMBER ತಲೆಬರಹದ ಸà³à²¥à²³à²µà³ ಕಾಣಿಸà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../gio/gdbusmessage.c:1299 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL ಸಂದೇಶ: The PATH ತಲೆಬರಹವೠಕಾದಿರಿಸಲಾದ /org/freedesktop/DBus/Local " +"ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಬಳಸà³à²¤à³à²¤à²¿à²¦à³†" + +#: ../gio/gdbusmessage.c:1307 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL ಸಂದೇಶ: INTERFACE ತಲೆಬರಹದ ಸà³à²¥à²³à²µà³ org.freedesktop.DBus.Local ಮೌಲà³à²¯à²µà²¨à³à²¨à³ " +"ಬಳಸà³à²¤à³à²¤à²¿à²¦à³†" + +#: ../gio/gdbusmessage.c:1355 ../gio/gdbusmessage.c:1415 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu ಬೈಟà³â€Œ ಅನà³à²¨à³ ಓದಬೇಕಿತà³à²¤à³ ಆದರೆ ಕೇವಲ %lu ದೊರೆತಿದೆ" +msgstr[1] "%lu ಬೈಟà³â€Œà²—ಳನà³à²¨à³ ಓದಬೇಕಿತà³à²¤à³ ಆದರೆ ಕೇವಲ %lu ದೊರೆತಿದೆ" + +#: ../gio/gdbusmessage.c:1369 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" +"'%s' ವಾಕà³à²¯à²¾à²‚ಶದ ನಂತರ ಮತà³à²¤à³ ಮೊದಲೠNUL ಅನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²²à²¾à²—ಿತà³à²¤à³ ಆದರೆ %d ಕಂಡà³à²¬à²‚ದಿದೆ" + +#: ../gio/gdbusmessage.c:1388 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"ಮಾನà³à²¯à²µà²¾à²¦ UTF-8 ವಾಕà³à²¯à²¾à²‚ಶವನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³ ಆದರೆ %d ಬೈಟà³â€Œ ಆಫà³â€Œà²¸à³†à²Ÿà³â€Œà²¨à²²à³à²²à²¿ " +"ಅಮಾನà³à²¯à²µà²¾à²¦ " +"ಬೈಟà³â€Œà²—ಳೠಕಂಡà³à²¬à²‚ದಿವೆ (ವಾಕà³à²¯à²¾à²‚ಶದ ಉದà³à²¦à²µà³ %d ಆಗಿದೆ). ಮಾನà³à²¯à²µà²¾à²¦ UTF-8 ವಾಕà³à²¯à²¾à²¶à²µà³ '%" +"s' " +"ವರೆಗಿದೆ" + +#: ../gio/gdbusmessage.c:1587 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" +"'%s' ಎಂಬ ಪಾರà³à²¸à³ ಮಾಡಲಾದ ಮೌಲà³à²¯à²µà³ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ D-Bus ಆಬà³à²œà³†à²•à³à²Ÿà³â€ ಮಾರà³à²—ವಲà³à²²" + +#: ../gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "'%s' ಎಂಬ ಪಾರà³à²¸à³ ಮಾಡಲಾದ ಮೌಲà³à²¯à²µà³ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ D-Bus ಆಬà³à²œà³†à²•à³à²Ÿà³â€ ಸಹಿಯಲà³à²²" + +#: ../gio/gdbusmessage.c:1656 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"%u ಬೈಟà³â€Œà²¨à²·à³à²Ÿà³ ಉದà³à²¦à²¦ ವà³à²¯à³‚ಹವೠಕಂಡà³à²¬à²‚ದಿದೆ. ಗರಿಷà³à²Ÿ ಉದà³à²¦à²µà³ 2<<26 ಬೈಟà³â€Œà²—ಳಷà³à²Ÿà³ " +"ಆಗಿದೆ (64 " +"MiB)." +msgstr[1] "" +"%u ಬೈಟà³â€Œà²—ಳಷà³à²Ÿà³ ಉದà³à²¦à²¦ ವà³à²¯à³‚ಹವೠಕಂಡà³à²¬à²‚ದಿದೆ. ಗರಿಷà³à²Ÿ ಉದà³à²¦à²µà³ 2<<26 ಬೈಟà³â€Œà²—ಳಷà³à²Ÿà³ " +"ಆಗಿದೆ (64 " +"MiB)." + +#: ../gio/gdbusmessage.c:1676 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"'a%c' ಬಗೆಯ ವà³à²¯à³‚ಹವೠ(ಅರೆ) ಎದà³à²°à²¾à²—ಿದೆ, ಅನೇಕ %u ಬೈಟà³â€Œà²—ಳ ಉದà³à²¦à²µà²¨à³à²¨à³ ಹೊಂದಿದೆ ಎಂದೠ" +"ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, ಆದರೆ %u ಬೈಟà³â€Œà²—ಳಷà³à²Ÿà³ ಉದà³à²¦ ಕಂಡà³à²¬à²‚ದಿದೆ" + +#: ../gio/gdbusmessage.c:1843 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" +"ವೇರಿಯಂಟà³â€Œà²—ಾಗಿನ '%s' ಎಂಬ ಪಾರà³à²¸à³ ಮಾಡಲಾದ ಮೌಲà³à²¯à²µà³ ಒಂದೠಮಾನà³à²¯ D-Bus ಆಬà³à²œà³†à²•à³à²Ÿà³â€ " +"ಸಹಿಯಾಗಿಲà³à²²" + +#: ../gio/gdbusmessage.c:1867 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"D-Bus ವೈರೠವಿನà³à²¯à²¾à²¸à²¦à²¿à²‚ದ GVariant ಅನà³à²¨à³ '%s' ಬಗೆಯ ವಾಕà³à²¯à²¾à²‚ಶದೊಂದಿಗೆ ಡಿಸೀರಿಯಲೈಸೠ" +"ಮಾಡà³à²µà²²à³à²²à²¿ ದೋಷ" + +#: ../gio/gdbusmessage.c:2051 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"ಅಮಾನà³à²¯à²µà²¾à²¦ ಎಂಡಿಯನà³â€Œà²¨à³†à²¸à³ ಮೌಲà³à²¯. 0x6c ('l') or 0x42 ('B') ಅನà³à²¨à³ " +"ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³ ಆದರೆ 0x" +"%02x ಕಂಡà³à²¬à²‚ದಿದೆ" + +#: ../gio/gdbusmessage.c:2064 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"ಅಮಾನà³à²¯à²µà²¾à²¦ ಪà³à²°à²®à³à²– ಪà³à²°à³Šà²Ÿà³Šà²•ಾಲೠಆವೃತà³à²¤à²¿. 1 ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³ ಆದರೆ %d ಕಂಡà³à²¬à²‚ದಿದೆ" + +#: ../gio/gdbusmessage.c:2120 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "'%s' ಸಹಿಯೊಂದಿಗಿನ ಸಹಿ ಹೆಡರೠಕಂಡà³à²¬à²‚ದಿದೆ ಆದರೆ ಸಂದೇಶದ ಮà³à²–à³à²¯à²­à²¾à²—ವೠಖಾಲಿ ಇದೆ" + +#: ../gio/gdbusmessage.c:2134 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "'%s' ಎಂಬ ಪಾರà³à²¸à³ ಮಾಡಲಾದ ಮೌಲà³à²¯ ಒಂದೠD-Bus ಸಹಿಯಾಗಿಲà³à²² (ಮà³à²–à³à²¯à²­à²¾à²—ಕà³à²•ಾಗಿ)" + +#: ../gio/gdbusmessage.c:2164 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"ಸಂದೇಶದಲà³à²²à²¿ ಯಾವà³à²¦à³† ಸಹಿ ತಲೆಬರಹವೠಕಂಡà³à²¬à²‚ದಿಲà³à²² ಆದರೆ ಸಂದೇಶದ ಮà³à²–à³à²¯à²­à²¾à²—ವೠ%u ಬೈಟೠ" +"ಆಗಿದೆ" +msgstr[1] "" +"ಸಂದೇಶದಲà³à²²à²¿ ಯಾವà³à²¦à³† ಸಹಿ ತಲೆಬರಹವೠಕಂಡà³à²¬à²‚ದಿಲà³à²² ಆದರೆ ಸಂದೇಶದ ಮà³à²–à³à²¯à²­à²¾à²—ವೠ%u ಬೈಟà³â€Œà²—ಳೠ" +"ಆಗಿವೆ" + +#: ../gio/gdbusmessage.c:2174 +msgid "Cannot deserialize message: " +msgstr "ಸಂದೇಶವನà³à²¨à³ ಡಿಸಿರಿಯಲೈಸೠಮಾಡಲಾಗಿಲà³à²²:" + +#: ../gio/gdbusmessage.c:2515 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"GVariant ಅನà³à²¨à³ '%s' ಎಂಬ ಬಗೆ ವಾಕà³à²¯à²¾à²‚ಶದೊಂದಿಗೆ D-Bus ವೈರೠಫಾರà³à²®à³à²¯à²¾à²Ÿà³â€Œà²—ೆ " +"ಅನà³à²•à³à²°à²®à²¿à²¤à²—ೊಳಿಸà³à²µà²²à³à²²à²¿ ದೋಷ" + +#: ../gio/gdbusmessage.c:2652 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"ಸಂದೇಶವೠ%d ಕಡತ ವಿವರಣೆಗಾರನನà³à²¨à³ ಹೊಂದಿದೆ ಆದರೆ ತಲೆಬರಹ (ಹೆಡರà³) ಸà³à²¥à²³à²µà³ %d ಕಡತ " +"ವಿವರಣೆಗಾರ ಎಂದೠಸೂಚಿಸà³à²¤à³à²¤à²¿à²¦à³†" + +#: ../gio/gdbusmessage.c:2660 +msgid "Cannot serialize message: " +msgstr "ಸಂದೇಶವನà³à²¨à³ ಅನà³à²•à³à²°à²®à²¿à²¤à²—ೊಳಿಸಲಾಗಿಲà³à²²:" + +#: ../gio/gdbusmessage.c:2704 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "ಸಂದೇಶದ ಮà³à²–à³à²¯ ಭಾಗವೠ'%s' ಸಹಿಯನà³à²¨à³ ಹೊಂದಿದೆ ಆದರೆ ಯಾವà³à²¦à³† ಸಹಿ ತಲೆಬರಹವಿಲà³à²²" + +#: ../gio/gdbusmessage.c:2714 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "" +"ಸಂದೇಶದ ಮà³à²–à³à²¯à²­à²¾à²—ವೠ'%s' ಬಗೆಯ ಸಹಿಯನà³à²¨à³ ಹೊಂದಿದೆ ಆದರೆ ತಲೆಬರಹ ಸà³à²¥à²³à²¦à²²à³à²²à²¿à²°à³à²µ ಸಹಿಯೠ'%" +"s' " +"ಆಗಿದೆ" + +#: ../gio/gdbusmessage.c:2730 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "ಸಂದೇಶದ ಮà³à²–à³à²¯à²­à²¾à²—ವೠಖಾಲಿ ಇದೆ ಆದರೆ ತಲೆಬರಹದಲà³à²²à²¿à²°à³à²µ ಸಹಿಯೠ'(%s)' ಆಗಿದೆ" + +#: ../gio/gdbusmessage.c:3280 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' ಬಗೆಯ ಪà³à²°à²®à³à²–ಭಾಗದೊಂದಿಗೆ ದೋಷವೠಮರಳಿದೆ" + +#: ../gio/gdbusmessage.c:3288 +msgid "Error return with empty body" +msgstr "ಖಾಲಿ ಇರà³à²µ ಪà³à²°à²®à³à²–ಭಾಗದೊಂದಿಗೆ ದೋಷವೠಮರಳಿದೆ" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "ಈ ಯಂತà³à²°à²¾à²‚ಶ ಪà³à²°à³Šà²«à³ˆà²²à³â€Œ ಅನà³à²¨à³ ಪಡೆಯಲಾಗಿಲà³à²²: %s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" +"/var/lib/dbus/machine-id ಅನà³à²¨à³ ಅಥವ /etc/machine-id ಅನà³à²¨à³ ಲೋಡೠಮಾಡಲೠ" +"ಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "ಇದಕà³à²•ಾಗಿ StartServiceByName ಅನà³à²¨à³ ಕರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ %s: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "ಅನಿರೀಕà³à²·à²¿à²¤ %d ಪà³à²°à²¤à²¿à²•à³à²°à²¿à²¯à³†, StartServiceByName(\"%s\") ವಿಧಾನದಿಂದ" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"ವಿಧಾನವನà³à²¨à³ ರದà³à²¦à³ ಮಾಡಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²; ಪà³à²°à²¾à²•à³à²¸à²¿à²¯à³ ಒಬà³à²¬ ಮಾಲಿಕನಿಲà³à²²à²¦ " +"ಅತà³à²¯à²‚ತ-ಪà³à²°à²šà²²à²¿à²¤à²µà²¾à²¦ " +"ಹೆಸರಿಗಾಗಿ ಇದೆ ಮತà³à²¤à³ ಪà³à²°à²¾à²•à³à²¸à²¿à²¯à²¨à³à²¨à³ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START " +"ಫà³à²²à³à²¯à²¾à²—à³â€Œà²¨à²¿à²‚ದ ಪà³à²°à²¾à²•à³à²¸à²¿à²¯à²¨à³à²¨à³ ನಿರà³à²®à²¿à²¸à²²à²¾à²—ಿದೆ" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "ಅಬà³â€Œà²¸à³à²Ÿà³à²°à²¾à²•à³à²Ÿà³â€ ಹೆಸರಿನ ಸà³à²¥à²³à²•à³à²•ೆ ಬೆಂಬಲವಿಲà³à²²" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "ಒಂದೠಪೂರೈಕೆಗಣಕವನà³à²¨à³ ರಚಿಸà³à²µà²¾à²— nonce ಕಡತವನà³à²¨à³ ಸೂಚಿಸಲಾಗಿಲà³à²²" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' ಎಂಬಲà³à²²à²¿ nonce ಕಡತಕà³à²•ೆ ಬರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' ಎನà³à²¨à³à²µà³à²¦à³ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ D-Bus GUID ಆಗಿಲà³à²²" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "ಬೆಂಬಲವಿರದ ವರà³à²—ಾವಣೆ '%s' ಯಲà³à²²à²¿ ಆಲಿಸಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"ಆದೇಶಗಳà³:\n" +" help ಈ ಮಾಹಿತಿಯನà³à²¨à³ ತೋರಿಸà³à²¤à³à²¤à²¦à³†\n" +" introspect ದೂರಸà³à²¥ ವಸà³à²¤à³à²µà²¨à³à²¨à³ ಅಂತರà³-ವಿಶà³à²²à³‡à²·à²£à³†\n" +" monitor ದೂರಸà³à²¥ ವಸà³à²¤à³à²µà²¨à³à²¨à³ ನೋಡಿಕೊ\n" +" call ದೂರಸà³à²¥ ವಸà³à²¤à³à²µà²¿à²¨à²²à³à²²à²¿ ಒಂದೠವಿಧಾನವನà³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸà³\n" +" emit ಸಂಜà³à²žà³†à²¯à²¨à³à²¨à³ ಹೊಮà³à²®à²¿à²¸à³\n" +"\n" +"ಪà³à²°à²¤à²¿à²¯à³Šà²‚ದೠಆದೇಶಯಲà³à²²à²¿à²¨ ನೆರವನà³à²¨à³ ನೋಡಲೠ\"%s COMMAND --help\" ಅನà³à²¨à³ ಬಳಸಿ.\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "ದೋಷ: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "ಅಂತರà³-ವಿಮರà³à²¶à³† XML ಅನà³à²¨à³ ಪಾರà³à²¸à³ ಮಾಡà³à²µà²²à³à²²à²¿ ದೋಷ: %s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "ವà³à²¯à²µà²¸à³à²¥à³†à²¯ ಬಸà³â€Œà²—ೆ ಸಂಪರà³à²• ಕಲà³à²ªà²¿à²¸à³" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "ಅಧಿವೇಶನದ ಬಸà³â€Œà²—ೆ ಸಂಪರà³à²• ಕಲà³à²ªà²¿à²¸à³" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "ಒದಗಿಸಲಾದ D-ಬಸೠವಿಳಾಸ ಬಸà³â€Œà²—ೆ ಸಂಪರà³à²• ಕಲà³à²ªà²¿à²¸à³" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "ಸಂಪರà³à²•ದ ಅಂತà³à²¯à²¬à²¿à²‚ದà³à²µà²¿à²¨ ಆಯà³à²•ೆಗಳà³:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "ಸಂಪರà³à²•ದ ಅಂತà³à²¯à²¬à²¿à²‚ದà³à²µà²¨à³à²¨à³ ಸೂಚಿಸà³à²µ ಆಯà³à²•ೆಗಳà³" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "ಯಾವà³à²¦à³† ಸಂಪರà³à²• ಅಂತà³à²¯à²¬à²¿à²‚ದà³à²µà²¨à³à²¨à³ ಸೂಚಿಸಲಾಗಿಲà³à²²" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "ಅನೇಕ ಸಂಪರà³à²• ಅಂತà³à²¯à²¬à²¿à²‚ದà³à²—ಳನà³à²¨à³ ಸೂಚಿಸಲಾಗಿದೆ" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" +"ಎಚà³à²šà²°à²¿à²•ೆ: ಅಂತರà³-ಪರಿಶೀಲನೆಯ ಅನà³à²¸à²¾à²°à²µà²¾à²—ಿ, ಸಂಪರà³à²•ಸಾಧನ '%s ಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²²à³à²²\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"ಎಚà³à²šà²°à²¿à²•ೆ: ಒಳಪರಿಶೋಧನೆಯ ಅನà³à²¸à²¾à²°à²µà²¾à²—ಿ, '%s ವಿಧಾನವೠ'%s' ಸಂಪರà³à²•ಸಾಧನದಲà³à²²à²¿ " +"ಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²²à³à²²\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "ಸಂಕೇತಕà³à²•ಾಗಿ à²à²šà³à²›à²¿à²• ಗà³à²°à²¿ (ವಿಶಿಷà³à²Ÿà²µà²¾à²¦ ಹೆಸರà³)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "ಆಬà³à²œà³†à²•à³à²Ÿà³â€ ಮಾರà³à²—ವೠಇಲà³à²²à²¿ ಸಂಕೇತವನà³à²¨à³ ಹೊಮà³à²®à²¿à²¸à³à²¤à³à²¤à²¦à³†" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "ಸಂಕೇತ ಮತà³à²¤à³ ಸಂಪರà³à²•ಸಾಧನದ ಹೆಸರà³" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "ಒಂದೠಸಂಜà³à²žà³†à²¯à²¨à³à²¨à³ ಹೊಮà³à²®à²¿à²¸à³." + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "ಸಂಪರà³à²• ಸಾಧಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "ದೋಷ: ವಸà³à²¤à³à²µà²¿à²¨ ಮಾರà³à²—ವನà³à²¨à³ ಸೂಚಿಸಲಾಗಿಲà³à²².\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "ದೋಷ: %s ಎನà³à²¨à³à²µà³à²¦à³ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ ಮಾರà³à²—ವಾಗಿಲà³à²²\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "ದೋಷ: ಸಂಕೇತವನà³à²¨à³ ಸೂಚಿಸಲಾಗಿಲà³à²².\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "ದೋಷ: ಸಂಕೇತವೠಸಂಪೂರà³à²£-ಅರà³à²¹à²—ೊಂಡ ಹೆಸರಾಗಿರಬೇಖà³.\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "ದೋಷ: %s ಎನà³à²¨à³à²µà³à²¦à³ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ ಸಂಪರà³à²•ಸಾಧನದ ಹೆಸರಾಗಿಲà³à²²\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "ದೋಷ: %s ಎನà³à²¨à³à²µà³à²¦à³ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ ಹೆಸರಾಗಿಲà³à²²\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "ದೋಷ: %s ಎನà³à²¨à³à²µà³à²¦à³ ಒಂದೠವಿಶಿಷà³à²Ÿà²µà²¾à²¦ ಹೆಸರಾಗಿಲà³à²²\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%d ನಿಯತಾಂಕವನà³à²¨à³ ಪಾರà³à²¸à³ ಮಾಡà³à²µà²²à³à²²à²¿ ದೋಷ: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "ಸಂಪರà³à²•ವನà³à²¨à³ ಹೊರತಳà³à²³à³à²µà²²à³à²²à²¿ ದೋಷ: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "ವಿಧಾನವನà³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸಬೇಕಿರà³à²µ ಗà³à²°à²¿à²¯ ಹೆಸರà³" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "ವಿಧಾನವನà³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸಬೇಕಿರà³à²µ ಆಬà³à²œà³†à²•à³à²Ÿà³â€ ಹೆಸರà³" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "ವಿಧಾನ ಮತà³à²¤à³ ಸಂಪರà³à²•ಸಾಧನದ ಹೆಸರà³" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "ಕಾಲತೀರಿಕೆ ಸೆಕೆಂಡà³à²—ಳà³" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "ದೂರಸà³à²¥ ಆಬà³à²œà³†à²•à³à²¸à²¿à²¨à²²à³à²²à²¿ ವಿಧಾನವನà³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸà³" + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "ದೋಷ: ಗà³à²°à²¿à²¯à²¨à³à²¨à³ ಸೂಚಿಸಲಾಗಿಲà³à²²\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "ದೋಷ: ಆಬà³à²œà³†à²•à³à²Ÿà³â€ ಮಾರà³à²—ವನà³à²¨à³ ಸೂಚಿಸಲಾಗಿಲà³à²²\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "ದೋಷ: ವಿಧಾನದ ಹೆಸರನà³à²¨à³ ಸೂಚಿಸಲಾಗಿಲà³à²²\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "ದೋಷ: '%s' ವಿಧಾನದ ಹೆಸರೠಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "%d ನಿಯತಾಂಕವನà³à²¨à³ ('%s' ಎಂಬ ಬಗೆ) ಪಾರà³à²¸à³ ಮಾಡà³à²µà²²à³à²²à²¿ ದೋಷ: %s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "ಒಳ-ಪರಿಶೋಧನೆಗೆ ಗà³à²°à²¿à²¯ ಹೆಸರà³" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "ಒಳ-ಪರಿಶೋಧನೆಗಾಗಿನ ಆಬà³à²œà³†à²•à³à²Ÿà³â€ ಮಾರà³à²—" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "ಮà³à²¦à³à²°à²£ XML" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "ಉಪಅಂಶದ ಅಂತರà³-ಪರಿಶೀಲನೆ" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "ಕೇವಲ ಗà³à²£à²—ಳನà³à²¨à³ ಮಾತà³à²° ಮà³à²¦à³à²°à²¿à²¸à³" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "ಒಂದೠದೂರಸà³à²¥ ಆಬà³à²œà³†à²•à³à²Ÿà²¨à³à²¨à³ ಅಂತರ-ಪರಿಶೀಲಿಸà³" + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "ನೋಡಿಕೊಳà³à²³à²¬à³‡à²•ಿರà³à²µ ಗà³à²°à²¿à²¯ ಹೆಸರà³" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "ನೋಡಿಕೊಳà³à²³à²¬à³‡à²•ಿರà³à²µ ಆಬà³à²œà³†à²•à³à²Ÿà²¿à²¨ ಹೆಸರà³" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "ನೋಡಿಕೊಳà³à²³à²¬à³‡à²•ಿರà³à²µ ದೂರಸà³à²¥ ಆಬà³à²œà³†à²•à³à²Ÿà³â€" + +#: ../gio/gdesktopappinfo.c:1999 ../gio/gdesktopappinfo.c:4523 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "ಹೆಸರಿಸಲಾಗದ" + +#: ../gio/gdesktopappinfo.c:2408 +msgid "Desktop file didn't specify Exec field" +msgstr "ಗಣಕತೆರೆ ಕಡತವೠExec ಕà³à²·à³‡à²¤à³à²°à²µà²¨à³à²¨à³ ಸೂಚಿಸಿಲà³à²²" + +#: ../gio/gdesktopappinfo.c:2693 +msgid "Unable to find terminal required for application" +msgstr "ಅನà³à²µà²¯à²•à³à²•ೆ ಅಗತà³à²¯à²µà²¿à²°à³à²µ ಟರà³à²®à²¿à²¨à²²à³â€ ಅನà³à²¨à³ ಪತà³à²¤à³†à²®à²¾à²¡à²²à²¾à²—ಲಿಲà³à²²" + +#: ../gio/gdesktopappinfo.c:3114 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "ಬಳಕೆದಾರ ಅನà³à²µà²¯ ಸಂರಚನಾ ಫೋಲà³à²¡à²°à³ %s ಅನà³à²¨à³ ರಚಿಸಲಾಗಿಲà³à²²: %s" + +#: ../gio/gdesktopappinfo.c:3118 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "ಬಳಕೆದಾರ MIME ಸಂರಚನಾ ಫೋಲà³à²¡à²°à³ %s ಅನà³à²¨à³ ರಚಿಸಲಾಗಿಲà³à²²: %s" + +#: ../gio/gdesktopappinfo.c:3358 ../gio/gdesktopappinfo.c:3382 +msgid "Application information lacks an identifier" +msgstr "ಅನà³à²µà²¯à²¦ ಮಾಹಿತಿಯಲà³à²²à²¿ à²à²¡à³†à²‚ಟಿಫಯರೠಇಲà³à²²" + +#: ../gio/gdesktopappinfo.c:3615 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "ಬಳಕೆದಾರನ ಡೆಸà³à²•à³â€à²Ÿà²¾à²ªà³ ಕಡತ %s ಅನà³à²¨à³ ತೆರೆಯಲಾಗಿಲà³à²²" + +#: ../gio/gdesktopappinfo.c:3749 +#, c-format +msgid "Custom definition for %s" +msgstr "%s ಗಾಗಿನ ಕಸà³à²Ÿà²®à³ ವಿವರಣೆ" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "ಹೊರತಳà³à²³à³à²µà³à²¦à²¨à³à²¨à³ ಡà³à²°à³ˆà²µà³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" +"ಡà³à²°à³ˆà²µà³ ಹೊರತಳà³à²³à³à²µà³à²¦à²¨à³à²¨à³ ಅಥವ eject_with_operation ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "ಮಾಧà³à²¯à²®à²•à³à²•ಾಗಿ ಪೋಲೠಮಾಡà³à²µà³à²¦à²¨à³à²¨à³ ಡà³à²°à³ˆà²µà³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "ಆರಂಭಿಸà³à²¦à²¨à³à²¨à³ ಡà³à²°à³ˆà²µà³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "ನಿಲà³à²²à²¿à²¸à³à²µà³à²¦à²¨à³à²¨à³ ಡà³à²°à³ˆà²µà³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS ಬೆಂಬಲವೠಲಭà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem ಎನà³à²•ೋಡಿಂಗà³â€Œà²¨ ಆವೃತà³à²¤à²¿ %d ಅನà³à²¨à³ ನಿಭಾಯಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem ಎನà³à²•ೋಡಿಂಗಿನಲà³à²²à²¿ ತಪà³à²ªà²¾à²¦ ಸಂಖà³à²¯à³†à²¯ ಟೋಕನà³â€Œà²—ಳೠ(%d)" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon ಎನà³à²•ೋಡಿಂಗà³â€Œà²¨ ಆವೃತà³à²¤à²¿ %d ಅನà³à²¨à³ ನಿಭಾಯಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon ಎನà³à²•ೋಡಿಂಗಿನಲà³à²²à²¿ ತಪà³à²ªà²¾à²¦ ಸಂಖà³à²¯à³†à²¯ ಟೋಕನà³â€Œà²—ಳೠ(%d)" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon ಗಾಗಿ GEmblem ಅನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³" + +#: ../gio/gfile.c:962 ../gio/gfile.c:1200 ../gio/gfile.c:1338 +#: ../gio/gfile.c:1576 ../gio/gfile.c:1631 ../gio/gfile.c:1689 +#: ../gio/gfile.c:1773 ../gio/gfile.c:1830 ../gio/gfile.c:1894 +#: ../gio/gfile.c:1949 ../gio/gfile.c:3597 ../gio/gfile.c:3652 +#: ../gio/gfile.c:3859 ../gio/gfile.c:3901 ../gio/gfile.c:4364 +#: ../gio/gfile.c:4775 ../gio/gfile.c:4860 ../gio/gfile.c:4950 +#: ../gio/gfile.c:5047 ../gio/gfile.c:5134 ../gio/gfile.c:5235 +#: ../gio/gfile.c:7754 ../gio/gfile.c:7844 ../gio/gfile.c:7928 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "ಕಾರà³à²¯à²µà³ ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1461 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "ಹೊಂದಿರà³à²µ ಮೌಂಟೠಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²²à³à²²" + +#: ../gio/gfile.c:2508 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "ಕೋಶಕà³à²•ೆ ನಕಲಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gfile.c:2568 +msgid "Can't copy directory over directory" +msgstr "ಕೋಶವನà³à²¨à³ ಕೋಶಕà³à²•ೆ ನಕಲಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gfile.c:2576 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "ಸೂಚಿತ ಕಡತವೠಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²²à³à²²" + +#: ../gio/gfile.c:2595 +msgid "Can't recursively copy directory" +msgstr "ಕೋಶವನà³à²¨à³ ಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¿à²¤à²µà²¾à²—ಿ ನಕಲಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gfile.c:2877 +msgid "Splice not supported" +msgstr "ಒಗà³à²—ೂಡಿಸà³à²µà²¿à²•ೆಗೆ ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/gfile.c:2881 +#, c-format +msgid "Error splicing file: %s" +msgstr "ಕಡತವನà³à²¨à³ ಒಗà³à²—ೂಡಿಸà³à²µà²¾à²— ದೋಷ: %s" + +#: ../gio/gfile.c:3012 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"à²à²°à²¿à²¸à³à²µà²¿à²•ೆಯ (ಮೌಂಟà³â€Œ) ನಡà³à²µà³† ಪà³à²°à²¤à²¿à²®à²¾à²¡à³à²µà²¿à²•ೆಗೆ (ರಿಫà³à²²à²¿à²‚ಕà³/ತದà³à²°à³‚ಪà³) ಬೆಂಬಲವಿಲà³à²²" + +#: ../gio/gfile.c:3016 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr " ಪà³à²°à²¤à²¿à²®à²¾à²¡à³à²µà²¿à²•ೆಗೆ (ರಿಫà³à²²à²¿à²‚ಕà³/ತದà³à²°à³‚ಪà³) ಬೆಂಬಲವಿಲà³à²² ಅಥವ ಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ" + +#: ../gio/gfile.c:3021 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr " ಪà³à²°à²¤à²¿à²®à²¾à²¡à³à²µà²¿à²•ೆಗೆ (ರಿಫà³à²²à²¿à²‚ಕà³/ತದà³à²°à³‚ಪà³) ಬೆಂಬಲವಿಲà³à²² ಅಥವ ಕೆಲಸ ಮಾಡà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gfile.c:3084 +msgid "Can't copy special file" +msgstr "ವಿಶೇಷ ಕಡತವನà³à²¨à³ ಕಾಪಿ ಮಾಡಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gfile.c:3849 +msgid "Invalid symlink value given" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಸಿಮà³â€à²²à²¿à²‚ಕೠಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಒದಗಿಸಲಾಗಿದೆ" + +#: ../gio/gfile.c:4010 +msgid "Trash not supported" +msgstr "ಟà³à²°à³à²¯à²¾à²¶à³ ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/gfile.c:4122 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ಕಡತದ ಹೆಸರà³à²—ಳೠ'%c' ಅನà³à²¨à³ ಹೊಂದà³à²µà²‚ತಿಲà³à²²" + +#: ../gio/gfile.c:6546 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "ಪರಿಮಾಣವೠಆರೋಹಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gfile.c:6655 +msgid "No application is registered as handling this file" +msgstr "ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ನಿಭಾಯಿಸಲೠಯಾವà³à²¦à³† ಅನà³à²µà²¯à²µà³ ಅನà³à²¸à³à²¥à²¾à²ªà²¿à²¤à²—ೊಂಡಿಲà³à²²" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "ಎನà³à²¯à³à²®à²°à³‡à²Ÿà²°à³ ಮà³à²šà³à²šà²²à³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ಕಡತ ಎನà³à²¯à³à²®à²°à³‡à²Ÿà²°à²¿à²¨à²²à³à²²à²¿ ಕಾರà³à²¯à²µà³ ಬಾಕಿ ಇದೆ" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ಕಡತ ಎನà³à²¯à³à²®à²°à³‡à²Ÿà²°à³ ಈಗಾಗಲೆ ಮà³à²šà³à²šà²²à³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon ಎನà³à²•ೋಡಿಂಗà³â€Œà²¨ ಆವೃತà³à²¤à²¿ %d ಅನà³à²¨à³ ನಿಭಾಯಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon ಗಾಗಿನ ತಪà³à²ªà²¾à²¦ ಇನà³â€Œà²ªà³à²Ÿà³ ದತà³à²¤à²¾à²‚ಶ" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "ಸà³à²Ÿà³à²°à³€à²®à³ query_info ಅನà³à²¨à³ ಬೆಂಬಲಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ಸà³à²Ÿà³à²°à³€à²®à³â€à²¨à²²à³à²²à²¿ ಕೋರà³à²µà³à²¦à³ (seek) ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ಆದಾನ ಸà³à²Ÿà³à²°à³€à²®à³â€à²¨à²²à³à²²à²¿ ಕಡಿತಗೊಳಿಸಲೠಅನà³à²®à²¤à²¿à²¯ ಇಲà³à²²" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "ಸà³à²Ÿà³à²°à³€à²®à³â€à²¨à²²à³à²²à²¿ ಕಡಿತಗೊಳಿಸಲೠಅನà³à²®à²¤à²¿à²¯ ಇಲà³à²²" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "ಟೋಕನà³â€Œà²—ಳ ತಪà³à²ªà²¾à²¦ ಸಂಖà³à²¯à³† (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "ವರà³à²—ದ ಹೆಸರೠ%s ಗೆ ಪà³à²°à²•ಾರವಿಲà³à²²" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "ಪà³à²°à²•ಾರ %s ವೠGIcon ಸಂಪರà³à²•ಸಾಧನವನà³à²¨à³ ಅನà³à²µà²¯à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "ಪà³à²°à²•ಾರ %s ಅನà³à²¨à³ ವರà³à²—ವಾಗಿಸಿಲà³à²²" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "ತಪà³à²ªà²¾à²¦ ಆವೃತà³à²¤à²¿ ಸಂಖà³à²¯à³†: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" +"ಪà³à²°à²•ಾರ %s ವೠfrom_tokens() ಅನà³à²¨à³ GIcon ಸಂಪರà³à²•ಸಾಧನದ ಮೇಲೆ ಅನà³à²µà²¯à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "ಒದಗಿಸಲಾದ ಚಿಹà³à²¨à³†à²¯ ಎನà³à²•ೋಡಿಂಗೠಅನà³à²¨à³ ನಿಭಾಯಿಸಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "ಯಾವ ವಿಳಾಸವನà³à²¨à³ ಸೂಚಿಸಲಾಗಿಲà³à²²" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "%u ಎನà³à²¨à³à²µ ಉದà³à²¦à²µà³ ವಿಳಾಸಕà³à²•ೆ ಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ಪà³à²°à²¿à²«à²¿à²•à³à²¸à²¿à²¨ ಉದà³à²¦à²•à³à²•ೂ ಮೀರಿದ ಬಿಟà³â€Œà²—ಳನà³à²¨à³ ವಿಳಾಸವೠಹೊಂದಿದೆ" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "'%s' ಅನà³à²¨à³ ಒಂದೠIP ವಿಳಾಸದ ಮಾಸà³à²•à³â€ ಆಗಿ ಪಾರà³à²¸à³ ಮಾಡಲಾಗಿಲà³à²²" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "ಸಾಕೆಟà³â€Œ ವಿಳಾಸಕà³à²•ಾಗಿ ಸಾಕಷà³à²Ÿà³ ಸà³à²¥à²³à²µà²¿à²²à³à²²" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "ಬೆಂಬಲವಿರದ ಸಾಕೆಟೠವಿಳಾಸ" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "ಆದಾನ ಸà³à²Ÿà³à²°à³€à²®à³â€à²¨à²²à³à²²à²¿ ಓದà³à²µà³à²¦à²¨à³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1212 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1664 +msgid "Stream has outstanding operation" +msgstr "ಸà³à²Ÿà³à²°à³€à²®à³â€à²¨à²²à³à²²à²¿ ಕಾರà³à²¯à²µà³ ಬಾಕಿ ಇದೆ" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> ಘಟಕಕà³à²•ೆ ಒಂದೠ<%s> ಒಳಗೆ ಇರಲೠಅನà³à²®à²¤à²¿ ಇಲà³à²²" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> ಘಟಕವೠಮೇಲà³à²­à²¾à²—ದಲà³à²²à²¿ ಇರಲೠಅನà³à²®à²¤à²¿ ಇಲà³à²²" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "%s ಕಡತವೠಸಂಪನà³à²®à³‚ಲದಲà³à²²à²¿ ಅನೇಕ ಬಾರಿ ಕಂಡà³à²¬à²‚ದಿದೆ" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "ಯಾವà³à²¦à³† ಮೂಲ ಕೋಶದಲà³à²²à²¿ '%s' ಅನà³à²¨à³ ಪತà³à²¤à³† ಮಾಡಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "ಮೂಲ ಕೋಶದಲà³à²²à²¿ '%s' ಅನà³à²¨à³ ಪತà³à²¤à³† ಮಾಡà³à²µà²²à³à²²à²¿ ವಿಫಲಗೊಂಡಿದೆ" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "ಗೊತà³à²¤à²¿à²°à²¦ ಸಂಸà³à²•ರಣಾ ಆಯà³à²•ೆ \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "ತಾತà³à²•ಾಲಿಕ ಕಡತವನà³à²¨à³ ರಚಿಸà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s ಕಡತವನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "%s ಕಡತವನà³à²¨à³ ಸಂಕà³à²šà²¨à²—ೊಳಿಸà³à²µà²²à³à²²à²¿ ದೋಷ" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "ಪಠà³à²¯à²µà³ <%s> ನ ಒಳಗೆ ಕಾಣಿಸದೆ ಇರಬಹà³à²¦à³" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "ಓಟà³â€Œà²ªà³à²Ÿà³ ಕಡತದ ಹೆಸರà³" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"ಕಡತಗಳನà³à²¨à³ ಎಲà³à²²à²¿à²‚ದ ಓದಬೇಕೊ ಆ ಕಡತಕೋಶ (ಪà³à²°à²¸à³à²¤à³à²¤ ಕೋಶಕà³à²•ೆ ಪೂರà³à²µà²¨à²¿à²¯à³‹à²œà²¿à²¤à²—ೊಳà³à²³à²¬à³‡à²•à³)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"ಗà³à²°à²¿ ಕಡತ ವಿಸà³à²¤à²°à²£à³†à²¯à²¿à²‚ದ ಆಯà³à²•ೆ ಮಾಡಲಾದ ವಿನà³à²¯à²¾à²¸à²¦à²²à³à²²à²¿ ಔಟà³â€Œà²ªà³à²Ÿà³ ಅನà³à²¨à³ ಉತà³à²ªà²¾à²¦à²¿à²¸à³" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "ಆಕರದ ತಲೆಬರಹವನà³à²¨à³ ಉತà³à²ªà²¾à²¦à²¿à²¸à³" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" +"ಸಂಪನà³à²®à³‚ಲ ಕಡತದಲà³à²²à²¿ ನಿಮà³à²® ಕೋಡà³â€Œà²—ೆ ಸಂಪರà³à²• ಜೋಡಿಸಲೠಬಳಸಲಾದ ಆಕರಸಂಕೇತವನà³à²¨à³ ಉತà³à²ªà²¾à²¦à²¿à²¸à³" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "ಅವಲಂಬನೆಯ ಪಠà³à²¯à²µà²¨à³à²¨à³ ಉತà³à²ªà²¾à²¦à²¿à²¸à³" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "ಸಂಪನà³à²®à³‚ಲವನà³à²¨à³ ಸà³à²µà²¯à²‚ಚಾಲಿತವಾಗಿ ರಚಿಸಬೇಡ ಮತà³à²¤à³ ನೋಂದಾಯಿಸಬೇಡ" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "ಕà³à²°à²¿à²¯à³†à²—ಳನà³à²¨à³ ರಫà³à²¤à³ ಮಾಡಬೇಡ; ಅವà³à²—ಳನà³à²¨à³ G_GNUC_INTERNAL ಘೋಷಿಸà³" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "ಉತà³à²ªà²¾à²¦à²¿à²¸à²²à²¾à²¦ ಆಕರ ಸಂಕೇತಕà³à²•ಾಗಿ ಬಳಸಲಾದ C à²à²¡à³†à²‚ಟಿಫಯರà³" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"ಒಂದೠಸಂಪನà³à²®à³‚ಲ ವಿವರಣೆಯನà³à²¨à³ ಒಂದೠಸಂಪನà³à²®à³‚ಲ ಕಡತಕà³à²•ೆ ಕಂಪೈಲೠಮಾಡà³.\n" +"ಸಂಪನà³à²®à³‚ಲ ವಿವರಣೆ ಕಡತಗಳೠ.gresource.xml ಎಂಬ ವಿಸà³à²¤à²°à²£à³†à²¯à²¨à³à²¨à³ ಹೊಂದಿರà³à²¤à³à²¤à²µà³†,\n" +"ಮತà³à²¤à³ ಸಂಪನà³à²®à³‚ಲ ಕಡತಗಳೠ.gresource ವಿಸà³à²¤à²°à²£à³†à²¯à²¨à³à²¨à³ ಹೊಂದಿರà³à²¤à³à²¤à²µà³†." + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "ನೀವೠಖಚಿತವಾಗಿ ಒಂದೠಕಡತದ ಹೆಸರನà³à²¨à³ ಒದಗಿಸಬೇಕà³\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "ಹೆಸರೠಖಾಲಿ ಇರà³à²µà²‚ತಿಲà³à²²" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಹೆಸರೠ'%s': ಹೆಸರà³à²—ಳೠಲೋಯರà³-ಕೇಸೠಆಕà³à²·à²°à²¦à²¿à²‚ದ ಪà³à²°à²¾à²°à²‚ಭಗೊಳà³à²³à²¬à³‡à²•à³" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"ಅಮಾನà³à²¯à²µà²¾à²¦ ಹೆಸರೠ'%s': ಅಮಾನà³à²¯à²µà²¾à²¦ ಅಕà³à²·à²° '%c'; ಕೇವಲ ಲೋಯರà³-ಕೇಸೠಅಕà³à²·à²°à²—ಳà³, " +"ಸಂಖà³à²¯à³†à²—ಳೠ" +"ಮತà³à²¤à³ ಹೈಫನà³â€Œà²—ೆ ('-') ಮಾತà³à²° ಅನà³à²®à²¤à²¿ ಇದೆ." + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಹೆಸರೠ'%s': ಅನà³à²•à³à²°à²®à²µà²¾à²—ಿ ಎರಡೠಹೈಫನà³â€Œà²—ಳಿಗೆ ('--') ಅನà³à²®à²¤à²¿ ಇಲà³à²²." + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಹೆಸರೠ'%s': ಕೊನೆಯ ಅಕà³à²·à²°à²µà³ ಹೈಫನೠ('-') ಆಗಿರದೆ ಇರಬಹà³à²¦à³." + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಹೆಸರೠ'%s': ಗರಿಷà³à²Ÿ ಉದà³à²§à²µà³1024 ಆಗಿರಬೇಕà³" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " ಅನà³à²¨à³ ಈಗಾಗಲೆ ಸೂಚಿಸಲಾಗಿದೆ" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "'list-of' ಸà³à²•ೀಮಾಕà³à²•ೆ ಕೀಲಿಗಳನà³à²¨à³ ಸೇರಿಸಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " ಅನà³à²¨à³ ಈಗಾಗಲೆ ಸೂಚಿಸಲಾಗಿದೆ" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" ನೆರಳà³à²—ಳೠನಲà³à²²à²¿; ಮೌಲà³à²¯à²µà²¨à³à²¨à³ " +"ಬದಲಾಯಿಸಲೠಅನà³à²¨à³ ಬಳಸಿ" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +" ಗೆ ಒಂದೠಗà³à²£à²µà²¿à²¶à³‡à²·à²µà²¾à²—ಿ ನಿರà³à²¦à²¿à²·à³à²Ÿà²µà²¾à²—ಿ ಒಂದೠ'ಬಗೆ', 'enum' ಅಥವ " +"'ಫà³à²²à³à²¯à²¾à²—à³â€Œà²—ಳà³' " +"ಅನà³à²¨à³ ಸೂಚಿಸಬೇಕà³" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> ಅನà³à²¨à³ (ಇನà³à²¨à³‚ ಸಹ) ಸೂಚಿಸಲಾಗಿಲà³à²²." + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ GVariant ಬಗೆಯ ವಾಕà³à²¯à²¾à²‚ಶ '%s'" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " ಅನà³à²¨à³ ಒದಗಿಸಲಾಗಿದೆ ಆದರೆ ಸà³à²•ೀಮ à²à²¨à²¨à³à²¨à³‚ ವಿಸà³à²¤à²°à²¿à²¸à³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "ಅತಿಕà³à²°à²®à²¿à²¸à²²à³ ಯಾವà³à²¦à³† ಇಲà³à²²" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " ಅನà³à²¨à³ ಈಗಾಗಲೆ ಸೂಚಿಸಲಾಗಿದೆ" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " ಅನà³à²¨à³ ಈಗಾಗಲೆ ಸೂಚಿಸಲಾಗಿದೆ" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" +" ವೠಇನà³à²¨à³‚ ಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²°à²¦ '%s' ಸà³à²•ೀಮಾವನà³à²¨à³ ವಿಸà³à²¤à²°à²¿à²¸à³à²¤à³à²¤à²¦à³†" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " ವೠಇನà³à²¨à³‚ ಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²°à²¦ '%s' ಸà³à²•ೀಮಾದ ಪಟà³à²Ÿà²¿à²¯à²¾à²—ಿದೆ" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "ಒಂದೠಮಾರà³à²—ದೊಂದಿಗಿನ ಸà³à²•ೀಮಾದ ಪಟà³à²Ÿà²¿à²¯à²¾à²—ಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "ಒಂದೠಮಾರà³à²—ದೊಂದಿಗಿನ ಸà³à²•ೀಮಾವನà³à²¨à³ ವಿಸà³à²¤à²°à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ಒಂದೠಪಟà³à²Ÿà²¿à²¯à²¾à²—ಿದೆ, ಪಟà³à²Ÿà²¿à²¯à²¾à²—ಿರದ ಅನà³à²¨à³ " +"ವಿಸà³à²¤à²°à²¿à²¸à²²à²¾à²—à³à²¤à³à²¤à²¿à²¦à³†" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" ವೠಅನà³à²¨à³ " +"ವಿಸà³à²¤à²°à²¿à²¸à³à²¤à³à²¤à²¦à³† ಆದರೆ '%s' ಯೠ'%s' ಅನà³à²¨à³ ವಿಸà³à²¤à²°à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" +"ಒಂದೠಮಾರà³à²—ವನà³à²¨à³ ಒದಗಿಸಿದಲà³à²²à²¿, ಅದೠಒಂದೠಸà³à²²à³à²¯à²¾à²¶à³â€Œà²¨à²¿à²‚ದ ಆರಂಭ ಮತà³à²¤à³ ಅಂತà³à²¯à²—ೊಳà³à²³à²¬à³‡à²•à³" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "ಪಟà³à²Ÿà²¿à²¯ ಮಾರà³à²—ವೠ':/' ನೊಂದಿಗೆ ಕೊನೆಗೊಳà³à²³à²¬à³‡à²•à³" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ಅನà³à²¨à³ ಈಗಾಗಲೆ ಸೂಚಿಸಲಾಗಿದೆ" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "<%s> ಘಟಕವೠಮೇಲà³à²­à²¾à²—ದಲà³à²²à²¿ ಇರಲೠಅನà³à²®à²¤à²¿ ಇಲà³à²²" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict ಅನà³à²¨à³ ಸೂಚಿಸಲಾಗಿದೆ; ನಿರà³à²—ಮಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†.\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "ಈ ಸಂಪೂರà³à²£ ಕಡತವನà³à²¨à³ ಕಡೆಗಣಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†.\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "ಈ ಕಡತವನà³à²¨à³ ಕಡೆಗಣಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†.\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"ಅಂತಹ ಯಾವà³à²¦à³† '%s' ಕೀಲಿಯೠ'%s' ಸà³à²•ೀಮಾದಲà³à²²à²¿ ಇಲà³à²², ('%s' ಎಂಬ ಅತಿಕà³à²°à²®à²¿à²¸à³à²µà²¿à²•ೆ " +"ಕಡತದಲà³à²²à²¿ " +"ಸೂಚಿಸಲಾಗಿರà³à²µà²‚ತಹ)" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; ಈ ಕೀಲಿಗಾಗಿನ ಅತಿಕà³à²°à²®à²¿à²¸à³à²µà²¿à²•ೆಯನà³à²¨à³ ಕಡೆಗಣಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†.\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " ಮತà³à²¤à³ --strict ಅನà³à²¨à³ ಸೂಚಿಸಲಾಗಿದೆ; ನಿರà³à²—ಮಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†.\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"'%s' ಕೀಲಿಯನà³à²¨à³ '%s' ಸà³à²•ೀಮಾದಲà³à²²à²¿ ಪಾರà³à²¸à³ ಮಾಡà³à²µà²¾à²— ದೋಷ ('%s' ಎಂಬ ಅತಿಕà³à²°à²®à²¿à²¸à³à²µà²¿à²•ೆ " +"ಕಡತದಲà³à²²à²¿ ಸೂಚಿಸಲಾಗಿರà³à²µà²‚ತಹ): %s." + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "ಈ ಕೀಲಿಗಾಗಿನ ಅತಿಕà³à²°à²®à²¿à²¸à³à²µà²¿à²•ೆಯನà³à²¨à³ ಕಡೆಗಣಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†.\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"'%s' ಕೀಲಿಗಾಗಿ '%s' ಸà³à²•ೀಮಾದಲà³à²²à²¿ ಅತಿಕà³à²°à²®à²¿à²¸à³à²µà²¿à²•ೆಯೠ('%s' ಅತಿಕà³à²°à²®à²¿à²¸à³à²µ ಕಡತದಲà³à²²à²¿) " +"ಒದಗಿಸಲಾದ ಸà³à²•ೀಮಾದ ವà³à²¯à²¾à²ªà³à²¤à²¿à²¯ ಹೊರಗಿದೆ" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"'%s' ಕೀಲಿಗಾಗಿ '%s' ಸà³à²•ೀಮಾದಲà³à²²à²¿ ಅತಿಕà³à²°à²®à²¿à²¸à³à²µà²¿à²•ೆಯೠ('%s' ಅತಿಕà³à²°à²®à²¿à²¸à³à²µ ಕಡತದಲà³à²²à²¿) " +"ಮಾನà³à²¯à²µà²¾à²¦ ಆಯà³à²•ೆಗಳ ಪಟà³à²Ÿà²¿à²¯à²²à³à²²à²¿à²²à³à²²" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled ಕಡತವನà³à²¨à³ ಎಲà³à²²à²¿ ಶೇಖರಿಸಿ ಇಡಬೇಕà³" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "ಸà³à²•ೀಮಾದಲà³à²²à²¿à²¨ ಯಾವà³à²¦à³† ದೋಷಗಳೠಕಂಡà³à²¬à²‚ದಲà³à²²à²¿ ಸà³à²¥à²—ಿತಗೊಳಿಸà³" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled ಕಡತವನà³à²¨à³ ಬರೆಯಬೇಡ" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "ಕೀಲಿ ಹೆಸರಿನ ನಿರà³à²¬à²‚ಧನೆಗಳನà³à²¨à³ ಒತà³à²¤à²¾à²¯à²¿à²¸à²¬à³‡à²¡" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"ಎಲà³à²²à²¾ GSettings ಸà³à²•ೀಮಾ ಕಡತಗಳನà³à²¨à³ ಒಂದೠಸà³à²•ೀಮಾ ಕà³à²¯à²¾à²¶à³â€Œà²—ೆ ಕಂಪೈಲೠಮಾಡà³.\n" +"ಸà³à²•ೀಮಾ ಕಡತಗಳೠ.gschema.xml ವಿಸà³à²¤à²°à²£à³†à²¯à²¨à³à²¨à³ ಹೊಂದಿರಬೇಕà³,\n" +"ಕà³à²¯à²¾à²¶à³† ಕಡತವನà³à²¨à³ gschemas.compiled ಎಂದೠಕರೆಯಲಾಗà³à²¤à³à²¤à²¦à³†." + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "ನೀವೠನಿರà³à²¦à²¿à²·à³à²Ÿà²µà²¾à²—ಿ ಒಂದೠಕೋಶದ ಹೆಸರನà³à²¨à³ ಒದಗಿಸಬೇಕà³\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "ಯಾವà³à²¦à³† ಸà³à²•ೀಮಾ ಕಡತ ಕಂಡà³à²¬à²‚ದಿಲà³à²²:" + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "à²à²¨à²¨à³à²¨à³‚ ಮಾಡಬೇಡ.\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "ಈಗಿರà³à²µ ಔಟà³â€Œà²ªà³à²Ÿà³ ಕಡತವನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•ಲಾಗಿದೆ.\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "ಪೂರà³à²µà²¨à²¿à²¯à³‹à²œà²¿à²¤à²µà²¾à²¦ ಕೋಶ ಮೇಲà³à²µà²¿à²šà²¾à²°à²• ಬಗೆಯನà³à²¨à³ ಪತà³à²¤à³† ಮಾಡಲಾಗಲಿಲà³à²²" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "ಅಮಾನà³à²¯ ಕಡತದ ಹೆಸರೠ%s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ಕಡತವà³à²¯à²µà²¸à³à²¥à³†à²¯ ಮಾಹಿತಿಯನà³à²¨à³ ಪಡೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "ಮೂಲ ಕಡತಕೋಶದ ಹೆಸರನà³à²¨à³ ಬದಲಾಯಿಸಲಾಗà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "ಕಡತದ ಹೆಸರನà³à²¨à³ ಬದಲಾಯಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "ಕಡತವನà³à²¨à³ ಮರà³à²¹à³†à²¸à²°à²¿à²¸à²²à²¾à²—ಿಲà³à²², ಕಡತವೠಈಗಾಗಲೆ ಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²¦à³†" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "ಅಮಾನà³à²¯ ಕಡತದ ಹೆಸರà³" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "ಕೋಶವನà³à²¨à³ ತೆರೆಯಲಾಗಿಲà³à²²" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "ಕಡತವನà³à²¨à³ ತೆರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "ಕಡತವನà³à²¨à³ ತೆಗೆದೠಹಾಕà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "ಕಡತವನà³à²¨à³ ಕಸದ ಬà³à²Ÿà³à²Ÿà²¿à²—ೆ ವರà³à²—ಾಯಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "ಕಸದ ಬà³à²Ÿà³à²Ÿà²¿ ಕೋಶ %s ಅನà³à²¨à³ ರಚಿಸಲಾಗಿಲà³à²²: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "ಕಸದ ಬà³à²Ÿà³à²Ÿà²¿à²—ಾಗಿ ಮೇಲà³à²®à²Ÿà³à²Ÿà²¦ ಕೋಶವನà³à²¨à³ ಪತà³à²¤à³†à²®à²¾à²¡à²²à²¾à²—ಲಿಲà³à²²" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "ಕಸದ ಬà³à²Ÿà³à²Ÿà²¿ ಕಡತಕೋಶವನà³à²¨à³ ಪತà³à²¤à³†à²®à²¾à²¡à²²à³ ಅಥವ ರಚಿಸಲಾಗಿಲà³à²²" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "ಟà³à²°à³à²¯à²¾à²¶à²¿à²‚ಗೠಮಾಹಿತಿ ಕಡತವನà³à²¨à³ ರಚಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ಕಡತವನà³à²¨à³ ಟà³à²°à³à²¯à²¾à²¶à³ ಮಾಡà³à²µà²²à³à²²à²¿ ಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "ಆಂತರಿಕ ದೋಷ" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "ಕಡತ ಕೋಶವನà³à²¨à³ ರಚಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ಕಡತವà³à²¯à²µà²¸à³à²¥à³†à²¯à³ ಸಾಂಕೇತಿಕ ಕೊಂಡಿಗಳನà³à²¨à³ ಬೆಂಬಲಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "ಸಾಂಕೇತಿಕ ಕೊಂಡಿಯನà³à²¨à³ ಮಾಡà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "ಕಡತವನà³à²¨à³ ಸà³à²¥à²³à²¾à²‚ತರಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "ಕೋಶವನà³à²¨à³ ಇನà³à²¨à³Šà²‚ದೠಕೋಶಕà³à²•ೆ ಸà³à²¥à²³à²¾à²‚ತರಿಸಲಾಗà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "ಬà³à²¯à²¾à²•ೠಕಡತವನà³à²¨à³ ನಿರà³à²®à²¿à²¸à³à²µà²²à³à²²à²¿ ವಿಫಲತೆ" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "ಸೂಚಿತ ಕಡತವನà³à²¨à³ ತೆಗೆದೠಹಾಕà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "ಎರಡೠಆರೋಹಣ ತಾಣಗಳ ನಡà³à²µà³† ವರà³à²—ಾಯಿಸà³à²µà³à²¦à³ ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/glocalfile.c:2603 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s ಗಾಗಿ ಡಿಸà³à²•ೠಬಳಕೆಯನà³à²¨à³ ನಿರà³à²§à²°à²¿à²¸à²²à²¾à²—ಿಲà³à²²: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "ವೈಶಿಷà³à²Ÿà³à²¯à²¦ ಮೌಲà³à²¯à²µà³ ಶೂನà³à²¯à²µà²²à³à²²à²¦à³à²¦à²¾à²—ಿರಬೇಕà³" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ವೈಶಿಷà³à²Ÿà³à²¯à²¦ ಬಗೆ (ನಿರೀಕà³à²·à²¿à²¤ ಸಾಲà³)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ವಿಸà³à²¤à²°à²¿à²¸à²²à³à²ªà²Ÿà³à²Ÿ ವೈಶಿಷà³à²Ÿà³à²¯à²¦ ಹೆಸರà³" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "ವಿಸà³à²¤à²°à²¿à²¸à²²à³à²ªà²Ÿà³à²Ÿ ವೈಶಿಷà³à²Ÿà³à²¯ '%s' ಅನà³à²¨à³ ಹೊಂದಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (ಅಮಾನà³à²¯ ಸಂಕೇತಿಕರಣ)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "'%s' ಕಡತಕà³à²•ಾಗಿ ಮಾಹಿತಿಯನà³à²¨à³ ಪಡೆದà³à²•ೊಳà³à²³à³à²µà²²à³à²²à²¿ ದೋಷ ಉಂಟಾಗಿದೆ: %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "ಕಡತ ವಿವರಣೆಗಾರನಿಗಾಗಿ ಮಾಹಿತಿಯನà³à²¨à³ ಪಡೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ವೈಶಿಷà³à²Ÿà³à²¯à²¦ ಬಗೆ (uint32 ಅನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ವೈಶಿಷà³à²Ÿà³à²¯à²¦ ಬಗೆ (uint64 ಅನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ವೈಶಿಷà³à²Ÿà³à²¯à²¦ ಬಗೆ (ಬೈಟೠಸಾಲನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "ಸಾಂಕೇತಿಕಕೊಂಡಿಗಳಲà³à²²à²¿ ಅನà³à²®à²¤à²¿à²—ಳನà³à²¨à³ ಹೊಂದಿಸಲಾಗಿಲà³à²²" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "ಅನà³à²®à²¤à²¿à²—ಳನà³à²¨à³ ಹೊಂದಿಸà³à²µà²¾à²— ದೋಷ: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "ಮಾಲಿಕನನà³à²¨à³ ಹೊಂದಿಸà³à²µà²¾à²— ದೋಷ: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "ಸಾಂಕೇತಿಕಕೊಂಡಿಯೠಶೂನà³à²¯à²µà²¾à²—ಿರà³à²µà²‚ತಿಲà³à²²" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "ಸಾಂಕೇತಿಕ ಕೊಂಡಿಯನà³à²¨à³ ಹೊಂದಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "ಸಾಂಕೇತಿಕ ಕೊಂಡಿಯನà³à²¨à³ ಹೊಂದಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: ಕಡತವೠಒಂದೠಸಾಂಕೇತಿಕಕೊಂಡಿಯಾಗಿಲà³à²²" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "ಮಾರà³à²ªà²¡à²£à³† ಅಥವ ನಿಲà³à²•ಣಾ ಸಮಯವನà³à²¨à³ ಹೊಂದಿಸà³à²µà²¾à²— ದೋಷ: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux ಸನà³à²¨à²¿à²µà³‡à²¶à²µà³ NULL ಆಗಿರಬಾರದà³" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux ಸನà³à²¨à²¿à²µà³‡à²¶à²µà²¨à³à²¨à³ ಹೊಂದಿಸà³à²µà²¾à²— ದೋಷ: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "ಈ ಗಣಕದಲà³à²²à²¿ SELinux ಶಕà³à²¤à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s ವೈಶಿಷà³à²Ÿà³à²¯à²—ಳನà³à²¨à³ ಹೊಂದಿಸà³à²µà³à²¦à³ ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "ಕಡತದಿಂದ ಓದà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ಕಡತದಲà³à²²à²¿ ಕೋರà³à²µà²¾à²— ದೋಷ: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "ಕಡತವನà³à²¨à³ ಮà³à²šà³à²šà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "ಪೂರà³à²µà²¨à²¿à²¯à³‹à²œà²¿à²¤à²µà²¾à²¦ ಸà³à²¥à²³à³€à²¯ ಕಡತ ಮೇಲà³à²µà²¿à²šà²¾à²°à²•ದ ಬಗೆಯನà³à²¨à³ ಪತà³à²¤à³† ಮಾಡಲಾಗಿಲà³à²²" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "ಕಡತಕà³à²•ೆ ಬರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "ಹಳೆಯ ಬà³à²¯à²¾à²•à³à²…ಪೠಕೊಂಡಿಯನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "ಬà³à²¯à²¾à²•à³à²…ಪೠಪà³à²°à²¤à²¿à²¯à²¨à³à²¨à³ ನಿರà³à²®à²¿à²¸à³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "ತಾತà³à²•ಾಲಿಕ ಕಡತದ ಹೆಸರನà³à²¨à³ ಬದಲಾಯಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "ಕಡತವನà³à²¨à³ ಟà³à²°à²‚ಕೇಟà³â€ ಮಾಡà³à²µà²²à³à²²à²¿ ಲಿ ದೋಷ: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "'%s' ಕಡತವನà³à²¨à³ ತೆರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "ಸೂಚಿತ ಕಡತವೠಒಂದೠಕೋಶವಾಗಿದೆ" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "ಸೂಚಿತ ಕಡತವೠಒಂದೠಸಾಮಾನà³à²¯ ಕಡತವಲà³à²²" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "ಕಡತವೠಹೊರಗಿನಿಂದ ಮಾರà³à²ªà²¡à²¿à²¸à²²à³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "ಹಳೆಯ ಕಡತವನà³à²¨à³ ತೆಗೆದೠಹಾಕà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:769 +msgid "Invalid GSeekType supplied" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ GSeekType ಅನà³à²¨à³ ಒದಗಿಸಲಾಗಿದೆ" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಕೋರಿಕೆ" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream ಅನà³à²¨à³ ಕಡಿತಗೊಳಿಸಲಾಗಿಲà³à²²" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "ಮೆಮೊರಿ ಪà³à²°à²¦à²¾à²¨ ಸà³à²Ÿà³à²°à³€à²®à³ ಪà³à²¨à²°à³ ಗಾತà³à²°à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "ಮೆಮೊರಿ ಪà³à²°à²¦à²¾à²¨ ಸà³à²Ÿà³à²°à³€à²®à³ ಅನà³à²¨à³ ಪà³à²¨à²°à³ ಗಾತà³à²°à²¿à²¸à³à²µà²²à³à²²à²¿ ವಿಫಲತೆ ಉಂಟಾಗಿದೆ" + +#: ../gio/gmemoryoutputstream.c:671 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"ಬರೆಯà³à²µà²¿à²•ೆಯನà³à²¨à³ ಸಂಸà³à²•ರಿಸಲೠಅಗತà³à²¯à²µà²¿à²°à³à²µ ಮೆಮೊರಿಯ ಮೊತà³à²¤à²µà³ ಲಭà³à²¯à²µà²¿à²°à³à²µ ವಿಳಾಸದ " +"ಸà³à²¥à²³à²•à³à²•ಿಂತ " +"ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../gio/gmemoryoutputstream.c:779 +msgid "Requested seek before the beginning of the stream" +msgstr "ಸà³à²Ÿà³à²°à³€à²®à³â€Œ ಆರಂಭಗೊಳà³à²³à³à²µ ಮೊದಲೠಮನವಿ ಮಾಡಲಾದ ಹà³à²¡à³à²•à³à²µà²¿à²•ೆ (ಸೀಕà³)" + +#: ../gio/gmemoryoutputstream.c:794 +msgid "Requested seek beyond the end of the stream" +msgstr "ಮನವಿಮಾಡಲಾದ ಹà³à²¡à³à²•ಾಟವೠಸà³à²Ÿà³à²°à³€à²®à³â€Œà²¨ ಅಂತà³à²¯à²¦ ಆಚೆ ಇದೆ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "à²à²°à²¿à²¸à³à²µà²¿à²•ೆಯೠ\"unmount\" ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "ಆರೋಹಣವೠ\"eject\" ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"ಆರೋಹಣವೠ\"unmount\" ಅನà³à²¨à³ ಅಥವ \"unmount_with_operation ಅನà³à²¨à³ " +"ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"ಆರೋಹಣವೠ\"eject\" ಅಥವ \"eject_with_operation\" ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "ಆರೋಹಣವೠ\"remount\" ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "ಆರೋಹಣವೠವಿಷಯದ ಬಗೆಯ ಊಹೆಯನà³à²¨à³ ಅನà³à²µà²¯à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "ಆರೋಹಣವೠಹೊಂದಿಕೊಳà³à²³à³à²µ ವಿಷಯದ ಬಗೆಯ ಊಹೆಯನà³à²¨à³ ಅನà³à²µà²¯à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gnetworkaddress.c:383 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "ಅತಿಥೇಯದ ಹೆಸರೠ'%s' '[' ಅನà³à²¨à³ ಹೊಂದಿದೆ ಆದರೆ ']' ಅನà³à²¨à³ ಹೊಂದಿಲà³à²²" + +#: ../gio/gnetworkmonitorbase.c:199 ../gio/gnetworkmonitorbase.c:302 +msgid "Network unreachable" +msgstr "ಜಾಲಬಂಧವನà³à²¨à³ ತಲà³à²ªà²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gnetworkmonitorbase.c:237 ../gio/gnetworkmonitorbase.c:267 +msgid "Host unreachable" +msgstr "ಆತಿಥೇಯವನà³à²¨à³ ತಲà³à²ªà²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "ಜಾಲಬಂಧ ಮೇಲà³à²µà²¿à²šà²¾à²°à²•ವನà³à²¨à³ ಪಡೆಯಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "ಜಾಲಬಂಧ ಮೇಲà³à²µà²¿à²šà²¾à²°à²•ವನà³à²¨à³ ಪಡೆಯಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "ಜಾಲಬಂಧ ಸà³à²¥à²¿à²¤à²¿à²¯à²¨à³à²¨à³ ಪಡೆಯಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²:" + +#: ../gio/gnetworkmonitornm.c:263 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager ಆವೃತà³à²¤à²¿à²¯à³ ಬಹಳ ಹಳೆಯದಾಗಿದೆ" + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:557 +msgid "Output stream doesn't implement write" +msgstr "ಪà³à²°à²¦à²¾à²¨ ಸà³à²Ÿà³à²°à³€à²®à³ ಬರೆಯà³à²µà³à²¦à²¨à³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/goutputstream.c:518 ../gio/goutputstream.c:1218 +msgid "Source stream is already closed" +msgstr "ಮೂಲ ಸà³à²Ÿà³à²°à³€à²®à³ ಈಗಾಗಲೆ ಮà³à²šà³à²šà²²à³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' ಅನà³à²¨à³ ಪರಿಹರಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' ನಲà³à²²à²¿à²¨ ಸಂಪನà³à²®à³‚ಲವೠಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²²à³à²²" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "'%s' ನಲà³à²²à²¿à²¨ ಸಂಪನà³à²®à³‚ಲವನà³à²¨à³ ಸಂಕà³à²šà²¨à²¦à²¿à²‚ದ ಹೊರತೆಗೆಯಲೠವಿಫಲಗೊಂಡಿದೆ" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "'%s' ನಲà³à²²à²¿à²¨ ಸಂಪನà³à²®à³‚ಲವೠಒಂದೠಕೋಶವಾಗಿಲà³à²²" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "ಇನà³â€Œà²ªà³à²Ÿà³ ಸà³à²Ÿà³à²°à³€à²®à³ ಹà³à²¡à³à²•ಾಟವನà³à²¨à³ ಅನà³à²µà²¯à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gresource-tool.c:491 +msgid "List sections containing resources in an elf FILE" +msgstr "ಒಂದೠelf FILE ನಲà³à²²à²¿ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಹೊಂದಿರà³à²µ ವಿಭಾಗಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³" + +#: ../gio/gresource-tool.c:497 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +"SECTION ಅನà³à²¨à³ ಒದಗಿಸಿದà³à²¦à²°à³†, ಈ ವಿಭಾಗದಲà³à²²à²¿ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಮಾತà³à²° ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +"PATH ಅನà³à²¨à³ ಒದಗಿಸಿದà³à²¦à²°à³†, ಹೊಂದಿಕೆಯಾಗà³à²µ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಮಾತà³à²° ಪಟà³à²Ÿà²¿ ಮಾಡà³" + +#: ../gio/gresource-tool.c:500 ../gio/gresource-tool.c:510 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:501 ../gio/gresource-tool.c:511 +#: ../gio/gresource-tool.c:518 +msgid "SECTION" +msgstr "SECTION" + +#: ../gio/gresource-tool.c:506 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +"SECTION ಅನà³à²¨à³ ಒದಗಿಸಿದà³à²¦à²°à³†, ಈ ವಿಭಾಗದಲà³à²²à²¿ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಮಾತà³à²° ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +"PATH ಅನà³à²¨à³ ಒದಗಿಸಿದà³à²¦à²°à³†, ಹೊಂದಿಕೆಯಾಗà³à²µ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಮಾತà³à²° ಪಟà³à²Ÿà²¿ ಮಾಡಿ.\n" +"ವಿವರಗಳೠವಿಭಾಗ, ಗಾತà³à²° ಮತà³à²¤à³ ಸಂಕà³à²šà²¨à²µà²¨à³à²¨à³ ಹೊಂದಿರà³à²¤à³à²¤à²¦à³†" + +#: ../gio/gresource-tool.c:516 +msgid "Extract a resource file to stdout" +msgstr "ಒಂದೠಸಂಪನà³à²®à³‚ಲ ಕಡತವನà³à²¨à³ stdout ಗೆ ಹೊರತೆಗೆ" + +#: ../gio/gresource-tool.c:517 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: ../gio/gresource-tool.c:531 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"ಬಳಕೆ:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"ಆದೇಶಗಳà³:\n" +" help ಈ ಮಾಹಿತಿಯನà³à²¨à³ ತೋರಿಸà³\n" +" sections ಸಂಪನà³à²®à³‚ಲ ವಿಭಾಗಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +" list ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +" details ವಿವರಗಳೊಂದಿಗೆ ಸಂಪನà³à²®à³‚ಲ ವಿಭಾಗಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +" extract ಒಂದೠಸಂಪನà³à²®à³‚ಲವನà³à²¨à³ ಹೊರತೆಗೆ\n" +"\n" +"ವಿವರವಾದ ನೆರವನà³à²¨à³ ಪಡೆಯಲೠ'gresource help COMMAND' ಅನà³à²¨à³ ಬಳಸಿ.\n" +"\n" + +#: ../gio/gresource-tool.c:545 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ಬಳಕೆ:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:552 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION ಒಂದೠ(à²à²šà³à²›à²¿à²•) elf ವಿಭಾಗದ ಹೆಸರà³\n" + +#: ../gio/gresource-tool.c:556 ../gio/gsettings-tool.c:648 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND ವಿವರಿಸಲೠ(à²à²šà³à²›à²¿à²•) ಆದೇಶ\n" + +#: ../gio/gresource-tool.c:562 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE ಒಂದೠelf ಕಡತ (ಒಂದೠಬೈನರಿ ಅಥವ ಹಂಚನಾದ ಲೈಬà³à²°à²°à²¿)\n" + +#: ../gio/gresource-tool.c:565 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE ಒಂದೠelf ಕಡತ (ಒಂದೠಬೈನರಿ ಅಥವ ಹಂಚನಾದ ಲೈಬà³à²°à²°à²¿)\n" +" ಅಥವ ಕಂಪೈಲೠಮಾಡಿದ ಸಂಪನà³à²®à³‚ಲ ಕಡತ\n" + +#: ../gio/gresource-tool.c:569 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:571 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH ಒಂದೠ(à²à²šà³à²›à²¿à²•) ಸಂಪನà³à²®à³‚ಲ ಮಾರà³à²— (ಆಂಶಿಕವಾಗಿರಬಹà³à²¦à³)\n" + +#: ../gio/gresource-tool.c:572 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:574 +msgid " PATH A resource path\n" +msgstr " PATH ಒಂದೠಸಂಪನà³à²®à³‚ಲ ಮಾರà³à²—\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "'%s' ನಂತಹ ಯಾವà³à²¦à³† ಸà³à²•ೀಮಾ ಇಲà³à²²\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "'%s' ಸà³à²•ೀಮಾವನà³à²¨à³ ಸà³à²¥à²³à²¾à²‚ತರಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²² (ಮಾರà³à²—ವನà³à²¨à³ ಸೂಚಿಸಬಾರದà³)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "'%s' ಸà³à²•ೀಮಾವನà³à²¨à³ ಸà³à²¥à²³à²¾à²‚ತರಿಸಬಹà³à²¦à³ (ಮಾರà³à²—ವನà³à²¨à³ ಸೂಚಿಸಬೇಕà³)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "ಖಾಲಿ ಮಾರà³à²—ವನà³à²¨à³ ಒದಗಿಸಲಾಗಿದೆ.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "ಮಾರà³à²—ವೠಒಂದೠಸà³à²²à³à²¯à²¾à²¶à³â€Œà²¨à²¿à²‚ದ ಆರಂಭಗೊಳà³à²³à²¬à³‡à²•à³ (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "ಮಾರà³à²—ವೠಒಂದೠಸà³à²²à³à²¯à²¾à²¶à³â€Œà²¨à²¿à²‚ದ ಕೊನೆಗೊಳà³à²³à²¬à³‡à²•à³ (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "ಮಾರà³à²—ವೠಒಂದೠಒಂದರ ನಂತರ ಇನà³à²¨à³Šà²‚ದೠಸà³à²²à³à²¯à²¾à²¶à³â€Œ ಹೊಂದಿರಬಾರದೠ(//)\n" + +#: ../gio/gsettings-tool.c:490 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "ಒದಗಿಸಲಾದ ಮೌಲà³à²¯à²µà³ ಮಾನà³à²¯à²µà²¾à²¦ ವà³à²¯à²¾à²ªà³à²¤à²¿à²¯ ಹೊರಗಿದೆ\n" + +#: ../gio/gsettings-tool.c:497 +#, c-format +msgid "The key is not writable\n" +msgstr "ಕೀಲಿಗೆ ಬರೆಯಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²\n" + +#: ../gio/gsettings-tool.c:533 +msgid "List the installed (non-relocatable) schemas" +msgstr "ಅನà³à²¸à³à²¥à²¾à²ªà²¿à²¸à²²à²¾à²¦ (ಸà³à²¥à²³à²¾à²‚ತರಿಸಲಾಗದ) ಸà³à²•ೀಮಾಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed relocatable schemas" +msgstr "ಅನà³à²¸à³à²¥à²¾à²ªà²¿à²¸à²²à²¾à²¦ ಸà³à²¥à²³à²¾à²‚ತರಿಸಬಹà³à²¦à²¾à²¦ ಸà³à²•ೀಮಾಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³" + +#: ../gio/gsettings-tool.c:545 +msgid "List the keys in SCHEMA" +msgstr "SCHEMA ನಲà³à²²à²¿ ಕೀಲಿಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³" + +#: ../gio/gsettings-tool.c:546 ../gio/gsettings-tool.c:552 +#: ../gio/gsettings-tool.c:589 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:551 +msgid "List the children of SCHEMA" +msgstr "SCHEMA ದ ಉಪಅಂಶಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³" + +#: ../gio/gsettings-tool.c:557 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"ಕೀಲಿಗಳೠಮತà³à²¤à³ ಮೌಲà³à²¯à²—ಳನà³à²¨à³ ಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¿à²¤à²µà²¾à²—ಿ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +"ಯಾವà³à²¦à³† SCHEMA ಒದಗಿಸದೆ ಇದà³à²¦à²²à³à²²à²¿, ಎಲà³à²²à²¾ ಕೀಲಿಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" + +#: ../gio/gsettings-tool.c:559 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:564 +msgid "Get the value of KEY" +msgstr "KEY ಯ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಪಡೆದà³à²•ೊ" + +#: ../gio/gsettings-tool.c:565 ../gio/gsettings-tool.c:571 +#: ../gio/gsettings-tool.c:583 ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:570 +msgid "Query the range of valid values for KEY" +msgstr "KEY ಗಾಗಿನ ಮಾನà³à²¯à²µà²¾à²¦ ಮೌಲà³à²¯à²—ಳ ವà³à²¯à²¾à²ªà³à²¤à²¿à²¯à²¨à³à²¨à³ ಮನವಿ ಮಾಡà³" + +#: ../gio/gsettings-tool.c:576 +msgid "Set the value of KEY to VALUE" +msgstr "KEY ಮೌಲà³à²¯à²µà²¨à³à²¨à³ VALUE ಗೆ ಹೊಂದಿಸà³" + +#: ../gio/gsettings-tool.c:577 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:582 +msgid "Reset KEY to its default value" +msgstr "KEY ಅನà³à²¨à³ ಪೂರà³à²µà²¨à²¿à²¯à³‹à²œà²¿à²¤ ಮೌಲà³à²¯à²•à³à²•ೆ ಮರà³à²¹à³Šà²‚ದಿಸà³" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "SCHEMA ದಲà³à²²à²¿à²¨ ಎಲà³à²²à²¾ ಕೀಲಿಗಳನà³à²¨à³ ಪೂರà³à²µà²¨à²¿à²¯à³‹à²œà²¿à²¤à²—ಳಿಗೆ ಮರà³à²¹à³Šà²‚ದಿಸà³" + +#: ../gio/gsettings-tool.c:594 +msgid "Check if KEY is writable" +msgstr "KEY ಗೆ ಬರೆಯಬಹà³à²¦à³† ಎಂದೠಪರೀಕà³à²·à²¿à²¸à²¿" + +#: ../gio/gsettings-tool.c:600 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"ಬದಲಾವಣೆಗಳಿಗಾಗಿ KEY ಅನà³à²¨à³ ಮೇಲà³à²µà²¿à²šà²¾à²°à²£à³† ಮಾಡà³.\n" +"ಯಾವà³à²¦à³† KEY ಅನà³à²¨à³ ಸೂಚಿಸದೆ ಇದà³à²¦à²²à³à²²à²¿, SCHEMA ದಲà³à²²à²¿à²¨ ಎಲà³à²²à²¾ ಕೀಲಿಗಳನà³à²¨à³ ಮೇಲà³à²µà²¿à²šà²¾à²°à²£à³† " +"ಮಾಡà³.\n" +"ಮೇಲà³à²µà²¿à²šà²¾à²°à²£à³†à²¯à²¨à³à²¨à³ ನಿಲà³à²²à²¿à²¸à²²à³ ^C ಅನà³à²¨à³ ಬಳಸಿ.\n" + +#: ../gio/gsettings-tool.c:603 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:615 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"ಬಳಕೆ:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"ಆದೇಶಗಳà³:\n" +" help ಈ ಮಾಹಿತಿಯನà³à²¨à³ ತೋರಿಸà³\n" +" list-schemas ಅನà³à²¸à³à²¥à²¾à²ªà²¿à²¸à²²à²¾à²¦ ಸà³à²•ೀಮಾಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +" list-relocatable-schemas ಸà³à²¥à²³à²¾à²‚ತರಿಸಬಹà³à²¦à²¾à²¦ ಸà³à²•ೀಮಾಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +" list-keys ಸà³à²•ೀಮಾದಲà³à²²à²¿à²¨ ಕೀಲಿಗಳನà³à²¨à³ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +" list-children ಸà³à²•ೀಮಾದ ಉಪಅಂಶದ ಪಟà³à²Ÿà²¿ ಮಾಡà³\n" +" list-recursively ಕೀಲಿಗಳ ಮತà³à²¤à³ ಮೌಲà³à²¯à²—ಳನà³à²¨à³, ಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¿à²¤à²µà²¾à²—ಿ ಪಟà³à²Ÿà²¿ " +"ಮಾಡà³\n" +" range ಕೀಲಿಯ ವà³à²¯à²¾à²ªà³à²¤à²¿à²—ಾಗಿ ಮನವಿ ಮಾಡà³\n" +" get ಕೀಲಿಯ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ನೀಡà³\n" +" set ಕೀಲಿಯ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಹೊಂದಿಸà³\n" +" reset ಕೀಲಿಯ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಮರà³à²¹à³Šà²‚ದಿಸà³\n" +" reset-recursively ಒಂದೠನಿರà³à²¦à²¿à²·à³à²Ÿ ಸà³à²•ೀಮಾದಲà³à²²à²¿à²¨ ಎಲà³à²²à²¾ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ " +"ಮರà³à²¹à³Šà²‚ದಿಸà³\n" +" writable ಕೀಲಿಗೆ ಬರೆಯಲೠಸಾಧà³à²¯à²µà³† ಎಂದೠಪರಿಶೀಲಿಸà³\n" +" monitor ಬದಲಾವಣೆಗಳಿಗಾಗಿ ನೋಡà³\n" +"\n" +"ವಿವರವಾದ ನೆರವಿಗಾಗಿ 'gsettings help COMMAND' ಅನà³à²¨à³ ಬಳಸಿ.\n" +"\n" + +#: ../gio/gsettings-tool.c:638 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ಬಳಕೆ:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:644 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR ಹೆಚà³à²šà³à²µà²°à²¿ ಸà³à²•ೀಮಾಗಳಿಗಾಗಿ ಹà³à²¡à³à²•ಬೇಕಿರà³à²µ ಒಂದೠಕೋಶ\n" + +#: ../gio/gsettings-tool.c:652 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA ಸà³à²•ೀಮಾದ ಹೆಸರà³\n" +" PATH ಸà³à²¥à²³à²¾à²‚ತರಿಸಬಹà³à²¦à²¾à²¦ ಸà³à²•ೀಮಾಗಳಿಗಾಗಿನ ಮಾರà³à²—\n" + +#: ../gio/gsettings-tool.c:657 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY ಸà³à²•ೀಮಾದಲà³à²²à²¿à²¨ (à²à²šà³à²›à²¿à²•) ಕೀಲಿ\n" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The key within the schema\n" +msgstr " KEY ಸà³à²•ೀಮಾದಲà³à²²à²¿à²¨ ಕೀಲಿ\n" + +#: ../gio/gsettings-tool.c:665 +msgid " VALUE The value to set\n" +msgstr " VALUE ಹೊಂದಿಸಬೇಕಿರà³à²µ ಮೌಲà³à²¯\n" + +#: ../gio/gsettings-tool.c:720 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s ಗಾಗಿ ಸà³à²•ೀಮಾಗಳನನà³à²¨à³ ಲೋಡೠಮಾಡಲಾಗಿಲà³à²²: %s\n" + +#: ../gio/gsettings-tool.c:782 +#, c-format +msgid "Empty schema name given\n" +msgstr "ಖಾಲಿ ಸà³à²•ೀಮಾದ ಹೆಸರನà³à²¨à³ ನೀಡಲಾಗಿದೆ\n" + +#: ../gio/gsettings-tool.c:811 +#, c-format +msgid "No such key '%s'\n" +msgstr "'%s' ನಂತಹ ಯಾವà³à²¦à³† ಕೀಲಿ ಇಲà³à²²\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಸಾಕೆಟà³, ಆರಂಭಿಸಲಾಗಿಲà³à²²" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಸಾಕೆಟà³, ಆರಂಭಿಸà³à²µà²¿à²•ೆಯೠವಿಫಲಗೊಂಡಿದೆ à²à²•ೆಂದರೆ: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "ಸಾಕೆಟೠಈಗಾಗಲೆ ಮà³à²šà³à²šà²²à³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "ಸಾಕೆಟೠI/O ಕಾಲಾವಧಿ ತೀರಿದೆ" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd ಇಂದ GSocket ಅನà³à²¨à³ ರಚಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "ಸಾಕೆಟà³â€Œ ಅನà³à²¨à³ ರಚಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "ಅಜà³à²žà²¾à²¤à²µà²¾à²¦ ಕà³à²Ÿà³à²‚ಬವನà³à²¨à³ ಸೂಚಿಸಲಾಗಿದೆ" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "ಅಜà³à²žà²¾à²¤à²µà²¾à²¦ ಪà³à²°à³Šà²Ÿà³Šà²•ಾಲೠಅನà³à²¨à³ ಸೂಚಿಸಲಾಗಿದೆ" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "ಸà³à²¥à²³à³€à²¯ ವಿಳಾಸವನà³à²¨à³ ಪಡೆಯಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "ದೂರಸà³à²¥ ವಿಳಾಸವನà³à²¨à³ ಪಡೆಯಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "ಆಲಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "ವಿಳಾಸಕà³à²•ೆ ಬದà³à²¦à²µà²¾à²—ಿರà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "ಮಲà³à²Ÿà²¿à²•à³à²¯à²¾à²¸à³à²Ÿà³â€ ಗà³à²‚ಪನà³à²¨à³ ಸೇರà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "ಮಲà³à²Ÿà²¿à²•à³à²¯à²¾à²¸à³à²Ÿà³â€ ಗà³à²‚ಪನà³à²¨à³ ತೊರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "ಆಕರ-ನಿಗದಿತವಾದ ಮಲà³à²Ÿà²¿à²•à³à²¯à²¾à²¸à³à²Ÿà²¿à²—ೆ ಬೆಂಬಲವಿಲà³à²²" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "ಸಂಪರà³à²•ವನà³à²¨à³ ಅಂಗೀಕರಿಸà³à²µà²¾à²— ದೋಷ: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "ಸಂಪರà³à²•ವೠಪà³à²°à²—ತಿಯಲà³à²²à²¿à²¦à³†" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "ಬಾಕಿ ಇರà³à²µ ದೋಷವನà³à²¨à³ ಪಡೆಯಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²:" + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "ದತà³à²¤à²¾à²‚ಶವನà³à²¨à³ ಸà³à²µà³€à²•ರಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "ದತà³à²¤à²¾à²‚ಶವನà³à²¨à³ ಕಳಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ಸಾಕೆಟà³â€Œ ಅನà³à²¨à³ ಸà³à²¥à²—ಿತಗೊಳಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "ದತà³à²¤à²¾à²‚ಶವನà³à²¨à³ ಮà³à²šà³à²šà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ಸಾಕೆಟà³â€Œ ಸà³à²¥à²¿à²¤à²¿à²—ಾಗಿ ಕಾಯಲಾಗà³à²¤à³à²¤à²¿à²¦à³†: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 ../gio/gsocket.c:4206 +#, c-format +msgid "Error sending message: %s" +msgstr "ಸಂದೇಶವನà³à²¨à³ ಕಳà³à²¹à²¿à²¸à³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "Windows ನಲà³à²²à²¿ GSocketControlMessage ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/gsocket.c:4534 ../gio/gsocket.c:4669 +#, c-format +msgid "Error receiving message: %s" +msgstr "ಸಂದೇಶವನà³à²¨à³ ಪಡೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gsocket.c:4791 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "ಸಾಕೆಟà³â€Œ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಓದಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" + +#: ../gio/gsocket.c:4800 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials ಅನà³à²¨à³ ಈ OS ನಲà³à²²à²¿ ಅನà³à²µà²¯à²¿à²¸à²²à²¾à²—ಿಲà³à²²" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "ಪà³à²°à²¾à²•à³à²¸à²¿ ಪರಿಚಾರಕ %s ಕà³à²•ೆ ಸಂಪರà³à²• ಹೊಂದಲಾಗಿಲà³à²²: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s ದೊಂದಿಗೆ ಸಂಪರà³à²• ಹೊಂದಲಾಗಿಲà³à²²: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "ಸಂಪರà³à²• ಹೊಂದಲಾಗಿಲà³à²²: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1603 +msgid "Unknown error on connect" +msgstr "ಸಂಪರà³à²•ಸಾಧಿಸà³à²µà²²à³à²²à²¿ ಗೊತà³à²¤à²¿à²°à²¦ ದೋಷ" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1538 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "TCPಯಲà³à²²à²¦ ಸಂಪರà³à²•ದಲà³à²²à²¿ ಪà³à²°à²¾à²•à³à²¸à²¿ ಮಾಡà³à²µà²¿à²•ೆಯನà³à²¨à³ ಬೆಂಬಲಿಸಲಾಗಿಲà³à²²." + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1559 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "'%s' ಎಂಬ ಪà³à²°à²¾à²•à³à²¸à²¿ ಪà³à²°à³Šà²Ÿà³Šà²•ಾಲೠಬೆಂಬಲಿತವಾಗಿಲà³à²²." + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "ಆಲಿಸà³à²µà³à²µà³à²¦à²¨à³à²¨à³ ಈಗಾಗಲೆ ಮà³à²šà³à²šà²²à²¾à²—ಿದೆ" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "ಸೇರಿಸಲಾದ ಸಾಕೆಟೠಅನà³à²¨à³ ಮà³à²šà³à²šà²²à²¾à²—ಿದೆ" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 '%s' ಎಂಬ IPv6 ವಿಳಾಸವನà³à²¨à³ ಬೆಂಬಲಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 ಪà³à²°à³Šà²Ÿà³Šà²•ಾಲà³â€Œà²—ಾಗಿ ಬಳಕೆದಾರ ಹೆಸರೠಬಹಳ ಉದà³à²¦à²µà²¾à²—ಿದೆ." + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 ಪà³à²°à³Šà²Ÿà³Šà²•ಾಲà³â€Œà²—ಾಗಿನ '%s' ಆತಿಥೇಯಗಣಕದ ಹೆಸರೠಬಹಳದ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "ಪೂರೈಕೆಗಣಕವೠಒಂದೠSOCKSv4 ಪà³à²°à²¾à²•à³à²¸à²¿ ಪೂರೈಕೆಗಣಕವಾಗಿಲà³à²²" + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 ಪೂರೈಕೆಗಣಕದ ಮà³à²–ಾಂತರದ ಸಂಪರà³à²•ವನà³à²¨à³ ನಿರಾಕರಿಸಲಾಗಿದೆ" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "ಪೂರೈಕೆಗಣಕವೠSOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿ ಪೂರೈಕೆಗಣಕವಾಗಿಲà³à²²." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿à²—ಾಗಿ ದೃಢೀಕರಣದ ಅಗತà³à²¯à²µà²¿à²¦à³†" + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿à²—ಾಗಿ GLib ನಿಂದ ಬೆಂಬಲಿತವಾಗಿರದ ದೃಢೀಕರಣ ವಿಧಾನದ ಅಗತà³à²¯à²µà²¿à²¦à³†." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 ಪà³à²°à³Šà²Ÿà³Šà²•ಾಲà³â€Œà²—ಾಗಿ ಬಳಕೆದಾರ ಹೆಸರೠಅಥವ ಗà³à²ªà³à²¤à²ªà²¦à²µà³ ಬಹಳ ಉದà³à²¦à²µà²¾à²—ಿದೆ." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"ತಪà³à²ªà³ ಬಳಕೆದಾರ ಹೆಸರೠಅಥವ ಗà³à²ªà³à²¤à²ªà²¦à²¦ ಕಾರಣದಿಂದಾಗಿ SOCKSv5 ದೃಢೀಕರಣವೠವಿಫಲಗೊಂಡಿದೆ." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "SOCKSv5 ಪà³à²°à³Šà²Ÿà³Šà²•ಾಲà³â€Œà²—ಾಗಿನ '%s' ಆತಿಥೇಯಗಣಕದ ಹೆಸರೠಬಹಳದ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿à²¯ ಪೂರೈಕೆಗಣಕವೠಗೊತà³à²¤à²¿à²°à²¦ ವಿಳಾಸದ ಬಗೆಯನà³à²¨à³ ಬಳಸà³à²¤à³à²¤à²¦à³†." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "ಆಂತರಿಕ SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿à²¯ ಪೂರೈಕೆಗಣಕ ದೋಷ." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 ಸಂಪರà³à²•ವನà³à²¨à³ ನಿಯಮಗಳಿಂದ ಅನà³à²®à²¤à²¿à²¸à²²à³à²ªà²Ÿà³à²Ÿà²¿à²²à³à²²." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 ಪೂರೈಕೆಗಣಕ ಮೂಲಕ ಆತಿಥೇಯವನà³à²¨à³ ತಲà³à²ªà²²à²¾à²—ಿಲà³à²²." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿à²¯ ಮೂಲಕ ಜಾಲಬಂಧವನà³à²¨à³ ತಲà³à²ªà²²à²¾à²—ಿಲà³à²²." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿à²¯ ಮೂಲಕದ ಸಂಪರà³à²•ವನà³à²¨à³ ನಿರಾಕರಿಸಲಾಗಿದೆ." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿à²¯à³ 'connect' ಆದೇಶಯನà³à²¨à³ ಬೆಂಬಲಿಸà³à²µà³à²¦à²¿à²²à³à²²." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿à²¯à³ ಒದಗಿಸಲಾದ ವಿಳಾಸದ ಬಗೆಯನà³à²¨à³ ಬೆಂಬಲಿಸà³à²µà³à²¦à²¿à²²à³à²²." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "ಅಜà³à²žà²¾à²¤ SOCKSv5 ಪà³à²°à²¾à²•à³à²¸à²¿ ದೋಷ." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon ಎನà³à²•ೋಡಿಂಗà³â€Œà²¨ ಆವೃತà³à²¤à²¿ %d ಅನà³à²¨à³ ನಿಭಾಯಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "ಯಾವà³à²¦à³† ಮಾನà³à²¯à²µà²¾à²¦ ವಿಳಾಸಗಳೠಕಂಡà³à²¬à²‚ದಿಲà³à²²" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' ಅನà³à²¨à³ ವಿಲೋಮವಾಗಿ ಪರಿಹರಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "'%s' ಗಾಗಿ ಮನವಿ ಮಾಡಲಾದ ಬಗೆಗೆ ಯಾವà³à²¦à³† DNS ದಾಖಲೆ ಇಲà³à²²" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "'%s' ಅನà³à²¨à³ ಪರಿಹರಿಸà³à²µà²²à³à²²à²¿ ತಾತà³à²•ಾಲಿಕ ದೋಷ ಉಂಟಾಗಿದೆ" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "'%s' ಅನà³à²¨à³ ಪರಿಹರಿಸà³à²µà²²à³à²²à²¿ ದೋಷ" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-ಎನà³à²•ೋಡೠಮಾಡಲಾದ ಖಾಸಗಿ ಕೀಲಿಯನà³à²¨à³ ಡಿಕೋಡೠಮಾಡಲಾಗಿಲà³à²²" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "ಯಾವà³à²¦à³† PEM-ಎನà³à²•ೋಡೠಮಾಡಲಾದ ಖಾಸಗಿ ಕೀಲಿಯೠಕಂಡà³à²¬à²‚ದಿಲà³à²²" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-ಎನà³à²•ೋಡೠಮಾಡಲಾದ ಖಾಸಗಿ ಕೀಲಿಯನà³à²¨à³ ಪಾರà³à²¸à³ ಮಾಡಲಾಗಿಲà³à²²" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "ಯಾವà³à²¦à³† PEM-ಎನà³à²•ೋಡೠಮಾಡಲಾದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ಕಂಡà³à²¬à²‚ದಿಲà³à²²" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-ಎನà³à²•ೋಡೠಮಾಡಲಾದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಪಾರà³à²¸à³ ಮಾಡಲಾಗಿಲà³à²²" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"ಇದೠನಿಮà³à²® ಪà³à²°à²µà³‡à²¶à²¾à²§à²¿à²•ಾರವನà³à²¨à³ ಬಂಧಿಸà³à²µ ಮà³à²‚ಚೆ ಸರಿಯಾದ ಗà³à²ªà³à²¤à²ªà²¦à²µà²¨à³à²¨à³ ನಮೂದಿಸà³à²µ ನಿಮà³à²® " +"ಕಡೆಯ " +"ಅವಕಾಶವಾಗಿರà³à²¤à³à²¤à²¦à³†." + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"ನಮೂದಿಸಲಾದ ಹಲವಾರೠಗà³à²ªà³à²¤à²ªà²¦à²—ಳೠತಪà³à²ªà²¾à²—ಿವೆ, ಮತà³à²¤à³ ಮà³à²‚ದಿನ ಬಾರಿ ನೀವೠವಿಫಲಗೊಂಡರೆ " +"ನಿಮà³à²® " +"ಪà³à²°à²µà³‡à²¶à²¾à²§à²¿à²•ಾರವನà³à²¨à³ ಬಂಧಿಸಲಾಗà³à²¤à³à²¤à²¦à³†." + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "ನಮೂದಿಸಲಾದ ಗà³à²ªà³à²¤à²ªà²¦à²µà³ ಸರಿಯಾಗಿಲà³à²²." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 ನಿಯಂತà³à²°à²£ ಸಂದೇಶವನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, %d ಅನà³à²¨à³ ಪಡೆಯಲಾಗಿದೆ" +msgstr[1] "1 ನಿಯಂತà³à²°à²£ ಸಂದೇಶವನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, %d ಅನà³à²¨à³ ಪಡೆಯಲಾಗಿದೆ" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "ಅನಿರೀಕà³à²·à²¿à²¤ ಬಗೆಯ ಪೂರಕ ದತà³à²¤à²¾à²‚ಶ" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "ಒಂದೠfd ಅನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, ಆದರೆ %d ಅನà³à²¨à³ ಪಡೆಯಲಾಗಿದೆ\n" +msgstr[1] "ಒಂದೠfd ಅನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, ಆದರೆ %d ಅನà³à²¨à³ ಪಡೆಯಲಾಗಿದೆ\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ fd ಯನà³à²¨à³ ಸà³à²µà³€à²•ರಿಸಲಾಗಿದೆ" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಕಳà³à²¹à²¿à²¸à³à²µà²²à³à²²à²¿ ದೋಷ: " + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "SO_PASSCRED ಅನà³à²¨à³ ಸಾಕೆಟà³â€Œà²—ಾಗಿ ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸಲಾಗಿದà³à²¦à²°à³† ದೋಷ: %s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED ಅನà³à²¨à³ ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಸà³à²µà³€à²•ರಿಸಲೠಒಂದೠಬೈಟೠಅನà³à²¨à³ ಓದà³à²µà³à²¦à²¨à³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, ಆದರೆ " +"ಸೊನà³à²¨à³† " +"ಬೈಟà³â€Œà²—ಳನà³à²¨à³ ಓದಲಾಗಿದೆ" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "ನಿಯಂತà³à²°à²£ ಸಂದೇಶವನà³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿರಲಿಲà³à²², ಆದರೆ %d ಅನà³à²¨à³ ಪಡೆಯಲಾಗಿದೆ" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED ಅನà³à²¨à³ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ಕಡತ ವಿವರಣೆಗಾರನನà³à²¨à³ ಲೋಡೠಮಾಡà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ಕಡತ ವಿವರಣೆಗಾರನನà³à²¨à³ ಮà³à²šà³à²šà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gunixmounts.c:2054 ../gio/gunixmounts.c:2107 +msgid "Filesystem root" +msgstr "ಕಡತವà³à²¯à²µà²¸à³à²¥à³† ಮೂಲ" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ಕಡತ ವಿವರಣೆಗಾರನಿಗೆ ಬರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"ಅಬà³â€Œà²¸à³à²Ÿà³à²°à²¾à²•à³à²Ÿà³ ಯà³à²¨à²¿à²•à³à²¸à³ ಡೊಮೈನೠಸಾಕೆಟೠವಿಳಾಸಗಳಿಗೆ ಈ ವà³à²¯à²µà²¸à³à²¥à³†à²¯à²²à³à²²à²¿ ಬೆಂಬಲವಿಲà³à²²" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "ಪರಿಮಾಣವೠಹೊರ ತಳà³à²³à³à²µà³à²¦à²¨à³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà³à²¦à²¿à²²à³à²²" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" +"ಪರಿಮಾಣವೠಹೊರ ತಳà³à²³à³à²µà³à²¦à²¨à³à²¨à³ ಅಥವ eject_with_operation ಅನà³à²¨à³ ಅನà³à²µà²¯à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "ಅನà³à²µà²¯à²µà²¨à³à²¨à³ ಪತà³à²¤à³†à²®à²¾à²¡à²²à²¾à²—à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../gio/gwin32appinfo.c:303 +#, c-format +msgid "Error launching application: %s" +msgstr "ಅನà³à²µà²¯à²µà²¨à³à²¨à³ ಆರಂಭಿಸà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gwin32appinfo.c:378 +msgid "association changes not supported on win32" +msgstr "win32 ನಲà³à²²à²¿ ಅಸೋಸಿಯೇಶನೠಬದಲಾವಣೆಗಳೠಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/gwin32appinfo.c:390 +msgid "Association creation not supported on win32" +msgstr "win32 ನಲà³à²²à²¿ ಅಸೋಸಿಯೇಶನೠರಚನೆಯೠಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "ಹಿಡಿಕೆಯಿಂದ ಓದà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "ಹಿಡಿಕೆಯನà³à²¨à³ ಮà³à²šà³à²šà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "ಹಿಡಿಕೆಗೆ ಬರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "ಸಾಕಷà³à²Ÿà³ ಮೆಮೊರಿಯೠಲಭà³à²¯à²µà²¿à²²à³à²²" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "ಆಂತರಿಕ ದೋಷ: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "ಹೆಚà³à²šà²¿à²¨ ಇನà³â€Œà²ªà³à²Ÿà³â€Œà²¨ ಅಗತà³à²¯à²µà²¿à²¦à³†" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಸಂಕà³à²šà²¨à²—ೊಂಡ ದತà³à²¤à²¾à²‚ಶ" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ಆಲಿಸಬೇಕಿರà³à²µ ವಿಳಾಸ" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "GTestDbus ನೊಂದಿಗೆ ಹೊಂದಿಕೆಗಾಗಿ ಕಡೆಗಣಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "ವಿಳಾಸವನà³à²¨à³ ಮà³à²¦à³à²°à²¿à²¸à³" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "ಶೆಲೠಸà³à²¥à²¿à²¤à²¿à²¯à²²à³à²²à²¿ ವಿಳಾಸವನà³à²¨à³ ಮà³à²¦à³à²°à²¿à²¸à³" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "ಒಂದೠdbus ಸೇವೆಯನà³à²¨à³ ಚಲಾಯಿಸà³" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "ತಪà³à²ªà³ ಆರà³à²—à³à²¯à³à²®à³†à²‚ಟà³â€Œà²—ಳà³\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "'%s'ಘಟಕಕà³à²•ೆ ಅನಪೇಕà³à²·à²¿à²¤ ಗà³à²£ ವಿಶೇಷ '%s'" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' ದ ಘಟಕಕà³à²•ೆ '%s' ಗà³à²£à²µà²¿à²¶à³‡à²· ಪತà³à²¤à³†à²¯à²¾à²—ಿಲà³à²²" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "ಅನಪೇಕà³à²·à²¿à²¤ ಪದಗà³à²šà³à²› '%s', ಪದಗà³à²šà³à²› '%s' ವನà³à²¨à³ ಅಪೇಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "'%s' ದ ಒಳಗೆ ಅನಪೇಕà³à²·à²¿à²¤ ಪದಗà³à²šà³à²› '%s" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "ದತà³à²¤à²¾à²‚ಶ ಕೋಶದಲà³à²²à²¿ ಯಾವà³à²¦à³‡ ಮಾನà³à²¯ ಬà³à²•ೠಮಾರà³à²•ೠಕಂಡೠಬಂದಿಲà³à²²" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s' ಗೆ ಈಗಾಗಲೆ ಒಂದೠಬà³à²•ೠಮಾರà³à²•ೠಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²¦à³†" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s' ಗೆ ಯಾವà³à²¦à³‡ ಬà³à²•ೠಮಾರà³à²•ೠಕಂಡೠಬಂದಿಲà³à²²" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s' ಗಾಗಿನ ಬà³à²•ೠಮಾರà³à²•ಿನಲà³à²²à²¿ ಯಾವà³à²¦à³‡ MIME ಪà³à²°à²•ಾರವೠಕಂಡà³à²¬à²‚ದಿಲà³à²²" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s' ನ ಬà³à²•ೠಮಾರà³à²•ಿನಲà³à²²à²¿ ಯಾವà³à²¦à³‡ ಖಾಸಗಿ ನಿಶಾನೆಯೠಸೂಚಿತವಾಗಿಲà³à²²" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s' ಗಾಗಿ ಯಾವà³à²¦à³‡ ಸಮೂಹವೠಸಂಯೋಜಿತವಾಗಿಲà³à²²" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" +"'%s' ಎಂಬ ಹೆಸರಿನ ಯಾವà³à²¦à³‡ ಅನà³à²µà²¯à²µà³ '%s' ಗಾಗಿ ಒಂದೠಬà³à²•à³-ಮಾರà³à²•ನà³à²¨à³ ನೊಂದಾಯಿಸಿಲà³à²²" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "exec ಸಾಲೠ'%s' ಅನà³à²¨à³ URI '%s' ನೊಂದಿಗೆ ವಿಸà³à²¤à²°à²¿à²¸à³à²µà²²à³à²²à²¿ ವಿಫಲತೆ ಎದà³à²°à²¾à²—ಿದೆ" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "ಆದಾನದ ಕೊನೆಯಲà³à²²à²¿ ಆಂಶಿಕ ಅಕà³à²·à²° ಅನà³à²•à³à²°à²®à²£à³†" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "fallback '%s' ಅನà³à²¨à³ ಸಂಕೇತಸೆಟೠ'%s' ಗೆ ಪರಿವರà³à²¤à²¿à²¸à²²à²¾à²—ಿಲà³à²²" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s' \"ಕಡತ\" ವಿಧಾನವನà³à²¨à³ ಬಳಸà³à²µ ಒಂದೠಪರಿಪೂರà³à²£à²µà²¾à²¦ URI ಅಲà³à²²" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "ಸà³à²¥à²³à³€à²¯ ಕಡತ URI '%s' ಒಂದೠ'#' ಅನà³à²¨à³ ಹೊಂದಿಲà³à²²à²¦à²¿à²°à²¬à²¹à³à²¦à³" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' ಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI '%s' ನ ಅತಿಥೇಯದ ಹೆಸರೠಸರಿಯಿಲà³à²²" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' ಅಮಾನà³à²¯à²µà²¾à²—ಿ ನà³à²£à³à²šà²¿à²•ೊಂಡ ಚಿಹà³à²¨à³†à²—ಳನà³à²¨à³ ಒಳಗೊಂಡಿದೆ" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "ಪಥದ ಹೆಸರೠ'%s' ಒಂದೠಪರಿಪೂರà³à²£à²µà²¾à²¦ ಪಥವಲà³à²²" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಅತಿಥೇಯದ ಹೆಸರà³" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "ಪೂರà³à²µà²¾à²¹à³à²¨" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "ಅಪರಾಹà³à²¨" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%A %d %b %Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%I:%M:%S %Z" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "ಜನವರಿ" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "ಫೆಬà³à²°à²µà²°à²¿" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "ಮಾರà³à²š" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "à²à²ªà³à²°à²¿à²²à³" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "ಮೇ" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "ಜೂನà³" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "ಜà³à²²à²¾à²¯à²¿" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "ಆಗಸà³à²Ÿà³â€" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "ಸಪà³à²Ÿà³†à²‚ಬರà³" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "ಅಕà³à²Ÿà³‹à²¬à²°à³" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "ನವೆಂಬರà³" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "ಡಿಸೆಂಬರà³" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ಜನ" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ಫೆಬà³à²°" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "ಮಾ" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à²" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "ಮೇ" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ಜೂ" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ಜà³" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ಆಗಸà³à²Ÿà³â€" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "ಸಪà³à²Ÿà³†à²‚" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "ಅಕà³à²Ÿà³Š" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ನವೆಂ" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ಡಿಸೆಂ" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "ಸೋಮವಾರ" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "ಮಂಗಳವಾರ" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "ಬà³à²§à²µà²¾à²°" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ಗà³à²°à³à²µà²¾à²°" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "ಶà³à²•à³à²°à²µà²¾à²°" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "ಶನಿವಾರ" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ರವಿವಾರ" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ಸೋ" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ಮಂ" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ಬà³" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ಗà³" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ಶà³" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ಶ" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ರ" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "ಕಡತ ಕೋಶ '%s' ವನà³à²¨à³ ತೆರೆಯà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "%lu ಬೈಟà³â€Œà²…ನà³à²¨à³, \"%s\" ಕಡತವನà³à²¨à³ ಓದà³à²µà²‚ತೆ ನಿಯೋಜಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" +msgstr[1] "%lu ಬೈಟà³â€Œà²—ಳನà³à²¨à³, \"%s\" ಕಡತವನà³à²¨à³ ಓದà³à²µà²‚ತೆ ನಿಯೋಜಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' ಕಡತವನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ದೋಷ: %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "ಕಡತ \"%s\" ವೠಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' ಕಡತದಿಂದ ಓದà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' ಅನà³à²¨à³ ತೆರೆಯಲೠವಿಫಲವಾಗಿದೆ: %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' ಕಡತದಿಂದ ಗà³à²£à²²à²•à³à²·à²£à²—ಳನà³à²¨à³ ಪಡೆಯà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: fstat() ವಿಫಲಗೊಂಡಿದೆ: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' ಕಡತವನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: fdopen() ವಿಫಲಗೊಂಡಿದೆ: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"'%s' ಕಡತವನà³à²¨à³ '%s' ಕà³à²•ೆ ಪà³à²¨à²°à³ ನಾಮಕರಣ ಮಾಡà³à²µà²²à³à²²à²¿: g_rename() ವಿಫಲಗೊಂಡಿದೆ: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' ಕಡತವನà³à²¨à³ ರಚಿಸà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "ಕಡತ '%s'ವನà³à²¨à³ ಬರೆಯà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: write() ವಿಫಲಗೊಂಡಿದೆ: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "ಕಡತ '%s'ವನà³à²¨à³ ಬರೆಯà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: fsync()) ವಿಫಲಗೊಂಡಿದೆ: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" +"ಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿à²°à³à²µ '%s' ಕಡತವನà³à²¨à³ ತೆಗೆದೠಹಾಕಲಾಗà³à²µà³à²¦à²¿à²²à³à²²: g_unlink() ವಿಫಲಗೊಂಡಿದೆ: " +"%s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "ಮಾದರಿ '%s' ಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ, ಅದೠಒಂದೠ'%s' ಅನà³à²¨à³ ಹೊಂದಿರà³à²µà²‚ತಿಲà³à²²" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "ಮಾದರಿ '%s' ಯೠXXXXXX ಅನà³à²¨à³ ಹೊಂದಿಲà³à²²" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "ಸಾಂಕೇತಿಕ ಲಿಂಕೠ'%s' ಅನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "ಸಾಂಕೇತಿಕ ಲಿಂಕà³à²—ಳೠಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' ನಿಂದ '%s' ಗೆ ಪರಿವರà³à²¤à²•ವನà³à²¨à³ ತೆರೆಯಲೠಆಗಿಲà³à²²: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string ನಲà³à²²à²¿ ಒಂದೠಹಗà³à²° ಓದನà³à²¨à³ ಮಾಡಲಾಗಲಿಲà³à²²" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "ಪರಿವರà³à²¤à²¿à²¤à²µà²¾à²—ದೆ ಬಾಕಿ ಉಳಿದ ದತà³à²¤à²¾à²‚ಶಗಳೠಓದà³-ಬಫರಿನಲà³à²²à²¿" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "ಮಾರà³à²—ವೠಒಂದೠಆಂಶಿಕ ಅಕà³à²·à²°à²¦à²²à³à²²à²¿ ಕೊನೆಗೊಳà³à²³à³à²¤à³à²¤à²¦à³†" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end ನಲà³à²²à²¿ ಒಂದೠಹಗà³à²° ಓದನà³à²¨à³ ಮಾಡಲಾಗಲಿಲà³à²²" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "ಹà³à²¡à³à²•ೠಕೋಶದಲà³à²²à²¿ ಮಾನà³à²¯ ಕೀಲಿ ಪತà³à²¤à³†à²¯à²¾à²—ಿಲà³à²²" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "ಒಂದೠಸಾಮಾನà³à²¯ ಕಡತವಲà³à²²" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"ಕೀಲಿ ಕಡತವೠ'%s' ಸಾಲನà³à²¨à³ ಹೊಂದಿದೆ, ಇದೠಒಂದೠಕೀಲಿ-ಮೌಲà³à²¯ ಜೋಡಿ, ಸಮೂಹ, ಅಥವ " +"ಹೇಳಿಕೆಯಲà³à²²" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "ಅಮಾನà³à²¯ ಸಮೂಹ ಹೆಸರà³: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "ಕೀಲಿ ಕಡತವೠಒಂದೠಸಮೂಹದೊಂದಿಗೆ ಆರಂಭಗೊಳà³à²³à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "ಅಮಾನà³à²¯ ಕೀಲಿ ಹೆಸರà³: %s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "ಕೀಲಿ ಕಡತವೠಬೆಂಬಲಿತವಲà³à²²à²¦ encoding '%s'ಅನà³à²¨à³ ಹೊಂದಿದೆ" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1703 ../glib/gkeyfile.c:3081 +#: ../glib/gkeyfile.c:3144 ../glib/gkeyfile.c:3270 ../glib/gkeyfile.c:3400 +#: ../glib/gkeyfile.c:3542 ../glib/gkeyfile.c:3771 ../glib/gkeyfile.c:3838 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "ಕೀಲಿ ಕಡತವೠಸಮೂಹ '%s'ವನà³à²¨à³ ಹೊಂದಿಲà³à²²" + +#: ../glib/gkeyfile.c:1658 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "ಕೀಲಿ ಕಡತವೠಕೀಲಿ'%s' ಯನà³à²¨à³ ಗà³à²‚ಪೠ'%s'ನಲà³à²²à²¿ ಹೊಂದಿಲà³à²²" + +#: ../glib/gkeyfile.c:1820 ../glib/gkeyfile.c:1936 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"ಕೀಲಿ ಕಡತವೠಕೀಲಿ '%s'ಯನà³à²¨à³ ಹೊಂದಿದà³à²¦à³ ಅದೠUTF-8 ಅಲà³à²²à²¦ ಮೌಲà³à²¯à²µà²¾à²¦ '%s'ವನà³à²¨à³ " +"ಹೊಂದಿದೆ " + +#: ../glib/gkeyfile.c:1840 ../glib/gkeyfile.c:1956 ../glib/gkeyfile.c:2325 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "ಕೀಲಿ ಕಡತವೠವಿವರಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ದೆ ಇರà³à²µà²‚ತಹ ಕೀಲಿ '%s'ಯ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಹೊಂದಿದೆ." + +#: ../glib/gkeyfile.c:2542 ../glib/gkeyfile.c:2910 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"ಕೀಲಿ ಕಡತವೠಕೀಲಿ '%s' ಅನà³à²¨à³ ಹೊಂದಿದà³à²¦à³, ಅದೠಸಮೂಹ '%s'ದà³à²¦à²¾à²—ಿದೆ ಹಾಗೂ ಅದರ " +"ಮೌಲà³à²¯à²µà²¨à³à²¨à³ " +"ವಿವರಿಸಲಾಗà³à²µà³à²¦à²¿à²²à³à²²." + +#: ../glib/gkeyfile.c:2620 ../glib/gkeyfile.c:2697 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" +"'%s' ಕೀಲಿಯೠ'%s' ಸಮೂಹದಲà³à²²à²¿à²¦à³†, '%s' ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಹೊಂದಿದೆ ಆದರೆ '%s' ಅನà³à²¨à³ " +"ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿದೆ" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "ಕೀಲಿ ಕಡತವೠಸಾಲಿನ ಕೊನೆಯಲà³à²²à²¿ ಪಾರೠಅಕà³à²·à²°à²—ಳನà³à²¨à³ ಹೊಂದಿದೆ" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "ಕೀಲಿ ಕಡತವೠಅಮಾನà³à²¯ ಪಾರೠಅನà³à²•à³à²°à²®à²µà²¨à³à²¨à³ ಹೊಂದಿದೆ '%s'" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "ಮೌಲà³à²¯ '%s' ವನà³à²¨à³ ಒಂದೠಸಂಖà³à²¯à³†à²¯à²¾à²—ಿ ಸೂಚಿಸಲೠಆಗà³à²µà³à²¦à²¿à²²à³à²²." + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "ಪೂರà³à²£à²¾à²‚ಕ ಮೌಲà³à²¯ '%s' ವೠವà³à²¯à²¾à²ªà³à²¤à²¿à²¯à²¨à³à²¨à³ ಮೀರಿದೆ" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "ಮೌಲà³à²¯ '%s' ವನà³à²¨à³ ಒಂದೠತೇಲೠಸಂಖà³à²¯à³† ಆಗಿ ವಿವರಿಸಲೠಆಗà³à²µà³à²¦à²¿à²²à³à²²." + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "ಮೌಲà³à²¯ '%s' ವನà³à²¨à³ ಒಂದೠಬೂಲಿಯನೠಆಗಿ ವಿವರಿಸಲೠಆಗà³à²µà³à²¦à²¿à²²à³à²²." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "" +"'%s%s%s%s' ಕಡತದಿಂದ ಗà³à²£à²²à²•à³à²·à²£à²—ಳನà³à²¨à³ ಪಡೆಯà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: fstat() ವಿಫಲಗೊಂಡಿದೆ: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s ಮಾಡà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ: mmap() ವಿಫಲಗೊಂಡಿದೆ: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "ಕಡತ '%s' ವನà³à²¨à³ ತೆರೆಯಲೠವಿಫಲವಾಗಿದೆ: ತೆರೆಯà³à²µà³à²¦à³() ವಿಫಲಗೊಂಡಿದೆ: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "%d ಸಾಲಿನ %d ಚಿಹà³à²¨à³†à²¯à²²à³à²²à²¿ ದೋಷ: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "ಹೆಸರಿನಲà³à²²à²¿ ಅಮಾನà³à²¯ UTF-8 ಎನà³à²•ೋಡೠಆದ ಪಠà³à²¯à²µà²¿à²¦à³† - ಮಾನà³à²¯à²µà²¾à²¦ '%s' ಅಲà³à²²" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' ಎನà³à²¨à³à²µà³à²¦à³ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ ಹೆಸರಾಗಿಲà³à²²" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' ಎನà³à²¨à³à²µà³à²¦à³ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ ಕಡತದ ಹೆಸರಾಗಿಲà³à²²: '%c'" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d ಸಾಲಿನಲà³à²²à²¿ ದೋಷ: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' ಅನà³à²¨à³ parse ಮಾಡà³à²µà²²à³à²²à²¿ ವಿಫಲ, ಇದೠಒಂದೠಉಲà³à²²à³‡à²– ಅಕà³à²·à²°à²¦ ಒಳಗಿನ ಒಂದೠ" +"ಅಂಕಿಯಾಗಿರಬೇಕಿತà³à²¤à³(ê ಉದಾಹರಣೆಗೆ) - ಬಹà³à²·à²ƒ ಅಂಕಿಯೠಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿರಬೇಕà³" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"ಅಕà³à²·à²° ಉಲà³à²²à³‡à²–ವೠಒಂದೠಅರà³à²§à²µà²¿à²°à²¾à²® ಚಿಹà³à²¨à³†à²¯à²¿à²‚ದ ಕೊನೆಗೊಂಡಿಲà³à²²; ಹೆಚà³à²šà²¿à²¨ ಪಕà³à²· ನೀವೠಒಂದೠ" +"ಘಟಕವನà³à²¨à³ ಆರಂಭಿಸà³à²µ ಉದà³à²¦à³‡à²¶à²µà²¿à²²à³à²²à²¦à³‡ ampersand ಅಕà³à²·à²°à²µà²¨à³à²¨à³ ಬಳಸಿದà³à²¦à³€à²°à²¿ - ampersand " +"ನಿಂದ " +"ಹೊರಬರಲೠ& ಎಂದೠಮಾಡಿ" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "ಅಕà³à²·à²° ಉಲà³à²²à³‡à²– '%-.*s' ವೠಒಂದೠಅನà³à²®à²¤à²¿ ಇರà³à²µ ಅಕà³à²·à²°à²µà²¨à³à²¨à³ encode ಮಾಡà³à²µà³à²¦à²¿à²²à³à²²" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"ಖಾಲಿ ಘಟಕ '&;' ಕಂಡೠಬಂದಿದೆ; ಮಾನà³à²¯ ನಮೂದà³à²—ಳೆಂದರೆ: & " < > '" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "ನಮೂದಿನ ಹೆಸರೠ'%-.*s' ತಿಳಿದಿಲà³à²²" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"ಘಟಕವೠಒಂದೠಅರà³à²§à²µà²¿à²°à²¾à²® ಚಿಹà³à²¨à³†à²¯à²¿à²‚ದ ಕೊನೆಗೊಂಡಿಲà³à²²; ಹೆಚà³à²šà²¿à²¨ ಪಕà³à²· ನೀವೠಒಂದೠಘಟಕವನà³à²¨à³ " +"ಆರಂಭಿಸà³à²µ ಉದà³à²¦à³‡à²¶à²µà²¿à²²à³à²²à²¦à³‡ ampersand ಅಕà³à²·à²°à²µà²¨à³à²¨à³ ಬಳಸಿದà³à²¦à³€à²°à²¿ - ampersand ನಿಂದ " +"ಹೊರಬರಲೠ" +"& ಎಂದೠಮಾಡಿ" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "ದಸà³à²¤à²¾à²µà³‡à²œà³à²—ಳೠಒಂದೠಅಂಶದಿಂದ ಆರಂಭಗೊಳà³à²³à²¬à³‡à²•à³ (e.g. )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'<' ಅಕà³à²·à²°à²µà³ ಬಂದ ನಂತರ, '%s' ವೠಒಂದೠಮಾನà³à²¯à²µà²²à³à²²à²¦ ಅಕà³à²·à²°à²µà²¾à²—ಿದೆ; ಅದೠಒಂದೠಅಂಶದ " +"ಹೆಸರನà³à²¨à³ " +"ಆರಂಭಿಸದೇ ಇರಬಹà³à²¦à³" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"ಸರಿಯಲà³à²²à²¦ ಅಕà³à²·à²° '%s', '%s' ಖಾಲಿ ಅಂಶದ ಟà³à²¯à²¾à²—ಿನ ಆರಂಭವೠಒಂದೠ'>' ಅಕà³à²·à²°à²¦à²¿à²‚ದ " +"ಕೊನೆಗೊಳà³à²³à²¬à³‡à²•ೠಎಂದೠಅಪೇಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"ಸರಿಯಲà³à²²à²¦ ಅಕà³à²·à²° '%s', '%s'ವೠ'%s' ಅಂಶದ ಗà³à²£à²²à²•à³à²·à²£ ಹೆಸರಾಗಿದà³à²¦à³ ಅದರ ನಂತರ ಒಂದೠ'=' " +"ಅನà³à²¨à³ ಅಪೇಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ಸರಿಯಲà³à²²à²¦ ಅಕà³à²·à²° '%s', '%s' ಅಂಶದ ಟà³à²¯à²¾à²—ಿನ ಆರಂಭವೠಒಂದೠ'>' ಅಥವ '/' ಅಕà³à²·à²°à²¦à²¿à²‚ದ " +"ಕೊನೆಗೊಳà³à²³à²¬à³‡à²•ೠಎಂದೠಅಪೇಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³, ಅಥವ ಆಯà³à²•ಾತà³à²®à²•ವಾಗಿ ಒಂದೠಗà³à²£à²²à²•à³à²·à²£; ಬಹà³à²·à²ƒ " +"ನೀವೠ" +"ಅಮಾನà³à²¯ ಅಕà³à²·à²°à²µà²¨à³à²¨à³ ಒಂದೠಗà³à²£à²²à²•à³à²·à²£à²¦ ಹೆಸರಿನಲà³à²²à²¿ ಬಳಸಿದà³à²¦à³€à²°à³†à²‚ದೠತೋರà³à²¤à³à²¤à²¦à³†" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"ಸರಿಯಲà³à²²à²¦ ಅಕà³à²·à²° '%s', ಗà³à²£à²²à²•à³à²·à²£ '%s'ವೠ'%s' ದ ಅಂಶವಾಗಿದà³à²¦à³, ಇದಕà³à²•ೆ ಒಂದೠ" +"ಮೌಲà³à²¯à²µà²¨à³à²¨à³ " +"ಕೊಡà³à²µà²¾à²— ಸಮ ಚಿಹà³à²¨à³†à²¯ ನಂತರ ಒಂದೠಮà³à²•à³à²¤ ಉದà³à²§à²°à²£ ಚಿಹà³à²¨à³†à²¯à²¨à³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' ವೠಮà³à²šà³à²šà²²à³à²ªà²Ÿà³à²Ÿ ಅಂಶ ಹೆಸರೠ'%s' ನಂತರ ಬರà³à²µ ಒಂದೠಮಾನà³à²¯à²µà²¾à²¦ ಅಕà³à²·à²°à²µà²²à³à²²; '>' ವೠ" +"ಅನà³à²®à²¤à²¿ ಇರà³à²µ ಅಕà³à²·à²°à²µà²¾à²—ಿರà³à²¤à³à²¤à²¦à³†" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "ಅಂಶವೠ'%s' was closed, no element is currently open" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"ಅಂಶ '%s' ವೠಮà³à²šà³à²šà²²à³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†, ಆದರೆ ಪà³à²°à²¸à³à²¤à³à²¤ ಮà³à²•à³à²¤à²µà²¾à²—ಿರà³à²µ ಅಂಶವೆಂದರೆ '%s' ಆಗಿದೆ" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "ದಸà³à²¤à²¾à²µà³‡à²œà³ ಖಾಲಿಯಾಗಿತà³à²¤à³ ಅಥವ ಕೇವಲ ಕೇವಲ ಖಾಲಿ ಜಾಗಗಳನà³à²¨à³ ಹೊಂದಿತà³à²¤à³" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"ದಸà³à²¤à²¾à²µà³‡à²œà³ ಒಂದೠಮà³à²•à³à²¤ ಕೋನ ಆವರಣ ಚಿಹà³à²¨à³† '<' ಯ ನಂತರ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"ಅಂಶಗಳೠತೆರೆದಿರà³à²µà²¾à²—ಲೇ ದಸà³à²¤à²¾à²µà³‡à²œà³ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ - '%s' ಯೠ" +"ತೆರೆಯಲà³à²ªà²Ÿà³à²Ÿ " +"ಕೊನೆಯ ಅಂಶ" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ದಸà³à²¤à²¾à²µà³‡à²œà³ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ, <%s/> ಟà³à²¯à²¾à²—ಿನ ಕೊನೆಯಲà³à²²à²¿ ಒಂದೠಮà³à²•à³à²¤ ಕೋನ " +"ಆವರಣ " +"ಚಿಹà³à²¨à³†à²¯à²¨à³à²¨à³ ಕಾಣಲೠಅಪೇಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "ದಸà³à²¤à²¾à²µà³‡à²œà³ ಒಂದೠಅಂಶದ ಹೆಸರಿನಲà³à²²à²¿ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "ದಸà³à²¤à²¾à²µà³‡à²œà³ ಒಂದೠಗà³à²£à²²à²•à³à²·à²£ ಹೆಸರಿನಲà³à²²à²¿ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ದಸà³à²¤à²¾à²µà³‡à²œà³ ಒಂದೠಅಂಶ ತೆರೆಯà³à²µ ಟà³à²¯à²¾à²—ಿನ ಒಳಗೆ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ." + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"ದಸà³à²¤à²¾à²µà³‡à²œà³ ಒಂದೠಗà³à²£à²²à²•à³à²·à²£à²¦ ಹೆಸರಿನ ನಂತರದ ಸಮ ಚಿಹà³à²¨à³†à²¯ ನಂತರ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ " +"ಕೊನೆಗೊಂಡಿದೆ; ಯಾವà³à²¦à³‡ ಗà³à²£à²²à²•à³à²·à²£ ಮೌಲà³à²¯à²µà²¿à²²à³à²²" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ದಸà³à²¤à²¾à²µà³‡à²œà³ ಒಂದೠಗà³à²£à²²à²•à³à²·à²£ ಮೌಲà³à²¯à²¦ ಒಳಗಿರà³à²µà²¾à²— ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"ದಸà³à²¤à²¾à²µà³‡à²œà³ ಒಂದೠಅಂಶ'%s'ದ ಮà³à²šà³à²šà²²à³à²ªà²Ÿà³à²Ÿ ಟà³à²¯à²¾à²—ಿನ ಒಳಗೆ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"ದಸà³à²¤à²¾à²µà³‡à²œà³ ಒಂದೠಹೇಳಿಕೆ ಅಥವ ಪà³à²°à²•à³à²°à²¿à²¯à³† ಸೂಚನೆಯ ಒಳಗೆ ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಕೊನೆಗೊಂಡಿದೆ" + +#: ../glib/goption.c:855 +msgid "Usage:" +msgstr "ಬಳಕೆ:" + +#: ../glib/goption.c:855 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:971 +msgid "Help Options:" +msgstr "ಸಹಾಯ ಆಯà³à²•ೆಗಳà³:" + +#: ../glib/goption.c:972 +msgid "Show help options" +msgstr "ಸಹಾಯ ಆಯà³à²•ೆಯನà³à²¨à³ ತೋರಿಸà³" + +#: ../glib/goption.c:978 +msgid "Show all help options" +msgstr "ಎಲà³à²²à²¾ ಸಹಾಯ ಅಂಶಪಟà³à²Ÿà²¿à²¯à²¨à³à²¨à³ ತೋರಿಸà³" + +#: ../glib/goption.c:1040 +msgid "Application Options:" +msgstr "ಅನà³à²µà²¯à²¦ ಆಯà³à²•ೆಗಳà³:" + +#: ../glib/goption.c:1104 ../glib/goption.c:1174 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr " for %s ಕà³à²•ಾಗಿನ ಪೂರà³à²£à²¾à²‚ಕ ಮೌಲà³à²¯ '%s' ಅನà³à²¨à³ ಶಬà³à²§à²²à²•à³à²·à²£ ಹೇಳಲಾಗಿಲà³à²²" + +#: ../glib/goption.c:1114 ../glib/goption.c:1182 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%s ಕà³à²•ಾಗಿನ ಪೂರà³à²£à²¾à²‚ಕ ಮೌಲà³à²¯ '%s' ವೠವà³à²¯à²¾à²ªà³à²¤à²¿à²¯à²¿à²‚ದ ಹೊರಗಿದೆ" + +#: ../glib/goption.c:1139 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "'%s' ದ %s ಕà³à²•ಾಗಿನ ದà³à²µà²¿à²®à³Œà²²à³à²¯à²µà²¨à³à²¨à³ parse ಮಾಡಲಾಗಿಲà³à²²" + +#: ../glib/goption.c:1147 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "%s ಕà³à²•ಾಗಿನ '%s' ದà³à²µà²¿ ಮೌಲà³à²¯à²µà³ ವà³à²¯à²¾à²ªà³à²¤à²¿à²¯à²¿à²‚ದ ಹೊರಗಿದೆ" + +#: ../glib/goption.c:1433 ../glib/goption.c:1512 +#, c-format +msgid "Error parsing option %s" +msgstr "%s ಆಯà³à²•ೆಯ ಶಬà³à²§à²²à²•à³à²·à²£à²µà²¨à³à²¨à³ ಹೇಳà³à²µà²¾à²— ದೋಷ" + +#: ../glib/goption.c:1543 ../glib/goption.c:1656 +#, c-format +msgid "Missing argument for %s" +msgstr "%s ಗೆ ಆರà³à²—à³à²¯à³à²®à³†à²‚ಟೠಕಾಣà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../glib/goption.c:2117 +#, c-format +msgid "Unknown option %s" +msgstr "ಗೊತà³à²¤à²¿à²°à²¦ ಆಯà³à²•ೆ %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "ಭà³à²°à²·à³à²Ÿà²—ೊಂಡ ವಸà³à²¤à³" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "ಆಂತರಿಕ ದೋಷ ಅಥವ ಭà³à²°à²·à³à²Ÿà²—ೊಂಡ ವಸà³à²¤à³" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "ಮೆಮೊರಿ ಖಾಲಿಯಾಗಿದೆ" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "ಹಿಂಬಾಲಿಸà³à²µ ಮಿತಿ ತಲà³à²ªà²¿à²¦à³†" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "ಆಂಶಿಕ ಹೊಂದಾಣಿಕೆಗೆ ಬೆಂಬಲಿತವಾಗದ ಅಂಶಗಳನà³à²¨à³ ಈ ವಿನà³à²¯à²¾à²¸à²µà³ ಹೊಂದಿದೆ" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"ಆಂಶಿಕ ತಾಳೆಗೆ ಪರಿಸà³à²¥à²¿à²¤à²¿à²¯à³ ಬೆಂಬಲಿತವಾಗಿಲà³à²² ಆದà³à²¦à²°à²¿à²‚ದ ಹಿಂಬದಿಯ ಉಲà³à²²à³‡à²–ಗಳನà³à²¨à³ " +"ಬಳಸಲಾಗà³à²µà³à²¦à³" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "ರಿಕರà³à²¶à²¨à³ ಮಿತಿಯನà³à²¨à³ ತಲà³à²ªà²¿à²¦à³†" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "ಹೊಸಸಾಲೠಗà³à²°à³à²¤à³à²—ಳ ಅಮಾನà³à²¯ ಸಂಯೋಜನೆ" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "ತಪà³à²ªà³ ಆಫà³â€Œà²¸à³†à²Ÿà³â€Œ" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "ಚಿಕà³à²• utf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "ಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¿à²¤ ಕà³à²£à²¿à²•ೆ" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "ಗೊತà³à²¤à²¿à²°à²¦ ದೋಷ" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ ನಮೂನೆಯ ಕೊನೆಯಲà³à²²à²¿" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c ನಮೂನೆಯ ಕೊನೆಯಲà³à²²à²¿" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "ಗà³à²°à³à²¤à²¿à²¸à²²à²¾à²—ದ ಅಕà³à²·à²°à²—ಳೠಕಂಡà³à²¬à²°à³à²¤à³à²¤à²µà³† \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} ಕà³à²µà²¾à²‚ಟಿಫೈರಿನಲà³à²²à²¿ ಸಂಖà³à²¯à³†à²—ಳೠಕà³à²°à²®à²¦à²²à³à²²à²¿ ಇಲà³à²²" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} ಕà³à²µà²¾à²‚ಟಿಫಯರಿನಲà³à²²à²¿à²¨ ಸಂಖà³à²¯à³†à²¯à³ ಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "ಕà³à²¯à²¾à²°à³†à²•à³à²Ÿà²°à³ ವರà³à²—ವೠಕೊನೆಗೊಳà³à²³à²¬à³‡à²•ಿದà³à²¦ ] ಕಾಣೆಯಾಗಿದೆ" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "ಕà³à²¯à²¾à²°à³†à²•à³à²Ÿà²°à³ ವರà³à²—ದಲà³à²²à²¿à²¨ ಪಾರೠಅನà³à²•à³à²°à²®à²µà³ ಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "ಕà³à²¯à²¾à²°à³†à²•à³à²Ÿà²°à³ ವರà³à²—ದಲà³à²²à²¿ ವà³à²¯à²¾à²ªà³à²¤à²¿à²¯à³ ಕೆಲಸ ಮಾಡà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "ಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¿à²¸à²²à³ à²à²¨à³‚ ಇಲà³à²²" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "ಅನಿರೀಕà³à²·à²¿à²¤ ಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¨à³†" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? ಅಥವ (?- ನ ನಂತರ ಗà³à²°à³à²¤à²¿à²¸à²²à²¾à²—ದ ಅಕà³à²·à²°" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX ಹೆಸರಿಸಲಾದ ವರà³à²—ಗಳೠಕೇವಲ ಒಂದೠವರà³à²—ದಲà³à²²à²¿ ಮಾತà³à²° ಬೆಂಬಲ ಹೊಂದಿರà³à²¤à³à²¤à²µà³†" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "ಕೊನೆಗೊಳಿಸà³à²µ ) ಕಾಣೆಯಾಗಿದೆ" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "ಅಸà³à²¤à²¿à²¤à³à²µà²¦à²²à³à²²à²¿ ಇರದ ಉಪವಿನà³à²¯à²¾à²¸à²¦ ಉಲà³à²²à³‡à²–" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "ಕಮೆಂಟà³â€à²¨ ನಂತರ ) ವೠಕಾಣೆಯಾಗಿದೆ" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "ಸಾಧಾರಣ ಗಣಿತೋಕà³à²¤à²¿à²¯à³ ಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "ಮೆಮೊರಿಯನà³à²¨à³ ಪಡೆದà³à²•ೊಳà³à²³à²²à³ ವಿಫಲವಾಗಿದೆ" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") ತೆರೆಯಲà³à²ªà²¡à²¦à³† (" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "ಕೋಡೠಓವರà³-ಫà³à²²à³‹" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "(?< ಯ ನಂತರ ಗà³à²°à³à²¤à²¿à²¸à²²à²¾à²—ದ ಅಕà³à²·à²°" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "ಹಿಂದೆನೋಡೠಪà³à²°à²¤à²¿à²ªà²¾à²¦à²¨à³†à²¯à³ ನಿಗದಿತ ಉದà³à²¦à²µà²¨à³à²¨à³ ಹೊಂದಿಲà³à²²" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "(?( ನಂತರದ ಸಂಖà³à²¯à³† ಅಥವ ಹೆಸರೠವಿರೂಪಗೊಂಡಿದೆ" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "ಶರತà³à²¤à²¿à²¨ ಸಮೂಹವೠಎರಡಕà³à²•ಿಂತ ಹೆಚà³à²šà²¿à²¨ ಶಾಖೆಗಳನà³à²¨à³ ಹೊಂದಿದೆ" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "(?( ನಂತರ ಪà³à²°à²¤à²¿à²ªà²¾à²¦à²¨à³†à²¯à²¨à³à²¨à³ ನಿರೀಕà³à²·à²¿à²¸à²²à²¾à²—ಿತà³à²¤à³" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ಅಥವ (?[+-] ಡಿಜಿಟà³â€à²—ಳೠ) ಅನà³à²¨à³ ಅನà³à²¸à²°à²¿à²¸à²¬à³‡à²•à³" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "ಗೊತà³à²¤à²¿à²°à²¦ POSIX ವರà³à²—ದ ಹೆಸರà³" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "ಘಟಕಗಳ POSIX ಹೋಲಿಕೆಯೠಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} ಅನà³à²•à³à²°à²®à²¦à²²à³à²²à²¿à²¨ ಅಕà³à²·à²° ಮೌಲà³à²¯à²µà³ ಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "ಸರಿಯಲà³à²²à²¦ (?(0) ಸà³à²¥à²¿à²¤à²¿" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "ಹಿಂದೆನೋಡೠಪà³à²°à²¤à²¿à²ªà²¾à²¦à²¨à³†à²¯à²²à³à²²à²¿ \\C ಗೆ ಅನà³à²®à²¤à²¿ ಇಲà³à²²" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "\\L, \\l, \\N{name}, \\U, ಮತà³à²¤à³ \\u ಎಸà³à²•ೇಪà³â€Œà²—ಳಿಗೆ ಬೆಂಬಲವಿಲà³à²²" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "ಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¿à²¤ ಕರೆಯೠಅನಿರà³à²¦à²¿à²·à³à²Ÿà²µà²¾à²—ಿ ಆವರà³à²¤à²¿à²¤à²—ೊಳà³à²³à²¬à²¹à³à²¦à³" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "(?P ಯ ನಂತರ ಗà³à²°à³à²¤à²¿à²¸à²²à²¾à²—ದ ಅಕà³à²·à²°" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "ಉಪನಮೂನೆಯ ಹೆಸರಿನಲà³à²²à²¿ ಟರà³à²®à²¿à²¨à³‡à²Ÿà²°à³ ಕಾಣಿಸà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "ಹೆಸರಿಸಲಾದ ಎರಡೠಉಪನಮೂನೆಗಳೠಒಂದೇ ಹೆಸರನà³à²¨à³ ಹೊಂದಿವೆ" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "ವಿರೂಪಗೊಂಡ\\P ಅಥವ \\p ಅನà³à²•à³à²°à²®" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "\\P ಅಥವ \\p ಯ ನಂತರ ಗೊತà³à²¤à²¿à²°à²¦ ಗà³à²£à²²à²•à³à²·à²£à²¦ ಹೆಸರà³" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ಉಪನಮೂನೆಯ ಹೆಸರೠಬಹಳ ಉದà³à²¦à²µà²¾à²—ಿದೆ (ಗರಿಷà³à²Ÿ 32 ಅಕà³à²·à²°à²—ಳನà³à²¨à³ ಹೊಂದಿರಬಹà³à²¦à³)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ಬಹಳಷà³à²Ÿà³ ಹೆಸರಿಸಲà³à²ªà²Ÿà³à²Ÿ ಉಪನಮೂನೆಗಳೠ(ಗರಿಷà³à²Ÿ 10,000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "\\377 ಕà³à²•ೂ ದೊಡà³à²¡à²¦à²¾à²¦ ಆಕà³à²Ÿà²²à³ ಮೌಲà³à²¯" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "ಸಂಕಲಿಸà³à²µ ಕಾರà³à²¯à²•à³à²·à³‡à²¤à³à²°à²µà³ overran ಆಗಿದೆ" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "ಈ ಮೊದಲೠಪರೀಕà³à²·à²¿à²¸à²²à²¾à²¦ ಉಲà³à²²à³‡à²– ಉಪವಿನà³à²¯à²¾à²¸ ಕಂಡà³à²¬à²‚ದಿಲà³à²²" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "ಒಂದಕà³à²•ಿಂತ ಹೆಚà³à²šà²¿à²¨ ಶಾಖೆಯನà³à²¨à³ ಹೊಂದಿರà³à²µ ಸಮೂಹವನà³à²¨à³ DEFINE ಮಾಡà³" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "ಅಸಂಜಸವಾದ NEWLINE ಆಯà³à²•ೆಗಳà³" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ದ ನಂತರ ಒಂದೠಬà³à²°à³‡à²¸à³ ಆದ, ಆಂಗಲà³-ಬà³à²°à²¾à²•ೆಟೆಡà³, ಅಥವ ಕೋಟೠಮಾಡಲಾದ ಹೆಸರೠಅಥವ " +"ಸಂಖà³à²¯à³†, ಅಥವ " +"ಒಂದೠಸರಳವಾದ ಸಂಖà³à²¯à³†à²¯à³ ಇಲà³à²²" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "ಒಂದೠಸಂಖà³à²¯à³†à²¯ ಉಲà³à²²à³‡à²–ವೠಶೂನà³à²¯à²µà²¾à²—ಿರಬಾರದà³" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" +"(*ACCEPT), (*FAIL), ಅಥವ (*COMMIT) ಗಾಗಿ ಒಂದೠಆರà³à²—à³à²¯à³à²®à³†à²‚ಟà³â€Œà²—ೆ ಅನà³à²®à²¤à²¿ ಇಲà³à²²" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ಗà³à²°à³à²¤à²¿à²¸à²²à²¾à²—ಿಲà³à²²" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "ಸಂಖà³à²¯à³†à²¯à³ ಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& ನಂತರ ಉಪನಮೂನೆಯ ಹೆಸರೠಕಾಣಿಸà³à²¤à³à²¤à²¿à²²à³à²²" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ ನಂತರ ನಿರೀಕà³à²·à²¿à²¸à²¿à²²à²¾à²¦ ಅಂಕಿ" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] ಎನà³à²¨à³à²µà³à²¦à³ JavaScript ಸಹವರà³à²¤à²¨à³€à²¯ ಕà³à²°à²®à²¦à²²à³à²²à²¿ ಒಂದೠಅಮಾನà³à²¯à²µà²¾à²¦ ದತà³à²¤à²¾à²‚ಶ ಅಕà³à²·à²°" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ಒಂದೆ ಸಂಖà³à²¯à³†à²¯ ಉಪನಮೂನೆಗಳಿಗಾಗಿ ಭಿನà³à²¨à²µà²¾à²¦ ಹೆಸರನà³à²¨à³ ಬಳಸಲೠಅನà³à²®à²¤à²¿ ಇಲà³à²²" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) ಒಂದೠಆರà³à²—à³à²¯à³à²®à³†à²‚ಟೠಅನà³à²¨à³ ಹೊಂದಿರಬೇಕà³" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c ನಂತರ ಒಂದೠASCII ಅಕà³à²·à²°à²µà²¿à²°à²¬à³‡à²•à³" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k ಯೠಒಂದೠಬà³à²°à³‡à²¸à³ ಆದ ಅಥವ ಆಯà³à²•ಾತà³à²®à²•-ಬà³à²°à²¾à²•ೆಟೆಡೠಆದ, ಅಥವ ಕೋಡà³â€Œ ಮಾಡಲಾದ ಹೆಸರನà³à²¨à³ " +"ಅನà³à²¸à²°à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N ಈ ವರà³à²—ದಲà³à²²à²¿ ಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "ಬಹಳಷà³à²Ÿà³ ಮà³à²‚ದಿನ ಉಲà³à²²à³‡à²–ಗಳà³" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), ಅಥವ (*THEN) ದಲà³à²²à²¿à²¨ ಹೆಸರೠಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... ಅನà³à²•à³à²°à²®à²¦à²²à³à²²à²¿à²¨ ಅಕà³à²·à²° ಮೌಲà³à²¯à²µà³ ಬಹಳ ದೊಡà³à²¡à²¦à²¾à²—ಿದೆ" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "ಸಾಮಾನà³à²¯ ನಿರೂಪಣೆಯ %s ಅನà³à²¨à³ ಹೊಂದಾಣಿಸà³à²µà²²à³à²²à²¿ ದೋಷ ಕಂಡà³à²¬à²‚ದಿದೆ: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "UTF8 ಬೆಂಬಲವಿಲà³à²²à²¦à³† PCRE ಭಂಡಾರವೠಸಂಕಲಿತಗೊಂಡಿದೆ" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "UTF8 ಗà³à²£à²²à²•à³à²·à²£à²—ಳ ಬೆಂಬಲವಿಲà³à²²à²¦à³† PCRE ಭಂಡಾರವೠಸಂಕಲಿತಗೊಂಡಿದೆ" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE ಲೈಬà³à²°à²°à²¿à²¯à²¨à³à²¨à³ ಹೊಂದಿಕೆಯಾಗದ ಆಯà³à²•ೆಗಳೊಂದಿಗೆ ಕಂಪೈಲೠಮಾಡಲà³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"ಸಾಮಾನà³à²¯ ನಿರೂಪಣೆಯ %s ಅನà³à²¨à³ char %d ನಲà³à²²à²¿ ಸಂಕಲಿಸà³à²µà²²à³à²²à²¿ ದೋಷ ಕಂಡà³à²¬à²‚ದಿದೆ: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "ಸಾಮಾನà³à²¯ ನಿರೂಪಣೆಯ %s ಅನà³à²¨à³ ಸರಳೀಕರಿಸà³à²µà²²à³à²²à²¿ ದೋಷ ಕಂಡà³à²¬à²‚ದಿದೆ: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "ಷೋಡ-ದಶಮಾನ ಅಂಕಿ ಅಥವ '}' ಅನà³à²¨à³ ಅಪೇಕà³à²·à²¿à²¸à²²à²¾à²—ಿದೆ" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "ಷೋಡ-ದಶಮಾನ ಅಂಕಿಯನà³à²¨à³ ಅಪೇಕà³à²·à²¿à²¸à²²à²¾à²—ಿದೆ" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "ಸಾಂಕೇತಿಕ ಉಲà³à²²à³‡à²–ದಲà³à²²à²¿ '<' ಕಾಣೆಯಾಗಿದೆ" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "ಅಪೂರà³à²£à²—ೊಂಡಿರà³à²µ ಸಾಂಕೇತಿಕ ಉಲà³à²²à³‡à²–" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "ಶೂನà³à²¯-ಉದà³à²¦à²¦ ಸಾಂಕೇತಿಕ ಉಲà³à²²à³‡à²–" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "ಅಪೇಕà³à²·à²¿à²¤ ಅಂಕಿ" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "ನಿಯಮ ಬಾಹಿರವಾದ ಸಾಂಕೇತಿಕ ಉಲà³à²²à³‡à²–" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "ಅಪರೂಪದ ಅಂತà³à²¯ '\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "ಗೊತà³à²¤à²¿à²°à²¦ ಪಾರೠಅನà³à²•à³à²°à²®" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" +"ಬದಲಾಯಿಸಲà³à²ªà²Ÿà³à²Ÿ ಪಠà³à²¯ \"%s\"ಅನà³à²¨à³ char %lu ನಲà³à²²à²¿ ಪಾರà³à²¸à²¿à²‚ಗೠಮಾಡà³à²µà²¾à²—ಿನ ದೋಷ: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "ಉದà³à²§à²°à²¿à²¤ ಪಠà³à²¯à²µà³ ಒಂದೠಉದà³à²§à²°à²¨ ಚಿಹà³à²¨à³†à²¯à²¿à²‚ದ ಆರಂಭಗೊಳà³à²³à³à²µà³à²¦à²¿à²²à³à²²" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"ಆಜà³à²žà²¾ ಸಾಲಿನಲà³à²²à²¿ ಅಥವ ಇತರೆ ಶೆಲà³à²²à²¿à²¨à²²à³à²²à²¿ ಉದà³à²§à²°à²¿à²¸à²²à²¾à²¦ ಪಠà³à²¯à²¦à²²à³à²²à²¿ ತಾಳೆಯಾಗದ " +"ಉದà³à²§à²°à²£à²šà²¿à²¹à³à²¨à³†à²—ಳà³" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "ಪಠà³à²¯à²µà³ ಒಂದೠ'\\' ಅಕà³à²·à²°à²¦ ನಂತರ ಅಂತà³à²¯à²—ೊಂಡಿತà³. (ಪಠà³à²¯à²µà³ '%s' ಆಗಿತà³à²¤à³)" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "%c ಗಾಗಿನ (ಪಠà³à²¯à²µà³ '%s' ಆಗಿತà³à²¤à³)" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "ಪಠà³à²¯à²µà³ ಖಾಲಿಯಾಗಿತà³à²¤à³ (ಅಥವ ಕೇವಲ ಖಾಲಿಜಾಗಗಳನà³à²¨à³ ಹೊಂದಿತà³à²¤à³)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "child ಪà³à²°à²•à³à²°à²¿à²¯à³† (%s) ಯಿಂದ ದತà³à²¤à²¾à²‚ಶವನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ವಿಫಲ" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"child ಪà³à²°à²•à³à²°à²¿à²¯à³† (%s) ಯಿಂದ ದತà³à²¤à²¾à²‚ಶವನà³à²¨à³ ಓದà³à²µà²¾à²— select() ನಲà³à²²à²¿ ಅನಪೇಕà³à²·à²¿à²¤ ದೋಷ" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() ನಲà³à²²à²¿ ಅನಪೇಕà³à²·à²¿à²¤ ದೋಷ (%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "ಉಪಪಕà³à²°à²¿à²¯à³†à²¯à³ %ld ಎಂಬ ಸಂಕೇತದಿಂದ ನಿರà³à²—ಮನಗೊಂಡಿದೆ" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "ಉಪಪಕà³à²°à²¿à²¯à³†à²¯à²¨à³à²¨à³ %ld ಎಂಬ ಸಂಕೇತದಿಂದ ನಿಲà³à²²à²¿à²¸à²²à²¾à²—ಿದೆ" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "ಉಪಪಕà³à²°à²¿à²¯à³†à²¯à³ %ld ಎಂಬ ಸಂಕೇತದಿಂದ ಅಂತà³à²¯à²—ೊಂಡಿದೆ" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "ಚೈಲà³à²¡à³ ಪà³à²°à²•à³à²°à²¿à²¯à³† ಸಾಮಾನà³à²¯à²µà²²à³à²²à²¦ ರೀತಿಯಲà³à²²à²¿ ನಿರà³à²—ಮಿಸಿದೆ" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "child pipe (%s) ನಿಂದ ಓದà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "ಕವಲೊಡೆಸà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ (%s)" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "'%s' ಕೋಶಕà³à²•ೆ ಬದಲಾಯಿಸà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ ಎದà³à²°à²¾à²—ಿದೆ (%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "child ಪà³à²°à²•à³à²°à²¿à²¯à³† \"%s\" (%s) ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ ಎದà³à²°à²¾à²—ಿದೆ" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"child ಪà³à²°à²•à³à²°à²¿à²¯à³†à²¯ ಆದಾನ ಅಥವ ಪà³à²°à²¦à²¾à²¨à²µà²¨à³à²¨à³ ಪà³à²¨à²°à³à²¨à²¿à²°à³à²¦à³‡à²¶à²¿à²¸à³à²µà²²à³à²²à²¿ ವಿಫಲತೆ ಎದà³à²°à²¾à²—ಿದೆ (%" +"s)" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "child ಪà³à²°à²•à³à²°à²¿à²¯à³†à²¯à²¨à³à²¨à³ ಕವಲೊಡೆಯಲೠವಿಫಲಗೊಂಡಿದೆ (%s)" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "child ಪà³à²°à²•à³à²°à²¿à²¯à³† \"%s\" ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà²¾à²— ಗೊತà³à²¤à²¿à²°à²¦ ದೋಷ" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "child pid pipe (%s) ಇಂದ ಸಾಕಷà³à²Ÿà³ ದತà³à²¤à²¾à²‚ಶವನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ವಿಫಲಗೊಂಡಿದೆ" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "child ಪà³à²°à²•à³à²°à²¿à²¯à³†à²¯à²¿à²‚ದ ದತà³à²¤à²¾à²‚ಶವನà³à²¨à³ ಓದà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ ಎದà³à²°à²¾à²—ಿದೆ" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ಉಪ ಪà³à²°à²•à³à²°à²¿à²¯à³†à²¯à³Šà²‚ದಿಗೆ ಸಂವಹನಕà³à²•ೆ ಪೈಪನà³à²¨à³ ರಚಿಸà³à²µà²²à³à²²à²¿ ವಿಫಲವಾಗಿದೆ (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "child ಪà³à²°à²•à³à²°à²¿à²¯à³† (%s) ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "ಅಮಾನà³à²¯à²µà²¾à²¦ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ ಹೆಸರà³: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d ದಲà³à²²à²¿à²°à³à²µ ಆರà³à²—à³à²¯à³à²®à³†à²‚ಟೠವೆಕà³à²Ÿà²°à²¿à²¨à²²à³à²²à²¿à²¨ ಅಮಾನà³à²¯ ಸಾಲà³: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "ಪರಿಸರದಲà³à²²à²¿à²¨ ಅಮಾನà³à²¯ ಸಾಲà³: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ಅಮಾನà³à²¯ ಕಾರà³à²¯à²•ಾರಿ ಕೋಶ: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ಸಹಾಯಕ ಪà³à²°à³Šà²—à³à²°à²¾à²‚ (%s) ಅನà³à²¨à³ ಕಾರà³à²¯à²—ತಗೊಳಿಸà³à²µà²²à³à²²à²¿ ವಿಫಲತೆ" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"child ಪà³à²°à²•à³à²°à²¿à²¯à³† ಯಿಂದ ದತà³à²¤à²¾à²‚ಶವನà³à²¨à³ ಓದà³à²µà²¾à²— g_io_channel_win32_poll() ನಲà³à²²à²¿ " +"ಅನಪೇಕà³à²·à²¿à²¤ " +"ದೋಷ" + +#: ../glib/gutf8.c:780 +msgid "Failed to allocate memory" +msgstr "ಮೆಮೊರಿಯನà³à²¨à³ ನಿಯೋಜಿಸಲೠವಿಫಲವಾಗಿದೆ" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "ಅಕà³à²·à²°à²µà³ UTF-8 ನ ವà³à²¯à²¾à²ªà³à²¤à²¿ ಇಂದ ಹೊರಗಿದೆ" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "ಆದಾನ ಪರಿವರà³à²¤à²¨à³†à²¯à²²à³à²²à²¿ ಅಮಾನà³à²¯ ಅನà³à²•à³à²°à²®" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "ಅಕà³à²·à²°à²µà³ UTF-16 ನ ವà³à²¯à²¾à²ªà³à²¤à²¿ ಇಂದ ಹೊರಗಿದೆ" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ಬೈಟà³" +msgstr[1] "%u ಬೈಟà³â€Œà²—ಳà³" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ಬೈಟà³" +msgstr[1] "%s ಬೈಟà³â€Œà²—ಳà³" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "ಜನವರಿ" + +msgctxt "full month name with day" +msgid "February" +msgstr "ಫೆಬà³à²°à²µà²°à²¿" + +msgctxt "full month name with day" +msgid "March" +msgstr "ಮಾರà³à²š" + +msgctxt "full month name with day" +msgid "April" +msgstr "à²à²ªà³à²°à²¿à²²à³" + +msgctxt "full month name with day" +msgid "May" +msgstr "ಮೇ" + +msgctxt "full month name with day" +msgid "June" +msgstr "ಜೂನà³" + +msgctxt "full month name with day" +msgid "July" +msgstr "ಜà³à²²à²¾à²¯à²¿" + +msgctxt "full month name with day" +msgid "August" +msgstr "ಆಗಸà³à²Ÿà³â€" + +msgctxt "full month name with day" +msgid "September" +msgstr "ಸಪà³à²Ÿà³†à²‚ಬರà³" + +msgctxt "full month name with day" +msgid "October" +msgstr "ಅಕà³à²Ÿà³‹à²¬à²°à³" + +msgctxt "full month name with day" +msgid "November" +msgstr "ನವೆಂಬರà³" + +msgctxt "full month name with day" +msgid "December" +msgstr "ಡಿಸೆಂಬರà³" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ಜನ" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ಫೆಬà³à²°" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "ಮಾ" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "à²" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "ಮೇ" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "ಜೂ" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "ಜà³" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ಆಗಸà³à²Ÿà³â€" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "ಸಪà³à²Ÿà³†à²‚" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "ಅಕà³à²Ÿà³Š" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ನವೆಂ" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ಡಿಸೆಂ" + +#~ msgid "URIs not supported" +#~ msgstr "URI ಗಳೠಬೆಂಬಲಿತವಾಗಿಲà³à²²" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "ಕೀಲಿ ಕಡತವೠಕೀಲಿ '%s'ಯನà³à²¨à³ ಹೊಂದಿಲà³à²²" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "xmllint ಇನà³â€Œà²ªà³à²Ÿà³ ಕಡತವನà³à²¨à³ ಸಂಸà³à²•ರಿಸà³à²µà²²à³à²²à²¿ ದೋಷ:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata ಇನà³â€Œà²ªà³à²Ÿà³ ಕಡತವನà³à²¨à³ ಸಂಸà³à²•ರಿಸà³à²µà²²à³à²²à²¿ ದೋಷ:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "ಬಾಕಿ ಇರà³à²µ ದೋಷವನà³à²¨à³ ಪಡೆಯಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²²: %s" diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000..e9e8494 --- /dev/null +++ b/po/ko.po @@ -0,0 +1,6222 @@ +# glib Korean messages +# This file is distributed under the same license as the glib package. +# +# Young-Ho Cha , 2002. +# Eunju Kim , 2007. +# Seong-ho Cho , 2011-2012. +# Changwoo Ryu , 2002, 2004-2006, 2007-2011, 2013-2022. +# +# +# 용어: +# +# - reflink (btrfsì˜ lightweight copy) - 참조ë§í¬ +# - clone - í´ë¡  +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-02-14 13:48+0000\n" +"PO-Revision-Date: 2022-03-01 19:16+0900\n" +"Last-Translator: Changwoo Ryu \n" +"Language-Team: GNOME Korea \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "기본 프로그램 ì„¤ì •ì€ ì•„ì§ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "íƒ€ìž…ì— ëŒ€í•´ 최근 사용한 프로그램 ì„¤ì •ì€ ì•„ì§ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gapplication.c:497 +msgid "GApplication options" +msgstr "GApplication 옵션" + +#: gio/gapplication.c:497 +msgid "Show GApplication options" +msgstr "GApplication ì˜µì…˜ì„ í‘œì‹œí•©ë‹ˆë‹¤" + +#: gio/gapplication.c:542 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication 서비스 모드로 들어갑니다 (D-버스 서비스 파ì¼ì—서 사용)" + +#: gio/gapplication.c:554 +msgid "Override the application’s ID" +msgstr "프로그램 ID를 ì§ì ‘ 지정합니다" + +#: gio/gapplication.c:566 +msgid "Replace the running instance" +msgstr "실행 ì¤‘ì¸ ì¸ìŠ¤í„´ìŠ¤ë¥¼ 바꿉니다" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "ë„움ë§ì„ 표시합니다" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[<명령>]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "버전 출력" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "버전 정보를 표시하고 ë납니다" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "프로그램 목ë¡" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"D-버스로 ë™ìž‘í•  수 있는(.desktop íŒŒì¼ ì‚¬ìš©) í”„ë¡œê·¸ëž¨ì˜ ì„¤ì¹˜ 목ë¡ì„ 봅니다" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "프로그램 실행" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰í•©ë‹ˆë‹¤ (ë’¤ì— ì—´ 파ì¼ì„ 추가해서)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "<프로그램ID> [파ì¼â€¦]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "ë™ìž‘ 활성화" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "í”„ë¡œê·¸ëž¨ì˜ í•œ ë™ìž‘ì„ í˜¸ì¶œí•©ë‹ˆë‹¤" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "<프로그램ID> <ë™ìž‘> [ì¸ìˆ˜]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "사용 가능 ë™ìž‘ 목ë¡" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "í”„ë¡œê·¸ëž¨ì˜ ê³ ì •ëœ ë™ìž‘ 목ë¡ì„ 봅니다 (.desktop 파ì¼ì—서)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "<프로그램ID>" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "<명령>" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "ìžì„¸í•œ ë„움ë§ì„ 표시하는 명령" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-버스 형ì‹ì˜ 프로그램 ID (예: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "<파ì¼>" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "추가로 열려는 파ì¼ì˜ ìƒëŒ€ ë˜ëŠ” 절대 경로, ë˜ëŠ” URI" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "<ë™ìž‘>" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "호출할 ë™ìž‘ ì´ë¦„" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "<ì¸ìˆ˜>" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "추가로 ë™ìž‘ í˜¸ì¶œì— ë¶™ì¼ ì¸ìˆ˜, GVariant 형ì‹" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"알 수 없는 명령 %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "사용법:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "ì¸ìˆ˜:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ì¸ìˆ˜â€¦]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "명령어:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ìžì„¸í•œ ë„움ë§ì„ 보려면 “%s help <명령>â€ì„ 실행하십시오.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s ëª…ë ¹ì€ í•´ë‹¹ 프로그램 IDê°€ 필요합니다.\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "ìž˜ëª»ëœ í”„ë¡œê·¸ëž¨ ID: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%sâ€ ì˜µì…˜ì€ ì¸ìˆ˜ë¥¼ 받지 않습니다\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-ë²„ìŠ¤ì— ì—°ê²°í•  수 없습니다: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "í”„ë¡œê·¸ëž¨ì— %s 메시지를 보내는 중 오류: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "프로그램 ID ë’¤ì— ë™ìž‘ ì´ë¦„ì„ ì¨ì•¼ 합니다\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"ë™ìž‘ ì´ë¦„ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤: “%sâ€\n" +"ë™ìž‘ ì´ë¦„ì€ ì•ŒíŒŒë²³, 숫ìž, “-â€, “.â€ë§Œ 쓸 수 있습니다\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "ë™ìž‘ 파ë¼ë¯¸í„° í•´ì„ ì˜¤ë¥˜: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "최대 1ê°œ ì¸ìˆ˜ë¥¼ 받는 ë™ìž‘\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions ëª…ë ¹ì€ í”„ë¡œê·¸ëž¨ IDë§Œ 받습니다" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "%s í”„ë¡œê·¸ëž¨ì— ëŒ€í•œ desktop 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"알 수 없는 명령 %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%sì— ë„˜ê¸´ 카운트 ê°’ì´ ë„ˆë¬´ í½ë‹ˆë‹¤" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "기반 스트림ì—서 íƒìƒ‰ì„ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GMemoryInputStreamì„ ìžë¥¼ 수 없습니다" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "ìŠ¤íŠ¸ë¦¼ì„ ì´ë¯¸ 닫았습니다" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "기반 스트림ì—서 ìžë¥´ê¸°ë¥¼ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1873 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "ë™ìž‘ì´ ì·¨ì†Œë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "올바른 ê°ì²´ê°€ 아닙니다. 초기화ë˜ì§€ 않았습니다" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "ìž…ë ¥ì—서 ìž˜ëª»ëœ ë©€í‹° ë°”ì´íЏ 시퀀스가 불완전합니다" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "대ìƒì— ê³µê°„ì´ ë¶€ì¡±í•©ë‹ˆë‹¤" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "변환 ìž…ë ¥ì—서 ìž˜ëª»ëœ ë°”ì´íЏ 순서" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "변환 중 오류: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "취소 가능한 초기화를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "문ìžì…‹ “%sâ€ì—서 “%sâ€(으)로 ë³€í™˜ì€ ì§€ì›ë˜ì§€ 않습니다" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "“%sâ€ì—서 “%sâ€(으)로 변환하는 변환기를 ì—´ 수 없습니다" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s 형ì‹" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "알 수 없는 형ì‹" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s íŒŒì¼ í˜•ì‹" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentialsì— ìž˜ëª»ëœ ë°ì´í„°ê°€ 들어 있습니다" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials는 ì´ OSì—서 구현ë˜ì§€ 않았습니다" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "ì´ í”Œëž«í¼ì—서는 GCredentials를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials는 ì´ OSì—서 프로세스 IDê°€ 없습니다" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "암호 ë°ì´í„° ì†ì´ê¸°ê°€ ì´ OSì—서는 불가능합니다" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "예기치 않게 ì¼ì° ìŠ¤íŠ¸ë¦¼ì´ ë났습니다" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "“%s†키를 주소 항목 “%sâ€ì—서 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "“%s†주소 항목ì—서 ì˜ë¯¸ 없는 키/ê°’ì˜ ìŒ" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"“%s†주소는 올바르지 않습니다 (정확히 1ê°œì˜ ê²½ë¡œ, í´ë”, 임시 í´ë”, 절대 키 " +"중 하나가 필요합니다)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "“%s†주소ì—서 오류 — “%s†ì†ì„±ì˜ 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" +"주소 “%2$sâ€ì— 대한 “%1$s†트랜스í¬íŠ¸ëŠ” 알려지지 않았거나 ì§€ì›í•˜ì§€ 않습니다." + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "주소 항목 “%sâ€ì— 콜론(:)ì´ ì—†ìŠµë‹ˆë‹¤" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "주소 항목 “%sâ€ì—서 트랜스í¬íЏ ì´ë¦„ì´ ë¹„ì–´ 있으면 안 ë©ë‹ˆë‹¤" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "키/ê°’ ìŒ %d번, “%sâ€ì— (주소 항목 “%sâ€) 등호 기호가 없습니다" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"키/ê°’ ìŒ %d번, “%sâ€ì— (주소 항목 “%sâ€) 비어 있는 키가 들어 ìžˆì„ ìˆ˜ 없습니다" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "키/ê°’ ìŒ %d번, “%sâ€ì— (주소 항목 “%sâ€) 키/ê°’ì˜ ì´ìŠ¤ì¼€ì´í”„ 제거 오류" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"“%s†주소ì—서 오류 — unix 트랜스í¬íЏì—서는 'path'나 'abstract' 키 중 하나를 " +"설정해야 합니다." + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "“%s†주소ì—서 오류 — host ì†ì„±ì´ 없거나 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "“%s†주소ì—서 오류 — port ì†ì„±ì´ 없거나 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "“%s†주소ì—서 오류 — noncefile ì†ì„±ì´ 없거나 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "ìžë™ 실행 오류: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "“%s†nonce 파ì¼ì„ 여는 중 오류: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "“%s†nonce 파ì¼ì„ ì½ëŠ” 중 오류: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "“%s†nonce 파ì¼ì„ ì½ëŠ” 중 오류, 16ë°”ì´íŠ¸ê°€ 있어야 하지만 %dë°”ì´íЏ" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "“%s†nonce 파ì¼ì˜ ë‚´ìš©ì„ ìŠ¤íŠ¸ë¦¼ì— ì“°ëŠ” 중 오류:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "ì§€ì •ëœ ì£¼ì†Œê°€ 빈 문ìžì—´ìž…니다" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "AT_SECUREê°€ 설정ë˜ì—ˆì„ 때 메시지 버스를 시작할 수 없습니다:" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "machine-id ì—†ì´ ë©”ì‹œì§€ 버스를 시작할 수 없습니다: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "X11 $DISPLAY ì—†ì´ D-Bus ìžë™ 실행할 수 없습니다" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "“%sâ€ ëª…ë ¹ì„ ì‹œìž‘í•˜ëŠ”ë° ì˜¤ë¥˜: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"세션 버스 주소를 알아낼 수 없습니다 (ì´ ìš´ì˜ì²´ì œì—서는 구현ë˜ì§€ 않았습니다)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7334 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"DBUS_STARTER_BUS_TYPE 환경 변수ì—서 세션 버스 주소를 알아낼 수 없습니다 — 알 " +"수 없는 ê°’ “%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7343 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"DBUS_STARTER_BUS_TYPE 환경 변수를 설정하지 않았으므로 세션 버스 주소를 알아" +"낼 수 없습니다" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "알 수 없는 버스 í˜•ì‹ (%d)" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "한 ì¤„ì„ ì½ìœ¼ë ¤ê³  시ë„하는 중 예ìƒì¹˜ 못하게 ì½ì„ ë‚´ìš©ì´ ë¶€ì¡±í•©ë‹ˆë‹¤." + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"한 줄ì„(안전하게) ì½ìœ¼ë ¤ê³  시ë„하는 중 예ìƒì¹˜ 못하게 ì½ì„ ë‚´ìš©ì´ ë¶€ì¡±í•©ë‹ˆë‹¤." + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "사용 가능한 모든 ì¸ì¦ ë°©ë²•ì„ ì‹œë„했습니다 (시ë„: %s) (사용 가능: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "ìƒëŒ€ì™€ ì„œë²„ì˜ ì‚¬ìš©ìž ì•„ì´ë””는 같아야 합니다" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer를 통해 취소ë¨" + +#: gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "디렉터리 “%sâ€ì˜ 정보를 가져오는 중 오류 : %s" + +#: gio/gdbusauthmechanismsha1.c:314 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "“%sâ€ ë””ë ‰í„°ë¦¬ì˜ ê¶Œí•œì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤. 0700ì´ì–´ì•¼ 하지만 0%o입니다" + +#: gio/gdbusauthmechanismsha1.c:347 gio/gdbusauthmechanismsha1.c:358 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "“%s†디렉터리를 만드는 중 오류: %s" + +#: gio/gdbusauthmechanismsha1.c:360 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "ë™ìž‘ì„ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gdbusauthmechanismsha1.c:403 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "“%s†키 모ìŒì„ ì½ê¸° ìš©ë„로 여는 중 오류: " + +#: gio/gdbusauthmechanismsha1.c:426 gio/gdbusauthmechanismsha1.c:748 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%2$sâ€ì˜ 키 ëª¨ìŒ %1$d번 ì¤„ì˜ ë‚´ìš© “%3$sâ€ì˜ 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤." + +#: gio/gdbusauthmechanismsha1.c:440 gio/gdbusauthmechanismsha1.c:762 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"'%2$s'ì˜ í‚¤ ëª¨ìŒ %1$d번 ì¤„ì˜ ì²«ë²ˆì§¸ 토í°ì˜ ë‚´ìš© “%3$sâ€ì˜ 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆ" +"다." + +#: gio/gdbusauthmechanismsha1.c:454 gio/gdbusauthmechanismsha1.c:776 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"“%2$sâ€ì˜ 키 ëª¨ìŒ %1$d번 ì¤„ì˜ ë‘번째 토í°ì˜ ë‚´ìš© “%3$sâ€ì˜ 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆ" +"다." + +#: gio/gdbusauthmechanismsha1.c:478 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "“%2$sâ€ì˜ 키 ëª¨ìŒ ì•„ì´ë”” %1$dì˜ ì¿ í‚¤ë¥¼ ì°¾ì„ ìˆ˜ 없습니다" + +#: gio/gdbusauthmechanismsha1.c:524 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "“%s†잠금 파ì¼ì„ 만드는 중 오류: %s" + +#: gio/gdbusauthmechanismsha1.c:588 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "ì˜¤ëž˜ëœ â€œ%s†잠금 파ì¼ì„ 만드는 중 오류: %s" + +#: gio/gdbusauthmechanismsha1.c:627 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "(ë§í¬ê°€ ëŠì–´ì§„) “%s†잠금 파ì¼ì„ 닫는 중 오류: %s" + +#: gio/gdbusauthmechanismsha1.c:638 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "“%s†잠금 파ì¼ì„ 삭제하는 중 오류: %s" + +#: gio/gdbusauthmechanismsha1.c:715 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "“%s†키 모ìŒì„ 쓰기 ìš©ë„로 여는 중 오류: " + +#: gio/gdbusauthmechanismsha1.c:909 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(추가로 “%sâ€ì— 대한 잠금 í•´ì œë„ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤: %s)" + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2418 +msgid "The connection is closed" +msgstr "ì—°ê²°ì´ ë‹«í˜”ìŠµë‹ˆë‹¤" + +#: gio/gdbusconnection.c:1903 +msgid "Timeout was reached" +msgstr "시간 ì œí•œì„ ë„˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gdbusconnection.c:2541 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²°ì„ ë§Œë“œëŠ” 중 ì§€ì›í•˜ì§€ 않는 플래그가 있습니다" + +#: gio/gdbusconnection.c:4269 gio/gdbusconnection.c:4623 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"경로 %sì˜ ê°ì²´ì— “org.freedesktop.DBus.Properties†ì¸í„°íŽ˜ì´ìŠ¤ê°€ 없습니다" + +#: gio/gdbusconnection.c:4414 +#, c-format +msgid "No such property “%sâ€" +msgstr "“%s†ì†ì„±ì´ 없습니다" + +#: gio/gdbusconnection.c:4426 +#, c-format +msgid "Property “%s†is not readable" +msgstr "“%s†ì†ì„±ì„ ì½ì„ 수 없습니다" + +#: gio/gdbusconnection.c:4437 +#, c-format +msgid "Property “%s†is not writable" +msgstr "“%s†ì†ì„±ì„ 쓸 수 없습니다" + +#: gio/gdbusconnection.c:4457 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "“%s†ì†ì„± 설정 오류: “%s†형ì‹ì´ì–´ì•¼ 하지만 “%sâ€ìž…니다" + +#: gio/gdbusconnection.c:4562 gio/gdbusconnection.c:4777 +#: gio/gdbusconnection.c:6760 +#, c-format +msgid "No such interface “%sâ€" +msgstr "“%s†ì¸í„°íŽ˜ì´ìŠ¤ê°€ 없습니다" + +#: gio/gdbusconnection.c:4999 gio/gdbusconnection.c:7274 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "경로 “%2$sâ€ì˜ ê°ì²´ì— “%1$s†ì¸í„°íŽ˜ì´ìŠ¤ê°€ 없습니다" + +#: gio/gdbusconnection.c:5100 +#, c-format +msgid "No such method “%sâ€" +msgstr "“%s†키가 없습니다" + +#: gio/gdbusconnection.c:5131 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "메시지 형ì‹ì´(“%sâ€) 예ìƒí•œ “%s†형ì‹ì— ë§žì§€ 않습니다." + +#: gio/gdbusconnection.c:5334 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "%2$sì˜ %1$s ì¸í„°íŽ˜ì´ìФ ìš©ë„로 ê°ì²´ë¥¼ ì´ë¯¸ 내보냈습니다" + +#: gio/gdbusconnection.c:5561 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "%s.%s ì†ì„±ì„ 가져올 수 없습니다" + +#: gio/gdbusconnection.c:5617 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "%s.%s ì†ì„±ì„ 설정할 수 없습니다" + +#: gio/gdbusconnection.c:5796 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "“%s†메소드가 “%s†형ì‹ì„ 리턴했지만, “%s†형ì‹ì´ì–´ì•¼ 합니다" + +#: gio/gdbusconnection.c:6872 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "“%3$sâ€ ì„œëª…ì´ ìžˆëŠ” “%2$s†ì¸í„°íŽ˜ì´ìŠ¤ì˜ â€œ%1$s†메서드가 없습니다" + +#: gio/gdbusconnection.c:6993 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "하위 트리를 ì´ë¯¸ %s ìš©ë„로 내보냈습니다" + +#: gio/gdbusconnection.c:7282 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "“%sâ€ ê²½ë¡œì— ì˜¤ë¸Œì íŠ¸ê°€ 없습니다" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "형ì‹ì´ 올바르지 않습니다" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL 메시지: PATH í˜¹ì€ MEMBER í—¤ë” í•„ë“œê°€ 없습니다" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_CALL 메시지: REPLY_SERIAL í—¤ë” í•„ë“œê°€ 없습니다" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR 메시지: REPLY_SERIAL í˜¹ì€ ERROR_NAME í—¤ë” í•„ë“œê°€ 없습니다" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL 메시지: PATH, INTERFACE í˜¹ì€ MEMBER í—¤ë” í•„ë“œê°€ 없습니다" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL 메시지: PATH í—¤ë” í•„ë“œê°€ /org/freedesktop/DBus/Local 예약 ê°’ì„ ì‚¬ìš©í•˜" +"ê³  있습니다" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL 메시지: INTERFACE í—¤ë” í•„ë“œê°€ org.freedesktop.DBus.Local 예약 ê°’ì„ ì‚¬" +"용하고 있습니다" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu ë°”ì´íŠ¸ë¥¼ ì½ì–´ì•¼ 하지만 %lu ë°”ì´íŠ¸ë§Œ 받았습니다" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "“%s†문ìžì—´ ë’¤ì— NUL ë°”ì´íŠ¸ê°€ 와야 하지만 %dë°”ì´íŠ¸ê°€ 있습니다" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"올바른 UTF-8 문ìžì—´ì´ 와야 하지만 오프셋 %dì—(문ìžì—´ ê¸¸ì´ %d) ìž˜ëª»ëœ ë°”ì´íЏ" +"ê°€ 있습니다. ê·¸ 부분까지 올바른 UTF-8 문ìžì—´ì€ “%sâ€ìž…니다." + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "ê°’ì´ ë„ˆë¬´ 깊숙히 ë¼ì›Œ 넣어져 있습니다" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "í•´ì„한 “%sâ€ ê°’ì´ ì˜¬ë°”ë¥¸ D-Bus ê°ì²´ 경로가 아닙니다" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "í•´ì„한 “%sâ€ ê°’ì´ ì˜¬ë°”ë¥¸ D-Bus 시그너ì³ê°€ 아닙니다" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"길ì´ê°€ %u ë°”ì´íŠ¸ì¸ ë°°ì—´ì´ ìžˆìŠµë‹ˆë‹¤. 최대 길ì´ëŠ” 2<<26 ë°”ì´íŠ¸ìž…ë‹ˆë‹¤. (64MiB)" + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"íƒ€ìž…ì´ â€œa%câ€ì¸ ë°°ì—´ì€ ê¸¸ì´ê°€ %u ë°”ì´íŠ¸ì˜ ë°°ìˆ˜ì—¬ì•¼ 하지만, 길ì´ê°€ %u ë°”ì´íŠ¸ìž…" +"니다." + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "D-Busì—서 빈 구조체(튜플)는 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "variantì— ëŒ€í•´ í•´ì„한 ê°’ “%sâ€ì€(는) 올바른 D-Bus 시그너ì³ê°€ 아닙니다." + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "“%sâ€ í˜•ì‹ ë¬¸ìžì—´ë¡œ GVariant를 D-Bus 전송 형ì‹ì—서 ìž¬êµ¬ì„±í•˜ëŠ”ë° ì˜¤ë¥˜" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"엔디안 ê°’ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤. 0x6c(“lâ€) ë˜ëŠ” 0x42 (“Bâ€)ê°€ 와야 하지만 0x%02x ê°’" +"ì´ ìžˆìŠµë‹ˆë‹¤" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "ë©”ì´ì € 프로토콜 ë²„ì „ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤. 1ì´ì–´ì•¼ 하지만 %d입니다." + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "ì‹œê·¸ë„ˆì³ í—¤ë”ê°€ 있지만 타입 ì‹œê·¸ë„ˆì³ í—¤ë”ê°€ 아닙니다" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "ì‹œê·¸ë„ˆì³ â€œ%sâ€ì¸ ì‹œê·¸ë„ˆì³ í—¤ë”ê°€ 있지만 메시지 ë³¸ë¬¸ì´ ë¹„ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "í•´ì„한 “%sâ€ ê°’ì´ (ë³¸ë¬¸ì— ëŒ€í•´) 올바른 D-Bus 시그너ì³ê°€ 아닙니다" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "ë©”ì‹œì§€ì— ì‹œê·¸ë„ˆì³ í—¤ë”ê°€ 없지만 메시지 ë³¸ë¬¸ì´ %u ë°”ì´íŠ¸ìž…ë‹ˆë‹¤" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "메시지를 재구성할 수 없습니다: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "“%sâ€ í˜•ì‹ ë¬¸ìžì—´ë¡œ GVariant를 D-Bus 전송 형ì‹ìœ¼ë¡œ ë§Œë“œëŠ”ë° ì˜¤ë¥˜" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "ë©”ì‹œì§€ì˜ íŒŒì¼ ë””ìŠ¤í¬ë¦½í„° 개수가 (%d) í—¤ë” í•„ë“œì˜ ê°œìˆ˜ì™€ (%d) 다릅니다" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "메시지를 전송 형ì‹ìœ¼ë¡œ 만들 수 없습니다: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "메시지 ë³¸ë¬¸ì— â€œ%s†시그너ì³ê°€ 있지만 ì‹œê·¸ë„ˆì³ í—¤ë”ê°€ 없습니다" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"메시지 ë³¸ë¬¸ì— â€œ%sâ€ í˜•ì‹ ì‹œê·¸ë„ˆì³ê°€ 있지만 í—¤ë” í•„ë“œì˜ ì‹œê·¸ë„ˆì³ê°€ “%sâ€ìž…니다" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "메시지 ë³¸ë¬¸ì´ ë¹„ì—ˆì§€ë§Œ í—¤ë” í•„ë“œì˜ ì‹œê·¸ë„ˆì³ê°€ “(%s)â€ìž…니다" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "오류 리턴, “%s†형ì‹ì˜ 본문" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "오류 리턴, 빈 본문" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(ì´ ì°½ì„ ë‹«ìœ¼ë ¤ë©´ 아무 글ìžë‚˜ 입력하십시오)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "dbus ì„¸ì…˜ì´ ì‹¤í–‰ì¤‘ì´ ì•„ë‹ˆë©°, ìžë™ì‹¤í–‰ì— 실패했습니다" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "하드웨어 프로파ì¼ì„ 가져올 수 없습니다: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "%s ë˜ëŠ” %sì„(를) ì½ì–´ë“¤ì¼ 수 없습니다: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%sì— ëŒ€í•´ StartServiceByName í˜¸ì¶œì´ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr " StartServiceByName(\"%2$s\") 메소드ì—서 예ìƒì¹˜ 못한 ì‘답 %1$d번" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"메소드를 호출할 수 없습니다. 프ë¡ì‹œëŠ” ì†Œìœ ìž ì—†ëŠ” 알려진 ì´ë¦„ì´ê³  (%s) 프ë¡ì‹œ" +"ê°€ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START 플래그를 ê°–ê³  만들어졌습니다" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "ì¶”ìƒ ë„¤ìž„ìŠ¤íŽ˜ì´ìŠ¤ë¥¼ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "서버를 만들 때 nonce 파ì¼ì„ 지정할 수 없습니다" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "“%sâ€ì˜ nonce 파ì¼ì— 쓰는 중 오류: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "“%s†문ìžì—´ì€ 올바른 D-BUS GUIDê°€ 아닙니다" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "ì§€ì›í•˜ì§€ 않는 transport “%sâ€ì—서 ì—°ê²°ì„ ë°›ì•„ë“¤ì¼ ìˆ˜ 없습니다" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"명령:\n" +" help ì´ ì •ë³´ë¥¼ 표시합니다\n" +" introspect ì›ê²© ê°ì²´ë¥¼ 조사합니다\n" +" monitor ì›ê²© ê°ì²´ë¥¼ 검사합니다\n" +" call ì›ê²© ê°ì²´ë¥¼ 메소드를 호출합니다\n" +" emit 시그ë„ì„ ë°œìƒí•©ë‹ˆë‹¤\n" +" wait 버스 ì´ë¦„ì´ ë‚˜íƒ€ë‚  때까지 대기합니다\n" +"\n" +"ê° ëª…ë ¹ì–´ì˜ ë„움ë§ì„ 보려면 “%s <명령> --helpâ€ ëª…ë ¹ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤.\n" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1244 +#: gio/gdbus-tool.c:1732 +#, c-format +msgid "Error: %s\n" +msgstr "오류: %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1748 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "introspection XMLì„ í•´ì„하는 ì¤‘ì— ì˜¤ë¥˜: %s\n" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "오류: “%sâ€ì€(는) 올바른 ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1063 +#: gio/gdbus-tool.c:1898 gio/gdbus-tool.c:2138 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "오류: “%sâ€ì€(는) 올바른 ê°ì²´ 경로가 아닙니다\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "시스템 ë²„ìŠ¤ì— ì—°ê²°" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "세션 ë²„ìŠ¤ì— ì—°ê²°" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "ì§€ì •ëœ D-Bus ì£¼ì†Œì— ì—°ê²°" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "ì—°ê²° ì¢…ì  ì˜µì…˜:" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "ì—°ê²° 종ì ì„ 지정하는 옵션" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "ì—°ê²° 종ì ì„ 지정하지 않았습니다" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "여러 ê°œì˜ ì—°ê²° 종ì ì„ 지정했습니다" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "경고: introspection ë°ì´í„°ì— 따르면 “%s†ì¸í„°íŽ˜ì´ìŠ¤ê°€ 없습니다\n" + +#: gio/gdbus-tool.c:531 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"경고: introspection ë°ì´í„°ì— 따르면 “%s†메소드가 “%s†ì¸í„°íŽ˜ì´ìŠ¤ì— ì—†ìŠµë‹ˆ" +"다\n" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "추가로 지정할 수 있는 시그ë„ì˜ ëŒ€ìƒ (고유 ì´ë¦„)" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "시그ë„ì„ ë°œìƒí•  ê°ì²´ 경로" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "ì‹œê·¸ë„ ë° ì¸í„°íŽ˜ì´ìФ ì´ë¦„" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "시그ë„ì„ ë°œìƒí•©ë‹ˆë‹¤." + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:1000 gio/gdbus-tool.c:1835 +#: gio/gdbus-tool.c:2067 gio/gdbus-tool.c:2287 +#, c-format +msgid "Error connecting: %s\n" +msgstr "ì—°ê²°í•˜ëŠ”ë° ì˜¤ë¥˜: %s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "오류: “%sâ€ì€(는) 올바른 고유 버스 ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤.\n" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1043 gio/gdbus-tool.c:1878 +msgid "Error: Object path is not specified\n" +msgstr "오류: ê°ì²´ 경로를 지정하지 않았습니다\n" + +#: gio/gdbus-tool.c:765 +msgid "Error: Signal name is not specified\n" +msgstr "오류: ì‹œê·¸ë„ ì´ë¦„ì„ ì§€ì •í•˜ì§€ 않았습니다\n" + +#: gio/gdbus-tool.c:779 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "오류: ì‹œê·¸ë„ ì´ë¦„ “%sâ€ì´(ê°€) 올바르지 않습니다\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "오류: “%sâ€ì€(는) 올바른 ì¸í„°íŽ˜ì´ìФ ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "오류: “%sâ€ì€(는) 올바른 멤버 ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1175 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "파ë¼ë¯¸í„° %d번 í•´ì„ ì˜¤ë¥˜: %s\n" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "ì—°ê²°ì˜ ë²„í¼ ë‚´ìš©ì„ ì ìš©í•˜ëŠ”ë° ì˜¤ë¥˜: %s\n" + +#: gio/gdbus-tool.c:894 +msgid "Destination name to invoke method on" +msgstr "메소드를 호출할 ëŒ€ìƒ ì´ë¦„" + +#: gio/gdbus-tool.c:895 +msgid "Object path to invoke method on" +msgstr "메소드를 호출할 ê°ì²´ 경로" + +#: gio/gdbus-tool.c:896 +msgid "Method and interface name" +msgstr "메소드 ë° ì¸í„°íŽ˜ì´ìФ ì´ë¦„" + +#: gio/gdbus-tool.c:897 +msgid "Timeout in seconds" +msgstr "시간 제한, ì´ˆ 단위" + +#: gio/gdbus-tool.c:898 +msgid "Allow interactive authorization" +msgstr "ë™ì  권한 부여를 허용" + +#: gio/gdbus-tool.c:945 +msgid "Invoke a method on a remote object." +msgstr "ì›ê²© ê°ì²´ì— 대해 메소드를 호출합니다." + +#: gio/gdbus-tool.c:1017 gio/gdbus-tool.c:1852 gio/gdbus-tool.c:2092 +msgid "Error: Destination is not specified\n" +msgstr "오류: 대ìƒì„ 지정하지 않았습니다\n" + +#: gio/gdbus-tool.c:1028 gio/gdbus-tool.c:1869 gio/gdbus-tool.c:2103 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "오류: “%sâ€ì€(는) 올바른 버스 ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤\n" + +#: gio/gdbus-tool.c:1078 +msgid "Error: Method name is not specified\n" +msgstr "오류: 메소드 ì´ë¦„ì„ ì§€ì •í•˜ì§€ 않았습니다\n" + +#: gio/gdbus-tool.c:1089 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "오류: 메소드 ì´ë¦„ “%sâ€ì´(ê°€) 올바르지 않습니다\n" + +#: gio/gdbus-tool.c:1167 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "í˜•ì‹ â€œ%2$sâ€ì˜ 파ë¼ë¯¸í„° %1$d번 í•´ì„ ì˜¤ë¥˜: %3$s\n" + +#: gio/gdbus-tool.c:1193 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "핸들 %d번 추가하는 중 오류: %s\n" + +#: gio/gdbus-tool.c:1694 +msgid "Destination name to introspect" +msgstr "조사할 ëŒ€ìƒ ì´ë¦„" + +#: gio/gdbus-tool.c:1695 +msgid "Object path to introspect" +msgstr "조사할 ê°ì²´ 경로" + +#: gio/gdbus-tool.c:1696 +msgid "Print XML" +msgstr "XMLì„ í‘œì‹œí•©ë‹ˆë‹¤" + +#: gio/gdbus-tool.c:1697 +msgid "Introspect children" +msgstr "하위 í•­ëª©ì— ì¸íŠ¸ë¡œìŠ¤íŽ™íŠ¸ ì ìš©" + +#: gio/gdbus-tool.c:1698 +msgid "Only print properties" +msgstr "ì†ì„±ì„ 표시하기만 합니다" + +#: gio/gdbus-tool.c:1787 +msgid "Introspect a remote object." +msgstr "ì›ê²© ê°ì²´ë¥¼ 조사합니다." + +#: gio/gdbus-tool.c:1993 +msgid "Destination name to monitor" +msgstr "ê°ì‹œí•  ëŒ€ìƒ ì´ë¦„" + +#: gio/gdbus-tool.c:1994 +msgid "Object path to monitor" +msgstr "ê°ì‹œí•  ê°ì²´ 경로" + +#: gio/gdbus-tool.c:2019 +msgid "Monitor a remote object." +msgstr "ì›ê²© ê°ì²´ë¥¼ ê°ì‹œí•©ë‹ˆë‹¤." + +#: gio/gdbus-tool.c:2077 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "오류: 메시지 버스가 아닌 ì—°ê²°ì„ ê°ì‹œí•  수 없습니다\n" + +#: gio/gdbus-tool.c:2201 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "(알려진 ì´ë¦„ì˜) 다른 서비스를 기다리기 ì „ì— í™œì„±í™”í•  서비스" + +#: gio/gdbus-tool.c:2204 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"오류로 ëë‚  때까지 대기할 시간 제한 (ì´ˆ 단위), 0ì´ë©´ 시간 무제한 (기본값)" + +#: gio/gdbus-tool.c:2252 +msgid "[OPTION…] BUS-NAME" +msgstr "[옵션…] <버스-ì´ë¦„>" + +#: gio/gdbus-tool.c:2253 +msgid "Wait for a bus name to appear." +msgstr "버스 ì´ë¦„ì´ ë‚˜íƒ€ë‚  때까지 대기합니다." + +#: gio/gdbus-tool.c:2329 +msgid "Error: A service to activate for must be specified.\n" +msgstr "오류: 활성화할 서비스를 지정해야 합니다.\n" + +#: gio/gdbus-tool.c:2334 +msgid "Error: A service to wait for must be specified.\n" +msgstr "오류: 대기할 서비스를 지정해야 합니다.\n" + +#: gio/gdbus-tool.c:2339 +msgid "Error: Too many arguments.\n" +msgstr "오류: ì¸ìžê°€ 너무 많습니다.\n" + +#: gio/gdbus-tool.c:2347 gio/gdbus-tool.c:2354 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "오류: “%sâ€ì€(는) 올바른 알려진 버스 ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤.\n" + +#: gio/gdebugcontrollerdbus.c:203 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "디버깅 ì„¤ì •ì„ ë°”ê¿€ ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤" + +#: gio/gdesktopappinfo.c:2174 gio/gdesktopappinfo.c:5099 +msgid "Unnamed" +msgstr "ì´ë¦„ì—†ìŒ" + +#: gio/gdesktopappinfo.c:2584 +msgid "Desktop file didn’t specify Exec field" +msgstr "desktop 파ì¼ì— Exec 필드를 지정하지 않았습니다" + +#: gio/gdesktopappinfo.c:2892 +msgid "Unable to find terminal required for application" +msgstr "í”„ë¡œê·¸ëž¨ì— í•„ìš”í•œ 터미ë„ì„ ì°¾ì„ ìˆ˜ 없습니다" + +#: gio/gdesktopappinfo.c:3619 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "ì‚¬ìš©ìž í”„ë¡œê·¸ëž¨ 설정 í´ë”(%s)를 만들 수 없습니다: %s" + +#: gio/gdesktopappinfo.c:3623 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "ì‚¬ìš©ìž MIME 설정 í´ë”(%s)를 만들 수 없습니다: %s" + +#: gio/gdesktopappinfo.c:3865 gio/gdesktopappinfo.c:3889 +msgid "Application information lacks an identifier" +msgstr "프로그램 ì •ë³´ì— ì•„ì´ë””ê°€ 없습니다" + +#: gio/gdesktopappinfo.c:4125 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "%s ì‚¬ìš©ìž desktop 파ì¼ì„ 만들 수 없습니다" + +#: gio/gdesktopappinfo.c:4261 +#, c-format +msgid "Custom definition for %s" +msgstr "%sì— ëŒ€í•œ ì‚¬ìš©ìž ì„¤ì • ì •ì˜" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "드ë¼ì´ë¸Œê°€ eject ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "드ë¼ì´ë¸Œê°€ eject ë˜ëŠ” eject_with_operation ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "드ë¼ì´ë¸Œê°€ 미디어 í´ë§ì„ 구현하지 않았습니다" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "드ë¼ì´ë¸Œê°€ start ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "드ë¼ì´ë¸Œê°€ stop ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS 백엔드가 TLS ë°”ì¸ë”© 가져오기를 구현하지 않았습니다" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 없습니다" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 없습니다" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "GEmblem ì¸ì½”ë”©ì˜ %d ë²„ì „ì„ ì²˜ë¦¬í•  수 없습니다" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem ì¸ì½”딩ì—서 í† í° ìˆ˜ê°€(%dê°œ) 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon ì¸ì½”ë”©ì˜ %d ë²„ì „ì„ ì²˜ë¦¬í•  수 없습니다" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon ì¸ì½”딩ì—서 í† í° ìˆ˜ê°€(%dê°œ) 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIconì— GEmblemì´ ì—†ìŠµë‹ˆë‹¤" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "들어 있는 마운트가 없습니다" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "디렉터리를 ë®ì–´ ì¨ì„œ 복사할 수 없습니다" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "디렉터리를 ë®ì–´ ì¨ì„œ 디렉터리를 복사할 수 없습니다" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "ëŒ€ìƒ íŒŒì¼ì´ 있습니다" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "디렉터리를 재귀ì ìœ¼ë¡œ 복사할 수 없습니다" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "잇기를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "íŒŒì¼ ìª¼ê°œê¸° 오류: %s" + +# reflink/cloneì€ btrfsì—서 임시 복사하는 걸 ë§í•œë‹¤ +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "다른 마운트 사ì´ì— 복사(참조ë§í¬/í´ë¡ )는 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "복사(참조ë§í¬/í´ë¡ )를 ì§€ì›í•˜ì§€ 않거나 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "복사(참조ë§í¬/í´ë¡ )를 ì§€ì›í•˜ì§€ 않거나 ë™ìž‘하지 않았습니다." + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "특수 파ì¼ì€ 복사할 수 없습니다" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "ìž˜ëª»ëœ ì‹¬ë³¼ë¦­ ë§í¬ ê°’ì´ ì£¼ì–´ì¡ŒìŠµë‹ˆë‹¤" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "심볼릭 ë§í¬ë¥¼ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "íœ´ì§€í†µì„ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "íŒŒì¼ ì´ë¦„ì— â€œ%c†문ìžê°€ 들어갈 수 없습니다" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "ë³¼ë¥¨ì´ mount를 구현하지 않았습니다" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "ì´ íŒŒì¼ì„ 처리하는 í”„ë¡œê·¸ëž¨ì„ ì•„ë¬´ ê²ƒë„ ë“±ë¡í•˜ì§€ 않았습니다" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "ì´ë‰´ë¨¸ë ˆì´í„°ë¥¼ ì´ë¯¸ 닫았습니다" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "íŒŒì¼ ì´ë‰´ë¨¸ë ˆì´í„°ì— ì§„í–‰ ì¤‘ì¸ ë™ìž‘ì´ ìžˆìŠµë‹ˆë‹¤" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "íŒŒì¼ ì´ë‰´ë¨¸ë ˆì´í„°ë¥¼ ì´ë¯¸ 닫았습니다" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "GFileIcon ì¸ì½”ë”©ì˜ %d ë²„ì „ì„ ì²˜ë¦¬í•  수 없습니다" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon ìž…ë ¥ ë°ì´í„°ì˜ 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "ìŠ¤íŠ¸ë¦¼ì´ query_info를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "스트림ì—서 seek를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ìž…ë ¥ ìŠ¤íŠ¸ë¦¼ì´ truncate를 허용하지 않습니다" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "스트림ì—서 truncate를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "ìž˜ëª»ëœ í˜¸ìŠ¤íŠ¸ ì´ë¦„" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "ìž˜ëª»ëœ HTTP 프ë¡ì‹œ ì‘답" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP 프ë¡ì‹œ ì—°ê²°ì„ í—ˆìš©í•˜ì§€ 않습니다" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP 프ë¡ì‹œ ì¸ì¦ì´ 실패했습니다" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP 프ë¡ì‹œ ì¸ì¦ì´ 필요합니다" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP 프ë¡ì‹œ ì—°ê²°ì´ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP 프ë¡ì‹œ ì‘ë‹µì´ ë„ˆë¬´ í½ë‹ˆë‹¤" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP 프ë¡ì‹œ 서버가 예ìƒì¹˜ 못하게 ì—°ê²°ì„ ë‹«ì•˜ìŠµë‹ˆë‹¤." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "í† í° ìˆ˜ê°€ (%dê°œ) 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "í´ëž˜ìФ ì´ë¦„ \"%s\"ì— ëŒ€í•œ 형ì‹ì´ 없습니다" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "\"%s\" 형ì‹ì€ GIcon ì¸í„°íŽ˜ì´ìŠ¤ë¥¼ 구현하지 않습니다" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "\"%s\" 형ì‹ì— 대한 í´ëž˜ìŠ¤ê°€ 없습니다" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "버전 형ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "\"%s\" 형ì‹ì€ GIcon ì¸í„°íŽ˜ì´ìФì—서 from_token()를 구현하지 않습니다" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "ì•„ì´ì½˜ ì¸ì½”ë”©ì— ì €ìž¥í•œ ë²„ì „ì„ ì²˜ë¦¬í•  수 없습니다" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "주소가 지정ë˜ì§€ 않았습니다" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "ì£¼ì†Œì˜ ê¸¸ì´ %uì´(ê°€) 너무 ê¹ë‹ˆë‹¤" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ì£¼ì†Œì— ì ‘ë‘ì–´ 길ì´ë³´ë‹¤ 긴 비트 ë°ì´í„°ê°€ 들어 있습니다" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "“%sâ€ì„(를) IP주소 마스í¬ë¡œ í•´ì„í•  수 없습니다" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "소켓 ì£¼ì†Œì— ê³µê°„ì´ ë¶€ì¡±í•©ë‹ˆë‹¤" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "소켓 주소를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "ìž…ë ¥ ìŠ¤íŠ¸ë¦¼ì´ read를 구현하지 않았습니다" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "ìŠ¤íŠ¸ë¦¼ì— ì§„í–‰ ì¤‘ì¸ ë™ìž‘ì´ ìžˆìŠµë‹ˆë‹¤" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "íŒŒì¼ ë³µì‚¬" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "íŒŒì¼ ì˜®ê¸¸ 때 유지" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“versionâ€ ì˜µì…˜ì€ ì¸ìˆ˜ë¥¼ 받지 않습니다" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "사용법:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "버전 정보를 표시하고 ë납니다." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "명령어:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "파ì¼ì„ 붙여서 표준 출력으로 출력합니다" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "하나 ë˜ëŠ” 여러 íŒŒì¼ ë³µì‚¬" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "ìœ„ì¹˜ì— ëŒ€í•œ 정보를 표시합니다" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "ë°ìФí¬í†± 파ì¼ì—서 í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰í•©ë‹ˆë‹¤" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "ìœ„ì¹˜ì˜ ë‚´ìš©ì„ í‘œì‹œ" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "지정한 MIME ìœ í˜•ì— ëŒ€í•œ 핸들러를 알아내거나 설정합니다" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "디렉터리 만듭니다" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "파ì¼ê³¼ ë””ë ‰í„°ë¦¬ì˜ ë°”ë€ ì‚¬í•­ì„ ê°ì‹œí•©ë‹ˆë‹¤" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "위치를 마운트하거나 해제합니다" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "하나 ë˜ëŠ” 여러 파ì¼ì„ 옮ê¹ë‹ˆë‹¤" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "파ì¼ì„ 기본 프로그램으로 엽니다" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "파ì¼ì˜ ì´ë¦„ì„ ë°”ê¿‰ë‹ˆë‹¤" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "하나 ë˜ëŠ” 여러 파ì¼ì„ 삭제합니다" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "표준 ìž…ë ¥ì—서 ì½ê³  저장합니다" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "íŒŒì¼ ì†ì„±ì„ 설정합니다" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "íŒŒì¼ ë˜ëŠ” 디렉터리를 휴지통으로 옮ê¹ë‹ˆë‹¤" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "ìœ„ì¹˜ì˜ ë‚´ìš©ì„ íŠ¸ë¦¬ 형태로 표시합니다" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "ìžì„¸í•œ ë„움ë§ì„ %s ì˜µì…˜ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "표준 ì¶œë ¥ì— ì“°ëŠ” 중 오류" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "<위치>" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "파ì¼ì„ 붙여서 표준 출력으로 출력합니다." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"GIO catì€ ì „í†µì ì¸ cat 유틸리티와 ë˜‘ê°™ì´ ë™ìž‘하지만, 로컬\n" +"íŒŒì¼ ëŒ€ì‹  GIO 위치를 사용합니다: 예를 들어 위치로\n" +"smb://server/resource/file.txt와 ê°™ì´ ì“¸ 수 있습니다." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "위치를 지정하지 않았습니다" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "ëŒ€ìƒ ë””ë ‰í„°ë¦¬ê°€ 없습니다" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "진행사항 표시" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "ë®ì–´ 쓰기 ì „ì— ë¬¼ì–´ë³´ê¸°" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "모든 ì†ì„± 유지" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "기존 ëŒ€ìƒ íŒŒì¼ì˜ ë°±ì—…ì„ ë§Œë“­ë‹ˆë‹¤" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "심볼릭 ë§í¬ë¥¼ ë”°ë¼ê°€ì§€ 않습니다" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "대ìƒì˜ ê¶Œí•œì— ê¸°ë³¸ê°’ì„ ì‚¬ìš©í•©ë‹ˆë‹¤" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%2$s 중 %1$s 전송함 (%3$s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "<ì›ë³¸>" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "<대ìƒ>" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "하나 ë˜ëŠ” 여러 파ì¼ì„ <ì›ë³¸>ì—서 <대ìƒ>으로 복사합니다." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"GIO copy는 전통ì ì¸ cp 유틸리티와 비슷하지만, 로컬 파ì¼\n" +"대신 GIO 위치를 사용합니다. 예를 들어 위치로\n" +"smb://server/resource/file.txt와 ê°™ì´ ì“¸ 수 있습니다." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "ëŒ€ìƒ %sì´(ê°€) 디렉터리가 아닙니다" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: “%s†파ì¼ì„ ë®ì–´ì”니까? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "쓰기 가능 ì†ì„± 목ë¡" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "íŒŒì¼ ì‹œìŠ¤í…œ ì •ë³´ 가져오기" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "가져올 ì†ì„±" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "<ì†ì„±>" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "심볼릭 ë§í¬ ë”°ë¼ê°€ì§€ 않기" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "ì†ì„±:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "표시 ì´ë¦„: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "편집 ì´ë¦„: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "ì´ë¦„: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "종류: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "í¬ê¸°: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "숨김\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "URI: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "로컬 경로: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "유닉스 마운트: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "설정 가능 ì†ì„±:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "쓰기 가능 ì†ì„± 네임스페ì´ìФ:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "ìœ„ì¹˜ì— ëŒ€í•œ 정보를 표시합니다." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"GIO info는 전통ì ì¸ ls 유틸리티와 비슷하지만, 로컬 파ì¼\n" +"대신 GIO 위치를 사용합니다. 예를 들어 위치로\n" +"smb://server/resource/file.txt와 ê°™ì´ ì“¸ 수 있습니다.\n" +"íŒŒì¼ ì†ì„±ì€ GIO ì´ë¦„ìœ¼ë¡œë„ ì§€ì •í•  ìˆ˜ë„ ìžˆê³  (예: standard::icon),\n" +"네임스페ì´ìŠ¤ë¡œ 지정할 ìˆ˜ë„ ìžˆê³  (예: unix), 모든 ì†ì„±ì— 해당하는\n" +"“*â€ë¡œ 지정할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "<ë°ìФí¬í†±-파ì¼> [<파ì¼-ì¸ìž> …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"ë°ìФí¬í†± 파ì¼ì—서 í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰í•©ë‹ˆë‹¤. 옵션으로 íŒŒì¼ ì´ë¦„ ì¸ìžë¥¼ 실행할 때 " +"전달합니다." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "대ìƒì„ 지정하지 않았습니다" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "ì´ ì‹¤í–‰ ëª…ë ¹ì€ í˜„ìž¬ ì´ í”Œëž«í¼ì—서 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "‘%s‘ì„(를) ì½ì–´ë“¤ì¼ 수 없습니다: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "‘%sâ€˜ì— ëŒ€í•œ 프로그램 정보를 ì½ì–´ë“¤ì¼ 수 없습니다" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "‘%s‘ í”„ë¡œê·¸ëž¨ì„ ì½ì–´ë“¤ì¼ 수 없습니다: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "숨김 íŒŒì¼ í‘œì‹œ" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "긴 ëª©ë¡ í˜•ì‹ ì‚¬ìš©í•˜ê¸°" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "표시 ì´ë¦„ì„ í‘œì‹œ" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "ì „ì²´ URI 표시" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "ìœ„ì¹˜ì˜ ë‚´ìš© 목ë¡ì„ 표시." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"GIO list는 전통ì ì¸ ls 유틸리티와 비슷하지만, 로컬 파ì¼\n" +"대신 GIO 위치를 사용합니다. 예를 들어 위치로\n" +"smb://server/resource/file.txt와 ê°™ì´ ì“¸ 수 있습니다.\n" +"íŒŒì¼ ì†ì„±ì€ GIO ì´ë¦„ìœ¼ë¡œë„ ì§€ì •í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤\n" +"(예: standard::icon)." + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "<핸들러>" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "지정한 MIME ìœ í˜•ì— ëŒ€í•œ 핸들러를 알아내거나 설정합니다." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"핸들러를 지정하지 않는 경우, 해당 MIME ìœ í˜•ì— ëŒ€í•´ 등ë¡ë˜ê³  추천하는\n" +"í”„ë¡œê·¸ëž¨ì˜ ëª©ë¡ì„ 표시합니다. 핸들러를 지정하면, ê·¸ 핸들러를 해당\n" +"MIME ìœ í˜•ì˜ ê¸°ë³¸ 핸들러로 지정합니다." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "í•˜ë‚˜ì˜ MIME ìœ í˜•ì„ ì§€ì •í•´ì•¼ 하고, 설정할 경우 핸들러를 지정합니다" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "“%sâ€ì— 대한 기본 í”„ë¡œê·¸ëž¨ì´ ì—†ìŠµë‹ˆë‹¤.\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "“%sâ€ì— 대한 기본 프로그램: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "등ë¡ëœ 프로그램:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "등ë¡ëœ í”„ë¡œê·¸ëž¨ì´ ì—†ìŠµë‹ˆë‹¤\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "추천 프로그램:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "추천 í”„ë¡œê·¸ëž¨ì´ ì—†ìŠµë‹ˆë‹¤\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "“%s†핸들러 정보를 ì½ì–´ë“¤ì´ëŠ”ë° ì‹¤íŒ¨" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "“%sâ€ì„(를) “%sâ€ì˜ 기본 핸들러로 ì„¤ì •í•˜ëŠ”ë° ì‹¤íŒ¨: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "ìƒìœ„ 디렉터리 만들기" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "디렉터리 만들기." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"GIO mkdirì€ ì „í†µì ì¸ mkdir 유틸리티와 비슷하지만, 로컬 파ì¼\n" +"대신 GIO 위치를 사용합니다. 예를 들어 위치로\n" +"smb://server/resource/mydir와 ê°™ì´ ì“¸ 수 있습니다." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "디렉터리를 ê°ì‹œí•©ë‹ˆë‹¤ (기본값: íŒŒì¼ ìœ í˜•ì— ë”°ë¼)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "파ì¼ì„ ê°ì‹œí•©ë‹ˆë‹¤ (기본값: íŒŒì¼ ìœ í˜•ì— ë”°ë¼)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "파ì¼ì„ ì§ì ‘ ê°ì‹œí•©ë‹ˆë‹¤ (하드 ë§í¬ë¥¼ 통해 ë°”ë€ ì‚¬í•­ì„ ì•Œë¦½ë‹ˆë‹¤)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "파ì¼ì„ ì§ì ‘ ê°ì‹œí•˜ì§€ë§Œ, ë°”ë€ ì‚¬í•­ì„ ì•Œë¦¬ì§€ 않습니다" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "íŒŒì¼ ì´ë™ê³¼ ì´ë¦„ 바꾸기를 간단한 ì‚­ì œ/ìƒì„± ì´ë²¤íŠ¸ë¡œ 알립니다" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "마운트 ì´ë²¤íЏ ê°ì‹œ" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "íŒŒì¼ ë˜ëŠ” 디렉터리 ë°”ë€ ì‚¬í•­ì„ ê°ì‹œí•©ë‹ˆë‹¤." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "마운트 가능 위치 마운트" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "ë³¼ë¥¨ì„ ë””ë°”ì´ìФ íŒŒì¼ ë˜ëŠ” 다른 ì•„ì´ë””로 마운트합니다" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "마운트 í•´ì œ" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "빼기" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "디바ì´ìФ 파ì¼ë¡œ 드ë¼ì´ë¸Œ 중지" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "<장치>" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "주어진 ìŠ¤í‚´ì— í•´ë‹¹í•˜ëŠ” 모든 마운트를 해제합니다" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "<스킴>" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "마운트 í•´ì œ ë˜ëŠ” 빼기ì—서 드러나는 íŒŒì¼ ë™ìž‘ 무시" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "ì¸ì¦í•  때 ìµëª… ì‚¬ìš©ìž ì‚¬ìš©" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "ëª©ë¡ í‘œì‹œ" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "ì´ë²¤íЏ ê°ì‹œ" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "추가 정보를 표시합니다" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "VeraCrypt ë³¼ë¥¨ì˜ ìž ê¸ˆì„ í•´ì œí•  때 쓰는 ìˆ«ìž PIM" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "TCRYPT 숨겨진 볼륨 마운트" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "TCRYPT 시스템 볼륨 마운트" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "ìµëª… ì ‘ê·¼ì´ ê±°ì ˆë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "디바ì´ìФ 파ì¼ì— 대한 드ë¼ì´ë¸Œê°€ 없습니다" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "지정한 IDì— ëŒ€í•œ ë³¼ë¥¨ì´ ì—†ìŠµë‹ˆë‹¤" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "위치를 마운트하거나 해제합니다." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "복사 ë˜ëŠ” ì‚­ì œ ëŒ€ë¹„ì±…ì„ ì‚¬ìš©í•˜ì§€ 않습니다" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "<ì›ë³¸>ì—서 <대ìƒ>으로 하나 ë˜ëŠ” 여러 파ì¼ì„ 옮ê¹ë‹ˆë‹¤." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"GIO move는 전통ì ì¸ mv 유틸리티와 비슷하지만, 로컬 파ì¼\n" +"대신 GIO 위치를 사용합니다. 예를 들어 위치로\n" +"smb://server/resource/file.txt와 ê°™ì´ ì“¸ 수 있습니다." + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "%s 대ìƒì´ 디렉터리가 아닙니다" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"해당 파ì¼ì˜ ìœ í˜•ì˜ ì²˜ë¦¬í•˜ë„ë¡ ë“±ë¡ëœ\n" +"기본 프로그램으로 파ì¼ì„ 엽니다." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "없는 파ì¼ì„ 무시하고, 물어보지 않습니다" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "지정한 파ì¼ì„ 삭제합니다." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "<ì´ë¦„>" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "파ì¼ì˜ ì´ë¦„ì„ ë°”ê¿‰ë‹ˆë‹¤." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "ì¸ìžê°€ 빠졌습니다" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "ì¸ìžê°€ 너무 많습니다" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "ì´ë¦„ 바꾸기 성공. 새 URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "ì—†ì„ ê²½ìš°ì—ë§Œ 만들기" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "íŒŒì¼ ë’¤ì— ì¶”ê°€" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "만들 때, 현재 사용ìžì—게만 ì ‘ê·¼ 허가" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "바꿀 때, 대ìƒì´ ì—†ì„ ê²½ìš°ì—ë§Œ 바꾸기" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "새 etag를 ë’¤ì— í‘œì‹œ" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "íŒŒì¼ etag를 ë®ì–´ì”€" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "표준 ìž…ë ¥ì—서 ì½ëŠ” 중 오류" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "etag를 사용할 수 없습니다\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "표준 ìž…ë ¥ì—서 ì½ì–´ì„œ <대ìƒ>ì— ì €ìž¥í•©ë‹ˆë‹¤." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "대ìƒì„ 지정하지 않았습니다" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "ì†ì„±ì˜ 종류" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "<종류>" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "<ì†ì„±>" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "<ê°’>" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "<위치>ì˜ íŒŒì¼ ì†ì„±ì„ 설정합니다." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "위치를 지정하지 않았습니다" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "ì†ì„±ì„ 지정하지 않았습니다" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "ê°’ì„ ì§€ì •í•˜ì§€ 않았습니다" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "ìž˜ëª»ëœ ì†ì„± í˜•ì‹ â€œ%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "휴지통 비우기" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "íœ´ì§€í†µì— ë“¤ì–´ 있는 파ì¼ì„ ì›ëž˜ 위치와 ê°™ì´ í‘œì‹œí•©ë‹ˆë‹¤" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"íœ´ì§€í†µì˜ íŒŒì¼ì„ ì›ëž˜ 위치로 복구합니다 (ê·¸ ë””ë ‰í„°ë¦¬ë„ ë‹¤ì‹œ 만들 수 있ìŒ)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "본래 경로를 ì°¾ì„ ìˆ˜ 없습니다" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "본래 위치를 다시 만들 수 없습니다: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "파ì¼ì„ 본래 위치로 옮길 수 없습니다: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "파ì¼ì´ë‚˜ 디렉터리를 íœ´ì§€í†µì— ì˜®ê¸°ê±°ë‚˜ 휴지통ì—서 복구합니다." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"주ì˜: --restore 옵션ì—서, 버린 파ì¼ì˜ 본래 위치가 ì´ë¯¸ 있는 경우,\n" +"--force ì˜µì…˜ì„ ì‚¬ìš©í•˜ì§€ 않는 한 ê·¸ 위치를 ë®ì–´ ì“°ì§€ 않습니다." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "주어진 위치가 trash:/// 문ìžì—´ë¡œ 시작하지 않습니다" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "심볼릭 ë§í¬, 마운트, 바로 가기를 ë”°ë¼ê°‘니다" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "ë””ë ‰í„°ë¦¬ì˜ ë‚´ìš©ì„ íŠ¸ë¦¬ 형ì‹ìœ¼ë¡œ 표시합니다." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> 요소는 <%s> ì•ˆì— ì“¸ 수 없습니다" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> 요소는 최ìƒìœ„ì— ì“¸ 수 없습니다" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "ìžì›ì—서 %s 파ì¼ì´ 여러번 나타납니다" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "ìž„ì˜ì˜ 소스 디렉터리ì—서 “%sâ€ì„(를) ì§€ì •í•˜ëŠ”ë° ì‹¤íŒ¨" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "현재 ë””ë ‰í„°ë¦¬ì˜ â€œ%s†지정 실패" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "알 수 없는 처리 옵션 “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"%s 처리가 요청ë˜ì—ˆìœ¼ë‚˜, %s ì„¤ì •ì´ ë˜ì§€ 않았고, %s ëª…ë ¹ì´ PATHì— ì—†ìŠµë‹ˆë‹¤" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s íŒŒì¼ ì½ëŠ” 중 오류: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "%s íŒŒì¼ ì••ì¶• 중 오류" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s> 안ì—는 문ìžê°€ 들어갈 수 없습니다" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "프로그램 ë²„ì „ì„ í‘œì‹œí•˜ê³  ë납니다" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "출력 파ì¼ì˜ ì´ë¦„" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "FILEì— ì°¸ì¡°ëœ íŒŒì¼ì„ ì½ì–´ë“¤ì¼ 디렉터리 (기본값: 현재 디렉터리)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "<디렉터리>" + +# 주ì˜: 옵션 설명 - 문장으로 번역 +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "ëŒ€ìƒ íŒŒì¼ ì´ë¦„ 확장ìžì— ë”°ë¼ ì„ íƒí•œ 형ì‹ìœ¼ë¡œ ì¶œë ¥ì„ ìƒì„±í•©ë‹ˆë‹¤" + +# 주ì˜: 옵션 설명 - 문장으로 번역 +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "소스 í—¤ë”를 ìƒì„±í•©ë‹ˆë‹¤" + +# 주ì˜: 옵션 설명 - 문장으로 번역 +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "리소스 파ì¼ì— ì—°ê²°í•˜ëŠ”ë° ì‚¬ìš©í•˜ëŠ” 소스 코드를 ì½”ë“œì— ìƒì„±í•©ë‹ˆë‹¤" + +# 주ì˜: 옵션 설명 - 문장으로 번역 +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "ì˜ì¡´ì„± 목ë¡ì„ ìƒì„±í•©ë‹ˆë‹¤" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "ìƒì„±í•  ì˜ì¡´ì„± 파ì¼ì˜ ì´ë¦„" + +# makefileì˜ .PHONY targetì„ ë§í•¨ +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "만들어진 ì˜ì¡´ì„± 파ì¼ì— í¬ë‹ˆ íƒ€ê²Ÿì´ ë“¤ì–´ê°‘ë‹ˆë‹¤" + +# 주ì˜: 옵션 설명 - 문장으로 번역 +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "ìžì›ì„ ìžë™ìœ¼ë¡œ 만들고 등ë¡í•˜ì§€ 않습니다" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "함수를 ë‚´ë³´ë‚´ì§€ 않고, G_GNU_INTERNAL로 선언합니다" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"C 파ì¼ì— 리소스 ë°ì´í„°ë¥¼ 내장하지 않고, ì™¸ë¶€ì— ë§í¬ë˜ì–´ 있다고 가정합니다" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C ì‹ë³„ìž ì´ë¦„ì€ ìƒì„±í•œ ì†ŒìŠ¤ì½”ë“œì— ëŒ€í•´ 사용합니다" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "타겟 C 컴파ì¼ëŸ¬ (기본값: CC 환경 변수)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"ìžì› 명세를 ìžì› 파ì¼ë¡œ 컴파ì¼í•©ë‹ˆë‹¤.\n" +"ìžì› 명세 파ì¼ì€ .gresource.xml 확장ìžë¥¼ 지니며,\n" +"ìžì› 파ì¼ì€ .gresourceë¼ëŠ” 확장ìžë¥¼ 지닙니다." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "정확히 íŒŒì¼ ì´ë¦„ì„ í•˜ë‚˜ 지정해야 합니다\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "ë³„ëª…ì€ ìµœì†Œ 2ê¸€ìž ì´ìƒì´ì–´ì•¼ 합니다" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "ìˆ«ìž ê°’ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " 태그가 ì´ë¯¸ 있습니다" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' ì†ì„±ì´ ì´ë¯¸ 있습니다" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "플래그 ê°’ì€ ìµœì†Œí•œ 1비트 세트가 들어 있어야 합니다" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> íƒœê·¸ì— ìµœì†Œ í•˜ë‚˜ì˜ íƒœê·¸ê°€ 들어 있어야 합니다" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> 태그가 지정한 범위 ì•ˆì— ë“¤ì–´ìžˆì§€ 않습니다" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> 태그는 지정한 열거형 íƒ€ìž…ì˜ ì˜¬ë°”ë¥¸ 멤버가 아닙니다" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> íƒœê·¸ì— ì§€ì •í•œ 플래그 íƒ€ìž…ì´ ì•„ë‹Œ 문ìžì—´ì´ 들어 있습니다" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> íƒœê·¸ì— ì— ë“¤ì–´ìžˆì§€ ì•Šì€ ë¬¸ìžì—´ì´ 들어 있습니다" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr "ê°€ ì´ í‚¤ì— ëŒ€í•´ ì´ë¯¸ 지정ë˜ì—ˆìŠµë‹ˆë‹¤." + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "는 “%sâ€ íƒ€ìž…ì˜ í‚¤ì— ëŒ€í•´ 허용ë˜ì§€ 않습니다" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "ì—서 ì§€ì •ëœ ìµœì†Œê°’ì´ ìµœëŒ€ê°’ë³´ë‹¤ í½ë‹ˆë‹¤" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "ì§€ì›í•˜ì§€ 않는 L10N 분류: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "L10Nì„ ìš”ì²­í–ˆì§€ë§Œ, gettext ë„ë©”ì¸ì„ 지정하지 않았습니다" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "L10Nì„ ì‚¬ìš©í•˜ì§€ 않고 ê°’ì— ë²ˆì—­ 컨í…스트를 지정했습니다" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "íƒ€ìž…ì´ â€œ%sâ€ì¸ ê°’ì„ íŒŒì‹±í•˜ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "는 열거형 íƒ€ìž…ì´ ìžˆë‹¤ê³  í‘œì‹œëœ í‚¤ì— ëŒ€í•´ ì§€ì •ë  ìˆ˜ 없습니다" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr "ì´ í‚¤ì— ëŒ€í•´ ê°€ ì´ë¯¸ 지정ë˜ì–´ 있습니다" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "“%sâ€ íƒ€ìž…ì¸ í‚¤ì— ëŒ€í•´ 는 허용ë˜ì§€ 않습니다" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " 태그를 ì´ë¯¸ 지정했습니다" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " 태그ì—는 최소 í•˜ë‚˜ì˜ íƒœê·¸ê°€ 들어 있어야 합니다" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr "를 ì´ í‚¤ì— ëŒ€í•´ ì´ë¯¸ 지정했습니다" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +"는 열거형ì´ë‚˜ 플래그 íƒ€ìž…ì˜ í‚¤ì— ëŒ€í•´ì„œ, ë˜ëŠ” 다ìŒì—ë§Œ ì§€" +"ì •í•  수 있습니다." + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" 태그가 지정ë˜ì—ˆì§€ë§Œ “%sâ€ì´(ê°€) ì´ë¯¸ 열거형 íƒ€ìž…ì˜ ë©¤ë²„ìž…" +"니다" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" 태그가 있지만 태그가 ì´ë¯¸ 있습니다" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " 태그가 ì´ë¯¸ 있습니다" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "참조 대ìƒì¸ “%sâ€ì€(는) 열거형 íƒ€ìž…ì´ ì•„ë‹™ë‹ˆë‹¤" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "참조 대ìƒì¸ “%sâ€ì´(ê°€) ì•ˆì— ì—†ìŠµë‹ˆë‹¤" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "ì— ìµœì†Œ í•˜ë‚˜ì˜ ê°€ 들어 있어야 합니다" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "빈 ì´ë¦„ì€ í—ˆìš©í•˜ì§€ 않습니다" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "ìž˜ëª»ëœ ì´ë¦„ “%sâ€: 소문ìžë¡œ 시작해야 합니다" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"ìž˜ëª»ëœ ì´ë¦„ “%sâ€: “%c†문ìžê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤. 소문ìž, 숫ìž, 빼기 문ìž(“-â€)ë§Œ " +"허용합니다." + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "ìž˜ëª»ëœ ì´ë¦„ “%sâ€: ë‘ ê°œ ì—°ì†ëœ 빼기 기호는 (“--â€) 허용하지 않습니다." + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "ìž˜ëª»ëœ ì´ë¦„ “%sâ€: 마지막 문ìžë¡œ 빼기 기호는 (“-â€) 안ë©ë‹ˆë‹¤." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "ìž˜ëª»ëœ ì´ë¦„ “%sâ€: 최대 길ì´ëŠ” 1024입니다" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " 태그를 ì´ë¯¸ 지정했습니다" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "“list-ofâ€ ìŠ¤í‚¤ë§ˆì— í‚¤ë¥¼ 추가할 수 없습니다" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " 태그가 ì´ë¯¸ 있습니다" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" 태그는 태그를( 스키마) ê°ì¶¥ë‹ˆ" +"다. ê°’ì„ ìˆ˜ì •í•˜ë ¤ë©´ 태그를 사용하십시오" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"ì˜ ì†ì„±ìœ¼ë¡œ “typeâ€, “enumâ€, “flagsâ€ ì¤‘ì— ì •í™•ížˆ 하나를 지정해야 합니다" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> 태그를(ì•„ì§) ì •ì˜í•˜ì§€ 않았습니다." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "GVariant í˜•ì‹ ë¬¸ìžì—´(“%sâ€)ì´ ì˜¬ë°”ë¥´ì§€ 않습니다" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " 태그가 있지만 스키마는 아무 ê²ƒë„ í™•ìž¥í•˜ì§€ 않습니다" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "ë®ì–´ì“¸ 태그가 없습니다" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " 태그가 ì´ë¯¸ 있습니다" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " 태그가 ì´ë¯¸ 있습니다" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " 태그는 ì•„ì§ ì—†ëŠ” “%s†스키마를 확장합니다" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " 태그는 ì•„ì§ ì—†ëŠ” “%sâ€ ìŠ¤í‚¤ë§ˆì˜ ëª©ë¡ìž…니다" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "경로가 있는 ìŠ¤í‚¤ë§ˆì˜ ëª©ë¡ì€ 있으면 안 ë©ë‹ˆë‹¤" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "경로가 있는 스키마를 확장할 수 없습니다" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" 태그는 목ë¡ì´ 아닌 스키마를 확장하는 목ë¡ìž…" +"니다" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" 태그는 스키마를 " +"확장하지만, “%sâ€ì€(는) “%sâ€ì„(를) 확장하지 않습니다." + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "경로를 지정할 경우 슬래시로 시작하고 ë나야 합니다" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "목ë¡ì˜ 경로는 “:/â€ë¡œ ë나야 합니다" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"주ì˜: “%sâ€ ìŠ¤í‚¤ë§ˆì— â€œ%s†경로가 있습니다. “/apps/â€, “/desktop/†ë˜ëŠ” “/" +"system/â€ìœ¼ë¡œ 시작하는 경로는 ì‚¬ìš©ì´ ì¤‘ì§€ë  ì˜ˆì •ìž…ë‹ˆë‹¤." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> 태그가 ì´ë¯¸ 있습니다" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "<%2$s> 안ì—는 <%1$s> 요소를 하나만 쓸 수 있습니다" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "<%s> 요소는 최ìƒìœ„ì— ì‚¬ìš©í•  수 없습니다" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr " 엘리먼트가 ì— í•„ìš”í•©ë‹ˆë‹¤" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "<%s> 안ì—는 문ìžê°€ 들어갈 수 없습니다" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "주ì˜: ì— ì •ì˜ë˜ì§€ ì•Šì€ ì°¸ì¡°" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict ì˜µì…˜ì„ ì§€ì •í–ˆìŠµë‹ˆë‹¤. ë냅니다." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "ì´ íŒŒì¼ ì „ì²´ë¥¼ 무시합니다." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "ì´ íŒŒì¼ì„ 무시합니다." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"“%s†키가 “%sâ€ ìŠ¤í‚¤ë§ˆì— ì—†ìŠµë‹ˆë‹¤ (오버ë¼ì´ë“œ íŒŒì¼ â€œ%sâ€). ì´ í‚¤ì— ëŒ€í•œ 오버ë¼" +"ì´ë“œë¥¼ 무시합니다." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"“%s†키가 “%sâ€ ìŠ¤í‚¤ë§ˆì— ì—†ê³  (오버ë¼ì´ë“œ íŒŒì¼ â€œ%sâ€), --strict ì˜µì…˜ì„ ì§€ì •í–ˆìœ¼" +"므로 ë납니다." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"지역화 키 “%sâ€ì— (스키마 “%sâ€, 오버ë¼ì´ë“œ íŒŒì¼ â€œ%sâ€) 대한 ë°ìФí¬í†±ë³„ 오버ë¼ì´" +"드를 제공할 수 없습니다. ì´ í‚¤ì— ëŒ€í•œ 오버ë¼ì´ë“œë¥¼ 무시합니다." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"지역화 키 “%sâ€ì— (스키마 “%sâ€, 오버ë¼ì´ë“œ íŒŒì¼ â€œ%sâ€) 대한 ë°ìФí¬í†±ë³„ 오버ë¼ì´" +"드를 제공할 수 없고, --strict ì˜µì…˜ì„ ì§€ì •í–ˆìœ¼ë¯€ë¡œ ë납니다." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"“%s†키를 (“%s†스키마) í•´ì„í•˜ëŠ”ë° ì˜¤ë¥˜ (오버ë¼ì´ë“œ íŒŒì¼ â€œ%sâ€): %s. ì´ í‚¤ì— " +"대한 오버ë¼ì´ë“œë¥¼ 무시합니다." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"“%s†키를 (“%s†스키마) í•´ì„í•˜ëŠ”ë° ì˜¤ë¥˜ (오버ë¼ì´ë“œ íŒŒì¼ â€œ%sâ€): %s. --strict " +"ì˜µì…˜ì„ ì§€ì •í–ˆìœ¼ë¯€ë¡œ ë납니다." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"오버ë¼ì´ë“œ íŒŒì¼ â€œ%3$sâ€, “%2$sâ€ ìŠ¤í‚¤ë§ˆì˜ â€œ%1$s†키 오버ë¼ì´ë“œëŠ” 주어진 스키마" +"ì˜ ë²”ìœ„ì—서 벗어납니다. ì´ í‚¤ì— ëŒ€í•œ 오버ë¼ì´ë“œë¥¼ 무시합니다." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"ë®ì–´ 쓸 íŒŒì¼ â€œ%3$sâ€, “%2$sâ€ ìŠ¤í‚¤ë§ˆì˜ â€œ%1$s†키 오버ë¼ì´ë“œëŠ” 주어진 ìŠ¤í‚¤ë§ˆì˜ " +"범위ì—서 벗어나고, --strict ì˜µì…˜ì„ ì§€ì •í–ˆìœ¼ë¯€ë¡œ ë납니다." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"오버ë¼ì´ë“œ íŒŒì¼ â€œ%3$sâ€, “%2$sâ€ ìŠ¤í‚¤ë§ˆì˜ â€œ%1$s†키는 올바른 ê°’ 중 하나가 ì•„ë‹™" +"니다. ì´ í‚¤ì— ëŒ€í•œ 오버ë¼ì´ë“œë¥¼ 무시합니다." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"오버ë¼ì´ë“œ íŒŒì¼ â€œ%3$sâ€, “%2$sâ€ ìŠ¤í‚¤ë§ˆì˜ â€œ%1$s†키는 올바른 ê°’ 중 하나가 아니" +"ê³ , --strict ì˜µì…˜ì„ ì§€ì •í–ˆìœ¼ë¯€ë¡œ ë납니다." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "gschemas.compiled 파ì¼ì„ 저장할 위치" + +# 옵션 설명 +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "ìŠ¤í‚¤ë§ˆì— ì˜¤ë¥˜ê°€ 하나ë¼ë„ 있으면 중지합니다" + +# 옵션 설명 +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled 파ì¼ì„ ì“°ì§€ 않습니다" + +# 옵션 설명 +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "키 ì´ë¦„ì„ ì œí•œí•˜ì§€ 않습니다" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"모든 GSettings 스키마 파ì¼ì„ 스키마 ìºì‹œ 하나로 컴파ì¼í•©ë‹ˆë‹¤.\n" +"스키마 íŒŒì¼ í™•ìž¥ìžëŠ” .schema.xmlì´ì–´ì•¼ 하고,\n" +"ìºì‹œ íŒŒì¼ ì´ë¦„ì€ gschemas.compileì´ì–´ì•¼ 합니다." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "정확히 디렉터리 ì´ë¦„ì„ í•˜ë‚˜ 지정해야 합니다" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "스키마 파ì¼ì´ 없습니다: 아무 ê²ƒë„ í•˜ì§€ 않습니다." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "스키마 파ì¼ì´ 없습니다: 현재 출력 파ì¼ì„ 제거합니다." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "ìž˜ëª»ëœ íŒŒì¼ ì´ë¦„ %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "%sì˜ íŒŒì¼ ì‹œìŠ¤í…œ 정보를 가져오는 중 오류: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "%s 파ì¼ì´ 들어 있는 마운트가 없습니다" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "루트 ë””ë ‰í„°ë¦¬ì˜ ì´ë¦„ì„ ë°”ê¿€ 수 없습니다" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "%s 파ì¼ì˜ ì´ë¦„ 바꾸는 중 오류: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "íŒŒì¼ ì´ë¦„ì„ ë°”ê¿€ 수 없습니다. 파ì¼ì´ ì´ë¯¸ 있습니다" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "ìž˜ëª»ëœ íŒŒì¼ ì´ë¦„" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "%s 파ì¼ì„ 여는 중 오류: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "%s íŒŒì¼ ì œê±°í•˜ëŠ” 중 오류: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "%s íŒŒì¼ ë²„ë¦¬ëŠ” 중 오류: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "휴지통 디렉터리(%s)를 만들 수 없습니다: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "%s íœ´ì§€í†µì˜ ìƒìœ„ 디렉터리를 ì°¾ì„ ìˆ˜ 없습니다" + +# reflink/cloneì€ btrfsì—서 임시 복사하는 걸 ë§í•œë‹¤ +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "시스템 ë‚´ë¶€ ë§ˆìš´íŠ¸ì— ëŒ€í•´ íœ´ì§€í†µì€ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "%s 휴지통 디렉터리를 (%s 버리기) ì°¾ì„ ìˆ˜ 없거나 만들 수 없습니다" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "%sì— ëŒ€í•œ 휴지통 ì •ë³´ 파ì¼ì„ 만들 수 없습니다: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "%s 파ì¼ì„ íŒŒì¼ ì‹œìŠ¤í…œ 경계를 넘어서서 버릴 수 없습니다" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "%s 파ì¼ì„ 버릴 수 없습니다: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "%s 파ì¼ì„ 버릴 수 없습니다" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "%s 디렉터리를 만드는 중 오류: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "íŒŒì¼ ì‹œìŠ¤í…œì´ ì‹¬ë³¼ë¦­ ë§í¬ë¥¼ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "%s 심볼릭 ë§í¬ë¥¼ 만드는 중 오류: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "%s íŒŒì¼ ì˜®ê¸°ëŠ” 중 오류: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "디렉터리를 ë®ì–´ ì¨ì„œ 디렉터리를 옮길 수 없습니다" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "백업 íŒŒì¼ ë§Œë“¤ê¸°ê°€ 실패했습니다" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "ëŒ€ìƒ íŒŒì¼ì„ 제거하는 중 오류: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "다른 마운트 사ì´ì— 옮기기는 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%sì˜ ë””ìŠ¤í¬ ì‚¬ìš©ëŸ‰ì„ ì•Œì•„ë‚¼ 수 없습니다: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "ì†ì„± ê°’ì€ NULLì´ ì•„ë‹ˆì–´ì•¼ 합니다" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "ìž˜ëª»ëœ ì†ì„± í˜•ì‹ (문ìžì—´ í•„ìš”)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "ìž˜ëª»ëœ í™•ìž¥ ì†ì„± ì´ë¦„" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "확장 ì†ì„± “%s†설정 중 오류: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (ìž˜ëª»ëœ ì¸ì½”딩)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "“%sâ€ íŒŒì¼ ì •ë³´ë¥¼ 가져오는 중 오류: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "íŒŒì¼ ì„œìˆ ìž ì •ë³´ë¥¼ 가져오는 중 오류: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "ìž˜ëª»ëœ ì†ì„± í˜•ì‹ (uint32 í•„ìš”)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "ìž˜ëª»ëœ ì†ì„± í˜•ì‹ (uint64 í•„ìš”)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "ìž˜ëª»ëœ ì†ì„± í˜•ì‹ (ë°”ì´íЏ 문ìžì—´ í•„ìš”)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "심볼릭 ë§í¬ì—는 ê¶Œí•œì„ ì„¤ì •í•  수 없습니다" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "권한 설정 중 오류: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "ì†Œìœ ìž ì„¤ì • 중 오류: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "심볼릭 ë§í¬ëŠ” NULLì´ ì•„ë‹ˆì–´ì•¼ 합니다" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "심볼릭 ë§í¬ 설정 중 오류: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "심볼릭 ë§í¬ 설정 중 오류: 파ì¼ì´ 심볼릭 ë§í¬ê°€ 아닙니다" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "유닉스 타임스탬프 %2$lldì— ëŒ€í•´ 추가 나노초 %1$d ê°’ì´ ìŒìˆ˜ìž…니다" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"유닉스 타임스탬프 %2$lldì— ëŒ€í•´ 추가 나노초 %1$d ê°’ì´ 1ì´ˆì— ë„달했습니다" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "유닉스 타임스탬프 %lld ê°’ì´ 64ë¹„íŠ¸ì— ë“¤ì–´ê°€ì§€ 않습니다" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "유닉스 타임스탬프 %lld ê°’ì´ ìœˆë„ìš°ì—서 ì§€ì›í•˜ëŠ” 범위 ë°–ì— ìžˆìŠµë‹ˆë‹¤" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "“%s†파ì¼ì´ë¦„ì„ UTF-16으로 변환할 수 없습니다." + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "“%s†파ì¼ì„ ì—´ 수 없습니다: 윈ë„ìš° 오류 %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "“%s†파ì¼ì— 대해 수정 ì‹œê° ë˜ëŠ” ì ‘ê·¼ ì‹œê° ì„¤ì •ì— ì˜¤ë¥˜: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "수정 시ê°ì´ë‚˜ ì ‘ê·¼ 시ê°ì„ ì„¤ì •í•˜ëŠ”ë° ì˜¤ë¥˜: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux 컨í…스트는 NULLì´ ì•„ë‹ˆì–´ì•¼ 합니다" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "ì´ ì‹œìŠ¤í…œì€ SELinux를 사용하지 않습니다" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux 컨í…스트 설정 중 오류: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s ì†ì„± ì„¤ì •ì€ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "파ì¼ì„ ì½ëŠ” 중 오류: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "파ì¼ì„ 닫는 중 오류: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "파ì¼ì„ íƒìƒ‰í•˜ëŠ” 중 오류: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "기본 로컬 íŒŒì¼ ê°ì‹œìž 형ì‹ì„ ì°¾ì„ ìˆ˜ 없습니다" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "파ì¼ì— 쓰는 중 오류: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "예전 백업 ë§í¬ë¥¼ 제거하는 중 오류: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "백업 ì‚¬ë³¸ì„ ë§Œë“œëŠ” 중 오류: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "임시 파ì¼ì˜ ì´ë¦„ì„ ë°”ê¾¸ëŠ” 오류: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "파ì¼ì„ ìžë¥´ëŠ” 중 오류: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "“%s†파ì¼ì„ 여는 중 오류: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "ëŒ€ìƒ íŒŒì¼ì´ 디렉터리입니다" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "ëŒ€ìƒ íŒŒì¼ì´ ì¼ë°˜ 파ì¼ì´ 아닙니다" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "파ì¼ì´ 외부ì—서 바뀌었습니다" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "예전 파ì¼ì„ 제거하는 중 오류: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "ìž˜ëª»ëœ GSeekTypeì´ ì£¼ì–´ì¡ŒìŠµë‹ˆë‹¤" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "ìž˜ëª»ëœ íƒìƒ‰ 요청" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStreamì€ ìžë¥¼ 수 없습니다" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "메모리 출력 ìŠ¤íŠ¸ë¦¼ì€ í¬ê¸°ë¥¼ 바꿀 수 없습니다" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "출력 ìŠ¤íŠ¸ë¦¼ì˜ í¬ê¸°ë¥¼ ë°”ê¾¸ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "쓰기를 ì²˜ë¦¬í•˜ëŠ”ë° í•„ìš”í•œ 메모리 ìš©ëŸ‰ì´ ë¹ˆ 공간보다 ë” í½ë‹ˆë‹¤" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "요청한 íŒŒì¼ ì´ë™ 위치가 ìŠ¤íŠ¸ë¦¼ì˜ ë§¨ 앞보다 ë” ì•žìª½ìž…ë‹ˆë‹¤" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "요청한 íŒŒì¼ ì´ë™ 위치가 ìŠ¤íŠ¸ë¦¼ì˜ ë§¨ 뒤보다 ë” ë’¤ìª½ìž…ë‹ˆë‹¤" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "마운트가 “unmountâ€ ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "마운트가 “ejectâ€ ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"마운트가 “unmountâ€ í˜¹ì€ â€œunmount_with_operationâ€ ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"마운트가 “ejectâ€ í˜¹ì€ â€œeject_with_operationâ€ ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "마운트가 “remountâ€ ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "마운트가 컨í…트 타입 íŒë³„ ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "마운트가 ë™ê¸°ì‹ 컨í…트 타입 íŒë³„ ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "“%s†호스트 ì´ë¦„ì— â€œ[†괄호가 ìžˆëŠ”ë° â€œ]†괄호가 없습니다" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "ë„달할 수 없는 네트워í¬" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "ë„달할 수 없는 호스트" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "ë„¤íŠ¸ì›Œí¬ ê°ì‹œìžë¥¼ 만들 수 없습니다: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "ë„¤íŠ¸ì›Œí¬ ê°ì‹œìžë¥¼ 만들 수 없습니다:" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "ë„¤íŠ¸ì›Œí¬ ìƒíƒœë¥¼ 가져올 수 없습니다:" + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager 실행 ì¤‘ì´ ì•„ë‹™ë‹ˆë‹¤" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager ë²„ì „ì´ ë„ˆë¬´ 오래 ë습니다" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "출력 ìŠ¤íŠ¸ë¦¼ì´ write를 구현하지 않았습니다" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "%sì— ì „ë‹¬ëœ ë²¡í„°ì˜ í•©ì´ ë„ˆë¬´ í½ë‹ˆë‹¤" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "ì›ë³¸ ìŠ¤íŠ¸ë¦¼ì„ ì´ë¯¸ 닫았습니다" + +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "“%sâ€ì˜ 주소를 알아내는 ë° ì˜¤ë¥˜: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s ê¸°ëŠ¥ì´ êµ¬í˜„ë˜ì§€ 않았습니다" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "ìž˜ëª»ëœ ë„ë©”ì¸" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "“%sâ€ ìœ„ì¹˜ì˜ ìžì›ì´ 없습니다" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "“%sâ€ ìœ„ì¹˜ì˜ ìžì›ì— 대해 ì••ì¶•ì„ í‘¸ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "“%sâ€ ìœ„ì¹˜ì˜ ìžì›ì€ 디렉터리가 아닙니다" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "ìž…ë ¥ ìŠ¤íŠ¸ë¦¼ì— íƒìƒ‰ì„ 구현하지 않았습니다" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "elf 파ì¼ì— 들어있는 ìžì›ì˜ 섹션 나열" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"ìžì›ì„ 나열합니다\n" +"<섹션>ì´ ì£¼ì–´ì¡Œë‹¤ë©´ ì´ ì„¹ì…˜ì— ìžˆëŠ” ìžì›ë§Œ 나열합니다\n" +"<경로>ê°€ 주어졌다면 ì¼ì¹˜í•˜ëŠ” ìžì›ë§Œ 나열합니다" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "<파ì¼> [<경로>]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "<섹션>" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"ìžì›ì„ 세부ì ìœ¼ë¡œ 나열합니다\n" +"<섹션>ì´ ì£¼ì–´ì¡Œë‹¤ë©´ ì´ ì„¹ì…˜ì˜ ìžì›ë§Œ 나열합니다\n" +"<경로>ê°€ 주어졌다면 ì¼ì¹˜í•˜ëŠ” ìžì›ë§Œ 나열합니다\n" +"세부사항ì—는 섹션, í¬ê¸°, ì••ì¶•ì´ ìžˆìŠµë‹ˆë‹¤" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "ìžì› 파ì¼ì„ stdout으로 추출하기" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "<íŒŒì¼ ê²½ë¡œ>" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Usage:\n" +" gresource [--section <섹션>] <명령> [<ì¸ìˆ˜>…]\n" +"\n" +"명령:\n" +" help ì´ ì •ë³´ë¥¼ ë³´ì—¬ì¤ë‹ˆë‹¤\n" +" sections ìžì› ì„¹ì…˜ì„ ë‚˜ì—´í•©ë‹ˆë‹¤\n" +" list ìžì›ì„ 나열합니다\n" +" details ìžì›ì„ 세부ì ìœ¼ë¡œ 나열합니다\n" +" extract ìžì›ì„ 추출합니다\n" +"\n" +"ìžì„¸í•œ ë„움ë§ì„ 보려면 “gresource help <명령>â€ ëª…ë ¹ì„ ì‹¤í–‰í•˜ì‹­ì‹œì˜¤.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"사용법:\n" +" gsettings %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " <섹션> (추가ì ) ELF 섹션 ì´ë¦„\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " <명령> 설명할 명령어(옵션)\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " <파ì¼> ELF 파ì¼(ë°”ì´ë„ˆë¦¬ í˜¹ì€ ê³µìœ  ë¼ì´ë¸ŒëŸ¬ë¦¬)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" <파ì¼> ELF 파ì¼(ë°”ì´ë„ˆë¦¬ í˜¹ì€ ê³µìœ  ë¼ì´ë¸ŒëŸ¬ë¦¬)\n" +" í˜¹ì€ ì»´íŒŒì¼í•œ ìžì› 파ì¼\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[<경로>]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " <경로> (추가ì ) ìžì› 경로(부분ì ì¼ 수 있ìŒ)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "<경로>" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " <경로> ìžì› 경로\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "“%s†스키마가 없습니다\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "“%s†스키마는 ì´ë™ 가능하지 않습니다 (경로를 지정해서는 안 ë©ë‹ˆë‹¤)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "“%s†스키마는 ì´ë™ 가능합니다 (경로를 지정해야 합니다)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "빈 경로를 지정했습니다.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "경로는 슬래시(/)로 시작해야 합니다\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "경로는 슬래시(/)로 ë나야 합니다\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "경로ì—는 ë‘ ê°œì˜ ì—°ì†ëœ 슬래시(//)ê°€ 들어 있어서는 안 ë©ë‹ˆë‹¤\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "지정한 ê°’ì´ ì˜¬ë°”ë¥¸ 범위ì—서 벗어납니다\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "키를 쓸 수 없습니다\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "설치한(ì´ë™ 가능하지 않ì€) ìŠ¤í‚¤ë§ˆì˜ ëª©ë¡ì„ 표시합니다" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "설치한 ì´ë™ 가능한 ìŠ¤í‚¤ë§ˆì˜ ëª©ë¡ì„ 표시합니다" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "<스키마>ì˜ í‚¤ 목ë¡ì„ 표시합니다" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "<스키마>[:<경로>]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "<스키마>ì˜ í•˜ìœ„ í•­ëª©ì˜ ëª©ë¡ì„ 표시합니다" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"키와 ê°’ì˜ ëª©ë¡ì„ 재귀ì ìœ¼ë¡œ 표시합니다.\n" +"<스키마>ê°€ 없으면 모든 키를 표시합니다.\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[<스키마>[:<경로>]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "<키>ì˜ ê°’ì„ ê°€ì ¸ì˜µë‹ˆë‹¤" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "<스키마>:[<경로>] <키>" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "<키>ì— ëŒ€í•œ 올바른 ê°’ì˜ ë²”ìœ„ë¥¼ 찾아 봅니다" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "<키>ì— ëŒ€í•œ ì„¤ëª…ì„ ì°¾ì•„ 봅니다" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "<키>ì˜ ê°’ì„ <ê°’>으로 설정합니다" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "<스키마>:[<경로>] <키> <ê°’>" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "<키>ì˜ ê°’ì„ ê¸°ë³¸ê°’ìœ¼ë¡œ 초기화합니다" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "<스키마>ì— ìžˆëŠ” 모든 í‚¤ì˜ ê°’ì„ ê¸°ë³¸ê°’ìœ¼ë¡œ 초기화합니다" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "<키>ê°€ 쓰기 가능한지 검사합니다" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"<키>ê°€ 바뀌는 ì‚¬í•­ì„ ê°ì‹œí•©ë‹ˆë‹¤.\n" +"<키>를 지정하지 않으면, <스키마>ì˜ ëª¨ë“  키를 ê°ì‹œí•©ë‹ˆë‹¤.\n" +"ê°ì‹œë¥¼ 중단하려면 ^C를 누르십시오.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "<스키마>[:<경로>] [<키>]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"사용법:\n" +" gsettings --version\n" +" gsettings [--schemadir <스키마 경로>] <명령> [<ì¸ìˆ˜>…]\n" +"\n" +"명령:\n" +" help ì´ ì •ë³´ë¥¼ 표시합니다\n" +" list-schemas 설치한 스키마 목ë¡ì„ 표시합니다\n" +" list-relocatable-schemas ì´ë™ 가능한 스키마 목ë¡ì„ 표시합니다\n" +" list-keys ìŠ¤í‚¤ë§ˆì˜ í‚¤ 목ë¡ì„ 표시합니다\n" +" list-children ìŠ¤í‚¤ë§ˆì˜ í•˜ìœ„ 항목 목ë¡ì„ 표시합니다\n" +" list-recursively 키와 ê°’ 목ë¡ì„ 재귀ì ìœ¼ë¡œ 표시합니다\n" +" range í‚¤ì˜ ë²”ìœ„ë¥¼ 알아봅니다\n" +" describe í‚¤ì˜ ì„¤ëª…ì„ ì•Œì•„ë´…ë‹ˆë‹¤\n" +" get í‚¤ì˜ ê°’ì„ ê°€ì ¸ì˜µë‹ˆë‹¤\n" +" set í‚¤ì˜ ê°’ì„ ì„¤ì •í•©ë‹ˆë‹¤\n" +" reset í‚¤ì˜ ê°’ì„ ì´ˆê¸°í™”í•©ë‹ˆë‹¤\n" +" reset-recursively í‚¤ì˜ ê°’ì„ ìž¬ê·€ì ìœ¼ë¡œ 초기화합니다\n" +" writable 키가 쓰기 가능한지 검사합니다\n" +" monitor 바뀌는 ì‚¬í•­ì„ ê°ì‹œí•©ë‹ˆë‹¤\n" +"\n" +"ìžì„¸í•œ ë„움ë§ì„ 보려면 “gsettings help <명령>â€ ëª…ë ¹ì„ ì‹¤í–‰í•˜ì‹­ì‹œì˜¤.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"사용법:\n" +" gsettings [--schemadir <스키마 경로>] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " <스키마 경로> 추가ì ì¸ 스키마를 검색하려는 디렉터리\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" <스키마> ìŠ¤í‚¤ë§ˆì˜ ì´ë¦„\n" +" <경로> 경로, ì´ë™ 가능한 ìŠ¤í‚¤ë§ˆì˜ ê²½ìš°\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " <키> 스키마 ì•ˆì˜ í‚¤(옵션)\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " <키> 스키마 ì•ˆì˜ í‚¤\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " <ê°’> 설정할 ê°’\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "“%sâ€ì—서 스키마를 ì½ì–´ë“¤ì¼ 수 없습니다: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "스키마를 설치하지 않았습니다\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "지정한 스키마 ì´ë¦„ì´ ë¹ˆ 문ìžì—´ìž…니다\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "“%s†키가 없습니다\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "올바른 ì†Œì¼“ì´ ì•„ë‹™ë‹ˆë‹¤. 초기화ë˜ì§€ 않았습니다" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "올바른 ì†Œì¼“ì´ ì•„ë‹™ë‹ˆë‹¤. 초기화가 ë‹¤ìŒ ì´ìœ ë¡œ 실패했습니다: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "ì†Œì¼“ì„ ì´ë¯¸ 닫았습니다" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "소켓 입출력 시간 ì œí•œì´ ë„˜ì—ˆìŠµë‹ˆë‹¤" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "íŒŒì¼ ì„œìˆ ìžì—서 GSocketì„ ë§Œë“œëŠ” 중: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "알 수 없는 ê³„ì—´ì„ ì§€ì •í–ˆìŠµë‹ˆë‹¤" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "알 수 없는 í”„ë¡œí† ì½œì„ ì§€ì •í–ˆìŠµë‹ˆë‹¤" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "ë°ì´í„°ê·¸ëž¨ ìš©ë„ê°€ 아닌 ì†Œì¼“ì— ë°ì´í„°ê·¸ëž¨ ë™ìž‘ì„ ìˆ˜í–‰í•  수 없습니다." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "ì œí•œì‹œê°„ì„ ì„¤ì •í•œ ì†Œì¼“ì— ë°ì´í„°ê·¸ëž¨ ë™ìž‘ì„ ìˆ˜í–‰í•  수 없습니다." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "로컬 주소를 알아낼 수 없습니다: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "ì›ê²© 주소를 알아낼 수 없습니다: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "ì—°ê²°ì„ ë°›ì„ ìˆ˜ 없습니다: %s" + +# NOTE: bind(2)를 뜻함 +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "%s ì£¼ì†Œì— ë°”ì¸ë“œí•˜ëŠ”ë° ì˜¤ë¥˜: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "멀티ìºìŠ¤íŠ¸ ê·¸ë£¹ì— ì°¸ì—¬í•˜ëŠ” 중 오류: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "멀티ìºìŠ¤íŠ¸ ê·¸ë£¹ì„ ë‚˜ì˜¤ëŠ” 중 오류: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "소스 지향 멀티ìºìŠ¤íŠ¸ë¥¼ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "소켓 패밀리를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "소스 지향 주소가 IPv4 주소가 아닙니다" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "ì¸í„°íŽ˜ì´ìФ ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "ì¸í„°íŽ˜ì´ìŠ¤ê°€ 없습니다: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "IPv4 소스 지향 멀티ìºìŠ¤íŠ¸ë¥¼ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "IPv6 소스 지향 멀티ìºìŠ¤íŠ¸ë¥¼ ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "ì—°ê²°ì„ ë°›ì•„ë“¤ì´ëŠ”ë° ì˜¤ë¥˜: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "ì—°ê²°ì´ ì§„í–‰ 중입니다" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "밀린 오류를 알아낼 수 없습니다: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "ë°ì´í„°ë¥¼ ë°›ëŠ”ë° ì˜¤ë¥˜: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "ë°ì´í„°ë¥¼ ë³´ë‚´ëŠ”ë° ì˜¤ë¥˜: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ì†Œì¼“ì„ ë‹«ì„ ìˆ˜ 없습니다: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "ì†Œì¼“ì„ ë‹«ëŠ”ë° ì˜¤ë¥˜: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "소켓 ì¡°ê±´ì„ ê¸°ë‹¤ë¦¬ëŠ” 중: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "메시지를 보낼 수 없습니다: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "메시지 벡터가 너무 í½ë‹ˆë‹¤" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "메시지를 보내는 중 오류: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "윈ë„ìš°ì—서는 GSocketControlMessage를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "메시지를 ë°›ëŠ”ë° ì˜¤ë¥˜: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "소켓 암호 ë°ì´í„°ë¥¼ ì½ì„ 수 없습니다: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentialsê°€ ì´ OSì—서 구현ë˜ì§€ 않았습니다" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "프ë¡ì‹œ 서버 %sì— ì—°ê²°í•  수 없습니다: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s(으)로 ì—°ê²°í•  수 없습니다: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "ì—°ê²°í•  수 없습니다: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "TCPê°€ 아닌 프ë¡ì‹œ ì—°ê²°ì€ ì§€ì›í•˜ì§€ 않습니다." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "“%s†프ë¡ì‹œ í”„ë¡œí† ì½œì€ ì§€ì›í•˜ì§€ 않습니다." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "리스너를 ì´ë¯¸ 닫았습니다" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "추가한 ì†Œì¼“ì´ ë‹«í˜”ìŠµë‹ˆë‹¤" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4는 “%s†IPv6 주소를 허용하지 않습니다" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 í”„ë¡œí† ì½œì— ëŒ€í•œ ì‚¬ìš©ìž ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 í”„ë¡œí† ì½œì— ëŒ€í•œ 호스트 ì´ë¦„ “%sâ€ì´(ê°€) 너무 ê¹ë‹ˆë‹¤." + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "ì´ ì„œë²„ëŠ” SOCKSv4 프ë¡ì‹œ 서버가 아닙니다." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 서버를 통한 ì—°ê²°ì´ ê±°ë¶€ë˜ì—ˆìŠµë‹ˆë‹¤." + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "ì´ ì„œë²„ëŠ” SOCKSv5 프ë¡ì‹œ 서버가 아닙니다." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 프ë¡ì‹œì— ì¸ì¦ì´ 필요합니다." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "ì´ SOCKSv5 프ë¡ì‹œëŠ” GLibì´ ì§€ì›í•˜ì§€ 않는 ì¸ì¦ ë°©ì‹ì„ 사용합니다." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 í”„ë¡œí† ì½œì— ëŒ€í•œ ì‚¬ìš©ìž ì´ë¦„ ë˜ëŠ” 암호가 너무 ê¹ë‹ˆë‹¤." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 ì¸ì¦ì´ ìž˜ëª»ëœ ì‚¬ìš©ìž ì´ë¦„ì´ë‚˜ 암호 ë•Œë¬¸ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "SOCKSv5 í”„ë¡œí† ì½œì— ëŒ€í•œ 호스트 ì´ë¦„ “%sâ€ì´(ê°€) 너무 ê¹ë‹ˆë‹¤" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 프로시 서버가 알 수 없는 주소 형ì‹ì„ 사용합니다." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "ë‚´ë¶€ SOCKSv5 프로시 서버 오류." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 ì—°ê²°ì„ ê·œì¹™ì— ë”°ë¼ í—ˆìš©í•˜ì§€ 않습니다." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 프ë¡ì‹œë¥¼ 통해 í˜¸ìŠ¤íŠ¸ì— ì—°ê²°í•  수 없습니다." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 프ë¡ì‹œë¥¼ 통해 네트워í¬ì— ì—°ê²°í•  수 없습니다." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 프ë¡ì‹œë¥¼ 통한 ì—°ê²°ì´ ê±°ë¶€ë˜ì—ˆìŠµë‹ˆë‹¤." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 프ë¡ì‹œê°€ “connectâ€ ëª…ë ¹ì„ ì§€ì›í•˜ì§€ 않습니다." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 프ë¡ì‹œê°€ 해당 주소 형ì‹ì„ ì§€ì›í•˜ì§€ 않습니다." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "알 수 없는 SOCKSv5 프ë¡ì‹œ 오류." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "하위 프로세스와 í†µì‹ ì„ ìœ„í•œ 파ì´í”„를 만드는 중 실패 (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "ì´ í”Œëž«í¼ì—서는 파ì´í”„를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon ì¸ì½”ë”©ì˜ %d ë²„ì „ì„ ì²˜ë¦¬í•  수 없습니다" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "올바른 주소가 없습니다" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "“%sâ€ ì£¼ì†Œì˜ í˜¸ìŠ¤íŠ¸ ì´ë¦„ì„ ì•Œì•„ë‚´ëŠ” ë° ì˜¤ë¥˜: %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "“%sâ€ì— 대한 요청 형ì‹ì— DNS 레코드가 없습니다" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "ì¼ì‹œì ìœ¼ë¡œ “%s†주소를 알아낼 수 없습니다" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "“%sâ€ì˜ 주소를 알아내는 ë° ì˜¤ë¥˜" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "PEM ì¸ì½”ë”©ëœ ê°œì¸ í‚¤ê°€ 없습니다" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM ì¸ì½”ë”©ëœ ê°œì¸ í‚¤ë¥¼ í•´ë…í•  수 없습니다" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM ì¸ì½”ë”©ëœ ê°œì¸ í‚¤ë¥¼ í•´ì„í•  수 없습니다" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "PEM ì¸ì½”ë”©ëœ ì¸ì¦ì„œê°€ 없습니다" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM ì¸ì½”ë”©ëœ ì¸ì¦ì„œë¥¼ í•´ì„í•  수 없습니다" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "현재 TLS 백엔드는 PKCS #12를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "ì´ GTlsBackend는 PKCS #11 ì¸ì¦ì„œ 만들기를 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "ì´ë²ˆì— 암호를 올바르게 입력하지 않으면 ì ‘ê·¼ì´ ë§‰íž™ë‹ˆë‹¤." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "암호 ìž…ë ¥ì´ ì—¬ëŸ¬ 차례 잘못ë˜ì—ˆìŠµë‹ˆë‹¤. ê³„ì† ì‹¤íŒ¨í•˜ë©´ ì ‘ê·¼ì´ ë§‰íž™ë‹ˆë‹¤." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "입력한 암호가 올바르지 않습니다." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "FD 보내기는 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "한 ê°œì˜ ì œì–´ 메시지가 와야 하지만, %d개를 받았습니다" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "예ìƒì¹˜ 못한 ë¶€ì† ë°ì´í„°ì˜ 형ì‹ìž…니다" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "한 ê°œì˜ íŒŒì¼ ì„œìˆ ìžê°€ 와야 하지만, %d개를 받았습니다\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "올바르지 ì•Šì€ íŒŒì¼ ì„œìˆ ìžë¥¼ 받았습니다" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "FD 받기는 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "암호 ë°ì´í„°ë¥¼ ë³´ë‚´ëŠ”ë° ì˜¤ë¥˜: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "ì†Œì¼“ì— SO_PASSCRED를 사용하는지 ê²€ì‚¬í•˜ëŠ”ë° ì˜¤ë¥˜: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED 사용 오류: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "암호 ë°ì´í„° 1ë°”ì´íŠ¸ë¥¼ ì½ì–´ì•¼ 하지만 0ë°”ì´íЏ ì½ìŒ" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "제어 메시지가 올 수 없지만, %d개를 받았습니다" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED 사용 í•´ì œ 오류: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "íŒŒì¼ ì„œìˆ ìžë¡œë¶€í„° ì½ì–´ì˜¤ëŠ” 중 오류: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "íŒŒì¼ ì„œìˆ ìžë¥¼ 닫는 중 오류: %s" + +#: gio/gunixmounts.c:2782 gio/gunixmounts.c:2835 +msgid "Filesystem root" +msgstr "íŒŒì¼ ì‹œìŠ¤í…œ 루트" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "íŒŒì¼ ì„œìˆ ìžì— 쓰는 중 오류: %s" + +# abstract unix domain socket address: 파ì¼ì‹œìŠ¤í…œê³¼ 관계없는 ì†Œì¼“ì„ ë§í•¨ +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "ì¶”ìƒ ìœ ë‹‰ìŠ¤ ë„ë©”ì¸ ì†Œì¼“ 주소는 ì´ ì‹œìŠ¤í…œì—서 ì§€ì›í•˜ì§€ 않습니다" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "ë³¼ë¥¨ì´ eject ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "ë³¼ë¥¨ì´ eject í˜¹ì€ eject_with_operation ê¸°ëŠ¥ì„ êµ¬í˜„í•˜ì§€ 않았습니다" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "핸들ì—서 ì½ëŠ” 중 오류: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "í•¸ë“¤ì„ ë‹«ëŠ” 중 오류: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "í•¸ë“¤ì— ì“°ëŠ” 중 오류: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "메모리가 부족합니다" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "ë‚´ë¶€ 오류: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "ìž…ë ¥ì´ ë” í•„ìš”í•©ë‹ˆë‹¤" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "ìž˜ëª»ëœ ì••ì¶• ë°ì´í„°" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ì—°ê²°ì„ ë°›ì•„ë“¤ì¼ ì£¼ì†Œ" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "GTestDbusì™€ì˜ í˜¸í™˜ì„ ìœ„í•´ 무시합니다" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "주소 출력" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "쉘 모드ì—서 주소 출력" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "dbus 서비스 실행" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "ìž˜ëª»ëœ ì¸ìž\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "예ìƒì¹˜ 못하게 “%2$sâ€ ìš”ì†Œì— '%1$s' ì†ì„±ì´ 있습니다" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "“%2$sâ€ ìš”ì†Œì— â€œ%1$s†ì†ì„±ì´ 없습니다" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "예ìƒì¹˜ 못하게 “%s†태그가 있습니다. “%s†태그가 있어야 합니다" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "예ìƒì¹˜ 못하게 “%2$sâ€ ì•ˆì— â€œ%1$s†태그가 있습니다" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "ë¶ë§ˆí¬ 파ì¼ì—서 ìž˜ëª»ëœ ë‚ ì§œ/ì‹œê° â€˜%s’" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "ë°ì´í„° ë””ë ‰í„°ë¦¬ì— ì˜¬ë°”ë¥¸ ë¶ë§ˆí¬ 파ì¼ì´ 없습니다" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "“%s†URLì— ëŒ€í•œ ë¶ë§ˆí¬ê°€ ì´ë¯¸ 있습니다" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "“%s†URLì— ëŒ€í•œ ë¶ë§ˆí¬ê°€ 없습니다" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "“%s†URLì— ëŒ€í•œ ë¶ë§ˆí¬ì— MIME 형ì‹ì´ 없습니다" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "“%s†URLì— ëŒ€í•œ ë¶ë§ˆí¬ì— ê°œì¸ í”Œëž˜ê·¸ê°€ 없습니다" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "“%s†URLì— ëŒ€í•œ ë¶ë§ˆí¬ì— ê·¸ë£¹ì´ ì„¤ì •ë˜ì–´ 있지 않습니다" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "“%sâ€ì— 대해 ë¶ë§ˆí¬ë¥¼ 등ë¡í•œ “%s†ì´ë¦„ì„ ê°€ì§„ í”„ë¡œê·¸ëž¨ì´ ì—†ìŠµë‹ˆë‹¤" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "URI “%sâ€ì„(를) 사용해 “%s†실행 명령 í™•ìž¥í•˜ê¸°ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "변환 ìž…ë ¥ì— í‘œí˜„í•  수 없는 글ìžê°€ 들어 있습니다" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "ìž…ë ¥ì˜ ëì—서 부분ì ì¸ ë¬¸ìž ìˆœì„œ" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "대체 코드셋 “%sâ€ì„(를) “%sâ€(으)로 변환할 수 없습니다" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "변환 ìž…ë ¥ì—서 NUL ë°”ì´íŠ¸ê°€ 들어 있습니다" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "변환 출력ì—서 NUL ë°”ì´íŠ¸ê°€ 들어 있습니다" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI “%sâ€ì€(는) “file†스키마를 사용하는 절대 경로 URIê°€ 아닙니다" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "로컬 íŒŒì¼ URI “%sâ€ì—는 “#â€ì´ 들어갈 수 없습니다" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI “%sâ€ì´(ê°€) 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI “%sâ€ì˜ 호스트 ì´ë¦„ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI “%sâ€ì€(는) ìž˜ëª»ëœ ì´ìŠ¤ì¼€ì´í”„ 문ìžê°€ 들어 있습니다" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "경로ì´ë¦„ “%sâ€ì€(는) 절대 경로가 아닙니다" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Yë…„ %b %eì¼ (%a) %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%y/%m/%d" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%p %I:%M:%S" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "1ì›”" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "2ì›”" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "3ì›”" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "4ì›”" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "5ì›”" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "6ì›”" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "7ì›”" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "8ì›”" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "9ì›”" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "10ì›”" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "11ì›”" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "12ì›”" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "1ì›”" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "2ì›”" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "3ì›”" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "4ì›”" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "5ì›”" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "6ì›”" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "7ì›”" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "8ì›”" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "9ì›”" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "10ì›”" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "11ì›”" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "12ì›”" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "월요ì¼" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "화요ì¼" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "수요ì¼" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "목요ì¼" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "금요ì¼" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "토요ì¼" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ì¼ìš”ì¼" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ì›”" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "í™”" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "수" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "목" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "금" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "토" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ì¼" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "1ì›”" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "2ì›”" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "3ì›”" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "4ì›”" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "5ì›”" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "6ì›”" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "7ì›”" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "8ì›”" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "9ì›”" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "10ì›”" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "11ì›”" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "12ì›”" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "1ì›”" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "2ì›”" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "3ì›”" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "4ì›”" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "5ì›”" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "6ì›”" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "7ì›”" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "8ì›”" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "9ì›”" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "10ì›”" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "11ì›”" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "12ì›”" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "오전" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "오후" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "디렉터리 “%s†여는 중 오류 : %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "“%2$s†파ì¼ì„ ì½ëŠ”ë° %1$lu ë°”ì´íŠ¸ë¥¼ 할당할 수 없습니다" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "“%sâ€ íŒŒì¼ ì½ëŠ” 중 오류: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "“%s†파ì¼ì´ 너무 í½ë‹ˆë‹¤" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "íŒŒì¼ â€œ%sâ€ì—서 ì½ê¸° 실패: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "íŒŒì¼ â€œ%s†열기 실패: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "íŒŒì¼ â€œ%sâ€ì˜ ì†ì„± 가져오기 실패: fstat() 실패: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "íŒŒì¼ â€œ%s†열기 실패: fdopen() 실패: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "íŒŒì¼ â€œ%sâ€ì˜ ì´ë¦„ì„ â€œ%sâ€(으)로 ë°”ê¾¸ëŠ”ë° ì‹¤íŒ¨: g_rename() 실패: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "íŒŒì¼ â€œ%s†쓰기 실패: write() 실패: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "íŒŒì¼ â€œ%s†쓰기 실패: fsync() 실패: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "íŒŒì¼ â€œ%s†만들기 실패: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "ê¸°ì¡´ì˜ â€œ%s†파ì¼ì„ 지울 수 없습니다: g_unlink() 실패: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "“%s†서ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤. “%sâ€ì´(ê°€) 들어 있으면 안 ë©ë‹ˆë‹¤" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "“%s†서ì‹ì— XXXXXXê°€ 없습니다" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "심볼릭 ë§í¬ “%s†ì½ê¸° 실패: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "“%sâ€ì—서 “%sâ€(으)로 변환하는 변환기를 ì—´ 수 ì—†ìŒ: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string으로 raw ì½ê¸°ë¥¼ í•  수 없습니다" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "ì½ê¸° 버í¼ì—서 변환ë˜ì§€ ì•Šì€ ë°ì´í„°ë¥¼ 남겨둠" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "ì¼ë¶€ 문ìžì—서 ì±„ë„ ë냄" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_endi로 raw ì½ê¸°ë¥¼ í•  수 없습니다" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "검색 디렉터리 ì•ˆì— ì˜¬ë°”ë¥¸ 키 파ì¼ì´ 없습니다" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "ì¼ë°˜ 파ì¼ì´ 아닙니다" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"키 파ì¼ì— 들어 있는 “%sâ€ ì¤„ì€ í‚¤-ê°’ ìŒë„ 아니고, ê·¸ë£¹ë„ ì•„ë‹ˆê³ , 주ì„ë„ ì•„ë‹™ë‹ˆ" +"다" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "ìž˜ëª»ëœ ê·¸ë£¹ ì´ë¦„: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "키 파ì¼ì´ 그룹으로 시작하지 않습니다" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "ìž˜ëª»ëœ í‚¤ ì´ë¦„: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "키 파ì¼ì— ì§€ì›í•˜ì§€ 않는 “%s†ì¸ì½”ë”©ì´ ë“¤ì–´ 있습니다" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "키 파ì¼ì— “%sâ€ ê·¸ë£¹ì´ ì—†ìŠµë‹ˆë‹¤" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "키 파ì¼ì— 있는 “%2$sâ€ ê·¸ë£¹ì˜ â€œ%1$s†키가 없습니다" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "키 파ì¼ì— 있는 “%s†키와 “%sâ€ ê°’ì€ UTF-8ì´ ì•„ë‹™ë‹ˆë‹¤" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "키 파ì¼ì— 있는 “%sâ€ í‚¤ì˜ ê°’ì„ í•´ì„í•  수 없습니다." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"키 파ì¼ì— í•´ì„í•  수 없는 ê°’ì„ ì§€ë‹Œ “%2$sâ€ ê·¸ë£¹ì˜ â€œ%1$s†키가 키 파ì¼ì— 있습니" +"다." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"%4$s ê°’ì´ ìžˆì–´ì•¼ í•  “%2$sâ€ ê·¸ë£¹ì˜ â€œ%1$s†키가 “%3$sâ€ ê°’ì„ ì§€ë‹ˆê³  있습니다" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "키 파ì¼ì˜ 줄 ëì— ì´ìŠ¤ì¼€ì´í”„ 문ìžê°€ 있습니다" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "키 파ì¼ì— ìž˜ëª»ëœ ì´ìŠ¤ì¼€ì´í”„ 시퀀스 “%sâ€ì´(ê°€) 들어 있습니다" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "ê°’ “%sâ€ì„(를) 숫ìžë¡œ í•´ì„í•  수 없습니다." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "정수 ê°’ “%sâ€ì´(ê°€) 범위를 벗어났습니다" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "ê°’ “%sâ€ì„(를) ë‹¨ì •ë„ ì‹¤ìˆ˜ë¡œ í•´ì„í•  수 없습니다." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "ê°’ “%sâ€ì„(를) 불리언 값으로 í•´ì„í•  수 없습니다." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "“%s%s%s%s†파ì¼ì˜ ì†ì„± 가져오기 실패: fstat() 실패: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s 매핑 실패: mmap() 실패: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "íŒŒì¼ â€œ%s†열기 실패: dopen() 실패: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "%d째 줄 %d 문ìžì—서 오류: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "ì´ë¦„ì— ìž˜ëª» UTF-8 ì¸ì½”ë”©ëœ í…스트 — “%sâ€ ë¶€ë¶„ì´ ì˜¬ë°”ë¥´ì§€ 않습니다" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%sâ€ì€(는) 올바른 ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%sâ€ì€(는) 올바른 ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d째 줄ì—서 오류: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"“%-.*sâ€ì˜ 구문 í•´ì„ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. ë¬¸ìž ì°¸ì¡°ì—는 숫ìžë¥¼ ì¨ì•¼ 합니다 (예를 " +"들어 ê) — 숫ìžê°€ 너무 í´ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"ë¬¸ìž ì°¸ì¡°ê°€ 세미콜론으로 ë나지 않습니다. 보통 엔티티 ì‹œìž‘ì— ì‚¬ìš©í•˜ë ¤ê³  하지 " +"ì•Šì€ ê³³ì—서 & 기호를 사용한 경우입니다 — ì´ëŸ° 경우 & ë¼ê³  쓰십시오" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "ë¬¸ìž ì°¸ì¡° “%-.*sâ€ì— 대ì‘ë˜ëŠ” 문ìžëŠ” 허용ë˜ì§€ 않습니다" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"비어있는 엔티티 “&;â€ë¥¼ 찾았습니다. 올바른 엔티티는 & " < > " +"' 입니다" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "엔티티 ì´ë¦„ “%-.*sâ€ì´(ê°€) 알려져 있지 않습니다" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"엔티티가 세미콜론으로 ë나지 않습니다. ëŒ€ë¶€ë¶„ì˜ ê²½ìš° 엔티티 ì‹œìž‘ì— ì‚¬ìš©í•˜ë ¤" +"ê³  하지 ì•Šì€ ê³³ì—서 & 기호를 사용한 경우입니다 — ì´ëŸ° 경우 & ë¼ê³  쓰십시" +"오" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "문서는 요소로 시작하여야 합니다 (예 )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%sâ€ì€(는) “<â€ ë¬¸ìž ë‹¤ìŒì— 쓸 수 없습니다. ì´ ë¬¸ìžë¡œëŠ” 요소 ì´ë¦„ì„ ì‹œìž‘í•  수 " +"없습니다" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"ì´ìƒí•œ ë¬¸ìž â€œ%sâ€. 빈 요소 “%s†태그를 ë내는 “>†문ìžê°€ 나타나야 합니다" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "“%sâ€ ìš”ì†Œì— ì†ì„±ì´ 너무 많습니다" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"ì´ìƒí•œ ë¬¸ìž â€œ%1$sâ€. 요소 “%3$sâ€ì˜ ì†ì„± ì´ë¦„ “%2$s†다ìŒì— “=â€ì´ 나타나야 í•©" +"니다" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ì´ìƒí•œ ë¬¸ìž â€œ%sâ€. 요소 “%sâ€ì˜ 시작 태그를 ë내는 “>â€ í˜¹ì€ â€œ/â€ê°€ 나타나거나, " +"ì†ì„±ì´ 나와야 합니다. ì•„ë§ˆë„ ì†ì„± ì´ë¦„ì— ìž˜ëª»ëœ ë¬¸ìžë¥¼ ì“´ 경우입니다." + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"ì´ìƒí•œ ë¬¸ìž â€œ%1$sâ€. 요소 “%3$sâ€ì˜ ì†ì„± “%2$sâ€ì˜ ê°’ì„ ë¶€ì—¬í•  때 “=†기호 다ìŒ" +"ì— ë”°ì˜´í‘œê°€ 나타나야 합니다" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%sâ€ì€(는) 요소 “%sâ€ì„(를) ë‹«ì€ ë‹¤ìŒì— 쓸 수 있는 문ìžê°€ 아닙니다. “>†문ìž" +"를 쓸 수 있습니다" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "“%s†요소는 닫혔고, 현재 아무 ìš”ì†Œë„ ì—´ë ¤ 있지 않습니다" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "“%s†요소는 닫혔고, 현재 ì—´ë ¤ 있는 요소는 “%sâ€ìž…니다" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "문서가 비어있거나 공백문ìžë§Œ 들어 있습니다" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "“<†바로 다ìŒì— 문서가 갑작스럽게 ë났습니다" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"요소가 ì—´ë ¤ 있는 ìƒíƒœë¡œ 문서가 갑작스럽게 ë났습니다 — ë§ˆì§€ë§‰ì— ì—´ë ¤ ìžˆë˜ ìš”" +"소는 “%sâ€ìž…니다" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"문서가 갑작스럽게 ë났습니다. <%s/> 태그를 ë내는 > 기호가 나타나야 합니다" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "요소 ì´ë¦„ì—서 문서가 갑작스럽게 ë났습니다" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "ì—트리뷰트 ì´ë¦„ì—서 문서가 갑작스럽게 ë났습니다" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ìš”ì†Œì˜ ì—´ê¸° 태그 안ì—서 문서가 갑작스럽게 ë났습니다." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"ì†ì„± ì´ë¦„ 다ìŒì˜ = 기호 다ìŒì—서 문서가 갑작스럽게 ë났습니다. ì†ì„± ê°’ì´ ì—†ìŠµ" +"니다" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ì†ì„± ê°’ 안ì—서 문서가 갑작스럽게 ë났습니다" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "“%sâ€ ìš”ì†Œì˜ ë‹«ê¸° 태그 안ì—서 문서가 갑작스럽게 ë났습니다" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "“%sâ€ ìš”ì†Œì˜ ë‹«ê¸° 태그 안ì—서 문서가 갑작스럽게 ë났습니다" + +# FIXME: processing instruction? +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "주ì„문 í˜¹ì€ ì²˜ë¦¬ ì•ˆë‚´ìž íƒœê·¸ 안ì—서 문서가 갑작스럽게 ë났습니다" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[옵션…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "ë„ì›€ë§ ì˜µì…˜:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "ë„ì›€ë§ ì˜µì…˜ì„ ë´…ë‹ˆë‹¤" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "모든 ë„ì›€ë§ ì˜µì…˜ì„ ë´…ë‹ˆë‹¤" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "프로그램 옵션:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "옵션:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "%2$sì— ëŒ€í•œ 정수 ê°’ “%1$sâ€ì„(를) ë¶„ì„í•  수 없습니다" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "%2$sì— ëŒ€í•œ 정수 ê°’ “%1$sâ€ì´(ê°€) 범위를 벗어났습니다" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "%2$sì— ëŒ€í•œ ë°°ì •ë„ ì‹¤ìˆ˜ ê°’ “%1$sâ€ì„(를) ë¶„ì„í•  수 없습니다" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "%2$sì— ëŒ€í•œ ë°°ì •ë„ ì‹¤ìˆ˜ ê°’ “%1$sâ€ì´(ê°€) 범위를 벗어났습니다" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "옵션 ì½ëŠ” ì¤‘ì— ì˜¤ë¥˜: %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "%sì— ëŒ€í•œ ì¸ìžê°€ 빠졌습니다" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "알 수 없는 옵션 %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "개체가 ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "ë‚´ë¶€ 오류 ë˜ëŠ” 개체가 ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "메모리 부족" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "ì—­ì¶”ì  ìµœëŒ€ê°’ì— ë„달했습니다" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "패턴 ì•ˆì— ë¶€ë¶„ 매치ì—서 ì§€ì›í•˜ì§€ 않는 í•­ëª©ì´ ë“¤ì–´ 있습니다." + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "ë‚´ë¶€ 오류" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "후위 참조를 조건으로 사용하면 부분 매치ì—서 ì§€ì›í•˜ì§€ 않습니다." + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "재귀 ìµœëŒ€ê°’ì— ë„달했습니다" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "줄바꿈 í”Œëž˜ê·¸ì˜ ì¡°í•©ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "ì˜¤í”„ì…‹ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "UTF-8 문ìžì—´ì´ ëŠê²¼ìŠµë‹ˆë‹¤" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "재귀 순환" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "알 수 없는 오류" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "패턴 ëì— \\\\" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "패턴 ëì— \\\\c" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "\\ 다ìŒì— ì¸ì‹í•  수 없는 문ìžê°€ 있습니다" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "{} ì•ˆì˜ ìˆ«ìžê°€ 순서를 벗어났습니다" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "{} ì•ˆì˜ ìˆ«ìžê°€ 너무 í½ë‹ˆë‹¤" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "ë¬¸ìž í´ëž˜ìФì—서 ë나는 ] 괄호가 빠졌습니다" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "ë¬¸ìž í´ëž˜ìФì—서 ì´ìŠ¤ì¼€ì´í”„ 시퀀스가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "ë¬¸ìž í´ëž˜ìФì—서 범위가 순서를 벗어났습니다" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "반복할 사항 ì—†ìŒ" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "예ìƒí•˜ì§€ 못한 반복" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "(? ë˜ëŠ” (?- 다ìŒì— 알 수 없는 문ìžê°€ 있습니다" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX 네임드 í´ëž˜ìŠ¤ëŠ” í´ëž˜ìФ 안ì—서만 ì§€ì›í•©ë‹ˆë‹¤" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "ë나는 ) 괄호가 없습니다" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "없는 하위 íŒ¨í„´ì„ ì°¸ì¡°í•©ë‹ˆë‹¤" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "ì£¼ì„ ë‹¤ìŒì— ) 괄호가 빠졌습니다" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "ì •ê·œì‹ì´ 너무 ê¹ë‹ˆë‹¤" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "메모리를 í™•ë³´í•˜ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "( 여는 괄호 ì—†ì´ ) 괄호가 있습니다" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "코드 오버플로우" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "(?< 다ìŒì— 알 수 없는 문ìž" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "룩비하ì¸ë“œ ì–´ì„œì…˜ì´ ê³ ì •ëœ ê¸¸ì´ê°€ 아닙니다" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "(?( 다ìŒì— 숫ìžë‚˜ ì´ë¦„ì˜ í˜•ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "조건문 ê·¸ë£¹ì— ë¸Œëžœì¹˜ê°€ 2개보다 ë§Žì´ ë“¤ì–´ 있습니다" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "(?( 다ìŒì— ì–´ì„œì…˜ì´ ì´ì™€ì•¼ 합니다" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R í˜¹ì€ (?[+-]digits 다ìŒì—는 ) 괄호가 와야 합니다" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "알 수 없는 POSIX í´ëž˜ìФ ì´ë¦„" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX 사전 순서 í•­ëª©ì€ ì§€ì›í•˜ì§€ 않습니다" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} ì‹œí€€ìŠ¤ì˜ ë¬¸ìž ê°’ì´ ë„ˆë¬´ í½ë‹ˆë‹¤" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "ìž˜ëª»ëœ ì¡°ê±´ë¬¸ (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C는 룩비하ì¸ë“œ 어서션ì—서 사용할 수 없습니다" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "\\L, \\l, \\N{name}, \\U, and \\u ì´ìŠ¤ì¼€ì´í”„는 ì§€ì›í•˜ì§€ 않습니다" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "재귀 í˜¸ì¶œë•Œë¬¸ì— ë¬´í•œížˆ 반복할 수 있습니다" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "(?P 다ìŒì— 알 수 없는 문ìž" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "하위 패턴 ì´ë¦„ì— ë나는 글ìžê°€ 빠졌습니다" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "ì´ë¦„ 있는 2ê°œì˜ í•˜ìœ„ íŒ¨í„´ì˜ ì´ë¦„ì´ ê°™ìŠµë‹ˆë‹¤" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "\\P í˜¹ì€ \\p ì‹œí€€ìŠ¤ì˜ í˜•ì‹ì´ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "\\P í˜¹ì€ \\p 다ìŒì— ì†ì„± ì´ë¦„ì„ ì•Œ 수 없습니다" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "하위 패턴 ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤ (최대 32글ìž)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ì´ë¦„ 있는 하위 íŒ¨í„´ì´ ë„ˆë¬´ 많습니다 (최대 10,000ê°œ)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "8ì§„ìˆ˜ê°’ì´ \\377보다 í½ë‹ˆë‹¤" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "ì»´íŒŒì¼ ìž‘ì—… ê³µê°„ì„ ë„˜ì–´ê°”ìŠµë‹ˆë‹¤" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "ì´ì „ì— ê²€ì‚¬í•œ 참조할 하위 íŒ¨í„´ì´ ì—†ìŠµë‹ˆë‹¤" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE ê·¸ë£¹ì— ë¸Œëžœì¹˜ê°€ 여러 ê°œ 들어 있습니다" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "ì¼ê´€ì„± 없는 NEWLINE 옵션" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"중괄호, ê°ê´„호, 따옴표가 ë¶™ì€ ì´ë¦„ ë˜ëŠ” 숫ìž, ë˜ëŠ” 순수한 숫ìžê°€ ë”°ë¼ì˜¤ì§€ 않" +"았습니다" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "번호를 매긴 참조는 0ì´ ë˜ì–´ì„œëŠ” 안ë©ë‹ˆë‹¤" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "(*ACCEPT), (*FAIL), ë˜ëŠ” (*COMMIT)ì„ ê°ì•ˆí•˜ì—¬ ì¸ìžë¥¼ 허용하지 않습니다" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB)를 ì¸ì‹í•˜ì§€ 않았습니다" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "숫ìžê°€ 너무 í½ë‹ˆë‹¤" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "(?& 다ìŒì— 하위 패턴 ì´ë¦„ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "(?+ 다ìŒì— 숫ìžê°€ 있어야 합니다" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "]는 ìžë°”스í¬ë¦½íЏ 호환 모드ì—서 ìž˜ëª»ëœ ë°ì´í„° ë¬¸ìž ìž…ë‹ˆë‹¤" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ë™ì¼í•œ ê°¯ìˆ˜ì˜ í•˜ìœ„ íŒ¨í„´ì— ëŒ€í•´ 다른 ì´ë¦„ì„ í—ˆìš©í•˜ì§€ 않습니다" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK)ì— ì¸ìžê°€ 있어야 합니다" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c 다ìŒì— 아스키 문ìžê°€ 있어야 합니다" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k 다ìŒì— 중괄호, ê°ê´„호, 따옴표가 ë¶™ì€ ì´ë¦„ì´ ë”°ë¼ì˜¤ì§€ 않았습니다" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "í´ëž˜ìФì—서 \\Nì„ ì§€ì›í•˜ì§€ 않습니다" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "너무 ë§Žì€ ì°¸ì¡°ë¥¼ 전달했습니다" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), ë˜ëŠ” (*THEN)ì˜ ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... ì‹œí€€ìŠ¤ì˜ ë¬¸ìž ê°’ì´ ë„ˆë¬´ í½ë‹ˆë‹¤" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "ì •ê·œ í‘œí˜„ì‹ %sì„(를) 맞추는 ë„중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE ë¼ì´ë¸ŒëŸ¬ë¦¬ê°€ UTF8 ì§€ì› ì—†ì´ ì»´íŒŒì¼ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” UTF8 ì†ì„±ì„ ì§€ì›í•˜ì§€ 않고 컴파ì¼ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "비호환 ì˜µì…˜ì„ ì‚¬ìš©í•˜ì—¬ PCRE ë¼ì´ë¸ŒëŸ¬ë¦¬ 컴파ì¼í–ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "ì •ê·œ í‘œí˜„ì‹ %sì„(를) 최ì í™”하는 ë„중 오류 ë°œìƒ: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"ì •ê·œ í‘œí˜„ì‹ %sì„(를) 컴파ì¼í•˜ëŠ” 중 %d번째 문ìžì—서 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "16 진수 ë˜ëŠ” “}â€ê°€ 있어야 합니다" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "16 진수가 있어야 합니다" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "심볼 ì°¸ì¡°ì— â€œ<†기호가 없습니다" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "심볼 참조가 ë나지 않았습니다" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "심볼 ì°¸ì¡°ì— ë‚´ìš©ì´ ì—†ìŠµë‹ˆë‹¤" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "숫ìžê°€ 있어야 합니다" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "심볼 참조가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "마지막 “\\â€ê°€ 없습니다" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "알 수 없는 ì´ìŠ¤ì¼€ì´í”„ 시퀀스" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "“%s†바꿀 문ìžì—´ì„ ì½ëŠ” 중 %lu번째 문ìžì—서 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤: %s" + +# g_shell_unquote()ì— ì“°ìž„. shellì˜ quoted text를 raw string으로 바꾸는 기능 +# FIXME: "quoted"ë¼ëŠ” ë§ì„ 어떻게 해야 í•  것ì¸ê°€? +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "ë”°ì˜´í‘œëœ í…스트가 따옴표로 시작하지 않습니다" + +# FIXME: 위 참조, "quoted" +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "명령줄ì—서 따옴표가 ë§žì§€ 않거나 ì…¸ ë”°ì˜´í‘œëœ í…스트가 ë˜ ìžˆìŠµë‹ˆë‹¤" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "í…스트가 “\\â€ ë¬¸ìž ë‹¤ìŒì— ë났습니다. (í…스트는 “%sâ€ìž…니다)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"í…스트가 %cì— ëŒ€ì‘ë˜ëŠ” 따옴표가 나타나기 ì „ì— ë났습니다. (í…스트는 “%sâ€ìž…니" +"다)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "í…스트가 비어 있ìŒ(ë˜ëŠ” 공백만 들어 있ìŒ)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "하위 프로세스ì—서 ë°ì´í„°ë¥¼ ì½ê¸° 실패 (%s)" + +#: glib/gspawn.c:461 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "하위 프로세스ì—서 ë°ì´í„°ë¥¼ ì½ëŠ” 중 예ìƒì¹˜ 못한 오류 (%s)" + +#: glib/gspawn.c:546 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid()ì—서 예ìƒì¹˜ 못한 오류 (%s)" + +#: glib/gspawn.c:1168 glib/gspawn-win32.c:1426 +#, c-format +msgid "Child process exited with code %ld" +msgstr "하위 프로세스가 %ld 코드로 ë났습니다" + +#: glib/gspawn.c:1176 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "하위 프로세스가 %ld 시그ë„로 죽었습니다" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "하위 프로세스가 %ld 시그ë„로 멈췄습니다" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process exited abnormally" +msgstr "하위 프로세스가 예기치 않게 ë났습니다" + +#: glib/gspawn.c:1881 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "하위 파ì´í”„로 부터 ì½ê¸° 실패 (%s)" + +#: glib/gspawn.c:2241 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "하위 프로세스 “%sâ€ì„(를) 실행하기 실패 (%s)" + +#: glib/gspawn.c:2358 +#, c-format +msgid "Failed to fork (%s)" +msgstr "í¬í¬ 실패 (%s)" + +#: glib/gspawn.c:2518 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "디렉터리 “%sâ€(으)로 바꾸기 실패 (%s)" + +#: glib/gspawn.c:2528 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "하위 프로세스 “%sâ€ì„(를) 실행하기 실패 (%s)" + +#: glib/gspawn.c:2538 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "íŒŒì¼ ë””ìŠ¤í¬ë¦½í„° 리맵하기 위한 íŒŒì¼ ì—´ê¸° 실패 (%s)" + +#: glib/gspawn.c:2546 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "하위 í”„ë¡œì„¸ìŠ¤ì— ëŒ€í•œ íŒŒì¼ ë””ìŠ¤í¬ë¦½í„° 복제 실패 (%s)" + +#: glib/gspawn.c:2555 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "하위 프로세스(%s) ìƒì„± 실패" + +#: glib/gspawn.c:2563 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "하위 í”„ë¡œì„¸ìŠ¤ì— ëŒ€í•œ íŒŒì¼ ë””ìŠ¤í¬ë¦½í„° 닫기 실패 (%s)" + +#: glib/gspawn.c:2571 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "하위 프로세스 “%sâ€ì„(를) 실행하는 중 알 수 없는 오류" + +#: glib/gspawn.c:2595 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "하위 PID 파ì´í”„ì—서 필요한 ë°ì´í„°ë¥¼ ì½ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤ (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "하위 프로세스ì—서 ë°ì´í„° ì½ê¸° 실패" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:519 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "하위 프로세스 실행 실패 (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "하위 프로세스ì—서 dup() 실패 (%s)" + +#: glib/gspawn-win32.c:469 +#, c-format +msgid "Invalid program name: %s" +msgstr "ìž˜ëª»ëœ í”„ë¡œê·¸ëž¨ ì´ë¦„: %s" + +#: glib/gspawn-win32.c:479 glib/gspawn-win32.c:797 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "ì¸ìžì—서 ìž˜ëª»ëœ ë¬¸ìžì—´, %d: %s" + +#: glib/gspawn-win32.c:490 glib/gspawn-win32.c:813 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "환경ì—서 ìž˜ëª»ëœ ë¬¸ìžì—´: %s" + +#: glib/gspawn-win32.c:793 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ìž˜ëª»ëœ í˜„ìž¬ 디렉터리: %s" + +#: glib/gspawn-win32.c:858 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ë„움 프로그램 실행 실패 (%s)" + +#: glib/gspawn-win32.c:1086 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"하위 프로세스ì—서 ë°ì´í„°ë¥¼ ì½ëŠ”ì¤‘ g_io_channel_win32_poll()ì—서 예기치 못한 " +"오류" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "빈 문ìžì—´ì€ 숫ìžê°€ 아닙니다" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%sâ€ì€(는) 부호 있는 숫ìžê°€ 아닙니다" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "“%s†숫ìžê°€ [%s, %s] 범위를 벗어납니다" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%sâ€ì€(는) 부호 없는 숫ìžê°€ 아닙니다" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "URIì— ìž˜ëª»ëœ % ì¸ì½”딩" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "URIì— ìž˜ëª»ëœ ë¬¸ìž" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "URIì— UTF-8 아닌 문ìž" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "URIì— ìž˜ëª»ëœ IPv6 주소 ‘%.*s’" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "URIì— ìž˜ëª» ì¸ì½”ë”©ëœ IP 주소 ‘%.*s’" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "URIì— êµ­ì œí™”ëœ í˜¸ìŠ¤íŠ¸ì´ë¦„ ‘%.*s’ 잘못ë¨" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "URIì—서 í¬íŠ¸ë¥¼ (‘%.*s’) í•´ì„í•  수 없습니다" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "URIì—서 í¬íŠ¸ê°€ (‘%.*s’) 범위를 벗어납니다" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "‘%s’ URI는 절대 URIê°€ 아닙니다" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI ‘%sâ€™ì— í˜¸ìŠ¤íŠ¸ 구성 요소가 없습니다" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URIê°€ 절대 URIê°€ 아니고, 기준 URI를 제공하지 않았습니다" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "‘=’ ë° íŒŒë¼ë¯¸í„° ê°’ì´ ì—†ìŠµë‹ˆë‹¤" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "메모리를 í• ë‹¹í•˜ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 ë¬¸ìž ë²”ìœ„ë¥¼ 벗어났습니다" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "변환 ìž…ë ¥ 순서가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 ë¬¸ìž ë²”ìœ„ë¥¼ 벗어났습니다" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ë°”ì´íЏ" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u 비트" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ë°”ì´íЏ" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s 비트" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" diff --git a/po/ku.po b/po/ku.po new file mode 100644 index 0000000..64e3c00 --- /dev/null +++ b/po/ku.po @@ -0,0 +1,3721 @@ +# translation of glib.glib-2-8.po to Kurdish +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Erdal Ronahi , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.glib-2-8\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2006-04-20 17:33+0000\n" +"Last-Translator: Erdal Ronahi \n" +"Language-Team: Kurdish \n" +"Language: ku\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' ne derbasdar e" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Navê hostê nederbasdar e" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %B %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Çile" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Sibat" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Adar" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "Nîsan" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Gulan" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Hezîran" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Tîrmeh" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Çil" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Sib" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Ada" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Nîs" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Gul" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Hez" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Tîr" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "dusêm" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "sêsêm" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "çarsêm" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "pêncsêm" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "înî" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sept" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "yêksêm" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "dus" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "sês" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "çar" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "pên" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "înî" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sep" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "yêk" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "Di rêza %d tîpa %d de çewtî: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Di rêza %d de çewtî: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Di rêza %d tîpa %d de çewtî: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Navê bernameyê nederbasdar e: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Bikaranîn:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Vebijêrkên Sepanê:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Vebijêrka nenas %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Dosya vala ye" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "Navê bernameyê nederbasdar e: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "Navê bernameyê nederbasdar e: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "Vebijêrka nenas %s" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Vebijêrka nenas %s" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +msgid "Abstract name space not supported" +msgstr "" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Di rêza %d de çewtî: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:646 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +msgid "empty names are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Navê bernameyê nederbasdar e: %s" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "Navê hostê nederbasdar e" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Di rêza %d de çewtî: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Di rêza %d de çewtî: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "Di rêza %d de çewtî: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Di rêza %d de çewtî: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Navê bernameyê nederbasdar e: %s" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Vebijêrka nenas %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Vekirina dosiya '%s' serneket: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "Di rêza %d de çewtî: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Navê hostê nederbasdar e" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Di xwendina dosyeya '%s' de çewtî: %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Di xwendina dosyeya '%s' de çewtî: %s" diff --git a/po/lt.po b/po/lt.po new file mode 100644 index 0000000..bab6a0c --- /dev/null +++ b/po/lt.po @@ -0,0 +1,6438 @@ +# Lithuanian translation of Glib library. +# Copyright © 2003-2005, 2007, 2008, 2010 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Tomas Kuliavas , 2003-2004. +# Žygimantas BeruÄka , 2004-2007, 2010, 2012. +# Mantas KriauÄiÅ«nas , 2006-2007. +# Gintautas Miliauskas , 2007, 2008. +# Rimas Kudelis , 2010. +# Algimantas MargeviÄius , 2011. +# Aurimas ÄŒernius , 2010-2022. +# +msgid "" +msgstr "" +"Project-Id-Version: lt\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 15:19+0000\n" +"PO-Revision-Date: 2022-03-22 21:16+0200\n" +"Last-Translator: Aurimas ÄŒernius \n" +"Language-Team: Lietuvių \n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" +"%100<10 || n%100>=20) ? 1 : 2)\n" +"X-Generator: Gtranslator 40.0\n" +"X-Project-Style: gnome\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Numatytųjų programų nustatymas dar nepalaikomas" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "Programos nustatymas kaip paskutinÄ—s naudotos dar nepalaikomas" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication parametrai" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Rodyti GApplication parametrus" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Ä®veskite GApplication tarnybos veiksenÄ… (naudoti iÅ¡ D-Bus tarnybų failų)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Pakeisti programos ID" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Pakeisti veikianÄiÄ…" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Spausdinti pagalbÄ…" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[KOMANDA]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Atspausdinti versijÄ…" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Atspausdinti versijos informacijÄ… ir iÅ¡eiti" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "IÅ¡vardinti programas" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"IÅ¡vardinti įdiegtas per D-Bus aktyvuojamas programas (pagal .desktop failus)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Paleisti programÄ…" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Paleisti programÄ… (su nebÅ«tinais failais atvÄ—rimui)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FAILAS...]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktyvuoti veiksmÄ…" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "IÅ¡kviesti veiksmÄ… programoje" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID veiksmas [PARAMETRAS]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "IÅ¡vardinti prieinamus veiksmus" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "IÅ¡vardinti statinius programos veiksmus (pagal .desktop failÄ…)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMANDA" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "KomandÄ…, kuriai atspausdinti detaliÄ… pagalbÄ…" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Programos identifikatorius D-Bus formatu (pvz.: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FAILAS" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"NebÅ«tini absoliutÅ«s arba santykiniai failų pavadinimai ar URI atvÄ—rimui" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "VEIKSMAS" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Veiksmo pavadinimas iÅ¡kvietimui" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETRAS" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "NebÅ«tinas parametras veiksmo iÅ¡kvietimui, GVariant formatu" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Nežinoma komanda „%s“\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Naudojimas:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumentai:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARG...]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Komandos:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "Naudokite „%s help KOMANDA“ detaliai pagalbai.\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "%s komanda reikalauja iÅ¡ karto pateikti programos id\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "netinkamas programos id: „%s“\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "„%s“ nepriima argumentų\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "nepavyko prisijungti prie D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "klaida siunÄiant %s praneÅ¡imÄ… programai: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "veiksmo pavadinimas turi bÅ«ti pateiktas po programos id\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"netinkamas veiksmo pavadinimas: „%s“\n" +"veiksmų pavadinimai turi susidÄ—ti tik iÅ¡ alfaskaitmenų, „-“ ir „.“\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "klaida skaitant veiksmo parametrÄ…: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "veiksmai priima ne daugiau kaip vienÄ… parametrÄ…\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions komanda priima tik programos id" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "nepavyksta rasti desktop failo programai %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"nežinoma komanda: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Per didelÄ— skaiÄiavimo reikÅ¡mÄ— perduota %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Pozicijos perkÄ—limas sraute nepalaikomas" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Nepavyko sutrumpinti GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Srautas jau užvertas" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Trumpinimas sraute nepalaikomas" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operacija nutraukta" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Netinkamas objektas, nepavyko inicijuoti" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Klaidinga baitų seka įvestyje" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Nepakanka paskirties vietos" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Klaidinga baitų seka keitimo įvedime" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Klaida keitimo metu: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "AtÅ¡aukiamas inicijavimas nepalaikomas" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Keitimas iÅ¡ koduotÄ—s „%s“ į koduotÄ™ „%s“ nepalaikomas" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Nepavyko atverti keitiklio iÅ¡ „%s“ į „%s“" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s tipas" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Nežinomas tipas" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s failo tipos" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials turi nekorektiÅ¡kus duomenis" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials nerealizuota Å¡ioje operacinÄ—je sistemoje" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "JÅ«sų platformoje nÄ—ra GCredentials palaikymo" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials neturi proceso ID Å¡ioje OS" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Ä®galiojimų apgavimas neįmanomas Å¡ioje operacinÄ—je sistemoje" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "NetikÄ—ta ankstyva srauto pabaiga" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nepalaikomas raktas „%s“ adreso įvestyje „%s“" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "BeprasmÄ— rakto/reikÅ¡mÄ—s poros kombinacija adreso įvestyje „%s“" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adresas „%s“ nÄ—ra tinkamas (reikia įvesti vienintelį path, dir, tmpdir arba " +"abstract raktÄ…)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Klaida adrese „%s“ — neteisingai suformuotas atributas „%s“" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Nežinomas arba nepalaikomas duomenų perdavimas „%s“ adresui „%s“" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adreso elementas „%s“ neturi dvitaÅ¡kio (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Transporto pavadinimas adreso elemente „%s“ negali bÅ«ti tuÅ¡Äias" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Rakto/reikÅ¡mÄ—s pora %d, „%s“, adreso elementas „%s“ neturi lygybÄ—s ženklo" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Rakto/reikÅ¡mÄ—s pora %d, „%s“, adreso elemente „%s“ negali turÄ—ti lygybÄ—s " +"ženklo" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Klaida Å¡alinant kaitÄ… rakte ar reikÅ¡mÄ—je rakto/reikÅ¡mÄ—s poroje %d, „%s“ " +"adreso elemente „%s“" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Klaida adrese „%s“ - unix duomenų perdavimas reikalauja nustatyti vienintelį " +"iÅ¡ raktų 'path' arba 'abstract'" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Klaida adrese „%s“ - pagrindinio kompiuterio atributas neįvestas arba blogai " +"suformuotas" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Klaida adrese „%s“ - prievado atributas neįvestas arba blogai suformuotas" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Klaida adrese „%s“ - laikino failo atributas neįvestas arba blogai " +"suformuotas" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Klaida automatiÅ¡kai paleidžiant: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Klaida atveriant vienkartinio kodo failÄ… „%s“: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Klaida skaitant iÅ¡ vienkartinio kodo failo „%s“: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Klaida skaitant iÅ¡ vienkartinio kodo failo „%s“, tikÄ—tasi 16 baitų, gauta %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Klaida raÅ¡ant vienkartinio kodo failo turinį „%s“ į srautÄ…:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Pateiktasis adresas yra tuÅ¡Äias" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Negalima paleisti praneÅ¡imų magistralÄ—s kai nustatyta AT_SECURE" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Negalima paleisti praneÅ¡imų magistralÄ—s be maÅ¡inos id: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Negalima automatiÅ¡kai paleisti D-Bus be X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Klaida paleidžiant komandų eilutÄ™ „%s“: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Nepavyko nustatyti sesijos magistralÄ—s adreso (nerealizuota Å¡iai operacinei " +"sistemai)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Nepavyko nustatyti magistralÄ—s adreso iÅ¡ DBUS_STARTER_BUS_TYPE aplinkos " +"kintamojo - nežinoma reikÅ¡mÄ— „%s“" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Nepavyko nustatyti magistralÄ—s adreso, kadangi DBUS_STARTER_BUS_TYPE " +"aplinkos kintamasis nenustatytas" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Nežinomas magistralÄ—s tipas %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "NetikÄ—tas turinio trÅ«kumas bandant nuskaityti eilutÄ™" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "NetikÄ—tas turinio trÅ«kumas bandant (saugiai) nuskaityti eilutÄ™" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"BaigÄ—si visi turimi tapatybÄ—s patvirtinimo mechanizmai (bandyta: %s) " +"(turimi: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Naudotojų ID turi sutapti porininkui bei serveriui" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "AtÅ¡aukta per GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Klaida gaunant informacijÄ… apie katalogÄ… „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Katalogo „%s“ leidimai yra suformuoti neteisingai. TikÄ—tasi mode 0700, gauta " +"0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Klaida kuriant katalogÄ… %s: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operacija nepalaikoma" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Klaida atveriant raktinÄ™ „%s“ skaitymui: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"%d eilutÄ— raktinÄ—s vietoje „%s“ su turiniu „%s“ yra suformuota neteisingai" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Pirmoji leksema raktinÄ—s %d eilutÄ—s vietoje „%s“ su turiniu „%s“ yra " +"suformuota neteisingai" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Antroji leksema raktinÄ—s %d eilutÄ—s vietoje „%s“ su turiniu „%s“ yra " +"suformuota neteisingai" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Nerastas slapukas su id %d raktinÄ—s vietoje „%s“" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Klaida kuriant rakinimo failÄ… „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Klaida trinant nebegaliojantį rakinimo failÄ… „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Klaida užveriant (nesusietÄ…) rakinimo failÄ… „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Klaida atsiejant rakinimo failÄ… „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Klaida atveriant raktinÄ™ „%s“ raÅ¡ymui: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Papildomai, užrakto atlaisvinimas „%s“ taip pat nepavyko: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "RyÅ¡ys yra užvertas" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "BaigÄ—si laikas" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Nepalaikomi požymiai aptikti konstruojant kliento pusÄ—s ryšį" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"NÄ—ra sÄ…sajos „org.freedesktop.DBus.Properties“ objektui, kurio kelias %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "NÄ—ra savybÄ—s „%s“" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "SavybÄ— „%s“ yra neskaitoma" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "SavybÄ— „%s“ nÄ—ra raÅ¡oma" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "Klaida nustatant savybÄ™ „%s“: tikÄ—tasi tipo „%s“, bet gauta „%s“" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "NÄ—ra sÄ…sajos „%s“" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "NÄ—ra sÄ…sajos „%s“ objektui, kurio kelias %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "NÄ—ra metodo „%s“" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "PraneÅ¡imo tipas „%s“ neatitinka laukiamo tipo „%s“" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Jau yra eksportuotas objektas sÄ…sajai %s vietoje %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Nepavyko gauti savybÄ—s: %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Nepavyko nustatyti savybÄ—s: %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metodas „%s“ grąžino tipÄ… „%s“, bet laukta „%s“" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metodas „%s“ sÄ…sajoje „%s“ su signatÅ«ra „%s“ neegzistuoja" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Pomedis %s jau yra eksportuotas" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Objekto kelyje „%s“ nÄ—ra" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "tipas yra NETINKAMAS" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL praneÅ¡imas: trÅ«ksta antraÅ¡tÄ—s lauko PATH arba MEMBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN praneÅ¡imas: trÅ«ksta REPLY_SERIAL antraÅ¡tÄ—s" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR praneÅ¡imas: antraÅ¡tÄ—s lauke trÅ«ksta REPLY_SERIAL arba ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL praneÅ¡imas: trÅ«ksta antraÅ¡tÄ—s lauko PATH, INTERFACE arba MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL praneÅ¡imas: antraÅ¡tÄ—s laukas PATH naudoja rezervuotÄ… reikÅ¡mÄ™ /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL praneÅ¡imas: antraÅ¡tÄ—s laukas INTERFACE naudoja rezervuotÄ… reikÅ¡mÄ™ org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "NorÄ—ta nuskaityti %lu baitÄ…, bet gauta tik %lu" +msgstr[1] "NorÄ—ta nuskaityti %lu baitus, bet gauta tik %lu" +msgstr[2] "NorÄ—ta nuskaityti %lu baitų, bet gauta tik %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "TikÄ—tasi NUL baito po simbolių eilutÄ—s „%s“, bet rastas baitas %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"TikÄ—tasi teisingos UTF-8 eilutÄ—s, bet rasta neteisingų baitų poslinkiu %d " +"(eilutÄ—s ilgis yra %d). Teisinga UTF-8 eilutÄ— iki tos vietos buvo „%s“" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "VertÄ— yra per giliai" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Perskaityta reikÅ¡mÄ— „%s“ nÄ—ra tinkamas D-Bus objekto kelias" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Perskaityta reikÅ¡mÄ— „%s“ nÄ—ra tinkama D-Bus signatÅ«ra" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Aptiktas %u baito ilgio masyvas. Maksimalus ilgis yra 2<<26 baitų (64 MiB)." +msgstr[1] "" +"Aptiktas %u baitų ilgio masyvas. Maksimalus ilgis yra 2<<26 baitų (64 MiB)." +msgstr[2] "" +"Aptiktas %u baitų ilgio masyvas. Maksimalus ilgis yra 2<<26 baitų (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Aptiktas „a%c“ tipo masyvas, tikÄ—tasi %u kartotinio baitų ilgio, bet rasta " +"%u baitų ilgyje" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "TuÅ¡Äios struktÅ«ros (junginiai) D-Bus neleidžiamos" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Perskaityta reikÅ¡mÄ— „%s“ variantui nÄ—ra tinkama D-Bus signatÅ«ra" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Klaida atstatant GVariant su tipo eilute „%s“ iÅ¡ D-Bus telegramos formato" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Netinkama baitų eiliÅ¡kumo reikÅ¡mÄ—. TikÄ—tasi 0x6c („l“) arba 0x42 („B“), bet " +"rasta 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Netinkama pagrindinÄ— protokolo versija. TikÄ—tasi 1, bet rasta %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Rasta signatÅ«ros antraÅ¡tÄ—, bet ji nÄ—ra signatÅ«ros tipo" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"SignatÅ«ros antraÅ¡tÄ— su signatÅ«ra „%s“ rasta, bet praneÅ¡imo pagrindinÄ— dalis " +"tuÅ¡Äia" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Perskaityta reikÅ¡mÄ— „%s“ nÄ—ra tinkama D-Bus signatÅ«ra (pagrindinei daliai)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"NÄ—ra signatÅ«ros antraÅ¡tÄ—s praneÅ¡ime, bet praneÅ¡imo pagrindinÄ— dalis yra %u " +"baito" +msgstr[1] "" +"NÄ—ra signatÅ«ros antraÅ¡tÄ—s praneÅ¡ime, bet praneÅ¡imo pagrindinÄ— dalis yra %u " +"baitų" +msgstr[2] "" +"NÄ—ra signatÅ«ros antraÅ¡tÄ—s praneÅ¡ime, bet praneÅ¡imo pagrindinÄ— dalis yra %u " +"baitų" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Nepavyko atstatyti praneÅ¡imo: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Klaida paverÄiant GVariant su tipo eilute „%s“ į D-Bus telegramos formatÄ…" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Failo deskriptorių skaiÄius žinutÄ—je (%d) skiriasi nuo antraÅ¡tÄ—s lauko (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Nepavyko iÅ¡saugoti praneÅ¡imo: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"PraneÅ¡imo pagrindinÄ— dalis turi signatÅ«rÄ… „%s“, bet nÄ—ra signatÅ«ros antraÅ¡tÄ—s" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"PraneÅ¡imo pagrindinÄ— dalis turi tipo signatÅ«rÄ… „%s“, bet signatÅ«ra antraÅ¡tÄ—s " +"lauke yra „%s“" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"PraneÅ¡imo pagrindinÄ— dalis yra tuÅ¡Äia, bet signatÅ«ra antraÅ¡tÄ—s lauke yra " +"„(%s)“" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Klaidos grąžinimas su pagrindinÄ—s dalies tipu „%s“" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Klaidos grąžinimas su tuÅ¡Äia pagrindine dalimi" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Spauskite bet kurį klavišą Å¡iam langui užverti)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Seanso dbus neveikia, automatinis paleidimas nepavyko" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Nepavyko gauti aparatÅ«ros profilio: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Nepavyko įkelti %s arba %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Klaida kvieÄiant StartServiceByName elementui %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Nelauktas atsakas %d iÅ¡ StartServiceByName(\"%s\") metodo" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Nepavyko iÅ¡kviesti metodo; proxy nÄ—ra gerai žinomas pavadinimas %s be " +"savininko ir proxy buvo sukonstruotas su " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START požymiu" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstrakti vardų sritis nepalaikoma" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Negalima nurodyti laikino failo kuriant serverį" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Klaida raÅ¡ant vienkartinio kodo failÄ… vietoje „%s“: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "EilutÄ— „%s“ nÄ—ra tinkamas D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Negalima laukti duomenų iÅ¡ nepalaikomo perdavimo „%s“" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Komandos:\n" +" help Parodo Å¡iÄ… informacijÄ…\n" +" introspect NagrinÄ—ti nutolusį objektÄ…\n" +" monitor StebÄ—ti nutolusį objektÄ…\n" +" call IÅ¡kviesti nutolusio objekto metodÄ…\n" +" emit Siųsti signalÄ…\n" +" wait Laukti, kol pasirodys magistralÄ—s pavadinimas\n" +"\n" +"Naudokite „%s KOMANDA --help“ kiekvienos komandos pagalbos gavimui.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Klaida: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Klaida skaitant introspekcijos XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Klaida: %s nÄ—ra tinkamas vardas\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Klaida: %s nÄ—ra tinkamas objekto kelias\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Prisijungti prie sistemos magistralÄ—s" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Prisijungti prie sesijos magistralÄ—s" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Prisijungti prie pateikto D-Bus adreso" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "RyÅ¡io pabaigos parametrai:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Parametrai, nurodantys ryÅ¡io pabaigÄ…" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "NÄ—ra nurodytos ryÅ¡io pabaigos" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Nurodytos kelio ryÅ¡io pabaigos" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "PerspÄ—jimas: pagal introspekcijos duomenis, sÄ…saja „%s“ neegzistuoja\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"PerspÄ—jimas: pagal introspekcijos duomenis, metodas „%s“ neegzistuoja " +"sÄ…sajoje „%s“\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "NebÅ«tinas signalo tikslas (unikalus vardas)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Objekto, kuriame siunÄiamas signalas, kelias" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Signalo ir sÄ…sajos vardai" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Siųsti signalÄ…." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Klaida prisijungiant: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Klaida: %s nÄ—ra tinkamas unikalus magistralÄ—s pavadinimas.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Klaida: nenurodytas objekto kelias\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Klaida: nenurodytas signalo pavadinimas\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Klaida: signalo pavadinimas „%s“ yra netinkamas\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Klaida: %s nÄ—ra tinkamas sÄ…sajos pavadinimas\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Klaida: %s nÄ—ra tinkamas nario pavadinimas\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Klaida skaitant parametrÄ… %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Klaida iÅ¡siunÄiant ryšį: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Tikslo pavadinimas metodo iÅ¡kvietimui" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Objekto kelias metodo iÅ¡kvietimui" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Metodo ir sÄ…sajos pavadinimai" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Laiko limitas sekundÄ—mis" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Rodyti interaktyviÄ… autorizacijÄ…" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "IÅ¡kviesti metodÄ… nutolusiame objekte." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Klaida: nenurodytas tikslas\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Klaida: %s nÄ—ra tinkamas magistralÄ—s pavadinimas\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Klaida: nenurodytas metodo vardas\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Klaida: metodo vardas „%s“ yra netinkamas\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Klaida skaitant parametrÄ… %d, kurio tipas „%s“: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Klaida pridedant rankenÄ—lÄ™ %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Tikslo vardas introspekcijai" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Objekto kelias introspekcijai" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Spausdinti XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "NagrinÄ—ti vaikÄ…" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Spausdinti tik savybes" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspekcija nutolusiam objektui." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Tikslo vardas stebÄ—jimui" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Objekto kelias stebÄ—jimui" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "StebÄ—ti nutolusį objektÄ…." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Klaida: nepavyksta stebÄ—ti ne žinuÄių magistralÄ—s ryÅ¡io\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Aktyvuotina tarnyba prieÅ¡ laukiant kitos (gerai žinomas pavadinimas)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Kiek laiko laukti prieÅ¡ iÅ¡einant su klaida (sekundÄ—mis); 0 reiÅ¡kia neribotai " +"(numatyta)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[PARAMETRAS…] MAGISTRALÄ–S-PAVADINIMAS" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Laukti, kol pasirodys magistralÄ—s pavadinimas." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "" +"Klaida: reikia nurodyti aktyvuojamÄ… tarnybÄ….\n" +"\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Klaida: turi bÅ«ti nurodyta tarnyba, kurios laukti.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Klaida: per daug argumentų.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Klaida: %s nÄ—ra tinkamas gerai žinomas magistralÄ—s pavadinimas.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Neleidžiama keisti derinimo nuostatų" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Nepavadinta" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Darbalaukio failas nenurodÄ— Exec lauko" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Nerastas terminalas, reikalingas programai" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Nepavyko sukurti naudotojo nustatymų aplanko %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Nepavyko sukurti naudotojo MIME nustatymų aplanko %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Programos informacijai trÅ«ksta identifikatoriaus" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Nepavyko sukurti naudotojo darbalaukio failo %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Specialus apibrėžimas %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "įrenginys nerealizuoja iÅ¡stÅ«mimo" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" +"įrenginys nerealizuoja iÅ¡stÅ«mimo nei su papildoma operacija, nei be jos" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "įrenginys nerealizuoja laikmenos tikrinimo užklausimo" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "įrenginys nerealizuoja startavimo" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "įrenginys nerealizuoja stabdymo" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS realizacija nerealizuoja TLS susiejimų gavimo" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "NÄ—ra TLS palaikymo" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "NÄ—ra DTLS palaikymo" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Nepavyko apdoroti GEmblem koduotÄ—s versijos %d" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Netinkamas leksemų skaiÄius (%d) GEmblem koduotÄ—je" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Nepavyko apdoroti GEmblemedIcon koduotÄ—s versijos %d" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Netinkamas leksemų skaiÄius (%d) GEmblemedIcon koduotÄ—je" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "TikÄ—tasi GEmblem skirto GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "TÄ—vinis prijungimo taÅ¡kas neegzistuoja" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Negalima kopijuoti ant aplanko virÅ¡aus" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Negalima kopijuoti aplanko ant aplanko" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Nurodytas failas jau egzistuoja" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Negalima rekursyviai kopijuoti aplanko" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Skaidymas nepalaikomas" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Klaida skaidant failÄ…: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopijavimas (reflink/clone) tarp prijungimo taÅ¡kų nepalaikomas" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopijavimas (reflink/clone) nepalaikomas arba netinkamas" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopijavimas (reflink/clone) nepalaikomas arba nesuveikÄ—" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Negalima kopijuoti specialaus failo" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Netaisyklinga simbolinÄ—s nuorodos reikÅ¡mÄ—" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "SimbolinÄ—s nuorodos nepalaikomos" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Å iukÅ¡lÄ—s nepalaikomos" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Failų pavadinimuose negali bÅ«ti '%c'" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "tomas nepalaiko prijungimo" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "NÄ—ra programos, priregistruotos kaip skaitanÄios šį failÄ…" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumeratorius užvartas" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Failų enumeratoriui liko neatlikta operacija" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Failų enumeratorius jau užvertas" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Nepavyko apdoroti GFileIcon koduotÄ—s versijos %d" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Netinkami GFileIcon įvesties duomenys" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Srautas nepalaiko query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Pozicijos perkÄ—limas sraute nepalaikomas" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Trumpinimas įėjimo srauto nepalaikomas" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Trumpinimas srauto nepalaikomas" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Klaidingas kompiuterio vardas" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Blogas HTTP tarpinio serverio atsakas" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Prisijungimas prie HTTP tarpinio serverio neleidžiamas" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Nepavyko patvirtinti tapatybÄ—s HTTP tarpiniame serveryje" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP tarpiniam serveriui reikia patvirtinti tapatybÄ™" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Nepavyko prisijungti prie HTTP tarpinio serverio: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP tarpinio serverio atsakymas per didelis" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "RyÅ¡ys su HTTP tarpiniu serveriu netikÄ—tai užvertas." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Neteisingas leksemų skaiÄius (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "NÄ—ra tipo klasÄ—s pavadinimui %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Tipas %s nerealizuoja GIcon sÄ…sajos" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Tipas %s neklasifikuotas" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Netinkamas versijos numeris: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Tipas %s nerealizuoja from_tokens() GIcon sÄ…sajoje" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Nepavyko apdoroti pateiktosios piktogramos koduotÄ—s versijos" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nenurodytas adresas" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "%u yra per didelis ilgis adresui" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adresas turi nustatytus bitus už prieÅ¡dÄ—lio ilgio" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Nepavyko perskaityti „%s“ kaip IP adreso kaukÄ—s" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Nepakanka vietos lizdo adresui" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nepalaikomas lizdo adresas" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Å altinio srautas nerealizuoja skaitymo" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Srautui liko neįvykdyta operacija" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopijuoti kartu su failu" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Palikti kartu su failu kai perkeliama" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "„version“ nepriima argumentų" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Naudojimas:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Atspausdinti versijos informacijÄ… ir iÅ¡eiti." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Komandos:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "IÅ¡vesti failus į standartinÄ™ iÅ¡vestį" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopijuoti vienÄ… ar daugiau failų" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Rodyti informacijÄ… apie vietas" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Paleisti programÄ… pagal desktop failÄ…" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "IÅ¡vardinti vietų turinį" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Gauti arba nustatyti MIME tipo doroklÄ™" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Sukurti katalogus" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "StebÄ—ti failų bei katalogų pasikeitimus" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Prijungti ar atjungti vietas" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Perkelti vienÄ… ar daugiau failų" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Atverti failus naudojant numatytÄ…jÄ… programÄ…" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Pervadinti failÄ…" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "IÅ¡trinti vienÄ… ar daugiau failų" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Skaityti iÅ¡ standartinÄ—s įvesties ir įraÅ¡yti" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Nustatyti failo atributÄ…" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Perkelti failus ar katalogus į Å¡iukÅ¡linÄ™" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "IÅ¡vardina vietų turinį medžio pavidalu" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Naudokite %s detaliai pagalbai.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Klaida raÅ¡ant į standartinÄ™ iÅ¡vestį" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "VIETA" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Sujungti failus ir iÅ¡spausdinti standartinÄ—je iÅ¡vestyje." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat veikia taip pat kaip ir įprastinis cat įrankis, bet naudoja\n" +"GIO vietas vietoj vietinių failų: pavyzdžiui, galite kaip vietÄ… naudoti\n" +"smb://serveris/iÅ¡teklius/failas.txt." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nepateikta vietų" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "NÄ—ra paskirties katalogo" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Rodyti eigÄ…" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Klausti prieÅ¡ perraÅ¡ant" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "IÅ¡laikyti visus atributus" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Padaryti esamų paskirties failų atsargines kopijas" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Niekada neleisti simbolinių nuorodų" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Naudoti numatytuosius leidimus paskirties vietai" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Perduota %s iÅ¡ %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "Å ALTINIS" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "PASKIRTIS" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopijuoti vienÄ… ar daugiau failų iÅ¡ Å ALTINIO į PASKIRTÄ®." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy yra panaÅ¡us į tradicinį cp įrankį, bet naudoja GIO\n" +"vietas vietoj vietinių failų: pavyzdžiui galite naudoti kaip vietÄ…\n" +"smb://serveris/iÅ¡teklius/failas.txt." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Paskirtis %s nÄ—ra katalogas" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: perraÅ¡yti „%s“? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "IÅ¡vardinti keiÄiamus atributus" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Gauti failų sistemos informacijÄ…" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Kuriuos atributus gauti" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTAI" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Nesekti simbolinÄ—mis nuorodomis" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributai:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "rodomas pavadinimas: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "keiÄiamas pavadinimas: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "pavadinimas: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipas: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "dydis: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "paslÄ—ptas\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "vietinis kelias: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix prijungimas: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Nustatomi atributai:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "RaÅ¡omų atributų vardų sritys:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Rodyti informacijÄ… apie vietas." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info yra panaÅ¡us į tradicinį ls įrankį, bet naudoja GIO vietas\n" +"vietoj vietinių failų: pavyzdžiui galite naudoti kaip vietÄ…\n" +"smb://serveris/iÅ¡teklius/failas.txt. Failų atributus galima\n" +"nurodyti jų GIO pavadinimais, pvz. standard::icon, arba tiesiog\n" +"pagal vardų sritį, pvz. unix, arba „*“, kuri atitinka visus atributus" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-FAILAS [FAILO-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Palesti programÄ… pagal desktop failÄ…, perduodant nebÅ«tinÄ… failo pavadinimo " +"argumentÄ…." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nepateiktas desktop failas" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "JÅ«sų platformoje nÄ—ra paleidimo komandos palaikymo" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Nepavyko įkelti „%s“: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Nepavyko įkelti „%s“ programos informacijos" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Nepavyko paleisti programos „%s“: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Rodyti paslÄ—ptus failus" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Naudoti ilgÄ… iÅ¡vardinimo formatÄ…" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Atspausdinti vaizduoklių pavadinimus" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Spausdinti pilnus URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "IÅ¡vardinti vietų turinį." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list yra panaÅ¡us į tradicinį ls įrankį, bet naudoja GIO vietas\n" +"vietoj vietinių failų: pavyzdžiui galite naudoti kaip vietÄ…\n" +"smb://serveris/iÅ¡teklius/failas.txt. Failų atributus galima nurodyti\n" +"jų GIO pavadinimu, pvz. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETIPAS" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "DOROKLÄ–" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Gauti arba nustatyti doroklÄ™ MIME tipui." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Jei nepateikta doroklÄ—, iÅ¡vardina registruotas bei rekomenduojamas\n" +"programas MIME tipui. Jei pateikta doroklÄ—, ji nustatoma kaip\n" +"numatytoji doroklÄ— MIME tipui." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Reikia nurodyti vienÄ… MIME tipÄ… arba doroklÄ™" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "NÄ—ra „%s“ numatytų programų\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Numatyta „%s“ programa: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registruotos programos:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "NÄ—ra registruotų programų\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Rekomenduojamos programos:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "NÄ—ra rekomenduojamų programų:\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Nepavyko įkelti „%s“ doroklÄ—s informacijos" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Nepavyko nustatyti „%s“ kaip numatytosios „%s“ doroklÄ—s: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Sukurti tÄ—vinius katalogus" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Sukurti aplankus." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir yra panaÅ¡us į tradicinį mkdir įrankį, bet naudoja GIO vietas\n" +"vietoj vietinių failų: pavyzdžiui galite naudoti kaip vietÄ…\n" +"smb://serveris/iÅ¡teklius/failas.txt." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "StebÄ—ti katalogÄ… (numatyta: priklauso nuo tipo)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "StebÄ—ti failÄ… (numatyta: priklauso nuo tipo)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"StebÄ—ti failÄ… tiesiogiai (pastebi per tiesiogines nuorodas atliktus " +"pakeitimus)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Stebi failÄ… tiesiogiai, bet nepraneÅ¡a apie pasikeitimus" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"PraneÅ¡ti apie perkÄ—limus bei pervadinimus kaip paprastus trynimo ir sukÅ«rimo " +"įvykius" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "StebÄ—ti prijungimo įvykius" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "StebÄ—ti failų bei katalogų pasikeitimus." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Prijungti kaip prijungiamÄ…" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Prijungti laikmenÄ… su įrenginio failu ar kitu identifikatoriumi" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Atjungti" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "IÅ¡stumti" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Sustabdyti laikmenÄ… su įrenginio failu" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "Ä®RENGINYS" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Atjungti visus prijungimus su pateikta schema" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Nepaisyti vykdomų veiksmų su failas atjungiant ar iÅ¡stumiant" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Naudoti anonimÄ… patvirtinant tapatybÄ™" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "IÅ¡vardinti" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "StebÄ—ti įvykius" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Rodyti papildomÄ… informacijÄ…" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Skaitmeninis PIM atrakinant VeraCrypt tomÄ…" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Prijungti TCRYPT paslÄ—ptÄ… tomÄ…" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Prijungti TCRYPT sisteminį tomÄ…" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Neleidžiama anoniminÄ— prieiga" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "NÄ—ra laikmenos ar įrenginio failo" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "NÄ—ra laikmenos pateiktam ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Prijungti ar atjungti vietas." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Nenaudoti kopijavimo ir trynimo atsarginÄ—s veiksenos" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Perkelti vienÄ… ar daugiau failų iÅ¡ Å ALTINIO į PASKIRTÄ®." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move yra panaÅ¡us į tradicinį mv įrankį, bet naudoja GIO vietas\n" +"vietoj vietinių failų: pavyzdžiui galite naudoti kaip vietÄ…\n" +"smb://serveris/iÅ¡teklius/failas.txt" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Paskirtis %s nÄ—ra katalogas" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Atverti failus numatytÄ…ja programa kuri yra\n" +"priregistruota darbui su Å¡io tipo failais." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Nepaisyti neegzistuojanÄių failų, niekada nepraneÅ¡ti" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "IÅ¡trinti pateiktus failus." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "PAVADINIMAS" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Pervadinti failÄ…." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "TrÅ«ksta argumento" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Per daug argumentų" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "SÄ—kmingai pervadinta. Naujas uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Sukurti tik jei neegzistuoja" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "PridÄ—ti prie failo pabaigos" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Sukuriant riboti prieiga tik esamam naudotojui" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "KeiÄiant pakeisti taip, lyg paskirtis neegzistuotų" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Atspausdinti naujÄ… etag pabaigoje" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "PerraÅ¡omo failo etag" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Klaida skaitant iÅ¡ standartinÄ—s įvesties" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "NÄ—ra etag\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Skaityti iÅ¡ standartinÄ—s įvesties ir įraÅ¡yti PASKIRTYJE." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nepateikta paskirtis" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Atributo tipas" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUTAS" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VERTÄ–" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Nustatyti VIETOS failo atributÄ…." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Nenurodyta vieta" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Nenurodytas atributas" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Nenurodyta vieta" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Netinkamas atributo tipas „%s“" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "IÅ¡valyti Å¡iukÅ¡linÄ™" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "IÅ¡vardinti Å¡iukÅ¡linÄ—s failus su jų pradinÄ—mis vietomis" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Atstatyti failÄ… iÅ¡ Å¡iukÅ¡linÄ—s į jo pradinÄ™ vietÄ… (galima atkuriant katalogÄ…)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Nerastas originalus kelias" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Nepavyko atkurti originalios vietos: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Nepavyksta perkelti failo į jo originaliÄ… vietÄ…: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Perkelti/atkurti failus ar katalogus į Å¡iukÅ¡linÄ™." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Pastaba: --restore raktui, jei pradinÄ— iÅ¡mesto vieta jau yra,\n" +"jis nebus perraÅ¡ytas, nebent nurodysite --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Pateikta vieta neprasideda trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Sekti simbolinÄ—mis nuorodomis, prijungimais bei trumpiniais" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "IÅ¡vardinti katalogų turinį medžio pavidalo formatu." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elementas <%s> neleidžiamas viduje <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elementas <%s> neleidžiamas aukÅ¡Äiausiame lygyje" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Failas %s iÅ¡tekliuje aptinkamas kelis kartus" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Nepavyko rasti „%s“ jokiame Å¡altinio kataloge" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Nepavyko rasti „%s“ esamame kataloge" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Nežinomas apdorojimo parametras „%s“" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "PraÅ¡omas %s apdorojimas, bet %s nenustatytas, o PATH nÄ—ra %s" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Klaida skaitant failÄ… %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Klaida spaudžiant failÄ…: %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "tekstas negali bÅ«ti viduje <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Parodyti programos versijÄ… ir iÅ¡eiti" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "IÅ¡vesties failo pavadinimas" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Katalogai, iÅ¡ kurių skaityti faile nurodytus failus (numatyta iÅ¡ esamo " +"katalogo)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "KATALOGAS" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Generuoti iÅ¡vestį formatu pagal pasirinkto tikslo failo plÄ—tinį" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Generuoti Å¡altinio antraÅ¡tÄ™" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Generuoti kodÄ…, naudojamÄ… iÅ¡teklių failo įriÅ¡imui į jÅ«sų kodÄ…" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Generuoti priklausomybių sÄ…rašą" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Generuojamo priklausomybių failo pavadinimas" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Ä®traukti į sugeneruotÄ… priklausomybių failÄ… netikras paskirtis" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "AutomatiÅ¡kai negeneruoti ir neregistruoti iÅ¡tekliaus" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Neeksportuoti funkcijų; deklaruoti jas G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Neįtraukti iÅ¡tekliaus duomenų C faile; laikyti, kad jis susiejamas iÅ¡oriÅ¡kai" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C identifikatoriaus vardas, naudojamas generuojamame kode" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Paskirties C kompiliatorius (numatyta: aplinkos kintamasis CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompiliuoti resurso specifikacijÄ… į resurso failÄ….\n" +"Resursų specifikacijos failai turi turÄ—ti plÄ—tinį .gresource.xml,\n" +"o resurso failas turi plÄ—tinį gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Turite nurodyti vienintelį failo pavadinimÄ…\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "slapyvardis turi bÅ«ti bent 2 simbolių ilgio" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Neteisinga skaitinÄ— vertÄ—" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " jau nurodytas" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' jau nurodytas" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "požymių vertÄ—s turi turÄ—ti nustatytÄ… vienintelį bitÄ…" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> turi turÄ—ti bent vienÄ… " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> nÄ—ra nurodytuose rėžiuose" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nÄ—ra tinkamas nurodyti iÅ¡vardinimo tipo narys" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> turi simbolių eilutÄ™, kuri nÄ—ra nurodytų požymių tipo" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> turi simbolių eilutÄ™, kurios nÄ—ra " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " jau nurodytas Å¡iam raktui" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " neleidžiamas „%s“ tipo raktams" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " nurodyta mažiausia vertÄ— yra didesnÄ— už didžiausiÄ…" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "nepalaikoma l10n kategorija: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n praÅ¡oma, bet nepateikta gettext sritis" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "vertei pateiktas vertimo kontekstas, bet l10n neįjungta" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Nepavyko perskaityti vertÄ—s tipui „%s“: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" negali bÅ«ti nurodyta raktams, pažymÄ—tiems turinÄiais iÅ¡vardinamÄ… " +"tipÄ…" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " jau nurodytas Å¡iam raktui" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " neleidžiamas „%s“ tipo raktams" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " jau nurodytas" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " turi turÄ—ti bent vienÄ… " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " jau nurodytas Å¡iam raktui" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" gali bÅ«ti nurodytas tik raktams su iÅ¡vardinamais arba požymių " +"tipais, arba po " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr " pateiktas, kai „%s“ jau yra iÅ¡vardinto tipo narys" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" pateiktas, kai jau yra pateiktas" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " jau nurodytas" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "Alt. pavadinimo paskirtis „%s“ nÄ—ra iÅ¡vardinamame tipe" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "Alt. pavadinimo paskirties „%s“ nÄ—ra " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " turi turÄ—ti bent vienÄ… " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Neleidžiami tuÅ¡ti pavadinimai" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" +"Netinkamas pavadinimas „%s“: pavadinimai turi prasidÄ—ti mažosiomis raidÄ—mis" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Netinkamas pavadinimas „%s“: netinkamas simbolis „%c“; leidžiamos tik " +"mažosios raidÄ—s, skaitmenys ir brÅ«kÅ¡niai („-“)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Netinkamas pavadinimas „%s“: du brÅ«kÅ¡niai („--“) vienos po kito neleidžiami." + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" +"Netinkamas pavadinimas „%s“: paskutinis simbolis negali bÅ«ti brÅ«kÅ¡nys („-“)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Netinkamas pavadinimas „%s“: didžiausias leistinas ilgis yra 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " jau nurodyta" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Nepavyko pridÄ—ti raktų į „list-of“ schemÄ…" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " jau nurodytas" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" paslÄ—pia elemente ; " +"naudokite reikÅ¡mei pakeisti" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Kaip atributas elementui turi bÅ«ti nurodytas vienintelis iÅ¡ „type“, " +"„enum“ arba „flags“" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (dar) neapibrėžta." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Netinkama GVariant tipo eilutÄ— „%s“" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " nurodytas, bet schema nieko neiÅ¡pleÄia" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "NÄ—ra perraÅ¡omo " + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " jau nurodytas" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " jau nurodytas" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " iÅ¡pleÄia dar neegzistuojanÄiÄ… schemÄ… „%s“" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " yra sÄ…raÅ¡as iÅ¡ dar neegzistuojanÄios schemos „%s“" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Negali bÅ«ti schemos sÄ…raÅ¡as su keliu" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Negalima iÅ¡plÄ—sti schemos su keliu" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" yra sÄ…raÅ¡as, iÅ¡pleÄiantis , kuris nÄ—ra " +"sÄ…raÅ¡as" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" iÅ¡pleÄia , bet " +"„%s“ neiÅ¡pleÄia „%s“" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Kelias, jei pateiktas, turi prasidÄ—ti ir baigtis pasviruoju brÅ«kÅ¡niu" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "SÄ…raÅ¡o kelias turi baigtis „:/“" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Ä®spÄ—jimas: schema „%s“ turi keliÄ… „%s“. Keliai, prasidedantys „/apps/“, „/" +"desktop/“ ar „/system“ yra pasenÄ™." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> jau nurodytas" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Tik vienas elementas <%s> leidžiamas <%s> viduje" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Elementas <%s> neleidžiamas aukÅ¡Äiausiame lygyje" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Elementas yra bÅ«tinas elemente " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Tekstas negali bÅ«ti viduje <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Ä®spÄ—jimas: neapibrėžta nuoroda į " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict buvo nurodyta; iÅ¡einama." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Visas failas nepaisomas." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Nepaisoma Å¡io failo." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"NÄ—ra rakto „%s“ schemoje „%s“ kaip nurodyta perraÅ¡anÄiame faile „%s“; " +"nepaisoma Å¡io rakto." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"NÄ—ra rakto „%s“ schemoje „%s“ kaip nurodyta perraÅ¡anÄiame faile „%s“ ir buvo " +"nurodyta --strict; iÅ¡einama." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Negalima pateikti darbalaukio pakeitimų lokalizuotam raktui „%s“ schemoje " +"„%s“ (perraÅ¡omas failas „%s“); nepaisoma Å¡io rakto perraÅ¡ymo." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Negalima pateikti darbalaukio pakeitimų lokalizuotam raktui „%s“ schemoje " +"„%s“ (perraÅ¡omas failas „%s“) ir buvo nurodyta --strict; iÅ¡einama." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"klaida skaitant raktÄ… „%s“ schemoje „%s“, kaip nurodyta perraÅ¡anÄiame faile " +"„%s“: %s. Nepaisoma Å¡io rakto perraÅ¡ymo." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"klaida skaitant raktÄ… „%s“ schemoje „%s“, kaip nurodyta perraÅ¡anÄiame faile " +"„%s“: %s. Buvo nurodyta --strict; iÅ¡einama." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"rakto „%s“ perraÅ¡ymas schemoje „%s“ perraÅ¡anÄiame faile „%s“ yra už schemoje " +"nurodytų ribų; nepaisoma Å¡io rakto perraÅ¡ymo." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"rakto „%s“ perraÅ¡ymas schemoje „%s“ perraÅ¡anÄiame faile „%s“ yra už schemoje " +"nurodytų ribų ir buvo nurodyta --strict; iÅ¡einama." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"rakto „%s“ perraÅ¡ymas schemoje „%s“ perraÅ¡anÄiame faile „%s“ nÄ—ra iÅ¡ " +"leistinų pasirinkimų; nepaisoma Å¡io rakto perraÅ¡ymo." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"rakto „%s“ perraÅ¡ymas schemoje „%s“ perraÅ¡anÄiame faile „%s“ nÄ—ra iÅ¡ " +"leistinų pasirinkimų ir buvo nurodyta --strict; iÅ¡einama." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Kur saugoti gschemas.compiled failÄ…" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Nutraukti darbÄ… esant bet kokiai klaidai schemoje" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "NeraÅ¡yti gschema.compiled failo" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Nereikalauti raktų vardų apribojimų" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompiliuoti visus GSettings schamų failus į schemų podÄ—lį.\n" +"Schemų failai turi turÄ—ti plÄ—tinį .gschema.xml,\n" +"o podÄ—lio failas yra vadinamas gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Turite nurodyti vienintelį katalogo pavadinimÄ…" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nerasti schemų failai: nieko nedaroma." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Nerasti schemų failai: paÅ¡alintas egzistuojanti iÅ¡vesties failas." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Netaisyklingas failo vardas %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Klaida gaunant %s failų sistemos informacijÄ…: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Nerastas tÄ—vinis prijungimo taÅ¡kas %s" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Negalima pervadinti Å¡akninio aplanko" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Klaida pervadinant failÄ… %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Nepavyko pervadinti failo, failo vardas jau užimtas" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Netaisyklingas failo vardas" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Klaida atveriant failÄ… %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Klaida trinant failÄ… %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Klaida perkeliant failÄ… %s į Å¡iukÅ¡linÄ™: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Nepavyko sukurti Å¡iukÅ¡lių aplanko %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Nepavyko rasti Å¡akninio aplanko %s iÅ¡mesti" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "IÅ¡metimas tarp sistemos vidinių prijungimo taÅ¡kų nepalaikomas" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Nepavyko rasti ar sukurti Å¡iukÅ¡lių aplanko %s %s iÅ¡mesti" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Nepavyko sukurti Å¡iukÅ¡linÄ—s informacijos failo %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Nepavyko perkelti failo %s į Å¡iukÅ¡linÄ™ per failų sistemos ribas" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Nepavyko failo %s iÅ¡mesti į Å¡iukÅ¡linÄ™: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Nepavyko iÅ¡mesti į Å¡iukÅ¡linÄ™ failo %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Klaida kuriant katalogÄ… %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Failų sistema nepalaiko simbolinių nuorodų" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Klaida kuriant simbolinÄ™ nuorodÄ… %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Klaida perkeliant failÄ… %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Negalima perkelti aplanko ant aplanko" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "AtsarginÄ—s kopijos sukÅ«rimas nesÄ—kmingas" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Klaida trinant nurodytÄ… failÄ…: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "PerkÄ—limas tarp prijungimo taÅ¡kų nepalaikomas" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Nepavyko nustatyti %s disko naudojimo: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Atributo reikÅ¡mÄ— turi bÅ«ti netuÅ¡Äia" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "netaisyklingas atributo tipas (tikimasi simbolių sekos)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "netaisyklingas iÅ¡plÄ—stinio atributo pavadinimas" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Klaida nustatant iÅ¡plÄ—stinį atributÄ… „%s“: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (netaisyklinga koduotÄ—)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Klaida gaunant informacijÄ… apie failÄ… „%s“: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Klaida gaunant informacijÄ… failo apraÅ¡ymui: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Klaidingas atributo tipas (tikimasi uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Klaidingas atributo tipas (tikimasi uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Klaidingas atributo tipas (tikimasi baitų sekos)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "SimbolinÄ—ms nuorodoms teisių nustatyti negalima" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Klaida nustatant teises: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Klaida nustatant savininkÄ…: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "simbolinÄ— nuoroda turi bÅ«ti netuÅ¡Äia" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Klaida nustatant simbolinÄ™ nuorodÄ…: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Klaida, nustatant simbolinÄ™ nuorodÄ…: failas nÄ—ra simbolinÄ— nuoroda" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Papildomos nanosekundÄ—s %d UNIX laiko žymai %lld yra neigiamos" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Papildomos nanosekundÄ—s %d UNIX laiko žymai %lld pasiekia 1 sekundÄ™" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX laiko žyma %lld netelpa į 64 bitus" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "UNIX laiko žyma %lld yra už Windows palaikomų ribų" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Failo pavadinimo „%s“ negalima kontertuoti į UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Failo „%s“ negalima atverti: Windows klaida %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Klaida nustatant pakeitimo arba prieigos laikÄ… failui „%s“: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Klaida nustatant pakeitimo arba prieigos laikÄ…: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux kontekstas bÅ«ti nelygus NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux Å¡ioje sistemoje neįjungtas" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Klaida nustatant SELinux kontekstÄ…: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Atributo %s nustatymas nepalaikomas" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Klaida skaitant failÄ…: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Klaida užveriant failÄ…: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Klaida keiÄiant pozicijÄ… faile: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Nepavyko rasti numatytojo vietinių failų stebyklÄ—s tipo" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Klaida raÅ¡ant į failÄ…: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Klaida Å¡alinant senos atsarginÄ—s kopijos nuorodÄ…: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Klaida kuriant atsarginÄ™ kopijÄ…: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Klaida pervadinant laikinÄ…jį failÄ…: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Klaida trumpinant failÄ…: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Klaida atveriant failÄ… %s: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Paskirties failas yra aplankas" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Paskirties failas nÄ—ra paprastas failas" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Failas buvo pakeistas kitos programos" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Klaida iÅ¡trinant senÄ…jį failÄ…: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Netaisyklingas GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Netinkama pozicijos keitimo užklausa" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Nepavyko sutrumpinti GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Atminties iÅ¡vedimo srauto dydis nekeiÄiamas" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Nepavyko pakeisti atminties iÅ¡vedimo srauto dydžio" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Atminties kiekis, reikalingas įraÅ¡ymui apdoroti, netelpa į prieinamÄ… adresų " +"erdvÄ™" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "PraÅ¡oma perkelti pozicijÄ… dar prieÅ¡ srauto pradžiÄ…" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "PraÅ¡oma perkelti pozicijÄ… jau už srauto pabaigos" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "prijungtasis objektas nepalaiko atjungimo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "prijungtasis objektas nepalaiko iÅ¡stÅ«mimo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"prijungtasis objektas nepalaiko atjungimo nei su papildoma operacija, nei be " +"jos" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"prijungtasis objektas nepalaiko iÅ¡stÅ«mimo nei su papildoma operacija, nei be " +"jos" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "prijungtasis objektas nepalaiko pakartotinio prijungimo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "prijungimo taÅ¡kas nepalaiko turinio tipo spÄ—jimo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "prijungimo taÅ¡kas nepalaiko sinchroninio turinio tipo spÄ—jimo" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Mazgo varde „%s“ yra ženklas „[“, bet nÄ—ra „]“" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Tinklas nepasiekiamas" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Serveris nepasiekiamas" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Nepavyko sukurti tinklo stebyklÄ—s: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Nepavyko sukurti tiklo stebÄ—tojo: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Nepavyko gauti tinklo bÅ«senos: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager neveikia" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Per sena NetworkManager versija" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "IÅ¡vedimo srautas nepalaiko raÅ¡ymo" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "%s perduotų vektorių suma yra per didelÄ—" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Å altinio srautas jau užvertas" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Klaida surandant „%s“: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s nerealizuota" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Neteisinga sritis" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "IÅ¡tekliaus ties „%s“ nÄ—ra" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "IÅ¡tekliaus ties „%s“ nepavyko iÅ¡skleisti" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "IÅ¡teklius ties „%s“ nÄ—ra katalogas" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Ä®vesties srautas nerealizuoja nenuoseklaus skaitymo" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "IÅ¡vardinti sekcijas, turinÄias iÅ¡teklius elf FAILE" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"IÅ¡vardinti iÅ¡teklius\n" +"Jei SEKCIJA pateikta, iÅ¡vardinti tik iÅ¡teklius Å¡ioje sekcijoje\n" +"Jei KELIAS yra pateiktas, iÅ¡vardinti tik atitinkanÄius iÅ¡teklius" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FAILAS [KELIAS]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEKCIJA" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"IÅ¡vardinti iÅ¡teklius su detalÄ—mis\n" +"Jei SEKCIJA pateikta, iÅ¡vardinti tik iÅ¡teklius Å¡ioje sekcijoje\n" +"Jei KELIAS pateiktas, iÅ¡vardinti tik atitinkamus iÅ¡teklius\n" +"Ä® detalÄ—s įeina sekcija, dydis ir glaudinimas" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "IÅ¡gauti iÅ¡tekliaus failÄ… į standartinÄ™ iÅ¡vestį" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FAILO KELIAS" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Naudojimas:\n" +" gresource [--section SEKCIJA] KOMANDA [ARGUMENTAI...]\n" +"\n" +"Komandos:\n" +" help Rodyti Å¡iÄ… informacijÄ…\n" +" sections IÅ¡vardinti sekcijas\n" +" list IÅ¡vardinti iÅ¡teklius\n" +" details IÅ¡vardinti iÅ¡teklius su detalÄ—mis\n" +" extract IÅ¡gauti iÅ¡teklių\n" +"\n" +"Naudokite „gresource help KOMANDA“ detalesnei pagalbai.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Naudojimas:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEKCIJA (NebÅ«tinas) elf sekcijos pavadinimas\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMANDA Komanda (nebÅ«tina) paaiÅ¡kinimui\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" FAILAS elf failas (dvejetainis arba bendro naudojimo biblioteka)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FAILAS elf failas (dvejetainis arba bendro naudojimo biblioteka)\n" +" arba kompiliuotas iÅ¡tekliaus failas\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[KELIAS]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " KELIAS (NebÅ«tinas) iÅ¡tekliaus kelias (gali bÅ«ti dalinis)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "KELIAS" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " KELIAS IÅ¡tekliaus kelias\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "NÄ—ra schemos „%s“\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Schema „%s“ yra neperkeliama (kelias neturi bÅ«ti nurodomas)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schema „%s“ yra perkeliama (kelias turi bÅ«ti nurodytas)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Pateiktas tuÅ¡Äias kelias.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Kelias turi prasidÄ—ti pasviruoju brÅ«kÅ¡niu (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Kelias turi baigtis pasviruoju brÅ«kÅ¡niu (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Kelias neturi turÄ—ti dviejų gretimų pasvirųjų brÅ«kÅ¡nių (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Pateikta reikÅ¡mÄ— yra už leistinų ribų\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Raktas nÄ—ra raÅ¡omas\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "IÅ¡vardinti įdiegtas (neperkeliamas) schemas" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "IÅ¡vardinti įdiegtas perkeliamas schemas" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "IÅ¡vardinti raktus SCHEMOJE" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:KELIAS]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "IÅ¡vardina vaikus SCHEMOJE" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Rekursyviai iÅ¡vardinti raktus ir reikÅ¡mes\n" +"Jei SCHEMA nepateikta, iÅ¡vardinti visus raktus\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:KELIAS]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Gauti RAKTO reikÅ¡mÄ™" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMOS[:KELIO] RAKTAS" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Užklausti galimų reikÅ¡mių rėžių RAKTUI" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Užklausti apraÅ¡ymo RAKTUI" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Nustatyti RAKTO REIKÅ MĘ" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMOS[:KELIO] RAKTO REIKÅ MÄ–" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Nustatyti RAKTÄ„ į jo numatytÄ…jÄ… reikÅ¡mÄ™" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Atstatyti visus SCHEMOS raktus į jų numatytasias reikÅ¡mes" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Patikrinti, ar RAKTAS yra raÅ¡omas" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"StebÄ—ti RAKTO pasikeitimus.\n" +"Jei RAKTAS nenurodytas, stebÄ—ti visus raktus SCHEMOJE.\n" +"Naudoti ^C stebÄ—jimo nutraukimui.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:KELIAS] [RAKTAS]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Naudojimas:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] KOMANDA [ARGUMENTAI...]\n" +"\n" +"Komandos:\n" +" help Rodyti Å¡iÄ… informacijÄ…\n" +" list-schemas IÅ¡vardinti įdiegtas schemas\n" +" list-relocatable-schemas IÅ¡vardinti perskeliamas schemas\n" +" list-keys IÅ¡vardinti raktus schemoje\n" +" list-children IÅ¡vardinti schemos vaikus\n" +" list-recursively Rekursyviai iÅ¡vardinti raktus ir reikÅ¡mes\n" +" range Užklausia rakto rėžių\n" +" describe Užklausia rakto apraÅ¡ymo\n" +" get Gauti rakto reikÅ¡mÄ™\n" +" set Nustatyti rakto reikÅ¡mÄ™\n" +" reset Atstatyti rakto reikÅ¡mÄ™\n" +" reset-recursively Atstatyti visas pateiktos schemos vertes\n" +" writable Patikrinti, ar raktas yra raÅ¡omas\n" +" monitor StebÄ—ti pasikeitimus\n" +"\n" +"Naudokite 'gsettings help KOMANDA' iÅ¡samesnei pagalbai gauti.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Naudojimas:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMOSKAT Katalogas, kur ieÅ¡koti papildomų schemų\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA Schemos pavadinimas\n" +" KELIAS Kelias perkeliamoms schemoms\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " RAKTAS Raktas schemoje (nebÅ«tinas)\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " RAKTAS Raktas schemoje\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " REIKÅ MÄ– ReikÅ¡mÄ—, kuriÄ… nustatyti\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Nepavyko atverti schemų iÅ¡ „%s“: „%s“\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "NÄ—ra įdiegtų schemų\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Pateiktas tuÅ¡Äias schemos pavadinimas\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "NÄ—ra rakto „%s“\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Netinkamas lizdas, nepavyko inicijuoti" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Netinkamas lizdas, nepavyko inicijuoti: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Lizdas jau užvertas" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Lizdo I/O baigÄ—si laikas" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "iÅ¡ fd kuriamas GSocket: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Nepavyko sukurti lizdo: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Nurodyta nežinoma Å¡eima" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Nurodytas nežinomas protokolas" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Negalima naudoti duomenų paketo operacijų ne duomenų paketo lizdui." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Negalima naudoti duomenų paketo operacijų lizdui su laiko limito rinkiniu." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "nepavyko gauto lokalaus adreso: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "nepavyko gauti nuotolinio adreso: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "nepavyko klausytis: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Susiejimo su adresu %s klaida: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Klaida prisijungian prie transliavimo grupÄ—s: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Klaida paliekant transliavimo grupÄ™: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "NÄ—ra resursams specifinio transliavimo palaikymo" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Nepalaikoma lizdo Å¡eima" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "iÅ¡tekliams specifinis nÄ—ra IPv4 adresas" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Per ilgas sÄ…sajos pavadinimas" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "SÄ…saja nerasta: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "NÄ—ra IPv4 iÅ¡tekliams specifinio transliavimo palaikymo" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "NÄ—ra palaikymo, skirto IPv4 iÅ¡tekliams specifiniam transliavimui" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Klaida priimant ryšį: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Prisijungiama" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Nepavyko gauti laukianÄios klaidos: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Klaida priimant duomenis: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Klaida siunÄiant duomenis: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Nepavyko iÅ¡jungti lizdo: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Klaida užveriant lizdÄ…: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Laukiama lizdo bÅ«senos: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Nepavyksta iÅ¡siųsti praneÅ¡imo: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "PraneÅ¡imų vektoriai per dideli" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Klaida siunÄiant praneÅ¡imÄ…: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "„Windows“ sistemoje „GSocketControlMessage“ nepalaikoma" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Klaida priimant praneÅ¡imÄ…: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Nepavyko perskaityti lizdo įgaliojimų: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials nerealizuota Å¡iai operacinei sistemai" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Nepavyko prisijungti prie tarpinio serverio %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Nepavyko prisijungti prie %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Nepavyko prisijungti: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Bandymas naudoti proxy ne per TCP ryšį nepalaikomas." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Tarpinio serverio protokolas „%s“ nepalaikomas." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "GavÄ—jas jau užvertas" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "PridÄ—tasis lizdas yra užvertas" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 nepalaiko IPv6 adreso „%s“" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Naudotojo vardas yra per ilgas SOCKSv4 protokolui" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Kompiuterio vardas „%s“ yra per ilgas SOCKSv4 protokolui" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Serveris nÄ—ra SOCKSv4 proxy serveris." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "RyÅ¡ys per SOCKSv4 serverį buvo atmestas" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Serveris nÄ—ra SOCKSv5 proxy serveris." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 proxy reikalauja tapatybÄ—s patvirtinimo." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 reikalauja tapatybÄ—s patvirtinimo metodo, kurio GLib nepalaiko." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Naudotojo vardas arba slaptažodis yra per ilgas SOCKSv5 protokolui." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5 tapatybÄ—s patvirtinimas nepavyko dÄ—l neteisingo naudotojo vardo arba " +"slaptažodžio." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Kompiuterio vardas „%s“ yra per ilgas SOCKSv5 protokolui" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 proxy serveris naudoja nežinomÄ… adresų tipÄ…." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "VidinÄ— SOCKSv5 proxy serverio klaida." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 ryÅ¡ys neleidžiamas pagal taisykles." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Kompiuteris nepasiekiamas per SOCKSv5 serverį." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Tinklas nepasiekiamas per SOCKSv5 proxy." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "RyÅ¡ys per SOCKSv5 proxy atmestas." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 proxy nepalaiko „connect“ komandos." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 proxy nepalaiko pateikto adreso tipo." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Nežinoma SOCKSv5 proxy klaida." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Nepavyko sukurti konvejerio skirto keistis duomenimis su antriniu procesu " +"(%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Duomenų kanalai Å¡ioje platformoje nepalaikomi" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Nepavyko apdoroti GThemedIcon koduotÄ—s versijos %d" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Nerasta tinkamų adresų" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Klaida atvirkÅ¡Äiai surandant „%s“: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Klaida analizuojant DNS %s įrašą: blogai suformuotas DNS paketas" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "NÄ—ra DNS įraÅ¡o praÅ¡omam tipui „%s“" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Laikinai nepavyko surasti „%s“" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Klaida surandant „%s“" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Blogai suformuotas DNS paketas" + +#: gio/gthreadedresolver.c:886 +#, c-format +#| msgid "Failed to read from file “%sâ€: %s" +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Nepavyko iÅ¡analizuoti DNS atsakymo į „%s“: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Nerastas PEM užkoduotas privatus raktas" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Nepavyko perskaityti PEM užkoduoto privataus rakto" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Nepavyko perskaityti PEM užkoduoto privataus rakto" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Nerastas PEM užkoduotas sertifikatas" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Nepavyko perskaityti PEM užkoduoto sertifikato" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "DabartinÄ— TLS realizacija nepalaiko PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "GTlsBackend nepalaiko PKCS #11 liudijimų kÅ«rimo" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Tai yra paskutinis Å¡ansas įvesti teisingÄ… slaptažodį, kitaip jÅ«sų prieiga " +"bus užrakinta." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Keli įvesti slaptažodžiai buvo neteisingi ir jÅ«sų prieiga bus užblokuota po " +"tolesnių nesÄ—kmių." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Ä®vestas slaptažodis yra neteisingas." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "FD siuntimas nepalaikomas" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "TikÄ—tasi 1 kontrolinio praneÅ¡imo, bet sulaukta %d" +msgstr[1] "TikÄ—tasi 1 kontrolinio praneÅ¡imo, bet sulaukta %d" +msgstr[2] "TikÄ—tasi 1 kontrolinio praneÅ¡imo, bet sulaukta %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "NetikÄ—tas tarnybinių duomenų tipas" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "TikÄ—tasi vieno fd, bet sulaukta %d\n" +msgstr[1] "TikÄ—tasi vieno fd, bet sulaukta %d\n" +msgstr[2] "TikÄ—tasi vieno fd, bet sulaukta %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Gautas netinkamas fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "FD gavimas nepalaikomas" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Klaida siunÄiant įgaliojimus: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Klaida tikrinant, ar SO_PASSCRED įjungta lizdui: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Klaida leidžiant SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Tikimasi nustatyti vienintelį baitÄ… įgaliojimų gavimui, bet nuskaityta nulis " +"baitų" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "NesitikÄ—ta kontrolinio praneÅ¡imo, bet sulaukta %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Klaida iÅ¡jungiant SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Klaida skaitant failÄ…: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Klaida užveriant failÄ…: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Failų sistemos Å¡aknis" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Klaida raÅ¡ant į failÄ…: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "AbstrakÄiųjų UNIX srities lizdų adresai Å¡ioje sistemoje nepalaikomi" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "tomas nerealizuoja iÅ¡stÅ«mimo" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "tomas nerealizuoja iÅ¡stÅ«mimo nei su papildoma operacija,nei be jos" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Klaida skaitant iÅ¡ rankenÄ—lÄ—s: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Klaida užveriant rankenÄ—lÄ™: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Klaida raÅ¡ant į rankenÄ—lÄ™: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nepakanka atminties" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "VidinÄ— klaida: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Reikia daugiau įvesties" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Netinkami suspausti duomenys" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresas, kurio klausytis" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Nepaisoma, suderinamumui su GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Spausdinti adresÄ…" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Spausdinti adresÄ… apvalkalo veiksenoje" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Paleisti dbus tarnybÄ…" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Blogi argumentai\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "NetikÄ—tas atributas „%s“ elementui „%s“" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Nerastas elemento „%2$s“ atributas „%1$s“" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "NetikÄ—ta žyma „%s“, tikÄ—tasi žymos „%s“" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "NetikÄ—ta žyma „%s“ „%s“ viduje" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Netinkama data/laikas „%s“ gairių faile" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Duomenų aplankuose nerasta tinkamo žymelių failo" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "URI „%s“ žymelÄ— jau yra" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nerasta žymelÄ— URI „%s“" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "URI „%s“ žymelÄ—je neapibrėžtas MIME tipas" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "URI „%s“ žymelÄ—je neapibrėžta privati vÄ—liavÄ—lÄ—" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI „%s“ žymelÄ—je nenurodyta jokia grupÄ—" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "NÄ—ra programos pavadinimu „%s“ registravusios „%s“ žymelÄ™" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Nepavyko iÅ¡skleisti vykdomosios eilutÄ—s „%s“ su URI „%s“" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Neatvaizduojamas simbolis keitimo įvestyje" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Nepilna simbolio seka įvedimo pabaigoje" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Negalima keisti atgalinio varianto „%s“ į koduotÄ™ „%s“" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Ä®taisytas NUL baitas keitimo įvestyje" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Ä®taisytas NUL baitas keitimo iÅ¡vestyje" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "Adresas „%s“ nÄ—ra absoliutus adresas naudojantis „file“ schemÄ…" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Vietinio failo adresas „%s“ negali turÄ—ti simbolio „#“" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI „%s“ yra klaidingas" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Kompiuterio vardas URI „%s“ yra netinkamas" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI „%s“ yra klaidingai perkoduoti simboliai" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Kelias „%s“ nÄ—ra absoliutus" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a, %Y m. %b %e d., %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%Y-%m-%d" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "sausis" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "vasaris" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "kovas" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "balandis" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "gegužė" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "birželis" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "liepa" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "rugpjÅ«tis" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "rugsÄ—jis" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "spalis" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "lapkritis" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "gruodis" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "saus." + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "vas." + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "kov." + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "bal." + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "geg." + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "birž." + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "liep." + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "rugp." + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "rugs." + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "spal." + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "lapkr." + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "gruod." + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Pirmadienis" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Antradienis" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "TreÄiadienis" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Ketvirtadienis" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Penktadienis" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Å eÅ¡tadienis" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Sekmadienis" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Pir" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Ant" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Tre" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Ket" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Pen" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Å eÅ¡" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Sek" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "sausio" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "vasario" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "kovo" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "balandžio" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "gegužės" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "birželio" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "liepos" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "rugpjÅ«Äio" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "rugsÄ—jo" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "spalio" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "lapkriÄio" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "gruodžio" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "saus." + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "vas." + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "kov." + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "bal." + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "geg." + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "birž." + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "liep." + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "rugp." + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "rugs." + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "spal." + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "lapkr." + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "gruod." + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Klaida atveriant aplankÄ… „%s“: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Nepavyko iÅ¡skirti %lu baito failo „%s“ perskaitymui" +msgstr[1] "Nepavyko iÅ¡skirti %lu baitų failo „%s“ perskaitymui" +msgstr[2] "Nepavyko iÅ¡skirti %lu baitų failo „%s“ perskaitymui" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Klaida skaitant failÄ… „%s“: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Failas „%s“ per didelis" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Nepavyko perskaityti failo „%s“: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Nepavyko atverti failo „%s“: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Nepavyko gauti failo „%s“ atributų: fstat() klaida: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Nepavyko atverti failo „%s“: fdopen() klaida: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Nepavyko pervadinti failo „%s“ į „%s“: g_rename() klaida: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Nepavyko įraÅ¡yti failo „%s“: write() klaida: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Nepavyko įraÅ¡yti failo „%s“: fsync() klaida: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Nepavyko sukurti failo „%s“: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Nepavyko paÅ¡alinti egzistuojanÄio failo „%s“: g_unlink() klaida: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Å ablonas „%s“ klaidingas, jame negali bÅ«ti „%s“" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Å ablone „%s“ nÄ—ra XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Nepavyko perskaityti simbolinÄ—s nuorodos „%s“: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Nepavyko atverti keitiklio iÅ¡ „%s“ į „%s“: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Negalima vykdyti tiesioginio skaitymo iÅ¡ g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Nepakeistų duomenų likuÄiai skaitymo buferyje" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanalas pasibaigia nepilnu simboliu" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Negalima vykdyti tiesioginio skaitymo iÅ¡ g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "PaieÅ¡kos aplankuose nepavyko rasti tinkamo raktų failo" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "NÄ—ra paprastas failas" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Raktų faile yra eilutÄ— „%s“, kuri nÄ—ra raktas-reikÅ¡mÄ— pora, grupÄ— ar " +"komentaras" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Netinkamas grupÄ—s pavadinimas: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Raktų failas neprasideda grupe" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Netinkamas rakto pavadinimas: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Raktų faile yra nepalaikoma koduotÄ— „%s“" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Raktų failas neturi grupÄ—s „%s“" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Raktų faile nÄ—ra rakto „%s“ grupÄ—je „%s“" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Raktų faile yra raktas „%s“ su reikÅ¡me „%s“, kuri nÄ—ra UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "Raktų faile yra raktas „%s“, turintis nesuprantamÄ… reikÅ¡mÄ™." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Raktų faile yra raktas „%s“ grupÄ—je „%s“, kuriame yra reikÅ¡mÄ—, kurios " +"negalima suprasti." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Raktas „%s“ grupÄ—je „%s“ turi reikÅ¡mÄ™ „%s“, nors tikimasi %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Raktų faile, eilutÄ—s pabaigoje yra pabÄ—gimo simbolis" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Raktų faile yra klaidinga kaitos eilutÄ— „%s“" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "ReikÅ¡mÄ—s „%s“ negalima interpretuoti kaip skaiÄiaus." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Sveikoji reikÅ¡mÄ— „%s“ virÅ¡ija ribas" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "" +"ReikÅ¡mÄ—s „%s“ negalima interpretuoti kaip slankiojo kablelio skaiÄiaus." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "ReikÅ¡mÄ—s „%s“ negalima interpretuoti kaip loginÄ—s." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Nepavyko gauti failo „%s%s%s%s“ atributų: fstat() klaida: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Nepavyko pažymÄ—ti failo %s%s%s%s: mmap() klaida: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Nepavyko atverti failo „%s“: open() klaida: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Klaida eilutÄ—je %d simbolyje %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Klaidingai koduotas UTF-8 tekstas varde – netinkamas „%s“" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "„%s“ nÄ—ra tinkamas vardas" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "„%s“ nÄ—ra tinkamas vardas: „%c“" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Klaida eilutÄ—je %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Nepavyko perskaityti „%-.*s“, kuris galÄ—jo turÄ—ti skaiÄius simbolio apraÅ¡yme " +"(pvz., ê) – gal skaiÄius per didelis" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Simbolio nuoroda nepasibaigÄ— kabliataÅ¡kiu; greiÄiausiai JÅ«s panaudojote " +"ampersendo simbolį nepradÄ—dami elemento įvedimo – pakeiskite ampersendÄ… " +"įvesdami &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Simbolio apraÅ¡ymas „%-.*s“ neatitinka leistinų simbolių" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Aptiktas tuÅ¡Äias elementas '&;'; galimi elementai yra: & " < " +"> '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Elemento vardas „%-.*s“ nežinomas" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Elementas nepasibaigÄ— kabliataÅ¡kiu; greiÄiausiai JÅ«s panaudojote ampersendo " +"simbolį nepradÄ—dami elemento įvedimo – pakeiskite ampersendÄ… įvesdami &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumentas turÄ—tų prasidÄ—ti elementu (pvz., )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"„%s“ negali bÅ«ti raÅ¡omas po „<“ simbolio; jis nepradeda jokio elemento vardo" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Neįprastas simbolis „%s“, tikÄ—tasi sulaukti „>“ simbolio, užbaigianÄio " +"tuÅ¡ÄiÄ… žymÄ… „%s“" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Per daug atributų elemente „%s“" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Neįprastas simbolis „%1$s“, tikÄ—tasi sulaukti „=“ po elemento „%3$s“ " +"atributo vardo „%2$s“" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Neįprastas simbolis „%s“, tikÄ—tasi sulaukti „>“ arba „/“ simbolių, " +"užbaigianÄių elementÄ… „%s“, arba papildomo požymio; gal JÅ«s panaudojote " +"netinkama simbolį požymio varde" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Neįprastas simbolis „%1$s“, po lygybÄ—s tikÄ—tasi sulaukti atidaranÄio " +"citavimo simbolio pradedant „%3$s“ elemento „%2$s“ atributo reikÅ¡mÄ™." + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"„%s“ negali bÅ«ti raÅ¡omas po uždaranÄio elemento vardo „%s“; leistinas " +"simbolis yra „>“" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "" +"Elemento „%s“ uždarymo simbolis sutiktas anksÄiau už elemento atidarymo " +"simbolį" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"Sutiktas elemento „%s“ uždarymo simbolis, taÄiau Å¡iuo metu atidarytas kitas " +"elementas „%s“" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumentas tuÅ¡Äias arba susideda tik iÅ¡ tarpų" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokumentas netikÄ—tai pasibaigÄ— tuoj po atidaranÄių skliaustų „<“" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokumentas netikÄ—tai pasibaigÄ— neuždarius dalies elementų – „%s“ yra " +"paskutinis atviras elementas" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokumentas netikÄ—tai pasibaigÄ—, tikÄ—tasi uždaranÄių skliaustų simbolio, " +"užbaigianÄio žymÄ… <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumentas netikÄ—tai pasibaigÄ— elemento varde" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumentas netikÄ—tai pasibaigÄ— požymio varde" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumentas netikÄ—tai pasibaigÄ— elemento atvÄ—rimo žyma." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokumentas netikÄ—tai pasibaigÄ— lygybÄ—s simboliu einanÄio po požymio vardo; " +"nerasta požymio reikÅ¡mÄ—" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumentas netikÄ—tai pasibaigÄ— požymio verte" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokumentas netikÄ—tai pasibaigÄ— žymos „%s“ uždaranÄiame simbolyje" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "Dokumentas netikÄ—tai pasibaigÄ— neatidaryto elemento uždarymo žymoje" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokumentas netikÄ—tai pasibaigÄ— komentaruose arba apdorojimo instrukcijose" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[PARAMETRAS…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Pagalbos parametrai:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Rodyti pagalbos parametrus" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Rodyti visus pagalbos parametrus" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Programos parametrai:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Parametrai:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Nepavyko perskaityti sveikosios reikÅ¡mÄ—s „%s“, reikalingos %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Sveikoji reikÅ¡mÄ— „%s“, reikalinga %s, virÅ¡ija ribas" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Nepavyko apdoroti dvigubos reikÅ¡mÄ—s „%s“, reikalingos %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Dviguboji reikÅ¡mÄ— „%s“, reikalinga %s, virÅ¡ija ribas" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Klaida apdorojant parametrÄ… %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "%s trÅ«ksta argumento" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Nežinomas parametras %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "sugadintas objektas" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "vidinÄ— klaida arba sugadintas objektas" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "nebÄ—ra atminties" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "pasiekta atgalinio sekimo riba" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "Å¡ablone yra dalinio atitikimo nepalaikomų elementų" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "vidinÄ— klaida" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "atgalinÄ—s nuorodos kaip sÄ…lygos nepalaikomos daliniam atitikimui" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "pasiekta rekursijos riba" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "netinkama naujos eilutÄ—s vÄ—liavÄ—lių kombinacija" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "blogas poslinkis" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "trumpas utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "rekursijos ciklas" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "nežinoma klaida" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ Å¡ablono pabaigoje" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c Å¡ablono pabaigoje" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "neatpažintas simbolis po \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "skaiÄiai ne iÅ¡ eilÄ—s {} kvantoriuje" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "skaiÄius per didelis {} kvantoriuje" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "trÅ«ksta baigiamojo ] simbolio klasei" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "klaidinga speciali seka simbolio klasÄ—je" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "ruožas ne iÅ¡ eilÄ—s simbolio klasÄ—je" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nÄ—ra kÄ… kartoti" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "netikÄ—tas pakartojimas" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "neatpažintas simbolis po (? arba (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "klasÄ—s POSIX vardais leidžiamos tik klasių viduje" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "trÅ«ksta baigiamojo )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "nuoroda į neegzistuojantį poÅ¡ablonį" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "trÅ«ksta ) po komentaro" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "reguliarioji iÅ¡raiÅ¡ka per didelÄ—" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "nepavyko rezervuoti atminties" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") be atveriamojo (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "kodo pervirÅ¡is" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "neatpažintas simbolis po (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "žiÅ«ros atgal teiginys nefiksuoto ilgio" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "netaisyklingas skaiÄius ar vardas po (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "sÄ…lyginÄ— grupÄ— turi daugiau negu dvi Å¡akas" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "tikimasi teiginio po (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "po (?R arba (?[+-]skaitmenys turi bÅ«ti )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nežinomas POSIX klasÄ—s vardas" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX gretinimo elementai nepalaikomi" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "simbolio reikÅ¡mÄ— \\x{…} sekoje per didelÄ—" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "netaisyklinga sÄ…lygÄ… (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C neleistinas žiÅ«ros atgal teiginyje" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "pakaitos simboliai \\L, \\l, \\N{name}, \\U, and \\u nepalaikomi" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "rekursyvus iÅ¡kvietimas gali veikti be galo" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "neatpažintas simbolis po (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "trÅ«ksta baigiamojo simbolio poÅ¡ablonio pavadinime" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "du vardiniai poÅ¡abloniai turi tÄ… patį vardÄ…" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "netaisyklinga \\P arba \\p seka" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nežinomas savybÄ—s vardas po \\P arba \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "poÅ¡ablonio vardas per ilgas (turi bÅ«ti iki 32 simbolių)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "per daug vardinių poÅ¡ablonių (iki 10000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "aÅ¡tuntainÄ— reikÅ¡mÄ— didesnÄ— už \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "perpildyta kompiliavimo darbo sritis" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "anksÄiau tikrintas nurodytas poÅ¡ablonis nerastas" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE grupÄ—je yra daugiau negu viena Å¡aka" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "nenuoseklÅ«s NEWLINE parametrai" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"po \\g nÄ—ra vardo riestiniuose arba lenktiniuose skliaustuose ar teigiamo " +"skaiÄiaus, ar tiesiog skaiÄiaus" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "numeruota nuoroda turi bÅ«ti ne nulis" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "argumentas neleidžiamas veiksmams (*ACCEPT), (*FAIL), ir (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) neatpažintas" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "numeris per didelis" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "trÅ«ksta baigiamojo simbolio poÅ¡ablonio po (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "laukta skaitmens po (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] yra netinkamas duomenų simbolis JavaScript suderinamumo veiksenoje" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "skirtingi vardai to paties skaiÄiaus poÅ¡abloniams nÄ—ra leistini" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) privalo turÄ—ti argumentÄ…" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "Po \\c turi bÅ«ti ASCII simbolis" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"po \\k nÄ—ra vardo riestiniuose arba lenktiniuose skliaustuose arba kabutÄ—se" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N nepalaikomas klasÄ—je" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "per daug nuorodų tolyn" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "pavadinimas yra per ilgas (*MARK), (*PRUNE), (*SKIP), ir (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "simbolio reikÅ¡mÄ— \\u… sekoje per didelÄ—" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Klaida ieÅ¡kant reguliariosios iÅ¡raiÅ¡kos %s atitikmens: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE biblioteka sukompiliuota be UTF8 palaikymo" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE biblioteka sukompiliuota be UTF8 ypatybių palaikymo" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE biblioteka sukompiliuota su nesuderinamais parametrais" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Klaida, optimizuojant reguliariÄ…jÄ… iÅ¡raiÅ¡kÄ… %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Klaida kompiliuojanti reguliariÄ… iÅ¡raiÅ¡kÄ… %s ties simboliu %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "laukta Å¡eÅ¡ioliktainio skaitmens arba „}“" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "laukta Å¡eÅ¡ioliktainio skaitmens" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "simbolinÄ—je nuorodoje trÅ«ksta „<“" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "nebaigta simbolinÄ— nuoroda" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "nulinio ilgio simbolinÄ— nuoroda" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "laukta skaitmens" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "neleistina simbolinÄ— nuoroda" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "nevietoje galutinis „\\“" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "nežinoma kaitos seka" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Klaida apdorojant pakeitimo tekstÄ… „%s“ ties simboliu %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Cituojamas tekstas neprasideda citavimo ženklu" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Nesutampantis citavimo simbolis komandinÄ—je eilutÄ—je arba kitame terpÄ—s " +"cituotame tekste" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Tekstas pasibaigÄ— tuoj po „\\“ simbolio. (Tekste buvo įraÅ¡yta „%s“)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Tekstas pasibaigÄ— nesulaukus %c atitinkanÄio citatos ženklo. (Tekste buvo " +"įraÅ¡yta „%s“)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Tekstas buvo tuÅ¡Äias arba turÄ—jo vien tik tarpo simbolius)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Nepavyko gauti duomenis iÅ¡ antrinio proceso (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "NetikÄ—ta klaida skaitant duomenis žiÅ¡ antrinio proceso (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NetikÄ—ta waitpid() klaida (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Vaikinis procesas išėjo su kodu %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Vaikinis procesas nutrauktas signalu %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Vaikinis procesas sustabdytas signalu %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Vaikinis procesas išėjo nenormaliai" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Nepavyko perskaityti duomenų iÅ¡ antrinio konvejerio (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Nepavyko paleisti antrinio proceso „%s“ (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Nepavyko atskirti (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Nepavyko pereiti į aplankÄ… „%s“ (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Nepavyko paleisti antrinio proceso „%s“ (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Nepavyko atverti failo deskriptoriaus pakeitimui (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Nepavyko dubliuoti failo deskriptoriaus antriniam procesui (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Nepavyko atskirti antrinio proceso (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Nepavyko užverti failo deskriptoriaus antriniam procesui (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Nežinoma klaida vykdant antrinį procesÄ… „%s“" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Nepavyko perskaityti reikiamo duomenų kiekio iÅ¡ antrinio pid konvejerio (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Nepavyko gauti duomenų iÅ¡ antrinio proceso" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Nepavyko paleisti antrinio proceso (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Nepavyko antriniams procesui iÅ¡kviesti dup() (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Netinkamas programos pavadinimas: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Netinkama seka argumento vektoriuje, pozicijoje %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Netinka seka aplinkoje: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Netinkamas darbinis katalogas: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Nepavyko paleisti pagalbinÄ—s programos (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"NetikÄ—ta klaida tarp g_io_channel_win32_poll() funkcijos duomenų skaitymo iÅ¡ " +"antrinio proceso metu" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "TuÅ¡Äia simbolių eilutÄ— nÄ—ra skaiÄius" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s“ nÄ—ra skaiÄius su ženklu" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "SkaiÄius „%s“ yra už [%s, %s] ribų" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s“ nÄ—ra skaiÄius be ženklo" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "URI yra netinkamas %-kodavimas" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "URI yra neleistinas simbolis" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "URI yra ne UTF-8 simbolių" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "URI yra netinkamas IPv6 adresas „%.*s“" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "URI yra neteisingai koduotas IP adresas „%.*s“" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "URI yra neteisingai internacionalizuotas serverio pavadinimas „%.*s“" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Nepavyko perskaityti URI esanÄio prievado „%.*s“" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "URI esantis prievadas „%.*s“ yra už ribų" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI „%s“ nÄ—ra absoliutus URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI „%s“ neturi kompiuterio komponentÄ—s" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI nÄ—ra absoliutus ir nepateiktas bazinis URI" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "TrÅ«ksta „=“ bei parametro vertÄ—s" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Nepavyko iÅ¡skirti atminties" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Simbolis neatitinka UTF-8 simbolių diapazono" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Klaidinga seka keitimo įvestyje" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Simbolis neatitinka UTF-16 simbolių diapazono" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u baitas" +msgstr[1] "%u baitai" +msgstr[2] "%u baitų" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bitas" +msgstr[1] "%u bitai" +msgstr[2] "%u bitų" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s baitas" +msgstr[1] "%s baitai" +msgstr[2] "%s baitų" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bitas" +msgstr[1] "%s bitai" +msgstr[2] "%s bitų" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Nepavyko įkelti /var/lib/dbus/machine-id or /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Nežinoma klaida prisijungiant" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Klaida adrese „%s“ - neteisingai suformuotas Å¡eimos atributas" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s prijungta kelyje %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; nepaisoma Å¡io rakto perraÅ¡ymo.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " ir --strict nurodyta; iÅ¡einama.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Nepaisoma Å¡io rakto perraÅ¡ymo.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "nedaro nieko.\n" + +#~ msgid "No such interface '%s'" +#~ msgstr "NÄ—ra sÄ…sajos „%s“" + +#~ msgid "No such method '%s'" +#~ msgstr "NÄ—ra metodo „%s“" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Nepavyko nustatyti magistralÄ—s adreso iÅ¡ DBUS_STARTER_BUS_TYPE aplinkos " +#~ "kintamojo - nežinoma reikÅ¡mÄ— „%s“" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGUMENTAI...]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Nepavyko sukurti laikino failo: %s" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "PraneÅ¡imas turi %d failų deskriptorių, bet antraÅ¡tÄ—s laukas nurodo %d " +#~ "failų deskriptorius" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Klaida: nenurodytas objekto kelias.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Klaida: nenurodytas signalas.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Klaida: signalas turi bÅ«ti pilnai-kvalifikuotas pavadinimas.\n" + +#~ msgid "No such interface" +#~ msgstr "NÄ—ra tokios sÄ…sajos" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Klaida gaunant keiÄiamus atributus: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Klaida prijungiant vietÄ…: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Klaida atjungiant prijungimÄ…: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Klaida ieÅ¡kant gaubianÄio prijungimo: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Klaida iÅ¡stumiant prijungimÄ…: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Klaida prijungiant %s: %s\n" + +#~ msgid "No files to open" +#~ msgstr "NÄ—ra failų atvÄ—rimui" + +#~ msgid "No files to delete" +#~ msgstr "NÄ—ra trinamų failų" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Klaida nustatant atributÄ… %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Klaida kuriant katalogÄ… „%s“: %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Klaida atveriant failÄ… „%s“: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Klaida skaitant failÄ… „%s“: %s" + +#~ msgid "No locations gives" +#~ msgstr "Nepateikta vietų" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Klaida pervadinant failÄ…: %s" + +#~ msgid "Can't open directory" +#~ msgstr "Nepavyko atverti aplanko" + +#~ msgid "Error opening file: %s" +#~ msgstr "Klaida atveriant failÄ…: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Klaida atveriant aplankÄ…: %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Nepavyko rasti įprasto vietinių aplankų stebÄ—jimo tipo" + +#~ msgid "association changes not supported on win32" +#~ msgstr "saitų keitimai win32 sistemose nepalaikomi" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Saitų kÅ«rimas win32 sistemose nepalaikomas" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Raktų failas neturi rakto „%s“" diff --git a/po/lv.po b/po/lv.po new file mode 100644 index 0000000..1f91293 --- /dev/null +++ b/po/lv.po @@ -0,0 +1,6244 @@ +# glib for Latvian. +# Copyright (C) 2002 Free Software Foundation, Inc. +# +# +# Artis Trops , 2002. +# RÅ«dofls Mazurs , 2011, 2012. +# RÅ«dolfs Mazurs , 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2020, 2021. +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2021-07-19 15:52+0000\n" +"PO-Revision-Date: 2021-10-25 19:39+0300\n" +"Last-Translator: RÅ«dolfs Mazurs \n" +"Language-Team: Latvian \n" +"Language: lv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 21.08.1\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 :" +" 2);\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication opcijas" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "ParÄdÄ«t GApplication opcijas" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Ievadiet GApplication servisa režīmu (izmantot no D-Bus servisa datnÄ“m)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "PÄrrakstÄ«t lietotnes ID" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Aizvietot palaisto instanci" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:572 +msgid "Print help" +msgstr "DrukÄÅ¡anas palÄ«dzÄ«ba" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[KOMANDA]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "DrukÄt versiju" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:578 +msgid "Print version information and exit" +msgstr "ParÄdÄ«t informÄciju par versiju un iziet" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "UzskaitÄ«t lietotnes" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"UzskaitÄ«t instalÄ“tÄs D-Bus aktivizÄ“jamÄs lietotnes (ar .desktop datnÄ“m)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Palaist lietotni" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Palaist lietotni (ar neobligÄti atveramÄm datnÄ“m)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "LIETID [DATNE…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "AktivizÄ“t darbÄ«bu" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Izsaukt darbÄ«bu uz lietotni" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "LIETID DARBĪBA [PARAMETRS]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Uzskaita pieejamÄs darbÄ«bas" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Uzskaita statiskÄs darbÄ«bas lietotnei (no .desktop datnes)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "LIETID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMANDA" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Komanda, lai drukÄtu detalizÄ“tu palÄ«dzÄ«bu priekÅ¡" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Lietotnes identifikators D-Bus formÄtÄ(piemÄ“ram: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "DATNE" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"NeobligÄts relatÄ«vs vai absolÅ«ts datnes nosaukums, vai URI, lai atvÄ“rtu" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "DARBĪBA" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "DarbÄ«bas nosaukums, ko izsaukt" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETRS" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "NeobligÄts parametrs darbÄ«bas izsaukÅ¡anai, GVariant formÄtÄ" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:664 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"NezinÄma komanda %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "LietoÅ¡ana:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:699 +msgid "Arguments:\n" +msgstr "Argumenti:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARG…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Komandas:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Lietojiet “%s help KOMANDAâ€, lai iegÅ«tu detalizÄ“tu palÄ«dzÄ«bu.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s komandai vajag lietotnes id, lai tieÅ¡i sekotu\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "nederÄ«gs lietotnes id — “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†nepieņem argumentus\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "NevarÄ“ja savienoties ar D-Bus — %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "kļūda, sÅ«tot %s ziņojumu lietotnei — %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "darbÄ«bas nosaukumam ir jÄbÅ«t dotam pÄ“c lietotnes id\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nederÄ«gs darbÄ«bas nosaukums — “%sâ€\n" +"darbÄ«bas nosaukumÄ var bÅ«t tikai burti, cipari, “-†un “.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "kļūda, parsÄ“jot darbÄ«bas parametru — %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "darbÄ«bas pieņem ne vairÄk ka vienu parametru\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "darbÄ«bu uzskaites komanda pieņem tikai lietotnes id" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "nevar atrast darbvirsmas datni lietotnei %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"neatpazÄ«ta komanda: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "PÄrÄk liela vÄ“rtÄ«ba tika padota %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Uz bÄzes plÅ«smas meklēšana netiek atbalstÄ«ta" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Nevar apraut GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "PlÅ«sma jau ir aizvÄ“rta" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Uz bÄzes plÅ«smas aprauÅ¡ana nav atbalstÄ«ta" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1872 gio/gdbusprivate.c:1416 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "DarbÄ«ba tika atcelta" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "NederÄ«gs objekts, nav inicializÄ“ts" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "NepilnÄ«ga vairÄku baitu sekvence ievadÄ“" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "MÄ“rÄ·Ä« nepietiek brÄ«vÄs vietas" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "Nepareiza baitu secÄ«ba konversijas ievadÄ“" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Kļūda, konversÄ“jot — %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1143 +msgid "Cancellable initialization not supported" +msgstr "Atceļama inicializÄcija nav atbalstÄ«ta" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "PÄrveidoÅ¡ana no rakstzÄ«mju kopas “%s†uz “%s†nav atbalstÄ«ta" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "NevarÄ“ja atvÄ“rt pÄrveidotÄju no “%s†uz “%sâ€" + +#: gio/gcontenttype.c:454 +#, c-format +msgid "%s type" +msgstr "%s tips" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "NezinÄms tips" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s datnes tips" + +#: gio/gcredentials.c:323 +msgid "GCredentials contains invalid data" +msgstr "GCredentials satur nederÄ«gus datus" + +#: gio/gcredentials.c:383 gio/gcredentials.c:667 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials nav implementÄ“ti Å¡ajÄ OS" + +#: gio/gcredentials.c:538 gio/gcredentials.c:556 +msgid "There is no GCredentials support for your platform" +msgstr "Å ajÄ platformÄ nav GCredentials atbalsta" + +#: gio/gcredentials.c:607 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials nesatur procesa ID Å¡ajÄ OS" + +#: gio/gcredentials.c:661 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Å ajÄ OS nevar viltot akreditÄcijas datus" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "NegaidÄ«ti agras plÅ«smas beigas" + +#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "NeatbalstÄ«ta atslÄ“ga “%s†adreses ierakstÄ â€œ%sâ€" + +#: gio/gdbusaddress.c:172 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "BezjÄ“dzÄ«gas atslÄ“gu/vÄ“rtÄ«bu pÄru kombinÄcijas adreÅ¡u ierakstÄ â€œ%sâ€" + +#: gio/gdbusaddress.c:181 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adrese “%s†ir nederÄ«ga (vajag tieÅ¡i vienu atslÄ“gu: path, dir, tmpdir vai " +"abstract)" + +#: gio/gdbusaddress.c:248 gio/gdbusaddress.c:259 gio/gdbusaddress.c:274 +#: gio/gdbusaddress.c:337 gio/gdbusaddress.c:348 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Kļūda adresÄ“ “%s†— “%s†atribÅ«ts ir slikti noformÄ“ts" + +#: gio/gdbusaddress.c:418 gio/gdbusaddress.c:682 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "NezinÄms vai neatbalstÄ«ts transports “%s†adresei “%sâ€" + +#: gio/gdbusaddress.c:462 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adreses elements “%s†nesatur kolu (:)" + +#: gio/gdbusaddress.c:471 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Transporta nosaukums adreses elementÄ â€œ%s†nedrÄ«kst bÅ«t tukÅ¡s" + +#: gio/gdbusaddress.c:492 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"AtslÄ“gas/vÄ“rtÄ«bas pÄris %d, “%sâ€, adreses elementÄ â€œ%sâ€, nesatur vienÄdÄ«bas " +"zÄ«mi" + +#: gio/gdbusaddress.c:503 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"AtslÄ“gas/vÄ“rtÄ«bas pÄris %d, “%sâ€, adreses elementÄ â€œ%sâ€, nedrÄ«kst saturÄ“t " +"tukÅ¡u atslÄ“gu" + +#: gio/gdbusaddress.c:517 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Kļūda, noņemot atsoli atslÄ“gai vai vÄ“rtÄ«bai atslÄ“ga/vÄ“rtÄ«ba pÄrÄ« %d. “%sâ€, " +"adreses elementÄ â€œ%sâ€" + +#: gio/gdbusaddress.c:589 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Kļūda adresÄ“ “%s†— unix transportam nepiecieÅ¡ams iestatÄ«t tieÅ¡i vienu " +"atslÄ“gu “path†vai “abstractâ€" + +#: gio/gdbusaddress.c:625 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Kļūda adresÄ“ “%s†— trÅ«kst vai slikti noformÄ“ts resursdatora atribÅ«ts" + +#: gio/gdbusaddress.c:639 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Kļūda adresÄ“ “%s†— trÅ«kst vai slikti noformÄ“ts porta atribÅ«ts" + +#: gio/gdbusaddress.c:653 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "Kļūda adresÄ“ “%s†— trÅ«kst vai slikti noformÄ“ts noncefile atribÅ«ts" + +#: gio/gdbusaddress.c:674 +msgid "Error auto-launching: " +msgstr "Kļūda, automÄtiski palaižot: " + +#: gio/gdbusaddress.c:727 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Kļūda, atverot nonce datni “%s†— %s" + +#: gio/gdbusaddress.c:746 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Kļūda, nolasot no nonce datnes “%s†— %s" + +#: gio/gdbusaddress.c:755 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Kļūda, nolasot no nonce datnes “%s†— gaidÄ«ja 16 baitus, saņēma %d" + +#: gio/gdbusaddress.c:773 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Kļūda, rakstot nonce datnes “%s†saturu uz straumi:" + +#: gio/gdbusaddress.c:988 +msgid "The given address is empty" +msgstr "DotÄ adrese ir tukÅ¡a" + +#: gio/gdbusaddress.c:1101 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Nevar izveidot ziņojumu kopni, kad veic machine-id" + +#: gio/gdbusaddress.c:1108 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Nevar izveidot ziņojumu kopni bez machine-id: " + +#: gio/gdbusaddress.c:1115 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Nevar automÄtiski palaist D-Bus bez X11 $DISPLAY" + +#: gio/gdbusaddress.c:1157 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Kļūda, izveidojot komandrindu “%sâ€: " + +#: gio/gdbusaddress.c:1226 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "Nevar noteikt sesijas kopnes adresi (nav implementÄ“ts Å¡ai OS)" + +#: gio/gdbusaddress.c:1397 gio/gdbusconnection.c:7261 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Nevar noteikt kopnes adresi no DBUS_STARTER_BUS_TYPE vides mainÄ«gÄ â€” " +"nezinÄma vÄ“rtÄ«ba “%sâ€" + +#: gio/gdbusaddress.c:1406 gio/gdbusconnection.c:7270 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Nevar noteikt kopnes adresi, jo DBUS_STARTER_BUS_TYPE vides mainÄ«gais nav " +"iestatÄ«ts" + +#: gio/gdbusaddress.c:1416 +#, c-format +msgid "Unknown bus type %d" +msgstr "NezinÄms kopnes tips %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "NegaidÄ«ts satura trÅ«kums, mēģinot lasÄ«t rindu" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "NegaidÄ«ts satura trÅ«kums, mēģinot (droÅ¡i) lasÄ«t rindu" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Izsmelti visi pieejamie autentifikÄcijas mehÄnismi (mēģinÄti: %s) (pieejami: " +"%s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "LietotÄja ID ir jÄbÅ«t vienÄdiem gan biedram, gan serverim" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Atcelts caur GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:298 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Kļūda, saņemot informÄciju par mapi “%s†— %s" + +#: gio/gdbusauthmechanismsha1.c:313 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Atļaujas mapei “%s†ir slikti formatÄ“tas. GaidÄ«ja režīmu 0700, saņēma 0%o" + +#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Kļūda, veidojot direktoriju “%s†— %s" + +#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1062 gio/gfile.c:1300 +#: gio/gfile.c:1438 gio/gfile.c:1676 gio/gfile.c:1731 gio/gfile.c:1789 +#: gio/gfile.c:1873 gio/gfile.c:1930 gio/gfile.c:1994 gio/gfile.c:2049 +#: gio/gfile.c:3754 gio/gfile.c:3809 gio/gfile.c:4102 gio/gfile.c:4572 +#: gio/gfile.c:4983 gio/gfile.c:5068 gio/gfile.c:5158 gio/gfile.c:5255 +#: gio/gfile.c:5342 gio/gfile.c:5443 gio/gfile.c:8153 gio/gfile.c:8243 +#: gio/gfile.c:8327 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "DarbÄ«ba nav atbalstÄ«ta" + +#: gio/gdbusauthmechanismsha1.c:402 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Kļūda, atverot atslÄ“gu saišķi “%s†lasīšanai: " + +#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Rinda %d atslÄ“gu saišķim “%s†ar saturu “%s†ir slikti formatÄ“ts" + +#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Pirmais marÄ·ieris rindai %d atslÄ“gu saišķim “%s†ar saturu “%s†ir slikti " +"formatÄ“ts" + +#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Otrais marÄ·ieris rindai %d atslÄ“gu saišķim “%s†ar saturu “%s†ir slikti " +"formatÄ“ts" + +#: gio/gdbusauthmechanismsha1.c:477 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Neatrada sÄ«kdatni ar id %d atslÄ“gu saišķī “%sâ€" + +#: gio/gdbusauthmechanismsha1.c:523 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Kļūda, veidojot slÄ“gÅ¡anas datni “%s†— %s" + +#: gio/gdbusauthmechanismsha1.c:587 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Kļūda, dzēšot neesoÅ¡u slÄ“gÅ¡anas datni “%s†— %s" + +#: gio/gdbusauthmechanismsha1.c:626 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Kļūda, aizverot (atsaitÄ“jot) slÄ“gÅ¡anas datni “%s†— %s" + +#: gio/gdbusauthmechanismsha1.c:637 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Kļūda, atsaitÄ“jot slÄ“gÅ¡anas datni “%s†— %s" + +#: gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Kļūda, atverot atslÄ“gu saišķi “%s†rakstīšanai: " + +#: gio/gdbusauthmechanismsha1.c:908 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Un vÄ“l, “%s†slÄ“guma atbrÄ«voÅ¡ana neizdevÄs — %s) " + +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2417 +msgid "The connection is closed" +msgstr "Savienojums ir aizvÄ“rts" + +#: gio/gdbusconnection.c:1902 +msgid "Timeout was reached" +msgstr "IestÄjÄs noildze" + +#: gio/gdbusconnection.c:2540 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"SastapÄs ar neatbalstÄ«tiem slÄ“džiem (flag), veidojot klienta puses " +"savienojumu" + +#: gio/gdbusconnection.c:4189 gio/gdbusconnection.c:4536 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Nav tÄdas saskarnes “org.freedesktop.DBus.Properties†uz objekta ceļa %s" + +#: gio/gdbusconnection.c:4331 +#, c-format +msgid "No such property “%sâ€" +msgstr "Nav tÄdas Ä«pašības “%sâ€" + +#: gio/gdbusconnection.c:4343 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Īpašība “%s†nav lasÄma" + +#: gio/gdbusconnection.c:4354 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Īpašība “%s†nav rakstÄma" + +#: gio/gdbusconnection.c:4374 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "Kļūda, iestatot Ä«pašību “%s†— gaidÄ«ja tipu “%sâ€, bet saņēma “%sâ€" + +#: gio/gdbusconnection.c:4479 gio/gdbusconnection.c:4687 +#: gio/gdbusconnection.c:6689 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Nav tÄdas saskarnes “%sâ€" + +#: gio/gdbusconnection.c:4905 gio/gdbusconnection.c:7201 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Nav tÄdas saskarnes “%s†uz objekta ceļa %s" + +#: gio/gdbusconnection.c:5003 +#, c-format +msgid "No such method “%sâ€" +msgstr "Nav tÄdas metodes “%sâ€" + +#: gio/gdbusconnection.c:5034 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Ziņojuma tips “%s†neatbilda gaidÄ«tajam tipam “%sâ€" + +#: gio/gdbusconnection.c:5237 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Objekts jau ir eksportÄ“ts saskarnei %s pie %s" + +#: gio/gdbusconnection.c:5463 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Nevar saņemt Ä«pašību %s.%s" + +#: gio/gdbusconnection.c:5519 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Nevar iestatÄ«t Ä«pašību %s.%s" + +#: gio/gdbusconnection.c:5698 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metode “%s†atgrieza tipu “%sâ€, bet gaidÄ«ja “%sâ€" + +#: gio/gdbusconnection.c:6800 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metode “%s†uz saskarnes “%s†ar parakstu “%s†neeksistÄ“" + +#: gio/gdbusconnection.c:6921 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "%s apakÅ¡koks jau ir eksportÄ“ts " + +#: gio/gdbusconnection.c:7209 +#, c-format +#| msgid "Key file does not have group “%sâ€" +msgid "Object does not exist at path “%sâ€" +msgstr "CeÄ¼Ä â€œ%s†objekts neeksistÄ“" + +#: gio/gdbusmessage.c:1266 +msgid "type is INVALID" +msgstr "tips ir INVALID" + +#: gio/gdbusmessage.c:1277 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL ziņojums — trÅ«kst PATH vai MEMBER galvene" + +#: gio/gdbusmessage.c:1288 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN ziņojums — trÅ«kst REPLY_SERIAL galvenes lauks" + +#: gio/gdbusmessage.c:1300 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR ziņojums — trÅ«kst REPLY_SERIAL vai ERROR_NAME galvenes lauks" + +#: gio/gdbusmessage.c:1313 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL ziņojums — trÅ«kst PATH, INTERFACE vai MEMBER galvenes datne" + +#: gio/gdbusmessage.c:1321 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL ziņojums — PATH galvenes datne izmanto rezervÄ“to vÄ“rtÄ«bu /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1329 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL ziņojums — INTERFACE galvenes dante izmanto rezervÄ“to vÄ“rtÄ«bu org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "VÄ“lÄ“jÄs lasÄ«t %lu baitu, bet saņēma %lu" +msgstr[1] "VÄ“lÄ“jÄs lasÄ«t %lu baitus, bet saņēma %lu" +msgstr[2] "VÄ“lÄ“jÄs lasÄ«t %lu baitus, bet saņēma %lu" + +#: gio/gdbusmessage.c:1391 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "GaidÄ«ja NUL baitu pÄ“c virknes “%sâ€, bet atrada baitu %d" + +#: gio/gdbusmessage.c:1410 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"GaidÄ«ja derÄ«gu UTF-8 virkni, bet atrada nederÄ«gus baitus pie baitu nobÄ«des " +"%d (virknes garums ir %d). DerÄ«gÄ UTF-8 virkne lÄ«dz tai vietai bija “%sâ€" + +#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911 +msgid "Value nested too deeply" +msgstr "VÄ“rtÄ«ba ir iegulta pÄrÄk dziļi" + +#: gio/gdbusmessage.c:1620 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "ParsÄ“tÄ vÄ“rtÄ«ba “%s†nav derÄ«gs D-Bus objekta ceļš" + +#: gio/gdbusmessage.c:1642 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "ParsÄ“tÄ vÄ“rtÄ«ba “%s†nav derÄ«gs D-Bus objekta paraksts" + +#: gio/gdbusmessage.c:1689 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"SaskÄrÄs ar %u baitu garu masÄ«vu. MaksimÄlais garums ir 2<<26 baiti (64 " +"MiB)." +msgstr[1] "" +"SaskÄrÄs ar %u baitus garu masÄ«vu. MaksimÄlais garums ir 2<<26 baiti (64 " +"MiB)." +msgstr[2] "" +"SaskÄrÄs ar %u baitu garu masÄ«vu. MaksimÄlais garums ir 2<<26 baiti (64 " +"MiB)." + +#: gio/gdbusmessage.c:1709 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"SaskÄrÄs ar masÄ«vu, kam tips ir “a%câ€, kura garumam vajadzÄ“tu dalÄ«ties ar %u " +"baitiem, bet tÄ garums ir %u baiti" + +#: gio/gdbusmessage.c:1895 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "ParsÄ“tÄ vÄ“rtÄ«ba “%s†variantam nav derÄ«gs D-Bus paraksts" + +#: gio/gdbusmessage.c:1936 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Kļūda, deserializÄ“jot GVariant ar tipa virkni “%s†no D-Bus vadu formÄta" + +#: gio/gdbusmessage.c:2121 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"NederÄ«ga secÄ«bas (endian) vÄ“rtÄ«ba. GaidÄ«ja 0x6c (“lâ€) vai 0x42 (“Bâ€), bet " +"atrada vÄ“rÄ«bu 0x%02x" + +#: gio/gdbusmessage.c:2134 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "NederÄ«ga lielÄ protokola vÄ“rtÄ«ba. GaidÄ«ja 1, bet saņēma %d" + +#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784 +msgid "Signature header found but is not of type signature" +msgstr "Parasta galvene ir atrasta, bet tai nav tipa paraksta" + +#: gio/gdbusmessage.c:2200 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Paraksta galvene ar parakstu “%s†atrasta, bet vÄ“stules pamatteksts ir tukÅ¡s" + +#: gio/gdbusmessage.c:2215 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "ParsÄ“tÄ vÄ“rtÄ«ba “%s†nav derÄ«gs D-Bus paraksts (pamattekstam)" + +#: gio/gdbusmessage.c:2247 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"ZiņojumÄ nav paraksta galvenes, bet ziņojuma pamatteksts ir %u baits" +msgstr[1] "" +"ZiņojumÄ nav paraksta galvenes, bet ziņojuma pamatteksts ir %u baiti" +msgstr[2] "" +"ZiņojumÄ nav paraksta galvenes, bet ziņojuma pamatteksts ir %u baitu" + +#: gio/gdbusmessage.c:2257 +msgid "Cannot deserialize message: " +msgstr "Nevar deserializÄ“t ziņojumu: " + +#: gio/gdbusmessage.c:2601 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "Kļūda, serializÄ“jot GVariant ar tipa virkni “%s†uz D-Bus vadu formÄtu" + +#: gio/gdbusmessage.c:2738 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "Datņu deskriptoru skaits (%d) ziņojumÄ atšķiras no galvenes lauka (%d)" + +#: gio/gdbusmessage.c:2746 +msgid "Cannot serialize message: " +msgstr "Nevar serializÄ“t ziņojumu: " + +#: gio/gdbusmessage.c:2799 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Ziņojuma pamattekstam ir paraksts “%sâ€, bet nav paraksta galvenes" + +#: gio/gdbusmessage.c:2809 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"VÄ“stules pamattekstam ir tipa paraksts “%sâ€, bet paraksts galvenes laukÄ ir " +"“%sâ€" + +#: gio/gdbusmessage.c:2825 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Ziņojuma pamatteksts ir tukÅ¡s, bet paraksta galvenes lauks ir “(%s)â€" + +#: gio/gdbusmessage.c:3380 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Kļūdas atgrieÅ¡ana ar pamattekstu ar tipu “%sâ€" + +#: gio/gdbusmessage.c:3388 +msgid "Error return with empty body" +msgstr "Kļūdas atgrieÅ¡ana ar tukÅ¡u pamattekstu" + +#: gio/gdbusprivate.c:2246 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Ievadiet jebkuru rakstzÄ«mi, lai aizvÄ“rtu Å¡o logu)\n" + +#: gio/gdbusprivate.c:2420 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Sesijas dbus nav palaists un automÄtiskÄ palaiÅ¡ana cieta neveiksmi" + +#: gio/gdbusprivate.c:2443 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Nevar saņemt aparatÅ«ras profilu — %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2494 +#, c-format +#| msgid "Unable to load ‘%s‘: %s" +msgid "Unable to load %s or %s: " +msgstr "Nevar ielÄdÄ“t %s vai %s: " + +#: gio/gdbusproxy.c:1569 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Kļūda, izsaucot StartServiceByName priekÅ¡ %s: " + +#: gio/gdbusproxy.c:1592 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "NegaidÄ«ta atbilde %d no StartServiceByName(“%sâ€) metodes" + +#: gio/gdbusproxy.c:2699 gio/gdbusproxy.c:2834 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Nevar izsaukt metodi; starpnieks ir labi zinÄmam nosaukumam %s bez " +"Ä«paÅ¡nieka, un starpnieks tika veidots ar " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START slÄ“dzi (flag)" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstraktas nosaukumu telpas nav atbalstÄ«tas" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Nevar norÄdÄ«t nonce datni, kad veido serveri" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Kļūda, rakstot nonce datni pie “%s†— %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Virkne “%s†nav derÄ«ga D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Nevar klausÄ«ties uz neatbalstÄ«ta transporta “%sâ€" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Komandas:\n" +" help RÄda Å¡o informÄciju\n" +" introspect IntrospektÄ“t attÄlinÄtu objektu\n" +" monitor PÄrraudzÄ«t attÄlinÄtu objektu\n" +" call Izsaukt metodi uz attÄlinÄta objekta\n" +" emit IzplatÄ«t signÄlu\n" +" wait GaidÄ«t lÄ«dz parÄdÄ«sies kopnes nosaukums\n" +"\n" +"Lieto “%s KOMANDA --helpâ€, lai saņemtu palÄ«dzÄ«bu par katru komandu.\n" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1236 +#: gio/gdbus-tool.c:1724 +#, c-format +msgid "Error: %s\n" +msgstr "Kļūda: %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1740 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Kļūda, parsÄ“jot introspekcijas XML: %s\n" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Kļūda — %s nav derÄ«gs nosaukums\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1060 +#: gio/gdbus-tool.c:1890 gio/gdbus-tool.c:2130 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Kļūda — %s nav derÄ«gs objekta ceļš\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "Savienoties ar sistÄ“mas kopni" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "Savienoties ar sesijas kopni" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "Savienoties ar doto D-Bus adresi" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "Savienojuma galapunktu opcijas:" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "Opcijas, kas norÄda savienojuma galapunktus" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nav norÄdÄ«ti savienojuma galapunkti" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "NorÄdÄ«ti vairÄki savienojuma galapunkti" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"BrÄ«dinÄjums — spriežot pÄ“c introspekcijas datiem, saskarne “%s†neeksistÄ“\n" + +#: gio/gdbus-tool.c:531 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"BrÄ«dinÄjums — spriežot pÄ“c introspekcijas datiem, metode “%s†neeksistÄ“ uz " +"saskarnes “%sâ€\n" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "NeobligÄts mÄ“rÄ·is signÄlam (unikÄls nosaukums)" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "Objekta ceļš, uz kura izplatÄ«t signÄlu" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "SignÄls un saskarnes nosaukums" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "IzplatÄ«t signÄlu." + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:997 gio/gdbus-tool.c:1827 +#: gio/gdbus-tool.c:2059 gio/gdbus-tool.c:2279 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Kļūda savienojot — %s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Kļūda — %s nav derÄ«gs unikÄls kopnes nosaukums.\n" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1870 +msgid "Error: Object path is not specified\n" +msgstr "Kļūda — nav norÄdÄ«ts objekta ceļš\n" + +#: gio/gdbus-tool.c:765 +msgid "Error: Signal name is not specified\n" +msgstr "Kļūda — nav norÄdÄ«ts signÄla nosaukums\n" + +#: gio/gdbus-tool.c:779 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Kļūda — signÄla nosaukums “%s†nav derÄ«gs\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Kļūda — %s nav derÄ«gs saskarnes nosaukums.\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Kļūda — %s nav derÄ«gs dalÄ«bnieka nosaukums.\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1172 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Kļūda, parsÄ“jot parametru %d — %s\n" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Kļūda, nopludinot savienojumu — %s\n" + +#: gio/gdbus-tool.c:893 +msgid "Destination name to invoke method on" +msgstr "MÄ“rÄ·a nosaukums, uz kura izsaukt metodi" + +#: gio/gdbus-tool.c:894 +msgid "Object path to invoke method on" +msgstr "Objekta ceļš, uz kura izsaukt metodi" + +#: gio/gdbus-tool.c:895 +msgid "Method and interface name" +msgstr "Metode un saskarnes nosaukums" + +#: gio/gdbus-tool.c:896 +msgid "Timeout in seconds" +msgstr "Noildze sekundÄ“s" + +#: gio/gdbus-tool.c:942 +msgid "Invoke a method on a remote object." +msgstr "Izsaukt metodi uz attÄlinÄta objekta." + +#: gio/gdbus-tool.c:1014 gio/gdbus-tool.c:1844 gio/gdbus-tool.c:2084 +msgid "Error: Destination is not specified\n" +msgstr "Kļūda — nav norÄdÄ«ts galamÄ“rÄ·is\n" + +#: gio/gdbus-tool.c:1025 gio/gdbus-tool.c:1861 gio/gdbus-tool.c:2095 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Kļūda — %s nav derÄ«gs kopnes nosaukums\n" + +#: gio/gdbus-tool.c:1075 +msgid "Error: Method name is not specified\n" +msgstr "Kļūda — nav norÄdÄ«ts metodes nosaukums\n" + +#: gio/gdbus-tool.c:1086 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Kļūda — metodes nosaukums “%s†nav derÄ«gs\n" + +#: gio/gdbus-tool.c:1164 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Kļūda, parsÄ“jot parametru %d ar tipu “%s†— %s\n" + +#: gio/gdbus-tool.c:1190 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Kļūda, pievienojot turi %d — %s\n" + +#: gio/gdbus-tool.c:1686 +msgid "Destination name to introspect" +msgstr "MÄ“rÄ·a nosaukums, kam veikt introspekciju" + +#: gio/gdbus-tool.c:1687 +msgid "Object path to introspect" +msgstr "Objekta ceļš, kam veikt introspekciju" + +#: gio/gdbus-tool.c:1688 +msgid "Print XML" +msgstr "DrukÄt XML" + +#: gio/gdbus-tool.c:1689 +msgid "Introspect children" +msgstr "Veikt introspekciju bÄ“rniem" + +#: gio/gdbus-tool.c:1690 +msgid "Only print properties" +msgstr "Tikai drukÄÅ¡anas Ä«pašības" + +#: gio/gdbus-tool.c:1779 +msgid "Introspect a remote object." +msgstr "Veikt introspekciju attÄlinÄtam objektam." + +#: gio/gdbus-tool.c:1985 +msgid "Destination name to monitor" +msgstr "MÄ“rÄ·a nosaukums uz pÄrraugu" + +#: gio/gdbus-tool.c:1986 +msgid "Object path to monitor" +msgstr "Objekta ceļš uz pÄrraugu" + +#: gio/gdbus-tool.c:2011 +msgid "Monitor a remote object." +msgstr "PÄrraudzÄ«t attÄlinÄtu objektu." + +#: gio/gdbus-tool.c:2069 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Kļūda: nevar pÄrraudzÄ«t non-message-bus savienojumu\n" + +#: gio/gdbus-tool.c:2193 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Serviss, ko aktivizÄ“t pirms gaidÄ«t otru (labi zinÄms nosaukums)" + +#: gio/gdbus-tool.c:2196 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Cik ilgi gaidÄ«t, pirms iziet ar kļūdu (sekundÄ“s); 0 nozÄ«mÄ“ bez noildzes " +"(noklusÄ“juma)" + +#: gio/gdbus-tool.c:2244 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPCIJA…] KOPNES-NOSAUKUMS" + +#: gio/gdbus-tool.c:2245 +msgid "Wait for a bus name to appear." +msgstr "GaidÄ«t lÄ«dz parÄdÄs kopnes nosaukums." + +#: gio/gdbus-tool.c:2321 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Kļūda — jÄnorÄda serviss, ko aktivizÄ“t.\n" + +#: gio/gdbus-tool.c:2326 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Kļūda — jÄnorÄda serviss, uz kuru gaidÄ«t.\n" + +#: gio/gdbus-tool.c:2331 +msgid "Error: Too many arguments.\n" +msgstr "Kļūda — pÄrÄk daudz argumentu.\n" + +#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Kļūda — %s nav derÄ«gs labi zinÄms kopnes nosaukums.\n" + +#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4932 +msgid "Unnamed" +msgstr "Nenosaukts" + +#: gio/gdesktopappinfo.c:2516 +msgid "Desktop file didn’t specify Exec field" +msgstr "Darbvirsmas datne nenorÄdÄ«ja Exec lauku" + +#: gio/gdesktopappinfo.c:2801 +msgid "Unable to find terminal required for application" +msgstr "NevarÄ“ja atrast terminÄli, kas ir nepiecieÅ¡ams lietotnei" + +#: gio/gdesktopappinfo.c:3452 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Nevar izveidot lietotÄja lietotnes konfigurÄcijas mapi %s — %s" + +#: gio/gdesktopappinfo.c:3456 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Nevar izveidot lietotÄja MIME konfigurÄcijas mapi %s — %s" + +#: gio/gdesktopappinfo.c:3698 gio/gdesktopappinfo.c:3722 +msgid "Application information lacks an identifier" +msgstr "Lietotnes informÄcijai trÅ«kst identifikatora" + +#: gio/gdesktopappinfo.c:3958 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Nevar izveidot lietotÄja darbvirsmas datni %s" + +#: gio/gdesktopappinfo.c:4094 +#, c-format +msgid "Custom definition for %s" +msgstr "PielÄgotas %s definÄ«cijas" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "dzinis neatbalsta izgrūšanu" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "dzinis neatbalsta izgrūšanu vai eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "dzinis neatbalsta medija aptauju" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "dzinis neatbalsta startēšanu" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "dzinis neatbalsta apturēšanu" + +#: gio/gdtlsconnection.c:1153 gio/gtlsconnection.c:920 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS aizmugure nav implementÄ“jusi TLS saistīšanas saņemÅ¡anu" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS atbalsts nav pieejams" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS atbalsts nav pieejams" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Nevar apstrÄdÄt GEmblem versijas %d kodÄ“jumu" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "VairÄki slikti formÄ“ti marÄ·ieri (%d) GEmblem kodÄ“jumÄ" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Nevar apstrÄdÄt GEmblemedIcon versijas %d kodÄ“jumu" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "VairÄki slikti formÄ“ti marÄ·ieri (%d) GEmblemedIcon kodÄ“jumÄ" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GaidÄ«ja GEmblem priekÅ¡ GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1561 +msgid "Containing mount does not exist" +msgstr "SaturoÅ¡ais montÄ“jums neeksistÄ“" + +#: gio/gfile.c:2608 gio/glocalfile.c:2477 +msgid "Can’t copy over directory" +msgstr "Nevar kopÄ“t virsÅ« mapei" + +#: gio/gfile.c:2668 +msgid "Can’t copy directory over directory" +msgstr "Nevar uzkopÄ“t mapi virsÅ« mapei" + +#: gio/gfile.c:2676 +msgid "Target file exists" +msgstr "MÄ“rÄ·a datne eksistÄ“" + +#: gio/gfile.c:2695 +msgid "Can’t recursively copy directory" +msgstr "Nevar rekursÄ«vi kopÄ“t mapi" + +#: gio/gfile.c:2996 +msgid "Splice not supported" +msgstr "Splice nav atbalstÄ«ts" + +#: gio/gfile.c:3000 +#, c-format +msgid "Error splicing file: %s" +msgstr "Kļūda, datnei veicot splice — %s" + +#: gio/gfile.c:3152 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopēšana (reflink/clone) starp montÄ“tiem sÄ“jumiem nav atbalstÄ«ta" + +#: gio/gfile.c:3156 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopēšana (reflink/clone) nav atbalstÄ«ta vai nav derÄ«ga" + +#: gio/gfile.c:3161 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopēšana (reflink/clone) nav atbalstÄ«ta vai nenostrÄdÄja" + +#: gio/gfile.c:3226 +msgid "Can’t copy special file" +msgstr "Nevar kopÄ“t Ä«paÅ¡u datni" + +#: gio/gfile.c:4035 +msgid "Invalid symlink value given" +msgstr "Ir dota nederÄ«ga simboliskÄs saites vÄ“rtÄ«ba" + +#: gio/gfile.c:4045 glib/gfileutils.c:2354 +msgid "Symbolic links not supported" +msgstr "SimboliskÄs saites nav atbalstÄ«tas" + +#: gio/gfile.c:4213 +msgid "Trash not supported" +msgstr "Miskaste nav atbalstÄ«ta" + +#: gio/gfile.c:4325 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Datņu nosaukums nevar saturÄ“t “%câ€" + +#: gio/gfile.c:6806 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "sÄ“jums neatbalsta montēšanu" + +#: gio/gfile.c:6920 gio/gfile.c:6968 +msgid "No application is registered as handling this file" +msgstr "Neviena lietotne nav reÄ£istrÄ“ta, kÄ Å¡o datni apstrÄdÄjoÅ¡a" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "SkaitÄ«tÄjs ir aizvÄ“rts" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Datņu skaitÄ«tÄjam ir neizpildÄ«ta darbÄ«ba" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Datņu skaitÄ«tÄjs jau ir aizvÄ“rts" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Nevar apstrÄdÄt GFileIcon versijas %d kodÄ“jumu" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Slikti formÄ“ti GFileIcon ievades dati" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "PlÅ«sma neatbalsta query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Uz plÅ«smas meklēšana netiek atbalstÄ«ta" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Uz ievades plÅ«smas aprauÅ¡ana nav atbalstÄ«ta" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Uz plÅ«smas aprauÅ¡ana nav atbalstÄ«ta" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:596 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Nepareizs resursdatora nosaukums" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Slikta HTTP starpnieka atbilde" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Nav atļauts savienojums ar HTTP starpnieku" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "NeizdevÄs autentificēšanÄs ar HTTP starpnieku" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "NepiecieÅ¡ama HTTP starpniekservera autentifikÄcija" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "NeizdevÄs savienojums ar HTTP starpnieku: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP starpnieka atbilde ir pÄrÄk liela" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP starpniekserveris negaidÄ«ti aizvÄ“ra savienojumu." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nepareizs marÄ·ieru skaits (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Nav tips klases nosaukumam %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Tips %s nav realizÄ“jis GIcon saskarni" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Tips %s nav klasÄ“" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Slikti formÄ“ts versijas numurs — %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Tips %s nerealizÄ“ from_tokens() uz GIcon saskarnes" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Nevar apstrÄdÄt piegÄdÄto ikonu kodÄ“jumu versiju" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nav norÄdÄ«tas adreses" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Garums “%u†ir pÄrÄk liels adresÄ“m" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adresei ir biti, kas ir iestatÄ«ti pÄ“c prefiksa garuma" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "NeizdevÄs parsÄ“t “%s†kÄ IP adreses masku" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "Nepietiek vietas ligzdas adresei" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "NeatbalstÄ«ta ligzdas adrese" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Ievades plÅ«sma neatbalsta lasīšanu" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "PlÅ«smai ir neizpildÄ«ta darbÄ«ba" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "KopÄ“t ar datni" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "PaturÄ“t ar datni, kad pÄrvietots" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†nepieņem argumentus" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "LietoÅ¡ana:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "ParÄdÄ«t informÄciju par versiju un iziet." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Komandas:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Savienot datnes uz standarta izvades" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "KopÄ“t vienu vai vairÄkas datnes" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "ParÄdÄ«t informÄciju par atraÅ¡anÄs vietÄm" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Palaist lietotni no darbvirsmas datnes" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "UzskaitÄ«t atraÅ¡anÄs vietu saturu" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "IegÅ«t vai iestatÄ«t apdarinÄtÄju priekÅ¡ mimetype" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Izveidot mapes" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "PÄrraudzÄ«t datnes un mapes pÄ“c izmaiņÄm" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "MontÄ“t vai atmontÄ“t atraÅ¡anÄs vietas" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "PÄrvietot vienu vai vairÄkas datnes" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Atver datnes ar noklusÄ“juma lietotni" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "PÄrsaukt datni" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "DzÄ“st vienu vai vairÄkas datnes" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "LasÄ«t no standarta ievades un saglabÄt" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "IestatÄ«t datnes atribÅ«tu" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "PÄrvietot datnes vai mapes uz miskasti" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Uzskaita atraÅ¡anÄs vietu saturu kokÄ" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Lietojiet %s, lai iegÅ«tu detalizÄ“tu palÄ«dzÄ«bu.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Kļūda, rakstot uz stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "ATRAÅ ANÄ€S_VIETA" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Savienot datnes un drukÄt uz standarta izvades" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat strÄdÄ tÄpat kÄ tradicionÄlÄ cat utilÄ«tprogramma, bet lieto\n" +"GIO atraÅ¡anÄs vietas, nevis lokÄlÄs datnes: piemÄ“ram, jÅ«s varat\n" +"lietot kaut ko lÄ«dzÄ«gu smb://serveris/resurss/datne.txt kÄ\n" +"atraÅ¡anÄs vietu." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nav dotas atraÅ¡anÄs vietas" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nav mÄ“rÄ·a mapes" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "RÄdÄ«t progresu" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Uzvedne pirms pÄrrakstīšanas" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "SaglabÄt visus atribÅ«tus" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Izveidot rezerves kopijas pastÄvoÅ¡ajÄm mÄ“rÄ·a datnÄ“m" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nekad nesekot simboliskajÄm saitÄ“m" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Lietot noklusÄ“juma atļaujas mÄ“rÄ·im" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "PÄrsÅ«tÄ«ti %s no %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "AVOTS" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "GALAMÄ’RĶIS" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "KopÄ“t vienu vai vairÄkas datnes no AVOTA uz GALAMÄ’RĶI." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy ir lÄ«dzÄ«ga tradicionÄlajai cp utilÄ«tprogrammai, bet lieto\n" +"GIO atraÅ¡anÄs vietas, nevis lokÄlÄs datnes: piemÄ“ram, jÅ«s varat\n" +"lietot kaut ko lÄ«dzÄ«gu smb://serveris/resurss/datne.txt kÄ\n" +"atraÅ¡anÄs vietu." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "MÄ“rÄ·is %s nav mape" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: pÄrrakstÄ«t “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "UzskaitÄ«t rakstÄmos atribÅ«tus" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "IegÅ«t datņu sistÄ“mas informÄciju" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "AtribÅ«ti, kurus iegÅ«t" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBŪTI" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Nesekot simboliskajÄm saitÄ“m" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atribÅ«ti:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "attÄ“lotais nosaukums: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "rediģēt nosaukumu: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nosaukums: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tips: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "izmÄ“rs: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "paslÄ“pts\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "lokÄlais ceļš: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix montÄ“jums: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "IestatÄmie atribÅ«ti:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "RakstÄmÄs atribÅ«tu nosaukumu telpas:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "ParÄdÄ«t informÄciju par atraÅ¡anÄs vietÄm." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info ir lÄ«dzÄ«ga tradicionÄlajai ls utilÄ«tprogrammai, bet lieto GIO\n" +"atraÅ¡anÄs vietas, nevis lokÄlÄs datnes: piemÄ“ram, jÅ«s varat lietot\n" +"kaut ko lÄ«dzÄ«gu smb://serveris/resurss/datne.txt kÄ atraÅ¡anÄs vietu.\n" +"Datņu atribÅ«ti var tikt norÄdÄ«ti ar to GIO nosaukumu, piemÄ“ram,\n" +"standard::icon, vai tikai ar nosaukumu telpu, piemÄ“ram, unix, vai ar “*â€, " +"kurÅ¡\n" +"atbilst visiem atribÅ«tiem" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DARBVIRSMAS-DATNE [DATNES-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Palaist lietotni no darbvirsmas datnes. Tai var padodot datņu argumentus." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nav dota darbvirsmas datne" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "PalaiÅ¡anas komanda Å¡obrÄ«d nav atbalstÄ«ta Å¡ajÄ platformÄ" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Nevar ielÄdÄ“t “%s†— %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Nevar ielÄdÄ“t “%s†lietotnes informÄciju" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Nevar palaist lietotni “%s†— %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "RÄdÄ«t slÄ“ptÄs datnes" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Lietot garo uzskaitÄ«juma formÄtu" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "AttÄ“lot displeju nosaukumus" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "DrukÄt pilnos URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "UzskaitÄ«t atraÅ¡anÄs vietu saturu." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list ir lÄ«dzÄ«ga tradicionÄlajai ls utilÄ«tprogrammai, bet lieto GIO\n" +"atraÅ¡anÄs vietas, nevis lokÄlÄs datnes: piemÄ“ram, jÅ«s varat lietot\n" +"kaut ko lÄ«dzÄ«gu smb://serveris/resurss/datne.txt kÄ atraÅ¡anÄs vietu.\n" +"Datņu atribÅ«ti var tikt norÄdÄ«ti ar to GIO nosaukumu, piemÄ“ram,\n" +"standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIME_TIPS" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "APDARINÄ€TÄ€JS" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "IegÅ«t vai iestatÄ«t apdarinÄtÄju priekÅ¡ mimetype." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Ja nav dots apdarinÄtÄjs, uzskaita reÄ£istrÄ“tÄs un ieteiktÄs lietotnes\n" +"priekÅ¡ mime tipa. Ja apdarinÄtÄjs ir dots, tas tiek iestatÄ«ts kÄ\n" +"noklusÄ“tais apdarinÄtÄjs mime tipam." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Vajag norÄdÄ«t vienu mime tipu un varbÅ«t apdarinÄtÄju" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Nav noklusÄ“tÄs lietotnes priekÅ¡ “%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "NoklusÄ“tÄ lietotne priekÅ¡ “%s†— %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "ReÄ£istrÄ“tÄs lietotnes:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nav reÄ£istrÄ“tu lietotņu\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "IeteiktÄs lietotnes:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Nav ieteikto lietotņu\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "NeizdevÄs ielÄdÄ“t informÄciju priekÅ¡ apdarinÄtÄja “%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "NeizdevÄs iestatÄ«t “%s†kÄ noklusÄ“juma apdarinÄtÄju priekÅ¡ “%s†— %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Izveidot vecÄkmapes" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Izveidot mapes." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir ir lÄ«dzÄ«ga tradicionÄlajai mkdir utilÄ«tprogrammai, bet lieto\n" +"GIO atraÅ¡anÄs vietas, nevis lokÄlÄs datnes: piemÄ“ram, jÅ«s varat\n" +"lietot kaut ko lÄ«dzÄ«gu smb://serveris/resurss/manamape kÄ\n" +"atraÅ¡anÄs vietu." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "PÄrraudzÄ«t mapi (noklusÄ“juma: atkarÄ«gs no tipa)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "PÄrraudzÄ«t datni (noklusÄ“juma: atkarÄ«gs no tipa)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"PÄrraudzÄ«t datni tieÅ¡i (paziņo par izmaiņÄm, veiktÄm caur stingrajÄm saitÄ“m)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "PÄrrauga datni tieÅ¡i, bet neziņo par izmaiņÄm" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Ziņot par pÄrvietoÅ¡anÄm un pÄrsaukÅ¡anÄm kÄ par vienkÄrÅ¡iem dzÄ“sts/izveidots " +"notikumiem" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "NovÄ“rot montēšanas notikumus" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "PÄrraudzÄ«t datnes vai mapes pÄ“c izmaiņÄm." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "MontÄ“t kÄ montÄ“jamu" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "MontÄ“t sÄ“jumu ar ierÄ«ces datni vai citu identifikatoru" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "AtmontÄ“t" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "IzgrÅ«st" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "ApturÄ“t dzini ar ierÄ«ces datni" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "IERĪCE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "AtmontÄ“t visus montÄ“jumus ar doto shÄ“mu" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SHÄ’MA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "IgnorÄ“t neizpildÄ«tÄs datņu darbÄ«bas, kad atmontÄ“jas vai izstumjas" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Lietot anonÄ«mo lietotÄju, kad autentificÄ“jas" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Saraksts" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "PÄrraudzÄ«t notikumus" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "RÄdÄ«t papildu informÄciju" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Skaitliskais PIM, kad atslÄ“dz VeraCrypt sÄ“jumu" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "MontÄ“t TCRYPT slÄ“pto sÄ“jumu" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "MontÄ“t TCRYPT sistÄ“mas sÄ“jumu" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "AnonÄ«ma pieeja liegta" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Nav dziņa ierÄ«ces datnei" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Nav sÄ“juma dotajai ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "MontÄ“t vai atmontÄ“t atraÅ¡anÄs vietas." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Nelietot kopiju un dzÄ“st apkÄpÅ¡anos" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "PÄrvietot vienu vai vairÄkas datnes no AVOTA uz GALAMÄ’RĶI." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move ir lÄ«dzÄ«ga tradicionÄlajai mv utilÄ«tprogrammai, bet lieto\n" +"GIO atraÅ¡anÄs vietas, nevis lokÄlÄs datnes: piemÄ“ram, jÅ«s varat\n" +"lietot kaut ko lÄ«dzÄ«gu smb://serveris/resurss/datne.txt kÄ\n" +"atraÅ¡anÄs vietu" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "MÄ“rÄ·is %s nav mape" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"AtvÄ“rt datnes ar noklusÄ“to lietotni, kura ir\n" +"reÄ£istrÄ“ta, lai apstrÄdÄtu šī tipa datnes." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "IgnorÄ“t neeksistÄ“joÅ¡as datnes, nekad neuzvadÄ«t" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "DzÄ“st dotÄs datnes." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOSAUKUMS" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "PÄrsaukt datni." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "TrÅ«kst arguments" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "PÄrÄk daudz argumentu" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "PÄrsaukÅ¡ana veiksmÄ«ga. Jaunais uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Izveidot tikai, ja nav pastÄvoÅ¡s" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Pievienot pie datnes beigÄm" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Kad izveido, ierobežot pieeju uz paÅ¡reizÄ“jo lietotÄju" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Kad aizvieto, darÄ«t to tÄ, it kÄ galamÄ“rÄ·is nepastÄvÄ“tu" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "DrukÄt jaunu etag beigÄs" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Datnes etag tiek pÄrrakstÄ«ts" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Kļūda, lasot no standarta ievades" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag nav pieejams\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "LasÄ«t no standarta ievades un saglabÄt uz GALAMÄ’RĶA." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nav dots galamÄ“rÄ·is" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "AtribÅ«ta tips" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPS" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBŪTS" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VÄ’RTĪBA" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "IestatÄ«t ATRAÅ ANÄ€S_VIETAS datnes atribÅ«tu." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "AtraÅ¡anÄs vieta nav norÄdÄ«ta" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "AtribÅ«ts nav norÄdÄ«ts" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "VÄ“rtÄ«ba nav norÄdÄ«ta" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "NederÄ«gs atribÅ«ta tips “%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "IztukÅ¡ot miskasti" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "UzrÄdÄ«t datnes miskastÄ“ ar to sÄkotnÄ“jo atraÅ¡anÄs vietÄm" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Atjaunot datni no miskastes uz tÄs sÄkotnÄ“jo vietu (iespÄ“jams, no jauna " +"izveidojot direktoriju)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Nevar atrast sÄkotnÄ“jo ceļu" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Nevar no jauna izveidot sÄkotnÄ“jo vietu: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Nevar pÄrvietot datni uz tÄs sÄkotnÄ“jo vietu: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "PÄrvietot/atjaunot datnes vai mapes uz miskasti." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"PiezÄ«me: --restore slÄ“dzim, ja sÄkotnÄ“jÄ vieta izmestajai datnei \n" +"jau eksistÄ“, tÄ netiks pÄrrakstÄ«ja, ja vien nav iestatÄ«ts --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "AtraÅ¡anÄs vieta nesÄkas ar trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Sekot simboliskajÄm saitÄ“m, montÄ“jumiem un saÄ«snÄ“m" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "UzskaitÄ«t mapju saturu kokam lÄ«dzÄ«gÄ formÄtÄ." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elements <%s> nav atļauts iekÅ¡ <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elements <%s> nav atļauts augšējÄ lÄ«menÄ«" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Datne %s resursÄ parÄdÄs vairÄkas reizes" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "NeizdevÄs atrast “%s†nevienÄ avotu mapÄ“" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "NeizdevÄs atrast “%s†paÅ¡reizÄ“jÄ mapÄ“" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "NezinÄma apstrÄdes opcija “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Ir pieprasÄ«ta %s pirmsapstrÄde, bet %s nav iestatÄ«ts un %s neatrodas PATH " +"mainÄ«gajÄ" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Kļūda, nolasot datni %s — %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Kļūda, saspiežot datni %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "teksts nevar atrasties iekÅ¡ <%s>" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "RÄdÄ«t programmas versiju un iziet" + +#: gio/glib-compile-resources.c:738 +msgid "Name of the output file" +msgstr "Izvades datnes nosaukums" + +#: gio/glib-compile-resources.c:739 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Direktorijas, no kurÄm nolasÄ«t datnes, kas ir norÄdÄ«tas DATNE (pÄ“c " +"noklusÄ“juma paÅ¡reizÄ“jÄ direktorija)" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "MAPE" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Veidot izvadi, kas ir mÄ“rÄ·a datnes nosaukuma paplaÅ¡inÄjuma formÄtÄ" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "Veidot avota galveni" + +#: gio/glib-compile-resources.c:742 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Veidot pirmkodu, ko izmantot, lai saistÄ«tu resursu datni jÅ«su kodÄ" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "Veidot atkarÄ«bu sarakstu" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "Nosaukums atkarÄ«bu datnei, kuru Ä£enerÄ“t" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "Iekļaut apÅ¡aubÄmus (phony) mÄ“rÄ·us Ä£enerÄ“tajÄ atkarÄ«bu datnÄ“" + +#: gio/glib-compile-resources.c:746 +msgid "Don’t automatically create and register resource" +msgstr "Resursu neveidot un nereÄ£istrÄ“t automÄtiski" + +#: gio/glib-compile-resources.c:747 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "NeeksportÄ“t funkcijas; deklarÄ“t tÄs G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Neiegult resursa datus C datnÄ“; tÄ vietÄ pieņemt, ka tie ir piesaistÄ«ti ÄrÄ“ji" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "C identifikatora nosaukums veidotajam pirmkodam" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"KompilÄ“t resursu specifikÄciju resursa datnÄ“.\n" +"Resursu specifikÄcijas datnÄ“m ir jÄbÅ«t ar paplaÅ¡inÄjumu .gresource.xml,\n" +"un resursu datnÄ“m jÄbÅ«t ar paplaÅ¡inÄjumu .gresource." + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "Jums jÄnorÄda tieÅ¡i viens datnes nosaukums\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "pseidonÄ«mam ir jÄbÅ«t vismaz 2 rakstzÄ«mju garam" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "NederÄ«ga skaitļa vÄ“rtÄ«ba" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " jau norÄdÄ«ts" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' jau ir norÄdÄ«ta" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "slÄ“džu vÄ“rtÄ«bÄm vismaz vienam bitam ir jÄbÅ«t iestatÄ«tam" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> jÄsatur vismaz viens " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> neatrodas norÄdÄ«tÄjÄ intervÄlÄ" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nav derÄ«gs skaitlis no norÄdÄ«tÄ uzskaitÄ«juma tipa" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> satur virkni, kas nav norÄdÄ«to slÄ“džu tipos" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> satur virkni, kas nav starp " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " jau ir norÄdÄ«ts Å¡ai atslÄ“gai" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nav atļauts atslÄ“gai ar tipu “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " norÄdÄ«tais minimums ir lielÄks par maksimumu" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "neatbalstÄ«ta l10n kategorija: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n ir pieprasÄ«ts, bet nav dots gettext domÄ“ns" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "tulkoÅ¡anas konteksts ir dots vÄ“rtÄ«bai ar neieslÄ“gtu l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "NeizdevÄs parsÄ“t vÄ“rtÄ«bu ar tipu “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" nevar norÄdÄ«t atslÄ“gÄm, kuras ir marÄ·Ä“tas kÄ uzskaitÄ«juma tips" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " jau ir norÄdÄ«ts Å¡ai atslÄ“gai" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nav atļautas atslÄ“gÄm ar tipu “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " jau dots" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " jÄsatur vismaz viens " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " jau ir norÄdÄ«ts Å¡ai atslÄ“gai" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" var tikai norÄdÄ«t atslÄ“gÄm ar uzskaitÄ«juma vai slÄ“džu tipiem vai " +"pÄ“c " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr " dots, kad “%s†jau ir daļa no uzskaitÄ«juma tipa" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " ja jau tika dots" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " jau norÄdÄ«ts" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "aliasa mÄ“rÄ·is “%s†nav uzskaitÄ«juma tips" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "aliasa mÄ“rÄ·is “%s†nav starp " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " jÄsatur vismaz viens " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Nav atļauti tukÅ¡i nosaukumi" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "NederÄ«gs nosaukums “%s†— nosaukumiem jÄsÄkas ar mazo burtu" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"NederÄ«gs nosaukums “%s†— nederÄ«ga rakstzÄ«me “%câ€; ir atļauti tikai burti, " +"skaitļi un defise (“-â€)." + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "NederÄ«gs nosaukums “%s†— divas secÄ«gas defises (“--â€) nav atļautas." + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "NederÄ«gs nosaukums “%s†— pÄ“dÄ“jÄ rakstzÄ«me nevar bÅ«t defise (“-â€)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "NederÄ«gs nosaukums “%s†— maksimÄlais garums ir 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " jau norÄdÄ«ts" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Nevar pievienot atslÄ“gas “list-of†shÄ“mai" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " jau norÄdÄ«ts" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" Ä“nas iekÅ¡ ; izmantojiet " +", lai mainÄ«tu vÄ“rtÄ«bu" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"JÄnorÄda tieÅ¡i viens tips “typeâ€, “enum†vai “flags†kÄ atribÅ«ts atslÄ“gai " +"" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (vÄ“l) nav definÄ“ts." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "NederÄ«ga GVariant tipa virkne “%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " dots, bet shÄ“ma neko nepaplaÅ¡ina" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Nav ko pÄrrakstÄ«t" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " jau norÄdÄ«ts" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " jau eksistÄ“" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " paplaÅ¡ina vÄ“l neesoÅ¡u shÄ“mu “%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " ir saraksts ar vÄ“l neesoÅ¡Äm shÄ“mÄm “%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Nevar bÅ«t shÄ“mu saraksts ar ceļu" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Nevar paplaÅ¡inÄt shÄ“mu ar ceļu" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ir saraksts, paplaÅ¡ina , kas nav saraksts" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" paplaÅ¡ina bet " +"“%s†nepaplaÅ¡ina “%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Ceļam, ja tÄds ir dots, jÄbeidzas ar slÄ«psvÄ«tru" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Ceļam jÄbeidzas ar “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"BrÄ«dinÄjums: shÄ“mai “%s†ir ceļš “%sâ€. Ceļi, kas sÄkas ar “/apps/â€, “/" +"desktop/†vai “/system/†ir novecojuÅ¡i." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> jau norÄdÄ«ts" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Ir atļauts tikai <%s> elements iekÅ¡ <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Elements <%s> nav atļauts augšējÄ lÄ«menÄ«" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Elements ir vajadzÄ«gs atslÄ“gai " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Teksts nevar atrasties iekÅ¡ <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "BrÄ«dinÄjums: nedefinÄ“ta atsauce uz " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict tika norÄdÄ«ts; iziet." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Tikai ignorÄ“ta visa datne." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "IgnorÄ“ Å¡o datni." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Nav tÄdas atslÄ“gas “%s†shÄ“mÄ â€œ%s†kÄ norÄdÄ«ts pÄrrakstīšanas datnÄ“ “%sâ€; " +"Å¡ai atslÄ“gai ignorÄ“t pÄrrakstīšanas." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Nav tÄdas atslÄ“gas “%s†shÄ“mÄ â€œ%s†kÄ norÄdÄ«ts pÄrrakstīšanas datnÄ“ “%s†un " +"tika norÄdÄ«ts --strict; iziet." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Nevar sniegt katrai darbvirsmai pÄrrakstīšanas lokalizÄ“tÄm atslÄ“gÄm “%s†" +"shÄ“mÄ â€œ%s†(ignorÄ“ datni “%sâ€); ignorÄ“ pÄrrakstīšanu Å¡ai atslÄ“gai." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Nevar sniegt katrai darbvirsmai pÄrrakstīšanas lokalizÄ“tÄm atslÄ“gÄm “%s†" +"shÄ“mÄ â€œ%s†(ignorÄ“ datni “%sâ€)un tika norÄdÄ«ts --strict; iziet." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Kļūda, parsÄ“jot atslÄ“gu “%s†shÄ“mÄ â€œ%s†kÄ norÄdÄ«ts pÄrrakstīšanas datnÄ“ " +"“%s†— %s. IgnorÄ“ pÄrrakstīšanu Å¡ai atslÄ“gai." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Kļūda, parsÄ“jot atslÄ“gu “%s†shÄ“mÄ â€œ%s†kÄ norÄdÄ«ts pÄrrakstīšanas datnÄ“ " +"“%s†— %s. Bija norÄdÄ«ts --strict; iziet." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"PÄrrakstīšana atslÄ“gai “%s†shÄ“mÄ â€œ%s†pÄrrakstīšanas datnÄ“ “%s†ir Ärpus " +"dotÄs shÄ“mas apgabala; ignorÄ“ pÄrrakstīšanas Å¡ai atslÄ“gai." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"PÄrrakstīšana atslÄ“gai “%s†shÄ“mÄ â€œ%s†pÄrrakstīšanas datnÄ“ “%s†ir Ärpus " +"dotÄs shÄ“mas apgabala un bija norÄdÄ«ts --strict; iziet." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"PÄrrakstīšana atslÄ“gai “%s†shÄ“mÄ â€œ%s†pÄrrakstīšanas datnÄ“ “%s†nav derÄ«go " +"izvēļu sarakstÄ; ignorÄ“ pÄrrakstīšanas Å¡ai atslÄ“gai." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"PÄrrakstīšana atslÄ“gai “%s†shÄ“mÄ â€œ%s†pÄrrakstīšanas datnÄ“ “%s†nav derÄ«go " +"izvēļu sarakstÄ un bija norÄdÄ«ts --strict; iziet." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Kur uzglabÄt gschemas.compiled datni" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Atcelt pie jebkuras kļūdas shÄ“mÄs" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "NerakstÄ«t gschema.compiled datni" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Neuzspiest atslÄ“gu nosaukumu ierobežojumus" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"KompilÄ“t visas GSettings shÄ“mas datnes uz shÄ“mas keÅ¡u.\n" +"ShÄ“mu datņu nosaukumiem ir jÄbÅ«t ar paplaÅ¡inÄjumu .gschema.xml,\n" +"un keÅ¡a datnÄ“m ir jÄsaucas gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Jums jÄnorÄda tieÅ¡i viens mapes nosaukums" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nav atrastas shÄ“mu datnes: neko nedara." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "izņēma esoÅ¡o izvades datni: izņēma esoÅ¡o izvades datni." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "NederÄ«gs datnes nosaukums %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Kļūda, iegÅ«stot datņu sistÄ“mas informÄciju priekÅ¡ %s — %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "SaturoÅ¡ais montÄ“jums priekÅ¡ datnes %s nav atrasts" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Nevar pÄrsaukt saknes mapi" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Kļūda, pÄrsaucot datni %s — %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Nevar pÄrsaukt datni; datnes nosaukums jau eksistÄ“" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2371 gio/glocalfile.c:2399 +#: gio/glocalfile.c:2538 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "NederÄ«gs datnes nosaukums" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Kļūda, atverot datni %s — %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Kļūda, dzēšot datni %s — %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Kļūda, izmetot miskastÄ“ datni %s — %s" + +#: gio/glocalfile.c:2031 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Nevar izveidot miskastes direktoriju %s — %s" + +#: gio/glocalfile.c:2052 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Nevar atrast augšējÄ lÄ«meņa mapi, lai izmestu miskastÄ“ %s" + +#: gio/glocalfile.c:2060 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "IzmeÅ¡ana uz sistÄ“mas iekšējiem montÄ“jumiem nav atbalstÄ«ta" + +#: gio/glocalfile.c:2146 gio/glocalfile.c:2174 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Nevar atrast vai izveidot miskastes direktoriju %s, lai izmestu %s" + +#: gio/glocalfile.c:2220 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Nevar izveidot miskastÄ“ izmeÅ¡anas informÄcijas datni priekÅ¡ %s — %s" + +#: gio/glocalfile.c:2282 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Nevar izmest miskastÄ“ datni %s pÄri datņu sistÄ“mas robežÄm" + +#: gio/glocalfile.c:2286 gio/glocalfile.c:2342 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Nevar izmest miskastÄ“ datni %s — %s" + +#: gio/glocalfile.c:2348 +#, c-format +msgid "Unable to trash file %s" +msgstr "Nevar izmest miskastÄ“ datni %s" + +#: gio/glocalfile.c:2374 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Kļūda, veidojot mapi %s — %s" + +#: gio/glocalfile.c:2403 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Datņu sistÄ“ma neatbalsta simboliskÄs saites" + +#: gio/glocalfile.c:2406 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Kļūda, veidojot simbolisko saiti %s — %s" + +#: gio/glocalfile.c:2449 gio/glocalfile.c:2484 gio/glocalfile.c:2541 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Kļūda, pÄrvietojot datni %s — %s" + +#: gio/glocalfile.c:2472 +msgid "Can’t move directory over directory" +msgstr "Nevar pÄrvietot mapi virsÅ« mapei" + +#: gio/glocalfile.c:2498 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "NeizdevÄs izveidot rezerves kopijas datni" + +#: gio/glocalfile.c:2517 +#, c-format +msgid "Error removing target file: %s" +msgstr "Kļūda, dzēšot mÄ“rÄ·a datni — %s" + +#: gio/glocalfile.c:2531 +msgid "Move between mounts not supported" +msgstr "PÄrvietoÅ¡ana starp montÄ“tiem sÄ“jumiem nav atbalstÄ«ta" + +#: gio/glocalfile.c:2705 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "NevarÄ“ja noteikt %s diska izmantojumu — %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "AtribÅ«ta vÄ“rtÄ«bai ir jÄbÅ«t ne NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "NederÄ«gs atribÅ«ta tips (tika gaidÄ«ta virkne)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "NederÄ«gs paplaÅ¡inÄtais atribÅ«ta nosaukums" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Kļūda, iestatot paplaÅ¡inÄto atribÅ«tu “%s†— %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (nederÄ«gs kodÄ“jums)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Kļūda, saņemot informÄciju par datni “%s†— %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Kļūda, saņemot informÄciju datnes deskriptoram — %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "NederÄ«gs atribÅ«ta tips (tika gaidÄ«ts uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "NederÄ«gs atribÅ«ta tips (tika gaidÄ«ts uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "NederÄ«gs atribÅ«ta tips (tika gaidÄ«ta baitu virkne)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Nevar iestatÄ«t atļaujas simboliskajÄm saitÄ“m" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Kļūda, iestatot tiesÄ«bas — %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Kļūda, iestatot Ä«paÅ¡nieku — %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "simboliskajai saitei ir jÄbÅ«t ne NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Kļūda, iestatot simbolisko saiti — %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Kļūda, iestatot simbolisko saiti — datne nav simboliskÄ saite" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Papildu nanosekundes %d UNIX laika spiedogiem %lld ir negatÄ«vas" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Papildu nanosekundes %d UNIX laika spiedogiem %lld sasniedza 1 sekundi" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX laika spiedogs %lld neiekļÄvÄs 64 bitos" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "UNIX laika spiedogs %lld ir Ärpus apgabala, ko atbalsta Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Datnes nosaukumu “%s†nevar pÄrveidot uz UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Datni “%s†nevar atvÄ“rt, Windows kļūda %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Kļūda, iestatot izmaiņu vai piekļuves laiku datnei “%s†— %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Kļūda, iestatot izmaiņu vai piekļuves laiku — %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux kontekstam ir jÄbÅ«t ne NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nav ieslÄ“gts uz šīs sistÄ“mas" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Kļūda, iestatot SELinux kontekstu — %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s atribÅ«ta iestatīšana nav atbalstÄ«ta" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Kļūda, lasot no datnes — %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Kļūda, aizverot datni — %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Kļūda, meklÄ“jot datnÄ“ — %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Nevar atrast noklusÄ“to lokÄlo datņu novÄ“roÅ¡anas tipu" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Kļūda, rakstot datnÄ“ — %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Kļūda, dzēšot vecu rezerves kopijas saiti — %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Kļūda, veidojot rezerves kopiju — %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Kļūda, pÄrsaucot pagaidu datni — %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "Kļūda, apraujot datni — %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:226 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Kļūda, atverot datni “%s†— %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "MÄ“rÄ·a datne ir mape" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "MÄ“rÄ·a datne nav parasta datne" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Datne tika mainÄ«ta no Ärpuses" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Kļūda, dzēšot veco datni — %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "PiegÄdÄts nederÄ«gs GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "NederÄ«gs meklēšanas pieprasÄ«jums" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Nevar apraut GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Atmiņas izvades plÅ«smai nav mainÄms izmÄ“rs" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "NeizdevÄs mainÄ«t atmiņas izvades plÅ«smas izmÄ“ru" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Atmiņas apjoms, kas nepiecieÅ¡ams, lai apstrÄdÄtu rakstīšanu, ir lielÄks nekÄ " +"pieejamÄ atmiņas telpa" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "PieprasÄ«tÄ meklēšana ir pirms plÅ«smas sÄkuma" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "PieprasÄ«tÄ meklēšana ir pÄ“c plÅ«smas beigÄm" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "montÄ“jums neatbalsta “unmount†(atmontēšanu)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "montÄ“jums neatbalsta “eject†(izgrūšanu)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"montÄ“jums neatbalsta “unmount†(atmontēšanu) vai “unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "montÄ“jums neatbalsta “eject†(izgrūšanu) vai “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "montÄ“jums neatbalsta “remount†(atkÄrtotu montēšanu)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "montÄ“jums neatbalsta satura tipa minēšanu" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "montÄ“jums neatbalsta sinhrono satura tipa minēšanu" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Datora nosaukums “%s†satur “[†bet ne “]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "TÄ«kls nav sasniedzams" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Dators nav sasniedzams" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "NeizdevÄs izveidot tÄ«kla pÄrraugu — %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "NeizdevÄs izveidot tÄ«kla pÄrraugu:" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "NeizdevÄs saņemt tÄ«kla statusu:" + +#: gio/gnetworkmonitornm.c:348 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager nav palaists" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager versija ir pÄrÄk veca" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Izvades plÅ«sma neatbalsta rakstīšanu" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Uz %s padoto vektoru summa ir pÄrÄk liela" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Avota plÅ«sma jau ir aizvÄ“rta" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Kļūda, sameklÄ“jot “%s†— %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:615 +#, c-format +msgid "%s not implemented" +msgstr "%s nav realizÄ“ts" + +#: gio/gresolver.c:984 gio/gresolver.c:1036 +msgid "Invalid domain" +msgstr "NederÄ«gs domÄ“ns" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Resurss pie “%s†neeksistÄ“" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Resursam pie “%s†neizdevÄs atspiesties" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Resurss pie “%s†nav mape" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Ievades plÅ«sma neatbalsta meklēšanu" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "UzskaitÄ«t sadaļas, kas satur resursus elf DATNÄ’" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"UzskaitÄ«t resursus\n" +"Ja ir norÄdÄ«ta SADAÄ»A, uzskaitÄ«t resursus Å¡ajÄ sadaļÄ\n" +"Ja ir norÄdÄ«ts CEĻŠ, uzskaitÄ«t tikai atbilstoÅ¡us resursus" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "DATNE [CEĻŠ]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SADAÄ»A" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"UzskaitÄ«t resursus ar informÄciju\n" +"Ja ir norÄdÄ«ta SADAÄ»A, uzskaitÄ«t resursus Å¡ajÄ sadaļÄ\n" +"Ja ir norÄdÄ«ts CEĻŠ, uzskaitÄ«t tikai atbilstoÅ¡us resursus\n" +"InformÄcija iekļauj sadaļu, izmÄ“ru un saspieÅ¡anu" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Izvilkt resursu datni uz stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "DATNE CEĻŠ" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Lietojums:\n" +" gresource [--section SADAÄ»A] KOMANDA [ARGUMENTI…]\n" +"\n" +"Komandas:\n" +" help RÄda Å¡o informÄciju\n" +" sections UzskaitÄ«t resursa sadaļas\n" +" list UzskaitÄ«t resursus\n" +" details UzskaitÄ«t resursus ar informÄciju\n" +" extract Izvilkt resursu\n" +"\n" +"Lietojiet “gresource help KOMANDAâ€, lai saņemtu detalizÄ“tu palÄ«dzÄ«bu.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Lietojums:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SADAÄ»A (NeobligÄts) elf sadaļas nosaukums\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:706 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMANDA (neobligÄta) komanda, ko izskaidrot\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " DATNE elf datne (binÄra datne vai koplietota bibliotÄ“ka)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" DATNE elf datne (binÄra datne vai koplietota bibliotÄ“ka)\n" +" vai saspiests resursu datne\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[CEĻŠ]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " CEĻŠ (NeobligÄts) resursa ceļš (var bÅ«t daļējs)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CEĻŠ" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " CEĻŠ Resursa ceļš\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:911 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Nav tÄdas shÄ“mas “%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "ShÄ“ma “%s†nav pÄrvietojama (nedrÄ«kst norÄdÄ«t ceļu)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "ShÄ“ma “%s†ir pÄrvietojama (jÄnorÄda ceļš)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Dots tukÅ¡s ceļš.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Ceļam jÄsÄkas ar slÄ«psvÄ«tru (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Ceļam jÄbeidzas ar slÄ«psvÄ«tru (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Ceļš nedrÄ«kst saturÄ“t divas blakus esoÅ¡as slÄ«psvÄ«tras (//)\n" + +#: gio/gsettings-tool.c:541 +msgid "The provided value is outside of the valid range\n" +msgstr "DotÄ vÄ“rtÄ«ba ir Ärpus derÄ«go vÄ“rtÄ«bu intervÄla\n" + +#: gio/gsettings-tool.c:548 +msgid "The key is not writable\n" +msgstr "AtslÄ“ga nav rakstÄma\n" + +#: gio/gsettings-tool.c:584 +msgid "List the installed (non-relocatable) schemas" +msgstr "Saraksts ar instalÄ“tÄm (nepÄrvietojamÄm) shÄ“mÄm" + +#: gio/gsettings-tool.c:590 +msgid "List the installed relocatable schemas" +msgstr "Saraksts ar instalÄ“tam pÄrvietojamÄm shÄ“mÄm" + +#: gio/gsettings-tool.c:596 +msgid "List the keys in SCHEMA" +msgstr "AtslÄ“gu saraksts SHÄ’MÄ€" + +#: gio/gsettings-tool.c:597 gio/gsettings-tool.c:603 gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH]" +msgstr "SHÄ’MA[:CEĻŠ]" + +#: gio/gsettings-tool.c:602 +msgid "List the children of SCHEMA" +msgstr "BÄ“rnu skaits SHÄ’MÄ€" + +#: gio/gsettings-tool.c:608 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Saraksts ar atslÄ“gÄm un vÄ“rtÄ«bÄm; rekursÄ«vi\n" +"Ja nav dota shÄ“ma, rÄdÄ«t visas atslÄ“gas\n" + +#: gio/gsettings-tool.c:610 +msgid "[SCHEMA[:PATH]]" +msgstr "[SHÄ’MA[:CEĻŠ]" + +#: gio/gsettings-tool.c:615 +msgid "Get the value of KEY" +msgstr "Saņemt vÄ“rtÄ«bu ATSLÄ’GAI" + +#: gio/gsettings-tool.c:616 gio/gsettings-tool.c:622 gio/gsettings-tool.c:628 +#: gio/gsettings-tool.c:640 gio/gsettings-tool.c:652 +msgid "SCHEMA[:PATH] KEY" +msgstr "SHÄ’MA[:CEĻŠ] ATSLÄ’GA" + +#: gio/gsettings-tool.c:621 +msgid "Query the range of valid values for KEY" +msgstr "VaicÄjums derÄ«go vÄ“rtÄ«bu intervÄlam ATSLÄ’GAI" + +#: gio/gsettings-tool.c:627 +msgid "Query the description for KEY" +msgstr "VaicÄt aprakstu ATSLÄ’GAI" + +#: gio/gsettings-tool.c:633 +msgid "Set the value of KEY to VALUE" +msgstr "IestatÄ«t ATSLÄ’GTAS vÄ“rtÄ«bu uz VÄ’RTĪBA" + +#: gio/gsettings-tool.c:634 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SHÄ’MA[:CEĻŠ] ATSLÄ’GA VÄ’RTĪBA" + +#: gio/gsettings-tool.c:639 +msgid "Reset KEY to its default value" +msgstr "PÄrstatÄ«t ATSLÄ’GAS vÄ“rtÄ«bu uz tÄs noklusÄ“to" + +#: gio/gsettings-tool.c:645 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "AtstatÄ«t visas atslÄ“gas SHÄ’MÄ€ uz to noklusÄ“tajÄm vÄ“rtÄ«bÄm" + +#: gio/gsettings-tool.c:651 +msgid "Check if KEY is writable" +msgstr "PÄrbaudÄ«t, vai ATSLÄ’GA ir rakstÄma" + +#: gio/gsettings-tool.c:657 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"NovÄ“rot ATSLÄ’GA uz izmaiņÄm.\n" +"Ja nav norÄdÄ«ta ATSLÄ’GA, novÄ“rot visas atslÄ“gas SHÄ’MÄ€.\n" +"Izmantojiet ^C, lai pÄrtrauktu novÄ“roÅ¡anu.\n" + +#: gio/gsettings-tool.c:660 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SHÄ’MA[:CEĻŠ] [ATSLÄ’GA]" + +#: gio/gsettings-tool.c:672 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Lietojums:\n" +" gsettings --version\n" +" gsettings [--schemadir SHÄ’MAS_MAPE] KOMANDA [ARGUMENTI…]\n" +"\n" +"Commands:\n" +" help RÄda Å¡o informÄciju\n" +" list-schemas UzrÄda instalÄ“tÄs shÄ“mas\n" +" list-relocatable-schemas UzrÄda pÄrvietojamÄs shÄ“mas\n" +" list-keys UzrÄda atslÄ“gas shÄ“mÄs\n" +" list-children UzrÄda shÄ“mas bÄ“rnus\n" +" list-recursively UzrÄda atslÄ“gas un vÄ“rtÄ«bas, rekursÄ«vi\n" +" range VaicÄ atslÄ“gu apgabalu\n" +" describe VaicÄ atslÄ“gas aprakstu\n" +" get Saņem atslÄ“gas vÄ“rtÄ«bu\n" +" set Iestata atslÄ“gas vÄ“rtÄ«bu\n" +" reset Atstata atslÄ“gas vÄ“rtÄ«bu\n" +" reset-recursively Atstata visas vÄ“rtÄ«bas dotajai shÄ“mai\n" +" writable PÄrbauda, vai atslÄ“ga ir rakstÄma\n" +" monitor Uzrauga izmaiņas\n" +"\n" +"Lietojiet “gsettings help KOMANDAâ€, lai saņemtu sÄ«kÄku palÄ«dzÄ«bu.\n" +"\n" + +#: gio/gsettings-tool.c:696 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Lietojums:\n" +" gsettings [--schemadir SHÄ’MAS_MAPE] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:702 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SHÄ’MAS_MAPE Mape, kurÄ meklÄ“t papildu shÄ“mas\n" + +#: gio/gsettings-tool.c:710 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SHÄ’MA ShÄ“mas nosaukums\n" +" CEĻŠ Ceļš pÄrvietojamÄm shÄ“mÄm\n" + +#: gio/gsettings-tool.c:715 +msgid " KEY The (optional) key within the schema\n" +msgstr " ATSLÄ’GA (neobligÄta) atslÄ“ga shÄ“mÄ\n" + +#: gio/gsettings-tool.c:719 +msgid " KEY The key within the schema\n" +msgstr " ATSLÄ’GA AtslÄ“ga shÄ“mÄ\n" + +#: gio/gsettings-tool.c:723 +msgid " VALUE The value to set\n" +msgstr " VÄ’RTĪBA VÄ“rtÄ«ba, ko iestatÄ«t\n" + +#: gio/gsettings-tool.c:778 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "NevarÄ“ja ielÄdÄ“t shÄ“mas no “%s†— “%sâ€\n" + +#: gio/gsettings-tool.c:790 +msgid "No schemas installed\n" +msgstr "Nav instalÄ“tu shÄ“mu\n" + +#: gio/gsettings-tool.c:869 +msgid "Empty schema name given\n" +msgstr "Dots tukÅ¡s shÄ“mas nosaukums\n" + +#: gio/gsettings-tool.c:924 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Nav tÄdas atslÄ“gas “%sâ€\n" + +#: gio/gsocket.c:413 +msgid "Invalid socket, not initialized" +msgstr "NederÄ«ga ligzda, nav inicializÄ“ta" + +#: gio/gsocket.c:420 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "NederÄ«ga ligzda, inicializÄcija neizdevÄs, jo — %s" + +#: gio/gsocket.c:428 +msgid "Socket is already closed" +msgstr "Ligzda jau ir aizvÄ“rta" + +#: gio/gsocket.c:443 gio/gsocket.c:3190 gio/gsocket.c:4420 gio/gsocket.c:4478 +msgid "Socket I/O timed out" +msgstr "Ligzdai I/O iestÄjÄs noildze" + +#: gio/gsocket.c:578 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "izveido GSocket no fd — %s" + +#: gio/gsocket.c:607 gio/gsocket.c:671 gio/gsocket.c:678 +#, c-format +msgid "Unable to create socket: %s" +msgstr "NevarÄ“ja izveidot ligzdu — %s" + +#: gio/gsocket.c:671 +msgid "Unknown family was specified" +msgstr "Tika norÄdÄ«ta nezinÄma saime" + +#: gio/gsocket.c:678 +msgid "Unknown protocol was specified" +msgstr "Tika norÄdÄ«ts nezinÄms protokols" + +#: gio/gsocket.c:1169 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Nevar izmantot datagrammu operÄcijas ar ne-datagrammu ligzdu." + +#: gio/gsocket.c:1186 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "Nevar izmantot datagrammu operÄcijas ar ligzdu, kurai ir noildze." + +#: gio/gsocket.c:1993 +#, c-format +msgid "could not get local address: %s" +msgstr "nevarÄ“ja iegÅ«t lokÄlo adresi — %s" + +#: gio/gsocket.c:2039 +#, c-format +msgid "could not get remote address: %s" +msgstr "nevarÄ“ja iegÅ«t attÄlinÄto adresi — %s" + +#: gio/gsocket.c:2105 +#, c-format +msgid "could not listen: %s" +msgstr "nevar klausÄ«ties — %s" + +#: gio/gsocket.c:2209 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Kļūda, sasaistoties ar adresi %s — %s" + +#: gio/gsocket.c:2385 gio/gsocket.c:2422 gio/gsocket.c:2532 gio/gsocket.c:2557 +#: gio/gsocket.c:2620 gio/gsocket.c:2678 gio/gsocket.c:2696 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Kļūda, pievienojoties multiraides grupai — %s" + +#: gio/gsocket.c:2386 gio/gsocket.c:2423 gio/gsocket.c:2533 gio/gsocket.c:2558 +#: gio/gsocket.c:2621 gio/gsocket.c:2679 gio/gsocket.c:2697 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Kļūda, pametot multiraides grupu — %s" + +#: gio/gsocket.c:2387 +msgid "No support for source-specific multicast" +msgstr "Nav atbalsta avotam specifiskÄm multiraidÄ“m" + +#: gio/gsocket.c:2534 +msgid "Unsupported socket family" +msgstr "NeatbalstÄ«ta ligzdu saime" + +#: gio/gsocket.c:2559 +msgid "source-specific not an IPv4 address" +msgstr "Avotam specifisks nav IPv4 adrese" + +#: gio/gsocket.c:2583 +#, c-format +msgid "Interface name too long" +msgstr "Saskarnes nosaukums ir pÄrÄk garÅ¡" + +#: gio/gsocket.c:2596 gio/gsocket.c:2646 +#, c-format +msgid "Interface not found: %s" +msgstr "Saskarne nav atrasta: %s" + +#: gio/gsocket.c:2622 +msgid "No support for IPv4 source-specific multicast" +msgstr "Nav atbalsta IPv4 avotam specifiskÄm multiraidÄ“m" + +#: gio/gsocket.c:2680 +msgid "No support for IPv6 source-specific multicast" +msgstr "Nav atbalsta IPv6 avotam specifiskÄm multiraidÄ“m" + +#: gio/gsocket.c:2889 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Kļūda, pieņemot savienojumu — %s" + +#: gio/gsocket.c:3015 +msgid "Connection in progress" +msgstr "Notiek savienoÅ¡anÄs" + +#: gio/gsocket.c:3066 +msgid "Unable to get pending error: " +msgstr "Nevar saņemt izpildes gaidīšanas kļūdu:" + +#: gio/gsocket.c:3255 +#, c-format +msgid "Error receiving data: %s" +msgstr "Kļūda, saņemot datus — %s" + +#: gio/gsocket.c:3452 +#, c-format +msgid "Error sending data: %s" +msgstr "Kļūda, sÅ«tot datus — %s" + +#: gio/gsocket.c:3639 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "NeizdevÄs izslÄ“gt ligzdu — %s" + +#: gio/gsocket.c:3720 +#, c-format +msgid "Error closing socket: %s" +msgstr "Kļūda, aizverot ligzdu — %s" + +#: gio/gsocket.c:4413 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Gaida ligzdas nosacÄ«jumu — %s" + +#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833 +#, c-format +msgid "Unable to send message: %s" +msgstr "Nevar nosÅ«tÄ«t ziņojumu — %s" + +#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834 +msgid "Message vectors too large" +msgstr "Ziņojumu vektors ir pÄrÄk liels" + +#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084 +#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304 +#, c-format +msgid "Error sending message: %s" +msgstr "Kļūda, sÅ«tot ziņojumu — %s" + +#: gio/gsocket.c:5026 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage nav atbalstÄ«ts uz Windows" + +#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797 +#, c-format +msgid "Error receiving message: %s" +msgstr "Kļūda, saņemot ziņojumu — %s" + +#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Nevar nolasÄ«t ligzdas datus — %s" + +#: gio/gsocket.c:6136 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials nav implementÄ“ts Å¡ai OS" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "NevarÄ“ja savienoties ar starpniekserveri %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "NevarÄ“ja savienoties ar %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "NevarÄ“ja savienoties:" + +#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Starpnieka mēģinÄÅ¡ana caur ne-TCP savienojumu nav atbalstÄ«ta." + +#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Starpnieka protokols “%s†nav atbalstÄ«ts." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "KlausÄ«tÄjs jau ir aizvÄ“rts" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "PievienotÄ ligzda ir aizvÄ“rta" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 neatbalsta IPv6 adreses “%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "LietotÄja vÄrds ir pÄrÄk garÅ¡ SOCKSv4 protokolam" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Datora nosaukums “%s†ir pÄrÄk garÅ¡ SOCKSv4 protokolam" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Serveris nav SOCKSv4 starpniekserveris." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Savienojums caur SOCKSv4 serveri tika noraidÄ«ts" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Serveris nav SOCKSv5 starpniekserveris." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 starpnieks pieprasa autentificēšanos." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 starpnieks pieprasa autentificēšanos metodi, ko GLib neatbalsta." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "LietotÄjvÄrds vai parole pÄrÄk gara SOCKSv5 protokolam" + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5 autentificēšanÄs neizdevÄs dēļ nepareiza lietotÄjvÄrda vai paroles." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Datora nosaukums “%s†ir pÄrÄk garÅ¡ SOCKSv5 protokolam" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 starpnieka serveris izmanto nezinÄmu adreses tipu." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Iekšēja SOCKSv5 starpnieka servera kļūda." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Noteikumu kopa neļauj SOCKSv5 savienojumu." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Dators nav sasniedzams caur SOCKSv5 serveri." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "TÄ«kls nav sasniedzams caur SOCKSv5 serveri." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Savienojums atteikts caur SOCKSv5 serveri." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 starpnieks neatbalsta “connect†komandu." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 starpnieks neatbalsta doto adreses tipu." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "NezinÄma SOCKSv5 starpnieka kļūda." + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Nevar apstrÄdÄt GThemedIcon versijas %d kodÄ“jumu" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Netika atrasta neviena derÄ«ga adrese" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Kļūda, apgriezti sameklÄ“jot “%s†— %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Nav DNS ierakstu “%s†pieprasÄ«tajam tipam" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "PagaidÄm nevar sameklÄ“t “%sâ€" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Kļūda, sameklÄ“jot “%sâ€" + +#: gio/gtlscertificate.c:419 +msgid "No PEM-encoded private key found" +msgstr "Nav atrasts PEM iekodÄ“ta privÄta atslÄ“ga" + +#: gio/gtlscertificate.c:429 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "NevarÄ“ja atÅ¡ifrÄ“t PEM-iekodÄ“tu privÄto atslÄ“gu" + +#: gio/gtlscertificate.c:440 +msgid "Could not parse PEM-encoded private key" +msgstr "NevarÄ“ja parsÄ“t PEM-iekodÄ“tu privÄto atslÄ“gu" + +#: gio/gtlscertificate.c:467 +msgid "No PEM-encoded certificate found" +msgstr "Nav atrasts PEM-iekodÄ“ts sertifikÄts" + +#: gio/gtlscertificate.c:476 +msgid "Could not parse PEM-encoded certificate" +msgstr "NevarÄ“ja parsÄ“t PEM-iekodÄ“tu sertifikÄtu" + +#: gio/gtlscertificate.c:832 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Å is GTlsBackend neatbalsta PKCS #11 sertifikÄtu izveidoÅ¡anu" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Å Ä« ir pÄ“dÄ“jÄ iespÄ“ja ievadÄ«t pareizu paroli, pirms jums tiek bloÄ·Ä“ta pieeja." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"VairÄkas ievadÄ«tÄs paroles ir bijuÅ¡as nepareizas, un jÅ«s tiksiet izslÄ“gts " +"pÄ“c turpmÄkÄm neveiksmÄ“m." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "IevadÄ«tÄ parole ir nepareiza." + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "GaidÄ«ja 1 kontroles ziņojumu, saņēma %d" +msgstr[1] "GaidÄ«ja 1 kontroles ziņojumu, saņēma %d" +msgstr[2] "GaidÄ«ja 1 kontroles ziņojumu, saņēma %d" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "NegaidÄ«ts palÄ«gdatu tips" + +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "GaidÄ«ja vienu fd, bet saņēma %d\n" +msgstr[1] "GaidÄ«ja vienu fd, bet saņēma %d\n" +msgstr[2] "GaidÄ«ja vienu fd, bet saņēma %d\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Saņemts nederÄ«gs fd" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "Kļūda, sÅ«tot rekvizÄ«tus: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Kļūda, pÄrbaudot, vai SO_PASSCRED ir aktivÄ“ts ligzdai — %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Kļūda, aktivÄ“jot SO_PASSCRED — %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Tikai gaidÄ«ts saņemt vienu baitu, lai saņemtu rekvizÄ«tus, bet nolasÄ«ja nulle " +"baitu" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Negaida kontroles ziņojumu, bet saņēma %d" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Kļūda, deaktivÄ“jot SO_PASSCRED — %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Kļūda, nolasot datnes deskriptoru — %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Kļūda, aizverot datnes deskriptoru — %s" + +#: gio/gunixmounts.c:2785 gio/gunixmounts.c:2838 +msgid "Filesystem root" +msgstr "Datņu sistÄ“mas sakne" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Kļūda, rakstot datnes deskriptorÄ â€” %s" + +#: gio/gunixsocketaddress.c:244 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Abstraktas UNIX domÄ“na ligzdas uz šīs sistÄ“mas nav atbalstÄ«tas" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "sÄ“jums neatbalsta izgrūšanu" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "sÄ“jums neatbalsta izgrūšanu vai eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Kļūda, lasot no tura — %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Kļūda, aizverot turi — %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Kļūda, rakstot turÄ« — %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nepietiek atmiņas" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Iekšēja kļūda — %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Vajag vairÄk ievades" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "NederÄ«gi saspiestie dati" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adrese, ko klausÄ«ties" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "IgnorÄ“ts priekÅ¡ compat ar GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "DrukÄÅ¡anas adrese" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "DrukÄt adresi Äaulas režīmÄ" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Palaist dbus servisu" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Nepareizi parametri\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "NegaidÄ«ts atribÅ«ts “%s†elementam “%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "AtribÅ«ts “%s†elementam “%s†netika atrasts" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "NegaidÄ«ta birka “%sâ€, tika gaidÄ«t birka “%sâ€" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "NegaidÄ«ta birka “%s†iekÅ¡ “%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "NederÄ«gs datums/laiks “%s†grÄmatzÄ«mes datnÄ“" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Nav atrasts derÄ«ga grÄmatzÄ«mes datne datu mapÄ“s" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "GrÄmatzÄ«me ar URI “%s†jau eksistÄ“" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nav atrasta grÄmatzÄ«me URI “%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Nav definÄ“ts MIME tips grÄmatzÄ«mÄ“ URI “%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Nav definÄ“ti privÄtie karogi grÄmatzÄ«mÄ“s URI “%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Nav iestatÄ«tas grupas grÄmatzÄ«mÄ“s URI “%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Neviena lietotne ar nosaukumu “%s†nav reÄ£istrÄ“jusi “%s†grÄmatzÄ«mi" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "NeizdevÄs izvÄ“rst exec rindu “%s†ar URI “%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "NeattÄ“lojama rakstzÄ«me konversijas ievadÄ“" + +#: glib/gconvert.c:495 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "Daļēja simbolu secÄ«ba ievades beigÄs" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Nevar pÄrveidot atkÄpÅ¡anos “%s†uz rakstzÄ«mju kopu “%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Iegults NUL baits konversijas ievadÄ“" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Iegults NUL baits konversijas izvadÄ“" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI “%s†nav absolÅ«tais URI, lietojot “file†shÄ“mu" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "LokÄlÄs datnes URI “%s†nedrÄ«kst saturÄ“t “#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI “%s†nav pareizs" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Resursdatora nosaukuma URI “%s†nav pareizs" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI “%s†satur nepareizi veidotas atsoļa rakstzÄ«mes" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Ceļa nosaukums “%s†nav absolÅ«ts ceļš" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A, %Y. gada %e. %B, plkst. %H un %M" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "JanvÄris" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "FebruÄris" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Marts" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "AprÄ«lis" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Maijs" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "JÅ«nijs" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "JÅ«lijs" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Augusts" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Septembris" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Oktobris" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Novembris" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Decembris" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "JÅ«n" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "JÅ«l" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Oct" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Pirmdiena" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Otrdiena" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "TreÅ¡diena" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Ceturdiena" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Piektdiena" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sestdiena" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "SvÄ“tdiena" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Pr" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Ot" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Tr" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Ct" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Pk" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Se" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Sv" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "janvÄris" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "februÄris" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "marts" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "aprÄ«lis" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "maijs" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "jÅ«nijs" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "jÅ«lijs" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "augusts" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "septembris" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "oktobris" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "novembris" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "decembris" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "janv." + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "febr." + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "marts" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr." + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "maijs" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jÅ«n." + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "jÅ«l." + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "aug." + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sept." + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt." + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov." + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec." + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Kļūda, atverot direktoriju “%s†— %s" + +#: glib/gfileutils.c:737 glib/gfileutils.c:829 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "NevarÄ“ja piešķirt %lu baitu, lai nolasÄ«tu datni “%sâ€" +msgstr[1] "NevarÄ“ja atrast %lu baitus, lai nolasÄ«tu datni “%sâ€" +msgstr[2] "NevarÄ“ja atrast %lu baitus, lai nolasÄ«tu datni “%sâ€" + +#: glib/gfileutils.c:754 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Kļūda, nolasot datni “%s†— %s" + +#: glib/gfileutils.c:790 +#, c-format +msgid "File “%s†is too large" +msgstr "Datne “%s†ir pÄrÄk liela" + +#: glib/gfileutils.c:854 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "NeizdevÄs nolasÄ«t no datnes “%s†— %s" + +#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1468 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "NeizdevÄs atvÄ“rt datni “%s†— %s" + +#: glib/gfileutils.c:917 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "NeizdevÄs dabÅ«t datnes “%s†atribÅ«tus — fstat() neizdevÄs — %s" + +#: glib/gfileutils.c:948 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "NeizdevÄs atvÄ“rt “%s†— fdopen() neizdevÄs — %s" + +#: glib/gfileutils.c:1049 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "NeizdevÄs pÄrsaukt datni “%s†uz “%s†— g_rename() neizdevÄs — %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "NeizdevÄs rakstÄ«t datnÄ“ “%s†— write() neizdevÄs — %s" + +#: glib/gfileutils.c:1196 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "NeizdevÄs rakstÄ«t datnÄ“ “%s†— fsync() neizdevÄs — %s" + +#: glib/gfileutils.c:1357 glib/gfileutils.c:1772 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "NeizdevÄs izveidot datni “%s†— %s" + +#: glib/gfileutils.c:1402 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "NevarÄ“ja izdzÄ“st esoÅ¡o datni “%s†— g_unlink() neizdevÄs — %s" + +#: glib/gfileutils.c:1737 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Veidne “%s†ir nepareiza, nedrÄ«kstÄ“tu saturÄ“t “%sâ€" + +#: glib/gfileutils.c:1750 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Veidne “%s†nesatur XXXXXX" + +#: glib/gfileutils.c:2310 glib/gfileutils.c:2339 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "NeizdevÄs nolasÄ«t simbolisko saiti “%s†— %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "NevarÄ“ja atvÄ“rt pÄrveidotÄju no “%s†uz “%s†— %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "NeizdevÄs izpildÄ«t jÄ“llasīšanu iekÅ¡ g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "PÄpalikuÅ¡ie nepÄrveidotie dati nolasīšanas buferÄ«" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "KanÄls pÄrtrÅ«kst daļējÄ rakstzÄ«mÄ“" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "NeizdevÄs izpildÄ«t jÄ“llasīšanu iekÅ¡ g_io_channel_read_to_end" + +#: glib/gkeyfile.c:790 +msgid "Valid key file could not be found in search dirs" +msgstr "Meklēšanas mapÄ“s nevarÄ“ja atrast derÄ«gu atslÄ“gu" + +#: glib/gkeyfile.c:827 +msgid "Not a regular file" +msgstr "Nav parasta datne" + +#: glib/gkeyfile.c:1282 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"AtslÄ“gu datne satur rindu “%sâ€, kura nav atslÄ“gas vÄ“rtÄ«bas pÄris, grupa vai " +"komentÄrs" + +#: glib/gkeyfile.c:1339 +#, c-format +msgid "Invalid group name: %s" +msgstr "NederÄ«gs grupas nosaukums — %s" + +#: glib/gkeyfile.c:1361 +msgid "Key file does not start with a group" +msgstr "AtslÄ“gu datne nesÄkas ar grupu" + +#: glib/gkeyfile.c:1387 +#, c-format +msgid "Invalid key name: %s" +msgstr "NederÄ«gs atslÄ“gas nosaukums — %s" + +#: glib/gkeyfile.c:1414 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "AtslÄ“gu datne satur neatbalstÄ«tu kodÄ“jumu “%sâ€" + +#: glib/gkeyfile.c:1663 glib/gkeyfile.c:1836 glib/gkeyfile.c:3289 +#: glib/gkeyfile.c:3353 glib/gkeyfile.c:3483 glib/gkeyfile.c:3615 +#: glib/gkeyfile.c:3761 glib/gkeyfile.c:3996 glib/gkeyfile.c:4063 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "AtslÄ“gu datnei nav grupa “%sâ€" + +#: glib/gkeyfile.c:1791 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "AtslÄ“gu datnei nav atslÄ“gas “%s†grupÄ â€œ%sâ€" + +#: glib/gkeyfile.c:1953 glib/gkeyfile.c:2069 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "AtslÄ“gu datne satur atslÄ“gu “%s†ar vÄ“rtÄ«bu “%s†kas nav UTF-8" + +#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089 glib/gkeyfile.c:2531 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"AtslÄ“gu datne satur atslÄ“gu “%sâ€. kurai ir vÄ“rtÄ«ba, kuru nevar interpretÄ“t." + +#: glib/gkeyfile.c:2749 glib/gkeyfile.c:3118 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"AtslÄ“gu datne satur atslÄ“gu “%s†grupÄ â€œ%s†kurai ir vÄ“rtÄ«ba, ko nevar " +"interpretÄ“t." + +#: glib/gkeyfile.c:2827 glib/gkeyfile.c:2904 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "AtslÄ“gai “%s†grupÄ â€œ%s†ir vÄ“rtÄ«ba “%sâ€, kur bija jÄbÅ«t %s" + +#: glib/gkeyfile.c:4306 +msgid "Key file contains escape character at end of line" +msgstr "AtslÄ“gu datne satur atsoļa rakstzÄ«me rindas beigÄs" + +#: glib/gkeyfile.c:4328 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "AtslÄ“gu datne satur nederÄ«gu atsoļa sekvenci “%sâ€" + +#: glib/gkeyfile.c:4472 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "VÄ“rtÄ«bu “%s†nevar interpretÄ“t kÄ skaitli." + +#: glib/gkeyfile.c:4486 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "VeselÄ skaitļa “%s†vÄ“rtÄ«ba ir Ärpus apgabala" + +#: glib/gkeyfile.c:4519 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "VÄ“rtÄ«bu “%s†nevar interpretÄ“t kÄ peldoÅ¡o komatu." + +#: glib/gkeyfile.c:4558 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "VÄ“rtÄ«bu “%s†nevar interpretÄ“t kÄ BÅ«la vÄ“rtÄ«bu." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "NevarÄ“ja dabÅ«t datnes “%s%s%s%s†atribÅ«tus — fstat() neizdevÄs — %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "NeizdevÄs kartÄ“t %s%s%s%s — mmap() neizdevÄs — %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "NeizdevÄs atvÄ“rt datni “%s†— open() neizdevÄs — %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Kļūda rindÄ %d rakstzÄ«me %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Nepareizi kodÄ“ts UTF-8 teksts — nav derÄ«gs “%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†nav derÄ«gs nosaukums" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†nav derÄ«gs nosaukums — “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Kļūda rindÄ %d — %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"NeizdevÄs apstrÄdÄt “%-.*sâ€, kur vajadzÄ“tu bÅ«t ciparam rakstzÄ«mes atsaucÄ“ " +"(piemÄ“ram, ê) — iespÄ“jams, ka cipars ir pÄrÄk liels" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"RakstzÄ«mes atsauce nebeidzÄs ar semikolu; visdrÄ«zÄk jÅ«s lietojÄt & zÄ«mi bez " +"nodoma sÄkt entÄ«tiju — aizvieto “&†zÄ«mes ar &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "RakstzÄ«mes atsauce “%-.*s†neiekodÄ“ atļautu rakstzÄ«mi" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"PamanÄ«ta tukÅ¡a entÄ«tija “&;â€; derÄ«gas entÄ«tijas ir: & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "EntÄ«tijas nosaukums “%-.*s†nav zinÄms" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"EntÄ«tija nebeidzÄs ar semikolu; visdrÄ«zÄk jÅ«s lietojÄt “&†zÄ«mi bez nodoma " +"sÄkt entÄ«tiju — aizvieto “&†zÄ«mes ar &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumentam jÄsÄkas ar elementu (piemÄ“ram, )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%s†nav atļauta rakstzÄ«me, sekojoÅ¡a aiz rakstzÄ«mes “<†tÄ nedrÄ«kst iesÄkt " +"elementa vÄrdu." + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"SavÄda rakstzÄ«me “%sâ€. Tika gaidÄ«ta “>†rakstzÄ«me, kas nobeigtu sÄkuma birku " +"elementam “%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "PÄrÄk daudz atribÅ«tu elementÄ â€œ%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"SavÄda rakstzÄ«me “%sâ€, gaidÄ«ju “=†aiz atribÅ«ta nosaukuma “%s†elementam “%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"SavÄda rakstzÄ«me “%sâ€, tika gaidÄ«ta “>†vai “/†rakstzÄ«me, kas nobeigtu " +"sÄkuma birku elementam “%s†vai fakultatÄ«vi atribÅ«tu; iespÄ“jams, jÅ«s " +"lietojÄt nepareizu rakstzÄ«mi atribÅ«ta nosaukumÄ" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"SavÄda rakstzÄ«me “%sâ€, tika gaidÄ«tas atvÄ“rtÄs pÄ“diņas pÄ“c vienÄdÄ«bas zÄ«me, " +"nosakot vÄ“rtÄ«bu atribÅ«tam “%s†no elementa “%sâ€" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%s†nav derÄ«ga rakstzÄ«me, sekojot aizveroÅ¡Ä elementa nosaukumam “%sâ€; " +"atļautÄ rakstzÄ«me ir “>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Elements “%s†tika aizvÄ“rts, neviens elements paÅ¡laik nav atvÄ“rts" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Elements “%s†tika aizvÄ“rts, bet paÅ¡laik atvÄ“rtais elements ir “%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokuments bija tukÅ¡s vai saturÄ“ja tikai tukÅ¡u atstarpi" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokuments negaidÄ«ti izbeidzÄs tieÅ¡i pÄ“c atvÄ“rtÄs leņķa iekavas “<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokuments negaidÄ«ti izbeidzÄs ar joprojÄm atvÄ“rtiem elementiem — “%s†bija " +"pÄ“dÄ“jais atvÄ“rtais elements" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokuments negaidÄ«ti izbeidzÄs, gaidÄ«ja ieraudzÄ«t aizveroÅ¡o leņķa iekavu, " +"beidzoties ar tagu <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokuments negaidÄ«ti izbeidzÄs elementa nosaukumÄ" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokuments negaidÄ«ti izbeidzÄs atribÅ«ta nosaukumÄ" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokuments negaidÄ«ti izbeidzÄs elementa atveroÅ¡ajÄ birkÄ." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokuments negaidÄ«ti beidzÄs aiz vienÄdÄ«bas zÄ«mes, sekojot atribÅ«ta " +"nosaukumam; nav atribÅ«ta vÄ“rtÄ«bas" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokuments negaidÄ«ti beidzÄs kamÄ“r atradÄs atribÅ«ta vÄ“rtÄ«bÄ" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokuments negaidÄ«ti beidzÄs elementa “%s†aizveroÅ¡ajÄ birkÄ" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "Dokuments negaidÄ«ti beidzÄs aizveroÅ¡ajÄ birkÄ neatvÄ“rtam elementam" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokuments negaidÄ«ti izbeidzÄs komentÄrÄ vai apstrÄdes instrukcijÄ" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPCIJA…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "PalÄ«dzÄ«bas opcijas:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "RÄdÄ«t palÄ«dzÄ«bas opcijas" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "RÄdÄ«t visas palÄ«dzÄ«bas opcijas" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Lietotnes opcijas:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opcijas:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Nevar apstrÄdÄt veselÄ skaitļa vÄ“rtÄ«bu “%s†priekÅ¡ %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "VeselÄ skaitļa vÄ“rtÄ«ba “%s†priekÅ¡ %s ir Ärpus apgabala" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Nevar apstrÄdÄt dubulto vÄ“rtÄ«bu “%s†priekÅ¡ %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "DubultÄ vÄ“rtÄ«ba “%s†priekÅ¡ %s ir Ärpus apgabala" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Kļūda, parsÄ“jot opciju %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "TrÅ«kst %s arguments" + +#: glib/goption.c:2185 +#, c-format +msgid "Unknown option %s" +msgstr "NezinÄma opcija %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "bojÄts objekts" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "IekšējÄ kļūda vai bojÄts objekts" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "beigusies atmiņa" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "atpakaļ izsekoÅ¡anas limits ir sasniegts" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "raksts satur elementus, kurus neatbalsta daļējÄ atbilstÄ«ba" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "iekšēja kļūda" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "atpakaļ atsauces kÄ nosacÄ«jumus neatbalsta daļējÄ atbilstÄ«ba" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "rekursiju limits ir sasniegts" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "nederÄ«ga jauno rindu karogu kombinÄcija" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "slikta nobÄ«de" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "Ä«ss utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "rekursijas cikls" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "nezinÄma kļūda" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ raksta beigÄs" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c raksta beigÄs" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "pÄ“c \\ seko neatpazÄ«ta rakstzÄ«me" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "skaitļi nav pareizÄ secÄ«bÄ {} kvantorÄ" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "skaitlis pÄrÄk liels {} kvantorÄ" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "trÅ«kst beigu “]†rakstzÄ«mju klasei" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "nederÄ«ga atsoļu sekvence rakstzÄ«mju klasÄ“" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "rakstzÄ«mju klasÄ“ apgabals ir Ärpus secÄ«bas" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nav ko atkÄrtot" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "negaidÄ«ta atkÄrtoÅ¡anÄs" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "neatpazÄ«ta rakstzÄ«me pÄ“c (? vai (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX nosauktÄs klases ir atbalstÄ«tas tikai klasÄ“s" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "trÅ«kst beigu )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "atsauce uz neesoÅ¡u apakÅ¡rakstu" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "trÅ«kst ) pÄ“c komentÄra" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "regulÄrÄ izteiksme ir pÄrÄk gara" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "neizdevÄs iegÅ«t atmiņu" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") bez atveroÅ¡Äs (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "koda pÄrpilde" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "neatpazÄ«ta rakstzÄ«me pÄ“c (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind pieņēmums nav fiksÄ“ta garuma" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "slikti formatÄ“ts skaitlis vai nosaukums pÄ“c (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "nosacÄ«juma grupa satur vairÄk kÄ divus zarus" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "pÄ“c (?( tiek sagaidÄ«ts pieņēmums" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "pÄ“c (?R vai (?[+-]digits ir jÄseko )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nezinÄms POSIX klases nosaukums" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX savÄktie elementi nav atbalstÄ«ti" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "rakstzÄ«mes vÄ“rtÄ«ba \\x{...} sekvencÄ“ ir pÄrÄk liela" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "nederÄ«gs nosacÄ«jums (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C nav atļauts lookbehind pieņēmumÄ" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "atsoļi \\L, \\l, \\N{nosaukums}, \\U un \\u nav atbalstÄ«ti" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "rekursÄ«vais izsaukums varÄ“tu cikloties bezgalÄ«gi" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "neatpazÄ«ta rakstzÄ«me pÄ“c (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "trÅ«kst nobeiguma apakÅ¡raksta nosaukumÄ" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "divi nosaukti apakÅ¡raksti ir ar vienÄdiem nosaukumiem" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "slikti formatÄ“ta \\P vai \\p sekvence" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nezinÄms Ä«pašības nosaukums pÄ“c \\P vai \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "apakÅ¡raksta nosaukums ir pÄrÄk liels (maksimums ir 32 rakstzÄ«mes)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "pÄrÄk daudz nosauktu apakÅ¡rakstu (maksimums ir 10 000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "astotnieku vÄ“rtÄ«ba ir lielÄka nekÄ \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "pÄrtÄ“rÄ“ta kompilēšanas darba telpa" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "iepriekÅ¡ pÄrbaudÄ«ts norÄdÄ«tais apakÅ¡raksts nav atrasts" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE grupa satur vairÄk kÄ vienu zaru" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "nekonsekventas NEWLINE opcijas" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"pÄ“c \\g neseko nosaukums iekavÄs, leņķa iekavÄs vai pÄ“diņÄs vai vienkÄrÅ¡s " +"skaitlis" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "skaitliska atsauce nevar bÅ«t nulle" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "arguments nav atļauts priekÅ¡ (*ACCEPT), (*FAIL) vai (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) nav atpazÄ«ts" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "skaitlis ir pÄrÄk liels" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "trÅ«kst apakÅ¡raksta nosaukums pÄ“c (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "tika gaidÄ«ts cipars pÄ“c (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] ir nederÄ«ga datu rakstzÄ«me JavaScript savietojamÄ«bas režīmÄ" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "dažÄdi nosaukumi apakÅ¡rakstiem ir ar vienÄdiem numuriem nav atļauti" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) jÄbÅ«t ar argumentu" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c jÄseko ASCII rakstzÄ«mei" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "pÄ“c \\k neseko nosaukums iekavÄs, leņķa iekavÄs vai pÄ“diņÄs" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N nav atbalstÄ«ts klasÄ“" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "pÄrÄk daudz atsauÄu uz priekÅ¡u" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "nosaukums ir pÄrÄk garÅ¡ iekÅ¡ (*MARK), (*PRUNE), (*SKIP) vai (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "rakstzÄ«mes vÄ“rtÄ«ba \\u.... sekvencÄ“ ir pÄrÄk liela" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Kļūda, kamÄ“r meklÄ“ atbilstÄ«bas regulÄrajai izteiksmei %s — %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE bibliotÄ“ka ir kompilÄ“ta bez UTF8 atbalsta" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE bibliotÄ“ka ir kompilÄ“ta bez UTF8 Ä«pašību atbalsta" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE bibliotÄ“ka ir kompilÄ“ta ar UTF8 Ä«pašību atbalstu" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Kļūda, optimizÄ“jot regulÄro izteiksmi %s — %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Kļūda, kompilÄ“jot regulÄro izteiksmi %s pie rakstzÄ«mes %d — %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "tika gaidÄ«ts heksadecimÄlais cipars vai “}â€" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "tika gaidÄ«ts heksadecimÄlais cipars" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "simboliskajÄ norÄdÄ“ trÅ«kst “<â€" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "nepabeigta simboliskÄ norÄde" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "simboliskÄs norÄdes garums ir nulle" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "tika gaidÄ«ts cipars" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "neatļauta simboliskÄ norÄde" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "noklÄ«dis beigu “\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "nezinÄma atsoļa sekvence" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Kļūda, apstrÄdÄjot aizvietoÅ¡anas tekstu “%s†pie rakstzÄ«mes %lu — %s" + +#: glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "CitÄ“tais teksts nesÄkas ar jautÄjuma zÄ«mi" + +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "NeatbilstoÅ¡a jautÄjuma zÄ«me komandrindÄ vai citÄ Äaulas-citÄ“tÄ tekstÄ" + +#: glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Teksts beidzÄs tieÅ¡i pÄ“c “\\†rakstzÄ«mes. (Teksts bija “%sâ€)" + +#: glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Teksts beidzÄs pirms atbilstoÅ¡ais citÄts tika atrasts priekÅ¡ %c. (Teksts " +"bija “%sâ€)" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Teksts bija tukÅ¡s (vai saturÄ“ja tikai tukÅ¡umus)" + +#: glib/gspawn.c:308 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "NevarÄ“ja nolasÄ«t datus no bÄ“rnprocesa (%s)" + +#: glib/gspawn.c:458 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "NegaidÄ«ta kļūda, lasot datus no bÄ“rnprocesa (%s)" + +#: glib/gspawn.c:543 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NegaidÄ«ta kļūda waitpid() (%s)" + +#: glib/gspawn.c:1152 glib/gspawn-win32.c:1407 +#, c-format +msgid "Child process exited with code %ld" +msgstr "BÄ“rna process beidza darbu ar kodu %ld" + +#: glib/gspawn.c:1160 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "BÄ“rna process tika pÄrtraukts ar signÄlu %ld" + +#: glib/gspawn.c:1167 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "BÄ“rna process tika apturÄ“ts ar signÄlu %ld" + +#: glib/gspawn.c:1174 +#, c-format +msgid "Child process exited abnormally" +msgstr "BÄ“rna process beidza darbu nenormÄli" + +#: glib/gspawn.c:1793 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "NevarÄ“ja nolasÄ«t no bÄ“rna programkanÄla (%s)" + +#: glib/gspawn.c:2095 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "NevarÄ“ja radÄ«t bÄ“rnprocesu “%s†(%s)" + +#: glib/gspawn.c:2212 +#, c-format +msgid "Failed to fork (%s)" +msgstr "NeizdevÄs sadalÄ«t (%s)" + +#: glib/gspawn.c:2372 glib/gspawn-win32.c:381 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "NevarÄ“ja pÄriet uz direktoriju “%s†(%s)" + +#: glib/gspawn.c:2382 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "NevarÄ“ja izpildÄ«t bÄ“rnprocesu “%s†(%s)" + +#: glib/gspawn.c:2392 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "NevarÄ“ja novadÄ«t bÄ“rnprocesa (%s) izvadi vai ievadi" + +#: glib/gspawn.c:2401 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "NevarÄ“ja sazarot bÄ“rnprocesu (%s)" + +#: glib/gspawn.c:2409 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "NezinÄma kļūda, izpildot bÄ“rnprocesu “%sâ€" + +#: glib/gspawn.c:2433 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"NevarÄ“ja nolasÄ«t pietiekami daudz datus no bÄ“rna pid programkanÄla (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "NevarÄ“ja nolasÄ«t datus no bÄ“rnprocesa" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "NevarÄ“ja izveidot programkanÄlu komunikÄcijai ar bÄ“rnprocesu (%s)" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "NevarÄ“ja izpildÄ«t bÄ“rnprocesu (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "NederÄ«gs programmas nosaukums — %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:779 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "NederÄ«ga virkne argumenta vektorÄ pie %d — %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:794 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "NederÄ«ga virkne vidÄ“ — %s" + +#: glib/gspawn-win32.c:775 +#, c-format +msgid "Invalid working directory: %s" +msgstr "NederÄ«ga darba mape — %s" + +#: glib/gspawn-win32.c:837 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "NeizdevÄs izpildÄ«t palÄ«ga programmu (%s)" + +#: glib/gspawn-win32.c:1064 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"NegaidÄ«ta kļūda iekÅ¡ g_io_channel_win32_poll(), lasot datus no bÄ“rnprocesa" + +#: glib/gstrfuncs.c:3338 glib/gstrfuncs.c:3440 +msgid "Empty string is not a number" +msgstr "TukÅ¡a virkne nav skaitlis" + +#: glib/gstrfuncs.c:3362 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†nav skaitlis ar zÄ«mi" + +#: glib/gstrfuncs.c:3372 glib/gstrfuncs.c:3476 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Skaitlis “%s†ir Ärpus robežÄm [%s, %s]" + +#: glib/gstrfuncs.c:3466 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†nav skaitlis bez zÄ«mes" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "NederÄ«gs %-kodÄ“jums iekÅ¡ URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Neatļauta rakstzÄ«me iekÅ¡ URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Ne-UTF-8 rakstzÄ«mes iekÅ¡ URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "NederÄ«ga IPv6 adrese “%.*s†iekÅ¡ URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Nepareizi iekodÄ“ta IP adrese “%.*s†iekÅ¡ URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nepareizi internacionalizÄ“ts resursdatora nosaukums “%.*s†iekÅ¡ URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "NevarÄ“ja parsÄ“t portu “%.*s†iekÅ¡ URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "URI ports “%.*s†ir Ärpus apgabala" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI “%s†nav absolÅ«ts URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI “%s†nav resursdatora komponentes" + +#: glib/guri.c:1435 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI nav absolÅ«ts un netika dots bÄzes URI" + +#: glib/guri.c:2213 +msgid "Missing ‘=’ and parameter value" +msgstr "TrÅ«kst “=†un parametra vÄ“rtÄ«bas" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "NeizdevÄs piešķirt atmiņu" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "RakstzÄ«me nav UTF-8 apgabalÄ" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "Nepareiza secÄ«ba konversijas ievadÄ“" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "RakstzÄ«me nav UTF-16 apgabalÄ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2727 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2729 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2731 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2733 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2735 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2737 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2741 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2743 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2745 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2747 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2749 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2751 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2755 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2757 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2759 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2761 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2763 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2765 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2769 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2771 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2773 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2775 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2777 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2779 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2813 glib/gutils.c:2930 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u baits" +msgstr[1] "%u baiti" +msgstr[2] "%u baitu" + +#: glib/gutils.c:2817 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bits" +msgstr[1] "%u biti" +msgstr[2] "%u bitu" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2884 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s baits" +msgstr[1] "%s baiti" +msgstr[2] "%s baitu" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2889 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bits" +msgstr[1] "%s biti" +msgstr[2] "%s bitu" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2943 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:2948 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2953 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2958 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2963 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2968 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "NevarÄ“ja ielÄdÄ“t /var/lib/dbus/machine-id vai /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "NezinÄma kļūda savienojoties" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Kļūda adresÄ“ “%s†— saimes atribÅ«ts ir slikti noformÄ“ts" + +#~ msgid "No such method '%s'" +#~ msgstr "Nav tÄdas metodes “%sâ€" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Nevar noteikt kopnes adresi no DBUS_STARTER_BUS_TYPE vides mainÄ«gÄ â€” " +#~ "nezinÄma vÄ“rtÄ«ba “%sâ€" + +#~ msgid "[ARGS...]" +#~ msgstr "[PARAM...]" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "MontÄ“ja %s pie %s\n" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "NeizdevÄs izveidot pagaidu datni — %s" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; ignorÄ“ pÄrrakstīšanu Å¡ai atslÄ“gai.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " un tika norÄdÄ«ts --strict; iziet.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "IgnorÄ“ pÄrrakstīšanu Å¡ai atslÄ“gai.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "neko nedarÄ«t.\n" diff --git a/po/mai.po b/po/mai.po new file mode 100644 index 0000000..089f38d --- /dev/null +++ b/po/mai.po @@ -0,0 +1,3845 @@ +# translation of glib.HEAD.po to maithili +# BOSS GNU/Linux , 2008. +# Rajesh Ranjan , 2009. +# translation to glib to Maithili +# Copyright (C) 2006 The GNOME Foundation +# This file is distributed under the same license as the PACKAGE package. +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2009-02-27 17:15+0530\n" +"Last-Translator: Rajesh Ranjan \n" +"Language-Team: maithili \n" +"Language: mai\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"\n" +"\n" +"\n" +"\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "'%s' अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ गà¥à¤£ '%s' ततà¥à¤µ क' लेल" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' ततà¥à¤µ '%s' क' गà¥à¤£ नहि भेटल" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "'%s' अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ टैग, '%s' टैग पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ टैग '%s' '%s' क' भीतर" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "कोनो वैध पà¥à¤¸à¥à¤¤à¤•चिहà¥à¤¨ फाइल आà¤à¤•ड़ा निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ामे नहि मिलल" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s' क' लेल पà¥à¤¸à¥à¤¤à¤•चिहà¥à¤¨ पहिनेसठमोजà¥à¤¦ अछि" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s' क' लेल कोनो पà¥à¤¸à¥à¤¤à¤•चिहà¥à¤¨ नहि मिलल" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "कोनो MIME पà¥à¤°à¤•ार URI '%s' क' लेल पà¥à¤¸à¥à¤¤à¤•चिहà¥à¤¨à¤®à¥‡ परिभाषित नहि अछि" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s' क' लेल पà¥à¤¸à¥à¤¤à¤•चिहà¥à¤¨à¤®à¥‡ कोनो निज फà¥à¤²à¥ˆà¤— परिभाषित नहि अछि" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s' क' लेल पà¥à¤¸à¥à¤¤à¤•चिहà¥à¤¨à¤®à¥‡ कोनो समूह सेट नहि अछि" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "'%s' क' नामसठकोनो अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— '%s' क' लेल पà¥à¤¸à¥à¤¤à¤•चिहà¥à¤¨ पंजीकृत नहि अछि" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "अकà¥à¤·à¤° समूह '%s' सठ'%s' मे परिवरà¥à¤¤à¤¨ समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' सठ'%s' परिवरà¥à¤¤à¤• नहि खोलल जाठसकल" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "परिवरà¥à¤¤à¤¨ इनपà¥à¤Ÿà¤®à¥‡ अवैध बाइट अनà¥à¤•à¥à¤°à¤®" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "परिवरà¥à¤¤à¤¨à¤• दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "इनपà¥à¤Ÿ क' अंतमे आंशिक अकà¥à¤·à¤° अनà¥à¤•à¥à¤°à¤®" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "फालबैक '%s' केठकोड सेट '%s' मे बदà¤à¤² नहि कठसकल" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "\"file\" योजना क' उपयोग करैबला URI '%s' à¤à¤•टा निरपेकà¥à¤· यूआरआई नहि अछि" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "सà¥à¤¥à¤¾à¤¨à¥€à¤¯ फाइल यूआरआई '%s' मे à¤à¤•टा '#' समà¥à¤®à¤¿à¤²à¤¿à¤¤ नहि अछि" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "यूआरआई '%s' अवैध अछि" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "यूआरआई '%s' क' होसà¥à¤Ÿà¤¨à¤¾à¤® अवैध अछि" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "यूआरआई '%s' मे अवैध à¤à¤¸à¥à¤•ेपà¥à¤¡ अकà¥à¤·à¤° समà¥à¤®à¤¿à¤²à¤¿à¤¤ अछि" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "पथनाम '%s' à¤à¤•टा निरपेकà¥à¤· पथ नहि अछि" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "अवैध होसà¥à¤Ÿ-नाम" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "पूरà¥à¤µà¤¾à¤¹à¥à¤¨" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "अपराहà¥à¤¨" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%A %d %b %Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%I:%M:%S %Z" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "जनवरी" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "फ़रवरी" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "मारà¥à¤š" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "अपà¥à¤°à¥‡à¤²" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "मई" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "जून" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "जनवरी" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "फ़रवरी" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "मारà¥à¤š" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "अपà¥à¤°à¥‡à¤²" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "मई" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "जून" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "सोमवार " + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "मंगलवार " + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "बà¥à¤§à¤µà¤¾à¤° " + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "गà¥à¤°à¥à¤µà¤¾à¤° " + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "शà¥à¤•à¥à¤°à¤µà¤¾à¤° " + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "शनिवार" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "रविवार " + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "सोम " + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "मंगल " + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "बà¥à¤§ " + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "गà¥à¤°à¥ " + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "शà¥à¤•à¥à¤° " + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "शनि" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "रवि " + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' केठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr " %lu बाइट आबंटित नहि कà¤à¤² जाठसकल फाइल \"%s\" केठपढ़ै हेतà¥" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "फाइल '%s' सठपढ़à¤à¤®à¥‡ असफल: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' फाइल खोलबामे असफल :%s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "फाइल '%s' क विशेषतासभ पता करबामे असफल: fstat() असफल: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "फाइल '%s': fdopen() खोलबामे असफल: %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "फाइल '%s' केठ'%s' मे नाम बदलठमे विफल: g_rename() विफल: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "फाइल '%s' बनाबैमे असफल: %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "फाइल '%s' केठलिखबाक लेल खोलबा मे विफल: fdopen() विफल: %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "'%s' फाइलकेठलिखबामे विफल: fwrite() विफल: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "'%s' फाइलकेठलिखबामे विफल: fwrite() विफल: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' फाइलकेठलिखबामे विफल: fwrite() विफल: %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "'%s' फाइल बनà¥à¤¨ करबामे विफल: fclose() विफल: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "'%s' मोजà¥à¤¦à¤¾ फाइल हटाà¤à¤² नहि जा सकैत अछि: g_unlink() विफल: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "टैमà¥à¤ªà¤²à¥‡à¤Ÿ '%s' अवैध अछि. à¤à¤¹à¤¿à¤®à¥‡ '%s' सामिल नहि अछि" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "टैमà¥à¤ªà¤²à¥‡à¤Ÿ '%s' मे XXXXXX समाहित नहि अछि" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f कि.बा." + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f मे.बा." + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f गी.बा." + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f कि.बा." + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f कि.बा." + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f कि.बा." + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f कि.बा." + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f मे.बा." + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f गी.बा." + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, fuzzy, c-format +msgid "%.1f TB" +msgstr "%.1f कि.बा." + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, fuzzy, c-format +msgid "%.1f PB" +msgstr "%.1f कि.बा." + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, fuzzy, c-format +msgid "%.1f EB" +msgstr "%.1f कि.बा." + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f कि.बा." + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "सिंबालिक लिंक '%s' सठथीम पढ़बामे असफल %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "सिंबालिक लिंक समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' सठ'%s' परिवरà¥à¤¤à¤• नहि खोलल जाठसकल: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "यहाठà¤à¤•टा रा रीड नहि कठसकैत g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "रीड बफर मे बचल अपरिवरà¥à¤¤à¤¿à¤¤ आà¤à¤•ड़ा" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "आंशिक अकà¥à¤·à¤° मे चैनल समापà¥à¤¤ होइछ" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "यहाठà¤à¤•टा रा रीड नहि कठसकैत - g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "फाइल '%s' खोलबामे असफल: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "'%s' फाइल चितà¥à¤°à¤¿à¤¤ करबामे विफल: mmap() विफल: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "पà¤à¤•à¥à¤¤à¤¿ %d पर तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' क' विशà¥à¤²à¥‡à¤·à¤£ करबामे असफल, जे अकà¥à¤·à¤° संदरà¥à¤­ क' भीतर à¤à¤•टा अà¤à¤• होनाइ चाही (उदाहरण " +"क लेल, ê) - साइत अà¤à¤• बेसी पैघ अछि" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"अकà¥à¤·à¤° संदरà¥à¤­ अरà¥à¤§à¤µà¤¿à¤°à¤¾à¤® चिनà¥à¤¹ क' सà¤à¤— समापà¥à¤¤ नहि होइछ. बेसी संभव अछि जे अहाठà¤à¤•टा à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड " +"अकà¥à¤·à¤° क' उपयोग कà¤à¤¨à¤ छी पर à¤à¤•टा à¤à¤‚टिटी केठपà¥à¤°à¤¾à¤°à¤‚भ कà¤à¤¨à¤¾à¤‡ नहि चाहैत छी - à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड केठ" +"à¤à¤¸à¥à¤•ेप करू à¤à¤¹à¤¿à¤¨à¤¾ &" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "संपà¥à¤°à¤¤à¥€à¤• संदरà¥à¤­ '%-.*s' à¤à¤•टा अनà¥à¤®à¤¤à¤¿ पà¥à¤°à¤¾à¤ªà¥à¤¤ संपà¥à¤°à¤¤à¥€à¤• केठà¤à¤¨à¤•ोड नहि करैत अछि" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "रिकà¥à¤¤ à¤à¤‚टिटी '&;' देखलक; वैध à¤à¤‚टिटी अछि: & " < > '" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "à¤à¤‚टिटी नाम '%s' जà¥à¤žà¤¾à¤¤ नहि अछि" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"à¤à¤‚टिटी अरà¥à¤§à¤µà¤¿à¤°à¤¾à¤® पर समापà¥à¤¤ नहि होइछ, बेसी संभव अछि जे अहाठà¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤¨à¥à¤¡ अकà¥à¤·à¤° क' पà¥à¤°à¤¯à¥‹à¤— " +"कà¤à¤¨à¤ छी आओर à¤à¤•टा à¤à¤‚टिटी पà¥à¤°à¤¾à¤°à¤‚भ नहि कà¤à¤¨à¤¾à¤‡ चाहैत छी- à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड केठà¤à¤¹à¤¿à¤¨à¤¾ à¤à¤¸à¥à¤•ेप करू: &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ à¤à¤•टा अवयव क' नामसठपà¥à¤°à¤¾à¤°à¤‚भ होनाइ चाही (उदाहरण क' लेल- <पà¥à¤¸à¥à¤¤à¤•>)" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "< क' पशà¥à¤šà¤¾à¤¤ आबल '%s' à¤à¤•टा वैध वरà¥à¤£ नहि अछि. ई अवयव नामसठपà¥à¤°à¤¾à¤°à¤‚भ नहि होइछ" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "विषम अकà¥à¤·à¤° '%s', पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ अछि à¤à¤•टा '=' लकà¥à¤·à¤£ नाम '%s' अवयव '%s' क' पशà¥à¤šà¤¾à¤¤" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"'%s' विसम संपà¥à¤°à¤¤à¥€à¤•, à¤à¤•टा '>' अथवा '/' संपà¥à¤°à¤¤à¥€à¤• केठ'%s' ततà¥à¤µ क' आरंभ टैग केठखतà¥à¤® कà¤à¤¨à¤¾à¤‡ " +"पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤, अथवा विकलà¥à¤ªà¤¤à¤ƒ à¤à¤•टा गà¥à¤£; साइत अहाठगà¥à¤£ नाममे à¤à¤•टा अमानà¥à¤¯ संपà¥à¤°à¤¤à¥€à¤• क' पà¥à¤°à¤¯à¥‹à¤— " +"कà¤à¤¨à¤ छी" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"पà¥à¤°à¤¾à¤¨ अकà¥à¤·à¤° '%s', जखन विशेषता '%s', अवयव '%s' क' मान देल जाइत अछि तठबराबर चिहà¥à¤¨à¤• " +"बाद à¤à¤•टा खà¥à¤²à¤² कोट चिहà¥à¤¨ वांछित अछि" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' à¤à¤•टा वैध अकà¥à¤·à¤° नहि अछि कà¥à¤²à¥‹à¤œà¤¼ अवयव नाम '%s' क' बाद; सà¥à¤µà¥€à¤•ारà¥à¤¯ अकà¥à¤·à¤° अछि '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "अवयव '%s' बनà¥à¤¦ छला, कोनो अवयव वरà¥à¤¤à¤®à¤¾à¤¨à¤®à¥‡ खà¥à¤²à¤² नहि अछि" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ '%s' बनà¥à¤¦ छला, मà¥à¤¦à¤¾ वरà¥à¤¤à¤®à¤¾à¤¨ खà¥à¤²à¤² अवयव अछि '%s'" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ खाली छला अथवा ओकरामे सिरà¥à¤« शà¥à¤µà¥‡à¤¤ रिकà¥à¤¤à¤¿ छला" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप सठà¤à¤•टा खà¥à¤²à¤² à¤à¤‚गल बà¥à¤°à¥‡à¤•ेट '<' क' पशà¥à¤šà¤¾à¤¤à¥‡ भ' गेल" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप सठअवयवसभ क' खà¥à¤²à¤² हठपर भ' गेल - '%s' अंतिम खà¥à¤²à¤² अवयव " +"छला" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप सठभ' गेल, वांछित छला देखनाइ टैगकेठबनà¥à¤¦ करैत à¤à¤•टा कà¥à¤²à¥‹à¤œ à¤à¤‚गल " +"बà¥à¤°à¥‡à¤•ेट <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपसठअवयव नाम क' भीतर भ' गेल" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूप सठविशेषता नाम क' भीतर भ' गेल" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपसठअवयव-खोलबाक टैगक भीतर भ' गेल." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपसठबराबर क' चिहà¥à¤¨ क' बाद à¤à¤•टा विशेषता नाम क' पशà¥à¤šà¤¾à¤¤ भ' " +"गेल; कोनो विशेषता मान नहि" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपसठविशेषता मान क' भीतर भ' गेल" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपसठअवयव '%s' लेल बनà¥à¤¦ टैग क' भीतर भ' गेल" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "दसà¥à¤¤à¤¾à¤¬à¥‡à¤œ क' अंत अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपसठटिपà¥à¤ªà¤£à¥€ अथवा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ निरà¥à¤¦à¥‡à¤¶ क' भीतर भ' गेल" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿à¤• बाहर" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "नियमित अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ बहà¥à¤¤ पैघ अछि" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ पाबैमे विफल" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "assertion expected after (?(" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "असंगत NEWLINE विकलà¥à¤ª" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¸à¤¿à¤¤ दोहराà¤à¤²" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "कोड ओवरफà¥à¤²à¥‹" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "हेकà¥à¤¸à¤¾à¤¡à¥‡à¤¸à¥€à¤®à¤² अंक या '}' पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "हेकà¥à¤¸à¤¾à¤¡à¥‡à¤¸à¥€à¤®à¤² अंक पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "नहि समापà¥à¤¤ भेल सांकेतिक संदरà¥à¤­" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "शूनà¥à¤¯ नमाइ सांकेतिक संदरà¥à¤­" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "अंक पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "अमानà¥à¤¯ सांकेतिक संदरà¥à¤­" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "stray final '\\'" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "कोटेड पाठ कोटेशन चिहà¥à¤¨ क' सà¤à¤— पà¥à¤°à¤¾à¤°à¤‚भ नहि होइछ" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "कमाà¤à¤¡ पंकà¥à¤¤à¤¿à¤®à¥‡ मेल नहि खाà¤à¤¤ उदà¥à¤§à¤°à¤£ चिहà¥à¤¨ अथवा आन शैल-कोटेड पाठ" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "पाठ क' अंत सिरà¥à¤« '\\' अकà¥à¤·à¤° क' बाद भ' गेल. (पाठ छला '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr " %c लेल मैचिंग कोट सठपहिने पाठ अंत पà¤à¤²à¤•. (पाठ छला '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "पाठ रिकà¥à¤¤ छला (अथवा ओकरामे सिरà¥à¤« शà¥à¤µà¥‡à¤¤ रिकà¥à¤¤à¤¿ छला)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾à¤¸à¤ आà¤à¤•ड़ा पढ़बामे असफल" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) सठसंचारण लेल पाइप बनाबैमे असफल" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "चाइलà¥à¤¡ पाइप (%s) सठपढ़बामे असफल" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' (%s) पर बदलबामे असफल" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करबामे असफल" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "अवैध पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® नाम: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d पर तरà¥à¤• सदिशमे अवैध सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "वातावरणमे अवैध सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "अवैध कारà¥à¤¯à¤¶à¥€à¤² निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "हेलà¥à¤ªà¤° पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करबामे असफल" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"à¤à¤•टा शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ सठआà¤à¤•ड़ा पढ़बामे g_io_channel_win32_poll() मे अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) सठआà¤à¤•ड़ा पढ़बामे असफल" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "à¤à¤•टा चाइलà¥à¤¡ पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) सठचà¥à¤¨à¥‡à¤‚() पढ़बाक आà¤à¤•ड़ामे अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() (%s) मे अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) फोरà¥à¤• करबामे असफल" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ \"%s\" (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करबामे असफल" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "आउटपà¥à¤Ÿ अथवा शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) क' इनपà¥à¤Ÿ केठअनà¥à¤ªà¥à¤°à¥‡à¤·à¤¿à¤¤ करब मे असफल" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) फॉरà¥à¤• करब मे असफल" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "शिशॠपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ \"%s\" कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करबामे अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "शिशॠपीआईडी पाइप (%s) सठपरà¥à¤¯à¤¾à¤ªà¥à¤¤ आà¤à¤•ड़ा पढ़बामे असफल" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "यूटीà¤à¤«-8 लेल अकà¥à¤·à¤° सीमासठबाहर" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "परिवरà¥à¤¤à¤¨ इनपà¥à¤Ÿà¤®à¥‡ अवैध अनà¥à¤•à¥à¤°à¤®" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "यूटीà¤à¤«-16 लेल अकà¥à¤·à¤° सीमासठबाहर" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "पà¥à¤°à¤¯à¥‹à¤—:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[विकलà¥à¤ª...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "मदà¥à¤¦à¤¤à¤¿ विकलà¥à¤ª:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "मदà¥à¤¦à¤¤à¤¿ विकलà¥à¤ª देखाबू" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "सभटा मदà¥à¤¦à¤¤à¤¿ विकलà¥à¤ª देखाबू" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— विकलà¥à¤ª:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "पूरà¥à¤£à¤¾à¤‚क मान '%s' केठ%s क' लेल विशà¥à¤²à¥‡à¤·à¤£ नहि कठसकैत अछि" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "पूरà¥à¤£à¤¾à¤‚क मान '%s' %s क' लेल रेंज क' बाहर अछि" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "'%s' दोहराà¤à¤² मान क' विशà¥à¤²à¥‡à¤·à¤£ %s क' लेल नहि कठसकैत अछि" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "'%s' दोहराà¤à¤² मान %s क' लेल परिसरसठबाहर अछि" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "%s विकलà¥à¤ª विशà¥à¤²à¥‡à¤·à¤£à¤®à¥‡ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "%s क' लेल गà¥à¤® तरà¥à¤•" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "अनजान विकलà¥à¤ª %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "à¤à¤•टा सामानà¥à¤¯ फाइल नहि" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "फाइल खाली अछि" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"कà¥à¤‚जी फाइलमे '%s' पंकà¥à¤¤à¤¿ समाहित अछि जे à¤à¤•टा कà¥à¤à¤œà¥€ मान जोड़ा, समूह, अथवा टिपà¥à¤ªà¤£à¥€ नहि अछि" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "अवैध समूह नाम: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "कà¥à¤‚जी फाइल à¤à¤•टा समूहक सà¤à¤— शà¥à¤°à¥‚ नहि होइछ" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "अवैध कà¥à¤à¤œà¥€ नाम: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "कà¥à¤à¤œà¥€ फाइल मे असमरà¥à¤¥à¤¿à¤¤ à¤à¤¨à¤•ोडिंग '%s' समाहित अछि" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "कà¥à¤à¤œà¥€ फाइल मे '%s' समूह नहि अछि" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "कà¥à¤à¤œà¥€ फाइलमे '%s' कà¥à¤à¤œà¥€ नहि अछि" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "कà¥à¤à¤œà¥€ फाइलमे '%s' कà¥à¤à¤œà¥€ समाहित अछि '%s' मान क' सà¤à¤— जे UTF-8 नहि अछि" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "कà¥à¤à¤œà¥€ फाइलमे '%s' कà¥à¤à¤œà¥€ अछि जकरा मान क' विशà¥à¤²à¥‡à¤·à¤£ नहि कà¤à¤² जाठसकैत अछि." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "कà¥à¤à¤œà¥€ फाइलमे '%s' कà¥à¤à¤œà¥€ अछि जकरा मान क' विशà¥à¤²à¥‡à¤·à¤£ नहि कà¤à¤² जाठसकैत अछि." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"कà¥à¤à¤œà¥€ फाइलमे '%s' कà¥à¤à¤œà¥€ अछि '%s' समूह मे जकर मान क' विशà¥à¤²à¥‡à¤·à¤£ नहि कà¤à¤² जाठसकैत अछि." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "कà¥à¤à¤œà¥€ फाइलमे '%s' कà¥à¤à¤œà¥€ नहि अछि '%s' समूहमे" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "कà¥à¤à¤œà¥€ फाइलमे पà¤à¤•à¥à¤¤à¤¿ क' अंतमे à¤à¤¸à¥à¤•ेप संपà¥à¤°à¤¤à¥€à¤• रहैत अछि" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "कà¥à¤à¤œà¥€ फाइल मे '%s' अमानà¥à¤¯ शà¥à¤°à¥ƒà¤‚खला समाहित अछि" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "मान '%s' केठà¤à¤•टा सà¤à¤–à¥à¤¯à¤¾à¤• तरह नहि विशà¥à¤²à¥‡à¤·à¤¿à¤¤ कà¤à¤² जाठसकैत अछि." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "पूरà¥à¤£à¤¾à¤‚क मान '%s' रेंज क' बाहर अछि" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "मान '%s' केठà¤à¤•टा फà¥à¤²à¥‹à¤Ÿ सà¤à¤–à¥à¤¯à¤¾à¤• तरह नहि विशà¥à¤²à¥‡à¤·à¤¿à¤¤ कà¤à¤² जाठसकैत अछि." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "मान '%s' केठबà¥à¤²à¤¿à¤¯à¤¨ क' तौर पर विशà¥à¤²à¥‡à¤·à¤¿à¤¤ नहि कà¤à¤² जाठसकैत अछि." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Too large count value passed to %s" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤¨ पहिनेसठबनà¥à¤¨ अछि" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "ऑपरेशन रदà¥à¤¦ छल" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "परिवरà¥à¤¤à¤¨ इनपà¥à¤Ÿà¤®à¥‡ अवैध बाइट अनà¥à¤•à¥à¤°à¤®" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "ऑपरेशन समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "अजà¥à¤žà¤¾à¤¤ पà¥à¤°à¤•ार" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s फाइल पà¥à¤°à¤•ार" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s पà¥à¤°à¤•ार" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "फाइलकेठकाटबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "'%s' फाइल खोलबमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "'%s' फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "'%s' फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "फाइलमे लिखबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "'%s' फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "अजà¥à¤žà¤¾à¤¤ पà¥à¤°à¤•ार" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' केठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा बनाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "'%s' फाइल खोलबमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "'%s' फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "'%s' फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "फाइल बनà¥à¤¨ करबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "'%s' फाइल खोलबमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "'%s' फाइल खोलबमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "Enumerator is closed" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, fuzzy, c-format +msgid "Property '%s' is not readable" +msgstr "पà¥à¤°à¤•ार %s वरà¥à¤—ीकृत नहि अछि" + +#: ../gio/gdbusconnection.c:3959 +#, fuzzy, c-format +msgid "Property '%s' is not writable" +msgstr "पà¥à¤°à¤•ार %s वरà¥à¤—ीकृत नहि अछि" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤¨ पहिनेसठबनà¥à¤¨ अछि" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "फाइलमे लिखबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "ऑपरेशन समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "फाइलमे लिखबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "पà¤à¤•à¥à¤¤à¤¿ %d पर तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "%s विकलà¥à¤ª विशà¥à¤²à¥‡à¤·à¤£à¤®à¥‡ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "फाइलकेठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "अकà¥à¤·à¤° '%s' à¤à¤•टा à¤à¤‚टिटी नाम क' भीतर वैध नहि अछि" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "अकà¥à¤·à¤° '%s' à¤à¤•टा à¤à¤‚टिटी नाम क' भीतर वैध नहि अछि" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "अकà¥à¤·à¤° '%s' à¤à¤•टा à¤à¤‚टिटी नाम क' भीतर वैध नहि अछि" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%s विकलà¥à¤ª विशà¥à¤²à¥‡à¤·à¤£à¤®à¥‡ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "परिवरà¥à¤¤à¤¨à¤• दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा '%s' केठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "बेनाम" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "पà¥à¤°à¤¯à¥‹à¤•à¥à¤¤à¤¾ डेसà¥à¤•टाप फाइल %s नहि बनाठसकैत अछि" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "%s कठलेल पसंदीदा परिभाषित" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +#, fuzzy +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "आवाज माउंटकेठलागू नहि करैत अछि" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +#, fuzzy +msgid "drive doesn't implement start" +msgstr "आवाज माउंटकेठलागू नहि करैत अछि" + +#: ../gio/gdrive.c:831 +#, fuzzy +msgid "drive doesn't implement stop" +msgstr "आवाज माउंटकेठलागू नहि करैत अछि" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblem पà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ GEmblemedIcon केठलेल" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "ऑपरेशन समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "माउंट नहि समाहित मोजà¥à¤¦ नहि अछि" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पर कापी नहि कठसकैत अछि" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ाकेठउपà¥à¤ªà¤° निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा कापी नहि कठसकैत अछि" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "लकà¥à¤·à¤¿à¤¤ फाइल मोजà¥à¤¦ अछि" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ाकेठबेरबेर सठनहि कापी कठसकैछ" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "सिंबालिक लिंक समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "फाइलकेठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "विशेष फाइलकेठकापी नहि कठसकल" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "फाइल नाम मे '%c' नहि रहि सकैत अछि" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "आवाज माउंटकेठलागू नहि करैत अछि" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "कोनो अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— ई फाइलकेठनियंतà¥à¤°à¤£à¤•ेठलेल पंजीकृत नहि अछि" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "Enumerator is closed" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "File enumerator has outstanding operation" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon à¤à¤¨à¥à¤•ोडिंगकेठ%d संसà¥à¤•रणकेठनियंतà¥à¤°à¤¿à¤¤ नहि कठसकैत अछि" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon केठलेल विरूपित इनपà¥à¤Ÿ डेटा" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "पà¥à¤°à¤•ार %s वरà¥à¤—ीकृत नहि अछि" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "विरूपित संसà¥à¤•रण संखà¥à¤¯à¤¾: %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤®à¤•ेठसंग बचल आपरेशन अछि" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "ऑपरेशन समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, fuzzy, c-format +msgid "invalid GVariant type string '%s'" +msgstr "अमानà¥à¤¯ गà¥à¤£ पà¥à¤°à¤•ार (string expected)" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "अवैध फाइलनाम %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "फाइलसिसà¥à¤Ÿà¤® सूचना पाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "रूट निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ाकेठनाम नहि बदलि सकल" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "फाइलक फेर नाम देबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "फाइलकेठफेर नाम नहि बदलि सकैत छी, फाइलनाम पहिनेसठमोजà¥à¤¦ अछि" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "अवैध फाइलनाम" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "फाइलकेठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा नहि खोलि सकैछ" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "फाइल हटाबै मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "फाइलकेठरदà¥à¤¦à¥€à¤®à¥‡ भेजबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "टà¥à¤°à¥ˆà¤¶ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा %s बनाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "टà¥à¤°à¥ˆà¤¶à¤• लेल उचà¥à¤š सà¥à¤¤à¤°à¥€à¤¯ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा ताकबामे असमरà¥à¤¥" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "टà¥à¤°à¥‡à¤¶ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा बनाबैमे या ताकबामे असमरà¥à¤¥" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "टà¥à¤°à¥‡à¤¶à¤¿à¤‚ग सूचनाकेठफाइलमे बनाबैमे असमरà¥à¤¥: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "फाइलकेठरदà¥à¤¦à¥€à¤®à¥‡ भेजबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा बनाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "सिंबालिक लिंक '%s' सठथीम पढ़बामे असफल %s" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "सिंबलिंक बनाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "फाइल घà¥à¤¸à¤•ाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पर निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा नहि घà¥à¤¸à¤•ाठसकैछ" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "बैकअप फाइल निरà¥à¤®à¤¾à¤£ विफल" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "लकà¥à¤·à¤¿à¤¤ फाइल हटाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "माउंटकेठबीच चलनाइ समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "गà¥à¤£à¤•ेठजरूर गैर-NULL होबा चाही" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "अमानà¥à¤¯ गà¥à¤£ पà¥à¤°à¤•ार (string expected)" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "अमानà¥à¤¯ विसà¥à¤¤à¤¾à¤°à¤¿à¤¤ गà¥à¤£ नाम" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "विसà¥à¤¤à¤¾à¤°à¤¿à¤¤ गà¥à¤£ '%s' सेटिंगमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "'%s' फाइल बताबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (अमानà¥à¤¯ à¤à¤¨à¥à¤•ोडिंग)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "फाइल विवरण कथित करने मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "अमानà¥à¤¯ गà¥à¤£ पà¥à¤°à¤•ार (uint32 expected)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "अमानà¥à¤¯ गà¥à¤£ पà¥à¤°à¤•ार (uint64 expected)" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "अमानà¥à¤¯ गà¥à¤£ पà¥à¤°à¤•ार (byte string expected)" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "अनà¥à¤®à¤¤à¤¿ सेटिंग मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "अनà¥à¤®à¤¤à¤¿ सेटिंग मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "सà¥à¤µà¤¾à¤®à¥€ सेटिंग मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "symlink जरूर गैर-NULL होबा चाही" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "symlink सेटिंग मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "symlink सेटिंग मे तà¥à¤°à¥à¤Ÿà¤¿: फाइल à¤à¤•टा symlink नहि अछि" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "अनà¥à¤®à¤¤à¤¿ सेटिंग मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "SELinux संदरà¥à¤­ गैर-NULL होबा चाही" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux संदरà¥à¤­ सेट करबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "SELinux ई सिसà¥à¤Ÿà¤® पर सकà¥à¤°à¤¿à¤¯ नहि अछि" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "सेटिंग गà¥à¤£ %s समरà¥à¤¥à¤¿à¤¤ नहि" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "फाइल पढबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "फाइल खोजबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "फाइल बनà¥à¤¨ करबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ सà¥à¤¥à¤¾à¤¨à¥€à¤¯ फाइल मानिटरक पà¥à¤°à¤•ार तकबामे असमरà¥à¤¥" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "फाइलमे लिखबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "पà¥à¤°à¤¾à¤¨ बैकअप लिंक हटाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "बैकअप कापी बनाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "असà¥à¤¥à¤¾à¤ˆ फाइलकेठनाम देबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "फाइलकेठकाटबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "'%s' फाइल खोलबमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "लकà¥à¤·à¤¿à¤¤ फाइल निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा अछि" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "लकà¥à¤·à¤¿à¤¤ फाइल à¤à¤•टा नियमित फाइल नहि अछि" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "फाइल बाहरी रूपेठबदलल अछि" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "पà¥à¤°à¤¾à¤¨ फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "अमानà¥à¤¯ GSeekType कठआपूरà¥à¤¤à¤¿" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "अमानà¥à¤¯ पà¥à¤°à¤¾à¤ªà¥à¤¤à¤¿ आगà¥à¤°à¤¹" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream केठकाटि नहि सकल" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ आउटपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤®à¤•ेठफेर आकार देनाइ संभव नहि" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ आउटपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤®à¤•ेठफेर आकार देनाइ विफल" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +#, fuzzy +msgid "mount doesn't implement \"unmount\"" +msgstr "माउंट अनमाउंट लागू नहि करैछ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +#, fuzzy +msgid "mount doesn't implement \"eject\"" +msgstr "माउंट बाहर निकालब लागू नहि करैछ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +#, fuzzy +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "माउंट अनमाउंट लागू नहि करैछ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +#, fuzzy +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "माउंट बाहर निकालब लागू नहि करैछ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +#, fuzzy +msgid "mount doesn't implement \"remount\"" +msgstr "माउंट फेर माउंट लागू नहि करैछ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "माउंट कंटेंट पà¥à¤°à¤•ार गेसिंगकेठलागू नहि करैछ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "माउंट तà¥à¤²à¥à¤¯à¤•ालित कंटेंट पà¥à¤°à¤•ार गेसिंगकेठलागू नहि करैछ" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "आउटपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤® लेखन केठलागू नहि करैछ" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "सà¥à¤°à¥‹à¤¤ सà¥à¤Ÿà¥à¤°à¥€à¤® पहिनेसठबनà¥à¤¨ अछि" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' फाइल केठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "फाइल हटाबै मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "अनजान विकलà¥à¤ª %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +#, fuzzy +msgid "Socket is already closed" +msgstr "सà¥à¤°à¥‹à¤¤ सà¥à¤Ÿà¥à¤°à¥€à¤® पहिनेसठबनà¥à¤¨ अछि" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "फाइल पढबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "टà¥à¤°à¥ˆà¤¶ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा %s बनाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "फाइलमे लिखबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "परिवरà¥à¤¤à¤¨à¤• दौरान तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "फाइलकेठकाटबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "फाइलकेठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "फाइलकेठरदà¥à¤¦à¥€à¤®à¥‡ भेजबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "फाइल हटाबै मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "फाइलकेठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "टà¥à¤°à¥ˆà¤¶ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा %s बनाबैमे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "फाइल बनà¥à¤¨ करबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "फाइलकेठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:3081 +#, fuzzy +msgid "GSocketControlMessage not supported on windows" +msgstr "संयोजन परिवरà¥à¤¤à¤¨ win32 पर समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "फाइल हटाबै मे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +#, fuzzy +msgid "Unknown error on connect" +msgstr "अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "पà¥à¤°à¤•ार %s वरà¥à¤—ीकृत नहि अछि" + +#: ../gio/gsocketlistener.c:191 +#, fuzzy +msgid "Listener is already closed" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤¨ पहिनेसठबनà¥à¤¨ अछि" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "%d संसà¥à¤•रण GThemedIcon à¤à¤¨à¥à¤•ोडिंगकेठनियंतà¥à¤°à¤¿à¤¤ नहि कठसकल" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "फाइलकेठखोलबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "फाइलक फेर नाम देबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "unix सठपढ़बामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "unix केठबनà¥à¤¨ करबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "फाइल सिसà¥à¤Ÿà¤® रूट" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "unix मे लिखबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "आवाज बाहर निकालबकेठलागू नहि करैछ" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +#, fuzzy +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "आवाज बाहर निकालबकेठलागू नहि करैछ" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— नहि पाबि सकल" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— लानà¥à¤š करबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "URI समरà¥à¤¥à¤¿à¤¤ नहि" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "संयोजन परिवरà¥à¤¤à¤¨ win32 पर समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "संयोजन निरà¥à¤®à¤¾à¤£ win32 पर समरà¥à¤¥à¤¿à¤¤ नहि अछि" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "फाइल पढबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "फाइल बनà¥à¤¨ करबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "फाइलमे लिखबामे तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿à¤• बाहर" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "अवैध होसà¥à¤Ÿ-नाम" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पर निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा नहि घà¥à¤¸à¤•ाठसकैछ" + +#, fuzzy +#~ msgid "Key %s is not writable\n" +#~ msgstr "पà¥à¤°à¤•ार %s वरà¥à¤—ीकृत नहि अछि" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "परिवरà¥à¤¤à¤¨ इनपà¥à¤Ÿà¤®à¥‡ अवैध अनà¥à¤•à¥à¤°à¤®" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "अधिकतम आंकड़ा सरणी सीमा तकि पहà¥à¤à¤šà¤¿ गेल" + +#~ msgid "do not hide entries" +#~ msgstr "पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¤¿ नहि नà¥à¤•ाउ" + +#~ msgid "use a long listing format" +#~ msgstr "नमहर सूची पà¥à¤°à¤¾à¤°à¥‚पक पà¥à¤°à¤¯à¥‹à¤— करू" + +#~ msgid "[FILE...]" +#~ msgstr "[फाइल...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "à¤à¤•टा à¤à¤‚टिटी क' पà¥à¤°à¤¾à¤°à¤‚भमे अकà¥à¤·à¤° '%s' वैध नहि अछि आओर & अकà¥à¤·à¤° à¤à¤•टा à¤à¤‚टिटीकेठपà¥à¤°à¤¾à¤°à¤‚भ " +#~ "करैत अछि. जठई à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड à¤à¤•टा à¤à¤‚टिटी नहि अछि तठà¤à¤•रा à¤à¤¹à¤¿à¤¨à¤¾ à¤à¤¸à¥à¤•ेप करू &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "रिकà¥à¤¤ अकà¥à¤·à¤° संदरà¥à¤­, अà¤à¤• जहिना dž समà¥à¤®à¤¿à¤²à¤¿à¤¤ अवशà¥à¤¯ होà¤à¤¬à¤¾à¤• चाही;" + +#~ msgid "Unfinished entity reference" +#~ msgstr "अपूरà¥à¤£ à¤à¤‚टिटी संदरà¥à¤­" + +#~ msgid "Unfinished character reference" +#~ msgstr "अपूरà¥à¤£ अकà¥à¤·à¤° संदरà¥à¤­" + +#~ msgid "file" +#~ msgstr "फाइल" + +#~ msgid "The file containing the icon" +#~ msgstr "फाइल जे पà¥à¤°à¤¤à¥€à¤• राखने अछि" + +#~ msgid "name" +#~ msgstr "नाम" + +#~ msgid "The name of the icon" +#~ msgstr "पà¥à¤°à¤¤à¥€à¤• कठनाम" + +#~ msgid "names" +#~ msgstr "नाम" + +#~ msgid "An array containing the icon names" +#~ msgstr "पà¥à¤°à¤¤à¥€à¤• नामक संग सरणी" + +#~ msgid "use default fallbacks" +#~ msgstr "पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ फालबैक पà¥à¤°à¤¯à¥‹à¤— करू" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." + +#~ msgid "File descriptor" +#~ msgstr "फाइल विवरक" + +#~ msgid "The file descriptor to read from" +#~ msgstr "फाइल विवरक जकरासठपढ़नाइ अछि" + +#~ msgid "Close file descriptor" +#~ msgstr "फाइल विवरक बनà¥à¤¨ करू" + +#~ msgid "Whether to close the file descriptor when the stream is closed" +#~ msgstr "फाइल विवरक केठबनà¥à¤¨ कà¤à¤¨à¤¾à¤‡ अछि जखन सà¥à¤Ÿà¥à¤°à¥€à¤® बनà¥à¤¨ अछि" + +#~ msgid "The file descriptor to write to" +#~ msgstr "फाइल विवरक जकरामे लिखनाइ अछि" diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 0000000..9fab018 --- /dev/null +++ b/po/meson.build @@ -0,0 +1,5 @@ +i18n = import('i18n') + +i18n.gettext('glib20', preset: 'glib') + +install_data('Makefile.in.in', install_dir : glib_pkgdatadir + '/gettext/po') diff --git a/po/mg.po b/po/mg.po new file mode 100644 index 0000000..2132316 --- /dev/null +++ b/po/mg.po @@ -0,0 +1,3845 @@ +# MALAGASY TRANSLATION OF GLIB. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Thierry Randrianiriana , 2007. +msgid "" +msgstr "" +"Project-Id-Version: GLIB VERSION\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2007-03-03 19:00+0300\n" +"Last-Translator: Fanomezana Rajaonarisoa \n" +"Language-Team: MALAGASY \n" +"Language: mg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Marika manokana '%s' ho an'ny '%s' tsy nampoizina" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Tsy hita ny marika manokana '%s' ho an'ny '%s'" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Tsy nampoizina ny taf '%s', nantenaina ny tag '%s'" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Misy tag '%s' tsy nampoizina anatin'ny '%s'" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "Tsy misy raki-drohy mitombina anatin'ny lahatahiry misy ny data" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Efa misy rohy ny URI '%s'" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Tsy nahitana rohy ny URI '%s'" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Tsy misy karazana MIME voafaritra ho an'ny rohin'ny URI '%s'" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Tsy misy saina manokana voafaritra ho an'ny rohin'ny URI '%s'" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Tsy misy vondrona voafaritra ho an'ny rohin'ny URI '%s'" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" +"Tsy misy rindranasa mitondra ny anarana '%s' nanambara rohy ho an'ny '%s'" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Tsy voavaky ny rohy misolotena '%s': %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Tsy raisina an-tànana ny famadihan'amboara-marika '%s' ho '%s'" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Tsy voasokatra ny mpanova rakitra '%s' ho '%s'" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Tsy mitombina filaharan'ny byte amin'ny zavatra ovaina" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Nisy olana teo am-panovana: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Tsy feno ny filaharan'ny marika amin'ny faran'ny zavatra ovaina" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Ny fallback '%s' tsy voaova ho amboaram-pango '%s'" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "Tsy URI feno mampiasa ny drafitra \"rakitra\" ny URI '%s'" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "Tsy azo asiana '#' ny URI '%s' an'ilay rakitra an-toerana " + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "Tsy mitombina ny URI '%s'" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Tsy mitombina ny anaram-mpampiantranon'ny URI '%s'" + +#: ../glib/gconvert.c:1941 +#, fuzzy, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "Misy marika nalana tamin'ny fomba tsy mety ny URI '%s'" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Tsy sori-dàlana feno ny anaran-tsori-dàlana '%s'" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Anaram-pampiantrano diso" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "janoary" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "febroary" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "martsa" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "aprily" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "mey" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "jona" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "jolay" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "jan" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "apr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "mey" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jon" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jol" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "alatsinainy" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "talata" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "alarobia" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "alakamisy" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "zoma" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sabotsy" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "alahady" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "lts" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "tlt" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "lrb" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "lkm" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "zom" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sab" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "lhd" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Nisy olana teo am-panokafana ny lahatahiry '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Tsy nahatokana %lu byte hamakiana ny rakitra \"%s\"" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Ny nahavaky ny mpiatin'ny rakitra '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Tsy voasokatran y rakitra '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Tsy azo ny marika manokan'ny rakitra '%s': tsy nahomby ny fstat(): %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Tsy voasokatra ny rakitra '%s': tsy nahomby ny fdopen(): %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"Tsy voaova ny anaran'ny rakitra '%s' mba ho '%s': tsy nahomby ny g_rename(): " +"%s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Tsy voaforona ny rakitra '%s': %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" +"Tsy voasotra mba hanoratana ny rakitra '%s': tsy nahomby ny fdopen(): %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Tsy voasoratra ny rakitra '%s': tsy nahomby ny fwrite(): %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Tsy voasoratra ny rakitra '%s': tsy nahomby ny fwrite(): %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Tsy voasoratra ny rakitra '%s': tsy nahomby ny fwrite(): %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Tsy voahidy ny rakitra '%s': tsy nahomby ny fclose(): %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "Tsy mety fafàna ny rakitra '%s' misy: tsy nahomby ny g_unlink(): %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Tsy mitombina ny lasitra '%s'; tsy tokony hisy '%s'" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Tsy misy XXXXXX ny lasitra '%s'" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Tsy voavaky ny rohy misolotena '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Tsy voasokatra ny mpanova rakitra '%s' ho '%s': %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" +"Tsy afaka manao famakiana fototra amin'ny g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Misy ambina data tsy voaova ao anatin'ny buffern'ny famakiana" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Marika tsy feno no mamarana ilay canal" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Tsy afaka manao famakiana fototra amin'ny g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Tsy voasokatra ny rakitra '%s': tsy nahomby ny open(): %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Tsy voamap ny rakitra '%s': tsy nahomby ny mmap(): %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "Misy tsy fetezana amin'ny andalana %d marika %d: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Lahabolana voafango UTF-8 tsy mitombina" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Misy tsy fetezana amin'ny andalana %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Tsy voazarazara ny '%-.*s' izay tokony ho isa anaty fiantsoana marika " +"(ê, ohatra). Mety lehibe loatra angamba ilay isa." + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Tsy niafara tamin'ny teboka amam-paingo ilay fiantsoana marika. Mety tsy " +"nihevitra hampiasa esperluette hanombohana ary angamba ianao - esperluette " +"fialana toy ny &" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Tsy manafango marika azo ampiasaina ny fiantsoana marika '%-.*s'" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Nahita ary '&;' foana; ireto no fidirana ekena: & " < > '" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Tsy fantatra ny anaran'ary '%s'" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Tsy nifarana tamin'ny teboka amam-paingo ilay ary. Mety tsy nihevitra " +"hampiasa esperluette hanombohana ary angamba ianao - esperluette fialana toy " +"ny &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "" +"Tsy maintsy manomboka amina singantaharo ilay tahirin-kevitra (oh. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"Tsy mety atao aorian'ny marika '<' ny marika '%s'. Tsy mety anombohana " +"anaran-tsingataharo io" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Marika '%s' hafahafa; nanantena marika '>' hamarana ny tag manomboka ny " +"singantaharo '%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Marika '%s' hafahafa; nanantena '=' aorian'ny anaran'ny marika manokana '%s' " +"amin'ny singantaharo '%s'" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Marika hafahafa '%s'; nanantena marika '>' na '/' hamarana ny tag manomboka " +"ny singantaharo '%s', na koa marika manokana iray. Mety nampiasa marika tsy " +"ekena amin'ny anarana marika manokana angamba ianao." + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Marika '%s' hafahafa; nanantena farango manokatra aorian'ny mira rehefa " +"manome ny sanda ny marika manokana '%s' amin'ny singantaharo '%s'" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' dia tsy mety atao aorian'ny anaran'ny singantaharo mamarana ny marika " +"'%s'. '>' no marika mety atao eo" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Nofaranana ny singantaharo '%s'; tsy misy singantaharo misokatra izao" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"Nofaranana ny singantaharo '%s', fa '%s' no singantaharo misokatra izao" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Foana na tsy misy afa-tsy elanelana ilay tahirin-kevitra" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Nifarana tampoka taoriana fonon-teny kitso loha '<' ilay tahirin-kevitra" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Nifarana tampoka ilay tahirin-kevitra nefa misy singantaharo mbola " +"misokatra; '%s' no singantaharo farany nisokatra" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Nifarana tampoka ilay singantaharo; nanantena fonon-teny kitso loha mamarana " +"ny tag <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Nifarana tampoka tanaty anaran-tsingataharo ilay tahirin-kevitra" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Nifarana tampoka tanaty anarana marika manokana ilay tahirin-kevitra" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Nifarana tampoka tanaty tag manomboka singantaharo ilay tahirin-kevitra." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Nifarana tampoka taorian'ny mira manaraka anarana marika manokana ilay " +"tahirin-kevitra; tsy misy sanda-marika manokana" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"Nifarana tampoka ilay tahirin-kevitra raha mbola tanaty sanda-marika manokana" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"Nifarana tampoka tanatin'ny tag mamarana ny singantaharo '%s' ilay tahirin-" +"kevitra" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Nifarana tampoka tanaty teny fanampiny na torolàlana fikirakirana ilay " +"tahirin-kevitra" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "Marika tsy feno no mamarana ilay canal" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "Tsy mitombina filaharan'ny byte amin'ny zavatra ovaina" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "Fiantsoana marika tsy vita" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "Fiantsoana marika tsy vita" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "Fiantsoana marika tsy vita" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Misy tsy fetezana amin'ny andalana %d marika %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "Fiantsoana ary tsy vita" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Tsy manomboka amin'ny farango ny teny nalaina" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Tsy mifamaly ny farango anaty lazam-baiko na lahabolana hafa tonon'ny akora" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" +"Nifarana taorian'ny marika '\\' ilay lahabolana. ('%s' ilay lahabolana)" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"Nifarana talohan'ny nahitana ny ilan'ny farango ho an'ny %c ilay lahabolana. " +"('%s' ilay lahabolana)" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Foana ilay lahabolana (na tsy misy afa-tsy elanelana)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Tsy voavaky ny datan'ny fizotra zanaka" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Tsy voaforona ny fantsona ifandraisana amin'ny fizotra zanaka (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Tsy voavaky ny mpiatin'ny fantson'ny zanaka (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Tsy nahomby ny fanovana lahatahiry ho '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Tsy nahavita nanatanteraka ny fizotra zanaka (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Anaran-drindranasa diso: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Tsy mitombina ny laha-dazan'ny mpitondra tondriky amin'ny %d: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Tsy mitombina ny laha-daza anatin'ny tontolo: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Lahatahiry fiasana tsy mitombina: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Tsy nahavita nandefa ny rindranasa mpanampy (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Nisy olana tsy nampoizina tanatin'ny g_io_channel_win32_poll() raha namaky " +"ny datan'ny fizotra zanaka" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Tsy voavaky ny datan'ny fizotra zanaka (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Nisy olana tsy nampoizina tanatin'ny select() raha namaky ny datan'ny " +"fizotra zanaka (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Nisy olana tsy nampoizina tanatin'ny waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Tsy nahavita nanasaka (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Tsy nahavita nandefa ny fizotra zanaka \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"Tsy nahavita namily lalana ny fivoahana na fidiran'ny fizotra zanaka (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Tsy nahavita nanasaka ny fizotra zanaka (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" +"Nisy olana tsy fantatra teo am-panatanterahana ny fizotra zanaka \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Tsy nahavaky data ampy tanatin'ny fantsona zanaka pid (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Mihoatra ny fetran'ny UTF-8 ilay marika" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Tsy mitombina ny filaharana amin'ny fidiran'ny fanovana" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Mihoatra ny fetran'ny UTF-16 ilay marika" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Fampiasa:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[SAFIDY...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Safidy momba ny toro-làlana:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Asehoy ny safidy momba ny toro-làlana" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Asehoy ny safidy rehetra momba ny toro-làlana" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Safidy momba ny rindranasa:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Tsy afaka mizarazara ny sanda feno '%s' ho an'ny %s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Mihoatra ny fetra ny sanda feno '%s' ho an'ny '%s'" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Tsy afaka mizarazara sanda roa '%s' ho an'ny '%s'" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Mihoatra ny fetra ny sanda roa '%s' ho an'ny '%s'" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Nisy olana teo am-pizarazarana ny safidy %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Tondrikin'ny %s tsy eo" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Safidy %s tsy fantatra" + +#: ../glib/gkeyfile.c:366 +#, fuzzy +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Tsy hita anatin'ny lahatahiry misy ny data ny rakitra misy ny famaha marina" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Rakitra tsy mahazatra" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Foana ilay rakitra" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Misy andalana '%s' izay tsy roroa famaha-sanda, vondrona, na teny fanampiny " +"ilay raki-pamaha" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Anaram-bondrona diso: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Tsy manomboka amina vondrona ilay raki-pamaha" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Anaram-pamaha diso: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Misy fango '%s' tsy raisina an-tànana ilay raki-pamaha" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Tsy manana vondrona '%s' ilay raki-pamaha" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Tsy manana famaha '%s' ilay raki-pamaha" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"Misy famaha '%s' manana sanda '%s' izay tsy UTF-8 anatin'ilay raki-pamaha " + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" +"Misy famaha '%s' manana sanda tsy mety avadika mba ho azo anatin'ilay raki-" +"pamaha." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"Misy famaha '%s' manana sanda tsy mety avadika mba ho azo anatin'ilay raki-" +"pamaha." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"Misy famaha '%s' anatin'ny vondrona '%s' manana sanda izay tsy mety avadika " +"mba ho azo ilay raki-pamaha." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Tsy manana famaha '%s' anatin'ny vondrona '%s' ilay raki-pamaha" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Misy marika fialana amin'ny faran'ny andalan'ilay raki-pamaha" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Misy fisesisesim-pialana '%s' tsy mitombina anatin'ilay raki-pamaha" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Tsy mety avadika ho isa mba ho azo ny sanda '%s'." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Mihoatra ny fetra ny sanda feno '%s'" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Tsy mety avadika ho isa float mba ho azo ny sanda '%s'." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Tsy mety avadika ho boleanina mba ho azo ny sanda '%s'." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Tsy mitombina filaharan'ny byte amin'ny zavatra ovaina" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "Safidy %s tsy fantatra" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Safidy %s tsy fantatra" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Nisy olana teo am-panokafana ny lahatahiry '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Nisy olana teo am-panokafana ny lahatahiry '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Misy tsy fetezana amin'ny andalana %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Nisy olana teo am-pizarazarana ny safidy %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Tsy mety atao amin'ny anaran'ary ny marika '%s'" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Tsy mety atao amin'ny anaran'ary ny marika '%s'" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Tsy mety atao amin'ny anaran'ary ny marika '%s'" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Nisy olana teo am-pizarazarana ny safidy %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Nisy olana teo am-panovana: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Nisy olana teo am-panokafana ny lahatahiry '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +#, fuzzy +msgid "No application is registered as handling this file" +msgstr "" +"Tsy misy rindranasa mitondra ny anarana '%s' nanambara rohy ho an'ny '%s'" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Anaram-pamaha diso: %s" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "Anaram-pampiantrano diso" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Tsy voaforona ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Tsy voaforona ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "Tsy voaforona ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Nisy olana teo am-panokafana ny lahatahiry '%s': %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Tsy voavaky ny rohy misolotena '%s': %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Nisy olana teo am-pizarazarana ny safidy %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "Nifarana tampoka tanaty anarana marika manokana ilay tahirin-kevitra" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Nisy olana teo am-panokafana ny lahatahiry '%s': %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Nisy olana teo am-panovana: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Nisy olana teo am-panovana: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Nisy olana teo am-panovana: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "Misy tsy fetezana amin'ny andalana %d: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Nisy olana teo am-panovana: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Nisy olana teo am-panovana: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Nisy olana teo am-pizarazarana ny safidy %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +#, fuzzy +msgid "Target file is not a regular file" +msgstr "Rakitra tsy mahazatra" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Anaram-pamaha diso: %s" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Safidy %s tsy fantatra" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Tsy voaforona ny rakitra '%s': %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Nisy olana teo am-panovana: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Tsy voaforona ny rakitra '%s': %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Tsy voaforona ny rakitra '%s': %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "Misy tsy fetezana amin'ny andalana %d: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Nisy olana teo am-pizarazarana ny safidy %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Nisy olana teo am-pizarazarana ny safidy %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "Tsy raisina an-tànana ny rohy misolotena" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Anaram-pampiantrano diso" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Tsy mitombina ny filaharana amin'ny fidiran'ny fanovana" + +#, fuzzy +#~ msgid "[FILE...]" +#~ msgstr "[SAFIDY...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Tsy mety atao fiantomboham-pidirana ny marika '%s'; ny & no manomboka ny " +#~ "anaran'ny ary. Raha toa ka tsy raisin'ny ary iray an-tànana io marika io " +#~ "(&), dia ataovy & mba ialana izany" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Fiantsoana marika foana; tokony hisy isa toy ny dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Fiantsoana ary tsy vita" + +#~ msgid "Unfinished character reference" +#~ msgstr "Fiantsoana marika tsy vita" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Lahabolana voafango UTF-8 tsy mitombina" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Lahabolana voafango UTF-8 tsy mitombina" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Tsy mitombina ny anaram-mpampiantranon'ny URI '%s'" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Tsy mitombina ny anaram-mpampiantranon'ny URI '%s'" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Nisy olana teo am-pamakiana ny rakitra '%s': %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Nisy olana teo am-pizarazarana ny safidy %s" diff --git a/po/mk.po b/po/mk.po new file mode 100644 index 0000000..89bc405 --- /dev/null +++ b/po/mk.po @@ -0,0 +1,3874 @@ +# translation of glib.HEAD.mk.po to Macedonian +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER. +# +# Ivan Stojmirov , 2002. +# Arangel Angov , 2004, 2005, 2006. +# Ðрангел Ðнгов , 2005. +# Jovan Naumovski , 2006, 2007, 2008. +# Arangel Angov , 2007. +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD.mk\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2008-02-04 04:11+0100\n" +"Last-Translator: Jovan Naumovski \n" +"Language-Team: Macedonian \n" +"Language: mk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural= n%10==1 && n%100!=11 ? 0 : 1\n" +"X-Generator: KBabel 1.11.4\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Ðеочекуван атрибут „%s“ за елементот „%s“" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Ðтрибутот „%s“ на елементот „%s“ не е пронајден" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Ðеочекувана етикета „%s“, Ñе очекуваше „%s“" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Ðеочекувана етикета „%s“ во „%s“" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Ðе е пронајдена валидна датотека за обележувач во дирекориумите Ñо податоци" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Обележувач за URI „%s“ веќе поÑтои" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Ðе е пронајден обележувач за URI „%s“" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Ðе е дефиниран MIME тип во обележувачот за URI „%s“" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Ðе е дефинирано приватно знаме за обележувачот за URI „%s“" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Ðе Ñе поÑтавени групи во обележувачот за URI „%s“" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "Ðема апликација Ñо име „%s“ која региÑтрирала обележувач за „%s“" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Ðе уÑпеав да ја проширам линијата за извршување „%s“ Ñо URI „%s“" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Конвертирањето од %s' во „%s“ не е поддржано" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Ðе можам да го отворам конверторот од „%s“ до „%s“" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Ðевалидна Ñеквенца на бајти во влезот на конвертирањето" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Грешка при конвертирање: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Парцијална Ñеквенца на карактер на крајот од влезот" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Ðе можам да го конвертирам „%s“ во енкодингот „%s“" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "„%s“ не е апÑолутна адреÑа која што ја кориÑти шемата на датотеката" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "Локалното URI „%s“ може да не кориÑти '#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "„%s“ е невалиден URI" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Името на хоÑтот на URI %s е невалидно" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "„%s“ Ñодржи невалидни поÑебни карактери" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Патеката „%s“ не е апÑолутна патека" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Ðевалидно име на хоÑÑ‚" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a, %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "јануари" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "февруари" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "март" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "април" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "мај" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "јуни" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "јули" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "јан" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "фев" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "мар" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "апр" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "мај" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "јун" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "јул" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "понеделник" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "вторник" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Ñреда" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "четврток" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "петок" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Ñабота" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "недела" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "пон" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "вто" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ñре" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "чет" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "пет" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Ñаб" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "нед" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Грешка при отворање на директориумот „%s“: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Ðе можам да алоцирам %lu бајти за да ја прочитам датотеката \"%s\"" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Грешка при читањето на датотеката „%s“: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Ðе уÑпеав да прочитам од датотеката „%s“: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Ðе уÑпеав да ја отворам датотеката „%s“: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" +"Ðе уÑпеав да ги добијам атрибутите на датотеката „%s“: fstat() failed: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Ðе уÑпеав да ја отворам датотеката „%s“: fdopen() failed: %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"Ðе уÑпеав да ја реименувам датотеката „%s“ во „%s“: g_rename() не уÑпеа: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Ðе уÑпеав да ја креирам датотеката „%s“: %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" +"Ðе уÑпеав да ја отворам датотеката „%s“ за запишување: fdopen() не уÑпеа: %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Ðе уÑпеав да запишам во датотеката „%s“: fwrite() не уÑпеа: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Ðе уÑпеав да запишам во датотеката „%s“: fwrite() не уÑпеа: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Ðе уÑпеав да запишам во датотеката „%s“: fwrite() не уÑпеа: %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Ðе уÑпеав да ја затворам датотeката „%s“: fclose() не уÑпеа: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" +"ПоÑтоечката датотека „%s“ не може да биде отÑтранета: g_unlink()·не уÑпеа " +"за: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "МоÑтрата „%s“ е невалидна, не треба да Ñодржи „%s“" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "МоÑтрата „%s“ не Ñодржи Ñо XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u бајт" +msgstr[1] "%u бајти" +msgstr[2] "%u бајти" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, fuzzy, c-format +msgid "%.1f TB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, fuzzy, c-format +msgid "%.1f PB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, fuzzy, c-format +msgid "%.1f EB" +msgstr "%.1f KB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, fuzzy, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%u бајт" +msgstr[1] "%u бајти" +msgstr[2] "%u бајти" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Ðе уÑпеав да ја прочитам Ñимболичката врÑка „%s“: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Симболичките врÑки не Ñе поддржани" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Ðе можам да го отворам конверторот од „%s“ до „%s“: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Ðе можам да направам грубо читање во g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "ПреоÑтанати неконвертирани податоци во баферот за читање" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Каналот Ñе терминира во парцијален карактер" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Ðеможам да читам во g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Ðе уÑпеав да ја отворам датотеката „%s“: open() не уÑпеа: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Ðе уÑпеав да ја означам датотеката „%s“: mmap() не уÑпеа: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Грешка на линија %d знак %d" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Ðевалиден UTF-8 енкодиран текÑÑ‚ - невалидно „%s“" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Грешка на линија %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Ðе уÑпеав да параÑирам '%-.*s', кое што требаше да биде параметар за " +"внатрешен дигитален карактер (на пример, ê) - најверојатно бројот е " +"преголем" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Референцата за карактерите не заврши Ñо полуколона; најверојатно Ñте " +"кориÑтеле Ñимбол без намера да започнете ентитет - одбегнете го Ñимболот Ñо " +"&" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Параметарот на карактерот '%-.*s' не енкодира забранет карактер" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Празен ентитет '&;' видени; валидни ентитети Ñе: & " < > " +"'" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Името на ентитетот „%s“ е познато" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Ентитетот не заврши Ñо полуколоната; најверојатно Ñте кориÑтеле Ñимбол без " +"намера да започнете ентитет - избегнете го Ñимболот Ñо &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Документите мора да започнуваат Ñо елемент (пр. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"„%s“ не е валиден карактер по '<' карактер; не може да започне име на елемент" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Чуден карактер „%s“, очекував '>' карактер да го заврши почетниот таг на " +"елементот „%s“" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Чуден карактер „%s“, очекував '=' по името на атрибутот „%s“ од елементот " +"'%s'" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Чуден карактер „%s“, очекував '>' или '/' за да го затворам почетниот таг на " +"елементот „%s“; можеби Ñте кориÑтеле невалиден карактер во името на атрибутот" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Чуден карактер „%s“, Ñе очекува отворен забележан цитат по еднаквите знаци " +"кога Ñе даваат вредноÑти за атрибутот „%s“· од елементот „%s“·" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"„%s“·не е валиден карактер што би можел да доје по името на елементот „%s“, " +"дозволениот карактер е '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Елементот „%s“ е затворен. Во моментов не е отворен ниеден елемент" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Елементот „%s“ е затворен, но тековно отворениот елемент е „%s“" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Документот е празен или Ñодржи Ñамо празни меÑта" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Документот заврши неочекувано веднаш по заградата за отворениот агол '<'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Документот заврши неочекувано Ñо Ñеуште отворени елементи - „%s“ беше " +"поÑледниот отворен елемент" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Документот заврши неочекувано, очекував да видам го видам аголот на " +"заградата за затворање на тагот <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Документот заврши неочекувано внатре во иметп на елементот" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Документот заврши неочекувано внатре во името на атрибутот" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Документот заврши неочекувано внатре во тагот за отворање на елементи." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "Ðема вредноÑÑ‚ за атрибутот" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"Документот заврши неочекувано додека беше внатре во вредноÑта на атрибутот" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"Документот заврши неочекувано внатре во тагот за затворање на елементи „%s“" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Документот заврши неочекувано внатре во коментар или инÑтрукција за " +"процеÑирање" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "корумпиран објект" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "интерна грешка или корумпиран објект" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "нема повеќе меморија" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "ограничувањето за Ñледење е доÑтигнато" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "шаблонот Ñодржи предмети кои не Ñе поддржани за парцијално Ñовпаѓање" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "внатрешна грешка" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "задните референци не Ñе поддржани како уÑлови за парцијално Ñовпаѓање" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "доÑтигнато е ограничувањето за рекурзија" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "доÑтигнато е ограничувањето за празни поднизи за работните проÑтори" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "невалидна комбинација од ознаки за нов ред" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "непозната грешка" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ на крајот на шаблонот" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c на крајот на шаблонот" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "непрепознатиот знак поÑле \\" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" +"знаците за промена на мала-голема буква (\\l, \\L, \\u, \\U) не Ñе дозволени " +"овде" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "броевите Ñе преголеми за во {}" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "бројот е преголем за ознаката {}" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "недоÑтаÑува ] за прекин за клаÑата знаци" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "невалидна Ñеквенца за излез во клаÑата за знаци" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "опÑегот е преминат во клаÑата на знаци" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "нема ништо за повторување" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "непрепознат знак поÑле (?" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "непрепознат знак поÑле (?<" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "непрепознат знак поÑле (?P" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "КлаÑите Ñо POSIX имиња Ñе поддржани Ñамо внатре во клаÑа" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "недоÑтаÑува ) за прекин" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") без отворање на (" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "цифрите (?R или (?[+-] мора да бидат проÑледени Ñо )" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "референца до непоÑтоечки подшаблон" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "недоÑтаÑува ) поÑле коментарот" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "регуларниот израз е преголем" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "не уÑпеав да добијам меморија" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "тврдењето за поглед наназад не е Ñо фикÑна должина" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "неправилен број или име поÑле (?(" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "уÑловната група Ñодржи повеќе од две гранки" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "Ñе очекува барање поÑле (?(" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "непознато име на POSIX клаÑа" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "POSIX елементите не Ñе поддржани" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "вредноÑта на знакот во Ñеквенцата \\x{...} е преголема" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "невалиден уÑлов (?(0)" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C не е дозволено во барање за поглед наназад" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "рекурзивниот повик може да Ñе повикува беÑконечно" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "недоÑтаÑува прекинувач во името на подшаблонот" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "два подшаблони имаат иÑти имиња" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "неправилна \\P или \\p Ñеквенца" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "непознато име на ÑвојÑтво поÑле \\P или \\p" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "името на подшаблонот е предолго (макÑимум 32 знаци)" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "премногу именувани подшаблони (макÑимум 10,000)" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "окталната вредноÑÑ‚ е поголема од \\377" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE групата Ñодржи повеќе од една гранка" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "повторувањето на DEFINE група не е дозволено" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "нецелоÑни NEWLINE опции" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" +"\\g не е проÑледено Ñо име во загради или опционално ненулти број во загради" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "неочекувано повторување" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "overflow на код" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "преминато меÑто за компајлирање" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "претходно проверениот референциран подшаблон не е пронајден" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Грешка при Ñовпаѓањето на регуларни изрази %s: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE библиотеката е компајлирана без UTF-8 поддршка" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE библиотеката е компајлирана без поддршка за ÑвојÑтвата на UTF8" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Грешка при компајлирање на регуларниот израз %s кај знакот %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Грешка во оптимизирањето на регуларниот израз %s: %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "Се очекува хекÑдецимална цифра или „}“" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "Се очекува хекÑдецимална цифра" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "недоÑтаÑува „<“ во Ñимболичката референца" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "Ðедовршена Ñимболичка референца" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "Ñимболичка референца Ñо нулта должина" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "Ñе очекува цифра" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "нелегална Ñимболичка референца" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "занемари го финалното „\\“" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "непозната излезна Ñеквенца" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "Грешка при парÑирањето на текÑтот за замена „%s“ на знакот %lu: %s" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Цитираниот текÑÑ‚ не започнува Ñо знакот за цитирање" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"ÐеÑовпаѓачки знак за цитирање на командната линија или друг текÑÑ‚ цитиран во " +"школка" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "ТекÑтот заврши веднаш по '\\' карактер. (ТекÑтот беше „%s“)" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"ТекÑтот заврши пред да биде пронајден Ñовпаѓачки цитат за %c. (ТекÑтот беше " +"„%s“)" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "ТекÑтот беше празен (или Ñодржеше Ñамо празни меÑта)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Ðе уÑпеав да ги прочитам податоците од подпроцеÑот" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Ðе уÑпеав да креирам цевка за комуникација Ñо другите подпроцеÑи (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Ðе уÑпеав да прочитам од под-цевката (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Ðе уÑпеав да го променам директориумот„%s“ (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Ðе уÑпеав да го извршам подпроцеÑот (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ðевалидно име на програма: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ðевалиден Ñтринг во аргументот за векторот кај %d: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ðевалиден Ñтринг во околината: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ðевалиден работен директориум: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Ðе уÑпеав да ја извршам програмата за помош (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ðеочекувана грешка во g_io_channel_win32_poll() при читање на податоциод " +"подпроцеÑот" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Ðе уÑпеав да ги прочитам податоците од подпроцеÑите (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Ðеочекувана грешка во select() при читањето на податоци од подпроцеÑот (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ðеочекувана грешка во waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Ðе уÑпеав да форкувам (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Ðе уÑпеав да го извршам подпроцеÑот \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Ðе уÑпеав да го пренаÑочам излезот или влезот на подпроцеÑот (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Ðе уÑпеав да го форкувам подпроцеÑот (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Ðепозната грешка при извршувањето на подпроцеÑот \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Ðе уÑпеав да прочитам доволно податоци од pid подцевката (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Карактерот е надвор од опÑегот за UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Ðевалидна Ñеквенца во излезот од конвертирањето" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Карактерот е надвор од опÑег за UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Употреба:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[ОПЦИЈÐ...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Опции за помош:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Покажи ги Ñите опции за помош" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Покажи ги Ñите опции за помош" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Опции на апликацијата:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Ðе можам да парÑирам вредноÑÑ‚ за целобројната вредноÑÑ‚ „%s“ за %s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "ВредноÑта на целиот број „%s“ за %s е надвор од опÑегот" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Ðе можам да ја анализирам целобројната вредноÑÑ‚ „%s“ за %s" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "ВредноÑта на целиот број „%s“ за %s е надвор од опÑегот" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Грешка при парÑирањето на опцијата %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "ÐедоÑтига аргумент за %s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Ðепозната опција „%s“·" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "Ðе е пронајден валиден клуч во директориумите за пребарување" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Ðе е обична датотека" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Датотеката е празна" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Клучната датотека Ñодржи линија „%s“· која што не е пар на клучна вредноÑÑ‚, " +"група или коментар" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ðевалидно име на група: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Клучната датотека не започнува Ñо група" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Ðевалидно име на клуч: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Клучната датотека Ñодржи неподдржан енкодинг „%s“·" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Клучната датотека не ја Ñодржи групата „%s“" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Клучната датотека не го Ñодржи клучот „%s“" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"Клучната датотека го Ñодржи клучот „%s“ Ñо вредноÑта „%s“ која што не е UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" +"Клучната датотека го Ñодржи клучот „%s“ чија што вредноÑÑ‚ неможе да биде " +"препознаена." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"Клучната датотека го Ñодржи клучот „%s“ чија што вредноÑÑ‚ неможе да биде " +"препознаена." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"Клучната датотека го Ñодржи клучот „%s“ во групата „%s“ која што има " +"вредноÑÑ‚ која што неможе да биде препознаена." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Клучната датотека не Ñодржи клуч во „%s“ во групата „%s“" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Клучната датотека Ñодржи Ñпецијални карактери на крајот на линијата" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Клучната датотека Ñодржи невалидни поÑебни карактери „%s“" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "ВредноÑта „%s“ неможе да биде препознаена како број." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Целобројната вредноÑÑ‚ „%s“ е надвор од опÑегот" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "ВредноÑта „%s“ неможе да биде препознаена како рационален број." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "ВредноÑта „%s“ не може да биде препознаена како boolean." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Преголема бројна вредноÑÑ‚ дадена на %s" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "Стримот е веќе затворен" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "Операцијата беше прекината" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Ðевалидна Ñеквенца на бајти во влезот на конвертирањето" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Операцијата не е поддржана" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Ðепознат тип" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s тип на датотека" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s тип" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "Ðеочекувано прерано завршување на Ñтрим" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Грешка при Ñкратувањето на датотеката: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Грешка при отворањето на датотеката „%s“: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Грешка при читањето на датотеката „%s“: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Грешка при читањето на датотеката „%s“: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Грешка во запишувањето во датотеката: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Грешка при читањето на датотеката „%s“: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Ðепознат тип" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Грешка при отворање на директориумот „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Грешка при отворање на директориумот „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Грешка при отворањето на датотеката „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Грешка при читањето на датотеката „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Грешка при читањето на датотеката „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Грешка во затворањето на датотеката: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Грешка при отворањето на датотеката „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Грешка при отворањето на датотеката „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "Енумераторот е затворен" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "Стримот е веќе затворен" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Грешка во запишувањето во датотеката: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Ѓубрето не е поддржано" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Грешка во запишувањето во датотеката: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Грешка на линија %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Грешка при парÑирањето на опцијата %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Грешка во отворањето на директоруимот: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Карактерот „%s“ не е валиден внатре во името на ентитетот" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Карактерот „%s“ не е валиден внатре во името на ентитетот" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Карактерот „%s“ не е валиден внатре во името на ентитетот" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Грешка при парÑирањето на опцијата %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Грешка при конвертирање: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Грешка при отворање на директориумот „%s“: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "корумпиран објект" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Ðеименувано" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "Desktop датотеката не одреди Exec поле" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "не уÑпеав да најдам терминал потребен за апликација" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" +"Ðе можам да креирам папка за конфигурација на кориÑничките апликации %s: %s" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "Ðе можам да креирам папка за MIME конфигурации %s: %s" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Ðе можам да креирам кориÑничка desktop датотека %s" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "СопÑтвена дефиниција на %s" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "уредот нема имплементирано вадење" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +#, fuzzy +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "уредот нема имплементирано вадење" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "уредот нема имплементирано барање за медиум" + +#: ../gio/gdrive.c:728 +#, fuzzy +msgid "drive doesn't implement start" +msgstr "уредот нема имплементирано вадење" + +#: ../gio/gdrive.c:831 +#, fuzzy +msgid "drive doesn't implement stop" +msgstr "уредот нема имплементирано вадење" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Операцијата не е поддржана" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "Монтирањето кое Ñе Ñодржи не поÑтои" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "Ðе можам да копирам над директориум" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "Ðе можам да копирам директориум над директориум" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "Целната датотека поÑтои" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "Ðе можам рекурзивно да го иÑкопирам директориумот" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Симболичките врÑки не Ñе поддржани" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Грешка во отворањето на директоруимот: %s" + +#: ../gio/gfile.c:2909 +#, fuzzy +msgid "Can't copy special file" +msgstr "Ðе можам да копирам над директориум" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "Дадена е невалидна вредноÑÑ‚ за Ñимболичката врÑка" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "Ѓубрето не е поддржано" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Имињата на датотеки не можат да Ñодржат „%c“" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "проÑторот нема имплементирано монтирање" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "Ðе е региÑтрирана апликација за Ñправување Ñо оваа датотека" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "Енумераторот е затворен" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "Енумераторот на датотеки има преголема операција " + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "Енумераторот за датотеки веќе е затворен" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "Стримот не поддржува query_info" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "Барањето не е поддржано за Ñтрим" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "Смалувањето не е дозволено на влезен Ñтрим" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "Смалувањето не е поддржано на Ñтрим" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "Влезниот Ñтрим нема имплементирано читање" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "Стримот има преголема операција" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Ѓубрето не е поддржано" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, fuzzy, c-format +msgid "invalid GVariant type string '%s'" +msgstr "Ðевалиден тип на атрибут (Ñе очекуваше знаковна низа)" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "Ðе можам да најдам локален директориум за тип на надгледување" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Ðевалидно име на датотека %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Грешка при добивањето на информации за датотечниот ÑиÑтем: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "Ðе можам да го преименувам директориумот root" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Грешка во преименувањето на директоруимот: %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "Ðе можам да ја преименувам датотеката, името на датотеката веќе поÑтои" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Ðевалидно име на датотека" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Грешка во отворањето на директоруимот: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "Ðе можам да го отворам директориумот" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Грешка при отÑтранувањето на датотеката: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "Грешка при премеÑтувањето на датотеката во ѓубре: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Ðе уÑпеав да креирам директориум за ѓубре %s: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "Ðе уÑпеав да го најдам директориумот од највиÑоко ниво за ѓубрето" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "Ðе уÑпеав да го најдам или креирам директориумот за ѓубре" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "" +"Ðе уÑпеав да креирам датотека Ñо информации за премеÑтувањето во ѓубре: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Ðе уÑпеав да ја премеÑтам датотеката во ѓубрето: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Грешка при отворање на директориумот „%s“: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Ðе уÑпеав да ја прочитам Ñимболичката врÑка „%s“: %s" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Грешка во креирањето на Ñимболичка врÑка: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Грешка во премеÑтувањето на датотеката: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "Ðе можам да го премеÑтам директориумот над друг директориум" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "Ðе уÑпеа креирањето на бекап датотеката" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "Грешка во отÑтранувањето на целната датотека: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "Движењето меѓу монтирањата не е поддржано" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "ВредноÑта на атрибутот не Ñмее да е NULL" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "Ðевалиден тип на атрибут (Ñе очекуваше знаковна низа)" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "Ðевалидно име на проширениот атрибут" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Грешка во поÑтавувањето на проширениот атрибут „%s“: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "Грешка во Ñтартувањето на датотеката „%s“: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (невалидно енкодирање)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "Грешка во поÑтавувањето на опишувач на датотека: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ðевалиден тип на атрибут (Ñе очекуваше uint32)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ðевалиден тип на атрибут (Ñе очекуваше uint64)" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ðевалиден тип на атрибут (Ñе очекуваше низа од бајти)" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Грешка во поÑтавувањето на пермиÑиите: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Грешка во поÑтавувањето на пермиÑиите: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "Грешка при поÑтавувањето на ÑопÑтвеникот: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "Ñимболичката врÑка не треба да е NULL" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Грешка во поÑтавувањето на Ñимболичката врÑка: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Грешка при креирањето на Ñимболичката врÑка: датотеката не е Ñимболичка врÑка" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Грешка во поÑтавувањето на пермиÑиите: %s" + +#: ../gio/glocalfileinfo.c:2162 +#, fuzzy +msgid "SELinux context must be non-NULL" +msgstr "Ñимболичката врÑка не треба да е NULL" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Грешка при поÑтавувањето на ÑопÑтвеникот: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "ПоÑтавувањето на атрибутот %s не е поддржано" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Грешка при читањето од датотеката: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Грешка при барањето во датотеката: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Грешка во затворањето на датотеката: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "Ðе можам да го откријам типот на локалниот надгледувач на датотеки" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Грешка во запишувањето во датотеката: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Грешка во отÑтранувањето на Ñтарата бекап врÑка: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Грешка при креирањето на бекап копија: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Грешка во преименувањето на привремената датотека: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "Грешка при Ñкратувањето на датотеката: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Грешка при отворањето на датотеката „%s“: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "Целната датотека е директориум" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "Целната датотека не е обична датотека" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "Датотеката беше надворешно изменета" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Грешка при отÑтранувањето на датотеката: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "Обезбеден е невалиден GSeekType" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Ðевалидно барање за барање" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ðе можам да го Ñмалам GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "Меморијата на излезниот Ñтрим не може да Ñи ја промени големината" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "Ðе уÑпеав да ја променам големината на меморијата на излезниот Ñтрим" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +#, fuzzy +msgid "mount doesn't implement \"unmount\"" +msgstr "mount нема имплементирано одмонтирање" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +#, fuzzy +msgid "mount doesn't implement \"eject\"" +msgstr "mount нема имплементирано вадење" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +#, fuzzy +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "mount нема имплементирано одмонтирање" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +#, fuzzy +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "mount нема имплементирано вадење" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +#, fuzzy +msgid "mount doesn't implement \"remount\"" +msgstr "mount нема имплементирано запишување" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +#, fuzzy +msgid "mount doesn't implement content type guessing" +msgstr "mount нема имплементирано одмонтирање" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +#, fuzzy +msgid "mount doesn't implement synchronous content type guessing" +msgstr "mount нема имплементирано одмонтирање" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "Излезниот Ñтрим нема имплементирано запишување" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "Изворот на Ñтримот веќе е затворен" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Грешка при читањето на датотеката „%s“: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Грешка при читањето на датотеката „%s“: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Грешка при отÑтранувањето на датотеката: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Ðепозната опција „%s“·" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +#, fuzzy +msgid "Socket is already closed" +msgstr "Изворот на Ñтримот веќе е затворен" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Грешка при читањето од датотеката: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Ðе уÑпеав да креирам директориум за ѓубре %s: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Грешка во запишувањето во датотеката: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Грешка при конвертирање: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Грешка при Ñкратувањето на датотеката: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Грешка во отворањето на директоруимот: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Ðе уÑпеав да ја премеÑтам датотеката во ѓубрето: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Грешка при отÑтранувањето на датотеката: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Грешка во отворањето на директоруимот: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ðе уÑпеав да креирам директориум за ѓубре %s: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Грешка во затворањето на датотеката: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Грешка во отворањето на директоруимот: %s" + +#: ../gio/gsocket.c:3081 +#, fuzzy +msgid "GSocketControlMessage not supported on windows" +msgstr "промените на аÑоцијации не Ñе поддржани на win32" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Грешка при отÑтранувањето на датотеката: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +#, fuzzy +msgid "Unknown error on connect" +msgstr "непозната грешка" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Симболичките врÑки не Ñе поддржани" + +#: ../gio/gsocketlistener.c:191 +#, fuzzy +msgid "Listener is already closed" +msgstr "Стримот е веќе затворен" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +#, fuzzy +msgid "Unexpected type of ancillary data" +msgstr "Ðеочекувано прерано завршување на Ñтрим" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Грешка во отворањето на директоруимот: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Грешка во преименувањето на директоруимот: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "Грешка при читањето од unix: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "Грешка во затворањето на unix: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "Root на датотечниот ÑиÑтем" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "Грешка во запишувањето на unix: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "проÑторот нема имплементирано вадење" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +#, fuzzy +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "проÑторот нема имплементирано вадење" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "Ðе можам да ја најдам апликацијата" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "Грешка во пуштањето на апликацијата: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "URI-те не Ñе поддржани" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "промените на аÑоцијации не Ñе поддржани на win32" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "Креирањето на аÑоцијација не е поддржано на win32" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Грешка при читањето од датотеката: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Грешка во затворањето на датотеката: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Грешка во запишувањето во датотеката: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "нема повеќе меморија" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "внатрешна грешка" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Ðевалидно име на хоÑÑ‚" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Ðе можам да го премеÑтам директориумот над друг директориум" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Ðевалидна Ñеквенца во излезот од конвертирањето" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "ДоÑтигнато е ограничувањето за макÑимум податоци во низа" + +#~ msgid "do not hide entries" +#~ msgstr "не ги криј запиÑите" + +#~ msgid "use a long listing format" +#~ msgstr "кориÑти фомрат Ñо долго лиÑтање" + +#~ msgid "[FILE...]" +#~ msgstr "[ДÐТОТЕКÐ...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Карактерот „%s“ претÑтавува невалиден почеток на име на ентитет, " +#~ "карактерот & го започнува ентитетот;" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "" +#~ "Параметар за празен карактер; треба да Ñодржи бројка како што е dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Ðедовршен параметар за ентитет" + +#~ msgid "Unfinished character reference" +#~ msgstr "Ðедовршен параметар за карактер" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Ðевалиден UTF-8 енкодиран текÑÑ‚ - предолга Ñеквенца" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Ðевалиден UTF-8 енкодиран текÑÑ‚ - нема почетен знак" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Името на хоÑтот на URI %s е невалидно" + +#, fuzzy +#~ msgid "name" +#~ msgstr "Ðеименувано" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Името на хоÑтот на URI %s е невалидно" + +#, fuzzy +#~ msgid "names" +#~ msgstr "Ðеименувано" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Грешка во поÑтавувањето на опишувач на датотека: %s" + +#~ msgid "Error creating backup link: %s" +#~ msgstr "Грешка при креирањето на бекап врÑка: %s" diff --git a/po/ml.po b/po/ml.po new file mode 100644 index 0000000..3957f0e --- /dev/null +++ b/po/ml.po @@ -0,0 +1,4520 @@ +# translation of glib.master.ml.po to +# translation of glib.HEAD.ml.po to +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# +# FSF-India , 2003. +# Ani Peter , 2006, 2007, 2008, 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: glib.master.ml\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-03-09 14:58+0000\n" +"PO-Revision-Date: 2013-03-22 21:35+0530\n" +"Last-Translator: Ani Peter \n" +"Language-Team: American English \n" +"Language: ml\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"\n" + +#: ../gio/gbufferedinputstream.c:427 ../gio/gbufferedinputstream.c:506 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:377 +#: ../gio/ginputstream.c:615 ../gio/ginputstream.c:833 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:732 +#: ../gio/gpollableinputstream.c:207 ../gio/gpollableoutputstream.c:208 +#, c-format +msgid "Too large count value passed to %s" +msgstr "വളരെ വലിയ കൌണàµà´Ÿàµ മൂലàµà´²àµà´¯à´‚ %s-à´¨àµàµ നലàµâ€à´•ിയിരികàµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gbufferedinputstream.c:899 ../gio/gbufferedoutputstream.c:581 +#: ../gio/gdataoutputstream.c:568 +#| msgid "Seek not supported on stream" +msgid "Seek not supported on base stream" +msgstr "à´…à´Ÿà´¿à´¸àµà´¥à´¾à´¨ à´¸àµà´Ÿàµà´°àµ€à´®à´¿à´²àµâ€ Seek പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gbufferedinputstream.c:945 +#| msgid "Cannot truncate GMemoryInputStream" +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream à´Ÿàµà´°à´¨àµâ€à´•േറàµà´±àµ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gbufferedinputstream.c:990 ../gio/ginputstream.c:1023 +#: ../gio/giostream.c:291 ../gio/goutputstream.c:1334 +msgid "Stream is already closed" +msgstr "à´¸àµà´Ÿàµà´°àµ€à´‚ നിലവിലàµâ€ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gbufferedoutputstream.c:618 ../gio/gdataoutputstream.c:598 +#, fuzzy +#| msgid "Truncate not supported on stream" +msgid "Truncate not supported on base stream" +msgstr "à´¸àµà´Ÿàµà´°àµ€à´®à´¿à´²àµâ€ Truncate à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gcancellable.c:318 ../gio/gdbusconnection.c:1885 +#: ../gio/gdbusconnection.c:1977 ../gio/gdbusprivate.c:1421 +#: ../gio/glocalfile.c:2172 ../gio/gsimpleasyncresult.c:843 +#: ../gio/gsimpleasyncresult.c:869 +#, c-format +msgid "Operation was cancelled" +msgstr "à´ªàµà´°à´•àµà´°à´¿à´¯ റദàµà´¦à´¾à´•àµà´•ിയിരികàµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gcharsetconverter.c:262 +#, fuzzy +msgid "Invalid object, not initialized" +msgstr "തെറàµà´±à´¾à´¯ സോകàµà´•à´±àµà´±àµ, ആരംഭിചàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´²" + +#: ../gio/gcharsetconverter.c:283 ../gio/gcharsetconverter.c:311 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "മാറàµà´±à´‚ വരàµà´¤àµà´¤àµà´¨àµà´¨ ഇനàµâ€à´ªàµà´Ÿàµà´Ÿà´¿à´²àµâ€ തെറàµà´±à´¾à´¯ ബൈറàµà´±àµ à´•àµà´°à´®à´‚" + +#: ../gio/gcharsetconverter.c:317 ../gio/gcharsetconverter.c:326 +msgid "Not enough space in destination" +msgstr "ലകàµà´·àµà´¯à´¤àµà´¤à´¿à´²àµâ€ à´…à´§à´¿à´•à´‚ à´¸àµà´¥à´²à´®à´¿à´²àµà´²" + +#: ../gio/gcharsetconverter.c:344 ../gio/gdatainputstream.c:854 +#: ../gio/gdatainputstream.c:1264 ../glib/gconvert.c:764 +#: ../glib/gconvert.c:1156 ../glib/giochannel.c:1586 ../glib/giochannel.c:1628 +#: ../glib/giochannel.c:2472 ../glib/gutf8.c:833 ../glib/gutf8.c:1284 +msgid "Invalid byte sequence in conversion input" +msgstr "മാറàµà´±à´‚ വരàµà´¤àµà´¤àµà´¨àµà´¨ ഇനàµâ€à´ªàµà´Ÿàµà´Ÿà´¿à´²àµâ€ തെറàµà´±à´¾à´¯ ബൈറàµà´±àµ à´•àµà´°à´®à´‚" + +#: ../gio/gcharsetconverter.c:349 ../glib/gconvert.c:772 +#: ../glib/gconvert.c:1081 ../glib/giochannel.c:1593 ../glib/giochannel.c:2484 +#, c-format +msgid "Error during conversion: %s" +msgstr "മാറàµà´±à´‚ വരàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം : %s" + +#: ../gio/gcharsetconverter.c:446 ../gio/gsocket.c:991 +msgid "Cancellable initialization not supported" +msgstr "റദàµà´¦à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധികàµà´•àµà´¨àµà´¨ ഇനീഷàµà´¯à´²àµˆà´¸àµ‡à´·à´¨àµâ€ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gcharsetconverter.c:457 ../glib/gconvert.c:564 +#: ../glib/gconvert.c:642 ../glib/giochannel.c:1414 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "à´…à´•àµà´·à´°à´•àµà´•ൂടàµà´Ÿà´‚'%s'ലൠനിനàµà´¨àµà´‚ '%s'ലേകàµà´•àµà´³à´³ മാറàµà´±à´‚ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gcharsetconverter.c:461 ../glib/gconvert.c:568 +#: ../glib/gconvert.c:646 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s'-à´²àµâ€ നിനàµà´¨àµà´‚ '%s'-ലേകàµà´•ൠവേരàµâ€à´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨ സംവിധാനം ലഭàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s തരതàµà´¤à´¿à´²àµà´³àµà´³" + +#: ../gio/gcontenttype-win32.c:162 +msgid "Unknown type" +msgstr "അപരിചിതമായ തരതàµà´¤à´¿à´²àµà´³àµà´³à´¤àµ" + +#: ../gio/gcontenttype-win32.c:163 +#, c-format +msgid "%s filetype" +msgstr "%s ഫയലàµâ€ രീതിയിലàµà´³àµà´³" + +#: ../gio/gcredentials.c:264 ../gio/gcredentials.c:528 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials à´ˆ ഒഎസിലàµâ€ ലഭàµà´¯à´®à´¾à´•àµà´•ിയിടàµà´Ÿà´¿à´²àµà´²" + +#: ../gio/gcredentials.c:438 +msgid "There is no GCredentials support for your platform" +msgstr "നിങàµà´™à´³àµà´Ÿàµ† à´ªàµà´²à´¾à´±àµà´±àµà´«àµ‹à´®à´¿à´¨àµà´šà´¿à´¤à´®à´¾à´¯ GCredentials ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gcredentials.c:480 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "à´ˆ ഒഎസിലàµâ€ GCredentials-à´¨àµàµ ഒരൠപàµà´°àµŠà´¸à´¸àµà´¸àµ à´à´¡à´¿ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "end-of-stream à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ സമയതàµà´¤à´¿à´¨àµàµ à´®àµà´®àµà´ªàµàµ" + +#: ../gio/gdbusaddress.c:150 ../gio/gdbusaddress.c:238 +#: ../gio/gdbusaddress.c:319 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "പിനàµà´¤àµà´£à´¯àµà´•àµà´•ാതàµà´¤ കീ '%s', '%s' വിലാസതàµà´¤à´¿à´²àµâ€" + +#: ../gio/gdbusaddress.c:177 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"വിലാസം '%s' അസാധൠ(കൃതàµà´¯à´‚ ഒരൠപാഥàµ, tmpdir à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ à´…à´¬àµà´¸àµà´Ÿàµà´°à´¾à´•àµà´±àµà´±àµ " +"കീകളàµâ€ ആവശàµà´¯à´®àµà´£àµà´Ÿàµàµ or abstract keys)" + +#: ../gio/gdbusaddress.c:190 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:253 ../gio/gdbusaddress.c:334 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:264 ../gio/gdbusaddress.c:345 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:454 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:475 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:489 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:567 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:603 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:617 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:631 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:652 +msgid "Error auto-launching: " +msgstr "à´¸àµà´µà´¯à´®à´¾à´¯à´¿ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: " + +#: ../gio/gdbusaddress.c:660 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:696 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "nonce ഫയലàµâ€ '%s' à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusaddress.c:714 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "nonce ഫയലàµâ€ '%s'-à´²àµâ€ നിനàµà´¨àµà´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusaddress.c:723 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "%s വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€â€Œ പരാജയം : %s" + +#: ../gio/gdbusaddress.c:741 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "ഫയലിലേകàµà´•ൠഎഴàµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusaddress.c:960 +msgid "The given address is empty" +msgstr "നലàµâ€à´•à´¿à´¯ വിലാസം കാലിയാണàµàµ" + +#: ../gio/gdbusaddress.c:1030 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "setuid ചെയàµà´¯àµà´®àµà´ªàµ‹à´³àµâ€ ഒരൠസനàµà´¦àµ‡à´¶à´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusaddress.c:1037 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1079 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "കമാനàµâ€à´¡àµ ലൈനàµâ€ '%s' ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: " + +#: ../gio/gdbusaddress.c:1296 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(à´ˆ ജാലകം à´…à´Ÿà´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ à´à´¤àµ†à´™àµà´•à´¿à´²àµà´‚ à´…à´•àµà´·à´°à´‚ ടൈപàµà´ªàµ ചെയàµà´¯àµà´•)\n" + +#: ../gio/gdbusaddress.c:1421 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"സെഷനàµâ€ dbus à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´², à´¸àµà´µà´¯à´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤àµàµ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ" + +#: ../gio/gdbusaddress.c:1442 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"സെഷനàµâ€ ബസൠവിലാസം à´•à´£àµà´Ÿàµà´ªà´¿à´Ÿà´¿à´¯àµà´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´² (à´ˆ ഒഎസിനàµàµ " +"ലഭàµà´¯à´®à´¾à´•àµà´•ിയിടàµà´Ÿà´¿à´²àµà´²)" + +#: ../gio/gdbusaddress.c:1541 ../gio/gdbusconnection.c:6757 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1550 ../gio/gdbusconnection.c:6766 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1560 +#, c-format +msgid "Unknown bus type %d" +msgstr "അപരിചിതമായ ബസൠതരം %d" + +#: ../gio/gdbusauth.c:298 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:342 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:513 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1175 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" +"GDBusAuthObserver::authorize-authenticated-peer à´®àµà´–േന റദàµà´¦à´¾à´•àµà´•ിയിരിയàµà´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "'%s' ഡയറകàµà´Ÿà´±à´¿à´¯à´¿à´²àµâ€ നിനàµà´¨àµà´‚ വിവരങàµà´™à´³àµâ€ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´®àµà´ªàµ‹à´³àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"'%s' ഡയറകàµà´Ÿà´±à´¿à´¯à´¿à´²àµà´³àµà´³ à´…à´¨àµà´®à´¤à´¿à´•ളിലàµâ€ തകരാരàµâ€. à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´š മോഡൠ0700, ലഭിചàµà´šà´¤àµàµ " +"0%o" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "ഡയറകàµà´Ÿà´±à´¿ '%s' ഉണàµà´Ÿà´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "'%s' കീറിങൠതàµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ:" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:719 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:733 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:747 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:537 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "%s വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€â€Œ പരാജയം : %s" + +#: ../gio/gdbusauthmechanismsha1.c:569 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "%s വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€â€Œ പരാജയം : %s" + +#: ../gio/gdbusauthmechanismsha1.c:599 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "ഫയലàµâ€ à´…à´Ÿà´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:609 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "'%s' ഫയലàµâ€ à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:686 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "'%s' ഫയലàµâ€ à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusauthmechanismsha1.c:883 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:597 ../gio/gdbusconnection.c:2440 +msgid "The connection is closed" +msgstr "കണകàµà´·à´¨àµâ€ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gdbusconnection.c:1930 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2562 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:4065 ../gio/gdbusconnection.c:4381 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4136 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"'%s' വിശേഷത സജàµà´œà´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´šà´¤àµàµ '%s' പകàµà´·àµ‡ ലഭിചàµà´šà´¤àµàµ '%" +"s'" + +#: ../gio/gdbusconnection.c:4231 +#, c-format +msgid "No such property '%s'" +msgstr "'%s' വിശേഷത ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusconnection.c:4243 +#, c-format +msgid "Property '%s' is not readable" +msgstr "'%s' വിശേഷത ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusconnection.c:4254 +#, c-format +msgid "Property '%s' is not writable" +msgstr "'%s' വിശേഷതയിലേകàµà´•àµàµ സൂകàµà´·à´¿à´¯àµà´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusconnection.c:4324 ../gio/gdbusconnection.c:6200 +#, c-format +msgid "No such interface '%s'" +msgstr "'%s' ഇനàµà´±à´°àµâ€à´«àµ†à´¯à´¿à´¸àµ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusconnection.c:4508 +msgid "No such interface" +msgstr "à´…à´¤àµà´¤à´°à´‚ ഇനàµà´±à´°àµâ€à´«àµ†à´¯à´¿à´¸à´¿à´²àµà´²" + +#: ../gio/gdbusconnection.c:4726 ../gio/gdbusconnection.c:6706 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4781 +#, c-format +msgid "No such method '%s'" +msgstr "'%s' പോലàµà´³àµà´³ മാരàµâ€à´—àµà´—മിലàµà´²" + +#: ../gio/gdbusconnection.c:4812 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5032 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:5230 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:6311 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6430 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "ലിസണരàµâ€ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gdbusmessage.c:1271 +msgid "type is INVALID" +msgstr "തരം INVALID ആണàµàµ" + +#: ../gio/gdbusmessage.c:1282 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1293 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN സനàµà´¦àµ‡à´¶à´‚: REPLY_SERIAL ഹെഡരàµâ€ ഫീളàµâ€à´¡àµ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusmessage.c:1305 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"പിശകൠസനàµà´¦àµ‡à´¶à´‚: REPLY_SERIAL à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ ERROR_NAME ഹെഡരàµâ€ ഫീളàµâ€à´¡àµ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusmessage.c:1318 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"SIGNAL സനàµà´¦àµ‡à´¶: PATH, INTERFACE à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ MEMBER ഹെഡരàµâ€ ഫീളàµâ€à´¡àµ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusmessage.c:1326 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1334 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1383 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1398 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1417 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1619 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1643 +#, fuzzy, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "'%s' തെറàµà´±à´¾à´¯ നാമം ആകàµà´¨àµà´¨àµ" + +#: ../gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1851 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1875 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2062 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:2075 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"തെറàµà´±à´¾à´¯ à´ªàµà´°à´§à´¾à´¨ à´ªàµà´°àµ‹à´Ÿàµà´Ÿàµ‹à´•àµà´•ോളàµâ€ പതിപàµà´ªàµàµ. à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´šà´¤àµàµ 1 പകàµà´·àµ‡ ലഭിചàµà´šà´¤àµàµ %d" + +#: ../gio/gdbusmessage.c:2131 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:2145 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:2175 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:2185 +msgid "Cannot deserialize message: " +msgstr "സനàµà´¦àµ‡à´¶à´‚ ഡീസീരിയലൈസൠചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²:" + +#: ../gio/gdbusmessage.c:2506 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2643 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2651 +msgid "Cannot serialize message: " +msgstr "സനàµà´¦àµ‡à´¶à´‚ സീരിയലൈസൠചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²:" + +#: ../gio/gdbusmessage.c:2695 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2705 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2721 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:3271 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "ഫയലിലേകàµà´•ൠഎഴàµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusmessage.c:3279 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:2069 +#, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to get Hardware profile: %s" +msgstr "ഹാരàµâ€à´¡àµâ€Œà´µàµ†à´¯à´°àµâ€ à´ªàµà´°àµŠà´«àµˆà´²àµâ€ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: %s" + +#: ../gio/gdbusprivate.c:2114 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" +"/var/lib/dbus/machine-id à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ /etc/machine-id ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ " +"സാധàµà´¯à´®à´²àµà´²: " + +#: ../gio/gdbusproxy.c:1640 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1663 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" +"à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ മറàµà´ªà´Ÿà´¿ %d-à´²àµâ€ നിനàµà´¨àµà´‚ StartServiceByName(\"%s\") മാരàµâ€à´—àµà´—à´‚" + +#: ../gio/gdbusproxy.c:2763 ../gio/gdbusproxy.c:2900 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:709 +msgid "Abstract name space not supported" +msgstr "à´…à´¬àµà´¸àµà´Ÿàµà´°à´¾à´•àµà´±àµà´±àµ നെയിം à´¸àµà´ªàµ†à´¯à´¿à´¸à´¿à´¨àµàµ പിനàµà´¤àµà´£ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusserver.c:796 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"ഒരൠസരàµâ€à´µà´°àµâ€ തയàµà´¯à´¾à´±à´¾à´•àµà´•àµà´®àµà´ªàµ‹à´³àµâ€ nonce ഫയലàµâ€ നിഷàµà´•à´°àµâ€à´·à´¿à´¯àµà´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gdbusserver.c:874 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "ഫയലിലേകàµà´•ൠഎഴàµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbusserver.c:1043 +#, fuzzy, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' തെറàµà´±à´¾à´¯ നാമം ആകàµà´¨àµà´¨àµ" + +#: ../gio/gdbusserver.c:1083 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:92 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gdbus-tool.c:97 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:166 ../gio/gdbus-tool.c:222 ../gio/gdbus-tool.c:294 +#: ../gio/gdbus-tool.c:318 ../gio/gdbus-tool.c:701 ../gio/gdbus-tool.c:1020 +#: ../gio/gdbus-tool.c:1453 +#, c-format +msgid "Error: %s\n" +msgstr "പിശകàµ: %s\n" + +#: ../gio/gdbus-tool.c:177 ../gio/gdbus-tool.c:235 ../gio/gdbus-tool.c:1469 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to the system bus" +msgstr "സിസàµà´±àµà´±à´‚ ബസിലേകàµà´•àµàµ കണകàµà´Ÿàµ ചെയàµà´¯àµà´•" + +#: ../gio/gdbus-tool.c:353 +msgid "Connect to the session bus" +msgstr "സെഷനàµâ€ ബസിലേകàµà´•àµàµ കണകàµà´Ÿàµ ചെയàµà´¯àµà´•" + +#: ../gio/gdbus-tool.c:354 +msgid "Connect to given D-Bus address" +msgstr "നലàµâ€à´•ിയിരിയàµà´•àµà´•àµà´¨àµà´¨ à´¡à´¿-ബസൠവിലാസതàµà´¤à´¿à´²àµ‡à´•àµà´•àµàµ കണകàµà´Ÿàµ ചെയàµà´¯àµà´•" + +#: ../gio/gdbus-tool.c:364 +msgid "Connection Endpoint Options:" +msgstr "കണകàµà´·à´¨àµâ€ à´Žà´¨àµâ€à´¡àµà´ªàµ‹à´¯à´¿à´¨àµà´±àµ à´à´šàµà´›à´¿à´•à´™àµà´™à´³àµâ€:" + +#: ../gio/gdbus-tool.c:365 +msgid "Options specifying the connection endpoint" +msgstr "കണകàµà´·à´¨àµâ€ à´Žà´¨àµâ€à´¡àµà´ªàµ‹à´¯à´¿à´¨àµà´±àµ നിഷàµà´•à´°àµâ€à´·à´¿à´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµà´³àµà´³ à´à´šàµà´›à´¿à´•à´™àµà´™à´³àµâ€" + +#: ../gio/gdbus-tool.c:387 +#, c-format +msgid "No connection endpoint specified" +msgstr "ഒരൠകണകàµà´·à´¨àµâ€ à´Žà´¨àµâ€à´¡àµà´ªàµ‹à´¯à´¿à´¨àµà´±àµà´‚ നലàµâ€à´•ിയിടàµà´Ÿà´¿à´²àµà´²" + +#: ../gio/gdbus-tool.c:397 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "അനവധി കണകàµà´·à´¨àµâ€ à´Žà´¨àµâ€à´¡àµà´ªàµ‹à´¯à´¿à´¨àµà´±àµà´•à´³àµâ€ നലàµâ€à´•ിയിരിയàµà´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gdbus-tool.c:467 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:476 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:538 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:539 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:540 +msgid "Signal and interface name" +msgstr "സിഗàµà´¨à´²àµà´‚ ഇനàµà´±à´°àµâ€à´«àµ†à´¯à´¿à´¸àµ നാമവàµà´‚" + +#: ../gio/gdbus-tool.c:572 +msgid "Emit a signal." +msgstr "ഒരൠസിഗàµà´¨à´²àµâ€ നലàµâ€à´•àµà´•." + +#: ../gio/gdbus-tool.c:606 ../gio/gdbus-tool.c:832 ../gio/gdbus-tool.c:1559 +#: ../gio/gdbus-tool.c:1791 +#, c-format +msgid "Error connecting: %s\n" +msgstr "കണകàµà´Ÿàµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s\n" + +#: ../gio/gdbus-tool.c:618 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "പിശകàµ: à´’à´¬àµà´œà´•àµà´Ÿàµ പാഥൠനിഷàµà´•à´°àµâ€à´·à´¿à´šàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´².\n" + +#: ../gio/gdbus-tool.c:623 ../gio/gdbus-tool.c:893 ../gio/gdbus-tool.c:1617 +#: ../gio/gdbus-tool.c:1850 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "പിശകàµ: %s ശരിയായൊരൠഒബàµà´œà´•àµà´Ÿàµ പാഥലàµà´²\n" + +#: ../gio/gdbus-tool.c:629 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "പിശകàµ: സിഗàµà´¨à´²àµâ€ നിഷàµà´•à´°àµâ€à´·à´¿à´šàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´².\n" + +#: ../gio/gdbus-tool.c:636 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:644 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "'%s' തെറàµà´±à´¾à´¯ നാമം ആകàµà´¨àµà´¨àµ" + +#: ../gio/gdbus-tool.c:650 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "'%s' തെറàµà´±à´¾à´¯ നാമം ആകàµà´¨àµà´¨àµ" + +#: ../gio/gdbus-tool.c:656 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "'%s' തെറàµà´±à´¾à´¯ നാമം ആകàµà´¨àµà´¨àµ" + +#: ../gio/gdbus-tool.c:679 ../gio/gdbus-tool.c:992 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%d പരാമീറàµà´±à´°àµâ€ പാഴàµà´¸àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s\n" + +#: ../gio/gdbus-tool.c:708 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "കണകàµà´·à´¨àµâ€ à´«àµà´²à´·àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s\n" + +#: ../gio/gdbus-tool.c:735 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:736 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:737 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:738 +msgid "Timeout in seconds" +msgstr "സമയപരിധി സെകàµà´•à´¨àµâ€à´¡àµà´•ളിലàµâ€" + +#: ../gio/gdbus-tool.c:777 +msgid "Invoke a method on a remote object." +msgstr "ഒരൠവിദൂര വസàµà´¤àµà´µà´¿à´²àµâ€ ഒരൠമാരàµâ€à´—àµà´—à´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´•." + +#: ../gio/gdbus-tool.c:852 ../gio/gdbus-tool.c:1578 ../gio/gdbus-tool.c:1810 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "പിശകàµ: ലകàµà´·àµà´¯à´‚ നിഷàµà´•à´°àµâ€à´·à´¿à´šàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´²\n" + +#: ../gio/gdbus-tool.c:873 ../gio/gdbus-tool.c:1597 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "പിശകàµ: à´’à´¬àµà´œà´•àµà´Ÿàµ നാമം നലàµâ€à´•ിയിടàµà´Ÿà´¿à´²àµà´²\n" + +#: ../gio/gdbus-tool.c:908 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "പിശകàµ: മാരàµâ€à´—àµà´— നാമം നിഷàµà´•à´°àµâ€à´·à´¿à´šàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´²\n" + +#: ../gio/gdbus-tool.c:919 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "പിശകàµ: മാരàµâ€à´—àµà´—ൠനാമം '%s' അസാധàµ\n" + +#: ../gio/gdbus-tool.c:984 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "ഡയറകàµà´Ÿà´±à´¿ '%s' à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gdbus-tool.c:1416 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1417 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1418 +msgid "Print XML" +msgstr "à´Žà´•àµà´¸àµà´Žà´‚à´Žà´²àµâ€ à´ªàµà´°à´¿à´¨àµà´±àµ ചെയàµà´¯àµà´•" + +#: ../gio/gdbus-tool.c:1419 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1420 +msgid "Only print properties" +msgstr "à´ªàµà´°à´¿à´¨àµà´±àµ വിശേഷതകളàµâ€ മാതàµà´°à´‚" + +#: ../gio/gdbus-tool.c:1511 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1709 +msgid "Destination name to monitor" +msgstr "നിരീകàµà´·à´¿à´¯àµà´•àµà´•àµà´µà´¾à´¨àµà´³àµà´³ ലകàµà´·àµà´¯ നാമം" + +#: ../gio/gdbus-tool.c:1710 +msgid "Object path to monitor" +msgstr "നിരീകàµà´·à´¿à´¯àµà´•àµà´•àµà´µà´¾à´¨àµà´³àµà´³ à´’à´¬àµà´œà´•àµà´Ÿàµ പാഥàµ" + +#: ../gio/gdbus-tool.c:1743 +msgid "Monitor a remote object." +msgstr "ഒരൠവിദൂര വസàµà´¤àµ നിരീകàµà´·à´¿à´¯àµà´•àµà´•àµà´•." + +#: ../gio/gdesktopappinfo.c:625 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "പേരിടാതàµà´¤" + +#: ../gio/gdesktopappinfo.c:1038 +msgid "Desktop file didn't specify Exec field" +msgstr "പണിയിട ഫയലàµâ€ Exec ഫീളàµâ€à´¡àµ à´µàµà´¯à´•àµà´¤à´®à´¾à´•àµà´•ിയിടàµà´Ÿà´¿à´²àµà´²" + +#: ../gio/gdesktopappinfo.c:1326 +msgid "Unable to find terminal required for application" +msgstr "à´ªàµà´°à´¯àµ‹à´—à´¤àµà´¤à´¿à´¨àµàµ ആവശàµà´¯à´®à´¾à´¯ ടെരàµâ€à´®à´¿à´¨à´²àµâ€ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gdesktopappinfo.c:1628 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" +"ഉപയോകàµà´¤à´¾à´µà´¿à´¨àµàµ à´ªàµà´°à´¯àµ‹à´—à´¤àµà´¤à´¿à´¨àµà´³àµà´³ à´•àµà´°à´®àµ€à´•à´°à´£ ഫോളàµâ€à´¡à´°àµâ€ %s ഉണàµà´Ÿà´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: " +"%s" + +#: ../gio/gdesktopappinfo.c:1632 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "ഉപയോകàµà´¤à´¾à´µà´¿à´¨àµà´³àµà´³ MIME à´•àµà´°à´®à´¿à´•à´°à´£ ഫയലàµâ€ %s ഉണàµà´Ÿà´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²: %s" + +#: ../gio/gdesktopappinfo.c:1872 ../gio/gdesktopappinfo.c:1896 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2128 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "ഉപയോകàµà´¤à´¾à´µà´¿à´¨àµà´³àµà´³ à´¡à´¸àµà´•àµà´Ÿàµ‹à´ªàµà´ªàµ ഫയലàµâ€ %s ഉണàµà´Ÿà´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/gdesktopappinfo.c:2252 +#, c-format +msgid "Custom definition for %s" +msgstr "യഥേഷàµà´Ÿà´‚ %s നിഷàµà´•à´°àµâ€à´·à´¿à´•àµà´•àµà´•" + +#: ../gio/gdrive.c:394 +msgid "drive doesn't implement eject" +msgstr "à´¡àµà´°àµˆà´µàµ eject à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµà´²" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:472 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "à´¡àµà´°àµˆà´µà´¿à´²àµâ€ നിനàµà´¨àµà´‚ eject à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ eject_with_operation സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gdrive.c:548 +msgid "drive doesn't implement polling for media" +msgstr "à´¡àµà´°àµˆà´µà´¿à´²àµâ€ മീഡിയ തെരഞàµà´žàµ†à´Ÿàµà´•àµà´•à´²àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gdrive.c:753 +msgid "drive doesn't implement start" +msgstr "à´¡àµà´°àµˆà´µà´°àµâ€ start à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµà´²" + +#: ../gio/gdrive.c:855 +msgid "drive doesn't implement stop" +msgstr "à´¡àµà´°àµˆà´µà´°àµâ€ stop à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµà´²" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "à´Ÿà´¿à´Žà´²àµâ€à´Žà´¸àµ പിനàµà´¤àµà´£ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem à´Žà´¨àµâ€à´•ോഡിങിനàµà´³àµà´³ പതിപàµà´ªàµàµ %d കൈകാരàµà´¯à´‚ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem à´Žà´¨àµâ€à´•ോഡിങിലàµà´³àµà´³ തെറàµà´±à´¾à´¯ ടോകàµà´•à´¨àµà´•à´³àµà´Ÿàµ† à´Žà´£àµà´£à´‚ (%d)" + +#: ../gio/gemblemedicon.c:367 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" +"GEmblemedIcon à´Žà´¨àµâ€à´•ോഡിങിനàµà´³àµà´³ പതിപàµà´ªàµàµ %d കൈകാരàµà´¯à´‚ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gemblemedicon.c:377 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon à´Žà´¨àµâ€à´•ോഡിങിലàµà´³àµà´³ തെറàµà´±à´¾à´¯ ടോകàµà´•à´¨àµà´•à´³àµà´Ÿàµ† à´Žà´£àµà´£à´‚ (%d)" + +#: ../gio/gemblemedicon.c:400 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon-à´¨àµàµ ഒരൠGEmblem à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´šàµ" + +#: ../gio/gfile.c:917 ../gio/gfile.c:1156 ../gio/gfile.c:1295 +#: ../gio/gfile.c:1535 ../gio/gfile.c:1590 ../gio/gfile.c:1648 +#: ../gio/gfile.c:1732 ../gio/gfile.c:1789 ../gio/gfile.c:1853 +#: ../gio/gfile.c:1908 ../gio/gfile.c:3468 ../gio/gfile.c:3523 +#: ../gio/gfile.c:3669 ../gio/gfile.c:3711 ../gio/gfile.c:4113 +#: ../gio/gfile.c:4525 ../gio/gfile.c:4610 ../gio/gfile.c:4700 +#: ../gio/gfile.c:4797 ../gio/gfile.c:4884 ../gio/gfile.c:4985 +#: ../gio/gfile.c:5258 ../gio/gfile.c:5536 ../gio/gfile.c:5590 +#: ../gio/gfile.c:7135 ../gio/gfile.c:7225 ../gio/gfile.c:7309 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "à´ªàµà´°à´•àµà´°à´¿à´¯ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1419 ../gio/glocalfile.c:1096 ../gio/glocalfile.c:1107 +#: ../gio/glocalfile.c:1120 +msgid "Containing mount does not exist" +msgstr "മൌണàµà´Ÿàµ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gfile.c:2474 ../gio/glocalfile.c:2328 +msgid "Can't copy over directory" +msgstr "ഡയറകàµà´Ÿà´±à´¿à´¯à´¿à´²àµâ€ പകരàµâ€à´¤àµà´¤àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gfile.c:2534 +msgid "Can't copy directory over directory" +msgstr "ഒരൠഡയറകàµà´Ÿà´±à´¿à´¯à´¿à´²àµâ€ മറàµà´±àµŠà´°àµ ഡയറകàµà´Ÿà´±à´¿ പകരàµâ€à´¤àµà´¤àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gfile.c:2542 ../gio/glocalfile.c:2337 +msgid "Target file exists" +msgstr "ലകàµà´·àµà´¯à´¸àµà´¥à´¾à´¨à´¤àµà´¤àµà´³àµà´³ ഫയലàµâ€ നിലവിലàµà´£àµà´Ÿàµ" + +#: ../gio/gfile.c:2561 +msgid "Can't recursively copy directory" +msgstr "ആവരàµâ€à´¤àµà´¤à´¿à´šàµà´šàµ ഡയറകàµà´Ÿà´±à´¿ പകരàµâ€à´¤àµà´¤àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gfile.c:2825 +msgid "Splice not supported" +msgstr "à´¸àµà´ªàµà´²àµˆà´¸àµ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gfile.c:2829 +#, c-format +msgid "Error splicing file: %s" +msgstr "ഫയലàµâ€ à´¸àµà´ªàµà´²àµˆà´¸àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gfile.c:2960 +#, fuzzy +#| msgid "Move between mounts not supported" +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"മൌണàµà´Ÿàµ പോയിനàµà´±àµà´•ളിലàµâ€ തമàµà´®à´¿à´²àµâ€ നീകàµà´•à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gfile.c:2964 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: ../gio/gfile.c:2969 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "" + +#: ../gio/gfile.c:3029 +msgid "Can't copy special file" +msgstr "à´ªàµà´°à´¤àµà´¯àµ‡à´• ഫയലàµâ€ പകരàµâ€à´¤àµà´¤àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gfile.c:3659 +msgid "Invalid symlink value given" +msgstr "തെറàµà´±à´¾à´¯ symlink മൂലàµà´²àµà´¯à´‚" + +#: ../gio/gfile.c:3819 +msgid "Trash not supported" +msgstr "ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gfile.c:3870 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ഫയലിനàµà´±àµ† പേരിലàµâ€ '%c' ഉണàµà´Ÿà´¾à´•àµà´µà´¾à´¨àµâ€ പാടിലàµà´²" + +#: ../gio/gfile.c:6258 ../gio/gvolume.c:365 +msgid "volume doesn't implement mount" +msgstr "വോളàµà´¯à´‚ മൌണàµà´Ÿà´¿à´¨àµ† ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gfile.c:6367 +msgid "No application is registered as handling this file" +msgstr "à´ˆ ഫയലàµâ€ കൈകാരàµà´¯à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ ഒരൠപàµà´°à´¯àµ‹à´—à´µàµà´‚ രജിസàµà´Ÿà´°àµâ€ ചെയàµà´¤à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²" + +#: ../gio/gfileenumerator.c:204 +msgid "Enumerator is closed" +msgstr "à´Žà´¨àµà´¯àµ‚മറേറàµà´±à´°àµâ€ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gfileenumerator.c:211 ../gio/gfileenumerator.c:270 +#: ../gio/gfileenumerator.c:367 ../gio/gfileenumerator.c:467 +msgid "File enumerator has outstanding operation" +msgstr "ഫയലàµâ€ à´Žà´¨àµà´¯àµ‚മറേറàµà´±à´°àµâ€ നനàµà´¨à´¾à´¯à´¿ à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gfileenumerator.c:358 ../gio/gfileenumerator.c:458 +msgid "File enumerator is already closed" +msgstr "ഫയലàµâ€ à´Žà´¨àµà´¯àµ‚മറേറàµà´±à´°àµâ€ നിലവിലàµâ€ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gfileicon.c:237 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon à´Žà´¨àµâ€à´•ോഡിങിനàµà´³àµà´³ പതിപàµà´ªàµàµ %d കൈകാരàµà´¯à´‚ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gfileicon.c:247 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon-നിലàµâ€ തെറàµà´±à´¾à´¯ ഡേറàµà´±à´¾" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:400 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:503 +msgid "Stream doesn't support query_info" +msgstr "à´¸àµà´Ÿàµà´°àµ€à´‚ query_info പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gfileinputstream.c:331 ../gio/gfileiostream.c:383 +#: ../gio/gfileoutputstream.c:377 +msgid "Seek not supported on stream" +msgstr "à´¸àµà´Ÿàµà´°àµ€à´®à´¿à´²àµâ€ Seek പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gfileinputstream.c:375 +msgid "Truncate not allowed on input stream" +msgstr "ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ à´¸àµà´Ÿàµà´°àµ€à´®à´¿à´²àµâ€ Truncate à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gfileiostream.c:459 ../gio/gfileoutputstream.c:453 +msgid "Truncate not supported on stream" +msgstr "à´¸àµà´Ÿàµà´°àµ€à´®à´¿à´²àµâ€ Truncate à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "തെറàµà´±à´¾à´¯ ടോകàµà´•à´¨àµà´±àµ† à´Žà´£àµà´£à´‚ (%d)" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "%s à´Žà´¨àµà´¨ à´•àµà´²à´¾à´¸àµ നാമതàµà´¤à´¿à´¨àµàµ à´à´¤àµàµ തരം à´Žà´¨àµà´¨àµàµ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s തരതàµà´¤à´¿à´²àµà´³àµà´³à´¤àµàµ GIcon ഇനàµà´±à´°àµâ€à´«àµ†à´¯à´¿à´¸àµ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "%s തരതàµà´¤à´¿à´²àµà´³àµà´³à´¤àµàµ à´•àµà´²à´¾à´¸àµà´¸àµ ചെയàµà´¤à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "തെറàµà´±à´¾à´¯ പതിപàµà´ªàµàµ: %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "GIcon ഇനàµà´±à´°àµâ€à´«àµ†à´¯à´¿à´¸à´¿à´²àµâ€ %s തരതàµà´¤à´¿à´²àµà´³àµà´³à´µ from_tokens() ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gicon.c:428 +#, fuzzy +#| msgid "Can't handle the supplied version the icon encoding" +msgid "Can't handle the supplied version of the icon encoding" +msgstr "" +"ലഭàµà´¯à´®à´¾à´•àµà´•à´¿à´¯ à´šà´¿à´¹àµà´¨à´‚ à´Žà´¨àµâ€à´•ോഡിങിനàµà´±àµ† പതിപàµà´ªàµ കൈകാരàµà´¯à´‚ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/ginetaddressmask.c:184 +msgid "No address specified" +msgstr "വിലാസം നലàµâ€à´•ിയിടàµà´Ÿà´¿à´²àµà´²" + +#: ../gio/ginetaddressmask.c:192 +#, c-format +msgid "Length %u is too long for address" +msgstr "à´µàµà´¯à´¾à´ªàµà´¤à´¿ %u വിലാസതàµà´¤à´¿à´¨àµàµ വളരെ വലàµà´¤àµàµ" + +#: ../gio/ginetaddressmask.c:225 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: ../gio/ginetaddressmask.c:304 +#, c-format +#| msgid "could not get local address: %s" +msgid "Could not parse '%s' as IP address mask" +msgstr "à´à´ªà´¿ വിലാസ മാസàµà´•ായി '%s' പാഴàµà´¸àµ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/ginetsocketaddress.c:206 ../gio/ginetsocketaddress.c:223 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "സോകàµà´•à´±àµà´±àµ വിലാസതàµà´¤à´¿à´¨àµàµ ആവശàµà´¯à´®àµà´³àµà´³ à´¸àµà´¥à´²à´‚ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/ginetsocketaddress.c:238 +msgid "Unsupported socket address" +msgstr "പിനàµà´¤àµà´£à´¯à´¿à´²àµà´²à´¾à´¤àµà´¤ സോകàµà´•à´±àµà´±àµ വിലാസം" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ à´¸àµà´Ÿàµà´°àµ€à´‚ read ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1033 ../gio/giostream.c:301 +#: ../gio/goutputstream.c:1344 +msgid "Stream has outstanding operation" +msgstr "à´¸àµà´Ÿàµà´°àµ€à´®à´¿à´²àµâ€ തെറàµà´±à´¾à´¯ à´ªàµà´°à´•àµà´°à´¿à´¯" + +#: ../gio/glib-compile-resources.c:145 ../gio/glib-compile-schemas.c:1459 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "എലമെനàµà´±àµ <%s>, <%s>-à´¨àµà´³àµà´³à´¿à´²àµâ€ à´…à´¨àµà´µà´¦à´¿à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/glib-compile-resources.c:149 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "എലമെനàµà´±àµ <%s> ടോപàµà´ªàµâ€Œà´²à´µà´²à´¿à´²àµâ€ à´…à´¨àµà´µà´¦à´¿à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/glib-compile-resources.c:239 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "ഫയലàµâ€ %s റിസോഴàµà´¸à´¿à´²àµâ€ അനവധി സമയം ലഭàµà´¯à´®à´¾à´•àµà´¨àµà´¨àµ" + +#: ../gio/glib-compile-resources.c:252 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "ഒരൠസോഴàµà´¸àµ ഡയറകàµà´Ÿà´±à´¿à´¯à´¿à´²àµà´‚ '%s' à´•à´£àµà´Ÿàµà´ªà´¿à´Ÿà´¿à´¯àµà´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/glib-compile-resources.c:263 +#, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to locate '%s' in current directory" +msgstr "നിലവിലàµà´³àµà´³ ഡയറകàµà´Ÿà´±à´¿à´¯à´¿à´²àµâ€ '%s' à´•à´£àµà´Ÿàµà´ªà´¿à´Ÿà´¿à´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ" + +#: ../gio/glib-compile-resources.c:291 +#, c-format +#| msgid "Unknown option %s" +msgid "Unknown processing option \"%s\"" +msgstr "അപരിചിതമായ à´ªàµà´°à´•àµà´°à´¿à´¯ à´à´šàµà´›à´¿à´•à´‚ \"%s\"" + +#: ../gio/glib-compile-resources.c:310 ../gio/glib-compile-resources.c:370 +#, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to create temp file: %s" +msgstr "താലàµâ€à´•àµà´•ാലിക ഫയലàµâ€ തയàµà´¯à´¾à´±à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../gio/glib-compile-resources.c:340 +#, c-format +#| msgid "Error seeking in file: %s" +msgid "" +"Error processing input file with xmllint:\n" +"%s" +msgstr "" +"xmllint-നൊപàµà´ªà´‚ ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ ഫയലàµâ€ നടപàµà´ªà´¿à´²à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ:\n" +"%s" + +#: ../gio/glib-compile-resources.c:396 +#, c-format +msgid "" +"Error processing input file with to-pixdata:\n" +"%s" +msgstr "" +"to-pixdata-നൊപàµà´ªà´‚ ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ ഫയലàµâ€ നടപàµà´ªà´¿à´²à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ:\n" +"%s" + +#: ../gio/glib-compile-resources.c:410 +#, c-format +#| msgid "Error reading file '%s': %s" +msgid "Error reading file %s: %s" +msgstr "%s ഫയലàµâ€ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/glib-compile-resources.c:430 +#, c-format +#| msgid "Error closing file: %s" +msgid "Error compressing file %s" +msgstr "ഫയലàµâ€ %s à´•à´‚à´ªàµà´°à´¸àµà´¸àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ" + +#: ../gio/glib-compile-resources.c:494 ../gio/glib-compile-schemas.c:1571 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s>-à´²àµâ€ വാചകം ഒരൠപകàµà´·àµ‡ " + +#: ../gio/glib-compile-resources.c:619 +msgid "name of the output file" +msgstr "" + +#: ../gio/glib-compile-resources.c:619 ../gio/glib-compile-resources.c:650 +#: ../gio/gresource-tool.c:482 ../gio/gresource-tool.c:548 +#| msgid "[FILE...]" +msgid "FILE" +msgstr "FILE" + +#: ../gio/glib-compile-resources.c:620 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" + +#: ../gio/glib-compile-resources.c:620 ../gio/glib-compile-schemas.c:1999 +#: ../gio/glib-compile-schemas.c:2028 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-resources.c:621 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: ../gio/glib-compile-resources.c:622 +msgid "Generate source header" +msgstr "" + +#: ../gio/glib-compile-resources.c:623 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" + +#: ../gio/glib-compile-resources.c:624 +msgid "Generate dependency list" +msgstr "" + +#: ../gio/glib-compile-resources.c:625 +msgid "Don't automatically create and register resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:626 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: ../gio/glib-compile-resources.c:627 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: ../gio/glib-compile-resources.c:653 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: ../gio/glib-compile-resources.c:669 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:778 +msgid "empty names are not permitted" +msgstr "കാലി നാമങàµà´™à´³àµâ€ à´…à´¨àµà´µà´¦à´¿à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/glib-compile-schemas.c:788 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:800 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:809 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:818 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:921 +msgid "cannot add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:932 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:950 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:961 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:980 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:995 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "തെറàµà´±à´¾à´¯ GVariant തരതàµà´¤à´¿à´²àµà´³àµà´³ à´¸àµà´Ÿàµà´°à´¿à´™àµ '%s'" + +#: ../gio/glib-compile-schemas.c:1025 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1038 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1046 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1117 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1129 +#, c-format +msgid " extends not-yet-existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1145 +#, c-format +msgid " is list of not-yet-existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1153 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1173 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1183 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1200 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1207 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1239 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1463 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1757 ../gio/glib-compile-schemas.c:1828 +#: ../gio/glib-compile-schemas.c:1904 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1765 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1824 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1864 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1870 ../gio/glib-compile-schemas.c:1928 +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1874 ../gio/glib-compile-schemas.c:1932 +#: ../gio/glib-compile-schemas.c:1960 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1900 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1918 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1946 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1999 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2000 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2001 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2002 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:2047 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2086 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2089 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2092 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:252 +msgid "Unable to find default local directory monitor type" +msgstr "" +"à´¸àµà´µà´¤à´µàµ‡à´¯àµà´³àµà´³ ലോകàµà´•à´²àµâ€ ഡയറകàµà´Ÿà´±à´¿ തരതàµà´¤à´¿à´²àµà´³àµà´³ മോണിറàµà´±à´°àµâ€ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ " +"സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/glocalfile.c:597 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "തെറàµà´±à´¾à´¯ ഫയലàµâ€ നാമം %s " + +#: ../gio/glocalfile.c:974 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ഫയലàµâ€à´¸à´¿à´¸àµà´±àµà´±à´‚ വിവരം ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfile.c:1142 +msgid "Can't rename root directory" +msgstr "റൂടàµà´Ÿàµ ഡയറകàµà´Ÿà´±à´¿à´¯àµà´Ÿàµ† പേരൠമാറàµà´±àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/glocalfile.c:1162 ../gio/glocalfile.c:1188 +#, c-format +msgid "Error renaming file: %s" +msgstr "ഫയലിനàµà´±àµ† പേരൠമാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfile.c:1171 +msgid "Can't rename file, filename already exists" +msgstr "ഫയലിനàµà´±àµ† പേരàµàµ മാറàµà´±àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´², പേരàµàµ നിലവിലàµà´£àµà´Ÿàµàµ" + +#: ../gio/glocalfile.c:1184 ../gio/glocalfile.c:2201 ../gio/glocalfile.c:2230 +#: ../gio/glocalfile.c:2390 ../gio/glocalfileoutputstream.c:575 +#: ../gio/glocalfileoutputstream.c:628 ../gio/glocalfileoutputstream.c:673 +#: ../gio/glocalfileoutputstream.c:1161 +msgid "Invalid filename" +msgstr "തെറàµà´±à´¾à´¯ ഫയലàµâ€à´¨à´¾à´®à´‚" + +#: ../gio/glocalfile.c:1351 ../gio/glocalfile.c:1375 +msgid "Can't open directory" +msgstr "ഡയറകàµà´Ÿà´±à´¿ à´¤àµà´±à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/glocalfile.c:1359 +#, c-format +msgid "Error opening file: %s" +msgstr "ഫയലàµâ€ à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/glocalfile.c:1500 +#, c-format +msgid "Error removing file: %s" +msgstr "ഫയലàµâ€ നീകàµà´•à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfile.c:1880 +#, c-format +msgid "Error trashing file: %s" +msgstr "ഫയലàµâ€ ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿà´¯à´¿à´²àµ‡à´•àµà´•àµàµ മാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfile.c:1903 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿà´¯àµà´•àµà´•àµà´³àµà´³ ഡയറകàµà´Ÿà´±à´¿ %s ഉണàµà´Ÿà´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²: %s" + +#: ../gio/glocalfile.c:1924 +msgid "Unable to find toplevel directory for trash" +msgstr "ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿà´¯àµà´•àµà´•àµà´³àµà´³ ടോപൠലവലàµâ€ ഡയറകàµà´Ÿà´±à´¿ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/glocalfile.c:2003 ../gio/glocalfile.c:2023 +msgid "Unable to find or create trash directory" +msgstr "" +"ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿà´¯àµà´•àµà´•àµà´³àµà´³ ഡയറകàµà´Ÿà´±à´¿ ഉണàµà´Ÿà´¾à´•àµà´•àµà´µà´¾à´¨àµ‹ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµ‹ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/glocalfile.c:2057 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "വിവരങàµà´™à´³àµâ€ സംബനàµà´§à´¿à´šàµà´šàµà´³àµà´³ ഫയലàµâ€ ഉണàµà´Ÿà´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²: %s" + +#: ../gio/glocalfile.c:2086 ../gio/glocalfile.c:2091 ../gio/glocalfile.c:2171 +#: ../gio/glocalfile.c:2178 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ഫയലàµâ€ ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿà´¯à´¿à´²àµ‡à´•àµà´•ൠനീകàµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²: %s" + +#: ../gio/glocalfile.c:2179 ../glib/gregex.c:280 +msgid "internal error" +msgstr "ആനàµà´¤à´°à´¿à´• പിശകàµ" + +#: ../gio/glocalfile.c:2205 +#, c-format +msgid "Error creating directory: %s" +msgstr "ഡയറകàµà´Ÿà´±à´¿ ഉണàµà´Ÿà´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfile.c:2234 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ഫയലàµâ€à´¸à´¿à´¸àµà´±àµà´±à´‚ സിബോളികàµà´•ൠലിങàµà´•ൠപിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/glocalfile.c:2238 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "സിംബോളികൠലിങàµà´•ൠഉണàµà´Ÿà´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfile.c:2300 ../gio/glocalfile.c:2394 +#, c-format +msgid "Error moving file: %s" +msgstr "ഫയലàµâ€ നീകàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfile.c:2323 +msgid "Can't move directory over directory" +msgstr "ഒരൠഡയറകàµà´Ÿà´±à´¿à´¯à´¿à´²àµâ€ മറàµà´±àµŠà´°àµ ഡയറകàµà´Ÿà´±à´¿ നീകàµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/glocalfile.c:2350 ../gio/glocalfileoutputstream.c:959 +#: ../gio/glocalfileoutputstream.c:973 ../gio/glocalfileoutputstream.c:988 +#: ../gio/glocalfileoutputstream.c:1004 ../gio/glocalfileoutputstream.c:1018 +msgid "Backup file creation failed" +msgstr "ബാകàµà´•à´ªàµà´ªàµ ഫയലàµâ€ ഉണàµà´Ÿà´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം" + +#: ../gio/glocalfile.c:2369 +#, c-format +msgid "Error removing target file: %s" +msgstr "ലകàµà´·àµà´¯à´¸àµà´¥à´¾à´¨à´¤àµà´¤àµà´³àµà´³ ഫയലàµâ€ നീകàµà´•à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfile.c:2383 +msgid "Move between mounts not supported" +msgstr "" +"മൌണàµà´Ÿàµ പോയിനàµà´±àµà´•ളിലàµâ€ തമàµà´®à´¿à´²àµâ€ നീകàµà´•à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/glocalfileinfo.c:722 +msgid "Attribute value must be non-NULL" +msgstr "ആടàµà´°à´¿à´¬àµà´¯àµ‚à´Ÿàµà´Ÿàµ മൂലàµà´²àµà´¯à´‚ non-NULL ആയിരികàµà´•ണം" + +#: ../gio/glocalfileinfo.c:729 +msgid "Invalid attribute type (string expected)" +msgstr "തെറàµà´±à´¾à´¯ ആടàµà´°à´¿à´¬àµà´¯àµ‚à´Ÿàµà´Ÿàµ തരം (à´¸àµà´Ÿàµà´°à´¿à´™àµ à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´šàµ)" + +#: ../gio/glocalfileinfo.c:736 +msgid "Invalid extended attribute name" +msgstr "തെറàµà´±à´¾à´¯ à´Žà´•àµà´¸àµà´±àµà´±àµ†à´¨àµâ€à´¡à´Ÿàµ ആടàµà´°à´¿à´¬àµà´¯àµ‚à´Ÿàµà´Ÿàµ നാമം" + +#: ../gio/glocalfileinfo.c:776 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "à´Žà´•àµà´¸àµà´±àµà´±àµ†à´¨àµâ€à´¡à´Ÿàµ ആടàµà´°à´¿à´¬àµà´¯àµ‚à´Ÿàµà´Ÿàµ ആയ '%s' à´•àµà´°à´®à´¿à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinfo.c:1548 +msgid " (invalid encoding)" +msgstr " (തെറàµà´±à´¾à´¯ à´Žà´¨àµâ€à´•ോഡിങàµ)" + +#: ../gio/glocalfileinfo.c:1740 ../gio/glocalfileoutputstream.c:837 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "'%s' ഫയലിനàµà´³àµà´³ വിവരം ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinfo.c:1986 +#, c-format +#| msgid "Error stating file descriptor: %s" +msgid "Error when getting information for file descriptor: %s" +msgstr "ഫയലàµâ€ വിശദീകരണ സംവിധാനം ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinfo.c:2031 +msgid "Invalid attribute type (uint32 expected)" +msgstr "തെറàµà´±à´¾à´¯ തരതàµà´¤à´¿à´²àµà´³àµà´³ വിശേഷത (uint32 à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´š)" + +#: ../gio/glocalfileinfo.c:2049 +msgid "Invalid attribute type (uint64 expected)" +msgstr "തെറàµà´±à´¾à´¯ തരതàµà´¤à´¿à´²àµà´³àµà´³ വിശേഷത (uint64 à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´š)" + +#: ../gio/glocalfileinfo.c:2068 ../gio/glocalfileinfo.c:2087 +msgid "Invalid attribute type (byte string expected)" +msgstr "തെറàµà´±à´¾à´¯ തരതàµà´¤à´¿à´²àµà´³àµà´³ വിശേഷത (ബൈറàµà´±àµ à´¸àµà´Ÿàµà´°à´¿à´™àµ à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´š)" + +#: ../gio/glocalfileinfo.c:2122 +msgid "Cannot set permissions on symlinks" +msgstr "സിംലിങàµà´•àµà´•à´³àµâ€à´•àµà´•àµà´³àµà´³ à´…à´¨àµà´®à´¤à´¿à´•à´³àµâ€ സജàµà´œà´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/glocalfileinfo.c:2138 +#, c-format +msgid "Error setting permissions: %s" +msgstr "à´…à´¨àµà´µà´¾à´¦à´™àµà´™à´³àµâ€ à´•àµà´°à´®à´¿à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinfo.c:2189 +#, c-format +msgid "Error setting owner: %s" +msgstr "ഉടമസàµà´¥à´¨àµ† à´•àµà´°à´®à´¿à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinfo.c:2212 +msgid "symlink must be non-NULL" +msgstr "സിംലിങàµà´•ൠnon-NULL ആയിരികàµà´•ണം" + +#: ../gio/glocalfileinfo.c:2222 ../gio/glocalfileinfo.c:2241 +#: ../gio/glocalfileinfo.c:2252 +#, c-format +msgid "Error setting symlink: %s" +msgstr "സിംലിങàµà´•ൠകàµà´°à´®à´¿à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinfo.c:2231 +msgid "Error setting symlink: file is not a symlink" +msgstr "symlink സജàµà´œàµ€à´•രണതàµà´¤à´¿à´²àµâ€ പിശകàµ: ഫയലàµâ€ ഒരൠsymlink à´…à´²àµà´²" + +#: ../gio/glocalfileinfo.c:2357 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "മാറàµà´±à´™àµà´™à´³àµâ€ à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ ആകàµà´¸à´¸àµ സമയം സജàµà´œà´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinfo.c:2380 +msgid "SELinux context must be non-NULL" +msgstr "SELinux കോണàµâ€à´Ÿàµ†à´•àµà´¸àµà´±àµà´±àµ non-NULL ആയിരികàµà´•ണം" + +#: ../gio/glocalfileinfo.c:2395 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux കോണàµâ€à´Ÿàµ†à´•àµà´¸àµà´±àµà´±àµ സജàµà´œà´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinfo.c:2402 +msgid "SELinux is not enabled on this system" +msgstr "SELinux à´ˆ സിസàµà´±àµà´±à´¤àµà´¤à´¿à´²àµâ€ സജàµà´œà´®à´²àµà´²" + +#: ../gio/glocalfileinfo.c:2494 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s ആടàµà´°à´¿à´¬àµà´¯àµ‚à´Ÿàµà´Ÿàµ à´•àµà´°à´®à´¿à´•രണം പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/glocalfileinputstream.c:186 ../gio/glocalfileoutputstream.c:726 +#, c-format +msgid "Error reading from file: %s" +msgstr "ഫയലിലàµâ€ നിനàµà´¨àµà´‚ വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileinputstream.c:217 ../gio/glocalfileinputstream.c:229 +#: ../gio/glocalfileinputstream.c:336 ../gio/glocalfileoutputstream.c:464 +#: ../gio/glocalfileoutputstream.c:1036 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ഫയലിലàµâ€ തിരയàµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/glocalfileinputstream.c:258 ../gio/glocalfileoutputstream.c:254 +#: ../gio/glocalfileoutputstream.c:348 +#, c-format +msgid "Error closing file: %s" +msgstr "ഫയലàµâ€ à´…à´Ÿà´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/glocalfilemonitor.c:176 +msgid "Unable to find default local file monitor type" +msgstr "" +"à´¸àµà´µà´¤à´µàµ‡à´¯àµà´³àµà´³ ലോകàµà´•à´²àµâ€ ഫയലàµâ€ മോണിറàµà´±à´°àµâ€ തരതàµà´¤à´¿à´²àµà´³àµà´³à´¤àµàµ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ " +"സാധിചàµà´šà´¿à´²àµà´²" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:234 +#: ../gio/glocalfileoutputstream.c:747 +#, c-format +msgid "Error writing to file: %s" +msgstr "ഫയലിലേകàµà´•ൠഎഴàµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileoutputstream.c:281 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "പഴയ ബാകàµà´•à´ªàµà´ªà´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ ലിങàµà´•ൠനീകàµà´•à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileoutputstream.c:295 ../gio/glocalfileoutputstream.c:308 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "ബാകàµà´•à´ªàµà´ªàµ പകരàµâ€à´ªàµà´ªàµ ഉണàµà´Ÿà´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileoutputstream.c:326 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "താലàµâ€à´•àµà´•ാലിക ഫയലിനàµà´±àµ† പേരൠമാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileoutputstream.c:510 ../gio/glocalfileoutputstream.c:1087 +#, c-format +msgid "Error truncating file: %s" +msgstr "ഫയലàµâ€ à´Ÿàµà´°à´™àµâ€Œà´•േറàµà´±àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileoutputstream.c:581 ../gio/glocalfileoutputstream.c:634 +#: ../gio/glocalfileoutputstream.c:679 ../gio/glocalfileoutputstream.c:819 +#: ../gio/glocalfileoutputstream.c:1068 ../gio/glocalfileoutputstream.c:1167 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "'%s' ഫയലàµâ€ à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/glocalfileoutputstream.c:850 +msgid "Target file is a directory" +msgstr "ലകàµà´·àµà´¯à´¸àµà´¥à´¾à´¨à´¤àµà´¤àµà´³àµà´³ ഫയലàµâ€ ഒരൠഡയറകàµà´Ÿà´±à´¿ ആകàµà´¨àµà´¨àµ" + +#: ../gio/glocalfileoutputstream.c:855 +msgid "Target file is not a regular file" +msgstr "ലകàµà´·àµà´¯à´¸àµà´¥à´¾à´¨à´¤àµà´¤àµà´³àµà´³ ഫയലàµâ€ ഒരൠസാധാരണ ഫയലàµâ€ à´…à´²àµà´²" + +#: ../gio/glocalfileoutputstream.c:867 +msgid "The file was externally modified" +msgstr "ഫയലàµâ€ à´ªàµà´±à´®àµ‡ നിനàµà´¨àµà´‚ മാറàµà´±à´‚ വരàµà´¤àµà´¤à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/glocalfileoutputstream.c:1052 +#, c-format +msgid "Error removing old file: %s" +msgstr "പഴയ ഫയലàµâ€ നീകàµà´•à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gmemoryinputstream.c:476 ../gio/gmemoryoutputstream.c:739 +msgid "Invalid GSeekType supplied" +msgstr "തെറàµà´±à´¾à´¯ GSeekType നലàµâ€à´•ിയിരികàµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gmemoryinputstream.c:486 +msgid "Invalid seek request" +msgstr "തെറàµà´±à´¾à´¯ seek ആവശàµà´¯à´ªàµà´ªàµ†à´Ÿàµà´Ÿà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gmemoryinputstream.c:510 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream à´Ÿàµà´°à´™àµâ€Œà´•േറàµà´±àµ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gmemoryoutputstream.c:544 +msgid "Memory output stream not resizable" +msgstr "മെമàµà´®à´±à´¿ ഔടàµà´Ÿàµà´ªàµà´Ÿàµà´Ÿàµ à´¸àµà´Ÿàµà´°àµ€à´®à´¿à´¨àµà´±àµ† à´µàµà´¯à´¾à´ªàµà´¤à´¿ മാറàµà´±àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gmemoryoutputstream.c:560 +msgid "Failed to resize memory output stream" +msgstr "മെമàµà´®à´±à´¿ ഔടàµà´Ÿàµà´ªàµà´Ÿàµà´Ÿàµ à´¸àµà´Ÿàµà´°àµ€à´®à´¿à´¨àµà´±àµ† à´µàµà´¯à´¾à´ªàµà´¤à´¿ മാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം" + +#: ../gio/gmemoryoutputstream.c:648 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:749 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:758 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:395 +msgid "mount doesn't implement \"unmount\"" +msgstr "mount 'unmount' à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:471 +msgid "mount doesn't implement \"eject\"" +msgstr "mount 'eject' à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:549 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"'unmount' à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ 'unmount_with_operation', mount à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:634 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "'eject' à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ 'eject_with_operation', mount à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:722 +msgid "mount doesn't implement \"remount\"" +msgstr "mount 'remount' à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:803 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "mount doesn't implement synchronous content type guessing" + +#: ../gio/gnetworkaddress.c:354 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "ഹോസàµà´±àµà´±àµà´¨àµ†à´¯à´¿à´‚ '%s'-à´²àµâ€ '[' but not ']' à´…à´Ÿà´™àµà´™àµà´¨àµà´¨àµ" + +#: ../gio/gnetworkmonitorbase.c:195 ../gio/gnetworkmonitorbase.c:298 +msgid "Network unreachable" +msgstr "" + +#: ../gio/gnetworkmonitorbase.c:233 ../gio/gnetworkmonitorbase.c:263 +msgid "Host unreachable" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:98 ../gio/gnetworkmonitornetlink.c:110 +#: ../gio/gnetworkmonitornetlink.c:129 +#, c-format +#| msgid "could not get remote address: %s" +msgid "Could not create network monitor: %s" +msgstr "നെറàµà´±àµâ€Œà´µà´°àµâ€à´•àµà´•ൠമോണിറàµà´±à´°àµâ€ തയàµà´¯à´¾à´±à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: %s" + +#: ../gio/gnetworkmonitornetlink.c:119 +msgid "Could not create network monitor: " +msgstr "നെറàµà´±àµâ€Œà´µà´°àµâ€à´•àµà´•ൠമോണിറàµà´±à´°àµâ€ തയàµà´¯à´¾à´±à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: " + +#: ../gio/gnetworkmonitornetlink.c:177 +#| msgid "could not get remote address: %s" +msgid "Could not get network status: " +msgstr "നെറàµà´±àµâ€Œà´µà´°àµâ€à´•àµà´•ൠഅലസàµà´¥ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²:" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:464 +msgid "Output stream doesn't implement write" +msgstr "ഔടàµà´Ÿàµà´ªàµà´Ÿàµà´Ÿàµ à´¸àµà´Ÿàµà´°àµ€à´‚ റൈറàµà´±àµ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/goutputstream.c:425 ../gio/goutputstream.c:950 +msgid "Source stream is already closed" +msgstr "സോഴàµà´¸àµ à´¸àµà´Ÿàµà´°àµ€à´‚ നിലവിലàµâ€ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:454 +#: ../gio/gresourcefile.c:555 ../gio/gresourcefile.c:657 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "" + +#: ../gio/gresourcefile.c:653 +#, c-format +#| msgid "Target file is a directory" +msgid "The resource at '%s' is not a directory" +msgstr "'%s'-à´²àµà´³àµà´³ റിസോഴàµà´¸àµ ഒരൠഡയറകàµà´Ÿà´±à´¿à´¯à´²àµà´²" + +#: ../gio/gresourcefile.c:861 +#, fuzzy +#| msgid "Input stream doesn't implement read" +msgid "Input stream doesn't implement seek" +msgstr "ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ à´¸àµà´Ÿàµà´°àµ€à´‚ read ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gresource-tool.c:475 ../gio/gsettings-tool.c:529 +msgid "Print help" +msgstr "à´ªàµà´°à´¿à´¨àµà´±à´¿à´¨àµà´³àµà´³ സഹായം" + +#: ../gio/gresource-tool.c:476 ../gio/gresource-tool.c:544 +msgid "[COMMAND]" +msgstr "" + +#: ../gio/gresource-tool.c:481 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: ../gio/gresource-tool.c:487 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: ../gio/gresource-tool.c:490 ../gio/gresource-tool.c:500 +msgid "FILE [PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:491 ../gio/gresource-tool.c:501 +#: ../gio/gresource-tool.c:508 +msgid "SECTION" +msgstr "" + +#: ../gio/gresource-tool.c:496 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: ../gio/gresource-tool.c:506 +msgid "Extract a resource file to stdout" +msgstr "" + +#: ../gio/gresource-tool.c:507 +msgid "FILE PATH" +msgstr "" + +#: ../gio/gresource-tool.c:513 ../gio/gsettings-tool.c:609 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"അപരിചിതമായ കമാനàµâ€à´¡àµ %s\n" +"\n" + +#: ../gio/gresource-tool.c:521 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:535 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:538 ../gio/gsettings-tool.c:642 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gresource-tool.c:542 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: ../gio/gresource-tool.c:546 ../gio/gsettings-tool.c:649 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gresource-tool.c:552 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: ../gio/gresource-tool.c:555 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: ../gio/gresource-tool.c:559 +msgid "[PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:561 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: ../gio/gresource-tool.c:562 +msgid "PATH" +msgstr "" + +#: ../gio/gresource-tool.c:564 +msgid " PATH A resource path\n" +msgstr "" + +#: ../gio/gsettings-tool.c:57 ../gio/gsettings-tool.c:78 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:63 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:84 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:116 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:137 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:502 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:535 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:541 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:547 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:548 ../gio/gsettings-tool.c:554 +#: ../gio/gsettings-tool.c:591 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:553 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:559 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:561 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:566 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:567 ../gio/gsettings-tool.c:573 +#: ../gio/gsettings-tool.c:585 ../gio/gsettings-tool.c:597 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:572 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:578 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:579 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:584 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:590 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:596 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:602 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:605 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:617 +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:639 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:645 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:653 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:658 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:662 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:666 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:725 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not load schemas from %s: %s\n" +msgstr "'%s'-à´²àµâ€ നിനàµà´¨àµà´‚ '%s'-ലേകàµà´•ൠവേരàµâ€à´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨ സംവിധാനം ലഭàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/gsettings-tool.c:784 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:311 +msgid "Invalid socket, not initialized" +msgstr "തെറàµà´±à´¾à´¯ സോകàµà´•à´±àµà´±àµ, ആരംഭിചàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´²" + +#: ../gio/gsocket.c:318 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "തെറàµà´±à´¾à´¯ സോകàµà´•à´±àµà´±àµ, ആരംഭികàµà´•ാതàµà´¤à´¿à´¤à´¿à´¨àµà´³àµà´³ കാരണം: %s" + +#: ../gio/gsocket.c:326 +msgid "Socket is already closed" +msgstr "സോകàµà´•à´±àµà´±àµ നിലവിലàµâ€ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gsocket.c:334 ../gio/gsocket.c:3525 ../gio/gsocket.c:3580 +msgid "Socket I/O timed out" +msgstr "സോകàµà´•à´±àµà´±àµ à´/à´’ സമയം à´•à´´à´¿â€à´žàµà´žà´¿à´°à´¿à´¯àµà´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gsocket.c:481 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd-à´²àµâ€ നിനàµà´¨àµà´‚ GSocket ഉണàµà´Ÿà´¾à´•àµà´•àµà´¨àµà´¨àµ: %s" + +#: ../gio/gsocket.c:509 ../gio/gsocket.c:563 ../gio/gsocket.c:570 +#, c-format +msgid "Unable to create socket: %s" +msgstr "സോകàµà´•à´±àµà´±àµ ഉണàµà´Ÿà´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: %s" + +#: ../gio/gsocket.c:563 +#, fuzzy +#| msgid "Unknown protocol was specified" +msgid "Unknown family was specified" +msgstr "അപരിചിതമായ കീഴàµà´µà´´à´•àµà´•à´‚ നലàµâ€à´•ിയിരികàµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gsocket.c:570 +msgid "Unknown protocol was specified" +msgstr "അപരിചിതമായ കീഴàµà´µà´´à´•àµà´•à´‚ നലàµâ€à´•ിയിരികàµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gsocket.c:1728 +#, c-format +msgid "could not get local address: %s" +msgstr "ലോകàµà´•à´²àµâ€ വിലാസം ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: %s" + +#: ../gio/gsocket.c:1771 +#, c-format +msgid "could not get remote address: %s" +msgstr "റിമോടàµà´Ÿàµ വിലാസം ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: %s" + +#: ../gio/gsocket.c:1832 +#, c-format +msgid "could not listen: %s" +msgstr "à´¶àµà´°à´¦àµà´§à´¿à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: %s" + +#: ../gio/gsocket.c:1904 +#, c-format +msgid "Error binding to address: %s" +msgstr "വിലാസതàµà´¤à´¿à´²àµ‡à´•àµà´•ൠബൈനàµâ€à´¡àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gsocket.c:1957 ../gio/gsocket.c:1994 +#, fuzzy, c-format +#| msgid "Error launching application: %s" +msgid "Error joining multicast group: %s" +msgstr "à´ªàµà´°à´¯àµ‹à´—à´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gsocket.c:1958 ../gio/gsocket.c:1995 +#, fuzzy, c-format +#| msgid "Error launching application: %s" +msgid "Error leaving multicast group: %s" +msgstr "à´ªàµà´°à´¯àµ‹à´—à´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gsocket.c:1959 +msgid "No support for source-specific multicast" +msgstr "" + +#: ../gio/gsocket.c:2178 +#, c-format +msgid "Error accepting connection: %s" +msgstr "കണകàµà´·à´¨àµâ€ à´¸àµà´µàµ€à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/gsocket.c:2299 +msgid "Connection in progress" +msgstr "കണകàµà´·à´¨àµâ€ à´ªàµà´°àµ‹à´—തിയിലàµâ€" + +#: ../gio/gsocket.c:2346 +#| msgid "Unable to get pending error: %s" +msgid "Unable to get pending error: " +msgstr "ബാകàµà´•à´¿à´¯àµà´³àµà´³ പിശകൠലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: " + +#: ../gio/gsocket.c:2512 +#, c-format +msgid "Error receiving data: %s" +msgstr "ഡേറàµà´±à´¾ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gsocket.c:2690 +#, c-format +msgid "Error sending data: %s" +msgstr "ഡേറàµà´±à´¾ അയയàµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/gsocket.c:2804 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "സോകàµà´•à´±àµà´±àµ à´…à´Ÿà´šàµà´šàµà´ªàµ‚à´Ÿàµà´Ÿàµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: %s" + +#: ../gio/gsocket.c:2883 +#, c-format +msgid "Error closing socket: %s" +msgstr "സോകàµà´•à´±àµà´±àµ à´…à´Ÿà´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/gsocket.c:3518 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "സോകàµà´•à´±àµà´±àµ അവസàµà´¥à´¯àµà´•àµà´•ായി കാതàµà´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ: %s" + +#: ../gio/gsocket.c:3796 ../gio/gsocket.c:3877 +#, c-format +msgid "Error sending message: %s" +msgstr "സനàµà´¦àµ‡à´¶à´‚ അയയàµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#: ../gio/gsocket.c:3821 +#| msgid "GSocketControlMessage not supported on windows" +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage വിനàµâ€à´¡àµ‹à´¸à´¿à´²àµâ€ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gsocket.c:4155 ../gio/gsocket.c:4290 +#, c-format +msgid "Error receiving message: %s" +msgstr "സനàµà´¦àµ‡à´¶à´‚ ലഭികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gsocket.c:4372 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "ബാകàµà´•à´¿à´¯àµà´³àµà´³ പിശകൠലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²: %s" + +#: ../gio/gsocket.c:4391 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:177 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: ../gio/gsocketclient.c:191 +#, c-format +#| msgid "Could not open converter from '%s' to '%s': %s" +msgid "Could not connect to %s: " +msgstr "%s-ലേകàµà´•àµàµ കണകàµà´Ÿàµ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: " + +#: ../gio/gsocketclient.c:193 +#| msgid "could not listen: %s" +msgid "Could not connect: " +msgstr "കണകàµà´Ÿàµ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: " + +#: ../gio/gsocketclient.c:1072 ../gio/gsocketclient.c:1636 +msgid "Unknown error on connect" +msgstr "കണകàµà´Ÿàµ ചെയàµà´¯àµà´®àµà´ªàµ‹à´³àµâ€ അപരിചിതമായ പിശകàµ" + +#: ../gio/gsocketclient.c:1125 ../gio/gsocketclient.c:1574 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" +"ഒരൠടിസിപി à´…à´²àµà´²à´¾à´¤àµà´¤ കണകàµà´·à´¨à´¿à´²àµâ€ à´ªàµà´°àµ‹à´•àµà´¸à´¿ ചെയàµà´¯àµà´¨àµà´¨à´¤àµàµ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²." + +#: ../gio/gsocketclient.c:1151 ../gio/gsocketclient.c:1595 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "'%s' à´ªàµà´°àµ‹à´•àµà´¸à´¿ കീഴàµâ€Œà´µà´´à´•àµà´•à´‚ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²." + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "ലിസണരàµâ€ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "ചേരàµâ€à´¤àµà´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨ സോകàµà´•à´±àµà´±àµ à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gsocks4aproxy.c:120 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:138 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:155 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:181 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:188 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:326 +#: ../gio/gsocks5proxy.c:336 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" + +#: ../gio/gsocks5proxy.c:238 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:288 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "" + +#: ../gio/gsocks5proxy.c:350 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:357 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:363 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:370 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:376 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 à´ªàµà´°àµ‹à´•àµà´¸à´¿ വഴി നെറàµà´±àµâ€Œà´µà´°àµâ€à´•àµà´•ൠലഭàµà´¯à´®à´²àµà´²." + +#: ../gio/gsocks5proxy.c:382 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:388 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:394 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:400 +msgid "Unknown SOCKSv5 proxy error." +msgstr "അപരിചിതമായ SOCKSv5 à´ªàµà´°àµ‹à´•àµà´¸à´¿ സരàµâ€à´µà´°àµâ€." + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon à´Žà´¨àµâ€à´•ോഡിങിനàµà´³àµà´³ %d പതിപàµà´ªàµàµ കൈകാരàµà´¯à´‚ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gthreadedresolver.c:110 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s'പരിഹരികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gthreadedresolver.c:195 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "റിവേഴàµà´¸àµ-റിസോളàµâ€à´µà´¿à´™àµ '%s'-à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gthreadedresolver.c:397 ../gio/gthreadedresolver.c:571 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "" + +#: ../gio/gthreadedresolver.c:402 ../gio/gthreadedresolver.c:576 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "'%s' പരിഹരികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµàµ താലàµâ€à´•àµà´•ാലം സാധàµà´¯à´®à´²àµà´²" + +#: ../gio/gthreadedresolver.c:407 ../gio/gthreadedresolver.c:581 +#, c-format +msgid "Error resolving '%s'" +msgstr "'%s' പരിഹരികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ" + +#: ../gio/gtlscertificate.c:248 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:253 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:263 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:288 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:297 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "നലàµâ€à´•ിയിരിയàµà´•àµà´•àµà´¨àµà´¨ രഹസàµà´¯à´µà´¾à´•àµà´•ൠതെറàµà´±à´¾à´£àµàµ." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:548 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "1 നിയനàµà´¤àµà´°à´£ സനàµà´¦àµ‡à´¶à´‚ à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´•àµà´•àµà´¨àµà´¨àµ, %d ലഭിചàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gunixconnection.c:172 ../gio/gunixconnection.c:558 +msgid "Unexpected type of ancillary data" +msgstr "à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ രീതിയിലàµà´³àµà´³ ആനàµâ€à´¸à´¿à´²à´¿à´¯à´±à´¿ ഡേറàµà´±à´¾" + +#: ../gio/gunixconnection.c:190 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "ഒരൠfd à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´•àµà´•àµà´¨àµà´¨àµ, പകàµà´·àµ‡ %d ലഭിചàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ\n" + +#: ../gio/gunixconnection.c:206 +msgid "Received invalid fd" +msgstr "തെറàµà´±à´¾à´¯ fd ലഭിചàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../gio/gunixconnection.c:342 +msgid "Error sending credentials: " +msgstr "വിവരങàµà´™à´³àµâ€ അയയàµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: " + +#: ../gio/gunixconnection.c:490 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:505 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¨ സജàµà´œà´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gunixconnection.c:534 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:572 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "നിയനàµà´¤àµà´°à´£ സനàµà´¦àµ‡à´¶à´‚ à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´², പകàµà´·àµ‡ ലഭàµà´¯à´®à´¾à´¯à´¤àµàµ %d" + +#: ../gio/gunixconnection.c:596 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:382 ../gio/gunixinputstream.c:403 +#, c-format +#| msgid "Error stating file descriptor: %s" +msgid "Error reading from file descriptor: %s" +msgstr "ഫയലàµâ€ വിശദീകരണ സംവിധാനം ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gunixinputstream.c:436 ../gio/gunixoutputstream.c:422 +#, c-format +#| msgid "Error stating file descriptor: %s" +msgid "Error closing file descriptor: %s" +msgstr "ഫയലàµâ€ വിശദീകരണ സംവിധാനം à´…à´Ÿà´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gunixmounts.c:1983 ../gio/gunixmounts.c:2036 +msgid "Filesystem root" +msgstr "ഫയലàµâ€à´¸à´¿à´¸àµà´±àµà´±à´‚ റൂടàµà´Ÿàµ" + +#: ../gio/gunixoutputstream.c:368 ../gio/gunixoutputstream.c:389 +#, c-format +#| msgid "Error stating file descriptor: %s" +msgid "Error writing to file descriptor: %s" +msgstr "ഫയലàµâ€ വിശദീകരണ സംവിധാനം സൂകàµà´·à´¿à´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gunixsocketaddress.c:244 +#, fuzzy +#| msgid "Abstract unix domain socket addresses not supported on this system" +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"à´ˆ സിസàµà´±àµà´±à´®à´¿à´²àµâ€ à´…à´¬àµà´¸àµà´Ÿàµà´°à´¾à´•àµà´Ÿàµ യൂണികàµà´¸àµ ഡൊമെയിനàµâ€ സോകàµà´•à´±àµà´±àµ വിലാസങàµà´™à´³àµâ€ " +"പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gvolume.c:439 +msgid "volume doesn't implement eject" +msgstr "വോളàµà´¯à´‚ à´ªàµà´±à´¤àµà´¤à´¿à´±à´•àµà´•à´²àµâ€ à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:516 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" +"വോളàµà´¯à´‚ à´ªàµà´±à´¤àµà´¤à´¿à´±à´•àµà´•à´²àµâ€ eject à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ eject_with_operation " +"à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "à´ªàµà´°à´¯àµ‹à´—à´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´¾à´¯à´¿à´²àµà´²" + +#: ../gio/gwin32appinfo.c:308 +#, c-format +msgid "Error launching application: %s" +msgstr "à´ªàµà´°à´¯àµ‹à´—à´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gwin32appinfo.c:344 +msgid "URIs not supported" +msgstr "à´¯àµà´†à´°àµâ€à´ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gwin32appinfo.c:366 +msgid "association changes not supported on win32" +msgstr "win32-à´²àµâ€ അസോസിയേഷനàµâ€ സൃഷàµà´Ÿà´¿ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gwin32appinfo.c:378 +msgid "Association creation not supported on win32" +msgstr "win32-à´²àµâ€ അസോസിയേഷനàµâ€ സൃഷàµà´Ÿà´¿ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../gio/gwin32inputstream.c:355 +#, c-format +msgid "Error reading from handle: %s" +msgstr "ഹാനàµâ€à´¡à´¿à´²à´¿à´²àµâ€ നിനàµà´¨àµà´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gwin32inputstream.c:387 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "ഹാനàµâ€à´¡à´¿à´²àµâ€ à´…à´Ÿà´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gwin32outputstream.c:343 +#, c-format +msgid "Error writing to handle: %s" +msgstr "ഹാനàµâ€à´¡à´¿à´²à´¿à´²àµ‡à´•àµà´•àµàµ à´Žà´´àµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "ആവശàµà´¯à´®à´¾à´¯ മെമàµà´®à´±à´¿ ലഭàµà´¯à´®à´²àµà´²" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "ആനàµà´¤à´°à´¿à´• പിശകàµ: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "കൂടàµà´¤à´²àµâ€ ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ ആവശàµà´¯à´®àµà´£àµà´Ÿàµàµ" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "à´•à´®àµà´ªàµà´°à´¸àµà´¸àµà´¡àµ ഡേറàµà´±à´¾à´¯àµà´•àµà´•àµàµ സാധàµà´¤à´¯à´¿à´²àµà´²" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "à´ªàµà´°à´¿à´¨àµà´±àµ വിലാസം" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "ഷെലàµâ€ മോഡിലàµâ€ à´ªàµà´°à´¿à´¨àµà´±àµ വിലാസം" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "ഒരൠഡീബസൠസരàµâ€à´µàµ€à´¸àµ à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´ªàµà´ªà´¿à´¯àµà´•àµà´•àµà´•" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "തെറàµà´±à´¾à´¯ ആരàµâ€à´—àµà´¯àµà´®àµ†à´¨àµà´±àµà´•à´³àµâ€\n" + +#: ../glib/gbookmarkfile.c:760 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "'%s' എലമെനàµà´±à´¿à´¨àµ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ സവിശേഷത '%s'" + +#: ../glib/gbookmarkfile.c:771 ../glib/gbookmarkfile.c:842 +#: ../glib/gbookmarkfile.c:852 ../glib/gbookmarkfile.c:959 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "എലമെനàµà´±àµ '%s'-à´¨àµà´±àµ† സവിശേഷതയായ '%s' à´•à´£àµà´Ÿàµà´•à´¿à´Ÿàµà´Ÿà´¿à´¯à´¿à´²àµà´²" + +#: ../glib/gbookmarkfile.c:1129 ../glib/gbookmarkfile.c:1194 +#: ../glib/gbookmarkfile.c:1258 ../glib/gbookmarkfile.c:1268 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ ടാഗൠ'%s', ടാഗൠ'%s' à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´šà´¿à´°àµà´¨àµà´¨àµ" + +#: ../glib/gbookmarkfile.c:1154 ../glib/gbookmarkfile.c:1168 +#: ../glib/gbookmarkfile.c:1236 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "'%s'-à´¨àµà´±àµ† ഉളളിലàµâ€ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ ടാഗൠ'%s'" + +#: ../glib/gbookmarkfile.c:1798 +msgid "No valid bookmark file found in data dirs" +msgstr "ഡേറàµà´±à´¾ ഡയറകàµà´Ÿà´±à´¿à´•ളിലàµâ€ സാധàµà´¤à´¯àµà´³à´³ à´¬àµà´•àµà´•ൠമാരàµâ€à´•àµà´•ൠകണàµà´Ÿàµà´•à´¿à´Ÿàµà´Ÿà´¿à´¯à´¿à´²àµà´²" + +#: ../glib/gbookmarkfile.c:1999 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s'-à´¨àµà´³à´³ à´¬àµà´•àµà´•ൠമാരàµâ€à´•àµà´•ൠനിലവിലàµà´£àµà´Ÿàµ " + +#: ../glib/gbookmarkfile.c:2045 ../glib/gbookmarkfile.c:2203 +#: ../glib/gbookmarkfile.c:2288 ../glib/gbookmarkfile.c:2368 +#: ../glib/gbookmarkfile.c:2453 ../glib/gbookmarkfile.c:2536 +#: ../glib/gbookmarkfile.c:2614 ../glib/gbookmarkfile.c:2693 +#: ../glib/gbookmarkfile.c:2735 ../glib/gbookmarkfile.c:2832 +#: ../glib/gbookmarkfile.c:2952 ../glib/gbookmarkfile.c:3142 +#: ../glib/gbookmarkfile.c:3218 ../glib/gbookmarkfile.c:3386 +#: ../glib/gbookmarkfile.c:3475 ../glib/gbookmarkfile.c:3565 +#: ../glib/gbookmarkfile.c:3693 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s'-à´¨àµà´³à´³ à´¬àµà´•àµà´•ൠമാരàµâ€à´•àµà´•ൠലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gbookmarkfile.c:2377 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s'-à´¨àµà´³à´³ à´¬àµà´•àµà´•ൠമാരàµâ€à´•àµà´•à´¿à´²àµâ€ MIME തരം à´µàµà´¯à´•àµà´¤à´®à´¾à´•àµà´•ിയിടàµà´Ÿà´¿à´²àµà´²" + +#: ../glib/gbookmarkfile.c:2462 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" +"URI '%s'-à´¨àµà´³à´³ à´¬àµà´•àµà´•ൠമാരàµâ€à´•àµà´•à´¿à´²àµâ€ à´¸àµà´µà´•ാരàµà´¯ à´«àµà´³à´¾à´—ൠവàµà´¯à´•àµà´¤à´®à´¾à´•àµà´•ിയിടàµà´Ÿà´¿à´²àµà´²" + +#: ../glib/gbookmarkfile.c:2841 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s'-à´¨àµà´³à´³ à´¬àµà´•àµà´•ൠമാരàµâ€à´•àµà´•à´¿à´²àµâ€ à´—àµà´°àµ‚à´ªàµà´ªàµà´•ളൊനàµà´¨àµà´‚ à´•àµà´°à´®àµ€à´•à´°à´¿à´šàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´²" + +#: ../glib/gbookmarkfile.c:3239 ../glib/gbookmarkfile.c:3396 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" +"'%s' à´Žà´¨àµà´¨àµ പേരàµà´³à´³ ഒരൠപàµà´°à´¯àµ‹à´—à´µàµà´‚ '%s'-à´¨àµà´³à´³ à´¬àµà´•àµà´•ൠമാരàµâ€à´•àµà´•à´¿à´²àµâ€ രജിസàµà´Ÿà´°àµâ€ " +"ചെയàµà´¤à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²" + +#: ../glib/gbookmarkfile.c:3419 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "" +"'%s' à´Žà´¨àµà´¨ URI ഉളള '%s' à´Žà´¨àµà´¨ exec വരി വികസിപàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ" + +#: ../glib/gconvert.c:803 ../glib/gutf8.c:829 ../glib/gutf8.c:1039 +#: ../glib/gutf8.c:1176 ../glib/gutf8.c:1280 +msgid "Partial character sequence at end of input" +msgstr "ഇനàµâ€à´ªàµà´Ÿàµà´Ÿà´¿à´¨àµà´±àµ† അവസാനം ഭാഗികമായ à´…à´•àµà´·à´° à´•àµà´°à´®à´‚" + +#: ../glib/gconvert.c:1053 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" +"ഫോളàµâ€à´¸àµ†à´±àµà´±àµ '%s'-à´²àµâ€ നിനàµà´¨àµà´‚ കോഡàµà´¸àµ†à´±àµà´±àµ '%s'-ലേകàµà´•ൠമാറàµà´±àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../glib/gconvert.c:1871 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI %s \"file\" à´¸àµà´•ീം ഉപയോഗികàµà´•àµà´¨àµà´¨ പൂരàµâ€à´£àµà´£à´®à´¾à´¯ ഒരൠURI à´…à´²àµà´²" + +#: ../glib/gconvert.c:1881 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "ലോകàµà´•à´²àµâ€ ഫയലàµâ€ URI %s-à´²àµâ€ '#' ഉലàµâ€à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¾à´¨àµâ€ പാടിലàµà´²" + +#: ../glib/gconvert.c:1898 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' അസാധàµà´µà´¾à´£àµ" + +#: ../glib/gconvert.c:1910 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI '%s'-à´¨àµà´±àµ† ഹോസàµà´±àµà´±àµ നാമം അസാധàµà´µà´¾à´£àµ" + +#: ../glib/gconvert.c:1926 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s'-à´²àµâ€ അസാധàµà´µà´¾à´¯ à´Žà´¸àµà´•േപàµà´¡àµ à´…à´•àµà´·à´°à´™àµà´™à´³àµâ€ ഉണàµà´Ÿàµ" + +#: ../glib/gconvert.c:2021 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s' പാഥൠനാമം പൂരàµâ€à´£àµà´£à´®à´¾à´¯ ഒരൠപാഥൠഅലàµà´²" + +#: ../glib/gconvert.c:2031 +msgid "Invalid hostname" +msgstr "സാധàµà´¤à´¯à´¿à´²àµà´²à´¾à´¤àµà´¤ ഹോസàµà´±àµà´±àµ നാമം" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "AM" +msgstr "രാവിലെ" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "PM" +msgstr "വൈകàµ" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %b %e %H:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:219 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "January" +msgstr "ജനàµà´µà´°à´¿" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "February" +msgstr "ഫെബàµà´°àµà´µà´°à´¿" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "March" +msgstr "മാരàµâ€à´šàµà´šàµ" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "April" +msgstr "à´à´ªàµà´°à´¿à´²àµâ€ " + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "May" +msgstr "മെയàµ" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "June" +msgstr "ജൂണàµâ€" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "July" +msgstr "ജൂലൈ" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "August" +msgstr "à´“à´—à´¸àµà´±àµà´±àµ" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "September" +msgstr "സെപàµà´Ÿà´‚ബരàµâ€" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "October" +msgstr "à´’à´•àµà´Ÿàµ‹à´¬à´°àµâ€" + +#: ../glib/gdatetime.c:252 +msgctxt "full month name" +msgid "November" +msgstr "നവംബരàµâ€" + +#: ../glib/gdatetime.c:254 +msgctxt "full month name" +msgid "December" +msgstr "ഡിസംബരàµâ€" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ജനàµ" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ഫെബàµ" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "മാരàµâ€" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à´à´ªàµà´°" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "May" +msgstr "മെ" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ജൂണàµâ€" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ജൂ" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "à´“" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "സെപàµà´Ÿ" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "à´’à´•àµà´Ÿàµ‹" + +#: ../glib/gdatetime.c:289 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "നവം" + +#: ../glib/gdatetime.c:291 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "à´¡à´¿" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Monday" +msgstr "തിങàµà´•à´³àµâ€" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "ചൊവàµà´µ" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "à´¬àµà´§à´¨àµâ€" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "à´µàµà´¯à´¾à´´à´‚" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Friday" +msgstr "വെളàµà´³à´¿" + +#: ../glib/gdatetime.c:316 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "ശനി" + +#: ../glib/gdatetime.c:318 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ഞായരàµâ€" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "തി" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ചൊ" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "à´¬àµ" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "à´µàµà´¯à´¾" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "വെ" + +#: ../glib/gdatetime.c:343 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "à´¶" + +#: ../glib/gdatetime.c:345 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "à´žà´¾" + +#: ../glib/gdir.c:120 ../glib/gdir.c:143 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "ഡയറകàµà´Ÿà´±à´¿ '%s' à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../glib/gfileutils.c:671 ../glib/gfileutils.c:759 +#, fuzzy, c-format +#| msgid "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "" +"%lu ബൈറàµà´±àµà´¸àµ ഫയലàµâ€ \"%s\" വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ നീകàµà´•ൠവയàµà´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" +msgstr[1] "" +"%lu ബൈറàµà´±àµà´¸àµ ഫയലàµâ€ \"%s\" വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ നീകàµà´•ൠവയàµà´•àµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../glib/gfileutils.c:686 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "%s വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€â€Œ പരാജയം : %s" + +#: ../glib/gfileutils.c:700 +#, c-format +msgid "File \"%s\" is too large" +msgstr "ഫയലàµâ€ \"%s\" വളരെ വലàµà´¤à´¾à´£àµàµ." + +#: ../glib/gfileutils.c:783 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "ഫയലàµâ€ '%s'-à´²àµâ€ നിനàµà´¨àµà´‚ വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം: %s" + +#: ../glib/gfileutils.c:834 ../glib/gfileutils.c:921 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "%s à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€â€Œ പരാജയം : %s" + +#: ../glib/gfileutils.c:851 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "%s-à´¨àµà´±àµ† വിശേഷതകളàµâ€ à´•à´£àµà´Ÿàµ†à´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം: fstat() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:885 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം: fdopen() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:993 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"ഫയലàµâ€ '%s'-à´¨àµà´±àµ† പേരൠ'%s' ആയി മാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: g_rename() " +"പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:1035 ../glib/gfileutils.c:1593 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "ഫയലàµâ€ '%s' സൃഷàµà´Ÿà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം: %s" + +#: ../glib/gfileutils.c:1049 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" +"à´Žà´´àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ '%s' à´¤àµà´±à´•àµà´•àµà´µà´¾à´¨àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: fdopen() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:1074 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "ഫയലàµâ€ '%s' à´Žà´´àµà´¤àµà´µà´¾à´¨àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: fwrite() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:1093 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "ഫയലàµâ€ '%s' à´Žà´´àµà´¤àµà´µà´¾à´¨àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: fflush() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:1137 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "ഫയലàµâ€ '%s' à´Žà´´àµà´¤àµà´µà´¾à´¨àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: fsync() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:1161 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "ഫയലàµâ€ '%s' à´…à´Ÿà´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: fclose() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:1282 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" +"നിലവിലàµà´³à´³ ഫയലàµâ€ '%s' നീകàµà´•à´‚ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²: g_unlink() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %" +"s" + +#: ../glib/gfileutils.c:1556 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "ടെംപàµà´³àµ‡à´±àµà´±àµ \"%s\" അസാധàµà´µà´¾à´£àµ,ഇതിലàµâ€ \"%s\" ഉണàµà´Ÿà´¾à´•àµà´µà´¾à´¨àµâ€ പാടിലàµà´²" + +#: ../glib/gfileutils.c:1569 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "ടെംപàµà´³àµ‡à´±àµà´±àµ \"%s\"-à´²àµâ€ XXXXXX ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gfileutils.c:2097 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "സിബോളികàµà´•ൠലിങàµà´•ൠ'%s' വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gfileutils.c:2118 +msgid "Symbolic links not supported" +msgstr "സിബോളികàµà´•ൠലിങàµà´•ൠപിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../glib/giochannel.c:1418 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s'-à´²àµâ€ നിനàµà´¨àµà´‚ '%s'-ലേകàµà´•ൠവേരàµâ€à´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨ സംവിധാനം ലഭàµà´¯à´®à´¾à´¯à´¿à´²àµà´²: %s" + +#: ../glib/giochannel.c:1763 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string-à´²àµâ€ റോ വായന സാധàµà´¯à´®à´²àµà´²" + +#: ../glib/giochannel.c:1810 ../glib/giochannel.c:2068 +#: ../glib/giochannel.c:2155 +msgid "Leftover unconverted data in read buffer" +msgstr "റീഡൠബഫറിലàµâ€ ബാകàµà´•à´¿à´¯àµà´³à´³ വേരàµâ€à´¤à´¿à´°à´¿à´•àµà´•ാതàµà´¤ ഡേറàµà´±à´¾" + +#: ../glib/giochannel.c:1891 ../glib/giochannel.c:1968 +msgid "Channel terminates in a partial character" +msgstr "ചാനലàµâ€ അവസാനികàµà´•àµà´¨àµà´¨à´¤àµ ഭാഗികമായ à´…à´•àµà´·à´°à´¤àµà´¤à´¿à´²àµâ€ ആണàµ" + +#: ../glib/giochannel.c:1954 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end-à´²àµâ€ റോ വായന സാധàµà´¯à´®à´²àµà´²" + +#: ../glib/gkeyfile.c:722 +msgid "Valid key file could not be found in search dirs" +msgstr "തിരചàµà´šà´¿à´²àµâ€ നടതàµà´¤à´¿à´¯ ഡയറകàµà´Ÿà´±à´¿à´•ളിലàµâ€ സാധàµà´¤à´¯àµà´³à´³ കീ ഫയലàµâ€ ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gkeyfile.c:758 +msgid "Not a regular file" +msgstr "ഒരൠസാധാരണ ഫയലàµâ€ à´…à´²àµà´²" + +#: ../glib/gkeyfile.c:1158 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"കീ ഫയലിലàµâ€ ഉളള '%s' à´Žà´¨àµà´¨ വരി ഒരൠകീ-മൂലàµà´²àµà´¯à´‚ ജോടി à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ ഒരൠഗàµà´±àµ‚à´ªàµà´ªàµ‹ " +"à´…à´­à´¿à´ªàµà´±à´¾à´¯à´®àµ‹ à´…à´²àµà´²" + +#: ../glib/gkeyfile.c:1215 +#, c-format +msgid "Invalid group name: %s" +msgstr "അസാധàµà´µà´¾à´¯ à´—àµà´°àµ‚à´ªàµà´ªàµ നാമം: %s" + +#: ../glib/gkeyfile.c:1237 +msgid "Key file does not start with a group" +msgstr "കീ ഫയലàµâ€ ആരംഭികàµà´•àµà´¨àµà´¨à´¤àµ ഒരൠഗàµà´°àµ‚à´ªàµà´ªà´¿à´²à´²àµà´²" + +#: ../glib/gkeyfile.c:1263 +#, c-format +msgid "Invalid key name: %s" +msgstr "അസാധàµà´µà´¾à´¯ കീ നാമം: %s" + +#: ../glib/gkeyfile.c:1290 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "പിനàµà´¤àµà´£à´¯àµà´•àµà´•ാതàµà´¤ രഹസàµà´¯ ഭാഷ '%s' കീ ഫയലàµâ€ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨àµ" + +#: ../glib/gkeyfile.c:1533 ../glib/gkeyfile.c:1695 ../glib/gkeyfile.c:3073 +#: ../glib/gkeyfile.c:3139 ../glib/gkeyfile.c:3265 ../glib/gkeyfile.c:3398 +#: ../glib/gkeyfile.c:3540 ../glib/gkeyfile.c:3770 ../glib/gkeyfile.c:3837 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "കീ ഫയലിനൠ'%s' à´Žà´¨àµà´¨ à´—àµà´°àµ‚à´ªàµà´ªà´¿à´²àµà´²" + +#: ../glib/gkeyfile.c:1707 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "കീ ഫയലിനൠ'%s' à´Žà´¨àµà´¨ കീയിലàµà´²" + +#: ../glib/gkeyfile.c:1814 ../glib/gkeyfile.c:1930 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "UTF-8 à´…à´²àµà´²à´¾à´¤àµà´¤ '%s' മൂലàµà´²àµà´¯à´®àµà´³à´³ കീ '%s' കീ ഫയലിലàµà´£àµà´Ÿàµ" + +#: ../glib/gkeyfile.c:1834 ../glib/gkeyfile.c:1950 ../glib/gkeyfile.c:2319 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "തിരിചàµà´šà´±à´¿à´¯àµà´µà´¾à´¨àµâ€ കഴിയാതàµà´¤ മൂലàµà´²àµà´¯à´®àµà´³à´³ കീ '%s' കീ ഫയലിലàµà´£àµà´Ÿàµ." + +#: ../glib/gkeyfile.c:2536 ../glib/gkeyfile.c:2902 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' in group '%s' which has value that cannot be " +#| "interpreted." +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"തിരിചàµà´šà´±à´¿à´¯àµà´µà´¾à´¨àµâ€ കഴിയാതàµà´¤ മൂലàµà´²àµà´¯à´®àµà´³à´³ കീ '%s', '%s' à´Žà´¨àµà´¨ à´—àµà´°àµ‚à´ªàµà´ªà´¿à´²àµâ€ കീ " +"ഫയലിലàµà´£àµà´Ÿàµ." + +#: ../glib/gkeyfile.c:2614 ../glib/gkeyfile.c:2690 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' in group '%s' which has value that cannot be " +#| "interpreted." +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" +"തിരിചàµà´šà´±à´¿à´¯àµà´µà´¾à´¨àµâ€ കഴിയാതàµà´¤ മൂലàµà´²àµà´¯à´®àµà´³à´³ കീ '%s', '%s' à´Žà´¨àµà´¨ à´—àµà´°àµ‚à´ªàµà´ªà´¿à´²àµâ€ കീ " +"ഫയലിലàµà´£àµà´Ÿàµ." + +#: ../glib/gkeyfile.c:3088 ../glib/gkeyfile.c:3280 ../glib/gkeyfile.c:3848 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "à´—àµà´°àµ‚à´ªàµà´ªàµ '%s'-à´²àµâ€ കീ ഫയലിനൠകീ '%s' ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gkeyfile.c:4080 +msgid "Key file contains escape character at end of line" +msgstr "കീ ഫയലിനàµà´±àµ† വരിയàµà´Ÿàµ† അവസാനം à´Žà´¸àµà´•െയിപàµà´ªàµ à´…à´•àµà´·à´°à´‚ ലഭàµà´¯à´®à´¾à´£àµ" + +#: ../glib/gkeyfile.c:4102 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "കീ ഫയലിലàµâ€ അസാധàµà´µà´¾à´¯ à´Žà´¸àµà´•െയിപàµà´ªàµ സീകàµà´µà´¨àµâ€à´¸àµ '%s' ലഭàµà´¯à´®à´¾à´£àµ" + +#: ../glib/gkeyfile.c:4244 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "മൂലàµà´²àµà´¯à´‚ '%s' ഒരൠഅകàµà´•മായി കണകàµà´•ാകàµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²." + +#: ../glib/gkeyfile.c:4258 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "ഇനàµà´±à´¿à´œà´°àµâ€ മൂലàµà´²àµà´¯à´‚ '%s' പരിധിയàµà´•àµà´•ൠപàµà´±à´¤àµà´¤àµ" + +#: ../glib/gkeyfile.c:4291 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "മൂലàµà´²àµà´¯à´‚ '%s' ഒരൠഫàµà´³àµ‹à´Ÿàµà´Ÿàµ à´…à´•àµà´•മായി കണകàµà´•ാകàµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²." + +#: ../glib/gkeyfile.c:4315 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "മൂലàµà´²àµà´¯à´‚ '%s' ഒരൠബൂളിയനായി കണകàµà´•ാകàµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²." + +#: ../glib/gmappedfile.c:130 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "%s-à´¨àµà´±àµ† വിശേഷതകളàµâ€ à´•à´£àµà´Ÿàµ†à´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം: fstat() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gmappedfile.c:196 +#, fuzzy, c-format +#| msgid "Failed to map file '%s': mmap() failed: %s" +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" +"ഫയലàµâ€ '%s' മാപàµà´ªàµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: mmap() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "ഫയലàµâ€ '%s' à´¤àµà´±à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: open() പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ: %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "%d-ആം വരിയിലàµâ€ %d-ആം à´…à´•àµà´·à´°à´¤àµà´¤à´¿à´²àµâ€ പിശകàµ:" + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "പേരിലàµâ€ സാധàµà´¤à´¯à´¿à´²àµà´²à´¾à´¤àµà´¤ UTF-8 രഹസàµà´¯ വാചകം - '%s' തെറàµà´±à´¾à´•àµà´¨àµà´¨àµ" + +#: ../glib/gmarkup.c:472 +#, c-format +#| msgid "'%s' is not a valid name " +msgid "'%s' is not a valid name" +msgstr "'%s' ശരിയായ നാമമലàµà´²" + +#: ../glib/gmarkup.c:488 +#, c-format +#| msgid "'%s' is not a valid name: '%c' " +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' ശരിയായ നാമമലàµà´²: '%c'" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "വരി %d-à´²àµâ€ പിശകàµ: %s" + +#: ../glib/gmarkup.c:682 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' പാഴàµà´¸àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ, ഇതൠഅകàµà´·à´° റഫറനàµâ€à´¸à´¿à´¨àµà´³à´³à´¿à´²àµâ€ ഒരൠ" +"à´…à´•àµà´•à´‚ ആയിരികàµà´•ണമാരàµà´¨àµà´¨àµ " +"(ê ഉദാഹരണതàµà´¤à´¿à´¨àµ) - ഒരൠപകàµà´·àµ‡ à´…à´•àµà´•à´‚ വളരെ വലàµà´¤à´¾à´µà´¾à´‚" + +#: ../glib/gmarkup.c:694 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"à´…à´•àµà´·à´°à´¸àµ‚à´šà´•à´‚ ഒരൠഅരàµà´¦àµà´§à´µà´¿à´°à´¾à´®à´¤àµà´¤à´¿à´²àµ അവസാനികàµà´•àµà´¨àµà´¨à´¿à´²àµà´². & à´Žà´¨àµà´¨ à´…à´•àµà´·à´°à´‚ അറിയാതെ " +"ഉളàµâ€à´•àµà´•ൊളളാനàµâ€ " +"ഇടയായോ? & ഒരൠസതàµà´¤ à´…à´²àµà´²àµ†à´™àµà´•ിലൠ& à´Žà´¨àµà´¨àµ à´ªàµà´°à´¤àµà´¯àµ‡à´•à´‚ സൂചിപàµà´ªà´¿à´•àµà´•àµà´•" + +#: ../glib/gmarkup.c:720 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" +"à´…à´•àµà´·à´°à´¤àµà´¤à´¿à´¨àµà´±àµ† സൂചനയായ '%-.*s' ഒരൠഅനàµà´µà´¦à´¨àµ€à´¯à´®à´¾à´¯ രഹസàµà´¯ à´…à´•àµà´·à´°à´¤àµà´¤à´¿à´²àµ‡à´•àµà´•à´²àµà´² " +"വേരàµâ€à´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ" + +#: ../glib/gmarkup.c:758 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"‌ശൂനàµà´¯à´®à´¾à´¯ à´Žà´¨àµà´±à´¿à´¨àµà´±à´¿ '&;' à´•à´£àµà´Ÿàµ; à´…à´¨àµà´µà´¦à´¨àµ€à´¯à´®à´¾à´¯à´µ ഇവയാണàµ: & " < > " +"'" + +#: ../glib/gmarkup.c:766 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "à´Žà´¨àµà´±à´¿à´¨àµà´±à´¿ നാമം '%-.*s' അപരിചിതമാണàµ" + +#: ../glib/gmarkup.c:771 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"à´Žà´¨àµà´±à´¿à´¨àµà´±à´¿ ഒരൠഅരàµà´¦àµà´§à´µà´¿à´°à´¾à´®à´¤àµà´¤à´¿à´²àµ അവസാനികàµà´•àµà´¨àµà´¨à´¿à´²àµà´². & à´Žà´¨àµà´¨ à´…à´•àµà´·à´°à´‚ അറിയാതെ " +"ഉളàµâ€à´•àµà´•ൊളളാനàµâ€ " +"ഇടയായോ? & ഒരൠഎനàµà´±à´¿à´¨àµà´±à´¿ à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ & à´Žà´¨àµà´¨àµ à´ªàµà´°à´¤àµà´¯àµ‡à´•à´‚ സൂചിപàµà´ªà´¿à´•àµà´•àµà´•" + +#: ../glib/gmarkup.c:1119 +msgid "Document must begin with an element (e.g. )" +msgstr "രേഖ à´¤àµà´Ÿà´™àµà´™àµ‡à´£àµà´Ÿà´¤àµ ഒരൠഎലമെനàµà´±à´¿à´²à´¾à´£àµ (ഉദാ )" + +#: ../glib/gmarkup.c:1159 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'<' à´…à´•àµà´·à´°à´¤àµà´¤à´¿à´¨àµ പിനàµà´¨à´¿à´²àµà´³à´³ '%s' ഒരൠഅസാധàµà´µà´¾à´¯ à´…à´•àµà´·à´°à´®à´¾à´£àµ; ഇതൠഒരൠഎലമെനàµà´±àµ " +"പേരിലàµâ€ à´¤àµà´Ÿà´™àµà´™à´¿à´²àµà´²" + +#: ../glib/gmarkup.c:1227 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"ഓഡൠഅകàµà´·à´°à´‚ '%s', '%s' à´Žà´¨àµà´¨ ശൂനàµà´¯-എലമെനàµà´±àµ à´±àµà´±à´¾à´—ൠഅവസാനിപàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ '>' " +"à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´šàµ" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"ഓഡൠഅകàµà´·à´°à´‚ '%s', എലമെനàµà´±àµ '%s'-à´¨àµà´±àµ† സവിശേഷത നാമം '%s'-നൠശേഷം ഒരൠ'=' " +"à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../glib/gmarkup.c:1352 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"'%s' ഒരൠഓഡൠഅകàµà´·à´°à´‚ ആണàµ, ഇതിനൠപകരം ഒരൠ'>' à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ '/' à´Žà´¨àµà´¨ à´…à´•àµà´·à´°à´‚ " +"à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ ഒരൠ" +"വിശേഷതായàµàµ '%s' à´Žà´¨àµà´¨ എലമെനàµà´±à´¿à´¨àµà´±àµ† â€à´±àµ† ആരംഭതàµà´¤à´¿à´²àµà´³à´³ ടാഗൠഅവസാനിപàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµ " +"à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´šà´¤àµ; " +"ഒരൠപകàµà´µà´¿à´¶àµ‡à´·à´¤à´¯àµà´Ÿàµ†àµâ€à´±àµ† പേരിലàµâ€ നിങàµà´™à´³àµâ€ തെറàµà´±à´¾à´¯ à´…à´•àµà´·à´°à´‚ ആവാം ഉപയോഗിചàµà´šà´¤àµ" + +#: ../glib/gmarkup.c:1396 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"'%s' ഒരൠഓഡൠഅകàµà´·à´°à´‚ ആണàµ, '%s' à´Žà´¨àµà´¨ എലമെനàµà´±à´¿à´¨àµà´±àµ† വിശേഷതയായ‌ '%s'ൂലàµà´²àµà´¯à´‚ " +"നലàµâ€à´•àµà´®àµà´ªàµ‹à´³àµâ€ സമം‌ à´Žà´¨àµà´¨ " +"à´šà´¿à´¹àµà´¨à´¤àµà´¤à´¿à´¨àµ ശേഷം ഒരൠതàµà´±à´¨àµà´¨ കോടàµà´Ÿàµ ആണൠപàµà´±à´¤àµ€à´•àµà´·à´¿à´šàµà´šà´¤àµ" + +#: ../glib/gmarkup.c:1529 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"എലമെനàµà´±àµ നാമം '%s'-നൠശേഷം ഉളള '%s', ഒരൠഅസാധàµà´µà´¾à´¯ à´…à´•àµà´·à´°à´®à´¾à´£àµ; '>' à´…à´•àµà´·à´°à´®à´¾à´£àµ " +"à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ" + +#: ../glib/gmarkup.c:1576 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" +"എലമെനàµà´±àµ '%s' à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ, ഒരൠഎലമെനàµà´±àµà´•à´³àµà´‚ നിലവിലàµâ€ à´¤àµà´±à´¨àµà´¨à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²" + +#: ../glib/gmarkup.c:1585 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"എലമെനàµà´±àµ '%s' à´…à´Ÿà´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ, പകàµà´·àµ‡ നിലവിലàµâ€ ലഭàµà´¯à´®à´¾à´¯ എലമെനàµà´±àµ '%s' ആണàµ" + +#: ../glib/gmarkup.c:1753 +msgid "Document was empty or contained only whitespace" +msgstr "രേഖ ശൂനàµà´¯à´®à´¾à´£àµ à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ അതിലàµâ€ വയിറàµà´±àµ à´¸àµà´ªàµ†à´¯à´¿à´¸àµ മാതàµà´°à´®àµ‡ ഉളàµà´³àµ‚" + +#: ../glib/gmarkup.c:1767 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "ഒരൠ'<' à´¬àµà´°à´¾à´•àµà´•à´±àµà´±à´¿à´¨àµ ശേഷം രേഖ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ അവസാനിചàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ " + +#: ../glib/gmarkup.c:1775 ../glib/gmarkup.c:1820 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"എലമെനàµà´±àµà´•à´³àµâ€ à´¤àµà´±à´¨àµà´¨àµ à´•à´¿à´Ÿà´•àµà´•àµà´®àµà´ªàµ‹à´³àµâ€ തനàµà´¨àµ† രേഖ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´®à´¾à´¯ à´…à´Ÿà´žàµà´žà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ - " +"à´’à´Ÿàµà´µà´¿à´²àµâ€ à´¤àµà´±à´¨àµà´¨ എലമെനàµà´±àµ " +"'%s' ആണàµ" + +#: ../glib/gmarkup.c:1783 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"തനàµà´¨àµ† രേഖ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´®à´¾à´¯ à´…à´Ÿà´žàµà´žà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ, ടാഗൠ<%s/>-നൠഅവസാനമായി ഒരൠകàµà´³àµ‹à´¸àµ " +"ആങàµà´•à´¿à´²àµâ€ à´¬àµà´°à´¾à´•àµà´•à´±àµà´±àµ " +"à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../glib/gmarkup.c:1789 +msgid "Document ended unexpectedly inside an element name" +msgstr "ഒരൠഎലമെനàµà´±à´¿à´¨àµà´±àµ† നാമതàµà´¤à´¿à´¨àµà´³à´³à´¿à´²àµâ€ രേഖ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ അവസാനിചàµà´šàµ" + +#: ../glib/gmarkup.c:1795 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "ഒരൠസവിശേഷത നാമതàµà´¤à´¿à´¨àµà´³à´³à´¿à´²àµâ€ രേഖ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ അവസാനിചàµà´šàµ" + +#: ../glib/gmarkup.c:1800 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ഒരൠഎലമെനàµà´±àµ-à´“à´ªàµà´ªà´£à´¿à´™àµ ടാഗിനàµà´³à´³à´¿à´²àµâ€ രേഖ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ അവസാനിചàµà´šàµ" + +#: ../glib/gmarkup.c:1806 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"സമം à´šà´¿à´¹àµà´¨à´¤àµà´¤à´¿à´¨àµ ശേഷം ഒരൠവിശേഷതയàµà´Ÿàµ† പേരൠആയതിനാലàµâ€ à´…à´ªàµà´±à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ " +"ഡോകàµà´¯àµà´®àµ†à´¨àµà´±àµ അവസാനിചàµà´šàµ; " +"വിശേഷതയàµà´•àµà´•àµàµ മൂലàµà´²àµà´¯à´‚ ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gmarkup.c:1813 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ഒരൠസവിശേഷത നാമതàµà´¤à´¿à´¨àµà´³à´³à´¿à´²àµâ€ വചàµà´šàµ രേഖ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ അവസാനിചàµà´šàµ" + +#: ../glib/gmarkup.c:1829 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "എലമെനàµà´±àµ '%s'-à´¨àµà´±àµ† à´•àµà´²àµ‹à´¸àµ ടാഗിനàµà´³àµà´³à´¿à´²àµâ€ രേഖ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ അവസാനിചàµà´šàµ" + +#: ../glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"ഒരൠഅഭിപàµà´°à´¾à´¯à´‚ à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ ഒരൠപàµà´°à´•àµà´°à´¿à´¯ നടതàµà´¤àµà´¨àµà´¨ നിരàµâ€à´¦àµà´¦àµ‡à´¶à´¤àµà´¤à´¿à´¨àµà´³àµà´³à´¿à´²àµâ€ രേഖ " +"à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ " +"അവസാനിചàµà´šàµ" + +#: ../glib/goption.c:754 +msgid "Usage:" +msgstr "ഉപയോഗികàµà´•േണàµà´Ÿ വിധം:" + +#: ../glib/goption.c:754 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:864 +msgid "Help Options:" +msgstr "സഹായ ഉപാധികളàµâ€:" + +#: ../glib/goption.c:865 +msgid "Show help options" +msgstr "സഹായ ഉപാധികളàµâ€ കാണികàµà´•àµà´•" + +#: ../glib/goption.c:871 +msgid "Show all help options" +msgstr "à´Žà´²àµà´²à´¾ സഹായ ഉപാധികളàµà´‚ കാണികàµà´•àµà´•" + +#: ../glib/goption.c:933 +msgid "Application Options:" +msgstr "à´ªàµà´°à´¯àµ‹à´—à´¤àµà´¤à´¿à´¨àµà´³à´³ ഉപാധികളàµâ€:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "%s-നൠവേണàµà´Ÿà´¿ ഇനàµà´±à´¿à´œà´°àµâ€ മൂലàµà´²àµà´¯à´‚ '%s' പാഴàµà´¸àµ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%s-നൠവേണàµà´Ÿà´¿à´¯àµà´³à´³ ഇനàµà´±à´¿à´œà´°àµâ€ മൂലàµà´²àµà´¯à´‚ '%s' പരിധിയàµà´•àµà´•ൠപàµà´±à´¤àµà´¤à´¾à´£àµ" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "%s-നൠവേണàµà´Ÿà´¿ ഡബിളàµâ€ മൂലàµà´²àµà´¯à´‚ '%s' പാഴàµà´¸àµ ചെയàµà´¯àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "%s-നൠവേണàµà´Ÿà´¿à´¯àµà´³à´³ ഡബിളàµâ€ മൂലàµà´²àµà´¯à´‚ '%s' പരിധിയàµà´•àµà´•ൠപàµà´±à´¤àµà´¤à´¾à´£àµ" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "%s ഉപാധി പാഴàµà´¸àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "%s-à´¨àµà´³à´³ ആരàµâ€à´—àµà´¯àµà´®àµ†à´¨àµà´±àµ ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/goption.c:1979 +#, c-format +msgid "Unknown option %s" +msgstr "അപരിചിതമായ ഉപാധി %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "തകരാറàµà´³à´³ à´’à´¬àµà´œà´•àµà´Ÿàµ" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "ആനàµà´¤à´°à´¿à´• പിശകൠഅലàµà´²àµ†à´™àµà´•à´¿à´²àµâ€ തകരാറàµà´³à´³ à´’à´¬àµà´œà´•àµà´Ÿàµ" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "ആവശàµà´¯à´®à´¾à´¯ മെമàµà´®à´±à´¿ ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "ബാകàµà´•àµà´Ÿàµà´°à´¾à´•àµà´•ിങൠപരിധി à´Žà´¤àµà´¤à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"പാറàµâ€à´·àµà´¯à´²àµâ€ മാചàµà´šà´¿à´™à´¿à´¨àµ പിനàµà´¤àµà´£ ലഭàµà´¯à´®à´²àµà´²à´¾à´¤àµà´¤ വസàµà´¤àµà´•àµà´•à´³àµâ€ à´ˆ മാതൃകയിലàµà´£àµà´Ÿàµ" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"പാറàµâ€à´·àµà´¯à´²àµâ€ മാചàµà´šà´¿à´™à´¿à´¨àµà´³à´³ പിനàµà´¤àµà´£ ലഭàµà´¯à´®à´²àµà´²à´¾à´¤àµà´¤à´¤à´¿à´¨à´¾à´²àµâ€ ബാകàµà´•ൠറിഫറനàµâ€à´¸àµà´•à´³àµâ€" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "റികàµà´•േറàµâ€à´·à´¨àµâ€ പരിധി à´Žà´¤àµà´¤à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "à´¨àµà´¯àµ‚ലൈനàµâ€ à´«àµà´³à´¾à´—àµà´•à´³àµà´Ÿàµ† അസാധàµà´µà´¾à´¯ കൂടàµà´Ÿà´¾à´¯àµà´®" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "തെറàµà´±à´¾à´¯ à´“à´«àµâ€Œà´¸àµ†à´±àµà´±àµ" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "ലഘൠutf8" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "റികàµà´•à´°àµâ€à´·à´¨àµâ€ ലൂപàµà´ªàµ" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "അപരിചിതമായ പിശകàµ" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "മാതൃകയàµà´Ÿàµ† അവസാനം \\" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "മാതൃകയàµà´Ÿàµ† അവസാനം \\c" + +#: ../glib/gregex.c:335 +#| msgid "unrecognized character follows \\" +msgid "unrecognized character following \\" +msgstr "\\-നൠശേഷം അപരിചിതമായ à´…à´•àµà´·à´°à´‚" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "{} à´•àµà´µà´¾à´£àµà´Ÿà´¿à´«à´¯à´±à´¿à´²àµâ€ നമàµà´ªà´±àµà´•à´³àµâ€ à´•àµà´°à´®à´¤àµà´¤à´¿à´²à´²àµà´²" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "{} à´•àµà´µà´¾à´£àµà´Ÿà´¿à´«à´¯à´±à´¿à´²àµâ€ നമàµà´ªà´°àµâ€ വളരെ വലàµà´¤à´¾à´£àµàµ" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "à´•àµà´¯à´¾à´°à´•àµà´Ÿà´°àµâ€ à´•àµà´²à´¾à´¸àµà´¸à´¿à´¨àµ അവസാനമàµà´³àµà´³ ] ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "à´•àµà´¯à´¾à´°à´•àµà´Ÿà´°àµâ€ à´•àµà´²à´¾à´¸àµà´¸à´¿à´²àµâ€ തെറàµà´±à´¾à´¯ à´Žà´¸àµà´•േപàµà´ªàµ സീകàµà´µà´¨àµâ€à´¸àµ" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "à´•àµà´¯à´¾à´°à´•àµà´Ÿà´°àµâ€ à´•àµà´²à´¾à´¸àµà´¸à´¿à´²àµâ€ പരിധി à´ªàµà´±à´¤àµà´¤àµ à´•à´Ÿà´•àµà´•àµà´¨àµà´¨àµ" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "ആവരàµâ€à´¤àµà´¤à´¨à´¤àµà´¤à´¿à´¨àµà´±àµ† ആവശàµà´¯à´•തയിലàµà´²" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ ആവരàµâ€à´¤àµà´¤à´¨à´‚" + +#: ../glib/gregex.c:360 +#, fuzzy +#| msgid "unrecognized character after (?" +msgid "unrecognized character after (? or (?-" +msgstr "(?-നൠശേഷം അപരിചിതമായ à´•àµà´¯à´¾à´°à´•àµà´Ÿà´°àµâ€" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "" +"POSIX named à´•àµà´²à´¾à´¸àµà´¸àµà´•à´³àµâ€à´•àµà´•àµàµ ഒരൠകàµà´²à´¾à´¸àµà´¸à´¿à´²àµâ€ മാതàµà´°à´®àµ‡ പിനàµà´¤àµà´£ ലഭàµà´¯à´®àµà´³àµà´³àµ‚" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "അവസാനതàµà´¤à´¿à´²àµà´³àµà´³ ) ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "നിലവിലിലàµà´²à´¾à´¤àµà´¤ ഉപമാതൃകയàµà´•àµà´•àµà´³àµà´³ സൂചന" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "കമനàµà´±à´¿à´¨àµ ശേഷം ) ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:375 +#, fuzzy +#| msgid "regular expression too large" +msgid "regular expression is too large" +msgstr "റെഗàµà´²à´°àµâ€ à´Žà´•àµà´¸àµà´ªàµà´°àµ†à´·à´¨àµâ€ വളരെ വലàµà´¤à´¾à´£àµàµ" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "മെമàµà´®à´±à´¿ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയം" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr "( à´Žà´¨àµà´¨à´¤à´¿à´²àµà´²à´¾à´¤àµ† )" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "കോഡൠഓവരàµâ€à´«àµà´²àµ‹" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "(?<-നൠശേഷം അപരിചിതമായ à´•àµà´¯à´¾à´°à´•àµà´Ÿà´°àµâ€" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind അസേരàµâ€à´·à´¨àµà´±àµ† à´µàµà´¯à´¾à´ªàµà´¤à´¿ à´¸àµà´¥à´¿à´°à´®à´²àµà´²" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "(?(-നൠശേഷം തെറàµà´±à´¾à´¯ à´…à´•àµà´•à´‚ à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ പേരàµ" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "à´•à´£àµà´Ÿàµ€à´·à´¨à´²àµâ€ à´—àµà´°àµ‚à´ªàµà´ªà´¿à´²àµâ€ à´°à´£àµà´Ÿàµàµ à´¬àµà´°à´¾à´žàµà´šà´¿à´²àµâ€ കൂടàµà´¤à´²àµà´£àµà´Ÿàµàµ" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "(?(-à´¨àµàµ ശേഷം അസേരàµâ€à´·à´¨àµâ€ à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ (?[+-]digits à´Žà´¨àµà´¨à´¿à´µà´¯àµà´•àµà´•ൠശേഷം ) ഉണàµà´Ÿà´¾à´¯à´¿à´°à´¿à´•àµà´•ണം" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "അപരിചിതമായ പോസികàµà´¸àµ à´•àµà´²à´¾à´¸àµà´¸àµ നാമം" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "POSIX കോളേറàµà´±à´¿à´™àµ എലമെനàµà´±àµà´•à´³àµâ€à´•àµà´•àµà´³àµà´³ പിനàµà´¤àµà´£ ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...}-à´²àµà´³àµà´³ à´…à´•àµà´·à´° മൂലàµà´²àµà´¯à´‚ വളരെ വലàµà´¤àµàµ" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "തെറàµà´±à´¾à´¯ അവസàµà´¥ (?(0)" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C not allowed in lookbehind assertion" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "റികàµà´•േരàµâ€à´¸àµ€à´µàµ കോളàµâ€ ലൂപിലàµâ€ അനിശàµà´šà´¿à´¤à´®à´¾à´¯à´¿ à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "(?P-നൠശേഷം അപരിചിതമായ à´•àµà´¯à´¾à´°à´•àµà´Ÿà´°àµâ€" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "ഉപമാതൃകയàµà´Ÿàµ† പേരിലàµâ€ ടെരàµâ€à´®à´¿à´¨àµ‡à´±àµà´±à´°àµâ€ ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "à´°à´£àµà´Ÿàµàµ named ഉപമാതൃകകളàµâ€à´•àµà´•àµàµ ഒരേ പേരàµàµ" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "തെറàµà´±à´¾à´¯ \\P à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ \\p à´•àµà´°à´®à´‚" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "അപരിചിതമായ വിശേഷത നാമം \\P à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ \\p" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ഉപമാതൃക നാമം വളരെ വലàµà´¤à´¾à´£àµàµ (കൂടിയതàµàµ 32 à´…à´•àµà´·à´°à´™àµà´™à´³àµâ€)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "അവനധി named ഉപമാതൃകകളàµâ€ (കൂടിയാലàµâ€ 10,000)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "à´’à´•àµà´Ÿà´²àµâ€ മൂലàµà´²àµà´¯à´‚ \\377-നേകàµà´•ാളàµâ€ വലàµà´¤à´¾à´•àµà´¨àµà´¨àµ" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "overran compiling workspace" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "à´®àµà´®àµà´ªàµàµ പരിശോധിചàµà´šà´¿à´Ÿàµà´Ÿàµà´³àµà´³ സൂചന ഉപമാതൃകകളàµâ€ ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE à´—àµà´°àµ‚à´ªàµà´ªà´¿à´²àµâ€ à´’à´¨àµà´¨à´¿à´²àµâ€ കൂടàµà´¤à´²àµâ€ à´¬àµà´°à´¾à´žàµà´šàµà´•à´³àµà´£àµà´Ÿàµàµ" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "à´¸àµà´¥à´¿à´°à´¤à´¯à´¿à´²àµà´²à´¾à´¤àµà´¤ NEWLINE ഉപാധികളàµâ€" + +#: ../glib/gregex.c:476 +#, fuzzy +#| msgid "" +#| "\\g is not followed by a braced name or an optionally braced non-zero " +#| "number" +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g is not followed by a braced name or an optionally braced non-zero number" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "" + +#: ../glib/gregex.c:492 +#, fuzzy +#| msgid "missing terminator in subpattern name" +msgid "missing subpattern name after (?&" +msgstr "ഉപമാതൃകയàµà´Ÿàµ† പേരിലàµâ€ ടെരàµâ€à´®à´¿à´¨àµ‡à´±àµà´±à´°àµâ€ ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:495 +#, fuzzy +#| msgid "digit expected" +msgid "digit expected after (?+" +msgstr "à´…à´•àµà´•à´‚ ആവശàµà´¯à´®àµà´£àµà´Ÿàµ" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: ../glib/gregex.c:501 +#, fuzzy +#| msgid "two named subpatterns have the same name" +msgid "different names for subpatterns of the same number are not allowed" +msgstr "à´°à´£àµà´Ÿàµàµ named ഉപമാതൃകകളàµâ€à´•àµà´•àµàµ ഒരേ പേരàµàµ" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: ../glib/gregex.c:510 +#, fuzzy +#| msgid "" +#| "\\g is not followed by a braced name or an optionally braced non-zero " +#| "number" +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\g is not followed by a braced name or an optionally braced non-zero number" + +#: ../glib/gregex.c:513 +#, fuzzy +#| msgid "URIs not supported" +msgid "\\N is not supported in a class" +msgstr "à´¯àµà´†à´°àµâ€à´ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: ../glib/gregex.c:522 +#, fuzzy +#| msgid "character value in \\x{...} sequence is too large" +msgid "character value in \\u.... sequence is too large" +msgstr "\\x{...}-à´²àµà´³àµà´³ à´…à´•àµà´·à´° മൂലàµà´²àµà´¯à´‚ വളരെ വലàµà´¤àµàµ" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1899 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "സാധാരണ à´Žà´•àµà´¸àµà´ªàµà´°àµ†à´·à´¨àµâ€ ആയ %s-നൊപàµà´ªà´‚ പൊരàµà´¤àµà´¤à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´®àµà´ªàµ‹à´³àµâ€ പിശകàµ: %s" + +#: ../glib/gregex.c:1319 +msgid "PCRE library is compiled without UTF8 support" +msgstr "UTF8 പിനàµà´¤àµà´£ ഇലàµà´²à´¾à´¤àµ†à´¯à´¾à´£àµ PCRE ലൈബàµà´±à´±à´¿ സംഗàµà´±à´¹à´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ" + +#: ../glib/gregex.c:1323 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"UTF8 à´—àµà´£à´—ണങàµà´™à´³àµà´Ÿàµ† പിനàµà´¤àµà´£ ഇലàµà´²à´¾à´¤àµ†à´¯à´¾à´£àµ PCRE ലൈബàµà´±à´±à´¿ സംഗàµà´±à´¹à´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ" + +#: ../glib/gregex.c:1331 +#, fuzzy +#| msgid "PCRE library is compiled without UTF8 properties support" +msgid "PCRE library is compiled with incompatible options" +msgstr "" +"UTF8 à´—àµà´£à´—ണങàµà´™à´³àµà´Ÿàµ† പിനàµà´¤àµà´£ ഇലàµà´²à´¾à´¤àµ†à´¯à´¾à´£àµ PCRE ലൈബàµà´±à´±à´¿ സംഗàµà´±à´¹à´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ" + +#: ../glib/gregex.c:1390 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"സാധാരണ à´Žà´•àµà´¸àµà´ªàµà´°àµ†à´·à´¨àµâ€ ആയ %s കംപൈലàµâ€ ചെയàµà´¯àµà´®àµà´ªàµ‹à´³àµâ€ %d à´Žà´¨àµà´¨ à´…à´•àµà´·à´°à´¤àµà´¤à´¿à´²àµâ€ പിശകൠ: " +"%s" + +#: ../glib/gregex.c:1432 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "%s à´Žà´¨àµà´¨ സാധാരണ à´Žà´•àµà´¸àµà´ªàµà´°àµ†à´·à´¨àµâ€ കൈകാരàµà´¯à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../glib/gregex.c:2331 +msgid "hexadecimal digit or '}' expected" +msgstr "ഹെകàµà´¸à´¾ ഡെസിമലàµâ€ à´…à´•àµà´•à´‚ à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ '}' ആവശàµà´¯à´®àµà´£àµà´Ÿàµ " + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit expected" +msgstr "ഹെകàµà´¸à´¾ ഡെസിമലàµâ€ à´…à´•àµà´•à´‚ ആവശàµà´¯à´®àµà´£àµà´Ÿàµ" + +#: ../glib/gregex.c:2387 +msgid "missing '<' in symbolic reference" +msgstr "സിംപോളികൠസൂചനയിലàµâ€ '<' ലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gregex.c:2396 +msgid "unfinished symbolic reference" +msgstr "പൂരàµâ€à´£àµà´£à´®à´¾à´•ാതàµà´¤ സിംപോളികൠസൂചനാ" + +#: ../glib/gregex.c:2403 +msgid "zero-length symbolic reference" +msgstr "zero-length symbolic reference" + +#: ../glib/gregex.c:2414 +msgid "digit expected" +msgstr "à´…à´•àµà´•à´‚ ആവശàµà´¯à´®àµà´£àµà´Ÿàµ" + +#: ../glib/gregex.c:2432 +msgid "illegal symbolic reference" +msgstr "തെറàµà´±à´¾à´¯ സിംപോളികൠസൂചനാ" + +#: ../glib/gregex.c:2494 +msgid "stray final '\\'" +msgstr "stray final '\\'" + +#: ../glib/gregex.c:2498 +msgid "unknown escape sequence" +msgstr "അപരിചിതമായ à´Žà´¸àµà´•േപàµà´ªàµ സീകàµà´µà´¨àµâ€à´¸àµ" + +#: ../glib/gregex.c:2508 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" +"പകരമായàµà´³à´³ ടെകàµà´¸àµà´±àµà´±àµ ആയ \"%s\" %lu-à´²àµâ€ പാഴàµà´¸àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´¨à´¿à´Ÿà´¯à´¿à´²àµâ€ പിശകàµ: %s" + +#: ../glib/gshell.c:88 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" +"à´Žà´Ÿàµà´¤àµà´¤àµ കാണികàµà´•àµà´¨àµà´¨ ടെസàµà´±àµà´±à´¿à´¨àµà´±àµ† ആരംഭതàµà´¤à´¿à´²àµâ€ കൊടàµà´Ÿàµ‡à´·à´¨àµâ€ മാറàµâ€à´•àµà´•ൠലഭàµà´¯à´®à´²àµà´²" + +#: ../glib/gshell.c:178 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"കമാനàµâ€à´¡àµ ലൈനàµâ€ à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ മറàµà´±àµ ഷെലàµâ€-കോടàµà´Ÿà´Ÿàµ ടെകàµà´¸àµà´±àµà´±à´¿à´²àµâ€ " +"ചേറàµâ€à´šàµà´šà´¯à´¿à´²àµà´²à´¾à´¤àµà´¤ അടയാളം" + +#: ../glib/gshell.c:574 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" +"'\\' à´…à´•àµà´·à´°à´¤àµà´¤à´¿à´¨àµ ശേഷം ഉടനàµâ€ തനàµà´¨àµ† വാചകം അവസാനിചàµà´šàµ. ('%s' ആയിരàµà´¨àµà´¨àµ വാചകം)" + +#: ../glib/gshell.c:581 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "%c-à´¨àµà´±àµ† അവസാനം കോടàµà´Ÿàµ ഇടàµà´Ÿà´¿à´Ÿàµà´Ÿà´¿à´²àµà´². ('%s' ആണൠടെകàµà´¸àµà´±àµà´±àµ)" + +#: ../glib/gshell.c:593 +msgid "Text was empty (or contained only whitespace)" +msgstr "" +"വാചകം ശൂനàµà´¯à´®à´¾à´¯à´¿à´°àµà´¨àµà´¨àµ (à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ ഇതിലàµâ€ വയിറàµà´±àµ à´¸àµà´ªàµ†à´¯à´¿à´¸àµ മാതàµà´°à´®àµ‡ ഉളളൂ)" + +#: ../glib/gspawn.c:203 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯à´¯à´¿à´²àµâ€ നിനàµà´¨àµà´‚ വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn.c:362 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯à´¯à´¿à´²àµâ€ (%s) നിനàµà´¨àµà´‚ ഡേറàµà´±à´¾ വായികàµà´•àµà´®àµà´ªàµ‹à´³àµâ€ select()-à´²àµâ€ " +"à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ പിശകൠ" + +#: ../glib/gspawn.c:853 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: ../glib/gspawn.c:861 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:868 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:875 +#, c-format +msgid "Child process exited abnormally" +msgstr "ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯ ശരിയായി à´ªàµà´±à´¤àµà´¤àµàµ à´•à´Ÿà´¨àµà´¨à´¿à´²àµà´²" + +#: ../glib/gspawn.c:1280 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ചൈളàµâ€à´¡àµ പൈപàµà´ªà´¿à´²àµâ€ നിനàµà´¨àµà´‚ വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn.c:1348 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn.c:1496 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "ഡയറകàµà´Ÿà´±à´¿ '%s'-ലേകàµà´•ൠമാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn.c:1506 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" +"ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯ \"%s\" (%s) à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ " + +#: ../glib/gspawn.c:1516 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯à´¯àµà´Ÿàµ† ഔടàµà´Ÿàµ à´ªàµà´Ÿàµà´Ÿàµ à´…à´²àµà´²àµ†à´™àµà´•à´¿à´²àµâ€ ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ തിരിചàµà´šàµ " +"വിടàµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn.c:1525 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯ fork ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn.c:1533 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" +"ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯ \"%s\" à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ പിശകàµ" + +#: ../glib/gspawn.c:1557 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"ചൈളàµâ€à´¡àµ pid പൈപàµà´ªà´¿à´¨àµâ€ നിനàµà´¨àµà´‚ ആവശàµà´¯à´¤àµà´¤à´¿à´¨àµà´³à´³ ഡേറàµà´±à´¾ വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ " +"പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn.c:1630 ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯à´¯àµà´®à´¾à´¯à´¿ ബനàµà´§à´ªàµà´ªàµ†à´Ÿàµà´¨àµà´¨à´¤à´¿à´¨àµà´³à´³ പൈപàµà´ªàµ ഉണàµà´Ÿà´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ " +"പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯à´¯à´¿à´²àµâ€ നിനàµà´¨àµà´‚ വായികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯ à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "അസാധàµà´µà´¾à´¯ à´ªàµà´°àµ‹à´—àµà´°à´¾à´‚ നാമം: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d-à´²àµâ€ ആരàµâ€à´—àµà´¯àµà´®àµ†à´¨àµà´±àµ വെകàµà´±àµà´±à´±à´¿à´²àµâ€ അസാധàµà´µà´¾à´¯ à´¸àµà´Ÿàµà´°à´¿à´™àµ: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "à´Žà´¨àµâ€à´µà´¿à´±àµ‹à´£àµâ€à´®àµ†à´¨àµà´±à´¿à´²àµâ€ അസാധàµà´µà´¾à´¯ à´¸àµà´Ÿàµà´°à´¿à´™àµ: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´•àµà´•àµà´¨àµà´¨ ഡയറകàµà´Ÿà´±à´¿ അസാധàµà´µà´¾à´£àµ: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "സഹായതàµà´¤à´¿à´¨àµà´³à´³ à´ªàµà´°àµ‹à´—àµà´°à´¾à´‚ à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"ചൈളàµâ€à´¡àµ à´ªàµà´°à´•àµà´°à´¿à´¯à´¯à´¿à´²àµâ€ നിനàµà´¨àµà´‚ ഡേറàµà´±à´¾ വായികàµà´•àµà´®àµà´ªàµ‹à´³àµâ€ " +"g_io_channel_win32_poll()-à´²àµâ€ " +"à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ പിശകൠ" + +#: ../glib/gutf8.c:907 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 പരിധിയിലàµâ€ നിനàµà´¨àµà´‚ à´ªàµà´±à´¤àµà´¤à´¾à´£àµ à´…à´•àµà´·à´°à´‚" + +#: ../glib/gutf8.c:1007 ../glib/gutf8.c:1016 ../glib/gutf8.c:1146 +#: ../glib/gutf8.c:1155 ../glib/gutf8.c:1294 ../glib/gutf8.c:1390 +msgid "Invalid sequence in conversion input" +msgstr "ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ വേരàµâ€à´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ അസാധàµà´µà´¾à´¯ à´•àµà´°à´®à´‚" + +#: ../glib/gutf8.c:1305 ../glib/gutf8.c:1401 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 പരിധിയിലàµâ€ നിനàµà´¨àµà´‚ à´ªàµà´±à´¤àµà´¤à´¾à´£àµ à´…à´•àµà´·à´°à´‚" + +#: ../glib/gutils.c:2183 ../glib/gutils.c:2210 ../glib/gutils.c:2314 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ബൈറàµà´±àµ" +msgstr[1] "%u ബൈറàµà´±àµà´•à´³àµâ€" + +#: ../glib/gutils.c:2189 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2191 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2194 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2197 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2200 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2203 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2216 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2219 ../glib/gutils.c:2332 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2222 ../glib/gutils.c:2337 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2224 ../glib/gutils.c:2342 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2227 ../glib/gutils.c:2347 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2230 ../glib/gutils.c:2352 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2267 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ബൈറàµà´±àµ" +msgstr[1] "%s ബൈറàµà´±àµà´•à´³àµâ€" + +msgctxt "full month name with day" +msgid "January" +msgstr "ജനàµà´µà´°à´¿" + +msgctxt "full month name with day" +msgid "February" +msgstr "ഫെബàµà´°àµà´µà´°à´¿" + +msgctxt "full month name with day" +msgid "March" +msgstr "മാരàµâ€à´šàµà´šàµ" + +msgctxt "full month name with day" +msgid "April" +msgstr "à´à´ªàµà´°à´¿à´²àµâ€ " + +msgctxt "full month name with day" +msgid "May" +msgstr "മെയàµ" + +msgctxt "full month name with day" +msgid "June" +msgstr "ജൂണàµâ€" + +msgctxt "full month name with day" +msgid "July" +msgstr "ജൂലൈ" + +msgctxt "full month name with day" +msgid "August" +msgstr "à´“à´—à´¸àµà´±àµà´±àµ" + +msgctxt "full month name with day" +msgid "September" +msgstr "സെപàµà´Ÿà´‚ബരàµâ€" + +msgctxt "full month name with day" +msgid "October" +msgstr "à´’à´•àµà´Ÿàµ‹à´¬à´°àµâ€" + +msgctxt "full month name with day" +msgid "November" +msgstr "നവംബരàµâ€" + +msgctxt "full month name with day" +msgid "December" +msgstr "ഡിസംബരàµâ€" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ജനàµ" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ഫെബàµ" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "മാരàµâ€" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "à´à´ªàµà´°" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "മെ" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "ജൂണàµâ€" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "ജൂ" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "à´“" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "സെപàµà´Ÿ" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "à´’à´•àµà´Ÿàµ‹" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "നവം" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "à´¡à´¿" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2327 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "ശൂനàµà´¯à´®à´¾à´¯ സബൠസàµà´Ÿàµà´°à´¿à´™àµà´™à´³àµà´•à´³àµâ€à´•àµà´•àµà´³à´³ പണിയിടതàµà´¤à´¿à´¨àµà´³à´³ പരിധി à´Žà´¤àµà´¤à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "കെയിസàµ-ചെഞàµà´šà´¿à´™àµ à´Žà´¸àµà´•േപàµà´ªàµà´•à´³àµâ€ (\\l, \\L, \\u, \\U) ഇവിടെ à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´²àµà´²" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "ഒരൠDEFINE à´—àµà´°àµ‚à´ªàµà´ªàµ" + +#~ msgid "Unexpected error in waitpid() (%s)" +#~ msgstr "waitpid()-à´²àµâ€ à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯ പിശകൠ(%s)" + +#~ msgid "File is empty" +#~ msgstr "ഫയലàµâ€ ശൂനàµà´¯à´®à´¾à´£àµ" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "തിരിചàµà´šà´±à´¿à´¯àµà´µà´¾à´¨àµâ€ കഴിയാതàµà´¤ മൂലàµà´²àµà´¯à´®àµà´³à´³ കീ '%s' കീ ഫയലിലàµà´£àµà´Ÿàµ" + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "'%s' à´Žà´¨àµà´¨ ഫയലàµâ€ à´¸àµà´±àµà´±à´¾à´±àµà´±àµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s'-à´¨àµàµ സരàµâ€à´µàµ€à´¸àµ റികàµà´•ോരàµâ€à´¡àµ ലഭàµà´¯à´®à´²àµà´²" + +#~ msgid "Error connecting: " +#~ msgstr "കണകàµà´Ÿàµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: " + +#~ msgid "Error connecting: %s" +#~ msgstr "കണകàµà´Ÿàµ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകൠ: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "യൂണികàµà´¸à´¿à´²àµâ€ നിനàµà´¨àµà´‚ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "യൂണികàµà´¸àµ à´…à´Ÿà´¯àµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "യൂണികàµà´¸à´¿à´²àµ‡à´•àµà´•ൠഎഴàµà´¤àµà´¨àµà´¨à´¤à´¿à´²àµâ€ പിശകàµ: %s" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "ഒരൠഡയറകàµà´Ÿà´±à´¿à´¯à´¿à´²àµâ€ മറàµà´±àµŠà´°àµ ഡയറകàµà´Ÿà´±à´¿ നീകàµà´•àµà´µà´¾à´¨àµâ€ സാധàµà´¯à´®à´²àµà´²" + +#, fuzzy +#~ msgid "Key %s is not writable\n" +#~ msgstr "%s തരതàµà´¤à´¿à´²àµà´³àµà´³à´¤àµàµ à´•àµà´²à´¾à´¸àµà´¸àµ ചെയàµà´¤à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "ഇനàµâ€à´ªàµà´Ÿàµà´Ÿàµ വേരàµâ€à´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµâ€ അസാധàµà´µà´¾à´¯ à´•àµà´°à´®à´‚" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "à´à´±àµà´±à´µàµà´‚ കൂടàµà´¤à´²à´¾à´¯ ഡേറàµà´±à´¾ അറേ പരിധി à´Žà´¤àµà´¤à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ" + +#~ msgid "do not hide entries" +#~ msgstr "à´Žà´¨àµâ€à´Ÿàµà´°à´¿à´•à´³àµâ€ അദൃശàµà´¯à´®à´¾à´•àµà´•à´°àµà´¤àµàµ" + +#~ msgid "use a long listing format" +#~ msgstr "ലോങൠലിസàµà´±àµà´±à´¿à´™àµ ഫോരàµâ€à´®à´¾à´±àµà´±àµ ഉപയോഗികàµà´•àµà´•" diff --git a/po/mn.po b/po/mn.po new file mode 100644 index 0000000..788fbef --- /dev/null +++ b/po/mn.po @@ -0,0 +1,3852 @@ +# translation of glib.HEAD.po to Mongolian +# translation of glib.HEAD.mn.po to Mongolian +# translation of glib.HEAD.po to mongolian +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Sanlig Badral , 2003. +# Sanlig Badral , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2005-05-30 01:07-0800\n" +"Last-Translator: Бадрал \n" +"Language-Team: Mongolian \n" +"Language: mn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0.2\n" +"Plural-Forms: 2\n" +"X-Poedit-Language: Mongolian\n" +"X-Poedit-Country: MONGOLIA\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: ../glib/gbookmarkfile.c:780 +#, fuzzy, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" +"Сонин Ñ‚ÑмдÑгт »%s«, »%s« Ñлементийн »%s« аттрибутын нÑрийн дараа »=« " +"хүлÑÑгдÑж байна" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +#, fuzzy +msgid "No valid bookmark file found in data dirs" +msgstr "Өгөгдлийн Ð»Ð°Ð²Ð»Ð°Ñ…Ð°Ð°Ñ Ñ…Ò¯Ñ‡Ð¸Ð½Ñ‚Ñй утга олдÑонгүй" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "»%s« Ñимволик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ ÑƒÐ½ÑˆÐ¸Ð³Ð´Ñангүй: %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "ТÑмдÑгт олонлог »%s« ÑÑÑ Â»%s« Ñ€Ò¯Ò¯ хөрвүүлÑÑ… дÑмжигдÑÑгүй байна" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "»%s« ÑÑÑ Â»%s« Ñ€Ò¯Ò¯ хөрвүүлÑгч нÑÑгдÑÑнгүй" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "ХөрвүүлÑлтийн оролтод хүчингүй байт дараалал байна" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Оролтын төгÑгөлд Ñ…Ð°Ð³Ð°Ñ Ñ‚ÑмдÑгтийн дараалал" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "»%s« ухарч »%s« кодчилол руу хөрвөхгүй байна" + +# CHECK +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI »%s« нь файл Ñхемд Ñ…ÑÑ€ÑглÑгддÑг үнÑмлÑхүй хаÑг биш" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "Дотоод URI »%s« нь »#« -г агуулж болохгүй" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "»%s« URI хүчингүй" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI »%s« -н хоÑтын нÑÑ€ хүчингүй" + +# CHECK +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "»%s« URI хүчингүй Escape-Ñ‚ÑмдÑгт агуулж байна" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "»%s« замын нÑÑ€ үнÑмлÑхүй зам биш" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Хүчингүй хоÑтын нÑÑ€" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Y %b %d, %a %T" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%Y.%m.%d" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Хулгана Ñарын" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "ҮхÑÑ€ Ñарын" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Бар Ñарын" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "Туулай Ñарын" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Луу Ñарын" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Могой Ñарын" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Морь Ñарын" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Хул" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ҮхÑ" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Бар" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Туу" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Луу" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Мог" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Мор" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Даваа" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "МÑгмар" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Лхагва" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ПүрÑв" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "БааÑан" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "БÑмба" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ÐÑм" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Да" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "МÑ" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Лх" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Пү" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Ба" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "БÑ" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ÐÑ" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "»%s« лавлахыг нÑÑÑ…Ñд алдаа: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "%lu байтуудыг »%s« файлыг уншихдаа байрлуулж чадÑангүй" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "»%s« Ñ„Ð°Ð¹Ð»Ð°Ð°Ñ ÑƒÐ½ÑˆÐ¸Ð¶ болохгүй байна: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "»%s« файлын аттрибут тодорхойлогдÑонгүй: fstat() нурлаа: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gfileutils.c:862 +#, fuzzy, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "»%s« файл Ò¯Ò¯ÑгÑгдÑÑнгүй: %s" + +#: ../glib/gfileutils.c:918 +#, fuzzy, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gfileutils.c:943 +#, fuzzy, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gfileutils.c:1030 +#, fuzzy, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "»%s« Ñ…Ñв хүчингүй, »%s« -г агуулах Ñ…ÑÑ€Ñггүй" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "»%s« Ñ…Ñв XXXXXX -Ñ€ төгÑөхгүй байна" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "»%s« Ñимволик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ ÑƒÐ½ÑˆÐ¸Ð³Ð´Ñангүй: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../glib/giochannel.c:1408 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "»%s« -ÑÑÑ Â»%s« Ñ€Ò¯Ò¯ хөрвүүлÑгч нÑÑгдÑÑнгүй: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Raw-read in g_io_channel_read_line_string боломжгүй" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Унших буфÑрт хөрвүүлÑÑгүй файл байна" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Суваг тал Ñ‚ÑмдÑгтÑÑÑ€ төгÑлөө" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Raw-read in g_io_channel_read_to_end боломжгүй" + +#: ../glib/gmappedfile.c:150 +#, fuzzy, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gmappedfile.c:229 +#, fuzzy, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "%d мөрөнд %d Ñ‚ÑмдÑгт алдаатай байна: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Хүчингүй UTF-8-Ñ€ кодлогдÑон текÑÑ‚" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d мөрөнд алдаа: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"»%-.*s« Ñ‚ÑмдÑгтийн дотор тоо байх Ñ‘Ñтой (ê шиг) , задлан Ñлгалд " +"танигдÑангүй - магадгүй Ñ…ÑÑ‚Ñрхий том тоо байна уу" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"ТÑмдÑгт Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ñ†Ñг таÑлалаар төгÑөөгүй байна; Та магад амперÑандыг абтын " +"ÑхлÑл буÑаар Ñ…ÑÑ€ÑглÑхийг Ñ…Ò¯ÑÑÑн байх - Та & гÑж Ð±Ð¸Ñ‡Ð½Ñ Ò¯Ò¯" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "»%-.*s« Ñ‚ÑмдÑгт Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð·Ó©Ð²ÑˆÓ©Ó©Ñ€Ó©Ð³Ð´Ó©Ó©Ð³Ò¯Ð¹ Ñ‚ÑмдÑгтÑÑÑ€ кодлогдÑон байна" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"ХооÑон абт »&;« олдлоо; хүчинтÑй абтууд & " < > ' юм. " +"(абт=аÑкий биш Ñ‚ÑмдÑгт)" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Ðбтын нÑÑ€ »%s« тодорхойгүй" + +# CHECK +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Ðбт цÑг таÑлалаар төгÑөөгүй байна; Та магад амперÑандыг абтын ÑхлÑл буÑаар " +"Ñ…ÑÑ€ÑглÑхийг Ñ…Ò¯ÑÑÑн байх - Та & гÑж Ð±Ð¸Ñ‡Ð½Ñ Ò¯Ò¯" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Баримт Ñмар нÑгÑн ÑлементÑÑÑ€ ÑхлÑÑ… Ñ‘Ñтой (Ж.нь )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"»%s« нь »<«-Ñ‚ÑмдÑгтийн арын хүчингүй Ñ‚ÑмдÑгт; Ð­Ð½Ñ Ð½ÑŒ Ñлементийн нÑÑ€ÑÑÑ€ ÑÑ…Ñлж " +"болохгүй." + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Сонин Ñ‚ÑмдÑгт »%s«, »%s« Ñлементийн ÑхлÑлийн тагийг хаахад »>« Ñ‚ÑмдÑгт дутуу " +"байна" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Сонин Ñ‚ÑмдÑгт »%s«, »%s« Ñлементийн »%s« аттрибутын нÑрийн дараа »=« " +"хүлÑÑгдÑж байна" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Сонин Ñ‚ÑмдÑгт »%s«, »%s« Ñлементийн ÑхлÑлийн тагийг хаахын тулд аттрибутын " +"нÑÑ€ ÑÑвÑл харин »>« ÑÑвÑл »/« Ñ‚ÑмдÑгт хүлÑÑгдÑж байна; Магадгүй та " +"аттрибутын нÑÑ€ÑндÑÑ Ñ…Ò¯Ñ‡Ð¸Ð½Ð³Ò¯Ð¹ Ñ‚ÑмдÑгт Ñ…ÑÑ€ÑглÑжÑÑ" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Сонин Ñ‚ÑмдÑгт »%s«; »%s« Ñлементийн »%s« аттрибутын хувьд өгÑөн утга " +"Ñ‚Ñнцүүгийн Ñ‚ÑмдÑгийн дараах хашилтыг хүлÑÑж байна" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"»%s« хүчингүй Ñ‚ÑмдÑгт, Ñ…ÑрвÑÑ ÑÐ½Ñ Ð½ÑŒ хааж буй »%s« Ñлементийн нÑрийн ард " +"байгаа бол; »>« Ñ‚ÑмдÑгт хүчинтÑй" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "»%s« Ñлемент хаагдÑан, Одоогоор Ñмарч Ñлемент нÑÑлттÑй Ð±ÑƒÑ Ð±Ð°Ð¹Ð½Ð°" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "»%s« Ñлемент хаагдÑан, харин одоогоор »%s« Ñлемент нÑÑлттÑй байна" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Баримт хооÑон ÑÑвÑл зүгÑÑÑ€ цагаан зай агуулж байна" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Баримт нÑÑлттÑй өнцөгтÑй хаалт »<« -н дараа гÑнÑÑ‚ төгÑөв" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Баримт нÑÑлттÑй ÑлементүүдтÑйгÑÑÑ€ гÑнÑтийн байдлаар төгÑөв - »%s« Ñүүлчийн " +"нÑÑлттÑй Ñлемент нь" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Баримт гÑнÑтийн байдлаар төгÑөв, таг <%s/> -г хаах өнцөгтÑй хаалт " +"»>«хүлÑÑгдÑж байна" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Баримт нÑгÑн Ñлементийн нÑрийн дотор гÑнÑтийн байдлаар төгÑөв" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Баримт нÑгÑн аттрибут нÑрийн дотор гÑнÑтийн байдлаар төгÑөв" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Баримт нÑÑгдÑж буй тагийн нÑгÑн Ñлементийн нÑрийн дотор гÑнÑтийн байдлаар " +"төгÑөв." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Баримт аттрибут нÑрийн дараах Ñ‚Ñнцүүгийн Ñ‚ÑмдÑгийн дараа гÑнÑтийн байдлаар " +"төгÑөв; аттрибутын утга алга" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Баримт нÑгÑн аттрибутын утгын дотор гÑнÑтийн байдлаар төгÑөв" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"Баримт гÑнÑтийн байдлаар нÑгÑн хаагдаж буй »%s« Ñлементийн тагийн дотор " +"төгÑөв" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Баримт тайлбар ÑÑвÑл заавар боловÑруулалтын дотор гÑнÑтийн байдлаар төгÑөв" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "Суваг тал Ñ‚ÑмдÑгтÑÑÑ€ төгÑлөө" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "ХөрвүүлÑлтийн оролтод хүчингүй байт дараалал байна" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "ТөгÑгөлгүй Ñ‚ÑмдÑгт холбооÑ" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "ТөгÑгөлгүй Ñ‚ÑмдÑгт холбооÑ" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "ТөгÑгөлгүй Ñ‚ÑмдÑгт холбооÑ" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "%d мөрөнд %d Ñ‚ÑмдÑгт алдаатай байна: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "ТөгÑгөлгүй абт холбооÑ" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Хашилтан доторхи текÑÑ‚ хашилтаар ÑхлÑхгүй" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Тушаалын мөр дÑÑ… ÑÑвÑл Ó©Ó©Ñ€ shell-quoted текÑÑ‚ доторхи хашилтын тоо " +"баланÑжаагүй байна" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "ТекÑÑ‚ »\\«-Ñ‚ÑмдÑгтийн дараа төгÑлөө. (ТекÑÑ‚ »%s« байÑан)" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "ТекÑÑ‚ %c -н тохирох хашилт Ð¾Ð»Ð´Ð¾Ñ…Ð¾Ð¾Ñ Ó©Ð¼Ð½Ó© төгÑлөө. (ТекÑÑ‚ »%s« байÑан)" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "ТекÑÑ‚ хооÑон байв (ÑÑвÑл зөвхөн цагаан зай агуулÑан)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Өгөгдөл Ñ…Ò¯Ò¯ процеÑÑоор уншигдÑангүй" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Ð¥Ò¯Ò¯ процеÑÑтой (%s) холбогдох шугам Ò¯Ò¯ÑгÑж чадÑангүй" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Ð¥Ò¯Ò¯ процеÑÑын (%s) ÑˆÑƒÐ³Ð°Ð¼Ð°Ð°Ñ ÑƒÐ½ÑˆÐ¸Ñ… бүтÑлгүйтлÑÑ" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "»%s« (%s) лавлах ÑолигдÑонгүй" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Ð¥Ò¯Ò¯ процеÑÑ Ð°Ð¶Ð¸Ð»Ð»Ð°Ñангүй (%s)" + +#: ../glib/gspawn-win32.c:444 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "Хүчингүй хоÑтын нÑÑ€" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, fuzzy, c-format +msgid "Invalid string in environment: %s" +msgstr "ХөрвүүлÑлтийн оролтод хүчингүй дараалал" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, fuzzy, c-format +msgid "Invalid working directory: %s" +msgstr "»%s« лавлахыг нÑÑÑ…Ñд алдаа: %s" + +#: ../glib/gspawn-win32.c:783 +#, fuzzy, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ТуÑламж программ ажиллахгүй байна" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ð¥Ò¯Ò¯ процеÑÑÐ¾Ð¾Ñ Ó©Ð³Ó©Ð³Ð´Ó©Ð» уншиж байхад g_io_channel_win32_poll() дотор " +"ÑанамÑаргүй алдаа гарлаа" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Ð¥Ò¯Ò¯ процеÑÑын (%s) өгөгдөл уншигдÑаж чадÑангүй" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Ð¥Ò¯Ò¯ процеÑÑÐ¾Ð¾Ñ (%s) өгөгдөл уншиж байхад select() дотор ÑанамÑаргүй алдаа " +"гарлаа" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "СанамÑаргүй алдаа waitpid() дотор (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Салаалалт нурлаа (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Ð¥Ò¯Ò¯ процеÑÑ Â»%s« -г ажиллуулах нурлаа (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Ð¥Ò¯Ò¯ процеÑÑийн (%s) гаралт ÑÑвÑл оролтыг Ñолих нурлаа" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Ð¥Ò¯Ò¯ процеÑÑын (%s) Ñалаалалт нурлаа" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "»%s« Ñ…Ò¯Ò¯ процеÑÑыг ажиллуулж байхад тодорхойгүй алдаа" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Ð¥Ò¯Ò¯ процеÑÑын процеÑÑын дугаарын ÑˆÑƒÐ³Ð°Ð¼Ð°Ð°Ñ (%s) хангалттай өгөгдөл уншиж " +"чадÑангүй" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 Ñ…ÑÐ·Ð³Ð°Ð°Ñ€Ð°Ð°Ñ Ð³Ð°Ð´Ð½Ð°Ñ… Ñ‚ÑмдÑгт" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "ХөрвүүлÑлтийн оролтод хүчингүй дараалал" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 Ñ…ÑÐ·Ð³Ð°Ð°Ñ€Ð°Ð°Ñ Ð³Ð°Ð´Ð½Ð°Ñ… Ñ‚ÑмдÑгт" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Ð¥ÑÑ€ÑглÑÑ:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "ТуÑламж:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "ТуÑламж харуулах" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Бүх туÑламж харуулах" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Програм:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, fuzzy, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "'%s' бүхÑл тоог --%s -н хувьд шинжлÑÑ… боломжгүй" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "'%s' бүхÑл %s -н хувьд Ñ…ÑÐ·Ð³Ð°Ð°Ñ€Ð°Ð°Ñ Ñ…Ð°Ð»ÑŒÐ¶ÑÑ" + +#: ../glib/goption.c:1032 +#, fuzzy, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "'%s' бүхÑл тоог --%s -н хувьд шинжлÑÑ… боломжгүй" + +#: ../glib/goption.c:1040 +#, fuzzy, c-format +msgid "Double value '%s' for %s out of range" +msgstr "'%s' бүхÑл %s -н хувьд Ñ…ÑÐ·Ð³Ð°Ð°Ñ€Ð°Ð°Ñ Ñ…Ð°Ð»ÑŒÐ¶ÑÑ" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Тодорхойгүй утга %s" + +#: ../glib/gkeyfile.c:366 +#, fuzzy +msgid "Valid key file could not be found in search dirs" +msgstr "Өгөгдлийн Ð»Ð°Ð²Ð»Ð°Ñ…Ð°Ð°Ñ Ñ…Ò¯Ñ‡Ð¸Ð½Ñ‚Ñй утга олдÑонгүй" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Тохиромжгүй файл" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Файл хооÑон" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Түлхүүр файл түлхүүр утга, бүлÑг, ÑÑвÑл тайлбаргүй '%s' мөр агуулж байна." + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "Хүчингүй хоÑтын нÑÑ€" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Түлхүүр файл бүлÑг утгаар ÑхлÑÑ… боломжгүй" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "Хүчингүй хоÑтын нÑÑ€" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Түлхүүр файлд дÑмжигдÑÑгүй кодчилол '%s' байна" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Түлхүүр файлд '%s' бүлÑг алга" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Түлхүүр файлд '%s' түлхүүр алга" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "Түлхүүр файлд '%s' мөр '%s' гÑÑÑн UTF-8 Ð±ÑƒÑ ÑƒÑ‚Ð³Ð°Ñ‚Ð°Ð¹ байна" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "Түлхүүр файлд илÑрхийлÑÑ… боломжгүй '%s' утга байна." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "Түлхүүр файлд илÑрхийлÑÑ… боломжгүй '%s' утга байна." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"Түлхүүр файлын '%2$s' бүлÑгт '%1$s' гÑÑÑн илÑрхийлÑÑ… боломжгүй утга байна." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Түлхүүр файлын '%2$s' бүлÑгт '%1$s' түлхүүр алга" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Түлхүүр файлын мөрийн төгÑгөлд ESC Ñ‚ÑмдÑгт байна" + +# CHECK +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Түлхүүр файлд »%s« хүчингүй escape-Ñ‚ÑмдÑгт байна" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "'%s' утга бүхÑл тоогоор илÑрхийлÑгдÑÑ… боломжгүй." + +#: ../glib/gkeyfile.c:3886 +#, fuzzy, c-format +msgid "Integer value '%s' out of range" +msgstr "'%s' бүхÑл %s -н хувьд Ñ…ÑÐ·Ð³Ð°Ð°Ñ€Ð°Ð°Ñ Ñ…Ð°Ð»ÑŒÐ¶ÑÑ" + +#: ../glib/gkeyfile.c:3919 +#, fuzzy, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "'%s' утга бүхÑл тоогоор илÑрхийлÑгдÑÑ… боломжгүй." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "'%s' утга бүүл утгаар дүрÑлÑгдÑÑ… боломжгүй ." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "ХөрвүүлÑлтийн оролтод хүчингүй байт дараалал байна" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "Тодорхойгүй утга %s" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Тодорхойгүй утга %s" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "»%s« лавлахыг нÑÑÑ…Ñд алдаа: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "»%s« лавлахыг нÑÑÑ…Ñд алдаа: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "%d мөрөнд алдаа: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "»%s« Ñ‚ÑмдÑгт абтын нÑÑ€Ñнд хүчингүй" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "»%s« Ñ‚ÑмдÑгт абтын нÑÑ€Ñнд хүчингүй" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "»%s« Ñ‚ÑмдÑгт абтын нÑÑ€Ñнд хүчингүй" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "»%s« лавлахыг нÑÑÑ…Ñд алдаа: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Хүчингүй хоÑтын нÑÑ€" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "Хүчингүй хоÑтын нÑÑ€" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "»%s« файл Ò¯Ò¯ÑгÑгдÑÑнгүй: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "»%s« файл Ò¯Ò¯ÑгÑгдÑÑнгүй: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "»%s« файл Ò¯Ò¯ÑгÑгдÑÑнгүй: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "»%s« лавлахыг нÑÑÑ…Ñд алдаа: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "»%s« Ñимволик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ ÑƒÐ½ÑˆÐ¸Ð³Ð´Ñангүй: %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "Баримт нÑгÑн аттрибут нÑрийн дотор гÑнÑтийн байдлаар төгÑөв" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "»%s« лавлахыг нÑÑÑ…Ñд алдаа: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "%d мөрөнд алдаа: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +#, fuzzy +msgid "Target file is not a regular file" +msgstr "Тохиромжгүй файл" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Хүчингүй хоÑтын нÑÑ€" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Тодорхойгүй утга %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "»%s« файл Ò¯Ò¯ÑгÑгдÑÑнгүй: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "%lu байтуудыг »%s« файлыг уншихдаа байрлуулж чадÑангүй" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "»%s« файл Ò¯Ò¯ÑгÑгдÑÑнгүй: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "»%s« файл Ò¯Ò¯ÑгÑгдÑÑнгүй: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "%d мөрөнд алдаа: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Хөрвүүлж байхад алдаа: %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "Символик Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑмжигдÑÑгүй" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Хүчингүй хоÑтын нÑÑ€" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "ХөрвүүлÑлтийн оролтод хүчингүй дараалал" + +#, fuzzy +#~ msgid "[FILE...]" +#~ msgstr "[OPTION...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Ðбтын нÑрийн ÑхлÑлийн »%s« Ñ‚ÑмдÑгт хүчингүй; Ðбт & Ñ‚ÑмдÑгтÑÑÑ€ ÑÑ…ÑлдÑг; " +#~ "Ð¥ÑрвÑÑ ÑÐ½Ñ Ð°Ð¼Ð¿ÐµÑ€Ñаныг абт бишÑÑÑ€ авах Ñ…ÑÑ€ÑгтÑй бол & гÑж Ð±Ð¸Ñ‡Ð½Ñ Ò¯Ò¯" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "ХооÑон Ñ‚ÑмдÑгтийн холбооÑ; dž гÑÑ… мÑÑ‚ тоо агуулах Ñ‘Ñтой" + +#~ msgid "Unfinished entity reference" +#~ msgstr "ТөгÑгөлгүй абт холбооÑ" + +#~ msgid "Unfinished character reference" +#~ msgstr "ТөгÑгөлгүй Ñ‚ÑмдÑгт холбооÑ" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Хүчингүй UTF-8-Ñ€ кодлогдÑон текÑÑ‚" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Хүчингүй UTF-8-Ñ€ кодлогдÑон текÑÑ‚" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "URI »%s« -н хоÑтын нÑÑ€ хүчингүй" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "URI »%s« -н хоÑтын нÑÑ€ хүчингүй" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Файл »%s« -ыг уншиж байхад алдаа: %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Хөрвүүлж байхад алдаа: %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "»%s« файл нÑÑгдÑхгүй байна: fdopen() нурлаа: %s" + +#~ msgid "Incorrect message size" +#~ msgstr "Буруу мÑдÑÑний Ñ…ÑмжÑÑ" + +#~ msgid "Socket error" +#~ msgstr "Сокет алдаа" diff --git a/po/mr.po b/po/mr.po new file mode 100644 index 0000000..75fceff --- /dev/null +++ b/po/mr.po @@ -0,0 +1,4789 @@ +# translation of mr.po to Marathi +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Sandeep Shedmake , 2008, 2009. +# Sandeep Shedmake , 2009, 2010, 2012, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: mr\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-12 05:54+0000\n" +"PO-Revision-Date: 2014-09-12 18:52+0530\n" +"Last-Translator: Sandeep Shedmake \n" +"Language-Team: Marathi \n" +"Language: mr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Lokalize 1.5\n" + +#: ../gio/gapplication.c:514 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication सरà¥à¤µà¥à¤¹à¤¿à¤¸ मोड दà¥à¤¯à¤¾ (D-Bus सरà¥à¤µà¥à¤¹à¤¿à¤¸ फाइलà¥à¤¸à¤ªà¤¾à¤¸à¥‚न वापर करा)" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "GApplication options" +msgstr "GApplication परà¥à¤¯à¤¾à¤¯" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "GApplication परà¥à¤¯à¤¾à¤¯ दाखवा" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:481 ../gio/gsettings-tool.c:508 +msgid "Print help" +msgstr "मदतची छपाई करा" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:482 +#: ../gio/gresource-tool.c:550 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gapplication-tool.c:49 +#| msgid "Print address" +msgid "Print version" +msgstr "छपाई आवृतà¥à¤¤à¥€" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:514 +msgid "Print version information and exit" +msgstr "आवृतà¥à¤¤à¥€ माहिती छपाई करा व बाहेर पडा" + +#: ../gio/gapplication-tool.c:52 +#| msgid "Can't find application" +msgid "List applications" +msgstr "ॲपà¥à¤²à¤¿à¤•ेशनà¥à¤¸ दाखवा" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"इंसà¥à¤Ÿà¥‰à¤² केलेले D-Bus सकà¥à¤°à¥€à¤¯à¤œà¥‹à¤—ी ॲपà¥à¤²à¤¿à¤•ेशनà¥à¤¸ (.desktop फाइलà¥à¤¸ पà¥à¤°à¤®à¤¾à¤£à¥‡) दाखवा" + +#: ../gio/gapplication-tool.c:55 +#| msgid "Can't find application" +msgid "Launch an application" +msgstr "ॲपà¥à¤²à¤¿à¤•ेशन सà¥à¤°à¥‚ करा" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "ॲपà¥à¤²à¤¿à¤•ेशन सà¥à¤°à¥‚ करा (उघडणà¥à¤¯à¤¾à¤œà¥‹à¤—ी वैकलà¥à¤ªà¤¿à¤• फाइलà¥à¤¸à¤¸à¤¹)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "कृती सà¥à¤°à¥‚ करा" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "ॲपà¥à¤²à¤¿à¤•ेशनवर कृती सà¥à¤°à¥‚ करा" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "उपलबà¥à¤§ कृती दाखवा" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "ॲपà¥à¤²à¤¿à¤•ेशनकरिता सà¥à¤Ÿà¥…टिक कृती दाखवा (.desktop फाइलपासून)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "तपशीलवार मदतचà¥à¤¯à¤¾ छपाईकरिता आदेश" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus रूपण (उदा: org.example.viewer) मधील ॲपà¥à¤²à¤¿à¤•ेशन आइडेंटिफायर" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:488 +#: ../gio/gresource-tool.c:554 +msgid "FILE" +msgstr "FILE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "वैकलà¥à¤ªà¤¿à¤• संबंधित किंवा वैकलà¥à¤ªà¤¿à¤• फाइलनाव, किंवा उघडणà¥à¤¯à¤¾à¤œà¥‹à¤—ी URIs" + +#: ../gio/gapplication-tool.c:73 +#| msgid "SECTION" +msgid "ACTION" +msgstr "कृती" + +#: ../gio/gapplication-tool.c:73 +#| msgid "Destination name to introspect" +msgid "The action name to invoke" +msgstr "सà¥à¤°à¥‚ करणà¥à¤¯à¤¾à¤œà¥‹à¤—ी कृतीचे नाव" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "ॲकà¥à¤¶à¤¨ सकà¥à¤°à¥€à¤¯à¤¤à¤¾à¤¸à¤¾à¤ à¥€ वैकलà¥à¤ªà¤¿à¤• बाब, GVariant सà¥à¤µà¤°à¥‚पात" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:519 +#: ../gio/gsettings-tool.c:594 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"अपरिचीत आदेश %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +#| msgid "Usage:" +msgid "Usage:\n" +msgstr "वापर:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:544 +#: ../gio/gsettings-tool.c:628 +msgid "Arguments:\n" +msgstr "बाब:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[बाबी...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "आदेश:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"तपशीलवार मदतकरिता '%s help COMMAND' आदेशचा वापर करा.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s आदेशला ॲपà¥à¤²à¤¿à¤•ेशन id आवशà¥à¤¯à¤• आहे\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +#| msgid "invalid GVariant type string '%s'" +msgid "invalid application id: '%s'\n" +msgstr "अवैध ॲपà¥à¤²à¤¿à¤•ेशन id: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' कोणतà¥à¤¯à¤¾à¤¹à¥€ बाबी सà¥à¤µà¥€à¤•ारत नाही\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +#| msgid "Could not connect to %s: " +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus: %s सह जोडणी अशकà¥à¤¯\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "%s संदेश पाठवतेवेळी तà¥à¤°à¥à¤Ÿà¥€, ॲपà¥à¤²à¤¿à¤•ेशन: %s करिता\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "ॲपà¥à¤²à¤¿à¤•ेशन id नंतर कृती नाव पाहिजे\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"अवैध कृती नाव: '%s'\n" +"कृती नावात फकà¥à¤¤ अलà¥à¤«à¤¾à¤¨à¥à¤¯à¥à¤®à¥‡à¤°à¤¿à¤•à¥à¤¸, '-' आणि '.' समाविषà¥à¤Ÿà¥€à¤¤ आहे\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "कृती बाब: %s वाचतेवेळी तà¥à¤°à¥à¤Ÿà¥€\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "कृती कमाल à¤à¤• बाब सà¥à¤µà¥€à¤•ारते\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "list-actions आदेश फकà¥à¤¤ ॲपà¥à¤²à¤¿à¤•ेशन id सà¥à¤µà¥€à¤•ारते" + +#: ../gio/gapplication-tool.c:421 +#, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "ॲपà¥à¤²à¤¿à¤•ेशन %s करिता desktop फाइल शोधणे अशकà¥à¤¯\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +#| msgid "" +#| "Unknown command %s\n" +#| "\n" +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"अपरिचीत आदेश: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:370 +#: ../gio/ginputstream.c:608 ../gio/ginputstream.c:828 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:823 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s करीता खूप मोठी पà¥à¤°à¤®à¤¾à¤£ संखà¥à¤¯à¤¾ पà¥à¤°à¤µà¤¿à¤²à¥‡ गेली" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "बेस सà¥à¤Ÿà¥à¤°à¥€à¤®à¤µà¤° सीक समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream टà¥à¤°à¤‚केट करणे अशकà¥à¤¯" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1017 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1464 +msgid "Stream is already closed" +msgstr "शà¥à¤°à¥ƒà¤‚खला आधिपासूनच बंद आहे" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "बेस सà¥à¤Ÿà¥à¤°à¥€à¤®à¤µà¤° टà¥à¤°à¤‚केट समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../gio/gcancellable.c:310 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "कारà¥à¤¯ रदà¥à¤¦ करणà¥à¤¯à¤¾à¤¤ आले" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "अवैध ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ, सà¥à¤°à¥‚ केले नाही" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "इंपà¥à¤Ÿà¤®à¤§à¥€à¤² अपूरà¥à¤£ मलà¥à¤Ÿà¤¿à¤¬à¤¾à¤ˆà¤Ÿ शà¥à¤°à¥ƒà¤‚खला" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "लकà¥à¤·à¥à¤¯à¤®à¤§à¥à¤¯à¥‡ अतिरीकà¥à¤¤ जागा आढळली नाही" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "रूपांतर आगत मधà¥à¤¯à¥‡ अवैध बाईट शà¥à¤°à¥ƒà¤‚खला" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "रूपांतर करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "रदà¥à¤¦ करणà¥à¤¯à¤¾à¤œà¥‹à¤—ी पà¥à¤°à¤¾à¤°à¤‚भ समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "अकà¥à¤·à¤° संच '%s' पासून '%s' असे रूपांतर समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' पासून '%s' असे रूपांतरक उघडू शकले नाही" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s पà¥à¤°à¤•ार" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "अपरिचीत पà¥à¤°à¤•ार" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s फाइलपà¥à¤°à¤•ार" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials या OS वर लागू केले नाही" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "तà¥à¤®à¤šà¥à¤¯à¤¾ पà¥à¤²à¥…टफॉरà¥à¤®à¤•रीता GCredentials समरà¥à¤¥à¤¨ आढळले नाही" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "या OS अंतरà¥à¤—त GCredentials मधà¥à¤¯à¥‡ पà¥à¤°à¥‹à¤¸à¥‡à¤¸ ID समाविषà¥à¤Ÿà¥€à¤¤ नाही" + +#: ../gio/gcredentials.c:565 +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "या OS वरील कà¥à¤°à¥‡à¤¡à¥‡à¤‚शिà¤à¤²à¥à¤¸ सà¥à¤ªà¥‚फिंग शकà¥à¤¯ नाही" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "अपरिचीत पूरà¥à¤µà¤°à¤¤ end-of-stream" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "पतà¥à¤¤à¤¾ नोंदणी '%2$s' मधà¥à¤¯à¥‡ असमरà¥à¤¥à¥€à¤¤ कि '%1$s' आढळली" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"पतà¥à¤¤à¤¾ '%s' अवैध आहे (हà¥à¤¬à¥‡à¤¹à¥à¤¬ à¤à¤• मारà¥à¤—, tmpdir किंवा ॲबà¥à¤¸à¥à¤Ÿà¥à¤°à¥…कà¥à¤Ÿ किजॠआवशà¥à¤¯à¤• " +"आहे)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "पतà¥à¤¤à¤¾ नोंदणी '%s' मधà¥à¤¯à¥‡ अयोगà¥à¤¯ कि/वॅलà¥à¤¯à¥ जोड आढळली" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "पतà¥à¤¤à¤¾ '%s' मधà¥à¤¯à¥‡ तà¥à¤°à¥à¤Ÿà¥€ - पोरà¥à¤Ÿ गà¥à¤£à¤§à¤°à¥à¤® सदोषीत आहे" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "पतà¥à¤¤à¤¾ '%s' मधà¥à¤¯à¥‡ तà¥à¤°à¥à¤Ÿà¥€ - फॅमिलि गà¥à¤£à¤§à¤°à¥à¤® सदोषीत आहे" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "पतà¥à¤¤à¤¾ घटक '%s'मधà¥à¤¯à¥‡ सà¥à¤µà¤²à¥à¤ªà¤µà¤¿à¤°à¤¾à¤® (:) समाविषà¥à¤Ÿà¥€à¤¤ नाही" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" +"कि/वॅलà¥à¤¯à¥ जोड %d, '%s', पतà¥à¤¤à¤¾ घटक '%s' मधà¥à¤¯à¥‡, समांतर चिनà¥à¤¹ समाविषà¥à¤Ÿà¥€à¤¤ नाही" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"कि/वॅलà¥à¤¯à¥ जोड %d, '%s', पतà¥à¤¤à¤¾ घटक '%s' मधà¥à¤¯à¥‡ कि किंवा वॅलà¥à¤¯à¥ सोडतेवेळी तà¥à¤°à¥à¤Ÿà¥€ " +"आढळली" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"पतà¥à¤¤à¤¾ '%s' मधà¥à¤¯à¥‡ तà¥à¤°à¥à¤Ÿà¥€- यà¥à¤¨à¤¿à¤•à¥à¤¸à¥ टà¥à¤°à¤¾à¤‚सपोरà¥à¤Ÿà¤²à¤¾ हà¥à¤¬à¥‡à¤¹à¥à¤¬ à¤à¤• किजॠ'path' किंवा " +"'abstract' " +"करीता निशà¥à¤šà¤¿à¤¤ असावे" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "पतà¥à¤¤à¤¾ '%s' मधà¥à¤¯à¥‡ तà¥à¤°à¥à¤Ÿà¥€ - यजमान गà¥à¤£à¤§à¤°à¥à¤® आढळले नाही किंवा सदोषीत आहे" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" +"पतà¥à¤¤à¤¾ '%s' मधà¥à¤¯à¥‡ तà¥à¤°à¥à¤Ÿà¥€ आढळली - पोरà¥à¤Ÿ गà¥à¤£à¤§à¤°à¥à¤® आढळले नाही किंवा सदोषीत आहे" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" +"पतà¥à¤¤à¤¾ '%s' मधà¥à¤¯à¥‡ तà¥à¤°à¥à¤Ÿà¥€ आढळली - noncefile गà¥à¤£à¤§à¤°à¥à¤® आढळले नाही किंवा सदोषीत आहे" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "सà¥à¤µà¤¯à¤‚ सà¥à¤°à¥‚ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: " + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "अपरिचीत किंवा असमरà¥à¤¥à¥€à¤¤ टà¥à¤°à¤¾à¤‚सà¥à¤ªà¥‹à¤°à¥à¤Ÿ '%s' पतà¥à¤¤à¤¾ '%s' करीता" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "नाà¤à¤¸à¥ फाइल '%s': %s उघडतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "नाà¤à¤¸à¥ फाइल '%s': %s पासून वाचतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "" +"नाà¤à¤¸à¥ फाइल '%s' पासून वाचतेवेळी तà¥à¤°à¥à¤Ÿà¥€, अपेकà¥à¤·à¥€à¤¤ 16 बाइटसà¥, %d पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "नाà¤à¤¸à¥ फाइल '%s' मधील अंतरà¥à¤­à¥à¤¤ माहिती सà¥à¤Ÿà¥à¤°à¤¿à¤®à¤•रीता लिहतेवेळी तà¥à¤°à¥à¤Ÿà¥€:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "दिलेला पतà¥à¤¤à¤¾ रिकामा आहे" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "setuid असलà¥à¤¯à¤¾à¤¸ संदेशला सà¥à¤ªà¥‰à¤¨ करणे अशकà¥à¤¯" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "मशीन-id विना संदेश बस सà¥à¤ªà¥‰à¤¨ करणे अशकà¥à¤¯: " + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "आदेश ओळ '%s' सà¥à¤ªà¥…न करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: " + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(हे पटल बंद करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ कोणतेहि अकà¥à¤·à¤° टाइप करा)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "सतà¥à¤° dbus सà¥à¤°à¥‚ नाही, व autolaunch अपयशी" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "सतà¥à¤° बस पतà¥à¤¤à¤¾ (या OS करीता लागू केले नाही) ओळखणे अशकà¥à¤¯" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"DBUS_STARTER_BUS_TYPE à¤à¤‚वारà¥à¤¯à¤‚मेंट वेरियेबल पासून बस पतà¥à¤¤à¤¾ ओळखणे अशकà¥à¤¯ - " +"अपरिचीत मूलà¥à¤¯ " +"'%s'" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"DBUS_STARTER_BUS_TYPE à¤à¤‚वारà¥à¤¯à¤‚मेंट वेरियेबल सà¥à¤°à¥‚ न केलà¥à¤¯à¤¾à¤¨à¥‡ बस पतà¥à¤¤à¤¾ ओळखणे " +"अशकà¥à¤¯" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "अपरिचीत बस पà¥à¤°à¤•ार %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "ओळ वाचतेवेळी अंतरà¥à¤­à¥à¤¤ माहिती अनपेकà¥à¤·à¥€à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ आढळली नाही" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "ओळ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤ªà¤£à¥‡ वाचतेवेळी अंतरà¥à¤­à¥à¤¤ माहिती अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ आढळली नाही" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"सरà¥à¤µ उपलबà¥à¤§ ओळखपटवणà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ पदà¥à¤§à¤¤à¥€ (वापरलेले: %s) (उपलबà¥à¤§: %s) रिकà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer तरà¥à¤«à¥‡ रदà¥à¤¦ केले" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "डिरेकà¥à¤Ÿà¥à¤°à¥€ '%s': %s करीता माहिती पà¥à¤°à¤¾à¤ªà¥à¤¤ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€ आढळली" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "डिरेकà¥à¤Ÿà¥à¤°à¥€ '%s' वरील सदोषीत आहे. अपेकà¥à¤·à¥€à¤¤ मोड 0700, 0%o पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "डिरेकà¥à¤Ÿà¥à¤°à¥€ '%s': %s निरà¥à¤®à¤¾à¤£ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "वाचणà¥à¤¯à¤¾à¤•रीता किरिंग '%s' उघडतेवेळी तà¥à¤°à¥à¤Ÿà¥€: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"'%2$s' येथील किरिंगमधील ओळ %1$d यावरील अंतरà¥à¤­à¥à¤¤ माहिती '%3$s' सदोषीत आहे" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"अंतरà¥à¤­à¥à¤¤ माहिती '%3$s' सह '%2$s' येथील किरिंगमधील ओळ %1$d मधील पहिले टोकन " +"सदोषीत आहे" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"अंतरà¥à¤­à¥à¤¤ माहिती '%3$s' सह '%2$s' येथील किरिंगमधील ओळ %1$d मधील दà¥à¤¸à¤°à¥‡ टोकन " +"सदोषीत आहे" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "'%2$s' येथे किरिंगमधà¥à¤¯à¥‡ id %1$d सह कूकि आढळले नाही" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "जà¥à¤£à¥€ लॉक फाइल '%s': %s नषà¥à¤Ÿ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€ आढळली" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "लॉक फाइल '%s': %s निरà¥à¤®à¤¾à¤£ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€ आढळली" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "लॉक फाइल '%s': %s बंद करतेवेळी (अनलिंकà¥à¤¡à¥) तà¥à¤°à¥à¤Ÿà¥€ आढळली" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "लॉक फाइल '%s': %s जोडणी अशकà¥à¤¯ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "लिहणà¥à¤¯à¤¾à¤•रीता किरिंग '%s' उघडतेवेळी तà¥à¤°à¥à¤Ÿà¥€: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(वैकलà¥à¤ªà¤¿à¤•रितà¥à¤¯à¤¾, '%s' करीता कà¥à¤²à¥‚पबंद मोकळे करणे अपयशी à¤à¤¾à¤²à¥‡: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "जोडणी बंद à¤à¤¾à¤²à¥€" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "वेळसमापà¥à¤¤à¤¿ पोहचली" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "कà¥à¤²à¤¾à¤à¤‚ट-साइड जोडणी बांधतेवेळी असमरà¥à¤¥à¥€à¤¤ फà¥à¤²à¥…गà¥à¤¸à¥ आढळली" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"मारà¥à¤— %s वर ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿà¤•रीता इंटरफेस 'org.freedesktop.DBus.Properties' आढळले नाही" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "गà¥à¤£à¤§à¤°à¥à¤® '%s' आढळले नाही" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "गà¥à¤£à¤§à¤°à¥à¤® '%s' वाचनजोगी नाही" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "गà¥à¤£à¤§à¤°à¥à¤® '%s' लेखनजोगी नाही" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"गà¥à¤£à¤§à¤°à¥à¤® '%1$s' निशà¥à¤šà¤¿à¤¤ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: अपेकà¥à¤·à¥€à¤¤ पà¥à¤°à¤•ार '%2$s' परंतॠ'%3$s' " +"पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "इंटरफेस '%s' आढळले नाही" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "इंटरफेस आढळले नाही" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "मारà¥à¤— %2$s येथे ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿà¤µà¤° इंटरफेस '%1$s' आढळले नाही" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "मेथड '%s' आढळले नाही" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "संदेशचे पà¥à¤°à¤•ार, '%s', अपेकà¥à¤·à¥€à¤¤ पà¥à¤°à¤•ार '%s' सह जà¥à¤³à¤£à¥€ अशकà¥à¤¯" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "%2$s येथे इंटरफेस %1$s करीता ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ आधिपासूनच à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ केले आहे" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "मेथड '%1$s' ने पà¥à¤°à¤•ार '%2$s' पà¥à¤°à¤µà¤²à¥‡, परंतॠ'%3$s' अपेकà¥à¤·à¥€à¤¤ आहे" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "इंटरफेस '%2$s' वरील मेथड '%1$s', सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ '%3$s' सह आढळले नाही" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "%s करीता सबटà¥à¤°à¤¿ आधिपासून à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ केले आहे" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "पà¥à¤°à¤•ार INVALID आहे" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL संदेश: PATH किंवा MEMBER हेडर कà¥à¤·à¥‡à¤¤à¥à¤° आढळले नाही" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN संदेश: REPLY_SERIAL हेडर कà¥à¤·à¥‡à¤¤à¥à¤° आढळले नाही" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR संदेश: REPLY_SERIAL किंवा ERROR_NAME हेडर कà¥à¤·à¥‡à¤¤à¥à¤° आढळले नाही" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL संदेश: PATH, INTERFACE किंवा MEMBER हेडर कà¥à¤·à¥‡à¤¤à¥à¤° आढळले नाही" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL संदेश: PATH हेडर कà¥à¤·à¥‡à¤¤à¥à¤° आरकà¥à¤·à¥€à¤¤ मूलà¥à¤¯ /org/freedesktop/DBus/Local " +"याचा वापर " +"करत आहे" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL संदेश: INTERFACE हेडर कà¥à¤·à¥‡à¤¤à¥à¤° आरकà¥à¤·à¥€à¤¤ मूलà¥à¤¯ org.freedesktop.DBus.Local " +"याचा " +"वापर करत आहे" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu बाइट वाचायचे होते परंतॠ%lu पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" +msgstr[1] "%lu बाइटà¥à¤¸ वाचायचे होते परंतॠ%lu पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s' नंतर NUL बाइट अपेकà¥à¤·à¥€à¤¤ परंतॠबाइट %d आढळले" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"वैध UTF-8 सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग अपेकà¥à¤·à¥€à¤¤ परंतॠबाइट ऑफसेट %d (सà¥à¤Ÿà¥à¤°à¤¿à¤‚गची लांबी %d आहे) " +"करीता अवैध बाईटसॠ" +"आढळले. वैध UTF-8 सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग तà¥à¤¯à¤¾à¤µà¥‡à¤³ परà¥à¤¯à¤‚त '%s' होते" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "वाचलेले मूलà¥à¤¯ '%s' वैध D-Bus ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मारà¥à¤— नाही" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "वाचलेले मूलà¥à¤¯ '%s' वैध D-Bus सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ नाही" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "%u बाइट लांबीचा अरे आढळले. कमाल लांबी 2<<26 bytes (64 MiB) आहे." +msgstr[1] "%u बाइटसॠलांबीचे अरे आढळले. कमाल लांबी 2<<26 bytes (64 MiB) आहे." + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"'a%c' पà¥à¤°à¤•ारचे अरे अपेकà¥à¤·à¤¿à¤¤, %u बाइटà¥à¤¸ लांबीचे अपेकà¥à¤·à¤¿à¤¤, परंतॠ%u बाइटà¥à¤¸à¤šà¥€ " +"लांबी आढळली" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "वेरियंटकरीता वाचलेले मूलà¥à¤¯ '%s' वैध D-Bus सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ नाही" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"D-Bus वायर रूपणपासून सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s' सह GVariant डिसिरिअलाइज करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"अवैध à¤à¤‚डियननेसॠमूलà¥à¤¯. 0x6c ('l') किंवा 0x42 ('B') अपेकà¥à¤·à¥€à¤¤ परंतॠमूलà¥à¤¯ 0x%" +"02x आढळले" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "अवैध मà¥à¤–à¥à¤¯ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल आवृतà¥à¤¤à¥€. 1 अपेकà¥à¤·à¥€à¤¤ परंतॠ%d आढळले" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ '%s' सह सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¤¿ हेडर आढळले परंतॠसंदेश बॉडि रिकामे आहे" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "वाचलेले मूलà¥à¤¯ '%s' वैध D-Bus सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ नाही (बॉडिकरीता)" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "संदेशमधà¥à¤¯à¥‡ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¤¿ हेडर आढळले नाही परंतॠसंदेश बॉडि %u बाइट आहे" +msgstr[1] "संदेशमधà¥à¤¯à¥‡ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¤¿ हेडर आढळले नाही परंतॠसंदेश बॉडि %u बाइटसॠआहे" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "संदेश डिसिरिअलाइज करणे अशकà¥à¤¯: " + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"D-Bus वायर रूपणकरीता सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s' सह GVariant डिसिरिअलाइज करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"%d फाइल डिसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿà¤°à¥à¤¸à¤•डे संदेश आढळले परंतॠहेडर कà¥à¤·à¥‡à¤¤à¥à¤° %d फाइल " +"डिसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿà¤°à¥à¤¸à¥ निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ करते" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "संदेशला सिरिअलाइज करणे अशकà¥à¤¯: " + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "संदेश बॉडिमधà¥à¤¯à¥‡ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ '%s' आढळले परंतॠसà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ हेडर आढळले नाही" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "" +"संदेश बॉडिमधà¥à¤¯à¥‡ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ '%s' आढळले परंतॠसà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ हेडरमधà¥à¤¯à¥‡ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ '%s' " +"आहे" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" +"संदेश बॉडि रिकामे आहे परंतॠपरंतॠसà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ हेडरमधà¥à¤¯à¥‡ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ '(%s)' आहे" + +#: ../gio/gdbusmessage.c:3282 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' पà¥à¤°à¤•ारचà¥à¤¯à¤¾ बॉडिसह तà¥à¤°à¥à¤Ÿà¥€ आढळली" + +#: ../gio/gdbusmessage.c:3290 +msgid "Error return with empty body" +msgstr "रिकामà¥à¤¯à¤¾ बॉडिसह तà¥à¤°à¥à¤Ÿà¥€ आढळली" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "हारà¥à¤¡à¤µà¥‡à¤…र पà¥à¤°à¥‹à¤«à¤¾à¤‡à¤²: %s पà¥à¤°à¤¾à¤ªà¥à¤¤ करणà¥à¤¯à¤¾à¤¸ अशकà¥à¤¯" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "/var/lib/dbus/machine-id किंवा /etc/machine-id लोड करणे अशकà¥à¤¯: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s करीता StartServiceByName ला कॉलकरतेवेळी तà¥à¤°à¥à¤Ÿà¥€: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "StartServiceByName(\"%2$s\") मेथडपासून अनपेकà¥à¤·à¥€à¤¤ पà¥à¤°à¤¤à¤¿à¤¸à¤¾à¤¦ %1$d" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"मेथड सà¥à¤°à¥‚ करणे अशकà¥à¤¯; पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ मालकविना परिचीत नावकरीता आहे व पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START फà¥à¤²à¥…गसह बांधले गेले" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "ॲबà¥à¤¸à¥à¤Ÿà¥à¤°à¥…कà¥à¤Ÿ नेम सà¥à¤ªà¥‡à¤¸à¤•रीता समरà¥à¤¥à¤¨ नाही" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "सरà¥à¤µà¥à¤¹à¤° निरà¥à¤®à¤¾à¤£ करतेवेळी nonce फाइल निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ करणे अशकà¥à¤¯" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s': %s येथे nonce फाइलकरीता लिहतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s' वैध D-Bus GUID नाही" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "समरà¥à¤¥à¥€à¤¤ टà¥à¤°à¤¾à¤‚सà¥à¤ªà¥‹à¤°à¥à¤Ÿ '%s' वर à¤à¤•णे अशकà¥à¤¯" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"आदेश:\n" +" help हि माहिती दाखवतो\n" +" introspect रिमोट ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿà¤šà¥€ चौकशी करा\n" +" monitor रिमोट ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मॉनिटर करा\n" +" call रिमोट ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿà¤µà¤° मेथड सà¥à¤°à¥‚ करा\n" +" emit सिगà¥à¤¨à¤² काढा\n" +"\n" +"पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• आदेशवर मदत पà¥à¤°à¤¾à¤ªà¥à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ \"%s COMMAND --help\" याचा वापर करा.\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "इंटà¥à¤°à¥‹à¤¸à¥à¤ªà¥‡à¤•à¥à¤¶à¤¨ XML: %s वाचतेवेळी तà¥à¤°à¥à¤Ÿà¥€\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "सिसà¥à¤Ÿà¤® बससह जोडणी करा" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "सेशन बससह जोडणी करा" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "दिलेलà¥à¤¯à¤¾ D-Bus पतà¥à¤¤à¥à¤¯à¤¾à¤¶à¥€ जोडणी करा" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "कनेकà¥à¤¶à¤¨ à¤à¤‚टपॉईंट परà¥à¤¯à¤¾à¤¯:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "जोडणी à¤à¤‚डपॉईंट निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ करणारे परà¥à¤¯à¤¾à¤¯" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "जोडणी à¤à¤‚डपॉईंट निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले नाही" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "à¤à¤•ापेकà¥à¤·à¤¾ जासà¥à¤¤ जोडणी à¤à¤‚डपॉईंटसॠनिरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "सावधानता: इंटà¥à¤°à¥‹à¤¸à¥à¤ªà¥‡à¤•à¥à¤¶à¤¨ डाटा पà¥à¤°à¤®à¤¾à¤£à¥‡, इंटरफेस '%s' असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤ नाही\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"सावधानता: इंटà¥à¤°à¥‹à¤¸à¥à¤ªà¥‡à¤•à¥à¤¶à¤¨ डाटापà¥à¤°à¤®à¤¾à¤£à¥‡, मेथड '%s' इंटरफेस '%s' वर आढळली नाही\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "सिगà¥à¤¨à¤²à¤•रीता (à¤à¤•मेव नाव) वैकलà¥à¤ªà¤¿à¤• लकà¥à¤·à¥à¤¯" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "सिगà¥à¤¨à¤²à¤•रीता ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿà¤šà¤¾ मारà¥à¤—" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "सिगà¥à¤¨à¤² व इंटरफेसचे नाव" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "सिगà¥à¤¨à¤² काढा." + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "जोडणी करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मारà¥à¤— निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले नाही.\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: %s वैध ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मारà¥à¤— नाही\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: सिगà¥à¤¨à¤² निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ नाही.\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: सिगà¥à¤¨à¤² फूलà¥à¤²à¤¿-कà¥à¤µà¤¾à¤²à¤¿à¤«à¤¾à¤‡à¤¡ नाव पाहिजे.\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: %s वैध इंटरफेस नाव नाही\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: %s वैध सदसà¥à¤¯ नाव नाही\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: %s वैध यà¥à¤¨à¤¿à¤• बस नाव नाही.\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "घटक %d: %s वाचतेवेळी तà¥à¤°à¥à¤Ÿà¥€\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "जोडणी फà¥à¤²à¤¶ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "मेथड सà¥à¤°à¥‚ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ लकà¥à¤·à¥à¤¯ नाव" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "मेथड सà¥à¤°à¥‚ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मारà¥à¤—" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "मेथड व इंटरफेसचे नाव" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "सेकंदातील वेळसमापà¥à¤¤à¤¿" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "रिमोट ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿà¤•रीता मेथड सà¥à¤°à¥‚ करा." + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: लकà¥à¤·à¥à¤¯ निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ नाही\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मारà¥à¤— निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ नाही\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: मेथडचे नाव निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ नाही\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "तà¥à¤°à¥à¤Ÿà¥€: मेथडचे नाव '%s' अवैध आहे\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "पà¥à¤°à¤•ार '%2$s': %3$s असलेले घटक %1$d वाचतेवेळी तà¥à¤°à¥à¤Ÿà¥€\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "चैकशीकरीताचे लकà¥à¤·à¥à¤¯ नाव" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "चौकशी करणà¥à¤¯à¤¾à¤œà¥‹à¤—ी ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मारà¥à¤—" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "XML ची छपाई करा" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "चिलà¥à¤¡à¤°à¤¨à¤šà¥€ चौकशी करा" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "फकà¥à¤¤ गà¥à¤£à¤§à¤°à¥à¤®à¤¾à¤‚ची छपाई करा" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "रिमोट ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿà¤šà¥€ चौकशी करा." + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "मॉनिटर करणà¥à¤¯à¤¾à¤œà¥‹à¤—ी लकà¥à¤·à¥à¤¯ नाव" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "मॉनिटर करणà¥à¤¯à¤¾à¤œà¥‹à¤—ी ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मारà¥à¤—" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "रिमोट ऑबà¥à¤œà¥‡à¤•à¥à¤Ÿ मॉनिटर करा." + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4522 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "निनावी" + +#: ../gio/gdesktopappinfo.c:2410 +msgid "Desktop file didn't specify Exec field" +msgstr "डेसà¥à¤•टॉप फाइल मधà¥à¤¯à¥‡ Exec नोंदणी निशà¥à¤šà¤¿à¤¤ नाही" + +#: ../gio/gdesktopappinfo.c:2695 +msgid "Unable to find terminal required for application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—करीता आवशà¥à¤¯à¤• टरà¥à¤®à¤¿à¤¨à¤² आढळले नाही" + +#: ../gio/gdesktopappinfo.c:3116 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "वापरकरà¥à¤¤à¤¾ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— संयोजन संचयीका %s बनवू शकले नाही: %s" + +#: ../gio/gdesktopappinfo.c:3120 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "वापरकरà¥à¤¤à¤¾ MIME संयोजन संचयीका %s बनवू शकले नाही: %s" + +#: ../gio/gdesktopappinfo.c:3360 ../gio/gdesktopappinfo.c:3384 +msgid "Application information lacks an identifier" +msgstr "ॲपà¥à¤²à¤¿à¤•ेशन माहितीमधà¥à¤¯à¥‡ आइडेंटिफायर आढळले नाही" + +#: ../gio/gdesktopappinfo.c:3617 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "वापरकरà¥à¤¤à¤¾ डेसà¥à¤•टॉप फाइल %s बनवू शकत नाही" + +#: ../gio/gdesktopappinfo.c:3751 +#, c-format +msgid "Custom definition for %s" +msgstr "%s करीता इचà¥à¤›à¤¿à¤• वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "डà¥à¤°à¤¾à¤‡à¤µà¥à¤¹ बाहेर पडा लागू करत नाही" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "डà¥à¤°à¤¾à¤‡à¤µà¥à¤¹ eject किंवा eject_with_operation लागू करत नाही" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "डà¥à¤°à¤¾à¤‡à¤µà¥à¤¹ मिडीयाकरीता पोलींग लागू करत नाही" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "डà¥à¤°à¤¾à¤‡à¤µà¥à¤¹ start लागू करत नाही" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "डà¥à¤°à¤¾à¤‡à¤µà¥à¤¹ stop लागू करत नाही" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS समरà¥à¤¥à¤¨ उपलबà¥à¤§ नाही" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem à¤à¤¨à¤•ोडींगची आवृतà¥à¤¤à¥€ %d हाताळू शकत नाही" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem à¤à¤¨à¤•ोडींग अंतरà¥à¤—त सदोषीत टोकन (%d) आढळले" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblem à¤à¤¨à¤•ोडींग ची आवृतà¥à¤¤à¥€ (%d) हाताळू शकत नाही" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblem à¤à¤¨à¤•ोडींग अंतरà¥à¤—त सदोषीत टोकन (%d) आढळले" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon करीता GEmblem अपेकà¥à¤·à¥€à¤¤" + +#: ../gio/gfile.c:956 ../gio/gfile.c:1194 ../gio/gfile.c:1332 +#: ../gio/gfile.c:1570 ../gio/gfile.c:1625 ../gio/gfile.c:1683 +#: ../gio/gfile.c:1767 ../gio/gfile.c:1824 ../gio/gfile.c:1888 +#: ../gio/gfile.c:1943 ../gio/gfile.c:3591 ../gio/gfile.c:3646 +#: ../gio/gfile.c:3853 ../gio/gfile.c:3895 ../gio/gfile.c:4358 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7748 ../gio/gfile.c:7838 ../gio/gfile.c:7922 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "कारà¥à¤¯ समरà¥à¤¥à¤¿à¤¤ नाही" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1455 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "समाविषà¥à¤Ÿà¥€à¤¤ आरोहन असà¥à¤¤à¥€à¤¤à¥à¤µà¤¾à¤¤ नाही" + +#: ../gio/gfile.c:2502 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "संचयीकेवर पà¥à¤°à¤¤ बनवू शकत नाही" + +#: ../gio/gfile.c:2562 +msgid "Can't copy directory over directory" +msgstr "संचयीकेवर संचयीकेची पà¥à¤°à¤¤ बनवू शकत नाही" + +#: ../gio/gfile.c:2570 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "लकà¥à¤·à¥à¤¯ फाइल असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤ आहे" + +#: ../gio/gfile.c:2589 +msgid "Can't recursively copy directory" +msgstr "संचयीकेची पà¥à¤¨à¤ƒ पà¥à¤°à¤¤ बनवू शकत नाही" + +#: ../gio/gfile.c:2871 +msgid "Splice not supported" +msgstr "सà¥à¤ªà¥à¤²à¤¾à¤‡à¤¸ समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../gio/gfile.c:2875 +#, c-format +msgid "Error splicing file: %s" +msgstr "फाइल सà¥à¤ªà¥à¤²à¤¾à¤‡à¤¸ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gfile.c:3006 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "माउंटà¥à¤¸ अंतरà¥à¤—त पà¥à¤°à¤¤ बनवणे (रिफà¥à¤²à¤¿à¤‚क/कà¥à¤²à¥‹à¤¨) समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../gio/gfile.c:3010 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "पà¥à¤°à¤¤ बनवणे (रिफà¥à¤²à¤¿à¤‚क/कà¥à¤²à¥‹à¤¨) समरà¥à¤¥à¥€à¤¤ नाही किंवा अवैध आहे" + +#: ../gio/gfile.c:3015 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "पà¥à¤°à¤¤ बनवणे (रिफà¥à¤²à¤¿à¤‚क/कà¥à¤²à¥‹à¤¨) समरà¥à¤¥à¥€à¤¤ नाही किंवा कारà¥à¤¯ केले नाही" + +#: ../gio/gfile.c:3078 +msgid "Can't copy special file" +msgstr "विशेष फाइलचे पà¥à¤°à¤¤ बनवू शकत नाही" + +#: ../gio/gfile.c:3843 +msgid "Invalid symlink value given" +msgstr "अवैध symlink मà¥à¤²à¥à¤¯ दिले गेले" + +#: ../gio/gfile.c:4004 +msgid "Trash not supported" +msgstr "कचरापेटी समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../gio/gfile.c:4116 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "फाइल नावात '%c' असू शकत नाही" + +#: ../gio/gfile.c:6540 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "खंड आरोहन कारà¥à¤¯à¤¾à¤°à¤¤ करत नाही" + +#: ../gio/gfile.c:6649 +msgid "No application is registered as handling this file" +msgstr "ही फाइल हाताळणà¥à¤¯à¤¾à¤•रीता कà¥à¤ à¤²à¥‡à¤¹à¥€ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— पंजीकृत नाही" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "à¤à¤¨à¥à¤¯à¥à¤®à¤°à¥‡à¤Ÿà¤° बंद आहे" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "फाइल à¤à¤¨à¥à¤¯à¥à¤®à¤°à¥‡à¤Ÿà¤°à¤šà¥€ अपà¥à¤°à¤¤à¤¿à¤® कारà¥à¤¯à¤•à¥à¤·à¤®à¤¤à¤¾" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "फाइल à¤à¤¨à¥à¤¯à¥à¤®à¤°à¥‡à¤Ÿà¤° आधिपासूनच बंद आहे" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon à¤à¤¨à¤•ोडींगची आवृतà¥à¤¤à¥€ %d हाताळू शकत नाही" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon करीता सदोषीत इनपà¥à¤Ÿ डेटा आढळले" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "शà¥à¤°à¥ƒà¤‚खला query_info ला समरà¥à¤¥à¤¨ देत नाही" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "शà¥à¤°à¥ƒà¤‚खलेवर सीक समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "आगत शà¥à¤°à¥ƒà¤‚खलेवर टà¥à¤°à¤‚केट वापरू शकत नाही" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "शà¥à¤°à¥ƒà¤‚खलेवर टà¥à¤°à¤‚केट समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "चà¥à¤•ीचे टोकन कà¥à¤°à¤®à¤¾à¤‚क (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "वरà¥à¤— नाव %s करीता पà¥à¤°à¤•ार आढळले नाही" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "पà¥à¤°à¤•ार %s GIcon संवाद लागू करणà¥à¤¯à¤¾à¤¸ अशकà¥à¤¯ ठरले" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "पà¥à¤°à¤•ार %s वरà¥à¤—ीकृत केले गेले नाही" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "सदोषीत आवृतà¥à¤¤à¥€ कà¥à¤°à¤®à¤¾à¤‚क: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "पà¥à¤°à¤•ार %s GIcon संवादवर from_tokens() लागू करत नाही" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "आयकन à¤à¤¨à¤•ोडिंगचे पà¥à¤°à¤µà¤²à¥‡à¤²à¥€ आवृतà¥à¤¤à¥€ हाताळणे अशकà¥à¤¯" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "पतà¥à¤¤à¤¾ निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले नाही" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "पतà¥à¤¤à¤¾à¤•रीता लांबी %u खूप लांब आहे" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "पतà¥à¤¤à¤¾à¤®à¤§à¥à¤¯à¥‡ सेट बियाà¤à¤¡ पà¥à¤°à¤¿à¤«à¤¿à¤•à¥à¤¸ लांबीचे बिट आढळले" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "'%s' ला IP पतà¥à¤¤à¤¾ मासà¥à¤• मà¥à¤¹à¤£à¥‚न वाचणे अशकà¥à¤¯" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "सॉकेट पतà¥à¤¤à¥à¤¯à¤¾à¤‚करीता अतिरीकà¥à¤¤ जागा आढळली नाही" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "असमरà¥à¤¥à¥€à¤¤ सॉकेट पतà¥à¤¤à¤¾" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "आगत शà¥à¤°à¥ƒà¤‚खला वाचतायेणà¥à¤¯à¤¾à¤œà¥‹à¤—ी कारà¥à¤¯à¤°à¤¤ करत नाही" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1027 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1474 +msgid "Stream has outstanding operation" +msgstr "शà¥à¤°à¥ƒà¤‚खलाचे अपà¥à¤°à¤¤à¤¿à¤® कारà¥à¤¯à¤•à¥à¤·à¤®à¤¤à¤¾" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "घटक <%s> यास <%s> अंतरà¥à¤—त सà¥à¤µà¥€à¤•ारले जात नाही" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "घटक <%s> यास उचà¥à¤šà¤¸à¥à¤¤à¤°à¤¾à¤•रीता सà¥à¤µà¥€à¤•ारà¥à¤¯ नाही" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "सà¥à¤°à¥‹à¤¤à¤®à¤§à¥à¤¯à¥‡ फाइल %s à¤à¤•ापेकà¥à¤·à¤¾à¤œà¤¾à¤¸à¥à¤¤à¤µà¥‡à¤³à¥€ आढळलते" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "'%s' ला कोणतà¥à¤¯à¤¾à¤¹à¤¿ सà¥à¤°à¥‹à¤¤ डिरेकà¥à¤Ÿà¥à¤°à¥€à¤®à¤§à¥à¤¯à¥‡ शोधणà¥à¤¯à¤¾à¤¸ अपयशी" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "सधà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ डिरेकà¥à¤Ÿà¥à¤°à¥€à¤®à¤§à¥à¤¯à¥‡ '%s' शोधणे अशकà¥à¤¯" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "अपरिचीत विशà¥à¤²à¥‡à¤·à¤£ परà¥à¤¯à¤¾à¤¯ \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "temp फाइल निरà¥à¤®à¤¾à¤£ करणà¥à¤¯à¤¾à¤¸ अपयशी: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "फाइल %s: %s वाचतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "फाइल %s संकोचीत करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "मजकूर <%s> अंतरà¥à¤—त कदाचित आढळणार नाही" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "आऊटपà¥à¤Ÿ फाइलचे नाव" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"फाइलà¥à¤¸à¥ वाचणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ डिरेकà¥à¤Ÿà¥à¤°à¥€à¤œà¥ (सधà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ डिरेकà¥à¤Ÿà¥à¤°à¥€à¤•रीता पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "लकà¥à¤·à¥à¤¯ फाइलनाव à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शनतरà¥à¤«à¥‡ निवडलेलà¥à¤¯à¤¾ रूपण करीता आऊटपà¥à¤Ÿ निरà¥à¤®à¤¾à¤£ करा" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "सà¥à¤°à¥‹à¤¤ हेडर निरà¥à¤®à¤¾à¤£ करा" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" +"सोअरà¥à¤¸à¤•ोड निरà¥à¤®à¤¾à¤£ करतेवेळी सà¥à¤°à¥‹à¤¤ फाइलपासून कोडपरà¥à¤¯à¤‚त दà¥à¤µà¤¾ निरà¥à¤®à¤¾à¤£ होत असे" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "अवलंबन सूची निरà¥à¤®à¤¾à¤£ करा" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "सà¥à¤µà¤¯à¤‚रितà¥à¤¯à¤¾ सà¥à¤°à¥‹à¤¤ निरà¥à¤®à¤¾à¤£ व नोंदणी करू नका" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "फंकशनà¥à¤¸ à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ करू नका; G_GNUC_INTERNAL असे घोषीत करा" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "निरà¥à¤®à¥€à¤¤ सोअरà¥à¤¸à¥ कोडकरीता वापरणà¥à¤¯à¤¾à¤œà¥‹à¤—ी C आइडेंटिफायर नाव" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"सà¥à¤°à¥‹à¤¤ सूचनाला सà¥à¤°à¥‹à¤¤ फाइलमधà¥à¤¯à¥‡ कंपाइल करा.\n" +"रिसोअरà¥à¤¸à¥ सà¥à¤ªà¥‡à¤¸à¤¿à¤«à¤¿à¤•ेशन फाइलà¥à¤¸à¥à¤®à¤§à¥à¤¯à¥‡ à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन .gresource.xml असते,\n" +"व सà¥à¤°à¥‹à¤¤ फाइलमधà¥à¤¯à¥‡ .gresource नामाक à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन असते." + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "हà¥à¤¬à¥‡à¤¹à¥à¤¬ à¤à¤• फाइल नाव पà¥à¤°à¤µà¤£à¥‡ आवशà¥à¤¯à¤• आहे\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "रिकामे नावांकरीता परवानगी दिली जात नाही" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "अवैध नाव '%s': नावे छोटà¥à¤¯à¤¾ आकाराचे अकà¥à¤·à¤°à¤¾à¤‚सह सà¥à¤°à¥‚ वà¥à¤¹à¤¾à¤¯à¤²à¤¾ हवे" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"अवैध नाव '%s': अवैध अकà¥à¤·à¤° '%c'; फकà¥à¤¤ छोटे अकà¥à¤·à¤°à¥‡, संखà¥à¤¯à¤¾ व डॅश ('-') करीता " +"परवानगी असते." + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "अवैध नाव '%s': दोन परसà¥à¤ªà¤° हायफनà¥à¤¸à¥ ('--') करीता परवानगी नाही." + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "अवैध नाव '%s': शेटवचे अकà¥à¤·à¤° हायफेन ('-') असणे अशकà¥à¤¯." + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "अवैध नाव '%s': कमाल लांबी 1024 आहे" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " आधिपासूनच निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "'list-of' सà¥à¤•िमामधà¥à¤¯à¥‡ किजॠसमाविषà¥à¤Ÿ करणे अशकà¥à¤¯" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " आधिपासूनच निरà¥à¤¦à¥‡à¤¶à¥€à¤¤" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" मधà¥à¤¯à¥‡ shadows ; मूलà¥à¤¯ संपादित " +"करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ याचा वापर करा" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +" करीता गà¥à¤£à¤§à¤°à¥à¤® मà¥à¤¹à¤£à¥‚न 'type', 'enum' किंवा 'flags' पैकी à¤à¤• निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ " +"करणे आवशà¥à¤¯à¤• " +"आहे" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> अजूनही ठरवले नाही." + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "अवैध GVariant पà¥à¤°à¤•ार सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग '%s'" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " दिले परंतॠसà¥à¤•िमा कशालाच à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚ड करत नाही" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "ओवà¥à¤¹à¤°à¤°à¤¾à¤‡à¤¡à¤•रीता आढळले नाही" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " आधिपासूनच निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " आधिपासूनच निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" +" अजूनही असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤à¥€à¤² नसलेलà¥à¤¯à¤¾ सà¥à¤•िमा '%s'ला à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚ड करतो" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " अजूनही असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤à¥€à¤² नसलेलà¥à¤¯à¤¾ सà¥à¤•िमा '%s'ची सूची आहे" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "मारà¥à¤—सह सà¥à¤•िमाची सूची असणे अशकà¥à¤¯" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "मारà¥à¤—सह सà¥à¤•िमा à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚ड करणे अशकà¥à¤¯" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" लिसà¥à¤Ÿ आहे, ला à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚ड केले जि लिसà¥à¤Ÿ नाही" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" हे ला à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚ड " +"करते " +"परंतॠ'%s' हे '%s' यास à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚ड करत नाही" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "मारà¥à¤—, दिले असलà¥à¤¯à¤¾à¤¸, सà¥à¤²à¥…शसह सà¥à¤°à¥‚ व समापà¥à¤¤ वà¥à¤¹à¤¾à¤¯à¤²à¤¾ हवे" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "सूचीचे मारà¥à¤— ':/' सह समापà¥à¤¤ वà¥à¤¹à¤¾à¤¯à¤²à¤¾ हवे" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> आधिपासूनच निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "à¤à¤²à¤¿à¤®à¥‡à¤‚ट <%s> शीरà¥à¤· सà¥à¤¤à¤°à¤•रीता सà¥à¤µà¥€à¤•ारले जात नाही" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले; बाहेर पडत आहे.\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "संपूरà¥à¤£ फाइलकडे दà¥à¤²à¤•à¥à¤· केले.\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "या फाइलकडे दà¥à¤°à¥à¤²à¤•à¥à¤· केले.\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"ओवà¥à¤¹à¤°à¤°à¤¾à¤‡à¤¡ फाइल '%3$s' मधà¥à¤¯à¥‡ निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केलà¥à¤¯à¤¾à¤ªà¥à¤°à¤®à¤¾à¤£à¥‡ सà¥à¤•िमा '%2$s' मधà¥à¤¯à¥‡ कि '%" +"1$s' आढळली " +"नाही" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; या किसाठी ओवà¥à¤¹à¤°à¤°à¤¾à¤‡à¤¡à¤•डे दà¥à¤°à¥à¤²à¤•à¥à¤· केले.\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " व --strict निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले; बाहेर पडत आहे.\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"ओवà¥à¤¹à¤°à¤°à¤¾à¤‡à¤¡ फाइल '%3$s': %4$s मधà¥à¤¯à¥‡ निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ सà¥à¤•िमा '%2$s' मधील कि '%1$s' " +"वाचतेवेळी " +"तà¥à¤°à¥à¤Ÿà¥€." + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "या किसाठी ओवà¥à¤¹à¤°à¤°à¤¾à¤‡à¤¡à¤•डे दà¥à¤°à¥à¤²à¤•à¥à¤· केले.\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"ओवà¥à¤¹à¤°à¤°à¤¾à¤‡à¤¡ फाइल '%3$s' मधà¥à¤¯à¥‡ सà¥à¤•िमा '%2$s' करीता कि '%1$s' दिलेलà¥à¤¯à¤¾ " +"सà¥à¤¤à¥à¤°à¤¯à¥‹à¤œà¤¨à¥‡à¤šà¥à¤¯à¤¾ " +"वà¥à¤¯à¤¾à¤ªà¥à¤¤à¤¿ बाहेर आहे" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"ओवà¥à¤¹à¤°à¤°à¤¾à¤‡à¤¡ फाइल '%3$s' मधà¥à¤¯à¥‡ सà¥à¤•िमा '%2$s' करीता कि '%1$s' वैध परà¥à¤¯à¤¾à¤¯à¤¾à¤‚चà¥à¤¯à¤¾ " +"सूचीत नाही" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled फाइल कà¥à¤ à¥‡ साठवायची" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "schemas मधील कोणतà¥à¤¯à¤¾à¤¹à¤¿ तà¥à¤°à¥à¤Ÿà¥€ रदà¥à¤¦ करा" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled फाइल लिहू नका" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "किचे नाव पà¥à¤°à¤¤à¤¿à¤¬à¤‚ध जबरनपणे लागू करू नका" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"सरà¥à¤µ GSettings सà¥à¤•िमा फाइलà¥à¤¸à¥à¤²à¤¾ सà¥à¤•िमा कॅशेमधà¥à¤¯à¥‡ कंपाइल करा.\n" +"सà¥à¤•िमा फाइलà¥à¤¸à¥à¤•डे .gschema.xml à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन आवशà¥à¤¯à¤• आहे,\n" +"व कॅश फाइलला gschemas.compiled असे मà¥à¤¹à¤Ÿà¤²à¥‡ जाते." + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "हà¥à¤¬à¥‡à¤¹à¥à¤¬ à¤à¤• डिरेकà¥à¤Ÿà¥à¤°à¥€ नाव दà¥à¤¯à¤¾\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "सà¥à¤•िमा फाइलà¥à¤¸à¥ आढळले नाही: " + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "काहिच करू नका.\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤à¥€à¤² आऊटपà¥à¤Ÿ फाइल काढून टाकले.\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "मà¥à¤²à¤­à¥‚त संचयीका मॉनीटर पà¥à¤°à¤•ार शोधता आली नाही" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "अवैध फाइलनाव %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "फाइलपà¥à¤°à¤£à¤¾à¤²à¥€ विषयी माहिती मिळवतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "रूट संचयीका पà¥à¤¨à¤ƒà¤¨à¤¾à¤®à¤¾à¤‚कीत करू शकत नाही" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "फाइल पà¥à¤¨à¤ƒà¤¨à¤¾à¤®à¤¾à¤‚कीत करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "फाइलचे पà¥à¤¨à¤ƒà¤¨à¤¾à¤®à¤¾à¤‚कन अशकà¥à¤¯, फाइलचेनाव आधिपासूनच असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤ आहे" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "अवैध फाइल नाव" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "संचयीका उघडू शकत नाही" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "फाइल उघडतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "फाइल काढून टाकतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "फाइल कचरापेटीत हलवितेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "कचरापेटी संचयीका %1$s निरà¥à¤®à¤¾à¤£ करती आली नाही: %2$s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "कचरापेटी करीता उचà¥à¤šà¤¸à¥à¤¥à¤°à¥€à¤¯ संचयीका शोधता आली नाही" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "कचरापेटी करीता उचà¥à¤šà¤¸à¥à¤¥à¤°à¥€à¤¯ संचयीका शोधता आली नाही" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "कचरापेटी माहिती फाइल बनविता आली नाही: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "कचरापेटीकडे फाइल हलवितेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "आंतरीक तà¥à¤°à¥‚टी" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "संचयीका बनवितेवेळी तà¥à¤°à¥‚टी आढळली: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "फाइलपà¥à¤°à¤£à¤¾à¤²à¥€ सिमà¥à¤¬à¥‰à¤²à¥€à¤• लिंकà¥à¤¸à¥ करीता समरà¥à¤¥à¤¨ पà¥à¤°à¤µà¤¤ नाही" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "बोधचिनà¥à¤¹ लिंक बनवितेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "फाइल सà¥à¤¥à¤¾à¤¨à¤¾à¤‚तरन करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "संचयीकेवर संचयीका हलवू शकत नाही" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "पà¥à¤°à¤¤à¤¿à¤•ृत फाइल निरà¥à¤®à¤¾à¤£ अपयशी" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "लकà¥à¤·à¥à¤¯ फाइल काढून टाकतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "आरोहन मधिल सà¥à¤¥à¤¾à¤¨à¤¾à¤‚तरन समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../gio/glocalfile.c:2603 +#, c-format +#| msgid "Could not load schemas from %s: %s\n" +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s: %s चे डिसà¥à¤• वापर ओळखणे शकà¥à¤¯ नाही" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "गà¥à¤£à¤§à¤°à¥à¤® मà¥à¤²à¥à¤¯ शूनà¥à¤¯ नसायला हवे" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "अवैध गà¥à¤£à¤§à¤°à¥à¤® पà¥à¤°à¤•ार (अकà¥à¤·à¤°à¤®à¤¾à¤³à¤¾ अपेकà¥à¤·à¥€à¤¤)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "अवैध विसà¥à¤¤à¤¾à¤°à¥€à¤¤ गà¥à¤£à¤§à¤°à¥à¤® नाव" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "विसà¥à¤¤à¤¾à¤°à¥€à¤¤ गà¥à¤£à¤§à¤°à¥à¤® निशà¥à¤šà¤¿à¤¤ करतेवेळी तà¥à¤°à¥‚टी '%s': %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (अवैध à¤à¤‚कोडींग)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "फाइल '%s': %s करीता माहिती पà¥à¤°à¤¾à¤ªà¥à¤¤ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "फाइल डिसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿà¤°: %s करीता माहिती पà¥à¤°à¤¾à¤ªà¥à¤¤ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "अवैध गà¥à¤£à¤§à¤°à¥à¤® पà¥à¤°à¤•ार (uint32 अपेकà¥à¤·à¥€à¤¤)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "अवैध गà¥à¤£à¤§à¤°à¥à¤® पà¥à¤°à¤•ार (uint64 अपेकà¥à¤·à¥€à¤¤)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "अवैध गà¥à¤£à¤§à¤°à¥à¤® पà¥à¤°à¤•ार (बाईट अकà¥à¤·à¤°à¤®à¤¾à¤³à¤¾ अपेकà¥à¤·à¥€à¤¤)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "symlinks करीता परवानगी सेट करणà¥à¤¯à¤¾à¤¸ अशकà¥à¤¯" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "परवानगी सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "मालक सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "symlink शूनà¥à¤¯ नसायला हवे" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "symlink सà¥à¤¥à¤¾à¤ªà¥€à¤¤ करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "symlink निशà¥à¤šà¤¿à¤¤ करतेवेळी तà¥à¤°à¥‚टी: फाइल symlink नाही" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "संपादन किंवा पà¥à¤°à¤µà¥‡à¤¶à¤µà¥‡à¤³ ठरवतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux संदरà¥à¤­ विना-शूनà¥à¤¯ असायला हवे" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux संदरà¥à¤­ संयोजीत करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "SELinux या पà¥à¤°à¤£à¤¾à¤²à¥€à¤µà¤° कारà¥à¤¯à¤¾à¤¨à¥à¤µà¥€à¤¤ नाही" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s गà¥à¤£à¤§à¤°à¥à¤® सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करणे समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "फाइल पासून वाचतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "फाइल शोधतेवळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "फाइल बंद करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "मà¥à¤²à¤­à¥‚त सà¥à¤¥à¤¾à¤¨à¥€à¤• फाइल मॉनीटर पà¥à¤°à¤•ार शोधता आले नाही" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "फाइलवर लिहीतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "जà¥à¤¨à¥‡ पà¥à¤°à¤¤à¤¿à¤•ृत लिंक काढून टाकतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "पà¥à¤°à¤¤à¤¿à¤•ृत पà¥à¤°à¤¤ बनवितेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "तातपूरती फाइल पà¥à¤¨à¤ƒà¤¨à¤¾à¤®à¤¾à¤‚कीत करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "फाइल टà¥à¤°à¤‚केट करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "फाइल '%s' उघडतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "लकà¥à¤·à¥à¤¯ फाइल संचयीका आहे" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "लकà¥à¤·à¥à¤¯ फाइल सामानà¥à¤¯ फाइल नाही" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "फाइल बाहेरà¥à¤¨ संपादित करणà¥à¤¯à¤¾à¤¤ आली" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "जà¥à¤£à¥€ फाइल काढूण टाकतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "अवैध GSeekType पà¥à¤°à¤µà¤¿à¤²à¥‡ गेले" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "अवैध संचयन विनंती" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream टà¥à¤°à¤‚केट करू शकत नाही" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "सà¥à¤®à¥ƒà¤¤à¥€ आउटपà¥à¤Ÿ शà¥à¤°à¥ƒà¤‚खला पà¥à¤¨à¥à¤¹à¤†à¤•ार देणà¥à¤¯à¤œà¥‹à¤—ी नाही" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "सà¥à¤®à¥ƒà¤¤à¥€ आउटपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¥€à¤® पà¥à¤¨à¥à¤¹ आकार देणà¥à¤¯à¤¾à¤¸ अपयशी" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"राईट पà¥à¤°à¥‹à¤¸à¥‡à¤¸à¥ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आवशà¥à¤¯à¤• मेमरी उपलबà¥à¤§ à¤à¤¡à¥à¤°à¥‡à¤¸à¥ सà¥à¤ªà¥‡à¤¸à¥ पेकà¥à¤·à¤¾ जासà¥à¤¤ आहे" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤®à¤šà¥à¤¯à¤¾ सà¥à¤°à¤µà¤¾à¤¤à¥€à¤¸, सीक करीता विनंती केली" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤®à¤šà¥à¤¯à¤¾ समापà¥à¤¤à¥€à¤¸, सीक करीता विनंती केली" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "mount \"unmount\" लागू करत नाही" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "mount \"eject\" लागू करत नाही" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "mount \"unmount\" किंवा \"unmount_with_operation\" लागू करत नाही" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "mount \"eject\" किंवा \"eject_with_operation\" लागू करत नाही" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "mount \"remount\" लागू करत नाही" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "माउनà¥à¤Ÿ अनà¥à¤•à¥à¤°à¤® पà¥à¤°à¤•ार अंदाज लागू करत नाही" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "माउनà¥à¤Ÿ समजà¥à¤³à¤µà¤£à¥€ अनà¥à¤•à¥à¤°à¤® पà¥à¤°à¤•ार अंदाज लागू करत नाही" + +#: ../gio/gnetworkaddress.c:338 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "यजमाननाव '%s' मधà¥à¤¯à¥‡ '[' समाविषà¥à¤Ÿà¥€à¤¤ आहे परंतॠ']' समाविषà¥à¤Ÿà¥€à¤¤ नाही" + +#: ../gio/gnetworkmonitorbase.c:189 ../gio/gnetworkmonitorbase.c:292 +msgid "Network unreachable" +msgstr "नेटवरà¥à¤• पोहचणà¥à¤¯à¤¾à¤œà¥‹à¤—ी नाही" + +#: ../gio/gnetworkmonitorbase.c:227 ../gio/gnetworkmonitorbase.c:257 +msgid "Host unreachable" +msgstr "यजमान पोहचणà¥à¤¯à¤¾à¤œà¥‹à¤—ी नाही" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "नेटवरà¥à¤• मॉनिटर निरà¥à¤®à¤¾à¤£ करणे अशकà¥à¤¯: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "नेटवरà¥à¤• मॉनिटर निरà¥à¤®à¤¾à¤£ करणे अशकà¥à¤¯: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "नेटवरà¥à¤• सà¥à¤Ÿà¤Ÿà¤¸à¥ पà¥à¤°à¤¾à¤ªà¥à¤¤ करणे अशकà¥à¤¯: " + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:550 +msgid "Output stream doesn't implement write" +msgstr "आऊटपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¤¿à¤® राइट लागू करत नाही" + +#: ../gio/goutputstream.c:511 ../gio/goutputstream.c:1028 +msgid "Source stream is already closed" +msgstr "सà¥à¤¤à¥à¤°à¥‹à¤¤ शà¥à¤°à¥ƒà¤‚खला आधिपासून बंद" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' चà¥à¤¯à¤¾ निरà¥à¤§à¤¾à¤°à¤£à¤µà¥‡à¤³à¥€ तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' येथील सà¥à¤°à¥‹à¤¤ असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤ नाही" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "'%s' येथील सà¥à¤°à¥‹à¤¤ डिकंपà¥à¤°à¥‡à¤¸ होणà¥à¤¯à¤¾à¤¸ अपयशी à¤à¤¾à¤²à¥‡" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "'%s' येथील सà¥à¤°à¥‹à¤¤ डिरेकà¥à¤Ÿà¥à¤°à¤¿ नाही" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "इंपà¥à¤Ÿ सà¥à¤Ÿà¥à¤°à¤¿à¤® सीक लागू करत नाही" + +#: ../gio/gresource-tool.c:487 +msgid "List sections containing resources in an elf FILE" +msgstr "elf FILE मधà¥à¤¯à¥‡ सà¥à¤°à¥‹à¤¤ समाविषà¥à¤Ÿà¥€à¤¤ असणारे विभागांची सूची दाखवा" + +#: ../gio/gresource-tool.c:493 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"सà¥à¤°à¥‹à¤¤ दाखवा\n" +"SECTION दिले असलà¥à¤¯à¤¾à¤¸, फकà¥à¤¤ या विभागतले सà¥à¤°à¤¤à¥‹ दाखवा\n" +"PATH दिले असलà¥à¤¯à¤¾à¤¸, फकà¥à¤¤ जà¥à¤³à¤£à¤¾à¤°à¥‡ सà¥à¤°à¥‹à¤¤ दाखवा" + +#: ../gio/gresource-tool.c:496 ../gio/gresource-tool.c:506 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:497 ../gio/gresource-tool.c:507 +#: ../gio/gresource-tool.c:514 +msgid "SECTION" +msgstr "SECTION" + +#: ../gio/gresource-tool.c:502 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"सà¥à¤°à¥‹à¤¤à¤²à¤¾ तपशीलसह सूचीत दाखवा\n" +"SECTION दिले असलà¥à¤¯à¤¾à¤¸, फकà¥à¤¤ या विभागातील सà¥à¤°à¥‹à¤¤ दाखवा\n" +"PATH दिले असलà¥à¤¯à¤¾à¤¸, फकà¥à¤¤ जà¥à¤³à¤£à¥à¤¯à¤¾à¤œà¥‹à¤—ी सà¥à¤°à¥‹à¤¤à¤šà¥€ सूची दाखवा\n" +"तपशीलमधà¥à¤¯à¥‡ विभाग, आकार व कमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ समाविषà¥à¤Ÿà¥€à¤¤ आहे" + +#: ../gio/gresource-tool.c:512 +msgid "Extract a resource file to stdout" +msgstr "सà¥à¤°à¥‹à¤¤ फाइलला stdout करीता काढा" + +#: ../gio/gresource-tool.c:513 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: ../gio/gresource-tool.c:527 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"वापर:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"आदेश:\n" +" help हि माहिती दाखवा\n" +" sections सà¥à¤°à¥‹à¤¤ विभाग दाखवा\n" +" list सà¥à¤°à¥‹à¤¤ दाखवा\n" +" details तपशीलसह सà¥à¤°à¥‹à¤¤à¤šà¥€ सूची दाखवा\n" +" extract सà¥à¤°à¥‹à¤¤ पà¥à¤°à¤¾à¤ªà¥à¤¤ करा\n" +"\n" +"तपशीलमधà¥à¤¯à¥‡ मदत पà¥à¤°à¤¾à¤ªà¥à¤¤ करायचे असलà¥à¤¯à¤¾à¤¸ 'gresource help COMMAND' याचा वापर " +"करा.\n" +"\n" + +#: ../gio/gresource-tool.c:541 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"वापर:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:548 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION à¤à¤• (वैकलà¥à¤ªà¤¿à¤•) elf विभागाचे नाव\n" + +#: ../gio/gresource-tool.c:552 ../gio/gsettings-tool.c:635 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND समà¤à¤µà¤£à¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€à¤šà¥‡ आदेश (वैकलà¥à¤ªà¤¿à¤•)\n" + +#: ../gio/gresource-tool.c:558 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE à¤à¤• elf फाइल (बाइनरि किंवा शेअरà¥à¤¡à¥ लाइबà¥à¤°à¤°à¤¿)\n" + +#: ../gio/gresource-tool.c:561 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE à¤à¤• elf फाइल (बाइनरि किंवा शेअरà¥à¤¡à¥ लाइबà¥à¤°à¤°à¤¿)\n" +" किंवा कंपाइलà¥à¤¡à¥ सà¥à¤°à¥‹à¤¤ फाइल\n" + +#: ../gio/gresource-tool.c:565 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:567 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH à¤à¤• (वैकलà¥à¤ªà¤¿à¤•) सà¥à¤°à¥‹à¤¤ मारà¥à¤— (अपà¥à¤°à¥‡ असू शकते)\n" + +#: ../gio/gresource-tool.c:568 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:570 +msgid " PATH A resource path\n" +msgstr " PATH सà¥à¤°à¥‹à¤¤à¤šà¥‡ मारà¥à¤—\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "सà¥à¤•िमा '%s' आढळले नाही\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "सà¥à¤•िमा '%s' पà¥à¤¨à¤ƒà¤¸à¥à¤¥à¤¾à¤¨à¤¾à¤‚तरनजोगी नाही (मारà¥à¤— निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ करणे आवशà¥à¤¯à¤•)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "सà¥à¤•िमा '%s' पà¥à¤¨à¤ƒà¤¸à¥à¤¥à¤¾à¤¨à¤¾à¤‚तरनजोगी आहे (मारà¥à¤— निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ करणे आवशà¥à¤¯à¤• आहे)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "रिकामे मारà¥à¤— दिले.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "मारà¥à¤— सà¥à¤²à¥…शसह सà¥à¤°à¥‚ वà¥à¤¹à¤¾à¤¯à¤²à¤¾ हवे (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "मारà¥à¤— सà¥à¤²à¥…शसह समापà¥à¤¤ वà¥à¤¹à¤¾à¤¯à¤²à¤¾ हवे (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "मारà¥à¤—मधà¥à¤¯à¥‡ दोन परसà¥à¤ªà¤° सà¥à¤²à¥…शेसॠसमाविषà¥à¤Ÿà¥€à¤¤ नाही पाहिजे (//)\n" + +#: ../gio/gsettings-tool.c:477 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "दिलेले मूलà¥à¤¯ वैध वà¥à¤¯à¤¾à¤ªà¥à¤¤à¤¿à¤šà¥à¤¯à¤¾ बाहेर आहे\n" + +#: ../gio/gsettings-tool.c:484 +#, c-format +msgid "The key is not writable\n" +msgstr "कि लेखनजोगी नाही\n" + +#: ../gio/gsettings-tool.c:520 +msgid "List the installed (non-relocatable) schemas" +msgstr "पà¥à¤°à¤¤à¤¿à¤·à¥à¤ à¤¾à¤ªà¥€à¤¤ (विना-पà¥à¤¨à¤ƒà¤¶à¥‹à¤§à¤£à¥à¤¯à¤¾à¤œà¥‹à¤—ी) सà¥à¤•िमाजॠदाखवा" + +#: ../gio/gsettings-tool.c:526 +msgid "List the installed relocatable schemas" +msgstr "पà¥à¤°à¤¤à¤¿à¤·à¥à¤ à¤¾à¤ªà¥€à¤¤ पà¥à¤¨à¤ƒà¤¶à¥‹à¤§à¤£à¥à¤¯à¤¾à¤œà¥‹à¤—ी सà¥à¤•िमाजॠदाखवा" + +#: ../gio/gsettings-tool.c:532 +msgid "List the keys in SCHEMA" +msgstr "SCHEMA मधील किजॠदाखवा" + +#: ../gio/gsettings-tool.c:533 ../gio/gsettings-tool.c:539 +#: ../gio/gsettings-tool.c:576 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:538 +msgid "List the children of SCHEMA" +msgstr "SCHEMA चे चिलà¥à¤¡à¤°à¤¨ दाखवा" + +#: ../gio/gsettings-tool.c:544 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"किजॠव मूलà¥à¤¯à¤¾à¤‚ची सूची दाखवा, पà¥à¤¨à¤ƒ\n" +"SCHEMA दिले नसलà¥à¤¯à¤¾à¤¸, सरà¥à¤µ किजॠदाखवा\n" + +#: ../gio/gsettings-tool.c:546 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:551 +msgid "Get the value of KEY" +msgstr "KEY किचे मूलà¥à¤¯ पà¥à¤°à¤¾à¤ªà¥à¤¤ करा" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:570 ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:557 +msgid "Query the range of valid values for KEY" +msgstr "KEY करीता वैध मूलà¥à¤¯à¤¾à¤‚ची वà¥à¤¯à¤¾à¤ªà¥à¤¤à¤¿à¤šà¥€ चौकशी करा" + +#: ../gio/gsettings-tool.c:563 +msgid "Set the value of KEY to VALUE" +msgstr "VALUE करीता KEY चे मूलà¥à¤¯ ठरवा" + +#: ../gio/gsettings-tool.c:564 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:569 +msgid "Reset KEY to its default value" +msgstr "KEY ला पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ मूलà¥à¤¯à¤•रीता पूरà¥à¤µà¤µà¤¤à¥ करा" + +#: ../gio/gsettings-tool.c:575 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "SCHEMA मधील सरà¥à¤µ किजà¥à¤²à¤¾ परसà¥à¤ªà¤° पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤à¤•रीता पूरà¥à¤µà¤µà¤¤à¥ करा" + +#: ../gio/gsettings-tool.c:581 +msgid "Check if KEY is writable" +msgstr "KEY लेखनजोगी आहे याची तपासणी करा" + +#: ../gio/gsettings-tool.c:587 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"बदलांकरीता KEY मॉनिटर करा.\n" +"KEY निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले नसलà¥à¤¯à¤¾à¤¸, SCHEMA मधील सरà¥à¤µ किज मॉनिटर करा.\n" +"मॉनिटरिंग थांबवणà¥à¤¯à¤¾à¤•रीता ^C याचा वापर करा.\n" + +#: ../gio/gsettings-tool.c:590 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:602 +#| msgid "" +#| "Usage:\n" +#| " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " list-schemas List installed schemas\n" +#| " list-relocatable-schemas List relocatable schemas\n" +#| " list-keys List keys in a schema\n" +#| " list-children List children of a schema\n" +#| " list-recursively List keys and values, recursively\n" +#| " range Queries the range of a key\n" +#| " get Get the value of a key\n" +#| " set Set the value of a key\n" +#| " reset Reset the value of a key\n" +#| " reset-recursively Reset all values in a given schema\n" +#| " writable Check if a key is writable\n" +#| " monitor Watch for changes\n" +#| "\n" +#| "Use 'gsettings help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"वापर:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"आदेश:\n" +" help हि माहिती दाखवा\n" +" list-schemas पà¥à¤°à¤¤à¤¿à¤·à¥à¤ à¤¾à¤ªà¥€à¤¤ सà¥à¤•िमा दाखवा\n" +" list-relocatable-schemas पà¥à¤¨à¤ƒà¤¸à¥à¤¥à¤¾à¤¨à¤¾à¤‚तरनजोगी सà¥à¤•िमाजॠदाखवा\n" +" list-keys सà¥à¤•िमामधà¥à¤¯à¥‡ किजॠदाखवा\n" +" list-children सà¥à¤•िमाचे चिलà¥à¤¡à¤°à¤¨ दाखवा\n" +" list-recursively किजॠव वॅलà¥à¤¯à¥à¤œà¥ दाखवा, पà¥à¤¨à¤ƒ\n" +" range किचà¥à¤¯à¤¾ वà¥à¤¯à¤¾à¤ªà¥à¤¤à¤¿à¤•रीता चौकशी करतो\n" +" get किचे मूलà¥à¤¯ पà¥à¤°à¤¾à¤ªà¥à¤¤ करा\n" +" set किचे मूलà¥à¤¯ ठरवा\n" +" reset किचे मूलà¥à¤¯ पूरà¥à¤µà¤µà¤¤à¥ करा\n" +" reset-recursively दिलेलà¥à¤¯à¤¾ सà¥à¤•िमामधà¥à¤¯à¥‡ सरà¥à¤µ मूलà¥à¤¯à¥‡ पूरà¥à¤µà¤µà¤¤à¥ करा\n" +" writable कि लेखनजोगी आहे याची तपासणी करा\n" +" monitor बदल तपासा\n" +"\n" +"तपशीलमधà¥à¤¯à¥‡ मदतकरीता 'gsettings help COMMAND' याचा वापर करा.\n" +"\n" + +#: ../gio/gsettings-tool.c:625 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"वापर:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:631 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR अगाऊ सà¥à¤•िमाजॠशोधणà¥à¤¯à¤¾à¤•रीता डिरेकà¥à¤Ÿà¥à¤°à¥€\n" + +#: ../gio/gsettings-tool.c:639 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA सà¥à¤•िमाचे नाव\n" +" PATH मारà¥à¤—, पà¥à¤¨à¤ƒà¤¸à¥à¤¥à¤¾à¤¨à¤¾à¤‚तरनजोगी सà¥à¤•िमाजॠकरीता\n" + +#: ../gio/gsettings-tool.c:644 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY सà¥à¤•िमा अंतरà¥à¤—त (वैकलà¥à¤ªà¤¿à¤•) कि\n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The key within the schema\n" +msgstr " KEY सà¥à¤•िमामधील कि\n" + +#: ../gio/gsettings-tool.c:652 +msgid " VALUE The value to set\n" +msgstr " VALUE ठरवणà¥à¤¯à¤¾à¤œà¥‹à¤—ी मूलà¥à¤¯\n" + +#: ../gio/gsettings-tool.c:707 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s: %s पासून सà¥à¤•िमाज लोड करणे अशकà¥à¤¯\n" + +#: ../gio/gsettings-tool.c:769 +#, c-format +msgid "Empty schema name given\n" +msgstr "रिकामे सà¥à¤•िमा नाव दिले\n" + +#: ../gio/gsettings-tool.c:798 +#, c-format +msgid "No such key '%s'\n" +msgstr "कि '%s' आढळली नाही\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "अवैध सॉकेट, सà¥à¤°à¥‚ केले नाही" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "अवैध सॉकेट, कारणासà¥à¤¤à¤µ अपयशी: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "सॉकेट आधिपासून बंद आहे" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "सॉकेट I/O वेळ समापà¥à¤¤à¤¿ आढळली" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd पासून GSocket बनवत आहे: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "सॉकेट निरà¥à¤®à¤¾à¤£ करणे अशकà¥à¤¯: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "अपरिचीत फॅमिलि निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केली" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "अपरिचीत पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ केले" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "सà¥à¤¥à¤¾à¤¨à¥€à¤¯ पतà¥à¤¤à¤¾ पà¥à¤°à¤¾à¤ªà¥à¤¤ करणà¥à¤¯à¤¾à¤¸ अशकà¥à¤¯: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "दूरसà¥à¤¥ पतà¥à¤¤à¤¾ पà¥à¤°à¤¾à¤ªà¥à¤¤ करणà¥à¤¯à¤¾à¤¸ अशकà¥à¤¯: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "à¤à¤•णे अशकà¥à¤¯: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "पतà¥à¤¤à¥à¤¯à¤¾à¤¶à¥€ बांधणी करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "मलà¥à¤Ÿà¤¿à¤•ासà¥à¤Ÿ गट: %s समाविषà¥à¤Ÿ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "मलà¥à¤Ÿà¤¿à¤•ासà¥à¤Ÿ गट: %s सोडतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "सà¥à¤°à¥‹à¤¤-निरà¥à¤¦à¥‡à¤¶à¥€à¤¤ मलà¥à¤Ÿà¤¿à¤•ासà¥à¤Ÿà¤•रीता समरà¥à¤¥à¤¨ नाही" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "तà¥à¤°à¥à¤Ÿà¥€ सà¥à¤µà¥€à¤•ारतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "जà¥à¤³à¤µà¤£à¥€ चालू आहे" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "उरà¥à¤µà¤°à¥€à¤¤ तà¥à¤°à¥à¤Ÿà¥€ पà¥à¤°à¤¾à¤ªà¥à¤¤ करणे अशकà¥à¤¯: " + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "डाटा पà¥à¤°à¤¾à¤ªà¥à¤¤ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "डाटा पाठवतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "सॉकेट: %s पूरà¥à¤£à¤ªà¤£à¥‡à¤¬à¤‚द करणे अशकà¥à¤¯" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "सॉकेट बंद करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "सॉकेट अटची पà¥à¤°à¤¤à¤¿à¤•à¥à¤·à¤¾ करत आहे: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "फाइल पाठवतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "Windows वर GSocketControlMessage समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "संदेश पà¥à¤°à¤¾à¤ªà¥à¤¤ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gsocket.c:4516 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "सॉकेट शà¥à¤°à¥‡à¤¯: %s वाचणà¥à¤¯à¤¾à¤¸ अशकà¥à¤¯" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "या OS करीता g_socket_get_credentials लागू केले नाही" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° %s सह जोडणी अशकà¥à¤¯: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s सह जोडणी अशकà¥à¤¯: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "जोडणी अशकà¥à¤¯: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1603 +msgid "Unknown error on connect" +msgstr "जà¥à¤³à¤µà¤£à¥€à¤¨à¤‚तर अपरिचीत तà¥à¤°à¥à¤Ÿà¥€ आढळली" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1538 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "विना-TCP जोडणी वरील पà¥à¤°à¥‰à¤•à¥à¤¸à¤¿à¤‡à¤‚ग समरà¥à¤¥à¥€à¤¤ नाही." + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1559 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल '%s' समरà¥à¤¥à¥€à¤¤ नाही." + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "Listener आधिपासूनच बंद आहे" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "समावेश केलेले सॉकेट बंद आहे" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 हे IPv6 पतà¥à¤¤à¤¾ '%s' करीता समरà¥à¤¥à¤¨ पà¥à¤°à¤µà¤¤ नाही" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "वापरकरà¥à¤¤à¤¾à¤¨à¤¾à¤µ SOCKSv4 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉलकरीता खूप लांब आहे" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉलकरीता यजमाननाव '%s' खूप लांब आहे" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "सरà¥à¤µà¥à¤¹à¤° SOCKSv4 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° नाही." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 सरà¥à¤µà¥à¤¹à¤°à¤¤à¤°à¥à¤«à¥‡ जोडणी नकारली गेली" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "सरà¥à¤µà¥à¤¹à¤° SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° नाही." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€à¤•रीता ओळखपटवणे आवशà¥à¤¯à¤•." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€à¤²à¤¾ ऑथेंटिकेशन मेथड आवशà¥à¤¯à¤• आहे जà¥à¤¯à¤¾à¤¸ GLib तरà¥à¤«à¥‡ समरà¥à¤¥à¤¨ पà¥à¤°à¤µà¤²à¥‡ " +"जात नाही." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉलकरीता वापरकरà¥à¤¤à¤¾à¤¨à¤¾à¤µ किंवा पासवरà¥à¤¡ खूप लांब आहे." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"चà¥à¤•िचà¥à¤¯à¤¾ वापरकरà¥à¤¤à¤¾à¤¨à¤¾à¤µ किंवा पासवरà¥à¤¡à¤®à¥à¤³à¥‡ SOCKSv5 ओळखपटवणà¥à¤¯à¤¾à¤šà¥€ पदà¥à¤§à¤¤ अपयशी à¤à¤¾à¤²à¥€." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉलकरीता यजमाननाव '%s' खूप लांब आहे" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° अपरिचीत पतà¥à¤¤à¤¾ पà¥à¤°à¤•ारचा वापर करते." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "आंतरिक SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° तà¥à¤°à¥à¤Ÿà¥€." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 जोडणी रूलसेटतरà¥à¤«à¥‡ सà¥à¤µà¥€à¤•ारले जात नाही." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 सरà¥à¤µà¥à¤¹à¤°à¤¤à¤°à¥à¤«à¥‡ यजमान पोहचणà¥à¤¯à¤¾à¤œà¥‹à¤—ी नाही." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€à¤¤à¤°à¥à¤«à¥‡ नेटवरà¥à¤• पोहचणà¥à¤¯à¤¾à¤œà¥‹à¤—ी नाही." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€à¤¤à¤°à¥à¤«à¥‡ जोडणी नकारली गेली." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ 'connect' आदेशकरीता समरà¥à¤¥à¤¨ पà¥à¤°à¤µà¤¤ नाही." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ पà¥à¤°à¤µà¤²à¥‡à¤²à¥à¤¯à¤¾ पतà¥à¤¤à¤¾ पà¥à¤°à¤•ारकरीता समरà¥à¤¥à¤¨ पà¥à¤°à¤µà¤¤ नाही." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "अपरिचीत SOCKSv5 पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ तà¥à¤°à¥à¤Ÿà¥€." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon à¤à¤¨à¤•ोडींगची आवृतà¥à¤¤à¥€ %d हाताळू शकत नाही" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "वैध पतà¥à¤¤à¥‡ आढळले नाही" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s'चà¥à¤¯à¤¾ उलट-निरà¥à¤§à¤¾à¤°à¤£à¤µà¥‡à¤³à¥€ तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "'%s' करीता विनंती केलेलà¥à¤¯à¤¾ पà¥à¤°à¤•ारचे DNS रेकॉरà¥à¤¡ आढळले नाही" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "तातà¥à¤ªà¥à¤°à¥à¤¤à¥‡ '%s'चे निरà¥à¤§à¤¾à¤°à¤£ करणà¥à¤¯à¤¾à¤¸ अशकà¥à¤¯" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "तà¥à¤°à¥à¤Ÿà¥€à¤šà¥à¤¯à¤¾ निरà¥à¤§à¤¾à¤°à¤£à¤µà¥‡à¤³à¥€ तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gtlscertificate.c:247 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-à¤à¤‚कोडेड पà¥à¤°à¤¾à¤‡à¤µà¥à¤¹à¥‡à¤Ÿ कि डिकà¥à¤°à¤¿à¤ªà¥à¤Ÿ करणे अशकà¥à¤¯" + +#: ../gio/gtlscertificate.c:252 +msgid "No PEM-encoded private key found" +msgstr "PEM-à¤à¤‚कोडेड पà¥à¤°à¤¾à¤‡à¤µà¥à¤¹à¥‡à¤Ÿ कि आढळली नाही" + +#: ../gio/gtlscertificate.c:262 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-à¤à¤‚कोडेड पà¥à¤°à¤¾à¤‡à¤µà¥à¤¹à¥‡à¤Ÿ कि वाचणे अशकà¥à¤¯" + +#: ../gio/gtlscertificate.c:287 +msgid "No PEM-encoded certificate found" +msgstr "PEM-à¤à¤‚कोडेड पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आढळले नाही" + +#: ../gio/gtlscertificate.c:296 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-à¤à¤‚कोडेड पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° वाचणे अशकà¥à¤¯" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"पà¥à¤°à¤µà¥‡à¤¶ कà¥à¤²à¥‚पबंद करणà¥à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€ पासवरà¥à¤¡ योगà¥à¤¯à¤°à¤¿à¤¤à¥à¤¯à¤¾ देणà¥à¤¯à¤¾à¤šà¤¾ हा शेवटचा परà¥à¤¯à¤¾à¤¯ " +"आहे." + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"बरेच दिलेले पासवरà¥à¤¡ अयोगà¥à¤¯ आहेत, व पà¥à¤¢à¥€à¤² अपयशनंतर तà¥à¤®à¤šà¥‡ पà¥à¤°à¤µà¥‡à¤¶ कà¥à¤²à¥‚पबंद केले " +"जाईल." + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "दिलेले पासवरà¥à¤¡ अयोगà¥à¤¯ आहे." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 कंटà¥à¤°à¥‹à¤² संदेश अपेकà¥à¤·à¥€à¤¤, %d पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" +msgstr[1] "1 कंटà¥à¤°à¥‹à¤² संदेश अपेकà¥à¤·à¥€à¤¤, %d पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "ancillary डाटाचा अनपेकà¥à¤·à¥€à¤¤ पà¥à¤°à¤•ार" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "à¤à¤• fd अपेकà¥à¤·à¥€à¤¤, परंतॠ%d पà¥à¤°à¤¾à¤ªà¥à¤¤\n" +msgstr[1] "à¤à¤• fd अपेकà¥à¤·à¥€à¤¤, परंतॠ%d पà¥à¤°à¤¾à¤ªà¥à¤¤\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "अवैध fd पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "शà¥à¤°à¥‡à¤¯ पाठवतेवेळी तà¥à¤°à¥à¤Ÿà¥€: " + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "सॉकेट: %s करीता SO_PASSCRED सà¥à¤°à¥‚ केले आहे याची तपासणी करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED: %s सà¥à¤°à¥‚ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"शà¥à¤°à¥‡à¤¯ पà¥à¤°à¤¾à¤ªà¥à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ सिंगल बाइट वाचणे अपकà¥à¤·à¥€à¤¤ आहे परंतॠà¤à¥€à¤°à¥‹ बाइटसॠवाचले" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "कंटà¥à¤°à¥‹à¤² संदेश अपेकà¥à¤·à¥€à¤¤ नाही, परंतॠ%d पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED: %s बंद करतेवेळी तà¥à¤°à¥à¤Ÿà¥€ आढळली" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "फाइल डिसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿà¤°: %s पासून वाचतेवेली तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "फाइल डिसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿà¤°: %s बंद करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gunixmounts.c:2054 ../gio/gunixmounts.c:2107 +msgid "Filesystem root" +msgstr "फाइलसिसà¥à¤Ÿà¤® रूट" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "फाइल डिसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿà¤°: %s करीता लिहतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "ॲबà¥à¤¸à¥à¤Ÿà¥à¤°à¥…कà¥à¤Ÿ UNIX डोमैन सॉकेट पतà¥à¤¤à¤¾ या पà¥à¤°à¤£à¤¾à¤²à¥€à¤µà¤° समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "खंड बाहेर कडा कारà¥à¤¯à¤¨à¥à¤µà¥€à¤¤ होत नाही" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "खंड eject किंवा eject_with_operation लागू करत नाही" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— आढळले नाही" + +#: ../gio/gwin32appinfo.c:306 +#, c-format +msgid "Error launching application: %s" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— पà¥à¤°à¤•à¥à¤·à¥‡à¤ªà¥€à¤¤ करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../gio/gwin32appinfo.c:342 +msgid "URIs not supported" +msgstr "URI समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../gio/gwin32appinfo.c:364 +msgid "association changes not supported on win32" +msgstr "संबंधीत बदल win32 वर समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../gio/gwin32appinfo.c:376 +msgid "Association creation not supported on win32" +msgstr "win32 वर ग निरà¥à¤®à¤¾à¤£ समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "हà¤à¤¡à¤²: %s पासून वाचतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "हà¤à¤¡à¤²: %s बंद करतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "हà¤à¤¡à¤²: %s करीता लिहतेवेळी तà¥à¤°à¥à¤Ÿà¥€" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "अतिरीकà¥à¤¤ मेमरी आढळली नाही" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "आंतरीक तà¥à¤°à¥à¤Ÿà¥€: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "आणखी इंपà¥à¤Ÿ आवशà¥à¤¯à¤•" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "अवैध संकोचीत डाटा" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "à¤à¤•णà¥à¤¯à¤¾à¤œà¥‹à¤—ी पतà¥à¤¤à¤¾" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "GTestDbus सह सहतà¥à¤µà¤¤à¤¾à¤•रीता दà¥à¤°à¥à¤²à¤•à¥à¤· केले" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "पतà¥à¤¤à¤¾à¤šà¥€ छपाई करा" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "शेल मोडमधà¥à¤¯à¥‡ पतà¥à¤¤à¥à¤¯à¤¾à¤šà¥€ छपाई करा" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "dbus सरà¥à¤µà¥à¤¹à¤¿à¤¸ चालवा" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "चà¥à¤•िचे आरà¥à¤—à¥à¤¸à¥\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "'%s' घटक करीता '%s' अनपेकà¥à¤·à¤¿à¤¤ गà¥à¤£à¤§à¤°à¥à¤®" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' घटकाकरीता '%s' गà¥à¤£à¤§à¤°à¥à¤® आढळले नाही" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "अनपेकà¥à¤·à¥€à¤¤ टॅग '%s', टॅग '%s' अपेकà¥à¤·à¥€à¤¤" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "'%2$s' चà¥à¤¯à¤¾ आत, '%1$s' अनपेकà¥à¤·à¥€à¤¤ टॅग" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "माहिती संचयीकेत वैध ओळखचिनà¥à¤¹ आढळले नाही" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s' करीता ओळखचिनà¥à¤¹ आधिपासूनच असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤ आहे" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s' करीता ओळखचिनà¥à¤¹ आढळले नाही" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s' करीता ओळखचिनà¥à¤¹à¤¾à¤¤ MIME पà¥à¤°à¤•ार वà¥à¤¯à¤¾à¤–à¥à¤¯à¥€à¤¤ नाही" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s' करीता ओळखचिनà¥à¤¹à¤¾à¤¤ वैयकà¥à¤¤à¤¿à¤• बाब वà¥à¤¯à¤¾à¤–à¥à¤¯à¥€à¤¤ नाही" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s' करीता ओळखचिनà¥à¤¹à¤¾à¤¤ गट निशà¥à¤šà¤¿à¤¤ नाही" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" +"'%s' नामांकीत कà¥à¤ à¤²à¥à¤¯à¤¾à¤¹à¥€ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—ाने '%s' करीता ओळखचिनà¥à¤¹ पंजीकृत केले नाही" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "'%s' पासून कारà¥à¤¯à¤¾à¤¨à¥à¤µà¥€à¤¤ ओळ '%s' विसà¥à¤¤à¤¾à¤°à¥€à¤¤ करू शकले नाही" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "आगतचà¥à¤¯à¤¾ शेवटी अपूरे अकà¥à¤·à¤° शà¥à¤°à¥ƒà¤‚खला" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "फॉलबॅक '%s' ला कोडसंच '%s' असे रूपांतर करू शकत नाही" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s' \"file\" योजना वापरणारी संपूरà¥à¤£ URI नाही" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "सà¥à¤¥à¤¾à¤¨à¤¿à¤• फाइल URI '%s' बहà¥à¤¦à¤¾ '#' समाविषà¥à¤Ÿà¥€à¤¤ करणार नाही" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' अवैध आहे" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI '%s' चे यजमान अवैध आहे" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' मधà¥à¤¯à¥‡ अवैध निसटती अकà¥à¤·à¤°à¥‡ समाविषà¥à¤Ÿà¥€à¤¤ आहे" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "मारà¥à¤—नाव '%s' संपूरà¥à¤£ मारà¥à¤— नाही" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "अवैध यजमान" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "म.पू." + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "म.नं." + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%A %d %b %Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%I:%M:%S %Z" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "जानेवारी" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "फेबà¥à¤°à¥à¤µà¤¾à¤°à¥€" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "मारà¥à¤š" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "à¤à¤ªà¥à¤°à¤¿à¤²" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "मे" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "जून" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "जà¥à¤²à¥ˆ" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "ऑगसà¥à¤Ÿ" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "सपà¥à¤Ÿà¥‡à¤‚बर" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "ऑकà¥à¤Ÿà¥‹à¤¬à¤°" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "नोवà¥à¤¹à¥‡à¤‚बर" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "डिसेंबर" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "जाने" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "फेबà¥à¤°à¥" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "मारà¥à¤š" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à¤à¤ªà¥à¤°à¤¿" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "मे" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "जून" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "जà¥à¤²à¥ˆ" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ऑग" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "सपà¥à¤Ÿà¥‡à¤‚" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "ऑकà¥à¤Ÿà¥‹" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "नोवà¥à¤¹à¥‡à¤‚" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "डिसें" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "सोमवार" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "मंगळवार" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "मंगळवार" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "गà¥à¤°à¥à¤µà¤¾à¤°" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "शà¥à¤•à¥à¤°à¤µà¤¾à¤°" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "शनिवार" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "रविवार" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "सोम" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "मंगळ" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "बà¥à¤§" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "गà¥à¤°à¥" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "शà¥à¤•à¥à¤°" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "शनि" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "रवि" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "संचयीका '%s' उघडतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "फाइल \"%2$s\" करीता %1$lu बाइटचे वाटप अशकà¥à¤¯" +msgstr[1] "फाइल \"%2$s\" करीता %1$lu बाइटà¥à¤¸à¤šà¥‡ वाटप अशकà¥à¤¯" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' फाइल वाचताना तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "फाइल \"%s\" खूप मोठे आहे" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' फाइल वाचतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' फाइल उघडणà¥à¤¯à¤¾à¤¸ अपयशी: %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "फाइल '%s'चे गà¥à¤£à¤§à¤°à¥à¤® पà¥à¤°à¤¾à¤ªà¥à¤¤ करणà¥à¤¯à¤¾à¤¸ अयशसà¥à¤µà¥€: fstat() अपयशी: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' फाइल उघडणà¥à¤¯à¤¾à¤¸ अपयशी: fdopen() अपयशी : %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"फाइलला '%s पासून '%s' असे पà¥à¤¨à¤°à¥à¤¨à¤¾à¤®à¤¾à¤‚कन करणà¥à¤¯à¤¾à¤¸ अपयशी: g_rename() अपयशी: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "फाइल बनविणà¥à¤¯à¤¾à¤¸ अपयशी '%s': %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "फाइल '%s' करिता लिहणे अपयशी: write() अपयशी: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' फाइलवर लिहणà¥à¤¯à¤¾à¤¸ अपयशी: fsync() अपयशी: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "उपलबà¥à¤§ फाइल '%s' काढूण टाकलà¥à¤¯à¤¾ जाऊ शकत नाही: g_unlink() अपयशी: %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "आराखडा '%s' अवैध, '%s' समाविषà¥à¤Ÿà¥€à¤¤ नसायला हवे" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "आराखडा '%s' मधà¥à¤¯à¥‡ XXXXXX समाविषà¥à¤Ÿà¥€à¤¤ नाही" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "बोधचिनà¥à¤¹ लिंक '%s' वाचणà¥à¤¯à¤¾à¤¸ अपयशी: %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "बोधचिनà¥à¤¹ लिंक समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' पासून '%s' असे रूपांतरक उघडू शकले नाही: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string वाचता येऊ शकले नाही" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "वाचन बफरमधà¥à¤¯à¥‡ उरà¥à¤µà¤°à¥€à¤¤ बिनरूपांतरीत माहिती" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "अपूरे अकà¥à¤·à¤° असलà¥à¤¯à¤¾à¤¸ मारà¥à¤— बंद होते" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end वाचता येऊ शकले नाही" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "शोध संचयीकेत वैध किलà¥à¤²à¥€ फाइल आढळली नाही" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "नियमीत फाइल नाही" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"की फाइल मधà¥à¤¯à¥‡ ओळ '%s' अंतरà¥à¤­à¥‚त आहे जे की-मà¥à¤²à¥à¤¯ जोड, गट, किंवा टिपपà¥à¤£à¥€ नाही" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "अवैध गट नाव: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "की फाइल गटासह सà¥à¤°à¥‚ होत नाही" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "अवैध की नाव: %s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "की फाइल मधà¥à¤¯à¥‡ असमरà¥à¤¥à¤¿à¤¤ à¤à¤¨à¤•ोडींग '%s' समाविषà¥à¤Ÿà¥€à¤¤ आहे" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1692 ../glib/gkeyfile.c:3072 +#: ../glib/gkeyfile.c:3138 ../glib/gkeyfile.c:3264 ../glib/gkeyfile.c:3397 +#: ../glib/gkeyfile.c:3539 ../glib/gkeyfile.c:3768 ../glib/gkeyfile.c:3835 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "की फाइलमधà¥à¤¯à¥‡ '%s' गट समाविषà¥à¤Ÿà¥€à¤¤ नाही" + +#: ../glib/gkeyfile.c:1704 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "की फाइल मधà¥à¤¯à¥‡ '%s' की नाही" + +#: ../glib/gkeyfile.c:1811 ../glib/gkeyfile.c:1927 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"किलà¥à¤²à¥€ फाइल मधà¥à¤¯à¥‡ '%1$s' किलà¥à¤²à¥€ समाविषà¥à¤Ÿà¥€à¤¤ आहे जà¥à¤¯à¤¾à¤šà¥‡ '%2$s' मà¥à¤²à¥à¤¯ UTF-8 नाही" + +#: ../glib/gkeyfile.c:1831 ../glib/gkeyfile.c:1947 ../glib/gkeyfile.c:2316 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"कि फाइल मधà¥à¤¯à¥‡ '%s' कि समाविषà¥à¤Ÿà¥€à¤¤ आहे जà¥à¤¯à¤¾à¤šà¥‡ मà¥à¤²à¥à¤¯ विशà¥à¤²à¥‡à¤·à¥€à¤¤ करणे अशकà¥à¤¯ आहे." + +#: ../glib/gkeyfile.c:2533 ../glib/gkeyfile.c:2901 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"कि फाइलमधà¥à¤¯à¥‡ गट '%2$s' मधà¥à¤¯à¥‡ कि '%1$s' समाविषà¥à¤Ÿà¥€à¤¤ आहे जà¥à¤¯à¤¾à¤šà¥‡ मूलà¥à¤¯ विशà¥à¤²à¥‡à¤·à¥€à¤¤ " +"करणे अशकà¥à¤¯ आहे." + +#: ../glib/gkeyfile.c:2611 ../glib/gkeyfile.c:2688 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" +"गट '%2$s' मधील कि '%1$s' याचे मूलà¥à¤¯ '%3$s' आहे, जेथे %4$s अपेकà¥à¤·à¤¿à¤¤ होते" + +#: ../glib/gkeyfile.c:3087 ../glib/gkeyfile.c:3279 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "गट '%s' मधिल '%s' किलà¥à¤²à¥€ किलà¥à¤²à¥€ फाइल मधà¥à¤¯à¥‡ समाविषà¥à¤Ÿà¥€à¤¤ नाही" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "किलà¥à¤²à¥€ फाइलीत निसटते अकà¥à¤·à¤° ओळीचà¥à¤¯à¤¾ अखेरस समाविषà¥à¤Ÿà¥€à¤¤ आहे" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "किलà¥à¤²à¥€ फाइल मधà¥à¤¯à¥‡ अवैध '%s' निसटती शà¥à¤°à¥ƒà¤‚खला समाविषà¥à¤Ÿà¥€à¤¤ आहे" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "मà¥à¤²à¥à¤¯ '%s' संखà¥à¤¯à¤¾ मà¥à¤¹à¤£à¥‚न विशà¥à¤²à¥‡à¤·à¥€à¤¤ केले जाऊ शकत नाही." + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मà¥à¤²à¥à¤¯ '%s' कà¥à¤·à¥‡à¤¤à¥à¤°à¤¾à¤šà¥à¤¯à¤¾ अंतरà¥à¤—त नाही" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "मà¥à¤²à¥à¤¯ '%s' फà¥à¤²à¥‹à¤Ÿ संखà¥à¤¯à¤¾ मà¥à¤¹à¤£à¥‚न विशà¥à¤²à¥‡à¤·à¥€à¤¤ केले जाऊ शकत नाही." + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "मà¥à¤²à¥à¤¯ '%s' बूलीयन मà¥à¤¹à¤£à¥‚न विशà¥à¤²à¥‡à¤·à¥€à¤¤ केले जाऊ शकत नाही." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "फाइल '%s%s%s%s' चे गà¥à¤£à¤§à¤°à¥à¤® पà¥à¤°à¤¾à¤ªà¥à¤¤ करणà¥à¤¯à¤¾à¤¸ अपयशी: fstat() अपयशी: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s ला मॅप करणà¥à¤¯à¤¾à¤¸ अपयशी: mmap() अपयशी: %s " + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "'%s' फाइल उघडणà¥à¤¯à¤¾à¤¸ अपयशी: open() अपयशी: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "ओळ %d अकà¥à¤·à¤° %d वर तà¥à¤°à¥‚टी आढळली: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "नावातील अवैध UTF-8 à¤à¤¨à¤•ोड मजकूर - वैध '%s' नाही" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' वैध नाव नाही" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' वैध नाव: '%c' नाही" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "ओळ %d वर तà¥à¤°à¥‚टी: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' वाचता आले नाही, जे अकà¥à¤·à¤° संदरà¥à¤­à¤šà¥à¤¯à¤¾ आत अंक मà¥à¤¹à¤£à¥‚न असायला हवे होते " +"(उदाहरà¥à¤£à¤¾à¤¥ " +"ê) - तसेच अंक खूप मोठे आहे" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"अकà¥à¤·à¤° संदरà¥à¤­ सेमीकोलनवर संपत नाही; शकà¥à¤¯à¤¤à¤ƒ तà¥à¤®à¥à¤¹à¥€ वसà¥à¤¤à¥à¤²à¤¾ सà¥à¤°à¥‚ करणà¥à¤¯à¤¾à¤•रीता " +"& सà¥à¤µà¤°à¥‚प न " +"वापरता तà¥à¤®à¥à¤¹à¥€ à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड अकà¥à¤·à¤° वापरले असावे" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "अकà¥à¤·à¤° संदरà¥à¤­ '%-.*s' परवानगीय अकà¥à¤·à¤°à¤¾à¤¸ à¤à¤¨à¤•ोड करीत नाही" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"रिकामी वसà¥à¤¤à¥ '&;' आढळली; वैध वसà¥à¤¤à¥‚ यापà¥à¤°à¤•ारे आहेत: & " < > " +"'" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "घटकाचे नाव '%-.*s' अपरिचीत आहे" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"वसà¥à¤¤à¥‚ सेमीकोलनवर संपत नाही; शकà¥à¤¯à¤¤à¤ƒ तà¥à¤®à¥à¤¹à¥€ वसà¥à¤¤à¥à¤²à¤¾ सà¥à¤°à¥‚ करणà¥à¤¯à¤¾à¤•रीता & " +"सà¥à¤µà¤°à¥‚प न वापरता " +"à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚ड अकà¥à¤·à¤° वापरले असावे" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "दसà¥à¤¤à¤à¤µà¤œà¤šà¥€ सà¥à¤°à¤µà¤¾à¤¤ घटकाशी वà¥à¤¹à¤¾à¤µà¥€ (उ.दा. )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'<' अकà¥à¤·à¤°à¤¾à¤¨à¤‚तर '%s' वैध अकà¥à¤·à¤° नाही; तà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ घटक नाव सà¥à¤°à¥‚ होऊ शकणार नाही" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "असाधारण अकà¥à¤·à¤° '%1$s', रिकामे-घटक टॅग '%2$s' करीता '>' अकà¥à¤·à¤° अपेकà¥à¤·à¥€à¤¤" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"'%s' असाधारण अकà¥à¤·à¤° आहे, घटक '%s' चà¥à¤¯à¤¾ '%s' गà¥à¤£à¤§à¤°à¥à¤® नावानंतर '=' अपेकà¥à¤·à¥€à¤¤" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"'%s' असाधारण अकà¥à¤·à¤° आहे, घटकाचे पà¥à¤°à¤¾à¤°à¤‚भीक टॅग '%s' समापà¥à¤¤ करणà¥à¤¯à¤¾à¤•रीता '>' " +"किंवा '/' " +"अकà¥à¤·à¤° अपेकà¥à¤·à¥€à¤¤, किंवा परà¥à¤¯à¤¾à¤¯à¤¸à¥à¤µà¤°à¥‚पी गà¥à¤£à¤§à¤°à¥à¤® अपेकà¥à¤·à¥€à¤¤; तसेच तà¥à¤®à¥à¤¹à¥€ गà¥à¤£à¤§à¤°à¥à¤® " +"नावात अवैध अकà¥à¤·à¤° " +"वापरले" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"'%s' असाधारण अकà¥à¤·à¤° आहे, घटक '%s' चà¥à¤¯à¤¾ गà¥à¤£à¤§à¤°à¥à¤® '%s' करीता मà¥à¤²à¥à¤¯ पà¥à¤°à¤¦à¤¾à¤¨ " +"करतेवेळी समांतर " +"चिनà¥à¤¹à¤¾ नंतर उघडे कà¥à¤µà¥‹à¤Ÿ अपेकà¥à¤·à¥€à¤¤" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "'%s' घटक नावानंतर '%s' वैध अकà¥à¤·à¤° नाही; परवानगीय अकà¥à¤·à¤° '>' आहे" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "घटक '%s' बंद केले गेले,कà¥à¤ à¤²à¥‡à¤¹à¥€ घटक आता उघडे नाही" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "घटक '%s' बंद केले गेले, पण सदà¥à¤¯à¤¾ '%s' हे घटक उघडे आहे" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "दसà¥à¤¤à¤à¤µà¤œ रिकामे होते किंवा फकà¥à¤¤ रिकà¥à¤¤ जागा समाविषà¥à¤Ÿà¥€à¤¤ होती" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "उघडे कोन कंस '<' नंतरच दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ समापà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"घटक उघडे असूनही दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ समापà¥à¤¤ à¤à¤¾à¤²à¥‡ - '%s'शेवटचे उगडे घटक होते" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ समापà¥à¤¤ à¤à¤¾à¤²à¥‡, टॅग <%s/> ला बंद करणà¥à¤¯à¤¾à¤•रीता समापà¥à¤¤à¥€à¤¯ " +"कोन कंस " +"उपेकà¥à¤·à¥€à¤¤" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "घटकाचà¥à¤¯à¤¾ नावाअंतरà¥à¤—त दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ समापà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "गà¥à¤£à¤§à¤°à¥à¤®à¤¾à¤šà¥à¤¯à¤¾ नावाअंतरà¥à¤—त दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ समापà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "घटकाचà¥à¤¯à¤¾-खà¥à¤²à¥à¤¯à¤¾ टॅग अंतरà¥à¤—त दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ समापà¥à¤¤ à¤à¤¾à¤²à¥‡." + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"गà¥à¤£à¤§à¤°à¥à¤® नावा पाठोपाठ समांतर चिनà¥à¤¹à¤¾à¤¨à¤‚तर दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ समापà¥à¤¤ à¤à¤¾à¤²à¥‡; " +"गà¥à¤£à¤§à¤°à¥à¤®à¤¾à¤šà¥‡ मà¥à¤²à¥à¤¯ " +"नाही" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"गà¥à¤£à¤§à¤°à¥à¤® मà¥à¤²à¥à¤¯à¤šà¥à¤¯à¤¾ अंतरà¥à¤­à¥‚त राहतेवेळी दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ समापà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ घटक '%s' करीता बंद टॅगचà¥à¤¯à¤¾ आत समापà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"दसà¥à¤¤à¤à¤µà¤œ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ टिपà¥à¤ªà¤£à¥€ किंवा सà¥à¤šà¤¨à¤¾à¤šà¥‡ विषलेशन करतेवेळी समापà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#: ../glib/goption.c:795 +msgid "Usage:" +msgstr "वापर:" + +#: ../glib/goption.c:795 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:911 +msgid "Help Options:" +msgstr "माहिती परà¥à¤¯à¤¾à¤¯:" + +#: ../glib/goption.c:912 +msgid "Show help options" +msgstr "मदत परà¥à¤¯à¤¾à¤¯ दारà¥à¤¶à¤µà¤¾" + +#: ../glib/goption.c:918 +msgid "Show all help options" +msgstr "सरà¥à¤µ मदत परà¥à¤¯à¤¾à¤¯ दरà¥à¤¶à¤µà¤¾" + +#: ../glib/goption.c:980 +msgid "Application Options:" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— परà¥à¤¯à¤¾à¤¯:" + +#: ../glib/goption.c:1044 ../glib/goption.c:1114 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "%2$s करीता संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मà¥à¤²à¥à¤¯ '%1$s' वाचता आले नाही" + +#: ../glib/goption.c:1054 ../glib/goption.c:1122 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%2$s करीता संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मà¥à¤²à¥à¤¯ '%1$s' कà¥à¤·à¥‡à¤¤à¥à¤°à¤¾à¤šà¥à¤¯à¤¾ अंतरà¥à¤—त नाही" + +#: ../glib/goption.c:1079 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "%2$s करीता दà¥à¤¹à¥‡à¤°à¥€ मà¥à¤²à¥à¤¯ '%1$s' वाचता आले नाही" + +#: ../glib/goption.c:1087 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "%2$s करीता दà¥à¤¹à¥‡à¤°à¥€ मà¥à¤²à¥à¤¯ '%1$s' कà¥à¤·à¥‡à¤¤à¥à¤°à¤¾à¤šà¥à¤¯à¤¾ अंतरà¥à¤—त नाही" + +#: ../glib/goption.c:1373 ../glib/goption.c:1452 +#, c-format +msgid "Error parsing option %s" +msgstr "%s परà¥à¤¯à¤¾à¤¯ वाचतेवेळी तà¥à¤°à¥‚टी" + +#: ../glib/goption.c:1483 ../glib/goption.c:1596 +#, c-format +msgid "Missing argument for %s" +msgstr "%s करीता बाब आढळले नाही" + +#: ../glib/goption.c:2057 +#, c-format +msgid "Unknown option %s" +msgstr "अपरिचीत परà¥à¤¯à¤¾à¤¯ %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "वसà¥à¤¤à¥ भà¥à¤°à¤·à¥à¤Ÿ आहे" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "आंतरीक तà¥à¤°à¥à¤Ÿà¥€ किंवा भà¥à¤°à¤·à¥à¤Ÿ वसà¥à¤¤à¥" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "अतिरीकà¥à¤¤ सà¥à¤®à¥ƒà¤¤à¥€ नाही" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "संयà¥à¤•à¥à¤¤ शोध सीमा पोहचले" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "रचनेत अपूरे जà¥à¤³à¤µà¤£à¥€à¤•रीता समाविषà¥à¤Ÿà¥€à¤¤ घटक जी समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "पà¥à¤¨à¤ƒ संदरà¥à¤­ कारण अपूरे जà¥à¤³à¤µà¤¿à¤£à¥€à¤•रीता सà¥à¤¥à¤¿à¤¤à¥€ समरà¥à¤¥à¤¿à¤¤ नाही" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "पà¥à¤¨à¤ƒà¤¨à¤¿à¤°à¥à¤®à¥€à¤¤ सीमा पोहचले" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "नविनओळ बाबींचे अवैध संयोग" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "अयोगà¥à¤¯ ऑफसेट" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "शारà¥à¤Ÿ utf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "रिकरà¥à¤¶à¤¨ लूप" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "अपरिचीत तà¥à¤°à¥à¤Ÿà¥€" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "रचनाचà¥à¤¯à¤¾ शेवटी \\" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "रचनाचà¥à¤¯à¤¾ शेवटी \\c" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "पाठोपाठ अनोळखी कॅरेकà¥à¤Ÿà¤° \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} quantifier मधील संखà¥à¤¯à¤¾ कà¥à¤°à¤®à¤¾à¤¤ नाही" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} quantifier मधील संखà¥à¤¯à¤¾ खूप मोठे आहे" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "अकà¥à¤·à¤° वरà¥à¤—करीता समापà¥à¤¤à¥€ ] चिनà¥à¤¹ आढळत नाही" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "अकà¥à¤·à¤° वरà¥à¤—ामधà¥à¤¯à¥‡ अवैध à¤à¤¸à¤•ेप शà¥à¤°à¥ƒà¤‚खला" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "अकà¥à¤·à¤° वरà¥à¤—ातले कà¥à¤°à¤®à¤¾à¤šà¥à¤¯à¤¾ कà¥à¤·à¥‡à¤¤à¥à¤°à¤¾ पलीकडे गेले आहे" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "पà¥à¤¨à¥à¤¹à¤¾à¤•ृती करीता काहीच नाही" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "अपरिचीत पà¥à¤¨à¤ƒà¤•ृती" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? किंवा (?- नंतर अनोळखी अकà¥à¤·à¤°" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX नामांकीत वरà¥à¤— फकà¥à¤¤ वरà¥à¤— अंतरà¥à¤—त समरà¥à¤¥à¥€à¤¤ आहे" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "समापà¥à¤¤à¥€ ) आढळले नाही" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "विना-असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾à¤¤à¥€à¤² उपरचना करीता संदरà¥à¤­" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "टिपà¥à¤ªà¤£à¥€ नंतर ) आढळले नाही" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "रेगà¥à¤¯à¥à¤²à¤° à¤à¤•à¥à¤¸à¤ªà¥à¤°à¥‡à¤¶à¤¨ खूप मोठे आहे" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¥€ पà¥à¤°à¤¾à¤ªà¥à¤¤ करणà¥à¤¯à¤¾à¤¸ अपयशी" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") ( ला न उघडता" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "कोड उतà¥à¤ªà¥à¤°à¤µà¤¾à¤¹" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "(?< नंतर अपरिचीत अकà¥à¤·à¤°" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind निशà¥à¤šà¤¿à¤¤ आकाराचे नाही" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "(?( नंतर सदोष संखà¥à¤¯à¤¾ किंवा नाव" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "सà¥à¤¥à¤¿à¤¤à¥€ समà¥à¤¹ मधà¥à¤¯à¥‡ à¤à¤•ा पेकà¥à¤·à¤¾ जासà¥à¤¤ शाखा आहेत" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "(?( नंतर होकारारà¥à¤¥à¥€ अपेकà¥à¤·à¥€à¤¤" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R किंवा (?[+-]अंक पाठोपाठ ) असायला पाहिजे" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "अपरिचीत POSIX वरà¥à¤— नाव" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "POSIX कोलेटींग घटक समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} शà¥à¤°à¥ƒà¤‚खला मधिल अकà¥à¤·à¤° मूलà¥à¤¯ खूप मोठे आहे" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "अवैध सà¥à¤¥à¤¿à¤¤à¥€ (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C lookbehind assertion अंतरà¥à¤—त सà¥à¤µà¥€à¤•ारà¥à¤¯ नाही" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "à¤à¤•à¥à¤¸à¥‡à¤ªà¥à¤¸à¥ \\L, \\l, \\N{name}, \\U, व \\u समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "recursive call चकà¥à¤° अनिशà¥à¤šà¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ चालू राहू शकते" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "(?P नंतर अपरिचीत अकà¥à¤·à¤°" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "उपरचना नावा मधà¥à¤¯à¥‡ समापà¥à¤¤à¥€ आढळली नाही" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "दोन नामांकीत उपरचनाकडे समान नाव आहे" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "सदोषीत \\P किंवा \\p शà¥à¤°à¥ƒà¤‚खला" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "\\P किंवा \\p नंतर अपरिचीत गà¥à¤£à¤§à¤°à¥à¤® नाव" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "उपरचना नाव खूपच लांब आहे (कमाल 32 अकà¥à¤·à¤°à¥‡)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "खूपच नामांकीत उपरचना आहेत (कमाल 10,000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "ऑकà¥à¤Ÿà¤² मूलà¥à¤¯ \\377 पेकà¥à¤·à¤¾ जासà¥à¤¤ आहे" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "उतà¥à¤ªà¤•ारà¥à¤¯à¤¨à¥à¤µà¥€à¤¤ कंपाइल कारà¥à¤¯à¤¸à¥à¤¥à¤³" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "पूरà¥à¤µà¥€-तपासलेले संदरà¥à¤­à¥€à¤¤ उपरचना आढळले नाही" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE समà¥à¤¹à¤¾à¤¤ à¤à¤•ा पेकà¥à¤·à¤¾ जासà¥à¤¤ शाखा आहे" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "असà¥à¤¥à¥€à¤° NEWLINE परà¥à¤¯à¤¾à¤¯" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"बà¥à¤°à¥‡à¤¸à¥à¤¡à¥, अà¤à¤—ल-बà¥à¤°à¥…केटेडà¥, किंवा कà¥à¤µà¥‹à¤Ÿà¥‡à¤¡à¥ नाव किंवा कà¥à¤°à¤®à¤¾à¤‚क, किंवा सोपे " +"कà¥à¤°à¤®à¤¾à¤‚क पाठोपाठ \\g येत " +"नाही" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "नंबरà¥à¤¡à¥ संदरà¥à¤­ à¤à¤¿à¤°à¥‹ असयला हवे" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" +"(*ACCEPT), (*FAIL), किंवा (*COMMIT) करीता आरà¥à¤—à¥à¤¯à¥à¤®à¥‡à¤‚टकरीता परवानगी नाही" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ओळखीचे नाही" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "कà¥à¤°à¤®à¤¾à¤‚क खूपच मोठे आहे" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& नंतर उपपॅटरà¥à¤¨ नाव आढळले नाही" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ नंतर अंक अपेकà¥à¤·à¤¿à¤¤ आहे" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "जावासà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ सहतà¥à¤µà¤¤à¤¾ मोडमधà¥à¤¯à¥‡ ] हे अवैध डाटा अकà¥à¤·à¤° आहे " + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "à¤à¤•ाच कà¥à¤°à¤®à¤¾à¤‚काचà¥à¤¯à¤¾ उपरचनाकरीता विविध नावे सà¥à¤µà¥€à¤•ारले जात नाही" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) कडे आरà¥à¤—à¥à¤¯à¥à¤®à¥‡à¤‚ट असणे आवशà¥à¤¯à¤•" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "ASCII अकà¥à¤·à¤°à¤¾à¤šà¥à¤¯à¤¾ पाठोपाठ \\c असायला हवे" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "बà¥à¤°à¥‡à¤¸à¥à¤¡à¥, अà¤à¤—ल-बà¥à¤°à¥…केटेडà¥, किंवा कà¥à¤µà¥‹à¤Ÿà¥‡à¤¡à¥ नाव पाठोपाठ \\k येत नाही" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N कà¥à¤²à¤¾à¤¸ अंतरà¥à¤—त समरà¥à¤¥à¥€à¤¤ नाही" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "फॉरवरà¥à¤¡ रेफरेंस à¤à¤• किंवा तà¥à¤¯à¤¾à¤ªà¥‡à¤•à¥à¤·à¤¾ जासà¥à¤¤ आहे" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), किंवा (*THEN) मधà¥à¤¯à¥‡ नाव खूपच लांब आहे " + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... शà¥à¤°à¥ƒà¤‚खला अंतरà¥à¤—त कॅरेकà¥à¤Ÿà¤° मूलà¥à¤¯ खूप मोठे आहे" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "रेगà¥à¤²à¤° à¤à¤•à¥à¤¸à¤ªà¥à¤°à¥‡à¤¶à¤¨ %s जà¥à¤³à¤µà¤£à¥€ करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE लायबà¥à¤°à¤°à¥€ बिना UTF8 समरà¥à¤¥à¤¨ कंपाईल केले गेले" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE लायबà¥à¤°à¤°à¥€ बिना UTF8 गà¥à¤£à¤§à¤°à¥à¤® समरà¥à¤¥à¤¨ कंपाईल केले गेले" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE लायबà¥à¤°à¤°à¥€ असहतà¥à¤µ परà¥à¤¯à¤¾à¤¯à¤¸à¤¹ कंपाइल केले" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"अकà¥à¤·à¤° %2$d वरील रेगà¥à¤²à¤° à¤à¤•à¥à¤¸à¤ªà¥à¤°à¥‡à¤¶à¤¨ %1$s जà¥à¤³à¤µà¤£à¥€ कंपाईल करतेवेळी तà¥à¤°à¥‚टी: %3$s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "रेगà¥à¤²à¤° à¤à¤•à¥à¤¸à¤ªà¥à¤°à¥‡à¤¶à¤¨ %s अधिक कारà¥à¤¯à¤•à¥à¤·à¤® करतेवेळी तà¥à¤°à¥‚टी: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "हेकà¥à¤œà¤¾à¤¡à¥‡à¤¸à¥€à¤®à¤² अंक किंवा '}' अपेकà¥à¤·à¥€à¤¤" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "कà¥à¤œà¤¾à¤¡à¥‡à¤¸à¥€à¤®à¤² अंक अपेकà¥à¤·à¥€à¤¤" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "बोधचिनà¥à¤¹ संदरà¥à¤­à¤¾à¤¤ '<' आढळले नाही" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "अपूरे बोधचिनà¥à¤¹ संदरà¥à¤­" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "शूनà¥à¤¯-लांबीचे बोधचिनà¥à¤¹ संदरà¥à¤­" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "अंक अपेकà¥à¤·à¥€à¤¤" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "अवैध बोधचिनà¥à¤¹ संदरà¥à¤­" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "अंतिम '\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "अपरिचीत निसटती शà¥à¤°à¥ƒà¤‚खला" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "अकà¥à¤·à¤° %2$lu वरील बदलाव पाठà¥à¤¯ \"%1$s\" वाचतेवेळी तà¥à¤°à¥‚टी: %3$s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "कà¥à¤µà¥‹à¤Ÿ मधà¥à¤¯à¥‡ असलेले पाठà¥à¤¯ कà¥à¤µà¥‹à¤Ÿà¥‡à¤¶à¤¨ चिनà¥à¤¹à¤¾à¤ªà¤¾à¤¸à¥‚न सà¥à¤°à¥‚ होत नाही" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "आदेश ओळ किंवा इतर शेल-कà¥à¤µà¥‹à¤Ÿ पाठà¥à¤¯ मधà¥à¤¯à¥‡ बिनजà¥à¤³à¤²à¥‡à¤²à¥€ कà¥à¤µà¥‹à¤Ÿà¥‡à¤¶à¤¨ चिनà¥à¤¹" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "पाठà¥à¤¯ '\\' अकà¥à¤·à¤° संपलà¥à¤¯à¤¾à¤µà¤° संपते. ('%s' पाठà¥à¤¯ होते)" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"%c करीता जà¥à¤³à¤¤à¥‡ कà¥à¤µà¥‹à¤Ÿ आढळणà¥à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€ पाठà¥à¤¯ समापà¥à¤¤ à¤à¤¾à¤²à¥‡. ('%s' पाठà¥à¤¯ होते)" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "पाठà¥à¤¯ रिकामे होते (किंवा तà¥à¤¯à¤¾à¤¤ फकà¥à¤¤ रिकà¥à¤¤ जागा समाविषà¥à¤Ÿà¥€à¤¤ होते)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "उप कारà¥à¤¯ पासून वाचतेवेळी तà¥à¤°à¥‚टी आढळली (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"उप कारà¥à¤¯ (%s) पासून माहिती वाचतेवेळी select() मधà¥à¤¯à¥‡ अपरिचीत तà¥à¤°à¥‚टी आढळली" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() (%s) मधà¥à¤¯à¥‡ अपरिचीत तà¥à¤°à¥‚टी आढळली" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "कोड %ld सह चाइलà¥à¤¡ पà¥à¤°à¥‹à¤¸à¥‡à¤¸à¥ बंद à¤à¤¾à¤²à¥€" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "सिगà¥à¤¨à¤² %ld तरà¥à¤«à¥‡ चाइलà¥à¤¡ पà¥à¤°à¥‹à¤¸à¥‡à¤¸ नषà¥à¤Ÿ à¤à¤¾à¤²à¥€" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "सिगà¥à¤¨à¤² %ld तरà¥à¤«à¥‡ चाइलà¥à¤¡ पà¥à¤°à¥‹à¤¸à¥‡à¤¸ बंद à¤à¤¾à¤²à¥€" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "चाइलà¥à¤¡ पà¥à¤°à¥‹à¤¸à¥‡à¤¸à¥ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ बंद à¤à¤¾à¤²à¥‡" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "उप कारà¥à¤¯ (%s) पासून वाचतेवेळी तà¥à¤°à¥‚टी" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) विभाजीत करणà¥à¤¯à¤¾à¤¸ अपयशी" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "'%s' संचयीकेत बदल करणà¥à¤¯à¤¾à¤¸ अपयशी (%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "उप कारà¥à¤¯ \"%s\" कारà¥à¤¯à¤¾à¤¨à¥à¤µà¥€à¤¤ करणà¥à¤¯à¤¾à¤¸ अपयशी (%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "उप कारà¥à¤¯ (%s) चे पà¥à¤°à¤¦à¤¾à¤¨ किंवा आगत परत पाठवू शकले नाही" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "उप कारà¥à¤¯ (%s) चे विभाजन करणà¥à¤¯à¤¾à¤¸ अपयशी" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "उप कारà¥à¤¯ \"%s\" कारà¥à¤¯à¤¾à¤¨à¥à¤µà¥€à¤¤ करतेवेळी तà¥à¤°à¥‚टी" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "उप pid पाईप (%s) पासून वाचतेवेळी तà¥à¤°à¥‚टी" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "उप कारà¥à¤¯ पासून माहिती वाचतेवेळी तà¥à¤°à¥‚टी" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "उप कारà¥à¤¯ पासून संभाषाणाकरीता पाईप बनविणà¥à¤¯à¤¾à¤¸ अपयशी (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "उप कारà¥à¤¯ (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¥€à¤¤ करतेवेळी तà¥à¤°à¥‚टी" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "अवैध कारà¥à¤¯à¤•à¥à¤°à¤® नाव: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%1$d वरील बाबी वेकà¥à¤Ÿà¤° मधà¥à¤¯à¥‡ अवैध अकà¥à¤·à¤°à¤®à¤¾à¤³à¤¾: %2$s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "वातावरणात अवैध अकà¥à¤·à¤°à¤®à¤¾à¤³à¤¾: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "अवैध कारà¥à¤¯à¤•à¥à¤·à¤® संचयीका: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "मदतीय कारà¥à¤¯à¤•à¥à¤°à¤® कारà¥à¤¯à¤¾à¤¨à¥à¤µà¥€à¤¤ करणà¥à¤¯à¤¾à¤¸ अपयशी (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"g_io_channel_win32_poll() मधà¥à¤¯à¥‡ उप कारà¥à¤¯ पासून माहिती वाचतवेली अपरिचीत तà¥à¤°à¥‚टी " +"आढळली" + +#: ../glib/gutf8.c:780 +#| msgid "failed to get memory" +msgid "Failed to allocate memory" +msgstr "मेमरिचे वाटप अपयशी" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 करीता अकà¥à¤·à¤° कà¥à¤·à¥‡à¤¤à¥à¤°à¤¾à¤šà¥à¤¯à¤¾ अंतरà¥à¤—त नाही" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "रूपांतर आगत मधà¥à¤¯à¥‡ अवैध शà¥à¤°à¥ƒà¤‚खला" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 करीता अकà¥à¤·à¤° कà¥à¤·à¥‡à¤¤à¥à¤°à¤¾à¤šà¥à¤¯à¤¾ अंतरà¥à¤—त नाही" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u बाइट" +msgstr[1] "%u बाइटसà¥" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s बाइट" +msgstr[1] "%s बाइटसà¥" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "जानेवारी" + +msgctxt "full month name with day" +msgid "February" +msgstr "फेबà¥à¤°à¥à¤µà¤¾à¤°à¥€" + +msgctxt "full month name with day" +msgid "March" +msgstr "मारà¥à¤š" + +msgctxt "full month name with day" +msgid "April" +msgstr "à¤à¤ªà¥à¤°à¤¿à¤²" + +msgctxt "full month name with day" +msgid "May" +msgstr "मे" + +msgctxt "full month name with day" +msgid "June" +msgstr "जून" + +msgctxt "full month name with day" +msgid "July" +msgstr "जà¥à¤²à¥ˆ" + +msgctxt "full month name with day" +msgid "August" +msgstr "ऑगसà¥à¤Ÿ" + +msgctxt "full month name with day" +msgid "September" +msgstr "सपà¥à¤Ÿà¥‡à¤‚बर" + +msgctxt "full month name with day" +msgid "October" +msgstr "ऑकà¥à¤Ÿà¥‹à¤¬à¤°" + +msgctxt "full month name with day" +msgid "November" +msgstr "नोवà¥à¤¹à¥‡à¤‚बर" + +msgctxt "full month name with day" +msgid "December" +msgstr "डिसेंबर" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "जाने" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "फेबà¥à¤°à¥" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "मारà¥à¤š" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "à¤à¤ªà¥à¤°à¤¿" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "मे" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "जून" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "जà¥à¤²à¥ˆ" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ऑग" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "सपà¥à¤Ÿà¥‡à¤‚" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "ऑकà¥à¤Ÿà¥‹" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "नोवà¥à¤¹à¥‡à¤‚" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "डिसें" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "xmllint सह इंपà¥à¤Ÿ फाइलचे विशà¥à¤²à¥‡à¤·à¤£ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata सह इंपà¥à¤Ÿ फाइलचे विशà¥à¤²à¥‡à¤·à¤£ करतेवेळी तà¥à¤°à¥à¤Ÿà¥€:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "सà¥à¤¥à¤¾à¤—ीत तà¥à¤°à¥à¤Ÿà¥€ पà¥à¤°à¤¾à¤ªà¥à¤¤ करणे अशकà¥à¤¯: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "लिहणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ '%s' फाइल उघडणà¥à¤¯à¤¾à¤¸ अपयशी: fdopen() अपयशी: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "'%s' फाइलवर लिहणà¥à¤¯à¤¾à¤¸ अपयशी: fflush() अपयशी: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "'%s' फाइल बंद करणà¥à¤¯à¤¾à¤¸ अपयशी: fclose() अपयशी: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "'%s' करीता अपà¥à¤°à¥‡ डाटा पà¥à¤°à¤¾à¤ªà¥à¤¤ à¤à¤¾à¤²à¥‡" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "सॉकेटकरीता SO_PASSCRED सà¥à¤°à¥‚ असलà¥à¤¯à¤¾à¤šà¥€ तपासणी करतेवेळी अनपेकà¥à¤·à¥€à¤¤ परà¥à¤¯à¤¾à¤¯ लांबी आढळली. " +#~ "%d बाइटसॠअपेकà¥à¤·à¥€à¤¤, %d पà¥à¤°à¤¾à¤ªà¥à¤¤" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "आदेश ओळ '%s': %s सà¥à¤ªà¥…नकरतेवेळी अयोगà¥à¤¯ पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® टरà¥à¤®à¤¿à¤¨à¥‡à¤¶à¤¨" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "आदेश ओळ '%s' नॉन-à¤à¤¿à¤°à¥‹ à¤à¤•à¥à¤œà¤¿à¤Ÿ सà¥à¤Ÿà¥‡à¤Ÿà¤¸ %d: %s सह बाहेर पडले" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' करीता सरà¥à¤µà¥à¤¹à¥€à¤¸ रेकॉरà¥à¤¡ आढळले नाही" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "कारà¥à¤¯à¤•à¥à¤·à¥‡à¤¤à¥à¤° सीमा रिकà¥à¤¤ उपअकà¥à¤·à¤°à¤“ळीकरीता पोहचले" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "case-changing escapes (\\l, \\L, \\u, \\U) चा वापर येथे शकà¥à¤¯ नाही" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE समà¥à¤¹à¤šà¥‡ पà¥à¤¨à¤ƒà¤•ृती करू शकत नाही" + +#~ msgid "File is empty" +#~ msgstr "फाइल रिकामी आहे" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "किलà¥à¤²à¥€ फाइल मधà¥à¤¯à¥‡ '%1$s' किलà¥à¤²à¥€ समाविषà¥à¤Ÿà¥€à¤¤ आहे जà¥à¤¯à¤¾à¤šà¥‡ मà¥à¤²à¥à¤¯ विशà¥à¤²à¥‡à¤·à¥€à¤¤ केलà¥à¤¯à¤¾ जाऊ शकत " +#~ "नाही." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "फाइल '%s' सà¥à¤°à¥‚ करतेवेळी तà¥à¤°à¥‚टी: %s" + +#~ msgid "Error connecting: " +#~ msgstr "जà¥à¤³à¤µà¤£à¥€à¤µà¥‡à¤³à¥€ तà¥à¤°à¥à¤Ÿà¥€: " + +#~ msgid "Error connecting: %s" +#~ msgstr "जà¥à¤³à¤µà¤£à¥€à¤µà¥‡à¤³à¥€ तà¥à¤°à¥à¤Ÿà¥€: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "unix पासून वाचतेवेळी तà¥à¤°à¥‚टी: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "unix बंद करतेवेळी तà¥à¤°à¥‚टी: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "unixकरीता लिहितेवेळी तà¥à¤°à¥‚टी: %s" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "संचयीकेवर संचयीका हलवू शकत नाही" diff --git a/po/ms.po b/po/ms.po new file mode 100644 index 0000000..df15e60 --- /dev/null +++ b/po/ms.po @@ -0,0 +1,6222 @@ +# glib Bahasa Melayu (ms) +# Jika takut risiko, Jangan bicara tentang Perjuangan +# Hasbullah Bin Pit (sebol) , 2002-2004 +# +msgid "" +msgstr "" +"Project-Id-Version: glib HEAD\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2020-01-10 14:33+0000\n" +"PO-Revision-Date: 2020-01-27 03:44+0800\n" +"Last-Translator: abuyop \n" +"Language-Team: Pasukan Terjemahan GNOME Malaysia\n" +"Language: ms\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 2.0.6\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Pilihan GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Tunjuk pilihan GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Masukkan mod perkhidmatan GApplication (guna dari fail perkhidmatan D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Batalkan ID aplikasi" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Ganti tika yang sedang berjalan" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:493 gio/gsettings-tool.c:567 +msgid "Print help" +msgstr "Cetak bantuan" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:494 gio/gresource-tool.c:562 +msgid "[COMMAND]" +msgstr "[PERINTAH]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Cetak versi" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:573 +msgid "Print version information and exit" +msgstr "Cetak maklumat versi dan keluar" + +#: gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Senarai aplikasi" + +#: gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "Senarai aplikasi boleh aktif D-Bus terpasang (mengikut fail .desktop)" + +#: gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "Lancar aplikasi" + +#: gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "Lancarkan aplikasi (dengan fail pilihan untuk dibuka)" + +#: gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "APPID [FAIL…]" + +#: gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "Aktifkan satu tindakan" + +#: gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "Seru satu tindakan pada aplikasi" + +#: gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Senarai tindakan yang tersedia" + +#: gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "Senarai tindakan statik untuk aplikasi (dari fail .desktop)" + +#: gio/gapplication-tool.c:65 gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMMAND" + +#: gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "Perintah untuk cetak bantuan terperinci" + +#: gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Pengecam aplikasi dalam format D-Bus (contohnya: org.example.viewer)" + +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:500 gio/gresource-tool.c:566 +msgid "FILE" +msgstr "FAIL" + +#: gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Nama fail relatif pilihan atau mutlak, atau URI yang hendak dibuka" + +#: gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "ACTION" + +#: gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "Nama tindakan yang diseru" + +#: gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Parameter pilihan ke penyeruan tindakan, dalam format GVariant" + +#: gio/gapplication-tool.c:96 gio/gresource-tool.c:531 gio/gsettings-tool.c:659 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Perintah %s tidak diketahui\n" +"\n" + +#: gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "Penggunaan:\n" + +#: gio/gapplication-tool.c:114 gio/gresource-tool.c:556 +#: gio/gsettings-tool.c:694 +msgid "Arguments:\n" +msgstr "Argumen:\n" + +#: gio/gapplication-tool.c:133 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS…]" + +#: gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Perintah:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Guna “%s help COMMAND†untuk dapatkan bantuan terperinci.\n" +"\n" + +#: gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"perintah %s memerlukan id aplikasi untuk diikuti secara terus\n" +"\n" + +#: gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "id aplikasi tidak sah: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:182 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†tidak mengambil argumen\n" +"\n" + +#: gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "tidak boleh sambung ke D-Bus: %s\n" + +#: gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "ralat menghantar mesej %s ke aplikasi: %s\n" + +#: gio/gapplication-tool.c:317 +msgid "action name must be given after application id\n" +msgstr "nama tindakan mesti diberi selepas id aplikasi\n" + +#: gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nama tindakan tidak sah: \"%s\"\n" +"nama tindakan mesti hanya mengandungi alfanumerik, \"-\" dan \".\"\n" + +#: gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "ralat menghurai parameter tindakan: %s\n" + +#: gio/gapplication-tool.c:356 +msgid "actions accept a maximum of one parameter\n" +msgstr "tindakan menerima semaksimum satu parameter\n" + +#: gio/gapplication-tool.c:411 +msgid "list-actions command takes only the application id" +msgstr "perintah list-actions hanya mengambil id aplikasi" + +#: gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "tidak boleh cari fail atas meja untuk aplikasi %s\n" + +#: gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"perintah tidak dikenali: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Niai kiraan terlalu besar dilepasi ke %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Jangkau tidak disokong pada strim asas" + +#: gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Tidak dapat pangkas GBufferedInputStream" + +#: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Strim sudah ditutup" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Pangkas tidak disokong dalam strim asas" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1871 gio/gdbusprivate.c:1411 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operasi telah dibatalkan" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Objek tidak sah, tidak diawalkan" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Jujukan bait berbilang tidak lengkap dalam input" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Jarak tidak mencukupi dalam destinasi" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:447 glib/gconvert.c:877 +#: glib/giochannel.c:1564 glib/giochannel.c:1606 glib/giochannel.c:2453 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "Jujukan bait tidak sah dalam input pertukaran" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:455 glib/gconvert.c:791 +#: glib/giochannel.c:1571 glib/giochannel.c:2465 +#, c-format +msgid "Error during conversion: %s" +msgstr "Ralat ketika penukaran: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1138 +msgid "Cancellable initialization not supported" +msgstr "Pengawalan boleh batal tidak disokong" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:320 glib/giochannel.c:1392 +#, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Pertukaran dari set aksara \"%s\" ke \"%s\" tidak disokong" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:324 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Tidak dapat membuka penukar dari \"%s\" ke \"%s\"" + +#: gio/gcontenttype.c:452 +#, c-format +msgid "%s type" +msgstr "Jenis %s" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Jenis tidak diketahui" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "Jenis fail %s" + +#: gio/gcredentials.c:289 +msgid "GCredentials contains invalid data" +msgstr "GCredentials mengandungi data tidak sah" + +#: gio/gcredentials.c:345 gio/gcredentials.c:609 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials tidak dilaksana pada OS ini" + +#: gio/gcredentials.c:503 +msgid "There is no GCredentials support for your platform" +msgstr "Tidak terdapat sokongan GCredentials untuk platform anda" + +#: gio/gcredentials.c:552 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials tidak mengandungi ID proses dalam OS ini" + +#: gio/gcredentials.c:603 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Pendayaan kelayakan tidak mungkin pada OS ini" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Penamatan-strim awal tidak dijangka" + +#: gio/gdbusaddress.c:158 gio/gdbusaddress.c:232 gio/gdbusaddress.c:321 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Kunci \"%s\" tidak disokong dalam masukan alamat \"%s\"" + +#: gio/gdbusaddress.c:171 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" +"Gabungan pasangan kunci/nilai tidak bermakna dalam masukan alamat \"%s\"" + +#: gio/gdbusaddress.c:180 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Alamat \"%s\" tidak sah (perlu sekurang-kurangnya satu laluan, dir, tmpdir, " +"atau kunci abstrak)" + +#: gio/gdbusaddress.c:247 gio/gdbusaddress.c:258 gio/gdbusaddress.c:273 +#: gio/gdbusaddress.c:336 gio/gdbusaddress.c:347 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Ralat dalam alamat “%s†— atribut “%s†adalah cacat" + +#: gio/gdbusaddress.c:417 gio/gdbusaddress.c:681 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "" +"Angkutan \"%s\" tidak diketahui atau tidak disokong untuk alamat \"%s\"" + +#: gio/gdbusaddress.c:461 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Unsur alamat \"%s\" tidak mengandungi tanda titik bertindih (:)" + +#: gio/gdbusaddress.c:470 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Nama angkutan dalam unsur alamat \"%s\" tidak boleh kosong" + +#: gio/gdbusaddress.c:491 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Pasangan Kunci/Nilai %d, \"%s\", dalam unsur alamat \"%s\" tidak mengandungi " +"satu tanda sama dengan" + +#: gio/gdbusaddress.c:502 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Pasangan Kunci/Nilai %d, \"%s\", dalam unsur alamat \"%s\" mesti tidak " +"mempunyai satu kunci kosong" + +#: gio/gdbusaddress.c:516 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Ralat unescape kunci atau nilai dalam pasangan Kunci/Nilai %d, \"%s\", dalam " +"unsur alamat \"%s\"" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Ralat dalam alamat \"%s\"— angkutan unix memerlukan sekurang-kurangnya salah " +"satu kunci “path†atau “abstract†ditetapkan" + +#: gio/gdbusaddress.c:624 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Ralat dalam alamat \"%s\"— atribut hos hilang atau cacat" + +#: gio/gdbusaddress.c:638 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Ralat dalam alamat \"%s\"— atribut port hilang atau cacat" + +#: gio/gdbusaddress.c:652 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "Ralat dalam alamat \"%s\"— atribut noncefile hilang atau cacat" + +#: gio/gdbusaddress.c:673 +msgid "Error auto-launching: " +msgstr "Ralat auto-melancar: " + +#: gio/gdbusaddress.c:726 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Ralat membuka fail nonce “%sâ€: %s" + +#: gio/gdbusaddress.c:745 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Ralat membaca dari fail nonce “%sâ€: %s" + +#: gio/gdbusaddress.c:754 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Ralat membaca dari fail nonce \"%s\", dijangka 16 bait, dapat %d" + +#: gio/gdbusaddress.c:772 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Ralat menulis kandungan fail nonce \"%s\" ke strim:" + +#: gio/gdbusaddress.c:981 +msgid "The given address is empty" +msgstr "Alamat diberi adalah kosong" + +#: gio/gdbusaddress.c:1094 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Tidak dapat mewujudkan bas mesej bila setuid" + +#: gio/gdbusaddress.c:1101 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Tidak dapat mewujudkan bas mesej tanpa machine-id: " + +#: gio/gdbusaddress.c:1108 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Tidak dapat auto-lancar D-Bus tanpa X11 $DISPLAY" + +#: gio/gdbusaddress.c:1150 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Ralat membiakkan baris perintah \"%s\": " + +#: gio/gdbusaddress.c:1219 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Tidak dapat menentukan alamat bas sesi (tidak dilaksanakan untuk OS ini)" + +#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7180 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Tidak dapat menentukan alamat bas dari pembolehubah persekitaran " +"DBUS_STARTER_BUS_TYPE — nilai \"%s\" tidak diketahui" + +#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7189 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Tidak dapat menentukan alamat bas kerana pembolehubah persekitaran " +"DBUS_STARTER_BUS_TYPE tidak ditetapkan" + +#: gio/gdbusaddress.c:1376 +#, c-format +msgid "Unknown bus type %d" +msgstr "Jenis bus %d tidak diketahui" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Kekurangan kandungan dijangka cuba membaca satu baris" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Kekurangan dijangka bagi kandungan yang cuba (secara selamat) membaca satu " +"baris" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Menghabiskan semua mekanisma pengesahihan yang tersedia (dicuba: %s) " +"(tersedia: %s)" + +#: gio/gdbusauth.c:1167 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Dibatalkan melalui GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:264 +#, c-format +#| msgid "Error opening directory '%s': %s" +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Ralat ketika mendapatkan maklumat untuk direktori \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:276 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Keizinan pada direktori \"%s\" adalah cacat. Dijangka mod 0700, dapat 0%o" + +#: gio/gdbusauthmechanismsha1.c:301 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Ralat mencipta direktori “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:348 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Ralat membuka gelang kunci \"%s\" untuk membaca: " + +#: gio/gdbusauthmechanismsha1.c:371 gio/gdbusauthmechanismsha1.c:689 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Baris %d bagi gelang kunci pada \"%s\" dengan kandungan \"%s\" adalah cacat" + +#: gio/gdbusauthmechanismsha1.c:385 gio/gdbusauthmechanismsha1.c:703 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Token pertama baris %d bagi gelang kunci pada \"%s\" dengan kandungan \"%s\" " +"adalah cacat" + +#: gio/gdbusauthmechanismsha1.c:399 gio/gdbusauthmechanismsha1.c:717 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Token kedua baris %d bagi gelang kunci pada \"%s\" dengan kandungan \"%s\" " +"adalah cacat" + +#: gio/gdbusauthmechanismsha1.c:423 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Tidak dapat mencari kuki dengan id %d dalam gelang kunci pada \"%s\"" + +#: gio/gdbusauthmechanismsha1.c:505 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Ralat memadam fail kunci basi \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:537 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Ralat mencipta fail kunci \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:568 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Ralat menutup fail kunci (nyahpaut) \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:579 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Ralat menyahpaut fail kunci \"%s\": %s" + +#: gio/gdbusauthmechanismsha1.c:656 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Ralat membuka gelang kunci \"%s\" untuk menulis: " + +#: gio/gdbusauthmechanismsha1.c:852 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" +"(Selain itu, melepaskan kunci untuk \"%s\" juga mengalami kegagalan: %s) " + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2400 +msgid "The connection is closed" +msgstr "Sambungan telah ditutup" + +#: gio/gdbusconnection.c:1901 +msgid "Timeout was reached" +msgstr "Had masa tamat telah dicapai" + +#: gio/gdbusconnection.c:2522 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Bendera tidak disokong dihadapi ketika membina sambungan sisi-klien" + +#: gio/gdbusconnection.c:4151 gio/gdbusconnection.c:4498 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Tiada antara muka 'org.freedesktop.DBus.Properties' sebegitu pada objek di " +"laluan %s" + +#: gio/gdbusconnection.c:4293 +#, c-format +msgid "No such property “%sâ€" +msgstr "Tiada sifat \"%s\" sebegitu" + +#: gio/gdbusconnection.c:4305 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Sifat \"%s\" tidak boleh baca" + +#: gio/gdbusconnection.c:4316 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Sifat \"%s\" tidak boleh tulis" + +#: gio/gdbusconnection.c:4336 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Ralat menetapkan sifat \"%s\": Jenis dijangka \"%s\" tetapi dapat \"%s\"" + +#: gio/gdbusconnection.c:4441 gio/gdbusconnection.c:4649 +#: gio/gdbusconnection.c:6620 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Tiada antara muka \"%s\" sebegitu" + +#: gio/gdbusconnection.c:4867 gio/gdbusconnection.c:7129 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Tiada antara muka \"%s\" sebegitu pada objek di laluan %s" + +#: gio/gdbusconnection.c:4965 +#, c-format +msgid "No such method “%sâ€" +msgstr "Tiada kaedah \"%s\" sebegitu" + +#: gio/gdbusconnection.c:4996 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Jenis mesej, \"%s\", tidak sepadan dengan jenis dijangka \"%s\"" + +#: gio/gdbusconnection.c:5194 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Satu objek sudah dieksport untuk antara muka %s pada %s" + +#: gio/gdbusconnection.c:5420 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Tidak memperoleh sifat %s.%s" + +#: gio/gdbusconnection.c:5476 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Tidak boleh menetapkan sifat %s.%s" + +#: gio/gdbusconnection.c:5654 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Kaedah \"%s\" jenis '%s' dikembalikan, tetapi dijangka \"%s\"" + +#: gio/gdbusconnection.c:6731 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "" +"Kaedah \"%s\" pada antara muka \"%s\" dengan tanda tangan \"%s\" tidak wujud" + +#: gio/gdbusconnection.c:6852 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Satu subpepohon sudah dieksport untuk %s" + +#: gio/gdbusmessage.c:1255 +msgid "type is INVALID" +msgstr "jenis adalah INVALID" + +#: gio/gdbusmessage.c:1266 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Mesej METHOD_CALL: medan pengepala PATH atau MEMBER telah hilang" + +#: gio/gdbusmessage.c:1277 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Mesej METHOD_RETURN: medan pengepala REPLY_SERIAL telah hilang" + +#: gio/gdbusmessage.c:1289 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Mesej ERROR: medan pengepala REPLY_SERIAL atau ERROR_NAME telah hilang" + +#: gio/gdbusmessage.c:1302 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Mesej SIGNAL: medan pengepala PATH, INTERFACE atau MEMBER telah hilang" + +#: gio/gdbusmessage.c:1310 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Mesej SIGNAL: medan pengepala PATH menggunakan nilai simpanan /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1318 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Mesej SIGNAL: Medan pengepala INTERFACE menggunakan nilai simpanan org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Mahu membaca %lu bait tetapi hanya dapat %lu" +msgstr[1] "Mahu membaca %lu bait tetapi hanya dapat %lu" + +#: gio/gdbusmessage.c:1380 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Bait NOL dijangka selepas rentetan \"%s\" tetapi temui bait %d" + +#: gio/gdbusmessage.c:1399 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Rentetan UTF-8 sah dijangka tetapi temui bait tidak sah pada ofset bait %d " +"(panjang rentetan ialah %d). Rentetan UTF-8 yang sah sehingga titik adalah " +"\"%s\"" + +#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900 +msgid "Value nested too deeply" +msgstr "Nilai tersarang terlalu dalam" + +#: gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Nilai terhurai \"%s\" bukanlah satu laluan objek D-Bus yang sah" + +#: gio/gdbusmessage.c:1631 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Nilai terhurai \"%s\" bukanlah satu tanda tangan D-Bus yang sah" + +#: gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Tatasusunan yang panjangnya %u bait dihadapi. Panjang maksimum ialah 2<<26 " +"bait (64 MiB)." +msgstr[1] "" +"Tatasusunan yang panjangnya %u bait dihadapi. Panjang maksimum ialah 2<<26 " +"bait (64 MiB)." + +#: gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Hadapi tatasusunan jenis \"a%c\", dijangka mempunyai panjang berbilang %u " +"bait, tetapi temui %u bait panjangnya" + +#: gio/gdbusmessage.c:1884 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"Nilai terhurai \"%s\" bagi varian bukanlah satu tanda tangan D-Bus yang sah" + +#: gio/gdbusmessage.c:1925 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Ralat menyahsiri GVariant dengan rentetan jenis \"%s\" dari format wayar D-" +"Bus" + +#: gio/gdbusmessage.c:2110 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Nilai endian tidak sah. Dijangka 0x6c (“lâ€) atau 0x42 (“Bâ€) tetapi temui " +"nilai 0x%02x" + +#: gio/gdbusmessage.c:2123 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Versi protokol major tidak sah. Dijangka 1 tetapi temui %d" + +#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773 +msgid "Signature header found but is not of type signature" +msgstr "Pengepala tanda tangan ditemui tetapi bukan jenis tanda tangan" + +#: gio/gdbusmessage.c:2189 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Pengepala tanda tangan dengan tanda tangan \"%s\" ditemui tetapi badan mesej " +"adalah kosong" + +#: gio/gdbusmessage.c:2204 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Nilai terhurai \"%s\" bukanlah satu tanda tangan D-Bus yang sah (untuk badan)" + +#: gio/gdbusmessage.c:2236 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Tiada pengepala tanda tangan dalam mesej tetapi badan mesej ialah %u bait" +msgstr[1] "" +"Tiada pengepala tanda tangan dalam mesej tetapi badan mesej ialah %u bait" + +#: gio/gdbusmessage.c:2246 +msgid "Cannot deserialize message: " +msgstr "Tidak dapat nyahsirikan mesej: " + +#: gio/gdbusmessage.c:2590 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Ralat menyahsiri GVariant dengan rentetan jenis \"%s\" ke format wayar D-Bus" + +#: gio/gdbusmessage.c:2727 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Bilangan penerang fail dalam mesej (%d) berbeza dari medan pengepala (%d)" + +#: gio/gdbusmessage.c:2735 +msgid "Cannot serialize message: " +msgstr "Tidak dapat sirikan mesej: " + +#: gio/gdbusmessage.c:2788 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Badan mesej mempunyai tanda tangan \"%s\" tetapi tiada pengepala tanda tangan" + +#: gio/gdbusmessage.c:2798 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Badan mesej mempunyai tanda tangan jenis \"%s\" tetapi tanda tangan dalam " +"medan pengepala ialah \"%s\"" + +#: gio/gdbusmessage.c:2814 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"Badan mesej adalah kosong tetapi tanda tangan dalam medan pengepala ialah " +"\"(%s)\"" + +#: gio/gdbusmessage.c:3367 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Ralat kembali dengan badan jenis \"%s\"" + +#: gio/gdbusmessage.c:3375 +msgid "Error return with empty body" +msgstr "Ralat kembali dengan badan kosong" + +#: gio/gdbusprivate.c:2242 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Taip apa-apa aksara untuk tutup tetingkap ini)\n" + +#: gio/gdbusprivate.c:2416 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Dbus sesi tidak dijalankan, dan auto-lancar mengalami kegagalan" + +#: gio/gdbusprivate.c:2439 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Tidak memperoleh profil Perkakasan: %s" + +#: gio/gdbusprivate.c:2484 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Tidak boleh memuatkan /var/lib/dbus/machine-id atau /etc/machine-id: " + +#: gio/gdbusproxy.c:1625 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Ralat memanggil StartServiceByName untuk %s: " + +#: gio/gdbusproxy.c:1648 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Balas tidak dijangka %d dari kaedah StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2748 gio/gdbusproxy.c:2883 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Tidak dapat menyeru kaedah; proksi ialah nama dikenali %s tanpa pemilik, dan " +"proksi telah dibina dengan bendera G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:755 +msgid "Abstract namespace not supported" +msgstr "Ruang nama abstrak tidak disokong" + +#: gio/gdbusserver.c:848 +msgid "Cannot specify nonce file when creating a server" +msgstr "Tidak dapat menyatakan fail nonce bila mencipta satu pelayan" + +#: gio/gdbusserver.c:930 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Ralat menulis fail nonce pada “%sâ€: %s" + +#: gio/gdbusserver.c:1103 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Rentetan “%s†bukanlah satu GUID D-Bus yang sah" + +#: gio/gdbusserver.c:1143 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Tidak dapat dengar pada angkutan \"%s\" yang tidak disokong" + +#: gio/gdbus-tool.c:107 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Perintah:\n" +" help Tunjuk maklumat ini\n" +" introspect Periksa satu objek jauh\n" +" monitor Pantau satu objek jauh\n" +" call Seru atau kaedah pada satu objek jauh\n" +" emit Pancarkan satu isyarat\n" +" wait Tunggu satu nama bas muncul\n" +"\n" +"Guna “%s COMMAND --help†untuk mendapatkan bantuan berkenaan setiap " +"perintah.\n" + +#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336 +#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:846 gio/gdbus-tool.c:1183 +#: gio/gdbus-tool.c:1668 +#, c-format +msgid "Error: %s\n" +msgstr "Ralat: %s\n" + +#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1684 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Ralat menghurai XML introspection: %s\n" + +#: gio/gdbus-tool.c:246 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Ralat: %s bukanlah nama yang sah\n" + +#: gio/gdbus-tool.c:394 +msgid "Connect to the system bus" +msgstr "Sambung ke bas sistem" + +#: gio/gdbus-tool.c:395 +msgid "Connect to the session bus" +msgstr "Sambung ke bas sesi" + +#: gio/gdbus-tool.c:396 +msgid "Connect to given D-Bus address" +msgstr "Sambung ke alamat D-Bus yang diberi" + +#: gio/gdbus-tool.c:406 +msgid "Connection Endpoint Options:" +msgstr "Pilihan Titi Akhir Sambungan:" + +#: gio/gdbus-tool.c:407 +msgid "Options specifying the connection endpoint" +msgstr "Pilihan menyatakan titik akhir sambungan" + +#: gio/gdbus-tool.c:429 +#, c-format +msgid "No connection endpoint specified" +msgstr "Tiada titik akhir sambungan dinyatakan" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Titik akhir sambungan berbilang dinyatakan" + +#: gio/gdbus-tool.c:509 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Amaran: Berdasarkan pada data introspection, antara muka \"%s\" tidak wujud\n" + +#: gio/gdbus-tool.c:518 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Amaran: Berdasarkan pada data introspection, kaedah \"%s\" tidak wujud pada " +"antara muka \"%s\"\n" + +#: gio/gdbus-tool.c:580 +msgid "Optional destination for signal (unique name)" +msgstr "Destinasi pilihan untuk isyarat (nama unik)" + +#: gio/gdbus-tool.c:581 +msgid "Object path to emit signal on" +msgstr "Laluan objek untuk pancarkan isyarat" + +#: gio/gdbus-tool.c:582 +msgid "Signal and interface name" +msgstr "Isyarat dan nama antara muka" + +#: gio/gdbus-tool.c:615 +msgid "Emit a signal." +msgstr "Pancarkan satu isyarat." + +#: gio/gdbus-tool.c:670 gio/gdbus-tool.c:977 gio/gdbus-tool.c:1771 +#: gio/gdbus-tool.c:2003 gio/gdbus-tool.c:2223 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Ralat menyambung: %s\n" + +#: gio/gdbus-tool.c:690 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Ralat: %s bukanlah nama bas unik yang sah.\n" + +#: gio/gdbus-tool.c:709 gio/gdbus-tool.c:1020 gio/gdbus-tool.c:1814 +msgid "Error: Object path is not specified\n" +msgstr "Ralat: Laluan objek tidak dinyatakan\n" + +#: gio/gdbus-tool.c:732 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1834 +#: gio/gdbus-tool.c:2074 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Ralat: %s bukanlah laluan objek yang sah\n" + +#: gio/gdbus-tool.c:752 +msgid "Error: Signal name is not specified\n" +msgstr "Ralat: Nama isyarat tidak dinyatakan\n" + +#: gio/gdbus-tool.c:766 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Ralat: Nama isyarat \"%s\" adalah tidak sah\n" + +#: gio/gdbus-tool.c:778 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Ralat: %s bukanlah nama antara muka yang sah\n" + +#: gio/gdbus-tool.c:784 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Ralat: %s bukanlah nama ahli yang sah\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:821 gio/gdbus-tool.c:1152 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Ralat menghurai parameter %d: %s\n" + +#: gio/gdbus-tool.c:853 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Ralat mengosongkan sambungan: %s\n" + +#: gio/gdbus-tool.c:880 +msgid "Destination name to invoke method on" +msgstr "Nama destinasi untuk menyeru kaedah" + +#: gio/gdbus-tool.c:881 +msgid "Object path to invoke method on" +msgstr "Laluan objek untuk menyeru kaedah" + +#: gio/gdbus-tool.c:882 +msgid "Method and interface name" +msgstr "Kaedah dan nama antara muka" + +#: gio/gdbus-tool.c:883 +msgid "Timeout in seconds" +msgstr "Had masa tamat dalam saat" + +#: gio/gdbus-tool.c:922 +msgid "Invoke a method on a remote object." +msgstr "Seru kaedah dalam objek jauh." + +#: gio/gdbus-tool.c:994 gio/gdbus-tool.c:1788 gio/gdbus-tool.c:2028 +msgid "Error: Destination is not specified\n" +msgstr "Ralat: Destinasi tidak dinyatakan\n" + +#: gio/gdbus-tool.c:1005 gio/gdbus-tool.c:1805 gio/gdbus-tool.c:2039 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Ralat: %s bukanlah nama bas yang sah\n" + +#: gio/gdbus-tool.c:1055 +msgid "Error: Method name is not specified\n" +msgstr "Ralat: Nama kaedah tidak dinyatakan\n" + +#: gio/gdbus-tool.c:1066 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Ralat: Nama kaedah \"%s\" adalah tidak sah\n" + +#: gio/gdbus-tool.c:1144 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Ralat menghurai parameter %d bagi jenis \"%s\": %s\n" + +#: gio/gdbus-tool.c:1630 +msgid "Destination name to introspect" +msgstr "Nama destinasi untuk diintrospect" + +#: gio/gdbus-tool.c:1631 +msgid "Object path to introspect" +msgstr "Laluan objek untuk diintrospect" + +#: gio/gdbus-tool.c:1632 +msgid "Print XML" +msgstr "Cetak XML" + +#: gio/gdbus-tool.c:1633 +msgid "Introspect children" +msgstr "Introspect anak" + +#: gio/gdbus-tool.c:1634 +msgid "Only print properties" +msgstr "Hanya cetak sifat" + +#: gio/gdbus-tool.c:1723 +msgid "Introspect a remote object." +msgstr "Introspect satu objek jauh." + +#: gio/gdbus-tool.c:1929 +msgid "Destination name to monitor" +msgstr "Nama destinasi untuk dipantau" + +#: gio/gdbus-tool.c:1930 +msgid "Object path to monitor" +msgstr "Laluan objek untuk dipantau" + +#: gio/gdbus-tool.c:1955 +msgid "Monitor a remote object." +msgstr "Pantau satu objek jauh." + +#: gio/gdbus-tool.c:2013 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Ralat: tidak dapat memantau satu sambungan bukan-bas-mesej\n" + +#: gio/gdbus-tool.c:2137 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" +"Perkhidmatan untuk diaktifkan sebelum menunggu yang lain (nama dikenali)" + +#: gio/gdbus-tool.c:2140 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Had masa tamat untuk menunggu sebelum keluar dengan satu ralat (saat); 0 " +"untuk tanpa had masa (lalai)" + +#: gio/gdbus-tool.c:2188 +msgid "[OPTION…] BUS-NAME" +msgstr "[PILIHAN…] NAMA-BAS" + +#: gio/gdbus-tool.c:2189 +msgid "Wait for a bus name to appear." +msgstr "Tunggu satu nama bas muncul." + +#: gio/gdbus-tool.c:2265 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Ralat: Satu perkhidmatan untuk diaktifkan mesti dinyatakan.\n" + +#: gio/gdbus-tool.c:2270 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Ralat: Satu perkhidmatan untuk menunggu mesti dinyatakan.\n" + +#: gio/gdbus-tool.c:2275 +msgid "Error: Too many arguments.\n" +msgstr "Ralat: Terlalu banyak argumen.\n" + +#: gio/gdbus-tool.c:2283 gio/gdbus-tool.c:2290 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Ralat: %s bukanlah satu nama bas unik yang dikenali.\n" + +#: gio/gdesktopappinfo.c:2072 gio/gdesktopappinfo.c:4870 +msgid "Unnamed" +msgstr "Tiada Nama" + +#: gio/gdesktopappinfo.c:2482 +msgid "Desktop file didn’t specify Exec field" +msgstr "Fail atas meja tidak menyatakan medan Exec" + +#: gio/gdesktopappinfo.c:2754 +msgid "Unable to find terminal required for application" +msgstr "Tidak dapat mencari terminal yang diperlukan untuk aplikasi" + +#: gio/gdesktopappinfo.c:3406 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Tidak dapat mencipta folder konfigurasi aplikasi pengguna %s: %s" + +#: gio/gdesktopappinfo.c:3410 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Tidak dapat mencipta folder konfigurasi MIME pengguna %s: %s" + +#: gio/gdesktopappinfo.c:3650 gio/gdesktopappinfo.c:3674 +msgid "Application information lacks an identifier" +msgstr "Maklumat aplikasi kekurangan satu pengecam" + +#: gio/gdesktopappinfo.c:3908 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Tidak dapat mencipta fail atas meja pengguna %s" + +#: gio/gdesktopappinfo.c:4042 +#, c-format +msgid "Custom definition for %s" +msgstr "Takrifan suai untuk %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "pemacu tidak melaksanakan lenting" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "pemacu tidak melaksanakan lenting atau eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "pemacu tidak melaksanakan peninjauan media" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "pemacu tidak melaksanakan mula" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "pemacu tidak melaksanakan henti" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:317 +#: gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "Sokongan TLS tidak tersedia" + +#: gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "Sokongan DTLS tidak tersedia" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Tidak dapat mengendalikan versi %d bagi pengekodan GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Bilangan token cacat (%d) dalam pengekodan GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Tidak dapat mengendalikan versi %d bagi pengekodan GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Bilangan token cacat (%d) dalam pengekodan GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Dijangka GEmblem untuk GEmblemedIcon" + +#: gio/gfile.c:1076 gio/gfile.c:1314 gio/gfile.c:1452 gio/gfile.c:1690 +#: gio/gfile.c:1745 gio/gfile.c:1803 gio/gfile.c:1887 gio/gfile.c:1944 +#: gio/gfile.c:2008 gio/gfile.c:2063 gio/gfile.c:3758 gio/gfile.c:3813 +#: gio/gfile.c:4091 gio/gfile.c:4559 gio/gfile.c:4970 gio/gfile.c:5055 +#: gio/gfile.c:5145 gio/gfile.c:5242 gio/gfile.c:5329 gio/gfile.c:5430 +#: gio/gfile.c:8134 gio/gfile.c:8224 gio/gfile.c:8308 +#: gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "Operasi tidak disokong" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1575 +msgid "Containing mount does not exist" +msgstr "Lekap terkandung yang tidak wujud" + +#: gio/gfile.c:2622 gio/glocalfile.c:2428 +msgid "Can’t copy over directory" +msgstr "Tidak dapat menyalin ke atas direktori" + +#: gio/gfile.c:2682 +msgid "Can’t copy directory over directory" +msgstr "Tidak dapat menyalin direktori ke atas direktori" + +#: gio/gfile.c:2690 +msgid "Target file exists" +msgstr "Fail sasaran sudah wujud" + +#: gio/gfile.c:2709 +msgid "Can’t recursively copy directory" +msgstr "Tidak dapat menyalin direktori secara rekursif" + +#: gio/gfile.c:2984 +msgid "Splice not supported" +msgstr "Splice tidak disokong" + +#: gio/gfile.c:2988 gio/gfile.c:3033 +#, c-format +msgid "Error splicing file: %s" +msgstr "Ralat menghiris fail: %s" + +#: gio/gfile.c:3149 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Salin (reflink/klon) antara lekap tidak disokong" + +#: gio/gfile.c:3153 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Salin (reflink/klon) tidak disokong atau tidak sah" + +#: gio/gfile.c:3158 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Salin (reflink/klon) tidak disokong atau tidak berfungsi" + +#: gio/gfile.c:3222 +msgid "Can’t copy special file" +msgstr "Tidak dapat menyalin fail khas" + +#: gio/gfile.c:4039 +msgid "Invalid symlink value given" +msgstr "Nilai pautan simbolik yang diberi tidak sah" + +#: gio/gfile.c:4049 glib/gfileutils.c:2172 +msgid "Symbolic links not supported" +msgstr "Pautan simbolik tidak disokong" + +#: gio/gfile.c:4200 +msgid "Trash not supported" +msgstr "Tong sampah tidak disokong" + +#: gio/gfile.c:4312 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Nama fail tidak boleh mengandungi \"%c\"" + +#: gio/gfile.c:6793 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "volum tidak melaksanakan lenting" + +#: gio/gfile.c:6904 gio/gfile.c:6950 +msgid "No application is registered as handling this file" +msgstr "Tiada aplikasi berdaftar sebagai pengendalian fail ini" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator tidak ditutup" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Enumerator fail mempunyai operasi tidak selesai" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Enumerator fail sudah pun ditutup" + +#: gio/gfileicon.c:236 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Tidak dapat mengendalikan versi %d bagi pengekodan GFileIcon" + +#: gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Data input cacat untuk GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Strim tidak menyokong query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Jangkau tidak disokong pada strim" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Pangkas tidak dibenarkan dalam strim input" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Pangkas tidak disokong dalam strim" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:595 +#: glib/gconvert.c:1777 +msgid "Invalid hostname" +msgstr "Nama hos tidak sah" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Balas proksi HTTP teruk" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Sambungan proksi HTTP tidak dibenarkan" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Pengesahihan proksi HTTP gagal" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Pengesahihan proksi HTTP diperlukan" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Sambungan proksi HTTP gagal: %i" + +#: gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Sambungan pelayan proksi HTTP ditutup tanpa jangka." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Bilangan token salah (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Tiada jenis bagi nama kelas %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Jenis %s tidak laksanakan antaramuka GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Jenis %s tidak dikelaskan" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Nombor versi cacat: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Jenis %s tidak dilaksana from_tokens() pada antaramuka GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Tidak dapat mengendalikan versi dibekal bagi pengekodan icon" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Tiada alamat dinyatakan" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Panjang %u terlalu panjang untuk alamat" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Alamat mempunyai set bit melangkaui panjang awalan" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Tidak dapat menghurai \"%s\" sebagai topeng alamat IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:220 +msgid "Not enough space for socket address" +msgstr "Ruang tidak mencukupi untuk alamat soket" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Alamat soket tidak disokong" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Strim input tidak melaksanakan baca" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Strim mempunyai operasi tidak selesai" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Salin dengan fail" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Kekalkan dengan fail bila dialihkan" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "\"version\" tidak mengambil argumen" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:864 +msgid "Usage:" +msgstr "Penggunaan:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Tunjuk maklumat versi kemudian keluar." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Perintah:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Pangkas fail dengan output piawai" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Salin satu atau lebih fail" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Tunjuk maklumat berkenaan lokasi" + +#: gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "Senarai kandungan lokasi" + +#: gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "Dapatkan atau tetapkan pengendali bagi jenis mime" + +#: gio/gio-tool.c:234 +msgid "Create directories" +msgstr "Cipta direktori" + +#: gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "Pantau fail dan direktori jika ada perubahan" + +#: gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "Lekap atau nyahlekap lokasi" + +#: gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "Alih satu atau lebih fail" + +#: gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "Buka fail dengan aplikasi lalai" + +#: gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "Namakan semula fail" + +#: gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "Padam satu atau lebih fail" + +#: gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "Baca dari input piawai dan simpan" + +#: gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "Tetapkan atribut fail" + +#: gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "Alih fail atau direktori ke dalam tong sampah" + +#: gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "Senarai kandungan lokasi dalam pepohon" + +#: gio/gio-tool.c:246 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Guna %s untuk dapatkan bantuan terperinci.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Ralat menulis ke stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:282 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOKASI" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Pangkas fail dan cetak ke output piawai." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat berfungsi seperti utiliti cat tradisional, tetapu menggunakan\n" +"lokasi GIO selain dari fail setempat: sebagai contoh, anda boleh gunakan\n" +"seperti smb://server/resource/file.txt sebagai lokasi." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:313 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 +msgid "No locations given" +msgstr "Tiada lokasi diberikan" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Bukan direktori sasaran" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Tunjuk kemajuan" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Maklumat sebelum tulis ganti" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Kekalkan semua atribut" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Sandar fail destinasi sedia ada" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Jangan ikut pautan simbolik" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Guna keizinan lalai untuk destinasi" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Memindahkan %s dari %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SUMBER" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINASI" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Salin satu atau lebih fail dari SUMBER ke DESTINASI." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy adalah serupa dengan utiliti cp tradisional, tetapi menggunakan\n" +"lokasi GIO selain dari fail setempat: sebagai contoh, anda boleh gunakan\n" +"sesuatu seperti smb://server/resource/file.txt sebagai lokasi." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Destinasi %s bukanlah satu direktori" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: tulis-ganti “%sâ€? " + +#: gio/gio-tool-info.c:34 +msgid "List writable attributes" +msgstr "Senaraikan atribut boleh tulis" + +#: gio/gio-tool-info.c:35 +msgid "Get file system info" +msgstr "Dapatkan maklumat sistem fail" + +#: gio/gio-tool-info.c:36 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Atribut untuk diperolehi" + +#: gio/gio-tool-info.c:36 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUT" + +#: gio/gio-tool-info.c:37 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Jangan ikuti pautan simbolik" + +#: gio/gio-tool-info.c:75 +msgid "attributes:\n" +msgstr "atribut:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "nama paparan: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "nama sunting: %s\n" + +#: gio/gio-tool-info.c:138 +#, c-format +msgid "name: %s\n" +msgstr "nama: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "jenis: %s\n" + +#: gio/gio-tool-info.c:151 +msgid "size: " +msgstr "saiz: " + +#: gio/gio-tool-info.c:156 +msgid "hidden\n" +msgstr "tersembunyi\n" + +#: gio/gio-tool-info.c:159 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:228 +msgid "Settable attributes:\n" +msgstr "Atribut boleh tetap:\n" + +#: gio/gio-tool-info.c:252 +msgid "Writable attribute namespaces:\n" +msgstr "Ruang nama atribut boleh tulis:\n" + +#: gio/gio-tool-info.c:287 +msgid "Show information about locations." +msgstr "Tunjuk maklumat berkenaan lokasi." + +#: gio/gio-tool-info.c:289 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info adalah serupa dengan utiliti ls tradisional, tetapi menggunakan\n" +"lokasi GIO selain dari fail setempat: contohnya, anda boleh guna sesuatu\n" +"seperti smb://server/resource/file.txt sebagai lokasi. Atribut fail boleh\n" +"dinyatakan dengan nama GIO mereka, spt. standard::icon, atau hanya\n" +"ruang nama, spt. unix, atau dengan “*â€, yang padankan semua atribut" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Tunjuk fail tersembunyi" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Guna format penyenaraian panjang" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Cetak nama paparan" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Cetak URI lengkap" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Senaraikan kandungan lokasi." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list adalah serupa dengan utiliti ls tradisional, tetapi menggunakan\n" +"lokasi GIO selain dari fail setempat: sebagai contoh, anda boleh guna\n" +"sesuatu seperti smb://server/resource/file.txt sebagai lokasi. Atribut\n" +"fail boleh dinyatakan dengan nama GIO mereka iaitu standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "JENISMIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "PENGENDALI" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Dapat atau tetapkan pengendali bagi jenis mime." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Jika tiada pengendali diberi, senarai berdaftar dan aplikasi disaran\n" +"untuk jenis mime. Jika pengendali diberi, maka ia ditetapkan sebagai\n" +"pengendali lalai untuk jenis mime." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Mesti nyatakan satu jenis mime, dan mungkin satu pengendali" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Tiada aplikasi lalai untuk \"%s\"\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplikasi lalai untuk “%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplikasi berdaftar:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Tiada aplikasi berdaftar\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplikasi saranan:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Tiada aplikasi saranan\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "Gagal memuatkan maklumat untuk pengendali \"%s\"" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Gagal menetapkan “%s†sebagai pengendali lalai untuk “%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Cipta direktori induk" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Cipta direktori." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir adalah serupa dengan utiliti mkdir tradisional, tetapi " +"menggunakan\n" +"lokasi GIO selain dari fail setempat: sebagai contoh, anda boleh gunakan\n" +"sesuatu seperti smb://server/resource/mydir sebgai lokasi." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Pantau satu direktori (lalai: bergantung pada jenis)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Pantau satu fail (lalai: bergantung pada jenis)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Pantau satu fail secara terus (perubahan berlaku melalui pautan keras)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Pantau satu fail secara terus (tidak melaporkan apa-apa perubahan)" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Laporkan pergerakan dan namakan semula sebagai peristiwa dipadam/dicipta " +"ringkas" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Pantau peristiwa lekap" + +#: gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "Pantau fail atau direktori jika ada perubahan." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Lekap sebagai boleh lekap" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Lekap volum dengan fail peranti, atau pengecam lain" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Nyahlekap" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Lenting" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Henti pemacu dengan fail peranti" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "PERANTI" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Nyahlekap semua lekap berdasarkan skema diberi" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SKEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Abai operasi fail belum selesai ketika menyahlekap atau melenting" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Guna seorang pengguna awanama ketika mengesahihkan" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Senarai" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Pantau peristiwa" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Tunjuk maklumat tambahan" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "PIM berangka ketika menyahkunci satu volum VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Lekap satu volum tersembunyi TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Lekap satu volum sistem TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Capaian awanama dinafikan" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Tiada pemacu untuk fail pemacu" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Tiada volum untuk ID diberi" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Lekap atau nyahlekap lokasi." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Jangan salin atau padam jatuh-balik" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Alih satu atau lebih fail dari SUMBER ke DEST." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move adalah serupa dengan utiliti mv tradisional, tetapi melalui GIO\n" +"lokasi GIO selain dari fail setempat: sebagai contoh, anda boleh gunakan\n" +"sesuatu seperti smb://server/resource/file.txt sebagai lokasi" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Sasaran %s bukanlah satu direktori" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Buka fail dengan aplikasi lalai yang terdaftar\n" +"untuk kendalikan fail jenis ini." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "Abai fail tidak wujud, jangan maklumkan" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Padam fail yang diberi." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAMA" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Namakan semula satu fail." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Argumen hilang" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Terlalu banyak argumen" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Namakan semula berjaya. Uri baharu: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Hanya cipta jika tidak wujud" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Tambah ke penghujung fail" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Bila mencipta, hadkan capaian ke pengguna semasa" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Bila digantikan, gantikan seolah-olah destinasi tidak wujud" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Cetak etag baharu dipenghujung" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "etag fail telah ditulis-ganti" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Ralat membaca dari input piawai" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag tidak tersedia\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Baca dari input piawai dan simpan ke DEST." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Tiada destinasi diberikan" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Jenis atribut" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "JENIS" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "NILAI" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Tetapkan atribut fail LOKASI." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Lokasi tidak dinyatakan" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atribut tidak dinyatakan" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Nilai tidak dinyatakan" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Jenis atribut \"%s\" tidak sah" + +#: gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "Kosongkan tong sampah" + +#: gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "Alih fail atau direktori ke dalam tong sampah." + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Ikuti pautan simbolik, lekap dan pintasan" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Senaraikan kandungan direktori dalam format seakan-pepohon." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Unsur <%s> tidak dibenarkan dalam <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Unsur <%s> tidak dibenarkan pada aras tertinggi" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Fail %s muncul berbilang kali dalam sumber" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Gagal mencari \"%s\" dalam mana-mana direktori sumber" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Gagal mencari \"%s\" dalam direktori semasa" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Pilihan pemprosesan \"%s\" tidak diketahui" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Pra-pemprosesan %s dipinta, tetapi %s tidak ditetapkan, dan %s tidak berada " +"dalam PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +#| msgid "Error reading file '%s': %s" +msgid "Error reading file %s: %s" +msgstr "Ralat membaca fail %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Ralat memampatkan fail %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "teks mungkin tidak muncul dalam <%s>" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Tunjuk versi program kemudian keluar" + +#: gio/glib-compile-resources.c:738 +msgid "Name of the output file" +msgstr "Nama bagi fail output" + +#: gio/glib-compile-resources.c:739 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Direktori untuk memuatkan fail dirujuk sari dalam FAIL (lala: direktori " +"semasa)" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIREKTORI" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Jana output dalam format terpilih berdasarkan sambungan nama fail sasaran" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "Jana pengepala sumber" + +#: gio/glib-compile-resources.c:742 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Jana kod sumber yang digunakan untuk dipautkan dalam fail sumber ke dalam " +"kod anda" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "Jana senarai dependensi" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "Nama bagi fail dependensi yang dijanakan" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "Sertakan sasaran foni dalam fail dependensi terjana" + +#: gio/glib-compile-resources.c:746 +msgid "Don’t automatically create and register resource" +msgstr "Jangan cipta dan daftar sumber secara automatik" + +#: gio/glib-compile-resources.c:747 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Jangan eksport fungsi; isytihar mereka sebagai G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Jangan benamkan data sumber dalam fail C; anggap ia terpaut secara luar" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "Nama pengecam C digunakan untuk kod sumber terjana" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompil satu spesifikasi sumber ke dalam fail sumber.\n" +"Fail spesifikasi sumber mempunyai sambungan .gresourse.xml,\n" +"dan fail sumber mempunyai sambungan dikenali sebagai .gresource." + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "Anda seharusnya berikan setepatnya satu nama fail\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "gelaran mesti minimum 2 aksara" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Nilai angka tidak sah" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " sudah dinyatakan" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' sudah dinyatakan" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "nilai bendera mesti mempunyai paling banyak 1 bit set" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> mesti mengandungi sekurang-kurangnya satu " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> tidak terkandung dalam julat yang dinyatakan" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> bukanlah satu ahli jenis terenumerasi dinyatakan yang sah" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" +"<%s> mengandungi rentetan yang tidak berada dalam jenis bendera yang " +"dinyatakan" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> mengandungi satu rentetan dalam " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " sudah dinyatakan untuk kunci ini" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " tidak dibenarkan untuk kunci jenis “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " dinyatakan minimum yang lebih besar dari maksimum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "kategori l10n tidak disokong: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n dipinta, tetapi tiada domain gettext diberikan" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "konteks terjemahan diberikan untuk nilai tanpa l10n dibenarkan" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Gagal menghurai nilai bagi jenis “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" tidak dapat dinyatakan untuk kunci-kunci bertag sebagai mempunyai " +"jenis terenumerasi" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " sudah dinyatakan untuk kunci ini" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " tidak dibenarkan utnuk kunci jenis “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " sudah diberikan" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " mesti mengandungi sekurang-kurangnya satu " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " sudah dinyatakan untuk kunci ini" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" hanya boleh dinyatakan untuk kunci berenumerasi atau jenis bendera " +"atau selepas " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" diberikan ketika “%s†sudah menjadi ahli bagi jenis " +"terenumerasi" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" diberikan ketika sudah pun diberikan" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " sudah dinyatakan" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "sasaran alias \"%s\" bukan jenis terenumerasi" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "Sasaran alias \"%s\" tidak berada di dalam " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " mesti mengandungi sekurang-kurangnya satu " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Nama kosong tidak dibenarkan" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" +"Nama \"%s\" tidak sah: nama mesti bermula dengan satu abjad berhuruf kecil" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nama \"%s\" tidak sah: aksara \"%c\" tidak sah; hanya abjad berhuruf kecil, " +"angka dan tanda sengkang (\"-\") dibenarkan" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Nama \"%s\" tidak sah: ada dua tanda sengkang (\"--\") tidak dibenarkan" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" +"Nama \"%s\" tidak sah: aksara terakhir tidak boleh dengan tanda sengkang (\"-" +"\")" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nama \"%s\" tidak sah: panjang maksimum ialah 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " sudah dinyatakan" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Tidak dapat tambah kunci pada satu skema \"list-of\"" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " sudah dinyatakan" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" bayang dalam ; guna " +" untuk mengubah suai nilai" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Sepatutnya salah satu dari “typeâ€, “enum†atau “flags†mesti dinyatakan " +"sebagai satu atribut pada " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> tidak (belum) ditakrif." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Rentetan jenis GVariant \"%s\" tidak sah" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " diberi tetapi skema tidak melanjutkan apa-apa" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Tiada untuk dibatalkan" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " sudah dinyatakan" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " sudah dinyatakan" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " lanjut tidak mengeluarkan skema “%s†sedia ada" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " ialah satu senarai, yang mana bukan skema \"%s\"" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Tidak dapat jadi satu senarai skema dengan satu laluan" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Tidak dapat lanjutkan satu skema dengan satu laluan" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ialah satu senarai, melanjutkan yang mana " +"bukan satu senarai" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" lanjutkan tetapi " +"“%s†tidak dilanjutkan “%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"Satu laluan, jika diberi, mesti bermula dan berakhir dengan satu tanda miring" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Laluan bagi satu senarai mesti berakhir dengan tanda \":/\"" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Amaran: Skema “%s†mempunyai laluan “%sâ€. Laluan bermula dengan “/apps/â€, “/" +"desktop/†atau “/system/†telah lapuk." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> sudah dinyatakan" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Hanya satu unsur <%s> dibenarkan dalam <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Unsur <%s> tidak dibenarkan pada aras tertinggi" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Unsur diperlukan dalam " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Teks mungkin tidak muncul dalam <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Amaran: rujukan tidak ditakrif pada " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict telah dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Keseluruhan fail ini telah diabaikan." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Mengabaikan fail ini." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Tiada kunci \"%s\" sebegitu dalam skema \"%s\" seperti dinyatakan dalam fail " +"pembatal \"%s\"; mengabaikan pembatal untuk kunci ini." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Tiada kunci \"%s\" sebegitu dalam skema \"%s\" seperti dinyatakan dalam fail " +"pembatal \"%s\" dan --strict telah dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Tidak dapat sediakan pembatal per-atas-meja untuk kunci tersetempat \"%s\" " +"dalam skema \"%s\" (batalkan fail \"%s\"); mengabaikan pembatal untuk kunci " +"ini." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Tidak dapat sediakan pembatal per-atas-meja untuk kunci tersetempat \"%s\" " +"dalam skema \"%s\" (batalkan fail \"%s\"); dan --strict telah dinyatakan; " +"keluar." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Ralat menghurai kunci \"%s\" dalam skema \"%s\" sebagai dinyatakan dalam " +"fail pembatal \"%s\": %s. Mengabaikan pembatal untuk kunci ini." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Ralat menghurai kunci \"%s\" dalam skema \"%s\" sebagai dinyatakan dalam " +"fail pembatal \"%s\": %s. --strict telah dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Pembatal bagi kunci \"%s\" dalam skema \"%s\" dalam fail pembatal \"%s\" " +"berada di luar julat yang diberi dalam skema; mengabaikan pembatal untuk " +"kunci ini." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Pembatal bagi kunci \"%s\" dalam skema \"%s\" dalam fail pembatal \"%s\" " +"berada di luar julat yang diberi dalam skema dan --strict telah dinyatakan; " +"keluar." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Pembatal bagi kunci \"%s\" dalam skema \"%s\" dalam fail pembatal \"%s\" " +"berada dalam senarai pilihan sah; mengabaikan pembatal untuk kunci ini." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Pembatal bagi kunci \"%s\" dalam skema \"%s\" dalam fail pembatal \"%s\" " +"berada dalam senarai pilihan sah dan --strict telah dinyatakan; keluar." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Lokasi untuk menyimpan fail gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Henti paksa pada mana-mana ralat dalam skema" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Jangan tulis fail gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Jangan paksa sekatan nama kunci" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompil semua fail skema GSettings menjadi cache skema.\n" +"Fail skema diperlukan untuk menghasilkan sambungan .gschema.xml,\n" +"dan fail cache dikenali sebagai gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Anda seharusnya berikan satu nama direktori" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Tiada fail skema ditemui: jangan buat apa-apa." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Tiada fail skema ditemui: buang fail output sedia ada." + +#: gio/glocalfile.c:546 gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "Nama fail %s tidak sah" + +#: gio/glocalfile.c:1013 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Ralat mendapatkan maklumat sistem fail bagi %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1152 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Lekap terkandung untuk fail %s tidak ditemui" + +#: gio/glocalfile.c:1175 +msgid "Can’t rename root directory" +msgstr "Tidak dapat menamakan semula direktori root" + +#: gio/glocalfile.c:1193 gio/glocalfile.c:1216 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Ralat menamakan semula fail %s: %s" + +#: gio/glocalfile.c:1200 +msgid "Can’t rename file, filename already exists" +msgstr "Tidak dapat menamakan semula fail, nama fail sudah wujud" + +#: gio/glocalfile.c:1213 gio/glocalfile.c:2322 gio/glocalfile.c:2350 +#: gio/glocalfile.c:2489 gio/glocalfileoutputstream.c:647 +msgid "Invalid filename" +msgstr "Nama fail tidak sah" + +#: gio/glocalfile.c:1381 gio/glocalfile.c:1396 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Ralat membuka fail %s: %s" + +#: gio/glocalfile.c:1521 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Ralat membuang fail %s: %s" + +#: gio/glocalfile.c:1963 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Ralat membuang fail %s ke dalam tong sampah: %s" + +#: gio/glocalfile.c:2004 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Tidak boleh mencipta dir tong sampah %s: %s" + +#: gio/glocalfile.c:2025 +#, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Unable to find toplevel directory to trash %s" +msgstr "Tidak boleh mencari direktori aras teratas ke dalam tong sampah %s" + +#: gio/glocalfile.c:2034 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Fungsi tong sampah pada lekap luar sistem tidak disokong" + +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 +#, c-format +msgid "Unable to find or create trash directory for %s" +msgstr "Tidak boleh mencari atau mencipta direktori tong sampah untuk %s" + +#: gio/glocalfile.c:2173 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Tidak boleh mencipta fail maklumat sampah untuk %s: %s" + +#: gio/glocalfile.c:2233 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Tidak boleh sampahkan fail %s yang merentasi sempadan sistem fail" + +#: gio/glocalfile.c:2237 gio/glocalfile.c:2293 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Tidak boleh sampahkan fail %s: %s" + +#: gio/glocalfile.c:2299 +#, c-format +msgid "Unable to trash file %s" +msgstr "Tidak boleh sampahkan fail %s" + +#: gio/glocalfile.c:2325 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Ralat mencipta direktori %s: %s" + +#: gio/glocalfile.c:2354 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Sistem fail tidak menyokong pautan simbolik" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Ralat membuat pautan simbolik %s: %s" + +#: gio/glocalfile.c:2400 gio/glocalfile.c:2435 gio/glocalfile.c:2492 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Ralat mengalih fail %s: %s" + +#: gio/glocalfile.c:2423 +msgid "Can’t move directory over directory" +msgstr "Tidak dapat mengalih direktori ke atas direktori" + +#: gio/glocalfile.c:2449 gio/glocalfileoutputstream.c:1031 +#: gio/glocalfileoutputstream.c:1045 gio/glocalfileoutputstream.c:1060 +#: gio/glocalfileoutputstream.c:1077 gio/glocalfileoutputstream.c:1091 +msgid "Backup file creation failed" +msgstr "Penciptaan fail sementara gagal" + +#: gio/glocalfile.c:2468 +#, c-format +msgid "Error removing target file: %s" +msgstr "Ralat membuang fail sasaran: %s" + +#: gio/glocalfile.c:2482 +msgid "Move between mounts not supported" +msgstr "Alih diantara lekap tidak disokong" + +#: gio/glocalfile.c:2673 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Tidak dapat tentukan penggunaan cakera bagi %s: %s" + +#: gio/glocalfileinfo.c:755 +msgid "Attribute value must be non-NULL" +msgstr "Nilai atribut mestilah bukan-NOL" + +#: gio/glocalfileinfo.c:762 +msgid "Invalid attribute type (string expected)" +msgstr "Jenis atribut tidak sah (rentetan dijangka)" + +#: gio/glocalfileinfo.c:769 +msgid "Invalid extended attribute name" +msgstr "Nama atribut lanjutan tidak sah" + +#: gio/glocalfileinfo.c:809 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Ralat menetapkan atribut terlanjut \"%s\": %s" + +#: gio/glocalfileinfo.c:1637 +msgid " (invalid encoding)" +msgstr " (pengekodan tidak sah)" + +#: gio/glocalfileinfo.c:1801 gio/glocalfileoutputstream.c:909 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Ralat mendapatkan maklumat untuk fail \"%s\": %s" + +#: gio/glocalfileinfo.c:2071 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Ralat mendapatkan maklumat untuk penerang fail: %s" + +#: gio/glocalfileinfo.c:2116 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Jenis atribut tidak sah (uint32 dijangka)" + +#: gio/glocalfileinfo.c:2134 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Jenis atribut tidak sah (dijangka uint64)" + +#: gio/glocalfileinfo.c:2153 gio/glocalfileinfo.c:2172 +msgid "Invalid attribute type (byte string expected)" +msgstr "Jenis atribut tidak sah (rentetan bait dijangka)" + +#: gio/glocalfileinfo.c:2219 +msgid "Cannot set permissions on symlinks" +msgstr "Tidak dapat tetapkan keizinan pada pautan simbolik" + +#: gio/glocalfileinfo.c:2235 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Ralat menetapkan keizinan: %s" + +#: gio/glocalfileinfo.c:2286 +#, c-format +msgid "Error setting owner: %s" +msgstr "Ralat menetapkan pemilik: %s" + +#: gio/glocalfileinfo.c:2309 +msgid "symlink must be non-NULL" +msgstr "pautan simbolik mestilah bukan-NOL" + +#: gio/glocalfileinfo.c:2319 gio/glocalfileinfo.c:2338 +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Ralat menetapkan pautan simbolik: %s" + +#: gio/glocalfileinfo.c:2328 +msgid "Error setting symlink: file is not a symlink" +msgstr "Ralat menetapkan pautan simbolik: fail bukan pautan simbolik" + +#: gio/glocalfileinfo.c:2454 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Ralat menetapkan pengubahsuaian atau masa capaian: %s" + +#: gio/glocalfileinfo.c:2477 +msgid "SELinux context must be non-NULL" +msgstr "Konteks SELinux mestilah bukan-NOL" + +#: gio/glocalfileinfo.c:2492 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Ralat menetapkan konteks SELinux: %s" + +#: gio/glocalfileinfo.c:2499 +msgid "SELinux is not enabled on this system" +msgstr "SELinux tidak dibenarkan dalam sistem ini" + +#: gio/glocalfileinfo.c:2591 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Penetapan atribut %s tidak disokong" + +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:792 +#, c-format +msgid "Error reading from file: %s" +msgstr "Ralat membaca dari fail: %s" + +#: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 +#: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 +#: gio/glocalfileoutputstream.c:554 gio/glocalfileoutputstream.c:1109 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Ralat menjangkau dalam fail: %s" + +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:344 +#: gio/glocalfileoutputstream.c:438 +#, c-format +msgid "Error closing file: %s" +msgstr "Ralat menutup fail: %s" + +#: gio/glocalfilemonitor.c:865 +msgid "Unable to find default local file monitor type" +msgstr "Tidak boleh mencari jenis pemantau fail setempat lalai" + +#: gio/glocalfileoutputstream.c:209 gio/glocalfileoutputstream.c:287 +#: gio/glocalfileoutputstream.c:324 gio/glocalfileoutputstream.c:813 +#, c-format +msgid "Error writing to file: %s" +msgstr "Ralat menulis ke fail: %s" + +#: gio/glocalfileoutputstream.c:371 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Ralat membuang pautan sandar lama: %s" + +#: gio/glocalfileoutputstream.c:385 gio/glocalfileoutputstream.c:398 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Ralat mencipta salinan sandar: %s" + +#: gio/glocalfileoutputstream.c:416 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Ralat menamakan semula fail sementara: %s" + +#: gio/glocalfileoutputstream.c:600 gio/glocalfileoutputstream.c:1160 +#, c-format +msgid "Error truncating file: %s" +msgstr "Ralat memangkas fail: %s" + +#: gio/glocalfileoutputstream.c:653 gio/glocalfileoutputstream.c:891 +#: gio/glocalfileoutputstream.c:1141 gio/gsubprocess.c:380 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Ralat membuka fail \"%s\": %s" + +#: gio/glocalfileoutputstream.c:922 +msgid "Target file is a directory" +msgstr "Fail sasaran adalah direktori" + +#: gio/glocalfileoutputstream.c:927 +msgid "Target file is not a regular file" +msgstr "Fail sasaran bukan satu fail nalar" + +#: gio/glocalfileoutputstream.c:939 +msgid "The file was externally modified" +msgstr "Fail telah diubah suai secara dalaman" + +#: gio/glocalfileoutputstream.c:1125 +#, c-format +msgid "Error removing old file: %s" +msgstr "Ralat membuang fail lama: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "GSeekType dibekalkan tidak sah" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Permintaan jangkau tidak sah" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Tidak dapat pangkas GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Strim output ingatan tidak boleh disaizkan semula" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Gagal saizkan semula strim output ingatan" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Amaun ingatan diperlukan untuk memproses tulis lebih besar dari ruang alamat " +"yang tersedia" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Jangkau dipinta sebelum permulaan strim" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Jangkau dipinta melangkaui penghujung strim" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "lekap tidak melaksanakan \"unmount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "lekap tidak melaksanakan \"eject\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "lekap tidak melaksanakan “unmount†atau “unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "lekap tidak melaksanakan “eject†atau “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "lekap tidak melaksanakan \"remount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "lekap tidak melaksanakan tekaan jenis kandungan" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "lekap tidak melaksanakan tekaan jenis kandungan segerak" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Nama hos \"%s\" mengandungi “[†tetapi bukan “]â€" + +#: gio/gnetworkmonitorbase.c:211 gio/gnetworkmonitorbase.c:315 +msgid "Network unreachable" +msgstr "Rangkaian tidak boleh capai" + +#: gio/gnetworkmonitorbase.c:249 gio/gnetworkmonitorbase.c:279 +msgid "Host unreachable" +msgstr "Hos tidak boleh capai" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Tidak dapat mencipta pemantau rangkaian: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Tidak dapat mencipta pemantau rangkaian: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Tidak memperoleh status rangkaian: " + +#: gio/gnetworkmonitornm.c:348 +#, c-format +msgid "NetworkManager not running" +msgstr "Pengurus Rangkaian tidak dijalankan" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "Versi Pengurus Rangkaian terlalu tua" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Strim output tidak melaksanakan tulis" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Hasil tambah vektor yang terlepas ke %s terlalu besar" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Strim sumber sudah ditutup" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Ralat meleraikan \"%s\": %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:613 +#, c-format +msgid "%s not implemented" +msgstr "%s tidak dilaksanakan" + +#: gio/gresolver.c:981 gio/gresolver.c:1033 +#| msgid "Invalid hostname" +msgid "Invalid domain" +msgstr "Domain tidak sah" + +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Sumber pada \"%s\" tidak wujud" + +#: gio/gresource.c:830 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Sumber pada \"%s\" gagal dinyahmampatkan" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Sumber pada \"%s\" bukan satu direktori" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Strim input tidak melaksanakan jangkau" + +#: gio/gresource-tool.c:499 +msgid "List sections containing resources in an elf FILE" +msgstr "Seksyen senarai mengandungi sumber dalam FILE elf" + +#: gio/gresource-tool.c:505 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Senaraikan sumber\n" +"Jika SECTION diberi, hanya senaraikan sumber dalam seksyen ini\n" +"Jika PATH diberi, hanya senaraikan sumber yang sepadan" + +#: gio/gresource-tool.c:508 gio/gresource-tool.c:518 +msgid "FILE [PATH]" +msgstr "FAIL [LALUAN]" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 gio/gresource-tool.c:526 +msgid "SECTION" +msgstr "SEKSYEN" + +#: gio/gresource-tool.c:514 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Senaraikan sumber dengan perincian\n" +"Jika SECTION diberi, hanya senaraikan sumber dalam seksyen ini\n" +"Jika PATH diberi, hanya senaraikan sumber yang sepadan\n" +"Perincian termasuklah seksyen, saiz dan pemampatan" + +#: gio/gresource-tool.c:524 +msgid "Extract a resource file to stdout" +msgstr "Ekstrak fail sumber ke stdout" + +#: gio/gresource-tool.c:525 +msgid "FILE PATH" +msgstr "FAIL LALUAN" + +#: gio/gresource-tool.c:539 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Penggunaan:\n" +" gresource [--section SEKSYAN] PERINTAH [ARG…]\n" +"\n" +"Perintah:\n" +" help Tunjuk maklumat ini\n" +" sections Senaraikan seksyen sumber\n" +" list Senaraikan sumber\n" +" details Senaraikan sumber secara terperinci\n" +" extract Ekstrak satu sumber\n" +"\n" +"Guna “gresource help PERINTAH†untuk bantuan lanjut.\n" +"\n" + +#: gio/gresource-tool.c:553 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Penggunaan:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:560 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION Satu nama seksyen elf (pilihan)\n" + +#: gio/gresource-tool.c:564 gio/gsettings-tool.c:701 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND Perintah (pilihan) yang dijelaskan\n" + +#: gio/gresource-tool.c:570 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE Satu fail elf (pustaka binari atau dikongsi)\n" + +#: gio/gresource-tool.c:573 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE Satu fail elf (pustaka binari atau dikongsi)\n" +" atau fail sumber dikompil\n" + +#: gio/gresource-tool.c:577 +msgid "[PATH]" +msgstr "[PATH]" + +#: gio/gresource-tool.c:579 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH Satu laluan sumber (pilihan) (boleh jadi separa)\n" + +#: gio/gresource-tool.c:580 +msgid "PATH" +msgstr "PATH" + +#: gio/gresource-tool.c:582 +msgid " PATH A resource path\n" +msgstr " PATH Satu laluan sumber\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:906 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Tiada skema \"%s\" sebegitu\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Skema \"%s\" tidak boleh alih (laluan tidak boleh dinyatakan)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Skema \"%s\" tidak boleh alih (laluan mesti dinyatakan)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Laluan kosong diberi.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Laluan mesti bermula dengan tanda miring (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Laluan mesti berakhir dengan tanda miring (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Laluan mesti tidak mengandungi dua tanda miring berturutan (//)\n" + +#: gio/gsettings-tool.c:536 +msgid "The provided value is outside of the valid range\n" +msgstr "Nilai disediakan berada luar julat yang sah\n" + +#: gio/gsettings-tool.c:543 +msgid "The key is not writable\n" +msgstr "Kunci tidak boleh ditulis-semula\n" + +#: gio/gsettings-tool.c:579 +msgid "List the installed (non-relocatable) schemas" +msgstr "Senarai skema (tidak-boleh-diletak-semula) terpasang" + +#: gio/gsettings-tool.c:585 +msgid "List the installed relocatable schemas" +msgstr "Senarai skema boleh letak semula terpasang" + +#: gio/gsettings-tool.c:591 +msgid "List the keys in SCHEMA" +msgstr "Senarai kunci dalam SCHEMA" + +#: gio/gsettings-tool.c:592 gio/gsettings-tool.c:598 gio/gsettings-tool.c:641 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:597 +msgid "List the children of SCHEMA" +msgstr "Senarai anak SCHEMA" + +#: gio/gsettings-tool.c:603 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Senarai kunci dan nilai, secara rekursif\n" +"Jika tiada SCHEMA diberi, senaraikan semua kunci\n" + +#: gio/gsettings-tool.c:605 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:610 +msgid "Get the value of KEY" +msgstr "Dapatkan nilai KEY" + +#: gio/gsettings-tool.c:611 gio/gsettings-tool.c:617 gio/gsettings-tool.c:623 +#: gio/gsettings-tool.c:635 gio/gsettings-tool.c:647 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:616 +msgid "Query the range of valid values for KEY" +msgstr "Tanya julat nilai sah untuk KEY" + +#: gio/gsettings-tool.c:622 +msgid "Query the description for KEY" +msgstr "Menanya keterangan bagi KEY" + +#: gio/gsettings-tool.c:628 +msgid "Set the value of KEY to VALUE" +msgstr "Tetapkan nilai KEY ke VALUE" + +#: gio/gsettings-tool.c:629 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:634 +msgid "Reset KEY to its default value" +msgstr "Tetap semula KEY ke nilai lalainya" + +#: gio/gsettings-tool.c:640 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Tetap semula semua kunci dalam SCHEMA ke lalai mereka" + +#: gio/gsettings-tool.c:646 +msgid "Check if KEY is writable" +msgstr "Periksa jika KEY boleh ditulis" + +#: gio/gsettings-tool.c:652 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Pantau KEY jika ada perubahan.\n" +"Jika tiada KEY dinyatakan, pantau semua kunci di dalam SCHEMA.\n" +"Guna ^C untuk hentikan pemantauan.\n" + +#: gio/gsettings-tool.c:655 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: gio/gsettings-tool.c:667 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Penggunaan:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Perintah:\n" +" help Tunjuk maklumat ini\n" +" list-schemas Senarai skema terpasang\n" +" list-relocatable-schemas Senarai skema boleh alih\n" +" list-keys Senarai kunci dalam satu skema\n" +" list-children Senarai anak satu skema\n" +" list-recursively Senarai kunci dan nilai, secara rekursif\n" +" range Tanya julat satu kunci\n" +" describe Tanya keterangan satu kunci\n" +" get Dapatkan nilai satu kunci\n" +" set Tetapkan nilai satu kunci\n" +" reset Tetap semula nilai satu kunci\n" +" reset-recursively Tetap semula semua nilai dalam skema yang " +"diberi\n" +" writable Periksa jika satu kunci boleh tulis\n" +" monitor Pantau jika ada perubahan\n" +"\n" +"Guna “gsettings help COMMAND†untuk perincian bantuan.\n" +"\n" + +#: gio/gsettings-tool.c:691 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:697 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR Satu direktori untuk gelintar skema tambahan\n" + +#: gio/gsettings-tool.c:705 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA Nama bagi skema\n" +" PATH Lalaun, untuk skema boleh-diletak-semula\n" + +#: gio/gsettings-tool.c:710 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY Kunci (pilihan) dengan skema\n" + +#: gio/gsettings-tool.c:714 +msgid " KEY The key within the schema\n" +msgstr " KEY Kunci dengan skema\n" + +#: gio/gsettings-tool.c:718 +msgid " VALUE The value to set\n" +msgstr " VALUE Nilai yang ditetapkan\n" + +#: gio/gsettings-tool.c:773 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Tidak dapat muat skema dari %s: %s\n" + +#: gio/gsettings-tool.c:785 +msgid "No schemas installed\n" +msgstr "Tiada skema terpasang\n" + +#: gio/gsettings-tool.c:864 +msgid "Empty schema name given\n" +msgstr "Nama skema kosong diberikan\n" + +#: gio/gsettings-tool.c:919 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Tiada kunci \"%s\" sebegitu\n" + +#: gio/gsocket.c:418 +msgid "Invalid socket, not initialized" +msgstr "Soket tidak sah, tidak diawalkan" + +#: gio/gsocket.c:425 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Soket tidak sah, pengawalan gagal kerana: %s" + +#: gio/gsocket.c:433 +msgid "Socket is already closed" +msgstr "Soket sudah ditutup" + +#: gio/gsocket.c:448 gio/gsocket.c:3182 gio/gsocket.c:4399 gio/gsocket.c:4457 +msgid "Socket I/O timed out" +msgstr "I/O soket telah tamat masa" + +#: gio/gsocket.c:583 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "mencipta GSocket dari fd: %s" + +#: gio/gsocket.c:612 gio/gsocket.c:666 gio/gsocket.c:673 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Tidak boleh cipta soket: %s" + +#: gio/gsocket.c:666 +msgid "Unknown family was specified" +msgstr "Keluarga tidak diketahui telah dinyatakan" + +#: gio/gsocket.c:673 +msgid "Unknown protocol was specified" +msgstr "Protokol tidak diketahui telah dinyatakan" + +#: gio/gsocket.c:1164 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Tidak dapat guna operasi datagram pada soket bukan-datagram." + +#: gio/gsocket.c:1181 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Tidak dapat guna operasi datagram pada soket dengan had masa tamat " +"ditetapkan." + +#: gio/gsocket.c:1988 +#, c-format +msgid "could not get local address: %s" +msgstr "tidak memperoleh alamat setempat: %s" + +#: gio/gsocket.c:2034 +#, c-format +msgid "could not get remote address: %s" +msgstr "tidak dapat alamat jauh: %s" + +#: gio/gsocket.c:2100 +#, c-format +msgid "could not listen: %s" +msgstr "tidak dapat dengar: %s" + +#: gio/gsocket.c:2204 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Ralat mengikat ke alamat %s: %s" + +#: gio/gsocket.c:2380 gio/gsocket.c:2417 gio/gsocket.c:2527 gio/gsocket.c:2552 +#: gio/gsocket.c:2615 gio/gsocket.c:2673 gio/gsocket.c:2691 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Ralat menyertai kumpulan multisiar: %s" + +#: gio/gsocket.c:2381 gio/gsocket.c:2418 gio/gsocket.c:2528 gio/gsocket.c:2553 +#: gio/gsocket.c:2616 gio/gsocket.c:2674 gio/gsocket.c:2692 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Ralat meninggalkan kumpulan multisiar: %s" + +#: gio/gsocket.c:2382 +msgid "No support for source-specific multicast" +msgstr "Tiada sokongan untuk multisiar spesifik-sumber" + +#: gio/gsocket.c:2529 +msgid "Unsupported socket family" +msgstr "Keluarga soket tidak disokong" + +#: gio/gsocket.c:2554 +msgid "source-specific not an IPv4 address" +msgstr "source-specific bukanlah satu alamat IPv4" + +#: gio/gsocket.c:2578 +#, c-format +msgid "Interface name too long" +msgstr "Nama antara muka terlalu panjang" + +#: gio/gsocket.c:2591 gio/gsocket.c:2641 +#, c-format +msgid "Interface not found: %s" +msgstr "Antara muka tidak ditemui: %s" + +#: gio/gsocket.c:2617 +msgid "No support for IPv4 source-specific multicast" +msgstr "Tiada sokongan untuk multisiar spesifik-sumber IPv4" + +#: gio/gsocket.c:2675 +msgid "No support for IPv6 source-specific multicast" +msgstr "Tiada sokongan untuk multisiar spesifik-sumber IPv6" + +#: gio/gsocket.c:2884 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Ralat menerima sambungan: %s" + +#: gio/gsocket.c:3010 +msgid "Connection in progress" +msgstr "Sambungan masih berlangsung" + +#: gio/gsocket.c:3061 +msgid "Unable to get pending error: " +msgstr "Tidak memperoleh ralat tertangguh: " + +#: gio/gsocket.c:3247 +#, c-format +msgid "Error receiving data: %s" +msgstr "Ralat menerima data: %s" + +#: gio/gsocket.c:3444 +#, c-format +msgid "Error sending data: %s" +msgstr "Ralat menghantar data: %s" + +#: gio/gsocket.c:3631 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Tidak boleh mematikan soket: %s" + +#: gio/gsocket.c:3712 +#, c-format +msgid "Error closing socket: %s" +msgstr "Ralat menutup soket: %s" + +#: gio/gsocket.c:4392 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Menunggu keadaan soket: %s" + +#: gio/gsocket.c:4770 gio/gsocket.c:4772 gio/gsocket.c:4919 gio/gsocket.c:5004 +#: gio/gsocket.c:5182 gio/gsocket.c:5222 gio/gsocket.c:5224 +#, c-format +msgid "Error sending message: %s" +msgstr "Ralat menghantar mesej: %s" + +#: gio/gsocket.c:4946 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage tidak disokong dalam Windows" + +#: gio/gsocket.c:5415 gio/gsocket.c:5488 gio/gsocket.c:5714 +#, c-format +msgid "Error receiving message: %s" +msgstr "Ralat menerima mesej: %s" + +#: gio/gsocket.c:5995 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Tidak boleh membaca kelayakan soket: %s" + +#: gio/gsocket.c:6004 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials tidak dilaksana untuk OS ini" + +#: gio/gsocketclient.c:182 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Tidak dapat sambung ke pelayan proksi %s: " + +#: gio/gsocketclient.c:196 +#, c-format +msgid "Could not connect to %s: " +msgstr "Tidak dapat bersambung ke %s: " + +#: gio/gsocketclient.c:198 +msgid "Could not connect: " +msgstr "Tidak dapat sambung: " + +#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1764 +msgid "Unknown error on connect" +msgstr "Ralat tidak diketahui ketika bersambung" + +#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1672 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Proksi terhadap sambungan bukan-TCP tidak disokong." + +#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Protokol proksi \"%s\" tidak disokong." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Pendengar sudah ditutup" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Soket ditambah telah tertutup" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 tidak menyokong alamat IPv6 “%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Nama pengguna terlalu panjang untuk protokol SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Nama hos \"%s\" terlalu panjang untuk protokol SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Pelayan bukanlah pelayan proksi SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Sambungan melalui pelayan SOCKSv4 telah ditolak" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:324 gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Pelayan bukanlah pelayan proksi SOCKSv5." + +#: gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Proksi SOCKSv5 memerlukan pengesahihan." + +#: gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Proksi SOCKSv5 memerlukan kaedah pengesahihan yang tidak disokong oleh GLib." + +#: gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Nama pengguna atau kata laluan terlalu panjang untuk protokol SOCKSv5." + +#: gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Pengesahihan SOCKSv5 gagal kerana nama pengguna dan kata laluan adalah salah." + +#: gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Nama hos \"%s\" terlalu panjang untuk protokol SOCKSv5" + +#: gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Pelayan proksi SOCKSv5 menggunakan jenis alamat tidak diketahui." + +#: gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Ralat pelayan proksi SOCKSv5 dalaman." + +#: gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Sambungan SOCKSv5 tidak dibenarkan oleh set peraturan." + +#: gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Hos tidak boleh dicapai melalui pelayan SOCKSv5." + +#: gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Rangkaian tidak boleh dicapai melalui proksi SOCKSv5." + +#: gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Sambungan dinafi melalui proksi SOCKSv5." + +#: gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Proksi SOCKSv5 tidak menyokong perintah \"connect\"." + +#: gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Proksi SOCKSv5 tidak menyokong jenis alamat yang disediakan." + +#: gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Ralat proksi SOCKSv5 tidak diketahui." + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Tidak dapat mengendalikan versi %d bagi pengekodan GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Tiada alamat yang sah ditemui" + +#: gio/gthreadedresolver.c:334 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Ralat melerai-songsang \"%s\": %s" + +#: gio/gthreadedresolver.c:671 gio/gthreadedresolver.c:750 +#: gio/gthreadedresolver.c:848 gio/gthreadedresolver.c:898 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Tiada rekod DNS bagi jenis dipinta untuk \"%s\"" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:853 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Tidak boleh lerai \"%s\" buat sementara" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#: gio/gthreadedresolver.c:968 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Ralat meleraikan \"%s\"" + +#: gio/gtlscertificate.c:298 +msgid "No PEM-encoded private key found" +msgstr "Tiada kunci persendirian terenkod-PEM ditemui" + +#: gio/gtlscertificate.c:308 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Tidak dapat menyahsulitkan kunci persendirian terenkod-PEM" + +#: gio/gtlscertificate.c:319 +msgid "Could not parse PEM-encoded private key" +msgstr "Tidak dapat menghuraikan kunci persendirian terenkod-PEM" + +#: gio/gtlscertificate.c:346 +msgid "No PEM-encoded certificate found" +msgstr "Tiada sijil terenkod-PEM ditemui" + +#: gio/gtlscertificate.c:355 +msgid "Could not parse PEM-encoded certificate" +msgstr "Tidak dapat menghurai sijil terenkod-PEM" + +#: gio/gtlscertificate.c:710 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "GTlsBackend ini tidak menyokong penciptaa sijil PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ini adalah peluang terakhir menginput kata laluan dengan betul sebelum " +"capaian anda terkunci." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Beberapa kata laluan dimasukkan adalah salah, dan capaian anda akan terkunci " +"selepas gagal beberapa kali." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Kata laluan yang dimasukkan adalah salah." + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Menjangkakan 1 mesej kawalan, dapat %d" +msgstr[1] "Menjangkakan 1 mesej kawalan, dapat %d" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "Jenis data sampingan tidak dijangka" + +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Menjangkakan satu fd, dapat %d\n" +msgstr[1] "Menjangkakan satu fd, dapat %d\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Terima fd tidak sah" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "Ralat menghantar kelayakan: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Ralat memeriksa jika SO_PASSCRED dibenarkan untuk soket: %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Ralat membenarkan SO_PASSCRED: %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Menjangkakan baca satu bait untuk kelayakan penerimaan tetapi baca sifar bait" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Tidak menjangkakan mesej kawalan, tetapi dapat %d" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Ralat ketika melumpuhkan SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:372 gio/gunixinputstream.c:393 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Ralat membaca dari penerang fail: %s" + +#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:535 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Ralat menutup penerang fail: %s" + +#: gio/gunixmounts.c:2664 gio/gunixmounts.c:2717 +msgid "Filesystem root" +msgstr "Root sistem fail" + +#: gio/gunixoutputstream.c:372 gio/gunixoutputstream.c:392 +#: gio/gunixoutputstream.c:479 gio/gunixoutputstream.c:499 +#: gio/gunixoutputstream.c:676 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Ralat menulis ke penerang fail: %s" + +#: gio/gunixsocketaddress.c:243 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Alamat soket domain UNIX abstrak tidak disokong pada sistem ini" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "volum tidak melaksanakan eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volum tidak melaksanakan eject atau eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Ralat membaca dari pemegang: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Ralat menutup pemegang: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Ralat menulis ke pemegang: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Ingatan tidak mencukupi" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Ralat dalaman: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Perlu lagi input" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Data termampat tidak sah" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Alamat didengarkan" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Diabaikan, untuk keserasian dengan GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Alamat cetak" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Cetak alamat dalam mod shell" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Jalankan satu perkhidmatan dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Arg salah\n" + +#: glib/gbookmarkfile.c:756 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Atribut tidak jangka \"%s\" untuk unsur \"%s\"" + +#: glib/gbookmarkfile.c:767 glib/gbookmarkfile.c:847 glib/gbookmarkfile.c:857 +#: glib/gbookmarkfile.c:969 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atribut \"%s\" bagi unsur \"%s\" tidak ditemui" + +#: glib/gbookmarkfile.c:1178 glib/gbookmarkfile.c:1243 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1317 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Tag \"%s\" tidak jangka, tag \"%s\" dijangka" + +#: glib/gbookmarkfile.c:1203 glib/gbookmarkfile.c:1217 +#: glib/gbookmarkfile.c:1285 glib/gbookmarkfile.c:1331 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Tag \"%s\" tidak jangka di dalam \"%s\"" + +#: glib/gbookmarkfile.c:1625 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Tarikh/waktu '%s' tidak sah dalam fail tanda buku" + +#: glib/gbookmarkfile.c:1831 +msgid "No valid bookmark file found in data dirs" +msgstr "Tiada fail tanda buku yang sah ditemui dalam dir data" + +#: glib/gbookmarkfile.c:2032 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Satu tanda buku untuk URI \"%s\" sudah wujud" + +#: glib/gbookmarkfile.c:2078 glib/gbookmarkfile.c:2236 +#: glib/gbookmarkfile.c:2321 glib/gbookmarkfile.c:2401 +#: glib/gbookmarkfile.c:2486 glib/gbookmarkfile.c:2569 +#: glib/gbookmarkfile.c:2647 glib/gbookmarkfile.c:2726 +#: glib/gbookmarkfile.c:2768 glib/gbookmarkfile.c:2865 +#: glib/gbookmarkfile.c:2986 glib/gbookmarkfile.c:3176 +#: glib/gbookmarkfile.c:3252 glib/gbookmarkfile.c:3420 +#: glib/gbookmarkfile.c:3509 glib/gbookmarkfile.c:3598 +#: glib/gbookmarkfile.c:3717 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Tiada tanda buku ditemui untuk URI \"%s\"" + +#: glib/gbookmarkfile.c:2410 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Tiada jenis MIME ditakrif dalam tanda buku bagi URI \"%s\"" + +#: glib/gbookmarkfile.c:2495 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" +"Tiada bendera persendirian telah ditakrif dalam tanda buku untuk URI \"%s\"" + +#: glib/gbookmarkfile.c:2874 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Tiada kumpulan ditetapkan dalam tanda buku untuk URI \"%s\"" + +#: glib/gbookmarkfile.c:3273 glib/gbookmarkfile.c:3430 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" +"Tiada aplikasi dengan nama \"%s\" daftarkan satu tanda buku untuk \"%s\"" + +#: glib/gbookmarkfile.c:3453 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Gagal kembangkan baris exec \"%s\" dengan URI \"%s\"" + +#: glib/gconvert.c:466 +#| msgid "Invalid sequence in conversion input" +msgid "Unrepresentable character in conversion input" +msgstr "Aksara tiada wakil dalam input pertukaran" + +#: glib/gconvert.c:493 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "Sebahagian turutan aksara berada di penghujung input" + +#: glib/gconvert.c:762 +#, c-format +#| msgid "Cannot convert fallback '%s' to codeset '%s'" +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Tidak dapat tukar jatuh-balik \"%s\" ke set kod \"%s\"" + +#: glib/gconvert.c:934 +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "Bait NOL terbenam dalam input pertukaran" + +#: glib/gconvert.c:955 +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "Bait NOL terbenam dalam output pertukaran" + +#: glib/gconvert.c:1640 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI '%s' adalah bukan URI mutlak menggunakan skema \"fail\"" + +#: glib/gconvert.c:1650 +#, c-format +#| msgid "The local file URI '%s' may not include a '#'" +msgid "The local file URI “%s†may not include a “#â€" +msgstr "URI Fail setempat \"%s\" mungkin tidak disertakan dengan \"#\"" + +#: glib/gconvert.c:1667 +#, c-format +#| msgid "The URI '%s' is invalid" +msgid "The URI “%s†is invalid" +msgstr "URI \"%s\" adalah tidak sah" + +#: glib/gconvert.c:1679 +#, c-format +#| msgid "The hostname of the URI '%s' is invalid" +msgid "The hostname of the URI “%s†is invalid" +msgstr "Nama hos bagi URI \"%s\" adalah tidak sah" + +#: glib/gconvert.c:1695 +#, c-format +#| msgid "The URI '%s' contains invalidly escaped characters" +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI \"%s\" mengandungi aksara escape yang tidak sah" + +#: glib/gconvert.c:1767 +#, c-format +#| msgid "The pathname '%s' is not an absolute path" +msgid "The pathname “%s†is not an absolute path" +msgstr "Nama laluan \"%s\" bukanlah laluan yang mutlak" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:220 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %b %e %H:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:223 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:268 +msgctxt "full month name" +msgid "January" +msgstr "Januari" + +#: glib/gdatetime.c:270 +msgctxt "full month name" +msgid "February" +msgstr "Februari" + +#: glib/gdatetime.c:272 +msgctxt "full month name" +msgid "March" +msgstr "Mac" + +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "May" +msgstr "Mei" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "June" +msgstr "Jun" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "July" +msgstr "Julai" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "August" +msgstr "Ogos" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "October" +msgstr "Oktober" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "December" +msgstr "Disember" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:322 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:324 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:326 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mac" + +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mei" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ogo" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dis" + +#: glib/gdatetime.c:359 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Isnin" + +#: glib/gdatetime.c:361 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Selasa" + +#: glib/gdatetime.c:363 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Rabu" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Khamis" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Jumaat" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sabtu" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Ahad" + +#: glib/gdatetime.c:386 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Isn" + +#: glib/gdatetime.c:388 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Sel" + +#: glib/gdatetime.c:390 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Rab" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Kha" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Jum" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sab" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Ahd" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:462 +#| msgctxt "full month name" +#| msgid "January" +msgctxt "full month name with day" +msgid "January" +msgstr "Januari" + +#: glib/gdatetime.c:464 +#| msgctxt "full month name" +#| msgid "February" +msgctxt "full month name with day" +msgid "February" +msgstr "Februari" + +#: glib/gdatetime.c:466 +#| msgctxt "full month name" +#| msgid "March" +msgctxt "full month name with day" +msgid "March" +msgstr "Mac" + +#: glib/gdatetime.c:468 +#| msgctxt "full month name" +#| msgid "April" +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:470 +#| msgctxt "full month name" +#| msgid "May" +msgctxt "full month name with day" +msgid "May" +msgstr "Mei" + +#: glib/gdatetime.c:472 +#| msgctxt "full month name" +#| msgid "June" +msgctxt "full month name with day" +msgid "June" +msgstr "Jun" + +#: glib/gdatetime.c:474 +#| msgctxt "full month name" +#| msgid "July" +msgctxt "full month name with day" +msgid "July" +msgstr "Julai" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "August" +msgstr "Ogos" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "October" +msgstr "Oktober" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "December" +msgstr "Disember" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:549 +#| msgctxt "abbreviated month name" +#| msgid "Jan" +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:551 +#| msgctxt "abbreviated month name" +#| msgid "Feb" +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:553 +#| msgctxt "abbreviated month name" +#| msgid "Mar" +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mac" + +#: glib/gdatetime.c:555 +#| msgctxt "abbreviated month name" +#| msgid "Apr" +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:557 +#| msgctxt "full month name" +#| msgid "May" +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mei" + +#: glib/gdatetime.c:559 +#| msgctxt "abbreviated month name" +#| msgid "Jun" +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:561 +#| msgctxt "abbreviated month name" +#| msgid "Jul" +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ogo" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Okt" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dis" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:588 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:591 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:154 +#, c-format +#| msgid "Error opening directory '%s': %s" +msgid "Error opening directory “%sâ€: %s" +msgstr "Ralat membuka direktori “%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +#| msgid "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Tidak dapat memperuntuk %lu bait untuk membaca fail \"%s\"" +msgstr[1] "Tidak dapat memperuntuk %lu bait untuk membaca fail \"%s\"" + +#: glib/gfileutils.c:750 +#, c-format +#| msgid "Error reading file '%s': %s" +msgid "Error reading file “%sâ€: %s" +msgstr "Ralat membaca fail \"%s\": %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Fail \"%s\" terlalu besar" + +#: glib/gfileutils.c:850 +#, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to read from file “%sâ€: %s" +msgstr "Gagal membaca daripada fail \"%s\": %s" + +#: glib/gfileutils.c:898 glib/gfileutils.c:970 +#, c-format +#| msgid "Failed to open file '%s': %s" +msgid "Failed to open file “%sâ€: %s" +msgstr "Gagal membuka fail \"%s\": %s" + +#: glib/gfileutils.c:910 +#, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Gagal mendapatkan atribut fail \"%s\": fstat() gagal: %s" + +#: glib/gfileutils.c:940 +#, c-format +#| msgid "Failed to open file '%s': fdopen() failed: %s" +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Gagal membuka fail \"%s\": fdopen() gagal: %s" + +#: glib/gfileutils.c:1039 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Gagal menamakan semula fail \"%s\" ke \"%s\": g_rename() gagal: %s" + +#: glib/gfileutils.c:1074 glib/gfileutils.c:1592 +#, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to create file “%sâ€: %s" +msgstr "Gagal mencipta fail \"%s\": %s" + +#: glib/gfileutils.c:1101 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Gagal menulis fail \"%s\": write() gagal: %s" + +#: glib/gfileutils.c:1144 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Gagal menulis fail \"%s\": fsync() gagal: %s" + +#: glib/gfileutils.c:1279 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Fail sedia ada \"%s\" tidak dapat dibuang: g_unlink() gagal: %s" + +#: glib/gfileutils.c:1558 +#, c-format +#| msgid "Template '%s' invalid, should not contain a '%s'" +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Templat \"%s\" tidak sah, sepatutnya tidak mengandungi \"%s\"" + +#: glib/gfileutils.c:1571 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Templat \"%s\" tidak mengandungi XXXXXX" + +#: glib/gfileutils.c:2129 glib/gfileutils.c:2157 +#, c-format +#| msgid "Failed to read the symbolic link '%s': %s" +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Gagal membaca pautan simbolik \"%s\": %s" + +#: glib/giochannel.c:1396 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Tidak dapat membuka penukar dari \"%s\" ke \"%s\": %s" + +#: glib/giochannel.c:1741 +#| msgid "Can't do a raw read in g_io_channel_read_line_string" +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Tidak dapat membaca rawak dalam g_io_channel_read_line_string" + +#: glib/giochannel.c:1788 glib/giochannel.c:2046 glib/giochannel.c:2133 +msgid "Leftover unconverted data in read buffer" +msgstr "Data tidak boleh ditukar Leftover dalam penimbal baca" + +#: glib/giochannel.c:1869 glib/giochannel.c:1946 +msgid "Channel terminates in a partial character" +msgstr "Saluran ditamatkan dalam satu aksara separa" + +#: glib/giochannel.c:1932 +#| msgid "Can't do a raw read in g_io_channel_read_to_end" +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Tidak dapat membuat bacaan rawak dalam g_io_channel_read_to_end" + +#: glib/gkeyfile.c:789 +msgid "Valid key file could not be found in search dirs" +msgstr "Fail kunci yang sah tidak ditemui dalam dir gelintar" + +#: glib/gkeyfile.c:826 +msgid "Not a regular file" +msgstr "Bukan satu fail nalar" + +#: glib/gkeyfile.c:1275 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Fail kunci mengandungi baris \"%s\" yang bukan pasangan kunci-nilai, " +"kumpulan, atau ulasan" + +#: glib/gkeyfile.c:1332 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nama kumpulan tidak sah: %s" + +#: glib/gkeyfile.c:1354 +msgid "Key file does not start with a group" +msgstr "Fail kunci tidak bermula dengan satu kumpulan" + +#: glib/gkeyfile.c:1380 +#, c-format +msgid "Invalid key name: %s" +msgstr "Nama kunci tidak sah: %s" + +#: glib/gkeyfile.c:1407 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Fail kunci mengandungi pengekodan \"%s\" yang tidak disokong" + +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3340 glib/gkeyfile.c:3470 glib/gkeyfile.c:3602 +#: glib/gkeyfile.c:3748 glib/gkeyfile.c:3977 glib/gkeyfile.c:4044 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Fail kunci tidak mempunyai kumpulan \"%s\"" + +#: glib/gkeyfile.c:1778 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Fail kunci tidak mempunyai kunci \"%s\" dalam kumpulan \"%s\"" + +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Fail kunci mengandungi kunci \"%s\" dengan nilai \"%s\" yang bukan UTF-8" + +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Fail kunci mengandungi kunci \"%s\" yang mempunyai satu nilai yang tidak " +"dapat ditafsirkan." + +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Fail kunci mengandungi kunci \"%s\" dalam kumpulan \"%s\" yang mempunyai " +"satu nilai yang tidak dapat ditafsirkan." + +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"Kunci \"%s\" dalam kumpulan \"%s\" mempunyai nilai \"%s\" yang mana %s telah " +"dijangka" + +#: glib/gkeyfile.c:4284 +msgid "Key file contains escape character at end of line" +msgstr "Fail kunci mengandungi aksara escape dipenghujung baris" + +#: glib/gkeyfile.c:4306 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Fail kunci mengandungi jujukan escaped \"%s\" yang tidak sah" + +#: glib/gkeyfile.c:4450 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Nilai \"%s\" tidak dapat ditafsir sebagai satu nombor." + +#: glib/gkeyfile.c:4464 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Nilai integer \"%s\" di luar julat" + +#: glib/gkeyfile.c:4497 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Nilai \"%s\" tidak dapat ditafsir sebagai satu angka apung." + +#: glib/gkeyfile.c:4536 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Nilai \"%s\" tidak dapat ditafsir sebagai satu boolean." + +#: glib/gmappedfile.c:129 +#, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Gagal mendapatkan atribut fail “%s%s%s%sâ€: fstat() gagal: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Gagal memetakan %s%s%s%s: mmap() gagal: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Gagal membuka fail \"%s\": open() gagal: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Ralat pada baris %d aksara %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Teks terenkod UTF-8 tidak dalam nama — \"%s\" tidak sah" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "\"%s\" bukanlah satu nama yang sah" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "\"%s\" bukanlah satu nama yang sah: \"%c\"" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Ralat pada baris %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Gagal menghurai \"%-.*s\", yang sepatutnya satu digit di dalam rujukan " +"aksara (ê sebagai contoh) — mungkin digit terlalu besar" + +#: glib/gmarkup.c:702 +#| msgid "" +#| "Character reference did not end with a semicolon; most likely you used an " +#| "ampersand character without intending to start an entity - escape " +#| "ampersand as &" +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Rujukan aksara tidak berakhir dengan satu titik bertindih; agaknya anda " +"menggunakan aksara ampersand tanpa niat untuk memulakan satu entiti - " +"escapekan ampersand sebagai &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Rujukan aksara \"%-*s\" tidak mengekodkan satu aksara yang diizinkan" + +#: glib/gmarkup.c:766 +#| msgid "" +#| "Empty entity '&;' seen; valid entities are: & " < > '" +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Entiti kosong \"&;\" kelihatan; entiti sah ialah : & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Nama entiti \"%-.*s\" tidak diketahui" + +#: glib/gmarkup.c:779 +#| msgid "" +#| "Entity did not end with a semicolon; most likely you used an ampersand " +#| "character without intending to start an entity - escape ampersand as &" +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entiti tidak berakhir dengan titik bertindih; mungkin anda gunakan aksara " +"ampersand tanpa menyedari untuk memulakan satu entiti - escape kan ampersand " +"sebagai &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumen mesti dimulakan dengan unsur (iaitu )" + +#: glib/gmarkup.c:1233 +#, c-format +#| msgid "" +#| "'%s' is not a valid character following a '<' character; it may not begin " +#| "an element name" +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"\"%s\" bukanlah satu aksara sah yang diikuti dengan aksara \"<\"; ia tidak " +"sepatutnya bermula dengan satu nama unsur" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Aksara ganjil \"%s\", dijangka satu aksara \">\" dipenghujung tag unsur-" +"kosong \"%s\"" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Terlalu banyak atribut dalam unsur \"%s\"" + +#: glib/gmarkup.c:1366 +#, c-format +#| msgid "" +#| "Odd character '%s', expected a '=' after attribute name '%s' of element " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Aksara ganjil \"%s\", jangkakan satu '=' selepas nama atribut \"%s\" bagi " +"unsur \"%s\"" + +#: glib/gmarkup.c:1408 +#, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' or '/' character to end the start tag " +#| "of element '%s', or optionally an attribute; perhaps you used an invalid " +#| "character in an attribute name" +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Aksara ganjil \"%s\", jangkakan satu aksara \">\" atau \"/\" di penghujung " +"tag permulaan unsur \"%s\", atau satu atribut secara pilihan; mungkin anda " +"telah menggunakan satu aksara tidak sah pada nama atribut" + +#: glib/gmarkup.c:1453 +#, c-format +#| msgid "" +#| "Odd character '%s', expected an open quote mark after the equals sign " +#| "when giving value for attribute '%s' of element '%s'" +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Aksara ganjil \"%s\", jangkakan satu tanda petikan membuka selepas tanda " +"sama dengan ketika memberi nilai atribut untuk \"%s\" bagi unsur \"%s\"" + +#: glib/gmarkup.c:1587 +#, c-format +#| msgid "" +#| "'%s' is not a valid character following the characters ''" +msgid "" +"“%s†is not a valid character following the close element name “%sâ€; the " +"allowed character is “>â€" +msgstr "" +"'%s' adalah bukan satu aksara yang sah diikuti dengan nama unsur penutup \"%s" +"\"; aksara yang diizinkan ialah \">\"" + +#: glib/gmarkup.c:1637 +#, c-format +#| msgid "Element '%s' was closed, no element is currently open" +msgid "Element “%s†was closed, no element is currently open" +msgstr "Unsur \"%s\" telah ditutup, tiada unsur terbuka buat masa ini" + +#: glib/gmarkup.c:1646 +#, c-format +#| msgid "Element '%s' was closed, but the currently open element is '%s'" +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"Unsur \"%s\" telah tertutup, tetapi unsur terbuka buat masa ini adalah \"%s\"" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumen kosong atau hanya menandungi ruang putih" + +#: glib/gmarkup.c:1813 +#| msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokumen berakhir tanpa jangka sebaik selepas membuka kurungan \"<\"" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +#| msgid "" +#| "Document ended unexpectedly with elements still open - '%s' was the last " +#| "element opened" +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokumen berakhir tanpa jangka dengan unsur masih terbuka — “%s†adalah unsur " +"terbuka yang terakhir" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokumen berakhir tanpa jangka, jangkakan dapat melihat satu kurungan " +"berakhir tag <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumen berakhir tanpa jangka dalam satu nama unsur" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumen berakhir tanpa jangka dalam satu nama atribut" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumen berakhir tanpa jangka dalam tag element-opening." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokumen berakhir tanpa jangka selepas tanda sama dengan diikuti dengan satu " +"nama atribut; tiada nilai atribut" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumen berakhir tanpa jangka ketika berada dalam satu nilai atribut" + +#: glib/gmarkup.c:1876 +#, c-format +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokumen berakhir tanpa jangka dalam tag tertutup untuk unsur \"%s\"" + +#: glib/gmarkup.c:1880 +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Dokumen berakhir tanpa jangka dalam tag tertutup untuk unsur tidak terbuka" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokumen berakhir tanpa jangka dalam satu ulasan atau memproses arahan" + +#: glib/goption.c:868 +msgid "[OPTION…]" +msgstr "[PILIHAN...]" + +#: glib/goption.c:984 +msgid "Help Options:" +msgstr "Pilihan Bantuan:" + +#: glib/goption.c:985 +msgid "Show help options" +msgstr "Tunjuk pilihan bantuan" + +#: glib/goption.c:991 +msgid "Show all help options" +msgstr "Tunjuk semua pilihan bantuan" + +#: glib/goption.c:1054 +msgid "Application Options:" +msgstr "Pilihan Aplikasi:" + +#: glib/goption.c:1056 +msgid "Options:" +msgstr "Pilihan:" + +#: glib/goption.c:1120 glib/goption.c:1190 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Tidak dapat menghurai nilai integer \"%s\" untuk %s" + +#: glib/goption.c:1130 glib/goption.c:1198 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Nilai interger \"%s\" untuk %s di luar julat" + +#: glib/goption.c:1155 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Tidak dapat menghurai nilai ganda dua \"%s\" untuk %s" + +#: glib/goption.c:1163 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Nilai ganda dua \"%s\" untuk %s di luar julat" + +#: glib/goption.c:1455 glib/goption.c:1534 +#, c-format +msgid "Error parsing option %s" +msgstr "Ralat menghurai pilihan %s" + +#: glib/goption.c:1565 glib/goption.c:1678 +#, c-format +msgid "Missing argument for %s" +msgstr "Argumen hilang bagi %s" + +#: glib/goption.c:2189 +#, c-format +msgid "Unknown option %s" +msgstr "Pilihan %s tidak diketahui" + +#: glib/gregex.c:257 +msgid "corrupted object" +msgstr "objek rosak" + +#: glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "ralat dalaman atau objek rosak" + +#: glib/gregex.c:261 +msgid "out of memory" +msgstr "kehabisan ingatan" + +#: glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "had patah balik telah dicapai" + +#: glib/gregex.c:278 glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "pola mengandungi item yang tidak disokong untuk pemadanan separa" + +#: glib/gregex.c:280 +msgid "internal error" +msgstr "ralat dalaman" + +#: glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "rujukan balik sebagai syarat tidak disokong untuk pemadanan separa" + +#: glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "had rekursi telah dicapai" + +#: glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "gabungan tidak sah bagi bendera baris baharu" + +#: glib/gregex.c:301 +msgid "bad offset" +msgstr "ofset teruk" + +#: glib/gregex.c:303 +msgid "short utf8" +msgstr "utf8 pendek" + +#: glib/gregex.c:305 +msgid "recursion loop" +msgstr "gelung rekursi" + +#: glib/gregex.c:309 +msgid "unknown error" +msgstr "ralat tidak diketahui" + +#: glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ dipenghujung pola" + +#: glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c dipenghujung pola" + +#: glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "aksara tidak dikenali diikuti dengan \\" + +#: glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "nombor diluar tertib dalam pembilang {}" + +#: glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "nombor terlalu besar dalam pembilang {}" + +#: glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "] penamat hilang bagi kelas aksara" + +#: glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "jujukan escape tidak sah dalam kelas aksara" + +#: glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "julat di luar tertib dalam kelas aksara" + +#: glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "tiada apa hendak diulang" + +#: glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "ulang tidak dijangka" + +#: glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "aksara tidak dikenali selepas (? atau (?-" + +#: glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "Kelas bernama POSIX disokong hanya dalam satu kelas" + +#: glib/gregex.c:366 +msgid "missing terminating )" +msgstr ") penamat hilang" + +#: glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "rujukan ke subpola tidak-wujud" + +#: glib/gregex.c:372 +msgid "missing ) after comment" +msgstr ") hilang selepas ulasan" + +#: glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "ungkapan nalar terlalu besar" + +#: glib/gregex.c:378 +msgid "failed to get memory" +msgstr "gagal mendapatkan ingatan" + +#: glib/gregex.c:382 +msgid ") without opening (" +msgstr ") tanpa membuka (" + +#: glib/gregex.c:386 +msgid "code overflow" +msgstr "kod melimpah" + +#: glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "aksara tidak dikenali selepas (?<" + +#: glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "penegasan lookbehind bukan panjang yang tetap" + +#: glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "nombor atau nama cacat selepas (?(" + +#: glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "kumpulan bersyarat mengandungi lebih dari dua cabang" + +#: glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "penegasan dijangka selepas (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R atau (?[+-]digit mesti diikuti dengan )" + +#: glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "nama kelas POSIX tidak diketahui" + +#: glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "Unsur pengumpulan-semak POSIX tidak disokong" + +#: glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "nilai aksara dalam jujukan \\x{...} terlalu besar" + +#: glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "syarat (?(0) tidak sah" + +#: glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C tidak dibenarkan dalam penegasan lookbehind" + +#: glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, dan \\u tidak disokong" + +#: glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "panggilan rekursif patut gelung secara tidak terbatas" + +#: glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "aksara tidak dikenali selepas (?P" + +#: glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "penamat hilang dalam nama sub-pola" + +#: glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "dua sub-pola bernama mempunyai nama yang serupa" + +#: glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "jujukan \\P atau \\p cacat" + +#: glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "nama sifat tidak diketahui selepas \\P atau \\p" + +#: glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "nama sub-pola terlalu panjang (maksimum 32 aksara)" + +#: glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "terlalu banyak sub-pola bernama (maksimum 10,000)" + +#: glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "nilai perlapanan lebih besar dari \\377" + +#: glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "lewati pengkompilan ruang kerja" + +#: glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "sub-pola dirujuk disemak-sebelum ini tidak ditemui" + +#: glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "Kumpulan DEFINE mengandungi lebih dari satu cabang" + +#: glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "pilihan NEWLINE tidak konsisten" + +#: glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g tidak diikuti dengan kurungan, kurungan-bersudut, atau nama atau nombor " +"petikan, atau dengan nombor biasa" + +#: glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "rujukan bernombor mestilah bukan sifar" + +#: glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "satu argumen tidak dibenarkan untuk (*ACCEPT), (*FAIL), atau (*COMMIT)" + +#: glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) tidak dikenali" + +#: glib/gregex.c:489 +msgid "number is too big" +msgstr "nombor terlalu besar" + +#: glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "nama sub-pola hilang selepas (?&" + +#: glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "digit dijangka selepas (?+" + +#: glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] adalah aksara data tidak sah dalam mod keserasian Skrip Java" + +#: glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "nama berbeza untuk sub-pola bagi nombor yang sama tidak dibenarkan" + +#: glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) mesti mempunyai argumen" + +#: glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c mesti diikuti dengan aksara ASCII" + +#: glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k tidak diikuti dengan kurungan, kurungan bersudut, atau nama petikan" + +#: glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "\\N tidak disokong dlaam kelas" + +#: glib/gregex.c:516 +msgid "too many forward references" +msgstr "terlalu banyak rujukan maju" + +#: glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "nama terlalu panjang dalam (*MARK), (*PRUNE), (*SKIP), atau (*THEN)" + +#: glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "nilai aksara dalam jujukan \\u.... terlalu besar" + +#: glib/gregex.c:745 glib/gregex.c:1983 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Ralat ketika memadankan ungkapan nalar %s: %s" + +#: glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Pustaka PCRE dikompil tanpa sokongan UTF8" + +#: glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Pustaka PCRE dikompil tanpa sokongan sifat UTF8" + +#: glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "Pustaka PCRE dikompil dengan pilihan tidak serasi" + +#: glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Ralat ketika mengoptimumkan ungkapan nalar %s: %s" + +#: glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Ralat ketika mengkompil ungkapan nalar %s pada aksarar %d: %s" + +#: glib/gregex.c:2419 +msgid "hexadecimal digit or “}†expected" +msgstr "digit heksadesimal atau \"}\" dijangka" + +#: glib/gregex.c:2435 +msgid "hexadecimal digit expected" +msgstr "digit heksadesimal dijangka" + +#: glib/gregex.c:2475 +msgid "missing “<†in symbolic reference" +msgstr "\"<\" hilang dalam rujukan simbolik" + +#: glib/gregex.c:2484 +msgid "unfinished symbolic reference" +msgstr "rujukan simbolik tidak selesai" + +#: glib/gregex.c:2491 +msgid "zero-length symbolic reference" +msgstr "rujukan simbolik panjang-sifar" + +#: glib/gregex.c:2502 +msgid "digit expected" +msgstr "digit dijangka" + +#: glib/gregex.c:2520 +msgid "illegal symbolic reference" +msgstr "rujukan simbolik tidak dibenarkan" + +#: glib/gregex.c:2583 +msgid "stray final “\\â€" +msgstr "muktamad \"/\" terbiar" + +#: glib/gregex.c:2587 +msgid "unknown escape sequence" +msgstr "jujukan escape tidak diketahui" + +#: glib/gregex.c:2597 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Ralat ketika menghurai teks pengganti \"%s\" pada aksara %lu: %s" + +#: glib/gshell.c:94 +#| msgid "Quoted text doesn't begin with a quotation mark" +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Teks dipetik tidak bermula dengan satu tanda baca" + +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Tanda petikan tidak sepadan pada arahan baris atau teks shell-quoted lain" + +#: glib/gshell.c:580 +#, c-format +#| msgid "Text ended just after a '\\' character. (The text was '%s')" +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Teks berakhir selepas satu aksara \"\\\". (Teks ialah \"%s\")" + +#: glib/gshell.c:587 +#, c-format +#| msgid "" +#| "Text ended before matching quote was found for %c. (The text was '%s')" +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Teks berakhir sebelum petikan sepadan ditemui untuk %c (Teks ialah \"%s\")" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Teks telah kosong (atau mengandungi hanya ruang putih)" + +#: glib/gspawn.c:315 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Gagal membaca data daripada proses anak (%s)" + +#: glib/gspawn.c:460 +#, c-format +#| msgid "Unexpected error in select() reading data from a child process (%s)" +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Ralat tidak jangka ketika membaca data daripada satu proses anak (%s)" + +#: glib/gspawn.c:545 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ralat tanpa jangka dalam waitpid() (%s)" + +#: glib/gspawn.c:1053 glib/gspawn-win32.c:1329 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Proses anak keluar dengan kod %ld" + +#: glib/gspawn.c:1061 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Proses anak dimatikan dengan isyarat %ld" + +#: glib/gspawn.c:1068 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Proses anak dihentikan dengan isyarat %ld" + +#: glib/gspawn.c:1075 +#, c-format +msgid "Child process exited abnormally" +msgstr "Proses anak keluar secara pelik" + +#: glib/gspawn.c:1475 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Gagal membaca daripada paip anak (%s)" + +#: glib/gspawn.c:1723 +#, c-format +#| msgid "Failed to fork child process (%s)" +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Gagal membiakkan proses anak \"%s\" (%s)" + +#: glib/gspawn.c:1762 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Gagal mencabang (%s)" + +#: glib/gspawn.c:1911 glib/gspawn-win32.c:381 +#, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to change to directory “%s†(%s)" +msgstr "Gagal mengubah ke direktori \"%s\": (%s)" + +#: glib/gspawn.c:1921 +#, c-format +#| msgid "Failed to execute child process \"%s\" (%s)" +msgid "Failed to execute child process “%s†(%s)" +msgstr "Gagal melakukan proses anak \"%s\" (%s)" + +#: glib/gspawn.c:1931 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Gagal menghala semula output atau input proses anak (%s)" + +#: glib/gspawn.c:1940 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Gagal mencabangkan proses anak (%s)" + +#: glib/gspawn.c:1948 +#, c-format +#| msgid "Unknown error executing child process \"%s\"" +msgid "Unknown error executing child process “%sâ€" +msgstr "Ralat tidak diketahui ketika melakukan proses anak \"%s\"" + +#: glib/gspawn.c:1972 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Gagal membaca data yang cukup daripada paip pid anak (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "Gagal membaca data daripada proses anak" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Gagal mencipta paip untuk berkomunikasi dengan proses anak (%s)" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Gagal melakukan proses anak (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nama program tidak sah: %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Rentetan tidak sah dalam vektor argumen pada %d: %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Rentetan tidak sah dalam persekitaran: %s" + +#: glib/gspawn-win32.c:721 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Direktori kerja tidak sah: %s" + +#: glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Gagal melakukan program pembantu (%s)" + +#: glib/gspawn-win32.c:1056 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ralat tidak jangka dalam g_io_channel_win32_poll() membaca data daripada " +"satu proses anak" + +#: glib/gstrfuncs.c:3309 glib/gstrfuncs.c:3411 +msgid "Empty string is not a number" +msgstr "Rentetan kosong bukanlah satu nombor" + +#: glib/gstrfuncs.c:3333 +#, c-format +msgid "“%s†is not a signed number" +msgstr "\"%s\" bukanlah satu nombor bertanda tangan" + +#: glib/gstrfuncs.c:3343 glib/gstrfuncs.c:3447 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Nombor \"%s\" di luar batas [%s, %s]" + +#: glib/gstrfuncs.c:3437 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "\"%s\" bukanlah satu nombor tanpa tanda tangan" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "Gagal memperuntukan ingatan" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "Aksara di luar julat UTF-8" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "Jujukan tidak sah dalan input pertukaran" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "Aksara di luar julat UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2756 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2758 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2760 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2762 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2764 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2766 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2770 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2772 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2774 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2776 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2778 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2780 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2784 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2786 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2788 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2790 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2792 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2794 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2798 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2800 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2802 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2804 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2806 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2808 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2842 glib/gutils.c:2959 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bait" +msgstr[1] "%u bait" + +#: glib/gutils.c:2846 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2913 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bait" +msgstr[1] "%s bait" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2918 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bit" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2972 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:2977 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2982 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2987 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2992 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2997 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#, fuzzy +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Gagal membuka fail '%s': fdopen() gagal: %s" + +#, fuzzy +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Gagal membuka fail '%s': fdopen() gagal: %s" + +#, fuzzy +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Gagal membuka fail '%s': fdopen() gagal: %s" + +#, fuzzy +#~ msgid "Error statting directory '%s': %s" +#~ msgstr "Ralat membuka direktori %s': %s" + +#, fuzzy +#~ msgid "Error opening file: %s" +#~ msgstr "Ralat membaca fail '%s': %s" + +#, fuzzy +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Ralat membaca fail '%s': %s" + +#, fuzzy +#~ msgid "Error connecting: " +#~ msgstr "Ralat membaca fail '%s': %s" + +#, fuzzy +#~ msgid "Error connecting: %s" +#~ msgstr "Ralat membaca fail '%s': %s" + +#, fuzzy +#~ msgid "Error reading from unix: %s" +#~ msgstr "Ralat membaca fail '%s': %s" + +#, fuzzy +#~ msgid "Error closing unix: %s" +#~ msgstr "Ralat pada baris %d: %s" + +#, fuzzy +#~ msgid "Error writing to unix: %s" +#~ msgstr "Ralat semasa penukaran: %s" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Turutan tidak sah semasa penukaran input" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Aksara '%s' adalah tidak sah pada permulaan nama entiti; aksara '&' " +#~ "memulakan entiti; jika & tidak disokong untuk dijadikan entiti, escapekan " +#~ "sebagai &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Rujukan aksara kosong; sepatutnya disertakan digit seperti dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Rujukan entiti tidak tamat" + +#~ msgid "Unfinished character reference" +#~ msgstr "Rujukan aksara tidak tamat" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Teks terenkod UTF-8 tidak sah" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Teks terenkod UTF-8 tidak sah" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Namahos URI '%s' tidak sah" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Namahos URI '%s' tidak sah" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Ralat membaca fail '%s': %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Ralat semasa penukaran: %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Gagal membuka fail '%s': fdopen() gagal: %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Gagal membuka fail '%s': fdopen() gagal: %s" diff --git a/po/nb.po b/po/nb.po new file mode 100644 index 0000000..e448ca7 --- /dev/null +++ b/po/nb.po @@ -0,0 +1,5701 @@ +# Norwegian bokmÃ¥l translation of glib. +# Copyright (C) 2001-2003, 2005 Free Software Foundation, Inc. +# Kjartan Maraas , 2001-2018. +# Terance Edward Sola , 2005. +# Torstein Adolf Winterseth , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: glib 2.59.x\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-11-06 12:56+0000\n" +"PO-Revision-Date: 2018-10-07 11:10+0200\n" +"Last-Translator: Kjartan Maraas \n" +"Language-Team: Norwegian bokmÃ¥l \n" +"Language: nb\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" + +#: ../gio/gapplication.c:490 +msgid "GApplication options" +msgstr "Flagg for GApplication" + +#: ../gio/gapplication.c:490 +msgid "Show GApplication options" +msgstr "Vis flagg for GApplication" + +#: ../gio/gapplication.c:535 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Oppgi tjenestemodus for GApplication (bruk fra D-Bus tjenestefiler)" + +#: ../gio/gapplication.c:547 +msgid "Override the application’s ID" +msgstr "Overstyr programmets ID" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gio-tool.c:227 ../gio/gresource-tool.c:488 +#: ../gio/gsettings-tool.c:522 +msgid "Print help" +msgstr "Skriv ut hjelp" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:489 +#: ../gio/gresource-tool.c:557 +msgid "[COMMAND]" +msgstr "[KOMMANDO]" + +#: ../gio/gapplication-tool.c:49 ../gio/gio-tool.c:228 +msgid "Print version" +msgstr "Skriv ut versjon" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:528 +msgid "Print version information and exit" +msgstr "Skriv versjonsinformasjon og avslutt" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Vis programmer" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Vis installerte programmer som kan aktiveres via D-Bus (pÃ¥ .desktop-filer)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "Start et program" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "Start programmet (med valgfrie filer som skal Ã¥pnes)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "PROGID [FIL …]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "Aktiver en handling" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "Utfør en handling pÃ¥ programmet" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "PROGID HANDLING [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Vis tilgjengelige handlinger" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "Vis statiske handlinger for et program (fra .desktop-fil)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "PROGID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 ../gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMMANDO" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "Vis detaljert hjelp for denne kommandoen" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Programidentifikator i D-Bus-format (f.eks. org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:665 +#: ../gio/glib-compile-resources.c:671 ../gio/glib-compile-resources.c:698 +#: ../gio/gresource-tool.c:495 ../gio/gresource-tool.c:561 +msgid "FILE" +msgstr "FIL" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Valgfrie relative eller absolutte filnavn eller URIer som skal Ã¥pnes" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "HANDLING" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "Handling som skal utføres" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Valgfri parameter til utførelse av handling, i GVariant-format" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:526 +#: ../gio/gsettings-tool.c:614 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Ukjent kommando «%s»\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "Bruk:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:551 +#: ../gio/gsettings-tool.c:649 +msgid "Arguments:\n" +msgstr "Argumenter:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS…]" +msgstr "[ARGUMENTER …]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Kommandoer:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Bruk «%s help KOMMANDO» for Ã¥ fÃ¥ detaljert hjelp.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "%s-kommandoen krever en program-ID etter kommandoen\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "ugyldig program-ID: «%s»\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"«%s» tar ingen argumenter\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "kan ikke koble til D-Bus: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "feil ved sending av %s-melding til program: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "navn pÃ¥ handling mÃ¥ oppgis etter program-ID\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"ugyldig navvn pÃ¥ handling: «%s»\n" +"navn pÃ¥ handlinger mÃ¥ kun bestÃ¥ av tall og bokstaver, «-» og «.»\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "feil under tolking av parameter for handling: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "handlinger godtar ikke mer enn en parameter\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "list-actions kommandoen tar kun program-ID" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "kan ikke finne skrivebordsfil for program %s\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"ukjent kommando: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:179 ../gio/ginputstream.c:379 +#: ../gio/ginputstream.c:617 ../gio/ginputstream.c:1019 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:834 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Tellerverdi gitt til %s er for stor" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Søk er ikke støttet pÃ¥ grunnstrøm" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Kan ikke avkorte GBufferedInputStream" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1208 +#: ../gio/giostream.c:300 ../gio/goutputstream.c:1660 +msgid "Stream is already closed" +msgstr "Strømmen er allerede lukket" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Avkorting er ikke støttet pÃ¥ grunnstrøm" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1849 +#: ../gio/gdbusprivate.c:1402 ../gio/gsimpleasyncresult.c:871 +#: ../gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operasjonen ble avbrutt" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Ugyldig objekt, ikke initiert" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Ugyldig multibytesekvens i inndata" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Ikke nok plass i mÃ¥l" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1257 ../glib/gconvert.c:438 ../glib/gconvert.c:845 +#: ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:866 ../glib/gutf8.c:1319 +msgid "Invalid byte sequence in conversion input" +msgstr "Ugyldig bytesekvens i inndata for konvertering" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 ../glib/gconvert.c:770 +#: ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "Feil under konvertering: %s" + +#: ../gio/gcharsetconverter.c:445 ../gio/gsocket.c:1101 +msgid "Cancellable initialization not supported" +msgstr "Avbrytbar initiering er ikke støttet" + +#: ../gio/gcharsetconverter.c:456 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Konvertering fra tegnsett «%s» til «%s» er ikke støttet" + +#: ../gio/gcharsetconverter.c:460 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Kunne ikke Ã¥pne program for Ã¥ konvertere fra «%s» til «%s»" + +#: ../gio/gcontenttype.c:358 +#, c-format +msgid "%s type" +msgstr "type %s" + +#: ../gio/gcontenttype-win32.c:177 +msgid "Unknown type" +msgstr "Ukjent type" + +#: ../gio/gcontenttype-win32.c:179 +#, c-format +msgid "%s filetype" +msgstr "filtype %s" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials er ikke implementert pÃ¥ dette OSet" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "Det finnes ingen støtte for GCredentials for din plattform" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials har ikke en prosess-ID pÃ¥ dette OSet" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Spoofing av Credentials er ikke mulig pÃ¥ dette OSet" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Uventet tidlig slutt pÃ¥ strøm" + +#: ../gio/gdbusaddress.c:155 ../gio/gdbusaddress.c:243 +#: ../gio/gdbusaddress.c:324 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Ikke støttet nøkkel «%s» i adresseoppføring «%s»" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"Adressen «%s» er ugyldig (trenger eksakt en av følgende: sti, tmpdir eller " +"abstrakte nøkler)" + +#: ../gio/gdbusaddress.c:195 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Meningsløst nøkkel-/verdi-par i adresseoppføring «%s»" + +#: ../gio/gdbusaddress.c:258 ../gio/gdbusaddress.c:339 +#, c-format +msgid "Error in address “%s†— the port attribute is malformed" +msgstr "Feil i adresse «%s» – portattributten er feilutformet" + +#: ../gio/gdbusaddress.c:269 ../gio/gdbusaddress.c:350 +#, c-format +msgid "Error in address “%s†— the family attribute is malformed" +msgstr "Feil i adresse «%s» – familieattributten er feilutformet" + +#: ../gio/gdbusaddress.c:460 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adresseelement «%s» inneholder ikke et kolon (:)" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Nøkkel/verdi-par %d, «%s», i adresseelement «%s» inneholder ikke et " +"likhetstegn" + +#: ../gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Feil ved unescaping av nøkkel eller verdi i nøkkel/verdi par %d, «%s», i " +"adresseelement «%s»" + +#: ../gio/gdbusaddress.c:573 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Feil i adresse «%s» – unix-transport krever at eksakt en av nøklene «path» " +"eller «abstract» er satt" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Feil i adresse «%s» – vertsattributt mangler eller er feilutformet" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Feil i adresse «%s» – portattributt mangler eller er feilutformet" + +#: ../gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "Feil i adresse «%s» – noncefil-attributt mangler eller er feilutformet" + +#: ../gio/gdbusaddress.c:658 +msgid "Error auto-launching: " +msgstr "Feil under automatisk oppstart: " + +#: ../gio/gdbusaddress.c:666 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Ukjent eller ikke støttet transport «%s» for adresse «%s»" + +#: ../gio/gdbusaddress.c:704 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Feil under Ã¥pning av nonce-fil «%s»: %s" + +#: ../gio/gdbusaddress.c:723 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Feil under lesing fra nonce-fil «%s»: %s" + +#: ../gio/gdbusaddress.c:732 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Feil under lesing fra nonce-fil «%s», forventet 16 bytes, fikk %d" + +#: ../gio/gdbusaddress.c:750 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Feil under skriving av innhold i nonce-fil «%s» til strøm:" + +#: ../gio/gdbusaddress.c:959 +msgid "The given address is empty" +msgstr "Gitt adresse er tom" + +#: ../gio/gdbusaddress.c:1072 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Kan ikke starte en meldingsbuss med setuid" + +#: ../gio/gdbusaddress.c:1079 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Kan ikke starte en meldingsbuss uten en machine-id: " + +#: ../gio/gdbusaddress.c:1086 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Kan ikke starte D-Bus automatisk uten X11 $DISPLAY" + +#: ../gio/gdbusaddress.c:1128 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Feil under start av kommandolinje «%s»: " + +#: ../gio/gdbusaddress.c:1345 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Trykk en tast for Ã¥ lukke dette vinduet)\n" + +#: ../gio/gdbusaddress.c:1499 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "D-Bus for økten kjører ikke og automatisk start feilet" + +#: ../gio/gdbusaddress.c:1510 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Kan ikke bestemme adresse til øktbussen (ikke implementert pÃ¥ dette OSet)" + +#: ../gio/gdbusaddress.c:1648 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Kan ikke bestemme adresse for buss fra miljøvariabelen DBUS_STARTER_BUS_TYPE " +"– ukjent verdi «%s»" + +#: ../gio/gdbusaddress.c:1657 ../gio/gdbusconnection.c:7155 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Kan ikke bestemme adressen til bussen fordi miljøvariabelen " +"DBUS_STARTER_BUS_TYPE ikke er satt" + +#: ../gio/gdbusaddress.c:1667 +#, c-format +msgid "Unknown bus type %d" +msgstr "Ukjent type buss %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "Uventet mangel pÃ¥ innhold ved forsøk pÃ¥ Ã¥ lese en linje" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Uventet mangel pÃ¥ innhold ved forsøk pÃ¥ Ã¥ lese en linje pÃ¥ trygg mÃ¥te" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Brukte opp alle tilgjengelige autentiseringsmekanismer (forsøkt: %s) " +"(tilgjengelig: %s)" + +#: ../gio/gdbusauth.c:1171 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Avbrutt via GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:262 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Feil under henting av informasjon for katalog «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:274 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Rettigheter for katalog «%s» er feilutformet. Forventet modus 0700, fikk 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:296 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Feil under oppretting av katalog «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:379 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Feil under Ã¥pning av nøkkelring «%s» for lesing: " + +#: ../gio/gdbusauthmechanismsha1.c:402 ../gio/gdbusauthmechanismsha1.c:720 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Linje %d av nøkkelring ved «%s» med innhold «%s» er feilutformet" + +#: ../gio/gdbusauthmechanismsha1.c:416 ../gio/gdbusauthmechanismsha1.c:734 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Første symbol pÃ¥ linje %d av nøkkelring ved «%s» med innhold «%s» er " +"feilutformet" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:748 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Andre symbol av linje %d i nøkkelring ved «%s» med innhold «%s» er " +"feilutformet" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Fant ingen informasjonskapsel med id %d i nøkkelring ved «%s»" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Feil under sletting av gammel lÃ¥sfil «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Feil under oppretting av lÃ¥sfil «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:599 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Feil under lukking av (unlink()et) lÃ¥sfil «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:610 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Feil under unlink()ing av lÃ¥sfil «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:687 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Feil under Ã¥pning av nøkkelring «%s» for skriving: " + +#: ../gio/gdbusauthmechanismsha1.c:883 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(I tillegg feilet frislipp av lÃ¥s for «%s» ogsÃ¥: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2378 +msgid "The connection is closed" +msgstr "Tilkoblingen er lukket" + +#: ../gio/gdbusconnection.c:1879 +msgid "Timeout was reached" +msgstr "Tidsavbrudd ble nÃ¥dd" + +#: ../gio/gdbusconnection.c:2500 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Ikke støttede flagg funnet ved oppretting av en klientside tilkobling" + +#: ../gio/gdbusconnection.c:4124 ../gio/gdbusconnection.c:4471 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"Grensesnitt «org.freedesktop.DBus.Properties» finnes ikke pÃ¥ objekt i sti %s" + +#: ../gio/gdbusconnection.c:4266 +#, c-format +msgid "No such property '%s'" +msgstr "Egenskap «%s» finnes ikke" + +#: ../gio/gdbusconnection.c:4278 +#, c-format +msgid "Property '%s' is not readable" +msgstr "Egenskap «%s» er er ikke lesbar" + +#: ../gio/gdbusconnection.c:4289 +#, c-format +msgid "Property '%s' is not writable" +msgstr "Egenskap «%s» er er ikke skrivbar" + +#: ../gio/gdbusconnection.c:4309 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "Feil ved setting av egenskap «%s»: Forventet type «%s», men fikk «%s»" + +#: ../gio/gdbusconnection.c:4414 ../gio/gdbusconnection.c:4622 +#: ../gio/gdbusconnection.c:6586 +#, c-format +msgid "No such interface '%s'" +msgstr "Grensesnitt «%s» finnes ikke" + +#: ../gio/gdbusconnection.c:4840 ../gio/gdbusconnection.c:7095 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "Grensesnitt «%s» finnes ikke pÃ¥ objektsti %s" + +#: ../gio/gdbusconnection.c:4938 +#, c-format +msgid "No such method '%s'" +msgstr "Metoden «%s» finnes ikke" + +#: ../gio/gdbusconnection.c:4969 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "Type melding, «%s», stemmer ikke overens med forventet type «%s»" + +#: ../gio/gdbusconnection.c:5167 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Et objekt er allerede eksportert for grensesnitt %s ved %s" + +#: ../gio/gdbusconnection.c:5393 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Kunne ikke hente egenskap %s.%s" + +#: ../gio/gdbusconnection.c:5449 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Kan ikke sette egenskap %s.%s" + +#: ../gio/gdbusconnection.c:5625 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "Metode «%s» returnerte type «%s», men forventet «%s»" + +#: ../gio/gdbusconnection.c:6697 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "Metode «%s» pÃ¥ grensesnitt «%s» med signatur «%s» eksisterer ikke" + +#: ../gio/gdbusconnection.c:6818 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Et undertre er allerede eksportert for %s" + +#: ../gio/gdbusconnection.c:7146 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"Kan ikke bestemme adresse for buss fra miljøvariabelen DBUS_STARTER_BUS_TYPE " +"- ukjent verdi «%s»" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "UGYLDIG type" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL melding: Topptekstfelt PATH eller MEMBER mangler" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN melding: Topptekstfelt REPLY_SERIAL mangler" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR melding: Topptekstfelt REPLY_SERIAL eller ERROR_NAME mangler" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL melding: Topptekstfelt for PATH, INTERFACE eller MEMBER mangler" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL-melding: Topptekstfelt for PATH bruker reservert verdi /org/" +"freedesktop/DBus/Local" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL melding: Topptekstfelt for INTERFACE bruker reservert verdi org." +"freedesktop.DBus.Local" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Ønsket Ã¥ lese %lu byte men fikk bare %lu" +msgstr[1] "Ønsket Ã¥ lese %lu bytes men fikk bare %lu" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Forventet NUL-byte etter strengen «%s», men fant byte %d" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Forventet en gyldig UTF-8 streng, men fant ugyldige bytes ved byteavstand %d " +"(lengden av strengen er %d). Gydldig UTF-8 streng opp til det punktet var " +"«%s»" + +#: ../gio/gdbusmessage.c:1593 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Lest verdi «%s» er ikke en gyldig objektsti for D-Bus" + +#: ../gio/gdbusmessage.c:1615 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Tolket verdi «%s» er ikke en gyldig D-Bus-signatur" + +#: ../gio/gdbusmessage.c:1662 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Fant en array med lengde %u byte. Maksimal lengde er 2<<26 byte (64 MiB)." +msgstr[1] "" +"Fant en array med lengde %u bytes. Maksimal lengde er 2<<26 byte (64 MiB)." + +#: ../gio/gdbusmessage.c:1682 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Fant en matrise av type «a%c» som var forventet Ã¥ ha en lengde som er en " +"multippel av %u bytes, men var %u bytes lang" + +#: ../gio/gdbusmessage.c:1849 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Lest verdi «%s» for variant er ikke en gyldig D-Bus-signatur" + +#: ../gio/gdbusmessage.c:1873 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Feil ved deserialisering av GVariant med strengtype «%s» fra D-Bus-format" + +#: ../gio/gdbusmessage.c:2055 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Ugyldig verdi for endianness. Forventet 0x6c ('l') eller 0x42 ('B'), men " +"fant verdien 0x%02x" + +#: ../gio/gdbusmessage.c:2068 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Ugyldig hovedversjon for protokoll. Forventet en men fikk %d" + +#: ../gio/gdbusmessage.c:2124 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "Signaturtopptekst med signatur «%s» funnet, men meldingskroppen er tom" + +#: ../gio/gdbusmessage.c:2138 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Lest verdi «%s» er ikke en gyldig D-Bus-signatur (for kropp)" + +#: ../gio/gdbusmessage.c:2168 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Ingen signaturtopptekst i meldingen, men meldingskroppen er %u byte" +msgstr[1] "" +"Ingen signaturtopptekst i meldingen, men meldingskroppen er %u bytes" + +#: ../gio/gdbusmessage.c:2178 +msgid "Cannot deserialize message: " +msgstr "Kan ikke deserialisere melding: " + +#: ../gio/gdbusmessage.c:2519 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Feil ved serialisering av GVariant med strengtype «%s» til D-Bus-format" + +#: ../gio/gdbusmessage.c:2656 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"Meldingen har %d fildeskriptorer men topptekstfeltet indikerer %d " +"fildeskriptorer" + +#: ../gio/gdbusmessage.c:2664 +msgid "Cannot serialize message: " +msgstr "Kan ikke serialisere melding: " + +#: ../gio/gdbusmessage.c:2708 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Meldingskroppen har signatur «%s» men det finnes ingen signaturtopptekst" + +#: ../gio/gdbusmessage.c:2718 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Meldingskroppen har signaturtype «%s», men signaturen i topptekstfeltet et " +"«%s»" + +#: ../gio/gdbusmessage.c:2734 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Meldingskroppen er tom men signatur i topptekstfeltet er «(%s)»" + +#: ../gio/gdbusmessage.c:3287 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Feil retur med kropp av type «%s»" + +#: ../gio/gdbusmessage.c:3295 +msgid "Error return with empty body" +msgstr "Feil retur med tom kropp" + +#: ../gio/gdbusprivate.c:2066 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Kan ikke hente maskinvareprofil: %s" + +#: ../gio/gdbusprivate.c:2111 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Kan ikke laste /var/lib/dbus/machine-id eller /etc/machine-id: " + +#: ../gio/gdbusproxy.c:1611 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Feil ved kall til StartServiceByName for %s: " + +#: ../gio/gdbusproxy.c:1634 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Uventet svar %d fra metoden StartServiceByName(«%s»)" + +#: ../gio/gdbusproxy.c:2719 ../gio/gdbusproxy.c:2853 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Kan ikke invokere metode; proxy er for et velkjent navn uten en eier og " +"proxy ble opprettet med flagget G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "Abstrakt navneomrÃ¥de er ikke støttet" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "Kan ikke oppgi nonce-fil nÃ¥r en tjener opprettes" + +#: ../gio/gdbusserver.c:876 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Feil under skriving av nonce-fil i «%s»: %s" + +#: ../gio/gdbusserver.c:1047 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Strengen «%s» er ikke en gyldig D-Bus-GUID" + +#: ../gio/gdbusserver.c:1087 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Kan ikke lytte pÃ¥ en transport «%s» som ikke er støttet" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Kommandoer:\n" +" help Viser denne informasjonen\n" +" introspect Introspekt et eksternt objekt\n" +" monitor OvervÃ¥k et eksternt objekt\n" +" call Kjør en metode pÃ¥ et eksternt objekt\n" +" emit Send ut et signal\n" +" wait Vent pÃ¥ et bussnavn\n" +" \n" +"Bruk «%s COMMAND --help» for Ã¥ fÃ¥ hjelp om hver kommando.\n" + +#: ../gio/gdbus-tool.c:167 ../gio/gdbus-tool.c:234 ../gio/gdbus-tool.c:306 +#: ../gio/gdbus-tool.c:330 ../gio/gdbus-tool.c:811 ../gio/gdbus-tool.c:1150 +#: ../gio/gdbus-tool.c:1592 +#, c-format +msgid "Error: %s\n" +msgstr "Feil: %s\n" + +#: ../gio/gdbus-tool.c:178 ../gio/gdbus-tool.c:247 ../gio/gdbus-tool.c:1608 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Feil under tolking av introspeksjons-XML: %s\n" + +#: ../gio/gdbus-tool.c:216 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Feil: %s er ikke et gyldig navn\n" + +#: ../gio/gdbus-tool.c:364 +msgid "Connect to the system bus" +msgstr "Koble til systembussen" + +#: ../gio/gdbus-tool.c:365 +msgid "Connect to the session bus" +msgstr "Koble til øktbussen" + +#: ../gio/gdbus-tool.c:366 +msgid "Connect to given D-Bus address" +msgstr "Koble til gitt D-Bus-adresse" + +#: ../gio/gdbus-tool.c:376 +msgid "Connection Endpoint Options:" +msgstr "Alternativer for tilkoblingssluttpunkt:" + +#: ../gio/gdbus-tool.c:377 +msgid "Options specifying the connection endpoint" +msgstr "Alternativer som spesifiserer sluttpunkt for tilkobling" + +#: ../gio/gdbus-tool.c:399 +#, c-format +msgid "No connection endpoint specified" +msgstr "Sluttpunkt for tilkobling ikke oppgitt" + +#: ../gio/gdbus-tool.c:409 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Flere sluttpunkt oppgitt for tilkobling" + +#: ../gio/gdbus-tool.c:479 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Advarsel: I følge introspeksjonsdata eksisterer ikke grensesnitt «%s»\n" + +#: ../gio/gdbus-tool.c:488 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Advarsel: I følge introspeksjonsdata eksisterer ikke metode «%s» pÃ¥ " +"grensesnitt «%s»\n" + +#: ../gio/gdbus-tool.c:550 +msgid "Optional destination for signal (unique name)" +msgstr "Valgfri destinasjon for signal (unikt navn)" + +#: ../gio/gdbus-tool.c:551 +msgid "Object path to emit signal on" +msgstr "Objektsti signal skal sendes ut pÃ¥" + +#: ../gio/gdbus-tool.c:552 +msgid "Signal and interface name" +msgstr "Navn pÃ¥ signal og grensesnitt" + +#: ../gio/gdbus-tool.c:587 +msgid "Emit a signal." +msgstr "Send ut et signal." + +#: ../gio/gdbus-tool.c:642 ../gio/gdbus-tool.c:944 ../gio/gdbus-tool.c:1698 +#: ../gio/gdbus-tool.c:1931 ../gio/gdbus-tool.c:2152 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Feil under tilkobling: %s\n" + +#: ../gio/gdbus-tool.c:659 ../gio/gdbus-tool.c:961 ../gio/gdbus-tool.c:1715 +#: ../gio/gdbus-tool.c:1956 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "Feil: MÃ¥l er ikke oppgitt\n" + +#: ../gio/gdbus-tool.c:670 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Feil: %s er ikke et gyldig unikt bussnavn.\n" + +#: ../gio/gdbus-tool.c:685 ../gio/gdbus-tool.c:987 ../gio/gdbus-tool.c:1741 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "Feil: Objektsti er ikke oppgitt\n" + +#: ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1007 ../gio/gdbus-tool.c:1761 +#: ../gio/gdbus-tool.c:2002 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Feil: %s er ikke en gyldig objektsti\n" + +#: ../gio/gdbus-tool.c:720 +#, c-format +msgid "Error: Signal name is not specified\n" +msgstr "Feil: Signalnavn er ikke oppgitt\n" + +#: ../gio/gdbus-tool.c:731 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Feil: Signalnavn «%s» er ugyldig\n" + +#: ../gio/gdbus-tool.c:743 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Feil: %s er ikke en gyldig navn pÃ¥ grensesnitt\n" + +#: ../gio/gdbus-tool.c:749 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Feil: %s er ikke et gyldig medlemsnavn\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:786 ../gio/gdbus-tool.c:1119 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Feil under tolking av parameter %d: %s\n" + +#: ../gio/gdbus-tool.c:818 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Feil ved nullstilling av tilkobling: %s\n" + +#: ../gio/gdbus-tool.c:845 +msgid "Destination name to invoke method on" +msgstr "MÃ¥lnavn metoden skal invokeres pÃ¥" + +#: ../gio/gdbus-tool.c:846 +msgid "Object path to invoke method on" +msgstr "Objektsti metoden skal invokeres pÃ¥" + +#: ../gio/gdbus-tool.c:847 +msgid "Method and interface name" +msgstr "Navn pÃ¥ metode og grensesnitt" + +#: ../gio/gdbus-tool.c:848 +msgid "Timeout in seconds" +msgstr "Tidsavbrudd i sekunder" + +#: ../gio/gdbus-tool.c:889 +msgid "Invoke a method on a remote object." +msgstr "Kjør en metode pÃ¥ et eksternt objekt." + +#: ../gio/gdbus-tool.c:972 ../gio/gdbus-tool.c:1732 ../gio/gdbus-tool.c:1967 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Feil: %s er ikke et gyldig navn pÃ¥ buss\n" + +#: ../gio/gdbus-tool.c:1022 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "Feil: metodenavn er ikke oppgitt\n" + +#: ../gio/gdbus-tool.c:1033 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Feil: metodenavn «%s» er ugyldig\n" + +#: ../gio/gdbus-tool.c:1111 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Feil under tolking av parameter %d av type «%s»: %s\n" + +#: ../gio/gdbus-tool.c:1555 +msgid "Destination name to introspect" +msgstr "MÃ¥lnavn som skal inspiseres" + +#: ../gio/gdbus-tool.c:1556 +msgid "Object path to introspect" +msgstr "Objektsti som skal inspiseres" + +#: ../gio/gdbus-tool.c:1557 +msgid "Print XML" +msgstr "Skriv ut XML" + +#: ../gio/gdbus-tool.c:1558 +msgid "Introspect children" +msgstr "Bruk introspeksjon for barn" + +#: ../gio/gdbus-tool.c:1559 +msgid "Only print properties" +msgstr "Skriv kun ut egenskaper" + +#: ../gio/gdbus-tool.c:1650 +msgid "Introspect a remote object." +msgstr "Inspiser et eksternt objekt." + +#: ../gio/gdbus-tool.c:1853 +msgid "Destination name to monitor" +msgstr "Navn pÃ¥ mÃ¥l som skal overvÃ¥kes" + +#: ../gio/gdbus-tool.c:1854 +msgid "Object path to monitor" +msgstr "Objektsti som skal overvÃ¥kes" + +#: ../gio/gdbus-tool.c:1883 +msgid "Monitor a remote object." +msgstr "OvervÃ¥k et eksternt objekt." + +#: ../gio/gdbus-tool.c:1941 +#, c-format +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: ../gio/gdbus-tool.c:2065 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: ../gio/gdbus-tool.c:2068 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: ../gio/gdbus-tool.c:2116 +msgid "[OPTION…] BUS-NAME" +msgstr "[FLAGG …] BUSS-NAVN" + +#: ../gio/gdbus-tool.c:2118 +msgid "Wait for a bus name to appear." +msgstr "Vent pÃ¥ et bussnavn." + +#: ../gio/gdbus-tool.c:2194 +#, c-format +msgid "Error: A service to activate for must be specified.\n" +msgstr "Feil: En tjeneste Ã¥ aktivere for mÃ¥ oppgis.\n" + +#: ../gio/gdbus-tool.c:2199 +#, c-format +msgid "Error: A service to wait for must be specified.\n" +msgstr "Feil: En tjeneste Ã¥ vente pÃ¥ mÃ¥ oppgis.\n" + +#: ../gio/gdbus-tool.c:2204 +#, c-format +msgid "Error: Too many arguments.\n" +msgstr "Feil: For mange argumenter.\n" + +#: ../gio/gdbus-tool.c:2212 ../gio/gdbus-tool.c:2219 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Feil: %s er ikke et gyldig og velkjent navn pÃ¥ en buss.\n" + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4531 +msgid "Unnamed" +msgstr "Uten navn" + +#: ../gio/gdesktopappinfo.c:2411 +msgid "Desktop file didn’t specify Exec field" +msgstr "Desktop-filen hadde ingen verdi i Exec-feltet" + +#: ../gio/gdesktopappinfo.c:2694 +msgid "Unable to find terminal required for application" +msgstr "Kan ikke finne terminalen som kreves for programmet" + +#: ../gio/gdesktopappinfo.c:3127 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Kan ikke opprette konfigurasjonsmappe %s for brukers program: %s" + +#: ../gio/gdesktopappinfo.c:3131 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Kan ikke opprette brukers konfigurasjonsmappe %s for MIME: %s" + +#: ../gio/gdesktopappinfo.c:3371 ../gio/gdesktopappinfo.c:3395 +msgid "Application information lacks an identifier" +msgstr "Programinformasjonen mangler en identifikator" + +#: ../gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Kan ikke opprette brukers desktop-fil %s" + +#: ../gio/gdesktopappinfo.c:3763 +#, c-format +msgid "Custom definition for %s" +msgstr "Egendefinert definisjon for %s" + +#: ../gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "stasjonen implementerer ikke utløsing" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "stasjonen implementerer ikke eject eller eject_with_operation" + +#: ../gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "stasjonen implementerer ikke sjekk om medie er satt inn" + +#: ../gio/gdrive.c:776 +msgid "drive doesn’t implement start" +msgstr "stasjonen implementerer ikke start" + +#: ../gio/gdrive.c:878 +msgid "drive doesn’t implement stop" +msgstr "stasjonen implementerer ikke stopp" + +#: ../gio/gdummytlsbackend.c:195 ../gio/gdummytlsbackend.c:317 +#: ../gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "TLS-støtte er ikke tilgjengelig" + +#: ../gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "DTLS-støtte er ikke tilgjengelig" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Kan ikke hÃ¥ndtere versjon %d av GEmblem-koding" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Feil antall tegn (%d) i GEmblem-koding" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Kan ikke hÃ¥ndtere versjon %d av GEmblemedIcon-koding" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Feil antall tegn (%d) i GEmblemedIcon-koding" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Ventet et GEmblem for GEmblemedIcon" + +#: ../gio/gfile.c:969 ../gio/gfile.c:1207 ../gio/gfile.c:1345 +#: ../gio/gfile.c:1583 ../gio/gfile.c:1638 ../gio/gfile.c:1696 +#: ../gio/gfile.c:1780 ../gio/gfile.c:1837 ../gio/gfile.c:1901 +#: ../gio/gfile.c:1956 ../gio/gfile.c:3602 ../gio/gfile.c:3657 +#: ../gio/gfile.c:3893 ../gio/gfile.c:3935 ../gio/gfile.c:4403 +#: ../gio/gfile.c:4814 ../gio/gfile.c:4899 ../gio/gfile.c:4989 +#: ../gio/gfile.c:5086 ../gio/gfile.c:5173 ../gio/gfile.c:5274 +#: ../gio/gfile.c:7817 ../gio/gfile.c:7907 ../gio/gfile.c:7991 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "Operasjonen er ikke støttet" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: ../gio/gfile.c:1468 +msgid "Containing mount does not exist" +msgstr "Omsluttende monteringspunkt finnes ikke" + +#: ../gio/gfile.c:2515 ../gio/glocalfile.c:2380 +msgid "Can’t copy over directory" +msgstr "Kan ikke kopiere over katalog" + +#: ../gio/gfile.c:2575 +msgid "Can’t copy directory over directory" +msgstr "Kan ikke kopiere katalog over katalog" + +#: ../gio/gfile.c:2583 +msgid "Target file exists" +msgstr "MÃ¥lfilen eksisterer" + +#: ../gio/gfile.c:2602 +msgid "Can’t recursively copy directory" +msgstr "Kan ikke kopiere katalog rekursivt" + +#: ../gio/gfile.c:2877 +msgid "Splice not supported" +msgstr "Splice er ikke støttet" + +#: ../gio/gfile.c:2881 +#, c-format +msgid "Error splicing file: %s" +msgstr "Feil ved bruk av splice(2) pÃ¥ fil: %s" + +#: ../gio/gfile.c:3013 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopiering (reflink/clone) mellom monteringspunkter er ikke støttet" + +#: ../gio/gfile.c:3017 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopiering (reflink/clone) er ikke støttet eller ugyldig" + +#: ../gio/gfile.c:3022 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopiering (reflink/clone) er ikke støttet eller virket ikke" + +#: ../gio/gfile.c:3085 +msgid "Can’t copy special file" +msgstr "Kan ikke kopiere spesiell fil" + +#: ../gio/gfile.c:3883 +msgid "Invalid symlink value given" +msgstr "Ugyldig verdi oppgitt for symbolsk lenke" + +#: ../gio/gfile.c:4044 +msgid "Trash not supported" +msgstr "Papirkurv er ikke støttet" + +#: ../gio/gfile.c:4156 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Filnavn kan ikke inneholde «%c»" + +#: ../gio/gfile.c:6602 ../gio/gvolume.c:363 +msgid "volume doesn’t implement mount" +msgstr "volumet implementerer ikke montering" + +#: ../gio/gfile.c:6711 +msgid "No application is registered as handling this file" +msgstr "Ingen program registrert for Ã¥ hÃ¥ndtere denne filen" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator er lukket" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Filenumerator har utestÃ¥ende operasjon" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Filenumerator er allerede lukket" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Kan ikke hÃ¥ndtere versjon %d av GFileIcon-koding" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Feil inndata for GFileIcon" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Strømmen støtter ikke query_info" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Søking ikke støttet pÃ¥ strøm" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Avkorting er ikke tillatt pÃ¥ en inndatastrøm" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Avkorting er ikke støttet pÃ¥ strømmen" + +#: ../gio/ghttpproxy.c:91 ../gio/gresolver.c:410 ../gio/gresolver.c:476 +#: ../glib/gconvert.c:1650 +msgid "Invalid hostname" +msgstr "Ugyldig vertsnavn" + +#: ../gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Ugyldig svar fra HTTP-proxy" + +#: ../gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP-proxytilkobling tillates ikke" + +#: ../gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Autentisering for HTTP-proxy feilet" + +#: ../gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Autentisering kreves for HTTP-proxy" + +#: ../gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP-proxytilkobling feilet: %i" + +#: ../gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP-proxytjener lukket tilkoblingen uventet." + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Feil antall tegn (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "Ingen type for klassenavn %s" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Type %s implementerer ikke GIcon-grensesnittet" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "Type %s er er ikke en klasse" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "Feil versjonsnummer: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Type %s implementerer ikke from_tokens() pÃ¥ GIcon-grensesnittet" + +#: ../gio/gicon.c:461 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Kan ikke hÃ¥ndtere oppgitt versjon i ikon-koding" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Ingen adresse oppgitt" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Lengde %u er for lang for adressen" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adressen har biter satt forbi lengde pÃ¥ prefiks" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Kunne ikke lese «%s» som IP-adressemaske" + +#: ../gio/ginetsocketaddress.c:203 ../gio/ginetsocketaddress.c:220 +#: ../gio/gnativesocketaddress.c:106 ../gio/gunixsocketaddress.c:218 +msgid "Not enough space for socket address" +msgstr "Ikke nok plass til adresse for plugg" + +#: ../gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Adresse for plugg er ikke støttet" + +#: ../gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Inndatastrøm implementerer ikke lesing" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1218 ../gio/giostream.c:310 +#: ../gio/goutputstream.c:1670 +msgid "Stream has outstanding operation" +msgstr "Strømmen har utestÃ¥ende operasjoner" + +#: ../gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopier med fil" + +#: ../gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Behold med fil nÃ¥r den flyttes" + +#: ../gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "«version» tar ingen argumenter" + +#: ../gio/gio-tool.c:207 ../gio/gio-tool.c:223 ../glib/goption.c:857 +msgid "Usage:" +msgstr "Bruk:" + +#: ../gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Skriv versjonsinformasjon og avslutt." + +#: ../gio/gio-tool.c:224 +msgid "[ARGS...]" +msgstr "[ARGUMENTER …]" + +#: ../gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Kommandoer:" + +#: ../gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Spleis filer til standard utdata" + +#: ../gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopier en eller flere filer" + +#: ../gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Vis informasjon om lokasjoner" + +#: ../gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "Vis innholdet i lokasjoner" + +#: ../gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "Hent eller sett hÃ¥ndterer for en MIME-type" + +#: ../gio/gio-tool.c:234 +msgid "Create directories" +msgstr "Lag kataloger" + +#: ../gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "OvervÃ¥k filer og kataloger for endringer" + +#: ../gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "Monter eller avmonter lokasjoner" + +#: ../gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "Flytt en eller flere filer" + +#: ../gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "Ã…pne filer med forvalgt program" + +#: ../gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "Endre navn pÃ¥ en fil" + +#: ../gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "Slett en eller flere filer" + +#: ../gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "Les fra standard inndata og lagre" + +#: ../gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "Sett en filattributt" + +#: ../gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "Flytt filer eller kataloger til papirkurven" + +#: ../gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "Lister innholdet av lokasjoner i et tre" + +#: ../gio/gio-tool.c:246 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Bruk %s for Ã¥ fÃ¥ detaljert hjelp.\n" + +#: ../gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Feil under skriving til standard utdata" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-cat.c:133 ../gio/gio-tool-info.c:282 +#: ../gio/gio-tool-list.c:165 ../gio/gio-tool-mkdir.c:48 +#: ../gio/gio-tool-monitor.c:37 ../gio/gio-tool-monitor.c:39 +#: ../gio/gio-tool-monitor.c:41 ../gio/gio-tool-monitor.c:43 +#: ../gio/gio-tool-monitor.c:203 ../gio/gio-tool-mount.c:1141 +#: ../gio/gio-tool-open.c:113 ../gio/gio-tool-remove.c:48 +#: ../gio/gio-tool-rename.c:45 ../gio/gio-tool-set.c:89 +#: ../gio/gio-tool-trash.c:81 ../gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOKASJON" + +#: ../gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "SlÃ¥ sammen filer og skriv til standard utdata." + +#: ../gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: ../gio/gio-tool-cat.c:162 ../gio/gio-tool-info.c:313 +#: ../gio/gio-tool-mkdir.c:76 ../gio/gio-tool-monitor.c:228 +#: ../gio/gio-tool-open.c:139 ../gio/gio-tool-remove.c:72 +msgid "No locations given" +msgstr "Ingen lokasjoner oppgitt" + +#: ../gio/gio-tool-copy.c:42 ../gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ingen mÃ¥lkatalog" + +#: ../gio/gio-tool-copy.c:43 ../gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Vis fremdrift" + +#: ../gio/gio-tool-copy.c:44 ../gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Spør før overskriving" + +#: ../gio/gio-tool-copy.c:45 +msgid "Preserve all attributes" +msgstr "Behold alle attributter" + +#: ../gio/gio-tool-copy.c:46 ../gio/gio-tool-move.c:41 +#: ../gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Ta sikkerhetskopi av eksisterende mÃ¥lfiler" + +#: ../gio/gio-tool-copy.c:47 +msgid "Never follow symbolic links" +msgstr "Aldri følg symbolske lenker" + +#: ../gio/gio-tool-copy.c:72 ../gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%s av %s er overført (%s/s)" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "KILDE" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +#: ../gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "MÃ…L" + +#: ../gio/gio-tool-copy.c:103 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopier en eller flere filer fra KILDE til MÃ…L." + +#: ../gio/gio-tool-copy.c:105 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: ../gio/gio-tool-copy.c:147 +#, c-format +msgid "Destination %s is not a directory" +msgstr "MÃ¥l %s er ikke en katalog" + +#: ../gio/gio-tool-copy.c:192 ../gio/gio-tool-move.c:185 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: overskriv «%s»? " + +#: ../gio/gio-tool-info.c:34 +msgid "List writable attributes" +msgstr "Vis skrivbare attributter" + +#: ../gio/gio-tool-info.c:35 +msgid "Get file system info" +msgstr "Hent informasjon om filsystem" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "The attributes to get" +msgstr "Attributter som skal hentes" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTTER" + +#: ../gio/gio-tool-info.c:37 ../gio/gio-tool-list.c:38 ../gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Aldri følg symbolske lenker" + +#: ../gio/gio-tool-info.c:75 +#, c-format +msgid "attributes:\n" +msgstr "attributter:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "vis navn: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "rediger navn: %s\n" + +#: ../gio/gio-tool-info.c:138 +#, c-format +msgid "name: %s\n" +msgstr "navn: %s\n" + +#: ../gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "type: %s\n" + +#: ../gio/gio-tool-info.c:151 +#, c-format +msgid "size: " +msgstr "størrelse: " + +#: ../gio/gio-tool-info.c:156 +#, c-format +msgid "hidden\n" +msgstr "skjult\n" + +#: ../gio/gio-tool-info.c:159 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: ../gio/gio-tool-info.c:228 +#, c-format +msgid "Settable attributes:\n" +msgstr "Attributter som kan settes:\n" + +#: ../gio/gio-tool-info.c:252 +#, c-format +msgid "Writable attribute namespaces:\n" +msgstr "NavneomrÃ¥der for skrivbar attributt:\n" + +#: ../gio/gio-tool-info.c:287 +msgid "Show information about locations." +msgstr "Vis informasjon om lokasjoner." + +#: ../gio/gio-tool-info.c:289 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#: ../gio/gio-tool-list.c:36 ../gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Vis skjulte filer" + +#: ../gio/gio-tool-list.c:37 +msgid "Use a long listing format" +msgstr "Bruk langt listeformat" + +#: ../gio/gio-tool-list.c:39 +msgid "Print full URIs" +msgstr "Skriv ut fulle URIer" + +#: ../gio/gio-tool-list.c:170 +msgid "List the contents of the locations." +msgstr "Vis innhold fra lokasjonene." + +#: ../gio/gio-tool-list.c:172 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: ../gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "HÃ…NDTERER" + +#: ../gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Hent eller sett hÃ¥ndterer for en MIME-type." + +#: ../gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: ../gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "MÃ¥ oppgi en enkelt MIME-type og kanskje en hÃ¥ndterer" + +#: ../gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Ingen forvalgte programmer for «%s»\n" + +#: ../gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Forvalgt program for «%s»: %s\n" + +#: ../gio/gio-tool-mime.c:127 +#, c-format +msgid "Registered applications:\n" +msgstr "Registrerte programmer:\n" + +#: ../gio/gio-tool-mime.c:129 +#, c-format +msgid "No registered applications\n" +msgstr "Ingen registrerte programmer\n" + +#: ../gio/gio-tool-mime.c:140 +#, c-format +msgid "Recommended applications:\n" +msgstr "Anbefalte programmer:\n" + +#: ../gio/gio-tool-mime.c:142 +#, c-format +msgid "No recommended applications\n" +msgstr "Ingen anbefalte programmer\n" + +#: ../gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Klarte ikke Ã¥ laste info for hÃ¥ndterer «%s»" + +#: ../gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Klarte ikke Ã¥ sette «%s» som forvalgt hÃ¥ndterer for «%s»: %s\n" + +#: ../gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Lag opphavsmapper" + +#: ../gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Lag kataloger." + +#: ../gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: ../gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "OvervÃ¥k en katalog (forvalg: avhenger av type)" + +#: ../gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "OvervÃ¥k en fil (forvalg: avhenger av type)" + +#: ../gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "OvervÃ¥k en fil direkte (merker endringer gjort via harde lenker)" + +#: ../gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "OvervÃ¥ker en fil direkte, men rapporterer ikke endringer" + +#: ../gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "Rapporter flytting og endring av navn som enkle slette- og opprettelseshendelser" + +#: ../gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Se etter monteringshendelser" + +#: ../gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "OvervÃ¥k filer eller kataloger for endringer." + +#: ../gio/gio-tool-mount.c:58 +msgid "Mount as mountable" +msgstr "Monter som monterbar" + +#: ../gio/gio-tool-mount.c:59 +msgid "Mount volume with device file" +msgstr "Monter volum med en enhetsfil" + +#: ../gio/gio-tool-mount.c:59 +msgid "DEVICE" +msgstr "ENHET" + +#: ../gio/gio-tool-mount.c:60 +msgid "Unmount" +msgstr "Avmonter" + +#: ../gio/gio-tool-mount.c:61 +msgid "Eject" +msgstr "Løs ut" + +#: ../gio/gio-tool-mount.c:62 +msgid "Unmount all mounts with the given scheme" +msgstr "Avmonter alle monteringspunkter med oppgitt schema" + +#: ../gio/gio-tool-mount.c:62 +msgid "SCHEME" +msgstr "SCHEMA" + +#: ../gio/gio-tool-mount.c:63 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Overse utestÃ¥ende filoperasjoner ved avmontering eller utløsing" + +#: ../gio/gio-tool-mount.c:64 +msgid "Use an anonymous user when authenticating" +msgstr "Bruk en anonym bruker ved autentisering" + +#. Translator: List here is a verb as in 'List all mounts' +#: ../gio/gio-tool-mount.c:66 +msgid "List" +msgstr "Vis" + +#: ../gio/gio-tool-mount.c:67 +msgid "Monitor events" +msgstr "OvervÃ¥k hendelser" + +#: ../gio/gio-tool-mount.c:68 +msgid "Show extra information" +msgstr "Vis ekstra informasjon" + +#: ../gio/gio-tool-mount.c:246 ../gio/gio-tool-mount.c:276 +msgid "Anonymous access denied" +msgstr "Anonym tilgang nektet" + +#: ../gio/gio-tool-mount.c:897 +#, c-format +msgid "Mounted %s at %s\n" +msgstr "Monterte %s under %s\n" + +#: ../gio/gio-tool-mount.c:950 +msgid "No volume for device file" +msgstr "Ingen volum for enhetsfil" + +#: ../gio/gio-tool-mount.c:1145 +msgid "Mount or unmount the locations." +msgstr "M not allowed inside <%s>" +msgstr "Element <%s> er ikke tillatt inne i <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> er ikke tillatt pÃ¥ toppnivÃ¥" + +#: ../gio/glib-compile-resources.c:237 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Filen %s finnes flere ganger i ressursen" + +#: ../gio/glib-compile-resources.c:248 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Klarte ikke Ã¥ finne «%s» i noen kildekatalog" + +#: ../gio/glib-compile-resources.c:259 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Klarte ikke Ã¥ finne «%s» i aktiv katalog" + +#: ../gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Ukjente flagg for preprosessering «%s»" + +#: ../gio/glib-compile-resources.c:308 ../gio/glib-compile-resources.c:354 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "Klarte ikke Ã¥ opprette midlertidig fil: %s" + +#: ../gio/glib-compile-resources.c:382 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Feil ved lesing av fil %s: %s" + +#: ../gio/glib-compile-resources.c:402 +#, c-format +msgid "Error compressing file %s" +msgstr "Feil ved komprimering av fil %s" + +#: ../gio/glib-compile-resources.c:469 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "tekst kan ikke forekomme inne i <%s>" + +#: ../gio/glib-compile-resources.c:664 ../gio/glib-compile-schemas.c:2067 +msgid "Show program version and exit" +msgstr "Vis programmets versjon og avslutt" + +#: ../gio/glib-compile-resources.c:665 +msgid "name of the output file" +msgstr "navn pÃ¥ utdatafil" + +#: ../gio/glib-compile-resources.c:666 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "Kataloger filene skal leses fra (aktiv katalog er forvalgt)" + +#: ../gio/glib-compile-resources.c:666 ../gio/glib-compile-schemas.c:2068 +#: ../gio/glib-compile-schemas.c:2096 +msgid "DIRECTORY" +msgstr "KATALOG" + +#: ../gio/glib-compile-resources.c:667 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Lag utdata i formatet som er valgt for mÃ¥lets filtype" + +#: ../gio/glib-compile-resources.c:668 +msgid "Generate source header" +msgstr "Lag hode for kildekode" + +#: ../gio/glib-compile-resources.c:669 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "Lag kildekode som skal brukes til Ã¥ lenke inn ressursfilen i din kode" + +#: ../gio/glib-compile-resources.c:670 +msgid "Generate dependency list" +msgstr "Lag listet med avhengigheter" + +#: ../gio/glib-compile-resources.c:671 +msgid "name of the dependency file to generate" +msgstr "navn pÃ¥ avhengighetsfil som skal lages" + +#: ../gio/glib-compile-resources.c:672 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: ../gio/glib-compile-resources.c:673 +msgid "Don’t automatically create and register resource" +msgstr "Ikke lag og registrer ressursen automatisk" + +#: ../gio/glib-compile-resources.c:674 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ikke ekporter funksjoner. Deklarer dem som G_GNUC_INTERNAL" + +#: ../gio/glib-compile-resources.c:675 +msgid "C identifier name used for the generated source code" +msgstr "Navn pÃ¥ C-identifikator som brukes for generert kildekode" + +#: ../gio/glib-compile-resources.c:701 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompiler en ressursspesifikasjon til en ressursfil.\n" +"Ressursspesifikasjonsfiler har type .gresource.xml,\n" +"og ressufsfilen har etternavn .gresource." + +#: ../gio/glib-compile-resources.c:723 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "Du mÃ¥ kun oppgi ett filnavn\n" + +#: ../gio/glib-compile-schemas.c:95 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "kallenavn mÃ¥ være minst 2 tegn" + +#: ../gio/glib-compile-schemas.c:106 +#, c-format +msgid "Invalid numeric value" +msgstr "Ugyldig numerisk verdi" + +#: ../gio/glib-compile-schemas.c:114 +#, c-format +msgid " already specified" +msgstr " er allerede spesifisert" + +#: ../gio/glib-compile-schemas.c:122 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' er allerede oppgitt" + +#: ../gio/glib-compile-schemas.c:136 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: ../gio/glib-compile-schemas.c:161 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> mÃ¥ inneholde minst en " + +#: ../gio/glib-compile-schemas.c:315 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> finnes ikke i oppgitt omrÃ¥de" + +#: ../gio/glib-compile-schemas.c:327 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:333 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:339 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:373 +msgid " already specified for this key" +msgstr " er allerede oppgitt for denne nøkkelen" + +#: ../gio/glib-compile-schemas.c:391 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: ../gio/glib-compile-schemas.c:408 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: ../gio/glib-compile-schemas.c:433 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: ../gio/glib-compile-schemas.c:441 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: ../gio/glib-compile-schemas.c:453 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: ../gio/glib-compile-schemas.c:475 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Klarte ikke Ã¥ tolke verdi av type «%s»: " + +#: ../gio/glib-compile-schemas.c:492 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:501 +msgid " already specified for this key" +msgstr " allerede oppgitt for denne nøkkelen" + +#: ../gio/glib-compile-schemas.c:513 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ikke tillatt for nøkler av type «%s»" + +#: ../gio/glib-compile-schemas.c:529 +#, c-format +msgid " already given" +msgstr " allerede oppgitt" + +#: ../gio/glib-compile-schemas.c:544 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: ../gio/glib-compile-schemas.c:558 +msgid " already specified for this key" +msgstr " er allerede oppgitt for denne nøkkelen" + +#: ../gio/glib-compile-schemas.c:562 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: ../gio/glib-compile-schemas.c:581 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: ../gio/glib-compile-schemas.c:587 +#, c-format +msgid " given when was already given" +msgstr "" + +#: ../gio/glib-compile-schemas.c:595 +#, c-format +msgid " already specified" +msgstr " er allerede spesifisert" + +#: ../gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "alias target «%s» er ikke i opplistet type" + +#: ../gio/glib-compile-schemas.c:606 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:621 +#, c-format +msgid " must contain at least one " +msgstr " mÃ¥ inneholde minst ett " + +#: ../gio/glib-compile-schemas.c:786 +msgid "Empty names are not permitted" +msgstr "Tomme navn er ikke tillatt" + +#: ../gio/glib-compile-schemas.c:796 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Ugyldig navn «%s»: navn mÃ¥ starte med liten bokstav" + +#: ../gio/glib-compile-schemas.c:808 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Ugyldig navn «%s»: ugyldig tegn «%c»; kun smÃ¥ bokstaver, tall og bindestrek " +"(«-») er tillatt" + +#: ../gio/glib-compile-schemas.c:817 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Ugyldig navn «%s»: to etterfølgende bindestreker («--») er ikke tillatt" + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Ugyldig navn «%s»: siste tegn kan ikke være en bindestrek («-»)" + +#: ../gio/glib-compile-schemas.c:834 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Ugyldig navn «%s»: maksimal lengde er 1024" + +#: ../gio/glib-compile-schemas.c:904 +#, c-format +msgid " already specified" +msgstr " allerede oppgitt" + +#: ../gio/glib-compile-schemas.c:930 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Kan ikke legge til nøkler i et «list-of»-schema" + +#: ../gio/glib-compile-schemas.c:941 +#, c-format +msgid " already specified" +msgstr " allerede oppgitt" + +#: ../gio/glib-compile-schemas.c:959 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" overskygger i ; bruk " +" for Ã¥ endre verdien" + +#: ../gio/glib-compile-schemas.c:970 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Eksakt en av 'type', 'enum' eller 'flags' mÃ¥ oppgis som en attributt for " +"" + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'>ikke definert ennÃ¥." + +#: ../gio/glib-compile-schemas.c:1004 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Ugyldig GVariant-typestreng «%s»" + +#: ../gio/glib-compile-schemas.c:1034 +msgid " given but schema isn’t extending anything" +msgstr " ble gitt men schema utvider ingenting" + +#: ../gio/glib-compile-schemas.c:1047 +#, c-format +msgid "No to override" +msgstr "Ingen Ã¥ overstyre" + +#: ../gio/glib-compile-schemas.c:1055 +#, c-format +msgid " already specified" +msgstr " allerede oppgitt" + +#: ../gio/glib-compile-schemas.c:1128 +#, c-format +msgid " already specified" +msgstr " allerede oppgitt" + +#: ../gio/glib-compile-schemas.c:1140 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " utvider et schema som ikke eksisterer ennÃ¥ «%s»" + +#: ../gio/glib-compile-schemas.c:1156 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " er en liste med schema som ikke eksisterer ennÃ¥ «%s»" + +#: ../gio/glib-compile-schemas.c:1164 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Kan ikke være en liste av et schema med en sti" + +#: ../gio/glib-compile-schemas.c:1174 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Kan ikke utvide et schema med en sti" + +#: ../gio/glib-compile-schemas.c:1184 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" er en liste som utvider som ikke er en " +"liste" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" utvider men «%s» " +"utvider ikke «%s»" + +#: ../gio/glib-compile-schemas.c:1211 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Hvis en sti oppgis mÃ¥ denne begynne med «slash»" + +#: ../gio/glib-compile-schemas.c:1218 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Stien for en liste mÃ¥ slutte med «:/»" + +#: ../gio/glib-compile-schemas.c:1227 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1257 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> er allerede spesifisert" + +#: ../gio/glib-compile-schemas.c:1407 ../gio/glib-compile-schemas.c:1423 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Kun ett <%s>-element er tillatt inne i <%s>" + +#: ../gio/glib-compile-schemas.c:1505 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> er ikke tillatt pÃ¥ toppnivÃ¥" + +#: ../gio/glib-compile-schemas.c:1523 +msgid "Element is required in " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1613 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Tekst kan ikke forekomme inne i <%s>" + +#: ../gio/glib-compile-schemas.c:1681 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1820 ../gio/glib-compile-schemas.c:1894 +#: ../gio/glib-compile-schemas.c:1970 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict ble oppgitt; avslutter.\n" + +#: ../gio/glib-compile-schemas.c:1830 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "Hele filen ble ignorert.\n" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Ignorerer denne filen.\n" + +#: ../gio/glib-compile-schemas.c:1930 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "Ingen nøkkel «%s» i skjema «%s» som oppgitt i overstyringsfil «%s»" + +#: ../gio/glib-compile-schemas.c:1936 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2022 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; ignorerer overstyring for denne nøkkelen.\n" + +#: ../gio/glib-compile-schemas.c:1940 ../gio/glib-compile-schemas.c:1998 +#: ../gio/glib-compile-schemas.c:2026 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " og --strict ble oppgitt; avslutter.\n" + +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"feil ved lesing av nøkkel «%s» i skjema «%s» som oppgitt i overstyringsfil " +"«%s»: %s. " + +#: ../gio/glib-compile-schemas.c:1966 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "Ignorerer overstyring for denne nøkkelen.\n" + +#: ../gio/glib-compile-schemas.c:1984 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"overstyring for nøkkel «%s» i skjema «%s» i overstyringsfil «%s» er utenfor " +"omrÃ¥det som er oppgitt i skjema" + +#: ../gio/glib-compile-schemas.c:2012 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"overstyring for nøkkel «%s» i skjema «%s» i overstyringsfil «%s» er ikke i " +"listen med gyldige valg" + +#: ../gio/glib-compile-schemas.c:2068 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled filen lagres her" + +#: ../gio/glib-compile-schemas.c:2069 +msgid "Abort on any errors in schemas" +msgstr "Avbryt ved feil i schema" + +#: ../gio/glib-compile-schemas.c:2070 +msgid "Do not write the gschema.compiled file" +msgstr "Ikke skriv filen gschema.compiled" + +#: ../gio/glib-compile-schemas.c:2071 +msgid "Do not enforce key name restrictions" +msgstr "Ikke sett restriksjoner pÃ¥ navn pÃ¥ nøkler" + +#: ../gio/glib-compile-schemas.c:2099 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompiler alle GSettings-skjemafiler til et mellomlager for skjema.\n" +"Skjemafiler mÃ¥ ha type .gschema.xml, og mellomlagerfilen\n" +"kalles gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:2120 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "Du mÃ¥ kun oppgi navn pÃ¥ én katalog\n" + +#: ../gio/glib-compile-schemas.c:2162 +#, c-format +msgid "No schema files found: " +msgstr "Ingen schema-filer funnet: " + +#: ../gio/glib-compile-schemas.c:2165 +#, c-format +msgid "doing nothing.\n" +msgstr "gjør ingenting.\n" + +#: ../gio/glib-compile-schemas.c:2168 +#, c-format +msgid "removed existing output file.\n" +msgstr "fjernet eksisterende utdatafil.\n" + +#: ../gio/glocalfile.c:643 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "Ugyldig filnavn %s" + +#: ../gio/glocalfile.c:1039 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Feil under lesing av informasjon om filsystem %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: ../gio/glocalfile.c:1178 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Fant ikke omsluttende monteringspunkt for fil %s" + +#: ../gio/glocalfile.c:1201 +msgid "Can’t rename root directory" +msgstr "Kan ikke endre navn pÃ¥ rotkatalogen" + +#: ../gio/glocalfile.c:1219 ../gio/glocalfile.c:1242 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Feil ved endring av navn pÃ¥ fil %s: %s" + +#: ../gio/glocalfile.c:1226 +msgid "Can’t rename file, filename already exists" +msgstr "Kan ikke endre navn pÃ¥ filen. Filnavnet eksisterer allerede" + +#: ../gio/glocalfile.c:1239 ../gio/glocalfile.c:2256 ../gio/glocalfile.c:2284 +#: ../gio/glocalfile.c:2441 ../gio/glocalfileoutputstream.c:551 +msgid "Invalid filename" +msgstr "Ugyldig filnavn" + +#: ../gio/glocalfile.c:1407 ../gio/glocalfile.c:1422 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Feil under Ã¥pning av fil %s: %s" + +#: ../gio/glocalfile.c:1547 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Feil ved fjerning av fil %s: %s" + +#: ../gio/glocalfile.c:1931 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Feil ved plassering av fil %s i papirkurv : %s" + +#: ../gio/glocalfile.c:1954 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Kan ikke legge katalog %s i papirkurven: %s" + +#: ../gio/glocalfile.c:1974 +#, fuzzy, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Kan ikke finne toppnivÃ¥ for papirkurv" + +#: ../gio/glocalfile.c:2053 ../gio/glocalfile.c:2073 +#, c-format +msgid "Unable to find or create trash directory for %s" +msgstr "Kan ikke finne eller opprette mappe for papirkurv for %s" + +#: ../gio/glocalfile.c:2108 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Kan ikke opprette informasjonsfil for papirkurv for %s: %s" + +#: ../gio/glocalfile.c:2167 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Kan ikke legge fil %s i papirkurven pÃ¥ tvers av filsystemgrenser" + +#: ../gio/glocalfile.c:2171 ../gio/glocalfile.c:2227 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Kan ikke legge fil %s i papirkurven: %s" + +#: ../gio/glocalfile.c:2233 +#, c-format +msgid "Unable to trash file %s" +msgstr "Kan ikke legge fil %s i papirkurven" + +#: ../gio/glocalfile.c:2259 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Feil under oppretting av katalog %s: %s" + +#: ../gio/glocalfile.c:2288 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Filsystemet støtter ikke symbolske lenker" + +#: ../gio/glocalfile.c:2291 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Feil ved oppretting av symbolsk lenke %s: %s" + +#: ../gio/glocalfile.c:2297 ../glib/gfileutils.c:2101 +msgid "Symbolic links not supported" +msgstr "Symbolske lenker er ikke støttet" + +#: ../gio/glocalfile.c:2352 ../gio/glocalfile.c:2387 ../gio/glocalfile.c:2444 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Feil under flytting av fil %s: %s" + +#: ../gio/glocalfile.c:2375 +msgid "Can’t move directory over directory" +msgstr "Kan ikke flytte katalog over katalog" + +#: ../gio/glocalfile.c:2401 ../gio/glocalfileoutputstream.c:935 +#: ../gio/glocalfileoutputstream.c:949 ../gio/glocalfileoutputstream.c:964 +#: ../gio/glocalfileoutputstream.c:981 ../gio/glocalfileoutputstream.c:995 +msgid "Backup file creation failed" +msgstr "Oppretting av sikkerhetskopi feilet" + +#: ../gio/glocalfile.c:2420 +#, c-format +msgid "Error removing target file: %s" +msgstr "Feil under fjerning av mÃ¥lfil: %s" + +#: ../gio/glocalfile.c:2434 +msgid "Move between mounts not supported" +msgstr "Flytting mellom monteringspunkter er ikke støttet" + +#: ../gio/glocalfile.c:2625 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Kunne ikke bestemme diskbruk for %s: %s" + +#: ../gio/glocalfileinfo.c:742 +msgid "Attribute value must be non-NULL" +msgstr "Attributtverdi mÃ¥ ikke være NULL" + +#: ../gio/glocalfileinfo.c:749 +msgid "Invalid attribute type (string expected)" +msgstr "Ugyldig type attributt (streng forventet)" + +#: ../gio/glocalfileinfo.c:756 +msgid "Invalid extended attribute name" +msgstr "Ugyldig navn pÃ¥ utvidet attributt" + +#: ../gio/glocalfileinfo.c:796 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Feil under setting av utvidet attributt «%s»: %s" + +#: ../gio/glocalfileinfo.c:1604 +msgid " (invalid encoding)" +msgstr " (ugyldig koding)" + +#: ../gio/glocalfileinfo.c:1773 ../gio/glocalfileoutputstream.c:813 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Feil ved henting av informasjon for fil «%s»: %s" + +#: ../gio/glocalfileinfo.c:2031 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Feil ved henting av informasjon om fildeskriptor: %s" + +#: ../gio/glocalfileinfo.c:2076 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ugyldig type attributt (uint32 forventet)" + +#: ../gio/glocalfileinfo.c:2094 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ugyldig type attributt (uint64 forventet)" + +#: ../gio/glocalfileinfo.c:2113 ../gio/glocalfileinfo.c:2132 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ugyldig type attributt (byte-streng forventet)" + +#: ../gio/glocalfileinfo.c:2177 +msgid "Cannot set permissions on symlinks" +msgstr "Kan ikke sette rettigheter pÃ¥ symbolske lenker" + +#: ../gio/glocalfileinfo.c:2193 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Feil ved setting av rettigheter: %s" + +#: ../gio/glocalfileinfo.c:2244 +#, c-format +msgid "Error setting owner: %s" +msgstr "Feil ved setting av eier: %s" + +#: ../gio/glocalfileinfo.c:2267 +msgid "symlink must be non-NULL" +msgstr "symbolsk lenke kan ikke være NULL" + +#: ../gio/glocalfileinfo.c:2277 ../gio/glocalfileinfo.c:2296 +#: ../gio/glocalfileinfo.c:2307 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Feil ved setting av symbolsk lenke: %s" + +#: ../gio/glocalfileinfo.c:2286 +msgid "Error setting symlink: file is not a symlink" +msgstr "Feil ved setting av symbolsk lenke: filen er ikke en symbolsk lenke" + +#: ../gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Feil ved setting av endrings- eller aksesstid: %s" + +#: ../gio/glocalfileinfo.c:2435 +msgid "SELinux context must be non-NULL" +msgstr "SELinux-kontekst kan ikke være NULL" + +#: ../gio/glocalfileinfo.c:2450 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Feil ved setting av SELinux-kontekst: %s" + +#: ../gio/glocalfileinfo.c:2457 +msgid "SELinux is not enabled on this system" +msgstr "SELinux er ikke slÃ¥tt pÃ¥ pÃ¥ dette systemet" + +#: ../gio/glocalfileinfo.c:2549 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Støtter ikke Ã¥ sette attributt %s" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:696 +#, c-format +msgid "Error reading from file: %s" +msgstr "Feil under lesing fra fil: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:458 ../gio/glocalfileoutputstream.c:1013 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Feil under søking i fil: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:248 +#: ../gio/glocalfileoutputstream.c:342 +#, c-format +msgid "Error closing file: %s" +msgstr "Feil under lukking av fil: %s" + +#: ../gio/glocalfilemonitor.c:840 +msgid "Unable to find default local file monitor type" +msgstr "Kan ikke finne forvalgt lokal filovervÃ¥kingstype" + +#: ../gio/glocalfileoutputstream.c:196 ../gio/glocalfileoutputstream.c:228 +#: ../gio/glocalfileoutputstream.c:717 +#, c-format +msgid "Error writing to file: %s" +msgstr "Feil under skriving til fil: %s" + +#: ../gio/glocalfileoutputstream.c:275 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Feil ved fjerning av gammel sikkerhetskopi av lenke: %s" + +#: ../gio/glocalfileoutputstream.c:289 ../gio/glocalfileoutputstream.c:302 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Feil under oppretting av sikkerhetskopi: %s" + +#: ../gio/glocalfileoutputstream.c:320 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Feil ved endring av navn pÃ¥ midlertidig fil: %s" + +#: ../gio/glocalfileoutputstream.c:504 ../gio/glocalfileoutputstream.c:1064 +#, c-format +msgid "Error truncating file: %s" +msgstr "Feil under avkorting av fil: %s" + +#: ../gio/glocalfileoutputstream.c:557 ../gio/glocalfileoutputstream.c:795 +#: ../gio/glocalfileoutputstream.c:1045 ../gio/gsubprocess.c:380 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Feil under Ã¥pning av fil «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:826 +msgid "Target file is a directory" +msgstr "MÃ¥lfilen er en katalog" + +#: ../gio/glocalfileoutputstream.c:831 +msgid "Target file is not a regular file" +msgstr "MÃ¥lfilen er ikke en vanlig fil" + +#: ../gio/glocalfileoutputstream.c:843 +msgid "The file was externally modified" +msgstr "Filen ble endret eksternt" + +#: ../gio/glocalfileoutputstream.c:1029 +#, c-format +msgid "Error removing old file: %s" +msgstr "Feil ved fjerning av gammel fil: %s" + +#: ../gio/gmemoryinputstream.c:474 ../gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Ugyldig GSeekType oppgitt" + +#: ../gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Ugyldig søkeforespørsel" + +#: ../gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Kan ikke avkorte GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Kan ikke endre størrelse pÃ¥ utdatastrøm for minne" + +#: ../gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Klarte ikke Ã¥ endre størrelse pÃ¥ utdatastrøm for minne" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Mengden minne som kreves for Ã¥ prosessere skriveoperasjonen er større enn " +"tilgjengelig adresseomrÃ¥de" + +#: ../gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Forespurt søk før begynnelsen pÃ¥ strømmen" + +#: ../gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Forespurt søk forbi slutten pÃ¥ strømmen" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:396 +msgid "mount doesn’t implement “unmountâ€" +msgstr "monteringspunkt implementerer ikke «unmount»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:472 +msgid "mount doesn’t implement “ejectâ€" +msgstr "monteringspunkt implementerer ikke «eject»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:550 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"monteringspunkt implementerer ikke «unmount» eller «unmount_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:635 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"monteringspunkt implementerer ikke «eject» eller «eject_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:723 +msgid "mount doesn’t implement “remountâ€" +msgstr "monteringspunkt implementerer ikke «remount»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:805 +msgid "mount doesn’t implement content type guessing" +msgstr "monteringspunkt implementerer ikke gjetting av innholdstype" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:892 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "monteringspunkt implementerer ikke synkron gjetting av innholdstype" + +#: ../gio/gnetworkaddress.c:378 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Vertsnavn «%s» inneholder «[» men ikke «]»" + +#: ../gio/gnetworkmonitorbase.c:206 ../gio/gnetworkmonitorbase.c:310 +msgid "Network unreachable" +msgstr "Nettverk kan ikke nÃ¥s" + +#: ../gio/gnetworkmonitorbase.c:244 ../gio/gnetworkmonitorbase.c:274 +msgid "Host unreachable" +msgstr "Kan ikke nÃ¥ vert" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Kunne ikke lage nettverksovervÃ¥ker: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "Kunne ikke lage nettverksovervÃ¥ker: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "Kunne ikke hente nettverksstatus: " + +#: ../gio/gnetworkmonitornm.c:329 +#, c-format +msgid "NetworkManager version too old" +msgstr "For gammel versjon av NetworkManager" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:560 +msgid "Output stream doesn’t implement write" +msgstr "Utdatastrømmen implementerer ikke skriving" + +#: ../gio/goutputstream.c:521 ../gio/goutputstream.c:1224 +msgid "Source stream is already closed" +msgstr "Kildestrømmen er allerede lukket" + +#: ../gio/gresolver.c:342 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Feil under oppslag av «%s»: %s" + +#: ../gio/gresource.c:606 ../gio/gresource.c:857 ../gio/gresource.c:874 +#: ../gio/gresource.c:998 ../gio/gresource.c:1070 ../gio/gresource.c:1143 +#: ../gio/gresource.c:1213 ../gio/gresourcefile.c:453 +#: ../gio/gresourcefile.c:576 ../gio/gresourcefile.c:713 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Ressurs ved «%s» eksisterer ikke" + +#: ../gio/gresource.c:771 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Ressursen ved «%s» kunne ikke dekomprimeres" + +#: ../gio/gresourcefile.c:709 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Ressurs ved «%s» er ikke en katalog" + +#: ../gio/gresourcefile.c:917 +msgid "Input stream doesn’t implement seek" +msgstr "Inndatastrøm implementerer ikke søk" + +#: ../gio/gresource-tool.c:494 +msgid "List sections containing resources in an elf FILE" +msgstr "Vis seksjoner som inneholder ressurser i en elf FIL" + +#: ../gio/gresource-tool.c:500 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Vis ressurser\n" +"Hvis SEKSJON oppgis skal kun ressurser i denne seksjonen vises\n" +"Hvis STI oppgis skal kun relevante ressurser vises" + +#: ../gio/gresource-tool.c:503 ../gio/gresource-tool.c:513 +msgid "FILE [PATH]" +msgstr "FIL [STI]" + +#: ../gio/gresource-tool.c:504 ../gio/gresource-tool.c:514 +#: ../gio/gresource-tool.c:521 +msgid "SECTION" +msgstr "SEKSJON" + +#: ../gio/gresource-tool.c:509 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Vis ressurser med detaljer\n" +"Hvis SEKSJON oppgis skal kun ressurser i denne seksjonen vises\n" +"Hvis STI oppgis vises kun relevante ressurser\n" +"Detaljer inkluderer seksjon, størrelse og komprimering" + +#: ../gio/gresource-tool.c:519 +msgid "Extract a resource file to stdout" +msgstr "Hent ut en ressursfil til stdout" + +#: ../gio/gresource-tool.c:520 +msgid "FILE PATH" +msgstr "STI TIL FIL" + +#: ../gio/gresource-tool.c:534 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Bruk:\n" +" gresource [--section SEKSJON] KOMMANDO [ARGUMENTER …]\n" +"\n" +"Kommandoer:\n" +" help Vis denne informasjonen\n" +" sections Vis ressursseksjoner\n" +" list Vis ressurser\n" +" details Vis ressurser med detaljer\n" +" extract Hent ut en ressurs\n" +"\n" +"Bruk «gresource help KOMMANDO» for Ã¥ fÃ¥ detaljert hjelp.\n" +"\n" + +#: ../gio/gresource-tool.c:548 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Bruk:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:555 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEKSJON Et valgfritt navn pÃ¥ en elf seksjon\n" + +#: ../gio/gresource-tool.c:559 ../gio/gsettings-tool.c:656 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMMANDO Valgfri kommando som skal forklares\n" + +#: ../gio/gresource-tool.c:565 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FIL En elf-fil. Binærfil eller delt bibliotek\n" + +#: ../gio/gresource-tool.c:568 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FIL En elf-fil - binær eller delt bibliotek\n" +" eller en kompilert ressursfil\n" + +#: ../gio/gresource-tool.c:572 +msgid "[PATH]" +msgstr "[STI]" + +#: ../gio/gresource-tool.c:574 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " STI En valgfri ressurssti - kan være ufullstendig\n" + +#: ../gio/gresource-tool.c:575 +msgid "PATH" +msgstr "STI" + +#: ../gio/gresource-tool.c:577 +msgid " PATH A resource path\n" +msgstr " STI En ressurssti\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#: ../gio/gsettings-tool.c:853 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Skjema «%s» finnes ikke\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Skjema «%s» er ikke omplasserbar (stien mÃ¥ ikke oppgis)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Skjema «%s» er omplasserbart (sti mÃ¥ oppgis)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "Stien som ble oppgitt er tom.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "Stien mÃ¥ starte med en skrÃ¥strek (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "Stien mÃ¥ slutte med skrÃ¥strek (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Sti mÃ¥ ikke inneholde to etterfølgende skrÃ¥streker (//)\n" + +#: ../gio/gsettings-tool.c:491 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "Oppgitt verdi er utenfor gyldig omrÃ¥de\n" + +#: ../gio/gsettings-tool.c:498 +#, c-format +msgid "The key is not writable\n" +msgstr "Nøkkelen er er ikke skrivbar\n" + +#: ../gio/gsettings-tool.c:534 +msgid "List the installed (non-relocatable) schemas" +msgstr "Vis installerte (ikke-flyttbare) schema" + +#: ../gio/gsettings-tool.c:540 +msgid "List the installed relocatable schemas" +msgstr "Vis installerte flyttbare schema" + +#: ../gio/gsettings-tool.c:546 +msgid "List the keys in SCHEMA" +msgstr "Vis nøklene i SCHEMA" + +#: ../gio/gsettings-tool.c:547 ../gio/gsettings-tool.c:553 +#: ../gio/gsettings-tool.c:596 +msgid "SCHEMA[:PATH]" +msgstr "SKJEMA[:STI]" + +#: ../gio/gsettings-tool.c:552 +msgid "List the children of SCHEMA" +msgstr "Vis barn av SCHEMA" + +#: ../gio/gsettings-tool.c:558 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Vis nøkler og verdier rekursivt\n" +"Vis alle nøkler hvis SKJEMA ikke oppgis\n" + +#: ../gio/gsettings-tool.c:560 +msgid "[SCHEMA[:PATH]]" +msgstr "SKJEMA[:STI]" + +#: ../gio/gsettings-tool.c:565 +msgid "Get the value of KEY" +msgstr "Hent verdi for NØKKEL" + +#: ../gio/gsettings-tool.c:566 ../gio/gsettings-tool.c:572 +#: ../gio/gsettings-tool.c:578 ../gio/gsettings-tool.c:590 +#: ../gio/gsettings-tool.c:602 +msgid "SCHEMA[:PATH] KEY" +msgstr "SKJEMA[:STI] NØKKEL" + +#: ../gio/gsettings-tool.c:571 +msgid "Query the range of valid values for KEY" +msgstr "Spør pÃ¥ gyldig verdiomrÃ¥de for NØKKEL" + +#: ../gio/gsettings-tool.c:577 +msgid "Query the description for KEY" +msgstr "Spør pÃ¥ beskrivelse for NØKKEL" + +#: ../gio/gsettings-tool.c:583 +msgid "Set the value of KEY to VALUE" +msgstr "Sett verdien for NØKKEL til VERDI" + +#: ../gio/gsettings-tool.c:584 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SKJEMA[:STI] NØKKEL VERDI" + +#: ../gio/gsettings-tool.c:589 +msgid "Reset KEY to its default value" +msgstr "Nullstill NØKKEL til forvalgt verdi" + +#: ../gio/gsettings-tool.c:595 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Nullstill alle nøkler i SKJEMA til sine forvalgte verdier" + +#: ../gio/gsettings-tool.c:601 +msgid "Check if KEY is writable" +msgstr "Sjekk om NØKKEL er skrivbar" + +#: ../gio/gsettings-tool.c:607 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"OvervÃ¥k endringer i NØKKEL.\n" +"Hvis ingen NØKKEL oppgis overvÃ¥kes alle nøkler i SKJEMA.\n" +"Bruk Ctrl+C for Ã¥ stoppe overvÃ¥king.\n" + +#: ../gio/gsettings-tool.c:610 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:STI] [NØKKEL]" + +#: ../gio/gsettings-tool.c:622 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Bruk:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMAKATALOG KOMMANDO [ARGUMENTER …]\n" +"\n" +"Kommandoer\n" +" help Vis denne informasjonen\n" +" list-schemas Vis liste med installerte skjema\n" +" list-relocatable-schemas Vis liste med omplasserbare skjema\n" +" list-keys Vis liste med nøkler i et skjema\n" +" list-children Vis liste med barn i et skjema\n" +" list-recursively Vis liste med nøkler og verdier rekursivt\n" +" range Spør etter omrÃ¥de for en nøkkel\n" +" describe Spør pÃ¥ beskrivelse for nøkkel\n" +" get Hent verdi for en nøkkel\n" +" set Sett verdi for en nøkkel\n" +" reset Nullstill verdi for en nøkkel\n" +" reset-recursively Nullstill alle verdier i et gitt skjema\n" +" writable Sjekk om en nøkkel er skrivbar\n" +" monitor OvervÃ¥k endringer\n" +"\n" +"Bruk «gsettings help KOMMANDO» for Ã¥ fÃ¥ detaljert hjelp.\n" +"\n" + +#: ../gio/gsettings-tool.c:646 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Bruk:\n" +" gsettings [--schemadir SCHEMAKATALOG] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:652 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMAKATALOG en katalog for søk etter ekstra schemas\n" + +#: ../gio/gsettings-tool.c:660 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +"Argumenter:\n" +" SCHEMA Id for schema\n" +" PATH Sti, for schema som kan relokeres\n" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The (optional) key within the schema\n" +msgstr " NØKKEL Valgfri nøkkel i schema\n" + +#: ../gio/gsettings-tool.c:669 +msgid " KEY The key within the schema\n" +msgstr " NØKKEL Nøkkel i schema\n" + +#: ../gio/gsettings-tool.c:673 +msgid " VALUE The value to set\n" +msgstr " VERDI Verdi som skal settes\n" + +#: ../gio/gsettings-tool.c:728 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Kunne ikke laste skjema fra %s: %s\n" + +#: ../gio/gsettings-tool.c:740 +#, c-format +msgid "No schemas installed\n" +msgstr "Ingen schema-filer installert\n" + +#: ../gio/gsettings-tool.c:811 +#, c-format +msgid "Empty schema name given\n" +msgstr "Tomt navn pÃ¥ schema oppgitt\n" + +#: ../gio/gsettings-tool.c:866 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Nøkkel «%s» finnes ikke\n" + +#: ../gio/gsocket.c:384 +msgid "Invalid socket, not initialized" +msgstr "Ugyldig plugg, ikke initiert" + +#: ../gio/gsocket.c:391 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Ugyldig plugg, initiering feilet pga: %s" + +#: ../gio/gsocket.c:399 +msgid "Socket is already closed" +msgstr "Pluggen er allerede lukket" + +#: ../gio/gsocket.c:414 ../gio/gsocket.c:2995 ../gio/gsocket.c:4205 +#: ../gio/gsocket.c:4263 +msgid "Socket I/O timed out" +msgstr "Tidsavbrudd for I/U mot plugg" + +#: ../gio/gsocket.c:546 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "lager GSocket fra fd: %s" + +#: ../gio/gsocket.c:575 ../gio/gsocket.c:629 ../gio/gsocket.c:636 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Kunne ikke lage plugg: %s" + +#: ../gio/gsocket.c:629 +msgid "Unknown family was specified" +msgstr "Ukjent familie ble oppgitt" + +#: ../gio/gsocket.c:636 +msgid "Unknown protocol was specified" +msgstr "Ukjent protokoll ble oppgitt" + +#: ../gio/gsocket.c:1127 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Kan ikke bruke datagramoperasjoner pÃ¥ en plugg som ikke er av type datagram." + +#: ../gio/gsocket.c:1144 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "Kan ikke bruke datagramoperasjoner pÃ¥ en plugg med tidsavbrudd satt." + +#: ../gio/gsocket.c:1948 +#, c-format +msgid "could not get local address: %s" +msgstr "kunne ikke hente lokal adresse: %s" + +#: ../gio/gsocket.c:1991 +#, c-format +msgid "could not get remote address: %s" +msgstr "kunne ikke hente ekstern adresse: %s" + +#: ../gio/gsocket.c:2057 +#, c-format +msgid "could not listen: %s" +msgstr "kunne ikke lytte: %s" + +#: ../gio/gsocket.c:2156 +#, c-format +msgid "Error binding to address: %s" +msgstr "Feil ved binding til adresse: %s" + +#: ../gio/gsocket.c:2214 ../gio/gsocket.c:2251 ../gio/gsocket.c:2361 +#: ../gio/gsocket.c:2379 ../gio/gsocket.c:2449 ../gio/gsocket.c:2507 +#: ../gio/gsocket.c:2525 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Feil ved forsøk pÃ¥ Ã¥ bli med i multicast-gruppe: %s" + +#: ../gio/gsocket.c:2215 ../gio/gsocket.c:2252 ../gio/gsocket.c:2362 +#: ../gio/gsocket.c:2380 ../gio/gsocket.c:2450 ../gio/gsocket.c:2508 +#: ../gio/gsocket.c:2526 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Feil ved forsøk pÃ¥ Ã¥ forlate multicast-gruppe: %s" + +#: ../gio/gsocket.c:2216 +msgid "No support for source-specific multicast" +msgstr "Ingen støtte for kildespesifikk multicast" + +#: ../gio/gsocket.c:2363 +msgid "Unsupported socket family" +msgstr "Familie for plugg er ikke støttet" + +#: ../gio/gsocket.c:2381 +msgid "source-specific not an IPv4 address" +msgstr "kildespesifikk er ikke en IPv4 adresse" + +#: ../gio/gsocket.c:2399 ../gio/gsocket.c:2428 ../gio/gsocket.c:2475 +#, c-format +msgid "Interface not found: %s" +msgstr "Fant ikke grensesnitt: %s" + +#: ../gio/gsocket.c:2415 +#, c-format +msgid "Interface name too long" +msgstr "Navnet pÃ¥ grensesnittet er for langt" + +#: ../gio/gsocket.c:2451 +msgid "No support for IPv4 source-specific multicast" +msgstr "Ingen støtte for IPv4 kildespesifikk multicast" + +#: ../gio/gsocket.c:2509 +msgid "No support for IPv6 source-specific multicast" +msgstr "Ingen støtte for IPv6 kildespesifikk multicast" + +#: ../gio/gsocket.c:2718 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Feil ved godkjenning av tilkobling: %s" + +#: ../gio/gsocket.c:2839 +msgid "Connection in progress" +msgstr "Tilkobling pÃ¥gÃ¥r" + +#: ../gio/gsocket.c:2888 +msgid "Unable to get pending error: " +msgstr "Kan ikke hente utestÃ¥ende feil: " + +#: ../gio/gsocket.c:3058 +#, c-format +msgid "Error receiving data: %s" +msgstr "Feil ved mottak av data: %s" + +#: ../gio/gsocket.c:3253 +#, c-format +msgid "Error sending data: %s" +msgstr "Feil ved sending av data: %s" + +#: ../gio/gsocket.c:3440 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Kan ikke stenge ned plugg: %s" + +#: ../gio/gsocket.c:3521 +#, c-format +msgid "Error closing socket: %s" +msgstr "Feil ved lukking av plugg: %s" + +#: ../gio/gsocket.c:4198 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Venter pÃ¥ tilstand for plugg: %s" + +#: ../gio/gsocket.c:4672 ../gio/gsocket.c:4752 ../gio/gsocket.c:4930 +#, c-format +msgid "Error sending message: %s" +msgstr "Feil ved sending av melding: %s" + +#: ../gio/gsocket.c:4696 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage er ikke støttet pÃ¥ Windows" + +#: ../gio/gsocket.c:5149 ../gio/gsocket.c:5222 ../gio/gsocket.c:5448 +#, c-format +msgid "Error receiving message: %s" +msgstr "Feil ved mottak av melding: %s" + +#: ../gio/gsocket.c:5720 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Kunne ikke lese autentiseringsinformasjon for plugg: %s" + +#: ../gio/gsocket.c:5729 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials ikke implementert for dette OSet" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Kunne ikke koble til proxy-tjener %s: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "Kunne ikke koble til «%s»: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "Kunne ikke koble til: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "Ukjent feil ved tilkobling" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Proxy over annet enn TCP-forbindelser er ikke støttet." + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Mellomtjenerprotokoll «%s» er er ikke støttet." + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "Lytter er allerede lukket" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "Tillagt plugg er lukket" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 støtter ikke IPv6-adresse «%s»" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Brukernavn er for langt for SOCKSv4-protokollen" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Vertsnavn «%s» er for langt for SOCKSv4-protokollen" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Tjeneren er ikke en SOCKSv4-proxytjener." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Tilkobling gjennom SOCKSv4-tjener ble avvist" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Tjeneren er ikke en SOCKSv5-proxytjener." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCSv5-proxy krever autentisering." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5-proxy krever en autentiseringsmetode som ikke støttes av GLib." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Brukernavn eller passord er for langt for SOCKSv5-protokollen." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5-autentisering feilet pÃ¥ grunn av feil brukernavn eller passord." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Vertsnavn «%s» er for langt for SOCKSv5-protokollen" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5-proxytjener bruker ukjent adressetype." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Intern feil i SOCKSv5-proxytjener." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5-tilkobling tillates ikke av regelsett." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Vert kan ikke nÃ¥s via SOCKSv5-tjener." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Nettverk kan ikke nÃ¥s via SOCKSv5-proxy." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Tilkobling nektet via SOCKSv5-proxy." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5-proxy støtter ikke «connect»-kommando." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5-proxy støtter ikke oppgitt type adresse." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Ukjent feil i SOCKSv5-proxy." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Kan ikke hÃ¥ndtere versjon %d av GThemedIcon-koding" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "Ingen gyldige adresser ble funnet" + +#: ../gio/gthreadedresolver.c:213 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Feil under omvendt oppslag av «%s»: %s" + +#: ../gio/gthreadedresolver.c:549 ../gio/gthreadedresolver.c:628 +#: ../gio/gthreadedresolver.c:726 ../gio/gthreadedresolver.c:776 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Ingen DNS-oppføring av forespurt type for «%s»" + +#: ../gio/gthreadedresolver.c:554 ../gio/gthreadedresolver.c:731 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Midlertidig ute av stand til Ã¥ slÃ¥ opp «%s»" + +#: ../gio/gthreadedresolver.c:559 ../gio/gthreadedresolver.c:736 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Feil ved oppslag av «%s»" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Kunne ikke dekryptere PEM-kodet privat nøkkel" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "Fant ikke PEM-kodet privat nøkkel" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "Kunne ikke lese PEM-kodet privat nøkkel" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "Fant ikke PEM-kodet sertifikat" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "Kunne ikke lese PEM-kodet sertifikat" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Dette er siste sjanse til Ã¥ oppgi korrekt passord før tilgangen blir lÃ¥st." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: ../gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Passord har blitt oppgitt feil flere ganger, og tilgangen vil bli lÃ¥st hvis " +"det oppgis feil pÃ¥ nytt." + +#: ../gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Oppgitt passord er ikke korrekt." + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:563 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Ventet 1 kontrollmelding, fikk %d" +msgstr[1] "Ventet 1 kontrollmelding, fikk %d" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:575 +msgid "Unexpected type of ancillary data" +msgstr "Uventet type data" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Ventet en fd, men fikk %d\n" +msgstr[1] "Ventet en fd, men fikk %d\n" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Mottok ugyldig fd" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "Feil ved sending av pÃ¥loggingsinformasjon: " + +#: ../gio/gunixconnection.c:504 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Feil under sjekk om SO_PASSCRED er slÃ¥tt pÃ¥ for plugg: %s" + +#: ../gio/gunixconnection.c:520 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Feil under forsøk pÃ¥ Ã¥ slÃ¥ pÃ¥ SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:549 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Forventer Ã¥ lese en enkelt byte for mottak av pÃ¥loggingsinformasjon, men " +"leste null byte" + +#: ../gio/gunixconnection.c:589 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Forventet ikke kontrollmelding, men fikk %d" + +#: ../gio/gunixconnection.c:614 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Feil ved forsøk pÃ¥ Ã¥ slÃ¥ av SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:372 ../gio/gunixinputstream.c:393 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Feil under lesing fra fildeskriptor: %s" + +#: ../gio/gunixinputstream.c:426 ../gio/gunixoutputstream.c:411 +#: ../gio/gwin32inputstream.c:217 ../gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Feil under lukking av fildeskriptor: %s" + +#: ../gio/gunixmounts.c:2539 ../gio/gunixmounts.c:2592 +msgid "Filesystem root" +msgstr "Filsystemrot" + +#: ../gio/gunixoutputstream.c:358 ../gio/gunixoutputstream.c:378 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Feil under skriving til fildeskriptor: %s" + +#: ../gio/gunixsocketaddress.c:241 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Abstrakte UNIX domenepluggadresser er ikke støttet pÃ¥ dette systemet" + +#: ../gio/gvolume.c:437 +msgid "volume doesn’t implement eject" +msgstr "volumet implementerer ikke utløsing" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volumet implementerer ikke eject eller eject_with_operation" + +#: ../gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Feil under lesing fra hÃ¥ndtak: %s" + +#: ../gio/gwin32inputstream.c:232 ../gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Feil under lukking av hÃ¥ndtak: %s" + +#: ../gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Feil under skriving til hÃ¥ndtak: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Ikke nok minne" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Intern feil: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Trenger med inndata" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Ugyldige komprimerte data" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Lytteadresse" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Oversett. For kompatibilitet med GTestDbus" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Skriv ut adresse" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Skriv ut adresse i skallmodus" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Kjør en dbus-tjeneste" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "Feil argument\n" + +#: ../glib/gbookmarkfile.c:754 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Uventet attributt «%s» for element «%s»" + +#: ../glib/gbookmarkfile.c:765 ../glib/gbookmarkfile.c:836 +#: ../glib/gbookmarkfile.c:846 ../glib/gbookmarkfile.c:953 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Attributt «%s» i element «%s» ble ikke funnet" + +#: ../glib/gbookmarkfile.c:1123 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1252 ../glib/gbookmarkfile.c:1262 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Uventet etikett «%s», etikett «%s» forventet" + +#: ../glib/gbookmarkfile.c:1148 ../glib/gbookmarkfile.c:1162 +#: ../glib/gbookmarkfile.c:1230 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Uventet etikett «%s» i «%s»" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "Ingen gyldig bokmerkefil ble funnet i datakatalogene" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Et bokmerke eksisterer allerede for URI «%s»" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Ingen bokmerker funnet for URI «%s»" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Ingen MIME-type definert i bokmerke for URI «%s»" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Ingen private flagg er definert i bokmerke for URI «%s»" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Ingen grupper satt i bokmerke for URI «%s»" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Ingen programmer med navn «%s» har registrert et bokmerke for «%s»" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Feil under utvidelse av exec-linje «%s» med URI «%s»" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:862 ../glib/gutf8.c:1074 +#: ../glib/gutf8.c:1211 ../glib/gutf8.c:1315 +msgid "Partial character sequence at end of input" +msgstr "Ufullstendig tegnsekvens ved slutten pÃ¥ inndata" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Kan ikke konvertere \"fallback\" «%s» til tegnsett «%s»" + +#: ../glib/gconvert.c:1513 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI «%s» er ikke en absolutt URI som bruker skjema for filer" + +#: ../glib/gconvert.c:1523 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Lokal fil-URI «%s» kan ikke inneholde en «#»" + +#: ../glib/gconvert.c:1540 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI «%s» er ugyldig" + +#: ../glib/gconvert.c:1552 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Vertsnavnet for URI «%s» er ugyldig" + +#: ../glib/gconvert.c:1568 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Vertsnavnet for URI «%s» inneholder ugyldige escape-tegn" + +#: ../glib/gconvert.c:1640 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Stinavnet «%s» er ikke en absolutt sti" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e %b %H.%M.%S" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H.%M.%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%H.%M.%S" + +#: ../glib/gdatetime.c:225 +msgctxt "full month name" +msgid "January" +msgstr "Januar" + +#: ../glib/gdatetime.c:227 +msgctxt "full month name" +msgid "February" +msgstr "Februar" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "March" +msgstr "Mars" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "May" +msgstr "Mai" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "June" +msgstr "Juni" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "July" +msgstr "Juli" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "August" +msgstr "August" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "October" +msgstr "Oktober" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "December" +msgstr "Desember" + +#: ../glib/gdatetime.c:262 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: ../glib/gdatetime.c:264 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Des" + +#: ../glib/gdatetime.c:299 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Mandag" + +#: ../glib/gdatetime.c:301 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Tirsdag" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Onsdag" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Torsdag" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Fredag" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Lørdag" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Søndag" + +#: ../glib/gdatetime.c:326 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Man" + +#: ../glib/gdatetime.c:328 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Tir" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ons" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Tor" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Fre" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Lør" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Søn" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:355 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:358 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Feil under Ã¥pning av katalog «%s»: %s" + +#: ../glib/gfileutils.c:716 ../glib/gfileutils.c:808 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Kunne ikke allokere %lu byte til lest fil «%s»" +msgstr[1] "Kunne ikke allokere %lu bytes til lest fil «%s»" + +#: ../glib/gfileutils.c:733 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Feil ved lesing av fil «%s»: %s" + +#: ../glib/gfileutils.c:769 +#, c-format +msgid "File “%s†is too large" +msgstr "Fil «%s» er for stor" + +#: ../glib/gfileutils.c:833 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Klarte ikke Ã¥ lese fra fil «%s»: %s" + +#: ../glib/gfileutils.c:881 ../glib/gfileutils.c:953 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Klarte ikke Ã¥ Ã¥pne fil «%s»: %s" + +#: ../glib/gfileutils.c:893 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Klarte ikke Ã¥ hente attributter for fil «%s»: fstat() feilet: %s" + +#: ../glib/gfileutils.c:923 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Klarte ikke Ã¥ Ã¥pne fil «%s»: fdopen() feilet: %s" + +#: ../glib/gfileutils.c:1022 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Klarte ikke Ã¥ endre navn pÃ¥ fil «%s» til «%s»: g_rename() feilet: %s" + +#: ../glib/gfileutils.c:1057 ../glib/gfileutils.c:1564 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Klarte ikke Ã¥ opprette fil «%s»: %s" + +#: ../glib/gfileutils.c:1084 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Klarte ikke Ã¥ skrive fil «%s»: write() feilet: %s" + +#: ../glib/gfileutils.c:1127 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Klarte ikke Ã¥ skrive fil «%s»: fsync() feilet: %s" + +#: ../glib/gfileutils.c:1251 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Eksisterende fil «%s» kunne ikke fjernes: g_unlink() feilet: %s" + +#: ../glib/gfileutils.c:1530 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Mal «%s» er ugyldig, mÃ¥ ikke inneholde «%s»" + +#: ../glib/gfileutils.c:1543 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Mal «%s» inneholder ikke XXXXXX" + +#: ../glib/gfileutils.c:2079 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Klarte ikke Ã¥ lese symbolsk lenke «%s»: %s" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Kunne ikke Ã¥pne konverterer fra «%s» til «%s»: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Kan ikke utføre rÃ¥ avlesing i g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "Overflødig ikke-konvertert data i innlesingsbuffer" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "Kanalen terminerer i et oppdelt tegn" + +#: ../glib/giochannel.c:1925 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Kan ikke utføre rÃ¥ avlesing i g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:788 +msgid "Valid key file could not be found in search dirs" +msgstr "Gyldig nøkkelfil ble ikke funnet i søkemapper" + +#: ../glib/gkeyfile.c:825 +msgid "Not a regular file" +msgstr "Ikke en vanlig fil" + +#: ../glib/gkeyfile.c:1270 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Nøkkelfil inneholder linjen «%s» som ikke er et par med nøkkelverdier, " +"gruppe eller kommentar" + +#: ../glib/gkeyfile.c:1327 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ugyldig navn pÃ¥ gruppe: %s" + +#: ../glib/gkeyfile.c:1349 +msgid "Key file does not start with a group" +msgstr "Nøkkelfil starter ikke med en gruppe" + +#: ../glib/gkeyfile.c:1375 +#, c-format +msgid "Invalid key name: %s" +msgstr "Ugyldig navn pÃ¥ nøkkel: %s" + +#: ../glib/gkeyfile.c:1402 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Nøkkelfil inneholder ustøttet tegnkoding «%s»" + +#: ../glib/gkeyfile.c:1645 ../glib/gkeyfile.c:1818 ../glib/gkeyfile.c:3198 +#: ../glib/gkeyfile.c:3261 ../glib/gkeyfile.c:3391 ../glib/gkeyfile.c:3521 +#: ../glib/gkeyfile.c:3665 ../glib/gkeyfile.c:3894 ../glib/gkeyfile.c:3961 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Nøkkelfil har ikke gruppe «%s»" + +#: ../glib/gkeyfile.c:1773 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Nøkkelfilen har ikke nøkkel «%s» i gruppe «%s»" + +#: ../glib/gkeyfile.c:1935 ../glib/gkeyfile.c:2051 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Nøkkelfilen inneholder nøkkel «%s» med verdi «%s» som ikke er UTF-8" + +#: ../glib/gkeyfile.c:1955 ../glib/gkeyfile.c:2071 ../glib/gkeyfile.c:2440 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Nøkkelfilen inneholder nøkkel «%s» som har en verdi som ikke kan bli tolket." + +#: ../glib/gkeyfile.c:2658 ../glib/gkeyfile.c:3027 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Nøkkelfilen inneholder nøkkel «%s» i gruppe «%s» som har en verdi som ikke " +"kan bli tolket." + +#: ../glib/gkeyfile.c:2736 ../glib/gkeyfile.c:2813 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Nøkkel «%s» i gruppe «%s» har en verdi «%s» hvor %s var forventet" + +#: ../glib/gkeyfile.c:4201 +msgid "Key file contains escape character at end of line" +msgstr "Nøkkelfilen inneholder skiftetegn ved linjeslutt" + +#: ../glib/gkeyfile.c:4223 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Nøkkelfil inneholder ugyldig skiftesekvens «%s»" + +#: ../glib/gkeyfile.c:4367 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Vedi «%s» kan ikke tolkes som et tall." + +#: ../glib/gkeyfile.c:4381 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Heltallsverdi «%s» er utenfor gyldig omrÃ¥de" + +#: ../glib/gkeyfile.c:4414 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Verdi «%s» kan ikke tolkes som et flyttall." + +#: ../glib/gkeyfile.c:4453 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Verdi «%s» kan ikke tolkes som en bolsk verdi." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Klarte ikke Ã¥ hente attributter for fil «%s%s%s%s»: fstat() feilet: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Kunne ikke lese fil «%s%s%s%s» inn i minnet: mmap() feilet: %s" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Klarte ikke Ã¥ Ã¥pne fil «%s»: open() feilet: %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Feil pÃ¥ linje %d tegn %d: " + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Ugyldig UTF-8 kodet tekst i navn - ikke gyldig «%s»" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "«%s» er ikke et gyldig navn" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "«%s» er ikke et gyldig navn: «%c»" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "Feil pÃ¥ linje %d: %s" + +#: ../glib/gmarkup.c:675 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Feil under lesing av «%-.*s», som skulle vært et tall inne i en " +"tegnreferanse (ê for eksempel) - tallet er muligens for stort" + +#: ../glib/gmarkup.c:687 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Tegnreferansen sluttet ikke med et semikolon; du har sannsynligvis brukt et " +"og-tegn uten at det var ment Ã¥ starte en entitet - unngÃ¥ ved Ã¥ bruke & i " +"stedet" + +#: ../glib/gmarkup.c:713 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Tegnreferanse «%-.*s» koder ikke et tillatt tegn" + +#: ../glib/gmarkup.c:751 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Tom entitet «&;» funnet; gyldige entiteter er: & " < > '" + +#: ../glib/gmarkup.c:759 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Entitetsnavn «%-.*s» er ikke kjent" + +#: ../glib/gmarkup.c:764 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Entiteten sluttet ikke med et semikolon; du har sannsynligvis brukt et og-" +"tegn uten at det var ment Ã¥ starte en entitet - ungÃ¥ ved Ã¥ bruke & i " +"stedet" + +#: ../glib/gmarkup.c:1170 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumentet mÃ¥ starte med et element (f.eks )" + +#: ../glib/gmarkup.c:1210 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"«%s» er ikke et gyldig tegn etter en «<» tegn; det kan ikke være begynnelsen " +"pÃ¥ et elementnavn" + +#: ../glib/gmarkup.c:1252 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Rart tegn «%s», forventet et «>» tegn for Ã¥ avslutte start-taggen til det " +"tomme elementet «%s»" + +#: ../glib/gmarkup.c:1333 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Rart tegn «%s», forventet et «=» etter attributtnavn «%s» for element «%s»" + +#: ../glib/gmarkup.c:1374 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Rart tegn «%s», forventet «>» eller «/» tegn for Ã¥ avslutte start-taggen til " +"element «%s», eller alternativt en attributt; kanskje du brukte et ugyldig " +"tegn i attributtnavnet" + +#: ../glib/gmarkup.c:1418 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Rart tegn «%s», ventet et Ã¥pent sitattegn etter likhetstegnet nÃ¥r verdi for " +"attributt «%s» for element «%s» oppgis" + +#: ../glib/gmarkup.c:1551 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"«%s» er ikke et gyldig tegn etter element for lukking med navn «%s»; tillatt " +"tegn er «>»" + +#: ../glib/gmarkup.c:1598 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Element «%s» ble lukket, ingen Ã¥pne elementer nÃ¥" + +#: ../glib/gmarkup.c:1607 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Element «%s» ble lukket, men aktivt Ã¥pent element er «%s»" + +#: ../glib/gmarkup.c:1760 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumentet var tomt eller inneholdt kun blanke tegn" + +#: ../glib/gmarkup.c:1774 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Dokumentet sluttet uventet rett etter en Ã¥pen vinkelparantes «<»" + +#: ../glib/gmarkup.c:1782 ../glib/gmarkup.c:1827 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Dokumentet sluttet uventet med Ã¥pne elementer - «%s» var siste Ã¥pne element" + +#: ../glib/gmarkup.c:1790 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokumentet sluttet uventet, forventet Ã¥ se en vinkelparantes for Ã¥ slutte av " +"den siste taggen <%s/>" + +#: ../glib/gmarkup.c:1796 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumentet sluttet uventet inni et elementnavn" + +#: ../glib/gmarkup.c:1802 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumentet sluttet uventet inni et attributtnavn" + +#: ../glib/gmarkup.c:1807 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumentet sluttet uventet inni en tagg for Ã¥pning av element." + +#: ../glib/gmarkup.c:1813 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokumentet sluttet uventet etter likhetstegnet som følger et attributtnavn; " +"ingen attributtverdi" + +#: ../glib/gmarkup.c:1820 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumentet sluttet uventet inni en attributtverdi" + +#: ../glib/gmarkup.c:1836 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Dokumentet sluttet uventet inni tagg for lukking av element «%s»" + +#: ../glib/gmarkup.c:1842 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokumentet sluttet uventet inni en kommentar eller prosesseringsinstruksjon" + +#: ../glib/goption.c:861 +msgid "[OPTION…]" +msgstr "[FLAGG …]" + +#: ../glib/goption.c:977 +msgid "Help Options:" +msgstr "Flagg for hjelp:" + +#: ../glib/goption.c:978 +msgid "Show help options" +msgstr "Vis flagg for hjelp" + +#: ../glib/goption.c:984 +msgid "Show all help options" +msgstr "Vis alle flagg for hjelp" + +#: ../glib/goption.c:1047 +msgid "Application Options:" +msgstr "Flagg for applikasjonen" + +#: ../glib/goption.c:1049 +msgid "Options:" +msgstr "Flagg:" + +#: ../glib/goption.c:1113 ../glib/goption.c:1183 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Kan ikke lese heltallsverdi «%s» for %s" + +#: ../glib/goption.c:1123 ../glib/goption.c:1191 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Heltallsverdi «%s» for %s er utenfor gyldig omrÃ¥de" + +#: ../glib/goption.c:1148 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Kan ikke lese verdi for double «%s» for %s" + +#: ../glib/goption.c:1156 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Double-verdi «%s» for %s er utenfor gyldig omrÃ¥de" + +#: ../glib/goption.c:1448 ../glib/goption.c:1527 +#, c-format +msgid "Error parsing option %s" +msgstr "Feil under tolking av flagg %s" + +#: ../glib/goption.c:1558 ../glib/goption.c:1671 +#, c-format +msgid "Missing argument for %s" +msgstr "Mangler argument for %s" + +#: ../glib/goption.c:2132 +#, c-format +msgid "Unknown option %s" +msgstr "Ukjent flagg %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "korrupt objekt" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "intern feil eller korrupt objekt" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "ikke mer minne" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "grense for liste av funksjonskall nÃ¥dd" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "mønsteret inneholder oppføringer som ikke støttes for delvise treff" + +#: ../glib/gregex.c:280 +msgid "internal error" +msgstr "intern feil" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "bakoverreferanser som betingelser er ikke støttet for delvise treff" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "rekursjonsgrense nÃ¥dd" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "ugyldig kombinasjon av flagg for nye linjer" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "ugyldig offset" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "kort utf8" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "rekursjonsløkke" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "ukjent feil" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ pÃ¥ slutten av mønsteret" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c pÃ¥ slutten av mønsteret" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "ugjenkjennelig tegn følger \\" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "tall ute av rekkefølge i {}-kvantifikator" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "for stort tall i {}-kvantifikator" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "mangler terminerende ] for tegnklassen" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "ugyldig escape-sekvens i tegnklassen" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "omrÃ¥de utenfor rekkefølge i tegnklassen" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "ingenting Ã¥ gjenta" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "uventet gjentagelse" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "ikke gjenkjent tegn etter (? eller (?-" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "klasser med POSIX-navngivning støttes kun innen en klasse" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "mangler terminerende )" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "referanse til ikke-eksisterende undermønster" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "mangler ) etter kommentar" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "regulært uttrykk er for stort" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "ikke nok minne" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr ") uten Ã¥pnende (" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "kodeoverflyt" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "ikke gjenkjent tegn etter (?<" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind-regel er ikke av fast lengde" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "ugyldig tall eller navn etter (?(" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "betinget gruppe inneholder mer enn to grener" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "assert forventet etter (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R eller (?[+-]tall mÃ¥ følges av )" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "ukjent navn pÃ¥ POSIX-klasse" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "POSIX elementer for sammenslÃ¥ing er ikke støttet" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "tegnverdi i \\x{…} sekvens er for stor" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "ugyldig betingelse (?(0)" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C er ikke tillatt i «lookbehind assertion»" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escape-verdier \\L, \\l, \\N{name}, \\U og \\u er ikke støttet" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "rekursivt kall kunne gÃ¥ i uendelig løkke" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "ikke gjenkjent tegn etter (?P" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "mangler terminering av navn pÃ¥ undermønster" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "to navngitte undermønster har samme navn" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "ugyldig \\P- eller \\p-sekvens" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "ukjent navn pÃ¥ egenskap etter \\P eller \\p" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "navn pÃ¥ undermønster er for langt (maks 32 tegn)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "for mange navngitte undermønster (maks 10.000)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "oktal verdi er større enn \\377" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "gikk ut over arbeidsomrÃ¥de for kompilering" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "tidligere sjekket og referert undermønster ikke funnet" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE-gruppe inneholder mer enn en gren" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "inkonsistente NEWLINE-alternativer" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g etterfølges ikke av et navn, eller tall i klammeparanteser, hakeparantes " +"eller sitattegn" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "en nummerert referanse mÃ¥ ikke være null" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "et argument tillates ikke for (*ACCEPT), (*FAIL) eller (*COMMIT)" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) gjenkjennes ikke" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "tallet er for stort" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "mangler navn pÃ¥ undermønster etter (?&" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "tall forventet etter (?+" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] er et ugyldig datategn i kompatibilitetsmodus for JavaScript" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "forskjellige navn for undermønster med samme nummer tillates ikke" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) mÃ¥ ha et argument" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c mÃ¥ etterfølges av et ASCII-tegn" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k etterfølges ikke av et navn i klammeparanteser, hakeparantes eller " +"sitattegn" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "\\N er ikke støttet i en klasse" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "for mange fremoverreferanser" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "for langt navn i (*MARK), (*PRUNE), (*SKIP) eller (*THEN)" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "tegnverdi i \\u.... sekvens er for stor" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1977 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Feil under treff pÃ¥ regulært uttrykk %s: %s" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE-biblioteket er kompilert uten støtte for UTF8" + +#: ../glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE-biblioteket er kompilert uten støtte for UTF8-egenskaper" + +#: ../glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE-biblioteket er kompilert med inkompatible alternativer" + +#: ../glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Feil under optimering av reguært utrykk %s: %s" + +#: ../glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Feil under sammensetting av regulært utrykk %s ved tegn %d: %s" + +#: ../glib/gregex.c:2413 +msgid "hexadecimal digit or “}†expected" +msgstr "heksadesimalt tall eller «}» forventet" + +#: ../glib/gregex.c:2429 +msgid "hexadecimal digit expected" +msgstr "heksadesimalt tall forventet" + +#: ../glib/gregex.c:2469 +msgid "missing “<†in symbolic reference" +msgstr "mangler «<» i symbolsk referanse" + +#: ../glib/gregex.c:2478 +msgid "unfinished symbolic reference" +msgstr "uferdig symbolsk referanse" + +#: ../glib/gregex.c:2485 +msgid "zero-length symbolic reference" +msgstr "symbolsk referanse med null lengde" + +#: ../glib/gregex.c:2496 +msgid "digit expected" +msgstr "tall forventet" + +#: ../glib/gregex.c:2514 +msgid "illegal symbolic reference" +msgstr "ugyldig symbolsk referanse" + +#: ../glib/gregex.c:2576 +msgid "stray final “\\â€" +msgstr "feilplassert siste «\\\\»" + +#: ../glib/gregex.c:2580 +msgid "unknown escape sequence" +msgstr "ukjent escapesekvens" + +#: ../glib/gregex.c:2590 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Feil under tolking av erstatningstekst «%s» ved tegn %lu: %s" + +#: ../glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Sitert tekst begynner ikke med sitattegn" + +#: ../glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Ubalansert sitattegn i kommandolinje eller annen skall-sitert tekst" + +#: ../glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Teksten sluttet rett etter et «\\» tegn. (Teksten var «%s»)" + +#: ../glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Teksten sluttet før likt sitattegn ble funnet for %c. (Teksten var «%s»)" + +#: ../glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Teksten var tom (eller inneholdt kun blanke tegn)" + +#: ../glib/gspawn.c:253 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Feil under lesing av data fra underprosess (%s)" + +#: ../glib/gspawn.c:401 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Uventet feil i select() ved lesing av data fra underprosess (%s)" + +#: ../glib/gspawn.c:486 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Uventet feil i waitpid() (%s)" + +#: ../glib/gspawn.c:897 ../glib/gspawn-win32.c:1231 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Underprosess avsluttet med kode %ld" + +#: ../glib/gspawn.c:905 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Underprosess terminert av signal %ld" + +#: ../glib/gspawn.c:912 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Underprosess stoppet av signal %ld" + +#: ../glib/gspawn.c:919 +#, c-format +msgid "Child process exited abnormally" +msgstr "Underprosess avsluttet unormalt" + +#: ../glib/gspawn.c:1324 ../glib/gspawn-win32.c:337 ../glib/gspawn-win32.c:345 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Feil under lesing fra \"child pipe\" (%s)" + +#: ../glib/gspawn.c:1394 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Feil under kjøring av fork (%s)" + +#: ../glib/gspawn.c:1543 ../glib/gspawn-win32.c:368 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Klarte ikke Ã¥ skifte til katalog «%s» (%s)" + +#: ../glib/gspawn.c:1553 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Klarte ikke Ã¥ kjøre underprosess «%s» (%s)" + +#: ../glib/gspawn.c:1563 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Feil under omdirigering av utdata eller inndata for underprosess (%s)" + +#: ../glib/gspawn.c:1572 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Feil under kjøring av fork() for underprosess (%s)" + +#: ../glib/gspawn.c:1580 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Ukjent feil under kjøring av underprosess «%s»" + +#: ../glib/gspawn.c:1604 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Klarte ikke Ã¥ lese nok data fra underprosessens pid-rør (%s)" + +#: ../glib/gspawn-win32.c:281 +msgid "Failed to read data from child process" +msgstr "Feil under lesing av data fra underprosess" + +#: ../glib/gspawn-win32.c:298 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Feil under oppretting av rør for kommunikasjon med underprosess (%s)" + +#: ../glib/gspawn-win32.c:374 ../glib/gspawn-win32.c:493 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Feil under kjøring av underprosess (%s)" + +#: ../glib/gspawn-win32.c:443 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ugyldig programnavn: %s" + +#: ../glib/gspawn-win32.c:453 ../glib/gspawn-win32.c:720 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ugyldig streng i argumentvektor pÃ¥ %d: %s" + +#: ../glib/gspawn-win32.c:464 ../glib/gspawn-win32.c:735 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ugyldig streng i miljø: %s" + +#: ../glib/gspawn-win32.c:716 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ugyldig arbeidsmappe: %s" + +#: ../glib/gspawn-win32.c:781 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Feil under kjøring av hjelpeprogram (%s)" + +#: ../glib/gspawn-win32.c:995 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Uventet feil i g_io_channel_win32_poll() under lesing av data fra en " +"underprosess" + +#: ../glib/gstrfuncs.c:3247 ../glib/gstrfuncs.c:3348 +msgid "Empty string is not a number" +msgstr "Tom streng er ikke et tall" + +#: ../glib/gstrfuncs.c:3271 +#, c-format +msgid "“%s†is not a signed number" +msgstr "«%s» er ikke et tall med fortegn" + +#: ../glib/gstrfuncs.c:3281 ../glib/gstrfuncs.c:3384 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Tallet «%s» er utenfor grensene [%s, %s]" + +#: ../glib/gstrfuncs.c:3374 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "«%s» er ikke et tall uten fortegn" + +#: ../glib/gutf8.c:808 +msgid "Failed to allocate memory" +msgstr "Klarte ikke Ã¥ allokere minne" + +#: ../glib/gutf8.c:941 +msgid "Character out of range for UTF-8" +msgstr "Tegn utenfor gyldig omrÃ¥de for UTF-8" + +#: ../glib/gutf8.c:1042 ../glib/gutf8.c:1051 ../glib/gutf8.c:1181 +#: ../glib/gutf8.c:1190 ../glib/gutf8.c:1329 ../glib/gutf8.c:1426 +msgid "Invalid sequence in conversion input" +msgstr "Ugyldig sekvens i inndata for konvertering" + +#: ../glib/gutf8.c:1340 ../glib/gutf8.c:1437 +msgid "Character out of range for UTF-16" +msgstr "Tegn utenfor gyldig omrÃ¥de for UTF-16" + +#: ../glib/gutils.c:2229 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2230 ../glib/gutils.c:2436 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2231 ../glib/gutils.c:2441 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2232 ../glib/gutils.c:2446 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2233 ../glib/gutils.c:2451 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2234 ../glib/gutils.c:2456 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#: ../glib/gutils.c:2237 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2238 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2239 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2240 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2241 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2242 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2245 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#: ../glib/gutils.c:2246 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#: ../glib/gutils.c:2247 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#: ../glib/gutils.c:2248 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#: ../glib/gutils.c:2249 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#: ../glib/gutils.c:2250 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#: ../glib/gutils.c:2253 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#: ../glib/gutils.c:2254 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#: ../glib/gutils.c:2255 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#: ../glib/gutils.c:2256 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#: ../glib/gutils.c:2257 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#: ../glib/gutils.c:2258 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: ../glib/gutils.c:2292 ../glib/gutils.c:2418 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: ../glib/gutils.c:2296 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2363 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: ../glib/gutils.c:2368 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2431 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "Januar" + +msgctxt "full month name with day" +msgid "February" +msgstr "Februar" + +msgctxt "full month name with day" +msgid "March" +msgstr "Mars" + +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +msgctxt "full month name with day" +msgid "May" +msgstr "Mai" + +msgctxt "full month name with day" +msgid "June" +msgstr "Juni" + +msgctxt "full month name with day" +msgid "July" +msgstr "Juli" + +msgctxt "full month name with day" +msgid "August" +msgstr "August" + +msgctxt "full month name with day" +msgid "September" +msgstr "September" + +msgctxt "full month name with day" +msgid "October" +msgstr "Oktober" + +msgctxt "full month name with day" +msgid "November" +msgstr "November" + +msgctxt "full month name with day" +msgid "December" +msgstr "Desember" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mai" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Aug" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Okt" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Des" diff --git a/po/nds.po b/po/nds.po new file mode 100644 index 0000000..e624b8d --- /dev/null +++ b/po/nds.po @@ -0,0 +1,3707 @@ +# Low German translation for glib. +# Copyright (C) 2010 glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the glib package. +# Nils-Christoph Fiedler , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2010-03-18 13:53+0100\n" +"Last-Translator: Nils-Christoph Fiedler \n" +"Language-Team: Low German \n" +"Language: nds\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Een Leseteken för de URI '%s' givt dat all" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Keen Leseteken funnen för URI '%s'" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "De URI '%s' is nich akerat" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Nich akerater Hostnaam" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d. %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Jannuaar" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Feberwaar" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "März" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Mai" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Juni" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Juli" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mär" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Maandag" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Dingsdag" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Middeweek" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Dunnersdag" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Freedag" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sünnavend" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Sünndag" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Maan" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Ding" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Migg" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Dunn" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Free" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Svd." + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Sdag" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Datei \"%s\" is to grot" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Dat Opmaken vun de Datei '%s' is fehlslagen: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f EB" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Künn de Datei '%s' nich opmaken: open() failed: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "'%s' is keen akerater Naam" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "'%s' is kee akerater Naam: '%c' " + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Fehler in Reeg %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "keen Spieker" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "Binnenfehler" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "unbekannter Fehler" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "nix to wedderholen" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "Code Överlööp" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Nich akerate Reeg in Umgeven: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Nich akerates Orbietsverteeknis: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Künn nich opgaveln (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Gebruk:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Hölpoptschoonen:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Hölpoptschoonen opwiesen" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "All Hölpoptschoonen opwiesen" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Programmoptschoonen:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Unbekannte Optschoon %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Keene normale Datei" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "De Datei is leer" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Nich akerater Slötelnaam: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "De Operatschoon weur avbreken" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Unbekannter Typ" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s Dateityp" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s Typ" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, fuzzy, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "Nich unnerstütte Sockelanskrivt" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Fehler bi'm Verbinnen:" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Unbekannter Typ" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Künn de Datei nich sluten: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "Tääler is sluten" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, fuzzy, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "'%s' is keen akerater Naam" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +msgid "Abstract name space not supported" +msgstr "" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gdbusserver.c:1042 +#, fuzzy, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' is keen akerater Naam" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Fehler in Reeg %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Fehler bi'm Verbinnen:" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, fuzzy, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "'%s' is keen akerater Naam" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "'%s' is keen akerater Naam" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "'%s' is keen akerater Naam" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "'%s' is keen akerater Naam" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Fehler in Reeg %d: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Fehler bi'm Verbinnen:" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Ohn Naam" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "Eegen Definitschoon för %s" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "Tääldatei givt dat all" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2762 +#, c-format +msgid "Error splicing file: %s" +msgstr "" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "Tääler is sluten" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "Nich genug Spieker för Sockelanskrivt" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "Nich unnerstütte Sockelanskrivt" + +#: ../gio/glib-compile-schemas.c:741 +msgid "empty names are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Nich akerater Dateinaam %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Künn dateisysteminfo nich kregen: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "Künn root Verteeknisnaam nich ännern" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Fehler bi'm Naam ännern vun de Datei: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Nich akerater Dateinaam" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Künn de Datei nich opmaken: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "Künn dat verteeknis nich opmaken" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "(nich akerate Koderen)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +msgid "Cannot set permissions on symlinks" +msgstr "" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Künn de Datei nich sluten: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "Tääldatei is een Verteeknis" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "Tääldatei is keene normale Datei" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Nich akerate Sökanfrage" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "" + +#: ../gio/gresolver.c:829 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, c-format +msgid "Error resolving '%s'" +msgstr "" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Unbekannte Optschoon %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, c-format +msgid "Unable to create socket: %s" +msgstr "" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, c-format +msgid "Error binding to address: %s" +msgstr "" + +#: ../gio/gsocket.c:1566 +#, c-format +msgid "Error accepting connection: %s" +msgstr "" + +#: ../gio/gsocket.c:1683 +msgid "Error connecting: " +msgstr "Fehler bi'm Verbinnen:" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, c-format +msgid "Error connecting: %s" +msgstr "" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "" + +#: ../gio/gsocket.c:1875 +#, c-format +msgid "Error receiving data: %s" +msgstr "" + +#: ../gio/gsocket.c:2050 +#, c-format +msgid "Error sending data: %s" +msgstr "" + +#: ../gio/gsocket.c:2163 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "" + +#: ../gio/gsocket.c:2242 +#, c-format +msgid "Error closing socket: %s" +msgstr "" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, c-format +msgid "Error sending message: %s" +msgstr "" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, c-format +msgid "Error receiving message: %s" +msgstr "" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "Unbekannter Fehler bi'm Verbinnen" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Künn de Datei nich opmaken: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Fehler bi'm Naam ännern vun de Datei: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "Dateisystem root" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "Künn dat Programm nich finnen" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "URIs nich unnerstütt" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Fehler bi'm Naam ännern vun de Datei: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Künn de Datei nich sluten: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Problem bi'm Lesen vun de Datei '%s': %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "Nich genug Spieker" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "Binnenfehler: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "Bruk mehr Ingaven" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "" diff --git a/po/ne.po b/po/ne.po new file mode 100644 index 0000000..e065997 --- /dev/null +++ b/po/ne.po @@ -0,0 +1,6344 @@ +# translation of glib.HEAD.ne.po to Nepali +# This file is distributed under the same license as the glib package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Jyotshna Shrestha , 2005. +# Ganesh Ghimire , 2005. +# Shiva Pokharel , 2005. +# Kapil Timilsina , 2005. +# Jaydeep Bhusal , 2005. +# Shyam Krishna Bal , 2006. +msgid "" +msgstr "" +"Project-Id-Version: Gnome Nepali Translation Project\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-08 12:19+0000\n" +"PO-Revision-Date: 2022-05-11 13:16+0545\n" +"Last-Translator: Pawan Chitrakar \n" +"Language-Team: Nepali Translation Team \n" +"Language: ne\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2;plural=(n!=1);\n" +"X-Generator: Poedit 3.0.1\n" + +#: gio/gappinfo.c:333 +#, fuzzy +msgid "Setting default applications not supported yet" +msgstr "%s: %s देखि %sमा सेट गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/gappinfo.c:366 +#, fuzzy +msgid "Setting application as last used for type not supported yet" +msgstr "%s: %s देखि %sमा सेट गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "जि-अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— विकलà¥à¤ªà¤¹à¤°à¥‚" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "जि-अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— विकलà¥à¤ªà¤¹à¤°à¥‚ देखाउनà¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "जी-अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— सेवा मोड पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ (D-Bus सेवा फाइलबाट पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—को आईडी अधिलेखन गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "चालॠदृषà¥à¤Ÿà¤¾à¤¨à¥à¤¤ बदलà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 gio/gresource-tool.c:494 +#: gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "मदà¥à¤¦à¤¤ मà¥à¤¦à¥à¤°à¤£ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[आदेश]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "मà¥à¤¦à¥à¤°à¤£ संसà¥à¤•रण" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "मà¥à¤¦à¥à¤°à¤£ संसà¥à¤•रण विवरण अनि बाहिरनà¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—हरूको सूची" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ गरिà¤à¤•ो D-Bus सकà¥à¤°à¤¿à¤¯ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—हरूको सूची बनाउनà¥à¤¹à¥‹à¤¸à¥ (.desktop files दà¥à¤µà¤¾à¤°à¤¾)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— खोलà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— सà¥à¤°à¥ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ (वैकलà¥à¤ªà¤¿à¤• फाइलहरू खोलà¥à¤¨à¤•ा लागी)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [फाइल…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "कारà¥à¤¯ सकà¥à¤°à¤¿à¤¯ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—मा à¤à¤‰à¤Ÿà¤¾ कारà¥à¤¯ आहà¥à¤µà¤¾à¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "उपलबà¥à¤§ कारà¥à¤¯à¤¹à¤°à¥‚को सूची" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "(.desktop फाइलबाट) अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—का लागि सà¥à¤¥à¤¿à¤° कारà¥à¤¯à¤¹à¤°à¥‚ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "आदेश" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "विसà¥à¤¤à¥ƒà¤¤ मदà¥à¤¦à¤¤ छापà¥à¤¨ आदेश" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus ढाà¤à¤šà¤¾à¤®à¤¾ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— पहिचायक (जसà¥à¤¤à¥ˆ: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 gio/glib-compile-resources.c:826 +#: gio/glib-compile-resources.c:855 gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "फाइल" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "वैकलà¥à¤ªà¤¿à¤• समà¥à¤¬à¤¨à¥à¤§à¤¿à¤¤ वा पूरà¥à¤£ फाइलनाम, वा URIs खोलà¥à¤¨" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "कारà¥à¤¯" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "कारà¥à¤¯ आहà¥à¤µà¤¾à¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "परामिति" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "GVariant ढाà¤à¤šà¤¾à¤®à¤¾, कà¥à¤°à¤¿à¤¯à¤¾ आवà¥à¤¨à¥à¤œà¤¨à¤®à¤¾ वैकलà¥à¤ªà¤¿à¤• परिमिति" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"अजà¥à¤žà¤¾à¤¤ आदेश %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "उपयोग: \n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "तरà¥à¤•हरू:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "गलत तरà¥à¤•" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "आदेशहरू:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"विसà¥à¤¤à¥ƒà¤¤ मदà¥à¤¦à¤¤ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ \"%s help COMMAND\" पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"पà¥à¤°à¤¤à¥à¤¯à¤•à¥à¤· अनà¥à¤—मन गरà¥à¤¨ %s आदेशलाई à¤à¤‰à¤Ÿà¤¾ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— आईडी आवशà¥à¤¯à¤• परà¥à¤¦à¤›\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "अवैध अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— आईडी: %s\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†तरà¥à¤•हरू लगà¥à¤¦à¥ˆà¤¨\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus जडान गरà¥à¤¨à¥ असकà¥à¤·à¤®: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "सनà¥à¤¦à¥‡à¤¶ पठाउदा तà¥à¤°à¥à¤Ÿà¤¿ “%sâ€: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— आईडी पछि कारà¥à¤¯ नाम दिनॠपरà¥à¤¦à¤›\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"अवैध कारà¥à¤¯ नाम: \"%s\"\n" +"कारà¥à¤¯ नाममा अलà¥à¤«à¤¾à¤¨à¥à¤¯à¥à¤®à¥‡à¤°à¤¿à¤• मातà¥à¤° हà¥à¤¨à¥à¤ªà¤°à¥à¤¦à¤›, \"-\" र \".\"\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "पà¥à¤¯à¤¾à¤°à¤¾à¤®à¤¿à¤Ÿà¤° पदवरà¥à¤£à¤¨ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "कारà¥à¤¯à¤²à¥‡ अधिकतम à¤à¤‰à¤Ÿà¤¾ परिमिति सà¥à¤µà¥€à¤•ार गरà¥à¤›\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "सूची-कारà¥à¤¯ आदेशले अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— आईडी मातà¥à¤° लिनà¥à¤›" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— पिकà¥à¤¸à¤®à¥à¤¯à¤¾à¤ª फाइल पतà¥à¤¤à¤¾ लगाउन सकेन: %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"नचिनेको आदेश: %s \n" +"\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 gio/ginputstream.c:179 gio/ginputstream.c:379 +#: gio/ginputstream.c:648 gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "अति ठूलो गणना मान %s मा पास गरियो" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "आधार सà¥à¤Ÿà¥à¤°à¤¿à¤®à¤®à¤¾ खोजी समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream काटà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤® पहिलà¥à¤¯à¥ˆ बनà¥à¤¦ छ" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "आधार सà¥à¤Ÿà¥à¤°à¥€à¤®à¤®à¤¾ कताई समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 gio/gsimpleasyncresult.c:871 +#: gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "सञà¥à¤šà¤¾à¤²à¤¨ रदà¥à¤¦ भà¤à¤•ो छ" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "अमानà¥à¤¯ वसà¥à¤¤à¥, पà¥à¤°à¤¾à¤°à¤®à¥à¤­ गरिà¤à¤•ो छैन" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "आगतमा अपूरà¥à¤£ बहà¥à¤¬à¥à¤¯ अनà¥à¤•à¥à¤°à¤®" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "गनà¥à¤¤à¤µà¥à¤¯à¤®à¤¾ परà¥à¤¯à¤¾à¤ªà¥à¤¤ सà¥à¤¥à¤¾à¤¨ छैन" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 gio/gdatainputstream.c:1266 glib/gconvert.c:449 +#: glib/gconvert.c:879 glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 glib/gutf8.c:890 +#: glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "रूपानà¥à¤¤à¤°à¤£ आगतमा अवैध बाइट अनà¥à¤•à¥à¤°à¤®" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "रूपानà¥à¤¤à¤°à¤£ अवधिमा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "रदà¥à¤¦-सकà¥à¤·à¤® थालनी समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° सेट '%s' बाट '%s' मा रूपानà¥à¤¤à¤°à¤£ समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "“%s†लाई “%s†मा रà¥à¤ªà¤¾à¤¨à¥à¤¤à¤°à¤£ खोलà¥à¤¨ सकिà¤à¤¨" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s पà¥à¤°à¤•ार" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "अजà¥à¤žà¤¾à¤¤ पà¥à¤°à¤•ार" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s फइल पà¥à¤°à¤•ार" + +#: gio/gcredentials.c:335 +#, fuzzy +msgid "GCredentials contains invalid data" +msgstr "फाइल नाममा अवैध वरà¥à¤£" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +#, fuzzy +msgid "GCredentials is not implemented on this OS" +msgstr "कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ भà¤à¤•ो छैन" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "तपाईà¤à¤•ो पà¥à¤²à¥‡à¤Ÿà¤«à¤°à¥à¤®à¤•ा लागि तà¥à¤¯à¤¹à¤¾à¤ GCredentials समरà¥à¤¥à¤¨ छैन" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials ले यो OS मा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ आईडी समावेश गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "यो सञà¥à¤šà¤¾à¤²à¤¨ पà¥à¤°à¤£à¤¾à¤²à¥€à¤®à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सà¥à¤ªà¥‚फिङ समà¥à¤­à¤µ छैन" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "सà¥à¤Ÿà¥à¤°à¤¿à¤®à¤•ो अनपेकà¥à¤·à¤¿à¤¤ अनà¥à¤¤à¥à¤¯" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "\"%s\" ठेगाना पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¤¿à¤®à¤¾ असमरà¥à¤¥à¤¿à¤¤ कà¥à¤žà¥à¤œà¥€ \"%s\"" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "ठेगाना पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¤¿ \"%s\" मा अरà¥à¤¥à¤¹à¥€à¤¨ कà¥à¤žà¥à¤œà¥€/मान जोडा संयोजन" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract keys)" +msgstr "ठेगाना \"%s\" अवैध छ (पथ, डाइरेकà¥à¤Ÿà¤°à¥€, tmpdir, वा अमूरà¥à¤¤ कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ मधà¥à¤¯à¥‡ ठà¥à¤¯à¤¾à¤•à¥à¤•ै à¤à¤• आवशà¥à¤¯à¤• छ)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "\"%s\" ठेगानामा तà¥à¤°à¥à¤Ÿà¤¿ — \"%s\" विशेषता विकृत छ" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, fuzzy, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "असमरà¥à¤¥à¤¿à¤¤ पारवाहन \"%s\" मा सà¥à¤¨à¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "ठेगाना ततà¥à¤µ \"%s\" मा विराम चिनà¥à¤¹ (:) समावेश छैन" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "ठेगाना ततà¥à¤µ \"%s\" मा यातायात नाम खाली हà¥à¤¨à¥ हà¥à¤¦à¥ˆà¤¨" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal sign" +msgstr "कà¥à¤žà¥à¤œà¥€/मान जोडा %d, \"%s\", ठेगाना ततà¥à¤µà¤®à¤¾ \"%s\" ले बराबर चिनà¥à¤¹ समावेश गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "कà¥à¤žà¥à¤œà¥€/मान जोडा %d, \"%s\", ठेगाना ततà¥à¤µà¤®à¤¾ \"%s\" सà¤à¤— à¤à¤‰à¤Ÿà¤¾ खाली कà¥à¤žà¥à¤œà¥€ हà¥à¤¨à¥ हà¥à¤¦à¥ˆà¤¨" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element “%sâ€" +msgstr "कà¥à¤žà¥à¤œà¥€/मान जोडा %d, \"%s\", ठेगाना ततà¥à¤µ \"%s\" मा मान वा कà¥à¤žà¥à¤œà¥€ खà¥à¤²à¤¾à¤‰à¤¨à¥‡ कà¥à¤°à¤®à¤®à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "Error in address “%s†— the unix transport requires exactly one of the keys “path†or “abstract†to be set" +msgstr "\"%s\" ठेगानामा तà¥à¤°à¥à¤Ÿà¤¿ - यà¥à¤¨à¤¿à¤•à¥à¤¸ टà¥à¤°à¤¾à¤¨à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿà¤²à¤¾à¤ˆ सेट हà¥à¤¨à¤•ा लागि ठीक à¤à¤‰à¤Ÿà¤¾ कà¥à¤žà¥à¤œà¥€ \"मारà¥à¤—\" वा \"अमूरà¥à¤¤\" आवशà¥à¤¯à¤• परà¥à¤¦à¤›" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "\"%s\" ठेगानामा तà¥à¤°à¥à¤Ÿà¤¿ — होसà¥à¤Ÿ विशेषता छà¥à¤Ÿà¥‡à¤•ो छ वा विकृत छ" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "\"%s\" ठेगानामा तà¥à¤°à¥à¤Ÿà¤¿ — पोरà¥à¤Ÿ विशेषता छà¥à¤Ÿà¥‡à¤•ो छ वा विकृत छ" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "\"%s\" ठेगानामा तà¥à¤°à¥à¤Ÿà¤¿ — noncefile विशेषता हराइरहेको छ वा विकृत छ" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "सà¥à¤µ:त सà¥à¤°à¥à¤†à¤¤ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: " + +#: gio/gdbusaddress.c:725 +#, fuzzy, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "फाइल “%s†पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿:%s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "फाइल “%s†पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿:%s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "nonce फ़ाइल \"%s\" से पढ़ने में तà¥à¤°à¥à¤Ÿà¤¿, अपेकà¥à¤·à¤¿à¤¤ 16 बाइटà¥à¤¸, %d मिला" + +#: gio/gdbusaddress.c:771 +#, fuzzy, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "दिà¤à¤•ो ठेगाना खाली छ" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "जब AT_SECURE सेट हà¥à¤¨à¥à¤› तब सनà¥à¤¦à¥‡à¤¶ बस उतà¥à¤ªà¤¨à¥à¤¨ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "मेशिन आईडी बिना सनà¥à¤¦à¥‡à¤¶ बस उतà¥à¤ªà¤¨à¥à¤¨ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "X11 $DISPLAY बिना D-Bus सà¥à¤µà¤¤: सà¥à¤°à¥à¤†à¤¤ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "आदेश-रेखा विकलà¥à¤ª पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकेन%s" + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "सतà¥à¤° बस ठेगाना निरà¥à¤§à¤¾à¤°à¤£ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨ (यो सञà¥à¤šà¤¾à¤²à¤¨ पà¥à¤°à¤£à¤¾à¤²à¥€à¤•ा लागि कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरिà¤à¤•ो छैन)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable — unknown value “%sâ€" +msgstr "DBUS_STARTER_BUS_TYPE परिवेश चलबाट बस ठेगाना निरà¥à¤§à¤¾à¤°à¤£ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨ — अजà¥à¤žà¤¾à¤¤ मान \"%s\"" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment variable is not set" +msgstr "बस ठेगाना निरà¥à¤§à¤¾à¤°à¤£ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨ किनभने DBUS_STARTER_BUS_TYPE परिवेश मान सेट गरिà¤à¤•ो छैन" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "अपरिचित बाà¤à¤£à¤•ो पà¥à¤°à¤•ार %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "लाइन पढà¥à¤¨ पà¥à¤°à¤¯à¤¾à¤¸ गरिरहेको सामागà¥à¤°à¥€à¤•ो अनपेकà¥à¤·à¤¿à¤¤ कमी" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "लाइन (सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ रूपमा) पढà¥à¤¨ पà¥à¤°à¤¯à¤¾à¤¸ गरिरहेको अनपेकà¥à¤·à¤¿à¤¤ सामगà¥à¤°à¥€à¤•ो कमी" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "सबै उपलबà¥à¤§ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण संयनà¥à¤¤à¥à¤°à¤¹à¤°à¥‚ निषà¥à¤•ासित गरियो (पà¥à¤°à¤¯à¤¾à¤¸ गरियो: %s) (उपलबà¥à¤§: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "समान र सरà¥à¤­à¤°à¤•ा लागि पà¥à¤°à¤¯à¥‹à¤—करà¥à¤¤à¤¾ आईडी उसà¥à¤¤à¥ˆ हà¥à¤¨à¥à¤ªà¤°à¥à¤›" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver मारà¥à¤«à¤¤ रदà¥à¤¦ गरियो:: authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, fuzzy, c-format +#| msgid "Error opening directory '%s': %s" +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "\"%s\" लोड गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: तà¥à¤¯à¤¸ पà¥à¤°à¤•ारको निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा छैन" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "डाइरेकà¥à¤Ÿà¤°à¥€ \"%s\" मा अनà¥à¤®à¤¤à¤¿ विकृत छ। अपेकà¥à¤·à¤¿à¤¤ मोड ०७००, ०%o पà¥à¤°à¤¾à¤ªà¥à¤¤ भयो" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा \"%s\" सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 gio/gfile.c:1456 gio/gfile.c:1694 +#: gio/gfile.c:1749 gio/gfile.c:1807 gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 gio/gfile.c:5086 gio/gfile.c:5171 +#: gio/gfile.c:5261 gio/gfile.c:5358 gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "सञà¥à¤šà¤¾à¤²à¤¨ समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "\"%s\" किरिङà¥à¤— पढà¥à¤¨à¤¾à¤•ा लागि खोलà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "किरिङको लाइन %d मा “%s†सामागà¥à¤°à¥€ “%s†विकृत छ" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "किरिङको पहिलो टोकन लाइन %d मा “%s†सामगà¥à¤°à¥€à¤¸à¤à¤— “%s†विकृत छ" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "किरिङको दोसà¥à¤°à¥‹ टोकन लाइन %d मा “%s†सामगà¥à¤°à¥€à¤¸à¤à¤— “%s†विकृत छ" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr " आईडी %d मा \"%s\"किरिङ कà¥à¤•ी फेला परेन" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "तालà¥à¤šà¤¾ लगाइà¤à¤•ो फाइल \"%s\" सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, fuzzy, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "तालà¥à¤šà¤¾ लगाइà¤à¤•ो फाइल \"%s\" सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "तालà¥à¤šà¤¾ लगाइà¤à¤•ो फाइल \"%s\" सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, fuzzy, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "तालà¥à¤šà¤¾ लगाइà¤à¤•ो फाइल \"%s\" सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "लेखà¥à¤¨à¤•ा लागि \"%s\" किरिङà¥à¤— खोलà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(\"%s\" का लागि तालà¥à¤šà¤¾ हटाउन असफल: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "जडान बनà¥à¤¦ भयो" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "समय समापà¥à¤¤à¤¿" + +#: gio/gdbusconnection.c:2525 +msgid "Unsupported flags encountered when constructing a client-side connection" +msgstr "कà¥à¤²à¤¾à¤‡à¤¨à¥à¤Ÿ-साइड जडान निरà¥à¤®à¤¾à¤£ गरà¥à¤¦à¤¾ असमरà¥à¤¥à¤¿à¤¤ à¤à¤£à¥à¤¡à¤¾à¤¹à¤°à¥‚ सामना भयो" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, fuzzy, c-format +msgid "No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "\"%s\" मारà¥à¤—मा वसà¥à¤¤à¥ अवसà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gdbusconnection.c:4398 +#, fuzzy, c-format +#| msgid "No such property '%s'" +msgid "No such property “%sâ€" +msgstr "'%s' गà¥à¤£ लेखà¥à¤¨ योगà¥à¤¯ छैन:%s" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "विशेषता \"%s\" पढà¥à¤¨à¤¯à¥‹à¤—à¥à¤¯ छैन" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "\"%s\" गà¥à¤£ लेखनयोगà¥à¤¯ छैन" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "विशेषता \"%s\" सेट गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: अपेकà¥à¤·à¤¿à¤¤ पà¥à¤°à¤•ार \"%s\" तर \"%s\" पà¥à¤°à¤¾à¤ªà¥à¤¤ भयो" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "चेतावनी: इनà¥à¤Ÿà¤°à¤•à¥à¤°à¥‡à¤¸à¤Ÿà¥‡à¤¸à¤¨ डाटाको अनà¥à¤¸à¤¾à¤°, इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸ \"%s\" अवसà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, fuzzy, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "\"%s\" मारà¥à¤—मा वसà¥à¤¤à¥ अवसà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gdbusconnection.c:5084 +#, fuzzy, c-format +#| msgid "No such key “%sâ€\n" +msgid "No such method “%sâ€" +msgstr "चेतावनी: जाच भठडाटाको अनà¥à¤¸à¤¾à¤°, \"%s\" विधिमा \"%s\" मा अवसà¥à¤¥à¤¿à¤¤ छैन।\n" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "सनà¥à¤¦à¥‡à¤¶à¤•ो पà¥à¤°à¤•ार, \"%s\", अपेकà¥à¤·à¤¿à¤¤ पà¥à¤°à¤•ार \"%s\" सà¤à¤— मिलà¥à¤¦à¥ˆà¤¨" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "%s मा %s इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸à¤•ा लागि à¤à¤‰à¤Ÿà¤¾ वसà¥à¤¤à¥ पहिलà¥à¤¯à¥ˆ निरà¥à¤¯à¤¾à¤¤ गरिà¤à¤•ो छ" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "%s गà¥à¤£ पà¥à¤¨:पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ अकà¥à¤·à¤®.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "'%s' गà¥à¤£ लेखà¥à¤¨ योगà¥à¤¯ छैन:%s" + +#: gio/gdbusconnection.c:5780 +#, fuzzy, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "विशेषता \"%s\" सेट गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: अपेकà¥à¤·à¤¿à¤¤ पà¥à¤°à¤•ार \"%s\" तर \"%s\" पà¥à¤°à¤¾à¤ªà¥à¤¤ भयो" + +#: gio/gdbusconnection.c:6856 +#, fuzzy, c-format +#| msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "चेतावनी: जाच भठडाटाको अनà¥à¤¸à¤¾à¤°, \"%s\" विधिमा \"%s\" मा अवसà¥à¤¥à¤¿à¤¤ छैन।\n" + +#: gio/gdbusconnection.c:6977 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "%s मा %s इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸à¤•ा लागि à¤à¤‰à¤Ÿà¤¾ वसà¥à¤¤à¥ पहिलà¥à¤¯à¥ˆ निरà¥à¤¯à¤¾à¤¤ गरिà¤à¤•ो छ" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "\"%s\" मारà¥à¤—मा वसà¥à¤¤à¥ अवसà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "पà¥à¤°à¤•ार अवैध छ" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL सनà¥à¤¦à¥‡à¤¶: बाटो वा सदसà¥à¤¯ हेडर फाà¤à¤Ÿ छà¥à¤Ÿà¥‡à¤•ो छ" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN सनà¥à¤¦à¥‡à¤¶: REPLY_SERIAL हेडर फाà¤à¤Ÿ हराइरहेको छ" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿ सनà¥à¤¦à¥‡à¤¶: REPLY_SERIAL वा ERROR_NAME हेडर फाà¤à¤Ÿ छà¥à¤Ÿà¥‡à¤•ो छ" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "सङà¥à¤•ेत सनà¥à¤¦à¥‡à¤¶: बाटो, इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸ वा सदसà¥à¤¯ हेडर फाà¤à¤Ÿ हराइरहेको छ" + +#: gio/gdbusmessage.c:1356 +msgid "SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local" +msgstr "संकेत सनà¥à¤¦à¥‡à¤¶: बाटो हेडर फाà¤à¤Ÿà¤²à¥‡ सञà¥à¤šà¤¿à¤¤ मान /org/freedesktop/DBus/Local पà¥à¤°à¤¯à¥‹à¤— गरिरहेको छ" + +#: gio/gdbusmessage.c:1364 +msgid "SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local" +msgstr "संकेत सनà¥à¤¦à¥‡à¤¶: इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸ हेडर फिलà¥à¤¡à¤²à¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ मान org.freedesktop.DBus.Local पà¥à¤°à¤¯à¥‹à¤— गरिरहेको छ" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu बाइट पढà¥à¤¨ चाहनà¥à¤¥à¥à¤¯à¥‹ तर %lu मातà¥à¤° पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¯à¥‹" +msgstr[1] "%lu बाइट पढà¥à¤¨ चाहनà¥à¤¥à¥à¤¯à¥‹ तर %lu मातà¥à¤° पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¯à¥‹" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "सà¥à¤Ÿà¥à¤°à¤¿à¤™ \"%s\" पछि NUL बाइट अपेकà¥à¤·à¤¿à¤¤ तर %d बाइट फेला परà¥à¤¯à¥‹" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). The valid UTF-8 " +"string up until that point was “%sâ€" +msgstr "" +"अपेकà¥à¤·à¤¿à¤¤ वैध UTF-8 सà¥à¤Ÿà¥à¤°à¤¿à¤™ तर बाइट अफसेट %d मा अवैध बाइटहरू फेला परà¥à¤¯à¥‹ (सà¥à¤Ÿà¥à¤°à¤¿à¤™à¤•ो लमà¥à¤¬à¤¾à¤‡ %d हो)। तà¥à¤¯à¥‹ बिनà¥à¤¦à¥ \"%s\" नभà¤à¤¸à¤®à¥à¤® वैध UTF-8 " +"सà¥à¤Ÿà¥à¤°à¤¿à¤™" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +#, fuzzy +msgid "Value nested too deeply" +msgstr "अति ठूलो गणना मान %s मा पास गरियो" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "पद वरà¥à¤£à¤¨ गरिà¤à¤•ो मान \"%s\" वैध D-Bus वसà¥à¤¤à¥ मारà¥à¤— होइन" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "पद वरà¥à¤£à¤¨ गरिà¤à¤•ो मान \"%s\" वैध D-Bus हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° होइन" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "%u बाइट लमà¥à¤¬à¤¾à¤‡à¤•ो à¤à¤°à¥‡ भेटिनà¥à¤› । अधिकतम लमà¥à¤¬à¤¾à¤‡ २<<२६ बाइट (६४ MiB) हो ।" +msgstr[1] "%u बाइट लमà¥à¤¬à¤¾à¤‡à¤•ो à¤à¤°à¥‡ भेटिनà¥à¤› । अधिकतम लमà¥à¤¬à¤¾à¤‡ २<<२६ बाइट (६४ MiB) हो ।" + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u bytes, but found to be %u bytes in length" +msgstr "\"a%c\" पà¥à¤°à¤•ारको à¤à¤°à¥‡, %u बाइटको गà¥à¤£à¤¨à¤«à¤² हà¥à¤¨à¥‡ अपेकà¥à¤·à¤¾ गरिà¤à¤•ो छ, तर %u बाइट लमà¥à¤¬à¤¾à¤‡à¤®à¤¾ भà¤à¤•ो फेला परà¥à¤¯à¥‹" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "D-Bus मा खाली बनावट (tuples) लाई अनà¥à¤®à¤¤à¤¿ छैन" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "भेरिà¤à¤¨à¥à¤Ÿà¤•ा लागि पद वरà¥à¤£à¤¨ गरिà¤à¤•ो मान \"%s\" वैध D-Bus हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° होइन" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "D-Bus तार ढाà¤à¤šà¤¾à¤¬à¤¾à¤Ÿ \"%s\" पà¥à¤°à¤•ार सà¥à¤Ÿà¥à¤°à¤¿à¤™à¤¸à¤à¤— GVariant deserializing गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value 0x%02x" +msgstr "अवैध अनà¥à¤¤à¥à¤¯ मान । अपेकà¥à¤·à¤¿à¤¤ 0x6c (\"l\") वा 0x42 (\"B\") तर मान 0x%02x फेला परà¥à¤¯à¥‹" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "अवैध मà¥à¤–à¥à¤¯ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ोल संसà¥à¤•रण । अपेकà¥à¤·à¤¿à¤¤ १ तर %d पà¥à¤°à¤¾à¤ªà¥à¤¤ भयो" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° हेडर फेला परà¥à¤¯à¥‹ तर यो पà¥à¤°à¤•ारको हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° होइन ।" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° \"%s\" सà¤à¤— हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° हेडर फेला परà¥à¤¯à¥‹ तर सनà¥à¤¦à¥‡à¤¶à¤•ो मà¥à¤–à¥à¤¯ भाग खाली छ" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "पद वरà¥à¤£à¤¨ गरिà¤à¤•ो मान \"%s\" वैध D-Bus हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° (मà¥à¤–à¥à¤¯ भागका लागि) होइन" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "सनà¥à¤¦à¥‡à¤¶à¤®à¤¾ हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° हेडर छैन तर सनà¥à¤¦à¥‡à¤¶à¤•ो मà¥à¤–à¥à¤¯ भाग %u बाइट हो" +msgstr[1] "सनà¥à¤¦à¥‡à¤¶à¤®à¤¾ हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° हेडर छैन तर सनà¥à¤¦à¥‡à¤¶ मà¥à¤–à¥à¤¯ भाग %u बाइट हो" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "सनà¥à¤¦à¥‡à¤¶ deserialize गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "\"%s\" पà¥à¤°à¤•ार सà¥à¤Ÿà¥à¤°à¤¿à¤™à¤¸à¤à¤— जी भेरिà¤à¤¨à¥à¤Ÿà¤²à¤¾à¤ˆ D-Bus तार ढाà¤à¤šà¤¾à¤®à¤¾ कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "सनà¥à¤¦à¥‡à¤¶ (%d) मा फाइल वरà¥à¤£à¤¨à¤•रà¥à¤¤à¤¾à¤•ो सङà¥à¤–à¥à¤¯à¤¾ हेडर फिलà¥à¤¡ (%d) भनà¥à¤¦à¤¾ फरक हà¥à¤¨à¥à¤›" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "सनà¥à¤¦à¥‡à¤¶ सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "सनà¥à¤¦à¥‡à¤¶ मà¥à¤–à¥à¤¯ भागसà¤à¤— हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° \"%s\" छ तर तà¥à¤¯à¤¹à¤¾à¤ हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° हेडर छैन" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "Message body has type signature “%s†but signature in the header field is “%sâ€" +msgstr "सनà¥à¤¦à¥‡à¤¶ मà¥à¤–à¥à¤¯ भागसà¤à¤— पà¥à¤°à¤•ार हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° \"%s\" छ तर हेडर फिलà¥à¤¡à¤®à¤¾ हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° \"%s\" हो" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "सनà¥à¤¦à¥‡à¤¶ मà¥à¤–à¥à¤¯ भाग खाली छ तर हेडर फिलà¥à¤¡à¤®à¤¾ हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° \"(%s)\" छ" + +#: gio/gdbusmessage.c:3477 +#, fuzzy, c-format +msgid "Error return with body of type “%sâ€" +msgstr "" +"चितà¥à¤° %s लोड गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿à¥¤\n" +"अजà¥à¤žà¤¾à¤¤ फाइल पà¥à¤°à¤•ार" + +#: gio/gdbusmessage.c:3485 +#, fuzzy +msgid "Error return with empty body" +msgstr "खाली मà¥à¤–à¥à¤¯ भागसà¤à¤— तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(यो सञà¥à¤à¥à¤¯à¤¾à¤² बनà¥à¤¦ गरà¥à¤¨ कà¥à¤¨à¥ˆ कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° टाइप गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "सतà¥à¤° dbus चलिरहेको छैन, र सà¥à¤µà¤¤: सà¥à¤°à¥à¤†à¤¤ असफल भयो" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "हारà¥à¤¡à¤µà¥‡à¤¯à¤° पà¥à¤°à¥‹à¤«à¤¾à¤‡à¤² पाउन असकà¥à¤·à¤®: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "%s वा %s लोड गरà¥à¤¨ असकà¥à¤·à¤® भयो: " + +#: gio/gdbusproxy.c:1573 +#, fuzzy, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "StartServiceByName(\"%2$s\") विधिबाट अनपेकà¥à¤·à¤¿à¤¤ जवाफ %1$d" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, and proxy was constructed with the " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"विधि आहà¥à¤µà¤¾à¤¨ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨; मालिक बिनाको पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ परिचित नाम %s का लागि हो, र G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START à¤à¤£à¥à¤¡à¤¾à¤¸à¤à¤— " +"पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ निरà¥à¤®à¤¾à¤£ गरिà¤à¤•ो थियो" + +#: gio/gdbusserver.c:767 +#, fuzzy +msgid "Abstract namespace not supported" +msgstr "संकà¥à¤·à¥‡à¤ª" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "सरà¥à¤­à¤° सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ कà¥à¤¨à¥ˆ पनि फाइल निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gdbusserver.c:942 +#, fuzzy, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "फाइल “%s†पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿:%s" + +#: gio/gdbusserver.c:1117 +#, fuzzy, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "पद वरà¥à¤£à¤¨ गरिà¤à¤•ो मान \"%s\" वैध D-Bus हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° होइन" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "असमरà¥à¤¥à¤¿à¤¤ पारवाहन \"%s\" मा सà¥à¤¨à¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"आदेशहरू:\n" +" help   यो जानकारी देखाउà¤à¤¦à¤›\n" +" introspect   introspect à¤à¤• रिमोट वसà¥à¤¤à¥ घà¥à¤¸à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" monitor   मनिटरमा टाढाको वसà¥à¤¤à¥ मनिटर\n" +" call   कल रिमोट वसà¥à¤¤à¥à¤®à¤¾ à¤à¤‰à¤Ÿà¤¾ विधि निमनà¥à¤¤à¥à¤°à¤£à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" emit   उतà¥à¤¸à¤°à¥à¤œà¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" wait   पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"\n" +"पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• आदेशमा मदà¥à¤¦à¤¤ पाउन \"% s COMMAND --help\" को पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 +#: gio/gdbus-tool.c:1245 gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "फिलà¥à¤Ÿà¤° पदवरà¥à¤£à¤¨ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s: %s" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "कारà¥à¤¯: %s अवैध नाम\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s अवैध वसà¥à¤¤à¥ मारà¥à¤—\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "सिसà¥à¤Ÿà¤® बस सà¤à¤—को जडान तà¥à¤°à¥à¤Ÿà¥€ : %s" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "सतà¥à¤° बस जडान" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "दिà¤à¤•ो D-Bus ठेगानामा जडान गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "जडान अनà¥à¤¤à¥à¤¯à¤¬à¤¿à¤¨à¥à¤¦à¥ विकलà¥à¤ªà¤¹à¤°à¥‚:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "जडान अनà¥à¤¤à¥à¤¯à¤¬à¤¿à¤¨à¥à¤¦à¥ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ विकलà¥à¤ª" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "जडान अनà¥à¤¤à¤¿à¤®à¤¬à¤¿à¤¨à¥à¤¦à¥ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छैन" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "à¤à¤•ाधिक जडान अनà¥à¤¤à¥à¤¯ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "चेतावनी: इनà¥à¤Ÿà¤°à¤•à¥à¤°à¥‡à¤¸à¤Ÿà¥‡à¤¸à¤¨ डाटाको अनà¥à¤¸à¤¾à¤°, इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸ \"%s\" अवसà¥à¤¥à¤¿à¤¤ छैन\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "Warning: According to introspection data, method “%s†does not exist on interface “%sâ€\n" +msgstr "चेतावनी: जाच भठडाटाको अनà¥à¤¸à¤¾à¤°, \"%s\" विधिमा \"%s\" मा अवसà¥à¤¥à¤¿à¤¤ छैन।\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "सङà¥à¤•ेत मा उतà¥à¤¸à¤°à¥à¤œà¤¨ गरà¥à¤¨à¥‡ वसà¥à¤¤à¥ मारà¥à¤—" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "सङà¥à¤•ेत र इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸ नाम" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "सङà¥à¤•ेत उतà¥à¤¸à¤°à¥à¤œà¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "'%s' मा जडान हà¥à¤¦à¥ˆ...\n" + +#: gio/gdbus-tool.c:704 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿:%s मानà¥à¤¯ जà¥à¤žà¤¾à¤¤ बस नाम होइन।\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: वसà¥à¤¤à¥ मारà¥à¤— निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नगरेको \n" + +#: gio/gdbus-tool.c:766 +#, fuzzy +#| msgid "Error: Method name is not specified\n" +msgid "Error: Signal name is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: विधि नाम निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ छैन\n" + +#: gio/gdbus-tool.c:780 +#, fuzzy, c-format +#| msgid "Error: Method name “%s†is invalid\n" +msgid "Error: Signal name “%s†is invalid\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s अवैध विधि नाम\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s अवैध इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸ नाम\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿:%s मानà¥à¤¯ सदसà¥à¤¯ नाम होइन।\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "पà¥à¤¯à¤¾à¤°à¤¾à¤®à¤¿à¤Ÿà¤° पदवरà¥à¤£à¤¨ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s मा जडान खोलà¥à¤¨ सकेन\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "गनà¥à¤¤à¤µà¥à¤¯ नाम विधि आहà¥à¤µà¤¾à¤¨" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "डेटासà¥à¤°à¥‹à¤¤ कनà¥à¤«à¤¿à¤—रेसन तà¥à¤°à¥à¤Ÿà¤¿:निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नगरेको पà¥à¤°à¤¦à¤¾à¤¯à¤•" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "विधि र इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸ नाम" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "सेकेणà¥à¤¡à¤®à¤¾ समय समापà¥à¤¤à¤¿" + +#: gio/gdbus-tool.c:899 +#, fuzzy +#| msgid "Show information about locations" +msgid "Allow interactive authorization" +msgstr "पà¥à¤°à¤®à¤¾à¤£à¤¿à¤•रण असफल" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "" +"आदेशहरू:\n" +" help   यो जानकारी देखाउà¤à¤¦à¤›\n" +" introspect   introspect à¤à¤• रिमोट वसà¥à¤¤à¥ घà¥à¤¸à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" monitor   मनिटरमा टाढाको वसà¥à¤¤à¥ मनिटर\n" +" call   कल रिमोट वसà¥à¤¤à¥à¤®à¤¾ à¤à¤‰à¤Ÿà¤¾ विधि निमनà¥à¤¤à¥à¤°à¤£à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" emit   उतà¥à¤¸à¤°à¥à¤œà¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" wait   पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"\n" +"पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• आदेशमा मदà¥à¤¦à¤¤ पाउन \"% s COMMAND --help\" को पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤" + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: गनà¥à¤¤à¤µà¥à¤¯ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नगरेको\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, fuzzy, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿:%s मानà¥à¤¯ जà¥à¤žà¤¾à¤¤ बस नाम होइन।\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: विधि नाम निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ छैन\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s अवैध विधि नाम\n" + +#: gio/gdbus-tool.c:1168 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "पà¥à¤¯à¤¾à¤°à¤¾à¤®à¤¿à¤Ÿà¤° पदवरà¥à¤£à¤¨ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "%d हà¥à¤¯à¤¾à¤¨à¥à¤¡à¤² थपà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "निगरानिको लागि गनà¥à¤¤à¤µà¥à¤¯ नाम" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "डेटासà¥à¤°à¥‹à¤¤ कनà¥à¤«à¤¿à¤—रेसन तà¥à¤°à¥à¤Ÿà¤¿:निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नगरेको पà¥à¤°à¤¦à¤¾à¤¯à¤•" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "XML मà¥à¤¦à¥à¤°à¤£ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gdbus-tool.c:1698 +#, fuzzy +msgid "Introspect children" +msgstr "शाखाहरà¥" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "मà¥à¤¦à¥à¤°à¤£ गà¥à¤£à¤¹à¤°à¥‚ मातà¥à¤°" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "" +"आदेशहरू:\n" +" help   यो जानकारी देखाउà¤à¤¦à¤›\n" +" introspect   introspect à¤à¤• रिमोट वसà¥à¤¤à¥ घà¥à¤¸à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" monitor   मनिटरमा टाढाको वसà¥à¤¤à¥ मनिटर\n" +" call   कल रिमोट वसà¥à¤¤à¥à¤®à¤¾ à¤à¤‰à¤Ÿà¤¾ विधि निमनà¥à¤¤à¥à¤°à¤£à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" emit   उतà¥à¤¸à¤°à¥à¤œà¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" wait   पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"\n" +"पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• आदेशमा मदà¥à¤¦à¤¤ पाउन \"% s COMMAND --help\" को पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤" + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "निगरानिको लागि गनà¥à¤¤à¤µà¥à¤¯ नाम" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "वसà¥à¤¤à¥ पथ निगरानी" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "" +"आदेशहरू:\n" +" help   यो जानकारी देखाउà¤à¤¦à¤›\n" +" introspect   introspect à¤à¤• रिमोट वसà¥à¤¤à¥ घà¥à¤¸à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" monitor   मनिटरमा टाढाको वसà¥à¤¤à¥ मनिटर\n" +" call   कल रिमोट वसà¥à¤¤à¥à¤®à¤¾ à¤à¤‰à¤Ÿà¤¾ विधि निमनà¥à¤¤à¥à¤°à¤£à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" emit   उतà¥à¤¸à¤°à¥à¤œà¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" wait   पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"\n" +"पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• आदेशमा मदà¥à¤¦à¤¤ पाउन \"% s COMMAND --help\" को पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤" + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: सनà¥à¤¦à¥‡à¤¶-विहिन जडान अनà¥à¤—मन गरà¥à¤¨ सकेन\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2205 +msgid "Timeout to wait for before exiting with an error (seconds); 0 for no timeout (default)" +msgstr "" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[विकलà¥à¤ªâ€¦]बस नाम" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "à¤à¤‰à¤Ÿà¤¾ बस नामको लागि परà¥à¤–नà¥à¤¹à¥‹à¤¸à¥à¥¤" + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: सकà¥à¤°à¤¿à¤¯ गरà¥à¤¨à¤•ा लागि à¤à¤‰à¤Ÿà¤¾ सेवा निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरà¥à¤¨à¥ परà¥à¤¦à¤› ।\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ गरà¥à¤¨à¥à¤ªà¤°à¥à¤¨à¥‡ सेवा निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरà¥à¤¨à¥ परà¥à¤¦à¤› ।\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: निकै धेरै तरà¥à¤•हरू\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿:%s मानà¥à¤¯ जà¥à¤žà¤¾à¤¤ बस नाम होइन।\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿ सचà¥à¤¯à¤¾à¤‰à¤¨à¥‡ सेटिङ परिवरà¥à¤¤à¤¨ गरà¥à¤¨ अधिकार पà¥à¤°à¤¾à¤ªà¥à¤¤ छैन" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "बेनामी" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "डेसà¥à¤•टप फाइलले Exec फाà¤à¤Ÿ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरेन" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— लागी टरà¥à¤®à¤¿à¤¨à¤² खोजà¥à¤¨ असकà¥à¤·à¤®" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "%s पà¥à¤°à¤¯à¥‹à¤—करà¥à¤¤à¤¾ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— कनà¥à¤«à¤¿à¤—रेसन फोलà¥à¤¡à¤° सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "%s पà¥à¤°à¤¯à¥‹à¤—करà¥à¤¤à¤¾ MIME कनà¥à¤«à¤¿à¤—रेसन फोलà¥à¤¡à¤° सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— सूचनामा पहिचायकको कमी छ" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "%s पà¥à¤°à¤¯à¥‹à¤—करà¥à¤¤à¤¾ डेसà¥à¤•टप फाइल सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ सकेन" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "%s को अनà¥à¤•ूल परिभाषा" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "डà¥à¤°à¤¾à¤‡à¤­à¤²à¥‡ निकालà¥à¤¨à¥‡ कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "डà¥à¤°à¤¾à¤‡à¤­à¤²à¥‡ निकालà¥à¤¨à¥‡ वा eject_with_operation कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "डà¥à¤°à¤¾à¤‡à¤­à¤²à¥‡ मिडियाका लागि गणना कारà¥à¤¯à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "डà¥à¤°à¤¾à¤‡à¤­à¤²à¥‡ सà¥à¤°à¥à¤†à¤¤ कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "डà¥à¤°à¤¾à¤‡à¤­à¤²à¥‡ रोक कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS समरà¥à¤¥à¤¨ उपलबà¥à¤§ छैन" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS समरà¥à¤¥à¤¨ उपलबà¥à¤§ छैन" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "GEmblem सङà¥à¤•ेतनको संसà¥à¤•रण %d हà¥à¤¯à¤¾à¤£à¥à¤¡à¤² गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon सङà¥à¤•ेतनको संसà¥à¤•रण %d हà¥à¤¯à¤¾à¤¨à¥à¤¡à¤² गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: gio/gemblemedicon.c:395 +#, fuzzy +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "अङà¥à¤• अपेकà¥à¤·à¤¿à¤¤" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "समाविषà¥à¤Ÿ माउनà¥à¤Ÿ अवसà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ामा पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gfile.c:2686 +#, fuzzy +msgid "Can’t copy directory over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ामा पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "लकà¥à¤·à¥à¤¯ फाइल अवसà¥à¤¥à¤¿à¤¤ छ" + +#: gio/gfile.c:2713 +#, fuzzy +msgid "Can’t recursively copy directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ामा पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "सà¥à¤ªà¥à¤²à¤¿à¤¸ समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gfile.c:3018 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ %s: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "माउनà¥à¤Ÿà¤¹à¤°à¥‚को बीचमा पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ (reflink/clone) समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ (reflink/clone) समरà¥à¤¥à¤¿à¤¤ वा अवैध छैन" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ (reflink/clone) समरà¥à¤¥à¤¿à¤¤ छैन वा काम गरेको छैन" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "विशेष फाइल पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ गरà¥à¤¨ सकà¥à¤¦à¥ˆà¤¨" + +#: gio/gfile.c:4138 +#, fuzzy +msgid "Invalid symlink value given" +msgstr " पहिलà¥à¤¯à¥ˆ नै दिà¤à¤•ो छ" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "सांकेतिक समà¥à¤¬à¤¨à¥à¤§ समरà¥à¤¥à¤¨ गरिà¤à¤¨" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•री समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "फाइल नामहरूमा “%c†समावेश गरà¥à¤¨ सकà¥à¤¦à¥ˆà¤¨" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "भोलà¥à¤¯à¥à¤®à¤²à¥‡ माउनà¥à¤Ÿ कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "यस फाइल हेरà¥à¤¨ पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— दरà¥à¤¤à¤¾ गरिà¤à¤•ो छैन।" + +#: gio/gfileenumerator.c:212 +#, fuzzy +msgid "Enumerator is closed" +msgstr "फाइल गणनाकरà¥à¤¤à¤¾ पहिले नै बनà¥à¤¦ छ" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "फाइल गणनाकरà¥à¤¤à¤¾ पहिले नै बनà¥à¤¦ छ" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "GFile Icon सङà¥à¤•ेतनको संसà¥à¤•रण %d हà¥à¤¯à¤¾à¤£à¥à¤¡à¤² गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gfileicon.c:260 +#, fuzzy +msgid "Malformed input data for GFileIcon" +msgstr "कà¥à¤°à¤®à¤¾à¤™à¥à¤•न गरिà¤à¤•ो डेटा विकृत छ" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "सà¥à¤Ÿà¥à¤°à¤¿à¤®à¤®à¤¾ खोजी समरà¥à¤¥à¤¿à¤¤ छैन " + +#: gio/gfileinputstream.c:369 +#, fuzzy +msgid "Truncate not allowed on input stream" +msgstr "आधार सà¥à¤Ÿà¥à¤°à¥€à¤®à¤®à¤¾ कताई समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤®à¤®à¤¾ कताई समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "अवैध होसà¥à¤Ÿà¤¨à¤¾à¤®" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "खराब HTTP पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ जवाफ" + +#: gio/ghttpproxy.c:159 +#, fuzzy +msgid "HTTP proxy connection not allowed" +msgstr "खराब HTTP पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ जवाफ" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "à¤à¤šà¤Ÿà¥€à¤Ÿà¥€à¤ªà¥€ (HTTP) पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण असफल भयो" + +#: gio/ghttpproxy.c:167 +#, fuzzy +msgid "HTTP proxy authentication required" +msgstr "à¤à¤šà¤Ÿà¥€à¤Ÿà¥€à¤ªà¥€ (HTTP) पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण असफल भयो" + +#: gio/ghttpproxy.c:171 +#, fuzzy, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "à¤à¤šà¤Ÿà¥€à¤Ÿà¥€à¤ªà¥€ (HTTP) पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण असफल भयो" + +#: gio/ghttpproxy.c:266 +#, fuzzy +msgid "HTTP proxy response too big" +msgstr "à¤à¤šà¤Ÿà¥€à¤Ÿà¥€à¤ªà¥€ (HTTP) पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण असफल भयो" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "" + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "गलत टोकन सङà¥à¤–à¥à¤¯à¤¾ (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "वरà¥à¤— नाम %s का लागि कà¥à¤¨à¥ˆ पà¥à¤°à¤•ार छैन" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "पà¥à¤°à¤•ार %s वरà¥à¤—िकरण गरिà¤à¤•ो छैन" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "विकृत संसà¥à¤•रण सङà¥à¤–à¥à¤¯à¤¾: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "पà¥à¤°à¤¤à¤¿à¤®à¤¾ सङà¥à¤•ेतनको आपूरà¥à¤¤à¤¿ गरिà¤à¤•ो संसà¥à¤•रण हà¥à¤¯à¤¾à¤¨à¥à¤¡à¤² गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "ठेगाना निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छैन" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "ठेगानाको लागि %u धेरै लामो छ" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ठेगानामा उपसरà¥à¤— लमà¥à¤¬à¤¾à¤‡ भनà¥à¤¦à¤¾ बाहिर बिटहरू सेट गरिà¤à¤•ो छ" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "आईपी ठेगाना मासà¥à¤•को रूपमा \"%s\" पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकेन" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 gio/gnativesocketaddress.c:109 +#: gio/gunixsocketaddress.c:228 +#, fuzzy +msgid "Not enough space for socket address" +msgstr "डिसà¥à¤•मा परà¥à¤¯à¤¾à¤ªà¥à¤¤ खालीसà¥à¤¥à¤¾à¤¨ उपलबà¥à¤§ छैन" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "असमरà¥à¤¥à¤¿à¤¤ सकेट ठेगाना" + +#: gio/ginputstream.c:188 +#, fuzzy +msgid "Input stream doesn’t implement read" +msgstr "आगत पà¥à¤°à¤µà¤¾à¤¹à¤²à¥‡ खोजी कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +#, fuzzy +msgid "Stream has outstanding operation" +msgstr "अलारà¥à¤®à¤®à¤¾ केहि अपà¥à¤°à¥‹ काम छ।" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "फाइलसहित पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "सारà¥à¤¦à¤¾ फाइल राखà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "\"संसà¥à¤•रण\" ले कà¥à¤¨à¥ˆ तरà¥à¤•हरू लिदैन" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "पà¥à¤°à¤¯à¥‹à¤—:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "संसà¥à¤•रण सूचना छापà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ र बाहिर निसà¥à¤•नà¥à¤¹à¥‹à¤¸à¥à¥¤" + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "आदेशहरू:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "मानक पà¥à¤°à¤¤à¤¿à¤«à¤² मा फाइलहरूको समायोजन" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "à¤à¤• वा धेरै फाइलहरू पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¥€ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "सà¥à¤¥à¤¾à¤¨à¤¹à¤°à¥‚को बारेमा जानकारी देखाउनà¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:232 +#, fuzzy +#| msgid "Launch an application" +msgid "Launch an application from a desktop file" +msgstr "(.desktop फाइलबाट) अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—का लागि सà¥à¤¥à¤¿à¤° कारà¥à¤¯à¤¹à¤°à¥‚ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:233 +#, fuzzy +msgid "List the contents of locations" +msgstr "फाइलहरू रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•रीमा तिनीहरूको मौलिक सà¥à¤¥à¤¾à¤¨à¤¸à¤à¤— सूचीकृत गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "à¤à¤•ैसाथ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ र सेट/अनसेट गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "नयाठडाइरेकà¥à¤Ÿà¤°à¥€ सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "परिवरà¥à¤¤à¤¨à¤¹à¤°à¥‚का लागि फाईलहरू र डाइरेकà¥à¤Ÿà¤°à¥€à¤¹à¤°à¥‚ निगरानि गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:237 +#, fuzzy +msgid "Mount or unmount the locations" +msgstr "सà¥à¤¥à¤¾à¤¨ माउनà¥à¤Ÿ वा अनमाउनà¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤" + +#: gio/gio-tool.c:238 +#, fuzzy +msgid "Move one or more files" +msgstr "à¤à¤• वा धेरै फाइलहरू पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¥€ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— दà¥à¤µà¤¾à¤°à¤¾ फाइल खोलà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "फाइल पà¥à¤¨:नामाकरण गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "à¤à¤• वा धेरै फाइलहरू मेटà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:242 +#, fuzzy +msgid "Read from standard input and save" +msgstr "मानक आगतमा तà¥à¤°à¥à¤Ÿà¤¿ पढà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "फाइलविशेषता सेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "फाईलहरू वा डाइरेकà¥à¤Ÿà¤°à¥€à¤¹à¤°à¥‚ रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•रीमा सारà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "विसà¥à¤¤à¥ƒà¤¤ मदà¥à¤¦à¤¤ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ \"%s\" पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।\n" + +#: gio/gio-tool-cat.c:87 +#, fuzzy +msgid "Error writing to stdout" +msgstr "%s: %s: सà¥à¤Ÿà¤¡à¤†à¤‰à¤Ÿà¤®à¤¾ लेखà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 gio/gio-tool-mkdir.c:48 +#: gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 gio/gio-tool-remove.c:48 +#: gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "सà¥à¤¥à¤¾à¤¨" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "मानक पà¥à¤°à¤¤à¤¿à¤«à¤²à¤®à¤¾ समायोजन फाइल मà¥à¤¦à¥à¤°à¤£ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 gio/gio-tool-monitor.c:229 +#: gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "कà¥à¤¨à¥ˆ सà¥à¤¥à¤¾à¤¨ दिà¤à¤•ो छैन" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "लकà¥à¤·à¤¿à¤¤ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा छैन" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "पà¥à¤°à¤—ति देखाउनà¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +#, fuzzy +msgid "Prompt before overwrite" +msgstr "अधिलेखन गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "सबै विशेषता सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "अवसà¥à¤¥à¤¿à¤¤ गनà¥à¤¤à¤¬à¥à¤¯ फाइलहरू जगेडा गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "साङà¥à¤•ेतिक लिङà¥à¤• नपछà¥à¤¯à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "गनà¥à¤¤à¤¬à¥à¤¯à¤•ा लागि पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ अनà¥à¤®à¤¤à¤¿à¤¹à¤°à¥‚ पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%s बाट %s (%s/s) सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ " + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "सà¥à¤°à¥‹à¤¤" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "गनà¥à¤¤à¤¬à¥à¤¯" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "सà¥à¤°à¥‹à¤¤à¤¬à¤¾à¤Ÿ गनà¥à¤¤à¤µà¥à¤¯à¤®à¤¾ à¤à¤• वा बढी फाइलहरू पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ बनाउनà¥à¤¹à¥‹à¤¸à¥ ।" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "लकà¥à¤·à¤¿à¤¤ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा “%s†निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा होईन" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: अधिलेखन “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "लेखà¥à¤¨à¤¯à¥‹à¤—à¥à¤¯ विशेषताहरू सà¥à¤šà¥€à¤¬à¤¦à¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "फाइल सूचना पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "विशेषताहरू पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "बिषेषताहरà¥" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "साङà¥à¤•ेतिक लिङà¥à¤• नपछà¥à¤¯à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "विशेषताहरू:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "पà¥à¤°à¤¦à¤°à¥à¤¶à¤¨ नाम %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "नाम समà¥à¤ªà¤¾à¤¦à¤¨ : %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "नाम: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "पà¥à¤°à¤•ार: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "साइज: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "लà¥à¤•ाइà¤à¤•ो\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "सà¥à¤¥à¤¾à¤¨à¥€à¤¯ मारà¥à¤—: %s\n" + +#: gio/gio-tool-info.c:205 +#, fuzzy, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "फाइल %s का लागि माउनà¥à¤Ÿ समाविषà¥à¤Ÿ फेला परेन" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "सà¥à¤²à¤­ विशेषताहरू:\n" + +#: gio/gio-tool-info.c:310 +#, fuzzy +msgid "Writable attribute namespaces:\n" +msgstr "कà¥à¤žà¥à¤œà¥€ लेखनयोगà¥à¤¯ छैन\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "सà¥à¤¥à¤¾à¤¨à¤¹à¤°à¥‚को बारेमा जानकारी देखाउनà¥à¤¹à¥‹à¤¸à¥à¥¤" + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-FILE [FILE-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "Launch an application from a desktop file, passing optional filename arguments to it." +msgstr "" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "डेसà¥à¤•टप फाइल छैन" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "'%s' लोड गरà¥à¤¨ अकà¥à¤·à¤®: %s" + +#: gio/gio-tool-launch.c:107 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Unable to load application information for ‘%s‘" +msgstr "%s लोड गरà¥à¤¨ असमरà¥à¤¥" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "'%s' अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— सà¥à¤°à¥à¤†à¤¤ गरà¥à¤¨ अकà¥à¤·à¤®: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "लà¥à¤•ेका फाइलहरू देखाउनà¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "लामो सूची ढाà¤à¤šà¤¾ पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "पà¥à¤°à¤¦à¤°à¥à¤¶à¤¨ नाम मà¥à¤¦à¥à¤°à¤£ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "पूरा URIs मà¥à¤¦à¥à¤°à¤£ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-list.c:177 +#, fuzzy +msgid "List the contents of the locations." +msgstr "फाइलहरू रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•रीमा तिनीहरूको मौलिक सà¥à¤¥à¤¾à¤¨à¤¸à¤à¤— सूचीकृत गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "हà¥à¤¯à¤¾à¤¨à¥à¤¡à¤²à¤°" + +#: gio/gio-tool-mime.c:76 +#, fuzzy +msgid "Get or set the handler for a mimetype." +msgstr "à¤à¤•ैसाथ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ र सेट/अनसेट गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "“%s†लागि पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— छैन \n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "“%s†लागि पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— दरà¥à¤¤à¤¾:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— दरà¥à¤¤à¤¾ छैन:\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "सिफारिस गरिà¤à¤•ो अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤—\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "सिफारिस गरिà¤à¤•ो अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— छैन\n" + +#: gio/gio-tool-mime.c:162 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° लोड गरà¥à¤¨ असफल: %s" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "\"%s\" का लागि पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ हà¥à¤¯à¤¾à¤¨à¥à¤¡à¤²à¤°à¤•ो रूपमा \"%s\" सेट गरà¥à¤¨ असफल भयो: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "पà¥à¤°à¤®à¥à¤² निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥." + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: gio/gio-tool-monitor.c:37 +#, fuzzy +msgid "Monitor a directory (default: depends on type)" +msgstr "फाइल अनà¥à¤—मन गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ (पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤: पà¥à¤°à¤•ारमा निरà¥à¤­à¤° हà¥à¤¨à¥à¤›)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "फाइल अनà¥à¤—मन गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ (पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤: पà¥à¤°à¤•ारमा निरà¥à¤­à¤° हà¥à¤¨à¥à¤›)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "माउनà¥à¤Ÿ घटनाका लागि हेरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "फाईलहरू वा निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ाहरू परिवरà¥à¤¤à¤¨à¤¹à¤°à¥‚का लागि निगरानि" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "माउनà¥à¤Ÿ गरà¥à¤¨ योगà¥à¤¯à¤•ो रूपमा माउनà¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-mount.c:64 +#, fuzzy +msgid "Mount volume with device file, or other identifier" +msgstr "यनà¥à¤¤à¥à¤° माउनà¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "आईडी" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "अनमाउणà¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "निकाल" + +#: gio/gio-tool-mount.c:67 +#, fuzzy +msgid "Stop drive with device file" +msgstr "उपकरण फाइलका लागि डà¥à¤°à¤¾à¤‡à¤­ छैन" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "यनà¥à¤¤à¥à¤°" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "योजना" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "सà¥à¤šà¥€" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "घटनाहरू निगरानि गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "थप जानकारी देखाउनà¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +#| msgctxt "GDateTime" +#| msgid "PM" +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "TCRYPT लà¥à¤•ेका भोलà¥à¤¯à¥à¤® माउनà¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "TCRYPT पà¥à¤°à¤£à¤¾à¤²à¥€ भोलà¥à¤¯à¥à¤® माउनà¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "बेनामी पहà¥à¤à¤š असà¥à¤µà¥€à¤•ृत भयो" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "उपकरण फाइलका लागि डà¥à¤°à¤¾à¤‡à¤­ छैन" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "दिà¤à¤•ो आईडीका लागि भोलà¥à¤¯à¥à¤® छैन" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "सà¥à¤¥à¤¾à¤¨ माउनà¥à¤Ÿ वा अनमाउनà¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: gio/gio-tool-move.c:99 +#, fuzzy +msgid "Move one or more files from SOURCE to DEST." +msgstr "सà¥à¤°à¥‹à¤¤à¤¬à¤¾à¤Ÿ गनà¥à¤¤à¤µà¥à¤¯à¤®à¤¾ à¤à¤• वा बढी फाइलहरू पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ बनाउनà¥à¤¹à¥‹à¤¸à¥ ।" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: gio/gio-tool-move.c:143 +#, fuzzy, c-format +msgid "Target %s is not a directory" +msgstr "लकà¥à¤·à¤¿à¤¤ निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा छैन" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "दिà¤à¤•ो फाइल मेटà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "नाम" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "फाइल पà¥à¤¨:नामाकरण गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "छà¥à¤Ÿà¥‡à¤•ो तरà¥à¤•" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "निकै धेरै तरà¥à¤•हरू" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "यदि अवसà¥à¤¥à¤¿à¤¤ छैन भने मातà¥à¤° सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "फाइलको अनà¥à¤¤à¥à¤¯à¤®à¤¾ थपà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +#, fuzzy +msgid "Print new etag at end" +msgstr "नयाठअनà¥à¤¤à¥à¤¯: %1" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +#, fuzzy +msgid "Error reading from standard input" +msgstr "हेनà¥à¤¦à¤²à¤¬à¤¾à¤Ÿ पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +#, fuzzy +msgid "Etag not available\n" +msgstr "ETAG" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "गनà¥à¤¤à¤µà¥à¤¯ दिइà¤à¤•ो छैन" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "विशेषताका पà¥à¤°à¤•ार" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "पà¥à¤°à¤•ार" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "विशेषता" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "मान" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "सà¥à¤¥à¤¾à¤¨à¤•ो फाइल विशेषता सेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।" + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "सà¥à¤¥à¤¾à¤¨ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ोछैन" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ विशेषता छैन" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "मान निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नगरिà¤à¤•ो" + +#: gio/gio-tool-set.c:180 +#, fuzzy, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•री खाली गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "फाइलहरू रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•रीमा तिनीहरूको मौलिक सà¥à¤¥à¤¾à¤¨à¤¸à¤à¤— सूचीकृत गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-trash.c:36 +msgid "Restore a file from trash to its original location (possibly recreating the directory)" +msgstr "" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "मौलिक मारà¥à¤— फेला पारà¥à¤¨ असकà¥à¤·à¤®" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "मौलिक सà¥à¤¥à¤¾à¤¨ पà¥à¤¨: सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ अकà¥à¤·à¤®: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "फाइललाई यसको मौलिक सà¥à¤¥à¤¾à¤¨à¤®à¤¾ सारà¥à¤¨ अकà¥à¤·à¤®: " + +#: gio/gio-tool-trash.c:225 +#, fuzzy +#| msgid "Move files or directories to the trash." +msgid "Move/Restore files or directories to the trash." +msgstr "फाईलहरू वा डाइरेकà¥à¤Ÿà¤°à¥€à¤¹à¤°à¥‚ रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•रीमा सारà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "साङà¥à¤•ेतिक लिङà¥à¤•, माउनà¥à¤Ÿ र सरà¥à¤Ÿà¤•ट पछà¥à¤¯à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "ततà¥à¤µ <%s> <%s भितà¥à¤° अनà¥à¤®à¤¤à¤¿ छैन>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "ततà¥à¤µ <%s> माथिलà¥à¤²à¥‹ सà¥à¤¤à¤°à¤®à¤¾ अनà¥à¤®à¤¤à¤¿ छैन" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "कà¥à¤¨à¥ˆ पनि सà¥à¤°à¥‹à¤¤ डाइरेकà¥à¤Ÿà¤°à¥€à¤®à¤¾ \"%s\" पाउन असफल" + +#: gio/glib-compile-resources.c:256 +#, fuzzy, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "कà¥à¤¨à¥ˆ पनि सà¥à¤°à¥‹à¤¤ डाइरेकà¥à¤Ÿà¤°à¥€à¤®à¤¾ \"%s\" पाउन असफल" + +#: gio/glib-compile-resources.c:290 +#, fuzzy, c-format +#| msgid "Unknown option %s" +msgid "Unknown processing option “%sâ€" +msgstr "अजà¥à¤žà¤¾à¤¤ विकलà¥à¤ª %s" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "%s पूरà¥à¤µ पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ अनà¥à¤°à¥‹à¤§ गरियो, तर %s सेट भà¤à¤•ो छैन, र %s पथ होइन" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ %s: %s" + +#: gio/glib-compile-resources.c:477 +#, fuzzy, c-format +msgid "Error compressing file %s" +msgstr "फाइलहरू सङà¥à¤•à¥à¤šà¤¨à¤®à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/glib-compile-resources.c:541 +#, fuzzy, c-format +msgid "text may not appear inside <%s>" +msgstr "पाठ <%s> भितà¥à¤° देखा परà¥à¤¦à¥ˆà¤¨" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "कारà¥à¤¯à¤•à¥à¤°à¤® संसà¥à¤•रण देखाउनà¥à¤¹à¥‹à¤¸à¥ र निसà¥à¤•नà¥à¤¹à¥‹à¤¸à¥" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "निरà¥à¤—त फाइलको नाम" + +#: gio/glib-compile-resources.c:821 +msgid "The directories to load files referenced in FILE from (default: current directory)" +msgstr "" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा" + +#: gio/glib-compile-resources.c:822 +msgid "Generate output in the format selected for by the target filename extension" +msgstr "" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "सà¥à¤°à¥‹à¤¤ हेडर सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" + +#: gio/glib-compile-resources.c:825 +#, fuzzy +msgid "Generate dependency list" +msgstr "जडान निरà¥à¤­à¤°à¤¤à¤¾ विफल" + +#: gio/glib-compile-resources.c:826 +#, fuzzy +msgid "Name of the dependency file to generate" +msgstr "यो नामको फाइल पहिलà¥à¤¯à¥ˆ अवसà¥à¤¥à¤¿à¤¤ छ" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: gio/glib-compile-resources.c:830 +msgid "Don’t embed resource data in the C file; assume it's linked externally instead" +msgstr "" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "सिरà¥à¤œà¤¨à¤¾ गरिà¤à¤•ो सà¥à¤°à¥‹à¤¤ सङà¥à¤•ेतका लागि पà¥à¤°à¤¯à¥‹à¤— गरिà¤à¤•ो C पहिचायक नाम" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "उपनाम कमà¥à¤¤à¤¿à¤®à¤¾ २ वरà¥à¤£à¤•ो हà¥à¤¨à¥à¤ªà¤°à¥à¤›" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "सङà¥à¤–à¥à¤¯à¤¾à¤¤à¥à¤®à¤• मान अवैध छ" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "मान ='%s' पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> कमà¥à¤¤à¥€à¤®à¤¾ à¤à¤• <मान> हà¥à¤¨à¥ परà¥à¤¦à¤›" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ दायरामा समावेश गरिà¤à¤•ो छैन" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो इनà¥à¤¯à¥à¤®à¤°à¥‡à¤Ÿ पà¥à¤°à¤•ारको वैध सदसà¥à¤¯ होइन" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> ले निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ à¤à¤£à¥à¤¡à¤¾ पà¥à¤°à¤•ारमा सà¥à¤Ÿà¥à¤°à¤¿à¤™ समाविषà¥à¤Ÿ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr " मा नभà¤à¤•ो <%s> मा समावेश " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " कà¥à¤žà¥à¤œà¤¿ पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नà¥à¤¯à¥‚नतम अधिकतम भनà¥à¤¦à¤¾ ठूलो छ" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "असमरà¥à¤¥à¤¿à¤¤ l10n कोटि: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, fuzzy, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "चेतावनी: पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ `%s' मान सà¥à¤•िमा (%s) का लागि पद वरà¥à¤£à¤¨ गरà¥à¤¨ असफल भयो\n" + +#: gio/glib-compile-schemas.c:491 +msgid " cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " कà¥à¤žà¥à¤œà¤¿ पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " पहिलà¥à¤¯à¥ˆ नै दिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " बाट कमà¥à¤¤à¤¿à¤®à¤¾ à¤à¤• समाविषà¥à¤Ÿ गरà¥à¤¨à¥ परà¥à¤¦à¤›à¥¤ " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr "यो कà¥à¤žà¥à¤œà¥€à¤•ा लागि पहिलà¥à¤¯à¥ˆ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:561 +msgid " can only be specified for keys with enumerated or flags types or after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid " given when “%s†is already a member of the enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "उरà¥à¤« लकà¥à¤·à¥à¤¯ \"%s\" इनà¥à¤¯à¥à¤®à¤°à¥‡à¤Ÿ पà¥à¤°à¤•ारमा छैन" + +#: gio/glib-compile-schemas.c:605 +#, fuzzy, c-format +msgid "alias target “%s†is not in " +msgstr "उरà¥à¤« लकà¥à¤·à¥à¤¯ \"%s\" इनà¥à¤¯à¥à¤®à¤°à¥‡à¤Ÿ पà¥à¤°à¤•ारमा छैन" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "कमà¥à¤¤à¤¿à¤®à¤¾ à¤à¤‰à¤Ÿà¤¾ समावेश गरà¥à¤¨à¥à¤ªà¤°à¥à¤›" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "खाली नाम अनà¥à¤®à¤¤à¤¿ छैन" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers and hyphen (“-â€) are permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "अवैध नाम \"%s\": अधिकतम लमà¥à¤¬à¤¾à¤ˆ १०२४ हो" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "\"सूची-को\" सà¥à¤•ीमामा कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ थपà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid " shadows in ; use to modify value" +msgstr "" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute to " +msgstr "\"type\", \"enum\" वा \"flags\" मधà¥à¤¯à¥‡ à¤à¤‰à¤Ÿà¤¾à¤²à¤¾à¤ˆ विशेषताको रूपमा निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरà¥à¤¨à¥ परà¥à¤¦à¤› " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> परिभाषित गरिà¤à¤•ो छैन ।." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "अवैध जिभेरिà¤à¤¨à¥à¤Ÿ पà¥à¤°à¤•ार सà¥à¤Ÿà¥à¤°à¤¿à¤™ \"%s\"" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "अधिलेखन गरà¥à¤¨ छैन" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1169 +#, fuzzy, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " सूची हो, विसà¥à¤¤à¤¾à¤° गरà¥à¤¦à¥ˆ जà¥à¤¨ सूची होइन" + +#: gio/glib-compile-schemas.c:1177 +#, fuzzy, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "\"सूची-को\" सà¥à¤•ीमामा कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ थपà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/glib-compile-schemas.c:1187 +#, fuzzy, c-format +msgid "Cannot extend a schema with a path" +msgstr "[SCHEMA[:PATH]]" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid " is a list, extending which is not a list" +msgstr " सूची हो, विसà¥à¤¤à¤¾à¤° गरà¥à¤¦à¥ˆ जà¥à¤¨ सूची होइन" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid " extends but “%s†does not extend “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "यदि दिइà¤à¤•ो भà¤, पथ सà¥à¤²à¥à¤¯à¤¾à¤¸à¤¸à¤à¤— सà¥à¤°à¥ र अनà¥à¤¤à¥à¤¯ हà¥à¤¨à¥à¤ªà¤°à¥à¤¦à¤›" + +#: gio/glib-compile-schemas.c:1231 +#, fuzzy, c-format +msgid "The path of a list must end with “:/â€" +msgstr "यदि दिइà¤à¤•ो भà¤, पथ सà¥à¤²à¥à¤¯à¤¾à¤¸à¤¸à¤à¤— सà¥à¤°à¥ र अनà¥à¤¤à¥à¤¯ हà¥à¤¨à¥à¤ªà¤°à¥à¤¦à¤›" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> पहिलà¥à¤¯à¥ˆ नै निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छ" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "<%s> ततà¥à¤µ à¤à¤‰à¤Ÿà¤¾ मातà¥à¤° <%s> भितà¥à¤° अनà¥à¤®à¤¤à¤¿ दिइयो" + +#: gio/glib-compile-schemas.c:1518 +#, fuzzy, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "ततà¥à¤µ <%s> <%s भितà¥à¤° अनà¥à¤®à¤¤à¤¿ छैन>" + +#: gio/glib-compile-schemas.c:1536 +#, fuzzy +msgid "Element is required in " +msgstr "%s को पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ मà¥à¤¦à¥à¤°à¤• पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण आवशà¥à¤¯à¤• छ" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "पाठ <%s> भितà¥à¤° देखा परà¥à¤¦à¥ˆà¤¨" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +#, fuzzy +msgid "--strict was specified; exiting." +msgstr "अनà¥à¤•ूलता वà¥à¤¯à¤¬à¤¸à¥à¤¥à¤¾à¤ªà¤•लाई सकà¥à¤°à¤¿à¤¯ बनाउन सकिà¤à¤¨ ।Exiting." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "यो समà¥à¤ªà¥‚रà¥à¤£ फाइल उपेकà¥à¤·à¤¾ गरिà¤à¤•ो छ ।" + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "यो फाइल उपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆà¤› ।" + +#: gio/glib-compile-schemas.c:1963 +#, fuzzy, c-format +msgid "No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring override for this key." +msgstr "चेतावनी: (%s) निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो कà¥à¤žà¥à¤œà¥€ अनतरà¥à¤—त सà¥à¤•िमाका लागि - उपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆ\n" + +#: gio/glib-compile-schemas.c:1971 +#, fuzzy, c-format +msgid "No such key “%s†in schema “%s†as specified in override file “%s†and --strict was specified; exiting." +msgstr "चेतावनी: (%s) निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो कà¥à¤žà¥à¤œà¥€ अनतरà¥à¤—त सà¥à¤•िमाका लागि - उपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆ\n" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema “%s†(override file “%sâ€); ignoring override " +"for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema “%s†(override file “%sâ€) and --strict was " +"specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: %s. Ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: %s. --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the range given in the schema; ignoring " +"override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the range given in the schema and --strict was " +"specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the list of valid choices; ignoring override " +"for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the list of valid choices and --strict was " +"specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "gschemas.compiled फाइल कहाठभणà¥à¤¡à¤¾à¤°à¤£ गरà¥à¤¨à¥‡" + +#: gio/glib-compile-schemas.c:2174 +#, fuzzy +msgid "Abort on any errors in schemas" +msgstr "%s ले कà¥à¤¨à¥ˆ तà¥à¤°à¥à¤Ÿà¤¿à¤¹à¤°à¥‚ दिà¤à¤•ो छैन ।" + +#: gio/glib-compile-schemas.c:2175 +#, fuzzy +msgid "Do not write the gschema.compiled file" +msgstr "कà¥à¤¯à¤¾à¤¸ फाइल लेखà¥à¤¨ असफल भयो: %s\n" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "सà¥à¤•िमा फाइल फेला परेन: केही पनि गरिरहेको छैन ।" + +#: gio/glib-compile-schemas.c:2271 +#, fuzzy +msgid "No schema files found: removed existing output file." +msgstr "फाइलबाट अवसà¥à¤¥à¤¿à¤¤ कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ आयात गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥:" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "%s अवैध फाइल नाम" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "%s का लागि फाइल पà¥à¤°à¤£à¤¾à¤²à¥€ सूचना पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "फाइल %s का लागि माउनà¥à¤Ÿ समाविषà¥à¤Ÿ फेला परेन" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "मूल निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा पà¥à¤¨: नामकरण गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "'%s' फाइल पà¥à¤¨: नामकरण गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "फाइल नाम फेरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨, फाइलनाम पहिले नै अवसà¥à¤¥à¤¿à¤¤ छ" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 gio/glocalfile.c:2547 +#: gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "अमानà¥à¤¯ फाइलनाम" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "%s फाइल खोलà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfile.c:1488 +#, fuzzy, c-format +msgid "Error removing file %s: %s" +msgstr "लकà¥à¤·à¥à¤¯ फाइल हटाउà¤à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, fuzzy, c-format +msgid "Error trashing file %s: %s" +msgstr "%s का लागि रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•री सूचना फाइल सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ असकà¥à¤·à¤®: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•री डाइरेकà¥à¤Ÿà¥à¤°à¥€ सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ असकà¥à¤·à¤® %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•रीमा माथिलà¥à¤²à¥‹ तहको डाइरेकà¥à¤Ÿà¤°à¥€ फेला पारà¥à¤¨ अकà¥à¤·à¤® %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "पà¥à¤°à¤£à¤¾à¤²à¥€ आनà¥à¤¤à¤°à¤¿à¤• माउनà¥à¤Ÿà¤®à¤¾ रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•री समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•रीमा %s डाइरेकà¥à¤Ÿà¤°à¥€ सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ वा फेला पारà¥à¤¨ असकà¥à¤·à¤® %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "%s का लागि रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•री सूचना फाइल सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ असकà¥à¤·à¤®: %s" + +#: gio/glocalfile.c:2291 +#, fuzzy, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "'%s' फाइल सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ असफल: %s" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "फाइल %s रदà¥à¤¦à¥€à¤Ÿà¥‹à¤•रीमा सारà¥à¤¨ अकà¥à¤·à¤®: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "फाइललाई रदà¥à¤¦à¤¿à¤Ÿà¥‹à¤•रीमा सारà¥à¤¨ असकà¥à¤·à¤®: %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा %s सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "फाइल पà¥à¤°à¤£à¤¾à¤²à¥€à¤²à¥‡ सांकेतिक समà¥à¤¬à¤¨à¥à¤§à¤²à¤¾à¤ˆ समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/glocalfile.c:2415 +#, fuzzy, c-format +msgid "Error making symbolic link %s: %s" +msgstr "\"%s\" à¤à¤‰à¤Ÿà¤¾ पà¥à¤¨à¤°à¤¾à¤µà¤°à¥à¤¤à¥€ सांकेतिक शृंखला हो." + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "%s फाइल सारà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfile.c:2481 +#, fuzzy +msgid "Can’t move directory over directory" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ामा पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 gio/glocalfileoutputstream.c:1122 +#: gio/glocalfileoutputstream.c:1137 gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +#, fuzzy +msgid "Backup file creation failed" +msgstr "असà¥à¤¥à¤¾à¤¯à¥€ फाइल सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ असफल भयो ।" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "लकà¥à¤·à¥à¤¯ फाइल हटाउà¤à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfile.c:2540 +#, fuzzy +msgid "Move between mounts not supported" +msgstr "माउनà¥à¤Ÿà¤¹à¤°à¥‚को बीचमा पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ (reflink/clone) समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/glocalfile.c:2714 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s': %s" +msgid "Could not determine the disk usage of %s: %s" +msgstr "“%s†को मौलिक सà¥à¤¥à¤¾à¤¨ निरà¥à¤§à¤¾à¤°à¤£ गरà¥à¤¨ सकेन " + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "विशेषता मान शूनà¥à¤¯-रहित हà¥à¤¨à¥à¤ªà¤°à¥à¤›" + +#: gio/glocalfileinfo.c:774 +#, fuzzy +msgid "Invalid attribute type (string expected)" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार (अपेकà¥à¤·à¤¿à¤¤ बाइट सà¥à¤Ÿà¥à¤°à¤¿à¤™)" + +#: gio/glocalfileinfo.c:781 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार" + +#: gio/glocalfileinfo.c:821 +#, fuzzy, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "गà¥à¤£ '%s' सेट गरà¥à¤¦à¤¾ अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿:%s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (अवैध सङà¥à¤•ेतन)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 gio/glocalfileoutputstream.c:995 +#, fuzzy, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#: gio/glocalfileinfo.c:2134 +#, fuzzy, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#: gio/glocalfileinfo.c:2179 +#, fuzzy +msgid "Invalid attribute type (uint32 expected)" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार (अपेकà¥à¤·à¤¿à¤¤ बाइट सà¥à¤Ÿà¥à¤°à¤¿à¤™)" + +#: gio/glocalfileinfo.c:2197 +#, fuzzy +msgid "Invalid attribute type (uint64 expected)" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार (अपेकà¥à¤·à¤¿à¤¤ बाइट सà¥à¤Ÿà¥à¤°à¤¿à¤™)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "अवैध विशेषता पà¥à¤°à¤•ार (अपेकà¥à¤·à¤¿à¤¤ बाइट सà¥à¤Ÿà¥à¤°à¤¿à¤™)" + +#: gio/glocalfileinfo.c:2282 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "सà¥à¤µà¥€à¤•ृति पà¥à¤°à¤§à¤¾à¤¨ गरà¥à¤¨ अनà¥à¤®à¤¤à¤¿ छैन" + +#: gio/glocalfileinfo.c:2298 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "%s: %s देखि %sमा सेट गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/glocalfileinfo.c:2349 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "%s: %s देखि %sमा सेट गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "सूची अनà¥à¤•à¥à¤°à¤®à¤£à¤¿à¤•ा नेगेटिभ नभà¤à¤•ो हà¥à¤¨à¥à¤ªà¤°à¥à¤¦à¤› ।" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 gio/glocalfileinfo.c:2412 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "सिमà¥à¤²à¤¿à¤™à¥à¤• सेट गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: फाइल सिमà¥à¤²à¤¿à¤™à¥à¤• होइन" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "सिमà¥à¤²à¤¿à¤™à¥à¤• सेट गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: फाइल सिमà¥à¤²à¤¿à¤™à¥à¤• होइन" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "अतिरिकà¥à¤¤ नानोसेकेनà¥à¤¡ %d ले यूनिकà¥à¤¸ टाइमसà¥à¤Ÿà¥à¤¯à¤¾à¤®à¥à¤ª %lld ऋणातà¥à¤®à¤• छनà¥" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "अतिरिकà¥à¤¤ नानोसेकेनà¥à¤¡ %d ले यूनिकà¥à¤¸ टाइमसà¥à¤Ÿà¥à¤¯à¤¾à¤®à¥à¤ª %lld १ सेकेनà¥à¤¡à¤¸à¤®à¥à¤® पà¥à¤—à¥à¤›" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2570 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a number." +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "मान '%s' लाई सङà¥à¤–à¥à¤¯à¤¾à¤•ो रूपमा वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/glocalfileinfo.c:2589 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a number." +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "मान '%s' लाई सङà¥à¤–à¥à¤¯à¤¾à¤•ो रूपमा वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/glocalfileinfo.c:2602 +#, fuzzy, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "रूपानà¥à¤¤à¤°à¤£ अवधिमा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfileinfo.c:2703 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "रूपानà¥à¤¤à¤°à¤£ अवधिमा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux पà¥à¤°à¤¸à¤™à¥à¤— नल हà¥à¤¨à¥ˆ परà¥à¤›" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "यो पà¥à¤°à¤£à¤¾à¤²à¥€à¤®à¤¾ SELinux सकà¥à¤·à¤® पारिà¤à¤•ो छैन" + +#: gio/glocalfileinfo.c:2743 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "• à¤à¤¸à¤‡à¤²à¤¿à¤¨à¥à¤•à¥à¤¸ सनà¥à¤¦à¤°à¥à¤­ पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ : %s\n" + +#: gio/glocalfileinfo.c:2836 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "खोजी फोलà¥à¤¡à¤° सेटअप गरà¥à¤¦à¥ˆ: %s" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "फाइल “%s†पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿:%s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "फाइल बनà¥à¤¦ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 gio/glocalfileoutputstream.c:1186 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "फाइल लेखनमा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 gio/glocalfileoutputstream.c:334 +#: gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "फाइल लेखनमा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfileoutputstream.c:380 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "पद वरà¥à¤£à¤¨ विकलà¥à¤ªà¤®à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "बà¥à¤¯à¤¾à¤•अप फाइल सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#: gio/glocalfileoutputstream.c:425 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "फाइलहरू पà¥à¤¨ नामकरणमा à¤à¤‰à¤Ÿà¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "फाइल '%s' खोलà¥à¤¨à¥‡ कà¥à¤°à¤®à¤®à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 gio/glocalfileoutputstream.c:1220 +#: gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "\"%s\" फाइल खोलà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "लकà¥à¤·à¥à¤¯ फाइल निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा हो" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "लकà¥à¤·à¥à¤¯ फाइल नियमित फाइल होइन ।" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "फाइल लाई बाहिरी तरिकाले परिमारà¥à¤œà¤¿à¤¤ गरियो" + +#: gio/glocalfileoutputstream.c:1202 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "लकà¥à¤·à¥à¤¯ फाइल हटाउà¤à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +#, fuzzy +msgid "Invalid GSeekType supplied" +msgstr "अवैध" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "अवैध खोजी अनà¥à¤°à¥‹à¤§" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream काटà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ निरà¥à¤—त सà¥à¤Ÿà¥à¤°à¤¿à¤® रिसाइज गरà¥à¤¨ सकिने छैन" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ निरà¥à¤—त पà¥à¤°à¤µà¤¾à¤¹ रिसाइज गरà¥à¤¨ असफल" + +#: gio/gmemoryoutputstream.c:663 +msgid "Amount of memory required to process the write is larger than available address space" +msgstr "लेखन पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ गरà¥à¤¨ आवशà¥à¤¯à¤• सà¥à¤®à¥ƒà¤¤à¤¿à¤•ो मातà¥à¤°à¤¾ उपलबà¥à¤§ ठेगाना खाली सà¥à¤¥à¤¾à¤¨ भनà¥à¤¦à¤¾ ठूलो छ" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "खोलाको सà¥à¤°à¥ हà¥à¤¨à¥à¤­à¤¨à¥à¤¦à¤¾ पहिले अनà¥à¤°à¥‹à¤§ गरिà¤à¤•ो खोजी गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "खोलाको अनà¥à¤¤à¥à¤¯ पछि खोजी गरà¥à¤¨ अनà¥à¤°à¥‹à¤§ गरियो" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +#, fuzzy +msgid "mount doesn’t implement “unmountâ€" +msgstr "माउनà¥à¤Ÿà¤²à¥‡ \"अनमाउनà¥à¤Ÿ\" वा \"unmount_with_operation\" कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +#, fuzzy +msgid "mount doesn’t implement “ejectâ€" +msgstr "भोलà¥à¤¯à¥à¤®à¤²à¥‡ माउनà¥à¤Ÿ कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "माउनà¥à¤Ÿà¤²à¥‡ \"अनमाउनà¥à¤Ÿ\" वा \"unmount_with_operation\" कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +#, fuzzy +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "डà¥à¤°à¤¾à¤‡à¤­à¤²à¥‡ निकालà¥à¤¨à¥‡ वा eject_with_operation कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +#, fuzzy +msgid "mount doesn’t implement “remountâ€" +msgstr "भोलà¥à¤¯à¥à¤®à¤²à¥‡ माउनà¥à¤Ÿ कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "माउनà¥à¤Ÿà¤²à¥‡ सामागà¥à¤°à¥€ पà¥à¤°à¤•ार अनà¥à¤®à¤¾à¤¨ कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "माउनà¥à¤Ÿà¤²à¥‡ समकà¥à¤°à¤®à¤¿à¤¤ सामागà¥à¤°à¥€ पà¥à¤°à¤•ार अनà¥à¤®à¤¾à¤¨ कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gnetworkaddress.c:415 +#, fuzzy, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr " मा नभà¤à¤•ो <%s> मा समावेश " + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "सञà¥à¤œà¤¾à¤² छैन" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "होसà¥à¤Ÿ पहà¥à¤à¤šà¤¯à¥‹à¤—à¥à¤¯ छैन" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 gio/gnetworkmonitornetlink.c:130 +#, fuzzy, c-format +msgid "Could not create network monitor: %s" +msgstr "%s मा असà¥à¤¥à¤¾à¤¯à¥€ डाइरेकà¥à¤Ÿà¤°à¥€ सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ सकेन।" + +#: gio/gnetworkmonitornetlink.c:120 +#, fuzzy +msgid "Could not create network monitor: " +msgstr "सञà¥à¤œà¤¾à¤² सà¥à¤¥à¤¾à¤¨ निगरानी" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "सञà¥à¤œà¤¾à¤² सà¥à¤¥à¤¿à¤¤à¤¿ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ सकेन: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "सञà¥à¤œà¤¾à¤² पà¥à¤°à¤¬à¤¨à¥à¤§à¤• चलिरहेको छैन" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "सञà¥à¤œà¤¾à¤² पà¥à¤°à¤¬à¤¨à¥à¤§à¤• संसà¥à¤•रण अति पà¥à¤°à¤¾à¤¨à¥‹ छ" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "निरà¥à¤—त पà¥à¤°à¤µà¤¾à¤¹à¤²à¥‡ लेखन कारà¥à¤¯à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, fuzzy, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "अति ठूलो गणना मान %s मा पास गरियो" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "सà¥à¤°à¥‹à¤¤ पà¥à¤°à¤µà¤¾à¤¹ पहिलà¥à¤¯à¥ˆ बनà¥à¤¦ छ" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 gio/gthreadedresolver.c:780 +#: gio/gthreadedresolver.c:804 gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "\"%s\" हल गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ भà¤à¤•ो छैन" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "अबैध डोमेन" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 gio/gresource.c:1107 gio/gresource.c:1179 +#: gio/gresource.c:1253 gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "\"%s\" मा सà¥à¤°à¥‹à¤¤ अवसà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "\"%s\" मा संसाधन विसङà¥à¤•à¥à¤šà¤¨ गरà¥à¤¨ असफल भयो" + +#: gio/gresourcefile.c:732 +#, fuzzy, c-format +msgid "The resource at “%s†is not a directory" +msgstr "अनà¥à¤°à¥‹à¤§ गरिà¤à¤•ो संसाधन फेला परेन: %s" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "आगत पà¥à¤°à¤µà¤¾à¤¹à¤²à¥‡ खोजी कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "à¤à¤‰à¤Ÿà¤¾ elf FILE मा संसाधन समाविषà¥à¤Ÿ सेकà¥à¤¸à¤¨ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"संसाधन सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"यदि सेकà¥à¤¸à¤¨ दिइà¤à¤•ो छ भने, यो खणà¥à¤¡à¤®à¤¾ संसाधन सूचीकृत गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"यदि बाटो दिइà¤à¤•ो छ भने, मिलà¥à¤¦à¥‹ संसाधनको सूची मातà¥à¤°" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "फाइल [मारà¥à¤—]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "खणà¥à¤¡" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"विसà¥à¤¤à¥ƒà¤¤ विवरण भà¤à¤•ा संसाधन सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"यदि सेकà¥à¤¸à¤¨ दिइà¤à¤•ो छ भने, यो खणà¥à¤¡à¤®à¤¾ संसाधन सूचीकृत गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"यदि बाटो दिइà¤à¤•ो छ भने, मिलà¥à¤¦à¥‹ संसाधनको सूची मातà¥à¤°\n" +"विवरणमा खणà¥à¤¡, साइज र सङà¥à¤•à¥à¤šà¤¨ समावेश छ" + +#: gio/gresource-tool.c:525 +#, fuzzy +msgid "Extract a resource file to stdout" +msgstr "मेटाडाटा निकालà¥à¤¨à¤•ा लागि फाइल" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "फाइल मारà¥à¤—" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"उपयोग:\n" +" gresource [--section] COMMAND [ARGS...]\n" +"\n" +"आदेश:\n" +" मदà¥à¤¦à¤¤ यो सूचना देखाउनà¥à¤¹à¥‹à¤¸à¥\n" +" सेकà¥à¤¸à¤¨à¤¹à¤°à¥‚ संसाधन सेकà¥à¤¸à¤¨à¤¹à¤°à¥‚ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" सूची संसाधन\n" +" विवरण सहितको संसाधन सूचीकृत गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" संसाधन à¤à¤¿à¤•à¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"\n" +"विसà¥à¤¤à¥ƒà¤¤ मदà¥à¤¦à¤¤ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ \"gresource help COMMAND\" पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"उपयोग:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " सेकà¥à¤¸à¤¨ à¤à¤‰à¤Ÿà¤¾ (वैकलà¥à¤ªà¤¿à¤•) à¤à¤²à¥à¤« सेकà¥à¤¸à¤¨ नाम\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" +" COMMAND वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨à¤•ा लागि (वैकलà¥à¤ªà¤¿à¤•) आदेश\n" +"\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " फाइल à¤à¤‰à¤Ÿà¤¾ ईलà¥à¤« फाइल (बाइनरी वा साà¤à¤¾ लाइबà¥à¤°à¥‡à¤°à¥€)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" फाइल à¤à¤‰à¤Ÿà¤¾ ईलà¥à¤« फाइल (बाइनरी वा साà¤à¤¾ लाइबà¥à¤°à¥‡à¤°à¥€)\n" +" वा कमà¥à¤ªà¤¾à¤‡à¤² गरिà¤à¤•ो संसाधन फाइल\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[बाटो]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " मारà¥à¤— à¤à¤‰à¤Ÿà¤¾ (वैकलà¥à¤ªà¤¿à¤•) संसाधन मारà¥à¤— (आंशिक हà¥à¤¨ सकà¥à¤›)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "मारà¥à¤—" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " PATH संसाधन मारà¥à¤—\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, fuzzy, c-format +msgid "No such schema “%sâ€\n" +msgstr "अजà¥à¤žà¤¾à¤¤ सà¥à¤•िमा “%sâ€." + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "सà¥à¤•िमा \"%s\" सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ योगà¥à¤¯ छैन (बाटो निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो छैन)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "सà¥à¤•िमा \"%s\" सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ योगà¥à¤¯ छ (मारà¥à¤— निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरà¥à¤¨à¥ परà¥à¤¦à¤›)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "दिà¤à¤•ो ठेगाना खाली छ\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "कागजात à¤à¤‰à¤Ÿà¤¾ ततà¥à¤µ बाट सà¥à¤°à¥ हà¥à¤¨à¥ˆà¤ªà¤°à¥à¤› (जसà¥à¤¤à¥ˆ: )\n" + +#: gio/gsettings-tool.c:102 +#, fuzzy +msgid "Path must end with a slash (/)\n" +msgstr "यदि दिइà¤à¤•ो भà¤, पथ सà¥à¤²à¥à¤¯à¤¾à¤¸à¤¸à¤à¤— सà¥à¤°à¥ र अनà¥à¤¤à¥à¤¯ हà¥à¤¨à¥à¤ªà¤°à¥à¤¦à¤›" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "मारà¥à¤—ले दà¥à¤ˆà¤µà¤Ÿà¤¾ आसनà¥à¤¨ सà¥à¤²à¥à¤¯à¤¾à¤¸ (//) समावेश गरà¥à¤¨à¥ हà¥à¤¦à¥ˆà¤¨\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "उपलबà¥à¤§ गराइà¤à¤•ो मान वैध दायरा को बाहिर छ\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "कà¥à¤žà¥à¤œà¥€ लेखनयोगà¥à¤¯ छैन\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ गरिà¤à¤•ो (सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ गरà¥à¤¨ नसकिने) सà¥à¤•िमाहरू सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gsettings-tool.c:602 +#, fuzzy +msgid "List the installed relocatable schemas" +msgstr "सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ गरिà¤à¤•ो (सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ गरà¥à¤¨ नसकिने) सà¥à¤•िमाहरू सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "सà¥à¤•िमामा कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:614 +#, fuzzy +msgid "List the children of SCHEMA" +msgstr "" +"उपयोग:\n" +" gsettings --संसà¥à¤•रण\n" +" gsettings [--schemadir SCHEMADIR] आदेश [ARGS...]\n" +"\n" +"आदेश:\n" +" मदà¥à¤¦à¤¤ यो सूचना देखाउनà¥à¤¹à¥‹à¤¸à¥\n" +" सूची-सà¥à¤•िमाहरू सूचीकृत गरिà¤à¤•ो सà¥à¤•िमाहरू\n" +" सूची सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ योगà¥à¤¯-सà¥à¤•ीमाहरू सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ गरà¥à¤¨ सकिने सूची\n" +" सà¥à¤•िमामा सूची कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" सूची-बचà¥à¤šà¤¾à¤•ो सूची सà¥à¤•िमा\n" +" सूची-पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा कà¥à¤žà¥à¤œà¥€ र मानहरू, पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" दायरा कà¥à¤µà¥‡à¤°à¥€à¤¹à¤°à¥‚ कà¥à¤žà¥à¤œà¥€à¤•ो दायरा\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो वरà¥à¤£à¤¨ कà¥à¤µà¥‡à¤°à¥€à¤µà¤°à¥à¤£à¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान सेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" दिइà¤à¤•ो सà¥à¤•िमामा सबै मानहरू पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€ लेखनयोगà¥à¤¯ भà¤à¤®à¤¾ लेखनयोगà¥à¤¯ जाà¤à¤š गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" परिवरà¥à¤¤à¤¨à¤•ा लागि मोनिटर घडी\n" +"\n" +"विसà¥à¤¤à¥ƒà¤¤ मदà¥à¤¦à¤¤ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ \"gsettings help COMMAND\" पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।\n" +"\n" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"कà¥à¤žà¥à¤œà¥€ र मानहरू, पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +"यदि सà¥à¤•िमा दिइà¤à¤•ो छैन भने, सबै कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:627 +#, fuzzy +msgid "Get the value of KEY" +msgstr "" +"उपयोग:\n" +" gsettings --संसà¥à¤•रण\n" +" gsettings [--schemadir SCHEMADIR] आदेश [ARGS...]\n" +"\n" +"आदेश:\n" +" मदà¥à¤¦à¤¤ यो सूचना देखाउनà¥à¤¹à¥‹à¤¸à¥\n" +" सूची-सà¥à¤•िमाहरू सूचीकृत गरिà¤à¤•ो सà¥à¤•िमाहरू\n" +" सूची सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ योगà¥à¤¯-सà¥à¤•ीमाहरू सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ गरà¥à¤¨ सकिने सूची\n" +" सà¥à¤•िमामा सूची कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" सूची-बचà¥à¤šà¤¾à¤•ो सूची सà¥à¤•िमा\n" +" सूची-पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा कà¥à¤žà¥à¤œà¥€ र मानहरू, पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" दायरा कà¥à¤µà¥‡à¤°à¥€à¤¹à¤°à¥‚ कà¥à¤žà¥à¤œà¥€à¤•ो दायरा\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो वरà¥à¤£à¤¨ कà¥à¤µà¥‡à¤°à¥€à¤µà¤°à¥à¤£à¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान सेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" दिइà¤à¤•ो सà¥à¤•िमामा सबै मानहरू पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€ लेखनयोगà¥à¤¯ भà¤à¤®à¤¾ लेखनयोगà¥à¤¯ जाà¤à¤š गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" परिवरà¥à¤¤à¤¨à¤•ा लागि मोनिटर घडी\n" +"\n" +"विसà¥à¤¤à¥ƒà¤¤ मदà¥à¤¦à¤¤ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ \"gsettings help COMMAND\" पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।\n" +"\n" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 gio/gsettings-tool.c:652 +#: gio/gsettings-tool.c:664 +#, fuzzy +msgid "SCHEMA[:PATH] KEY" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "कà¥à¤žà¥à¤œà¥€à¤•ा लागि वैध मानहरूको दायरा कà¥à¤µà¥‡à¤°à¥€ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gsettings-tool.c:639 +#, fuzzy +msgid "Query the description for KEY" +msgstr "कà¥à¤žà¥à¤œà¥€à¤•ा लागि वैध मानहरूको दायरा कà¥à¤µà¥‡à¤°à¥€ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gsettings-tool.c:645 +#, fuzzy +msgid "Set the value of KEY to VALUE" +msgstr "कà¥à¤žà¥à¤œà¥€ मान" + +#: gio/gsettings-tool.c:646 +#, fuzzy +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr " KEY सà¥à¤•िमा भितà¥à¤°à¤•ो कà¥à¤žà¥à¤œà¥€\n" + +#: gio/gsettings-tool.c:651 +#, fuzzy +msgid "Reset KEY to its default value" +msgstr "यसको पूरà¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤ मानमा सरà¥à¤Ÿà¤•ट रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gsettings-tool.c:657 +#, fuzzy +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "पà¥à¤°à¤£à¤¾à¤²à¥€ पà¥à¤°à¥à¤µà¤¨à¤¿à¤°à¥à¤§à¤¾à¤°à¤¿à¤¤à¤¹à¤°à¥à¤®à¤¾ सबै सेटिङà¥à¤¹à¤°à¥‚ रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "कà¥à¤žà¥à¤œà¥€ लेखनयोगà¥à¤¯ छ की छैन जाà¤à¤š गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"परिवरà¥à¤¤à¤¨à¤•ा लागि कà¥à¤žà¥à¤œà¥€ मोनिटर गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।\n" +"यदि कà¥à¤žà¥à¤œà¥€ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤¨ भने, सà¥à¤•िमामा भà¤à¤•ा सबै कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ अनà¥à¤—मन गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।\n" +"अनà¥à¤—मन रोकà¥à¤¨à¤•ा लागि ^C पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।\n" + +#: gio/gsettings-tool.c:672 +#, fuzzy +msgid "SCHEMA[:PATH] [KEY]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"उपयोग:\n" +" gsettings --संसà¥à¤•रण\n" +" gsettings [--schemadir SCHEMADIR] आदेश [ARGS...]\n" +"\n" +"आदेश:\n" +" मदà¥à¤¦à¤¤ यो सूचना देखाउनà¥à¤¹à¥‹à¤¸à¥\n" +" सूची-सà¥à¤•िमाहरू सूचीकृत गरिà¤à¤•ो सà¥à¤•िमाहरू\n" +" सूची सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ योगà¥à¤¯-सà¥à¤•ीमाहरू सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ गरà¥à¤¨ सकिने सूची\n" +" सà¥à¤•िमामा सूची कà¥à¤žà¥à¤œà¥€à¤¹à¤°à¥‚ सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" सूची-बचà¥à¤šà¤¾à¤•ो सूची सà¥à¤•िमा\n" +" सूची-पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा कà¥à¤žà¥à¤œà¥€ र मानहरू, पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा सूचीबदà¥à¤§ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" दायरा कà¥à¤µà¥‡à¤°à¥€à¤¹à¤°à¥‚ कà¥à¤žà¥à¤œà¥€à¤•ो दायरा\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो वरà¥à¤£à¤¨ कà¥à¤µà¥‡à¤°à¥€à¤µà¤°à¥à¤£à¤¨ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान सेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€à¤•ो मान रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" दिइà¤à¤•ो सà¥à¤•िमामा सबै मानहरू पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¤¿à¤• रूपमा रिसेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" कà¥à¤žà¥à¤œà¥€ लेखनयोगà¥à¤¯ भà¤à¤®à¤¾ लेखनयोगà¥à¤¯ जाà¤à¤š गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" +" परिवरà¥à¤¤à¤¨à¤•ा लागि मोनिटर घडी\n" +"\n" +"विसà¥à¤¤à¥ƒà¤¤ मदà¥à¤¦à¤¤ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ \"gsettings help COMMAND\" पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ ।\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"उपयोग:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " अतिरिकà¥à¤¤ सà¥à¤•ीमाहरू खोजी गरà¥à¤¨à¤•ा लागि à¤à¤‰à¤Ÿà¤¾ डाइरेकà¥à¤Ÿà¤°à¥€ सà¥à¤•िमाडाइरेकà¥à¤Ÿà¤°à¥€\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" सà¥à¤•िमाको नाम सà¥à¤•िमा\n" +" बाटो बाटो, सà¥à¤¥à¤¾à¤¨à¤¾à¤¨à¥à¤¤à¤°à¤£ योगà¥à¤¯ सà¥à¤•िमाहरूका लागि\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY सà¥à¤•िमा भितà¥à¤°à¤•ो (वैकलà¥à¤ªà¤¿à¤•) कà¥à¤žà¥à¤œà¥€\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KEY सà¥à¤•िमा भितà¥à¤°à¤•ो कà¥à¤žà¥à¤œà¥€\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALUE मान सेट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s बाट सà¥à¤•िमाहरू लोड गरà¥à¤¨ सकेन: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "सà¥à¤•िमाहरू सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ गरिà¤à¤•ो छैन\n" + +#: gio/gsettings-tool.c:881 +#, fuzzy +msgid "Empty schema name given\n" +msgstr "दिà¤à¤•ो ठेगाना खाली छ" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "\"%s\" कà¥à¤žà¥à¤œà¥€ छैन\n" + +#: gio/gsocket.c:417 +#, fuzzy +msgid "Invalid socket, not initialized" +msgstr "अमानà¥à¤¯ वसà¥à¤¤à¥, पà¥à¤°à¤¾à¤°à¤®à¥à¤­ गरिà¤à¤•ो छैन" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "अवैध सकेट, सà¥à¤°à¥à¤†à¤¤ गरà¥à¤¨ असफल: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "सकेट पहिलà¥à¤¯à¥ˆ बनà¥à¤¦ गरिà¤à¤•ो छ" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "सकेट I/O समय समापà¥à¤¤à¤¿ भयो" + +#: gio/gsocket.c:582 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "सकेट सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ अकà¥à¤·à¤®: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "अजà¥à¤žà¤¾à¤¤ परिवार निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो थियो" + +#: gio/gsocket.c:682 +#, fuzzy +msgid "Unknown protocol was specified" +msgstr "अजà¥à¤žà¤¾à¤¤ परिवार निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ो थियो" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "डेटागà¥à¤°à¤¾à¤® विहिन सकेटमा डेटागà¥à¤°à¤¾à¤® सञà¥à¤šà¤¾à¤²à¤¨ पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨ ।" + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "टाइमआउट सेटसà¤à¤— सकेटमा डेटागà¥à¤°à¤¾à¤® सञà¥à¤šà¤¾à¤²à¤¨ पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨ ।" + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "सà¥à¤¥à¤¾à¤¨à¥€à¤¯ ठेगाना पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ सकेन: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "दूर ठेगाना पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ सकेन: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "सà¥à¤¨à¥à¤¨ सकिà¤à¤¨: %s" + +#: gio/gsocket.c:2213 +#, fuzzy, c-format +msgid "Error binding to address %s: %s" +msgstr "\"%s\" ठेगानामा तà¥à¤°à¥à¤Ÿà¤¿ — पोरà¥à¤Ÿ विशेषता छà¥à¤Ÿà¥‡à¤•ो छ वा विकृत छ" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 gio/gsocket.c:2624 gio/gsocket.c:2682 +#: gio/gsocket.c:2700 +#, fuzzy, c-format +msgid "Error joining multicast group: %s" +msgstr "'%s' समà¥à¤ªà¤°à¥à¤• समूह परिवरà¥à¤¤à¤¨ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 gio/gsocket.c:2625 gio/gsocket.c:2683 +#: gio/gsocket.c:2701 +#, fuzzy, c-format +msgid "Error leaving multicast group: %s" +msgstr "'%s' समà¥à¤ªà¤°à¥à¤• समूह परिवरà¥à¤¤à¤¨ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "सà¥à¤°à¥‹à¤¤ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ मलà¥à¤Ÿà¤¿à¤•ासà¥à¤Ÿà¤•ा लागि समरà¥à¤¥à¤¨ छैन" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "असमरà¥à¤¥à¤¿à¤¤ सकेट परिवार" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "सà¥à¤°à¥‹à¤¤-निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ à¤à¤‰à¤Ÿà¤¾ IPv4 ठेगाना होइन" + +#: gio/gsocket.c:2587 +#, fuzzy, c-format +msgid "Interface name too long" +msgstr "लामो सङà¥à¤—à¥à¤°à¤¹ नाम" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, fuzzy, c-format +msgid "Interface not found: %s" +msgstr "चेतावनी: इनà¥à¤Ÿà¤°à¤•à¥à¤°à¥‡à¤¸à¤Ÿà¥‡à¤¸à¤¨ डाटाको अनà¥à¤¸à¤¾à¤°, इनà¥à¤Ÿà¤°à¤«à¥‡à¤¸ \"%s\" अवसà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gsocket.c:2626 +#, fuzzy +msgid "No support for IPv4 source-specific multicast" +msgstr "सà¥à¤°à¥‹à¤¤ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ मलà¥à¤Ÿà¤¿à¤•ासà¥à¤Ÿà¤•ा लागि समरà¥à¤¥à¤¨ छैन" + +#: gio/gsocket.c:2684 +#, fuzzy +msgid "No support for IPv6 source-specific multicast" +msgstr "सà¥à¤°à¥‹à¤¤ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ मलà¥à¤Ÿà¤¿à¤•ासà¥à¤Ÿà¤•ा लागि समरà¥à¤¥à¤¨ छैन" + +#: gio/gsocket.c:2893 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿: %s मा जडान खोलà¥à¤¨ सकेन\n" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "जडान पà¥à¤°à¤—तिमा छ" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "विचाराधिन तà¥à¤°à¥à¤Ÿà¤¿ पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ असकà¥à¤·à¤®: %s " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "डाटा पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "डाटा पठाउदा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "सकेट बनà¥à¤¦ गरà¥à¤¨ अकà¥à¤·à¤®: %s" + +#: gio/gsocket.c:3724 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "%s: %s: बनà¥à¤¦ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "सकेट अवसà¥à¤¥à¤¾à¤•ा लागि पà¥à¤°à¤¤à¤¿à¤•à¥à¤·à¤¾ गरà¥à¤¦à¥ˆ: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "सनà¥à¤¦à¥‡à¤¶ पठाउन अकà¥à¤·à¤®: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +#, fuzzy +msgid "Message vectors too large" +msgstr "अति ठूलो गणना मान %s मा पास गरियो" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 gio/gsocket.c:5268 gio/gsocket.c:5308 +#: gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "सनà¥à¤¦à¥‡à¤¶ पठाउदा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "सञà¥à¤à¥à¤¯à¤¾à¤²à¤®à¤¾ GSocketControlMessage समरà¥à¤¥à¤¿à¤¤ छैन" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "डाटा पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, fuzzy, c-format +msgid "Unable to read socket credentials: %s" +msgstr "सकेट सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ अकà¥à¤·à¤®: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "यो OS का लागि g_socket_get_credentials कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरिà¤à¤•ो छैन" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ सरà¥à¤­à¤°à¤®à¤¾ जडान गरà¥à¤¨ सकेन: %s " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s मा जडान गरà¥à¤¨ सकेन: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "जडान गरà¥à¤¨ सकेन: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "TCP बाहेकका जडानमा पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ समरà¥à¤¥à¤¿à¤¤ छैन ।" + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, fuzzy, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "(पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ल %s)" + +#: gio/gsocketlistener.c:230 +#, fuzzy +msgid "Listener is already closed" +msgstr "सà¥à¤Ÿà¥à¤°à¥€à¤® पहिलà¥à¤¯à¥ˆ बनà¥à¤¦ छ" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "थपिà¤à¤•ो सकेट बनà¥à¤¦ छ" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 ले IPv6 ठेगाना \"%s\" समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•लका लागि पà¥à¤°à¤¯à¥‹à¤—करà¥à¤¤à¤¾ नाम धेरै लामो छ" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•लका लागि होसà¥à¤Ÿà¤¨à¤¾à¤® \"%s\" धेरै लामो छ" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "सरà¥à¤­à¤° SOCKSv4 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ सरà¥à¤­à¤° होइन ।" + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "सरà¥à¤­à¤°à¤¬à¤¾à¤Ÿ SOCKSv4 जडान असà¥à¤µà¥€à¤•ार गरियो" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "सरà¥à¤­à¤° SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ सरà¥à¤­à¤° होइन ।" + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€à¤²à¤¾à¤ˆ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण आवशà¥à¤¯à¤• परà¥à¤¦à¤› ।" + +#: gio/gsocks5proxy.c:191 +msgid "The SOCKSv5 proxy requires an authentication method that is not supported by GLib." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€à¤²à¤¾à¤ˆ à¤à¤‰à¤Ÿà¤¾ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण विधि आवशà¥à¤¯à¤• परà¥à¤¦à¤› जà¥à¤¨ GLib दà¥à¤µà¤¾à¤°à¤¾ समरà¥à¤¥à¤¿à¤¤ छैन ।" + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•लका लागि पà¥à¤°à¤¯à¥‹à¤—करà¥à¤¤à¤¾ नाम वा पासवरà¥à¤¡ धेरै लामो छ ।" + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "गलत पà¥à¤°à¤¯à¥‹à¤—करà¥à¤¤à¤¾ नाम वा पासवरà¥à¤¡à¤•ा कारणSOCKSv5 पà¥à¤°à¤®à¤¾à¤£à¥€à¤•रण असफल भयो ।" + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "होसà¥à¤Ÿà¤¨à¤¾à¤® \"%s\" SOCKSv5 पà¥à¤°à¥‹à¤Ÿà¥‹à¤•लका लागि धेरै लामो छ" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ सरà¥à¤­à¤°à¤²à¥‡ अजà¥à¤žà¤¾à¤¤ ठेगाना पà¥à¤°à¤•ार पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¦à¤› ।" + +#: gio/gsocks5proxy.c:369 +#, fuzzy +msgid "Internal SOCKSv5 proxy server error." +msgstr "सरà¥à¤­à¤° SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ सरà¥à¤­à¤° होइन ।" + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "रूलसेटदà¥à¤µà¤¾à¤°à¤¾ SOCKSv5 जडानलाई अनà¥à¤®à¤¤à¤¿ छैन ।" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 सरà¥à¤­à¤° मारà¥à¤«à¤¤ पहà¥à¤à¤š योगà¥à¤¯ नभà¤à¤•ो होसà¥à¤Ÿ ।" + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€à¤¸à¤à¤— सञà¥à¤œà¤¾à¤² पहà¥à¤à¤šà¤¯à¥‹à¤—à¥à¤¯ छैन ।" + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ सà¤à¤— जडान असà¥à¤µà¥€à¤•ृत भयो ।" + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€à¤²à¥‡ \"जडान\" आदेश समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨ ।" + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€à¤²à¥‡ पà¥à¤°à¤¦à¤¾à¤¨ गरिà¤à¤•ो ठेगाना पà¥à¤°à¤•ार समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨ ।" + +#: gio/gsocks5proxy.c:412 +#, fuzzy +msgid "Unknown SOCKSv5 proxy error." +msgstr "सरà¥à¤­à¤° SOCKSv5 पà¥à¤°à¥‹à¤•à¥à¤¸à¥€ सरà¥à¤­à¤° होइन ।" + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s)सà¤à¤— कà¥à¤°à¤¾à¤•ानीका लागि पाइप सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ असफल" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "यो पà¥à¤²à¥‡à¤Ÿà¤«à¤°à¥à¤®à¤®à¤¾ पाइपहरू समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon सङà¥à¤•ेतनको संसà¥à¤•रण %d हà¥à¤¯à¤¾à¤¨à¥à¤¡à¤² गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gthreadedresolver.c:152 +#, fuzzy +msgid "No valid addresses were found" +msgstr "कà¥à¤¨à¥ˆ गà¥à¤£à¤¹à¤°à¥‚ फेला परेन ।" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "\"%s\" पà¥à¤¨: समाधान गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "%s रेकरà¥à¤¡ पद वरà¥à¤£à¤¨ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: विकृत DNS पà¥à¤¯à¤¾à¤•ेट" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, fuzzy, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "वसà¥à¤¤à¥ पà¥à¤°à¤•ार '%s' यो पà¥à¤°à¤¸à¤™à¥à¤—मा अनà¥à¤°à¥‹à¤§ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, fuzzy, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "URI '%s' को लागि मिडिया समाधान गरà¥à¤¨ सकेन" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "\"%s\" हल गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "विकृत DNS पà¥à¤¯à¤¾à¤•ेट" + +#: gio/gthreadedresolver.c:886 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "सà¥à¤µà¤¤: खोज पà¥à¤°à¤¤à¤¿à¤•à¥à¤°à¤¿à¤¯à¤¾ à¤à¤•à¥à¤¸à¤à¤®à¤à¤² पारà¥à¤¸ गरà¥à¤¨ असफल भयो" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "PEM-सङà¥à¤•ेतन गरिà¤à¤•ो निजी कà¥à¤žà¥à¤œà¥€ फेला परेन" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-सङà¥à¤•ेतन गरिà¤à¤•ो निजी कà¥à¤žà¥à¤œà¥€à¤•ो गà¥à¤ªà¥à¤¤à¤²à¥‡à¤–न उलà¥à¤Ÿà¤¾à¤‰à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: gio/gtlscertificate.c:499 +#, fuzzy +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-सङà¥à¤•ेतन गरिà¤à¤•ो पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकेन" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "PEM-सङà¥à¤•ेतन गरिà¤à¤•ो पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° फेला परेन" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-सङà¥à¤•ेतन गरिà¤à¤•ो पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकेन" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "हालको TLS बà¥à¤¯à¤¾à¤•इनà¥à¤¡à¤²à¥‡ PKCS #12 समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "यो GTlsBackend ले PKCS #11 पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨ ।" + +#: gio/gtlspassword.c:111 +msgid "This is the last chance to enter the password correctly before your access is locked out." +msgstr "तपाईà¤à¤•ो पहà¥à¤à¤š तालà¥à¤šà¤¾ लगाउनॠभनà¥à¤¦à¤¾ पहिले सही तरिकाले पासवरà¥à¤¡ पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ गरà¥à¤¨à¥‡ यो अनà¥à¤¤à¤¿à¤® मौका हो ।" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "Several passwords entered have been incorrect, and your access will be locked out after further failures." +msgstr "पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ गरिà¤à¤•ा धेरै पासवरà¥à¤¡à¤¹à¤°à¥‚ गलत भà¤à¤•ा छनà¥, र तपाईà¤à¤•ो पहà¥à¤à¤š थप असफलता पछि तालà¥à¤šà¤¾ लगाइà¤à¤•ो हà¥à¤¨à¥‡à¤› ।" + +#: gio/gtlspassword.c:117 +#, fuzzy +msgid "The password entered is incorrect." +msgstr "पासवरà¥à¤¡ गलत थियो" + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "FD पठाउन समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "१ नियनà¥à¤¤à¥à¤°à¤£ सनà¥à¤¦à¥‡à¤¶ अपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆ, %d पà¥à¤°à¤¾à¤ªà¥à¤¤ भयो" +msgstr[1] "१ नियनà¥à¤¤à¥à¤°à¤£ सनà¥à¤¦à¥‡à¤¶ अपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆ, %d पà¥à¤°à¤¾à¤ªà¥à¤¤ भयो" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "अनपेकà¥à¤·à¤¿à¤¤ पà¥à¤°à¤•ारको सहायक डेटा" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "à¤à¤‰à¤Ÿà¤¾ fd अपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆ, तर %d पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¯à¥‹\n" +msgstr[1] "à¤à¤‰à¤Ÿà¤¾ fd अपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆ, तर %d पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¯à¥‹\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "अवैध fd पà¥à¤°à¤¾à¤ªà¥à¤¤ भयो" + +#: gio/gunixconnection.c:238 +#, fuzzy +msgid "Receiving FD is not supported" +msgstr "FD पठाउन समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gunixconnection.c:380 +#, fuzzy +msgid "Error sending credentials: " +msgstr "सनà¥à¤¦à¥‡à¤¶ पठाउदा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED सकà¥à¤·à¤® पारà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gunixconnection.c:582 +msgid "Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨à¤•ा लागि à¤à¤•ल बाइट पढà¥à¤¨à¥‡ अपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆà¤› तर शूनà¥à¤¯ बाइटहरू पढà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/gunixconnection.c:622 +#, fuzzy, c-format +msgid "Not expecting control message, but got %d" +msgstr "१ नियनà¥à¤¤à¥à¤°à¤£ सनà¥à¤¦à¥‡à¤¶ अपेकà¥à¤·à¤¾ गरà¥à¤¦à¥ˆ, %d पà¥à¤°à¤¾à¤ªà¥à¤¤ भयो" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED अकà¥à¤·à¤® गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, fuzzy, c-format +msgid "Error reading from file descriptor: %s" +msgstr "फाइल “%s†पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿:%s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, fuzzy, c-format +msgid "Error closing file descriptor: %s" +msgstr "फाइल बनà¥à¤¦ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "मà¥à¤² फाइल पà¥à¤°à¤£à¤¾à¤²à¥€ " + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, fuzzy, c-format +msgid "Error writing to file descriptor: %s" +msgstr "छवि फाइलमा लेखà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "संकà¥à¤·à¥‡à¤ª यà¥à¤¨à¤¿à¤•à¥à¤¸ डोमेन सकेट ठेगाना यो पà¥à¤°à¤£à¤¾à¤²à¥€à¤®à¤¾ समरà¥à¤¥à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "भोलà¥à¤¯à¥à¤®à¤²à¥‡ निकालà¥à¤¨à¥‡ कारà¥à¤¯ कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +#, fuzzy +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "डà¥à¤°à¤¾à¤‡à¤­à¤²à¥‡ निकालà¥à¤¨à¥‡ वा eject_with_operation कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¥ˆà¤¨" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "हेनà¥à¤¦à¤²à¤¬à¤¾à¤Ÿ पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "%s: %s: बनà¥à¤¦ गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s\n" + +#: gio/gwin32outputstream.c:172 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "फाइल लेखनमा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "पà¥à¤°à¤¶à¤¸à¥à¤¤ सà¥à¤®à¥ƒà¤¤à¤¿ छैन" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "आनà¥à¤¤à¤°à¤¿à¤• तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "बढी आगत आवशà¥à¤¯à¤•" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "समà¥à¤ªà¤°à¥à¤• डेटा अवैध छ" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Address to listen on" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "GTestDbus सà¤à¤— कमà¥à¤ªà¤¾à¤Ÿà¤•ा लागि, उपेकà¥à¤·à¤¾ गरियो" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "ठेगाना मà¥à¤¦à¥à¤°à¤£ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "dbus सेवा चलाउनà¥à¤¹à¥‹à¤¸à¥" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "गलत तरà¥à¤•\n" + +#: glib/gbookmarkfile.c:777 +#, fuzzy, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "\"%s\" विशेषताको \"%s\" ततà¥à¤µ फेला परेन" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "\"%s\" विशेषताको \"%s\" ततà¥à¤µ फेला परेन" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, fuzzy, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ सà¥à¤°à¥ टà¥à¤¯à¤¾à¤— '%s' लाइन %d मा char %d" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, fuzzy, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "%s भितà¥à¤°à¤ªà¤Ÿà¤¿ (%s) अनà¥à¤®à¤¤à¤¿ दिà¤à¤•ो छैन" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "पà¥à¤¸à¥à¤¤à¤•चिनो फाइलमा अवैध मिति/समय '%s'" + +#: glib/gbookmarkfile.c:1836 +#, fuzzy +msgid "No valid bookmark file found in data dirs" +msgstr "खोजी डाइरेकà¥à¤Ÿà¤°à¥€à¤¹à¤°à¥‚मा वैध कà¥à¤žà¥à¤œà¥€ फाइल फेला पारà¥à¤¨ सकेन ।" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "URI \"%s\" का लागि पà¥à¤¸à¥à¤¤à¤•चिनो पहिले नै अवसà¥à¤¥à¤¿à¤¤ छ" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, fuzzy, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "'%s' URI का लागि वसà¥à¤¤à¥ फेला परेन" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" + +#: glib/gbookmarkfile.c:3044 +#, fuzzy, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI \"%s\" का लागि पà¥à¤¸à¥à¤¤à¤•चिनो पहिले नै अवसà¥à¤¥à¤¿à¤¤ छ" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, fuzzy, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "%s: अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— नाम हराइरहेको छ" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "\"%s\" यूआरआईसà¤à¤— exec लाइन \"%s\" विसà¥à¤¤à¤¾à¤° गरà¥à¤¨ असफल भयो" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "रूपानà¥à¤¤à¤°à¤£ आगतमा पà¥à¤°à¤¤à¤¿à¤¨à¤¿à¤§à¤¿à¤¤à¥à¤µ गरà¥à¤¨ नसकिने वरà¥à¤£" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "आगतको अनà¥à¤¤à¥à¤¯à¤®à¤¾ आंशिक कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤°" + +#: glib/gconvert.c:764 +#, fuzzy, c-format +#| msgid "Cannot convert fallback '%s' to codeset '%s'" +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "फलबà¥à¤¯à¤¾à¤• '%s' बाट कोड सेट'%s' मा रूपानà¥à¤¤à¤°à¤£ गरà¥à¤¨ सकà¥à¤¦à¥ˆà¤¨" + +#: glib/gconvert.c:936 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "रूपानà¥à¤¤à¤°à¤£ आगतमा अवैध बाइट अनà¥à¤•à¥à¤°à¤®" + +#: glib/gconvert.c:957 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "रूपानà¥à¤¤à¤°à¤£ आगतमा अवैध बाइट अनà¥à¤•à¥à¤°à¤®" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI \"%s\" \"file\" योजना पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥‡ à¤à¤‰à¤Ÿà¤¾ निशà¥à¤šà¤¿à¤¤ URI होइन" + +#: glib/gconvert.c:1698 +#, fuzzy, c-format +#| msgid "The local file URI '%s' may not include a '#'" +msgid "The local file URI “%s†may not include a “#â€" +msgstr "सà¥à¤¥à¤¾à¤¨à¥€à¤¯ फाइल URI '%s' मा à¤à¤‰à¤Ÿà¤¾ '#' समावेश नहà¥à¤¨à¤¸à¤•à¥à¤›" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI “%s†अवैध" + +#: glib/gconvert.c:1727 +#, fuzzy, c-format +#| msgid "The hostname of the URI '%s' is invalid" +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI “%s†अवैध" + +#: glib/gconvert.c:1743 +#, fuzzy, c-format +#| msgid "The URI '%s' contains invalidly escaped characters" +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI '%s' मा अवैध रूपमा निसà¥à¤•िà¤à¤•ा कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤°à¤¹à¤°à¥‚ देखिनà¥à¤›à¤¨à¥" + +#: glib/gconvert.c:1815 +#, fuzzy, c-format +#| msgid "The pathname '%s' is not an absolute path" +msgid "The pathname “%s†is not an absolute path" +msgstr "%s भणà¥à¤¡à¤¾à¤° मूल à¤à¤‰à¤Ÿà¤¾ सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ मारà¥à¤— होइन" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%A %d %b %Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%I:%M:%S %Z" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "जनवरी" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "फेबà¥à¤°à¥à¤…री" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "मारà¥à¤š" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "अपà¥à¤°à¥‡à¤²" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "मे" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "जून" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "अगसà¥à¤Ÿ" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "सेपà¥à¤Ÿà¥‡à¤®à¥à¤¬à¤°" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "अकà¥à¤Ÿà¥‹à¤¬à¤°" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "नोभेमà¥à¤¬à¤°" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "डिसेमà¥à¤¬à¤°" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "जनवरी" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "फेबà¥à¤°à¥à¤…री" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "मारà¥à¤š" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "अपà¥à¤°à¥‡à¤²" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "मे" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "जून" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "अगसà¥à¤Ÿ" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "सेपà¥à¤Ÿà¥‡à¤®à¥à¤¬à¤°" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "अकà¥à¤Ÿà¥‹à¤¬à¤°" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "नोभेमà¥à¤¬à¤°" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "डिसेमà¥à¤¬à¤°" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "सोमबार" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "मङà¥à¤—लबार" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "बà¥à¤§à¤¬à¤¾à¤°" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "बिहिबार" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "शà¥à¤•à¥à¤°à¤¬à¤¾à¤°" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "शनिबार" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "आइतबार" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "सोम" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "मङà¥à¤—ल" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "बà¥à¤§" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "बिही" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "शà¥à¤•à¥à¤°" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "शनि" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "आइत" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "जनवरी" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "फेबà¥à¤°à¥à¤…री" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "मारà¥à¤š" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "अपà¥à¤°à¥‡à¤²" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "मे" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "जून" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "अगसà¥à¤Ÿ" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "सेपà¥à¤Ÿà¥‡à¤®à¥à¤¬à¤°" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "अकà¥à¤Ÿà¥‹à¤¬à¤°" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "नोभेमà¥à¤¬à¤°" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "डिसेमà¥à¤¬à¤°" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "जनवरी" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "फेबà¥à¤°à¥à¤…री" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "मारà¥à¤š" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "अपà¥à¤°à¥‡à¤²" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "मे" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "जून" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "जà¥à¤²à¤¾à¤ˆ" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "अगसà¥à¤Ÿ" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "सेपà¥à¤Ÿà¥‡à¤®à¥à¤¬à¤°" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "अकà¥à¤Ÿà¥‹à¤¬à¤°" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "नोभेमà¥à¤¬à¤°" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "डिसेमà¥à¤¬à¤°" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "पूरà¥à¤µà¤¾à¤¹à¥à¤¨" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "अपराहà¥à¤¨" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा खोलà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ “%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, fuzzy, c-format +#| msgid "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "फाइल \"%2$s\" पढà¥à¤¨ %1$lu बाईटà¥à¤¸ बाà¤à¤¡à¤«à¤¾à¤à¤¡ गरà¥à¤¨ सकिà¤à¤¨" +msgstr[1] "फाइल \"%2$s\" पढà¥à¤¨ %1$lu बाईटà¥à¤¸ बाà¤à¤¡à¤«à¤¾à¤à¤¡ गरà¥à¤¨ सकिà¤à¤¨" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ “%sâ€: %s" + +#: glib/gfileutils.c:786 +#, fuzzy, c-format +msgid "File “%s†is too large" +msgstr "अति ठूलो गणना मान %s मा पास गरियो" + +#: glib/gfileutils.c:850 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to read from file “%sâ€: %s" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) बाट डेटा पढà¥à¤¨ असफल" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': %s" +msgid "Failed to open file “%sâ€: %s" +msgstr "फाइल %s खोलà¥à¤¨ असफल: %s\n" + +#: glib/gfileutils.c:913 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "फाइल '%s' का लागि जानकारी पà¥à¤°à¤¾à¤ªà¥à¤¤ गरà¥à¤¨ सकेन: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "कारà¥à¤¯ फाइल %s: %s fdopen() गरà¥à¤¨ असफल" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "फाइल “%s†लाई “%s†मा पà¥à¤¨: नामकरण गरà¥à¤¨ असफल:g_rename() असफल: %s" + +#: glib/gfileutils.c:1154 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': fwrite() failed: %s" +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "कà¥à¤¯à¤¾à¤¸ फाइल लेखà¥à¤¨ असफल भयो: %s\n" + +#: glib/gfileutils.c:1175 +#, fuzzy, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "कà¥à¤¯à¤¾à¤¸ फाइल लेखà¥à¤¨ असफल भयो: %s\n" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, fuzzy, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to create file “%sâ€: %s" +msgstr "असà¥à¤¥à¤¾à¤¯à¥€ फाईल सिरà¥à¤œà¤¨à¤¾ गरà¥à¤¨ असफल`%s': %s\n" + +#: glib/gfileutils.c:1381 +#, fuzzy, c-format +#| msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "अवसà¥à¤¥à¤¿à¤¤ फाइल '%s' हटाउन सकिà¤à¤¨:g_unlink() असफल: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ %s को #%s मा 'टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ:' लाइन समाविषà¥à¤Ÿ छैन" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "\"%s\" टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ XXXXXX समावेश छैन" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "सांकेतिक समà¥à¤¬à¤¨à¥à¤§ \"%s\" पढà¥à¤¨ असफल भयो: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "\"%s\" बाट \"%s\" मा रूपानà¥à¤¤à¤°à¤£à¤•रà¥à¤¤à¤¾ खोलà¥à¤¨ सकेन: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string मा परीकà¥à¤·à¤£ पढाई गरà¥à¤¨ सकà¥à¤¦à¥ˆà¤¨" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "पढà¥à¤¨à¥‡ बफरमा छाडेको अरूपानà¥à¤¤à¤°à¤¿à¤¤ डेटा" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "आंशिक-कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤°à¤®à¤¾ माधà¥à¤¯à¤® टà¥à¤™à¥à¤—िनà¥à¤›" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end मा परीकà¥à¤·à¤£ पढाई गरà¥à¤¨ सकà¥à¤¦à¥ˆà¤¨" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "खोजी डाइरेकà¥à¤Ÿà¤°à¥€à¤¹à¤°à¥‚मा वैध कà¥à¤žà¥à¤œà¥€ फाइल फेला पारà¥à¤¨ सकेन ।" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "नियमित फाइल होइन" + +#: glib/gkeyfile.c:1289 +#, fuzzy, c-format +#| msgid "Key file contains line '%s' which is not a key-value pair, group, or comment" +msgid "Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा पङà¥à¤—ति '%s' समावेश छ जà¥à¤¨ कà¥à¤žà¥à¤œà¥€-मान जोडि, समूह, वा टिपà¥à¤ªà¤£à¥€ होइन।" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "अवैध समà¥à¤¹ नाम : %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "कà¥à¤žà¥à¤œà¥€ फाइल à¤à¤‰à¤Ÿà¤¾ समूहबाट सà¥à¤°à¥ हà¥à¤à¤¦à¥ˆà¤¨" + +#: glib/gkeyfile.c:1394 +#, fuzzy, c-format +#| msgid "Invalid key name: %s" +msgid "Invalid key name: %.*s" +msgstr "अवैध समà¥à¤¹ नाम : %s" + +#: glib/gkeyfile.c:1422 +#, fuzzy, c-format +#| msgid "Key file contains unsupported encoding '%s'" +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा समरà¥à¤¥à¤¨ पà¥à¤°à¤¾à¤ªà¥à¤¤ नभà¤à¤•ो सङà¥à¤•ेतन '%s' समावेश छ।" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 +#: glib/gkeyfile.c:3623 glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, fuzzy, c-format +#| msgid "Key file does not have group '%s'" +msgid "Key file does not have group “%sâ€" +msgstr "कà¥à¤žà¥à¤œà¥€ फाइल à¤à¤‰à¤Ÿà¤¾ समूहबाट सà¥à¤°à¥ हà¥à¤à¤¦à¥ˆà¤¨" + +#: glib/gkeyfile.c:1805 +#, fuzzy, c-format +#| msgid "Key file does not have key '%s' in group '%s'" +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा समूह '%s' मा कà¥à¤žà¥à¤œà¥€ '%s' हà¥à¤à¤¦à¥ˆà¤¨" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, fuzzy, c-format +#| msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा मान '%s'सà¤à¤—ै कà¥à¤žà¥à¤œà¥€ '%s' समावेश छ जà¥à¤¨ UTF-8 होइन" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, fuzzy, c-format +msgid "Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा कà¥à¤žà¥à¤œà¥€ '%s' समावेश छ जसको मानलाई वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨à¥¤" + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, fuzzy, c-format +#| msgid "Key file contains key '%s' in group '%s' which has value that cannot be interpreted." +msgid "Key file contains key “%s†in group “%s†which has a value that cannot be interpreted." +msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा समूह '%s' मा कà¥à¤žà¥à¤œà¥€ '%s' समावेश छ जसको मानलाई वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨à¥¤" + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा पङà¥à¤—तिको अनà¥à¤¤à¥à¤¯à¤®à¤¾ निकास कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° समावेश छ।" + +#: glib/gkeyfile.c:4346 +#, fuzzy, c-format +#| msgid "Key file contains invalid escape sequence '%s'" +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा अवैध निकास अनà¥à¤•à¥à¤°à¤® '%s' समावेस छ।" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "मान '%s' लाई सङà¥à¤–à¥à¤¯à¤¾à¤•ो रूपमा वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨" + +#: glib/gkeyfile.c:4505 +#, fuzzy, c-format +#| msgid "Integer value '%s' out of range" +msgid "Integer value “%s†out of range" +msgstr "दायरा बाहिरको मान ।\n" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "मान \"%s\" लाई उतà¥à¤ªà¥à¤²à¤µà¤¾à¤¨ सङà¥à¤–à¥à¤¯à¤¾à¤•ो रूपमा वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨à¥¤" + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "मान \"%s\" लाई बà¥à¤²à¤¿à¤¯à¤¨à¤•ो रूपमा वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨à¥¤" + +#: glib/gmappedfile.c:129 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "'%s' फाइलको विशेषता पाउन असफल: fstat() असफल भयो: %s" + +#: glib/gmappedfile.c:195 +#, fuzzy, c-format +#| msgid "Failed to map file '%s': mmap() failed: %s" +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "कारà¥à¤¯ फाइल %s: %s fdopen() गरà¥à¤¨ असफल" + +#: glib/gmappedfile.c:262 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': open() failed: %s" +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "कारà¥à¤¯ फाइल %s: %s fdopen() गरà¥à¤¨ असफल" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "पङà¥à¤•à¥à¤¤à¤¿ %d वरà¥à¤£ %d मा तà¥à¤°à¥à¤Ÿà¤¿: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "अवैध UTF-8 सङà¥à¤•ेतन गरिà¤à¤•ो पाठ" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "%s अवैध नाम" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "%s अवैध नाम: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "लाइन %d मा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character reference (ê for example) — perhaps " +"the digit is too large" +msgstr "'%-*s' पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकिà¤à¤¨, जà¥à¤¨ à¤à¤‰à¤Ÿà¤¾ कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° सनà¥à¤¦à¤°à¥à¤­ (उदाहरणका लागि; ê) हà¥à¤¨à¥ परà¥à¤¥à¥à¤¯à¥‹ - संभवत अङà¥à¤• जà¥à¤¯à¤¾à¤¦à¥ˆ ठूलो छ" + +#: glib/gmarkup.c:702 +#, fuzzy +#| msgid "" +#| "Character reference did not end with a semicolon; most likely you used an ampersand character without intending " +#| "to start an entity - escape ampersand as &" +msgid "" +"Character reference did not end with a semicolon; most likely you used an ampersand character without intending to " +"start an entity — escape ampersand as &" +msgstr "" +"कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° सनà¥à¤¦à¤°à¥à¤­ अरà¥à¤§à¤µà¤¿à¤°à¤¾à¤®à¤®à¤¾ सकिà¤à¤¨;तपाईà¤à¤²à¥‡ धेरैजसो à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤£à¥à¤¡ कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤°à¤¬à¤¾à¤Ÿ à¤à¤‰à¤Ÿà¤¾ असà¥à¤¤à¤¿à¤¤à¥à¤µ सà¥à¤°à¥ गरà¥à¤¨à¤•ा लागि पà¥à¤°à¤¯à¤¾à¤¸ नगरिकन सà¥à¤°à¥ गरà¥à¤¨à¥à¤­à¤¯à¥‹ - " +"& को रूपमा à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚नà¥à¤¡ निकास गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: glib/gmarkup.c:728 +#, fuzzy, c-format +#| msgid "Character reference '%-.*s' does not encode a permitted character" +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° सनà¥à¤¦à¤°à¥à¤­ '%-.*s' ले सà¥à¤µà¥€à¤•ृत कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤°à¤•ो सङà¥à¤•ेतन गरà¥à¤¦à¥ˆà¤¨ " + +#: glib/gmarkup.c:766 +#, fuzzy +#| msgid "Empty entity '&;' seen; valid entities are: & " < > '" +msgid "Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "खाली असà¥à¤¤à¤¿à¤¤à¥à¤µ '&;' देखियो; वैध असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¹à¤°à¥‚ निमà¥à¤¨ हà¥à¤¨ : & " < > '" + +#: glib/gmarkup.c:774 +#, fuzzy, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "%s अहिले %s को रà¥à¤ªà¤®à¤¾ चिनिनà¥à¤›" + +#: glib/gmarkup.c:779 +#, fuzzy +#| msgid "" +#| "Entity did not end with a semicolon; most likely you used an ampersand character without intending to start an " +#| "entity - escape ampersand as &" +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand character without intending to start an " +"entity — escape ampersand as &" +msgstr "" +"असà¥à¤¤à¤¿à¤¤à¥à¤µ अरà¥à¤§à¤µà¤¿à¤°à¤¾à¤®à¤®à¤¾ सकिà¤à¤¨; तपाईà¤à¤²à¥‡ धेरैजसो à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤£à¥à¤¡ कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤°à¤¬à¤¾à¤Ÿ à¤à¤‰à¤Ÿà¤¾ असà¥à¤¤à¤¿à¤¤à¥à¤µ सà¥à¤°à¥ गरà¥à¤¨à¤•ो लागि पà¥à¤°à¤¯à¤¾à¤¸ नगरिकन सà¥à¤°à¥ गरà¥à¤¨à¥à¤­à¤¯à¥‹ - & को " +"रूपमा à¤à¤®à¥à¤ªà¤°à¤¸à¥‡à¤‚नà¥à¤¡ निकास गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "कागजात à¤à¤‰à¤Ÿà¤¾ ततà¥à¤µ बाट सà¥à¤°à¥ हà¥à¤¨à¥ˆà¤ªà¤°à¥à¤› (जसà¥à¤¤à¥ˆ: )" + +#: glib/gmarkup.c:1233 +#, fuzzy, c-format +#| msgid "'%s' is not a valid character following a '<' character; it may not begin an element name" +msgid "“%s†is not a valid character following a “<†character; it may not begin an element name" +msgstr "\"%s\" वरà¥à¤£à¤¹à¤°à¥‚ \"†character to end the empty-element tag “%sâ€" +msgstr "बिजोड कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° '%s', à¤à¤‰à¤Ÿà¤¾ अपेकà¥à¤·à¤¾ गरिà¤à¤•ो कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° '>', '%s' को सà¥à¤°à¥ टà¥à¤¯à¤¾à¤— अनà¥à¤¤à¥à¤¯ गरà¥à¤¨à¤²à¤¾à¤‡" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "ततà¥à¤µ \"%s\" मा निकै धेरै विशेषताहरू" + +#: glib/gmarkup.c:1366 +#, fuzzy, c-format +#| msgid "Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgid "Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "विजोड कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° '%s' ले,'%s' ततà¥à¤µà¤•ो गà¥à¤£ नाम '%s' पछि अपेकà¥à¤·à¤¾ गरिà¤à¤•ो à¤à¤‰à¤Ÿà¤¾ '=' " + +#: glib/gmarkup.c:1408 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' or '/' character to end the start tag of element '%s', or optionally an " +#| "attribute; perhaps you used an invalid character in an attribute name" +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of element “%sâ€, or optionally an " +"attribute; perhaps you used an invalid character in an attribute name" +msgstr "" +"बिजोड कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° '%s', ततà¥à¤µ '%s' को सà¥à¤°à¥ टà¥à¤¯à¤¾à¤— अनà¥à¤¤à¥à¤¯ गरà¥à¤¨à¤²à¤¾à¤ˆ अपेकà¥à¤·à¤¾ गरिà¤à¤•ो à¤à¤‰à¤Ÿà¤¾ '>' वा '/' कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤°, वा वैकलà¥à¤ªà¤¿à¤• रूपमा à¤à¤‰à¤Ÿà¤¾ " +"विशेषता ,सायद तपाईà¤à¤²à¥‡ à¤à¤‰à¤Ÿà¤¾ विशेषता नाममा अवैध कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤­à¤¯à¥‹" + +#: glib/gmarkup.c:1453 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected an open quote mark after the equals sign when giving value for attribute '%s' of " +#| "element '%s'" +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when giving value for attribute “%s†of " +"element “%sâ€" +msgstr "" +"बिजोड कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° '%s',ततà¥à¤µ '%s' को '%s' विशेषताका लागि मान दिइà¤à¤•ो बेला बराबर चिनà¥à¤¹ पछि खà¥à¤²à¤¾ उदà¥à¤§à¤°à¤£ चिनà¥à¤¹à¤•ो अपेकà¥à¤·à¤¾ गरेको हà¥à¤¨à¥à¤›à¥¤" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "“%s†is not a valid character following the characters “'" +msgid "“%s†is not a valid character following the close element name “%sâ€; the allowed character is “>â€" +msgstr "\"%s\" वरà¥à¤£à¤¹à¤°à¥‚ \"" +msgstr "कागजपतà¥à¤° अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपले समापà¥à¤¤ भयो, टà¥à¤¯à¤¾à¤— <%s/> को अनà¥à¤¤à¤®à¤¾ बनà¥à¤¦ कोण कोषà¥à¤ à¤•ो अपेकà¥à¤·à¤¾ गरà¥à¤¦à¤›à¥¤" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "ततà¥à¤µ नाम भितà¥à¤° कागजात अपेकà¥à¤·à¤¿à¤¤ रूपले समापà¥à¤¤ भयो।" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "विशेषता नाम भितà¥à¤° कागजात अपेकà¥à¤·à¤¿à¤¤ रूपले समापà¥à¤¤ भयो।" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ततà¥à¤µ-खà¥à¤²à¥à¤²à¤¾ टà¥à¤¯à¤¾à¤— भितà¥à¤° कागजात अपेकà¥à¤·à¤¿à¤¤ रूपले समापà¥à¤¤ भयो।" + +#: glib/gmarkup.c:1852 +msgid "Document ended unexpectedly after the equals sign following an attribute name; no attribute value" +msgstr "बिशेषता नाम पछà¥à¤¯à¤¾à¤‰à¤¨ बराबर चिनà¥à¤¹ पछि कागजातपतà¥à¤° अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपले समापà¥à¤¤ भयो; गà¥à¤£ मान होइन" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "गà¥à¤£ मान भितà¥à¤° भà¤à¤•ो बेला कागजपतà¥à¤° अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपले समापà¥à¤¤ भयो" + +#: glib/gmarkup.c:1876 +#, fuzzy, c-format +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "ततà¥à¤µ-खà¥à¤²à¥à¤²à¤¾ टà¥à¤¯à¤¾à¤— भितà¥à¤° कागजात अपेकà¥à¤·à¤¿à¤¤ रूपले समापà¥à¤¤ भयो।" + +#: glib/gmarkup.c:1880 +#, fuzzy +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for an unopened element" +msgstr "ततà¥à¤µ-खà¥à¤²à¥à¤²à¤¾ टà¥à¤¯à¤¾à¤— भितà¥à¤° कागजात अपेकà¥à¤·à¤¿à¤¤ रूपले समापà¥à¤¤ भयो।" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "à¤à¤‰à¤Ÿà¤¾ टिपà¥à¤ªà¤£à¥€ वा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ निरà¥à¤¦à¥‡à¤¶à¤¨ भितà¥à¤° कागजपतà¥à¤° अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ रूपले समापà¥à¤¤ भयो" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[विकलà¥à¤ªâ€¦]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "मदà¥à¤¦à¤¤ विकलà¥à¤ªà¤¹à¤°à¥‚:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "मदà¥à¤¦à¤¤ विकलà¥à¤ªà¤¹à¤°à¥‚ देखाउनà¥à¤¹à¥‹à¤¸à¥" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "सबै मदà¥à¤¦à¤¤ विकलà¥à¤ªà¤¹à¤°à¥‚ देखाउनà¥à¤¹à¥‹à¤¸à¥" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— विकलà¥à¤ªà¤¹à¤°à¥‚:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "विकलà¥à¤ªà¤¹à¤°à¥‚:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, fuzzy, c-format +#| msgid "Cannot parse integer value '%s' for %s" +msgid "Cannot parse integer value “%s†for %s" +msgstr "" +"खोजी अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकà¥à¤¦à¥ˆà¤¨: %s:\n" +"%s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, fuzzy, c-format +#| msgid "Integer value '%s' for %s out of range" +msgid "Integer value “%s†for %s out of range" +msgstr "विशेषता %s का लागि, इनà¥à¤Ÿà¤¿à¤œà¤° '%s' दायरा बाहिर छ" + +#: glib/goption.c:1160 +#, fuzzy, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "" +"खोजी अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकà¥à¤¦à¥ˆà¤¨: %s:\n" +"%s" + +#: glib/goption.c:1168 +#, fuzzy, c-format +msgid "Double value “%s†for %s out of range" +msgstr "“%s†को मान दायरा बाहिर भयो" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "पद वरà¥à¤£à¤¨ विकलà¥à¤ªà¤®à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "%s का छà¥à¤Ÿà¥‡à¤•ो तरà¥à¤•" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "अजà¥à¤žà¤¾à¤¤ विकलà¥à¤ª %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "दूषित वसà¥à¤¤à¥" + +#: glib/gregex.c:257 +#, fuzzy +msgid "internal error or corrupted object" +msgstr "दूषित वसà¥à¤¤à¥" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¥€ भनà¥à¤¦à¤¾ बाहिर" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "बà¥à¤¯à¤¾à¤•टà¥à¤°à¥à¤¯à¤¾à¤•िङ सिमा पà¥à¤—à¥à¤¯à¥‹" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "आनà¥à¤¤à¤°à¤¿à¤• तà¥à¤°à¥à¤Ÿà¤¿" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "पछिलà¥à¤²à¥‹ सनà¥à¤¦à¤°à¥à¤­ लान आंशिक मिलान शरà¥à¤¤ समरà¥à¤¥à¤¿à¤¤ छैन" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¥à¤¤à¤¿ सीमा पà¥à¤—à¥à¤¯à¥‹" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "नयाठपङà¥à¤•à¥à¤¤à¤¿ à¤à¤£à¥à¤¡à¤¾à¤•ो अवैध संयोजन" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "खराब अफसेट" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "छोटो utf8" + +#: glib/gregex.c:303 +#, fuzzy +msgid "recursion loop" +msgstr "लूप" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: glib/gregex.c:327 +#, fuzzy +msgid "\\ at end of pattern" +msgstr "बाà¤à¤¨à¥à¤•ी:" + +#: glib/gregex.c:330 +#, fuzzy +msgid "\\c at end of pattern" +msgstr "बाà¤à¤¨à¥à¤•ी:" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "अपरिचित वरà¥à¤£ \\ पछि" + +#: glib/gregex.c:336 +#, fuzzy +msgid "numbers out of order in {} quantifier" +msgstr "कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° वरà¥à¤—मा कà¥à¤°à¤® बाहिर को दायरा" + +#: glib/gregex.c:339 +#, fuzzy +msgid "number too big in {} quantifier" +msgstr "अङà¥à¤• निकै ठूलो" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "वरà¥à¤£ वरà¥à¤— को अनà¥à¤¤à¥à¤¯ ] छà¥à¤Ÿà¥‡à¤•ो छ" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "वरà¥à¤£ वरà¥à¤—मा अवैध इसà¥à¤•ेप अनà¥à¤•à¥à¤°à¤®" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° वरà¥à¤—मा कà¥à¤°à¤® बाहिर को दायरा" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "दोहोरà¥à¤¯à¤¾à¤‰à¤¨à¤•ा लागि केही छैन" + +#: glib/gregex.c:355 +#, fuzzy +msgid "unexpected repeat" +msgstr "नदोहो-याउनà¥" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "अपरिचित वरà¥à¤£ पछि (? वा (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "अनà¥à¤¤à¥à¤¯à¤•ो ) छà¥à¤Ÿà¥‡à¤•ो छ" + +#: glib/gregex.c:367 +#, fuzzy +msgid "reference to non-existent subpattern" +msgstr "अ-सनà¥à¤¦à¤°à¥à¤­à¤•ो फरक !" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "टिपà¥à¤ªà¤£à¥€ पछि ) हराइरहेको छ" + +#: glib/gregex.c:373 +#, fuzzy +msgid "regular expression is too large" +msgstr "खराब नियमित अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ “{0}â€." + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ पाउन असफल" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") बिना खà¥à¤²à¥à¤¦à¥ˆà¤› (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "सङà¥à¤•ेत अतिपà¥à¤°à¤µà¤¾à¤¹" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "अजà¥à¤žà¤¾à¤¤ वरà¥à¤£ पछि (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: glib/gregex.c:394 +#, fuzzy +msgid "malformed number or name after (?(" +msgstr "विकृत संसà¥à¤•रण सङà¥à¤–à¥à¤¯à¤¾: %s" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "ससरà¥à¤¤ समूहले दà¥à¤ˆ भनà¥à¤¦à¤¾ बढी शाखा समाविषà¥à¤Ÿ गरà¥à¤¦à¤›" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "(?( पछि दाबी अपेकà¥à¤·à¤¿à¤¤" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +#, fuzzy +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "फाà¤à¤Ÿ नाम `%.*s' विरामचिनà¥à¤¹ दà¥à¤§à¤¾à¤°à¤¾ साथ दिनॠपरà¥à¤›" + +#: glib/gregex.c:410 +#, fuzzy +msgid "unknown POSIX class name" +msgstr "वरà¥à¤— नाम %s का लागि कà¥à¤¨à¥ˆ पà¥à¤°à¤•ार छैन" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX कोलà¥à¤¯à¤¾à¤Ÿà¤¿à¤™ ततà¥à¤µà¤¹à¤°à¥‚ समरà¥à¤¥à¤¿à¤¤ छैननà¥" + +#: glib/gregex.c:416 +#, fuzzy +msgid "character value in \\x{...} sequence is too large" +msgstr "\\u.... मा कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° मान अनà¥à¤•à¥à¤°à¤® धेरै ठूलो छ" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "अवैध अवसà¥à¤¥à¤¾ (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L,\\l, \\N{name}, \\U, र \\u समरà¥à¤¥à¤¿à¤¤ छैन" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "अजà¥à¤žà¤¾à¤¤ वरà¥à¤£ पछि (? पी" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "उपपटà¥à¤Ÿà¤¿à¤•ो नाममा छà¥à¤Ÿà¥‡à¤•ो टरà¥à¤®à¤¿à¤¨à¥‡à¤Ÿà¤°" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "" + +#: glib/gregex.c:445 +#, fuzzy +msgid "malformed \\P or \\p sequence" +msgstr "टà¥à¤¯à¤¾à¤¬ पिन गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: glib/gregex.c:457 +#, fuzzy +msgid "octal value is greater than \\377" +msgstr "अधिकà¥à¤¤à¤® मान नà¥à¤¯à¥‚नतम मान भनà¥à¤¦à¤¾ ठूलो हà¥à¤¨à¥à¤ªà¤°à¥à¤› ।\n" + +#: glib/gregex.c:461 +#, fuzzy +msgid "overran compiling workspace" +msgstr "कारà¥à¤¯à¤¸à¥à¤¥à¤²" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "परिभाषित समूहले à¤à¤• भनà¥à¤¦à¤¾ बढी शाखा समाविषà¥à¤Ÿ गरà¥à¤¦à¤›" + +#: glib/gregex.c:471 +#, fuzzy +msgid "inconsistent NEWLINE options" +msgstr "परसà¥à¤ªà¤°à¤¬à¤¿à¤°à¥‹à¤§à¤¿" + +#: glib/gregex.c:474 +msgid "\\g is not followed by a braced, angle-bracketed, or quoted name or number, or by a plain number" +msgstr "" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "à¤à¤‰à¤Ÿà¤¾ कà¥à¤°à¤®à¤¾à¤™à¥à¤•ित सनà¥à¤¦à¤°à¥à¤­ शूनà¥à¤¯ हà¥à¤¨à¥ हà¥à¤¦à¥ˆà¤¨" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*कà¥à¤°à¤¿à¤¯à¤¾) पहिचान गरिà¤à¤•ो छैन" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "अङà¥à¤• निकै ठूलो" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "(?& पछि उपबाà¤à¤¨à¥à¤•ी नाम हराइरहेको छ" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "(?+ पछि अङà¥à¤• अपेकà¥à¤·à¤¿à¤¤" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "उसà¥à¤¤à¥ˆ नमà¥à¤¬à¤°à¤•ो उपबाà¤à¤¨à¥à¤•ीहरूका लागि फरक नामहरू अनà¥à¤®à¤¤à¤¿ दिइà¤à¤•ो छैन" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(* मारà¥à¤•) तरà¥à¤• हà¥à¤¨à¥ परà¥à¤¦à¤›" + +#: glib/gregex.c:505 +#, fuzzy +msgid "\\c must be followed by an ASCII character" +msgstr "मà¥à¤² नोड पछि अवैध वरà¥à¤£ “%câ€" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N à¤à¤‰à¤Ÿà¤¾ वरà¥à¤—मा समरà¥à¤¥à¤¿à¤¤ छैन" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "अति धेरै अगाडीको सनà¥à¤¦à¤°à¥à¤­" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... मा कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° मान अनà¥à¤•à¥à¤°à¤® धेरै ठूलो छ" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, fuzzy, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "नियमित अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ कमà¥à¤ªà¤¾à¤‡à¤² गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ \"%s\" ।" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "" + +#: glib/gregex.c:1362 +#, fuzzy, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "नियमित अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ कमà¥à¤ªà¤¾à¤‡à¤² गरà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ \"%s\" ।" + +#: glib/gregex.c:1442 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "लाइन %d कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° %d मा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: glib/gregex.c:2427 +#, fuzzy +msgid "hexadecimal digit or “}†expected" +msgstr "(?+ पछि अङà¥à¤• अपेकà¥à¤·à¤¿à¤¤" + +#: glib/gregex.c:2443 +#, fuzzy +msgid "hexadecimal digit expected" +msgstr "(?+ पछि अङà¥à¤• अपेकà¥à¤·à¤¿à¤¤" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "पà¥à¤°à¤¤à¥€à¤•ातà¥à¤®à¤• सनà¥à¤¦à¤°à¥à¤­à¤®à¤¾ \"<\" छà¥à¤Ÿà¥‡à¤•ो छ" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "अधूरो पà¥à¤°à¤¤à¥€à¤•ातà¥à¤®à¤• सनà¥à¤¦à¤°à¥à¤­" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "शूनà¥à¤¯ लमà¥à¤¬à¤¾à¤‡à¤•ो सांकेतिक सनà¥à¤¦à¤°à¥à¤­" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "अङà¥à¤• अपेकà¥à¤·à¤¿à¤¤" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "अवैध पà¥à¤°à¤¤à¥€à¤•ातà¥à¤®à¤• सनà¥à¤¦à¤°à¥à¤­" + +#: glib/gregex.c:2591 +#, fuzzy +msgid "stray final “\\â€" +msgstr "अनà¥à¤¤à¤¿à¤®" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "अजà¥à¤žà¤¾à¤¤ इसà¥à¤•ेप अनà¥à¤•à¥à¤°à¤®" + +#: glib/gregex.c:2605 +#, fuzzy, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "लाइन %d कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° %d मा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#: glib/gshell.c:96 +#, fuzzy +#| msgid "Quoted text doesn't begin with a quotation mark" +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "उदà¥à¤§à¤°à¤£ गरिà¤à¤•ो पाठ उदà¥à¤§à¤°à¤£ चिनà¥à¤¹ बाट सà¥à¤°à¥ हà¥à¤à¤¦à¥ˆà¤¨" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "आदेश रेखामा वा अरू कवच-उदà¥à¤§à¤°à¤£ गरिà¤à¤•ो पाठमा नमिलेको उदà¥à¤§à¤°à¤£ चिनà¥à¤¹" + +#: glib/gshell.c:592 +#, fuzzy, c-format +#| msgid "Text ended just after a '\\' character. (The text was '%s')" +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "पाठ चाà¤à¤¹à¥€ '\\' कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° पछि मातà¥à¤° समापà¥à¤¤ भयो। (पाठ '%s' थियो)" + +#: glib/gshell.c:599 +#, fuzzy, c-format +#| msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "%c का लागि मिलà¥à¤¨à¥‡ उदà¥à¤§à¤°à¤£ फेला परà¥à¤¨à¥ अगाडि पाठ समापà¥à¤¤ भयो। (पाठ '%s' थियो)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "पाठ खाली थियो (वा सेतो खाली सà¥à¤¥à¤¾à¤¨ मातà¥à¤° समावेश थियो)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) बाट डेटा पढà¥à¤¨ असफल" + +#: glib/gspawn.c:462 +#, fuzzy, c-format +#| msgid "Unexpected error in select() reading data from a child process (%s)" +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾à¤¬à¤¾à¤Ÿ डेटा पढà¥à¤¦à¤¾ g_io_channel_win32_poll() अनपेकà¥à¤·à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() (%s) मा अनपेकà¥à¤·à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ सङà¥à¤•ेत %ld सà¤à¤— बाहिरियो" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ %ld सङà¥à¤•ेतदà¥à¤µà¤¾à¤°à¤¾ मारियो" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ %ld सङà¥à¤•ेतदà¥à¤µà¤¾à¤°à¤¾ रोकियो" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ असामानà¥à¤¯ तरिकाले अनà¥à¤¤à¥à¤¯ भयो" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s)बाट पढà¥à¤¨ असफल" + +#: glib/gspawn.c:2253 +#, fuzzy, c-format +#| msgid "Failed to execute child process \"%s\" (%s)" +msgid "Failed to spawn child process “%s†(%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¨ असफल" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) फोरà¥à¤• गरà¥à¤¨ असफल" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, fuzzy, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to change to directory “%s†(%s)" +msgstr "समà¥à¤ªà¤°à¥à¤•को उपनाम परिवरà¥à¤¤à¤¨ गरà¥à¤¨ असफल भयो:%s" + +#: glib/gspawn.c:2540 +#, fuzzy, c-format +#| msgid "Failed to execute child process \"%s\" (%s)" +msgid "Failed to execute child process “%s†(%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¨ असफल" + +#: glib/gspawn.c:2550 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': open() failed: %s" +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "कारà¥à¤¯ फाइल %s: %s fdopen() गरà¥à¤¨ असफल" + +#: glib/gspawn.c:2558 +#, fuzzy, c-format +#| msgid "Failed to redirect output or input of child process (%s)" +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) को निरà¥à¤—त वा आगत पà¥à¤¨:निरà¥à¤¦à¥‡à¤¶à¤¿à¤¨ गरà¥à¤¨ असफल" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) फोरà¥à¤• गरà¥à¤¨ असफल" + +#: glib/gspawn.c:2575 +#, fuzzy, c-format +#| msgid "Failed to read data from child process (%s)" +msgid "Failed to close file descriptor for child process (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) बाट डेटा पढà¥à¤¨ असफल" + +#: glib/gspawn.c:2583 +#, fuzzy, c-format +#| msgid "Unknown error executing child process \"%s\"" +msgid "Unknown error executing child process “%sâ€" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ \"%s\" कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¦à¤¾ अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "शाखा पिड पाईप (%s) बाट पà¥à¤°à¤¶à¤¸à¥à¤¤ डेटाहरू पढà¥à¤¨ असफल" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾à¤¬à¤¾à¤Ÿ डेटा पढà¥à¤¨ असफल भयो" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¨ असफल" + +#: glib/gspawn-win32.c:400 +#, fuzzy, c-format +#| msgid "Failed to fork child process (%s)" +msgid "Failed to dup() in child process (%s)" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ (%s) कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¨ असफल" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "अवैध कारà¥à¤¯à¤•à¥à¤°à¤® नाम : %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "आरà¥à¤—à¥à¤®à¥‡à¤¨à¥à¤Ÿ भेकà¥à¤Ÿà¤°à¤•ो %d मा अवैध सà¥à¤Ÿà¥à¤°à¥€à¤™: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "वातावरणमा अवैध सà¥à¤Ÿà¥à¤°à¥€à¤™: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "अवैध कारà¥à¤¯ डाइरेकà¥à¤Ÿà¤°à¥€ : %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "मदà¥à¤¦à¤¤ गरà¥à¤¨à¥‡ कारà¥à¤¯à¤•à¥à¤°à¤® कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¤¨ गरà¥à¤¨ असफल (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "Unexpected error in g_io_channel_win32_poll() reading data from a child process" +msgstr "शाखा पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾à¤¬à¤¾à¤Ÿ डेटा पढà¥à¤¦à¤¾ g_io_channel_win32_poll() अनपेकà¥à¤·à¤¿à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "खाली सà¥à¤Ÿà¥à¤°à¤¿à¤™ सङà¥à¤–à¥à¤¯à¤¾ होइन" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "\"%s\" चिनà¥à¤¹ लगाइà¤à¤•ो सङà¥à¤–à¥à¤¯à¤¾ होइन" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, fuzzy, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "मà¥à¤¦à¥à¤°à¤£à¤¯à¤¨à¥à¤¤à¥à¤°\"%s\" मा विकासकरà¥à¤¤à¤¾ छैन ।." + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "\"%s\" चिनà¥à¤¹ रहित सङà¥à¤–à¥à¤¯à¤¾ होइन" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "URI मा अवैध %-सङà¥à¤•ेतन" + +#: glib/guri.c:332 +#, fuzzy +msgid "Illegal character in URI" +msgstr "URI" + +#: glib/guri.c:366 +#, fuzzy +msgid "Non-UTF-8 characters in URI" +msgstr "जहाठसंखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• नभà¤à¤•ो वरà¥à¤£à¤¹à¤°à¥ बेवासà¥à¤¤à¤¾ गरिन सकà¥à¤›à¤¨" + +#: glib/guri.c:546 +#, fuzzy, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "अमानà¥à¤¯ \"%s\" URI:%s" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "यूआरआईमा पोरà¥à¤Ÿ '%.*s' पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकेन" + +#: glib/guri.c:664 +#, fuzzy, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "यूआरआईमा पोरà¥à¤Ÿ '%.*s' पद वरà¥à¤£à¤¨ गरà¥à¤¨ सकेन" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "'%s' यूआरआई à¤à¤‰à¤Ÿà¤¾ निशà¥à¤šà¤¿à¤¤ यूआरआई होइन" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "" + +#: glib/guri.c:1460 +#, fuzzy +msgid "URI is not absolute, and no base URI was provided" +msgstr "'%s' यूआरआई à¤à¤‰à¤Ÿà¤¾ निशà¥à¤šà¤¿à¤¤ यूआरआई होइन" + +#: glib/guri.c:2238 +#, fuzzy +msgid "Missing ‘=’ and parameter value" +msgstr "परामिति" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ निरà¥à¤§à¤¾à¤°à¤£ गरà¥à¤¨ अकà¥à¤·à¤®" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 का लागि कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° दायरा भनà¥à¤¦à¤¾ बाहिर छ" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "रूपानà¥à¤¤à¤°à¤£ आगतमा अवैध अनà¥à¤•à¥à¤°à¤®" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 का लागि कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° दायरा भनà¥à¤¦à¤¾ बाहिर छ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u बाइट" +msgstr[1] "%u बाइट" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u विट" +msgstr[1] "%u बिटहरू" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s बाइट" +msgstr[1] "%s बाइट" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s विट" +msgstr[1] "%s विटहरू" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "No such method '%s'" +#~ msgstr "यसà¥à¤¤à¥‹ '%s' विधि छैन" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "डेटासà¥à¤°à¥‹à¤¤ कनà¥à¤«à¤¿à¤—रेसन तà¥à¤°à¥à¤Ÿà¤¿:निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नगरेको पà¥à¤°à¤¦à¤¾à¤¯à¤•\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "डेटासà¥à¤°à¥‹à¤¤ कनà¥à¤«à¤¿à¤—रेसन तà¥à¤°à¥à¤Ÿà¤¿:निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नगरेको पà¥à¤°à¤¦à¤¾à¤¯à¤•\n" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGS...]" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s मा %s मा माउनà¥à¤Ÿ गरियो\n" + +#, fuzzy +#~| msgid "Failed to create file '%s': %s" +#~ msgid "Failed to create temp file: %s" +#~ msgstr "%s टेमà¥à¤ª फाइल भितà¥à¤° पतà¥à¤° भणà¥à¤¡à¤¾à¤° गरà¥à¤¨ असफल भयो: %s" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "कà¥à¤žà¥à¤œà¥€à¤®à¤¾ अधिलेखन बेवासà¥à¤¤à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" + +#, fuzzy +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr "निसà¥à¤•à¤à¤¦à¥ˆ" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "कà¥à¤žà¥à¤œà¥€à¤®à¤¾ अधिलेखन बेवासà¥à¤¤à¤¾ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "केही पनि होइन\n" + +#, fuzzy +#~ msgid "Unknown error on connect" +#~ msgstr "आनà¥à¤¤à¤°à¤¿à¤• तà¥à¤°à¥à¤Ÿà¤¿: अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¤¿" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "लेखà¥à¤¨à¤•ा लागि '%s' फाइल खोलà¥à¤¨ असफल : fdopen() असफल : %s" + +#, fuzzy +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "'%s' फाइल लेखà¥à¤¨ असफल : fलेखà¥à¤¨() असफल : %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "'%s' फाइल बनà¥à¤¦ गरà¥à¤¨ असफल : fबनà¥à¤¦ गरà¥à¤¨() असफल : %s" + +#~ msgid "File is empty" +#~ msgstr "फाइल खाली छ" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "कà¥à¤žà¥à¤œà¥€ फाइलसंगकà¥à¤žà¥à¤œà¥€ '%s' हà¥à¤à¤¦à¥ˆà¤¨" + +#~ msgid "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "कà¥à¤žà¥à¤œà¥€ फाइलमा कà¥à¤žà¥à¤œà¥€ '%s' समावेश छ जसको मानलाई वà¥à¤¯à¤¾à¤–à¥à¤¯à¤¾ गरà¥à¤¨ सकिà¤à¤¦à¥ˆà¤¨à¥¤" + +#, fuzzy +#~ msgid "Error statting directory '%s': %s" +#~ msgstr "डाइरेकà¥à¤Ÿà¤°à¥€ '%s' खोलà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#, fuzzy +#~ msgid "Error opening file: %s" +#~ msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#, fuzzy +#~ msgid "Error stating file '%s': %s" +#~ msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#, fuzzy +#~ msgid "Error connecting: " +#~ msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#, fuzzy +#~ msgid "Error connecting: %s" +#~ msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#, fuzzy +#~ msgid "Error reading from unix: %s" +#~ msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#, fuzzy +#~ msgid "Error closing unix: %s" +#~ msgstr "लाइन %d मा तà¥à¤°à¥à¤Ÿà¤¿: %s" + +#, fuzzy +#~ msgid "Error writing to unix: %s" +#~ msgstr "पद वरà¥à¤£à¤¨ विकलà¥à¤ªà¤®à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ %s" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "रूपानà¥à¤¤à¤°à¤£ आगतमा अवैध अनà¥à¤•à¥à¤°à¤®" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & character begins an entity; if this ampersand " +#~ "isn't supposed to be an entity, escape it as &" +#~ msgstr "" +#~ "असà¥à¤¤à¤¿à¤¤à¥à¤µ नामको सà¥à¤°à¥à¤®à¤¾ कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° '%s' वैध हà¥à¤à¤¦à¥ˆà¤¨ ; & कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤°à¤²à¥‡ à¤à¤‰à¤Ÿà¤¾ असà¥à¤¤à¤¿à¤¤à¥à¤µà¤¾ सà¥à¤°à¥ गरà¥à¤¦à¤› ; यदि यो à¤à¤®à¥à¤ªà¤°à¤¸à¥à¤¯à¤¾à¤¨à¥à¤¡ भà¤à¤®à¤¾ à¤à¤‰à¤Ÿà¤¾ असà¥à¤¤à¤¿à¤¤à¥à¤µà¤•ो " +#~ "रूपमा मानिà¤à¤¦à¥ˆà¤¨,यसलाई & को रूपमा परितà¥à¤¯à¤¾à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "खाली कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° सनà¥à¤¦à¤°à¥à¤­, dž जसà¥à¤¤à¥‹ अङà¥à¤• समाहित हà¥à¤¨à¥à¤ªà¤°à¥à¤›" + +#~ msgid "Unfinished entity reference" +#~ msgstr "अधà¥à¤°à¥‹ असà¥à¤¤à¤¿à¤¤à¥à¤µ सनà¥à¤¦à¤°à¥à¤­" + +#~ msgid "Unfinished character reference" +#~ msgstr "अधà¥à¤°à¥‹ कà¥à¤¯à¤¾à¤°à¥‡à¤•à¥à¤Ÿà¤° सनà¥à¤¦à¤°à¥à¤­" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "अवैध UTF-8 सङà¥à¤•ेतन गरिà¤à¤•ो पाठ" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "अवैध UTF-8 सङà¥à¤•ेतन गरिà¤à¤•ो पाठ" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "URI '%s' को होसà¥à¤Ÿà¤¨à¤¾à¤® अवैध छ" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "'%s' फाइल पढà¥à¤¦à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ : %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "पद वरà¥à¤£à¤¨ विकलà¥à¤ªà¤®à¤¾ तà¥à¤°à¥à¤Ÿà¤¿ %s" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000..e73d986 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,6241 @@ +# Dutch translation for glib +# This file is distributed under the same license as the glib package. +# Dirk-Jan C. Binnema 2001 +# Tino Meinen 2002–2008 +# Wouter Bolsterlee , 2008–2013 +# Rachid , 2012. +# Justin van Steijn , 2018. +# Nathan Follens , 2019-2020. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2020-03-06 12:58+0000\n" +"PO-Revision-Date: 2020-02-27 20:48+0100\n" +"Last-Translator: Nathan Follens \n" +"Language-Team: Dutch \n" +"Language: nl\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 2.3\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication-opties" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "GApplication-opties tonen" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Voer de GApplication-dienstmodus in (gebruik uit D-Bus-dienstbestanden)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Toepassings-ID overschrijven" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Vervang de actieve instantie" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:493 gio/gsettings-tool.c:567 +msgid "Print help" +msgstr "Hulp tonen" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:494 gio/gresource-tool.c:562 +msgid "[COMMAND]" +msgstr "[OPDRACHT]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Versie tonen" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:573 +msgid "Print version information and exit" +msgstr "Versie-informatie tonen en afsluiten" + +#: gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Toepassingen tonen" + +#: gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" + +#: gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "Een toepassing starten" + +#: gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "De toepassing starten (met optioneel te openen bestanden)" + +#: gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "APPID [BESTAND…]" + +#: gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "Een actie activeren" + +#: gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "" + +#: gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTIE [PARAMETER]" + +#: gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Beschikbare acties tonen" + +#: gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" + +#: gio/gapplication-tool.c:65 gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "OPDRACHT" + +#: gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "" + +#: gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" + +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:500 gio/gresource-tool.c:566 +msgid "FILE" +msgstr "BESTAND" + +#: gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" + +#: gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "ACTIE" + +# opsomming/teller +#: gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "De actienaam om aan te roepen" + +#: gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" + +#: gio/gapplication-tool.c:96 gio/gresource-tool.c:531 gio/gsettings-tool.c:659 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Onbekende opdracht %s\n" +"\n" + +#: gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "Gebruik:\n" + +#: gio/gapplication-tool.c:114 gio/gresource-tool.c:556 +#: gio/gsettings-tool.c:694 +msgid "Arguments:\n" +msgstr "Argumenten:\n" + +#: gio/gapplication-tool.c:133 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTEN…]" + +#: gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Opdrachten:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" + +#: gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "ongeldige toepassings-id: ‘%s’\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:182 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"‘%s’ verwacht geen argumenten\n" +"\n" + +# Openen van converteerder van '%s' naar '%s' mislukt: %s +#: gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "kan niet verbinden met D-Bus: %s\n" + +# openen/lezen +#: gio/gapplication-tool.c:286 +#, fuzzy, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "Fout bij versturen van bericht: %s" + +#: gio/gapplication-tool.c:317 +msgid "action name must be given after application id\n" +msgstr "" + +#: gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" + +#: gio/gapplication-tool.c:344 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "Fout bij ontleden van parameter %d: %s\n" + +#: gio/gapplication-tool.c:356 +msgid "actions accept a maximum of one parameter\n" +msgstr "" + +#: gio/gapplication-tool.c:411 +msgid "list-actions command takes only the application id" +msgstr "" + +#: gio/gapplication-tool.c:421 +#, fuzzy, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "Kan geen terminalvenster vinden voor het uitvoeren van het programma" + +#: gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"niet-herkende opdracht: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "De telwaarde die aan %s werd gegeven is te groot" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Zoeken binnen datastroom niet mogelijk" + +#: gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Kan GMemoryInputStream niet afkappen" + +#: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "De stroom is al gesloten" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Afkappen wordt niet ondersteund op een datastroom" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1411 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "De bewerking werd afgebroken" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Ongeldig object, niet geïnitialiseerd" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Onvolledige multibyte-reeks in invoer" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Niet genoeg ruimte op bestemming" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:447 glib/gconvert.c:877 +#: glib/giochannel.c:1564 glib/giochannel.c:1606 glib/giochannel.c:2461 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "Ongeldige bytereeks in conversie-invoer" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:455 glib/gconvert.c:791 +#: glib/giochannel.c:1571 glib/giochannel.c:2473 +#, c-format +msgid "Error during conversion: %s" +msgstr "Fout tijdens omzetten: %s" + +# niet ondersteund/niet mogelijk +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1138 +msgid "Cancellable initialization not supported" +msgstr "Annuleerbare initialisatie wordt niet ondersteund" + +# is niet mogelijk/wordt niet ondersteund +#: gio/gcharsetconverter.c:456 glib/gconvert.c:320 glib/giochannel.c:1392 +#, fuzzy, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Het omzetten van tekenset ‘%s’ naar ‘%s’ is niet mogelijk" + +# conversieprogramma/omzet-programma/omzetter +# kon converteerder van %s naar %s niet openen +# Openen van converteerder van '%s' naar '%s' mislukt +# Openen van het programma voor het omzetten van s naar s is mislukt +# (tekenreeks komt verderop nog een keer voor) +#: gio/gcharsetconverter.c:460 glib/gconvert.c:324 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "" +"Kon het conversieprogramma voor het omzetten van ‘%s’ naar ‘%s’ niet openen" + +#: gio/gcontenttype.c:452 +#, c-format +msgid "%s type" +msgstr "type %s" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Onbekend type" + +# bestandssoort/bestandstype +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "bestandstype %s" + +#: gio/gcredentials.c:289 +msgid "GCredentials contains invalid data" +msgstr "GCredentials bevat ongeldige gegevens" + +#: gio/gcredentials.c:345 gio/gcredentials.c:609 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials is niet geïmplementeerd op dit besturingssysteem" + +#: gio/gcredentials.c:503 +msgid "There is no GCredentials support for your platform" +msgstr "GCredentials wordt niet ondersteund op uw platform" + +#: gio/gcredentials.c:552 +#, fuzzy +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials is niet geïmplementeerd op dit besturingssysteem" + +#: gio/gcredentials.c:603 +#, fuzzy +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "GCredentials is niet geïmplementeerd op dit besturingssysteem" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Voortijdig einde aan gegevensstroom" + +#: gio/gdbusaddress.c:158 gio/gdbusaddress.c:232 gio/gdbusaddress.c:321 +#, fuzzy, c-format +#| msgid "Unsupported key '%s' in address entry '%s'" +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Niet ondersteunde sleutel ‘%s’ in adres ‘%s’" + +#: gio/gdbusaddress.c:171 +#, fuzzy, c-format +#| msgid "Meaningless key/value pair combination in address entry '%s'" +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Onzinnige sleutel- en waardecombinatie in adres ‘%s’" + +#: gio/gdbusaddress.c:180 +#, fuzzy, c-format +#| msgid "" +#| "Address '%s' is invalid (need exactly one of path, tmpdir or abstract " +#| "keys)" +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "Adres ‘%s’ is ongeldig (pad, tmpdir of abstracte sleutel nodig)" + +#: gio/gdbusaddress.c:247 gio/gdbusaddress.c:258 gio/gdbusaddress.c:273 +#: gio/gdbusaddress.c:336 gio/gdbusaddress.c:347 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the port attribute is malformed" +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Fout in adres ‘%s’ - het poort-attribuut is onjuist gevormd" + +#: gio/gdbusaddress.c:417 gio/gdbusaddress.c:681 +#, fuzzy, c-format +#| msgid "Unknown or unsupported transport '%s' for address '%s'" +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Onbekend of niet ondersteund transport ‘%s’ voor adres ‘%s’" + +#: gio/gdbusaddress.c:461 +#, fuzzy, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adreselement ‘%s’ bevat geen dubbele punt (:)" + +#: gio/gdbusaddress.c:470 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:491 +#, fuzzy, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Sleutel/waarde-paar %d, ‘%s’ in adreselement ‘%s’ bevat geen is-gelijk-teken." + +#: gio/gdbusaddress.c:502 +#, fuzzy, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Sleutel/waarde-paar %d, ‘%s’ in adreselement ‘%s’ bevat geen is-gelijk-teken." + +#: gio/gdbusaddress.c:516 +#, fuzzy, c-format +#| msgid "" +#| "Error unescaping key or value in Key/Value pair %d, '%s', in address " +#| "element '%s'" +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Fout bij het ‘unescapen’ van sleutel of waarde in sleutel/waarde-paar %d, " +"‘%s’, in adreselement ‘%s’" + +#: gio/gdbusaddress.c:588 +#, fuzzy, c-format +#| msgid "" +#| "Error in address '%s' - the unix transport requires exactly one of the " +#| "keys 'path' or 'abstract' to be set" +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Fout in adres ‘%s’ — Unix-transport heeft ofwel de sleutel ‘path’ ofwel de " +"sleutel ‘abstract’ nodig" + +#: gio/gdbusaddress.c:624 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the host attribute is missing or malformed" +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Fout in adres ‘%s’ — het host-attribuut ontbreekt of is onjuist gevormd" + +#: gio/gdbusaddress.c:638 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the port attribute is missing or malformed" +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Fout in adres ‘%s’ — het port-attribuut ontbreekt of is onjuist gevormd" + +#: gio/gdbusaddress.c:652 +#, fuzzy, c-format +#| msgid "" +#| "Error in address '%s' - the noncefile attribute is missing or malformed" +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Fout in adres ‘%s’ — het noncefile-attribuut ontbreekt of is onjuist gevormd" + +#: gio/gdbusaddress.c:673 +msgid "Error auto-launching: " +msgstr "Fout bij automatisch opstarten: " + +# lezen/openen +#: gio/gdbusaddress.c:726 +#, fuzzy, c-format +#| msgid "Error opening nonce file '%s': %s" +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Fout bij het openen van nonce-bestand ‘%s’: %s" + +#: gio/gdbusaddress.c:745 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s': %s" +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Fout bij het lezen van nonce-bestand ‘%s’: %s" + +#: gio/gdbusaddress.c:754 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Fout bij het lezen van nonce-bestand ‘%s’, 16 bytes werden verwacht, maar %d " +"bytes ontvangen" + +#: gio/gdbusaddress.c:772 +#, fuzzy, c-format +#| msgid "Error writing contents of nonce file '%s' to stream:" +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Fout tijdens het schrijven van de inhoud van nonce-bestand ‘%s’ naar " +"gegevensstroom:" + +#: gio/gdbusaddress.c:981 +msgid "The given address is empty" +msgstr "Het opgegeven adres is leeg" + +#: gio/gdbusaddress.c:1094 +#, fuzzy, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Kan geen message-bus starten zonder machine-ID: " + +#: gio/gdbusaddress.c:1101 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Kan geen message-bus starten zonder machine-ID: " + +#: gio/gdbusaddress.c:1108 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: gio/gdbusaddress.c:1150 +#, fuzzy, c-format +#| msgid "Error spawning command line '%s': " +msgid "Error spawning command line “%sâ€: " +msgstr "Fout bij starten van de opdrachtregel ‘%s’: " + +#: gio/gdbusaddress.c:1219 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Kan adres van sessiebus niet bepalen (niet geïmplementeerd voor dit " +"besturingssysteem)" + +#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7190 +#, fuzzy, c-format +#| msgid "" +#| "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#| "variable - unknown value '%s'" +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Kan adres van bus niet bepalen van DBUS_STARTER_BUS_TYPE omgevingsvariabele " +"- onbekende waarde ‘%s’" + +#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7199 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Kan adres van bus niet bepalen omdat de omgevingsvariabele " +"DBUS_STARTER_BUS_TYPE niet is ingesteld" + +#: gio/gdbusaddress.c:1376 +#, c-format +msgid "Unknown bus type %d" +msgstr "Onbekend bustype %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: gio/gdbusauth.c:1167 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:264 +#, fuzzy, c-format +#| msgid "Error when getting information for directory '%s': %s" +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Fout bij ophalen van informatie voor de map ‘%s’: %s" + +#: gio/gdbusauthmechanismsha1.c:276 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:301 +#, fuzzy, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory “%sâ€: %s" +msgstr "Fout bij het aanmaken van map ‘%s’: %s" + +# lezen/openen +#: gio/gdbusauthmechanismsha1.c:348 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for reading: " +msgid "Error opening keyring “%s†for reading: " +msgstr "Fout bij het openen van sleutelbos ‘%s’: " + +#: gio/gdbusauthmechanismsha1.c:371 gio/gdbusauthmechanismsha1.c:689 +#, fuzzy, c-format +#| msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Regel %d van de sleutelbos in ‘%s’ met inhoud ‘%s’ is onjuist gevormd" + +#: gio/gdbusauthmechanismsha1.c:385 gio/gdbusauthmechanismsha1.c:703 +#, fuzzy, c-format +#| msgid "" +#| "First token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Eerste token op regel %d van de sleutelbos in ‘%s’ met inhoud ‘%s’ is " +"onjuist gevormd" + +#: gio/gdbusauthmechanismsha1.c:399 gio/gdbusauthmechanismsha1.c:717 +#, fuzzy, c-format +#| msgid "" +#| "First token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Eerste token op regel %d van de sleutelbos in ‘%s’ met inhoud ‘%s’ is " +"onjuist gevormd" + +#: gio/gdbusauthmechanismsha1.c:423 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" + +#: gio/gdbusauthmechanismsha1.c:505 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Fout bij lezen van verouderd vergrendelingsbestand ‘%s’: %s" + +#: gio/gdbusauthmechanismsha1.c:537 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Fout bij aanmaken vergrendelingsbestand ‘%s’: %s" + +#: gio/gdbusauthmechanismsha1.c:568 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Fout bij het sluiten van (ontkoppeld) vergrendelingsbestand ‘%s’: %s" + +# lezen/openen +#: gio/gdbusauthmechanismsha1.c:579 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Fout bij het ontkoppelen van vergrendelingsbestand ‘%s’: %s" + +# lezen/openen +#: gio/gdbusauthmechanismsha1.c:656 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Fout bij het openen van sleutelbos ‘%s’ voor schrijven: " + +#: gio/gdbusauthmechanismsha1.c:852 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Vrijgeven van vergrendeling voor ‘%s’ is ook mislukt: %s) " + +# opsomming/teller +#: gio/gdbusconnection.c:595 gio/gdbusconnection.c:2391 +msgid "The connection is closed" +msgstr "De verbinding is gesloten" + +#: gio/gdbusconnection.c:1892 +msgid "Timeout was reached" +msgstr "Tijd is verlopen" + +#: gio/gdbusconnection.c:2513 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: gio/gdbusconnection.c:4161 gio/gdbusconnection.c:4508 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "Geen interface ‘org.freedesktop.DBus.Properties’ op object met pad %s" + +#: gio/gdbusconnection.c:4303 +#, c-format +msgid "No such property “%sâ€" +msgstr "Geen eigenschap ‘%s’" + +#: gio/gdbusconnection.c:4315 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Eigenschap ‘%s’ is niet leesbaar" + +#: gio/gdbusconnection.c:4326 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Eigenschap ‘%s’ is niet schrijfbaar" + +#: gio/gdbusconnection.c:4346 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Fout bij het instellen van eigenschap ‘%s’: verwachte type ‘%s’, maar ‘%s’ " +"ontvangen" + +#: gio/gdbusconnection.c:4451 gio/gdbusconnection.c:4659 +#: gio/gdbusconnection.c:6630 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Interface ‘%s’ bestaat niet" + +#: gio/gdbusconnection.c:4877 gio/gdbusconnection.c:7139 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Interface ‘%s’ op object met pad %s bestaat niet" + +#: gio/gdbusconnection.c:4975 +#, c-format +msgid "No such method “%sâ€" +msgstr "Geen methode ‘%s’" + +#: gio/gdbusconnection.c:5006 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Berichttype ‘%s’ komt niet overeen met verwachte type ‘%s’" + +#: gio/gdbusconnection.c:5204 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Er is al een object geëxporteerd voor de interface %s op %s" + +#: gio/gdbusconnection.c:5430 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Kan eigenschap %s.%s niet ophalen" + +#: gio/gdbusconnection.c:5486 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Kan eigenschap %s.%s niet instellen" + +#: gio/gdbusconnection.c:5664 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Methode ‘%s’ gaf type ‘%s’ terug, maar ‘%s’ werd verwacht" + +#: gio/gdbusconnection.c:6741 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Methode ‘%s’ op interface ‘%s’ met ondertekening ‘%s’ bestaat niet" + +#: gio/gdbusconnection.c:6862 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Er is reeds een sub-boom geëxporteerd voor %s" + +#: gio/gdbusmessage.c:1255 +msgid "type is INVALID" +msgstr "type is INVALID" + +#: gio/gdbusmessage.c:1266 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL-bericht: veld PATH of MEMBER ontbreekt in koptekst" + +#: gio/gdbusmessage.c:1277 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN-bericht: veld REPLY_SERIAL ontbreekt in koptekst" + +#: gio/gdbusmessage.c:1289 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR-bericht: veld REPLY_SERIAL of ERROR_NAME ontbreekt in koptekst" + +#: gio/gdbusmessage.c:1302 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL message: veld PATH, INTERFACE of MEMBER ontbreekt in koptekst" + +#: gio/gdbusmessage.c:1310 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL-bericht: veld PATH in koptekst gebruikt de gereserveerde waarde /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1318 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL-bericht: veld PATH in koptekst gebruikt de gereserveerde waarde org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" +msgstr[1] "" + +#: gio/gdbusmessage.c:1380 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" + +#: gio/gdbusmessage.c:1399 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "" + +#: gio/gdbusmessage.c:1631 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "" + +#: gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" + +#: gio/gdbusmessage.c:1884 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" + +#: gio/gdbusmessage.c:1925 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2110 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" + +#: gio/gdbusmessage.c:2123 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773 +msgid "Signature header found but is not of type signature" +msgstr "Ondertekeningshoofding gevonden, maar niet van type ondertekening" + +#: gio/gdbusmessage.c:2189 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Ondertekeningshoofding met ondertekening ‘%s’ gevonden, maar berichtinhoud " +"is leeg" + +#: gio/gdbusmessage.c:2204 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Verwerkte waarde ‘%s’ is geen geldige D-Bus-ondertekening (voor inhoud)" + +#: gio/gdbusmessage.c:2236 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Geen berichthoofding in bericht, maar berichtinhoud is %u byte" +msgstr[1] "Geen berichthoofding in bericht, maar berichtinhoud is %u bytes" + +#: gio/gdbusmessage.c:2246 +msgid "Cannot deserialize message: " +msgstr "Kan bericht niet deserialiseren: " + +#: gio/gdbusmessage.c:2590 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" + +#: gio/gdbusmessage.c:2727 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2735 +msgid "Cannot serialize message: " +msgstr "Kan bericht niet serialiseren: " + +#: gio/gdbusmessage.c:2788 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Berichtinhoud heeft ondertekening ‘%s’, maar er is geen " +"ondertekeningshoofding" + +#: gio/gdbusmessage.c:2798 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Berichtinhoud heeft type ondertekening ‘%s’, maar ondertekening in het " +"hoofdingsvak is ‘%s’" + +#: gio/gdbusmessage.c:2814 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Berichtinhoud is leeg, maar ondertekening in hoofdingsvak is ‘(%s)’" + +#: gio/gdbusmessage.c:3367 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "" + +#: gio/gdbusmessage.c:3375 +msgid "Error return with empty body" +msgstr "" + +#: gio/gdbusprivate.c:2242 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Typ een willekeurige letter om dit venster te sluiten)\n" + +#: gio/gdbusprivate.c:2416 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Sessie-dbus is niet actief, en autolauch is mislukt" + +#: gio/gdbusprivate.c:2439 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Kan hardware-profiel niet verkrijgen: %s" + +#: gio/gdbusprivate.c:2484 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Kan /var/lib/dbus/machine-id of /etc/machine-id niet laden: " + +#: gio/gdbusproxy.c:1562 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Fout bij aanroepen van StartServiceByName voor %s: " + +#: gio/gdbusproxy.c:1585 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: gio/gdbusproxy.c:2685 gio/gdbusproxy.c:2820 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +# wordt hier niet ondersteund +# (dus bijv. op een aangekoppelde externe opslag?) +#: gio/gdbusserver.c:755 +msgid "Abstract namespace not supported" +msgstr "Abstracte namespace wordt niet ondersteund" + +#: gio/gdbusserver.c:848 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: gio/gdbusserver.c:930 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Fout bij schrijven van nonce-bestand naar ‘%s’: %s" + +#: gio/gdbusserver.c:1103 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "De tekenreeks ‘%s’ is geen geldige GUID voor D-Bus" + +#: gio/gdbusserver.c:1143 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Kan niet luisteren op niet-ondersteund transport ‘%s’" + +#: gio/gdbus-tool.c:107 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" + +#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336 +#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:850 gio/gdbus-tool.c:1187 +#: gio/gdbus-tool.c:1672 +#, c-format +msgid "Error: %s\n" +msgstr "Fout: %s\n" + +#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1688 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Fout bij verwerken van introspectie-XML %s\n" + +#: gio/gdbus-tool.c:246 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Fout: %s is geen geldige naam\n" + +#: gio/gdbus-tool.c:394 +msgid "Connect to the system bus" +msgstr "Verbinden met systeembus" + +#: gio/gdbus-tool.c:395 +msgid "Connect to the session bus" +msgstr "Verbinden met sessiebus" + +#: gio/gdbus-tool.c:396 +msgid "Connect to given D-Bus address" +msgstr "Verbinden met opgegeven D-Bus-adres" + +#: gio/gdbus-tool.c:406 +msgid "Connection Endpoint Options:" +msgstr "Verbindingseindpuntopties:" + +#: gio/gdbus-tool.c:407 +msgid "Options specifying the connection endpoint" +msgstr "Opties voor het verbindingseindpunt" + +#: gio/gdbus-tool.c:430 +#, c-format +msgid "No connection endpoint specified" +msgstr "Geen eindpunt voor verbinding opgegeven" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Meerdere eindpunten voor verbinding opgegeven" + +#: gio/gdbus-tool.c:513 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Let op: volgens de introspectiegegevens bestaat de interface ‘%s’ niet\n" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Let op: volgens de introspectiegegevens bestaat de methode ‘%s’ op de " +"interface ‘%s’ niet\n" + +#: gio/gdbus-tool.c:584 +msgid "Optional destination for signal (unique name)" +msgstr "Optionele bestemming van signaal (unieke naam)" + +#: gio/gdbus-tool.c:585 +msgid "Object path to emit signal on" +msgstr "Objectpad waarop het signaal uitgestuurd moet worden" + +#: gio/gdbus-tool.c:586 +msgid "Signal and interface name" +msgstr "Signaal- en interfacenaam" + +#: gio/gdbus-tool.c:619 +msgid "Emit a signal." +msgstr "Stuur een signaal uit." + +# openen/lezen +#: gio/gdbus-tool.c:674 gio/gdbus-tool.c:981 gio/gdbus-tool.c:1775 +#: gio/gdbus-tool.c:2007 gio/gdbus-tool.c:2227 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Fout bij verbinden: %s\n" + +#: gio/gdbus-tool.c:694 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Fout: %s is geen geldige unieke busnaam.\n" + +#: gio/gdbus-tool.c:713 gio/gdbus-tool.c:1024 gio/gdbus-tool.c:1818 +msgid "Error: Object path is not specified\n" +msgstr "Fout: geen objectpad opgegeven\n" + +#: gio/gdbus-tool.c:736 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1838 +#: gio/gdbus-tool.c:2078 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Fout: %s is geen geldig objectpad\n" + +#: gio/gdbus-tool.c:756 +msgid "Error: Signal name is not specified\n" +msgstr "Fout: signaalnaam is niet opgegeven\n" + +#: gio/gdbus-tool.c:770 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Fout: signaalnaam ‘%s’ is ongeldig\n" + +#: gio/gdbus-tool.c:782 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Fout: ‘%s’ is geen geldige interface-naam\n" + +#: gio/gdbus-tool.c:788 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Fout: ‘%s’ is geen geldige member-naam\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:825 gio/gdbus-tool.c:1156 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Fout bij ontleden van parameter %d: %s\n" + +#: gio/gdbus-tool.c:857 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Fout bij flushen van verbinding: %s\n" + +#: gio/gdbus-tool.c:884 +msgid "Destination name to invoke method on" +msgstr "Bestemmingsnaam om methode voor aan te roepen" + +#: gio/gdbus-tool.c:885 +msgid "Object path to invoke method on" +msgstr "Objectpad om methode op aan te roepen" + +#: gio/gdbus-tool.c:886 +msgid "Method and interface name" +msgstr "Methode en interfacenaam" + +#: gio/gdbus-tool.c:887 +msgid "Timeout in seconds" +msgstr "Tijdslimiet in seconden" + +#: gio/gdbus-tool.c:926 +msgid "Invoke a method on a remote object." +msgstr "Methode aanroepen op een object op afstand." + +#: gio/gdbus-tool.c:998 gio/gdbus-tool.c:1792 gio/gdbus-tool.c:2032 +msgid "Error: Destination is not specified\n" +msgstr "Fout: bestemming is niet opgegeven\n" + +#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1809 gio/gdbus-tool.c:2043 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Fout: %s is geen geldige busnaam\n" + +#: gio/gdbus-tool.c:1059 +msgid "Error: Method name is not specified\n" +msgstr "Fout: methodenaam is niet opgegeven\n" + +#: gio/gdbus-tool.c:1070 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Fout: methodenaam ‘%s’ is ongeldig\n" + +#: gio/gdbus-tool.c:1148 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Fout bij ontleden van parameter %d van type ‘%s’: %s\n" + +#: gio/gdbus-tool.c:1634 +msgid "Destination name to introspect" +msgstr "Bestemmingsnaam voor introspectie" + +#: gio/gdbus-tool.c:1635 +msgid "Object path to introspect" +msgstr "Objectpad voor introspectie" + +#: gio/gdbus-tool.c:1636 +msgid "Print XML" +msgstr "XML tonen" + +#: gio/gdbus-tool.c:1637 +msgid "Introspect children" +msgstr "" + +#: gio/gdbus-tool.c:1638 +msgid "Only print properties" +msgstr "Alleen eigenschappen tonen" + +# Ugh, anglicisme :( (Wouter Bolsterlee) +#: gio/gdbus-tool.c:1727 +msgid "Introspect a remote object." +msgstr "Een object op afstand introspecteren." + +#: gio/gdbus-tool.c:1933 +msgid "Destination name to monitor" +msgstr "Bestemmingsnaam om te controleren" + +#: gio/gdbus-tool.c:1934 +msgid "Object path to monitor" +msgstr "Te monitoren object-pad" + +#: gio/gdbus-tool.c:1959 +msgid "Monitor a remote object." +msgstr "Een object op afstand monitoren." + +#: gio/gdbus-tool.c:2017 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"Fout: kan geen verbindingen controleren anders dan berichtenbusverbindingen\n" + +#: gio/gdbus-tool.c:2141 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2144 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: gio/gdbus-tool.c:2192 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPTIE…] BUS-NAAM" + +#: gio/gdbus-tool.c:2193 +msgid "Wait for a bus name to appear." +msgstr "Wacht tot er een busnaam verschijnt." + +#: gio/gdbus-tool.c:2269 +#, fuzzy +#| msgid "Error: Destination is not specified\n" +msgid "Error: A service to activate for must be specified.\n" +msgstr "Fout: bestemming is niet opgegeven\n" + +#: gio/gdbus-tool.c:2274 +#, fuzzy +#| msgid "Error: Destination is not specified\n" +msgid "Error: A service to wait for must be specified.\n" +msgstr "Fout: bestemming is niet opgegeven\n" + +#: gio/gdbus-tool.c:2279 +msgid "Error: Too many arguments.\n" +msgstr "Fout: te veel argumenten.\n" + +#: gio/gdbus-tool.c:2287 gio/gdbus-tool.c:2294 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Fout: %s is geen geldige bekende busnaam.\n" + +# naamloos/zonder naam/onbenoemd +#: gio/gdesktopappinfo.c:2071 gio/gdesktopappinfo.c:4877 +msgid "Unnamed" +msgstr "Zonder naam" + +# bureaubladbestand/desktopbestand +#: gio/gdesktopappinfo.c:2481 +msgid "Desktop file didn’t specify Exec field" +msgstr "Bureaubladbestand bevat geen Exec-veld" + +#: gio/gdesktopappinfo.c:2761 +msgid "Unable to find terminal required for application" +msgstr "Kan geen terminalvenster vinden voor het uitvoeren van het programma" + +#: gio/gdesktopappinfo.c:3413 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Kan persoonlijke programmaconfiguratiemap %s niet aanmaken: %s" + +#: gio/gdesktopappinfo.c:3417 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Kan persoonlijke MIME-configuratiemap %s niet aanmaken: %s" + +#: gio/gdesktopappinfo.c:3657 gio/gdesktopappinfo.c:3681 +msgid "Application information lacks an identifier" +msgstr "Toepassingsinformatie bevat geen identificatie" + +#: gio/gdesktopappinfo.c:3915 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Kan bureaubladbestand %s niet aanmaken" + +#: gio/gdesktopappinfo.c:4049 +#, c-format +msgid "Custom definition for %s" +msgstr "Zelfgemaakte definitie voor %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "dit station begrijpt de opdracht ‘uitwerpen’ niet" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" +"dit station begrijpt de opdracht ‘uitwerpen’ of ‘eject_with_operation’ niet" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "dit station kan niet onderzocht worden op de aanwezigheid van media" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "dit station begrijpt de opdracht ‘start’ niet" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "dit station begrijpt de opdracht ‘stop’ niet" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:317 +#: gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "TLS-ondersteuning niet beschikbaar" + +#: gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "DTLS-ondersteuning niet beschikbaar" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Kan versie %d van GEmblem-codering niet verwerken" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Onjuist aantal tokens (%d) in GEmblem-codering" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Kan versie %d van GEmblemedIcon-codering niet verwerken" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Onjuist aantal tokens (%d) in GEmblemedIcon-codering" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblem voor GEmblemedIcon verwacht" + +# niet ondersteund/niet mogelijk +#: gio/gfile.c:1044 gio/gfile.c:1282 gio/gfile.c:1420 gio/gfile.c:1658 +#: gio/gfile.c:1713 gio/gfile.c:1771 gio/gfile.c:1855 gio/gfile.c:1912 +#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3722 gio/gfile.c:3777 +#: gio/gfile.c:4055 gio/gfile.c:4523 gio/gfile.c:4934 gio/gfile.c:5019 +#: gio/gfile.c:5109 gio/gfile.c:5206 gio/gfile.c:5293 gio/gfile.c:5394 +#: gio/gfile.c:8098 gio/gfile.c:8188 gio/gfile.c:8272 +#: gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "De bewerking is niet mogelijk" + +# de koppeling hiervan bestaat niet/het koppelpunt hiervan bestaat niet +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1543 +msgid "Containing mount does not exist" +msgstr "Het koppelpunt hiervan bestaat niet" + +#: gio/gfile.c:2590 gio/glocalfile.c:2428 +msgid "Can’t copy over directory" +msgstr "Kan niet over map kopiëren" + +#: gio/gfile.c:2650 +msgid "Can’t copy directory over directory" +msgstr "Kan map niet over map heen kopiëren" + +# er is al een bestand met die naam? +# Het doelbestand bestaat (al) +# er was ook een msgid: Target file already exists +#: gio/gfile.c:2658 +msgid "Target file exists" +msgstr "Doelbestand bestaat al" + +# map/de map +#: gio/gfile.c:2677 +msgid "Can’t recursively copy directory" +msgstr "Kan map niet recursief kopiëren" + +#: gio/gfile.c:2952 +msgid "Splice not supported" +msgstr "Splice wordt niet ondersteund" + +# openen/lezen +#: gio/gfile.c:2956 gio/gfile.c:3001 +#, c-format +msgid "Error splicing file: %s" +msgstr "Fout bij splicen van bestand: %s" + +# (nog) niet mogelijk/niet ondersteund +#: gio/gfile.c:3117 +#, fuzzy +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Verplaatsen tussen aankoppelpunten is niet mogelijk" + +#: gio/gfile.c:3121 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopiëren (reflink/klonen) wordt niet ondersteund of is ongeldig" + +# (nog) niet mogelijk/niet ondersteund +#: gio/gfile.c:3126 +#, fuzzy +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Verplaatsen tussen aankoppelpunten is niet mogelijk" + +#: gio/gfile.c:3190 +msgid "Can’t copy special file" +msgstr "Kan speciaal bestand niet kopiëren" + +#: gio/gfile.c:4003 +msgid "Invalid symlink value given" +msgstr "Ongeldige symbolische verwijzing gegeven" + +#: gio/gfile.c:4013 glib/gfileutils.c:2172 +msgid "Symbolic links not supported" +msgstr "Symbolische verwijzingen zijn niet mogelijk" + +# wordt hier niet ondersteund +# (dus bijv. op een aangekoppelde externe opslag?) +#: gio/gfile.c:4164 +msgid "Trash not supported" +msgstr "Prullenbak wordt ondersteund" + +# Een bestandsnaam mag het teken / niet bevatten +#: gio/gfile.c:4276 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Bestandsnamen kunnen geen ‘%c’ bevatten" + +#: gio/gfile.c:6757 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "volume begrijpt de opdracht ‘aankoppelen’ niet" + +#: gio/gfile.c:6868 gio/gfile.c:6914 +msgid "No application is registered as handling this file" +msgstr "Er is geen programma toegewezen om dit bestand te openen" + +# opsomming/teller +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Teller is gesloten" + +# hmm +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Bestandsteller bevat een lopende bewerking" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Bestandsteller is al gesloten" + +#: gio/gfileicon.c:236 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Kan versie %d van GFileIcon-codering niet verwerken" + +#: gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Ongeldige invoergegevens voor GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Gegevensstroom ondersteunt query_info niet" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Zoeken binnen gegevensstroom niet mogelijk" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Afkappen is niet toegestaan op een invoerdatastroom" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Afkappen wordt niet ondersteund op een gegevensstroom" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:595 +#: glib/gconvert.c:1777 +msgid "Invalid hostname" +msgstr "Ongeldige hostnaam" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Verkeerd HTTP-proxyantwoord" + +# opsomming/teller +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP-proxyverbinding niet toegestaan" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP-proxyaanmeldingscontrole mislukt" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP-proxyaanmeldingscontrole vereist" + +# opsomming/teller +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP-proxyverbinding mislukt: %i" + +#: gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "De HTTP-proxyserver heeft de verbinding onverwacht beëindigd." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Verkeerd aantal tokens (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Geen type voor klassenaam %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Type %s implementeert de GIcon-interface niet" + +# Uhhh? (Wouter Bolsterlee) +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Type %s is niet ‘classed’" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Onjuist versienummer: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Type %s implementeert from_tokens() op de GIcon-interface niet" + +#: gio/gicon.c:469 +#, fuzzy +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Kan de opgegeven versie in de pictogram-codering niet verwerken" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Geen adres opgegeven" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Lengte %u is te lang voor een adres" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Kon ‘%s’ niet ontleden als IP-adresmasker" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:220 +msgid "Not enough space for socket address" +msgstr "Niet genoeg ruimte voor socket-adres" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Niet ondersteund socket-adres" + +# huh? +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Invoerdatastroom begrijpt de opdracht ‘lezen’ niet" + +# Vrij vertaald (Wouter Bolsterlee) +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Gegevensstroom is nog bezig" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopiëren met bestand" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Bestanden meenemen bij verplaatsen" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "‘version’ verwacht geen argumenten" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:864 +msgid "Usage:" +msgstr "Gebruik:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Versie-informatie tonen en afsluiten." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Opdrachten:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Een of meerdere bestanden kopiëren" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "" + +#: gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "" + +#: gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "" + +#: gio/gio-tool.c:234 +msgid "Create directories" +msgstr "Mappen aanmaken" + +#: gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "" + +#: gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "" + +#: gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "Eén of meerdere bestanden verplaatsen" + +#: gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "" + +#: gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "Een bestand hernoemen" + +#: gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "Eén of meerdere bestanden verwijderen" + +#: gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "" + +#: gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "" + +#: gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "" + +#: gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: gio/gio-tool.c:246 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Fout bij schrijven naar stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:333 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCATIE" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:364 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 +msgid "No locations given" +msgstr "Geen locaties opgegeven" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Geen doelmap" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Voortgang tonen" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Vragen voor overschrijven" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Alle attributen behouden" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Reservekopie maken van bestaande bestemmingsbestanden" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Symbolische verwijzingen nooit volgen" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "BRON" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DOEL" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopieer één of meerdere bestanden van BRON naar DOEL." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Doel %s is geen map" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: ‘%s’ overschrijven? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Beschrijfbare attributen tonen" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Bestandssysteeminformatie verkrijgen" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "De attributen om te verkrijgen" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTEN" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Symbolische verwijzingen niet volgen" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "attributen:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "weergavenaam: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "bewerkersnaam: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "naam: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "type: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "grootte: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "verborgen\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "lokaal pad: %s\n" + +#: gio/gio-tool-info.c:199 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:279 +msgid "Settable attributes:\n" +msgstr "Instelbare attributen:\n" + +#: gio/gio-tool-info.c:303 +msgid "Writable attribute namespaces:\n" +msgstr "Schrijfbare attribuutnaamruimten:\n" + +#: gio/gio-tool-info.c:338 +msgid "Show information about locations." +msgstr "Informatie tonen over locaties." + +#: gio/gio-tool-info.c:340 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Verborgen bestanden tonen" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Weergavenamen weergeven" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Volledige URI’s tonen" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "HANDLER" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Geregistreerde toepassingen:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Geen geregistreerde toepassingen\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aanbevolen toepassingen:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Geen aanbevolen toepassingen\n" + +#: gio/gio-tool-mime.c:162 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "Lezen uit bestand ‘%s’ is mislukt: %s" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" + +#: gio/gio-tool-mkdir.c:31 +#, fuzzy +#| msgid "Can't open directory" +msgid "Create parent directories" +msgstr "Kan map niet openen" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Mappen aanmaken." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Aankoppelen als aankoppelbaar" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Volume aankoppelen met apparaatsbestand, of een andere identifier" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Ontkoppelen" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Uitwerpen" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Schijf stoppen met apparaatsbestand" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "APPARAAT" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Lijst" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Gebeurtenissen observeren" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Extra informatie tonen" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "TCRYPT-verborgen volume aankoppelen" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "TCRYPT-systeemvolume aankoppelen" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonieme toegang geweigerd" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Geen schijf voor apparaatsbestand" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Geen volume voor gegeven ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Koppel de locaties aan of los." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Doel %s is geen map" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Verwijder de gegeven bestanden." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAAM" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Hernoem een bestand." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Ontbrekend argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Te veel parameters" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Hernoemen voltooid. Nieuwe URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Enkel aanmaken als het nog niet bestaat" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Toevoegen aan einde van bestand" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Fout bij het lezen van standaardinvoer" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag niet beschikbaar\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Geen bestemming gegeven" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATTRIBUUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "WAARDE" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "" + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Locatie niet opgegeven" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Attribuut niet opgegeven" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Waarde niet opgegeven" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Ongeldig attribuuttype ‘%s’" + +#: gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "Prullenbak legen" + +#: gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "Verplaats bestanden of mappen naar de prullenbak." + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Symbolische verwijzingen en (snel)koppelingen volgen" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> is niet toegestaan binnen <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> is niet toegestaan op het hoogste niveau" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Bestand %s komt meerdere keren voor in de bron" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "‘%s’ kon niet gevonden worden in de bronmap" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "‘%s’ kon niet gevonden worden in de huidige map" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Onbekende verwerkingsoptie ‘%s’" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Fout bij lezen van bestand %s: %s" + +# openen/lezen +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Fout bij comprimeren van bestand: %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "er mag geen tekst staan binnen <%s>" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Programmaversie tonen en afsluiten" + +#: gio/glib-compile-resources.c:738 +msgid "Name of the output file" +msgstr "Naam van uitvoerbestand" + +#: gio/glib-compile-resources.c:739 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "MAP" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "Bronheader genereren" + +#: gio/glib-compile-resources.c:742 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "Lijst met afhankelijkheden genereren" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:746 +msgid "Don’t automatically create and register resource" +msgstr "" + +#: gio/glib-compile-resources.c:747 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "U dient exact één bestandsnaam op te geven\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Ongeldige numerieke waarde" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " reeds opgegeven" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' reeds opgegeven" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr "" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "l10n-category niet ondersteund: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n gevraagd, maar geen gettext-domein gegeven" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "vertaalcontext gegeven voor waarde zonder ingeschakelde l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Ontleden van -waarde van type ‘%s’ mislukt: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " reeds opgegeven voor deze sleutel" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " reeds opgegeven" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " reeds opgegeven voor deze sleutel" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" gegeven maar was reeds opgegeven" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " reeds opgegeven" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " moet minstens één bevatten" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Lege namen zijn niet toegestaan" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Ongeldige naam ‘%s’: namen moet met een kleine letter beginnen" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Ongeldige naam ‘%s’: ongeldig teken ‘%c’; enkel kleine letters, cijfers en " +"streepjes (‘-’) zijn toegestaan" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Ongeldige naam ‘%s’: twee opeenvolgende streepjes (‘--’) zijn niet toegestaan" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Ongeldige naam ‘%s’: het laatste teken mag geen streepje zijn (‘-’)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Ongeldige naam ‘%s’: maximale lengte is 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " reeds opgegeven" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Kan geen sleutels aan een ‘list-of’-schema toevoegen" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " reeds opgegeven" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (nog) niet bepaald." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Ongeldige GVariant-tekenreeks ‘%s’" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Geen om te overschrijven" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " reeds opgegeven" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " reeds opgegeven" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Kan geen lijst van een schema met een pad zijn" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Kan geen schema uitbreiden met een pad" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Het pad van een lijst moet eindigen met ‘:/’" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> reeds opgegeven" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Slechts één element <%s> toegestaan binnen <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> is niet toegestaan op het hoogste niveau" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Tekst kan niet in <%s> voorkomen" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Dit volledige bestand is genegeerd." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Dit bestand wordt genegeerd." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Waar het bestand ‘gschemas.compiled’ opgeslagen wordt" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Afbreken bij een fout in een schema" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Het bestand ‘gschema.compiled’ niet schrijven" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "U dient exact één mapnaam op te geven" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Geen schemabestanden gevonden: geen actie uitgevoerd." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Geen schemabestanden gevonden: bestaand uitvoerbestand verwijderd." + +#: gio/glocalfile.c:546 gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "Ongeldige bestandsnaam: %s" + +#: gio/glocalfile.c:1013 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Fout bij het ophalen van informatie over bestandssysteem voor %s: %s" + +# de koppeling hiervan bestaat niet/het koppelpunt hiervan bestaat niet +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1152 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Het koppelpunt van bestand %s is niet gevonden" + +#: gio/glocalfile.c:1175 +msgid "Can’t rename root directory" +msgstr "Kan de root-map niet hernoemen" + +#: gio/glocalfile.c:1193 gio/glocalfile.c:1216 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Fout bij hernoemen van bestand %s: %s" + +#: gio/glocalfile.c:1200 +msgid "Can’t rename file, filename already exists" +msgstr "Kan bestand niet hernoemen; bestandsnaam reeds in gebruik" + +# ongeldige naam voor bestand/ongeldige bestandsnaam +#: gio/glocalfile.c:1213 gio/glocalfile.c:2322 gio/glocalfile.c:2350 +#: gio/glocalfile.c:2489 gio/glocalfileoutputstream.c:647 +msgid "Invalid filename" +msgstr "Ongeldige bestandsnaam" + +# lezen/openen +#: gio/glocalfile.c:1381 gio/glocalfile.c:1396 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Fout bij het openen van bestand %s: %s" + +# volledig verwijderen/definitief verwijderen/verwijderen +#: gio/glocalfile.c:1521 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Fout bij het verwijderen van bestand %s: %s" + +# naar prullenbak verplaatsen/verwijderen +#: gio/glocalfile.c:1963 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Fout bij het verplaatsen naar de prullenbak van bestand %s: %s" + +#: gio/glocalfile.c:2004 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Kan de prullenbakmap %s niet aanmaken: %s" + +#: gio/glocalfile.c:2025 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Kan de bovenliggende map voor de prullenbak %s niet vinden" + +# (nog) niet mogelijk/niet ondersteund +#: gio/glocalfile.c:2034 +#, fuzzy, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Verplaatsen tussen aankoppelpunten is niet mogelijk" + +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 +#, c-format +msgid "Unable to find or create trash directory for %s" +msgstr "Kan prullenbakmap voor %s niet vinden of aanmaken" + +#: gio/glocalfile.c:2173 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Kan prullenbak-informatiebestand voor %s niet aanmaken: %s" + +#: gio/glocalfile.c:2233 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" + +#: gio/glocalfile.c:2237 gio/glocalfile.c:2293 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Kan het bestand %s niet naar de prullenbak verplaatsen: %s" + +#: gio/glocalfile.c:2299 +#, c-format +msgid "Unable to trash file %s" +msgstr "Kan het bestand %s niet naar de prullenbak verplaatsen" + +#: gio/glocalfile.c:2325 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Fout bij het aanmaken van map %s: %s" + +#: gio/glocalfile.c:2354 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Bestandssysteem ondersteunt geen symbolische verwijzingen" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Fout bij het maken van symbolische verwijzing %s: %s" + +#: gio/glocalfile.c:2400 gio/glocalfile.c:2435 gio/glocalfile.c:2492 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Fout bij het verplaatsen van bestand %s: %s" + +#: gio/glocalfile.c:2423 +msgid "Can’t move directory over directory" +msgstr "Kan map niet over andere map heen verplaatsen" + +#: gio/glocalfile.c:2449 gio/glocalfileoutputstream.c:1031 +#: gio/glocalfileoutputstream.c:1045 gio/glocalfileoutputstream.c:1060 +#: gio/glocalfileoutputstream.c:1077 gio/glocalfileoutputstream.c:1091 +msgid "Backup file creation failed" +msgstr "Aanmaken van backupbestand is mislukt" + +#: gio/glocalfile.c:2468 +#, c-format +msgid "Error removing target file: %s" +msgstr "Fout bij het verwijderen doelbestand: %s" + +# (nog) niet mogelijk/niet ondersteund +#: gio/glocalfile.c:2482 +msgid "Move between mounts not supported" +msgstr "Verplaatsen tussen aankoppelpunten is niet mogelijk" + +#: gio/glocalfile.c:2673 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Kon het schijfgebruik van %s niet verkrijgen: %s" + +# technotalk +#: gio/glocalfileinfo.c:760 +msgid "Attribute value must be non-NULL" +msgstr "Attribuutwaarde moet niet-NULL zijn" + +#: gio/glocalfileinfo.c:767 +msgid "Invalid attribute type (string expected)" +msgstr "Ongeldig attribuuttype (hoort een tekenreeks te zijn)" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid extended attribute name" +msgstr "Ongeldige uitgebreide attribuutnaam" + +#: gio/glocalfileinfo.c:814 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Fout bij het instellen van uitgebreid attribuut ‘%s’: %s" + +#: gio/glocalfileinfo.c:1650 +msgid " (invalid encoding)" +msgstr " (ongeldige codering)" + +# lezen/openen +#: gio/glocalfileinfo.c:1814 gio/glocalfileoutputstream.c:909 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Fout bij het verkrijgen van informatie over het bestand ‘%s’: %s" + +#: gio/glocalfileinfo.c:2084 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Fout bij het verkrijgen van informatie over het bestanddescriptor %s" + +#: gio/glocalfileinfo.c:2129 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ongeldig attribuuttype (hoort een uint32 te zijn)" + +#: gio/glocalfileinfo.c:2147 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ongeldig attribuuttype (hoort een uint64 te zijn)" + +#: gio/glocalfileinfo.c:2166 gio/glocalfileinfo.c:2185 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ongeldig attribuuttype (hoort een byte-tekenreeks te zijn)" + +#: gio/glocalfileinfo.c:2232 +msgid "Cannot set permissions on symlinks" +msgstr "Kan geen toegangsrechten instellen voor symbolische verwijzing: %s" + +#: gio/glocalfileinfo.c:2248 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Fout bij instellen toegangsrechten: %s" + +#: gio/glocalfileinfo.c:2299 +#, c-format +msgid "Error setting owner: %s" +msgstr "Fout bij instellen eigenaar: %s" + +# technotalk +# symlink/symbolische verwijzing +#: gio/glocalfileinfo.c:2322 +msgid "symlink must be non-NULL" +msgstr "symbolische verwijzing moet niet-NULL zijn" + +#: gio/glocalfileinfo.c:2332 gio/glocalfileinfo.c:2351 +#: gio/glocalfileinfo.c:2362 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Fout bij instellen symbolische verwijzing: %s" + +#: gio/glocalfileinfo.c:2341 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Fout bij instellen symbolische verwijzing: bestand is geen symbolische " +"verwijzing" + +#: gio/glocalfileinfo.c:2413 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2422 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2432 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2443 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2507 +#, fuzzy, c-format +#| msgid "Value “%s†cannot be interpreted as a number." +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "De waarde ‘%s’ kan niet geïnterpreteerd worden als een getal." + +#: gio/glocalfileinfo.c:2526 +#, fuzzy, c-format +#| msgid "Value “%s†cannot be interpreted as a number." +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "De waarde ‘%s’ kan niet geïnterpreteerd worden als een getal." + +# lezen/openen +#: gio/glocalfileinfo.c:2539 +#, fuzzy, c-format +#| msgid "Error when getting information for file “%sâ€: %s" +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Fout bij het verkrijgen van informatie over het bestand ‘%s’: %s" + +#: gio/glocalfileinfo.c:2640 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" + +# technotalk +#: gio/glocalfileinfo.c:2663 +msgid "SELinux context must be non-NULL" +msgstr "SELinux-context moet niet-NULL zijn" + +#: gio/glocalfileinfo.c:2678 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Fout bij instellen SELinux-context: %s" + +# geactiveerd/aangezet +# systeem/computer +#: gio/glocalfileinfo.c:2685 +msgid "SELinux is not enabled on this system" +msgstr "SELinux is niet geactiveerd op dit systeem" + +#: gio/glocalfileinfo.c:2777 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Instellen van attribuut %s is niet mogelijk" + +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:792 +#, c-format +msgid "Error reading from file: %s" +msgstr "Fout bij het lezen van bestand: %s" + +#: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 +#: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 +#: gio/glocalfileoutputstream.c:554 gio/glocalfileoutputstream.c:1109 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Fout bij het doorzoeken van bestand: %s" + +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:344 +#: gio/glocalfileoutputstream.c:438 +#, c-format +msgid "Error closing file: %s" +msgstr "Fout bij het sluiten van bestand: %s" + +#: gio/glocalfilemonitor.c:865 +msgid "Unable to find default local file monitor type" +msgstr "Kon de standaard ‘file monitor type’ niet vinden" + +#: gio/glocalfileoutputstream.c:209 gio/glocalfileoutputstream.c:287 +#: gio/glocalfileoutputstream.c:324 gio/glocalfileoutputstream.c:813 +#, c-format +msgid "Error writing to file: %s" +msgstr "Fout bij het schrijven naar bestand: %s" + +#: gio/glocalfileoutputstream.c:371 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Fout bij verwijderen van oude verwijzing naar reservekopie: %s" + +#: gio/glocalfileoutputstream.c:385 gio/glocalfileoutputstream.c:398 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Fout bij het aanmaken van reservekopie: %s" + +#: gio/glocalfileoutputstream.c:416 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Fout bij het hernoemen van tijdelijk bestand: %s" + +#: gio/glocalfileoutputstream.c:600 gio/glocalfileoutputstream.c:1160 +#, c-format +msgid "Error truncating file: %s" +msgstr "Fout bij het afkappen bestand: %s" + +# lezen/openen +#: gio/glocalfileoutputstream.c:653 gio/glocalfileoutputstream.c:891 +#: gio/glocalfileoutputstream.c:1141 gio/gsubprocess.c:380 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Fout bij het openen van bestand ‘%s’: %s" + +#: gio/glocalfileoutputstream.c:922 +msgid "Target file is a directory" +msgstr "Doelbestand is geen map" + +#: gio/glocalfileoutputstream.c:927 +msgid "Target file is not a regular file" +msgstr "Doelbestand is geen gewoon bestand" + +#: gio/glocalfileoutputstream.c:939 +msgid "The file was externally modified" +msgstr "Het bestand is door een ander programma gewijzigd" + +#: gio/glocalfileoutputstream.c:1125 +#, c-format +msgid "Error removing old file: %s" +msgstr "Fout bij verwijderen van oude bestand: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Ongeldig GSeekType geleverd" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Ongeldige zoekopdracht" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Kan GMemoryInputStream niet afkappen" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Wijzigen van geheugenruimte uitvoerdatastroom is niet mogelijk" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Wijzigen van geheugenruimte uitvoerdatastroom is mislukt" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"De benodigde geheugenruimte om de schrijfactie te verwerken is groter dan de " +"beschikbare adresruimte" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "‘Seek’-aanvraag ligt voor het beginpunt van de stroom" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "‘Seek’-aanvraag ligt na het eindpunt van de stroom" + +# ontkoppelen is op deze koppeling niet mogelijk/niet geimplementeerd +# ontkoppelen is bij deze koppeling/bij dit aangekoppelde object +# dit aangekoppelde object kan niet worden ontkoppeld/losgemaakt/vrijgemaakt +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "mount heeft geen ondersteuning voor ‘unmount’ (ontkoppelen)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount heeft geen ondersteuning voor ‘eject’ (uitwerpen)" + +# ontkoppelen is op deze koppeling niet mogelijk/niet geimplementeerd +# ontkoppelen is bij deze koppeling/bij dit aangekoppelde object +# dit aangekoppelde object kan niet worden ontkoppeld/losgemaakt/vrijgemaakt +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"mount heeft geen ondersteuning voor ‘unmount’ of ‘unmount_with_operation’" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "mount heeft geen ondersteuning voor ‘eject’ of ‘eject_with_operation’" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "mount heeft geen ondersteuning voor ‘remount’ (opnieuw koppelen)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "mount heeft geen ondersteuning voor raden van inhoudstype" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" +"mount heeft geen ondersteuning voor raden inhoudstype op synchrone wijze" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Hostnaam ‘%s’ bevat ‘[’ maar geen ‘]’" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Netwerk onbereikbaar" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Host onbereikbaar" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Kon geen netwerkstatus verkrijgen: " + +#: gio/gnetworkmonitornm.c:348 +#, c-format +msgid "NetworkManager not running" +msgstr "Netwerkbeheer draait niet" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "Geïnstalleerde versie van Netwerkbeheer is te oud" + +# uitvoerdatastroom begrijpt de opdracht 'scrijven' niet +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Schrijven wordt niet ondersteund door de uitvoerdatastroom" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Brongegevensstroom is al gesloten" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Fout bij oplossen van ‘%s’: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:613 +#, c-format +msgid "%s not implemented" +msgstr "%s niet geïmplementeerd" + +# ongeldige naam voor bestand/ongeldige bestandsnaam +#: gio/gresolver.c:981 gio/gresolver.c:1033 +msgid "Invalid domain" +msgstr "Ongeldig domein" + +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "De bron op ‘%s’ bestaat niet" + +#: gio/gresource.c:830 +#, fuzzy, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Doelbestand is geen map" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "De bron op ‘%s’ is geen map" + +# huh? +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Invoerdatastroom ondersteunt ‘seek’ (lezen) niet" + +#: gio/gresource-tool.c:499 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: gio/gresource-tool.c:505 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: gio/gresource-tool.c:508 gio/gresource-tool.c:518 +msgid "FILE [PATH]" +msgstr "BESTAND [PAD]" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 gio/gresource-tool.c:526 +msgid "SECTION" +msgstr "SECTIE" + +#: gio/gresource-tool.c:514 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: gio/gresource-tool.c:524 +msgid "Extract a resource file to stdout" +msgstr "Bronbestand uitpakken naar stdout" + +#: gio/gresource-tool.c:525 +msgid "FILE PATH" +msgstr "BESTANDSPAD" + +#: gio/gresource-tool.c:539 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gresource-tool.c:553 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Gebruik:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:560 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: gio/gresource-tool.c:564 gio/gsettings-tool.c:701 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: gio/gresource-tool.c:570 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: gio/gresource-tool.c:573 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: gio/gresource-tool.c:577 +msgid "[PATH]" +msgstr "[PAD]" + +#: gio/gresource-tool.c:579 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: gio/gresource-tool.c:580 +msgid "PATH" +msgstr "PAD" + +#: gio/gresource-tool.c:582 +msgid " PATH A resource path\n" +msgstr " PAD Een bronpad\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:906 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Geen schema ‘%s’\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Schema ‘%s’ is niet verplaatsbaar (pad mag niet opgegeven worden)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schema ‘%s’ is verplaatsbaar (pad moet opgegeven worden)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Leeg pad gegeven.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Pad moet beginnen met een schuine streep (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Pad moet eindigen met een schuine streep (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Pad mag geen twee opeenvolgende schuine strepen bevatten (//)\n" + +#: gio/gsettings-tool.c:536 +msgid "The provided value is outside of the valid range\n" +msgstr "De opgegeven waarde valt buiten het toegestane bereik\n" + +#: gio/gsettings-tool.c:543 +msgid "The key is not writable\n" +msgstr "De sleutel is niet schrijfbaar\n" + +#: gio/gsettings-tool.c:579 +msgid "List the installed (non-relocatable) schemas" +msgstr "Geïnstalleerde (onverplaatsbare) schema’s oplijsten" + +#: gio/gsettings-tool.c:585 +msgid "List the installed relocatable schemas" +msgstr "Geïnstalleerde verplaatsbare schema’s oplijsten" + +#: gio/gsettings-tool.c:591 +msgid "List the keys in SCHEMA" +msgstr "Sleutels in SCHEMA oplijsten" + +#: gio/gsettings-tool.c:592 gio/gsettings-tool.c:598 gio/gsettings-tool.c:641 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PAD]" + +#: gio/gsettings-tool.c:597 +msgid "List the children of SCHEMA" +msgstr "Kinderen van SCHEMA oplijsten" + +#: gio/gsettings-tool.c:603 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Sleutels en waarden recursief oplijsten\n" +"Indien er geen SCHEMA gegeven is, alle sleutels oplijsten\n" + +#: gio/gsettings-tool.c:605 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PAD]]" + +#: gio/gsettings-tool.c:610 +msgid "Get the value of KEY" +msgstr "De waarde van KEY opvragen" + +#: gio/gsettings-tool.c:611 gio/gsettings-tool.c:617 gio/gsettings-tool.c:623 +#: gio/gsettings-tool.c:635 gio/gsettings-tool.c:647 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PAD] KEY" + +#: gio/gsettings-tool.c:616 +msgid "Query the range of valid values for KEY" +msgstr "Bereik van geldige waarden voor SLEUTEL opvragen" + +#: gio/gsettings-tool.c:622 +msgid "Query the description for KEY" +msgstr "Beschrijving voor SLEUTEL opvragen" + +#: gio/gsettings-tool.c:628 +msgid "Set the value of KEY to VALUE" +msgstr "Waarde van SLEUTEL instellen op WAARDE" + +#: gio/gsettings-tool.c:629 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PAD] SLEUTEL WAARDE" + +#: gio/gsettings-tool.c:634 +msgid "Reset KEY to its default value" +msgstr "SLEUTEL instellen op standaardwaarde" + +#: gio/gsettings-tool.c:640 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Alle sleutels in SCHEMA instellen op standaardwaarden" + +#: gio/gsettings-tool.c:646 +msgid "Check if KEY is writable" +msgstr "Controleren of SLEUTEL schrijfbaar is" + +#: gio/gsettings-tool.c:652 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"SLEUTEL controleren op wijzigingen.\n" +"Indien er geen SLEUTEL gegeven is, alle sleutels in SCHEMA controleren.\n" +"Gebruik ^C om controle te stoppen.\n" + +#: gio/gsettings-tool.c:655 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PAD] [SLEUTEL]" + +#: gio/gsettings-tool.c:667 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:691 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: gio/gsettings-tool.c:697 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMAMAP Een map om te zoeken naar bijkomende schema’s\n" + +#: gio/gsettings-tool.c:705 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA De naam van het schema\n" +" PATH Het pad, voor verplaatsbare schema’s\n" + +#: gio/gsettings-tool.c:710 +msgid " KEY The (optional) key within the schema\n" +msgstr " SLEUTEL De (optionele) sleutel in het schema\n" + +#: gio/gsettings-tool.c:714 +msgid " KEY The key within the schema\n" +msgstr " SLEUTEL De sleutel in het schema\n" + +#: gio/gsettings-tool.c:718 +msgid " VALUE The value to set\n" +msgstr " WAARDE De in te stellen waarde\n" + +# conversieprogramma/omzet-programma/omzetter +# kon converteerder van %s naar %s niet openen +# Openen van converteerder van '%s' naar '%s' mislukt +# Openen van het programma voor het omzetten van s naar s is mislukt +# (tekenreeks komt verderop nog een keer voor) +#: gio/gsettings-tool.c:773 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Kon schema’s niet laden uit %s: %s\n" + +#: gio/gsettings-tool.c:785 +msgid "No schemas installed\n" +msgstr "Geen schema’s geïnstalleerd\n" + +#: gio/gsettings-tool.c:864 +msgid "Empty schema name given\n" +msgstr "Lege schemanaam gegeven\n" + +#: gio/gsettings-tool.c:919 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Geen sleutel ‘%s’\n" + +#: gio/gsocket.c:418 +msgid "Invalid socket, not initialized" +msgstr "Ongeldige socket, niet geïnitialiseerd" + +#: gio/gsocket.c:425 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Ongeldige socket, initialisatie mislukt door: %s" + +# bronstroom/datastroom van de bron +#: gio/gsocket.c:433 +msgid "Socket is already closed" +msgstr "Socket is al gesloten" + +#: gio/gsocket.c:448 gio/gsocket.c:3182 gio/gsocket.c:4399 gio/gsocket.c:4457 +msgid "Socket I/O timed out" +msgstr "Time-out bij socket I/O" + +#: gio/gsocket.c:583 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "GSocket maken van fd: %s" + +#: gio/gsocket.c:612 gio/gsocket.c:666 gio/gsocket.c:673 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Kan socket niet aanmaken: %s" + +#: gio/gsocket.c:666 +msgid "Unknown family was specified" +msgstr "Onbekende familie opgegeven" + +#: gio/gsocket.c:673 +msgid "Unknown protocol was specified" +msgstr "Onbekend protocol opgegeven" + +#: gio/gsocket.c:1164 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: gio/gsocket.c:1181 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: gio/gsocket.c:1988 +#, c-format +msgid "could not get local address: %s" +msgstr "kon lokaal adres niet verkrijgen: %s" + +#: gio/gsocket.c:2034 +#, c-format +msgid "could not get remote address: %s" +msgstr "kon adres op afstand niet verkrijgen: %s" + +#: gio/gsocket.c:2100 +#, c-format +msgid "could not listen: %s" +msgstr "kon niet luisteren: %s" + +#: gio/gsocket.c:2204 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Fout bij het koppelen aan adres %s: %s" + +#: gio/gsocket.c:2380 gio/gsocket.c:2417 gio/gsocket.c:2527 gio/gsocket.c:2552 +#: gio/gsocket.c:2615 gio/gsocket.c:2673 gio/gsocket.c:2691 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Fout bij toetreden tot multicastgroep: %s" + +#: gio/gsocket.c:2381 gio/gsocket.c:2418 gio/gsocket.c:2528 gio/gsocket.c:2553 +#: gio/gsocket.c:2616 gio/gsocket.c:2674 gio/gsocket.c:2692 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Fout bij verlaten van multicastgroep: %s" + +#: gio/gsocket.c:2382 +msgid "No support for source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2529 +msgid "Unsupported socket family" +msgstr "Niet-ondersteunde socketfamilie" + +#: gio/gsocket.c:2554 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2578 +#, c-format +msgid "Interface name too long" +msgstr "Interfacenaam is te lang" + +#: gio/gsocket.c:2591 gio/gsocket.c:2641 +#, c-format +msgid "Interface not found: %s" +msgstr "Interface niet gevonden: %s" + +#: gio/gsocket.c:2617 +msgid "No support for IPv4 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2675 +msgid "No support for IPv6 source-specific multicast" +msgstr "" + +#: gio/gsocket.c:2884 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Fout bij accepteren van verbinding: %s" + +#: gio/gsocket.c:3010 +msgid "Connection in progress" +msgstr "Verbinding bezig" + +#: gio/gsocket.c:3061 +msgid "Unable to get pending error: " +msgstr "Kan lopende fout niet verkrijgen: " + +# volledig verwijderen/definitief verwijderen/verwijderen +#: gio/gsocket.c:3247 +#, c-format +msgid "Error receiving data: %s" +msgstr "Fout bij ontvangen van gegevens: %s" + +# openen/lezen +#: gio/gsocket.c:3444 +#, c-format +msgid "Error sending data: %s" +msgstr "Fout bij versturen van gegevens: %s" + +#: gio/gsocket.c:3631 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Kan socket niet afsluiten: %s" + +#: gio/gsocket.c:3712 +#, c-format +msgid "Error closing socket: %s" +msgstr "Fout bij het sluiten van socket: %s" + +#: gio/gsocket.c:4392 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +# openen/lezen +#: gio/gsocket.c:4770 gio/gsocket.c:4772 gio/gsocket.c:4919 gio/gsocket.c:5004 +#: gio/gsocket.c:5182 gio/gsocket.c:5222 gio/gsocket.c:5224 +#, c-format +msgid "Error sending message: %s" +msgstr "Fout bij versturen van bericht: %s" + +#: gio/gsocket.c:4946 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage wordt niet ondersteund op windows" + +# volledig verwijderen/definitief verwijderen/verwijderen +#: gio/gsocket.c:5415 gio/gsocket.c:5488 gio/gsocket.c:5714 +#, c-format +msgid "Error receiving message: %s" +msgstr "Fout bij ontvangen van bericht: %s" + +#: gio/gsocket.c:5995 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to read socket credentials: %s" +msgstr "Kan socket niet aanmaken: %s" + +#: gio/gsocket.c:6004 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: gio/gsocketclient.c:182 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +# Openen van converteerder van '%s' naar '%s' mislukt: %s +#: gio/gsocketclient.c:196 +#, c-format +msgid "Could not connect to %s: " +msgstr "Kon niet verbinden met %s: " + +#: gio/gsocketclient.c:198 +msgid "Could not connect: " +msgstr "Kon niet verbinden: " + +#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1866 +msgid "Unknown error on connect" +msgstr "Onbekende fout bij verbinden" + +#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1668 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Proxyen via een verbinding anders dan TCP wordt niet ondersteund." + +#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proxy-protocol ‘%s’ wordt niet ondersteund." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Listener is al gesloten" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Toegevoegde socket is gesloten" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 ondersteunt IPv6-adres ‘%s’ niet" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Gebruikersnaam is te lang voor het SOCKSv4-protocol" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Hostnaam ‘%s’ is te lang voor het SOCKSv4-protocol" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "De server is geen SOCKSv4-proxyserver." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Verbinding via SOCKSv4-server is geweigerd" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:324 gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "De server is geen SOCKSv5-proxyserver." + +#: gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "De SOCKSv5-proxy vereist authenticatie." + +#: gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"De SOCKSv5-proxy vereist een authenticatiemethode die niet door GLib wordt " +"ondersteund." + +#: gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Gebruikersnaam of wachtwoord is te lang voor het SOCKSv5-protocol." + +#: gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5-authenticatie mislukt wegens onjuiste gebruikersnaam of wachtwoord." + +#: gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Hostnaam ‘%s’ is te lang voor het SOCKSv5-protocol" + +#: gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "De SOCKSv5-proxyserver gebruikt een onbekend adrestype." + +#: gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Interne SOCKSv5-proxyserverfout." + +#: gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5-verbinding niet toegestaan door regelset." + +#: gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Host onbereikbaar via SOCKSv5-server." + +#: gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Netwerk onbereikbaar via SOCKSv5-server." + +#: gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Verbinding geweigerd via SOCKSv5-server." + +#: gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5-proxy ondersteunt de ‘connect’-opdracht niet." + +#: gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5-proxy ondersteunt het opgegeven adrestype niet." + +#: gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Onbekende SOCKSv5-proxyfout." + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Kan versie %d van GThemedIcon-codering niet verwerken" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Geen geldige adressen gevonden" + +#: gio/gthreadedresolver.c:334 +#, fuzzy, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Fout bij lezen van bestand ‘%s’: %s" + +#: gio/gthreadedresolver.c:671 gio/gthreadedresolver.c:750 +#: gio/gthreadedresolver.c:848 gio/gthreadedresolver.c:898 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:853 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Kan ‘%s’ tijdelijk niet oplossen" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#: gio/gthreadedresolver.c:968 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Fout bij oplossen van ‘%s’" + +#: gio/gtlscertificate.c:243 +msgid "No PEM-encoded private key found" +msgstr "Geen PEM-gecodeerde privésleutel gevonden" + +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Kan PEM-gecodeerde privésleutel niet ontsleutelen" + +#: gio/gtlscertificate.c:264 +msgid "Could not parse PEM-encoded private key" +msgstr "Kon PEM-gecodeerde privésleutel niet verwerken" + +#: gio/gtlscertificate.c:291 +msgid "No PEM-encoded certificate found" +msgstr "Geen PEM-gecodeerd certificaat gevonden" + +#: gio/gtlscertificate.c:300 +msgid "Could not parse PEM-encoded certificate" +msgstr "Kon PEM-gecodeerd certificaat niet verwerken" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Dit is de laatste kans om uw wachtwoord correct in te voeren voordat u de " +"toegang ontzegd wordt." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Het ingevoerde wachtwoord is onjuist." + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 control-bericht verwacht, maar %d gekregen" +msgstr[1] "1 control-bericht verwacht, maar %d gekregen" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +#, fuzzy +msgid "Unexpected type of ancillary data" +msgstr "Voortijdig einde aan gegevensstroom" + +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Eén fd verwacht, maar %d ontvangen\n" +msgstr[1] "Eén fd verwacht, maar %d ontvangen\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Ongeldige fd ontvangen" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "Fout bij het sturen van gebruikersreferenties: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Fout bij controleren of SO_PASSCRED is ingeschakeld voor de socket: %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Fout bij inschakelen van SO_PASSCRED: %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Een enkele byte werd verwacht voor het lezen van gebruikersreferenties, maar " +"geen enkele byte werd gelezen" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Geen control-bericht, maar %d gekregen" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Fout bij het uitschakelen van SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:362 gio/gunixinputstream.c:383 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Fout bij lezen van bestandsdescriptor: %s" + +#: gio/gunixinputstream.c:416 gio/gunixoutputstream.c:525 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Fout bij sluiten van bestandsdescriptor: %s" + +# hoofdmap van bestandssysteem +#: gio/gunixmounts.c:2709 gio/gunixmounts.c:2762 +msgid "Filesystem root" +msgstr "Hoofdmap van bestandssysteem" + +#: gio/gunixoutputstream.c:362 gio/gunixoutputstream.c:382 +#: gio/gunixoutputstream.c:469 gio/gunixoutputstream.c:489 +#: gio/gunixoutputstream.c:635 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Fout bij schrijven van bestandsdescriptor: %s" + +#: gio/gunixsocketaddress.c:243 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "volume begrijpt de opdracht ‘uitwerpen’ niet" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volume begrijpt de opdracht ‘uitwerpen’ of ‘eject_with_operation’ niet" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Fout bij het lezen van handle: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Fout bij het sluiten van handle: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Fout bij het schrijven naar handle: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Onvoldoende geheugen" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Interne fout: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Meer invoer nodig" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Ongeldige gecomprimeerde gegevens" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adres om op te luisteren" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Adres tonen" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Adres tonen in shell-modus" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Een dbus-service uitvoeren" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Verkeerde argumenten\n" + +#: glib/gbookmarkfile.c:756 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Onverwacht attribuut ‘%s’ voor element ‘%s’" + +# aangetroffen hier mooier dan gevonden +#: glib/gbookmarkfile.c:767 glib/gbookmarkfile.c:847 glib/gbookmarkfile.c:857 +#: glib/gbookmarkfile.c:969 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Attribuut ‘%s’ van element ‘%s’ niet gevonden" + +#: glib/gbookmarkfile.c:1178 glib/gbookmarkfile.c:1243 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1317 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Onverwachte tag ‘%s’, tag ‘%s’ werd verwacht" + +#: glib/gbookmarkfile.c:1203 glib/gbookmarkfile.c:1217 +#: glib/gbookmarkfile.c:1285 glib/gbookmarkfile.c:1331 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Onverwachte tag ‘%s’ binnen ‘%s’" + +#: glib/gbookmarkfile.c:1625 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1831 +msgid "No valid bookmark file found in data dirs" +msgstr "Er is geen geldig bladwijzerbestand gevonden in de datamappen" + +#: glib/gbookmarkfile.c:2032 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Er bestaat al een bladwijzer voor de URI ‘%s’" + +#: glib/gbookmarkfile.c:2078 glib/gbookmarkfile.c:2236 +#: glib/gbookmarkfile.c:2321 glib/gbookmarkfile.c:2401 +#: glib/gbookmarkfile.c:2486 glib/gbookmarkfile.c:2569 +#: glib/gbookmarkfile.c:2647 glib/gbookmarkfile.c:2726 +#: glib/gbookmarkfile.c:2768 glib/gbookmarkfile.c:2865 +#: glib/gbookmarkfile.c:2986 glib/gbookmarkfile.c:3176 +#: glib/gbookmarkfile.c:3252 glib/gbookmarkfile.c:3420 +#: glib/gbookmarkfile.c:3509 glib/gbookmarkfile.c:3598 +#: glib/gbookmarkfile.c:3717 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Geen bladwijzer gevonden voor URI ‘%s’" + +#: glib/gbookmarkfile.c:2410 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Er is geen MIME-type gedefinieerd in de bladwijzer voor URI ‘%s’" + +#: glib/gbookmarkfile.c:2495 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Er is geen privé-vlag gedefinieerd in de bladwijzer voor URI ‘%s’" + +#: glib/gbookmarkfile.c:2874 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Er zijn geen groepen ingesteld in de bladwijzer voor URI ‘%s’" + +#: glib/gbookmarkfile.c:3273 glib/gbookmarkfile.c:3430 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" +"Er is geen programma genaamd ‘%s’ dat een bladwijzer geregistreerd heeft " +"voor ‘%s’" + +#: glib/gbookmarkfile.c:3453 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Exec-regel ‘%s’ kon niet worden verwerkt met URI ‘%s’" + +#: glib/gconvert.c:466 +msgid "Unrepresentable character in conversion input" +msgstr "Teken in conversieinvoer kan niet weergegeven worden" + +#: glib/gconvert.c:493 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "Onvolledige tekenreeks aan het eind van de invoer" + +# wordt hier niet character set ipv codeset bedoeld? +#: glib/gconvert.c:762 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Kan terugval ‘%s’ niet converteren naar codeset ‘%s’" + +#: glib/gconvert.c:934 +msgid "Embedded NUL byte in conversion input" +msgstr "NUL-byte ingebed in conversie-invoer" + +#: glib/gconvert.c:955 +msgid "Embedded NUL byte in conversion output" +msgstr "NUL-byte ingebed in conversie-uitvoer" + +#: glib/gconvert.c:1640 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" +"De URI ‘%s’ is geen absolute URI die gebruik maakt van het schema ‘bestand’" + +#: glib/gconvert.c:1650 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "De lokale bestands-URI ‘%s’ mag het teken ‘#’ niet bevatten" + +#: glib/gconvert.c:1667 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "De URI ‘%s’ is ongeldig" + +#: glib/gconvert.c:1679 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "De hostnaam van de URI ‘%s’ is ongeldig" + +# controle-tekens/ontsnappingstekens/sturingstekens +# betere vertaling? +#: glib/gconvert.c:1695 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "De URI ‘%s’ bevat tekens met een foutief controleteken" + +#: glib/gconvert.c:1767 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Het pad ‘%s’ is geen absoluut pad" + +# bijv. ‘za 3 mrt 2018 22:30:00’ +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:220 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e %b %Y %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:223 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d-%m-%Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:268 +msgctxt "full month name" +msgid "January" +msgstr "januari" + +#: glib/gdatetime.c:270 +msgctxt "full month name" +msgid "February" +msgstr "februari" + +#: glib/gdatetime.c:272 +msgctxt "full month name" +msgid "March" +msgstr "maart" + +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "April" +msgstr "april" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "May" +msgstr "mei" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "June" +msgstr "juni" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "July" +msgstr "juli" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "August" +msgstr "augustus" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "September" +msgstr "september" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "October" +msgstr "oktober" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:322 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:324 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:326 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mrt" + +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "May" +msgstr "mei" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "aug" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "dec" + +#: glib/gdatetime.c:359 +msgctxt "full weekday name" +msgid "Monday" +msgstr "maandag" + +#: glib/gdatetime.c:361 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "dinsdag" + +#: glib/gdatetime.c:363 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "woensdag" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "donderdag" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Friday" +msgstr "vrijdag" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "zaterdag" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "zondag" + +#: glib/gdatetime.c:386 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ma" + +#: glib/gdatetime.c:388 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "di" + +#: glib/gdatetime.c:390 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "wo" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "do" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "vr" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "za" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "zo" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:462 +msgctxt "full month name with day" +msgid "January" +msgstr "januari" + +#: glib/gdatetime.c:464 +msgctxt "full month name with day" +msgid "February" +msgstr "februari" + +#: glib/gdatetime.c:466 +msgctxt "full month name with day" +msgid "March" +msgstr "maart" + +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "April" +msgstr "april" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "May" +msgstr "mei" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "June" +msgstr "juni" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "July" +msgstr "juli" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "August" +msgstr "augustus" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "September" +msgstr "september" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "October" +msgstr "oktober" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:549 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:551 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:553 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mrt" + +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "mei" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "aug" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:588 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:591 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:154 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Fout bij openen van map ‘%s’: %s" + +# Allocatie van %lu bytes om bestand "%s" te lezen is mislukt< +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "" +"Kon geen %lu byte geheugenruimte reserveren om bestand ‘%s’ te lezen" +msgstr[1] "" +"Kon geen %lu bytes geheugenruimte reserveren om bestand ‘%s’ te lezen" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Fout bij lezen van bestand ‘%s’: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Bestand ‘%s’ is te groot" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Lezen uit bestand ‘%s’ is mislukt: %s" + +#: glib/gfileutils.c:898 glib/gfileutils.c:970 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Openen van bestand ‘%s’ is mislukt: %s" + +#: glib/gfileutils.c:910 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Opvragen gegevens van bestand ‘%s’ is mislukt: fstat() is mislukt: %s" + +#: glib/gfileutils.c:940 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Openen van bestand ‘%s’ is mislukt: fdopen() is mislukt: %s" + +#: glib/gfileutils.c:1039 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Hernoemen van bestand ‘%s’ naar ‘%s’ is mislukt: g_rename() is mislukt: %s" + +#: glib/gfileutils.c:1074 glib/gfileutils.c:1592 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Aanmaken van bestand ‘%s’ is mislukt: %s" + +#: glib/gfileutils.c:1101 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Schrijven van bestand ‘%s’ is mislukt: write() is mislukt: %s" + +#: glib/gfileutils.c:1144 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Schrijven van bestand ‘%s’ is mislukt: fsync() is mislukt: %s" + +# bestaand bestand is een beetje dubbelop +#: glib/gfileutils.c:1279 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Bestand ‘%s’ kon niet worden verwijderd: g_unlink() is mislukt: %s" + +#: glib/gfileutils.c:1558 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Sjabloon ‘%s’ is ongeldig, het zou geen ‘%s’ mogen bevatten" + +#: glib/gfileutils.c:1571 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Sjabloon ‘%s’ bevat geen XXXXXX" + +#: glib/gfileutils.c:2129 glib/gfileutils.c:2157 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Lezen van symbolische verwijzing ‘%s’ is mislukt: %s" + +# Openen van converteerder van '%s' naar '%s' mislukt: %s +#: glib/giochannel.c:1396 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Converteerder van ‘%s’ naar ‘%s’ kon niet geopend worden: %s" + +#: glib/giochannel.c:1749 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Een kale (‘raw’) leesoperatie is niet mogelijk in " +"g_io_channel_read_line_string" + +#: glib/giochannel.c:1796 glib/giochannel.c:2054 glib/giochannel.c:2141 +msgid "Leftover unconverted data in read buffer" +msgstr "Restant aan ongeconverteerde data in de leesbuffer" + +#: glib/giochannel.c:1877 glib/giochannel.c:1954 +msgid "Channel terminates in a partial character" +msgstr "Kanaal eindigt in een gedeeltelijk teken" + +#: glib/giochannel.c:1940 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "" +"Een kale (‘raw’) leesoperatie is niet mogelijk in g_io_channel_read_to_end" + +#: glib/gkeyfile.c:789 +msgid "Valid key file could not be found in search dirs" +msgstr "Er kon geen geldig sleutelbestand gevonden worden in de zoekmappen" + +#: glib/gkeyfile.c:826 +msgid "Not a regular file" +msgstr "Geen gewoon bestand" + +#: glib/gkeyfile.c:1275 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Sleutelbestand bevat regel ‘%s’, wat geen sleutelwaarde-paar, groep of " +"opmerking is" + +#: glib/gkeyfile.c:1332 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ongeldige groepsnaam: %s" + +#: glib/gkeyfile.c:1354 +msgid "Key file does not start with a group" +msgstr "Het sleutelbestand start niet met een groep" + +#: glib/gkeyfile.c:1380 +#, c-format +msgid "Invalid key name: %s" +msgstr "Ongeldige sleutelnaam: %s" + +#: glib/gkeyfile.c:1407 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Het sleutelbestand bevat de niet-ondersteunde tekenset ‘%s’" + +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3340 glib/gkeyfile.c:3470 glib/gkeyfile.c:3602 +#: glib/gkeyfile.c:3748 glib/gkeyfile.c:3977 glib/gkeyfile.c:4044 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Het sleutelbestand bevat geen groep ‘%s’" + +#: glib/gkeyfile.c:1778 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Het sleutelbestand bevat geen sleutel ‘%s’ in groep ‘%s’" + +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Het sleutelbestand bevat sleutel ‘%s’ met waarde ‘%s’, wat geen UTF-8 is" + +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Het sleutelbestand bevat sleutel ‘%s’, die een waarde heeft die niet " +"geïnterpreteerd kan worden." + +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Het sleutelbestand bevat sleutel ‘%s’ in groep ‘%s’, die een waarde heeft " +"die niet geïnterpreteerd kan worden." + +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Sleutel ‘%s’ in groep ‘%s’ heeft de waarde ‘%s’ waar %s werd verwacht" + +#: glib/gkeyfile.c:4284 +msgid "Key file contains escape character at end of line" +msgstr "" +"Het sleutelbestand bevat een ontsnappingsteken aan het einde van een regel" + +#: glib/gkeyfile.c:4306 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Het sleutelbestand bevat ongeldige ontsnappingstekens ‘%s’" + +#: glib/gkeyfile.c:4450 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "De waarde ‘%s’ kan niet geïnterpreteerd worden als een getal." + +#: glib/gkeyfile.c:4464 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Het geheel getal ‘%s’ valt buiten het bereik" + +#: glib/gkeyfile.c:4497 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "" +"De waarde ‘%s’ kan niet geïnterpreteerd worden als een getal van het type " +"float." + +#: glib/gkeyfile.c:4536 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "" +"De waarde ‘%s’ kan niet geïnterpreteerd worden als een booleaans waarde." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Ophalen van eigenschappen van bestand ‘%s%s%s%s’ is mislukt: fstat() is " +"mislukt: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Toewijzen van %s%s%s%s is mislukt: mmap() is mislukt: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Openen van bestand ‘%s’ is mislukt: open() is mislukt: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Fout in regel %d teken %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Ongeldige UTF-8-gecodeerde tekst — niet geldig ‘%s’" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "‘%s’ is geen geldige naam" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "‘%s’ is geen geldige naam: ‘%c’" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Fout in regel %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Verwerken van ‘%-.*s’ is mislukt, hetgeen een getal in een tekenreferentie " +"zou moeten zijn (bijvoorbeeld ê) - misschien is het getal te groot" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Tekenreferentie eindigt niet op een puntkomma; waarschijnlijk heeft u een " +"ampersand-teken gebruikt zonder daarmee een entiteit te willen beginnen — " +"gebruik in plaats daarvan &" + +# niet geoorloofd/toegestaan/ongeoorloofd +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Tekenreferentie ‘%-.*s’ staat niet voor een toegestaan teken" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Lege entiteit ‘&;’ gevonden; geldige entiteiten zijn: & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Entiteitnaam ‘%-.*s’ is onbekend" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"De entiteit eindigde niet op een puntkomma; waarschijnlijk heeft u een " +"ampersand-teken gebruikt zonder daarmee een entiteit te willen beginnen — " +"gebruik in plaats daarvan &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Het document moet beginnen met een element (bijv. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"‘%s’ is geen geldig teken na ‘<’; een elementnaam mag er niet mee beginnen" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Onverwacht teken ‘%s’, er werd een ‘>’-teken verwacht om de ledig-element-" +"tag ‘%s’ af te sluiten" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Te veel attributen in element ‘%s’" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Onverwacht teken ‘%s’, er werd een ‘=’ verwacht na de attribuutnaam ‘%s’ van " +"element ‘%s’" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Onverwacht teken ‘%s’, er werd een ‘>’- of een ‘/’-teken verwacht om de " +"start-tag van element ‘%s’ af te sluiten, of eventueel een attribuut; " +"misschien heeft u ongeldige tekens gebruikt in een attribuutnaam" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Onverwacht teken ‘%s’, er werd een ‘\"’-teken verwacht na het ‘=’-teken bij " +"de attribuutwaarde van ‘%s’ in element ‘%s’" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"‘%s’ is geen geldig teken na de elementnaam ‘%s’ in de afluitingstag; het " +"teken dat toegestaan is is ‘>’" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Element ‘%s’ is afgesloten, er is nu geen enkel element open" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Element ‘%s’ is afgesloten, maar op dit moment is element ‘%s’ open" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Het document was leeg of bevatte slechts lege ruimte" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Het document eindigde onverwacht na een openingshaakje ‘<’" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Het document eindigde onverwacht met niet-afgesloten elementen — ‘%s’ is het " +"laatst geopende element" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Het document eindigde onverwacht, er werd een sluithaakje (‘>’) verwacht " +"voor de tag <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Het document eindigde onverwacht in een elementnaam" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Het document eindigde onverwacht in een attribuutnaam" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Het document eindigde onverwacht in een element-openingstag." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Het document eindigde onverwacht na een ‘=’-teken dat op een attribuutnaam " +"volgde; geen attribuutwaarde" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Het document eindigde onverwacht in een attribuutwaarde" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Het document eindigde onverwacht in een afsluitingstag voor element ‘%s’" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Het document eindigde onverwacht in een afsluitingstag voor een niet-geopend " +"element" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Het document eindigde onverwacht in commentaar of een bewerkingsinstructie" + +#: glib/goption.c:868 +msgid "[OPTION…]" +msgstr "[OPTIE…]" + +#: glib/goption.c:984 +msgid "Help Options:" +msgstr "Hulpopties:" + +#: glib/goption.c:985 +msgid "Show help options" +msgstr "Deze hulptekst tonen" + +#: glib/goption.c:991 +msgid "Show all help options" +msgstr "Alle hulpteksten tonen" + +#: glib/goption.c:1054 +msgid "Application Options:" +msgstr "Programmaopties:" + +#: glib/goption.c:1056 +msgid "Options:" +msgstr "Opties:" + +#: glib/goption.c:1120 glib/goption.c:1190 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Kan het geheel getal ‘%s’ voor %s niet verwerken" + +#: glib/goption.c:1130 glib/goption.c:1198 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Het geheel getal ‘%s’ voor %s valt buiten het bereik" + +# integer-double +#: glib/goption.c:1155 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Kan het lange geheel getal ‘%s’ voor %s niet verwerken" + +#: glib/goption.c:1163 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Het lange geheel getal ‘%s’ voor %s valt buiten het bereik" + +#: glib/goption.c:1455 glib/goption.c:1534 +#, c-format +msgid "Error parsing option %s" +msgstr "Fout bij verwerken van optie %s" + +#: glib/goption.c:1565 glib/goption.c:1678 +#, c-format +msgid "Missing argument for %s" +msgstr "Ontbrekend argument voor %s" + +#: glib/goption.c:2189 +#, c-format +msgid "Unknown option %s" +msgstr "Onbekende optie %s" + +#: glib/gregex.c:257 +msgid "corrupted object" +msgstr "beschadigd object" + +#: glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "interne fout of beschadigd object" + +#: glib/gregex.c:261 +msgid "out of memory" +msgstr "onvoldoende geheugen" + +#: glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "limiet voor backtracking bereikt" + +# voor deelzoeken +#: glib/gregex.c:278 glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "het patroon bevat niet-ondersteunde tekens" + +#: glib/gregex.c:280 +msgid "internal error" +msgstr "interne fout" + +#: glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "achterwaartse referenties als condities zijn niet mogelijk" + +#: glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "recursielimiet bereikt" + +#: glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "ongeldige combinatie van nieuwe-regelvlaggen" + +#: glib/gregex.c:301 +msgid "bad offset" +msgstr "verkeerde offset" + +#: glib/gregex.c:303 +msgid "short utf8" +msgstr "te korte UTF-8" + +#: glib/gregex.c:305 +msgid "recursion loop" +msgstr "recursie-loop" + +#: glib/gregex.c:309 +msgid "unknown error" +msgstr "onbekende fout" + +#: glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ aan het einde van het patroon" + +#: glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c aan het einde van het patroon" + +# onbekend/niet herkend +#: glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "onbekend teken volgt na \\" + +#: glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "getallen in verkeerde volgorde in {} waardegever" + +#: glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "getal te groot in {} waardegever" + +#: glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "sluithaakje ] ontbreekt bij lettertekenklasse" + +# controleteken/sturingsteken/stuurcode/escape-teken +#: glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "ongelde stuurcode in lettertekenklasse" + +# [Z-a] +#: glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "bereik in verkeerde volgorde in lettertekenklasse" + +#: glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "niets te herhalen" + +#: glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "onverwachte herhaling" + +#: glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "onbekend teken na (? of (?-" + +#: glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX benoemde klassen zijn alleen ondersteund binnen een klasse" + +#: glib/gregex.c:366 +msgid "missing terminating )" +msgstr "ontbrekend sluithaakje: )" + +#: glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "verwijzing naar een niet-bestaand subpatroon" + +# opmerking/commentaar +#: glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "ontbrekend sluithaakje ) na commentaar" + +# te groot/te lang +#: glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "reguliere expressie te groot" + +#: glib/gregex.c:378 +msgid "failed to get memory" +msgstr "kon onvoldoende geheugen krijgen" + +#: glib/gregex.c:382 +msgid ") without opening (" +msgstr ") zonder openingshaakje: (" + +# te weinig geheugen voor code/code overstroomt/ +# programmacode loopt over +#: glib/gregex.c:386 +msgid "code overflow" +msgstr "overstroming programmacode" + +#: glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "onbekend teken na (?<" + +# terugkijkbewering +#: glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "‘lookbehind assertion’ heeft geen vaste lengte" + +#: glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "foutief getal of naam na (?(" + +#: glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "voorwaardelijke groep bevat meer dan twee vertakkingen" + +#: glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "bewering verwacht na (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R of (?[+-]cijfers moeten gevolgd worden door )" + +#: glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "onbekende POSIX-klassenaam" + +# collate=vergelijken/ordenen +# POSIX collating zorgt bijv. dat de Spaanse ll, na de l komt en voor de m. +# het betreft het beschouwen van meerdere tekens als 1 teken +# samengesteld teken +# geordende elementen/samengestelde elementen +#: glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "POSIX-samengestelde elementen worden niet ondersteund" + +#: glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "lettertekenwaarde in de reeks \\x{...} is te groot" + +#: glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "ongeldige voorwaarde (?(0)" + +# terugkijkbewering +#: glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C niet toegestaan in ‘lookbehind assertion’" + +#: glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, en \\u worden niet ondersteund" + +#: glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "recursieve aanroep zou oneindig kunnen doorlopen" + +#: glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "onbekend teken na (?P" + +# afsluiter/afsluitteken +#: glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "afsluitteken ontbreekt in naam subpatroon" + +#: glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "twee genoemde subpatronen hebben dezelfde naam" + +# onjuist samengesteld/gevormd +#: glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "onjuist gevormde \\P of \\p reeks" + +#: glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "onbekende eigenschapnaam na \\P of \\p" + +#: glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "naam van subpatroon is te lang (maximaal 32 tekens)" + +#: glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "teveel genoemde subpatronen (maximaal 10.000)" + +#: glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "octale waarde is groter dan \\377" + +#: glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "compile-werkruimte is overlopen" + +#: glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "eerder nagekeken gerefereerd subpatroon niet gevonden" + +#: glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE-groep bevat meer dan één vertakking" + +#: glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "inconsistente NEWLINE-opties" + +#: glib/gregex.c:476 +#, fuzzy +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g wordt niet gevolgd door een naam tussen haakjes, of getal niet gelijk " +"aan nul, optioneel tussen haakjes" + +#: glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "" + +#: glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) niet herkend" + +#: glib/gregex.c:489 +msgid "number is too big" +msgstr "getal is te groot" + +# afsluiter/afsluitteken +#: glib/gregex.c:492 +#, fuzzy +msgid "missing subpattern name after (?&" +msgstr "afsluitteken ontbreekt in naam subpatroon" + +#: glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "cijfer verwacht na (?+" + +#: glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: glib/gregex.c:501 +#, fuzzy +msgid "different names for subpatterns of the same number are not allowed" +msgstr "twee genoemde subpatronen hebben dezelfde naam" + +#: glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) vereist een parameter" + +#: glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c moet gevolgd worden door een ASCII-teken" + +#: glib/gregex.c:510 +#, fuzzy +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\g wordt niet gevolgd door een naam tussen haakjes, of getal niet gelijk " +"aan nul, optioneel tussen haakjes" + +#: glib/gregex.c:513 +#, fuzzy +msgid "\\N is not supported in a class" +msgstr "Zoeken binnen datastroom niet mogelijk" + +#: glib/gregex.c:516 +msgid "too many forward references" +msgstr "" + +#: glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "naam is te lang in (*MARK), (*PRUNE), (*SKIP) of (*THEN)" + +#: glib/gregex.c:522 +#, fuzzy +msgid "character value in \\u.... sequence is too large" +msgstr "lettertekenwaarde in de reeks \\x{...} is te groot" + +#: glib/gregex.c:745 glib/gregex.c:1983 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Fout bij reguliere expressie %s: %s" + +#: glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE-bibliotheek is gecompileerd zonder ondersteuning voor UTF8" + +#: glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"PCRE-bibliotheek is gecompileerd zonder ondersteuning voor UTF8-eigenschappen" + +#: glib/gregex.c:1328 +#, fuzzy +msgid "PCRE library is compiled with incompatible options" +msgstr "" +"PCRE-bibliotheek is gecompileerd zonder ondersteuning voor UTF8-eigenschappen" + +#: glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Fout bij optimaliseren van reguliere expressie %s: %s" + +# opbouwen/compileren +#: glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Fout bij compileren van reguliere expressie %s op teken %d:%s" + +#: glib/gregex.c:2419 +msgid "hexadecimal digit or “}†expected" +msgstr "hexadecimaal getal of ‘}’ verwacht" + +#: glib/gregex.c:2435 +msgid "hexadecimal digit expected" +msgstr "hexadecimaal getal verwacht" + +# tekort/ontbreekt/te weinig +#: glib/gregex.c:2475 +msgid "missing “<†in symbolic reference" +msgstr "‘<’ ontbreekt in verwijzing" + +# symbolische verwijzing +#: glib/gregex.c:2484 +msgid "unfinished symbolic reference" +msgstr "onafgemaakte verwijzing" + +#: glib/gregex.c:2491 +msgid "zero-length symbolic reference" +msgstr "verwijzing heeft nullengte" + +#: glib/gregex.c:2502 +msgid "digit expected" +msgstr "cijfer verwacht" + +#: glib/gregex.c:2520 +msgid "illegal symbolic reference" +msgstr "ongeldige verwijzing" + +#: glib/gregex.c:2583 +msgid "stray final “\\â€" +msgstr "extra afsluiting ‘\\’" + +#: glib/gregex.c:2587 +msgid "unknown escape sequence" +msgstr "onbekende escape-reeks" + +#: glib/gregex.c:2597 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Fout bij inlezen vervangende tekst ‘%s’ op teken %lu: %s" + +#: glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Aangehaalde tekst begint niet met een ‘\"’-teken" + +# solitair "-teken/ongebalanceerd +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Solitair ‘\"’-teken in opdrachtregel of andere shell-aangehaalde tekst" + +#: glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Tekst eindigde na een ‘\\’-teken. (De tekst was ‘%s’)" + +#: glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"De tekst eindigde voordat een afsluitend aanhalingsteken was gevonden voor " +"%c. (De tekst was ‘%s’)" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "De tekst was leeg (of bevatte slechts lege ruimte)" + +#: glib/gspawn.c:315 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Lezen van data van dochterproces is mislukt (%s)" + +#: glib/gspawn.c:460 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Onverwachte fout bij het lezen van data van een dochterproces (%s)" + +#: glib/gspawn.c:545 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Onverwachte fout in waitpid() (%s)" + +#: glib/gspawn.c:1053 glib/gspawn-win32.c:1329 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Dochterproces eindigde met code %ld" + +#: glib/gspawn.c:1061 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Dochterproces afgesloten met signaal %ld" + +#: glib/gspawn.c:1068 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Dochterproces gestopt met signaal %ld" + +#: glib/gspawn.c:1075 +#, c-format +msgid "Child process exited abnormally" +msgstr "Dochterproces eindigde niet normaal" + +#: glib/gspawn.c:1475 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Lezen van pijplijn naar dochter (%s) is mislukt" + +#: glib/gspawn.c:1723 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Voortbrengen van dochterproces ‘%s’ is mislukt (%s)" + +#: glib/gspawn.c:1762 +#, c-format +msgid "Failed to fork (%s)" +msgstr "De fork is mislukt (%s)" + +#: glib/gspawn.c:1911 glib/gspawn-win32.c:381 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Wijzigen naar map ‘%s’ is mislukt (%s)" + +#: glib/gspawn.c:1921 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Uitvoeren van dochterproces ‘%s’ is mislukt (%s)" + +# was eerst: herleiden +#: glib/gspawn.c:1931 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"Doorsluizen van invoer of uitvoer van een dochterproces is mislukt (%s)" + +#: glib/gspawn.c:1940 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Het forken van een dochterproces is mislukt (%s)" + +#: glib/gspawn.c:1948 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Onbekende fout bij het uitvoeren van dochterproces ‘%s’" + +#: glib/gspawn.c:1972 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Lezen van voldoende data van pijplijn van dochter-pid is mislukt (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "Lezen van data van dochterproces is mislukt" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Aanmaken van pijplijn voor het communiceren met dochterproces is mislukt (%s)" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Uitvoeren van dochterproces is mislukt (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ongeldige programmanaam: %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ongeldige tekenreeks in argumentvector bij %d: %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ongeldige tekenreeks in omgeving: %s" + +# werkmap/huidige map +#: glib/gspawn-win32.c:721 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ongeldige werkmap: %s" + +#: glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Uitvoeren van het hulpprogramma (%s) is mislukt" + +#: glib/gspawn-win32.c:1056 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Onverwachte fout in g_io_channel_win32_poll() bij het lezen van data van een " +"dochterproces" + +#: glib/gstrfuncs.c:3309 glib/gstrfuncs.c:3411 +msgid "Empty string is not a number" +msgstr "Lege tekenreeks is geen getal" + +#: glib/gstrfuncs.c:3333 +#, fuzzy, c-format +msgid "“%s†is not a signed number" +msgstr "‘%s’ is geen geldige naam" + +#: glib/gstrfuncs.c:3343 glib/gstrfuncs.c:3447 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Getal ‘%s’ is buiten bereik [%s, %s]" + +#: glib/gstrfuncs.c:3437 +#, fuzzy, c-format +msgid "“%s†is not an unsigned number" +msgstr "‘%s’ is geen geldige naam" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "Geheugen toewijzen mislukt" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "Teken valt buiten het bereik van UTF-8" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "Ongeldige reeks in conversieinvoer" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "Teken valt buiten het bereik van UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2756 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2758 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2760 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2762 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2764 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2766 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2770 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2772 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2774 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2776 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2778 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2780 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2784 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2786 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2788 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2790 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2792 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2794 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2798 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2800 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2802 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2804 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2806 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2808 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +# ook byte voor meervoud (het bestand is 29 byte groot) +#: glib/gutils.c:2842 glib/gutils.c:2959 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u byte" + +#: glib/gutils.c:2846 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +# ook byte voor meervoud (het bestand is 29 byte groot) +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2913 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s byte" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2918 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2972 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:2977 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2982 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2987 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2992 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2997 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#, fuzzy +#~| msgid "Error in address '%s' - the family attribute is malformed" +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Fout in adres ‘%s’ - het family-attribuut is onjuist gevormd" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s aangekoppeld op %s\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "niets doen.\n" + +#~ msgid "No such method '%s'" +#~ msgstr "Methode ‘%s' bstaat niet" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Kan adres van bus niet bepalen van DBUS_STARTER_BUS_TYPE " +#~ "omgevingsvariabele - onbekende waarde ‘%s’" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGUMENTEN…]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Aanmaken van tijdelijk bestand mislukt: %s" + +#~ msgid "No such interface" +#~ msgstr "Interface bestaat niet" + +# openen/lezen +#, fuzzy +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "Fout bij comprimeren van bestand: %s" + +# openen/lezen +#, fuzzy +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "Fout bij comprimeren van bestand: %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Kon de standaard ‘directory monitor type’ niet vinden" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Fout bij het hernoemen van bestand: %s" + +# openen/lezen +#~ msgid "Error opening file: %s" +#~ msgstr "Fout bij het openen van bestand: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Fout bij het aanmaken van map: %s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "Kan fout niet verkrijgen: %s" + +#~ msgid "Error launching application: %s" +#~ msgstr "Fout bij opstarten van het programma: %s" + +#~ msgid "URIs not supported" +#~ msgstr "URI's worden niet ondersteund" + +#~ msgid "association changes not supported on win32" +#~ msgstr "associatiewijzigingen niet mogelijk op win32" + +# Associeren/associaties aanmaken +#~ msgid "Association creation not supported on win32" +#~ msgstr "Associaties aanmaken niet mogelijk op win32" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Fout bij lezen van bestand ‘%s’: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "" +#~ "Openen van bestand ‘%s’ voor schrijven is mislukt: fdopen() is mislukt: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Schrijven van bestand ‘%s’ is mislukt: fflush() is mislukt: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Sluiten van bestand ‘%s’ is mislukt: fclose() is mislukt: %s" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Het sleutelbestand bevat geen sleutel ‘%s’" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "" +#~ "Ongebruikelijk beëindiging van programma tijdens starten van " +#~ "opdrachtregel ‘%s’: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "Opdrachtregel ‘%s’ beëindigd met exit-status %d: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "limiet voor lege substrings bereikt" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "tekens die hoofd,- en kleine letters wijzigen zijn hier niet toegestaan" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "herhalen van een DEFINE-groep is niet toegestaan" + +#~ msgid "File is empty" +#~ msgstr "Bestand is leeg" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "Het sleutelbestand bevat sleutel ‘%s’ die een waarde heeft die niet " +#~ "geïnterpreteerd kan worden." + +#~ msgid "This option will be removed soon." +#~ msgstr "Deze optie zal binnenkort verwijderd worden." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Fout bij het benaderen van bestand ‘%s’: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "Geen service-record voor ‘%s’" + +#~ msgid "Error connecting: " +#~ msgstr "Fout tijdens verbinden: " + +# openen/lezen +#~ msgid "Error connecting: %s" +#~ msgstr "Fout bij verbinden: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "De SOCKSv4-implementatie limiteert de gebruikersnaam tot %i tekens" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "De SOCKSv4-implementatie limiteert de host-naam tot %i tekens" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Fout bij lezen van unix: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "Fout bij sluiten van unix: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Fout bij schrijven naar unix: %s" + +#, fuzzy +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "naam" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" diff --git a/po/nn.po b/po/nn.po new file mode 100644 index 0000000..c49c5d4 --- /dev/null +++ b/po/nn.po @@ -0,0 +1,3916 @@ +# translation of nn.po to Norwegian Nynorsk +# Roy-Magne Mo , 2002. +# Ã…smund Skjæveland , 2003-2008, 2011. +# Norwegian (Nynorsk) translation of glib +# Copyright (C) Free Software Foundation, 2002. +msgid "" +msgstr "" +"Project-Id-Version: nn\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2011-12-26 17:14+0100\n" +"Last-Translator: Ã…smund Skjæveland \n" +"Language-Team: Norwegian Nynorsk \n" +"Language: nn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Uventa attributt «%s» til elementet «%s»" + +#: ../glib/gbookmarkfile.c:791 +#: ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 +#: ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Attributt «%s» til elementet «%s» ikkje funnen" + +#: ../glib/gbookmarkfile.c:1149 +#: ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 +#: ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Uventa merke «%s», venta merket «%s»" + +#: ../glib/gbookmarkfile.c:1174 +#: ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 +#: ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Uventa merke «%s» inni «%s»" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "Klarte ikkje Ã¥ finna gyldig bokmerkefil i datamappene" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Eit bokmerke for adressa «%s» finst frÃ¥ før" + +#: ../glib/gbookmarkfile.c:2081 +#: ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 +#: ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 +#: ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 +#: ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 +#: ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 +#: ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 +#: ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 +#: ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Klarte ikkje Ã¥ finna noko bokmerke for adressa «%s»" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Det er ikkje definert nokon MIME-type i bokmerket for adressa «%s»" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Privat-flagg er ikkje definert i bokmerket for adressa «%s»" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Det er ikkje laga nokon grupper i bokmerket for adressa «%s»" + +#: ../glib/gbookmarkfile.c:3278 +#: ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "Det er ikkje nokon program som heiter «%s» som har registrert bokmerke for «%s»" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Klarte ikkje Ã¥ utvida køyrelinja «%s» med adressa «%s»" + +#: ../glib/gconvert.c:567 +#: ../glib/gconvert.c:645 +#: ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr ")" +msgstr "Dokumentet mÃ¥ byrja med eit element (t.d. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "'%s' is not a valid character following a '<' character; it may not begin an element name" +msgstr "«%s» er ikkje eit gyldig teikn etter ein «<»-teikn. Det kan ikkje vera det fyrste teiknet i eit elementnamn" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "Odd character '%s', expected a '>' character to end the empty-element tag '%s'" +msgstr "Merkeleg teikn «%s», venta eit «>»-teikn for Ã¥ avslutta startmerket av elementet «%s»" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "Merkeleg teikn «%s», venta ein «=» etter attributtnamnet «%s» av elementet «%s»" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "Odd character '%s', expected a '>' or '/' character to end the start tag of element '%s', or optionally an attribute; perhaps you used an invalid character in an attribute name" +msgstr "Merkeleg teikn «%s», venta anten eit «>»-teikn eller «/»-teikn for Ã¥ avslutta startmerket av elementet «%s», eller ein valfri attributt. Kan henda du brukte eit ugyldig teikn i attributtnamnet" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "Odd character '%s', expected an open quote mark after the equals sign when giving value for attribute '%s' of element '%s'" +msgstr "Merkeleg teikn «%s», venta eit ope siteringsmerke etter likskapsteiknet for Ã¥ gje ein verdi for attributten «%s» av elementet «%s»" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "'%s' is not a valid character following the characters ''" +msgstr "«%s» er ikkje eit gyldig teikn etter avsluttande merket «%s»; det tillatne teiknet er «>»" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Elementet «%s» vart lukka. Det er ingen opne element no" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Elementet «%s» vart avslutta, men det opne elementet er «%s»" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumentet var tomt eller innheldt berre tomme teikn" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Dokument avslutta uventa rett etter ei open vinkelhake «<»" + +#: ../glib/gmarkup.c:1734 +#: ../glib/gmarkup.c:1779 +#, c-format +msgid "Document ended unexpectedly with elements still open - '%s' was the last element opened" +msgstr "Dokumentet slutta uventa med element framleis opne. «%s» var det siste elementet som vart opna" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "Document ended unexpectedly, expected to see a close angle bracket ending the tag <%s/>" +msgstr "Dokumentet slutta uventa, venta Ã¥ sjÃ¥ at ei vinkelhake lukka det avsluttande merket <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumentet tok uventa slutt inni eit elementnamn" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumentet tok uventa slutt inni eit attributtnamn" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumentet vart uventa avslutta inne i eit merke som opnar eit element." + +#: ../glib/gmarkup.c:1765 +msgid "Document ended unexpectedly after the equals sign following an attribute name; no attribute value" +msgstr "Dokumentet slutta uventa etter likskapsteiknet etter attributtnamnet; ingen attributtverdi" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumentet avslutta uventa medan det var inne i ein attributtverdi" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Dokumentet avslutta uventa i eit lukkemerke for elementet «%s»" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokumentet avslutta uventa inne i ein merknad eller prosseseringsinstruksjon" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "øydelagt objekt" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "intern feil eller øydelagt objekt" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "tom for minne" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "tilbakesporingsgrensa nÃ¥dd" + +#: ../glib/gregex.c:210 +#: ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "mønsteret inneheld element som ikkje er støtta i delsamanlikning" + +#: ../glib/gregex.c:212 +#: ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "intern feil" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "tilbakereferansar som vilkÃ¥r er ikkje støtta i delsamanlikning" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "rekursjonsgrensa nÃ¥dd" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "arbeidsomrÃ¥degrensa for tomme understrengar nÃ¥dd" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "ugyldig kombinasjon av nylinjeflagg" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "ukjend feil" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ pÃ¥ slutten av mønsteret" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c pÃ¥ slutten av mønsteret" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "ukjend teikn etter \\" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "skiftesekvensar som pÃ¥verkar smÃ¥/store bokstavar (\\I, \\L, \\u, \\U) er ikkje tillatne her" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "tal ikkje i rekkefølgje i {}-kvantor" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "tal for stort i {}-kvantor" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "manglar avsluttande ] i teiknklassen" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "ugyldig skiftesekvens i teiknklassen" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "spenn ikkje i rekkefølgje i teiknklassen" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "ikkje noko Ã¥ gjenta" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "kjenner ikkje att teiknet etter (?" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "kjenner ikkje att teiknet etter (?<" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "kjenner ikkje att teiknet etter (?P" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX-type klassar med namn er berre støtta inni ein klasse" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "manglar avsluttande )" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") utan opnande (" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R eller (?[+-]tal mÃ¥ følgjast av )" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "referanse til undermønster som ikkje finst" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "manglar ) etter kommentar" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "regulært uttrykk for stort" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "klarte ikkje Ã¥ fÃ¥ minne" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "bakoversøk-pÃ¥stand har ikkje fast lengde" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "uleseleg tal eller namn etter (?(" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "vilkÃ¥rgruppa inneheld meir enn to greiner" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "pÃ¥stand venta etter (?(" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "ukjend POSIX-klassenamn" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "POSIX-type sorterte element er ikkje støtta" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "teiknverdi i \\x{...}-sekvens er for stor" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "ugyldig vilkÃ¥r (?(0)" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C ikkje tillate i bakoversøk-pÃ¥stand" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "rekursivt kall kan kanskje gÃ¥ til evig tid" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "manglar lukketeikn i undermønsternamn" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "to namngjevne undermønster har same namn" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "feilskriven \\P- eller \\p-sekvens" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "ukjend eigenskapnamn etter \\P eller \\p" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "undermønsternamn for langt (toppen 32 teikn)" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "for mange namngjevne undermønster (toppen 10 000)" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "oktalverdi er større enn \\377" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE-gruppe inneheld meir enn ei grein" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "det er ikkje tillate Ã¥ gjenta ei DEFINE-gruppe" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "inkonsistente NEWLINE-val" + +#: ../glib/gregex.c:395 +msgid "\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "\\g er ikkje følgd av eit namn i klammer eller eit ikkje-null tal i valfrie klamer" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "uventa gjentaking" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "kode-overflyt" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "gjekk utanfor kompileringsarbeidsomrÃ¥det" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "tidlegare kontrollert referert undermønster ikkje funne" + +#: ../glib/gregex.c:630 +#: ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Feil under samanlikning med regulært uttrykk %s: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE-bibliotek er kompilert utan støtte for UTF-8" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE-bibliotek er kompilert utan støtte for UTF-8-eigenskapar" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Feil under kompilering av regulært uttrykk %s pÃ¥ teikn %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Feil under optimering av regulært uttrykk %s: %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "heksadesimalt teikn eller «}» venta" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "heksadesimalt teikn venta" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "manglar «<» i symbolsk referanse" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "uferdig symbolsk referanse" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "null-lengd symbolsk referanse" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "venta siffer" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "ugyldig symbolsk referanse" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "laus avsluttande «\\»" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "ukjend skiftesekvens" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "Feil under tolking av erstatningsteksten «%s» pÃ¥ teikn «%lu»: %s" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Sitert tekst startar ikkje med eit siteringsmerke" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Upara siteringsmerke i kommandolinje eller anna skal-sitert tekst" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Teksten tok slutt rett etter eit «\\»-teikn (Teksten var «%s»)" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "Teksten tok slutt før avsluttande sitatteikn vart funne for %c. (Teksten var «%s»)" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Teksten var tom (eller inneheldt berre tomme teikn)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Klarte ikkje Ã¥ lesa data frÃ¥ barneprosess" + +#: ../glib/gspawn-win32.c:299 +#: ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Klarte ikkje Ã¥ oppretta røyr for Ã¥ kommunisera med barneprosess (%s)" + +#: ../glib/gspawn-win32.c:338 +#: ../glib/gspawn-win32.c:346 +#: ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Klarte ikkje Ã¥ lesa frÃ¥ røyr frÃ¥ barn (%s)" + +#: ../glib/gspawn-win32.c:369 +#: ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Klarte ikkje Ã¥ skifta til katalogen «%s» (%s)" + +#: ../glib/gspawn-win32.c:375 +#: ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Klarte ikkje Ã¥ utføra barneprosess (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ugyldig programnamn: %s" + +#: ../glib/gspawn-win32.c:454 +#: ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ugyldig streng i argumentvektor plass %d: %s" + +#: ../glib/gspawn-win32.c:465 +#: ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ugyldig streng i miljø: %s" + +#: ../glib/gspawn-win32.c:718 +#: ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ugyldig arbeidskatalog: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Klarte ikkje Ã¥ køyra hjelpeprogram (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "Unexpected error in g_io_channel_win32_poll() reading data from a child process" +msgstr "Uventa feil i g_io_channel_win32_poll() ved lesing av data frÃ¥ barneprosess" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Klarte ikkje Ã¥ lesa data frÃ¥ barneprosess (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Uventa feil i select() ved lesing av data frÃ¥ barneprosess (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Uventa feil i waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Kunne ikkje starta barneprosess (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Klarte ikkje Ã¥ utføra barnprosess «%s» (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Klarte ikkje Ã¥ redirigera utdata eller inndata frÃ¥ barneprosess (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Kunne ikkje starta barneprosess (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Ukjend feil ved køyring av barneprosess «%s»" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Klarte ikkje Ã¥ lesa nok data frÃ¥ pid-røyr frÃ¥ barn (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Teikn ikkje gyldig for UTF-8" + +#: ../glib/gutf8.c:1186 +#: ../glib/gutf8.c:1195 +#: ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 +#: ../glib/gutf8.c:1473 +#: ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Ugyldig sekvens i inndata-konvertering" + +#: ../glib/gutf8.c:1484 +#: ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Teikn ikkje gyldig for UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Bruk:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[VAL...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Hjelpeval:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Vis hjelpeval" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Vis alle hjelpevala" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Programval:" + +#: ../glib/goption.c:997 +#: ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Kan ikkje tolka heiltalsverdien «%s» til %s" + +#: ../glib/goption.c:1007 +#: ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Heiltalsverdien «%s» til «%s» utanfor gyldig omrÃ¥de" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Kan ikkje tolka flyttalsverdien «%s» til «--%s»" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Flyttalsverdien «%s» til «%s» utanfor gyldig omrÃ¥de" + +#: ../glib/goption.c:1303 +#: ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Feil under tolking av val %s" + +#: ../glib/goption.c:1413 +#: ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Argument manglar for %s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Ukjend val «%s»" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "Klarte ikkje Ã¥ finna gyldig nøkkelfil i søkjemappene" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Ikkje ei vanleg fil" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Fila er tom" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "Nøkkelfila inneheld linja «%s» som ikkje er eit nøkkel-verdi-par, ei gruppe eller ein kommentar" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ugyldig gruppenamn: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Nøkkelfila startar ikkje med ei gruppe" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Ugyldig nøkkelnamn: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Nøkkelfila inneheld den ikkje støtta kodinga «%s»" + +#: ../glib/gkeyfile.c:1149 +#: ../glib/gkeyfile.c:1311 +#: ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 +#: ../glib/gkeyfile.c:2887 +#: ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 +#: ../glib/gkeyfile.c:3394 +#: ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Nøkkelfila manglar gruppa «%s»" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Nøkkelfila manglar nøkkelen «%s»" + +#: ../glib/gkeyfile.c:1430 +#: ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "Nøkkelfila har nøkkelen «%s» med verdien «%s», som ikkje er UTF-8" + +#: ../glib/gkeyfile.c:1450 +#: ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "Nøkkelfila har nøkkelen «%s» med ein verdi som ikkje kan tolkast." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "Nøkkelfila har nøkkelen «%s» med ein verdi som ikkje kan tolkast." + +#: ../glib/gkeyfile.c:2151 +#: ../glib/gkeyfile.c:2515 +#, c-format +msgid "Key file contains key '%s' in group '%s' which has value that cannot be interpreted." +msgstr "Nøkkelfila har feil i nøkkelen «%s» i gruppa «%s». Verdien kan ikkje tolkast." + +#: ../glib/gkeyfile.c:2701 +#: ../glib/gkeyfile.c:2902 +#: ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Nøkkelfila har ikkje nøkkelen «%s» i gruppa «%s»" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Nøkkelfila inneheld escape-teikn pÃ¥ slutten av linja" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Nøkkelfila inneheld ugyldig escape-sekvens «%s»" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Verdien «%s» kan ikkje tolkast som eit tal." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Heiltalsverdien «%s» er utanfor gyldig omrÃ¥de" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Verdien «%s» kan ikkje tolkast som eit flyttal." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Verdien «%s» kan ikkje tolkast som ein boolsk verdi." + +#: ../gio/gbufferedinputstream.c:411 +#: ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 +#: ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 +#: ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 +#: ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "For stor teljingsverdi sendt til %s" + +#: ../gio/gbufferedinputstream.c:881 +#: ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 +#: ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "Straumen er allereie stengt" + +#: ../gio/gcancellable.c:321 +#: ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 +#: ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 +#: ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "Operasjonen vart avbroten" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 +#: ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Ugyldig bytesekvens i inndata for konvertering" + +#: ../gio/gcharsetconverter.c:318 +#: ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 +#: ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Operasjonen er ikkje støtta" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Ukjend type" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "%s-filtype" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "%s-type" + +#: ../gio/gcredentials.c:273 +#: ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "Uventa tidleg slutt pÃ¥ straumen" + +#: ../gio/gdbusaddress.c:142 +#: ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 +#: ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 +#: ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "Key/Value pair %d, '%s', in address element '%s', does not contain an equal sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "Error unescaping key or value in Key/Value pair %d, '%s', in address element '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "Error in address '%s' - the unix transport requires exactly one of the keys 'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Feil ved trunkering av fila: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Feil ved opning av fila «%s»: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Feil ved lesing av fil «%s»: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Feil ved lesing av fil «%s»: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Feil ved skriving til fila: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Feil ved lesing av fil «%s»: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 +#: ../gio/gdbusconnection.c:6409 +#, c-format +msgid "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable - unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 +#: ../gio/gdbusconnection.c:6418 +msgid "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Ukjend type" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Feil ved opning av katalog «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Feil ved opning av katalog «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Feil ved opning av fila «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 +#: ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 +#: ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 +#: ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Feil ved lesing av fil «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Feil ved lesing av fil «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Feil ved stenging av fila: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Feil ved opning av fila «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Feil ved opning av fila «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 +#: ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 +#: ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "Teljaren er stengt" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 +#: ../gio/gdbusconnection.c:4086 +#, c-format +msgid "No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 +#: ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 +#: ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "Straumen er allereie stengt" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value 0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "Message has %d file descriptors but the header field indicates %d file descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "Message body has type signature '%s' but signature in the header field is '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Feil ved skriving til fila: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 +#: ../gio/gdbusproxy.c:2734 +msgid "Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Papirkorg er ikkje støtta" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Feil ved skriving til fila: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 +#: ../gio/gdbus-tool.c:218 +#: ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 +#: ../gio/gdbus-tool.c:691 +#: ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Feil pÃ¥ linje %d: %s" + +#: ../gio/gdbus-tool.c:173 +#: ../gio/gdbus-tool.c:231 +#: ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Feil under tolking av val %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "Warning: According to introspection data, method '%s' does not exist on interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 +#: ../gio/gdbus-tool.c:822 +#: ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Feil ved opning av fila: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 +#: ../gio/gdbus-tool.c:883 +#: ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Teiknet «%s» er ikkje gyldig inne i eit entitetsnamn" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Teiknet «%s» er ikkje gyldig inne i eit entitetsnamn" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Teiknet «%s» er ikkje gyldig inne i eit entitetsnamn" + +#: ../gio/gdbus-tool.c:669 +#: ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Feil under tolking av val %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Feil under konvertering: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 +#: ../gio/gdbus-tool.c:1568 +#: ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 +#: ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Feil ved opning av katalog «%s»: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "øydelagt objekt" + +#: ../gio/gdesktopappinfo.c:572 +#: ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Utan namn" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "Skrivebordfila oppgav ikkje Exec-felt" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "Klarte ikkje Ã¥ finna terminalen programmet krev" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "Kan ikkje laga programoppsettmappe %s for brukaren: %s" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "Kan ikkje laga MIME-oppsettmappe %s: %s" + +#: ../gio/gdesktopappinfo.c:1785 +#: ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Kan ikkje laga skrivebordfila %s for brukaren" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "Sjølvvald definisjon av %s" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "stasjonen støttar ikkje Ã¥ løysa ut" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +#, fuzzy +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "stasjonen støttar ikkje Ã¥ løysa ut" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "stasjonen støttar ikkje Ã¥ spørja etter media" + +#: ../gio/gdrive.c:728 +#, fuzzy +msgid "drive doesn't implement start" +msgstr "stasjonen støttar ikkje Ã¥ løysa ut" + +#: ../gio/gdrive.c:831 +#, fuzzy +msgid "drive doesn't implement stop" +msgstr "stasjonen støttar ikkje Ã¥ løysa ut" + +#: ../gio/gdummytlsbackend.c:168 +#: ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 +#: ../gio/gfile.c:1102 +#: ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 +#: ../gio/gfile.c:1528 +#: ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 +#: ../gio/gfile.c:1723 +#: ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 +#: ../gio/gfile.c:3307 +#: ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 +#: ../gio/gfile.c:3534 +#: ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 +#: ../gio/gfile.c:4352 +#: ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 +#: ../gio/gfile.c:4626 +#: ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 +#: ../gio/gfile.c:5308 +#: ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 +#: ../gio/gfile.c:7037 +#: ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Operasjonen er ikkje støtta" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 +#: ../gio/glocalfile.c:1051 +#: ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "Omsluttande monteringspunkt finst ikkje" + +#: ../gio/gfile.c:2411 +#: ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "Kan ikkje skriva over mappe" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "Kan ikkje skriva ei mappe over ei mappe" + +#: ../gio/gfile.c:2480 +#: ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "MÃ¥lfila finst" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "Kan ikkje kopiera katalog rekursivt" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Symbolske lenkjer er ikkje støtta" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Feil ved opning av fila: %s" + +#: ../gio/gfile.c:2909 +#, fuzzy +msgid "Can't copy special file" +msgstr "Kan ikkje skriva over mappe" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "Ugyldig symlink-verdi oppgjeven" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "Papirkorg er ikkje støtta" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Filnamn kan ikkje innehalda «%c»" + +#: ../gio/gfile.c:6006 +#: ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "volumet støttar ikkje montering" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "Ingen program er registrert til Ã¥ handtera denne fila" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "Teljaren er stengt" + +#: ../gio/gfileenumerator.c:212 +#: ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 +#: ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "Filteljaren har ventande operasjon" + +#: ../gio/gfileenumerator.c:361 +#: ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "Filteljaren er allereie lukka" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 +#: ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 +#: ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "Straumen støttar ikkje query_info" + +#: ../gio/gfileinputstream.c:335 +#: ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "Søking ikkje støtta i straumen" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "Trunkering ikkje tillate pÃ¥ innstraumen" + +#: ../gio/gfileiostream.c:463 +#: ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "Trunkerung ikkje tillate pÃ¥ straumen" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "Innstraumen støttar ikkje lesing" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 +#: ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "Straumen har ventande operasjon" + +#: ../gio/ginetsocketaddress.c:181 +#: ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Papirkorg er ikkje støtta" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "invalid name '%s': invalid character '%c'; only lowercase letters, numbers and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid " shadows in ; use to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "exactly one of 'type', 'enum' or 'flags' must be specified as an attribute to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, fuzzy, c-format +msgid "invalid GVariant type string '%s'" +msgstr "Ugyldig attributtype (venta streng)" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid " is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid " extends but '%s' does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 +#: ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 +#: ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 +#: ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "error parsing key '%s' in schema '%s' as specified in override file '%s': %s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "override for key '%s' in schema '%s' in override file '%s' is out of the range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "override for key '%s' in schema '%s' in override file '%s' is not in the list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +#: ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "Klarer ikkje Ã¥ finna typen standard lokal mappeovervakar" + +#: ../gio/glocalfile.c:571 +#: ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Ugyldig filnamn %s" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Feil ved henting av filsysteminfo: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "Kan ikkje gje rotmappa nytt namn" + +#: ../gio/glocalfile.c:1117 +#: ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Feil ved namnebyte pÃ¥ fila: %s" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "Kan ikkje gje fila nytt namn, filnamnet finst frÃ¥ før" + +#: ../gio/glocalfile.c:1139 +#: ../gio/glocalfile.c:2129 +#: ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 +#: ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 +#: ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Ugyldig filnamn" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Feil ved opning av fila: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "Kan ikkje opna mappa" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Feil under fjerning av fila: %s" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "Feil under kassering av fila: %s" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Klarte ikkje Ã¥ laga papirkorgmappa %s: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "Klarar ikkje Ã¥ finna toppnivÃ¥mappe for papirkorga" + +#: ../gio/glocalfile.c:1931 +#: ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "Klarar ikkje Ã¥ finna eller laga papirkorgmappa" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Klarte ikkje Ã¥ laga infofil om kassering: %s" + +#: ../gio/glocalfile.c:2014 +#: ../gio/glocalfile.c:2019 +#: ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Klarte ikkje Ã¥ kassera fila: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Feil ved opning av katalog «%s»: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Klarte ikkje Ã¥ lesa den symbolske lenkja «%s»: %s" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Klarte ikkje Ã¥ laga symbolsk lenkje: %s" + +#: ../gio/glocalfile.c:2228 +#: ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Feil under flytting av fil: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "Kan ikkje flytta mappa over ei mappe" + +#: ../gio/glocalfile.c:2278 +#: ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 +#: ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 +#: ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "Klarte ikkje Ã¥ laga tryggleikskopi av fila" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "Klarte ikkje Ã¥ sletta mÃ¥lfila: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "Flytting mellom monteringar ikkje støtta" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "Attributtverdien mÃ¥ vera ikkje-NULL" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "Ugyldig attributtype (venta streng)" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "Ugyldig utvida attributtnamn" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Feil under endring av utvida attributtverdi «%s»: %s" + +#: ../gio/glocalfileinfo.c:1482 +#: ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "Feil under lesing av informasjon om fila «%s»: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "(ugyldig teiknkoding)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "Feil under lesing av info om fildeskriptoren: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ugyldig attributtype (venta uint32)" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ugyldig attributtype (venta uint64)" + +#: ../gio/glocalfileinfo.c:1850 +#: ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ugyldig attributtype (venta byte-streng)" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Feil endring av løyve: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Feil endring av løyve: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "Feil under eigarskifte: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "symbolsk lenkje mÃ¥ vera ikkje-NULL" + +#: ../gio/glocalfileinfo.c:2004 +#: ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Fil under oppretting av symbolsk lenkje: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "Fil under oppretting av symbolsk lenkje: Fila er ikkje ei symbolsk lenkje" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Feil endring av løyve: %s" + +#: ../gio/glocalfileinfo.c:2162 +#, fuzzy +msgid "SELinux context must be non-NULL" +msgstr "symbolsk lenkje mÃ¥ vera ikkje-NULL" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Feil under eigarskifte: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Ã… setja attributten %s er ikkje støtta" + +#: ../gio/glocalfileinputstream.c:185 +#: ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Feil ved lesing frÃ¥ fila: %s" + +#: ../gio/glocalfileinputstream.c:216 +#: ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 +#: ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Feil ved søking i fila: %s" + +#: ../gio/glocalfileinputstream.c:261 +#: ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Feil ved stenging av fila: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "Klarer ikkje Ã¥ finna typen standard lokal filovervakar" + +#: ../gio/glocalfileoutputstream.c:202 +#: ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Feil ved skriving til fila: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Feil under fjerning av gamal tryggleikskopilenkje: %s" + +#: ../gio/glocalfileoutputstream.c:297 +#: ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Feil ved oppretting av tryggleikskopi: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Feil ved namnebyte pÃ¥ mellombels fil: %s" + +#: ../gio/glocalfileoutputstream.c:516 +#: ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "Feil ved trunkering av fila: %s" + +#: ../gio/glocalfileoutputstream.c:577 +#: ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 +#: ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 +#: ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Feil ved opning av fila «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "MÃ¥lfila er ei mappe" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "MÃ¥lfila er ikkje ei vanleg fil" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "Fila vart endra utanfrÃ¥" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Feil under fjerning av fila: %s" + +#: ../gio/gmemoryinputstream.c:486 +#: ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "Ugyldig GSeekType sendt med" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Ugyldig søkeførespurnad" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Kan ikkje trunkera GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "Utstraumen frÃ¥ minnet kan ikkje endra storleik" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "Klarte ikkje Ã¥ endra storleik pÃ¥ utstraumen frÃ¥ minnet" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "Amount of memory required to process the write is larger than available address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +#, fuzzy +msgid "mount doesn't implement \"unmount\"" +msgstr "monteringspunktet støttar ikkje avmontering" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +#, fuzzy +msgid "mount doesn't implement \"eject\"" +msgstr "monteringspunktet støttar ikkje Ã¥ løysa ut" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +#, fuzzy +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "monteringspunktet støttar ikkje avmontering" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +#, fuzzy +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "monteringspunktet støttar ikkje Ã¥ løysa ut" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +#, fuzzy +msgid "mount doesn't implement \"remount\"" +msgstr "monteringspunktet støttar ikkje Ã¥ remontera" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +#, fuzzy +msgid "mount doesn't implement content type guessing" +msgstr "monteringspunktet støttar ikkje avmontering" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +#, fuzzy +msgid "mount doesn't implement synchronous content type guessing" +msgstr "monteringspunktet støttar ikkje avmontering" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 +#: ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "utstraumen støttar ikkje skriving" + +#: ../gio/goutputstream.c:372 +#: ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "Kjeldestraumen er allereie stengt" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Feil ved lesing av fil «%s»: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Feil ved lesing av fil «%s»: %s" + +#: ../gio/gresolver.c:864 +#: ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 +#: ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 +#: ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Feil under fjerning av fila: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 +#: ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 +#: ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 +#: ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 +#: ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Ukjend val «%s»" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +#, fuzzy +msgid "Socket is already closed" +msgstr "Kjeldestraumen er allereie stengt" + +#: ../gio/gsocket.c:298 +#: ../gio/gsocket.c:2798 +#: ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Feil ved lesing frÃ¥ fila: %s" + +#: ../gio/gsocket.c:498 +#: ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Klarte ikkje Ã¥ laga papirkorgmappa %s: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Feil ved skriving til fila: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Feil under konvertering: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Feil ved trunkering av fila: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Feil ved opning av fila: %s" + +#: ../gio/gsocket.c:1738 +#: ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Klarte ikkje Ã¥ kassera fila: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Feil under fjerning av fila: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Feil ved opning av fila: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Klarte ikkje Ã¥ laga papirkorgmappa %s: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Feil ved stenging av fila: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 +#: ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Feil ved opning av fila: %s" + +#: ../gio/gsocket.c:3081 +#, fuzzy +msgid "GSocketControlMessage not supported on windows" +msgstr "Ã¥ endra assosiasjonar er ikkje støtta pÃ¥ win32" + +#: ../gio/gsocket.c:3358 +#: ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Feil under fjerning av fila: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 +#: ../gio/gsocketclient.c:1368 +#, fuzzy +msgid "Unknown error on connect" +msgstr "ukjend feil" + +#: ../gio/gsocketclient.c:836 +#: ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 +#: ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Symbolske lenkjer er ikkje støtta" + +#: ../gio/gsocketlistener.c:191 +#, fuzzy +msgid "Listener is already closed" +msgstr "Straumen er allereie stengt" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 +#: ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "The SOCKSv5 proxy requires an authentication method that is not supported by GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "This is the last chance to enter the password correctly before your access is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "Several password entered have been incorrect, and your access will be locked out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 +#: ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 +#: ../gio/gunixconnection.c:531 +#, fuzzy +msgid "Unexpected type of ancillary data" +msgstr "Uventa tidleg slutt pÃ¥ straumen" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Feil ved opning av fila: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "Unexpected option length while checking if SO_PASSCRED is enabled for socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Feil ved namnebyte pÃ¥ fila: %s" + +#: ../gio/gunixconnection.c:509 +msgid "Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 +#: ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "Feil ved lesing frÃ¥ unix: %s" + +#: ../gio/gunixinputstream.c:421 +#: ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 +#: ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "Feilved lukking av: %s" + +#: ../gio/gunixmounts.c:1900 +#: ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "Filsystemrot" + +#: ../gio/gunixoutputstream.c:353 +#: ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "Feil under skriving til unix: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "volumet støttar ikkje Ã¥ løysa ut" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +#, fuzzy +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "volumet støttar ikkje Ã¥ løysa ut" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "Kan ikkje finna programmet" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "Feil under oppstart av programmet: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "URI-ar er ikkje støtta" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "Ã¥ endra assosiasjonar er ikkje støtta pÃ¥ win32" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "Ã… laga assosiasjonar er ikkje støtta pÃ¥ win32" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Feil ved lesing frÃ¥ fila: %s" + +#: ../gio/gwin32inputstream.c:348 +#: ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Feil ved stenging av fila: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Feil ved skriving til fila: %s" + +#: ../gio/gzlibcompressor.c:396 +#: ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "tom for minne" + +#: ../gio/gzlibcompressor.c:403 +#: ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "intern feil" + +#: ../gio/gzlibcompressor.c:416 +#: ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Ugyldig vertsnamn" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Kan ikkje flytta mappa over ei mappe" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Ugyldig sekvens i inndata-konvertering" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "NÃ¥dd maksgrensa for dataarray" + +#~ msgid "do not hide entries" +#~ msgstr "ikkje gøym oppføringar" + +#~ msgid "use a long listing format" +#~ msgstr "bruk langt listeformat" + +#~ msgid "[FILE...]" +#~ msgstr "[FIL ...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Teiknet «%s» er ikkje gyldig pÃ¥ byrjinga av eit entitetsnamn; &-teiknet " +#~ "opnar ein entitet; om dette et-teiknet ikkje er meint Ã¥ vere ein entitet, " +#~ "skriv den som &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Tom teiknreferanse, bør innehalda eit nummer slik som dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Referansen til entiteten er uferdig" + +#~ msgid "Unfinished character reference" +#~ msgstr "Referansen til teiknet er uferdig" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Ugyldig UTF-8-koda tekst - for lang sekvens" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Ugyldig UTF-8-koda tekst - ikkje eit startteikn" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Vertsnamnet i URIen «%s» er ugyldig" + +#, fuzzy +#~ msgid "name" +#~ msgstr "Utan namn" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Vertsnamnet i URIen «%s» er ugyldig" + +#, fuzzy +#~ msgid "names" +#~ msgstr "Utan namn" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Feil under lesing av info om fildeskriptoren: %s" diff --git a/po/oc.po b/po/oc.po new file mode 100644 index 0000000..7d1bb6c --- /dev/null +++ b/po/oc.po @@ -0,0 +1,7028 @@ +# Occitan translation of glib. +# Copyright (C) 2001-2015 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Yannig Marchegay (Kokoyaya) , 2007. +# Cédric Valmary (totenoc.eu) , 2016. +# Cédric VALMARY , 2016. +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2021-11-24 10:24+0000\n" +"PO-Revision-Date: 2021-12-02 16:04+0100\n" +"Last-Translator: Quentin PAGÈS\n" +"Language-Team: Tot en òc (totenoc.eu)\n" +"Language: oc\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 3.0\n" +"X-Launchpad-Export-Date: 2016-10-11 14:28+0000\n" +"X-Project-Style: gnome\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opcions GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Afichar las opcions GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Entrar dins lo mòde de servici GApplication (utilizar a partir dels fichièrs " +"de servici D-Bus)" + +#: gio/gapplication.c:557 +#, fuzzy +#| msgid "Override the application's ID" +msgid "Override the application’s ID" +msgstr "Restablir los ID de l'aplicacion" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:572 +msgid "Print help" +msgstr "Afichar l'ajuda" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMANDA]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Afichar la version" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:578 +msgid "Print version information and exit" +msgstr "Afichar las informacions de version e quitar" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Listar las aplicacions" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Afichar la lista de las aplicacions installadas activablas per D-Bus (per " +"fichièrs .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Aviar una aplicacion" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Aviar l'aplicacion (amb d'eventuals fichièrs de dobrir)" + +#: gio/gapplication-tool.c:59 +#, fuzzy +#| msgid "APPID [FILE...]" +msgid "APPID [FILE…]" +msgstr "ID_APP [FICHIÈR...]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Activar una accion" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invocar una accion sus l'aplicacion" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ID_APP ACCION [PARAMÈTRE]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Afichar las accions disponiblas" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"Afichar la lista de las accions estaticas d'una aplicacion (a partir del " +"fichièr .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ID_APP" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMANDA" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "La comanda per la quala l'ajuda detalhada deu èsser afichada" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Identificant d'aplicacion al format D-Bus (ex. : org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FICHIÈR" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Noms de fichièrs relatius o absoluts o URI de dobrir" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACCION" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Nom de l'accion d'invocar" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMÈTRE" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Paramètre facultatiu per l'invocacion de l'accion, al format GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:664 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Comanda desconeguda %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Utilizacion :\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:699 +msgid "Arguments:\n" +msgstr "Paramètres :\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[PARAMS…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Comandas :\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, fuzzy, c-format +#| msgid "" +#| "Use '%s help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilizatz « %s help COMANDA » per obténer de l'ajuda detalhada.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"La comanda %s exigís un identificant d'aplicacion de seguir dirèctament\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "identificant d'aplicacion invalid : « %s »\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"« %s » accèpta pas cap de paramètre\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "impossible de se connectar a D-Bus : %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "error de mandadís del messatge %s a l'aplicacion : %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "un nom d'accion deu èsser indicat aprèp l'identificant d'aplicacion\n" + +#: gio/gapplication-tool.c:327 +#, fuzzy, c-format +#| msgid "" +#| "invalid action name: '%s'\n" +#| "action names must consist of only alphanumerics, '-' and '.'\n" +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nom d'accion invalid : « %s »\n" +"los noms d'accions pòdon pas conténer que de caractèrs alfanumerics, « - » e " +"« . »\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "error d'analisi del paramètre d'accion : %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "las accions accèptan pas mai d'un paramètre\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "la comanda list-actions accèpta pas que l'identificant de l'aplicacion" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "impossible de trobar lo fichièr desktop per l'aplicacion %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"comanda pas reconeguda : %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "La valor de comptage provesida a %s es tròp granda" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Lo posicionament es pas pres en carga sul flux de basa" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Impossible de troncar GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Lo flux es ja tampat" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "La troncadura es pas presa en carga sul flux de basa" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1872 gio/gdbusprivate.c:1416 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "L'operacion es estada anullada" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Objècte invalid, non inicializat" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Sequéncia multi-octet incompleta en entrada" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Espaci insufisent dins la destinacion" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "Sequéncia d'octets incorrècta en entrada del convertidor" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Error al moment de la conversion : %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1143 +msgid "Cancellable initialization not supported" +msgstr "Inicializacion anullabla pas presa en carga" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, fuzzy, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "" +"La conversion del jòc de caractèrs « %s » cap a « %s » es pas presa en carga" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Impossible de dobrir lo convertidor de « %s » cap a « %s »" + +#: gio/gcontenttype.c:454 +#, c-format +msgid "%s type" +msgstr "Tipe %s" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Tipe desconegut" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "Tipe de fichièr %s" + +#: gio/gcredentials.c:323 +msgid "GCredentials contains invalid data" +msgstr "" + +#: gio/gcredentials.c:383 gio/gcredentials.c:667 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials es pas implementat sus aqueste sistèma operatiu" + +#: gio/gcredentials.c:538 gio/gcredentials.c:556 +msgid "There is no GCredentials support for your platform" +msgstr "I a pas de presa en carga de GCredentials per vòstra plataforma" + +#: gio/gcredentials.c:607 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"GCredentials conten pas d'identificant de processus sus aqueste sistèma " +"operatiu" + +#: gio/gcredentials.c:661 +msgid "Credentials spoofing is not possible on this OS" +msgstr "L'usurpacion d'identitat es pas possible sus aqueste sistèma operatiu" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Fin precòça de flux inesperada" + +#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322 +#, fuzzy, c-format +#| msgid "Unsupported key '%s' in address entry '%s'" +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Clau « %s » pas presa en carga dins l'element d'adreça « %s »" + +#: gio/gdbusaddress.c:172 +#, fuzzy, c-format +#| msgid "Meaningless key/value pair combination in address entry '%s'" +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" +"Combinason clau/valor sens significacion dins l'element d'adreça « %s »" + +#: gio/gdbusaddress.c:181 +#, fuzzy, c-format +#| msgid "" +#| "Address '%s' is invalid (need exactly one of path, tmpdir or abstract " +#| "keys)" +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"L'adreça « %s » es pas valida (necessita exactement una de las claus de « " +"path », « tmpdir » o « abstract »)" + +#: gio/gdbusaddress.c:248 gio/gdbusaddress.c:259 gio/gdbusaddress.c:274 +#: gio/gdbusaddress.c:337 gio/gdbusaddress.c:348 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Error dins l'adreça « %s » — l'atribut « %s » es mal format" + +#: gio/gdbusaddress.c:418 gio/gdbusaddress.c:682 +#, fuzzy, c-format +#| msgid "Unknown or unsupported transport '%s' for address '%s'" +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transpòrt « %s » desconegut o pas pres en carga per l'adreça « %s »" + +#: gio/gdbusaddress.c:462 +#, fuzzy, c-format +#| msgid "Address element '%s' does not contain a colon (:)" +msgid "Address element “%s†does not contain a colon (:)" +msgstr "L'element d'adreça « %s » compòrta pas de caractèr dos-punts (:)" + +#: gio/gdbusaddress.c:471 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:492 +#, fuzzy, c-format +#| msgid "" +#| "Key/Value pair %d, '%s', in address element '%s' does not contain an " +#| "equal sign" +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Lo parelh clau/valor %d, « %s », dins l'element d'adreça « %s » compòrta pas " +"de signe egal" + +#: gio/gdbusaddress.c:503 +#, fuzzy, c-format +#| msgid "" +#| "Key/Value pair %d, '%s', in address element '%s' does not contain an " +#| "equal sign" +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Lo parelh clau/valor %d, « %s », dins l'element d'adreça « %s » compòrta pas " +"de signe egal" + +#: gio/gdbusaddress.c:517 +#, fuzzy, c-format +#| msgid "" +#| "Error unescaping key or value in Key/Value pair %d, '%s', in address " +#| "element '%s'" +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Error al moment del desencodatge de la clau o de la valor dins lo couple " +"clau/valor %d, « %s », dins l'element d'adreça « %s »" + +#: gio/gdbusaddress.c:589 +#, fuzzy, c-format +#| msgid "" +#| "Error in address '%s' - the unix transport requires exactly one of the " +#| "keys 'path' or 'abstract' to be set" +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Error dins l'adreça « %s » — lo transpòrt Unix requerís que siá exactement " +"definida una de las claus « path » o « abstract »" + +#: gio/gdbusaddress.c:625 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the host attribute is missing or malformed" +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Error dins l'adreça « %s » — l'atribut de l'òste es mancant o mal format" + +#: gio/gdbusaddress.c:639 +#, fuzzy, c-format +#| msgid "Error in address '%s' - the port attribute is missing or malformed" +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Error dins l'adreça « %s » — l'atribut del pòrt es mancant o mal format" + +#: gio/gdbusaddress.c:653 +#, fuzzy, c-format +#| msgid "" +#| "Error in address '%s' - the noncefile attribute is missing or malformed" +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Error dins l'adreça « %s » — l'atribut del fichièr de denominacion unica es " +"mancant o mal format" + +#: gio/gdbusaddress.c:674 +msgid "Error auto-launching: " +msgstr "Error d'aviada automatica : " + +#: gio/gdbusaddress.c:727 +#, fuzzy, c-format +#| msgid "Error opening nonce file '%s': %s" +msgid "Error opening nonce file “%sâ€: %s" +msgstr "" +"Error al moment de la dobertura del fichièr de denominacion unica « %s » : %s" + +#: gio/gdbusaddress.c:746 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s': %s" +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Error de lectura del fichièr de denominacion unica « %s » : %s" + +#: gio/gdbusaddress.c:755 +#, fuzzy, c-format +#| msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Error de lectura del fichièr de denominacion unica « %s », 16 octets " +"esperats, %d recebuts" + +#: gio/gdbusaddress.c:773 +#, fuzzy, c-format +#| msgid "Error writing contents of nonce file '%s' to stream:" +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Error d'escritura del contengut del fichièr a numerotacion unica « %s » sul " +"flux :" + +#: gio/gdbusaddress.c:988 +msgid "The given address is empty" +msgstr "L'adreça indicada es voida" + +#: gio/gdbusaddress.c:1101 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "" +"Impossible de generar dinamicament un bus messatges quand la bandièra setuid " +"es mis" + +#: gio/gdbusaddress.c:1108 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Impossible de generar dinamicament un bus messatges sens identificant " +"maquina : " + +#: gio/gdbusaddress.c:1115 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Impossible d'aviar automaticament D-Bus sens $DISPLAY X11" + +#: gio/gdbusaddress.c:1157 +#, fuzzy, c-format +#| msgid "Error spawning command line '%s': " +msgid "Error spawning command line “%sâ€: " +msgstr "Error al moment de la generacion de la linha de comanda « %s » : " + +#: gio/gdbusaddress.c:1226 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Impossible de determinar l'adreça del bus de session (pas pres en carga per " +"aqueste sistèma operatiu)" + +#: gio/gdbusaddress.c:1375 gio/gdbusconnection.c:7261 +#, fuzzy, c-format +#| msgid "" +#| "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#| "variable - unknown value '%s'" +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Impossible de determinar l'adreça del bus a partir de la variabla " +"d'environament DBUS_STARTER_BUS_TYPE — valor desconeguda « %s »" + +#: gio/gdbusaddress.c:1384 gio/gdbusconnection.c:7270 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Impossible de determinar l'adreça del bus donat que la variabla " +"d'environament DBUS_STARTER_BUS_TYPE es pas definida" + +#: gio/gdbusaddress.c:1394 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipe de bus %d desconegut" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "" +"Manca de contengut imprevist al moment de la temptativa de lectura d'una " +"linha" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Manca de contengut imprevist al moment de la temptativa de lectura " +"(securizada) d'una linha" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Totes los mecanismes d'autentificacion disponibles son estats agotats " +"(temptats : %s) (disponibles : %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Anullat via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:298 +#, fuzzy, c-format +#| msgid "Error when getting information for directory '%s': %s" +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "" +"Error al moment de la recuperacion d'informacion sul repertòri « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:313 +#, fuzzy, c-format +#| msgid "" +#| "Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Los dreits d'accès al repertòri « %s » son mal formats. Mòde 0700 esperat, " +"0%o obtengut" + +#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Error a la creacion del repertòri « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1062 gio/gfile.c:1300 +#: gio/gfile.c:1438 gio/gfile.c:1676 gio/gfile.c:1731 gio/gfile.c:1789 +#: gio/gfile.c:1873 gio/gfile.c:1930 gio/gfile.c:1994 gio/gfile.c:2049 +#: gio/gfile.c:3754 gio/gfile.c:3809 gio/gfile.c:4102 gio/gfile.c:4572 +#: gio/gfile.c:4983 gio/gfile.c:5068 gio/gfile.c:5158 gio/gfile.c:5255 +#: gio/gfile.c:5342 gio/gfile.c:5443 gio/gfile.c:8153 gio/gfile.c:8243 +#: gio/gfile.c:8327 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operacion pas presa en carga" + +#: gio/gdbusauthmechanismsha1.c:402 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for reading: " +msgid "Error opening keyring “%s†for reading: " +msgstr "" +"Error al moment de la dobertura del trossèl de claus « %s » en lectura : " + +#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747 +#, fuzzy, c-format +#| msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"La linha %d del trossèl de claus de « %s » amb lo contengut « %s » es mal " +"formada" + +#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761 +#, fuzzy, c-format +#| msgid "" +#| "First token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Lo primièr geton de la linha %d del trossèl de claus de « %s » amb lo " +"contengut « %s » es mal format" + +#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775 +#, fuzzy, c-format +#| msgid "" +#| "Second token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Lo segond geton de la linha %d del trossèl de claus de « %s » amb lo " +"contengut « %s » es mal format" + +#: gio/gdbusauthmechanismsha1.c:477 +#, fuzzy, c-format +#| msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "" +"Impossible de trobar un cookie amb l'identificant %d dins lo trossèl de " +"claus de « %s »" + +#: gio/gdbusauthmechanismsha1.c:523 +#, fuzzy, c-format +#| msgid "Error creating lock file '%s': %s" +msgid "Error creating lock file “%sâ€: %s" +msgstr "Error al moment de la creacion del fichièr verrolh « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:587 +#, fuzzy, c-format +#| msgid "Error deleting stale lock file '%s': %s" +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "" +"Error al moment de la destruccion de l'ancian fichièr verrolh « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:626 +#, fuzzy, c-format +#| msgid "Error closing (unlinked) lock file '%s': %s" +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "" +"Error al moment de la tampadura del fichièr verrolh (non ligat) « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:637 +#, fuzzy, c-format +#| msgid "Error unlinking lock file '%s': %s" +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "" +"Error al moment de la supression del ligam amb lo fichièr verrolh « %s » : %s" + +#: gio/gdbusauthmechanismsha1.c:714 +#, fuzzy, c-format +#| msgid "Error opening keyring '%s' for writing: " +msgid "Error opening keyring “%s†for writing: " +msgstr "" +"Error al moment de la dobertura del trossèl de claus « %s » en escritura : " + +#: gio/gdbusauthmechanismsha1.c:908 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "" +"(en otra, lo relèvament del verrolh per « %s » a fracassat tanben : %s) " + +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2417 +msgid "The connection is closed" +msgstr "La connexion es tampada" + +#: gio/gdbusconnection.c:1902 +msgid "Timeout was reached" +msgstr "Lo relambi d'espèra es depassat" + +#: gio/gdbusconnection.c:2540 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Marcadors pas preses en carga rencontrats al moment de la construccion d'una " +"connexion costat client" + +#: gio/gdbusconnection.c:4189 gio/gdbusconnection.c:4536 +#, fuzzy, c-format +#| msgid "" +#| "No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Pas d'interfàcia « org.freedesktop.DBus.Properties » per l'objècte a " +"l'emplaçament %s" + +#: gio/gdbusconnection.c:4331 +#, c-format +msgid "No such property “%sâ€" +msgstr "La proprietat « %s » existís pas" + +#: gio/gdbusconnection.c:4343 +#, c-format +msgid "Property “%s†is not readable" +msgstr "La proprietat « %s » se pòt pas legir" + +#: gio/gdbusconnection.c:4354 +#, c-format +msgid "Property “%s†is not writable" +msgstr "La proprietat « %s » se pòt pas escriure" + +#: gio/gdbusconnection.c:4374 +#, fuzzy, c-format +#| msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Error al moment de la definicion de la proprietat « %s » : tipe esperat « %s " +"», « %s » obtengut" + +#: gio/gdbusconnection.c:4479 gio/gdbusconnection.c:4687 +#: gio/gdbusconnection.c:6689 +#, fuzzy, c-format +#| msgid "No such interface '%s'" +msgid "No such interface “%sâ€" +msgstr "L'interfàcia « %s » existís pas" + +#: gio/gdbusconnection.c:4905 gio/gdbusconnection.c:7201 +#, fuzzy, c-format +#| msgid "No such interface '%s' on object at path %s" +msgid "No such interface “%s†on object at path %s" +msgstr "L'interfàcia « %s » existís pas per l'objècte a l'emplaçament %s" + +#: gio/gdbusconnection.c:5003 +#, fuzzy, c-format +#| msgid "No such method '%s'" +msgid "No such method “%sâ€" +msgstr "Lo metòde « %s » existís pas" + +#: gio/gdbusconnection.c:5034 +#, fuzzy, c-format +#| msgid "Type of message, '%s', does not match expected type '%s'" +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Lo tipe del messatge, « %s », correspond pas al tipe esperat « %s »" + +#: gio/gdbusconnection.c:5237 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Un objècte es ja exportat per l'interfàcia « %s » en « %s »" + +#: gio/gdbusconnection.c:5463 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Impossible d'obténer la proprietat %s.%s" + +#: gio/gdbusconnection.c:5519 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Impossible de definir la proprietat %s.%s" + +#: gio/gdbusconnection.c:5698 +#, fuzzy, c-format +#| msgid "Method '%s' returned type '%s', but expected '%s'" +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Lo metòde « %s » a renviat lo tipe « %s », mas « %s » èra esperat" + +#: gio/gdbusconnection.c:6800 +#, fuzzy, c-format +#| msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "" +"Lo metòde « %s » sus l'interfàcia « %s » amb la signatura « %s » existís pas" + +#: gio/gdbusconnection.c:6921 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Una sosarborescéncia es ja exportada per « %s »" + +#: gio/gdbusconnection.c:7209 +#, fuzzy, c-format +#| msgid "Key file does not have group '%s'" +msgid "Object does not exist at path “%sâ€" +msgstr "Lo fichièr de claus a pas de grop « %s »" + +#: gio/gdbusmessage.c:1311 +msgid "type is INVALID" +msgstr "lo tipe es « INVALID »" + +#: gio/gdbusmessage.c:1322 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Messatge de METHOD_CALL : camp d'entèsta PATH o MEMBER mancant" + +#: gio/gdbusmessage.c:1333 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Messatge de METHOD_RETURN : camp d'entèsta REPLY_SERIAL mancant" + +#: gio/gdbusmessage.c:1345 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Messatge d'ERROR : camp d'entèsta REPLY_SERIAL o ERROR_NAME mancant" + +#: gio/gdbusmessage.c:1358 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Messatge de SIGNAL : camp d'entèsta PATH, INTERFACE o MEMBER mancant" + +#: gio/gdbusmessage.c:1366 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Messatge de SIGNAL : lo camp d'entèsta PATH utiliza la valor reservada /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1374 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Messatge de SIGNAL : lo camp d'entèsta INTERFACE utiliza la valor reservada " +"org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1422 gio/gdbusmessage.c:1482 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Lectura de %lu octet demandada, mas solament %lu recebut(s)" +msgstr[1] "Lectura de %lu octets demandada, mas solament %lu recebut(s)" + +#: gio/gdbusmessage.c:1436 +#, fuzzy, c-format +#| msgid "Expected NUL byte after the string '%s' but found byte %d" +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"Octet 00 (NUL) esperat a la fin de la cadena « %s » mas un octet %d es estat " +"trobat" + +#: gio/gdbusmessage.c:1455 +#, fuzzy, c-format +#| msgid "" +#| "Expected valid UTF-8 string but found invalid bytes at byte offset %d " +#| "(length of string is %d). The valid UTF-8 string up until that point was " +#| "'%s'" +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Una cadena UTF-8 valida es esperada mas d'octets invalids son rencontrats a " +"la posicion %d (longor de la cadena : %d octets). La cadena UTF-8 valida " +"fins a aqueste endreit es « %s »" + +#: gio/gdbusmessage.c:1519 gio/gdbusmessage.c:1795 gio/gdbusmessage.c:1986 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1687 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus object path" +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "La valor analisada « %s » es pas un camin cap a un objècte D-Bus valid" + +#: gio/gdbusmessage.c:1711 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus signature" +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "La valor analisada « %s » es pas una signatura D-Bus valida" + +# 2<<26 donne 128 Mo, 2^26 donne 64 Mo, 1<<26 donne 64 Mo +#: gio/gdbusmessage.c:1762 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Un tablèu de %u octet de long es estat trobat. La longor maximala es de " +"2<<26 octets (64 Mo)." +msgstr[1] "" +"Un tablèu de %u octets de long es estat trobat. La longor maximala es de " +"2<<26 octets (64 Mo)." + +#: gio/gdbusmessage.c:1782 +#, fuzzy, c-format +#| msgid "" +#| "Encountered array of type 'a%c', expected to have a length a multiple of " +#| "%u bytes, but found to be %u bytes in length" +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Un tablèu de tipe « a%c » es estat trobat, amb una longor esperada multipla " +"de %u octets, mas la longor vertadièra es de %u octets" + +#: gio/gdbusmessage.c:1970 +#, fuzzy, c-format +#| msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"La valor « %s » analisada en tant que variant es pas una signatura valida de " +"D-Bus" + +#: gio/gdbusmessage.c:2011 +#, fuzzy, c-format +#| msgid "" +#| "Error deserializing GVariant with type string '%s' from the D-Bus wire " +#| "format" +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Error en deserializant lo GVariant en cadena de tipe « %s » a partir del " +"format de transmission D-Bus" + +#: gio/gdbusmessage.c:2196 +#, fuzzy, c-format +#| msgid "" +#| "Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found " +#| "value 0x%02x" +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valor de boutisme invalida. 0x6c (« l ») o 0x42 (« B ») esperats, mas 0x%02x " +"trobat" + +#: gio/gdbusmessage.c:2215 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Version majeure del protocòl invalida. 1 esperat, %d trobat" + +#: gio/gdbusmessage.c:2273 gio/gdbusmessage.c:2862 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2285 +#, fuzzy, c-format +#| msgid "Signature header with signature '%s' found but message body is empty" +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Entèsta de signatura trobat amb la signatura « %s », mas lo còs del messatge " +"es void" + +#: gio/gdbusmessage.c:2300 +#, fuzzy, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"La valor analisada « %s » es pas una signatura valida de D-Bus (per lo còs)" + +#: gio/gdbusmessage.c:2332 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Pas de signatura d'entèsta dins lo messatge, mas lo còs del messatge es de " +"%u octet" +msgstr[1] "" +"Pas de signatura d'entèsta dins lo messatge, mas lo còs del messatge es de " +"%u octets" + +#: gio/gdbusmessage.c:2342 +msgid "Cannot deserialize message: " +msgstr "Impossible de deserializar lo messatge : " + +#: gio/gdbusmessage.c:2679 +#, fuzzy, c-format +#| msgid "" +#| "Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Error en serializant lo GVariant en cadena de tipe « %s » dins lo format de " +"transmission D-Bus" + +#: gio/gdbusmessage.c:2816 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2824 +msgid "Cannot serialize message: " +msgstr "Impossible de serializar lo messatge : " + +#: gio/gdbusmessage.c:2877 +#, fuzzy, c-format +#| msgid "Message body has signature '%s' but there is no signature header" +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Lo còs del messatge a la signatura « %s », mas i a pas d'entèsta de signatura" + +#: gio/gdbusmessage.c:2887 +#, fuzzy, c-format +#| msgid "" +#| "Message body has type signature '%s' but signature in the header field is " +#| "'%s'" +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Lo còs del messatge a una signatura de tipe « %s », mas la qu'es dins lo " +"camp d'entèsta es « %s »" + +#: gio/gdbusmessage.c:2903 +#, fuzzy, c-format +#| msgid "Message body is empty but signature in the header field is '(%s)'" +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"Lo còs del messatge es void mas sa signatura dins lo camp d'entèsta es " +"« (%s) »" + +#: gio/gdbusmessage.c:3458 +#, fuzzy, c-format +#| msgid "Error return with body of type '%s'" +msgid "Error return with body of type “%sâ€" +msgstr "Retorn d'error amb un còs de tipe « %s »" + +#: gio/gdbusmessage.c:3466 +msgid "Error return with empty body" +msgstr "Retorn d'error amb un còs void" + +#: gio/gdbusprivate.c:2246 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(sasissètz quin caractèr que siá per tampar aquesta fenèstra)\n" + +#: gio/gdbusprivate.c:2420 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"La session dbus es pas aviada e autolaunch (l'aviada automatica) a fracassat" + +#: gio/gdbusprivate.c:2443 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Impossible d'obténer lo perfil material : %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2494 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Cargament impossible de %s o %s : " + +#: gio/gdbusproxy.c:1569 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Error al moment de l'apèl de StartServiceByName per %s : " + +# Guillemets anglais laissés volontairement +#: gio/gdbusproxy.c:1592 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Responsa %d inesperada del metòde StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2699 gio/gdbusproxy.c:2834 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Impossible d'apelar lo metòde ; lo servidor es mandatari d'un nom %s conegut " +"sens proprietari mentre que lo proxy es estat construit amb lo marcador " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +#, fuzzy +#| msgid "Abstract name space not supported" +msgid "Abstract namespace not supported" +msgstr "L'espaci de noms abstrait es pas pres en carga" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Impossible de definir un fichièr de denominacion unica al moment de la " +"creacion d'un servidor" + +#: gio/gdbusserver.c:942 +#, fuzzy, c-format +#| msgid "Error writing nonce file at '%s': %s" +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "" +"Error al moment de l'escritura del fichièr de denominacion unica a « %s » : " +"%s" + +#: gio/gdbusserver.c:1117 +#, fuzzy, c-format +#| msgid "The string '%s' is not a valid D-Bus GUID" +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "La cadena « %s » es pas un GUID valid de D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Impossible d’escotar sul transpòrt « %s » pas pres en carga" + +#: gio/gdbus-tool.c:111 +#, fuzzy, c-format +#| msgid "" +#| "Commands:\n" +#| " help Shows this information\n" +#| " introspect Introspect a remote object\n" +#| " monitor Monitor a remote object\n" +#| " call Invoke a method on a remote object\n" +#| " emit Emit a signal\n" +#| "\n" +#| "Use \"%s COMMAND --help\" to get help on each command.\n" +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Comandas :\n" +" help Aficha la presenta informacion\n" +" introspect Inspècta la constitucion d'un objècte distant\n" +" monitor Susvelha un objècte distant\n" +" call Apèla un metòde sus un objècte distant\n" +" emit Emet un senhal\n" +"\n" +"Utilizar « %s COMANDA --help » per obténer una ajuda sus cada comanda.\n" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1236 +#: gio/gdbus-tool.c:1724 +#, c-format +msgid "Error: %s\n" +msgstr "Error : %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1740 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Error al moment de l'analisi del XML d'introspection : %s\n" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Error : %s es pas un nom valid\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1060 +#: gio/gdbus-tool.c:1890 gio/gdbus-tool.c:2130 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Error : « %s » es pas un camin d'objècte valid\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "Connexion al bus sistèma" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "Connexion al bus de session" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "Connexion a l'adreça D-Bus donada" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "Opcions de connexion al punt terminal :" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "Opcions que definisson la connexion al punt terminal" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "Cap de punt terminal de connexion pas definit" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Mantun punt terminals de connexion definits" + +#: gio/gdbus-tool.c:522 +#, fuzzy, c-format +#| msgid "" +#| "Warning: According to introspection data, interface '%s' does not exist\n" +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Avertiment : segon las donadas de l'examèn intèrne, l'interfàcia « %s » " +"existís pas\n" + +#: gio/gdbus-tool.c:531 +#, fuzzy, c-format +#| msgid "" +#| "Warning: According to introspection data, method '%s' does not exist on " +#| "interface '%s'\n" +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Avertiment : segon las donadas de l'examèn intèrne, lo metòde « %s » existís " +"pas sus l'interfàcia « %s »\n" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "Destinacion facultativa pel senhal (nom unic)" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "Camin de l'objècte sul qual émetra lo senhal" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "Noms de senhal e d'interfàcia" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "Emet un senhal." + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:997 gio/gdbus-tool.c:1827 +#: gio/gdbus-tool.c:2059 gio/gdbus-tool.c:2279 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Error de connexion : %s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Error : %s es pas un nom unic de bus valid.\n" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1870 +msgid "Error: Object path is not specified\n" +msgstr "Error : lo camin per l'objècte es pas precisat\n" + +#: gio/gdbus-tool.c:765 +#, fuzzy +#| msgid "Error: Method name is not specified\n" +msgid "Error: Signal name is not specified\n" +msgstr "Error : lo nom del metòde es pas definit\n" + +#: gio/gdbus-tool.c:779 +#, fuzzy, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Error : lo nom de metòde « %s » es pas valid\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Error : %s es pas un nom d'interfàcia valida\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Error : %s es pas un nom de membre valid\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1172 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Error al moment de l'analisi del paramètre %d : %s\n" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Error de purge de la connexion : %s\n" + +#: gio/gdbus-tool.c:893 +msgid "Destination name to invoke method on" +msgstr "Nom de la destinacion sus la quala apelar un metòde" + +#: gio/gdbus-tool.c:894 +msgid "Object path to invoke method on" +msgstr "Camin de l'objècte sul qual apelar un metòde" + +#: gio/gdbus-tool.c:895 +msgid "Method and interface name" +msgstr "Noms de metòde e d'interfàcia" + +#: gio/gdbus-tool.c:896 +msgid "Timeout in seconds" +msgstr "Relambi d'espèra en segondas" + +#: gio/gdbus-tool.c:942 +msgid "Invoke a method on a remote object." +msgstr "Apelar un metòde sus un objècte distant." + +#: gio/gdbus-tool.c:1014 gio/gdbus-tool.c:1844 gio/gdbus-tool.c:2084 +msgid "Error: Destination is not specified\n" +msgstr "Error : la destinacion es pas precisada\n" + +#: gio/gdbus-tool.c:1025 gio/gdbus-tool.c:1861 gio/gdbus-tool.c:2095 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Error : %s es pas un nom de bus valid\n" + +#: gio/gdbus-tool.c:1075 +msgid "Error: Method name is not specified\n" +msgstr "Error : lo nom del metòde es pas definit\n" + +#: gio/gdbus-tool.c:1086 +#, fuzzy, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Method name “%s†is invalid\n" +msgstr "Error : lo nom de metòde « %s » es pas valid\n" + +#: gio/gdbus-tool.c:1164 +#, fuzzy, c-format +#| msgid "Error parsing parameter %d of type '%s': %s\n" +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Error d'analisi del paramètre %d de tipe « %s » : %s\n" + +#: gio/gdbus-tool.c:1190 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Error d'apondon de l'identificador %d : %s\n" + +#: gio/gdbus-tool.c:1686 +msgid "Destination name to introspect" +msgstr "Nom de la destinacion d'examinar en intèrne" + +#: gio/gdbus-tool.c:1687 +msgid "Object path to introspect" +msgstr "Camin de l'objècte d'examinar en intèrne" + +#: gio/gdbus-tool.c:1688 +msgid "Print XML" +msgstr "Imprimir lo XML" + +#: gio/gdbus-tool.c:1689 +msgid "Introspect children" +msgstr "Examinar en intèrne los enfants" + +#: gio/gdbus-tool.c:1690 +msgid "Only print properties" +msgstr "Afichar pas que las proprietats" + +#: gio/gdbus-tool.c:1779 +msgid "Introspect a remote object." +msgstr "Examinar en intèrne un objècte distant." + +#: gio/gdbus-tool.c:1985 +msgid "Destination name to monitor" +msgstr "Nom de la destinacion de susvelhar" + +#: gio/gdbus-tool.c:1986 +msgid "Object path to monitor" +msgstr "Camin de l'objècte de susvelhar" + +#: gio/gdbus-tool.c:2011 +msgid "Monitor a remote object." +msgstr "Susvelhar un objècte distant." + +#: gio/gdbus-tool.c:2069 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: gio/gdbus-tool.c:2193 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2196 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: gio/gdbus-tool.c:2244 +msgid "[OPTION…] BUS-NAME" +msgstr "" + +#: gio/gdbus-tool.c:2245 +msgid "Wait for a bus name to appear." +msgstr "" + +#: gio/gdbus-tool.c:2321 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to activate for must be specified.\n" +msgstr "Error : lo camin per l'objècte es pas precisat.\n" + +#: gio/gdbus-tool.c:2326 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to wait for must be specified.\n" +msgstr "Error : lo camin per l'objècte es pas precisat.\n" + +#: gio/gdbus-tool.c:2331 +#, fuzzy +#| msgid "Too many arguments" +msgid "Error: Too many arguments.\n" +msgstr "Tròp d'arguments" + +#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346 +#, fuzzy, c-format +#| msgid "Error: %s is not a valid bus name\n" +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Error : %s es pas un nom de bus valid\n" + +#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4935 +msgid "Unnamed" +msgstr "Sens nom" + +# Un fichier Desktop n'est pas forcément sur le bureau... +# Un fichièr Desktop n'est pas forcément sul burèu... +#: gio/gdesktopappinfo.c:2516 +#, fuzzy +#| msgid "Desktop file didn't specify Exec field" +msgid "Desktop file didn’t specify Exec field" +msgstr "Lo fichièr .desktop a pas precisat son camp Exec" + +#: gio/gdesktopappinfo.c:2804 +msgid "Unable to find terminal required for application" +msgstr "Impossible de trobar lo terminal requesit per l'aplicacion" + +#: gio/gdesktopappinfo.c:3455 +#, fuzzy, c-format +#| msgid "Can't create user application configuration folder %s: %s" +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Impossible de crear lo dorsièr de configuracion utilizaire d'aplicacion %s : " +"%s" + +#: gio/gdesktopappinfo.c:3459 +#, fuzzy, c-format +#| msgid "Can't create user MIME configuration folder %s: %s" +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "" +"Impossible de crear lo dorsièr de configuracion utilizaire MIME %s : %s" + +#: gio/gdesktopappinfo.c:3701 gio/gdesktopappinfo.c:3725 +msgid "Application information lacks an identifier" +msgstr "Las informacions de l'aplicacion compòrtan pas d'identificant" + +#: gio/gdesktopappinfo.c:3961 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Impossible de crear lo fichièr .desktop utilizaire %s" + +#: gio/gdesktopappinfo.c:4097 +#, c-format +msgid "Custom definition for %s" +msgstr "Definicion personnalisée per %s" + +#: gio/gdrive.c:417 +#, fuzzy +#| msgid "drive doesn't implement eject" +msgid "drive doesn’t implement eject" +msgstr "lo lector implementa pas l'ejeccion (« eject »)" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +#, fuzzy +#| msgid "drive doesn't implement eject or eject_with_operation" +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" +"lo lector implementa pas l'ejeccion combinada o pas (« eject » o « " +"eject_with_operation »)" + +#: gio/gdrive.c:571 +#, fuzzy +#| msgid "drive doesn't implement polling for media" +msgid "drive doesn’t implement polling for media" +msgstr "lo lector implementa pas l'escrutacion del mèdia (« polling »)" + +#: gio/gdrive.c:778 +#, fuzzy +#| msgid "drive doesn't implement start" +msgid "drive doesn’t implement start" +msgstr "lo lector implementa pas l'aviada (« start »)" + +#: gio/gdrive.c:880 +#, fuzzy +#| msgid "drive doesn't implement stop" +msgid "drive doesn’t implement stop" +msgstr "lo lector implementa pas l'arrèst (« stop »)" + +#: gio/gdtlsconnection.c:1153 gio/gtlsconnection.c:920 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "La presa en carga TLS es pas disponibla" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "La presa en carga DTLS es pas disponibla" + +#: gio/gemblem.c:323 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GEmblem encoding" +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Impossible de gerir la version %d de l'encodatge GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Nombre de getons incorrècte (%d) dins lo encodatge GEmblem" + +#: gio/gemblemedicon.c:362 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GEmblemedIcon encoding" +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Impossible de gerir la version %d de l'encodatge GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Nombre de getons incorrècte (%d) dins lo encodatge GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Un GEmblem es esperat pel GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1561 +msgid "Containing mount does not exist" +msgstr "Lo punt de montatge contenidor existís pas" + +#: gio/gfile.c:2608 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Impossible d’espotir un repertòri" + +#: gio/gfile.c:2668 +msgid "Can’t copy directory over directory" +msgstr "Impossible d’espotir un repertòri per un autre repertòri" + +#: gio/gfile.c:2676 +msgid "Target file exists" +msgstr "Lo fichièr cibla existís" + +#: gio/gfile.c:2695 +msgid "Can’t recursively copy directory" +msgstr "Impossible de copiar recursivament un repertòri" + +# http://en.wikipedia.org/wiki/Splice_(system_call) +#: gio/gfile.c:2996 +msgid "Splice not supported" +msgstr "L'operacion « splice » es pas presa en carga" + +#: gio/gfile.c:3000 +#, c-format +msgid "Error splicing file: %s" +msgstr "Error al moment de l'operacion de « splicing » sul fichièr : %s" + +#: gio/gfile.c:3152 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "La còpia (reflink/clone) entre punts de montatge es pas presa en carga" + +#: gio/gfile.c:3156 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "La còpia (reflink/clone) es pas presa en carga o es pas valida" + +#: gio/gfile.c:3161 +#, fuzzy +#| msgid "Copy (reflink/clone) is not supported or didn't work" +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "La còpia (reflink/clone) es pas presa en carga o a pas foncionat" + +#: gio/gfile.c:3226 +msgid "Can’t copy special file" +msgstr "Impossible de copiar lo fichièr especial" + +#: gio/gfile.c:4035 +msgid "Invalid symlink value given" +msgstr "Valor de ligam simbolic donada invalida" + +#: gio/gfile.c:4045 glib/gfileutils.c:2355 +msgid "Symbolic links not supported" +msgstr "Ligams simbolics pas preses en carga" + +#: gio/gfile.c:4213 +msgid "Trash not supported" +msgstr "L'escobilhièr es pas presa en carga" + +#: gio/gfile.c:4325 +#, fuzzy, c-format +#| msgid "File names cannot contain '%c'" +msgid "File names cannot contain “%câ€" +msgstr "Los noms de fichièrs pòdon pas comportar de « %c »" + +#: gio/gfile.c:6806 gio/gvolume.c:364 +#, fuzzy +#| msgid "volume doesn't implement mount" +msgid "volume doesn’t implement mount" +msgstr "lo volum implementa pas lo montatge" + +#: gio/gfile.c:6920 gio/gfile.c:6968 +msgid "No application is registered as handling this file" +msgstr "Cap d'aplicacion es pas enregistrada per gerir aqueste fichièr" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "L'enumerador es tampat" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "L'enumerador de fichièrs es en cors d'operacion" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "L'enumerador de fichièrs es ja tampat" + +#: gio/gfileicon.c:250 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GFileIcon encoding" +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Impossible de gerir la version %d de l'encodatge de GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Donadas d'entrada incorrèctas per GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +#, fuzzy +#| msgid "Stream doesn't support query_info" +msgid "Stream doesn’t support query_info" +msgstr "Lo flux pren pas en carga query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Lo posicionament es pas pres en carga sul flux" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "La troncadura es pas autorizada sus un flux d'entrada" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "La troncadura es pas presa en carga sul flux" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:596 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Nom d'òste invalid" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Marrida responsa del mandatari HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Connexion al mandatari HTTP pas autorizada" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "L'autentificacion auprès del mandatari HTTP a fracassat" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Autentificacion obligatòri pel mandatari HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "La connexion al mandatari HTTP a fracassat : %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Reponsa del mandatari HTTP tròp longa" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Lo servidor mandatari HTTP a acabat la connexion d'un biais imprevist." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nombre de getons incorrècte (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Pas cap de tipe pel nom de classa %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Lo tipe %s implementa pas l'interfàcia GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Lo tipe %s es pas classat" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Numèro de version incorrècte : %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" +"Lo tipe %s implementa pas la foncion from_tokens() de l'interfàcia GIcon" + +#: gio/gicon.c:469 +#, fuzzy +#| msgid "Can't handle the supplied version of the icon encoding" +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Impossible de gerir la version provesida de l'encodatge de l'icòna" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Cap d'adreça pas indicada" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "La longor %u es tròp importanta per l'adreça" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "L'adreça possedís de bits definits al delà de la longor del prefix" + +#: gio/ginetaddressmask.c:300 +#, fuzzy, c-format +#| msgid "Could not parse '%s' as IP address mask" +msgid "Could not parse “%s†as IP address mask" +msgstr "Impossible d'analisar « %s » coma masque d'adreça IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "Espaci insufisent per una adreça de connector ret" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Adreça de connector ret pas presa en carga" + +#: gio/ginputstream.c:188 +#, fuzzy +#| msgid "Input stream doesn't implement read" +msgid "Input stream doesn’t implement read" +msgstr "Lo flux en entrada implementa pas « read »" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Lo flux a una operacion en cors" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copiar amb lo fichièr" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Conservar amb lo fichièr al moment del desplaçament" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "« version » accèpta pas cap de paramètre" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Utilizacion :" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Afichar las informacions de version e quitar." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Comandas :" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatenar los fichièrs cap a la sortida estandarda" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copiar un o mantun fichièr" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Afichar l'informacion sus las localizacions" + +#: gio/gio-tool.c:232 +#, fuzzy +#| msgid "List static actions for an application (from .desktop file)" +msgid "Launch an application from a desktop file" +msgstr "" +"Afichar la lista de las accions estaticas d'una aplicacion (a partir del " +"fichièr .desktop)" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Enumerar lo contengut dels emplaçaments" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Obténer o definir lo gestionari d'un tipe MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Crear de repertòris" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Susvelhar las modificacions de fichièrs e de repertòris" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montar o desmontar los emplaçaments" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Desplaçar un o mantun fichièr" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Dobrir de fichièrs amb l'aplicacion per defaut" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Renomenar un fichièr" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Suprimir un o mantun fichièr" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Legir a partir de l'entrada estandard e enregistrar" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Definir un atribut de fichièr" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Desplaçar de fichièrs o repertòris dins l'escobilhièr" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Enumerar lo contengut dels emplaçaments dins una arborescéncia" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Utilizatz « %s » per obténer d'ajuda detalhada.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Error al moment de l’escritura cap a stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCALIZACION" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatenar de fichièrs e afichar cap a la sortida estandarda." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat fonciona coma l'utilitari tradicional cat, mas en\n" +"utilizant d'emplaçaments GIO al luòc de fichièrs locals : per exemple,\n" +"se pòt indicar un emplaçament coma smb://servidor/ressorsa/fichièr.txt." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Cap d'emplaçament pas indicat" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Pas de repertòri cibla" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Afichar la progression" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Demandar abans d'espotir" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Preservar totes los atributs" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Crear un salvament dels fichièrs de destinacion existents" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Seguir pas jamai los ligams simbolics" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%s sus %s transferits (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "FONT" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINACION" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copiar un o mantun fichièr de FONT cap a DESTINACION." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy fonciona coma l'utilitari tradicional cp, mas en\n" +"utilizant d'emplaçaments GIO al luòc de fichièrs locals : per exemple,\n" +"se pòt indicar un emplaçament coma smb://servidor/ressorsa/fichièr.txt." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "La destinacion « %s » es pas un repertòri" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s : remplaçar « %s » ? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Afichar los atributs en escritura" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Obténer las informacions del sistèma de fichièrs" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Los atributs d'obténer" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTS" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +#, fuzzy +#| msgid "Don't follow symbolic links" +msgid "Don’t follow symbolic links" +msgstr "Seguir pas los ligams simbolics" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributs :\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nom d'afichatge : %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "nom d'edicion : %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nom : %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipe : %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "talha : " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "amagat\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri : %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "camin local : %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atributs que pòdon èsser definits :\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Espacis de noms dels atributs en escritura :\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Afichar d'informacions a prepaus dels emplaçaments." + +#: gio/gio-tool-info.c:347 +#, fuzzy +#| msgid "" +#| "gio info is similar to the traditional ls utility, but using GIO\n" +#| "locations instead of local files: for example, you can use something\n" +#| "like smb://server/resource/file.txt as location. File attributes can\n" +#| "be specified with their GIO name, e.g. standard::icon, or just by\n" +#| "namespace, e.g. unix, or by '*', which matches all attributes" +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info fonciona coma l'utilitari tradicional ls, mas en\n" +"utilizant d'emplaçaments GIO al luòc de fichièrs locals : per exemple,\n" +"se pòt indicar un emplaçament coma smb://servidor/ressorsa/fichièr.txt.\n" +"Los atributs de fichièrs pòdon èsser indicats per lor nom GIO (exemple :\n" +"standard::icon), per lor espaci de nom (exemple : unix) o per « * » qui\n" +"correspond a totes los atributs" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Cap de fichièr pas indicat" + +#: gio/gio-tool-launch.c:85 +#, fuzzy +#| msgid "There is no GCredentials support for your platform" +msgid "The launch command is not currently supported on this platform" +msgstr "I a pas de presa en carga de GCredentials per vòstra plataforma" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Cargament impossible de « %s » : %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Impossible d'aviar l'aplicacion « %s » : %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Afichar los fichièrs amagats" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Utilizar una mesa en forma de lista espandida" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Afichar los noms d’afichatge" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Afichar los URI complets" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Enumerar lo contengut dels emplaçaments." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list fonciona coma l'utilitari tradicional ls, mas en\n" +"utilizant d'emplaçaments GIO al luòc de fichièrs locals : per exemple,\n" +"se pòt indicar un emplaçament coma smb://servidor/ressorsa/fichièr.txt.\n" +"Los atributs de fichièrs pòdon èsser indicats per lor nom GIO (exemple :\n" +"standard::icon)" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TIPE_MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "GESTIONARI" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Obten o definís lo gestionari d'un tipe MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Se cap de gestionari es pas indicat, enumèra las aplicacions inscritas\n" +"e recomandadas pel tipe MIME. Se un gestionari es indicat, il est\n" +"défini coma gestionari per defaut pel tipe MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Un seul tipe MIME deu èsser indicat, e potencialament un gestionari" + +#: gio/gio-tool-mime.c:116 +#, fuzzy, c-format +#| msgid "No default applications for '%s'\n" +msgid "No default applications for “%sâ€\n" +msgstr "Pas d'aplicacions per defaut per « %s »\n" + +#: gio/gio-tool-mime.c:122 +#, fuzzy, c-format +#| msgid "Default application for '%s': %s\n" +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplicacion per defaut per « %s » : %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplicacions enregistradas :\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Pas d'aplicacions enregistradas\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplicacions recomandadas :\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Pas d'aplicacions recomandadas :\n" + +#: gio/gio-tool-mime.c:162 +#, fuzzy, c-format +#| msgid "Failed to load info for handler '%s'\n" +msgid "Failed to load info for handler “%sâ€" +msgstr "Lo cargament de las informacions del gestionari « %s » a fracassat\n" + +#: gio/gio-tool-mime.c:168 +#, fuzzy, c-format +#| msgid "Failed to set '%s' as the default handler for '%s': %s\n" +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"La definicion de « %s » coma gestionari per defaut per « %s » a fracassat : " +"%s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Crear de repertòris parents" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Crear de repertòris." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir fonciona coma l'utilitari tradicional mkdir, mas en\n" +"utilizant d'emplaçaments GIO al luòc de fichièrs locals : per exemple,\n" +"se pòt indicar un emplaçament coma smb://servidor/ressorsa/repertòri." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Susvelha un repertòri (per defaut : en foncion del tipe)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Susvelha un fichièr (per defaut : en foncion del tipe)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Susvelha un fichièr dirèctament (detècta las modificacions per ligams durs)" + +#: gio/gio-tool-monitor.c:43 +#, fuzzy +#| msgid "Monitors a file directly, but doesn't report changes" +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Susvelha un fichièr dirèctament, mas senhala pas las modificacions" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Senhala los desplaçaments e los renomenatges coma simples eveniments " +"supression/creacion" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Susvelha los eveniments de montatge" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Susvelha las modificacions de fichièrs o de repertòris." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Montar coma montable" + +#: gio/gio-tool-mount.c:64 +#, fuzzy +#| msgid "Mount volume with device file" +msgid "Mount volume with device file, or other identifier" +msgstr "Montar lo volum amb un fichièr de periferic" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Desmontar" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Ejectar" + +#: gio/gio-tool-mount.c:67 +#, fuzzy +#| msgid "Mount volume with device file" +msgid "Stop drive with device file" +msgstr "Montar lo volum amb un fichièr de periferic" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "PERIFERIC" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Desmontar totes los montatges del protocòl donat" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "PROTOCÃ’L" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Ignorar las operacions de fichièr en cors al moment del desmontatge o de " +"l'ejeccion" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Utilizar un utilizaire anonim al moment de l'authentification" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Enumerar" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Susvelhar los eveniments" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Aficha las opcions de l'ajuda" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +#, fuzzy +#| msgctxt "GDateTime" +#| msgid "PM" +msgid "PIM" +msgstr "PM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montar un volume amagat TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montar un volume sistèma TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Accès anonim refusat" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Pas cap de volum pel fichièr de periferic" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Pas cap de volum per l'identificant donat" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montar o desmontar los emplaçaments." + +#: gio/gio-tool-move.c:42 +#, fuzzy +#| msgid "Don't use copy and delete fallback" +msgid "Don’t use copy and delete fallback" +msgstr "Utilizar pas la còpia o la supression de replec" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Desplaçar un o mantun fichièr de FONT cap a DEST." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move fonciona coma l'utilitari tradicional mv, mas en\n" +"utilizant d'emplaçaments GIO al luòc de fichièrs locals : per exemple,\n" +"se pòt indicar un emplaçament coma smb://servidor/ressorsa/fichièr.txt" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "La cibla %s es pas un repertòri" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Dobrir los fichièrs amb l'aplicacion per defaut\n" +"inscrita per gerir los fichièrs d'aqueste tipe." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignorar los fichièrs non existents, demandar pas jamai" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Suprimir los fichièrs indicats." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOM" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Renomenar un fichièr." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Argument mancant" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Tròp d'arguments" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Lo renomenatge a capitat. Novèl uri : %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Crear solament se existís pas" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Apondre a la fin del fichièr" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Al moment de la creacion, limitar l'accès a l'utilizaire actual" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" +"Al moment d'un remplaçament, remplaçar coma se la destinacion existissiá pas" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Afichar lo novèl etag a la fin" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "L'etag del fichièr en cors d'espotiment" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Error de lectura a partir de l'entrada estandarda" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag pas disponible\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Legir a partir de l'entrada estandard e enregistrar cap a DEST." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Cap de destinacion pas indicada" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Tipe de l'atribut" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALOR" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Definir un atribut de fichièr de l'EMPLAÇAMENT." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Localizacion pas especificada" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atribut pas especificat" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Valor pas especificada" + +#: gio/gio-tool-set.c:180 +#, fuzzy, c-format +#| msgid "Invalid attribute type %s\n" +msgid "Invalid attribute type “%sâ€" +msgstr "Tipe d'atribut %s invalid\n" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Voidar l'escobilhièr" + +#: gio/gio-tool-trash.c:35 +#, fuzzy +#| msgid "List the contents of the locations." +msgid "List files in the trash with their original locations" +msgstr "Enumerar lo contengut dels emplaçaments." + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Impossible de trobar lo camin original" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Impossible de recrear l’emplaçament original : " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Impossible de tornar lo fichièr a son emplaçament d’origina : " + +#: gio/gio-tool-trash.c:225 +#, fuzzy +#| msgid "Move files or directories to the trash." +msgid "Move/Restore files or directories to the trash." +msgstr "Desplaçar de fichièrs o de repertòris cap a l'escobilhièr." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Seguir los ligams simbolics, los montatges e los acorchis" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "" +"Afichar la lista del contengut de repertòris dins un format arborescent." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> interdit dins <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> interdit al primièr nivèl" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Lo fichièr %s apareis mantun còp dins la ressorsa" + +#: gio/glib-compile-resources.c:245 +#, fuzzy, c-format +#| msgid "Failed to locate '%s' in any source directory" +msgid "Failed to locate “%s†in any source directory" +msgstr "La localizacion de « %s » dins totes los repertòris font a fracassat" + +#: gio/glib-compile-resources.c:256 +#, fuzzy, c-format +#| msgid "Failed to locate '%s' in current directory" +msgid "Failed to locate “%s†in current directory" +msgstr "La localizacion de « %s » dins lo repertòri actual a fracassat" + +#: gio/glib-compile-resources.c:290 +#, fuzzy, c-format +#| msgid "Unknown processing option \"%s\"" +msgid "Unknown processing option “%sâ€" +msgstr "Opcion de tractament desconeguda « %s »" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Error de lectura del fichièr %s : %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Error a la compression del fichièr %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s> pòt pas conténer de tèxte" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "" + +#: gio/glib-compile-resources.c:738 +#, fuzzy +#| msgid "name of the output file" +msgid "Name of the output file" +msgstr "nom del fichièr de sortida" + +#: gio/glib-compile-resources.c:739 +#, fuzzy +#| msgid "" +#| "The directories where files are to be read from (default to current " +#| "directory)" +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Los repertòris a partir dels quals los fichièrs seràn legits (per defaut lo " +"repertòri actual)" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "REPERTÃ’RI" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Generar la sortida dins lo format seleccionat per l'extension del nom de " +"fichièr cibla" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "Generar l'entèsta de la font" + +#: gio/glib-compile-resources.c:742 +#, fuzzy +#| msgid "Generate sourcecode used to link in the resource file into your code" +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Generar lo còdi font utilizat per ligar cap a lo fichièr ressorsa dins " +"vòstre còdi" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "Generar la lista de las dependéncias" + +#: gio/glib-compile-resources.c:744 +#, fuzzy +#| msgid "name of the dependency file to generate" +msgid "Name of the dependency file to generate" +msgstr "nom del fichièr de las dependéncias de generar" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:746 +#, fuzzy +#| msgid "Don't automatically create and register resource" +msgid "Don’t automatically create and register resource" +msgstr "Crear pas e enregistrar automaticament la ressorsa" + +#: gio/glib-compile-resources.c:747 +#, fuzzy +#| msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Exportar pas las foncions ; las declarar G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "Nom d'identificant C utilizat pel còdi font generat" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compilar una especificacion de ressorsa dins un fichièr de ressorsa.\n" +"Los fichièrs d'especificacion de ressorsa possedisson l'extension .gresource." +"xml\n" +"e lo fichièr de ressorsa possedís l'extension .gresource." + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "Vos cal indicar un e un sol nom de fichièr\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, fuzzy, c-format +#| msgid "Invalid symlink value given" +msgid "Invalid numeric value" +msgstr "Valor de ligam simbolic donada invalida" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " es ja definit" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' es ja estada definida" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> conten pas la plaja especificada" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " ja especificada per aquesta clau" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Fracàs de l’analisi de la valor del tipe « %s » : " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " ja definits per aquesta clau" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " ja donada" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " es ja estada definida" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " es ja definit" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +#, fuzzy +#| msgid "empty names are not permitted" +msgid "Empty names are not permitted" +msgstr "los noms voids son pas autorizats" + +#: gio/glib-compile-schemas.c:807 +#, fuzzy, c-format +#| msgid "invalid name '%s': names must begin with a lowercase letter" +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "nom « %s » invalid : los noms devon començar per una letra minuscula" + +#: gio/glib-compile-schemas.c:819 +#, fuzzy, c-format +#| msgid "" +#| "invalid name '%s': invalid character '%c'; only lowercase letters, " +#| "numbers and hyphen ('-') are permitted." +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"nom « %s » invalid : caractèr « %c » invalid ; sols las minusculas, los " +"nombres e lo jonhent (« - ») son autorizats." + +#: gio/glib-compile-schemas.c:828 +#, fuzzy, c-format +#| msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"nom « %s » invalid : dos jonhents successius (« -- ») son pas autorizats." + +#: gio/glib-compile-schemas.c:837 +#, fuzzy, c-format +#| msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "" +"nom « %s » invalid : lo darrièr caractèr pòt pas èsser un jonhent (« - »)." + +#: gio/glib-compile-schemas.c:845 +#, fuzzy, c-format +#| msgid "invalid name '%s': maximum length is 1024" +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "nom « %s » invalid : la longor maximala es 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " es ja estat definit" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Impossible d'apondre de claus a un esquèma « list-of »" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " a ja été definit" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" masque dins ; utilizatz " +" per modificar la valor" + +#: gio/glib-compile-schemas.c:983 +#, fuzzy, c-format +#| msgid "" +#| "exactly one of 'type', 'enum' or 'flags' must be specified as an " +#| "attribute to " +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +" pòt pas recebre qu'un e un sol atribut demest « tipe », « enum » o « " +"flags »" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> pas (encara) definit." + +#: gio/glib-compile-schemas.c:1017 +#, fuzzy, c-format +#| msgid "invalid GVariant type string '%s'" +msgid "Invalid GVariant type string “%sâ€" +msgstr "cadena de tipe GVariant « %s » invalida" + +#: gio/glib-compile-schemas.c:1047 +#, fuzzy +#| msgid " given but schema isn't extending anything" +msgid " given but schema isn’t extending anything" +msgstr "un es donat mas son esquèma espandís pas res" + +#: gio/glib-compile-schemas.c:1060 +#, fuzzy, c-format +#| msgid "no to override" +msgid "No to override" +msgstr "pas cap de de redefinir" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " ja definit" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " ja definit" + +#: gio/glib-compile-schemas.c:1153 +#, fuzzy, c-format +#| msgid " extends not yet existing schema '%s'" +msgid " extends not yet existing schema “%sâ€" +msgstr " espandís l'esquèma « %s » qu'existís pas encara" + +#: gio/glib-compile-schemas.c:1169 +#, fuzzy, c-format +#| msgid " is list of not yet existing schema '%s'" +msgid " is list of not yet existing schema “%sâ€" +msgstr "" +" es una lista de l'esquèma « %s » qu'existís pas encara" + +#: gio/glib-compile-schemas.c:1177 +#, fuzzy, c-format +#| msgid "Can not be a list of a schema with a path" +msgid "Cannot be a list of a schema with a path" +msgstr "Un esquèma amb un camin pòt pas conténer de lista" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Impossible d’espandir un esquèma amb un camin" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" es una lista ; espandís qu'es pas una lista" + +#: gio/glib-compile-schemas.c:1207 +#, fuzzy, c-format +#| msgid "" +#| " extends but " +#| "'%s' does not extend '%s'" +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" espandís mas « " +"%s » n'étend pas « %s »" + +#: gio/glib-compile-schemas.c:1224 +#, fuzzy, c-format +#| msgid "a path, if given, must begin and end with a slash" +msgid "A path, if given, must begin and end with a slash" +msgstr "se un camin es indicat, deu començar e finir per una barra oblica" + +#: gio/glib-compile-schemas.c:1231 +#, fuzzy, c-format +#| msgid "the path of a list must end with ':/'" +msgid "The path of a list must end with “:/â€" +msgstr "lo camin d'una lista deu finir per « :/ »" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> es ja definit" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Un sol element <%s> es autorizat dins <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> interdit al primièr nivèl" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "<%s> pòt pas conténer de tèxte" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +#, fuzzy +#| msgid "--strict was specified; exiting.\n" +msgid "--strict was specified; exiting." +msgstr "--strict es estat especificat ; sortida en cors.\n" + +#: gio/glib-compile-schemas.c:1845 +#, fuzzy +#| msgid "This entire file has been ignored.\n" +msgid "This entire file has been ignored." +msgstr "Lo fichièr complet es estat ignorat.\n" + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Aqueste fichièr es ignorat." + +#: gio/glib-compile-schemas.c:1963 +#, fuzzy, c-format +#| msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Pas cap de clau nomenada « %s » dins l'esquèma « %s » coma definit dins lo " +"fichièr « %s » de redefinicion" + +#: gio/glib-compile-schemas.c:1971 +#, fuzzy, c-format +#| msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Pas cap de clau nomenada « %s » dins l'esquèma « %s » coma definit dins lo " +"fichièr « %s » de redefinicion" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s." +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Error d'analisi de la clau « %s » dins l'esquèma « %s » coma definit dins lo " +"fichièr « %s » de redefinicion : %s." + +#: gio/glib-compile-schemas.c:2038 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s." +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Error d'analisi de la clau « %s » dins l'esquèma « %s » coma definit dins lo " +"fichièr « %s » de redefinicion : %s." + +#: gio/glib-compile-schemas.c:2065 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is outside the " +#| "range given in the schema" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"la redefinicion de la clau « %s » dins l'esquèma « %s » del fichièr de " +"redefinicion « %s » es pas dins la plaja indicada per l'esquèma" + +#: gio/glib-compile-schemas.c:2075 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is outside the " +#| "range given in the schema" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"la redefinicion de la clau « %s » dins l'esquèma « %s » del fichièr de " +"redefinicion « %s » es pas dins la plaja indicada per l'esquèma" + +#: gio/glib-compile-schemas.c:2101 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"la redefinicion de la clau « %s » dins l'esquèma « %s » del fichièr de " +"redefinicion « %s » es pas dins la lista de las causida validas" + +#: gio/glib-compile-schemas.c:2111 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"la redefinicion de la clau « %s » dins l'esquèma « %s » del fichièr de " +"redefinicion « %s » es pas dins la lista de las causida validas" + +#: gio/glib-compile-schemas.c:2173 +#, fuzzy +#| msgid "where to store the gschemas.compiled file" +msgid "Where to store the gschemas.compiled file" +msgstr "endreit ont enregistrar lo fichièr gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Anullacion en cas d'errors dins d'esquèmas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Escriure pas cap de fichièr gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Aplicar pas las limitacions de nom de clau" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compilar totes los fichièrs esquèmas GSettings dins un cache.\n" +"L'extension .gschema.xml es requesida pels fichièrs esquèmas,\n" +"e lo fichièr cache es nomenat gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +#, fuzzy +#| msgid "You should give exactly one directory name\n" +msgid "You should give exactly one directory name" +msgstr "Vos cal indicar un e un sol nom de repertòri\n" + +#: gio/glib-compile-schemas.c:2269 +#, fuzzy +#| msgid "No schema files found: " +msgid "No schema files found: doing nothing." +msgstr "Cap de fichièr esquèma pas trobat : " + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Nom de fichièr invalid : %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "" +"Error d'obtencion de las informacions del sistèma de fichièrs per %s : %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Lo punt de montatge contenidor pel fichièr %s es introbable" + +#: gio/glocalfile.c:1146 +#, fuzzy +#| msgid "Can't rename root directory" +msgid "Can’t rename root directory" +msgstr "Impossible de renomenar lo repertòri raiç" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Error de renomenatge del fichièr %s : %s" + +#: gio/glocalfile.c:1171 +#, fuzzy +#| msgid "Can't rename file, filename already exists" +msgid "Can’t rename file, filename already exists" +msgstr "Impossible de renomenar lo fichièr perque aqueste nom es ja utilizat" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nom de fichièr invalid" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Error al moment de la dobertura del fichièr %s : %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Error al moment de la supression del fichièr %s : %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Error al moment de la mesa a l'escobilhièr del fichièr %s : %s" + +#: gio/glocalfile.c:2040 +#, fuzzy, c-format +#| msgid "Unable to create trash dir %s: %s" +msgid "Unable to create trash directory %s: %s" +msgstr "Impossible de crear lo repertòri de l'escobilhièr %s : %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Impossible de trobar lo repertòri raiç per metre %s a l'escobilhièr" + +#: gio/glocalfile.c:2069 +#, fuzzy, c-format +#| msgid "Copy (reflink/clone) between mounts is not supported" +msgid "Trashing on system internal mounts is not supported" +msgstr "La còpia (reflink/clone) entre punts de montatge es pas presa en carga" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Impossible de trobar o crear lo repertòri de l'escobilhièr %s per %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "" +"Impossible de crear lo fichièr d'informacions de mesa a l'escobilhièr per " +"%s : %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Impossible de metre a l'escobilhièr lo fichièr %s de delà dels limits del " +"sistèma de fichièrs" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Impossible de metre a l'escobilhièr lo fichièr %s : %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Impossible de metre a l'escobilhièr lo fichièr %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Error al moment de la creacion del repertòri %s : %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Lo sistèma de fichièrs gerís pas los ligams simbolics" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Error al moment de la creacion del ligam simbolic %s : %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Error al moment del desplaçament del fichièr %s : %s" + +#: gio/glocalfile.c:2481 +#, fuzzy +#| msgid "Can't move directory over directory" +msgid "Can’t move directory over directory" +msgstr "Impossible de desplaçar un repertòri per dessús un autre" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "La creacion del fichièr de salvament a fracassat" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Error al moment de la supression del fichièr cibla : %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Lo desplaçament entre punts de montatge es pas pres en carga" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Impossible de determinar l'utilizacion disc de %s : %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "La valor d'atribut deu pas èsser « NULL »" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tipe d'atribut invalid (una cadena es esperada)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nom d'atribut espandit invalid" + +#: gio/glocalfileinfo.c:821 +#, fuzzy, c-format +#| msgid "Error setting extended attribute '%s': %s" +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Error al moment de la definicion de l'atribut espandit « %s » : %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (encodatge invalid)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, fuzzy, c-format +#| msgid "Error when getting information for file '%s': %s" +msgid "Error when getting information for file “%sâ€: %s" +msgstr "" +"Error al moment de l'obtencion de las informacions del fichièr « %s » : %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" +"Error al moment de l'obtencion de las informacions del descriptor de " +"fichièr : %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tipe d'atribut invalid (uint32 esperat)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tipe d'atribut invalid (uint64 esperat)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Tipe d'atribut invalid (cadena d'octets esperada)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Impossible de definir de permissions suls ligams simbolics" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Error al moment de la definicion de las permissions : %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Error al moment de la definicion del proprietari : %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "un ligam simbolic deu pas èsser « NULL »" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Error al moment de la definicion del ligam simbolic : %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Error al moment de la definicion del ligam simbolic : lo fichièr es pas un " +"ligam simbolic" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Error pendent definicion de l'ora de modificacion o d'accès del fichièr " +"« %s » : %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" +"Error al moment de la definicion de l'ora de modificacion o d'accès : %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Lo contèxte SELinux deu pas èsser « NULL »" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux es pas activat sus aqueste sistèma" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Error al moment de la definicion del contèxte SELinux : %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "La definicion de l'atribut %s es pas presa en carga" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Error al moment de la lectura del fichièr : %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Error al moment de la tampadura del fichièr : %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Error de posicionament dins lo fichièr : %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Impossible de trobar lo tipe de monitor de fichièr local per defaut" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Error al moment de l'escritura del fichièr : %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Error al moment de la supression de l'ancian ligam de salvament : %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Error al moment de la creacion de la còpia de salvament : %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Error al moment del cambiament de nom del fichièr temporari : %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "Error al moment de la troncadura del fichièr : %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:226 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Error al moment de la dobertura del fichièr « %s » : %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Lo fichièr cibla es un repertòri" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Lo fichièr cibla es pas un fichièr estandard" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Lo fichièr es estat modificat exteriorament" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Error a la supression de l'ancian fichièr : %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Lo tipe GSeekTipe provesit es pas valid" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Requête « seek » invalida" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Impossible de troncar GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Lo flux de sortida memòria es pas redimensionable" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Lo redimensionament del flux de sortida memòria a fracassat" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"La quantitat de memòria necessària per efectuar l'escritura es mai granda " +"que l'espaci d'adressatge disponible" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Posicionament demandat abans lo començament del flux" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Posicionament demandat aprèp la fin del flux" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +#, fuzzy +#| msgid "mount doesn't implement \"unmount\"" +msgid "mount doesn’t implement “unmountâ€" +msgstr "mount implementa pas lo desmontatge (« unmount »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +#, fuzzy +#| msgid "mount doesn't implement \"eject\"" +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount implementa pas l'ejeccion (« eject »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +#, fuzzy +#| msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"mount implementa pas lo desmontatge (« unmount » o « unmount_with_operation " +"»)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +#, fuzzy +#| msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "mount implementa pas l'ejeccion (« eject » o « eject_with_operation »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +#, fuzzy +#| msgid "mount doesn't implement \"remount\"" +msgid "mount doesn’t implement “remountâ€" +msgstr "mount implementa pas lo remontatge (« remount »)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +#, fuzzy +#| msgid "mount doesn't implement content type guessing" +msgid "mount doesn’t implement content type guessing" +msgstr "mount implementa pas l'estimacion del tipe de contengut" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +#, fuzzy +#| msgid "mount doesn't implement synchronous content type guessing" +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "mount implementa pas la suposicion d'un tipe de contengut sincròn" + +#: gio/gnetworkaddress.c:415 +#, fuzzy, c-format +#| msgid "Hostname '%s' contains '[' but not ']'" +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Lo nom d'òste « %s » compòrta « [ » mas pas « ] »" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Ret inaccessibla" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Ã’ste inaccessible" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Impossible de crear lo monitor de ret : %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Impossible de crear lo monitor de ret : " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Impossible d'obténer l'estatut de la ret : " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager es pas aviat" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "La version de NetworkManager es tròp anciana" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +#, fuzzy +#| msgid "Output stream doesn't implement write" +msgid "Output stream doesn’t implement write" +msgstr "Lo flux de sortida implementa pas « write »" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Lo flux font es ja tampat" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Error de resolucion de « %s » : %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:615 +#, fuzzy, c-format +#| msgid "Input stream doesn't implement read" +msgid "%s not implemented" +msgstr "Lo flux en entrada implementa pas « read »" + +#: gio/gresolver.c:984 gio/gresolver.c:1036 +#, fuzzy +#| msgid "Invalid filename" +msgid "Invalid domain" +msgstr "Nom de fichièr invalid" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, fuzzy, c-format +#| msgid "The resource at '%s' does not exist" +msgid "The resource at “%s†does not exist" +msgstr "La ressorsa dins « %s » existís pas" + +#: gio/gresource.c:848 +#, fuzzy, c-format +#| msgid "The resource at '%s' failed to decompress" +msgid "The resource at “%s†failed to decompress" +msgstr "La descompression de la ressorsa dins « %s » a pas capitat" + +#: gio/gresourcefile.c:732 +#, fuzzy, c-format +#| msgid "The resource at '%s' is not a directory" +msgid "The resource at “%s†is not a directory" +msgstr "La ressorsa dins « %s » es pas un repertòri" + +#: gio/gresourcefile.c:940 +#, fuzzy +#| msgid "Input stream doesn't implement seek" +msgid "Input stream doesn’t implement seek" +msgstr "Lo flux en entrada implementa pas « seek » (lo posicionament)" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "" +"Enumèra las seccions que contenon las ressorsas dins un fichièr « elf »" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Enumèra las ressorsas\n" +"Se SECCION es provesida, enumèra solament las ressorsas d'aquesta seccion\n" +"Se CAMIN es provesit, enumèra solament las ressorsas correspondentas" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FICHIÈR [CAMIN]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECCION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Enumèra las ressorsas en detalh\n" +"Se SECCION es provesida, enumèra solament las ressorsas d'aquesta seccion\n" +"Se CAMIN es provesit, enumèra solament las ressorsas correspondentas\n" +"Los detalhs incluisson la seccion, la talha e la compression" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extrai un fichièr ressorsa cap a la sortida estandarda" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "CAMIN DEL FICHIÈR" + +#: gio/gresource-tool.c:540 +#, fuzzy +#| msgid "" +#| "Usage:\n" +#| " gresource [--section SECTION] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " sections List resource sections\n" +#| " list List resources\n" +#| " details List resources with details\n" +#| " extract Extract a resource\n" +#| "\n" +#| "Use 'gresource help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilizacion :\n" +" gresource [--seccion SECCION] COMANDA [ARGUMENTS...]\n" +"\n" +"Comandas :\n" +" help Aficha aquesta informacion\n" +" seccions Enumèra las seccions de ressorsas\n" +" list Enumèra las ressorsas\n" +" details Enumèra las ressorsas en detalh\n" +" extract Extrai una ressorsa\n" +"\n" +"Utilizatz « gresource help COMANDA » per obténer d'ajuda detalhada.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilizacion :\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECCION Un nom de seccion elf (facultatiu)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:706 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMANDA La comanda (facultativa) d'explicar\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FICHIÈR Un fichièr elf (un binari o una bibliotèca partejada)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FICHIÈR Un fichièr elf (un binari o una bibliotèca partejada)\n" +" o un fichièr ressorsa compilat\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[CAMIN]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " CAMIN Un camin (facultatiu) de ressorsa (pòt èsser parcial)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CAMIN" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " CAMIN Un camin de ressorsa\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:911 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "L'esquèma « %s » existís pas\n" + +#: gio/gsettings-tool.c:55 +#, fuzzy, c-format +#| msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "L'esquèma « %s » es pas readreçable (lo camin deu pas èsser indicat)\n" + +#: gio/gsettings-tool.c:76 +#, fuzzy, c-format +#| msgid "Schema '%s' is relocatable (path must be specified)\n" +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "L'esquèma « %s » es readreçable (lo camin deu èsser indicat)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Camin indicat void.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Un camin deu començar per una barra oblica (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Un camin deu s'acabar per una barra oblica (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Un camin deu pas conténer doas barras oblicas de seguida (//)\n" + +#: gio/gsettings-tool.c:541 +msgid "The provided value is outside of the valid range\n" +msgstr "La valor donada es en defòra del domeni de validitat\n" + +#: gio/gsettings-tool.c:548 +msgid "The key is not writable\n" +msgstr "La clau pòt pas èsser escrita\n" + +#: gio/gsettings-tool.c:584 +msgid "List the installed (non-relocatable) schemas" +msgstr "Listar los esquèmas (non-readreçables) installats" + +#: gio/gsettings-tool.c:590 +msgid "List the installed relocatable schemas" +msgstr "Listar los esquèmas readreçables installats" + +#: gio/gsettings-tool.c:596 +msgid "List the keys in SCHEMA" +msgstr "Listar las claus del ESQUÈMA" + +#: gio/gsettings-tool.c:597 gio/gsettings-tool.c:603 gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH]" +msgstr "ESQUÈMA[:CAMIN]" + +#: gio/gsettings-tool.c:602 +msgid "List the children of SCHEMA" +msgstr "Listar los enfants del ESQUÈMA" + +#: gio/gsettings-tool.c:608 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Listar las claus e las valors recursivament\n" +"Se cap d'ESQUÈMA es pas indicat, listar totas las claus\n" + +#: gio/gsettings-tool.c:610 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESQUÈMA[:CAMIN]]" + +#: gio/gsettings-tool.c:615 +msgid "Get the value of KEY" +msgstr "Obténer la valor de KEY" + +#: gio/gsettings-tool.c:616 gio/gsettings-tool.c:622 gio/gsettings-tool.c:628 +#: gio/gsettings-tool.c:640 gio/gsettings-tool.c:652 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESQUÈMA[:CAMIN] CLAU" + +#: gio/gsettings-tool.c:621 +msgid "Query the range of valid values for KEY" +msgstr "Demandar la plaja de validitat de las valors de la CLAU" + +#: gio/gsettings-tool.c:627 +msgid "Query the description for KEY" +msgstr "Demandar la descripcion per la CLAU" + +#: gio/gsettings-tool.c:633 +msgid "Set the value of KEY to VALUE" +msgstr "Definir la valor de CLAU a VALOR" + +#: gio/gsettings-tool.c:634 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESQUÈMA[:CAMIN] CLAU VALOR" + +#: gio/gsettings-tool.c:639 +msgid "Reset KEY to its default value" +msgstr "Restablir CLAU a sa valor per defaut" + +#: gio/gsettings-tool.c:645 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Reïnicializar totas las claus de ESQUÈMA a lors valors per defaut" + +#: gio/gsettings-tool.c:651 +msgid "Check if KEY is writable" +msgstr "Testar se CLAU es inscriptible" + +#: gio/gsettings-tool.c:657 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Contrarotlar las modificacions de CLAU.\n" +"Se CLAU es pas definit, contraròtla totas las claus dins ESQUÈMA.\n" +"Quichar ^C per metre fin al contraròtle.\n" + +#: gio/gsettings-tool.c:660 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESQUÈMA[:CAMIN] [CLAU]" + +#: gio/gsettings-tool.c:672 +#, fuzzy +#| msgid "" +#| "Usage:\n" +#| " gsettings --version\n" +#| " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " list-schemas List installed schemas\n" +#| " list-relocatable-schemas List relocatable schemas\n" +#| " list-keys List keys in a schema\n" +#| " list-children List children of a schema\n" +#| " list-recursively List keys and values, recursively\n" +#| " range Queries the range of a key\n" +#| " describe Queries the description of a key\n" +#| " get Get the value of a key\n" +#| " set Set the value of a key\n" +#| " reset Reset the value of a key\n" +#| " reset-recursively Reset all values in a given schema\n" +#| " writable Check if a key is writable\n" +#| " monitor Watch for changes\n" +#| "\n" +#| "Use 'gsettings help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilizacion :\n" +" gsettings --version\n" +" gsettings [--schemadir REPERTÃ’RI2ESQUÈMA] COMANDA [PARAMÈTRES...]\n" +"\n" +"Comandas :\n" +" help Aficha la presenta informacion\n" +" list-schemas Lista los esquèmas installats\n" +" list-relocatable-schemas Lista los esquèmas readreçables\n" +" list-keys Lista las claus dins un esquèma\n" +" list-children Lista los enfants d'un esquèma\n" +" list-recursively Lista las claus e las valors, recursivament\n" +" range Demanda lo domeni de validitat de la clau\n" +" get Renvia la valor d'una clau\n" +" set Definís la valor d'una clau\n" +" reset Restablís la valor per defaut d'una clau\n" +" reset-recursively Restablís totas las valors dins un esquèma " +"donat\n" +" writable Tèsta se la clau es inscriptibla\n" +" monitor Contraròtla las modificacions\n" +"\n" +"Picatz 'gsettings help COMANDA' per una ajuda detalhada.\n" +"\n" + +#: gio/gsettings-tool.c:696 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilizacion :\n" +" gsettings [--schemadir REPERTÃ’RI2ESQUÈMA] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:702 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " REPERTÃ’RI2ESQUÈMA Un repertòri de recèrca d'esquèmas suplementaris\n" + +#: gio/gsettings-tool.c:710 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" ESQUÈMA Lo nom de l'esquèma\n" +" CAMIN Lo camin, pels esquèmas readreçables\n" + +#: gio/gsettings-tool.c:715 +msgid " KEY The (optional) key within the schema\n" +msgstr " CLAU La clau (opcionala) dins l'esquèma\n" + +#: gio/gsettings-tool.c:719 +msgid " KEY The key within the schema\n" +msgstr " CLAU La clau dins l'esquèma\n" + +#: gio/gsettings-tool.c:723 +msgid " VALUE The value to set\n" +msgstr " VALOR La valor a definir\n" + +#: gio/gsettings-tool.c:778 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Impossible de cargar los esquèmas dempuèi %s : %s\n" + +#: gio/gsettings-tool.c:790 +msgid "No schemas installed\n" +msgstr "Cap de fichièr esquèma pas installat\n" + +#: gio/gsettings-tool.c:869 +msgid "Empty schema name given\n" +msgstr "Nom d'esquèma provesit void\n" + +#: gio/gsettings-tool.c:924 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "La clau « %s » existís pas\n" + +#: gio/gsocket.c:413 +msgid "Invalid socket, not initialized" +msgstr "Connector invalid, pas inicializat" + +#: gio/gsocket.c:420 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Connector invalid, l'inicializacion a fracassat en rason de : %s" + +#: gio/gsocket.c:428 +msgid "Socket is already closed" +msgstr "Lo connector es ja tampat" + +#: gio/gsocket.c:443 gio/gsocket.c:3190 gio/gsocket.c:4420 gio/gsocket.c:4478 +msgid "Socket I/O timed out" +msgstr "Entradas/sortidas fòra relambi sul connector" + +#: gio/gsocket.c:578 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "creacion de GSocket a partir del descriptor de fichièr : %s" + +#: gio/gsocket.c:607 gio/gsocket.c:671 gio/gsocket.c:678 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Impossible de crear lo connector : %s" + +#: gio/gsocket.c:671 +msgid "Unknown family was specified" +msgstr "Indicacion d'una familha desconeguda" + +#: gio/gsocket.c:678 +msgid "Unknown protocol was specified" +msgstr "Indicacion d'un protocòl desconegut" + +#: gio/gsocket.c:1169 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Impossible d'utilizar d'operacions datagrama sus un connector non datagrama." + +#: gio/gsocket.c:1186 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Impossible d'utilizar d'operacions datagrama sus un connector dotat d'un " +"relambi d'expiracion." + +#: gio/gsocket.c:1993 +#, c-format +msgid "could not get local address: %s" +msgstr "impossible d'obténer l'adreça locala : %s" + +#: gio/gsocket.c:2039 +#, c-format +msgid "could not get remote address: %s" +msgstr "impossible d'obténer l'adreça distanta : %s" + +#: gio/gsocket.c:2105 +#, c-format +msgid "could not listen: %s" +msgstr "impossible d'escotar : %s" + +#: gio/gsocket.c:2209 +#, fuzzy, c-format +#| msgid "Error binding to address: %s" +msgid "Error binding to address %s: %s" +msgstr "Error al moment de ligason a l'adreça : %s" + +#: gio/gsocket.c:2385 gio/gsocket.c:2422 gio/gsocket.c:2532 gio/gsocket.c:2557 +#: gio/gsocket.c:2620 gio/gsocket.c:2678 gio/gsocket.c:2696 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Error al moment de la connexion al grop multicast : %s" + +#: gio/gsocket.c:2386 gio/gsocket.c:2423 gio/gsocket.c:2533 gio/gsocket.c:2558 +#: gio/gsocket.c:2621 gio/gsocket.c:2679 gio/gsocket.c:2697 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Error al moment de la desconnexion del grop multicast : %s" + +#: gio/gsocket.c:2387 +msgid "No support for source-specific multicast" +msgstr "Pas cap de presa en carga pel multicast especific a la font" + +#: gio/gsocket.c:2534 +#, fuzzy +#| msgid "Unsupported socket address" +msgid "Unsupported socket family" +msgstr "Adreça de connector ret pas presa en carga" + +#: gio/gsocket.c:2559 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2583 +#, c-format +msgid "Interface name too long" +msgstr "Nom d’interfàcia tròp long" + +#: gio/gsocket.c:2596 gio/gsocket.c:2646 +#, c-format +msgid "Interface not found: %s" +msgstr "Interfàcia introbabla : %s" + +#: gio/gsocket.c:2622 +#, fuzzy +#| msgid "No support for source-specific multicast" +msgid "No support for IPv4 source-specific multicast" +msgstr "Pas cap de presa en carga pel multicast especific a la font" + +#: gio/gsocket.c:2680 +#, fuzzy +#| msgid "No support for source-specific multicast" +msgid "No support for IPv6 source-specific multicast" +msgstr "Pas cap de presa en carga pel multicast especific a la font" + +#: gio/gsocket.c:2889 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Error d'acceptacion de la connexion : %s" + +#: gio/gsocket.c:3015 +msgid "Connection in progress" +msgstr "Connexion en cors" + +#: gio/gsocket.c:3066 +msgid "Unable to get pending error: " +msgstr "Impossible d'obténer l'error actuala : " + +#: gio/gsocket.c:3255 +#, c-format +msgid "Error receiving data: %s" +msgstr "Error al moment de la recepcion de las donadas : %s" + +#: gio/gsocket.c:3452 +#, c-format +msgid "Error sending data: %s" +msgstr "Error al moment del mandadís de las donadas : %s" + +#: gio/gsocket.c:3639 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Impossible de tampar lo connector : %s" + +#: gio/gsocket.c:3720 +#, c-format +msgid "Error closing socket: %s" +msgstr "Error al moment de la tampadura del connector : %s" + +#: gio/gsocket.c:4413 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "En espèra de l'estat del connector : %s" + +#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833 +#, c-format +msgid "Unable to send message: %s" +msgstr "Impossible d'enviar lo messatge : %s" + +#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834 +msgid "Message vectors too large" +msgstr "" + +#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084 +#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304 +#, c-format +msgid "Error sending message: %s" +msgstr "Error de mandadís de messatge : %s" + +#: gio/gsocket.c:5026 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage es pas pres en carga per Windows" + +#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797 +#, c-format +msgid "Error receiving message: %s" +msgstr "Error al moment de la recepcion del messatge : %s" + +#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Impossible de legir las donadas d'autentificacion del connector : %s" + +#: gio/gsocket.c:6136 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials es pas implementat sus aqueste sistèma operatiu" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Impossible de se connectar al servidor mandatari %s : " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Impossible de se connectar a %s : " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Impossible de se connectar : " + +#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "L'usatge d'un proxy es pas pres en carga dins una connexion non-TCP." + +#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778 +#, fuzzy, c-format +#| msgid "Proxy protocol '%s' is not supported." +msgid "Proxy protocol “%s†is not supported." +msgstr "Lo protocòl del proxy « %s » es pas pres en carga." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Lo processus d'escota es ja tampat" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Lo connector ret apondut es tampat" + +#: gio/gsocks4aproxy.c:118 +#, fuzzy, c-format +#| msgid "SOCKSv4 does not support IPv6 address '%s'" +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 pren pas en carga l'adreça IPv6 « %s »" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Lo nom d'utilizaire es tròp long pel protocòl SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, fuzzy, c-format +#| msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Lo nom d'òste « %s » es tròp long pel protocòl SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Lo servidor es pas un servidor mandatari SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "La connexion a travèrs lo servidor SOCKSv4 es estada regetada" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Lo servidor es pas un servidor mandatari SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Lo servidor mandatari SOCKSv5 necessita una autentificacion." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Lo protocòl SOCKSv5 necessita un metòde d'autentificacion qu'es pas presa en " +"carga per GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Lo nom d'utilizaire o lo senhal es tròp long pel protocòl SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"L'autentificacion SOCKSv5 a fracassat a causa d'un marrit nom d'utilizaire o " +"senhal." + +#: gio/gsocks5proxy.c:300 +#, fuzzy, c-format +#| msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Lo nom d'òste « %s » es tròp long pel protocòl SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Lo servidor mandatari SOCKSv5 utiliza un tipe d'adreça desconegut." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Error intèrna de servidor mandatari SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "La connexion SOCKSv5 es pas autorizada per la règla." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "L'òste es pas accessible a travèrs lo servidor SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "La ret es pas accessibla a travèrs lo proxy SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Connexion a travèrs lo servidor mandatari SOCKSv5 refusada." + +#: gio/gsocks5proxy.c:400 +#, fuzzy +#| msgid "SOCKSv5 proxy does not support 'connect' command." +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "" +"Lo servidor mandatari SOCKSv5 pren pas en carga la comanda « connect »." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" +"Lo servidor mandatari SOCKSv5 pren pas en carga lo tipe d'adreça provesit." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Error desconeguda del servidor mandatari SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"La creacion del tub de comunicacion amb lo processus filh a fracassat (%s)" + +#: gio/gtestdbus.c:619 +#, fuzzy, c-format +#| msgid "Seek not supported on stream" +msgid "Pipes are not supported in this platform" +msgstr "Lo posicionament es pas pres en carga sul flux" + +#: gio/gthemedicon.c:595 +#, fuzzy, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Impossible de gerir la version %d de l'encodatge GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Cap d'adreça valida es pas estada trobada" + +#: gio/gthreadedresolver.c:337 +#, fuzzy, c-format +#| msgid "Error reverse-resolving '%s': %s" +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Error de resolucion invèrsa de « %s » : %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, fuzzy, c-format +#| msgid "No DNS record of the requested type for '%s'" +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Cap d'enregistrament DNS del tipe pas demandat per « %s »" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, fuzzy, c-format +#| msgid "Temporarily unable to resolve '%s'" +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Impossible temporàriament de resòlvre « %s »" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Error de resolucion de « %s »" + +#: gio/gtlscertificate.c:431 +msgid "No PEM-encoded private key found" +msgstr "Cap de clau privada pas encodada PEM trobada" + +#: gio/gtlscertificate.c:441 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Impossible de deschifrar la clau privada encodada-PEM" + +#: gio/gtlscertificate.c:452 +msgid "Could not parse PEM-encoded private key" +msgstr "Impossible d'analisar la clau privada encodada-PEM" + +#: gio/gtlscertificate.c:479 +msgid "No PEM-encoded certificate found" +msgstr "Cap de certificat encodat-PEM pas trobat" + +#: gio/gtlscertificate.c:488 +msgid "Could not parse PEM-encoded certificate" +msgstr "Impossible d'analisar lo certificat encodat-PEM" + +#: gio/gtlscertificate.c:844 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Aquò es vòstra darrièra chança de picar un senhal corrècte abans que vòstre " +"accès siá blocat." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +#, fuzzy +#| msgid "" +#| "Several password entered have been incorrect, and your access will be " +#| "locked out after further failures." +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Mantun senhal picats son estats incorrèctes, vòstre accès serà blocat aprèp " +"qualques fracasses mai." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Lo senhal picat es incorrècte." + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 messatge de contraròtle esperat, %d recebut" +msgstr[1] "1 messatge de contraròtle esperat, %d recebuts" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "Tipe de donadas auxiliaras inesperat" + +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Un descriptor de fichièr esperat, %d obtengut\n" +msgstr[1] "Un descriptor de fichièr esperat, %d obtenguts\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Lo descriptor de fichièr recebut es pas valid" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "Error al moment del mandadís de l'identificacion : " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"Error al moment de la verificacion de l'activacion de SO_PASSCRED pel " +"connector : %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Error al moment de l'activacion de SO_PASSCRED : %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Lectura d'un unic octet esperada a la recepcion de l'identificacion, mas pas " +"cap d'octet lu" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Pas de messatge de contraròtle esperat, %d recebut(s)" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Error al moment de la desactivacion de SO_PASSCRED : %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Error de lectura a partir del descriptor de fichièr : %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Error de tampadura del descriptor de fichièr : %s" + +#: gio/gunixmounts.c:2785 gio/gunixmounts.c:2838 +msgid "Filesystem root" +msgstr "Raiç del sistèma de fichièrs" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Error d'escritura cap a lo descriptor de fichièr : %s" + +#: gio/gunixsocketaddress.c:244 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Las adreças abstraitas de connector ret de domeni UNIX son pas presas en " +"carga sus aqueste sistèma" + +#: gio/gvolume.c:438 +#, fuzzy +#| msgid "volume doesn't implement eject" +msgid "volume doesn’t implement eject" +msgstr "lo volum implementa pas l'ejeccion (« eject »)" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +#, fuzzy +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" +"lo volum implementa pas l'ejeccion (« eject » o « eject_with_operation »)" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Error de lectura a partir de l'identificador : %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Error de tampadura de l'identificador : %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Error al moment de l'escritura cap a l'identificador : %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Memòria insufisenta" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Error intèrna : %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Entrada que necessita mai de donadas" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Donadas compressadas invalidas" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adreça a escotar" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorat, per compatibilitat amb GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Imprimir l'adreça" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Imprimir l'adreça en mòde shell" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Executar un servici dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Arguments incorrèctes\n" + +#: glib/gbookmarkfile.c:777 +#, fuzzy, c-format +#| msgid "Unexpected attribute '%s' for element '%s'" +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Atribut « %s » inesperat per l'element « %s »" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, fuzzy, c-format +#| msgid "Attribute '%s' of element '%s' not found" +msgid "Attribute “%s†of element “%s†not found" +msgstr "L'atribut « %s » de l'element « %s » es introbable" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, fuzzy, c-format +#| msgid "Unexpected tag '%s', tag '%s' expected" +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Balisa « %s » inesperada. La balisa « %s » èra esperada" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, fuzzy, c-format +#| msgid "Unexpected tag '%s' inside '%s'" +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Balisa « %s » inesperada a l'interior de « %s »" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Impossible de trobar un fichièr de signets valid dins los repertòris de " +"donadas" + +#: glib/gbookmarkfile.c:2037 +#, fuzzy, c-format +#| msgid "A bookmark for URI '%s' already exists" +msgid "A bookmark for URI “%s†already exists" +msgstr "Un signet per l'URI « %s » existís ja" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Cap de signet pas trobat per l'URI « %s »" + +#: glib/gbookmarkfile.c:2418 +#, fuzzy, c-format +#| msgid "No MIME type defined in the bookmark for URI '%s'" +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Cap de tipe MIME pas definit dins lo signet per l'URI « %s »" + +#: glib/gbookmarkfile.c:2503 +#, fuzzy, c-format +#| msgid "No private flag has been defined in bookmark for URI '%s'" +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Cap d'indicator privat es pas definit dins lo signet per l'URI « %s »" + +#: glib/gbookmarkfile.c:3044 +#, fuzzy, c-format +#| msgid "No groups set in bookmark for URI '%s'" +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Cap de grop es pas definit dins lo signet per l'URI « %s »" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, fuzzy, c-format +#| msgid "No application with name '%s' registered a bookmark for '%s'" +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "" +"Cap d'aplicacion nomenada « %s » a pas enregistrat un signet per « %s »" + +#: glib/gbookmarkfile.c:3743 +#, fuzzy, c-format +#| msgid "Failed to expand exec line '%s' with URI '%s'" +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "" +"Fracàs del desvolopament de la linha de comanda « %s » per l'URI « %s »" + +#: glib/gconvert.c:468 +#, fuzzy +#| msgid "Invalid sequence in conversion input" +msgid "Unrepresentable character in conversion input" +msgstr "Sequéncia invalida dins l'entrada del convertidor" + +#: glib/gconvert.c:495 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "Sequéncia de caractèrs incompleta en fin d'entrada" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" +"Impossible de convertir lo caractèr de replec « %s » dins lo jòc de còdis « " +"%s »" + +#: glib/gconvert.c:936 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "Sequéncia d'octets incorrècta en entrada del convertidor" + +#: glib/gconvert.c:957 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "Sequéncia d'octets incorrècta en entrada del convertidor" + +#: glib/gconvert.c:1688 +#, fuzzy, c-format +#| msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "L'URI « %s » es pas una URI absoluda qu'utiliza lo protocòl « file »" + +#: glib/gconvert.c:1698 +#, fuzzy, c-format +#| msgid "The local file URI '%s' may not include a '#'" +msgid "The local file URI “%s†may not include a “#â€" +msgstr "L'URI de fichièr local « %s » pòt pas inclure un caractèr « # »" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "L’URI « %s » es pas valida" + +#: glib/gconvert.c:1727 +#, fuzzy, c-format +#| msgid "The hostname of the URI '%s' is invalid" +msgid "The hostname of the URI “%s†is invalid" +msgstr "Lo nom d'òste de l'URI « %s » es pas valid" + +#: glib/gconvert.c:1743 +#, fuzzy, c-format +#| msgid "The URI '%s' contains invalidly escaped characters" +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "L'URI « %s » conten de caractèrs d'escapament incorrèctes" + +#: glib/gconvert.c:1815 +#, fuzzy, c-format +#| msgid "The pathname '%s' is not an absolute path" +msgid "The pathname “%s†is not an absolute path" +msgstr "Lo camin « %s » es pas un camin absolu" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "genièr" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "febrièr" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "març" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "abril" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "mai" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "junh" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "julhet" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "agost" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "setembre" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "octobre" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "novembre" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "decembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "gen." + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "febr." + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "març" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "abril" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "mai" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "junh" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "julh." + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "agost" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "set." + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "oct." + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov." + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "dec." + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "diluns" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "dimars" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "dimècres" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "dijòus" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "divendres" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "dissabte" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "dimenge" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Dl" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Dm" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Dc" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Dj" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Dv" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Ds" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Dg" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "genièr" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "febrièr" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "març" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "abril" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "mai" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "junh" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "julhet" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "agost" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "setembre" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "octobre" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "novembre" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "decembre" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "gen." + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "febr." + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "març" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "abril" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "mai" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "junh" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "julh." + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "agost" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "set." + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "oct." + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov." + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec." + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, fuzzy, c-format +#| msgid "Error opening directory '%s': %s" +msgid "Error opening directory “%sâ€: %s" +msgstr "Error a la dobertura del repertòri « %s » : %s" + +#: glib/gfileutils.c:738 glib/gfileutils.c:830 +#, fuzzy, c-format +#| msgid "Could not allocate %lu byte to read file \"%s\"" +#| msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Impossible d'alogar %lu octet per legir lo fichièr « %s »" +msgstr[1] "Impossible d'alogar %lu octets per legir lo fichièr « %s »" + +#: glib/gfileutils.c:755 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Error de lectura del fichièr « %s » : %s" + +#: glib/gfileutils.c:791 +#, c-format +msgid "File “%s†is too large" +msgstr "Lo fichièr « %s » es tròp grand" + +#: glib/gfileutils.c:855 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to read from file “%sâ€: %s" +msgstr "La lectura dempuèi lo fichièr « %s » a fracassat : %s" + +#: glib/gfileutils.c:905 glib/gfileutils.c:980 glib/gfileutils.c:1469 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "La dobertura del fichièr « %s » a fracassat : %s" + +#: glib/gfileutils.c:918 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"L'obtencion dels atributs del fichièr « %s » a fracassat : fracàs de " +"fstat() : %s" + +#: glib/gfileutils.c:949 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': fdopen() failed: %s" +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "La dobertura del fichièr « %s » a fracassat : fracàs de fdopen() : %s" + +#: glib/gfileutils.c:1050 +#, fuzzy, c-format +#| msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Lo cambiament de nom del fichièr « %s » cap a « %s » a fracassat : fracàs de " +"g_rename() : %s" + +#: glib/gfileutils.c:1176 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': write() failed: %s" +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "" +"L'escritura dins lo fichièr « %s » a fracassat : fracàs de write() : %s" + +#: glib/gfileutils.c:1197 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': fsync() failed: %s" +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "" +"L'escritura dins lo fichièr « %s » a fracassat : fracàs de fsync() : %s" + +#: glib/gfileutils.c:1358 glib/gfileutils.c:1773 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "La creacion del fichièr « %s » a fracassat : %s" + +#: glib/gfileutils.c:1403 +#, fuzzy, c-format +#| msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Lo fichièr existent « %s » pòt pas èsser suprimit : fracàs de g_unlink() : %s" + +#: glib/gfileutils.c:1738 +#, fuzzy, c-format +#| msgid "Template '%s' invalid, should not contain a '%s'" +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Lo modèl « %s » es pas valid, deuriá pas conténer un « %s »" + +#: glib/gfileutils.c:1751 +#, fuzzy, c-format +#| msgid "Template '%s' doesn't contain XXXXXX" +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Lo modèl « %s » conten pas XXXXXX" + +#: glib/gfileutils.c:2311 glib/gfileutils.c:2340 +#, fuzzy, c-format +#| msgid "Failed to read the symbolic link '%s': %s" +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "La lectura del ligam simbolic « %s » a fracassat : %s" + +#: glib/giochannel.c:1405 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s': %s" +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Impossible de dobrir lo convertidor de « %s » cap a « %s » : %s" + +#: glib/giochannel.c:1758 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_line_string" +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Lectura de donadas brutas impossibla dins g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Donadas restantas pas convertidas dins lo tampon de lectura" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "La canal s'acaba amb un caractèr parcial" + +#: glib/giochannel.c:1949 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_to_end" +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Lectura de donadas brutas impossibla dins g_io_channel_read_to_end" + +#: glib/gkeyfile.c:791 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Impossible de trobar un fichièr de claus valid dins los repertòris de recèrca" + +#: glib/gkeyfile.c:828 +msgid "Not a regular file" +msgstr "Es pas un fichièr estandard" + +#: glib/gkeyfile.c:1283 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains line '%s' which is not a key-value pair, group, or " +#| "comment" +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Lo fichièr de claus conten la linha « %s » qu'es pas ni una para de valors " +"de clau, ni un grop, ni un comentari" + +#: glib/gkeyfile.c:1340 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nom de grop invalid : %s" + +#: glib/gkeyfile.c:1362 +msgid "Key file does not start with a group" +msgstr "Lo fichièr de claus comença pas per un grop" + +#: glib/gkeyfile.c:1388 +#, c-format +msgid "Invalid key name: %s" +msgstr "Nom de clau invalid : %s" + +#: glib/gkeyfile.c:1415 +#, fuzzy, c-format +#| msgid "Key file contains unsupported encoding '%s'" +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "" +"Lo fichièr de claus conten un encodatge de caractèrs pas preses en carga « " +"%s »" + +#: glib/gkeyfile.c:1664 glib/gkeyfile.c:1837 glib/gkeyfile.c:3287 +#: glib/gkeyfile.c:3351 glib/gkeyfile.c:3481 glib/gkeyfile.c:3613 +#: glib/gkeyfile.c:3759 glib/gkeyfile.c:3994 glib/gkeyfile.c:4061 +#, fuzzy, c-format +#| msgid "Key file does not have group '%s'" +msgid "Key file does not have group “%sâ€" +msgstr "Lo fichièr de claus a pas de grop « %s »" + +#: glib/gkeyfile.c:1792 +#, fuzzy, c-format +#| msgid "Key file does not have key '%s' in group '%s'" +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Lo fichièr de claus conten pas de clau « %s » dins lo grop « %s »" + +#: glib/gkeyfile.c:1954 glib/gkeyfile.c:2070 +#, fuzzy, c-format +#| msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Lo fichièr de claus conten la clau « %s » amb la valor « %s » qu'es pas " +"encodat en UTF-8" + +#: glib/gkeyfile.c:1974 glib/gkeyfile.c:2090 glib/gkeyfile.c:2529 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' which has a value that cannot be interpreted." +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Lo fichièr de claus conten la clau « %s » qu'una valor n'es impossibla a " +"interpretar." + +#: glib/gkeyfile.c:2747 glib/gkeyfile.c:3116 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' in group '%s' which has a value that cannot be " +#| "interpreted." +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Lo fichièr de claus conten la clau « %s » dins lo grop « %s » qu'a una valor " +"impossibla a interpretar." + +#: glib/gkeyfile.c:2825 glib/gkeyfile.c:2902 +#, fuzzy, c-format +#| msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"La clau « %s » dins lo grop « %s » a una valor « %s » mentre que %s èra " +"esperat" + +#: glib/gkeyfile.c:4304 +msgid "Key file contains escape character at end of line" +msgstr "Lo fichièr de claus conten un caractèr d'escapament en fin de linha" + +#: glib/gkeyfile.c:4326 +#, fuzzy, c-format +#| msgid "Key file contains invalid escape sequence '%s'" +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Lo fichièr de claus conten una sequéncia d'escapament invalida « %s »" + +#: glib/gkeyfile.c:4470 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a number." +msgid "Value “%s†cannot be interpreted as a number." +msgstr "La valor « %s » pòt pas èsser interpretada coma un nombre." + +#: glib/gkeyfile.c:4484 +#, fuzzy, c-format +#| msgid "Integer value '%s' out of range" +msgid "Integer value “%s†out of range" +msgstr "La valor entièra « %s » es fòra plaja" + +#: glib/gkeyfile.c:4517 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a float number." +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "" +"La valor « %s » pòt pas èsser interpretada coma un nombre a virgula flotanta." + +#: glib/gkeyfile.c:4556 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a boolean." +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "La valor « %s » pòt pas èsser interpretada coma un boolean." + +#: glib/gmappedfile.c:129 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"L'obtencion dels atributs del fichièr « %s%s%s%s » a fracassat : fracàs de " +"fstat() : %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Lo mappage %s%s%s%s a fracassat : fracàs de mmap() : %s" + +#: glib/gmappedfile.c:262 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': open() failed: %s" +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "La dobertura del fichièr « %s » a fracassat : fracàs de open() : %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Error a la linha %d, caractèr %d : " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, fuzzy, c-format +#| msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Encodatge UTF-8 invalid dins lo nom - « %s » es pas valid" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "« %s » es pas un nom valid" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "« %s » es pas un nom valid : « %c »" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Error a la linha %d : %s" + +#: glib/gmarkup.c:690 +#, fuzzy, c-format +#| msgid "" +#| "Failed to parse '%-.*s', which should have been a digit inside a " +#| "character reference (ê for example) - perhaps the digit is too large" +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Fracàs de l'analisi de « %-.*s » que deuriá èsser un nombre dins la plaja de " +"referéncia dels caractèrs (ê per exemple) - benlèu que lo nombre es " +"tròp grand" + +#: glib/gmarkup.c:702 +#, fuzzy +#| msgid "" +#| "Character reference did not end with a semicolon; most likely you used an " +#| "ampersand character without intending to start an entity - escape " +#| "ampersand as &" +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"La referéncia del caractèr s'acaba pas per un punt-virgula ; avètz " +"vraisemblablement utilizat una esperlueta sens intention d'escriure una " +"entitat - escapatz l'esperlueta amb &" + +#: glib/gmarkup.c:728 +#, fuzzy, c-format +#| msgid "Character reference '%-.*s' does not encode a permitted character" +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "La referéncia al caractèr « %-.*s » encòda pas un caractèr autorizat" + +#: glib/gmarkup.c:766 +#, fuzzy +#| msgid "" +#| "Empty entity '&;' seen; valid entities are: & " < > '" +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Entitat voida « &; » rencontrada : las entitats validas son : & " " +"< > '" + +#: glib/gmarkup.c:774 +#, fuzzy, c-format +#| msgid "Entity name '%-.*s' is not known" +msgid "Entity name “%-.*s†is not known" +msgstr "L'entitat nomenada « %-.*s » es desconeguda" + +#: glib/gmarkup.c:779 +#, fuzzy +#| msgid "" +#| "Entity did not end with a semicolon; most likely you used an ampersand " +#| "character without intending to start an entity - escape ampersand as &" +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"L'entitat s'acaba pas per un punt-virgula ; avètz probablament utilizat una " +"esperlueta sens intention d'escriure una entitat - escapatz l'esperlueta amb " +"&" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Lo document deu començar amb un element (per ex. )" + +#: glib/gmarkup.c:1233 +#, fuzzy, c-format +#| msgid "" +#| "'%s' is not a valid character following a '<' character; it may not begin " +#| "an element name" +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"« %s » es pas un caractèr valid en seguida del caractèr « < » ; sembla que " +"comença pas un nom d'element" + +#: glib/gmarkup.c:1276 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' character to end the empty-element tag " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Caractèr anormal « %s », un caractèr « > » es requesit per acabar la balisa " +"d'element void « %s »" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "" + +#: glib/gmarkup.c:1366 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '=' after attribute name '%s' of element " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Caractèr anormal « %s », un caractèr « = » es requesit aprèp lo nom de " +"l'atribut « %s » de l'element « %s »" + +#: glib/gmarkup.c:1408 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' or '/' character to end the start tag " +#| "of element '%s', or optionally an attribute; perhaps you used an invalid " +#| "character in an attribute name" +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Caractèr anormal « %s », es requesit un caractèr « > » o « / », o " +"opcionalament un atribut, per clore la balisa de començament de l'element « " +"%s » ; benlèu qu'avètz utilizat un caractèr invalid dins un nom d'atribut" + +#: glib/gmarkup.c:1453 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected an open quote mark after the equals sign " +#| "when giving value for attribute '%s' of element '%s'" +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Caractèr anormal « %s », una vergueta de dobertura aprèp lo signe egal es " +"requesit quand s'afècta una valor a l'atribut « %s » de l'element « %s »" + +#: glib/gmarkup.c:1587 +#, fuzzy, c-format +#| msgid "" +#| "'%s' is not a valid character following the characters ''" +msgid "" +"“%s†is not a valid character following the close element name “%sâ€; the " +"allowed character is “>â€" +msgstr "" +"« %s » es pas un caractèr valid en seguida del nom d'element « %s » a " +"tampar ; lo caractèr autorizat es « > »" + +#: glib/gmarkup.c:1637 +#, fuzzy, c-format +#| msgid "Element '%s' was closed, no element is currently open" +msgid "Element “%s†was closed, no element is currently open" +msgstr "" +"L'element « %s » es estat tampat, cap d'element es pas actualament dobèrt" + +#: glib/gmarkup.c:1646 +#, fuzzy, c-format +#| msgid "Element '%s' was closed, but the currently open element is '%s'" +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"L'element « %s » es estat tampat, mas l'element actualament dobèrt es « %s »" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Lo document èra void o conteniá pas que d'espacis" + +#: glib/gmarkup.c:1813 +#, fuzzy +#| msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Lo document s'es acabat d'un biais imprevist juste aprèp un crochet ouvrant " +"« < »" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, fuzzy, c-format +#| msgid "" +#| "Document ended unexpectedly with elements still open - '%s' was the last " +#| "element opened" +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Lo document s'es acabat d'un biais imprevist amb d'elements encara dobèrts - " +"« %s » èra lo darrièr element dobèrt" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Lo document s'es acabat d'un biais imprevist, un crochet fermant per la " +"balisa <%s/> es requesit" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "" +"Lo document s'es acabat d'un biais imprevist a l'interior d'un nom d'element" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" +"Lo document s'es acabat d'un biais imprevist a l'interior d'un nom d'atribut" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Lo document s'es acabat d'un biais imprevist a l'interior d'una balisa de " +"dobertura d'element." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Lo document s'es acabat d'un biais imprevist aprèp lo signe egal que seguis " +"un nom d'atribut ; pas cap de valor d'atribut" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"Lo document s'es acabat d'un biais imprevist mentre qu'èra a l'interior " +"d'una valor d'atribut" + +#: glib/gmarkup.c:1876 +#, fuzzy, c-format +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Lo document s'es acabat d'un biais imprevist a l'interior de la balisa de " +"tampadura per l'element « %s »" + +#: glib/gmarkup.c:1880 +#, fuzzy +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Lo document s'es acabat d'un biais imprevist a l'interior de la balisa de " +"tampadura per l'element « %s »" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Lo document s'es acabat d'un biais imprevist a l'interior d'un comentari o " +"d'una instruccion de tractament" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPCION...]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opcions de l'ajuda :" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Aficha las opcions de l'ajuda" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Aficha totas las opcions de l'ajuda" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opcions de l'aplicacion :" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opcions :" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Impossible d'analisar la valor entièra « %s » per %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, fuzzy, c-format +#| msgid "Integer value '%s' for %s out of range" +msgid "Integer value “%s†for %s out of range" +msgstr "La valor entièra « %s » per %s es fòra plaja" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Impossible d'analisar la valor dobla « %s » per %s" + +#: glib/goption.c:1168 +#, fuzzy, c-format +#| msgid "Double value '%s' for %s out of range" +msgid "Double value “%s†for %s out of range" +msgstr "La valor dobla « %s » per %s es fòra plaja" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Error al moment de l'analisi de l'opcion %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Argument mancant per %s" + +#: glib/goption.c:2185 +#, c-format +msgid "Unknown option %s" +msgstr "Opcion desconeguda %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "objècte damatjat" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "error intèrna o objècte damatjat" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "memòria insufisenta" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "limit de seguiment arrièr atent" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"lo motiu conten d'elements pas preses en carga per una correspondéncia " +"parciala" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "error intèrna" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"las referéncias inverses utilizadas coma condicions son pas presas en carga " +"per una correspondéncia parciala" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "limit de recursivitat atent" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "combinason de marcadors de novèla linha invalida" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "marrit décalage" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 cort" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "bocla recursiva" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "error desconeguda" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ a la fin del motiu" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c a la fin del motiu" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "un caractèr pas reconegut suit \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "nombres en desòrdre dins lo quantificador {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "nombre tròp grand dins lo quantificador {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "caractèr terminason ] mancant per la classa de caractèr" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "sequéncia d'escapament invalida dins la classa de caractèr" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "plaja déclassada dins la classa de caractèr" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "pas res de repetir" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "repeticion inesperada" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "caractèr pas reconegut aprèp (? o (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "" +"Las classas nomenadas segon la nòrma POSIX son unicament presas en carga " +"dins una classa" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr ") de terminason mancanta" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referéncia a un sosmotiu inexistent" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "« ) » mancanta aprèp un comentari" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "l'expression regulara es tròp granda" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "l'obtencion de la memòria a fracassat" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") sens ( de dobertura" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "depassament de còdi" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "caractèr pas reconegut aprèp (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "l'assercion « lookbehind » a pas de longor fixe" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "nom o nombre non confòrme aprèp (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "un grop condicional conten mai de doas brancas" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "une assercion es esperada aprèp (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "« (?R » o « (?[+-]chifras » devon èsser seguits d'una « ) »" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nom de classa POSIX desconegut" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "los elements d'interclassament POSIX son pas preses en carga" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "la valor del caractèr dins la sequéncia \\x{...} es tròp granda" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condicion (?(0) invalida" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C es pas autorizat dins l'assercion « lookbehind »" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "los escapaments \\L, \\l, \\N{name}, \\U e \\u son pas preses en carga" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "un apèl recursiu pòt efectuar de boclas indefinidament" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "caractèr pas reconegut aprèp (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "terminason mancanta dins lo nom del sosmotiu" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dos sosmotius nomenats possedisson lo meteis nom" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "sequéncia \\P o \\p mal formada" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nom de proprietat desconegut aprèp \\P o \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "lo nom del sosmotiu es tròp long (32 caractèrs maximum)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "tròp de sosmotius nomenats (10 000 maximum)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "la valor octala es mai granda que \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "depassament de capacitat en compilant l'espaci de trabalh" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "un sosmotiu referenciat e precedentament verificat es pas estat trobat" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "lo grop DEFINE conten mai d'una branca" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opcions NEWLINE inconsistentas" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g es pas seguit d'un nom o nombre entre acoladas, cabirons, verguetas " +"simplas o d'un nombre simple" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "une referéncia numerotada deu pas èsser zèro" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "un argument es pas permés per (*ACCEPT), (*FAIL) o (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) pas reconegut" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "lo nombre es tròp grand" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "nom de sosmotiu mancant aprèp (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "chifra esperat aprèp (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] es un caractèr de donadas invalid en mòde de compatibilitat JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" +"es pas permés d'aver de noms diferents per de sosmotius del meteis nombre" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) deu aver un argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c deu èsser seguit d'un caractèr ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k es pas seguit d'un nom entre accolades, chevrons o verguetas simplas" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N es pas pres en carga dins una classa" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "tròp de referéncias en avant" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "lo nom es tròp long dins (*MARK), (*PRUNE), (*SKIP) o (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "la valor del caractèr dins la sequéncia \\u.... es tròp granda" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Error al moment de la correspondéncia de l'expression regulara %s : %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "La bibliotèca PCRE es compilada sens la presa en carga UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" +"La bibliotèca PCRE es compilada sens la presa en carga de las proprietats " +"UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "La bibliotèca PCRE es compilada amb d'opcions incompatiblas" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Error al moment de l'optimizacion de l'expression regulara %s : %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Error a la compilation de l'expression regulara %s al caractèr %d : %s" + +#: glib/gregex.c:2427 +#, fuzzy +#| msgid "hexadecimal digit or '}' expected" +msgid "hexadecimal digit or “}†expected" +msgstr "chifra exadecimala o « } » esperat" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "chifra exadecimala esperat" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "« < » mancant dins la referéncia simbolica" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "referéncia simbolica pas acabada" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "referéncia simbolica de longor nulla" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "chifra esperada" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "referéncia simbolica illegala" + +#: glib/gregex.c:2591 +#, fuzzy +#| msgid "stray final '\\'" +msgid "stray final “\\â€" +msgstr "terminason parasita « \\ »" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "sequéncia d'escapament desconeguda" + +#: glib/gregex.c:2605 +#, fuzzy, c-format +#| msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Error al moment de l'analisi del tèxte de substitucion « %s » al caractèr " +"%lu : %s" + +#: glib/gshell.c:96 +#, fuzzy +#| msgid "Quoted text doesn't begin with a quotation mark" +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Lo tèxte citat comença pas per de verguetas" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Verguetas de tampadura introbablas dins la linha de comanda o autre tèxte " +"rapporté" + +#: glib/gshell.c:592 +#, fuzzy, c-format +#| msgid "Text ended just after a '\\' character. (The text was '%s')" +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "" +"Lo tèxte s'es acabat juste aprèp un caractèr « \\ » (lo tèxte èra « %s »)." + +#: glib/gshell.c:599 +#, fuzzy, c-format +#| msgid "" +#| "Text ended before matching quote was found for %c. (The text was '%s')" +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Lo tèxte s'es acabat abans que de verguetas correspondentas sián rencontrats " +"per %c (lo tèxte èra « %s »)." + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Lo tèxte èra void (o conteniá pas que d'espacis)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "La lectura de las donadas dempuèi lo processus filh a fracassat (%s)" + +#: glib/gspawn.c:461 +#, fuzzy, c-format +#| msgid "Unexpected error in select() reading data from a child process (%s)" +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "" +"Error inesperada dins select() a la lectura de las donadas dempuèi un " +"processus filh (%s)" + +#: glib/gspawn.c:546 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Error inesperada dins waitpid() (%s)" + +#: glib/gspawn.c:1166 glib/gspawn-win32.c:1407 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Lo processus filh s'es acabat amb lo còdi %ld" + +#: glib/gspawn.c:1174 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Lo processus filh es estat tuat pel senhal %ld" + +#: glib/gspawn.c:1181 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Lo processus filh es estat arrestat pel senhal %ld" + +#: glib/gspawn.c:1188 +#, c-format +msgid "Child process exited abnormally" +msgstr "Lo processus filh s'es acabat anormalement" + +#: glib/gspawn.c:1855 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "La lectura dempuèi un tub filh a fracassat (%s)" + +#: glib/gspawn.c:2157 +#, fuzzy, c-format +#| msgid "Failed to fork child process (%s)" +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Lo clonatge del processus filh a fracassat (%s)" + +#: glib/gspawn.c:2274 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Lo clonatge a fracassat (%s)" + +#: glib/gspawn.c:2434 glib/gspawn-win32.c:381 +#, fuzzy, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to change to directory “%s†(%s)" +msgstr "Lo cambiament de repertòri « %s » a fracassat (%s)" + +#: glib/gspawn.c:2444 +#, fuzzy, c-format +#| msgid "Failed to execute child process \"%s\" (%s)" +msgid "Failed to execute child process “%s†(%s)" +msgstr "L'execucion del processus filh « %s » a fracassat (%s)" + +#: glib/gspawn.c:2454 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"La redireccion de la sortida o de l'entrada del processus filh a fracassat " +"(%s)" + +#: glib/gspawn.c:2463 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Lo clonatge del processus filh a fracassat (%s)" + +#: glib/gspawn.c:2471 +#, fuzzy, c-format +#| msgid "Unknown error executing child process \"%s\"" +msgid "Unknown error executing child process “%sâ€" +msgstr "Error desconeguda a l'execucion del processus filh « %s »" + +#: glib/gspawn.c:2495 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Impossible de legir pro de donadas dempuèi lo tub del processus filh de pid " +"(%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "La lectura de las donadas dempuèi lo processus filh a fracassat" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "L'execucion del processus filh a fracassat (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nom de programa invalid : %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:779 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Cadena invalida dins l'argument vector a %d : %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:794 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Cadena invalida dins l'environament : %s" + +#: glib/gspawn-win32.c:775 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Repertòri de trabalh invalid : %s" + +#: glib/gspawn-win32.c:837 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "L'execucion del programa d'ajuda a fracassat (%s)" + +#: glib/gspawn-win32.c:1064 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Error inesperada dins g_io_channel_win32_poll() al moment de la lectura de " +"las donadas dempuèi un processus fils" + +#: glib/gstrfuncs.c:3345 glib/gstrfuncs.c:3447 +msgid "Empty string is not a number" +msgstr "" + +#: glib/gstrfuncs.c:3369 +#, c-format +msgid "“%s†is not a signed number" +msgstr "« %s » es pas un nombre valid" + +#: glib/gstrfuncs.c:3379 glib/gstrfuncs.c:3483 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: glib/gstrfuncs.c:3473 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "« %s » es pas un nombre pas signat" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-encoding invalid dins l'URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Caractèr defendut dins l’URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caractèrs non-UTF-8 dins l'URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Adreça IPv6 invalida « %.*s » dins l’URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Impossible d’analisar lo pòrt « %.*s » dins l’URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "L’URI « %s » es pas una URI absoluta" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "Impossible d'alogar de la memòria" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "Caractèr fòra plaja per UTF-8" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "Sequéncia invalida dins l'entrada del convertidor" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "Caractèr fòra plaja per UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2730 +#, c-format +msgid "%.1f kB" +msgstr "%.1f ko" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2732 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mo" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2734 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Go" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2736 +#, c-format +msgid "%.1f TB" +msgstr "%.1f To" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2738 +#, c-format +msgid "%.1f PB" +msgstr "%.1f Po" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2740 +#, c-format +msgid "%.1f EB" +msgstr "%.1f Eo" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2744 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f Kio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2746 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f Mio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2748 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f Gio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2750 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f Tio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2752 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f Pio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2754 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f Eio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2758 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2760 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2762 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2764 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2766 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2768 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2772 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2774 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2776 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2778 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2780 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pio" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2782 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eio" + +#: glib/gutils.c:2816 glib/gutils.c:2933 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u octet" +msgstr[1] "%u octets" + +#: glib/gutils.c:2820 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u octet" +msgstr[1] "%u octets" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2887 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s octet" +msgstr[1] "%s octets" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2892 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s octet" +msgstr[1] "%s octets" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2946 +#, c-format +msgid "%.1f KB" +msgstr "%.1f Ko" + +#: glib/gutils.c:2951 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mo" + +#: glib/gutils.c:2956 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Go" + +#: glib/gutils.c:2961 +#, c-format +msgid "%.1f TB" +msgstr "%.1f To" + +#: glib/gutils.c:2966 +#, c-format +msgid "%.1f PB" +msgstr "%.1f Po" + +#: glib/gutils.c:2971 +#, c-format +msgid "%.1f EB" +msgstr "%.1f Eo" + +#~ msgid "Error in address '%s' - the family attribute is malformed" +#~ msgstr "Error dins l'adreça « %s » — l'atribut de la familha es mal format" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Error a la creacion del repertòri « %s » : %s" + +#~ msgid "No such interface" +#~ msgstr "Interfàcia pas reconeguda" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Lo messatge compòrta %d descriptors de fichièrs mentre que lo camp " +#~ "d'entèsta indica %d descriptors de fichièrs" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "Cargament de /var/lib/dbus/machine-id o /etc/machine-id impossible : " + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Error : lo senhal es pas precisat.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Error : lo senhal deu èsser lo nom completament qualificat.\n" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Error al moment de l'obtencion dels atributs en escritura : %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Error de montatge d'emplaçament : %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Error de desmontatge : %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Error de descoberta del montatge de basa : %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Error d'ejeccion del montatge : %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Error de montatge de %s : %s\n" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s es estat montat sus %s\n" + +#~ msgid "No files to open" +#~ msgstr "Pas cap de fichièr de dobrir" + +#~ msgid "No files to delete" +#~ msgstr "Pas cap de fichièr de suprimir" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Error al moment de la definicion de l'atribut : %s\n" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "La creacion del fichièr temporari a fracassat : %s" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; la redefinicion d'aquesta clau es estada ignorada.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " e --strict es estat especificat ; sortida en cors.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "La redefinicion d'aquesta clau es estada ignorada.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "cap d'accion pas efectuada.\n" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Error al moment de la dobertura del fichièr « %s » : %s" + +#~ msgid "Unknown error on connect" +#~ msgstr "Error desconeguda a la connexion" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Error de lectura del fichièr « %s » : %s" + +#~ msgid "Error getting filesystem info: %s" +#~ msgstr "Impossible d'obténer las informacions del sistèma de fichièrs : %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Error al cambiament de nom del fichièr : %s" + +#~ msgid "Can't open directory" +#~ msgstr "Impossible de dobrir lo repertòri" + +#~ msgid "Error opening file: %s" +#~ msgstr "Error a la dobertura del fichièr : %s" + +#~ msgid "Error removing file: %s" +#~ msgstr "Error a la supression del fichièr : %s" + +#~ msgid "Unable to find toplevel directory for trash" +#~ msgstr "Impossible de trobar lo repertòri raiç per l'escobilhièr" + +#~ msgid "Unable to find or create trash directory" +#~ msgstr "Impossible de trobar o crear lo repertòri de l'escobilhièr" + +#~ msgid "Unable to trash file: %s" +#~ msgstr "Impossible de metre a l'escobilhièr lo fichièr : %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Error a la creacion del repertòri : %s" + +#~ msgid "Error making symbolic link: %s" +#~ msgstr "Error al moment de la creacion del ligam simbolic : %s" + +#~ msgid "Error moving file: %s" +#~ msgstr "Error al moment del desplaçament del fichièr : %s" + +#~ msgid "Error trashing file: %s" +#~ msgstr "Error al moment de la mesa a l'escobilhièr del fichièr : %s" + +#~ msgid "Unable to create trashing info file: %s" +#~ msgstr "" +#~ "Impossible de crear lo fichièr d'informacions de mesa a l'escobilhièr : %s" + +#~ msgid "" +#~ "Usage:\n" +#~ " gsettings --version\n" +#~ " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#~ "\n" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " list-schemas List installed schemas\n" +#~ " list-relocatable-schemas List relocatable schemas\n" +#~ " list-keys List keys in a schema\n" +#~ " list-children List children of a schema\n" +#~ " list-recursively List keys and values, recursively\n" +#~ " range Queries the range of a key\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " reset-recursively Reset all values in a given schema\n" +#~ " writable Check if a key is writable\n" +#~ " monitor Watch for changes\n" +#~ "\n" +#~ "Use 'gsettings help COMMAND' to get detailed help.\n" +#~ "\n" +#~ msgstr "" +#~ "Utilizacion :\n" +#~ " gsettings --version\n" +#~ " gsettings [--schemadir REPERTÃ’RI2ESQUÈMA] COMANDA [PARAMÈTRES...]\n" +#~ "\n" +#~ "Comandas :\n" +#~ " help Aficha la presenta informacion\n" +#~ " list-schemas Lista los esquèmas installats\n" +#~ " list-relocatable-schemas Lista los esquèmas readreçables\n" +#~ " list-keys Lista las claus dins un esquèma\n" +#~ " list-children Lista los enfants d'un esquèma\n" +#~ " list-recursively Lista las claus e las valors, recursivament\n" +#~ " range Demanda lo domeni de validitat de la clau\n" +#~ " get Renvia la valor d'una clau\n" +#~ " set Definís la valor d'una clau\n" +#~ " reset Restablís la valor per defaut d'una clau\n" +#~ " reset-recursively Restablís totas las valors dins un esquèma " +#~ "donat\n" +#~ " writable Tèsta se la clau es inscriptible\n" +#~ " monitor Contraròtla las modificacions\n" +#~ "\n" +#~ "Picatz 'gsettings help COMANDA' per una ajuda detalhada.\n" +#~ "\n" + +#~ msgid "association changes not supported on win32" +#~ msgstr "" +#~ "Les modifications d'association ne son pas prises en en carga sus win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "La creacion d'associacions es pas presa en carga sus win32" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "" +#~ "Impossible de trobar lo tipe de monitor de repertòri local per defaut" + +#~ msgid "URIs not supported" +#~ msgstr "URI pas pres en carga" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Lo fichièr de claus a pas de clau « %s »" diff --git a/po/or.po b/po/or.po new file mode 100644 index 0000000..1cb9752 --- /dev/null +++ b/po/or.po @@ -0,0 +1,4843 @@ +# translation of glib.master.or.po to Oriya +# translation of or.po to +# Oriya translation of glib.glib-2-4.or.pot. +# Copyright (C) 2004, 2006, 2007, 2008, 2009, Free Software Foundation, Inc. +# This file is distributed under the same license as the glib.glib-2-4 package. +# $Id: or.po,v 1.37 2006/08/16 00:43:58 matthiasc Exp $ +# +# Subhransu Behera , 2004, 2006, 2007. +# Manoj Kumar Giri , 2008, 2009, 2011, 2012, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: glib.master.or\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-08-22 05:54+0000\n" +"PO-Revision-Date: 2014-08-27 19:04+0530\n" +"Last-Translator: Manoj Kumar Giri \n" +"Language-Team: Oriya \n" +"Language: or\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" + +#: ../gio/gapplication.c:514 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"GApplication ସରà­à¬­à¬¿à¬¸ ଧାରା ଭରଣ କରନà­à¬¤à­ (D-Bus ସରà­à¬­à¬¿à¬¸ ଫାଇଲଗà­à¬¡à¬¼à¬¿à¬•ରୠବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରନà­à¬¤à­)" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "GApplication options" +msgstr "GApplication ବିକଳà­à¬ªà¬—à­à¬¡à¬¼à¬¿à¬•" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "GApplication ବିକଳà­à¬ªà¬—à­à¬¡à¬¼à¬¿à¬•ୠଦରà­à¬¶à¬¾à¬¨à­à¬¤à­" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:481 ../gio/gsettings-tool.c:508 +msgid "Print help" +msgstr "ସହାୟତାକୠମà­à¬¦à­à¬°à¬£ କରନà­à¬¤à­" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:482 +#: ../gio/gresource-tool.c:550 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gapplication-tool.c:49 +#| msgid "Print address" +msgid "Print version" +msgstr "ମà­à¬¦à­à¬°à¬£ ସଂସà­à¬•ରଣ" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:514 +msgid "Print version information and exit" +msgstr "ସଂସà­à¬•ରଣ ସୂଚନା ମà­à¬¦à­à¬°à¬£ କରି ପà­à¬°à¬¸à­à¬¥à¬¾à¬¨ କରନà­à¬¤à­" + +#: ../gio/gapplication-tool.c:52 +#| msgid "Can't find application" +msgid "List applications" +msgstr "ପà­à¬°à­Ÿà­‹à¬—ଗà­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"ସà­à¬¥à¬¾à¬ªà¬¿à¬¤ D-Bus ସକà­à¬°à¬¿à­Ÿà¬£à¬¯à­‹à¬—à­à­Ÿ ପà­à¬°à­Ÿà­‹à¬—ଗà­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­ ( .desktop " +"ଫାଇଲଗà­à¬¡à¬¼à¬¿à¬• ଦà­à­±à¬¾à¬°à¬¾)" + +#: ../gio/gapplication-tool.c:55 +#| msgid "Can't find application" +msgid "Launch an application" +msgstr "ଗୋଟିଠପà­à¬°à­Ÿà­‹à¬— ଆରମà­à¬­ କରନà­à¬¤à­" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "à¬à¬¹à¬¿ ପà­à¬°à­Ÿà­‹à¬—କୠଆରମà­à¬­ କରନà­à¬¤à­ (ଖୋଲିବା ପାଇଠବୈକଳà­à¬ªà¬¿à¬• ଫାଇଲଗà­à¬¡à¬¼à¬¿à¬• ସହିତ)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "ଗୋଟିଠକାରà­à¬¯à­à­Ÿà¬•ୠସକà­à¬°à¬¿à­Ÿ କରନà­à¬¤à­" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "ପà­à¬°à­Ÿà­‹à¬— ଉପରେ à¬à¬• କାରà­à¬¯à­à­Ÿà¬•ୠଉପଯୋଗ କରନà­à¬¤à­" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "ଉପଲବà­à¬§ କାରà­à¬¯à­à­Ÿà¬—à­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"à¬à¬• ପà­à¬°à­Ÿà­‹à¬— ପାଇଠସà­à¬¥à¬¾à­Ÿà­€ କାରà­à¬¯à­à¬¯à¬—à­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­ (.desktop ଫାଇଲରà­)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "à¬à¬¹à¬¾ ପାଇଠବିଶେଷ ସହାୟତାକୠମà­à¬¦à­à¬°à¬£ କରିବା ପାଇଠନିରà­à¬¦à­à¬¦à­‡à¬¶" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus ଶୈଳୀରେ ପà­à¬°à­Ÿà­‹à¬— ପରିଚାୟକ (ଯେପରିକି: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:488 +#: ../gio/gresource-tool.c:554 +msgid "FILE" +msgstr "FILE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "" +"ବୈକଳà­à¬ªà¬¿à¬• ସମà­à¬ªà­ƒà¬•à­à¬¤ କିମà­à¬¬à¬¾ ସମà­à¬ªà¬°à­à¬•ୀୟ ଫାଇଲନାମଗà­à¬¡à¬¼à¬¿à¬•, ଅଥବା ଖୋଲିବା ପାଇଠଥିବା URI " +"ଗà­à¬¡à¬¼à¬¿à¬•" + +#: ../gio/gapplication-tool.c:73 +#| msgid "SECTION" +msgid "ACTION" +msgstr "କାରà­à¬¯à­à¬¯" + +#: ../gio/gapplication-tool.c:73 +#| msgid "Destination name to introspect" +msgid "The action name to invoke" +msgstr "ଉପଯୋଗ କରିବା ପାଇଠକାରà­à¬¯à­à­Ÿà¬° ନାମ" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "ପà­à¬°à¬¾à¬šà¬³" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "ଉପଯୋଗ କାରà­à¬¯à­à­Ÿ ପାଇଠଇଚà­à¬›à¬¾à¬§à­€à¬¨ ପà­à¬°à¬¾à¬šà¬³, GVariant ଶୈଳୀରେ" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:519 +#: ../gio/gsettings-tool.c:594 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"ଅଜଣା ନିରà­à¬¦à­à¬¦à­‡à¬¶ %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +#| msgid "Usage:" +msgid "Usage:\n" +msgstr "ବà­à¬¯à¬¬à¬¹à¬¾à¬°:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:544 +#: ../gio/gsettings-tool.c:628 +msgid "Arguments:\n" +msgstr "ସà­à­±à¬¤à¬¨à­à¬¤à­à¬°à¬šà¬°à¬—à­à¬¡à¬¼à¬¿à¬•:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "ନିରà­à¬¦à­à¬¦à­‡à¬¶à¬—à­à¬¡à¬¿à¬•:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"ବିଶେଷ ସହାୟତା ପାଇଠ'%s help COMMAND' ବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରନà­à¬¤à­à¥¤\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s ନିରà­à¬¦à­à¬¦à­‡à¬¶ ସିଧାସଳଖ ଭାବରେ ଅନà­à¬¸à¬°à¬£ କରିବା ପାଇଠଗୋଟିଠପà­à¬°à­Ÿà­‹à¬— id ଆବଶà­à­Ÿà¬• କରିଥାà¬\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +#| msgid "invalid GVariant type string '%s'" +msgid "invalid application id: '%s'\n" +msgstr "ଅବୈଧ ପà­à¬°à­Ÿà­‹à¬— id: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' କୌଣସି ସà­à­±à¬¤à¬¨à­à¬¤à­à¬°à¬šà¬° ନେଇନଥାà¬\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +#| msgid "Could not connect to %s: " +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus ସହିତ ସଂଯୋଗ କରିବାକୠଅସମରà­à¬¥: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "%s ସନà­à¬¦à­‡à¬¶à¬•ୠପà­à¬°à­Ÿà­‹à¬— ପାଖକୠପଠାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ ପà­à¬°à­Ÿà­‹à¬— id ପରେ କାରà­à¬¯à­à­Ÿà¬° ନାମ ଦେବା ଉଚିତ\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"ଅବୈଧ କାରà­à¬¯à­à¬¯ ନାମ: '%s'\n" +"କାରà­à¬¯à­à¬¯ ନାମଗà­à¬¡à¬¼à¬¿à¬• ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ କେବଳ ଅକà­à¬·à¬° ସାଂଖିକ, '-' à¬à¬¬à¬‚ '.' ହେବା ଉଚିତ\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "କାରà­à¬¯à­à¬¯ ପà­à¬°à¬¾à¬šà¬³à¬•ୠବିଶà­à¬³à­‡à¬·à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "କାରà­à¬¯à­à¬¯à¬—à­à¬¡à¬¼à¬¿à¬• ସରà­à¬¬à¬¾à¬§à¬¿à¬• ଗୋଟିଠପà­à¬°à¬¾à¬šà¬³ ଗà­à¬°à¬¹à¬£ କରିଥାà¬\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "ତାଲିକା କାରà­à¬¯à­à­Ÿ ନିରà­à¬¦à­à¬¦à­‡à¬¶ କେବଳ ପà­à¬°à­Ÿà­‹à¬— id ନେଇଥାà¬" + +#: ../gio/gapplication-tool.c:421 +#, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "ପà­à¬°à­Ÿà­‹à¬— %s ପାଇଠଡେସà­à¬•ଟପ ଫାଇଲ ଖୋଜିବାରେ ଅସମରà­à¬¥\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +#| msgid "" +#| "Unknown command %s\n" +#| "\n" +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"ଅଜଣା ନିରà­à¬¦à­à¬¦à­‡à¬¶ :%s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:370 +#: ../gio/ginputstream.c:608 ../gio/ginputstream.c:828 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:823 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼ ଗଣନା ମୂଲà­à­Ÿ %sକୠପଠାଯାଇଛି" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "ମୂଳ ଧାରାରେ ଦà­à¬°à­à¬¬à¬³à¬¤à¬¾ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream କୠବିଚà­à¬›à¬¿à¬¨à­à¬¨ କରିହେବ ନାହିà¬" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1017 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1464 +msgid "Stream is already closed" +msgstr "ଧାରା ପୂରà­à¬¬à¬°à­ ବନà­à¬¦à¬…ଛି" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "ମୂଳ ଧାରାରେ କାଟିବା ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gcancellable.c:310 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "ପà­à¬°à­Ÿà­‹à¬—ଟି ବାତିଲ ହୋଇଛି" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "ଅବୈଧ ବସà­à¬¤à­, ଆରମà­à¬­ ହୋଇନାହିà¬" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "ନିବେଶରେ ଅସମà­à¬ªà­‚ରà­à¬£à­à¬£ à¬à¬•ାଧିକ ବାଇଟ କà­à¬°à¬®" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "ଲକà­à¬·à­à¬¯à¬¸à­à¬¥à¬³à¬°à­‡ ଯଥେଷà­à¬Ÿ ସà­à¬¥à¬¾à¬¨ ନାହିà¬" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "ରà­à¬ªà¬¾à¬¨à­à¬¤à¬°à¬£ ନିବେଶେର ଅବୈଧ ବାଇଟୠଅନà­à¬•à­à¬°à¬®" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "ରà­à¬ªà¬¾à¬¨à­à¬¤à¬°à¬£à¬°à­‡ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "ବାତିଲଯୋଗà­à­Ÿ ପà­à¬°à¬¾à¬°à¬®à­à¬­à¬¿à¬•ରଣ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "ଅକà­à¬·à¬° ସେଟୠ'%s'କୠ'%s'େର ରୂପାନà­à¬¤à¬°à¬¿à¬¤ କରିବା ଅସହାୟକ" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s'ରୠ'%s'ର ରà­à¬ªà¬¾à¬¨à­à¬¤à¬°à¬• ଖୋଲି ହେଲା ନାହିà¬" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s ପà­à¬°à¬•ାର" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "ଅଜଣା ପà­à¬°à¬•ାର" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s ଫାଇଲପà­à¬°à¬•ାର" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "à¬à¬¹à¬¿ OS ରେ GCredentials କୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରାଯାଇନାହିà¬" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "ଆପଣଙà­à¬• ପà­à¬²à¬¾à¬Ÿà¬«à¬°à­à¬® ପାଇଠକୌଣସି GCredentials ସହାୟତା ନାହିà¬" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "à¬à¬¹à¬¿ OS ରେ GCredentials କୌଣସି ପଦà­à¬§à¬¤à¬¿ ID ଧାରଣ କରିନଥାà¬" + +#: ../gio/gcredentials.c:565 +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "à¬à¬¹à¬¿ OS ରେ ଅଧିକାରଗà­à¬¡à¬¼à¬¿à¬•ୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରିବା ସମà­à¬­à¬¬ ନà­à¬¹à¬" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "ଅପà­à¬°à¬¤à­à­Ÿà¬¾à¬¶à¬¿à¬¤ ପà­à¬°à¬¾à¬°à¬®à­à¬­à¬¿à¬• ଧାରାର ଶେଷ" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "ଠିକଣା ଭରଣ '%s' ରେ ଅସମରà­à¬¥à¬¿à¬¤ କି '%s'" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"ଠିକଣା '%s' ଟି ଅବୈଧ ଅଟେ (କେବଳ ଗୋଟିଠପଥ ଆବଶà­à­Ÿà¬•, tmpdir କିମà­à¬¬à¬¾ କଢ଼ାଯାଇଥିବା " +"କିଗà­à¬¡à¬¼à¬¿à¬•)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "ଠିକଣା ଭରଣ '%s' ରେ ଅରà­à¬¥à¬¹à­€à¬¨ କି/ମୂଲà­à­Ÿ ଯà­à¬—ଳ" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "ଠିକଣା '%s' ରେ ତà­à¬°à­à¬Ÿà¬¿ - ପୋରà­à¬Ÿ ଗà­à¬£à¬§à¬°à­à¬®à¬Ÿà¬¿ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ଅଟେ" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "ଠିକଣା '%s' ରେ ତà­à¬°à­à¬Ÿà¬¿ - ପରିବାର ଗà­à¬£à¬§à¬°à­à¬®à¬Ÿà¬¿ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ଅଟେ" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "ଠିକଣା ଉପାଦନ '%s' ରେ କୌଣସି କଲନ (:) ନଥାà¬" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "କି/ମୂଲà­à­Ÿ ଯà­à¬—ଳ %d, '%s', ଠିକଣା ଉପାଦାନ '%s' ରେ ସମାନ ଚିହà­à¬¨ ଧାରଣ କରିନଥାà¬" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"କି/ମୂଲà­à­Ÿ ଯà­à¬—ଳ %d, '%s' ରେ କି କିମà­à¬¬à¬¾ ମୂଲà­à­Ÿà¬•ୠନଛଡ଼ାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿, ଠିକଣା ଉପାଦାନ'%" +"s' ରେ" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"ଠିକଣା '%s' ରେ ତà­à¬°à­à¬Ÿà¬¿ - unix ପରିବହନ 'path' ଅଥବା 'abstract' କିଗà­à¬¡à¬¼à¬¿à¬• ମଧà­à¬¯à¬°à­ " +"ଗୋଟିà¬à¬•ୠସେଟ " +"କରିବା ପାଇଠଆବଶà­à­Ÿà¬• କରିଥାà¬" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "ଠିକଣା '%s' ରେ ତà­à¬°à­à¬Ÿà¬¿ - ହୋଷà­à¬Ÿ ଗà­à¬£à¬§à¬°à­à¬® ନାହିଠକିମà­à¬¬à¬¾ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "ଠିକଣା '%s' ରେ ତà­à¬°à­à¬Ÿà¬¿ - ପୋରà­à¬Ÿ ଗà­à¬£à¬§à¬°à­à¬® ନାହିଠକିମà­à¬¬à¬¾ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "ଠିକଣା '%s' ରେ ତà­à¬°à­à¬Ÿà¬¿ - ନୋନସ ଫାଇଲ ଗà­à¬£à¬§à¬°à­à¬® ନାହିଠକିମà­à¬¬à¬¾ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "ସà­à­±à­Ÿà¬‚-ଆରମà­à¬­ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: " + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "ଠିକଣା '%s' ପାଇଠଅଜଣା କିମà­à¬¬à¬¾ ଅସମରà­à¬¥à¬¿à¬¤ ପରିବହନ '%s'" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "ଫାଇଲ '%s' କୠଖୋଲିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "ନୋନସ ଫାଇଲ '%s' ରୠପଢିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "ନୋନସ ଫାଇଲ '%s' ରୠପଢିବାରେ ତà­à¬°à­à¬Ÿà¬¿,16 ବାଇଟ ଆଶାକରାଯାଇଥାà¬, %d ପାଇଅଛି" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "ନୋନସ ଫାଇଲ '%s' ର ବିଷୟବସà­à¬¤à­à¬•ୠଧାରାରେ ଲେଖିବାରେ ତà­à¬°à­à¬Ÿà¬¿:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "ପà­à¬°à¬¦à¬¤à­à¬¤ ଠିକଣାଟି ଖାଲି ଅଛି" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "uid ସେଟ କରିବା ସମୟରେ à¬à¬• ସନà­à¬¦à­‡à¬¶à¬•ୠଉତà­à¬ªà¬¨à­à¬¨ କରିପାରିବେ ନାହିà¬" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "ତନà­à¬¤à­à¬°-id ବିନା କୌଣସି ସନà­à¬¦à­‡à¬¶à¬•ୠଉତà­à¬ªà¬¨à­à¬¨ କରି ପାରିବେ ନାହିà¬:" + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "ନିରà­à¬¦à­à¬¦à­‡à¬¶ '%s' କୠଉତà­à¬ªà¬¨à­à¬¨ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿:" + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(à¬à¬¹à¬¿ ୱିଣà­à¬¡à­‹à¬•ୠବନà­à¬¦ କରିବା ପାଇଠକୌଣସି ଅକà­à¬·à¬°à¬•ୠଲେଖନà­à¬¤à­)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "ଅଧିବେଶନ dbus ଚାଲà­à¬¨à¬¾à¬¹à¬¿à¬, à¬à¬¬à¬‚ ସà­à­±à­Ÿà¬‚ ପà­à¬°à¬¾à¬°à¬®à­à¬­ ବିଫଳ ହୋଇଛି" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"ଅଧିବେଶନ ବସ ଠିକଣାକୠନିରà­à¬¦à­à¬§à¬¾à¬°à¬£ କରିପାରିବେ ନାହିଠ(à¬à¬¹à¬¿ OS ପାଇଠନିୟୋଜିତ ହୋଇନାହିà¬)" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"DBUS_STARTER_BUS_TYPE ପରିବେଶ ପà­à¬°à¬¾à¬šà¬³à¬°à­ ବସ ଠିକଣାକୠନିରà­à¬¦à­à¬§à¬¾à¬°à¬£ କରିପାରିବେ ନାହିà¬- " +"ଅଜଣା ମୂଲà­à­Ÿ " +"'%s'" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"ବସ ଠିକଣା ନିରà­à¬¦à­à¬§à¬¾à¬°à¬£ କରିପାରିବେ ନାହିଠକାରଣ DBUS_STARTER_BUS_TYPE ପରିବେଶ ପà­à¬°à¬¾à¬šà¬³ " +"ସେଟ ହୋଇନାହିà¬" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "ଅଜଣା ବସ ପà­à¬°à¬•ାର %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "ଅପà­à¬°à¬¤à­à­Ÿà¬¾à¬¶à¬¿à¬¤ ବିଷୟବସà­à¬¤à­ ଅଭାବ à¬à¬• ଧାଡ଼ି ପଢ଼ିବାକୠଚେଷà­à¬Ÿà¬¾ କରà­à¬…ଛି" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"ଅପà­à¬°à¬¤à­à­Ÿà¬¾à¬¶à¬¿à¬¤ ବିଷୟବସà­à¬¤à­à¬° ଅଭାବ (ସà­à¬°à¬•à­à¬·à¬¿à¬¤ ଭାବରେ) à¬à¬• ଧାଡ଼ିକୠପଢ଼ିବାକୠଚେଷà­à¬Ÿà¬¾à¬•ରà­à¬…ଛି" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "ବହିଷà­à¬•ୃତ ସମସà­à¬¤ ଉପଲବà­à¬§ ବୈଧିକରଣ କୌଶଳ (ପà­à¬°à­Ÿà¬¾à¬¸: %s) (ଉପଲବà­à¬§: %s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer ମାଧà­à¬¯à¬®à¬°à­‡ ବାତିଲ ହୋଇଛି" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "'%s' ଡିରେକà­à¬Ÿà­‹à¬°à¬¿ ପାଇଠସୂଚନା ପାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"ଡିରେକà­à¬Ÿà­‹à¬°à­€ '%s' ଉପରେ ଅନà­à¬®à¬¤à¬¿à¬—à­à¬¡à¬¼à¬¿à¬• ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ହୋଇଛି। ଆଶାକରାଯାଇଥିବା ଧାରା 0700, " +"ମିଳିଛି 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "ଡିରେକà­à¬Ÿà­‹à¬°à¬¿ '%s' କୠନିରà­à¬®à¬¾à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "ପଢ଼ିବା ପାଇଠକିରିଙà­à¬— '%s' କୠଖୋଲିବାରେ ତà­à¬°à­à¬Ÿà¬¿: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "କିରିଙà­à¬— ର %d ଧାଡ଼ି '%s' ଠାରେ ବିଷୟବସà­à¬¤à­ '%s' ସହିତ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ଅଟେ" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"କିରିଙà­à¬—ର ଧାଡ଼ି %d ର ପà­à¬°à¬¥à¬® ଟକେନ '%s' ରେ ବିଷୟବସà­à¬¤à­ '%s' ସହିତ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ହୋଇଛି" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"କିରିଙà­à¬—ର ଧାଡ଼ି %d ର ଦà­à­±à¬¿à¬¤à­€à­Ÿ ଟକେନ '%s' ରେ ବିଷୟବସà­à¬¤à­ '%s' ସହିତ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ହୋଇଛି" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "id %d ସହିତ '%s' ରେ ଥିବା କିରିଙà­à¬—ରେ କà­à¬•ି ମିଳିଲା ନାହିà¬" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "ଷà­à¬Ÿà­‡à¬² ଲକ ଫାଇଲ '%s' କୠଅପସାରଣ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "ଲକ ଫାଇଲ '%s' ନିରà­à¬®à¬¾à¬£ କରିବାେର ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "ଲକ ଫାଇଲ (ଅସଂଯà­à¬•à­à¬¤) '%s' କୠବନà­à¬¦ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "ଲକ ଫାଇଲ '%s' କୠଅସଂଯà­à¬•à­à¬¤ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "ଲେଖିବା ପାଇଠକିରିଙà­à¬— '%s' କୠଖୋଲିବାରେ ତà­à¬°à­à¬Ÿà¬¿:" + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(ଅତିରିକà­à¬¤ ଭାବରେ, '%s' ପାଇଠମଧà­à¬¯ ତାଲାକୠଖୋଲିବାରେ ବିଫଳ: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "ସଂଯୋଗ ବନà­à¬¦ ହୋଇଯାଇଛି" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "ସମୟ ସୀମା ପହଞà­à¬šà¬¿à¬¯à¬¾à¬‡à¬›à¬¿" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"କà­à¬²à¬¾à¬à¬£à­à¬Ÿ ପାଖ ସଂଯୋଗକୠସà­à¬¥à¬¾à¬ªà¬¨ କରିବା ସମୟରେ ଅସମରà­à¬¥à¬¿à¬¤ ସୂଚକଗà­à¬¡à¬¼à¬¿à¬•ର ସମà­à¬®à­à¬–ିନ ହୋଇଛି" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"ପଥ %s ରେ ବସà­à¬¤à­ ଉପରେ à¬à¬ªà¬°à¬¿ କୋଣସି ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  'org.freedesktop.DBus.Properties' " +"ନାହିà¬" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "'%s' ପରି କୌଣସି ଗà­à¬£à¬§à¬°à­à¬® ନାହିà¬" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "'%s' ବିଶେଷତାଗà­à¬¡à¬¿à¬• ପଢ଼ିବା ଯୋଗà­à­Ÿ ନà­à¬¹à¬¿à¬" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "'%s' ବିଶେଷତାଗà­à¬¡à¬¿à¬• ଲେଖିବା ଯୋଗà­à­Ÿ ନà­à¬¹à¬¿à¬" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"ଗà­à¬£à¬§à¬°à­à¬® '%s' ସେଟ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: ଆଶାକରାଯାଇଥିବା ପà­à¬°à¬•ାର '%s' କିନà­à¬¤à­ '%s' ପାଇଛି" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "'%s' ପରି କୌଣସି ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  ନାହିà¬" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "à¬à¬ªà¬°à¬¿ କୌଣସି ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  ନାହିà¬" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "%s ପଥରେ ବସà­à¬¤à­ ଉପରେ '%s' ପରି କୌଣସି ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  ନାହିà¬" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "'%s' ପରି କୌଣସି ପଦà­à¬§à¬¤à¬¿ ନାହିà¬" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "ସନà­à¬¦à­‡à¬¶ ପà­à¬°à¬•ାର, '%s', ଆଶା କରାଯାଇଥିବା ପà­à¬°à¬•ାର '%s' ସହିତ ମିଶୠନାହିà¬" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  %s ପାଇଠ%s ରେ ଗୋଟିଠବସà­à¬¤à­à¬•ୠପୂରà­à¬¬à¬°à­ ପଠାଯାଇଛି" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "ପଦà­à¬§à¬¤à¬¿ '%s' ପà­à¬°à¬•ାର '%s' ଫେରାଇଥାà¬, କିନà­à¬¤à­ '%s' କୠଆଶାକରିଥାà¬" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  '%s' ଉପରେ ହସà­à¬¤à¬¾à¬•à­à¬·à¬° '%s' ସହିତ '%s' ପଦà­à¬§à¬¤à¬¿ ଅବସà­à¬¥à¬¿à¬¤ ନାହିà¬" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "%s ପାଇଠପୂରà­à¬¬à¬°à­ à¬à¬• ସବଟà­à¬°à­€ ପଠାଯାଇଛି" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "ପà­à¬°à¬•ାରଟି ଅବୈଧ ଅଟେ" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL ସନà­à¬¦à­‡à¬¶: PATH କିମà­à¬¬à¬¾ MEMBER ଶୀରà­à¬·à¬• ସà­à¬¥à¬¾à¬¨ ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤ ଅଛି" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN ସନà­à¬¦à­‡à¬¶: REPLY_SERIAL ଶୀରà­à¬·à¬• ସà­à¬¥à¬¾à¬¨ ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤ ଅଛି" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"ତà­à¬°à­à¬Ÿà¬¿ ସନà­à¬¦à­‡à¬¶: REPLY_SERIAL କିମà­à¬¬à¬¾ ERROR_NAME ଶୀରà­à¬·à¬• ସà­à¬¥à¬¾à¬¨ ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤ ଅଛି" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "ସଂକେତ ସନà­à¬¦à­‡à¬¶: ପଥ, ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  କିମà­à¬¬à¬¾ ସଦସà­à­Ÿ ଶୀରà­à¬·à¬• ସà­à¬¥à¬¾à¬¨ ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤ ଅଛି" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"ସଂକେତ ସନà­à¬¦à­‡à¬¶: ପଥ ଶୀରà­à¬·à¬• ସà­à¬¥à¬¾à¬¨à¬Ÿà¬¿ ସଂରକà­à¬·à¬¿à¬¤ ମୂଲà­à­Ÿ /org/freedesktop/DBus/Local " +"ବà­à­Ÿà¬¬à¬¹à¬¾à¬° " +"କରିଥାà¬" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"ସଂକେତ ସନà­à¬¦à­‡à¬¶: ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  ଶୀରà­à¬·à¬• ସà­à¬¥à¬¾à¬¨ ସଂରକà­à¬·à¬¿à¬¤ ମୂଲà­à­Ÿ " +"org.freedesktop.DBus.Local କୠ" +"ବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରିଥାà¬" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu ବାଇଟ ପଢ଼ିବା ପାଇଠଚାହà­à¬à¬›à¬¿ କିନà­à¬¤à­ କେବଳ %lu ମିଲିଲା" +msgstr[1] "%lu ବାଇଟ ପଢ଼ିବା ପାଇଠଚାହà­à¬à¬›à¬¿ କିନà­à¬¤à­ କେବଳ %lu ମିଲିଲା" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "ବାକà­à­Ÿà¬–ଣà­à¬¡ '%s' ପରେ ଶୂନà­à­Ÿ ବାଇଟ ଆଶାକରାଯାଇଥିଲା କିନà­à¬¤à­ ବାଇଟ %d ମିଳିଲା" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"ବୈଧ UTF-8 ବାକà­à­Ÿà¬–ଣà­à¬¡ ଆଶାକରାଯାଇଥିଲା କିନà­à¬¤à­ ବାଇଟ ଅଫସେଟ %d ରେ ଅବୈଧ ବାଇଟ " +"ମିଳିଲା(ବାକà­à­Ÿà¬–ଣà­à¬¡à¬° " +"ଲମà­à¬¬ ହେଉଛି %d)। ସେହି ବିନà­à¬¦à­ ପରà­à¬¯à­à­Ÿà¬¨à­à¬¤ ଉଠିଥିବା ବାକà­à­Ÿà¬–ଣà­à¬¡à¬Ÿà¬¿ ହେଉଛି ବୈଧ UTF-8 " +"ବାକà­à­Ÿà¬–ଣà­à¬¡ '%s'" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "ବିଶà­à¬³à­‡à¬·à¬¿à¬¤ ମୂଲà­à­Ÿ '%s' ଟି à¬à¬• ବୈଧ D-Bus ବସà­à¬¤à­ ପଥ ନà­à¬¹à¬" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "ବିଶà­à¬³à­‡à¬·à¬¿à¬¤ ମୂଲà­à­Ÿ '%s' ଟି à¬à¬• ବୈଧ D-Bus ହସà­à¬¤à¬¾à¬•à­à¬·à¬° ନà­à¬¹à¬" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"%u ବାଇଟ ଲମà­à¬¬ ବିଶିଷà­à¬Ÿ ଆରେର ସମà­à¬®à­à¬–ିନ ହୋଇଛି। ସରà­à¬¬à¬¾à¬§à¬¿à¬• ଲମà­à¬¬ ହେଉଛି 2<<26 ବାଇଟ (64 " +"MiB)." +msgstr[1] "" +"%u ବାଇଟ ଲମà­à¬¬ ବିଶିଷà­à¬Ÿ ଆରେର ସମà­à¬®à­à¬–ିନ ହୋଇଛି। ସରà­à¬¬à¬¾à¬§à¬¿à¬• ଲମà­à¬¬ ହେଉଛି 2<<26 ବାଇଟ (64 " +"MiB)." + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"'a%c' ପà­à¬°à¬•ାରର ଆରେର ସମà­à¬®à­à¬–ିନ ହୋଇଛି, %u ବାଇଟର ଗà­à¬£à¬¿à¬¤à¬• ଆକାରର ଲମà­à¬¬ ଆଶା କରାଯାଇଥିଲା, " +"କିନà­à¬¤à­ %u ବାଇଟ ଲମà­à¬¬à¬¾ ମିଳିଲା" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "ପà­à¬°à¬¾à¬šà¬³ ପାଇଠବିଶà­à¬³à¬·à¬¿à¬¤ ମୂଲà­à­Ÿ '%s' ଟି à¬à¬• ବୈଧ D-ବସ ହସà­à¬¤à¬¾à¬•à­à¬·à¬° ନà­à¬¹à¬" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "D-Bus ତାରମୟ ଶୈଳୀରà­'%s' ପà­à¬°à¬•ାରର ବାକà­à­Ÿà¬–ଣà­à¬¡ ସହିତ ତà­à¬°à­à¬Ÿà¬¿ କà­à¬°à¬®à¬­à¬™à­à¬— GVariant" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"ଅବୈଧ endianness ମୂଲà­à­Ÿà¥¤ 0x6c ('l') କିମà­à¬¬à¬¾ 0x42 ('B') ଆଶାକରିଥିଲା କିନà­à¬¤à­0x%02x " +"ମୂଲà­à­Ÿà¬®à¬¿à¬³à¬¿à¬²à¬¾" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "ଅବୈଧ ମୂଖà­à­Ÿ ପà­à¬°à¬Ÿà­‹à¬•ଲ ସଂସà­à¬•ରଣ। 1 ଆଶାକରାଯାଇଥିଲା କିନà­à¬¤à­ %d ମିଳିଲା" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "ହସà­à¬¤à¬¾à¬•à­à¬·à¬° '%s' ସହିତ ହସà­à¬¤à¬¾à¬•à­à¬·à¬° ଶୀରà­à¬·à¬• ମିଳିଛି କିନà­à¬¤à­ ସନà­à¬¦à­‡à¬¶ ଖାଲିଅଛି" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "ବିଶà­à¬³à­‡à¬·à¬¿à¬¤ ମୂଲà­à­Ÿ '%s' ଟି à¬à¬• ବୈଧ D-Bus ହସà­à¬¤à¬¾à¬•à­à¬·à¬° ନà­à¬¹à¬ (ସନà­à¬¦à­‡à¬¶ ପାଇà¬)" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "ସନà­à¬¦à­‡à¬¶à¬°à­‡ କୌଣସି ହସà­à¬¤à¬¾à¬•à­à¬·à¬° ଶୀରà­à¬·à¬• ନାହିଠକିନà­à¬¤à­ ସନà­à¬¦à­‡à¬¶à¬Ÿà¬¿ %u ବାଇଟର" +msgstr[1] "ସନà­à¬¦à­‡à¬¶à¬°à­‡ କୌଣସି ହସà­à¬¤à¬¾à¬•à­à¬·à¬° ଶୀରà­à¬·à¬• ନାହିଠକିନà­à¬¤à­ ସନà­à¬¦à­‡à¬¶à¬Ÿà¬¿ %u ବାଇଟର" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "ସନà­à¬¦à­‡à¬¶à¬•ୠକà­à¬°à¬®à¬¹à­€à¬¨ କରିପାରିବେ ନାହିà¬: " + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"D-Bus ତାରମୟ ଶୈଳୀରà­'%s' ପà­à¬°à¬•ାରର ବାକà­à­Ÿà¬–ଣà­à¬¡ ସହିତ GVariant କୠକà­à¬°à¬®à¬°à­‡ ରଖିବାରେ " +"ତà­à¬°à­à¬Ÿà¬¿" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"ସନà­à¬¦à­‡à¬¶à¬°à­‡ %d ଫାଇଲ ବରà­à¬£à­à¬£à¬¨à¬¾à¬•ାରୀମାନେ ଅଛନà­à¬¤à¬¿ କିନà­à¬¤à­ ଶୀରà­à¬·à¬• ସà­à¬¥à¬¾à¬¨ %d ଫାଇଲ " +"ବରà­à¬£à­à¬£à¬¨à¬¾à¬•ାରୀମାନଙà­à¬•à­ " +"ସୂଚାଇଥାà¬" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "ସନà­à¬¦à­‡à¬¶à¬•ୠକà­à¬°à¬®à¬°à­‡ ସଜାଇପାରିବେ ନାହିà¬: " + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "ସନà­à¬¦à­‡à¬¶à¬°à­‡ ହସà­à¬¤à¬¾à¬•à­à¬·à¬° '%s' ଅଛି କିନà­à¬¤à­ ସେଠାରେ କୌଣସି ହସà­à¬¤à¬¾à¬•à­à¬·à¬° ଶୀରà­à¬·à¬• ନାହିà¬" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "" +"ସନà­à¬¦à­‡à¬¶à¬°à­‡ ହସà­à¬¤à¬¾à¬•à­à¬·à¬° ପà­à¬°à¬•ାର '%s' ଅଛି କିନà­à¬¤à­ ଶୀରà­à¬·à¬•ରେ ଥିବା ହସà­à¬¤à¬¾à¬•à­à¬·à¬°à¬Ÿà¬¿ ହେଉଛି '%s'" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "ସନà­à¬¦à­‡à¬¶à¬Ÿà¬¿ ଖାଲି ଅଛି କିନà­à¬¤à­ ଶୀରà­à¬·à¬•ରେ ଥିବା ହସà­à¬¤à¬¾à¬•à­à¬·à¬°à¬Ÿà¬¿ ହେଉଛି '(%s)'" + +#: ../gio/gdbusmessage.c:3282 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' ପà­à¬°à¬•ାରର ସନà­à¬¦à­‡à¬¶à¬°à­‡ ତà­à¬°à­à¬Ÿà¬¿ ଦେଖାଦେଇଛି" + +#: ../gio/gdbusmessage.c:3290 +msgid "Error return with empty body" +msgstr "ଖାଲି ସà­à¬¥à¬¾à¬¨ ସହିତ ତà­à¬°à­à¬Ÿà¬¿ ଫେରାଇଥାà¬" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "ହାରà­à¬¡à­±à­‡à¬° ରୂପରେଖା ପାଇବାରେ ଅସମରà­à¬¥: %s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" +"/var/lib/dbus/machine-id କିମà­à¬¬à¬¾ /etc/machine-id କୠଧାରଣ କରିବାରେ ଅସମରà­à¬¥: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s ପାଇଠନାମ ଅନà­à¬¯à¬¾à­Ÿà­€ ସରà­à¬­à¬¿à¬¸ ଆରମà­à¬­ କରନà­à¬¤à­à¬•ୠଡ଼ାକିବାରେ ତà­à¬°à­à¬Ÿà¬¿: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "ଅପà­à¬°à¬¤à­à­Ÿà¬¾à¬¶à¬¿à¬¤ ଉତà­à¬¤à¬° %d StartServiceByName(\"%s\") ପଦà­à¬§à¬¤à¬¿à¬°à­ ମିଳିଛି " + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"ପଦà­à¬§à¬¤à¬¿à¬•ୠକାଢ଼ିପାରିବେ ନାହିà¬; ପà­à¬°à¬•à­à¬¸à¬¿à¬Ÿà¬¿ ହେଉଛି ମାଲିକ ନଥିବା à¬à¬• ସà­à¬ªà¬°à¬¿à¬šà¬¿à¬¤ ନାମ à¬à¬¬à¬‚ " +"ପà­à¬°à¬•à­à¬¸à¬¿à¬Ÿà¬¿ " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START ସୂଚକ ଦà­à­±à¬¾à¬°à¬¾ ନିରà­à¬®à¬¿à¬¤" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "ବାହାର କରାଯାଇଥିବା ନାମ ସà­à¬¥à¬¾à¬¨à¬Ÿà¬¿ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "à¬à¬• ସରà­à¬­à¬° ନିରà­à¬®à¬¾à¬£ କରିବା ସମୟରେ ନୋନସ ଫାଇଲକୠଉଲà­à¬²à­‡à¬– କରିପାରିବେ ନାହିà¬" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "ନୋନସ ଫାଇଲକୠ'%s' ରେ ଲେଖିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' ବାକà­à­Ÿà¬–ଣà­à¬¡à¬Ÿà¬¿ ଗୋଟିଠବୈଧ D-Bus GUID ନà­à¬¹à¬" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "ଅସମରà­à¬¥à¬¿à¬¤ ପରିବହନ '%s' ଉପରେ ଶà­à¬£à¬¿à¬ªà¬¾à¬°à¬¿à¬¬à­‡ ନାହିà¬" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"ନିରà­à¬¦à­à¬¦à­‡à¬¶à¬—à­à¬¡à¬¼à¬¿à¬•:\n" +" help à¬à¬¹à¬¿ ସୂଚନାକୠଦରà­à¬¶à¬¾à¬‡à¬¥à¬¾à¬\n" +" introspect à¬à¬• ସà­à¬¦à­‚ର ବସà­à¬¤à­à¬•ୠଆତà­à¬®à¬¨à¬¿à¬°à­€à¬•à­à¬·à¬£ କରିଥାà¬\n" +" monitor à¬à¬• ସà­à¬¦à­‚ର ବସà­à¬¤à­à¬•ୠନିରୀକà­à¬·à¬£ କରିଥାà¬\n" +" call à¬à¬• ସà­à¬¦à­‚ର ବସà­à¬¤à­ ଉପରେ ପଦà­à¬§à¬¤à¬¿à¬•ୠବାହାର କରିଥାà¬\n" +" emit à¬à¬• ସଂକେତକୠଲà­à¬šà¬¾à¬‡à¬¥à¬¾à¬\n" +"\n" +"ପà­à¬°à¬¤à­à­Ÿà­‡à¬• ନିରà­à¬¦à­à¬¦à­‡à¬¶ ବିଷୟରେ ସହାୟତା ପାଇବା ପାଇଠ\"%s COMMAND --help\" କୠବà­à­Ÿà¬¬à¬¹à¬¾à¬° " +"କରନà­à¬¤à­à¥¤\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "ଆତà­à¬®à¬¨à¬¿à¬°à­€à¬•à­à¬·à¬£ XML କୠବିଶà­à¬³à­‡à¬·à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "ତନà­à¬¤à­à¬° ବସ ସହିତ ସଂଯୋଗ କରନà­à¬¤à­" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "ଅଧିବେଶନ ବସ ସହିତ ସଂଯୋଗ କରନà­à¬¤à­" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "ପà­à¬°à¬¦à¬¤à­à¬¤ D-ବସ ଠିକଣା ସହିତ ସଂଯୋଗ କରନà­à¬¤à­" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "ସଂଯୋଗ ଶେଷବିନà­à¬¦à­ ବିକଳà­à¬ªà¬—à­à¬¡à¬¼à¬¿à¬•:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "ସଂଯୋଗ ଶେଷବିନà­à¬¦à­à¬•ୠଉଲà­à¬²à­‡à¬– କରିବା ବିକଳà­à¬ªà¬—à­à¬¡à¬¼à¬¿à¬•" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "କୌଣସି ସଂଯୋଗ ଶେଷବିନà­à¬¦à­ ଉଲà­à¬²à­‡à¬– ହୋଇନାହିà¬" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "à¬à¬•ାଧିକ ସଂଯୋଗ ଶେଷବିନà­à¬¦à­à¬—à­à¬¡à¬¼à¬¿à¬•ୠଉଲà­à¬²à­‡à¬– ହୋଇଛି" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "ଚେତାବନୀ: ଆତà­à¬®à¬¨à¬¿à¬°à­€à¬•à­à¬·à¬£ ତଥà­à­Ÿ ଅନà­à¬¸à¬¾à¬°à­‡, ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  '%s' ଅବସà­à¬¥à¬¿à¬¤ ନାହିà¬\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"ଚେତାବନୀ: ଆତà­à¬®à¬¨à¬¿à¬°à­€à¬•à­à¬·à¬£ ତଥà­à­Ÿ ଅନà­à¬¸à¬¾à¬°à­‡, ପଦà­à¬§à¬¤à¬¿ '%s' ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  '%s' ଉପରେ ଅବସà­à¬¥à¬¿à¬¤ " +"ନାହିà¬\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "ସଂକେତ ପାଇଠବୈକଳà­à¬ªà¬¿à¬• ଲକà­à¬·à­à¬¯à¬¸à­à¬¥à¬³ (ଅନନà­à­Ÿ ନାମ)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "ସଂକେତ ବନà­à¬¦ କରିବା ପାଇଠବସà­à¬¤à­ ପଥ" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "ସଂକେତ à¬à¬¬à¬‚ ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  ନାମ" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "à¬à¬• ସଂକେତକୠବନà­à¬¦ କରନà­à¬¤à­à¥¤" + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "ସଂଯୋଗ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: ବସà­à¬¤à­ ପà­à¬°à¬•ାର ଉଲà­à¬²à­‡à¬– ହୋଇନାହିà¬à¥¤\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: '%s' ଟି ଗୋଟିଠବୈଧ ବସà­à¬¤à­ ପଥ ନà­à¬¹à¬\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: ସଂକେତ ନିରà­à¬¦à­à¬¦à¬¿à¬·à­à¬Ÿ ହୋଇ ନାହିà¬à¥¤\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: ସଂକେତଟି à¬à¬• ସମà­à¬ªà­‚ରà­à¬£à­à¬£ ନାମ ହୋଇଥିବା ଉଚିତ।\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: %s ଟି ଗୋଟିଠବୈଧ ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  ନାମ ନà­à¬¹à¬\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿:%s ଟି ଗୋଟିଠବୈଧ ସଦସà­à¬¯ ନାମ ନà­à¬¹à¬\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿:%s ଟି ଗୋଟିଠବୈଧ ଅନନà­à­Ÿ ବସ ନାମ ନà­à¬¹à¬à¥¤\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "ପà­à¬°à¬¾à¬šà¬³ %d କୠବିଶà­à¬³à­‡à¬·à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "ସଂଯୋଗ ଦେଖାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "ପଦà­à¬§à¬¤à¬¿ ବାହାର ଜାଣିବା ପାଇଠଲକà­à¬·à­à¬¯à¬¸à­à¬¥à¬³ ନାମ" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "ପଦà­à¬§à¬¤à¬¿à¬•ୠଜାଣିବା ପାଇଠବସà­à¬¤à­ ପଥ" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "ପଦà­à¬§à¬¤à¬¿ à¬à¬¬à¬‚ ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬  ନାମ" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "ସମୟ ସମାପà­à¬¤à¬¿ ସେକଣà­à¬¡à¬°à­‡" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "ସà­à¬¦à­‚ର ବସà­à¬¤à­ ଉପରେ à¬à¬• ପଦà­à¬§à¬¤à¬¿à¬•ୠପà­à¬°à­Ÿà­‹à¬— କରନà­à¬¤à­" + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: ଲକà­à¬·à­à¬¯à¬¸à­à¬¥à¬³ ଉଲà­à¬²à­‡à¬– ହୋଇନାହିà¬\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: ବସà­à¬¤à­ ପଥ ଉଲà­à¬²à­‡à¬– ହୋଇନାହିà¬\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: ପଦà­à¬§à¬¤à¬¿ ନାମ ଉଲà­à¬²à­‡à¬– ହୋଇନାହିà¬\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "ତà­à¬°à­à¬Ÿà¬¿: ପଦà­à¬§à¬¤à¬¿ ନାମ '%s' ଟି ଅବୈଧ ଅଟେ\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "ପà­à¬°à¬¾à¬šà¬³ %d କୠ'%s' ପà­à¬°à¬•ାରରେ ବିଶà­à¬³à­‡à¬·à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "ଆତà­à¬®à¬¨à­€à¬°à¬¿à¬•à­à¬·à¬£ କରିବାକୠଲକà­à¬·à­à¬¯à¬¸à­à¬¥à¬³ ନାମ" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "ଆତà­à¬®à¬¨à­€à¬°à¬¿à¬•à­à¬·à¬£ କରିବାକୠବସà­à¬¤à­ ପଥ" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "XML ମà­à¬¦à­à¬°à¬£ କରନà­à¬¤à­" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "ନିରà­à¬­à¬°à¬•କୠଆତà­à¬®à¬¨à­€à¬°à¬¿à¬•à­à¬·à¬£ କରନà­à¬¤à­" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "କେବଳ ମà­à¬¦à­à¬°à¬£ ଗà­à¬£à¬§à¬°à­à¬®à¬—à­à¬¡à¬¼à¬¿à¬•" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "ସà­à¬¦à­‚ର ବସà­à¬¤à­à¬° ଆତà­à¬®à¬¨à¬¿à¬°à­€à¬•à­à¬·à¬£ କରନà­à¬¤à­à¥¤" + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "ନିରୀକà­à¬·à¬£ କରିବା ପାଇଠଲକà­à¬·à­à¬¯à¬¸à­à¬¥à¬³ ନାମ" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "ନିରୀକà­à¬·à¬£ କରିବା ପାଇଠବସà­à¬¤à­ ପଥ" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "à¬à¬• ସà­à¬¦à­‚ର ବସà­à¬¤à­à¬•ୠନିରୀକà­à¬·à¬£ କରନà­à¬¤à­" + +#: ../gio/gdesktopappinfo.c:1919 ../gio/gdesktopappinfo.c:4440 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "ବେନାମୀ" + +#: ../gio/gdesktopappinfo.c:2328 +msgid "Desktop file didn't specify Exec field" +msgstr "ଡେସà­à¬•ଟପ ଫାଇଲ Exec କà­à¬·à­‡à¬¤à­à¬° ଉଲà­à¬²à­‡à¬– କରିନଥିଲା" + +#: ../gio/gdesktopappinfo.c:2613 +msgid "Unable to find terminal required for application" +msgstr "ପà­à¬°à­Ÿà­‹à¬— ପାଇଠଆବଶà­à­Ÿà¬• ଟରà­à¬®à¬¿à¬¨à¬¾à¬² ଖୋଜିବାରେ ଅସମରà­à¬¥" + +#: ../gio/gdesktopappinfo.c:3034 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "ଚାଳକ ପà­à¬°à­Ÿà­‹à¬— ବିନà­à­Ÿà¬¾à¬¸ ଫୋଲଡର %s କୠନିରà­à¬®à¬¾à¬£ କରିପାରିବେ ନାହିà¬: %s" + +#: ../gio/gdesktopappinfo.c:3038 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "ଚାଳକ MIME ବିନà­à­Ÿà¬¾à¬¸à¬¿à¬¤ ଫୋଲଡର %s ନିରà­à¬®à¬¾à¬£ କରିପାରିବ ନାହିà¬: %s" + +#: ../gio/gdesktopappinfo.c:3278 ../gio/gdesktopappinfo.c:3302 +msgid "Application information lacks an identifier" +msgstr "ପà­à¬°à­Ÿà­‹à¬— ସୂଚନାରେ à¬à¬• ପରିଚାୟକର ଅଭାବ" + +#: ../gio/gdesktopappinfo.c:3535 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "ଚାଳକ ଡେସà­à¬•ଟପ ଫାଇଲ %s ନିରà­à¬®à¬¾à¬£ କରିପାରିବ ନାହିà¬" + +#: ../gio/gdesktopappinfo.c:3669 +#, c-format +msgid "Custom definition for %s" +msgstr "%s ପାଇଠଇଚà­à¬›à¬¾à¬°à­‚ପୀ ପରିଭାଷା" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "ଡà­à¬°à¬¾à¬‡à¬­ ବାହାର କରିବାକୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "ଡà­à¬°à¬¾à¬‡à¬­ ବାହାର କରିବା କିମà­à¬¬à¬¾ eject_with_operation କୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "ଡà­à¬°à¬¾à¬‡à¬­ ସଞà­à¬šà¬¾à¬° ମାଧà­à¬¯à¬® ପାଇଠଚୟନକୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "ଡà­à¬°à¬¾à¬‡à¬­ ଆରମà­à¬­ କରିବାକୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "ଡà­à¬°à¬¾à¬‡à¬­ ବନà­à¬¦ କରିବାକୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS ସହାୟତା ଉପଲବà­à¬§ ନାହିà¬" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem ସାଙà­à¬•େତିକରଣର ସଂସà­à¬•ରଣ %dକୠନିୟନà­à¬¤à­à¬°à¬£ କରà­à¬…ଛି" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem ସାଙà­à¬•େତିକରଣରେ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ଟକେନ ସଂଖà­à­Ÿà¬¾ (%d)" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon ସାଙà­à¬•େତିକରଣର ସଂସà­à¬•ରଣ %dକୠନିୟନà­à¬¤à­à¬°à¬£ କରିପାରୠନାହିà¬" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon ସାଙà­à¬•େତିକରଣରେ ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ଟକେନ ସଂଖà­à­Ÿà¬¾ (%d)" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon ପାଇଠଗୋଟିଠGEmblem ଆଶାକରାଯାଉଅଛି" + +#: ../gio/gfile.c:956 ../gio/gfile.c:1194 ../gio/gfile.c:1332 +#: ../gio/gfile.c:1570 ../gio/gfile.c:1625 ../gio/gfile.c:1683 +#: ../gio/gfile.c:1767 ../gio/gfile.c:1824 ../gio/gfile.c:1888 +#: ../gio/gfile.c:1943 ../gio/gfile.c:3591 ../gio/gfile.c:3646 +#: ../gio/gfile.c:3853 ../gio/gfile.c:3895 ../gio/gfile.c:4358 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7748 ../gio/gfile.c:7838 ../gio/gfile.c:7922 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "ପà­à¬°à­Ÿà­‹à¬— ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1455 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "ଧାରଣ କରିଥିବା ସà­à¬¥à¬¾à¬ªà¬¨ ଅବସà­à¬¥à¬¿à¬¤ ନାହିà¬" + +#: ../gio/gfile.c:2502 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "ଡିରେକà­à¬Ÿà­‹à¬°à­€ ଉପରେ ନକଲ କରିପାରିବେ ନାହିà¬" + +#: ../gio/gfile.c:2562 +msgid "Can't copy directory over directory" +msgstr "ଡିରେକà­à¬Ÿà­‹à¬°à­€ ଉପରେ ଡିରେକà­à¬Ÿà­‹à¬°à­€ ନକଲ କରିପାରିବେ ନାହିà¬" + +#: ../gio/gfile.c:2570 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "ଲକà­à¬·à­à­Ÿ ଫାଇଲ ଅବସà­à¬¥à¬¿à¬¤" + +#: ../gio/gfile.c:2589 +msgid "Can't recursively copy directory" +msgstr "ପà­à¬¨à¬°à¬¾à¬¬à¬°à­à¬¤à­à¬¤à­€ ଭାବରେ ଡିରେକà­à¬Ÿà­‹à¬°à­€ ନକଲ କରିପାରିବେ ନାହିà¬" + +#: ../gio/gfile.c:2871 +msgid "Splice not supported" +msgstr "ବନà­à¬§à¬¨ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gfile.c:2875 +#, c-format +msgid "Error splicing file: %s" +msgstr "ଫାଇଲକୠଗà­à¬¨à­à¬¥à¬¿à¬¬à¬¾à¬°à­‡ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gfile.c:3006 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "ଅସମରà­à¬¥à¬¿à¬¤ ସà­à¬¥à¬¾à¬ªà¬¨à¬—à­à¬¡à¬¼à¬¿à¬• ମଧà­à¬¯à¬°à­‡ (reflink/clone) ନକଲ କରନà­à¬¤à­" + +#: ../gio/gfile.c:3010 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "(reflink/clone) ନକଲ କିରବା ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬ ଅଥବା ଅବୈଧ ଅଟେ" + +#: ../gio/gfile.c:3015 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "(reflink/clone) ନକଲ କରିବା ସମରà­à¬¥à¬¿à¬¤ ନà­à¬ ଅଥବା କାମକରିନାହିà¬" + +#: ../gio/gfile.c:3078 +msgid "Can't copy special file" +msgstr "ବିଶେଷ ଫାଇଲକୠନକଲ କରିପାରିବେ ନାହିà¬" + +#: ../gio/gfile.c:3843 +msgid "Invalid symlink value given" +msgstr "ଅବୈଧ symlink ମୂଲà­à­Ÿ ପà­à¬°à¬¦à¬¾à¬¨ କରାଯାଇଛି" + +#: ../gio/gfile.c:4004 +msgid "Trash not supported" +msgstr "ଆବରà­à¬œà¬¨à¬¾ ପାତà­à¬° ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gfile.c:4116 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ଫାଇଲ ନାମଗà­à¬¡à¬¼à¬¿à¬• '%c' ଧାରଣ କରିପାରେ ନାହିà¬" + +#: ../gio/gfile.c:6540 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "ଆକାର ସà­à¬¥à¬¾à¬ªà¬¨à¬•ୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gfile.c:6649 +msgid "No application is registered as handling this file" +msgstr "à¬à¬¹à¬¿ ଫାଇଲକୠନିୟନà­à¬¤à­à¬°à¬® କରିବା ଫଳରେ କୌଣସି ପà­à¬°à­Ÿà­‹à¬— ପଞà­à¬œà¬¿à¬•ୃତ ହୋଇନାହିà¬" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "ଗଣନାକାର ବନà­à¬¦ ହୋଇଯାଇଛି" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ଫାଇଲ ଗଣନାକାର ପାଖରେ ଉତà­à¬•ୃଷà­à¬Ÿ ପà­à¬°à­Ÿà­‹à¬— ଅଛି" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ଫାଇଲ ଗଣନାକାର ପୂରà­à¬¬à¬°à­ ବନà­à¬¦ ହୋଇଯାଇଛି" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon ସାଙà­à¬•େତିକରଣର ସଂସà­à¬•ରଣ %d କୠନିୟନà­à¬¤à­à¬°à¬£ କରିପାରିବେ ନାହିà¬" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon ପାଇଠତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ନିବେଶ ତଥà­à­Ÿ" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "ଧାରା query_info କୠସମରà­à¬¥à¬¨ କରେନାହିà¬" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ଧାରାରେ Seek ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ନିବେଶ ଧାରାରେ କାଟିବା ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "ଧାରାରେ କାଟିବା ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "ଭà­à¬² ସଂଖà­à­Ÿà¬• ଟକେନ (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "ଶà­à¬°à­‡à¬£à­€ ନାମ %s ପାଇଠକୌଣସି ପà­à¬°à¬•ାର ନାହିà¬" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "ପà­à¬°à¬•ାର %s GIcon ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬ à¬•ୠକାରà­à¬¯à­à­Ÿà¬•ାରି କରେନାହିà¬" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "ପà­à¬°à¬•ାର %s ଶà­à¬°à­‡à¬£à­€à¬­à­à¬•à­à¬¤ ନà­à¬¹à¬" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "ତà­à¬°à­à¬Ÿà¬¿à¬¯à­à¬•à­à¬¤ ସଂସà­à¬•ରଣ ସଂଖà­à­Ÿà¬¾: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "ପà­à¬°à¬•ାର %s GIcon ଅନà­à¬¤à¬°à¬¾à¬ªà­ƒà¬·à­à¬ à¬°à­‡ ଟକେନ()ରୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "ଚିତà­à¬°à¬¸à¬‚କେତ ସାଙà­à¬•େତିକରଣର ପà­à¬°à¬¦à¬¤à­à¬¤ ସଂସà­à¬•ରଣକୠନିୟନà­à¬¤à­à¬°à¬£ କରାଯାଇପାରିବ ନାହିà¬" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "କୌଣସି ଠିକଣା ଉଲà­à¬²à­‡à¬– କରାଯାଇ ନାହିà¬" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "ଲମà­à¬¬ %u ଟି ଠିକଣା ପାଇଠଅତà­à¬¯à¬§à¬¿à¬• ବଡ଼" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ଉପସରà­à¬— ଲମà­à¬¬à¬ à¬¾à¬°à­ ଠିକଣାରେ ବିଟଗà­à¬¡à¬¼à¬¿à¬•ୠସେଟ କରାଯାଇଥାà¬" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "'%s' କୠIP ଠିକଣା ମାସà­à¬• ଭାବରେ ବିଶà­à¬³à­‡à¬·à¬£ କରିପାରିଲା ନାହିà¬" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "ସକେଟ ଠିକଣା ପାଇଠଯଥେଷà­à¬Ÿ ସà­à¬¥à¬¾à¬¨ ନାହିà¬" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "ଅସମରà­à¬¥à¬¿à¬¤ ସକେଟ ଠିକଣା" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "ନିବେଶ ଧାରାରେ ପଢ଼ିବାକୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1027 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1474 +msgid "Stream has outstanding operation" +msgstr "ଧାରା ପାଖରେ ଉତà­à¬•ୃଷà­à¬Ÿ ପà­à¬°à­Ÿà­‹à¬— ଅଛି" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "ଉପାଦାନ <%s> କୠ<%s> ଭିତରେ ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "ଉପାଦାନ <%s> ଉପର ସà­à¬¤à¬°à¬°à­‡ ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "ଫାଇଲ %s ଟି ଉତà­à¬¸à¬°à­‡ à¬à¬•ାଧିକ ଥର ଦୃଶà­à­Ÿà¬®à¬¾à¬¨ ହୋଇଥାà¬" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "'%s' କୠକୌଣସି ଉତà­à¬¸ ଡିରେକà­à¬Ÿà­‹à¬°à­€à¬°à­‡ ଦେଖିବାରେ ବିଫଳ" + +# Gora: "change to directory" means "go to directory" here +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "ପà­à¬°à¬šà¬³à¬¿à¬¤ ଡିରେକà­à¬Ÿà­‹à¬°à¬¿à¬°à­‡ '%s' କୠପାଇବାରେ ଅସଫଳ" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "ଅଜଣା କାରà­à¬¯à­à­Ÿà¬•ାରୀ ବିକଳà­à¬ª \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "ଅସà­à¬¥à¬¾à­Ÿà­€ ଫାଇଲ ସà­à¬°à­à¬·à­à¬Ÿà¬¿ କରିବାରେ ବିଫଳ: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s ଫାଇଲ ପଢିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "%s ଫାଇଲକୠସଙà­à¬•ୋଚନ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s> ଭିତରେ ପାଠà­à­Ÿ ଦେଖାଯାଇ ନପାରେ" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "ଫଳାଫଳ ଫାଇଲର ନାମ" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"ଫାଇଲଗà­à¬¡à¬¼à¬¿à¬•ୠପଢ଼ିବାକୠଥିବା ଡିରେକà­à¬Ÿà­‹à¬°à­€ (ପà­à¬°à¬šà¬³à¬¿à¬¤ ଡିରେକà­à¬Ÿà­‹à¬°à­€ ପାଇଠ" +"ପୂରà­à¬¬à¬¨à¬¿à¬°à­à¬¦à­à¬§à¬¾à¬°à¬¿à¬¤)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "ବଚà­à¬›à¬¿à¬¤ ଶୈଳୀରେ ଲକà­à¬·à­à¬¯à¬¸à­à¬¥à¬³ ଫାଇଲ ନାମ ଅନà­à¬²à¬—à­à¬¨ ଦà­à­±à¬¾à¬°à¬¾ ଫଳାଫଳ କାଢନà­à¬¤à­" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "ଉତà­à¬¸ ଶୀରà­à¬·à¬• ସୃଷà­à¬Ÿà¬¿ କରନà­à¬¤à­" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "ଉତà­à¬¸ ଫାଇଲରେ ଆପଣଙà­à¬• ସଂକେତରେ ଉତà­à¬¸ ସଂକେତ ସୃଷà­à¬Ÿà¬¿ କରନà­à¬¤à­" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "ନିରà­à¬­à­‹à¬°à¬• ତାଲିକା ସୃଷà­à¬Ÿà¬¿ କରନà­à¬¤à­" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "ସà­à­±à­Ÿà¬‚ଚାଳିତ ଭାବରେ ଉତà­à¬¸à¬•ୠନିରà­à¬®à¬¾à¬£ କରି ପଞà­à¬œà¬¿à¬•ୃତ କରନà­à¬¤à­ ନାହିà¬" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "ଫଳନଗà­à¬¡à¬¼à¬¿à¬•ୠପଠାନà­à¬¤à­ ନାହିà¬; ସେଗà­à¬¡à¬¼à¬¿à¬•à­ G_GNUC_INTERNAL ଭାବରେ ଘୋଷଣା କରନà­à¬¤à­" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "ନିରà­à¬®à¬¿à¬¤ ଉତà­à¬¸ ସଂକେତ ପାଇଠବà­à­Ÿà¬¬à¬¹à­ƒà¬¤ C ପରିଚାୟକ ନାମ" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"à¬à¬• ଉତà­à¬¸ ଫାଇଲରେ ଉତà­à¬¸ ବିଶେଷାଙà­à¬• ସଙà­à¬•ଳନ କରନà­à¬¤à­à¥¤\n" +"ଉତà­à¬¸ ବିଶେଷାଙà­à¬• ଫାଇଲଗà­à¬¡à¬¼à¬¿à¬•ରେ extension .gresource.xml,\n" +"à¬à¬¬à¬‚ ଉତà­à¬¸ ଫାଇଲ ଥାଠଯାହାକୠ.gresource କà­à¬¹à¬¾à¬¯à¬¾à¬à¥¤" + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "ଆପଣଙà­à¬•ୠକେବଳ ଗୋଟିଠଫାଇଲ ନାମ ଦେବା ଉଚିତ\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "ଖାଲି ନାମଗà­à¬¡à¬¼à¬¿à¬• ଅନà­à¬®à¬¤à¬¿ ପà­à¬°à¬¾à¬ªà­à¬¤ ନà­à¬¹à¬" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "ଅବୈଧ ନାମ '%s': ନାମଗà­à¬¡à¬¼à¬¿à¬• ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ ଛୋଟ ଅକà­à¬·à¬°à¬°à­‡ ଆରମà­à¬­ ହୋଇଥିବା ଉଚିତ" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"ଅବୈଧ ନାମ '%s': ଅବୈଧ ଅକà­à¬·à¬° '%c'; କେବଳ ଛୋଟ ଅକà­à¬·à¬°, ଗଣନ ସଂଖà­à­Ÿà¬¾ à¬à¬¬à¬‚ ହାଇଫେନ ('-') " +"ଗà­à¬¡à¬¼à¬¿à¬• " +"ଅନà­à¬®à¬¤à¬¿ ପà­à¬°à¬¾à¬ªà­à¬¤à¥¤" + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "ଅବୈଧ ନାମ '%s': ଦà­à¬‡à¬Ÿà¬¿ କà­à¬°à¬®à¬¾à¬¨à­Ÿ ହାଇଫେନଗà­à¬¡à¬¼à¬¿à¬• ('--') ଅନà­à¬®à¬¤à¬¿ ପà­à¬°à¬¾à¬ªà­à¬¤ ନà­à¬¹à¬à¥¤" + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "ଅବୈଧ ନାମ '%s': ଶେଷ ଅକà­à¬·à¬° ହà­à¬à¬¤à¬ƒ ହାଇଫେନ ('-') ହୋଇନପାରେ।" + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "ଅବୈଧ ନାମ '%s': ସରà­à¬¬à¬¾à¬§à¬¿à¬• ଲମà­à¬¬ ହେଉଛି 1024" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " ପୂରà­à¬¬à¬°à­ ଉଲà­à¬²à­‡à¬– କରାଯାଇଛି" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "ଯୋଜନା 'ତାଲିକାରେ' କି ଗà­à¬¡à¬¼à¬¿à¬•ୠଯୋଗ କରିପାରିବେ ନାହିà¬" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " ପୂରà­à¬¬à¬°à­ ଉଲà­à¬²à­‡à¬– କରାଯାଇଛି" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" ଶାୟା ରେ; ମୂଲà­à­Ÿ ପରିବରà­à¬¤à­à¬¤à¬¨ " +"ପାଇଠ" +" କୠବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରନà­à¬¤à­" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"କେବଳ ଗୋଟିଠ'ପà­à¬°à¬•ାର', 'enum' କିମà­à¬¬à¬¾ 'flags' ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ ପାଇଠଉଲà­à¬²à­‡à¬– " +"ହେବା ଉଚିତ" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> କୠà¬à¬ªà¬°à­à¬¯à­à­Ÿà¬¨à­à¬¤ ବà­à­Ÿà¬¾à¬–à­à­Ÿà¬¾ କରାଯାଇ ନାହିà¬à¥¤" + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "ଅବୈଧ GVariant ପà­à¬°à¬•ାରର ବାକà­à­Ÿà¬–ଣà­à¬¡ '%s'" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " ଦିଆଯାଇଛି କିନà­à¬¤à­ ଯୋଜନାଟି କାହାକୠବଢ଼ାଉନାହିà¬" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "ନବଲିଖନ କରିବା ପାଇଠକୌଣସି ନାହିà¬" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " ପୂରà­à¬¬à¬°à­ ଉଲà­à¬²à­‡à¬– କରାଯାଇଛି" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " ପୂରà­à¬¬à¬°à­ ଉଲà­à¬²à­‡à¬– କରାଯାଇଛି" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " ଅନà­à¬²à¬®à­à¬¬à¬—à­à¬¡à¬¼à¬¿à¬•ରେ à¬à¬ªà¬°à­à¬¯à­à­Ÿà¬¨à­à¬¤ ଯୋଜନା '%s' ନାହିà¬" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" +" ଟି ହେଉଛି à¬à¬ªà¬°à­à¬¯à­à­Ÿà¬¨à­à¬¤ ଅନà­à¬²à¬®à­à¬¬à¬¿à¬¤ ହୋଇନଥିବା ଯୋଜନା '%s' ର ତାଲିକା" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "କୌଣସି ଯୋଜନାକୠପଥ ସହିତ ତାଲିକାଭà­à¬•à­à¬¤ କରିହେବ ନାହିà¬" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "କୌଣସି ଯୋଜନାକୠପଥ ସହିତ ଅନà­à¬²à¬®à­à¬¬à¬¿à¬¤ କରିହେବ ନାହିà¬" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ଟି ଗୋଟିଠତାଲିକା, କୠଅନà­à¬²à¬®à­à¬¬à¬¿à¬¤ କରାଯାଉଛି " +"ଯାହାକି ଗୋଟିଠ" +"ତାଲିକା ନà­à¬¹à¬" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" କୠବଢ଼ାଇଥାଠ" +"କିନà­à¬¤à­ " +"'%s' '%s' କୠବଢ଼ାଇନଥାà¬" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" +"ଯଦି ଗୋଟିଠପଥ ଦିଆଯାଇଥାà¬, ତେବେ ତାହା ଗୋଟିଠସà­à¬²à¬¾à¬¶ ସହିତ ଆରମà­à¬­ à¬à¬¬à¬‚ ଶେଷ ହେବା ଉଚିତ" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "ତାଲିକାର ପଥ ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ ':/' ସହିତ ସମାପà­à¬¤ ହେବା ଉଚିତ" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ପୂରà­à¬¬à¬°à­ ଉଲà­à¬²à­‡à¬– ହୋଇଛି" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "ଉପାଦାନ <%s> ଉପର ସà­à¬¤à¬°à¬°à­‡ ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict କୠଉଲà­à¬²à­‡à¬– କରାଯାଇଛି; ପà­à¬°à¬¸à­à¬¥à¬¾à¬¨ କରà­à¬…ଛି।\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "à¬à¬¹à¬¿ ଫାଇଲକୠସମà­à¬ªà­‚ରà­à¬£à­à¬£ ଭାବରେ ଅଗà­à¬°à¬¾à¬¹à­à­Ÿ କରାଯାଇଛି।\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "à¬à¬¹à¬¿ ଫାଇଲକୠଅଗà­à¬°à¬¾à¬¹à­à­Ÿ କରà­à¬…ଛି।\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"à¬à¬ªà¬°à¬¿ କୌଣସି କି '%s' ଯୋଜନା '%s' ରେ ଉଲà­à¬²à¬¿à¬–ିତ ଭାବରେ ନବଲିଖନ ଫାଇଲ '%s' ରେ ଉଲà­à¬²à­‡à¬– " +"ହୋଇନାହିà¬" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; à¬à¬¹à¬¿ କି ପାଇଠନବଲିଖନକୠଅଗà­à¬°à¬¾à¬¹à­à­Ÿ କରà­à¬…ଛି।\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " à¬à¬¬à¬‚ --strict କୠଉଲà­à¬²à­‡à¬– କରାଯାଇଛି; ପà­à¬°à¬¸à­à¬¥à¬¾à¬¨ କରà­à¬…ଛି।\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "କି '%s' କୠଯୋଜନା '%s' ରେ ନବଲିଖନ ଫାଇଲ '%s' ଭାବରେ ଉଲà­à¬²à­‡à¬– ହୋଇନାହିà¬: %s." + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "à¬à¬¹à¬¿ କି ପାଇଠନବଲିଖନକୠଅଗà­à¬°à¬¾à¬¹à­à­Ÿ କରà­à¬…ଛି।\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"କି '%s' ପାଇଠଯୋଜନା '%s' ରେ ନବଲିଖନ ଫାଇଲ '%s' କୠପà­à¬°à¬¦à¬¤à­à¬¤ ସୀମା ବାହାରେ ନବଲିଖନ" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"କି '%s' ପାଇଠଯୋଜନା '%s' ରେ ନବଲିଖନ ଫାଇଲ '%s' କୠପà­à¬°à¬¦à¬¤à­à¬¤ ସୀମା ବାହାରେ ନବଲିଖନ " +"ତାଲିକାରେ " +"ବୈଧ ପସନà­à¬¦ ଭାବରେ ନାହିà¬" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled ଫାଇଲକୠକେଉà¬à¬ à¬¿ ସଂରକà­à¬·à¬£ କରିବେ" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "ଯୋଜନାନରେ କୌଣସି ତà­à¬°à­à¬Ÿà¬¿à¬•ୠପରିତà­à­Ÿà¬¾à¬— କରନà­à¬¤à­" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled ଫାଇଲକୠଲେଖନà­à¬¤à­ ନାହିà¬" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "କି ନାମ ପà­à¬°à¬¤à¬¿à¬¬à¬¨à­à¬§à¬•ୠବାଧà­à­Ÿ କରନà­à¬¤à­ ନାହିà¬" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"ସମସà­à¬¤ GSettings ଯୋଜନା ଫାଇଲଗà­à¬¡à¬¼à¬¿à¬•ୠଯୋଜନା କà­à­Ÿà¬¾à¬¶à­‡ ମଧà­à¬¯à¬°à­‡ ସଙà­à¬•ଳନ କରନà­à¬¤à­à¥¤\n" +"ଯୋଜନା ଫାଇଲଗà­à¬¡à¬¼à¬¿à¬•ରେ ଅନà­à¬²à¬—à­à¬¨ .gschema.xml,\n" +"à¬à¬¬à¬‚ gschemas.compiled ନାମକ କà­à­Ÿà¬¾à¬¶à­‡ ଫାଇଲ ଥିବା ଉଚିତ।" + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "ଆପଣଙà­à¬•ୠକେବଳ ଗୋଟିଠଡିରେକà­à¬Ÿà­‹à¬°à­€ ନାମ ଦେବା ଉଚିତ\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "କୌଣସି ଯୋଜନା ଫାଇଲ ମିଳିଲା ନାହିà¬: " + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "କିଛି କରà­à¬¨à¬¾à¬¹à¬¿à¬à¥¤\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "ସà­à¬¥à¬¿à¬¤à¬¬à¬¾à¬¨ ଫଳାଫଳ ଫାଇଲକୠକଢ଼ାଯାଇଛି।\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "ପୂରà­à¬¬à¬¨à¬¿à¬°à­à¬¦à­à¬§à¬¾à¬°à¬¿à¬¤ ସà­à¬¥à¬¾à¬¨à­€à­Ÿ ଡିରେକà­à¬Ÿà­‹à¬°à­€ ମନିଟର ପà­à¬°à¬•ାର ଖୋଜିବାରେ ଅସମରà­à¬¥" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "ଅବୈଧ ଫାଇଲ ନାମ %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ଫାଇଲତନà­à¬¤à­à¬° ସୂଚନା ପାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "ମୂଳ ଡିରେକà­à¬Ÿà­‹à¬°à­€à¬° ନାମ ବଦଳାଯାଇପାରିବ ନାହିà¬" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "ଫାଇଲର ନାମ ବଦଳାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "ଫାଇଲର ନାମ ବଦଳାଯାଇପାରିବେ ନାହିà¬, ଫାଇଲ ନାମ ପୂରà­à¬¬à¬°à­ ଅବସà­à¬¥à¬¿à¬¤" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "ଅବୈଧ ଫାଇଲ ନାମ" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "ଡିରେକà­à¬Ÿà­‹à¬°à­€ ଖୋଲିପାରିବେ ନାହିà¬" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "ଫାଇଲ ଖୋଲିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "ଫାଇଲ ଅପସାରଣରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "ଫାଇଲକୠବରà­à¬œà¬¨ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "ଆବରà­à¬œà¬¨à¬¾ ପାତà­à¬° ଡିରେକà­à¬Ÿà­‹à¬°à­€ %sକୠନିରà­à¬®à¬¾à¬£ କରିବାରେ ଅସମରà­à¬¥: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "ଆବରà­à¬œà¬¨à¬¾ ପାତà­à¬° ପାଇଠଉଚà­à¬šà¬¸à­à¬¤à¬°à­€à­Ÿ ଡିରେକà­à¬Ÿà­‹à¬°à­€ ଖୋଜିବାରେ ଅସମରà­à¬¥" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "ଆବରà­à¬œà¬¨à¬¾ ପାତà­à¬° ଡିରେକà­à¬Ÿà­‹à¬°à­€ ଖୋଜିବା à¬à¬¬à¬‚ ନିରà­à¬®à¬¾à¬£ କରିବାରେ ଅସମରà­à¬¥" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "ବରà­à¬œà¬¿à¬¤ ସୂଚନା ଫାଇଲ ନିରà­à¬®à¬¾à¬£à¬°à­‡ ଅସମରà­à¬¥ : %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ଫାଇଲକୠବରà­à¬œà¬¨ କରିବାରେ ଅସମରà­à¬¥: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "ଆଭà­à¬¯à¬¨à­à¬¤à¬°à­€à¬£ ତୃଟି" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "ଡିରେକà­à¬Ÿà­‹à¬°à¬¿ ନିରà­à¬®à¬¾à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ଫାଇଲତନà­à¬¤à­à¬° ସାଙà­à¬•େତିକ ସଂଯୋଗିକିଗà­à¬¡à¬¼à¬¿à¬•ୠସହାୟତା କରେନାହିà¬" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "ପà­à¬°à¬¤à­€à¬•ାତà­à¬®à¬• ସମà­à¬ªà¬°à­à¬• ନିରà­à¬®à¬¾à¬£à¬°à­‡ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "ଫାଇଲ ଘà­à¬žà­à¬šà¬¾à¬‡à¬¬à¬¾à¬°à­‡ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "ଡିରେକà­à¬Ÿà­‹à¬°à­€ ଉପରେ ଡିରେକà­à¬Ÿà­‹à¬°à­€à¬•ୠଘà­à¬žà­à¬šà¬¾à¬‡à¬ªà¬¾à¬°à¬¿à¬¬à­‡ ନାହିà¬" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "ନକଲ ସଂରକà­à¬·à¬£ ଫାଇଲ ନିରà­à¬®à¬¾à¬£ ଅସଫଳ ହେଲା" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "ଲକà­à¬·à­à­Ÿ ଫାଇଲ ଘà­à¬žà­à¬šà¬¾à¬‡à¬¬à¬¾à¬°à­‡ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "ଅସମରà­à¬¥à¬¿à¬¤ ସà­à¬¥à¬¾à¬ªà¬¨à¬—à­à¬¡à¬¼à¬¿à¬• ମଧà­à¬¯à¬°à­‡ ଗତିକରନà­à¬¤à­" + +#: ../gio/glocalfile.c:2603 +#, c-format +#| msgid "Could not load schemas from %s: %s\n" +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s ର ଡିସà­à¬• ବà­à­Ÿà¬¬à¬¹à¬¾à¬° ନିରà­à¬¦à­à¬§à¬¾à¬°à¬£ କରିପାରିଲା ନାହିà¬: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "ଗà­à¬£à¬° ମୂଲà­à­Ÿ ନିଶà­à¬šà¬¿à¬¤à¬°à­‚ପେ non-NULL ହୋଇଥିବା ଉଚିତ" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "ଅବୈଧ ଗà­à¬£à¬° ପà­à¬°à¬•ାର (ବାକà­à­Ÿà¬–ଣà­à¬¡ ଆଶାକରାଯାଉଛି)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "ଅବୈଧ ବିସà­à¬¤à­ƒà¬¤ ଗà­à¬£à¬° ନାମ" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "ଅନà­à¬²à¬—à­à¬¨ ଗà­à¬£ '%s'କୠବିନà­à­Ÿà¬¾à¬¸ କରିବା ସମୟରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (ଅବୈଧ ସାଙà­à¬•େତିକରଣ)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "ଫାଇଲ '%s' ପାଇଠସୂଚନା ପାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "ଫାଇଲ ନିରୂପକ ପାଇଠସୂଚନା ପାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "ଅବୈଧ ଗà­à¬£ ପà­à¬°à¬•ାର (unit32 ଆଶାକରାଯାଉଛି)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "ଅବୈଧ ଗà­à¬£ ପà­à¬°à¬•ାର (unit64 ଆଶାକରାଯାଉଛି)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "ଅବୈଧ ଗà­à¬£ ପà­à¬°à¬•ାର (ବାଇଟ ବାକà­à­Ÿà¬–ଣà­à¬¡ ଆଶାକରାଯାଉଛି)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "symlinks ରେ ଅନà­à¬®à¬¤à¬¿à¬—à­à¬¡à¬¼à¬¿à¬•ୠସେଟ କରିପାରିବେ ନାହିà¬" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "ଅନà­à¬®à¬¤à¬¿ ବିନà­à­Ÿà¬¾à¬¸à¬•ରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "ମାଲିକ ନିରà­à¬ªà¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "symlink ନିଶà­à¬šà¬¿à¬¤ ରୂପେ non-NULL" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "symlink ବିନà­à­Ÿà¬¾à¬¸ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "symlink ବିନà­à­Ÿà¬¾à¬¸ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: ଫାଇଲଟି ଗୋଟିଠsymlink ନà­à¬¹à¬" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "ପରିବରà­à¬¤à­à¬¤à¬¨ ଅଥବା ଅଭିଗମà­à­Ÿà¬¤à¬¾ ସମୟ ବିନà­à­Ÿà¬¾à¬¸à¬•ରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux ପà­à¬°à¬¸à¬™à­à¬—ଟି ନିଶà­à¬šà¬¿à¬¤ ରୂପେ non-NULL ଅଟେ" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux ପà­à¬°à¬¸à¬™à­à¬— ବିନà­à­Ÿà¬¾à¬¸ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "SELinux à¬à¬¹à¬¿ ତନà­à¬¤à­à¬°à¬°à­‡ ସକà­à¬°à¬¿à­Ÿ ହୋଇନାହିà¬" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "ଗà­à¬£ %s ବିନà­à­Ÿà¬¾à¬¸ କରିବା ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "ଫାଇଲରୠପଢିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ଫାଇଲଭିତରେ ଅନà­à¬¸à¬¨à­à¬§à¬¾à¬¨ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "ଫାଇଲ ବନà­à¬¦à¬•ରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "ପୂରà­à¬¬à¬¨à¬¿à¬°à­à¬¦à­à¬§à¬¾à¬°à¬¿à¬¤ ସà­à¬¥à¬¾à¬¨à­€à­Ÿ ଫାଇଲ ମନିଟର ପà­à¬°à¬•ାର ଖୋଜିବାରେ ଅସମରà­à¬¥" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "ଫାଇଲଭିତରେ ଲେଖିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "ପà­à¬°à­à¬£à¬¾ ନକଲ ସଂରକà­à¬·à¬£ ସଂଯୋଗ ଅପସାରଣ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "ନକଲ ସଂରକà­à¬·à¬£ ନକଲ ନିରà­à¬®à¬¾à¬£à¬°à­‡ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "ଅସà­à¬¥à¬¾à­Ÿà­€ ଫାଇଲର ନାମ ବଦଳାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "ଫାଇଲ ବିଚà­à¬›à¬¿à¬¨à­à¬¨ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "ଫାଇଲ '%s' ଖୋଲିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "ଲକà­à¬·à­à­Ÿ ଫାଇଲଟି ଗୋଟିଠଡିରେକà­à¬Ÿà­‹à¬°à­€ ଅଟେ" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "ଲକà­à¬·à­à­Ÿ ଫାଇଲଟି ଗୋଟିଠନିୟମିତ ଫାଇଲ ନà­à¬¹à­‡à¬" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "ଫାଇଲଟି ବାହାରୠପରିବରà­à¬¤à­à¬¤à¬¿à¬¤" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "ପà­à¬°à­à¬£à¬¾ ଫାଇଲକୠଅପସାରଣରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "ଅବୈଧ GSeekType ଦିଆଯାଇଅଛି" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "ଅବୈଧ ଅନà­à¬¸à¬¨à­à¬§à¬¾à¬¨ ଅନà­à¬°à­‹à¬§" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream କୠବିଚà­à¬›à¬¿à¬¨à­à¬¨ କରିହେବ ନାହିଠ" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "ସà­à¬®à­ƒà¬¤à¬¿ ଫଳାଫଳ ବାକà­à¬¯à¬–ଣà­à¬¡à¬° ଆକାର ବଦଳାଯାଇପାରିବ ନାହିà¬" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "ସà­à¬®à­ƒà¬¤à¬¿ ଫଳାଫଳ ବାକà­à¬¯à¬–ଣà­à¬¡à¬° ଆକାର ବଦଳାଇବାରେ ଅସଫଳ" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "ଲେଖିବା ପାଇଠଆବଶà­à­Ÿà¬•ୀୟ ସà­à¬®à­ƒà¬¤à¬¿ ସà­à¬¥à¬¾à¬¨ ଉପଲବà­à¬§ ଠିକଣା ଠାରୠଅଧିକ" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "ଧାରା ଆରମà­à¬­ ପୂରà­à¬¬à¬°à­ ପାଇବା ପାଇଠଅନà­à¬°à­‹à¬§ କରିଛି" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "ଧାରା ସମାପà­à¬¤ ପୂରà­à¬¬à¬°à­ ପାଇବା ପାଇଠଅନà­à¬°à­‹à¬§ କରିଛି" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "\"unmount\" କୠmount କାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "\"eject\" କୠmount କାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"\"unmount\" କିମà­à¬¬à¬¾ \"unmount_with_operation\" କୠmount କାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"\"eject\" କିମà­à¬¬à¬¾ \"eject_with_operation\" କୠmount କାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "\"remount\" କୠmount କାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "ସà­à¬¥à¬¾à¬ªà¬¨ ସୂଚୀପତà­à¬° ପà­à¬°à¬•ାର ଅନà­à¬®à¬¾à¬¨à¬•ୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "ସà­à¬¥à¬¾à¬ªà¬¨ ସମକାଳୀନ ସୂଚୀପତà­à¬° ପà­à¬°à¬•ାର ଅନà­à¬®à¬¾à¬¨à¬•ୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gnetworkaddress.c:338 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "'%s' ଆଧାର ନାମ '[' but not ']' କୠଧାରଣ କରିଥାà¬" + +#: ../gio/gnetworkmonitorbase.c:189 ../gio/gnetworkmonitorbase.c:292 +msgid "Network unreachable" +msgstr "ନେଟୱରà­à¬• ଅପହଞà­à¬š ଦୂରତାରେ ଅଛି" + +#: ../gio/gnetworkmonitorbase.c:227 ../gio/gnetworkmonitorbase.c:257 +msgid "Host unreachable" +msgstr "ହୋଷà­à¬Ÿ ଅପହଞà­à¬š ଦୂରତାରେ ଅଛି" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "ନେଟୱରà­à¬• ପà­à¬°à¬¦à¬°à­à¬¶à¬¿à¬•ା ନିରà­à¬®à¬¾à¬£ କରି ପାଇଲା ନାହିà¬: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "ନେଟୱରà­à¬• ପà­à¬°à¬¦à¬°à­à¬¶à¬¿à¬•ା ନିରà­à¬®à¬¾à¬£ କରି ପାଇଲା ନାହିà¬:" + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "ନେଟୱରà­à¬• ସà­à¬¥à¬¿à¬¤à¬¿ ପାଇଲା ନାହିà¬:" + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:550 +msgid "Output stream doesn't implement write" +msgstr "ଫଳାଫଳ ବାକà­à¬¯à¬–ଣà­à¬¡ ଲେଖିବାକୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/goutputstream.c:511 ../gio/goutputstream.c:1028 +msgid "Source stream is already closed" +msgstr "ଉତà­à¬¸ ବାକà­à­Ÿà¬–ଣà­à¬¡à¬Ÿà¬¿ ପୂରà­à¬¬à¬°à­ ବନà­à¬¦à¬¹à­‹à¬‡à¬¯à¬¾à¬‡à¬›à¬¿" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' କୠସମାଧାନ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' ରେ ଉତà­à¬¸ ଅବସà­à¬¥à¬¿à¬¤ ନାହିà¬" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "ସଙà­à¬•ଚନ ଖୋଲିବା ପାଇଠ'%s' ରେ ଉତà­à¬¸ ବିଫଳ ହୋଇଛି" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "'%s' ରେ ଥିବା ଉତà­à¬¸à¬Ÿà¬¿ à¬à¬• ଡିରେକà­à¬Ÿà­‹à¬°à­€ ନà­à¬¹à¬" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "ନିବେଶ ଧାରାରେ ପଢ଼ିବାକୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gresource-tool.c:487 +msgid "List sections containing resources in an elf FILE" +msgstr "elf FILE ରେ ଉତà­à¬¸à¬—à­à¬¡à¬¼à¬¿à¬•ୠଧାରଣ କରିଥିବା ତାଲିକା ବିଭାଗ" + +#: ../gio/gresource-tool.c:493 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"ତାଲିକା ଉତà­à¬¸à¬—à­à¬¡à¬¼à¬¿à¬•\n" +"ଯଦି SECTION ଦିଆଯାଇଥାà¬, ତେବେ à¬à¬¹à¬¿ ବିବାଗରେ କେବଳ ଉତà­à¬¸à¬—à­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­\n" +"ଯଦି PATH ଦିଆଯାଇଥାà¬, ତେବେ ମେଳଖାଉଥିବା ଉତà­à¬¸à¬—à­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­" + +#: ../gio/gresource-tool.c:496 ../gio/gresource-tool.c:506 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:497 ../gio/gresource-tool.c:507 +#: ../gio/gresource-tool.c:514 +msgid "SECTION" +msgstr "ବିଭାଗ" + +#: ../gio/gresource-tool.c:502 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"ବିବରଣୀ ସହିତ ତାଲିକା ଉତà­à¬¸à¬—à­à¬¡à¬¼à¬¿à¬•\n" +"ଯଦି SECTION ଦିଆଯାଇଥାà¬, ତେବେ କେବଳ à¬à¬¹à¬¿ ବିଭାଗରେ ଥିବା ଉତà­à¬¸à¬—à­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ " +"କରନà­à¬¤à­\n" +"ଯଦି PATH ଦିଆଯାଇଥାà¬, ତେବେ ମେଳଖାଉଥିବା ଉତà­à¬¸à¬—à­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­\n" +"à¬à¬¹à¬¿ ବିଭାଗରେ ବିବରଣୀ, ଆକାର à¬à¬¬à¬‚ ସଙà­à¬•ୋଚନଗà­à¬¡à¬¼à¬¿à¬• ଅନà­à¬¤à¬°à­à¬­à­à¬•à­à¬¤" + +#: ../gio/gresource-tool.c:512 +msgid "Extract a resource file to stdout" +msgstr "stdout କରିବାକୠà¬à¬• ଉତà­à¬¸à¬•ୠବାହାର କରନà­à¬¤à­" + +#: ../gio/gresource-tool.c:513 +msgid "FILE PATH" +msgstr "ଫାଇଲ ପଥ" + +#: ../gio/gresource-tool.c:527 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"ବà­à­Ÿà¬¬à¬¹à¬¾à¬° ବିଧି:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"ନିରà­à¬¦à­à¬¦à­‡à¬¶à¬—à­à¬¡à¬¼à¬¿à¬•:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"ବିସà­à¬¤à¬¾à¬° ଭାବରେ ସହାୟତା ପାଇବା ପାଇଠ'gresource help COMMAND' ବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରନà­à¬¤à­à¥¤\n" +"\n" + +#: ../gio/gresource-tool.c:541 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ବà­à¬¯à¬¬à¬¹à¬¾à¬° ବିଧି:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:548 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION à¬à¬• (ବୈକଳà­à¬ªà¬¿à¬•) elf ବିଭାଗ ନାମ\n" + +#: ../gio/gresource-tool.c:552 ../gio/gsettings-tool.c:635 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND ବରà­à¬£à­à¬£à¬¨à¬¾ କରିବା ପାଇଠ(ବୈକଳà­à¬ªà¬¿à¬•) ନିରà­à¬¦à­à¬¦à­‡à¬¶\n" + +#: ../gio/gresource-tool.c:558 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE à¬à¬• elf ଫାଇଲ (à¬à¬• ଦà­à­±à¬®à¬¿à¬• ଅଥବା ସହଭାଗୀ ଲାଇବà­à¬°à­‡à¬°à­€)\n" + +#: ../gio/gresource-tool.c:561 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE à¬à¬• elf ଫାଇଲ (à¬à¬• ଦà­à­±à¬®à¬¿à¬• ଅଥବା ସହଭାଗୀ ଲାଇବà­à¬°à­‡à¬°à­€)\n" +" କିମà­à¬¬à¬¾ à¬à¬• ଉତà­à¬¸ ଫାଇଲ\n" + +#: ../gio/gresource-tool.c:565 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:567 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH à¬à¬• (ଇଚà­à¬›à¬¾à¬®à­à¬¤à¬¾à¬¬à¬•) ଉତà­à¬¸ ପଥ (ହà­à¬à¬¤à¬ƒ ଆଂଶିକ)\n" + +#: ../gio/gresource-tool.c:568 +msgid "PATH" +msgstr "ପଥ" + +#: ../gio/gresource-tool.c:570 +msgid " PATH A resource path\n" +msgstr " PATH à¬à¬• ଉତà­à¬¸ ପଥ\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "à¬à¬ªà¬°à¬¿ କୌଣସି ଯୋଜନା ନାହିଠ'%s'\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" +"ଯୋଜନା '%s' କୠସà­à¬¥à¬¾à¬¨à¬¾à¬¨à­à¬¤à¬° କରିହେବ ନାହିଠ(ପଥକୠନିଶà­à¬šà¬¿à¬¤ ଭାବରେ ଉଲà­à¬²à­‡à¬– କରିହେବ " +"ନାହିà¬)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "ଯୋଜନା '%s' କୠସà­à¬¥à¬¾à¬¨à¬¾à¬¨à­à¬¤à¬° କରିହେବ (ପଥ ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ ଉଲà­à¬²à¬¿à¬–ିତ)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "ଖାଲି ପଥ ଦିଆଯାଇଛି।\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "ପଥଟି ସà­à¬²à¬¾à¬¶ (/) ସହିତ ଆରମà­à¬­ ହେବା ଉଚିତ\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "ପଥଟି ସà­à¬²à¬¾à¬¶ (/) ସହିତ ଶେଷ ହେବା ଉଚିତ\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "ପଥରେ ଦà­à¬‡à¬Ÿà¬¿ ପାଖାପାଖି ସà­à¬²à¬¾à¬¶ (//) ରହିବା ଉଚିତ ନà­à¬¹à¬\n" + +#: ../gio/gsettings-tool.c:477 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "ପà­à¬°à¬¦à¬¤à­à¬¤ ମୂଲà­à­Ÿà¬Ÿà¬¿ ସୀମା ବାହାରେ\n" + +#: ../gio/gsettings-tool.c:484 +#, c-format +msgid "The key is not writable\n" +msgstr "à¬à¬¹à¬¿ କି ଟି ଲେଖିବାଯୋଗà­à­Ÿ ନà­à¬¹à¬\n" + +#: ../gio/gsettings-tool.c:520 +msgid "List the installed (non-relocatable) schemas" +msgstr "ସà­à¬¥à¬¾à¬ªà¬¿à¬¤ (ସà­à¬¥à¬¾à¬¨à¬¾à¬¨à­à¬¤à¬°-ଅଯୋଗà­à­Ÿ) ଯୋଜନାଗà­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:526 +msgid "List the installed relocatable schemas" +msgstr "ସà­à¬¥à¬¾à¬ªà¬¿à¬¤ ସà­à¬¥à¬¾à¬¨à¬¾à¬¨à­à¬¤à¬°à¬¯à­‹à¬—à­à­Ÿ ଯୋଜନାଗà­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:532 +msgid "List the keys in SCHEMA" +msgstr "SCHEMA ରେ ଥିବା କିଗà­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:533 ../gio/gsettings-tool.c:539 +#: ../gio/gsettings-tool.c:576 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:538 +msgid "List the children of SCHEMA" +msgstr "SCHEMA ର ନିମà­à¬¨à¬¸à­à¬¤à¬°à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:544 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"କି à¬à¬¬à¬‚ ମୂଲà­à­Ÿà¬—à­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­, ପà­à¬¨à¬ƒà¬ªà­Œà¬¨à¬¿à¬• ଭାବରେ\n" +"ଯଦି କୌଣସି ଯୋଜନା ଦିଆଯାଇନଥାà¬, ତେବେ ସମସà­à¬¤ କି ଗà­à¬¡à¬¼à¬¿à¬•ୠତାଲିକାଭà­à¬•à­à¬¤ କରନà­à¬¤à­\n" + +#: ../gio/gsettings-tool.c:546 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:551 +msgid "Get the value of KEY" +msgstr "KEY ପାଇଠମୂଲà­à­Ÿ ଆଣନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:570 ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:557 +msgid "Query the range of valid values for KEY" +msgstr "KEY ପାଇଠବୈଧ ମୂଲà­à­Ÿà¬° ସୀମା ପଚରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:563 +msgid "Set the value of KEY to VALUE" +msgstr "KEY ର ମୂଲà­à­Ÿà¬•à­ VALUE ରେ ସେଟକରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:564 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:569 +msgid "Reset KEY to its default value" +msgstr "KEY କୠତାହାର ପୂରà­à¬¬à¬¨à¬¿à¬°à­à¬¦à­à¬§à¬¾à¬°à¬¿à¬¤ ମୂଲà­à­Ÿà¬°à­‡ ପà­à¬¨à¬ƒà¬¸à­à¬¥à¬¾à¬ªà¬¨ କରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:575 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" +"SCHEMA ରେ ଥିବା ସମସà­à¬¤ କିଗà­à¬¡à¬¼à¬¿à¬•ୠତାହାର ପୂରà­à¬¬à¬¨à¬¿à¬°à­à¬¦à­à¬§à¬¾à¬°à¬¿à¬¤ ମୂଲà­à­Ÿà¬°à­‡ ପà­à¬¨à¬ƒà¬¸à­à¬¥à¬¾à¬ªà¬¨ " +"କରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:581 +msgid "Check if KEY is writable" +msgstr "KEY ଟି ଲିଖନଯୋଗà­à­Ÿ କି ନà­à¬¹à¬ ତାହା ଯାଞà­à¬š କରନà­à¬¤à­" + +#: ../gio/gsettings-tool.c:587 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"ପରିବରà­à¬¤à­à¬¤à¬¨à¬—à­à¬¡à¬¼à¬¿à¬• ପାଇଠKEY କୠନିରୀକà­à¬·à¬£ କରନà­à¬¤à­à¥¤\n" +"ଯଦି କୌଣସି KEY ଉଲà­à¬²à­‡à¬– ହୋଇନାହିà¬, ତେବେ SCHEMA ରେ ଥିବା ସମସà­à¬¤ କିଗà­à¬¡à¬¼à¬¿à¬•ୠନିରୀକà­à¬·à¬£ " +"କରନà­à¬¤à­à¥¤\n" +"ନିରୀକà­à¬·à¬£ କରିବା ପାଇଠ^C କୠବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରନà­à¬¤à­à¥¤\n" + +#: ../gio/gsettings-tool.c:590 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:602 +#| msgid "" +#| "Usage:\n" +#| " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " list-schemas List installed schemas\n" +#| " list-relocatable-schemas List relocatable schemas\n" +#| " list-keys List keys in a schema\n" +#| " list-children List children of a schema\n" +#| " list-recursively List keys and values, recursively\n" +#| " range Queries the range of a key\n" +#| " get Get the value of a key\n" +#| " set Set the value of a key\n" +#| " reset Reset the value of a key\n" +#| " reset-recursively Reset all values in a given schema\n" +#| " writable Check if a key is writable\n" +#| " monitor Watch for changes\n" +#| "\n" +#| "Use 'gsettings help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"ବà­à­Ÿà¬¬à¬¹à¬¾à¬° ବିଧି:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"ନିରà­à¬¦à­à¬¦à­‡à¬¶à¬—à­à¬¡à¬¼à¬¿à¬•:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"ସମà­à¬ªà­‚ରà­à¬£à­à¬£ ସହାୟତା ପାଇବା ପାଇଠ'gsettings help COMMAND' କୠବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରନà­à¬¤à­à¥¤\n" +"\n" + +#: ../gio/gsettings-tool.c:625 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ବà­à¬¯à¬¬à¬¹à¬¾à¬° ବିଧି:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:631 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "ଅତିରିକà­à¬¤ ଯୋଜନା ପାଇଠSCHEMADIR à¬à¬• ଡିରେକà­à¬Ÿà­‹à¬°à­€ ଅଟେ\n" + +#: ../gio/gsettings-tool.c:639 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA ଯୋଜନାର ନାମ\n" +" PATH ସà­à¬¥à¬¾à¬¨à¬¾à¬¨à­à¬¤à¬°à¬£ ଯୋଗà­à­Ÿ ପଥ\n" + +#: ../gio/gsettings-tool.c:644 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY ଯୋଜନା ମଧà­à¬¯à¬°à­‡ ଥିବା (ବୈକଳà­à¬ªà¬¿à¬•) କି\n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The key within the schema\n" +msgstr " KEY ଯୋଜନା ମଧà­à¬¯à¬°à­‡ ଥିବା କି\n" + +#: ../gio/gsettings-tool.c:652 +msgid " VALUE The value to set\n" +msgstr " VALUE ସେଟ କରିବା ପାଇଠଥିବା ମୂଲà­à­Ÿ\n" + +#: ../gio/gsettings-tool.c:707 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s ରୠଯୋଜନାକୠଧାରଣ କରିନାହିà¬: %s\n" + +#: ../gio/gsettings-tool.c:769 +#, c-format +msgid "Empty schema name given\n" +msgstr "ଖାଲି ଯୋଜନା ନାମ ଦିଆଯାଇଛି\n" + +#: ../gio/gsettings-tool.c:798 +#, c-format +msgid "No such key '%s'\n" +msgstr "à¬à¬ªà¬°à¬¿ କୌଣସି କି ନାହିଠ'%s'\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "ଅବୈଧ ସକେଟ, ଆରମà­à¬­ ହୋଇନାହିà¬" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ଅବୈଧ ସକେଟ, à¬à¬¹à¬¾ ଯୋଗà­à¬ ପà­à¬°à¬¾à¬°à¬®à­à¬­à¬¿à¬•ରଣ ବିଫଳ ହୋଇଛି: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "ସକେଟ ପୂରà­à¬¬à¬°à­ ବନà­à¬¦à¬¹à­‹à¬‡à¬¯à¬¾à¬‡à¬›à¬¿" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "ସକେଟ I/O ର ସମୟ ସମାପà­à¬¤" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd ରୠGSocket ନିରà­à¬®à¬¾à¬£ କରà­à¬…ଛି : %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "ସକେଟ ନିରà­à¬®à¬¾à¬£ କରିବାରେ ଅସମରà­à¬¥: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "ଅଜଣା ପରିବାରକୠଉଲà­à¬²à­‡à¬– କରାଯାଇଛି" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "ଅଜଣା ପà­à¬°à¬Ÿà­‹à¬•ଲକୠଉଲà­à¬²à­‡à¬– କରାଯାଇଛି" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "ସà­à¬¥à¬¾à¬¨à­€à­Ÿ ଠିକଣା ପାଇଲା ନାହିà¬: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "ସà­à¬¦à­‚ର ଠିକଣା ପାଇଲା ନାହିà¬: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "ଶà­à¬£à¬¿ ପାରିଲା ନାହିà¬: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "ଠିକଣା ସହିତ ବାନà­à¬§à¬¿à¬¬à¬¾à¬°à­‡ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "ମଲଟିକାଷà­à¬Ÿ ସମୂହକୠଯୋଗ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "ମଲଟିକାଷà­à¬Ÿ ସମୂହକୠତà­à­Ÿà¬¾à¬— କରିବା ସମୟରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "ଉତà­à¬¸ ନିରà­à¬¦à­à¬¦à¬¿à¬·à­à¬Ÿ ମଲଟିକାଷà­à¬Ÿ ପାଇଠକୌଣସି ସହାୟତା ନାହିà¬" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "ସଂଯୋଗ ଗà­à¬°à¬¹à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "ସଂଯୋଗ କà­à¬°à¬¿à­Ÿà¬¾ ଚାଲିଅଛି" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "ବକୟା ତà­à¬°à­à¬Ÿà¬¿ ପାଇବାରେ ଅସମରà­à¬¥:" + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "ତଥà­à­Ÿ ଗà­à¬°à¬¹à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "ତଥà­à­Ÿ ପଠାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ସକେଟ ବନà­à¬¦ କରିବାରେ ଅସମରà­à¬¥: %s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "ସକେଟ ବନà­à¬¦à¬•ରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ସକେଟ ଅବସà­à¬¥à¬¾ ପାଇଠଅପେକà­à¬·à¬¾ କରିଅଛି: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "ସନà­à¬¦à­‡à¬¶ ପଠାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage Windows ରେ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "ସନà­à¬¦à­‡à¬¶ ଗà­à¬°à¬¹à¬£ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gsocket.c:4516 +#, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to read socket credentials: %s" +msgstr "ସକେଟ ଅଧିକାରଗà­à¬¡à¬¼à¬¿à¬•ୠପଢ଼ିବାରେ ଅସମରà­à¬¥: %s" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials କୠà¬à¬¹à¬¿ OS ପାଇଠନିଯà­à¬•à­à¬¤ କରାଯାଇ ନାହିà¬" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "ପà­à¬°à¬•à­à¬¸à¬¿ ସରà­à¬­à¬° %s ସହିତ ସଂଯୋଗ କରିପାରିଲା ନାହିà¬: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s ସହିତ ସଂଯà­à¬•à­à¬¤ କରିପାରିଲା ନାହିà¬:" + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "ସଂଯà­à¬•à­à¬¤ କରିପାରିଲା ନାହିà¬:" + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1597 +msgid "Unknown error on connect" +msgstr "ସଂଯୋଗ କରିବା ସମୟରେ ଅଜଣା ତୃଟି" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1532 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "à¬à¬• TCP ହୀନ ସଂଯୋଗ ଉପରେ ପà­à¬°à¬•à­à¬¸à¬¿ ସଂଯୋଗ ସହାୟତା ପà­à¬°à¬¾à¬ªà­à¬¤ ନà­à¬¹à¬à¥¤" + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1553 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "ପà­à¬°à¬•à­à¬¸à¬¿ ପà­à¬°à¬Ÿà­‹à¬•ଲ '%s' ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬à¥¤" + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "ଗà­à¬°à¬¹à¬£à¬•ାରୀ ପୂରà­à¬¬à¬°à­ ବନà­à¬¦à¬…ଛି" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "ଅତିରିକà­à¬¤ ସକେଟ ବନà­à¬¦ ଅଛି" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 IPv6 ଠିକଣା '%s' କୠସମରà­à¬¥à¬¨ କରେନାହିà¬" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 ପà­à¬°à­‹à¬Ÿà­‹à¬•ଲ ପାଇଠବà­à­Ÿà¬¬à¬¹à¬¾à¬°à¬•ାରୀ ନାମଟି ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "ହୋଷà­à¬Ÿà¬¨à¬¾à¬® '%s' ଟି SOCKSv4 ପà­à¬°à¬Ÿà­‹à¬•ଲ ପାଇଠଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "à¬à¬¹à¬¿ ସରà­à¬­à¬°à¬Ÿà¬¿ ଗୋଟିଠSOCKSv4 ପà­à¬°à¬•à­à¬¸à¬¿ ସରà­à¬­à¬° ନà­à¬¹à¬à¥¤" + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 ସରà­à¬­à¬° ମାଧà­à¬¯à¬®à¬°à­‡ ଥିବା ସଂଯୋଗକୠପà­à¬°à¬¤à­à­Ÿà¬¾à¬–à­à­Ÿà¬¾à¬¨ କରାଯାଇଛି" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "ସରà­à¬­à¬°à¬Ÿà¬¿ ଗୋଟିଠSOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ ସରà­à¬­à¬° ନà­à¬¹à¬à¥¤" + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ ବୈଧିକରଣ ଆବଶà­à­Ÿà¬• କରିଥାà¬à¥¤" + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ à¬à¬• ବୈଧିକରଣ ପଦà­à¬§à¬¤à¬¿ ଆବଶà­à­Ÿà¬• କରିଥାଠଯାହାକି GLib ଦà­à­±à¬¾à¬°à¬¾ ସହାୟତା " +"ପà­à¬°à¬¾à¬ªà­à¬¤ ନà­à¬¹à¬à¥¤" + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"SOCKSv5 ପà­à¬°à¬Ÿà­‹à¬•ଲ ପାଇଠବà­à­Ÿà¬¬à¬¹à¬¾à¬°à¬•ାରୀ ନାମ କିମà­à¬¬à¬¾ ପà­à¬°à¬¬à­‡à¬¶ ସଂକେତଟି ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼।" + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "ଭà­à¬² ଚାଳକନାମ କିମà­à¬¬à¬¾ ପà­à¬°à¬¬à­‡à¬¶ ସଂକେତ ହେତୠSOCKSv5 ବୈଧିକରଣ ବିଫଳ ହୋଇଛି।" + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "ହୋଷà­à¬Ÿà¬¨à¬¾à¬® '%s' ଟି SOCKSv5 ପà­à¬°à¬Ÿà­‹à¬•ଲ ପାଇଠଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ ସରà­à¬­à¬° ଅଜଣା ଠିକଣା ପà­à¬°à¬•ାର ବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରିଥାà¬à¥¤" + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "ଆଭà­à­Ÿà¬¨à­à¬¤à¬°à­€à¬£ SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ ସରà­à¬­à¬° ତà­à¬°à­à¬Ÿà¬¿à¥¤" + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 ସଂଯୋଗ ନିୟମାବଳୀ ଦà­à­±à¬¾à¬°à¬¾ ଅନà­à¬®à¬¤à¬¿ ପà­à¬°à¬¾à¬ªà­à¬¤ ନà­à¬¹à¬à¥¤" + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "ହୋଷà­à¬Ÿ SOCKSv5 ସରà­à¬­à¬° ମାଧà­à¬¯à¬®à¬°à­‡ ପହଞà­à¬šà¬¿à¬¹à­‡à¬¬ ନାହିà¬à¥¤" + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "ନେଟୱରà­à¬• SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ ମାଧà­à¬¯à¬®à¬°à­‡ ପହଞà­à¬šà¬¿ ହେବ ନାହିà¬à¥¤" + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "ସଂଯୋଗଟି SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ ମାଧà­à¬¯à¬®à¬°à­‡ ବାରଣ ହୋଇଛି।" + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ 'connect' ନିରà­à¬¦à­à¬¦à­‡à¬¶à¬•ୠସମରà­à¬¥à¬¨ କରେ ନାହିà¬à¥¤" + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ ଦିଆଯାଇଥିବା ଠିକଣା ପà­à¬°à¬•ାରକୠସମରà­à¬¥à¬¨ କରେନାହିà¬à¥¤" + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "ଅଜଣା SOCKSv5 ପà­à¬°à¬•à­à¬¸à¬¿ ତà­à¬°à­à¬Ÿà¬¿à¥¤" + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon ସାଙà­à¬•େତିକରଣର ସଂସà­à¬•ରଣ %dକୠନିୟନà­à¬¤à­à¬°à¬£ କରାଯାଇପାରିବ ନାହିà¬" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "କୌଣସି ବୈଧ ଠିକଣା ମିଳି ନାହିà¬" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' କୠବିପରିତ-ସମାଧାନ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "ଅନà­à¬°à­‹à¬§ କରାଯାଇଥିବା '%s' ପାଇଠକୌଣସି DNS ବିବରଣୀ ନାହିà¬" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "ଅସà­à¬¥à¬¾à­Ÿà­€ ଭାବରେ '%s' କୠସମାଧାନ କରିବାରେ ଅସମରà­à¬¥" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "'%s' କୠସମାଧାନ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿" + +#: ../gio/gtlscertificate.c:247 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-ସାଙà­à¬•େତିକ ବà­à­Ÿà¬•à­à¬¤à¬¿à¬—ତ କିକୠବିଶà­à¬³à¬·à¬£ କରିପାରିଲା ନାହିà¬à¥¤" + +#: ../gio/gtlscertificate.c:252 +msgid "No PEM-encoded private key found" +msgstr "କୌଣସି PEM-ସାଙà­à¬•େତିକ ବà­à­Ÿà¬•à­à¬¤à¬¿à¬—ତ କି ମିଳି ନାହିà¬" + +#: ../gio/gtlscertificate.c:262 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-ସାଙà­à¬•େତିକ ବà­à­Ÿà¬•à­à¬¤à¬¿à¬—ତ କିକୠବିଶà­à¬³à¬·à¬£ କରିପାରିଲା ନାହିà¬à¥¤" + +#: ../gio/gtlscertificate.c:287 +msgid "No PEM-encoded certificate found" +msgstr "କୌଣସି PEM-ସାଙà­à¬•େତିକ ପà­à¬°à¬®à¬¾à¬£à¬ªà¬¤à­à¬° ମିଳି ନାହିà¬" + +#: ../gio/gtlscertificate.c:296 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-ସାଙà­à¬•େତିକ ପà­à¬°à¬®à¬¾à¬£à¬ªà¬¤à­à¬°à¬•ୠବିଶà­à¬³à¬·à¬£ କରିପାରିଲା ନାହିà¬" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"ପà­à¬°à¬¬à­‡à¬¶à¬¾à¬¨à­à¬®à¬¤à¬¿ ବାରଣ ହେବା ପୂରà­à¬¬à¬°à­ ପà­à¬°à¬¬à­‡à¬¶ ସଂକେତକୠସଠିକ ଭାବରେ ଭରଣ କରିବା ପାଇଠà¬à¬¹à¬¾ " +"ହେଉଛି ଅନà­à¬¤à¬¿à¬® " +"ସà­à¬¯à­‹à¬—।" + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"ଭରଣ ହୋଇଥିବା ଅନେକ ପà­à¬°à¬¬à­‡à¬¶ ସଂକେତ ଭà­à¬² ଅଟେ, à¬à¬¬à¬‚ ଆପଣଙà­à¬•ର ପà­à¬°à¬¬à­‡à¬¶à¬¾à¬¨à­à¬®à¬¤à¬¿à¬•à­ à¬à¬¹à¬¾à¬ªà¬°à­‡ " +"ଅପରିବରà­à¬¤à­à¬¤à¬¨à­€à­Ÿ " +"କରିଦିଆଯିବ।" + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "ଦିଆଯାଇଥିବା ପà­à¬°à¬¬à­‡à¬¶ ସଂକେତଟି ଠିକ ନà­à¬¹à¬à¥¤" + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 ନିୟନà­à¬¤à­à¬°à¬£ ସନà­à¬¦à­‡à¬¶à¬•ୠଆଶାକରà­à¬…ଛି, %d ପାଇଲି" +msgstr[1] "1 ନିୟନà­à¬¤à­à¬°à¬£ ସନà­à¬¦à­‡à¬¶à¬•ୠଆଶାକରà­à¬…ଛି, %d ପାଇଲି" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "ସହାୟକ ତଥà­à­Ÿà¬° ଅପà­à¬°à¬¤à­à­Ÿà¬¾à¬¶à¬¿à¬¤ ପà­à¬°à¬•ାର" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "ଗୋଟିଠfd ଆଶାକରà­à¬…ଛି, କିନà­à¬¤à­ %d ପାଇଲି\n" +msgstr[1] "ଗୋଟିଠfd ଆଶାକରà­à¬…ଛି, କିନà­à¬¤à­ %d ପାଇଲି\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "ଅବୈଧ fd ଗà­à¬°à¬¹à¬£ କରିଛି" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "ଅଧିକାରଗà­à¬¡à¬¼à¬¿à¬•ୠପଠାଇବାରେ ତà­à¬°à­à¬Ÿà¬¿: " + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "ଯଦି SO_PASSCRED କୠସକେଟ ପାଇଠସକà­à¬°à¬¿à­Ÿ କରାଗଲେ ଯାଞà­à¬š ତà­à¬°à­à¬Ÿà¬¿ ହେବ: %s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED କୠସକà­à¬°à¬¿à­Ÿ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"ଅଧିକାର ଗà­à¬°à¬¹à¬£ ପାଇଠà¬à¬• ବାଇଟ ପଢ଼ିବାକୠଆଶାକରାଯାଇଥାଠକିନà­à¬¤à­ ଶୂନà­à­Ÿ ବାଇଟ ପଢ଼ିଥାà¬" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "ନିୟନà­à¬¤à­à¬°à¬£ ସନà­à¬¦à­‡à¬¶à¬•ୠଆଶାକରିନଥାà¬, %d ପାଇଲି" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED କୠନିଷà­à¬•à­à¬°à¬¿à­Ÿ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ଫାଇଲ ବରà­à¬£à­à¬£à¬¨à¬¾à¬•ାରୀରୠପଢିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ଫାଇଲ ବରà­à¬£à­à¬£à¬¨à¬¾à¬•ାରୀକୠବନà­à¬¦ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gunixmounts.c:2066 ../gio/gunixmounts.c:2119 +msgid "Filesystem root" +msgstr "ଫାଇଲତନà­à¬¤à­à¬° ମୂଳସà­à¬¥à¬¾à¬¨" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ଫାଇଲ ନିରୂପକକୠଲେଖିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "ଅବà­à­Ÿà¬¬à¬¹à¬¾à¬°à¬¿à¬• UNIX ଡମେନ ସକେଟ ଠିକଣା à¬à¬¹à¬¿ ତନà­à¬¤à­à¬°à¬°à­‡ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "ଆକାର ବାହାର କରିବାକୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "ଆକାର ବାହାର କରିବା ଅଥବା eject_with_operation କୠକାରà­à¬¯à­à­Ÿà¬•ାରୀ କରେନାହିà¬" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "ପà­à¬°à­Ÿà­‹à¬—କୠଖୋଜିପାରିଲା ନାହିà¬" + +#: ../gio/gwin32appinfo.c:306 +#, c-format +msgid "Error launching application: %s" +msgstr "ପà­à¬°à­Ÿà­‹à¬—କୠଆରମà­à¬­à¬•ରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gwin32appinfo.c:342 +msgid "URIs not supported" +msgstr "URIଗà­à¬¡à¬¼à¬¿à¬• ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gwin32appinfo.c:364 +msgid "association changes not supported on win32" +msgstr "win32 ରେ ସଂସà­à¬¥à¬¾ ପରିବରà­à¬¤à­à¬¤à¬¨ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gwin32appinfo.c:376 +msgid "Association creation not supported on win32" +msgstr "win32 ରେ ସଂସà­à¬¥à¬¾ ନିରà­à¬®à¬¾à¬£ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "ନିୟନà­à¬¤à­à¬°à¬£à¬°à­ ପଢିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "ନିୟନà­à¬¤à­à¬°à¬£à¬•ୠବନà­à¬¦à¬•ରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "ନିୟନà­à¬¤à­à¬°à¬£à¬°à­‡ ଲେଖିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "ଯଥେଷà­à¬Ÿ ସà­à¬®à­ƒà¬¤à¬¿ ସà­à¬¥à¬¾à¬¨ ନାହିà¬" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "ଆଭà­à­Ÿà¬¨à­à¬¤à¬°à­€à¬£ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "ଅଧିକ ନିବେଶ ଆବଶà­à­Ÿà¬•" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "ଅବୈଧ ସଙà­à¬•ୋଚିତ ତଥà­à­Ÿ" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ଶà­à¬£à¬¿à¬¬à¬¾ ପାଇଠଠିକଣା" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "ଅଗà­à¬°à¬¾à¬¹à­à­Ÿ, GTestDbus ସହିତ ସନà­à¬¨à¬¿à¬¹à¬¿à¬¤" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "ଠିକଣାକୠମà­à¬¦à­à¬°à¬£ କରନà­à¬¤à­" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "ସେଲ ଧାରାରେ ଠିକଣାକୠମà­à¬¦à­à¬°à¬£ କରନà­à¬¤à­" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "à¬à¬• dbus ସରà­à¬­à¬¿à¬¸à¬•ୠଚଲାନà­à¬¤à­" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "ଭà­à¬² ସà­à­±à¬¤à¬¨à­à¬¤à­à¬°à¬šà¬°à¬—à­à¬¡à¬¼à¬¿à¬•\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "'%s' ର ଗà­à¬£ '%s' ଉପାଦାନ ପାଇଠଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଅଟେ" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' ଗà­à¬£à¬•à­ '%s' ଉପାଦାନ ପାଇଠଖୋଜି ପାରିଲା ନାହିà¬" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ '%s' ସୂଚକ, '%s' ସୂଚକକୠଆଶା କରାଯାଉଥିଲା" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ '%s' ସୂଚକଟି '%s' ମଧà­à¬¯à¬°à­‡ ଅଛି" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "ତଥà­à¬¯ ଡିରେକà­à¬Ÿà­‹à¬°à¬¿ ମାନଙà­à¬•ରେ କୌଣସି ବୈଧ ଚିହà­à¬¨à¬¿à¬¤ ସà­à¬¥à¬¾à¬¨ ମିଳିଲା ନାହିà¬" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "'%s' URI ପାଇଠଗୋଟିଠବà­à¬•ୠମାରà­à¬• ପୂରà­à¬¬à¬°à­ ଅବସà­à¬¥à¬¿à¬¤ ଅଛି" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "'%s' à­Ÿà­.ଆର.ଆଇ. ପାଇଠକୌଣସି ବà­à¬•ୠମାରà­à¬• ମିଳିଲା ନାହିà¬" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" +"'%s' à­Ÿà­.ଆର.ଆଇ. ପାଇଠବà­à¬•ୠମାରà­à¬•ରେ କୌଣସି MIME ପà­à¬°à¬•ାରକୠବà­à¬¯à¬¾à¬–à­à¬¯à¬¾ କରାଯାଇ ନାହିà¬" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" +"'%s' à­Ÿà­.ଆର.ଆଇ. ପାଇଠବà­à¬•ୠମାରà­à¬•ରେ କୌଣସି ଗà­à¬ªà­à¬¤ ଚିହà­à¬¨à¬•କୠବà­à¬¯à¬¾à¬–à­à¬¯à¬¾ କରାଯାଇ ନାହିà¬" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "'%s' à­Ÿà­.ଆର.ଆଇ. ପାଇଠବà­à¬•ୠମାରà­à¬•ରେ କୈଣସି ସମୂହକୠସେଟ କରାଯାଇ ନାହିà¬" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" +"'%s' ନାମରେ ନାମିତ କୌଣସି ପà­à¬°à­Ÿà­‹à¬— '%s' ପାଇଠଗୋଟିଠବà­à¬•ୠମାରà­à¬•କୠପଞà­à¬œà¬¿à¬•à­à¬°à­à¬¤ କରିନାହିà¬" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "'%s' à­Ÿà­.ଆର.ଆଇ. ସହିତ '%s' ନିଷà­à¬ªà¬¾à¬¦à¬¨ ଧାଡିକୠବରà­à¬¦à­à¬§à¬¨ କରିବାରେ ବିଫଳ" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "ନିବେଶର ସମାପà­à¬¤à¬¿à¬°à­‡ ଆଶିଂକ ଅକà­à¬·à¬° ଅନà­à¬•à­à¬°à¬®" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "'%s' ସହାୟକକୠସଂକେତ '%s' ସେଟୠରେ ରà­à¬ªà¬¾à¬¨à­à¬¤à¬°à¬¿à¬¤ କରିହେଲା ନାହିà¬" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" +"'%s' à­Ÿà­.ଆରà­.ଆଇ. \"ଫାଇଲ\" ଯୋଜନାକୠବà­à¬¯à¬¬à¬¹à¬¾à¬° କରà­à¬¥à¬¿à¬¬à¬¾ ଗୋଟିଠସମà­à¬ªà­‚ରà­à¬£à­à¬£ à­Ÿà­.ଆରà­.ଆଇ. " +"ନà­à¬¹à­‡à¬" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "'%s' ସà­à¬¥à¬¾à¬¨à­€à­Ÿ ଫାଇଲ à­Ÿà­.ଆରà­.ଆଇ. '#' ଚିହà­à¬¨à¬•ୠସମà­à¬®à¬¿à¬³à¬¿à¬¤ କରିପାରିବ ନାହିà¬" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "'%s' à­Ÿà­.ଆରà­.ଆଇ. ଅବୈଧ ଅଟେ" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "'%s' à­Ÿà­.ଆରà­.ଆଇ.ର ଆଧାର ନାମ ଅବୈଧ ଅଟେ" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "'%s' à­Ÿà­.ଆରà­.ଆଇ.ରେ ଅବୈଧ à¬à¬¸à­à¬•େପୠଅକà­à¬·à¬° ରହିଛି" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s' ପଥ ନାମ à¬à¬• ସମà­à¬ªà­‚ରà­à¬£à­à¬£ ପଥ ନà­à¬¹à­‡à¬" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "ଅବୈଧ ଆଧାର ନାମ" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Oe %B %Oy %OI:%OM:%OS %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%Od-%Om-%Oy" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%OI:%OM:%OS %p" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%OI:%OM:%OS %p" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "ଜାନà­à¬†à¬°à­€" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "ଫେବୃଆରୀ" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "ମାରà­à¬šà­à¬š" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "ଅପà­à¬°à­‡à¬²" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "ମଇ" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "ଜà­à¬¨" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "ଜà­à¬²à¬¾à¬‡" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "ଅଗଷà­à¬Ÿ" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "ସେପଟେମà­à¬¬à¬°" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "ଅକà­à¬Ÿà­‹à¬¬à¬°" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "ନଭେମà­à¬¬à¬°" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "ଡିସେମà­à¬¬à¬°" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ଜାନà­à­Ÿà¬¾à¬°à­€" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ଫେବୃଯାରୀ" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "ମାରà­à¬šà­à¬š" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "ଅପà­à¬°à­‡à¬²" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "ମେ" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ଜà­à¬¨" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ଜà­à¬²à¬¾à¬‡" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ଅଗଷà­à¬Ÿ" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "ସେପଟେମà­à¬¬à¬°" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "ଅକà­à¬Ÿà­‹à¬¬à¬°" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ନଭେମà­à¬¬à¬°" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ଡିସେମà­à¬¬à¬°" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "ସୋମବାର" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "ମଙà­à¬—ଳବାର" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "ବà­à¬§à¬¬à¬¾à¬°" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ଗà­à¬°à­à¬¬à¬¾à¬°" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "ଶà­à¬•à­à¬°à¬¬à¬¾à¬°" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "ଶନିବାର" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ରବିବାର" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ସୋମ" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ମଙà­à¬—ଳ" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ବà­à¬§" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ଗà­à¬°à­" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ଶà­à¬•à­à¬°" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ଶନି" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ରବି" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "%s' ଡିରେକà­à¬Ÿà­‹à¬°à¬¿ ଖୋଲିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "%lu ବାଇଟà­â€Œà¬•à­ \"%s\" ଫାଇଲ ପଢିବା ପାଇଠବାଣà­à¬Ÿà¬¿à¬¹à­‡à¬²à¬¾ ନାହିà¬" +msgstr[1] "%lu ବାଇଟà­â€Œà¬•à­ \"%s\" ଫାଇଲ ପଢିବା ପାଇଠବାଣà­à¬Ÿà¬¿à¬¹à­‡à¬²à¬¾ ନାହିà¬" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' ଫାଇଲ ପଢିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "ଫାଇଲ \"%s\" ଟି ଅତà­à¬¯à¬§à¬¿à¬• ବଡ଼" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' ଫାଇଲ ପଢିବାରେ ଅସଫଳ: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' ଫାଇଲ ଖୋଲିବାରେ ଅସଫଳ: %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' ଫାଇଲର ଗà­à¬£ ପାଇବାରେ ଅସଫଳ: fstat() ଅସଫଳ: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' ଫାଇଲ ଖୋଲିବାରେ ଅସଫଳ: fdopen() ଅସଫଳ: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "'%s' ଫାଇଲ ରୠ'%s' ନାମ ବଦଳାଇ ବାରେ ଅସଫଳ: g_rename() ଅସଫଳ: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' ଫାଇଲ ସà­à¬°à­à¬·à­à¬Ÿà¬¿ କରିବାରେ ଅସଫଳ: %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "'%s' ଫାଇଲ ଖୋଲିବାରେ ଅସଫଳ: write() ବିଫଳ ହୋଇଛି: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' ଫାଇଲ ଖୋଲିବାରେ ଅସଫଳ: fsync() ଅସଫଳ: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "ଅବସà­à¬¥à¬¿à¬¤ '%s' ଫାଇଲ କାଢି ହେଲା ନାହିà¬: g_unlink ଅସଫଳ %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "'%s' ନମà­à¬¨à¬¾ ଟି ଅବୈଧ ଅଟେ, '%s' ଧାରଣ କରିବା ଉଚିତ ନà­à¬¹à­‡à¬" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "'%s' ନମà­à¬¨à¬¾ ଟି XXXXXXକୠଧାରଣ କରିନାହିà¬" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "'%s' ପà­à¬°à¬¤à¬¿à¬•ାତà­à¬®à¬• ସଂୟୋଗ ପଢିବାରେ ଅସଫଳ: %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "ପà­à¬°à¬¤à¬¿à¬•ାତà­à¬®à¬• ସଂୟୋଗ ଅସହାୟକ" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "%s' ରୠ'%s' ର ରà­à¬ªà¬¾à¬¨à­à¬¤à¬°à¬• ଖୋଲି ପାରିଲା ନାହିà¬: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string ରେ ଅଂସସାଧିତ ପଠନ କରିହେଲା ନାହିà¬" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "ପଠନ ବଫରରେ ଅରୂପାନà­à¬¤à¬°à¬¿à¬¤ ତଥà­à¬¯ ବଳକା ଅଛି" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "ଆଂଶିକ ଅକà­à¬·à¬° ରେ ଚାନେଲର ସମାପà­à¬¤à¬¿" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end ରେ ଅଂସସାଧିତ ପଠନ କରିହେଲା ନାହିà¬" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "ଅନà­à¬¸à¬¨à­à¬§à¬¾à¬¨ ଡିରେକà­à¬Ÿà­‹à¬°à¬¿ ମାନଙà­à¬•ରେ ବୈଧ ଚାବି ଫାଇଲ ମିଳିଲା ନାହିà¬" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "à¬à¬¹à¬¾ à¬à¬• ନିୟମିତ ଫାଇଲ ନà­à¬¹à­‡à¬" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"ମà­à¬–à­à¬¯ ଫାଇଲ '%s' କୠଧାରଣ କରିଛି ଯାହାକି ଗୋଟିଠମà­à¬–à­à¬¯-ଗà­à¬£ ର ଯୋଡି, ସମୂହ, କିମà­à¬¬à¬¾ " +"ବାକà­à¬¯ ନà­à¬¹à­‡à¬" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "ଅବୈଧ ସମୂହ ନାମ: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "ମୂଖà­à¬¯ ଫାଇଲ କୌଣସି ସମୂହ ସହ ଆରମà­à¬­ ହà­à¬ ନାହିà¬" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "ଅବୈଧ ଚାବି ନାମ: %s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "ମୂଖà­à¬¯ ଫାଇଲ ଟି ଗୋଟିଠଅସହାୟକ ସଂକେତ '%s' ଧାରଣ କରିଛି" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1692 ../glib/gkeyfile.c:3072 +#: ../glib/gkeyfile.c:3138 ../glib/gkeyfile.c:3264 ../glib/gkeyfile.c:3397 +#: ../glib/gkeyfile.c:3539 ../glib/gkeyfile.c:3768 ../glib/gkeyfile.c:3835 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "ମୂଖà­à¬¯ ଫାଇଲ ରେ '%s' ନାମ ଥିବା କୌଣସି ସମୂହ ନାହିà¬" + +#: ../glib/gkeyfile.c:1704 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "ମୂଖà­à¬¯ ଫାଇଲ ରେ '%s' ନାମ ଥିବା କୌଣସି ଚାବିକାଠି ନାହିà¬" + +#: ../glib/gkeyfile.c:1811 ../glib/gkeyfile.c:1927 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"ମୂଖà­à¬¯ ଫାଇଲ ଧାରଣ କରିଥିବା '%s' ଚାବିକାଠି ର ମୂଲà­à¬¯ '%s' ଅଟେ, ଯାହାକି ଇଉ-ଟି-à¬à¬«à­-à­® " +"ନà­à¬¹à­‡à¬" + +#: ../glib/gkeyfile.c:1831 ../glib/gkeyfile.c:1947 ../glib/gkeyfile.c:2316 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "ମୂଖà­à¬¯ ଫାଇଲ ଧାରଣ କରିଥିବା '%s' ଚାବିକାଠି ର ମୂଲà­à¬¯ ନିରୂପଣ କରିହେବ ନାହିà¬" + +#: ../glib/gkeyfile.c:2533 ../glib/gkeyfile.c:2901 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"ମୂଖà­à¬¯ ଫାଇଲ ଧାରଣ କରିଥିବା '%s' ଚାବିକାଠି ଗୋଟିଠ'%s' ସମୂହ ସହିତ ଅଛି ଯାହାର ମୂଲà­à¬¯ " +"ନିରୂପଣ କରିହେବ " +"ନାହିà¬à¥¤" + +#: ../glib/gkeyfile.c:2611 ../glib/gkeyfile.c:2688 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" +"କି '%s' ଯାହା ସମୂହ '%s' ରେ ଅଛି ତାହାର ମୂଲà­à­Ÿ '%s' ଯେଉà¬à¬ à¬¿ %s କୠଆଶାକରାଯାଇଥିଲା" + +#: ../glib/gkeyfile.c:3087 ../glib/gkeyfile.c:3279 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "ମୂଖà­à¬¯ ଫାଇଲ େର '%s' ନାମ ଥିବା କୌଣସି ଚାବିକାଠି '%s' ସମୂହ ରେ ନାହିଠ" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "ମୂଖà­à¬¯ ଫାଇଲ ଟି ଲାଇନୠର ସମାପà­à¬¤à¬¿ ରେ à¬à¬¸à­à¬•େପୠଅକà­à¬·à¬° ଧାରଣ କରିଛି" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "ମୂଖà­à¬¯ ଫାଇଲ '%s' ଅବୈଧ à¬à¬¸à­à¬•େପୠଅକà­à¬·à¬° ଧାରଣ କରିଛି" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "'%s' ର ମୂଲà­à¬¯ ଗୋଟିଠସଂଖà­à¬¯à¬¾ ଭାବରେ ନିରୂପଣ କରିହେବ ନାହିà¬" + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "ପୂରà­à¬£ ମୂଲà­à¬¯ '%s' ପରିସର ର ବାହାରେ ଅଛି" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "'%s' ମୂଲà­à¬¯à¬•ୠଗୋଟିଠଭାସମାନ ସଂଖà­à¬¯à¬¾ ଭାବରେ ବà­à¬¯à¬¾à¬–à­à¬¯à¬¾ କରିହେବ ନାହିà¬" + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "'%s' ର ମୂଲà­à¬¯ ଗୋଟିଠବà­à¬²à¬¿à¬†à¬¨à­ ଭାବରେ ନିରୂପଣ କରିହେବ ନାହିà¬" + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "'%s%s%s%s' ଫାଇଲର ଗà­à¬£ ପାଇବାରେ ଅସଫଳ: fstat() ଅସଫଳ: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s ଫାଇଲ କୠମେଳାଇବାରେ ଅସଫଳ: mmap() ଅସଫଳ: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "'%s' ଫାଇଲ ଖୋଲିବାରେ ଅସଫଳ: open() ଅସଫଳ: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "ଧାଡ଼ି %dର ଅକà­à¬·à¬° %dରେ ତà­à¬°à­à¬Ÿà¬¿: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "ନାମରେ ଅବୈଧ UTF-8 ସାଙà­à¬•େତିକ ପାଠà­à¬¯- '%s' ବୈଧ ନà­à¬¹à¬" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' ଟି ଗୋଟିଠବୈଧ ନାମ ନà­à¬¹à¬" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' ଟି ଗୋଟିଠବୈଧ ନାମ ନà­à¬¹à¬: '%c'" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d ଧାଡ଼ିରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s' କୠବିଶà­à¬³à­‡à¬·à¬£ କରିବାରେ ଅସଫଳ, ଯାହାକି ଗୋଟିଠଅକà­à¬·à¬° ରେଫରେନà­à¬¸ ମଦà­à¬§à­à¬¯à¬°à­‡ à¬à¬• " +"ଅଙà­à¬• ହେବା ଉଚିତ " +"ଥିଲା(ଉଦାହରଣ ସà­à¬¬à¬°à­‚ପେ &#୨୩୪;) - ବୋଧହà­à¬ ଅଙà­à¬•ଟି ବହà­à¬¤ ବଡ଼ ଅଟେ" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"ଅକà­à¬·à¬° ରେଫରେନà­à¬¸ ସେମିକୋଲନରେ ସମାପà­à¬¤ ହେଉ ନାହିà¬; ସମà­à¬­à¬¬à¬¤à¬ƒ ଆପଣ ଗୋଟିଠବସà­à¬¤à­ ଆରମà­à¬­ " +"କରିବାକୠନ ଚାହିà¬, " +"à¬à¬• ଆମà­à¬ªà¬°à­à¬¸à­‡à¬£à­à¬¡à­ ଅକà­à¬·à¬° ବà­à¬¯à¬¬à¬¹à¬¾à¬° କରିଛନà­à¬¤à¬¿ - ତାହାକୠ& ଭାବରେ à¬à¬¸à­à¬•େପୠକରନà­à¬¤à­" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "'%-.*s' ଅକà­à¬·à¬° ରେଫରେନà­à¬¸ ଟି ଗୋଟିଠଅନà­à¬®à¬¤ ଅକà­à¬·à¬°à¬•ୠସଙà­à¬•େତ କରୠନାହିà¬" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"ଖାଲି ବସà­à¬¤à­ '&;' ଦେଖା ଗଲା; ବୈଧ ବସà­à¬¤à­à¬—à­à¬¡à¬¼à¬¿à¬• ହେଲା: & " < > '" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "ବସà­à¬¤à­ ନାମ '%-.*s' ଜଣା ନାହିà¬" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"ବସà­à¬¤à­à¬Ÿà¬¿ ସେମିକୋଲନରେ ଶେଷ ହେଲା ନାହିà¬; ସମà­à¬­à¬¬à¬¤à¬ƒ ଆପଣ ଗୋଟିଠବସà­à¬¤à­ ଆରମà­à¬­ କରିବାକୠନ " +"ଚାହିà¬, à¬à¬• " +"ଆମà­à¬ªà¬°à­à¬¸à­‡à¬£à­à¬¡à­ ଅକà­à¬·à¬° ବà­à¬¯à¬¬à¬¹à¬¾à¬° କରିଛନà­à¬¤à¬¿ - ତାହାକୠ& ଭାବରେ à¬à¬¸à­à¬•େପୠକରନà­à¬¤à­" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "ଦଲିଲ ଗୋଟିଠଉପାଦାନରେ ଆରମà­à¬­ ହେବା ଉଚିତ (ଉଦାହରଣ ସà­à¬¬à¬°à­‚ପ )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'<' ଅକà­à¬·à¬° ପଛରେ ଆସà­à¬¥à¬¿à¬¬à¬¾ '%s' ଅକà­à¬·à¬° ବୈଧ ନà­à¬¹à­‡à¬; à¬à¬¹à¬¾ ଗୋଟିଠବସà­à¬¤à­à¬° ନାମକୠଆରମà­à¬­ " +"କରିପାରିବ ନାହିà¬" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"ଅଯà­à¬—à­à¬® ସଂଖà­à­Ÿà¬¾ '%s', ଖାଲି-ଉପାଦାନ ଟà­à­Ÿà¬¾à¬— '%s' ପà­à¬°à¬¾à¬°à¬®à­à¬­ ସୂଚକକୠସମାପà­à¬¤ କରିବା ପାଇଠ" +"'>' ଅକà­à¬·à¬° " +"ଆଶାକରାଯାଉଥିଲା" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"ବିଚିତà­à¬° ଅକà­à¬·à¬° '%1$s', '%3$s' ଉପାଦାନର ଗୋଟିଠଗà­à¬£à¬° ନାମ '%2$s' ପରେ '=' ପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ " +"ଥିଲା" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ବିଚିତà­à¬° ଅକà­à¬·à¬° '%s', '%s' ଉପାଦାନର ପà­à¬°à¬¾à¬°à¬®à­à¬­ ସୂଚକକୠସମାପà­à¬¤ କରିବା ପାଇଠ'>' ବା " +"'/' ଅକà­à¬·à¬° " +"ପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଥିଲା, ଅଥବା ଇଚà­à¬›à¬¾à¬§à­€à¬¨ ଭାବରେ ଗୋଟିଠଗà­à¬£; ବୋଧହà­à¬ ଆପଣ ଗୋଟିଠଗà­à¬£à¬° ନାମରେ " +"à¬à¬• ଅବୈଧ " +"ଅକà­à¬·à¬° ବà­à¬¯à¬¬à¬¹à¬¾à¬° କରିଛନà­à¬¤à¬¿" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"ବିଚିତà­à¬° ଅକà­à¬·à¬° '%1$s', ସମାନ ଚିହà­à¬¨ ପରେ '%3$s' ଉପାଦାନର '%2$s' ଗà­à¬£à¬° ମୂଲà­à¬¯ ଦେବା " +"ପାଇଠଗୋଟିଠ" +"ଖୋଲା ଉଦà­à¬§à­à¬°à­à¬¤à¬¿ ଚିହà­à¬¨ ପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଥିଲା" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"ବନà­à¬¦ ଉପାଦାନ ନାମ '%2$s' ପଛରେ ଆସà­à¬¥à¬¿à¬¬à¬¾ '%1$s' ଅକà­à¬·à¬° ବୈଧ ନà­à¬¹à­‡à¬; ଅନà­à¬®à¬¤ ଅକà­à¬·à¬° ହେଲା " +"'>'" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "ଉପାଦାନ '%s' ବନà­à¬¦ କରାଯାଇଥିଲା, ବରà­à¬¤à­à¬¤à¬®à¬¾à¬¨ କୌଣସି ଉପାଦାନ ଖୋଲା ନାହିà¬" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "ଉପାଦାନ '%s' ବନà­à¬¦ କରାଯାଇଥିଲା, କିନà­à¬¤à­ ବରà­à¬¤à­à¬¤à¬®à¬¾à¬¨ '%s' ଉପାଦାନଟି ଖୋଲା ଅଛି" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "ଦଲିଲ ଖାଲି ଥିଲା ବା କେବଳ ଖାଲି ଯାଗା ଧାରଣ କରିଥିଲା" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"ଦଲିଲଟି ଗୋଟିଠକୌଣିକ ବନà­à¬§à¬¨à­€ '<'ର ଠିକ ପରେ ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"ଉପାଦାନଗà­à¬¡à¬¼à¬¿à¬• ଖୋଲା ଥାଇ ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା'%s' ଉପାଦାନ " +"ସରà­à¬¬à¬¶à­‡à¬· ଖୋଲା " +"ଥିଲା" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା, <%s/> ସୂଚକ ସମାପà­à¬¤ କରିବା ପାଇଠଗୋଟିଠ" +"ବନà­à¬¦ କୌଣିକ " +"ବନà­à¬§à¬¨à­€ ପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଥିଲା" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "ଉପାଦାନର ନାମ ମଧà­à¬¯à¬°à­‡ ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "ଗà­à¬£à¬° ନାମ ମଧà­à¬¯à¬°à­‡ ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ଉପାଦାନ ଆରମà­à¬­à¬° ସୂଚକ ମଧà­à¬¯à¬°à­‡ ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା" + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"ଗà­à¬£à¬° ନାମ ପଛରେ ଆସà­à¬¥à¬¿à¬¬à¬¾ ସମାନ ଚିହà­à¬¨ ପରେ ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା; " +"ଗà­à¬£à¬° କିଛି " +"ମୂଲà­à¬¯ ନାହିà¬" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ଗà­à¬£à¬° ମୂଲà­à¬¯ ମଧà­à¬¯à¬°à­‡ ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "'%s' ଉପାଦାନର ବନà­à¬¦ ସୂଚକ ମଧà­à¬¯à¬°à­‡ ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "ଟିପà­à¬ªà¬£à­€ ବା ସଂସାଧନ ସାଧନ ମଧà­à¬¯à¬°à­‡ ଦଲିଲଟି ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ଭାବରେ ସମାପà­à¬¤ ହୋଇ ଗଲା" + +#: ../glib/goption.c:795 +msgid "Usage:" +msgstr "ବà­à¬¯à¬¬à¬¹à¬¾à¬°:" + +#: ../glib/goption.c:795 +msgid "[OPTION...]" +msgstr "[ପସନà­à¬¦...]" + +#: ../glib/goption.c:911 +msgid "Help Options:" +msgstr "ସାହାଯà­à¬¯ ପସନà­à¬¦" + +#: ../glib/goption.c:912 +msgid "Show help options" +msgstr "ସାହାଯà­à¬¯ ପସନà­à¬¦ ଦେଖାନà­à¬¤à­" + +#: ../glib/goption.c:918 +msgid "Show all help options" +msgstr "ସବୠସାହାଯà­à¬¯ ପସନà­à¬¦ ଦେଖାନà­à¬¤à­" + +#: ../glib/goption.c:980 +msgid "Application Options:" +msgstr "ପà­à¬°à­Ÿà­‹à¬— ପସନà­à¬¦" + +#: ../glib/goption.c:1044 ../glib/goption.c:1114 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "%s ପାଇଠପୂରà­à¬£ ସଂଖà­à¬¯à¬¾ ମୂଲà­à¬¯ '%s' କୠବିଶà­à¬²à­‡à¬·à¬¿à¬£ କରିହେଲା ନାହିà¬" + +#: ../glib/goption.c:1054 ../glib/goption.c:1122 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%s ପାଇଠପୂରà­à¬£ ସଂଖà­à¬¯à¬¾ '%s' ର ମୂଲà­à¬¯ ପରିସର ବାହାରେ" + +#: ../glib/goption.c:1079 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "'%s' ଦà­à¬¬à­à¬¯à¬°à­à¬¥à¬• ମୂଲà­à¬¯à¬•à­ %s ପାଇଠବିଶà­à¬³à­‡à¬·à¬¿à¬¤ କରିପାରିଲା ନାହିà¬" + +#: ../glib/goption.c:1087 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "'%s' ଦà­à¬¬à­à¬¯à¬°à­à¬¥à¬• ମୂଲà­à¬¯à¬Ÿà¬¿ %s ପାଇଠପରିସରର ବହିରà­à¬­à­‚ତ।" + +#: ../glib/goption.c:1373 ../glib/goption.c:1452 +#, c-format +msgid "Error parsing option %s" +msgstr "ରà­à¬ªà¬¾à¬¨à­à¬¤à¬°à¬£ ର ବିକଲà­à¬ª ରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#: ../glib/goption.c:1483 ../glib/goption.c:1596 +#, c-format +msgid "Missing argument for %s" +msgstr "%s ପାଇଠସà­à¬¬à¬¤à¬¨à­à¬¤à­à¬°à¬šà¬° ଟି ହଜି ଯାଇଛି" + +#: ../glib/goption.c:2057 +#, c-format +msgid "Unknown option %s" +msgstr "ଅଜଣା ପସନà­à¬¦ %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "ଭà­à¬°à¬·à­à¬Ÿ ବସà­à¬¤à­" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "ଆଭà­à¬¯à¬¨à­à¬¤à¬°à­€à¬£ ତୃଟି କିମà­à¬¬à¬¾ ଭà­à¬°à¬·à­à¬Ÿ ବସà­à¬¤à­" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "ସà­à¬®à­ƒà¬¤à¬¿ ପରିସର ବାହାରେ" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "ପଶà­à¬šà¬¾à¬¤ ଅନà­à¬®à¬¾à¬°à­à¬—ଣ ସୀମା ପହଞà­à¬šà¬¿ ଯାଇଛି" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "à¬à¬¹à¬¿ ଶୈଳୀ ଆଂଶିକ ମେଳନ ପାଇଠସମରà­à¬¥à¬¿à¬¤ ନ ଥିବା ବସà­à¬¤à­ ମାନଙà­à¬•ୠଧାରଣ କରିଥାà¬" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "ଆଂଶିକ ମେଳନ ପାଇଠସରà­à¬¤à­à¬¤ ରୂପରେ ପଶà­à¬šà¬¾à¬¤ ନିରà­à¬¦à­à¬¦à­‡à¬¶ ମାନ ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬à¬¨à­à¬¤à¬¿" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "ପà­à¬¨à¬°à¬¾à¬¬à¬°à­à¬¤à­à¬¤à¬¨ ସୀମା ପହଞà­à¬šà¬¿à¬¯à¬¾à¬‡à¬›à¬¿" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "ନୂତନ ଧାଡି ପତାକା ମାନଙà­à¬• ପାଇଠଅବୈଧ ମିଶà­à¬°à¬£" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "ଖରାପ ଅଫସେଟ" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "ସଂକà­à¬·à¬¿à¬ªà­à¬¤ utf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "ପà­à¬¨à¬ƒà¬ªà­Œà¬®à¬¿à¬• ଲà­à¬ª" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "ଅଜଣା ତୃଟି" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ ନମà­à¬¨à¬¾ ଶେଷରେ" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c ନମà­à¬¨à¬¾ ଶେଷରେ" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "ନିମà­à¬¨à¬²à¬¿à¬–ିତ ପରେ ଅଚିହà­à¬¨à¬¾ ଅକà­à¬·à¬°\\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} ପରିମାଣକ ରେ ସଂଖà­à­Ÿà¬¾à¬—à­à¬¡à¬¼à¬¿à¬• କà­à¬°à¬®à¬°à­‡ ନାହିà¬" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} ପରିମାଣକ ରେ ସଂଖà­à­Ÿà¬¾à¬Ÿà¬¿ ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "ବରà­à¬£à­à¬£ ଶà­à¬°à­‡à¬£à­€ ପାଇଠସମାପà­à¬¤à¬¿ ] ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤ ଅଛି" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "ବରà­à¬£à­à¬£ ଶà­à¬°à­‡à¬£à­€à¬°à­‡ ଅବୈଧ ନିକାସ ଅନà­à¬•à­à¬°à¬®" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "ବରà­à¬£à­à¬£ ଶà­à¬°à­‡à¬£à­€à¬°à­‡ ପରିସର ଅବà­à­Ÿà¬¬à¬¸à­à¬¥à¬¿à¬¤" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "ପà­à¬¨à¬°à¬¾à¬¬à¬°à­à¬¤à­à¬¤à¬¨ ପାଇଠକିଛି ନାହିà¬" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "ଅପà­à¬°à¬¤à­à­Ÿà¬¾à¬¶à¬¿à¬¤ ପà­à¬¨à¬°à¬¾à¬¬à­ƒà¬¤à­à¬¤à¬¿" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? କିମà­à¬¬à¬¾ (?- ପରେ ଅଚିହà­à¬¨à¬¾ ଅକà­à¬·à¬°" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX ନାମିତ ଶà­à¬°à­‡à¬£à­€à¬—à­à¬¡à¬¼à¬¿à¬• କେବଳ ଗୋଟିଠଶà­à¬°à­‡à¬£à­€ ମଧà­à¬¯à¬°à­‡ ସମରà­à¬¥à¬¿à¬¤" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "ସମାପà­à¬¤à¬•ାରୀ ) ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "ଅସà­à¬¤à¬¿à¬¤à­à­± ନଥିବା ଉପନମà­à¬¨à¬¾à¬° ସନà­à¬¦à¬°à­à¬­" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "ଟିପà­à¬ªà¬£à­€ ପରେ ) ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "ନିୟମିତ ପରିପà­à¬°à¬•ାଶଟି ଅତà­à¬¯à¬§à¬¿à¬• ବଡ଼" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "ସà­à¬®à­ƒà¬¤à¬¿à¬¸à­à¬¥à¬¾à¬¨ ପାଇବାରେ ବିଫଳ" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") ଆରମà­à¬­ ବିନା (" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "ସଂକେତ ଅତିପà­à¬°à¬¬à¬¾à¬¹" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "(?< ପରେ ଅଚିହà­à¬¨à¬¾ ଅକà­à¬·à¬°" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "ପଛକୠଦେଖି ନିଶà­à¬šà¬¿à¬¤à¬•ରଣର ସà­à¬¥à¬¾à­Ÿà­€ ଆକାର ନଥାà¬" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "ବିକୃତ ସଂଖà­à­Ÿà¬¾ କିମà­à¬¬à¬¾ (?( ପରେଥିବା ନାମ" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "ପà­à¬°à¬¤à¬¿à¬¬à¬¨à­à¬§à¬¿à¬¤ ଶà­à¬°à­‡à¬£à­€ ଦà­à¬‡à¬°à­ ଅଧିକ ଶାଖା ଧାରଣ କରିଥାà¬" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "(?( ପରେ ନିଶà­à¬šà¬¿à¬¤à¬•ରଣ ଆବଶà­à­Ÿà¬•" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R କିମà­à¬¬à¬¾ (?[+-]ଅଙà­à¬•ଗà­à¬¡à¬¼à¬¿à¬• ନିଶà­à¬šà¬¿à¬¤à¬°à­‚ପେ ) ପରେ ଆସିବା ଉଚିତ" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "ଅଜଣା POSIX ଶà­à¬°à­‡à¬£à­€ ନାମ" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "POSIX ସଂକଳନ ଉପାଦାନଗà­à¬¡à¬¼à¬¿à¬• ସମରà­à¬¥à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} ଅନà­à¬•à­à¬°à¬®à¬°à­‡ ବରà­à¬£à­à¬£à¬° ମୂଲà­à­Ÿ ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "ଅବୈଧ ସରà­à¬¤à­à¬¤ (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "ପଛକୠଦେଖି ନିଶà­à¬šà¬¿à¬¤à¬•ରଣରେ \\C ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "\\L, \\l, \\N{name}, \\U, à¬à¬¬à¬‚ \\u ଗà­à¬¡à¬¼à¬¿à¬• ସହାୟତା ପà­à¬°à¬¾à¬ªà­à¬¤ ନà­à¬¹à¬" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "ପà­à¬¨à¬°à¬¾à¬¬à¬°à­à¬¤à­à¬¤à­€ ଡାକରା ଅନିରà­à¬¦à­à¬§à¬¿à¬·à­à¬Ÿ କାଳପାଇଠଚକà­à¬° ସୃଷà­à¬Ÿà¬¿à¬•ରିପାରେ" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "(?P ପରେ ଅଚିହà­à¬¨à¬¾ ଅକà­à¬·à¬°" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "ଉପନମà­à¬¨à¬¾ ନାମରେ ଅନà­à¬¤à¬• ନାହିà¬" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "ଦà­à¬‡à¬Ÿà¬¿ ନାମିତ ଉପନମà­à¬¨à¬¾à¬° à¬à¬•ା ନାମ ଅଛି" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "\\P କିମà­à¬¬à¬¾ \\p ଅନà­à¬•à­à¬°à¬®à¬Ÿà¬¿ ବିକୃତ ହୋଇଯାଇଛି" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "\\P କିମà­à¬¬à¬¾ \\p ପରେ ଅଜଣା ଗà­à¬£à¬§à¬°à­à¬® ନାମ" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ଉପଢ଼ାଞà­à¬šà¬¾ ନାମଟି ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼ (ସରà­à¬¬à¬¾à¬§à¬¿à¬• 32 ବରà­à¬£à­à¬£)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ଅତà­à­Ÿà¬§à¬¿à¬• ନାମିତ ଉପଢ଼ାଞà­à¬šà¬¾ (ସରà­à¬¬à¬¾à¬§à¬¿à¬• 10,000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "ଅଷà­à¬Ÿà¬®à¬¿à¬• ମୂଲà­à­Ÿà¬Ÿà¬¿ \\377 ଠାରୠବଡ଼" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "overran ସଙà­à¬•ଳନ କାରà­à¬¯à­à­Ÿà¬•à­à¬·à­‡à¬¤à­à¬°" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "ପୂରà­à¬¬à¬°à­ ଯାଞà­à¬šà¬•ରାଯାଇଥିବା ଉଲà­à¬²à­‡à¬–ିତ ଉପଢ଼ାଞà­à¬šà¬¾ ମିଳà­à¬¨à¬¾à¬¹à¬¿à¬" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE ଶà­à¬°à­‡à¬£à­€ à¬à¬•ାଧିକ ଶାଖା ଧାରଣ କରେ" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "ଅସଂଗତ NEWLINE ବିକଳà­à¬ªà¬—à­à¬¡à¬¼à¬¿à¬•" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ଟି ଗୋଟିଠଆବଦà­à¬§ ନାମ ପରେ କିମà­à¬¬à¬¾ ଇଚà­à¬›à¬¾à¬§à­€à¬¨ ଆବଦà­à¬§ ପୂରà­à¬£à­à¬£ ସଂଖà­à­Ÿà¬¾ ପରେ ନଥାà¬" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "à¬à¬• ସାଂଖିକ ସନà­à¬¦à¬°à­à¬­ ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ ଶୂନà­à­Ÿ ହୋଇନଥିବା ଉଚିତ" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" +"à¬à¬• ସà­à­±à¬¤à¬¨à­à¬¤à­à¬°à¬šà¬°à¬•à­ (*ACCEPT), (*FAIL), କିମà­à¬¬à¬¾ (*COMMIT) ପାଇଠଅନà­à¬®à¬¤à¬¿ ପà­à¬°à¬¾à¬ªà­à¬¤ ନà­à¬¹à¬" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) କୠଚିହà­à¬¨à¬¿à¬¹à­‡à¬¬ ନାହିà¬" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "ସଂଖà­à­Ÿà¬¾à¬Ÿà¬¿ ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& ପରେ ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤ ଉପନମà­à¬¨à¬¾ ନାମ" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ପରେ ଅଙà­à¬• ଆଶା କରାଯାଉଥିଲା" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] ଟି JavaScript ସà­à¬¸à¬™à­à¬—ତ ଧାରାରେ à¬à¬• ଅବୈଧ ତଥà­à­Ÿ ଅକà­à¬·à¬°" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ସମାନ ସଂଖà­à­Ÿà¬¾à¬° ଦà­à¬‡à¬Ÿà¬¿ ନାମିତ ଉପନମà­à¬¨à¬¾ ପାଇଠଭିନà­à¬¨ ନାମଗà­à¬¡à¬¼à¬¿à¬• ଅନà­à¬®à¬¤à¬¿ ପà­à¬°à¬¾à¬ªà­à¬¤" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) ରେ ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ à¬à¬• ସà­à­±à¬¤à¬¨à­à¬¤à­à¬°à¬šà¬° ଅଛି" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c ଟି ନିଶà­à¬šà¬¿à¬¤ ଭାବରେ à¬à¬• ASCII ଅକà­à¬·à¬° ପରେ ଥାà¬" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k କୠବନà­à¬§à¬¨à¬¿ ପରେ ରଖାାଇନଥାà¬, କୌଣ-ବନà­à¬§à¬¨à¬¿, ଅଥବା ଉଦà­à¬§à­ƒà¬¤ ନାମ" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N କୠà¬à¬• ଶà­à¬°à­‡à¬£à­€à¬°à­‡ ସହାୟତା ଦିଆଯାଇନଥାà¬" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "ଅତà­à­Ÿà¬§à¬¿à¬• ଆଗà­à¬† ସନà­à¬¦à¬°à­à¬­" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), ଅଥବା (*THEN) ରେ ନାମଟି ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... କà­à¬°à¬®à¬°à­‡ ଥିବା ଅକà­à¬·à¬° ମୂଲà­à­Ÿà¬Ÿà¬¿ ଅତà­à­Ÿà¬§à¬¿à¬• ବଡ଼" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "%s ନିୟମିତ ପରିପà­à¬°à¬•ାଶକୠମିଳାଇବା ସମୟରେ ତୃଟି: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE ଲାଇବà­à¬°à­‡à¬°à­€à¬•à­ UTF8 ସମରà­à¬¥à¬¨ ବିନା ସଙà­à¬•ଳନ କରାଯାଇଛି" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE ଲାଇବà­à¬°à­‡à¬°à­€à¬•à­ UTF8 ଗà­à¬£à¬§à¬°à­à¬® ସମରà­à¬¥à¬¨ ବିନା ସଙà­à¬•ଳନ କରାଯାଇଛି" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE ଲାଇବà­à¬°à­‡à¬°à­€à¬•ୠଅସଙà­à¬—ତ ବିକଳà­à¬ªà¬—à­à¬¡à¬¼à¬¿à¬• ସହିତ ସଙà­à¬•ଳନ କରାଯାଇଛି" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "%s ନିୟମିତ ପରିପà­à¬°à¬•ାଶକୠ%d ଅକà­à¬·à¬°à¬°à­‡ ସଙà­à¬•ଳନ କରିବା ସମୟରେ ତୃଟି: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "%s ନିୟମିତ ପରିପà­à¬°à¬•ାଶକୠଅନà­à¬•ୂଳତମ କରିବା ସମୟରେ ତୃଟି: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "ଷୋଡଶାଧାରୀ ଅଙà­à¬• କିମà­à¬¬à¬¾ '}' ଆଶା କରାଯାଉଥିଲା" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "ଷୋଡଶାଧାରୀ ଅଙà­à¬• ଆଶା କରାଯାଉଥିଲା" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "ପà­à¬°à¬¤à­€à¬•ାତà­à¬®à¬• ନିରà­à¬¦à­à¬¦à­‡à¬¶à¬°à­‡ '<' ଅନà­à¬ªà¬¸à­à¬¥à¬¿à¬¤" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "ଅସମାପà­à¬¤ ପà­à¬°à¬¤à­€à¬•ାତà­à¬®à¬• ନିରà­à¬¦à­à¬¦à­‡à¬¶" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "ଶୂନà­à¬¯ ଲମà­à¬¬ ବିଶିଷà­à¬Ÿ ପà­à¬°à¬¤à­€à¬•ାତà­à¬®à¬• ନିରà­à¬¦à­à¬¦à­‡à¬¶" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "ଅଙà­à¬• ଆଶା କରାଯାଉଥିଲା" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "ଅବୈଧ ପà­à¬°à¬¤à­€à¬•ାତà­à¬®à¬• ନିରà­à¬¦à­à¬¦à­‡à¬¶" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "ପଥଭà­à¬°à¬·à­à¬Ÿ ନିରà­à¬£à­à¬£à­Ÿ '\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "ଅଜଣା ପଳାୟନ ସଂପà­à¬°à¬¤à­€à¬•" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "ପରିବରà­à¬¤à­à¬¤à¬¿à¬¤ ପାଠà­à¬¯ \"%s\" ର %lu ଅକà­à¬·à¬°à¬°à­‡ ବିଶà­à¬³à¬·à¬£ କରିବା ସମୟରେ ତୃଟି: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "ଉଦà­à¬§à­à¬°à­à¬¤ ପାଠà­à¬¯ ଉଦà­à¬§à­à¬°à­à¬¤ ଚିହà­à¬¨à¬°à­‡ ଆରମà­à¬­ ହୋଇ ନାହିà¬" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "ପାଠà­à¬¯ ନିରà­à¬¦à­à¬¦à­‡à¬¶ ବା ଅନà­à¬¯ ଆବରଣ-ଉଦà­à¬§à­à¬°à­à¬¤ ପାଠà­à¬¯à¬°à­‡ ଅମେଳ ଉଦà­à¬§à­à¬°à­à¬¤à¬¿ ଚିହà­à¬¨" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "ଗୋଟିଠ'\\' ଅକà­à¬·à¬°à¬° ଠିକ ପରେ ପାଠà­à¬¯ ସମାପà­à¬¤ ହୋଇ ଗଲା (ପାଠà­à¬¯à¬Ÿà¬¿ ଥିଲା: '%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"%c ପାଇଠମେଳ ହେଉ ଥିବା ଉଦà­à¬§à­à¬°à­à¬¤à¬¿ ଚିହà­à¬¨ ମିଳିବା ପୂରà­à¬¬à¬°à­ ପାଠà­à¬¯ ସମାପà­à¬¤ ହୋଇ ଗଲା. " +"(ପାଠà­à¬¯à¬Ÿà¬¿ ଥିଲା: '%s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "ପାଠà­à¬¯ ଖାଲି ଥିଲା (ବା କେବଳ ଖାଲି ଯାଗା ଧାରଣ କରିଥିଲା)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾à¬°à­ ତଥà­à¬¯ ପଢି଼ବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾à¬°à­ ତଥà­à¬¯ ପଢି଼ବାରେ select()ରେ ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ତà­à¬°à­à¬Ÿà¬¿ (%s)" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid()ରେ ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ ତà­à¬°à­à¬Ÿà¬¿ (%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "ନିମà­à¬¨ ସà­à¬¤à¬°à­€à­Ÿ ପଦà­à¬§à¬¤à¬¿à¬•ୠସଂକେତ %ld ସହିତ ପà­à¬°à¬¸à­à¬¥à¬¾à¬¨ କରିଥାà¬" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "ନିମà­à¬¨ ସà­à¬¤à¬°à­€à­Ÿ ପଦà­à¬§à¬¤à¬¿à¬•ୠସଂକେତ %ld ଦà­à­±à¬¾à¬°à¬¾ ବନà­à¬¦ କରିଥାà¬" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "ନିମà­à¬¨ ସà­à¬¤à¬°à­€à­Ÿ ପଦà­à¬§à¬¤à¬¿à¬•ୠସଂକେତ %ld ଦà­à­±à¬¾à¬°à¬¾ ଅଟକ ରଖିଥାà¬" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "ନିମà­à¬¨ ସà­à¬¤à¬°à­€à­Ÿ ପଦà­à¬§à¬¤à¬¿ ଅସାଧରଣ ଭାବରେ ପà­à¬°à¬¸à­à¬¥à¬¾à¬¨ କରିଥାà¬" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପାଇପୠରୠତଥà­à¬¯ ପଢି଼ବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "ଶାଖା ସୃଷà­à¬Ÿà¬¿ କରିବାରେ ଅସଫଳ (%s" + +# Gora: "change to directory" means "go to directory" here +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "'%s' ଡିରେକà­à¬Ÿà­‹à¬°à¬¿à¬•ୠଯିବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾ \"%s\" ନିଷà­à¬ªà¬¾à¬¦à¬¨ କରିବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾à¬° ନିରà­à¬—ମ ବା ନିବେଶର ପà­à¬¨à¬ƒà¬¨à¬¿à¬°à­à¬¦à­à¬¦à­‡à¬¶à¬¨ କରିବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾à¬•ୠଶାଖାଯà­à¬•à­à¬¤ କରିବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾à¬•ୠନିଷà­à¬ªà¬¾à¬¦à¬¨ କରିବାରେ ଅଜଣା ତà­à¬°à­à¬Ÿà¬¿ \"%s\"" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପି.ଆଇ.ଡି. ପାଇପୠରୠପରà­à¬¯à­à¬¯à¬¾à¬ªà­à¬¤ ତଥà­à¬¯ ପଢି଼ବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾à¬°à­ ତଥà­à¬¯ ପଢ଼ିବାରେ ଅସଫଳ" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾ ସହିତ ସଂଯୋଗ ପାଇଠପାଇପୠସୃଷà­à¬Ÿà¬¿ କରିବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾à¬•ୠନିଷà­à¬ªà¬¾à¬¦à¬¨ କରିବାରେ ଅସଫଳ (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "ଅବୈଧ ପà­à¬°à­‹à¬—à­à¬°à¬¾à¬® ନାମ: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "ସଦିଶ ସà­à¬¬à¬¤à¬¨à­à¬¤à­à¬°à¬šà¬° %d ରେ ବାକà­à¬¯à¬–ଣà­à¬¡ %s ଟି ଅବୈଧ ଅଟେ" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "à¬à¬¹à¬¿ ପରିୂବେଶ ରେ ବାକà­à¬¯à¬–ଣà­à¬¡:%s ଅବୈଧ ଅଟେ" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ଚଳନà­à¬¤à¬¿ ଡିରେକà­à¬Ÿà­‹à¬°à¬¿: %s ଟି ଅବୈଧ ଅଟେ" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ସାହାଯà­à¬¯ କାରିକା (%s) କୠନିଷà­à¬ªà¬¾à¬¦à¬¨ କରିବାରେ ଅସଫଳ" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"ନିରà­à¬­à¬°à¬• ପà­à¬°à¬•à­à¬°à¬¿à­Ÿà¬¾à¬°à­ ତଥà­à¬¯ ପଢି଼ବାରେ g_io_channel_win32_poll()ରେ ଅପà­à¬°à¬¤à­à¬¯à¬¾à¬¶à¬¿à¬¤ " +"ତà­à¬°à­à¬Ÿà¬¿" + +#: ../glib/gutf8.c:780 +#| msgid "failed to get memory" +msgid "Failed to allocate memory" +msgstr "ସà­à¬®à­ƒà¬¤à¬¿à¬¸à­à¬¥à¬¾à¬¨ ବାଣà­à¬Ÿà¬¿à¬¬à¬¾à¬°à­‡ ବିଫଳ" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "ଇ.ଉ.ଟିà¬à¬«à­.-à­® ପାଇଠଅକà­à¬·à¬°à¬Ÿà¬¿ ପରିସର ବାହାରେ" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "ରà­à¬ªà¬¾à¬¨à­à¬¤à¬°à¬£ ନିବେଶେର ଅବୈଧ ଅନà­à¬•à­à¬°à¬®" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "ଇ.ଉ.ଟିà¬à¬«à­.-à­§à­¬ ପାଇଠଅକà­à¬·à¬°à¬Ÿà¬¿ ପରିସର ବାହାରେ" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ବାଇଟ" +msgstr[1] "%u ବାଇଟ" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ବାଇଟ" +msgstr[1] "%s ବାଇଟ" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "ଜାନà­à¬†à¬°à­€" + +msgctxt "full month name with day" +msgid "February" +msgstr "ଫେବୃଆରୀ" + +msgctxt "full month name with day" +msgid "March" +msgstr "ମାରà­à¬šà­à¬š" + +msgctxt "full month name with day" +msgid "April" +msgstr "ଅପà­à¬°à­‡à¬²" + +msgctxt "full month name with day" +msgid "May" +msgstr "ମଇ" + +msgctxt "full month name with day" +msgid "June" +msgstr "ଜà­à¬¨" + +msgctxt "full month name with day" +msgid "July" +msgstr "ଜà­à¬²à¬¾à¬‡" + +msgctxt "full month name with day" +msgid "August" +msgstr "ଅଗଷà­à¬Ÿ" + +msgctxt "full month name with day" +msgid "September" +msgstr "ସେପଟେମà­à¬¬à¬°" + +msgctxt "full month name with day" +msgid "October" +msgstr "ଅକà­à¬Ÿà­‹à¬¬à¬°" + +msgctxt "full month name with day" +msgid "November" +msgstr "ନଭେମà­à¬¬à¬°" + +msgctxt "full month name with day" +msgid "December" +msgstr "ଡିସେମà­à¬¬à¬°" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ଜାନà­à­Ÿà¬¾à¬°à­€" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ଫେବୃଯାରୀ" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "ମାରà­à¬šà­à¬š" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "ଅପà­à¬°à­‡à¬²" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "ମେ" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "ଜà­à¬¨" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "ଜà­à¬²à¬¾à¬‡" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ଅଗଷà­à¬Ÿ" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "ସେପଟେମà­à¬¬à¬°" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "ଅକà­à¬Ÿà­‹à¬¬à¬°" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ନଭେମà­à¬¬à¬°" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ଡିସେମà­à¬¬à¬°" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "ନିବେଶ ଫାଇଲକୠxmllint ସହିତ କାରà­à¬¯à­à­Ÿà¬•ାରୀ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "ନିବେଶ ଫାଇଲକୠପିକà­à¬¸ ତଥà­à­Ÿ ସହିତ କାରà­à¬¯à­à­Ÿà¬•ାରୀ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "ବକୟା ତà­à¬°à­à¬Ÿà¬¿ ପାଇବାରେ ଅସମରà­à¬¥: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "'%s' ଫାଇଲ କୠେଲଖନ ପାଇଠଖୋଲିବାରେ ଅସଫଳ: fdopen() ଅସଫଳ: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "'%s' ଫାଇଲ ଖୋଲିବାରେ ଅସଫଳ: fflush() ଅସଫଳ: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "'%s' ଫାଇଲ କୠବନà­à¬¦ କରିବା ରେ ଅସଫଳ: fclose() ଅସଫଳ: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "'%s' ପାଇଠଅସମà­à¬ªà­‚ରà­à¬£à­à¬£ ତଥà­à­Ÿ ଗà­à¬°à¬¹à¬£ ହୋଇଛି" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "ଯାଞà­à¬š କରିବା ସମୟରେ ଅପà­à¬°à¬¤à­à­Ÿà¬¾à¬¶à¬¿à¬¤ ବିକଳà­à¬ª ଲମà­à¬¬ ଯଦି SO_PASSCRED କୠସକେଟରେ ସକà­à¬°à¬¿à­Ÿ କରାଯାà¬à¥¤ " +#~ "ଆଶାତିତ %d ବାଇଟ, %d ପାଇଛି" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' ପାଇଠକୌଣସି ସରà­à¬­à¬¿à¬¸ ଅନà­à¬²à¬¿à¬ªà¬¿ ନାହିà¬" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "ଶୂନà­à¬¯ ଉପବାକà­à¬¯à¬–ଣà­à¬¡ କାରà­à¬¯à­à¬¯à¬¸à­à¬¥à¬³à­€ ପରିସୀମା ଶେଷ ହୋଇଯାଇଛି" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "ଅକà­à¬·à¬° ପà­à¬°à¬•ାର-ପରିବରà­à¬¤à­à¬¤à¬¨ escapes (\\l, \\L, \\u, \\U) ଗà­à¬¡à¬¼à¬¿à¬• à¬à¬ à¬¾à¬°à­‡ ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬à¬¨à­à¬¤à¬¿" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE ଶà­à¬°à­‡à¬£à­€à¬° ପà­à¬¨à¬°à¬¾à¬¬à¬°à­à¬¤à­à¬¤à¬¨ ଅନà­à¬®à­‹à¬¦à¬¿à¬¤ ନà­à¬¹à¬" + +#~ msgid "File is empty" +#~ msgstr "ଫାଇଲ ଟି ଖାଲି ଅଛି" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "ମୂଖà­à¬¯ ଫାଇଲ ଧାରଣ କରିଥିବା '%s' ଚାବିକାଠି ର ମୂଲà­à¬¯ ନିରୂପଣ କରିହେବ ନାହିà¬" + +#~ msgid "This option will be removed soon." +#~ msgstr "à¬à¬¹à¬¿ ବିକଳà­à¬ªà¬•ୠଅତିଶିଘà­à¬° ବାହାର କରିଦିଆଯିବ।" + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "ଫାଇଲ '%s'କୠଆରମà­à¬­ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#~ msgid "Error connecting: " +#~ msgstr "ସଂଯୋଗ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: " + +#~ msgid "Error connecting: %s" +#~ msgstr "ସଂଯୋଗ କରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "unixରୠପଢିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "unix ବନà­à¬¦à¬•ରିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "unixରେ ଲେଖିବାରେ ତà­à¬°à­à¬Ÿà¬¿: %s" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "ଡିରେକà­à¬Ÿà­‹à¬°à­€ ଉପରେ ଡିରେକà­à¬Ÿà­‹à¬°à­€à¬•ୠଘà­à¬žà­à¬šà¬¾à¬‡à¬ªà¬¾à¬°à¬¿à¬¬à­‡ ନାହିà¬" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "ରà­à¬ªà¬¾à¬¨à­à¬¤à¬°à¬£ ନିବେଶେର ଅବୈଧ ଅନà­à¬•à­à¬°à¬®" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "ସରà­à¬¬à¬¾à¬§à¬¿à¬• ତଥà­à­Ÿ ଆରେ ସୀମା ପହଞà­à¬šà¬¿à¬—ଲା" + +#~ msgid "do not hide entries" +#~ msgstr "ଭରଣଗà­à¬¡à¬¼à¬¿à¬•ୠଲà­à¬šà¬¾à¬¨à­à¬¤à­ ନାହିà¬" + +#~ msgid "use a long listing format" +#~ msgstr "ଲମà­à¬¬à¬¾ ତାଲିକାଭà­à¬•à­à¬¤ ଶୈଳୀ ବà­à­Ÿà¬¬à¬¹à¬¾à¬° କରନà­à¬¤à­" diff --git a/po/pa.po b/po/pa.po new file mode 100644 index 0000000..82cc4c6 --- /dev/null +++ b/po/pa.po @@ -0,0 +1,6745 @@ +# translation of glib.HEAD.po to Punjabi +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# +# +# Amanpreet Singh Alam , 2004. +# ASB , 2004, 2005, 2006, 2007. +# Amanpreet Singh Alam , 2008. +# A S Alam , 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2019. +msgid "" +msgstr "" +"Project-Id-Version: glib.HEAD\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2019-09-07 11:26+0000\n" +"PO-Revision-Date: 2019-09-08 22:39-0700\n" +"Last-Translator: A S Alam \n" +"Language-Team: Punjabi \n" +"Language: pa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.04.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "ਜੀ-à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਚੋਣ" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "ਜੀ-à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਚੋਣ ਵੇਖਾਓ" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication ਸੇਵਾ ਮੋਡ ਦਿਓ (ਡੀ-ਬੱਸ ਸੇਵਾ ਫਾਇਲਾਂ ਤੋਂ ਵਰਤੋਂ)" + +#: gio/gapplication.c:557 +#, fuzzy +#| msgid "List applications" +msgid "Override the application’s ID" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਸੂਚੀ" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:493 gio/gsettings-tool.c:567 +msgid "Print help" +msgstr "ਮੱਦਦ ਪਰਿੰਟ ਕਰੋ" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:494 gio/gresource-tool.c:562 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "ਵਰਜਨ ਛਾਪੋ" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:573 +msgid "Print version information and exit" +msgstr "ਵਰਜਨ ਜਾਣਕਾਰੀ ਛਾਪੋ ਅਤੇ ਬੰਦ ਕਰੋ" + +#: gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਸੂਚੀ" + +#: gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"ਇੰਸਟਾਲ ਹੋਈਆਂ ਡੀ-ਬੱਸ ਸਰਗਰਮ ਕਰਨ ਯੋਗ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਦੀ ਸੂਚੀ (.desktop ਫਾਇਲਾਂ ਰਾਹੀਂ)" + +#: gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਚਲਾਓ" + +#: gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਚਲਾਓ (ਚੋਣਵੇਂ ਰੂਪ ਵਿੱਚ ਫਾਇਲਾਂ ਖੋਲà©à¨¹ ਕੇ)" + +#: gio/gapplication-tool.c:57 +#| msgid "APPID [FILE...]" +msgid "APPID [FILE…]" +msgstr "APPID [FILE…]" + +#: gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "ਕਾਰਵਾਈ ਸਰਗਰਮ ਕਰੋ" + +#: gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਉੱਤੇ ਸੱਦਾ ਦਿੱਤੀ ਕਾਰਵਾਈ" + +#: gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "ਉਪਲੱਬਧ ਕਾਰਵਾਈਆਂ ਦੀ ਸੂਚੀ" + +#: gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਲਈ ਤਹਿ ਕਾਰਵਾਈਆਂ ਦੀ ਸੂਚੀ (.desktop ਫਾਇਲ ਤੋਂ)" + +#: gio/gapplication-tool.c:65 gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMMAND" + +#: gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "ਵੇਰਵੇ ਸਮੇਤ ਮੱਦਦ ਛਾਪਣ ਲਈ ਕਮਾਂਡ" + +#: gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "ਡੀ-ਬੱਸ ਫਾਰਮੈਟ ਵਿੱਚ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਪਛਾਣਕਰਤਾ (ਜਿਵੇਂ ਕਿ: org.example.viewer)" + +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:500 gio/gresource-tool.c:566 +msgid "FILE" +msgstr "FILE" + +#: gio/gapplication-tool.c:72 +#| msgid "Optional relative or relative filenames, or URIs to open" +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "ਖੋਲà©à¨¹à¨£ ਲਈ ਅਨà©à¨¸à¨¾à¨°à©€ ਜਾਂ ਅਸਲ ਫਾਇਲ-ਨਾਂ ਜਾਂ URI ਚੋਣਵੇਂ ਰੂਪ ਵਿੱਚ ਦਿਓ" + +#: gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "à¨à¨•ਸ਼ਨ" + +#: gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "ਵਾਪਿਸ ਲੈਣ ਵਾਲੀ ਕਾਰਵਾਈ ਦਾ ਨਾਂ" + +#: gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "ਪੈਰਾਮੀਟਰ" + +#: gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "ਕਾਰਵਾਈ ਵਾਪਿਸ ਲੈਣ ਲਈ ਚੋਣਵਾਂ ਪੈਰਾਮੀਟਰ, GVariant ਰੂਪ ਵਿੱਚ" + +#: gio/gapplication-tool.c:96 gio/gresource-tool.c:531 gio/gsettings-tool.c:659 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"ਅਣਜਾਣ ਕਮਾਂਡ %s\n" +"\n" + +#: gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "ਵਰਤੋਂ:\n" + +#: gio/gapplication-tool.c:114 gio/gresource-tool.c:556 +#: gio/gsettings-tool.c:694 +msgid "Arguments:\n" +msgstr "ਆਰਗੂਮੈਂਟ:\n" + +#: gio/gapplication-tool.c:133 gio/gio-tool.c:224 +#| msgid "[ARGS...]" +msgid "[ARGS…]" +msgstr "[ARGS…]" + +#: gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "ਕਮਾਂਡਾਂ:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:146 +#, c-format +#| msgid "" +#| "Use '%s help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ਵੇਰਵੇ ਸਮੇਤ ਮਦਦ ਪà©à¨°à¨¾à¨ªà¨¤ ਕਰਨ ਲਈ “%s help COMMAND†ਵਰਤੋਂ।\n" +"\n" + +#: gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"'%s' ਕਮਾਂਡ ਲਈ ਸਿੱਧੇ ਫਲੋਅ ਲਈ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਆਈਡੀ ਚਾਹੀਦਾ ਹੈ\n" +"\n" + +#: gio/gapplication-tool.c:171 +#, c-format +#| msgid "invalid application id: '%s'\n" +msgid "invalid application id: “%sâ€\n" +msgstr "ਗਲਤ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ id: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:182 +#, c-format +#| msgid "" +#| "'%s' takes no arguments\n" +#| "\n" +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†ਲਈ ਕੋਈ ਆਰਗੂਮੈਂਟ ਨਹੀਂ ਚਾਹੀਦਾ ਹੈ\n" +"\n" + +#: gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "%s: ਡੀ-ਬੱਸ ਨਾਲ ਕà©à¨¨à©ˆà¨•ਟ ਕਰਨ ਲਈ ਅਸਮਰੱਥ\n" + +#: gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "%s ਸà©à¨¨à©‡à¨¹à¨¾ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਨੂੰ ਭੇਜਣ ਦੌਰਾਨ ਗਲਤੀ: %s\n" + +#: gio/gapplication-tool.c:317 +msgid "action name must be given after application id\n" +msgstr "ਕਾਰਵਾਈ ਨਾਂ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਆਈਡੀ ਦੇਣ ਬਾਅਦ ਦਿੱਤਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ\n" + +#: gio/gapplication-tool.c:325 +#, c-format +#| msgid "" +#| "invalid action name: '%s'\n" +#| "action names must consist of only alphanumerics, '-' and '.'\n" +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"ਗਲਤ ਕਾਰਵਾਈ ਨਾਂ: “%sâ€\n" +"ਕਾਰਵਾਈ ਨਾਂ ਵਿੱਚ ਕੇਵਲ ਵਰਣਮਾਲਾ ਅੱਖਰ, “-†ਅਤੇ “.†ਹੀ ਸਕਦੇ ਹਨ।\n" + +#: gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "ਕਾਰਵਾਈ ਪੈਰਾਮੀਟਰ ਪਾਰਸ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s\n" + +#: gio/gapplication-tool.c:356 +msgid "actions accept a maximum of one parameter\n" +msgstr "ਕਾਰਵਾਈਆਂ ਵੱਧ ਤੋਂ ਵੱਧ ਇੱਕ ਪੈਰਾਮੀਟਰ ਮਨਜ਼ੂਰ ਕਰਦੇ ਹਨ\n" + +#: gio/gapplication-tool.c:411 +msgid "list-actions command takes only the application id" +msgstr "ਲਿਸਟ-ਕਾਰਵਾਈ ਕਮਾਂਡ ਕੇਵਲ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਆਈਡੀ ਲੈਂਦੀ ਹੈ" + +#: gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "%s à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਲਈ ਡੈਸਕਟਾਪ ਫਾਇਲ ਲੱਭਣ ਲਈ ਅਸਮਰੱਥ ਹੈ\n" + +#: gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"ਅਣਜਾਣ ਕਮਾਂਡ: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s ਨੂੰ ਬਹà©à¨¤ ਵੱਧ ਗਿਣਤੀ ਪਾਸ ਕੀਤੀ ਗਈ" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "ਬੇਸ ਸਟਰੀਮ ਉੱਤੇ ਸੀਕ ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#: gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream ਨੂੰ ਛੋਟਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "ਸਟਰੀਮ ਪਹਿਲਾਂ ਹੀ ਬੰਦ ਹੈ" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "ਬੇਸ ਸਟਰੀਮ ਉੱਤੇ ਟਰਾਂਸਕੇਟ ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1871 gio/gdbusprivate.c:1409 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "ਓਪਰੇਸ਼ਨ ਰੱਦ ਕੀਤਾ ਗਿਆ" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "ਗਲਤ ਆਬਜੈਕਟ, ਸ਼à©à¨°à©‚ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "ਇੰਪà©à©±à¨Ÿ ਵਿੱਚ ਅਧੂਰਾ ਮਲਟੀਬਾਈਟ ਕà©à¨°à¨®" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "ਟਿਕਾਣੇ ਉੱਤੇ ਲੋੜੀਦੀ ਥਾਂ ਨਹੀਂ" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:447 glib/gconvert.c:877 +#: glib/giochannel.c:1561 glib/giochannel.c:1603 glib/giochannel.c:2450 +#: glib/gutf8.c:869 glib/gutf8.c:1322 +msgid "Invalid byte sequence in conversion input" +msgstr "ਬਦਲਣ ਲਈ ਦਿੱਤੀ ਸਤਰ ਵਿੱਚ ਬਾਇਟ ਦਾ ਸਰੂਪ ਠੀਕ ਨਹੀਂ ਹੈ" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:455 glib/gconvert.c:791 +#: glib/giochannel.c:1568 glib/giochannel.c:2462 +#, c-format +msgid "Error during conversion: %s" +msgstr "ਤਬਦੀਲੀ ਦੌਰਾਨ ਗਲਤੀ %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1094 +msgid "Cancellable initialization not supported" +msgstr "ਰੱਦਕਰਨਯੋਗ ਸ਼à©à¨°à©‚ ਲਈ ਸਹਾਇਕ ਨਹੀਂ" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:320 glib/giochannel.c:1389 +#, c-format +#| msgid "Conversion from character set '%s' to '%s' is not supported" +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "ਕਰੈਕਟਰ ਸਮੂਹ “%s†ਤੋਂ “%s†ਵਿੱਚ ਬਦਲਣ ਇਸ ਵੇਲੇ ਸੰਭਵ ਨਹੀਂ" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:324 +#, c-format +#| msgid "Could not open converter from '%s' to '%s'" +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "“%s†ਤੋੱ “%s†ਵਿੱਚ ਬਦਲਣ ਵਾਲਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ" + +#: gio/gcontenttype.c:452 +#, c-format +msgid "%s type" +msgstr "%s ਟਾਈਪ" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "ਅਣਜਾਣ ਟਾਈਪ" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s ਫਾਇਲ-ਟਾਈਪ" + +#: gio/gcredentials.c:315 gio/gcredentials.c:574 +msgid "GCredentials is not implemented on this OS" +msgstr "ਇਸ ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਲਈ GCredentials ਬਣਾਇਆ ਨਹੀਂ ਗਿਆ" + +#: gio/gcredentials.c:470 +msgid "There is no GCredentials support for your platform" +msgstr "ਤà©à¨¹à¨¾à¨¡à©‡ ਪਲੇਟਫਾਰਮ ਲਈ GCredentials ਸਹਿਯੋਗ ਨਹੀਂ ਹੈ" + +#: gio/gcredentials.c:516 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "ਇਸ ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਲਈ GCredentials ਕਾਰਵਾਈ ਆਈਡੀ ਨਹੀਂ ਰੱਖਦਾ ਹੈ" + +#: gio/gcredentials.c:568 +msgid "Credentials spoofing is not possible on this OS" +msgstr "ਇਸ ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਲਈ ਸਨਦ (credential) ਧੋਖਾ ਦੇਣਾ ਸੰਭਵ ਨਹੀਂ ਹੈ" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "ਅਚਾਨਕ ਛੇਤੀ à¨à¨‚ਡ-ਆਫ਼-ਸਟੀਰਮ" + +#: gio/gdbusaddress.c:158 gio/gdbusaddress.c:232 gio/gdbusaddress.c:313 +#, c-format +#| msgid "Unsupported key '%s' in address entry '%s'" +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "à¨à¨¡à¨°à©ˆà©±à¨¸ à¨à¨‚ਟਰੀ â€%2$s†ਵਿੱਚ ਗ਼ੈਰ-ਸਹਾਇਕ ਕà©à©°à¨œà©€ â€%1$sâ€" + +#: gio/gdbusaddress.c:171 +#, c-format +#| msgid "Meaningless key/value pair combination in address entry '%s'" +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "à¨à¨¡à¨°à©ˆà©±à¨¸ à¨à¨‚ਟਰੀ â€%s†ਵਿੱਚ ਬਿਨ-ਕਾਰਨ ਕà©à©°à¨œà©€ ਜੋੜਾ" + +#: gio/gdbusaddress.c:180 +#, c-format +#| msgid "" +#| "Address '%s' is invalid (need exactly one of path, tmpdir or abstract " +#| "keys)" +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "à¨à¨¡à¨°à©ˆà©±à¨¸ â€%s†ਗਲਤ ਹੈ (ਠੀਕ ਪਾਥ, tmpdir ਜਾਂ abstract ਕà©à©°à¨œà©€à¨†à¨‚ ਚਾਹੀਦੀਆਂ ਹਨ)" + +#: gio/gdbusaddress.c:247 gio/gdbusaddress.c:328 +#, c-format +#| msgid "Error in address '%s' - the port attribute is malformed" +msgid "Error in address “%s†— the port attribute is malformed" +msgstr "â€%s†à¨à¨¡à¨°à©ˆà©±à¨¸ 'ਚ ਗਲਤੀ — ਪੋਰਟ ਗà©à¨£ ਖ਼ਰਾਬ ਹੈ" + +#: gio/gdbusaddress.c:258 gio/gdbusaddress.c:339 +#, c-format +#| msgid "Error in address '%s' - the family attribute is malformed" +msgid "Error in address “%s†— the family attribute is malformed" +msgstr "à¨à¨¡à¨°à©ˆà©±à¨¸ “%s“ ਵਿੱਚ ਗਲਤੀ - ਫੈਮਲੀ ਗà©à¨£ ਖ਼ਰਾਬ ਹੈ" + +#: gio/gdbusaddress.c:409 gio/gdbusaddress.c:673 +#, c-format +#| msgid "Unknown or unsupported transport '%s' for address '%s'" +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "à¨à¨¡à¨°à©ˆà©±à¨¸ “%2$s“ ਲਈ ਅਣਜਾਣ ਜਾਂ ਗ਼ੈਰ-ਸਹਾਇਕ “%1$s“ ਟਰਾਂਸਪੋਰਟ" + +#: gio/gdbusaddress.c:453 +#, c-format +#| msgid "Address element '%s' does not contain a colon (:)" +msgid "Address element “%s†does not contain a colon (:)" +msgstr "à¨à¨¡à¨°à©ˆà©±à¨¸ à¨à¨²à©€à¨®à©ˆà¨‚ਟ “%s“ ਕਾਲਨ (:) ਨਹੀਂ ਰੱਖਦਾ ਹੈ" + +#: gio/gdbusaddress.c:462 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:483 +#, c-format +#| msgid "" +#| "Key/Value pair %d, '%s', in address element '%s' does not contain an " +#| "equal sign" +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"à¨à¨¡à¨°à©ˆà©±à¨¸ à¨à¨²à©€à¨®à©ˆà¨‚ਟ “%3$s“ ਵਿੱਚ ਕà©à©°à¨œà©€/ਮà©à©±à¨² ਜੋੜਾ %1$d, “%2$s“ ਬਰਾਬਰ ਸਾਈਨ ਨਹੀਂ ਰੱਖਦਾ" +" ਹੈ" + +#: gio/gdbusaddress.c:494 +#, fuzzy, c-format +#| msgid "" +#| "Key/Value pair %d, '%s', in address element '%s' does not contain an " +#| "equal sign" +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"à¨à¨¡à¨°à©ˆà©±à¨¸ à¨à¨²à©€à¨®à©ˆà¨‚ਟ '%3$s' ਵਿੱਚ ਕà©à©°à¨œà©€/ਮà©à©±à¨² ਜੋੜਾ %1$d, '%2$s' ਬਰਾਬਰ ਸਾਈਨ ਨਹੀਂ ਰੱਖਦਾ" +" ਹੈ" + +#: gio/gdbusaddress.c:508 +#, c-format +#| msgid "" +#| "Error unescaping key or value in Key/Value pair %d, '%s', in address " +#| "element '%s'" +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"à¨à¨¡à¨°à©ˆà©±à¨¸ ਤੱਕ “%3$s“ ਵਿੱਚ ਗਲਤ ਕà©à©°à¨œà©€ ਜਾਂ ਕà©à©°à¨œà©€/ਮà©à©±à¨² ਪੇਅਰ %1$d, “%2$s“ 'ਚ ਗਲਤੀ ਹੈ" + +#: gio/gdbusaddress.c:580 +#, c-format +#| msgid "" +#| "Error in address '%s' - the unix transport requires exactly one of the " +#| "keys 'path' or 'abstract' to be set" +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"“%s“ à¨à¨¡à¨°à©ˆà©±à¨¸ 'ਚ ਗਲਤੀ — ਯੂਨੈਕਸ ਟਰਾਂਸਪੋਰਟ ਲਈ ਠੀਕ “path“ ਜਾਂ “abstract“ ਕà©à©°à¨œà©€" +" ਸੈੱਟ ਹੋਣੀ " +"ਚਾਹੀਦੀ ਹੈ।" + +#: gio/gdbusaddress.c:616 +#, c-format +#| msgid "Error in address '%s' - the host attribute is missing or malformed" +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "â€%s†à¨à¨¡à¨°à©ˆà©±à¨¸ 'ਚ ਗਲਤੀ — ਹੋਸਟ ਗà©à¨£ ਮੌਜੂਦ ਨਹੀਂ ਜਾਂ ਗਲਤ ਹੈ" + +#: gio/gdbusaddress.c:630 +#, c-format +#| msgid "Error in address '%s' - the port attribute is missing or malformed" +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "â€%s†à¨à¨¡à¨°à©ˆà©±à¨¸ 'ਚ ਗਲਤੀ — ਪੋਰਟ ਗà©à¨£ ਮੌਜੂਦ ਨਹੀਂ ਜਾਂ ਗਲਤ ਹੈ" + +#: gio/gdbusaddress.c:644 +#, c-format +#| msgid "" +#| "Error in address '%s' - the noncefile attribute is missing or malformed" +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "“%s“ à¨à¨¡à¨°à©ˆà©±à¨¸ 'ਚ ਗਲਤੀ — noncefile ਗà©à¨£ ਮੌਜੂਦ ਨਹੀਂ ਜਾਂ ਗਲਤ ਹੈ" + +#: gio/gdbusaddress.c:665 +msgid "Error auto-launching: " +msgstr "ਆਟੋ-ਚਲਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: " + +#: gio/gdbusaddress.c:718 +#, c-format +#| msgid "Error opening nonce file '%s': %s" +msgid "Error opening nonce file “%sâ€: %s" +msgstr "nonce ਫਾਇਲ “%s“ ਖੋਲà©à¨¹à¨£ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gdbusaddress.c:737 +#, c-format +#| msgid "Error reading from nonce file '%s': %s" +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "“%s“ nonce ਫਾਇਲ ਤੋਂ ਪੜà©à¨¹à¨¨ 'ਚ ਗਲਤੀ: %s" + +#: gio/gdbusaddress.c:746 +#, c-format +#| msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "“%s“ nonce ਫਾਇਲ ਤੋਂ ਪੜà©à¨¹à¨¨ 'ਚ ਗਲਤੀ, ਲੋੜ ਸੀ ੧੬ ਬਾਈਟ ਦੀ, ਮਿਲੇ %d" + +#: gio/gdbusaddress.c:764 +#, c-format +#| msgid "Error writing contents of nonce file '%s' to stream:" +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "nonce ਫਾਇਲ “%s“ ਦੀ ਸਮੱਗਰੀ ਸਟਰੀਮ ਉੱਤੇ ਲਿਖਣ ਦੌਰਾਨ ਗਲਤੀ:" + +#: gio/gdbusaddress.c:973 +msgid "The given address is empty" +msgstr "ਦਿੱਤਾ à¨à¨¡à¨°à©ˆà©±à¨¸ ਖਾਲੀ ਹੈ" + +#: gio/gdbusaddress.c:1086 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "ਬਿਨਾਂ setuid ਦੇ ਸà©à¨¨à©‡à¨¹à¨¾ ਬਸ ਸਪੈਵ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ:" + +#: gio/gdbusaddress.c:1093 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "ਬਿਨਾਂ ਮਸ਼ੀਨ-id ਦੇ ਸà©à¨¨à©‡à¨¹à¨¾ ਬਸ ਸਪੈਵਨ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ: " + +#: gio/gdbusaddress.c:1100 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" + +#: gio/gdbusaddress.c:1142 +#, c-format +#| msgid "Error spawning command line '%s': " +msgid "Error spawning command line “%sâ€: " +msgstr "“%s“ ਕਮਾਂਡ ਲਾਈਨ ਸਵੈਪ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: " + +#: gio/gdbusaddress.c:1211 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "ਸ਼ੈਸ਼ਨ ਬਸ à¨à¨¡à¨°à©ˆà©±à¨¸ ਜਾਣਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ (ਇਸ OS ਵਲੋਂ ਬਣਾਇਆ ਨਹੀਂ ਹੈ)" + +#: gio/gdbusaddress.c:1349 gio/gdbusconnection.c:7178 +#, c-format +#| msgid "" +#| "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#| "variable - unknown value '%s'" +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"ਬਸ à¨à¨¡à¨°à©ˆà©±à¨¸ ਜਾਣਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ, ਕਿਉਂਕਿ DBUS_STARTER_BUS_TYPE ਇੰਵਾਇਰਨਮੈਂਟ ਵੇਰੀਬਲ" +" — " +"ਅਣਜਾਣ ਮà©à©±à¨² “%s“" + +#: gio/gdbusaddress.c:1358 gio/gdbusconnection.c:7187 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"ਬਸ à¨à¨¡à¨°à©ˆà©±à¨¸ ਜਾਣਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ, ਕਿਉਂਕਿ DBUS_STARTER_BUS_TYPE ਇੰਵਾਇਰਨਮੈਂਟ ਵੇਰੀਬਲ" +" ਸੈੱਟ ਨਹੀਂ " +"ਹੈ" + +#: gio/gdbusaddress.c:1368 +#, c-format +msgid "Unknown bus type %d" +msgstr "ਅਣਜਾਣ ਬਸ ਟਾਈਪ %d" + +#: gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "ਲਾਈਨ ਦੀ ਸਮੱਗਰੀ ਪੜà©à¨¹à¨¨ ਦੌਰਾਨ ਅਚਾਨਕ ਸਮੱਗਰੀ ਦੀ ਕਿਸਮ ਆਈ" + +#: gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "ਲਾਈਨ ਪੜà©à¨¹à¨¨ ਦੀ ਕੋਸ਼ਿਸ਼ (ਸà©à¨°à©±à¨–ਿਅਤ) ਅਚਾਨਕ ਸਮੱਗਰੀ ਦੀ ਕਿਸਮ ਆਈ" + +#: gio/gdbusauth.c:481 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "ਸਭ ਉਪਲੱਬਧ ਪਰਮਾਣਿਤ ਢੰਗ ਖਤਮ (ਵਰਤੇ: %s) (ਉਪਲੱਬਧ: %s)" + +#: gio/gdbusauth.c:1144 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer ਰਾਹੀਂ ਰੱਦ ਕੀਤਾ" + +#: gio/gdbusauthmechanismsha1.c:262 +#, c-format +#| msgid "Error when getting information for directory '%s': %s" +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "ਡਾਇਰੈਕਟਰੀ â€%s†ਲਈ ਜਾਨਕਾਰੀ ਪà©à¨°à¨¾à¨ªà¨¤ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gdbusauthmechanismsha1.c:274 +#, c-format +#| msgid "" +#| "Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"ਡਾਇਰੈਕਟਰੀ â€%s†ਦੇ ਅਧਿਕਾਰ ਖ਼ਰਾਬ ਹੋ ਚà©à©±à¨•ੇ ਹਨ। ਲੋੜੀਦਾ ਮੋਡ 0700 ਸੀ, ਪਰ ਹੈ 0%o" + +#: gio/gdbusauthmechanismsha1.c:299 +#, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory “%sâ€: %s" +msgstr "â€%s†ਡਾਇਰੈਕਟਰੀ ਬਣਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gdbusauthmechanismsha1.c:346 +#, c-format +#| msgid "Error opening keyring '%s' for reading: " +msgid "Error opening keyring “%s†for reading: " +msgstr "â€%s†ਕੀਰਿੰਗ ਨੂੰ ਪੜà©à¨¹à¨¨ ਦੌਰਾਨ ਗਲਤੀ: " + +#: gio/gdbusauthmechanismsha1.c:369 gio/gdbusauthmechanismsha1.c:687 +#, c-format +#| msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "â€%2$s†ਉੱਤੇ ਕੀਰਿੰਗ ਦੀ %1$d ਲਾਈਨ ਦੀ ਸਮੱਗਰੀ â€%3$s†ਨਿਕਾਰਾ ਹੈ" + +#: gio/gdbusauthmechanismsha1.c:383 gio/gdbusauthmechanismsha1.c:701 +#, c-format +#| msgid "" +#| "First token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"â€%2$s†ਉੱਤੇ ਕੀਰਿੰਗ ਦੀ %1$d ਲਾਈਨ ਉੱਤੇ ਪਹਿਲੇ ਟੋਕਨ ਦੀ ਸਮੱਗਰੀ â€%3$s†ਨਿਕਾਰਾ ਹੈ" + +#: gio/gdbusauthmechanismsha1.c:397 gio/gdbusauthmechanismsha1.c:715 +#, c-format +#| msgid "" +#| "Second token of line %d of the keyring at '%s' with content '%s' is " +#| "malformed" +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"â€%2$s†ਉੱਤੇ ਕੀਰਿੰਗ ਦੀ %1$d ਲਾਈਨ ਉੱਤੇ ਦੂਜੇ ਟੋਕਨ ਦੀ ਸਮੱਗਰੀ â€%3$s†ਨਿਕਾਰਾ ਹੈ" + +#: gio/gdbusauthmechanismsha1.c:421 +#, c-format +#| msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "â€%2$s†ਉੱਤੇ ਕੀਰਿੰਗ ਵਿੱਚ id %1$d ਨਾਲ ਕੋਈ ਕੂਕੀਜ਼ ਨਹੀਂ ਲੱਭਿਆ" + +#: gio/gdbusauthmechanismsha1.c:503 +#, c-format +#| msgid "Error deleting stale lock file '%s': %s" +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "ਸਟਾਲ ਲਾਕ ਫਾਇਲ â€%s†ਹਟਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gdbusauthmechanismsha1.c:535 +#, c-format +#| msgid "Error creating lock file '%s': %s" +msgid "Error creating lock file “%sâ€: %s" +msgstr "â€%s†ਲਾਕ ਫਾਇਲ ਬਣਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gdbusauthmechanismsha1.c:566 +#, c-format +#| msgid "Error closing (unlinked) lock file '%s': %s" +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "â€%s†ਲਾਕ ਫਾਇਲ ਬੰਦ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ (ਬਿਨ-ਲਿੰਕ): %s" + +#: gio/gdbusauthmechanismsha1.c:577 +#, c-format +#| msgid "Error unlinking lock file '%s': %s" +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "ਲਾਕ ਫਾਇਲ â€%s†ਅਣ-ਲਿੰਕ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gdbusauthmechanismsha1.c:654 +#, c-format +#| msgid "Error opening keyring '%s' for writing: " +msgid "Error opening keyring “%s†for writing: " +msgstr "â€%s†ਕੀਰਿੰਗ ਨੂੰ ਲਿਖਣ ਲਈ ਖੋਲà©à¨¹à¨£ ਦੌਰਾਨ ਗਲਤੀ: " + +#: gio/gdbusauthmechanismsha1.c:850 +#, c-format +#| msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(ਇਸ ਤੋਂ ਇਲਾਵਾ, â€%s†ਲਈ ਲਾਕ ਛੱਡਣ ਲਈ ਫੇਲà©à¨¹ ਹੈ: %s) " + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2400 +msgid "The connection is closed" +msgstr "ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਬੰਦ ਕੀਤਾ ਗਿਆ।" + +#: gio/gdbusconnection.c:1901 +msgid "Timeout was reached" +msgstr "ਸਮਾਂ ਸਮਾਪਤ ਹੋ ਚà©à©±à¨•ਾ ਸੀ" + +#: gio/gdbusconnection.c:2522 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "ਗ਼ੈਰ-ਸਹਾਇਕ ਫਲੈਗ ਮਿਲੇ, ਜਦੋਂ ਕਿ ਕਲਾਇਟ-ਪੱਖੀ ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਬਣਾਇਆ ਜਾ ਰਿਹਾ ਸੀ" + +#: gio/gdbusconnection.c:4151 gio/gdbusconnection.c:4498 +#, c-format +#| msgid "" +#| "No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"ਪਾਥ %s ਉੱਤੇ ਆਬਜੈਕਟ ਉੱਤੇ â€org.freedesktop.DBus.Properties†ਵਰਗਾ ਕੋਈ ਆਬਜੈਕਟ ਨਹੀਂ" + +#: gio/gdbusconnection.c:4293 +#, c-format +#| msgid "No such property '%s'" +msgid "No such property “%sâ€" +msgstr "ਕੋਈ â€%s†ਵਿਸ਼ੇਸ਼ਤਾ ਨਹੀਂ" + +#: gio/gdbusconnection.c:4305 +#, c-format +#| msgid "Property '%s' is not readable" +msgid "Property “%s†is not readable" +msgstr "ਵਿਸ਼ੇਸ਼ਤਾ â€%s†ਪੜà©à¨¹à¨¨à¨¯à©‹à¨— ਨਹੀਂ" + +#: gio/gdbusconnection.c:4316 +#, c-format +#| msgid "Property '%s' is not writable" +msgid "Property “%s†is not writable" +msgstr "ਵਿਸ਼ੇਸ਼ਤਾ â€%s†ਲਿਖਣਯੋਗ ਨਹੀਂ" + +#: gio/gdbusconnection.c:4336 +#, c-format +#| msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "ਵਿਸ਼ੇਸ਼ਤਾ â€%s†ਸੈੱਟ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: ਲੋੜੀਦੀ ਕਿਸਮ ਸੀ â€%sâ€, ਪਰ ਮਿਲੀ â€%sâ€" + +#: gio/gdbusconnection.c:4441 gio/gdbusconnection.c:4649 +#: gio/gdbusconnection.c:6618 +#, c-format +#| msgid "No such interface '%s'" +msgid "No such interface “%sâ€" +msgstr "â€%s†ਕੋਈ ਇੰਟਰਫੇਸ ਨਹੀਂ" + +#: gio/gdbusconnection.c:4867 gio/gdbusconnection.c:7127 +#, c-format +#| msgid "No such interface '%s' on object at path %s" +msgid "No such interface “%s†on object at path %s" +msgstr "ਪਾਥ %2$s ਉੱਤੇ ਆਬਜੈਕਟ ਲਈ â€%1$s†ਕੋਈ ਇੰਟਰਫੇਸ ਨਹੀਂ ਹੈ" + +#: gio/gdbusconnection.c:4965 +#, c-format +#| msgid "No such method '%s'" +msgid "No such method “%sâ€" +msgstr "â€%s†ਢੰਗ ਨਹੀਂ ਹੈ" + +#: gio/gdbusconnection.c:4996 +#, c-format +#| msgid "Type of message, '%s', does not match expected type '%s'" +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "ਸà©à¨¨à©‡à¨¹à©‡ ਦੀ ਕਿਸਮ â€%s†ਮੰਗੀ ਗਈ ਕਿਸਮ â€%s†ਨਾਲ ਨਹੀਂ ਮਿਲਦੀ" + +#: gio/gdbusconnection.c:5194 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "ਆਬਜੈਕਟ %s ਆਬਜੈਕਟ ਲਈ %s ਉੱਤੇ ਪਹਿਲਾਂ ਹੀ à¨à¨•ਸਪੋਰਟ ਕੀਤਾ ਗਿਆ ਹੈ" + +#: gio/gdbusconnection.c:5420 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to retrieve property %s.%s" +msgstr "ਸਾਕਟ ਬਣਾਉਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/gdbusconnection.c:5476 +#, fuzzy, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to set property %s.%s" +msgstr "ਸਾਕਟ ਬਣਾਉਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/gdbusconnection.c:5654 +#, c-format +#| msgid "Method '%s' returned type '%s', but expected '%s'" +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "ਢੰਗ “%s“ ਨੇ “%s“ ਕਿਸਮ ਵਾਪਸ ਕੀਤੀ, ਪਰ ਚਾਹੀਦੀ ਸੀ “%s“" + +#: gio/gdbusconnection.c:6729 +#, c-format +#| msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "ਇੰਟਰਫੇਸ “%2$s“ ਉੱਤੇ ਢੰਗ “%1$s“ ਦਸਤਖਤ “%3$s“ ਨਾਲ ਮੌਜੂਦ ਨਹੀਂ ਹੈ" + +#: gio/gdbusconnection.c:6850 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "ਸਬ-ਟਰੀ ਪਹਿਲਾਂ ਹੀ %s ਲਈ à¨à¨•ਸਪੋਰ ਕੀਤਾ ਜਾ ਚà©à©±à¨•ਿਆ ਹੈ" + +#: gio/gdbusmessage.c:1251 +msgid "type is INVALID" +msgstr "ਕਿਸਮ ਅਢà©à©±à¨•ਵੀਂ(INVALID) ਹੈ" + +#: gio/gdbusmessage.c:1262 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL ਸà©à¨¨à©‡à¨¹à¨¾: PATH ਜਾਂ MEMBER ਹੈੱਡਰ ਖੇਤਰ ਗà©à©°à¨® ਹੈ" + +#: gio/gdbusmessage.c:1273 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN ਸà©à¨¨à©‡à¨¹à¨¾: REPLY_SERIAL ਹੈੱਡਰ ਖੇਤਰ ਗà©à©°à¨® ਹੈ" + +#: gio/gdbusmessage.c:1285 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR ਸà©à¨¨à©‡à¨¹à¨¾: REPLY_SERIAL ਜਾਂ ERROR_NAME ਹੈੱਡਰ ਖੇਤਰ ਗà©à©°à¨® ਹੈ" + +#: gio/gdbusmessage.c:1298 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL ਸà©à¨¨à©‡à¨¹à¨¾: PATH, INTERFACE ਜਾਂ MEMBER ਹੈੱਡਰ ਖੇਤਰ ਮੌਜੂਦ ਨਹੀਂ" + +#: gio/gdbusmessage.c:1306 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL ਸà©à¨¨à©‡à¨¹à¨¾: PATH ਹੈੱਡਰ ਖੇਤਰ ਨੂੰ ਉਲਟ /org/freedesktop/DBus/Local ਮà©à©±à¨² ਨਾਲ" +" ਵਰਤਿਆ " +"ਜਾਂਦਾ ਹੈ।" + +#: gio/gdbusmessage.c:1314 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL ਸà©à¨¨à©‡à¨¹à¨¾: INTERFACE ਹੈੱਡਰ ਖੇਤਰ ਨੂੰ ਉਲਟ org.freedesktop.DBus.Local ਮà©à©±à¨²" +" ਨਾਲ ਵਰਤਿਆ " +"ਜਾਂਦਾ ਹੈ।" + +#: gio/gdbusmessage.c:1362 gio/gdbusmessage.c:1422 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu ਬਾਈਟ ਪੜà©à¨¹à¨¨ ਚਾਹੀਦੇ ਸਨ, ਪਰ %lu ਮਿਲੇ" +msgstr[1] "%lu ਬਾਈਟ ਪੜà©à¨¹à¨¨ ਚਾਹੀਦੇ ਸਨ, ਪਰ %lu ਮਿਲੇ" + +#: gio/gdbusmessage.c:1376 +#, c-format +#| msgid "Expected NUL byte after the string '%s' but found byte %d" +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "“%s“ ਲਾਈਨ ਦੇ ਬਾਅਦ NUL ਬਾਈਟ ਦੀ ਲੋੜ ਸੀ, ਪਰ %d ਬਾਈਟ ਮਿਲੇ" + +#: gio/gdbusmessage.c:1395 +#, c-format +#| msgid "" +#| "Expected valid UTF-8 string but found invalid bytes at byte offset %d " +#| "(length of string is %d). The valid UTF-8 string up until that point was " +#| "'%s'" +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"ਠੀਕ UTF-8 ਲਾਈਨ ਦੀ ਲੋੜ ਸੀ, ਪਰ ਬਾਈਟ ਆਫਸੈਟ %d ਉੱਤੇ ਗਲਤ ਬਾਈਟ ਮਿਲੇ (ਲਾਈਨ ਦੀ ਲੰਬਾਈ " +"%d)। " +"ਉਸ ਪà©à¨†à¨‡à©°à¨Ÿ ਤੱਕ ਠੀਕ UTF-8 ਲਾਈਨ “%s“ ਸੀ।" + +#: gio/gdbusmessage.c:1598 +#, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus object path" +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "ਪਾਰਸ ਕੀਤਾ ਮà©à©±à¨² “%s“ ਢà©à©±à¨•ਵਾਂ ਡੀ-ਬੱਸ ਆਬਜੈਕਟ ਪਾਥ ਨਹੀਂ ਹੈ" + +#: gio/gdbusmessage.c:1620 +#, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus signature" +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "ਪਾਰਸ ਕੀਤਾ ਮà©à©±à¨² “%s“ ਢà©à©±à¨•ਵਾਂ ਡੀ-ਬੱਸ ਦਸਤਖਤ ਨਹੀਂ ਹੈ" + +#: gio/gdbusmessage.c:1667 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"ਮਿਲੀ ਅਰੇ ਦੀ ਲੰਬਾਈ %u ਬਾਈਟ ਹੈ। ਵੱਧੋ-ਵੱਧ ਲੰਬਾਈ 2<<26 ਬਾਈਟ (64 MiB) ਹੈ।" +msgstr[1] "" +"ਮਿਲੀ ਅਰੇ ਦੀ ਲੰਬਾਈ %u ਬਾਈਟ ਹੈ। ਵੱਧੋ-ਵੱਧ ਲੰਬਾਈ 2<<26 ਬਾਈਟ (64 MiB) ਹੈ।" + +#: gio/gdbusmessage.c:1687 +#, c-format +#| msgid "" +#| "Encountered array of type 'a%c', expected to have a length a multiple of " +#| "%u bytes, but found to be %u bytes in length" +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"“a%c“ ਕਿਸਮ ਦੀ ਅਰੇ ਮਿਲੀ ਹੈ, %u ਬਾਈਟ ਦੇ ਗà©à¨£à¨¾à¨‚ਕ ਲੰਬਾਈ ਦੀ ਉਮੀਦ ਕੀਤੀ ਸੀ, ਪਰ %u" +" ਬਾਈਟ " +"ਲੰਬਾਈ ਹੀ ਮਿਲੀ।" + +#: gio/gdbusmessage.c:1857 +#, c-format +#| msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "ਵੇਰੀà¨à¨‚ਟ ਲਈ ਪਾਰਸ ਕੀਤਾ ਮà©à©±à¨² “%s“ ਢà©à©±à¨•ਵਾਂ ਡੀ-ਬੱਸ ਦਸਤਖਤ ਨਹੀਂ ਹੈ" + +#: gio/gdbusmessage.c:1881 +#, c-format +#| msgid "" +#| "Error deserializing GVariant with type string '%s' from the D-Bus wire " +#| "format" +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"GVariant ਨੂੰ type string “%s“ ਨਾਲ ਡੀ-ਬੱਸ ਵਾਇਰ ਫਾਰਮੈਟ 'ਚ ਗ਼ੈਰ-ਲੜੀਬੱਧ ਕਰਨ ਦੌਰਾਨ" +" ਗਲਤੀ" + +#: gio/gdbusmessage.c:2066 +#, c-format +#| msgid "" +#| "Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found " +#| "value 0x%02x" +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"ਗਲਤ endianness ਮà©à©±à¨²à¥¤ 0x6c (“l“) ਜਾਂ 0x42 (“B“) ਚਾਹੀਦਾ ਹੈ, ਪਰ ਮਿਲਿਆ ਮà©à©±à¨² 0x" +"%02x ਹੈ" + +#: gio/gdbusmessage.c:2079 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "ਗਲਤ ਮੇਜ਼ਰ ਪਰੋਟੋਕਾਲ ਵਰਜਨ ਹੈ। ਲੋੜ ਸੀ 1, ਪਰ ਮਿਲਿਆ %d" + +#: gio/gdbusmessage.c:2132 gio/gdbusmessage.c:2727 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2144 +#, c-format +#| msgid "Signature header with signature '%s' found but message body is empty" +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "ਦਸਤਖਤ “%s“ ਨਾਲ ਦਸਤਖਤ ਹੈੱਡਰ ਮਿਲਿਆ, ਪਰ ਸà©à¨¨à©‡à¨¹à¨¾ ਮà©à©±à¨– ਭਾਗ ਖਾਲੀ ਹੈ" + +#: gio/gdbusmessage.c:2159 +#, c-format +#| msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "ਪਾਰਸ ਕੀਤਾ ਮà©à©±à¨² “%s“ ਠੀਕ ਡੀ-ਬੱਸ ਦਸਤਖਤ ਨਹੀਂ ਹਨ (ਮà©à©±à¨– ਭਾਗ ਲਈ)" + +#: gio/gdbusmessage.c:2190 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "ਸà©à¨¨à©‡à¨¹à©‡ 'ਚ ਕੋਈ ਦਸਤਖਤ ਹੈੱਡਰ ਨਹੀਂ ਹੈ, ਪਰ ਸà©à¨¨à©‡à¨¹à¨¾ ਮà©à©±à¨– ਭਾਗ 'ਚ %u ਬਾਈਟ ਹਨ" +msgstr[1] "ਸà©à¨¨à©‡à¨¹à©‡ 'ਚ ਕੋਈ ਦਸਤਖਤ ਹੈੱਡਰ ਨਹੀਂ ਹੈ, ਪਰ ਸà©à¨¨à©‡à¨¹à¨¾ ਮà©à©±à¨– ਭਾਗ 'ਚ %u ਬਾਈਟ ਹਨ" + +#: gio/gdbusmessage.c:2200 +msgid "Cannot deserialize message: " +msgstr "ਸà©à¨¨à©‡à¨¹à¨¾ ਡੀਸੀਰੀਅਲਾਈਜ਼ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ: " + +#: gio/gdbusmessage.c:2544 +#, c-format +#| msgid "" +#| "Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"GVariant ਨੂੰ type string “%s“ ਨਾਲ ਡੀ-ਬੱਸ ਵਾਇਰ ਫਾਰਮੈਟ 'ਚ ਲੜੀਬੱਧ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ" + +#: gio/gdbusmessage.c:2681 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" + +#: gio/gdbusmessage.c:2689 +msgid "Cannot serialize message: " +msgstr "ਸà©à¨¨à©‡à¨¹à¨¾ ਲੜੀਬੱਧ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ: " + +#: gio/gdbusmessage.c:2742 +#, c-format +#| msgid "Message body has signature '%s' but there is no signature header" +msgid "Message body has signature “%s†but there is no signature header" +msgstr "ਸà©à¨¨à©‡à¨¹à¨¾ ਮà©à©±à¨– ਭਾਗ 'ਚ ਦਸਤਖਤ “%s“ ਹਨ, ਪਰ ਹੈੱਡਰ ਲਈ ਕੋਈ ਦਸਤਖਤ ਨਹੀਂ" + +#: gio/gdbusmessage.c:2752 +#, c-format +#| msgid "" +#| "Message body has type signature '%s' but signature in the header field is " +#| "'%s'" +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"ਸà©à¨¨à©‡à¨¹à¨¾ ਮà©à©±à¨– ਭਾਗ 'ਚ “%s“ ਕਿਸਮ ਦੇ ਦਸਤਖਤ ਹਨ, ਪਰ ਹੈੱਡਰ ਖੇਤਰ 'ਚ ਦਸਤਖਤ “%s“ ਹਨ" + +#: gio/gdbusmessage.c:2768 +#, c-format +#| msgid "Message body is empty but signature in the header field is '(%s)'" +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "ਸà©à¨¨à©‡à¨¹à¨¾ ਦਾ ਮà©à©±à¨– ਭਾਗ ਖਾਲੀ ਹੈ, ਪਰ ਹੈੱਡਰ ਖੇਤਰ 'ਚ “(%s)“ ਦਸਤਖਤ ਹਨ" + +#: gio/gdbusmessage.c:3321 +#, c-format +#| msgid "Error return with body of type '%s'" +msgid "Error return with body of type “%sâ€" +msgstr "“%s“ ਕਿਸਮ ਦੇ ਮà©à©±à¨– ਭਾਗ ਨੇ ਗਲਤੀ ਵਾਪਸ ਕੀਤੀ" + +#: gio/gdbusmessage.c:3329 +msgid "Error return with empty body" +msgstr "ਗਲਤੀ ਨੇ ਖਾਲੀ ਭਾਗ ਦਿੱਤਾ" + +#: gio/gdbusprivate.c:2243 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(ਇਹ ਵਿੰਡੋ ਬੰਦ ਕਰਨ ਲਈ ਕੋਈ ਅੱਖਰ ਲਿਖੋ)\n" + +#: gio/gdbusprivate.c:2417 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "ਸ਼ੈਸ਼ਨ ਡੀਬਸ ਚੱਲ ਨਹੀਂ ਰਹੀ ਹੈ, ਅਤੇ ਆਪੇ-ਸ਼à©à¨°à©‚ ਫੇਲà©à¨¹ ਹੈ" + +#: gio/gdbusprivate.c:2440 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "ਹਾਰਡਵੇਅਰ ਪਰੋਫਾਇਲ ਲੈਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/gdbusprivate.c:2485 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "/var/lib/dbus/machine-id ਜਾਂ /etc/machine-id ਲੋਡ ਕਰਨ ਲਈ ਅਸਮਰੱਥ: " + +#: gio/gdbusproxy.c:1625 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s ਲਈ StartServiceByName ਕਾਲ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: " + +#: gio/gdbusproxy.c:1648 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "StartServiceByName(\"%2$s\") ਢੰਗ ਤੋਂ ਗਲਤ ਜਵਾਬ %1$d" + +#: gio/gdbusproxy.c:2748 gio/gdbusproxy.c:2883 +#, c-format +#| msgid "" +#| "Cannot invoke method; proxy is for a well-known name without an owner and " +#| "proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"ਢੰਗ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ; ਪਰਾਕਸੀ ਜਾਣੇ-ਪਛਾਣੇ ਨਾਂ %s ਨਾਲ ਬਿਨਾਂ ਓਨਰ ਦੇ ਪਰਾਕਸੀ" +" ਹੈ ਅਤੇ " +"ਪਰਾਕਸੀ ਨੂੰ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START ਫਲੈਗ ਨਾਲ ਬਣਾਇਆ ਗਿਆ।" + +#: gio/gdbusserver.c:746 +#, fuzzy +#| msgid "Abstract name space not supported" +msgid "Abstract namespace not supported" +msgstr "Abstract ਨਾਂ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" + +#: gio/gdbusserver.c:839 +msgid "Cannot specify nonce file when creating a server" +msgstr "ਜਦੋਂ ਸਰਵਰ ਬਣਾਉਣਾ ਹੋਵੇ ਤਾਂ nonce ਫਾਇਲ ਨਹੀਂ ਦਿੱਤੀ ਜਾ ਸਕਦੀ" + +#: gio/gdbusserver.c:921 +#, c-format +#| msgid "Error writing nonce file at '%s': %s" +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "“%s“ ਉੱਤੇ nonce ਫਾਇਲ ਲਿਖਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gdbusserver.c:1094 +#, c-format +#| msgid "The string '%s' is not a valid D-Bus GUID" +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "ਲਾਈਨ “%s“ ਢà©à©±à¨•ਵਾਂ ਡੀ-ਬੱਸ GUID ਨਹੀਂ ਹੈ" + +#: gio/gdbusserver.c:1134 +#, c-format +#| msgid "Cannot listen on unsupported transport '%s'" +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "ਗ਼ੈਰ-ਸਹਾਇਕ ਟਰਾਂਸਪੋਰਟ “%s“ ਉੱਤੇ ਸà©à¨£à¨¿à¨† ਨਹੀਂ ਜਾ ਸਕਦਾ" + +#: gio/gdbus-tool.c:107 +#, c-format +#| msgid "" +#| "Commands:\n" +#| " help Shows this information\n" +#| " introspect Introspect a remote object\n" +#| " monitor Monitor a remote object\n" +#| " call Invoke a method on a remote object\n" +#| " emit Emit a signal\n" +#| "\n" +#| "Use \"%s COMMAND --help\" to get help on each command.\n" +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" + +#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336 +#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:846 gio/gdbus-tool.c:1183 +#: gio/gdbus-tool.c:1668 +#, c-format +msgid "Error: %s\n" +msgstr "ਗਲਤੀ: %s\n" + +#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1684 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "XML ਇੰਟਰੋਸਪੈਕਸ਼ਨ ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਗਲਤੀ: %s\n" + +#: gio/gdbus-tool.c:246 +#, c-format +#| msgid "Error: %s is not a valid member name\n" +msgid "Error: %s is not a valid name\n" +msgstr "ਗਲਤੀ: %s ਢà©à©±à¨•ਵਾਂ ਨਾਂ ਨਹੀਂ ਹੈ\n" + +#: gio/gdbus-tool.c:394 +msgid "Connect to the system bus" +msgstr "ਸਿਸਟਮ ਬਸ ਨਾਲ ਕà©à¨¨à©ˆà¨•ਟ ਕਰੋ" + +#: gio/gdbus-tool.c:395 +msgid "Connect to the session bus" +msgstr "ਸ਼ੈਸ਼ਨ ਬੱਸ ਨਾਲ ਕà©à¨¨à©ˆà¨•ਟ ਕਰੋ" + +#: gio/gdbus-tool.c:396 +msgid "Connect to given D-Bus address" +msgstr "ਦਿੱਤੇ ਡੀ-ਬੱਸ à¨à¨¡à¨°à©ˆà©±à¨¸ ਨਾਲ ਕà©à¨¨à©ˆà¨•ਟ" + +#: gio/gdbus-tool.c:406 +msgid "Connection Endpoint Options:" +msgstr "ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਅੰਤ-ਪà©à¨†à¨‡à©°à¨Ÿ ਚੋਣਾਂ:" + +#: gio/gdbus-tool.c:407 +msgid "Options specifying the connection endpoint" +msgstr "ਚੋਣਾਂ ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਅੰਤ-ਪà©à¨†à¨‡à©°à¨Ÿ ਦਿੰਦੀਆਂ ਹਨ" + +#: gio/gdbus-tool.c:429 +#, c-format +msgid "No connection endpoint specified" +msgstr "ਕੋਈ ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਅੰਤ ਪà©à¨†à¨‡à©°à¨Ÿ ਨਹੀਂ ਦਿੱਤਾ" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "ਕਈ ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਅੰਤ-ਪà©à¨†à¨‡à©°à¨Ÿ ਦਿੱਤੇ ਗà¨" + +#: gio/gdbus-tool.c:509 +#, c-format +#| msgid "" +#| "Warning: According to introspection data, interface '%s' does not exist\n" +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "ਸਾਵਧਾਨ: ਇੰਟਰੋਸਪੈਕਸ਼ਨ ਡਾਟੇ ਦੇ ਮà©à¨¤à¨¾à¨¬à¨•, ਇੰਟਰਫੇਸ “%s“ ਮੌਜੂਦ ਨਹੀਂ ਹੈ।\n" + +#: gio/gdbus-tool.c:518 +#, c-format +#| msgid "" +#| "Warning: According to introspection data, method '%s' does not exist on " +#| "interface '%s'\n" +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"ਸਾਵਧਾਨ: ਇੰਟਰੋਸਪੈਕਸ਼ਨ ਡਾਟੇ ਦੇ ਮà©à¨¤à¨¾à¨¬à¨•, ਢੰਗ “%s“ ਇੰਟਰਫੇਸ “%s“ ਉੱਤੇ ਮੌਜੂਦ ਨਹੀਂ" +" ਹੈ।\n" + +#: gio/gdbus-tool.c:580 +msgid "Optional destination for signal (unique name)" +msgstr "ਸਿਗਨਲ ਲਈ ਚੋਣਵਾਂ ਟਿਕਾਣਾ (ਵਿਲੱਖਣ ਨਾਂ)" + +#: gio/gdbus-tool.c:581 +msgid "Object path to emit signal on" +msgstr "ਨਿਕਲੇ ਸਿਗਨਲ ਲਈ ਆਬਜੈਕਟ ਮਾਰਗ" + +#: gio/gdbus-tool.c:582 +msgid "Signal and interface name" +msgstr "ਸਿਗਨਲ ਅਤੇ ਇੰਟਰਫੇਸ ਨਾਂ" + +#: gio/gdbus-tool.c:615 +msgid "Emit a signal." +msgstr "ਨਿਕਲਿਆਂ ਸਿਗਨਲ।" + +#: gio/gdbus-tool.c:670 gio/gdbus-tool.c:977 gio/gdbus-tool.c:1771 +#: gio/gdbus-tool.c:2003 gio/gdbus-tool.c:2223 +#, c-format +msgid "Error connecting: %s\n" +msgstr "ਕà©à¨¨à©ˆà¨•ਟ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s\n" + +#: gio/gdbus-tool.c:690 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "ਗਲਤੀ: %s ਢà©à©±à¨•ਵਾਂ ਵਿਲੱਖਣ ਬਸ ਨਾਂ ਨਹੀਂ ਹੈ।\n" + +#: gio/gdbus-tool.c:709 gio/gdbus-tool.c:1020 gio/gdbus-tool.c:1814 +msgid "Error: Object path is not specified\n" +msgstr "ਗਲਤੀ: ਆਬਜੈਕਟ ਪਾਥ ਨਹੀਂ ਦਿੱਤਾ\n" + +#: gio/gdbus-tool.c:732 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1834 +#: gio/gdbus-tool.c:2074 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "ਗਲਤੀ: %s ਢà©à©±à¨•ਵਾਂ ਆਬਜੈਕਟ ਪਾਥ ਨਹੀਂ ਹੈ\n" + +#: gio/gdbus-tool.c:752 +#| msgid "Error: Method name is not specified\n" +msgid "Error: Signal name is not specified\n" +msgstr "ਗਲਤੀ: ਸਿਗਨਲ ਨਾਂ ਨਹੀਂ ਦਿੱਤਾ ਗਿਆ।\n" + +#: gio/gdbus-tool.c:766 +#, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Signal name “%s†is invalid\n" +msgstr "ਗਲਤੀ: ਸਿਗਨਲ ਨਾਂ “%s“ ਢà©à©±à¨•ਵਾਂ ਨਹੀਂ\n" + +#: gio/gdbus-tool.c:778 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "ਗਲਤੀ: %s ਢà©à©±à¨•ਵਾਂ ਇੰਟਰਫੇਸ ਨਾਂ ਨਹੀਂ ਹੈ\n" + +#: gio/gdbus-tool.c:784 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "ਗਲਤੀ: %s ਢà©à©±à¨•ਵਾਂ ਮੈਂਬਰ ਨਾਂ ਨਹੀਂ ਹੈ\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:821 gio/gdbus-tool.c:1152 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%d ਪੈਰਾਮੀਟਰ ਪਾਰਸ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s\n" + +#: gio/gdbus-tool.c:853 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਖਤਮ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s\n" + +#: gio/gdbus-tool.c:880 +msgid "Destination name to invoke method on" +msgstr "ਸ਼ਾਮਲ ਢੰਗ ਲਈ ਟਿਕਾਣਾ ਨਾਂ" + +#: gio/gdbus-tool.c:881 +msgid "Object path to invoke method on" +msgstr "ਇਸ ਉੱਤੇ ਸ਼ਾਮਲ ਢੰਗ ਲਈ ਆਬਜੈਕਟ ਪਾਥ" + +#: gio/gdbus-tool.c:882 +msgid "Method and interface name" +msgstr "ਢੰਗ ਤੇ ਇੰਟਰਫੇਸ ਨਾਂ" + +#: gio/gdbus-tool.c:883 +msgid "Timeout in seconds" +msgstr "ਟਾਈਮ-ਆਉਟ ਸਕਿੰਟਾਂ ਵਿੱਚ" + +#: gio/gdbus-tool.c:922 +msgid "Invoke a method on a remote object." +msgstr "ਰਿਮੋਟ ਆਬਜੈਕਟ ਉੱਤੇ ਢੰਗ ਸ਼ਾਮਲ" + +#: gio/gdbus-tool.c:994 gio/gdbus-tool.c:1788 gio/gdbus-tool.c:2028 +msgid "Error: Destination is not specified\n" +msgstr "ਗਲਤੀ: ਟਿਕਾਣਾ ਨਹੀਂ ਦਿੱਤਾ ਗਿਆ\n" + +#: gio/gdbus-tool.c:1005 gio/gdbus-tool.c:1805 gio/gdbus-tool.c:2039 +#, c-format +#| msgid "Error: %s is not a valid member name\n" +msgid "Error: %s is not a valid bus name\n" +msgstr "ਗਲਤੀ: %s ਢà©à©±à¨•ਵਾਂ ਵਿਲੱਖਣ ਬਸ ਨਾਂ ਨਹੀਂ ਹੈ।\n" + +#: gio/gdbus-tool.c:1055 +msgid "Error: Method name is not specified\n" +msgstr "ਗਲਤੀ: ਢੰਘ ਨਾਂ ਨਹੀਂ ਦਿੱਤਾ \n" + +#: gio/gdbus-tool.c:1066 +#, c-format +#| msgid "Error: Method name '%s' is invalid\n" +msgid "Error: Method name “%s†is invalid\n" +msgstr "ਗਲਤੀ: ਢੰਗ ਨਾਂ “%s“ ਢà©à©±à¨•ਵਾਂ ਨਹੀਂ\n" + +#: gio/gdbus-tool.c:1144 +#, c-format +#| msgid "Error parsing parameter %d of type '%s': %s\n" +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "“%2$s“ ਕਿਸਮ ਦੇ %1$d ਪੈਰਾਮੀਟਰ ਪਾਰਸ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %3$s\n" + +#: gio/gdbus-tool.c:1630 +msgid "Destination name to introspect" +msgstr "ਇੰਟਰਸਪੈਕਟ ਲਈ ਟਿਕਾਣਾ ਨਾਂ" + +#: gio/gdbus-tool.c:1631 +msgid "Object path to introspect" +msgstr "ਇੰਟਰਸਪੈਕਟ ਲਈ ਆਬਜੈਕਟ ਪਾਥ" + +#: gio/gdbus-tool.c:1632 +msgid "Print XML" +msgstr "XML ਪਰਿੰਟ ਕਰੋ" + +#: gio/gdbus-tool.c:1633 +msgid "Introspect children" +msgstr "ਆਪਸ ਵਿੱਚ ਜà©à©œà©‡ ਚਾਈਲਡ" + +#: gio/gdbus-tool.c:1634 +msgid "Only print properties" +msgstr "ਕੇਵਲ ਪà©à¨°à¨¿à©°à¨Ÿ ਵਿਸ਼ੇਸ਼ਤਾ" + +#: gio/gdbus-tool.c:1723 +msgid "Introspect a remote object." +msgstr "ਰਿਮੋਟ ਆਬਜੈਕਟ ਇੰਟਰਸਪੈਕਟ ਕਰੋ।" + +#: gio/gdbus-tool.c:1929 +msgid "Destination name to monitor" +msgstr "ਨਿਗਰਾਨੀ ਲਈ ਟਿਕਾਣਾ ਨਾਂ" + +#: gio/gdbus-tool.c:1930 +msgid "Object path to monitor" +msgstr "ਨਿਗਰਾਨੀ ਲਈ ਆਬਜੈਕਟ ਨਾਂ" + +#: gio/gdbus-tool.c:1955 +msgid "Monitor a remote object." +msgstr "ਰਿਮੋਟ ਆਬਜੈਕਟ ਦੀ ਨਿਗਰਾਨੀ।" + +#: gio/gdbus-tool.c:2013 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: gio/gdbus-tool.c:2137 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" + +#: gio/gdbus-tool.c:2140 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" + +#: gio/gdbus-tool.c:2188 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPTION…] BUS-NAME" + +#: gio/gdbus-tool.c:2189 +msgid "Wait for a bus name to appear." +msgstr "" + +#: gio/gdbus-tool.c:2265 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to activate for must be specified.\n" +msgstr "ਗਲਤੀ: ਆਬਜੈਕਟ ਪਾਥ ਨਹੀਂ ਦਿੱਤਾ\n" + +#: gio/gdbus-tool.c:2270 +#, fuzzy +#| msgid "Error: object path not specified.\n" +msgid "Error: A service to wait for must be specified.\n" +msgstr "ਗਲਤੀ: ਆਬਜੈਕਟ ਪਾਥ ਨਹੀਂ ਦਿੱਤਾ\n" + +#: gio/gdbus-tool.c:2275 +msgid "Error: Too many arguments.\n" +msgstr "ਗਲਤੀ: ਕੋਈ ਆਰਗੂਮੈਂਟ ਹਨ।\n" + +#: gio/gdbus-tool.c:2283 gio/gdbus-tool.c:2290 +#, c-format +#| msgid "Error: %s is not a valid unique bus name.\n" +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "ਗਲਤੀ: %s ਢà©à©±à¨•ਵਾਂ ਜਾਣਿਆ-ਪਛਾਣਿਆ ਬਸ ਨਾਂ ਨਹੀਂ ਹੈ।\n" + +#: gio/gdesktopappinfo.c:2045 gio/gdesktopappinfo.c:4843 +msgid "Unnamed" +msgstr "ਬਿਨ-ਨਾਂ" + +#: gio/gdesktopappinfo.c:2455 +#| msgid "Desktop file didn't specify Exec field" +msgid "Desktop file didn’t specify Exec field" +msgstr "ਡੈਸਕਟਾਪ ਫਾਇਲ ਨੇ Exec ਫੀਲਡ ਨਹੀਂ ਦਿੱਤਾ ਹੈ" + +#: gio/gdesktopappinfo.c:2727 +msgid "Unable to find terminal required for application" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਲਈ ਟਰਮੀਨਲ ਲੋੜ ਲੱਭਣ ਲਈ ਅਸਮਰੱਥ ਹੈ" + +#: gio/gdesktopappinfo.c:3379 +#, c-format +#| msgid "Can't create user application configuration folder %s: %s" +msgid "Can’t create user application configuration folder %s: %s" +msgstr "ਵਰਤੋਂਕਾਰ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਸੰਰਚਨਾ ਫੋਲਡਰ %s ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ: %s" + +#: gio/gdesktopappinfo.c:3383 +#, c-format +#| msgid "Can't create user MIME configuration folder %s: %s" +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "ਵਰਤੋਂਕਾਰ MIME ਸੰਰਚਨਾ ਫੋਲਡਰ %s ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ: %s" + +#: gio/gdesktopappinfo.c:3623 gio/gdesktopappinfo.c:3647 +msgid "Application information lacks an identifier" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਜਾਣਕਾਰੀ ਲਈ ਪਛਾਣਕਰਤਾ ਦੀ ਕਮੀ ਹੈ" + +#: gio/gdesktopappinfo.c:3881 +#, c-format +#| msgid "Can't create user desktop file %s" +msgid "Can’t create user desktop file %s" +msgstr "ਵਰਤੋਂਕਾਰ ਡੈਸਕਟਾਪ ਫਾਇਲ %s ਬਣਾਈ ਨਹੀਂ ਜਾ ਸਕਦੀ" + +#: gio/gdesktopappinfo.c:4015 +#, c-format +msgid "Custom definition for %s" +msgstr "%s ਲਈ ਕਸਟਮ ਪਰਿਭਾਸ਼ਾ" + +#: gio/gdrive.c:417 +#| msgid "drive doesn't implement eject" +msgid "drive doesn’t implement eject" +msgstr "ਡਰਾਇਵ ਲਈ ਬਾਹਰ ਕੱਢਣਾ ਨਹੀਂ ਬਣਾਇਆ" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +#| msgid "drive doesn't implement eject or eject_with_operation" +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "ਡਰਾਇਵ eject ਜਾਂ eject_with_operation ਸਥਾਪਿਤ ਨਹੀਂ ਹੈ।" + +#: gio/gdrive.c:571 +#| msgid "drive doesn't implement polling for media" +msgid "drive doesn’t implement polling for media" +msgstr "ਮੀਡਿਆ ਪੋਲਿੰਗ ਲਈ ਡਰਾਇਵ ਹਾਲੇ ਸਥਾਪਤ ਨਹੀਂ" + +#: gio/gdrive.c:778 +#| msgid "drive doesn't implement start" +msgid "drive doesn’t implement start" +msgstr "ਡਰਾਇਵਹ start ਹਾਲੇ ਸਥਾਪਿਤ ਨਹੀਂ ਹੈ" + +#: gio/gdrive.c:880 +#| msgid "drive doesn't implement stop" +msgid "drive doesn’t implement stop" +msgstr "ਡਰਾਇਵ stop ਸਥਾਪਿਤ ਨਹੀਂ ਹੈ" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:317 +#: gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "TLS ਸਹਿਯੋਗ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ" + +#: gio/gdummytlsbackend.c:419 +#| msgid "TLS support is not available" +msgid "DTLS support is not available" +msgstr "DTLS ਸਹਿਯੋਗ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ" + +#: gio/gemblem.c:323 +#, c-format +#| msgid "Can't handle version %d of GEmblem encoding" +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "GEmblem ਇੰਕੋਡਿੰਗ ਦਾ %d ਵਰਜਨ ਹੈਂਡਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem ਇੰਕੋਡਿੰਗ ਵਿੱਚ ਨਿਕਾਰਾ ਟੋਕਨਾਂ ਦੀ ਗਿਣਤੀ (%d)" + +#: gio/gemblemedicon.c:362 +#, c-format +#| msgid "Can't handle version %d of GEmblemedIcon encoding" +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "GThemedIcon ਇੰਕੋਡਿੰਗ ਦਾ %d ਵਰਜਨ ਹੈਂਡਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon ਇੰਕੋਡਿੰਗ ਵਿੱਚ ਨਿਕਾਰਾ ਟੋਕਨਾਂ ਦੀ ਗਿਣਤੀ (%d)" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon ਲਈ GEmblem ਦੀ ਲੋੜ ਸੀ" + +#: gio/gfile.c:1076 gio/gfile.c:1314 gio/gfile.c:1452 gio/gfile.c:1690 +#: gio/gfile.c:1745 gio/gfile.c:1803 gio/gfile.c:1887 gio/gfile.c:1944 +#: gio/gfile.c:2008 gio/gfile.c:2063 gio/gfile.c:3739 gio/gfile.c:3794 +#: gio/gfile.c:4030 gio/gfile.c:4072 gio/gfile.c:4540 gio/gfile.c:4951 +#: gio/gfile.c:5036 gio/gfile.c:5126 gio/gfile.c:5223 gio/gfile.c:5310 +#: gio/gfile.c:5411 gio/gfile.c:8115 gio/gfile.c:8205 gio/gfile.c:8289 +#: gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "ਓਪਰੇਸ਼ਨ ਸਹਾਇਕ ਨਹੀਂ" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1575 +msgid "Containing mount does not exist" +msgstr "ਰੱਖਣ ਵਾਲਾ ਮਾਊਂਟ ਮੌਜੂਦ ਨਹੀਂ" + +#: gio/gfile.c:2622 gio/glocalfile.c:2446 +#| msgid "Can't copy over directory" +msgid "Can’t copy over directory" +msgstr "ਡਾਇਰੈਕਟਰੀ ਉੱਤੇ ਕਾਪੀ ਨਹੀਂ ਹੋ ਸਕਦਾ" + +#: gio/gfile.c:2682 +#| msgid "Can't copy directory over directory" +msgid "Can’t copy directory over directory" +msgstr "ਡਾਇਰੈਕਟਰੀ ਡਾਇਰੈਕਟਰੀ ਉੱਤੇ ਕਾਪੀ ਨਹੀਂ ਹੋ ਸਕਦੀ" + +#: gio/gfile.c:2690 +msgid "Target file exists" +msgstr "ਟਾਰਗੇਟ ਫਾਇਲ ਮੌਜੂਦ ਹੈ" + +#: gio/gfile.c:2709 +#| msgid "Can't recursively copy directory" +msgid "Can’t recursively copy directory" +msgstr "ਡਾਇਰੈਕਟਰੀ ਲਗਾਤਾਰ ਕਾਪੀ ਨਹੀਂ ਹੋ ਸਕਦੀ" + +#: gio/gfile.c:2984 +msgid "Splice not supported" +msgstr "ਸਪਲਿਸ ਸਕਾਇਕ ਨਹੀਂ" + +#: gio/gfile.c:2988 gio/gfile.c:3033 +#, c-format +msgid "Error splicing file: %s" +msgstr "ਸਪਲਿਸ ਫਾਇਲ ਗਲਤੀ: %s " + +#: gio/gfile.c:3149 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "ਮਾਊਂਟ ਵਿੱਚ ਕਾਪੀ (ਮà©à©œ-ਲਿੰਕ/ਕਲੋਨ) ਕਰਨਾ ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#: gio/gfile.c:3153 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr " ਕਾਪੀ (ਮà©à©œ-ਲਿੰਕ/ਕਲੋਨ) ਕਰਨਾ ਸਹਿਯੋਗੀ ਨਹੀਂ ਜਾਂ ਗਲਤ ਹੈ" + +#: gio/gfile.c:3158 +#| msgid "Copy (reflink/clone) is not supported or didn't work" +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr " ਕਾਪੀ (ਮà©à©œ-ਲਿੰਕ/ਕਲੋਨ) ਕਰਨਾ ਸਹਿਯੋਗੀ ਨਹੀਂ ਜਾਂ ਕੰਮ ਨਹੀਂ ਕਰਦਾ" + +#: gio/gfile.c:3221 +#| msgid "Can't copy special file" +msgid "Can’t copy special file" +msgstr "ਖਾਸ ਫਾਇਲ ਕਾਪੀ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ" + +#: gio/gfile.c:4020 +msgid "Invalid symlink value given" +msgstr "ਗਲਤ ਸਿੰਬੋਲਿੰਕ ਮà©à©±à¨² ਦਿੱਤਾ" + +#: gio/gfile.c:4181 +msgid "Trash not supported" +msgstr "ਰੱਦ ਸਹਾਇਕ ਨਹੀਂ" + +#: gio/gfile.c:4293 +#, c-format +#| msgid "File names cannot contain '%c'" +msgid "File names cannot contain “%câ€" +msgstr "ਫਾਇਲ ਨਾਂਵਾਂ ਵਿੱਚ “%c†ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ" + +#: gio/gfile.c:6774 gio/gvolume.c:364 +#| msgid "volume doesn't implement mount" +msgid "volume doesn’t implement mount" +msgstr "ਵਾਲੀਅਮ ਲਈ ਮਾਊਂਟ ਸਥਾਪਤ ਨਹੀਂ ਹੈ" + +#: gio/gfile.c:6885 gio/gfile.c:6931 +msgid "No application is registered as handling this file" +msgstr "ਇਹ ਫਾਇਲ ਹੈਂਡਲ ਕਰਨ ਲਈ ਕੋਈ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਰਜਿਸਟਰ ਨਹੀਂ ਹੈ" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "ਈਨੂਮੀਟਰੇਟਰ ਬੰਦ ਹੈ" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ਫਾਇਲ ਈਨੂਮੀਟਰੇਟਰ ਗੰਭੀਰ ਕਾਰਵਾਈ ਕਰ ਚà©à©±à¨•ਾ ਹੈ" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ਫਾਇਲ ਈਨੂਮੀਟਰੇਟਰ ਪਹਿਲਾਂ ਹੀ ਬੰਦ ਹੈ" + +#: gio/gfileicon.c:236 +#, c-format +#| msgid "Can't handle version %d of GFileIcon encoding" +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "GFileIcon ਇੰਕੋਡਿੰਗ ਦਾ %d ਵਰਜਨ ਹੈਂਡਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon ਲਈ ਨਿਕਾਰਾ ਇੰਪà©à©±à¨Ÿ ਡਾਟਾ" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +#| msgid "Stream doesn't support query_info" +msgid "Stream doesn’t support query_info" +msgstr "ਸਟਰੀਮ query_info ਲਈ ਸਹਾਇਕ ਨਹੀਂ" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ਸਟਰੀਮ ਉੱਤੇ ਸੀਕ ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ਇੰਪà©à©±à¨Ÿ ਸਟਰੀਮ ਉੱਤੇ ਟਰਾਂਸਕੇਟ ਮਨਜ਼ੂਰ ਨਹੀਂ" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "ਸਟਰੀਮ ਉੱਤੇ ਟਰਾਂਸਕੇਟ ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:386 gio/gresolver.c:538 +#: glib/gconvert.c:1777 +msgid "Invalid hostname" +msgstr "ਗਲਤ ਹੋਸਟ-ਨਾਂ" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "ਖ਼ਰਾਬ HTTP ਪਰਾਕਸੀ ਜਵਾਬ" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP ਪਰਾਕਸੀ ਕਨੈਕਸ਼ਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP ਪਰਾਕਸੀ ਪਰਮਾਣਕਿਤਾ ਫੇਲà©à¨¹ ਹੋਈ" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP ਪਰਾਕਸੀ ਪਰਮਾਣਕਿਤਾ ਚਾਹੀਦੀ ਹੈ" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP ਪਰਾਕਸੀ ਕਨੈਕਸ਼ਨ ਫੇਲà©à¨¹ ਹੈ: %i" + +#: gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP ਪਰਾਕਸੀ ਸਰਵਰ ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ।" + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "ਟੋਕਨਾਂ ਦੀ ਗਲਤ ਗਿਣਤੀ (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "ਕਲਾਸ ਨਾਂ %s ਲਈ ਕੋਈ ਟਾਈਪ ਨਹੀਂ" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "ਟਾਈਪ %s GIcon ਇੰਟਰਫੇਸ ਲਈ ਸਥਾਪਿਤ ਨਹੀਂ" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "ਟਾਈਪ %s ਕਲਾਸ ਨਹੀਂ ਹੈ" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "ਨਿਕਾਰਾ ਵਰਜਨ ਨੰਬਰ: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "ਟਾਈਪ %s GIcon ਇੰਟਰਫੇਸ ਉੱਤੇ from_tokens() ਸਥਾਪਨ ਚਾਹੀਦਾ ਨਹੀਂ" + +#: gio/gicon.c:469 +#| msgid "Can't handle the supplied version of the icon encoding" +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "ਆਈਕਾਨ ਇੰਕੋਡਿੰਗ ਦਾ ਦਿੱਤਾ ਵਰਜਨ ਨੰਬਰ ਹੈਂਡਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "ਕੋਈ à¨à¨¡à¨°à©ˆà¨¸ ਨਹੀਂ ਦਿੱਤਾ" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "ਲੰਬਾਈ %u à¨à¨¡à¨°à©ˆà¨¸ ਲਈ ਬਹà©à¨¤ ਲੰਮੀ ਹੈ" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "à¨à¨¡à¨°à©ˆà¨¸ ਨੇ ਪà©à¨°à©€-ਫਿਕਸ ਲੰਬਾਈ ਤੋਂ ਵੱਧ ਬਿੱਟ ਸੈੱਟ ਕੀਤੇ ਹਨ" + +#: gio/ginetaddressmask.c:300 +#, c-format +#| msgid "Could not parse '%s' as IP address mask" +msgid "Could not parse “%s†as IP address mask" +msgstr "“%s†ਨੂੰ IP à¨à¨¡à¨°à©ˆà¨¸ ਮਾਸਕ ਵਜੋਂ ਪਾਰਸ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:220 +msgid "Not enough space for socket address" +msgstr "ਸਾਕਟ à¨à¨¡à¨°à©ˆà©±à¨¸ ਲਈ ਲੋੜੀਦੀ ਥਾਂ ਨਹੀਂ" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "ਗ਼ੈਰ-ਸਹਾਇਕ ਸਾਕਟ à¨à¨¡à¨°à©ˆà©±à¨¸" + +#: gio/ginputstream.c:188 +#| msgid "Input stream doesn't implement read" +msgid "Input stream doesn’t implement read" +msgstr "ਇੰਪà©à©±à¨Ÿ ਸਟਰੀਮ ਹਾਲੇ ਪੜà©à¨¹à¨¨ ਲਈ ਨਹੀਂ ਹੈ" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "ਸਟਰੀਮ ਪਹਿਲਾਂ ਹੀ ਕਾਰਵਾਈ ਅਧੀਨ ਹੈ" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "ਫਾਇਲ ਨਾਲ ਕਾਪੀ ਕਰੋ" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "ਜਦੋਂ ਭੇਜਿਆ ਜਾਵੇ ਤਾਂ ਫਾਇਲ ਰੱਖੋ" + +#: gio/gio-tool.c:205 +#| msgid "" +#| "'%s' takes no arguments\n" +#| "\n" +msgid "“version†takes no arguments" +msgstr "“version†ਲਈ ਕੋਈ ਆਰਗੂਮੈਂਟ ਨਹੀਂ ਹà©à©°à¨¦à¨¾" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:864 +msgid "Usage:" +msgstr "ਵਰਤੋਂ:" + +#: gio/gio-tool.c:210 +#| msgid "Print version information and exit" +msgid "Print version information and exit." +msgstr "ਵਰਜ਼ਨ ਜਾਣਕਾਰੀ ਛਾਪੋ ਅਤੇ ਬੰਦ ਕਰੋ।" + +#: gio/gio-tool.c:226 +#| msgid "Commands:\n" +msgid "Commands:" +msgstr "ਕਮਾਂਡਾਂ:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "ਇੱਕ ਜਾਂ ਵੱਧ ਫਾਇਲਾਂ ਦੀ ਕਾਪੀ ਕਰੋ" + +#: gio/gio-tool.c:231 +#| msgid "Show GApplication options" +msgid "Show information about locations" +msgstr "ਟਿਕਾਣੇ ਲਈ ਜਾਣਕਾਰੀ ਵੇਖੋ" + +#: gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "ਟਿਕਾਣਿਆਂ ਦੀ ਸਮੱਗਰੀ ਸੂਚੀਬੱਧ ਕਰੋ" + +#: gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "ਮਾਈਮ-ਕਿਸਮ ਲਈ ਹੈਂਡਲਰ ਲਵੋ ਜਾਂ ਸੈੱਟ ਕਰੋ" + +#: gio/gio-tool.c:234 +#| msgid "Can't open directory" +msgid "Create directories" +msgstr "ਡਾਇਰਕੈਟਰੀਆਂ ਬਣਾਓ" + +#: gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "ਤਬਦੀਲੀਆਂ ਲਈ ਫਾਇਲਾਂ ਅਤੇ ਡਾਇਰੈਕਟਰੀਆਂ ਦੀ ਨਿਗਰਾਨੀ ਕਰੋ" + +#: gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "ਟਿਕਾਣੇ ਮਾਊਂਟ ਜਾਂ ਅਣ-ਮਾਊਂਟ ਕਰੋ।" + +#: gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "ਇੱਕ ਜਾਂ ਵੱਧ ਫਾਇਲਾਂ ਭੇਜੋ" + +#: gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "ਡਿਫਾਲਟ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਨਾਲ ਫਾਇਲਾਂ ਖੋਲà©à¨¹à©‹" + +#: gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "ਫਾਇਲ ਦਾ ਨਾਂ ਬਦਲੋ" + +#: gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "ਇੱਕ ਜਾਂ ਵੱਧ ਫਾਇਲਾਂ ਹਟਾਓ" + +#: gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "" + +#: gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "ਫਾਇਲ ਗà©à¨£ ਸੈੱਟ ਕਰੋ" + +#: gio/gio-tool.c:243 +#| msgid "The file descriptor to write to" +msgid "Move files or directories to the trash" +msgstr "ਫਾਇਲਾਂ ਜਾਂ ਡਾਇਰੈਕਟਰੀ ਨੂੰ ਰੱਦੀ ਵਿੱਚ ਭੇਜੋ" + +#: gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "" + +#: gio/gio-tool.c:246 +#, c-format +#| msgid "" +#| "Use '%s help COMMAND' to get detailed help.\n" +#| "\n" +msgid "Use %s to get detailed help.\n" +msgstr "ਵੇਰਵੇ ਸਮੇਤ ਮਦਦ ਲੈਣ ਲਈ %s ਵਰਤੋ।\n" + +#: gio/gio-tool-cat.c:87 +#, fuzzy +#| msgid "Error writing to file: %s" +msgid "Error writing to stdout" +msgstr "ਫਾਇਲ ਲਿਖਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:282 gio/gio-tool-list.c:165 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 +#| msgid "ACTION" +msgid "LOCATION" +msgstr "ਟਿਕਾਣਾ" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "ਫਾਇਲਾਂ ਨੂੰ ਜੋੜਦੀ ਹੈ ਅਤੇ ਸਟੈਂਡਰਡ ਆਉਟਪà©à©±à¨Ÿ ਉੱਤੇ ਪਰਿੰਟ ਕਰਦੀ ਹੈ।" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat ਪà©à¨°à¨¾à¨£à©€ cat ਸਹੂਲਤ ਵਾਂਗ ਹੀ ਕੰਮ ਕਰਦੀ ਹੈ, ਪਰ ਲੋਕਲ ਫਾਇਲ ਦੀ\n" +"ਬਜਾਠGIO ਟਿਕਾਣੇ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ: ਜਿਵੇਂ ਤà©à¨¸à©€à¨‚ ਟਿਕਾਣੇ ਵਜੋਂ\n" +"smb://server/resource/file.txt ਵਰਤ ਸਕਦੇ ਹੋ।" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:313 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 +msgid "No locations given" +msgstr "ਕੋਈ ਟਿਕਾਣਾ ਨਹੀਂ ਦਿੱਤਾ" + +#: gio/gio-tool-copy.c:42 gio/gio-tool-move.c:38 +#| msgid "Target file is a directory" +msgid "No target directory" +msgstr "ਟਾਰਗੇਟ ਡਾਇਰੈਕਟਰੀ ਹੈ" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "ਤਰੱਕੀ ਵੇਖਾਓ" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "ਉੱਤੇ ਲਿਖਣ ਤੋਂ ਪਹਿਲਾਂ ਪà©à©±à¨›à©‹" + +#: gio/gio-tool-copy.c:45 +msgid "Preserve all attributes" +msgstr "ਸਭ ਗà©à¨£ ਸੰਭਾਲੀ ਰੱਖੋ" + +#: gio/gio-tool-copy.c:46 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +#| msgid "Backup file creation failed" +msgid "Backup existing destination files" +msgstr "ਮੌਜੂਦਾ ਟਿਕਾਣਾ ਫਾਇਲਾਂ ਦਾ ਬੈਕਅੱਪ ਬਣਾਓ" + +#: gio/gio-tool-copy.c:47 +msgid "Never follow symbolic links" +msgstr "ਸਿੰਬੋਲਿਕ ਲਿੰਕ ਕਦੇ ਨਾ ਵੇਖੋ" + +#: gio/gio-tool-copy.c:72 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%2$s ਵਿੱਚੋਂ %1$s ਟਰਾਂਸਫਰ ਹੋਠ(%3$s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:98 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ਸਰੋਤ" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:98 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ਟਿਕਾਣਾ" + +#: gio/gio-tool-copy.c:103 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "SOURCE ਤੋਂ DESTINATION ਤੋਂ ਇੱਕ ਜਾਂ ਵੱਧ ਫਾਇਲਾਂ ਕਾਪੀ ਕਰੋ।" + +#: gio/gio-tool-copy.c:105 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" + +#: gio/gio-tool-copy.c:147 +#, c-format +#| msgid "The resource at '%s' is not a directory" +msgid "Destination %s is not a directory" +msgstr "ਟਿਕਾਣਾ %s ਡਾਇਰੈਕਟਰੀ ਨਹੀਂ ਹੈ" + +#: gio/gio-tool-copy.c:192 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "“%s: “%s†ਉੱਤੇ ਲਿਖਣਾ?" + +#: gio/gio-tool-info.c:34 +#| msgid "List available actions" +msgid "List writable attributes" +msgstr "ਲਿਖਣਯੋਗ ਗà©à¨£ ਵੇਖੋ" + +#: gio/gio-tool-info.c:35 +#| msgid "Error getting filesystem info: %s" +msgid "Get file system info" +msgstr "ਫਾਇਲ ਸਿਸਟਮ ਜਾਣਕਾਰੀ ਲਵੋ" + +#: gio/gio-tool-info.c:36 gio/gio-tool-list.c:35 +msgid "The attributes to get" +msgstr "ਲੈਣ ਲਈ ਗà©à¨£" + +#: gio/gio-tool-info.c:36 gio/gio-tool-list.c:35 +msgid "ATTRIBUTES" +msgstr "ਗà©à¨£" + +#: gio/gio-tool-info.c:37 gio/gio-tool-list.c:38 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "ਸਿਮ-ਲਿੰਕ ਨਾ ਵਰਤੋਂ" + +#: gio/gio-tool-info.c:75 +msgid "attributes:\n" +msgstr "ਗà©à¨£:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "ਡਿਸਪਲੇਅ ਨਾਂ: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "ਨਾਂ ਸੋਧੋ: %s\n" + +#: gio/gio-tool-info.c:138 +#, c-format +#| msgid "names" +msgid "name: %s\n" +msgstr "ਨਾਂ: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "ਕਿਸਮ: %s\n" + +#: gio/gio-tool-info.c:151 +msgid "size: " +msgstr "ਆਕਾਰ:" + +#: gio/gio-tool-info.c:156 +msgid "hidden\n" +msgstr "ਲà©à¨•ਵਾਂ\n" + +#: gio/gio-tool-info.c:159 +#, c-format +#| msgid "Error: %s\n" +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:228 +msgid "Settable attributes:\n" +msgstr "ਸੈੱਟ ਕਰਨ ਯੋਗ ਗà©à¨£:\n" + +#: gio/gio-tool-info.c:252 +msgid "Writable attribute namespaces:\n" +msgstr "ਲਿਖਣਯੋਗ ਗà©à¨£ ਨਾਂ-ਥਾਂ:\n" + +#: gio/gio-tool-info.c:287 +#| msgid "Show GApplication options" +msgid "Show information about locations." +msgstr "ਟਿਕਾਣੇ ਲਈ ਜਾਣਕਾਰੀ ਵੇਖੋ।" + +#: gio/gio-tool-info.c:289 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info ਪà©à¨°à¨¾à¨£à©€ ls ਸਹੂਲਤ ਵਾਂਗ ਹੀ ਕੰਮ ਕਰਦੀ ਹੈ, ਪਰ ਲੋਕਲ ਫਾਇਲ ਦੀ ਬਜਾà¨\n" +"GIO ਟਿਕਾਣੇ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ: ਜਿਵੇਂ ਤà©à¨¸à©€à¨‚ ਜੋੜਨ ਵਾਸਤੇ ਟਿਕਾਣੇ ਵਜੋਂ\n" +"smb://server/resource/file.txt ਦੇ ਸਕਦੇ ਹੋ। ਫਾਇਲ ਹà©à¨£ ਨੂੰ ਉਹਨਾਂ\n" +"ਦੇ GIO ਨਾਂ ਰਾਹੀਂ ਦਿੱਤਾ ਜਾ ਸਕਦਾ ਹੈ ਜਿਵੇਂ ਕਿ standard::icon, ਜਾਂ ਨਾਂ ਥਾਂ ਰਾਹੀਂ\n" +"ਜਿਵੇਂ ਕਿ ਯੂਨੈਕਸ ਜਾਂ \"*\", ਜੋ ਕਿ ਸਾਰੇ ਗà©à¨£à¨¾à¨‚ ਨਾਲ ਮਿਲਦੇ ਹਨ" + +#: gio/gio-tool-list.c:36 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "ਲà©à¨•ਵੀਆਂ ਫਾਈਲਾਂ ਵੇਖੋ" + +#: gio/gio-tool-list.c:37 +#| msgid "use a long listing format" +msgid "Use a long listing format" +msgstr "ਲੰਮਾ ਲਿਸਟ ਫਾਰਮੈਟ ਵਰਤੋਂ" + +#: gio/gio-tool-list.c:39 +msgid "Print full URIs" +msgstr "ਪੂਰੇ URI ਛਾਪੋ" + +#: gio/gio-tool-list.c:170 +msgid "List the contents of the locations." +msgstr "ਟਿਕਾਣਿਆਂ ਦੀ ਸਮੱਗਰੀ ਸੂਚੀਬੱਧ ਕਰੋ।" + +#: gio/gio-tool-list.c:172 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list ਪà©à¨°à¨¾à¨£à©€ ls ਸਹੂਲਤ ਵਾਂਗ ਹੀ ਕੰਮ ਕਰਦੀ ਹੈ, ਪਰ ਲੋਕਲ ਫਾਇਲ ਦੀ ਬਜਾà¨\n" +"GIO ਟਿਕਾਣੇ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ: ਜਿਵੇਂ ਤà©à¨¸à©€à¨‚ ਜੋੜਨ ਵਾਸਤੇ ਟਿਕਾਣੇ ਵਜੋਂ\n" +"smb://server/resource/file.txt ਦੇ ਸਕਦੇ ਹੋ। ਫਾਇਲ ਹà©à¨£ ਨੂੰ ਉਹਨਾਂ\n" +"ਦੇ GIO ਨਾਂ ਰਾਹੀਂ ਦਿੱਤਾ ਜਾ ਸਕਦਾ ਹੈ ਜਿਵੇਂ ਕਿ standard::icon " + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "ਮਾਈਮ-ਕਿਸਮ" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "ਹੈਂਡਲਰ" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "ਮਾਈਮ-ਕਿਸਮ ਲਈ ਹੈਂਡਲਰ ਲਵੋ ਜਾਂ ਸੈੱਟ ਕਰੋ।" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "“%s†ਲਈ ਕੋਈ ਡਿਫਾਲਟ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਨਹੀਂ ਹੈ\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +#| msgid "invalid application id: '%s'\n" +msgid "Default application for “%sâ€: %s\n" +msgstr "“%s†ਲਈ ਡਿਫਾਲਟ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ: %s\n" + +#: gio/gio-tool-mime.c:127 +#| msgid "List applications" +msgid "Registered applications:\n" +msgstr "ਰਜਿਸਟਰ ਹੋਈਆਂ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ:\n" + +#: gio/gio-tool-mime.c:129 +#| msgid "List applications" +msgid "No registered applications\n" +msgstr "ਕੋਈ ਰਜਿਸਟਰ ਹੋਈ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਨਹੀਂ\n" + +#: gio/gio-tool-mime.c:140 +#| msgid "List applications" +msgid "Recommended applications:\n" +msgstr "ਸਿਫਾਰਸ਼ੀ ਕੀਤੀਆਂ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ:\n" + +#: gio/gio-tool-mime.c:142 +#| msgid "Can't find application" +msgid "No recommended applications\n" +msgstr "ਕੋਈ ਸਿਫਾਰਸ਼ ਕੀਤੀ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਨਹੀਂ ਹੈ\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to load info for handler “%sâ€" +msgstr "“%s†ਹੈਂਡਲਰ ਲਈ ਜਾਣਕਾਰੀ ਲੋਡ ਕਰਨ ਲਈ ਫੇਲà©à¨¹ ਹੈ" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "“%s†ਨੂੰ “%s†ਲਈ ਡਿਫਾਲਟ ਹੈਂਡਲਰ ਸੈੱਟ ਕਰਨ ਲਈ ਫੇਲà©à¨¹ ਹੈ: %s\n" + +#: gio/gio-tool-mkdir.c:31 +#| msgid "Can't open directory" +msgid "Create parent directories" +msgstr "ਮà©à©±à¨¢à¨²à©€à¨†à¨‚ ਡਾਇਰੈਕਟਰੀਆਂ ਬਣਾਓ" + +#: gio/gio-tool-mkdir.c:52 +#| msgid "Can't open directory" +msgid "Create directories." +msgstr "ਡਾਇਰਕੈਟਰੀਆਂ ਬਣਾਉ।" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "" + +#: gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "ਮਾਊਂਟ ਕਰਨ ਯੋਗ ਵਜੋਂ ਮਾਊਂਟ" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file" +msgstr "ਜੰਤਰ ਫਾਇਲ ਨਾਲ ਵਾਲੀਅਮ ਮਾਊਂਟ" + +#: gio/gio-tool-mount.c:64 gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ਜੰਤਰ" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "ਅਣ-ਮਾਊਂਟ" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "ਬਾਹਰ ਕੱਢੋ" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "ਡਿਵਾਈਸ ਫਾਇਲ ਨਾਲ ਡਰਾਇਵ ਰੋਕੋ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "ਦਿੱਤੀ ਸਕੀਮ ਨਾਲ ਸਭ ਮਾਊਂਟ ਅਣ-ਮਾਊਂਟ ਕਰੋ" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ਸਕੀਮ" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"ਜਦੋਂ ਅਣਮਾਊਂਟ ਜਾਂ ਬਾਹਰ ਕੱਢਣਾ ਹੋਵੇ ਤਾਂ ਬਾਕੀ ਪਈਆਂ ਫਾਈਲਾਂ ਕਾਰਵਾਈਆਂ ਨੂੰ ਅਣਡਿੱਠਾ ਕਰੋ" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "ਪਰਮਾਣਿਤ ਕਰਨ ਦੇ ਦੌਰਾਨ ਅਣਪਛਾਤੇ ਵਰਤੋਂਕਾਰ ਵਰਤੋਂ" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "ਸੂਚੀ" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "ਈਵੈਂਟਾਂ ਦੀ ਨਿਗਰਾਨੀ" + +#: gio/gio-tool-mount.c:74 +#| msgid "Show help options" +msgid "Show extra information" +msgstr "ਹੋਰ ਜਾਣਕਾਰੀ ਵੇਖਾਓ" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +#| msgctxt "GDateTime" +#| msgid "PM" +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "ਅਣਪਛਾਤੀ ਪਹà©à©°à¨š ਲਈ ਇਨਕਾਰ ਕੀਤਾ" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "ਜੰਤਰ ਫਾਇਲ ਲਈ ਕੋਈ ਡਰਾਇਵ ਨਹੀਂ ਹੈ" + +#: gio/gio-tool-mount.c:975 +#, c-format +msgid "Mounted %s at %s\n" +msgstr "%s %s ਉੱਤੇ ਮਾਊਂਟ ਹੈ\n" + +#: gio/gio-tool-mount.c:1027 +msgid "No volume for device file" +msgstr "ਜੰਤਰ ਫਾਇਲ ਲਈ ਕੋਈ ਵਾਲੀਅਮ ਨਹੀਂ ਲੱਭਿਆ" + +#: gio/gio-tool-mount.c:1216 +msgid "Mount or unmount the locations." +msgstr "ਟਿਕਾਣੇ ਮਾਊਂਟ ਜਾਂ ਅਣ-ਮਾਊਂਟ ਕਰੋ।" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "ਕਾਪੀ ਤੇ ਹਟਾਓ ਫਾਲਬੈਕ ਨੂੰ ਨਾ ਵਰਤੋਂ" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "SOURCE ਤੋਂ DEST ਤੋਂ ਇੱਕ ਜਾਂ ਵੱਧ ਫਾਇਲਾਂ ਭੇਜੋ।" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" + +#: gio/gio-tool-move.c:143 +#, c-format +#| msgid "Target file is a directory" +msgid "Target %s is not a directory" +msgstr "ਟਾਰਗੇਟ %s ਡਾਇਰੈਕਟਰੀ ਨਹੀਂ ਹੈ" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"ਇਸ ਟਾਈਪ ਦੀਆਂ ਫਾਇਲਾਂ ਵਰਤਣ ਲਈ ਰਜਿਸਟਰ\n" +"ਡਿਫਾਲਟ à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਨਾਲ ਇਹ ਫਾਇਲਾਂ ਖੋਲà©à¨¹à©‹à¥¤" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "ਨਾ-ਮੌਜੂਦ ਫਾਇਲਾਂ ਅਣਡਿੱਠੀਆਂ, ਕਦੇ ਨਾ ਪà©à©±à¨›à©‹" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "ਦਿੱਤੀਆਂ ਫਾਇਲਾਂ ਹਟਾਉ।" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "ਨਾਂ" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "ਫਾਇਲ ਦਾ ਨਾਂ ਬਦਲੋ।" + +#: gio/gio-tool-rename.c:70 +#| msgid "Missing argument for %s" +msgid "Missing argument" +msgstr "ਆਰਗੂਮੈਂਟ ਗà©à©°à¨® ਹੈ" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +#| msgid "" +#| "'%s' takes no arguments\n" +#| "\n" +msgid "Too many arguments" +msgstr "ਬਹà©à¨¤ ਸਾਰੇ ਆਰਗੂਮੈਂਟ" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "ਨਾਂ ਠੀਕ ਤਰà©à¨¹à¨¾à¨‚ ਬਦਲਿਆ ਗਿਆ। ਨਵਾਂ uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "ਕੇਵਲ ਤਾਂ ਹੀ ਬਣਾਓ, ਜੇ ਮੌਜੂਦ ਨਾ ਹੋਵੇ" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "ਫਾਇਲ ਦੇ ਅੰਤ ਵਿੱਚ ਸ਼ਾਮਲ" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "ਜਦੋਂ ਬਣਾਉਣਾ ਹੋਵੇ ਤਾਂ ਮੌਜੂਦਾ ਵਰਤੋਂਕਾਰ ਵਲੋਂ ਵਰਤੋਂ ਲਈ ਹੀ ਸੀਮਿਤ ਕਰੋ" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" +"ਜਦੋਂ ਤਬਦੀਲ ਕਰਨਾ ਹੋਵੇ ਤਾਂ ਇੰਠਤਬਦੀਲ ਕਰੋ ਕਿ ਟਿਕਾਣੇ ਉੱਤੇ ਕà©à¨ ਵੀ ਮੌਜੂਦ ਨਹੀਂ ਸੀ" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "ਅੰਤ ਉੱਤੇ ਨਵਾਂ etag ਲਿਖੋ" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "ਉੱਤੇ ਲਿਖੀ ਜਾਣ ਵਾਲੀ ਫਾਇਲ ਦਾ etag" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +#| msgid "Error reading from handle: %s" +msgid "Error reading from standard input" +msgstr "ਮਿਆਰੀ ਇਨਪà©à¨Ÿ ਦੌਰਾਨ ਗਲਤੀ" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +#| msgid "TLS support is not available" +msgid "Etag not available\n" +msgstr "ਈਟੈਗ ਉਪਲੱਬਧ ਨਹੀਂ\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "ਸਟੈਂਡਰਡ ਇੰਪà©à©±à¨Ÿ ਪੜà©à¨¹à©‹ ਅਤੇ DEST ਉੱਤੇ ਸੰਭਾਲੋ।" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "ਕੋਈ ਟਿਕਾਣਾ ਨਹੀਂ ਦਿੱਤਾ" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "ਗà©à¨£ ਦੀ ਕਿਸਮ" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "ਕਿਸਮ" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ਗà©à¨£" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "ਮà©à©±à¨²" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "ਟਿਕਾਣੇ ਦਾ ਫਾਇਲ ਗà©à¨£ ਸੈੱਟ ਕਰੋ।" + +#: gio/gio-tool-set.c:113 +#| msgid "No connection endpoint specified" +msgid "Location not specified" +msgstr "ਟਿਕਾਣਾ ਨਹੀਂ ਦਿੱਤਾ" + +#: gio/gio-tool-set.c:120 +#| msgid "Error: signal not specified.\n" +msgid "Attribute not specified" +msgstr "ਗà©à¨£ ਨਹੀਂ ਦਿੱਤਾ" + +#: gio/gio-tool-set.c:130 +#| msgid "Error: signal not specified.\n" +msgid "Value not specified" +msgstr "ਮà©à©±à¨² ਨਹੀਂ ਦਿੱਤਾ" + +#: gio/gio-tool-set.c:180 +#, c-format +#| msgid "Invalid attribute type (string expected)" +msgid "Invalid attribute type “%sâ€" +msgstr "ਗਲਤ ਗà©à¨£ ਕਿਸਮ “%sâ€" + +#: gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "ਰੱਦੀ ਖਾਲੀ ਕਰੋ" + +#: gio/gio-tool-trash.c:86 +#| msgid "The file descriptor to write to" +msgid "Move files or directories to the trash." +msgstr "ਫਾਇਲਾਂ ਜਾਂ ਡਾਇਰੈਕਟਰੀ ਨੂੰ ਰੱਦੀ ਵਿੱਚ ਭੇਜੋ।" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "ਸਿੰਬੋਲਿਕ ਲਿੰਕ, ਮਾਊਂਟ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਵਰਤੋਂ" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "ਡਾਇਰੈਕਟਰੀਆਂ ਦੀ ਸਮੱਗਰੀ ਟਰੀ-ਵਰਗੇ ਫਾਰਮੈਟ ਵਿੱਚ ਵੇਖੋ।" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> à¨à¨²à©€à¨®à©ˆà¨‚ਟ <%s> ਵਿੱਚ ਮਨਜ਼ੂਰ ਨਹੀਂ" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "à¨à¨²à©€à¨®à©ˆà¨‚ਟ <%s> ਸਭ ਤੋਂ ਉੱਤੇ ਮਨਜ਼ੂਰ ਨਹੀਂ ਹੈ" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "ਫਾਇਲ %s ਸਰੋਤ ਵਿੱਚ ਕਈ ਵਾਰ ਆਈ ਹੋਈ ਜਾਪਦੀ ਹੈ" + +#: gio/glib-compile-resources.c:245 +#, c-format +#| msgid "Failed to locate '%s' in any source directory" +msgid "Failed to locate “%s†in any source directory" +msgstr "ਕੋਈ ਸਰੋਤ ਡਾਇਰੈਕਟਰੀ ਵਿੱਚ “%s†ਲੱਭਣ ਲਈ ਫੇਲà©à¨¹ ਹੈ" + +#: gio/glib-compile-resources.c:256 +#, c-format +#| msgid "Failed to locate '%s' in current directory" +msgid "Failed to locate “%s†in current directory" +msgstr "ਮੌਜੂਦਾ ਡਾਇਰੈਕਟਰੀ ਵਿੱਚ “%s†ਲੱਭਣ ਲਈ ਫੇਲà©à¨¹ ਹੈ" + +#: gio/glib-compile-resources.c:290 +#, c-format +#| msgid "Unknown processing option \"%s\"" +msgid "Unknown processing option “%sâ€" +msgstr "ਅਣਜਾਣ ਕਾਰਵਾਈ ਚੋਣ “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s ਫਾਇਲ ਪੜà©à¨¹à¨¨ 'ਚ ਗਲਤੀ: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "ਫਾਇਲ ਕੰਪਰੈਸ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "ਟੈਕਸਟ <%s> ਦੇ ਅੰਦਰ ਨਹੀਂ ਹੋ ਸਕਦਾ" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "ਪਰੋਗਰਾਮ ਵਰਜਨ ਵੇਖੋ ਅਤੇ ਬੰਦ" + +#: gio/glib-compile-resources.c:738 +#| msgid "name of the output file" +msgid "Name of the output file" +msgstr "ਆਉਟਪà©à©±à¨Ÿ ਫਾਇਲ ਦਾ ਨਾਂ" + +#: gio/glib-compile-resources.c:739 +#, fuzzy +#| msgid "" +#| "The directories where files are to be read from (default to current " +#| "directory)" +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"ਡਾਇਰੈਕਟਰੀਆਂ, ਜਿੱਥੋਂ ਫਾਇਲਾਂ ਨੂੰ ਪੜà©à¨¹à¨¿à¨† ਜਾ ਸਕਦਾ ਹੈ (ਡਿਫਾਲਟ ਮੌਜੂਦਾ ਡਾਇਰੈਕਟਰੀ ਹੈ)" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "ਡਾਇਰੈਕਟਰੀ" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "ਟਾਰਗੇਟ ਫਾਇਲ-ਨਾਂ ਇਕਸਟੈਸ਼ਨ ਰਾਹੀਂ ਚà©à¨£à©‡ ਫਾਰਮੈਟ ਵਿੱਚ ਆਉਟਪà©à©±à¨Ÿ ਤਿਆਰ ਕਰੋ" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "ਸਰੋਤ ਹੈੱਡਰ ਤਿਆਰ ਕਰੋ" + +#: gio/glib-compile-resources.c:742 +#, fuzzy +#| msgid "Generate sourcecode used to link in the resource file into your code" +msgid "Generate source code used to link in the resource file into your code" +msgstr "ਸਰੋਤ ਫਾਇਲ ਵਿੱਚ ਵਰਤੇ ਲਿੰਕ ਤੋਂ ਸਰੋਤ ਕੋਡ ਨੂੰ ਆਪਣੇ ਕੋਡ ਵਿੱਚ ਤਿਆਰ ਕਰੋ" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "ਨਿਰਭਰਤਾ ਸੂਚੀ ਬਣਾਓ" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "" + +#: gio/glib-compile-resources.c:746 +#| msgid "Don't automatically create and register resource" +msgid "Don’t automatically create and register resource" +msgstr "ਸਰੋਤ ਆਪਣੇ-ਆਪ ਨਾ ਬਣਾਓ ਅਤੇ ਰਜਿਸਟਰ ਕਰੋ" + +#: gio/glib-compile-resources.c:747 +#| msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "ਫੰਕਸ਼ਨ à¨à¨•ਸਪੋਰਟ ਨਾ ਕਰੋ; ਉਹਨਾਂ ਨੂੰ G_GNUC_INTERNAL à¨à¨²à¨¾à¨¨à©‹" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "ਤਿਆਰ ਕੀਤੇ ਸਰੋਤ ਕੋਡ ਲਈ C ਅਡੈਂਟਟੀਫਾਇਰ ਨਾਂ" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"ਸਰੋਤ ਫਾਇਲ ਨੂੰ ਇੱਕ ਸਰੋਤ ਹਦਾਇਤ 'ਚ ਕੰਪਾਇਲ ਕਰੋ।\n" +"ਸਰੋਤ ਹਦਾਇਤਾਂ ਲਈ .gresourcexml ਇਕਸਟੈਨਸ਼ਨ ਹੋਣਾ ਲਾਜ਼ਮੀ ਹੈ\n" +"ਅਤੇ ਸਰੋਤ ਫਾਇਲ ਦੀ ਇਕਸਟੈਨਸ਼ਨ ਨੂੰ .gresource ਕਿਹਾ ਜਾਂਦਾ ਹੈ।" + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "ਤà©à¨¹à¨¾à¨¨à©‚à©° ਇੱਕ ਫਾਇਲ ਦਾ ਪੂਰਾ ਨਾਂ ਦੇਣਾ ਚਾਹੀਦਾ ਹੈ\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "" + +#: gio/glib-compile-schemas.c:103 +#, c-format +#| msgid "Invalid symlink value given" +msgid "Invalid numeric value" +msgstr "ਗਲਤ ਅੰਕ ਮà©à©±à¨²" + +#: gio/glib-compile-schemas.c:111 +#, c-format +#| msgid "<%s id='%s'> already specified" +msgid " already specified" +msgstr " ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਗਿਆ" + +#: gio/glib-compile-schemas.c:119 +#, c-format +#| msgid " already specified" +msgid "value='%s' already specified" +msgstr "value='%s' ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:314 +#, c-format +#| msgid "No connection endpoint specified" +msgid "<%s> is not contained in the specified range" +msgstr "<%s> ਤੈਅ ਕੀਤੀ ਹੱਦ ਵਿੱਚ ਨਹੀਂ ਹੈ" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "" + +#: gio/glib-compile-schemas.c:372 +#| msgid " already specified" +msgid " already specified for this key" +msgstr " ਇਸ ਕà©à©°à¨œà©€ ਲਈ ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਗਿਆ" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "" + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:500 +#| msgid " already specified" +msgid " already specified for this key" +msgstr " ਇਸ ਕà©à©°à¨œà©€ ਲਈ ਪਹਿਲਾਂ ਹੀ ਦਿੱਤੀਆਂ" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "" + +#: gio/glib-compile-schemas.c:528 +#, fuzzy, c-format +#| msgid " already specified" +msgid " already given" +msgstr " ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਗਿਆ" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:557 +#| msgid " already specified" +msgid " already specified for this key" +msgstr " ਇਸ ਕà©à©°à¨œà©€ ਲਈ ਪਹਿਲਾਂ ਹੀ ਦਿੱਤੀਆਂ" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" + +#: gio/glib-compile-schemas.c:594 +#, c-format +#| msgid "<%s id='%s'> already specified" +msgid " already specified" +msgstr " ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਹੈ" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "" + +#: gio/glib-compile-schemas.c:797 +#| msgid "empty names are not permitted" +msgid "Empty names are not permitted" +msgstr "ਖਾਲੀ ਨਾਂ ਮਨਜ਼ੂਰ ਨਹੀਂ ਹੈ" + +#: gio/glib-compile-schemas.c:807 +#, c-format +#| msgid "invalid name '%s': names must begin with a lowercase letter" +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "ਗਲਤ ਨਾਂ â€%sâ€: ਨਾਂ ਛੋਟੇ ਅੱਖਰ ਨਾਲ ਹੀ ਸ਼à©à¨°à©‚ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: gio/glib-compile-schemas.c:819 +#, c-format +#| msgid "" +#| "invalid name '%s': invalid character '%c'; only lowercase letters, " +#| "numbers and hyphen ('-') are permitted." +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"ਗਲਤ ਨਾਂ '“%sâ€: ਗਲਤ ਅੱਖਰ â€%câ€; ਕੇਵਲ ਛੋਟੇ ਅੱਖਰ, ਨੰਬਰ, ਤੇ ਹਾਈਫਨ (â€-â€) ਮਨਜ਼ੂਰ" +" ਨਹੀਂ ਹਨ।" + +#: gio/glib-compile-schemas.c:828 +#, c-format +#| msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "ਗਲਤ ਨਾਂ “%sâ€: ਲਗਾਤਾਰ ਦੋ ਹਾਈਫਨ (“--â€) ਮਨਜ਼ੂਰ ਨਹੀਂ।" + +#: gio/glib-compile-schemas.c:837 +#, c-format +#| msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "ਗਲਤ ਨਾਂ “%sâ€: ਆਖਰੀ ਅੱਖਰ ਹਾਈਫਨ (“-â€) ਨਹੀਂ ਹੋ ਸਕਦਾ।" + +#: gio/glib-compile-schemas.c:845 +#, c-format +#| msgid "invalid name '%s': maximum length is 1024" +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "ਗਲਤ ਨਾਂ “%sâ€: ਵੱਧੋ-ਵੱਧ ਲੰਬਾਈ ੧੦੨੪" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਗਿਆ" + +#: gio/glib-compile-schemas.c:943 +#| msgid "cannot add keys to a 'list-of' schema" +msgid "Cannot add keys to a “list-of†schema" +msgstr " ਕà©à©°à¨œà©€à¨†à¨‚ “list-of†ਸਕੀਮਾ 'ਚ ਜੋੜੀਆਂ ਨਹੀਂ ਜਾ ਸਕਦਾ" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਗਿਆ" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" ਸ਼ੈਡੋ ਵਿੱਚ; ਮà©à©±à¨² ਸੋਧਣ ਲਈ " +" ਵਰਤੋਂ" + +#: gio/glib-compile-schemas.c:983 +#, c-format +#| msgid "" +#| "exactly one of 'type', 'enum' or 'flags' must be specified as an " +#| "attribute to " +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +" ਲਈ ਗà©à¨£ ਵਜੋਂ ਦੇਣ ਲਈ “typeâ€, “enum†ਜਾਂ “flags†ਵਿੱਚੋਂ ਠੀਕ ਇੱਕ ਦੇਣਾ" +" ਲਾਜ਼ਮੀ ਹੈ" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (ਹਾਲੇ) ਨਹੀਂ ਦਿੱਤਾ ਗਿਆ।" + +#: gio/glib-compile-schemas.c:1017 +#, c-format +#| msgid "invalid GVariant type string '%s'" +msgid "Invalid GVariant type string “%sâ€" +msgstr "ਗਲਤ GVariant ਕਿਸਮ ਲਾਈਨ “%sâ€" + +#: gio/glib-compile-schemas.c:1047 +#| msgid " given but schema isn't extending anything" +msgid " given but schema isn’t extending anything" +msgstr " ਦਿੱਤਾ, ਪਰ ਸਕੀਮਾ ਕà©à¨ ਨਹੀਂ ਵਧਾ ਰਿਹਾ ਹੈ" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +#| msgid "no to override" +msgid "No to override" +msgstr "ਅਣਡਿੱਠਾ ਕਰਨ ਲਈ ਨਹੀਂ" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਗਿਆ" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਗਿਆ" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +#| msgid " extends not yet existing schema '%s'" +msgid " extends not yet existing schema “%sâ€" +msgstr " ਮੌਜੂਦਾ ਸਕੀਮਾ “%s†ਵਧਾਇਆ ਨਹੀਂ ਗਿਆ" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +#| msgid " is list of not yet existing schema '%s'" +msgid " is list of not yet existing schema “%sâ€" +msgstr " ਹਾਲੇ ਨਾ-ਮੌਜੂਦ “%s†ਸਕੀਮਾ ਦੀ ਲਿਸਟ ਹੈ" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +#| msgid "Can not be a list of a schema with a path" +msgid "Cannot be a list of a schema with a path" +msgstr "ਪਾਥ ਨਾਲ ਸਕੀਮਾ ਦੀ ਲਿਸਟ ਨਹੀਂ ਦਿੱਤੀ ਜਾ ਸਕਦੀ" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +#| msgid "Can not extend a schema with a path" +msgid "Cannot extend a schema with a path" +msgstr "ਪਾਥ ਨਾਲ ਸਕੀਮਾ ਨੂੰ ਵਧਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ਲਿਸਟ ਹੈ, ਵਧਾਇਆ ਜਾ ਰਿਹਾ ਹੈ, ਜੋ ਕਿ ਲਿਸਟ ਨਹੀਂ" +" ਹੈ" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +#| msgid "" +#| " extends but " +#| "'%s' does not extend '%s'" +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" ਵਧਾਇਆ, ਪਰ “%s†" +"“%s†ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +#| msgid "a path, if given, must begin and end with a slash" +msgid "A path, if given, must begin and end with a slash" +msgstr "ਪਾਥ, ਜੇ ਦਿੱਤਾ ਹੋਵੇ ਤਾਂ ਸ਼à©à¨°à©‚ ਤੇ ਖਤਮ ਸਲੈਸ਼ ਨਾਲ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +#| msgid "the path of a list must end with ':/'" +msgid "The path of a list must end with “:/â€" +msgstr "ਲਿਸਟ ਦਾ ਪਾਥ “:/†ਨਾਲ ਖਤਮ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ਪਹਿਲਾਂ ਹੀ ਦਿੱਤਾ ਹੈ" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, fuzzy, c-format +#| msgid "Element <%s> not allowed inside <%s>" +msgid "Only one <%s> element allowed inside <%s>" +msgstr "<%s> à¨à¨²à©€à¨®à©ˆà¨‚ਟ <%s> ਵਿੱਚ ਮਨਜ਼ੂਰ ਨਹੀਂ" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "à¨à¨²à©€à¨®à©ˆà¨‚ਟ <%s> ਸਭ ਤੋਂ ਉੱਤੇ ਮਨਜ਼ੂਰ ਨਹੀਂ ਹੈ" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +#| msgid "text may not appear inside <%s>" +msgid "Text may not appear inside <%s>" +msgstr "ਟੈਕਸਟ <%s> ਦੇ ਅੰਦਰ ਨਹੀਂ ਹੋ ਸਕਦਾ" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +#| msgid "--strict was specified; exiting.\n" +msgid "--strict was specified; exiting." +msgstr "--strict ਦਿੱਤੀ ਗਈ ਸੀ। ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।" + +#: gio/glib-compile-schemas.c:1845 +#| msgid "This entire file has been ignored.\n" +msgid "This entire file has been ignored." +msgstr "ਇਹ ਪੂਰੀ ਫਾਇਲ ਅਣਡਿੱਠੀ ਕੀਤੀ ਗਈ।" + +#: gio/glib-compile-schemas.c:1908 +#| msgid "Ignoring this file.\n" +msgid "Ignoring this file." +msgstr "ਇਹ ਫਾਇਲ ਅਣਡਿੱਠੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ।" + +#: gio/glib-compile-schemas.c:1963 +#, fuzzy, c-format +#| msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "ਅਣਡਿੱਠਾ ਫਾਇਲ '%3$s' ਵਿੱਚ '%2$s' ਸਕੀਮਾ ਅੰਦਰ ਕੋਈ '%1$s' ਕà©à©°à¨œà©€ ਨਹੀਂ ਹੈ" + +#: gio/glib-compile-schemas.c:1971 +#, fuzzy, c-format +#| msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "ਅਣਡਿੱਠਾ ਫਾਇਲ '%3$s' ਵਿੱਚ '%2$s' ਸਕੀਮਾ ਅੰਦਰ ਕੋਈ '%1$s' ਕà©à©°à¨œà©€ ਨਹੀਂ ਹੈ" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" + +#: gio/glib-compile-schemas.c:2026 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s." +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"ਅਣਡਿੱਠੀ ਫਾਇਲ '%3$s' ਵਿੱਚ '%2$s' ਸਕੀਮਾ ਅੰਦਰ ਕੋਈ '%1$s' ਕà©à©°à¨œà©€ ਨਹੀਂ ਹੈ: %4$s।" + +#: gio/glib-compile-schemas.c:2038 +#, fuzzy, c-format +#| msgid "" +#| "error parsing key '%s' in schema '%s' as specified in override file '%s': " +#| "%s." +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"ਅਣਡਿੱਠੀ ਫਾਇਲ '%3$s' ਵਿੱਚ '%2$s' ਸਕੀਮਾ ਅੰਦਰ ਕੋਈ '%1$s' ਕà©à©°à¨œà©€ ਨਹੀਂ ਹੈ: %4$s।" + +#: gio/glib-compile-schemas.c:2065 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is outside the " +#| "range given in the schema" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"ਅਣਡਿੱਠਾ ਫਾਇਲ '%3$s' ਵਿੱਚ '%2$s' ਸਕੀਮਾ ਅੰਦਰ '%1$s' ਕà©à©°à¨œà©€ ਲਈ ਅਣਡਿੱਠਾ ਕਰਨਾ ਸਕੀਮ" +" 'ਚ " +"ਦਿੱਤੀ ਰੇਜ਼ ਤੋਂ ਬਾਹਰ ਹੈ" + +#: gio/glib-compile-schemas.c:2075 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is outside the " +#| "range given in the schema" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"ਅਣਡਿੱਠਾ ਫਾਇਲ '%3$s' ਵਿੱਚ '%2$s' ਸਕੀਮਾ ਅੰਦਰ '%1$s' ਕà©à©°à¨œà©€ ਲਈ ਅਣਡਿੱਠਾ ਕਰਨਾ ਸਕੀਮ" +" 'ਚ " +"ਦਿੱਤੀ ਰੇਜ਼ ਤੋਂ ਬਾਹਰ ਹੈ" + +#: gio/glib-compile-schemas.c:2101 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"ਅਣਡਿੱਠਾ ਫਾਇਲ '%3$s' ਵਿੱਚ '%2$s' ਸਕੀਮਾ ਅੰਦਰ '%1$s' ਕà©à©°à¨œà©€ ਲਈ ਅਣਡਿੱਠਾ ਕਰਨਾ" +" ਦਿੱਤੀਆਂ " +"ਢà©à©±à¨•ਵੀਆਂ ਚੋਣਾਂ ਦੀ ਲਿਸਟ ਹੈ" + +#: gio/glib-compile-schemas.c:2111 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"ਅਣਡਿੱਠਾ ਫਾਇਲ '%3$s' ਵਿੱਚ '%2$s' ਸਕੀਮਾ ਅੰਦਰ '%1$s' ਕà©à©°à¨œà©€ ਲਈ ਅਣਡਿੱਠਾ ਕਰਨਾ" +" ਦਿੱਤੀਆਂ " +"ਢà©à©±à¨•ਵੀਆਂ ਚੋਣਾਂ ਦੀ ਲਿਸਟ ਹੈ" + +#: gio/glib-compile-schemas.c:2173 +#| msgid "where to store the gschemas.compiled file" +msgid "Where to store the gschemas.compiled file" +msgstr "gschemas.compiled ਫਾਇਲ ਨੂੰ ਕਿੱਥੇ ਸਟੋਰ ਕਰਨਾ ਹੈ" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "ਸਕੀਮਾ 'ਚ ਕੋਈ ਵੀ ਗਲਤੀ ਉੱਤੇ ਅਧੂਰਾ ਛੱਡੋ" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled ਫਾਇਲ ਨਾ ਲਿਖੋ" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "ਕà©à©°à¨œà©€ ਨਾਂ ਪਾਬੰਦੀਆਂ ਲਈ ਮਜ਼ਬੂਰ ਨਾ ਕਰੋ" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"ਜੀਸੈਟਿੰਗ ਸਕੀਮਾ ਫਾਇਲਾਂ ਨੂੰ ਇੱਕ ਸਕੀਮਾ ਕੈਸ਼ 'ਚ ਕੰਪਾਇਲ ਕਰੋ।\n" +"ਸਕੀਮਾ ਫਾਇਲਾਂ ਲਈ .gschema.xml ਇਕਸਟੈਨਸ਼ਨ ਹੋਣਾ ਲਾਜ਼ਮੀ ਹੈ\n" +"ਅਤੇ ਕੈਸ਼ ਫਾਇਲ ਨੂੰ gschemas.compiled ਕਿਹਾ ਜਾਂਦਾ ਹੈ।" + +#: gio/glib-compile-schemas.c:2226 +#| msgid "You should give exactly one directory name\n" +msgid "You should give exactly one directory name" +msgstr "ਤà©à¨¹à¨¾à¨¨à©‚à©° ਇੱਕ ਡਾਇਰੈਕਟਰੀ ਦਾ ਪੂਰਾ ਨਾਂ ਦੇਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: gio/glib-compile-schemas.c:2269 +#| msgid "No schema files found: " +msgid "No schema files found: doing nothing." +msgstr "ਕੋਈ ਸਕੀਮਾਂ ਫਾਇਲ ਨਹੀਂ ਲੱਭੀ: ਕਰਨ ਲਈ ਕà©à¨ ਨਹੀਂ ਹੈ।" + +#: gio/glib-compile-schemas.c:2271 +#| msgid "removed existing output file.\n" +msgid "No schema files found: removed existing output file." +msgstr "ਸਕੀਮਾ ਫਾਇਲਾਂ ਨਹੀਂ ਲੱਭੀਆਂ। ਮੌਜੂਦਾ ਆਉਟਪà©à©±à¨Ÿ ਫਾਇਲ ਹਟਾਈ ਗਈ।" + +#: gio/glocalfile.c:546 gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "ਗਲਤ ਫਾਇਲ ਨਾਂ %s" + +#: gio/glocalfile.c:1013 +#, c-format +#| msgid "Error getting filesystem info: %s" +msgid "Error getting filesystem info for %s: %s" +msgstr "%s ਲਈ ਫਾਇਲ ਸਿਸਟਮ ਜਾਣਕਾਰੀ ਲੈਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1152 +#, c-format +#| msgid "Containing mount does not exist" +msgid "Containing mount for file %s not found" +msgstr "%s ਫਾਇਲ ਲਈ ਰੱਖਣ ਵਾਲਾ ਮਾਊਂਟ ਨਹੀਂ ਲੱਭਿਆ" + +#: gio/glocalfile.c:1175 +#| msgid "Can't rename root directory" +msgid "Can’t rename root directory" +msgstr "ਰੂਟ ਡਾਇਰੈਕਟਰੀ ਦਾ ਨਾਂ ਨਹੀਂ ਬਦਲਿਆ ਜਾ ਸਕਦਾ" + +#: gio/glocalfile.c:1193 gio/glocalfile.c:1216 +#, c-format +#| msgid "Error reading file %s: %s" +msgid "Error renaming file %s: %s" +msgstr "%s ਫਾਇਲ ਨਾਂ ਬਦਲਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfile.c:1200 +#| msgid "Can't rename file, filename already exists" +msgid "Can’t rename file, filename already exists" +msgstr "ਫਾਇਲ ਨਾਂ ਨਹੀਂ ਬਦਲਿਆ ਜਾ ਸਕਦਾ, ਫਾਇਲ ਨਾਂ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ" + +#: gio/glocalfile.c:1213 gio/glocalfile.c:2322 gio/glocalfile.c:2350 +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:647 +msgid "Invalid filename" +msgstr "ਗਲਤ ਫਾਇਲ ਨਾਂ" + +#: gio/glocalfile.c:1381 gio/glocalfile.c:1396 +#, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file %s: %s" +msgstr "%s ਫਾਇਲ ਖੋਲà©à¨¹à¨£ 'ਚ ਗਲਤੀ: %s" + +#: gio/glocalfile.c:1521 +#, c-format +#| msgid "Error removing file: %s" +msgid "Error removing file %s: %s" +msgstr "%s ਫਾਇਲ ਹਟਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfile.c:1963 +#, c-format +#| msgid "Error trashing file: %s" +msgid "Error trashing file %s: %s" +msgstr "%s ਫਾਇਲ ਰੱਦੀ 'ਚ ਭੇਜਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfile.c:2004 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "ਰੱਦੀ ਡਾਇਰੈਕਟਰੀ %s ਬਣਾਉਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/glocalfile.c:2025 +#, c-format +#| msgid "Unable to find toplevel directory for trash" +msgid "Unable to find toplevel directory to trash %s" +msgstr "%s ਰੱਦੀ ਲਈ ਟਾਪ-ਲੈਵਲ ਡਾਇਰੈਕਟਰੀ ਲੱਭਣ ਲਈ ਅਸਮਰੱਥ" + +#: gio/glocalfile.c:2034 +#, fuzzy, c-format +#| msgid "Copy (reflink/clone) between mounts is not supported" +msgid "Trashing on system internal mounts is not supported" +msgstr "ਮਾਊਂਟ ਵਿੱਚ ਕਾਪੀ (ਮà©à©œ-ਲਿੰਕ/ਕਲੋਨ) ਕਰਨਾ ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 +#, c-format +#| msgid "Unable to find or create trash directory" +msgid "Unable to find or create trash directory for %s" +msgstr "%s ਲਈ ਰੱਦੀ ਡਾਇਰੈਕਟਰੀ ਲੱਭਣ ਜਾਂ ਬਣਾਉਣ ਲਈ ਅਸਮਰੱਥ" + +#: gio/glocalfile.c:2173 +#, c-format +#| msgid "Unable to create trashing info file: %s" +msgid "Unable to create trashing info file for %s: %s" +msgstr "%s ਲਈ ਰੱਦੀ 'ਚ ਭੇਜੀ ਫਾਇਲ ਬਣਾਉਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/glocalfile.c:2233 +#, fuzzy, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "ਫਾਇਲ ਰੱਦੀ 'ਚ ਭੇਜਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/glocalfile.c:2237 gio/glocalfile.c:2293 +#, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s: %s" +msgstr "%s ਫਾਇਲ ਰੱਦੀ 'ਚ ਭੇਜਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/glocalfile.c:2299 +#, c-format +#| msgid "Unable to trash file: %s" +msgid "Unable to trash file %s" +msgstr "%s ਫਾਇਲ ਰੱਦੀ 'ਚ ਭੇਜਣ ਲਈ ਅਸਮਰੱਥ" + +#: gio/glocalfile.c:2325 +#, c-format +#| msgid "Error creating directory '%s': %s" +msgid "Error creating directory %s: %s" +msgstr "%s ਡਾਇਰੈਕਟਰੀ ਬਣਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfile.c:2354 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ਫਾਇਲ-ਸਿਸਟਮ ਸਿੰਬੋਲਿਕ ਲਿੰਕ ਲਈ ਸਹਾਇਕ ਨਹੀਂ" + +#: gio/glocalfile.c:2357 +#, c-format +#| msgid "Error making symbolic link: %s" +msgid "Error making symbolic link %s: %s" +msgstr "ਸਿਬੋਲਿਕ ਲਿੰਕ %s ਬਣਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfile.c:2363 glib/gfileutils.c:2172 +msgid "Symbolic links not supported" +msgstr "ਸਿੰਬੋਲਿਕ ਲਿੰਕ ਮੱਦਦ ਪà©à¨°à¨¾à¨ªà¨¤ ਨਹੀਂ ਹਨ" + +#: gio/glocalfile.c:2418 gio/glocalfile.c:2453 gio/glocalfile.c:2510 +#, c-format +#| msgid "Error moving file: %s" +msgid "Error moving file %s: %s" +msgstr "ਫਾਇਲ %s ਭੇਜਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfile.c:2441 +#| msgid "Can't move directory over directory" +msgid "Can’t move directory over directory" +msgstr "ਡਾਇਰੈਕਟਰੀ ਨੂੰ ਡਾਇਰੈਕਟਰੀ ਉੱਤੇ ਭੇਜਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ" + +#: gio/glocalfile.c:2467 gio/glocalfileoutputstream.c:1031 +#: gio/glocalfileoutputstream.c:1045 gio/glocalfileoutputstream.c:1060 +#: gio/glocalfileoutputstream.c:1077 gio/glocalfileoutputstream.c:1091 +msgid "Backup file creation failed" +msgstr "ਬੈਕਅੱਪ ਫਾਇਲ ਬਣਾਉਣ ਲਈ ਫੇਲà©à¨¹" + +#: gio/glocalfile.c:2486 +#, c-format +msgid "Error removing target file: %s" +msgstr "ਟਾਰਗੇਟ ਫਾਇਲ ਹਟਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfile.c:2500 +msgid "Move between mounts not supported" +msgstr "ਮਾਊਂਟ ਵਿੱਚ ਭੇਜਣਾ ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#: gio/glocalfile.c:2691 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s ਦੀ ਡਿਸਕ ਵਰਤੋਂ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ: %s" + +#: gio/glocalfileinfo.c:752 +msgid "Attribute value must be non-NULL" +msgstr "ਗà©à¨£ ਮà©à©±à¨² ਗ਼ੈਰ-ਨਲ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: gio/glocalfileinfo.c:759 +msgid "Invalid attribute type (string expected)" +msgstr "ਗਲਤ ਗà©à¨£ ਟਾਈਪ (ਲਾਈਨ ਦੀ ਲੋੜ ਸੀ)" + +#: gio/glocalfileinfo.c:766 +msgid "Invalid extended attribute name" +msgstr "ਗਲਤ à¨à¨•ਸਟੈੱਡ ਗà©à¨£ ਨਾਂ" + +#: gio/glocalfileinfo.c:806 +#, c-format +#| msgid "Error setting extended attribute '%s': %s" +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "à¨à¨•ਸਟੈੱਡ ਗà©à¨£ “%s†ਸੈੱਟ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileinfo.c:1634 +msgid " (invalid encoding)" +msgstr "(ਗਲਤ ਇੰਕੋਡਿੰਗ)" + +#: gio/glocalfileinfo.c:1798 gio/glocalfileoutputstream.c:909 +#, c-format +#| msgid "Error when getting information for file '%s': %s" +msgid "Error when getting information for file “%sâ€: %s" +msgstr "ਫਾਇਲ “%s†ਲਈ ਜਾਣਕਾਰੀ ਲੈਣ ਲਈ ਗਲਤੀ: %s" + +#: gio/glocalfileinfo.c:2068 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਲਈ ਜਾਣਕਾਰੀ ਲੈਣ ਦੇ ਦੌਰਾਨ ਗਲਤੀ: %s " + +#: gio/glocalfileinfo.c:2113 +msgid "Invalid attribute type (uint32 expected)" +msgstr "ਗਲਤ à¨à¨Ÿà¨°à©€à¨¬à¨¿à¨Šà¨Ÿ ਟਾਈਪ (uint32 ਲੋੜੀਦਾ ਸੀ)" + +#: gio/glocalfileinfo.c:2131 +msgid "Invalid attribute type (uint64 expected)" +msgstr "ਗਲਤ à¨à¨Ÿà¨°à©€à¨¬à¨¿à¨Šà¨Ÿ ਟਾਈਪ (uint64 ਲੋੜੀਦਾ ਸੀ)" + +#: gio/glocalfileinfo.c:2150 gio/glocalfileinfo.c:2169 +msgid "Invalid attribute type (byte string expected)" +msgstr "ਗਲਤ à¨à¨Ÿà¨°à©€à¨¬à¨¿à¨Šà¨Ÿ ਟਾਈਪ (ਬਾਈਟ ਲਾਈਨ ਲੋੜੀਦੀ ਸੀ)" + +#: gio/glocalfileinfo.c:2216 +msgid "Cannot set permissions on symlinks" +msgstr "ਸਿਮਲਿੰਕਲਈ ਅਧਿਕਾਰ ਨਹੀਂ ਸੈੱਟ ਕੀਤੇ ਜਾ ਸਕਦੇ" + +#: gio/glocalfileinfo.c:2232 +#, c-format +msgid "Error setting permissions: %s" +msgstr "ਅਧਿਕਾਰ ਸੈੱਟ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileinfo.c:2283 +#, c-format +msgid "Error setting owner: %s" +msgstr "ਓਪਨ ਸੈਟਿੰਗ ਗਲਤੀ: %s " + +#: gio/glocalfileinfo.c:2306 +msgid "symlink must be non-NULL" +msgstr "ਸਿਮਲਿੰਕ ਗ਼ੈਰ-ਨਲ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: gio/glocalfileinfo.c:2316 gio/glocalfileinfo.c:2335 +#: gio/glocalfileinfo.c:2346 +#, c-format +msgid "Error setting symlink: %s" +msgstr "symlink ਸੈਟਿੰਗ ਗਲਤੀ: %s " + +#: gio/glocalfileinfo.c:2325 +msgid "Error setting symlink: file is not a symlink" +msgstr "symlink ਸੈਟਿੰਗ ਗਲਤੀ: ਫਾਇਲ ਇੱਕ symlink ਨਹੀਂ ਹੈ" + +#: gio/glocalfileinfo.c:2451 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "ਸੋਧਣ ਜਾਂ ਵਰਤਣ ਸਮਾਂ ਸੈੱਟ ਕਰਨ ਲਈ ਗਲਤੀ: %s" + +#: gio/glocalfileinfo.c:2474 +msgid "SELinux context must be non-NULL" +msgstr "SELinux ਪਰਸੰਗ ਗੈਰ-ਨਲ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: gio/glocalfileinfo.c:2489 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux ਪਰਸੰਗ ਸੈਟ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileinfo.c:2496 +msgid "SELinux is not enabled on this system" +msgstr "ਇਸ ਸਿਸਟਮ ਉੱਤੇ SELinux ਚਾਲੂ ਨਹੀਂ ਹੈ" + +#: gio/glocalfileinfo.c:2588 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "ਗà©à¨£ %s ਸੈਟਿੰਗ ਸਹਾਇਕ ਨਹੀਂ" + +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:792 +#, c-format +msgid "Error reading from file: %s" +msgstr "ਫਾਇਲ ਤੋਂ ਪੜà©à¨¹à¨¨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 +#: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 +#: gio/glocalfileoutputstream.c:554 gio/glocalfileoutputstream.c:1109 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ਫਾਇਲ 'ਚ ਵੇਖਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:344 +#: gio/glocalfileoutputstream.c:438 +#, c-format +msgid "Error closing file: %s" +msgstr "ਫਾਇਲ ਬੰਦ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfilemonitor.c:858 +msgid "Unable to find default local file monitor type" +msgstr "ਡਿਫਾਲਟ ਲੋਕਲ ਫਾਇਲ ਮਾਨੀਟਰ ਟਾਈਪ ਖੋਜਣ ਲਈ ਅਸਮਰੱਥ" + +#: gio/glocalfileoutputstream.c:209 gio/glocalfileoutputstream.c:287 +#: gio/glocalfileoutputstream.c:324 gio/glocalfileoutputstream.c:813 +#, c-format +msgid "Error writing to file: %s" +msgstr "ਫਾਇਲ ਲਿਖਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileoutputstream.c:371 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "ਪà©à¨°à¨¾à¨£à¨¾ ਬੈਕਅੱਪ ਲਿੰਕ ਹਟਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileoutputstream.c:385 gio/glocalfileoutputstream.c:398 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "ਬੈਕਅੱਪ ਕਾਪੀ ਬਣਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileoutputstream.c:416 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "ਆਰਜ਼ੀ ਫਾਇਲ ਨਾਂ ਬਦਲਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileoutputstream.c:600 gio/glocalfileoutputstream.c:1160 +#, c-format +msgid "Error truncating file: %s" +msgstr "ਫਾਇਲ ਸੰਖੇਪ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/glocalfileoutputstream.c:653 gio/glocalfileoutputstream.c:891 +#: gio/glocalfileoutputstream.c:1141 gio/gsubprocess.c:380 +#, c-format +#| msgid "Error opening file '%s': %s" +msgid "Error opening file “%sâ€: %s" +msgstr "“%s†ਫਾਇਲ ਖੋਲà©à¨¹à¨£ 'ਚ ਗਲਤੀ: %s" + +#: gio/glocalfileoutputstream.c:922 +msgid "Target file is a directory" +msgstr "ਟਾਰਗੇਟ ਫਾਇਲ ਡਾਇਰੈਕਟਰੀ ਹੈ" + +#: gio/glocalfileoutputstream.c:927 +msgid "Target file is not a regular file" +msgstr "ਟਾਰਗੇਟ ਫਾਇਲ ਇੱਕ ਰੈਗੂਲਰ ਫਾਇਲ ਨਹੀਂ ਹੈ" + +#: gio/glocalfileoutputstream.c:939 +msgid "The file was externally modified" +msgstr "ਫਾਇਲ ਬਾਹਰੋਂ ਸੋਧੀ ਗਈ ਸੀ" + +#: gio/glocalfileoutputstream.c:1125 +#, c-format +msgid "Error removing old file: %s" +msgstr "ਪà©à¨°à¨¾à¨£à©€ ਫਾਇਲ ਹਟਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "ਗਲਤ GSeekType ਦਿੱਤੀ ਗਈ" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "ਸੀਕ ਮੰਗ ਗਲਤ ਹੈ" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream ਛੋਟੀ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "ਮੈਮੋਰੀ ਆਉਟਪà©à©±à¨Ÿ ਸਟਰੀਮ ਮà©à©œ-ਅਕਾਰ ਯੋਗ ਨਹੀਂ" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "ਮੈਮੋਰੀ ਆਉਟਪà©à©±à¨Ÿ ਸਟਰੀਮ ਮà©à©œ-ਸਾਈਜ਼ ਕਰਨ ਲਈ ਫੇਲà©à¨¹ ਹੈ" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "ਲਿਖਣ ਲਈ ਲੋੜੀਦੀ ਮੈਮੋਰੀ ਦੀ ਮਾਤਰਾ ਉਪਲੱਬਧ à¨à¨¡à¨°à©ˆà©±à¨¸ ਥਾਂ ਤੋਂ ਵੱਧ ਹੈ" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "ਕੀਤੀ ਗਈ ਮੰਗ ਸਟਰੀਮ ਦੇ ਸ਼à©à¨°à©‚ ਤੋਂ ਪਹਿਲਾਂ ਹੈ" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "ਕੀਤੀ ਗਈ ਮੰਗ ਸਟਰੀਮ ਦੇ ਅੰਤ ਤੋਂ ਬਾਅਦ ਹੈ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +#| msgid "mount doesn't implement \"unmount\"" +msgid "mount doesn’t implement “unmountâ€" +msgstr "ਮਾਊਂਟ ਹਾਲੇ ਅਣ-ਮਾਊਂਟ (“unmountâ€) ਲਈ ਸਥਾਪਿਤ ਨਹੀਂ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +#| msgid "mount doesn't implement \"eject\"" +msgid "mount doesn’t implement “ejectâ€" +msgstr "ਮਾਊਂਟ ਹਾਲੇ ਬਾਹਰ ਕੱਢਣ (“ejectâ€) ਲਈ ਸਥਾਪਤ ਨਹੀਂ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +#| msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "ਮਾਊਂਟ ਲਈ ਹਾਲੇ “unmount†ਜਾਂ “unmount_with_operation†ਸਥਾਪਿਤ ਨਹੀਂ।" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +#| msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "ਮਾਊਂਟ ਲਈ “eject†ਜਾਂ “eject_with_operation†ਸਥਾਪਿਤ ਨਹੀਂ ਹੈ।" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +#| msgid "mount doesn't implement \"remount\"" +msgid "mount doesn’t implement “remountâ€" +msgstr "ਮਾਊਂਟ ਹਾਲੇ ਰੀ-ਮਾਊਂਟ (“remountâ€) ਲਈ ਸਥਾਪਿਤ ਨਹੀਂ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +#| msgid "mount doesn't implement content type guessing" +msgid "mount doesn’t implement content type guessing" +msgstr "ਪਰਸੰਗ ਟਾਈਪ ਗੈੱਸਿੰਗ ਲਈ ਮਾਊਂਟ ਸਥਾਪਤ ਨਹੀਂ ਹੈ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +#| msgid "mount doesn't implement synchronous content type guessing" +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "ਸੈਕਰੋਨਿਸ ਪਰਸੰਗ ਟਾਈਪ ਗੈਸਿੰਗ ਲਈ ਮਾਊਂਟ ਸਥਾਪਤ ਨਹੀਂ ਹੈ" + +#: gio/gnetworkaddress.c:415 +#, fuzzy, c-format +#| msgid "Hostname '%s' contains '[' but not ']'" +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "ਹੋਸਟ-ਨਾਂ '%s' '[' ਰੱਖਦਾ ਹੈ, ਪਰ ']' ਨਹੀਂ" + +#: gio/gnetworkmonitorbase.c:211 gio/gnetworkmonitorbase.c:315 +msgid "Network unreachable" +msgstr "ਨੈੱਟਵਰਕ ਪਹà©à©°à¨š 'ਚ ਨਹੀਂ" + +#: gio/gnetworkmonitorbase.c:249 gio/gnetworkmonitorbase.c:279 +msgid "Host unreachable" +msgstr "ਹੋਸਟ ਪਹà©à©°à¨š 'ਚ ਨਹੀਂ" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "ਨੈੱਟਵਰਕ ਮਾਨੀਟਰ ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "ਨੈੱਟਵਰਕ ਮਾਨੀਟਰ ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "ਨੈੱਟਵਰਕ ਹਾਲਤ ਲਈ ਨਹੀਂ ਜਾ ਸਕੀ: " + +#: gio/gnetworkmonitornm.c:348 +#, c-format +#| msgid "NetworkManager version too old" +msgid "NetworkManager not running" +msgstr "ਨੈੱਟਵਰਕਮੈਨੇਜਰ ਚੱਲ ਨਹੀਂ ਰਿਹਾ ਹੈ" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "ਨੈਟਵਰਕਮੈਨੇਜਰ ਵਰਜ਼ਨ ਬਹà©à¨¤ ਪà©à¨°à¨¾à¨£à¨¾ ਹੈ" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +#| msgid "Output stream doesn't implement write" +msgid "Output stream doesn’t implement write" +msgstr "ਆਉਟਪà©à©±à¨Ÿ ਸਟਰੀਮ ਲਿਕਣ ਲਈ ਬਣਾਈ ਨਹੀਂ ਗਈ" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "ਸਰੋਤ ਸਟਰੀਮ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ" + +#: gio/gresolver.c:351 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +#| msgid "Error resolving '%s': %s" +msgid "Error resolving “%sâ€: %s" +msgstr "“%s†ਲੱਭਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:398 gio/gresolver.c:556 +#, c-format +#| msgid "Input stream doesn't implement read" +msgid "%s not implemented" +msgstr "%s ਸਥਾਪਿਤ ਨਹੀਂ ਹੈ" + +#: gio/gresolver.c:924 gio/gresolver.c:976 +#| msgid "Invalid filename" +msgid "Invalid domain" +msgstr "ਗਲਤ ਡੋਮੇਨ" + +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +#| msgid "The resource at '%s' does not exist" +msgid "The resource at “%s†does not exist" +msgstr "“%s†ਉੱਤੇ ਸਰੋਤ ਮੌਜੂਦ ਨਹੀਂ ਹੈ" + +#: gio/gresource.c:830 +#, c-format +#| msgid "The resource at '%s' failed to decompress" +msgid "The resource at “%s†failed to decompress" +msgstr "“%s†ਉੱਤੇ ਸਰੋਤ ਡੀਕੰਪਰੈਸ ਕਰਨ ਲਈ ਫੇਲà©à¨¹" + +#: gio/gresourcefile.c:732 +#, c-format +#| msgid "The resource at '%s' is not a directory" +msgid "The resource at “%s†is not a directory" +msgstr "“%s†ਉੱਤੇ ਸਰੋਤ ਡਾਇਰੈਕਟਰੀ ਨਹੀਂ ਹੈ" + +#: gio/gresourcefile.c:940 +#| msgid "Input stream doesn't implement seek" +msgid "Input stream doesn’t implement seek" +msgstr "ਇੰਪà©à©±à¨Ÿ ਸਟਰੀਮ ਲਈ seek ਸਥਾਪਿਤ ਨਹੀਂ ਹੈ" + +#: gio/gresource-tool.c:499 +msgid "List sections containing resources in an elf FILE" +msgstr "elf FILE ਵਿੱਚ ਮੌਜੂਦ ਸ਼ੈਕਸ਼ਨ ਰੱਖਣ ਵਾਲੇ ਸਰੋਤਾਂ ਦੀ ਸੂਚੀ" + +#: gio/gresource-tool.c:505 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"ਸਰੋਤਾਂ ਦੀ ਸੂਚੀ\n" +"ਜੇ SECTION ਦਿੱਤਾ ਤਾਂ ਇਹ ਸ਼ੈਕਸ਼ਨ ਵਿੱਚ ਸਰੋਤ ਵੇਖਾਠਜਾਣਗੇ\n" +"ਜੇ PATH ਦਿੱਤਾ ਤਾਂ ਕੇਵਲ ਮਿਲਦੀ ਸਰੋਤ ਹੀ ਵੇਖਾਠਜਾਂਦੇ ਹਨ" + +#: gio/gresource-tool.c:508 gio/gresource-tool.c:518 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 gio/gresource-tool.c:526 +msgid "SECTION" +msgstr "SECTION" + +#: gio/gresource-tool.c:514 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"ਵੇਰਵੇ ਸਮੇਤ ਸਰੋਤਾਂ ਦੀ ਸੂਚੀ\n" +"ਜੇ SECTION ਦਿੱਤਾ ਤਾਂ ਇਹ ਸ਼ੈਕਸ਼ਨ ਵਿੱਚ ਸਰੋਤ ਵੇਖਾਠਜਾਣਗੇ\n" +"ਜੇ PATH ਦਿੱਤਾ ਤਾਂ ਕੇਵਲ ਮਿਲਦੀ ਸਰੋਤ ਹੀ ਵੇਖਾਠਜਾਂਦੇ ਹਨ\n" +"ਵੇਰਵੇ ਵਿੱਚ ਸ਼ੈਕਸ਼ਨ, ਆਕਾਰ ਅਤੇ ਕੰਪਰੈਸ਼ਨ ਹà©à©°à¨¦à©€ ਹੈ" + +#: gio/gresource-tool.c:524 +msgid "Extract a resource file to stdout" +msgstr "ਸਰੋਤ ਫਾਇਲ ਨੂੰ stdout ਉੱਤੇ ਖੋਲà©à¨¹à©‹" + +#: gio/gresource-tool.c:525 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: gio/gresource-tool.c:539 +#| msgid "" +#| "Usage:\n" +#| " gresource [--section SECTION] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " sections List resource sections\n" +#| " list List resources\n" +#| " details List resources with details\n" +#| " extract Extract a resource\n" +#| "\n" +#| "Use 'gresource help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ਵਰਤੋਂ:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" + +#: gio/gresource-tool.c:553 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ਵਰਤੋਂ:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:560 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION ਇੱਕ (ਚੋਣਵਾਂ) elf ਭਾਗ ਨਾਂ\n" + +#: gio/gresource-tool.c:564 gio/gsettings-tool.c:701 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND (ਚੋਣਵਾਂ) ਕਮਾਂਡ ਬਾਰੇ ਜਾਣਕਾਰੀ\n" + +#: gio/gresource-tool.c:570 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE elf ਫਾਇਲ (ਬਾਈਨਰੀ ਜਾਂ ਸਾਂà¨à©€ ਲਾਇਬਰੇਰੀ)\n" + +#: gio/gresource-tool.c:573 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE elf ਫਾਇਲ (ਬਾਈਨਰੀ ਜਾਂ ਸਾਂà¨à©€ ਲਾਇਬਰੇਰੀ)\n" +" ਜਾਂ ਇੱਕ ਕੰਪਾਇਲ ਕੀਤੀ ਸਰੋਤ ਫਾਇਲ\n" + +#: gio/gresource-tool.c:577 +msgid "[PATH]" +msgstr "[PATH]" + +#: gio/gresource-tool.c:579 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH ਇੱਕ (ਚੋਣਵਾਂ) ਸਰੋਤ ਪਾਥ (ਅਧੂਰਾ ਵੀ ਹੋ ਸਕਦਾ ਹੈ)\n" + +#: gio/gresource-tool.c:580 +msgid "PATH" +msgstr "PATH" + +#: gio/gresource-tool.c:582 +msgid " PATH A resource path\n" +msgstr " PATH ਇੱਕ ਸਰੋਤ ਪਾਥ\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:906 +#, c-format +#| msgid "No such schema '%s'\n" +msgid "No such schema “%sâ€\n" +msgstr "ਇੰਠਦਾ ਕੋਈ ਵੀ “%s†ਸਕੀਮਾ ਨਹੀਂ\n" + +#: gio/gsettings-tool.c:55 +#, c-format +#| msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "ਸਕੀਮਾ “%s†ਮà©à©œ-ਬਦਲਣਯੋਗ ਨਹੀਂ ਹੈ (ਪਾਥ ਨਹੀਂ ਦਿੱਤਾ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +#| msgid "Schema '%s' is relocatable (path must be specified)\n" +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "ਸਕੀਮਾ “%s†ਮà©à©œ-ਬਦਲਣਯੋਗ ਹੈ (ਪਾਥ ਦਿੱਤਾ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "ਖਾਲੀ ਪਾਥ ਦਿੱਤਾ।\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "ਪਾਥ ਸਲੈਸ਼ (/) ਨਾਲ ਸ਼à©à¨°à©‚ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "ਪਾਥ ਸਲੈਸ਼ (/) ਨਾਲ ਖਤਮ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "ਪਾਥ ਵਿੱਚ ਦੋ ਲਗਾਤਾਰ ਸਲੈਸ਼ (//) ਨਹੀਂ ਹੋ ਸਕਦੀਆਂ\n" + +#: gio/gsettings-tool.c:536 +msgid "The provided value is outside of the valid range\n" +msgstr "ਦਿੱਤਾ ਮà©à©±à¨² ਢà©à©±à¨•ਵੀਂ ਰੇਜ਼ ਤੋਂ ਬਾਹਰ ਹੈ\n" + +#: gio/gsettings-tool.c:543 +msgid "The key is not writable\n" +msgstr "ਕà©à©°à¨œà©€ ਲਿਖਣਯੋਗ ਨਹੀਂ ਹੈ\n" + +#: gio/gsettings-tool.c:579 +msgid "List the installed (non-relocatable) schemas" +msgstr "ਇੰਸਟਾਲ ਹੋਠ(ਗ਼ੈਰ-ਬਦਲਣਯੋਗ) ਸਕੀਮਾ ਦੀ ਲਿਸਟ" + +#: gio/gsettings-tool.c:585 +msgid "List the installed relocatable schemas" +msgstr "ਇੰਸਟਾਲ ਹੋਠਬਦਲਣਯੋਗ ਸਕੀਮਾ ਦੀ ਲਿਸਟ" + +#: gio/gsettings-tool.c:591 +msgid "List the keys in SCHEMA" +msgstr "SCHEMA ਵਿੱਚ ਕà©à©°à¨œà©€à¨†à¨‚ ਦੀ ਲਿਸਟ" + +#: gio/gsettings-tool.c:592 gio/gsettings-tool.c:598 gio/gsettings-tool.c:641 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:597 +msgid "List the children of SCHEMA" +msgstr "SCHEMA ਵਿੱਚ ਚਿਲਡਰਨ ਦੀ ਲਿਸਟ" + +#: gio/gsettings-tool.c:603 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"ਕà©à©°à¨œà©€à¨†à¨‚ ਤੇ ਮà©à©±à¨² ਲਗਾਤਾਰ ਲਿਸਟ ਕਰੋ\n" +"ਜੇ ਕੋਈ SCHEMA ਨਹੀਂ ਦਿੱਤਾ ਤਾਂ, ਸਭ ਕà©à©°à¨œà©€à¨†à¨‚ ਦਿਉ\n" + +#: gio/gsettings-tool.c:605 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:610 +msgid "Get the value of KEY" +msgstr "KEY ਦਾ ਮà©à©±à¨² ਲਵੋ" + +#: gio/gsettings-tool.c:611 gio/gsettings-tool.c:617 gio/gsettings-tool.c:623 +#: gio/gsettings-tool.c:635 gio/gsettings-tool.c:647 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:616 +msgid "Query the range of valid values for KEY" +msgstr "KEY ਲਈ ਢà©à©±à¨•ਵੇਂ ਮà©à©±à¨² ਲਈ ਰੇਜ਼ ਕਿਊਰੀਆਂ" + +#: gio/gsettings-tool.c:622 +#, fuzzy +#| msgid "Query the range of valid values for KEY" +msgid "Query the description for KEY" +msgstr "KEY ਲਈ ਢà©à©±à¨•ਵੇਂ ਮà©à©±à¨² ਲਈ ਰੇਜ਼ ਕਿਊਰੀਆਂ" + +#: gio/gsettings-tool.c:628 +msgid "Set the value of KEY to VALUE" +msgstr "KEY ਲਈ ਮà©à©±à¨² (VALUE) ਸੈੱਟ ਕਰੋ" + +#: gio/gsettings-tool.c:629 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:634 +msgid "Reset KEY to its default value" +msgstr "KEY ਨੂੰ ਡਿਫਾਲਟ ਮà©à©±à¨² ਲਈ ਮà©à©œ-ਸੈੱਟ ਕਰੋ" + +#: gio/gsettings-tool.c:640 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "SCHEMA ਵਿੱਚ ਸਭ ਸਵਿੱਚਾਂ ਨੂੰ ਉਹਨਾਂ ਦੇ ਡਿਫਾਲਟ ਲਈ ਮà©à©œ-ਸੈੱਟ ਕਰੋ" + +#: gio/gsettings-tool.c:646 +msgid "Check if KEY is writable" +msgstr "ਚੈੱਕ ਕਰੋ ਕਿ KEY ਲਿਖਣਯੋਗ ਹੈ" + +#: gio/gsettings-tool.c:652 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"KEY ਲਈ ਬਦਲਾਅ ਉੱਤੇ ਨਿਗà©à¨¹à¨¾ ਰੱਖੋ।\n" +"ਜੇ ਕੋਈ KEY ਨਾ ਦਿੱਤੀ ਹੋਵੇ ਤਾਂ SCHEMA ਵਿੱਚ ਸਭ ਕà©à©°à¨œà©€à¨†à¨‚ ਤੇ ਨਿਗà©à¨¹à¨¾ ਰੱਖੋ।\n" +"ਨਿਗਰਾਨੀ ਬੰਦ ਕਰਨ ਲਈ ^C ਵਰਤੋਂ।\n" + +#: gio/gsettings-tool.c:655 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: gio/gsettings-tool.c:667 +#| msgid "" +#| "Usage:\n" +#| " gsettings --version\n" +#| " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " list-schemas List installed schemas\n" +#| " list-relocatable-schemas List relocatable schemas\n" +#| " list-keys List keys in a schema\n" +#| " list-children List children of a schema\n" +#| " list-recursively List keys and values, recursively\n" +#| " range Queries the range of a key\n" +#| " get Get the value of a key\n" +#| " set Set the value of a key\n" +#| " reset Reset the value of a key\n" +#| " reset-recursively Reset all values in a given schema\n" +#| " writable Check if a key is writable\n" +#| " monitor Watch for changes\n" +#| "\n" +#| "Use 'gsettings help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ਵਰਤੋਂ:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" + +#: gio/gsettings-tool.c:691 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ਵਰਤੋਂ:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:697 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR ਇੱਕ ਡਾਇਰੈਕਟਰੀ, ਜੋ ਕਿ ਹੋਰ ਸਕੀਮਾ ਲੱਭਣ ਲਈ ਹੈ\n" + +#: gio/gsettings-tool.c:705 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA ਸਕੀਮਾ ਦਾ ਨਾਂ\n" +" PATH ਮà©à©œ-ਲੱਭਣਯੋਗ ਸਕੀਮਾ ਲਈ ਪਾਥ\n" + +#: gio/gsettings-tool.c:710 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY ਸਕੀਮਾ ਵਿੱਚ (ਚੋਣਵੀਂ) ਕà©à©°à¨œà©€\n" + +#: gio/gsettings-tool.c:714 +msgid " KEY The key within the schema\n" +msgstr " KEY ਸਕੀਮਾ ਵਿੱਚ ਕà©à©°à¨œà©€\n" + +#: gio/gsettings-tool.c:718 +msgid " VALUE The value to set\n" +msgstr " VALUE ਸੈੱਟ ਕਰਨ ਲਈ ਮà©à©±à¨²\n" + +#: gio/gsettings-tool.c:773 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s ਤੋਂ ਸਕੀਮਾ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ: %s\n" + +#: gio/gsettings-tool.c:785 +#, fuzzy +#| msgid "No schema files found: " +msgid "No schemas installed\n" +msgstr "ਕੋਈ ਸਕੀਮਾਂ ਫਾਇਲ ਨਹੀਂ ਲੱਭੀ: " + +#: gio/gsettings-tool.c:864 +msgid "Empty schema name given\n" +msgstr "ਖਾਲੀ ਸਕੀਮਾ ਨਾਂ ਦਿੱਤਾ\n" + +#: gio/gsettings-tool.c:919 +#, c-format +#| msgid "No such key '%s'\n" +msgid "No such key “%sâ€\n" +msgstr "ਇੰਠਦੀ “%s†ਕà©à©°à¨œà©€ ਨਹੀਂ\n" + +#: gio/gsocket.c:374 +msgid "Invalid socket, not initialized" +msgstr "ਗਲਤ ਸਾਕਟ, ਸ਼à©à¨°à©‚ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: gio/gsocket.c:381 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ਗਲਤ ਸਾਕਟ, %s: ਕਰਕੇ ਸ਼à©à¨°à©‚ ਕਰਨ ਲਈ ਫੇਲà©à¨¹" + +#: gio/gsocket.c:389 +msgid "Socket is already closed" +msgstr "ਸਾਕਟ ਪਹਿਲਾਂ ਹੀ ਬੰਦ ਹੈ" + +#: gio/gsocket.c:404 gio/gsocket.c:3134 gio/gsocket.c:4351 gio/gsocket.c:4409 +msgid "Socket I/O timed out" +msgstr "ਸਾਕਟ I/O ਟਾਈਮ-ਆਉਟ" + +#: gio/gsocket.c:539 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd ਤੋਂ ਜੀਸਾਕਟ ਬਣਾਈ ਜਾ ਰਹੀ ਹੈ: %s" + +#: gio/gsocket.c:568 gio/gsocket.c:622 gio/gsocket.c:629 +#, c-format +msgid "Unable to create socket: %s" +msgstr "ਸਾਕਟ ਬਣਾਉਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/gsocket.c:622 +msgid "Unknown family was specified" +msgstr "ਅਣਜਾਣ ਵਰਗ ਦਿੱਤਾ ਗਿਆ" + +#: gio/gsocket.c:629 +msgid "Unknown protocol was specified" +msgstr "ਅਣਜਾਣ ਪਰੋਟੋਕਾਲ ਦਿੱਤਾ ਗਿਆ" + +#: gio/gsocket.c:1120 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" + +#: gio/gsocket.c:1137 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" + +#: gio/gsocket.c:1944 +#, c-format +msgid "could not get local address: %s" +msgstr "ਲੋਕਲ à¨à¨¡à¨°à©ˆà©±à¨¸ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਿਆ: %s" + +#: gio/gsocket.c:1990 +#, c-format +msgid "could not get remote address: %s" +msgstr "ਰਿਮੋਟ à¨à¨¡à¨°à©ˆà©±à¨¸ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਿਆ: %s" + +#: gio/gsocket.c:2056 +#, c-format +msgid "could not listen: %s" +msgstr "ਸà©à¨£à¨¿à¨† ਨਹੀਂ ਜਾ ਸਕਿਆ: %s" + +#: gio/gsocket.c:2158 +#, c-format +msgid "Error binding to address: %s" +msgstr "à¨à¨¡à¨°à©ˆà©±à¨¸ ਸਬੰਧਿਤ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:2332 gio/gsocket.c:2369 gio/gsocket.c:2479 gio/gsocket.c:2504 +#: gio/gsocket.c:2567 gio/gsocket.c:2625 gio/gsocket.c:2643 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "ਮਲਟੀਕਾਸਟ ਗਰà©à©±à¨ª ਜà©à¨†à¨‡à©°à¨¨ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:2333 gio/gsocket.c:2370 gio/gsocket.c:2480 gio/gsocket.c:2505 +#: gio/gsocket.c:2568 gio/gsocket.c:2626 gio/gsocket.c:2644 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "ਮਲਟੀਕਾਸਟ ਗਰà©à©±à¨ª ਛੱਡਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:2334 +msgid "No support for source-specific multicast" +msgstr "ਸਰੋਤ-ਖਾਸ ਮਲਟੀਕਾਸਟ ਲਈ ਕੋਈ ਸਹਿਯੋਗ ਨਹੀਂ" + +#: gio/gsocket.c:2481 +#| msgid "Unsupported socket address" +msgid "Unsupported socket family" +msgstr "ਗ਼ੈਰ-ਸਹਾਇਕ ਸਾਕਟ ਵਰਗ" + +#: gio/gsocket.c:2506 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2530 +#, c-format +msgid "Interface name too long" +msgstr "" + +#: gio/gsocket.c:2543 gio/gsocket.c:2593 +#, c-format +msgid "Interface not found: %s" +msgstr "" + +#: gio/gsocket.c:2569 +#| msgid "No support for source-specific multicast" +msgid "No support for IPv4 source-specific multicast" +msgstr "IPv4 ਸਰੋਤ-ਖਾਸ ਮਲਟੀਕਾਸਟ ਲਈ ਕੋਈ ਸਹਿਯੋਗ ਨਹੀਂ" + +#: gio/gsocket.c:2627 +#| msgid "No support for source-specific multicast" +msgid "No support for IPv6 source-specific multicast" +msgstr "IPv6 ਸਰੋਤ-ਖਾਸ ਮਲਟੀਕਾਸਟ ਲਈ ਕੋਈ ਸਹਿਯੋਗ ਨਹੀਂ" + +#: gio/gsocket.c:2836 +#, c-format +msgid "Error accepting connection: %s" +msgstr "ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਮਨਜ਼ੂਰ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:2962 +msgid "Connection in progress" +msgstr "ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਜਾਰੀ ਹੈ" + +#: gio/gsocket.c:3013 +msgid "Unable to get pending error: " +msgstr "ਬਾਕੀ ਗਲਤੀ ਲੈਣ ਲਈ ਅਸਮਰੱਥ: " + +#: gio/gsocket.c:3199 +#, c-format +msgid "Error receiving data: %s" +msgstr "ਡਾਟਾ ਲੈਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:3396 +#, c-format +msgid "Error sending data: %s" +msgstr "ਡਾਟਾ ਭੇਜਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:3583 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ਸਾਕਟ ਬੰਦ ਕਰਨ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/gsocket.c:3664 +#, c-format +msgid "Error closing socket: %s" +msgstr "ਸਾਕਟ ਬੰਦ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:4344 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ਸਾਕਟ ਸ਼ਰਤ ਲਈ ਉਡੀਕ ਜਾਰੀ: %s" + +#: gio/gsocket.c:4722 gio/gsocket.c:4724 gio/gsocket.c:4871 gio/gsocket.c:4956 +#: gio/gsocket.c:5134 gio/gsocket.c:5174 gio/gsocket.c:5176 +#, c-format +msgid "Error sending message: %s" +msgstr "ਸà©à¨¨à©‡à¨¹à¨¾ ਭੇਜਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:4898 +msgid "GSocketControlMessage not supported on Windows" +msgstr "ਵਿੰਡੋਜ਼ ਉੱਤੇ GSocketControlMessage ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + +#: gio/gsocket.c:5367 gio/gsocket.c:5440 gio/gsocket.c:5666 +#, c-format +msgid "Error receiving message: %s" +msgstr "ਸà©à¨¨à©‡à¨¹à¨¾ ਲੈਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gsocket.c:5947 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "ਸਾਕਟ ਸਨਦ ਪੜà©à¨¹à¨¨ ਲਈ ਅਸਮਰੱਥ: %s" + +#: gio/gsocket.c:5956 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "ਇਸ ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਲਈ g_socket_get_credentials ਬਣਾਇਆ ਨਹੀਂ" + +#: gio/gsocketclient.c:182 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "%s ਪਰਾਕਸੀ ਸਰਵਰ ਨਾਲ ਕà©à¨¨à©ˆà¨•ਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ: " + +#: gio/gsocketclient.c:196 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s ਨਾਲ ਕà©à¨¨à©ˆà¨•ਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ: " + +#: gio/gsocketclient.c:198 +msgid "Could not connect: " +msgstr "ਕà©à¨¨à©ˆà¨•ਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ: " + +#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1764 +msgid "Unknown error on connect" +msgstr "ਕà©à¨¨à©ˆà¨•ਟ ਉੱਤੇ ਅਣਜਾਣ ਗਲਤੀ" + +#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1672 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "ਗ਼ੈਰ-TCP ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਉੱਤੇ ਪਰਾਕਸੀ ਵਰਤਣਾ ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + +#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698 +#, c-format +#| msgid "Proxy protocol '%s' is not supported." +msgid "Proxy protocol “%s†is not supported." +msgstr "ਪਰਾਕਸੀ ਪਰੋਟੋਕਾਲ “%s†ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "ਲਿਸਨਰ ਪਹਿਲਾਂ ਹੀ ਬੰਦ ਹੈ" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "ਸਾਕਟ ਪਹਿਲਾਂ ਹੀ ਬੰਦ ਹੈ" + +#: gio/gsocks4aproxy.c:118 +#, c-format +#| msgid "SOCKSv4 does not support IPv6 address '%s'" +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 IPv6 à¨à¨¡à¨°à©ˆà©±à¨¸ “%s†ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 ਪਰੋਟੋਕਾਲ ਲਈ ਬਹà©à¨¤ ਲੰਮਾ ਯੂਜ਼ਰ ਨਾਂ ਹੈ" + +#: gio/gsocks4aproxy.c:153 +#, c-format +#| msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 ਪਰੋਟੋਕਾਲ ਲਈ “%s†ਹੋਸਟ-ਨਾਂ ਬਹà©à¨¤ ਲੰਮਾ ਹੈ" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "ਸਰਵਰ ਇੱਕ SOCKSv4 ਪਰਾਕਸੀ ਸਰਵਰ ਨਹੀਂ ਹੈ।" + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv5 ਸਰਵਰ ਰਾਹੀਂ ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਨੂੰ ਰੱਦ ਕੀਤਾ ਗਿਆ ਹੈ" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:324 gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "ਸਰਵਰ SOCKSv5 ਪਰਾਕਸੀ ਸਰਵਰ ਨਹੀਂ ਹੈ।" + +#: gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 ਪਰਾਕਸੀ ਲਈ ਪਰਮਾਣਿਕਤਾ ਦੀ ਲੋੜ ਹੈ।" + +#: gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 ਲਈ ਅਜਿਹੇ ਪਰਮਾਣਿਕਤਾ ਢੰਗ ਦੀ ਲੋੜ ਹੈ, ਜੋ ਕਿ GLib ਵਲੋਂ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" + +#: gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 ਪਰੋਟੋਕਾਲ ਲਈ ਬਹà©à¨¤ ਲੰਮਾ ਵਰਤੋਂਕਾਰ ਨਾਂ ਜਾਂ ਪਾਸਵਰਡ ਹੈ।" + +#: gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 ਪਰਮਾਣਕਿਤਾ ਗਲਤ ਵਰਤੋਂਕਾਰ-ਨਾਂ ਜਾਂ ਪਾਸਵਰਡ ਕਰਕੇ ਫੇਲà©à¨¹ ਹੋ ਗਈ ਹੈ" + +#: gio/gsocks5proxy.c:286 +#, c-format +#| msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "SOCKSv5 ਪਰੋਟੋਕਾਲ ਲਈ “%s†ਹੋਸਟ-ਨਾਂ ਬਹà©à¨¤ ਲੰਮਾ ਹੈ।" + +#: gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 ਪਰਾਕਸੀ ਸਰਵਰ ਅਣਜਾਣ à¨à¨¡à¨°à©ˆà©±à¨¸ ਕਿਸਮ ਵਰਤਦਾ ਹੈ।" + +#: gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "ਅੰਦਰੂਨੀ SOCKSv5 ਪਰਾਕਸੀ ਸਰਵਰ ਗਲਤੀ।" + +#: gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ruleset ਨਾਲ ਮਨਜ਼ੂਰ ਨਹੀਂ ਹੈ।" + +#: gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 ਸਰਵਰ ਰਾਹੀਂ ਹੋਸਟ ਪਹà©à©°à¨š-ਯੋਗ ਨਹੀਂ ਹੈ।" + +#: gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 ਪਰਾਕਸੀ ਰਾਹੀਂ ਨੈੱਟਵਰਕ ਪਹà©à©°à¨š 'ਚ ਨਹੀਂ ਹੈ।" + +#: gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 ਪਰਾਕਸੀ ਨੇ ਕà©à¨¨à©ˆà¨•ਸ਼ਨ ਤੋਂ ਇਨਕਾਰ ਕਰ ਦਿੱਤਾ ਹੈ।" + +#: gio/gsocks5proxy.c:386 +#| msgid "SOCKSv5 proxy does not support 'connect' command." +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 ਪਰਾਕਸੀ “connect†ਕਮਾਂਡ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" + +#: gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 ਪਰਾਕਸੀ ਦਿੱਤੀ à¨à¨¡à¨°à©ˆà©±à¨¸ ਕਿਸਮ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" + +#: gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "ਅਣਜਾਣ SOCKSv5 ਪਰਾਕਸੀ ਗਲਤੀ ਹੈ।" + +#: gio/gthemedicon.c:595 +#, c-format +#| msgid "Can't handle version %d of GThemedIcon encoding" +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon ਇੰਕੋਡਿੰਗ ਦਾ %d ਵਰਜਨ ਹੈਂਡਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "ਕੋਈ ਜਾਇਜ਼ ਸਿਰਨਾਵੇ ਨਹੀਂ ਲੱਭੇ" + +#: gio/gthreadedresolver.c:334 +#, c-format +#| msgid "Error reverse-resolving '%s': %s" +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "“%s†ਉਲਟ-ਲੱਭਣ ਲਈ ਗਲਤੀ: %s" + +#: gio/gthreadedresolver.c:671 gio/gthreadedresolver.c:750 +#: gio/gthreadedresolver.c:848 gio/gthreadedresolver.c:898 +#, c-format +#| msgid "No DNS record of the requested type for '%s'" +msgid "No DNS record of the requested type for “%sâ€" +msgstr "“%s†ਲਈ ਮੰਗੀ ਕਿਸਮ ਦਾ ਕੋਈ ਵੀ DNS ਰਿਕਾਰਡ ਨਹੀਂ" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:853 +#, c-format +#| msgid "Temporarily unable to resolve '%s'" +msgid "Temporarily unable to resolve “%sâ€" +msgstr "“%s†ਲੱਭਣ ਲਈ ਆਰਜ਼ੀ ਰੂਪ ਵਿੱਚ ਅਸਮਰੱਥ" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#: gio/gthreadedresolver.c:968 +#, c-format +#| msgid "Error resolving '%s'" +msgid "Error resolving “%sâ€" +msgstr "“%s†ਲੱਭਣ ਦੌਰਾਨ ਗਲਤੀ" + +#: gio/gtlscertificate.c:243 +msgid "No PEM-encoded private key found" +msgstr "ਕੋਈ PEM-ਇੰਕੋਡ ਕੀਤੀ ਪà©à¨°à¨¾à¨ˆà¨µà©‡à¨Ÿ ਕà©à©°à¨œà©€ ਨਹੀਂ ਲੱਭੀ" + +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-ਇੰਕੋਡ ਕੀਤੀ ਪà©à¨°à¨¾à¨ˆà¨µà©‡à¨Ÿ ਕà©à©°à¨œà©€ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦਾ" + +#: gio/gtlscertificate.c:264 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-ਇੰਕੋਡ ਕੀਤੀ ਪà©à¨°à¨¾à¨ˆà¨µà©‡à¨Ÿ ਕà©à©°à¨œà©€ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ" + +#: gio/gtlscertificate.c:291 +msgid "No PEM-encoded certificate found" +msgstr "ਕੋਈ PEM-ਇੰਕੋਡ ਕੀਤਾ ਸਰਟੀਫਿਕੇਟ ਨਹੀਂ ਲੱਭਿਆ ਹੈ" + +#: gio/gtlscertificate.c:300 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-ਇੰਕੋਡ ਕੀਤਾ ਸਰਟੀਫਿਕੇਟ ਪਾਰਸ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"ਇਹ ਠੀਕ ਪਾਸਵਰਡ ਦੇਣ ਦਾ ਆਖਰੀ ਮੌਕਾ ਹੈ, ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕੀ ਤà©à¨¹à¨¾à¨¡à©€ ਅਸੈਸ ਲਾਕ ਹੋ ਜਾਵੇ।" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +#| msgid "" +#| "Several password entered have been incorrect, and your access will be " +#| "locked out after further failures." +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"ਦਿੱਤੇ ਪਾਸਵਰਡ ਬਹà©à¨¤ ਵਾਰ ਗਲਤ ਹੋ ਚà©à©±à¨•ੇ ਹਨ, ਅਤੇ ਹੋਰ ਵਾਰ ਫੇਲà©à¨¹ ਹੋਣ ਦੀ ਹਾਲਤ ਤà©à¨¹à¨¾à¨¡à©€" +" ਵਰਤਣ ਦੀ " +"ਸਮੱਰਥਾ (ਅਸੈਸ) ਨੂੰ ਲਾਕ ਕਰ ਦਿੱਤਾ ਜਾਵੇਗਾ।" + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "ਦਿੱਤਾ ਗਿਆ ਪਾਸਵਰਡ ਗਲਤ ਹੈ।" + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 ਕੰਟਰੋਲ ਸà©à¨¨à©‡à¨¹à©‡ ਦੀ ਲੋੜ ਸੀ, %d ਮਿਲੇ" +msgstr[1] "1 ਕੰਟਰੋਲ ਸà©à¨¨à©‡à¨¹à©‡ ਦੀ ਲੋੜ ਸੀ, %d ਮਿਲੇ" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "ਅਚੀਲਿਰੇ ਡਾਟਾ ਦੀ ਅਣਜਾਣ ਕਿਸਮ" + +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "ਇੱਕ fd ਦੀ ਲੋੜ ਸੀ, ਪਰ %d ਮਿਲੀਆਂ।\n" +msgstr[1] "ਇੱਕ fd ਦੀ ਲੋੜ ਸੀ, ਪਰ %d ਮਿਲੀਆਂ।\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "ਗਲਤ fd ਮਿਲੀ" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "ਸਨਦ ਭੇਜਣ ਦੌਰਾਨ ਗਲਤੀ: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "%s: ਸਾਕਟ ਲਈ SO_PASSCRED ਚਾਲੂ ਹੈ ਜਾਂ ਨਹੀਂ ਚੈੱਕ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED ਚਾਲੂ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"ਮਿਲੀ ਸਨਦ (credentials) ਲਈ ਇੱਕਲਾ ਬਾਈਟ ਪੜà©à¨¹à¨¨ ਦੀ ਲੋੜ ਸੀ, ਪਰ ਮਿਲੇ ਸਿਫ਼ਰ ਬਾਈਟ" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "ਕੋਈ ਲੋੜੀਦਾ ਕੰਟਰੋਲ ਸà©à¨¨à©‡à¨¹à¨¾ ਨਹੀਂ, ਪਰ %d ਮਿਲੇ" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED ਬੰਦ ਕਰਨ ਦੇ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gunixinputstream.c:372 gio/gunixinputstream.c:393 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਤੋਂ ਪੜà©à¨¹à¨¨ ਥਈ ਗਲਤੀ: %s" + +#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:535 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਬੰਦ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gunixmounts.c:2661 gio/gunixmounts.c:2714 +msgid "Filesystem root" +msgstr "ਫਾਇਲ ਸਿਸਟਮ ਰੂਟ" + +#: gio/gunixoutputstream.c:372 gio/gunixoutputstream.c:392 +#: gio/gunixoutputstream.c:479 gio/gunixoutputstream.c:499 +#: gio/gunixoutputstream.c:676 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਲਿਖਣ ਲਈ ਗਲਤੀ: %s" + +#: gio/gunixsocketaddress.c:243 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "ਯੂਨੈਕਸ ਡੋਮੇਨ ਸਾਕਟ à¨à¨¡à¨°à©ˆà©±à¨¸ ਇਹ ਸਿਸਟਮ ਵਲੋਂ ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + +#: gio/gvolume.c:438 +#| msgid "volume doesn't implement eject" +msgid "volume doesn’t implement eject" +msgstr "ਵਾਲੀਅਮ ਹਾਲੇ ਬਣਾਇਆ ਨਹੀਂ ਹੈ" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +#| msgid "volume doesn't implement eject or eject_with_operation" +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "ਵਾਲੀਅਮ ਲਈ eject ਜਾਂ eject_with_operation ਸਥਾਪਿਤ ਨਹੀਂ ਹੈ" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "ਹੈਂਡਲ ਤੋਂ ਪੜà©à¨¹à¨¨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "ਹੈਂਡਲ ਬੰਦ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "ਹੈਂਡਲ ਲਿਖਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "ਲੋੜੀਦੀ ਮੈਮੋਰੀ ਨਹੀਂ" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "ਅੰਦਰੂਨੀ ਗਲਤੀ: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "ਹੋਰ ਇੰਪà©à©±à¨Ÿ ਦੀ ਲੋੜ" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "ਗਲਤ ਕੰਪਰੈੱਸ ਕੀਤਾ ਡਾਟਾ" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ਸà©à¨£à¨¨ ਲਈ à¨à¨¡à¨°à©ˆà¨¸" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "ਅਣਡਿੱਠਾ, GTestDbus ਨਾਲ ਕੰਪੈਕਟ" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "à¨à¨¡à¨°à©ˆà©±à¨¸ ਪਰਿੰਟ ਕਰੋ" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "ਸ਼ੈੱਲ ਮੋਡ ਵਿੱਚ à¨à¨¡à¨°à©ˆà¨¸ ਪਰਿੰਟ ਕਰੋ" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "ਡੀਬਸ ਸਰਵਿਸ ਚਲਾਓ" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "ਗਲਤ ਆਰਗੂਮੈਂਟ\n" + +#: glib/gbookmarkfile.c:756 +#, c-format +#| msgid "Unexpected attribute '%s' for element '%s'" +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "à¨à¨²à©€à¨®à©ˆà¨‚ਟ “%2$s“ ਲਈ ਗਲਤ ਗà©à¨£ “%1$s“" + +#: glib/gbookmarkfile.c:767 glib/gbookmarkfile.c:838 glib/gbookmarkfile.c:848 +#: glib/gbookmarkfile.c:960 +#, c-format +#| msgid "Attribute '%s' of element '%s' not found" +msgid "Attribute “%s†of element “%s†not found" +msgstr "à¨à¨²à©€à¨®à©ˆà¨‚ਟ “%2$s“ ਲਈ “%1$s“ ਗà©à¨£ ਨਹੀਂ ਲੱਭਿਆ" + +#: glib/gbookmarkfile.c:1169 glib/gbookmarkfile.c:1234 +#: glib/gbookmarkfile.c:1298 glib/gbookmarkfile.c:1308 +#, c-format +#| msgid "Unexpected tag '%s', tag '%s' expected" +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "ਗਲਤ ਟੈਗ “%sâ€, ਟੈਗ “%s†ਲੋੜੀਦਾ ਸੀ" + +#: glib/gbookmarkfile.c:1194 glib/gbookmarkfile.c:1208 +#: glib/gbookmarkfile.c:1276 glib/gbookmarkfile.c:1322 +#, c-format +#| msgid "Unexpected tag '%s' inside '%s'" +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "“%2$s†ਵਿੱਚ “%1$s“ ਟੈਗ" + +#: glib/gbookmarkfile.c:1616 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "" + +#: glib/gbookmarkfile.c:1822 +msgid "No valid bookmark file found in data dirs" +msgstr "ਡਾਟਾ ਡਾਇਰੈਕਟਰੀਆਂ ਵਿੱਚ ਕੋਈ ਢà©à©±à¨•ਵੀਂ ਬà©à©±à¨•ਮਾਰਕ ਫਾਇਲ ਨਹੀਂ ਲੱਭੀ" + +#: glib/gbookmarkfile.c:2023 +#, c-format +#| msgid "A bookmark for URI '%s' already exists" +msgid "A bookmark for URI “%s†already exists" +msgstr "URI “%s†ਲਈ ਬà©à©±à¨•ਮਾਰਕ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ" + +#: glib/gbookmarkfile.c:2069 glib/gbookmarkfile.c:2227 +#: glib/gbookmarkfile.c:2312 glib/gbookmarkfile.c:2392 +#: glib/gbookmarkfile.c:2477 glib/gbookmarkfile.c:2560 +#: glib/gbookmarkfile.c:2638 glib/gbookmarkfile.c:2717 +#: glib/gbookmarkfile.c:2759 glib/gbookmarkfile.c:2856 +#: glib/gbookmarkfile.c:2977 glib/gbookmarkfile.c:3167 +#: glib/gbookmarkfile.c:3243 glib/gbookmarkfile.c:3411 +#: glib/gbookmarkfile.c:3500 glib/gbookmarkfile.c:3589 +#: glib/gbookmarkfile.c:3708 +#, fuzzy, c-format +#| msgid "No bookmark found for URI '%s'" +msgid "No bookmark found for URI “%sâ€" +msgstr "URI '%s' ਲਈ ਕੋਈ ਬà©à©±à¨•ਮਾਰਕ ਨਹੀਂ ਲੱਭਾ" + +#: glib/gbookmarkfile.c:2401 +#, fuzzy, c-format +#| msgid "No MIME type defined in the bookmark for URI '%s'" +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "URI '%s' ਲਈ ਬà©à©±à¨•ਮਾਰਕ ਵਿੱਚ ਕੋਈ MIME ਕਿਸਮ ਪਰਿਭਾਸ਼ਿਤ ਨਹੀਂ ਹੈ" + +#: glib/gbookmarkfile.c:2486 +#, fuzzy, c-format +#| msgid "No private flag has been defined in bookmark for URI '%s'" +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "URI '%s' ਲਈ ਬà©à©±à¨•ਮਾਰਕ ਕੋਈ ਪà©à¨°à¨¾à¨ˆà¨µà©‡à¨Ÿ ਫਲੈਗ ਨਹੀਂ ਦੱਸਿਆ ਗਿਆ" + +#: glib/gbookmarkfile.c:2865 +#, fuzzy, c-format +#| msgid "No groups set in bookmark for URI '%s'" +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI '%s' ਲਈ ਬà©à©±à¨•ਮਾਰਕ ਵਿੱਚ ਕੋਈ ਗਰà©à©±à¨ª ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ" + +#: glib/gbookmarkfile.c:3264 glib/gbookmarkfile.c:3421 +#, fuzzy, c-format +#| msgid "No application with name '%s' registered a bookmark for '%s'" +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "ਕਿਸੇ ਕਾਰਜ ਨੇ '%2$s' ਲਈ '%1$s' ਨਾਂ ਨਾਲ ਕੋਈ ਬà©à©±à¨•ਮਾਰਕ ਰਜਿਸਟਰ ਨਹੀਂ ਕੀਤਾ" + +#: glib/gbookmarkfile.c:3444 +#, fuzzy, c-format +#| msgid "Failed to expand exec line '%s' with URI '%s'" +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "exec ਲਾਈਨ '%s' ਨੂੰ URI '%s' ਨਾਲ ਫੈਲਾਉਣ ਲਈ ਫੇਲà©à¨¹ ਹੋਇਆ" + +#: glib/gconvert.c:466 +#, fuzzy +#| msgid "Invalid sequence in conversion input" +msgid "Unrepresentable character in conversion input" +msgstr "ਬਦਲਾਉ ਇੰਪà©à©±à¨Ÿ ਵਿੱਚ ਤਰਤੀਬ ਜਾਇਜ਼ ਨਹੀਂ ਹੈ" + +#: glib/gconvert.c:493 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 +#: glib/gutf8.c:1318 +msgid "Partial character sequence at end of input" +msgstr "ਸਤਰ ਦੇ ਅਖੀਰ ਤੇ ਅੱਖਰਾਂ ਦਾ ਸਰੂਪ ਅਧੂਰਾ ਹੈ" + +#: glib/gconvert.c:762 +#, fuzzy, c-format +#| msgid "Cannot convert fallback '%s' to codeset '%s'" +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "ਕੋਡ ਸਮੂਹ %s ਤੋਂ %s ਵਿੱਚ ਤਬਦੀਲੀ ਸੰਭਵ ਨਹੀਂ" + +#: glib/gconvert.c:934 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "ਬਦਲਣ ਲਈ ਦਿੱਤੀ ਸਤਰ ਵਿੱਚ ਬਾਇਟ ਦਾ ਸਰੂਪ ਠੀਕ ਨਹੀਂ ਹੈ" + +#: glib/gconvert.c:955 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "ਬਦਲਣ ਲਈ ਦਿੱਤੀ ਸਤਰ ਵਿੱਚ ਬਾਇਟ ਦਾ ਸਰੂਪ ਠੀਕ ਨਹੀਂ ਹੈ" + +#: glib/gconvert.c:1640 +#, fuzzy, c-format +#| msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI '%s' \"file\" ਸਕੀਮ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਅਸਲ URI ਨਹੀਂ ਹੈ" + +#: glib/gconvert.c:1650 +#, fuzzy, c-format +#| msgid "The local file URI '%s' may not include a '#'" +msgid "The local file URI “%s†may not include a “#â€" +msgstr "ਲੋਕਲ ਫਾਇਲ URI %s ਵਿੱਚ ਇਹ ਨਿਸ਼ਾਨ # ਨਹੀਂ ਹੈ" + +#: glib/gconvert.c:1667 +#, fuzzy, c-format +#| msgid "The URI '%s' is invalid" +msgid "The URI “%s†is invalid" +msgstr "URI '%s' ਜਾਇਜ਼ ਨਹੀਂ ਹੈ" + +#: glib/gconvert.c:1679 +#, fuzzy, c-format +#| msgid "The hostname of the URI '%s' is invalid" +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI '%s' ਦੇ ਹੋਸਟ ਦਾ ਨਾਂ ਜਾਇਜ਼ ਨਹੀਂ ਹੈ" + +#: glib/gconvert.c:1695 +#, fuzzy, c-format +#| msgid "The URI '%s' contains invalidly escaped characters" +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI '%s' ਕੋਲ ਗਲਤ ਅੱਖਰ ਹਨ" + +#: glib/gconvert.c:1767 +#, fuzzy, c-format +#| msgid "The pathname '%s' is not an absolute path" +msgid "The pathname “%s†is not an absolute path" +msgstr "ਮਾਰਗ-ਨਾਂ %s ਇਕ ਅਸਲੀ (absolute) ਮਾਰਗ ਨਹੀਂ ਹੈ" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:220 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %b %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:223 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:268 +msgctxt "full month name" +msgid "January" +msgstr "ਜਨਵਰੀ" + +#: glib/gdatetime.c:270 +msgctxt "full month name" +msgid "February" +msgstr "ਫਰਵਰੀ" + +#: glib/gdatetime.c:272 +msgctxt "full month name" +msgid "March" +msgstr "ਮਾਰਚ" + +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "April" +msgstr "ਅਪਰੈਲ" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "May" +msgstr "ਮਈ" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "June" +msgstr "ਜੂਨ" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "July" +msgstr "ਜà©à¨²à¨¾à¨ˆ" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "August" +msgstr "ਅਗਸਤ" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "September" +msgstr "ਸਤੰਬਰ" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "October" +msgstr "ਅਕਤੂਬਰ" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "November" +msgstr "ਨਵੰਬਰ" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "December" +msgstr "ਦਸੰਬਰ" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:322 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ਜਨ" + +#: glib/gdatetime.c:324 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ਫਰ" + +#: glib/gdatetime.c:326 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "ਮਾਰ" + +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "ਅਪ" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "May" +msgstr "ਮਈ" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ਜੂਨ" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ਜà©à¨²" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ਅਗ" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "ਸਤੰ" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "ਅਕ" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ਨਵੰ" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ਦਸੰ" + +#: glib/gdatetime.c:359 +msgctxt "full weekday name" +msgid "Monday" +msgstr "ਸੋਮਵਾਰ" + +#: glib/gdatetime.c:361 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "ਮੰਗਲਵਾਰ" + +#: glib/gdatetime.c:363 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "ਬà©à©±à¨§à¨µà¨¾à¨°" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ਵੀਰਵਾਰ" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Friday" +msgstr "ਸ਼à©à©±à¨•ਰਵਾਰ" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "ਸ਼ਨਿੱਚਰਵਾਰ" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "à¨à¨¤à¨µà¨¾à¨°" + +#: glib/gdatetime.c:386 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "ਸੋਮ" + +#: glib/gdatetime.c:388 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ਮੰਗ" + +#: glib/gdatetime.c:390 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ਬà©à©±à¨§" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ਵੀਰ" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ਸ਼à©à©±à¨•" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ਸ਼ਨਿੱ" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "à¨à¨¤" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:462 +msgctxt "full month name with day" +msgid "January" +msgstr "ਜਨਵਰੀ" + +#: glib/gdatetime.c:464 +msgctxt "full month name with day" +msgid "February" +msgstr "ਫਰਵਰੀ" + +#: glib/gdatetime.c:466 +msgctxt "full month name with day" +msgid "March" +msgstr "ਮਾਰਚ" + +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "April" +msgstr "ਅਪਰੈਲ" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "May" +msgstr "ਮਈ" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "June" +msgstr "ਜੂਨ" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "July" +msgstr "ਜà©à¨²à¨¾à¨ˆ" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "August" +msgstr "ਅਗਸਤ" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "September" +msgstr "ਸਤੰਬਰ" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "October" +msgstr "ਅਕਤੂਬਰ" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "November" +msgstr "ਨਵੰਬਰ" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "December" +msgstr "ਦਸੰਬਰ" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:549 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ਜਨ" + +#: glib/gdatetime.c:551 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ਫਰ" + +#: glib/gdatetime.c:553 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "ਮਾਰ" + +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "ਅਪ" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "ਮਈ" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "ਜੂਨ" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "ਜà©à¨²" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ਅਗ" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "ਸਤੰ" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "ਅਕ" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ਨਵੰ" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ਦਸੰ" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:588 +msgctxt "GDateTime" +msgid "AM" +msgstr "ਸਵੇਰ" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:591 +msgctxt "GDateTime" +msgid "PM" +msgstr "ਸ਼ਾਮ" + +#: glib/gdir.c:154 +#, fuzzy, c-format +#| msgid "Error opening directory '%s': %s" +msgid "Error opening directory “%sâ€: %s" +msgstr "ਡਾਇਰੈਕਟਰੀ '%s' ਖੋਲà©à¨¹à¨£ ਲਈ ਗਲਤੀ: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, fuzzy, c-format +#| msgid "Could not allocate %lu byte to read file \"%s\"" +#| msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "ਫਾਇਲ \"%2$s\" ਖੋਲà©à¨¹à¨£ ਲਈ %1$lu ਬਾਈਟ ਨਹੀਂ ਦਿੱਤਾ ਜਾ ਸਕਿਆ" +msgstr[1] "ਫਾਇਲ \"%2$s\" ਖੋਲà©à¨¹à¨£ ਲਈ %1$lu ਬਾਈਟ ਨਹੀਂ ਦਿੱਤੇ ਜਾ ਸਕੇ" + +#: glib/gfileutils.c:750 +#, fuzzy, c-format +#| msgid "Error reading file %s: %s" +msgid "Error reading file “%sâ€: %s" +msgstr "%s ਫਾਇਲ ਪੜà©à¨¹à¨¨ 'ਚ ਗਲਤੀ: %s" + +#: glib/gfileutils.c:786 +#, fuzzy, c-format +#| msgid "File \"%s\" is too large" +msgid "File “%s†is too large" +msgstr "ਫਾਇਲ \"%s\" ਬਹà©à¨¤ ਵੱਡੀ ਹੈ" + +#: glib/gfileutils.c:850 +#, fuzzy, c-format +#| msgid "Failed to read from file '%s': %s" +msgid "Failed to read from file “%sâ€: %s" +msgstr "ਫਾਇਲ '%s' ਤੋਂ ਪੜà©à¨¹à¨¨ 'ਚ ਅਸਫ਼ਲ: %s" + +#: glib/gfileutils.c:898 glib/gfileutils.c:970 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': %s" +msgid "Failed to open file “%sâ€: %s" +msgstr "'%s' ਫਾਇਲ ਖੋਲà©à¨¹ 'ਚ ਗਲਤੀ %s" + +#: glib/gfileutils.c:910 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "ਫਾਇਲ '%s' ਦੀਆਂ ਵਿਸ਼ੇਸਤਾ ਖੋਲà©à¨¹à¨£ 'ਚ ਫੇਲà©à¨¹: fstat() ਫੇਲà©à¨¹: %s" + +#: glib/gfileutils.c:940 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': fdopen() failed: %s" +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "ਫਾਇਲ '%s' ਖੋਲà©à¨¹à¨£ ਵਿੱਚ ਫੇਲà©à¨¹: fdopen() ਫੇਲà©à¨¹: %s" + +#: glib/gfileutils.c:1039 +#, fuzzy, c-format +#| msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "ਫਾਇਲ '%s' ਦਾ ਨਾਂ '%s' ਬਦਲਣ 'ਚ ਅਸਫ਼ਲ: g_rename() ਫੇਲà©à¨¹: %s" + +#: glib/gfileutils.c:1074 glib/gfileutils.c:1592 +#, fuzzy, c-format +#| msgid "Failed to create file '%s': %s" +msgid "Failed to create file “%sâ€: %s" +msgstr "ਫਾਇਲ %s' ਬਣਾਉਣ ਵਿੱਚ ਫੇਲà©à¨¹: %s" + +#: glib/gfileutils.c:1101 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': write() failed: %s" +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "ਫਾਇਲ '%s' ਨੂੰ ਲਿਖਣ ਲਈ ਫੇਲà©à¨¹: write() ਫੇਲà©à¨¹: %s" + +#: glib/gfileutils.c:1144 +#, fuzzy, c-format +#| msgid "Failed to write file '%s': fsync() failed: %s" +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "ਫਾਇਲ '%s' ਨੂੰ ਲਿਖਣ ਲਈ ਫੇਲà©à¨¹: fsync() ਫੇਲà©à¨¹: %s" + +#: glib/gfileutils.c:1279 +#, fuzzy, c-format +#| msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "ਮੌਜੂਦਾ ਫਾਇਲ '%s' ਨੂੰ ਹਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ: g_unlink() ਫੇਲà©à¨¹: %s" + +#: glib/gfileutils.c:1558 +#, fuzzy, c-format +#| msgid "Template '%s' invalid, should not contain a '%s'" +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "ਟੈਪਲੇਟ '%s' ਸਹੀਂ ਨਹੀਂ ਹੈ, ਇਸ ਕੋਲ '%s' ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: glib/gfileutils.c:1571 +#, fuzzy, c-format +#| msgid "Template '%s' doesn't contain XXXXXX" +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "ਟੈਂਪਲੇਟ '%s' XXXXXX ਨਹੀਂ ਰੱਖਦਾ ਹੈ" + +#: glib/gfileutils.c:2129 glib/gfileutils.c:2157 +#, fuzzy, c-format +#| msgid "Failed to read the symbolic link '%s': %s" +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "ਸਿੰਬੋਲਿਕ ਲਿੰਕ '%s' ਪੜà©à¨¹à¨¨ ਲਈ ਫੇਲà©à¨¹: %s" + +#: glib/giochannel.c:1393 +#, fuzzy, c-format +#| msgid "Could not open converter from '%s' to '%s': %s" +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "'%s' ਤੋਂ '%s' ਬਦਲਣ ਵਾਲਾ ਖੋਲà©à¨¹à¨¿à¨† ਨਹੀਂ ਜਾ ਸਕਿਆ: %s" + +#: glib/giochannel.c:1738 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_line_string" +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string ਵਿੱਚ ਰਾਅ ਪੜà©à¨¹à¨¿à¨† ਨਹੀਂ ਜਾ ਸਕਦਾ" + +#: glib/giochannel.c:1785 glib/giochannel.c:2043 glib/giochannel.c:2130 +msgid "Leftover unconverted data in read buffer" +msgstr "ਕà©à¨ ਅਣ-ਬਦਲਿਆ ਡਾਟਾ ਬਫਰ ਵਿੱਚ ਪਿਆ ਹੈ" + +#: glib/giochannel.c:1866 glib/giochannel.c:1943 +msgid "Channel terminates in a partial character" +msgstr "ਇਕ ਅੱਧ ਪਚਦੇ ਅੱਖਰ ਉੱਤੇ ਚੈਨਲ ਬੰਦ ਹੋ ਗਿਆ" + +#: glib/giochannel.c:1929 +#, fuzzy +#| msgid "Can't do a raw read in g_io_channel_read_to_end" +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end ਵਿੱਚ ਰਾਅ ਪੜà©à¨¹à¨¿à¨† ਨਹੀਂ ਜਾ ਸਕਦਾ" + +#: glib/gkeyfile.c:789 +msgid "Valid key file could not be found in search dirs" +msgstr "ਖੋਜ ਡਾਇਰੈਕਟਰੀਆਂ ਵਿੱਚ ਠੀਕ ਕà©à©°à¨œà©€ ਫਾਇਲ ਨਹੀਂ ਖੋਜੀ ਜਾ ਸਕੀ" + +#: glib/gkeyfile.c:826 +msgid "Not a regular file" +msgstr "ਇੱਕ ਰੈਗੂਲਰ ਫਾਇਲ ਨਹੀਂ" + +#: glib/gkeyfile.c:1275 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains line '%s' which is not a key-value pair, group, or " +#| "comment" +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"ਕà©à©°à¨œà©€ ਫਾਇਲ ਲਾਈਨ '%s' ਰੱਖਦੀ ਹੈ, ਜੋ ਕਿ ਕà©à©°à¨œà©€-ਮà©à©±à¨² ਜੋੜਾ, ਗਰà©à©±à¨ª ਜਾਂ ਟਿੱਪਣੀ ਨਹੀਂ ਹੈ" + +#: glib/gkeyfile.c:1332 +#, c-format +msgid "Invalid group name: %s" +msgstr "ਗਲਤ ਗਰà©à©±à¨ª ਨਾਂ: %s" + +#: glib/gkeyfile.c:1354 +msgid "Key file does not start with a group" +msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਗਰà©à©±à¨ª ਨਾਲ ਸ਼à©à¨°à©‚ ਨਹੀਂ ਹੋ ਸਕਦੀ ਹੈ" + +#: glib/gkeyfile.c:1380 +#, c-format +msgid "Invalid key name: %s" +msgstr "ਗਲਤ ਕà©à©°à¨œà©€ ਨਾਂ: %s" + +#: glib/gkeyfile.c:1407 +#, fuzzy, c-format +#| msgid "Key file contains unsupported encoding '%s'" +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਨਾ-ਸਹਾਇਕ ਇੰਕੋਡਿੰਗ '%s' ਰੱਖਦੀ ਹੈ" + +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3339 glib/gkeyfile.c:3469 glib/gkeyfile.c:3601 +#: glib/gkeyfile.c:3747 glib/gkeyfile.c:3976 glib/gkeyfile.c:4043 +#, fuzzy, c-format +#| msgid "Key file does not have group '%s'" +msgid "Key file does not have group “%sâ€" +msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਦਾ ਗਰà©à©±à¨ª '%s' ਨਹੀਂ ਹੈ" + +#: glib/gkeyfile.c:1778 +#, fuzzy, c-format +#| msgid "Key file does not have key '%s' in group '%s'" +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਕà©à©°à¨œà©€ '%s' ਗਰà©à©±à¨ª '%s' ਵਿੱਚ ਨਹੀਂ ਹੈ" + +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 +#, fuzzy, c-format +#| msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਵਿੱਚ ਕà©à©°à¨œà©€ '%s' ਦਾ ਮà©à©±à¨² '%s' ਹੈ, ਜੋ ਕਿ UTF-8 ਨਹੀਂ ਹੈ" + +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' which has a value that cannot be interpreted." +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"ਕà©à©°à¨œà©€ ਫਾਇਲ ਵਿੱਚ '%s' ਕà©à©°à¨œà©€ ਹੈ, ਜਿਸ ਵਿੱਚ ਮà©à©±à¨² ਹੈ, ਜਿਸ ਉੱਤੇ ਕਾਰਵਾਈ ਨਹੀਂ ਹੋ ਸਕਦੀ" +" ਹੈ" + +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 +#, fuzzy, c-format +#| msgid "" +#| "Key file contains key '%s' in group '%s' which has a value that cannot be " +#| "interpreted." +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"ਕà©à©°à¨œà©€ ਫਾਇਲ ਵਿੱਚ ਗਰà©à©±à¨ª '%2$s' ਵਿੱਚ ਕà©à©°à¨œà©€ '%1$s' ਹੈ, ਜਿਸ ਲਈ ਅਜਿਹਾ ਮà©à©±à¨² ਹੈ, ਜਿਸ" +" ਨੂੰ ਵਰਤਿਆ ਨਹੀਂ " +"ਜਾ ਸਕਦਾ।" + +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 +#, fuzzy, c-format +#| msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"ਗਰà©à©±à¨ª '%2$s' ਵਿੱਚ ਕà©à©°à¨œà©€ '%1$s' ਦਾ ਮà©à©±à¨² '%3$s' ਹੈ, ਜਦੋਂ ਕਿ ਲੋੜ %4$s ਦੀ ਸੀ" + +#: glib/gkeyfile.c:4283 +msgid "Key file contains escape character at end of line" +msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਵਿੱਚ ਲਾਈਨ ਦੇ ਅੰਤ ਵਿੱਚ ਇਸਕੇਪ ਅੱਖਰ ਹੈ" + +#: glib/gkeyfile.c:4305 +#, fuzzy, c-format +#| msgid "Key file contains invalid escape sequence '%s'" +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਵਿੱਚ ਗਲਤ ਇਸਕੇਪ ਕà©à¨°à¨® '%s' ਹੈ" + +#: glib/gkeyfile.c:4449 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a number." +msgid "Value “%s†cannot be interpreted as a number." +msgstr "ਮà©à©±à¨² '%s' ਨੂੰ ਇੱਕ ਅੰਕ ਦੇ ਤੌਰ 'ਤੇ ਪਾਰਸ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ ਹੈ।" + +#: glib/gkeyfile.c:4463 +#, fuzzy, c-format +#| msgid "Integer value '%s' out of range" +msgid "Integer value “%s†out of range" +msgstr "ਪੂਰਨ ਅੰਕ '%s' ਰੇਜ਼ ਤੋਂ ਬਾਹਰ ਹੈ" + +#: glib/gkeyfile.c:4496 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a float number." +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "ਮà©à©±à¨² '%s' ਨੂੰ ਇੱਕ ਦਸ਼ਮਲਵ ਅੰਕ ਦੇ ਤੌਰ 'ਤੇ ਪਾਰਸ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ ਹੈ।" + +#: glib/gkeyfile.c:4535 +#, fuzzy, c-format +#| msgid "Value '%s' cannot be interpreted as a boolean." +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "ਮà©à©±à¨² '%s' ਨੂੰ ਬੂਲੀਅਨ ਵਾਂਗ ਇੰਟਰਪਰੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।" + +#: glib/gmappedfile.c:129 +#, fuzzy, c-format +#| msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "ਫਾਇਲ '%s%s%s%s': fstat() ਦੇ ਗà©à¨£ ਲੈਣ ਲਈ ਫੇਲà©à¨¹: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "ਮੈਪ %s%s%s%s: mmap() ਲਈ ਫੇਲà©à¨¹ ਹੈ: %s" + +#: glib/gmappedfile.c:262 +#, fuzzy, c-format +#| msgid "Failed to open file '%s': open() failed: %s" +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "ਫਾਇਲ '%s': ਖੋਲà©à¨¹à¨£ ਵਿੱਚ ਫੇਲà©à¨¹: fdopen() ਫੇਲà©à¨¹: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "ਲਾਈਨ %d ਅੱਖਰ %d ਉੱਤੇ ਗਲਤੀ:" + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, fuzzy, c-format +#| msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "ਨਾਂ ਵਿੱਚ ਗਲਤ UTF-8 ਇੰਕੋਡ ਟੈਕਸਟ - ਵੈਧ '%s' ਨਹੀਂ" + +#: glib/gmarkup.c:473 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name" +msgid "“%s†is not a valid name" +msgstr "'%s' ਢà©à©±à¨•ਵਾਂ ਨਾਂ ਨਹੀਂ" + +#: glib/gmarkup.c:489 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name: '%c'" +msgid "“%s†is not a valid name: “%câ€" +msgstr "'%s' ਢà©à©±à¨•ਵਾਂ ਨਾਂ ਨਹੀਂ ਹੈ: '%c'" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "ਲਾਈਨ %d ਉੱਤੇ ਗਲਤੀ: %s" + +#: glib/gmarkup.c:690 +#, fuzzy, c-format +#| msgid "" +#| "Failed to parse '%-.*s', which should have been a digit inside a " +#| "character reference (ê for example) - perhaps the digit is too large" +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +" '%-.*s' ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਫੇਲà©à¨¹, ਜੋ ਕਿ ਅੱਖਰ ਵਿੱਚ ਨੰਬਰ ਹੋਣ ਚਾਹੀਦਾ ਹੈ ਵੇਖੋ (ê" +" ਉਦਾਹਰਨ " +"ਲਈ) - ਅੱਖਰ ਬਹà©à¨¤ ਲੰਮਾ ਹੋ ਗਿਆ ਹੈ" + +#: glib/gmarkup.c:702 +#, fuzzy +#| msgid "" +#| "Character reference did not end with a semicolon; most likely you used an " +#| "ampersand character without intending to start an entity - escape " +#| "ampersand as &" +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"ਅੱਖਰੀ ਰੈਫਰੈਂਸ ਸੈਮੀਕਾਲਨ ਨਾਲ ਖਤਮ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੋ ਕਿ ਤà©à¨¸à©€ ਇੱਕ à¨à¨ªà¨°à¨¸à©ˆà¨¨à¨¡ ਅੱਖਰ ਬਿਨਾਂ" +" à¨à¨‚ਟਟੀ ਸ਼à©à¨°à©‚ ਕੀਤੇ " +"ਹੀ ਵਰਤ ਰਹੇ ਹੋ, à¨à¨ªà¨°à¨¸à©ˆà¨¨à¨¡ ਇੰਠ& ਛੱਡੋ" + +#: glib/gmarkup.c:728 +#, fuzzy, c-format +#| msgid "Character reference '%-.*s' does not encode a permitted character" +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "ਅੱਖਰ ਰੈਫਰੈਂਸ '%-.*s' ਇਕ ਚà©à¨£à©‡ ਅੱਖਰ ਨੂੰ ਇਨਕੋਡ ਨਹੀਂ ਕਰ ਸਕਦਾ" + +#: glib/gmarkup.c:766 +#, fuzzy +#| msgid "" +#| "Empty entity '&;' seen; valid entities are: & " < > '" +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "ਖਾਲੀ à¨à¨‚ਟਟੀ '&;' ਵੇਖੋ; ਵੈਧ à¨à¨‚ਟਟੀਆਂ ਹਨ : & " < > '" + +#: glib/gmarkup.c:774 +#, fuzzy, c-format +#| msgid "Entity name '%-.*s' is not known" +msgid "Entity name “%-.*s†is not known" +msgstr "à¨à¨‚ਟਟੀ ਨਾਂ '%-.*s' ਪਤਾ ਨਹੀਂ ਹੈ" + +#: glib/gmarkup.c:779 +#, fuzzy +#| msgid "" +#| "Entity did not end with a semicolon; most likely you used an ampersand " +#| "character without intending to start an entity - escape ampersand as &" +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"à¨à¨‚ਟਟੀ ਸੈਮੀਕਾਲਨ ਨਾਲ ਖਤਮ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੋ ਸਕਦਾ ਕਿ ਤà©à¨¸à©€à¨‚ ਇੱਕ à¨à¨ªà¨°à¨¸à©ˆà¨¨à¨¡ ਅੱਖਰ ਬਿਨਾਂ" +" à¨à¨‚ਟਟੀ ਸ਼à©à¨°à©‚ ਕੀਤੇ " +"ਹੀ ਵਰਤ ਰਹੇ ਹੋ, à¨à¨ªà¨°à¨¸à©ˆà¨¨à¨¡ ਇਸਤਰਾਂ & ਛੱਡੋ" + +#: glib/gmarkup.c:1187 +msgid "Document must begin with an element (e.g. )" +msgstr "ਦਸਤਾਵੇਜ਼ ਇਕ à¨à¨²à©€à¨®à©ˆà¨‚ਟ (ਜਿਵੇਂ ਕਿ ) ਨਾਲ ਸ਼à©à¨°à©‚ ਹੋਣਾ ਜਰੂਰੀ ਹੈ" + +#: glib/gmarkup.c:1227 +#, fuzzy, c-format +#| msgid "" +#| "'%s' is not a valid character following a '<' character; it may not begin " +#| "an element name" +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"ਇਹ '%s' ਜਾਇਜ ਅੱਖਰ ਨਹੀਂ ਹੈ ਜੋ ਕਿ '<' ਅੱਖਰ ਤੋਂ ਮਗਰ ਹੈ, ਇਹ ਕਿਸੇ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ ਦੇ ਨਾਂ" +" ਨਾਲ ਆਰੰਭ ਨਹੀਂ " +"ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: glib/gmarkup.c:1270 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' character to end the empty-element tag " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"ਅਨਿਸ਼ਚਿਤ ਅੱਖਰ '%s', ਇਹ '>' ਅੱਖਰ ਦੀ ਉਮੀਦ ਖਾਲੀ-à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ ਟੈਗ '%s' ਬੰਦ ਕਰਨ ਲਈ ਸੀ" + +#: glib/gmarkup.c:1352 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '=' after attribute name '%s' of element " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"ਅਨਿਸ਼ਚਿਤ ਅੱਖਰ %1$s ਹੈ, à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ %3$s ਦੇ ਇਸ ਵਿਸ਼ੇਸਤਾ ਨਾਂ %2$s ਮਗਰੋਂ = ਲੋੜੀਦਾ ਸੀ" + +#: glib/gmarkup.c:1394 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' or '/' character to end the start tag " +#| "of element '%s', or optionally an attribute; perhaps you used an invalid " +#| "character in an attribute name" +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ਅਨਿਸ਼ਚਿਤ ਅੱਖਰ '%s' ਹੈ, ਇਕ ਅੱਖਰ '>'ਜਾਂ '/' ਨਿਸ਼ਚਿਤ ਅੱਖਰ ਹੈ ਤਾਂ ਕਿ ਹਿੱਸੇ ਦੇ ਸ਼à©à¨°à©‚" +" ਕੀਤੇ ਟੈਗ ਨੂੰ " +"ਖਤਮ ਕੀਤੀ ਜਾ ਸਕੇ '%s', ਜਾਂ ਚà©à¨£à¨¿à¨† ਪà©à¨°à¨¤à©€à¨•, ਜਿਸ ਲ਼ਈ ਤà©à¨¸à©€ ਗਲਤ ਨਾਂ ਭਰਿਆ ਹੈ।" + +#: glib/gmarkup.c:1439 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected an open quote mark after the equals sign " +#| "when giving value for attribute '%s' of element '%s'" +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"ਅਨਿਸ਼ਚਿਤ ਅੱਖਰ '%1$s', ਬਰਾਬਰ ਦੇ ਨਿਸ਼ਾਨ ਮਗਰੋਂ ਇਕ ਖà©à©±à¨²à¨¾ ਹਵਾਲਾ ਨਿਸ਼ਾਨ ਜ਼ਰੂਰੀ ਹੈ," +" ਜਦੋਂ ਕਿ ਤà©à¨¸à©€à¨‚ " +"ਇੱਕ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ '%3$s' ਦੀ ਵਿਸ਼ੇਸ਼ਤਾ '%2$s' ਲਈ ਮà©à©±à¨² ਦੇ ਰਹੇ ਹੋ।" + +#: glib/gmarkup.c:1573 +#, fuzzy, c-format +#| msgid "" +#| "'%s' is not a valid character following the characters ''" +msgid "" +"“%s†is not a valid character following the close element name “%sâ€; the " +"allowed character is “>â€" +msgstr "" +"ਇਹ '%s' ਅੱਖਰ '%s' à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ ਨਾਂ ਮਗਰੋਂ ਜਾਇਜ ਨਹੀਂ ਹੈ ; ਸਿਰਫ '>' ਅੱਖਰ ਹੀ ਮਨਜ਼ੂਰ ਹੈ" + +#: glib/gmarkup.c:1623 +#, fuzzy, c-format +#| msgid "Element '%s' was closed, no element is currently open" +msgid "Element “%s†was closed, no element is currently open" +msgstr "ਇਹ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ '%s' ਬੰਦ ਸੀ, ਕੋਈ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ ਖà©à©±à¨²à©à¨¹à¨¾ ਨਹੀਂ ਹੈ" + +#: glib/gmarkup.c:1632 +#, fuzzy, c-format +#| msgid "Element '%s' was closed, but the currently open element is '%s'" +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "ਇਹ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ '%s' ਬੰਦ ਸੀ, ਪਰ ਅਜੇ '%s' à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ ਖà©à©±à¨²à¨¾ ਹੈ" + +#: glib/gmarkup.c:1785 +msgid "Document was empty or contained only whitespace" +msgstr "ਦਸਤਾਵੇਜ਼ ਖਾਲੀ ਹੈ ਜਾਂ ਕੇਵਲ ਖਾਲੀ ਥਾਂ ਹੀ ਰੱਖਦਾ ਹੈ" + +#: glib/gmarkup.c:1799 +#, fuzzy +#| msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ, ਇਕ ਖà©à©±à¨²à©€ ਬਰੈਕਟ '<' ਪਾਉਣ ਮਗਰੋਂ" + +#: glib/gmarkup.c:1807 glib/gmarkup.c:1852 +#, fuzzy, c-format +#| msgid "" +#| "Document ended unexpectedly with elements still open - '%s' was the last " +#| "element opened" +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ, ਜਦੋਂ ਕਿ-ਇਹ '%s' ਆਖਰੀ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ ਖà©à©±à¨²à¨¾ ਹੈ" + +#: glib/gmarkup.c:1815 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ, ਇਕ ਬੰਦ ਬਰੈਕਟ <%s/> ਜੋ ਕਿ ਪੱਟੀ ਨੂੰ ਬੰਦ ਕਰਦੀ ਹੈ," +" ਦੀ ਉਮੀਦ ਸੀ" + +#: glib/gmarkup.c:1821 +msgid "Document ended unexpectedly inside an element name" +msgstr "ਇਕ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ ਦੇ ਨਾਂ ਕਰਕੇ ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ" + +#: glib/gmarkup.c:1827 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "ਇਕ ਗà©à¨£ ਦੇ ਨਾਂ ਕਰਕੇ ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ" + +#: glib/gmarkup.c:1832 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ਇਕ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ-ਖੋਲà©à¨¹à¨£ ਟੈਗ ਕਰਕੇ ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ" + +#: glib/gmarkup.c:1838 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"ਇਕ ਗà©à¨£ ਦੇ ਨਾਂ ਤੋਂ ਪਹਿਲਾਂ ਬਰਾਬਰ ਦੇ ਨਿਸ਼ਾਨ ਕਰਕੇ ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ, ਗà©à¨£" +" ਦਾ ਕੋਈ ਮà©à©±à¨² " +"ਨਹੀਂ ਹੈ" + +#: glib/gmarkup.c:1845 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ਇਕ ਗà©à¨£ ਦੇ ਮà©à©±à¨² ਕਰਕੇ ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ" + +#: glib/gmarkup.c:1862 +#, fuzzy, c-format +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "ਇਕ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ '%s' ਦੇ ਟੈਗ ਕਰਕੇ ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ" + +#: glib/gmarkup.c:1866 +#, fuzzy +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "ਇਕ à¨à¨²à©€à¨®à¨¿à©°à¨Ÿ '%s' ਦੇ ਟੈਗ ਕਰਕੇ ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ" + +#: glib/gmarkup.c:1872 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "ਇਕ ਟਿੱਪਣੀ ਜਾਂ ਹਦਾਇਤ ਚਲਾਉਣ ਦੌਰਾਨ ਦਸਤਾਵੇਜ਼ ਅਚਾਨਕ ਬੰਦ ਹੋ ਗਿਆ ਹੈ" + +#: glib/goption.c:868 +#, fuzzy +#| msgid "[OPTION...]" +msgid "[OPTION…]" +msgstr "[ਚੋਣ...]" + +#: glib/goption.c:984 +msgid "Help Options:" +msgstr "ਮੱਦਦ ਚੋਣ:" + +#: glib/goption.c:985 +msgid "Show help options" +msgstr "ਮੱਦਦ ਚੋਣ ਵੇਖੋ" + +#: glib/goption.c:991 +msgid "Show all help options" +msgstr "ਸਭ ਮੱਦਦ ਚੋਣਾਂ ਵੇਖੋ" + +#: glib/goption.c:1054 +msgid "Application Options:" +msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਚੋਣ:" + +#: glib/goption.c:1056 +#, fuzzy +#| msgid "Help Options:" +msgid "Options:" +msgstr "ਮੱਦਦ ਚੋਣ:" + +#: glib/goption.c:1120 glib/goption.c:1190 +#, fuzzy, c-format +#| msgid "Cannot parse integer value '%s' for %s" +msgid "Cannot parse integer value “%s†for %s" +msgstr "ਪੂਰਨ ਅੰਕ ਮà©à©±à¨² %s' ਨੂੰ %s ਲਈ ਪਾਰਸ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: glib/goption.c:1130 glib/goption.c:1198 +#, fuzzy, c-format +#| msgid "Integer value '%s' for %s out of range" +msgid "Integer value “%s†for %s out of range" +msgstr "ਪੂਰਨ ਅੰਕ '%s' %s ਲਈ ਰੇਜ਼ ਤੋਂ ਬਾਹਰ ਜਾ ਰਿਹਾ ਹੈ" + +#: glib/goption.c:1155 +#, fuzzy, c-format +#| msgid "Cannot parse double value '%s' for %s" +msgid "Cannot parse double value “%s†for %s" +msgstr "%2$s ਲਈ ਡਬਲ ਮà©à©±à¨² '%1$s' ਪਾਰਸ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" + +#: glib/goption.c:1163 +#, fuzzy, c-format +#| msgid "Double value '%s' for %s out of range" +msgid "Double value “%s†for %s out of range" +msgstr "%2$s ਲਈ '%1$s' ਡਬਲ ਮà©à©±à¨² ਰੇਜ਼ ਤੋਂ ਬਾਹਰ ਹੈ" + +#: glib/goption.c:1455 glib/goption.c:1534 +#, c-format +msgid "Error parsing option %s" +msgstr "ਚੋਣ %s ਪਾਰਸ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ" + +#: glib/goption.c:1565 glib/goption.c:1678 +#, c-format +msgid "Missing argument for %s" +msgstr "%s ਲਈ ਆਰਗੂਮੈਂਟ ਗà©à©°à¨® ਹੈ" + +#: glib/goption.c:2187 +#, c-format +msgid "Unknown option %s" +msgstr "ਅਣਜਾਣ ਚੋਣ %s" + +#: glib/gregex.c:257 +msgid "corrupted object" +msgstr "ਨਿਕਾਰਾ ਆਬਜੈਕਟ" + +#: glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "ਅੰਦਰੂਨੀ ਗਲਤੀ ਜਾਂ ਨਿਕਾਰਾ ਆਬਜੈਕਟ" + +#: glib/gregex.c:261 +msgid "out of memory" +msgstr "ਮੈਮੋਰੀ ਖਤਮ ਹੋਈ" + +#: glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "ਬੈਕ-ਟਰੈਕਿੰਗ ਲਿਸਟ ਆ ਗਈ" + +#: glib/gregex.c:278 glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "ਪੈਟਰਨ ਵਿੱਚ ਆਈਟਮਾਂ ਹਨ, ਜੋ ਕਿ ਅਧੂਰੀ ਮੈਂਚਿੰਗ ਲਈ ਸਹਾਇਕ ਨਹੀਂ।" + +#: glib/gregex.c:280 +msgid "internal error" +msgstr "ਅੰਦਰੂਨੀ ਗਲਤੀ" + +#: glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "ਬੈਕ ਰੈਡਰੈਂਸ ਕੰਡੀਸ਼ਨ ਵਾਂਗ ਅਧੂਰੀ ਮੈਂਚਿੰਗ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹਨ" + +#: glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "ਰੀਕਰਸਵ ਲਿਮਟ ਆਈ" + +#: glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "ਗਲਤ ਨਵੀਂ ਲਾਈਨ ਫਲੈਗ ਦਾ ਸੰਯੋਗ" + +#: glib/gregex.c:301 +msgid "bad offset" +msgstr "ਖ਼ਰਾਬ ਆਫਸੈੱਟ" + +#: glib/gregex.c:303 +msgid "short utf8" +msgstr "ਛੋਟਾ utf8" + +#: glib/gregex.c:305 +msgid "recursion loop" +msgstr "ਲਗਾਤਾਰ ਲੂਪ" + +#: glib/gregex.c:309 +msgid "unknown error" +msgstr "ਅਣਜਾਣ ਗਲਤੀ" + +#: glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ ਪੈਟਰਨ ਦੇ ਅੰਤ ਉੱਤੇ" + +#: glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\ਪੈਟਰਨ ਦੇ ਅੰਤ ਉੱਤੇ c" + +#: glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "ਬੇਪਛਾਣ ਕਰੈਕਟਰ ਅੱਗੇ \\" + +#: glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "ਨੰਬਰ {} ਗਿਣਤੀ ਤੋਂ ਬਾਹਰ ਹਨ" + +#: glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "ਨੰਬਰ {} ਵਿੱਚ ਆਉਣ ਤੋਂ ਬਹà©à¨¤ ਵੱਡਾ" + +#: glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "ਕਰੈਕਟਰ ਕਲਾਸ ਲਈ ਟਰਮੀਨੇਸ਼ਨ ] ਗà©à©°à¨® ਹੈ" + +#: glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "ਕਰੈਕਟਰ ਕਲਾਸ ਵਿੱਚ ਅਸਕੇਪ ਲੜੀ ਗਲਤ ਹੈ" + +#: glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "ਕਰੈਕਟਰ ਕਲਾਸ ਵਿੱਚ ਰੇਜ਼ ਬਿਨ-ਕà©à¨°à¨®" + +#: glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "ਰਪੀਟ ਕਰਨ ਲਈ ਕà©à¨ ਨਹੀਂ" + +#: glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "ਅਣਜਾਣ ਰਪੀਟ" + +#: glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "(? ਜਾਂ (?- ਦੇ ਬਾਅਦ ਬੇਪਛਾਣ ਕਰੈਕਟਰ" + +#: glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX ਨਾਂ ਦੀ ਕਲਾਸ ਕੇਵਲ ਇੱਕ ਹੀ ਕਲਾਸ ਸਹਿਯੋਗੀ ਹੈ" + +#: glib/gregex.c:366 +msgid "missing terminating )" +msgstr "ਟਰਮੀਨੇਸ਼ਨ ) ਗà©à©°à¨® ਹੈ" + +#: glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "ਗ਼ੈਰ ਮੌਜੂਦ ਸਬ-ਪੈਟਰਨ ਲਈ ਰੈਫਰੈਂਸ" + +#: glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "ਟਿੱਪਣੀ ਦੇ ਬਾਅਦ ) ਗà©à©°à¨® ਹੈ" + +#: glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "ਰੈਗੂਲਰ ਸਮੀਕਰਨ ਬਹà©à¨¤ ਲੰਮਾ ਹੈ " + +#: glib/gregex.c:378 +msgid "failed to get memory" +msgstr "ਮੈਮੋਰੀ ਲੈਣ ਲਈ ਫੇਲà©à¨¹" + +#: glib/gregex.c:382 +msgid ") without opening (" +msgstr ") ਬਿਨਾਂ ( ਖੋਲà©à¨¹à¨£ ਦੇ ਹੈ" + +#: glib/gregex.c:386 +msgid "code overflow" +msgstr "ਕੋਡ ਓਵਰਫਲੋ" + +#: glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "(?< ਬਾਅਦ ਬੇਪਛਾਣ ਕਰੈਕਟਰ" + +#: glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind ਸਥਿਰ ਲੰਬਾਈ ਵਿੱਚ ਨਹੀਂ" + +#: glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "(?( ਦੇ ਬਾਅਦ ਨਿਕਾਰਾ ਨੰਬਰ ਜਾਂ ਨਾਂ" + +#: glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "ਕੰਡੀਸ਼ਨ ਗਰà©à©±à¨ª ਵਿੱਚ ਦੋ ਤੋਂ ਵੱਧ ਬਰਾਂਚਾਂ ਹਨ" + +#: glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr " (?( ਤੋਂ ਬਾਅਦ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਲੋੜ ਸੀ" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ਜਾਂ (?[+-]ਡਿਜ਼ਟ ਦੇ ਬਾਅਦ ) ਹੋਣਾ ਚਾਹੀਦੀ ਹੈ" + +#: glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "ਅਣਜਾਣ POSIX ਕਲਾਸ ਨਾਂ" + +#: glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "POSIX ਲੋਕੇਲ à¨à¨²à©€à¨®à©ˆà¨‚ਟ ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + +#: glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} ਵਿੱਚ ਅੱਖਰ ਮà©à©±à¨–, ਲੜੀ ਬਹà©à¨¤ ਲੰਮੀ ਹੈ" + +#: glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "ਗਲਤ ਕੰਡੀਸ਼ਨ (?(0)" + +#: glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C lookbehind assertion ਲਈ ਸਹਾਇਕ ਨਹੀਂ" + +#: glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "ਇਸਕੇਪ \\L, \\l, \\N{name}, \\U, ਅਤੇ \\u ਸਹਾਇਕ ਨਹੀਂ" + +#: glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "ਲਗਾਤਾਰ ਕਾਲ ਨਾਲ ਬੇਅੰਤ ਲੂਪ ਚਾਲੂ ਹੋ ਸਕਦਾ ਸੀ" + +#: glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "(?P ਬਾਅਦ ਬੇਪਛਾਣ ਕਰੈਕਟਰ" + +#: glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "ਸਬ-ਪੈਟਰਨ ਨਾਂ ਵਿੱਚ ਟਰਮੀਨੇਟਰ ਗà©à©°à¨® ਹੈ" + +#: glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "ਦੋ ਨਾਮੀ ਸਬ-ਪੈਟਰਨ ਲਈ ਇੱਕੋ ਨਾਂ ਹੈ" + +#: glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "ਨਿਕਾਰਾ \\P ਜਾਂ \\p ਕà©à¨°à¨®" + +#: glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "\\P ਜਾਂ \\p ਦੇ ਬਾਅਦ ਅਣਜਾਣ ਵਿਸ਼ੇਸ਼ਤਾ ਨਾਂ" + +#: glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ਸਬ-ਪੈਟਰਨ ਬਹà©à¨¤ ਲੰਮਾ ਹੈ (ਵੱਧੋ-ਵੱਧ ੩੨ ਅੱਖਰ)" + +#: glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ਬਹà©à¨¤ ਵੱਧ ਸਬ-ਪੈਟਰਨ (ਵੱਧੋ-ਵੱਧ ੧੦,੦੦੦)" + +#: glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "ਓਕਟਲ ਮà©à©±à¨² \\à©©à©­à©­ ਤੋਂ ਵੱਧ" + +#: glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "ਓਵਰ-ਰਨ ਕੰਪਾਇਲਿੰਗ ਵਰਕਸਪੇਸ" + +#: glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "ਪਹਿਲਾਂ-ਚੈੱਕ ਕੀਤਾ ਰੈਂਫਰਡ ਸਬ-ਪੈਟਰਨ ਨਹੀਂ ਲੱਭਿਆ" + +#: glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE ਗਰà©à©±à¨ª ਵਿੱਚ ਇੱਕ ਤੋਂ ਵੱਧ ਬਰਾਂਚਾਂ ਹਨ" + +#: glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "ਗਲਤ NEWLINE ਚੋਣਾਂ" + +#: glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ਨੂੰ ਕਿਸੇ ਵੀ ਬਰੈਕਟ ਨਾਂ ਜਾਂ ਚੋਣਵੀਂ ਬਰੈਕਟ, ਕੋਟ ਕੀਤੇ ਨਾਂ ਜਾਂ ਨੰਬਰ, ਜਾਂ ਪਲੇਨ" +" ਨੰਬਰ ਬਾਅਦ ਮਨਜ਼ੂਰ ਨਹੀਂ" + +#: glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "ਅੰਕ ਰੈਫ਼ਰੈਂਸ ਜ਼ੀਰੋ ਹੋਣਾ ਨਹੀਂ ਚਾਹੀਦਾ ਹੈ" + +#: glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "(*ACCEPT), (*FAIL), ਜਾਂ (*COMMIT) ਦੇ ਬਾਅਦ ਆਰਗੂਮੈਂਟ ਮਨਜ਼ੂਰ ਨਹੀਂ" + +#: glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ਦੀ ਪਛਾਣ ਨਹੀਂ" + +#: glib/gregex.c:489 +msgid "number is too big" +msgstr "ਨੰਬਰ ਬਹà©à¨¤ ਵੱਡਾ ਹੈ" + +#: glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "(?& ਦੇ ਬਾਅਦ ਸਬ-ਪੈਟਰਨ ਨਾਂ ਵਿੱਚ ਟਰਮੀਨੇਟਰ ਗà©à©°à¨® ਹੈ" + +#: glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "(?+ ਦੇ ਬਾਅਦ ਅੰਕ ਲੋੜੀਦਾ ਸੀ" + +#: glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "ਜਾਵਾਸਕà©à¨°à¨¿à¨ªà¨Ÿ ਮੋਡ ਵਿੱਚ ] ਗਲਤ ਡਾਟਾ ਅੱਖਰ ਹੈ" + +#: glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ਇਕੋ ਅੰਕ ਦੇ ਦੋ ਨਾਮੀ ਸਬ-ਪੈਟਰਨ ਮਨਜ਼ੂਰ ਨਹੀਂ ਹਨ" + +#: glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) ਲਈ ਇੱਕ ਆਰਗੂਮੈਂਟ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c ਨੂੰ ਇੱਕ ASCII ਅੱਖਰ ਦੇ ਬਾਅਦ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ" + +#: glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k ਨੂੰ ਕਿਸੇ ਵੀ ਬਰੈਕਟ ਨਾਂ ਜਾਂ ਕੋਣੀ ਬਰੈਕਟ ਜਾਂ ਕੋਟ ਕੀਤੇ ਨਾਂ ਦੇ ਬਾਅਦ ਮਨਜ਼ੂਰ ਨਹੀਂ" + +#: glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "\\N ਕਲਾਸ ਵਿੱਚ ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#: glib/gregex.c:516 +msgid "too many forward references" +msgstr "ਬਹà©à¨¤ ਸਾਰੇ ਅੱਗੇ ਰੈਫਰੈਂਸ" + +#: glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), ਜਾਂ (*THEN) ਵਿੱਚ ਨਾਂ ਬਹà©à¨¤ ਵੱਡਾ ਹੈ" + +#: glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u... ਵਿੱਚ ਅੱਖਰ ਮà©à©±à¨–, ਲੜੀ ਬਹà©à¨¤ ਲੰਮੀ ਹੈ" + +#: glib/gregex.c:745 glib/gregex.c:1983 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "ਰੈਗੂਲਰ à¨à¨•ਸਪਰੈਸ਼ਨ %s ਮਿਲਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE ਲਾਇਬਰੇਰੀ ਨੂੰ UTF8 ਮੱਦਦ ਬਗੈਰ ਕੰਪਾਇਲ ਕੀਤਾ ਗਿਆ ਹੈ।" + +#: glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE ਲਾਇਬਰੇਰੀ ਨੂੰ UTF8 ਵਿਸ਼ੇਸ਼ਤਾ ਮੱਦਦ ਬਗੈਰ ਕੰਪਾਇਲ ਕੀਤਾ ਗਿਆ ਹੈ।" + +#: glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE ਲਾਇਬਰੇਰੀ ਨੂੰ ਗੈਰ-ਅਨà©à¨•ੂਲ ਚੋਣਾਂ ਨਾਲ ਕੰਪਾਇਲ ਕੀਤਾ ਗਿਆ ਹੈ।" + +#: glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "%s ਰੈਗੂਲਰ à¨à¨•ਸਪਰੈਸ਼ਨ ਅਨà©à¨•ੂਲ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#: glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "ਅੱਖਰ %2$d ਉੱਤੇ ਰੈਗੂਲਰ ਸਮੀਕਰਨ %1$s ਨਾਲ ਕੰਪਾਇਲ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %3$s" + +#: glib/gregex.c:2419 +#, fuzzy +#| msgid "hexadecimal digit or '}' expected" +msgid "hexadecimal digit or “}†expected" +msgstr "ਹੈਕਸਾਡੈਸੀਮਕ ਅੰਕ ਜਾਂ '}' ਦੀ ਮੰਗ ਸੀ" + +#: glib/gregex.c:2435 +msgid "hexadecimal digit expected" +msgstr "ਹੈਕਾਡੈਸੀਮਲ ਅੰਕ ਲੋੜੀਦਾ ਸੀ" + +#: glib/gregex.c:2475 +#, fuzzy +#| msgid "missing '<' in symbolic reference" +msgid "missing “<†in symbolic reference" +msgstr "ਸਿੰਬੋਲਿਕ ਰੈਡਰੈਂਸ ਵਿੱਚ '<' ਨਹੀਂ ਹੈ" + +#: glib/gregex.c:2484 +msgid "unfinished symbolic reference" +msgstr "ਅਧੂਰਾ ਸਿੰਬੋਲਿਕ ਰੈਡਰੈਂਸ" + +#: glib/gregex.c:2491 +msgid "zero-length symbolic reference" +msgstr "ਜ਼ੀਰੋ-ਲੰਬਾਈ ਸਿੰਬੋਲਿਕ ਰੈਡਰੈਂਸ" + +#: glib/gregex.c:2502 +msgid "digit expected" +msgstr "ਅੰਕ ਲੋੜੀਦਾ ਸੀ" + +#: glib/gregex.c:2520 +msgid "illegal symbolic reference" +msgstr "ਗਲਤ ਸਿੰਬੋਲਿਕ ਰੈਡਰੈਂਸ" + +#: glib/gregex.c:2583 +#, fuzzy +#| msgid "stray final '\\'" +msgid "stray final “\\â€" +msgstr "ਸਟਰੇ ਫਾਈਨਲ '\\'" + +#: glib/gregex.c:2587 +msgid "unknown escape sequence" +msgstr "ਅਣਜਾਣ ਇਸਕੇਪ ਕਰਮ" + +#: glib/gregex.c:2597 +#, fuzzy, c-format +#| msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "ਬਦਲਣ ਟੈਕਸਟ \"%s\" ਨੂੰ ਪਾਰਸ ਕਰਨ ਦੌਰਾਨ ਅੱਖਰ %lu ਉੱਤੇ ਗਲਤੀ: %s" + +#: glib/gshell.c:94 +#, fuzzy +#| msgid "Quoted text doesn't begin with a quotation mark" +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "ਹਵਾਲਾ ਟੈਕਸਟ ਇਕ ਹਵਾਲਾ ਮਾਰਕ ਨਾਲ ਸ਼à©à¨°à©‚ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ" + +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "ਕਮਾਂਡ ਲਾਈਨ ਜਾਂ ਸੈੱਲ ਟੈਕਸਟ ਵਿੱਚ ਬੇਮੇਲ ਹਵਾਲਾ ਮਾਰਕ ਹੈ" + +#: glib/gshell.c:580 +#, c-format +#| msgid "Text ended just after a '\\' character. (The text was '%s')" +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "ਇੱਕ “\\†ਅੱਖਰ ਮਗਰੋਂ ਟੈਕਸਟ ਖਤਮ ਹੋਣੇ ਹਨ (ਟੈਕਸਟ ਸੀ “%sâ€)" + +#: glib/gshell.c:587 +#, c-format +#| msgid "" +#| "Text ended before matching quote was found for %c. (The text was '%s')" +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "%c ਲਈ ਹਵਾਲਾ ਲੱਭਣ ਤੋਂ ਪਹਿਲਾਂ ਟੈਕਸਟ ਖਤਮ ਹੈ। (ਟੈਕਸਟ ਸੀ “%sâ€)" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "ਟੈਕਸਟ ਖਾਲੀ ਸੀ (ਜਾਂ ਸਾਫ ਥਾਂ ਹੀ ਹੈ)" + +#: glib/gspawn.c:315 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ਚਾਈਲਡ ਪਰੋਸੈਸ (%s) ਤੋਂ ਡਾਟਾ ਪੜà©à¨¹à¨¨ ਲਈ ਫੇਲà©à¨¹" + +#: glib/gspawn.c:463 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "ਚਾਈਲਡ ਪਰੋਸੈਸ (%s) ਤੋਂ ਡਾਟਾ ਖੋਲà©à¨¹à¨£ ਲਈ select() ਵਿੱਚ ਅਚਾਨਕ ਗਲਤੀ" + +#: glib/gspawn.c:548 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() (%s) ਵਿੱਚ ਅਚਾਨਕ ਗਲਤੀ" + +#: glib/gspawn.c:1056 glib/gspawn-win32.c:1329 +#, c-format +msgid "Child process exited with code %ld" +msgstr "ਚਲਾਈਡ ਪਰੋਸੈਸ %ld ਕੋਡ ਨਾਲ ਬੰਦ ਹੋਇਆ" + +#: glib/gspawn.c:1064 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "ਚਲਾਈਡ ਪਰੋਸੈਸ %ld ਸਿਗਨਲ ਰਾਹੀਂ ਖਤਮ ਕੀਤਾ" + +#: glib/gspawn.c:1071 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "ਚਲਾਈਡ ਪਰੋਸੈਸ %ld ਸਿਗਨਲ ਰਾਹੀਂ ਰੋਕਿਆ ਗਿਆ" + +#: glib/gspawn.c:1078 +#, c-format +msgid "Child process exited abnormally" +msgstr "ਚਲਾਈਡ ਪਰੋਸੈਸ ਅਸਧਾਰਨ ਢੰਗ ਨਾਲ ਬੰਦ" + +#: glib/gspawn.c:1405 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ਚਾਈਲਡ ਪਾਈਪ (%s) ਤੋਂ ਡਾਟਾ ਖੋਲà©à¨¹à¨£ ਵਿੱਚ ਫੇਲà©à¨¹ ਹੈ" + +#: glib/gspawn.c:1653 +#, c-format +#| msgid "Failed to fork child process (%s)" +msgid "Failed to spawn child process “%s†(%s)" +msgstr "" + +#: glib/gspawn.c:1692 +#, c-format +msgid "Failed to fork (%s)" +msgstr "ਫੋਰਕ (%s) ਲਈ ਫੇਲà©à¨¹" + +#: glib/gspawn.c:1841 glib/gspawn-win32.c:381 +#, c-format +#| msgid "Failed to change to directory '%s' (%s)" +msgid "Failed to change to directory “%s†(%s)" +msgstr "ਡਾਇਰੈਕਟਰੀ “%s†ਬਦਲਣ ਵਿੱਚ ਫੇਲà©à¨¹ (%s)" + +#: glib/gspawn.c:1851 +#, c-format +#| msgid "Failed to execute child process \"%s\" (%s)" +msgid "Failed to execute child process “%s†(%s)" +msgstr "ਚਾਈਲਡ ਪਰੋਸੈਸ “%s†(%s) ਸ਼à©à¨°à©‚ ਕਰਨ ਲਈ ਫੇਲà©à¨¹ ਹੈ" + +#: glib/gspawn.c:1861 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "ਚਾਈਲਡ ਪਰੋਸੈਸ (%s) ਦੀ ਆਉਟਪà©à©±à¨Ÿ ਜਾਂ ਇੰਪà©à©±à¨Ÿ ਦੀ ਦਿਸ਼ਾ ਬਦਲਣ 'ਚ ਫੇਲà©à¨¹" + +#: glib/gspawn.c:1870 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ਚਾਈਲਡ ਪਰੋਸੈਸ (%s) ਫੋਰਕ ਕਰਨ ਲਈ ਫੇਲà©à¨¹" + +#: glib/gspawn.c:1878 +#, c-format +#| msgid "Unknown error executing child process \"%s\"" +msgid "Unknown error executing child process “%sâ€" +msgstr "ਚਾਈਲਡ ਪਰੋਸੈਸ “%s†ਚਾਲੂ ਕਰਨ ਵਿੱਚ ਅਣਜਾਣੀ ਗਲਤੀ" + +#: glib/gspawn.c:1902 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "ਚਾਈਲਡ pid ਪਾਇਪ (%s) ਤੋਂ ਚਾਹੀਦਾ ਡਾਟਾ ਪੜà©à¨¹à¨¨ ਲਈ ਫੇਲà©à¨¹" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "ਚਾਈਲਡ ਪਰੋਸੈੱਸ ਤੋਂ ਡਾਟਾ ਪੜà©à¨¹à¨¨ ਲਈ ਫੇਲà©à¨¹" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ਚਾਈਲਡ ਪਰੋਸੈਸ (%s) ਨਾਲ ਕਮਿਊਨੀਕੇਸ਼ਨ ਲਈ ਪਾਇਪ ਬਣਾਉਣ ਵਿੱਚ ਫੇਲà©à¨¹" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ਚਾਈਲਡ ਕਾਰਵਾਈ (%s) ਚਾਲੂ ਕਰਨ ਵਿੱਚ ਫੇਲà©à¨¹" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "ਗਲਤ ਪà©à¨°à©‹à¨—ਰਾਮ ਨਾਂ: %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d ਉੱਤੇ ਮà©à©±à¨² ਵੈਕਟਰ ਵਿੱਚ ਗਲਤ ਲਾਈਨ: %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "ਇੰਵਾਇਰਨਮਿੰਟ ਵਿੱਚ ਗਲਤ ਲਾਈਨ: %s" + +#: glib/gspawn-win32.c:721 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ਗਲਤ ਵਰਕਿੰਗ ਡਾਇਰੈਕਟਰੀ: %s" + +#: glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ਮੱਦਦ ਪਰੋਗਰਾਮ (%s) ਸ਼à©à¨°à©‚ ਕਰਨ 'ਚ ਫੇਲà©à¨¹" + +#: glib/gspawn-win32.c:1056 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"ਇੱਕ ਚਾਈਲਡ ਪਰੋਸੈਸ ਤੋਂ ਡਾਟਾ ਪੜà©à¨¹à¨¨ ਦੌਰਾਨ g_io_channel_win32_poll() ਵਿੱਚ ਅਚਾਨਕ" +" ਗਲਤੀ" + +#: glib/gstrfuncs.c:3301 glib/gstrfuncs.c:3403 +msgid "Empty string is not a number" +msgstr "" + +#: glib/gstrfuncs.c:3325 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name" +msgid "“%s†is not a signed number" +msgstr "'%s' ਢà©à©±à¨•ਵਾਂ ਨਾਂ ਨਹੀਂ" + +#: glib/gstrfuncs.c:3335 glib/gstrfuncs.c:3439 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "" + +#: glib/gstrfuncs.c:3429 +#, fuzzy, c-format +#| msgid "'%s' is not a valid name" +msgid "“%s†is not an unsigned number" +msgstr "'%s' ਢà©à©±à¨•ਵਾਂ ਨਾਂ ਨਹੀਂ" + +#: glib/gutf8.c:811 +msgid "Failed to allocate memory" +msgstr "ਮੈਮੋਰੀ ਜਾਰੀ ਕਰਨ ਲਈ ਫੇਲà©à¨¹" + +#: glib/gutf8.c:944 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 ਲਈ ਅੱਖਰ ਰੇਜ਼ ਤੋਂ ਬਾਹਰ" + +#: glib/gutf8.c:1045 glib/gutf8.c:1054 glib/gutf8.c:1184 glib/gutf8.c:1193 +#: glib/gutf8.c:1332 glib/gutf8.c:1429 +msgid "Invalid sequence in conversion input" +msgstr "ਬਦਲਾਉ ਇੰਪà©à©±à¨Ÿ ਵਿੱਚ ਤਰਤੀਬ ਜਾਇਜ਼ ਨਹੀਂ ਹੈ" + +#: glib/gutf8.c:1343 glib/gutf8.c:1440 +msgid "Character out of range for UTF-16" +msgstr "UTF-੧੬ ਲਈ ਅੱਖਰ ਰੇਜ਼ ਤੋਂ ਬਾਹਰ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2326 +#, c-format +#| msgid "%.1f kB" +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2328 +#, c-format +#| msgid "%.1f MB" +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2330 +#, c-format +#| msgid "%.1f GB" +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2332 +#, c-format +#| msgid "%.1f TB" +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2334 +#, c-format +#| msgid "%.1f PB" +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2336 +#, c-format +#| msgid "%.1f EB" +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2340 +#, c-format +#| msgid "%.1f KiB" +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2342 +#, c-format +#| msgid "%.1f MiB" +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2344 +#, c-format +#| msgid "%.1f GiB" +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2346 +#, c-format +#| msgid "%.1f TiB" +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2348 +#, c-format +#| msgid "%.1f PiB" +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2350 +#, c-format +#| msgid "%.1f EiB" +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2354 +#, c-format +#| msgid "%.1f kB" +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2356 +#, c-format +#| msgid "%.1f MB" +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2358 +#, c-format +#| msgid "%.1f GB" +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2360 +#, c-format +#| msgid "%.1f TB" +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2362 +#, c-format +#| msgid "%.1f PB" +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2364 +#, c-format +#| msgid "%.1f EB" +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2368 +#, c-format +#| msgid "%.1f KiB" +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2370 +#, c-format +#| msgid "%.1f MiB" +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2372 +#, c-format +#| msgid "%.1f GiB" +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2374 +#, c-format +#| msgid "%.1f TiB" +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2376 +#, c-format +#| msgid "%.1f PiB" +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2378 +#, c-format +#| msgid "%.1f EiB" +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2412 glib/gutils.c:2529 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ਬਾਈਟ" +msgstr[1] "%u ਬਾਈਟ" + +#: glib/gutils.c:2416 +#, c-format +#| msgid "%u byte" +#| msgid_plural "%u bytes" +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u ਬਿੱਟ" +msgstr[1] "%u ਬਿੱਟ" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2483 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ਬਾਈਟ" +msgstr[1] "%s ਬਾਈਟ" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2488 +#, c-format +#| msgid "%s byte" +#| msgid_plural "%s bytes" +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s ਬਿੱਟ" +msgstr[1] "%s ਬਿੱਟ" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2542 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:2547 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2552 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2557 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2562 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2567 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "No such interface" +#~ msgstr "ਕੋਈ ਇੰਟਰਫੇਸ ਨਹੀਂ" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "ਸà©à¨¨à©‡à¨¹à¨¾ %d ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਹੈ, ਪਰ ਹੈੱਡਰ ਖੇਤਰ ਦਰਸਾਉਂਦਾ %d ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਦਾ ਹੈ" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "ਗਲਤੀ: ਸਿਗਨਲ ਪੂਰਾ ਸਹੀਂ ਨਾਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।\n" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "ਆਰਜ਼ੀ ਫਾਇਲ ਬਣਾਉਣ ਲਈ ਫੇਲà©à¨¹: %s" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; ਇਹ ਕà©à©°à¨œà©€ ਅਣਡਿੱਠਾ ਕਰਨ ਨੂੰ ਰੱਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " ਅਤੇ --strict ਦਿੱਤਾ ਗਿਆ ਸੀ, ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "ਇਹ ਕà©à©°à¨œà©€ ਨੂੰ ਅਣਡਿੱਠਾ ਕਰਨ ਨੂੰ ਰੱਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "ਕà©à¨ ਨਾ ਕਰੋ।\n" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "ਡਿਫਾਲਟ ਲੋਕਲ ਡਾਇਰੈਕਟਰੀ ਮਾਨੀਟਰ ਟਾਈਪ ਲੱਭਣ ਲਈ ਅਸਮਰੱਥ" + +#~ msgid "Error renaming file: %s" +#~ msgstr "ਫਾਇਲ ਨਾਂ ਬਦਲਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "ਫਾਇਲ ਖੋਲà©à¨¹à¨£ ਦੌਰਾਨ ਗਲਤੀ: %s " + +#~ msgid "Error creating directory: %s" +#~ msgstr "ਡਾਇਰੈਕਟਰੀ ਬਣਾਉਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#~ msgid "Error launching application: %s" +#~ msgstr "à¨à¨ªà¨²à©€à¨•ੇਸ਼ਨ ਲਾਂਚ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "ਸਬੰਧ ਬਦਲਣਾ win32 ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "ਸਬੰਧ ਬਣਾਉਣਾ win32 ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "'%s' ਫਾਇਲ ਪੜà©à¨¹à¨¨ 'ਚ ਗਲਤੀ: %s" + +#~ msgid "URIs not supported" +#~ msgstr "URI ਸਹਿਯੋਗੀ ਨਹੀਂ" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਵਿੱਚ '%s' ਕà©à©°à¨œà©€ ਨਹੀਂ ਹੈ" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "xmllint ਨਾਲ ਇੰਪà©à©±à¨Ÿ ਫਾਇਲ ਉੱਤੇ ਕਾਰਵਾਈ ਕਰਨ ਲਈ ਗਲਤੀ:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata ਨਾਲ ਇੰਪà©à©±à¨Ÿ ਫਾਇਲ ਉੱਤੇ ਕਾਰਵਾਈ ਕਰਨ ਲਈ ਗਲਤੀ:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "ਬਾਕੀ ਗਲਤੀ ਲੈਣ ਲਈ ਅਸਮਰੱਥ: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "ਫਾਇਲ '%s' ਨੂੰ ਲਿਖਣ ਲਈ ਖੋਲà©à¨¹à¨£ ਵਾਸਤੇ ਫੇਲà©à¨¹: fdopen() ਫੇਲà©à¨¹: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "ਫਾਇਲ '%s' ਨੂੰ ਲਿਖਣ ਲਈ ਫੇਲà©à¨¹: fflush() ਫੇਲà©à¨¹: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "ਫਾਇਲ '%s' ਨੂੰ ਬੰਦ ਕਰਨ 'ਚ ਫੇਲà©à¨¹: fclose() ਫੇਲà©à¨¹: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "'%s' ਲਈ ਅਧੂਰਾ ਡਾਟਾ ਮਿਲਿਆ" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "ਸਾਕਟ ਲਈ SO_PASSCRED ਚਾਲੂ ਹੈ, ਚੈੱਕ ਕਰਨ ਦੌਰਾਨ ਗਲਤ ਚੋਣ ਲੰਬਾਈ। ਚਾਹੀਦੇ %d ਬਾਈਟ, ਮਿਲੇ %d" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "ਕਮਾਂਡ ਲਾਈਨ '%s' ਨਾਲ ਅਸਧਾਰਨ ਪਰੋਗਰਾਮ ਖਤਮ: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "ਕਮਾਂਡ ਲਾਈਨ '%s' ਗ਼ੈਰ-ਸਿਫ਼ਰ ਬੰਦ ਹਾਲਤ %d ਨਾਲ ਬੰਦ ਹੋ ਗਈ ਹੈ: %s " + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' ਲਈ ਕੋਈ ਸਰਵਿਸ ਰਿਕਾਰਡ ਨਹੀਂ" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "ਖਾਲੀ ਸਬ-ਲਾਈਨਾਂ ਲਈ ਵਰਕਸਪੇਸ ਲਿਸਮਟ ਆਈ" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "ਅੱਖਰ ਅੱਖਰ ਬਦਲਣਾ (\\l, \\L, \\u, \\U) ਇੱਥੇ ਮਨਜ਼ੂਰ ਨਹੀਂ" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE ਗਰà©à©±à¨ª ਨੂੰ ਦà©à¨¹à¨°à¨¾à¨‰à¨£à¨¾ ਮਨਜ਼ੂਰ ਨਹੀਂ" + +#~ msgid "File is empty" +#~ msgstr "ਫਾਇਲ ਖਾਲੀ ਹੈ" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "ਕà©à©°à¨œà©€ ਫਾਇਲ ਵਿੱਚ '%s' ਕà©à©°à¨œà©€ ਹੈ, ਜਿਸ ਤੇ ਕਾਰਵਾਈ ਨਹੀਂ ਹੋ ਸਕਦੀ ਹੈ" + +#~ msgid "This option will be removed soon." +#~ msgstr "ਇਹ ਚੋਣ ਛੇਤੀ ਹੀ ਹਟਾਈ ਜਾਵੇਗੀ।" + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "'%s' ਫਾਇਲ ਦੇਣ'ਚ ਗਲਤੀ: %s" + +#~ msgid "Error connecting: " +#~ msgstr "ਕà©à¨¨à©ˆà¨•ਟ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: " + +#~ msgid "Error connecting: %s" +#~ msgstr "ਕà©à¨¨à©ˆà¨•ਟ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "SOCKSv4 ਸਥਾਪਨ 'ਚ ਯੂਜ਼ਰ-ਨਾਂ ਦੀ ਸੀਮਾ %i ਅੱਖਰਾਂ ਤੱਕ ਹੈ" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKSv4 ਸਥਾਪਨ 'ਚ ਹੋਸਟ-ਨਾਂ ਦੀ ਸੀਮਾ %i ਅੱਖਰਾਂ ਤੱਕ ਹੈ" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "unix ਤੋਂ ਪੜà©à¨¹à¨¨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "unix ਬੰਦ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "unix ਉੱਤੇ ਲਿਖਣ ਦੌਰਾਨ ਗਲਤੀ: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "ਸਵੇਰ" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "ਸ਼ਾਮ" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "ਦਿੱਤਾ ਮà©à©±à¨² ਗਲਤ ਹੈ, ਮਿਲਿਆ '%s', ਚਾਹੀਦਾ ਸੀ '%s'" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "%2$s ਕਿਸਮ ਦੀ %1$s ਵਿਸ਼ੇਸ਼ਤਾ ਸੈੱਟ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ, ਪਰ ਇੰਟਰਫੇਸ ਲਈ ਚਾਹੀਦਾ ਮà©à©±à¨² %3$s " +#~ "ਹੈ।" + +#~ msgid "No such schema '%s' specified in override file '%s'" +#~ msgstr "ਅਣਡਿੱਠਾ ਫਾਇਲ '%2$s' ਵਿੱਚ '%1$s' ਵਰਗਾ ਕੋਈ ਸਕੀਮਾ ਨਹੀਂ ਦਿੱਤਾ" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "ਕਮਾਂਡ:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "ਸਕੀਮਾ ਲਈ ਪਾਥ ਦਿਓ" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "ਆਰਗੂਮੈਂਟ:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "ਬਦਾਅਲ ਲਈ KEY ਦਾ ਧਿਆਨ ਰੱਖੋ ਤੇ ਬਦਲਾਅ ਮà©à©±à¨² ਪਰਿੰਟ ਕਰੋ।\n" +#~ "ਜਦੋਂ ਤੱਕ ਪਰੋਸੈਸ ਖਤਮ ਨਹੀਂ ਹੋ ਜਾਂਦਾ ਨਿਗਰਾਨੀ ਜਾਰੀ ਰਹੇਗੀ।" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "ਡਾਇਰੈਕਟਰੀ ਨੂੰ ਡਾਇਰੈਕਟਰੀ ਉੱਤੇ ਭੇਜਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "ਬਦਲਾਉ ਇੰਪà©à©±à¨Ÿ ਵਿੱਚ ਤਰਤੀਬ ਜਾਇਜ਼ ਨਹੀਂ ਹੈ" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "ਵੱਧੋ-ਵੱਧ ਡਾਟਾ ਅਰੇ ਲਿਮਟ ਆ ਗਈ" + +#~ msgid "do not hide entries" +#~ msgstr "à¨à¨‚ਟਰੀਆਂ ਓਹਲੇ ਨਾ ਕਰੋ" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "ਇਹ %s ਅੱਖਰ ਕੋਈ à¨à¨‚ਟਟੀ ਸ਼à©à¨°à©‚ ਕਰਨ ਲਈ ਗਲਤ ਹੈ & ਅੱਖਰ ਇਕਾਈ ਆਰੰਭ ਕਰਦਾ ਹੈ; ਜੇਕਰ ਇਹ à¨à¨ªà¨°à¨¸à©ˆà¨¡ " +#~ "à¨à¨‚ਟਟੀ ਬਣਨਯੋਗ ਨਹੀਂ ਤਾਂ ਇਸ ਨੂੰ ਇੰਠ& ਛੱਡ ਦਿਓ" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "'%s' ਅੱਖਰ ਇੱਕ à¨à¨‚ਟਟੀ ਦੇ ਨਾਂ ਲਈ ਜਾਇਜ਼ ਨਹੀਂ ਹੈ" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "ਖਾਲੀ ਅੱਖਰ ਰੈਫਰੈਂਸ, ਕੋਈ ਨੰਬਰ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਜਿਵੇਂ ਕਿ dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "ਅਧੂਰਾ à¨à¨‚ਟਟੀ ਰੈਫਰੈਂਸ" + +#~ msgid "Unfinished character reference" +#~ msgstr "ਅਧੂਰਾ ਅੱਖਰੀ ਰੈਫਰੈਂਸ" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "ਗਲਤ UTF-8 ਇੰਕੋਡ ਟੈਕਸਟ - ਓਵਰਲਾਂਗ ਕà©à¨°à¨®" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "ਗਲਤ UTF-8 ਇੰਕੋਡ ਟੈਕਸਟ - ਇੱਕ ਸ਼à©à¨°à©‚ਆਤੀ ਅੱਖਰ ਨਹੀਂ" + +#~ msgid "file" +#~ msgstr "ਫਾਇਲ" + +#~ msgid "The file containing the icon" +#~ msgstr "ਫਾਇਲ ਆਈਕਾਨ ਰੱਖਦੀ ਹੈ" + +#~ msgid "An array containing the icon names" +#~ msgstr "ਅਰੇ ਵਿੱਚ ਆਈਕਾਨ ਨਾਂ ਹਨ" + +#~ msgid "use default fallbacks" +#~ msgstr "ਡਿਫਾਲਟ ਫਾਲਬੈਕ ਵਰਤੋਂ" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "ਜੀ '-' ਅੱਖਰ ਉੱਤੇ ਨਾਂ ਨੂੰ ਛੋਟਾ ਕਰਨ ਲਈ ਡਿਫਾਲਟ ਫਾਲਬੈਕ ਲੱਭਿਆ ਵਰਤਣਾ ਹੈ। ਜੇ ਕਈ ਨਾਂ ਲੱਭਣ ਤਾਂ " +#~ "ਪਹਿਲੇ ਦੇ ਬਾਅਦ ਨਾਂ ਅਣਡਿੱਠੇ ਕਰੋ।" + +#~ msgid "File descriptor" +#~ msgstr "ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨°" + +#~ msgid "The file descriptor to read from" +#~ msgstr "ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਪੜà©à¨¹à¨¨à¨¾ ਹੈ" + +#~ msgid "Close file descriptor" +#~ msgstr "ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਬੰਦ ਕਰੋ" + +#~ msgid "Whether to close the file descriptor when the stream is closed" +#~ msgstr "ਕੀ ਸਟਰੀਮ ਬੰਦ ਹੋਣ ਨਾਲ ਫਾਇਲ ਡਿਸਕà©à¨°à¨¿à¨ªà¨Ÿà¨° ਵੀ ਬੰਦ ਕਰਨਾ ਹੈ" diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 0000000..7c75eb3 --- /dev/null +++ b/po/pl.po @@ -0,0 +1,6402 @@ +# Polish translation for glib. +# Copyright © 2002-2022 the glib authors. +# This file is distributed under the same license as the glib package. +# Zbigniew Chyla , 2002-2003. +# Artur Flinta , 2003-2006. +# Tomasz KÅ‚oczko , 2005. +# Wadim Dziedzic , 2007-2009. +# Tomasz Dominikowski , 2008-2009. +# Piotr DrÄ…g , 2009-2022. +# Aviary.pl , 2007-2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 15:19+0000\n" +"PO-Revision-Date: 2022-03-22 17:25+0100\n" +"Last-Translator: Piotr DrÄ…g \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Ustawianie domyÅ›lnych programów nie jest jeszcze obsÅ‚ugiwane" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Ustawianie programu jako ostatnio używanego dla danego typu nie jest jeszcze " +"obsÅ‚ugiwane" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opcje GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "WyÅ›wietla opcje GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Przechodzi do trybu usÅ‚ugi GApplication (używane z plików usÅ‚ug D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "ZastÄ™puje identyfikator programu" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "ZastÄ™puje dziaÅ‚ajÄ…ce wystÄ…pienie" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "WyÅ›wietla pomoc" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[POLECENIE]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "WyÅ›wietla wersjÄ™" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "WyÅ›wietla informacjÄ™ o wersji i koÅ„czy dziaÅ‚anie" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "WyÅ›wietla listÄ™ programów" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"WyÅ›wietla listÄ™ zainstalowanych programów aktywowanych przez D-Bus (wedÅ‚ug " +"plików .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Uruchamia program" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Uruchamia program (opcjonalnie z plikami do otwarcia)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "IDENTYFIKATOR-PROGRAMU [PLIK…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktywuje dziaÅ‚anie" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "WywoÅ‚uje dziaÅ‚anie na programie" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "IDENTYFIKATOR-PROGRAMU DZIAÅANIE [PARAMETR]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "WyÅ›wietla listÄ™ dostÄ™pnych dziaÅ‚aÅ„" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "WyÅ›wietla listÄ™ statycznych dziaÅ‚aÅ„ dla programu (z pliku .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "IDENTYFIKATOR-PROGRAMU" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "POLECENIE" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Polecenie, dla którego wyÅ›wietlić szczegółowÄ… pomoc" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identyfikator programu w formacie usÅ‚ugi D-Bus (np. org.przykÅ‚ad." +"przeglÄ…darka)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "PLIK" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Opcjonalne wzglÄ™dne lub bezwzglÄ™dne nazwy plików albo adresy URI do otwarcia" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "DZIAÅANIE" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Nazwa dziaÅ‚ania do wywoÅ‚ania" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETR" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Opcjonalny parametr do wywoÅ‚ania dziaÅ‚ania w formacie GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Nieznane polecenie %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Użycie:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Parametry:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[PARAMETRY…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Polecenia:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Polecenie „%s help POLECENIE†wyÅ›wietla szczegółowÄ… pomoc.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"polecenie %s wymaga identyfikatora programu bezpoÅ›rednio po nim\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "nieprawidÅ‚owy identyfikator programu: „%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"polecenie „%s†nie przyjmuje żadnych parametrów\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "nie można połączyć z usÅ‚ugÄ… D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "błąd podczas wysyÅ‚ania komunikatu %s do programu: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "nazwa dziaÅ‚ania musi zostać podana po identyfikatorze programu\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nieprawidÅ‚owa nazwa dziaÅ‚ania: „%sâ€\n" +"nazwy dziaÅ‚aÅ„ mogÄ… skÅ‚adać siÄ™ tylko ze znaków alfanumerycznych, „-†i „.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "błąd podczas przetwarzania parametru dziaÅ‚ania: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "dziaÅ‚ania przyjmujÄ… maksymalnie jeden parametr\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "polecenie „list-actions†przyjmuje tylko identyfikator programu" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "nie można odnaleźć pliku .desktop dla programu %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"nierozpoznane polecenie: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Za duża wartość licznika przekazana do %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Szukanie nie jest obsÅ‚ugiwane przez podstawowy potok" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Nie można skrócić GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Potok jest już zamkniÄ™ty" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Skracanie nie jest dozwolone na podstawowym potoku" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "DziaÅ‚anie zostaÅ‚o anulowane" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "NieprawidÅ‚owy obiekt, nie zainicjowano" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "NiepeÅ‚na sekwencja wielu bajtów na wejÅ›ciu" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Brak wystarczajÄ…cej iloÅ›ci miejsca w miejscu docelowym" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "NieprawidÅ‚owa sekwencja bajtów na wejÅ›ciu konwersji" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Błąd podczas konwersji: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Zainicjowanie, które można anulować nie jest obsÅ‚ugiwane" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Konwersja z zestawu znaków „%s†na zestaw „%s†nie jest obsÅ‚ugiwana" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Nie można otworzyć konwertera z „%s†na „%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "Typ %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Nieznany typ" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "Typ pliku %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials zawiera nieprawidÅ‚owe dane" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials nie jest zaimplementowane w tym systemie operacyjnym" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Platforma nie obsÅ‚uguje GCredentials" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"GCredentials nie zawiera identyfikatora procesu w tym systemie operacyjnym" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" +"FaÅ‚szowanie danych uwierzytelniajÄ…cych nie jest możliwe w tym systemie " +"operacyjnym" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Nieoczekiwany, przedwczesny koniec potoku" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "NieobsÅ‚ugiwany klucz „%s†we wpisie adresu „%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Para klucz/wartość we wpisie adresu „%s†nie ma znaczenia" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adres „%s†jest nieprawidÅ‚owy (wymaga dokÅ‚adnie jednej Å›cieżki, katalogu, " +"katalogu tymczasowego lub kluczy abstrakcyjnych)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Błąd w adresie „%s†— atrybut „%s†jest błędnie sformatowany" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Nieznany lub nieobsÅ‚ugiwany transport „%s†dla adresu „%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Element adresu „%s†nie zawiera dwukropka (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Nazwa transportu w elemencie adresu „%s†nie może być pusta" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Para klucz/wartość %d, „%s†w elemencie adresu „%s†nie zawiera znaku " +"równoÅ›ci" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Para klucz/wartość %d, „%s†w elemencie adresu „%s†nie może mieć pustego " +"klucza" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Błąd podczas usuwania znaku sterujÄ…cego klucza lub wartoÅ›ci w parze klucz/" +"wartość %d, „%s†w elemencie adresu „%sâ€" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Błąd w adresie „%s†— transport systemu UNIX wymaga ustawienia dokÅ‚adnie " +"jednego z kluczy „path†lub „abstractâ€" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Błąd w adresie „%s†— brak atrybutu komputera lub jest błędnie sformatowany" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Błąd w adresie „%s†— brak atrybutu portu lub jest błędnie sformatowany" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Błąd w adresie „%s†— brak atrybutu pliku nonce lub jest błędnie sformatowany" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Błąd podczas automatycznego uruchamiania: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Błąd podczas otwierania pliku nonce „%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Błąd podczas odczytywania pliku nonce „%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Błąd podczas odczytywania pliku nonce „%sâ€, oczekiwano 16 bajtów, otrzymano " +"%d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Błąd podczas zapisywania zawartoÅ›ci pliku nonce „%s†do potoku:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Podany adres jest pusty" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Nie można wywoÅ‚ać magistrali komunikatów, kiedy AT_SECURE jest ustawione" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Nie można wywoÅ‚ać magistrali komunikatów bez identyfikatora komputera: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "" +"Nie można automatycznie uruchomić usÅ‚ugi D-Bus bez zmiennej $DISPLAY " +"Å›rodowiska X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Błąd podczas wywoÅ‚ywania wiersza poleceÅ„ „%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Nie można ustalić adresu magistrali sesji (nie jest zaimplementowane dla " +"tego systemu operacyjnego)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Nie można ustalić adresu magistrali ze zmiennej Å›rodowiskowej " +"DBUS_STARTER_BUS_TYPE — nieznana wartość „%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Nie można ustalić adresu magistrali, ponieważ nie ustawiono zmiennej " +"Å›rodowiskowej DBUS_STARTER_BUS_TYPE" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Nieznany typ magistrali %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Oczekiwano braku zawartoÅ›ci podczas próby odczytania wiersza" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Oczekiwano braku zawartoÅ›ci podczas próby (bezpiecznego) odczytania wiersza" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Wyczerpano wszystkie dostÄ™pne mechanizmy uwierzytelniania (próby: %s, " +"dostÄ™pne: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Identyfikatory użytkownika muszÄ… być takie same dla partnera i serwera" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Anulowano przez GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Błąd podczas pobierania informacji o katalogu „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Uprawnienia katalogu „%s†sÄ… błędnie sformatowane. Oczekiwano trybu 0700, " +"otrzymano 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Błąd podczas tworzenia katalogu „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "DziaÅ‚anie nie jest obsÅ‚ugiwane" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Błąd podczas otwierania bazy kluczy „%s†do odczytania: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"%d. wiersz bazy kluczy w „%s†z zawartoÅ›ciÄ… „%s†jest błędnie sformatowany" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Pierwszy token %d. wiersza bazy kluczy w „%s†z zawartoÅ›ciÄ… „%s†jest " +"błędnie sformatowany" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Drugi token %d. wiersza bazy kluczy w „%s†z zawartoÅ›ciÄ… „%s†jest błędnie " +"sformatowany" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Nie odnaleziono ciasteczka z identyfikatorem %d w bazie kluczy w „%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Błąd podczas tworzenia pliku blokady „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Błąd podczas usuwania starego pliku blokady „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Błąd podczas zamykania (niedowiÄ…zanego) pliku blokady „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Błąd podczas odwiÄ…zywania pliku blokady „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Błąd podczas otwierania bazy kluczy „%s†do zapisania: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Dodatkowo, uwolnienie blokady „%s†także siÄ™ nie powiodÅ‚o: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Połączenie jest zamkniÄ™te" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Przekroczono czas oczekiwania" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"WystÄ…piÅ‚y nieobsÅ‚ugiwane flagi podczas tworzenia połączenia ze strony klienta" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Brak interfejsu „org.freedesktop.DBus.Properties†w obiekcie w ścieżce %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Brak wÅ‚aÅ›ciwoÅ›ci „%sâ€" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "WÅ‚aÅ›ciwość „%s†nie jest odczytywalna" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "WÅ‚aÅ›ciwość „%s†nie jest zapisywalna" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Błąd podczas ustawiania wÅ‚aÅ›ciwoÅ›ci „%sâ€: oczekiwano typ „%sâ€, ale otrzymano " +"„%sâ€" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Brak interfejsu „%sâ€" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Brak interfejsu „%s†w obiekcie w ścieżce %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Brak metody „%sâ€" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Typ komunikatu, „%sâ€, nie pasuje do oczekiwanego typu „%sâ€" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Obiekt zostaÅ‚ już wyeksportowany dla interfejsu %s w %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Nie można pobrać wÅ‚aÅ›ciwoÅ›ci %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Nie można ustawić wÅ‚aÅ›ciwoÅ›ci %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metoda „%s†zwróciÅ‚a typ „%sâ€, ale oczekiwano „%sâ€" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metoda „%s†w interfejsie „%s†z podpisem „%s†nie istnieje" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Poddrzewo zostaÅ‚o już wyeksportowane dla %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Obiekt nie istnieje w ścieżce „%sâ€" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "typ jest NIEPRAWIDÅOWY" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Komunikat METHOD_CALL: brak pola nagłówka PATH lub MEMBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Komunikat METHOD_RETURN: brak pola nagłówka REPLY_SERIAL" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Komunikat o BÅĘDZIE: brak pola nagłówka REPLY_SERIAL lub ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Komunikat SYGNAÅU: brak pola nagłówka PATH, INTERFACE lub MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Komunikat SYGNAÅU: pole nagłówka PATH używa zastrzeżonej wartoÅ›ci /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Komunikat SYGNAÅU: pole nagłówka INTERFACE używa zastrzeżonej wartoÅ›ci org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Chciano odczytać %lu bajt, ale otrzymano tylko %lu" +msgstr[1] "Chciano odczytać %lu bajty, ale otrzymano tylko %lu" +msgstr[2] "Chciano odczytać %lu bajtów, ale otrzymano tylko %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Oczekiwano bajtu NUL po ciÄ…gu „%sâ€, ale odnaleziono bajt %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Oczekiwano prawidÅ‚owego ciÄ…gu UTF-8, ale odnaleziono nieprawidÅ‚owe bajty " +"w wyrównaniu bajtu %d (dÅ‚ugość ciÄ…gu wynosi %d). PrawidÅ‚owy ciÄ…g UTF-8 do " +"tego miejsca to „%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Wartość jest zagnieżdżona za głęboko" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "" +"Przetworzona wartość „%s†nie jest prawidÅ‚owÄ… Å›cieżkÄ… do obiektu usÅ‚ugi D-Bus" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Przetworzona wartość „%s†nie jest prawidÅ‚owym podpisem usÅ‚ugi D-Bus" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"WystÄ…piÅ‚a macierz o dÅ‚ugoÅ›ci %u bajta. Maksymalna dÅ‚ugość to 2<<26 bajtów " +"(64 MiB)." +msgstr[1] "" +"WystÄ…piÅ‚a macierz o dÅ‚ugoÅ›ci %u bajtów. Maksymalna dÅ‚ugość to 2<<26 bajtów " +"(64 MiB)." +msgstr[2] "" +"WystÄ…piÅ‚a macierz o dÅ‚ugoÅ›ci %u bajtów. Maksymalna dÅ‚ugość to 2<<26 bajtów " +"(64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"WystÄ…piÅ‚a macierz typu „a%câ€, której oczekiwana dÅ‚ugość jest wielokrotnoÅ›ciÄ… " +"%u B, ale wynosi %u B" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Puste struktury (krotki) nie sÄ… dozwolone na magistrali D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"Przetworzona wartość „%s†dla wariantu nie jest prawidÅ‚owym podpisem usÅ‚ugi " +"D-Bus" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Błąd podczas deserializowania GVariant za pomocÄ… ciÄ…gu typu „%s†z formatu " +"przewodu usÅ‚ugi D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"NieprawidÅ‚owa wartość kolejnoÅ›ci bajtów. Oczekiwano 0x6c („lâ€) lub 0x42 " +"(„Bâ€), ale odnaleziono wartość 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"NieprawidÅ‚owa główna wersja protokoÅ‚u. Oczekiwano 1, ale odnaleziono %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Odnaleziono nagłówek podpisu, ale nie jest podpisem typu" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Odnaleziono nagłówek podpisu z podpisem „%sâ€, ale treść komunikatu jest pusta" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Przetworzona wartość „%s†nie jest prawidÅ‚owym podpisem usÅ‚ugi D-Bus (dla " +"treÅ›ci)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Brak nagłówka podpisu w komunikacie, ale treść komunikatu liczy %u bajt" +msgstr[1] "" +"Brak nagłówka podpisu w komunikacie, ale treść komunikatu liczy %u bajty" +msgstr[2] "" +"Brak nagłówka podpisu w komunikacie, ale treść komunikatu liczy %u bajtów" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Nie można deserializować komunikatu: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Błąd podczas serializowania GVariant za pomocÄ… ciÄ…gu typu „%s†z formatu " +"przewodu usÅ‚ugi D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Liczba deskryptorów plików w komunikacie (%d) różni siÄ™ od pola nagłówka (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Nie można serializować komunikatu: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Treść komunikatu ma podpis „%sâ€, ale brak nagłówka podpisu" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Treść komunikatu ma podpis typu „%sâ€, ale podpis w polu nagłówka to „%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Treść komunikatu jest pusta, ale podpis w polu nagłówka to „(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Błąd zwrotu z treÅ›ciÄ… typu „%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Błąd zwrotu z pustÄ… treÅ›ciÄ…" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Wpisanie dowolnego znaku zamknie to okno)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"Magistrala D-Bus sesji nie jest uruchomiona, i automatyczne uruchomienie siÄ™ " +"nie powiodÅ‚o" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Nie można pobrać profilu sprzÄ™tu: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Nie można wczytać pliku %s ani %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Błąd podczas wywoÅ‚ywania metody StartServiceByName dla %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Nieoczekiwana odpowiedź %d od metody StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Nie można wywoÅ‚ać metody; poÅ›rednik jest dla znanej nazwy %s bez " +"wÅ‚aÅ›ciciela, a poÅ›rednik zostaÅ‚ utworzony za pomocÄ… flagi " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "PrzestrzeÅ„ nazw abstrakcyjnych jest nieobsÅ‚ugiwana" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Nie można okreÅ›lić pliku nonce podczas tworzenia serwera" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Błąd podczas zapisywania pliku nonce w „%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "CiÄ…g „%s†nie jest prawidÅ‚owym GUID usÅ‚ugi D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Nie można nasÅ‚uchiwać na nieobsÅ‚ugiwanym transporcie „%sâ€" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Polecenia:\n" +" help WyÅ›wietla tÄ™ informacjÄ™\n" +" introspect Bada zdalny obiekt\n" +" monitor Monitoruje zdalny obiekt\n" +" call WywoÅ‚uje metodÄ™ na zdalnym obiekcie\n" +" emit Emituje sygnaÅ‚\n" +" wait Oczekuje na pojawienie siÄ™ nazwy magistrali\n" +"\n" +"Polecenie „%s POLECENIE --help†wyÅ›wietla pomoc o każdym poleceniu.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Błąd: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Błąd podczas przetwarzania kodu XML introspekcji: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Błąd: %s nie jest prawidÅ‚owÄ… nazwÄ…\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Błąd: %s nie jest prawidÅ‚owÄ… Å›cieżkÄ… do obiektu\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "ÅÄ…czy z magistralÄ… systemowÄ…" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "ÅÄ…czy z magistralÄ… sesji" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "ÅÄ…czy z podanym adresem usÅ‚ugi D-Bus" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opcje punktów koÅ„cowych połączenia:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opcje okreÅ›lajÄ…ce punkt koÅ„cowy połączenia" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nie okreÅ›lono żadnych punktów koÅ„cowych połączenia" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "OkreÅ›lono wiele punktów koÅ„cowych połączenia" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Ostrzeżenie: wedÅ‚ug danych introspekcji, interfejs „%s†nie istnieje\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Ostrzeżenie: wedÅ‚ug danych introspekcji, metoda „%s†nie istnieje " +"w interfejsie „%sâ€\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Opcjonalny cel sygnaÅ‚u (unikalna nazwa)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Åšcieżka do obiektu do wyemitowania sygnaÅ‚u" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Nazwa sygnaÅ‚u i interfejsu" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emituje sygnaÅ‚." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Błąd podczas łączenia: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Błąd: %s nie jest prawidÅ‚owÄ… unikalnÄ… nazwÄ… magistrali.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Błąd: nie podano Å›cieżki do obiektu\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Błąd: nie podano nazwy sygnaÅ‚u\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Błąd: nazwa sygnaÅ‚u „%s†jest nieprawidÅ‚owa\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Błąd: %s nie jest prawidÅ‚owÄ… nazwÄ… interfejsu\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Błąd: %s nie jest prawidÅ‚owÄ… nazwÄ… elementu\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Błąd podczas przetwarzania parametru %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Błąd podczas czyszczenia połączenia: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nazwa docelowa do wywoÅ‚ania na niej metody" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Åšcieżka do obiektu do wywoÅ‚ania na niej metody" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Nazwa metody i interfejsu" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Czas oczekiwania w sekundach" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Zezwala na interaktywne upoważnienie" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "WywoÅ‚uje metodÄ™ na zdalnym obiekcie." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Błąd: nie podano celu\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Błąd: %s nie jest prawidÅ‚owÄ… nazwÄ… magistrali\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Błąd: nie podano nazwy metody\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Błąd: nazwa metody „%s†jest nieprawidÅ‚owa\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Błąd podczas przetwarzania parametru %d typu „%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Błąd podczas dodawania pliku obsÅ‚ugi %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nazwa docelowa do zbadania" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Åšcieżka do obiektu do zbadania" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "WyÅ›wietla kod XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Bada elementy potomne" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "WyÅ›wietla tylko wÅ‚aÅ›ciwoÅ›ci" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Bada zdalny obiekt." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nazwa docelowa do monitorowania" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Åšcieżka do obiektu do monitorowania" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitoruje zdalny obiekt." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"Błąd: nie można monitorować połączenia niebÄ™dÄ…cego magistralÄ… komunikatów\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "UsÅ‚uga do aktywowania przed oczekiwaniem na drugÄ… (znanÄ… nazwÄ™)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Czas oczekiwania przed zakoÅ„czeniem z błędem (w sekundach), 0 oznacza brak " +"ograniczenia (domyÅ›lne)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPCJA…] NAZWA-MAGISTRALI" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Oczekuje na pojawienie siÄ™ nazwy magistrali." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Błąd: należy podać usÅ‚ugÄ™, dla której aktywować.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Błąd: należy podać usÅ‚ugÄ™, na którÄ… oczekiwać.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Błąd: za dużo parametrów.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Błąd: %s nie jest prawidÅ‚owÄ… znanÄ… nazwÄ… magistrali.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Brak upoważnienia do zmiany ustawieÅ„ debugowania" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Bez nazwy" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Plik .desktop nie okreÅ›la pola Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Nie można odnaleźć terminala wymaganego przez program" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Nie można utworzyć katalogu użytkownika dla konfiguracji programu %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Nie można utworzyć katalogu użytkownika dla konfiguracji MIME %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Brak identyfikatora w informacjach o programie" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Nie można utworzyć pliku .desktop dla użytkownika %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Niestandardowa definicja dla %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "napÄ™d nie obsÅ‚uguje wysuniÄ™cia" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "napÄ™d nie obsÅ‚uguje wysuniÄ™cia lub „eject_with_operationâ€" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "napÄ™d nie obsÅ‚uguje wykrywania noÅ›nika" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "napÄ™d nie obsÅ‚uguje rozpoczÄ™cia" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "napÄ™d nie obsÅ‚uguje zatrzymania" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "Mechanizm TLS nie obsÅ‚uguje wiążącego pobierania TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "ObsÅ‚uga TLS jest niedostÄ™pna" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "ObsÅ‚uga DTLS jest niedostÄ™pna" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Nie można obsÅ‚użyć wersji %d kodowania GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Błędna liczba elementów (%d) w kodowaniu GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Nie można obsÅ‚użyć wersji %d kodowania GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Błędna liczba elementów (%d) w kodowaniu GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Oczekiwano obiektu GEmblem dla GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Nie istnieje zawierajÄ…cy punkt montowania" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Nie można skopiować na katalog" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Nie można skopiować katalogu na katalog" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Plik docelowy istnieje" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Nie można skopiować katalogu rekurencyjnie" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "WywoÅ‚anie „splice†nie jest obsÅ‚ugiwane" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Błąd podczas dzielenia pliku: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"Kopiowanie (reflink/clone) miÄ™dzy punktami montowania nie jest obsÅ‚ugiwane" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopiowanie (reflink/clone) nie jest obsÅ‚ugiwane lub jest nieprawidÅ‚owe" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopiowanie (reflink/clone) nie jest obsÅ‚ugiwane lub nie zadziaÅ‚aÅ‚o" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Nie można skopiować pliku specjalnego" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Wprowadzono nieprawidÅ‚owÄ… wartość dowiÄ…zania symbolicznego" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "DowiÄ…zania symboliczne nie sÄ… obsÅ‚ugiwane" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Kosz nie jest obsÅ‚ugiwany" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Nazwy plików nie mogÄ… zawierać „%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "wolumin nie obsÅ‚uguje montowania" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Å»aden program nie jest zarejestrowany do obsÅ‚ugi tego pliku" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator jest zamkniÄ™ty" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Enumerator plików ma zalegÅ‚e dziaÅ‚anie" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Enumerator plików jest już zamkniÄ™ty" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Nie można obsÅ‚użyć wersji %d kodowania GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Błędny format danych wejÅ›ciowych dla GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Potok nie obsÅ‚uguje dziaÅ‚ania query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Szukanie nie jest obsÅ‚ugiwane przez potok" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Skracanie nie jest dozwolone na potoku wejÅ›ciowym" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Skracanie nie jest dozwolone na potoku" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "NieprawidÅ‚owa nazwa komputera" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Błędna odpowiedź poÅ›rednika HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Połączenie poÅ›rednika HTTP nie jest dozwolone" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Uwierzytelnienie poÅ›rednika HTTP siÄ™ nie powiodÅ‚o" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Wymagane jest uwierzytelnienie poÅ›rednika HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Połączenie poÅ›rednika HTTP siÄ™ nie powiodÅ‚o: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Odpowiedź poÅ›rednika HTTP jest za duża" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Serwer poÅ›rednika HTTP nieoczekiwanie zamknÄ…Å‚ połączenie." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Błędna liczba elementów (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Brak typu dla nazwy klasy %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Typ %s nie obsÅ‚uguje interfejsu GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Typ %s nie jest klasowy" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Błędny format numeru wersji: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Typ %s nie obsÅ‚uguje metody from_tokens() z interfejsu GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Nie można obsÅ‚użyć podanej wersji kodowania ikony" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nie podano adresu" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "DÅ‚ugość %u jest za dÅ‚uga na adres" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adres ma bity ustawione poza dÅ‚ugoÅ›ciÄ… przedrostka" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Nie można przetworzyć „%s†jako maskÄ™ adresu IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Brak wystarczajÄ…cej iloÅ›ci miejsca dla adresu gniazda" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "NieobsÅ‚ugiwany adres gniazda" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Potok wejÅ›ciowy nie obsÅ‚uguje odczytu" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Potok ma zalegÅ‚e dziaÅ‚anie" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopiuje za pomocÄ… pliku" + +# FIXME — co to w ogóle jest? +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Podąża za plikiem podczas przenoszenia" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "„version†nie przyjmuje żadnych parametrów" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Użycie:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "WyÅ›wietla informacjÄ™ o wersji i koÅ„czy dziaÅ‚anie." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Polecenia:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Dołącza pliki na standardowym wyjÅ›ciu" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopiuje jeden lub wiÄ™cej plików" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "WyÅ›wietla informacje o poÅ‚ożeniach" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Uruchamia program z pliku .desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "WyÅ›wietla listÄ™ zawartoÅ›ci poÅ‚ożeÅ„" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Pobiera lub ustawia program obsÅ‚ugujÄ…cy dla typu MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Tworzy katalogi" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitoruje zmiany plików i katalogów" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montuje lub odmontowuje poÅ‚ożenia" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Przenosi jeden lub wiÄ™cej plików" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Otwiera pliki za pomocÄ… domyÅ›lnego programu" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Zmienia nazwÄ™ pliku" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Usuwa jeden lub wiÄ™cej plików" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Odczytuje ze standardowego wejÅ›cia i zapisuje" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Ustawia atrybut pliku" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Przenosi pliki lub katalogi do kosza" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "WyÅ›wietla listÄ™ zawartoÅ›ci poÅ‚ożeÅ„ w drzewie" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "%s wyÅ›wietla szczegółowÄ… pomoc.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Błąd podczas zapisywania do standardowego wyjÅ›cia" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "POÅOÅ»ENIE" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Dołącza pliki i wyÅ›wietla je na standardowym wyjÅ›ciu." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"Program gio cat dziaÅ‚a jak zwykÅ‚e narzÄ™dzie cat, ale za pomocÄ… poÅ‚ożeÅ„\n" +"GIO zamiast plików lokalnych: przykÅ‚adowo można użyć czegoÅ› takiego jak\n" +"smb://serwer/zasób/plik.txt jako poÅ‚ożenia." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nie podano poÅ‚ożeÅ„" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Brak katalogu docelowego" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "WyÅ›wietla postÄ™p" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Pyta przed zastÄ…pieniem" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Zachowuje wszystkie atrybuty" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Tworzy kopiÄ™ zapasowÄ… istniejÄ…cych plików docelowych" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nigdy nie podąża za dowiÄ…zaniami symbolicznymi" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Używa domyÅ›lnych uprawnieÅ„ dla elementu docelowego" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "PrzesÅ‚ano %s z %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "PLIK-ŹRÓDÅOWY" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "CEL" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopiuje jeden lub wiÄ™cej PLIKÓW ŹRÓDÅOWYCH do PLIKÓW DOCELOWYCH." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"Program gio copy dziaÅ‚a jak zwykÅ‚e narzÄ™dzie cp, ale za pomocÄ… poÅ‚ożeÅ„\n" +"GIO zamiast plików lokalnych: przykÅ‚adowo można użyć czegoÅ› takiego jak\n" +"smb://serwer/zasób/plik.txt jako poÅ‚ożenia." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Plik docelowy %s nie jest katalogiem" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: zastÄ…pić „%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Lista zapisywalnych atrybutów" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Pobiera informacje o systemie plików" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Atrybuty do pobrania" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRYBUTY" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Bez podążania za dowiÄ…zaniami symbolicznymi" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atrybuty:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "wyÅ›wietlana nazwa: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "modyfikowana nazwa: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nazwa: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "typ: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "rozmiar: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "ukryty\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "URI: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "lokalna Å›cieżka: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "punkt montowania systemu UNIX: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atrybuty możliwe do ustawienia:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "PrzestrzeÅ„ nazw atrybutów możliwych do ustawienia:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "WyÅ›wietla informacje o poÅ‚ożeniach." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"Program gio info dziaÅ‚a jak zwykÅ‚e narzÄ™dzie ls, ale za pomocÄ… poÅ‚ożenia\n" +"GIO zamiast plików lokalnych: przykÅ‚adowo można użyć czegoÅ› takiego jak\n" +"smb://serwer/zasób/plik.txt jako poÅ‚ożenia. Atrybuty plików mogÄ… być\n" +"podawane za pomocÄ… ich nazwy GIO, np. standard::icon, przestrzeni nazw,\n" +"np. unix, albo „*â€, co oznacza wszystkie atrybuty" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "PLIK-DESKTOP [PARAMETRY-PLIKU…]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Uruchamia program z pliku .desktop, przekazujÄ…c mu opcjonalne parametry nazw " +"plików." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nie podano pliku .desktop" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Polecenie uruchamiania nie jest obecnie obsÅ‚ugiwane na tej platformie" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Nie można wczytać „%sâ€: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Nie można wczytać informacji o programie dla „%sâ€" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Nie można uruchomić programu „%sâ€: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "WyÅ›wietla ukryte pliki" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Używa dÅ‚ugiego formatu list" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "WyÅ›wietla wyÅ›wietlane nazwy" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "WyÅ›wietla peÅ‚ne adresy URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "WyÅ›wietla listÄ™ zawartoÅ›ci poÅ‚ożenia." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"Program gio list dziaÅ‚a jak zwykÅ‚e narzÄ™dzie ls, ale za pomocÄ… poÅ‚ożenia\n" +"GIO zamiast plików lokalnych: przykÅ‚adowo można użyć czegoÅ› takiego jak\n" +"smb://serwer/zasób/plik.txt jako poÅ‚ożenia. Atrybuty plików mogÄ… być\n" +"podawane za pomocÄ… ich nazwy GIO, np. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TYP-MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "PROGRAM-OBSÅUGUJÄ„CY" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Pobiera lub ustawia program obsÅ‚ugujÄ…cy dla typu MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"JeÅ›li nie podano programu obsÅ‚ugujÄ…cego, to wyÅ›wietla listÄ™\n" +"zarejestrowanych i polecanych programów dla typu MIME. JeÅ›li\n" +"podano program obsÅ‚ugujÄ…cy, to jest on ustawiany jako domyÅ›lny\n" +"program obsÅ‚ugujÄ…cy dla typu MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Należy podać jeden typ MIME i opcjonalnie program obsÅ‚ugujÄ…cy" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Brak domyÅ›lnego programu dla „%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "DomyÅ›lny program dla „%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Zarejestrowane programy:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Brak zarejestrowanych programów\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Zalecane programy:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Brak zalecanych programów\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Wczytanie informacji o programie obsÅ‚ugujÄ…cym „%s†siÄ™ nie powiodÅ‚o" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"Ustawienie „%s†jako domyÅ›lny program obsÅ‚ugujÄ…cy „%s†siÄ™ nie powiodÅ‚o: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Tworzy katalogi nadrzÄ™dne" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Tworzy katalogi." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"Program gio mkdir dziaÅ‚a jak zwykÅ‚e narzÄ™dzie mkdir, ale za pomocÄ… poÅ‚ożeÅ„\n" +"GIO zamiast plików lokalnych: przykÅ‚adowo można użyć czegoÅ› takiego jak\n" +"smb://serwer/zasób/plik.txt jako poÅ‚ożenia." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitoruje katalog (domyÅ›lnie: zależy od typu)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitoruje plik (domyÅ›lnie: zależy od typu)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Monitoruje plik bezpoÅ›rednio (uwzglÄ™dnia zmiany wprowadzone przez twarde " +"dowiÄ…zania)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitoruje plik bezpoÅ›rednio, ale nie zgÅ‚asza zmian" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"ZgÅ‚asza przeniesienia i zmiany nazw jako proste zdarzenia usuniÄ™cia/" +"utworzenia" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Obserwuje zdarzenia montowania" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitoruje zmiany plików lub katalogów." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Montuje jako montowalny" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Montuje wolumin za pomocÄ… pliku urzÄ…dzenia lub innego identyfikatora" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "Identyfikator" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Odmontowuje" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Wysuwa" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Zatrzymuje napÄ™d za pomocÄ… pliku urzÄ…dzenia" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "URZÄ„DZENIE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Odmontowuje wszystko za pomocÄ… podanego schematu" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEMAT" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Ignoruje trwajÄ…ce dziaÅ‚ania na plikach podczas odmontowywania lub wysuwania" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Używa anonimowego użytkownika podczas uwierzytelniania" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "WyÅ›wietla listÄ™" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitoruje zdarzenia" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "WyÅ›wietla dodatkowe informacje" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Numeryczny kod PIM podczas odblokowywania woluminu VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montuje ukryty wolumin TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montuje systemowy wolumin TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Odmowa dostÄ™pu anonimowego" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Brak napÄ™du dla pliku urzÄ…dzenia" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Brak woluminu dla podanego identyfikatora" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montuje lub odmontowuje poÅ‚ożenia." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Bez używania zapasowego kopiowania i usuwania" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Przenosi jeden lub wiÄ™cej PLIKÓW ŹRÓDÅOWYCH do PLIKÓW DOCELOWYCH." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"Program gio move dziaÅ‚a jak zwykÅ‚e narzÄ™dzie mv, ale za pomocÄ… poÅ‚ożeÅ„\n" +"GIO zamiast plików lokalnych: przykÅ‚adowo można użyć czegoÅ› takiego jak\n" +"smb://serwer/zasób/plik.txt jako poÅ‚ożenia" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Plik docelowy %s nie jest katalogiem" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Otwiera pliki za pomocÄ… domyÅ›lnego programu\n" +"zarejestrowanego do obsÅ‚ugi pliku tego typu." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignoruje nieistniejÄ…ce pliki, nigdy nie pyta" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Usuwa podane pliki." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAZWA" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Zmienia nazwÄ™ pliku." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Brak parametru" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Za dużo parametrów" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Zmiana nazwy zostaÅ‚a ukoÅ„czona powodzeniem. Nowy adres URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Tworzy tylko, jeÅ›li nie istnieje" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Dołącza do koÅ„ca pliku" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Podczas tworzenia ogranicza dostÄ™p do bieżącego użytkownika" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "" +"Podczas zastÄ™powania zastÄ™puje tak, jakby miejsce docelowe nie istniaÅ‚o" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "WyÅ›wietla nowÄ… etykietÄ™ etag na koÅ„cu" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Etykieta etag pliku zostanie zastÄ…piona" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Błąd podczas odczytywania ze standardowego wejÅ›cia" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etykieta etag jest niedostÄ™pna\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Odczytuje ze standardowego wejÅ›cia i zapisuje do PLIKU DOCELOWEGO." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nie podano celu" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Typ atrybutu" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYP" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRYBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "WARTOŚĆ" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Ustawia atrybut pliku POÅOÅ»ENIA." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Nie podano poÅ‚ożenia" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Nie podano atrybutu" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Nie podano wartoÅ›ci" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "NieprawidÅ‚owy typ atrybutu „%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Opróżnia kosz" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "WyÅ›wietla listÄ™ plików w koszu z ich oryginalnymi poÅ‚ożeniami" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Przywraca plik z kosza do jego oryginalnego poÅ‚ożenia (ewentualnie " +"odtwarzajÄ…c katalog)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Nie można odnaleźć oryginalnej Å›cieżki" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Nie można odtworzyć oryginalnego poÅ‚ożenia: %s" + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Nie można przenieść pliku do jego oryginalnego poÅ‚ożenia: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Przenosi/przywraca pliki lub katalogi do/z kosza." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Uwaga: w przypadku przełącznika --restore, jeÅ›li oryginalne poÅ‚ożenie\n" +"pliku w koszu już istnieje, to nie zostanie zastÄ…pione, jeÅ›li\n" +"nie zostanie ustawione --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Podane poÅ‚ożenie nie zaczyna siÄ™ od trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Podąża za dowiÄ…zaniami symbolicznymi, punktami montowania i skrótami" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "WyÅ›wietla listÄ™ zawartoÅ›ci katalogów w formacie drzewa." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> nie jest dozwolony wewnÄ…trz <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> nie jest dozwolony jako główny element" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Plik %s pojawia siÄ™ wiele razy w zasobie" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "" +"Ustalenie poÅ‚ożenia „%s†w dowolnym katalogu źródÅ‚owym siÄ™ nie powiodÅ‚o" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Ustalenie poÅ‚ożenia „%s†w bieżącym katalogu siÄ™ nie powiodÅ‚o" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Nieznana opcja przetwarzania „%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Zażądano wstÄ™pnego przetworzenia %s, ale %s nie jest ustawione, a %s nie " +"jest w PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Błąd podczas odczytywania pliku %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Błąd podczas kompresowania pliku %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "tekst nie może znajdować siÄ™ wewnÄ…trz <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "WyÅ›wietla wersjÄ™ programu i koÅ„czy dziaÅ‚anie" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nazwa pliku wyjÅ›ciowego" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "Katalog, z którego wczytywać PLIKI (domyÅ›lnie bieżący katalog)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "KATALOG" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Tworzy wyjÅ›cie w formacie wybranym przez rozszerzenie pliku docelowego" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Tworzy nagłówek źródÅ‚a" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Tworzy kod źródÅ‚owy używany do dowiÄ…zania pliku zasobu do kodu" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Tworzy listÄ™ zależnoÅ›ci" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nazwa pliku zależnoÅ›ci do utworzenia" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Dołącza faÅ‚szywe cele w utworzonym pliku zależnoÅ›ci" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Bez automatycznego tworzenia i rejestrowania zasobu" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Bez eksportowania funkcji; deklaruje je jako G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Bez osadzania danych zasobów w pliku C; przyjmuje, że jest zamiast tego " +"zewnÄ™trznie dowiÄ…zane" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Nazwa identyfikatora jÄ™zyka C używana dla utworzonego kodu źródÅ‚owego" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Docelowy kompilator jÄ™zyka C (domyÅ›lnie: zmienna Å›rodowiskowa CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompiluje okreÅ›lenie zasobu do pliku zasobu. Pliki okreÅ›leÅ„\n" +"zasobów majÄ… rozszerzenie .gresource.xml, a pliki\n" +"zasobów majÄ… rozszerzenie .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Należy podać dokÅ‚adnie jednÄ… nazwÄ™ pliku\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "pseudonim musi mieć co najmniej 2 znaki" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "NieprawidÅ‚owa wartość numeryczna" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " zostaÅ‚o już okreÅ›lone" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' zostaÅ‚o już okreÅ›lone" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "wartoÅ›ci flag mogÄ… mieć ustawiony co najwyżej 1 bit" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> musi zawierać co najmniej jeden znacznik " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> nie jest zawarte w okreÅ›lonym zakresie" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nie jest prawidÅ‚owym elementem okreÅ›lonego wyliczonego typu" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> zawiera ciÄ…g spoza okreÅ›lonego typu flag" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> zawiera ciÄ…g, którego nie ma w znaczniku " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " zostaÅ‚o już okreÅ›lone dla tego klucza" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nie jest dozwolone dla kluczy typu „%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "okreÅ›lony minimum jest wyższy niż maksimum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "nieobsÅ‚ugiwana kategoria lokalizacji: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "zażądano lokalizacji, ale nie podano domeny gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "podano kontekst tÅ‚umaczenia dla wartoÅ›ci bez włączonej lokalizacji" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Przetworzenie wartoÅ›ci typu „%s†siÄ™ nie powiodÅ‚o: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" nie może być okreÅ›lane dla kluczy oznaczonych jako majÄ…ce " +"wyliczony typ" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " zostaÅ‚o już okreÅ›lone dla tego klucza" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nie jest dozwolone dla kluczy typu „%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " zostaÅ‚o już podane" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " musi zawierać co najmniej jeden znacznik " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " zostaÅ‚o już okreÅ›lone dla tego klucza" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" może być okreÅ›lane tylko dla kluczy z wyliczonym typem lub typem " +"flag, albo po znaczniku " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +"podano , kiedy „%s†jest już elementem wyliczonego typu" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "podano , kiedy już podano " + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " zostaÅ‚o już okreÅ›lone" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "cel aliasu „%s†nie jest w wyliczonym typie" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "cel aliasu „%s†nie jest w znaczniku " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " musi zawierać co najmniej jeden znacznik " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Puste nazwy nie sÄ… dozwolone" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "NieprawidÅ‚owa nazwa „%sâ€: nazwy muszÄ… rozpoczynać siÄ™ od maÅ‚ej litery" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"NieprawidÅ‚owa nazwa „%sâ€: niedozwolony znak „%câ€. Dozwolone sÄ… tylko maÅ‚e " +"litery, liczby i myÅ›lniki („-â€)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "NieprawidÅ‚owa nazwa „%sâ€: dwa myÅ›lniki („--â€) nie sÄ… dozwolone" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "NieprawidÅ‚owa nazwa „%sâ€: ostatni znak nie może być myÅ›lnikiem („-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "NieprawidÅ‚owa nazwa „%sâ€: maksymalna dÅ‚ugość to 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " zostaÅ‚o już okreÅ›lone" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Nie można dodać kluczy do schematu „list-ofâ€" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " zostaÅ‚o już okreÅ›lone" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" pokrywa w ; należy użyć " +"znacznika , aby zmodyfikować wartość" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"DokÅ‚adnie jedna z wartoÅ›ci „typeâ€, „enum†lub „flags†musi zostać okreÅ›lona " +"jako atrybut znacznika " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> nie zostaÅ‚o (jeszcze) okreÅ›lone." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "NieprawidÅ‚owy typ GVariant ciÄ…gu „%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "Podano znacznik , ale schemat nic nie rozszerza" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Brak znacznika do zastÄ…pienia" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " zostaÅ‚o już okreÅ›lone" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " zostaÅ‚o już okreÅ›lone" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " rozszerza jeszcze nieistniejÄ…cy schemat „%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " jest listÄ… jeszcze nieistniejÄ…cego schematu „%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Nie można być listÄ… schematów ze Å›cieżkami" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Nie można rozszerzyć schematu ze Å›cieżkÄ…" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" jest listÄ… rozszerzajÄ…cÄ… znacznik , który " +"nie jest listÄ…" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" rozszerza znacznik , ale „%s†nie rozszerza „%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"Åšcieżka, jeÅ›li zostanie podana, musi rozpoczynać siÄ™ i koÅ„czyć ukoÅ›nikiem" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Åšcieżka do listy musi koÅ„czyć siÄ™ „:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Ostrzeżenie: schemat „%s†ma Å›cieżkÄ™ „%sâ€. Åšcieżki zaczynajÄ…ce siÄ™ od „/" +"apps/â€, „/desktop/†i „/system/†sÄ… przestarzaÅ‚e." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> zostaÅ‚o już okreÅ›lone" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Tylko jeden element <%s> jest dozwolony wewnÄ…trz <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> nie jest dozwolony jako główny element" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Element jest wymagany w znaczniku " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Tekst nie może znajdować siÄ™ wewnÄ…trz <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Ostrzeżenie: nieokreÅ›lone odniesienie do znacznika " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "Podano opcjÄ™ --strict; koÅ„czenie dziaÅ‚ania." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "CaÅ‚y plik zostaÅ‚ zignorowany." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignorowanie tego pliku." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Brak klucza „%s†w schemacie „%sâ€, jak okreÅ›lono w pliku zastÄ…pienia „%sâ€; " +"ignorowanie zastÄ…pienia dla tego klucza." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Brak klucza „%s†w schemacie „%sâ€, jak okreÅ›lono w pliku zastÄ…pienia „%sâ€, " +"oraz podano opcjÄ™ --strict; koÅ„czenie dziaÅ‚ania." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Nie można dostarczyć zastÄ…pieÅ„ wedÅ‚ug Å›rodowiska dla lokalizowanego klucza " +"„%s†w schemacie „%s†(plik zastÄ…pienia „%sâ€); ignorowanie zastÄ…pienia dla " +"tego klucza." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Nie można dostarczyć zastÄ…pieÅ„ wedÅ‚ug Å›rodowiska dla lokalizowanego klucza " +"„%s†w schemacie „%s†(plik zastÄ…pienia „%sâ€) oraz podano opcjÄ™ --strict; " +"koÅ„czenie dziaÅ‚ania." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Błąd podczas przetwarzania klucza „%s†w schemacie „%sâ€, jak okreÅ›lono " +"w pliku zastÄ…pienia „%sâ€: %s. Ignorowanie zastÄ…pienia dla tego klucza." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Błąd podczas przetwarzania klucza „%s†w schemacie „%sâ€, jak okreÅ›lono " +"w pliku zastÄ…pienia „%sâ€: %s. Podano opcjÄ™ --strict; koÅ„czenie dziaÅ‚ania." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"ZastÄ…pienie dla klucza „%s†w schemacie „%s†w pliku zastÄ…pienia „%s†jest " +"poza zakresem podanym w schemacie; ignorowanie zastÄ…pienia dla tego klucza." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"ZastÄ…pienie dla klucza „%s†w schemacie „%s†w pliku zastÄ…pienia „%s†jest " +"poza zakresem podanym w schemacie oraz podano opcjÄ™ --strict; koÅ„czenie " +"dziaÅ‚ania." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"ZastÄ…pienie dla klucza „%s†w schemacie „%s†w pliku zastÄ…pienia „%s†nie " +"znajduje siÄ™ na liÅ›cie prawidÅ‚owych wyborów; ignorowanie zastÄ…pienia dla " +"tego klucza." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"ZastÄ…pienie dla klucza „%s†w schemacie „%s†w pliku zastÄ…pienia „%s†nie " +"znajduje siÄ™ na liÅ›cie prawidÅ‚owych wyborów oraz podano opcjÄ™ --strict; " +"koÅ„czenie dziaÅ‚ania." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Gdzie przechowywać plik gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Przerywa po każdym błędzie w schematach" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Bez zapisywania pliku gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Bez wymuszania ograniczeÅ„ nazw kluczy" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompiluje wszystkie pliki schematów GSettings do pamiÄ™ci\n" +"podrÄ™cznej schematów. Pliki schematów muszÄ… mieć\n" +"rozszerzenie .gschema.xml, a pliki pamiÄ™ci podrÄ™cznej\n" +"nazywajÄ… siÄ™ gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Należy podać dokÅ‚adnie jednÄ… nazwÄ™ katalogu" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nie odnaleziono plików schematów: nierobienie niczego." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Nie odnaleziono plików schematów: usuniÄ™to istniejÄ…cy plik wyjÅ›ciowy." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "NieprawidÅ‚owa nazwa pliku %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Błąd podczas pobierania informacji o systemie plików dla %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Nie odnaleziono punktu montowania zawierajÄ…cego plik %s" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Nie można zmienić nazwy katalogu głównego" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Błąd podczas zmieniania nazwy pliku %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Nie można zmienić nazwy pliku, plik o takiej nazwie już istnieje" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "NieprawidÅ‚owa nazwa pliku" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Błąd podczas otwierania pliku %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Błąd podczas usuwania pliku %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Błąd podczas przenoszenia pliku %s do kosza: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Nie można utworzyć katalogu kosza %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Nie można odnaleźć głównego katalogu dla kosza %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"Przenoszenie do kosza na wewnÄ™trznych punktach montowania systemu nie jest " +"obsÅ‚ugiwane" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Nie można odnaleźć lub utworzyć katalogu kosza %s do kosza %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Nie można utworzyć pliku informacji o koszu dla %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Nie można przenieść pliku %s do kosza pomiÄ™dzy systemami plików" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Nie można przenieść pliku %s do kosza: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Nie można przenieść pliku %s do kosza" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Błąd podczas tworzenia katalogu %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "System plików nie obsÅ‚uguje dowiÄ…zaÅ„ symbolicznych" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Błąd podczas tworzenia dowiÄ…zania symbolicznego %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Błąd podczas przenoszenia pliku %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Nie można przenieść katalogu na katalog" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Utworzenie pliku kopii zapasowej siÄ™ nie powiodÅ‚o" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Błąd podczas usuwania pliku docelowego: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Przenoszenie miÄ™dzy punktami montowania nie jest obsÅ‚ugiwane" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Nie można ustalić wykorzystania dysku %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Wartość atrybutu nie może być pusta" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "NieprawidÅ‚owy typ atrybutu (oczekiwano „stringâ€)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "NieprawidÅ‚owa nazwa rozszerzonego atrybutu" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Błąd podczas ustawiania rozszerzonego atrybutu „%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (nieprawidÅ‚owe kodowanie)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Błąd podczas pobierania informacji o pliku „%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Błąd podczas pobierania informacji o deskryptorze pliku: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "NieprawidÅ‚owy typ atrybutu (oczekiwano „uint32â€)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "NieprawidÅ‚owy typ atrybutu (oczekiwano „uint64â€)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "NieprawidÅ‚owy typ atrybutu (oczekiwano „byte stringâ€)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Nie można ustawić uprawnieÅ„ na dowiÄ…zaniach symbolicznych" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Błąd podczas ustawiania uprawnieÅ„: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Błąd podczas ustawiania wÅ‚aÅ›ciciela: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "dowiÄ…zanie symboliczne nie może być puste" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Błąd podczas ustawiania dowiÄ…zania symbolicznego: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Błąd podczas ustawiania dowiÄ…zania symbolicznego: plik nie jest dowiÄ…zaniem " +"symbolicznym" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Dodatkowe nanosekundy %d dla czasu uniksowego %lld sÄ… ujemne" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Dodatkowe nanosekundy %d dla czasu uniksowego %lld osiÄ…gajÄ… 1 sekundÄ™" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "Czas uniksowy %lld nie mieÅ›ci siÄ™ w 64 bitach" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"Czas uniksowy %lld jest poza zakresem obsÅ‚ugiwanym przez system Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Nie można skonwertować nazwy pliku „%s†na kodowanie UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Nie można otworzyć pliku „%sâ€: błąd %lu systemu Windows" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Błąd podczas ustawiania czasu modyfikacji lub dostÄ™pu pliku „%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Błąd podczas ustawiania czasu modyfikacji lub dostÄ™pu: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Kontekst SELinux nie może być pusty" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nie jest włączony w tym systemie" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Błąd podczas ustawiania kontekstu SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Ustawianie atrybutu %s nie jest obsÅ‚ugiwane" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Błąd podczas odczytywania z pliku: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Błąd podczas zamykania pliku: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Błąd podczas wyszukiwania w pliku: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Nie można odnaleźć domyÅ›lnego typu monitora pliku lokalnego" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Błąd podczas zapisywania do pliku: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Błąd podczas usuwania odnoÅ›nika do starej kopii zapasowej: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Błąd podczas tworzenia kopii zapasowej: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Błąd podczas zmieniania nazwy pliku tymczasowego: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Błąd podczas skracania pliku: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Błąd podczas otwierania pliku „%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Plik docelowy jest katalogiem" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Plik docelowy nie jest zwykÅ‚ym plikiem" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Plik zostaÅ‚ zmieniony poza programem" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Błąd podczas usuwania starego pliku: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Podano nieprawidÅ‚owy obiekt GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "NieprawidÅ‚owe żądanie wyszukiwania" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Nie można skrócić GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Potok wyjÅ›ciowy pamiÄ™ci nie obsÅ‚uguje zmiany rozmiaru" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Zmiana rozmiaru potoku wyjÅ›ciowego pamiÄ™ci siÄ™ nie powiodÅ‚a" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Ilość pamiÄ™ci wymagana dla przetworzenia zapisu jest wiÄ™ksza od dostÄ™pnej " +"przestrzeni adresowej" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Zażądano przejÅ›cia przed poczÄ…tkiem potoku" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Zażądano przejÅ›cia poza koniec potoku" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "punkt montowania nie obsÅ‚uguje odmontowania" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "punkt montowania nie obsÅ‚uguje wysuniÄ™cia" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"punkt montowania nie obsÅ‚uguje odmontowania lub „unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "punkt montowania nie obsÅ‚uguje wysuniÄ™cia lub „eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "punkt montowania nie obsÅ‚uguje ponownego montowania" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "punkt montowania nie obsÅ‚uguje rozpoznania typu zawartoÅ›ci" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" +"punkt montowania nie obsÅ‚uguje synchronicznego rozpoznania typu zawartoÅ›ci" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Nazwa komputera „%s†zawiera „[â€, ale nie „]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Sieć jest niedostÄ™pna" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Komputer jest niedostÄ™pny" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Nie można utworzyć monitora sieci: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Nie można utworzyć monitora sieci: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Nie można uzyskać stanu sieci: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "UsÅ‚uga NetworkManager nie jest uruchomiona" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Wersja usÅ‚ugi NetworkManager jest za stara" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Potok wyjÅ›ciowy nie obsÅ‚uguje zapisu" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Suma wektorów przekazanych do %s jest za duża" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Potok źródÅ‚owy jest już zamkniÄ™ty" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Błąd podczas rozwiÄ…zywania „%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s nie jest zaimplementowane" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "NieprawidÅ‚owa domena" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Zasób w „%s†nie istnieje" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Dekompresowanie zasobu w „%s†siÄ™ nie powiodÅ‚o" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Zasób w „%s†nie jest katalogiem" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Potok wejÅ›ciowy nie obsÅ‚uguje szukania" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "WyÅ›wietla listÄ™ sekcji zawierajÄ…cych zasoby w PLIKU w formacie ELF" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"WyÅ›wietla listÄ™ zasobów\n" +"JeÅ›li podano SEKCJĘ, to wyÅ›wietla tylko zasoby w tej sekcji\n" +"JeÅ›li podano ÅšCIEÅ»KĘ, to wyÅ›wietla tylko pasujÄ…ce zasoby" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "PLIK [ÅšCIEÅ»KA]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEKCJA" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"WyÅ›wietla listÄ™ zasobów ze szczegółami\n" +"JeÅ›li podano SEKCJĘ, to wyÅ›wietla tylko zasoby w tej sekcji\n" +"JeÅ›li podano ÅšCIEÅ»KĘ, to wyÅ›wietla tylko pasujÄ…ce zasoby\n" +"Szczegóły zawierajÄ… sekcjÄ™, rozmiar i kompresjÄ™" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Wydobywa plik zasobu do standardowego wyjÅ›cia" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "PLIK ÅšCIEÅ»KA" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Użycie:\n" +" gresource [--section SEKCJA] POLECENIE [PARAMETRY…]\n" +"\n" +"Polecenia:\n" +" help WyÅ›wietla tÄ™ informacjÄ™\n" +" sections WyÅ›wietla listÄ™ sekcji zasobów\n" +" list WyÅ›wietla listÄ™ zasobów\n" +" details WyÅ›wietla listÄ™ zasobów ze szczegółami\n" +" extract Wydobywa zasób\n" +"\n" +"Polecenie „gresource help POLECENIE†wyÅ›wietla szczegółowÄ… pomoc.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Użycie:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEKCJA (Opcjonalna) nazwa sekcji formatu ELF\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " POLECENIE (Opcjonalne) polecenie do wyjaÅ›nienia\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" PLIK Plik w formacie ELF (plik binarny lub\n" +" biblioteka współdzielona)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" PLIK Plik w formacie ELF (plik binarny lub biblioteka\n" +" współdzielona) lub skompilowany plik zasobów\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[ÅšCIEÅ»KA]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " ÅšCIEÅ»KA (Opcjonalna) Å›cieżka do zasobu (może być częściowa)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "ÅšCIEÅ»KA" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " ÅšCIEÅ»KA Åšcieżka do zasobu\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Brak schematu „%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Nie można przenosić schematu „%s†(nie można podać Å›cieżki)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Można przenosić schemat „%s†(należy podać Å›cieżkÄ™)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Podano pustÄ… Å›cieżkÄ™.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Åšcieżka musi rozpoczynać siÄ™ od ukoÅ›nika (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Åšcieżka musi koÅ„czyć siÄ™ ukoÅ›nikiem (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Åšcieżka nie może zawierać dwóch sÄ…siadujÄ…cych ukoÅ›ników (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Podana wartość jest poza prawidÅ‚owym zakresem\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Klucz nie jest zapisywalny\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "" +"WyÅ›wietla listÄ™ zainstalowanych schematów (których nie można przenosić)" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "WyÅ›wietla listÄ™ zainstalowanych schematów (które można przenosić)" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "WyÅ›wietla listÄ™ kluczy w SCHEMACIE" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMAT[:ÅšCIEÅ»KA]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "WyÅ›wietla listÄ™ elementów potomnych SCHEMATU" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"WyÅ›wietla listÄ™ kluczy i wartoÅ›ci, rekursywnie\n" +"JeÅ›li nie podano SCHEMATU, to wyÅ›wietla listÄ™ wszystkich kluczy\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMAT[:ÅšCIEÅ»KA]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Uzyskuje wartość KLUCZA" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMAT[:ÅšCIEÅ»KA] KLUCZ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Odpytuje zakres prawidÅ‚owych wartoÅ›ci KLUCZA" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Odpytuje opis KLUCZA" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Ustawia wartość KLUCZA na WARTOŚĆ" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMAT[:ÅšCIEÅ»KA] KLUCZ WARTOŚĆ" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Przywraca KLUCZ na jego domyÅ›lnÄ… wartość" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Przywraca wszystkie klucze w SCHEMACIE do domyÅ›lnych wartoÅ›ci" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Sprawdza, czy KLUCZ jest zapisywalny" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitoruje zmiany KLUCZA.\n" +"JeÅ›li nie podano KLUCZA, to monitoruje wszystkie klucze w SCHEMACIE.\n" +"Użycie ^C zatrzymuje monitorowanie.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMAT[:ÅšCIEÅ»KA] [KLUCZ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Użycie:\n" +" gsettings --version\n" +" gsettings [--schemadir KATALOG-SCHEMATÓW] POLECENIE [PARAMETRY…]\n" +"\n" +"Polecenia:\n" +" help WyÅ›wietla te informacje\n" +" list-schemas WyÅ›wietla listÄ™ zainstalowanych schematów\n" +" list-relocatable-schemas WyÅ›wietla listÄ™ zainstalowanych schematów,\n" +" które można przenosić\n" +" list-keys WyÅ›wietla listÄ™ kluczy w schemacie\n" +" list-children WyÅ›wietla listÄ™ elementów potomnych schematu\n" +" list-recursively WyÅ›wietla listÄ™ kluczy i wartoÅ›ci, rekursywnie\n" +" range Odpytuje zakres klucza\n" +" describe Odpytuje opis klucza\n" +" get Uzyskuje wartość klucza\n" +" set Ustawia wartość klucza\n" +" reset Przywraca wartość klucza\n" +" reset-recursively Przywraca wszystkie wartoÅ›ci\n" +" w podanym schemacie\n" +" writable Sprawdza, czy klucz jest zapisywalny\n" +" monitor Obserwuje zmiany\n" +"\n" +"Polecenie „gsettings help POLECENIE†wyÅ›wietla szczegółowÄ… pomoc.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Użycie:\n" +" gsettings [--schemadir KATALOG-SCHEMATÓW] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " KATALOG-SCHEMATÓW Katalog do wyszukiwania dodatkowych schematów\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMAT Identyfikator schematu\n" +" ÅšCIEÅ»KA Åšcieżka (dla schematów, które można przenosić)\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KLUCZ (Opcjonalny) klucz w schemacie\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KLUCZ Klucz w schemacie\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " WARTOŚĆ Wartość do ustawienia\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Nie można wczytać schematów z %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nie zainstalowano schematów\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Podano pustÄ… nazwÄ™ schematu\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Brak klucza „%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "NieprawidÅ‚owe gniazdo, nie zainicjowano" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "NieprawidÅ‚owe gniazdo, zainicjowanie siÄ™ nie powiodÅ‚o z powodu: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Gniazdo jest już zamkniÄ™te" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Przekroczono czas oczekiwania wejÅ›cia/wyjÅ›cia gniazda" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "tworzenie GSocket z fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Nie można utworzyć gniazda: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Podano nieznanÄ… rodzinÄ™" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Podano nieznany protokół" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Nie można używać dziaÅ‚aÅ„ datagramowych na niedatagramowych gniazdach." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Nie można używać dziaÅ‚aÅ„ datagramowych na gniazdach z ustawionym czasem " +"oczekiwania." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "nie można uzyskać lokalnego adresu: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "nie można uzyskać zdalnego adresu: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "nie można nasÅ‚uchiwać: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Błąd podczas dowiÄ…zywania do adresu %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Błąd podczas dołączania do grupy multicast: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Błąd podczas opuszczania grupy multicast: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Brak obsÅ‚ugi multicastu dla konkretnych źródeÅ‚" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "NieobsÅ‚ugiwana rodzina gniazda" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "konkretne źródÅ‚a nie sÄ… adresem IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Nazwa interfejsu jest za dÅ‚uga" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Nie odnaleziono interfejsu: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Brak obsÅ‚ugi multicastu IPv4 dla konkretnych źródeÅ‚" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Brak obsÅ‚ugi multicastu IPv6 dla konkretnych źródeÅ‚" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Błąd podczas akceptowania połączenia: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Trwa połączenie" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Nie można uzyskać oczekujÄ…cego błędu: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Błąd podczas pobierania danych: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Błąd podczas wysyÅ‚ania danych: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Nie można zamknąć gniazda: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Błąd podczas zamykania gniazda: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Oczekiwanie na warunek gniazda: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Nie można wysÅ‚ać komunikatu: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Wektory komunikatu sÄ… za duże" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Błąd podczas wysyÅ‚ania komunikatu: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage nie jest obsÅ‚ugiwane w systemie Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Błąd podczas pobierania komunikatu: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Nie można odczytać danych uwierzytelniajÄ…cych gniazda: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials nie jest zaimplementowane dla tego systemu " +"operacyjnego" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Nie można połączyć z serwerem poÅ›rednika %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Nie można połączyć z %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Nie można połączyć: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "PoÅ›redniczenie przez połączenie niebÄ™dÄ…ce TCP nie jest obsÅ‚ugiwane." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Protokół poÅ›rednika „%s†nie jest obsÅ‚ugiwany." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "NasÅ‚uch jest już zamkniÄ™ty" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Dodane gniazdo jest zamkniÄ™te" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 nie obsÅ‚uguje adresu IPv6 „%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Nazwa użytkownika jest za dÅ‚uga dla protokoÅ‚u SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Nazwa komputera „%s†jest za dÅ‚uga dla protokoÅ‚u SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Serwer nie jest serwerem poÅ›rednika SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Połączenie przez serwer SOCKSv4 zostaÅ‚o odrzucone" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Serwer nie jest serwerem poÅ›rednika SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "PoÅ›rednik SOCKSv5 wymaga uwierzytelnienia." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 wymaga metody uwierzytelnienia nieobsÅ‚ugiwanÄ… przez bibliotekÄ™ GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Nazwa użytkownika lub hasÅ‚o sÄ… za dÅ‚ugie dla protokoÅ‚u SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Uwierzytelnienie SOCKSv5 siÄ™ nie powiodÅ‚o z powodu błędnej nazwy użytkownika " +"lub hasÅ‚a." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Nazwa komputera „%s†jest za dÅ‚uga dla protokoÅ‚u SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Serwer poÅ›rednika SOCKSv5 używa nieznanego typu adresu." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "WewnÄ™trzny błąd serwera poÅ›rednika SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Połączenia SOCKSv5 nie sÄ… dozwolone przez zestaw reguÅ‚." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Komputer jest niedostÄ™pny przez serwer SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Sieć jest niedostÄ™pna przez serwer SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Połączenie przez poÅ›rednika SOCKSv5 zostaÅ‚o odrzucone." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "PoÅ›rednik SOCKSv5 nie obsÅ‚uguje polecenia „connectâ€." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "PoÅ›rednik SOCKSv5 nie obsÅ‚uguje podanego typu adresu." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Nieznany błąd poÅ›rednika SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Utworzenie potoku do komunikacji z procesem potomnym (%s) siÄ™ nie powiodÅ‚o" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Potoki nie sÄ… obsÅ‚ugiwane na tej platformie" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Nie można obsÅ‚użyć wersji %d kodowania GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Nie odnaleziono prawidÅ‚owych adresów" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Błąd podczas odwrotnego rozwiÄ…zywania „%sâ€: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "" +"Błąd podczas przetwarzania wpisu DNS %s: błędnie sformatowany pakiet DNS" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Brak wpisu DNS żądanego typu dla „%sâ€" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Nie można tymczasowo rozwiÄ…zać „%sâ€" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Błąd podczas rozwiÄ…zywania „%sâ€" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Błędnie sformatowany pakiet DNS" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Przetworzenie odpowiedzi DNS na „%s†siÄ™ nie powiodÅ‚o: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Nie odnaleziono klucza prywatnego zakodowanego za pomocÄ… PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Nie można odszyfrować klucza prywatnego zakodowanego za pomocÄ… PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Nie można przetworzyć klucza prywatnego zakodowanego za pomocÄ… PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Nie odnaleziono certyfikatu zakodowanego za pomocÄ… PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Nie można przetworzyć certyfikatów zakodowanych za pomocÄ… PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Obecny mechanizm TLS nie obsÅ‚uguje PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" +"Ten mechanizm GTlsBackend nie obsÅ‚uguje tworzenia certyfikatów PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"To jest ostatnia szansa na poprawne podanie hasÅ‚a, zanim dostÄ™p zostanie " +"zablokowany." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Kilka podanych haseÅ‚ byÅ‚o niepoprawnych, dostÄ™p zostanie zablokowany po " +"dalszych niepowodzeniach." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Podane hasÅ‚o jest niepoprawne." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "WysyÅ‚anie DP nie jest obsÅ‚ugiwane" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Oczekiwano jeden komunikat kontrolny, otrzymano %d" +msgstr[1] "Oczekiwano jeden komunikat kontrolny, otrzymano %d" +msgstr[2] "Oczekiwano jeden komunikat kontrolny, otrzymano %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Nieoczekiwany typ podrzÄ™dnych danych" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Oczekiwano jedno fd, a otrzymano %d\n" +msgstr[1] "Oczekiwano jedno fd, a otrzymano %d\n" +msgstr[2] "Oczekiwano jedno fd, a otrzymano %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Pobrano nieprawidÅ‚owe fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Odbieranie DP nie jest obsÅ‚ugiwane" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Błąd podczas wysyÅ‚ania danych uwierzytelniajÄ…cych: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"Błąd podczas sprawdzania, czy zmienna SO_PASSCRED zostaÅ‚a włączona dla " +"gniazda: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Błąd podczas włączania zmiennej SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Oczekiwano odczytania pojedynczego bajtu dla odbieranych danych " +"uwierzytelniajÄ…cych, ale odczytano zero bajtów" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Nie oczekiwano komunikatu kontrolnego, a otrzymano %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Błąd podczas wyłączania zmiennej SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Błąd podczas odczytywania z deskryptora pliku: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Błąd podczas zamykania deskryptora pliku: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Katalog główny systemu plików" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Błąd podczas zapisywania do deskryptora pliku: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Abstrakcyjne adresy gniazd domen systemu UNIX nie sÄ… obsÅ‚ugiwane w tym " +"systemie" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "wolumin nie obsÅ‚uguje wysuniÄ™cia" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "wolumin nie obsÅ‚uguje wysuniÄ™cia lub „eject_with_operationâ€" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Błąd podczas odczytywania z pliku obsÅ‚ugi: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Błąd podczas zamykania pliku obsÅ‚ugi: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Błąd podczas zapisywania do pliku obsÅ‚ugi: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Brak wystarczajÄ…cej iloÅ›ci pamiÄ™ci" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Błąd wewnÄ™trzny: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Wymagane jest danych wejÅ›ciowych" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "NieprawidÅ‚owe skompresowane dane" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adres, na którym nasÅ‚uchiwać" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorowane, dla zgodnoÅ›ci z GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "WyÅ›wietla adres" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "WyÅ›wietla adres w trybie powÅ‚oki" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Uruchamia usÅ‚ugÄ™ D-Bus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Błędne parametry\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Nieoczekiwany atrybut „%s†dla elementu „%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Nie odnaleziono atrybutu „%s†dla elementu „%sâ€" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Nieoczekiwany znacznik „%sâ€, oczekiwano znacznika „%sâ€" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Nieoczekiwany znacznik „%s†wewnÄ…trz „%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "NieprawidÅ‚owa data/czas „%s†w pliku zakÅ‚adek" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Nie można odnaleźć prawidÅ‚owego pliku zakÅ‚adek w katalogach danych" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "ZakÅ‚adka dla adresu URI „%s†już istnieje" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nie odnaleziono zakÅ‚adki dla adresu URI „%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Nie zdefiniowano typu MIME w zakÅ‚adce dla adresu URI „%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Nie zdefiniowano prywatnej flagi w zakÅ‚adce dla adresu URI „%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Nie ustawiono grup w zakÅ‚adce dla adresu URI „%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Å»aden program o nazwie „%s†nie zarejestrowaÅ‚ zakÅ‚adki dla „%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "RozwiniÄ™cie wiersza exec „%s†z adresem URI „%s†siÄ™ nie powiodÅ‚o" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Nieprzedstawialny znak na wejÅ›ciu konwersji" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Na koÅ„cu wejÅ›cia wystÄ™puje sekwencja odpowiadajÄ…ca części znaku" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Nie można skonwertować napisu zastÄ™pczego „%s†na zestaw znaków „%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Osadzony bajt NUL na wejÅ›ciu konwersji" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Osadzony bajt NUL na wyjÅ›ciu konwersji" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" +"Adres URI „%s†nie jest bezwzglÄ™dnym adresem URI, używajÄ…cym schematu „fileâ€" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Adres URI lokalnego pliku „%s†nie może zawierać znaku „#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Adres URI „%s†jest nieprawidÅ‚owy" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Nazwa komputera w adresie URI „%s†jest nieprawidÅ‚owa" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Adres URI „%s†zawiera nieprawidÅ‚owe znaki sterujÄ…ce" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Åšcieżka „%s†nie jest Å›cieżkÄ… bezwzglÄ™dnÄ…" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %-d %b %Y, %H∶%M∶%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%-d %b %Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H∶%M∶%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%-I∶%M∶%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "styczeÅ„" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "luty" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "marzec" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "kwiecieÅ„" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "czerwiec" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "lipiec" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "sierpieÅ„" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "wrzesieÅ„" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "październik" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "listopad" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "grudzieÅ„" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "sty" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "lut" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "kwi" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "cze" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "lip" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "sie" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "wrz" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "paź" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "lis" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "gru" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "poniedziaÅ‚ek" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "wtorek" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Å›roda" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "czwartek" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "piÄ…tek" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sobota" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "niedziela" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "pon" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "wto" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Å›ro" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "czw" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "piÄ…" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sob" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "nie" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "stycznia" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "lutego" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "marca" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "kwietnia" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "maja" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "czerwca" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "lipca" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "sierpnia" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "wrzeÅ›nia" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "października" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "listopada" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "grudnia" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "sty" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "lut" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "kwi" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "cze" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "lip" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "sie" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "wrz" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "paź" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "lis" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "gru" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Błąd podczas otwierania katalogu „%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Nie można przydzielić %lu bajtu do odczytu pliku „%sâ€" +msgstr[1] "Nie można przydzielić %lu bajtów do odczytu pliku „%sâ€" +msgstr[2] "Nie można przydzielić %lu bajtów do odczytu pliku „%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Błąd podczas odczytywania pliku „%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Plik „%s†jest za duży" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Odczytanie z pliku „%s†siÄ™ nie powiodÅ‚o: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Otwarcie pliku „%s†siÄ™ nie powiodÅ‚o: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Uzyskanie atrybutów pliku „%s†siÄ™ nie powiodÅ‚o: funkcja fstat() zwróciÅ‚a " +"błąd: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "" +"Otwarcie pliku „%s†siÄ™ nie powiodÅ‚o: funkcja fdopen() zwróciÅ‚a błąd: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Zmiana nazwy pliku „%s†na „%s†siÄ™ nie powiodÅ‚a: funkcja g_rename() " +"zwróciÅ‚a błąd: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "" +"Zapisanie pliku „%s†siÄ™ nie powiodÅ‚o: funkcja write() zwróciÅ‚a błąd: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "" +"Zapisanie pliku „%s†siÄ™ nie powiodÅ‚o: funkcja fsync() zwróciÅ‚a błąd: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Utworzenie pliku „%s†siÄ™ nie powiodÅ‚o: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Nie można usunąć istniejÄ…cego pliku „%sâ€: funkcja g_unlink() zwróciÅ‚a błąd: " +"%s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Szablon „%s†jest nieprawidÅ‚owy, nie powinien on zawierać „%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Szablon „%s†nie zawiera XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Odczytanie dowiÄ…zania symbolicznego „%s†siÄ™ nie powiodÅ‚o: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Nie można otworzyć konwertera z „%s†na „%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Nie można wykonać surowego odczytu w zmiennej g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "W buforze odczytu pozostaÅ‚y nieskonwertowane dane" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Na koÅ„cu kanaÅ‚u wystÄ™puje sekwencja odpowiadajÄ…ca części znaku" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Nie można wykonać surowego odczytu w zmiennej g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Nie można odnaleźć prawidÅ‚owego pliku klucza w przeszukiwanych katalogach" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "To nie jest zwykÅ‚y plik" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Plik klucza zawiera wiersz „%sâ€, który nie jest parÄ… klucz-wartość, grupÄ… " +"lub komentarzem" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "NieprawidÅ‚owa nazwa grupy: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Plik klucza nie rozpoczyna siÄ™ od grupy" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "NieprawidÅ‚owa nazwa klucza: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Plik klucza zawiera nieobsÅ‚ugiwane kodowanie „%sâ€" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Plik klucza nie zawiera grupy „%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Plik klucza nie zawiera klucza „%s†w grupie „%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Plik klucza zawiera klucz „%s†o wartoÅ›ci „%sâ€, która nie jest zapisana " +"w UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Plik klucza zawiera klucz „%sâ€, który ma wartość niemożliwÄ… do " +"zinterpretowania." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Plik klucza zawiera klucz „%s†w grupie „%sâ€, która ma wartość niemożliwÄ… do " +"zinterpretowania." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Klucz „%s†w grupie „%s†ma wartość „%sâ€, podczas gdy oczekiwano %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Plik klucza zawiera znak sterujÄ…cy na koÅ„cu linii" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Plik klucza zawiera nieprawidÅ‚owÄ… sekwencjÄ™ sterujÄ…cÄ… „%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Nie można zinterpretować „%s†jako liczby." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Wartość caÅ‚kowita „%s†jest spoza dopuszczalnego zakresu" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Nie można zinterpretować „%s†jako liczby zmiennoprzecinkowej." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Nie można zinterpretować „%s†jako wartoÅ›ci logicznej." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Uzyskanie atrybutów pliku „%s%s%s%s†siÄ™ nie powiodÅ‚o: funkcja fstat() " +"zwróciÅ‚a błąd: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" +"Zmapowanie pliku %s%s%s%s siÄ™ nie powiodÅ‚o: funkcja mmap() zwróciÅ‚a błąd: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Otwarcie pliku „%s†siÄ™ nie powiodÅ‚o: funkcja open() zwróciÅ‚a błąd: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Błąd w %d. wierszu przy %d. znaku: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "" +"Nazwa zawiera nieprawidÅ‚owy tekst zakodowany za pomocÄ… UTF-8 — nieprawidÅ‚owe " +"„%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "„%s†nie jest prawidÅ‚owÄ… nazwÄ…" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "„%s†nie jest prawidÅ‚owÄ… nazwÄ…: „%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Błąd w %d. wierszu: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Nie można przetworzyć znaku „%-.*sâ€, w którego miejscu powinna wystÄ…pić " +"liczba, bÄ™dÄ…ca częściÄ… odniesienia do znaku (np. ê) — być może liczba " +"jest za duża" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Odniesienie do znaku nie jest zakoÅ„czone Å›rednikiem; najprawdopodobniej " +"zostaÅ‚ użyty znak &, który nie miaÅ‚ oznaczać jednostki — należy go zapisać " +"jako &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Odniesienie do znaku „%-.*s†nie jest zapisem dozwolonego znaku" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Napotkano pustÄ… jednostkÄ™ „&;â€; poprawnymi jednostkami sÄ…: & " < " +"> '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Nazwa jednostki „%-.*s†nie jest znana" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Jednostka nie jest zakoÅ„czona Å›rednikiem; najprawdopodobniej zostaÅ‚ użyty " +"znak &, który nie miaÅ‚ oznaczać jednostki — należy go zapisać jako &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument musi rozpoczynać siÄ™ jakimÅ› elementem (np. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"Znak „%s†nie powinien wystÄ™pować po znaku „<â€; nie może on rozpoczynać " +"nazwy elementu" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Nieoczekiwany znak „%sâ€, oczekiwano znaku „>â€, aby zakoÅ„czyć znacznik „%s†" +"pustego elementu" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Za dużo atrybutów w elemencie „%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Nieoczekiwany znak „%sâ€; po nazwie atrybutu „%s†elementu „%s†oczekiwano " +"znaku „=â€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Nieoczekiwany znak „%sâ€; oczekiwano znaku „>†lub „/â€, koÅ„czÄ…cego znacznik " +"poczÄ…tkowy elementu „%s†lub opcjonalnie atrybutu; być może w nazwie " +"atrybutu zostaÅ‚ użyty nieprawidÅ‚owy znak" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Nieoczekiwany znak „%sâ€; oczekiwano otwierajÄ…cego znaku cudzysÅ‚owu po znaku " +"równoÅ›ci podczas podawania wartoÅ›ci atrybutu „%s†elementu „%sâ€" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"Znak „%s†nie jest znakiem, który może wystÄ…pić po domykajÄ…cej nazwie " +"elementu „%sâ€; dopuszczalnym znakiem jest „>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Element „%s†zostaÅ‚ zamkniÄ™ty, ale brak obecnie otwartego elementu" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"Element „%s†zostaÅ‚ zamkniÄ™ty, ale obecnie otwartym elementem jest „%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument jest pusty lub zawiera tylko spacje" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Zaraz po znaku „<†nastÄ…piÅ‚ nieoczekiwany koniec dokumentu" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"NastÄ…piÅ‚ nieoczekiwany koniec dokumentu, gdy pewne elementy sÄ… wciąż otwarte " +"— „%s†byÅ‚ ostatnim otwartym elementem" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"NastÄ…piÅ‚ nieoczekiwany koniec dokumentu; oczekiwano znaku „>â€, koÅ„czÄ…cego " +"znacznik <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "NastÄ…piÅ‚ nieoczekiwany koniec dokumentu wewnÄ…trz nazwy elementu" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "NastÄ…piÅ‚ nieoczekiwany koniec dokumentu wewnÄ…trz nazwy atrybutu" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"NastÄ…piÅ‚ nieoczekiwany koniec dokumentu wewnÄ…trz znacznika otwierajÄ…cego " +"element." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"NastÄ…piÅ‚ nieoczekiwany koniec dokumentu po znaku równoÅ›ci wystÄ™pujÄ…cym po " +"nazwie atrybutu; brak wartoÅ›ci atrybutu" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "NastÄ…piÅ‚ nieoczekiwany koniec dokumentu wewnÄ…trz wartoÅ›ci atrybutu" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"NastÄ…piÅ‚ nieoczekiwany koniec dokumentu wewnÄ…trz znacznika domykajÄ…cego " +"elementu „%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"NastÄ…piÅ‚ nieoczekiwany koniec dokumentu wewnÄ…trz znacznika domykajÄ…cego " +"nieotwartego elementu" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"NastÄ…piÅ‚ nieoczekiwany koniec dokumentu wewnÄ…trz komentarza lub instrukcji " +"przetwarzania" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPCJA…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opcje pomocy:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "WyÅ›wietla opcje pomocy" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "WyÅ›wietla wszystkie opcje pomocy" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opcje programu:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opcje:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Nie można przetworzyć wartoÅ›ci caÅ‚kowitej „%s†dla %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Wartość caÅ‚kowita „%s†dla %s jest spoza dopuszczalnego zakresu" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Nie można przetworzyć podwójnej wartoÅ›ci liczbowej „%s†dla %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "" +"Podwójna wartość liczbowa „%s†dla %s jest spoza dopuszczalnego zakresu" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Błąd podczas przetwarzania opcji %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Brak parametru dla %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Nieznana opcja %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "uszkodzony obiekt" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "błąd wewnÄ™trzny lub uszkodzony obiekt" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "brak pamiÄ™ci" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "osiÄ…gniÄ™to limit wyjÄ…tku" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "wzorzec zawiera elementy nieobsÅ‚ugiwane w dopasowywaniu częściowym" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "błąd wewnÄ™trzny" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"referencje wstecz jako warunki nie sÄ… obsÅ‚ugiwane w dopasowywaniu częściowym" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "osiÄ…gniÄ™to limit rekurencji" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "nieprawidÅ‚owa kombinacja flag nowych linii" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "błędne wyrównanie" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "krótki UTF-8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "pÄ™tla rekurencji" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "nieznany błąd" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ na koÅ„cu wzoru" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c na koÅ„cu wzoru" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "nierozpoznany znak po \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "liczby w operatorze {} nie sÄ… w kolejnoÅ›ci" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "liczba za duża w kwantyfikatorze {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "brak koÅ„czÄ…cego znaku „]†dla klasy znaku" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "nieprawidÅ‚owa sekwencja sterujÄ…ca w klasie znaku" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "zakres klasy znaków nie jest w kolejnoÅ›ci" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nic do powtórzenia" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "nieoczekiwane powtórzenie" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "nierozpoznany znak po (? lub (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "Klasy nazwane z użyciem POSIX sÄ… obsÅ‚ugiwane tylko wewnÄ…trz klasy" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "brak znaku koÅ„czÄ…cego )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "nawiÄ…zanie do nieistniejÄ…cego podwzoru" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "brakujÄ…cy znak „)†po komentarzu" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "wyrażenie regularne jest za duże" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "uzyskanie pamiÄ™ci siÄ™ nie powiodÅ‚o" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "znak ) bez znaku otwierajÄ…cego (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "przepeÅ‚nienie kodu" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "nierozpoznany znak po (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "asercja „lookbehind†nie ma staÅ‚ej dÅ‚ugoÅ›ci" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "błędna liczba lub nazwa za (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "zależna grupa zawiera wiÄ™cej niż dwie gałęzie" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "za (?( oczekiwano asercji" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "po (?R lub (?[+-]cyfry musi nastÄ™pować znak )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nieznana nazwa klasy POSIX" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "elementy porównujÄ…ce POSIX nie sÄ… obsÅ‚ugiwane" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "wartość znaku w sekwencji \\x{...} jest za duża" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "nieprawidÅ‚owy warunek (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "znak \\C nie jest dozwolony w asercji „lookbehindâ€" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "znaki sterujÄ…ce \\L, \\l, \\N{nazwa}, \\U i \\u nie sÄ… obsÅ‚ugiwane" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "wywoÅ‚anie rekurencyjne mogÅ‚o prowadzić do pÄ™tli nieskoÅ„czonej" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "nierozpoznany znak po (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "brak terminatora w nazwie podwzoru" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dwa podwzory majÄ… tÄ™ samÄ… nazwÄ™" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "błędna sekwencja \\P lub \\p" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nieznana nazwa wÅ‚aÅ›ciwoÅ›ci za \\P lub \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "nazwa podwzoru jest za dÅ‚uga (maksymalnie 32 znaki)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "za dużo nazwanych podwzorów (maksymalnie 10000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "wartość ósemkowa jest wiÄ™ksza niż \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "przekroczono przestrzeÅ„ roboczÄ… kompilacji" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "nie znaleziono wczeÅ›niej sprawdzonego podwzoru" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "grupa DEFINE zawiera wiÄ™cej niż jednÄ… gałąź" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "niespójne opcje NEWLINE" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"po \\g nie nastÄ™puje nazwa lub liczba w nawiasach, nawiasach ostrych, " +"cytowana, ani zwykÅ‚a liczba" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "liczbowe odniesienie nie może wynosić zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "parametr nie jest dozwolony dla (*ACCEPT), (*FAIL) lub (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "nie rozpoznano (*VERB)" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "liczba jest za duża" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "brak nazwy podwzoru po (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "oczekiwano cyfry po (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] jest nieprawidÅ‚owym znakiem danych w trybie zgodnoÅ›ci z jÄ™zykiem JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "różne nazwy dla podwzorów tej samej liczby nie sÄ… dozwolone" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) musi mieć parametr" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "po \\c musi być znak ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"po \\k nie nastÄ™puje nazwa w nawiasach, nawiasach ostrych, ani cytowana" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N nie jest obsÅ‚ugiwane w klasie" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "za dużo odniesieÅ„ naprzód" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "nazwa jest za dÅ‚uga w (*MARK), (*PRUNE), (*SKIP) lub (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "wartość znaku w sekwencji \\u.... jest za duża" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Błąd podczas dopasowywania wyrażenia regularnego %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Biblioteka PCRE zostaÅ‚a skompilowana bez obsÅ‚ugi UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Biblioteka PCRE zostaÅ‚a skompilowana bez obsÅ‚ugi wÅ‚aÅ›ciwoÅ›ci UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Biblioteka PCRE zostaÅ‚a skompilowana za pomocÄ… niezgodnych opcji" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Błąd podczas optymalizowania wyrażenia regularnego %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Błąd kompilacji wyrażenia regularnego %s przy znaku %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "oczekiwano cyfry szesnastkowej lub znaku „}â€" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "oczekiwano cyfry szesnastkowej" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "brak znaku „<†w odniesieniu symbolicznym" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "niezakoÅ„czona referencja symboliczna" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "referencja symboliczna o zerowej dÅ‚ugoÅ›ci" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "oczekiwano cyfry" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "niedozwolona referencja symboliczna" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "pominiÄ™to koÅ„cowe „\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "nieznana sekwencja sterujÄ…ca" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Błąd podczas przetwarzania tekstu zastÄ™pczego „%s†przy znaku %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Cytowany znak nie rozpoczyna siÄ™ znakiem cytowania" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"W wierszu poleceÅ„ lub innym napisie cytowanym jak w powÅ‚oce wystÄ…piÅ‚ " +"niesparowany znak cytowania" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "" +"Tekst zakoÅ„czyÅ‚ siÄ™ bezpoÅ›rednio po znaku „\\†(wartoÅ›ciÄ… tekstu byÅ‚o „%sâ€)." + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Tekst zakoÅ„czyÅ‚ siÄ™ przed odnalezieniem domykajÄ…cego znaku cytowania dla %c " +"(tekstem jest „%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Tekst jest pusty (lub zawiera tylko spacje)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Odczytanie danych z procesu potomnego (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "" +"Nieoczekiwany błąd podczas odczytywania danych z procesu potomnego (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Nieoczekiwany błąd w waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Proces potomny zostaÅ‚ zakoÅ„czony z kodem %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Proces potomny zostaÅ‚ zakoÅ„czony sygnaÅ‚em %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Proces potomny zostaÅ‚ zatrzymany sygnaÅ‚em %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Proces potomny zostaÅ‚ nieprawidÅ‚owo zakoÅ„czony" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" +"Odczytanie danych z potoku łączÄ…cego z procesem potomnym (%s) siÄ™ nie " +"powiodÅ‚o" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "WywoÅ‚anie procesu potomnego „%s†(%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Rozdzielenie procesu (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Zmiana katalogu na „%s†(%s) siÄ™ nie powiodÅ‚a" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Wykonanie procesu potomnego „%s†(%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" +"Otwarcie pliku do ponownego mapowania deskryptora pliku (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "" +"Powielenie deskryptora pliku dla procesu potomnego (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Rozdzielenie procesu potomnego (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "" +"ZamkniÄ™cie deskryptora pliku dla procesu potomnego (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Podczas wykonywania procesu potomnego „%s†wystÄ…piÅ‚ nieznany błąd" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Odczytanie odpowiedniej liczby danych z potoku procesu potomnego (%s) siÄ™ " +"nie powiodÅ‚o" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Odczytanie danych z procesu potomnego siÄ™ nie powiodÅ‚o" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Wykonanie procesu potomnego (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Wykonanie dup() w procesie potomnym (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "NieprawidÅ‚owa nazwa programu: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "NieprawidÅ‚owy ciÄ…g w wektorze parametrów w %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "NieprawidÅ‚owa sekwencja w środowisku: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "NieprawidÅ‚owy katalog roboczy: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Wykonanie programu pomocniczego (%s) siÄ™ nie powiodÅ‚o" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Podczas odczytu danych z procesu potomnego w g_io_channel_win32_poll() " +"wystÄ…piÅ‚ nieznany błąd" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Pusty ciÄ…g nie jest liczbÄ…" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s†nie jest liczbÄ… ze znakiem" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Liczba „%s†jest poza zakresem [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s†nie jest liczbÄ… bez znaku" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "NieprawidÅ‚owe „%-encoding†w adresie URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Niedozwolony znak w adresie URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Znaki niebÄ™dÄ…ce UTF-8 w adresie URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "NieprawidÅ‚owy adres IPv6 „%.*s†w adresie URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Niedozwolony zakodowany adres IP „%.*s†w adresie URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Niedozwolona umiÄ™dzynarodowiona nazwa komputera „%.*s†w adresie URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Nie można przetworzyć portu „%.*s†w adresie URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Port „%.*s†w adresie URI jest poza zakresem" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "Adres URI „%s†nie jest bezwzglÄ™dnym adresem URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "Adres URI „%s†nie ma skÅ‚adnika komputera" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "Adres URI nie jest bezwzglÄ™dny i nie podano podstawy adresu URI" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Brak „=†i wartoÅ›ci parametru" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Przydzielenie pamiÄ™ci siÄ™ nie powiodÅ‚o" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Znak jest poza zakresem dla UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "NieprawidÅ‚owa sekwencja na wejÅ›ciu konwersji" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Znak jest poza zakresem dla UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajt" +msgstr[1] "%u bajty" +msgstr[2] "%u bajtów" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bity" +msgstr[2] "%u bitów" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bajt" +msgstr[1] "%s bajty" +msgstr[2] "%s bajtów" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bity" +msgstr[2] "%s bitów" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" diff --git a/po/po2tbl.sed.in b/po/po2tbl.sed.in new file mode 100644 index 0000000..bc6ff22 --- /dev/null +++ b/po/po2tbl.sed.in @@ -0,0 +1,101 @@ +# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +1 { + i\ +/* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\ +\ +#if HAVE_CONFIG_H\ +# include \ +#endif\ +\ +#include "libgettext.h"\ +\ +const struct _msg_ent _msg_tbl[] = { + h + s/.*/0/ + x +} +# +# Write msgid entries in C array form. +# +/^msgid/ { + s/msgid[ ]*\(".*"\)/ {\1/ + tb +# Append the next line + :b + N +# Look whether second part is continuation line. + s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/ +# Yes, then branch. + ta +# Because we assume that the input file correctly formed the line +# just read cannot be again be a msgid line. So it's safe to ignore +# it. + s/\(.*\)\n.*/\1/ + bc +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use D here. + s/.*\n\(.*\)/\1/ +# Some buggy seds do not clear the `successful substitution since last ``t''' +# flag on `N', so we do a `t' here to clear it. + tb +# Not reached + :c + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x + G + s/\(.*\)\n\([0-9]*\)/\1, \2},/ + s/\(.*\)"$/\1/ + p +} +# +# Last line. +# +$ { + i\ +};\ + + g + s/0*\(.*\)/int _msg_tbl_length = \1;/p +} +d diff --git a/po/ps.po b/po/ps.po new file mode 100644 index 0000000..dc6f3e8 --- /dev/null +++ b/po/ps.po @@ -0,0 +1,3744 @@ +# Pashto translation of glib.head +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the Glib package. +# Zabeeh Khan , 2008. +# +msgid "" +msgstr "" +"Project-Id-Version: glib.head\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2009-04-12 17:07-0800\n" +"Last-Translator: \n" +"Language-Team: Pashto \n" +"Language: ps\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Pashto, Pushto\n" +"X-Poedit-Country: AFGHANISTAN\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "په اومتوک درکموندونو Ú©Û Ú©ÙˆÙ…Ù‡ سمه ليکنښه دوتنه ونه موندل شوه" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "لپاره يوه ليکنښه د Ù…Ø®Ú©Û Ù†Ù‡ شته دی URI '%s' د" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "لپاره کومه ليکنښه ونه مونل شوه URI '%s' د" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "%s :د Ø§Ú“ÙˆÙ†Û Ù¾Ø± مهال ستونزه" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "ناسم دی URI '%s'" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "ناسم کوربه نوم" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "غ.Ù…." + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "غ.Ùˆ." + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A د %Y د %B %eØŒ %Z %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "د %Y د %B %e" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "‫%I:%M:%S %p‬" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "جنوري" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "ÙØ¨Ø±ÙˆØ±ÙŠ" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "مارچ" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "اپریل" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Ù…Û" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "جون" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "جولاي" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "جنو" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ÙØ¨Ø±" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "مار" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "اپر" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "مـÛ" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "جون" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "جول" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "دوشنبه" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "سه‌شنبه" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "چارشنبه" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "پنجشنبه" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "جمعه" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "شنبه" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "یکشنبه" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "د." + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "س." + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ú†." + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Ù¾." + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ج." + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Ø´." + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ÛŒ." + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "%s :درکموند پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "%s :دوتنه لوسلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ù†Ù‡ لوستلو Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ '%s' د" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ '%s'" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ø¬ÙˆÚ“ÙˆÙ„Ùˆ Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ '%s' د" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:962 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f Ú© ب" + +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f Ù… ب" + +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f Ú« ب" + +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f Ú© ب" + +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f Ú© ب" + +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f Ú© ب" + +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f Ú© ب" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Ù… ب" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Ú« ب" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, fuzzy, c-format +msgid "%.1f TB" +msgstr "%.1f Ú© ب" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, fuzzy, c-format +msgid "%.1f PB" +msgstr "%.1f Ú© ب" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, fuzzy, c-format +msgid "%.1f EB" +msgstr "%.1f Ú© ب" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f Ú© ب" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "%s :په لوستلو Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ '%s' د Ù¾Ûلامي تړنÛ" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Ù¾Ûلامي ØªÚ“Ù†Û Ù†Ù‡ منل Ú©ÙŠÚ–ÙŠ" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "اندرغل څيز" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "Ø¯Ù†Ù†Ù†Û ØªÛØ±ÙˆØªÙ†Ù‡ يا اندرغل څيز" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "له ياده بهر" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "Ø¯Ù†Ù†Ù†Û ØªÛØ±ÙˆØªÙ†Ù‡" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "ناپÛÚ˜Ù†Ø¯Ù„Û ØªÛØ±ÙˆØªÙ†Ù‡" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "ليکنه تشه وه (يا ÙŠÙˆØ§Ø²Û Ø³Ù¾ÙŠÙ†Ù‡ تشه ÙŠÛ Ù„Ø±Ù„Ù‡)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "د ماشوم بهير نه د اومتوک په لوستلو Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "(%s) درکموند ته Ø¨Ø¯Ù„ÛØ¯Ù„Ùˆ Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ '%s'" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "(%s) د ماشوم بهيرپه Ù¾Ûلولو Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "%s :ناسم کړنلار نوم" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "%s :ناسم Ú©Ø§Ø±ÙˆÙ†Û Ø¯Ø±Ú©Ù…ÙˆÙ†Ø¯" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "په Ù¾Ûلولو Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ (%s) د مرستندويه کړنلار" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr ":کارونه" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[...غوراوی]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr ":مرسته غوراوي" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "مرسته غوراوي ښودل" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "ټول مرسته غوراوي ښودل" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr ":کاريال غوراوي" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "صحيح ارزښت له Ø³ÙŠÙ…Û Ø¨Ù‡Ø± دی '%s' لپاره د %s د" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "%s ناپÛÚ˜Ù†Ø¯Ù„Û ØºÙˆØ±Ø§ÙˆÛŒ" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "ساده دوتنه نه ده" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "دوتنه تشه ده" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "%s :ناسم ډله نوم" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Ú©ÙŠÙ„Û Ø¯ÙˆØªÙ†Ù‡ د Ú©ÙˆÙ…Û Ú‰Ù„Û Ø³Ø±Ù‡ نه Ù¾Ûليږي" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "%s :ناسم Ú©ÙŠÙ„Û Ù†ÙˆÙ…" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "لري '%s' Ú©ÙŠÙ„Û Ø¯ÙˆØªÙ†Ù‡ ناسمه کوډييزونه" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "ډله نه لري '%s' Ú©ÙŠÙ„Û Ø¯ÙˆØªÙ†Ù‡" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Ú©ÙŠÙ„Û Ù†Ù‡ لري '%s' Ú©ÙŠÙ„Û Ø¯ÙˆØªÙ†Ù‡" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Ú©ÙŠÙ„Û Ù†Ù‡ لري '%s' ډله Ú©Û '%s' Ú©ÙŠÙ„Û Ø¯ÙˆØªÙ†Ù‡ په" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "ارزښت د Ø´Ù…ÛØ±Û په توګه نه شي ژباړل Ú©ÛØ¯ÛŒ '%s'" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "د Ø³ÙŠÙ…Û Ù†Ù‡ بهر دی '%s' صحيح ارزښت" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "چار بند شو" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "چار نه منل Ú©ÙŠÚ–ÙŠ" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "ناپÛژندلی ډول" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "دوتنه ډول %s" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "ډول %s" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "%s :دوتنه لوسلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "%s :دوتنه لوسلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "%s :پر Ø¯ÙˆØªÙ†Û Ù„ÙŠÚ©Ù„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "%s :دوتنه لوسلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "ناپÛژندلی ډول" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "%s :درکموند پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "%s د Ù¾ÙˆÚšÛ Ù¾Ù‡ جوړولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡:" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "%s :دوتنه لوسلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "%s :دوتنه لوسلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "%s :دوتنه بندولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "%s :پر Ø¯ÙˆØªÙ†Û Ù„ÙŠÚ©Ù„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "چار نه منل Ú©ÙŠÚ–ÙŠ" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "%s :پر Ø¯ÙˆØªÙ†Û Ù„ÙŠÚ©Ù„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "%s :د Ø§Ú“ÙˆÙ†Û Ù¾Ø± مهال ستونزه" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:646 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%s :درکموند پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "%s :د Ø§Ú“ÙˆÙ†Û Ù¾Ø± مهال ستونزه" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "%s :درکموند پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "اندرغل څيز" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "بÛنومه" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "نه شي جوړولی %s د کارن Ø³Ø±Ù¾Ø§Ú¼Û Ø¯ÙˆØªÙ†Ù‡" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "لپاره دوديز Ù¾Ûژنداوی %s د" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "چار نه منل Ú©ÙŠÚ–ÙŠ" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "د درکموند پر سر نه شي Ù„Ù…ÛØ³Ù„ÛŒ" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "درکموند د درکموند پر سر نه شي Ù„Ù…ÛØ³Ù„ÛŒ" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "موخه دوتنه شتون لري" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Ù¾Ûلامي ØªÚ“Ù†Û Ù†Ù‡ منل Ú©ÙŠÚ–ÙŠ" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "ÚØ§Ù†Ú«Ú“Û Ø¯ÙˆØªÙ†Ù‡ نه شي Ù„Ù…ÛØ³Ù„ÛŒ" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "ناسم Ù¾ÛÙ„Ø§Ù…ØªÚ“Ù†Û Ø§Ø±Ø²ÚšØª ورکړل شوی" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "نه شي لرلی '%c' دوتنه نومونه" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "چار نه منل Ú©ÙŠÚ–ÙŠ" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "%s ناسم دوتنه نوم" + +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "%s :د دوتنه غونډال خبرتياوو اخيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "ÙˆÙ„Û Ø¯Ø±Ú©Ù…ÙˆÙ†Ø¯ نه شي بيانومولی" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "%s :دوتنه بيانومولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "دوتنه نه شي بيانومولی، دوتنه نوم د Ù…Ø®Ú©Û Ù†Ù‡ شته" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "ناسم دوتنه نوم" + +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "درکموند نه شي پرانيستلی" + +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ú“Ù†Ú«ÙˆÙ„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "" + +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "%s د Ù¾ÙˆÚšÛ Ù¾Ù‡ جوړولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡:" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "%s :په لوستلو Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ '%s' د Ù¾Ûلامي تړنÛ" + +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "%s :د Ù¾Ûلامي ØªÚ“Ù†Û Ù¾Ù‡ جوړولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "%s :دوتنه خوÚولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "يو درکموند پر بل درکموند نه شي خوÚولی" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "د شاتړ Ø¯ÙˆØªÙ†Û Ø¬ÙˆÚ“ÙˆÙ†Ù‡ Ù¾Ø§ØªÛ Ø±Ø§ØºÙ„Ù‡" + +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "%s :د موخه Ø¯ÙˆØªÙ†Û Ù¾Ù‡ ړنګولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "د ماونټونو ØªØ±Ù…Ù†Ú Ø®ÙˆÚÛØ¯Ù†Ù‡ نه منل Ú©ÙŠÚ–ÙŠ" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (ناسمه کوډييزونه)" + +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "%s :د پرÛښلو په امستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "%s :د پرÛښلو په امستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "%s :د خاوند په امستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "%s :د پرÛښلو په امستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ù†Ù‡ لوستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "%s :دوتنه بندولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "%s :پر Ø¯ÙˆØªÙ†Û Ù„ÙŠÚ©Ù„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "%s :د زوړ شاتړ تړون په ړنګولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "%s :شاتړ Ù„Ù…ÛØ³Û جوړولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "%s :د لنډمهاله Ø¯ÙˆØªÙ†Û Ù¾Ù‡ بيانومولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "موخه دوتنه يوه Ù¾ÙˆÚšÛ Ø¯Ù‡" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "موخه دوتنه ساده دوتنه نه ده" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "دوتنه په Ø¨Ù‡Ø±Ù†Û ØªÙˆÚ«Ù‡ بدله Ø´ÙˆÛ ÙˆÙ‡" + +#: ../gio/glocalfileoutputstream.c:1048 +#, c-format +msgid "Error removing old file: %s" +msgstr "%s :د Ø²Ú“Û Ø¯ÙˆØªÙ†Û Ú“Ù†Ú«ÙˆÙ„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "%s :دوتنه لوسلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "%s :دوتنه لوسلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡ '%s'" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ú“Ù†Ú«ÙˆÙ„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "%s ناپÛÚ˜Ù†Ø¯Ù„Û ØºÙˆØ±Ø§ÙˆÛŒ" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ù†Ù‡ لوستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ø¬ÙˆÚ“ÙˆÙ„Ùˆ Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ '%s' د" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "%s :پر Ø¯ÙˆØªÙ†Û Ù„ÙŠÚ©Ù„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "%s :د Ø§Ú“ÙˆÙ†Û Ù¾Ø± مهال ستونزه" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ú“Ù†Ú«ÙˆÙ„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ø¬ÙˆÚ“ÙˆÙ„Ùˆ Ú©Û Ù¾Ø§ØªÛ Ø±Ø§ØºÛŒ '%s' د" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "%s :دوتنه بندولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ú“Ù†Ú«ÙˆÙ„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +#, fuzzy +msgid "Unknown error on connect" +msgstr "ناپÛÚ˜Ù†Ø¯Ù„Û ØªÛØ±ÙˆØªÙ†Ù‡" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Ù¾Ûلامي ØªÚ“Ù†Û Ù†Ù‡ منل Ú©ÙŠÚ–ÙŠ" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "%s :دوتنه پرانيستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "%s :دوتنه بيانومولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "%s :د يونÛکس نه په لوستلو Ú©Û ØªÛØ±ÙˆØªÙ†Ù‡" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "%s :د يونÛکس په بندولو Ú©Û ØªÛØ±ÙˆØªÙ†Ù‡" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "دوتنه غونډال ولÛ" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "%s :پر يونÛکس ليکلو Ú©Û ØªÛØ±ÙˆØªÙ†Ù‡" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "کاريال نه شي موندلی" + +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "%s :د کاريال په Ù¾Ûلولو Ú©Û ØªÛØ±ÙˆØªÙ†Ù‡" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "نه منل Ú©ÙŠÚ–ÙŠ URIs" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "%s :Ø¯ÙˆØªÙ†Û Ù†Ù‡ لوستلو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "%s :دوتنه بندولو Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "%s :پر Ø¯ÙˆØªÙ†Û Ù„ÙŠÚ©Ù„Ùˆ Ú©Û Ø³ØªÙˆÙ†Ø²Ù‡" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "له ياده بهر" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "Ø¯Ù†Ù†Ù†Û ØªÛØ±ÙˆØªÙ†Ù‡" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "ناسم کوربه نوم" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "يو درکموند پر بل درکموند نه شي خوÚولی" + +#~ msgid "do not hide entries" +#~ msgstr "Ù†Ù†ÙˆØªÙ†Û Ù†Ù‡ پټول" + +#~ msgid "use a long listing format" +#~ msgstr "د اوږد Ù„Ú“ÙˆÙ†Û Ø¨Ú¼Ù‡ کارول" + +#~ msgid "[FILE...]" +#~ msgstr "[...دوتنه]" + +#~ msgid "The file containing the icon" +#~ msgstr "د انÚورن دوتنه" + +#~ msgid "name" +#~ msgstr "نوم" + +#~ msgid "The name of the icon" +#~ msgstr "د انÚورن نوم" + +#~ msgid "names" +#~ msgstr "نومونه" diff --git a/po/pt.po b/po/pt.po new file mode 100644 index 0000000..792671b --- /dev/null +++ b/po/pt.po @@ -0,0 +1,6715 @@ +# glib's Portuguese Translation +# Copyright © 2001-2022 glib +# Distributed under the same licence as the glib package +# Duarte Loreto , 2001-2014. +# Pedro Albuquerque , 2015. +# Sérgio Cardeira , 2016. +# Tiago Santos , 2014 - 2016. +# Juliano de Souza Camargo , 2020. +# Hugo Carvalho , 2020, 2021, 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: 3.12\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 15:19+0000\n" +"PO-Revision-Date: 2022-03-22 22:18+0000\n" +"Last-Translator: Hugo Carvalho \n" +"Language-Team: Portuguese \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Definição de aplicações predefinidas ainda não suportado" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "Definir aplicação como última utilizada para tipo ainda não suportado" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opções GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Mostrar opções GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Entrar em modo de serviço GApplication (utilizar a partir de ficheiros D-Bus " +"de serviço)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Ignorar o ID da aplicação" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Substituir a instância em execução" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Imprimir a ajuda" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMANDO]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Imprimir versão" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Imprimir informação de versão e sair" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Listar aplicações" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Listar as aplicações D-Bus ativáveis instaladas (por ficheiros .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Iniciar uma aplicação" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Iniciar a aplicação (com ficheiros opcionais a abrir)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "IDAPLICAÇÃO [FICHEIRO...]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Ativar uma ação" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invocar uma ação na aplicação" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "IDAPLICAÇÃO AÇÃO [PARÂMETRO]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Listar ações disponíveis" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Listar ações estáticas para uma aplicação (de ficheiro .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "IDAPLICAÇÃO" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMANDO" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "O comando para imprimir ajuda detalhada para" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identificador de aplicação em formato D-Bus (por ex: org.exemplo." +"visualizador)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FICHEIRO" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Nomes de ficheiro relativos ou absolutos opcionais, ou URIs a abrir" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "AÇÃO" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "O nome da ação a invocar" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARÂMETRO" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Parâmetro opcional para a invocação da ação, em formato GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Comando %s desconhecido\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Utilização:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumentos:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Comandos:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilizar “%s help COMANDO†para obter ajuda detalhada.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"O comando %s tem de ser imediatamente seguido de um id de aplicação\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "id de aplicação inválido: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†não recebe argumentos\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "impossível ligar ao D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "erro ao enviar a mensagem %s para a aplicação: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "nome da ação tem de ser especificado após o id de aplicação\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nome de ação inválido: “%sâ€\n" +"nomes de ações têm de consistir apenas de alfanuméricos, “-†e “.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "erro ao processar o parâmetro de ação: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "ação aceita no máximo um parâmetro\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "o comando list-actions apenas aceita o id de aplicação" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "impossível encontrar o ficheiro desktop da aplicação %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"comando desconhecido: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Valor de contagem demasiado grande passado para %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Procura não é suportada no fluxo base" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Impossível truncar um GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "O fluxo já se encontra fechado" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Truncar não é suportado no fluxo base" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "A operação foi cancelada" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Objeto inválido, não inicializado" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Sequência multibyte inválida na entrada" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Espaço insuficiente no destino" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Sequência de bytes inválida na origem da conversão" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Erro durante a conversão: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Não é suportada a inicialização cancelável" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Conversão do conjunto de caracteres “%s†para “%s†não é suportada" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Impossível abrir conversor de “%s†para “%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "Tipo %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Tipo desconhecido" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "Tipo de ficheiro %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials contém dados inválidos" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials não está implementado neste SO" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Não existe suporte para GCredentials na sua plataforma" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials não contém um ID de processo neste SO" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Simular credenciais não é possível neste SO" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Final precoce de fluxo inesperado" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Chave “%s†não suportada na entrada de endereço “%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Combinação chave/valor sem sentido na entrada de endereço “%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Endereço “%s†é inválido (é necessário um de caminho, dir, tmpdir ou chaves " +"abstratas)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Erro no endereço “%s†- o atributo “%s†está mal formado" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transporte “%s†desconhecido ou não suportado para o endereço “%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Elemento “%s†de endereço não contém dois-pontos (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Nome do transporte no elemento “%s†endereço não pode ser vazio" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Par chave/valor %d, “%sâ€, no elemento “%s†de endereço, não contém um sinal " +"de igual" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Par chave/valor %d, “%sâ€, no elemento “%s†de endereço não pode ser vazio" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Erro ao desfazer o escape de chave ou valor no par Chave/Valor %d, “%sâ€, no " +"elemento “%s†de endereço" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Erro no endereço “%s†— o transporte unix requer que exatamente uma das " +"chaves “path†ou “abstract†esteja definida" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Erro no endereço “%s†— o atributo host está em falta ou mal formado" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Erro no endereço “%s†— o atributo port está em falta ou mal formado" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Erro no endereço “%s†— o atributo noncefile está em falta ou mal formado" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Erro ao autoiniciar: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Erro ao abrir o ficheiro nonce “%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Erro ao ler do ficheiro nonce “%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Erro ao ler do ficheiro nonce “%sâ€, esperados 16 bytes, obtidos %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Erro ao escrever o conteúdo do ficheiro nonce “%s†para o fluxo:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "O endereço indicado está vazio" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Impossível criar um canal de mensagem quando o AT_SECURE está configurado" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Impossível criar um canal de mensagem sem um id de máquina: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Não foi possível lançar automaticamente o D-Bus sem o $DISPLAY X-11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Erro ao criar uma linha de comando “%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Impossível determinar o endereço do canal de sessão (não implementado para " +"este SO)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Impossível determinar o endereço de canal a partir da variável de sessão " +"DBUS_STARTER_BUS_TYPE — valor “%s†desconhecido" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Impossível determinar o endereço do canal porque a variável de ambiente " +"DBUS_STARTER_BUS_TYPE não está definida" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipo de canal %d desconhecido" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Falta de conteúdo inesperada ao tentar ler uma linha" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Falta de conteúdo inesperada ao tentar ler uma linha (em segurança)" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Esgotados todos os mecanismos de autenticação disponíveis (tentados: %s) " +"(disponíveis: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" +"As IDs dos utilizadores devem ser as mesmas para os pares e para o servidor" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Cancelado via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Erro ao obter informação da diretório “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"As permissões da diretório “%s†estão mal formadas. Esperado o modo 0700, " +"obtido 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Erro ao criar o diretório “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operação não suportada" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Erro ao abrir o chaveiro “%s†para leitura: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Linha %d do chaveiro em “%s†com o conteúdo “%s†está mal formada" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"O primeiro bloco da linha %d do chaveiro em “%s†com o conteúdo “%s†está " +"mal formado" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"O segundo bloco da linha %d do chaveiro em “%s†com o conteúdo “%s†está mal " +"formado" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Impossível encontrar a cookie com o id %d no chaveiro em “%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Erro ao criar o ficheiro de acesso exclusivo “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Erro ao eliminar o ficheiro de acesso exclusivo “%s†abandonado: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Erro ao fechar o ficheiro de acesso exclusivo “%s†(não ligado): %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Erro ao desfazer a ligação do ficheiro de acesso exclusivo “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Erro ao abrir o chaveiro “%s†para escrita: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(adicionalmente, também falhou a libertação para “%sâ€: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "A ligação está fechada" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Foi atingido o tempo de expiração" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Foram encontrados parâmetros não suportados ao construir a ligação de cliente" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Não existe o ambiente “org.freedesktop.DBus.Properties†no objeto no caminho " +"%s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Não existe a propriedade “%sâ€" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "A propriedade “%s†não pode ser lida" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "A propriedade “%s†não pode ser escrita" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Erro ao definir a propriedade “%sâ€: esperado o tipo “%sâ€, obtido o “%sâ€" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Não existe o ambiente “%sâ€" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Não existe o ambiente “%s†no objeto no caminho %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Não existe o método “%sâ€" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Tipo de mensagem, “%sâ€, não corresponde ao tipo “%s†esperado" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Já existe um objeto exportado para o ambiente %s em %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Impossível obter propriedade %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Impossível definir propriedade %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "O método “%s†devolveu o tipo “%sâ€, mas era esperado “%sâ€" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "O método “%s†no ambiente “%s†com a assinatura “%s†não existe" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Já existe uma subárvore exportada para %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "O objeto não existe no caminho \"%s\"" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "tipo é INVÃLIDO" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Mensagem METHOD_CALL: falta campo de cabeçalho PATH ou MEMBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Mensagem ETHOD_RETURN: falta campo de cabeçalho REPLY_SERIAL" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Mensagem ERROR: Falta campo de cabeçalho REPLY_SERIAL ou ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Mensagem SIGNAL: falta campo de cabeçalho PATH, INTERFACE ou MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Mensagem SIGNAL: o campo de cabeçalho PATH está a utilizar o valor " +"reservado /org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Mensagem SIGNAL: o campo de cabeçalho INTERFACE está a utilizar o valor " +"reservado org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Tentativa de ler %lu byte mas só obtido %lu" +msgstr[1] "Tentativa de ler %lu bytes mas só obtidos %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Esperado o byte NUL após a cadeia “%s†mas encontrado o byte %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Esperada uma cadeia UTF-8 válida mas encontrados bytes inválidos no desvio " +"de bytes %d (comprimento da cadeia é %d). A cadeia UTF-8 válida até esse " +"ponto era “%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Origem do valor muito antiga" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Valor processado “%s†não é um caminho de objeto D-Bus válido" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Valor processado “%s†não é uma assinatura D-Bus válida" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Encontrado um vetor de %u byte de comprimento. Tamanho máximo é 2<<26 bytes " +"(64MiB)." +msgstr[1] "" +"Encontrado um vetor de %u bytes de comprimento. Tamanho máximo é 2<<26 bytes " +"(64MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Encontrado um vetor de tipo \"a%c\", esperado um comprimento múltiplo de %u " +"bytes, obtidos %u bytes de comprimento" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Estruturas vazias (tuples) não são permitidas no D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Valor processado “%s†para variante não é uma assinatura D-Bus válida" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Erro ao remover serialização GVariant com a cadeia de tipo “%s†do formato " +"de ligação D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valor de \"endianness\" inválido. Esperado 0x6c (“lâ€) ou 0x42 (“Bâ€) mas " +"obtido o valor 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Versão principal de protocolo inválida. Esperada 1 mas obtida %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Assinatura de cabeçalho encontrada, mas não do tipo assinatura" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Assinatura de cabeçalho com a assinatura “%s†encontrada, mas o corpo da " +"mensagem está vazio" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Valor processado “%s†não é uma assinatura D-Bus válida (para corpo)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Nenhum cabeçalho de assinatura na mensagem mas o corpo da mensagem tem %u " +"byte" +msgstr[1] "" +"Nenhum cabeçalho de assinatura na mensagem mas o corpo da mensagem tem %u " +"bytes" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Impossível remover serialização da mensagem: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Erro ao serializar GVariant com a cadeia de tipo “%s†para o formato de " +"ligação D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Número de descritores de ficheiro na mensagem (%d) difere do campo no " +"cabeçalho (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Impossível serializar a mensagem: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"O corpo da mensagem tem a assinatura “%s†mas não existe a assinatura de " +"cabeçalho" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"O corpo da mensagem tem o tipo de assinatura “%sâ€, mas a assinatura no campo " +"de cabeçalho é “%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"O corpo da mensagem está vazio mas a assinatura no campo de cabeçalho é " +"“(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Resposta de erro com corpo do tipo “%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Resposta de erro com corpo vazio" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(insira um qualquer carácter para fechar esta janela)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" +"Dbus de sessão não se encontra em execução e o início automático falhou" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Impossível obter o perfil de equipamento: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Incapaz de carregar %s ou %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Erro ao invocar StartServiceByName para %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Resposta %d inesperada do método StartServiceByName(“%sâ€)" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Impossível invocar o método; o proxy é para o nome conhecido %s sem um dono " +"e o proxy foi construído com o parâmetro G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Não é suportado nome de espaço abstrato" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Impossível especificar ficheiro nonce ao criar um servidor" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Erro ao escrever no ficheiro nonce em “%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "A cadeia “%s†não é um GUID D-Bus válido" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Impossível ouvir no transporte não suportado “%sâ€" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Comandos:\n" +" help Mostra esta informação\n" +" introspect Realiza introspeção de um objeto remoto\n" +" monitor Monitoriza um objeto remoto\n" +" call Invoca um método num objeto remoto\n" +" emit Emite um sinal\n" +" wait Espera por um nome de canal aparecer \n" +"\n" +"Utilize \"%s COMMAND --help\" para obter ajuda sobre cada comando.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Erro: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Erro ao processar XML de introspeção: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Erro: %s não é um nome válido\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Erro: %s não é um caminho de objeto válido\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Ligar ao bus de sistema" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Ligar ao bus de sessão" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Ligar ao endereço D-Bus especificado" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opções de destino da ligação:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opções que especificam o destino da ligação" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nenhum destino de ligação especificado" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Múltiplos destinos de ligação especificados" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Aviso: De acordo com os dados de introspeção, o ambiente “%s†não existe\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Aviso: De acordo com os dados de introspeção, o método “%s†não existe no " +"ambiente “%sâ€\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Destino opcional para o sinal (nome único)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Caminho do objeto sobre o qual emitir sinal" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Nome do sinal e do ambiente" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emitir um sinal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Erro ao ligar: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Erro: %s não é um nome único de canal (bus) válido.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Erro: caminho de objeto não está especificado\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Erro: nome do sinal não é especificado\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Erro: nome do sinal “%s†é inválido\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Erro: %s não é um nome de ambiente válido\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Erro: %s não é um nome de membro válido\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Erro ao processar o parâmetro %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Erro ao despejar a ligação: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nome de destino no qual invocar o método" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Caminho do objeto no qual invocar o método" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Método e nome de ambiente" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Tempo limite em segundos" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Permitir autorização interativa" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Invocar um método num objeto remoto." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Erro: Destino não está especificado\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Erro: %s não é um nome de canal válido\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Erro: nome de método não é especificado\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Erro: nome de método “%s†é inválido\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Erro ao processar o parâmetro %d do tipo “%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Erro ao adicionar manipulador: %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nome do destino sobre o qual realizar a introspeção" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Caminho do objeto sobre o qual realizar a introspeção" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Imprimir XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Realizar introspeção dos sub processos" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Imprimir só propriedades" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Realizar a introspeção de um objeto remoto." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nome do destino a monitorizar" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Caminho do objeto a monitorizar" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitorizar um objeto remoto." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Erro: impossível monitorizar um ligação non-message-bus\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Serviço a ativar enquanto espera por um outro (nome conhecido)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Compasso de espera antes de sair com erro (segundos); 0 para nenhum " +"(predefinição)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPÇÃO…] BUS-NAME" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Esperar por um nome de canal aparecer." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Erro: um serviço para ser ativado precisa ser especificado.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Erro: um serviço a ser esperado precisa ser especificado\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Erro: demasiados argumentos\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Erro: %s não é um nome de canal válido\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Não autorizado a alterar as definições de depuração" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Sem nome" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Ficheiro do ambiente de trabalho não especificou campo Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Impossível encontrar o terminal necessário à aplicação" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Impossível criar a pasta de configurações de utilizador da aplicação %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Impossível criar a pasta de configurações MIME do utilizador %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Informação da aplicação não possui um identificador" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Impossível criar ficheiro do ambiente de trabalho do utilizador %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Definição personalizada de %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "a unidade não implementa a ejeção" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "a unidade não implementa eject ou eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "a unidade não implementa a verificação de existência de suportes" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "a unidade não implementa a reprodução" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "a unidade não implementa a paragem" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "O suporte TLS não implementa a recuperação de fomatos TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "O suporte TLS não está disponível" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "O suporte DTLS não está disponível" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Impossível manipular a versão %d da codificação GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Número de blocos (%d) mal-formado na codificação GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Impossível manipular a versão %d da codificação GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Número de blocos (%d) mal-formado na codificação GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Esperado um GEmblem para o GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Montagem contida não existe" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Impossível copiar sobre um diretório" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Impossível copiar uma pasta sobre uma pasta" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Ficheiro de destino já existe" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Impossível copiar diretório recursivamente" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Dividir ficheiros não é suportado" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Erro ao dividir o ficheiro: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Copiar (reflink/clonar) entre montados não é suportado" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Copiar (reflink/clonar) não é suportado ou é inválido" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Copiar (reflink/clonar) não é suportado ou falhou" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Impossível copiar ficheiro especial" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Dado um valor de ligação simbólica inválida" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Ligações simbólicas não são suportadas" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Não existe suporte para o lixo" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Nomes de ficheiros não podem conter “%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "unidade não implementa a montagem" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Não existe nenhuma aplicação registada para gerir este ficheiro" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerador está fechado" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Enumerador de ficheiro tem uma operação por terminar" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Enumerador de ficheiro já está fechado" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Impossível manipular a versão %d da codificação GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Dados de entrada mal-formados para o GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Fluxo não suporta query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Fluxo não suporta procura" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Fluxo de entrada não permite truncar" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Fluxo não suporta truncar" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Nome de máquina inválido" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Resposta do proxy HTTP incorreta" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Ligação de proxy HTTP não permitida" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Autenticação no proxy HTTP falhou" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Autenticação no proxy HTTP requerida" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Ligação de proxy HTTP falhou: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Resposta de proxy HTTP demasiado grande" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "O servidor proxy HTTP fechou a ligação inesperadamente." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Número incorreto de blocos (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Nenhum tipo para o nome da classe %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "O tipo %s não implementa o ambiente GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "O tipo %s não possui uma classe" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Número de versão mal-formado: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "O tipo %s não implementa from_tokens() no ambiente GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Impossível manipular a versão especificada da codificação do ícone" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nenhum endereço especificado" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Comprimento %u é demasiado extenso para um endereço" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Endereço tem bits definidos para lá do comprimento do prefixo" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Impossível processar “%s†como a máscara de endereço IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Espaço insuficiente para o endereço do socket" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Endereço de socket não suportado" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Fluxo de entrada não implementa a leitura" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Fluxo tem uma operação por terminar" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copiar com ficheiro" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Manter com o ficheiro depois de mover" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“versão†não recebe argumentos" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Utilização:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Imprimir informação de versão e sair." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Comandos:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatenar ficheiros para a saída predefinida" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copiar um ou mais ficheiros" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Mostrar informação sobre as localizações" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Iniciar uma aplicação a partir de um ficheiro desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Lista de conteúdos das localizações" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Obter ou definir o manuseador mimetype" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Criar diretórios" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitorizar ficheiros e diretórios por mudanças" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montar ou desmontar as localizações" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Mover um ou mais ficheiros" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Abrir ficheiros com a aplicação pré-definida" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Renomear um ficheiro" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Apagar um ou mais ficheiros" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Ler da entrada predefinida e guardar" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Definir um atributo de ficheiro" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Mover ficheiros ou diretórios para o lixo" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Listar os conteúdos das localizações numa árvore" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Utilizar %s para obter ajuda detalhada.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Erro ao escrever no stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCALIZAÇÃO" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatenar ficheiros e imprimir para a saída predefinida." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat funciona como uma utilidade tradicional de cat, mas \n" +"utilizando localizações GIO em vez de ficheiros locais: por exemplo\n" +"pode utilizar smb://server/resource/ficheiro.txt como localização." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nenhuma localização fornecida" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nenhum diretório destino" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Mostrar progresso" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Pedir confirmação antes de sobrescrever" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Preservar todos os atributos" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Criar cópia de segurança dos ficheiros existentes do destino" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nunca seguir ligações simbólicas" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Usar permissões predefinidas para o destino" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Transferido %s de %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "FONTE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINO" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copiar um ou mais ficheiros da FONTE para o DESTINO." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy é similar ao tradicional utilitário cp, mas usa localizações \n" +"GIO ao invés de ficheiros locais: a exemplo, pode usar algo feito \n" +"smb://server/resource/file.txt como localização." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Destino %s\" não é um diretório" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: sobrescrever“%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Listar atributos que podem ser escritos" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Obter informação do sistema de ficheiros" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Os atributos a obter" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTOS" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Não seguir ligações simbólicas" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributos:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nome de apresentação: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "nome de edição: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nome: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipo: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "tamanho: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "escondido\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "caminho local: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "montagem unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atributos definíveis:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Espaço de nomes de atributos graváveis:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Mostrar informação sobre as localizações." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info funciona como uma utilidade tradicional de ls, mas \n" +"utilizando localizações GIO em vez de ficheiros locais: por exemplo\n" +"pode utilizar smb://server/resource/file.txt como localização. \n" +"Os atributos de ficheiros podem ser especificados com seus nomes GIO,\n" +"exp. standard::icon, ou só o espaço de nome, exp. unix, ou com “*â€,\n" +"que corresponde a todos os atributos" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-FILE [FILE-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Iniciar uma aplicação a partir de um ficheiro desktop, passando-lhe " +"argumentos opcionais de nome de ficheiro." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nenhum ficheiro desktop dado" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "O comando de lançamento não é atualmente suportado nesta plataforma" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Incapaz de carregar '%s': %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Incapaz de carregar informação de aplicação para '%s'" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Incapaz de lançar a aplicação '%s': %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Mostrar ficheiros escondidos" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Utilizar um formato de lista longa" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Imprimir os nomes de apresentação" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Imprimir URIs completos" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Lista de conteúdos das localizações." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list funciona como uma utilidade tradicional de ls, mas\n" +"utilizando localizações GIO em vez de ficheiros locais: a\n" +"exemplo, pode usar smb://server/resource/file.txt como\n" +"localização. Os atributos de ficheiro podem ser especificados\n" +"com seus nomes GIO,ex. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "MANUSEADOR" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Obter ou definir o manuseador do mimetype." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Se nenhum manuseador for fornecido, listar as aplicações registadas e\n" +" recomendadas para o mimetype. Se o manuseador for fornecido, é \n" +"definido como o manuseador padrão para o mimetype." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Tem de especificar apenas um mimetype, e possivelmente um manuseador" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Nenhuma aplicação predefinida para “%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplicação predefinida para “%sâ€:%s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplicações registadas:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nenhuma aplicação registada\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplicações recomendadas:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Nenhuma aplicação recomendada\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Falha ao ler informação do gestor “%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Falha ao definir “%s†como gestor predefinido para “%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Criar diretórios pai" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Criar diretórios." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir funciona como o utilitário tradicional mkdir, mas usando\n" +"localizações GIO mas utilizando localizações GIO em vez de ficheiros\n" +"locais: a exemplo, pode usar smb://server/resource/mydir como localização." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitorizar um diretório (predefinição: depende do tipo)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitorizar um ficheiro (predefinição: depende do tipo)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Monitorizar um ficheiro diretamente (nota as alterações feitas por via de " +"hardlinks)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitoriza um ficheiro diretamente, mas não reporta as mudanças" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "Reporta as mudanças e renomeia como apenas eventos apagados/criados" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Observar eventos montados" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitorizar ficheiros ou diretórios por alterações." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Montar como montável" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Montar unidade com ficheiro de dispositivo, ou outro identificador" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Desmontar" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Ejetar" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Parar unidade com ficheiro de dispositivo" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DISPOSITIVO" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Desmontar todas as montagens com um dado esquema" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ESQUEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignorar operações de ficheiros pendentes quando desmontar ou ejetar" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Utilizar um utilizador anónimo quando autenticar" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Listar" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitorizar eventos" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Mostrar informação extra" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "O PIM numérico quando desbloquear uma unidade VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montar uma unidade TCRYPT oculta" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montar uma unidade TCRYPT de sistema" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Acesso anónimo negado" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Nenhum volume para o ficheiro de dispositivo" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Nenhum volume para o dado ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montar ou desmontar localizações." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Não usar copiar e eliminar por omissão" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Mover um ou mais ficheiros de FONTE para DESTINO." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move funciona como o utilitário tradicional mv, mas usando\n" +"localizações GIO mas utilizando localizações GIO em vez de ficheiros\n" +"locais: a exemplo, pode usar smb://server/resource/file.txt como localização" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Alvo %s não é um diretório" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Abrir ficheiros com a aplicação predefinida\n" +"é registada para manusear ficheiros deste tipo." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignorar ficheiros inexistentes, sem confirmação" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Apagar ficheiros fornecidos." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Renomear um ficheiro." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Argumento em falta" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Demasiados argumentos" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Mudança de nome bem sucedida. Novo uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Só criar se não existir" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Acrescentar ao final do ficheiro" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Quando criar, restringir acesso ao utilizador atual" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Quando substituir, substituir como se o destino não existisse" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Imprimir novo etag no final" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "O etag do ficheiro a ser sobrescrito" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Erro ao ler da entrada predefinida" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag não está disponível\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Ler da entrada predefinida e guardar no DESTINO." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nenhum destino fornecido" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Tipo do atributo" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPO" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUTO" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALOR" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Definir um atributo de ficheiro da LOCALIZAÇÃO." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Nenhum localização especificada" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Nenhum atributo especificado" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Valor não especificado" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Tipo de atributo inválido “%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Esvaziar lixo" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Listar os ficheiros no lixo com as suas localizações originais" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restaurar um ficheiro do lixo até à sua localização original (possivelmente " +"recriando o diretório)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Incapaz de encontrar o caminho original" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Incapaz de recriar a localização original: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Incapaz de mover o ficheiro para a sua localização original: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Mover/Restaurar ficheiros e diretórios para o lixo." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Nota: para o comutador --restore, se a localização original do ficheiro " +"eliminado \n" +"já existe, não será substituído a menos que --force seja definida." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "O local dado não começa com o trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Seguir ligações simbólicos, montagens e atalhos" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Listar conteúdos de diretórios num formato tipo árvore." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elemento <%s> não é permitido dentro de <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elemento <%s> não é permitido no nível de topo" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "O ficheiro %s surge várias vezes no recurso" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Falha ao localizar “%s†em qualquer diretório de origem" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Falha ao localizar “%s†na diretório atual" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Opção de processamento “%s†desconhecida" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"pré-processamento %s requisitado, mas %s é indefinido, e %s não está no PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Erro ao ler o ficheiro %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Erro ao comprimir o ficheiro %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "não pode surgir texto dentro de <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Mostrar a versão da aplicação e sair" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nome do ficheiro de saída" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"O diretório de onde ler os ficheiros referenciados no FICHEIRO do " +"(predefinição: diretório atual)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "PASTA" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Gerar o resultado no formato selecionado pela extensão do nome do ficheiro " +"de saída" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Gerar o cabeçalho de código" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Gerar o código-fonte utilizado para ligar o ficheiro de recurso ao seu código" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Gerar lista de dependências" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nome do ficheiro de dependência a gerar" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Incluir alvos falsos no ficheiro de dependência gerado" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Não criar e registar um recurso automaticamente" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Não exportar funções; declará-las G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Não imbuir dados de recurso num ficheiro C; assuma-o ligado externamente" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Nome do identificador C utilizado no código fonte gerado" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "O compilador C de destino (padrão: a variável de ambiente CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compilar a especificação de um recurso num ficheiro de recursos.\n" +"Ficheiros de especificação de recursos têm de ter a extensão .gresource." +"xml,\n" +"e o ficheiro de recurso tem a extensão .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Deverá indicar apenas um nome de ficheiro\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "nome deve ter um mínimo de 2 caracteres" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Valor numérico inválido" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "valor=“%s†já especificado" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "valores de parâmetros devem ter ao menos 1 bit definido" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> deve conter ao menos um " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> não está contido na região especificada" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> não é um membro válido do tipo enumerado especificado" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> contém cadeias não inclusas no tipo de parâmetros especificados" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> contém uma cadeia não inclusa em " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " já especificado para esta chave" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " não permitido para chaves do tipo “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " o mínimo especificado é maior que o máximo" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categoria l10n não suportada: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "o l10n requisitou, mas nenhum domínio gettext foi dado" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "contexto de tradução dado a um valor sem l10n ativado" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Falha ao processar o valor do tipo “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" não podem ser especificadas a chaves marcadas como tendo um tipo " +"enumerado" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " já especificadas para esta chave" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " não permitidas para chaves do tipo “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " devem conter ao menos uma " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " já especificados para esta chave" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" podem serem especificados só a chaves com tipo enumerada ou " +"parâmetro ou após " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr " dado quando “%s†já é um membro do tipo enumerado" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" dado quando já foi especificada" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "alcunha alvo “%s†não é do tipo enumerada" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "alcunha alvo “%s†não está inclusa em " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " devem conter ao menos uma " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Não são permitidos nomes vazios" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Nome “%s†inválido: nomes têm de começar com uma letra minúscula" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nome “%s†inválido: carácter “%c†inválido; apenas são permitidas letras " +"minúsculas, números e um traço (“-â€)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Nome “%s†inválido: não são permitidos dois traços (“--â€) consecutivos" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Nome “%s†inválido: o último carácter não pode ser um traço (“-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nome “%s†inválido: o tamanho máximo é 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Não é possível adicionar chaves a um esquema de “lista-deâ€" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" sobrepõe-se a no ; utilize " +" para alterar o valor" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Exatamente “typeâ€, “enum†ou “flags†tem de ser especificado como um " +"atributo de " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id=“%sâ€> (ainda) não definido." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Cadeia de tipo GVariante “%s†inválida" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " especificado mas o esquema não estende nada" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Nenhum a sobrepor" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " estende-se a um esquema “%s†ainda não existente" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " é uma lista do esquema “%s†que ainda não existe" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Não é possível ser uma lista de um esquema com um caminho" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Impossível estender um esquema com um caminho" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" é uma lista, que estende o que não é uma " +"lista" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" estende mas “%s†" +"não estende “%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Um caminho, se indicado, tem de começar e terminar com uma barra" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "O caminho de uma lista tem de terminar com “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Aviso: o esquema “%s†tem um caminho “%sâ€. Caminhos começando com “/apps/â€, " +"“/desktop/†ou “/system/†estão obsoletos." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id=“%sâ€> já especificado" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Elemento <%s> não é permitido dentro de <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Elemento <%s> não é permitido no nível de topo" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Elemento é requerido em " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Não pode surgir texto dentro de <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Aviso: referência unificada a " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "Foi especificado --strict; a terminar." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Todo este ficheiro foi ignorado." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "A ignorar este ficheiro." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Nenhuma chave “%s†no esquema “%s†tal como especificado no ficheiro de " +"sobreposição “%sâ€; a ignorar sobreposição desta chave." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Nenhuma chave “%s†no esquema “%s†tal como especificado no ficheiro de " +"sobreposição “%s†e --strict foi definido; a terminar." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Impossível fornecer sobreposições per-desktop para chaves localizadas “%s†" +"no esquema “%s†(ficheiro de sobreposição “%sâ€); a ignorar sobreposição para " +"esta chave." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Impossível fornecer sobreposições per-desktop para chaves localizadas “%s†" +"no esquema “%s†(ficheiro de sobreposição “%sâ€) e --strict foi definido; a " +"terminar." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Erro ao processar a chave “%s†no esquema “%s†tal como especificado no " +"ficheiro de sobreposição “%sâ€: %s. A ignorar sobreposição para esta chave." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Erro ao processar a chave “%s†no esquema “%s†tal como especificado no " +"ficheiro de sobreposição “%sâ€: %s. --strict foi definido; a terminar." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Sobreposição para a chave “%s†no esquema “%s†no ficheiro de sobreposição " +"“%s†está fora do intervalo indicado no esquema; a ignorar sobreposição " +"desta chave." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Sobreposição para a chave “%s†no esquema “%s†no ficheiro de sobreposição " +"“%s†está fora do intervalo indicado no esquema e --strict foi definido; a " +"terminar." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Sobreposição para a chave “%s†no esquema “%s†no ficheiro de sobreposição " +"“%s†não pertence à lista de opções válidas; a ignorar sobreposição desta " +"chave." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Sobreposição para a chave “%s†no esquema “%s†no ficheiro de sobreposição " +"“%s†não pertence à lista de opções válidas e --strict foi definido; a " +"terminar." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Onde armazenar o ficheiro gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Abortar em qualquer erro nos esquemas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Não escrever o ficheiro gschemas.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Não forçar restrições de nomes de chaves" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compilar todos os ficheiros de esquema GSettings numa cache de esquemas.\n" +"Ficheiros de esquema têm de ter a extensão .gschema.xml,\n" +"e o ficheiro de cache é designado gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Deverá indicar apenas um nome de pasta" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nenhum ficheiro de esquema encontrado: nada a fazer." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Nenhum ficheiro de esquema encontrado: removido o ficheiro de resultado " +"existente." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Nome de ficheiro %s inválido" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Erro ao obter a informação do sistema de ficheiros para %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Montagem que contém o ficheiro %s não encontrada" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Impossível renomear o diretório raiz" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Erro ao renomear o ficheiro %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Impossível renomear o ficheiro, o nome já existe" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nome de ficheiro inválido" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Erro ao abrir o ficheiro %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Erro ao remover o ficheiro %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Erro ao enviar o ficheiro %s para o lixo: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Impossível criar o diretório de lixo %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Impossível encontrar o diretório de topo para o lixo %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Impossível enviar para o lixo montagens internas do sistema" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Impossível encontrar ou criar o diretório de lixo %s para o lixo %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Impossível criar o ficheiro de informação do lixo para %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Impossível enviar o ficheiro %s para o lixo através dos limites do sistema " +"de ficheiros" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Impossível enviar o ficheiro %s para o lixo: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Impossível enviar o ficheiro %s para o lixo" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Erro ao criar o diretório %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "O sistema de ficheiros não suporta ligações simbólicas" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Erro ao criar ligação simbólica %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Erro ao mover o ficheiro %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Impossível mover uma pasta sobre uma pasta" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Falha ao criar o ficheiro de cópia de segurança" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Erro ao remover o ficheiro de destino: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Não é suportado mover entre montados" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Impossível determinar a utilização de disco de %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Valor do atributo tem de ser não-NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tipo de atributo inválido (esperada uma cadeia)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nome de atributo extendido inválido" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Erro ao definir o atributo extendido “%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codificação inválida)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Erro ao obter informação para o ficheiro “%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Erro ao obter informação sobre o descritor do ficheiro: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tipo de atributo inválido (esperado um uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tipo de atributo inválido (esperado um uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Tipo de atributo inválido (esperado uma cadeia byte)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Impossível definir permissões em ligações simbólicas" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Erro ao definir as permissões: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Erro ao definir o dono: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "ligação simbólica tem de ser não-NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Erro ao definir a ligação simbólica: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Erro ao definir a ligação simbólica: ficheiro não é uma ligação simbólica" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Nanosegundos %d extras para a data/hora UNIX %lld são negativos" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Nanosegundos %d extras para a data/hora UNIX %lld atinge 1 segundo" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "Data/hora UNIX %lld não cabem em 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "Data/hora UNIX %lld estão fora do alcance suportado pelo Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Nome de ficheiro “%s†não pode ser convertido para UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Ficheiro “%s†não pode ser aberto: erro do Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Erro ao definir ou modificar a hora de acesso para o ficheiro “%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Erro ao definir a hora de modificação ou acesso: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "O contexto SELinux tem de ser não-NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "O SELinux não está ativo neste sistema" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Erro ao definir o contexto SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Não é suportada a definição do atributo %s" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Erro ao ler do ficheiro: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Erro ao fechar o ficheiro: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Erro ao procurar no ficheiro: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Impossível encontrar tipo de monitor predefinido de ficheiro local" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Erro ao escrever no ficheiro: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Erro ao remover o atalho para a cópia de segurança antiga: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Erro ao criar a cópia da cópia de segurança: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Erro ao renomear ficheiro temporário: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Erro ao truncar ficheiro: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Erro ao abrir o ficheiro “%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Ficheiro de destino é uma pasta" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "O ficheiro de destino não é um ficheiro comum" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "O ficheiro foi alterado externamente" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Erro ao remover o ficheiro antigo: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Fornecido um GSeekType inválido" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Pedido de procura inválido" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Impossível truncar um GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Fluxo de saída de memória não é redimensionável" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Falha ao redimensionar fluxo de saída de memória" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Quantidade de memória necessária para processar a escrita é maior do que o " +"espaço de endereçamento disponível" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Pedida uma procura para antes do início do fluxo" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Pedida uma procura para depois do final do fluxo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "dispositivo montado não implementa “desmontarâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "dispositivo montado não implementa “ejetarâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"dispositivo montado não implementa “desmontar†ou “desmontar_com_operacaoâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "dispositivo montado não implementa “eject†ou “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "dispositivo montado não implementa “remontarâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "dispositivo montado não implementa deteção do tipo de conteúdo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" +"dispositivo montado não implementa deteção síncrona do tipo de conteúdo" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Nome de máquina “%s†contém “[†mas não “]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Rede inacessível" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Servidor inacessível" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Impossível criar o monitor de rede: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Impossível criar o monitor de rede: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Impossível obter o estado da rede: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "Gestor de rede não está em execução" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Versão do gestor de rede demasiado antiga" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Fluxo de saída não implementa a escrita" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Soma dos vetores passados ao %s demasiado longa" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Fluxo de origem já está fechado" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Erro ao resolver “%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s não implementado" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Domínio inválido" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "O recurso em “%s†não existe" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Falha ao descomprimir o recurso em “%sâ€" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "O recurso em “%s†não é um diretório" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Fluxo de entrada não implementa procura" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Lista secções que contêm recursos num FICHEIRO elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Lista recursos\n" +"Se for especificada uma SECÇÃO, apenas listar recursos nesta secção\n" +"Se for especificado uma LOCALIZAÇÃO, apenas listar recursos que coincidam" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FICHEIRO [LOCALIZAÇÃO]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECÇÃO" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Listar recursos com detalhes\n" +"Se for especificada uma SECÇÃO, apenas listar recursos nesta secção\n" +"Se for especificado uma LOCALIZAÇÃO, apenas listar recursos que coincidam\n" +"Detalhes incluem a secção, tamanho e compressão" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extrair um ficheiro de recurso para o terminal" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "LOCALIZAÇÃO FICHEIRO" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilização:\n" +" gresource [--section SECÇÃO] COMANDO [ARGS...]\n" +"\n" +"Comandos:\n" +" help Mostra esta informação\n" +" sections Lista secções de recursos\n" +" list Lista recursos\n" +" details Lista recursos com detalhes\n" +" extract Extrai um recurso\n" +"\n" +"Utilize \"gresource help COMANDO\" para obter ajuda detalhada.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilização:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECÇÃO Um nome (opcional) de secção elf\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMANDO O comando (opcional) a ser explicado\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" +" FICHEIRO Um ficheiro elf (um binário ou uma biblioteca partilhada)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FICHEIRO Um ficheiro elf (um binário ou uma biblioteca partilhada)\n" +" ou um ficheiro de recurso compilado\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[LOCALIZAÇÃO]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" +" LOCALIZAÇÃO Uma localização (opcional) de recurso (pode ser parcial)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "LOCALIZAÇÃO" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " LOCALIZAÇÃO Uma localização de recurso\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Não existe o esquema “%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "O esquema “%s†não é realocável (não pode ser especificado caminho)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "O esquema “%s†é realocável (tem de ser especificado o caminho)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Indicado um caminho vazio.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "O caminho tem de começar com uma barra (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "O caminho tem de terminar com uma barra (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "O caminho não pode conter duas barras adjacentes (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "O valor especificado encontra-se fora do intervalo válido\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "O valor da chave não pode ser escrito\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Listar os esquemas instalados (não-realocáveis)" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Listar os esquemas instalados realocáveis" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Listar as chaves no ESQUEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "ESQUEMA[:LOCALIZAÇÃO]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Listar os sub processos de ESQUEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Listar as chaves e valores, recursivamente\n" +"Se não for indicado um ESQUEMA, listar todas as chaves\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESQUEMA[:LOCALIZAÇÃO]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Obter o valor da CHAVE" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESQUEMA[:LOCALIZAÇÃO] CHAVE" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Consultar o intervalo de valores válidos para a CHAVE" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Consultar o descritor para a CHAVE" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Definir o valor da CHAVE com o VALOR" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESQUEMA[:LOCALIZAÇÃO] CHAVE VALOR" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Repor o valor predefinido de CHAVE" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Repor todas as chaves no ESQUEMA para os seus valores predefinidos" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Verificar se é possível definir o valor de CHAVE" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitorizar a ocorrência de alterações da CHAVE.\n" +"Se nenhuma chave for especificada, monitorizar todas as chaves do ESQUEMA.\n" +"Utilizar ^C para parar de monitorizar.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESQUEMA[:LOCALIZAÇÃO] [CHAVE]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilização:\n" +" gsettings --version\n" +" gsettings [--schemadir DIRESQUEMAS] COMANDO [ARGS...]\n" +"\n" +"Comandos:\n" +" help Mostra esta informação\n" +" list-schemas Lista os esquemas instalados\n" +" list-relocatable-schemas Lista os esquemas realocáveis\n" +" list-keys Lista as chaves num esquema\n" +" list-children Lista os sub processos de um esquema\n" +" list-recursively Lista as chaves e valores, recursivamente\n" +" range Consulta o intervalo de uma chave\n" +" describe Consulta a descrição de um chave\n" +" get Obtém o valor de uma chave\n" +" set Define o valor de uma chave\n" +" reset Repõe o valor predefinido de uma chave\n" +" reset-recursively Repor todos os valores de um esquema\n" +" writable Verifica se é possível alterar a chave\n" +" monitor Monitoriza por alterações\n" +"\n" +"Utilize \"gsettings help COMANDO\" para obter ajuda detalhada.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilização:\n" +" gsettings [--schemadir DIRESQUEMAS] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " DIRESQUEMAS Um pasta onde procurar por esquemas adicionais\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" ESQUEMA O nome do esquema\n" +" LOCALIZAÇÃO A localização, para esquemas realocáveis\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " CHAVE A chave (opcional) dentro do esquema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " CHAVE A chave dentro do esquema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALOR O valor a definir\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Impossível ler esquemas de %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nenhum ficheiro de esquema instalado\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Indicado um nome de esquema vazio\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Não existe a chave “%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Socket inválido, não inicializado" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Socket inválido, a inicialização falhou devido a: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Socket já está fechado" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Tempo expirou no I/O de socket" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "a criar o GSocket do fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Impossível criar socket: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Foi especificada uma família desconhecida" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Foi especificado um protocolo desconhecido" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Impossível utilizar operações datagram em sockets não datagram." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Impossível utilizar operações datagram num socket com um tempo de expiração " +"definido." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "impossível obter o endereço local: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "impossível obter o endereço remoto: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "impossível escutar: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Erro ao ligar-se ao endereço: %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Erro ao juntar-se a um grupo multicast: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Erro ao sair do grupo multicast: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Suporte indisponível para multicast específico da origem" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Família de socket não suportada" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "fonte-específica não é um endereço IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Nome de ambiente demasiado extenso" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Ambiente não encontrado: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Suporte indisponível para difusão de fonte-específica IPv4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Suporte indisponível para difusão de fonte-específica IPv6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Erro ao aceitar a ligação: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Ligação em curso" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Impossível obter o erro pendente: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Erro ao receber os dados: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Erro ao enviar os dados: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Impossível desligar o socket: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Erro ao fechar o socket: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "A aguardar pela condição do socket: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Incapaz de enviar a mensagem: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vectores de mensagem demasiado grandes" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Erro ao enviar a mensagem: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage não é suportada em Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Erro ao receber a mensagem: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Impossível ler as credenciais do socket: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials não implementado neste SO" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Impossível ligar ao servidor de proxy %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Impossível ligar a %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Impossível ligar: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Não há suporte à realização de proxy sobre ligações não-TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "O protocolo de proxy “%s†não é suportado." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "A escuta já se encontra fechada" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Socket adicionado está fechado" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 não suporta o endereço IPv6 “%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Utilizador demasiado extenso para o protocolo SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Nome de máquina “%s†é demasiado extenso para o protocolo SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "O servidor não é um servidor de proxy SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "A ligação através do servidor SOCKSv4 foi rejeitada" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "O servidor não é um servidor de proxy SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "A proxy SOCKSv5 requer autenticação." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"O SOCKSv5 requer um método de autenticação que não é suportado pelo GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"Utilizador ou palavra-passe demasiado extenso para o protocolo SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Falha na autenticação SOCKSv5 devido a utilizador ou palavra-passe " +"incorretos." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Nome de máquina “%s†demasiado extenso para o protocolo SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "O servidor de proxy SOCKSv5 utiliza um tipo de endereço desconhecido." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Erro interno de servidor de proxy SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Ligação SOCKSv5 não é permitida pelo conjunto de regras." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Máquina inacessível através do servidor SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Rede inacessível através da proxy SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Ligação recusada através da proxy SOCKSv5." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Proxy SOCKSv5 não suporta o comando “connectâ€." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Proxy SOCKSv5 não suporta o tipo de endereço indicado." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Erro de proxy SOCKSv5 desconhecido." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Falha ao criar canal para comunicar com sub processo (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Os canais não são suportados nesta plataforma" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Impossível manipular a versão %d da codificação GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Não foram encontrados endereços válidos" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Erro ao realizar a resolução invertida de “%sâ€: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Erro ao analisar o registo DNS %s: pacote DNS malformado" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Nenhum registo DNS do tipo pedido para “%sâ€" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Temporariamente indisponível para resolver “%sâ€" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Erro ao resolver “%sâ€" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Pacote DNS malformado" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Falha ao analisar a resposta do DNS para \"%s\": " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Nenhuma chave privada codificada PEM encontrada" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Impossível desencriptar a chave privada codificada PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Impossível processar a chave privada codificada PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Nenhum certificado codificado PEM encontrado" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Impossível processar certificado codificado PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "O backend TLS atual não suporta o PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Este GTlsBackend não suporta a criação de certificados PKCS # 11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Esta é a última oportunidade para introduzir corretamente a palavra-passe " +"antes de lhe ser vedado o acesso." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Foram introduzidas várias palavras-passe incorretas e o seu acesso será " +"vedado após falhas adicionais." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "A palavra-passe introduzida está incorreta." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "O envio de FD não é suportado" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Era esperada 1 mensagem de controlo, obtida %d" +msgstr[1] "Era esperada 1 mensagem de controlo, obtidas %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Tipo inesperado de dados basilares" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Esperado um fd, obtido %d\n" +msgstr[1] "Esperado um fd, obtidos %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Recebido um fd inválido" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "A receção FD não é suportada" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Erro ao enviar as credenciais: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Erro ao verificar se SO_PASSCRED está ativo para o socket: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Erro ao ativar SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Deveria ler um único byte para receber credenciais mas foram lidos zero bytes" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Não eram esperadas mensagens de controlo, obtidas %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Erro ao desativar SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Erro ao ler do descritor do ficheiro: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Erro ao fechar o descritor do ficheiro: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Raiz do sistema de ficheiros" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Erro ao escrever no descritor do ficheiro: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Endereços abstratos de sockets de domínio UNIX não são suportados neste " +"sistema" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "unidade não implementa a ejeção" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "unidade não implementa eject ou eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Erro ao ler do manipulador: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Erro ao fechar o manipulador: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Erro ao escrever no manipulador: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Memória livre insuficiente" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Erro interno: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Necessita de mais dados" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Dados comprimidos inválidos" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Endereço onde ouvir" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorado, para compatibilidade com GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Endereço de impressão" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Endereço de impressão em modo de consola" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Executar um serviço dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Argumentos incorretos\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Atributo “%s†inesperado para o elemento “%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atributo “%s†do elemento “%s†não foi encontrado" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Etiqueta “%s†inesperada, esperada a etiqueta “%sâ€" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Etiqueta “%s†inesperada dentro de “%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Data/hora “%s†inválida no ficheiro marcado" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Não foi encontrado nenhum ficheiro de marcador válido nos pastas de dados" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Já existe um marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Não foi encontrado nenhum marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Nenhum tipo MIME definido no marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Nenhum sinal privado definido no marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Nenhum grupo definido no marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Nenhuma aplicação denominada “%s†registou um marcador para “%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Falha ao expandir a linha de execução “%s†com o URI “%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Sequência inválida na conversão da entrada" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Sequência de caracteres parcial no final da origem" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" +"Impossível converter contingência “%s†para conjunto de caracteres “%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Sequência de bytes nula na origem da conversão" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Sequência de bytes nula na saída da conversão" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "O URI “%s†não é um URI absoluto que utiliza o esquema “fileâ€" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "O URI de ficheiro local “%s†não deverá incluir um “#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "O URI “%s†é inválido" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "O nome de máquina do URI “%s†é inválido" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "O URI “%s†contém caracteres mascarados inválidos" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "O nome de caminho “%s†não é um caminho absoluto" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%y/%m/%d" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Janeiro" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Fevereiro" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Março" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Abril" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Maio" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Junho" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Julho" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Agosto" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Setembro" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Outubro" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Novembro" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Dezembro" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Fev" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Abr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ago" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Set" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Out" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dez" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "2ª feira" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "3ª feira" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "4ª feira" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "5ª feira" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "6ª feira" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sábado" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Domingo" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "2ª" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "3ª" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "4ª" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "5ª" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "6ª" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sáb" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Dom" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Janeiro" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Fevereiro" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Março" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "Abril" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Maio" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Junho" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Julho" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "Agosto" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Setembro" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Outubro" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "Novembro" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Dezembro" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Fev" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Abr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ago" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Set" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Out" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dez" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Erro ao abrir o diretório “%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Impossível alocar %lu byte para ler o ficheiro “%sâ€" +msgstr[1] "Impossível alocar %lu bytes para ler o ficheiro “%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Erro ao ler o ficheiro %s: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Ficheiro “%s†é demasiado grande" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Falha ao ler do ficheiro “%sâ€: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Falha ao abrir o ficheiro “%sâ€: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Falha ao obter atributos do ficheiro “%sâ€: falha no fstat(): %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Falha ao abrir o ficheiro “%sâ€: falha no fdopen(): %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Falha ao renomear o ficheiro “%s†para “%sâ€: falha no g_rename(): %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Falha ao escrever o ficheiro “%sâ€: falha no write(): %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Falha ao escrever o ficheiro “%sâ€: falha no fsync(): %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Falha ao criar o ficheiro “%sâ€: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Impossível remover o ficheiro “%s†existente: falha no g_unlink(): %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Modelo “%s†inválido, não deveria conter um “%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Modelo “%s†não contém XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Falha ao ler a ligação simbólica “%sâ€: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Impossível abrir conversor de “%s†para “%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Impossível efetuar uma leitura em bruto em g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Dados residuais não convertidos no buffer de leitura" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Canal termina num carácter parcial" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Impossível efetuar uma leitura em bruto em g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Impossível encontrar um ficheiro de chave válido nas pastas procuradas" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Não é um ficheiro normal" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"O ficheiro de chave contém a linha “%s†que não é um par chave-valor, grupo " +"ou comentário" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nome de grupo inválido: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Ficheiro de chave não começa com um grupo" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nome de chave inválida: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Ficheiro de chave contém uma codificação não suportada “%sâ€" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Ficheiro de chave não possui um grupo “%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Ficheiro de chave não possui a chave “%s†no grupo “%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Ficheiro de chave contém a chave “%s†com o valor “%s†que não é UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "Ficheiro de chaves contém a chave “%s†cujo valor não é interpretável." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Ficheiro de chave contém a chave “%s†no grupo “%s†que tem um valor que não " +"pode ser interpretado." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Chave “%s†no grupo “%s†tem o valor “%s†onde %s era esperado" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Ficheiro de chave contém caracteres mascarados no final da linha" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "" +"Ficheiro de chave contém uma sequência de caracteres mascarados inválida “%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Impossível interpretar o valor “%s†como um numérico." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Valor inteiro “%s†para além do limite permitido" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Impossível interpretar o valor “%s†como um número vírgula flutuante." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Impossível interpretar o valor “%s†como lógico." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Falha ao obter atributos do ficheiro “%s%s%s%sâ€: falha no fstat(): %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Falha ao mapear %s%s%s%s: falha no mmap(): %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Falha ao abrir o ficheiro “%sâ€: falha no open(): %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Erro na linha %d, carácter %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Texto codificado em UTF-8 no nome inválido — “%s†inválido" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†não é um nome válido" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†não é um nome válido: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Erro na linha %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Falha ao processar “%-.*sâ€, que deveria ser um dígito dentro de uma " +"referência de carácter (ê por exemplo) — talvez o dígito seja demasiado " +"grande" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Referência de carácter não termina com um ponto e vírgula; provavelmente foi " +"utilizado um carácter “i comercial†sem intenção de iniciar uma entidade — " +"mascare-o como &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Referência de carácter “%-.*s†não codifica um carácter permitido" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Entidade vazia “&;†avistada; entidades válidas são: & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Nome de entidade “%-.*s†é desconhecido" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entidade não termina com um ponto e vírgula; provavelmente foi utilizado um " +"carácter “e comercial†sem intenção de iniciar uma entidade — mascare-o como " +"&" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Documento tem de começar com um elemento (ex. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%s†não é um carácter válido após um carácter “<â€; pode não iniciar um nome " +"de elemento" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Carácter estranho “%sâ€, era esperado um carácter “>†para terminar a " +"etiqueta de elemento vazio “%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Demasiados atributos no elemento “%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Carácter estranho “%sâ€, era esperado um “=†após o nome do atributo “%s†do " +"elemento “%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Carácter estranho “%sâ€, era esperado um carácter “>†ou “/†para terminar a " +"etiqueta inicial do elemento “%sâ€, ou opcionalmente um atributo; talvez " +"tenha sido utilizado um carácter inválido no nome de um atributo" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Carácter estranho “%sâ€, era esperada uma abertura de aspa após o sinal de " +"igual ao atribuir valor ao atributo “%s†do elemento “%sâ€" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%s†não é um carácter válido após o nome do elemento de fecho “%sâ€; o " +"carácter permitido é “>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Elemento “%s†foi fechado, nenhum elemento está atualmente aberto" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Elemento “%s†foi fechado, mas o elemento atualmente aberto é “%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Documento estava vazio ou só continha espaços" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Documento terminou inesperadamente logo após um carácter menor que “<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Documento terminou inesperadamente com elementos ainda abertos — “%s†foi o " +"último elemento aberto" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Documento terminou inesperadamente, era esperado um maior que \">\" para " +"terminar a etiqueta <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Documento terminou inesperadamente dentro do nome de um elemento" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Documento terminou inesperadamente dentro do nome de um atributo" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Documento terminou inesperadamente dentro da etiqueta de abertura de um " +"elemento." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Documento terminou inesperadamente após o sinal de igual posterior a um nome " +"de atributo; nenhum valor de atributo" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Documento terminou inesperadamente dentro do valor de um atributo" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Documento terminou inesperadamente dentro da etiqueta de fecho do elemento " +"“%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Documento terminou inesperadamente dentro da etiqueta de fecho do elemento " +"para um elemento não aberto" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Documento terminou inesperadamente dentro de um comentário ou instrução de " +"processamento" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPÇÃO...]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opções de ajuda:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Mostrar as opções de ajuda" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Mostrar todas as opções de ajuda" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opções da aplicação:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opções:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Impossível processar o valor inteiro “%s†para %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Valor inteiro “%s†para %s para lá do limite permitido" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Impossível processar o valor de dupla precisão “%s†para %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Valor de dupla precisão “%s†para %s para lá do limite permitido" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Erro ao processar a opção %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Argumento em falta para %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Opção %s desconhecida" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "objeto corrompido" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "erro interno ou objeto corrompido" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "sem memória livre" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "limite de retroceder alcançado" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "o padrão contém itens não suportados para comparação parcial" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "erro interno" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"referências anteriores como condições não são suportadas para comparação " +"parcial" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "alcançado o limite de recursividade" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "combinação inválida de parâmetros de quebra de linha" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "desvio inválido" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 curto" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "recursão infinita" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "erro desconhecido" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ no final do padrão" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c no final do padrão" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "carácter desconhecido após \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "números fora da ordem no quantificador {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "número demasiado grande no quantificador {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "falta o ] de fecho da classe de carácter" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "sequência de escape inválida na classe de carácter" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "intervalo fora da ordem na classe de carácter" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nada a repetir" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "repetição inesperada" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "carácter desconhecido após (? or (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "Classes denominadas POSIX apenas são suportadas dentro de uma classe" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "falta o ) de fecho" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referência a padrão inexistente" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "falta o ) após o comentário" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "expressão regular demasiado extensa" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "falha ao obter memória" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") sem um ( de abertura" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "código fora dos limites" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "carácter desconhecido após (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "asserção de verificação anterior não é de largura fixa" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "número ou nome mal formado após (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "grupo condicional contém mais de dois ramos" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "esperada uma asserção após (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ou (?[+-]números tem de ser seguido de )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nome de classe POSIX desconhecido" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "Não são suportados os elementos de junção POSIX" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "valor do carácter na sequência \\x{...} é demasiado grande" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condição inválida (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C não é permitido numa asserção de verificação anterior" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{nome}, \\U, e \\u não são suportados" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "chamada recursiva pode iterar indefinidamente" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "carácter desconhecido após (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "falta o terminador no nome do subpadrão" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dois subpadrões denominados têm o mesmo nome" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "sequência \\P ou \\p mal formada" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nome de propriedade desconhecido após \\P ou \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "nome do subpadrão é demasiado extenso (máximo de 32 caracteres)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "demasiados subpadrões denominados (máximo de 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "valor octal é maior do que \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "derramou fora da área de trabalho de compilação" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "subpadrão referenciado previamente verificado não foi encontrado" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "Grupo DEFINE contém mais de um ramo" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opções de NEWLINE inconsistentes" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g não é seguido de um nome ou número delimitado por chavetas, parenteses " +"ou aspas ou um número simples" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "uma referência numerada não pode ser zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "não é permitido um argumento para (*ACCEPT), (*FAIL), ou (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) não é reconhecido" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "número é demasiado grande" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "falta o nome do subpadrão após (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "esperado um dígito após (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] é um carácter de dados inválido no modo de compatibilidade JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "não são permitidos nomes diferentes para subpadrões do mesmo número" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) tem de ter um argumento" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c não pode ser seguido de um carácter ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k não é seguido de um nome delimitado por chavetas, parenteses angulares " +"ou aspas" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N não é suportado numa classe" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "demasiadas referências de reencaminhamento" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "nome é demasiado extenso em (*MARK), (*PRUNE), (*SKIP), ou (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "valor do carácter na sequência \\u.... é demasiado grande" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Erro ao comparar a expressão regular %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Biblioteca PCRE está compilada sem suporte UTF8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Biblioteca PCRE está compilada sem suporte para propriedades UTF8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Biblioteca PCRE está compilada com opções incompatíveis" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Erro ao otimizar a expressão regular %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Erro ao compilar a expressão regular %s no carácter %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "esperado um dígito hexadecimal ou \"}\"" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "esperado um dígito hexadecimal" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "falta “<†na referência simbólica" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "referência simbólica por terminar" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "referência simbólica de tamanho zero" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "esperado um dígito" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "referência simbólica ilegal" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "“\\†final a mais" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "sequência de escape desconhecida" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Erro ao processar o texto de substituição “%s†no carácter %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Texto citado não é iniciado com um carácter de aspa" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Aspa sem par na linha de comando ou outro texto de consola citado" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Texto terminou após um carácter “\\â€. (O texto era “%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Texto terminou antes de ser encontrada a aspa equivalente para %c. (O texto " +"era “%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Texto estava vazio (ou apenas continha espaços)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Falha ao ler dados de sub processo (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Erro inesperado ao ler dados de sub processo (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Erro inesperado em waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Sub processo terminou com o código %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Sub processo morto com o sinal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Sub processo parado com o sinal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "O sub processo terminou anormalmente" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Falha ao ler de canal acima (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Falha ao criar sub processo “%s†(%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Falha ao bifurcar \"fork\" (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Falha ao ir para o diretório “%s†(%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Falha ao executar o sub processo “%s†(%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Falha ao abrir o ficheiro para remapear o descritor do ficheiro (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Falha ao duplicar descritor do ficheiro para o sub processo (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Falha ao efetuar fork de sub processo (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Falha em fechar o descritor de ficheiro para sub processo (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Erro desconhecido ao executar sub processo “%sâ€" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Impossível ler dados suficientes de canal pid acima (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Falha ao ler dados de sub processo" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Falha ao executar sub processo (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Falha ao dup() no sub processo (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nome de programa inválido: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Cadeia inválida no vetor de argumentos na posição %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Cadeia inválida no ambiente: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Pasta de trabalho inválida: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Falha ao executar aplicação auxiliar (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Erro inesperado no g_io_channel_win32_poll() ao ler dados de um sub processo" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Cadeia vazia não é um número" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†não é um número com sinal" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Número “%s†está fora do limite [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†não é um valor sem sinal" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-encoding inválido no URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Carácter ilegal no URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caracteres non-UTF-8 no URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Endereço IPv6 inválido ‘%.*s’ no URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Endereço IP codificado ilegal ‘%.*s’ no URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nome de máquina ilegalmente internacionalizado '%.*s' no URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Impossível processar porto ‘%.*s’ no URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Porto ‘%.*s’ no URI fora de alcance" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI ‘%s’ não é um URI absoluto" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI ‘%s’ não possui uma componente destino" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI não é absoluto, e nenhuma base URI foi fornecida" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "‘=’ e valor de parâmetro em falta" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Falha ao alocar memória" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Carácter fora do limite para UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Sequência inválida na conversão da entrada" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Carácter fora do limite para UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Impossível ler /var/lib/dbus/machine-id ou /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Erro desconhecido ao ligar" + +#~ msgid "Error in address '%s' - the family attribute is malformed" +#~ msgstr "Erro no endereço \"%s\" - o atributo family está mal formado" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Erro ao criar a pasta \"%s\": %s" + +#~ msgid "No such interface" +#~ msgstr "Não existe o a pasta" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Mensagem tem %d descritores de ficheiros mas o campo de cabeçalho indica " +#~ "%d descritores de ficheiros" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Erro: sinal não especificado.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Erro: sinal tem de ser o nome completo (fully-qualified).\n" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Erro ao definir atributos que podem ser escritos: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Erro a montar localização: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Erro a desmontar montagem: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Erro a encontrar montagem fechada: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Erro a ejetar montagem: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Erro a montar %s: %s\n" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "Montar %s em %s\n" + +#~ msgid "No files to open" +#~ msgstr "Nenhum ficheiro a abrir" + +#~ msgid "No files to delete" +#~ msgstr "Nenhum ficheiro a apagar" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Erro ao definir o atributo: %s\n" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Falha ao criar o ficheiro temporário: %s" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; a ignorar a sobreposição para esta chave.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " e foi especificado o modo --strict; a terminar.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "A ignorar sobreposição para esta chave.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "inativo.\n" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Erro ao abrir o ficheiro \"%s\": %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Erro ao ler o ficheiro \"%s\": %s" + +#~ msgid "No locations gives" +#~ msgstr "Nenhuma localização dá" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Erro ao renomear o ficheiro: %s" + +#~ msgid "Can't open directory" +#~ msgstr "Impossível abrir a pasta" + +#~ msgid "Error opening file: %s" +#~ msgstr "Erro ao abrir o ficheiro: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Erro ao criar a pasta: %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "" +#~ "Incapaz de encontrar o tipo de monitor por omissão do diretório local" + +#~ msgid "association changes not supported on win32" +#~ msgstr "alterações de associação não são suportadas em win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Criação de associação não é suportada em win32" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Ficheiro de chave não contém a chave '%s'" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "Erro ao processar o ficheiro de entrada com o xmllint:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "Erro ao processar o ficheiro de entrada com o to-pixdata:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "Incapaz de obter o erro pendente: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Falha ao abrir o ficheiro '%s' para escrita: falha no fdopen(): %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Falha ao escrever o ficheiro '%s': falha no fflush(): %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Falha ao fechar o ficheiro '%s': falha no fclose(): %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "Dados incompletos recebidos para '%s'" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Comprimento de opção inesperado ao verificar se SO_PASSCRED está ativo " +#~ "para socket. Esperados %d bytes, obtidos %d" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "" +#~ "Aplicação terminou anormalmente ao criar uma linha de comando '%s': %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "" +#~ "Linha de comando '%s' terminou com o estado diferente de zero %d: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "Nenhum registo de serviço para '%s'" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "alcançado o limite da área de trabalho para subexpressões vazias" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "não são aqui permitidos escapes de alteração de capitalização (\\l, \\L, " +#~ "\\u, \\U)" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "não é permitido repetir um grupo DEFINE" + +#~ msgid "File is empty" +#~ msgstr "Ficheiro está vazio" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "Ficheiro de chave contém a chave '%s' cujo valor não é interpretável." + +#~ msgid "This option will be removed soon." +#~ msgstr "Esta opção será removida brevemente." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Erro ao verificar o ficheiro '%s': %s" + +#~ msgid "Error connecting: " +#~ msgstr "Erro ao se ligar: %s" + +#~ msgid "Error connecting: %s" +#~ msgstr "Erro ao se ligar: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "A implementação SOCKSv4 limita o nome de utilizador a %i carateres" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "A implementação SOCKSv4a limita o nome de máquina a %i carateres" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Erro ao ler de unix: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Erro ao escrever no unix: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "am" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "Tipo de valor de resposta é incorreto, obtido '%s', esperado '%s'" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "A tentar definir a propriedade %s do tipo %s mas, de acordo com o " +#~ "interface esperado, o tipo é %s" + +#~ msgid "No such schema '%s' specified in override file '%s'" +#~ msgstr "Esquema '%s' não foi especificado no ficheiro de sobreposição '%s'" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "Comandos:\n" +#~ " help Apresenta esta informação\n" +#~ " get Obtém o valor de uma chave\n" +#~ " set Define o valor de uma chave\n" +#~ " reset Repõe o valor original de uma chave\n" +#~ " monitor Monitoriza alterações a uma chave\n" +#~ " writable Verifica se é possível definir o valor de uma chave\n" +#~ "\n" +#~ "Utilize '%s COMMAND --help' para obter ajuda para comandos individuais.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "Especifique o caminho para o esquema" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "Argumentos:\n" +#~ " ESQUEMA O id do esquema\n" +#~ " CHAVE O nome da chave\n" +#~ " VALOR O valor a definir para a chave, como um GVariant " +#~ "serializado\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "Monitoriza por alterações a CHAVE e imprime os valores alterados.\n" +#~ "A monitorização continua até que o processo seja terminado." + +#~ msgid "Do not give error for empty directory" +#~ msgstr "Não dar erro para um diretório" + +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Sequência UTF-8 inválida na entrada" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "Atingido o limite de dados de uma matriz" + +#~ msgid "do not hide entries" +#~ msgstr "não esconder as entradas" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Caracter '%s' não é válido no início do nome de uma entidade; o caracter " +#~ "& inicia uma entidade; se este 'i comercial' não é suposto ser uma " +#~ "entidade, mascare-o como &" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "Caracter '%s' não é válido dentro do nome de uma entidade" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "" +#~ "Referência de caracter vazia; deverá incluir um dígito tal como dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Referência de entidade por terminar" + +#~ msgid "Unfinished character reference" +#~ msgstr "Referência de caracter por terminar" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Texto codificado UTF-8 inválido - sequência demasiado extensa" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Texto codificado UTF-8 inválido - não é um caracter inicial" + +#~ msgid "file" +#~ msgstr "ficheiro" + +#~ msgid "The file containing the icon" +#~ msgstr "O ficheiro que contém o ícone" + +#~ msgid "An array containing the icon names" +#~ msgstr "Uma matriz contendo os nomes dos ícones" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "Se utilizar ou não os nomes de recurso criados abreviando o nome nos " +#~ "carateres '-'. Ignora os nomes após o primeiro se forem indicados vários." + +#~ msgid "File descriptor" +#~ msgstr "Descritor de ficheiro" + +#~ msgid "The file descriptor to read from" +#~ msgstr "O descritor do ficheiro de onde ler" + +#~ msgid "Close file descriptor" +#~ msgstr "Fechar o descritor de ficheiro" + +#~ msgid "Whether to close the file descriptor when the stream is closed" +#~ msgstr "Se fechar ou não o descritor do ficheiro quando o fluxo é fechado" + +#~ msgid "Error creating backup link: %s" +#~ msgstr "Erro ao criar o atalho para a cópia de segurança: %s" + +#~ msgid "Can't load just created desktop file" +#~ msgstr "" +#~ "Incapaz de ler o ficheiro de área de trabalho que acabou de ser criado" + +#~ msgid "Too large count value passed to g_input_stream_read_async" +#~ msgstr "" +#~ "Valor de contagem demasiado elevado passado a g_input_stream_read_async" + +#~ msgid "Too large count value passed to g_input_stream_skip" +#~ msgstr "Valor de contagem demasiado grande passado para g_input_stream_skip" + +#~ msgid "Too large count value passed to g_input_stream_skip_async" +#~ msgstr "" +#~ "Valor de contagem demasiado grande passado para g_input_stream_skip_async" + +#~ msgid "Target file already exists" +#~ msgstr "Já existe o ficheiro de destino" + +#~ msgid "Too large count value passed to g_output_stream_write" +#~ msgstr "" +#~ "Valor de contagem demasiado grande passado para g_output_stream_write" + +#~ msgid "Too large count value passed to g_output_stream_write_async" +#~ msgstr "" +#~ "Valor de contagem demasiado grande passado para " +#~ "g_output_stream_write_async" + +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Incapaz de alterar o modo do ficheiro: falha no fork(): %s" + +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Incapaz de alterar o modo do ficheiro: falha no chmod(): %s" + +#~ msgid "Could not change file mode: Child terminated by signal: %s" +#~ msgstr "" +#~ "Incapaz de alterar o modo do ficheiro: Filho terminado pelo sinal: %s" + +#~ msgid "Could not change file mode: Child terminated abnormally" +#~ msgstr "Incapaz de alterar o modo do ficheiro: Filho terminou anormalmente" + +#~ msgid "Incorrect message size" +#~ msgstr "Tamanho de mensagem incorreto" + +#~ msgid "Socket error" +#~ msgstr "Erro de socket" + +#~ msgid "Channel set flags unsupported" +#~ msgstr "Canal definiu parâmetros não suportados" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 0000000..bfee3cb --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,6654 @@ +# Brazilian Portuguese translation of glib. +# Copyright (C) 2022 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Gustavo Noronha Silva , 2001-2005 +# Leonardo Ferreira Fontenelle , 2006-2009. +# Vladimir Melo , 2007, 2009. +# Luiz Armesto , 2008. +# Og Maciel , 2008-2009, 2011. +# Henrique P Machado , 2008-2009. +# Fábio Nogueira , 2009. +# Fabrício Godoy , 2010. +# Djavan Fagundes , 2011. +# Adorilson Bezerra , 2011. +# Jonh Wendell , 2009, 2010, 2012. +# Felipe Braga , 2015. +# Artur de Aquino Morais , 2016. +# Enrico Nicoletto , 2013-2014, 2016, 2021-2022. +# Leônidas Araújo , 2022. +# Rafael Fontenelle , 2013-2022. +# Matheus Barbosa , 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-14 12:00+0000\n" +"PO-Revision-Date: 2022-04-15 13:53-0300\n" +"Last-Translator: Enrico Nicoletto \n" +"Language-Team: Brazilian Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 3.0.1\n" +"X-Project-Style: gnome\n" +"X-DL-Team: pt_BR\n" +"X-DL-Module: glib\n" +"X-DL-Branch: main\n" +"X-DL-Domain: po\n" +"X-DL-State: Translating\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Definir aplicativos padrão ainda não suportado" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Definir o aplicativo como usado pela última vez para o tipo ainda não " +"suportado" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Opções do GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Mostra as opções do GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Digite o modo de serviço do GApplication (usar dos arquivos de serviços do D-" +"Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Substitui ID do aplicativo" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Substitui a instância em execução" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Exibe a ajuda" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMANDO]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Exibe a versão" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Exibe a informação da versão e sai" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Lista aplicativos" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Lista os aplicativos instalados que ativam D-Bus (por arquivos .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Inicia um aplicativo" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Inicia o aplicativo (com arquivos opcionais a serem abertos)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [ARQUIVO…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Ativa uma ação" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invoca uma ação no aplicativo" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID AÇÃO [PARÂMETRO]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Lista as ações disponíveis" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Lista as ações estáticas para um aplicativo (de arquivos .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMANDO" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "O comando para exibir ajuda detalhada para" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identificador do aplicativo em formato D-Bus (ex: org.exemplo.visualizador)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "ARQUIVO" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Nomes de arquivos relativo ou absoluto, ou URIs a abrir, opcionalmente" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "AÇÃO" + +# Espaço inicial acrescentado para alinhar o texto (gapplication help action) -- Rafael +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr " O nome da ação a ser invocada" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARÂMETRO" + +# Espaço inicial acrescentado para alinhar o texto (gapplication help action) -- Rafael +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Parâmetro opcional para a invocação da ação, em formato GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Comando desconhecido %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Uso:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumentos:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTOS…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Comandos:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Use “%s help COMANDO†para obter ajuda detalhada.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"o comando %s necessita de um id de aplicativo para segui-lo diretamente\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "id de aplicativo inválido: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†não leva argumentos\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "não foi possível se conectar ao D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "erro ao enviar %s mensagens ao aplicativo: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "o nome da ação deve ser fornecido após o id do aplicativo\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nome da ação inválido: “%sâ€\n" +"os nomes de ações devem consistir de apenas caracteres alfanuméricos, “-†e " +"“.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "erro ao analisar o parâmetro da ação: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "as ações aceitam um máximo de um parâmetro\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "o comando list-actions leva apenas um id de aplicativo" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "não foi possível localizar o arquivo desktop para o aplicativo %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"comando não reconhecido: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Valor muito alto passado para %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Não há suporte à busca no fluxo base" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Não é possível truncar GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "O fluxo já está fechado" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Não há suporte para truncar fluxo base" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "A operação foi cancelada" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Objeto inválido, não inicializado" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Sequência de bytes incompleta na entrada" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Espaço insuficiente no destino" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Sequência de bytes inválida na entrada de conversão" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Erro durante a conversão: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Sem suporte a inicialização cancelável" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Não há suporte à conversão do conjunto de caracteres “%s†para “%sâ€" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Não foi possível abrir conversor de “%s†para “%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "tipo %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Tipo desconhecido" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "tipo de arquivo %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials contém dados inválidos" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials não está implementado neste SO" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Não há suporte ao GCredentials para sua plataforma" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials não contém um ID de processo neste SO" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "" +"Não é possível fazer uso de falsificação de credenciais neste sistema " +"operacional" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Fim do fluxo inesperadamente prematuro" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Não há suporte a chave “%s†na entrada de endereço “%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "" +"Combinação de pares chave/valor sem sentido na entrada de endereço “%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"O endereço “%s†é inválido (é necessário exatamente um dentre: caminho, " +"diretório, diretório temporário ou chaves abstratas)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Erro no endereço “%s†— o atributo “%s†está malformado" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transporte desconhecido ou sem suporte “%s†para o endereço “%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "O elemento endereço “%s†não contém um caractere de dois-pontos (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "O nome do transporte no elemento de endereço “%s†não pode estar vazio" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"O par chave/valor %d, “%sâ€, no elemento endereço “%sâ€, não contém um sinal " +"de igual" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"O par chave/valor %d, “%sâ€, no elemento endereço “%sâ€, não pode ter uma " +"chave vazia" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Erro ao distinguir a chave sem escape ou valor no par chave/valor %d, “%sâ€, " +"no elemento endereço “%sâ€" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Erro no endereço “%s†— o transporte Unix requer exatamente uma das chaves " +"“path†ou “abstract†sejam definidas" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Erro no endereço “%s†— o atributo servidor está faltando ou malformado" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Erro no endereço “%s†— o atributo porta está faltando ou malformado" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Erro no endereço “%s†— o atributo do arquivo de valor de uso único está " +"faltando ou malformado" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Erro ao iniciar automaticamente: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Erro ao abrir arquivo de valor de uso único “%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Erro ao ler arquivo de valor de uso único “%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Erro ao ler o arquivo de valor de uso único “%sâ€; era esperado 16 bytes, mas " +"foi obtido %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Erro ao gravar o arquivo de valor de uso único “%s†no fluxo:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "O endereço fornecido está vazio" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Não é possível chamar um barramento de mensagens quando AT_SECURE está " +"definido" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Não foi possível chamar um barramento de mensagens sem um ID de máquina: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Não foi possível iniciar automaticamente o D-Bus sem X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Erro ao chamar a linha de comandos “%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Não foi possível determinar o endereço de barramento da sessão (sem " +"implementação para este SO)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Não foi possível determinar o endereço de barramento da variável de ambiente " +"DBUS_STARTER_BUS_TYPE — valor desconhecido “%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Não foi possível determinar o endereço do barramento porque a variável de " +"ambiente DBUS_STARTER_BUS_TYPE não está definida" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tipo de barramento %d desconhecido" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Falta de conteúdo inesperada ao tentar ler uma linha" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Falta de conteúdo inesperada ao tentar (seguramente) ler uma linha" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Foram esgotados todos mecanismos de autenticação disponíveis (tentado: %s) " +"(disponível: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "IDs de usuário devem ser o mesmo para a ponta e o servidor" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Cancelado via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Erro ao obter informação para o diretório “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"As permissões no diretório “%s†estão malformadas. É esperado 0700, mas foi " +"obtido 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Erro ao criar o diretório “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Operação sem suporte" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Erro ao abrir o chaveiro “%s†para leitura: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "A linha %d do chaveiro em “%s†com o conteúdo “%s†está malformado" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"O primeiro símbolo da linha %d do chaveiro em “%s†com o conteúdo “%s†está " +"malformado" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"O segundo símbolo da linha %d do chaveiro em “%s†com o conteúdo “%s†está " +"malformado" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Não foi possível localizar um anexo com o ID %d no chaveiro em “%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Erro ao criar o arquivo de bloqueio “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Erro ao excluir o arquivo de bloqueio anterior “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Erro ao fechar o arquivo de bloqueio (desvinculado) “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Erro ao desvincular o arquivo de bloqueio “%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Erro ao abrir o chaveiro “%s†para escrita: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Adicionalmente, liberar o bloqueio de “%s†também falhou: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "A conexão está fechada" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "O tempo limite foi alcançado" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Foram encontrados sinalizadores sem suporte ao construir uma conexão do lado " +"do cliente" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Nenhuma interface “org.freedesktop.DBus.Properties†no objeto no caminho %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Nenhuma propriedade “%sâ€" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "A propriedade “%s†não pode ser lida" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "A propriedade “%s†não pode ser escrita" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Erro ao definir a propriedade “%sâ€: o tipo esperado é “%sâ€, mas obteve “%sâ€" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Nenhuma interface “%sâ€" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Nenhuma interface “%s†no objeto no caminho %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Método inexistente “%sâ€" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "O tipo da mensagem, “%sâ€, não equivale ao tipo esperado “%sâ€" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Um objeto já foi exportado para a interface %s em %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Não foi possível obter a propriedade %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Não foi possível definir a propriedade %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "O método “%s†retornou o tipo “%sâ€, mas é esperado “%sâ€" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "O método “%s†na interface “%s†com a assinatura “%s†não existe" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Uma subárvore já foi exportada para %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "O objeto não existe no caminho “%sâ€" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "o tipo é INVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" +"Mensagem de METHOD_CALL: O campo de cabeçalho PATH ou MEMBER está faltando" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" +"Mensagem de METHOD_RETURN: O campo de cabeçalho REPLY_SERIAL está faltando" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Mensagem de ERROR: O campo de cabeçalho REPLY_SERIAL ou ERROR_NAME está " +"faltando" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Mensagem de SIGNAL: O campo de cabeçalho PATH, INTERFACE ou MEMBER está " +"faltando" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Mensagem de SIGNAL: O campo de cabeçalho PATH está usando o valor reservado /" +"org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Mensagem de SIGNAL: O campo de cabeçalho INTERFACE está usando o valor " +"reservado org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Ao tentar ler %lu byte obteve-se %lu" +msgstr[1] "Ao tentar ler %lu bytes obteve-se %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "" +"Era esperado um byte NUL (nulo) após o texto “%sâ€, mas foi localizado o byte " +"%d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Era esperado um texto UTF-8 válido, mas foi localizado bytes inválidos na " +"posição %d (tamanho do texto é %d). O texto UTF-8 válido até este ponto era " +"“%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Valor aninhado profundo demais" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "O valor “%s†analisado não é um objeto de caminho D-Bus válido" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "O valor “%s†analisado não é uma assinatura D-Bus válida" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Foi encontrado um vetor com tamanho de %u byte. O tamanho máximo é de 2<<26 " +"bytes (64 MiB)." +msgstr[1] "" +"Foi encontrado um vetor com tamanho de %u bytes. O tamanho máximo é de 2<<26 " +"bytes (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Foi encontrado um vetor de tipo “a%câ€, esperava-se que tivesse um " +"comprimento múltiplo de %u bytes, porém foi localizado %u bytes em " +"comprimento" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Estruturas (tuplas) vazias não são permitidas no D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "O valor “%s†analisado para variante não é uma assinatura D-Bus válida" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Erro ao desserializar GVariant com o texto de tipo “%s†do formato " +"delimitado pelo D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valor identificador de endian inválido. Era esperado 0x6c (“lâ€) ou 0x42 " +"(“Bâ€), mas foi localizado o valor 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"Versão majoritária de protocolo inválida. Era esperado 1, mas foi localizado " +"%d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Cabeçalho da assinatura localizado, mas não é do tipo assinatura" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"O cabeçalho de assinatura foi localizado com a assinatura “%sâ€, mas o corpo " +"da mensagem está vazio" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"O valor “%s†analisado não é uma assinatura D-Bus válida (para o corpo)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Nenhum cabeçalho de assinatura na mensagem, mas o corpo da mensagem tem %u " +"byte" +msgstr[1] "" +"Nenhum cabeçalho de assinatura na mensagem, mas o corpo da mensagem tem %u " +"bytes" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Não foi possível desserializar a mensagem: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Erro ao serializar GVariant com o texto de tipo “%s†para o formato " +"delimitado pelo D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"O número de descritores de arquivo na mensagem (%d) difere do campo de " +"cabeçalho (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Não foi possível serializar a mensagem: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"O corpo da mensagem tem a assinatura “%sâ€, mas não há um cabeçalho de " +"assinatura" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"O corpo da mensagem tem o tipo de assinatura “%sâ€, mas a assinatura no campo " +"de cabeçalho é “%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"O corpo da mensagem está vazio, mas a assinatura no campo de cabeçalho é " +"“(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Retorno de erro com o corpo de tipo “%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Retorno de erro com o corpo vazio" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Digite qualquer tecla para fechar esta janela)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "A sessão dbus não está em execução, e o início automático falhou" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Não foi possível obter o perfil da máquina: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Não foi possível carregar %s ou %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Erro ao chamar StartServiceByName para %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Resposta %d inesperada do método StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Não foi possível chamar método; o proxy é para um nome conhecido %s sem um " +"dono e o proxy foi construído com o sinalizador " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Sem suporte a espaço de nome abstrato" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Não foi possível especificar o arquivo de valor de uso único ao criar um " +"servidor" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Erro ao gravar o arquivo de valor de uso único em “%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "O texto “%s†não é válido para GUID D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Não é possível escutar no transporte “%s†por falta de suporte" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Comandos:\n" +" help Mostra esta informação\n" +" introspect Introspecção de um objeto remoto\n" +" monitor Monitora um objeto remoto\n" +" call Chama um método de um objeto remoto\n" +" emit Emite um sinal\n" +" wait Aguarda por um nome de barramento para aparecer\n" +"\n" +"Use “%s COMANDO --help†para obter ajuda de cada comando.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Erro: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Erro ao analisar XML de introspecção: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Erro: %s não é um nome válido\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Erro: %s não é um caminho de objeto válido\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Conectar ao barramento de sistema" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Conectar ao barramento de sessão" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Conectar ao endereço D-Bus escolhido" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Opções de conexão de ponto final:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Opções especificando a conexão de ponto final" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nenhuma conexão de ponto final especificada" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Múltiplas conexões de ponto final especificadas" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Aviso: De acordo com os dados de introspecção a interface “%s†não existe\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Aviso: De acordo com os dados de introspecção o método “%s†não existe na " +"interface “%sâ€\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Destino opcional para o sinal (nome único)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Caminho do objeto para emitir sinal" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Nome de sinal e de interface" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Emitir um sinal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Erro ao conectar: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Erro: %s não é um nome válido de barramento exclusivo.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Erro: O caminho do objeto não foi especificado\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Erro: O nome do sinal não foi especificado\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Erro: O nome do sinal “%s†é inválido\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Erro: %s não é um nome de interface válido\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Erro: %s não é um nome de membro válido\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Erro ao analisar o parâmetro %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Erro limpando conexão: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Nome do destino para chamar um método" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Caminho do objeto para chamar um método" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Nome de método e de interface" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Tempo limite em segundos" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Permitir autorização interativa" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Chamar um método no objeto remoto." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Erro: O destino não foi especificado\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Erro: %s não é um nome de barramento válido\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Erro: O nome do método não foi especificado\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Erro: O nome do método “%s†é inválido\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Erro ao analisar o parâmetro %d do tipo “%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Erro ao adicionar manipulador %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Nome do destino para introspecção" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Caminho do objeto para introspecção" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Exibir XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Auto-examinar filhos" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Apenas imprimir as propriedades" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspecção de um objeto remoto." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nome do destino para monitorar" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Caminho do objeto para monitorar" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Monitora um objeto remoto." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"Erro: não é possível monitorar uma conexão que não seja de barramento de " +"mensagem\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Serviço a ser ativado antes de esperar por uma outra (nome conhecido)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Tempo limite de espera antes de sair com um erro (segundos); 0 para nenhum " +"tempo limite (padrão)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPÇÃO…] NOME-BARRAMENTO" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Espera por um nome de barramento para aparecer." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Erro: Um serviço a ser ativado deve ser especificado.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Erro: Um serviço a ser esperado deve ser especificado.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Erro: Número excessivo de argumentos.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Erro: %s não é um nome válido de barramento conhecido.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Não autorizado para alterar configurações de depuração" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Sem nome" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "O arquivo da área de trabalho não especifica o campo Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Não é possível localizar o terminal requerido para o aplicativo" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Não é possível criar pasta de configuração do aplicativo do usuário %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Não é possível criar pasta de configuração MIME do usuário %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "A informação do aplicativo carece de um identificador" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Não é possível criar arquivo %s da área de trabalho do usuário" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Definição personalizada para %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "a unidade não implementa ejetar" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "a unidade não implementa ejetar ou eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "a unidade não implementa verificação por mídia" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "a unidade não implementa start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "a unidade não implementa stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "O backend TLS não implementa recuperação de vinculação TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Suporte TLS não disponível" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Suporte DTLS não disponível" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Não é possível lidar com a versão %d da codificação GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Número inválido de tokens (%d) na codificação GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Não é possível lidar com a versão %d da codificação GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Número inválido de tokens (%d) na codificação GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Esperado um GEmblem para o GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Ponto de montagem contido não existe" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Não é possível copiar sobre diretório" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Não é possível copiar diretório sobre diretório" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Arquivo alvo existe" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Não é possível copiar o diretório recursivamente" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Não há suporte a união de arquivos" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Erro ao unir o arquivo: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Não há suporte a copiar (reflink/clone) entre montagens" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Não há suporte a copiar (reflink/clone) ou é inválido" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Não há suporte a copiar (reflink/clone) ou não funcionou" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Não é possível copiar o arquivo especial" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Fornecido valor inválido de link simbólico" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Não há suporte a links simbólicos" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Não há suporte para lixeira" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Nomes de arquivo não podem conter “%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "volume não implementa montagem" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Nenhum aplicativo está registrado como manipulador deste arquivo" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "O enumerador está fechado" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "O enumerador do arquivo tem operação pendente" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "O enumerador do arquivo já está fechado" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Não é possível lidar com a versão %d da codificação GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Dados de entrada malformados para o GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Fluxo não tem suporte para query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Não há suporte à busca no fluxo" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Não é permitido truncar fluxo de entrada" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Não há suporte para truncar fluxo" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Nome de máquina inválido" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Resposta do proxy HTTP inválida" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Conexão do proxy HTTP não permitida" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Falha na autenticação com o proxy HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Autenticação necessária com o proxy HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Falha na conexão com o proxy HTTP: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Resposta do proxy HTTP grande demais" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "O servidor proxy HTTP fechou a conexão de forma inesperada." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Número errado de tokens (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Sem tipo para a classe chamada %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "O tipo %s não implementa a interface GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "O tipo %s não tem classe" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Número de versão malformado: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "O tipo %s não implementa from_tokens() na interface GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Não é possível lidar com a versão fornecida da codificação do ícone" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nenhum endereço fornecido" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "O tamanho %u é muito longo para o endereço" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "O endereço contém bits ativos além do tamanho do prefixo (máscara)" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Não foi possível interpretar “%s†como uma máscara de endereço IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Sem espaço suficiente para o endereço do soquete" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Endereço de soquete não suportado" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Fluxo de entrada não implementa leitura" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "O fluxo tem operação pendente" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copiar com o arquivo" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Manter com o arquivo quando movido" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†não leva argumentos" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Uso:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Exibe a informação da versão e sai." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Comandos:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatena arquivos para a saída padrão" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copia um ou mais arquivos" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Mostra informações sobre locais" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Inicia um aplicativo a partir de um arquivo desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Lista o conteúdo dos locais" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Obtém ou define o manipulador para um tipo mime" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Cria diretórios" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitora arquivos e diretórios por alterações" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Monta ou desmonta os locais" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Move um ou mais arquivos" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Abre arquivos com o aplicativo padrão" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Renomeia um arquivo" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Exclui um ou mais arquivos" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Lê da entrada padrão e salva" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Define um atributo de arquivo" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Move arquivos ou diretórios para a lixeira" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Lista o conteúdo de locais em uma árvore" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Use %s para obter ajuda detalhada.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Erro ao gravar para a saída padrão" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCAL" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatena arquivos e os envia para a saída padrão." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat funciona quase igual ao utilitário cat tradicional, mas\n" +"usando locais GIO em vez de arquivos locais: por exemplo, você pode\n" +"usar alguma coisa como smb://servidor/recurso/arquivo.txt como local." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nenhum local fornecido" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nenhum diretório alvo" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Mostra progresso" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Pergunta antes de sobrescrever" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Preserva todos os atributos" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Cria backup dos arquivos de destino existentes" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nunca segue links simbólicos" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Usa permissões padrão para o destino" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Transferido(s) %s de %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ORIGEM" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINO" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copia um ou mais arquivos de ORIGEM para DESTINO." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy é similar ao utilitário cp tradicional, mas usando locais\n" +"GIO em vez de arquivos locais: por exemplo, você pode usar alguma\n" +"coisa como smb://servidor/recurso/arquivo.txt como local." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "O destino %s não é um diretório" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: sobrescrever “%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Lista os atributos graváveis" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Obtém informação de sistema de arquivos" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Os atributos a obter" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTOS" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Não segue links simbólicos" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributos:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nome de exibição: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "nome para edição: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nome: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tipo: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "tamanho: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "oculto\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "caminho local: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "montagem unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atributos definíveis:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Atributos graváveis no namespace:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Mostra informações sobre locais." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info é similar ao utilitário ls tradicional, mas usando locais\n" +"GIO em vez de arquivos locais: por exemplo, você pode usar alguma\n" +"coisa como smb://servidor/recurso/arquivo.txt como local. Atributos\n" +"de arquivos podem ser especificados por meio de seus nome GIO\n" +"(ex.: standard::icon), ou apenas pelo espaço de nome (ex.: unix),\n" +"ou por “*â€, que corresponde a todos atributos" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "ARQUIVO-DESKTOP [ARG-ARQUIVO …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Inicia um aplicativo a partir de um arquivo desktop, passando argumentos " +"opcionais de nome de arquivo para ele." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nenhum arquivo desktop fornecido" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" +"O comando de inicialização não é compatível atualmente com esta plataforma" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Não foi possível carregar “%sâ€: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Não foi possível carregar informações de aplicativo para “%sâ€" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Não foi possível iniciar o aplicativo “%sâ€: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Mostra arquivos ocultos" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Usa um formato de listagem longa" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Exibe nomes de exibição" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Imprime URIs completas" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Lista o conteúdo dos locais." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list é similar ao utilitário ls tradicional, mas usando locais\n" +"GIO em vez de arquivos locais: por exemplo, você pode usar alguma\n" +"coisa como smb://servidor/recurso/arquivo.txt como local. Atributos\n" +"de arquivos podem ser especificados por meio de seus nome GIO\n" +"(ex.: standard::icon)" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TIPO MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "MANIPULADOR" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Obtém ou define o manipulador para um tipo mime." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Se nenhum manipulador for fornecido, lista aplicativos registrados e\n" +"recomendados para o tipo mime. Se um manipulador for fornecido, ele é\n" +"definido como o manipulador padrão para o tipo mime." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Deve-se especificar um único tipo mime, e talvez um manipulado" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Nenhum aplicativo padrão para “%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Aplicativo padrão para “%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Aplicativos registrados:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nenhum aplicativo registrado\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Aplicativos recomendados:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Nenhum aplicativo recomendado\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Falha ao carregar informação para manipulador de “%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Falha ao definir “%s†como o manipulador padrão para “%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Criar diretórios pais" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Cria diretórios." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir é similar ao utilitário mkdir tradicional, mas usando\n" +"locais GIO em vez de arquivos locais: por exemplo, você pode usar\n" +"alguma coisa como smb://servidor/recurso/meudir.txt como local." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitora um diretório (padrão: depende do tipo)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitora um arquivo (padrão: depende do tipo)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Monitora um arquivo diretamente (note mudanças via links absolutos)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitora um arquivo diretamente, mas não relata alterações" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Relata movimentos e renomeação como eventos de exclusão/criação simples" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Monitora eventos de montagem" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitora arquivos ou diretórios por alterações." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Monta como montável" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Monta o volume com o arquivo de dispositivo ou outro identificador" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Desmonta" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Ejeta" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Interrompe o volume com o arquivo de dispositivo" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DISPOSITIVO" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Desmonta todas montagens com o esquema dado" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ESQUEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignora operações pendentes de arquivos ao desmontar ou ejetar" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Usa um usuário anônimo ao autenticar" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Lista" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitora eventos" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Mostra informações extras" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "O PIM numérico ao desbloquear um volume VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Mota um volume TCRYPT oculto" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Mota um volume TCRYPT de sistema" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Acesso anônimo negado" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Nenhuma unidade para o arquivo de dispositivo" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Nenhum volume para o ID dado" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Monta ou desmontar os locais." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Não usa reserva de cópia ou exclusão" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Move um ou mais arquivos da ORIGEM para DESTINO." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move é similar ao utilitário mv tradicional, mas usando locais\n" +"GIO em vez de arquivos locais: por exemplo, você pode usar alguma\n" +"coisa como smb://servidor/recurso/arquivo.txt como local" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Alvo %s não é um diretório" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Abre arquivos com o aplicativo padrão que está\n" +"registrado para manipular arquivos deste tipo." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignora arquivos não existentes, nunca pergunta" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Exclui os arquivos dados." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NOME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Renomeia um arquivo." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Faltando argumento" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Número excessivo de argumentos" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Renomeação realizada com sucesso. Nova uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Só cria se não existir" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Adiciona ao final do arquivo" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Ao criar, restringe acesso ao usuário atual" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Ao substituir, substitui como se o destino não existe" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Emite uma nova etag ao final" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "A etag do arquivo sendo sobrescrito" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Erro ao ler a partir da saída padrão" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag não disponível\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Lê da entrada padrão e salva no DESTINO." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nenhum destino dado" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Tipo do atributo" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIPO" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUTO" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALOR" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Define um atributo de arquivos de LOCAL." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Local não especificado" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atributo não especificado" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Valor não especificado" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Tipo de atributo inválido “%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Esvazia a lixeira" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Lista arquivos na lixeira com seus locais originais" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restaura um arquivo da lixeira para seu local original (possivelmente " +"recriando o diretório)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Não foi possível localizar o caminho original" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Não foi possível recriar local original: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Não foi possível mover o arquivo para seu local original: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Move/Restaura arquivos ou diretórios para/da lixeira." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Nota: para a opção --restore, se o local original do arquivo na lixeira \n" +"já existir, ele não será sobrescrito a menos que --force seja usado." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "O local fornecido não inicia com trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Segue links simbólicos, montagens e atalhos" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Lista conteúdos de diretórios em um formato tipo árvore." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "O elemento <%s> não é permitido dentro de <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "O elemento <%s> não é permitido no nível mais alto" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "O arquivo %s aparece várias vezes no recurso" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Falha ao localizar “%s†em todos os diretórios fontes" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Falha ao localizar “%s†no diretório atual" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Opção de processamento “%s†desconhecida" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Pré-processamento de %s requisitado, mas %s não está definida e %s não está " +"no PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Ocorreu erro ao ler arquivo %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Ocorreu erro ao comprimir o arquivo %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "texto não pode aparecer dentro de <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Mostra a versão do programa e sai" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Nome do arquivo de saída" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Os diretórios do quais serão carregados arquivos referenciados em ARQUIVO " +"(padrão: diretório atual)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DIRETÓRIO" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Gera a saída no formato definido pela extensão do arquivo alvo" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Gera um cabeçalho" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Gera código-fonte que vincula o recurso ao seu programa" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Gera uma lista de dependência" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Nome do arquivo de dependências para gerar" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Inclui alvos falsos no arquivo de dependência gerado" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Não cria e registra o recurso automaticamente" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Não exporta funções; declara-as G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Não embute dados de recurso no arquivo C; presume estar vinculado " +"externamente" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Nome do identificador C usado no código-fonte gerado" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "O compilador C alvo (padrão: a variável de ambiente CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compila uma especificação de recurso em um arquivo de recurso.\n" +"Arquivos de especificação de recurso têm a extensão .gresource.xml,\n" +"e um arquivo de recurso tem a extensão .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Você deve fornecer exatamente um arquivo\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "o apelido deve ter um mínimo de 2 caracteres" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Valor numérico inválido" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value=\"%s\" já especificado" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "valores de sinalizadores devem ter no máximo 1 bit definido" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> deve conter pelo menos um " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> não está contido no intervalo especificado" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> não é um membro válido do tipo enumerado especificado" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> contém string ausente no tipo de sinalizadores especializados" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> contém uma string ausente em " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " já especificado para essa chave" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " não permitido para as chaves de tipo “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "o mínimo do especificado é maior que o máximo" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categoria de l10n sem suporte: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n requisitado, mas nenhum domínio gettext dado" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "contexto de tradução dado para o valor sem l10n habilitado" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Falha ao analisar o valor de tipo “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" não pode ser especificado para chaves marcadas como tendo um tipo " +"enumerado" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " já especificado para essa chave" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " não permitido para as chaves de tipo “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " já dado" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " deve conter pelo menos um " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " já especificado para essa chave" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" só pode ser especificado para chaves com tipos enumerados ou " +"sinalizadores ou após " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr " dado quando “%s†já é um membro do tipo enumerado" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" dado quando já tinha sido dado" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "o alvo do alias “%s†não é um tipo enumerado" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "o alvo alias “%s†não está em " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " deve conter pelo menos um " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Nomes vazios não são permitidos" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Nome inválido “%sâ€: nomes precisam começar com uma letra minúscula" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nome inválido “%sâ€: caractere inválido “%câ€; apenas é permitido letras " +"minúsculas, números e traços (â€-â€)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Nome inválido “%sâ€: dois hifens (â€--â€) consecutivos não são permitidos" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Nome inválido “%sâ€: o último caractere não pode ser um hífen (â€-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nome inválido “%sâ€: o tamanho máximo é 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Não é possível adicionar chaves ao esquema “list-ofâ€" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" oculta em ; use " +"para modificar o valor" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Apenas um entre “typeâ€, “enum†ou “flags†deve ser especificado como " +"atributo para " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> não está (ainda) definido." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Tipo inválido de texto GVariant “%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " determinado, mas o esquema não está estendendo nada" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Nenhum para sobrescrever" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " já especificado" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " estende um esquema ainda não existente “%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " é uma lista de esquema ainda não existente “%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Não pode ser uma lista de um esquema com um caminho" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Não é possível estender um esquema com um caminho" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" é uma lista, estendendo que não é uma lista" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" estende , mas " +"“%s†não estende “%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Um caminho, se determinado, precisa começar e terminar com uma barra" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "O caminho de uma lista precisa terminar com “:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Aviso: Esquema “%s†possui caminho “%sâ€. Caminhos iniciando com “/apps/â€, “/" +"desktop/†ou “/system/†são obsoletos." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> já especificado" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Apenas um elemento <%s> é permitido dentro de um <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "O elemento <%s> não é permitido no nível mais alto" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "O elemento é exigido por " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Texto não pode aparecer dentro de <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Aviso: referência indefinida a " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict foi especificado; saindo." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Todo o arquivo foi ignorado." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignorando este arquivo." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Nenhuma chave “%s†no esquema “%s†como especificado no arquivo de " +"sobrescrita “%sâ€; ignorando sobrescrita para essa chave." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Nenhuma chave “%s†no esquema “%s†como especificado no arquivo de " +"sobrescrita “%s†e --strict foi especificado; saindo." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Não foi possível fornecer substituições por-desktop para chave localizada " +"“%s†no esquema “%s†(arquivo de substituição “%sâ€); ignorando substituição " +"para esta chave." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Não foi possível fornecer substituições por-desktop para chave localizada " +"“%s†no esquema “%s†(arquivo de substituição “%sâ€) e --script foi " +"especificado; saindo." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Erro ao analisar chave “%s†no esquema “%s†como especificado no arquivo de " +"sobrescrita “%sâ€: %s. Ignorando sobrescrita para essa chave." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Erro ao analisar chave “%s†no esquema “%s†como especificado no arquivo de " +"sobrescrita “%sâ€: %s. --script foi especificado; saindo." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Sobrescrita para chave “%s†no esquema “%s†no arquivo de sobrescrita “%s†" +"está fora dos limites dado pelo esquema; ignorando sobrescrita para essa " +"chave." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Sobrescrita para chave “%s†no esquema “%s†no arquivo de sobrescrita “%s†" +"está fora dos limites dado pelo esquema e --script foi especificado; saindo." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Sobrescrita para a chave “%s†no esquema “%s†no arquivo de sobrescrita “%s†" +"não está na lista de escolhas válidas; ignorando sobrescrita para essa chave." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Sobrescrita para a chave “%s†no esquema “%s†no arquivo de sobrescrita “%s†" +"não está na lista de escolhas válidas e --scrict foi especificado; saindo." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Onde armazenar o arquivo gschemas compilado" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Aborta se ocorrer erros nos esquemas" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Não escreve o arquivo gschema compilado" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Não força restrições de nome de chave" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compila todos os arquivos schema GSettings em um cache schema.\n" +"É necessário que os arquivos schema tenham a extensão\n" +".gschema.xml, e o arquivo de cache é chamado gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Você deveria dar exatamente um nome de diretório" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nenhum arquivo schema localizado: fazendo nada." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Nenhum arquivo de schema encontrado: arquivo de saída existente removido." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Nome de arquivo inválido: %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Erro ao obter informações do sistema de arquivos para %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Ponto de montagem contido para arquivo %s não existe" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Não é possível renomear o diretório root" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Erro ao renomear arquivo %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Não é possível renomear o arquivo, o nome do arquivo já existe" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nome de arquivo inválido" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Erro ao abrir arquivo %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Erro ao remover arquivo %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Erro ao mover para a lixeira o arquivo %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Não é possível criar o diretório da lixeira %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Não é possível localizar diretório de nível superior para a lixeira %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Não há suporte a mover para lixeira em montagens internas do sistema" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "" +"Não é possível localizar ou criar o diretório da lixeira %s para a lixeira %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Não é possível criar o arquivo de informações da lixeira para %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Não é possível mover para a lixeira o arquivo %s entre os limites de sistema " +"de arquivos" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Não é possível mover para a lixeira o arquivo %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Não é possível mover para a lixeira o arquivo %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Erro ao criar o diretório %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "O sistema de arquivos não tem suporte a links simbólicos" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Erro ao criar link simbólico %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Erro ao mover arquivo %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Não é possível mover diretório sobre diretório" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Falha ao criar arquivo de backup" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Erro ao remover arquivo alvo: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Não há suporte a mover entre montagens" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Não foi possível determinar a utilização de disco de %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Valor de atributo deve ser não-NULO" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tipo de atributo inválido (esperava-se expressão)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nome de atributo estendido inválido" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Erro ao definir atributo estendido “%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codificação inválida)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Erro ao obter informação para o arquivo “%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Erro ao obter informação para o descritor de arquivo: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tipo de atributo inválido (esperado uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tipo de atributo inválido (esperado uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Tipo de atributo inválido (expressão de byte esperada)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Não foi possível definir permissões aos links simbólicos" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Erro ao definir permissões: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Erro ao definir proprietário: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "o link simbólico deve ser não-NULO" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Erro ao definir link simbólico: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Erro ao definir link simbólico: o arquivo não é um link simbólico" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"Os nanossegundos extras %d para a marca de data/hora UNIX %lld são negativos" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Os nanossegundos extras %d para a marca de data/hora UNIX %lld alcança 1 " +"segundo" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "A marca de data/hora UNIX %lld não cabe em 64 bits" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"A marca de data/hora UNIX %lld está fora do intervalo suportado pelo Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "O nome de arquivo “%s†não pode ser convertido para UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "O arquivo “%s†não pôde ser aberto: Erro %lu do Windows" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Erro ao definir data/hora de modificação ou acesso para o arquivo “%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Erro ao definir data/hora de modificação ou acesso: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "O contexto SELinux deve ser não-NULO" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux não está habilitado neste sistema" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Erro ao definir o contexto SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Não há suporte à definição do atributo %s" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Erro ao ler do arquivo: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Erro ao fechar arquivo: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Erro ao buscar no arquivo: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Não é possível localizar o tipo de arquivo monitor local padrão" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Erro ao gravar o arquivo: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Erro ao remover link antigo de backup: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Erro ao criar cópia de backup: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Erro ao renomear arquivo temporário: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Erro ao truncar arquivo: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Erro ao abrir arquivo “%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Arquivo alvo é um diretório" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Arquivo alvo não é um arquivo comum" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "O arquivo foi modificado externamente" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Erro ao remover arquivo antigo: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "GSeekType fornecido inválido" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Solicitação de busca inválida" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Não é possível truncar GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Fluxo de saída da memória não redimensionável" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Falha ao redimensionar fluxo de saída da memória" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Quantidade de memória necessária para processar a escrita é maior que a " +"disponível" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Solicitada uma busca antes do começo do fluxo" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Solicitada uma busca além do fim do fluxo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "objeto de montagem não implementa “umountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "objeto de montagem não implementa “ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"objeto de montagem não implementa “unmount†ou “unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "objeto de montagem não implementa “eject†ou “eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "objeto de montagem não implementa “remountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "objeto de montagem não implementa estimativa de tipo de conteúdo" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" +"objeto de montagem não implementa estimativa de tipo de conteúdo síncrono" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Nome da máquina “%s†contém “[†mas não “]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Rede inalcançável" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Máquina inalcançável" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Não foi possível criar o monitor de rede: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Não foi possível criar o monitor de rede: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Não foi possível obter o estado da rede: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "O NetworkManager não está em execução" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "A versão do NetworkManager é muito antiga" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Fluxo de saída não implementa escrita" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "A soma dos vetores passada para %s é grande demais" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "A fonte do fluxo já está fechada" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Erro ao resolver “%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s não implementado" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Domínio inválido" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "O recurso em “%s†não existe" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Falha ao descompactar o recurso em “%sâ€" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "O recurso em “%s†não é um diretório" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Fluxo de entrada não implementa busca" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Lista as seções contendo recursos no arquivo elf ARQUIVO" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Lista recursos\n" +"Se SEÇÃO é fornecida, só lista os recursos dentro desta seção\n" +"Se CAMINHO é fornecido, só lista recursos que casam com o caminho" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "ARQUIVO [CAMINHO]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEÇÃO" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Lista recursos com detalhes\n" +"Se SEÇÃO é fornecida, só lista os recursos dentro desta seção\n" +"Se CAMINHO é fornecido, só lista recursos que casam com o caminho\n" +"Detalhes incluem a seção, tamanho e compactação" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extrai um arquivo de recurso para a saída padrão" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "ARQUIVO CAMINHO" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gresource [--section SEÇÃO] COMANDO [ARGUMENTOS…]\n" +"\n" +"Comandos:\n" +" help Mostra esta ajuda\n" +" sections Lista as seções do recurso\n" +" list Lista os recursos\n" +" details Lista os recursos com detalhes\n" +" extract Extrai um recurso\n" +"\n" +"Use “gresource help COMANDO†para obter uma ajuda detalhada.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEÇÃO Um nome de seção elf (opcional)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMANDO O comando a ser explicado (opcional)\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " ARQUIVO Um arquivo elf (binário ou biblioteca compartilhada)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" ARQUIVO Um arquivo elf (binário ou biblioteca compartilhada)\n" +" ou um arquivo de recurso compilado\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[CAMINHO]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " CAMINHO Um caminho (opcional) do recurso (pode ser parcial)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CAMINHO" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " CAMINHO Um caminho do recurso\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Nenhum esquema “%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Esquema “%s†não é recolocável (o caminho não deve ser especificado)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Esquema “%s†é recolocável (o caminho deve ser especificado)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Caminho fornecido está vazio.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "O caminho deve começar com uma barra (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "O caminho deve terminar com uma barra (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "O caminho não pode conter duas barras adjacentes (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "O valor fornecido está fora do intervalo válido\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "A chave não é gravável\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Lista os esquemas instalados (não-recolocáveis)" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Lista os esquemas recolocáveis instalados" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Lista as chaves no ESQUEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "ESQUEMA[:CAMINHO]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Lista os filhos do ESQUEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Lista as chaves e valores, recursivamente\n" +"Se nenhum ESQUEMA for fornecido, lista todas as chaves\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[ESQUEMA[:CAMINHO]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Obtém o valor de CHAVE" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "ESQUEMA[:CAMINHO] CHAVE" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Consulta o intervalo de valores válidos para CHAVE" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Consulta a descrição para a CHAVE" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Define o valor de CHAVE para VALOR" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ESQUEMA[:CAMINHO] CHAVE VALOR" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Restaurar CHAVE para seu valor padrão" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Restaurar todas as chaves no ESQUEMA para seus padrões" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Verifica se CHAVE é gravável" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitora por alterações de CHAVE.\n" +"Se nenhuma CHAVE for especificada, monitora todas as chaves no ESQUEMA.\n" +"Use ^C para parar o monitoramento.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ESQUEMA[:CAMINHO] [CHAVE]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMANDO [ARGS…]\n" +"\n" +"Comandos:\n" +" help Mostra esta informação\n" +" list-schemas Lista os esquemas instalados\n" +" list-relocatable-schemas Lista os esquemas realocáveis\n" +" list-keys Lista as chaves em um esquema\n" +" list-children Lista os filhos de um esquema\n" +" list-recursively Lista as chaves e valores, recursivamente\n" +" range Consulta o intervalo de uma chave\n" +" describe Consulta a descrição de uma chave\n" +" get Obtém o valor de uma chave\n" +" set Define o valor de uma chave\n" +" reset Redefine o valor de uma chave\n" +" reset-recursively Restaura todas as chaves em um determinado " +"esquema\n" +" writable Verifica se uma chave é gravável\n" +" monitor Monitora alterações\n" +"\n" +"Use “gsettings help COMANDO†para obter ajuda detalhada.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uso:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR Um diretório para procurar por esquemas adicionais\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" ESQUEMA O nome do esquema\n" +" CAMINHO O caminho, para esquemas recolocáveis\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " CHAVE A chave (opcional) com o esquema\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " CHAVE A chave com o esquema\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALOR O valor para definir\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Não foi possível carregar esquemas de %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nenhum esquema instalado\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Nome de esquema vazio\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Nenhuma chave “%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Soquete inválido, não inicializado" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Soquete inválido, inicialização falhou devido a: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "O soquete já está fechado" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Tempo de E/S do soquete foi esgotado" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "criando GSocket a partir do fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Não é possível criar soquete: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Foi especificada uma família desconhecida" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Foi especificado um protocolo desconhecido" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Não foi possível usar operações de datagrama em um soquete não-datagrama." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Não foi possível usar operações de datagrama em um soquete com um tempo " +"limite definido." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "não foi possível obter endereço local: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "não foi possível obter endereço remoto: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "não foi possível escutar: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Erro ao vincular ao endereço %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Erro ao entrar no grupo multicast: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Erro ao sair do grupo multicast: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Não há suporte para multicast específico da origem" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Família de soquete sem suporte" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "a origem específica não é um endereço IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Nome de interface grande demais" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Interface não localizada: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Não há suporte para multicast específico da origem IPv4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Não há suporte para multicast específico da origem IPv6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Erro ao aceitar a conexão: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Conexão em progresso" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Não é possível obter erro pendente: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Erro ao receber dados: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Erro ao enviar dados: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Não é possível encerrar soquete: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Erro ao fechar soquete: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Aguardando pela condição do soquete: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Não foi possível enviar mensagem: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vetores da mensagem muito grandes" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Erro ao enviar mensagem: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "Não há suporte a GSocketControlMessage no Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Erro ao receber mensagem: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Não é possível ler as credenciais do soquete: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials não está implementado para este SO" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Não foi possível conectar-se ao servidor proxy %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Não foi possível conectar-se a %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Não foi possível conectar: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Não há suporte ao uso de proxy sobre uma conexão não TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Não há suporte ao protocolo de proxy “%sâ€." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "O ouvinte já está fechado" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "O soquete adicionado está fechado" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "Não há suporte ao endereço IPv6 “%s†pelo SOCKSv4" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "O nome de usuário é muito longo para o protocolo SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "O nome de máquina “%s†é muito longo para o protocolo SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "O servidor não é um servidor proxy SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "A conexão ao servidor por meio de SOCKSv4 foi rejeitada" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "O servidor não é um servidor proxy SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "O proxy SOCKSv5 requer autenticação." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "O SOCKSv5 requer um método de autenticação sem suporte pelo GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"O nome de usuário ou a senha são muito longos para o protocolo SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"A autenticação SOCKSv5 falhou devido a um nome de usuário ou senha errados." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "O nome de máquina “%s†é muito longo para o protocolo SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "O servidor proxy SOCKSv5 está usando um tipo de endereço desconhecido." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Erro interno de servidor proxy SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "A conexão SOCKSv5 não foi permitida pelo conjunto de regras." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Servidor inalcançável por meio do servidor SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Rede inalcançável por meio do proxy SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Conexão recusada por meio do proxy SOCKSv5." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Proxy SOCKSv5 sem suporte ao comando “connectâ€." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Proxy SOCKSv5 sem suporte ao tipo de endereço fornecido." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Erro de proxy SOCKSv5 desconhecido." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Falha ao criar canal para comunicar com processo filho (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Não há suporte a canais nesta plataforma" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Não é possível lidar com a versão %d da codificação GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Nenhum endereço válido foi localizado" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Erro ao resolver reversalmente “%sâ€: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Erro ao analisar registro %s do DNS: pacote DNS mal formado" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Nenhum registro DNS do tipo de requisição para “%sâ€" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Temporariamente sem condições de resolver “%sâ€" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Erro ao resolver “%sâ€" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Pacote DNS mal formado" + +#: gio/gthreadedresolver.c:886 +#, c-format +#| msgid "Failed to read from file “%sâ€: %s" +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Falha ao analisar resposta DNS para “%sâ€: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Chave privada codificada com PEM não localizada" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Não foi possível decodificar uma chave privada codificada com PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Não foi possível analisar chave privada codificada com PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Certificado codificado com PEM não localizado" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Não foi possível analisar certificado codificado com PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "O backend TLS atual não oferece suporte a PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" +"Este GTlsBackend não oferece suporte à criação de certificados PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Esta é a última chance para digitar a senha corretamente antes de seu acesso " +"ser bloqueado." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Várias das senhas digitadas estavam incorretas, e o seu acesso será " +"bloqueado se houverem mais falhas." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "A senha digitada está incorreta." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Não há suporte ao envio de FD" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Esperando 1 mensagem de controle, obtive %d" +msgstr[1] "Esperando 1 mensagem de controle, obtive %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Tipo de dado auxiliar não esperado" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Esperando um fd, mas obtive %d\n" +msgstr[1] "Esperando um fd, mas obtive %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Recebido fd inválido" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Não há suporte ao recebimento de FD" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Erro ao enviar credenciais: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Erro ao verificar se SO_PASSCRED está habilitado pelo soquete: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Erro ao habilitar SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Era esperado ler apenas um byte para receber credenciais, mas foi lido zero " +"byte" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Não esperava mensagem de controle, mas recebeu %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Erro ao desabilitar SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Erro ao ler do descritor de arquivo: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Erro ao fechar o descritor de arquivo: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Sistema de arquivos root" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Erro ao gravar o descritor de arquivo: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Não há suporte a endereços de soquetes de domínio UNIX abstratos neste " +"sistema" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "volume não implementa ejetar" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volume não implementa eject ou eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Erro ao ler do manipulador: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Erro ao fechar manipulador: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Erro ao gravar o manipulador: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Memória insuficiente" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Erro interno: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Precisa de mais entrada" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Dados comprimidos inválidos" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Endereço para escutar" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorado, para compatibilidade com GTesTDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Exibe o endereço" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Imprime endereço no modo shell" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Executa um serviço dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Args. incorretos\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Atributo “%s†inesperado para o elemento “%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atributo “%s†do elemento “%s†não localizado" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Marca “%s†inesperada, esperava marca “%sâ€" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Marca “%s†inesperada dentro de “%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Data/hora “%s†inválida no arquivo de marcadores" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Nenhum arquivo de marcadores válido foi localizado nos diretórios de dados" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Já existe um marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nenhum marcador localizado para o URI “%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Não foi definido tipo MIME no marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Não foi definido sinal de particular no marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Não há grupos definidos no marcador para o URI “%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Nenhum aplicativo chamado “%s†registrou um marcador para “%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Falha em expandir linha de execução “%s†com URI “%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Caractere não representável na conversão da entrada" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Sequência de caracteres parcial no final da entrada" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" +"Não é possível converter a sequência “%s†para conjunto caracteres “%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Byte NULO embutido na entrada de conversão" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Byte NULO embutido na saída de conversão" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "O URI “%s†não é um URI absoluto que utilize o esquema “fileâ€" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "O URI de arquivo local “%s†não pode incluir um “#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "O URI “%s†é inválido" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "O nome de máquina do URI “%s†é inválido" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "O URI “%s†contém caracteres com escape inválido" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "O nome de caminho “%s†não é um caminho absoluto" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d de %b %H:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "janeiro" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "fevereiro" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "março" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "abril" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "maio" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "junho" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "julho" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "agosto" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "setembro" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "outubro" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "novembro" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "dezembro" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "fev" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "abr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "maio" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ago" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "set" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "out" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "dez" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "segunda-feira" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "terça-feira" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "quarta-feira" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "quinta-feira" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "sexta-feira" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sábado" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "domingo" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "seg" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ter" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "qua" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "qui" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "sex" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sáb" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "dom" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "janeiro" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "fevereiro" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "março" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "abril" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "maio" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "junho" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "julho" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "agosto" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "setembro" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "outubro" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "novembro" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "dezembro" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "fev" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "abr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "maio" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ago" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "set" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "out" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dez" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Erro ao abrir o diretório “%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Não foi possível alocar %lu byte para ler arquivo “%sâ€" +msgstr[1] "Não foi possível alocar %lu bytes para ler arquivo “%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Ocorreu erro ao ler arquivo “%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Arquivo “%s†é muito grande" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Falha ao ler do arquivo “%sâ€: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Falha ao abrir arquivo “%sâ€: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Falha ao obter atributos do arquivo “%sâ€: fstat() falhou: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Falha ao abrir arquivo “%sâ€: fdopen() falhou: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Falha ao renomear arquivo “%s†para “%sâ€: g_rename() falhou: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Falha ao gravar o arquivo “%sâ€: write() falhou: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Falha ao gravar o arquivo “%sâ€: fsync() falhou: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Falha ao criar arquivo “%sâ€: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "O arquivo “%s†não pôde ser removido: g_unlink() falhou: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Modelo “%s†inválido, não deveria conter um “%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Modelo “%s†não contém XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Falha ao ler link simbólico “%sâ€: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Não foi possível abrir conversor de “%s†para “%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Não é possível fazer uma leitura em bruto em g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Dados residuais não convertidos no buffer de leitura" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Canal termina em um caractere parcial" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Não é possível fazer uma leitura em bruto de g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Não foi possível localizar arquivo de chave válido nos diretórios pesquisados" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Não é um arquivo comum" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Arquivo de chave contém a linha “%s†que não é um par chave-valor, grupo ou " +"comentário" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nome de grupo inválido: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Arquivo de chave não começa com um grupo" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nome de chave inválido: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Arquivo de chave contém codificação “%s†sem suporte" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Arquivo de chave não tem grupo “%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Arquivo de chave não tem chave “%s†no grupo “%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Arquivo de chave contém chave “%s†com valor “%s†que não é UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Arquivo de chave contém chave “%s†cujo valor não pode ser interpretado." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Arquivo de chave contém chave “%s†no grupo “%s†que tem um valor que não " +"pode ser interpretado." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Chave “%s†no grupo “%s†tem o valor “%s†onde %s era esperado" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Arquivo de chave contém caractere de escape no fim da linha" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Arquivo de chave contém sequência de escape “%s†inválida" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "O valor “%s†não pode ser interpretado como um número." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Valor inteiro “%s†fora dos limites" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "O valor “%s†não pode ser interpretado como ponto flutuante." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "O valor “%s†não pode ser interpretado como um booleano." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Falha ao obter atributos do arquivo “%s%s%s%sâ€: fstat() falhou: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Falha ao mapear arquivo “%s%s%s%sâ€: mmap() falhou: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Falha ao abrir arquivo “%sâ€: open() falhou: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Erro na linha %d caractere %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Texto do nome codificado em UTF-8 inválido — “%s†não válido" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†não é um nome válido" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†não é um nome válido: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Erro na linha %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Falha ao analisar “%-.*sâ€, que deveria ter sido um dígito dentro de uma " +"referência de caractere (ê por exemplo) — talvez o dígito seja grande " +"demais" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Referência de caractere não terminou com um ponto e vírgula; provavelmente " +"utilizou um caractere “e comercial†sem desejar iniciar uma entidade — " +"escape-o com &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Referência de caractere “%-.*s†não codifica um caractere permitido" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Entidade “&;†vazia; as entidades válidas são: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Nome de entidade “%-.*s†não é conhecido" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entidade não termina com um ponto e vírgula; provavelmente você utilizou um " +"“e comercial†sem desejar iniciar uma entidade — escape-o com &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Documento tem de começar com um elemento (ex. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“%s†não é um caractere válido após um caractere “<â€; não poderá começar um " +"nome de elemento" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Caractere estranho “%sâ€, esperado um caractere “>†para finalizar a marca " +"“%s†de elemento vazio" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Número excessivo de atributos no elemento “%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Caractere estranho “%sâ€, esperava-se um “=†após o nome do atributo “%s†do " +"elemento “%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Caractere estranho “%sâ€, esperava-se um caractere “>†ou “/†para terminar a " +"marca inicial do elemento “%sâ€, ou opcionalmente um atributo; talvez tenha " +"utilizado um caractere inválido no nome de atributo" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Caractere estranho “%sâ€, esperava-se uma abertura de aspas após o sinal de " +"igual ao atribuir o valor ao atributo “%s†do elemento “%sâ€" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%s†não é um caractere válido após o nome do elemento de fecho “%sâ€; o " +"caractere permitido é “>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Elemento “%s†foi fechado, nenhum elemento está atualmente aberto" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Elemento “%s†foi fechado, mas o elemento atualmente aberto é “%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Documento estava vazio ou apenas continha espaços" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Documento terminou inesperadamente logo após um menor que “<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Documento terminou inesperadamente com elementos ainda abertos — “%s†foi o " +"último elemento aberto" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Documento terminou inesperadamente, esperava-se ver um sinal de maior (“>â€) " +"para terminar a marca <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Documento terminou inesperadamente dentro de um nome de elemento" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Documento terminou inesperadamente dentro de um nome de atributo" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Documento terminou inesperadamente dentro de uma marca de abertura de " +"elemento." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Documento terminou inesperadamente após o sinal de igual que se seguiu a um " +"nome de atributo; nenhum valor de atributo" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Documento terminou inesperadamente dentro de um valor de atributo" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Documento terminou inesperadamente dentro da marca de fechamento do elemento " +"“%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Documento terminou inesperadamente dentro da marca de um elemento não aberto" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Documento terminou inesperadamente dentro de um comentário ou instrução de " +"processamento" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPÇÃO…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Opções de ajuda:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Mostra opções de ajuda" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Mostra todas as opções de ajuda" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Opções de aplicativo:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Opções:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Não é possível converter o valor inteiro “%s†para %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Valor inteiro “%s†para %s fora dos limites" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "" +"Não é possível converter o ponto flutuante com dupla precisão “%s†para %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Ponto flutuante com dupla precisão “%s†para %s fora dos limites" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Erro ao ler a opção %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Falta argumento para %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Opção %s desconhecida" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "objeto corrompido" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "erro interno ou objeto corrompido" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "memória insuficiente" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "limite de backtracking alcançado" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "o padrão contém itens sem suporte para correspondência parcial" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "erro interno" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"não há suporte à referência retroativa como condição para correspondência " +"parcial" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "limite de recursão alcançado" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "combinação inválida de sinalizador de nova linha" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "deslocamento ruim" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 curto" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "recursão infinita" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "erro desconhecido" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ no fim do padrão" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c no fim do padrão" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "caractere não reconhecido seguindo \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "números fora de ordem no quantificador {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "número grande demais no quantificador {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "terminação ] em falta para classe de caracteres" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "sequência de escape inválida na classe de caracteres" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "intervalo fora de ordem na classe de caracteres" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nada a repetir" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "repetição inesperada" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "caractere não reconhecido após (? ou (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "Classes nomeadas POSIX têm suporte apenas dentro de uma classe" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "faltando terminação )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referência a subpadrão não existente" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "faltando ) após o comentário" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "expressão regular é grande demais" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "falha ao obter memória" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") sem abrir (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "estouro de código" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "caractere não reconhecido após (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "declaração de verificação anterior não é de largura fixa" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "número mal formado ou nome após (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "grupo condicional contém mais que duas ramificações" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "esperava-se declaração após (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ou (?[+-]dígitos devem ser seguidos por )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nome de classe POSIX desconhecido" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "Elementos de arranjo POSIX sem suporte" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "valor de caractere na sequência \\x{...} é grande demais" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condição inválida (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C não permitido na declaração de verificação anterior" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "não há suporte a escapes \\L, \\l, \\N{nome}, \\U e \\u" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "chamada recursiva pode causar uma repetição indefinidamente" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "caractere não reconhecido após (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "terminação em falta no nome do subpadrão" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dois subpadrões nomeados têm o mesmo nome" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "sequência \\P ou \\p mal formada" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nome de propriedade desconhecido após \\P ou \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "nome de subpadrão é grande demais (máximo 32 caracteres)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "excesso de subpadrões nomeados (máximo 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "valor octal é maior que \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "espaço de trabalho de compilação invadido" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "subpadrão de referência verificado anteriormente não localizado" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "O grupo DEFINE contém mais que uma ramificação" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opções do NEWLINE inconsistentes" + +# obs.: "angle-brackets" não existe no Brasil, mas existe brackets, que é '<' e '>' +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g não é seguido por um número ou nome entre aspas, chaves ou sinais de " +"menor que ou maior que um número diferente de zero opcionalmente entre chaves" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "uma referência numerada não pode ser zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "um argumento não é permitido para (*ACCEPT), (*FAIL) ou (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) não reconhecido" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "número é muito grande" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "faltando o nome do subpadrão após (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "esperava-se dígito após (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] é um caractere de dados inválido no modo de compatibilidade do JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "não é permitido dois subpadrões nomeados com o mesmo nome" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) deve possuir um argumento" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c pode ser seguido por um caractere ASCII" + +# obs.: "angle-brackets" não existe no Brasil, mas existe brackets, que é '<' e '>' +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k não é seguido por um nome entre aspas, chaves ou sinais de menor que ou " +"maior que" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N não é suportado em uma classe" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "muitas referências de encaminhamento" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "nome é muito cumprido em (*MARK), (*PRUNE), (*SKIP) ou (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "valor de caractere na sequência \\u.... é grande demais" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Erro ao coincidir expressão regular %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Biblioteca PCRE compilada sem suporte a UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Biblioteca PCRE compilada sem suporte às propriedades UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Biblioteca PCRE compilada com opções incompatíveis" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Erro ao otimizar expressão regular %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Erro ao compilar expressão regular %s no caractere %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "esperava-se dígito hexadecimal ou “}â€" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "esperava-se dígito hexadecimal" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "“<†em falta na referência simbólica" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "referência simbólica inacabada" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "referência simbólica de comprimento zero" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "esperava-se dígito" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "referência simbólica ilegal" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "“\\†final errado" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "sequência de escape desconhecida" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Erro ao analisar texto de substituição “%s†no caractere %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Texto citado não começa com uma aspa" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Aspa sem par na linha de comando ou outro texto de console" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Texto terminou logo após um caractere “\\â€. (O texto era “%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Texto terminou antes da aspa equivalente ter sido localizada para %c. (texto " +"era “%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Texto estava vazio (ou apenas continha espaços)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Falha ao ler dados de processo filho (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Erro inesperado na leitura de dados de um processo filho (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Erro inesperado em waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Processo filho concluiu com código %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Processo filho foi terminado pelo sinal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Processo filho foi parado pelo sinal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Processo filho concluiu anormalmente" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Falha ao ler de canal filho (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Falha ao criar processo filho “%s†(%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Falha no fork (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Falha ao ir para diretório “%s†(%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Falha ao executar processo filho “%s†(%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Falha ao abrir o arquivo para remapear o descritor de arquivo (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Falha ao duplicar o descritor de arquivo para o processo filho (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Falha no fork de processo filho (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Falha ao fechar o descritor de arquivo para o processo filho (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Erro desconhecido ao executar processo filho “%sâ€" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Falha ao ler dados suficientes de canal pid do filho (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Falha ao ler dados de processo filho" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Falha ao executar processo filho (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Falha em dup() no processo filho (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nome de programa inválido: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "String inválida no vetor de argumentos em %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "String inválida no ambiente: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Diretório de trabalho inválido: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Falha ao executar programa auxiliar (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Erro inesperado no g_io_channel_win32_poll() ao ler dados de um processo " +"filho" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Texto vazio não é um número" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†não é um número assinado" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "O número “%s†está fora dos limites [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†não é um número não assinado" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-encoding inválida na URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Caractere ilegal na URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caracteres não UTF-8 na URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Endereço IPv6 “%.*s†inválido na URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Endereço IP “%.*s†codificado ilegal na URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nome de máquina internacionalizado ilegal “%.*s†na URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Não foi possível analisar a porta “%.*s†na URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "A porta “%.*s†na URI está fora dos limites" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "A URI “%s†não é uma URI absoluta" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "A URI “%s†possui nenhum componente de host" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "A URI não é absoluta, e nenhuma URI base foi fornecida" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Faltando “=†e valor de parâmetro" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Falha ao alocar memória" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Caractere fora do limite para UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Sequência inválida na conversão da entrada" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Caractere fora do limite para UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u bytes" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bits" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s bytes" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bits" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "Não foi possível carregar /var/lib/dbus/machine-id ou /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Erro desconhecido ao conectar" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Erro no endereço “%s†— o atributo família está malformada" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "Montado %s em %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; ignorando sobrescrita para esta chave.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " e --strict foi especificado; saindo.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Ignorando sobrescrita para esta chave.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "fazendo nada.\n" + +#~ msgid "No such method '%s'" +#~ msgstr "Método “%s†inexistente" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Não foi possível determinar o endereço de barramento da variável de " +#~ "ambiente DBUS_STARTER_BUS_TYPE - valor desconhecido “%sâ€" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGUMENTOS…]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Falha ao criar um arquivo temporário: %s" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "A mensagem possui %d descritores de arquivos, mas o campo de cabeçalho " +#~ "indica %d descritores de arquivos" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Erro: caminho do objeto não especificado.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Erro: sinal não especificado.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Erro: sinal deve ser o nome completamente qualificado.\n" + +#~ msgid "No such interface" +#~ msgstr "Nenhuma interface" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Erro ao obter atributos graváveis: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Erro ao montar o local: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Erro ao desmontar a montagem: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Erro ao localizar a montagem: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Erro ao ejetar a montagem: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Erro ao montar %s: %s\n" + +#~ msgid "No files to open" +#~ msgstr "Nenhum arquivo para abrir" + +#~ msgid "No files to delete" +#~ msgstr "Nenhum arquivo para excluir" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Erro ao definir o atributo: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Erro ao criar o diretório \"%s\": %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Erro ao abrir arquivo \"%s\": %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Erro ao ler arquivo \"%s\": %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Erro ao renomear arquivo: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Erro ao abrir arquivo: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Erro ao criar o diretório: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "não há suporte às alterações de associação em win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Não há suporte à criação de associação em win32" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Não é possível localizar o tipo de diretório monitor local padrão" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Arquivo de chave não tem chave \"%s\"" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "Ocorreu erro ao processar o arquivo de entrada com o xmllint:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "Ocorreu erro ao processar o arquivo de entrada com o to-pixdata:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "Não é possível obter erro pendente: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Falha ao abrir arquivo \"%s\" para escrita: fdopen() falhou: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Falha ao escrever no arquivo \"%s\": fflush() falhou: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Falha ao fechar arquivo \"%s\": fclose() falhou: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "Dados incompletos recebidos para \"%s\"" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Tamanho inesperado de opção ao verificar se SO_PASSCRED está habilitado " +#~ "pelo soquete. Esperado %d bytes, mas obteve %d" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "" +#~ "Término anormal de programa ao chamar a linha de comandos \"%s\": %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "" +#~ "A linha de comandos \"%s\" saiu com status de saída não-zero, %d: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "Nenhum serviço de registro para \"%s\"" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "limite de espaço de trabalho para substrings vazias alcançado" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "escapes de alteração de maiusculização (\\l, \\L, \\u, \\U) não são " +#~ "permitidos aqui" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "repetição de um grupo DEFINE não é permitida" + +#~ msgid "File is empty" +#~ msgstr "Arquivo vazio" + +#~ msgid "This option will be removed soon." +#~ msgstr "Esta opção será removida logo." + +#~ msgid "Error connecting: " +#~ msgstr "Erro ao conectar: " + +#~ msgid "Error connecting: %s" +#~ msgstr "Erro ao conectar: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "A implementação SOCKSv4 limita o nome de usuário a %i caracteres" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "" +#~ "A implementação SOCKSv4a limita o nome de servidor para %i caracteres" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Erro ao ler do unix: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Erro ao escrever para unix: %s" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "Arquivo de chave contém chave \"%s\" que tem valor que não pode ser " +#~ "interpretado." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Erro ao iniciar arquivo \"%s\": %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "am" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "" +#~ "O tipo do valor de retorno está incorreto, obtido \"%s\", era esperado " +#~ "\"%s\"" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "Tentando definir a propriedade %s do tipo %s, mas de acordo com a " +#~ "interface esperada o tipo é %s" + +#~ msgid "No such schema '%s' specified in override file '%s'" +#~ msgstr "Nenhum esquema \"%s\" especificado no arquivo de sobrescrita \"%s\"" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "Comandos:\n" +#~ " help Mostra esta informação\n" +#~ " get Obtém o valor de uma chave\n" +#~ " set Define o valor de uma chave\n" +#~ " reset Restaura o valor de uma chave\n" +#~ " monitor Monitora uma chave por alterações\n" +#~ " writable Verifica se uma chave é gravável\n" +#~ "\n" +#~ "Use '%s COMANDO --help' para obter ajuda para comando individuais.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "Especificar o caminho para um esquema" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "Argumentos:\n" +#~ " ESQUEMA A identificação do esquema\n" +#~ " CHAVE O nome da chave\n" +#~ " VALOR O valor para definir na chave, como um GVariant " +#~ "serializado\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "Monitorar CHAVE por alterações e exibir os valores alterados.\n" +#~ "O monitoramento continuará até que o processo seja terminado." diff --git a/po/ro.po b/po/ro.po new file mode 100644 index 0000000..0792344 --- /dev/null +++ b/po/ro.po @@ -0,0 +1,6625 @@ +# Romanian translation for glib +# Copyright (C) 2001 - 2010 Free Software Foundation, Inc. +# Marius Andreiana , 2001. +# MiÈ™u Moldovan , 2004 - 2010. +# Lucian Adrian Grijincu , 2010, 2011. +# Lupescu Mircea , 2010. +# Lupescu Mircea , 2011. +# Daniel Șerbănescu , 2017. +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-02-19 13:43+0000\n" +"PO-Revision-Date: 2022-03-06 12:47+0100\n" +"Last-Translator: Daniel Șerbănescu \n" +"Language-Team: Gnome Romanian Translation Team \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " +"20)) ? 1 : 2);\n" +"X-Generator: Poedit 3.0.1\n" +"X-Project-Style: gnome\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Stabilirea aplicaÈ›iilor implicite nu este suportată încă" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Stabilirea aplicaÈ›iei ca ultima folosită pentru acest tip nu este suportată" + +#: gio/gapplication.c:497 +msgid "GApplication options" +msgstr "OpÈ›iuni GApplication" + +#: gio/gapplication.c:497 +msgid "Show GApplication options" +msgstr "Arată opÈ›iunile GApplication" + +#: gio/gapplication.c:542 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Intră în modul de serviciu GApplication (utilizează de la fiÈ™ierele de " +"serviciu D-Bus)" + +#: gio/gapplication.c:554 +msgid "Override the application’s ID" +msgstr "Suprascrie ID-ul aplicaÈ›iei" + +#: gio/gapplication.c:566 +msgid "Replace the running instance" +msgstr "ÃŽnlocuieÈ™te instanÈ›a care rulează" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "AfiÈ™ează ajutorul" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[COMANDÄ‚]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "TipăreÈ™te versiunea" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "AfiÈ™ează informaÈ›iile despre versiune È™i ieÈ™i" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Listează aplicaÈ›iile" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "Listează aplicaÈ›iile D-Bus care se pot activa (după fiÈ™iere .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Lansează o aplicaÈ›ie" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Lansează aplicaÈ›ia (cu fiÈ™iere opÈ›ionale de deschis)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FIȘIER…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Activează o acÈ›iune" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Invocă o acÈ›iune pe aplicaÈ›ie" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ACÈšIUNE APPID [PARAMETRU]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Listează acÈ›iunile disponibile" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Listează acÈ›iuni statice pentru o aplicaÈ›ie (din fiÈ™ierul .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "COMANDÄ‚" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Comanda pentru care să se afiÈ™eze ajutorul detaliat" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Identificatorul de aplicaÈ›ie în format D-Bus (eg: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FIȘIER" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Calea relativă sau absolută a fisierelor, sau URIs pentru deschidere" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACÈšIUNE" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Numele acÈ›iunii de invocat" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETRU" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Parametru opÈ›ional pentru invocarea acÈ›iunii, în formatul GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Comandă necunoscută %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Utilizare:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumente:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTE…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Comenzi:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"UtilizaÈ›i „%s help COMANDÆpentru a obÈ›ine ajutor detaliat.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"comanda %s trebuie să fie urmată imediat de un id de aplicaÈ›ie\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "id de aplicaÈ›ie nevalid: „%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"„%s†nu ia argumente\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "nu se poate conecta la D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "eroare la trimiterea mesajului %s la aplicaÈ›ia: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "numele acÈ›iunii trebuie introdus după id-ul aplicaÈ›iei\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"nume de acÈ›iune nevalid „%sâ€\n" +"numele de acÈ›iuni trebuie să fie formate doar din caractere alfanumerice, " +"„-†și „.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "eroare la parsarea parametrului: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "acÈ›iunile acceptă maximum un parametru\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "comanda list-actions ia numai id-ul aplicaÈ›iei" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "nu se poate găsi fiÈ™ierul desktop pentru aplicaÈ›ia %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"comandă nerecunoscută: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "S-a pasat o valoare prea mare către %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Căutarea în fluxul de bază nu este suportată" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Nu se poate trunchia GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Flux deja închis" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Trunchierea fluxului de bază nu este suportată" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1873 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "OperaÈ›iunea a fost anulată" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Obiect nevalid, neiniÈ›ializat" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Secvență de octeÈ›i incompletă la intrare" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "SpaÈ›iu insuficient în destinaÈ›ie" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Secvență de octeÈ›i incorectă în inputul conversiei" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Eroare în timpul conversiei: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "IniÈ›ializarea întreruptibilă nu este implementată" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Conversia de la setul de caractere „%s†la „%s†nu este suportată" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Nu s-a putut deschide convertorul de la „%s†la „%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "tip %s" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Tip necunoscută" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "tip de fiÈ™ier %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials conÈ›ine date nevalide" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials nu este implementat pe acest SO" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Nu există suport pentru GCredentials pe platforma dumneavoastră" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials nu conÈ›ine un ID de proces pe acest SO" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Spoofing-ul certificărilor nu este posibil pe acest SO" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Flux terminat neaÈ™teptat de repede" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Cheie „%s†nesuportată în intrarea de adresă „%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Pereche cheie/valoare fără sens în intrarea de adresă „%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adresa „%s†nu este validă (este nevoie de exact una din cale, dir, tmpdir " +"sau chei abstracte)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Eroare în adresa „%s†— atributul „%s†este malformat" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transport „%s†necunoscut sau nesuportat pentru adresa „%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Elementul de adresă „%s†nu conÈ›ine două puncte (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Numele de transport în elementul de adresă „%s†nu trebuie să fie gol" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Perechea cheie/valoare %d, „%sâ€, în elementul de adresă „%sâ€, nu conÈ›ine un " +"semn de egalitate" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Perechea cheie/valoare %d, „%sâ€, în elementul de adresă „%sâ€, nu trebuie să " +"aibă o cheie goală" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Eroare la conversia din formatul „escaped†a cheii sau a valorii din " +"perechea cheie/valoare %d, „%sâ€, în elementul de adresă „%sâ€" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Eroare în adresa „%s†- transportul unix necesită exact una din cheile " +"„path†sau „abstract†să fie stabilită" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Eroare în adresa „%s†- atributul gazdă lipseÈ™te sau este eronat" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Eroare la adresa „%s†- atributul port lipseÈ™te sau este eronat" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "Eroare în adresa „%s†- atributul noncefile lipseÈ™te sau este eronat" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Eroare la auto-lansare: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Eroare la deschiderea fiÈ™ierului nonce „%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Eroare la citirea din fiÈ™ierul nonce „%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Eroare la citirea din fiÈ™ierul nonce „%sâ€, se aÈ™teptau 16 octeÈ›i, s-au " +"primit %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Eroare la scrierea conÈ›inutului fiÈ™ierului nonce „%s†la flux:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Adresa oferită este goală" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Nu se poate lansa o magistrală de mesaje când AT_SECURE este stabilit" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" +"Nu se poate lansa o magistrală de mesaje fără un identificator de maÈ™ină: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Nu se poate lansa automat D-Bus fără $DISPLAY X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Eroare la crearea liniei de comandă „%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Nu se poate determina adresa magistralei de sesiune (neimplementat pe acest " +"sistem de operare)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7334 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Nu se poate determina adresa magistralei din variabila de mediu " +"DBUS_STARTER_BUS_TYPE — valoare necunoscută „%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7343 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Nu s-a putut determina adresa magistralei pentru că variabila de mediu " +"DBUS_STARTER_BUS_TYPE nu este setată" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Tip de magistrală %d necunoscut" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Lipsă de conÈ›inut neaÈ™teptată în timp ce se încerca citirea unei linii" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"Lipsă de conÈ›inut neaÈ™teptată în timp ce se încerca citirea (în siguranță a) " +"unei linii" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"S-au epuizat toate mecanismele de autentificare disponibile (încercat: %s) " +"(disponibile: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "" +"ID-urile utilizatorului trebuie să fie aceleaÈ™i pentru client È™i server" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Anulat via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Eroare în timpul obÈ›inerii de informaÈ›ii pentru directorul „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:314 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Permisiunile pentru dosarul „%s†sunt eronate. Se aÈ™tepta modul 0700, s-a " +"primit 0%o" + +#: gio/gdbusauthmechanismsha1.c:347 gio/gdbusauthmechanismsha1.c:358 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Eroare la crearea directorului „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:360 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "OperaÈ›iune neimplementată" + +#: gio/gdbusauthmechanismsha1.c:403 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Eroare la deschiderea inelului de chei „%s†pentru citire: " + +#: gio/gdbusauthmechanismsha1.c:426 gio/gdbusauthmechanismsha1.c:748 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Linia %d a inelului de chei de la „%s†cu conÈ›inutul „%s†este eronată" + +#: gio/gdbusauthmechanismsha1.c:440 gio/gdbusauthmechanismsha1.c:762 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Primul jeton al liniei %d a inelului de chei de la „%s†cu conÈ›inutul „%s†" +"este eronat" + +#: gio/gdbusauthmechanismsha1.c:454 gio/gdbusauthmechanismsha1.c:776 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Al doilea jeton al liniei %d a inelului de chei de la „%s†cu conÈ›inutul " +"„%s†este eronat" + +#: gio/gdbusauthmechanismsha1.c:478 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Nu s-a găsit un cookie cu id-ul %d în inelul de chei de la „%sâ€" + +#: gio/gdbusauthmechanismsha1.c:524 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Eroare la crearea fiÈ™ierului de blocare „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:588 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Eroare la È™tergerea fiÈ™ierului de blocare învechit „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:627 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Eroare la închiderea fiÈ™ierului de blocare (deconectat) „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:638 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Eroare la deconectarea fiÈ™ierului de blocare „%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:715 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Eroare la deschiderea inelului de chei „%s†pentru citire: " + +#: gio/gdbusauthmechanismsha1.c:909 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(AdiÈ›ional, a eÈ™uat È™i eliberarea blocării pentru „%sâ€: %s) " + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2418 +msgid "The connection is closed" +msgstr "Conexiunea este închisă" + +#: gio/gdbusconnection.c:1903 +msgid "Timeout was reached" +msgstr "Limita de timp a fost atinsă" + +#: gio/gdbusconnection.c:2541 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"S-au întâlnit fanioane nesuportate când se construia partea de client a " +"conexiunii" + +#: gio/gdbusconnection.c:4269 gio/gdbusconnection.c:4623 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Nu există interfaÈ›a „org.freedesktop.DBus.Properties†în obiectul de la " +"calea %s" + +#: gio/gdbusconnection.c:4414 +#, c-format +msgid "No such property “%sâ€" +msgstr "Nu există proprietatea „%sâ€" + +#: gio/gdbusconnection.c:4426 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Proprietatea „%s†nu poate fi citită" + +#: gio/gdbusconnection.c:4437 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Proprietatea „%s†nu poate fi scrisă" + +#: gio/gdbusconnection.c:4457 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Eroare la stabilirea proprietății „%sâ€: Se aÈ™tepta tipul „%sâ€, dar s-a " +"primit „%sâ€" + +#: gio/gdbusconnection.c:4562 gio/gdbusconnection.c:4777 +#: gio/gdbusconnection.c:6760 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Nu există interfaÈ›a „%sâ€" + +#: gio/gdbusconnection.c:4999 gio/gdbusconnection.c:7274 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Nu există interfaÈ›a „%s†în obiectul de la calea %s" + +#: gio/gdbusconnection.c:5100 +#, c-format +msgid "No such method “%sâ€" +msgstr "Nu există metoda „%sâ€" + +#: gio/gdbusconnection.c:5131 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Tipul de mesaj, „%sâ€, nu se potriveÈ™te cu cel aÈ™teptat „%sâ€" + +#: gio/gdbusconnection.c:5334 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Există deja un obiect exportat pentru interfaÈ›a %s de la %s" + +#: gio/gdbusconnection.c:5561 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Nu se poate obÈ›ine proprietatea %s.%s" + +#: gio/gdbusconnection.c:5617 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Nu se poate stabili proprietatea %s.%s" + +#: gio/gdbusconnection.c:5796 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metoda „%s†a întors tipul „%sâ€, dar se aÈ™tepta „%sâ€" + +#: gio/gdbusconnection.c:6872 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metoda „%s†din interfaÈ›a „%s†cu semnătura „%s†nu există" + +#: gio/gdbusconnection.c:6993 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Un subarbore este deja exporta pentru %s" + +#: gio/gdbusconnection.c:7282 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Obiectul nu există la calea „%sâ€" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "tipul este NEVALID" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" +"Mesaj METHOD_CALL: unul din câmpurile de antet PATH sau MEMBER lipseÈ™te" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Mesaj METHOD_RETURN: câmpul antet REPLY_SERIAL lipseÈ™te" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Mesaj de EROARE: unul din câmpurile de antet REPLY_SERIAL sau ERROR_NAME " +"lipseÈ™te" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Mesaj SIGNAL: unul din câmpurile de antet PATH, INTERFACE sau MEMBER lipseÈ™te" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Mesaj SIGNAL: câmpul de antet PATH utilizează valoarea rezervată /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Mesaj SIGNAL: câmpul de antet INTERFACE utilizează valoarea rezervată org." +"freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "S-a încercat să se citească %lu octet, dar s-a primit doar %lu" +msgstr[1] "S-a încercat să se citească %lu octeÈ›i, dar s-au primit doar %lu" +msgstr[2] "S-a încercat să se citească %lu de octeÈ›i, dar s-au primit doar %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "S-a aÈ™teptat un octet NUL după È™irul „%sâ€, dar s-a găsit octetul %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Se aÈ™tepta un È™ir UTF-8 valid, dar s-au găsit octeÈ›i nevalizi la decalajul " +"%d (lungimea È™irului este %d). Șirul UTF-8 valid până la acel punct a fost " +"„%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Valoare imbricată prea adânc" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Valoarea parsată „%s†nu este o cale de obiect D-Bus validă" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Valoarea parsată „%s†nu este o semnătură D-Bus validă" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"S-a întâlnit un È™ir cu lungimea de %u octet. Lungimea maximă este de 2<<26 " +"de octeÈ›i (64 MiB)." +msgstr[1] "" +"S-a întâlnit un È™ir cu lungimea de %u octeÈ›i. Lungimea maximă este de 2<<26 " +"de octeÈ›i (64 MiB)." +msgstr[2] "" +"S-a întâlnit un È™ir cu lungimea de %u de octeÈ›i. Lungimea maximă este de " +"2<<26 de octeÈ›i (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"S-a întâlnit un È™ir de tipul „a%câ€, se aÈ™tepta să aibă o lungime un multiplu " +"de %u octeÈ›i, dar s-a constatat că are o lungime de %u octeÈ›i" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Structuri goale (tuple) nu sunt permise în D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Valoarea parsată „%s†pentru variantă nu este o semnătură D-Bus validă" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Eroare la deserializarea GVariant cu È™irul de tipul „%s†din formatul de " +"reÈ›ea D-Bus" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Valoare de endianness nevalidă. Se aÈ™tepta 0x6c („lâ€) sau 0x42 („Bâ€), dar s-" +"a găsit valoarea 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Versiune majoră de protocol nevalidă. Se aÈ™tepta 1 dar s-a găsit %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Antet de semnătură găsit dar nu este de tipul semnătură" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"S-a găsit un antet de semnătură cu semnătura „%sâ€, dar corpul mesajului este " +"vid" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Valoarea parsată „%s†nu este o semnătură D-Bus validă (pentru corp)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Nu există niciun antet de semnătură în mesaj, dar corpul mesajului este de " +"%u octet" +msgstr[1] "" +"Nu există niciun antet de semnătură în mesaj, dar corpul mesajului este de " +"%u octeÈ›i" +msgstr[2] "" +"Nu există niciun antet de semnătură în mesaj, dar corpul mesajului este de " +"%u de octeÈ›i" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Nu se poate deserializa mesajul: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Eroare la serializarea GVariant cu È™irul de tipul „%s†în formatul de reÈ›ea " +"D-Bus" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Numărul de descriptori de fiÈ™ier în mesaj (%d) diferă de câmpul de antet (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Nu se poate serializa mesajul: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Corpul mesajului are semnătura „%sâ€, dar nu există nicio semnătură de antet" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Corpul mesajului are semnătura „%sâ€, dar semnătura din câmpul de antet este " +"„%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"Corpul mesajului este vid, dar semnătura din câmpul de antet este „(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Eroare la întoarcere cu corpul de tipul „%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Rezultat de eroare cu corp vid" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(TastaÈ›i orice caracter pentru a închide această fereastră)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Sesiunea dbus nu rulează, È™i lansarea automată a eÈ™uat" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Nu se poate obÈ›ine profilul hardware: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Nu s-a putut încărca %s sau %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Eroare la apelul StartServiceByName pentru %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Răspuns neaÈ™teptat %d de la metoda StartServiceByName(\"%s\")" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Nu se poate invoca metoda; proxy-ul este pentru un nume cunoscut %s fără " +"proprietar, È™i a fost construit utilizând fanionul " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "SpaÈ›iul de nume abstract nu este suportat" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Nu se poate specifica un fiÈ™ier nonce când se creează un server" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Eroare la scrierea fiÈ™ierului nonce la „%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Șirul „%s†nu este un GUID D-Bus valid" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Nu se poate asculta pe transportul nesuportat „%sâ€" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Comenzi:\n" +" help Arată aceste informaÈ›ii\n" +" introspect Introspectează un obiect la distanță\n" +" monitor Monitorizează un obiect la distanță\n" +" call Invocă o metodă pe un obiect la distanță\n" +" emit Emite un semnal\n" +" wait AÈ™teaptă apariÈ›ia unui nume de magistrală\n" +"\n" +"UtilizaÈ›i \"%s COMANDÄ‚ --help\" pentru a obÈ›ine ajutor pentru fiecare " +"comandă.\n" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1244 +#: gio/gdbus-tool.c:1732 +#, c-format +msgid "Error: %s\n" +msgstr "Eroare: %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1748 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Eroare la parsarea introspecÈ›iei XML: %s\n" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "" +"Eroare: %s nu este un nume valid\n" +"\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1063 +#: gio/gdbus-tool.c:1898 gio/gdbus-tool.c:2138 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Eroare: calea %s către obiect nu este validă\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "Conectare la magistrala sistemului" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "Conectare la magistrala de sesiune" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "Conectare la adresa D-Bus dată" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "OpÈ›iuni ale capătului conexiunii:" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "OpÈ›iuni care specifică capătul conexiunii" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "Niciun capăt de conexiune specificat" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Mai multe capete de conexiune specificate" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Avertisment: conform datelor de introspecÈ›ie, interfaÈ›a „%s†nu există\n" + +#: gio/gdbus-tool.c:531 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Avertisment: conform datelor de introspecÈ›ie, metoda „%s†nu există în " +"interfaÈ›a „%sâ€\n" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "DestinaÈ›ia opÈ›ională pentru semnal (nume unic)" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "Calea obiectului pe care se emite semnalul" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "Numele semnalului È™i interfeÈ›ei" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "Emite un semnal." + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:1000 gio/gdbus-tool.c:1835 +#: gio/gdbus-tool.c:2067 gio/gdbus-tool.c:2287 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Eroare la conectare: %s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Eroare: %s nu este un nume de magistrală unic valid.\n" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1043 gio/gdbus-tool.c:1878 +msgid "Error: Object path is not specified\n" +msgstr "Eroare: calea către obiect nu a fost specificată\n" + +#: gio/gdbus-tool.c:765 +msgid "Error: Signal name is not specified\n" +msgstr "Eroare: numele de semnal nu a fost specificat\n" + +#: gio/gdbus-tool.c:779 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "" +"Eroare: numele de semnal „%s†nu este valid\n" +"\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Eroare: %s nu este un nume de interfață valid\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Eroare: %s nu este un nume de membru valid\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1175 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Eroare la parsarea parametrului %d: %s\n" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Eroare la golirea conexiunii: %s\n" + +#: gio/gdbus-tool.c:894 +msgid "Destination name to invoke method on" +msgstr "Numele destinaÈ›iei pe care se va invoca metoda" + +#: gio/gdbus-tool.c:895 +msgid "Object path to invoke method on" +msgstr "Calea către obiectul pe care se va invoca metoda" + +#: gio/gdbus-tool.c:896 +msgid "Method and interface name" +msgstr "Metoda È™i numele interfeÈ›ei" + +#: gio/gdbus-tool.c:897 +msgid "Timeout in seconds" +msgstr "Limita de timp în secunde" + +#: gio/gdbus-tool.c:898 +msgid "Allow interactive authorization" +msgstr "Permite autorizarea interactivă" + +#: gio/gdbus-tool.c:945 +msgid "Invoke a method on a remote object." +msgstr "Invocă o metodă pe un obiect la distanță." + +#: gio/gdbus-tool.c:1017 gio/gdbus-tool.c:1852 gio/gdbus-tool.c:2092 +msgid "Error: Destination is not specified\n" +msgstr "Eroare: destinaÈ›ia nu a fost specificată\n" + +#: gio/gdbus-tool.c:1028 gio/gdbus-tool.c:1869 gio/gdbus-tool.c:2103 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "" +"Eroare: %s nu este un nume de magistrală valid\n" +"\n" + +#: gio/gdbus-tool.c:1078 +msgid "Error: Method name is not specified\n" +msgstr "Eroare: numele metodei nu a fost specificat\n" + +#: gio/gdbus-tool.c:1089 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "" +"Eroare: numele de metodă „%s†nu este valid\n" +"\n" + +#: gio/gdbus-tool.c:1167 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Eroare la parsarea parametrului %d cu tipul „%sâ€: %s\n" + +#: gio/gdbus-tool.c:1193 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Eroare la adăugarea mânerului %d: %s\n" + +#: gio/gdbus-tool.c:1694 +msgid "Destination name to introspect" +msgstr "Numele destinaÈ›iei de introspectat" + +#: gio/gdbus-tool.c:1695 +msgid "Object path to introspect" +msgstr "Calea obiectului de introspectat" + +#: gio/gdbus-tool.c:1696 +msgid "Print XML" +msgstr "AfiÈ™ează XML" + +#: gio/gdbus-tool.c:1697 +msgid "Introspect children" +msgstr "Introspectează inferiorii" + +#: gio/gdbus-tool.c:1698 +msgid "Only print properties" +msgstr "TipăreÈ™te doar proprietățile" + +#: gio/gdbus-tool.c:1787 +msgid "Introspect a remote object." +msgstr "Introspectează un obiect la distanță." + +#: gio/gdbus-tool.c:1993 +msgid "Destination name to monitor" +msgstr "Numele destinaÈ›iei de monitorizat" + +#: gio/gdbus-tool.c:1994 +msgid "Object path to monitor" +msgstr "Calea către obiectul de monitorizat" + +#: gio/gdbus-tool.c:2019 +msgid "Monitor a remote object." +msgstr "Monitorizează un obiect la distanță." + +#: gio/gdbus-tool.c:2077 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Eroare: nu se poate monitoriza o conexiune non-magistrală-mesaj\n" + +#: gio/gdbus-tool.c:2201 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" +"Serviciu de activat înainte de a-l aÈ™tepta pe celălalt (nume bine cunoscut)" + +#: gio/gdbus-tool.c:2204 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Limita de timp de aÈ™teptat înainte de a ieÈ™i cu o eroare (secunde); 0 pentru " +"nicio limită de timp (implicit)" + +#: gio/gdbus-tool.c:2252 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPÈšIUNE…] NUME-MAGISTRALÄ‚" + +#: gio/gdbus-tool.c:2253 +msgid "Wait for a bus name to appear." +msgstr "AÈ™teaptă apariÈ›ia unui nume de magistrală." + +#: gio/gdbus-tool.c:2329 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Eroare: trebuie specificat un serviciu pentru care să se activeze.\n" + +#: gio/gdbus-tool.c:2334 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Eroare: trebuie specificat un serviciu după care să se aÈ™tepte.\n" + +#: gio/gdbus-tool.c:2339 +msgid "Error: Too many arguments.\n" +msgstr "Eroare: prea multe argumente.\n" + +#: gio/gdbus-tool.c:2347 gio/gdbus-tool.c:2354 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Eroare: %s nu este un nume de magistrală popular valid.\n" + +#: gio/gdebugcontrollerdbus.c:357 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Neautorizat pentru a modifica configurările de depanare" + +#: gio/gdesktopappinfo.c:2174 gio/gdesktopappinfo.c:5101 +msgid "Unnamed" +msgstr "Nedenumit" + +#: gio/gdesktopappinfo.c:2584 +msgid "Desktop file didn’t specify Exec field" +msgstr "FiÈ™ierul desktop nu a specificat un câmp Exec" + +#: gio/gdesktopappinfo.c:2892 +msgid "Unable to find terminal required for application" +msgstr "Nu s-a găsit un terminal pentru pornirea aplicaÈ›iei" + +#: gio/gdesktopappinfo.c:3621 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "" +"Nu se poate crea dosarul de configurare pentru aplicaÈ›iile utilizatorului " +"%s: %s" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Nu se poate crea dosarul de configurare MIME al utilizatorului %s: %s" + +#: gio/gdesktopappinfo.c:3867 gio/gdesktopappinfo.c:3891 +msgid "Application information lacks an identifier" +msgstr "InformaÈ›iile despre aplicaÈ›ie nu au un indentificator" + +#: gio/gdesktopappinfo.c:4127 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Nu se poate crea fiÈ™ierul desktop al utilizatorului %s" + +#: gio/gdesktopappinfo.c:4263 +#, c-format +msgid "Custom definition for %s" +msgstr "DefiniÈ›ie personalizată pentru %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "unitatea nu implementează scoaterea" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "unitatea nu implementează comenzile eject sau eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "" +"unitatea nu implementează verificarea periodică pentru medii de stocare noi" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "unitatea nu implementează comanda start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "unitatea nu implementează comanda stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "Suportul TLS nu implementează obÈ›inerea legăturii TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Suportul TLS nu este disponibil" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Suportul DTLS nu este disponibil" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Nu se poate lucra cu versiunea %d a codării GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Număr de jetoane formatat eronat (%d) în codarea GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Nu se poate lucra cu versiunea %d a codării GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Număr de jetoane formatat eronat (%d) în codarea GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Se aÈ™tepta un GEmblem pentru GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Montarea conÈ›inută nu există" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Nu se poate copia peste director" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Nu se poate copia un director peste alt director" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "FiÈ™ierul destinaÈ›ie există deja" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Nu se poate copia recursiv directorul" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Nu există suport pentru funcÈ›ia splice" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Eroare la aplicarea funcÈ›iei „splice†fiÈ™ierului: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Copierea (reflink/clonarea) între două montări nu este suportată" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" +"Copierea (legătura de referință/clonarea) nu este suportată sau nu este " +"validă" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" +"Copierea (legătura de referință/clonarea) nu este suportată sau nu a " +"funcÈ›ionat" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Nu se poate copia fiÈ™ierul special" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "S-a primit o valoare incorectă pentru legătura simbolică" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Legăturile simbolice nu sunt implementate" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Nu există o implementare pentru coÈ™ul de gunoi" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Numele de fiÈ™iere nu pot conÈ›ine „%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "volumul nu implementează montarea" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Nu există o aplicaÈ›ie înregistrată pentru deschiderea acestui fiÈ™ier" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumeratorul este închis" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Enumeratorul fiÈ™ierului este deja deschis de o altă operaÈ›iune" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Enumeratorul fiÈ™ierului este deja închis" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Nu se poate lucra cu versiunea %d a codării GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Date de intrare eronate pentru GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Fluxul nu suportă query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Căutarea în flux nu este implementată" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Nu se permite trunchierea fluxului de intrare" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Trunchierea fluxului nu este implementată" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Nume nevalid" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Răspuns proxy HTTP greÈ™it" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Conexiunea proxy HTTP nu este permisă" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "A eÈ™uat autentificarea la proxy-ul HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Este necesară autentificarea la proxy-ul HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Conexiunea proxy HTTP a eÈ™uat: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Răspunsul proxy HTTP este prea mare" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Conexiunea la serverul proxy HTTP s-a închis în mod neaÈ™teptat." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Număr greÈ™it de elemente (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Niciun tip pentru numele clasei %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Tipul %s nu implementează interfaÈ›a GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Tipul %s nu este clasificat" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Număr de versiune eronat: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Tipul %s nu implementează from_tokens() în interfaÈ›a GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Nu se poate lucra cu versiunea furnizată pentru codarea iconiÈ›ei" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nu s-a specificat o adresă" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Lungimea %u este prea mare pentru adresă" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adresa are biÈ›i stabiliÈ›i peste lungimea prefixului" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Nu s-a putut parsa „%s†ca mască de adresă IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "SpaÈ›iu insuficient pentru adresa socket-ului" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Adresă nesuportată de socket" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Fluxul de intrare nu implementează citirea" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Asupra fluxului se execută deja o operaÈ›iune" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Copiază cu fiÈ™ier" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Păstrează cu fiÈ™ierul când este mutat" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "„version†nu ia argumente" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Utilizare:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "TipăreÈ™te informaÈ›ia versiunii È™i ieÈ™i." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Comenzi:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Concatenează fiÈ™ierele la ieÈ™irea standard" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Copiază unul sau mai multe fiÈ™iere" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Arată informaÈ›iile despre locaÈ›ii" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Lansează o aplicaÈ›ie de la un fiÈ™ier desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Listează conÈ›inuturile locaÈ›iilor" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "ObÈ›ine sau stabileÈ™te operatorul pentru un tip mime" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Creează directoare" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Monitorizează fiÈ™ierele È™i directoarele pentru modificări" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montează sau demontează locaÈ›iile" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Mută unul sau mai multe fiÈ™iere" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Deschide fiÈ™ierele cu aplicaÈ›ia implicită" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "RedenumeÈ™te un fiÈ™ier" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Șterge unul sau mai multe fiÈ™iere" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "CiteÈ™te de la intrarea standard È™i salvează" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "StabileÈ™te un atribut de fiÈ™ier" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Mută fiÈ™iere sau directoare la gunoi" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Listează conÈ›inuturile locaÈ›iilor într-un arbore" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "UtilizaÈ›i %s pentru a obÈ›ine ajutor detaliat.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Eroare la scrierea la stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCAÈšIE" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Concatenează fiÈ™ierele È™i tipăreÈ™te la ieÈ™irea standard." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat funcÈ›ionează exact ca utilitatea cat tradiÈ›ională, dar utilizând " +"locaÈ›ii\n" +"GIO în loc de fiÈ™iere locale: de exemplu, puteÈ›i să utilizaÈ›i ceva " +"asemănător\n" +"cu smb://server/resource/file.txt ca locaÈ›ie." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Nu s-au furnizat locaÈ›ii" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nu este niciun director È›intă" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Arată progresul" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Solicită înainte de suprascriere" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Păstrează toate atributele" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Creează o copie de siguranță a fiÈ™ierelor destinaÈ›ie existente" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nu urmări niciodată legăturile simbolice" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Utilizează permisiunile implicite pentru destinaÈ›ie" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Transferat %s din %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SURSÄ‚" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINAÈšIE" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Copiază unul sau mai multe fiÈ™iere de la SURSÄ‚ la DESTINAÈšIE." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy funcÈ›ionează exact ca utilitatea cp tradiÈ›ională, dar utilizând " +"locaÈ›ii\n" +"GIO în loc de fiÈ™iere locale: de exemplu, puteÈ›i să utilizaÈ›i ceva " +"asemănător\n" +"cu smb://server/resource/file.txt ca locaÈ›ie." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "DestinaÈ›ia %s nu este un director" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: se suprascrie „%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Listează atributele inscripÈ›ionabile" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "ObÈ›ine informaÈ›iile sistemului de fiÈ™iere" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Atributele de obÈ›inut" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTE" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Nu urmări legăturile simbolice" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atribute:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "nume de afiÈ™aj: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "editează numele: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "nume: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tip: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "dimensiune: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "ascuns\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "cale locală: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "montare unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Atribute care se pot stabili:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "SpaÈ›ii de nume de atribut inscripÈ›ionabile:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Arată informaÈ›iile despre locaÈ›ii." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info funcÈ›ionează exact ca utilitatea ls tradiÈ›ională, dar utilizând " +"locaÈ›ii\n" +"GIO în loc de fiÈ™iere locale: de exemplu, puteÈ›i să utilizaÈ›i ceva " +"asemănător\n" +"cu smb://server/resource/file.txt ca locaÈ›ie. Atributele de fiÈ™ier pot fi\n" +"specificate cu numele lor GIO, ex. standard:icon, sau doar prin\n" +"spaÈ›iul de nume, ex. unix, sau prin „*â€, care se potriveÈ™te cu toate " +"atributele" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "FIȘIER-DESKTOP [ARG-FIȘIER …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Lansează o aplicaÈ›ie de la un fiÈ™ier desktop, trecându-i argumente opÈ›ionale " +"de nume de fiÈ™iere." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Nu a fost furnizat niciun fiÈ™ier desktop" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" +"Comanda de lansare nu este suportată în mod curent pe această platformă" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Nu s-a putut încărca „%sâ€: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Nu s-au putut încărca informaÈ›iile aplicaÈ›iei pentru „%sâ€" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Nu s-a putut lansa aplicaÈ›ia „%sâ€: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Arată fiÈ™ierele ascunse" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Utilizează un format de listare lung" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "TipăreÈ™te nume de afiÈ™aje" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "TipăreÈ™te URI-uri complete" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Listează conÈ›inuturile locaÈ›iilor." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list funcÈ›ionează exact ca utilitatea ls tradiÈ›ională, dar utilizând " +"locaÈ›ii\n" +"GIO în loc de fiÈ™iere locale: de exemplu, puteÈ›i să utilizaÈ›i ceva " +"asemănător\n" +"cu smb://server/resource/file.txt ca locaÈ›ie. Atributele de fiÈ™ier pot fi\n" +"specificate cu numele lor GIO, ex. standard:icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TIP MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "OPERATOR" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "ObÈ›ine sau stabileÈ™te operatorul pentru un tip mime." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Dacă nu este furnizat niciun operator, listează aplicaÈ›iile înregistrate È™i " +"recomandate\n" +"pentru tipul mime. Dacă un operator este furnizat, acesta este stabilit ca " +"operatorul\n" +"implicit pentru tipul mime." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Trebuie să specificaÈ›i un singur tip mime, È™i poate un operator" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Nu sunt aplicaÈ›ii implicite pentru „%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "AplicaÈ›ia implicită pentru „%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "AplicaÈ›ii înregistrate:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Nu sunt aplicaÈ›ii înregistrate\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "AplicaÈ›ii recomandate:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Nu sunt aplicaÈ›ii recomandate\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Nu s-au putut încărca informaÈ›iile pentru operatorul „%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Nu s-a putut stabili „%s†ca operatorul implicit pentru „%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Creează directoare superioare" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Creează directoare." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir funcÈ›ionează exact ca utilitatea mkdir tradiÈ›ională, dar utilizând " +"locaÈ›ii\n" +"GIO în loc de fiÈ™iere locale: de exemplu, puteÈ›i să utilizaÈ›i ceva " +"asemănător\n" +"cu smb://server/resource/mydir ca locaÈ›ie." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Monitorizează un director (implicit: depinde de tip)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Monitorizează un fiÈ™ier (implicit: depinde de tip)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Monitorizează un fiÈ™ier direct (observă modificările făcute via legături " +"fizice)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Monitorizează un fiÈ™ier direct, dar nu raportează modificările" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Raportează mutările È™i redenumirile ca simple evenimente È™terse / create" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "UrmăreÈ™te evenimentele de montare" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Monitorizează fiÈ™ierele sau directoarele pentru modificări." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Montează ca montabil" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Montează volumul cu fiÈ™ier de dispozitiv, sau alt indicator" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Demontează" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Scoate" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "OpreÈ™te unitatea cu fiÈ™ierul de dispozitiv" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DISPOZITIV" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Demontează toate montările cu schema dată" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Ignoră operaÈ›iile de fiÈ™ier importante atunci când se demontează sau se " +"scoate" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Utilizează un utilizator anonim la autentificare" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Listează" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Monitorizează evenimente" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Arată informaÈ›iile suplimentare" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "PIM-ul numeric la deblocarea unui volum VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montează un volum ascuns TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montează un volum de sistem TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Accesul anonim respins" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Nu există nicio unitate pentru fiÈ™ierul de dispozitiv" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Nu există niciun volum pentru ID-ul dat" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montează sau demontează locaÈ›iile." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Nu utiliza opÈ›iunile de revenire pentru copiere È™i È™tergere" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Mută unul sau mai multe fiÈ™iere de la SURSÄ‚ la DEST." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move funcÈ›ionează exact ca utilitatea mv tradiÈ›ională, dar utilizând " +"locaÈ›ii\n" +"GIO în loc de fiÈ™iere locale: de exemplu, puteÈ›i să utilizaÈ›i ceva " +"asemănător\n" +"cu smb://server/resource/file.txt ca locaÈ›ie" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Èšinta %s nu este un director" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Deschide fiÈ™ierele cu aplicaÈ›ia implicită care\n" +"este înregistrată pentru a lucra cu fiÈ™iere de acest tip." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignoră fiÈ™ierele care nu există, nu solicita niciodată" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Șterge fiÈ™ierele date." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NUME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "RedenumeÈ™te un fiÈ™ier." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "LipseÈ™te un argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Prea multe argumente" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Redenumire cu succes. Uri nou: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Creează doar dacă nu există" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Adaugă la sfârÈ™itul fiÈ™ierului" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "La creare, restricÈ›ionează accesul pentru utilizatorul curent" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "La înlocuire, înlocuieÈ™te ca È™i cum destinaÈ›ia nu ar exista" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "TipăreÈ™te etag nou la sfârÈ™it" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Etag-ul fiÈ™ierului care este suprascris" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Eroare la citirea din intrarea standard" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag nu este disponibil\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "CiteÈ™te de la intrarea standard È™i salvează la DEST." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nu s-a furnizat o destinaÈ›ie" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Tipul atributului" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TIP" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALOARE" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "StabileÈ™te un atribut de fiÈ™ier pentru LOCAÈšIE." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "LocaÈ›ia nu a fost specificată" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atributul nu a fost specificat" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Valoarea nu a fost specificată" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Tip de atribut nevalid „%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "GoleÈ™te gunoiul" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Listează fiÈ™ierele de la gunoi cu locaÈ›iile originale" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Restaurează un fiÈ™ier de la gunoi la locaÈ›ia originală a acestuia (eventual " +"recreând directorul)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Nu s-a putut găsi calea originală" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Nu s-a putut recrea locaÈ›ia originală: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Nu s-a putut muta fiÈ™ierul în locaÈ›ia originală: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Mută/Restaurează fiÈ™ierele sau directoarele la gunoi." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Notă: pentru comutatorul --restore, dacă locaÈ›ia originală a fiÈ™ierului " +"trimis la gunoi \n" +"există deja, aceasta nu va fi suprascrisă decât dacă --force este stabilit." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "LocaÈ›ia dată nu începe cu trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "UrmăreÈ™te legăturile simbolice, montările È™i scurtăturile" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Listează conÈ›inuturile directoarelor într-un format arborescent." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elementul <%s> nu este permis în <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elementul <%s> nu este permis la nivelul cel mai de sus" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "FiÈ™ierul %s apare de mai multe ori în resursă" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Nu s-a putut localiza „%s†în niciun director sursă" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Nu s-a putut localiza %s†în directorul curent" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "OpÈ›iune de procesare necunoscută „%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"preprocesarea %s a fost solicitată, dar nu este stabilit %s, È™i %s nu se " +"află în CALE" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Eroare la citirea fiÈ™ierului %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Eroare la comprimarea fiÈ™ierului %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "textul nu are voie să apară în <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Arată versiunea programului È™i ieÈ™i" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Numele fiÈ™ierului de ieÈ™ire" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Directoarele de unde se vor încărca fiÈ™ierele referenÈ›iate în FILE " +"(implicit: directorul curent)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DOSAR" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Generează rezultatul în formatul selectat de extensia numelui de fiÈ™ier È›intă" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Generează antetul sursei" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Generează codul sursă utilizat pentru a lega fiÈ™ierul resursă în cod" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Generează lista de dependenÈ›e" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Numele fiÈ™ierului de dependenÈ›e de generat" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Include È›intele false în fiÈ™ierul de dependenÈ›e generat" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Nu crea È™i înregistra automat resursa" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Nu exporta funcÈ›iile; declară-le G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "Nu îngloba date în fiÈ™ierul C; presupuneÈ›i că este legat extern" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Nume de identificator C utilizat pentru codul sursă generat" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Compilatorul C È›intă (implicit: variabila de mediu CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Compilează o specificaÈ›ie de resursă într-un fiÈ™ier resursă.\n" +"FiÈ™ierele specificaÈ›ie de resursă au extensia .gresource.xml,\n" +"iar fiÈ™ierul resursă are extensia cu numele .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Ar trebui să furnizaÈ›i exact un nume de fiÈ™ier\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "pseudonimul trebuie să aibă minim 2 caractere" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Valoare numerică nevalidă" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " a fost specificat deja" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value=„%s†deja specificată" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "valorile fanioanelor trebuie să aibă stabilit cel mult 1 bit" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> trebuie să conÈ›ină cel puÈ›in o " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> nu este conÈ›inut în intervalul specificat" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nu este un membru valid al tipului enumerat specificat" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> conÈ›ine un È™ir care nu se află în tipul de fanioane specificat" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> conÈ›ine un È™ir care nu se află în " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " a fost specificat deja pentru această cheie" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nu este permis pentru cheile de tipul „%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "minimul specificat al este mai mare decât maximul" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "categorie l10n nesuportată: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "s-a solicitat l10n, dar nu s-a furnizat niciun domeniu gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "context de traducere furnizat pentru valoare fără să fie activat l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Nu s-a putut parsa valoarea de tipul „%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" nu pot fi specificate pentru cheile etichetate ca având un tip " +"enumerat" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " au fost specificate deja pentru această cheie" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nu sunt permise pentru cheile de tipul „%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " a fost furnizat deja" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " trebuie să conÈ›ină cel puÈ›in o " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " au fost specificate deja pentru această cheie" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" pot fi specificate doar pentru cheile cu tipuri fanioane sau " +"enumerate sau după " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" furnizată atunci când „%s†este deja un membru al " +"tipului enumerat" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" furnizată atunci când a fost dată " +"deja" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " a fost specificat deja" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "È›inta aliasului „%s†nu este un tip enumerat" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "È›inta aliasului „%s†nu este în " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " trebuie să conÈ›ină cel puÈ›in un " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Numele goale nu sunt permise" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Nume nevalid „%sâ€: numele trebuie să înceapă cu o literă mică" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Nume nevalid „%sâ€: caracter nevalid „%câ€; doar literele mici, numerele È™i " +"cratima („-â€) sunt permise" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Nume nevalid „%sâ€: două cratime consecutive („--â€) nu sunt permise" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Nume nevalid „%sâ€: ultimul caracter nu poate fi o cratimă („-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Nume nevalid „%sâ€: lungimea maximă este 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " deja specificat" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Nu se pot adăuga chei la o schemă de tipul „list-ofâ€" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " deja specificat" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" ascunde în ; utilizaÈ›i " +" pentru a modifica valoarea" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Exact una dintre valorile „typeâ€, „enum†sau „flags†trebuie specificată ca " +"atribut pentru " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> nu este (încă) definit." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Șir de tip GVariant nevalid „%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " a fost furnizat dar schema nu extinde nimic" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Nu este niciun element de suprascris" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " deja specificat" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " deja specificat" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " extinde o schemă încă inexistentă „%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " este o listare a unei scheme încă inexistente „%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Nu poate fi o listă a unei scheme care are o cale" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Nu se poate extinde o schemă care are o cale" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" este o listă, ce extinde care nu este o " +"listă" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" extinde , dar " +"„%s†nu extinde „%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"O cale, dacă este furnizată, trebuie să înceapă È™i să se termine cu o bară " +"oblică" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Calea unei liste trebuie să se termine cu „:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Avertisment: Schema „%s†are calea „%sâ€. Căile care încep cu „/apps/â€, „/" +"desktop/†sau „/system/†sunt învechite." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> deja specificat" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Doar un element <%s> este permis în <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Elementul <%s> nu este permis la nivelul de top" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Elementul este necesar în " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Textul nu poate să apară înăuntrul <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Avertisment: referință nedefinită la " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict a fost specificat; se iese." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "ÃŽntregul fiÈ™ier a fost ignorat." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Se ignoră acest fiÈ™ier." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Nu există cheia „%s†în schema „%s†cum este specificat în fiÈ™ierul de " +"suprascriere „%sâ€; se ignoră suprascrierea pentru această cheie." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Nu există cheia „%s†în schema „%s†cum este specificat în fiÈ™ierul de " +"suprascriere „%s†și --strict a fost specificat; se iese." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Nu se pot furniza suprascrierile per-desktop pentru cheia localizată „%s†în " +"schema „%s†(suprascrie fiÈ™ierul „%sâ€); se ignoră suprascrierea pentru " +"această cheie." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Nu se pot furniza suprascrierile per-desktop pentru cheia localizată „%s†în " +"schema „%s†(suprascrie fiÈ™ierul „%sâ€) È™i --strict a fost specificat; se " +"iese." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Eroare la parsarea cheii „%s†în schema „%s†cum este specificat în fiÈ™ierul " +"de suprascriere „%sâ€: %s. Se ignoră suprascrierea pentru această cheie." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Eroare la parsarea cheii „%s†în schema „%s†cum este specificat în fiÈ™ierul " +"de suprascriere „%sâ€: %s. --strict a fost specificat; se iese." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Suprascrierea cheii „%s†în schema „%s†din fiÈ™ierul de suprascriere „%s†nu " +"se află în intervalul specificat de schemă; se ignoră suprascrierea pentru " +"această cheie." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Suprascrierea cheii „%s†în schema „%s†din fiÈ™ierul de suprascriere „%s†nu " +"se află în intervalul specificat de schemă È™i --strict a fost specificat; se " +"iese." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Suprascrierea cheii „%s†în schema „%s†din fiÈ™ierul de suprascriere „%s†nu " +"este în lista de alegeri valide; se ignoră suprascrierea pentru această " +"cheie." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Suprascrierea cheii „%s†în schema „%s†din fiÈ™ierul de suprascriere „%s†nu " +"este în lista de alegeri valide È™i --strict a fost specificat; se iese." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Unde se stochează fiÈ™ierul gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Abandonează execuÈ›ia la detectarea oricăror erori în scheme" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Nu scrie fiÈ™ierul gschemas.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Nu impune restricÈ›ii numelor cheilor" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Compilează toate fiÈ™ierele-schemă GSettings într-un cache de schemă.\n" +"FiÈ™ierele schemă trebuie să aibă extensia .gschema.xml,\n" +"iar fiÈ™ierul cache se numeÈ™te gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Trebuie să daÈ›i exact un nume de dosar" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nu s-a găsit niciun fiÈ™ier schemă: nu se face nimic." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Nu s-a găsit niciun fiÈ™ier schemă: s-a È™ters fiÈ™ierul de ieÈ™ire existent." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Nume incorect de fiÈ™ier %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Eroare la obÈ›inerea informaÈ›iilor sistemului de fiÈ™iere pentru %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Montarea conÈ›inătoare pentru fiÈ™ierul %s nu a fost găsită" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Nu se poate redenumi directorul rădăcină" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Eroare la redenumirea fiÈ™ierului %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Nu se poate redenumi fiÈ™ierul, numele de fiÈ™ier există deja" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Nume nevalid de fiÈ™ier" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Eroare la deschiderea fiÈ™ierului %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Eroare la eliminarea fiÈ™ierului %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Eroare la mutarea la coÈ™ul de gunoi a fiÈ™ierului %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Nu s-a putut crea directorul coÈ™ului de gunoi %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Nu se poate găsi directorul de top pentru a muta la coÈ™ul de gunoi %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"Mutarea la coÈ™ul de gunoi în montările interne de sistem nu este suportată" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "" +"Nu se poate găsi sau crea directorul coÈ™ului de gunoi %s pentru a È™terge %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "" +"Nu se poate crea fiÈ™ierul cu informaÈ›ii despre mutarea la coÈ™ul de gunoi " +"pentru %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Nu se poate muta la coÈ™ul de gunoi fiÈ™ierul %s dincolo de limitele " +"sistemului de fiÈ™iere" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Nu se poate muta la coÈ™ul de gunoi fiÈ™ierul %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Nu se poate muta la gunoi fiÈ™ierul %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Eroare la crearea directorului %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Sistemul de fiÈ™iere nu suportă legături simbolice" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Eroare la crearea legăturii simbolice %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Eroare la mutarea fiÈ™ierului %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Nu se poate muta un director peste alt director" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Crearea fiÈ™ierului pentru copia de siguranță a eÈ™uat" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Eroare la È™tergerea fiÈ™ierului destinaÈ›ie: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "" +"OperaÈ›iunea de mutare între două dispozitive montate nu este implementată" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Nu s-a putut determina utilizarea discului a %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Valoarea atributului trebuie să fie diferită de NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Tip incorect de atribut (se aÈ™tepta un È™ir)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Nume incorect de atribut extins" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Eroare la stabilirea atributului extins „%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (codare incorectă)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Eroare în timpul obÈ›inerii de informaÈ›ii pentru fiÈ™ierul „%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" +"Eroare în timpul obÈ›inerii de informaÈ›ii pentru descriptorul de fiÈ™ier: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Tip incorect de atribut (se aÈ™tepta o valoare uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Tip incorect de atribut (se aÈ™tepta o valoare uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Tip incorect de atribut (se aÈ™tepta un È™ir de octeÈ›i)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Nu se pot defini drepturi pentru legături simbolice" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Eroare la definirea drepturilor: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Eroare la definirea deÈ›inătorului: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "legătura simbolică trebuie să fie diferită de NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Eroare la definirea legăturii simbolice: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Eroare la definirea legăturii simbolice: fiÈ™ierul nu este o legătură " +"simbolică" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Nanosecundele extra %d pentru datarea UNIX %lld sunt negative" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Nanosecundele extra %d pentru datarea UNIX %lld au ajuns la 1 secundă" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "Datarea UNIVX %lld nu se potriveÈ™te pe 64 de biÈ›i" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "Datarea UNIX %lld este în afara intervalului suportate de Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Numele de fiÈ™ier „%s†nu poate fi convertit la UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "FiÈ™ierul „%s†nu poate fi deschis: eroare de Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Eroare la stabilirea modificării sau timpului de acces pentru fiÈ™ierul „%sâ€: " +"%lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Eroare la schimbarea datei de acces ori modificare: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Contextul SELinux trebuie să fie diferit de NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nu este activat pentru acest sistem" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Eroare la definirea contextului SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Definirea atributului %s nu este implementată" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Eroare la citirea din fiÈ™ier: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Eroare la închiderea fiÈ™ierului: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Eroare la căutarea în fiÈ™ier: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Nu s-a găsit tipul implicit de monitorizare a fiÈ™ierelor locale" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Eroare la scrierea în fiÈ™ier: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Eroare la È™tergerea vechii legături simbolice de backup: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Eroare la crearea copiei de backup: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Eroare la redenumirea fiÈ™ierului temporar: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "Eroare la trunchierea fiÈ™ierului: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Eroare la deschiderea fiÈ™ierului „%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "FiÈ™ierul destinaÈ›ie este un director" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "FiÈ™ierul destinaÈ›ie nu este un fiÈ™ier obiÈ™nuit" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "FiÈ™ierul a fost modificat de o terță parte" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Eroare la È™tergerea vechiului fiÈ™ier: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "S-a primit un GSeekType nevalid" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Cerere de căutare nevalidă" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Nu se poate trunchia GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Fluxul de ieÈ™ire al memoriei nu poate fi redimensionat" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Nu s-a putut redimensiona fluxul de ieÈ™ire al memoriei" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Cantitatea de memorie necesară pentru a procesa scrierea este mai mare decât " +"spaÈ›iul de adrese disponibil" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "S-a cerut mutarea cursorului înaintea începutului fluxului" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "S-a cerut mutarea cursorului după sfârÈ™itul fluxului" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "montarea nu implementează operaÈ›ia de demontare „unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "montarea nu implementează operaÈ›ia de scoatere „ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "montarea nu implementează „unmount†sau „unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "montarea nu implementează „eject†sau „eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "montarea nu implementează operaÈ›ia de remontare „remountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "montarea nu implementează detecÈ›ia tipului de conÈ›inut" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "montarea nu implementează detecÈ›ia sincronizată a tipului de conÈ›inut" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Numele de gazdă „%s†conÈ›ine „[†dar nu È™i „]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Nu se poate accesa reÈ›eaua" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Nu se poate accesa gazda" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Nu s-a putut crea monitorul de reÈ›ea: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Nu s-a putut crea monitorul de reÈ›ea: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Nu s-a putut obÈ›ine starea reÈ›elei: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager nu rulează" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Versiunea de NetworkManager este prea veche" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Fluxul de ieÈ™ire nu implementează scrierea" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Suma vectorilor oferiÈ›i la %s este prea mare" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Sursa fluxului este deja închisă" + +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Eroare la rezolvarea „%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s nu este implementat" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Domeniu nevalid" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Resursa de la „%s†nu există" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Resursa de la „%s†nu s-a putut decomprima" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Resursa de la „%s†nu este un director" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Fluxul de intrare nu implementează căutarea" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Listează secÈ›iunile care conÈ›in resurse într-un FIȘIER elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Listează resursele\n" +"Dacă s-a furnizat SECÈšIUNE, listează resursele doar din această secÈ›iune\n" +"Dacă s-a furnizat CALE, listează doar resursele care se potrivesc" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FIȘIER [CALE]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SECÈšIUNE" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Listează resursele cu detalii\n" +"Dacă s-a furnizat SECÈšIUNE, listează resursele doar din această secÈ›iune\n" +"Dacă s-a furnizat CALE, listează doar resursele care se potrivesc\n" +"Detaliile includ secÈ›iunea, dimensiunea È™i compresia" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extrage un fiÈ™ier resursă la stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "CALE FIȘIER" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilizare:\n" +" gresource [--section SECÈšIUNE] COMANDÄ‚ [ARGUMENTE…]\n" +"\n" +"Comenzi:\n" +" help Arată aceste informaÈ›ii\n" +" sections Listează secÈ›iunile de resursă\n" +" list Listează resursele\n" +" details Listează resursele cu detalii\n" +" extract Extrage o resursă\n" +"\n" +"UtilizaÈ›i “gresource help COMANDÆpentru a obÈ›ine ajutor detaliat.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilizare:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECÈšIUNE Un nume (opÈ›ional) de secÈ›iune elf\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMANDÄ‚ Comandă (opÈ›ională) de explicat\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FIȘIER Un fiÈ™ier elf (o bibliotecă binară sau partajată)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FIȘIER Un fiÈ™ier elf (o bibliotecă binară sau partajată)\n" +" sau un fiÈ™ier resursă partajat\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[CALE]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " CALE O cale (opÈ›ională) de resursă (poate fi parÈ›ială)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CALE" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " CALE O cale de resursă\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Nu există schema „%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Schema „%s†nu este relocalizabilă (nu trebuie specificată calea)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schema „%s†este relocalizabilă (trebuie specificată calea)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Calea dată este goală.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Calea trebuie să înceapă cu o bară oblică (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Calea trebuie să se termine cu o bară oblică (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Calea trebuie să nu conÈ›ină două bare oblice adiacente (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Valoarea furnizată este în afara intervalului valid\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Cheia nu este inscripÈ›ionabilă\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Listează schemele (nerelocalizabile) instalate" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Listează schemele relocalizabile instalate" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Listează cheile din SCHEMÄ‚" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMÄ‚[:CALE]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Listează copiii SCHEMEI" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Listează chei È™i valori, recursiv\n" +"Dacă nu a fost furnizată nicio SCHEMÄ‚, listează toate cheile\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMÄ‚[:CALE]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "ObÈ›ine valoarea CHEII" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMÄ‚[:CALE] CHEIE" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Interoghează intervalul valorilor valide pentru CHEIE" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Interoghează descrierea pentru CHEIE" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Setează valoarea CHEII la VALOARE" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMÄ‚[:CALE] CHEIE VALOARE" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Resetează CHEIA la valoarea ei implicită" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "RestabileÈ™te toate cheile în SCHEMA la valorile implicite" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Verifică dacă CHEIA poate fi scrisă" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Monitorizează CHEIA pentru modificări.\n" +"Dacă nicio CHEIE nu este specificată, monitorizează toate cheile din " +"SCHEMÄ‚.\n" +"FolosiÈ›i ^C pentru a opri monitorizarea.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMÄ‚[:CALE] [CHEIE]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Utilizare:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMANDÄ‚ [ARGS…]\n" +"\n" +"Comenzi:\n" +" help Arată aceste informaÈ›ii\n" +" list-schemas Listează schemele instalate\n" +" list-relocatable-schemas Listează schemele relocalizabile\n" +" list-keys Listează cheile dintr-o schemă\n" +" list-children Listează inferiorii unei scheme\n" +" list-recursively Listează cheile È™i valorile, recursiv\n" +" range Interoghează intervalul unei chei\n" +" describe Interoghează descrierea unei chei\n" +" get ObÈ›ine valoarea unei chei\n" +" set StabileÈ™te valoarea unei chei\n" +" reset RestabileÈ™te valoarea unei chei\n" +" reset-recursively RestabileÈ™te toate valorile într-o schemă dată\n" +" writable Verifică dacă o cheie este inscripÈ›ionabilă\n" +" monitor Monitorizează modificările\n" +"\n" +"FolosiÈ›i comanda „gsettings help COMANDÆpentru a obÈ›ine ajutor detaliat.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Utilizare:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR Un director pentru căutarea de scheme adiÈ›ionale\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMÄ‚ Numele schemei\n" +" CALE Calea, pentru schemele relocalizabile\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " CHEIE Cheia (opÈ›ională) din schemă\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " CHEIE Cheia din schemă\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VALOARE Valoarea de setat\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Nu s-au putut încărca schemele de la %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Nu sunt scheme instalate\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Numele schemei dat este gol \n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Nu există cheia „%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Socket nevalid (neiniÈ›ializat)" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Socket nevalid, iniÈ›ializarea a eÈ™uat din următoarea cauză: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Socket-ul este deja închis" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "A expirat limita de timp la I/O pe socket" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "se creează GSocket din fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Nu s-a putut crea socket-ul: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "S-a specificat o familie necunoscută" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "S-a specificat un protocol necunoscut" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Nu se pot utiliza operaÈ›iile de datagramă pe un soclu non-datagramă." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Nu se pot utiliza operaÈ›iile de datagramă pe un soclu care are stabilită o " +"limită de timp." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "nu s-a putut obÈ›ine adresa locală: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "nu s-a putut obÈ›ine adresa la distanță: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "nu s-a putut asculta: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Eroare la asocierea adresei %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Eroare la alăturarea grupului multicast: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Eroare la părăsirea grupului multicast: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Nu există niciun suport pentru difuzarea multiplă specifică sursei" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Familie de soclu nesuportată" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "specific sursei nu o adresă IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Numele de interfață este prea lung" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Nu s-a putut găsi interfaÈ›a: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "" +"Nu există niciun suport pentru difuzarea multiplă specifică sursei IPv4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "" +"Nu există niciun suport pentru difuzarea multiplă specifică sursei IPv6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Eroare la acceptarea conexiunii: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Conectare în progres" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Nu se poate obÈ›ine eroarea în aÈ™teptare: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Eroare la primirea datelor: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Eroare la trimiterea datelor: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Nu se poate opri soclul: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Eroare la închiderea socket-ului: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Se aÈ™teaptă condiÈ›ia socket-ului: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Nu s-a putut trimite mesajul: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vectorii mesaj prea mari" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Eroare la trimiterea mesajului: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage nu este suportat pe Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Eroare la primirea mesajului: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Nu se pot citi certificările soclului: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials nu este implementat pe acest sistem de operare" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Nu s-a putut conecta la serverul proxy %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Nu s-a putut conecta la %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Nu s-a putut conecta: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Nu se poate utiliza proxy peste o conexiune non-TCP." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Protocolul proxy „%s†nu este suportat." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Procesul de ascultare este deja închis" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Socket-ul adăugat este închis" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 nu suportă adresa IPv6 „%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Numele de utilizator este prea lung pentru protocolul SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Numele de gazdă „%s†este prea lung pentru protocolul SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Serverul nu este un server de proxy SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Conectarea prin serverul SOCKSv4 a fost respinsă" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Serverul nu este un server de proxy SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Proxy-ul SOCKSv5 necesită autentificare." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 necesită o metodă de autentificare ce nu este acceptată de GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" +"Numele de utilizator sau parola este prea lungă pentru protocolul SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Autentificarea SOCKSv5 a eÈ™uat din cauza unui nume de utilizator sau a unei " +"parole greÈ™ite." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Numele de gazdă „%s†este prea lung pentru protocolul SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Serverul proxy SOCKSv5 utilizează un tip de adresă necunoscut." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Eroare internă a serverului proxy SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Setul de reguli nu permite conexiuni SOCKSv5." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Gazda nu poate fi contactată prin intermediul serverului SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "ReÈ›eaua nu poate fi contactată prin intermediul proxy-ului SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Conexiune refuzată prin proxy-ul SOCKSv5." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Proxy-ul SOCKSv5 nu suportă comanda „connectâ€." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Proxy-ul SOCKSv5 nu acceptă tipul de adresă furnizat." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Eroare necunoscută a proxy-ului SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Nu s-a putut crea conectorul „pipe†pentru comunicarea cu procesul copil (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Conductele nu sunt suportate pe această platformă" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Nu se poate lucra cu versiunea %d a codării GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Nu s-au găsit adrese valide" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Eroare la rezolvarea inversă a „%sâ€: %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Nu există nicio înregistrare DNS a tipului solicitat pentru „%sâ€" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Nu se poate rezolva temporar „%sâ€" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Eroare la rezolvarea „%sâ€" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Nu s-a găsit nicio cheie privată codată PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Nu se poate decripta cheia privată codată PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Nu s-a putut parsa cheia privată codificată PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Nu s-a găsit niciun certificat codificat PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Nu s-a putut parsa certificatul codificat PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Backendul TLS curent nu suportă PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Acest GTlsBackend nu suportă crearea de certificate PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Aceasta este ultima È™ansă de a introduce parola corect înainte ca accesul să " +"fie blocat." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Mai multe parole introduse nu au fost corecte, È™i accesul va fi blocat după " +"alte eÈ™ecuri." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Parola introdusă nu este corectă." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Trimiterea FD nu este suportată" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "S-a aÈ™teptat un mesaj de control, dar s-a primit %d" +msgstr[1] "S-a aÈ™teptat un mesaj de control, dar s-au primit %d" +msgstr[2] "S-a aÈ™teptat un mesaj de control, dar s-au primit %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Tip neaÈ™teptat de date auxiliare" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "S-a aÈ™teptat un fd, dar s-a primit %d\n" +msgstr[1] "S-a aÈ™teptat un fd, dar s-a primit %d\n" +msgstr[2] "S-a aÈ™teptat un fd, dar s-a primit %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "S-a primit un fd nevalid" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Primirea FD nu este suportată" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Eroare la trimiterea credenÈ›ialelor: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Eroare la verificarea dacă SO_PASSCRED este activat pe socket: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Eroare la activarea SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Se aÈ™tepta să se citească un singur octet pentru a primi credenÈ›ialele, dar " +"s-au citi zero octeÈ›i" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Nu s-a aÈ™teptat un mesaj de control, dar s-a primit %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Eroare la dezactivarea SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Eroare la citirea din descriptorul de fiÈ™ier: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Eroare la închiderea descriptorului de fiÈ™ier: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Rădăcina sistemului de fiÈ™iere" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Eroare la scrierea în descriptorul de fiÈ™ier: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"Adresele de soclu abstracte pentru domeniul UNIX nu sunt suportate pe acest " +"sistem" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "volumul nu implementează eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volumul nu implementează eject sau eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Eroare la citirea din handle: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Eroare la închiderea handle-ului: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Eroare la scrierea în handle: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Memorie insuficientă" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Eroare internă: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Sunt necesare date suplimentare de la intrare" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Date comprimate nevalid" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresa de pe care se ascultă" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorat, pentru compatibilitate cu GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "TipăreÈ™te adresa" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "TipăreÈ™te adresa în modul shell" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Rulează un serviciu dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Argumente greÈ™ite\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Atribut neaÈ™teptat „%s†pentru elementul „%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atributul „%s†al elementului „%s†nu a fost găsit" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Etichetă neaÈ™teptată „%sâ€, se aÈ™tepta eticheta „%sâ€" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Etichetă neaÈ™teptată „%s†în „%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Dată/oră nevalidă „%s†în fiÈ™ierul de favorit" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Nu s-a găsit un fiÈ™ier valid cu favorite în directoarele de date" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Un favorit pentru URI-ul „%s†există deja" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nu s-a găsit niciun favorit pentru URI-ul „%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Nu s-a definit niciun tip MIME în favorit pentru URI-ul „%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Nu s-a definit niciun fanion privat în favorit pentru URI-ul „%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Nu s-au stabilit grupuri în favorit pentru URI-ul „%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Nicio aplicaÈ›ie cu numele „%s†nu a înregistrat un favorit pentru „%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Nu s-a putut extinde linia de exec „%s†cu URI-ul „%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Caracter nereprezentabil în intrarea conversiei" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Secvență parÈ›ială de caractere la sfârÈ™itul inputului" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Nu se poate converti rezerva „%s†la setul de codare „%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Octet NUL încorporat în intrarea conversiei" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Octet NUL încorporat în ieÈ™irea conversiei" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI-ul „%s†nu este un URI absolut care utilizează schema „fileâ€" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "URI-ul fiÈ™ierului local „%s†nu poate include un „#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI-ul „%s†nu este valid" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Numele de gazdă al URI-ului „%s†nu este valid" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI-ul „%s†conÈ›ine caractere eludate nevalid" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Numele căii „%s†nu este o cale absolută" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Ianuarie" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Februarie" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Martie" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Aprilie" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Iunie" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Iulie" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "August" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Septembrie" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Octombrie" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Noiembrie" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Decembrie" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Ian" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Iun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Iul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Oct" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Noi" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Luni" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "MarÈ›i" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Miercuri" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Joi" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Vineri" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sâmbătă" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Duminică" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Lun" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Mar" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mie" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Joi" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Vin" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sâm" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Dum" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Ianuarie" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Februarie" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Martie" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "Aprilie" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Iunie" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Iulie" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "August" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Septembrie" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Octombrie" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "Noiembrie" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Decembrie" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Ian" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Mai" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Iun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Iul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Oct" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Noi" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dec" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Eroare la deschiderea directorului „%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Nu s-a putut aloca %lu octet pentru a citi fiÈ™ierul „%sâ€" +msgstr[1] "Nu s-au putut aloca %lu octeÈ›i pentru a citi fiÈ™ierul „%sâ€" +msgstr[2] "Nu s-au putut aloca %lu de octeÈ›i pentru a citi fiÈ™ierul „%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Eroare la citirea fiÈ™ierului „%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "FiÈ™ierul „%s†este prea mare" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Nu s-a putut citi din fiÈ™ierul „%sâ€: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Nu s-a putut deschide fiÈ™ierul „%sâ€: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Nu s-au putut obÈ›ine atributele fiÈ™ierului „%sâ€: fstat() a eÈ™uat: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Nu s-a putut deschide fiÈ™ierul „%sâ€: fdopen() a eÈ™uat: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Nu s-a putut redenumi fiÈ™ierul „%s†în „%sâ€: g_rename() a eÈ™uat: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Nu s-a putut scrie fiÈ™ierul „%sâ€: write() a eÈ™uat: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Nu s-a putut scrie fiÈ™ierul „%sâ€: fsync() a eÈ™uat: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Nu s-a putut crea fiÈ™ierul „%sâ€: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "FiÈ™ierul existent „%s†nu a putut fi eliminat: g_unlink() a eÈ™uat: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Șablonul „%s†nu este valid, nu ar trebui să conÈ›ină un „%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Șablonul „%s†nu conÈ›ine XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Nu s-a putut citi legătura simbolică „%sâ€: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Nu s-a putut deschide convertorul de la „%s†la „%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Nu se poate efectua o citire brută în g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Date neconvertite rămase în memoria tampon pentru citire" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Canalul se termină cu un caracter parÈ›ial" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Nu se poate efectua o citire brută în g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Nu s-a găsit un fiÈ™ier cheie valid în directoarele de căutare" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Nu e un fiÈ™ier obiÈ™nuit" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"FiÈ™ierul cheii conÈ›ine linia „%s†care nu este o pereche cheie-valoare, un " +"grup, sau un comentariu" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Nume incorect de grup: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "FiÈ™ierul cheie nu începe cu un grup" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Nume nevalid de cheie: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "FiÈ™ierul cheii conÈ›ine codarea nesuportată „%sâ€" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "FiÈ™ierul cheii nu are grupul „%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "FiÈ™ierul cheii nu are cheia „%s†în grupul „%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"FiÈ™ierul cheii conÈ›ine cheia „%sâ€, cu valoarea „%sâ€, care nu este UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"FiÈ™ierul cheii conÈ›ine cheia „%s†care are o valoare care nu se poate " +"interpreta." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"FiÈ™ierul cheie conÈ›ine cheia „%s†în grupul „%sâ€, care are o valoare ce nu " +"poate fi interpretată." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Cheia „%s†în grupul „%s†are valoarea „%s†unde %s a fost aÈ™teptat" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "FiÈ™ieul cheie conÈ›ine caractere „escape†la sfârÈ™it de linie" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "FiÈ™ierul cheie conÈ›ine secvenÈ›a de eludare nevalidă „%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Valoarea „%s†nu poate fi interpretată ca un număr." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Valoarea întreagă „%s†este în afara limitelor" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Valoarea „%s†nu poate fi interpretată ca un număr raÈ›ional." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Valoarea „%s†nu poate fi interpretată ca o valoare logică." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Nu s-au putut obÈ›ine atributele fiÈ™ierului „%s%s%s%sâ€: fstat() a eÈ™uat: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Nu s-a putut mapa %s%s%s%s: mmap() a eÈ™uat: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Nu s-a putut deschide fiÈ™ierul „%sâ€: open() a eÈ™uat: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Eroare în linia %d, caracterul %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Text codat UTF-8 nevalid în nume — „%s†nu este valid" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "„%s†nu este un nume valid" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "„%s†nu este un nume valid: „%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Eroare în linia %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Nu s-a putut parsa „%-.*sâ€, care ar fi trebuit să fie o cifră într-o " +"referință de caracter (de exemplu ê) — poate cifra este prea mare" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"ReferinÈ›a de caracter nu s-a terminat cu punct virgulă; cel mai probabil aÈ›i " +"utilizat un caracter ampersand fără intenÈ›ia de a începe o entitate — " +"eludaÈ›i ampersand ca &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "ReferinÈ›a de caracter „%-.*s†nu codează un caracter permis" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"S-a depistat o entitate goală „&;â€; entitățile valide sunt: & " " +"< > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Numele entității „%-.*s†nu este cunoscut" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entitatea nu s-a terminat cu punct È™i virgulă; probabil că aÈ›i folosit un " +"caracter ampersand fără intenÈ›ia de a începe o entitate — eludaÈ›i ampersand " +"ca &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Documentul trebuie să înceapă cu un element (de ex. )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"„%s†nu este un caracter valid după un caracter „<â€; nu poate începe numele " +"unui element" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Caracter neobiÈ™nuit „%sâ€, se aÈ™tepta un caracter „>†pentru a termina " +"eticheta de element gol „%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Prea multe atribute în elementul „%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Caracter neobiÈ™nuit „%sâ€, se aÈ™tepta un caracter „=†după numele atributului " +"„%s†al elementului „%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Caracter neobiÈ™nuit „%sâ€, se aÈ™tepta un caracter „>†sau „/†pentru a " +"termina eticheta de început a elementului „%sâ€, sau opÈ›ional un atribut; " +"poate aÈ›i utilizat un caracter nevalid în numele atributului" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Caracter neobiÈ™nuit „%sâ€, se aÈ™teptau ghilimele de deschidere după semnul " +"egal când se dă valoarea atributului „%s†al elementului „%sâ€" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"„%s†nu este un caracter valid după numele elementului de închidere „%sâ€; " +"caracterul permis este „>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Elementul „%s†a fost închis, nici un element nu este curent deschis" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Elementul „%s†a fost închis, dar elementul deschis curent este „%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Documentul era gol sau conÈ›inea doar spaÈ›iu gol" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat imediat după o paranteză " +"unghiulară de deschidere „<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat cu unele elemente încă deschise — " +"„%s†a fost ultimul element deschis" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat, se aÈ™tepta un caracter „>†care " +"să încheie eticheta <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat în cadrul numelui unui element" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat în cadrul numele unui atribut" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat în cadrul unei etichete ce " +"deschidea un element." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat după semnul egal ce urma unui nume " +"atribut. Nici o valoare pentru atribut" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat în cadrul valorii unui atribut" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat în cadrul etichetei de închidere a " +"elementului „%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat în cadrul etichetei de închidere a " +"unui element nedeschis" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Documentul s-a terminat în mod neaÈ™teptat în cadrul unui comentariu sau a " +"unei instrucÈ›iuni de procesare" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[OPÈšIUNE…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "OpÈ›iuni ajutor:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Arată opÈ›iunile de ajutor" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Arată toate opÈ›iunile de ajutor" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "OpÈ›iuni aplicaÈ›ie:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "OpÈ›iuni:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Nu se poate parsa valoarea întreagă „%s†pentru %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Valoarea întreagă „%s†pentru %s este în afara limitelor" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Nu se poate parsa valoarea dublă „%s†pentru %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Valoarea dublă „%s†pentru %s este în afara limitelor" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Eroare la prelucrarea opÈ›iunii %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Argument lipsă pentru %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "OpÈ›iune necunoscută %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "obiect corupt" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "eroare internă sau obiect corupt" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "memorie insuficientă" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "s-a atins limita de backtracking" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"modelul de căutare conÈ›ine elemente pentru care nu se pot face comparaÈ›ii " +"parÈ›iale" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "eroare internă" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"pentru condiÈ›iile de tip „back reference†nu se pot face comparaÈ›ii parÈ›iale" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "s-a atins limita de recursivitate" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "combinaÈ›ie incorectă de indicatori de linie nouă" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "deplasament greÈ™it" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "utf8 scurt" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "buclă de recursivitate" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "eroare necunoscută" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ la sfârÈ™itul unui model" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c la sfârÈ™itul unui model" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "caracter nerecunoscut după \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "numere neordonate în cuantificatorul {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "număr prea mare în cuantificatorul {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "lipseÈ™te un ] de închidere pentru clasa caracter" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "secvență de eludare incorectă în clasa caracter" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "interval depășit în clasa caracter" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nimic de repetat" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "repetare neaÈ™teptată" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "caracter nerecunoscut după (? sau (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "Clasele cu nume POSIX sunt implementate doar înăuntrul altei clase" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "lipseÈ™te un ) de închidere" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referință la un submodel inexistent" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "lipseÈ™te un ) după comentariu" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "expresia regulată este prea lungă" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "nu s-a putut aloca memoria" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") fără paranteza de deschidere (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "„overflow†în cod" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "caracter nerecunoscut după (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "aserÈ›iunea „lookbehind†nu e de lungime fixă" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "număr sau nume formatat eronat după (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "grupul de condiÈ›ii conÈ›ine mai mult de două ramuri" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "se aÈ™teaptă o aserÈ›iune după (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R sau (?[+-]digiÈ›i trebuie urmaÈ›i de )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "nume necunoscut de clasă POSIX" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "Elementele POSIX de unire nu sunt suportate" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "valoarea caracterului în secvenÈ›a \\x{...} este prea mare" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "condiÈ›ie nevalidă (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C nu este permis în aserÈ›iunea lookbehind" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" +"caracterele de eludare \\L, \\l, \\N{nume}, \\U, È™i \\u nu sunt suportate" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "apelul recursiv ar putea intra în buclă infinită" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "caracter nerecunoscut după (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "terminator lipsă în numele de submodel" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "două submodele au acelaÈ™i nume" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "secvență eronată \\P sau \\p" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "nume necunoscut de proprietate după \\P ori \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "nume de submodel prea lung (sunt permise cel mult 32 de caractere)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "prea multe nume de submodeluri (sunt permise cel mult 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "valoarea octală este mai mare decât \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "spaÈ›iul de compilare a fost depășit" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "nu s-a găsit submodelul referit È™i verificat anterior" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "Grupul DEFINE conÈ›ine mai mult de o ramură" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "opÈ›iuni NEWLINE inconsistente" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g nu este urmat de un nume sau un număr între acolade, paranteze " +"unghiulare sau citate, sau de un număr simplu" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "o referință numerotată trebuie să fie diferită de zero" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "nu este permis un argument pentru (*ACCEPT), (*FAIL), sau (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) nu este recunoscut" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "numărul este prea mare" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "lipseÈ™te numele de sub-mostră după (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "s-a aÈ™teptat o cifră după (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] este un caracter de date nevalid în modul de compatibilitate JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "nume diferite pentru submodele ale aceluiaÈ™i număr nu sunt permise" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) trebuie să aibă un argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c trebuie să fie urmat de un caracter ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k nu este urmat de un nume scris între paranteze acolade, unghiulare sau " +"cu citate" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N nu este suportat într-o clasă" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "prea multe referinÈ›e de înaintare" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "numele este prea lung în (*MARK), (*PRUNE), (*SKIP), sau (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "valoarea caracterului în secvenÈ›a \\u.... este prea mare" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Eroare la compararea expresiei regulate %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Biblioteca PCRE este compilată cu suport UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Biblioteca PCRE este compilată fără suport pentru proprietăți UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Biblioteca PCRE este compilată cu opÈ›iuni incompatibile" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Eroare la optimizarea expresiei regulate %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Eroare la parsarea expresiei regulate %s la caracterul %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "s-a aÈ™teptat o cifră hexazecimală sau „}â€" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "se aÈ™tepta un digit hexadecimal" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "lipseÈ™te „<†în referinÈ›a simbolică" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "referință simbolică neterminată" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "referință simbolică de lungime zero" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "se aÈ™tepta un digit" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "referință simbolică ilegală" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "caracter neprevăzut la final „\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "secvență de eludare necunoscută" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Eroare în timpul parsării textului de înlocuire „%s†la caracterul %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Textul citat nu începe cu un semn de citare" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Semn de citare nepereche în linia de comandă sau alt text „shell-quotedâ€" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Textul s-a terminat imediat după un caracter „\\â€. (Textul era „%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Textul s-a terminat înainte de semnul de citare pereche pentru %c. (Textul " +"era „%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Textul era gol (sau conÈ›inea doar spaÈ›iu gol)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Nu s-au putut citi datele din procesul copil (%s)" + +#: glib/gspawn.c:461 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Eroare neaÈ™teptată la citirea datelor din procesul copil (%s)" + +#: glib/gspawn.c:546 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Eroare neaÈ™teptată în waitpid() (%s)" + +#: glib/gspawn.c:1168 glib/gspawn-win32.c:1426 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Procesul inferior a ieÈ™it cu codul %ld" + +#: glib/gspawn.c:1176 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Procesul inferior a fost terminat de semnalul %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Procesul inferior a fost oprit de semnalul %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process exited abnormally" +msgstr "Procesul inferior a ieÈ™it în mod neobiÈ™nuit" + +#: glib/gspawn.c:1881 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Nu s-au putut citi datele din conectorul „pipe†copil (%s)" + +#: glib/gspawn.c:2241 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Nu s-a putut crea procesul inferior „%s†(%s)" + +#: glib/gspawn.c:2358 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Nu s-a putut clona procesul (%s)" + +#: glib/gspawn.c:2518 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Nu s-a putut schimba la directorul „%s†(%s)" + +#: glib/gspawn.c:2528 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Nu s-a putut executa procesul inferior „%s†(%s)" + +#: glib/gspawn.c:2538 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" +"Nu s-a putut deschide fiÈ™ierul pentru a recartografia descriptorul de " +"fiÈ™iere (%s)" + +#: glib/gspawn.c:2546 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Nu s-a putut duplica descriptorul de fiÈ™ier pentru procesul copil (%s)" + +#: glib/gspawn.c:2555 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Nu s-a putut clona procesul copil (%s)" + +#: glib/gspawn.c:2563 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Nu s-a putut închide descriptorul de fiÈ™ier pentru procesul copil (%s)" + +#: glib/gspawn.c:2571 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Eroare necunoscută la executarea procesului inferior „%sâ€" + +#: glib/gspawn.c:2595 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Nu s-au putut citi date suficiente de la procesul copil (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Nu s-au putut citi datele de la procesul copil" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:519 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Nu s-a putut executa procesul copil (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Nu s-a putut clona «dup()» procesul copil (%s)" + +#: glib/gspawn-win32.c:469 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nume incorect de program: %s" + +#: glib/gspawn-win32.c:479 glib/gspawn-win32.c:797 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Secvență incorectă în vectorul argumentului la %d: %s" + +#: glib/gspawn-win32.c:490 glib/gspawn-win32.c:813 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Secvență incorectă în variabilele de mediu: %s" + +#: glib/gspawn-win32.c:793 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Director curent nevalid: %s" + +#: glib/gspawn-win32.c:858 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Nu s-a putut porni programul asociat (%s)" + +#: glib/gspawn-win32.c:1086 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Eroare neaÈ™teptată în g_io_channel_win32_poll() la citirea datelor de la " +"procesul copil" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Șirul gol nu este un număr" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s†nu este un număr negativ" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Numărul „%s†se află în afara intervalului [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s†nu este un număr pozitiv" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "%-e codare nevalidă în URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Caracter ilegal în URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Caractere non-UTF-8 în URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Adresă IPv6 nevalidă „%.*s†în URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Adresă IP codată ilegal „%.*s†în URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nume de gazdă internaÈ›ionalizat ilegal „%.*s†în URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Nu s-a putut parsa portul „%.*s†în URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Portul „%.*s†în URI este în afara intervalului" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI-ul „%s†nu este un URI absolut" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI-ul „%s†nu are nicio componentă gazdă" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI-ul nu este absolut, È™i nu s-a furnizat nicio bază URI" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "LipseÈ™te „=†și valoarea parametrului" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Nu s-a putut aloca memoria" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Caracter în afara limitelor standardului UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Secvență incorectă în inputul conversiei" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Caracter în afara limitelor standardului UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u octet" +msgstr[1] "%u octeÈ›i" +msgstr[2] "%u de octeÈ›i" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u biÈ›i" +msgstr[2] "%u de biÈ›i" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s octet" +msgstr[1] "%s octeÈ›i" +msgstr[2] "%s de octeÈ›i" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s biÈ›i" +msgstr[2] "%s de biÈ›i" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Failed to redirect output or input of child process (%s)" +#~ msgstr "Nu s-a putut redirecta ieÈ™irea sau inputul procesului copil (%s)" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Nu se poate încărca /var/lib/dbus/machine-id sau /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Eroare necunoscută la conectare" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Eroare în adresa „%s†- atributul familie este eronat" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "S-a montat %s la %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; se ignoră suprascrierea pentru această cheie.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " È™i --strict a fost specificat; se iese.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Se ignoră suprascrierea pentru această cheie.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "nu se face nimic.\n" + +#~ msgid "No such method '%s'" +#~ msgstr "Nu există metoda „%sâ€" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Nu s-a putut determina adresa magistralei din variabila de mediu " +#~ "DBUS_STARTER_BUS_TYPE - valoare necunoscută „%sâ€" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGUMENTE…]" + +#, fuzzy +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "Mesajul are %d fds, dar câmpul antet indică %d fds" + +#, fuzzy +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Eroare: calea către obiect nu a fost specificată\n" + +#, fuzzy +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Eroare: destinaÈ›ia nu a fost specificată\n" + +#, fuzzy +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Eroare: destinaÈ›ia nu a fost specificată\n" + +#, fuzzy +#~| msgid "Failed to create file '%s': %s" +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Nu s-a putut crea fiÈ™ierul „%sâ€: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "" +#~ "Nu s-a putut deschide fiÈ™ierul „%s†pentru scriere, fdopen() a eÈ™uat: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Nu s-a putut scrie fiÈ™ierul „%sâ€: fflush() eÈ™uat: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Nu s-a putut închide fiÈ™ierul „%sâ€: fclose() a eÈ™uat: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "s-a atins limita maximă pentru subÈ™iruri nule" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "nu se permite aici trecerea la majuscule sau invers prin folosirea de " +#~ "caractere „escape†(\\l, \\L, \\u, \\U)" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "nu se permite repetarea unui grup DEFINE" + +#~ msgid "File is empty" +#~ msgstr "FiÈ™ierul e gol" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "FiÈ™ierul cheie nu are cheia „%sâ€" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "FiÈ™ierul cheie conÈ›ine cheia „%sâ€, ce are o valoare neinterpretabilă." + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "Eroare la lansarea liniei de comandă „%s†s-a terminat anormal: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "" +#~ "Linia de comandă „%s†s-a încheiat cu un cod non-zero de eroare %d: %s" + +#~ msgid "Error statting directory '%s': %s" +#~ msgstr "Eroare la aflarea statisticilor despre dosarul „%sâ€: %s" + +#~ msgid "No such interface" +#~ msgstr "Nu există interfaÈ›a" + +#~ msgid "This option will be removed soon." +#~ msgstr "Această opÈ›iune va fi eliminată în curând." + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "" +#~ "Nu s-a putut identifica tipul implicit de monitorizare a directoarelor " +#~ "locale" + +#~ msgid "Error opening file: %s" +#~ msgstr "Eroare la deschiderea fiÈ™ierului: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Eroare la crearea directorului: %s" + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Eroare la citirea detaliilor fiÈ™ierului „%sâ€: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "Nu există înregistrări de serviciu pentru „%sâ€" + +#~ msgid "Error connecting: " +#~ msgstr "Eroare la conectare: " + +#~ msgid "Error connecting: %s" +#~ msgstr "Eroare la conectare: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "" +#~ "Implementarea SOCKSv4 limitează numele de utilizator la %i caractere" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "Implementarea SOCKSv4 limitează numele gazdei la %i caractere" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Lungime de opÈ›iune neaÈ™teptată în timp ce se verifica dacă SO_PASSCRED " +#~ "este activat pe socket. Se aÈ™teptau %d octeÈ›i, s-a primit %d" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Eroare la citirea din „unixâ€: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "Eroare la închiderea „unixâ€: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Eroare la scrierea în „unixâ€: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "editarea asocierilor de fiÈ™iere nu e implementată în win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Crearea asocierilor de fiÈ™iere nu este implementată în win32" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "am" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "" +#~ "Tipul valorii rezultatului nu este corect, s-a primit „%sâ€, se aÈ™tepta " +#~ "„%sâ€" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "S-a încercat setarea proprietății %s cu tipul %s, dar conform interfeÈ›ei " +#~ "aÈ™teptate tipul este %s" + +#~ msgid "No such schema '%s' specified in override file '%s'" +#~ msgstr "Nu există schema „%s†specificată în fiÈ™ierul de suprascriere „%sâ€" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " reset Reset the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "Comenzi:\n" +#~ " help AfiÈ™ează aceste informaÈ›ii\n" +#~ " get ObÈ›ine valoarea unei chei\n" +#~ " set Setează valoarea unei chei\n" +#~ " reset Resetează valoarea unei chei\n" +#~ " monitor Monitorizează o cheie pentru schimbări\n" +#~ " writable Verifică dacă o cheie poate fi scrisă\n" +#~ "\n" +#~ "UtilizaÈ›i '%s COMANDÄ‚ --help' pentru a primi ajutor pentru comenzi " +#~ "individuale.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "Specifică calea către schemă" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "Argumente:\n" +#~ " SCHEMÄ‚ Identificatorul schemei\n" +#~ " CHEIE Numele cheii\n" +#~ " VALOARE Valoarea la care se defineÈ™te cheia, cum este serializată " +#~ "de GVariant\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "Monitorizează cheia CHEIE pentru modificări È™i afiÈ™ează valorile " +#~ "modificate.\n" +#~ "Monitorizarea va continua până când procesul este terminat." + +#~ msgid "Error writing first 16 bytes of message to socket: " +#~ msgstr "Eroare la scrierea primilor 16 octeÈ›i ai mesajului în socket: " + +#~ msgid "The nonce-file '%s' was %lu bytes. Expected 16 bytes." +#~ msgstr "FiÈ™ierul nonce „%s†are %lu octeÈ›i. Se aÈ™teptau exact 16 octeÈ›i." diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 0000000..31a5f54 --- /dev/null +++ b/po/ru.po @@ -0,0 +1,6371 @@ +# translation of ru.po to Russian +# Copyright (C) 1998-2002, 2004, 2006, 2008, 2010 Free Software Foundation, Inc. +# +# Valek Filippov , 2001-2002. +# Dmitry G. Mastrukov , 2002-2003. +# Leonid Kanter , 2004, 2006, 2010. +# Vasiliy Faronov , 2008. +# Yuri Kozlov , 2008. +# Anisimov Victor , 2009. +# Yuri Kozlov , 2010, 2011, 2012. +# Yuri Myasoedov , 2012-2014. +# Stas Solovey , 2015, 2016. +# Ivan Komaritsyn , 2015, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: ru\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-04-08 12:19+0000\n" +"PO-Revision-Date: 2022-04-08 15:24+0300\n" +"Last-Translator: Aleksandr Melman \n" +"Language-Team: РуÑÑкий \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Poedit 3.0.1\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "УÑтановка приложений по умолчанию пока не поддерживаетÑÑ" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"УÑтановка Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÐºÐ°Ðº поÑледнего иÑпользованного Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° файла, который " +"еще не поддерживаетÑÑ" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Параметры GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Показать параметры GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"ЗапуÑтить GApplication в режиме ÑервиÑа (иÑпользовать из ÑервиÑных файлов D-" +"Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Переопределить идентификатор приложениÑ" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Заменить запущенный ÑкземплÑÑ€" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Ðапечатать Ñправку" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[КОМÐÐДÐ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "ВывеÑти номер верии" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "ВывеÑти информацию о верÑии и выйти" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "ВывеÑти ÑпиÑок приложений" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"ВывеÑти ÑпиÑок уÑтановленных активируемых по D-Bus приложений (по desktop-" +"файлам)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "ЗапуÑтить приложение" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "ЗапуÑтить приложение (Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸ÐµÐ¼ необÑзательных файлов)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "ID_ПРИЛОЖЕÐИЯ [ФÐЙЛ…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Ðктивировать дейÑтвие" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Вызвать дейÑтвие приложениÑ" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ИД_ПРИЛОЖЕÐИЯ ДЕЙСТВИЕ [ПÐРÐМЕТР]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "ВывеÑти ÑпиÑок доÑтупных дейÑтвий" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "ВывеÑти ÑпиÑок ÑтатичеÑких дейÑтвий Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (из desktop-файла)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ID_ПРИЛОЖЕÐИЯ" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "КОМÐÐДÐ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Команда, по которой выводитÑÑ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ñправка" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Идентификатор Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² формате D-Bus (напр.: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "ФÐЙЛ" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"ÐеобÑзательные отноÑительные или абÑолютные имена файлов или адреÑа URI Ð´Ð»Ñ " +"открытиÑ" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ДЕЙСТВИЕ" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Ð˜Ð¼Ñ Ð²Ñ‹Ð·Ñ‹Ð²Ð°ÐµÐ¼Ð¾Ð³Ð¾ дейÑтвиÑ" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "ПÐРÐМЕТР" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "ÐеобÑзательный параметр Ð´Ð»Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° дейÑÑ‚Ð²Ð¸Ñ Ð² формате GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"ÐеизвеÑÑ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "ИÑпользование:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Ðргументы:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ÐРГУМЕÐТЫ…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Команды:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ИÑпользуйте команду «%s help КОМÐÐДл Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ð¹ Ñправки.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"команде %s требуетÑÑ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ приложениÑ\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "недопуÑтимый идентификатор приложениÑ: «%s»\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"«%s» не принимает аргументов\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "невозможно подключитьÑÑ Ðº D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "ошибка отправки ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ %s приложению: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "Ð¸Ð¼Ñ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ указыватьÑÑ Ð¿Ð¾Ñле идентификатора приложениÑ\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"недопуÑтимое Ð¸Ð¼Ñ Ð´ÐµÐ¹ÑтвиÑ: «%s»\n" +"Ð¸Ð¼Ñ Ð¼Ð¾Ð¶ÐµÑ‚ ÑоÑтоÑть только из букв, цифр и Ñимволов «-» и «.»\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "ошибка разбора параметра дейÑтвиÑ: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "дейÑÑ‚Ð²Ð¸Ñ Ð¿Ñ€Ð¸Ð½Ð¸Ð¼Ð°ÑŽÑ‚ макÑимум один параметр\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "команда list-actions принимает только идентификатор приложениÑ" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "невозможно найти desktop-файл Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"нераÑÐ¿Ð¾Ð·Ð½Ð°Ð½Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Слишком большое значение количеÑтва передано в %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Переход в базовом потоке не поддерживаетÑÑ" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "ÐÐµÐ»ÑŒÐ·Ñ ÑƒÑечь GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Поток уже закрыт" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "УÑечение не поддерживаетÑÑ Ð² базовом потоке" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "ДейÑтвие было отменено" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "ÐедопуÑтимый объект, не инициализировано" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "ÐÐµÐ¿Ð¾Ð»Ð½Ð°Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð±Ð°Ð¹Ñ‚Ð¾Ð²Ð°Ñ Ð¿Ð¾ÑледовательноÑть во входных данных" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "ÐедоÑтаточно меÑта в целевом раÑположении" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¿Ð¾ÑледовательноÑть байтов во входных преобразуемых данных" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Произошла ошибка при преобразовании: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "ÐŸÑ€ÐµÑ€Ñ‹Ð²Ð°ÐµÐ¼Ð°Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ðµ поддерживаетÑÑ" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Преобразование из набора Ñимволов «%s» в «%s» не поддерживаетÑÑ" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Ðе удалоÑÑŒ открыть преобразователь из «%s» в «%s»" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "Тип %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "ÐеизвеÑтный тип" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "Тип файлов %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "Объект GCredentials Ñодержит некорректные данные" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "Тип GCredentials не реализован Ð´Ð»Ñ Ñтой ОС" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Поддержка GCredentials Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ платформы отÑутÑтвует" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "Тип GCredentials не Ñодержит идентификатора процеÑÑа Ð´Ð»Ñ Ñтой ОС" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Спуфинг учётных данных невозможен в Ñтой ОС" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Ðеожиданный ранний конец потока" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Ðеподдерживаемый ключ «%s» в Ñлементе адреÑа «%s»" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "БеÑÑмыÑÐ»ÐµÐ½Ð½Ð°Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ ÐºÐ»ÑŽÑ‡/значение в Ñлементе адреÑа «%s»" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Ðеправильный Ð°Ð´Ñ€ÐµÑ Â«%s» (требуетÑÑ Ð¿ÑƒÑ‚ÑŒ, временный каталог или один из " +"абÑтрактных ключей)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Ошибка в адреÑе «%s» — неправильный формат атрибута «%s»" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "ÐеизвеÑтный или неподдерживаемый транÑпорт «%s» Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа «%s»" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Ð’ Ñлементе адреÑа «%s» отÑутÑтвует двоеточие (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Ðазвание протокола в Ñлементе адреÑа “%s†не должен быть пуÑтым" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Пара ключ/значение %d, «%s», в Ñлементе адреÑа «%s» не Ñодержит знака " +"равенÑтва" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Пара ключ/значение %d, «%s», в Ñлементе адреÑа «%s» не должна иметь пуÑтого " +"ключа" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Ошибка ÑнÑÑ‚Ð¸Ñ ÑÐºÑ€Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð° или Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² паре ключ/значение %d, " +"«%s», в Ñлементе адреÑа «%s»" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Ошибка в адреÑе «%s» — Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ñпорта unix требуетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ один " +"уÑтановленный ключ «path» или «abstract»" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Ошибка в адреÑе «%s» — атрибут узла отÑутÑтвует или имеет неправильный формат" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Ошибка в адреÑе «%s» — атрибут порта отÑутÑтвует или имеет неправильный " +"формат" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Ошибка в адреÑе «%s» — атрибут noncefile отÑутÑтвует или имеет неправильный " +"формат" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Ошибка автоматичеÑкого запуÑка: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Произошла ошибка при открытии nonce-файла «%s»: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Произошла ошибка при чтении nonce-файла «%s»: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Произошла ошибка при чтении nonce-файла «%s», ожидалоÑÑŒ 16 байт, получено %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Произошла ошибка запиÑи Ñодержимого nonce-файла «%s» в поток:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Указанный Ð°Ð´Ñ€ÐµÑ Ð¿ÑƒÑÑ‚" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Ðевозможно Ñоздать шину Ñообщений, когда уÑтановлено значение AT_SECURE" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ðевозможно породить процеÑÑ ÑˆÐ¸Ð½Ñ‹ Ñообщений без идентификатора машины: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Ðевозможно автоматичеÑки запуÑтить D-Bus без X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Произошла ошибка при Ñоздании процеÑÑа командной Ñтроки «%s»: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Ðе удалоÑÑŒ определить Ð°Ð´Ñ€ÐµÑ ÑеанÑовой шины (не реализовано Ð´Ð»Ñ Ñтой ОС)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Ðе удалоÑÑŒ определить Ð°Ð´Ñ€ÐµÑ ÑˆÐ¸Ð½Ñ‹ из Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ " +"DBUS_STARTER_BUS_TYPE — неизвеÑтное значение «%s»" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ðе удалоÑÑŒ определить Ð°Ð´Ñ€ÐµÑ ÑˆÐ¸Ð½Ñ‹, Ñ‚. к. значение переменной Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ " +"DBUS_STARTER_BUS_TYPE не уÑтановлено" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "ÐеизвеÑтный тип шины %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Ðеожиданное отÑутÑтвие Ñодержимого при чтении Ñтроки" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Ðеожиданное отÑутÑтвие Ñодержимого при (надёжном) чтении Ñтроки" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Перепробованы вÑе доÑтупные механизмы аутентификации (проведено: %s) " +"(доÑтупно: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Идентификаторы Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ быть и на клиенте и на Ñервере" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Отменено через GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Ошибка при получении информации о каталоге «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "Ошибочные права на каталог «%s». ОжидалоÑÑŒ 0700, получено 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Произошла ошибка при Ñоздании каталога «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "ДейÑтвие не поддерживаетÑÑ" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Произошла ошибка при открытии ÑвÑзки ключей «%s» на чтение: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "ÐÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ñтрока %d в ÑвÑзке ключей около «%s» Ñ Ñодержимым «%s»" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"ÐÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð¿ÐµÑ€Ð²Ð°Ñ Ð»ÐµÐºÑема в Ñтроке %d в ÑвÑзке ключей около «%s» Ñ " +"Ñодержимым «%s»" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"ÐÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð²Ñ‚Ð¾Ñ€Ð°Ñ Ð»ÐµÐºÑема в Ñтроке %d в ÑвÑзке ключей около «%s» Ñ " +"Ñодержимым «%s»" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Ðе удалоÑÑŒ найти куки Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ %d в ÑвÑзке ключей «%s»" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Произошла ошибка при Ñоздании файла блокировки «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Произошла ошибка при удалении уÑтаревшего файла блокировки «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Произошла ошибка при закрытии (удалённого) файла блокировки «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Произошла ошибка при удалении файла блокировки «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Произошла ошибка при открытии ÑвÑзки ключей «%s» на запиÑÑŒ: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Также, не удалоÑÑŒ оÑвободить блокировку Ð´Ð»Ñ Â«%s»: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Соединение закрыто" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¸Ñтекло" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "При Ñоздании клиентÑкого ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ñ‹ неподдерживаемые флаги" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Â«org.freedesktop.DBus.Properties» Ð´Ð»Ñ Ð¿ÑƒÑ‚Ð¸ %s объекта не найден" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "СвойÑтво «%s» отÑутÑтвует" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "СвойÑтво «%s» недоÑтупно Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "СвойÑтво «%s» недоÑтупно Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "Ошибка уÑтановки ÑвойÑтва «%s»: ожидалÑÑ Ñ‚Ð¸Ð¿ «%s», но получен «%s»" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Â«%s» отÑутÑтвует" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Â«%s» Ð´Ð»Ñ Ð¿ÑƒÑ‚Ð¸ %s объекта не найден" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Ключ «%s» отÑутÑтвует" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Тип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Â«%s» не Ñовпадает Ñ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼Ñ‹Ð¼ типом «%s»" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Объект интерфейÑа %s уже ÑкÑпортирован как %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Ðевозможно получить ÑвойÑтво %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Ðевозможно уÑтановить ÑвойÑтво %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Метод «%s» вернул тип «%s», но ожидалоÑÑŒ «%s»" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Метод «%s» интерфейÑа «%s» Ñ Ñигнатурой «%s» не ÑущеÑтвует" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Поддерево уже ÑкÑпортировано Ð´Ð»Ñ %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Объект по пути «%s» не ÑущеÑтвует" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "тип ÑвлÑетÑÑ ÐЕДОПУСТИМЫМ" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Сообщение METHOD_CALL: отÑутÑтвует поле заголовка PATH или MEMBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Сообщение METHOD_RETURN: отÑутÑтвует поле заголовка REPLY_SERIAL" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Сообщение ERROR: отÑутÑтвует поле заголовка REPLY_SERIAL или ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Сообщение SIGNAL: отÑутÑтвует поле заголовка PATH, INTERFACE или MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Сообщение SIGNAL: поле заголовка PATH иÑпользует зарезервированное значение /" +"org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Сообщение SIGNAL: поле заголовка INTERFACE иÑпользует зарезервированное " +"значение org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "ТребовалоÑÑŒ прочитать %lu байт, но прочитано только %lu" +msgstr[1] "ТребовалоÑÑŒ прочитать %lu байта, но прочитано только %lu" +msgstr[2] "ТребовалоÑÑŒ прочитать %lu байт, но прочитано только %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "ОжидалÑÑ Ð±Ð°Ð¹Ñ‚ NUL поÑле Ñтроки «%s», но найден байт %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"ОжидалаÑÑŒ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ñтрока UTF-8, но обнаружены недопуÑтимые байты " +"(Ñмещение %d, длина Ñтроки %d). ÐšÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ñтрока UTF-8 вплоть до тех байт: " +"«%s»" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Слишком Ð³Ð»ÑƒÐ±Ð¾ÐºÐ°Ñ Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Разобранное значение «%s» не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым путём объекта D-Bus" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Разобранное значение «%s» не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимой подпиÑью D-Bus" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Обнаружен маÑÑив длинной %u байт. МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° равна 2<<26 байт (64 " +"МиБ)." +msgstr[1] "" +"Обнаружен маÑÑив длинной %u байта. МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° равна 2<<26 байт (64 " +"МиБ)." +msgstr[2] "" +"Обнаружен маÑÑив длинной %u байт. МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° равна 2<<26 байт (64 " +"МиБ)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Получен маÑÑив типа «a%c», который должен иметь размер кратный %u (байт), но " +"маÑÑив имеет длину %u (байт)" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "ПуÑтые Ñтруктуры (запиÑи) не допуÑкаютÑÑ Ð² D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"Разобранное значение «%s» Ð´Ð»Ñ Ð²Ð°Ñ€Ð¸Ð°Ð½Ñ‚Ð° не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимой подпиÑью D-Bus" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Ошибка деÑериализации GVariant Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ Ñтроки «%s» из формата D-Bus wire" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Ðеправильный порÑдок байтов в значении. ОжидалÑÑ 0x6c ('l') или 0x42 ('B'), " +"но найдено значение 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Ðеправильный Ñтарший номер верÑии протокола. ОжидалÑÑ 1, но найден %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Заголовок подпиÑи найден, но его тип отличаетÑÑ Ð¾Ñ‚ подпиÑи" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "Ðайден заголовок подпиÑи Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñью «%s», но тело ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¿ÑƒÑто" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Разобранное значение «%s» не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимой подпиÑью D-Bus (Ð´Ð»Ñ Ñ‚ÐµÐ»Ð°)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"ОтÑутÑтвует заголовок подпиÑи в Ñообщении, но тело ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð·Ð°Ð½Ð¸Ð¼Ð°ÐµÑ‚ %u байт" +msgstr[1] "" +"ОтÑутÑтвует заголовок подпиÑи в Ñообщении, но тело ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð·Ð°Ð½Ð¸Ð¼Ð°ÐµÑ‚ %u " +"байта" +msgstr[2] "" +"ОтÑутÑтвует заголовок подпиÑи в Ñообщении, но тело ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð·Ð°Ð½Ð¸Ð¼Ð°ÐµÑ‚ %u байт" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Ðе удалоÑÑŒ выполнить извлечение ÑообщениÑ: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "Ошибка Ñериализации GVariant Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ Ñтроки «%s» в формат D-Bus wire" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"КоличеÑтво деÑкрипторов файлов в Ñообщении (%d) отличаетÑÑ Ð¾Ñ‚ указанного в " +"заголовке (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Ðе удалоÑÑŒ Ñериализовать Ñообщение: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Тело ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐµÑ‚ подпиÑÑŒ «%s», но нет заголовка подпиÑи" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Тело ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐµÑ‚ тип подпиÑи «%s», но значение подпиÑи в поле заголовка " +"равно «%s»" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"Тело ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¿ÑƒÑто, но значение подпиÑи в поле заголовка равно «(%s)»" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Возвращена ошибка Ñ Ñ‚ÐµÐ»Ð¾Ð¼ типа «%s»" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Возвращена ошибка Ñ Ð¿ÑƒÑтым телом" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Чтобы закрыть Ñто окно, введите любой Ñимвол)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Ð¡ÐµÐ°Ð½Ñ dbus не запущен, и автозапуÑк не выполнилÑÑ" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Ðе удалоÑÑŒ получить профиль аппаратуры: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Ðе удалоÑÑŒ загрузить %s или %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Ошибка вызова StartServiceByName Ð´Ð»Ñ %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Ðеожиданный ответ %d из метода StartServiceByName(«%s»)" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ðе удалоÑÑŒ вызвать метод; у прокÑи Ñ Ñ…Ð¾Ñ€Ð¾ÑˆÐ¾ извеÑтным именем %s нет " +"владельца и прокÑи Ñоздать Ñ Ñ„Ð»Ð°Ð³Ð¾Ð¼ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "ÐбÑтрактное проÑтранÑтво имён не поддерживаетÑÑ" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Ðе удалоÑÑŒ задать nonce-файл при Ñоздании Ñервера" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Произошла ошибка при запиÑи в nonce-файл у «%s»: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Строка «%s» не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Ðевозможно проÑлушивать неподдерживаемый транÑпорт «%s»" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Команды:\n" +" help Показать Ñту Ñправку\n" +" introspect ИнтроÑпектировать удалённый объект\n" +" monitor Следить за удалённым объектом\n" +" call Вызвать метод удалённого объекта\n" +" emit ПоÑлать Ñигнал\n" +" wait Подождать поÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐ½Ð¸ шины\n" +"\n" +"Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки по команде иÑпользуйте «%s КОМÐÐДР--help».\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Ошибка: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Произошла ошибка при разборе интроÑпекции XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Ошибка: %s не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым именем\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Ошибка: %s не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым объектным путём\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "ПодключитьÑÑ Ðº ÑиÑтемной шине" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "ПодключитьÑÑ Ðº пользовательÑкой шине" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "ПодключитьÑÑ Ðº заданному адреÑу D-Bus" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Параметры оконечной точки ÑоединениÑ:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Параметры, определÑющие оконечную точку ÑоединениÑ" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "ÐžÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ указана" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Указано неÑколько оконечных точек ÑоединениÑ" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Предупреждение: ÑоглаÑно данным интроÑпекции, Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Â«%s» не ÑущеÑтвует\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Предупреждение: ÑоглаÑно данным интроÑпекции, метод «%s» в интерфейÑе «%s» " +"не ÑущеÑтвует\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "ÐеобÑзательный получатель Ñигнала (уникальное имÑ)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Объектный путь, Ð´Ð»Ñ Ð²Ñ‹Ð¿ÑƒÑка Ñигнала" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Ðазвание Ñигнала и интерфейÑа" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "ПоÑлать Ñигнал." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Произошла ошибка при Ñоединении: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Ошибка: %s не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым уникальным именем шины.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Ошибка: не указан объектный путь\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Ошибка: не указано Ð¸Ð¼Ñ Ñигнала\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Ошибка: неправильное Ð¸Ð¼Ñ Ñигнала «%s»\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Ошибка: %s не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым именем интерфейÑа\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Ошибка: %s не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым именем члена\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Произошла ошибка при разборе параметра %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Произошла ошибка при ÑброÑе подключениÑ: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Ð˜Ð¼Ñ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ вызываетÑÑ Ð¼ÐµÑ‚Ð¾Ð´" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Объектный путь, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ вызываетÑÑ Ð¼ÐµÑ‚Ð¾Ð´" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Ðазвание метода или интерфейÑа" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð² Ñекундах" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Разрешить интерактивную авторизацию" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Вызывает метод на удалённом объекте." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Ошибка: не указано назначение\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Ошибка: %s не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым именем шины\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Ошибка: не указано Ð¸Ð¼Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð°\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Ошибка: неправильное Ð¸Ð¼Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° «%s»\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Произошла ошибка при разборе параметра %d типа «%s»: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Произошла ошибка при добавлении деÑкриптора %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Ð˜Ð¼Ñ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¸Ð½Ñ‚Ñ€Ð¾Ñпекции" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Объектный путь Ð´Ð»Ñ Ð¸Ð½Ñ‚Ñ€Ð¾Ñпекции" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Ðапечатать XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "ИнтроÑÐ¿ÐµÐºÑ†Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ°" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Только ÑвойÑтва печати" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Выполнить интроÑпекцию удалённого объекта." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Ð˜Ð¼Ñ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸Ñ" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Объектный путь Ð´Ð»Ñ Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸Ñ" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Ðаблюдать за удалённым объектом." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Ошибка: невозможно Ñледить за Ñоединением non-message-bus\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Ð¡ÐµÑ€Ð²Ð¸Ñ Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸ перед ожиданием другого (хорошо извеÑтное имÑ)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Срок ожидание до выхода Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹ (Ñекунды); 0 Ð´Ð»Ñ Ð±ÐµÑконечноÑти (по " +"умолчанию)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[ПÐРÐМЕТР…] ИМЯ-ШИÐЫ" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "ДождитеÑÑŒ поÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐ½Ð¸ шины." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Ошибка: должен быть указан ÑÐµÑ€Ð²Ð¸Ñ Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Ошибка: должен быть указан ÑÐµÑ€Ð²Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Ошибка: Ñлишком много аргументов.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Ошибка: %s не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым извеÑтным именем шины\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Ðе вправе изменÑть наÑтройки отладки" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Без имени" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Ð’ desktop-файле не указано поле Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Ðе удалоÑÑŒ найти терминал, требуемый Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Ðе удалоÑÑŒ Ñоздать пользовательÑкую папку наÑтроек Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Ðе удалоÑÑŒ Ñоздать пользовательÑкую папку наÑтроек MIME %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Ð’ информации о приложении отÑутÑтвует идентификатор" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Ðе удалоÑÑŒ Ñоздать пользовательÑкий desktop-файл %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "ОÑобое определение Ð´Ð»Ñ %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "привод не поддерживает извлечение" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "привод не поддерживает извлечение или извлечение_Ñ_операцией" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "привод не поддерживает Ð¾Ð¿Ñ€Ð¾Ñ Ð½Ð¾ÑителÑ" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "привод не поддерживает запуÑк" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "привод не поддерживает оÑтановку" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "Библиотека TLS не реализует Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° TLS binding" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Поддержка TLS недоÑтупна" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Поддержка DTLS недоÑтупна" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Ðе удалоÑÑŒ обработать верÑию %d текÑтового предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Ðекорректное чиÑло лекÑем (%d) текÑтового предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Ðе удалоÑÑŒ обработать верÑию %d текÑтового предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Ðекорректное чиÑло лекÑем (%d) текÑтового предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Ð”Ð»Ñ GEmblemedIcon ожидаетÑÑ GEmblem" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Ð¡Ð¾Ð´ÐµÑ€Ð¶Ð°Ñ‰Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ ÑущеÑтвует" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "ÐÐµÐ»ÑŒÐ·Ñ Ñкопировать поверх каталога" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "ÐÐµÐ»ÑŒÐ·Ñ Ñкопировать каталог поверх каталога" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Целевой файл ÑущеÑтвует" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Ðе удалоÑÑŒ рекурÑивно Ñкопировать каталог" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Соединение не поддерживаетÑÑ" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Произошла ошибка при Ñоединении файла: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"Копирование (reflink/clone) между точками Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживаетÑÑ" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Копирование (reflink/clone) не поддерживаетÑÑ Ð¸Ð»Ð¸ некорректно" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Копирование (reflink/clone) не поддерживаетÑÑ Ð¸Ð»Ð¸ не работает" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "ÐÐµÐ»ÑŒÐ·Ñ Ñкопировать Ñпециальный файл" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Дано неверное значение Ñимвольной ÑÑылки" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Символьные ÑÑылки не поддерживаютÑÑ" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Корзина не поддерживаетÑÑ" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Имена файлов не могут Ñодержать «%c»" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "том не поддерживает приÑоединение" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Ðет зарегиÑтрированного Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ данного файла" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "ПеречиÑлитель закрыт" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ПеречиÑлитель файлов имеет незавершённое дейÑтвие" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ПеречиÑлитель файлов уже закрыт" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Ðе удалоÑÑŒ обработать верÑию %d текÑтового предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Ðекорректные входные данные Ð´Ð»Ñ GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Поток не поддерживает query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Переход по потоку не поддерживаетÑÑ" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "УÑечение на входном потоке не разрешено" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "УÑечение не поддерживаетÑÑ Ð½Ð° потоке" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð°" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Ðеправильный ответ прокÑи HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Соединение прокÑи HTTP запрещено" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Сбой аутентификации прокÑи HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "ТребуетÑÑ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿Ñ€Ð¾ÐºÑи HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Сбой ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾ÐºÑи HTTP: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Ответ HTTP Ñ Ð¿Ñ€Ð¾ÐºÑи Ñлишком большой" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Cервер прокÑи HTTP неожиданно закрыл Ñоединение." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Ðеверное чиÑло лекÑем (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Ðет типа Ð´Ð»Ñ ÐºÐ»Ð°ÑÑа Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Тип %s не реализует Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Тип %s не ÑвлÑетÑÑ ÐºÐ»Ð°ÑÑифицируемым" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Ðекорректный номер верÑии: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Тип %s не реализует from_tokens() интерфейÑа GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Ðе удалоÑÑŒ обработать данную верÑию текÑтового предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð½Ð°Ñ‡ÐºÐ°" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "ÐÐ´Ñ€ÐµÑ Ð½Ðµ указан" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Значение длины %u Ñлишком велико Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Ð’ адреÑе уÑтановлены биты вне пределов длины префикÑа" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Ðевозможно Ñчитать «%s» маÑкой IP-адреÑа" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "ÐедоÑтаточно меÑта Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа Ñокета" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Ðеподдерживаемый Ð°Ð´Ñ€ÐµÑ Ñокета" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Входной поток не поддерживает чтение" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Поток имеет незавершённое дейÑтвие" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Копировать Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "СохранÑть Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ при перемещении" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "«version» не принимает аргументов" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "ИÑпользование:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "ВывеÑти информацию о верÑии и выйти." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Команды:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Объединить файлы и вывеÑти в Ñтандартный вывод" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Копировать один или неÑколько файлов" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Показать информацию о раÑположениÑÑ…" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "ЗапуÑтить приложение из desktop-файла" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Показать Ñодержимое раÑположений" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Получить или уÑтановить обработчик Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Создать каталоги" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "ОтÑлеживать изменение файлов и каталогов" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Монтирование или размонтирование раÑположений" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "ПеремеÑтить один или неÑколько файлов" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Открыть файлы приложением по умолчанию" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Переименовать файл" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Удалить один или неÑколько файлов" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Прочитать Ñо Ñтандартного входа и Ñохранить" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "УÑтановить атрибут файла" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "ПеремеÑтить файлы или каталоги в корзину" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Показать Ñодержимое раÑположений в виде дерева" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "ИÑпользуйте команду %s Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ð¹ Ñправки.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Ошибка при запиÑи в stdout" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "РÐСПОЛОЖЕÐИЕ" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Объединить файлы и вывеÑти в Ñтандартный вывод." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat работает так же, как и Ð¾Ð±Ñ‹Ñ‡Ð½Ð°Ñ ÑƒÑ‚Ð¸Ð»Ð¸Ñ‚Ð° cat, но иÑпользует GIO-" +"раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¼ÐµÑто локальных файлов: например, вы можете иÑпользовать что-" +"то вроде smb://server/resource/file.txt в качеÑтве раÑположениÑ." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Ðе указаны адреÑа" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ðе указан целевой каталог" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Показать ход выполнениÑ" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Спрашивать перед перезапиÑью" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "СохранÑть вÑе атрибуты" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Создать резервную копию ÑущеÑтвующих файлов назначениÑ" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Ðикогда не переходить по ÑимволичеÑким ÑÑылкам" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "ИÑпользовать Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Передано %s из %s (%s/Ñ)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ИСТОЧÐИК" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ПРИÐМÐИК" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "" +"Копировать один или неÑколько файлов из ИСТОЧÐИКРв каталог ÐÐЗÐÐЧЕÐИЯ." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy работает так же, как и Ð¾Ð±Ñ‹Ñ‡Ð½Ð°Ñ ÑƒÑ‚Ð¸Ð»Ð¸Ñ‚Ð° cp, но иÑпользует\n" +"GIO-раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¼ÐµÑто локальных файлов: например, вы можете иÑпользовать\n" +"что-то вроде smb://server/resource/file.txt в качеÑтве раÑположениÑ." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Цель «%s» не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: перезапиÑать «%s»? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "ВывеÑти ÑпиÑок доÑтупных Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи атрибутов" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Получить информацию о файловой ÑиÑтеме" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Получаемые атрибуты" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ÐТРИБУТЫ" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ðе переходить по ÑимволичеÑким ÑÑылкам" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "атрибуты:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "отображаемое имÑ: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "редактируемое имÑ: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "имÑ: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "тип: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "размер: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "Ñкрытый\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "локальный путь: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "УÑтанавливаемые атрибуты:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "ПроÑтранÑтва имён запиÑываемых атрибутов:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Показать информацию о раÑположениÑÑ…." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info работает так же, как и Ð¾Ð±Ñ‹Ñ‡Ð½Ð°Ñ ÑƒÑ‚Ð¸Ð»Ð¸Ñ‚Ð° ls, но иÑпользует\n" +"GIO-раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¼ÐµÑто локальных файлов: например, вы можете иÑпользовать\n" +"что-то вроде smb://server/resource/file.txt в качеÑтве раÑположениÑ. " +"Ðтрибуты файлов\n" +"могут быть указаны Ñ Ð¸Ñ… GIO-именем, например: standard::icon, или проÑто\n" +"по проÑтранÑтву имен, например: unix, или \"*\", который ÑоответÑтвует вÑем " +"атрибутам" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-ФÐЙЛ [ÐРГУМЕÐТЫ_ФÐЙЛР…]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"ЗапуÑтить приложение из desktop-файла Ñ Ð¾Ð¿Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ñ‹Ð¼Ð¸ аргументами Ð´Ð»Ñ Ð½ÐµÐ³Ð¾." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Ðе указаны desktop-файл" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Команда запуÑка Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ платформы отÑутÑтвует" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Ðе удалоÑÑŒ загрузить «%s»: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Ðе удалоÑÑŒ загрузить информацию о приложении Ð´Ð»Ñ Â«%s»" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Ðе удалоÑÑŒ запуÑтить приложение «%s»: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Показывать Ñкрытые файлы" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "ИÑпользовать раÑширенный формат" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "ВывеÑти отображаемые имена" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Выводить полные URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Показать Ñодержимое адреÑов." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list работает так же, как и Ð¾Ð±Ñ‹Ñ‡Ð½Ð°Ñ ÑƒÑ‚Ð¸Ð»Ð¸Ñ‚Ð° ls, но иÑпользует\n" +"GIO-раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¼ÐµÑто локальных файлов: например, вы можете иÑпользовать\n" +"что-то вроде smb://server/resource/file.txt в качеÑтве раÑположениÑ. " +"Ðтрибуты файлов\n" +"могут быть указаны Ñ Ð¸Ñ… GIO-именем, например: standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "ТИП-MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "ОБРÐБОТЧИК" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "УÑтановить или получить обработчик Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"ЕÑли обработчик не задан, показать зарегиÑтрированные и рекомендуемые " +"приложениÑ\n" +"Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° mime. ЕÑли обработчик задан, он уÑтанавливаетÑÑ ÐºÐ°Ðº обработчик\n" +"по умолчанию Ð´Ð»Ñ Ñтого типа mime." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Ðеобходимо указать один тип mime и возможно обработчик" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Ð”Ð»Ñ Â«%s» нет Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Приложение по умолчанию Ð´Ð»Ñ Â«%s»: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "ЗарегиÑтрированные приложениÑ:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Ðет зарегиÑтрированных приложений\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Рекомендуемые приложениÑ:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Ðет рекомендуемых приложений\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "При загрузке информации Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ° «%s» произошёл Ñбой" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"При попытке уÑтановить «%s» в качеÑтве обработчика по умолчанию Ð´Ð»Ñ Â«%s» " +"произошёл Ñбой: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Создать родительÑкие каталоги" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Создать каталоги." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir работает так же, как и Ð¾Ð±Ñ‹Ñ‡Ð½Ð°Ñ ÑƒÑ‚Ð¸Ð»Ð¸Ñ‚Ð° mkdir, но иÑпользует\n" +"GIO-раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¼ÐµÑто локальных файлов: например, вы можете иÑпользовать\n" +"что-то вроде smb://server/resource/mydir в качеÑтве раÑположениÑ." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Следить за каталогом (по умолчанию: завиÑит от типа)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Следить за файлом (по умолчанию: завиÑит от типа)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Следить за файлом напрÑмую (ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾Ð± изменениÑÑ…, Ñделанных через " +"жеÑткие ÑÑылки)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Следить за файлом напрÑмую, но не Ñообщать об изменениÑÑ…" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Сообщать о перемещении и переименовании в виде Ñобытий удалениÑ/ÑозданиÑ" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Ðаблюдать за ÑобытиÑми подключений" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Следить за изменением файлов и каталогов." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Подключить как подключаемый" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Подключить том Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ уÑтройÑтва или другим идентификатором" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Отключить" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Извлечь" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "ОÑтановить диÑк Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ уÑтройÑтва" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "УСТРОЙСТВО" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Отключить вÑе точки Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ заданной Ñхеме" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "СХЕМÐ" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Игнорировать незавершённые дейÑÑ‚Ð²Ð¸Ñ Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸ при размонтировании или " +"извлечении" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "ИÑпользовать анонимного Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "СпиÑок" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "ОтÑлеживать ÑобытиÑ" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Показать дополнительную информацию" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "ЧиÑловой множитель PIM при разблокировке тома VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "ПИМ" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Подключить Ñкрытый том TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Подключить ÑиÑтемный том TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Ðнонимный доÑтуп запрещён" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Ðет диÑка Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° уÑтройÑтва" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Ðет тома Ð´Ð»Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð³Ð¾ идентификатора" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Подключить или отключить адреÑа." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ðе иÑпользовать копирование и удалÑть резервные варианты" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "ПеремеÑтить один или неÑколько файлов из ИСТОЧÐИКРв ПРИÐМÐИК." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move работает так же, как и Ð¾Ð±Ñ‹Ñ‡Ð½Ð°Ñ ÑƒÑ‚Ð¸Ð»Ð¸Ñ‚Ð° mv, но иÑпользует\n" +"GIO-раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¼ÐµÑто локальных файлов: например, вы можете иÑпользовать\n" +"что-то вроде smb://server/resource/file.txt в качеÑтве раÑположениÑ" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Цель %s не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Открыть файлы Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию,\n" +"зарегиÑтрированного Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ файлов Ñтого типа." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Игнорировать неÑущеÑтвующие файлы, никогда не Ñпрашивать" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Удалить данные файлы." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "ИМЯ" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Переименовать файл." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "ОтÑутÑтвует аргумент" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Слишком много аргументов" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Переименование уÑпешно завершено. Ðовый URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Создать только еÑли не ÑущеÑтвует" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Добавить в конец файла" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "При Ñоздании ограничить права доÑтупа только Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ пользователÑ" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "При замене заменÑть так, как еÑли бы объект Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð½Ðµ ÑущеÑтвовал" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "ДобавлÑть атрибут etag в конце" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "ПерезапиÑываетÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ файла etag" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Произошла ошибка при чтении Ñтандартного ввода" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag недоÑтупен\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Прочитать из Ñтандартного ввода и Ñохранить в ПРИÐМÐИК." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Ðе указан путь назначениÑ" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Тип атрибута" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "ТИП" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ÐТРИБУТ" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "ЗÐÐЧЕÐИЕ" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "УÑтановить атрибуты файла ПРИÐМÐИКÐ." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "ÐÐ´Ñ€ÐµÑ Ð½Ðµ определён" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Ðтрибут не определён" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Значение не определено" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Ðеверный тип атрибута «%s»" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "ОчиÑтить корзину" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Показать Ñодержимое корзины Ñ Ð¸Ð·Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ñ‹Ð¼Ð¸ путÑми" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"ВоÑÑтановить файл из корзины в изначальном меÑтоположении (Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ‹Ð¼ " +"воÑÑтановлением нужных папок)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Ðе удалоÑÑŒ найти изначальный путь" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Ðе удалоÑÑŒ воÑÑоздать оригинальное меÑтоположение: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Ðе удалоÑÑŒ перемеÑтить файл в изначальное меÑтоположение: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "ПеремеÑтить/ВоÑÑтановить файлы или каталоги в корзину." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Заметьте: Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° --restore, еÑли изначальное меÑтоположение удалённого " +"файла \n" +"уже ÑущеÑтвует, оно не будет перезапиÑано, еÑли не добавлен ключ --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Указанное меÑтоположение не начинаетÑÑ Ñ trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Следовать ÑимволичеÑким ÑÑылкам, точкам Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ Ñрлыкам" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "ВывеÑти Ñодержимое каталогов в виде дерева." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Элемент <%s> не может быть внутри <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Элемент <%s> не может быть Ñамым верхним" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Файл %s указан в реÑурÑе неÑколько раз" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Ðе удалоÑÑŒ обнаружить «%s» в каталогах-иÑточниках" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Ðе удалоÑÑŒ обнаружить «%s» в текущем каталоге" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "ÐеизвеÑтный параметр обработки «%s»" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"ÐŸÑ€ÐµÐ´Ð²Ð°Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ° %s запрошена, но не указано значение %s, и %s не " +"добавлено в параметр PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Ошибка при чтении файла %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Ошибка при Ñжатии файла %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "текÑта не может быть внутри <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Показать верÑию программы и выйти" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ ÑохранениÑ" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Каталоги Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ файлов, указанных в параметре FILE (по умолчанию: " +"текущий каталог)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "КÐТÐЛОГ" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Генерировать результат в формате в ÑоответÑтвии Ñ Ñ€Ð°Ñширением целевого файла" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Генерировать иÑходный заголовок" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Генерировать иÑходный код, который иÑпользуетÑÑ Ð´Ð»Ñ ÑвÑзи Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ реÑурÑов " +"вашего кода" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Генерировать ÑпиÑок завиÑимоÑтей" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° завиÑимоÑтей Ð´Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Включить фиктивные цели в Ñозданный файл завиÑимоÑтей" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Ðе Ñоздавать и не региÑтрировать реÑÑƒÑ€Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ðе ÑкÑпортируйте функции; объÑвлÑйте их как G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Ðе включайте реÑурÑные данные в файл С. ПредполагаетÑÑ Ñ‡Ñ‚Ð¾ они подключаютÑÑ " +"из отдельных файлов" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Ð˜Ð¼Ñ C-идентификатора, иÑпользуемое Ð´Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ иÑходного кода" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Целевой компилÑтор Ñзыка C (по умолчанию: Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Компилировать Ñпецификацию реÑурÑов в файл реÑурÑов.\n" +"Файлы Ñпецификации реÑурÑов имеют раÑширение .gresource.xml,\n" +"а файл реÑурÑа имеет раÑширение .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Должно быть указано только одно Ð¸Ð¼Ñ Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "пÑевдоним должен Ñодержать Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ два Ñимвола" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Ðеверное чиÑловое значение" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " уже задан" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' уже задано" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "значение флага должно Ñодержать Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один уÑтановленный бит" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "Ð’ <%s> должно ÑодержатьÑÑ Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одно значение " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> выходит за рамки указанного диапазона" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "Значение <%s> не входит в указанное перечиÑление" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> Ñодержит Ñтроку в формате отличающимÑÑ Ð¾Ñ‚ указанного флагом" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> Ñодержит Ñтроку не входÑщую в " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " уже задан Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ ключа" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "Диапазон не разрешён Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ типа “%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "Минимум, указанный в превышает макÑимум" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ l10n: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "запрошен l10n, но домен gettext не указан" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "дан контекÑÑ‚ перевода Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð±ÐµÐ· включённого l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Ðе удалоÑÑŒ разобрать значение типа “%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" не могут быть указаны Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ обозначенных как перечиÑление" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " уже заданы Ð´Ð»Ñ Ñтого ключа" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " не разрешены Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ типа “%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " уже задано" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "Ð¥Ð¾Ñ‚Ñ Ð±Ñ‹ одно значение должно ÑодержатьÑÑ Ð² " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " уже заданы Ð´Ð»Ñ Ñтого ключа" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" могут быть указаны только Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ‡Ð¸Ñлений, флагов или вÑлед за " +"" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" указан при том, что значение “%s†уже включено в " +"перечиÑление" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " задан, когда уже был указан" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " уже задан" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "цель пÑевдонима «%s» не ÑвлÑетÑÑ Ð¿ÐµÑ€ÐµÑ‡Ð¸Ñлением" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "цель пÑевдонима «%s»не включена в " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " должны Ñодержать Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одно значение " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "ПуÑтые имена запрещены" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Ðеверное Ð¸Ð¼Ñ Â«%s»: имена должны начинатьÑÑ Ñо Ñтрочной буквы" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Ðеверное Ð¸Ð¼Ñ Â«%s»: неверный Ñимвол «%c»; допуÑкаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñтрочные буквы, " +"чиÑла и Ð´ÐµÑ„Ð¸Ñ («-»)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Ðеверное Ð¸Ð¼Ñ Â«%s»: Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ два дефиÑа одновременно («--»)" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Ðеверное Ð¸Ð¼Ñ Â«%s»: поÑледний Ñимвол не может быть дефиÑом («-»)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Ðеверное Ð¸Ð¼Ñ Â«%s»: макÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° равна 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " уже задан" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Ðе удалоÑÑŒ добавить ключи в Ñхему «list-of»" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " уже задан" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" оттенÑет в ; Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ " +"Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ñпользуйте " + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Ð’ качеÑтве атрибута можно указать только «type», «enum» или «flags»" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id=«%s»> не определён (пока)." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñтрока типа GVariant «%s»" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " указан, но Ñхема ничего не раÑширÑет" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Ðе задан Ð´Ð»Ñ Ð·Ð°Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " уже задан" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " уже задан" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " раÑширÑет пока не ÑущеÑтвующую Ñхему «%s»" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " ÑвлÑетÑÑ ÑпиÑком пока не ÑущеÑтвующей Ñхемы «%s»" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Ðе может быть ÑпиÑком Ñхемы Ñ Ð¿ÑƒÑ‚Ñ‘Ð¼" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Ðе удалоÑÑŒ раÑширить Ñхему путём" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ÑвлÑетÑÑ ÑпиÑком, раÑширÑющим , который не " +"ÑвлÑетÑÑ ÑпиÑком" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" раÑширÑет , но " +"«%s» не раÑширÑет «%s»" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"ЕÑли указываетÑÑ Ð¿ÑƒÑ‚ÑŒ, то он должен начинатьÑÑ Ð¸ заканчиватьÑÑ Ñимволом " +"коÑой черты" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Путь в ÑпиÑке должен заканчиватьÑÑ Â«:/»" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Предупреждение: Схема «%s» Ñодержит путь «%s». Пути, начинающиеÑÑ Ñ Â«/" +"apps/», «/desktop/» или «/system/» ÑвлÑÑŽÑ‚ÑÑ ÑƒÑтаревшими." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> уже задан" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Только один <%s> Ñлемент может быть внутри <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Элемент <%s> не может быть Ñамым верхним" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Элемент требуетÑÑ Ð² " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "ТекÑÑ‚ не может быть внутри <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Предупреждение: не определена ÑÑылка на " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "Был указан параметр --strict; завершение работы." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Ð’ÑÑ‘ Ñодержимое файла было проигнорировано." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Этот файл игнорируетÑÑ." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "Ключ «%s» в Ñхеме «%s» отÑутÑтвует, Ñ…Ð¾Ñ‚Ñ ÑƒÐºÐ°Ð·Ð°Ð½ в файле замен «%s»." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "Ключ «%s» в Ñхеме «%s» отÑутÑтвует, Ñ…Ð¾Ñ‚Ñ ÑƒÐºÐ°Ð·Ð°Ð½ в файле замен «%s»." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Ðе удаётÑÑ Ð¿Ñ€ÐµÐ´Ð¾Ñтавить замену Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ ключа «%s» в Ñхеме " +"«%s» (файл Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñми «%s»); переопределение ключа игнорируетÑÑ." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Ðе удаётÑÑ Ð¿Ñ€ÐµÐ´Ð¾Ñтавить замену Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ ключа «%s» в Ñхеме " +"«%s» (файл Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñми «%s»), Кроме того был указан параметр --strict. " +"ПроцеÑÑ Ð¿Ñ€ÐµÑ€Ð²Ð°Ð½." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Ошибка разбора ключа «%s» в Ñхеме «%s», ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð° в файле замен " +"«%s»: %s." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Ошибка разбора ключа «%s» в Ñхеме «%s», ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð° в файле замен " +"«%s»: %s." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Замена ключа «%s» в Ñхеме «%s» ÑоглаÑно файлу замен «%s» лежит вне диапазона " +"данной Ñхемы." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Замена ключа «%s» в Ñхеме «%s» ÑоглаÑно файлу замен «%s» лежит вне диапазона " +"данной Ñхемы. Кроме того указан ключ --strict. ПроцеÑÑ Ð¿Ñ€ÐµÑ€Ð²Ð°Ð½." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Замена ключа «%s» в Ñхеме «%s» ÑоглаÑно файлу замен «%s» лежит вне ÑпиÑка " +"допуÑтимых значений. Переопределение ключа игнорируетÑÑ." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Замена ключа «%s» в Ñхеме «%s» ÑоглаÑно файлу замен «%s» лежит вне ÑпиÑка " +"допуÑтимых значений. Кроме того указан ключ --strict. ПроцеÑÑ Ð¿Ñ€ÐµÑ€Ð²Ð°Ð½." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "МеÑто ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "ОÑтанавливать работу при возникновении ошибок в Ñхемах" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Ðе запиÑывать файл gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Ðе уÑтанавливать Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° Ð¸Ð¼Ñ ÐºÐ»ÑŽÑ‡Ð°" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Компилировать вÑе файлы Ñхемы GSettings в кÑш Ñхемы.\n" +"Файлы Ñхемы требуютÑÑ Ð´Ð»Ñ Ñ€Ð°ÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ .gschema.xml,\n" +"а файл кÑша называетÑÑ gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Должно быть указано только одно Ð¸Ð¼Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð°" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Файлы Ñхемы не найдены: процеÑÑ Ð¿Ñ€ÐµÑ€Ð²Ð°Ð½." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Ðе найден файл Ñхемы: удалён ÑущеÑтвующий выходной файл." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Произошла ошибка при получении Ñведений о файловой ÑиÑтеме %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Точка Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° %s не найдена" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ñ‚ÑŒ корневой каталог" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Произошла ошибка при переименовании файла %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Ðевозможно переименовать файл, Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° уже ÑущеÑтвует" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Произошла ошибка Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Произошла ошибка при удалении файла %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Произошла ошибка при удалении файла в корзину %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Ðе удалоÑÑŒ Ñоздать каталог корзины %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Ðе удалоÑÑŒ найти каталог верхнего ÑƒÑ€Ð¾Ð²Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð·Ð¸Ð½Ñ‹ %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Удаление в корзину на ÑиÑтемных томах не поддерживаетÑÑ" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Ðе удалоÑÑŒ найти или Ñоздать каталог корзины %s Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Ðе удалоÑÑŒ Ñоздать запиÑÑŒ о файле в корзине %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Ðе удалоÑÑŒ удалить файл %s в корзину, из-за ограничений файловой ÑиÑтемы" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Ðе удалоÑÑŒ удалить файл в корзину %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Ðе удалоÑÑŒ удалить файл в корзину %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Произошла ошибка при Ñоздании каталога %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Ð¤Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема не поддерживает Ñимвольные ÑÑылки" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Произошла ошибка при Ñоздании Ñимвольной ÑÑылки %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Произошла ошибка при перемещении файла %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить каталог поверх каталога" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Ðе удалоÑÑŒ Ñоздать резервный файл" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Произошла ошибка при удалении целевого файла: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Перемещение между точками Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживаетÑÑ" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ðе удалоÑÑŒ определить иÑпользование диÑка %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Значение атрибута не должно быть NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Ðеверный тип атрибута (ожидалаÑÑŒ Ñтрока)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ Ñ€Ð°Ñширенного атрибута" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Произошла ошибка при уÑтановке раÑширенного атрибута «%s»: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ°)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Ошибка при получении информации о файле «%s»: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Ошибка при получении информации о файловом деÑкрипторе: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ðеверный тип атрибута (ожидалÑÑ uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ðеверный тип атрибута (ожидалÑÑ uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ðеверный тип атрибута (ожидалаÑÑŒ Ñтрока byte)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Ðе удалоÑÑŒ уÑтановить права на ÑимволичеÑкие ÑÑылки" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Произошла ошибка при уÑтановке прав: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Произошла ошибка при уÑтановке владельца: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "ÑÐ¸Ð¼Ð²Ð¾Ð»ÑŒÐ½Ð°Ñ ÑÑылка не должна быть NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Произошла ошибка при уÑтановке Ñимвольной ÑÑылки: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Произошла ошибка при уÑтановке Ñимвольной ÑÑылки: файл не ÑвлÑетÑÑ " +"Ñимвольной ÑÑылкой" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "" +"Дополнительные нано-Ñекунды %d во временной метке UNIX %lld имеют " +"отрицательное значение" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Дополнительные нано-Ñекунды %d во временной метке UNIX %lld доÑтигли одной " +"Ñекунды" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° UNIX %lld не помещаетÑÑ Ð² 64 бита" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° UNIX %lld не входит в диапазон, поддерживаемый Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Ðе удалоÑÑŒ преобразовать Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° «%s» в Ñтроку UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Ðе удалоÑÑŒ открыть файл «%s»: ошибка Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "" +"Произошла ошибка при уÑтановке времени модификации или доÑтупа файла «%s»: " +"%lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Произошла ошибка при уÑтановке времени модификации или доÑтупа: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "КонтекÑÑ‚ SELinux не должен быть равен NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "Ð’ Ñтой ÑиÑтеме не включён SELinux" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Произошла ошибка при уÑтановке контекÑта SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "УÑтановка атрибута %s не поддерживаетÑÑ" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Произошла ошибка при чтении из файла: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Произошла ошибка при закрытии файла: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Произошла ошибка при переходе по файлу: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Ðе удалоÑÑŒ найти тип монитора локальных файлов по умолчанию" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Произошла ошибка при запиÑи в файл: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Произошла ошибка при удалении Ñтарой резервной ÑÑылки: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Произошла ошибка при Ñоздании резервной копии: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Произошла ошибка при переименовании временного файла: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Произошла ошибка при уÑечении файла: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Произошла ошибка при открытии файла «%s»: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Целевой файл ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Целевой файл не ÑвлÑетÑÑ Ð¾Ð±Ñ‹Ñ‡Ð½Ñ‹Ð¼ файлом" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Файл был изменён извне" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Произошла ошибка при удалении Ñтарого файла: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Передан недопуÑтимый GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "ÐедопуÑтимый Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° переход" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "ÐÐµÐ»ÑŒÐ·Ñ ÑƒÑечь GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Ðевозможно изменить размер выходного потока в памÑть" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Ðе удалоÑÑŒ изменить размер выходного потока в памÑть" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"КоличеÑтво памÑти, требуемое процеÑÑом запиÑи, больше чем доÑтупное адреÑное " +"проÑтранÑтво" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "ВыполнÑть перемещение в начало потока" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "ВыполнÑть перемещение в конец потока" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "точка Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживает «отÑоединение»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "точка Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживает «извлечение»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"точка Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживает «отÑоединение» или " +"«отÑоединение_Ñ_операцией»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"точка Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживает «извлечение» или «извлечение_Ñ_операцией»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "точка Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживает «переподÑоединение»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "" +"точка Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживает возможноÑть Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° Ñодержимого" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" +"точка Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживает возможноÑть Ñинхронного Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° " +"Ñодержимого" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Ð˜Ð¼Ñ ÑƒÐ·Ð»Ð° «%s» Ñодержит «[», но не «]»" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Сеть недоÑтупна" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Узел недоÑтупен" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ðе удалоÑÑŒ Ñоздать Ñетевой монитор: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Ðе удалоÑÑŒ Ñоздать Ñетевой монитор: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Ðе удалоÑÑŒ получить ÑоÑтоÑние Ñети: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager не запущен" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "ВерÑÐ¸Ñ NetworkManager Ñлишком ÑтараÑ" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Выходной поток не поддерживает запиÑÑŒ" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Сумма маÑÑивов, переданных в «%s» Ñлишком велика" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "ИÑходный поток уже закрыт" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Ошибка Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Â«%s»: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "«%s» не реализовано" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "ÐедопуÑтимый домен" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "РеÑÑƒÑ€Ñ Ð¸Ð· «%s» не ÑущеÑтвует" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Ðе удалоÑÑŒ раÑпаковать реÑÑƒÑ€Ñ Ð¸Ð· «%s»" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "РеÑÑƒÑ€Ñ Ð¸Ð· «%s» не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "По входному потоку перемещение не поддерживаетÑÑ" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "ВывеÑти разделы, Ñодержащие реÑурÑÑ‹ в elf-ФÐЙЛЕ" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Вывод ÑпиÑка реÑурÑов\n" +"ЕÑли указан РÐЗДЕЛ, то выводитÑÑ ÑпиÑок реÑурÑов только из Ñтого раздела\n" +"ЕÑли указан ПУТЬ, то выводитÑÑ ÑпиÑок Ñовпадающих реÑурÑов" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "ФÐЙЛ [ПУТЬ]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "РÐЗДЕЛ" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Вывод ÑпиÑка реÑурÑов Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾ÑÑ‚Ñми\n" +"ЕÑли указан РÐЗДЕЛ, то выводитÑÑ ÑпиÑок реÑурÑов только из Ñтого раздела\n" +"ЕÑли указан ПУТЬ, то выводитÑÑ ÑпиÑок Ñовпадающих реÑурÑов\n" +"Дополнительно выводитÑÑ Ñ€Ð°Ð·Ð´ÐµÐ», размер и Ñжатие" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Извлечь файл реÑурÑа в stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "ФÐЙЛ ПУТЬ" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ИÑпользование:\n" +" gresource [--section РÐЗДЕЛ] КОМÐÐДР[ÐРГУМЕÐТЫ…]\n" +"\n" +"Команды:\n" +" help Показать Ñту Ñправку\n" +" sections ВывеÑти разделы Ñ Ñ€ÐµÑурÑами\n" +" list ВывеÑти реÑурÑÑ‹\n" +" details ВывеÑти реÑурÑÑ‹ Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾ÑÑ‚Ñми\n" +" extract Извлечь реÑурÑ\n" +"\n" +"Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки иÑпользуйте «gresource help КОМÐÐДл.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ИÑпользование:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " РÐЗДЕЛ Ð˜Ð¼Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° elf (необÑзательный)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " КОМÐÐДРКоманда Ð´Ð»Ñ Ð¿Ð¾ÑÑÐ½ÐµÐ½Ð¸Ñ (необÑзательный)\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " ФÐЙЛ Файл elf (иÑполнÑемый или Ð¾Ð±Ñ‰Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ°)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" ФÐЙЛ Файл elf (иÑполнÑемый или Ð¾Ð±Ñ‰Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ°)\n" +" или Ñкомпилированный файл реÑурÑов\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[ПУТЬ]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" +" ПУТЬ Путь реÑурÑа (необÑзательный, можно указать только чаÑть)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "ПУТЬ" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " ПУТЬ Путь реÑурÑа\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Схема «%s» отÑутÑтвует\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Схема «%s» не ÑвлÑетÑÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰Ð°ÐµÐ¼Ð¾Ð¹ (задание пути недопуÑтимо)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Схема «%s» ÑвлÑетÑÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰Ð°ÐµÐ¼Ð¾Ð¹ (должен быть указан путь)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Указан пуÑтой путь.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Путь должен начинатьÑÑ Ñимволом коÑой черты (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Путь должен заканчиватьÑÑ Ñимволом коÑой черты (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Ð’ пути не должно быть две ÑтоÑщих Ñ€Ñдом коÑых черты (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "ПредоÑтавленное величина лежит вне диапазона допуÑтимых значений\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Ключ недоÑтупен Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "СпиÑок уÑтановленных (неперемещаемых) Ñхем" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "СпиÑок уÑтановленных перемещаемых Ñхем" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "СпиÑок ключей в СХЕМЕ" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "СХЕМÐ[:ПУТЬ]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "СпиÑок потомков СХЕМЫ" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"ПеречиÑлить ключи и Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ€ÐµÐºÑƒÑ€Ñивно\n" +"ЕÑли указана СХЕМÐ, то перечиÑлить вÑе ключи\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[СХЕМÐ[:ПУТЬ]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Получить значение КЛЮЧÐ" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "СХЕМÐ[:ПУТЬ] КЛЮЧ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "ЗапроÑить диапазон допуÑтимых значений КЛЮЧÐ" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "ЗапроÑить опиÑание Ð´Ð»Ñ ÐšÐ›Ð®Ð§Ð" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "ПриÑвоить величину ЗÐÐЧЕÐИЕ КЛЮЧУ" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "СХЕМÐ[:ПУТЬ] КЛЮЧ ЗÐÐЧЕÐИЕ" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Ðазначить КЛЮЧУ его значение по умолчанию" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "СброÑить вÑе ключи в СХЕМЕ в их Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Проверить, что КЛЮЧ доÑтупен Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Следить за изменениÑми КЛЮЧÐ.\n" +"ЕÑли КЛЮЧ не задан, то Ñледить за вÑеми ключами СХЕМЫ.\n" +"Ð”Ð»Ñ Ð¾Ñтановки ÑÐ»ÐµÐ¶ÐµÐ½Ð¸Ñ Ð¸Ñпользуйте ^C.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "СХЕМÐ[:ПУТЬ] [КЛЮЧ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ИÑпользование:\n" +" gsettings --version\n" +" gsettings [--schemadir КÐТÐЛОГ_СХЕМ] КОМÐÐДР[ÐРГУМЕÐТЫ…]\n" +"\n" +"Команды:\n" +" help Показать Ñту Ñправку\n" +" list-schemas СпиÑок уÑтановленных Ñхем\n" +" list-relocatable-schemas СпиÑок перемещаемых Ñхем\n" +" list-keys СпиÑок ключей Ñхемы\n" +" list-children СпиÑок потомков Ñхемы\n" +" list-recursively СпиÑок ключей и значений, рекурÑивно\n" +" range ЗапроÑить диапазон значений ключа\n" +" describe ЗапроÑить опиÑание ключа\n" +" get Получить значение ключа\n" +" set Изменить значение ключа\n" +" reset СброÑить значение ключа\n" +" reset-recursively СброÑить вÑе Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² заданной Ñхеме\n" +" writable Проверить ключ на запиÑÑŒ\n" +" monitor Следить за изменениÑми\n" +"\n" +"Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ð¹ Ñправки иÑпользуйте команду «gsettings help " +"КОМÐÐДл.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ИÑпользование:\n" +" gsettings [--schemadir КÐТÐЛОГ_СХЕМ] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " КÐТ_СХЕМ Каталог Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка дополнительных Ñхем\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" СХЕМРИдентификатор Ñхемы\n" +" ПУТЬ Путь, Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰Ð°ÐµÐ¼Ñ‹Ñ… Ñхем\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " КЛЮЧ (ÐеобÑзательный) ключ Ñхемы\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " КЛЮЧ Ключ Ñхемы\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " ЗÐÐЧЕÐИЕ ПриÑваиваемое значение\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Ðе удалоÑÑŒ загрузить Ñхемы из «%s»: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Схемы не уÑтановлены\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Указано пуÑтое Ð¸Ð¼Ñ Ñхемы\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Ключ «%s» отÑутÑтвует\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "ÐедопуÑтимый Ñокет, не инициализировано" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ÐедопуÑтимый Ñокет, Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ðµ удалаÑÑŒ по причине: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Сокет уже закрыт" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Превышено Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð²Ð²Ð¾Ð´Ð°-вывода Ñокета" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ÑоздаётÑÑ GSocket из fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ðе удалоÑÑŒ Ñоздать Ñокет: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Указано неизвеÑтное ÑемейÑтво" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Указан неизвеÑтный протокол" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Ðевозможно иÑпользовать дейтаграммные операции на не-дейтаграммном Ñокете." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Ðевозможно иÑпользовать дейтаграммные операции на Ñокете Ñ ÑƒÑтановленным " +"тайм-аутом." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "не удалоÑÑŒ получить локальный адреÑ: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "не удалоÑÑŒ получить удаленный адреÑ: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "не удалоÑÑŒ Ñлушать: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Произошла ошибка при ÑвÑзывании к адреÑу %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Ошибка при вÑтуплении в мультикаÑтовую группу: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Ошибка при выходе из мультикаÑтовой группы: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "ОтÑутÑтвует поддержка мультикаÑта по иÑточнику" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Ðеподдерживаемое ÑемейÑтво Ñокетов" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "Ñпецифичный иÑточник, не Ð°Ð´Ñ€ÐµÑ IP4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Ð˜Ð¼Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñа Ñлишком длинное" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð½Ðµ найден: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "ОтÑутÑтвует поддержка IPv4 мультикаÑта по иÑточнику" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "ОтÑутÑтвует поддержка IPv6 мультикаÑта по иÑточнику" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Ошибка приёма подключениÑ: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "ВыполнÑетÑÑ Ñоединение" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Ðе удалоÑÑŒ получить ошибку ожиданиÑ: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Ошибка при получении данных: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Ошибка при отправлении данных: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ðе удалоÑÑŒ выключить Ñокет: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Произошла ошибка при закрытии Ñокета: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Ожидание ÑоÑтоÑÐ½Ð¸Ñ Ñокета: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Ðе удалоÑÑŒ отправить Ñообщение: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Слишком большие маÑÑивы ÑообщениÑ" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Произошла ошибка при отправлении ÑообщениÑ: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage не поддерживаетÑÑ Ð² Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Произошла ошибка при получении ÑообщениÑ: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Ðе удалоÑÑŒ прочитать Ð¿Ð¾Ð»Ð½Ð¾Ð¼Ð¾Ñ‡Ð¸Ñ Ñокета: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials не реализован Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ОС" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ðе удалоÑÑŒ подключитьÑÑ Ðº прокÑи-Ñерверу %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ðе удалоÑÑŒ подключитьÑÑ Ðº %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Ðе удалоÑÑŒ подключитьÑÑ Ðº: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "ПрокÑирование через не-TCP Ñоединение не поддерживаетÑÑ." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Протокол прокÑи «%s» не поддерживаетÑÑ." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Слушатель уже закрыт" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Добавленный Ñокет закрыт" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 не поддерживает Ð°Ð´Ñ€ÐµÑ IPv6 «%s»" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñлишком длинно Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ð° SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Ð˜Ð¼Ñ ÑƒÐ·Ð»Ð° «%s» Ñлишком длинно Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ð° SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Сервер не ÑвлÑетÑÑ Ð¿Ñ€Ð¾ÐºÑи-Ñервером SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Подключение через Ñервер SOCKSv4 было отклонено" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Сервер не ÑвлÑетÑÑ Ð¿Ñ€Ð¾ÐºÑи-Ñервером SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "ПрокÑи SOCKSv5 требует аутентификацию." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Ð”Ð»Ñ Ð¿Ñ€Ð¾ÐºÑи SOCKSv5 требуетÑÑ Ð¼ÐµÑ‚Ð¾Ð´ аутентификации, который не поддерживаетÑÑ " +"GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ пароль Ñлишком длинные Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ð° SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ SOCKSv5 завершилаÑÑŒ неудачно из-за неверного имени " +"Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ паролÑ." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Ð˜Ð¼Ñ ÑƒÐ·Ð»Ð° «%s» Ñлишком длинное Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ð° SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "ПрокÑи-Ñервер SOCKSv5 иÑпользует неизвеÑтный тип адреÑа." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° прокÑи-Ñервера SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Подключение SOCKSv5 запрещено набором правил." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Узел недоÑтупен через Ñервер SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Сеть недоÑтупна через прокÑи SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Подключение через прокÑи SOCKSv5 отклонено." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "ПрокÑи SOCKSv5 не поддерживает команду «connect»." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "ПрокÑи SOCKSv5 не поддерживает предложенный тип адреÑа." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° прокÑи SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Ðе удалоÑÑŒ Ñоздать канал Ð´Ð»Ñ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑом-потомком (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Каналы не поддерживаютÑÑ Ð½Ð° Ñтой платформе" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Ðе удалоÑÑŒ обработать верÑию %d текÑтового предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Ðе найдено ни одного допуÑтимого адреÑа" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Ошибка обратного Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Â«%s»: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Ошибка при разборе запиÑи DNS %s: некорректный DNS-пакет" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "ЗапиÑÑŒ DNS Ñ Ð·Ð°Ð¿Ñ€Ð°ÑˆÐ¸Ð²Ð°ÐµÐ¼Ñ‹Ð¼ типом «%s» отÑутÑтвует" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Временно невозможно разрешить «%s»" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Произошла ошибка Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Â«%s»" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Ðекорректный DNS-пакет" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Ðе удалоÑÑŒ разобрать ответ DNS Ð´Ð»Ñ \"%s\": " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Ðе найден Ñекретный ключ в формате PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ðе удалоÑÑŒ раÑшифровать Ñекретный ключ в формате PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Ðе удалоÑÑŒ разобрать Ñекретный ключ в формате PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Ðе найден Ñертификат в формате PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ðе удалоÑÑŒ разобрать Ñертификат в формате PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Текущий бÑкенд TLS не поддерживает PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Ð¡ÐµÑ€Ð²Ð¸Ñ GTlsBackend не поддерживает Ñоздание Ñертификатов PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Это поÑледнÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñть правильно ввеÑти пароль перед тем, как доÑтуп " +"будет заблокирован." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Пароль был неÑколько раз введён неправильно, поÑле Ñледующих отказов ваш " +"доÑтуп будет заблокирован." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Введённый пароль неверен." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Отправка деÑкриптора файла не поддерживаетÑÑ" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "ОжидаетÑÑ 1 контрольное Ñообщение, получено %d" +msgstr[1] "ОжидаетÑÑ 1 контрольное Ñообщение, получено %d" +msgstr[2] "ОжидаетÑÑ 1 контрольное Ñообщение, получено %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Ðеожиданный тип вÑпомогательных данных" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "ОжидаетÑÑ Ð¾Ð´Ð¸Ð½ файловый деÑкриптор но получено %d\n" +msgstr[1] "ОжидаетÑÑ Ð¾Ð´Ð¸Ð½ файловый деÑкриптор но получено %d\n" +msgstr[2] "ОжидаетÑÑ Ð¾Ð´Ð¸Ð½ файловый деÑкриптор но получено %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Получен недопуÑтимый файловый деÑкриптор" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Получение деÑкриптора файла не поддерживаетÑÑ" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Произошла ошибка при отправлении мандата: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Произошла ошибка при проверке Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SO_PASSCRED Ð´Ð»Ñ Ñокета: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Произошла ошибка при включении SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"ОжидалоÑÑŒ прочитать один байт идентификационной информации (credentials), но " +"не прочитано ни одного байта" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Контрольное Ñообщение не ожидалоÑÑŒ, но получено %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Произошла ошибка при отключении SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Ошибка при чтении из файлового деÑкриптора: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Ошибка при закрытии файлового деÑкриптора: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Корень файловой ÑиÑтемы" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Ошибка при запиÑи в файловый деÑкриптор: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"ÐбÑтрактные адреÑа доменных Ñокетов UNIX не поддерживаютÑÑ Ð½Ð° Ñтой ÑиÑтеме" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "том не поддерживает извлечение" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "том не поддерживает извлечение или извлечение_Ñ_операцией" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Произошла ошибка при чтении из деÑкриптора: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Произошла ошибка при закрытии деÑкриптора: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Произошла ошибка при запиÑи в деÑкриптор: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "ÐедоÑтаточно памÑти" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "ТребуетÑÑ Ð±Ð¾Ð»ÑŒÑˆÐµ входных данных" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Ðеправильные Ñжатые данные" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ПроÑлушиваемый адреÑ" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "ИгнорируетÑÑ, Ð´Ð»Ñ ÑовмеÑтимоÑти Ñ GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Ðапечатать адреÑ" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Ðапечатать Ð°Ð´Ñ€ÐµÑ Ð² режиме оболочки" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "ЗапуÑк Ñлужбы dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Ðеверные параметры\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Ðеожиданный атрибут «%s» Ð´Ð»Ñ Ñлемента «%s»" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Ðе найден атрибут «%s» Ñлемента «%s»" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Ðеожиданный Ñ‚Ñг «%s», ожидалÑÑ Ñ‚Ñг «%s»" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Ðеожиданный Ñ‚Ñг «%s» внутри «%s»" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð°Ñ‚Ð° и Ð²Ñ€ÐµÐ¼Ñ â€˜%s’ в файле закладок" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Ðе удалоÑÑŒ найти допуÑтимый файл закладок в каталогах поиÑка" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Закладка Ð´Ð»Ñ Ñ€ÐµÑурÑа URI «%s» уже ÑущеÑтвует" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Ð”Ð»Ñ Ñ€ÐµÑурÑа URI «%s» закладок не найдено" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Ð’ закладке на реÑÑƒÑ€Ñ Â«%s» не определён тип MIME" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Отметка о приватноÑти данных в закладке Ð´Ð»Ñ URI «%s» не определена" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Ð’ закладке Ð´Ð»Ñ URI «%s» не определена группа" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Ðет Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ «%s», Ñоздавшего закладку Ð´Ð»Ñ Â«%s»" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Ðе удалоÑÑŒ дополнить Ñтроку Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Â«%s» Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ URI «%s»" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Во входной Ñтроке Ð´Ð»Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½ неотображаемый Ñимвол" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "" +"ÐÐµÐ¿Ð¾Ð»Ð½Ð°Ñ ÑÐ¸Ð¼Ð²Ð¾Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾ÑледовательноÑть ÑодержитÑÑ Ð² конце входных данных" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Ðевозможно корректно преобразовать Ñимвол «%s» в Ñимвол из набора «%s»" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Байт Ñо значением NUL во входных преобразуемых данных" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Байт Ñо значением NUL в выходных преобразованных данных" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" +"URI «%s» не ÑвлÑетÑÑ Ð°Ð±Ñолютным идентификатором при иÑпользовании Ñхемы " +"«file»" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Идентификатор URI локального файла «%s» не может включать Ñимвол «#»" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "ÐедопуÑтимый URI «%s»" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð° в URI «%s»" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI «%s» Ñодержит недопуÑтимо Ñкранированные Ñимволы" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Путь «%s» не ÑвлÑетÑÑ Ð°Ð±Ñолютным" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a, %-d %b %Y, %H∶%M∶%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%-I∶%M∶%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Январь" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Февраль" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Март" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Ðпрель" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Май" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Июнь" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Июль" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "ÐвгуÑÑ‚" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "СентÑбрь" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "ОктÑбрь" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "ÐоÑбрь" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Декабрь" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Янв" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Фев" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Мар" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Ðпр" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Май" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Июн" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Июл" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ðвг" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Сен" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Окт" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ÐоÑ" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Дек" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Понедельник" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Вторник" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Среда" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Четверг" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "ПÑтница" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Суббота" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ВоÑкреÑенье" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Пн" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Ð’Ñ‚" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ср" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Чт" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Пт" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Сб" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Ð’Ñ" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "ЯнварÑ" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "ФевралÑ" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Марта" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "ÐпрелÑ" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "МаÑ" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "ИюнÑ" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "ИюлÑ" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "ÐвгуÑта" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "СентÑбрÑ" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "ОктÑбрÑ" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "ÐоÑбрÑ" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "ДекабрÑ" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Янв" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Фев" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Мар" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Ðпр" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Май" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Июн" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Июл" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ðвг" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Сен" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Окт" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ÐоÑ" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Дек" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "ДП (AM)" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "ПП (PM)" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Произошла ошибка при открытии каталога «%s»: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ðе удалоÑÑŒ выделить %lu байт Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»" +msgstr[1] "Ðе удалоÑÑŒ выделить %lu байта Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»" +msgstr[2] "Ðе удалоÑÑŒ выделить %lu байт Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Ошибка при чтении файла «%s»: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Файл «%s» Ñлишком велик" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Ðе удалоÑÑŒ прочитать из файла «%s»: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Ðе удалоÑÑŒ открыть файл «%s»: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Ðе удалоÑÑŒ получить атрибуты файла «%s»: Ñбой в функции fstat(): %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Ðе удалоÑÑŒ открыть файл «%s»: Ñбой в функции fdopen(): %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Ðе удалоÑÑŒ переименовать файл «%s» в «%s»: Ñбой в функции g_rename(): %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Ðе удалоÑÑŒ запиÑать файл «%s»: Ñбой в функции write(): %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Ðе удалоÑÑŒ запиÑать файл «%s»: Ñбой в функции fsync(): %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Ðе удалоÑÑŒ Ñоздать файл «%s»: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Ðе удалоÑÑŒ удалить ÑущеÑтвующий файл «%s»: Ñбой в функции g_unlink(): %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Шаблон «%s» недопуÑтим: он не должен Ñодержать «%s»" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Шаблон «%s» не Ñодержит XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Ðе удалоÑÑŒ прочитать Ñимвольную ÑÑылку «%s»: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Ðе удалоÑÑŒ открыть преобразователь из «%s» в «%s»: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Ðевозможно выполнить непоÑредÑтвенное чтение в функции " +"g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Ð’ буфере Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¾ÑталиÑÑŒ непреобразованные данные" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Канал закрываетÑÑ Ð½Ð° неполном Ñимволе" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "" +"Ðевозможно выполнить непоÑредÑтвенное чтение в функции " +"g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Ð’ каталогах поиÑка не удалоÑÑŒ найти допуÑтимый файл ключей" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Ðе ÑвлÑетÑÑ Ð¾Ð±Ñ‹Ñ‡Ð½Ñ‹Ð¼ файлом" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Файл ключей Ñодержит Ñтроку «%s», ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ ÑвлÑетÑÑ Ð¿Ð°Ñ€Ð¾Ð¹ «ключ-значение», " +"группой или комментарием" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Файл ключей не начинаетÑÑ Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ ÐºÐ»ÑŽÑ‡Ð°: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Файл ключей Ñодержит неподдерживаемую кодировку «%s»" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Файл ключей не Ñодержит группу «%s»" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Файл ключей не Ñодержит ключа «%s» в группе «%s»" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Файл ключей Ñодержит ключ «%s», значение которого «%s» не в кодировке UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Файл ключей Ñодержит ключ «%s», значение которого не удалоÑÑŒ " +"интерпретировать." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Файл ключей Ñодержит ключ «%s» в группе «%s», значение которого не удалоÑÑŒ " +"интерпретировать." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Значение ключа «%s» в группе «%s» имеет значение «%s», но ожидалоÑÑŒ %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Файл ключей Ñодержит Ñимвол escape в конце Ñтроки" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Файл ключей Ñодержит неверную Ñкранирующую поÑледовательноÑть «%s»" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Ðе удалоÑÑŒ преобразовать значение «%s» в чиÑло." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "ЦелочиÑленное значение «%s» выходит за пределы" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Ðе удалоÑÑŒ преобразовать «%s» в чиÑло Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ запÑтой." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Ðе удалоÑÑŒ преобразовать «%s» в булево значение." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Ðе удалоÑÑŒ получить атрибуты файла «%s%s%s%s»: Ñбой в функции fstat(): %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Ðе удалоÑÑŒ отобразить файл «%s%s%s%s»: Ñбой в функции mmap(): %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Ðе удалоÑÑŒ открыть файл «%s»: Ñбой в функции open(): %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Ошибка в Ñтроке %d на Ñимволе %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "" +"ÐедопуÑтимый UTF-8 текÑÑ‚ в имени — Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾ÑледовательноÑть «%s»" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "Ð˜Ð¼Ñ Â«%s» недопуÑтимо" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "Ð˜Ð¼Ñ Â«%s» недопуÑтимо: «%c»" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Ошибка в Ñтроке %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Ðе удалоÑÑŒ разобрать Ñтроку «%-.*s», ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть чиÑлом внутри кода " +"Ñимвола (например ê) — возможно, чиÑло Ñлишком велико" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Код Ñимвола не оканчиваетÑÑ Ñ‚Ð¾Ñ‡ÐºÐ¾Ð¹ Ñ Ð·Ð°Ð¿Ñтой; похоже, Ñимвол «&» был " +"иÑпользован не Ð´Ð»Ñ Ð¾Ð±Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° конÑтрукции — Ñкранируйте его как &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Код «%-.*s» не определÑет допуÑтимый Ñимвол" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Обнаружена пуÑÑ‚Ð°Ñ ÐºÐ¾Ð½ÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Â«&;»; допуÑтимыми конÑтрукциÑми ÑвлÑÑŽÑ‚ÑÑ: " +"& " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Ð˜Ð¼Ñ ÑущноÑти «%-.*s» неизвеÑтно" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"КонÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ð½Ðµ заканчиваетÑÑ Ñ‚Ð¾Ñ‡ÐºÐ¾Ð¹ Ñ Ð·Ð°Ð¿Ñтой; похоже, что Ñимвол «&» был " +"иÑпользован не Ð´Ð»Ñ Ð¾Ð±Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° конÑтрукции — Ñкранируйте его как " +"«&" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Документ должен начинатьÑÑ Ñ Ñлемента (например )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"Символ «%s» ÑвлÑетÑÑ Ð½ÐµÐ´Ð¾Ð¿ÑƒÑтимым поÑле Ñимвола «<»; Ñтот Ñимвол не может " +"начинать Ð¸Ð¼Ñ Ñлемента" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Ð’ÑтретилÑÑ Ð»Ð¸ÑˆÐ½Ð¸Ð¹ Ñимвол «%s», ожидалÑÑ Ñимвол «>» Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿ÑƒÑтого " +"Ñлемента Ñ‚Ñга «%s»" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Слишком много атрибутов Ð´Ð»Ñ Ñлемента «%s»" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Ð’ÑтретилÑÑ Ð»Ð¸ÑˆÐ½Ð¸Ð¹ Ñимвол «%s», ожидалÑÑ Ñимвол «=» поÑле имени атрибута «%s» " +"Ñлемента «%s»" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Ð’ÑтретилÑÑ Ð»Ð¸ÑˆÐ½Ð¸Ð¹ Ñимвол «%s»; ожидалиÑÑŒ Ñимволы «>» или «/» Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ " +"открывающего Ñ‚Ñга Ñлемента «%s», либо, возможно, атрибут; может быть, был " +"иÑпользован недопуÑтимый Ñимвол в имени атрибута" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Ð’ÑтретилÑÑ Ð»Ð¸ÑˆÐ½Ð¸Ð¹ Ñимвол «%s», ожидалаÑÑŒ Ð¾Ñ‚ÐºÑ€Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ Ð´Ð²Ð¾Ð¹Ð½Ð°Ñ ÐºÐ°Ð²Ñ‹Ñ‡ÐºÐ° поÑле " +"знака равенÑтва при приÑваивании Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ñƒ «%s» Ñлемента «%s»" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"Символ «%s» недопуÑтим поÑле закрывающего Ñлемента имени «%s»; допуÑтимым " +"Ñимволом ÑвлÑетÑÑ Â«>»" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Элемент «%s» был закрыт, ни один Ñлемент в наÑтоÑщий момент не открыт" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"Элемент «%s» был закрыт, но открытым в наÑтоÑщий момент ÑвлÑетÑÑ Ñлемент «%s»" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Документ был пуÑÑ‚ или Ñодержал только пробелы" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Документ неожиданно окончилÑÑ Ñразу же поÑле открывающей угловой Ñкобки «<»" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Документ неожиданно окончилÑÑ, когда ещё были открыты Ñлементы — «%s» был " +"поÑледним открытым Ñлементом" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Документ неожиданно окончилÑÑ, ожидалаÑÑŒ Ð·Ð°ÐºÑ€Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ Ñ‚Ñг <%s/> ÑƒÐ³Ð»Ð¾Ð²Ð°Ñ Ñкобка" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Документ неожиданно окончилÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ имени Ñлемента" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Документ неожиданно окончилÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ имени атрибута" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Документ неожиданно окончилÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ открывающего Ñлемент Ñ‚Ñга." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Документ неожиданно окончилÑÑ Ð¿Ð¾Ñле знака равенÑтва, Ñледующего за именем " +"атрибута; значение атрибута не указано" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Документ неожиданно окончилÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð°" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Документ неожиданно окончилÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ Ñ‚Ñга, закрывающего Ñлемент «%s»" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "Документ неожиданно окончилÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ закрывающего Ñлемент Ñ‚Ñга" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Документ неожиданно окончилÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ Ð¸Ð»Ð¸ инÑтрукции обработки" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[ПÐРÐМЕТР…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Параметры Ñправки:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Показать параметры Ñправки" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Показать вÑе параметры Ñправки" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Параметры приложениÑ:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Параметры:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Ðе удалоÑÑŒ разобрать целочиÑленное значение «%s» Ð´Ð»Ñ %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "ЦелочиÑленное значение «%s» Ð´Ð»Ñ %s выходит за пределы" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Ðе удалоÑÑŒ разобрать дробное значение двойной точноÑти «%s» Ð´Ð»Ñ %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Дробное значение двойной точноÑти «%s» Ð´Ð»Ñ %s выходит за пределы" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Произошла ошибка при разборе параметра %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "ОтÑутÑтвует аргумент Ð´Ð»Ñ %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "ÐеизвеÑтный параметр %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "повреждённый объект" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° или повреждённый объект" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "закончилаÑÑŒ памÑть" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "доÑтигнут предел обратного хода" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"шаблон Ñодержит Ñлементы, которые не поддерживаютÑÑ Ð¿Ñ€Ð¸ поиÑке чаÑтичного " +"ÑовпадениÑ" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"уÑÐ»Ð¾Ð²Ð¸Ñ Ð² виде обратных ÑÑылок при поиÑке чаÑтичного ÑÐ¾Ð²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ð½Ðµ " +"поддерживаютÑÑ" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "доÑтигнут предел рекурÑии" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ñ„Ð»Ð°Ð³Ð¾Ð² перевода Ñтроки" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "неправильное Ñмещение" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "короткий utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "зацикливание рекурÑии" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ в конце шаблона" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c в конце шаблона" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "неопознанный Ñимвол Ñледует за \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "чиÑла в квантификаторе {} в неправильном порÑдке" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "Ñлишком большое чиÑло в квантификаторе {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "отÑутÑтвует Ð·Ð°Ð²ÐµÑ€ÑˆÐ°ÑŽÑ‰Ð°Ñ ] Ð´Ð»Ñ ÐºÐ»Ð°ÑÑа Ñимволов" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "неверное Ñкранирование в клаÑÑе Ñимволов" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "диапазон в клаÑÑе Ñимволов в неправильном порÑдке" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "нечего повторÑть" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "неожиданное повторение" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "неопознанный Ñимвол поÑле (? или (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "Именованные клаÑÑÑ‹ POSIX поддерживаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ внутри клаÑÑа" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "отÑутÑтвует Ð·Ð°Ð²ÐµÑ€ÑˆÐ°ÑŽÑ‰Ð°Ñ )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "ÑÑылка на неÑущеÑтвующий подшаблон" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "отÑутÑтвует ) поÑле комментариÑ" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "Ñлишком длинное регулÑрное выражение" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "не удалоÑÑŒ получить памÑть" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") без открывающей (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "переполнение кода" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "неопознанный Ñимвол поÑле (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind-утверждение не имеет фикÑированную длину" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "ошибочное чиÑло или Ð¸Ð¼Ñ Ð¿Ð¾Ñле (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "уÑÐ»Ð¾Ð²Ð½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð° Ñодержит более двух ветвей" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "ожидалоÑÑŒ утверждение поÑле (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "поÑле (?R или (?[+-]цифры должна идти )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "неизвеÑтное Ð¸Ð¼Ñ ÐºÐ»Ð°ÑÑа POSIX" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "Сортировочные Ñлементы POSIX не поддерживаютÑÑ" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "Ñлишком большое значение Ñимвола в поÑледовательноÑти \\x{…}" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "ошибочное уÑловие (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C запрещено в lookbehind-утверждениÑÑ…" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "Ñкранирование \\L, \\l, \\N{name}, \\U и \\u не поддерживаетÑÑ" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "рекурÑивный вызов мог повторÑтьÑÑ Ð±ÐµÑконечно" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "неопознанный Ñимвол поÑле (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "отÑутÑтвует завершающий Ñимвол в имени подшаблона" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "два именованных подшаблона имеют одинаковое имÑ" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "Ð¾ÑˆÐ¸Ð±Ð¾Ñ‡Ð½Ð°Ñ Ð¿Ð¾ÑледовательноÑть \\P или \\p" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "неизвеÑтное Ð¸Ð¼Ñ ÑвойÑтва поÑле \\P или \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "Ð¸Ð¼Ñ Ð¿Ð¾Ð´ÑˆÐ°Ð±Ð»Ð¾Ð½Ð° Ñлишком длинное (не должно превышать 32 Ñимвола)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "Ñлишком много именованных подшаблонов (не должно быть больше 10 000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "воÑьмеричное значение превышает \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "переполнение рабочего проÑтранÑтва компилÑции" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "не найден ранее проверенный подшаблон Ñо ÑÑылкой" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "Группа DEFINE Ñодержит более одной ветви" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "противоречивые параметры NEWLINE" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"за \\g не Ñледует Ð¸Ð¼Ñ Ð¸Ð»Ð¸ чиÑло в Ñкобках, угловых Ñкобках или кавычках, или " +"проÑто чиÑло" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "Ð½Ð¾Ð¼ÐµÑ€Ð½Ð°Ñ ÑÑылка не может быть нулём" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ параметр Ð´Ð»Ñ (*ACCEPT), (*FAIL) или (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "значение (*VERB) не раÑпознано" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "Ñлишком большое чиÑло" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "отÑутÑтвует Ð¸Ð¼Ñ Ð¿Ð¾Ð´ÑˆÐ°Ð±Ð»Ð¾Ð½Ð° поÑле (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "ожидалаÑÑŒ цифра поÑле (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñимвол ] в режиме ÑовмеÑтимоÑти JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" +"не допуÑкаютÑÑ Ð¸Ñпользовать различные имена Ð´Ð»Ñ Ð¿Ð¾Ð´ÑˆÐ°Ð±Ð»Ð¾Ð½Ð¾Ð² Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼ " +"номером" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "Ð´Ð»Ñ (*MARK) требуетÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "за \\c должен быть Ñимвол ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "за \\k не Ñледует Ð¸Ð¼Ñ Ð² Ñкобках, угловых Ñкобках или кавычках" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N в клаÑÑе не поддерживаетÑÑ" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "Ñлишком много прÑмых ÑÑылок" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "Ñлишком длинное Ð¸Ð¼Ñ Ð² (*MARK), (*PRUNE), (*SKIP) или (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "значение Ñимвола в поÑледовательноÑти \\u.... Ñлишком велико" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" +"Во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð¸Ñка Ñовпадений Ñ Ñ€ÐµÐ³ÑƒÐ»Ñрным выражением %s возникла ошибка: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Библиотека PCRE Ñобрана без поддержки UTF-8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Библиотека PCRE Ñобрана без поддержки ÑвойÑтв UTF-8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Библиотека PCRE Ñобрана Ñ Ð½ÐµÑовмеÑтимыми параметрами" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Произошла ошибка при оптимизации регулÑрного Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" +"Произошла ошибка при компилÑции регулÑрного Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ %s у Ñимвола Ñ Ð½Ð¾Ð¼ÐµÑ€Ð¾Ð¼ " +"%d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "ожидалаÑÑŒ шеÑÑ‚Ð½Ð°Ð´Ñ†Ð°Ñ‚ÐµÑ€Ð¸Ñ‡Ð½Ð°Ñ Ñ†Ð¸Ñ„Ñ€Ð° или Ñимвол «}»" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "ожидалаÑÑŒ шеÑÑ‚Ð½Ð°Ð´Ñ†Ð°Ñ‚ÐµÑ€Ð¸Ñ‡Ð½Ð°Ñ Ñ†Ð¸Ñ„Ñ€Ð°" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "в Ñимвольной ÑÑылке отÑутÑтвует «<»" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "Ð½ÐµÐ·Ð°ÐºÐ¾Ð½Ñ‡ÐµÐ½Ð½Ð°Ñ ÑÐ¸Ð¼Ð²Ð¾Ð»ÑŒÐ½Ð°Ñ ÑÑылка" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "ÑÐ¸Ð¼Ð²Ð¾Ð»ÑŒÐ½Ð°Ñ ÑÑылка нулевой длины" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "ожидалаÑÑŒ цифра" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "недопуÑÑ‚Ð¸Ð¼Ð°Ñ ÑÐ¸Ð¼Ð²Ð¾Ð»ÑŒÐ½Ð°Ñ ÑÑылка" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "лишний «\\» в конце" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "неизвеÑÑ‚Ð½Ð°Ñ ÑÐºÑ€Ð°Ð½Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ð¿Ð¾ÑледовательноÑть" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Произошла ошибка во Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð·Ð±Ð¾Ñ€Ð° текÑта замен «%s» у Ñимвола Ñ Ð½Ð¾Ð¼ÐµÑ€Ð¾Ð¼ %lu: " +"%s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "ТекÑÑ‚ в кавычках не начинаетÑÑ Ñ Ñимвола кавычки" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Обнаружена Ð½ÐµÐ·Ð°ÐºÑ€Ñ‹Ñ‚Ð°Ñ ÐºÐ°Ð²Ñ‹Ñ‡ÐºÐ° в командной Ñтроке или другом текÑте от " +"оболочки" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "ТекÑÑ‚ закончилÑÑ Ñразу поÑле Ñимвола «\\» (текÑÑ‚ был «%s»)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"ТекÑÑ‚ закончилÑÑ Ð´Ð¾ того, как была найдена Ð·Ð°ÐºÑ€Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ ÐºÐ°Ð²Ñ‹Ñ‡ÐºÐ° Ð´Ð»Ñ %c. " +"(ТекÑÑ‚ был «%s»)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "ТекÑÑ‚ был пуÑÑ‚ (или Ñодержал только пробелы)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Ðе удалоÑÑŒ прочитать данные из дочернего процеÑÑа (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "ÐÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при чтении данных из дочернего процеÑÑа (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Произошла Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° в функции waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Дочерний процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»ÑÑ Ñ ÐºÐ¾Ð´Ð¾Ð¼ %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Дочерний процеÑÑ ÑƒÐ±Ð¸Ñ‚ по Ñигналу %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Дочерний процеÑÑ Ð¾Ñтановлен по Ñигналу %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Дочерний процеÑÑ Ð°Ð²Ð°Ñ€Ð¸Ð¹Ð½Ð¾ завершил работу" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Ðе удалоÑÑŒ выполнить чтение из дочернего канала (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Ðе удалоÑÑŒ запуÑтить дочерний процеÑÑ \"%s\" (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ fork завершилаÑÑŒ неудачно (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Ðе удалоÑÑŒ Ñменить каталог на «%s» (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Ðе удалоÑÑŒ выполнить дочерний процеÑÑ \"%s\" (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Ðе удалоÑÑŒ открыть файл Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´ÐµÑкриптора файла (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Ðе удалоÑÑŒ дублировать деÑкриптор файла Ð´Ð»Ñ Ð´Ð¾Ñ‡ÐµÑ€Ð½ÐµÐ³Ð¾ процеÑÑа (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "При Ñоздании дочернего процеÑÑа Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ fork завершилаÑÑŒ неудачно (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Ðе удалоÑÑŒ закрыть деÑкриптор файла Ð´Ð»Ñ Ð´Ð¾Ñ‡ÐµÑ€Ð½ÐµÐ³Ð¾ процеÑÑа (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Произошла неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при выполнении дочернего процеÑÑа «%s»" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Ðе удалоÑÑŒ прочитать нужное количеÑтво данных из канала дочернего процеÑÑа " +"(%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Ðе удалоÑÑŒ прочитать данные из дочернего процеÑÑа" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Ðе удалоÑÑŒ выполнить дочерний процеÑÑ (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Ðе удалоÑÑŒ выполнить dup() в дочернем процеÑÑе (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñтрока в векторе аргументов под номером %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñтрока в окружении: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ÐедопуÑтимый рабочий каталог: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Ðе удалоÑÑŒ выполнить вÑпомогательную программу (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Произошла Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° в функции g_io_channel_win32_poll() при чтении " +"данных из процеÑÑа-потомка" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "ПуÑÑ‚Ð°Ñ Ñтрока не ÑвлÑетÑÑ Ñ‡Ð¸Ñлом" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "«%s» не ÑвлÑетÑÑ Ñ‡Ð¸Ñлом Ñо знаком" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "ЧиÑло «%s» is out of bounds [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "«%s» не ÑвлÑетÑÑ Ñ‡Ð¸Ñлом без знака" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ %-кодировка в URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "ÐедопуÑтимый Ñимвол в URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Ðе UTF-8 Ñимвол в URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "ÐедопуÑтимый IPv6 Ð°Ð´Ñ€ÐµÑ â€˜%.*s’ в URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "ÐедопуÑтимый закодированный IP Ð°Ð´Ñ€ÐµÑ â€˜%.*s’ в URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "ÐедопуÑтимое интернациональное Ð¸Ð¼Ñ Ñ…Ð¾Ñта ‘%.*s’ в URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Ðевозможно разобрать порт ‘%.*s’ в URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Порт ‘%.*s’ в URI выходит за разрешённые границы" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "Путь «%s» не ÑвлÑетÑÑ Ð°Ð±Ñолютным URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI ‘%s’ не Ñодержит имени или адреÑа Ñервера" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI не абÑолютный, базовый Ð°Ð´Ñ€ÐµÑ URI не указан" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Ðе хватает Ñимвола ‘=’ и Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Ðе удалоÑÑŒ выделить памÑть" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Символ находитÑÑ Ð²Ð½Ðµ диапазона Ð´Ð»Ñ UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "" +"Во входной Ñтроке Ð´Ð»Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð° недопуÑÑ‚Ð¸Ð¼Ð°Ñ " +"поÑледовательноÑть" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Символ находитÑÑ Ð²Ð½Ðµ диапазона Ð´Ð»Ñ UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f кБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ТБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ПБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ЭБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f КиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f МиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f ГиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f ТиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f ПиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f ЭиБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f кбит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Мбит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Гбит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Тбит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Пбит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Эбит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Кибит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Мибит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Гибит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Тибит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Пибит" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Эибит" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u байт" +msgstr[1] "%u байта" +msgstr[2] "%u байт" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u бит" +msgstr[1] "%u бита" +msgstr[2] "%u бит" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s байт" +msgstr[1] "%s байта" +msgstr[2] "%s байт" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s бит" +msgstr[1] "%s бита" +msgstr[2] "%s бит" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f КБ" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ТБ" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ПБ" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ЭБ" diff --git a/po/rw.po b/po/rw.po new file mode 100644 index 0000000..25b3702 --- /dev/null +++ b/po/rw.po @@ -0,0 +1,3892 @@ +# translation of glib to Kinyarwanda. +# Copyright (C) 2005 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Steve Murphy , 2005 +# Steve performed initial rough translation from compendium built from translations provided by the following translators: +# Philibert Ndandali , 2005. +# Viateur MUGENZI , 2005. +# Noëlla Mupole , 2005. +# Carole Karema , 2005. +# JEAN BAPTISTE NGENDAHAYO , 2005. +# Augustin KIBERWA , 2005. +# Donatien NSENGIYUMVA , 2005.. +# +msgid "" +msgstr "" +"Project-Id-Version: glib 2.12\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2005-03-28 19:34-0700\n" +"Last-Translator: Steve Murphy \n" +"Language-Team: Kinyarwanda \n" +"Language: rw\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, fuzzy, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Inyuguti Ikitezwe: a Nyuma Ikiranga Izina: Bya Ikigize:" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +#, fuzzy +msgid "No valid bookmark file found in data dirs" +msgstr "Urufunguzo IDOSIYE OYA Byabonetse in Ibyatanzwe" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Kuri Gusoma Ihuza" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, fuzzy, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Bivuye Inyuguti Gushyiraho Kuri ni OYA" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "OYA Gufungura Bivuye Kuri" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +#, fuzzy +msgid "Invalid byte sequence in conversion input" +msgstr "Bayite in Ihindurangero Iyinjiza" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, fuzzy, c-format +msgid "Error during conversion: %s" +msgstr "Ihindurangero" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +#, fuzzy +msgid "Partial character sequence at end of input" +msgstr "Inyuguti ku Impera Bya Iyinjiza" + +#: ../glib/gconvert.c:1059 +#, fuzzy, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "GUHINDURA Kuri" + +#: ../glib/gconvert.c:1886 +#, fuzzy, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "ni OYA ikoresha IDOSIYE Igishusho" + +#: ../glib/gconvert.c:1896 +#, fuzzy, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "IDOSIYE Gicurasi OYA Gushyiramo a" + +#: ../glib/gconvert.c:1913 +#, fuzzy, c-format +msgid "The URI '%s' is invalid" +msgstr "ni Sibyo" + +#: ../glib/gconvert.c:1925 +#, fuzzy, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Izina ry'inturo: Bya ni Sibyo" + +#: ../glib/gconvert.c:1941 +#, fuzzy, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "Kirimo Inyuguti" + +#: ../glib/gconvert.c:2036 +#, fuzzy, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "ni OYA Inzira" + +#: ../glib/gconvert.c:2046 +#, fuzzy +msgid "Invalid hostname" +msgstr "Izina ry'inturo:" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Mutarama" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Gashyantare" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Werurwe" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "Mata" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Gicuransi" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Kamena" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Nyakanga" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Mut" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Gas" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Wer" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Mat" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Gic" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Kam" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Nya" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Kuwa mbere" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Kuwa kabiri" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Kuwa gatatu" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Kuwa kane" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Kuwa gatanu" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Kuwa gatandatu" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Ku cyumweru" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Mbe" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Kab" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Gtu" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Kan" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Gnu" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Gnd" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Mwe" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, fuzzy, c-format +msgid "Error opening directory '%s': %s" +msgstr "Gufungura %s%S bushyinguro" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, fuzzy, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "OYA Bayite Kuri Gusoma IDOSIYE" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../glib/gfileutils.c:555 +#, fuzzy, c-format +msgid "Error reading file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, fuzzy, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Kuri Gusoma Bivuye IDOSIYE" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, fuzzy, c-format +msgid "Failed to open file '%s': %s" +msgstr "Kuri Gufungura IDOSIYE" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, fuzzy, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Kuri Kubona Ibiranga Bya IDOSIYE Byanze" + +#: ../glib/gfileutils.c:754 +#, fuzzy, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Kuri Gufungura IDOSIYE Byanze" + +#: ../glib/gfileutils.c:862 +#, fuzzy, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Kuri Guhindura izina IDOSIYE Kuri Byanze" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, fuzzy, c-format +msgid "Failed to create file '%s': %s" +msgstr "Kuri Kurema IDOSIYE" + +#: ../glib/gfileutils.c:918 +#, fuzzy, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Kuri Gufungura IDOSIYE kugirango Byanze" + +#: ../glib/gfileutils.c:943 +#, fuzzy, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Kuri IDOSIYE Byanze" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Kuri IDOSIYE Byanze" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Kuri IDOSIYE Byanze" + +#: ../glib/gfileutils.c:1030 +#, fuzzy, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Kuri Gufunga IDOSIYE Byanze" + +#: ../glib/gfileutils.c:1152 +#, fuzzy, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "IDOSIYE OYA Cyavanyweho Byanze" + +#: ../glib/gfileutils.c:1412 +#, fuzzy, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Sibyo OYA a" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Impera Na:" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, fuzzy, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Kuri Gusoma Ihuza" + +#: ../glib/gfileutils.c:2231 +#, fuzzy +msgid "Symbolic links not supported" +msgstr "amahuza OYA" + +#: ../glib/giochannel.c:1408 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "OYA Gufungura Bivuye Kuri" + +#: ../glib/giochannel.c:1753 +#, fuzzy +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "a Gusoma in" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +#, fuzzy +msgid "Leftover unconverted data in read buffer" +msgstr "Ibyatanzwe in Gusoma" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +#, fuzzy +msgid "Channel terminates in a partial character" +msgstr "in a Bituzuye Inyuguti" + +#: ../glib/giochannel.c:1944 +#, fuzzy +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "a Gusoma in" + +#: ../glib/gmappedfile.c:150 +#, fuzzy, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Kuri Gufungura IDOSIYE Byanze" + +#: ../glib/gmappedfile.c:229 +#, fuzzy, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Kuri Gufungura IDOSIYE Byanze" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "ku Umurongo INYUGUTI" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "8 Umwandiko" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, fuzzy, c-format +msgid "Error on line %d: %s" +msgstr "ku Umurongo" + +#: ../glib/gmarkup.c:638 +#, fuzzy, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "Kuri a Mo Imbere a Inyuguti Indango kugirango Urugero ni Binini" + +#: ../glib/gmarkup.c:650 +#, fuzzy +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "Indango OYA Impera Na: a Akabago n'Akitso Inyuguti Kuri Gutangira Nka" + +#: ../glib/gmarkup.c:676 +#, fuzzy, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Indango OYA a Inyuguti" + +#: ../glib/gmarkup.c:714 +#, fuzzy +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "Byemewe" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Izina: ni OYA" + +#: ../glib/gmarkup.c:727 +#, fuzzy +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "OYA Impera Na: a Akabago n'Akitso Inyuguti Kuri Gutangira Nka" + +#: ../glib/gmarkup.c:1078 +#, fuzzy +msgid "Document must begin with an element (e.g. )" +msgstr "g." + +#: ../glib/gmarkup.c:1118 +#, fuzzy, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "'%s'ni OYA a Byemewe Inyuguti a Inyuguti Gicurasi OYA Ikigize: Izina:" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Inyuguti Ikitezwe: a Inyuguti Kuri Impera Gutangira Itagi: Bya Ikigize:" + +#: ../glib/gmarkup.c:1270 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "Inyuguti Ikitezwe: a Nyuma Ikiranga Izina: Bya Ikigize:" + +#: ../glib/gmarkup.c:1311 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Inyuguti Ikitezwe: a Cyangwa Inyuguti Kuri Impera Gutangira Itagi: Bya " +"Ikigize: Cyangwa Ikiranga Sibyo Inyuguti in Ikiranga Izina:" + +#: ../glib/gmarkup.c:1355 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Inyuguti Ikitezwe: Gufungura Gushyiraho akugarizo Ikimenyetso Nyuma " +"IKIMENYETSO Ryari: Agaciro kugirango Ikiranga Bya Ikigize:" + +#: ../glib/gmarkup.c:1488 +#, fuzzy, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "'%s'ni OYA a Byemewe Inyuguti Gufunga Ikigize: Izina: Inyuguti ni" + +#: ../glib/gmarkup.c:1535 +#, fuzzy, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Oya Ikigize: ni Gufungura" + +#: ../glib/gmarkup.c:1544 +#, fuzzy, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Gufungura Ikigize: ni" + +#: ../glib/gmarkup.c:1712 +#, fuzzy +msgid "Document was empty or contained only whitespace" +msgstr "ubusa Cyangwa" + +#: ../glib/gmarkup.c:1726 +#, fuzzy +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "Nyuma Gufungura Imfuruka" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, fuzzy, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "Na: Ibintu Gufungura Iheruka Ikigize:" + +#: ../glib/gmarkup.c:1742 +#, fuzzy, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "Ikitezwe: Kuri a Gufunga Imfuruka Itagi:" + +#: ../glib/gmarkup.c:1748 +#, fuzzy +msgid "Document ended unexpectedly inside an element name" +msgstr "Mo Imbere Ikigize: Izina:" + +#: ../glib/gmarkup.c:1754 +#, fuzzy +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Mo Imbere Ikiranga Izina:" + +#: ../glib/gmarkup.c:1759 +#, fuzzy +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Mo Imbere Ikigize: Gufungura%S Itagi:" + +#: ../glib/gmarkup.c:1765 +#, fuzzy +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "Nyuma IKIMENYETSO Ikiranga Izina: Oya Ikiranga Agaciro" + +#: ../glib/gmarkup.c:1772 +#, fuzzy +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Mo Imbere Ikiranga Agaciro" + +#: ../glib/gmarkup.c:1788 +#, fuzzy, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Mo Imbere Gufunga Itagi: kugirango Ikigize:" + +#: ../glib/gmarkup.c:1794 +#, fuzzy +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Mo Imbere a Icyo wongeraho Cyangwa Inonosora" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "in a Bituzuye Inyuguti" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "Bayite in Ihindurangero Iyinjiza" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "Inyuguti Indango" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "Inyuguti Indango" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "Inyuguti Indango" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "amahuza OYA" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "ku Umurongo INYUGUTI" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "Indango" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +#, fuzzy +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Umwandiko Na: a Gusubiramo ibyavuzwe Ikimenyetso" + +#: ../glib/gshell.c:181 +#, fuzzy +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Gusubiramo ibyavuzwe Ikimenyetso in Komandi: Umurongo Cyangwa Ikindi " +"Igikonoshwa Umwandiko" + +#: ../glib/gshell.c:559 +#, fuzzy, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Nyuma a Inyuguti Umwandiko" + +#: ../glib/gshell.c:566 +#, fuzzy, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "Mbere Gushyiraho akugarizo Byabonetse kugirango Umwandiko" + +#: ../glib/gshell.c:578 +#, fuzzy +msgid "Text was empty (or contained only whitespace)" +msgstr "ubusa Cyangwa" + +#: ../glib/gspawn-win32.c:282 +#, fuzzy +msgid "Failed to read data from child process" +msgstr "Kuri Gusoma Ibyatanzwe Bivuye" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, fuzzy, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Kuri Kurema kugirango Na:" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, fuzzy, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Kuri Gusoma Bivuye" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, fuzzy, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Kuri Guhindura>> Kuri bushyinguro" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, fuzzy, c-format +msgid "Failed to execute child process (%s)" +msgstr "Kuri Gukora" + +#: ../glib/gspawn-win32.c:444 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "Izina ry'inturo:" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, fuzzy, c-format +msgid "Invalid string in environment: %s" +msgstr "in Ihindurangero Iyinjiza" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, fuzzy, c-format +msgid "Invalid working directory: %s" +msgstr "Gufungura %s%S bushyinguro" + +#: ../glib/gspawn-win32.c:783 +#, fuzzy, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Kuri Gukora Porogaramu" + +#: ../glib/gspawn-win32.c:997 +#, fuzzy +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "Ikosa in Ibyatanzwe Bivuye a" + +#: ../glib/gspawn.c:207 +#, fuzzy, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Kuri Gusoma Ibyatanzwe Bivuye" + +#: ../glib/gspawn.c:347 +#, fuzzy, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Ikosa in Guhitamo Ibyatanzwe Bivuye a" + +#: ../glib/gspawn.c:432 +#, fuzzy, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ikosa in" + +#: ../glib/gspawn.c:1237 +#, fuzzy, c-format +msgid "Failed to fork (%s)" +msgstr "Kuri" + +#: ../glib/gspawn.c:1393 +#, fuzzy, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Kuri Gukora" + +#: ../glib/gspawn.c:1403 +#, fuzzy, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Kuri Ibisohoka Cyangwa Iyinjiza Bya" + +#: ../glib/gspawn.c:1412 +#, fuzzy, c-format +msgid "Failed to fork child process (%s)" +msgstr "Kuri" + +#: ../glib/gspawn.c:1420 +#, fuzzy, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Ikosa Gukora: %s%s" + +#: ../glib/gspawn.c:1444 +#, fuzzy, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Kuri Gusoma Ibyatanzwe Bivuye" + +#: ../glib/gutf8.c:1086 +#, fuzzy +msgid "Character out of range for UTF-8" +msgstr "Inyuma Bya Urutonde kugirango 8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +#, fuzzy +msgid "Invalid sequence in conversion input" +msgstr "in Ihindurangero Iyinjiza" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +#, fuzzy +msgid "Character out of range for UTF-16" +msgstr "Inyuma Bya Urutonde kugirango" + +# crashrep/source\all\crashrep.lng:%MSG_CMDLINE_USAGE%.text +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Ikoresha:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:867 +#, fuzzy +msgid "Show help options" +msgstr "Ifashayobora Amahitamo" + +#: ../glib/goption.c:873 +#, fuzzy +msgid "Show all help options" +msgstr "Byose Ifashayobora Amahitamo" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, fuzzy, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Umubare wuzuye Agaciro kugirango" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, fuzzy, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Agaciro kugirango Inyuma Bya Urutonde" + +#: ../glib/goption.c:1032 +#, fuzzy, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Umubare wuzuye Agaciro kugirango" + +#: ../glib/goption.c:1040 +#, fuzzy, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Agaciro kugirango Inyuma Bya Urutonde" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "Ihindurangero" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, fuzzy, c-format +msgid "Unknown option %s" +msgstr "Ihitamo ritazwi:" + +#: ../glib/gkeyfile.c:366 +#, fuzzy +msgid "Valid key file could not be found in search dirs" +msgstr "Urufunguzo IDOSIYE OYA Byabonetse in Ibyatanzwe" + +#: ../glib/gkeyfile.c:401 +#, fuzzy +msgid "Not a regular file" +msgstr "a Ibisanzwe IDOSIYE" + +#: ../glib/gkeyfile.c:409 +#, fuzzy +msgid "File is empty" +msgstr "Idosiye ni ubusa" + +#: ../glib/gkeyfile.c:768 +#, fuzzy, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"IDOSIYE Kirimo Umurongo ni OYA a Urufunguzo Agaciro Itsinda Cyangwa Icyo " +"wongeraho" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "Izina ry'inturo:" + +#: ../glib/gkeyfile.c:850 +#, fuzzy +msgid "Key file does not start with a group" +msgstr "IDOSIYE OYA Gutangira Na: a Itsinda" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "Izina ry'inturo:" + +#: ../glib/gkeyfile.c:903 +#, fuzzy, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "IDOSIYE Kirimo Imisobekere:" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, fuzzy, c-format +msgid "Key file does not have group '%s'" +msgstr "IDOSIYE OYA Itsinda" + +#: ../glib/gkeyfile.c:1323 +#, fuzzy, c-format +msgid "Key file does not have key '%s'" +msgstr "IDOSIYE OYA Urufunguzo" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, fuzzy, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "IDOSIYE Kirimo Urufunguzo Na: Agaciro ni OYA 8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, fuzzy, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "IDOSIYE Kirimo Urufunguzo Agaciro" + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "IDOSIYE Kirimo Urufunguzo Agaciro" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "IDOSIYE Kirimo Urufunguzo in Itsinda Agaciro" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, fuzzy, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "IDOSIYE OYA Urufunguzo in Itsinda" + +#: ../glib/gkeyfile.c:3708 +#, fuzzy +msgid "Key file contains escape character at end of line" +msgstr "IDOSIYE Kirimo Inyuguti ku Impera Bya Umurongo" + +#: ../glib/gkeyfile.c:3730 +#, fuzzy, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "IDOSIYE Kirimo Sibyo" + +#: ../glib/gkeyfile.c:3872 +#, fuzzy, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Nka a Umubare" + +#: ../glib/gkeyfile.c:3886 +#, fuzzy, c-format +msgid "Integer value '%s' out of range" +msgstr "Agaciro kugirango Inyuma Bya Urutonde" + +#: ../glib/gkeyfile.c:3919 +#, fuzzy, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Nka a Umubare" + +#: ../glib/gkeyfile.c:3943 +#, fuzzy, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Nka a Icyungo" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Bayite in Ihindurangero Iyinjiza" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "amahuza OYA" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "Ihitamo ritazwi:" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Ihitamo ritazwi:" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Gufungura %s%S bushyinguro" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Gufungura %s%S bushyinguro" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "amahuza OYA" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "ku Umurongo" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Ihindurangero" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "ni OYA Byemewe Mo Imbere Izina:" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "ni OYA Byemewe Mo Imbere Izina:" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "ni OYA Byemewe Mo Imbere Izina:" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Ihindurangero" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Ihindurangero" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Gufungura %s%S bushyinguro" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "amahuza OYA" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "amahuza OYA" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "amahuza OYA" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "amahuza OYA" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Izina ry'inturo:" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "Izina ry'inturo:" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Kuri Kurema IDOSIYE" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Kuri Kurema IDOSIYE" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "Kuri Kurema IDOSIYE" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Gufungura %s%S bushyinguro" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Kuri Gusoma Ihuza" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Ihindurangero" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "Mo Imbere Ikiranga Izina:" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Gufungura %s%S bushyinguro" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Ihindurangero" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Ihindurangero" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Ihindurangero" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "ku Umurongo" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Ihindurangero" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Ihindurangero" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "amahuza OYA" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Ihindurangero" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +#, fuzzy +msgid "Target file is not a regular file" +msgstr "a Ibisanzwe IDOSIYE" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Izina ry'inturo:" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Ihitamo ritazwi:" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Kuri Kurema IDOSIYE" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "Kuri IDOSIYE Byanze" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Ihindurangero" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Kuri Kurema IDOSIYE" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Kuri Kurema IDOSIYE" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "amahuza OYA" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "ku Umurongo" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Ihindurangero" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Ihindurangero" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "amahuza OYA" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Ikosa mu gusoma idosiye" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Ikosa mu gusoma idosiye" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Izina ry'inturo:" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "in Ihindurangero Iyinjiza" + +#, fuzzy +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "ni OYA Byemewe ku Gutangira Bya Izina: Inyuguti NIBA iyi Kuri Nka" + +#, fuzzy +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Inyuguti Indango Gushyiramo a Nka" + +#, fuzzy +#~ msgid "Unfinished entity reference" +#~ msgstr "Indango" + +#, fuzzy +#~ msgid "Unfinished character reference" +#~ msgstr "Inyuguti Indango" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "8 Umwandiko" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "8 Umwandiko" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Izina ry'inturo: Bya ni Sibyo" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Izina ry'inturo: Bya ni Sibyo" + +# svtools/source\misc\errtxt.src:RID_ERRHDL.ERRCODE_SFX_DOLOADFAILED.text +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Ikosa mu gusoma idosiye" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Ihindurangero" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Kuri Gufunga IDOSIYE Byanze" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Kuri Gufunga IDOSIYE Byanze" diff --git a/po/si.po b/po/si.po new file mode 100644 index 0000000..84b9771 --- /dev/null +++ b/po/si.po @@ -0,0 +1,3769 @@ +# translation of glib.si.po to Sinhala +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Danishka Navin , 2007. +msgid "" +msgstr "" +"Project-Id-Version: glib.si\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2007-06-20 14:56+0530\n" +"Last-Translator: Danishka Navin \n" +"Language-Team: Sinhala \n" +"Language: si\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "'%s' මූලය සඳහ෠බලà·à¶´à·œà¶»à·œà¶­à·Šà¶­à·” නොවු '%s' විà·à·šà·‚ණය" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "'%s' මූලයෙහි '%s' විà·à·šà·‚ණය හමුවුයේ à¶±à·à¶­" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "'%s'à¶¶à¶½à·à¶´à·œà¶»à·œà¶­à·Šà¶­à·” නොවු à¶§à·à¶œà¶ºà¶šà·’, à¶¶à¶½à·à¶´à·œà¶»à·œà¶­à·Šà¶­à·” වුයේ '%s' à¶§à·à¶œà¶ºà¶ºà·’" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "'%s'à¶¶à¶½à·à¶´à·œà¶»à·œà¶­à·Šà¶­à·” නොවු à¶§à·à¶œà¶ºà¶šà·Š '%s' තුළ ඇත" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "දත්ත බහලුම් තුළ නිරවද්â€à¶º à¶´à·’à¶§à·” සළකුණක් හමුවූයෙ à¶±à·à¶­" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "'%s' URI සඳහ෠වු à¶´à·’à¶§à·” සළකුණ දà·à¶±à¶§ à¶·à·à·€à·’තයේ ඇත" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "'%s' URI සඳහ෠පිටු සළකුණු හමුවුයේ à¶±à·à¶­" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "'%s' URI සඳහ෠වු à¶´à·’à¶§à·” සළකුණු තුළ MIME වර්â€à·„ගයක් සදහන් කරුයේ à¶±à·à¶­" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "'%s' URI සඳහ෠වු à¶´à·’à¶§à·” සළකුණු තුළ සමූහ කට්ටලය à¶±à·à¶­" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' සිට '%s' දක්ව෠පරිවර්තකය විවෘත à¶šà·… නොහà·à¶šà·’ විය" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "පරිවර්තන à¶´à·Šâ€à¶»à¶°à·à¶°à· තුළ à·ƒà·à·€à¶¯à·Šâ€à¶º බයිට් පිළිවෙළක්යේ" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "%s' URI à·ƒà·à·€à¶¯à·Šâ€à¶º වේ" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "'%s' URI à·„à·’ à¶°à·à¶»à¶š à¶±à·à¶¸à¶º à·ƒà·à·€à¶¯à·Šâ€à¶º වේ" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º à¶°à·à¶»à¶š à¶±à·à¶¸à¶º" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "à¶´à·™.à·€." + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "à¶´.à·€." + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Y-%m-%d %H:%M:%S %z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%Y-%m-%d" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%p %I:%M:%S" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "ජනවà·à¶»à·’" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "පෙබරවà·à¶»à·’" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "මà·à¶»à·Šà¶­à·”" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "à¶…à¶´à·Šâ€à¶»à·’යෙල්" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "මà·à¶ºà·’" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "ජූනි" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "ජූලි" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ජන" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "පෙබ" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "මà·à¶»à·Š" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à¶…à¶´à·Šâ€à¶»à·’" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "මà·à¶ºà·’" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ජූනි" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ජූලි" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "සඳුදà·" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "අඟහරුවà·à¶¯à·" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "බදà·à¶¯à·" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "à¶¶à·Šâ€à¶»à·„ස්පතින්දà·" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "සිකුරà·à¶¯à·" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "සෙනසුරà·à¶¯à·" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ඉරිදà·" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "à·ƒ" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "à¶…" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "à¶¶" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "à¶¶à·Šâ€à¶»" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "සි" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "සෙ" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ඉ" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "'%s' ගහලුම විවෘත කිරීම දà·à·‚ සහිතයි: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, fuzzy, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr " \"%s\" ගොනුව කියවීම සඳහ෠%lu බයිට් à¶´à·Šâ€à¶»à¶¸à·à¶«à¶ºà¶šà·Š යෙදවිය නොහà·à¶šà·’ විය" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' ගොනුවෙන් කියවීම අසමත් විය: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' ගොනුව විවෘත කිරීම අසමත් විය: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' ගොනුවේ විà·à·šà·‚à¶« ලබ෠ගà·à¶±à·“ම අසමත් විය: fstat() අසමත් විය: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' ගොනුව විවෘත කිරීම අසමත් විය: fdopen() අසමත් විය: %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "'%s' ගොනුව '%s' ලෙස නම වෙනස් à¶­ කිරීම අසමත් විය: g_rename(අසමත් වියed: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' ගොනුව නිර්මà·à¶«à¶º දà·à·‚ සහිතයි: %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "ලිවීම සඳහ෠'%s' ගොනුව විවෘත කිරීම අසමත් විය: fdopen() අසමත් විය: %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "'%s' ගොනුවට ලිවීම අසමත් විය: fwrite() අසමත් විය: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "'%s' ගොනුවට ලිවීම අසමත් විය: fwrite() අසමත් විය: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' ගොනුවට ලිවීම අසමත් විය: fwrite() අසමත් විය: %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "'%s' ගොනුව à·€à·à·ƒà·“මීම අසමත් විය: fclose() අසමත් විය: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "දà·à¶±à¶§ ඇති '%s' ගොනුව ඉවත් à¶šà·… නොහà·à¶š: g_unlink() අසමත් විය: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "'%s' ආකෘතිය à·ƒà·à·€à¶¯à·Šâ€à¶º වේ, '%s' අඩංගු නොවිය යූතුය" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "'%s' ආකෘතියේ XXXXXX අඩංගු නොවේ" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "'%s' සංකේතà·à¶­à·Šà¶¸à¶š පුරුක කියවිම අසමත් විය: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' සිට '%s' දක්ව෠පරිවර්තකය විවෘත à¶šà·… නොහà·à¶š: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "'%s' ගොනුව විවෘත කිරීම අසමත් විය: open() අසමත් විය: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "'%s' ගොනුව අනුරුපණය කිරීම අසමත් විය: mmap()අසමත් විය: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "%d පේළියේ %d à¶…à¶šà·Šâ€à·‚රය මත දà·à·‚යකි: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º UTF-8 සංකේතà·à¶‚à¶šà¶± පෙළ" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d පේළියේ à¶­ දà·à·‚යකි: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "'%s' වස්තුවේ නම නොදනී" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "ලේඛණය මූලයකින්ම ආරම්භ à¶šà·… යුතුම වේ (උදà·. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "'%s' මූලය වස෠ඇති à¶…à¶­à¶» කිසිම මූලයක් විවෘතව ඇත" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "'%s' මූලය වස෠ඇති à¶…à¶­à¶» දà·à¶±à¶§'%s' මූලය විවෘතව ඇත" + +#: ../glib/gmarkup.c:1712 +#, fuzzy +msgid "Document was empty or contained only whitespace" +msgstr "ලේඛණය හිස්ව තිබුනි හ෠තිබුනේ සුදුඉඩ පමණි" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "විනà·à· වු වස්තුවක්" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "à¶…à¶·à·Šâ€à¶ºà¶±à·Šà¶­à¶» දà·à·‚ය හ෠විනà·à· වු වස්තුවක්" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "à¶´à·Šâ€à¶»à¶¸à·à¶«à·€à¶­à·Š මතකයක් à¶±à·à¶­" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "à¶…à¶·à·Šâ€à¶ºà¶±à·Šà¶­à¶» දà·à·‚ය" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "නොදන්න෠දà·à·‚ය" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "පරිවර්තන à¶´à·Šâ€à¶»à¶°à·à¶°à· තුළ à·ƒà·à·€à¶¯à·Šâ€à¶º බයිට් පිළිවෙළක්යේ" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "අවසන් නොකළ à¶…à¶šà·Šâ€à·‚à¶» යොමුව" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "අවසන් නොකළ à¶…à¶šà·Šâ€à·‚à¶» යොමුව" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "අවසන් නොකළ à¶…à¶šà·Šâ€à·‚à¶» යොමුව" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "දහසයේ à¶´à·à¶¯à¶ºà·š අංකිතයක් à·„à· '}' à¶¶à¶½à·à¶´à·œà¶»à·œà¶­à·Šà¶­à·” වේ" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "දහසයේ à¶´à·à¶¯à¶ºà·š අංකිතයක් à¶¶à¶½à·à¶´à·œà¶»à·œà¶­à·Šà¶­à·” වේ" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š යොමුව තුළ '<' මගහà·à¶»à·“ ඇත" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "අවසන් නොකළ සංකේතà·à¶­à·Šà¶¸à¶š යොමුව" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "à·à·”න්â€à¶º දිග සංකේතà·à¶­à·Šà¶¸à¶š යොමුව" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "අංකයක් à¶¶à¶½à·à¶´à·œà¶»à·œà¶­à·Šà¶­à·” විය" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º සංකේතà·à¶­à·Šà¶¸à¶š යොමුව" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º à·€à·à¶©à·ƒà¶§à·„න් නම: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º à·€à·à¶©à¶šà¶»à¶± බහලුම: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() à¶¶à¶½à·à¶´à·œà¶»à·œà¶­à·Šà¶­à·” නොවු දà·à·‚යකි (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "à¶·à·à·à·€à·’තය:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "සහà·à¶º විකල්ප:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "සහà·à¶º විකල්ප දර්à·à¶±à¶º කරන්න" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "සියළු සහà·à¶º විකල්ප දර්à·à¶±à¶º කරන්න" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "යෙදුම් විකල්ප:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "%s නොදන්න෠විකල්පයකි" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "හිස් ගොනුවකි" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º සමූහ à¶±à·à¶¸à¶º: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º යතුරු නම: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "පරිවර්තන à¶´à·Šâ€à¶»à¶°à·à¶°à· තුළ à·ƒà·à·€à¶¯à·Šâ€à¶º බයිට් පිළිවෙළක්යේ" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "නොදන්න෠දà·à·‚ය" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "නොදන්න෠දà·à·‚ය" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "'%s' ගහලුම විවෘත කිරීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "'%s' ගහලුම විවෘත කිරීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "%d පේළියේ à¶­ දà·à·‚යකි: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "ඇතුළත් à¶šà·… නම තුළ ඇති '%s' à¶…à¶šà·Šâ€à·‚රය à·ƒà·à¶¯à·Šâ€à¶ºà·€à·š " + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "ඇතුළත් à¶šà·… නම තුළ ඇති '%s' à¶…à¶šà·Šâ€à·‚රය à·ƒà·à¶¯à·Šâ€à¶ºà·€à·š " + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "ඇතුළත් à¶šà·… නම තුළ ඇති '%s' à¶…à¶šà·Šâ€à·‚රය à·ƒà·à¶¯à·Šâ€à¶ºà·€à·š " + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "'%s' ගහලුම විවෘත කිරීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "'%s' ගහලුම විවෘත කිරීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "විනà·à· වු වස්තුවක්" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º යතුරු නම: %s" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º à¶°à·à¶»à¶š à¶±à·à¶¸à¶º" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "'%s' ගොනුව නිර්මà·à¶«à¶º දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "'%s' ගොනුව නිර්මà·à¶«à¶º දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "'%s' ගොනුව නිර්මà·à¶«à¶º දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "'%s' ගහලුම විවෘත කිරීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "'%s' සංකේතà·à¶­à·Šà¶¸à¶š පුරුක කියවිම අසමත් විය: %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "%d පේළියේ à¶­ දà·à·‚යකි: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "'%s' ගහලුම විවෘත කිරීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "%d පේළියේ à¶­ දà·à·‚යකි: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º යතුරු නම: %s" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "%s නොදන්න෠විකල්පයකි" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "'%s' ගොනුව නිර්මà·à¶«à¶º දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "'%s' ගොනුව නිර්මà·à¶«à¶º දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "'%s' ගොනුව නිර්මà·à¶«à¶º දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +#, fuzzy +msgid "Unknown error on connect" +msgstr "නොදන්න෠දà·à·‚ය" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "%d පේළියේ à¶­ දà·à·‚යකි: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "සංකේතà·à¶­à·Šà¶¸à¶š පුරුක සහà·à¶º දක්නන්නේ à¶±à·à¶­" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "à¶´à·Šâ€à¶»à¶¸à·à¶«à·€à¶­à·Š මතකයක් à¶±à·à¶­" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "à¶…à¶·à·Šâ€à¶ºà¶±à·Šà¶­à¶» දà·à·‚ය" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º à¶°à·à¶»à¶š à¶±à·à¶¸à¶º" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "පරිවර්තන à¶´à·Šâ€à¶»à¶°à·à¶°à· තුළ à·ƒà·à·€à¶¯à·Šâ€à¶º බයිට් පිළිවෙළක්යේ" + +#, fuzzy +#~ msgid "[FILE...]" +#~ msgstr "[OPTION...]" + +#~ msgid "Unfinished entity reference" +#~ msgstr "අවසන් නොකළ වස්තු යොමුව" + +#~ msgid "Unfinished character reference" +#~ msgstr "අවසන් නොකළ à¶…à¶šà·Šâ€à·‚à¶» යොමුව" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º UTF-8 සංකේතà·à¶‚à¶šà¶± පෙළ" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "à·ƒà·à·€à¶¯à·Šâ€à¶º UTF-8 සංකේතà·à¶‚à¶šà¶± පෙළ" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "'%s' URI à·„à·’ à¶°à·à¶»à¶š à¶±à·à¶¸à¶º à·ƒà·à·€à¶¯à·Šâ€à¶º වේ" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "'%s' URI à·„à·’ à¶°à·à¶»à¶š à¶±à·à¶¸à¶º à·ƒà·à·€à¶¯à·Šâ€à¶º වේ" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "'%s' ගොනුව කියවීම දà·à·‚ සහිතයි: %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "පරිවර්තනයේදි දà·à·‚යකි : %s" diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 0000000..8d6a1ce --- /dev/null +++ b/po/sk.po @@ -0,0 +1,6572 @@ +# Slovak translation for glib. +# Copyright (C) 2001, 2002, 2004, 2005, 2008, 2011-2013 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Stanislav Visnovsky , 2001, 2002. +# Stanislav Visnovsky , 2004. +# Marcel Telka , 2005, 2008. +# Peter Mráz , 2011, 2012. +# Ján Kyselica , 2013. +# DuÅ¡an Kazik , 2014-2021. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2021-07-19 15:52+0000\n" +"PO-Revision-Date: 2021-10-05 08:53+0200\n" +"Last-Translator: DuÅ¡an Kazik \n" +"Language-Team: Slovak \n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0\n" +"X-Generator: Gtranslator 40.0\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Voľby GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Zobrazí voľby GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Vstúpi do režimu služby GApplication (použije súbory zo služby zbernice D-" +"Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Preváži ID aplikácie" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Nahradí spustenú inÅ¡tanciu" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:572 +msgid "Print help" +msgstr "Zobrazí pomocníka" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[PRÃKAZ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Vypíše verziu" + +# MÄŒ: „Vypíše …“, podobne ako nasledujúce reÅ¥azce. +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:578 +msgid "Print version information and exit" +msgstr "Vypíše informácie o verzii a skonÄí" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Vypíše zoznam aplikácií" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Vypíše zoznam nainÅ¡talovaných aplikácií aktivovateľných zbernicou D-Bus " +"(podľa súborov typu .desktop)" + +# cmd desc +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Spustí aplikáciu" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Spustí aplikáciu (s voliteľnými súbormi na otvorenie)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "IDAPLIKÃCIE [SÚBOR…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktivuje akciu" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Vyvolá akciu na aplikácii" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "IDAPLIKÃCIE AKCIA [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Vypíše zoznam dostupných akcií" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Vypíše zoznam statických akcií pre aplikáciu (zo súboru typu .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "IDAPLIKÃCIE" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "PRÃKAZ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Príkaz, pre ktorý sa má vypísaÅ¥ podrobný pomocník" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"Identifikátor aplikácie vo formáte zbernice D-Bus (napr.: org.príklad.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "SÚBOR" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Voliteľné relatívne alebo absolútne názvy súborov, alebo URI na otvorenie" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "AKCIA" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Názov akcie na vyvolanie" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Voliteľný parameter pre vyvolanie akcie vo formáte GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:664 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Neznámy príkaz %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Použitie:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:699 +msgid "Arguments:\n" +msgstr "Parametre:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[PARAMETRE…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Príkazy:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Na získanie podrobnejÅ¡ieho pomocníka, použite „%s help PRÃKAZ“.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"príkaz %s vyžaduje, aby ihneÄ po ňom nasledoval identifikátor aplikácie\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "neplatný identifikátor aplikácie: „%s“\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"Príkaz „%s“ sa nedá použiÅ¥ so žiadnymi parametrami\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "nepodarilo sa pripojiÅ¥ k zbernici D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "chyba pri odosielaní správy %s aplikácii: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "názov akcie musí byÅ¥ zadaný po identifikátore aplikácie\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"neplatný názov akcie: „%s“\n" +"názvy akcií musia pozostávaÅ¥ iba zo znakov, Äíslic, „-“ a „.“\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "chyba pri spracovaní parametra akcie: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "akcie prijímajú maximálne jeden parameter\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "príkaz list-actions sa dá použiÅ¥ iba s identifikátorom aplikácie" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "nepodarilo sa nájsÅ¥ súbor desktop pre aplikáciu %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"nerozpoznaný príkaz: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "PríliÅ¡ vysoký poÄet hodnôt predaný do %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Presúvanie v základnom prúde nie je podporované" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream sa nedá skrátiÅ¥" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Prúd je už zatvorený" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Skrátenie nie je v základnom prúde podporované" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1872 gio/gdbusprivate.c:1416 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Operácia bola zruÅ¡ená" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Neplatný objekt, neinicializované" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Neúplná viacbajtová sekvencia na vstupe" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Nedostatok miesta v cieli" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "Neplatná sekvencia bajtov na vstupe prevodu" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Chyba poÄas prevodu: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1143 +msgid "Cancellable initialization not supported" +msgstr "ZruÅ¡iteľná inicializácia nie je podporovaná" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Prevod zo znakovej sady „%s“ do „%s“ nie je podporovaný" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Nepodarilo sa otvoriÅ¥ program na prevod z „%s“ do „%s“" + +#: gio/gcontenttype.c:454 +#, c-format +msgid "%s type" +msgstr "typ %s" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "Neznámy typ" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "typ súboru %s" + +#: gio/gcredentials.c:323 +msgid "GCredentials contains invalid data" +msgstr "GCredentials obsahuje neplatné údaje" + +#: gio/gcredentials.c:383 gio/gcredentials.c:667 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials nie je implementované v tomto operaÄnom systéme" + +#: gio/gcredentials.c:538 gio/gcredentials.c:556 +msgid "There is no GCredentials support for your platform" +msgstr "Neexistuje podpora GCredentials pre vaÅ¡u platformu" + +#: gio/gcredentials.c:607 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" +"GCredentials neobsahuje identifikátor procesu v tomto operaÄnom systéme" + +#: gio/gcredentials.c:661 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Zmena poverení nie je možná v tomto operaÄnom systéme" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "NeoÄakávane skorý koniec prúdu" + +#: gio/gdbusaddress.c:159 gio/gdbusaddress.c:233 gio/gdbusaddress.c:322 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nepodporovaný kÄ¾ÃºÄ â€ž%s“ v položke adresy „%s“" + +#: gio/gdbusaddress.c:172 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Nezmyselná kombinácia kľúÄ/hodnota v položke adresy „%s“" + +#: gio/gdbusaddress.c:181 +#, c-format +#| msgid "" +#| "Address “%s†is invalid (need exactly one of path, tmpdir or abstract " +#| "keys)" +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adresa „%s“ je neplatná (je potrebný práve jeden kÄ¾ÃºÄ path, dir, tmpdir " +"alebo abstract)" + +#: gio/gdbusaddress.c:248 gio/gdbusaddress.c:259 gio/gdbusaddress.c:274 +#: gio/gdbusaddress.c:337 gio/gdbusaddress.c:348 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Chyba v adrese „%s“ — atribút „%s“ má zlý formát" + +# first is transport name +#: gio/gdbusaddress.c:418 gio/gdbusaddress.c:682 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Neznámy alebo nepodporovaný transport typu „%s“ pre adresu „%s“" + +#: gio/gdbusaddress.c:462 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Prvok adresy „%s“ neobsahuje dvojbodku (:)" + +#: gio/gdbusaddress.c:471 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "" + +#: gio/gdbusaddress.c:492 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "Pár kľúÄ/hodnota %d, „%s“ v prvku adresy „%s“ neobsahuje znak rovnosti" + +#: gio/gdbusaddress.c:503 +#, c-format +#| msgid "" +#| "Key/Value pair %d, “%sâ€, in address element “%s†does not contain an " +#| "equal sign" +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Pár kľúÄ/hodnota %d, „%s“ v prvku adresy „%s“ nemôže obsahovaÅ¥ prázdny kľúÄ" + +#: gio/gdbusaddress.c:517 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Chyba kľúÄa alebo hodnoty s nahradenými Å¡peciálne uvedenými sekvenciami v " +"páre kľúÄ/hodnota %d, „%s“ v prvku adresy „%s“" + +#: gio/gdbusaddress.c:589 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Chyba v adrese „%s“ — transport typu unix vyžaduje nastavenie práve jedného " +"z kľúÄov „path“ alebo „abstract“" + +#: gio/gdbusaddress.c:625 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Chyba v adrese „%s“ — atribút hostiteľa chýba alebo má zlý formát" + +#: gio/gdbusaddress.c:639 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Chyba v adrese „%s“ — atribút portu chýba alebo má zlý formát" + +#: gio/gdbusaddress.c:653 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "Chyba v adrese „%s“ — atribút noncefile chýba alebo má zlý formát" + +#: gio/gdbusaddress.c:674 +msgid "Error auto-launching: " +msgstr "Chyba pri automatickom spustení: " + +#: gio/gdbusaddress.c:727 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Chyba pri otváraní nonce súboru „%s“: %s" + +#: gio/gdbusaddress.c:746 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Chyba pri Äítaní z nonce súboru „%s“: %s" + +#: gio/gdbusaddress.c:755 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Chyba pri Äítaní z nonce súboru „%s“, oÄakávaných 16 bajtov, získaných %d" + +#: gio/gdbusaddress.c:773 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Chyba pri zápise obsahu nounce súboru „%s“ do prúdu:" + +#: gio/gdbusaddress.c:988 +msgid "The given address is empty" +msgstr "Daná adresa je prázdna" + +# PM: tu si nie som istý +# MÄŒ: Komentár v kóde: /* Don't run binaries as root if we're setuid. */ +# MÄŒ: v tomto prípade „spawn“ znamená: Spustí a posiela dáta, cez stdin a oÄakáva dáta cez stdout, takže by som skôr dal spustiÅ¥. +#: gio/gdbusaddress.c:1101 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Zbernica správ sa nedá spustiÅ¥ pri setuid" + +# MÄŒ: v tomto prípade „spawn“ znamená: Spustí a posiela dáta, cez stdin a oÄakáva dáta cez stdout, takže by som skôr dal spustiÅ¥. +#: gio/gdbusaddress.c:1108 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Zbernica správ sa nedá spustiÅ¥ bez machine-id: " + +#: gio/gdbusaddress.c:1115 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Zbernica D-Bus sa nedá spustiÅ¥ automaticky bez X11 $DISPLAY" + +# MÄŒ: v tomto prípade „spawn“ znamená: Spustí a posiela dáta, cez stdin a oÄakáva dáta cez stdout, takže by som skôr dal spustiÅ¥. +#: gio/gdbusaddress.c:1157 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Chyba pri spúšťaní príkazového riadka „%s“: " + +# funkcia na urÄenie adresy relaÄnej zbernice +#: gio/gdbusaddress.c:1226 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Nedá sa urÄiÅ¥ adresa relaÄnej zbernice (nie je implementovaná pre tento " +"operaÄný systém)" + +#: gio/gdbusaddress.c:1397 gio/gdbusconnection.c:7261 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Nedá sa urÄiÅ¥ adresa zbernice z premennej prostredia DBUS_STARTER_BUS_TYPE — " +"neznáma hodnota „%s“" + +#: gio/gdbusaddress.c:1406 gio/gdbusconnection.c:7270 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Nedá sa urÄiÅ¥ adresa zbernice, pretože premenná prostredia " +"DBUS_STARTER_BUS_TYPE nie je nastavená" + +#: gio/gdbusaddress.c:1416 +#, c-format +msgid "Unknown bus type %d" +msgstr "Neznámy typ zbernice %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "NeÄakaný nedostatok obsahu pri pokuse ÄítaÅ¥ riadok" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "NeÄakaný nedostatok obsahu pri pokuse (bezpeÄne) ÄítaÅ¥ riadok" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"VyÄerpané vÅ¡etky dostupné mechanizmy overenia totožnosti (pokusy: %s) " +"(dostupné: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Identifikátory používateľa musia byÅ¥ rovnaké pre partnera a server" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "ZruÅ¡ené cez GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:298 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Chyba pri získavaní informácií pre adresár „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:313 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Oprávnenia k adresáru „%s“ sú zle formátované. OÄakávaný režim 0700, získaný " +"0%o" + +#: gio/gdbusauthmechanismsha1.c:346 gio/gdbusauthmechanismsha1.c:357 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Chyba pri vytváraní adresára %s: %s" + +#: gio/gdbusauthmechanismsha1.c:359 gio/gfile.c:1062 gio/gfile.c:1300 +#: gio/gfile.c:1438 gio/gfile.c:1676 gio/gfile.c:1731 gio/gfile.c:1789 +#: gio/gfile.c:1873 gio/gfile.c:1930 gio/gfile.c:1994 gio/gfile.c:2049 +#: gio/gfile.c:3754 gio/gfile.c:3809 gio/gfile.c:4102 gio/gfile.c:4572 +#: gio/gfile.c:4983 gio/gfile.c:5068 gio/gfile.c:5158 gio/gfile.c:5255 +#: gio/gfile.c:5342 gio/gfile.c:5443 gio/gfile.c:8153 gio/gfile.c:8243 +#: gio/gfile.c:8327 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Nepodporovaná operácia" + +#: gio/gdbusauthmechanismsha1.c:402 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Chyba pri otváraní zväzku kľúÄov „%s“ na Äítanie: " + +#: gio/gdbusauthmechanismsha1.c:425 gio/gdbusauthmechanismsha1.c:747 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Riadok Ä. %d zväzku kľúÄov na „%s“ s obsahom „%s“ je zle formátovaný" + +# PK: token nie je nejaky znak? viacX +# PM: token je napríklad "%s" ide o znaky ktoré môžu byt nahradené nejakým textom napr %u - meno používateľa +# PK: token by mal byt string +#: gio/gdbusauthmechanismsha1.c:439 gio/gdbusauthmechanismsha1.c:761 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Prvý token riadka Ä. %d zväzku kľúÄov na „%s“ s obsahom „%s“ je zle " +"formátovaný" + +#: gio/gdbusauthmechanismsha1.c:453 gio/gdbusauthmechanismsha1.c:775 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Druhý token riadka Ä. %d zväzku kľúÄov na „%s“ s obsahom „%s“ je zle " +"formátovaný" + +#: gio/gdbusauthmechanismsha1.c:477 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "NenaÅ¡lo sa cookie s identifikátorom %d vo zväzku kľúÄov na „%s“" + +#: gio/gdbusauthmechanismsha1.c:523 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Chyba pri vytváraní súboru uzamknutia „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:587 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Chyba pri odstraňovaní starého súboru uzamknutia „%s“: %s" + +# PM: Je to súbor urÄený na vymazanie ale vymaže sa až vtedy, keÄ ho zatvorí posledný, kto ho má otvorený +#: gio/gdbusauthmechanismsha1.c:626 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Chyba pri zatváraní (vymazávaného) súboru uzamknutia „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:637 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Chyba pri mazaní súboru uzamknutia „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Chyba pri otváraní zväzku kľúÄov „%s“ na zápis: " + +#: gio/gdbusauthmechanismsha1.c:908 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Okrem toho zlyhalo aj uvoľnenie zámky pre „%s“: %s) " + +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2417 +msgid "The connection is closed" +msgstr "Pripojenie je ukonÄené" + +#: gio/gdbusconnection.c:1902 +msgid "Timeout was reached" +msgstr "VyprÅ¡al Äasový limit" + +#: gio/gdbusconnection.c:2540 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Pri vytváraní klientského pripojenia boli nájdené nepodporované príznaky" + +#: gio/gdbusconnection.c:4189 gio/gdbusconnection.c:4536 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Rozhranie „org.freedesktop.DBus.Properties“ nie je v objekte na ceste %s" + +#: gio/gdbusconnection.c:4331 +#, c-format +msgid "No such property “%sâ€" +msgstr "Neexistuje vlastnosÅ¥ „%s“" + +#: gio/gdbusconnection.c:4343 +#, c-format +msgid "Property “%s†is not readable" +msgstr "VlastnosÅ¥ „%s“ nie je Äitateľná" + +#: gio/gdbusconnection.c:4354 +#, c-format +msgid "Property “%s†is not writable" +msgstr "VlastnosÅ¥ „%s“ nie je zapisovateľná" + +#: gio/gdbusconnection.c:4374 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Chyba pri nastavovaní vlastnosti „%s“: Bol oÄakávaný typ „%s“, no získaný " +"bol „%s“" + +#: gio/gdbusconnection.c:4479 gio/gdbusconnection.c:4687 +#: gio/gdbusconnection.c:6689 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Neexistuje rozhranie „%s“" + +#: gio/gdbusconnection.c:4905 gio/gdbusconnection.c:7201 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Rozhranie „%s“ nie je v objekte na ceste %s" + +#: gio/gdbusconnection.c:5003 +#, c-format +msgid "No such method “%sâ€" +msgstr "Neexistujúca metóda „%s“" + +#: gio/gdbusconnection.c:5034 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Typ správy „%s“ nezodpovedá oÄakávanému typu „%s“" + +#: gio/gdbusconnection.c:5237 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Pre rozhranie %s je už exportovaný objekt na %s" + +#: gio/gdbusconnection.c:5463 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Nepodarilo sa získaÅ¥ vlastnosÅ¥ %s.%s" + +#: gio/gdbusconnection.c:5519 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Nepodarilo sa nastaviÅ¥ vlastnosÅ¥ %s.%s" + +#: gio/gdbusconnection.c:5698 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metóda „%s“ vrátila typ „%s“, no oÄakávaný bol „%s“" + +# MÄŒ: mám k tomuto preklady výhrady, ale keÄ to tak chcete, môže byÅ¥. KeÄ signatúra nevyhovuje, tak skôr znaÄka. Ak sa rozhodnete upraviÅ¥, tak pri vÅ¡etkých výskytoch. +# PK: http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures +# PK: mozno oznacenie +#: gio/gdbusconnection.c:6800 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metóda „%s“ z rozhrania „%s“ s oznaÄením „%s“ neexistuje" + +#: gio/gdbusconnection.c:6921 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Podstrom je už exportovaný do %s" + +#: gio/gdbusconnection.c:7209 +#, c-format +#| msgid "Key file does not have group “%sâ€" +msgid "Object does not exist at path “%sâ€" +msgstr "Objekt neexistuje na ceste „%s“" + +#: gio/gdbusmessage.c:1266 +msgid "type is INVALID" +msgstr "typ je INVALID" + +#: gio/gdbusmessage.c:1277 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Správa METHOD_CALL: chýba pole hlaviÄky PATH alebo MEMBER" + +#: gio/gdbusmessage.c:1288 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Správa METHOD_RETURN: chýba pole hlaviÄky REPLY_SERIAL" + +#: gio/gdbusmessage.c:1300 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "Správa ERROR: chýba pole hlaviÄky REPLY_SERIAL alebo ERROR_NAME" + +#: gio/gdbusmessage.c:1313 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Správa SIGNAL: chýba pole hlaviÄky PATH, INTERFACE alebo MEMBER" + +#: gio/gdbusmessage.c:1321 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Správa SIGNAL: pole hlaviÄky PATH používa vyhradenú hodnotu /org/freedesktop/" +"DBus/Local" + +#: gio/gdbusmessage.c:1329 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Správa SIGNAL: pole hlaviÄky INTERFACE používa vyhradenú hodnotu org." +"freedesktop.DBus.Local" + +# MÄŒ: Asi bude tre daÅ¥ rozdeliÅ¥ reÅ¥azec, nenapadá mi, ako by sa druhá ÄasÅ¥ dala preložiÅ¥ neutrálne. Jedna vec je istá, pri druhom reÅ¥azci môže byÅ¥ ozískaných“ len nula, keÄže iba to je menej ako jedna. Prípadne vÅ¡ade použiÅ¥ „získaných“, malo by to narobiÅ¥ najmenej problémov. +# JK: https://bugzilla.gnome.org/show_bug.cgi?id=695234 +#: gio/gdbusmessage.c:1377 gio/gdbusmessage.c:1437 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Potrebných %lu bajtov na Äítanie, no získaných iba %lu" +msgstr[1] "Potrebný %lu bajt na Äítanie, no získaných %lu" +msgstr[2] "Potrebné %lu bajty na Äítanie, no získaných iba %lu" + +# *https://bugzilla.gnome.org/show_bug.cgi?id=658913 +# PM: tu je to hodnota znaku nie smerníka +#: gio/gdbusmessage.c:1391 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "OÄakávaný znak NUL za reÅ¥azcom „%s“, no nájdený bajt %d" + +#: gio/gdbusmessage.c:1410 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"OÄakávaný platný UTF-8 reÅ¥azec, no nájdené neplatné bajty na pozícii %d " +"(dĺžka reÅ¥azca je %d). Platný UTF-8 reÅ¥azec do toho miesta bol „%s“" + +#: gio/gdbusmessage.c:1474 gio/gdbusmessage.c:1722 gio/gdbusmessage.c:1911 +msgid "Value nested too deeply" +msgstr "" + +#: gio/gdbusmessage.c:1620 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "" +"Analyzovaná hodnota „%s“ nie je platnou cestou k objektu zbernice D-Bus" + +#: gio/gdbusmessage.c:1642 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Analyzovaná hodnota „%s“ nie je platným oznaÄením zbernice D-Bus" + +#: gio/gdbusmessage.c:1689 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Zistené pole s dĺžkou %u bajtov. Maximálna dĺžka je 2<<26 bajtov (64 MiB)" +msgstr[1] "" +"Zistené pole s dĺžkou %u bajt. Maximálna dĺžka je 2<<26 bajtov (64 MiB)" +msgstr[2] "" +"Zistené pole s dĺžkou %u bajty. Maximálna dĺžka je 2<<26 bajtov (64 MiB)" + +#: gio/gdbusmessage.c:1709 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Zistené pole typu „a%c“, ktoré by malo maÅ¥ dĺžku v násobkoch %u bajtov, ale " +"reálna dĺžka je %u bajtov" + +#: gio/gdbusmessage.c:1895 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"Analyzovaná hodnota „%s“ pre variant nie je platným oznaÄením zbernice D-Bus" + +#: gio/gdbusmessage.c:1936 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Chyba pri deserializovaní GVariantu pomocou reÅ¥azca typu „%s“ z prenosového " +"formátu zbernice D-Bus" + +# tu musia byt taketo uvodzovky, kedze je to tak aj v C alebo Java +#: gio/gdbusmessage.c:2121 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Neplatná hodnota poradia bytov. OÄakávané 0x6c ('l') alebo 0x42 ('B'), no " +"nájdená hodnota 0x%02x" + +#  protocol version +#: gio/gdbusmessage.c:2134 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Neplatná hlavná verzia protokolu. OÄakávaná 1, no nájdená %d" + +#: gio/gdbusmessage.c:2188 gio/gdbusmessage.c:2784 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2200 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Nájdená hlaviÄka oznaÄenia s oznaÄením „%s“, no nájdené telo správy je " +"prázdne" + +#: gio/gdbusmessage.c:2215 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Analyzovaná hodnota „%s“ nie je platným oznaÄením zbernice D-Bus (pre telo)" + +#: gio/gdbusmessage.c:2247 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"V správe nie je žiadna hlaviÄka oznaÄenia, no telo správy má %u bajtov" +msgstr[1] "" +"V správe nie je žiadna hlaviÄka oznaÄenia, no telo správy má %u bajt" +msgstr[2] "" +"V správe nie je žiadna hlaviÄka oznaÄenia, no telo správy má %u bajty" + +#: gio/gdbusmessage.c:2257 +msgid "Cannot deserialize message: " +msgstr "Nedá sa deserializovaÅ¥ správa: " + +#: gio/gdbusmessage.c:2601 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Chyba pri serializovaní Gvariant pomocou reÅ¥azca typu „%s“ z prenosového " +"formátu zbernice D-Bus" + +#: gio/gdbusmessage.c:2738 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"PoÄet popisovaÄov súboru v správe (%d) sa odliÅ¡uje od poÄtu v poli hlaviÄka " +"(%d)" + +#: gio/gdbusmessage.c:2746 +msgid "Cannot serialize message: " +msgstr "Nedá sa serializovaÅ¥ správa: " + +#: gio/gdbusmessage.c:2799 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Telo správy má oznaÄenie „%s“, no neexistuje žiadna hlaviÄka oznaÄenia" + +#: gio/gdbusmessage.c:2809 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Telo správy má oznaÄenie typu „%s“, no oznaÄenie v poli hlaviÄky je „%s“" + +#: gio/gdbusmessage.c:2825 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Telo správy je prázdne, no oznaÄenie v poli hlaviÄky je „(%s)“" + +#: gio/gdbusmessage.c:3380 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Chyba pri návrate s telom typu „%s“" + +#: gio/gdbusmessage.c:3388 +msgid "Error return with empty body" +msgstr "Chyba pri návrate s prázdnym telom" + +# PM: podľa mňa ked ide o zadanie treba na konci stlaÄiÅ¥ enter, nie som si istý Äi je to tento prípad +#: gio/gdbusprivate.c:2246 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Toto okno zatvoríte zadaním ľubovolného znaku)\n" + +#: gio/gdbusprivate.c:2420 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Relácia dbus nebeží a automatické spustenie zlyhalo" + +#: gio/gdbusprivate.c:2443 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Nepodarilo sa získaÅ¥ hardvérový profil: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2494 +#, c-format +#| msgid "Unable to trash file %s: %s" +msgid "Unable to load %s or %s: " +msgstr "Nie je možné naÄítaÅ¥ %s alebo %s:" + +#: gio/gdbusproxy.c:1569 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Chyba pri volaní StartServiceByName pre %s: " + +#: gio/gdbusproxy.c:1592 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "NeoÄakávaná odpoveÄ %d z metódy StartServiceByName(„%s“)" + +#: gio/gdbusproxy.c:2699 gio/gdbusproxy.c:2834 +#, fuzzy, c-format +#| msgid "" +#| "Cannot invoke method; proxy is for a well-known name without an owner and " +#| "proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Nedá sa vyvolaÅ¥ metóda; proxy je pre dobre známy názov bez vlastníka a proxy " +"bol vytvorený s príznakom G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstraktný menný priestor nie je podporovaný" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Pri vytváraní servera sa nedá zadaÅ¥ nonce súbor" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Chyba pri zápise do nonce súboru na „%s“: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "ReÅ¥azec „%s“ nie je platný D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Nedá sa poÄúvaÅ¥ na nepodporovanom transporte „%s“" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Príkazy:\n" +" help Zobrazí tieto informácie\n" +" introspect Vnútorne preskúma vzdialený objekt\n" +" monitor Sleduje vzdialený objekt\n" +" call Vyvolá metódu na vzdialenom objekte\n" +" emit VyÅ¡le signál\n" +" wait ÄŒaká na zjavenie názvu zbernice\n" +"\n" +"\n" +"\n" +"Pomocníka pre každý z príkazov získate zadaním „%s PRÃKAZ --help“.\n" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1236 +#: gio/gdbus-tool.c:1724 +#, c-format +msgid "Error: %s\n" +msgstr "Chyba: %s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1740 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Chyba pri analýze XML vútorného preskúmania: %s\n" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Chyba: %s nie je platný názov\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1060 +#: gio/gdbus-tool.c:1890 gio/gdbus-tool.c:2130 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Chyba: %s nie platná cesta objektu\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "PripojiÅ¥ k systémovej zbernici" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "PripojiÅ¥ k relaÄnej zbernici" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "PripojiÅ¥ k danej adrese zbernice D-Bus" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "Voľby koncového bodu pripojenia:" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "Voľby urÄujúce koncový bod pripojenia" + +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "NeurÄený žiadny koncový bod pripojenia" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "UrÄených viacero koncových bodov pripojenia" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Upozornenie: Podľa údajov vnútorného preskúmania rozhranie „%s“ neexistuje\n" + +#: gio/gdbus-tool.c:531 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Upozornenie: Podľa údajov vnútorného preskúmania metóda „%s“ neexistuje na " +"rozhraní „%s“\n" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "Voliteľný cieľ pre signál (jedineÄný názov)" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "Cesta objektu, ktorému vyslaÅ¥ signál" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "Názov signálu a rozhrania" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "VyslaÅ¥ signál." + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:997 gio/gdbus-tool.c:1827 +#: gio/gdbus-tool.c:2059 gio/gdbus-tool.c:2279 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Chyba pri pripájaní: %s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Chyba: %s nie je platný jedineÄný názov zbernice.\n" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1040 gio/gdbus-tool.c:1870 +msgid "Error: Object path is not specified\n" +msgstr "Chyba: Cesta objektu nie je urÄená\n" + +#: gio/gdbus-tool.c:765 +msgid "Error: Signal name is not specified\n" +msgstr "Chyba: Názov signálu nie je urÄený\n" + +#: gio/gdbus-tool.c:779 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Chyba: Názov signálu „%s“ nie je platný\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Chyba: %s nie je platný názov rozhrania\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Chyba: %s nie je platný názov Älena objektu\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1172 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Chyba pri spracovaní parametra %d: %s\n" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Chyba pri vyprázdnení pripojenia: %s\n" + +#: gio/gdbus-tool.c:893 +msgid "Destination name to invoke method on" +msgstr "Názov cieľa, na ktorom sa má zavolaÅ¥ metóda" + +# PK: Nazov ciela, na ktorom zavolat metodu +#: gio/gdbus-tool.c:894 +msgid "Object path to invoke method on" +msgstr "Cesta objektu na zavolanie metódy" + +#: gio/gdbus-tool.c:895 +msgid "Method and interface name" +msgstr "Názov metódy a rozhrania" + +#: gio/gdbus-tool.c:896 +msgid "Timeout in seconds" +msgstr "ÄŒasový limit v sekundách" + +#: gio/gdbus-tool.c:942 +msgid "Invoke a method on a remote object." +msgstr "ZavolaÅ¥ metódu na vzdialenom objekte." + +#: gio/gdbus-tool.c:1014 gio/gdbus-tool.c:1844 gio/gdbus-tool.c:2084 +msgid "Error: Destination is not specified\n" +msgstr "Chyba: Cieľ nie je urÄený\n" + +#: gio/gdbus-tool.c:1025 gio/gdbus-tool.c:1861 gio/gdbus-tool.c:2095 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Chyba: %s nie je platný názov zbernice\n" + +#: gio/gdbus-tool.c:1075 +msgid "Error: Method name is not specified\n" +msgstr "Chyba: Názov metódy nie je urÄený\n" + +#: gio/gdbus-tool.c:1086 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Chyba: Názov metódy „%s“ nie je platný\n" + +#: gio/gdbus-tool.c:1164 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Chyba pri spracovaní parametra %d typu „%s“: %s\n" + +# PÅ : file handle (win32) je ekvivalent file descriptor - dovolil som si to preložiÅ¥ rovnako. KeÄže používané manipulátor, alebo rukoväť sú oba zlé preklady (obsluha je handler)... A dokonca aj v slovenskom preklade Správcu úloh vo win je použitý popisovaÄ. +#: gio/gdbus-tool.c:1190 +#, fuzzy, c-format +#| msgid "Error reading from handle: %s" +msgid "Error adding handle %d: %s\n" +msgstr "Chyba pri Äítaní z popisovaÄa: %s" + +#: gio/gdbus-tool.c:1686 +msgid "Destination name to introspect" +msgstr "Názov cieľa na vnútorné preskúmanie" + +#: gio/gdbus-tool.c:1687 +msgid "Object path to introspect" +msgstr "Cesta objektu na vnútorné preskúmanie" + +#: gio/gdbus-tool.c:1688 +msgid "Print XML" +msgstr "VypísaÅ¥ XML" + +#: gio/gdbus-tool.c:1689 +msgid "Introspect children" +msgstr "Vnútorne preskúmaÅ¥ potomka" + +#: gio/gdbus-tool.c:1690 +msgid "Only print properties" +msgstr "Iba vypísaÅ¥ vlastnosti" + +#: gio/gdbus-tool.c:1779 +msgid "Introspect a remote object." +msgstr "Vnútorne preskúmaÅ¥ vzdialený objekt." + +#: gio/gdbus-tool.c:1985 +msgid "Destination name to monitor" +msgstr "Názov cieľa na sledovanie" + +#: gio/gdbus-tool.c:1986 +msgid "Object path to monitor" +msgstr "Cesta objektu na sledovanie" + +#: gio/gdbus-tool.c:2011 +msgid "Monitor a remote object." +msgstr "SledovaÅ¥ vzdialený objekt." + +#: gio/gdbus-tool.c:2069 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" + +#: gio/gdbus-tool.c:2193 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Služba, ktorá sa má aktivovaÅ¥ pred Äakaním na inú (so známym menom)" + +#: gio/gdbus-tool.c:2196 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"ÄŒasový limit (v sekundách) pre Äakanie, po uplynutí ktorého sa ukonÄí " +"chybou; 0 bez limitu (predvolené)" + +#: gio/gdbus-tool.c:2244 +msgid "[OPTION…] BUS-NAME" +msgstr "[VOĽBA…] NÃZOV_ZBERNICE" + +#: gio/gdbus-tool.c:2245 +msgid "Wait for a bus name to appear." +msgstr "ÄŒakaÅ¥ na zjavenie názvu zbernice." + +#: gio/gdbus-tool.c:2321 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Chyba: Musí byÅ¥ urÄená služba, ktorá sa má aktivovaÅ¥.\n" + +#: gio/gdbus-tool.c:2326 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Chyba: Musí byÅ¥ urÄená služba, na ktorú sa má ÄakaÅ¥.\n" + +#: gio/gdbus-tool.c:2331 +msgid "Error: Too many arguments.\n" +msgstr "Chyba: PríliÅ¡ veľa parametrov.\n" + +#: gio/gdbus-tool.c:2339 gio/gdbus-tool.c:2346 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Chyba: %s nie je platný známy názov zbernice.\n" + +#: gio/gdesktopappinfo.c:2106 gio/gdesktopappinfo.c:4932 +msgid "Unnamed" +msgstr "Bez názvu" + +#: gio/gdesktopappinfo.c:2516 +msgid "Desktop file didn’t specify Exec field" +msgstr "V súbore desktop nie je urÄené pole Exec" + +#: gio/gdesktopappinfo.c:2801 +msgid "Unable to find terminal required for application" +msgstr "Nepodarilo sa nájsÅ¥ terminál vyžadovaný pre aplikáciu" + +#: gio/gdesktopappinfo.c:3452 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Nedá sa vytvoriÅ¥ používateľský konfiguraÄný prieÄinok aplikácie %s: %s" + +#: gio/gdesktopappinfo.c:3456 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Nedá sa vytvoriÅ¥ používateľský konfiguraÄný prieÄinok MIME %s: %s" + +#: gio/gdesktopappinfo.c:3698 gio/gdesktopappinfo.c:3722 +msgid "Application information lacks an identifier" +msgstr "V informáciách o aplikácii chýba identifikátor" + +#: gio/gdesktopappinfo.c:3958 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Nedá sa vytvoriÅ¥ používateľský desktop súbor %s" + +#: gio/gdesktopappinfo.c:4094 +#, c-format +msgid "Custom definition for %s" +msgstr "Vlastná definícia pre %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "mechanika neimplementuje vysúvanie" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "" +"mechanika neimplementuje eject (vysunutie) ani eject_with_operation " +"(vysunutie s operáciou)" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "mechanika neimplementuje dotazovanie na vložené médium" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "mechanika neimplementuje spustenie" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "mechanika neimplementuje zastavenie" + +#: gio/gdtlsconnection.c:1153 gio/gtlsconnection.c:920 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Podpora TLS nie je dostupná" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Podpora DTLS nie je dostupná" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Nedá sa spracovaÅ¥ kódovanie GEmblem verzie %d" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Chybný poÄet tokenov (%d) v kódovaní GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Nedá sa spracovaÅ¥ kódovanie GEmblemedIcon verzie %d" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Chybný poÄet tokenov (%d) v kódovaní GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "OÄakávaný GEmblem pre GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1561 +msgid "Containing mount does not exist" +msgstr "Obklopujúce pripojenie neexistuje" + +#: gio/gfile.c:2608 gio/glocalfile.c:2477 +msgid "Can’t copy over directory" +msgstr "Nedá sa prepísaÅ¥ adresár pri kopírovaní" + +#: gio/gfile.c:2668 +msgid "Can’t copy directory over directory" +msgstr "Nedá sa prepísaÅ¥ adresár adresárom pri kopírovaní" + +#: gio/gfile.c:2676 +msgid "Target file exists" +msgstr "Cieľový súbor existuje" + +#: gio/gfile.c:2695 +msgid "Can’t recursively copy directory" +msgstr "Adresár sa nedá kopírovaÅ¥ rekurzívne" + +#: gio/gfile.c:2996 +msgid "Splice not supported" +msgstr "Operácia zreÅ¥azovania vstupu s výstupom nie je podporovaná" + +# http://developer.gnome.org/gio/2.32/GOutputStream.html#g-output-stream-splice +#: gio/gfile.c:3000 +#, c-format +msgid "Error splicing file: %s" +msgstr "Chyba pri zreÅ¥azovaní súboru: %s" + +#: gio/gfile.c:3152 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopírovanie (odkaz/klon) medzi pripojeniami nie je podporované" + +#: gio/gfile.c:3156 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" +"Kopírovanie (odkaz/klon) medzi pripojeniami nie je podporované alebo je " +"neplatné" + +#: gio/gfile.c:3161 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" +"Kopírovanie (odkaz/klon) medzi pripojeniami nie je podporované alebo " +"nefunguje" + +#: gio/gfile.c:3226 +msgid "Can’t copy special file" +msgstr "Å peciálny súbor sa nedá kopírovaÅ¥" + +#: gio/gfile.c:4035 +msgid "Invalid symlink value given" +msgstr "Neplatný daný symbolický odkaz" + +#: gio/gfile.c:4045 glib/gfileutils.c:2354 +msgid "Symbolic links not supported" +msgstr "Symbolické odkazy nie sú podporované" + +#: gio/gfile.c:4213 +msgid "Trash not supported" +msgstr "Zahodenie do KoÅ¡a nie je podporované" + +# literal character +#: gio/gfile.c:4325 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Názvy súborov nemôžu obsahovaÅ¥ „%c“" + +#: gio/gfile.c:6806 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "zväzok neimplementuje pripojenie" + +#: gio/gfile.c:6920 gio/gfile.c:6968 +msgid "No application is registered as handling this file" +msgstr "Žiadna aplikácia nie je zaregistrovaná na spracovanie tohto súboru" + +# PK: vymenovavac hodnot, suborov +#  PM: som za zachovanie aktuálneho preklad, iterátor tiež nejako zvlášť neprekladáme +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerátor je uzatvorený" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Enumerátor súborov má nevykonanú operáciu" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Enumerátor súborov je už uzatvorený" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Nedá sa spracovaÅ¥ kódovanie GFileIcon verzie %d" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Zle formátované vstupné údaje pre GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Prúd nepodporuje query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Presúvanie v prúde nie je podporované" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Skrátenie vo vstupnom prúde nie je podporované" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Skrátenie nie je v prúde podporované" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:596 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Neplatný názov hostiteľa" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Nesprávna odpoveÄ sprostredkovateľa HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Pripojenie k sprostredkovateľovi HTTP nie je umožnené" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Zlyhalo overenie totožnosti sprostredkovateľa HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Vyžaduje sa overenie totožnosti sprostredkovateľa HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Pripojenie k sprostredkovateľovi HTTP zlyhalo: %i" + +#: gio/ghttpproxy.c:266 +#, fuzzy +#| msgid "HTTP proxy connection failed: %i" +msgid "HTTP proxy response too big" +msgstr "Pripojenie k sprostredkovateľovi HTTP zlyhalo: %i" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Server sprostredkovateľa HTTP neoÄakávane preruÅ¡il pripojenie." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nesprávny poÄet tokenov (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Názov triedy %s nemá typ" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Typ %s neimplementuje rozhranie GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Typ %s nemá triedu" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Zlé Äíslo verzie: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Typ %s neimplementuje from_tokens() na rozhraní GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Nedá sa spracovaÅ¥ poskytnutá verzia kódovania ikon" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nebola zadaná žiadna adresa" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Dĺžka %u je pre adresu príliÅ¡ krátka" + +# PM: neviem Äi je to dosÅ¥ zrozumitelne +# MÄŒ: „Adresa má nastavené bity aj mimo prefixu“ prefix by som neprekladal, pri slove predpona by som sa asi stratil. +# PM: Predpona adresy sa mi zdá úplne zrozumiteľná, skôr som myslel Äi nepoužiÅ¥ preklad ako napr. bity adresy presahujú sa hranicu stanovenú pre predponu adresy +# MÄŒ: Skôr tento druhý reÅ¥azec, „dĺžka predpony“ by bola osobne pre mňa Å¡ialene nepochopiteľná, keby som nemal k dispozícii anglický originál. +# PK: to necham slovensky, lebo pre mna to je spanielska dedina +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adresa má bity nastavené za dĺžkou predpony" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Nepodarilo sa analyzovaÅ¥ „%s“ ako masku adresy IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "Nie je dostatok miesta pre adresu soketu" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nepodporovaná adresa soketu" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Vstupný prúd neimplementuje Äítanie" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Prúd má nevykonanú operáciu" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Skopíruje so súborom" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Ponechá so súborom pri presunutí" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "Voľba „version“ neprijíma žiadne parametre" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Použitie:" + +# MÄŒ: „Vypíše …“, podobne ako nasledujúce reÅ¥azce. +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Vypíše informácie o verzii a skonÄí." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Príkazy:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Spojí súbory na Å¡tandardný výstup" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Skopíruje jeden alebo viac súborov" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Zobrazí informácie o umiestneniach" + +#: gio/gio-tool.c:232 +#, fuzzy +#| msgid "List static actions for an application (from .desktop file)" +msgid "Launch an application from a desktop file" +msgstr "Vypíše zoznam statických akcií pre aplikáciu (zo súboru typu .desktop)" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Vypíše obsah umiestnení" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Získa alebo nastaví obslužný program pre typ MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Vytvorí adresáre" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Sleduje zmeny súborov a adresárov" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Pripojí alebo odpojí umiestnenia" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Presunie jeden alebo viac súborov" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Otvorí súbory predvolenou aplikáciou" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Premenuje súbor" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Odstráni jeden alebo viac súborov" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Číta z predvoleného vstupu a ukladá" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Nastaví atribút súboru" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Presunie súbory alebo adresáre do KoÅ¡a" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Vypíše obsah umiestnení v stromovom zobrazení" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Na získanie podrobnejÅ¡ieho pomocníka, použite %s.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Chyba pri zápise na Å¡tandardný výstup" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "UMIESTNENIE" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Spojí súbory a vypíše na Å¡tandardný výstup." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat pracuje podobne ako tradiÄná utilita cat, iba že \n" +"s použitím umiestnení GIO namiesto lokálnych súborov: napríklad môžete " +"použiÅ¥ nieÄo ako \n" +"smb://server/resource/file.txt ako umiestnenie." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Neposkytnuté žiadne umiestnenia" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Bez cieľového adresára" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Zobrazí priebeh" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Pýta sa pred prepísaním" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Zachová vÅ¡etky atribúty" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Zálohuje existujúce cieľové súbory" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nikdy nenasleduje symbolické odkazy" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Prenesených %s z %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ZDROJ" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "CIEĽ" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Skopíruje jeden alebo viaceré súbory zo ZDROJA do CIEĽA." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy pracuje podobne ako tradiÄná utilita cp, iba že \n" +"s použitím umiestnení GIO namiesto lokálnych súborov: napríklad môžete " +"použiÅ¥ nieÄo ako \n" +"smb://server/resource/file.txt ako umiestnenie." + +# %s je cesta +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Cieľ %s nie je adresárom" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: prepísaÅ¥ „%s“? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Vypíše zapisovateľné atribúty" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Získa informácie o súborovom systéme" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Atribúty, ktoré sa majú získaÅ¥" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBÚTY" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Nenasleduje symbolické odkazy" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atribúty:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "názov na zobrazenie: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "názov na úpravu: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "názov: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "typ: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "veľkosÅ¥: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "skrytý\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "miestna cesta: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Nastaviteľné atribúty:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Menné priestory zapisovateľného atribútu:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Zobrazí informácie o umiestneniach." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info pracuje podobne ako tradiÄná utilita ls, iba že \n" +"s použitím umiestnení GIO namiesto lokálnych súborov: napríklad môžete " +"použiÅ¥ nieÄo ako \n" +"smb://server/resource/file.txt ako umiestnenie. Vlastnosti súborov môžu byÅ¥\n" +"zadané pomocou názvov GIO, napr. standard::icon, alebo použitím\n" +"menného priestoru, napr. unix, alebo zadaním '*', Äo zastupuje vÅ¡etky " +"vlastnosti" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" + +#: gio/gio-tool-launch.c:77 +#, fuzzy +#| msgid "No files given" +msgid "No desktop file given" +msgstr "Neposkytnuté žiadne súbory" + +#: gio/gio-tool-launch.c:85 +#, fuzzy +#| msgid "There is no GCredentials support for your platform" +msgid "The launch command is not currently supported on this platform" +msgstr "Neexistuje podpora GCredentials pre vaÅ¡u platformu" + +#: gio/gio-tool-launch.c:98 +#, fuzzy, c-format +#| msgid "Unable to trash file %s: %s" +msgid "Unable to load ‘%s‘: %s" +msgstr "Nepodarilo sa zahodiÅ¥ súbor %s do KoÅ¡a: %s" + +#: gio/gio-tool-launch.c:107 +#, fuzzy, c-format +#| msgid "Failed to load info for handler “%sâ€" +msgid "Unable to load application information for ‘%s‘" +msgstr "Zlyhalo naÄítanie informácii pre obslužný program „%s“" + +#: gio/gio-tool-launch.c:119 +#, fuzzy, c-format +#| msgid "Default application for “%sâ€: %s\n" +msgid "Unable to launch application ‘%s’: %s" +msgstr "Predvolená aplikácia pre „%s“: %s\n" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Zobrazí skryté súbory" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Použije dlhý formát výpisu" + +#: gio/gio-tool-list.c:40 +#, fuzzy +#| msgid "display name: %s\n" +msgid "Print display names" +msgstr "názov na zobrazenie: %s\n" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Vypíše celé URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Vypíše obsah umiestnení." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list pracuje podobne ako tradiÄná utilita ls, iba že \n" +"s použitím umiestnení GIO namiesto lokálnych súborov: napríklad môžete " +"použiÅ¥ nieÄo ako \n" +"smb://server/resource/file.txt ako umiestnenie. Vlastnosti súborov môžu byÅ¥\n" +"zadané pomocou názvov GIO, napr. standard::icon, alebo použitím\n" +"menného priestoru, napr. unix, alebo zadaním '*', Äo zastupuje vÅ¡etky " +"vlastnosti" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "TYP_MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "OBSLUŽNÃ_PROGRAM" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "ZískaÅ¥ alebo nastaviÅ¥ obslužný program pre typ MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Ak nie je zadaný obslužný program, vypíše zaregistrované a odporúÄané " +"aplikácie\n" +"pre typ mime. Ak je zadaný obslužný program, je nastavený ako predvolený\n" +"obslužný program pre zadaný typ mime." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Je potrebné zadaÅ¥ jeden typ mime a možno tiež obslužný program" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Žiadne predvolené aplikácie pre „%s“\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Predvolená aplikácia pre „%s“: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registrované aplikácie:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Neregistrované aplikácie\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "OdporúÄané aplikácie:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Žiadne odporúÄané aplikácie\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Zlyhalo naÄítanie informácii pre obslužný program „%s“" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"Zlyhalo nastavenie „%s“ ako predvoleného obslužného programu pre „%s“: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Vytvorí nadradené adresáre" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "VytvoriÅ¥ adresáre." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir pracuje podobne ako tradiÄná utilita mkdir, iba že \n" +"s použitím umiestnení GIO namiesto lokálnych súborov: napríklad môžete " +"použiÅ¥ nieÄo ako \n" +"smb://server/resource/mydir ako umiestnenie." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "SledovaÅ¥ adresár (predvolené: závisí od typu)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "SledovaÅ¥ súbor (predvolené: závisí od typu)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "SledovaÅ¥ súbor priamo (zaznamenáva tiež zmeny cez hardlink)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Sleduje súbor priamo, ale oznamuje zmeny" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"OznamovaÅ¥ premenovanie a presunutie ako jednoduché udalosti odstrániÅ¥ a " +"vytvoriÅ¥" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Sleduje udalosti pripojení" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "SledovaÅ¥ zmeny súborov a adresárov." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Pripojí ako pripojiteľné" + +#: gio/gio-tool-mount.c:64 +#, fuzzy +#| msgid "Mount volume with device file" +msgid "Mount volume with device file, or other identifier" +msgstr "Pripojí zväzok so súborom zariadenia" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Odpojí" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Vysunie" + +#: gio/gio-tool-mount.c:67 +#, fuzzy +#| msgid "Mount volume with device file" +msgid "Stop drive with device file" +msgstr "Pripojí zväzok so súborom zariadenia" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ZARIADENIE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Odpojí vÅ¡etky pripojenia s danou schémou" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHÉMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignoruje nedokonÄené operácie so súbormi pri odpájaní alebo vysúvaní" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Použije anonymného používateľa pri autorizovaní" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Zoznam" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Sleduje udalosti" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Zobrazí ÄalÅ¡ie informácie" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonymný prístup zamietnutý" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Pre súbor zariadenia neexistuje jednotka" + +#: gio/gio-tool-mount.c:1014 +#, fuzzy +#| msgid "No volume for device file" +msgid "No volume for given ID" +msgstr "Pre súbor zariadenia neexistuje zväzok" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Pripojí alebo odpojí umiestnenia." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Nepoužije sa záložný režim pri kopírovaní a odstraňovaní" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Presunúť jeden alebo viac súborov zo ZDROJA do CIEĽA." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move pracuje podobne ako tradiÄná utilita mv, iba že \n" +"s použitím umiestnení GIO namiesto lokálnych súborov: napríklad môžete " +"použiÅ¥ nieÄo ako \n" +"smb://server/resource/file.txt ako umiestnenie" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Cieľ %s nie je adresárom" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Otvára súbory predvolenou aplikáciou, ktorá\n" +"je zaregistrovanou na obsluhu súborov zadaného typu." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignoruje neexistujúce súbory, nepýta sa" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Odstraňuje zadané súbory." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NÃZOV" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Premenuje súbor." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Chýbajúci parameter" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "PríliÅ¡ veľa parametrov" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Premenovanie úspeÅ¡né. Nové uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Vytvorí len ak neexistuje" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Pripojí na koniec súboru" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Pri vytváraní súboru obmedzí prístup len na aktuálneho používateľa" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Pri nahradení uskutoÄní nahradenie ako keby cieľ neexistoval" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Na konci vypíše nový etag" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Etag prepisovaného súboru" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +# PÅ : file handle (win32) je ekvivalent file descriptor - dovolil som si to preložiÅ¥ rovnako. KeÄže používané manipulátor, alebo rukoväť sú oba zlé preklady (obsluha je handler)... A dokonca aj v slovenskom preklade Správcu úloh vo win je použitý popisovaÄ. +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Chyba pri Äítaní zo Å¡tandardného vstupu" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag nie je k dispozícii\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Číta z predvoleného vstupu a ukladá do CIEĽA." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Neposkytnutý žiadny cieľ" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Typ atribútu" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYP" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBÚT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "HODNOTA" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Nastavuje atribút súboru z UMIESTNENIA." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Umiestnenie neurÄené" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atribút neurÄený" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Hodnota neurÄená" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Neplatný typ atribútu „%s“" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Vyprázdni Kôš" + +#: gio/gio-tool-trash.c:35 +#, fuzzy +#| msgid "List the contents of the locations." +msgid "List files in the trash with their original locations" +msgstr "Vypíše obsah umiestnení." + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" + +#: gio/gio-tool-trash.c:106 +#, fuzzy +#| msgid "Unable to find terminal required for application" +msgid "Unable to find original path" +msgstr "Nepodarilo sa nájsÅ¥ terminál vyžadovaný pre aplikáciu" + +#: gio/gio-tool-trash.c:123 +#, fuzzy +#| msgid "Unable to create socket: %s" +msgid "Unable to recreate original location: " +msgstr "Nepodarilo sa vytvoriÅ¥ soket: %s" + +#: gio/gio-tool-trash.c:136 +#, fuzzy +#| msgid "unable to find desktop file for application %s\n" +msgid "Unable to move file to its original location: " +msgstr "nepodarilo sa nájsÅ¥ súbor desktop pre aplikáciu %s\n" + +#: gio/gio-tool-trash.c:225 +#, fuzzy +#| msgid "Move files or directories to the trash." +msgid "Move/Restore files or directories to the trash." +msgstr "Presúva súbory alebo adresáre do KoÅ¡a." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Nasleduje symbolické odkazy, pripojenia a skratky" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Vypíše obsah adresárov v stromovom zobrazení." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Prvok <%s> nie je dovolený vo vnútri <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Prvok <%s> nie je dovolený na najvyššej úrovni" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Súbor %s sa v zdroji objavil viackrát" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Nepodarilo sa nájsÅ¥ „%s“ v žiadnom zdrojovom adresári" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Zlyhalo hľadanie „%s“ v aktuálnom adresári" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Neznáma voľba spracovania „%s“" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Chyba pri Äítaní súboru %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Chyba pri komprimovaní súboru %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "text sa nemôže nachádzaÅ¥ vo vnútri <%s>" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Zobrazí verziu programu a skonÄí" + +# cmd desc +#: gio/glib-compile-resources.c:738 +msgid "Name of the output file" +msgstr "Názov výstupného súboru" + +# cmd desc +#: gio/glib-compile-resources.c:739 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Adresáre odkiaľ sa majú ÄítaÅ¥ súbory odkazované v SÚBORe (predvolené: " +"aktuálny adresár)" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "ADRESÃR" + +# cmd desc +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Vygeneruje výstup vo formáte stanovenom podľa prípony cieľového súboru" + +#  cmd desc +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "Vygeneruje zdrojové hlaviÄky" + +# cmd desc +#: gio/glib-compile-resources.c:742 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Vygeneruje zdrojový kód použitý na prepojenie súboru zdrojov s vaším kódom" + +# cmd desc +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "Vygeneruje zoznam závislostí" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "Názov súboru závislostí na vygenerovanie" + +# cmd line desc +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "Zahrnie fiktívne ciele do vygenerovaného súboru závislosti" + +# cmd desc +#: gio/glib-compile-resources.c:746 +msgid "Don’t automatically create and register resource" +msgstr "Nebude vytváraÅ¥ a registrovaÅ¥ zdroj automaticky" + +# cmd desc +#: gio/glib-compile-resources.c:747 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Nebude exportovaÅ¥ funkcie; deklaruje ich pomocou G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Nezabuduje údaje zdrojov do súboru jazyka C, usudzujúc, že sú namiesto toho " +"prepojené externe" + +# cmd desc +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "IdentifikaÄný názov v jazyku C použitý pre generovaný zdrojový kód" + +# cmd program desc +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Preklad Å¡pecifikácie zdrojov do súboru zdrojov.\n" +"Súbory Å¡pecifikácie zdrojov majú príponu .gresource.xml,\n" +"a súbor zdrojov má príponu s názvom .gresource." + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "Mali by ste zadaÅ¥ práve jeden názov súboru\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "atribút nick musí maÅ¥ najmenej 2 znaky" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Neplatná Äíselná hodnota" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " je už urÄený" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' je už urÄený" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "hodnoty príznakov musia maÅ¥ nastavený najviac 1 bit" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> musí obsahovaÅ¥ aspoň jednu hodnotu " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> sa nenachádza v urÄenom rozsahu" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nie je platným Älenom urÄeného vymenovaného typu" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> obsiahnutý reÅ¥azec nie je medzi príznakmi urÄeného typu" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> obsiahnutý reÅ¥azec sa nenachádza vo výbere " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr "Rozsah je už pre tento kÄ¾ÃºÄ urÄený" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nie je povolený pre kľúÄe typu „%s“" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "Minimum urÄené pomocou je väÄÅ¡ie ako maximum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "nepodporovaná kategória l10n: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "vyžadovaná l10n, no nebola zadaná doména gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "poskytnutý kontext pre prekladateľov pre hodnotu bez povolenej l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Zlyhalo spracovanie hodnoty typu „%s“: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr " nemôžu byÅ¥ urÄené pri kľúÄoch, ktoré majú vymenovaný typ" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " je pre tento kÄ¾ÃºÄ už urÄený" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nie je povolený pre kľúÄe typu „%s“" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " je už zadaný" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " musí obsahovaÅ¥ aspoň jeden " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " je pre tento kÄ¾ÃºÄ už urÄený" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" môže byÅ¥ urÄený iba pre kľúÄe s vymenovaným typom, príznakmi alebo " +"za " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +"bol zadaný priÄom „%s“ je už Älenom vymenovaného typu" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +"bol zadaný priÄom už bol zadaný " + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " je už zadaný" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "cieľ aliasu „%s“ ne je vymenovaný typ" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "cieľ aliasu „%s“ ne je v " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " musí obsahovaÅ¥ aspoň jeden " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Prázdne názvy nie sú povolené" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Neplatný názov „%s“: názvy musia zaÄínaÅ¥ malým písmenom" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Neplatný názov „%s“: neplatný znak „%c“: povolené sú iba malé písmená, Äísla " +"a spojovník („-“)" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "" +"Neplatný názov „%s“: dva za sebou nasledujúce spojovníky („--“) nie sú " +"povolené" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Neplatný názov „%s“: posledný znak nesmie byÅ¥ spojovník („-“)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Neplatný názov „%s“: maximálna dĺžka je 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " je už urÄený" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Nedajú sa pridaÅ¥ kľúÄe do schémy „list-of“" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " je už urÄený" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" zatieni v ; na úpravu " +"hodnoty použite " + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Ako atribút pre musí byÅ¥ urÄená práve jedna hodnota z „type“, „enum“ " +"alebo „flags“" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> nie je (zatiaľ) definovaný." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Neplatný reÅ¥azec typu GVariant „%s“" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "Zadaný , no schéma niÄ nerozÅ¡iruje" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Žiadny na preváženie" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " je už urÄený" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " je už urÄený" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " rozÅ¡iruje zatiaľ neexistujúcu schému „%s“" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " je zoznamom zatiaľ neexistujúcej schémy „%s“" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Nemôže byÅ¥ zoznamom schémy s cestou" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Nemôže rozšíriÅ¥ schému s cestou" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" je zoznamom rozÅ¡irujúcim , ktorý nie je " +"zoznamom" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" rozÅ¡iruje , no " +"„%s“ nerozÅ¡iruje „%s“" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Cesta (ak je zadaná) musí zaÄínaÅ¥ a konÄiÅ¥ lomkou" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Cesta zoznamu musí konÄiÅ¥ „:/“" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Upozornenie: Schéma „%s“ má cestu „%s“. Cesty zaÄínajúce „/apps/“, „/" +"desktop/“ alebo „/system/“ sú zavrhnuté." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> je už urÄený" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Iba jeden prvok <%s> je dovolený vo vnútri <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Prvok <%s> nie je dovolený na najvyššej úrovni" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Prvok sa v vyžaduje" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Text sa nemôže nachádzaÅ¥ vo vnútri <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Upozornenie: nedefinovaná referencia na " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "Bol urÄený parameter --strict. UkonÄuje sa." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Celý tento súbor bol ignorovaný." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignoruje sa tento súbor." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"KÄ¾ÃºÄ â€ž%s“ neexistuje v schéme „%s“ ako to bolo urÄené v súbore preváženia " +"„%s“. Ignoruje sa preváženie tohto kľúÄa." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"KÄ¾ÃºÄ â€ž%s“ neexistuje v schéme „%s“ ako to bolo urÄené v súbore preváženia " +"„%s“ a bol urÄený parameter --strict. UkonÄuje sa." + +#: gio/glib-compile-schemas.c:1993 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"preváženie kľúÄa „%s“ v schéme „%s“ v súbore preváženia „%s“ nie je v " +"zozname platných možností" + +#: gio/glib-compile-schemas.c:2002 +#, fuzzy, c-format +#| msgid "" +#| "override for key '%s' in schema '%s' in override file '%s' is not in the " +#| "list of valid choices" +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"preváženie kľúÄa „%s“ v schéme „%s“ v súbore preváženia „%s“ nie je v " +"zozname platných možností" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Chyba pri analyzovaní kľúÄa „%s“ v schéme „%s“ ako bolo urÄené v súbore " +"preváženia „%s“: %s. Ignoruje sa preváženie tohto kľúÄa." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Chyba pri analyzovaní kľúÄa „%s“ v schéme „%s“ ako bolo urÄené v súbore " +"preváženia „%s“: %s. Bol urÄený parameter --strict. UkonÄuje sa." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Preváženie kľúÄa „%s“ v schéme „%s“ v prevažujúcom súbore „%s“ je mimo " +"rozsah daný schémou. Ignoruje sa preváženie tohto kľúÄa." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Preváženie kľúÄa „%s“ v schéme „%s“ v prevažujúcom súbore „%s“ je mimo " +"rozsah daný schémou a bol urÄený parameter --strict. UkonÄuje sa." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Preváženie kľúÄa „%s“ v schéme „%s“ v súbore preváženia „%s“ nie je v " +"zozname platných možností. Ignoruje sa preváženie tohto kľúÄa." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Preváženie kľúÄa „%s“ v schéme „%s“ v súbore preváženia „%s“ nie je v " +"zozname platných možností a bol urÄený parameter --strict. UkonÄuje sa." + +# cmd desc +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Kam sa má uložiÅ¥ súbor gschemas.compiled" + +# cmd desc +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Preruší pri ľubovoľnej chybe v schémach" + +# cmd desc +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Nezapíše súbor gschema.compiled" + +# cmd desc +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Nevynúti obmedzenia pre názvy kľúÄov" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Preklad vÅ¡etkých súborov schém GSettings do vyrovnávacej pamäte schém.\n" +"Súbory schém musia maÅ¥ príponu .gschema.xml,\n" +"a súbor vyrovnávacej pamäte sa nazýva gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Mali by ste zadaÅ¥ práve jeden názov adresára" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Nenájdené žiadne súbory schém: neurobí sa niÄ." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Nenájdené žiadne súbory schém: existujúci výstupný súbor odstránený." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Neplatný názov súboru %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Chyba pri získavaní informácií o súborovom systéme pre %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Obklopujúce pripojenie pre súbor %s sa nepodarilo nájsÅ¥" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Koreňový adresár sa nedá premenovaÅ¥" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Chyba pri premenovaní súboru %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Nedá sa premenovaÅ¥ súbor, názov súboru už existuje" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2371 gio/glocalfile.c:2399 +#: gio/glocalfile.c:2538 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Neplatný názov súboru" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Chyba pri otváraní súboru %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Chyba pri odstraňovaní súboru %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Chyba pri zahadzovaní súboru %s do KoÅ¡a: %s" + +#: gio/glocalfile.c:2031 +#, fuzzy, c-format +#| msgid "Unable to create trash dir %s: %s" +msgid "Unable to create trash directory %s: %s" +msgstr "Nepodarilo sa vytvoriÅ¥ adresár Kôš %s: %s" + +#: gio/glocalfile.c:2052 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Nepodarilo sa nájsÅ¥ adresár najvyššej úrovne pre Kôš %s" + +#: gio/glocalfile.c:2060 +#, fuzzy, c-format +#| msgid "Copy (reflink/clone) between mounts is not supported" +msgid "Trashing on system internal mounts is not supported" +msgstr "Kopírovanie (odkaz/klon) medzi pripojeniami nie je podporované" + +#: gio/glocalfile.c:2146 gio/glocalfile.c:2174 +#, fuzzy, c-format +#| msgid "Unable to find or create trash directory for %s" +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Nepodarilo sa nájsÅ¥ ani vytvoriÅ¥ adresár Kôš pre %s" + +#: gio/glocalfile.c:2220 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "" +"Nepodarilo sa vytvoriÅ¥ informaÄný súbor o zahadzovaní do KoÅ¡a pre %s: %s" + +#: gio/glocalfile.c:2282 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Nepodarilo sa zahodiÅ¥ súbor do KoÅ¡a cez hranice súborových systémov: %s" + +#: gio/glocalfile.c:2286 gio/glocalfile.c:2342 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Nepodarilo sa zahodiÅ¥ súbor %s do KoÅ¡a: %s" + +#: gio/glocalfile.c:2348 +#, c-format +msgid "Unable to trash file %s" +msgstr "Nepodarilo sa zahodiÅ¥ súbor %s do KoÅ¡a" + +#: gio/glocalfile.c:2374 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Chyba pri vytváraní adresára %s: %s" + +#: gio/glocalfile.c:2403 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Súborový systém nepodporuje symbolické odkazy" + +#: gio/glocalfile.c:2406 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Chyba pri vytváraní symbolického odkazu %s: %s" + +#: gio/glocalfile.c:2449 gio/glocalfile.c:2484 gio/glocalfile.c:2541 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Chyba pri presúvaní súboru %s: %s" + +#: gio/glocalfile.c:2472 +msgid "Can’t move directory over directory" +msgstr "Nedá sa prepísaÅ¥ adresár adresárom poÄas presúvania" + +#: gio/glocalfile.c:2498 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Vytvorenie súboru zálohy zlyhalo" + +#: gio/glocalfile.c:2517 +#, c-format +msgid "Error removing target file: %s" +msgstr "Chyba pri odstraňovaní cieľového súboru: %s" + +#: gio/glocalfile.c:2531 +msgid "Move between mounts not supported" +msgstr "Presun medzi pripojeniami nie je podporovaný" + +#: gio/glocalfile.c:2705 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Nepodarilo sa urÄiÅ¥ využitie disku %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Hodnota atribútu nesmie byÅ¥ NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Neplatný typ atribútu (oÄakávaný reÅ¥azec)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Neplatný názov rozšíreného atribútu" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Chyba pri nastavovaní rozšíreného atribútu „%s“: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (neplatné kódovanie)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Chyba pri získavaní informácií pre súbor „%s“: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Chyba pri získavaní informácií pre popisovaÄ súboru: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Neplatný typ atribútu (oÄakávané uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Neplatný typ atribútu (oÄakávané uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Neplatný typ atribútu (oÄakávaný bajtový reÅ¥azec)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Pre symbolické odkazy sa nedajú nastaviÅ¥ oprávnenia" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Chyba pri nastavovaní oprávnení: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Chyba pri nastavovaní vlastníka: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "symbolický odkaz nesmie byÅ¥ NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Chyba pri nastavovaní symbolického odkazu: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Chyba pri nastavovaní symbolického odkazu: súbor nie je symbolický odkaz" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "%d nanosekúnd navyÅ¡e pre UNIXovú Äasovú znaÄku %lld je záporných" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "%d nanosekúnd navyÅ¡e pre UNIXovú Äasovú znaÄku %lld dosiahlo 1 sekundu" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIXová Äasová znaÄka %lld sa nevmestí do 64 bitov" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"UNIXová Äasová znaÄka %lld je mimo rozsahu podporovaného systémom Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Názov súboru „%s“ nemôže byÅ¥ prevedený na kódovanie UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Súbor „%s“ sa nedá otvoriÅ¥: Chyba systému Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Chyba pri nastavovaní Äasu prístupu alebo zmeny súboru „%s“: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Chyba pri nastavovaní Äasu prístupu alebo zmeny: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Kontext pre SELinux nesmie byÅ¥ NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nie je na tomto systéme povolený" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Chyba pri nastavovaní kontextu pre SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Nastavovanie atribútu %s nie je podporované" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Chyba pri Äítaní zo súboru: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Chyba pri zatváraní súboru: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Chyba pri presúvaní v súbore: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Nepodarilo sa nájsÅ¥ predvolený typ sledovania lokálneho súboru" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Chyba pri zápise do súboru: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Chyba pri odstraňovaní starého záložného odkazu: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Chyba pri vytváraní záložnej kópie: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Chyba pri premenúvaní doÄasného súboru: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "Chyba pri skracovaní súboru: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:226 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Chyba pri otváraní súboru %s: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Cieľový súbor je adresár" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Cieľový súbor nie je obyÄajný súbor" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Súbor bol externe zmenený" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Chyba pri odstraňovaní starého súboru: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Poskytnutý neplatný GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Neplatná požiadavka na presunutie" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream sa nedá skrátiÅ¥" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Pamäťový výstupný prúd nepodporuje zmenu veľkosti" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Zlyhala zmena veľkosti pamäťového výstupného prúdu" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"VeľkosÅ¥ pamäte potrebná na vykonanie zápisu je väÄÅ¡ia ako dostupný adresný " +"priestor" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Požadovaný presun pred zaÄiatok prúdu" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Požadovaný presun za koniec prúdu" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "pripojenie neimplementuje „unmount“ (odpojenie)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "pripojenie neimplementuje „eject“ (vysunutie)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"pripojenie neimplementuje „unmount“ (odpojenie) ani " +"„unmount_with_operation“ (odpojenie s operáciou)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"pripojenie neimplementuje „eject“ (vysunutie) ani " +"„eject_with_operation“ (vysunutie s operáciou)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "pripojenie neimplementuje „remount“ (opätovné pripojenie)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "pripojenie neimplementuje odhad typu obsahu" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "pripojenie neimplementuje synchrónny odhad typu obsahu" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Názov hostiteľa „%s“ obsahuje „[“, ale neobsahuje „]“" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "SieÅ¥ nedostupná" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Hostiteľ nedostupný" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Nepodarilo sa vytvoriÅ¥ monitor siete: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Nepodarilo sa vytvoriÅ¥ monitor siete: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Nepodarilo sa získaÅ¥ vzdialenú adresu: " + +#: gio/gnetworkmonitornm.c:348 +#, c-format +msgid "NetworkManager not running" +msgstr "Program NetworkManager nie je spustený" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "Verzia programu NetworkManager je príliÅ¡ stará" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Výstupný prúd neimplementuje zápis" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "SúÄet vektorov predaných funkcii %s je príliÅ¡ veľký" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Zdrojový prúd je už zatvorený" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Chyba pri preklade adresy „%s“: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:615 +#, c-format +msgid "%s not implemented" +msgstr "Funkcia %s nie je implementovaná" + +#: gio/gresolver.c:984 gio/gresolver.c:1036 +msgid "Invalid domain" +msgstr "Neplatná doména" + +# %s je cesta +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Zdroj v „%s“ neexistuje" + +# %s je cesta +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Zdroj v „%s“ sa nepodarilo rozbaliÅ¥" + +# %s je cesta +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Zdroj v „%s“ nie je adresár" + +# MÄŒ: vÅ¡imol som si to na viacerých miestach, ale nepasuje mi to. Nemalo by byÅ¥ skôr „posúvanie“? +# PM: presúvaÅ¡ sa na iné miesto posúvanie mi tiez nevadí, ak dalsí kontrolór uzná ze by to malo byt posúvanie môže zmeniÅ¥. +# PK: necham presuvanie, lebo presuva sa kurzor, posuvanie mi evokuje ze sa data posuvaju +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Vstupný prúd neimplementuje presúvanie" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Zoznam Äastí obsahujúcich zdroje v SÚBORE vo formáte elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Zoznam zdrojov\n" +"Ak je zadaná ÄŒASŤ, budú to iba zdroje tejto Äasti\n" +"Ak je zadaná CESTA, bude to iba zoznam zodpovedajúcich zdrojov" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "SÚBOR [CESTA]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "ÄŒASŤ" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Zoznam zdrojov s podrobnosÅ¥ami\n" +"Ak je zadaná ÄŒASŤ, budú to iba zdroje tejto Äasti\n" +"Ak je zadaná CESTA, bude to iba zoznam zodpovedajúcich zdrojov\n" +"Podrobnosti zahŕňajú Äasti, veľkosti a kompresie" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extrahuje súbor zdrojov do stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "CESTA SÚBORU" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Použitie:\n" +" gresource [--section ÄŒASŤ] PRÃKAZ [PARAMETRE...]\n" +"\n" +"Príkazy:\n" +" help Zobrazí tieto informácie\n" +" sections Zoznam Äastí so zdrojmi\n" +" list Zoznam zdrojov\n" +" details Zoznam zdrojov s podrobnosÅ¥ami\n" +" extract Extrahuje zdroj\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Použitie:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +# http://en.wikipedia.org/wiki/Executable_and_Linkable_Format +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " ÄŒASŤ (voliteľný) názov Äasti elf\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:706 +msgid " COMMAND The (optional) command to explain\n" +msgstr " PRÃKAZ (voliteľný) príkaz na vysvetlenie\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " SÚBOR elf súbor (binárny súbor alebo zdieľaná knižnica)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" SÚBOR Súbor vo formáte elf (binárny súbor alebo zdieľaná knižnica)\n" +" alebo preložený súbor zdrojov\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[CESTA]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " CESTA (voliteľná) cesta k súboru zdrojov (môže byÅ¥ ÄiastoÄná)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "CESTA" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " CESTA Cesta k súboru zdrojov\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:911 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Neexistuje schéma „%s“\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Schéma „%s“ nie je premiestniteľná (cesta nesmie byÅ¥ urÄená)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schéma „%s“ je premiestniteľná (cesta musí byÅ¥ urÄená)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Poskytnutá prázdna cesta.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Cesta musí zaÄínaÅ¥ lomkou (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Cesta musí konÄiÅ¥ lomkou (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Cesta nesmie obsahovaÅ¥ dve po sebe nasledujúce lomky (//)\n" + +#: gio/gsettings-tool.c:541 +msgid "The provided value is outside of the valid range\n" +msgstr "Poskytnutá hodnota nepatrí do platného rozsahu\n" + +#: gio/gsettings-tool.c:548 +msgid "The key is not writable\n" +msgstr "KÄ¾ÃºÄ nie je zapisovateľný\n" + +#: gio/gsettings-tool.c:584 +msgid "List the installed (non-relocatable) schemas" +msgstr "Vypíše nainÅ¡talované (nepremiestniteľné) schémy" + +#: gio/gsettings-tool.c:590 +msgid "List the installed relocatable schemas" +msgstr "Vypíše nainÅ¡talované premiestniteľné schémy" + +#: gio/gsettings-tool.c:596 +msgid "List the keys in SCHEMA" +msgstr "Vypíše kľúÄe v SCHÉME" + +#: gio/gsettings-tool.c:597 gio/gsettings-tool.c:603 gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH]" +msgstr "SCHÉMA[:CESTA]" + +#: gio/gsettings-tool.c:602 +msgid "List the children of SCHEMA" +msgstr "Vypíše potomkov SCHÉMY" + +#: gio/gsettings-tool.c:608 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Vypíše rekurzívne vÅ¡etky kľúÄe a hodnoty\n" +"Ak SCHÉMA nie je zadaná, vypíše vÅ¡etky kľúÄe\n" + +#: gio/gsettings-tool.c:610 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHÉMA[:CESTA]]" + +#: gio/gsettings-tool.c:615 +msgid "Get the value of KEY" +msgstr "Získa hodnotu KĽÚČA" + +#: gio/gsettings-tool.c:616 gio/gsettings-tool.c:622 gio/gsettings-tool.c:628 +#: gio/gsettings-tool.c:640 gio/gsettings-tool.c:652 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHÉMA[:CESTA] KĽÚČ" + +#: gio/gsettings-tool.c:621 +msgid "Query the range of valid values for KEY" +msgstr "Spýta sa na platný rozsah hodnôt KĽÚČA" + +#: gio/gsettings-tool.c:627 +msgid "Query the description for KEY" +msgstr "Spýta sa na popis KĽÚČA" + +#: gio/gsettings-tool.c:633 +msgid "Set the value of KEY to VALUE" +msgstr "Nastaví hodnotu KĽÚČA na HODNOTU" + +#: gio/gsettings-tool.c:634 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHÉMA[:CESTA] KĽÚČ HODNOTA" + +#: gio/gsettings-tool.c:639 +msgid "Reset KEY to its default value" +msgstr "Nastaví KĽÚČ na jeho predvolenú hodnotu" + +#: gio/gsettings-tool.c:645 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Nastaví vÅ¡etky kľúÄe v SCHÉME na ich predvolené hodnoty" + +#: gio/gsettings-tool.c:651 +msgid "Check if KEY is writable" +msgstr "Skontroluje, Äi je KĽÚČ zapisovateľný" + +#: gio/gsettings-tool.c:657 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Sleduje zmeny KĽÚČA.\n" +"Ak KĽÚČ nie urÄený, sleduje vÅ¡etky kľúÄe v SCHÉME.\n" +"Sledovanie zastavíte pomocou ^C.\n" + +#: gio/gsettings-tool.c:660 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHÉMA[:CESTA] [KĽÚČ]" + +#: gio/gsettings-tool.c:672 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Použitie:\n" +" gsettings --version\n" +" gsettings [--schemadir ADRESÃR_SCHÉMY] PRÃKAZ [PARAMETRE...]\n" +"\n" +"Príkazy:\n" +" help Zobrazí tieto informácie\n" +" list-schemas Vypíše nainÅ¡talované schémy\n" +" list-relocatable-schemas Vypíše premiestniteľné schémy\n" +" list-keys Vypíše kľúÄe v schéme\n" +" list-children Vypíše potomkov schémy\n" +" list-recursively Rekurzívne vypíše kľúÄe a hodnoty\n" +" range Zistí rozsah hodnôt kľúÄa\n" +" describe Zistí popis kľúÄa\n" +" get Získa hodnotu kľúÄa\n" +" set Nastaví hodnotu kľúÄa\n" +" reset Obnoví predvolenú hodnotu kľúÄa\n" +" reset-recursively Obnoví hodnoty vÅ¡etkých kľúÄov v danej schéme\n" +" writable Skontroluje Äi je kÄ¾ÃºÄ zapisovateľný\n" +" monitor Sleduje zmeny\n" +"\n" +"PodrobnejÅ¡ieho pomocníka získate pomocou „gsettings help PRÃKAZ“.\n" +"\n" + +#: gio/gsettings-tool.c:696 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Použitie:\n" +" gsettings [--schemadir ADRESÃR_SCHÉMY] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:702 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " ADRESÃR_SCHÉMY Adresár, v ktorom sa majú hľadaÅ¥ dodatoÄné schémy\n" + +#: gio/gsettings-tool.c:710 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHÉMA Názov schémy\n" +" CESTA Cesta pre premiestniteľné schémy\n" + +#: gio/gsettings-tool.c:715 +msgid " KEY The (optional) key within the schema\n" +msgstr " KĽÚČ (voliteľný) kÄ¾ÃºÄ vo vnútri schémy\n" + +#: gio/gsettings-tool.c:719 +msgid " KEY The key within the schema\n" +msgstr " KĽÚČ KÄ¾ÃºÄ vo vnútri schémy\n" + +#: gio/gsettings-tool.c:723 +msgid " VALUE The value to set\n" +msgstr " HODNOTA Hodnota, ktorá sa má nastaviÅ¥\n" + +#: gio/gsettings-tool.c:778 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Nepodarilo sa naÄítaÅ¥ schémy z %s: %s\n" + +#: gio/gsettings-tool.c:790 +msgid "No schemas installed\n" +msgstr "Nie sú nainÅ¡talované žiadne schémy\n" + +#: gio/gsettings-tool.c:869 +msgid "Empty schema name given\n" +msgstr "Poskytnutý prázdny názov schémy\n" + +#: gio/gsettings-tool.c:924 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Neexistuje kÄ¾ÃºÄ â€ž%s“\n" + +#: gio/gsocket.c:413 +msgid "Invalid socket, not initialized" +msgstr "Neplatný soket, neinicializované" + +#: gio/gsocket.c:420 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Neplatný soket, inicializácia zlyhala kvôli: %s" + +#: gio/gsocket.c:428 +msgid "Socket is already closed" +msgstr "Soket je už zatvorený" + +#: gio/gsocket.c:443 gio/gsocket.c:3190 gio/gsocket.c:4420 gio/gsocket.c:4478 +msgid "Socket I/O timed out" +msgstr "VyprÅ¡al Äasový limit V/V soketu" + +#: gio/gsocket.c:578 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "vytvára sa GSocket z popisovanÄa súboru: %s" + +#: gio/gsocket.c:607 gio/gsocket.c:671 gio/gsocket.c:678 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Nepodarilo sa vytvoriÅ¥ soket: %s" + +#: gio/gsocket.c:671 +msgid "Unknown family was specified" +msgstr "Bola zadaná neznáma rodina protokolov" + +#: gio/gsocket.c:678 +msgid "Unknown protocol was specified" +msgstr "Bol zadaný neznámy protokol" + +#: gio/gsocket.c:1169 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Nedajú sa použiÅ¥ operácie soketu datagram na sokete nepodporujúcom datagram." + +#: gio/gsocket.c:1186 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Nedajú sa použiÅ¥ operácie soketu datagram na sokete s nastavením vyprÅ¡aním " +"Äasu." + +#: gio/gsocket.c:1993 +#, c-format +msgid "could not get local address: %s" +msgstr "nepodarilo sa získaÅ¥ lokálnu adresu: %s" + +#: gio/gsocket.c:2039 +#, c-format +msgid "could not get remote address: %s" +msgstr "nepodarilo sa získaÅ¥ vzdialenú adresu: %s" + +#: gio/gsocket.c:2105 +#, c-format +msgid "could not listen: %s" +msgstr "nepodarilo sa poÄúvaÅ¥: %s" + +#: gio/gsocket.c:2209 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Chyba pri viazaní sa na adresu %s: %s" + +#: gio/gsocket.c:2385 gio/gsocket.c:2422 gio/gsocket.c:2532 gio/gsocket.c:2557 +#: gio/gsocket.c:2620 gio/gsocket.c:2678 gio/gsocket.c:2696 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Chyba pri pripájaní sa k multicast skupine: %s" + +#: gio/gsocket.c:2386 gio/gsocket.c:2423 gio/gsocket.c:2533 gio/gsocket.c:2558 +#: gio/gsocket.c:2621 gio/gsocket.c:2679 gio/gsocket.c:2697 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Chyba pri odpájaní sa od multicast skupiny: %s" + +# PM: SSM je termín neprekladal som to +# http://en.wikipedia.org/wiki/Source-specific_multicast +#: gio/gsocket.c:2387 +msgid "No support for source-specific multicast" +msgstr "Nie je podpora pre source-specific multicast" + +#: gio/gsocket.c:2534 +msgid "Unsupported socket family" +msgstr "Nepodporovaná rodina soketu" + +#: gio/gsocket.c:2559 +msgid "source-specific not an IPv4 address" +msgstr "" + +#: gio/gsocket.c:2583 +#, c-format +msgid "Interface name too long" +msgstr "Názov rozhrania je príliÅ¡ dlhý" + +#: gio/gsocket.c:2596 gio/gsocket.c:2646 +#, c-format +msgid "Interface not found: %s" +msgstr "NenaÅ¡lo sa rozhranie: %s" + +# PM: SSM je termín neprekladal som to +# http://en.wikipedia.org/wiki/Source-specific_multicast +#: gio/gsocket.c:2622 +msgid "No support for IPv4 source-specific multicast" +msgstr "Nie je podpora pre IPv4 source-specific multicast" + +# PM: SSM je termín neprekladal som to +# http://en.wikipedia.org/wiki/Source-specific_multicast +#: gio/gsocket.c:2680 +msgid "No support for IPv6 source-specific multicast" +msgstr "Nie je podpora pre IPv6 source-specific multicast" + +#: gio/gsocket.c:2889 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Chyba pri prijímaní pripojenia: %s" + +#: gio/gsocket.c:3015 +msgid "Connection in progress" +msgstr "Prebieha pripájanie" + +#: gio/gsocket.c:3066 +msgid "Unable to get pending error: " +msgstr "Nepodarilo sa získaÅ¥ chybu urÄenú na spracovanie: " + +#: gio/gsocket.c:3255 +#, c-format +msgid "Error receiving data: %s" +msgstr "Chyba pri prijímaní údajov: %s" + +#: gio/gsocket.c:3452 +#, c-format +msgid "Error sending data: %s" +msgstr "Chyba pri odosielaní údajov: %s" + +#: gio/gsocket.c:3639 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Nepodarilo sa vypnúť soket: %s" + +#: gio/gsocket.c:3720 +#, c-format +msgid "Error closing socket: %s" +msgstr "Chyba pri zatváraní soketu: %s" + +#: gio/gsocket.c:4413 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ÄŒaká sa na stav soketu: %s" + +#: gio/gsocket.c:4804 gio/gsocket.c:4820 gio/gsocket.c:4833 +#, fuzzy, c-format +#| msgid "Error sending message: %s" +msgid "Unable to send message: %s" +msgstr "Chyba pri odosielaní správy: %s" + +#: gio/gsocket.c:4805 gio/gsocket.c:4821 gio/gsocket.c:4834 +msgid "Message vectors too large" +msgstr "" + +#: gio/gsocket.c:4850 gio/gsocket.c:4852 gio/gsocket.c:4999 gio/gsocket.c:5084 +#: gio/gsocket.c:5262 gio/gsocket.c:5302 gio/gsocket.c:5304 +#, c-format +msgid "Error sending message: %s" +msgstr "Chyba pri odosielaní správy: %s" + +#: gio/gsocket.c:5026 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage nie je podporovaný vo Windows" + +#: gio/gsocket.c:5495 gio/gsocket.c:5571 gio/gsocket.c:5797 +#, c-format +msgid "Error receiving message: %s" +msgstr "Chyba pri prijímaní správy: %s" + +#: gio/gsocket.c:6070 gio/gsocket.c:6081 gio/gsocket.c:6127 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Nepodarilo sa preÄítaÅ¥ poverenia soketu: %s" + +#: gio/gsocket.c:6136 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials nie je pre tento operaÄný systém implementovaný" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Nepodarilo sa pripojiÅ¥ k proxy serveru %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Nepodarilo sa pripojiÅ¥ k %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Nepodarilo sa pripojiÅ¥: " + +#: gio/gsocketclient.c:1162 gio/gsocketclient.c:1749 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Pripojenie cez proxy nepoužívajúce TCP nie je podporované." + +#: gio/gsocketclient.c:1194 gio/gsocketclient.c:1778 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Protokol proxy „%s“ nie je podporovaný." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "PosluchÃ¡Ä je už zatvorený" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Pridaný soket je zatvorený" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 nepodporuje adresu IPv6 „%s“" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Používateľské meno je príliÅ¡ dlhé pre protokol SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Názov hostiteľa „%s“ je pre protokol SOCKSv4 príliÅ¡ dlhý" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Server nie je proxy serverom SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Pripojenie cez server SOCKSv4 bolo odmietnuté" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Server nie je proxy serverom SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Proxy SOCKSv5 vyžaduje overenie totožnosti." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Proxy SOCKSv5 vyžaduje metódu overenia totožnosti, ktorú nepodporuje GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Používateľské meno alebo heslo je príliÅ¡ dlhé pre protokol SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Overenie totožnosti SOCKSv5 zlyhalo pre nesprávne používateľské meno alebo " +"heslo." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Názov hostiteľa „%s“ je pre protokol SOCKSv5 príliÅ¡ dlhý" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Proxy server SOCKSv5 používa neznámy typ adresy." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Vnútorná chyba proxy servera SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Pripojenie SOCKSv5 nie je povolené sadou pravidiel." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Hostiteľ nie je dostupný cez server SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SieÅ¥ nie je dostupný cez proxy SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Pripojenie cez proxy SOCKSv5 je odmietnuté." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "Proxy SOCKSv5 nepodporuje príkaz „connect“." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Proxy SOCKSv5 nepodporuje poskytnutý typ adresy." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Neznáma chyba proxy SOCKSv5." + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Nedá sa spracovaÅ¥ kódovanie GThemedIcon verzie %d" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "NenaÅ¡li sa žiadne platné adresy" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Chyba pri pri spätnom preklade adresy „%s“: %s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Neexistuje DNS záznam požadovaného typu pre „%s“" + +# DNS +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Služba nie je doÄasne schopná preložiÅ¥ adresu „%s“" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Chyba pri preklade adresy „%s“" + +#: gio/gtlscertificate.c:419 +msgid "No PEM-encoded private key found" +msgstr "NenaÅ¡iel sa súkromný kÄ¾ÃºÄ v PEM kódovaní" + +#: gio/gtlscertificate.c:429 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Nepodá sa rozÅ¡ifrovaÅ¥ súkromný kÄ¾ÃºÄ v kódovaní PEM" + +#: gio/gtlscertificate.c:440 +msgid "Could not parse PEM-encoded private key" +msgstr "Nepodarilo sa analyzovaÅ¥ súkromný kÄ¾ÃºÄ v kódovaní PEM" + +#: gio/gtlscertificate.c:467 +msgid "No PEM-encoded certificate found" +msgstr "NenaÅ¡iel sa certifikát v kódovaní PEM" + +#: gio/gtlscertificate.c:476 +msgid "Could not parse PEM-encoded certificate" +msgstr "Neporarilo sa analyzovaÅ¥ certifikát v kódovaní PEM" + +#: gio/gtlscertificate.c:832 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Toto je posledná Å¡anca na zadanie správneho hesla pred uzamknutím vášho " +"prístupu." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Niekoľko zadaných hesiel bolo nesprávnych a po Äalších zlyhaniach bude váš " +"prístup uzamknutý." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Zadané heslo je nesprávne." + +# PK: plural forms +# JK: https://bugzilla.gnome.org/show_bug.cgi?id=695233 +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "OÄakávaná jedna riadiaca správa, získaných %d" +msgstr[1] "OÄakávaná jedna riadiaca správa, získaná %d" +msgstr[2] "OÄakávaná jedna riadiaca správa, získané %d" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "NeoÄakávaný typ doplnkových údajov" + +# PK: plural forms +# JK: https://bugzilla.gnome.org/show_bug.cgi?id=695233 +# MÄŒ: Myslím, že by malo byÅ¥ získaný, keÄ ide o ten popisovaÄ. +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "OÄakávaný jeden popisovaÄ súboru, no získaných %d\n" +msgstr[1] "OÄakávaný jeden popisovaÄ súboru, no získaný %d\n" +msgstr[2] "OÄakávaný jeden popisovaÄ súboru, no získané %d\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Prijatý neplatný popisovaÄ súboru" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "Chyba pri odosielaní poverení: " + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Chyba pri kontrole, Äi je SO_PASSCRED povolené pre soket: %s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Chyba pri povoľovaní SO_PASSCRED: %s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Mal sa preÄítaÅ¥ jeden bajt s prichádzajúcimi povereniami, no preÄítalo sa " +"nula bajtov" + +# https://bugzilla.gnome.org/show_bug.cgi?id=658713 +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "NeoÄakávala sa riadiaca správa, no získané %d" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Chyba poÄas zakazovania SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Chyba pri Äítaní z popisovaÄa súboru: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Chyba pri zatváraní popisovaÄa súboru: %s" + +#: gio/gunixmounts.c:2785 gio/gunixmounts.c:2838 +msgid "Filesystem root" +msgstr "Koreň súborového systému" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Chyba pri zápise do popisovaÄa súboru: %s" + +#: gio/gunixsocketaddress.c:244 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"V tomto systéme nie sú podporované abstraktné adresy soketov unixových domén" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "zväzok neimplementuje vysunutie" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" +"zväzok neimplementuje eject (vysunutie) ani eject_with_operation (vysunutie " +"s operáciou)" + +# PÅ : file handle (win32) je ekvivalent file descriptor - dovolil som si to preložiÅ¥ rovnako. KeÄže používané manipulátor, alebo rukoväť sú oba zlé preklady (obsluha je handler)... A dokonca aj v slovenskom preklade Správcu úloh vo win je použitý popisovaÄ. +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Chyba pri Äítaní z popisovaÄa: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Chyba pri zatváraní popisovaÄa: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Chyba pri zápise do popisovaÄa: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nedostatok pamäte" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Vnútorná chyba: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Potrebných viac vstupov" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Neplatné komprimované údaje" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresa, na ktorej sa má poÄúvaÅ¥" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorované kvôli kompatibilite s GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Zobrazí adresu" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Zobrazí adresu v režime shellu" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Spustí službu dbus" + +# PK: argumenty +# PM: agumenty sú (skutoÄné) parametre a parametre sú formálne parametre tak je to zaužívané - vid napr lexikón informatiky alebo knihu o pascale +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Chybné parametre\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "NeoÄakávaný atribút „%s“ prvku „%s“" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atribút „%s“ prvku „%s“ nenájdený" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "NeoÄakávaná znaÄka „%s“, bola oÄakávaná znaÄka „%s“" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "NeoÄakávaná znaÄka „%s“ vo vnútri „%s“" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Neplatný dátum alebo Äas „%s“ v súbore záložky" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "V dátových adresároch nebol nájdený žiadny platný súbor záložiek" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Záložka pre identifikátor URI „%s“ už existuje" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nebola nájedená záložka pre identifikátor URI „%s“" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "V záložke pre identifikátor URI „%s“ nie je definovaný žiadny typ MIME" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "" +"V záložke pre identifikátor URI „%s“ nebol definovaný žiadny súkromný príznak" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "V záložke pre identifikátor URI „%s“ neboli nastavené žiadne skupiny" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Žiadna aplikácia s názvom „%s“ nezaregistrovala záložku pre „%s“" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Zlyhalo rozvinutie spustiteľného riadka „%s“ o identifikátor URI „%s“" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Nezobraziteľný znak na vstupe prevodu" + +#: glib/gconvert.c:495 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "ÄŒiastoÄná sekvencia znakov na konci vstupu" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Nedá sa previesÅ¥ náhradné „%s“ do kódovej stránky „%s“" + +#: glib/gconvert.c:936 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion input" +msgstr "Neplatná sekvencia bajtov na vstupe prevodu" + +#: glib/gconvert.c:957 +#, fuzzy +#| msgid "Invalid byte sequence in conversion input" +msgid "Embedded NUL byte in conversion output" +msgstr "Neplatná sekvencia bajtov na vstupe prevodu" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "" +"Identifikátor URI „%s“ nie je absolútny identifikátor URI používajúci schému " +"„file“" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Identifikátor URI lokálneho súboru „%s“ nesmie obsahovaÅ¥ „#“" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Identifikátor URI „%s“ je neplatný" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Názov hostiteľa URI „%s“ je neplatný" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Identifikátor URI „%s“ obsahuje neplatné Å¡peciálne uvedené znaky" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Cesta „%s“ nie je absolútna" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %-d. %B %Y, %H:%M:%S %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%H:%M:%S" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "január" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "február" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "marec" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "apríl" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "máj" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "jún" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "júl" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "august" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "september" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "október" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "máj" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jún" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "júl" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "aug" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "pondelok" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "utorok" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "streda" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Å¡tvrtok" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "piatok" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sobota" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "nedela" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "po" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "ut" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "st" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Å¡t" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "pi" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "so" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ne" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "januára" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "februára" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "marca" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "apríla" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "mája" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "júna" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "júla" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "augusta" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "septembra" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "októbra" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "novembra" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "decembra" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "máj" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jún" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "júl" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "aug" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec" + +# PM: ale myslím si ze by to malo byÅ¥ preložené, lebo ak si niekto v hodinách prepne na 12 hodinový formát tak si potom nebude vedieÅ¥ nastaviÅ¥ správny Äas +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "Doobeda" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "Poobede" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Chyba pri otváraní adresára „%s“: %s" + +#: glib/gfileutils.c:737 glib/gfileutils.c:829 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Nepodarilo sa alokovaÅ¥ %lu bajtov na Äítanie súboru „%s“" +msgstr[1] "Nepodarilo sa alokovaÅ¥ %lu bajt na Äítanie súboru „%s“" +msgstr[2] "Nepodarilo sa alokovaÅ¥ %lu bajty na Äítanie súboru „%s“" + +#: glib/gfileutils.c:754 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Chyba pri Äítaní súboru %s: %s" + +#: glib/gfileutils.c:790 +#, c-format +msgid "File “%s†is too large" +msgstr "Súbor „%s“ je príliÅ¡ veľký" + +#: glib/gfileutils.c:854 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Zlyhalo Äítanie zo súboru „%s“: %s" + +#: glib/gfileutils.c:904 glib/gfileutils.c:979 glib/gfileutils.c:1468 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Zlyhalo otvorenie súboru „%s“: %s" + +#: glib/gfileutils.c:917 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Zlyhalo získanie atribútov súboru „%s“: fstat() zlyhalo: %s" + +#: glib/gfileutils.c:948 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Zlyhalo otvorenie súboru „%s“: fdopen() zlyhalo: %s" + +#: glib/gfileutils.c:1049 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Zlyhalo premenovanie súboru „%s“ na „%s“: g_rename() zlyhalo: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Zlyhal zápis súboru „%s“: write() zlyhalo: %s" + +#: glib/gfileutils.c:1196 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Zlyhal zápis súboru „%s“: fsync() zlyhalo: %s" + +#: glib/gfileutils.c:1357 glib/gfileutils.c:1772 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Zlyhalo vytvorenie súboru „%s“: %s" + +#: glib/gfileutils.c:1402 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Existujúci súbor „%s“ nemohol byÅ¥ odstránený: g_unlink() zlyhalo: %s" + +#: glib/gfileutils.c:1737 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Å ablóna „%s“ je neplatná, nesmie obsahovaÅ¥ „%s“" + +#: glib/gfileutils.c:1750 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Å ablóna „%s“ neobsahuje XXXXXX" + +#: glib/gfileutils.c:2310 glib/gfileutils.c:2339 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Zlyhalo naÄítanie symbolického odkazu „%s“: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Nepodarilo sa otvoriÅ¥ program na prevod z „%s“ do „%s“: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Nedá sa urobiÅ¥ priame Äítanie v g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Zanechané neprevedené údaje v zásobníku na Äítanie" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanál skonÄil s neúplným znakom" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Nedá sa urobiÅ¥ priame Äítanie v g_io_channel_read_to_end" + +#: glib/gkeyfile.c:790 +msgid "Valid key file could not be found in search dirs" +msgstr "Nepodarilo sa nájsÅ¥ platný súbor kľúÄov vo vyhľadávacích adresároch" + +#: glib/gkeyfile.c:827 +msgid "Not a regular file" +msgstr "Nie je bežný súbor" + +#: glib/gkeyfile.c:1282 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Súbor kľúÄov obsahuje riadok „%s“, ktorý nie je párom kľúÄ-hodnota, " +"skupinou, ani komentárom" + +#: glib/gkeyfile.c:1339 +#, c-format +msgid "Invalid group name: %s" +msgstr "Neplatný názov skupiny: %s" + +#: glib/gkeyfile.c:1361 +msgid "Key file does not start with a group" +msgstr "Súbor kľúÄov nezaÄína skupinou" + +#: glib/gkeyfile.c:1387 +#, c-format +msgid "Invalid key name: %s" +msgstr "Neplatný názov kľúÄa: %s" + +#: glib/gkeyfile.c:1414 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Súbor kľúÄov obsahuje nepodporované kódovane „%s“" + +#: glib/gkeyfile.c:1663 glib/gkeyfile.c:1836 glib/gkeyfile.c:3289 +#: glib/gkeyfile.c:3353 glib/gkeyfile.c:3483 glib/gkeyfile.c:3615 +#: glib/gkeyfile.c:3761 glib/gkeyfile.c:3996 glib/gkeyfile.c:4063 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Súbor kľúÄov nemá skupinu „%s“" + +#: glib/gkeyfile.c:1791 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Súbor kľúÄov nemá kÄ¾ÃºÄ â€ž%s“ v skupine „%s“" + +#: glib/gkeyfile.c:1953 glib/gkeyfile.c:2069 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Súbor kľúÄov obsahuje kÄ¾ÃºÄ â€ž%s“ s hodnotou „%s“, ktorá nie je UTF-8" + +#: glib/gkeyfile.c:1973 glib/gkeyfile.c:2089 glib/gkeyfile.c:2531 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "Súbor kľúÄov obsahuje kÄ¾ÃºÄ â€ž%s“, ktorý má neinterpretovateľnú hodnotu." + +#: glib/gkeyfile.c:2749 glib/gkeyfile.c:3118 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Súbor kľúÄov obsahuje kÄ¾ÃºÄ â€ž%s“ v skupine „%s“, ktorý má neinterpretovateľnú " +"hodnotu." + +#: glib/gkeyfile.c:2827 glib/gkeyfile.c:2904 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "KÄ¾ÃºÄ â€ž%s“ v skupine „%s“ má hodnotu „%s“, priÄom bola oÄakávaná %s" + +#: glib/gkeyfile.c:4306 +msgid "Key file contains escape character at end of line" +msgstr "Súbor kľúÄov obsahuje znak escape na konci riadku" + +#: glib/gkeyfile.c:4328 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Súbor kľúÄov obsahuje neplatnú Å¡peciálnu (escape) sekvenciu „%s“" + +#: glib/gkeyfile.c:4472 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Hodnota „%s“ nemôže byÅ¥ interpretovaná ako Äíslo." + +#: glib/gkeyfile.c:4486 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "CeloÄíselná hodnota „%s“ je mimo rozsah" + +#: glib/gkeyfile.c:4519 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Hodnota „%s“ nemôže byÅ¥ interpretovaná ako reálne Äíslo." + +#: glib/gkeyfile.c:4558 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Hodnota „%s“ nemôže byÅ¥ interpretovaná ako logická hodnota." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "Zlyhalo získanie atribútov súboru „%s%s%s%s“: fstat() zlyhalo: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Zlyhalo mapovanie %s%s%s%s: mmap() zlyhalo: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Zlyhalo otvorenie súboru „%s“: open() zlyhalo: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Chyba na riadku %d znak %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "V názve je neplatný text v kódovaní UTF-8 — neplatné reÅ¥azec „%s“" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "„%s“ nie je platný názov" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "„%s“ nie je platným názvom: „%c“" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Chyba na riadku Ä. %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Zlyhalo analyzovanie „%-.*s“, Äo by mala byÅ¥ Äíslica z Äíselného kódu znaku " +"(napríklad ê) — možno je Äíslica príliÅ¡ veľká" + +#: glib/gmarkup.c:702 +#, fuzzy +#| msgid "" +#| "Character reference did not end with a semicolon; most likely you used an " +#| "ampersand character without intending to start an entity - escape " +#| "ampersand as &" +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Kód znaku neskonÄil bodkoÄiarkou. Asi ste použili & bez úmyslu napísaÅ¥ kód " +"znaku – zapíšte ho ako entitu &" + +#: glib/gmarkup.c:728 +#, fuzzy, c-format +#| msgid "Character reference '%-.*s' does not encode a permitted character" +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Kód znaku „%-.*s“ nie je kódom povoleného znaku" + +#: glib/gmarkup.c:766 +#, fuzzy +#| msgid "" +#| "Empty entity '&;' seen; valid entities are: & " < > '" +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Nájdená prázdna entita „&;“, platné entity sú: & " < > '" + +#: glib/gmarkup.c:774 +#, fuzzy, c-format +#| msgid "Entity name '%-.*s' is not known" +msgid "Entity name “%-.*s†is not known" +msgstr "Názov entity „%-.*s“ nie je známy" + +#: glib/gmarkup.c:779 +#, fuzzy +#| msgid "" +#| "Entity did not end with a semicolon; most likely you used an ampersand " +#| "character without intending to start an entity - escape ampersand as &" +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entita neskonÄila bodkoÄiarkou. Asi ste použili & bez úmyslu napísaÅ¥ kód " +"znaku – zapíšte ho ako entitu &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument musí zaÄínaÅ¥ prvkom (napr. )" + +#: glib/gmarkup.c:1233 +#, fuzzy, c-format +#| msgid "" +#| "'%s' is not a valid character following a '<' character; it may not begin " +#| "an element name" +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"„%s“ nie je platným znakom za znakom „<“, nesmie ním zaÄínaÅ¥ názov prvku" + +#: glib/gmarkup.c:1276 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' character to end the empty-element tag " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"PrebytoÄný znak „%s“. Bol oÄakávaný znak „>“ ukonÄujúci znaÄku prázdneho " +"prvku „%s“" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "PríliÅ¡ veľa atribútov v prvku „%s“" + +#: glib/gmarkup.c:1366 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '=' after attribute name '%s' of element " +#| "'%s'" +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"PrebytoÄný znak „%s“. Bol oÄakávaný znak „=“ za názvom atribútu „%s“ v prvku " +"„%s“" + +#: glib/gmarkup.c:1408 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected a '>' or '/' character to end the start tag " +#| "of element '%s', or optionally an attribute; perhaps you used an invalid " +#| "character in an attribute name" +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"PrebytoÄný znak „%s“. Bol oÄakávaný nepovinný atribút alebo znak „>“ alebo " +"„/“ ukonÄujúci zaÄiatoÄnú znaÄku prvku „%s“. Možno ste použili neplatný znak " +"v názve atribútu" + +#: glib/gmarkup.c:1453 +#, fuzzy, c-format +#| msgid "" +#| "Odd character '%s', expected an open quote mark after the equals sign " +#| "when giving value for attribute '%s' of element '%s'" +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"PrebytoÄný znak „%s“. Bola oÄakávaná úvodzovka za znakom „=“ uvádzajúca " +"hodnotu atribútu „%s“ prvku „%s“" + +#: glib/gmarkup.c:1587 +#, fuzzy, c-format +#| msgid "" +#| "'%s' is not a valid character following the characters ''" +msgid "" +"“%s†is not a valid character following the close element name “%sâ€; the " +"allowed character is “>â€" +msgstr "" +"„%s“ nie je platným znakom po koncovom názve prvku „%s“. Povolený znak je „>“" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Prvok „%s“ bol ukonÄený, momentálne nie je otvorený žiadny prvok" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Prvok „%s“ bol ukonÄený, ale momentálne otvorený prvok je „%s“" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument je prázdny alebo obsahuje iba netlaÄiteľné znaky" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokument neoÄakávane skonÄil hneÄ po zaÄiatoÄnej lomenej zátvorke „<“" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokument neoÄakávane skonÄil s otvorenými prvkami — „%s“ bol posledný " +"otvorený prvok." + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokument neoÄakávane skonÄil, oÄakával sa znak „>“ pre ukonÄenie znaÄky <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokument neoÄakávane skonÄil v názve prvku" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokument neoÄakávane skonÄil v názve atribútu" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokument neoÄakávane skonÄil v zaÄiatoÄnej znaÄke prvku." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokument neoÄakávane skonÄil po „=“ za názvom atribútu, chýba hodnota " +"atribútu" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokument neoÄakávane skonÄil v hodnote atribútu" + +#: glib/gmarkup.c:1876 +#, fuzzy, c-format +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokument neoÄakávane skonÄil v koncovej znaÄke pre prvok „%s“" + +#: glib/gmarkup.c:1880 +#, fuzzy +#| msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "Dokument neoÄakávane skonÄil v koncovej znaÄke pre prvok „%s“" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokument neoÄakávane skonÄil v komentári alebo inÅ¡trukcii pre spracovanie" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[VOĽBA…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Voľby pomocníka:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Zobrazí voľby pomocníka" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Zobrazí vÅ¡etky voľby pomocníka" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Voľby aplikácie:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Voľby:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Nedá sa analyzovaÅ¥ celoÄíselná hodnota „%s“ pre %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "CeloÄíselná hodnota „%s“ pre %s je mimo rozsah" + +# PÅ : double je dvojitá presnosÅ¥ (Äísla s desatinnou Äiarkou) +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Nedá sa analyzovaÅ¥ hodnota double „%s“ pre %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Hodnota double „%s“ pre %s je mimo rozsah" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Chyba analyzovania voľby %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Chýbajúci parameter pre %s" + +#: glib/goption.c:2185 +#, c-format +msgid "Unknown option %s" +msgstr "Neznáma voľba %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "poÅ¡kodený objekt" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "vnútorná chyba alebo poÅ¡kodený objekt" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "nedostatok pamäte" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "dosiahnutý limit spätného hľadania" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "vzor obsahuje položky nepodporované pri ÄiastoÄnom porovnávaní" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "vnútorná chyba" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"spätné odkazy použité ako podmienky nie sú podporované pri ÄiastoÄnom " +"porovnávaní" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "dosiahnutý limit rekurzie" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "neplatná kombinácia príznakov nového riadka" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "zlý ofset" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "krátke utf8" + +# Ide o omyl programátora: case PCRE_ERROR_RECURSELOOP: return _("recursion loop"); +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "rekurzívna sluÄka" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "neznáma chyba" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ na konci vzoru" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c na konci vzoru" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "nerozpoznaný znak nasledujúci za \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "nesprávne poradie Äísel v kvantifikátore {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "príliÅ¡ veľké Äíslo v kvantifikátore {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "chýbajúca koncová ] pre triedu znakov" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "neplatná Å¡peciálna (escape) sekvencia v triede znakov" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "nesprávne poradie rozsahu v triede znakov" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "nie je Äo opakovaÅ¥" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "neoÄakávané opakovanie" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "nerozpoznaný znak za (? alebo (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "triedy s názvami POSIX sú podporované iba v triedach" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "chýbajúca koncová )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "odkaz na neexistujúci podvzor" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "chýbajúca ) po komentári" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "regulárny výraz je príliÅ¡ veľký" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "nepodarilo sa získaÅ¥ pamäť" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") bez otváracej (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "preteÄenie kódu" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "nerozpoznaný znak za (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "spätné tvrdenie nemá pevnú dĺžku" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "zle formátované Äíslo alebo názov za (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "podmienková skupina obsahuje viac ako dve zátvorky" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "tvrdenie oÄakávané za (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "za (?R alebo (?[+-]Äíslice musí nasledovaÅ¥ )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "neznámy POSIX názov triedy" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "porovnávacie POSIX prvky nie sú podporované" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "hodnota znaku v postupnosti \\x{...} je príliÅ¡ veľká" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "neplatná podmienka (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C nie je povolené v spätnom tvrdení" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "\\L, \\l, \\N{name}, \\U, a \\u nie sú podporované" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "rekurzívne volanie by sa mohlo donekoneÄna opakovaÅ¥" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "nerozpoznaný znak za (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "chýba ukonÄovací Älen v názve podvzoru" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dva pomenované podvzory majú rovnaký názov" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "zle formátovaná postupnosÅ¥ \\P alebo \\p" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "neznámy názov vlastnosti za \\P alebo \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "názov podvzoru je príliÅ¡ dlhý (maximum je 32 znakov)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "príliÅ¡ mnoho pomenovaných podvzorov (maximum je 10 000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "osmiÄková hodnota je väÄÅ¡ia ako \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "preteÄený priestor pre preklad" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "predtým kontrolovaný odkazovaný podvzor nenájdený" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "skupina DEFINE obsahuje viac ako jednu vetvu" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "nekonzistentné voľby NEWLINE" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"za \\g nenasleduje názov v guľatých ani lomených zátvorkách, názov alebo " +"Äíslo v úvodzovkách ani nekódované Äíslo" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "oÄíslovaný odkaz nesmie byÅ¥ nula" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "parameter nie je pre (*ACCEPT), (*FAIL) a (*COMMIT) dovolený" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) nebolo rozpoznané" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "Äíslo je príliÅ¡ veľké" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "za (?& chýba názov podvzoru" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "za (?+ sa oÄakáva Äíslica" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" +"] nie je platný dátový znak v režime kompatibility s jazykom JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "rôzne názvy pre podvzory s rovnakým Äíslom nie sú povolené" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) musí maÅ¥ parameter" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "za \\c musí nasledovaÅ¥ znak ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"za \\k nenasleduje názov v zátvorkách, lomených zátvorkách alebo úvodzovkách" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N nie je v triede podporované" + +# PM:nie som si istý +# MÄŒ: Hmm. Musel som pozrieÅ¥ zdrojáky pcre, aby som sa troÅ¡ku ztoho vymotal. Pri doprednom vyhľadávaní (lookahead) si stroj regulárneho výrazu odkladá odkazy na už asociované (zjednoduÅ¡ene nájdené) Äasti textu k regulárnemu výrazu. Ak je ich priveľa, nezmestia sa do pamäte, malloc zlyhá, vráti túto chybovú hlášku. Myslím, že preklad aj originál mi povedali rovnako veľa informácií. +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "príliÅ¡ mnoho dopredných odkazov" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "názov v (*MARK), (*PRUNE), (*SKIP) alebo (*THEN) je príliÅ¡ dlhý" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "hodnota znaku v postupnosti \\u.... je príliÅ¡ veľká" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Chyba poÄas porovnávania regulárneho výrazu %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Knižnica PCRE je preložená bez podpory UTF8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Knižnica PCRE je preložená bez podpory vlastností UTF8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Knižnica PCRE je preložená s nekompatibilnými voľbami" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Chyba poÄas optimalizovania regulárneho výrazu %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Chyba poÄas prekladu regulárneho výrazu %s pri znaku %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "oÄakávaná Å¡estnástková Äíslica alebo „}“" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "oÄakávaná Å¡estnástková Äíslica" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "chýba „<“ v symbolickom odkaze" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "neukonÄený symbolický odkaz" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "symbolický odkaz s nulovou dĺžkou" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "oÄakávaná Äíslica" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "neplatný symbolický odkaz" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "zabudnuté koncové „\\“" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "neznáma Å¡peciálna (escape) sekvencia" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Chyba poÄas analyzovania nahrádzajúceho textu „%s“ pri znaku %lu: %s" + +#: glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Citovaný text nezaÄína úvodzovkami" + +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"PrebytoÄné úvodzovky v príkazovom riadku alebo v inom texte shellu v " +"úvodzovkách" + +#: glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Text skonÄil hneÄ po znaku „\\“. (Text bol „%s“)" + +#: glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Text skonÄil pred nájdením zodpovedajúcej úvodzovky znakom %c. (Text bol " +"„%s“)" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Text bol prázdny (alebo obsahoval iba medzery)" + +#: glib/gspawn.c:308 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Zlyhalo Äítanie údajov z dcérskeho procesu (%s)" + +#: glib/gspawn.c:458 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "NeoÄakávaná chyba pri Äítaní údajov z dcérskeho procesu (%s)" + +#: glib/gspawn.c:543 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NeoÄakávaná chyba vo waitpid() (%s)" + +#: glib/gspawn.c:1152 glib/gspawn-win32.c:1407 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Dcérsky proces skonÄil s kódom %ld" + +#: glib/gspawn.c:1160 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Dcérsky proces bol zabitý signálom %ld" + +#: glib/gspawn.c:1167 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Dcérsky proces bol zastavený signálom %ld" + +#: glib/gspawn.c:1174 +#, c-format +msgid "Child process exited abnormally" +msgstr "Dcérsky proces skonÄil neobvykle" + +#: glib/gspawn.c:1793 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Zlyhalo Äítanie zo zreÅ¥azenia s potomkom (%s)" + +#: glib/gspawn.c:2095 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Zlyhalo vytvorenie dcérskeho procesu „%s“ (%s)" + +#: glib/gspawn.c:2212 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Zlyhalo vytvorenie vetvy (%s)" + +#: glib/gspawn.c:2372 glib/gspawn-win32.c:381 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Zlyhala zmena adresára na „%s“ (%s)" + +#: glib/gspawn.c:2382 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Zlyhalo spustenie dcérskeho procesu „%s“ (%s)" + +#: glib/gspawn.c:2392 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Zlyhalo presmerovanie vstupu alebo výstupu dcérskeho procesu (%s)" + +#: glib/gspawn.c:2401 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Zlyhalo vytvorenie vetvy dcérskeho procesu (%s)" + +#: glib/gspawn.c:2409 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Neznáma chyba pri spúšťaní dcérskeho procesu „%s“" + +#: glib/gspawn.c:2433 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Nepodarilo sa preÄítaÅ¥ dostatok údajov zo zreÅ¥azenia s dcérskym procesom (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "Zlyhalo Äítanie údajov z dcérskeho procesu" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Zlyhalo vytvorenie zreÅ¥azenia pre komunikáciu s dcérskym procesom (%s)" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Zlyhalo spustenie dcérskeho procesu (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "Neplatný názov programu: %s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:779 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Neplatný reÅ¥azec vo vektore parametra na %d: %s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:794 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Neplatný reÅ¥azec v prostredí: %s" + +#: glib/gspawn-win32.c:775 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Neplatný pracovný adresár: %s" + +#: glib/gspawn-win32.c:837 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Zlyhalo spustenie pomocného programu (%s)" + +#: glib/gspawn-win32.c:1064 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"NeoÄakávaná chyba v g_io_channel_win32_poll() pri Äítaní údajov z dcérskeho " +"procesu" + +#: glib/gstrfuncs.c:3338 glib/gstrfuncs.c:3440 +msgid "Empty string is not a number" +msgstr "Prázdny reÅ¥azec nie je Äíslo" + +#: glib/gstrfuncs.c:3362 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s“ nie je Äíslo so znamienkom" + +#: glib/gstrfuncs.c:3372 glib/gstrfuncs.c:3476 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Číslo „%s“ je mimo rozsah [%s, %s]" + +#: glib/gstrfuncs.c:3466 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s“ nie je Äíslo bez znamienka" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Neplatné kódovanie použitím znaku % v URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Neplatný znak v URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "" + +#: glib/guri.c:613 +#, fuzzy, c-format +#| msgid "Could not parse port ‘%.*s’ in URI" +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Nepodarilo sa analyzovaÅ¥ port „%.*s“ v URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Nepodarilo sa analyzovaÅ¥ port „%.*s“ v URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Port „%.*s“ v URI je mimo rozsah" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI „%s“ nie je absolútnym URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "" + +#: glib/guri.c:1435 +msgid "URI is not absolute, and no base URI was provided" +msgstr "" + +#: glib/guri.c:2213 +msgid "Missing ‘=’ and parameter value" +msgstr "Chýba znak „=“ a hodnota parametra" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "Zlyhalo alokovanie pamäte" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "Znak mimo rozsah UTF-8" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "Neplatná sekvencia na vstupe prevodu" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "Znak mimo rozsah UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2727 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2729 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2731 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2733 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2735 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2737 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2741 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2743 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2745 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2747 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2749 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2751 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2755 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2757 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2759 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2761 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2763 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2765 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2769 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2771 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2773 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2775 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2777 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2779 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2813 glib/gutils.c:2930 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajtov" +msgstr[1] "%u bajt" +msgstr[2] "%u bajty" + +#: glib/gutils.c:2817 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bitov" +msgstr[1] "%u bit" +msgstr[2] "%u bity" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2884 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bajtov" +msgstr[1] "%s bajt" +msgstr[2] "%s bajty" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2889 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bitov" +msgstr[1] "%s bit" +msgstr[2] "%s bity" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2943 +#, c-format +msgid "%.1f KB" +msgstr "%.1f kB" + +#: glib/gutils.c:2948 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2953 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2958 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2963 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2968 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "Nepodarilo sa naÄítaÅ¥ /var/lib/dbus/machine-id ani /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Neznáma chyba pripájania" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Chyba v adrese „%s“ — atribút rodiny má zlý formát" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "Pripojené %s do %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; ignoruje sa preváženie tohto kľúÄa.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " a --strict bolo zadané; ukonÄuje sa.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Ignoruje sa preváženie tohto kľúÄa.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "neurobí sa niÄ.\n" + +#~ msgid "No such method '%s'" +#~ msgstr "Neexistuje metóda „%s“" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Nedá sa urÄiÅ¥ adresa zbernice z premennej prostredia " +#~ "DBUS_STARTER_BUS_TYPE – neznáma hodnota „%s“" + +#~ msgid "[ARGS...]" +#~ msgstr "[PARAMETRE...]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Zlyhalo vytvorenie doÄasného súboru: %s" + +# https://bugzilla.gnome.org/show_bug.cgi?id=658713 +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Správa má %d popisovaÄov súboru, no pole hlaviÄky uvádza %d popisovaÄov " +#~ "súboru" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Chyba: neurÄená cesta objektu.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Chyba: signál nebol urÄený.\n" + +# PM: nie som si istý +# MÄŒ: buÄ: „musí maÅ¥ plne-kvalifikovaný názov.“, alebo „musí byÅ¥ identifikovateľný plne-kvalifikovaným názvom“, majú predpísaný spôsob pomenovania. Preferoval by som prvý spôsob, +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "" +#~ "Chyba: signál musí byÅ¥ identifikovateľný plne kvalifikovaným názvom.\n" + +#~ msgid "No such interface" +#~ msgstr "Také rozhranie neexistuje" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Chyba pri získavaní zapisovateľných atribútov: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Chyba pripájania umiestnenia: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Chyba pri odpájaní pripojenia: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Chyba pri hľadaní súvisiaceho pripojenia: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Chyba pri odpájaní pripojenia: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Chyba pripájania %s: %s\n" + +#~ msgid "No files to open" +#~ msgstr "Žiadne súbory na otvorenie" + +#~ msgid "No files to delete" +#~ msgstr "Žiadne súbory na odstránenie" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Chyba pri nastavovaní atribútu: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Chyba pri vytváraní adresára „%s“: %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Chyba pri otváraní súboru „%s“: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Chyba pri Äítaní súboru „%s“: %s" + +#~ msgid "No locations gives" +#~ msgstr "Neposkytnuté žiadne umiestnenia" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Chyba pri premenovaní súboru: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Chyba pri otváraní súboru: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Chyba pri vytváraní adresára: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "menenie asociácií nie je podporované na win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Vytváranie asociácií nie je podporované na win32" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Nepodarilo sa nájsÅ¥ predvolený typ sledovania lokálneho adresára" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "Chyba pri spracovaní vstupného súboru pomocou xmllint:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "Chyba pri spracovaní vstupného súboru pomocou to-pixdata:\n" +#~ "%s" + +#~ msgid "URIs not supported" +#~ msgstr "Identifikátory URI nie sú podporované" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Súbor kľúÄov neobsahuje kÄ¾ÃºÄ â€ž%s“" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "Nepodarilo sa získaÅ¥ chybu urÄenú na spracovanie: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Zlyhalo otvorenie súboru „%s“ na zápis: fdopen() zlyhalo: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Zlyhal zápis súboru „%s“: fflush() zlyhalo: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Zlyhalo zatvorenie súboru „%s“: fclose() zlyhalo: %s" diff --git a/po/sl.po b/po/sl.po new file mode 100644 index 0000000..5ea1af7 --- /dev/null +++ b/po/sl.po @@ -0,0 +1,6451 @@ +# Slovenian translations for glib. +# Copyright (C) 2002-2006 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# +# Andraž Tori 2000. +# Matej UrbanÄiÄ , 2007–2022 . +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 16:26+0000\n" +"PO-Revision-Date: 2022-03-22 19:31+0100\n" +"Last-Translator: Matej UrbanÄiÄ \n" +"Language-Team: Slovenian GNOME Translation Team \n" +"Language: sl_SI\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" +"%100==4 ? 3 : 0);\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 3.0\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Nastavljanje privzetih programov ni podprto" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Nastavljanje programa kot nazadnje uporabljenega za vrsto datotek ni podprto" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Možnosti programa GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Prikaže možnosti programa" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "Vstopi v naÄin storitev (uporabi iz storitvenih datotek D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "PrepiÅ¡i ID programa" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Zamenjaj trenutno zagnan primerek" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "IzpiÅ¡i pomoÄ" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[UKAZ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "IzpiÅ¡i razliÄico" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "IzpiÅ¡i podatke o razliÄici in konÄaj" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Seznam znanih programov" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"IzpiÅ¡i nameÅ¡Äene programe, ki se lahko zaženejo z vodila D-Bus (po " +"datotekah .desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Zagon programa" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Zagon programa (z možnostjo doloÄitve datoteke za odpiranje)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [DATOTEKA ...]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "OmogoÄi dejanje" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Izvedi dejanje na programu" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Izpis dejanja na voljo" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "IzpiÅ¡i statiÄna dejanja za program (iz datoteke .desktop)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "UKAZ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Ukaz, za katerega naj bo izpisana pomoÄ" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "" +"DoloÄila programa v zapisu vodila D-Bus (na primer: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "DATOTEKA" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Izbirno relativno ali absolutno ime datoteke oziroma naslov URI za odpiranje" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ACTION" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Ime dejanja za zagon" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Neobvezen parameter za priklic dejanja, v zapisu GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Neznan ukaz %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Uporaba:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argumenti:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENTI ...]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Ukazi:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Z ukazom »%s help UKAZ« se izpiÅ¡e podrobna pomoÄ.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Ukaz %s zahteva ID programa, da mu neposredno sledi\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "neveljaven ID programa: »%s«\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"»%s« ne prevzema argumentov\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "povezava z vodilom D-Bus ni uspela: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "Napaka pri poÅ¡iljanju sporoÄila %s programu: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "ime dejanja mora biti podano po doloÄilu id programa\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"neveljavno ime dejanja: »%s«\n" +"imena dejanj lahko tvorijo le Å¡tevilke in Ärke, vezaj » - « in pika » . «.\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "napaka razÄlenjevanja parametra dejanja: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "dejanja prejemajo najveÄ en parameter\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "ukaz list-actions zahteva le id programa" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "ni mogoÄe najti datoteke namizja za program %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"neprepoznan ukaz: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Prevelika vrednost Å¡tetja poslana na %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Iskanje po osnovnem pretoku ni podprto" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Ni mogoÄe razÄleniti GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Pretok je že zaprt" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "RazÄlenitev na osnovnem pretoku ni dovoljena" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Opravilo je bilo preklicano." + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Neveljaven predmet, opravilo ni zaÄeto" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Neveljavno veÄbitno zaporedje na vhodu" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Ni dovolj prostora za cilju" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Neveljavno zaporedje bajtov na vhodu pretvorbe" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Napaka med pretvorbo: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Dejanje prekinitve zagona ni podprto" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Pretvorba iz nabora znakov »%s« v »%s« ni podprta" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Ni mogoÄe odpreti pretvornika iz »%s« v »%s«" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s vrsta" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Neznana vrsta" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s vrsta datoteke" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials vsebuje neveljavne podatke" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "Na tem OS predmet GCredentials ni podprt" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Okolje ne podpira možnosti GCredentials" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "Predmet GCredentials na tem sistemu ne vsebuje ustreznega ID opravila" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Na tem OS vohljanje po poverilih ni podprto" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "NepriÄakovan prezgodnji konec pretoka" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nepodprt kljuÄ Â»%s« v vnosu naslova »%s«" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Nesmiselna kombinacija za par kljuÄ/vrednost v vnosu naslova »%s«" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Naslov »%s« ni veÄkavem (zahtevana je pot, zaÄasna mapa ali abstraktni kljuÄ)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Napaka v naslovu »%s« – atribut »%s« je nepravilno oblikovan" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Neznan ali nepodprt prenos »%s« za naslov »%s«" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Predmet naslova »%s« ne vsebuje dvopiÄja ( : )" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Transportno ime v naslovu predmeta »%s« ne sme biti prazno polje" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "Par kljuÄ/vrednost %d, »%s« v predmetu naslova »%s« ne vsebuje enaÄaja" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Par kljuÄ/vrednost %d, »%s« v predmetu naslova »%s« ne sme vsebovati " +"praznega kljuÄa" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Napaka neubežnega kljuÄa ali vrednosti v paru kljuÄ/vrednost %d, »%s«, v " +"predmetu naslova »%s«" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Napaka v naslovu »%s« – prenos unix zahteva enega izmed kljuÄev »path« ali " +"»abstract«" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Napaka v naslovu »%s« – atribut gostitelja manjka ali pa je nepravilno " +"oblikovan" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Napaka v naslovu »%s« – manjka atribut vrat ali pa ali je nepravilno " +"oblikovan" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Napaka v naslovu »%s« – atribut enkratne datoteke manjka ali pa je " +"nepravilno oblikovan" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Napaka samodejnega zaganjanja: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Napaka med odpiranjem enkratne datoteke »%s«: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Napaka med branjem iz enkratne datoteke »%s«: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Napaka med branjem iz enkratne datoteke »%s«; priÄakovanih 16 bajtov, " +"pridobljenih pa %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Napaka med pisanjem vsebine enkratne datoteke »%s« v pretok:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Podan naslov je prazen." + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "" +"Ni mogoÄe oživiti vodila sporoÄila, Äe je nastavljena možnost AT_SECURE" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ni mogoÄe oživiti vodila sporoÄila brez predmeta machine-id: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Ni mogoÄe samodejno zagnati vodila D-Bus brez nastavitve X11 $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Napaka med oživljanjem ukazne vrstice »%s«: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "Ni mogoÄe doloÄiti naslova vodila seje (ni podprto v tem OS)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Ni mogoÄe doloÄiti naslova vodila iz okoljske spremenljivke " +"DBUS_STARTER_BUS_TYPE – neznana vrednost »%s«" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ni mogoÄe doloÄiti naslova vodila, kajti okoljska spremenljivka " +"DBUS_STARTER_BUS_TYPE ni nastavljena" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Neznana vrsta vodila %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "NepriÄakovano pomanjkanje vsebine med branjem vrstice" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "NepriÄakovano pomanjkanje vsebine med (varnem) branjem vrstice" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"IzÄrpani so vsi razpoložljivi overitveni mehanizmi (poskusi: %s) " +"(razpoložljivih: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "UporabniÅ¡ki ID mora biti enak za odjemalca in strežnik" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Prekinjeno s strani GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Napaka med pridobivanjem podrobnosti mape »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Dovoljenja na mapi »%s« so napaÄno oblikovana. PriÄakovano je dovoljenje " +"0700, pridobljeno pa 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Napaka med ustvarjanjem mape »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Opravilo ni podprto" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Napaka med odpiranjem zbirke kljuÄev »%s« za branje: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Vrstica %d zbirke kljuÄev »%s« z vsebino »%s« je neustrezno oblikovana" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Prvi žeton vrstice %d zbirke kljuÄev pri »%s« z vsebino »%s« je neustrezno " +"oblikovan" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Drugi žeton vrstice %d zbirke kljuÄev pri »%s« z vsebino »%s« je neustrezno " +"oblikovana" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "PiÅ¡kotka z ID %d v zbirki kljuÄev »%s« ni mogoÄe najti" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Napaka med ustvarjanjem datoteke zaklepa »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Napaka brisanja stare datoteke zaklepa »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Napaka med zapiranjem (nepovezane) datoteke zaklepa »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Napaka med razvezovanjem datoteke zaklepa »%s«: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Napaka med odpiranjem zbirke kljuÄev »%s« za branje: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(V nadaljevanju je spodletelo tudi sproÅ¡Äanje zaklepa »%s«: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Povezava je zaprta" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "ÄŒas zakasnitve je potekel" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Med izgrajevanjem povezave s strani odjemalca so bile odkrite nepodprte " +"zastavice" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Vmesnik »org.freedesktop.DBus.Properties« na predmetu na poti %s ne obstaja" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Lastnost »%s« ne obstaja" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Lastnost »%s« ni berljiva" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Lastnost »%s« ni zapisljiva" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Napaka med nastavljanjem lastnosti »%s«: priÄakovana je vrsta »%s«, javljena " +"pa »%s«." + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Vmesnik »%s« ne obstaja" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Vmesnik »%s« na predmetu na poti %s ne obstaja" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "NaÄin »%s« ne obstaja" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Vrsta sporoÄila »%s« se ne sklada s priÄakovano vrsto »%s«" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Za vmesnik %s pri %s je predmet že izvožen" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Ni mogoÄe pridobiti lastnosti %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Ni mogoÄe doloÄiti lastnosti %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "NaÄin »%s« je vrnil vrsto »%s«, priÄakovana pa je vrsta »%s«" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "NaÄin »%s« na vmesniku »%s« s podpisom »%s« ne obstaja" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Podrejeno drevo je že izvoženo za %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Predmeta na poti »%s« ni mogoÄe najti." + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "vrsta je neveljavna" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "SporoÄilo METHOD_CALL: manjka polje glave PATH ali MEMBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "SporoÄilo METHOD_RETURN: manjka polje glave REPLY_SERIAL" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "SporoÄilo ERROR: manjka polje glave REPLY_SERIAL ali ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SporoÄilo SIGNAL: manjka polje glave PATH, INTERFACE ali MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SporoÄilo SIGNAL: polje glave PATH uporablja rezervirano vrednost /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SporoÄilo SIGNAL: polje glave INTERFACE uporablja rezervirano vrednost org." +"freedesktop.DBus.Local" + +# Double multiple plural? +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Med poskusom branja %lu bajtov je bilo prejetih le %lu" +msgstr[1] "Med poskusom branja %lu bajtov je bil prejet le %lu" +msgstr[2] "Med poskusom branja %lu bajtov sta bila prejeta le %lu" +msgstr[3] "Med poskusom branja %lu bajtov so bili prejeti le %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Po nizu »%s« je priÄakovan bajt NUL, vendar je bil zaznan %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"PriÄakovan je veljaven UTF-8 niz, vendar je najdenih nepravilno Å¡tevilo " +"bajtov na bajtnem odmiku %d (dolžina niza %d). Do takrat veljaven UTF-8 niz " +"je »%s«" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Vrednost je gnezdene pregloboko" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "RazÄlenjena vrednost »%s« ni veljavna pot predmeta vodila D-Bus" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "RazÄlenjena vrednost »%s« ni veljaven podpis vodila D-Bus" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Najdeno je polje dolžine %u bajtov, najveÄja dovoljena pa je 2<<26 bajtov " +"(64 MiB)." +msgstr[1] "" +"Najdeno je polje dolžine %u bajta, najveÄja dovoljena pa je 2<<26 bajtov (64 " +"MiB)." +msgstr[2] "" +"Najdeno je polje dolžine %u bajtov, najveÄja dovoljena pa je 2<<26 bajtov " +"(64 MiB)." +msgstr[3] "" +"Najdeno je polje dolžine %u bajtov, najveÄja dovoljena pa je 2<<26 bajtov " +"(64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Zaznano je polje vrste »'a%c«, priÄakovana pa je vrednost veÄkratnika %u " +"bajtov, zaznanih pa je %u bajtov dolžine" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "V vodilu D-Bus prazne vrednosti niso dovoljene" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "RazÄlenjena vrednost »%s« ni veljaven podpis vodila D-Bus" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Napaka med loÄevanjem GVariant iz zaporedja z vrsto niza »%s« iz D-Bus žiÄne " +"oblike" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Neveljavna vrednost vrstnega reda zlogov. PriÄakovana je ali vrednost 0x6c " +"(» l «) ali 0x42 (» B «), najdena pa je vrednost 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"Neveljavna veÄja razliÄica protokola. PriÄakovana je 1, najdenih pa jih je " +"veÄ (%d)" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Glava podpisa je najdena, vendar ni ustrezno oblikovana" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Glava podpisa s podpisom »%s« je najdena, vendar je telo sporoÄila prazno" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "RazÄlenjena vrednost »%s« ni veljaven podpis vodila D-Bus (za telo)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"V sporoÄilu ni glave podpisa, vendar je telo sporoÄila dolgo %u bajtov" +msgstr[1] "" +"V sporoÄilu ni glave podpisa, vendar je telo sporoÄila dolgo %u bajt" +msgstr[2] "" +"V sporoÄilu ni glave podpisa, vendar je telo sporoÄila dolgo %u bajta" +msgstr[3] "" +"V sporoÄilu ni glave podpisa, vendar je telo sporoÄila dolgo %u bajte" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "SporoÄila ni mogoÄe loÄiti iz zaporedja: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Napaka pri združevanju GVariant v zaporedje z vrsto niza »%s« v D-Bus žiÄno " +"obliko" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "Å tevilo opisnikov v sporoÄilu (%d) se razlikuje od polja glave (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "SporoÄila ni bilo mogoÄe združiti v zaporedje: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Telo sporoÄila ima podpis »%s«, vendar v glavi ni podpisa" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Telo sporoÄila ima podpis vrste »%s«, vendar je podpis v polju glave »%s«" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Telo sporoÄila je prazno, vendar je v polju glave podpis »(%s)«" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Napaka vrnjena s telesom vrste »%s«" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Napaka vrnjena s praznim telesom" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(S pritiskom na katerikoli znak, se okno zapre)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Vodilo seje DBus ni zagnano, zato je samodejni zagon spodletel" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Ni mogoÄe pridobiti strojnega profila: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Ni mogoÄe naložiti %s oziroma %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Napaka med klicanjem predmeta StartServiceByName za %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "NepriÄakovan odgovor %d iz naÄina StartServiceByName(»%s«)" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ni mogoÄe sklicati naÄina; posredniÅ¡ki strežnik za znano ime %s brez " +"lastnika je bil zgrajen z zastavico G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstraktni imenski prostor ni podprt" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Med ustvarjanjem strežnika ni mogoÄe doloÄiti enkratne datoteke" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Napaka med zapisovanjem enkratne datoteke na »%s«: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Niz »%s« ni veljaven D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Na nepodprtem naÄinu prenosa »%s« ni mogoÄe posluÅ¡ati" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Ukazi:\n" +" help Prikaže te podrobnosti\n" +" introspect Samo-preveri oddaljen predmet\n" +" monitor Nadzoruje oddaljen predmet\n" +" call PokliÄe metodo nad oddaljenim predmetom\n" +" emit Odda signal\n" +" wait Zahteva prikaz imena vodila\n" +"\n" +"Uporabite »%s COMMAND --help« za pomoÄ o posameznem ukazu.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Napaka: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Napaka med samopreverjanjem XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Napaka: %s ni veljavno ime\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Napaka: %s ni veljavna pot predmeta\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Poveži s sistemskim vodilom" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Poveži z vodilom seje" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Poveži s podanim naslovom vodila D-Bus" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Možnosti konÄnih toÄk povezave:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Možnosti, ki doloÄajo konÄne toÄke povezave" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Ni doloÄene konÄne toÄke povezave" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "DoloÄenih je veÄ povezav konÄne toÄke" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Opozorilo: na osnovi podatkov samopregleda, vmesnik »%s« ne obstaja\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Opozorilo: na osnovi podatkov samopregleda, naÄin »%s« ne obstaja na " +"vmesniku »%s«\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Izbirni cilj za signal (enoznaÄno ime)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Pot predmeta za oddajanje signala" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Ime signala in vmesnika" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Oddaj signal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Napaka med povezovanjem: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Napaka: %s ni veljavno enoznaÄno ime vodila.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Napaka: pot predmeta ni doloÄena\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Napaka: ime signala ni doloÄeno\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Napaka: ime signala »%s« ni veljavno\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Napaka: %s ni veljavno ime vmesnika.\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Napaka: %s ni veljavno ime predmeta.\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Napaka med razÄlenjevanjem parametra %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Napaka med poÄiÅ¡Äenjem povezave: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Ime cilja za sklicanje naÄina" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Pot do predmeta za sklicanje naÄina" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Ime naÄina in vmesnika" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "ÄŒasovni zamik v sekundah" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Dovoli interaktivno overjanje" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "SkliÄi naÄin na oddaljenem predmetu." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Napaka: cilj ni doloÄen\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Napaka: %s ni veljavno ime vodila\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Napaka: ime naÄina ni doloÄeno\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Napaka: ime naÄina »%s« ni veljavno\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Napaka med razÄlenjevanjem parametra %d vrste »%s«: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Napaka med dodajanjem roÄnika: %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Samopreverjanje ciljnega imena" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Samopreverjanje poti predmeta" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Natisni XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Samopreverjanje podrejenih predmetov" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Natisni le lastnosti" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Samopreverjanje oddaljenega predmeta." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Nadzor ciljnega imena" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Nadzor poti predmeta" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Nadzoruj oddaljeni predmet." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Napaka: ni mogoÄe nadzirati povezav mimo sporoÄilnega vtiÄa\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Storitev, ki naj se zaÄne, preden zaÄne program Äakati na drugo (ime)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"ÄŒasovni zamik, po katerem je program konÄan z napako (v sekundah); vrednost " +"0 onemogoÄi zamik (privzeto)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[MOŽNOST …] IME-VODILA" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "PoÄakaj na izpis imena vodila." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Napaka: storitev za omogoÄanje mora biti doloÄena.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "" +"Napaka: storitev za Äakanje mora biti doloÄena.\n" +"\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Napaka: navedenih je preveÄ argumentov.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Napaka: %s ni veljavno enoznaÄno ime vodila.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "" +"Za spreminjanje nastavitev razhroÅ¡Äevanja so zahtevana posebna dovoljenja" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Neimenovano" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Namizna datoteka ne vsebuje doloÄenega polja Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Ni mogoÄe najti terminala, ki ga zahteva program" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Ni mogoÄe ustvariti nastavitvene mape uporabnikovega programa %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Ni mogoÄe ustvariti uporabnikove nastavitvene mape MIME %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Podatki programa so brez doloÄila" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Ni mogoÄe ustvariti uporabnikove datoteke namizja %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "DoloÄilo po meri za %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "pogona ni mogoÄe izvreÄi" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "pogon ne vkljuÄuje ukaza izvrzi ali izvrzi_z_dejanjem" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "pogon ne podpira preverjanja enote" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "pogon ne vkljuÄuje možnosti zagona" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "pogon ne vkljuÄuje možnosti zaustavitve" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "Ozadnji program TLS ne vkljuÄuje pridobivanje vezi TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Podpora TLS ni na voljo" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Podpora za DTLS ni na voljo" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Ni mogoÄe upravljati z razliÄico %d kodiranja GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Nepravilno oblikovana znakov (%d) v kodiranju GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Ni mogoÄe upravljati z razliÄico %d kodiranja GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Nepravilno oblikovana znakov (%d) v kodiranju GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "PriÄakovan GEmblem za GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "ObstojeÄa enota ne obstaja" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Ni mogoÄe kopirati prek mape" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Ni mogoÄe kopirati mape prek mape" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Ciljna datoteka obstaja" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Ni mogoÄe kopirati drevesne zgradbe map" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Splice ni podprt" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Napaka med prepletanjem datoteke: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"Kopiranje (sklic povezave/kloniranje) med razliÄnimi priklopi ni podprto" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopiranje (sklic povezave/kloniranje) ni podprto ali pa ni veljavno" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopiranje (sklic povezave/kloniranje) ni podprto, ali pa ni delovalo" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Ni mogoÄe kopirati posebne datoteke" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Neveljavna vrednost simbolne povezave" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Simbolne povezave niso podprte" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Smeti niso podprte" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Ni mogoÄe uporabiti »%c« v imenu datoteke" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "enota ne podpira priklopa" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Na voljo ni programa z a upravljanje s to datoteko" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Å tevilÄnik je zaprt" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Å tevilÄnik izvaja izredno dejanje" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Å tevilÄnik datotek je že zaprt" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Ni mogoÄe upravljati z razliÄico %d kodiranja GFileIcon" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Nepravilno oblikovani podatki za GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Pretok ne podpira query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Iskanje po pretoku ni podprto" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "RazÄlenitev ni dovoljena na dovodnem pretoku" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "RazÄlenitev ni podprta na pretoku" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Neveljavno ime gostitelja" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Neustrezen odziv posredniÅ¡kega strežnika HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Overitev s posredniÅ¡kim strežnikom HTTP ni dovoljena" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Overitev s posredniÅ¡kim strežnikom HTTP je spodletala" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Zahtevana je overitev s posredniÅ¡kim strežnikom HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Povezava s posredniÅ¡kim strežnikom HTTP je spodletela: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Odziv posredniÅ¡kegam strežnika HTTP je preobsežen." + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Povezava s posredniÅ¡kim strežnikom HTTP je nepriÄakovano konÄana." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "NapaÄno Å¡tevilo znakov (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Ni doloÄenega imena razreda %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Vrsta %s ne vstavlja vmesnika GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Vrste %s ni uvrÅ¡Äena v razred" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Nepravilno oblikovana Å¡tevilka razliÄice: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Vrsta %s ne vstavlja from_tokens() vmesnika GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Ni mogoÄe ravnati z navedeno razliÄico kodiranja ikone" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Naslov ni naveden" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Dolžina %u je predolga za naslov" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Naslov ima doloÄene bite prek dolžine predpone" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Ni mogoÄe razÄleniti »%s« kot maske naslova IP" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Ni dovolj prostora za naslov vtiÄa" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nepodprti naslov vtiÄa" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Vhodni pretok ne podpira branja" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Pretok izvaja izredno dejanje" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopiraj z datoteko" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Ohrani z datoteko ob premikanju" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "»razliÄica« ne prevzema argumentov" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Uporaba:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "IzpiÅ¡i podatke o razliÄici in konÄaj." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Ukazi:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Spoji datoteke in jih izpiÅ¡i na standardni izhod" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopiraj eno ali veÄ datotek" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Pokaži podatke o mestih" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Zagon programa iz datoteke namizja" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "IzpiÅ¡i seznam vsebine mest" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Pridobi ali doloÄi roÄnik za vrsto MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Ustvarite mape" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Spremljaj spremembe datotek in map" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Priklop oziroma odklop mest" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Premakni eno ali veÄ datotek" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Odpri datoteke s privzetim programom" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Preimenuj datoteko" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "IzbriÅ¡i eno ali veÄ datotek" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Preberi prek standardnega vhoda in shrani" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "DoloÄi atribut datoteke" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Premakni datoteke in mape v smeti" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "IzpiÅ¡i vsebino v drevesni obliki" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Z ukazom %s se izpiÅ¡e podrobna pomoÄ.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Napaka med pisanjem v standardni odvod" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "MESTO" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Spoji datoteke in jih izpiÅ¡i na standardni izhod." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"Program gio cat deluje enako kot ukaz cat z razliko, da uporablja\n" +"oddaljen GIO namesto krajevnih poti do datotek. Primer: kot pot je\n" +"mogoÄe uporabiti smb://strežnik/vir/datoteka.txt." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Ni podanih mest" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ni ciljne mape" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Pokaži napredek" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Opozori pred prepisovanjem" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Ohrani vse atribute" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Varnostno kopiraj obstojeÄe ciljne datoteke" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Nikoli ne sledi simbolnim povezavam" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Uporabi privzeta dovoljenja za ciljno mesto" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Preneseno %s od %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "VIR" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "CILJ" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopiraj eno ali veÄ datotek iz VIRA na CILJ." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"Program gio copy deluje enako kot ukaz cp z razliko, da uporablja\n" +"oddaljen GIO namesto krajevnih poti do datotek. Primer: kot pot je\n" +"mogoÄe uporabiti smb://strežnik/vir/datoteka.txt." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "CIljni predmet %s ni mapa" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: Ali želite prepisati »%s«? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "IzpiÅ¡i zapisljive atribute" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Pridobi podrobnosti datoteÄnega sistema" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Zahtevani atributi" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATRIBUTI" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ne sledi simbolnim povezavam" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "atributi:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "prikaži ime: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "uredi ime: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "ime: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "vrsta: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "velikost: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "skrito\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "naslov URI: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "Krajevna pot: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "priklopna toÄka unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Nastavljivi atributi:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Imenski prostor zapisljivih atributov:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Pokaže podatke o mestih." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"Program gio info deluje enako kot ukaz ls z razliko, da uporablja\n" +"oddaljen GIO namesto krajevnih poti do datotek. Primer: kot pot je\n" +"mogoÄe uporabiti smb://strežnik/vir/datoteka.txt. Atributi datoteke\n" +"so lahko navedeni z imeni GIO, na primer standard::ikona, ali pa le z\n" +"imenskim prostorom, na primer: unix ali z » * «, ki ustreza vsem." + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DATOTEKA-NAMIZJA [ARGUMENT …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Zagon programa prek datoteke desktop skupaj z izbirnimi argumenti ukaza." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Ni nobene podane datoteke namizja" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Ukaz za zagon trenutno v tem okolju ni podprt." + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Ni mogoÄe naložiti »%s«: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Ni mogoÄe naložiti podrobnosti programa »%s«." + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Ni mogoÄe zagnati programa »%s«: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Pokaži skrite datoteke" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Uporabi zapis v dolgi obliki" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "IzpiÅ¡i prikazna imena" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "IzpiÅ¡i celotne naslove URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "IzpiÅ¡i vsebino mest." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"Program gio list deluje enako kot ukaz ls z razliko, da uporablja\n" +"oddaljen GIO namesto krajevnih poti do datotek. Primer: kot pot je\n" +"mogoÄe uporabiti smb://strežnik/vir/datoteka.txt. Atributi datoteke\n" +"so lahko navedeni z imeni GIO, na primer standard::ikona." + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "VRSTA-MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "ROÄŒNIK" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Pridobi ali doloÄi roÄnik za vrsto MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"ÄŒe roÄnik ni podan, se izpiÅ¡e seznam priporoÄene programske\n" +"opreme za vrsto MIME, Äe pa je podan, je doloÄen kot privzet\n" +"roÄnik za to vrsto MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "DoloÄiti je treba eno vrsto MIME in pogojno roÄnik" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Ni privzetega programa za »%s«\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Privzet program za »%s«: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Vpisani programi:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Ni vpisanih programov.\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "PriporoÄeni programi:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Ni priporoÄenih programov.\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Nalaganje podrobnosti roÄnika »%s« je spodletelo." + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "DoloÄanje »%s« kot privzet roÄnik za »%s« je spodletelo: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Ustvari nadrejene mape" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Ustvarjanje map" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"Program gio mkdir deluje enako kot ukaz mkdir z razliko, da uporablja\n" +"oddaljen GIO namesto krajevnih poti do datotek. Primer: kot pot je\n" +"mogoÄe uporabiti smb://strežnik/vir/mapa." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Nadzor mape (privzeto: odvisno od vrste)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Nadzor datoteke (privzeto: odvisno od vrste)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Nadzira spremembe datotek (prek trdih povezav)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Nadzira datoteko, vendar ne shranjuje poroÄil sprememb" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Zabeleži premikanja in preimenovanja kot enostavne dogodke izbrisano/" +"ustvarjeno" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Spremljaj dogodke priklopne toÄke" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Spremljaj spremembe map in datotek." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "priklopi kot priklopno" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Priklopi nosilec z datoteko naprave oz. drugim doloÄilnikom" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Odklopi" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Izvrzi" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Zaustavi pogon z datoteko naprave" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "NAPRAVA" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Odklopi vse priklope s podano shemo" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SHEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "" +"Prezri opravila datotek med odklapljanjem oziroma izmetavanjem priklopa" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Uporabni brezimne podatke za overjanje" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Seznam" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Nadzor dogodkov" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Pokaži dodatne podrobnosti" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Å tevilska koda PIM za odklepanje razdelka VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Priklopi skrit razdelek TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Priklopi sistemski razdelek TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Brezimen dostop ni dovoljen!" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Ni doloÄenega pogona za datoteko naprave" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Ni nosilca za podano doloÄilo ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Priklop oziroma odklop razliÄnih nosilcev" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ne ustvari kopije in izbriÅ¡i povrnitvene datoteke" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Premakni datoteke iz VIRA na CILJ." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"Program gio move deluje enako kot ukaz mv z razliko, da uporablja\n" +"oddaljen GIO namesto krajevnih poti do datotek. Primer: kot pot je\n" +"mogoÄe uporabiti smb://strežnik/vir/datoteka.txt." + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Cilj %s ni mapa" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Odpre datoteke s privzetim programom, ki\n" +"je nastavljen za odpiranje te vrste datotek." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Prezri neobstojeÄe datoteke in ne opozarjaj" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "IzbriÅ¡i podane datoteke." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "IME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Preimenovanje datoteke" + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Manjka argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Navedenih je preveÄ argumentov" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Preimenovanje je bilo uspeÅ¡no. Nov naslov URI: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Ustvari le, Äe ne obstaja" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Pripni na konec datoteke" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Med ustvarjanjem omeji dostop trenutnemu uporabniku" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Med zamenjavo zamenjaj ciljno mesto, kot da to Å¡e ne obstaja." + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Natisni novo oznako etag na koncu" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Oznaka Etag datoteke, ki bo prepisana" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Napaka branja prek standardnega dovoda" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Oznaka Etag ni na voljo\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Preberi preko standardnega vhoda in shrani na CILJ." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Ni podanega cilja" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Vrsta atributa" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "VRSTA" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VREDNOST" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "DoloÄitev atributa MESTA za datoteko" + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Mesto ni doloÄeno" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Atribut ni doloÄen" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Vrednost ni doloÄena" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Neveljavna vrsta atributa »%s«" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Izprazni smeti" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "IzpiÅ¡i seznam datotek v smeteh z navedbo izvornega mesta." + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Obnovi datoteko iz smeti na njeno izvorno mesto (upoÅ¡tevajoÄ drevesno " +"strukturo)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Ni mogoÄe doloÄiti izvorne poti." + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Ni mogoÄe poustvariti izvornega mesta: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Ni mogoÄe premakniti datoteke na njeno izvorno mesto: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Premakni/Obnovi datoteke in mape v smeteh." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Opomba: Äe izvorna datoteka že obstaja in je uporabljen argument --restore,\n" +"ta ne bo prepisana, Äe ni uporabljen tudi argument --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Podano mesto se ne zaÄne z trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Sledi simbolnim povezavam, priklopom in bližnjicam map" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "IzpiÅ¡i seznam vsebine map v drevesni obliki." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Predmet <%s> ni dovoljen znotraj predmeta <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Predmet <%s> ni dovoljen na vrhnji ravni" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Datoteka %s se v viru pojavi veÄkrat" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Datoteke »%s« ni mogoÄe najti v nobeni mapi virov" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Datoteke »%s« ni mogoÄe najti v trenutni mapi" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Neznana možnost obdelovanja »%s«" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Zahtevan ja atribut %s, vendar spremenljivka %s ni nastavljena, orodje " +"ukazne vrstice %s pa ni vpisano na poti PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Napaka med branjem datoteke %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Napaka med stiskanjem datoteke %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "besedilo se ne sme pojaviti znotraj <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "IzpiÅ¡i podrobnosti razliÄice in konÄaj" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Ime izhodne datoteke" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Mape, iz katerih naj bodo prebrane datoteke (privzeto je to trenutna mapa)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "MAPA" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Ustvari odvod v obliki, izbrani s pripono imena ciljne datoteke" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Ustvari glavo vira" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Ustvari izvorno kodo za povezavo datoteke virov z vaÅ¡o kodo" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Ustvari seznam odvisnosti." + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Ime ustvarjene datoteke odvisnosti za ustvarjanje" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "VkljuÄi lažne cilje v ustvarjeni datoteki odvisnosti" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Vira ne ustvari in ne vpiÅ¡i samodejno" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ne izvozi funkcij; te je treba deklarirati v G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "Ne vgrajuj podatkov vira v datoteko C; predvidi zunanjo povezavo" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "DoloÄilo imena jezika C za ustvarjanje izvorne kode" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Ciljni prevajalnik C (privzeto: okoljska spremenljivka CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kodno prevedi doloÄilo vira v datoteko vira.\n" +"Datoteke doloÄil vira imajo pripone .gresource.xml,\n" +"datoteke vira pa pripono .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Podati je treba natanko eno ime datoteke\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "vzdevek mora vsebovati najmanj 2 znaka" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Neveljavna Å¡tevilÄna vrednost" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " je že doloÄeno" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr " je že doloÄena" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "zastavice morajo biti nastavljene vsaj kot 1 bitni niz" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> oznaka mora vsebovati vsaj eno " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> ni znotraj doloÄenega obsega" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> ni veljavni Älan doloÄene oÅ¡tevilÄene vrste" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> vsebuje niz, ki ni med doloÄenimi vrstami zastavic" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> vsebuje niz, ki ni med izbirami " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " je za ta kljuÄ Å¾e doloÄen" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ni dovoljena vrednost vrste »%s«" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "najmanjÅ¡a vrednost je veÄja od najveÄje vrednosti" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "nepodprta kategorija l10n: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "zahtevan je predmet l10n, vendar pa ni podana domena gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "podan je prevod, ni pa omogoÄena podpora za l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "RazÄlenjevanje vrednosti vrste »%s« je spodletelo: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr " ni mogoÄe doloÄiti za kljuÄe, oznaÄene kot oÅ¡tevilÄene vrste" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " so za ta kljuÄ Å¾e doloÄene" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ni dovoljena vrednost vrste »%s«" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " je že podano" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr "vrednost mora vsebovati vsaj en " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " je za ta kljuÄ Å¾e doloÄen" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" je mogoÄe doloÄiti le za kljuÄe z oÅ¡tevilÄenimi vrednostmi, z " +"vrsto zastavic ali za " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +"vrednost je podana, Äeprav je »%s« že veljaven Älan " +"oÅ¡tevilÄene vrste" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" je podano, vendar je že podan given" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " je že doloÄeno" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "cilj vzdevka »%s« ni oÅ¡tevilÄene vrste" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "cilj vzdevka »%s« ni med izbirami " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr "vrednost mora vsebovati vsaj en " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Prazna polja imen niso dovoljena." + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Neveljavno ime »%s«: imena se morajo zaÄeti z malo Ärko." + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Neveljavno ime »%s«: neveljaven znak »%c«; dovoljene so samo male Ärke, " +"Å¡tevilke in vezaj (» - «)." + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Neveljavno ime »%s«: zaporedna vezaja (» -- «) nista dovoljena." + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Neveljavno ime »%s«: zadnji znak ne sme biti vezaj (» - «)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Neveljavno ime »%s«: najveÄja dolžina je 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " je že doloÄeno" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Shemi »list-of« ni mogoÄe dodati kljuÄev." + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " je že doloÄeno" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" sence v ; za spreminjanje " +"vrednosti uporabite " + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Natanko ena izmed možnosti »vrste«, »enum« ali »zastavice« mora biti " +"doloÄena kot lastnost kljuÄa " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id=»%s«> (Å¡e) ni doloÄen." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Neveljavna vrsta niza GVariant »%s«" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " je podan, vendar shema ne razÅ¡irja niÄesar" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr " za prepis ni na voljo" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " je že doloÄeno" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " je že doloÄeno" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " razÅ¡irja Å¡e neobstojeÄo shemo »%s«" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " je seznam Å¡e neobstojeÄe sheme »%s«" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Seznam sheme s potjo ni mogoÄ" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Sheme ni mogoÄe razÅ¡iriti s potjo" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " je seznam, ki razÅ¡irja , ki ni seznam" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" razÅ¡irja vendar " +"»%s« ne razÅ¡irja »%s«" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Pot, Äe je podana, se mora zaÄeti in konÄati s poÅ¡evnico" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Pot seznama se mora konÄati z » :/ «" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Opozorilo: shema »%s« ima doloÄeno pot »%s«. Poti, ki se zaÄnejo z »/apps/«, " +"»/desktop/« ali »/system/« so opuÅ¡Äene." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id=»%s«> je že doloÄeno" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Le en predmet <%s> je lahko znotraj predmeta <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Predmet <%s> na vrhnji ravni ni dovoljen" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Predmet mora biti zapisan v kljuÄu " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Besedilo se ne sme pojaviti znotraj <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Opozorilo: neveljaven sklic na " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "doloÄena je zastavica --strict; opravilo bo preklicano." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Celotna datoteka je prezrta." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Datoteka je prezrta." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"KljuÄ Â»%s« v shemi »%s« kot je doloÄen v datoteki prepisa »%s« ne obstaja. " +"Prepis za ta kljuÄ bo prezrt." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"KljuÄ Â»%s« v shemi »%s« kot je doloÄen v datoteki prepisa »%s« ne obstaja, " +"doloÄena je tudi zastavica --strict. Opravilo je prekinjeno." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Ni mogoÄe uporabiti prepisa jezikovno prilagojenega kljuÄa »%s« za namizje v " +"shemi »%s« (prepisna datoteka »%s«). Prepis za ta kljuÄ bo prezrt." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Ni mogoÄe uporabiti prepisa jezikovno prilagojenega kljuÄa »%s« za namizje v " +"shemi »%s« (prepisna datoteka »%s«), doloÄena je tudi zastavica --strict. " +"Opravilo je prekinjeno." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Napaka razÄlenjevanja kljuÄa »%s« v shemi »%s« kot je doloÄen v datoteki " +"prepisa »%s«: %s. Prepis za ta kljuÄ bo prezrt." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Napaka razÄlenjevanja kljuÄa »%s« v shemi »%s« kot je doloÄen v datoteki " +"prepisa »%s«: %s. DoloÄena je bila zastavica --strict; opravilo je " +"preklicano." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Prepis za kljuÄ Â»%s« v shemi »%s« v datoteki prepisa »%s« ni v obsegu, " +"podanem v shemi. Prepis za ta kljuÄ bo prezrt." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Prepis za kljuÄ Â»%s« v shemi »%s« v datoteki prepisa »%s« ni v obsegu, " +"podanem v shemi, doloÄena je tudi zastavica --strict. Opravilo je prekinjeno." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Prepis za kljuÄ Â»%s« v shemi »%s« v datoteki prepisa »%s« ni v seznamu " +"veljavnih možnosti. Prepis za ta kljuÄ bo prezrt." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Prepis za kljuÄ Â»%s« v shemi »%s« v datoteki prepisa »%s« ni v seznamu " +"veljavnih možnosti, doloÄena je tudi zastavica --strict. Opravilo je " +"prekinjeno." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Kje naj se shrani datoteka gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Prekini ob vsakrÅ¡ni napaki v shemi" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Ne zapiÅ¡i datoteke gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Ne vsili omejitev imena kljuÄa" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kodno prevedi vse datoteke shem GSetting v predpomnilnik.\n" +"sheme. Datoteke shem morajo imeti pripono .gschema.xml,\n" +"datoteka predpomnilnika pa se imenuje gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Podati je treba natanko eno ime mape" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Datotek sheme ni mogoÄe najti: opravilo bo preklicano." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Datotek sheme ni mogoÄe najti: obstojeÄa odvodna datoteka je odstranjena." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Neveljavno ime datoteke %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Napaka med pridobivanjem podrobnosti datoteÄnega sistema za %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Priklopne toÄke datoteke %s ni mogoÄe najti" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Ni mogoÄe preimenovati korenske mape" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Napaka med preimenovanjem datoteke %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Ni mogoÄe preimenovati datoteke, izbrano ime že obstaja" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Neveljavno ime datoteke" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Napaka med odpiranjem datoteke %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Napaka med odstranjevanjem datoteke %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Napaka med premikanjem datoteke %s v smeti: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Ni mogoÄe ustvariti mape smeti %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Ni mogoÄe najti vrhnje ravni smeti %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"Kopiranje (sklic povezave/kloniranje) med razliÄnimi priklopi ni podprto" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Ni mogoÄe najti oziroma ustvariti mape smeti %s za brisanje %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Ni mogoÄe ustvariti datoteke podrobnosti smeti za %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "" +"Datoteke %s ni mogoÄe premakniti v smeti prek razliÄnih datoteÄnih sistemov" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Datoteke %s ni mogoÄe premakniti v smeti: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Datoteke %s ni mogoÄe premakniti v smeti" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Napaka med ustvarjanjem mape %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "DatoteÄni sistem ne podpira simbolnih povezav" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Napaka med ustvarjanjem simbolne povezave %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Napaka med premikanjem datoteke %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Ni mogoÄe premakniti mape Äez mapo" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Ustvarjanje varnostne kopije je spodletelo." + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Napaka med odstranjevanjem ciljne datoteke: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Premikanje med priklopi ni podprto" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ni mogoÄe doloÄiti porabe diska %s: %s." + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Vrednost atributa ni mogoÄe doloÄiti kot NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Neveljavna vrsta atributa (priÄakovan niz)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Neveljavno razÅ¡irjeno ime atributa" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Napaka med doloÄanjem razÅ¡irjenega atributa »%s«: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (neveljavni nabor znakov)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Napaka med pridobivanjem podatkov za datoteko »%s«: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Napaka med potrjevanjem opisovalnika datoteke: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Neveljavna vrsta atributa (priÄakovan uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Neveljavna vrsta atributa (priÄakovan uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Neveljavna vrsta atributa (priÄakovan bitni niz)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Ni mogoÄe doloÄiti dovoljenj simbolnih povezav" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Napaka med doloÄanjem dovoljenj: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Napaka med doloÄanjem lastnika: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "Simbolna povezava ne sme biti doloÄena kot NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Napaka med doloÄanjem simbolne povezave: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"Napaka med doloÄevanjem simbolne povezave; datoteka ni simbolna povezava" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Dodatne nanosekunde %d za Äasovni žig UNIX %lld so negativne" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Dodatne nanosekunde %d za Äasovni žig UNIX %lld so dosegle 1 sekundo" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "ÄŒasovni žig UNIX %lld je prevelik za 64-bitni zapis" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"ÄŒasovni žig UNIX %lld je izven obsega, ki je podprt na sistemih MS Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Imena datoteke »%s« ni mogoÄe pretvoriti v zapis UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Datoteke »%s« ni mogoÄe odpreti: napaka Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Napaka med doloÄanjem sprememb ali Äasa dostopa za datoteko »%s«: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Napaka med doloÄanjem sprememb ali Äasa dostopa: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Atributa SELinux ni mogoÄe doloÄiti kot NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "Na tem sistemu SELinux ni omogoÄen" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Napaka nastavitve vsebine SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "DoloÄanje atributa %s ni podprto" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Napaka med branjem iz datoteke: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Napaka med zapiranjem datoteke: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Napaka med iskanjem v datoteki: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Ni mogoÄe najti privzete krajevne datoteke nadzora" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Napaka med pisanjem v datoteko: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Napaka med odstranjevanjem stare varnostne povezave: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Napaka med ustvarjanjem varnostne kopije: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Napaka med preimenovanjem zaÄasne datoteke: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Napaka med obrezovanjem datoteke: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Napaka med odpiranjem datoteke »%s«: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Ciljna datoteka je mapa" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Ciljna datoteka ni obiÄajna datoteka" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Datoteka je bila zunanje spremenjena" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Napaka med odstranjevanjem datoteke: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Privzet neveljaven GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Neveljavna zahteva iskanja" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ni mogoÄe razÄleniti GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Odvoda pretoka pomnilnika ni mogoÄe razÅ¡iriti" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "RazÅ¡irjanje pretoka odvoda pomnilnika je spodletelo." + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"KoliÄina pomnilnika zahtevana za pisanje je veÄja kot je razpoložljivi " +"prostor naslova" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Zahtevano iskanje pred zaÄetkom pretoka" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Zahtevano iskanje za koncem pretoka" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "enota ne podpira možnosti »odklopi«" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "enota ne podpira možnosti »izvrzi«" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "enota ne podpira možnosti »odklopi« ali »odklopi z dejanjem«" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "enota ne podpira možnosti »izvrzi« ali »izvrzi z dejanjem«" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "enota ne podpira možnosti »ponovnega priklopa«" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "priklop ne podpira ugibanja vsebine vrste" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "priklop ne podpira usklajevanja ugibanja vsebine vrste" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Ime gostitelja »%s« vsebuje » [ «, ne pa tudi » ] «" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Omrežje ni dosegljivo" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Gostitelj ni dosegljiv" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ni mogoÄe ustvariti nadzornika omrežja: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Ni mogoÄe ustvariti nadzornika omrežja: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Ni mogoÄe pridobiti stanja omrežja: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "Program NetworkManager ni zagnan" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "RazliÄica programa NetworkManager je prestara" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Odvodni pretok ne podpira pisanja" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Vsota vektorjev, poslanih na %s, je prevelika." + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Izvorni pretok je že zaprt" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Napaka med razreÅ¡evanjem »%s«: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "Za funkcijo %s ni zagotovljene podpore." + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Neveljavna domena" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Vir »%s« ne obstaja." + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Vira »%s« ni mogoÄe razÅ¡iriti" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Vir »%s« ni mapa." + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Vhodni pretok ne podpira iskanja" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "IzpiÅ¡i seznam odsekov, ki vsebujejo vire v DATOTEKI elf" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"IzpiÅ¡i seznam virov\n" +"ÄŒe je ODSEK podan, izpiÅ¡i le vire iz tega odseka\n" +"ÄŒe je podana POT, izpiÅ¡i le skladne vire" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "DATOTEKA [POT]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "ODSEK" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"IzpiÅ¡i seznam virov s podrobnostmi\n" +"ÄŒe je ODSEK podan, izpiÅ¡i le vire iz tega odseka\n" +"ÄŒe je podana POT, izpiÅ¡i le ujemajoÄe vire\n" +"Podrobnosti vsebujejo odsek, velikost in stiskanje" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "RazÅ¡iri datoteko vira na standardni odvod" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "DATOTEKA POT" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uporaba:\n" +" gresource [--section ODSEK] UKAZ [ARGUMENTI ...]\n" +"\n" +"Ukazi:\n" +" help IzpiÅ¡i to besedilo\n" +" sections IzpiÅ¡i odseke vira\n" +" list IzpiÅ¡i vire\n" +" details IzpiÅ¡i vire s podrobnostmi\n" +" extract IzluÅ¡Äi vir\n" +"\n" +"Z ukazom »gresource help UKAZ« pridobite podrobno pomoÄ.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uporaba:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " ODSEK Ime (izbirno) izbora elf\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " UKAZ Ukaz (izbirno) za razlago\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " DATOTEKA Datoteka elf (dvojiÅ¡ka ali skupna knjižnica)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" DATOTEKA Datoteka elf (dvojiÅ¡ka ali skupna knjižnica)\n" +" ali prevedena datoteka vira\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[POT]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " POT Dodatna (neobvezna) pot vira (lahko je delna)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "POT" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " POT Pot vira\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Shema »%s« ne obstaja.\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Shema »%s« ni dodeljiva (pot ne sme biti doloÄena)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Shema »%s« je dodeljiva (pot mora biti doloÄena)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Pot ni podana.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Zapis poti se mora zaÄeti s poÅ¡evnico (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Zapis poti se mora konÄati s poÅ¡evnico (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Pot ne sme vsebovati dveh zaporednih poÅ¡evnic (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Ponujena vrednost je izven veljavnega obmoÄja\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "KljuÄ ni zapisljiv\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "IzpiÅ¡i nameÅ¡Äene (nedodeljive) sheme" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Seznam naloženih dodeljivih SHEM" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "IzpiÅ¡i seznam kljuÄev SHEME" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SHEMA[:POT]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "IzpiÅ¡i seznam podrejenih predmetov SHEME" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Rekurzivno izpiÅ¡i kljuÄe in vrednosti,\n" +"Äe ni podana SHEMA, pa izpiÅ¡i vse kljuÄe\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SHEMA[:POT]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Pridobi vrednost KLJUÄŒA" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SHEMA[:POT] KLJUÄŒ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Poizvej obmoÄje veljavnih vrednosti KLJUÄŒA" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Preveri opis za KLJUÄŒ" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Nastavi vrednosti KLJUÄŒA na VREDNOST" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SHEMA[:POT] KLJUÄŒ VREDNOST" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Ponastavi KLJUÄŒ na privzeto vrednost" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Ponastavi vse kljuÄe SHEME na privzete vrednosti" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Preveri ali je KLJUÄŒ zapisljiv" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Nadzoruj KLJUÄŒ za spremembe.\n" +"V kolikor KLJUÄŒ ni doloÄen, nadzoruj vse kljuÄe SHEME.\n" +"Pritisni ^C za zaustavitev nadzora.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SHEMA[:POT] [KLJUÄŒ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Uporaba:\n" +" gsettings --version\n" +" gsettings [--schemadir MAPASHEM] UKAZ [ARGUMENTI ...]\n" +"\n" +"Ukazi:\n" +" help Pokaži to pomoÄ\n" +" list-schemas IzpiÅ¡i seznam nameÅ¡Äenih shem\n" +" list-relocatable-schemas IzpiÅ¡i seznam dodeljivih shem\n" +" list-keys IzpiÅ¡i seznam kljuÄev v shemi\n" +" list-children IzpiÅ¡i seznam podrejenih shem\n" +" list-recursively Rekurzivno izpiÅ¡i seznam kljuÄev in vrednosti\n" +" range Izvede poizvedbo obmoÄja kljuÄa\n" +" describe Izvede poizvedbo opisa kljuÄa\n" +" get Pridobi vrednost kljuÄa\n" +" set DoloÄi vrednost kljuÄa\n" +" reset PoÄisti vrednost kljuÄa\n" +" reset-recursively PoÄisti vse vrednosti v podani shemi\n" +" writable Preveri ali je kljuÄ zapisljiv\n" +" monitor Nadzira spremembe\n" +"\n" +"Z ukazom »gsettings help UKAZ« se izpiÅ¡e podrobna pomoÄ.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Uporaba:\n" +" gsettings [--schemadir MAPASHEM] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " MAPASHEM Mapa za iskanje dodatnih shem\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SHEMA Ime sheme\n" +" POT Pot do dodeljive sheme\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " KLJUÄŒ KljuÄ (izbirno) znotraj sheme\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " KLJUÄŒ KljuÄ znotraj sheme\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VREDNOST Vrednost za nastavitev\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Ni mogoÄe odpreti shem iz %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Ni nameÅ¡Äenih shem\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Ni podanega imena sheme.\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "KljuÄ Â»%s« ne obstaja.\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Neveljaven vtiÄ, ni zagnano" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Neveljaven vtiÄ, zaganjanje je spodletelo: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "VtiÄ je že zaprt" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "VtiÄ V/I naprave je Äasovno potekel" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ustvarjanje GSocet preko fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ni mogoÄe ustvariti vtiÄa: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "DoloÄena je neznana družina" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "DoloÄen je neznan protokol" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Ni mogoÄe uporabiti opravil datagrama na vtiÄu, ki jih ne podpira." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Ni mogoÄe uporabiti opravil datagrama na vtiÄu z nastavljenim Äasovnim " +"pretekom" + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "ni mogoÄe pridobiti krajevnega naslova: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "ni mogoÄe pridobiti oddaljenega naslova: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "ni mogoÄe slediti: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Napaka vezave na naslov %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Napaka povezovanja v skupino za veÄsmerno oddajanje: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Napaka zapuÅ¡Äanja skupine za veÄsmerno oddajanje: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Ni podpore za veÄsmerno oddajanje lastno viru" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Nepodprta skupina vtiÄa" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "doloÄeno po viru in ne po naslovu IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Ime vmesnika je predolgo" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Vmesnika ni mogoÄe najti: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Ni podpore za veÄsmerno oddajanje v protokolu IPv4" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Ni podpore za veÄsmerno oddajanje v protokolu IPv6" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Napaka med sprejemanjem povezave: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Povezava v teku" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Ni mogoÄe pridobiti uvrÅ¡Äene napake:" + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Napaka med prejemanjem podatkov: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Napaka med poÅ¡iljanjem podatkov: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ni mogoÄe izklopiti vtiÄa: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Napaka med zapiranjem vtiÄa: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ÄŒakanje na stanje vtiÄa: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Ni mogoÄe poslati sporoÄila: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Vektorji sporoÄila so preobsežni." + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Napaka med poÅ¡iljanjem sporoÄila: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "Predmet GSocketControlMessage na sistemih Windows ni podprt" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Napaka med prejemanjem sporoÄila: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Ni mogoÄe prebrati poveril vtiÄa: %s." + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "Operacijski sistem ne podpira možnosti g_socket_get_credentials" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ni se mogoÄe povezati s posredniÅ¡kim strežnikom %s:" + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ni se mogoÄe povezati s strežnikom %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Ni se mogoÄe povezati: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Posredovanje preko ne-TCP povezave ni podprto." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Protokol posredniÅ¡kega strežnika »%s« ni podprt." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "PosluÅ¡alnik je že zaprt" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Dodan vtiÄ je zaprt" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "PosredniÅ¡ki strežnik SOCKSv4 nima podpore za naslov IPv6 »%s«" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "UporabniÅ¡ko ime je predolgo za protokol SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Ime gostitelja »%s« je predolgo za protokol SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Strežnik ni SOCKSv4 posredniÅ¡ki strežnik." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Povezava preko posredniÅ¡kega strežnika SOCKSv4 je zavrnjena." + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Strežnik ni SOCKSv5 posredniÅ¡ki strežnik." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "PosredniÅ¡ki strežnik SOCKSv5 zahteva overitev." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "Strežnik SOCKSv5 zahteva overitveni naÄin, ki ni podprt v GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "UporabniÅ¡ko ime ali geslo za protokol SOCKSv5 je predolgo." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Overitev strežnika SOCKSv5 je spodletela zaradi napaÄno vnesenega " +"uporabniÅ¡kega imena ali gesla." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Ime gostitelja »%s« je predolgo za protokol SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "PosredniÅ¡ki strežnik SOCKSv5 uporablja neznano vrsto naslova." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Notranja napaka posredniÅ¡kega strežnika SOCKSv5" + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Nabor pravil ne dovoljuje SOCKSv5 povezave" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Gostitelj ni dosegljiv preko strežnika SOCKSv5" + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Skozi SOCKSv5 posredniÅ¡ki strežnik ni mogoÄe doseÄi omrežja." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Povezava skozi posredniÅ¡ki strežnik SOCKSv5 je zavrnjena." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "PosredniÅ¡ki strežnik SOCKSv5 ne podpira ukaza »connect«." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 posredniÅ¡ki strežnik ne podpira ponujene vrste naslova" + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Neznana napaka posredniÅ¡kega strežnika SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Ni mogoÄe ustvariti cevi za stik z opravilom podrejenega predmeta (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Uporaba cevljenja na tem sistemu ni podprta" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Ni mogoÄe upravljati z razliÄico %d kodiranja GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Ni mogoÄe najti veljavnega naslova" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Napaka med obratnim razreÅ¡evanjem »%s«: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Napaka razÄlenjevanja zapisa DNS %s: nepravilno oblikovan paket DNS" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Ni zapisa DNS za zahtevano vrsto »%s«" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Trenutno ni mogoÄe razreÅ¡iti »%s«" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Napaka med razreÅ¡evanjem »%s«" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Nepravilno oblikovan paket DNS" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "RazÄlenjevanje odziva DNS za »%s« je spodletelo: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Potrdila kodiranega s protokolom PEM ni mogoÄe najti." + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ni mogoÄe odÅ¡ifrirati s protokolom PEM Å¡ifriranega osebnega kljuÄa" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Ni mogoÄe razÄleniti s protokolom PEM kodiranega zasebnega kljuÄa." + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Potrdila kodiranega s protokolom PEM ni mogoÄe najti." + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ni mogoÄe razÄleniti s protokolom PEM kodiranega potrdila." + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Ozadnji program TLS ne podpira potrdil PKCS #12." + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Ozadnji program GTlsBackend ne podpira ustvarjanja potrdil PKCS #11." + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"To je zadnja priložnost za pravilen vnos gesla preden se dostop zaklene." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"NeuspeÅ¡nih je bilo veÄ poskusov vnosa gesla, zato bo dostop ob naslednjem " +"napaÄnem vnosu zaklenjen." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Vneseno geslo je nepravilno." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "PoÅ¡iljanje FD ni podprto" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "PriÄakovano eno nadzorno sporoÄilo, prejetih pa je %d sporoÄil" +msgstr[1] "PriÄakovano eno nadzorno sporoÄilo, prejeto pa je %d sporoÄilo" +msgstr[2] "PriÄakovano eno nadzorno sporoÄilo, prejeti pa sta %d sporoÄili" +msgstr[3] "PriÄakovano eno nadzorno sporoÄilo, prejeta pa so %d sporoÄila" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "NepriÄakovana vrsta dodatnih podatkov" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "PriÄakovan en fd, prejetih pa je %d\n" +msgstr[1] "PriÄakovan en fd, prejet pa je %d\n" +msgstr[2] "PriÄakovan en fd, prejeta pa sta %d\n" +msgstr[3] "PriÄakovan en fd, prejetih pa so %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Prejet neveljaven fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Prejemanje FD ni podprto" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Napaka med poÅ¡iljanjem poveril:" + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Napaka med preverjanjem ali je predmet O_PASSCRED omogoÄen za vtiÄ: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Napaka omogoÄanja predmeta SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Pri prejemanju poveril je priÄakovano branje enega bajta, vendar se je " +"prebralo niÄ bajtov" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Nadzorno sporoÄilo ni priÄakovano, vendar pa je prejeto %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Napaka med onemogoÄanjem SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Napaka med branjem iz opisovalnika datoteke: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Napaka med zapiranjem opisovalnika datoteke: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Koren datoteÄnega sistema" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Napaka med pisanjem v opisovalnik datoteke: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Abstraktni naslovi vtiÄa domene UNIX na tem sistemu niso podprti" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "nosilec ne podpira možnosti izmetavanja" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "nosilec ne prepozna ukaza izvrzi ali izvrzi_z_dejanjem" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Napaka branja iz roÄnika: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Napaka med zapiranjem roÄnika: %s." + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Napaka pisanja v roÄnik: %s." + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Ni dovolj pomnilnika" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Notranja napaka: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Zahteva veÄ vhoda" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Neveljavni stisnjeni podatki" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Naslov za prisluh" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Prezrto zaradi skladnosti z GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Natisni naslov" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Natisni naslov v naÄinu lupine" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Zaženi storitev DBus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "NapaÄni argumenti\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "NepriÄakovan atribut »%s« za predmet »%s«" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Atributa »%s« predmeta »%s« ni mogoÄe najti" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "NepriÄakovana oznaka »%s«, priÄakovana je »%s«" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "NepriÄakovana oznaka »%s« znotraj »%s«" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Neveljaven zapis datuma/Äasa »%s« v datoteki zaznamka" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Ni veljavne datoteke zaznamkov v podatkovnih mapah" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Zaznamek za naslov URI »%s« že obstaja" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Ni veljavnega zaznamka za naslov URI »%s«" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "V zaznamku za naslov URI »%s« ni doloÄene vrsta MIME" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "V zaznamku za naslov URI »%s« ni doloÄene zasebne zastavice" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "V zaznamku za naslov URI »%s« ni nastavljenih skupin" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Program z imenom »%s« ni ustvaril zaznamka za »%s«" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "RazÅ¡irjanje ukazne vrstice »%s« z naslovom URI »%s« je spodletelo." + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Nepredstavljiv znak na dovodu pretvorbe" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "NedokonÄano zaporedje znakov na koncu vhoda" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Ni mogoÄe pretvoriti »%s« v nabor znakov »%s«" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Vstavljeno je prazno zaporedje bajtov na dovod pretvorbe" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Vstavljeno je prazno zaporedje bajtov na odvod pretvorbe" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "Naslov URI »%s« pri uporabi »datoteÄne« sheme ni absoluten" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "V naslovu URI krajevne datoteke »%s« ni mogoÄe uporabiti '#'" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Naslov URI »%s« je neveljaven" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Ime gostitelja naslova URI »%s« ni veljavno" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Naslov URI »%s« vsebuje neveljavne ubežne znake" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Pot »%s« ni absolutna pot" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a, %e. %b %Y %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "januar" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "februar" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "marec" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "april" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "junij" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "julij" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "avgust" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "september" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "oktober" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "avg" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "ponedeljek" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "torek" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "sreda" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Äetrtek" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "petek" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "sobota" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "nedeljo" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "pon" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "tor" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "sre" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Äet" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "pet" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sob" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ned" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "januar" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "februar" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "marec" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "april" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "junij" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "julij" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "avgust" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "september" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "oktober" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "avg" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "dop" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "pop" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Napaka med odpiranjem imenika »%s«: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ni mogoÄe dodeliti %lu bajtov za branje datoteke »%s«" +msgstr[1] "Ni mogoÄe dodeliti %lu bajta za branje datoteke »%s«" +msgstr[2] "Ni mogoÄe dodeliti %lu bajtov za branje datoteke »%s«" +msgstr[3] "Ni mogoÄe dodeliti %lu bajtov za branje datoteke »%s«" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Napaka med branjem datoteke »%s«: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Datoteka »%s« je prevelika." + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Branje datoteke »%s« je spodletelo: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Odpiranje datoteke »%s« je spodletelo: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Pridobivanje atributov datoteke »%s« je spodletelo: ukaz fstat() ni uspeÅ¡no " +"izveden: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Ni mogoÄe odpreti datoteke »%s«: ukaz fdopen() ni uspeÅ¡no izveden: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Ni mogoÄe preimenovati datoteke »%s« v »%s«: ukaz g_rename() ni uspeÅ¡no " +"izveden: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Ni mogoÄe zapisati datoteke »%s«: ukaz write() je spodletel: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Ni mogoÄe zapisati datoteke »%s«: ukaz fsync() ni uspeÅ¡no izveden: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Ni mogoÄe ustvariti datoteke »%s«: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"ObstojeÄe datoteke »%s« ni mogoÄe odstraniti: ukaz g_unlink() ni uspeÅ¡no " +"izveden: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Predloga »%s« je neveljavna, saj ne sme vsebovati »%s«" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Predloga »%s« ne vsebuje XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Branje simbolne povezave »%s« je spodletelo: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Ni mogoÄe odpreti pretvornika iz »%s« v »%s«: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Ni mogoÄe prebrati g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Preostanek nepretvorjenih podatkov v bralnem medpomnilniku" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanal je prekinjen v delnem znaku" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Ni mogoÄe prebrati v g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Veljavnega kljuÄa v iskanih mapah ni mogoÄe najti" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Ni obiÄajna datoteka" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Datoteka kljuÄa vsebuje vrstico »%s«, ki ni par kljuÄ-vrednost, skupina ali " +"opomba" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Neveljavno ime skupine: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Datoteka s kljuÄem se ne zaÄne s skupino" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Neveljavno ime kljuÄa: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Datoteka kljuÄa vsebuje nepodprto kodiranje »%s«" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Datoteka s kljuÄem ni del skupine »%s«" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Datoteka s kljuÄem nima kljuÄa »%s« v skupini »%s«" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Datoteka kljuÄa vsebuje kljuÄ Â»%s« z vrednostjo »%s«, ki ni zapisan v naboru " +"UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Datoteka kljuÄa vsebuje kljuÄ Â»%s« z vrednostjo, ki je ni mogoÄe tolmaÄiti." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Datoteka kljuÄa vsebuje kljuÄ Â»%s« v skupini »%s« z vrednostjo, ki je ni " +"mogoÄe tolmaÄiti." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"KljuÄ Â»%s« v skupini »%s« ima vrednost »%s«, priÄakovana pa je vrednost %s." + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Datoteka s kljuÄem vsebuje ubežni znak na koncu vrstice" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Datoteka kljuÄa vsebuje neveljavno ubežno zaporedje »%s«" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Vrednosti »%s« ni mogoÄe obravnavati kot Å¡tevilo." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "CeloÅ¡tevilska vrednost »%s« je izven obsega" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Vrednosti »%s« ni mogoÄe obravnavati kot Å¡tevilo s plavajoÄo vejico." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Vrednosti »%s« ni mogoÄe obravnavati kot logiÄno Boolovo vrednost." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Ni mogoÄe pridobiti atributov datoteke »%s%s%s%s«: ukaz fstat() je " +"spodletel: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Ni mogoÄe preslikati %s%s%s%s: ukaz mmap() nje spodletel: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "" +"Odpiranje datoteke »%s« je spodletelo: ukaz open() ni uspeÅ¡no izveden: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Napaka v vrstici %d, znak %d:" + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Neveljavno UTF-8 kodirano besedilo imena – neveljaven »%s«" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "»%s« ni veljavno ime" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "»%s« ni veljavno ime: »%c«" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Napaka v vrstici %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"RazÄlenjevanje vrste »%-.*s«, ki bi morala doloÄati Å¡tevilko znotraj sklica " +"znaka (na primer ê) je spodletelo – morda je Å¡tevilka prevelika" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Sklic znaka ni konÄan s podpiÄjem; najverjetneje je uporabljen znak » & « " +"brez povezave s predmetom – znak » & « mora biti zapisan kot »&«." + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Sklic znaka »%-.*s« ne kodira dovoljenega znaka" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Zaznan je prazen predmet » &; «; veljavne možnosti so: & " < " +"> '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Ime predmeta »%-.*s« ni prepoznano" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Predmet ni zakljuÄen s podpiÄjem; najverjetneje je uporabljen znak » & « " +"brez povezave s predmetom – znak » & « mora biti zapisan kot »&«." + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument se mora zaÄeti z predmetom (na primer )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"»%s« ni veljaven znak, ki lahko sledi znaku » < «;. Morda se ne zaÄne z " +"imenom predmeta." + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Nenavaden znak »%s«; priÄakovan znak je » > «, da zakljuÄi oznako predmeta " +"»%s«" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "DoloÄenih je preveÄ atributov za predmet »%s«" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Nenavaden znak »%s«; za imenom atributa »%s« (predmeta »%s«) je priÄakovan " +"znak » = «." + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Nenavaden znak »%s«; priÄakovan znak » > « ali » / «, ki bi zakljuÄil oznako " +"predmeta »%s« ali pogojno atribut. Morda je uporabljen neveljaven znak v " +"imenu atributa." + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Nenavaden znak »%s«; za enaÄajem je priÄakovan narekovaj, znotraj katerega " +"je podana vrednost atributa »%s« predmeta »%s«." + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"Znak »%s« ni veljaven, kadar sledi zaprtju imena predmeta »%s«; dovoljen " +"znak je » > «." + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Predmet »%s« je zaprt, trenutno ni odprtega drugega predmeta" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Predmet »%s« je zaprt, Å¡e vedno pa je odprt predmet »%s«" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument je prazen ali pa vsebuje le presledne znake" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokument je nepriÄakovano zakljuÄen takoj za odprtjem oznake z » < «" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokument je nepriÄakovano zakljuÄen s Å¡e odprtimi predmeti – »%s« je zadnji " +"odprt predmet" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokument nepriÄakovano zakljuÄen, priÄakovan je zakljuÄni zaklepaj oznake <" +"%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokument nepriÄakovano zakljuÄen sredi imena predmeta" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokument nepriÄakovano zakljuÄen sredi imena atributa" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokument nepriÄakovano zakljuÄen sredi oznake za odprtje predmeta." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokument nepriÄakovano zakljuÄen za enaÄajem, ki sledil imenu atributa; ni " +"doloÄena vrednosti atributa" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokument nepriÄakovano zakljuÄen sredi vrednosti atributa" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokument je nepriÄakovano zakljuÄen sredi oznake zaprtja predmeta »%s«" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Dokument je nepriÄakovano zakljuÄen sredi oznake zaprtja predmeta za neodprt " +"predmet" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokument nepriÄakovano zakljuÄen sredi opombe ali ukaza" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[MOŽNOST ...]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Možnosti pomoÄi:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Pokaži možnosti pomoÄi" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Pokaži vse možnosti pomoÄi" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Možnosti programa:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Možnosti:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Ni mogoÄe razÄleniti celoÅ¡tevilske vrednosti »%s« za %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "CeloÅ¡tevilska vrednost »%s« za %s je izven obsega" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Ni mogoÄe razÄleniti dvojne vrednosti »%s« za %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Dvojna vrednost »%s« za %s je izven obsega" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Napaka med razÄlenjevanjem %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Manjka argument za %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Neznana možnost %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "pokvarjen predmet" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "notranja napaka ali pokvarjen predmet" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "primanjkuje pomnilnika" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "dosežena omejitev sledenja nazaj" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "vzorec vsebuje predmete, ki niso podprti za delno iskanje zadetkov" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "notranja napaka" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "predhodne povezave, kot pogoji, niso podprti za delno primerjavo" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "dosežena omejitev globine drevesne ravni" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "nepravilna sestava zastavic nove vrstice" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "slab odmik" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "kratki utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "rekurzivna zanka" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "neznana napaka" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ na koncu vzorca" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c na koncu vzorca" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "neprepoznan znak sledi \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "Å¡tevilke niso zapisane pravilno v {} koliÄilniku" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "Å¡tevilke so prevelike v {} koliÄilniku" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "manjkajoÄ zakljuÄni znak ] za znakovni razred" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "neveljavno ubežno zaporedje v znakovnem razredu" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "nepravilen obseg v znakovnem razredu" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "ni mogoÄe ponoviti" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "nepriÄakovana ponovitev" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "neprepoznan znak za (? ali (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "Imenski razredi POSIX so podprti le znotraj razreda" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "manjka zakljuÄujoÄi )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "povezava na neobstojeÄ podrejen vzorec" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "manjka ) po opombi" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "logiÄni izraz je preobsežen" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "napaka med pridobivanjem pomnilnika" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") brez odpirajoÄega (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "prekoraÄitev kode" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "neprepoznan znak za (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "povratna trditev ni doloÄene dolžine" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "nepravilno oblikovano ime ali Å¡tevilka za (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "pogojna skupina vsebuje veÄ kot dve veji" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "trditev priÄakovana za (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ali (?[+-] Å¡tevilom mora slediti )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "neznano ime razreda POSIX" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "Zbirni predmeti POSIX niso podprti" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "znakovna vrednost v zaporedju \\x{...} je predolga" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "neveljaven pogoj (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C ni dovoljen v povratnih trditvah" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "ubežna zaporedja \\L, \\l, \\N{name}, \\U in \\u niso podprta" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "drevesni klic opravila se lahko izvaja v neskonÄnost" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "neprepoznan znak za (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "manjkajoÄ zakljuÄni znak v imenu podrejenega vzorca" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "dva imenovana podrejena vzorca imata enako ime" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "nepravilno oblikovano \\P ali \\p zaporedje" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "neznano ime lastnosti za \\P ali \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ime podrejenega vzorca je predolgo (najveÄ 32 znakov)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "preveÄ imenovanih podrejenih vzorcev (najveÄ 10,000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "osmiÅ¡ka vrednost je veÄja kot \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "preteÄena delovna povrÅ¡ina prevajanja kode" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "predhodno preverjene povezave podrejenega vzorca ni mogoÄe najti" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE skupina vsebuje veÄ kot eno vejo" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "nepopolna NEWLINE možnost" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ne sledi ime oziroma Å¡tevilo v oklepajih, oglatih oklepajih ali " +"narekovajih, niti navadno Å¡tevilo" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "oÅ¡tevilÄen sklic ne sme biti niÄeln" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "argument ni dovoljen za (*ACCEPT), (*FAIL) ali (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) ni prepoznan" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "Å¡tevilka je prevelika" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "manjkajoÄe ime podrejenega vzorca po (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "priÄakovana Å¡tevka po (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] je neveljaven podatkovni znak v združljivostnem naÄinu JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "razliÄna imena podrejenih vzorcev z isto Å¡tevilko niso dovoljena" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) mora obvezno imeti argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c mora slediti znak ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k ne sledi ime v oklepajih, oglatih oklepajih ali narekovajih" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N ni podprto v razredu" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "preveÄ sklicev s preskokom" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "ime je predolgo v (*MARK), (*PRUNE), (*SKIP) ali (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "znakovna vrednost v zaporedju \\u.... je predolga" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Napaka med primerjanjem logiÄnega izraza %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Knjižnica PCRE je pretvorjena brez UTF-8 podpore" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Knjižnica PCRE je pretvorjena brez lastnosti UTF-8 podpore" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Knjižnica PCRE je prevedena brez možnosti nezdružljivosti" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Napaka med prilagajanjem logiÄnega izraza %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Napaka med pretvarjanjem logiÄnega izraza %s pri znaku %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "Å¡estnajstiÅ¡ko Å¡tevilo ali pa manjka » } «" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "priÄakovano Å¡estnajstiÅ¡ko Å¡tevilo" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "manjka znak » < « v simbolni povezavi" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "nedokonÄana simbolna povezava" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "simbolna povezava niÄne dolžine" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "priÄakovano Å¡tevilo" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "neveljavna simbolna povezava" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "obidi konÄna » \\ «" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "neznano ubežno zaporedje" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Napaka med razÄlenjevanjem besedila zamenjave »%s« pri znaku %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Navedeno besedilo se ne zaÄne z narekovajem" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "V ukazni vrstici ali v navedenem besedilu manjka konÄni narekovaj" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Besedilo je konÄano takoj za znakom » \\ « (besedilo je »%s«)." + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Besedilo je konÄano pred zakljuÄnim narekovajem za %c (besedilo je »%s«)." + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Besedilo je bilo prazno (ali pa vsebuje le presledne znake)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Ni mogoÄe prebrati podatkov podrejenega procesa (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "NepriÄakovana napaka branja podatkov podrejenega opravila (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NepriÄakovana napaka v waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Podrejeni proces se je zakljuÄil s kodo %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Podrejeni proces je uniÄen s signalom %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Podrejeni proces se je ustavil s signalom %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Podrejeni proces se je zakljuÄil nenaravno" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Ni mogoÄe prebrati iz cevi podrejenega procesa (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Ni mogoÄe ustvariti podrejenega opravila »%s« (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Ni mogoÄa razvejitev (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Ni mogoÄe spremeniti v mapo »%s« (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Ni mogoÄe izvesti podrejenega opravila »%s« (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Ni mogoÄe odpreti datoteke za preslikavo opisnika datoteke (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Ni mogoÄe podvojiti opisnika datoteke podrejenega procesa (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Ni mogoÄe razvejiti podrejenega procesa (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Ni mogoÄe zapreti opisnika datoteke podrejenega procesa (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Neznana napaka med izvajanjem podrejenega opravila »%s«" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Ni mogoÄe prebrati dovolj podatkov iz cevi podrejenega procesa (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Ni mogoÄe prebrati podatkov iz opravila podrejenega predmeta" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Ni mogoÄe izvesti podrejenega opravila (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Ni mogoÄe izvesti ukaza dup() podrejenega procesa (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Neveljavno ime programa: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Neveljaven niz v vektorju argumenta pri %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Neveljaven niz okolja: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Neveljavna delovna mapa: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Napaka med izvajanjem pomožnega programa (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"NepriÄakovana napaka v g_io_channel_win32_poll() med branjem podatkov " +"procesa podrejenega predmeta" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Prazen niz ni Å¡tevilska vrednost" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "»%s« ni podpisano Å¡tevilo" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Å tevilo »%s« je izven obmoÄja [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "»%s« ni nepodpisano Å¡tevilo" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Neveljavni nabor znakov v naslovu URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Neveljaven naslov v naslovu URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "NapaÄen ne-UTF-8 znak v naslovu URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Neveljaven naslov IPv6 »%.*s« v naslovu URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Neveljaven kodiran naslov IP »%.*s« v naslovu URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Neveljavno internacionalizirano ime gostitelja »%.*s« v naslovu URI." + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Ni mogoÄe razÄleniti vrat »%.*s« v naslovu URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Vrednost vrat »%.*s« v naslovu URI je izven obsega" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "Naslov URI »%s« ni absolutna pot" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "Naslov URI »%s« je brez vpisa gostitelja" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "Naslov URI ni absoluten naslov in ni podanega osnovnega naslova URI" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Manjka znak »=« in vrednost parametra" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Ni mogoÄe dodeliti pomnilnika" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Znak izven obmoÄja za UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Neveljavno zaporedje na vhodu pretvorbe" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Znak izven obmoÄja za UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajtov" +msgstr[1] "%u bajt" +msgstr[2] "%u bajta" +msgstr[3] "%u bajti" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bitov" +msgstr[1] "%u bit" +msgstr[2] "%u bita" +msgstr[3] "%u biti" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bajtov" +msgstr[1] "%s bajt" +msgstr[2] "%s bajta" +msgstr[3] "%s bajti" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bitov" +msgstr[1] "%s bit" +msgstr[2] "%s bita" +msgstr[3] "%s biti" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "Ni mogoÄe naložiti /var/lib/dbus/machine-id oziroma /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Neznana napaka med povezovanjem" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Napaka v naslovu »%s« – atribut družine je nepravilno oblikovan" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "Priklopljen %s na %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; prepis za ta kljuÄ je prezrt.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " in --strict sta doloÄena, konÄanje.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Prepis za ta kljuÄ je prezrt.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "je brez dela.\n" + +#~ msgid "No such interface '%s'" +#~ msgstr "Vmesnik »%s«ne obstaja" + +#~ msgid "No such method '%s'" +#~ msgstr "NaÄin »%s« ne obstaja" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Ni mogoÄe doloÄiti naslova vodila iz okoljske spremenljivke " +#~ "DBUS_STARTER_BUS_TYPE - neznana vrednost »%s«" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGUMENTI ...]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Ustvarjanje zaÄasne datoteke je spodletelo: %s" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "SporoÄilo ima %d opisnikov datoteke, polje glave pa jih doloÄa %d" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Napaka: pot predmeta ni doloÄena.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Napaka: signal ni doloÄen\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Napaka: signal mora imeti polno kvalificirano ime.\n" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Napaka med pridobivanjem zapisljivih atributov: %s\n" + +#~ msgid "Error mounting location: Anonymous access denied\n" +#~ msgstr "Napaka med priklapljanjem mesta: brezimen dostop ni dovoljen\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Napaka med priklapljanjem mesta: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Napaka med odklapljanjem mesta: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Napaka med prilaganjem mesta: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Napaka med izmetavanjem nosilca: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Napaka med priklapljanjem %s: %s\n" + +#~ msgid "No files to open" +#~ msgstr "Ni datotek, oznaÄenih za odpiranje" + +#~ msgid "No files to delete" +#~ msgstr "Ni datotek, oznaÄenih za brisanje" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Napaka med doloÄevanjem atributa: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Napaka med ustvarjanjem mape '%s': %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Napaka med odpiranjem datoteke '%s': %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Napaka med branjem datoteke '%s': %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Napaka med preimenovanjem datoteke: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Napaka med odpiranjem datoteke: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Napaka med ustvarjanjem mape: %s" + +#~ msgid "Optional relative or relative filenames, or URIs to open" +#~ msgstr "" +#~ "Neobvezna relativna ali relativna imena datotek ali URI-ji za odpiranje" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Ni mogoÄe najti privzete vrste nadzora mape" + +#~ msgid "association changes not supported on win32" +#~ msgstr "Spreminjanje asociativnih povezav ni podprto na win32 sistemih" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Ustvarjanje asociativnih povezav ni podprto na win32 sistemih" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Datoteka s kljuÄem nima kljuÄa '%s'" diff --git a/po/sq.po b/po/sq.po new file mode 100644 index 0000000..98c8167 --- /dev/null +++ b/po/sq.po @@ -0,0 +1,4294 @@ +# Përkthimi i mesazheve të glib në shqip +# Copyright (C) 2003-2008 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Laurent Dhima , 2003-2008. +msgid "" +msgstr "" +"Project-Id-Version: glib HEAD\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2008-08-18 10:19+0200\n" +"Last-Translator: Laurent Dhima \n" +"Language-Team: albanian \n" +"Language: sq\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" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Atribut i papritur '%s' për elementin '%s'" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Atributi '%s' i elementit '%s' nuk u gjet" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Tag '%s' i papritur, pritej tag '%s'" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Tag '%s' i papritur në brendësi të '%s'" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Nuk u gjet asnjë file i vlefshëm libërshënimesh tek directory e të dhënave" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Një libërshënim për URI '%s' ekziston rregullisht" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Nuk u gjet asnjë libërshënim për URI '%s'" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Asnjë përcaktim i llojit të MIME në libërshënimin për URI '%s'" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Nuk është përcaktuar asnjë flag privat në libërshënimin për URI '%s'" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Nuk është përcaktuar asnjë grup për URI '%s'" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "Asnjë aplikativ me emrin '%s' ka regjistruar një libërshënues për '%s'" + +#: ../glib/gbookmarkfile.c:3458 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Zgjerimi i rreshtit exec '%s' me URI '%s' dështoi" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Konvertimi nga familja e simboleve '%s' në '%s' nuk suportohet" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "E pamundur hapja e konvertuesit nga '%s' në '%s'" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Sekuencë byte e pavlefshme tek të dhënat për konvertim" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Gabim gjatë konvertimit: %s" + +# (pofilter) doublewords: The word 'të' is repeated +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Sekuencë e pjesëshme simbolesh në fund të së dhënave në hyrje" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "I pamundur konvertimi i '%s' në familjen e simboleve '%s'" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s' nuk është një URI absolute duke përdorur skemën e \"file\"" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "URI për file lokal '%s' mund të mos përdorë një '#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' është e pasaktë" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Emri i host të URI '%s' është i pasaktë" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' përmban simbole escape të pavlefshëm" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Pozicioni me emër '%s' nuk është një pozicion absolut" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Emër host i pasaktë" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "PD" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "MD" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Y-%b-%d %I.%M.%S.%p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%Y-%b-%d" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%I.%M.%S. %Z" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I.%M.%S.%p %Z" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "janar" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "shkurt" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "mars" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "prill" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "maj" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "qershor" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "korrik" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Shk" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Pri" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Maj" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Qer" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Kor" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "e hënë " + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "e martë " + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "e mërkurë " + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "e enjte " + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "e premte " + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "e shtunë" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "e diel " + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Hën " + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Mar " + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Mër " + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Enj " + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Pre " + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sht" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Die " + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Gabim gjatë hapjes së directory '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "I pamundur grumbullimi i %lu bytes për të lexuar file \"%s\"" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Gabim gjatë leximit të file '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "File \"%s\" është tepër i madh" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "I pamundur leximi nga file '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "E pamundur hapja e file '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "E pamundur marrja e pronësive të file '%s': fstat() dështoi: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Dështoi hapja e file '%s': fdopen() dështoi: %s" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"Ndryshimi i emrit të file nga '%s' në '%s' dështoi: g_rename() dështoi: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Dështoi krijimi i file '%s': %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Hapja e file '%s' për shkrim dështoi: fdopen() dështoi: %s" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Shkrimi i file '%s' dështoi: fwrite() dështoi: %s" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Shkrimi i file '%s' dështoi: fwrite() dështoi: %s" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Shkrimi i file '%s' dështoi: fwrite() dështoi: %s" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Mbyllja e file '%s' dështoi: fclose() dështoi: %s" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "E pamundur heqja e file ekzistues '%s': g_unlink() dështoi: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Shabllon '%s' i pavlefshëm, nuk mund të përmbajë një '%s'" + +#: ../glib/gfileutils.c:1425 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Modeli '%s' nuk përmban XXXXXX" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u byte" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2007 +#, fuzzy, c-format +msgid "%.1f KiB" +msgstr "%.1f KB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2010 +#, fuzzy, c-format +msgid "%.1f MiB" +msgstr "%.1f MB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2013 +#, fuzzy, c-format +msgid "%.1f GiB" +msgstr "%.1f GB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2016 +#, fuzzy, c-format +msgid "%.1f TiB" +msgstr "%.1f KB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2019 +#, fuzzy, c-format +msgid "%.1f PiB" +msgstr "%.1f KB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2022 +#, fuzzy, c-format +msgid "%.1f EiB" +msgstr "%.1f KB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2035 +#, fuzzy, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, fuzzy, c-format +msgid "%.1f TB" +msgstr "%.1f KB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, fuzzy, c-format +msgid "%.1f PB" +msgstr "%.1f KB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, fuzzy, c-format +msgid "%.1f EB" +msgstr "%.1f KB" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, fuzzy, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%u byte" +msgstr[1] "%u byte" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "I pamundur leximi i lidhjes simbolike '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Lidhjet simbolike nuk suportohen" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Nuk arrij të hap konvertuesin nga '%s' në '%s': %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" +"I pamundur leximi i të dhënave të papërpunuara tek " +"g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Kanë tepruar të dhëna të pakonvertuara tek buffer i leximit" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Kanali përfundon me një simbol të pjesëshëm" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" +"I pamundur leximi i të dhënave të papërpunuara tek g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "E pamundur hapja e file '%s': open() dështoi: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "I pamundur mapimi i file '%s': mmap() dështoi: %s" + +# (pofilter) variables: translation contains variables not in original: %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) endwhitespace: checks whether whitespace at the end of the strings matches +# (pofilter) printf: checks whether printf format strings match +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Gabim tek rreshti %d simboli %d: " + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Tekst i kodifikuar UTF-8 i pavlefshëm - '%s' e pavlefshme" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Gabim tek rreshti %d: %s" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +# (pofilter) sentencecount: The number of sentences differ: 1 versus 2 +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"I pamundur analizimi i '%-.*s', duhet të ishte një numër brenda riferimeve " +"të një simboli (p.sh. ê) - ndoshta numri është tepër i madh" + +# (pofilter) endwhitespace: checks whether whitespace at the end of the strings matches +# (pofilter) doublespacing: checks for bad double-spaces by comparing to original +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Simboli nuk mbaron me pikëpresje; ndoshta keni përdorur një simbol ampersand " +"& pa pasur ndërmend fillimin e një entiteti të ri - përdorni & " + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Riferimi '%-.*s' i simbolit nuk kodifikon një simbol të lejuar" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"U gjet një entitet bosh '&;'; entitetet e vlefshme janë: & " < " +"> '" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Emri entitetit '%s' nuk njihet" + +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Entiteti nuk përfundon me pikëpresje; ndoshta keni përdorur një \"e\" " +"komerciale pa dashur të nisni një entity - zëvendësojeni me &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumenti duhet të fillojë me një element (p.sh. )" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' nuk është një simbol i vlefshëm mbas simbolit '<', nuk mund të fillojë " +"me emrin e një elementi" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Simbol tek '%s', pritet një simbol '>' për të mbyllur etiketën e elementit " +"bosh '%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Simbol tek '%s', pritet një '=' mbas emrit të atributit '%s' të elementit " +"'%s'" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Simbol tek '%s', pritet një simbol '>' ose '/' për të përfunduar etiketën e " +"nisjes së elementit '%s', ose në menyrë apsionale një atribut; ka shumë " +"mundësi të keni përdorur një simbol të pavlefshëm tek emri i një atributi" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Simbol tek '%s', pritet simboli i kuotës së hapur mbas shenjës së barazimit " +"për t'i caktuar një vlerë atributit '%s' të elementit '%s'" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' nuk është një simbol i vlefshëm për të vazhduar mbylljen e emrit të " +"elementit '%s'; simboli i lejuar është '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Elementi '%s' është mbyllur, asnjë element aktualisht është i hapur" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"Elementi '%s' është mbyllur, por elementi aktualisht i hapur është '%s'" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumenti ishte bosh apo përmbante vetëm hapësira të bardha" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Dokumenti u mbyll papritur, menjëherë pas hapjes së kllapës këndore '<'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Dokumenti u mbyll papritur me elementë akoma të hapur - '%s' ishte elementi " +"i fundit i hapur" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "Dokumenti u mbyll papritur, pritet simboli i mbylljes për tag-un <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumenti përfundoi papritur në brendësi të emrit të një elementi" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumenti u mbyll papritur në brendësi të emrit të një atributi" + +# (pofilter) endpunc: checks whether punctuation at the end of the strings match +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumenti u mbyll papritur brënda një etikete hapje elementi" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokumenti u mbyll papritur mbas shenjës së barazimit që vjen mbas emrit të " +"një atributi; atributi nuk ka vlerë" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumenti u mbyll papritur në brendësi të vlerës së një atributi" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"Dokumenti u mbyll papritur në brendësi të tag-ut mbyllës të elementit '%s'" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokumenti u mbyll papritur në brendësi të një komenti apo instruksioni " +"proçesi" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "objekt i korruptuar" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "gabim i brendshëm ose objekt i korruptuar" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "mbi memorjen" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "u arrit kufiri i backtracking" + +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "modeli përmban elementë të pasuportuar për korrispondimin e pjesëshëm" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "gabim i brendshëm" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"për korrispondimin e pjesëshëm nuk suportohen referimet mbrapsht si kushte" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "u arrit kufiri i ndjekjes" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "u arrit kufiri i hapësirës së punës pën nënstringa boshe" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "kombinim i pavlefshëm i flag të fund'rreshtit" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "gabim i panjohur" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "\\ në fund të modelit" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "\\c në fund të modelit" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "simbol i papërshtatshëm mbas \\" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "ndryshimet gërma të vogla/mëdha nuk (\\l, \\L, \\u, \\U) lejohen këtu" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "numra jashtë rendit në sasiuesin {}" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "numër tepër i madh në sasiuesin {}" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +# (pofilter) brackets: translation is missing ']' +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "] përfunduese munguese për klasën e simboleve" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "sekuencë escape e pavlefshme në klasën e simboleve" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "interval i parregullt në klasën e simboleve" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "asgjë për tu përsëritur" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) endpunc: checks whether punctuation at the end of the strings match +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +# (pofilter) brackets: translation is missing '(' +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "simbol i panjohur mbas (?" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +# (pofilter) brackets: translation is missing '(' +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "simbol i panjohur mbas (?<" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +# (pofilter) brackets: translation is missing '(' +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "simbol i panjohur mbas (?P" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "klasat e përmendura POSIX suportohen vetëm në brendësi të një klase" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr ") përfunduese mungon" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr ") pa ( hapje" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ose (?[+-]shifra duhet të ndiqet nga )" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "riferim ndaj një nën-modeli joekzistues" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr ") mungon mbas komentit" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "shprehje e rregullt tepër e gjatë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "rekuperimi i memorjes dështoi" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "kushti lookbehind nuk ka gjatësi të fiksuar" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "numër apo emër i keqformuar mbas (?(" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "grupi kushtëzor përmban më shumë se dy degëzime" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "pritej kushti mbas (?(" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "emër i panjohur klase POSIX" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) acronyms: acronyms should not be translated: POSIX +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "elementët vendosës POSIX nuk suportohen" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "vlera e simbolit në sekuencën \\x{...} është tepër e madhe" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "kusht (?(0) i pavlefshëm" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C e palejuar në kushtin lookbehind" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "thirrja rekursive mund të hyjë në loop pafund" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "mungon përfunduesi në emrin e nën-modelit" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "dy nën-modelet e emërtuar kanë të njëjtin emër" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "sekuencë \\P ose \\p e keqformuar" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "emër i panjohur pronësie mbas \\P ose \\p" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "emri i nën-modelit është tepër i gjatë (maksimum 32 simbole)" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "emërtuar tepër nën-modele (maksimum 10,000)" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "vlera tetore është më e madhe se \\377" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "grupi DEFINE përmban më shumë se një degëzim" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "përsëritja e një grupi DEFINE nuk është e lejuar" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "opsione NEWLINE jokoerente" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" +"\\g nuk ndiqet nga një emër në kllapa ose një numër të ndryshëm nga zero me " +"dëshirë në kllapa" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "përsëritje e papritur" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "sasi e tepërt kodi" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "tejkalim kufir gjatë kompilimit të zonës së punës" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "nën-model referues i kontrolluar më parë nuk u gjet" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" +"Gabim gjatë kërkimit të korrispondimeve për shprehjen e rregullt %s: %s" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Libraria PCRE është kompiluar pa suportin për UTF8" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Libraria PCRE është kompiluar pa suportin për pronësitë UTF8" + +#: ../glib/gregex.c:1271 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Gabim gjatë kompilimit të shprehjes së rregullt %s tek simboli %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Gabim gjatë optimizimit të shprehjes së rregullt %s: %s" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "pritej një shifër exadecimale ose '}'" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "pritej një shifër exadecimale" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "mungon '<' në referimin simbolik" + +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "Riferim simbolik i papërfunduar" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "referim simbolik me gjatësi zero" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "pritej një shifër" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "referim simbolik i palejuar" + +# (pofilter) startpunc: checks whether punctuation at the beginning of the strings match +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "'\\' në fund e izoluar" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "sekuencë e panjohur escape" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" +"Gabim gjatë analizimit të tekstit zëvendësues \"%s\" tek simboli %lu: %s" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Teksti i kuotuar nuk fillon me shenjën e kuotimit" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Nuk u gjet simboli i kuotimit tek rreshti i komandës apo tek teksti i " +"kuotuar nga shell" + +# (pofilter) puncspacing: checks for bad spacing after punctuation +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Teksti përfundoi menjëherë pas një simboli '\\'. (Teksti ishte '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"Teksti përfundoi përpara se të gjente tekstin e kërkuar për %c. (Teksti " +"ishte '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Teksti është bosh (ose përmban vetëm hapsira të bardha)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "I pamundur leximi i të dhënave nga proçesi bir" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "I pamundur krijimi i pipe për të komunikuar me proçesin bir (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "I pamundur leximi nga pipe bijë (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "I pamundur ndryshimi i directory në '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "I pamundur ekzekutimi i proçesit bir (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Emër i pasaktë programi: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Vlerë e pasaktë në vektorin e argumentit tek %d: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Vlerë e pavlefshme në ambient: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Directory e pavlefshme pune: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "I pamundur ekzekutimi i programit ndihmues (%s)" + +# (pofilter) doublewords: The word 'të' is repeated +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Gabim i papritur në g_io_channel_win32_poll() gjatë leximit të të dhënave " +"nga një proçes bir" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "I pamundur leximi i të dhënave nga proçesi bir (%s)" + +# (pofilter) doublewords: The word 'të' is repeated +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Gabim i papritur në select() gjatë leximit të të dhënave nga një proçes bir " +"(%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Gabim i papritur në waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "E pamundur kryerja e fork (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "I pamundur zbatimi i proçesit bir \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"I pamundur ridrejtimi i të dhënave në hyrje apo dalje të proçesit bir (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "E pamundur kryerja e fork për proçesin bir (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Gabim i panjohur gjatë ekzekutimit të proçesit bir \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"I pamundur leximi i një sasie të dhënash të mjaftueshme nga pid pipe bir (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Simboli nuk ekziston në UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Sekuencë e pavlefshme në hyrje për konvertimin" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Simboli nuk ekziston në UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Përdorimi:" + +# (pofilter) acronyms: acronyms should not be translated: OPTION +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPSIONI...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Opcionet e ndihmës:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Shfaq opcionet e ndihmës" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Shfaq të gjithë opcionet e ndihmës" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Opcionet e programit:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "I pamundur analizimi i vlerës së plotë '%s' për %s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Vlera integruese '%s' për %s është jashtë kufirit" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "I pamundur analizimi i vlerës së dyfishtë '%s' për %s" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Vlera e dyfishtë '%s' për %s është jashtë kufirit" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "Gabim gjatë analizimit të opsionit %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Mungojnë argumentë për %s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Opcion i panjohur %s" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "Nuk u gjet asnjë file i vlefshëm kyçi tek directory e kërkimit" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Nuk është një file i rregullt" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "File është bosh" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Kyçi përmban rreshtin '%s' që nuk është një vlerë çift, grup apo koment kyçi" + +#: ../glib/gkeyfile.c:828 +#, c-format +msgid "Invalid group name: %s" +msgstr "Emër i pasaktë grupi: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "File i kyçit nuk fillon me një grup" + +#: ../glib/gkeyfile.c:876 +#, c-format +msgid "Invalid key name: %s" +msgstr "Emër i pasaktë kyçi: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "File i kyçit përmban kodifikimin e pasuportuar '%s'" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "File i kyçit nuk ka grupin '%s'" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "File i kyçit nuk përmban kyçin '%s'" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "File i kyçit përmban kyçin '%s' me vlerë '%s' që nuk është në UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "File i kyçit përmban kyçin '%s' që ka një vlerë të painterpretueshme." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "File i kyçit përmban kyçin '%s' që ka një vlerë të painterpretueshme." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"File i kyçit përmban kyçin '%s' në grupin '%s' që ka një vlerë të " +"painterpretueshme." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "File i kyçit nuk ka kyçin '%s' në grupin '%s'" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "File i kyçit përmban simbolin escape në fund të rreshtit" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "File i kyçit përmban sekuencën e pavlefshme escape '%s'" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Vlera '%s' nuk mund të interpretohet si një numër." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Vlera integruese '%s' është jashtë kufirit" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Vlera '%s' nuk mund të interpretohet si një numër float." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Vlera '%s' nuk mund të interpretohet si një boolean." + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Vlerë count tepër e madhe kaluar tek %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "Stream është i mbyllur rregullisht" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "Operacioni është anulluar" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Sekuencë byte e pavlefshme tek të dhënat për konvertim" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Veprimi nuk suportohet" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "Lloj i panjohur" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "Lloj file %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "Lloj %s" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "End-of-stream i parakohshëm papritur" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Gabim gjatë ndarjes së file: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Gabim gjatë hapjes së file '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Gabim gjatë leximit të file '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Gabim gjatë leximit të file '%s': %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Gabim gjatë shkrimit tek file: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Gabim gjatë leximit të file '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) startcaps: checks that the message starts with the correct capitalisation +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Lloj i panjohur" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Gabim gjatë hapjes së directory '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Gabim gjatë krijimit të directory: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Gabim gjatë hapjes së file '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Gabim gjatë leximit të file '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Gabim gjatë leximit të file '%s': %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Gabim gjatë mbylljes së file: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Gabim gjatë hapjes së file '%s': %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Gabim gjatë hapjes së file '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +#, fuzzy +msgid "The connection is closed" +msgstr "Enumuruesi është mbyllur" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdbusconnection.c:6082 +#, fuzzy, c-format +msgid "A subtree is already exported for %s" +msgstr "Stream është i mbyllur rregullisht" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Gabim gjatë shkrimit tek file: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Koshi nuk suportohet" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Gabim gjatë shkrimit tek file: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Gabim tek rreshti %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Gabim gjatë analizimit të opsionit %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Gabim gjatë hapjes së file: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Simboli '%s' nuk është i vlefshëm brenda emrit të një entiteti" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Simboli '%s' nuk është i vlefshëm brenda emrit të një entiteti" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Simboli '%s' nuk është i vlefshëm brenda emrit të një entiteti" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Gabim gjatë analizimit të opsionit %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Gabim gjatë konvertimit: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Gabim gjatë hapjes së directory '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +#, fuzzy +msgid "Monitor a remote object." +msgstr "objekt i korruptuar" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "Paemër" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "File .desktop nuk specifikon fushën Exec" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "E pamundur gjetja e terminalit të kërkuar nga aplikativi" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" +"E pamundur gjetja e kartelës së përdoruesit për konfigurimin e aplikativëve " +"(%s): %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" +"E pamundur gjetja e kartelës së përdoruesit për konfigurimin MIME (%s): %s" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "I pamundur krijimi i file .desktop të përdoruesit %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "Përcaktimi i personalizuar për %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "njësia nuk suporton nxjerrjen jashtë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +#, fuzzy +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "njësia nuk suporton nxjerrjen jashtë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "njësia nuk suporton shqyrtimin e suporteve" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdrive.c:728 +#, fuzzy +msgid "drive doesn't implement start" +msgstr "njësia nuk suporton nxjerrjen jashtë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gdrive.c:831 +#, fuzzy +msgid "drive doesn't implement stop" +msgstr "njësia nuk suporton nxjerrjen jashtë" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "Veprimi nuk suportohet" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "Objekti mount i përmbajtur nuk ekziston" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "I pamundur kopjimi mbi directory" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "I pamundur kopjimi i directory mbi directory" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "File objektiv ekziston" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "I pamundur kopjimi rekursiv i directory" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Lidhjet simbolike nuk suportohen" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Gabim gjatë hapjes së file: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfile.c:2909 +#, fuzzy +msgid "Can't copy special file" +msgstr "I pamundur kopjimi mbi directory" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "Dhënë vlerë e pavlefshme lidhje simbolike" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "Koshi nuk suportohet" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Emrat e file nuk mund të përmbajnë '%c'" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "Volumi nuk suporton montimin" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "Nuk rezulton i regjistruar asnjë aplikativ për të manazhuar këtë file" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "Enumuruesi është mbyllur" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "Enumuruesi i file prezanton një operacion të papërfunduar" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "Enumuruesi i file është rregullisht i mbyllur" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "Stream nuk suporton query_info" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "Pikëvendosja nuk suportohet në stream" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "Ndërprerja nuk suportohet tek stream në hyrje" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "Ndërprerja nuk suportohet tek stream" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "Stream i input nuk suporton leximin" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "Stream prezanton një operacion në pritje" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Koshi nuk suportohet" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glib-compile-schemas.c:958 +#, fuzzy, c-format +msgid "invalid GVariant type string '%s'" +msgstr "Lloj i pasaktë atributi (pritej string)" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" +"E pamundur gjetja e llojit të monitorit të paracaktuar për directory lokale" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "Emër file i pasaktë %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:948 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Gabim gjatë marrjes së informacioneve mbi file të sistemit: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "I pamundur riemërtimi i directory root" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, c-format +msgid "Error renaming file: %s" +msgstr "Gabim gjatë ndryshimit të emrit të file: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfile.c:1126 +#, fuzzy +msgid "Can't rename file, filename already exists" +msgstr "I pamundur riemërtimi i file, emër ekzistues file" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +msgid "Invalid filename" +msgstr "Emër i pavlefshëm file" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:1300 +#, c-format +msgid "Error opening file: %s" +msgstr "Gabim gjatë hapjes së file: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "E pamundur hapja e directory" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:1441 +#, c-format +msgid "Error removing file: %s" +msgstr "Gabim gjatë fshirjes së file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:1808 +#, c-format +msgid "Error trashing file: %s" +msgstr "Gabim gjatë hedhjes në kosh të file: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +#: ../gio/glocalfile.c:1831 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "I pamundur krijimi i directory koshit \"%s\": %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "E pamundur gjetja e directory së sipërme për koshin" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "I pamundur krijimi apo gjetja e directory të koshit" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:1985 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "I pamundur krijimi i një file me informacionet e hedhjes në kosh: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, c-format +msgid "Unable to trash file: %s" +msgstr "E pamundur hedhja në kosh e file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +#: ../gio/glocalfile.c:2133 +#, c-format +msgid "Error creating directory: %s" +msgstr "Gabim gjatë krijimit të directory: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "I pamundur leximi i lidhjes simbolike '%s': %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfile.c:2166 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Gabim gjatë krijimit të lidhjes simbolike: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, c-format +msgid "Error moving file: %s" +msgstr "Gabim gjatë lëvizjes së file: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "E pamundur lëvizja e directory mbi directory" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "Krijimi i file backup dështoi" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfile.c:2297 +#, c-format +msgid "Error removing target file: %s" +msgstr "Gabim gjatë heqjes së file objektiv: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "Lëvizja midis objekteve mount nuk suportohet" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "Vlera e atributit duhet të jetë jo-NULL" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "Lloj i pasaktë atributi (pritej string)" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "Emër i pavlefshëm atributi të zgjeruar" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileinfo.c:773 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Gabim gjatë caktimit të atributit të zgjeruar '%s': %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, c-format +msgid "Error stating file '%s': %s" +msgstr "E pamundur kryerja e stat të file '%s': %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr " (kodifikim i pavlefshëm)" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileinfo.c:1768 +#, c-format +msgid "Error stating file descriptor: %s" +msgstr "Gabim gjatë kryerjes së stat të përshkruesit të file: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Lloj i pasaktë atributi (pritej uint32)" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Lloj i pasaktë atributi (pritej uint64)" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "Lloj i pasaktë atributi (pritej byte string)" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Gabim gjatë caktimit të së drejtave: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileinfo.c:1920 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Gabim gjatë caktimit të së drejtave: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileinfo.c:1971 +#, c-format +msgid "Error setting owner: %s" +msgstr "Gabim gjatë caktimit të pronarit: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "symlink duhet të jetë jo-NULL" + +# (pofilter) variables: translation contains variables not in original: %d +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Gabim gjatë caktimit të symlink: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "Gabim gjatë caktimit të symlink: file nuk është një lidhje simbolike" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Gabim gjatë caktimit të së drejtave: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "Konteksti SELinux duhet të jetë non-NULL" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileinfo.c:2177 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Gabim gjatë përcaktimit të kontekstit SELinux: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "SELinux nuk është aktivizuar në këtë sistem" + +# (pofilter) variables: do not translate: %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Caktimi i atributit %s nuk suportohet" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, c-format +msgid "Error reading from file: %s" +msgstr "Gabim gjatë leximit nga file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Gabim gjatë pikëvendosjes në brendësi të file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, c-format +msgid "Error closing file: %s" +msgstr "Gabim gjatë mbylljes së file: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "E pamundur gjetja e llojit të monitorit të paracaktuar për file lokalë" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, c-format +msgid "Error writing to file: %s" +msgstr "Gabim gjatë shkrimit tek file: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileoutputstream.c:283 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Gabim gjatë heqjes së lidhjes së vjetër të backup: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Gabim gjatë krijimit të kopjes së backup: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileoutputstream.c:328 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Gabim gjatë riemërtimit të përkohshëm të file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, c-format +msgid "Error truncating file: %s" +msgstr "Gabim gjatë ndarjes së file: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Gabim gjatë hapjes së file '%s': %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "File objektiv është një directory" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "File objektiv nuk është një file i rregullt" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "File është ndryshuar nga jashtë" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Gabim gjatë fshirjes së file: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "Dhënë GSeekType i pavlefshëm" + +# (pofilter) variables: translation contains variables not in original: %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gmemoryinputstream.c:496 +msgid "Invalid seek request" +msgstr "Kërkesë pikëvendosje e pavlefshme" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "E pamundur ndërprerja e GMemoryInputStream" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "Stream output memorje të papërmasueshme" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "Ripërmasimi i stream të output të memories dështoi" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +#, fuzzy +msgid "mount doesn't implement \"unmount\"" +msgstr "objekti mount nuk suporton zmontimin" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +#, fuzzy +msgid "mount doesn't implement \"eject\"" +msgstr "objekti mount nuk suporton nxjerrjen jashtë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +#, fuzzy +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "objekti mount nuk suporton zmontimin" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +#, fuzzy +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "objekti mount nuk suporton nxjerrjen jashtë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +#, fuzzy +msgid "mount doesn't implement \"remount\"" +msgstr "objekti mount nuk suporton rimontimin" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "objekti mount nuk suporton mbivendosjen e llojit të përmbajtjes" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" +"objekti mount nuk suporton mbivendosjen sinkrone të llojit të përmbajtjes" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "Stream i output nuk suporton shkrimin" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "Stream burues është i mbyllur" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Gabim gjatë leximit të file '%s': %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Gabim gjatë leximit të file '%s': %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Gabim gjatë fshirjes së file: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Opcion i panjohur %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gsocket.c:290 +#, fuzzy +msgid "Socket is already closed" +msgstr "Stream burues është i mbyllur" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Gabim gjatë leximit nga file: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "I pamundur krijimi i directory koshit \"%s\": %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Gabim gjatë shkrimit tek file: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Gabim gjatë konvertimit: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Gabim gjatë ndarjes së file: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Gabim gjatë hapjes së file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "E pamundur hedhja në kosh e file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Gabim gjatë fshirjes së file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Gabim gjatë hapjes së file: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "I pamundur krijimi i directory koshit \"%s\": %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Gabim gjatë mbylljes së file: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Gabim gjatë hapjes së file: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gsocket.c:3081 +#, fuzzy +msgid "GSocketControlMessage not supported on windows" +msgstr "ndryshimi i shoqërimeve nuk suportohet në win32" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Gabim gjatë fshirjes së file: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +#, fuzzy +msgid "Unknown error on connect" +msgstr "gabim i panjohur" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Lidhjet simbolike nuk suportohen" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gsocketlistener.c:191 +#, fuzzy +msgid "Listener is already closed" +msgstr "Stream është i mbyllur rregullisht" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +#, fuzzy +msgid "Unexpected type of ancillary data" +msgstr "End-of-stream i parakohshëm papritur" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Gabim gjatë hapjes së file: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Gabim gjatë ndryshimit të emrit të file: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, c-format +msgid "Error reading from unix: %s" +msgstr "Gabim gjatë leximit nga unix: %s" + +# (pofilter) variables: translation contains variables not in original: %d +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, c-format +msgid "Error closing unix: %s" +msgstr "Gabim duke mbyllur unix: %s" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "File rrënjë i sistemit" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, c-format +msgid "Error writing to unix: %s" +msgstr "Gabim gjatë shkrimit në unix: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "volumi nuk suporton nxjerrjen jashtë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +#, fuzzy +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "volumi nuk suporton nxjerrjen jashtë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "E pamundur gjetja e aplikativit" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gwin32appinfo.c:299 +#, c-format +msgid "Error launching application: %s" +msgstr "Gabim gjatë nisjes së aplikativit: %s" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "URI nuk suportohen" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "ndryshimi i shoqërimeve nuk suportohet në win32" + +# (pofilter) untranslated: checks whether a string has been translated at all +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "Krijimi i shoqërimeve nuk suportohet në win32" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Gabim gjatë leximit nga file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Gabim gjatë mbylljes së file: %s" + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Gabim gjatë shkrimit tek file: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +#, fuzzy +msgid "Not enough memory" +msgstr "mbi memorjen" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, fuzzy, c-format +msgid "Internal error: %s" +msgstr "gabim i brendshëm" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Emër host i pasaktë" + +# (pofilter) untranslated: checks whether a string has been translated at all +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "E pamundur lëvizja e directory mbi directory" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Sekuencë e pavlefshme në hyrje për konvertimin" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "Reached maximum data array limit" +#~ msgstr "U arrit kufiri maksimum i array të së dhënave" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "do not hide entries" +#~ msgstr "mos fshih zërat" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "use a long listing format" +#~ msgstr "përdor një format liste të gjatë" + +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) acronyms: acronyms should not be translated: FILE +#~ msgid "[FILE...]" +#~ msgstr "[FILE...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Simboli '%s' nuk vlen si fillues i emrit të një entiteti; simboli & " +#~ "fillon një entitet; nëse ky simbol nuk do të jetë fillimi i një entiteti, " +#~ "përdore si &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Simbol bosh, duhet të përmbajë një vlerë numerike, si dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Riferim entiteti i papërfunduar" + +#~ msgid "Unfinished character reference" +#~ msgstr "Referim i papërfunduar i simbolit" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Tekst i kodifikuar UTF-8 i pavlefshëm - sekuencë tepër e gjatë" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Tekst i kodifikuar UTF-8 i pavlefshëm - nuk është një simbol nisje" + +#~ msgid "file" +#~ msgstr "file" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "The file containing the icon" +#~ msgstr "File që përmban ikonën" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "name" +#~ msgstr "emri" + +# (pofilter) variables: translation contains variables not in original: %s +# (pofilter) simplecaps: checks the capitalisation of two strings isn't wildly different +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) printf: checks whether printf format strings match +#~ msgid "The name of the icon" +#~ msgstr "Emri i ikonës" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "names" +#~ msgstr "emrat" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "An array containing the icon names" +#~ msgstr "Një array me emrat e ikonave" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "use default fallbacks" +#~ msgstr "përdor alternativat e paracaktuara" + +# (pofilter) untranslated: checks whether a string has been translated at all +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "Tregon nëse duhen përdorur ikonat alternative të paracaktuara gjetur duke " +#~ "shkurtuar emrin tek simbolet '-'. Shpërfill emrat mbas emrit të parë në " +#~ "rast se jepen më shumë se një." + +# (pofilter) variables: translation contains variables not in original: %s, %s +# (pofilter) isfuzzy: Check if the unit has been marked fuzzy. +# (pofilter) singlequoting: checks whether singlequoting is consistent between the two strings +# (pofilter) printf: checks whether printf format strings match +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Gabim gjatë kryerjes së stat të përshkruesit të file: %s" diff --git a/po/sr.po b/po/sr.po new file mode 100644 index 0000000..d1fe191 --- /dev/null +++ b/po/sr.po @@ -0,0 +1,6467 @@ +# Serbian translation of glib +# Courtesy of Prevod.org team (http://prevod.org/) -- 2003–2022. +# This file is distributed under the same license as the glib package. +# Translators: +# Данило Шеган , 2004–2005. +# Слободан Д. Средојевић , 2006. +# Бранко Кокановић , 2010. +# Милош Поповић , 2010–2015. +# Марко М. КоÑтић , 2016. +# МироÑлав Ðиколић , 2011–2022. +# +msgid "" +msgstr "" +"Project-Id-Version: 2.8\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-05-10 09:00+0000\n" +"PO-Revision-Date: 2022-07-03 03:56+0200\n" +"Last-Translator: МироÑлав Ðиколић \n" +"Language-Team: Serbian <ÑрпÑки >\n" +"Language: sr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" +"X-Project-Style: gnome\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "ПоÑтављање оÑновних програма још није подржано" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"ПоÑтављање програма као што је поÑледњи пут коришћен за врÑту није још " +"подржано" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Опције Гпрограма" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Показује опције Гпрограма" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Улази у режим уÑлуге Гпрограма (кориÑти Ñа датотека уÑлуге Д-Ñабирнице)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Ðадглашава ИБ програма" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Замени покренути примерак" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Штампа помоћ" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[ÐÐРЕДБÐ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "ИÑпиÑује издање" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "ИÑпиÑује податке о издању и излази" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "ИÑпиÑује програме" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"ИÑпиÑује инÑталиране програме који Ñе могу покренути Д-Ñабирницом (према " +"датотекама радне површи)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Покреће програм" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Покреће програм (Ñа изборним датотекама за отварање)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "ИБПРОГРÐМР[ДÐТОТЕКÐ…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Покреће радњу" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Призива радњу над програмом" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ИБПРОГРÐМРРÐДЊР[ПÐРÐМЕТÐР]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "ИÑпиÑује доÑтупне радње" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "ИÑпиÑује Ñтатичке радње за програм (из датотеке радне површи)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ИБПРОГРÐМÐ" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "ÐÐРЕДБÐ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Ðаредба за коју ће иÑпиÑати опширнију помоћ" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Одредник програма у запиÑу Д-Ñабирнице (нпр: „org.example.viewer“)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "ДÐТОТЕКÐ" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Ðеобавезна релативни или апÑолутни називи датотека или путање које желите да " +"отворите" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "РÐДЊÐ" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Ðазив радње за призивање" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "ПÐРÐМЕТÐР" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Изборни параметар за призивање радње, у запиÑу Гваријанта" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Ðепозната наредба „%s“\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Употреба:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Ðргументи:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ÐРГУМЕÐТИ…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Ðаредбе:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"КориÑтите „%s help ÐÐРЕДБГ за подробнију помоћ.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Ðредба „%s“ захтева иб програма за непоÑредно праћење\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "неиÑправан иб програма: „%s“\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"„%s“ не прихвата аргументе\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "не могу да Ñе повежем на Д-Ñабирницу: „%s“\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "грешка Ñлања %s поруке програму: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "назив радње мора бити дат након иб-а програма\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"неиÑправан назив радње: „%s“\n" +"називи радњи морају да Ñадрже Ñамо Ñлова и бројеве, „-“ и „.“\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "грешка обраде параметра радње: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "радње прихватају највише један параметар\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "наредба „list-actions“ прихвата Ñамо иб програма" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "не могу да нађем датотеку радне површи за програм „%s“\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"непозната наредба: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Превелика бројчана вредноÑÑ‚ је проÑлеђена у %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Ðије подржавано премотавање оÑновног тока" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Ðе могу да Ñкратим улазни ток у Гмеђумеморији" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Ток је већ затворен" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Ðије подржано ÑаÑецање оÑновног тока" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Радња је отказана" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "ÐеиÑправан објекат, није покренуто" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Ðепотпун низ бајтова на улазу" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Ðема довољно меÑта у одредишту" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "ÐеиÑправан низ бајтова у улазу који претварам" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Грешка приликом претварања: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Ðије подржано покретање уз могућноÑÑ‚ отказивања" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Претварање из Ñкупа знакова „%s“ у „%s“ није подржано" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Ðе могу да покренем претварање из „%s“ у „%s“" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s врÑта" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Ðепозната врÑта" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s врÑта датотеке" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "Г-акредитиви Ñадрже неиÑправне податке" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "Гуверења ниÑу подржана на оперативном ÑиÑтему" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Ðемате подршку за Гуверења на овој платформи" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "Гуверења не Ñадрже ИБ процеÑа на овом оперативном ÑиÑтему" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Заваравање уверења није могуће на овом оперативном ÑиÑтему" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Ðеочекиван, преран крај тока" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Кључ „%s“ није подржан унутар адреÑе „%s“" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Безначајна комбинација кључ/вредноÑÑ‚ унутар адреÑе „%s“" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"ÐдреÑа „%s“ је неиÑправна (потребна Ñамо једна путања, директоријум, " +"привремени директоријум или апÑтрактни кључ)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Грешка унутар адреÑе „%s“ — оÑобина „%s“ није иÑправна" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Ðепознати или неподржани Ð¿Ñ€ÐµÐ½Ð¾Ñ â€ž%s“ за адреÑе „%s“" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Елемент адреÑе „%s“ не Ñадржи две тачке (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Ðазив транÑпорта у елементу адреÑе „%s“ не Ñме бити празан" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Пар кључ/вредноÑÑ‚ %d, „%s“, у елементу адреÑе „%s“ не Ñадржи знак једнакоÑти" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Пар кључ/вредноÑÑ‚ %d, „%s“, у елементу адреÑе „%s“ не Ñме задржати празан " +"кључ" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Грешка при неизбегавању кључа или вредноÑти у пару Кључ/ВредноÑти %d, „%s“, " +"у елементу адреÑе „%s“" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Грешка у адреÑи „%s“ — ЈуникÑов Ð¿Ñ€ÐµÐ½Ð¾Ñ Ð·Ð°Ñ…Ñ‚ÐµÐ²Ð° поÑтављање кључа " +"„path“ (путања) или „abstract“ (резиме)" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Грешка унутар адреÑе „%s“ — атрибут домаћина недоÑтаје или је неиÑправан" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Грешка унутар адреÑе „%s“ — порт недоÑтаје или је неиÑправан" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Грешка унутар адреÑе „%s“ — атрибут датотеке једнократних Ñлучајних бројева " +"недоÑтаје или је неиÑправан" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Грешка у Ñамопокретању: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "" +"Грешка приликом отварања датотеке једнократних Ñлучајних бројева „%s“: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Грешка при читању датотеке једнократних Ñлучајних бројева „%s“: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"Грешка при читању датотеке једнократних Ñлучајних бројева „%s“, очекивано 16 " +"бајтова, а добијено %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"Грешка приликом упиÑа Ñадржаја датотеке једнократних Ñлучајних бројева „%s“ " +"у ток:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Дата адреÑа је празна" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Ðе могу да изродим магиÑтралу поруке када је поÑтављено „AT_SECURE“" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ðе могу да покренем магиÑтралу порука без идентификације машине: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Ðе могу да Ñамопокренем Д-Ñабирницу без „X11 $DISPLAY“" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Грешка при покретању наредбе „%s“: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Ðе могу да одредим адреÑу магиÑтрале ÑеÑије (није направљено за овај " +"оперативни ÑиÑтем)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Ðе могу да одредим адреÑу магиÑтрале ÑеÑије из променљиве окружења " +"DBUS_STARTER_BUS_TYPE — непозната вредноÑÑ‚ „%s“" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ðе могу да одредим адреÑу магиÑтрале ÑеÑије јер није поÑтављена променљива " +"окружења DBUS_STARTER_BUS_TYPE" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Ðепознат тип магиÑтрале %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Ðеочекивани недоÑтатак Ñадржаја при читању линије" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Ðеочекивани недоÑтатак Ñадржаја при (Ñигурном) читању линије" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"ИÑтрошени Ñу Ñви доÑтупни механизми пријављивања (покушано: %s) (доÑтупно: " +"%s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "КориÑнички ИБ-ови морају бити иÑти и за парњака и за Ñервер" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Поништено преко GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Грешка приликом добављања података за директоријум „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Овлашћења фаÑцикле „%s“ Ñу неиÑправна. Очекивана вредноÑÑ‚ је била 0700, а " +"добијено је 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Грешка Ñтварања директоријума „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Радња није подржана" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Грешка приликом отварања привеÑка кључева „%s“ за читање: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Линија %d привеÑка кључева на „%s“ Ñа Ñадржајем „%s“ није иÑправна" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Први токен линије %d привеÑка кључева на „%s“ Ñа Ñадржајем „%s“ није иÑправан" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Други токен линије %d привеÑка кључева на „%s“ Ñа Ñадржајем „%s“ није " +"иÑправан" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "ÐиÑам нашао колачић Ñа идентификацијом %d у привеÑку кључева на „%s“" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Грешка при прављењу датотеке закључавања „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Грешка при бриÑању заоÑтале датотеке закључавања „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Грешка приликом затварања (неповезане) датотеке закључавања „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Грешка приликом одвезивању датотеке закључавања „%s“: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Грешка приликом отварања привеÑка кључева „%s“ за пиÑање: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Додатно, отпуштање кључа Ñа „%s“ такође није уÑпело: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Веза је затворена" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Време је иÑтекло" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Ðаишао Ñам на неподржане ознаке при изградњи клијентÑког дела везе" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Ðема интерфејÑа „org.freedesktop.DBus.Properties“ у објекту на путањи %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Ðема оÑобине „%s“" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "ОÑобина „%s“ није читљива" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Ðије могуће пиÑање оÑобине „%s“" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Грешка при поÑтављању оÑобине „%s“: Очекивани тип је био „%s“, а добијен је " +"„%s“" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Ðема таквог интерфејÑа „%s“" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Ðема таквог интерфејÑа „%s“ у објекту на путањи %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Ðема таквог метода „%s“" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Тип поруке, „%s“, не одговара очекиваном типу „%s“" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Објекат је већ извезен за Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÑ˜Ñ %s на %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Ðе могу да добијем оÑобину %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Ðе могу да поÑтавим оÑобину %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Метод „%s“ је вратио тип „%s“, али је био очекиван „%s“" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Метод „%s“ на интерфејÑу „%s“ Ñа потпиÑом „%s“ не поÑтоји" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Поддрво је већ извезено за %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Објекат не поÑтоји у путањи „%s“" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "врÑта је ÐЕИСПРÐÐ’ÐÐ" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Порука ПОЗИВÐ_МЕТОДÐ: недоÑтају поља заглавља ПУТÐЊРили ЧЛÐÐ" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Порука РЕЗУЛТÐТ_МЕТОДÐ: недоÑтаје поље заглавља ОДГОВОРИ_СЕРИЈСКИ" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Порука ГРЕШКЕ: недоÑтају поља заглавља ОДГОВОРИ_СЕРИЈСКИ или ÐÐЗИВ_ГРЕШКЕ" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Порука СИГÐÐЛÐ: недоÑтају поља заглавља ПУТÐЊÐ, СУЧЕЉЕ или ЧЛÐÐ" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Порука СИГÐÐЛÐ: поље заглавља ПУТÐЊРкориÑти резервиÑану вредноÑÑ‚ „/org/" +"freedesktop/DBus/Local“" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Порука СИГÐÐЛÐ: поље заглавља СУЧЕЉЕ кориÑти резервиÑану вредноÑÑ‚ „org." +"freedesktop.DBus.Local“" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Покушах да читам %lu бајт, али добих Ñамо %lu" +msgstr[1] "Покушах да читам %lu бајта, али добих Ñамо %lu" +msgstr[2] "Покушах да читам %lu бајтова, али добих Ñамо %lu" +msgstr[3] "Покушах да читам један бајт, али добих Ñамо %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Очекивао Ñам NUL бајт поÑле ниÑке „%s“, али Ñам нашао бајт %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Очекивах иÑправну УТФ-8 ниÑку, али нађох неиÑправне бајтове на бајт померају " +"%d (дужина ниÑке је %d). ИÑправна ниÑка до тог дела је била „%s“" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "ВредноÑÑ‚ је угнеждена предубоко" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Рашчлањена вредноÑÑ‚ „%s“ није иÑправна путања објекта Д-магиÑтрале" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Рашчлањена вредноÑÑ‚ „%s“ није иÑправан Ð¿Ð¾Ñ‚Ð¿Ð¸Ñ Ð”-магиÑтрале" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"Ðаишао Ñам на низ дужине %u бајт. Ðајвећа дужина је 2<<26 бајта (64 MiB)." +msgstr[1] "" +"Ðаишао Ñам на низ дужине %u бајта. Ðајвећа дужина је 2<<26 бајта (64 MiB)." +msgstr[2] "" +"Ðаишао Ñам на низ дужине %u бајтова. Ðајвећа дужина је 2<<26 бајтова (64 " +"MiB)." +msgstr[3] "" +"Ðаишао Ñам на низ дужине једног бајта. Ðајвећа дужина је 2<<26 бајтова (64 " +"MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Ðаиђох на низ врÑте „a%c“, очекивах да је дужина умножак од %u бајта, али " +"нађох да је дуг %u бајта" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Празне Ñтруктуре (н-торке) ниÑу дозвољене у Д-Ñабирници" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"Рашчлањена вредноÑÑ‚ „%s“ за варијанту није иÑправан Ð¿Ð¾Ñ‚Ð¿Ð¸Ñ Ð”-магиÑтрале" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Грешка при деÑеријализацији Гваријанта Ñа ниÑком врÑте „%s“ из жичаног " +"формата Д-магиÑтрале" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"ÐеиÑправна вредноÑÑ‚ за крајњоÑÑ‚. Очекивао Ñам 0x6c („l“) или 0x42 („Bд) али " +"Ñам нашао вредноÑÑ‚ 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "ÐеиÑправна главно издање протокола. Очекивано 1, али нађено %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "ÐŸÐ¾Ñ‚Ð¿Ð¸Ñ Ð·Ð°Ð³Ð»Ð°Ð²Ñ™Ð° је пронађен али он није врÑте потпиÑ" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "ÐŸÐ¾Ñ‚Ð¿Ð¸Ñ Ð·Ð°Ð³Ð»Ð°Ð²Ñ™Ð° Ñа потпиÑом „%s“ је нађен, али је тело поруке празно" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"Рашчлањена вредноÑÑ‚ „%s“ није иÑправан Ð¿Ð¾Ñ‚Ð¿Ð¸Ñ Ð”-магиÑтрале (за тело поруке)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Ðема заглавља потпиÑа у поруци, али тело поруке има %u бајт" +msgstr[1] "Ðема заглавља потпиÑа у поруци, али тело поруке има %u бајта" +msgstr[2] "Ðема заглавља потпиÑа у поруци, али тело поруке има %u бајтова" +msgstr[3] "Ðема заглавља потпиÑа у поруци, али тело поруке има један бајт" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Ðе могу да деÑеријализујем поруку: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Грешка при Ñеријализацији Гваријанта Ñа ниÑком врÑте „%s“ из жичаног формата " +"Д-магиÑтрале" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Број опиÑника датотеке у поруци (%d) Ñе разликује од заглавља поља (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Ðе могу да Ñеријализујем поруку: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Тело поруке има Ð¿Ð¾Ñ‚Ð¿Ð¸Ñ â€ž%s“, али недоÑтаје заглавље потпиÑа" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "Тело поруке има тип потпиÑа „%s“, али Ð¿Ð¾Ñ‚Ð¿Ð¸Ñ Ñƒ пољу заглавља је „%s“" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Тело поруке је празно,,, али је Ð¿Ð¾Ñ‚Ð¿Ð¸Ñ Ñƒ пољу заглавља „(%s)“" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Добијена је грешка Ñа телом поруке типа „%s“" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Добијена је грешка Ñа празним телом поруке" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Упишите било који знак да затворите овај прозор)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Д-магиÑтрала ÑеÑије није покренута, Ñамопокретање није уÑпело" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Ðе могу да добавим профил физичких делова: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Ðе могу да учитам „%s“ или „%s“: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Грешка при позиву покрени уÑлугу према називу за %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Ðеочекиван одговор %d од StartServiceByName(„%s“) метода" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ðе могу да позовем метод; поÑредник је за добро знани назив „%s“ без " +"влаÑника, а направљен је без G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START заÑтавице" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "ÐпÑтрактни именÑки проÑтор није подржан" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Ðе могу да наведем датотеку једнократних Ñлучајних бројева при повезивању Ñа " +"Ñервером" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "" +"Грешка приликом упиÑа датотеке једнократних Ñлучајних бројева на „%s“: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "ÐиÑка „%s“ није иÑправни ГЈИБ Д-Ñабирнице" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Ðе могу да Ñлушам на неподржаном преноÑном механизму „%s“" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Ðаредбе:\n" +" help Приказује ову информацију\n" +" introspect ИÑпитује удаљени објекат\n" +" monitor Ðадгледа удаљени објекат\n" +" call Позива начин на удаљеном објекту\n" +" emit Шаље Ñигнал\n" +" wait Чека да Ñе појави назив магиÑтрале\n" +"\n" +"КориÑтите „%s ÐÐРЕДБР--help“ да добијете помоћ за појединачне наредбе.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Грешка: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Грешка при рашчлањивању XML-а добијеног иÑпитивањем: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Грешка: „%s“ није иÑправан назив\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Грешка: %s није иÑправна путања до објеката\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Повезивање на ÑиÑтемÑку магиÑтрали" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Повезивање на магиÑтралу ÑеÑије" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Повезивање на задату Д-Ð±Ð°Ñ Ð°Ð´Ñ€ÐµÑу" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Опције крајње тачке везе:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Опције које одређују крајњу тачку везе" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Ðије наведена крајња тачка везе" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Ðаведено више крајњих тачака везе" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Упозорење: Према подацима добијеним иÑпитивањем, Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÑ˜Ñ â€ž%s“ не поÑтоји\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Упозорење: Према подацима добијеним иÑпитивањем, метод „%s“ не поÑтоји на " +"интерфејÑу „%s“\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Опционална деÑтинација Ñигнала (јединÑтвено име)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Путања објекта за емитовање Ñигнала" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Ðазив Ñигнала и Ñучеља" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Емитује Ñигнал." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Грешка у повезивању: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Грешка: „%s“ није иÑправан назив јединÑтвене магиÑтрале.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Грешка: Ðије изабрана путања до објекта\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Грешка: Име Ñигнала није одређено\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Грешка: Име Ñигнала „%s“ није одређено\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Грешка: „%s“ није иÑправан назив Ñучеља\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Грешка: „%s“ није иÑправан назив члана\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Грешка при обради параметра %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Грешка иÑпирања везе: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Ðазив одредишта на коме треба позвати метод" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Путања објекта на коме треба позвати метод" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Име метода и интерфејÑа" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Време иÑтека у Ñекундама" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Дозвољава међудејÑтвено овлашћивање" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Позивање метода на удаљеном објекту." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Грешка: Ðије изабрано одредиште\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Грешка: „%s“ није иÑправан назив магиÑтрале\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Грешка: Име начина није одређено\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Грешка: Име начина „%s“ није одређено\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Грешка при обради параметра %d врÑте „%s“: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Грешка додавања ручке %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Ðазив одредишта за иÑпитивање" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Путања објекта за иÑпитивање" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Штампа ИкÑМЛ" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "ПреиÑпитује чланове" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Само штампа ÑвојÑтва" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "ИÑпитајте удаљени објекат." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Ðазив одредишта за надгледање" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Путања објекта за надгледање" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Ðадгледање удаљеног објекта." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Грешка: не могу да надгледам везу на Ñабирници која није за поруке\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "УÑлуга за активирање пре чекања на другу (добро знан назив)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Време за чекање пре излаÑка Ñа грешком (Ñекунде); 0 — без временÑког рока " +"(оÑновно)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[ОПЦИЈÐ…] ÐÐЗИВ_МÐГИСТРÐЛЕ" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Чека да Ñе појави назив магиÑтрале." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Грешка: УÑлуга за активирање мора бити наведена.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Грешка: УÑлуга за чекање мора бити наведена.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Грешка: Превише аргумената.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Грешка: „%s“ није иÑправан назив добро знане магиÑтрале.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "ÐиÑте овлашћени да измените поÑтавке прочишћавања" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Ðеименовано" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Датотека за радну површ не Ñадржи Exec уноÑ" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Ðе могу да нађем терминал ради покретања овог програма" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Ðе могу да направим фаÑциклу за кориÑникова подешавања %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Ðе могу да направим фаÑциклу за кориÑникова МИМЕ подешавања %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Подацима о програму недоÑтаје идентификатор" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Ðе могу да направим датотеку радне површи %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Произвољне одреднице за %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "уређај не подржава „избаци“" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "уређај не подржава „избаци“ или „избаци_Ñа_операцијом“" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "није подржано извлачење медијума на уређају" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "уређај не подржава „покрени“" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "уређај не подржава „зауÑтави“" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "ТЛС позадинац не подржава добаваљање ТЛС повезивања" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "ТЛС подршка није доÑтупна" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "ДТЛС подршка није доÑтупна" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Ðе могу да радим Ñа издањем %d кодирања ГЕмблема" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "ÐеиÑправно задат број токена (%d) у кодирању ГЕмблема" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Ðе могу да радим Ñа издањем %d кодирања иконице ГЕмблема" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Ðије иÑправно задат број токена (%d) у кодирању иконице ГЕмблема" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Очекивано је ГЕмблем за иконицу ГЕмблема" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Садржано монтирање не поÑтоји" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Ðе могу да умножим преко директоријума" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Ðе могу да умножим директоријум преко директоријума" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Циљна датотека већ поÑтоји" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Ðе могу да умножим директоријум и његов Ñадржај" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Дељење није подржано" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Грешка приликом дељења датотеке: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Ðије подржано умножавање (reflink/clone) између монтираних уређаја" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Умножавање (reflink/clone) није подржано или је неиÑправно" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Умножавање (reflink/clone) није подржано или не ради" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Ðе могу да умножим Ñпецијалну датотеку" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Дата је неиÑправна Ñимболичка веза" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Ðије подржано Ñмеће" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Имена датотека не могу да Ñадрже „%c“" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "није подржано монтирање диÑка" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Ðи један програм не може да отвори ову датотеку" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Ðабрајање је затворено" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Бројање датотека има неиÑпуњену радњу" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Бројање датотека је већ завршено" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Ðе могу да радим Ñа издањем %d кодирања иконице ГДатотеке" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Лоши улазни подаци за иконицу ГДатотеке" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Ток не подржава „пропитај_податке“" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Ðије подржавано премотавање тока" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "СаÑецање није дозвољену над улазним током" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "СаÑецање није дозвољено над током" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "ÐеиÑправно име домаћина" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Лош одговор од ХТТП поÑредника" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Ðије дозвољена веза Ñа поÑредником за ХТТП" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Ðије уÑпела пријава на поÑредника за ХТТП" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Потребна је пријава на поÑредника за ХТТП" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Ðије уÑпело веза Ñа поÑредником за ХТТП: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Одговор ХТТП поÑредника је превелик" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Сервер ХТТП поÑредника је неочекивано прекинуо везу." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Ðије иÑправан број токена (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Ðе поÑтоји врÑта за назив клаÑе %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Ð’Ñ€Ñта %s не подржава Ñучеље ГИконице" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Ð’Ñ€Ñта %s не припада ни једној клаÑи" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Број издања је лоше задат: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s врÑта не подржава „from_tokens()“ на Ñучељу ГИконице" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Ðе могу да радим Ñа датим издањем кодирања иконице" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Ðије наведена адреÑа" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Дужина %u је превише дуга за адреÑу" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ÐдреÑа има Ñкуп битова преко дужине префикÑа" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Ðе могу да обрадим „%s“ као маÑку ИП адреÑе" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Ðема довољно меÑта за адреÑу утичнице" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Ðије подржана адреÑа утичнице" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Улазни ток не подржава читање" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Ток ради јако добро" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Умножи Ñа датотеком" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Задржи Ñа датотеком приликом премештања" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "„version“ не прихвата аргументе" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Употреба:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "ИÑпиÑује податке о издању и излази." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Ðаредбе:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Ðадовезује датотеке на Ñтандардни излаз" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Умножава једну или више датотека" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Приказује податке о меÑтима" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Покреће програм из датотеке радне површи" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "ИÑпиÑује Ñадржај меÑта" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Добавља и поÑтавља руковаоца за миме врÑту" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Прави директоријуме" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Прати датотеке и директоријуме за изменама" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Качи или откачиње меÑта" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Премешта једну или више датотека" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Отвара датотеке оÑновним програмом" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Преименује датотеку" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Брише једну или више датотека" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Чита Ñа Ñтандардног улаза и чува" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Подешава атрибут датотеке" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Премешта датотеке или директоријуме у Ñмеће" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "ИÑпиÑује Ñадржај меÑта у Ñтаблу" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "КориÑтите „%s“ да добавите опширнију помоћ.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Грешка пиÑања на Ñтандардни излаз" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:91 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "МЕСТО" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Ðадовезује датотеке и иÑпиÑује на Ñтандардни излаз." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"„gio cat“ ради баш као традиционално помагало „cat“, али кориÑти ГИО\n" +"меÑта умеÑто меÑних датотека: на пример, можете кориÑтити нешто\n" +"као „smb://server/resource/datoteka.txt“ као меÑто." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Ðије дато меÑто" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ðема циљне датотеке" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Приказује напредак" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Пита пре препиÑивања" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Очувава Ñве атрибуте" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Прави резерву поÑтојећих одредишних датотека" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Ðикада не прати Ñимболичке везе" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "КориÑти подразумевана овлашћења за одредиште" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Пренешено је %s од %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ИЗВОР" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ОДРЕДИШТЕ" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Умножава једну или више датотека из ИЗВОРРу ОДРЕДИШТЕ." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"„gio copy“ је Ñличан традиционалном помагалу „cp“, али кориÑти ГИО\n" +"меÑта умеÑто меÑних датотека: на пример, можете кориÑтити нешто\n" +"као „smb://server/resource/datoteka.txt“ као меÑто." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "Одредиште „%s“ није директоријум" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: да препишем „%s“? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "ИÑпиÑује иÑпиÑиве атрибуте" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Добавља податаке о ÑиÑтему датотека" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Ðтрибути за добављање" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ÐТРИБУТИ" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ðе прати Ñимболичке везе" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "атрибути:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "назив приказа: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "назив уређивања: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "назив: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "врÑта: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "величина: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "Ñкривено\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "путања: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "локална путања: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "Ñ˜ÑƒÐ½Ð¸ÐºÑ ÐºÐ°Ñ‡ÐµÑšÐµ: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "ПодеÑиве оÑобине:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Ðазивни проÑтори запиÑиве оÑобине:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Приказује податке о меÑтима." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"„gio info“ је Ñличан традиционалном помагалу „ls“, али кориÑти ГИО\n" +"меÑта умеÑто меÑних датотека: на пример, можете кориÑтити нешто\n" +"као „smb://server/resource/datoteka.txt“ као меÑто. Ðтрибути датотеке Ñе " +"могу\n" +"навеÑти њиховим ГИО називом, тј. „standard::icon“, или Ñамо\n" +"називним проÑтором, тј. „unix“, или Ñа „*“, која одговара Ñвим атрибутима" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "ДÐТОТЕКÐ-РÐДÐЕ_ПОВРШИ [ÐРГУМЕÐТ-ДÐТОТЕКЕ …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Покрените програм из радне површи, проÑлеђујући јој изборне аргументе назива " +"датотеке." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Ðије дата датотека радне површи" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Ðаредба покретања није тренутно подржана на овој платформ" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Ðе могу да учитам „%s“: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Ðе могу да учитам податке програма за „%s“" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Ðе могу да покренем програм „%s“: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Приказује Ñкривене датотеке" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "КориÑти дуги Ð·Ð°Ð¿Ð¸Ñ ÑпиÑка" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "ИÑпиши приказна имена" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Штампа пуне путање" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "ИÑпиÑује Ñадржаје меÑта." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"„gio list“ је Ñличан традиционалном помагалу „ls“, али кориÑти ГИО\n" +"меÑта умеÑто меÑних датотека: на пример, можете кориÑтити нешто\n" +"као „smb://server/resource/datoteka.txt“ као меÑто. Ðтрибути датотеке Ñе " +"могу\n" +"навеÑти њиховим ГИО називом, тј. „standard::icon“" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "МИМЕВРСТÐ" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "РУКОВÐЛÐЦ" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Добавља и поÑтавља руковаоца за миме врÑту." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Ðко није дат руковалац, иÑпиÑује региÑтроване и препоручене програме\n" +"за миме врÑту. Ðко је руковалац дат, поÑтавља Ñе као оÑновни\n" +"руковалац за миме врÑту." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Морате навеÑти једну миме врÑту, и можда руковаоца" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "нема оÑновног програма за „%s“\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "ОÑновни програм за „%s“: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Забележени програми:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Ðема забележених програма\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Препоручени програми:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Ðема препоручених програма\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "ÐиÑам уÑпео да учитам податке за руковаоца „%s“" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "ÐиÑам уÑпео да подеÑим „%s“ као оÑновног руковаоца за „%s“: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Прави родитељÑке директоријуме" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Прави директоријуме." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"„gio cmkdir“ је Ñличан традиционалном помагалу „mkdir“, али кориÑти ГИО\n" +"меÑта умеÑто меÑних датотека: на пример, можете кориÑтити нешто\n" +"као „smb://server/resource/mojdirektorijum“ као меÑто." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Прати директоријум (оÑновно: завиÑи од врÑте)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Прати датотеку (оÑновно: завиÑи од врÑте)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Прати датотеку директно (запажа измене учињене путем чврÑтих веза)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Прати датотеку директно, али не извештава о изменама" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Извештава о премештањима и преименовањима као о једном догађају бриÑања/" +"Ñтварања" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Гледа догађаје качења" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Прати датотеке или директоријуме за изменама." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Качи као прикачљивом" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Закачи волумен Ñа уређај-датотеком или другим идентификатором" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ИБ" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Откачи" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Избаци" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "ЗауÑтави уређај Ñа уређај-датотеком" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "УРЕЂÐЈ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Откачиње Ñва качења датом шемом" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ШЕМÐ" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Занемарује заоÑтале радње датотеке када откачиње или избацује" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "КориÑти анонимног кориÑника приликом потврде идентитета" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "ИÑпиши" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Прати догађаје" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Приказује додатне податке" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Бројевни ЛИЧ (PIM) приликом откључавања Веракрипт волумена" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "ЛИЧ (PIM)" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Закачи ТКРИПТ Ñкривени волумен" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Закачи ТКРИПТ ÑиÑтемÑки волумен" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Ðнониман приÑтуп је забрањен" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Ðема уређаја за уређај-датотеку" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Ðема волумена за дати ИБ" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Качи или откачиње меÑта." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ðе кориÑти умножак и брише враћање на Ñтаро" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Премешта једну или више датотека из ИЗВОРРу ОДРЕДИШТЕ." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"„gio move“ је Ñличан традиционалном помагалу „mv“, али кориÑти ГИО\n" +"меÑта умеÑто меÑних датотека: на пример, можете кориÑтити нешто\n" +"као „smb://server/resource/datoteka.txt“ као меÑто" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "Циљ „%s“ није директоријум" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Отворите датотеке оÑновним програмом који је\n" +"региÑтрован за рад Ñа датотекама ове врÑте." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Занемарује непоÑтојеће датотеке, никада не поÑтавља упит" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Обришите дате датотеке." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "ÐÐЗИВ" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Преименујте датотеку." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "ÐедоÑтаје аргумент" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:139 +msgid "Too many arguments" +msgstr "Превише аргумената" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Преименовање је уÑпело. Ðова путања: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Прави Ñамо ако је непоÑтојећа" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Додаје на крај датотеке" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Приликом Ñтварања, ограничава приÑтуп на тренутног кориÑника" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Приликом замене, замењује као да одредиште не поÑтоји" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Штампа нову е-ознаку на крају" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Е-ознака датотеке која је препиÑана" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "Е-ОЗÐÐКÐ" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Грешка читања Ñа Ñтандардног улаза" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Е-ознака није доÑтупна\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Чита Ñа Ñтандардног улаза и чува у ОДРЕДИШТЕ." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Ðије дато одредиште" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Ð’Ñ€Ñта атрибута" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "ВРСТÐ" + +#: gio/gio-tool-set.c:91 +msgid "ATTRIBUTE" +msgstr "ÐТРИБУТ" + +#: gio/gio-tool-set.c:91 +msgid "VALUE" +msgstr "ВРЕДÐОСТ" + +#: gio/gio-tool-set.c:95 +msgid "Set a file attribute of LOCATION." +msgstr "Подешава атрибут датотеке за МЕСТО." + +#: gio/gio-tool-set.c:115 +msgid "Location not specified" +msgstr "Ðије наведено меÑто" + +#: gio/gio-tool-set.c:122 +msgid "Attribute not specified" +msgstr "Ðије наведен атрибут" + +#: gio/gio-tool-set.c:132 +msgid "Value not specified" +msgstr "Ðије наведена вредноÑÑ‚" + +#: gio/gio-tool-set.c:182 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "ÐеиÑправна врÑта атрибута „%s“" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Празни Ñмеће" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "ИÑпиÑује датотеке у Ñмећу Ñа њиховим изворним меÑтима" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Враћа датотеку из Ñмећа на њено изворно меÑто (по могућÑтву поновно " +"Ñтварајући директоријум)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Ðе могу да нађем изворну путању" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Ðе могу поново да направим изворно меÑто: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Ðе могу да премеÑтим датотеку на њено изворно меÑто: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Премешта/враћа датотеке или директоријуме у Ñмеће." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Ðапомена: за „--restore“ прекидач, ако изворно меÑто датотеке у Ñмећу \n" +"већ поÑтоји, неће бити препиÑана оÑим ако „--force“ није поÑтављено." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Дато меÑто не почиње Ñа „trash:///“" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Прати Ñимболичке везе, качења и пречице" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "ИÑпиÑује Ñадржај директоријума у запиÑу Ñтабла." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Елемент <%s> није дозвољен унутар <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Елемент <%s> није дозвољен на највишем нивоу" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Датотека „%s“ Ñе појављује више пута у извору" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "ÐиÑам уÑпео да пронађем „%s“ ни у јеном изворном директоријуму" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "ÐиÑам уÑпео да пронађем „%s“ у текућем директоријуму" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Ðепозната опција обраде „%s“" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Преобрада Ñтавке „%s“ је затражена али Ñтавка „%s“ није подешена и Ñтавка " +"„%s“ није у ПУТÐЊИ" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Грешка при Ñажимању датотеке „%s“" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "текÑÑ‚ не може да Ñе појављује унутар <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Приказује издање програма и излази" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Ðазив излазне датотеке" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Директоријуми из којих ће датотеке дефиниÑане у ДÐТОТЕЦИ бити учитане " +"(подразумевано: тренутни директоријум)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "ДИРЕКТОРИЈУМ" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Ствара излаз у формату изабраном проширењем назива циљне датотеке" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Ствара заглавље извора" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Ствара изворни код коришћен да повеже датотеку реÑурÑа у ваш код" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Ствара ÑпиÑак завиÑноÑти" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Ðазив датотеке завиÑноÑти за Ñтварање" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Укључује лажне мете у Ñтвореној датотеци завиÑноÑти" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Ðе Ñтвара ÑамоÑтално и не бележи извор" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ðе извози функције; објављује их „Г_ГÐУЦ_УÐУТРÐШЊИМ“" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Ðе угнежђујте реÑурÑне податке у Це датотеку, умеÑто тога претпоÑтавите да " +"је повезан (линкована) Ñпоља" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "Ðазив Ц одредника коришћеног за Ñтворени изворни код" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Ц преводилац мете (оÑновно: променљива ЦЦ окружења)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Преводи одредницу реÑурÑа у датотеку реÑурÑа.\n" +"Датотеке одреднице реÑурÑа имају проширење „.gresource.xml“,\n" +"а датотеке реÑурÑа имају проширење „.gresource“." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Треба да наведете тачно један назив датотеке\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "надимак мора бити најмање 2 знака" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "ÐеиÑправна бројевна вредноÑÑ‚" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr "„“ је већ наведено" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' је већ наведено" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "вредноÑти заÑтавица морају имати највише 1 подешен бит" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> мора Ñадржати барем једну <вредноÑÑ‚>" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> није Ñадржано у наведеном опÑегу" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> није иÑправан члан наведене набројане врÑте" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> Ñадржана ниÑка није у наведеној врÑти заÑтавице" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> Ñадржана ниÑка није у " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " је већ наведен за овај кључ" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " није допуштен за кључеве врÑте „%s“" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " наведени минимум је већи од макÑимума" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "неподржана „l10n“ категорија: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "„l10n“ је затражено, али није дат домен геттекÑта" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "дат је контекÑÑ‚ превода за вредноÑÑ‚ без укљученог „l10n“" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "ÐиÑам уÑпео да обрадим вредноÑÑ‚ врÑте „%s“: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" Ñе не може навеÑти за кључеве означене да имају набројану врÑту" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " је већ наведен за овај кључ" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " није допуштен за кључеве врÑте „%s“" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " је већ дато" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " мора да Ñадржи барем један " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " је већ наведен за овај кључ" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" Ñе може навеÑти једино за кључеве Ñа набројаним или Ñа врÑтама " +"заÑтавица или након " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr " је дато када је „%s“ већ члан набројане врÑте" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr " је дато када је већ дато " + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " је већ наведено" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "мета алијаÑа „%s“ није у набројаној врÑти" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "мета алијаÑа „%s“ није у " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " мора да Ñадржи барем један " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Празни називи ниÑу дозвољени" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "ÐеиÑправан назив „%s“: називи морају да почињу малим Ñловом" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"ÐеиÑправан назив „%s“: неиÑправан знак „%c“; Ñамо мала Ñлова, бројеви и " +"цртица („-“) Ñу дозвољени" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "ÐеиÑправан назив „%s“: две узаÑтопне цртице („--“) ниÑу дозвољене" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "ÐеиÑправан назив „%s“: поÑледњи знак не може да буде цртиица („-“)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "ÐеиÑправан назив „%s“: највећа дужина је 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " је већ наведено" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Ðе могу да додам кључеве у шему „list-of“" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " је већ наведено" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" прекрива у ; кориÑтите " +" да измените вредноÑÑ‚" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Тачно једна Ñтвар од „type“, „enum“ или „flags“ мора бити наведена као " +"атрибут за " + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> није (још) дефиниÑано." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "ÐеиÑправна врÑта ниÑке ГВаријанта „%s“" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " је дато, али шема не проширује ништа" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Ðема за преклапање" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " је већ наведено" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " је већ наведено" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " проширује још увек непоÑтојећу шему „%s“" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " је ÑпиÑак још увек непоÑтојеће шеме „%s“" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Ðе може бити ÑпиÑак шеме Ñа путањом" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Ðе могу да проширим шему Ñа путањом" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" је ÑпиÑак који проширује која није ÑпиÑак" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" проширује али " +"„%s“ не проширује „%s“" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Путања, ако Ñе наводи мора да почиње и завршава Ñа коÑом цртом" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Путања ÑпиÑка мора да Ñе завршава Ñа „:/“" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Упозорење: Шема „%s“ има путању „%s“. Путање које почињу на „/apps/“, „/" +"desktop/“ или „/system/“ Ñу заÑтареле." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id=„%s“> је већ наведено" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Само један <%s> елемент је дозвољен унутар <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Елемент <%s> није дозвољен на највишем нивоу" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Елемент је затражен у " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "ТекÑÑ‚ не може да Ñе појављује унутар <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Упозорење: неодређена упута ка " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "„--strict“ је наведено; излазим." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Ова читава датотека је занемарена." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Занемарујем ову датотеку." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Ðе поÑтоји кључ „%s“ у шеми „%s“ као што је наведено у датотеци замене „%s“; " +"занемарујем премошћење за овај кључ." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Ðе поÑтоји кључ „%s“ у шеми „%s“ као што је наведено у датотеци замене „%s“ " +"и „--strict“ заÑтавица је дата; излазим." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Ðе могу доÑтавити премошћења за локализовани кључ „%s“, за Ñваку радну површ " +"понаоÑоб, у шеми „%s“ (датотека премошћења „%s“); занемарујем премошћење за " +"овај кључ." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Ðе могу доÑтавити премошћења за локализовани кључ „%s“, за Ñваку радну површ " +"понаоÑоб, у шеми „%s“ (датотека премошћења „%s“) и заÑтавица „--strict“ је " +"наведена; излазим." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Грешка у тумачењу кључа „%s“ у шеми „%s“ као што је наведено у датотеци " +"премошћења „%s“: %s. Занемарујем премошћење за оај кључ." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Грешка у тумачењу кључа „%s“ у шеми „%s“ као што је наведено у датотеци " +"премошћења „%s“: %s. ЗаÑтавица „--strict“ је наведена, излазим." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Премошћење за кључ „%s“ у шеми „%s“, у датотеци премошћења „%s“ је изван " +"опÑега датог у шеми; занемарујем премошћење за овај кључ." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Премошћење за кључ „%s“, у шеми „%s“, у датотеци премошћења „%s“ је изван " +"опÑега датог у шеми и заÑтавица „--strict“ је наведена; излазим." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Премошћење за кључ „%s“, у шеми „%s“, у датотеци премошћења „%s“ није у " +"ÑпиÑку дозвољених избора; занемарујем премошћење на овај кључ." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Премошћење за кључ „%s“, у шеми „%s“, у датотеци премошћења „%s“ није у " +"ÑпиÑку дозвољених избора и заÑтавица „--strict“ је наведена; излазим." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Где да Ñкладиштим „gschemas.compiled“ датотеку" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Прекини при било којој грешци у шемама" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Ðе упиÑуј „gschemas.compiled“ датотеку" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Ðе намеће ограничења назива кључа" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Преводи Ñве датотеке шема ГПодешавања у кеш шема.\n" +"Датотеке шема морају да Ñе завршавају Ñа „.gschema.xml“,\n" +"а датотеке кеша имају назив „gschemas.compiled“." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Требате навеÑти тачно један назив фаÑцикле" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Ðиједна датотека Ñа шемама није нађена: не радим било шта." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "" +"Ðиједна датотека Ñа шемама није нађена: уклањам поÑтојећу излазну датотеку." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "ÐеиÑправан назив датотеке %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Грешка добављања података о ÑиÑтему датотека за „%s“: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "ÐиÑам нашао Ñадржано качење за датотеку „%s“" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Ðе могу да преименујем корени директоријум" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Грешка преименовања датотеке „%s“: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Ðе могу да преименујем датотеку, назив датотеке већ поÑтоји" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "ÐеиÑправан назив датотеке" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Грешка отварања датотеке „%s“: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Грешка уклањања датотеке „%s“: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Грешка премештања датотеке „%s“ у Ñмеће: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Ðе могу да направим директоријум за Ñмеће %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Ðе могу да нађем корени директоријум да бацим у Ñмеће „%s“" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Ðије подржано Ñтварање Ñмећа на ÑиÑтемÑким унутрашњим тачкама качења" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Ðе могу да нађем или направим директоријум „%s“ за Ñмеће „%s“" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Ðе могу да направим датотеку података Ñмећа за „%s“: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Ðе могу да бацим у Ñмеће датотеку „%s“ преко граница ÑиÑтема датотека" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Ðе могу да бацим датотеку „%s“ у Ñмеће: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Ðе могу да бацим датотеку „%s“ у Ñмеће" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Грешка Ñтварања директоријума „%s“: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "СиÑтем датотека не подржава Ñимболичке везе" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Грешка Ñтварања Ñимболичке везе „%s“: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Грешка премештања датотеке „%s“: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Ðе могу да премеÑтим директоријум преко директоријума" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Ðије уÑпела израда резервне датотеке" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Грешка уклањања циљне датотеке: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Ðије подржано премештање између монтираних уређаја" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ðе могу да одредим иÑкоришћеноÑÑ‚ диÑка за „%s“: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "ВредноÑÑ‚ оÑобине мора бити различита од NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Ðије иÑправна врÑта атрибута (очекивана је ниÑка знакова)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Ðије иÑправан назив проширене оÑобине" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Грешка приликом поÑтављања проширене оÑобине „%s“: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (неиÑправно кодирање)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Грешка приликом добављања података за датотеку „%s“: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Грешка приликом добављања података за опиÑника датотеке: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ðије иÑправна врÑта оÑобине („uint32“ је очекивано)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ðије иÑправна врÑта оÑобине („uint64“ је очекивано)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ðије иÑправна врÑта оÑобине (очекивана је ниÑка битова)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Ðе могу да поÑтавим овлашћења за Ñимболичке везе" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Грешка приликом поÑтављања овлашћења: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Грешка приликом поÑтављања влаÑника: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "Ñимболичке везе морају бити различите од NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Грешка приликом поÑтављања Ñимболичке везе: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Грешка при поÑтављању Ñимболичке везе: датотека није Ñимболичка веза" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Додатне наноÑекунде %d за ЈУÐИКС временÑки жиг %lld Ñу негативне" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Додатне наноÑекунде %d за ЈУÐИКС временÑки жиг %lld Ñу доÑегле једну Ñекунду" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "ЈУÐИКС временÑки жиг %lld не може Ñтати у 64 бита" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "ЈУÐИКС временÑки жиг %lld је ван опÑега којег подржава ВиндоуÑ" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Ðазив датотеке „%s“ Ñе не може претворити у УТФ-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Датотека „%s“ Ñе не може отворити: Ð’Ð¸Ð½Ð´Ð¾ÑƒÑ Ð³Ñ€ÐµÑˆÐºÐ° %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Грешка при поÑтављању датума измене или приÑтупа за датотеку „%s“: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Грешка при поÑтављању датума измене или приÑтупа: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "Ð¡Ð•Ð›Ð¸Ð½ÑƒÐºÑ ÐºÐ¾Ð½Ñ‚ÐµÐºÑÑ‚ не Ñме бити NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "Ð¡Ð•Ð›Ð¸Ð½ÑƒÐºÑ Ð½Ð¸Ñ˜Ðµ укључен на вашем ÑиÑтему" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Грешка приликом поÑтављања Ð¡Ð•Ð›Ð¸Ð½ÑƒÐºÑ ÐºÐ¾Ð½Ñ‚ÐµÐºÑта: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Ðије подржано поÑтављање оÑобине %s" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Грешка приликом читања датотеке: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Грешка приликом затварања датотеке: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Грешка приликом претраге унутар датотеке: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Ðе могу да пронађем подразумевану, локалну врÑту монитора датотеке" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Грешка приликом упиÑа у датотеку: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Грешка приликом уклањања Ñтаре резервне копије везе: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Грешка приликом образовања резервне копије: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Грешка приликом преименовања привремене датотеке: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Грешка при ÑаÑецању датотеке: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Грешка отварања датотеке „%s“: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Циљна датотека је директоријум" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Циљна датотека није обична датотека" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Датотека је измењена Ñпољним програмом" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Грешка приликом уклањања Ñтаре датотеке: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Ðије иÑправно одређена врÑта ГПретраге" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "ÐеиÑправан захтев претраге" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ðе могу да Ñкратим улазни ток ГМеморије" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Величина излазне меморије Ñе не може променити" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "ÐиÑам уÑпеода променим величину излазног меморијÑког тока" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "Има више меморије за ÑƒÐ¿Ð¸Ñ Ð½ÐµÐ³Ð¾ што има меÑта у датој адреÑи" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Захтевано је премотавање на део пре почетка тока" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Захтевано је премотавање на део након завршетка тока" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "монтирање не подржава „unmount“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "монтирање не подржава „eject“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "монтирање не подржава „unmount“ или „unmount_with_operation“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "монтирање не подржава „eject“ или „eject_with_operation“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "монтирање не подржава „remount“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "монтирање не подржава налажење врÑте Ñадржаја" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "монтирање не подржава уÑклађено налажење врÑте Ñадржаја" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Име домаћина „%s“ Ñадржи „[“, али не и „]“" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Мрежа је недоÑтижна" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Домаћин је недоÑтижан" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ðе могу да направим праћење мреже: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Ðе могу да направим праћење мреже: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Ðе могу да добавим Ñтање мреже: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "Управник мреже није покренут" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Издање управника мреже је превише Ñтаро" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Излазни ток не подржава упиÑ" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Збир вектора доÑтављених у „%s“ је превелик" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Изворни ток је већ затворен" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Грешка у разрешавању „%s“: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "Ставка „%s“ није израђена" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "ÐеиÑправан домен" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "РеÑÑƒÑ€Ñ â€ž%s“ не поÑтоји" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "РеÑÑƒÑ€Ñ Ð½Ð° „%s“ није уÑпео да Ñе раÑпакује" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "РеÑÑƒÑ€Ñ Ð½Ð° „%s“ није директоријум" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Улазни ток не подржава премотавање" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Ðаводи одељке који Ñадрже реÑурÑе у елф ДÐТОТЕЦИ" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Ðаводи реÑурÑе\n" +"Ðко је дато ОДЕЉÐК, наводи Ñамо реÑурÑе у том одељку\n" +"Ðко је дато ПУТÐЊÐ, наводи Ñамо одговарајуће реÑурÑе" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "ДÐТОТЕКР[ПУТÐЊÐ]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "ОДЕЉÐК" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Ðаводи реÑурÑе Ñа појединоÑтима\n" +"Ðко је дато ОДЕЉÐК, наводи Ñамо реÑурÑе у том одељку\n" +"Ðко је дато ПУТÐЊÐ, наводи Ñамо одговарајуће реÑурÑе\n" +"У појединоÑти Ñпадају одељак, величина и Ñажимање" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Извлачи датотеку реÑурÑа у Ñтандардни излаз" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "ПУТÐЊРДÐТОТЕКЕ" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Употреба:\n" +" gresource [--section ОДЕЉÐК] ÐÐРЕДБР[ÐРГУМЕÐТИ…]\n" +"\n" +"Ðаредбе:\n" +" help Приказује ово обавештење\n" +" sections ИÑпиÑује одељке реÑурÑа\n" +" list ИÑпиÑује реÑурÑе\n" +" details ИÑпиÑује реÑурÑе Ñа појединоÑтима\n" +" extract Извлачи реÑурÑ\n" +"\n" +"КориÑтите „gresource help ÐÐРЕДБГ да прикажете опширнију помоћ.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Коришћење:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " ОДЕЉÐК Ðазив (опционално) елф одељка\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " ÐÐРЕДБРÐаредба (опционално) за објашњавање\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " ДÐТОТЕКРЕлф датотека (извршна или дељена библиотека)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" ДÐТОТЕКРЕлф датотека (извршна или дељена библиотека)\n" +" или преведена датотека реÑурÑа\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[ПУТÐЊÐ]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " ПУТÐЊРПутања (опционално) реÑурÑа (може бити делимична)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "ПУТÐЊÐ" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " ПУТÐЊРПутања реÑурÑа\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Ðема такве шеме „%s“\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Шема „%s“ није премеÑтљива (путања не Ñме бити наведена)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Шема „%s“ је премеÑтљива (путања мора бити наведена)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Дата је празна путања.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Путања мора почети коÑом цртом (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Путања мора да Ñе заврши коÑом цртом (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Путања не Ñме да Ñадржи две ÑуÑедне коÑе црте (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Обезбеђена вредноÑÑ‚ је изван важећег опÑега\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "У овај кључ Ñе не може упиÑивати\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Ðаводи инÑталиране (непремеÑтљиве) шеме" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Ðаводи инÑталиране премеÑтљиве шеме" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Ðаводи кључеве у ШЕМИ" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "ШЕМР[:ПУТÐЊÐ]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Ðаводи проиÑтекле из ШЕМЕ" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Ðаводи кључеве и вредноÑти, рекурзивно\n" +"Ðко СХЕМРније дата, наводи Ñве кључеве\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[ШЕМÐ[:ПУТÐЊÐ]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Добавља вредноÑÑ‚ кључа" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "ШЕМР[:ПУТÐЊÐ] КЉУЧ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Пропитује опÑег важећих вредноÑти за КЉУЧ" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Пропитује Ð¾Ð¿Ð¸Ñ Ð·Ð° КЉУЧ" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "ПоÑтавља вредноÑÑ‚ КЉУЧРна ВРЕДÐОСТ" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ШЕМР[:ПУТÐЊÐ] КЉУЧ ВРЕДÐОСТ" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Поново поÑтавља КЉУЧ на подразумевану вредноÑÑ‚" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Враћа Ñве кључеве у СХЕМИ на оÑновне вредноÑти" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Проверава да ли је КЉУЧ упиÑив" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Прати КЉУЧ за изменама.\n" +"Ðко није наведен ниједан КЉУЧ, прати Ñве кључеве у ШЕМИ.\n" +"КориÑтите „^C“ да зауÑтавите праћење.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ШЕМР[:ПУТÐЊÐ] [КЉУЧ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Коришћење:\n" +" gsettings --version\n" +" gsettings [--schemadir ШЕМÐДИР] ÐÐРЕДБР[ÐРГУМЕÐТИ…]\n" +"\n" +"Ðаредба:\n" +" help Приказује ову информацију\n" +" list-schemas Ðаводи инÑталиране шеме\n" +" list-relocatable-schemas Ðаводи премеÑтљиве шеме\n" +" list-keys Ðаводи кључеве у шеми\n" +" list-children Ðаводи проиÑтекле из шеме\n" +" list-recursively Ðаводи кључеве и вредноÑти, дубинÑки\n" +" range Пропитује опÑег кључа\n" +" describe Пропитује Ð¾Ð¿Ð¸Ñ ÐºÑ™ÑƒÑ‡Ð°\n" +" get Ðабавља вредноÑÑ‚ кључа\n" +" set Подешава вредноÑÑ‚ кључа\n" +" reset Поново подешава вредноÑÑ‚ кључа\n" +" reset-recursively Враћа Ñве вредноÑти у датој шеми\n" +" writable Проверава да ли је кључ упиÑив\n" +" monitor Ðадгледа измене\n" +"\n" +"КориÑтите „gsettings help ÐÐРЕДБГ да добијете детаљнију помоћ.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Коришћење:\n" +" gsettings [--schemadir ШЕМÐДИР] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " ШЕМÐДИР Директоријум за тражење додатних шема\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" ШЕМРИме шеме\n" +" ПУТÐЊРПутања, за премеÑтиве шеме\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " КЉУЧ (изборни) кључ унутар шеме\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " КЉУЧ Кључ унутар шеме\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " ВРЕДÐОСТ ВредноÑÑ‚ за подешавање\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Ðе могу да учитам шеме из „%s“: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Ðиједна шема није инÑталирана\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Дат је празан назив шеме\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Ðема таквог кључа „%s“\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "ÐеиÑправна утичница, није покренуто" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ÐеиÑправна утичница, покретање није уÑпело због: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Утичница је већ затворена" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "ИÑтекло време за У/И утичнице" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "правим ГУтичницу из фд-а: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ðе могу да направим утичницу: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Задата је непозната породица" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Задат је непознати протокол" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Ðе могу да кориÑтим датаграм радње над недатаграмÑком утичницом." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Ðе могу да кориÑтим датаграмÑке радње над утичницом Ñа подешеним иÑтицањем " +"времена." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "не могу да добијем локалну адреÑу: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "не могу да добијем удаљену адреÑу: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "не могу да Ñлушам: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Грешка при повезивању на адреÑу %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Грешка приликом приÑтупања групи вишеÑтруког емитовања: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Грешка приликом напуштања групе вишеÑтруког емитовања: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Ðема подршке за поÑебно вишеÑтруко емитовање извора" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Ðије подржана породица утичнице" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "поÑебни извор није ИПв4 адреÑа" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Ðазив интерфејÑа је предугачак" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÑ˜Ñ Ð½Ð¸Ñ˜Ðµ нађен: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Ðема подршке за поÑебно вишеÑтруко емитовање ИПв4 извора" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Ðема подршке за поÑебно вишеÑтруко емитовање ИПв6 извора" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "грешка у прихватању везе: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Повезивање је у току" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Ðе могу да добијем грешку на чекању: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Грешка у примању података: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Грешка у Ñлању података: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ðе могу да угаÑим утичницу: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Грешка у затварању утичнице: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Чекам уÑлов утичнице: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Ðе могу да пошаљем поруку: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Вектори поруке Ñу превелики" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Грешка при Ñлању поруке: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "Порука управљања Гутичницом није подржана на Виндоузу" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Грешка при примању поруке: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Ðе могу да прочитам уверења утичнице: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "г_утичница_добавља_уверења није примењена за овај оперативни ÑиÑтем" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ðе могу да Ñе повежем на Ñервер поÑредника „%s“: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ðе могу да Ñе повежем на „%s“: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Ðе могу да Ñе повежем: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "ПоÑредовање преко везе која није ТЦП није подржано." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Протокол поÑредника „%s“ није подржан." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Слушање је већ затворено" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Додата утичница је затворена" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "СОЦКСв4 не подржава ИПв6 адреÑу „%s“" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "КориÑничко име је предуго за СОЦКСв4 протокол" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Име домаћина „%s“ је предуго за СОЦКСв4 протокол" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Сервер није СОЦКСв4 Ñервер поÑредник." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Веза кроз СОЦКСв4 Ñервер је одбијена" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Сервер није СОЦКСв5 поÑреднички Ñервер." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "СОЦКСв5 поÑредник захтева потврђивање идентитета." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "Овај СОЦКСв5 захтева начин пријављивања који ГБибл не подржава." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "КориÑничко име или лозинка Ñу предуги за СОЦКСв5 протокол." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"СОЦКСв5 пријављивање није уÑпело јер Ñу кориÑничко име или лозинка погрешни." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Име домаћина „%s“ је предуго за СОЦКСв5 протокол" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Овај СОЦКСв5 Ñервер поÑредник кориÑти непознати тип адреÑе." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Унутрашња грешка СОЦКСв5 Ñервера поÑредника." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "СОЦКСв5 веза није дозвољена од Ñтране Ñкупа правила." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Домаћин недоÑтупан кроз СОЦКСв5 Ñервер." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Мрежа недоÑтупна кроз СОЦКСв5 Ñервер." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Веза одбијена кроз СОЦКСв5 поÑредника." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "СОЦКСв5 поÑредник не подржава наредбу „connect“." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "СОЦКСв5 поÑредник не подржава дати тип адреÑе." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Ðепозната грешка СОЦКСв5 поÑредника." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ÐиÑам уÑпео да направим Ñпојку за везу Ñа потпроцеÑом (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Спојке ниÑу подржане на овој платформи" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Ðе могу да радим Ñа издањем кодирања %d иконице ГТемирања" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "ÐиÑам пронашао иÑправне адреÑе" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Грешка у обрнутом разрешавању „%s“: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Грешка обраде ДÐС „%s“ запиÑа: лош ДÐС пакет" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Ðема ДÐС запиÑа затражене врÑте за „%s“" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Привремено не могу да разрешим „%s“" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Грешка у разрешивању „%s“" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Лош ДÐС пакет" + +#: gio/gthreadedresolver.c:886 +#, c-format +#| msgid "Failed to read from file “%sâ€: %s" +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "ÐиÑам уÑпео да обрадим ДÐС одговор за „%s“: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "ÐиÑам пронашао ПЕМ шифровани приватни кључ" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ðе могу да дешифрујем ПЕМ шифровани приватни кључ" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Ðе могу да рашчланим ПЕМ шифровани приватни кључ" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "ÐиÑам пронашао ПЕМ шифровано уверење" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ðе могу да рашчланим ПЕМ шифровано уверење" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Тренутни ТЛС позадинац не подржава ПКЦС #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Овај Ð“Ð¢Ð»Ñ Ð¿Ð¾Ð·Ð°Ð´Ð¸Ð½Ð°Ñ† не подржава Ñтварање ПКЦС #11 уверења" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ово је поÑледња прилика да иÑправно унеÑете лозинку пре него што ваш приÑтуп " +"буде закључан." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Ðеколико унешених лозинки је било неиÑправно, и зато ће ваш приÑтуп бити " +"закључан након будућих неуÑпеха." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Унешена лозинка је погрешна." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Слање опиÑника датотеке није подржано" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Очекујем једну контролну поруку, добио Ñам %d" +msgstr[1] "Очекујем једну контролну поруку, добио Ñам %d" +msgstr[2] "Очекујем једну контролну поруку, добио Ñам %d" +msgstr[3] "Очекујем једну контролну поруку, добио Ñам %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Ðеочекивана врÑта подређених података" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Очекујем један опиÑник датотеке, али добих %d\n" +msgstr[1] "Очекујем један опиÑник датотеке, али добих %d\n" +msgstr[2] "Очекујем један опиÑник датотеке, али добих %d\n" +msgstr[3] "Очекујем један опиÑник датотеке, али добих %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Примљен је неиÑправни fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Примање опиÑника датотеке није подржано" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Грешка у Ñлању акредитива: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"Грешка приликом провере да ли је „SO_PASSCRED“ омогућен за утичницу: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Грешка приликом омогућавања „SO_PASSCRED“: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Очекивано да Ñе прочита један бајт за добијање акредитива, али је прочитано " +"нула бајтова" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ðе очекивах контролну поруку, али добих %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Грешка приликом онемогућавања „SO_PASSCRED“: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Грешка приликом читања из опиÑивача датотеке: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Грешка приликом затварања опиÑника датотеке: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Корени ÑиÑтем датотека" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Грешка приликом пиÑања у опиÑивач датотеке: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "ÐпÑтрактна ЈУÐИКС утичница адреÑа домена није подржана на овом ÑиÑтему" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "диÑк не подржава избацивање" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "диÑк не подржава „избаци“ или „избаци_Ñа_радњом“" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Грешка приликом читања ручке: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Грешка приликом затварања ручке: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Грешка приликом упиÑа у ручку: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Ðема довољно меморије" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Унутрашња грешка: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Потребан је већи уноÑ" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Подаци ниÑу иÑправно запаковани" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ÐдреÑа на којој вршити оÑлушкивање" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Занемарено, због ÑаглаÑноÑти Ñа ГТеÑтДмагиÑтралом" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "ИÑпиÑује адреÑу" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "ИÑпиÑује адреÑу у режиму шкољке" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Покреће уÑлугу д-магиÑтрале" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Погрешни аргументи\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Ðеочекивано ÑвојÑтво „%s“ елемента „%s“" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "СвојÑтво „%s“ елемента „%s“ није пронађено" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Ðеочекивана ознака „%s“, очекивана је „%s“" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Ðеочекивана ознака „%s“ унутар „%s“" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "ÐеÑправно време и датум „%s“ у датотеци обележивача" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Ðе могу да нађем иÑправну датотеку Ñа обележивачима међу фаÑциклама Ñа " +"подацима" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Обележивач за путању „%s“ већ поÑтоји" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Ðије пронађен обележивач за путању „%s“" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "У обележивачу за путању „%s“ није одређена МИМЕ врÑта" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "У обележивачу за путању „%s“ није одређена приватна заÑтавица" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "У обележивачу за путању „%s“ ниÑу одређене групе" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Програм „%s“ није региÑтровао обележивач за „%s“" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "ÐиÑам уÑпеода проширим комадну линију „%s“ Ñа путањом „%s“" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Ðеприказив знак у уноÑу за претварање" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Ðепотпун низ знакова на крају улаза" + +# ово претпоÑтављам да Ñе одноÑи на делимичан УТФ8 Ð·Ð°Ð¿Ð¸Ñ +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Ðе може претворити резерву „%s“ у Ð·Ð°Ð¿Ð¸Ñ â€ž%s“" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Уграђени ништавни бајт у улазу који претварам" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Уграђени ништавни бајт у излазу који претварам" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "Путања „%s“ није апÑолутна путања помоћу „file“ шеме" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Путања локалне датотеке „%s“ не Ñме Ñадржати „#“" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Путања „%s“ је неиÑправна" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Име домаћина из путање „%s“ је неиÑправно" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Путања „%s“ Ñадржи неиÑправно назначене знаке" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Ðазив путање „%s“ није апÑолутна путања" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A, %d. %B %Y. %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%T" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Јануар" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Фебруар" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Март" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Ðприл" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Мај" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Јун" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Јул" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "ÐвгуÑÑ‚" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Септембар" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Октобар" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Ðовембар" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Децембар" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Јан" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Феб" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Мар" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Ðпр" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Мај" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Јун" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Јул" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ðвг" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Сеп" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Окт" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Ðов" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Дец" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Понедељак" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Уторак" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Среда" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Четвртак" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Петак" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Субота" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Ðедеља" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Пон" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Уто" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Сре" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Чет" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Пет" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Суб" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Ðед" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Јануар" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Фебруар" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Март" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "Ðприл" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Мај" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Јун" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Јул" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "ÐвгуÑÑ‚" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Септембар" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Октобар" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "Ðовембар" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Децембар" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Јан" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Феб" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Мар" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Ðпр" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Мај" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Јун" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Јул" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ðвг" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Сеп" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Окт" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Ðов" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Дец" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "ПрП" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "ПоП" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Грешка при отварању директоријума „%s“: %s" + +# bug: plural-forms +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ðе могу да доделим %lu бајт за читање датотеке „%s“" +msgstr[1] "Ðе могу да доделим %lu бајта за читање датотеке „%s“" +msgstr[2] "Ðе могу да доделим %lu бајтова за читање датотеке „%s“" +msgstr[3] "Ðе могу да доделим %lu бајт за читање датотеке „%s“" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Датотека „%s“ је превелика" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "ÐиÑам уÑпеода прочитам из датотеке „%s“: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "ÐиÑам уÑпео да отворим датотеку „%s“: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"ÐиÑам уÑпео да Ñазнам оÑобине датотеке „%s“: није уÑпела функција „fstat()“: " +"%s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "" +"ÐиÑам уÑпео да отворим датотеку „%s“: није уÑпела функција „fdopen()“: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"ÐиÑам уÑпео да преименујем датотеку „%s“ у „%s“: није уÑпела функција " +"„g_rename()“: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "" +"ÐиÑам уÑпео да запишем датотеку „%s“: није уÑпела функција „write()“: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "" +"ÐиÑам уÑпео да упишем у датотеку „%s“: није уÑпела функција „fsync()“: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "ÐиÑам уÑпео да направим датотеку „%s“: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"ПоÑтојећа датотека „%s“ Ñе не може уклонити: није уÑпела функција " +"„g_unlink()“: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "ÐеиÑправан шаблон „%s“, не Ñме Ñадржати „%s“" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Шаблон „%s“ не Ñадржи XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "ÐиÑам уÑпео да прочитам Ñимболичку везу „%s“: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Ðе могу да покренем претварање из „%s“ у „%s“: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Ðе могу да обавим Ñирово читање ниÑке_г_уи_канала_читања_реда" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "ПреоÑтали непретворени подаци у баферу за читање" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Канал Ñе завршава делимичним знаком" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Ðе могу да читам без обраде у г_уи_каналу_читај_до_краја" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Ðе могу да нађем иÑправну датотеку Ñа кључевима међу директоријумима претраге" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Ðије обична датотека" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Датотека Ñа кључевима Ñадржи ред „%s“ што не чини пар кључ-вредноÑÑ‚, групу " +"или примедбу" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "ÐеиÑправан назив групе: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Датотека Ñа кључевима не почиње групом" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "ÐеиÑправан назив кључа: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Датотека Ñа кључевима Ñадржи неподржано кодирање „%s“" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Датотека Ñа кључевима нема групу „%s“" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Датотека Ñа кључевима не Ñадржи кључ „%s“ у групи „%s“" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Датотека Ñа кључевима Ñадржи кључ „%s“ вредноÑти „%s“ што није УТФ-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "Датотека Ñа кључевима Ñадржи кључ „%s“ неразумљиве вредноÑти." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Датотека Ñа кључевима Ñадржи кључ „%s“ у групи „%s“ неразумљиве вредноÑти." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Кључ „%s“ у групи „%s“ има вредноÑÑ‚ „%s“ где је очекивано %s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Датотека Ñа кључевима Ñадржи знак иÑтицања на крају реда" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Датотека Ñа кључевима Ñадржи недозвољен низ иÑтицања „%s“" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "ВредноÑÑ‚ „%s“ Ñе не може Ñматрати бројем." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Целобројна вредноÑÑ‚ „%s“ је изван опÑега" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "ВредноÑÑ‚ „%s“ Ñе не може Ñматрати реалним бројем једноÑтруке тачноÑти." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "ВредноÑÑ‚ „%s“ Ñе не може Ñматрати иÑтинитоÑном." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"ÐиÑам уÑпео да Ñазнам оÑобине датотеке „%s%s%s%s“: није уÑпела функција " +"„fstat()“: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" +"ÐиÑам уÑпео да мапирам датотеку „%s%s%s%s“: није уÑпела функција „mmap()“: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "" +"ÐиÑам уÑпео да отворим датотеку „%s“: није уÑпела функција „open()“: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Грешка у %d. реду, %d. знак: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "ÐеиÑправан УТФ-8 текÑÑ‚ у имену — „%s“ није иÑправно" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "„%s“ није иÑправан назив" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "„%s“ није иÑправан назив: „%c“" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Грешка у %d. реду: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"ÐиÑам уÑпео да рашчланим „%-.*s“, што је требало да предÑтавља цифру унутар " +"знаковне референце (на пример ê) — можда је цифра превелика" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Знаковна референца Ñе не завршава тачка-запетом; највероватније Ñте " +"кориÑтили амперÑанд без намере да започнете ентитет — назначите амперÑанд Ñа " +"&" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Знаковна референца „%-.*s“ не предÑтавља дозвољени знак" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Уочен празан ентитет „&;“; прихватљиви ентитети Ñу & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Име ентитета „%-.*s“ није познато" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Ентитет Ñе не завршава тачка-запетом; највероватније Ñте кориÑтили амперÑанд " +"без намере да започнете ентитет — назначите амперÑанд Ñа &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Документ мора почети елементом (нпр. <књига>)" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"„%s“ не предÑтавља иÑправан знак након знака „<“; назив елемента не може " +"њиме почети" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Чудан знак „%s“, а очекиван је „>“ знак ради окончања ознаке празног " +"елемента „%s“" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Превише оÑобина у елементу „%s“" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Чудан знак „%s“, очекиван је „=“ поÑле имена атрибута „%s“ елемента „%s“" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Чудан знак „%s“, очекиван је или „>“ или „/“ ради окончања почетне ознаке " +"елемента „%s“, или можда атрибут; можда Ñте кориÑтили неиÑправан знак у " +"имену атрибута" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Чудан знак „%s“, очекиван је почетни наводник након знака једнакоÑти при " +"додели вредноÑти атрибута „%s“ елемента „%s“" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"„%s“ није иÑправан знак након имена затвореног елемента „%s“; дозвољени знак " +"је „>“" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Елемент „%s“ је затворен, нема тренутно отворених елемената" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Елемент „%s“ је затворен, а тренутно отворен елемент је „%s“" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Документ је празан или Ñадржи Ñамо белине" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Документ je завршен неочекивано непоÑредно након отворене коÑоугле заграде " +"„<“" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Документ je завршен неочекивано Ñа отвореним елементима — „%s“ је поÑледње " +"отворен елемент" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Документ је завршен неочекивано, а очекивана је затворена коÑоугла заграда " +"која затвара ознаку <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Документ je завршен неочекивано уÑред имена елемента" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Документ je завршен неочекивано уÑред имена атрибута" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Документ je завршен неочекивано уÑред почетне ознаке елемента." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Документ je завршен неочекивано након знака једнакоÑти поÑле имена атрибута; " +"вредноÑÑ‚ атрибута није наведена" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Документ je завршен неочекивано уÑред вредноÑти атрибута" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Документ je завршен неочекивано уÑред завршне ознаке елемента „%s“" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Документ je завршен неочекивано унутар завршне ознаке неотвореног елемента" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Документ je завршен неочекивано уÑред примедбе или упута за обраду" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[ОПЦИЈÐ…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Помоћне опције:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Приказује опције за помоћ" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Приказује Ñве опције за помоћ" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Опције програма:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Опције:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Ðе могу да рашчланим целобројну вредноÑÑ‚ „%s“ за %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Целобројна вредноÑÑ‚ „%s“ за %s је изван опÑега" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Ðе могу да рашчланим реалну вредноÑÑ‚ двоÑтруке тачноÑти „%s“ за %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Реална вредноÑÑ‚ двоÑтруке тачноÑти „%s“ за %s је изван опÑега" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Грешка при рашчлањивању могућноÑти %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "ÐедоÑтаје аргумент за %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Ðепозната опција %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "оштећен објекат" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "интерна грешка или оштећен објекат" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "нема више меморије" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "доÑтигнут је лимит претраживања уназад" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "образац Ñадржи Ñтавке које ниÑу подржане за делимично поклапање" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "унутрашња грешка" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"референце на претходно поклапање не могу бити уÑлов за делимично поклапање" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "доÑтигнут је лимит рекурзије" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "неиÑправна комбинација ознака за нову линију" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "лош померај" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "кратaк утф8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "дубинÑко вртење кроз директоријуме" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "непозната грешка" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ на крају обраÑца" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c на крају обраÑца" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "непознат знак Ñледи након \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "бројеви ниÑу по реду у {} бројачу" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "бројеви Ñу превелики у {} бројачу" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "недоÑтаје завршница ] за клаÑу знакова" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "неиÑправан избегавачки низ у клаÑи знакова" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "опÑег је неиÑправан унутар клаÑе знакова" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "нема ничега за понављање" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "неочекивано понављање" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "непознат знак након (? или (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "клаÑе именоване ПОСИКС-ом Ñу подржане Ñамо унутар клаÑе" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "недоÑтаје завршница )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "референца на непоÑтојећи подобразац" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "недоÑтаје ) након коментара" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "регуларни израз је предуг" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "не могу да добијем меморију" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") без отварања (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "прекорачење кода" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "непознат знак након (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "подаци иза тврдње ниÑу задате дужине" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "неиÑправно задат број или назив након (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "уÑловна група Ñадржи више од две гране" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "очекивана је тврдња након (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "након(?R или (?[+-]бројева мора да Ñледи )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "непознат назив ПОСИКС клаÑе" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "ниÑу подржани ПОСИКС колациони елементи" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "превелика је вредноÑÑ‚ карактера у \\x{…} Ñеквенци" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "неиÑправан је уÑлов (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "није дозвољено \\C у подацима иза тврдње" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "знаци за промену реда „\\L, \\l, \\N{назив}, \\U, \\u“ ниÑу подржани" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "дубинÑки захтев Ñе може понављати беÑконачно" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "непознат знак након (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "недоÑтаје завршница у називу подобраÑца" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "двоимени подобраÑци имају иÑто име" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "није иÑправно задата \\P или \\p Ñеквенца" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "није познат назив оÑобине након \\P или \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "назив подобраÑца је предуг (највише 32 знака)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "има превише именованих подобразаца (Ñме их бити највише 10000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "оÑмобројна вредноÑÑ‚ је већа од \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "превише покренутих радних проÑтора за превођење изворног кода" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "није нађен претходно проверени и повезани подобразац" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE група Ñадржи више од једне гране" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "неуједначене NEWLINE опције" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"иза „\\g“ Ñе не налази назив или број у загради, углаÑтој загради, или под " +"наводницима, или обичан број" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "нумериÑана референца не Ñме бити нула" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "аргумент није дозвољен за (*ACCEPT), (*FAIL), или (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) није препознато" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "број је превелик" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "недоÑтаје назив подобраÑца након (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "очекивана је цифра након (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] је неиÑправан знак података у режиму ÑаглаÑноÑти Ñкрипте Јаве" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "различити називи за подобраÑце иÑтог броја ниÑу дозвољени" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) мора да Ñадржи аргумент" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "иза „\\c“ мора да Ñледи ÐСКРИ знак" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"иза „\\k“ Ñе не налази назив у загради, углаÑтој загради, или под наводницима" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "„\\N“ није подржано у разреду" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "превише референци проÑлеђивања" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "назив је предуг у (*MARK), (*PRUNE), (*SKIP), или (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "вредноÑÑ‚ знака у низу „\\u….“ је превелика" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Грешка приликом претраживања регуларним изразом %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "ПЦРЕ библиотека је преведена без подршке за УТФ8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "ПЦРЕ библиотека је преведена без подршке за УТФ8 оÑобине" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "ПЦРЕ библиотека је преведена Ñа неÑаглаÑним опцијама" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Грешка при оптимизовању регуларног израза %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Грешка при превођењу регуларног израза %s код знака %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "очекивана је хекÑадекадна цифра или „}“" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "очекивана је хекÑадекадна цифра" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "недоÑтаје „<“ у референци Ñимбола" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "Ðедовршена референца Ñимбола" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "референца Ñимбола је дужине нула" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "очекивана је цифра" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "неиÑправна референца Ñимбола" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "одлутало завршно „\\“" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "непозната Ñеквенца избегавања" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Грешка приликом обраде текÑта за замену „%s“ код карактера %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Ðавод не почиње наводником" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Ðеупарен наводник у наредби или другом цитату из љуÑке" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Садржај завршен непоÑредно након „\\“ знака. (Ради Ñе о текÑту „%s“)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Садржај завршен пре наилаÑка на одговарајући наводник за %c. (Ради Ñе о " +"текÑту „%s“)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Садржај празан (или Ñадржи Ñамо белине)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ÐеуÑпело читање података од потпроцеÑа (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Ðеочекивана грешка приликом читања података из дете процеÑа (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ðеочекивана грешка у функцији „waitpid()“ (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ˜Ðµ изашао Ñа шифром %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ˜Ðµ убијен Ñигналом %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ˜Ðµ зауÑтављен Ñигналом %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñ˜Ðµ неочекивано прекинут" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ÐиÑам уÑпео да читам из Ñпојке порода (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "ÐиÑам уÑпео да извршим Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ†ÐµÑ â€ž%s“ (%s)" + +# за Ñада овако, можда гранање, умножавање? виљушкање ;-) +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "ÐиÑам уÑпео да иÑцепим (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "ÐиÑам уÑпео да пређем у директоријум „%s“ (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "ÐиÑам уÑпео да извршим Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ†ÐµÑ â€ž%s“ (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "" +"ÐиÑам уÑпео да отворим датотеку да поново мапирам опиÑника датотеке (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "ÐиÑам уÑпео да удвоÑтручим опиÑника датотеке за изрођени Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ÐиÑам уÑпео да иÑцепим Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "ÐиÑам уÑпео да затворим опиÑника датотеке за изрођени Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Ðепозната грешка при извршавању потпроцеÑа „%s“" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Ðије уÑпео да прочита довољно података из цевке ка потпроцеÑу (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "ÐиÑам уÑпео да читам податке из потпроцеÑа" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ÐиÑам уÑпео да извршим Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ†ÐµÑ (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "ÐиÑам уÑпео да „dup()“ у изрођеном процеÑу (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ðије иÑправан назив програма: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ðије иÑправна ниÑка — члан вектора у %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ðије иÑправна ниÑка у окружењу: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ðије иÑправна радна фаÑцикла: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ÐиÑам уÑпео да извршим помоћнички програм (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ðеочекивана грешка док Ñу у „g_io_channel_win32_poll()“ читани подаци из " +"потпроцеÑа" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Празна ниÑка није број" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s“ није потпиÑан број" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Број „%s“ је ван граница [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s“ није непотпиÑан број" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "ÐеиÑправно %-кодирање у путањи" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Забрањени знак у путањи" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Ðе-УТФ-8 знакови у путањи" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "ÐеиÑправна ИПв6 адреÑа „%.*s“ у путањи" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "ÐеиÑправна енкодирана ИП адреÑа „%.*s“ у путањи" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "ÐеиÑправан интернационализован назив домаћина „%.*s“ у путањи" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Ðе могу да обрадим порт „%.*s“ у путањи" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Порт „%.*s“ у путањи је ван опÑега" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "Путања „%s“ није апÑолутна путања" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "Путања „%s“ нема део за домаћина" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "Путања није апÑолутна, а оÑновна путања није доÑтављена" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "ÐедоÑтаје „=“ и вредноÑÑ‚ параметра" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "ÐиÑам уÑпео да доделим меморију" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Знак ван опÑега за УТФ-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Ðије иÑправан низ у уноÑу за претварање" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Знак ван опÑега за УТФ-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u бајт" +msgstr[1] "%u бајта" +msgstr[2] "%u бајта" +msgstr[3] "Један бајт" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u бит" +msgstr[1] "%u бита" +msgstr[2] "%u битова" +msgstr[3] "Један бит" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s бајт" +msgstr[1] "%s бајта" +msgstr[2] "%s бајтова" +msgstr[3] "Један бајт" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s бит" +msgstr[1] "%s бита" +msgstr[2] "%s битова" +msgstr[3] "Један бит" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "Ðе могу да учитам „/var/lib/dbus/machine-id“ или „/etc/machine-id“: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Ðепозната грешка везе" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Грешка унутар адреÑе „%s“ — атрибут фамилије је неиÑправно упиÑан" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "Монтирах „%s“ на „%s“\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; занемарујем замену за овај кључ.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " и „--strict“ је наведено; излазим.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Занемарујем замену за овај кључ.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "не радим ништа.\n" + +#~ msgid "No such method '%s'" +#~ msgstr "Ðема метода „%s“" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Ðе могу да одредим адреÑу магиÑтрале ÑеÑије из променљиве окружења " +#~ "DBUS_STARTER_BUS_TYPE — непозната вредноÑÑ‚ „%s“" + +#~ msgid "[ARGS...]" +#~ msgstr "[ÐРГУМЕÐТИ…]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "ÐиÑам уÑпео да направим привремену датотеку: %s" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Порука има %d опиÑивача датотеке, али заглавље указује на %d опиÑивача " +#~ "датотеке" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Грешка: није изабрана путања објекта.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Грешка: Ñигнал није наведен.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Грешка: Ñигнал мора бити потпуно одговарајући назив.\n" + +#~ msgid "No such interface" +#~ msgstr "Ðема таквог интерфејÑа" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Грешка добављања запиÑивих оÑобина: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Грешка качења меÑта: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Грешка откачињања качења: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Грешка у налажењу угнежденог качења: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Грешка избацивања качења: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Грешка качења „%s“: %s\n" + +#~ msgid "No files to open" +#~ msgstr "Ðема датотека за отварање" + +#~ msgid "No files to delete" +#~ msgstr "Ðема датотека за бриÑање" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Грешка поÑтављања атрибута: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Грешка приликом образовања директоријума „%s“: %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Грешка приликом отварања датотеке „%s“: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Грешка при читању датотеке „%s“: %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Грешка у преименовању датотеке: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Грешка приликом отварања датотеке: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Грешка приликом образовања директоријума: %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "" +#~ "Ðе могу да нађем подразумевану врÑту монитора за локални директоријум" + +#~ msgid "association changes not supported on win32" +#~ msgstr "ниÑу подржане промене придруживања за win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "ÐиÑу подржане промене придруживања за win32" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Датотека Ñа кључевима нема кључ „%s“" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "Грешка обраде улазне датотеке Ñа „xmllint“-ом:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "Грешка обраде улазне датотеке Ñа „to-pixdata“-ом:\n" +#~ "%s" diff --git a/po/sr@ije.po b/po/sr@ije.po new file mode 100644 index 0000000..2951e55 --- /dev/null +++ b/po/sr@ije.po @@ -0,0 +1,3830 @@ +# Serbian translation of glib +# Courtesy of Prevod.org team (http://prevod.org/) -- 2003, 2004. +# +# This file is distributed under the same license as the glib package. +# +# Maintainer: Данило Шеган +# Reviewed on 2004-02-01 by: Данило Шеган +# +msgid "" +msgstr "" +"Project-Id-Version: 2.4\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2004-04-29 01:11+0200\n" +"Last-Translator: Bojan Suzic \n" +"Language-Team: Serbian (sr) \n" +"Language: sr@ije\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, fuzzy, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Чудан знак „%s“, очекивао Ñам „=“ поÑле оÑобине „%s“ елемента „%s“" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Ðе могу да прочитам Ñимболичку везу „%s“: %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Претварање из Ñкупа знакова „%s“ у „%s“ није подржано" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Ðе могу да покренем претварање из „%s“ у „%s“" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "ÐеиÑправан низ бајтова у улазу који претварам" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Грешка при претварању: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Ðепотпун низ знакова на крају улаза" + +# ово претпоÑтављам да Ñе одноÑи на делимичан УТФ8 Ð·Ð°Ð¿Ð¸Ñ +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Ðе може претворити резерву „%s“ у Ð·Ð°Ð¿Ð¸Ñ â€ž%s“" + +# bug: "file" should be in quotes, if it's about "file:///" +#: ../glib/gconvert.c:1886 +#, fuzzy, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "ÐдреÑа „%s“ није апÑолутна адреÑа помоћу „file“ шеме" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "ÐдреÑа локалне датотеке „%s“ не Ñмије Ñадржати „#“" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "ÐдреÑа „%s“ је неиÑправна" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Име домаћина из адреÑе „%s“ је неиÑправно" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "ÐдреÑа „%s“ Ñадржи неиÑправно назначене знаке" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Путања „%s“ није апÑолутна путања" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "ÐеиÑправно име домаћина" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A, %d. %B %Y. %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y." + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%T" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "јануар" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "фебруар" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "март" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "април" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "мај" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "јун" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "јул" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "јан" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "феб" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "мар" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "апр" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "мај" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "јун" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "јул" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "понедељак" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "уторак" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Ñреда" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "четвртак" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "петак" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Ñубота" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "недеља" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "пон" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "уто" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ñре" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "чет" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "пет" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Ñуб" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "нед" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Грешка при отварању директоријума „%s“: %s" + +# bug: plural-forms +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Ðе могу да обезбједим %lu бајтова за читање датотеке „%s“" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Ðе могу да прочитам из датотеке „%s“: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Ðе могу да отворим датотеку „%s“: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Ðе могу да Ñазнам оÑобине датотеке „%s“: неуÑпјешан fstat(): %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gfileutils.c:862 +#, fuzzy, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Ðе могу да направим датотеку „%s“: %s" + +#: ../glib/gfileutils.c:918 +#, fuzzy, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gfileutils.c:943 +#, fuzzy, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gfileutils.c:1030 +#, fuzzy, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "ÐеиÑправан шаблон „%s“, не Ñмије Ñадржати „%s“" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Шаблон „%s“ Ñе не завршава Ñа XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Ðе могу да прочитам Ñимболичку везу „%s“: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: ../glib/giochannel.c:1408 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Ðе могу да покренем претварање из „%s“ у „%s“: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Ðе могу да читам без обраде у g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "ПреоÑтали непретворени подаци у међуÑпремнику за читање" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Канал Ñе завршава дјелимичним знаком" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Ðе могу да читам без обраде у g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, fuzzy, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gmappedfile.c:229 +#, fuzzy, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "Грешка у %d. реду, %d. знак: %s" + +# ознака знака??? неееее +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "ÐеиÑправан текÑÑ‚ у УТФ-8 запиÑу" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Грешка у %d. реду: %s" + +#: ../glib/gmarkup.c:638 +#, fuzzy, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"ÐиÑам уÑпио да рашчланим „%s“, што је требало да предÑтавља цифру унутар " +"позива знака (на пример ê) — можда је цифра превелика" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Позив знака Ñе не завршава тачка-запетом; највјероватније Ñте кориÑтили " +"амперÑанд без намере да започнете ентитет — назначите амперÑанд као &" + +#: ../glib/gmarkup.c:676 +#, fuzzy, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Позив знака „%s“ не Ñтоји за дозвољени знак" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Уочен празан ентитет „&;“; прихватљиви ентитети Ñу & " < > " +"'" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Ентитет „%s“ није познат" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Ентитет Ñе не завршава тачка-запетом; највјероватније Ñте кориÑтили " +"амперÑанд без намере да започнете ентитет — назначите амперÑанд као &" + +# може и ћирилица: „Уникод ТранÑФормација 8“ +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Документ мора почети елементом (нпр. <књига>)" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"„%s“ не предÑтавља иÑправан знак након знака „<“; име елемента не може њиме " +"почети" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Чудан знак „%s“, а очекивао Ñам „>“ знак ради окончања почетне ознаке " +"елемента „%s“" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "Чудан знак „%s“, очекивао Ñам „=“ поÑле оÑобине „%s“ елемента „%s“" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Чудан знак „%s“, очекивао Ñам или „>“ или „/“ ради окончања почетне ознаке " +"елемента „%s“, или могућу оÑобину; можда Ñте кориÑтили неиÑправан знак у " +"имену оÑобине" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Чудан знак „%s“, очекивао Ñам почетни наводник након знака једнакоÑти при " +"додјели вриједноÑти оÑобини „%s“ елемента „%s“" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"„%s“ није иÑправан знак након имена затвореног елемента „%s“; дозвољени знак " +"је „>“" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Елемент „%s“ је затворен, нема тренутно отворених елемената" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Елемент „%s“ је затворен, а тренутно отворен елемент је „%s“" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Документ је празан или Ñадржи Ñамо бјелине" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Документ завршен неочекивано непоÑредно након отворене коÑоугле заграде „<“" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Документ завршен неочекивано Ñа отвореним елементима — „%s“ је поÑледње " +"отворен елемент" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Документ завршен неочекивано, очекивао Ñам да наиђем на затворену коÑоуглу " +"заграду која затвара ознаку <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Документ завршен неочекивано уÑред имена елемента" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Документ завршен неочекивано уÑред имена оÑобине" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Документ завршен неочекивано уÑред почетне ознаке елемента." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Документ завршен неочекивано након знака једнакоÑти поÑле имена оÑобине; " +"вриједноÑÑ‚ оÑобине није наведена" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Документ завршен неочекивано уÑред вриједноÑти оÑобине" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Документ завршен неочекивано уÑред завршне ознаке елемента „%s“" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Документ завршен неочекивано уÑред примедбе или упута за обраду" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "Канал Ñе завршава дјелимичним знаком" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "ÐеиÑправан низ бајтова у улазу који претварам" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +# позив умеÑто ознака? +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "Ðедовршен позив знака" + +# позив умеÑто ознака? +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "Ðедовршен позив знака" + +# позив умеÑто ознака? +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "Ðедовршен позив знака" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Грешка у %d. реду, %d. знак: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "Ðедовршена ознака ентитета" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Ðавод не почиње наводником" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Ðеупарен наводник у наредби или другом цитату из љуÑке" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Садржај завршен непоÑредно након „\\“ знака. (Ради Ñе о текÑту „%s“)" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"Садржај завршен прије наилаÑка на одговарајући наводник за %c. (Ради Ñе о " +"текÑту „%s“)" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Садржај празан (или Ñадржи Ñамо бјелине)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "ÐеуÑпјело читање података из подређеног процеÑа" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "ÐеуÑпјело Ñтварање цјевке за везу Ñа подређеним процеÑом (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "ÐеуÑпјело читање из подређене цјевке (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "ÐеуÑпјело приÑтупање директоријуму „%s“ (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ÐеуÑпјело извршавање подређеног процеÑа (%s)" + +#: ../glib/gspawn-win32.c:444 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "ÐеиÑправно име домаћина" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, fuzzy, c-format +msgid "Invalid string in environment: %s" +msgstr "ÐеиÑправан низ у уноÑу за претварање" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, fuzzy, c-format +msgid "Invalid working directory: %s" +msgstr "Грешка при отварању директоријума „%s“: %s" + +#: ../glib/gspawn-win32.c:783 +#, fuzzy, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ÐеуÑпјело извршавање помоћног програма" + +# Овај превод није пÑихолошке природе :) +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ðеочекивана грешка док Ñу у g_io_channel_win32_poll() читани подаци од " +"подређеног процеÑа" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "ÐеуÑпјело читање података од подређеног процеÑа (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Ðеочекивана грешка у select() при читању података од подређеног процеÑа (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ðеочекивана грешка у waitpid() (%s)" + +# за Ñада овако, можда гранање, умножавање? виљушкање ;-) +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "ÐеуÑпио fork() (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "ÐеуÑпјело извршавање подређеног процеÑа „%s“ (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "ÐеуÑпјело преуÑмјеравање улаза или излаза подређеног процеÑа (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "ÐеуÑпио fork() подређеног процеÑа (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Ðепозната грешка при извршавању подређеног процеÑа „%s“" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Ðије уÑпио да прочита довољно података из цјевке ка подређеном процеÑу (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Знак ван опÑега за УТФ-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "ÐеиÑправан низ у уноÑу за претварање" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Знак ван опÑега за УТФ-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "Грешка при претварању: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "ÐеиÑправно име домаћина" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "ÐеиÑправно име домаћина" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, fuzzy, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "ÐдреÑа „%s“ Ñадржи неиÑправно назначене знаке" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "ÐеиÑправан низ бајтова у улазу који претварам" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Грешка при отварању директоријума „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Грешка при отварању директоријума „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Грешка у %d. реду: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Грешка при претварању: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Знак „%s“ није дозвољен у имену ентитета" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Знак „%s“ није дозвољен у имену ентитета" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Знак „%s“ није дозвољен у имену ентитета" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Грешка при претварању: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Грешка при претварању: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Грешка при отварању директоријума „%s“: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "Симболичке везе ниÑу подржане" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Симболичке везе ниÑу подржане" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "ÐеиÑправно име домаћина" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "ÐеиÑправно име домаћина" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Ðе могу да направим датотеку „%s“: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Ðе могу да направим датотеку „%s“: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "Ðе могу да направим датотеку „%s“: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Грешка при отварању директоријума „%s“: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Ðе могу да прочитам Ñимболичку везу „%s“: %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "Документ завршен неочекивано уÑред имена оÑобине" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Грешка при отварању директоријума „%s“: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Грешка при претварању: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "Грешка у %d. реду: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "ÐеиÑправно име домаћина" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Ðе могу да направим датотеку „%s“: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +# bug: plural-forms +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "Ðе могу да обезбједим %lu бајтова за читање датотеке „%s“" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Ðе могу да направим датотеку „%s“: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ðе могу да направим датотеку „%s“: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Симболичке везе ниÑу подржане" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "Грешка у %d. реду: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Грешка при претварању: %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "Симболичке везе ниÑу подржане" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Грешка при читању датотеке „%s“: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "ÐеиÑправно име домаћина" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "ÐеиÑправан низ у уноÑу за претварање" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Име ентитета не може почети знаком „%s“ ; знак & започиње ентитет; ако " +#~ "овај знак не означава ентитет, иÑтакните га помоћу &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Празан позив знака; морао би Ñадржати цифру као на примјер ˫" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Ðедовршена ознака ентитета" + +# позив умеÑто ознака? +#~ msgid "Unfinished character reference" +#~ msgstr "Ðедовршен позив знака" + +# ознака знака??? неееее +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "ÐеиÑправан текÑÑ‚ у УТФ-8 запиÑу" + +# ознака знака??? неееее +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "ÐеиÑправан текÑÑ‚ у УТФ-8 запиÑу" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Име домаћина из адреÑе „%s“ је неиÑправно" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Име домаћина из адреÑе „%s“ је неиÑправно" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Грешка при читању датотеке „%s“: %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Грешка при претварању: %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Ðе могу да отворим датотеку „%s“: неуÑпјешан fdopen(): %s" diff --git a/po/sr@latin.po b/po/sr@latin.po new file mode 100644 index 0000000..fbeee74 --- /dev/null +++ b/po/sr@latin.po @@ -0,0 +1,6010 @@ +# Serbian translation of glib +# Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2017. +# This file is distributed under the same license as the glib package. +# Translators: +# Danilo Å egan , 2004—2005. +# Slobodan D. Sredojević , 2006. +# Branko Kokanović , 2010. +# MiloÅ¡ Popović , 2010—2015. +# Miroslav Nikolić , 2011—2017. +# Marko M. Kostić , 2016. +msgid "" +msgstr "" +"Project-Id-Version: 2.8\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2018-02-21 14:56+0000\n" +"PO-Revision-Date: 2018-02-21 21:40+0100\n" +"Last-Translator: Marko M. Kostić \n" +"Language-Team: srpski \n" +"Language: sr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Project-Style: gnome\n" +"X-Generator: Poedit 2.0.6\n" + +#: ../gio/gapplication.c:495 +msgid "GApplication options" +msgstr "Opcije Gprograma" + +#: ../gio/gapplication.c:495 +msgid "Show GApplication options" +msgstr "Pokazuje opcije Gprograma" + +#: ../gio/gapplication.c:540 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Ulazi u režim usluge Gprograma (koristi sa datoteka usluge D-sabirnice)" + +#: ../gio/gapplication.c:552 +msgid "Override the application’s ID" +msgstr "NadglaÅ¡ava IB programa" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gio-tool.c:227 ../gio/gresource-tool.c:488 +#: ../gio/gsettings-tool.c:569 +msgid "Print help" +msgstr "Å tampa pomoć" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:489 +#: ../gio/gresource-tool.c:557 +msgid "[COMMAND]" +msgstr "[NAREDBA]" + +#: ../gio/gapplication-tool.c:49 ../gio/gio-tool.c:228 +msgid "Print version" +msgstr "Ispisuje izdanje" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:575 +msgid "Print version information and exit" +msgstr "Ispisuje podatke o izdanju i izlazi" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Ispisuje programe" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Ispisuje instalirane programe koji se mogu pokrenuti D-sabirnicom (prema " +"datotekama radne povrÅ¡i)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "Pokreće program" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "Pokreće program (sa izbornim datotekama za otvaranje)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "IBPROGRAMA [DATOTEKA…]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "Pokreće radnju" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "Priziva radnju nad programom" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "IBPROGRAMA RADNJA [PARAMETAR]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Ispisuje dostupne radnje" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "Ispisuje statiÄke radnje za program (iz datoteke radne povrÅ¡i)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "IBPROGRAMA" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 ../gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "NAREDBA" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "Naredba za koju će ispisati opÅ¡irniju pomoć" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Odrednik programa u zapisu D-sabirnice (npr: „org.example.viewer“)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:665 +#: ../gio/glib-compile-resources.c:671 ../gio/glib-compile-resources.c:698 +#: ../gio/gresource-tool.c:495 ../gio/gresource-tool.c:561 +msgid "FILE" +msgstr "DATOTEKA" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Neobavezna relativni ili apsolutni nazivi datoteka ili putanje koje želite da " +"otvorite" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "RADNJA" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "Naziv radnje za prizivanje" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "PARAMETAR" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Izborni parametar za prizivanje radnje, u zapisu Gvarijanta" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:526 +#: ../gio/gsettings-tool.c:661 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Nepoznata naredba „%s“\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "Upotreba:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:551 +#: ../gio/gsettings-tool.c:696 +msgid "Arguments:\n" +msgstr "Argumenti:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS…]" +msgstr "[ARGUMENTI…]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Naredbe:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Koristite „%s help NAREDBA“ za podrobniju pomoć.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"Nredba „%s“ zahteva ib programa za neposredno praćenje\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "neispravan ib programa: „%s“\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"„%s“ ne prihvata argumente\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "ne mogu da se povežem na D-sabirnicu: „%s“\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "greÅ¡ka slanja %s poruke programu: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "naziv radnje mora biti dat nakon ib-a programa\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"neispravan naziv radnje: „%s“\n" +"nazivi radnji moraju da sadrže samo slova i brojeve, „-“ i „.“\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "greÅ¡ka obrade parametra radnje: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "radnje prihvataju najviÅ¡e jedan parametar\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "naredba „list-actions“ prihvata samo ib programa" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "ne mogu da naÄ‘em datoteku radne povrÅ¡i za program „%s“\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"nepoznata naredba: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:179 ../gio/ginputstream.c:379 +#: ../gio/ginputstream.c:617 ../gio/ginputstream.c:1019 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:834 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:209 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Prevelika brojÄana vrednost je prosleÄ‘ena u %s" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Nije podržavano premotavanje osnovnog toka" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Ne mogu da skratim ulazni tok u GmeÄ‘umemoriji" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1208 +#: ../gio/giostream.c:300 ../gio/goutputstream.c:1661 +msgid "Stream is already closed" +msgstr "Tok je već zatvoren" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Nije podržano sasecanje osnovnog toka" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1849 +#: ../gio/gdbusprivate.c:1402 ../gio/gsimpleasyncresult.c:871 +#: ../gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Radnja je otkazana" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Neispravan objekat, nije pokrenuto" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Nepotpun niz bajtova na ulazu" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Nema dovoljno mesta u odrediÅ¡tu" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1261 ../glib/gconvert.c:454 ../glib/gconvert.c:883 +#: ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:869 ../glib/gutf8.c:1322 +msgid "Invalid byte sequence in conversion input" +msgstr "Neispravan niz bajtova u ulazu koji pretvaram" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:462 ../glib/gconvert.c:797 +#: ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "GreÅ¡ka prilikom pretvaranja: %s" + +#: ../gio/gcharsetconverter.c:445 ../gio/gsocket.c:1104 +msgid "Cancellable initialization not supported" +msgstr "Nije podržano pokretanje uz mogućnost otkazivanja" + +#: ../gio/gcharsetconverter.c:456 ../glib/gconvert.c:327 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Pretvaranje iz skupa znakova „%s“ u „%s“ nije podržano" + +#: ../gio/gcharsetconverter.c:460 ../glib/gconvert.c:331 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Ne mogu da pokrenem pretvaranje iz „%s“ u „%s“" + +#: ../gio/gcontenttype.c:358 +#, c-format +msgid "%s type" +msgstr "%s vrsta" + +#: ../gio/gcontenttype-win32.c:177 +msgid "Unknown type" +msgstr "Nepoznata vrsta" + +#: ../gio/gcontenttype-win32.c:179 +#, c-format +msgid "%s filetype" +msgstr "%s vrsta datoteke" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "Guverenja nisu podržana na operativnom sistemu" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "Nemate podrÅ¡ku za Guverenja na ovoj platformi" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "Guverenja ne sadrže IB procesa na ovom operativnom sistemu" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Zavaravanje uverenja nije moguće na ovom operativnom sistemu" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "NeoÄekivan, preran kraj toka" + +#: ../gio/gdbusaddress.c:158 ../gio/gdbusaddress.c:246 +#: ../gio/gdbusaddress.c:327 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "KljuÄ â€ž%s“ nije podržan unutar adrese „%s“" + +#: ../gio/gdbusaddress.c:185 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"Adresa „%s“ je neispravna (potrebna samo jedna putanja, privremeni " +"direktorijum ili apstraktni kljuÄ)" + +#: ../gio/gdbusaddress.c:198 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "BeznaÄajna kombinacija kljuÄ/vrednost unutar adrese „%s“" + +#: ../gio/gdbusaddress.c:261 ../gio/gdbusaddress.c:342 +#, c-format +msgid "Error in address “%s†— the port attribute is malformed" +msgstr "GreÅ¡ka unutar adrese „%s“ — port nije ispravno upisan" + +#: ../gio/gdbusaddress.c:272 ../gio/gdbusaddress.c:353 +#, c-format +msgid "Error in address “%s†— the family attribute is malformed" +msgstr "GreÅ¡ka unutar adrese „%s“ — atribut familije je neispravno upisan" + +#: ../gio/gdbusaddress.c:463 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Element adrese „%s“ ne sadrži dve taÄke (:)" + +#: ../gio/gdbusaddress.c:484 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Par kljuÄ/vrednost %d, „%s“, u elementu adrese „%s“ ne sadrži znak jednakosti" + +#: ../gio/gdbusaddress.c:498 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"GreÅ¡ka pri neizbegavanju kljuÄa ili vrednosti u paru KljuÄ/Vrednosti %d, „%s“, " +"u elementu adrese „%s“" + +#: ../gio/gdbusaddress.c:576 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"GreÅ¡ka u adresi „%s“ — Juniksov prenos zahteva postavljanje kljuÄa " +"„path“ (putanja) ili „abstract“ (rezime)" + +#: ../gio/gdbusaddress.c:612 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"GreÅ¡ka unutar adrese „%s“ — atribut domaćina nedostaje ili je neispravan" + +#: ../gio/gdbusaddress.c:626 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "GreÅ¡ka unutar adrese „%s“ — port nedostaje ili je neispravan" + +#: ../gio/gdbusaddress.c:640 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"GreÅ¡ka unutar adrese „%s“ — atribut datoteke jednokratnih sluÄajnih brojeva " +"nedostaje ili je neispravan" + +#: ../gio/gdbusaddress.c:661 +msgid "Error auto-launching: " +msgstr "GreÅ¡ka u samopokretanju: " + +#: ../gio/gdbusaddress.c:669 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Nepoznati ili nepodržani prenos „%s“ za adrese „%s“" + +#: ../gio/gdbusaddress.c:714 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "" +"GreÅ¡ka prilikom otvaranja datoteke jednokratnih sluÄajnih brojeva „%s“: %s" + +#: ../gio/gdbusaddress.c:733 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "GreÅ¡ka pri Äitanju datoteke jednokratnih sluÄajnih brojeva „%s“: %s" + +#: ../gio/gdbusaddress.c:742 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"GreÅ¡ka pri Äitanju datoteke jednokratnih sluÄajnih brojeva „%s“, oÄekivano 16 " +"bajtova, a dobijeno %d" + +#: ../gio/gdbusaddress.c:760 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "" +"GreÅ¡ka prilikom upisa sadržaja datoteke jednokratnih sluÄajnih brojeva „%s“ " +"u tok:" + +#: ../gio/gdbusaddress.c:969 +msgid "The given address is empty" +msgstr "Data adresa je prazna" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Ne mogu da pokrenem magistralu poruka kada podeÅ¡avam jib" + +#: ../gio/gdbusaddress.c:1089 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ne mogu da pokrenem magistralu poruka bez identifikacije maÅ¡ine: " + +#: ../gio/gdbusaddress.c:1096 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Ne mogu da samopokrenem D-sabirnicu bez „X11 $DISPLAY“" + +#: ../gio/gdbusaddress.c:1138 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "GreÅ¡ka pri pokretanju naredbe „%s“: " + +#: ../gio/gdbusaddress.c:1355 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(UpiÅ¡ite bilo koji znak da zatvorite ovaj prozor)\n" + +#: ../gio/gdbusaddress.c:1509 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "D-magistrala sesije nije pokrenuta, samopokretanje nije uspelo" + +#: ../gio/gdbusaddress.c:1520 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Ne mogu da odredim adresu magistrale sesije (nije napravljeno za ovaj " +"operativni sistem)" + +#: ../gio/gdbusaddress.c:1658 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Ne mogu da odredim adresu magistrale sesije iz promenljive okruženja " +"DBUS_STARTER_BUS_TYPE — nepoznata vrednost „%s“" + +#: ../gio/gdbusaddress.c:1667 ../gio/gdbusconnection.c:7160 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ne mogu da odredim adresu magistrale sesije jer nije postavljena promenljiva " +"okruženja DBUS_STARTER_BUS_TYPE" + +#: ../gio/gdbusaddress.c:1677 +#, c-format +msgid "Unknown bus type %d" +msgstr "Nepoznat tip magistrale %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "NeoÄekivani nedostatak sadržaja pri Äitanju linije" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "NeoÄekivani nedostatak sadržaja pri (sigurnom) Äitanju linije" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"IstroÅ¡eni su svi dostupni mehanizmi prijavljivanja (pokuÅ¡ano: %s) (dostupno: " +"%s)" + +#: ../gio/gdbusauth.c:1171 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "PoniÅ¡teno preko GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:262 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "GreÅ¡ka prilikom dobavljanja podataka za direktorijum „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:274 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Ovlašćenja fascikle „%s“ su neispravna. OÄekivana vrednost je bila 0700, a " +"dobijeno je 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:296 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "GreÅ¡ka stvaranja direktorijuma „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:379 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "GreÅ¡ka prilikom otvaranja priveska kljuÄeva „%s“ za Äitanje: " + +#: ../gio/gdbusauthmechanismsha1.c:402 ../gio/gdbusauthmechanismsha1.c:720 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Linija %d priveska kljuÄeva na „%s“ sa sadržajem „%s“ nije ispravna" + +#: ../gio/gdbusauthmechanismsha1.c:416 ../gio/gdbusauthmechanismsha1.c:734 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Prvi token linije %d priveska kljuÄeva na „%s“ sa sadržajem „%s“ nije ispravan" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:748 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Drugi token linije %d priveska kljuÄeva na „%s“ sa sadržajem „%s“ nije " +"ispravan" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Nisam naÅ¡ao kolaÄić sa identifikacijom %d u privesku kljuÄeva na „%s“" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "GreÅ¡ka pri brisanju zaostale datoteke zakljuÄavanja „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "GreÅ¡ka pri pravljenju datoteke zakljuÄavanja „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:599 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "GreÅ¡ka prilikom zatvaranja (nepovezane) datoteke zakljuÄavanja „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:610 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "GreÅ¡ka prilikom odvezivanju datoteke zakljuÄavanja „%s“: %s" + +#: ../gio/gdbusauthmechanismsha1.c:687 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "GreÅ¡ka prilikom otvaranja priveska kljuÄeva „%s“ za pisanje: " + +#: ../gio/gdbusauthmechanismsha1.c:883 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Dodatno, otpuÅ¡tanje kljuÄa sa „%s“ takoÄ‘e nije uspelo: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2378 +msgid "The connection is closed" +msgstr "Veza je zatvorena" + +#: ../gio/gdbusconnection.c:1879 +msgid "Timeout was reached" +msgstr "Vreme je isteklo" + +#: ../gio/gdbusconnection.c:2500 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "NaiÅ¡ao sam na nepodržane oznake pri izgradnji klijentskog dela veze" + +#: ../gio/gdbusconnection.c:4124 ../gio/gdbusconnection.c:4471 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"Nema interfejsa „org.freedesktop.DBus.Properties“ u objektu na putanji %s" + +#: ../gio/gdbusconnection.c:4266 +#, c-format +msgid "No such property '%s'" +msgstr "Nema osobine „%s“" + +#: ../gio/gdbusconnection.c:4278 +#, c-format +msgid "Property '%s' is not readable" +msgstr "Osobina „%s“ nije Äitljiva" + +#: ../gio/gdbusconnection.c:4289 +#, c-format +msgid "Property '%s' is not writable" +msgstr "Nije moguće pisanje osobine „%s“" + +#: ../gio/gdbusconnection.c:4309 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"GreÅ¡ka pri postavljanju osobine „%s“: OÄekivani tip je bio „%s“, a dobijen je " +"„%s“" + +#: ../gio/gdbusconnection.c:4414 ../gio/gdbusconnection.c:4622 +#: ../gio/gdbusconnection.c:6591 +#, c-format +msgid "No such interface '%s'" +msgstr "Nema interfejsa „%s“" + +#: ../gio/gdbusconnection.c:4840 ../gio/gdbusconnection.c:7100 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "Nema interfejsa „%s“ u objektu na putanji %s" + +#: ../gio/gdbusconnection.c:4938 +#, c-format +msgid "No such method '%s'" +msgstr "Nema metoda „%s“" + +#: ../gio/gdbusconnection.c:4969 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "Tpi poruke, „%s“, ne odgovara oÄekivanom tipu „%s“" + +#: ../gio/gdbusconnection.c:5167 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Objekat je već izvezen za interfejs %s na %s" + +#: ../gio/gdbusconnection.c:5393 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Ne mogu da dobijem osobinu %s.%s" + +#: ../gio/gdbusconnection.c:5449 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Ne mogu da postavim osobinu %s.%s" + +#: ../gio/gdbusconnection.c:5627 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "Metod „%s“ je vratio tip „%s“, ali je bio oÄekivan „%s“" + +#: ../gio/gdbusconnection.c:6702 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "Metod „%s“ na interfejsu „%s“ sa potpisom „%s“ ne postoji" + +#: ../gio/gdbusconnection.c:6823 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Poddrvo je već izvezeno za %s" + +#: ../gio/gdbusconnection.c:7151 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"Ne mogu da odredim adresu magistrale sesije iz promenljive okruženja " +"DBUS_STARTER_BUS_TYPE — nepoznata vrednost „%s“" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "vrsta je NEISPRAVNA" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "Poruka POZIVA_METODA: nedostaju polja zaglavlja PUTANJA ili ÄŒLAN" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Poruka REZULTAT_METODA: nedostaje polje zaglavlja ODGOVORI_SERIJSKI" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Poruka GREÅ KE: nedostaju polja zaglavlja ODGOVORI_SERIJSKI ili NAZIV_GREÅ KE" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "Poruka SIGNALA: nedostaju polja zaglavlja PUTANJA, SUÄŒELJE ili ÄŒLAN" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Poruka SIGNALA: polje zaglavlja PUTANJA koristi rezervisanu vrednost „/org/" +"freedesktop/DBus/Local“" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Poruka SIGNALA: polje zaglavlja SUÄŒELJE koristi rezervisanu vrednost „org." +"freedesktop.DBus.Local“" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "PokuÅ¡ah da Äitam %lu bajt, ali dobih samo %lu" +msgstr[1] "PokuÅ¡ah da Äitam %lu bajta, ali dobih samo %lu" +msgstr[2] "PokuÅ¡ah da Äitam %lu bajtova, ali dobih samo %lu" +msgstr[3] "PokuÅ¡ah da Äitam jedan bajt, ali dobih samo %lu" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "OÄekivao sam NUL bajt posle niske „%s“, ali sam naÅ¡ao bajt %d" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"OÄekivah ispravnu UTF-8 nisku, ali naÄ‘oh neispravne bajtove na bajt pomeraju " +"%d (dužina niske je %d). Ispravna niska do tog dela je bila „%s“" + +#: ../gio/gdbusmessage.c:1593 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "RaÅ¡Älanjena vrednost „%s“ nije ispravna putanja objekta D-magistrale" + +#: ../gio/gdbusmessage.c:1615 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "RaÅ¡Älanjena vrednost „%s“ nije ispravan potpis D-magistrale" + +#: ../gio/gdbusmessage.c:1662 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"NaiÅ¡ao sam na niz dužine %u bajt. Najveća dužina je 2<<26 bajta (64 MiB)." +msgstr[1] "" +"NaiÅ¡ao sam na niz dužine %u bajta. Najveća dužina je 2<<26 bajta (64 MiB)." +msgstr[2] "" +"NaiÅ¡ao sam na niz dužine %u bajtova. Najveća dužina je 2<<26 bajtova (64 " +"MiB)." +msgstr[3] "" +"NaiÅ¡ao sam na niz dužine jednog bajta. Najveća dužina je 2<<26 bajtova (64 " +"MiB)." + +#: ../gio/gdbusmessage.c:1682 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"NaiÄ‘oh na niz vrste „a%c“, oÄekivah da je dužina umnožak od %u bajta, ali " +"naÄ‘oh da je dug %u bajta" + +#: ../gio/gdbusmessage.c:1849 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "" +"RaÅ¡Älanjena vrednost „%s“ za varijantu nije ispravan potpis D-magistrale" + +#: ../gio/gdbusmessage.c:1873 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"GreÅ¡ka pri deserijalizaciji Gvarijanta sa niskom vrste „%s“ iz žiÄanog " +"formata D-magistrale" + +#: ../gio/gdbusmessage.c:2055 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Neispravna vrednost za krajnjost. OÄekivao sam 0x6c („l“) ili 0x42 („Bd) ali " +"sam naÅ¡ao vrednost 0x%02x" + +#: ../gio/gdbusmessage.c:2068 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Neispravna glavno izdanje protokola. OÄekivano 1, ali naÄ‘eno %d" + +#: ../gio/gdbusmessage.c:2124 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "Potpis zaglavlja sa potpisom „%s“ je naÄ‘en, ali je telo poruke prazno" + +#: ../gio/gdbusmessage.c:2138 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "" +"RaÅ¡Älanjena vrednost „%s“ nije ispravan potpis D-magistrale (za telo poruke)" + +#: ../gio/gdbusmessage.c:2168 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Nema zaglavlja potpisa u poruci, ali telo poruke ima %u bajt" +msgstr[1] "Nema zaglavlja potpisa u poruci, ali telo poruke ima %u bajta" +msgstr[2] "Nema zaglavlja potpisa u poruci, ali telo poruke ima %u bajtova" +msgstr[3] "Nema zaglavlja potpisa u poruci, ali telo poruke ima jedan bajt" + +#: ../gio/gdbusmessage.c:2178 +msgid "Cannot deserialize message: " +msgstr "Ne mogu da deserijalizujem poruku: " + +#: ../gio/gdbusmessage.c:2519 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"GreÅ¡ka pri serijalizaciji Gvarijanta sa niskom vrste „%s“ iz žiÄanog formata " +"D-magistrale" + +#: ../gio/gdbusmessage.c:2656 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"Broj opisnika datoteke u poruci (%d) se razlikuje od zaglavlja polja (%d)" + +#: ../gio/gdbusmessage.c:2664 +msgid "Cannot serialize message: " +msgstr "Ne mogu da serijalizujem poruku: " + +#: ../gio/gdbusmessage.c:2708 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "Telo poruke ima potpis „%s“, ali nedostaje zaglavlje potpisa" + +#: ../gio/gdbusmessage.c:2718 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "Telo poruke ima tip potpisa „%s“, ali potpis u polju zaglavlja je „%s“" + +#: ../gio/gdbusmessage.c:2734 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Telo poruke je prazno,,, ali je potpis u polju zaglavlja „(%s)“" + +#: ../gio/gdbusmessage.c:3287 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Dobijena je greÅ¡ka sa telom poruke tipa „%s“" + +#: ../gio/gdbusmessage.c:3295 +msgid "Error return with empty body" +msgstr "Dobijena je greÅ¡ka sa praznim telom poruke" + +#: ../gio/gdbusprivate.c:2066 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Ne mogu da dobavim profil fiziÄkih delova: %s" + +#: ../gio/gdbusprivate.c:2111 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Ne mogu da uÄitam „/var/lib/dbus/machine-id“ ili „/etc/machine-id“: " + +#: ../gio/gdbusproxy.c:1612 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "GreÅ¡ka pri pozivu pokreni uslugu prema nazivu za %s: " + +#: ../gio/gdbusproxy.c:1635 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "NeoÄekivan odgovor %d od StartServiceByName(„%s“) metoda" + +#: ../gio/gdbusproxy.c:2726 ../gio/gdbusproxy.c:2860 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ne mogu da pozovem metod; posrednik je za dobro znani naziv bez vlasnika, a " +"napravljen je bez G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START oznake" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "Apstraktni imenski prostor nije podržan" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"Ne mogu da navedem datoteku jednokratnih sluÄajnih brojeva pri povezivanju sa " +"serverom" + +#: ../gio/gdbusserver.c:876 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "" +"GreÅ¡ka prilikom upisa datoteke jednokratnih sluÄajnih brojeva na „%s“: %s" + +#: ../gio/gdbusserver.c:1047 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Niska „%s“ nije ispravni GJIB D-sabirnice" + +#: ../gio/gdbusserver.c:1087 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Ne mogu da sluÅ¡am na nepodržanom prenosnom mehanizmu „%s“" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Naredbe:\n" +" help Prikazuje ovu informaciju\n" +" introspect Ispituje udaljeni objekat\n" +" monitor Nadgleda udaljeni objekat\n" +" call Poziva naÄin na udaljenom objektu\n" +" emit Å alje signal\n" +" wait ÄŒeka da se pojavi naziv magistrale\n" +"\n" +"Koristite „%s NAREDBA --help“ da dobijete pomoć za pojedinaÄne naredbe.\n" + +#: ../gio/gdbus-tool.c:185 ../gio/gdbus-tool.c:252 ../gio/gdbus-tool.c:324 +#: ../gio/gdbus-tool.c:348 ../gio/gdbus-tool.c:834 ../gio/gdbus-tool.c:1171 +#: ../gio/gdbus-tool.c:1613 +#, c-format +msgid "Error: %s\n" +msgstr "GreÅ¡ka: %s\n" + +#: ../gio/gdbus-tool.c:196 ../gio/gdbus-tool.c:265 ../gio/gdbus-tool.c:1629 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "GreÅ¡ka pri raÅ¡Älanjivanju XML-a dobijenog ispitivanjem: %s\n" + +#: ../gio/gdbus-tool.c:234 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv\n" + +#: ../gio/gdbus-tool.c:382 +msgid "Connect to the system bus" +msgstr "Povezivanje na sistemsku magistrali" + +#: ../gio/gdbus-tool.c:383 +msgid "Connect to the session bus" +msgstr "Povezivanje na magistralu sesije" + +#: ../gio/gdbus-tool.c:384 +msgid "Connect to given D-Bus address" +msgstr "Povezivanje na zadatu D-bas adresu" + +#: ../gio/gdbus-tool.c:394 +msgid "Connection Endpoint Options:" +msgstr "Opcije krajnje taÄke veze:" + +#: ../gio/gdbus-tool.c:395 +msgid "Options specifying the connection endpoint" +msgstr "Opcije koje odreÄ‘uju krajnju taÄku veze" + +#: ../gio/gdbus-tool.c:417 +#, c-format +msgid "No connection endpoint specified" +msgstr "Nije navedena krajnja taÄka veze" + +#: ../gio/gdbus-tool.c:427 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Navedeno viÅ¡e krajnjih taÄaka veze" + +#: ../gio/gdbus-tool.c:497 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "" +"Upozorenje: Prema podacima dobijenim ispitivanjem, interfejs „%s“ ne postoji\n" + +#: ../gio/gdbus-tool.c:506 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Upozorenje: Prema podacima dobijenim ispitivanjem, metod „%s“ ne postoji na " +"interfejsu „%s“\n" + +#: ../gio/gdbus-tool.c:568 +msgid "Optional destination for signal (unique name)" +msgstr "Opcionalna destinacija signala (jedinstveno ime)" + +#: ../gio/gdbus-tool.c:569 +msgid "Object path to emit signal on" +msgstr "Putanja objekta za emitovanje signala" + +#: ../gio/gdbus-tool.c:570 +msgid "Signal and interface name" +msgstr "Naziv signala i suÄelja" + +#: ../gio/gdbus-tool.c:603 +msgid "Emit a signal." +msgstr "Emituje signal." + +#: ../gio/gdbus-tool.c:658 ../gio/gdbus-tool.c:965 ../gio/gdbus-tool.c:1715 +#: ../gio/gdbus-tool.c:1944 ../gio/gdbus-tool.c:2164 +#, c-format +msgid "Error connecting: %s\n" +msgstr "GreÅ¡ka u povezivanju: %s\n" + +#: ../gio/gdbus-tool.c:678 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv jedinstvene magistrale.\n" + +#: ../gio/gdbus-tool.c:697 ../gio/gdbus-tool.c:1008 ../gio/gdbus-tool.c:1758 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "GreÅ¡ka: Nije izabrana putanja do objekta\n" + +#: ../gio/gdbus-tool.c:720 ../gio/gdbus-tool.c:1028 ../gio/gdbus-tool.c:1778 +#: ../gio/gdbus-tool.c:2015 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "GreÅ¡ka: %s nije ispravna putanja do objekata\n" + +#: ../gio/gdbus-tool.c:740 +#, c-format +msgid "Error: Signal name is not specified\n" +msgstr "GreÅ¡ka: Ime signala nije odreÄ‘eno\n" + +#: ../gio/gdbus-tool.c:754 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "GreÅ¡ka: Ime signala „%s“ nije odreÄ‘eno\n" + +#: ../gio/gdbus-tool.c:766 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv suÄelja\n" + +#: ../gio/gdbus-tool.c:772 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv Älana\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:809 ../gio/gdbus-tool.c:1140 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "GreÅ¡ka pri obradi parametra %d: %s\n" + +#: ../gio/gdbus-tool.c:841 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "GreÅ¡ka ispiranja veze: %s\n" + +#: ../gio/gdbus-tool.c:868 +msgid "Destination name to invoke method on" +msgstr "Naziv odrediÅ¡ta na kome treba pozvati metod" + +#: ../gio/gdbus-tool.c:869 +msgid "Object path to invoke method on" +msgstr "Putanja objekta na kome treba pozvati metod" + +#: ../gio/gdbus-tool.c:870 +msgid "Method and interface name" +msgstr "Ime metoda i interfejsa" + +#: ../gio/gdbus-tool.c:871 +msgid "Timeout in seconds" +msgstr "Vreme isteka u sekundama" + +#: ../gio/gdbus-tool.c:910 +msgid "Invoke a method on a remote object." +msgstr "Pozivanje metoda na udaljenom objektu." + +#: ../gio/gdbus-tool.c:982 ../gio/gdbus-tool.c:1732 ../gio/gdbus-tool.c:1969 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "GreÅ¡ka: Nije izabrano odrediÅ¡te\n" + +#: ../gio/gdbus-tool.c:993 ../gio/gdbus-tool.c:1749 ../gio/gdbus-tool.c:1980 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv magistrale\n" + +#: ../gio/gdbus-tool.c:1043 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "GreÅ¡ka: Ime naÄina nije odreÄ‘eno\n" + +#: ../gio/gdbus-tool.c:1054 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "GreÅ¡ka: Ime naÄina „%s“ nije odreÄ‘eno\n" + +#: ../gio/gdbus-tool.c:1132 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "GreÅ¡ka pri obradi parametra %d vrste „%s“: %s\n" + +#: ../gio/gdbus-tool.c:1576 +msgid "Destination name to introspect" +msgstr "Naziv odrediÅ¡ta za ispitivanje" + +#: ../gio/gdbus-tool.c:1577 +msgid "Object path to introspect" +msgstr "Putanja objekta za ispitivanje" + +#: ../gio/gdbus-tool.c:1578 +msgid "Print XML" +msgstr "Å tampa IksML" + +#: ../gio/gdbus-tool.c:1579 +msgid "Introspect children" +msgstr "Preispituje Älanove" + +#: ../gio/gdbus-tool.c:1580 +msgid "Only print properties" +msgstr "Samo Å¡tampa svojstva" + +#: ../gio/gdbus-tool.c:1667 +msgid "Introspect a remote object." +msgstr "Ispitajte udaljeni objekat." + +#: ../gio/gdbus-tool.c:1870 +msgid "Destination name to monitor" +msgstr "Naziv odrediÅ¡ta za nadgledanje" + +#: ../gio/gdbus-tool.c:1871 +msgid "Object path to monitor" +msgstr "Putanja objekta za nadgledanje" + +#: ../gio/gdbus-tool.c:1896 +msgid "Monitor a remote object." +msgstr "Nadgledanje udaljenog objekta." + +#: ../gio/gdbus-tool.c:1954 +#, c-format +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "GreÅ¡ka: ne mogu da nadgledam vezu na sabirnici koja nije za poruke\n" + +#: ../gio/gdbus-tool.c:2078 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Usluga za aktiviranje pre Äekanja na drugu (dobro znan naziv)" + +#: ../gio/gdbus-tool.c:2081 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Vreme za Äekanje pre izlaska sa greÅ¡kom (sekunde); 0 — bez vremenskog roka " +"(osnovno)" + +#: ../gio/gdbus-tool.c:2129 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPCIJA…] NAZIV_MAGISTRALE" + +#: ../gio/gdbus-tool.c:2130 +msgid "Wait for a bus name to appear." +msgstr "ÄŒeka da se pojavi naziv magistrale." + +#: ../gio/gdbus-tool.c:2206 +#, c-format +msgid "Error: A service to activate for must be specified.\n" +msgstr "GreÅ¡ka: Usluga za aktiviranje mora biti navedena.\n" + +#: ../gio/gdbus-tool.c:2211 +#, c-format +msgid "Error: A service to wait for must be specified.\n" +msgstr "GreÅ¡ka: Usluga za Äekanje mora biti navedena.\n" + +#: ../gio/gdbus-tool.c:2216 +#, c-format +msgid "Error: Too many arguments.\n" +msgstr "GreÅ¡ka: PreviÅ¡e argumenata.\n" + +#: ../gio/gdbus-tool.c:2224 ../gio/gdbus-tool.c:2231 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "GreÅ¡ka: „%s“ nije ispravan naziv dobro znane magistrale.\n" + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4566 +msgid "Unnamed" +msgstr "Neimenovano" + +#: ../gio/gdesktopappinfo.c:2411 +msgid "Desktop file didn’t specify Exec field" +msgstr "Datoteka za radnu povrÅ¡ ne sadrži Exec unos" + +#: ../gio/gdesktopappinfo.c:2701 +msgid "Unable to find terminal required for application" +msgstr "Ne mogu da naÄ‘em terminal radi pokretanja ovog programa" + +#: ../gio/gdesktopappinfo.c:3135 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Ne mogu da napravim fasciklu za korisnikova podeÅ¡avanja %s: %s" + +#: ../gio/gdesktopappinfo.c:3139 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Ne mogu da napravim fasciklu za korisnikova MIME podeÅ¡avanja %s: %s" + +#: ../gio/gdesktopappinfo.c:3379 ../gio/gdesktopappinfo.c:3403 +msgid "Application information lacks an identifier" +msgstr "Podacima o programu nedostaje identifikator" + +#: ../gio/gdesktopappinfo.c:3637 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Ne mogu da napravim datoteku radne povrÅ¡i %s" + +#: ../gio/gdesktopappinfo.c:3771 +#, c-format +msgid "Custom definition for %s" +msgstr "Proizvoljne odrednice za %s" + +#: ../gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "ureÄ‘aj ne podržava „izbaci“" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "ureÄ‘aj ne podržava „izbaci“ ili „izbaci_sa_operacijom“" + +#: ../gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "nije podržano izvlaÄenje medijuma na ureÄ‘aju" + +#: ../gio/gdrive.c:776 +msgid "drive doesn’t implement start" +msgstr "ureÄ‘aj ne podržava „pokreni“" + +#: ../gio/gdrive.c:878 +msgid "drive doesn’t implement stop" +msgstr "ureÄ‘aj ne podržava „zaustavi“" + +#: ../gio/gdummytlsbackend.c:195 ../gio/gdummytlsbackend.c:317 +#: ../gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "TLS podrÅ¡ka nije dostupna" + +#: ../gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "DTLS podrÅ¡ka nije dostupna" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Ne mogu da radim sa izdanjem %d kodiranja GEmblema" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Neispravno zadat broj tokena (%d) u kodiranju GEmblema" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Ne mogu da radim sa izdanjem %d kodiranja ikonice GEmblema" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Nije ispravno zadat broj tokena (%d) u kodiranju ikonice GEmblema" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "OÄekivano je GEmblem za ikonicu GEmblema" + +#: ../gio/gfile.c:1071 ../gio/gfile.c:1309 ../gio/gfile.c:1447 +#: ../gio/gfile.c:1685 ../gio/gfile.c:1740 ../gio/gfile.c:1798 +#: ../gio/gfile.c:1882 ../gio/gfile.c:1939 ../gio/gfile.c:2003 +#: ../gio/gfile.c:2058 ../gio/gfile.c:3725 ../gio/gfile.c:3780 +#: ../gio/gfile.c:4016 ../gio/gfile.c:4058 ../gio/gfile.c:4526 +#: ../gio/gfile.c:4937 ../gio/gfile.c:5022 ../gio/gfile.c:5112 +#: ../gio/gfile.c:5209 ../gio/gfile.c:5296 ../gio/gfile.c:5397 +#: ../gio/gfile.c:7975 ../gio/gfile.c:8065 ../gio/gfile.c:8149 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "Radnja nije podržana" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: ../gio/gfile.c:1570 +msgid "Containing mount does not exist" +msgstr "Sadržano montiranje ne postoji" + +#: ../gio/gfile.c:2617 ../gio/glocalfile.c:2446 +msgid "Can’t copy over directory" +msgstr "Ne mogu da umnožim preko direktorijuma" + +#: ../gio/gfile.c:2677 +msgid "Can’t copy directory over directory" +msgstr "Ne mogu da umnožim direktorijum preko direktorijuma" + +#: ../gio/gfile.c:2685 +msgid "Target file exists" +msgstr "Ciljna datoteka već postoji" + +#: ../gio/gfile.c:2704 +msgid "Can’t recursively copy directory" +msgstr "Ne mogu da umnožim direktorijum i njegov sadržaj" + +#: ../gio/gfile.c:2979 +msgid "Splice not supported" +msgstr "Deljenje nije podržano" + +#: ../gio/gfile.c:2983 ../gio/gfile.c:3027 +#, c-format +msgid "Error splicing file: %s" +msgstr "GreÅ¡ka prilikom deljenja datoteke: %s" + +#: ../gio/gfile.c:3136 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Nije podržano umnožavanje (reflink/clone) izmeÄ‘u montiranih ureÄ‘aja" + +#: ../gio/gfile.c:3140 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Umnožavanje (reflink/clone) nije podržano ili je neispravno" + +#: ../gio/gfile.c:3145 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Umnožavanje (reflink/clone) nije podržano ili ne radi" + +#: ../gio/gfile.c:3208 +msgid "Can’t copy special file" +msgstr "Ne mogu da umnožim specijalnu datoteku" + +#: ../gio/gfile.c:4006 +msgid "Invalid symlink value given" +msgstr "Data je neispravna simboliÄka veza" + +#: ../gio/gfile.c:4167 +msgid "Trash not supported" +msgstr "Nije podržano smeće" + +#: ../gio/gfile.c:4279 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Imena datoteka ne mogu da sadrže „%c“" + +#: ../gio/gfile.c:6760 ../gio/gvolume.c:363 +msgid "volume doesn’t implement mount" +msgstr "nije podržano montiranje diska" + +#: ../gio/gfile.c:6869 +msgid "No application is registered as handling this file" +msgstr "Ni jedan program ne može da otvori ovu datoteku" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Nabrajanje je zatvoreno" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Brojanje datoteka ima neispunjenu radnju" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Brojanje datoteka je već zavrÅ¡eno" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Ne mogu da radim sa izdanjem %d kodiranja ikonice GDatoteke" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "LoÅ¡i ulazni podaci za ikonicu GDatoteke" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Tok ne podržava „propitaj_podatke“" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Nije podržavano premotavanje toka" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Sasecanje nije dozvoljenu nad ulaznim tokom" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Sasecanje nije dozvoljeno nad tokom" + +#: ../gio/ghttpproxy.c:91 ../gio/gresolver.c:410 ../gio/gresolver.c:476 +#: ../glib/gconvert.c:1786 +msgid "Invalid hostname" +msgstr "Neispravno ime domaćina" + +#: ../gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "LoÅ¡ odgovor od HTTP posrednika" + +#: ../gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "Nije dozvoljena veza sa posrednikom za HTTP" + +#: ../gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Nije uspela prijava na posrednika za HTTP" + +#: ../gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Potrebna je prijava na posrednika za HTTP" + +#: ../gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Nije uspelo veza sa posrednikom za HTTP: %i" + +#: ../gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Server HTTP posrednika je neoÄekivano prekinuo vezu." + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Nije ispravan broj tokena (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "Ne postoji vrsta za naziv klase %s" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Vrsta %s ne podržava suÄelje GIkonice" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "Vrsta %s ne pripada ni jednoj klasi" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "Broj izdanja je loÅ¡e zadat: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s vrsta ne podržava „from_tokens()“ na suÄelju GIkonice" + +#: ../gio/gicon.c:461 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Ne mogu da radim sa datim izdanjem kodiranja ikonice" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Nije navedena adresa" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Dužina %u je previÅ¡e duga za adresu" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adresa ima skup bitova preko dužine prefiksa" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Ne mogu da obradim „%s“ kao masku IP adrese" + +#: ../gio/ginetsocketaddress.c:203 ../gio/ginetsocketaddress.c:220 +#: ../gio/gnativesocketaddress.c:109 ../gio/gunixsocketaddress.c:218 +msgid "Not enough space for socket address" +msgstr "Nema dovoljno mesta za adresu utiÄnice" + +#: ../gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Nije podržana adresa utiÄnice" + +#: ../gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Ulazni tok ne podržava Äitanje" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1218 ../gio/giostream.c:310 +#: ../gio/goutputstream.c:1671 +msgid "Stream has outstanding operation" +msgstr "Tok radi jako dobro" + +#: ../gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Umnoži sa datotekom" + +#: ../gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Zadrži sa datotekom prilikom premeÅ¡tanja" + +#: ../gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "„version“ ne prihvata argumente" + +#: ../gio/gio-tool.c:207 ../gio/gio-tool.c:223 ../glib/goption.c:857 +msgid "Usage:" +msgstr "Upotreba:" + +#: ../gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Ispisuje podatke o izdanju i izlazi." + +#: ../gio/gio-tool.c:224 +msgid "[ARGS...]" +msgstr "[ARGUMENTI…]" + +#: ../gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Naredbe:" + +#: ../gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Nadovezuje datoteke na standardni izlaz" + +#: ../gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Umnožava jednu ili viÅ¡e datoteka" + +#: ../gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Prikazuje podatke o mestima" + +#: ../gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "Ispisuje sadržaj mesta" + +#: ../gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "Dobavlja i postavlja rukovaoca za mime vrstu" + +#: ../gio/gio-tool.c:234 +msgid "Create directories" +msgstr "Pravi direktorijume" + +#: ../gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "Prati datoteke i direktorijume za izmenama" + +#: ../gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "KaÄi ili otkaÄinje mesta" + +#: ../gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "PremeÅ¡ta jednu ili viÅ¡e datoteka" + +#: ../gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "Otvara datoteke osnovnim programom" + +#: ../gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "Preimenuje datoteku" + +#: ../gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "BriÅ¡e jednu ili viÅ¡e datoteka" + +#: ../gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "ÄŒita sa standardnog ulaza i Äuva" + +#: ../gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "PodeÅ¡ava atribut datoteke" + +#: ../gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "PremeÅ¡ta datoteke ili direktorijume u smeće" + +#: ../gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "Ispisuje sadržaj mesta u stablu" + +#: ../gio/gio-tool.c:246 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Koristite „%s“ da dobavite opÅ¡irniju pomoć.\n" + +#: ../gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "GreÅ¡ka pisanja na standardni izlaz" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-cat.c:133 ../gio/gio-tool-info.c:282 +#: ../gio/gio-tool-list.c:165 ../gio/gio-tool-mkdir.c:48 +#: ../gio/gio-tool-monitor.c:37 ../gio/gio-tool-monitor.c:39 +#: ../gio/gio-tool-monitor.c:41 ../gio/gio-tool-monitor.c:43 +#: ../gio/gio-tool-monitor.c:203 ../gio/gio-tool-mount.c:1141 +#: ../gio/gio-tool-open.c:113 ../gio/gio-tool-remove.c:48 +#: ../gio/gio-tool-rename.c:45 ../gio/gio-tool-set.c:89 +#: ../gio/gio-tool-trash.c:81 ../gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "MESTO" + +#: ../gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Nadovezuje datoteke i ispisuje na standardni izlaz." + +#: ../gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"„gio cat“ radi baÅ¡ kao tradicionalno pomagalo „cat“, ali koristi GIO\n" +"mesta umesto mesnih datoteka: na primer, možete koristiti neÅ¡to\n" +"kao „smb://server/resource/datoteka.txt“ kao mesto." + +#: ../gio/gio-tool-cat.c:162 ../gio/gio-tool-info.c:313 +#: ../gio/gio-tool-mkdir.c:76 ../gio/gio-tool-monitor.c:228 +#: ../gio/gio-tool-open.c:139 ../gio/gio-tool-remove.c:72 +msgid "No locations given" +msgstr "Nije dato mesto" + +#: ../gio/gio-tool-copy.c:42 ../gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Nema ciljne datoteke" + +#: ../gio/gio-tool-copy.c:43 ../gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Prikazuje napredak" + +#: ../gio/gio-tool-copy.c:44 ../gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Pita pre prepisivanja" + +#: ../gio/gio-tool-copy.c:45 +msgid "Preserve all attributes" +msgstr "OÄuvava sve atribute" + +#: ../gio/gio-tool-copy.c:46 ../gio/gio-tool-move.c:41 +#: ../gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Pravi rezervu postojećih odrediÅ¡nih datoteka" + +#: ../gio/gio-tool-copy.c:47 +msgid "Never follow symbolic links" +msgstr "Nikada ne prati simboliÄke veze" + +#: ../gio/gio-tool-copy.c:72 ../gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "PreneÅ¡eno je %s od %s (%s/s)" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "IZVOR" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +#: ../gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ODREDIÅ TE" + +#: ../gio/gio-tool-copy.c:103 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Umnožava jednu ili viÅ¡e datoteka iz IZVORA u ODREDIÅ TE." + +#: ../gio/gio-tool-copy.c:105 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"„gio copy“ je sliÄan tradicionalnom pomagalu „cp“, ali koristi GIO\n" +"mesta umesto mesnih datoteka: na primer, možete koristiti neÅ¡to\n" +"kao „smb://server/resource/datoteka.txt“ kao mesto." + +#: ../gio/gio-tool-copy.c:147 +#, c-format +msgid "Destination %s is not a directory" +msgstr "OdrediÅ¡te „%s“ nije direktorijum" + +#: ../gio/gio-tool-copy.c:192 ../gio/gio-tool-move.c:185 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: da prepiÅ¡em „%s“? " + +#: ../gio/gio-tool-info.c:34 +msgid "List writable attributes" +msgstr "Ispisuje ispisive atribute" + +#: ../gio/gio-tool-info.c:35 +msgid "Get file system info" +msgstr "Dobavlja podatake o sistemu datoteka" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "The attributes to get" +msgstr "Atributi za dobavljanje" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "ATTRIBUTES" +msgstr "ATRIBUTI" + +#: ../gio/gio-tool-info.c:37 ../gio/gio-tool-list.c:38 ../gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ne prati simboliÄke veze" + +#: ../gio/gio-tool-info.c:75 +#, c-format +msgid "attributes:\n" +msgstr "atributi:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "naziv prikaza: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "naziv ureÄ‘ivanja: %s\n" + +#: ../gio/gio-tool-info.c:138 +#, c-format +msgid "name: %s\n" +msgstr "naziv: %s\n" + +#: ../gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "vrsta: %s\n" + +#: ../gio/gio-tool-info.c:151 +#, c-format +msgid "size: " +msgstr "veliÄina: " + +#: ../gio/gio-tool-info.c:156 +#, c-format +msgid "hidden\n" +msgstr "skriveno\n" + +#: ../gio/gio-tool-info.c:159 +#, c-format +msgid "uri: %s\n" +msgstr "putanja: %s\n" + +#: ../gio/gio-tool-info.c:228 +#, c-format +msgid "Settable attributes:\n" +msgstr "Podesive osobine:\n" + +#: ../gio/gio-tool-info.c:252 +#, c-format +msgid "Writable attribute namespaces:\n" +msgstr "Nazivni prostori zapisive osobine:\n" + +#: ../gio/gio-tool-info.c:287 +msgid "Show information about locations." +msgstr "Prikazuje podatke o mestima." + +#: ../gio/gio-tool-info.c:289 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"„gio info“ je sliÄan tradicionalnom pomagalu „ls“, ali koristi GIO\n" +"mesta umesto mesnih datoteka: na primer, možete koristiti neÅ¡to\n" +"kao „smb://server/resource/datoteka.txt“ kao mesto. Atributi datoteke se " +"mogu\n" +"navesti njihovim GIO nazivom, tj. „standard::icon“, ili samo\n" +"nazivnim prostorom, tj. „unix“, ili sa „*“, koja odgovara svim atributima" + +#: ../gio/gio-tool-list.c:36 ../gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Prikazuje skrivene datoteke" + +#: ../gio/gio-tool-list.c:37 +msgid "Use a long listing format" +msgstr "Koristi dugi zapis spiska" + +#: ../gio/gio-tool-list.c:39 +msgid "Print full URIs" +msgstr "Å tampa pune putanje" + +#: ../gio/gio-tool-list.c:170 +msgid "List the contents of the locations." +msgstr "Ispisuje sadržaje mesta." + +#: ../gio/gio-tool-list.c:172 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"„gio list“ je sliÄan tradicionalnom pomagalu „ls“, ali koristi GIO\n" +"mesta umesto mesnih datoteka: na primer, možete koristiti neÅ¡to\n" +"kao „smb://server/resource/datoteka.txt“ kao mesto. Atributi datoteke se " +"mogu\n" +"navesti njihovim GIO nazivom, tj. „standard::icon“" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMEVRSTA" + +#: ../gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "RUKOVALAC" + +#: ../gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Dobavlja i postavlja rukovaoca za mime vrstu." + +#: ../gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Ako nije dat rukovalac, ispisuje registrovane i preporuÄene programe\n" +"za mime vrstu. Ako je rukovalac dat, postavlja se kao osnovni\n" +"rukovalac za mime vrstu." + +#: ../gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Morate navesti jednu mime vrstu, i možda rukovaoca" + +#: ../gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "nema osnovnog programa za „%s“\n" + +#: ../gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Osnovni program za „%s“: %s\n" + +#: ../gio/gio-tool-mime.c:127 +#, c-format +msgid "Registered applications:\n" +msgstr "Zabeleženi programi:\n" + +#: ../gio/gio-tool-mime.c:129 +#, c-format +msgid "No registered applications\n" +msgstr "Nema zabeleženih programa\n" + +#: ../gio/gio-tool-mime.c:140 +#, c-format +msgid "Recommended applications:\n" +msgstr "PreporuÄeni programi:\n" + +#: ../gio/gio-tool-mime.c:142 +#, c-format +msgid "No recommended applications\n" +msgstr "Nema preporuÄenih programa\n" + +#: ../gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Nisam uspeo da uÄitam podatke za rukovaoca „%s“" + +#: ../gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Nisam uspeo da podesim „%s“ kao osnovnog rukovaoca za „%s“: %s\n" + +#: ../gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Pravi roditeljske direktorijume" + +#: ../gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Pravi direktorijume." + +#: ../gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"„gio cmkdir“ je sliÄan tradicionalnom pomagalu „mkdir“, ali koristi GIO\n" +"mesta umesto mesnih datoteka: na primer, možete koristiti neÅ¡to\n" +"kao „smb://server/resource/mojdirektorijum“ kao mesto." + +#: ../gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Prati direktorijum (osnovno: zavisi od vrste)" + +#: ../gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Prati datoteku (osnovno: zavisi od vrste)" + +#: ../gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Prati datoteku direktno (zapaža izmene uÄinjene putem Ävrstih veza)" + +#: ../gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Prati datoteku direktno, ali ne izveÅ¡tava o izmenama" + +#: ../gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"IzveÅ¡tava o premeÅ¡tanjima i preimenovanjima kao o jednom dogaÄ‘aju brisanja/" +"stvaranja" + +#: ../gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Gleda dogaÄ‘aje kaÄenja" + +#: ../gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "Prati datoteke ili direktorijume za izmenama." + +#: ../gio/gio-tool-mount.c:58 +msgid "Mount as mountable" +msgstr "KaÄi kao prikaÄljivom" + +#: ../gio/gio-tool-mount.c:59 +msgid "Mount volume with device file" +msgstr "KaÄi volumen sa datotekom ureÄ‘aja" + +#: ../gio/gio-tool-mount.c:59 +msgid "DEVICE" +msgstr "UREÄAJ" + +#: ../gio/gio-tool-mount.c:60 +msgid "Unmount" +msgstr "OtkaÄi" + +#: ../gio/gio-tool-mount.c:61 +msgid "Eject" +msgstr "Izbaci" + +#: ../gio/gio-tool-mount.c:62 +msgid "Unmount all mounts with the given scheme" +msgstr "OtkaÄinje sva kaÄenja datom Å¡emom" + +#: ../gio/gio-tool-mount.c:62 +msgid "SCHEME" +msgstr "Å EMA" + +#: ../gio/gio-tool-mount.c:63 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Zanemaruje zaostale radnje datoteke kada otkaÄinje ili izbacuje" + +#: ../gio/gio-tool-mount.c:64 +msgid "Use an anonymous user when authenticating" +msgstr "Koristi anonimnog korisnika prilikom potvrde identiteta" + +#. Translator: List here is a verb as in 'List all mounts' +#: ../gio/gio-tool-mount.c:66 +msgid "List" +msgstr "IspiÅ¡i" + +#: ../gio/gio-tool-mount.c:67 +msgid "Monitor events" +msgstr "Prati dogaÄ‘aje" + +#: ../gio/gio-tool-mount.c:68 +msgid "Show extra information" +msgstr "Prikazuje dodatne podatke" + +#: ../gio/gio-tool-mount.c:246 ../gio/gio-tool-mount.c:276 +msgid "Anonymous access denied" +msgstr "Anoniman pristup je zabranjen" + +#: ../gio/gio-tool-mount.c:897 +#, c-format +msgid "Mounted %s at %s\n" +msgstr "Montirah „%s“ na „%s“\n" + +#: ../gio/gio-tool-mount.c:950 +msgid "No volume for device file" +msgstr "Nema volumena za datoteku ureÄ‘aja" + +#: ../gio/gio-tool-mount.c:1145 +msgid "Mount or unmount the locations." +msgstr "KaÄi ili otkaÄinje mesta." + +#: ../gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ne koristi umnožak i briÅ¡e vraćanje na staro" + +#: ../gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "PremeÅ¡ta jednu ili viÅ¡e datoteka iz IZVORA u ODREDIÅ TE." + +#: ../gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"„gio move“ je sliÄan tradicionalnom pomagalu „mv“, ali koristi GIO\n" +"mesta umesto mesnih datoteka: na primer, možete koristiti neÅ¡to\n" +"kao „smb://server/resource/datoteka.txt“ kao mesto" + +#: ../gio/gio-tool-move.c:142 +#, c-format +msgid "Target %s is not a directory" +msgstr "Cilj „%s“ nije direktorijum" + +#: ../gio/gio-tool-open.c:118 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Otvorite datoteke osnovnim programom koji je\n" +"registrovan za rad sa datotekama ove vrste." + +#: ../gio/gio-tool-remove.c:31 ../gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "Zanemaruje nepostojeće datoteke, nikada ne postavlja upit" + +#: ../gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "ObriÅ¡ite date datoteke." + +#: ../gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAZIV" + +#: ../gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Preimenujte datoteku." + +#: ../gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Nedostaje argument" + +#: ../gio/gio-tool-rename.c:76 ../gio/gio-tool-save.c:190 +#: ../gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "PreviÅ¡e argumenata" + +#: ../gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Preimenovanje je uspelo. Nova putanja: %s\n" + +#: ../gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Pravi samo ako je nepostojeća" + +#: ../gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Dodaje na kraj datoteke" + +#: ../gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "Prilikom stvaranja, ograniÄava pristup na trenutnog korisnika" + +#: ../gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Prilikom zamene, zamenjuje kao da odrediÅ¡te ne postoji" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Å tampa novu e-oznaku na kraju" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "E-oznaka datoteke koja je prepisana" + +#: ../gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "E-OZNAKA" + +#: ../gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "GreÅ¡ka Äitanja sa standardnog ulaza" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:139 +#, c-format +msgid "Etag not available\n" +msgstr "E-oznaka nije dostupna\n" + +#: ../gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "ÄŒita sa standardnog ulaza i Äuva u ODREDIÅ TE." + +#: ../gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Nije dato odrediÅ¡te" + +#: ../gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Vrsta atributa" + +#: ../gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "VRSTA" + +#: ../gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATRIBUT" + +#: ../gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VREDNOST" + +#: ../gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "PodeÅ¡ava atribut datoteke za MESTO." + +#: ../gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Nije navedeno mesto" + +#: ../gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Nije naveden atribut" + +#: ../gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Nije navedena vrednost" + +#: ../gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Neispravna vrsta atributa „%s“" + +#: ../gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "Prazni smeće" + +#: ../gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "PremeÅ¡ta datoteke ili direktorijume u smeće." + +#: ../gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Prati simboliÄke veze, kaÄenja i preÄice" + +#: ../gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Ispisuje sadržaj direktorijuma u zapisu stabla." + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1501 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Element <%s> nije dozvoljen unutar <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Element <%s> nije dozvoljen na najviÅ¡em nivou" + +#: ../gio/glib-compile-resources.c:237 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Datoteka „%s“ se pojavljuje viÅ¡e puta u izvoru" + +#: ../gio/glib-compile-resources.c:248 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Nisam uspeo da pronaÄ‘em „%s“ ni u jenom izvornom direktorijumu" + +#: ../gio/glib-compile-resources.c:259 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Nisam uspeo da pronaÄ‘em „%s“ u tekućem direktorijumu" + +#: ../gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Nepoznata opcija obrade „%s“" + +#: ../gio/glib-compile-resources.c:308 ../gio/glib-compile-resources.c:354 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "Nisam uspeo da napravim privremenu datoteku: %s" + +#: ../gio/glib-compile-resources.c:382 +#, c-format +msgid "Error reading file %s: %s" +msgstr "GreÅ¡ka pri Äitanju datoteke „%s“: %s" + +#: ../gio/glib-compile-resources.c:402 +#, c-format +msgid "Error compressing file %s" +msgstr "GreÅ¡ka pri sažimanju datoteke „%s“" + +#: ../gio/glib-compile-resources.c:469 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "tekst ne može da se pojavljuje unutar <%s>" + +#: ../gio/glib-compile-resources.c:664 ../gio/glib-compile-schemas.c:2067 +msgid "Show program version and exit" +msgstr "Prikazuje izdanje programa i izlazi" + +#: ../gio/glib-compile-resources.c:665 +msgid "name of the output file" +msgstr "naziv izlazne datoteke" + +#: ../gio/glib-compile-resources.c:666 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"Direktorijumi iz kojih će datoteke biti Äitane (osnovno je tekući " +"direktorijum)" + +#: ../gio/glib-compile-resources.c:666 ../gio/glib-compile-schemas.c:2068 +#: ../gio/glib-compile-schemas.c:2096 +msgid "DIRECTORY" +msgstr "DIREKTORIJUM" + +#: ../gio/glib-compile-resources.c:667 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Stvara izlaz u formatu izabranom proÅ¡irenjem naziva ciljne datoteke" + +#: ../gio/glib-compile-resources.c:668 +msgid "Generate source header" +msgstr "Stvara zaglavlje izvora" + +#: ../gio/glib-compile-resources.c:669 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "Stvara izvorni kod korišćen da poveže datoteku resursa u vaÅ¡ kod" + +#: ../gio/glib-compile-resources.c:670 +msgid "Generate dependency list" +msgstr "Stvara spisak zavisnosti" + +#: ../gio/glib-compile-resources.c:671 +msgid "name of the dependency file to generate" +msgstr "naziv datoteke zavisnosti za stvaranje" + +#: ../gio/glib-compile-resources.c:672 +msgid "Include phony targets in the generated dependency file" +msgstr "UkljuÄuje lažne mete u stvorenoj datoteci zavisnosti" + +#: ../gio/glib-compile-resources.c:673 +msgid "Don’t automatically create and register resource" +msgstr "Ne stvara samostalno i ne beleži izvor" + +#: ../gio/glib-compile-resources.c:674 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ne izvozi funkcije; objavljuje ih „G_GNUC_UNUTRAÅ NJIM“" + +#: ../gio/glib-compile-resources.c:675 +msgid "C identifier name used for the generated source code" +msgstr "Naziv C odrednika korišćenog za stvoreni izvorni kod" + +#: ../gio/glib-compile-resources.c:701 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Prevodi odrednicu resursa u datoteku resursa.\n" +"Datoteke odrednice resursa imaju proÅ¡irenje „.gresource.xml“,\n" +"a datoteke resursa imaju proÅ¡irenje „.gresource“." + +#: ../gio/glib-compile-resources.c:723 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "Treba da navedete taÄno jedan naziv datoteke\n" + +#: ../gio/glib-compile-schemas.c:95 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "nadimak mora biti najmanje 2 znaka" + +#: ../gio/glib-compile-schemas.c:106 +#, c-format +msgid "Invalid numeric value" +msgstr "Neispravna brojevna vrednost" + +#: ../gio/glib-compile-schemas.c:114 +#, c-format +msgid " already specified" +msgstr "„“ je već navedeno" + +#: ../gio/glib-compile-schemas.c:122 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' je već navedeno" + +#: ../gio/glib-compile-schemas.c:136 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "vrednosti zastavica moraju imati najviÅ¡e 1 podeÅ¡en bit" + +#: ../gio/glib-compile-schemas.c:161 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> mora sadržati barem jednu " + +#: ../gio/glib-compile-schemas.c:315 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> nije sadržano u navedenom opsegu" + +#: ../gio/glib-compile-schemas.c:327 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> nije ispravan Älan navedene nabrojane vrste" + +#: ../gio/glib-compile-schemas.c:333 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> sadržana niska nije u navedenoj vrsti zastavice" + +#: ../gio/glib-compile-schemas.c:339 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> sadržana niska nije u " + +#: ../gio/glib-compile-schemas.c:373 +msgid " already specified for this key" +msgstr " je već naveden za ovaj kljuÄ" + +#: ../gio/glib-compile-schemas.c:391 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nije dopuÅ¡ten za kljuÄeve vrste „%s“" + +#: ../gio/glib-compile-schemas.c:408 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " navedeni minimum je veći od maksimuma" + +#: ../gio/glib-compile-schemas.c:433 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "nepodržana „l10n“ kategorija: %s" + +#: ../gio/glib-compile-schemas.c:441 +msgid "l10n requested, but no gettext domain given" +msgstr "„l10n“ je zatraženo, ali nije dat domen getteksta" + +#: ../gio/glib-compile-schemas.c:453 +msgid "translation context given for value without l10n enabled" +msgstr "dat je kontekst prevoda za vrednost bez ukljuÄenog „l10n“" + +#: ../gio/glib-compile-schemas.c:475 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Nisam uspeo da obradim vrednost vrste „%s“: " + +#: ../gio/glib-compile-schemas.c:492 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" se ne može navesti za kljuÄeve oznaÄene da imaju nabrojanu vrstu" + +#: ../gio/glib-compile-schemas.c:501 +msgid " already specified for this key" +msgstr " je već naveden za ovaj kljuÄ" + +#: ../gio/glib-compile-schemas.c:513 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " nije dopuÅ¡ten za kljuÄeve vrste „%s“" + +#: ../gio/glib-compile-schemas.c:529 +#, c-format +msgid " already given" +msgstr " je već dato" + +#: ../gio/glib-compile-schemas.c:544 +#, c-format +msgid " must contain at least one " +msgstr " mora da sadrži barem jedan " + +#: ../gio/glib-compile-schemas.c:558 +msgid " already specified for this key" +msgstr " je već naveden za ovaj kljuÄ" + +#: ../gio/glib-compile-schemas.c:562 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" se može navesti jedino za kljuÄeve sa nabrojanim ili sa vrstama " +"zastavica ili nakon " + +#: ../gio/glib-compile-schemas.c:581 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr " je dato kada je „%s“ već Älan nabrojane vrste" + +#: ../gio/glib-compile-schemas.c:587 +#, c-format +msgid " given when was already given" +msgstr " je dato kada je već dato " + +#: ../gio/glib-compile-schemas.c:595 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "meta alijasa „%s“ nije u nabrojanoj vrsti" + +#: ../gio/glib-compile-schemas.c:606 +#, c-format +msgid "alias target “%s†is not in " +msgstr "meta alijasa „%s“ nije u " + +#: ../gio/glib-compile-schemas.c:621 +#, c-format +msgid " must contain at least one " +msgstr " mora da sadrži barem jedan " + +#: ../gio/glib-compile-schemas.c:786 +msgid "Empty names are not permitted" +msgstr "Prazni nazivi nisu dozvoljeni" + +#: ../gio/glib-compile-schemas.c:796 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Neispravan naziv „%s“: nazivi moraju da poÄinju malim slovom" + +#: ../gio/glib-compile-schemas.c:808 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Neispravan naziv „%s“: neispravan znak „%c“; samo mala slova, brojevi i " +"crtica („-“) su dozvoljeni" + +#: ../gio/glib-compile-schemas.c:817 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Neispravan naziv „%s“: dve uzastopne crtice („--“) nisu dozvoljene" + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Neispravan naziv „%s“: poslednji znak ne može da bude crtiica („-“)" + +#: ../gio/glib-compile-schemas.c:834 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Neispravan naziv „%s“: najveća dužina je 1024" + +#: ../gio/glib-compile-schemas.c:904 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:930 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Ne mogu da dodam kljuÄeve u Å¡emu „list-of“" + +#: ../gio/glib-compile-schemas.c:941 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:959 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" prekriva u ; koristite " +" da izmenite vrednost" + +#: ../gio/glib-compile-schemas.c:970 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"TaÄno jedna stvar od „type“, „enum“ ili „flags“ mora biti navedena kao " +"atribut za " + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> nije (joÅ¡) definisano." + +#: ../gio/glib-compile-schemas.c:1004 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Neispravna vrsta niske GVarijanta „%s“" + +#: ../gio/glib-compile-schemas.c:1034 +msgid " given but schema isn’t extending anything" +msgstr " je dato, ali Å¡ema ne proÅ¡iruje niÅ¡ta" + +#: ../gio/glib-compile-schemas.c:1047 +#, c-format +msgid "No to override" +msgstr "Nema za preklapanje" + +#: ../gio/glib-compile-schemas.c:1055 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:1128 +#, c-format +msgid " already specified" +msgstr " je već navedeno" + +#: ../gio/glib-compile-schemas.c:1140 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " proÅ¡iruje joÅ¡ uvek nepostojeću Å¡emu „%s“" + +#: ../gio/glib-compile-schemas.c:1156 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " je spisak joÅ¡ uvek nepostojeće Å¡eme „%s“" + +#: ../gio/glib-compile-schemas.c:1164 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Ne može biti spisak Å¡eme sa putanjom" + +#: ../gio/glib-compile-schemas.c:1174 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Ne mogu da proÅ¡irim Å¡emu sa putanjom" + +#: ../gio/glib-compile-schemas.c:1184 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" je spisak koji proÅ¡iruje koja nije spisak" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" proÅ¡iruje ali " +"„%s“ ne proÅ¡iruje „%s“" + +#: ../gio/glib-compile-schemas.c:1211 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "Putanja, ako se navodi mora da poÄinje i zavrÅ¡ava sa kosom crtom" + +#: ../gio/glib-compile-schemas.c:1218 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Putanja spiska mora da se zavrÅ¡ava sa „:/“" + +#: ../gio/glib-compile-schemas.c:1227 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Upozorenje: Å ema „%s“ ima putanju „%s“. Putanje koje poÄinju na „/apps/“, „/" +"desktop/“ ili „/system/“ su zastarele." + +#: ../gio/glib-compile-schemas.c:1257 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id=„%s“> je već navedeno" + +#: ../gio/glib-compile-schemas.c:1407 ../gio/glib-compile-schemas.c:1423 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Samo jedan <%s> element je dozvoljen unutar <%s>" + +#: ../gio/glib-compile-schemas.c:1505 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Element <%s> nije dozvoljen na najviÅ¡em nivou" + +#: ../gio/glib-compile-schemas.c:1523 +msgid "Element is required in " +msgstr "Element je zatražen u " + +#: ../gio/glib-compile-schemas.c:1613 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Tekst ne može da se pojavljuje unutar <%s>" + +#: ../gio/glib-compile-schemas.c:1681 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Upozorenje: neodreÄ‘ena uputa ka " + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1820 ../gio/glib-compile-schemas.c:1894 +#: ../gio/glib-compile-schemas.c:1970 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "„--strict“ je navedeno; izlazim.\n" + +#: ../gio/glib-compile-schemas.c:1830 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "ÄŒitava ova datoteka je zanemarena.\n" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Zanemarujem ovu datoteku.\n" + +#: ../gio/glib-compile-schemas.c:1930 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"Ne postoji kljuÄ â€ž%s“ u Å¡emi „%s“ kao Å¡to je navedeno u datoteci zamene „%s“" + +#: ../gio/glib-compile-schemas.c:1936 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2022 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; zanemarujem zamenu za ovaj kljuÄ.\n" + +#: ../gio/glib-compile-schemas.c:1940 ../gio/glib-compile-schemas.c:1998 +#: ../gio/glib-compile-schemas.c:2026 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " i „--strict“ je navedeno; izlazim.\n" + +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"greÅ¡ka u analizi kljuÄa „%s“ u Å¡emi „%s“ kao Å¡to je navedeno u datoteci " +"zamene „%s“: %s." + +#: ../gio/glib-compile-schemas.c:1966 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "Zanemarujem zamenu za ovaj kljuÄ.\n" + +#: ../gio/glib-compile-schemas.c:1984 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"preklapanje za kljuÄ â€ž%s“ u Å¡emi „%s“ u preklopljenoj datoteci „%s“ je izvan " +"opsega datog u Å¡emi" + +#: ../gio/glib-compile-schemas.c:2012 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"preklapanje za kljuÄ â€ž%s“ u Å¡emi „%s“ u preklopljenoj datoteci „%s“ nije u " +"spisku dozvoljenih izbora" + +#: ../gio/glib-compile-schemas.c:2068 +msgid "where to store the gschemas.compiled file" +msgstr "gde da skladiÅ¡tim „gschemas.compiled“ datoteku" + +#: ../gio/glib-compile-schemas.c:2069 +msgid "Abort on any errors in schemas" +msgstr "Prekini pri bilo kojoj greÅ¡ci u Å¡emama" + +#: ../gio/glib-compile-schemas.c:2070 +msgid "Do not write the gschema.compiled file" +msgstr "Ne upisuj „gschemas.compiled“ datoteku" + +#: ../gio/glib-compile-schemas.c:2071 +msgid "Do not enforce key name restrictions" +msgstr "Ne nameće ograniÄenja naziva kljuÄa" + +#: ../gio/glib-compile-schemas.c:2099 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Prevodi sve datoteke Å¡ema GPodeÅ¡avanja u keÅ¡ Å¡ema.\n" +"Datoteke Å¡ema moraju da se zavrÅ¡avaju sa „.gschema.xml“,\n" +"a datoteke keÅ¡a imaju naziv „gschemas.compiled“." + +#: ../gio/glib-compile-schemas.c:2120 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "Trebate navesti taÄno jedan naziv fascikle\n" + +#: ../gio/glib-compile-schemas.c:2162 +#, c-format +msgid "No schema files found: " +msgstr "Nijedna datoteka sa Å¡emama nije naÄ‘ena: " + +#: ../gio/glib-compile-schemas.c:2165 +#, c-format +msgid "doing nothing.\n" +msgstr "ne radim niÅ¡ta.\n" + +#: ../gio/glib-compile-schemas.c:2168 +#, c-format +msgid "removed existing output file.\n" +msgstr "uklonjena postojeća izlazna datoteka.\n" + +#: ../gio/glocalfile.c:643 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "Neispravan naziv datoteke %s" + +#: ../gio/glocalfile.c:1105 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "GreÅ¡ka dobavljanja podataka o sistemu datoteka za „%s“: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: ../gio/glocalfile.c:1244 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Nisam naÅ¡ao sadržano kaÄenje za datoteku „%s“" + +#: ../gio/glocalfile.c:1267 +msgid "Can’t rename root directory" +msgstr "Ne mogu da preimenujem koreni direktorijum" + +#: ../gio/glocalfile.c:1285 ../gio/glocalfile.c:1308 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "GreÅ¡ka preimenovanja datoteke „%s“: %s" + +#: ../gio/glocalfile.c:1292 +msgid "Can’t rename file, filename already exists" +msgstr "Ne mogu da preimenujem datoteku, naziv datoteke već postoji" + +#: ../gio/glocalfile.c:1305 ../gio/glocalfile.c:2322 ../gio/glocalfile.c:2350 +#: ../gio/glocalfile.c:2507 ../gio/glocalfileoutputstream.c:551 +msgid "Invalid filename" +msgstr "Neispravan naziv datoteke" + +#: ../gio/glocalfile.c:1473 ../gio/glocalfile.c:1488 +#, c-format +msgid "Error opening file %s: %s" +msgstr "GreÅ¡ka otvaranja datoteke „%s“: %s" + +#: ../gio/glocalfile.c:1613 +#, c-format +msgid "Error removing file %s: %s" +msgstr "GreÅ¡ka uklanjanja datoteke „%s“: %s" + +#: ../gio/glocalfile.c:1997 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "GreÅ¡ka premeÅ¡tanja datoteke „%s“ u smeće: %s" + +#: ../gio/glocalfile.c:2020 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Ne mogu da napravim direktorijum za smeće %s: %s" + +#: ../gio/glocalfile.c:2040 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Ne mogu da naÄ‘em koreni direktorijum da bacim u smeće „%s“" + +#: ../gio/glocalfile.c:2119 ../gio/glocalfile.c:2139 +#, c-format +msgid "Unable to find or create trash directory for %s" +msgstr "Ne mogu da naÄ‘em ili napravim direktorijum smeća za „%s“" + +#: ../gio/glocalfile.c:2174 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Ne mogu da napravim datoteku podataka smeća za „%s“: %s" + +#: ../gio/glocalfile.c:2233 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Ne mogu da bacim u smeće datoteku „%s“ preko granica sistema datoteka" + +#: ../gio/glocalfile.c:2237 ../gio/glocalfile.c:2293 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Ne mogu da bacim datoteku „%s“ u smeće: %s" + +#: ../gio/glocalfile.c:2299 +#, c-format +msgid "Unable to trash file %s" +msgstr "Ne mogu da bacim datoteku „%s“ u smeće" + +#: ../gio/glocalfile.c:2325 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "GreÅ¡ka stvaranja direktorijuma „%s“: %s" + +#: ../gio/glocalfile.c:2354 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Sistem datoteka ne podržava simboliÄke veze" + +#: ../gio/glocalfile.c:2357 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "GreÅ¡ka stvaranja simboliÄke veze „%s“: %s" + +#: ../gio/glocalfile.c:2363 ../glib/gfileutils.c:2127 +msgid "Symbolic links not supported" +msgstr "SimboliÄke veze nisu podržane" + +#: ../gio/glocalfile.c:2418 ../gio/glocalfile.c:2453 ../gio/glocalfile.c:2510 +#, c-format +msgid "Error moving file %s: %s" +msgstr "GreÅ¡ka premeÅ¡tanja datoteke „%s“: %s" + +#: ../gio/glocalfile.c:2441 +msgid "Can’t move directory over directory" +msgstr "Ne mogu da premestim direktorijum preko direktorijuma" + +#: ../gio/glocalfile.c:2467 ../gio/glocalfileoutputstream.c:935 +#: ../gio/glocalfileoutputstream.c:949 ../gio/glocalfileoutputstream.c:964 +#: ../gio/glocalfileoutputstream.c:981 ../gio/glocalfileoutputstream.c:995 +msgid "Backup file creation failed" +msgstr "Nije uspela izrada rezervne datoteke" + +#: ../gio/glocalfile.c:2486 +#, c-format +msgid "Error removing target file: %s" +msgstr "GreÅ¡ka uklanjanja ciljne datoteke: %s" + +#: ../gio/glocalfile.c:2500 +msgid "Move between mounts not supported" +msgstr "Nije podržano premeÅ¡tanje izmeÄ‘u montiranih ureÄ‘aja" + +#: ../gio/glocalfile.c:2691 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ne mogu da odredim iskorišćenost diska za „%s“: %s" + +#: ../gio/glocalfileinfo.c:745 +msgid "Attribute value must be non-NULL" +msgstr "Vrednost osobine mora biti razliÄita od NULL" + +#: ../gio/glocalfileinfo.c:752 +msgid "Invalid attribute type (string expected)" +msgstr "Nije ispravna vrsta atributa (oÄekivana je niska znakova)" + +#: ../gio/glocalfileinfo.c:759 +msgid "Invalid extended attribute name" +msgstr "Nije ispravan naziv proÅ¡irene osobine" + +#: ../gio/glocalfileinfo.c:799 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "GreÅ¡ka prilikom postavljanja proÅ¡irene osobine „%s“: %s" + +#: ../gio/glocalfileinfo.c:1607 +msgid " (invalid encoding)" +msgstr " (neispravno kodiranje)" + +#: ../gio/glocalfileinfo.c:1776 ../gio/glocalfileoutputstream.c:813 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "GreÅ¡ka prilikom dobavljanja podataka za datoteku „%s“: %s" + +#: ../gio/glocalfileinfo.c:2038 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "GreÅ¡ka prilikom dobavljanja podataka za opisnika datoteke: %s" + +#: ../gio/glocalfileinfo.c:2083 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Nije ispravna vrsta osobine („uint32“ je oÄekivano)" + +#: ../gio/glocalfileinfo.c:2101 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Nije ispravna vrsta osobine („uint64“ je oÄekivano)" + +#: ../gio/glocalfileinfo.c:2120 ../gio/glocalfileinfo.c:2139 +msgid "Invalid attribute type (byte string expected)" +msgstr "Nije ispravna vrsta osobine (oÄekivana je niska bitova)" + +#: ../gio/glocalfileinfo.c:2184 +msgid "Cannot set permissions on symlinks" +msgstr "Ne mogu da postavim ovlašćenja za simboliÄke veze" + +#: ../gio/glocalfileinfo.c:2200 +#, c-format +msgid "Error setting permissions: %s" +msgstr "GreÅ¡ka prilikom postavljanja ovlašćenja: %s" + +#: ../gio/glocalfileinfo.c:2251 +#, c-format +msgid "Error setting owner: %s" +msgstr "GreÅ¡ka prilikom postavljanja vlasnika: %s" + +#: ../gio/glocalfileinfo.c:2274 +msgid "symlink must be non-NULL" +msgstr "simboliÄke veze moraju biti razliÄite od NULL" + +#: ../gio/glocalfileinfo.c:2284 ../gio/glocalfileinfo.c:2303 +#: ../gio/glocalfileinfo.c:2314 +#, c-format +msgid "Error setting symlink: %s" +msgstr "GreÅ¡ka prilikom postavljanja simboliÄke veze: %s" + +#: ../gio/glocalfileinfo.c:2293 +msgid "Error setting symlink: file is not a symlink" +msgstr "GreÅ¡ka pri postavljanju simboliÄke veze: datoteka nije simboliÄka veza" + +#: ../gio/glocalfileinfo.c:2419 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "GreÅ¡ka pri postavljanju datuma izmene ili pristupa: %s" + +#: ../gio/glocalfileinfo.c:2442 +msgid "SELinux context must be non-NULL" +msgstr "SELinuks kontekst ne sme biti NULL" + +#: ../gio/glocalfileinfo.c:2457 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "GreÅ¡ka prilikom postavljanja SELinuks konteksta: %s" + +#: ../gio/glocalfileinfo.c:2464 +msgid "SELinux is not enabled on this system" +msgstr "SELinuks nije ukljuÄen na vaÅ¡em sistemu" + +#: ../gio/glocalfileinfo.c:2556 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Nije podržano postavljanje osobine %s" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:696 +#, c-format +msgid "Error reading from file: %s" +msgstr "GreÅ¡ka prilikom Äitanja datoteke: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:458 ../gio/glocalfileoutputstream.c:1013 +#, c-format +msgid "Error seeking in file: %s" +msgstr "GreÅ¡ka prilikom pretrage unutar datoteke: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:248 +#: ../gio/glocalfileoutputstream.c:342 +#, c-format +msgid "Error closing file: %s" +msgstr "GreÅ¡ka prilikom zatvaranja datoteke: %s" + +#: ../gio/glocalfilemonitor.c:840 +msgid "Unable to find default local file monitor type" +msgstr "Ne mogu da pronaÄ‘em podrazumevanu, lokalnu vrstu monitora datoteke" + +#: ../gio/glocalfileoutputstream.c:196 ../gio/glocalfileoutputstream.c:228 +#: ../gio/glocalfileoutputstream.c:717 +#, c-format +msgid "Error writing to file: %s" +msgstr "GreÅ¡ka prilikom upisa u datoteku: %s" + +#: ../gio/glocalfileoutputstream.c:275 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "GreÅ¡ka prilikom uklanjanja stare rezervne kopije veze: %s" + +#: ../gio/glocalfileoutputstream.c:289 ../gio/glocalfileoutputstream.c:302 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "GreÅ¡ka prilikom obrazovanja rezervne kopije: %s" + +#: ../gio/glocalfileoutputstream.c:320 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "GreÅ¡ka prilikom preimenovanja privremene datoteke: %s" + +#: ../gio/glocalfileoutputstream.c:504 ../gio/glocalfileoutputstream.c:1064 +#, c-format +msgid "Error truncating file: %s" +msgstr "GreÅ¡ka pri sasecanju datoteke: %s" + +#: ../gio/glocalfileoutputstream.c:557 ../gio/glocalfileoutputstream.c:795 +#: ../gio/glocalfileoutputstream.c:1045 ../gio/gsubprocess.c:380 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "GreÅ¡ka otvaranja datoteke „%s“: %s" + +#: ../gio/glocalfileoutputstream.c:826 +msgid "Target file is a directory" +msgstr "Ciljna datoteka je direktorijum" + +#: ../gio/glocalfileoutputstream.c:831 +msgid "Target file is not a regular file" +msgstr "Ciljna datoteka nije obiÄna datoteka" + +#: ../gio/glocalfileoutputstream.c:843 +msgid "The file was externally modified" +msgstr "Datoteka je izmenjena spoljnim programom" + +#: ../gio/glocalfileoutputstream.c:1029 +#, c-format +msgid "Error removing old file: %s" +msgstr "GreÅ¡ka prilikom uklanjanja stare datoteke: %s" + +#: ../gio/gmemoryinputstream.c:474 ../gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "Nije ispravno odreÄ‘ena vrsta GPretrage" + +#: ../gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Neispravan zahtev pretrage" + +#: ../gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ne mogu da skratim ulazni tok GMemorije" + +#: ../gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "VeliÄina izlazne memorije se ne može promeniti" + +#: ../gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Nisam uspeoda promenim veliÄinu izlaznog memorijskog toka" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "Ima viÅ¡e memorije za upis nego Å¡to ima mesta u datoj adresi" + +#: ../gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "Zahtevano je premotavanje na deo pre poÄetka toka" + +#: ../gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "Zahtevano je premotavanje na deo nakon zavrÅ¡etka toka" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:396 +msgid "mount doesn’t implement “unmountâ€" +msgstr "montiranje ne podržava „unmount“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:472 +msgid "mount doesn’t implement “ejectâ€" +msgstr "montiranje ne podržava „eject“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:550 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "montiranje ne podržava „unmount“ ili „unmount_with_operation“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:635 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "montiranje ne podržava „eject“ ili „eject_with_operation“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:723 +msgid "mount doesn’t implement “remountâ€" +msgstr "montiranje ne podržava „remount“" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:805 +msgid "mount doesn’t implement content type guessing" +msgstr "montiranje ne podržava nalaženje vrste sadržaja" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:892 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "montiranje ne podržava usklaÄ‘eno nalaženje vrste sadržaja" + +#: ../gio/gnetworkaddress.c:378 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Ime domaćina „%s“ sadrži „[“, ali ne i „]“" + +#: ../gio/gnetworkmonitorbase.c:206 ../gio/gnetworkmonitorbase.c:310 +msgid "Network unreachable" +msgstr "Mreža je nedostižna" + +#: ../gio/gnetworkmonitorbase.c:244 ../gio/gnetworkmonitorbase.c:274 +msgid "Host unreachable" +msgstr "Domaćin je nedostižan" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ne mogu da napravim praćenje mreže: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "Ne mogu da napravim praćenje mreže: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "Ne mogu da dobavim stanje mreže: " + +#: ../gio/gnetworkmonitornm.c:329 +#, c-format +msgid "NetworkManager version too old" +msgstr "Izdanje upravnika mreže je previÅ¡e staro" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:560 +msgid "Output stream doesn’t implement write" +msgstr "Izlazni tok ne podržava upis" + +#: ../gio/goutputstream.c:521 ../gio/goutputstream.c:1224 +msgid "Source stream is already closed" +msgstr "Izvorni tok je već zatvoren" + +#: ../gio/gresolver.c:342 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "GreÅ¡ka u razreÅ¡avanju „%s“: %s" + +#: ../gio/gresolver.c:729 ../gio/gresolver.c:781 +msgid "Invalid domain" +msgstr "Neispravan domen" + +#: ../gio/gresource.c:621 ../gio/gresource.c:880 ../gio/gresource.c:919 +#: ../gio/gresource.c:1043 ../gio/gresource.c:1115 ../gio/gresource.c:1188 +#: ../gio/gresource.c:1258 ../gio/gresourcefile.c:476 +#: ../gio/gresourcefile.c:599 ../gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Resurs „%s“ ne postoji" + +#: ../gio/gresource.c:786 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Resurs na „%s“ nije uspeo da se raspakuje" + +#: ../gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Resurs na „%s“ nije direktorijum" + +#: ../gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Ulazni tok ne podržava premotavanje" + +#: ../gio/gresource-tool.c:494 +msgid "List sections containing resources in an elf FILE" +msgstr "Navodi odeljke koji sadrže resurse u elf DATOTECI" + +#: ../gio/gresource-tool.c:500 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Navodi resurse\n" +"Ako je dato ODELJAK, navodi samo resurse u tom odeljku\n" +"Ako je dato PUTANJA, navodi samo odgovarajuće resurse" + +#: ../gio/gresource-tool.c:503 ../gio/gresource-tool.c:513 +msgid "FILE [PATH]" +msgstr "DATOTEKA [PUTANJA]" + +#: ../gio/gresource-tool.c:504 ../gio/gresource-tool.c:514 +#: ../gio/gresource-tool.c:521 +msgid "SECTION" +msgstr "ODELJAK" + +#: ../gio/gresource-tool.c:509 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Navodi resurse sa pojedinostima\n" +"Ako je dato ODELJAK, navodi samo resurse u tom odeljku\n" +"Ako je dato PUTANJA, navodi samo odgovarajuće resurse\n" +"U pojedinosti spadaju odeljak, veliÄina i sažimanje" + +#: ../gio/gresource-tool.c:519 +msgid "Extract a resource file to stdout" +msgstr "IzvlaÄi datoteku resursa u standardni izlaz" + +#: ../gio/gresource-tool.c:520 +msgid "FILE PATH" +msgstr "PUTANJA DATOTEKE" + +#: ../gio/gresource-tool.c:534 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Upotreba:\n" +" gresource [--section ODELJAK] NAREDBA [ARGUMENTI…]\n" +"\n" +"Naredbe:\n" +" help Prikazuje ovo obaveÅ¡tenje\n" +" sections Ispisuje odeljke resursa\n" +" list Ispisuje resurse\n" +" details Ispisuje resurse sa pojedinostima\n" +" extract IzvlaÄi resurs\n" +"\n" +"Koristite „gresource help NAREDBA“ da prikažete opÅ¡irniju pomoć.\n" +"\n" + +#: ../gio/gresource-tool.c:548 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Korišćenje:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:555 +msgid " SECTION An (optional) elf section name\n" +msgstr " ODELJAK Naziv (opcionalno) elf odeljka\n" + +#: ../gio/gresource-tool.c:559 ../gio/gsettings-tool.c:703 +msgid " COMMAND The (optional) command to explain\n" +msgstr " NAREDBA Naredba (opcionalno) za objaÅ¡njavanje\n" + +#: ../gio/gresource-tool.c:565 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " DATOTEKA Elf datoteka (izvrÅ¡na ili deljena biblioteka)\n" + +#: ../gio/gresource-tool.c:568 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" DATOTEKA Elf datoteka (izvrÅ¡na ili deljena biblioteka)\n" +" ili prevedena datoteka resursa\n" + +#: ../gio/gresource-tool.c:572 +msgid "[PATH]" +msgstr "[PUTANJA]" + +#: ../gio/gresource-tool.c:574 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PUTANJA Putanja (opcionalno) resursa (može biti delimiÄna)\n" + +#: ../gio/gresource-tool.c:575 +msgid "PATH" +msgstr "PUTANJA" + +#: ../gio/gresource-tool.c:577 +msgid " PATH A resource path\n" +msgstr " PUTANJA Putanja resursa\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#: ../gio/gsettings-tool.c:908 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Nema takve Å¡eme „%s“\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Å ema „%s“ nije premestljiva (putanja ne sme biti navedena)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Å ema „%s“ je premestljiva (putanja mora biti navedena)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "Data je prazna putanja.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "Putanja mora poÄeti kosom crtom (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "Putanja mora da se zavrÅ¡i kosom crtom (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Putanja ne sme da sadrži dve susedne kose crte (//)\n" + +#: ../gio/gsettings-tool.c:538 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "ObezbeÄ‘ena vrednost je izvan važećeg opsega\n" + +#: ../gio/gsettings-tool.c:545 +#, c-format +msgid "The key is not writable\n" +msgstr "U ovaj kljuÄ se ne može upisivati\n" + +#: ../gio/gsettings-tool.c:581 +msgid "List the installed (non-relocatable) schemas" +msgstr "Navodi instalirane (nepremestljive) Å¡eme" + +#: ../gio/gsettings-tool.c:587 +msgid "List the installed relocatable schemas" +msgstr "Navodi instalirane premestljive Å¡eme" + +#: ../gio/gsettings-tool.c:593 +msgid "List the keys in SCHEMA" +msgstr "Navodi kljuÄeve u Å EMI" + +#: ../gio/gsettings-tool.c:594 ../gio/gsettings-tool.c:600 +#: ../gio/gsettings-tool.c:643 +msgid "SCHEMA[:PATH]" +msgstr "Å EMA [:PUTANJA]" + +#: ../gio/gsettings-tool.c:599 +msgid "List the children of SCHEMA" +msgstr "Navodi proistekle iz Å EME" + +#: ../gio/gsettings-tool.c:605 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Navodi kljuÄeve i vrednosti, rekurzivno\n" +"Ako SHEMA nije data, navodi sve kljuÄeve\n" + +#: ../gio/gsettings-tool.c:607 +msgid "[SCHEMA[:PATH]]" +msgstr "[Å EMA[:PUTANJA]]" + +#: ../gio/gsettings-tool.c:612 +msgid "Get the value of KEY" +msgstr "Dobavlja vrednost kljuÄa" + +#: ../gio/gsettings-tool.c:613 ../gio/gsettings-tool.c:619 +#: ../gio/gsettings-tool.c:625 ../gio/gsettings-tool.c:637 +#: ../gio/gsettings-tool.c:649 +msgid "SCHEMA[:PATH] KEY" +msgstr "Å EMA [:PUTANJA] KLJUÄŒ" + +#: ../gio/gsettings-tool.c:618 +msgid "Query the range of valid values for KEY" +msgstr "Propituje opseg važećih vrednosti za KLJUÄŒ" + +#: ../gio/gsettings-tool.c:624 +msgid "Query the description for KEY" +msgstr "Propituje opis za KLJUÄŒ" + +#: ../gio/gsettings-tool.c:630 +msgid "Set the value of KEY to VALUE" +msgstr "Postavlja vrednost KLJUÄŒA na VREDNOST" + +#: ../gio/gsettings-tool.c:631 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "Å EMA [:PUTANJA] KLJUÄŒ VREDNOST" + +#: ../gio/gsettings-tool.c:636 +msgid "Reset KEY to its default value" +msgstr "Ponovo postavlja KLJUÄŒ na podrazumevanu vrednost" + +#: ../gio/gsettings-tool.c:642 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Vraća sve kljuÄeve u SHEMI na osnovne vrednosti" + +#: ../gio/gsettings-tool.c:648 +msgid "Check if KEY is writable" +msgstr "Proverava da li je KLJUÄŒ upisiv" + +#: ../gio/gsettings-tool.c:654 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Prati KLJUÄŒ za izmenama.\n" +"Ako nije naveden nijedan KLJUÄŒ, prati sve kljuÄeve u Å EMI.\n" +"Koristite „^C“ da zaustavite praćenje.\n" + +#: ../gio/gsettings-tool.c:657 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "Å EMA [:PUTANJA] [KLJUÄŒ]" + +#: ../gio/gsettings-tool.c:669 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Korišćenje:\n" +" gsettings --version\n" +" gsettings [--schemadir Å EMADIR] NAREDBA [ARGUMENTI…]\n" +"\n" +"Naredba:\n" +" help Prikazuje ovu informaciju\n" +" list-schemas Navodi instalirane Å¡eme\n" +" list-relocatable-schemas Navodi premestljive Å¡eme\n" +" list-keys Navodi kljuÄeve u Å¡emi\n" +" list-children Navodi proistekle iz Å¡eme\n" +" list-recursively Navodi kljuÄeve i vrednosti, dubinski\n" +" range Propituje opseg kljuÄa\n" +" describe Propituje opis kljuÄa\n" +" get Nabavlja vrednost kljuÄa\n" +" set PodeÅ¡ava vrednost kljuÄa\n" +" reset Ponovo podeÅ¡ava vrednost kljuÄa\n" +" reset-recursively Vraća sve vrednosti u datoj Å¡emi\n" +" writable Proverava da li je kljuÄ upisiv\n" +" monitor Nadgleda izmene\n" +"\n" +"Koristite „gsettings help NAREDBA“ da dobijete detaljniju pomoć.\n" +"\n" + +#: ../gio/gsettings-tool.c:693 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Korišćenje:\n" +" gsettings [--schemadir Å EMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:699 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " Å EMADIR Direktorijum za traženje dodatnih Å¡ema\n" + +#: ../gio/gsettings-tool.c:707 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" Å EMA Ime Å¡eme\n" +" PUTANJA Putanja, za premestive Å¡eme\n" + +#: ../gio/gsettings-tool.c:712 +msgid " KEY The (optional) key within the schema\n" +msgstr " KLJUÄŒ (izborni) kljuÄ unutar Å¡eme\n" + +#: ../gio/gsettings-tool.c:716 +msgid " KEY The key within the schema\n" +msgstr " KLJUÄŒ KljuÄ unutar Å¡eme\n" + +#: ../gio/gsettings-tool.c:720 +msgid " VALUE The value to set\n" +msgstr " VREDNOST Vrednost za podeÅ¡avanje\n" + +#: ../gio/gsettings-tool.c:775 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Ne mogu da uÄitam Å¡eme iz „%s“: %s\n" + +#: ../gio/gsettings-tool.c:787 +#, c-format +msgid "No schemas installed\n" +msgstr "Nijedna Å¡ema nije instalirana\n" + +#: ../gio/gsettings-tool.c:866 +#, c-format +msgid "Empty schema name given\n" +msgstr "Dat je prazan naziv Å¡eme\n" + +#: ../gio/gsettings-tool.c:921 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Nema takvog kljuÄa „%s“\n" + +#: ../gio/gsocket.c:384 +msgid "Invalid socket, not initialized" +msgstr "Neispravna utiÄnica, nije pokrenuto" + +#: ../gio/gsocket.c:391 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Neispravna utiÄnica, pokretanje nije uspelo zbog: %s" + +#: ../gio/gsocket.c:399 +msgid "Socket is already closed" +msgstr "UtiÄnica je već zatvorena" + +#: ../gio/gsocket.c:414 ../gio/gsocket.c:3010 ../gio/gsocket.c:4220 +#: ../gio/gsocket.c:4278 +msgid "Socket I/O timed out" +msgstr "Isteklo vreme za U/I utiÄnice" + +#: ../gio/gsocket.c:549 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "pravim GUtiÄnicu iz fd-a: %s" + +#: ../gio/gsocket.c:578 ../gio/gsocket.c:632 ../gio/gsocket.c:639 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ne mogu da napravim utiÄnicu: %s" + +#: ../gio/gsocket.c:632 +msgid "Unknown family was specified" +msgstr "Zadata je nepoznata porodica" + +#: ../gio/gsocket.c:639 +msgid "Unknown protocol was specified" +msgstr "Zadat je nepoznati protokol" + +#: ../gio/gsocket.c:1130 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Ne mogu da koristim datagram radnje nad nedatagramskom utiÄnicom." + +#: ../gio/gsocket.c:1147 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Ne mogu da koristim datagramske radnje nad utiÄnicom sa podeÅ¡enim isticanjem " +"vremena." + +#: ../gio/gsocket.c:1954 +#, c-format +msgid "could not get local address: %s" +msgstr "ne mogu da dobijem lokalnu adresu: %s" + +#: ../gio/gsocket.c:2000 +#, c-format +msgid "could not get remote address: %s" +msgstr "ne mogu da dobijem udaljenu adresu: %s" + +#: ../gio/gsocket.c:2066 +#, c-format +msgid "could not listen: %s" +msgstr "ne mogu da sluÅ¡am: %s" + +#: ../gio/gsocket.c:2168 +#, c-format +msgid "Error binding to address: %s" +msgstr "greÅ¡ka pri povezivanju na adresu: %s" + +#: ../gio/gsocket.c:2226 ../gio/gsocket.c:2263 ../gio/gsocket.c:2373 +#: ../gio/gsocket.c:2391 ../gio/gsocket.c:2461 ../gio/gsocket.c:2519 +#: ../gio/gsocket.c:2537 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "GreÅ¡ka prilikom pristupanja grupi viÅ¡estrukog emitovanja: %s" + +#: ../gio/gsocket.c:2227 ../gio/gsocket.c:2264 ../gio/gsocket.c:2374 +#: ../gio/gsocket.c:2392 ../gio/gsocket.c:2462 ../gio/gsocket.c:2520 +#: ../gio/gsocket.c:2538 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "GreÅ¡ka prilikom napuÅ¡tanja grupe viÅ¡estrukog emitovanja: %s" + +#: ../gio/gsocket.c:2228 +msgid "No support for source-specific multicast" +msgstr "Nema podrÅ¡ke za posebno viÅ¡estruko emitovanje izvora" + +#: ../gio/gsocket.c:2375 +msgid "Unsupported socket family" +msgstr "Nije podržana porodica utiÄnice" + +#: ../gio/gsocket.c:2393 +msgid "source-specific not an IPv4 address" +msgstr "posebni izvor nije IPv4 adresa" + +#: ../gio/gsocket.c:2411 ../gio/gsocket.c:2440 ../gio/gsocket.c:2487 +#, c-format +msgid "Interface not found: %s" +msgstr "Interfejs nije naÄ‘en: %s" + +#: ../gio/gsocket.c:2427 +#, c-format +msgid "Interface name too long" +msgstr "Naziv interfejsa je predugaÄak" + +#: ../gio/gsocket.c:2463 +msgid "No support for IPv4 source-specific multicast" +msgstr "Nema podrÅ¡ke za posebno viÅ¡estruko emitovanje IPv4 izvora" + +#: ../gio/gsocket.c:2521 +msgid "No support for IPv6 source-specific multicast" +msgstr "Nema podrÅ¡ke za posebno viÅ¡estruko emitovanje IPv6 izvora" + +#: ../gio/gsocket.c:2730 +#, c-format +msgid "Error accepting connection: %s" +msgstr "greÅ¡ka u prihvatanju veze: %s" + +#: ../gio/gsocket.c:2854 +msgid "Connection in progress" +msgstr "Povezivanje je u toku" + +#: ../gio/gsocket.c:2903 +msgid "Unable to get pending error: " +msgstr "Ne mogu da dobijem greÅ¡ku na Äekanju: " + +#: ../gio/gsocket.c:3073 +#, c-format +msgid "Error receiving data: %s" +msgstr "GreÅ¡ka u primanju podataka: %s" + +#: ../gio/gsocket.c:3268 +#, c-format +msgid "Error sending data: %s" +msgstr "GreÅ¡ka u slanju podataka: %s" + +#: ../gio/gsocket.c:3455 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ne mogu da ugasim utiÄnicu: %s" + +#: ../gio/gsocket.c:3536 +#, c-format +msgid "Error closing socket: %s" +msgstr "GreÅ¡ka u zatvaranju utiÄnice: %s" + +#: ../gio/gsocket.c:4213 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ÄŒekam uslov utiÄnice: %s" + +#: ../gio/gsocket.c:4687 ../gio/gsocket.c:4767 ../gio/gsocket.c:4945 +#, c-format +msgid "Error sending message: %s" +msgstr "GreÅ¡ka pri slanju poruke: %s" + +#: ../gio/gsocket.c:4711 +msgid "GSocketControlMessage not supported on Windows" +msgstr "Poruka upravljanja GutiÄnicom nije podržana na Vindouzu" + +#: ../gio/gsocket.c:5164 ../gio/gsocket.c:5237 ../gio/gsocket.c:5463 +#, c-format +msgid "Error receiving message: %s" +msgstr "GreÅ¡ka pri primanju poruke: %s" + +#: ../gio/gsocket.c:5735 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Ne mogu da proÄitam uverenja utiÄnice: %s" + +#: ../gio/gsocket.c:5744 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_utiÄnica_dobavlja_uverenja nije primenjena za ovaj operativni sistem" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ne mogu da se povežem na server posrednika „%s“: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ne mogu da se povežem na „%s“: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "Ne mogu da se povežem: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "Nepoznata greÅ¡ka veze" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Posredovanje preko veze koja nije TCP nije podržano." + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Protokol posrednika „%s“ nije podržan." + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "SluÅ¡anje je već zatvoreno" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "Dodata utiÄnica je zatvorena" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 ne podržava IPv6 adresu „%s“" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "KorisniÄko ime je predugo za SOCKSv4 protokol" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Ime domaćina „%s“ je predugo za SOCKSv4 protokol" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Server nije SOCKSv4 server posrednik." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Veza kroz SOCKSv4 server je odbijena" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Server nije SOCKSv5 posredniÄki server." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 posrednik zahteva potvrÄ‘ivanje identiteta." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "Ovaj SOCKSv5 zahteva naÄin prijavljivanja koji GBibl ne podržava." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "KorisniÄko ime ili lozinka su predugi za SOCKSv5 protokol." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5 prijavljivanje nije uspelo jer su korisniÄko ime ili lozinka pogreÅ¡ni." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Ime domaćina „%s“ je predugo za SOCKSv5 protokol" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Ovaj SOCKSv5 server posrednik koristi nepoznati tip adrese." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "UnutraÅ¡nja greÅ¡ka SOCKSv5 servera posrednika." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 veza nije dozvoljena od strane skupa pravila." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Domaćin nedostupan kroz SOCKSv5 server." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Mreža nedostupna kroz SOCKSv5 server." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Veza odbijena kroz SOCKSv5 posrednika." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 posrednik ne podržava naredbu „connect“." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 posrednik ne podržava dati tip adrese." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Nepoznata greÅ¡ka SOCKSv5 posrednika." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Ne mogu da radim sa izdanjem kodiranja %d ikonice GTemiranja" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "Nisam pronaÅ¡ao ispravne adrese" + +#: ../gio/gthreadedresolver.c:213 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "GreÅ¡ka u obrnutom razreÅ¡avanju „%s“: %s" + +#: ../gio/gthreadedresolver.c:549 ../gio/gthreadedresolver.c:628 +#: ../gio/gthreadedresolver.c:726 ../gio/gthreadedresolver.c:776 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Nema DNS zapisa zatražene vrste za „%s“" + +#: ../gio/gthreadedresolver.c:554 ../gio/gthreadedresolver.c:731 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Privremeno ne mogu da razreÅ¡im „%s“" + +#: ../gio/gthreadedresolver.c:559 ../gio/gthreadedresolver.c:736 +#: ../gio/gthreadedresolver.c:842 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "GreÅ¡ka u razreÅ¡ivanju „%s“" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ne mogu da deÅ¡ifrujem PEM Å¡ifrovani privatni kljuÄ" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "Nisam pronaÅ¡ao PEM Å¡ifrovani privatni kljuÄ" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "Ne mogu da raÅ¡Älanim PEM Å¡ifrovani privatni kljuÄ" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "Nisam pronaÅ¡ao PEM Å¡ifrovano uverenje" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ne mogu da raÅ¡Älanim PEM Å¡ifrovano uverenje" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Ovo je poslednja prilika da ispravno unesete lozinku pre nego Å¡to vaÅ¡ pristup " +"bude zakljuÄan." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: ../gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Nekoliko uneÅ¡enih lozinki je bilo neispravno, i zato će vaÅ¡ pristup biti " +"zakljuÄan nakon budućih neuspeha." + +#: ../gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "UneÅ¡ena lozinka je pogreÅ¡na." + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:563 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "OÄekujem jednu kontrolnu poruku, dobio sam %d" +msgstr[1] "OÄekujem jednu kontrolnu poruku, dobio sam %d" +msgstr[2] "OÄekujem jednu kontrolnu poruku, dobio sam %d" +msgstr[3] "OÄekujem jednu kontrolnu poruku, dobio sam %d" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:575 +msgid "Unexpected type of ancillary data" +msgstr "NeoÄekivana vrsta podreÄ‘enih podataka" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "OÄekujem jedan opisnik datoteke, ali dobih %d\n" +msgstr[1] "OÄekujem jedan opisnik datoteke, ali dobih %d\n" +msgstr[2] "OÄekujem jedan opisnik datoteke, ali dobih %d\n" +msgstr[3] "OÄekujem jedan opisnik datoteke, ali dobih %d\n" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Primljen je neispravni fd" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "GreÅ¡ka u slanju akreditiva: " + +#: ../gio/gunixconnection.c:504 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "GreÅ¡ka prilikom provere da li je SO_PASSCRED omogućen za utiÄnicu: %s" + +#: ../gio/gunixconnection.c:520 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "GreÅ¡ka prilikom omogućavanja SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:549 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"OÄekivano da se proÄita jedan bajt za dobijanje akreditiva, ali je proÄitano " +"nula bajtova" + +#: ../gio/gunixconnection.c:589 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Ne oÄekivah kontrolnu poruku, ali dobih %d" + +#: ../gio/gunixconnection.c:614 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "GreÅ¡ka prilikom onemogućavanja SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:372 ../gio/gunixinputstream.c:393 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "GreÅ¡ka prilikom Äitanja iz opisivaÄa datoteke: %s" + +#: ../gio/gunixinputstream.c:426 ../gio/gunixoutputstream.c:411 +#: ../gio/gwin32inputstream.c:217 ../gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "GreÅ¡ka prilikom zatvaranja opisnika datoteke: %s" + +#: ../gio/gunixmounts.c:2556 ../gio/gunixmounts.c:2609 +msgid "Filesystem root" +msgstr "Koreni sistem datoteka" + +#: ../gio/gunixoutputstream.c:358 ../gio/gunixoutputstream.c:378 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "GreÅ¡ka prilikom pisanja u opisivaÄ datoteke: %s" + +#: ../gio/gunixsocketaddress.c:241 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Apstraktna JUNIKS utiÄnica adresa domena nije podržana na ovom sistemu" + +#: ../gio/gvolume.c:437 +msgid "volume doesn’t implement eject" +msgstr "disk ne podržava izbacivanje" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "disk ne podržava „izbaci“ ili „izbaci_sa_radnjom“" + +#: ../gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "GreÅ¡ka prilikom Äitanja ruÄke: %s" + +#: ../gio/gwin32inputstream.c:232 ../gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "GreÅ¡ka prilikom zatvaranja ruÄke: %s" + +#: ../gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "GreÅ¡ka prilikom upisa u ruÄku: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Nema dovoljno memorije" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "UnutraÅ¡nja greÅ¡ka: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Potreban je veći unos" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Podaci nisu ispravno zapakovani" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adresa na kojoj vrÅ¡iti osluÅ¡kivanje" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Zanemareno, zbog saglasnosti sa GTestDmagistralom" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Ispisuje adresu" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Ispisuje adresu u režimu Å¡koljke" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Pokreće uslugu d-magistrale" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "PogreÅ¡ni argumenti\n" + +#: ../glib/gbookmarkfile.c:754 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "NeoÄekivano svojstvo „%s“ elementa „%s“" + +#: ../glib/gbookmarkfile.c:765 ../glib/gbookmarkfile.c:836 +#: ../glib/gbookmarkfile.c:846 ../glib/gbookmarkfile.c:953 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Svojstvo „%s“ elementa „%s“ nije pronaÄ‘eno" + +#: ../glib/gbookmarkfile.c:1123 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1252 ../glib/gbookmarkfile.c:1262 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "NeoÄekivana oznaka „%s“, oÄekivana je „%s“" + +#: ../glib/gbookmarkfile.c:1148 ../glib/gbookmarkfile.c:1162 +#: ../glib/gbookmarkfile.c:1230 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "NeoÄekivana oznaka „%s“ unutar „%s“" + +#: ../glib/gbookmarkfile.c:1757 +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Ne mogu da naÄ‘em ispravnu datoteku sa obeleživaÄima meÄ‘u fasciklama sa " +"podacima" + +#: ../glib/gbookmarkfile.c:1958 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "ObeleživaÄ za putanju „%s“ već postoji" + +#: ../glib/gbookmarkfile.c:2004 ../glib/gbookmarkfile.c:2162 +#: ../glib/gbookmarkfile.c:2247 ../glib/gbookmarkfile.c:2327 +#: ../glib/gbookmarkfile.c:2412 ../glib/gbookmarkfile.c:2495 +#: ../glib/gbookmarkfile.c:2573 ../glib/gbookmarkfile.c:2652 +#: ../glib/gbookmarkfile.c:2694 ../glib/gbookmarkfile.c:2791 +#: ../glib/gbookmarkfile.c:2912 ../glib/gbookmarkfile.c:3102 +#: ../glib/gbookmarkfile.c:3178 ../glib/gbookmarkfile.c:3346 +#: ../glib/gbookmarkfile.c:3435 ../glib/gbookmarkfile.c:3524 +#: ../glib/gbookmarkfile.c:3640 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Nije pronaÄ‘en obeleživaÄ za putanju „%s“" + +#: ../glib/gbookmarkfile.c:2336 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "U obeleživaÄu za putanju „%s“ nije odreÄ‘ena MIME vrsta" + +#: ../glib/gbookmarkfile.c:2421 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "U obeleživaÄu za putanju „%s“ nije odreÄ‘ena privatna zastavica" + +#: ../glib/gbookmarkfile.c:2800 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "U obeleživaÄu za putanju „%s“ nisu odreÄ‘ene grupe" + +#: ../glib/gbookmarkfile.c:3199 ../glib/gbookmarkfile.c:3356 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Program „%s“ nije registrovao obeleživaÄ za „%s“" + +#: ../glib/gbookmarkfile.c:3379 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Nisam uspeoda proÅ¡irim komadnu liniju „%s“ sa putanjom „%s“" + +#: ../glib/gconvert.c:473 +msgid "Unrepresentable character in conversion input" +msgstr "Neprikaziv znak u unosu za pretvaranje" + +#: ../glib/gconvert.c:500 ../glib/gutf8.c:865 ../glib/gutf8.c:1077 +#: ../glib/gutf8.c:1214 ../glib/gutf8.c:1318 +msgid "Partial character sequence at end of input" +msgstr "Nepotpun niz znakova na kraju ulaza" + +# ovo pretpostavljam da se odnosi na delimiÄan UTF8 zapis +#: ../glib/gconvert.c:769 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Ne može pretvoriti rezervu „%s“ u zapis „%s“" + +#: ../glib/gconvert.c:940 +msgid "Embedded NUL byte in conversion input" +msgstr "UgraÄ‘eni niÅ¡tavni bajt u ulazu koji pretvaram" + +#: ../glib/gconvert.c:961 +msgid "Embedded NUL byte in conversion output" +msgstr "UgraÄ‘eni niÅ¡tavni bajt u izlazu koji pretvaram" + +#: ../glib/gconvert.c:1649 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "Putanja „%s“ nije apsolutna putanja pomoću „file“ Å¡eme" + +#: ../glib/gconvert.c:1659 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Putanja lokalne datoteke „%s“ ne sme sadržati „#“" + +#: ../glib/gconvert.c:1676 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Putanja „%s“ je neispravna" + +#: ../glib/gconvert.c:1688 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Ime domaćina iz putanje „%s“ je neispravno" + +#: ../glib/gconvert.c:1704 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Putanja „%s“ sadrži neispravno naznaÄene znake" + +#: ../glib/gconvert.c:1776 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Naziv putanje „%s“ nije apsolutna putanja" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A, %d. %B %Y. %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%T" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "January" +msgstr "Januar" + +#: ../glib/gdatetime.c:253 +msgctxt "full month name" +msgid "February" +msgstr "Februar" + +#: ../glib/gdatetime.c:255 +msgctxt "full month name" +msgid "March" +msgstr "Mart" + +#: ../glib/gdatetime.c:257 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: ../glib/gdatetime.c:259 +msgctxt "full month name" +msgid "May" +msgstr "Maj" + +#: ../glib/gdatetime.c:261 +msgctxt "full month name" +msgid "June" +msgstr "Jun" + +#: ../glib/gdatetime.c:263 +msgctxt "full month name" +msgid "July" +msgstr "Jul" + +#: ../glib/gdatetime.c:265 +msgctxt "full month name" +msgid "August" +msgstr "Avgust" + +#: ../glib/gdatetime.c:267 +msgctxt "full month name" +msgid "September" +msgstr "Septembar" + +#: ../glib/gdatetime.c:269 +msgctxt "full month name" +msgid "October" +msgstr "Oktobar" + +#: ../glib/gdatetime.c:271 +msgctxt "full month name" +msgid "November" +msgstr "Novembar" + +#: ../glib/gdatetime.c:273 +msgctxt "full month name" +msgid "December" +msgstr "Decembar" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: ../glib/gdatetime.c:305 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: ../glib/gdatetime.c:307 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: ../glib/gdatetime.c:309 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:311 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:313 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Maj" + +#: ../glib/gdatetime.c:315 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: ../glib/gdatetime.c:317 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: ../glib/gdatetime.c:319 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Avg" + +#: ../glib/gdatetime.c:321 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: ../glib/gdatetime.c:323 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: ../glib/gdatetime.c:325 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: ../glib/gdatetime.c:327 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: ../glib/gdatetime.c:342 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Ponedeljak" + +#: ../glib/gdatetime.c:344 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Utorak" + +#: ../glib/gdatetime.c:346 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Sreda" + +#: ../glib/gdatetime.c:348 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ÄŒetvrtak" + +#: ../glib/gdatetime.c:350 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Petak" + +#: ../glib/gdatetime.c:352 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Subota" + +#: ../glib/gdatetime.c:354 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Nedelja" + +#: ../glib/gdatetime.c:369 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Pon" + +#: ../glib/gdatetime.c:371 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Uto" + +#: ../glib/gdatetime.c:373 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Sre" + +#: ../glib/gdatetime.c:375 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ÄŒet" + +#: ../glib/gdatetime.c:377 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Pet" + +#: ../glib/gdatetime.c:379 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sub" + +#: ../glib/gdatetime.c:381 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Ned" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: ../glib/gdatetime.c:441 +msgctxt "full month name with day" +msgid "January" +msgstr "Januar" + +#: ../glib/gdatetime.c:443 +msgctxt "full month name with day" +msgid "February" +msgstr "Februar" + +#: ../glib/gdatetime.c:445 +msgctxt "full month name with day" +msgid "March" +msgstr "Mart" + +#: ../glib/gdatetime.c:447 +msgctxt "full month name with day" +msgid "April" +msgstr "April" + +#: ../glib/gdatetime.c:449 +msgctxt "full month name with day" +msgid "May" +msgstr "Maj" + +#: ../glib/gdatetime.c:451 +msgctxt "full month name with day" +msgid "June" +msgstr "Jun" + +#: ../glib/gdatetime.c:453 +msgctxt "full month name with day" +msgid "July" +msgstr "Jul" + +#: ../glib/gdatetime.c:455 +msgctxt "full month name with day" +msgid "August" +msgstr "Avgust" + +#: ../glib/gdatetime.c:457 +msgctxt "full month name with day" +msgid "September" +msgstr "Septembar" + +#: ../glib/gdatetime.c:459 +msgctxt "full month name with day" +msgid "October" +msgstr "Oktobar" + +#: ../glib/gdatetime.c:461 +msgctxt "full month name with day" +msgid "November" +msgstr "Novembar" + +#: ../glib/gdatetime.c:463 +msgctxt "full month name with day" +msgid "December" +msgstr "Decembar" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: ../glib/gdatetime.c:524 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Jan" + +#: ../glib/gdatetime.c:526 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Feb" + +#: ../glib/gdatetime.c:528 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:530 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Apr" + +#: ../glib/gdatetime.c:532 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Maj" + +#: ../glib/gdatetime.c:534 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Jun" + +#: ../glib/gdatetime.c:536 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Jul" + +#: ../glib/gdatetime.c:538 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Avg" + +#: ../glib/gdatetime.c:540 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Sep" + +#: ../glib/gdatetime.c:542 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Okt" + +#: ../glib/gdatetime.c:544 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Nov" + +#: ../glib/gdatetime.c:546 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Dec" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:563 +msgctxt "GDateTime" +msgid "AM" +msgstr "PrP" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:566 +msgctxt "GDateTime" +msgid "PM" +msgstr "PoP" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "GreÅ¡ka pri otvaranju direktorijuma „%s“: %s" + +# bug: plural-forms +#: ../glib/gfileutils.c:716 ../glib/gfileutils.c:808 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ne mogu da dodelim %lu bajt za Äitanje datoteke „%s“" +msgstr[1] "Ne mogu da dodelim %lu bajta za Äitanje datoteke „%s“" +msgstr[2] "Ne mogu da dodelim %lu bajtova za Äitanje datoteke „%s“" +msgstr[3] "Ne mogu da dodelim %lu bajt za Äitanje datoteke „%s“" + +#: ../glib/gfileutils.c:733 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "GreÅ¡ka pri Äitanju datoteke „%s“: %s" + +#: ../glib/gfileutils.c:769 +#, c-format +msgid "File “%s†is too large" +msgstr "Datoteka „%s“ je prevelika" + +#: ../glib/gfileutils.c:833 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Nisam uspeoda proÄitam iz datoteke „%s“: %s" + +#: ../glib/gfileutils.c:881 ../glib/gfileutils.c:953 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Nisam uspeo da otvorim datoteku „%s“: %s" + +#: ../glib/gfileutils.c:893 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Nisam uspeo da saznam osobine datoteke „%s“: nije uspela funkcija „fstat()“: " +"%s" + +#: ../glib/gfileutils.c:923 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "" +"Nisam uspeo da otvorim datoteku „%s“: nije uspela funkcija „fdopen()“: %s" + +#: ../glib/gfileutils.c:1022 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Nisam uspeo da preimenujem datoteku „%s“ u „%s“: nije uspela funkcija " +"„g_rename()“: %s" + +#: ../glib/gfileutils.c:1057 ../glib/gfileutils.c:1564 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Nisam uspeo da napravim datoteku „%s“: %s" + +#: ../glib/gfileutils.c:1084 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "" +"Nisam uspeo da zapiÅ¡em datoteku „%s“: nije uspela funkcija „write()“: %s" + +#: ../glib/gfileutils.c:1127 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "" +"Nisam uspeo da upiÅ¡em u datoteku „%s“: nije uspela funkcija „fsync()“: %s" + +#: ../glib/gfileutils.c:1251 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "" +"Postojeća datoteka „%s“ se ne može ukloniti: nije uspela funkcija " +"„g_unlink()“: %s" + +#: ../glib/gfileutils.c:1530 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Neispravan Å¡ablon „%s“, ne sme sadržati „%s“" + +#: ../glib/gfileutils.c:1543 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Å ablon „%s“ ne sadrži XXXXXX" + +#: ../glib/gfileutils.c:2105 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Nisam uspeo da proÄitam simboliÄku vezu „%s“: %s" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Ne mogu da pokrenem pretvaranje iz „%s“ u „%s“: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Ne mogu da obavim sirovo Äitanje niske_g_ui_kanala_Äitanja_reda" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "Preostali nepretvoreni podaci u baferu za Äitanje" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "Kanal se zavrÅ¡ava delimiÄnim znakom" + +#: ../glib/giochannel.c:1925 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Ne mogu da Äitam bez obrade u g_ui_kanalu_Äitaj_do_kraja" + +#: ../glib/gkeyfile.c:788 +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Ne mogu da naÄ‘em ispravnu datoteku sa kljuÄevima meÄ‘u direktorijumima pretrage" + +#: ../glib/gkeyfile.c:825 +msgid "Not a regular file" +msgstr "Nije obiÄna datoteka" + +#: ../glib/gkeyfile.c:1270 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Datoteka sa kljuÄevima sadrži red „%s“ Å¡to ne Äini par kljuÄ-vrednost, grupu " +"ili primedbu" + +#: ../glib/gkeyfile.c:1327 +#, c-format +msgid "Invalid group name: %s" +msgstr "Neispravan naziv grupe: %s" + +#: ../glib/gkeyfile.c:1349 +msgid "Key file does not start with a group" +msgstr "Datoteka sa kljuÄevima ne poÄinje grupom" + +#: ../glib/gkeyfile.c:1375 +#, c-format +msgid "Invalid key name: %s" +msgstr "Neispravan naziv kljuÄa: %s" + +#: ../glib/gkeyfile.c:1402 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Datoteka sa kljuÄevima sadrži nepodržano kodiranje „%s“" + +#: ../glib/gkeyfile.c:1645 ../glib/gkeyfile.c:1818 ../glib/gkeyfile.c:3271 +#: ../glib/gkeyfile.c:3334 ../glib/gkeyfile.c:3464 ../glib/gkeyfile.c:3594 +#: ../glib/gkeyfile.c:3738 ../glib/gkeyfile.c:3967 ../glib/gkeyfile.c:4034 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Datoteka sa kljuÄevima nema grupu „%s“" + +#: ../glib/gkeyfile.c:1773 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Datoteka sa kljuÄevima ne sadrži kljuÄ â€ž%s“ u grupi „%s“" + +#: ../glib/gkeyfile.c:1935 ../glib/gkeyfile.c:2051 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Datoteka sa kljuÄevima sadrži kljuÄ â€ž%s“ vrednosti „%s“ Å¡to nije UTF-8" + +#: ../glib/gkeyfile.c:1955 ../glib/gkeyfile.c:2071 ../glib/gkeyfile.c:2513 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "Datoteka sa kljuÄevima sadrži kljuÄ â€ž%s“ nerazumljive vrednosti." + +#: ../glib/gkeyfile.c:2731 ../glib/gkeyfile.c:3100 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Datoteka sa kljuÄevima sadrži kljuÄ â€ž%s“ u grupi „%s“ nerazumljive vrednosti." + +#: ../glib/gkeyfile.c:2809 ../glib/gkeyfile.c:2886 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "KljuÄ â€ž%s“ u grupi „%s“ ima vrednost „%s“ gde je oÄekivano %s" + +#: ../glib/gkeyfile.c:4274 +msgid "Key file contains escape character at end of line" +msgstr "Datoteka sa kljuÄevima sadrži znak isticanja na kraju reda" + +#: ../glib/gkeyfile.c:4296 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Datoteka sa kljuÄevima sadrži nedozvoljen niz isticanja „%s“" + +#: ../glib/gkeyfile.c:4440 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Vrednost „%s“ se ne može smatrati brojem." + +#: ../glib/gkeyfile.c:4454 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Celobrojna vrednost „%s“ je izvan opsega" + +#: ../glib/gkeyfile.c:4487 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Vrednost „%s“ se ne može smatrati realnim brojem jednostruke taÄnosti." + +#: ../glib/gkeyfile.c:4526 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Vrednost „%s“ se ne može smatrati istinitosnom." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Nisam uspeo da saznam osobine datoteke „%s%s%s%s“: nije uspela funkcija " +"„fstat()“: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" +"Nisam uspeo da mapiram datoteku „%s%s%s%s“: nije uspela funkcija „mmap()“: %s" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "" +"Nisam uspeo da otvorim datoteku „%s“: nije uspela funkcija „open()“: %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "GreÅ¡ka u %d. redu, %d. znak: " + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Neispravan UTF-8 tekst u imenu — „%s“ nije ispravno" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "„%s“ nije ispravan naziv" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "„%s“ nije ispravan naziv: „%c“" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "GreÅ¡ka u %d. redu: %s" + +#: ../glib/gmarkup.c:675 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Nisam uspeo da raÅ¡Älanim „%-.*s“, Å¡to je trebalo da predstavlja cifru unutar " +"znakovne reference (na primer ê) — možda je cifra prevelika" + +#: ../glib/gmarkup.c:687 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Znakovna referenca se ne zavrÅ¡ava taÄka-zapetom; najverovatnije ste " +"koristili ampersand bez namere da zapoÄnete entitet — naznaÄite ampersand sa " +"&" + +#: ../glib/gmarkup.c:713 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Znakovna referenca „%-.*s“ ne predstavlja dozvoljeni znak" + +#: ../glib/gmarkup.c:751 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"UoÄen prazan entitet „&;“; prihvatljivi entiteti su & " < > " +"'" + +#: ../glib/gmarkup.c:759 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Ime entiteta „%-.*s“ nije poznato" + +#: ../glib/gmarkup.c:764 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Entitet se ne zavrÅ¡ava taÄka-zapetom; najverovatnije ste koristili ampersand " +"bez namere da zapoÄnete entitet — naznaÄite ampersand sa &" + +#: ../glib/gmarkup.c:1170 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokument mora poÄeti elementom (npr. )" + +#: ../glib/gmarkup.c:1210 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"„%s“ ne predstavlja ispravan znak nakon znaka „<“; naziv elementa ne može " +"njime poÄeti" + +#: ../glib/gmarkup.c:1252 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"ÄŒudan znak „%s“, a oÄekivan je „>“ znak radi okonÄanja oznake praznog " +"elementa „%s“" + +#: ../glib/gmarkup.c:1333 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"ÄŒudan znak „%s“, oÄekivan je „=“ posle imena atributa „%s“ elementa „%s“" + +#: ../glib/gmarkup.c:1374 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ÄŒudan znak „%s“, oÄekivan je ili „>“ ili „/“ radi okonÄanja poÄetne oznake " +"elementa „%s“, ili možda atribut; možda ste koristili neispravan znak u " +"imenu atributa" + +#: ../glib/gmarkup.c:1418 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"ÄŒudan znak „%s“, oÄekivan je poÄetni navodnik nakon znaka jednakosti pri " +"dodeli vrednosti atributa „%s“ elementa „%s“" + +#: ../glib/gmarkup.c:1551 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"„%s“ nije ispravan znak nakon imena zatvorenog elementa „%s“; dozvoljeni znak " +"je „>“" + +#: ../glib/gmarkup.c:1598 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Element „%s“ je zatvoren, nema trenutno otvorenih elemenata" + +#: ../glib/gmarkup.c:1607 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Element „%s“ je zatvoren, a trenutno otvoren element je „%s“" + +#: ../glib/gmarkup.c:1760 +msgid "Document was empty or contained only whitespace" +msgstr "Dokument je prazan ili sadrži samo beline" + +#: ../glib/gmarkup.c:1774 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Dokument je zavrÅ¡en neoÄekivano neposredno nakon otvorene kosougle zagrade " +"„<“" + +#: ../glib/gmarkup.c:1782 ../glib/gmarkup.c:1827 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Dokument je zavrÅ¡en neoÄekivano sa otvorenim elementima — „%s“ je poslednje " +"otvoren element" + +#: ../glib/gmarkup.c:1790 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokument je zavrÅ¡en neoÄekivano, a oÄekivana je zatvorena kosougla zagrada " +"koja zatvara oznaku <%s/>" + +#: ../glib/gmarkup.c:1796 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokument je zavrÅ¡en neoÄekivano usred imena elementa" + +#: ../glib/gmarkup.c:1802 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokument je zavrÅ¡en neoÄekivano usred imena atributa" + +#: ../glib/gmarkup.c:1807 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokument je zavrÅ¡en neoÄekivano usred poÄetne oznake elementa." + +#: ../glib/gmarkup.c:1813 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokument je zavrÅ¡en neoÄekivano nakon znaka jednakosti posle imena atributa; " +"vrednost atributa nije navedena" + +#: ../glib/gmarkup.c:1820 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokument je zavrÅ¡en neoÄekivano usred vrednosti atributa" + +#: ../glib/gmarkup.c:1836 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "Dokument je zavrÅ¡en neoÄekivano usred zavrÅ¡ne oznake elementa „%s“" + +#: ../glib/gmarkup.c:1842 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Dokument je zavrÅ¡en neoÄekivano usred primedbe ili uputa za obradu" + +#: ../glib/goption.c:861 +msgid "[OPTION…]" +msgstr "[OPCIJA…]" + +#: ../glib/goption.c:977 +msgid "Help Options:" +msgstr "Pomoćne opcije:" + +#: ../glib/goption.c:978 +msgid "Show help options" +msgstr "Prikazuje opcije za pomoć" + +#: ../glib/goption.c:984 +msgid "Show all help options" +msgstr "Prikazuje sve opcije za pomoć" + +#: ../glib/goption.c:1047 +msgid "Application Options:" +msgstr "Opcije programa:" + +#: ../glib/goption.c:1049 +msgid "Options:" +msgstr "Opcije:" + +#: ../glib/goption.c:1113 ../glib/goption.c:1183 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Ne mogu da raÅ¡Älanim celobrojnu vrednost „%s“ za %s" + +#: ../glib/goption.c:1123 ../glib/goption.c:1191 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Celobrojna vrednost „%s“ za %s je izvan opsega" + +#: ../glib/goption.c:1148 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Ne mogu da raÅ¡Älanim realnu vrednost dvostruke taÄnosti „%s“ za %s" + +#: ../glib/goption.c:1156 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Realna vrednost dvostruke taÄnosti „%s“ za %s je izvan opsega" + +#: ../glib/goption.c:1448 ../glib/goption.c:1527 +#, c-format +msgid "Error parsing option %s" +msgstr "GreÅ¡ka pri raÅ¡Älanjivanju mogućnosti %s" + +#: ../glib/goption.c:1558 ../glib/goption.c:1671 +#, c-format +msgid "Missing argument for %s" +msgstr "Nedostaje argument za %s" + +#: ../glib/goption.c:2132 +#, c-format +msgid "Unknown option %s" +msgstr "Nepoznata opcija %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "oÅ¡tećen objekat" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "interna greÅ¡ka ili oÅ¡tećen objekat" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "nema viÅ¡e memorije" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "dostignut je limit pretraživanja unazad" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "obrazac sadrži stavke koje nisu podržane za delimiÄno poklapanje" + +#: ../glib/gregex.c:280 +msgid "internal error" +msgstr "unutraÅ¡nja greÅ¡ka" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"reference na prethodno poklapanje ne mogu biti uslov za delimiÄno poklapanje" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "dostignut je limit rekurzije" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "neispravna kombinacija oznaka za novu liniju" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "loÅ¡ pomeraj" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "kratak utf8" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "dubinsko vrtenje kroz direktorijume" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "nepoznata greÅ¡ka" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ na kraju obrasca" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c na kraju obrasca" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "nepoznat znak sledi nakon \\" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "brojevi nisu po redu u {} brojaÄu" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "brojevi su preveliki u {} brojaÄu" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "nedostaje zavrÅ¡nica ] za klasu znakova" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "neispravan izbegavaÄki niz u klasi znakova" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "opseg je neispravan unutar klase znakova" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "nema niÄega za ponavljanje" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "neoÄekivano ponavljanje" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "nepoznat znak nakon (? ili (?-" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "klase imenovane POSIKS-om su podržane samo unutar klase" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "nedostaje zavrÅ¡nica )" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "referenca na nepostojeći podobrazac" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "nedostaje ) nakon komentara" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "regularni izraz je predug" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "ne mogu da dobijem memoriju" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr ") bez otvaranja (" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "prekoraÄenje koda" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "nepoznat znak nakon (?<" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "podaci iza tvrdnje nisu zadate dužine" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "neispravno zadat broj ili naziv nakon (?(" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "uslovna grupa sadrži viÅ¡e od dve grane" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "oÄekivana je tvrdnja nakon (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "nakon(?R ili (?[+-]brojeva mora da sledi )" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "nepoznat naziv POSIKS klase" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "nisu podržani POSIKS kolacioni elementi" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "prevelika je vrednost karaktera u \\x{…} sekvenci" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "neispravan je uslov (?(0)" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "nije dozvoljeno \\C u podacima iza tvrdnje" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "znaci za promenu reda „\\L, \\l, \\N{naziv}, \\U, \\u“ nisu podržani" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "dubinski zahtev se može ponavljati beskonaÄno" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "nepoznat znak nakon (?P" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "nedostaje zavrÅ¡nica u nazivu podobrasca" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "dvoimeni podobrasci imaju isto ime" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "nije ispravno zadata \\P ili \\p sekvenca" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "nije poznat naziv osobine nakon \\P ili \\p" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "naziv podobrasca je predug (najviÅ¡e 32 znaka)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ima previÅ¡e imenovanih podobrazaca (sme ih biti najviÅ¡e 10000)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "osmobrojna vrednost je veća od \\377" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "previÅ¡e pokrenutih radnih prostora za prevoÄ‘enje izvornog koda" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "nije naÄ‘en prethodno provereni i povezani podobrazac" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE grupa sadrži viÅ¡e od jedne grane" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "neujednaÄene NEWLINE opcije" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"iza „\\g“ se ne nalazi naziv ili broj u zagradi, uglastoj zagradi, ili pod " +"navodnicima, ili obiÄan broj" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "numerisana referenca ne sme biti nula" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "argument nije dozvoljen za (*ACCEPT), (*FAIL), ili (*COMMIT)" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) nije prepoznato" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "broj je prevelik" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "nedostaje naziv podobrasca nakon (?&" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "oÄekivana je cifra nakon (?+" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] je neispravan znak podataka u režimu saglasnosti skripte Jave" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "razliÄiti nazivi za podobrasce istog broja nisu dozvoljeni" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) mora da sadrži argument" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "iza „\\c“ mora da sledi ASKRI znak" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"iza „\\k“ se ne nalazi naziv u zagradi, uglastoj zagradi, ili pod navodnicima" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "„\\N“ nije podržano u razredu" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "previÅ¡e referenci prosleÄ‘ivanja" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "naziv je predug u (*MARK), (*PRUNE), (*SKIP), ili (*THEN)" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "vrednost znaka u nizu „\\u….“ je prevelika" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1977 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "GreÅ¡ka prilikom pretraživanja regularnim izrazom %s: %s" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE biblioteka je prevedena bez podrÅ¡ke za UTF8" + +#: ../glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE biblioteka je prevedena bez podrÅ¡ke za UTF8 osobine" + +#: ../glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE biblioteka je prevedena sa nesaglasnim opcijama" + +#: ../glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "GreÅ¡ka pri optimizovanju regularnog izraza %s: %s" + +#: ../glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "GreÅ¡ka pri prevoÄ‘enju regularnog izraza %s kod znaka %d: %s" + +#: ../glib/gregex.c:2413 +msgid "hexadecimal digit or “}†expected" +msgstr "oÄekivana je heksadekadna cifra ili „}“" + +#: ../glib/gregex.c:2429 +msgid "hexadecimal digit expected" +msgstr "oÄekivana je heksadekadna cifra" + +#: ../glib/gregex.c:2469 +msgid "missing “<†in symbolic reference" +msgstr "nedostaje „<“ u referenci simbola" + +#: ../glib/gregex.c:2478 +msgid "unfinished symbolic reference" +msgstr "NedovrÅ¡ena referenca simbola" + +#: ../glib/gregex.c:2485 +msgid "zero-length symbolic reference" +msgstr "referenca simbola je dužine nula" + +#: ../glib/gregex.c:2496 +msgid "digit expected" +msgstr "oÄekivana je cifra" + +#: ../glib/gregex.c:2514 +msgid "illegal symbolic reference" +msgstr "neispravna referenca simbola" + +#: ../glib/gregex.c:2576 +msgid "stray final “\\â€" +msgstr "odlutalo zavrÅ¡no „\\“" + +#: ../glib/gregex.c:2580 +msgid "unknown escape sequence" +msgstr "nepoznata sekvenca izbegavanja" + +#: ../glib/gregex.c:2590 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "GreÅ¡ka prilikom obrade teksta za zamenu „%s“ kod karaktera %lu: %s" + +#: ../glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Navod ne poÄinje navodnikom" + +#: ../glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Neuparen navodnik u naredbi ili drugom citatu iz ljuske" + +#: ../glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Sadržaj zavrÅ¡en neposredno nakon „\\“ znaka. (Radi se o tekstu „%s“)" + +#: ../glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Sadržaj zavrÅ¡en pre nailaska na odgovarajući navodnik za %c. (Radi se o " +"tekstu „%s“)" + +#: ../glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "Sadržaj prazan (ili sadrži samo beline)" + +#: ../glib/gspawn.c:253 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Neuspelo Äitanje podataka od potprocesa (%s)" + +#: ../glib/gspawn.c:401 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"NeoÄekivana greÅ¡ka u funkciji „select()“ prilikom Äitanja podataka iz " +"potprocesa (%s)" + +#: ../glib/gspawn.c:486 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "NeoÄekivana greÅ¡ka u funkciji „waitpid()“ (%s)" + +#: ../glib/gspawn.c:897 ../glib/gspawn-win32.c:1231 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Potproces je izaÅ¡ao sa Å¡ifrom %ld" + +#: ../glib/gspawn.c:905 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Potproces je ubijen signalom %ld" + +#: ../glib/gspawn.c:912 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Potproces je zaustavljen signalom %ld" + +#: ../glib/gspawn.c:919 +#, c-format +msgid "Child process exited abnormally" +msgstr "Potproces je neoÄekivano prekinut" + +#: ../glib/gspawn.c:1324 ../glib/gspawn-win32.c:337 ../glib/gspawn-win32.c:345 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Nisam uspeo da Äitam iz spojke poroda (%s)" + +# za sada ovako, možda grananje, umnožavanje? viljuÅ¡kanje ;-) +#: ../glib/gspawn.c:1394 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Nisam uspeo da iscepim (%s)" + +#: ../glib/gspawn.c:1543 ../glib/gspawn-win32.c:368 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Nisam uspeo da preÄ‘em u direktorijum „%s“ (%s)" + +#: ../glib/gspawn.c:1553 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Nisam uspeo da izvrÅ¡im potproces „%s“ (%s)" + +#: ../glib/gspawn.c:1563 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Nisam uspeo da preusmerim ulaz ili izlaz potprocesa (%s)" + +#: ../glib/gspawn.c:1572 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Nisam uspeo da iscepim potproces (%s)" + +#: ../glib/gspawn.c:1580 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Nepoznata greÅ¡ka pri izvrÅ¡avanju potprocesa „%s“" + +#: ../glib/gspawn.c:1604 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Nije uspeo da proÄita dovoljno podataka iz cevke ka potprocesu (%s)" + +#: ../glib/gspawn-win32.c:281 +msgid "Failed to read data from child process" +msgstr "Nisam uspeo da Äitam podatke iz potprocesa" + +#: ../glib/gspawn-win32.c:298 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Nisam uspeo da napravim spojku za vezu sa potprocesom (%s)" + +#: ../glib/gspawn-win32.c:374 ../glib/gspawn-win32.c:493 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Nisam uspeo da izvrÅ¡im potproces (%s)" + +#: ../glib/gspawn-win32.c:443 +#, c-format +msgid "Invalid program name: %s" +msgstr "Nije ispravan naziv programa: %s" + +#: ../glib/gspawn-win32.c:453 ../glib/gspawn-win32.c:720 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Nije ispravna niska — Älan vektora u %d: %s" + +#: ../glib/gspawn-win32.c:464 ../glib/gspawn-win32.c:735 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Nije ispravna niska u okruženju: %s" + +#: ../glib/gspawn-win32.c:716 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Nije ispravna radna fascikla: %s" + +#: ../glib/gspawn-win32.c:781 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Nisam uspeo da izvrÅ¡im pomoćniÄki program (%s)" + +#: ../glib/gspawn-win32.c:995 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"NeoÄekivana greÅ¡ka dok su u g_io_channel_win32_poll() Äitani podaci iz " +"potprocesa" + +#: ../glib/gstrfuncs.c:3247 ../glib/gstrfuncs.c:3348 +msgid "Empty string is not a number" +msgstr "Prazna niska nije broj" + +#: ../glib/gstrfuncs.c:3271 +#, c-format +msgid "“%s†is not a signed number" +msgstr "„%s“ nije potpisan broj" + +#: ../glib/gstrfuncs.c:3281 ../glib/gstrfuncs.c:3384 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Broj „%s“ je van granica [%s, %s]" + +#: ../glib/gstrfuncs.c:3374 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "„%s“ nije nepotpisan broj" + +#: ../glib/gutf8.c:811 +msgid "Failed to allocate memory" +msgstr "Nisam uspeo da dodelim memoriju" + +#: ../glib/gutf8.c:944 +msgid "Character out of range for UTF-8" +msgstr "Znak van opsega za UTF-8" + +#: ../glib/gutf8.c:1045 ../glib/gutf8.c:1054 ../glib/gutf8.c:1184 +#: ../glib/gutf8.c:1193 ../glib/gutf8.c:1332 ../glib/gutf8.c:1429 +msgid "Invalid sequence in conversion input" +msgstr "Nije ispravan niz u unosu za pretvaranje" + +#: ../glib/gutf8.c:1343 ../glib/gutf8.c:1440 +msgid "Character out of range for UTF-16" +msgstr "Znak van opsega za UTF-16" + +#: ../glib/gutils.c:2229 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2230 ../glib/gutils.c:2436 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2231 ../glib/gutils.c:2441 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2232 ../glib/gutils.c:2446 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2233 ../glib/gutils.c:2451 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2234 ../glib/gutils.c:2456 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#: ../glib/gutils.c:2237 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2238 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2239 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2240 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2241 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2242 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2245 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#: ../glib/gutils.c:2246 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#: ../glib/gutils.c:2247 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#: ../glib/gutils.c:2248 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#: ../glib/gutils.c:2249 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#: ../glib/gutils.c:2250 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#: ../glib/gutils.c:2253 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#: ../glib/gutils.c:2254 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#: ../glib/gutils.c:2255 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#: ../glib/gutils.c:2256 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#: ../glib/gutils.c:2257 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#: ../glib/gutils.c:2258 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: ../glib/gutils.c:2292 ../glib/gutils.c:2418 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bajt" +msgstr[1] "%u bajta" +msgstr[2] "%u bajta" +msgstr[3] "Jedan bajt" + +#: ../glib/gutils.c:2296 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bita" +msgstr[2] "%u bitova" +msgstr[3] "Jedan bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2363 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bajt" +msgstr[1] "%s bajta" +msgstr[2] "%s bajtova" +msgstr[3] "Jedan bajt" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: ../glib/gutils.c:2368 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bita" +msgstr[2] "%s bitova" +msgstr[3] "Jedan bit" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2431 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Poruka ima %d opisivaÄa datoteke, ali zaglavlje ukazuje na %d opisivaÄa " +#~ "datoteke" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "GreÅ¡ka: nije izabrana putanja objekta.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "GreÅ¡ka: signal nije naveden.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "GreÅ¡ka: signal mora biti potpuno odgovarajući naziv.\n" + +#~ msgid "No such interface" +#~ msgstr "Nema takvog interfejsa" + +#~ msgid "No files given" +#~ msgstr "Nije data datoteka" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "GreÅ¡ka dobavljanja zapisivih osobina: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "GreÅ¡ka kaÄenja mesta: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "GreÅ¡ka otkaÄinjanja kaÄenja: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "GreÅ¡ka u nalaženju ugneždenog kaÄenja: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "GreÅ¡ka izbacivanja kaÄenja: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "GreÅ¡ka kaÄenja „%s“: %s\n" + +#~ msgid "No files to open" +#~ msgstr "Nema datoteka za otvaranje" + +#~ msgid "No files to delete" +#~ msgstr "Nema datoteka za brisanje" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "GreÅ¡ka postavljanja atributa: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "GreÅ¡ka prilikom obrazovanja direktorijuma „%s“: %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "GreÅ¡ka prilikom otvaranja datoteke „%s“: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "GreÅ¡ka pri Äitanju datoteke „%s“: %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "GreÅ¡ka u preimenovanju datoteke: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "GreÅ¡ka prilikom otvaranja datoteke: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "GreÅ¡ka prilikom obrazovanja direktorijuma: %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "" +#~ "Ne mogu da naÄ‘em podrazumevanu vrstu monitora za lokalni direktorijum" + +#~ msgid "association changes not supported on win32" +#~ msgstr "nisu podržane promene pridruživanja za win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Nisu podržane promene pridruživanja za win32" + +#~ msgid "URIs not supported" +#~ msgstr "Adrese nisu podržane" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Datoteka sa kljuÄevima nema kljuÄ â€ž%s“" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "GreÅ¡ka obrade ulazne datoteke sa „xmllint“-om:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "GreÅ¡ka obrade ulazne datoteke sa „to-pixdata“-om:\n" +#~ "%s" diff --git a/po/sv.po b/po/sv.po new file mode 100644 index 0000000..e852909 --- /dev/null +++ b/po/sv.po @@ -0,0 +1,6407 @@ +# Swedish messages for glib. +# Copyright © 2001-2022 Free Software Foundation, Inc. +# Christian Rose , 2001-2005. +# Daniel Nylander , 2006-2012. +# Sebastian Rasmussen , 2014, 2015. +# Anders Jonsson , 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. +# Luna Jernberg , 2021, 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 15:19+0000\n" +"PO-Revision-Date: 2022-03-22 16:33+0100\n" +"Last-Translator: Anders Jonsson \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Inställning av standardprogram stöds inte ännu" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "Inställning av program som senast använt för typ stöds inte ännu" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication-alternativ" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Visa GApplication-alternativ" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GÃ¥ in i GApplication-serviceläge (användning frÃ¥n D-Bus-servicefil)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Ã…sidosätt programmets ID" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Ersätt den körande instansen" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Skriv ut hjälp" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[KOMMANDO]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Skriv ut version" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Skriv ut versionsinformation och avsluta" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Lista program" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Lista de installerade D-Bus-aktiverbara programmen (via .desktop-filer)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Starta ett program" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Starta programmet (med frivilliga filer att öppna)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [FIL…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Aktivera en Ã¥tgärd" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Anropa en Ã¥tgärd i programmet" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID Ã…TGÄRD [PARAMETER]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Lista tillgängliga Ã¥tgärder" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Lista statiska Ã¥tgärder för ett program (frÃ¥n .desktop-fil)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMMANDO" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Kommandot att skriva ut detaljerad hjälp för" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Programidentifierare i D-Bus-format (t.ex: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "FIL" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Frivilliga relativa eller absoluta filnamn eller URI:er att öppna" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "Ã…TGÄRD" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Ã…tgärdsnamn att starta" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETER" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Frivillig parameter till Ã¥tgärdsstarten, i GVariant-format" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Okänt kommando %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Användning:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argument:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGUMENT…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Kommandon:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Använd â€%s help KOMMANDO†för att fÃ¥ detaljerad hjälp.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s-kommando kräver ett program-ID direkt efter\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "ogiltigt program-ID: â€%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"â€%s†tar inga argument\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "kunde inte ansluta till D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "fel vid sändning av meddelande %s till program: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "Ã¥tgärdsnamn mÃ¥ste ges efter program-ID\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"ogiltigt Ã¥tgärdsnamn: â€%sâ€\n" +"Ã¥tgärdsnamn mÃ¥ste bestÃ¥ av enbart alfanumeriska, â€-†och â€.â€\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "fel vid tolkning av Ã¥tgärdsparameter: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "Ã¥tgärder accepterar maximalt en parameter\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions-kommandot tar enbart program-ID:t" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "kunde inte hitta desktopfil för programmet %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"okänt kommando: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "För stort räknevärde skickat till %s" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Sökning stöds inte pÃ¥ basströmmen" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Kan inte kapa av GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Strömmen är redan stängd" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Kapning stöds inte pÃ¥ basströmmen" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Ã…tgärden avbröts" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Ogiltigt objekt, inte initierat" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Ofullständig flerbytesekvens i inmatning" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Inte tillräckligt med utrymme i mÃ¥let" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Ogiltig bytesekvens i konverteringsindata" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Fel vid konvertering: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Avbrytningsbar initiering stöds inte" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Konvertering frÃ¥n teckentabellen â€%s†till â€%s†stöds inte" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Kunde inte öppna konverteraren frÃ¥n â€%s†till â€%sâ€" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s-typ" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Okänd typ" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s-filtyp" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials innehÃ¥ller ogiltiga data" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials är inte implementerat för detta operativsystem" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Det finns inget stöd för GCredentials för din plattform" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials innehÃ¥ller inte ett process-ID för detta OS" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Inloggningsuppgiftsspoofning är inte möjligt i detta OS" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Oväntat tidig end-of-stream" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Nyckeln â€%s†stöds inte i adressposten â€%sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "Betydelselös kombination av nyckel/värde-par i adressposten â€%sâ€" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Adressen â€%s†är ogiltig (behöver exakt en av sökväg, katalog, " +"temporärkatalog eller abstrakta nycklar)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Fel i adressen â€%s†— attributet â€%s†är felformulerat" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Transport â€%s†är okänd eller saknar stöd för adressen â€%sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adresselementet â€%s†innehÃ¥ller inte ett kolontecken (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Transportnamn i adresselementet â€%s†fÃ¥r inte vara tomt" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Nyckel/Värde-par %d, â€%sâ€, i adresselementet â€%s†innehÃ¥ller inte ett " +"likhetstecken" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Nyckel/Värde-par %d, â€%sâ€, i adresselementet â€%s†fÃ¥r inte ha en tom nyckel" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Fel vid borttagning av escape i nyckel eller värde i Nyckel/Värde-par %d, " +"â€%sâ€, i adresselementet â€%sâ€" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Fel i adressen â€%s†— unix-transporten kräver att exakt en av nycklarna " +"â€path†eller â€abstract†har ställts in" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "Fel i adressen â€%s†— värdattributet saknas eller är felformulerat" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "Fel i adressen â€%s†— portattributet saknas eller är felformulerat" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Fel i adressen â€%s†— attributet noncefile saknas eller är felformulerat" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Fel vid automatisk körning: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Fel vid öppning av nonce-filen â€%sâ€: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Fel vid läsning frÃ¥n nonce-filen â€%sâ€: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Fel vid läsning frÃ¥n nonce-filen â€%sâ€, förväntade 16 byte, fick %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "Fel vid skrivning av innehÃ¥ll i nonce-filen â€%s†till ström:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Angivna adressen är tom" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Kan inte starta en meddelandebuss när AT_SECURE har ställts in" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Kan inte starta en meddelandebuss utan ett maskin-id: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Kan inte starta D-Bus automatiskt utan X11-miljövariabeln $DISPLAY" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Fel vid körning av kommandoraden â€%sâ€: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Kan inte fastställa adress för sessionsbuss (inte implementerat för detta " +"operativsystem)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Kan inte fastställa bussadressen frÃ¥n miljövariabeln DBUS_STARTER_BUS_TYPE — " +"okänt värde â€%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Kan inte fastställa bussadress därför att miljövariabeln " +"DBUS_STARTER_BUS_TYPE inte är inställd" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Okänd busstyp %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Oväntad avsaknad av innehÃ¥ll vid försök att läsa en rad" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Oväntad avsaknad av innehÃ¥ll vid försök att (säkert) läsa en rad" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Alla tillgängliga autentiseringsmekanismer har testats (försök: %s) " +"(tillgängliga: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Användar-ID:n mÃ¥ste vara samma för motpart och server" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Avbröts via GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Fel vid hämtning av information för katalogen â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Rättigheter pÃ¥ katalogen â€%s†är felformulerade. Förväntade rättigheten " +"0700, fick 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "Fel vid skapandet av katalogen â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "Ã…tgärden stöds inte" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Fel vid öppnandet av nyckelringen â€%s†för läsning: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "Rad %d av nyckelringen vid â€%s†med innehÃ¥ll â€%s†är felformulerad" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Första token pÃ¥ rad %d av nyckelringen i â€%s†med innehÃ¥llet â€%s†är " +"felformulerad" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Andra token pÃ¥ rad %d av nyckelringen i â€%s†med innehÃ¥llet â€%s†är " +"felformulerad" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Hittade inte kaka med id %d i nyckelringen vid â€%sâ€" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Fel vid skapandet av lÃ¥sfilen â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Fel vid borttagning av gamla lÃ¥sfilen â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "Fel vid stängning av (avlänkad) lÃ¥sfil â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "Fel vid avlänkning av lÃ¥sfilen â€%sâ€: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "Fel vid öppning av nyckelringen â€%s†för skrivning: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(I tillägg misslyckades även upplÃ¥sningen för â€%sâ€: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "Anslutningen är stängd" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Tidsgränsen uppnÃ¥ddes" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Flaggor som inte stöds pÃ¥träffades vid konstruktion av en anslutning pÃ¥ " +"klientsidan" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Inget sÃ¥dant gränssnitt â€org.freedesktop.DBus.Properties†pÃ¥ objekt med " +"sökvägen %s" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Ingen sÃ¥dan egenskap â€%sâ€" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "Egenskapen â€%s†är inte läsbar" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "Egenskapen â€%s†är inte skrivbar" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Fel vid inställning av egenskapen â€%sâ€: Förväntade typen â€%s†men fick â€%sâ€" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Inget sÃ¥dan gränssnitt â€%sâ€" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Inget sÃ¥dant gränssnitt â€%s†pÃ¥ objekt med sökvägen %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Ingen sÃ¥dan metod â€%sâ€" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Typ av meddelande, â€%sâ€, matchar inte förväntade typen â€%sâ€" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Ett objekt är redan exporterat för gränssnittet %s vid %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Kunde inte hämta egenskap %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Kunde inte sätta egenskap %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Metoden â€%s†returnerade typen â€%sâ€, men förväntade â€%sâ€" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Metoden â€%s†pÃ¥ gränssnittet â€%s†med signaturen â€%s†finns inte" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Ett underträd har redan exporterats för %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Objektet finns inte pÃ¥ sökvägen â€%sâ€" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "typ är OGILTIG" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL-meddelande: rubrikfältet PATH eller MEMBER saknas" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN-meddelande: rubrikfältet REPLY_SERIAL saknas" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "FELmeddelande: rubrikfältet REPLY_SERIAL eller ERROR_NAME saknas" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL-meddelande: rubrikfältet PATH, INTERFACE eller MEMBER saknas" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL-meddelande: Rubrikfältet PATH använder det reserverade värdet /org/" +"freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL-meddelande: Rubrikfältet INTERFACE använder det reserverade värdet " +"org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Ville läsa %lu byte men fick bara %lu" +msgstr[1] "Ville läsa %lu byte men fick bara %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Förväntade NUL-byte efter strängen â€%s†men hittade byte %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Förväntade giltig UTF-8-sträng men hittade ogiltiga byte vid byte-offset %d " +"(längd av strängen är %d). Den giltiga UTF-8-strängen fram till den punkten " +"var â€%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Värde nästlat för djupt" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Tolkat värde â€%s†är inte en giltig D-Bus-objektsökväg" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Tolkat värde â€%s†är inte en giltig D-Bus-signatur" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"PÃ¥träffade array med längden %u byte. Maximal längd är 2<<26 byte (64 MiB)." +msgstr[1] "" +"PÃ¥träffade array med längden %u byte. Maximal längd är 2<<26 byte (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"PÃ¥träffade array av typ â€a%câ€, förväntad att ha en längd som är en multipel " +"av %u byte, men visade sig vara %u byte lÃ¥ng" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Tomma strukturer (tupler) tillÃ¥ts inte i D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Tolkat värde â€%s†för variant är inte en giltig D-Bus-signatur" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Fel vid deserialisering av GVariant med typsträngen â€%s†frÃ¥n D-Bus-" +"transportformatet" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Ogiltigt värde för byteordning. Förväntade 0x6c (â€lâ€) eller 0x42 (â€Bâ€) men " +"hittade värdet 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Ogiltig större protokollversion. Förväntade 1 men hittade %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "Signaturrubrik hittades men är inte av typen signatur" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Signaturrubrik med signaturen â€%s†hittades men meddelandekroppen är tom" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Tolkat värde â€%s†är inte en giltig D-Bus-signatur (för kropp)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "Ingen signaturrubrik i meddelande men meddelandekroppen är %u byte" +msgstr[1] "Ingen signaturrubrik i meddelande men meddelandekroppen är %u byte" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Kan inte deserialisera meddelande: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "" +"Fel vid serialisering av GVariant med typsträngen â€%s†till D-Bus-" +"transportformatet" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "Antal filhandtag i meddelande (%d) skiljer sig frÃ¥n rubrikfältet (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Kan inte serialisera meddelandet: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "" +"Meddelandekroppen har signaturen â€%s†men det finns ingen signaturrubrik" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"Meddelandekroppen har typsignaturen â€%s†men signaturen i rubrikfältet är " +"â€%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "Meddelandekroppen är tom men signaturen i rubrikfältet är â€(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Fel returnerades med kropp av typen â€%sâ€" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Fel returnerade med tom kropp" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Skriv vilket tecken som helst för att stänga detta fönster)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Sessions-dbus kör inte, och autostart misslyckades" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Kunde inte hämta hÃ¥rdvaruprofil: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Kunde inte läsa in %s eller %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Fel vid anrop av StartServiceByName för %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Oväntat svar %d frÃ¥n StartServiceByName(â€%sâ€)-metod" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Kan inte anropa metod; proxy är för det välkända namnet %s utan en ägare och " +"proxy konstruerades med flaggan G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Abstrakt namnrymd stöds inte" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Kan inte ange nonce-filen när en server skapas" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "Fel vid skrivning av nonce-fil i â€%sâ€: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "Strängen â€%s†är inte ett giltigt D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Kan inte lyssna pÃ¥ transport â€%s†som inte stöds" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Kommandon:\n" +" help Visar denna information\n" +" introspect Introspektera ett fjärrobjekt\n" +" monitor Övervaka ett fjärrobjekt\n" +" call Anropa en metod pÃ¥ ett fjärrobjekt\n" +" emit Sänd en signal\n" +" wait Vänta pÃ¥ att ett bussnamn dyker upp\n" +"\n" +"Använd â€%s KOMMANDO --help†för hjälp med varje kommando.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Fel: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Fel vid tolkning av introspektions-XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Fel: %s är inte ett giltigt namn\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Fel: %s är inte en giltig objektsökväg\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Anslut till systembussen" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Anslut till sessionsbussen" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Anslut till angiven D-Bus-adress" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Flaggor för anslutningspunkt:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Flaggor som anger anslutningens ändpunkt" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Ingen anslutningsändpunkt har angivits" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Flera anslutningsändpunkter har angivits" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Varning: Enligt introspektionsdata finns inte gränssnittet â€%sâ€\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"Varning: Enligt introspektionsdata finns inte metoden â€%s†pÃ¥ gränssnittet " +"â€%sâ€\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Frivilligt mÃ¥l för signal (unikt namn)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Objektsökväg att sända signalen pÃ¥" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Signal- och gränssnittsnamn" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Sänd en signal." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Fel vid anslutning: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Fel: %s är inte ett giltigt unikt bussnamn.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Fel: Objektsökväg har inte angivits\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Fel: Signalnamnet är inte angivet\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Fel: Signalnamnet â€%s†är ogiltigt\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Fel: %s är inte ett giltigt gränssnittsnamn\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Fel: %s är inte ett giltigt medlemsnamn\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Fel vid tolkning av parameter %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Fel vid tömning av anslutning: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "MÃ¥lnamn att anropa metod pÃ¥" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Objektsökväg att anropa metod pÃ¥" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Metod- och gränssnittsnamn" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Tidsgräns i sekunder" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "TillÃ¥t interaktiv auktorisering" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Anropa en metod pÃ¥ ett fjärrobjekt." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Fel: MÃ¥l har inte angivits\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Fel: %s är inte ett giltigt bussnamn\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Fel: Metodnamnet är inte angivet\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Fel: Metodnamnet â€%s†är ogiltigt\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "Fel vid tolkning av parameter %d av typen â€%sâ€: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Fel vid tillägg av handtag %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "MÃ¥lnamn att introspektera" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Objektsökväg att introspektera" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Skriv ut XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Introspektera barn" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Skriv endast ut egenskaper" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Introspektera ett fjärrobjekt." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "MÃ¥lnamn att övervaka" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Objektsökväg att övervaka" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Övervaka ett fjärrobjekt." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Fel: kan inte övervaka en anslutning som ej är pÃ¥ meddelandebuss\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Tjänst att aktivera innan den andra väntas pÃ¥ (välkänt namn)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Tidsgräns att vänta pÃ¥ innan vi avslutar med ett fel (sekunder); 0 för ingen " +"tidsgräns (standard)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[FLAGGA…] BUSSNAMN" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Vänta pÃ¥ att ett bussnamn ska dyka upp." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Fel: En tjänst att aktivera för mÃ¥ste anges.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Fel: En tjänst att vänta pÃ¥ mÃ¥ste anges.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Fel: För mÃ¥nga argument.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Fel: %s är inte ett giltigt välkänt bussnamn.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Inte behörig att ändra felsökningsinställningar" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Namnlös" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Desktop-filen angav inget Exec-fält" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Kunde inte hitta terminal som krävs för programmet" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Kan inte skapa programkonfigurationsmapp för användare %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Kan inte skapa MIME-konfigurationsmapp för användare %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Programinformation saknar en identifierare" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Kan inte skapa desktop-fil %s för användare" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "Anpassad definition för %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "enheten har inte implementerat eject" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "enheten har inte implementerat eject eller eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "enheten har inte implementerat pollning av media" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "enheten har inte implementerat start" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "enheten har inte implementerat stop" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS-bakänden implementerar inte hämtande av TLS-bindning" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS-stöd finns inte tillgängligt" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS-stöd finns inte tillgängligt" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Kan inte hantera version %d av GEmblem-kodning" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Felformaterat antal token (%d) i GEmblem-kodning" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Kan inte hantera version %d av GEmblemedIcon-kodning" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Felformaterat antal token (%d) i GEmblemedIcon-kodning" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Förväntade en GEmblem för GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Innefattande montering finns inte" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Kan inte kopiera över katalog" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Kan inte kopiera katalog över katalog" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "MÃ¥lfilen finns" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Kan inte kopiera katalogen rekursivt" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Splice stöds inte" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Fel vid splice av fil: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Kopiering (reflänk/klon) mellan monteringar stöds inte" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopiering (reflänk/klon) stöds inte eller är ogiltigt" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopiering (reflänk/klon) stöds inte eller fungerade inte" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Kan inte kopiera specialfil" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Ogiltigt värde för symbolisk länk angivet" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Symboliska länkar stöds inte" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Papperskorgen stöds inte" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Filnamn fÃ¥r inte innehÃ¥lla â€%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "volymen har inte implementerat montering" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Inget program är registrerat för hantering av denna fil" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Numreraren är stängd" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Filnumreraren har kvarstÃ¥ende Ã¥tgärd" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Filnumreraren är redan stängd" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Kan inte hantera version %d av GFileIcon-kodning" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Felformaterade inmatningsdata för GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Strömmen saknar stöd för query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Sökning stöds inte pÃ¥ strömmen" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Kapning tillÃ¥ts inte pÃ¥ inmatningsströmmen" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Kapning stöds inte pÃ¥ strömmen" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Ogiltigt värdnamn" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Felaktigt HTTP-proxysvar" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP-proxyanslutning tillÃ¥ts inte" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP-proxyautentisering misslyckades" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP-proxyautentisering krävs" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP-proxyanslutning misslyckades: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP-proxysvar för stort" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP-proxyservern stängde oväntat anslutningen." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Fel antal token (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Ingen typ för klassnamnet %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Typen %s implementerar inte GIcon-gränssnittet" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Typen %s är inte klassad" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Felformaterat versionsnummer: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Typen %s implementerar inte from_tokens() pÃ¥ GIcon-gränssnittet" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Kan inte hantera angiven version av ikonkodningen" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Ingen adress angiven" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Längden %u är för lÃ¥ng för adressen" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adress har bitar inställda utanför prefixlängden" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Kunde inte tolka â€%s†som IP-adressmask" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Inte tillräckligt med utrymme för uttagsadress" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Uttagsadressen stöds inte" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Inmatningsströmmen har inte implementerat läsning" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Strömmen har kvarstÃ¥ende Ã¥tgärd" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Kopiera med fil" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "BehÃ¥ll med filen vid flyttning" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "â€version†tar inga argument" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Användning:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Skriv ut versionsinformation och avsluta." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Kommandon:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Konkatenera filer till standard ut" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Kopiera en eller flera filer" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Visa information om platser" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Starta ett program frÃ¥n en desktop-fil" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Lista innehÃ¥llet för platser" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Hämta eller sätt hanteraren för en mime-typ" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Skapa kataloger" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Övervaka filer och kataloger efter förändringar" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Montera eller avmontera platserna" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Flytta en eller flera filer" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Öppna filer med standardprogrammet" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Byt namn pÃ¥ en fil" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Ta bort en eller flera filer" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Läs frÃ¥n standard in och spara" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Sätt ett filattribut" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Flytta filer eller kataloger till papperskorgen" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Lista innehÃ¥llet för platser i ett träd" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Använd %s för att fÃ¥ detaljerad hjälp.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Fel vid skrivning till standard ut" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "PLATS" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Konkatenera filer och skriv till standard ut." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat fungerar precis som det traditionella cat-verktyget, men\n" +"använder GIO-platser istället för lokala filer: exempelvis kan du använda\n" +"nÃ¥got liknande smb://server/resurs/fil.txt som plats." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Inga platser angivna" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ingen mÃ¥lkatalog" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Visa förlopp" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "FrÃ¥ga innan överskrivning" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "BehÃ¥ll alla attribut" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Säkerhetskopiera befintliga mÃ¥lfiler" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Följ aldrig symboliska länkar" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Använd standardrättigheter för mÃ¥let" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "Överförde %s av %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "KÄLLA" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "MÃ…L" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Kopiera en eller fler filer frÃ¥n KÄLLA till MÃ…L." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy liknar det traditionella cp-verktyget, men använder\n" +"GIO-platser istället för lokala filer: exempelvis kan du använda nÃ¥got\n" +"liknande smb://server/resurs/fil.txt som plats." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "MÃ¥let %s är inte en katalog" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: skriv över â€%sâ€? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Lista skrivbara attribut" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Hämta information om filsystem" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Attributen att hämta" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUT" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Följ inte symboliska länkar" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "attribut:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "visningsnamn: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "redigeringsnamn: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "namn: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "typ: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "storlek: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "dold\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "lokal sökväg: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix-montering: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Inställningsbara attribut:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Skrivbara namnrymder för attribut:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Visa information om platser." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info liknar det traditionella ls-verktyget, men använder\n" +"GIO-platser istället för lokala filer: exempelvis kan du använda nÃ¥got\n" +"liknande smb://server/resurs/fil.txt som plats. Filattribut kan\n" +"anges med deras GIO-namn, t.ex. standard::icon, eller bara efter\n" +"namnrymd, t.ex. unix, eller med â€*†som matchar alla attribut" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "DESKTOP-FIL [FILARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Starta ett program frÃ¥n en desktop-fil, och skicka med valfria " +"filnamnsargument till det." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Ingen desktop-fil angiven" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "Startkommandot stöds för närvarande inte pÃ¥ denna plattform" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Kunde inte läsa in â€%sâ€: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Kunde inte läsa in programinformation för â€%sâ€" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Kunde inte starta programmet â€%sâ€: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Visa dolda filer" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Använd ett lÃ¥ngt listningsformat" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Skriv ut visningsnamn" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Skriv ut fullständiga URI:er" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Lista innehÃ¥llet för platserna." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list liknar det traditionella ls-verktyget, men använder\n" +"GIO-platser istället för lokala filer: exempelvis kan du använda nÃ¥got\n" +"liknande smb://server/resurs/fil.txt som plats. Filattribut kan\n" +"anges med deras GIO-namn, t.ex. standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIME-TYP" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "HANTERARE" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Hämta eller sätt hanteraren för en mime-typ." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Om ingen hanterare anges listas registrerade och rekommenderade\n" +"program för mime-typen. Om en hanterare anges sÃ¥ sätts den som\n" +"standardhanterare för mime-typen." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "MÃ¥ste ange en ensam mime-typ, och kanske en hanterare" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Inga standardprogram för â€%sâ€\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Standardprogram för â€%sâ€: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Registrerade program:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Inga registrerade program\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Rekommenderade program:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Inga rekommenderade program\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "Misslyckades med att läsa in information för hanteraren â€%sâ€" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "" +"Misslyckades med att ställa in â€%s†som standardhanterare för â€%sâ€: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Skapa överordnade kataloger" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Skapa kataloger." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir liknar det traditionella mkdir-verktyget, men använder\n" +"GIO-platser istället för lokala filer: exempelvis kan du använda nÃ¥got\n" +"liknande smb://server/resurs/minkat som plats." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Övervaka en katalog (standard: beror pÃ¥ typ)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Övervaka en fil (standard: beror pÃ¥ typ)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "Övervaka en fil direkt (upptäcker ändringar gjorda via hÃ¥rda länkar)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Övervakar en fil direkt men rapporterar inte ändringar" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Rapportera förflyttningar och namnbyten som enkla borttaget/skapat-händelser" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "Bevaka monteringshändelser" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Övervaka filer och kataloger efter förändringar." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Montera som monteringsbar" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Montera volym med enhetsfil, eller annan identifierare" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Avmontera" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Mata ut" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Stoppa enhet med enhetsfil" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ENHET" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Avmontera alla monteringar med angivet schema" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ignorera kvarstÃ¥ende filÃ¥tgärder vid avmontering eller utmatning" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Använd en anonym användare vid autentisering" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Lista" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Övervaka händelser" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Visa extra information" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "Numerisk PIM dÃ¥ en VeraCrypt-volym lÃ¥ses upp" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Montera en dold TCRYPT-volym" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Montera en TCRYPT-systemvolym" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonym Ã¥tkomst nekad" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Ingen enhet för enhetsfil" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Ingen volym för angivet ID" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Montera eller avmontera platserna." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Fall inte tillbaka pÃ¥ kopiera och ta bort" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Flytta en eller flera filer frÃ¥n KÄLLA till MÃ…L." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move liknar det traditionella mv-verktyget, men använder\n" +"GIO-platser istället för lokala filer: exempelvis kan du använda nÃ¥got\n" +"liknande smb://server/resurs/fil.txt som plats" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "MÃ¥let %s är inte en katalog" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Öppna filer med standardprogrammet som\n" +"är registrerat att hantera denna typ av filer." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ignorera obefintliga filer, frÃ¥ga aldrig" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Ta bort de angivna filerna." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAMN" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Byt namn pÃ¥ en fil." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Saknar argument" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "För mÃ¥nga argument" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Namnbyte lyckades. Ny uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Skapa endast om den inte redan finns" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Lägg till i slutet pÃ¥ filen" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "När en fil skapas, begränsa Ã¥tkomsten till den aktuella användaren" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Vid ersättning, ersätt som om mÃ¥let inte finns" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Skriv ny etag pÃ¥ slutet" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Etag för filen som skrivs över" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Fel vid läsning frÃ¥n standard in" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag finns inte tillgänglig\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Läs frÃ¥n standard in och spara till MÃ…L." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Inget mÃ¥l angivet" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Typ för attributet" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYP" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATTRIBUT" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VÄRDE" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Sätt ett filattribut för PLATS." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Platsen är inte angiven" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Attributet är inte angivet" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Värdet är inte angivet" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Ogiltig attributtyp â€%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Töm papperskorgen" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Lista filer i papperskorgen med deras ursprungliga platser" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Ã…terställ en fil frÃ¥n papperskorgen till dess ursprungliga plats (möjligen " +"genom att Ã¥terskapa katalogen)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Kunde inte hitta ursprunglig sökväg" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Kunde inte Ã¥terskapa ursprunglig plats: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Kunde inte flytta filen till dess ursprungliga plats: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Flytta/Ã¥terställ filer eller kataloger till papperskorgen." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Observera: för flaggan --restore kommer den ursprungliga platsen för filen\n" +"i papperskorgen inte skrivas över om den redan existerar, om inte --force\n" +"ställs in." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Den angivna platsen börjar inte med trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Följ symboliska länkar, monteringar och genvägar" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Lista innehÃ¥llet i kataloger i ett trädliknande format." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Elementet <%s> tillÃ¥ts inte inuti <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Elementet <%s> tillÃ¥ts inte pÃ¥ toppnivÃ¥" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Filen %s finns pÃ¥ flera ställen i resursen" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Misslyckades med att hitta â€%s†i nÃ¥gon källkatalog" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Misslyckades med att hitta â€%s†i aktuell katalog" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Okänd behandlingsflagga â€%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"Förbehandling av %s begärt, men %s inte inställt, och %s är inte i PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Fel vid läsning av filen %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Fel vid komprimering av filen %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "text fÃ¥r inte vara inuti <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Visa programversion och avsluta" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Namn pÃ¥ utmatningsfilen" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Katalogerna där filer som hänvisas till i FIL ska läsas frÃ¥n (standard: " +"aktuell katalog)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "KATALOG" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Generera utmatning i formatet valt av mÃ¥lfilnamnets filändelse" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Generera källkods-header" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "Generera källkod som används för att länka in resursfilen i din kod" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Generera beroendelista" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Namn pÃ¥ beroendefilen att generera" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Inkludera phony-mÃ¥l i den genererade beroendefilen" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Skapa och registrera inte resursen automatiskt" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Exportera inte funktioner; deklarera dem som G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Bädda inte in resursdata i C-filen; anta att de är länkade externt istället" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C-identifierarnamn som används för den genererade källkoden" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "MÃ¥l-C-kompilatorn (standard: CC-miljövariabeln)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Kompilera en resursspecifikation till en resursfil.\n" +"Resursspecifikationsfiler har filändelsen .gresource.xml,\n" +"och resursfilen har filändelsen .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Du bör ange exakt ett filnamn\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "smeknamn mÃ¥ste bestÃ¥ av minst 2 tecken" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Ogiltigt numeriskt värde" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " redan angivet" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' redan angivet" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "flaggvärden fÃ¥r ha högst 1 bit satt" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> mÃ¥ste innehÃ¥lla minst ett " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> ligger inte i det angivna intervallet" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> är inte en giltig medlem av den angivna uppräkningstypen" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> innehÃ¥ller sträng som inte finns i angiven flaggtyp" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> innehÃ¥ller en sträng som inte finns i " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " redan angivet för denna nyckel" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " inte tillÃ¥tet för nycklar av typen â€%sâ€" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "angivet minimum för är större än maximum" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "l10n-kategori som inte stöds: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n begärt, men ingen gettext-domän angiven" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "översättningskontext angiven för värde utan att l10n är aktiverat" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Misslyckades med att tolka -värde av typen â€%sâ€: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" kan inte anges för nycklar som taggats som att de är av " +"uppräkningstyp" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " redan angivet för denna nyckel" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " inte tillÃ¥tet för nycklar av typen â€%sâ€" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " redan angivet" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " mÃ¥ste innehÃ¥lla minst ett " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " redan angivet för denna nyckel" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" kan endast anges för nycklar med uppräknings- eller flaggtyp eller " +"efter " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +" angivet dÃ¥ â€%s†redan är en medlem av uppräkningstypen" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" angavs när redan hade angivits" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " redan angivet" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "aliasmÃ¥let â€%s†finns inte i uppräkningstyp" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "aliasmÃ¥l â€%s†finns inte " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " mÃ¥ste innehÃ¥lla minst ett " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Tomma namn tillÃ¥ts inte" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Ogiltigt namn â€%sâ€: namn mÃ¥ste börja med en liten bokstav" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Ogiltigt namn â€%sâ€: ogiltigt tecken â€%câ€; endast gemena bokstäver, siffror " +"och bindestreck (â€-â€) tillÃ¥ts" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Ogiltigt namn â€%sâ€: tvÃ¥ efterföljande bindestreck (â€--â€) tillÃ¥ts inte" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Ogiltigt namn â€%sâ€: sista tecknet fÃ¥r inte vara ett bindestreck (â€-â€)" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Ogiltigt namn â€%sâ€: maximal längd är 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " redan angiven" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Kan inte lägga till nycklar till ett â€list-ofâ€-schema" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " redan angiven" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" skuggar i ; använd " +" för att ändra värdet" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"Exakt en av â€typeâ€, â€enum†eller â€flags†mÃ¥ste anges som ett attribut till " +"" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> inte (ännu) angiven." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Ogiltig GVariant-typsträng â€%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " angavs men schemat utökar inte nÃ¥gonting" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Ingen att Ã¥sidosätta" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " redan angiven" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " redan angiven" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " utökar ännu inte befintliga schemat â€%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " är lista av ännu inte befintliga schemat â€%sâ€" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Kan inte vara en lista för ett schema med en sökväg" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Kan inte utöka ett schema med en sökväg" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" är en lista, som utökar vilket inte är en " +"lista" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" utökar men â€%s†" +"utökar inte â€%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "En sökväg, om angiven, mÃ¥ste börja och sluta med ett snedstreck" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Sökvägen för en lista mÃ¥ste sluta med â€:/â€" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Varning: Schemat â€%s†har sökvägen â€%sâ€. Sökvägar som startar med â€/apps/â€, " +"â€/desktop/†eller â€/system/†är förÃ¥ldrade." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> redan angiven" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Endast ett <%s>-element tillÃ¥ts inuti <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Elementet <%s> tillÃ¥ts inte pÃ¥ toppnivÃ¥n" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Elementet krävs i " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "Text fÃ¥r inte vara inuti <%s>" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Varning: odefinierad referens till " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict angavs; avslutar." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Hela denna fil har ignorerats." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ignorerar denna fil." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Ingen sÃ¥dan nyckel â€%s†i schemat â€%s†som angetts i Ã¥sidosättningsfilen " +"â€%sâ€; ignorerar Ã¥sidosättning för denna nyckel." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Ingen sÃ¥dan nyckel â€%s†i schemat â€%s†som angetts i Ã¥sidosättningsfilen " +"â€%s†och --strict angavs; avslutar." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Det gÃ¥r inte att tillhandahÃ¥lla Ã¥sidosättningar per skrivbord för den " +"lokaliserade nyckeln â€%s†i schemat â€%s†(Ã¥sidosättningsfil â€%sâ€); ignorerar " +"Ã¥sidosättning för denna nyckel." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Det gÃ¥r inte att tillhandahÃ¥lla Ã¥sidosättningar per skrivbord för den " +"lokaliserade nyckeln â€%s†i schemat â€%s†(Ã¥sidosättningsfil â€%sâ€) och --" +"strict angavs; avslutar." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Fel vid tolkning av nyckeln â€%s†i schemat â€%s†som angetts i " +"Ã¥sidosättningsfilen â€%sâ€: %s. Ignorerar Ã¥sidosättning för denna nyckel." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Fel vid tolkning av nyckeln â€%s†i schemat â€%s†som angetts i " +"Ã¥sidosättningsfilen â€%sâ€: %s. --strict angavs; avslutar." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Ã…sidosättning för nyckeln â€%s†i schemat â€%s†i Ã¥sidosättningsfilen â€%s†är " +"utanför intervallet som anges i schemat; ignorerar Ã¥sidosättning för denna " +"nyckel." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Ã…sidosättning för nyckeln â€%s†i schemat â€%s†i Ã¥sidosättningsfilen â€%s†är " +"utanför intervallet som anges i schemat och --strict angavs; avslutar." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Ã…sidosättning för nyckeln â€%s†i schemat â€%s†i Ã¥sidosättningsfilen â€%s†" +"finns inte i listan över giltiga val; ignorerar Ã¥sidosättning för denna " +"nyckel." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Ã…sidosättning för nyckeln â€%s†i schemat â€%s†i Ã¥sidosättningsfilen â€%s†" +"finns inte i listan över giltiga val och --strict angavs; avslutar." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "Var filen gschemas.compiled ska lagras" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Avbryt vid alla fel i scheman" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Skriv inte filen gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Tvinga inte igenom begränsningar för nyckelnamn" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Kompilera alla GSettings-schemafiler till en schemacache.\n" +"Schemafiler mÃ¥ste ha filändelsen .gschema.xml,\n" +"och cachefilen kallas för gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Du bör ange exakt ett katalognamn" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Inga schemafiler hittades: gör ingenting." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Inga schemafiler hittades: tog bort befintlig utmatningsfil." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Ogiltigt filnamn %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Fel vid hämtning av filsystemsinformation för %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Innefattande montering för filen %s hittades inte" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Kan inte byta namn pÃ¥ rotkatalog" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Fel vid namnbyte av filen %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Kan inte byta namn pÃ¥ filen, filnamnet finns redan" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Ogiltigt filnamn" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Fel vid öppning av filen %s: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Fel vid borttagning av filen %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Fel vid kastande av filen %s: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Kunde inte skapa papperskorgskatalogen %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Kunde inte hitta toppnivÃ¥katalog för att kasta %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Att kasta i papperskorg pÃ¥ systeminterna monteringar stöds inte" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Kunde inte hitta eller skapa papperskorgskatalog %s att slänga %s i" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "Kunde inte skapa fil med information om vad som kastats för %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Kunde inte kasta filen %s över filsystemsgränser" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Kunde inte kasta filen %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Kunde inte kasta filen %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "Fel vid skapandet av katalogen %s: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Filsystemet saknar stöd för symboliska länkar" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Fel vid skapande av symboliska länken %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Fel vid flyttning av filen %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Kan inte flytta katalog över katalog" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Misslyckades med att skapa säkerhetskopiefil" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Fel vid borttagning av mÃ¥lfil: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "Flyttning mellan monteringar stöds inte" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Kunde inte bestämma diskanvändningen för %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Attributvärde mÃ¥ste vara icke-NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Ogiltig attributtyp (sträng förväntades)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Ogiltigt utökat attributnamn" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Fel vid inställning av utökat attribut â€%sâ€: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (ogiltig kodning)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Fel vid hämtning av information om filen â€%sâ€: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Fel vid hämtning av information om filhandtag: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ogiltig attributtyp (uint32 förväntades)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ogiltig attributtyp (uint64 förväntades)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ogiltig attributtyp (bytesträng förväntades)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Kan inte ställa in rättigheter pÃ¥ symboliska länkar" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Fel vid inställning av rättigheter: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Fel vid inställning av ägare: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "symbolisk länk mÃ¥ste vara icke-NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Fel vid inställning av symbolisk länk: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Fel vid inställning av symbolisk länk: filen är inte en symbolisk länk" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Extra nanosekunder %d för UNIX-tidsstämpeln %lld är negativa" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "Extra nanosekunder %d för UNIX-tidsstämpeln %lld överstiger 1 sekund" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX-tidstämpeln %lld ryms inte i 64 bitar" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "UNIX-tidstämpeln %lld är utanför intervallet som stöds av Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Filnamnet â€%s†kan inte konverteras till UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Filen â€%s†kan inte öppnas: Windows-fel %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Fel vid inställning av ändrings- eller Ã¥tkomsttid för filen â€%sâ€: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Fel vid inställning av ändrings- eller Ã¥tkomsttid: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux-kontext mÃ¥ste vara icke-NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux är inte aktiverat pÃ¥ detta system" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Fel vid inställning av SELinux-kontext: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Inställning av attributet %s stöds inte" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Fel vid läsning frÃ¥n fil: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Fel vid stängning av fil: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Fel vid sökning i fil: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Kunde inte hitta standardtyp för lokal filövervakare" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Fel vid skrivning till fil: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Fel vid borttagning av gamla länk till säkerhetskopia: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Fel vid skapande av säkerhetskopia: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Fel vid namnbyte pÃ¥ temporärfil: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Fel vid kapning av fil: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Fel vid öppning av filen â€%sâ€: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "MÃ¥lfilen är en katalog" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "MÃ¥lfilen är inte en vanlig fil" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Filen blev externt ändrad" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Fel vid borttagning av gammal fil: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Ogiltig GSeekType angavs" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Ogiltig sökbegäran" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Kan inte kapa av GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Storlek för minnesutmatningsström är inte ändringsbar" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Misslyckades med att ändra storlek pÃ¥ minnesutmatningsström" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Den mängd minne som krävs för att behandla skrivningen är större än " +"tillgänglig adressrymd" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Begärde sökning innan början av strömmen" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Begärde sökning bortom slutet av strömmen" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "mount har inte implementerat â€unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "mount har inte implementerat â€ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "mount har inte implementerat â€unmount†eller â€unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "mount har inte implementerat â€eject†eller â€eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "mount har inte implementerat â€remountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "mount har inte implementerat estimering av innehÃ¥llstyp" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "mount har inte implementerat synkron estimering av innehÃ¥llstyp" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Värdnamnet â€%s†innehÃ¥ller â€[†men inte â€]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Nätverket är inte nÃ¥bart" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Värddatorn är inte nÃ¥bar" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Kunde inte skapa nätverksövervakare: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Kunde inte skapa nätverksövervakare: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Kunde inte fÃ¥ nätverksstatus: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "Nätverkshanteraren är inte igÃ¥ng" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "Nätverkshanterare är för gammal" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Utmatningsström har inte implementerat skrivning" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Summan av vektorer skickade till %s är för stor" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Källströmmen är redan stängd" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Fel vid uppslag av â€%sâ€: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s inte implementerad" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Ogiltig domän" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "Resursen pÃ¥ â€%s†finns inte" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Resursen pÃ¥ â€%s†gick inte att dekomprimera" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "Resursen pÃ¥ â€%s†är inte en katalog" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Inmatningsströmmen har inte implementerat spolning" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Lista sektioner som innehÃ¥ller resurser i en elf-FIL" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Lista resurser\n" +"Om SEKTION anges, lista endast resurser i denna sektion\n" +"Om SÖKVÄG anges, lista endast matchande resurser" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "FIL [SÖKVÄG]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "SEKTION" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Lista resurser med detaljer\n" +"Om SEKTION anges, lista endast resurser i denna sektion\n" +"Om SÖKVÄG anges, lista endast matchande resurser\n" +"Detaljer inkluderar sektionen, storlek och komprimering" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Extrahera en resursfil till standard ut" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "FIL SÖKVÄG" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Användning:\n" +" gresource [--section SEKTION] KOMMANDO [ARG…]\n" +"\n" +"Kommandon:\n" +" help Visa denna information\n" +" sections Lista resurssektioner\n" +" list Lista resurser\n" +" details Lista resurser med detaljer\n" +" extract Extrahera en resurs\n" +"\n" +"Använd â€gresource help KOMMANDO†för detaljerad hjälp.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Användning:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " SEKTION Ett (eventuellt) elf-sektionsnamn\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMMANDO (Eventuellt) kommando att förklara\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FIL En elf-fil (en binär eller ett delat bibliotek)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FIL En elf-fil (en binär eller ett delat bibliotek)\n" +" eller en kompilerad resursfil\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[SÖKVÄG]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " SÖKVÄG En (eventuell) resurssökväg (kan vara partiell)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "SÖKVÄG" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " SÖKVÄG En resurssökväg\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Inget sÃ¥dant schema â€%sâ€\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Schemat â€%s†är inte flyttbart (sökvägen fÃ¥r inte anges)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Schemat â€%s†är flyttbart (sökvägen mÃ¥ste anges)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Tom sökväg angavs.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Sökvägen mÃ¥ste börja med ett snedstreck (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Sökvägen mÃ¥ste sluta med ett snedstreck (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Sökvägen fÃ¥r inte innehÃ¥lla tvÃ¥ efterföljande snedstreck (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "TillhandahÃ¥llet värde är utanför det giltiga intervallet\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Nyckeln är inte skrivbar\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Lista installerade (icke-flyttbara) scheman" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Lista installerade, flyttbara scheman" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Lista nycklarna i SCHEMA" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:SÖKVÄG]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Lista barnen i SCHEMA" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Lista nycklar och värden, rekursivt\n" +"Om inget SCHEMA anges, lista alla nycklar\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:SÖKVÄG]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "FÃ¥ värdet för NYCKEL" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:SÖKVÄG] NYCKEL" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "FrÃ¥ga efter giltiga värden för NYCKEL" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "FrÃ¥ga efter beskrivningen för NYCKEL" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "Ställ in värdet för NYCKEL till VÄRDE" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:SÖKVÄG] NYCKEL VÄRDE" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Ã…terställ NYCKEL till dess standardvärde" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Nollställ alla nycklar i SCHEMA till sina standardvärden" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Kontrollera om NYCKEL är skrivbar" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Övervaka NYCKEL efter ändringar.\n" +"Om ingen NYCKEL anges, övervaka alla nycklar i SCHEMA.\n" +"Använd ^C för att avsluta övervakningen.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:SÖKVÄG] [NYCKEL]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Användning:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMAKAT] KOMMANDO [ARG…]\n" +"\n" +"Kommandon:\n" +" help Visa denna information\n" +" list-schemas Lista installerade scheman\n" +" list-relocatable-schemas Lista flyttbara scheman\n" +" list-keys Lista nycklar i ett schema\n" +" list-children Lista barn av ett schema\n" +" list-recursively Lista nycklar och värden, rekursivt\n" +" range FrÃ¥gar efter intervallet för en nyckel\n" +" describe FrÃ¥gar efter beskrivningen för en nyckel\n" +" get Hämta värdet för en nyckel\n" +" set Ställ in värdet för en nyckel\n" +" reset Ã…terställ värdet för en nyckel\n" +" reset-recursively Ã…terställ alla värden i ett angivet schema\n" +" writable Kontrollera om en nyckel är skrivbar\n" +" monitor Bevaka ändringar\n" +"\n" +"Använd â€gsettings help KOMMANDO†för detaljerad hjälp.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Användning:\n" +" gsettings [--schemadir SCHEMAKAT] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMAKAT En katalog att söka i efter ytterligare scheman\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA Namnet pÃ¥ schemat\n" +" SÖKVÄG Sökvägen, för flyttbara scheman\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " NYCKEL (Eventuell) nyckel inom schemat\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " NYCKEL Nyckeln inom schemat\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " VÄRDE Värdet att ställa in\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Kunde inte läsa in schema frÃ¥n %s: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Inga scheman installerade\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Tomt schemanamn angavs\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Ingen sÃ¥dan nyckel â€%sâ€\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Ogiltigt uttag, inte initierat" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Ogiltigt uttag, initiering misslyckades pÃ¥ grund av: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Uttaget är redan stängt" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Tidsgräns för in/ut pÃ¥ uttaget överstegs" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "skapar GSocket frÃ¥n fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Kunde inte skapa uttag: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Okänd familj angavs" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Okänt protokoll angavs" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Kan inte använda datagramÃ¥tgärder pÃ¥ ett icke-datagram-uttag." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "Kan inte använda datagramÃ¥tgärder pÃ¥ ett uttag med en satt tidsgräns." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "kunde inte fÃ¥ lokal adress: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "kunde inte fÃ¥ fjärradress: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "kunde inte lyssna: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Fel vid bindning till adressen %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Fel vid medlemskap i multicast-grupp: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Fel vid lämnande av multicast-grupp: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "Inget stöd för källspecifik multicast" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Uttagsfamiljen stöds inte" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "källspecifik är inte en IPv4-adress" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Gränssnittsnamnet är för lÃ¥ngt" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Gränssnitt hittades inte: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "Inget stöd för IPv4-källspecifik multicast" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "Inget stöd för IPv6-källspecifik multicast" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Fel vid godkännande av anslutning: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "Anslutningsförsök pÃ¥gÃ¥r" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Kunde inte fÃ¥ tag pÃ¥ väntande fel: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Fel vid mottagning av data: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Fel vid sändning av data: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Kunde inte stänga ner uttag: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Fel vid stängning av uttag: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Väntar pÃ¥ uttagstillstÃ¥nd: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Kunde inte skicka meddelande: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Meddelandevektorerna är för stora" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Fel vid sändning av meddelande: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage stöds inte pÃ¥ Windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Fel vid mottagning av meddelande: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Kunde inte läsa uttagets inloggningsuppgifter: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" +"g_socket_get_credentials har inte implementerats för detta operativsystem" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Kunde inte ansluta till proxyservern %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Kunde inte ansluta till %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Kunde inte ansluta: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Att skicka via proxy över en icke-TCP-anslutning stöds inte." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Proxyprotokollet â€%s†stöds inte." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Lyssnaren är redan stängd" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Tillagt uttag är stängt" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 saknar stöd för IPv6-adressen â€%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Användarnamnet är för lÃ¥ngt för SOCKSv4-protokollet" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Värdnamnet â€%s†är för lÃ¥ngt för SOCKSv4-protokollet" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Servern är inte en SOCKSv4-proxyserver." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Anslutningen genom SOCKSv4-servern nekades" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Servern är inte en SOCKSv5-proxyserver." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5-proxyservern kräver autentisering." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 kräver en autentiseringsmetod som inte stöds av GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Användarnamn eller lösenord är för lÃ¥ngt för SOCKSv5-protokollet." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"SOCKSv5-autentiseringen misslyckades pÃ¥ grund av felaktigt användarnamn " +"eller lösenord." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Värdnamnet â€%s†är för lÃ¥ngt för SOCKSv5-protokollet" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5-proxyservern använder en okänd adresstyp." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Internt fel i SOCKSv5-proxyserver." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5-anslutning tillÃ¥ts inte av regeluppsättningen." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Värden är inte nÃ¥bar genom SOCKSv5-servern." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Nätverket är inte nÃ¥bart genom SOCKSv5-proxyservern." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Anslutningen nekades genom SOCKSv5-proxyservern." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5-proxyservern saknar stöd för kommandot â€connectâ€." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5-proxyservern saknar stöd för angiven adresstyp." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Okänt fel i SOCKSv5-proxyserver." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Misslyckades med att skapa rör för kommunikation med barnprocess (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Rör stöds inte pÃ¥ denna plattform" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Kan inte hantera version %d av GThemedIcon-kodning" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Inga giltiga adresser hittades" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Fel vid omvänt uppslag av â€%sâ€: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "Fel vid tolkning av DNS %s-post: felformulerat DNS-paket" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Inga DNS-poster av den begärda typen för â€%sâ€" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Kan för tillfället inte slÃ¥ upp â€%sâ€" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Fel vid uppslag av â€%sâ€" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Felformulerat DNS-paket" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Misslyckades med att tolka DNS-svar för â€%sâ€: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Ingen PEM-kodad privat nyckel hittades" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Kan inte dekryptera PEM-kodad privat nyckel" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Kunde inte tolka PEM-kodad privat nyckel" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Inget PEM-kodat certifikat hittades" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Kunde inte tolka PEM-kodat certifikat" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Den aktuella TLS-bakänden stöder inte PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "Denna GTlsBackend stöder inte skapande av PKCS #11-certifikat" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Detta är sista chansen att ange ett korrekt lösenord innan ditt konto blir " +"lÃ¥st." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Flera felaktiga lösenord har angivits och din Ã¥tkomst kommer att lÃ¥sas efter " +"ytterligare misslyckanden." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Det angivna lösenordet är felaktigt." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Sändning av FD stöds inte" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Förväntade 1 kontrollmeddelande, fick %d" +msgstr[1] "Förväntade 1 kontrollmeddelande, fick %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Oväntad typ av underordnade data" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Förväntade en fd, men fick %d\n" +msgstr[1] "Förväntade en fd, men fick %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Tog emot ogiltig fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Mottagning av FD stöds inte" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Fel vid sändning av inloggningsuppgifter: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Fel vid kontroll om SO_PASSCRED har aktiverats för uttaget: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Fel vid aktivering av SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Förväntade att läsa ett enda byte för mottagning av inloggningsuppgifter men " +"läste noll byte" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Förväntade inte kontrollmeddelande, men fick %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Fel vid inaktivering av SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Fel vid läsning frÃ¥n filhandtag: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Fel vid stängning av filhandtag: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Filsystemsrot" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Fel vid skrivning till filhandtag: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Abstrakta UNIX-domänuttagsadresser stöds inte pÃ¥ detta system" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "volymen har inte implementerat eject" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "volymen har inte implementerat eject eller eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Fel vid läsning frÃ¥n handtag: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Fel vid stängning av handtag: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Fel vid skrivning till handtag: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Slut pÃ¥ minne" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Internt fel: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Behöver mer inmatning" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Ogiltiga komprimerade data" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Adress att lyssna pÃ¥" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Ignorerad, för kompatibilitet med GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Skriv ut adress" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Skriv ut adress i skalläge" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Kör en dbustjänst" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Fel argument\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Oväntat attribut â€%s†för elementet â€%sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Attributet â€%s†för elementet â€%s†hittades inte" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Oväntad tagg â€%sâ€, taggen â€%s†förväntades" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Oväntad tagg â€%s†inom â€%sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Ogiltigt datum/tid â€%s†i bokmärkesfil" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Ingen giltig bokmärkesfil hittades i datakataloger" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Ett bokmärke för URI â€%s†finns redan" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Inget bokmärke hittades för URI â€%sâ€" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Ingen Mime-typ definierad i bokmärket för URI â€%sâ€" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Ingen privat flagga har definierats i bokmärket för URI â€%sâ€" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Inga grupper inställda i bokmärket för URI â€%sâ€" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Inget program med namnet â€%s†registrerade ett bokmärke för â€%sâ€" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Misslyckades med att expandera exec-raden â€%s†med URI â€%sâ€" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Tecken som ej gÃ¥r att uttrycka i konverteringsindata" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Ofullständig teckensekvens vid slutet av indata" + +# fallback syftar pÃ¥ en sträng +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Kan inte konvertera reservsträngen â€%s†till kodningen â€%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Inbäddad NUL-byte i konverteringsindata" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Inbäddad NUL-byte i konverteringsutdata" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI:n â€%s†är ingen absolut URI som använder â€fileâ€-schemat" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Lokala fil-URI:n â€%s†fÃ¥r inte innehÃ¥lla en â€#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI:n â€%s†är ogiltig" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Värdnamnet i URI:n â€%s†är ogiltigt" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI:n â€%s†innehÃ¥ller ogiltigt kodade tecken" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Sökvägen â€%s†är ingen absolut sökväg" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e %b %Y %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%y-%m-%d" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Januari" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Februari" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Mars" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "April" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Maj" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Juni" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Juli" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Augusti" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "September" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Oktober" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "November" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "December" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Jan" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Feb" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Apr" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Maj" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Jun" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Jul" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Aug" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Sep" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Okt" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Nov" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Dec" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "MÃ¥ndag" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Tisdag" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Onsdag" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Torsdag" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Fredag" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Lördag" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Söndag" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "MÃ¥n" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Tis" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ons" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Tor" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Fre" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Lör" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Sön" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "januari" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "februari" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "mars" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "april" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "juni" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "juli" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "augusti" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "september" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "oktober" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "november" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "december" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "jan" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "feb" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "apr" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "maj" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "jun" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "jul" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "aug" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "sep" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "okt" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "nov" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "dec" + +# Enligt ICU-locale: https://www.localeplanet.com/icu/sv/index.html +# Glibc är istället tom: https://lh.2xlibre.net/locale/sv_SE/ +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "fm" + +# Enligt ICU-locale: https://www.localeplanet.com/icu/sv/index.html +# Glibc är istället tom: https://lh.2xlibre.net/locale/sv_SE/ +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "em" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Fel vid öppning av katalogen â€%sâ€: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Kunde inte allokera %lu byte för att läsa filen â€%sâ€" +msgstr[1] "Kunde inte allokera %lu byte för att läsa filen â€%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Fel vid läsning av filen â€%sâ€: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Filen â€%s†är för stor" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Misslyckades med att läsa frÃ¥n filen â€%sâ€: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Misslyckades med att öppna filen â€%sâ€: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"Misslyckades med att fÃ¥ tag pÃ¥ attributen pÃ¥ filen â€%sâ€: fstat() " +"misslyckades: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Misslyckades med att öppna filen â€%sâ€: fdopen() misslyckades: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"Misslyckades med att byta namn pÃ¥ filen â€%s†till â€%sâ€: g_rename() " +"misslyckades: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Misslyckades med att skriva filen â€%sâ€: write() misslyckades: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Misslyckades med att skriva filen â€%sâ€: fsync() misslyckades: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Misslyckades med att skapa filen â€%sâ€: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Befintliga filen â€%s†kunde inte tas bort: g_unlink() misslyckades: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Mallen â€%s†är ogiltig, den fÃ¥r inte innehÃ¥lla ett â€%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Mallen â€%s†innehÃ¥ller inte XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Misslyckades med att läsa den symboliska länken â€%sâ€: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Kunde inte öppna konverteraren frÃ¥n â€%s†till â€%sâ€: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "Kan inte göra en rÃ¥ läsning i g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Överblivna okonverterade data i läsbufferten" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanalen slutar med ett ofullständigt tecken" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "Kan inte göra en rÃ¥ läsning i g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Giltig nyckelfil kunde inte hittas i sökkatalogerna" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Inte en vanlig fil" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Nyckelfilen innehÃ¥ller raden â€%s†som inte är ett nyckel-värde-par, grupp " +"eller kommentar" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ogiltigt gruppnamn: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Nyckelfilen börjar inte med en grupp" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Ogiltigt nyckelnamn: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Nyckelfilen innehÃ¥ller kodningen â€%s†som inte stöds" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Nyckelfilen har inte gruppen â€%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Nyckelfilen har inte nyckeln â€%s†i gruppen â€%sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Nyckelfilen innehÃ¥ller nyckeln â€%s†med värdet â€%s†som inte är UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Nyckelfilen innehÃ¥ller nyckeln â€%s†som innehÃ¥ller ett värde som inte kan " +"tolkas." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Nyckelfilen innehÃ¥ller nyckeln â€%s†i gruppen â€%s†vilken innehÃ¥ller ett " +"värde som inte kan tolkas." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Nyckeln â€%s†i gruppen â€%s†innehÃ¥ller värdet â€%s†där %s förväntades" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Nyckelfilen innehÃ¥ller kontrolltecken i slutet pÃ¥ en rad" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Nyckelfilen innehÃ¥ller ogiltiga kontrollsekvensen â€%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Värdet â€%s†kan inte tolkas som ett tal." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "Heltalsvärdet â€%s†är utanför intervallet" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Värdet â€%s†kan inte tolkas som ett flyttal." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Värdet â€%s†kan inte tolkas som ett booleskt värde." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Misslyckades med att fÃ¥ attribut för filen â€%s%s%s%sâ€: fstat() misslyckades: " +"%s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Misslyckades med att mappa %s%s%s%s: mmap() misslyckades: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Misslyckades med att öppna filen â€%sâ€: open() misslyckades: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Fel pÃ¥ rad %d tecken %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Ogiltig UTF-8-kodad text i namnet — inte giltig â€%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "â€%s†är inte ett giltigt namn" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "â€%s†är inte ett giltigt namn: â€%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Fel pÃ¥ rad %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Misslyckades med att tolka â€%-.*sâ€, som skulle ha varit en siffra inuti en " +"teckenreferens (ê till exempel) — siffran är kanske för stor" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Teckenreferensen slutade inte med ett semikolon. Troligtvis använde du ett &-" +"tecken utan att avse att starta en entitet. Skriv om &-tecknet som &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Teckenreferensen â€%-.*s†kodar inte ett tillÃ¥tet tecken" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"Tom entitet â€&;†hittades, giltiga entiteter är: & " < > " +"'" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Entitetsnamnet â€%-.*s†är okänt" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entiteten slutade inte med ett semikolon. Troligtvis använde du ett &-tecken " +"utan att avse att starta en entitet. Skriv om &-tecknet som &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Dokumentet mÃ¥ste börja med ett element (exempelvis )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"â€%s†är inte ett giltigt tecken efter ett â€<â€-tecken. Det fÃ¥r inte inleda " +"ett elementnamn" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Konstigt tecken â€%sâ€, ett â€>â€-tecken förväntades för att avsluta tomma " +"elementtaggen â€%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "För mÃ¥nga attribut i elementet â€%sâ€" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Konstigt tecken â€%sâ€, ett â€=†förväntades efter attributnamnet â€%s†till " +"elementet â€%sâ€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Konstigt tecken â€%sâ€, ett â€>â€- eller â€/â€-tecken förväntades för att avsluta " +"starttaggen för elementet â€%sâ€, eller möjligtvis ett attribut. Du kanske " +"använde ett ogiltigt tecken i ett attributnamn" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Konstigt tecken â€%sâ€, ett startcitationstecken förväntades efter " +"likhetstecknet när värdet av attributet â€%s†till elementet â€%s†tilldelades" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"â€%s†är inte ett giltigt tecken efter stängelementnamnet â€%sâ€. Det tillÃ¥tna " +"tecknet är â€>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Elementet â€%s†stängdes, inget element är öppet för tillfället" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "" +"Elementet â€%s†stängdes, men det element som är öppet för tillfället är â€%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Dokumentet var tomt eller innehöll endast tomrum" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Dokumentet tog oväntat slut efter ett öppningsklammer â€<â€" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Dokumentet tog oväntat slut dÃ¥ element fortfarande var öppna. â€%s†var det " +"senast öppnade elementet" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Dokumentet tog oväntat slut, en stängningsklammer förväntades för att " +"avsluta taggen <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Dokumentet tog oväntat slut inuti ett elementnamn" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Dokumentet tog oväntat slut inuti ett attributnamn" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Dokumentet tog oväntat slut inuti en elementöppnande tagg." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Dokumentet tog oväntat slut efter likhetstecknet som följde ett " +"attributnamn. Inget attributvärde" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Dokumentet tog oväntat slut inuti ett attributvärde" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Dokumentet tog oväntat slut inuti stängningstaggen för elementet â€%sâ€" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Dokumentet tog oväntat slut inuti stängningstaggen för ett oöppnat element" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Dokumentet tog oväntat slut inuti en kommentar eller behandlingsinstruktion" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[FLAGGA…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Hjälpflaggor:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Visa hjälpflaggor" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Visa alla hjälpflaggor" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Programflaggor:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Flaggor:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Kan inte tolka heltalsvärdet â€%s†för %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "Heltalsvärdet â€%s†för %s är utanför intervallet" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Kan inte tolka dubbelvärdet â€%s†för %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "Dubbelvärdet â€%s†för %s är utanför intervallet" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Fel vid tolkning av flaggan %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "Argument saknas för %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Okänd flagga %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "skadat objekt" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "internt fel eller skadat objekt" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "slut pÃ¥ minne" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "bakÃ¥tspÃ¥rningsgräns nÃ¥dd" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "mönstret innehÃ¥ller objekt som inte stöds för delvis matchning" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "internt fel" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "bakreferenser som villkor stöds inte för delvis matchning" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "rekursionsgräns nÃ¥dd" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "ogiltig kombination av nyradsflaggor" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "felaktig offset" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "kort utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "rekursionsloop" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "okänt fel" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ pÃ¥ slutet av mönster" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c pÃ¥ slutet av mönster" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "okänt tecken efter \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "tal är inte i ordning i {}-kvantifierare" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "tal för stort i {}-kvantifierare" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "saknar avslutande ] för teckenklass" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "ogiltig escape-sekvens i teckenklass" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "intervall är inte i ordning i teckenklass" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "ingenting att upprepa" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "oväntad upprepning" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "okänt tecken efter (? eller (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX-namngivna klasser stöds endast inom en klass" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "saknar avslutande )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "referens till icke-existerande undermönster" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "saknar ) efter kommentar" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "reguljärt uttryck är för stort" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "misslyckades med att fÃ¥ minne" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") utan öppnande (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "överflöde i kod" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "okänt tecken efter (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind-assertion är inte av fast längd" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "felformulerat tal eller namn efter (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "villkorsgrupp innehÃ¥ller fler än tvÃ¥ grenar" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "assertion förväntades efter (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R eller (?[+-]siffror mÃ¥ste efterföljas av )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "okänt POSIX-klassnamn" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX-sorteringselement stöds inte" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "teckenvärde i \\x{…}-sekvens är för stort" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "ogiltigt tillstÃ¥nd (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C tillÃ¥ts inte i lookbehind-assertion" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapesekvenser \\L, \\l, \\N{namn}, \\U, och \\u stöds inte" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "rekursivt anrop kan gÃ¥ in i en oändlig slinga" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "okänt tecken efter (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "saknar avslutstecken i undermönstrets namn" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "tvÃ¥ namngivna undermönster har samma namn" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "felformulerad \\P eller \\p-sekvens" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "okänt egenskapsnamn efter \\P eller \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "undermönstrets namn är för lÃ¥ngt (maximalt 32 tecken)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "för mÃ¥nga namngivna undermönster (maximalt 10 000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "oktalt värde är större än \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "fyllde över kompileringsutrymme" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "tidigare kontrollerad refererande undermönster hittades inte" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE-grupp innehÃ¥ller fler än en gren" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "inkonsistenta NEWLINE-flaggor" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g följs inte av ett namn inom klammerparentes, vinkelparentes eller " +"citattecken eller siffra, eller en enkel siffra" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "en numrerad referens fÃ¥r inte vara noll" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "ett argument tillÃ¥ts inte för (*ACCEPT), (*FAIL) eller (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) kändes inte igen" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "tal är för stort" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "saknar undermönsternamn efter (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "siffra förväntas efter (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] är ett ogiltigt datatecken i JavaScript-kompatibilitetsläge" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "olika namn för undermönster för samma siffra är inte tillÃ¥tet" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) mÃ¥ste ha ett argument" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c mÃ¥ste följas av ett ASCII-tecken" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k följs inte av ett namn inom klammerparentes, vinkelparentes eller " +"citattecken" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N är saknar stöd i en klass" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "alltför mÃ¥nga framÃ¥treferenser" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "namn är alltför lÃ¥ngt i (*MARK), (*PRUNE), (*SKIP) eller (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "teckenvärde i \\u....-sekvens är för stort" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Fel vid matchning av reguljära uttrycket %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE-biblioteket är byggt utan stöd för UTF8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE-biblioteket är byggt utan stöd för UTF8-egenskaper" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE-biblioteket är byggt med inkompatibla alternativ" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Fel vid optimering av reguljära uttrycket %s: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Fel vid kompilering av reguljära uttrycket %s vid tecknet %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "hexadecimal siffra eller â€}†förväntades" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "hexadecimal siffra förväntades" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "saknar â€<†i symbolisk referens" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "oavslutad symbolisk referens" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "symbolisk referens med noll-längd" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "siffra förväntades" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "otillÃ¥ten symbolisk referens" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "felplacerad avslutande â€\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "okänd escape-sekvens" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Fel vid tolkning av ersättningstexten â€%s†vid tecknet %lu: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Citerad text börjar inte med citationstecken" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Ensamt citationstecken pÃ¥ kommandoraden eller annan skalciterad text" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Texten slutade efter ett â€\\â€-tecken (texten var â€%sâ€)." + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"Texten slutade innan matchande citationstecken hittades för %c (texten var " +"â€%sâ€)." + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Texten var tom (eller innehöll bara tomrum)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Misslyckades med att läsa data frÃ¥n barnprocess (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Oväntat fel vid läsning av data frÃ¥n en barnprocess (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Oväntat fel i waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Barnprocess avslutades med kod %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Barnprocess dödat av signal %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Barnprocess stoppad av signal %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Barnprocess avslutades onormalt" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Misslyckades med att läsa frÃ¥n rör till barn (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Misslyckades med att starta barnprocessen â€%s†(%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Misslyckades med att grena (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Misslyckades med att byta till katalogen â€%s†(%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Misslyckades med att köra barnprocessen â€%s†(%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Misslyckades med att öppna fil för att mappa om filhandtag (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Misslyckades med att duplicera filhandtag för barnprocess (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Misslyckades med att skapa barnprocess (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Misslyckades med att stänga filhandtag för barnprocess (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Okänt fel vid körning av barnprocessen â€%sâ€" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Misslyckades med att läsa tillräckligt med data frÃ¥n röret till barnets pid " +"(%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Misslyckades med att läsa data frÃ¥n barnprocessen" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Misslyckades med att köra barnprocess (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Misslyckades med att köra dup() i barnprocess (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ogiltigt programnamn: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ogiltig sträng i argumentvektorn vid %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ogiltig sträng i miljön: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ogiltig arbetskatalog: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Misslyckades med att köra hjälparprogram (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Oväntat fel i g_io_channel_win32_poll() vid inläsning av data frÃ¥n en " +"barnprocess" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Tom sträng är inte ett tal" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "â€%s†är inte ett tal med tecken" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "Talet â€%s†är utanför gränserna [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "â€%s†är inte ett teckenlöst tal" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Ogiltig %-kodning i URI" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "OtillÃ¥tet tecken i URI" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Tecken som inte är UTF-8 i URI" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Ogiltig IPv6-adress â€%.*s†i URI" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "OtillÃ¥tet kodad IP-adress â€%.*s†i URI" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "OtillÃ¥tet internationaliserat värdnamn â€%.*s†i URI" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Kunde inte tolka port â€%.*s†i URI" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Port â€%.*s†i URI är utanför intervallet" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI â€%s†är inte en absolut URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI â€%s†har ingen värdkomponent" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI är inte absolut, och ingen bas-URI angavs" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Saknar â€=†och parametervärde" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Misslyckades med att allokera minne" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Tecknet är utanför intervallet för UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Ogiltig sekvens i konverteringsindata" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Tecknet är utanför intervallet för UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" +msgstr[1] "%u byte" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" +msgstr[1] "%u bitar" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" +msgstr[1] "%s byte" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" +msgstr[1] "%s bitar" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "Kunde inte läsa in /var/lib/dbus/machine-id eller /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Okänt fel inträffade vid anslutning" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "Fel i adressen â€%s†— familjeattributet är felformulerat" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "Monterade %s pÃ¥ %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; ignorerar Ã¥sidosättning för denna nyckel.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " och --strict angavs; avslutar.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Ignorerar Ã¥sidosättning för denna nyckel.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "gör ingenting.\n" + +#~ msgid "No such interface '%s'" +#~ msgstr "Inget sÃ¥dant gränssnitt '%s'" + +#~ msgid "No such method '%s'" +#~ msgstr "Ingen sÃ¥dan metod '%s'" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Kan inte fastställa bussadressen frÃ¥n miljövariabeln " +#~ "DBUS_STARTER_BUS_TYPE - okänt värde '%s'" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGUMENT…]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Misslyckades med att skapa temporärfil: %s" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "Meddelandet har %d filhandtag men rubrikfältet indikerar %d filhandtag" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Fel: objektsökväg har inte angivits.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Fel: signal har inte angivits.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Fel: signal mÃ¥ste vara det fullständiga namnet.\n" + +#~ msgid "No such interface" +#~ msgstr "Inget sÃ¥dant gränssnitt" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "Fel vid hämtning av skrivbara attribut: %s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Fel vid montering av plats: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "Fel vid avmontering av montering: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Kunde inte hitta inneslutande montering: %s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Fel vid utmatning av montering: %s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "Fel vid montering av %s: %s\n" + +#~ msgid "No files to open" +#~ msgstr "Inga filer att öppna" + +#~ msgid "No files to delete" +#~ msgstr "Inga filer att ta bort" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "Fel vid inställning av attribut: %s\n" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "Fel vid skapandet av katalogen â€%sâ€: %s" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "Fel vid öppning av filen â€%sâ€: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "Fel vid läsning av filen â€%sâ€: %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Fel vid namnbyte av fil: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Fel vid öppnande av fil: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Fel vid skapande av katalog: %s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Kunde inte hitta standardtyp för lokal katalogövervakare" + +#~ msgid "association changes not supported on win32" +#~ msgstr "associeringsändringar stöds inte pÃ¥ win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "Associeringsskapanden stöds inte pÃ¥ win32" diff --git a/po/ta.po b/po/ta.po new file mode 100644 index 0000000..1303aa3 --- /dev/null +++ b/po/ta.po @@ -0,0 +1,4859 @@ +# translation of glib.master.ta.po to +# translation of ta.po to +# Tamil translation of GLib. +# Copyright (C) 2001, 2006, 2007, 2009 Free Software Foundation, Inc. +# +# Dinesh Nadarajah , 2001. +# Felix , 2006. +# Dr.T.Vasudevan , 2007. +# I. Felix , 2009. +# Priyadharsini , 2009. +# I Felix , 2011. +# Shantha kumar , 2012, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: glib.master.ta\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-15 05:53+0000\n" +"PO-Revision-Date: 2014-09-15 19:08+0630\n" +"Last-Translator: Shantha kumar \n" +"Language-Team: Tamil \n" +"Language: ta\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\\n" +";\n" + +#: ../gio/gapplication.c:514 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"GApplication சேவை à®®à¯à®±à¯ˆà®®à¯ˆà®•à¯à®•à¯à®šà¯ செல௠(D-Bus சேவைக௠கோபà¯à®ªà¯à®•ளிலிரà¯à®¨à¯à®¤à¯ " +"பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯)" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "GApplication options" +msgstr "GApplication விரà¯à®ªà¯à®ªà®™à¯à®•ளà¯" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "GApplication விரà¯à®ªà¯à®ªà®™à¯à®•ளைக௠காடà¯à®Ÿà¯" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:481 ../gio/gsettings-tool.c:508 +msgid "Print help" +msgstr "உதவியை அசà¯à®šà®¿à®Ÿà®µà¯à®®à¯" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:482 +#: ../gio/gresource-tool.c:550 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "அசà¯à®šà¯à®ªà¯ பதிபà¯à®ªà¯" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:514 +msgid "Print version information and exit" +msgstr "பதிபà¯à®ªà¯ தகவலை அசà¯à®šà®¿à®Ÿà¯à®Ÿà¯ வெளியேறவà¯à®®à¯" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"நிறà¯à®µà®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³ D-Bus செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®•à¯à®•ூடிய பயனà¯à®ªà®¾à®Ÿà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯ (.desktop " +"கோபà¯à®ªà¯ " +"மூலமà¯)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "ஒர௠பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆà®¤à¯ தà¯à®µà®•à¯à®•வà¯à®®à¯" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆà®¤à¯ தà¯à®µà®•à¯à®•வà¯à®®à¯ (விரà¯à®®à¯à®ªà®¿à®©à®¾à®²à¯ திறகà¯à®• வேணà¯à®Ÿà®¿à®¯ கோபà¯à®ªà¯à®•ளà¯à®Ÿà®©à¯)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "ஒர௠செயலை செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà®¿à®©à¯ மீத௠ஒர௠செயலை செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID செயல௠[அளவà¯à®°à¯]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "கிடைகà¯à®•à¯à®®à¯ செயலà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "" +"ஒர௠பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯à®•à¯à®•ான நிலையான செயலà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯ (.desktop கோபà¯à®ªà®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "விரிவான உதவி அசà¯à®šà®¿à®Ÿà®ªà¯à®ªà®Ÿ வேணà¯à®Ÿà®¿à®¯ கடà¯à®Ÿà®³à¯ˆ" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus வடிவமைபà¯à®ªà®¿à®²à¯ பயனà¯à®ªà®¾à®Ÿà¯ அடையாளஙà¯à®•ாடà¯à®Ÿà®¿ (எ.கா: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:488 +#: ../gio/gresource-tool.c:554 +msgid "FILE" +msgstr "FILE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "" +"திறகà¯à®• வேணà¯à®Ÿà®¿à®¯ விரà¯à®®à¯à®ªà®¿à®©à®¾à®²à¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®•à¯à®•ூடிய உறவ௠அலà¯à®²à®¤à¯ உறவ௠கோபà¯à®ªà¯à®ªà¯ " +"பெயரà¯à®•ள௠அலà¯à®²à®¤à¯ " +"URIகளà¯" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "செயலà¯" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "தரà¯à®µà®¿à®•à¯à®• வேணà¯à®Ÿà®¿à®¯ செயல௠பெயரà¯" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "அளவà¯à®°à¯" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "" +"GVariant வடிவமைபà¯à®ªà®¿à®²à¯, செயல௠தரà¯à®µà®¿à®¤à¯à®¤à®²à¯à®•à¯à®•ான விரà¯à®®à¯à®ªà®¿à®©à®¾à®²à¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®•à¯à®•ூடிய " +"அளவà¯à®°à¯" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:519 +#: ../gio/gsettings-tool.c:594 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"தெரியாத கடà¯à®Ÿà®³à¯ˆ %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:544 +#: ../gio/gsettings-tool.c:628 +msgid "Arguments:\n" +msgstr "விவாதஙà¯à®•ளà¯:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "கடà¯à®Ÿà®³à¯ˆà®•ளà¯:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"விரிவான உதவி பெற '%s help COMMAND' à®à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s கடà¯à®Ÿà®³à¯ˆ நேரடியாக பின௠தொடர அதறà¯à®•௠ஒர௠பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ id தேவை\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாத பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ id: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' கà¯à®•௠மதிபà¯à®ªà¯à®°à¯à®•à¯à®•ள௠செலà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus கà¯à®•௠இணைகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "%s செயà¯à®¤à®¿à®•ளை பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯à®•à¯à®•௠அனà¯à®ªà¯à®ªà¯à®µà®¤à®¿à®²à¯ பிழை: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ id கà¯à®•௠அடà¯à®¤à¯à®¤à¯ செயல௠பெயர௠வழஙà¯à®•பà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாத செயல௠பெயரà¯: '%s'\n" +"செயல௠பெயரà¯à®•ளில௠எணà¯à®•ளà¯à®®à¯ எழà¯à®¤à¯à®¤à¯à®•ளà¯à®®à¯ '-', '.' ஆகிய எழà¯à®¤à¯à®¤à¯à®•ளà¯à®®à¯ மடà¯à®Ÿà¯à®®à¯‡ " +"இரà¯à®•à¯à®•லாமà¯\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "செயல௠அளவà¯à®°à¯à®µà¯ˆà®ªà¯ பாகà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®µà®¤à®¿à®²à¯ பிழை: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "செயல௠அதிகபடà¯à®šà®®à¯ ஒர௠அளவà¯à®°à¯à®µà¯ˆà®¯à¯‡ à®à®±à¯à®•à¯à®®à¯\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "list-actions கடà¯à®Ÿà®³à¯ˆ பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ id ஠மடà¯à®Ÿà¯à®®à¯‡ எடà¯à®¤à¯à®¤à¯à®•à¯à®•ொளà¯à®³à¯à®®à¯" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯ %s கà¯à®•௠டெஸà¯à®•à¯à®Ÿà®¾à®ªà¯ கோபà¯à®ªà¯ˆà®•௠கணà¯à®Ÿà®±à®¿à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"அடையாளம௠காணபà¯à®ªà®Ÿà®¾à®¤ கடà¯à®Ÿà®³à¯ˆ: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:370 +#: ../gio/ginputstream.c:608 ../gio/ginputstream.c:828 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:823 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s கà¯à®•௠மிகபà¯à®ªà¯†à®°à®¿à®¯ எணà¯à®£à®¿à®•à¯à®•ை மதிபà¯à®ªà¯ செலà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "ஸà¯à®Ÿà¯à®°à¯€à®®à®¿à®²à¯ தேடà¯à®¤à®²à¯ தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStream ஠தசமமிட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1017 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1464 +msgid "Stream is already closed" +msgstr "ஸà¯à®Ÿà¯à®°à¯€à®®à¯ à®à®±à¯à®•னவே மூடபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "பேஸ௠ஸà¯à®Ÿà¯à®°à¯€à®®à®¿à®²à¯ டà¯à®°à®©à¯à®•à¯à®•ேட௠செயலà¯à®•à¯à®•௠ஆதரவிலà¯à®²à¯ˆ" + +#: ../gio/gcancellable.c:310 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "செயலà¯à®ªà®¾à®Ÿà¯ ரதà¯à®¤à¯ செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "தவறான பொரà¯à®³à¯, தà¯à®µà®•à¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "உளà¯à®³à¯€à®Ÿà¯ à®®à¯à®´à¯à®®à¯ˆà®¯à®Ÿà¯ˆà®¯à®¾ மலà¯à®Ÿà®¿à®ªà¯ˆà®Ÿà¯à®Ÿà®¿à®©à¯ வரிசை" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "இலகà¯à®•ில௠போதà¯à®®à®¾à®© இடம௠இலà¯à®²à¯ˆ" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "நிலை மாறà¯à®±à®¿à®¯à®¿à®©à¯ உளà¯à®³à¯€à®Ÿà¯à®•à¯à®•௠தவறான பைட௠வரிசைமà¯à®±à¯ˆ" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "மாறà¯à®±à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "ரதà¯à®¤à¯à®šà¯†à®¯à¯à®¯à®•à¯à®•ூடிய தà¯à®µà®•à¯à®•à¯à®¤à®²à¯ தà¯à®£à¯ˆà®ªà¯à®°à®¿à®µà®¤à®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "வரியà¯à®°à¯ வகை '%s' இலிரà¯à®¨à¯à®¤à¯ '%s' கà¯à®•௠மாறà¯à®±à¯à®µà®¤à®±à¯à®•௠ஆதரவளிபà¯à®ªà¯ கிடையாதà¯" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' லிரà¯à®¨à¯à®¤à¯ '%s'கà¯à®•௠மாறà¯à®±à®¿à®¯à¯ˆ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s வகை" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "தெரியாத வகை" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s கோபà¯à®ªà¯ வகை" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials ஆனத௠இநà¯à®¤ OS இல௠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "உஙà¯à®•ள௠தளதà¯à®¤à®¿à®±à¯à®•ான GCredentials தà¯à®£à¯ˆ இலà¯à®²à¯ˆ" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "இநà¯à®¤ OS இல௠GCredentials கà¯à®•௠ஒர௠செயலாகà¯à®• ID இலà¯à®²à¯ˆ" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "இநà¯à®¤ OS இல௠சானà¯à®±à®³à®¿à®ªà¯à®ªà¯à®•ளை ஸà¯à®ªà¯‚ஃபிங௠செயà¯à®¯ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "எதிரà¯à®ªà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà®¾à®¤ à®®à¯à®Ÿà®¿à®µà¯ ஸà¯à®Ÿà¯à®°à¯€à®®à¯" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®¾à®¤ விசை '%s' ஆனத௠மà¯à®•வரி உளà¯à®³à®¿à®Ÿà¯ '%s' இல௠உளà¯à®³à®¤à¯" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"à®®à¯à®•வரி '%s' தவறானத௠(சரியாக ஒர௠பாதை தேவைபà¯à®ªà®Ÿà¯à®•ிறதà¯, tmpdir அலà¯à®²à®¤à¯ சà¯à®°à¯à®•à¯à®• " +"விசைகளà¯)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "à®®à¯à®•வரி உளà¯à®³à®¿à®Ÿà¯ '%s' இல௠அரà¯à®¤à¯à®¤à®®à®±à¯à®± விசை/மதிபà¯à®ªà¯ ஜோடி கலவை" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "à®®à¯à®•வரி '%s' இல௠பிழை - தà¯à®±à¯ˆ பணà¯à®ªà¯ தவறானதà¯" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "à®®à¯à®•வரி '%s' இல௠பிழை - கà¯à®Ÿà¯à®®à¯à®ª பணà¯à®ªà¯ தவறானதà¯" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "à®®à¯à®•வரியின௠'%s' எனà¯à®± கூறில௠கோலன௠(:) இலà¯à®²à¯ˆ" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" +"à®®à¯à®•வரியின௠'%3$s' கூறில௠உளà¯à®³ விசை/மதிபà¯à®ªà¯ ஜோடி %1$d, '%2$s' இல௠சமக௠கà¯à®±à®¿ " +"இலà¯à®²à¯ˆ" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"பிழை தபà¯à®ªà®¿à®•à¯à®•ாத விசை அலà¯à®²à®¤à¯ விசையின௠மதிபà¯à®ªà¯/மதிபà¯à®ªà¯ ஜோடி %d, '%s', உரà¯à®ªà¯à®ªà®Ÿà®¿ " +"à®®à¯à®•வரியிலà¯'%s'" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"à®®à¯à®•வரியில௠பிழை '%s' - யà¯à®©à®¿à®•à¯à®¸à¯ போகà¯à®•à¯à®µà®°à®¤à¯à®¤à¯à®šà®°à®¿à®¯à®¾à®• விசைகளின௠ஒர௠'பாதை' " +"அலà¯à®²à®¤à¯ " +"'தடà¯à®¤à¯à®¤à®²à¯' போனà¯à®±à®µà®±à¯à®±à¯ˆ அமைகà¯à®• கோரà¯à®•ிறதà¯" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "à®®à¯à®•வரி '%s' இல௠பிழை - பà¯à®°à®µà®²à®©à¯ பணà¯à®ªà¯ விடà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ அலà¯à®²à®¤à¯ தவறானதà¯" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "à®®à¯à®•வரி '%s' இல௠பிழை - தà¯à®±à¯ˆ பணà¯à®ªà¯ விடà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ அலà¯à®²à®¤à¯ தவறானதà¯" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" +"à®®à¯à®•வரி '%s' இல௠பிழை - நினைவà¯à®•à¯à®•à¯à®±à®¿à®¯à¯€à®Ÿà¯à®•ோபà¯à®ªà¯ பணà¯à®ªà¯ விடà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ அலà¯à®²à®¤à¯ தவறானதà¯" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "தானியகà¯à®•-தà¯à®µà®•à¯à®•தà¯à®¤à®¿à®²à¯ பிழை:" + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "'%s' à®®à¯à®•வரிகà¯à®•ான தெரியாத அலà¯à®²à®¤à¯ தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®¾à®¤ போகà¯à®•à¯à®µà®°à®¤à¯à®¤à¯ '%s'" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "தறà¯à®ªà¯‹à®¤à¯ˆà®¯ கோபà¯à®ªà¯ '%s' ஠திறகà¯à®•à¯à®®à¯ பிழை: %s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "தறà¯à®šà®®à®¯ கோபà¯à®ªà¯ '%s' இலிரà¯à®¨à¯à®¤à¯ வாசிகà¯à®•à¯à®®à¯ பிழை: %s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "" +"தறà¯à®šà®®à®¯ கோபà¯à®ªà¯ '%s' இலிரà¯à®¨à¯à®¤à¯ பிழை வாசிகà¯à®•ிறதà¯, 16 பைடà¯à®Ÿà¯à®•ள௠" +"எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯, %d " +"பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "தறà¯à®šà®®à®¯ கோபà¯à®ªà¯ '%s' ஠ஸà¯à®Ÿà¯à®°à¯†à®®à¯à®®à®¿à®±à¯à®•௠உளà¯à®³à®Ÿà®•à¯à®•à®™à¯à®•ளை எழà¯à®¤à¯à®®à¯ பிழை:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ à®®à¯à®•வரி காலியாக உளà¯à®³à®¤à¯ " + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "uid ஠அமைகà¯à®•à¯à®®à¯ போத௠ஒர௠செயà¯à®¤à®¿à®¯à¯ˆ கொணà¯à®Ÿà¯ வர à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "ஒர௠கணினி-கà¯à®±à®¿à®¯à¯€à®Ÿà¯ இலà¯à®²à®¾à®®à®²à¯ ஒர௠செயà¯à®¤à®¿ பஸà¯à®¸à¯ˆ உறà¯à®ªà®¤à¯à®¤à®¿ செயà¯à®¯ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯:" + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "பிழை ஸà¯à®ªà¯‡à®©à®¿à®™à¯ கடà¯à®Ÿà®³à¯ˆ வரி '%s': " + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(இநà¯à®¤ சாளரதà¯à®¤à¯ˆ மூட à®à®¤à¯‡à®©à¯à®®à¯ ஒர௠எழà¯à®¤à¯à®¤à¯à®•à¯à®•à¯à®±à®¿à®¯à¯ˆà®¤à¯ தடà¯à®Ÿà®šà¯à®šà¯ செயà¯à®¯à®µà¯à®®à¯)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "dbus அமரà¯à®µà¯ இயஙà¯à®•விலà¯à®²à¯ˆ தானியகà¯à®• தொடகà¯à®•ம௠தோலà¯à®µà®¿à®¯à®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"அமரà¯à®µà¯ பஸ௠மà¯à®•வரியை வரையறà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ (இநà¯à®¤ OS கà¯à®•ாக " +"செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ)" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"DBUS_STARTER_BUS_TYPE சூழல௠மாறியிலிரà¯à®¨à¯à®¤à¯ பஸ௠மà¯à®•வரியை வரையறà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯- " +"தெரியாத மதிபà¯à®ªà¯ '%s'" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"பஸ௠மà¯à®•வரியை வரையறà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ à®à®©à¯†à®©à®¿à®²à¯ DBUS_STARTER_BUS_TYPE சூழல௠மாறி " +"அமைகà¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ " + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "தெரியாத பஸ௠வகை %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "" +"எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà®¾à®¤ உளà¯à®³à®Ÿà®•à¯à®•தà¯à®¤à®¿à®©à¯ பறà¯à®±à®¾à®•à¯à®•à¯à®±à¯ˆ ஒர௠வரியில௠வாசிகà¯à®• " +"à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•ிறதà¯" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" +"எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà®¾à®¤ உளà¯à®³à®Ÿà®•à¯à®•தà¯à®¤à®¿à®©à¯ பறà¯à®±à®¾à®•à¯à®•à¯à®±à¯ˆ ஒர௠வரியில௠(பாதà¯à®•ாபà¯à®ªà®¾à®•) " +"வாசிகà¯à®• " +"à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•ிறதà¯" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"அனைதà¯à®¤à¯ கிடைகà¯à®•à¯à®®à¯ à®…à®™à¯à®•ீகார நà¯à®Ÿà¯à®ªà®™à¯à®•ள௠வெளியேறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ (à®®à¯à®¯à®±à¯à®šà®¿à®¤à¯à®¤à®¤à¯: %s) " +"(இரà¯à®ªà¯à®ªà®µà¯ˆ: %s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" +"GDBusAuthObserver::authorize-authenticated-peer வழியாக ரதà¯à®¤à¯à®šà¯†à®¯à¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "'%s' கோபà¯à®ªà¯à®±à¯ˆà®•à¯à®•ான தகவலைப௠பெறà¯à®•ையில௠பிழை: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"அடைவிலà¯à®³à¯à®³ '%s' அனà¯à®®à®¤à®¿à®•ள௠தவறானதà¯. எதிரà¯à®ªà®¾à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ à®®à¯à®±à¯ˆà®®à¯ˆ 0700, கிடைதà¯à®¤à®¤à¯ 0%" +"o ஆகà¯à®®à¯" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "பிழை உரà¯à®µà®¾à®•à¯à®•à¯à®®à¯ அடைவ௠'%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "திறகà¯à®•à¯à®®à¯ கீரிங௠'%s' கà¯à®•ாக வாசிபà¯à®ªà®¤à¯à®¤à®¿à®²à¯ பிழை: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "கீரிஙà¯à®•ின௠வரி %d '%s' இல௠உளà¯à®³à®Ÿà®•à¯à®•தà¯à®¤à¯à®Ÿà®©à¯ '%s' தவறானதà¯" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "வரியின௠மà¯à®¤à®²à¯ டோகà¯à®•ன௠%d கீரிங௠'%s'இல௠உளà¯à®³à®Ÿà®•à¯à®•தà¯à®¤à¯à®Ÿà®©à¯ '%s' தவறானதà¯" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"வரியின௠இரணà¯à®Ÿà®¾à®µà®¤à¯ டோகà¯à®•ன௠%d கீரிங௠'%s'இல௠உளà¯à®³à®Ÿà®•à¯à®•தà¯à®¤à¯à®Ÿà®©à¯ '%s' தவறானதà¯" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "id %d உடன௠'%s' விசைரிஙà¯à®•ில௠கà¯à®•à¯à®•ீயை தேட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "பிழை அழிகà¯à®•à¯à®®à¯ பழைய பூடà¯à®Ÿà¯ கோபà¯à®ªà¯ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "பிழை உரà¯à®µà®¾à®•à¯à®•à¯à®®à¯ பூடà¯à®Ÿà¯ கோபà¯à®ªà¯ '%s' : %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "பிழை மூடà¯à®®à¯ (இணைபà¯à®ªà®¿à®²à¯à®²à®¾à®¤) பூடà¯à®Ÿà¯ கோபà¯à®ªà¯ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "பிழை இணைபà¯à®ªà¯ நீகà¯à®•à¯à®®à¯ பூடà¯à®Ÿà¯ கோபà¯à®ªà¯ '%s' : %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "எழà¯à®¤à¯à®µà®¤à®±à¯à®•ாக பிழை திறகà¯à®•à¯à®®à¯ கீரிங௠'%s' : " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(கூடà¯à®¤à®²à®¾à®•, '%s' கà¯à®•ாக வெளியிடà¯à®®à¯ பூடà¯à®Ÿà¯à®®à¯ தொலà¯à®µà®¿à®¯à¯à®±à¯à®±à®¤à¯: %s) " + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "இணைபà¯à®ªà¯ மூடபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "நேரமà¯à®®à¯à®Ÿà®¿à®µà¯ பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"ஒர௠கிளையனà¯à®Ÿà¯ -பகà¯à®• இணைபà¯à®ªà¯ˆ உரà¯à®µà®¾à®•à¯à®•à¯à®®à¯ போத௠ஆதரிகà¯à®•பà¯à®ªà®Ÿà®¾à®¤ கொடிகள௠" +"எதிரà¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®©" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"'org.freedesktop.DBus.Properties' பொரà¯à®³à®¿à®²à¯ %s பாதையில௠இத௠போனà¯à®± இடைமà¯à®•ம௠" +"இலà¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "'%s' போனà¯à®± பணà¯à®ªà¯ எதà¯à®µà¯à®®à¯ இலà¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "பணà¯à®ªà¯ '%s' ஠வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "பணà¯à®ªà¯ '%s' ஠எழà¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"பிழை அமைகà¯à®•à¯à®®à¯ பணà¯à®ªà¯ '%s': எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ வகை '%s' ஆனால௠கிடைதà¯à®¤à®¤à¯ '%s' " +"ஆகà¯à®®à¯" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "'%s' போனà¯à®± இடைமà¯à®•ம௠இலà¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "இத௠போனà¯à®± இடைமà¯à®•ம௠இலà¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "'%s' பொரà¯à®³à®¿à®²à¯ பாதை %s போனà¯à®± இடைமà¯à®•ம௠இலà¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "'%s' போனà¯à®± à®®à¯à®±à¯ˆ இலà¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "செயà¯à®¤à®¿à®¯à®¿à®©à¯ வகை, '%s', எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿ வகை '%s' கà¯à®•௠பொரà¯à®¨à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "இடைமà¯à®•ம௠%s கà¯à®•ாக %s இல௠à®à®±à¯à®•னவே ஒர௠பொரà¯à®³à¯ à®à®±à¯à®±à¯à®®à®¤à®¿ செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "à®®à¯à®±à¯ˆ '%s' திரà¯à®®à¯à®ªà®¿à®¯ வகை '%s', ஆனால௠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ '%s'" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "இடைமà¯à®•தà¯à®¤à®¿à®²à¯ '%s' à®®à¯à®±à¯ˆ '%s' உடன௠கையெழà¯à®¤à¯à®¤à¯ '%s' இலà¯à®²à¯ˆ" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "ஒர௠தà¯à®£à¯ˆà®®à®°à®®à®¾à®©à®¤à¯ %s கà¯à®•ாக à®à®±à¯à®•னவே வெளியேறà¯à®±à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "வகை தவறானதà¯" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL செயà¯à®¤à®¿: பாதை அலà¯à®²à®¤à¯ உறà¯à®ªà¯à®ªà®¿à®©à®°à¯ தலைபà¯à®ªà¯ பà¯à®²à®®à¯ விடà¯à®ªà®Ÿà¯à®•ிறதà¯" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN செயà¯à®¤à®¿: REPLY_SERIAL தலைபà¯à®ªà¯ பà¯à®²à®®à¯ விடà¯à®ªà®Ÿà¯à®•ிறதà¯" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"ERROR செயà¯à®¤à®¿: REPLY_SERIAL அலà¯à®²à®¤à¯ ERROR_NAME தலைபà¯à®ªà¯ பà¯à®²à®®à¯ விடà¯à®ªà®Ÿà¯à®•ிறதà¯" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"SIGNAL செயà¯à®¤à®¿: PATH, INTERFACE அலà¯à®²à®¤à¯ MEMBER தலைபà¯à®ªà¯ பà¯à®²à®®à¯ விடà¯à®ªà®Ÿà¯à®•ிறதà¯" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL செயà¯à®¤à®¿: PATH தலைபà¯à®ªà¯ பà¯à®²à®®à¯ /org/freedesktop/DBus/Local கà¯à®•ாக " +"à®®à¯à®©à¯à®ªà®¤à®¿à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿ " +"மதிபà¯à®ªà®¿à®©à¯ˆ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•ிறதà¯" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL செயà¯à®¤à®¿: INTERFACE தலைபà¯à®ªà¯ பà¯à®²à®®à¯ /org/freedesktop/.DBus/Local கà¯à®•ாக " +"à®®à¯à®©à¯à®ªà®¤à®¿à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿ மதிபà¯à®ªà®¿à®©à¯ˆ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•ிறதà¯" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu பைடà¯à®Ÿà¯ˆ வாசிகà¯à®• விரà¯à®®à¯à®ªà®¿à®¯à®¤à¯ ஆனால௠%lu மடà¯à®Ÿà¯à®®à¯‡ கிடைதà¯à®¤à®¤à¯" +msgstr[1] "%lu பைடà¯à®Ÿà¯à®•ளை வாசிகà¯à®• விரà¯à®®à¯à®ªà®¿à®¯à®¤à¯ ஆனால௠%lu மடà¯à®Ÿà¯à®®à¯‡ கிடைதà¯à®¤à®¤à¯" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "Expected NUL byte after the string '%s' but found byte %d" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ சரியான UTF-8 சரம௠ஆனாலà¯à®¤à®µà®±à®¾à®© கைடà¯à®Ÿà¯à®•ள௠பைட௠ஆஃபà¯à®šà¯†à®Ÿà¯ %d " +"இல௠கிடைதà¯à®¤à®¤à¯ " +"(சரதà¯à®¤à®¿à®©à¯ நீளம௠%d). சரியான UTF-8 சரமானத௠'%s' பà¯à®³à¯à®³à®¿ இரà¯à®•à¯à®•à¯à®®à¯ வரை" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "பகà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ மதிபà¯à®ªà¯ '%s' ஆனத௠ஒர௠சரியான D-Bus பொரà¯à®³à¯ பாதை இலà¯à®²à¯ˆ" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "பகà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ மதிபà¯à®ªà¯ '%s' ஆனத௠ஒர௠சரியான D-Bus கையெழà¯à®¤à¯à®¤à¯ இலà¯à®²à¯ˆ" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"எதிரà¯à®•ொளà¯à®³à®ªà¯à®ªà®Ÿà¯à®Ÿ à®…à®®à¯à®ªà¯à®•à¯à®•à¯à®±à®¿à®¯à®¿à®©à¯ நீளம௠%u பைடà¯. அதிகபடà¯à®š நீளம௠2<<26 bytes " +"(64 MiB)." +msgstr[1] "" +"எதிரà¯à®•ொளà¯à®³à®ªà¯à®ªà®Ÿà¯à®Ÿ à®…à®®à¯à®ªà¯à®•à¯à®•à¯à®±à®¿ நீள %u பைடà¯à®Ÿà¯à®•ளà¯. அதிகபடà¯à®š நீளம௠2<<26 bytes (64 " +"MiB)." + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"'a%c' அணிவரிசை வகை எதிரà¯à®•ொளà¯à®³à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯, %u " +"பைடà¯à®Ÿà¯à®•ளின௠மடஙà¯à®•ிலான நீளம௠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯, ஆனால௠நீளம௠%u பைடà¯à®Ÿà®¾à®• " +"இரà¯à®ªà¯à®ªà®¤à¯ கணà¯à®Ÿà®±à®¿à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" +"மாறிகà¯à®•ான பகà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ மதிபà¯à®ªà¯ '%s' ஆனத௠ஒர௠சரியான D-Bus கையெழà¯à®¤à¯à®¤à®¿à®±à¯à®•௠இலà¯à®²à¯ˆ" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"GVariant உடன௠சர வகை '%s' இலிரà¯à®¨à¯à®¤à¯ D-Bus ஒயர௠வடிவதà¯à®¤à®¿à®²à¯ வரிசைநீகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿ " +"பிழை" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"தவறாக à®®à¯à®Ÿà®¿à®µà¯à®±à¯à®®à¯ மதிபà¯à®ªà¯. எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ 0x6c ('l') or 0x42 ('B') ஆனால௠" +"காணபà¯à®ªà®Ÿà¯à®Ÿ மதிபà¯à®ªà¯ 0x%02x" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"தவறான à®®à¯à®•à¯à®•ியமான நெறிமà¯à®±à¯ˆ பதிபà¯à®ªà¯. எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ 1 ஆனால௠%d காணபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" +"கையெழà¯à®¤à¯à®¤à¯ தலைபà¯à®ªà¯ கையெழà¯à®¤à¯à®¤à¯ '%s' உடன௠காணபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ ஆனால௠செயà¯à®¤à®¿à®¯à®¿à®©à¯ " +"மூயபà¯à®ªà®•à¯à®¤à®¿ " +"காலியாக உளà¯à®³à®¤à¯" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" +"பகà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ மதிபà¯à®ªà¯ '%s' ஆனத௠ஒர௠சரியான D-Bus கையெழà¯à®¤à¯à®¤à¯ இலà¯à®²à¯ˆ (மையதà¯à®¤à®¿à®±à¯à®•à¯)" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"கையெழà¯à®¤à¯à®¤à¯ தலைபà¯à®ªà¯ எதà¯à®µà¯à®®à¯ செயà¯à®¤à®¿à®¯à®¿à®²à¯ இலà¯à®²à¯ˆ ஆனால௠செயà¯à®¤à®¿ மையபà¯à®ªà®•à¯à®¤à®¿ %u பைட௠" +"ஆகà¯à®®à¯" +msgstr[1] "" +"கையெழà¯à®¤à¯à®¤à¯ தலைபà¯à®ªà¯ எதà¯à®µà¯à®®à¯ செயà¯à®¤à®¿à®¯à®¿à®²à¯ இலà¯à®²à¯ˆ ஆனால௠செயà¯à®¤à®¿ மையபà¯à®ªà®•à¯à®¤à®¿ %u " +"பைடà¯à®Ÿà¯à®•ள௠ஆகà¯à®®à¯" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "செயà¯à®¤à®¿ வரிசைநீகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ:" + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"GVariant உடன௠சர வகை '%s' இலிரà¯à®¨à¯à®¤à¯ D-Bus ஒயர௠வடிவதà¯à®¤à®¿à®²à¯ வரிசைநீகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿ " +"பிழை" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"செயà¯à®¤à®¿à®¯à®¾à®©à®¤à¯ %d கோபà¯à®ªà¯ விளகà¯à®•ிகளை கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯ ஆனால௠பà¯à®²à®®à®¾à®©à®¤à¯ %d கோபà¯à®ªà¯ " +"விளகà¯à®•ியை " +"சà¯à®Ÿà¯à®Ÿà®¿à®•௠காடà¯à®Ÿà¯à®•ிறதà¯" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "செயà¯à®¤à®¿à®¯à¯ˆ வரிசைபà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ:" + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" +"செயà¯à®¤à®¿à®ªà¯ பகà¯à®¤à®¿ கையெழà¯à®¤à¯à®¤à¯ '%s' ஠கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯ ஆனால௠கையெழà¯à®¤à¯à®¤à¯ தலைபà¯à®ªà¯ இலà¯à®²à¯ˆ" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "" +"செயà¯à®¤à®¿à®ªà¯ பகà¯à®¤à®¿ வகை கையெழà¯à®¤à¯à®¤à¯ '%s' ஠கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯ ஆனால௠கையெழà¯à®¤à¯à®¤à¯ தலைபà¯à®ªà¯ " +"பà¯à®²à®®à¯ '%s' " +"இல௠உளà¯à®³à®¤à¯" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" +"செயà¯à®¤à®¿à®ªà¯ பகà¯à®¤à®¿ காலியாக உளà¯à®³à®¤à¯ ஆனால௠கையெழà¯à®¤à¯à®¤à¯ தலைபà¯à®ªà¯ பà¯à®²à®®à¯ '(%s)' இல௠உளà¯à®³à®¤à¯" + +#: ../gio/gdbusmessage.c:3282 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "வகை மையதà¯à®¤à¯à®Ÿà®©à¯ '%s' திரà¯à®®à¯à®ªà¯à®®à¯ பிழை" + +#: ../gio/gdbusmessage.c:3290 +msgid "Error return with empty body" +msgstr "காலியான மையதà¯à®¤à¯à®Ÿà®©à¯ பிழை திரà¯à®®à¯à®ªà¯à®®à¯" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "வனà¯à®ªà¯Šà®°à¯à®³à¯ விவரதà¯à®¤à¯Šà®•à¯à®ªà¯à®ªà¯ˆà®ªà¯ பெற à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "/var/lib/dbus/machine-id அலà¯à®²à®¤à¯ /etc/machine-id à® à®à®±à¯à®± à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "பிழை அழைகà¯à®•à¯à®®à¯ StartServiceByName கà¯à®•ான %s: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr " எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà®¾à®¤ பதில௠%d StartServiceByName(\"%s\") à®®à¯à®±à¯ˆà®¯à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"à®®à¯à®±à¯ˆ செயலாகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ; ஒர௠நனà¯à®±à®¾à®• தெரியà¯à®®à¯ பெயரà¯à®Ÿà¯ˆà®¯ பà¯à®°à®¾à®•à¯à®¸à®¿ ஒர௠" +"உரிமையாளர௠" +"இலà¯à®²à®¾à®®à®²à¯ பà¯à®°à®¾à®•à¯à®¸à®¿à®¯à®¾à®©à®¤à¯ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START கொடியà¯à®Ÿà®©à¯ " +"கடà¯à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "சà¯à®°à¯à®•à¯à®• பெயர௠இடதà¯à®¤à®¿à®±à¯à®•௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®µà®¤à®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "" +"ஒர௠சேவையகதà¯à®¤à¯ˆ உரà¯à®µà®¾à®•à¯à®•à¯à®®à¯ போத௠நினைவà¯à®•à¯à®•à¯à®±à®¿à®¯à¯€à®Ÿà¯à®Ÿà¯ˆ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' இல௠பிழை எழà¯à®¤à¯à®®à¯ தறà¯à®šà®®à®¯ கோபà¯à®ªà¯: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "சரம௠'%s' ஒர௠சரியான D-Bus GUID இலà¯à®²à¯ˆ" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®¾à®¤ போகà¯à®•à¯à®µà®°à®¤à¯à®¤à¯ '%s' ஠கவனிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "பிழை: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "பிழை பகà¯à®•à¯à®•à¯à®®à¯ உளà¯à®³à®¾à®¯à¯à®µà¯ XML: %s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "கணினி பஸà¯à®¸à®¿à®±à¯à®•௠இணைகà¯à®•ிறதà¯" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "அமரà¯à®µà¯ பஸà¯à®¸à¯à®•à¯à®•௠இணைகà¯à®•ிறதà¯" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ D-Bus à®®à¯à®•வரிகà¯à®•௠இணைகà¯à®•வà¯à®®à¯" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "இணைபà¯à®ªà¯ இறà¯à®¤à®¿à®ªà¯à®³à¯à®³à®¿ விரà¯à®ªà¯à®ªà®™à¯à®•ளà¯:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "இணைபà¯à®ªà¯ à®®à¯à®Ÿà®¿à®µà¯à®ªà¯à®³à¯à®³à®¿à®¯à®¿à®²à¯ விரà¯à®ªà¯à®ªà®™à¯à®•ளை கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®•ிறதà¯" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "இறà¯à®¤à®¿à®ªà¯à®³à¯à®³à®¿à®¯à®¿à®²à¯ இணைபà¯à®ªà¯ எதà¯à®µà¯à®®à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "பல இணைபà¯à®ªà¯ இறà¯à®¤à®¿à®ªà¯à®³à¯à®³à®¿à®•ளில௠கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "எசà¯à®šà®°à®¿à®•à¯à®•ை: தனà¯à®©à®¿à®²à¯ˆ தரவின௠படி, à®®à¯à®±à¯ˆ இடைமà¯à®•ம௠'%s' இலà¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "எசà¯à®šà®°à®¿à®•à¯à®•ை: தனà¯à®©à®¿à®²à¯ˆ தரவின௠படி, à®®à¯à®±à¯ˆ '%s' இடைமà¯à®•ம௠'%s' இல௠இலà¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "சிகà¯à®©à®²à¯à®•à¯à®•ான விரà¯à®ªà¯à®ªà®®à®¾à®© இலகà¯à®•௠( தனிபà¯à®ªà®Ÿà¯à®Ÿ பெயரà¯)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "சிகà¯à®©à®²à¯ ஆனà¯à®©à¯ˆ வெளியேறà¯à®µà®¤à®±à¯à®•௠பொரà¯à®³à¯ பாதை" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "சிகà¯à®©à®²à¯ மறà¯à®±à¯à®®à¯ இடைமà¯à®• பெயரà¯" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "ஒர௠சிகà¯à®©à®²à¯ˆ வெளியிடà¯." + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "பிழை இணைகà¯à®•ிறதà¯: %s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "பிழை: பொரà¯à®³à¯ பாதை கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "பிழை: %s ஒர௠சரியான பெயர௠பாதை இலà¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "பிழை: சிகà¯à®©à®²à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "பிழை: சிகà¯à®©à®²à¯ ஒர௠மà¯à®´à¯ தகà¯à®¤à®¿à®µà®¾à®¯à¯à®¨à¯à®¤ பெயராக இரà¯à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯.\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "பிழை: %s ஒர௠சரியான இடைமà¯à®• பெயர௠இலà¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "பிழை: %s ஒர௠சரியான நபர௠பெயர௠இலà¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "பிழை: %s ஆனத௠ஒர௠சரியான ஒதà¯à®¤ பஸ௠பெயர௠இலà¯à®²à¯ˆ.\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "பிழை பகà¯à®•à¯à®•à¯à®®à¯ அளவà¯à®°à¯ %d: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "பிழை சà¯à®¤à¯à®¤à®®à®¾à®•à¯à®•à¯à®®à¯ இணைபà¯à®ªà¯: %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "இலகà¯à®•௠பெயரானத௠மà¯à®±à¯ˆà®¯à¯ˆ ஆனà¯à®©à®¾à®•à¯à®• செயலாகà¯à®•à¯à®•ிறதà¯" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "பொரà¯à®³à¯ பாதை à®®à¯à®±à¯ˆà®¯à¯ˆ ஆனà¯à®©à®¾à®•à¯à®• செயலாகà¯à®•à¯à®•ிறதà¯" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "à®®à¯à®±à¯ˆ மறà¯à®±à¯à®®à¯ இடைமà¯à®•ப௠பெயரà¯" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "விநாடிகள௠நேரம௠மà¯à®Ÿà®¿à®¨à¯à®¤à®¤à¯" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "ஒர௠தொலை பொரà¯à®³à®¿à®²à¯ ஒர௠மà¯à®±à¯ˆ செயலாறà¯à®±à¯à®•ிறதà¯." + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "பிழை: இலகà¯à®•௠கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "பிழை: பொரà¯à®³à¯ பாதை கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "பிழை: à®®à¯à®±à¯ˆà®ªà¯ பெயர௠கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "பிழை: à®®à¯à®±à¯ˆ பெயர௠'%s' தவறானதà¯\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "பிழை பகà¯à®•à¯à®•à¯à®®à¯ அளவà¯à®°à¯ %d வகை '%s': %s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "உளà¯à®³à®¾à®¯à¯à®µà®¿à®±à¯à®•௠இலகà¯à®•௠பெயரà¯" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "உளà¯à®³à®¾à®¯à¯à®µà®¿à®±à¯à®•௠பொரà¯à®³à¯ பாதை" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "XML ஠அசà¯à®šà®¿à®Ÿà¯" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "உளà¯à®³à®¾à®¯à¯à®µà¯ கà¯à®´à®¨à¯à®¤à¯ˆ" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "அசà¯à®šà¯ பணà¯à®ªà¯à®•ள௠மடà¯à®Ÿà¯à®®à¯" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "ஒர௠தொலை பொரà¯à®³à¯ˆ உளà¯à®³à®¾à®¯à®µà¯à®®à¯." + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "கணிபà¯à®ªà®¤à®±à¯à®•ான இலகà¯à®•௠பெயரà¯" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "கணிபà¯à®ªà®¤à®±à¯à®•ான பொரà¯à®³à¯ பாதை" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "ஒர௠தொலை பொரà¯à®³à¯ˆ கணிகà¯à®•வà¯à®®à¯." + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4522 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "பெயரிலà¯à®²à®¾à®¤à®¤à¯" + +#: ../gio/gdesktopappinfo.c:2410 +msgid "Desktop file didn't specify Exec field" +msgstr "பணிமேடை கோபà¯à®ªà¯ Exec பà¯à®²à®®à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdesktopappinfo.c:2695 +msgid "Unable to find terminal required for application" +msgstr "விணà¯à®£à®ªà¯à®ªà®¤à¯à®¤à®¿à®±à¯à®•௠தேவைபà¯à®ªà®Ÿà¯à®®à¯ à®®à¯à®©à¯ˆà®¯à®¤à¯à®¤à¯ˆ கணà¯à®Ÿà¯à®ªà®¿à®Ÿà®¿à®•à¯à®• இயலவிலà¯à®²à¯ˆ" + +#: ../gio/gdesktopappinfo.c:3116 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "பயனர௠விணà¯à®£à®ªà¯à®ª கடà¯à®Ÿà®®à¯ˆà®ªà¯à®ªà¯ கோபà¯à®ªà¯à®±à¯ˆ %s஠உரà¯à®µà®¾à®•à¯à®• இயலவிலà¯à®²à¯ˆ: %s" + +#: ../gio/gdesktopappinfo.c:3120 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "பயனர௠MIME கடà¯à®Ÿà®®à¯ˆà®ªà¯à®ªà¯ கோபà¯à®ªà¯à®±à¯ˆ %s உரà¯à®µà®¾à®•à¯à®• இயலவிலà¯à®²à¯ˆ: %s" + +#: ../gio/gdesktopappinfo.c:3360 ../gio/gdesktopappinfo.c:3384 +msgid "Application information lacks an identifier" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ தகவல௠ஒர௠அடையாளஙà¯à®•ாடà¯à®Ÿà®¿à®¯à¯ˆ இலà¯à®²à®¾à®®à®²à¯ செயà¯à®•ிறதà¯" + +#: ../gio/gdesktopappinfo.c:3617 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "பயனர௠டெஸà¯à®•à¯à®Ÿà®¾à®ªà¯ கோபà¯à®ªà¯ %s உரà¯à®µà®¾à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/gdesktopappinfo.c:3751 +#, c-format +msgid "Custom definition for %s" +msgstr "%sகà¯à®•௠தனிபயன௠விளகà¯à®•à®®à¯" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "இயகà¯à®•ி வெளியேறà¯à®±à®®à¯ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®µà®¿à®²à¯à®²à¯ˆ" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "இயகà¯à®•ி eject_with_operation அலà¯à®²à®¤à¯ வெளியேறà¯à®±à®®à¯ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "இயகà¯à®•ி ஊடகதà¯à®¤à®¿à®²à¯ பதிவ௠செயà¯à®¯à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "இயகà¯à®•ி தà¯à®µà®•à¯à®•தà¯à®¤à¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "இயகà¯à®•ி நிறà¯à®¤à¯à®¤à®¤à¯à®¤à¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS தà¯à®£à¯ˆ கிடைகà¯à®•விலà¯à®²à¯ˆ" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "பதிபà¯à®ªà¯ %d GEmblem கà¯à®±à®¿à®®à¯à®±à¯ˆà®¯à®¿à®²à¯ கையாள à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "தவறான டோகà¯à®•னà¯à®•ளின௠எணà¯à®£à®¿à®•à¯à®•ை (%d) GEmblem கà¯à®±à®¿à®®à¯à®±à¯ˆà®¯à®¿à®²à¯" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "பதிபà¯à®ªà¯ %dà® GEmblemedIcon கà¯à®±à®¿à®®à¯à®±à¯ˆà®¯à®¿à®²à¯ கையாள à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "தவறான டோகà¯à®•ன௠எணà¯à®£à®¿à®•à¯à®•ை (%d) GEmblemedIcon கà¯à®±à®¿à®®à¯à®±à¯ˆà®¯à®¿à®²à¯" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon கà¯à®•ாக ஒர௠GEmblem எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®•ிறதà¯" + +#: ../gio/gfile.c:956 ../gio/gfile.c:1194 ../gio/gfile.c:1332 +#: ../gio/gfile.c:1570 ../gio/gfile.c:1625 ../gio/gfile.c:1683 +#: ../gio/gfile.c:1767 ../gio/gfile.c:1824 ../gio/gfile.c:1888 +#: ../gio/gfile.c:1943 ../gio/gfile.c:3591 ../gio/gfile.c:3646 +#: ../gio/gfile.c:3853 ../gio/gfile.c:3895 ../gio/gfile.c:4358 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7748 ../gio/gfile.c:7838 ../gio/gfile.c:7922 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà®¿à®±à¯à®•௠ஆதரவ௠கிடையாதà¯" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1455 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "கொணà¯à®Ÿà¯à®³à¯à®³ மவà¯à®£à¯à®Ÿà¯ இலà¯à®²à¯ˆ" + +#: ../gio/gfile.c:2502 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "அடைவà¯à®•à¯à®•௠மேலாக நகலெடà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/gfile.c:2562 +msgid "Can't copy directory over directory" +msgstr "அடைவà¯à®•à¯à®•௠மேலாக அடைவினை நகலெடà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/gfile.c:2570 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "இலகà¯à®•௠கோபà¯à®ªà¯ வெளியேறà¯à®±à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gfile.c:2589 +msgid "Can't recursively copy directory" +msgstr "அடைவை மீணà¯à®Ÿà¯à®®à¯ நகலெடà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gfile.c:2871 +msgid "Splice not supported" +msgstr "ஸà¯à®ªà¯à®²à¯ˆà®¸à¯à®•à¯à®•௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gfile.c:2875 +#, c-format +msgid "Error splicing file: %s" +msgstr "பிழையை பிளகà¯à®•à¯à®®à¯ கோபà¯à®ªà¯: %s" + +#: ../gio/gfile.c:3006 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "மவà¯à®©à¯à®Ÿà¯à®Ÿà¯à®•ளà¯à®•à¯à®•௠இடையே நகலெடà¯à®¤à¯à®¤à®²à¯à®•à¯à®•௠(reflink/clone) ஆதரவிலà¯à®²à¯ˆ" + +#: ../gio/gfile.c:3010 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "நகலெடà¯à®¤à¯à®¤à®²à¯à®•à¯à®•௠(reflink/clone) ஆதரவிலà¯à®²à¯ˆ அலà¯à®²à®¤à¯ செலà¯à®²à®¾à®¤à¯" + +#: ../gio/gfile.c:3015 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "நகலெடà¯à®¤à¯à®¤à®²à¯à®•à¯à®•௠(reflink/clone) ஆதரவிலà¯à®²à¯ˆ அலà¯à®²à®¤à¯ செயலà¯à®ªà®Ÿà®¾à®¤à¯" + +#: ../gio/gfile.c:3078 +msgid "Can't copy special file" +msgstr "சிறபà¯à®ªà¯ கோபà¯à®ªà¯ˆ நகலெடà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gfile.c:3843 +msgid "Invalid symlink value given" +msgstr "தவறான symlink மதிபà¯à®ªà¯ கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/gfile.c:4004 +msgid "Trash not supported" +msgstr "கà¯à®ªà¯à®ªà¯ˆ ஆதரவ௠கிடையாதà¯" + +#: ../gio/gfile.c:4116 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "'%c' கோபà¯à®ªà®¿à®©à¯ பெயரà¯à®•ளை பெறà¯à®±à®¿à®°à¯à®•à¯à®•விலà¯à®²à¯ˆ" + +#: ../gio/gfile.c:6540 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "தொகà¯à®¤à®¿ மவà¯à®£à¯à®Ÿà¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gfile.c:6649 +msgid "No application is registered as handling this file" +msgstr "இநà¯à®¤ கோபà¯à®ªà¯ˆà®•௠கையாள எநà¯à®¤ பதிவ௠செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿ விணà¯à®£à®ªà¯à®ªà®®à¯à®®à¯ இலà¯à®²à¯ˆ" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "எணà¯à®£à®¿à®Ÿà®²à¯ மூடபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "கோபà¯à®ªà¯ எணà¯à®£à®¿à®Ÿà®²à¯ சிறநà¯à®¤ செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "கோபà¯à®ªà¯ எண௠à®à®±à¯à®•னவே மூடபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon கà¯à®±à®¿à®®à¯à®±à¯ˆ பதிபà¯à®ªà¯ %d ஠கையாள à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon கà¯à®•௠தவறான உளà¯à®ªà®¾à®Ÿà¯ தரவà¯" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "ஸà¯à®Ÿà¯à®°à¯€à®®à¯ query_infoகà¯à®•௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ஸà¯à®Ÿà¯à®°à¯€à®®à®¿à®²à¯ தேடà¯à®¤à®²à¯ தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "உளà¯à®³à¯€à®Ÿà¯ ஸà¯à®Ÿà¯à®°à¯€à®®à®¿à®²à¯ வெடà¯à®Ÿà¯à®¤à®²à¯ அனà¯à®®à®¤à®¿ இலà¯à®²à¯ˆ" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "ஸà¯à®Ÿà¯à®°à¯€à®®à®¿à®²à¯ வெடà¯à®Ÿà¯à®¤à®²à¯ தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "தவறான டோகà¯à®•னà¯à®•ளின௠எணà¯à®£à®¿à®•à¯à®•ை (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "வகà¯à®ªà¯à®ªà¯ பெயர௠%sகà¯à®•௠வகை இலà¯à®²à¯ˆ" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "வகை %s GIcon à®®à¯à®•பà¯à®ªà¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "வகை %s பிரிகà¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "தவறான பதிபà¯à®ªà¯ எணà¯: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "வகை %s from_tokens()à® GIcon à®®à¯à®•பà¯à®ªà®¿à®²à¯ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "வழஙà¯à®•பà¯à®ªà®Ÿà¯à®Ÿ சினà¯à®© கà¯à®±à®¿à®¯à¯€à®Ÿà®¾à®•à¯à®•தà¯à®¤à®¿à®©à¯ பதிபà¯à®ªà¯ˆ கையாள à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "à®®à¯à®•வரி கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "à®®à¯à®•வரியின௠நீளம௠%u மிக நீளமானதà¯" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "à®®à¯à®•வரியில௠மà¯à®©à¯à®©à¯Šà®Ÿà¯à®Ÿà¯ நீளதà¯à®¤à®¿à®±à¯à®•à¯à®®à¯ அதிகமான பிடà¯à®Ÿà¯à®•ள௠உளà¯à®³à®©" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "'%s' à® IP à®®à¯à®•வரி மூடியாக பாகà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "சாகà¯à®•ெட௠மà¯à®•வரிகà¯à®•௠போதிய இடம௠இலà¯à®²à¯ˆ" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®¾à®¤ சாகà¯à®•ெட௠மà¯à®•வரி" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "உளà¯à®³à¯€à®Ÿà¯ ஸà¯à®Ÿà¯à®°à¯€à®®à¯ வாசிபà¯à®ªà¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1027 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1474 +msgid "Stream has outstanding operation" +msgstr "ஸà¯à®Ÿà¯à®°à¯€à®®à¯ சிறநà¯à®¤ செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "உரà¯à®ªà¯à®ªà®Ÿà®¿ <%s> உளà¯à®³à¯‡ அனà¯à®®à®¤à®¿à®•à¯à®•பà¯à®ªà®Ÿà¯à®µà®¤à®¿à®²à¯à®²à¯ˆ <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "உரà¯à®ªà¯à®ªà®Ÿà®¿ <%s> மேலà¯à®¨à®¿à®²à¯ˆà®¯à®¿à®²à¯ அனà¯à®®à®¤à®¿à®•à¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "%s எனà¯à®± கோபà¯à®ªà¯ வளதà¯à®¤à®¿à®²à¯ பல à®®à¯à®±à¯ˆ உளà¯à®³à®¤à®¾à®•த௠தெரிகிறதà¯" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "எநà¯à®¤ மூலக௠கோபà¯à®ªà®•தà¯à®¤à®¿à®²à¯à®®à¯ '%s' à®à®•௠கணà¯à®Ÿà®±à®¿à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "நடபà¯à®ªà¯ கோபà¯à®ªà®•தà¯à®¤à®¿à®²à¯ '%s' à®à®•௠கணà¯à®Ÿà®±à®¿à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "தெரியாத செயலாகà¯à®• விரà¯à®ªà¯à®ªà®®à¯ \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "தறà¯à®•ாலிகக௠கோபà¯à®ªà¯ˆ உரà¯à®µà®¾à®•à¯à®•à¯à®µà®¤à®¿à®²à¯ தோலà¯à®µà®¿: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s கோபà¯à®ªà¯ˆ வாசிகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "%s கோபà¯à®ªà¯ˆ கமà¯à®ªà¯à®°à®¸à¯ செயà¯à®¯à¯à®®à¯ போத௠பிழை: " + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "உரை உளà¯à®³à¯‡ தோனà¯à®±à®¾à®®à®²à¯ இரà¯à®•à¯à®•லாம௠<%s>" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "வெளியீடà¯à®Ÿà¯à®•௠கோபà¯à®ªà®¿à®©à¯ பெயரà¯" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"படிகà¯à®• வேணà¯à®Ÿà®¿à®¯ கோபà¯à®ªà¯à®•ளைக௠கொணà¯à®Ÿà¯à®³à¯à®³ கோபà¯à®ªà®•à®™à¯à®•ள௠(நடபà¯à®ªà¯ கோபà¯à®ªà®•தà¯à®¤à®¿à®±à¯à®•௠" +"à®®à¯à®©à¯à®©à®¿à®°à¯à®ªà¯à®ªà®¾à®• " +"அமைநà¯à®¤à®¿à®°à¯à®ªà¯à®ªà®¤à¯)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"இலகà¯à®•௠கோபà¯à®ªà¯à®ªà¯ பெயர௠நீடà¯à®šà®¿à®¯à®¾à®²à¯ தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ வெளியீடà¯à®Ÿà¯ வடிவதà¯à®¤à¯ˆ " +"உரà¯à®µà®¾à®•à¯à®•à¯" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "மூலத௠தலைபà¯à®ªà¯ˆ உரà¯à®µà®¾à®•à¯à®•à¯" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" +"உஙà¯à®•ள௠கà¯à®±à¯€à®¯à¯€à®Ÿà¯à®Ÿà®¿à®²à¯ வளக௠கோபà¯à®ªà®¿à®²à¯ இணைகà¯à®•ப௠பயனà¯à®ªà®Ÿà¯à®®à¯ மூலகà¯à®•à¯à®±à®¿à®¯à¯€à®Ÿà¯à®Ÿà¯ˆ உரà¯à®µà®¾à®•à¯à®•à¯" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "சாரà¯à®¨à®¿à®²à¯ˆà®ªà¯ படà¯à®Ÿà®¿à®¯à®²à¯ˆ உரà¯à®µà®¾à®•à¯à®•à¯" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "வளதà¯à®¤à¯ˆ தானாக உரà¯à®µà®¾à®•à¯à®•ி பதிவ௠செயà¯à®¯ வேணà¯à®Ÿà®¾à®®à¯" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "" +"சாரà¯à®ªà¯à®•ளை à®à®±à¯à®±à¯à®®à®¤à®¿ செயà¯à®¯ வேணà¯à®Ÿà®¾à®®à¯; அவறà¯à®±à¯ˆ à®®à¯à®©à¯à®©à®±à®¿à®µà®¿à®•à¯à®•வà¯à®®à¯ G_GNUC_INTERNAL" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "" +"உரà¯à®µà®¾à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ மூலக௠கà¯à®±à®¿à®¯à¯€à®Ÿà¯à®Ÿà¯à®•à¯à®•௠C à®à®Ÿà®©à¯à®Ÿà¯à®Ÿà®¿à®ƒà®ªà®¯à®°à¯ பெயர௠" +"பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"ஒர௠வளக௠கோபà¯à®ªà®¿à®²à¯ வள விவரகà¯à®•à¯à®±à®¿à®ªà¯à®ªà¯ˆ கமà¯à®ªà¯ˆà®²à¯ செயà¯.\n" +"வள விவரகà¯à®•à¯à®±à®¿à®ªà¯à®ªà¯ கோபà¯à®ªà¯à®•à¯à®•௠.gresource.xml எனà¯à®± நீடà¯à®šà®¿ இரà¯à®•à¯à®•à¯à®®à¯,\n" +"வளக௠கோபà¯à®ªà¯à®•à¯à®•௠.gresource எனà¯à®± நீடà¯à®šà®¿ இரà¯à®•à¯à®•à¯à®®à¯." + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "நீஙà¯à®•ள௠சரியாக ஒர௠கோபà¯à®ªà¯à®ªà¯ பெயரையே கொடà¯à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "காலி பெயரà¯à®•ள௠அனà¯à®®à®¤à®¿à®•à¯à®•பà¯à®ªà®Ÿà¯à®µà®¤à®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "தவறான பெயர௠'%s': பெயரà¯à®•ள௠ஒர௠சிறிய எழà¯à®¤à¯à®¤à®¿à®²à¯ ஆரமà¯à®ªà®¿à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"தவறான பெயர௠'%s': தவறான எழà¯à®¤à¯à®¤à¯ '%c'; சிறிய எழà¯à®¤à¯à®¤à¯à®•à¯à®•ளà¯, எணà¯à®•ள௠மறà¯à®±à¯à®®à¯ டேஷ௠" +"('-') " +"ஆகியவை மடà¯à®Ÿà¯à®®à¯‡ அனà¯à®®à®¤à®¿à®•à¯à®•பà¯à®ªà®Ÿà¯à®®à¯." + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "தவறான பெயர௠'%s': இரணà¯à®Ÿà¯ அடà¯à®¤à¯à®¤à®Ÿà¯à®¤à¯à®¤ டேஷà¯à®•ள௠('--') அனà¯à®®à®¤à®¿à®•à¯à®•பà¯à®ªà®Ÿà®¾à®¤à¯." + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "தவறான பெயர௠'%s': கடைசி எழà¯à®¤à¯à®¤à¯ ஒர௠கோடாக இரà¯à®•à¯à®•ாத௠('-')." + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "தவறான பெயர௠'%s': அதிகபடà¯à®š நீளமானத௠1024 ஆகà¯à®®à¯" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " à®à®±à¯à®•னவே கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "ஒர௠திடà¯à®Ÿà®¤à¯à®¤à®¿à®©à¯ 'படà¯à®Ÿà®¿à®¯à®²à®¿à®²à¯' விசைகளை சேரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " à®à®±à¯à®•னவே கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" நிழலà¯à®•ள௠இதில௠; மாறà¯à®±à¯ " +"மதிபà¯à®ªà¯ˆ " +"பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯ " + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"சரியாக ஒர௠'வகை', 'enum' அலà¯à®²à®¤à¯ 'கொடிகளà¯' இதறà¯à®•௠ஒர௠பணà¯à®ªà®¿à®²à¯ " +"கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> இனà¯à®©à¯à®®à¯ வரையறà¯à®•à¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ." + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "தவறான GVariant வகை சரம௠'%s'" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ ஆனால௠திடà¯à®Ÿà®¤à¯à®¤à®¿à®²à¯ எதà¯à®µà¯à®®à¯ நீடிகà¯à®•விலà¯à®²à¯ˆ" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "கà¯à®•௠மேலேறà¯à®±à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " à®à®±à¯à®•னவே கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " à®à®±à¯à®•னவே கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " இனà¯à®©à¯à®®à¯ இலà¯à®²à®¾à®¤ திடà¯à®Ÿà®®à¯ '%s' ஠நீடà¯à®Ÿà®¿à®•à¯à®•ிறதà¯" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " எனà¯à®ªà®¤à¯ இனà¯à®©à¯à®®à¯ இலà¯à®²à®¾à®¤ திடà¯à®Ÿà®®à¯ '%s' இன௠படà¯à®Ÿà®¿à®¯à®²à¯" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "ஒர௠பாதையà¯à®Ÿà®©à¯ ஒர௠திடà¯à®Ÿà®¤à¯à®¤à®¿à®©à¯ படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "ஒர௠பாதையà¯à®Ÿà®©à¯ ஒர௠திடà¯à®Ÿà®¤à¯à®¤à¯ˆ நீடà¯à®Ÿ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" ஒர௠படà¯à®Ÿà®¿à®¯à®²à¯, எத௠படà¯à®Ÿà®¿à®¯à®²à®¿à®²à¯ இலà¯à®²à¯ˆà®¯à¯‹ à® " +"நீடà¯à®Ÿà®¿à®•à¯à®•ிறதà¯" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" நீடà¯à®Ÿà®¿à®•à¯à®•ிறத௠" +"ஆனால௠" +"'%s' ஆனத௠'%s'஠நீடà¯à®Ÿà®¿à®•à¯à®•விலà¯à®²à¯ˆ" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "ஒர௠பாதை, கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯à®° ஒர௠ஸà¯à®²à®¾à®·à¯ à®®à¯à®Ÿà®¿à®µà¯à®Ÿà®©à¯ தà¯à®µà®•à¯à®•பà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "ஒர௠படà¯à®Ÿà®¿à®¯à®²à®¿à®©à¯ பாதை à®®à¯à®Ÿà®¿à®µà¯à®Ÿà®©à¯ இரà¯à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯ ':/'" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id ='%s'> à®à®±à¯à®•னவே கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "கூற௠<%s> மேலà¯à®¨à®¿à®²à¯ˆà®¯à®¿à®²à¯ அனà¯à®®à®¤à®¿à®•à¯à®•பà¯à®ªà®Ÿà®¾à®¤à¯" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯; வெளியேறà¯à®•ிறதà¯.\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "இநà¯à®¤ à®®à¯à®´à¯ கோபà¯à®ªà¯ பà¯à®±à®•à¯à®•ணிகà¯à®•பà¯à®ªà®Ÿà®²à®¾à®®à¯.\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "இநà¯à®¤ கோபà¯à®ªà¯ˆ பà¯à®±à®•à¯à®•ணிகà¯à®•ிறதà¯.\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"'%s' திடà¯à®Ÿà®¤à¯à®¤à®¿à®²à¯ '%s' ஆக கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®®à¯ பà¯à®±à®•à¯à®•ணிகà¯à®•à¯à®®à¯ கோபà¯à®ªà¯ '%s' இல௠விசை " +"எதà¯à®µà¯à®®à¯ " +"இலà¯à®²à¯ˆ" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; பà¯à®±à®•à¯à®•ணிபà¯à®ªà®¤à®±à¯à®•ான இநà¯à®¤ விசையை பà¯à®±à®•à¯à®•ணிகà¯à®•ிறதà¯.\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " மறà¯à®±à¯à®®à¯ --strict கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯; வெளியேறà¯à®•ிறதà¯.\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"'%s' திடà¯à®Ÿà®¤à¯à®¤à®¿à®²à¯ '%s' ஆக கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®®à¯ பà¯à®±à®•à¯à®•ணிகà¯à®•à¯à®®à¯ கோபà¯à®ªà®¿à®²à¯ பிழை " +"பகà¯à®•à¯à®•à¯à®®à¯ விசை " +"'%s': %s. " + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "பà¯à®±à®•à¯à®•ணிபà¯à®ªà®¤à®±à¯à®•ான இநà¯à®¤ விசையை பà¯à®±à®•à¯à®•ணிகà¯à®•ிறதà¯.\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"ஓவரà¯à®°à¯ˆà®Ÿà¯ கோபà¯à®ªà¯ '%s' இல௠உளà¯à®³ திடà¯à®Ÿà®®à¯ '%s' இல௠உளà¯à®³ விசை'%s'திடà¯à®Ÿà®¤à¯à®¤à®¿à®²à¯ " +"கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³ " +"வரமà¯à®ªà¯à®•à¯à®•௠வெளியே உளà¯à®³à®¤à¯" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"'%s' திடà¯à®Ÿà®¤à¯à®¤à®¿à®±à¯à®•ான விசையை பà¯à®±à®•à¯à®•ணிதà¯à®¤à¯ '%s' பà¯à®±à®•à¯à®•ணிபà¯à®ªà¯ கோபà¯à®ªà®¿à®²à¯ '%s' ஆனத௠" +"சரியான " +"தேரà¯à®µà¯à®•ளின௠படà¯à®Ÿà®¿à®¯à®²à®¿à®²à¯ இலà¯à®²à¯ˆ" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled கோபà¯à®ªà®¿à®²à¯ எஙà¯à®•ே சேமிபà¯à®ªà®¤à¯" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "திடà¯à®Ÿà®™à¯à®•ளிலà¯à®³à¯à®³ à®à®¤à®¾à®µà®¤à¯ பிழைகளை ஒதà¯à®•à¯à®•வà¯à®®à¯" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled கோபà¯à®ªà®¿à®²à¯ எழà¯à®¤ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "விசை பெயர௠கடà¯à®Ÿà¯à®ªà¯à®ªà®¾à®Ÿà¯à®•ளை வலà¯à®¯à¯à®±à¯à®¤à¯à®¤ கூடாதà¯" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"அனைதà¯à®¤à¯GSettings திடà¯à®Ÿ கோபà¯à®ªà¯à®•ளை ஒர௠செகà¯à®•ின௠ஒர௠திடà¯à®Ÿà®¤à¯à®¤à®¿à®²à¯ " +"தொகà¯à®¤à¯à®¤à¯†à®´à¯à®¤à®µà¯à®®à¯.\n" +"extension .gschema.xml போனà¯à®±à®µà®±à¯à®±à¯ˆ திடà¯à®Ÿà®•௠கோபà¯à®ªà¯à®•ளà¯, மறà¯à®±à¯à®®à¯\n" +"gschemas.compiled என அழைகà¯à®•பà¯à®ªà®Ÿà¯à®®à¯ செக௠கோபà¯à®ªà®¿à®©à¯ கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯." + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "நீஙà¯à®•ள௠சரியாக ஒர௠நேரடி பெயரை கொடà¯à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "திடà¯à®Ÿ கோபà¯à®ªà¯à®•ள௠எதà¯à®µà¯à®®à¯ காணபà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ:" + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "செயà¯à®µà®¤à®±à¯à®•௠ஒனà¯à®±à¯à®®à®¿à®²à¯à®²à¯ˆ.\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "இரà¯à®•à¯à®•à¯à®®à¯ வெளிபà¯à®ªà®¾à®Ÿà¯ கோபà¯à®ªà¯ நீகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "à®®à¯à®©à¯à®©à®¿à®°à¯à®ªà¯à®ªà¯ உளà¯à®³à®®à¯ˆ அடைவ௠மானிடà¯à®Ÿà®°à¯ வகையை தேட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாத கோபà¯à®ªà¯ பெயர௠%s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "கோபà¯à®ªà¯ à®®à¯à®±à¯ˆà®®à¯ˆ தகவலை பெறà¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "ரூட௠அடைவை மறà¯à®ªà¯†à®¯à®°à®¿à®Ÿ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "கோபà¯à®ªà¯ மறà¯à®ªà¯†à®¯à®°à®¿à®Ÿà¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "கோபà¯à®ªà¯ˆ மறà¯à®ªà¯†à®¯à®°à®¿à®Ÿ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ, கோபà¯à®ªà¯à®ªà¯†à®¯à®°à¯ à®à®±à¯à®•னவே உளà¯à®³à®¤à¯" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "தவறான கோபà¯à®ªà¯ பெயரà¯" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "அடைவை திறகà¯à®• இயலவிலà¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "கோபà¯à®ªà¯ திறகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "கோபà¯à®ªà¯ நீகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "கோபà¯à®ªà®¿à®©à¯ˆ கà¯à®ªà¯à®ªà¯ˆà®•à¯à®•௠அனà¯à®ªà¯à®ªà¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "கà¯à®ªà¯à®ªà¯ˆ அடைவ௠%s஠உரà¯à®µà®¾à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "கà¯à®ªà¯à®ªà¯ˆà®•à¯à®•௠மேல௠நிலை அடைவை தேட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "கà¯à®ªà¯à®ªà¯ˆ அடைவை தேட அலà¯à®²à®¤à¯ உரà¯à®µà®¾à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "கà¯à®ªà¯à®ªà¯ˆ தகவல௠கோபà¯à®ªà®¿à®©à¯ˆ உரà¯à®µà®¾à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "கோபà¯à®ªà¯ˆ இழà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "உளà¯à®³à®®à¯ˆ தவறà¯" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "அடைவை உரà¯à®µà®¾à®•à¯à®•à¯à®®à¯à®ªà¯‹à®¤à¯ பிழை: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "கோபà¯à®ªà¯ à®®à¯à®±à¯ˆà®®à¯ˆ அடையாள இணைபà¯à®ªà¯à®•ளà¯à®•à¯à®•௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "கà¯à®±à®¿à®ªà¯à®ªà¯€à®Ÿà¯à®Ÿà®¿à®©à¯ இணைபà¯à®ªà¯ˆ à®à®±à¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®µà®¤à¯à®²à¯ பிழை: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "பிழை நகரà¯à®¤à¯à®¤à¯à®®à¯ கோபà¯à®ªà¯: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "அடைவில௠அடைவை நகரà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "பினà¯à®šà¯‡à®®à®¿à®ªà¯à®ªà¯ கோபà¯à®ªà¯ உரà¯à®µà®¾à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "பிழை நீகà¯à®•à¯à®®à¯ இலகà¯à®•௠கோபà¯à®ªà¯ : %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "மவà¯à®£à¯à®Ÿà®¿à®±à¯à®•ிடையே நகரà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfile.c:2603 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s இன௠வடà¯à®Ÿà¯à®ªà¯ பயனீடà¯à®Ÿà¯ˆà®¤à¯ தீரà¯à®®à®¾à®©à®¿à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "அளவà¯à®°à¯ மதிபà¯à®ªà¯ பூஜà¯à®œà®¿à®¯à®®à®¾à®• இரà¯à®•à¯à®•கà¯à®•ூடாதà¯" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "தவறான அளவà¯à®°à¯ வகை (சரம௠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "பணà¯à®ªà¯ பெயர௠உளà¯à®³à¯‡ ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "விரிவான அளவà¯à®°à¯'%s' அமைபà¯à®ªà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (தவறான கà¯à®±à®¿à®®à¯à®±à¯ˆ)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "கோபà¯à®ªà¯ '%s' கà¯à®•ான தகவலைப௠பெறூம௠போத௠பிழை: %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "கோபà¯à®ªà¯ டிஸà¯à®•à¯à®°à®¿à®ªà¯à®Ÿà¯à®Ÿà®°à¯à®•à¯à®•ான தகவலைப௠பெறà¯à®µà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "தவறான அளவà¯à®°à¯ வகை (uint32 எதிரà¯à®ªà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "தவறான அளவà¯à®°à¯ வகை (uint64 எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "தவறான அளவà¯à®°à¯ வகை (பைட௠சரம௠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "symlinksகà¯à®•௠அனà¯à®®à®¤à®¿à®•ளை அமைகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "பிழை அமைபà¯à®ªà®¤à®¿à®²à¯ அனà¯à®®à®¤à®¿: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "மாறà¯à®±à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "symlink பூஜà¯à®œà®¿à®¯à®®à®¾à®• இரà¯à®•à¯à®•கà¯à®•ூடாதà¯" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "symlink: %s கை அமைபà¯à®ªà®¤à®¿à®²à¯ பிழை" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "symlink அமைபà¯à®ªà®¤à®¿à®²à¯ பிழை: கோபà¯à®ªà¯ ஒர௠symlinkஆக இலà¯à®²à¯ˆ" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "மாறà¯à®±à®¤à¯à®¤à¯ˆ அமைகà¯à®•à¯à®®à¯ போத௠அலà¯à®²à®¤à¯ அணà¯à®•ல௠நேரதà¯à®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux சூழல௠பூஜà¯à®œà®¿à®¯à®®à®¾à®• இரà¯à®•à¯à®•கà¯à®•ூடாதà¯" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux சூழலை அமைபà¯à®ªà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "SELinux இநà¯à®¤ கணினியில௠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "அளவà¯à®°à¯ %s ஠அமைபà¯à®ªà®¤à®¿à®²à¯ ஆதரவ௠கிடையாதà¯" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "கோபà¯à®ªà®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ வாசிகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "கோபà¯à®ªà¯ˆ பாரà¯à®•à¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "கோபà¯à®ªà¯ˆ à®®à¯à®Ÿà®¿à®•à¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "à®®à¯à®©à¯à®©à®¿à®°à¯à®ªà¯à®ªà¯ உளà¯à®³à®®à¯ˆ கோபà¯à®ªà¯ மானிடà¯à®Ÿà®°à¯ வகையை தேட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "பிழையை எழà¯à®¤à¯à®®à¯ கோபà¯à®ªà¯: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "பழைய பினà¯à®šà¯‡à®®à®¿à®ªà¯à®ªà¯ இணைபà¯à®ªà¯ˆ நீகà¯à®•à¯à®µà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "பினà¯à®šà¯‡à®®à®¿à®ªà¯à®ªà¯ நகலை உரà¯à®µà®¾à®•à¯à®•à¯à®µà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "மறà¯à®ªà¯†à®¯à®°à®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿ தறà¯à®•ாலிக கோபà¯à®ªà®¿à®²à¯ பிழை: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "கோபà¯à®ªà¯ வாசிகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "'%s' பிழையை திறகà¯à®•à¯à®®à¯ கோபà¯à®ªà¯: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "இலகà¯à®•௠கோபà¯à®ªà¯ ஒர௠அடைவிலà¯à®²à¯ˆ" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "இலகà¯à®•௠கோபà¯à®ªà¯ ஒர௠நிரநà¯à®¤à®° கோபà¯à®ªà¯ இலà¯à®²à¯ˆ" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "இநà¯à®¤ கோபà¯à®ªà¯ வெளியாரà¯à®¨à¯à®¤à¯ மாறà¯à®±à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "பிழையை நீகà¯à®•à¯à®®à¯ பழைய கோபà¯à®ªà¯: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "தவறான GSeekType கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "தவறான தேடà¯à®®à¯ கோரிகà¯à®•ை" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream஠தசமமிட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "நினைவக வெளிபà¯à®ªà®¾à®Ÿà¯ ஸà¯à®Ÿà¯à®°à¯€à®®à¯ அளவிடகà¯à®•ூடியதலà¯à®²" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "நினைவக வெளிபà¯à®ªà®¾à®Ÿà¯ ஸà¯à®Ÿà¯à®°à¯€à®®à¯ˆ மறà¯à®…ளவிட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà®¿à®±à¯à®•௠எழà¯à®¤ தேவைபà¯à®ªà®Ÿà¯à®®à¯ நினைவக தொகையானத௠இரà¯à®•à¯à®•à¯à®®à¯ à®®à¯à®•வரி இடதà¯à®¤à¯ˆ விட " +"பெரியதாகà¯à®®à¯" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "ஸà¯à®Ÿà¯à®°à¯†à®®à¯ தà¯à®µà®•à¯à®•தà¯à®¤à®¿à®±à¯à®•௠மà¯à®©à¯ பெற வேணà¯à®Ÿà¯à®®à¯" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "ஸà¯à®Ÿà¯à®°à¯†à®®à¯ தà¯à®µà®•à¯à®•தà¯à®¤à®¿à®±à¯à®•௠மà¯à®©à¯ பெற வேணà¯à®Ÿà¯à®®à¯" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "à®à®±à¯à®±à®®à¯ \"à®à®±à¯à®±à®®à¯ நீகà¯à®•à®®à¯\"஠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "\"வெளியேறà¯\" இல௠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ \"à®à®±à¯à®±à®¨à¯€à®•à¯à®•à®®à¯\" அலà¯à®²à®¤à¯ \"unmount_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ \"வெளியேறà¯à®±à¯\" அலà¯à®²à®¤à¯ \"eject_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "à®à®±à¯à®±à®²à®¾à®©à®¤à¯ \"மீணà¯à®Ÿà¯à®®à¯ à®à®±à¯à®±à®²à¯ˆ\" செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "mount உளà¯à®³à®Ÿà®•à¯à®• வகையை செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "mount à®’à®°à¯à®™à¯à®•ிணைதà¯à®¤à®²à¯ உளà¯à®³à®Ÿà®•à¯à®• வகையை செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gnetworkaddress.c:338 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "பà¯à®°à®µà®²à®©à¯ பெயர௠'%s' '[' but not ']'஠கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/gnetworkmonitorbase.c:189 ../gio/gnetworkmonitorbase.c:292 +msgid "Network unreachable" +msgstr "பிணையதà¯à®¤à¯ˆ அடையமà¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gnetworkmonitorbase.c:227 ../gio/gnetworkmonitorbase.c:257 +msgid "Host unreachable" +msgstr "வழஙà¯à®•ியை அடைய à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "பிணைய மானிடà¯à®Ÿà®°à¯ˆ உரà¯à®µà®¾à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "பிணைய மானிடà¯à®Ÿà®°à¯ˆ உரà¯à®µà®¾à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ:" + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "நெடà¯à®µà¯Šà®°à¯à®•௠நிலையைப௠பெற à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ:" + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:550 +msgid "Output stream doesn't implement write" +msgstr "வெளிபà¯à®ªà®¾à®Ÿà¯ ஸà¯à®Ÿà¯à®°à¯€à®®à¯ எழà¯à®¤à¯à®¤à®²à¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/goutputstream.c:511 ../gio/goutputstream.c:1028 +msgid "Source stream is already closed" +msgstr "மூல ஸà¯à®Ÿà¯à®°à¯€à®®à¯ à®à®±à¯à®•னவே மூடபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s'஠தீரà¯à®•à¯à®•à¯à®®à¯ பிழை: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' இல௠உளà¯à®³ வளம௠இலà¯à®²à¯ˆ" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "'%s' இல௠உளà¯à®³ வளம௠டிகமà¯à®°à®¸à¯ செயலில௠தோலà¯à®µà®¿à®¯à®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "%s இல௠உளà¯à®³ வளம௠ஒர௠கோபà¯à®ªà®•மலà¯à®²" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "உளà¯à®³à¯€à®Ÿà¯ ஸà¯à®Ÿà¯à®°à¯€à®®à¯ வாசிபà¯à®ªà¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gresource-tool.c:487 +msgid "List sections containing resources in an elf FILE" +msgstr "ஒர௠elf FILE இல௠வளஙà¯à®•ளைக௠கொணà¯à®Ÿà¯à®³à¯à®³ பிரிவà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯" + +#: ../gio/gresource-tool.c:493 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"வளஙà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +"SECTION கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯, இநà¯à®¤à®ªà¯ பிரிவில௠உளà¯à®³ வளஙà¯à®•ளை மடà¯à®Ÿà¯à®®à¯ படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +"PATH கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯, பொரà¯à®¨à¯à®¤à¯à®®à¯ வளஙà¯à®•ளை மடà¯à®Ÿà¯à®®à¯ படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯" + +#: ../gio/gresource-tool.c:496 ../gio/gresource-tool.c:506 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:497 ../gio/gresource-tool.c:507 +#: ../gio/gresource-tool.c:514 +msgid "SECTION" +msgstr "SECTION" + +#: ../gio/gresource-tool.c:502 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"விவரஙà¯à®•ளà¯à®Ÿà®©à¯ வளஙà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +"SECTION கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯, இநà¯à®¤à®ªà¯ பிரிவில௠உளà¯à®³ வளஙà¯à®•ளை மடà¯à®Ÿà¯à®®à¯ படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +"PATH கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯, பொரà¯à®¨à¯à®¤à¯à®®à¯ வளஙà¯à®•ளை மடà¯à®Ÿà¯à®®à¯ படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +"விவரஙà¯à®•ளில௠பிரிவà¯, அளவ௠மறà¯à®±à¯à®®à¯ கமà¯à®ªà¯à®°à¯†à®·à®©à¯ ஆகியவை இரà¯à®•à¯à®•à¯à®®à¯" + +#: ../gio/gresource-tool.c:512 +msgid "Extract a resource file to stdout" +msgstr "ஒர௠வளக௠கோபà¯à®ªà¯ˆ stdout கà¯à®•௠பிரிதà¯à®¤à¯†à®Ÿà¯" + +#: ../gio/gresource-tool.c:513 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: ../gio/gresource-tool.c:527 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"பயனà¯à®ªà®¾à®Ÿà¯:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"கடà¯à®Ÿà®³à¯ˆà®•ளà¯:\n" +" help இநà¯à®¤à®¤à¯ தகவலைக௠காணà¯à®ªà®¿\n" +" sections வளப௠பிரிவà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +" list வளஙà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +" details வளஙà¯à®•ளை விவரஙà¯à®•ளà¯à®Ÿà®©à¯ படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +" extract ஒர௠வளதà¯à®¤à¯ˆà®ªà¯ பிரிதà¯à®¤à¯†à®Ÿà¯\n" +"\n" +"விவரமான உதவியைப௠பெற 'gresource help COMMAND' கடà¯à®Ÿà®³à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯.\n" +"\n" + +#: ../gio/gresource-tool.c:541 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"பயனà¯à®ªà®¾à®Ÿà¯:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:548 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION ஒர௠(விரà¯à®®à¯à®ªà®¿à®©à®¾à®²à¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®®à¯) elf பிரிவ௠பெயரà¯\n" + +#: ../gio/gresource-tool.c:552 ../gio/gsettings-tool.c:635 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND விவரிபà¯à®ªà®¤à®±à¯à®•ான (விரà¯à®ªà¯à®ªà®®à®¾à®©) கடà¯à®Ÿà®³à¯ˆ\n" + +#: ../gio/gresource-tool.c:558 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE ஒர௠elf கோபà¯à®ªà¯ (பைனரி அலà¯à®²à®¤à¯ பகிரபà¯à®ªà®Ÿà¯à®Ÿ லைபà¯à®°à®°à®¿)\n" + +#: ../gio/gresource-tool.c:561 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE ஒர௠elf கோபà¯à®ªà¯ (பைனரி அலà¯à®²à®¤à¯ பகிரபà¯à®ªà®Ÿà¯à®Ÿ லைபà¯à®°à®°à®¿)\n" +" அலà¯à®²à®¤à¯ கமà¯à®ªà¯ˆà®²à¯ செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿ வளக௠கோபà¯à®ªà¯\n" + +#: ../gio/gresource-tool.c:565 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:567 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" +" PATH ஒர௠(விரà¯à®®à¯à®ªà®¿à®©à®¾à®²à¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®®à¯) வளப௠பாதை (பகà¯à®¤à®¿à®¯à®¾à®• " +"இரà¯à®•à¯à®•கà¯à®•ூடà¯à®®à¯)\n" + +#: ../gio/gresource-tool.c:568 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:570 +msgid " PATH A resource path\n" +msgstr " PATH வளப௠பாதை\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "'%s' போனà¯à®± திடà¯à®Ÿà®®à¯ எதà¯à®µà¯à®®à¯ இலà¯à®²à¯ˆ\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "திடà¯à®Ÿà®®à¯ '%s' ஆனத௠மற௠அமைகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ (பாதை கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "திடà¯à®Ÿà®®à¯ '%s' ஆனத௠மற௠அமைகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ (பாதை கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "காலி பாதை கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "பாதை ஒர௠ஸà¯à®²à®¾à®·à¯ உடன௠தà¯à®µà®™à¯à®•பà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯ (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "பாதை ஒர௠ஸà¯à®²à®¾à®·à¯ உடன௠மà¯à®Ÿà®¿à®•à¯à®•பà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯ (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "பாதையானத௠இரணà¯à®Ÿà¯ à®…à®°à¯à®•ிலà¯à®³à¯à®³ ஸà¯à®²à®¾à®·à¯à®•ளை கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯ (//)\n" + +#: ../gio/gsettings-tool.c:477 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "மதிபà¯à®ªà¯ வரமà¯à®ªà®¿à®©à¯ வெளிபà¯à®ªà®•à¯à®•தà¯à®¤à®¿à®²à¯ வழஙà¯à®•பà¯à®ªà®Ÿà¯à®Ÿ மதிபà¯à®ªà¯\n" + +#: ../gio/gsettings-tool.c:484 +#, c-format +msgid "The key is not writable\n" +msgstr "விசை எழà¯à®¤à®•à¯à®•ூடியதலà¯à®²\n" + +#: ../gio/gsettings-tool.c:520 +msgid "List the installed (non-relocatable) schemas" +msgstr "நினà¯à®µà®ªà¯à®ªà®Ÿà¯à®Ÿ (மறà¯à®…மைகà¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤) திடà¯à®Ÿà®™à¯à®•ளின௠படà¯à®Ÿà®¿à®¯à®²à¯" + +#: ../gio/gsettings-tool.c:526 +msgid "List the installed relocatable schemas" +msgstr "நிறà¯à®µà®ªà¯à®ªà®Ÿà®•à¯à®•ூடிய மறà¯à®…மைகà¯à®•கà¯à®•ூடிய திடà¯à®Ÿà®™à¯à®•ளின௠படà¯à®Ÿà®¿à®¯à®²à¯" + +#: ../gio/gsettings-tool.c:532 +msgid "List the keys in SCHEMA" +msgstr "திடà¯à®Ÿà®¤à¯à®¤à®¿à®²à¯ விசைகளில௠படà¯à®Ÿà®¿à®¯à®²à¯" + +#: ../gio/gsettings-tool.c:533 ../gio/gsettings-tool.c:539 +#: ../gio/gsettings-tool.c:576 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:538 +msgid "List the children of SCHEMA" +msgstr "திடà¯à®Ÿà®¤à¯à®¤à®¿à®©à¯ சேய௠படà¯à®Ÿà®¿à®¯à®²à¯" + +#: ../gio/gsettings-tool.c:544 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"விசைகள௠மதிபà¯à®ªà¯à®•ளà¯, சà¯à®´à®²à¯à®¨à®¿à®²à¯ˆà®¯à®¿à®©à¯ படà¯à®Ÿà®¿à®¯à®²à¯\n" +"SCHEMA கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ எனிலà¯, அனைதà¯à®¤à¯ விசைகளையà¯à®®à¯ படà¯à®Ÿà®¿à®¯à®µà®¿à®Ÿà®µà¯à®®à¯\n" + +#: ../gio/gsettings-tool.c:546 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:551 +msgid "Get the value of KEY" +msgstr "விசையின௠மதிபà¯à®ªà¯ˆ பெறவà¯à®®à¯" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:570 ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:557 +msgid "Query the range of valid values for KEY" +msgstr "சரியான மதிபà¯à®ªà¯à®•ளின௠விசைகà¯à®•ான வரமà¯à®ªà¯ˆ வினவவà¯à®®à¯" + +#: ../gio/gsettings-tool.c:563 +msgid "Set the value of KEY to VALUE" +msgstr "விசையின௠மதிபà¯à®ªà¯ˆ மதிபà¯à®ªà®¿à®±à¯à®•௠அமைகà¯à®•வà¯à®®à¯" + +#: ../gio/gsettings-tool.c:564 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:569 +msgid "Reset KEY to its default value" +msgstr "அதனà¯à®Ÿà¯ˆà®¯ à®®à¯à®©à¯à®©à®¿à®°à¯à®ªà¯à®ªà¯ மதிபà¯à®ªà®¿à®±à¯à®•௠விசையை மறà¯à®…மைகà¯à®•வà¯à®®à¯" + +#: ../gio/gsettings-tool.c:575 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "அதனà¯à®Ÿà¯ˆà®¯ à®®à¯à®©à¯à®©à®¿à®°à¯à®ªà¯à®ªà¯à®•ளà¯à®•à¯à®•௠திடà¯à®Ÿà®¤à¯à®¤à®¿à®©à¯ அனைதà¯à®¤à¯ விசைகளை " + +#: ../gio/gsettings-tool.c:581 +msgid "Check if KEY is writable" +msgstr "விசை எழà¯à®¤à®•à¯à®•ூடியதாக இரà¯à®¨à¯à®¤à®¾à®²à¯ சரிபாரà¯à®•à¯à®•வà¯à®®à¯" + +#: ../gio/gsettings-tool.c:587 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"மாறà¯à®±à®™à¯à®•ளà¯à®•à¯à®•௠விசையை கணிகà¯à®•வà¯à®®à¯.\n" +"விசை கà¯à®±à®¿à®•à¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ, அனைதà¯à®¤à¯ விசைகளையà¯à®®à¯ திடà¯à®Ÿà®¤à¯à®¤à®¿à®²à¯ கணிகà¯à®•வà¯à®®à¯.\n" +"கணிபà¯à®ªà®¤à¯ˆ நிறà¯à®¤à¯à®¤à¯à®µà®¤à®±à¯à®•௠^C ஠பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯.\n" + +#: ../gio/gsettings-tool.c:590 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:602 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"பயனà¯à®ªà®¾à®Ÿà¯:\n" +" gsettings --version\n" +"gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"கடà¯à®Ÿà®³à¯ˆà®•ளà¯:\n" +" help இநà¯à®¤à®¤à¯ தகவலைக௠காணà¯à®ªà®¿\n" +" list-schemas நிறà¯à®µà®¿à®¯à¯à®³à¯à®³ திடà¯à®Ÿà®µà®Ÿà®¿à®µà®™à¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +" list-relocatable-schemas இடமாறà¯à®±à®•à¯à®•ூடிய திடà¯à®Ÿà®µà®Ÿà®¿à®µà®™à¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +" list-keys திடà¯à®Ÿà®µà®Ÿà®¿à®µà®¤à¯à®¤à®¿à®²à¯à®³à¯à®³ விசைகளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +" list-children திடà¯à®Ÿà®µà®Ÿà®¿à®µà®¤à¯à®¤à®¿à®©à¯ சேய௠உறà¯à®ªà¯à®ªà¯à®•ளைப௠படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +" list-recursively விசைகளையà¯à®®à¯ மதிபà¯à®ªà¯à®•ளையà¯à®®à¯ சேரà¯à®¤à¯à®¤à¯à®ªà¯ படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯\n" +" range ஒர௠விசையின௠வரமà¯à®ªà¯ˆ வினவà¯à®•ிறதà¯\n" +" get ஒர௠விசையின௠மதிபà¯à®ªà¯ˆà®ªà¯ பெறà¯\n" +" set ஒர௠விசையின௠மதிபà¯à®ªà¯ˆ அமை\n" +" reset ஒர௠விசையின௠மதிபà¯à®ªà¯ˆ மீடà¯à®Ÿà®®à¯ˆ\n" +" reset-recursively கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ திடà¯à®Ÿà®µà®Ÿà®¿à®µà®¤à¯à®¤à®¿à®²à¯ உளà¯à®³ எலà¯à®²à®¾ " +"மதிபà¯à®ªà¯à®•ளையà¯à®®à¯ " +"மீடà¯à®Ÿà®®à¯ˆ\n" +" writable ஒர௠விசை எழà¯à®¤à®•à¯à®•ூடியதா என சோதி\n" +" monitor மாறà¯à®±à®™à¯à®•ளைக௠கவனி\n" +"\n" +"விவரமான உதவிகà¯à®•௠'gsettings help COMMAND' கடà¯à®Ÿà®³à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯.\n" +"\n" + +#: ../gio/gsettings-tool.c:625 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"பயனà¯à®ªà®¾à®Ÿà¯:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:631 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR கூடà¯à®¤à®²à¯ திடà¯à®Ÿà®µà®Ÿà®¿à®µà®™à¯à®•ளைத௠தேடà¯à®µà®¤à®±à¯à®•ான கோபà¯à®ªà®•à®®à¯\n" + +#: ../gio/gsettings-tool.c:639 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" + +#: ../gio/gsettings-tool.c:644 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY (விரà¯à®ªà¯à®ªà®®à®¾à®©) விசை திடà¯à®Ÿà®¤à¯à®¤à®¿à®©à¯à®³à¯ உளà¯à®³à®¤à¯\n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The key within the schema\n" +msgstr " KEY விசை திடà¯à®Ÿà®¤à¯à®¤à®¿à®©à¯à®³à¯ உளà¯à®³à®¤à¯\n" + +#: ../gio/gsettings-tool.c:652 +msgid " VALUE The value to set\n" +msgstr "மதிபà¯à®ªà¯ அமைபà¯à®ªà®¤à®±à¯à®•ான மதிபà¯à®ªà¯\n" + +#: ../gio/gsettings-tool.c:707 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s இலிரà¯à®¨à¯à®¤à¯ திடà¯à®Ÿà®™à¯à®•ளை à®à®±à¯à®± à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s\n" + +#: ../gio/gsettings-tool.c:769 +#, c-format +msgid "Empty schema name given\n" +msgstr "காலி திடà¯à®Ÿà®ªà¯à®ªà¯†à®¯à®°à¯ கொடà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯\n" + +#: ../gio/gsettings-tool.c:798 +#, c-format +msgid "No such key '%s'\n" +msgstr "'%s' போனà¯à®± விசை எதà¯à®µà¯à®®à¯ இலà¯à®²à¯ˆ\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "தவறான சாகà¯à®•ெடà¯, தà¯à®µà®•à¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "தவறான சாகà¯à®•ெடà¯, இதனால௠தà¯à®µà®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "சாகà¯à®•ெட௠à®à®±à¯à®•னவே மூடபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "சாகà¯à®•ெட௠I/O நேரம௠மà¯à®Ÿà®¿à®¨à¯à®¤à®¤à¯" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "GSocketà® fdஇலிரà¯à®¨à¯à®¤à¯ உரà¯à®µà®¾à®•à¯à®•à¯à®•ிறதà¯: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "சாகà¯à®•ெடà¯à®Ÿà¯ˆ உரà¯à®µà®¾à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "தெரியாத கà¯à®Ÿà¯à®®à¯à®ªà®®à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "தெரியாத நெறிமà¯à®±à¯ˆ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "உளà¯à®³à®®à¯ˆ à®®à¯à®•வரியை பெற à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "தொலை à®®à¯à®•வரியை பெற à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "கேடà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "à®®à¯à®•வரியை பிணைகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "மலà¯à®Ÿà®¿à®•ாஸà¯à®Ÿà¯ கà¯à®´à¯à®µà¯ˆ இணைபà¯à®ªà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "மலà¯à®Ÿà®¿à®•ாஸà¯à®Ÿà¯ கà¯à®´à¯à®µà®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ வெளியேறà¯à®µà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "மூலம௠சாரà¯à®¨à¯à®¤ மலà¯à®Ÿà®¿à®•ாஸà¯à®Ÿà¯à®Ÿà¯à®•à¯à®•௠ஆதரவ௠இலà¯à®²à¯ˆ" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "இணைபà¯à®ªà¯ˆ à®à®±à¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "இணைபà¯à®ªà¯ செயலிலà¯à®³à¯à®³à®¤à¯" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "நிலà¯à®µà¯ˆ பிழையைப௠பெற à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: " + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "தரவைப௠பெறà¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "தரவை அனà¯à®ªà¯à®ªà¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "சாகà¯à®•ெடà¯à®Ÿà¯ˆ பணிநிறà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "சாகà¯à®•ெடà¯à®Ÿà¯ˆ மூடà¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "சாகà¯à®•ெட௠நிலைகà¯à®•ாக காதà¯à®¤à®¿à®°à¯à®•à¯à®•ிறதà¯: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "செயà¯à®¤à®¿ அனà¯à®ªà¯à®ªà¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage கà¯à®•௠வினà¯à®Ÿà¯‹à®šà®¿à®²à¯ ஆதரவிலà¯à®²à¯ˆ" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "செயà¯à®¤à®¿ பெறà¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gsocket.c:4516 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "சாகà¯à®•ெட௠சானà¯à®±à®³à®¿à®ªà¯à®ªà¯à®•ளை வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials இநà¯à®¤ OS கà¯à®•ாக செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "பதிலி சேவையகம௠%s உடன௠இணைகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s கà¯à®•௠இணைகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "இணைகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1603 +msgid "Unknown error on connect" +msgstr "இணைபà¯à®ªà®¿à®²à¯ தெரியாத தவறà¯" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1538 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "TCP அலà¯à®²à®¾à®¤ இணைபà¯à®ªà®¿à®²à¯ பதிலியைப௠பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®¤à®²à¯à®•à¯à®•௠ஆதரவிலà¯à®²à¯ˆ." + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1559 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "பà¯à®°à®¾à®•à¯à®¸à®¿ '%s' தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ." + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "கேடà¯à®ªà®¾à®³à®°à¯ à®à®±à¯à®•னவே மூடபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "சேரà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ சாகà¯à®•ெட௠மூடபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 ஆனத௠IPv6 à®®à¯à®•வரி '%s' கà¯à®•௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 நெறிமà¯à®±à¯ˆà®•à¯à®•ான பயனர௠பெயர௠மிக நீளமாக உளà¯à®³à®¤à¯" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 நெறிமà¯à®±à¯ˆà®•à¯à®•ான வழஙà¯à®•ி பெயர௠'%s' ஆனத௠மிக நீளமாக உளà¯à®³à®¤à¯" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "சேவையகம௠ஒர௠SOCKSv4 பà¯à®°à®¾à®•à¯à®¸à®¿ சேவையகம௠இலà¯à®²à¯ˆ." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "இணைபà¯à®ªà¯ வழியாக SOCKSv4 சேவையகம௠மறà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "சேவையகமானத௠ஒர௠SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿ சேவையகம௠இலà¯à®²à¯ˆ." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿à®•à¯à®•௠அஙà¯à®•ீகாரம௠தேவைபà¯à®ªà®Ÿà¯à®•ிறதà¯." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿à®¯à®¿à®²à¯ ஒர௠அஙà¯à®•ீகரிகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿ à®®à¯à®±à¯ˆ தேவைபà¯à®ªà®Ÿà¯à®•ிறத௠இத௠GLib ஆல௠" +"தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 நெறிமà¯à®±à¯ˆà®•à¯à®•ான பயனர௠பெயர௠அலà¯à®²à®¤à¯ கடவà¯à®šà¯à®šà¯Šà®²à¯ மிக நீளமாக உளà¯à®³à®¤à¯." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "தவறான பயனரà¯à®ªà¯†à®¯à®°à¯ அலà¯à®²à®¤à¯ கடவà¯à®šà¯à®šà¯Šà®²à®¾à®²à¯ SOCKSv5 à®…à®™à¯à®•ீகாரம௠தோலà¯à®µà®¿à®¯à¯à®±à¯à®±à®¤à¯." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "SOCKSv5 நெறிமà¯à®±à¯ˆà®•à¯à®•ான வழஙà¯à®•ி பெயர௠'%s' ஆனத௠மிக நீளமாக உளà¯à®³à®¤à¯" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿ சேவையகமானத௠தெரியாக à®®à¯à®•வரி வகையை பயனà¯à®ªà®Ÿà¯à®•ிறதà¯." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "உளà¯à®³à®¾à®°à¯à®¨à¯à®¤ SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿ சேவையக பிழை." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "ரூலà¯à®šà¯†à®Ÿà¯à®Ÿà®¿à®©à¯ படி SOCKSv5 இணைபà¯à®ªà¯ அனà¯à®®à®¤à®¿à®•à¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 சேவையகதà¯à®¤à®¿à®©à¯ வழியாக பà¯à®°à®µà®²à®©à¯ அடையமà¯à®Ÿà®¿à®¯à®¾à®¤à®¤à¯." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿ வழியாக பிணையதà¯à®¤à¯ˆ அடையமà¯à®Ÿà®¿à®¯à®¾à®¤à®¤à¯." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿ வழியாக இணைபà¯à®ªà¯ மறà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿ 'இணை' கடà¯à®Ÿà®³à¯ˆà®•à¯à®•௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "வழஙà¯à®•பà¯à®ªà®Ÿà¯à®Ÿ à®®à¯à®•வரி வகையானத௠SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿à®•à¯à®•௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "தெரியாத SOCKSv5 பà¯à®°à®¾à®•à¯à®¸à®¿ பிழை." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "பதிபà¯à®ªà¯ %d இன௠GThemedIcon கà¯à®±à®¿à®®à¯à®±à¯ˆà®¯à®¾à®•à¯à®•தà¯à®¤à®¿à®±à¯à®•௠கையாள à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®© à®®à¯à®•வரிகள௠இலà¯à®²à¯ˆ" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' ஠தலைகீழாக தீரà¯à®•à¯à®•ையில௠பிழை: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "'%s' கà¯à®•௠கோரபà¯à®ªà®Ÿà¯à®Ÿ வகையிலான DNS பதிவ௠இலà¯à®²à¯ˆ" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "தறà¯à®•ாலிகமாக '%s'஠தீரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "%s஠தீரà¯à®•à¯à®•ையில௠பிழை" + +#: ../gio/gtlscertificate.c:247 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM தனிபà¯à®ªà®Ÿà¯à®Ÿ திறபà¯à®ªà¯ˆ கà¯à®±à®¿à®¨à¯€à®•à¯à®•ம௠செயà¯à®¯ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../gio/gtlscertificate.c:252 +msgid "No PEM-encoded private key found" +msgstr "PEM-மறைகà¯à®±à®¿à®¯à®¾à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ தனிபà¯à®ªà®Ÿà¯à®Ÿ விசை காணபà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gtlscertificate.c:262 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM தனிபடà¯à®Ÿ விசையை பிரிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gtlscertificate.c:287 +msgid "No PEM-encoded certificate found" +msgstr "PEM-மறைகà¯à®±à®¿à®¯à®¾à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ சானà¯à®±à®¿à®¤à®´à¯ˆ காணபà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gtlscertificate.c:296 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-மறைகà¯à®±à®¿à®¯à®¾à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ சானà¯à®±à®¿à®¤à®´à¯ˆ பகà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"உஙà¯à®•ள௠அணà¯à®•ல௠பூடà¯à®Ÿà®ªà¯à®ªà®Ÿà¯à®µà®¤à®±à¯à®•௠மà¯à®©à¯ சரியாக கடவà¯à®šà¯à®šà¯Šà®²à¯à®²à¯ˆ உளà¯à®³à®¿à®Ÿà¯à®µà®¤à®±à¯à®•ான கடைசி " +"வாயà¯à®ªà¯à®ªà®¾à®•à¯à®®à¯." + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"உளà¯à®³à®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿ பல கடவà¯à®šà¯à®šà¯Šà®²à¯ தவறானதà¯, இத௠போனà¯à®± தோலà¯à®µà®¿à®•ளà¯à®•à¯à®•௠பின௠உஙà¯à®•ள௠" +"அணà¯à®•ல௠பூடà¯à®Ÿà®ªà¯à®ªà®Ÿà¯à®®à¯." + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "உளà¯à®³à®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿ கடவà¯à®šà¯à®šà¯Šà®²à¯ தவறானதà¯." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 கடà¯à®Ÿà¯à®ªà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ செயà¯à®¤à®¿à®¯à¯ˆ எதிரà¯à®ªà¯à®ªà®¾à®°à¯à®•à¯à®•ிறதà¯, %d ஠பெறà¯à®±à®¤à¯" +msgstr[1] "1 கடà¯à®Ÿà¯à®ªà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ செயà¯à®¤à®¿à®¯à¯ˆ எதிரà¯à®ªà¯à®ªà®¾à®°à¯à®•à¯à®•ிறதà¯, %d ஠பெறà¯à®±à®¤à¯" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "எதிரà¯à®ªà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà®¾à®¤ தà¯à®£à¯ˆ தரவ௠வகை" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "ஒர௠fd ஠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•ிறதà¯, ஆனால௠%d ஠பெறà¯à®±à®¤à¯\n" +msgstr[1] "ஒர௠fd ஠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•ிறதà¯, ஆனால௠%d஠பெறà¯à®±à®¤à¯\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "தவறான fd பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "சானà¯à®±à¯à®•ளà¯à®•à¯à®•௠பிழையை அனà¯à®ªà¯à®ªà¯à®•ிறதà¯:" + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +"SO_PASSCRED ஆனத௠சாகà¯à®•ெடà¯à®Ÿà®¿à®±à¯à®•ாக செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯ பிழை " +"சரிபாரà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®•ிறதà¯: %s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "பிழை SO_PASSCRED ஠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•ிறதà¯: %s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"பெறà¯à®®à¯ சானà¯à®±à¯à®•ளà¯à®•à¯à®•ாக ஆனால௠பூஜà¯à®œà®¿à®¯ பைடà¯à®Ÿà¯à®•ளை வாணிபà¯à®ªà®¤à®±à¯à®•ான ஒர௠ஒறà¯à®±à¯ˆ பைடà¯à®Ÿà¯ˆ " +"வாசிகà¯à®• " +"எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•ிறதà¯" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "கடà¯à®Ÿà¯à®ªà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ செயà¯à®¤à®¿à®¯à¯ˆ எதிரà¯à®ªà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ, %d஠பெறà¯à®•ிறதà¯" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED செயலà¯à®¨à¯€à®•à¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "கோபà¯à®ªà¯ விவரிபà¯à®ªà®¾à®©à¯ˆ வாசிபà¯à®ªà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "கோபà¯à®ªà¯ விவரிபà¯à®ªà®¾à®©à¯ˆ மூடà¯à®µà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/gunixmounts.c:2054 ../gio/gunixmounts.c:2107 +msgid "Filesystem root" +msgstr "கோபà¯à®ªà¯ à®®à¯à®±à¯ˆà®®à¯ˆ ரூடà¯" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "கோபà¯à®ªà¯ விவரிபà¯à®ªà®¾à®©à®¿à®²à¯ எழà¯à®¤à¯à®µà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "யà¯à®©à®¿à®•à¯à®¸à¯ டொமைன௠சாகà¯à®•ெட௠மà¯à®•வரிகளà¯à®•à¯à®•௠இநà¯à®¤ கணினியில௠ஆதரவிலà¯à®²à¯ˆ" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "தொகà¯à®¤à®¿ வெளியேறà¯à®±à®¤à¯à®¤à¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "தொகà¯à®¤à®¿ eject_with_operation அலà¯à®²à®¤à¯ வெளியேறà¯à®±à®¤à¯à®¤à¯ˆ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆ காணவிலà¯à®²à¯ˆ" + +#: ../gio/gwin32appinfo.c:306 +#, c-format +msgid "Error launching application: %s" +msgstr "பிழையை கணà¯à®Ÿà¯à®ªà®¿à®Ÿà®¿à®•à¯à®•à¯à®®à¯ விணà¯à®£à®ªà¯à®ªà®®à¯: %s" + +#: ../gio/gwin32appinfo.c:342 +msgid "URIs not supported" +msgstr "URIs தà¯à®£à¯ˆà®ªà¯à®ªà¯à®°à®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gwin32appinfo.c:364 +msgid "association changes not supported on win32" +msgstr "win32இல௠அமைபà¯à®ªà¯ மாறà¯à®±à®™à¯à®•ள௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®µà®¤à®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gwin32appinfo.c:376 +msgid "Association creation not supported on win32" +msgstr "win32இல௠அமைபà¯à®ªà¯ உரà¯à®µà®¾à®•à¯à®•ம௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®µà®¤à®¿à®²à¯à®²à¯ˆ" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "கையாளà¯à®µà®¤à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ வாசிகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "பிழை மூடà¯à®®à¯ கைபà¯à®ªà®¿à®Ÿà®¿: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "கையாளà¯à®µà®¤à®±à¯à®•௠எழà¯à®¤à¯à®µà®¤à®¿à®²à¯ பிழை: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "போதà¯à®®à®¾à®© நினைவகம௠இலà¯à®²à¯ˆ" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "உளà¯à®³à®¾à®°à¯à®¨à¯à®¤ பிழை: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "அதிக உளà¯à®³à¯€à®Ÿà¯ தேவை" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "தவறான சà¯à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ தரவà¯" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "கவனிகà¯à®• வேணà¯à®Ÿà®¿à®¯ à®®à¯à®•வரி" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "GTestDbus உடன௠போடà¯à®Ÿà®¿à®¯à®¿à®Ÿà¯à®µà®¤à®±à¯à®•௠பà¯à®±à®•à¯à®•ணிகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "à®®à¯à®•வரியை அசà¯à®šà®¿à®Ÿà¯" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "à®®à¯à®•வரியை ஷெல௠பயனà¯à®®à¯à®±à¯ˆà®¯à®¿à®²à¯ அசà¯à®šà®¿à®Ÿà¯" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "ஒர௠dbus சேவையை இயகà¯à®•à¯" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "தவறான அளவà¯à®°à¯à®•à¯à®•ள௠(args)\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "எதிரà¯à®ªà®¾à®°à®¾à®¤ பணà¯à®ªà¯à®•à¯à®•ூற௠'%s' இநà¯à®¤ உறà¯à®ªà¯à®ªà¯à®•à¯à®•௠'%s'" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "மதிபà¯à®ªà¯ '%s' கà¯à®•௠'%s' உறà¯à®ªà¯à®ªà¯ எதà¯à®µà¯à®®à¯ இலà¯à®²à¯ˆ" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "எதிரà¯à®ªà®¾à®°à®¾à®¤ ஒடà¯à®Ÿà¯'%s', ஒடà¯à®Ÿà¯ '%s' எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "'%s' கà¯à®•à¯à®³à¯ எதிரà¯à®ªà®¾à®°à®¾à®¤ ஒடà¯à®Ÿà¯ '%s' உளà¯à®³à®¤à¯" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "தரவ௠அடைவà¯à®•ளில௠சரியான பà¯à®¤à¯à®¤à®•கà¯à®•à¯à®±à®¿ கோபà¯à®ªà¯ எதà¯à®µà¯à®®à¯ இலà¯à®²à¯ˆ" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s' கà¯à®•௠à®à®±à¯à®•னவே பà¯à®¤à¯à®¤à®•கà¯à®•à¯à®±à®¿ உளà¯à®³à®¤à¯" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URIகà¯à®•௠பà¯à®¤à¯à®¤à®•கà¯à®•à¯à®±à®¿ எதà¯à®µà¯à®®à¯ இலà¯à®²à¯ˆ '%s'" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s'கà¯à®•௠MIME வகை எதà¯à®µà¯à®®à¯ பà¯à®¤à¯à®¤à®•கà¯à®•à¯à®±à®¿à®¯à®¿à®²à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s'கà¯à®•௠பà¯à®¤à¯à®¤à®•கà¯à®•à¯à®±à®¿à®¯à®¿à®²à¯ தனிபடà¯à®Ÿ கொடி எதà¯à®µà¯à®®à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s'கà¯à®•ான பà¯à®¤à¯à®¤à®•கà¯à®•à¯à®±à®¿à®¯à®¿à®²à¯ கà¯à®´à¯à®•à¯à®•ள௠எதà¯à®µà¯à®®à¯ அமைகà¯à®•பà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "'%s' பெயரிலà¯à®³à¯à®³ பயனà¯à®ªà®¾à®Ÿà¯ '%s'கà¯à®•௠ஒர௠பà¯à®¤à¯à®¤à®•கà¯à®•à¯à®±à®¿à®¯à¯ˆ பதிவ௠செயà¯à®¤à®¤à¯" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "exec வரி '%s' ஠யூஆரà¯à® (URI) '%s' உடன௠விரிவாகà¯à®•à¯à®¤à®²à¯ தோலà¯à®µà®¿à®¯à¯à®±à¯à®±à®¤à¯" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "உளà¯à®³à¯€à®Ÿà®¿à®©à¯ à®®à¯à®Ÿà®¿à®µà®¿à®²à¯ பூரà¯à®¤à¯à®¤à®¿à®¯à®¾à®•ாத வரியà¯à®°à¯ வரிசைமà¯à®±à¯ˆ" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "பினà¯à®©à®Ÿà¯ˆà®ªà¯à®ªà¯ '%s', '%s' கà¯à®±à®¿à®•௠கணமிறà¯à®•௠மாறà¯à®± à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s' \"கோபà¯à®ªà¯\"திடà¯à®Ÿà®¤à¯à®¤à¯ˆ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®®à¯ à®®à¯à®´à¯à®®à¯ˆà®¯à®¾à®© URI அலà¯à®²" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "உளà¯à®³à®®à¯ˆà®•௠கோபà¯à®ªà¯ வலை à®®à¯à®•வரி '%s' இல௠ஓர௠'#' இலà¯à®²à®¾à®®à®²à¯ இரà¯à®•à¯à®•லாமà¯" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "'%s' செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாத வலை à®®à¯à®•வரி" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "'%s' வலை à®®à¯à®•வரியின௠விரà¯à®¨à¯à®¤à¯‹à®®à¯à®ªà¯à®ªà¯-பெயர௠செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாததà¯" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "வலை à®®à¯à®•வரி '%s' இல௠செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாத 'விடà¯à®ªà®Ÿà¯' வரியà¯à®°à¯à®•ளà¯" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s' பாதைபà¯-பெயர௠ஓர௠தனிப௠பாதை அலà¯à®²" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "பிழையான விரà¯à®¨à¯à®¤à¯‹à®®à¯à®ªà¯à®ªà¯-பெயரà¯" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "காலை" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "மாலை" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A %d %B %Y %I:%M:%S %p %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%A %d %B %Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%I:%M:%S %Z" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p %Z" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "ஜனவரி" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "பிபà¯à®°à®µà®°à®¿" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "மாரà¯à®šà¯" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "à®à®ªà¯à®°à®²à¯" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "மே" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "ஜூனà¯" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "ஜூலை" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "ஆகஸà¯à®Ÿà¯" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "செபà¯à®Ÿà®®à¯à®ªà®°à¯" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "அகà¯à®Ÿà¯‹à®ªà®°à¯" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "நவமà¯à®ªà®°à¯" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "டிசமà¯à®ªà®°à¯" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ஜன" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "பிபà¯" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "மாரà¯" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à®à®ªà¯" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "மே" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "ஜூனà¯" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "ஜூலை" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ஆகஸà¯" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "செபà¯" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "அகà¯" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "நவà¯" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "டிசமà¯" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "திஙà¯à®•ளà¯" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "செவà¯à®µà®¾à®¯à¯" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "பà¯à®¤à®©à¯" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "வியாழனà¯" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "வெளà¯à®³à®¿" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "சனி" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ஞாயிறà¯" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "தி" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "செ" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "பà¯" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "வி" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "வெ" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ச" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ஞா" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "'%s' அடைவ௠திறகà¯à®•à¯à®®à¯à®ªà¯‹à®¤à¯ பிழை: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "கோபà¯à®ªà¯ \"%2$s\" à®à®ªà¯ படிகà¯à®• %1$lu பைடà¯à®Ÿà¯ˆ ஒதà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" +msgstr[1] "கோபà¯à®ªà¯ \"%2$s\" à®à®ªà¯ படிகà¯à®• %1$lu பைடà¯à®Ÿà¯à®•ளை ஒதà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' கோபà¯à®ªà¯ வாசிகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "கோபà¯à®ªà¯ \"%s\" மிகபà¯à®ªà¯†à®°à®¿à®¯à®¤à¯" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' கோபà¯à®ªà®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' கோபà¯à®ªà¯ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' கோபà¯à®ªà®¿à®©à¯ பணà¯à®ªà¯à®•ளை பெறமà¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: fstat() செயலிழநà¯à®¤à®¤à¯: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' கோபà¯à®ªà¯ˆ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: fdopen() செயலிழநà¯à®¤à®¤à¯: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"'%s'கோபà¯à®ªà®¿à®©à¯ˆ '%s'கà¯à®•௠மறà¯à®ªà¯†à®¯à®°à®¿à®Ÿ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: g_rename() செயலிழநà¯à®¤à®¤à¯: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' கோபà¯à®ªà¯ˆ படைகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "கோபà¯à®ªà¯ '%s' இல௠எழà¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: write() தோலà¯à®µà®¿à®¯à®Ÿà¯ˆà®¨à¯à®¤à®¤à¯: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "கோபà¯à®ªà¯ '%s' எழà¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: fsync() செயலிழநà¯à®¤à®¤à¯: %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "இரà¯à®•à¯à®•à¯à®®à¯ கோபà¯à®ªà¯ '%s' ஠நீகà¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯: g_unlink() செயலிழநà¯à®¤à®¤à¯: %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "'%s' படிம அசà¯à®šà¯ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாததà¯; அதனில௠'%s' இரà¯à®•à¯à®•க௠கூடாதà¯" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "'%s' படிம அசà¯à®šà®¿à®²à¯ XXXXXX இலà¯à®²à¯ˆ" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "'%s' எனà¯à®ªà®¤à®©à¯-கà¯à®±à¯à®•à¯à®•ம௠இணைபà¯à®ªà¯ˆ வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "எனà¯à®ªà®¤à®©à¯-கà¯à®±à¯à®•à¯à®•ம௠இணைபà¯à®ªà¯à®•ளà¯à®•à¯à®•௠ஆதரவ௠கிடையாதà¯" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' லிரà¯à®¨à¯à®¤à¯'%s'கà¯à®•௠மாறà¯à®±à®¿à®¯à¯ˆ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string இல௠மூலமாக வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "வாசிபà¯à®ªà¯à®¤à¯ தாஙà¯à®•கதà¯à®¤à®¿à®²à¯ மாறà¯à®±à®ªà¯à®ªà®Ÿà®¾à®¤ மீதித௠தரவà¯à®•ளà¯" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "வாயà¯à®•à¯à®•ால௠பாதி வரியà¯à®°à¯à®µà®¿à®²à¯ à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®•ிறதà¯" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end இல௠மூலமாக வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "தேடல௠அடைவà¯à®•ளில௠சரியான விசை கோபà¯à®ªà®¿à®©à¯ˆ காண à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "ஒர௠மà¯à®±à¯ˆà®¯à®¾à®© கோபà¯à®ªà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"விசை கோபà¯à®ªà¯ வரி '%s' கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯ இத௠விசை-மதிபà¯à®ªà¯ சோடியை, கà¯à®´à¯, அலà¯à®²à®¤à¯ " +"கà¯à®±à®¿à®ªà¯à®ªà¯ அலà¯à®²" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாத கà¯à®´à¯ பெயரà¯: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "விசை கோபà¯à®ªà¯ ஒர௠கà¯à®´à¯à®µà®¾à®• ஆரமà¯à®ªà®®à®¾à®•ாதà¯" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•ாத விசை பெயரà¯: %s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "விசை கோபà¯à®ªà¯ தà¯à®£à¯ˆà®¯à®¿à®²à¯à®²à®¾à®¤ கà¯à®±à®¿à®®à¯à®±à¯ˆà®¯à¯ˆ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯ '%s'" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1692 ../glib/gkeyfile.c:3072 +#: ../glib/gkeyfile.c:3138 ../glib/gkeyfile.c:3264 ../glib/gkeyfile.c:3397 +#: ../glib/gkeyfile.c:3539 ../glib/gkeyfile.c:3768 ../glib/gkeyfile.c:3835 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "விசை கோபà¯à®ªà¯ கà¯à®´à¯à®µà®¿à®©à¯ˆ கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®•விலà¯à®²à¯ˆ '%s'" + +#: ../glib/gkeyfile.c:1704 +#, c-format +msgid "Key file does not have key '%s'" +msgstr " '%s' விசையை விசை கோபà¯à®ªà¯ கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®•விலà¯à®²à¯ˆ" + +#: ../glib/gkeyfile.c:1811 ../glib/gkeyfile.c:1927 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr " '%s'மதிபà¯à®ªà®¿à®©à¯ˆ உடைய '%s'விசை விசை கோபà¯à®ªà¯ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯, இத௠UTF-8 அலà¯à®²" + +#: ../glib/gkeyfile.c:1831 ../glib/gkeyfile.c:1947 ../glib/gkeyfile.c:2316 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"%s'விசையை விசை கோபà¯à®ªà¯ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯ அத௠கொணà¯à®Ÿà¯à®³à¯à®³ மதிபà¯à®ªà®¿à®©à¯ˆ மாறà¯à®± à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯." + +#: ../glib/gkeyfile.c:2533 ../glib/gkeyfile.c:2901 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"விசைக௠கோபà¯à®ªà®¿à®²à¯ '%s' கà¯à®´à¯à®µà®¿à®²à¯ '%s' விசை உளà¯à®³à®¤à¯. அத௠கொணà¯à®Ÿà¯à®³à¯à®³ மதிபà¯à®ªà®¿à®©à¯ˆ " +"பà¯à®°à®¿à®¨à¯à®¤à¯à®•ொளà¯à®³ " +"à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯." + +#: ../glib/gkeyfile.c:2611 ../glib/gkeyfile.c:2688 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" +"'%2$s' கà¯à®´à¯à®µà®¿à®²à¯ உளà¯à®³ விசை '%1$s' இல௠மதிபà¯à®ªà¯ '%3$s'உளà¯à®³à®¤à¯, ஆனால௠அஙà¯à®•௠இரà¯à®•à¯à®• " +"எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ %4$s." + +#: ../glib/gkeyfile.c:3087 ../glib/gkeyfile.c:3279 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "'%s' கà¯à®´à¯à®µà®¿à®²à¯ '%s' விசையை விசை கோபà¯à®ªà¯ கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®•விலà¯à®²à¯ˆ" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "கடைசி வரியில௠விசை கோபà¯à®ªà¯ விடà¯à®ªà®Ÿà¯ எழà¯à®¤à¯à®¤à®¿à®©à¯ˆ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "விசை கோபà¯à®ªà¯ தவறான விடà¯à®ªà®Ÿà¯ வரிசையை கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯ '%s'" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "மதிபà¯à®ªà¯ '%s' ஒர௠எணà¯à®£à®¾à®• செயலà¯à®ªà®Ÿ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯." + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "இயல௠எண௠மதிபà¯à®ªà¯ '%s' வரையறையை தாணà¯à®Ÿà®¿à®¯à¯à®³à¯à®³à®¤à¯" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "மதிபà¯à®ªà¯ '%s' தசம எணà¯à®£à®¾à®• செயலà¯à®ªà®Ÿ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯." + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "மதிபà¯à®ªà¯ '%s' பூலியனாக செயலà¯à®ªà®Ÿ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "'%s%s%s%s' கோபà¯à®ªà®¿à®©à¯ பணà¯à®ªà¯à®°à¯à®•à¯à®•ளைப௠பெறமà¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: fstat() தோலà¯à®µà®¿: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s ஠மேப௠செயà¯à®µà®¤à®¿à®²à¯ தோலà¯à®µà®¿: mmap() தோலà¯à®µà®¿: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "'%s' கோபà¯à®ªà®¿à®©à¯ˆ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: open() செயலிழநà¯à®¤à®¤à¯: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "வரி %d எழà¯à®¤à¯à®¤à¯ %d ல௠பிழை: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "பிழையான UTF-8 கà¯à®±à®¿à®¯à¯€à®Ÿà¯ செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿ உரை - செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à¯à®®à¯ '%s' அலà¯à®²" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' ஒர௠செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®© பெயர௠அலà¯à®²" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' ஒர௠செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®© பெயர௠அலà¯à®²: '%c' " + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d வரியில௠பிழை: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"'%-.*s'஠கூறிட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ,அதன௠ஒர௠எழà¯à®¤à¯à®¤à¯à®•à¯à®•à¯à®³à¯ ஒர௠தசமதà¯à®¤à¯ˆ கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®• " +"வேணà¯à®Ÿà¯à®®à¯ " +"கà¯à®±à®¿à®ªà¯à®ªà¯ (ê எடà¯à®¤à¯à®¤à¯à®•à¯à®•ாடà¯à®Ÿà®¾à®•) - எனினà¯à®®à¯ தசமம௠மிக பெரியதாக உளà¯à®³à®¤à¯" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" +"எழà¯à®¤à¯à®¤à¯ கà¯à®±à®¿à®ªà¯à®ªà¯ '%-.*s' ஒர௠அனà¯à®®à®¤à®¿à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ எழà¯à®¤à¯à®¤à®¿à®©à¯ˆ கà¯à®±à®¿à®®à¯à®±à¯ˆà®¯à®¾à®•à¯à®•விலà¯à®²à¯ˆ" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"வெறà¯à®±à®¾ பிரதிநிதி '&;' கணà¯à®Ÿà®¤à¯; சரியான பிரதிநிதிகளà¯: & " < &qt; " +"'" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "பிரதிநிதியின௠பெயர௠'%-.*s' தெரியாததà¯" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"பிரதிநிதி ';' உடன௠மà¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¯à®µà®¿à®²à¯à®²à¯ˆ; நீஙà¯à®•ள௠பிரதிநிதி ஒனà¯à®±à¯ˆ தொடஙà¯à®• யோசிகà¯à®•ாமல௠" +"'&' " +"பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ இரà¯à®•à¯à®•லாம௠- '&'சை & ஆக விடà¯à®µà®¿;" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "ஆவணம௠ஓர௠உறà¯à®ªà¯à®ªà¯à®Ÿà®©à¯ (உதாரணமà¯: ) தொடஙà¯à®• வேணà¯à®Ÿà¯à®®à¯" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'<' வரியà¯à®°à¯à®µà¯ˆ தொடரà¯à®¨à¯à®¤à¯ '%s' வர à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯; அதைப௠பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ ஓர௠உறà¯à®ªà¯à®ªà®Ÿà®¿à®¯à®¿à®©à¯ " +"பெயரைத௠" +"தொடஙà¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"à®’à®±à¯à®±à¯ˆ வரியà¯à®°à¯ '%s', '%s' உறà¯à®ªà¯à®ªà®Ÿà®¿ தொடஙà¯à®•ல௠ஒடà¯à®Ÿà¯ˆ ஓர௠'>' வரியà¯à®°à¯ à®®à¯à®Ÿà®¿à®µà¯ " +"செயà¯à®¯à¯à®®à¯ " +"எனà¯à®±à¯ எதிரà¯à®ªà®¾à®°à¯à®¤à¯à®¤à®¤à¯" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"'%s' ஓர௠ஒறà¯à®±à¯ˆ வரியà¯à®°à¯, பணà¯à®ªà®¿à®©à¯ பெயர௠'%s' பின௠('%s' உறà¯à®ªà¯à®ªà®¿à®©à¯) " +"எதிரà¯à®ªà®¾à®°à¯à®¤à¯à®¤à®¤à¯ ஓர௠'=' " +"வரியà¯à®°à¯" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' is not a valid character following the close element name '%s'; the " +"allowed character is '>'" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "'%s' உறà¯à®ªà¯à®ªà¯ மூடபà¯à®ªà®Ÿà¯à®Ÿà¯à®²à¯à®²à®¤à¯, தறà¯à®ªà¯Šà®¤à¯ ஒர௠உறà¯à®ªà¯à®ªà¯à®®à¯ திறநà¯à®¤à¯ இலà¯à®²à¯ˆ" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"'%s' உறà¯à®ªà¯à®ªà¯ மூடபà¯à®ªà®Ÿà¯à®Ÿà¯à®²à¯à®²à®¤à¯, அனால௠தறà¯à®ªà¯Šà®¤à¯ திறநà¯à®¤à®¿à®±à¯à®•à¯à®•à¯à®®à¯ உறà¯à®ªà¯à®ªà¯ '%s'" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "வெறà¯à®±à®¾à®© ஆவணம௠அலà¯à®²à®¤à¯ ஆவணதà¯à®¤à®¿à®²à¯ இறà¯à®ªà¯à®ªà®¤à¯ அனைதà¯à®¤à¯à®®à¯ வெணà¯à®µà¯†à®³à®¿" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "'<' பிறக௠ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"உறà¯à®ªà¯à®ªà¯à®•ள௠திறநà¯à®¤à®¿à®±à¯à®•à¯à®•à¯à®®à¯à®ªà¯‹à®¤à¯ ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯ - கடைசியாகத௠" +"திறகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿ " +"உறà¯à®ªà¯à®ªà¯ '%s'" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯, அடையாள ஒடà¯à®Ÿà¯ <%s/> à®®à¯à®Ÿà®¿à®µà®¿à®²à¯ ஓர௠'}' இரà¯à®•à¯à®•à¯à®®à¯ என " +"எதிரà¯à®ªà®¾à®°à¯à®¤à¯à®¤à®¤à¯" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "உறà¯à®ªà¯à®ªà¯ பெயர௠உளà¯à®³à¯‡ ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "பணà¯à®ªà¯ பெயர௠உளà¯à®³à¯‡ ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "உறà¯à®ªà¯à®ªà¯-தொடஙà¯à®•ளின௠அடையாள ஒடà¯à®Ÿà¯ உளà¯à®³à¯‡ ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "பணà¯à®ªà¯ பெயர௠உளà¯à®³à®¿à®±à¯à®•à¯à®•à¯à®®à¯ போத௠ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "'%s' எனà¯à®©à¯à®®à¯ மூடà¯-அடையாள ஒடà¯à®Ÿà¯ உளà¯à®³à¯‡ ஆவணம௠திடீரென à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "ஆவணம௠திடீரென கà¯à®±à®¿à®ªà¯à®ªà¯à®°à¯ˆà®¯à¯à®²à¯ அலà¯à®²à®¤à¯ செயலாகà¯à®•ம௠ஆணையà¯à®²à¯ à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯" + +#: ../glib/goption.c:795 +msgid "Usage:" +msgstr "ஓபயனà¯à®ªà®¾à®Ÿà¯:" + +#: ../glib/goption.c:795 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:911 +msgid "Help Options:" +msgstr "உதவி விரà¯à®ªà¯à®ªà®™à¯à®•ளà¯:" + +#: ../glib/goption.c:912 +msgid "Show help options" +msgstr "உதவி விரà¯à®ªà¯à®ªà®™à¯à®•ளை காடà¯à®Ÿà¯" + +#: ../glib/goption.c:918 +msgid "Show all help options" +msgstr "அனைதà¯à®¤à¯ உதவி விரà¯à®ªà¯à®ªà®™à¯à®•ளை காடà¯à®Ÿà¯" + +#: ../glib/goption.c:980 +msgid "Application Options:" +msgstr "பயனà¯à®ªà®¾à®Ÿà¯ விரà¯à®ªà¯à®ªà®™à¯à®•ளà¯:" + +#: ../glib/goption.c:1044 ../glib/goption.c:1114 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "'%s' கà¯à®•௠%sன௠இயல௠எண௠மதிபà¯à®ªà®¿à®©à¯ˆ கூறிட à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../glib/goption.c:1054 ../glib/goption.c:1122 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "'%s' கà¯à®•௠%sன௠இயல௠எண௠மதிபà¯à®ªà¯ வரையறையை தாணà¯à®Ÿà®¿à®¯à¯à®³à¯à®³à®¤à¯" + +#: ../glib/goption.c:1079 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "இரடà¯à®Ÿà¯ˆ மதிபà¯à®ªà¯ '%s' à® %sகà¯à®•௠கூறிட à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯" + +#: ../glib/goption.c:1087 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "இரடà¯à®Ÿà¯ˆ மதிபà¯à®ªà¯ '%s' %sகà¯à®•௠வரையறையை தாணà¯à®Ÿà®¿à®¯à¯à®³à¯à®³à®¤à¯" + +#: ../glib/goption.c:1373 ../glib/goption.c:1452 +#, c-format +msgid "Error parsing option %s" +msgstr "கூறிடà¯à®®à¯ போத௠பிழை: %s" + +#: ../glib/goption.c:1483 ../glib/goption.c:1596 +#, c-format +msgid "Missing argument for %s" +msgstr " %sகà¯à®•ான விடà¯à®ªà®Ÿà¯à®Ÿ மதிபà¯à®ªà¯à®°à¯" + +#: ../glib/goption.c:2057 +#, c-format +msgid "Unknown option %s" +msgstr "தெரியாத விரà¯à®ªà¯à®ªà®®à¯ %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "சிதைநà¯à®¤ பொரà¯à®³à¯" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "உளà¯à®³à®®à¯ˆ தவற௠அலà¯à®²à®¤à¯ சிதைநà¯à®¤ பொரà¯à®³à¯" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "நினைவகம௠நிரமà¯à®ªà®¿à®¯à®¤à¯" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "பினà¯à®¨à¯‹à®•à¯à®•ி ஆராயà¯à®®à¯ எலà¯à®²à¯ˆ அடையபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"தோரணி உளà¯à®³à®Ÿà®•à¯à®•à®™à¯à®•ள௠பகà¯à®¤à®¿ பொரà¯à®¤à¯à®¤à®¤à¯à®¤à¯à®•à¯à®•௠ஆதரவ௠தராத உரà¯à®ªà¯à®ªà®Ÿà®¿à®•ளாக உளà¯à®³à®©" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"பினà¯à®¨à¯‹à®•à¯à®•à¯à®®à¯ சமரà¯à®ªà®£à®™à¯à®•ள௠பகà¯à®¤à®¿ பொரà¯à®¤à¯à®¤à®¤à¯à®¤à¯à®•à¯à®•௠ஆதரவ௠தராத உரà¯à®ªà¯à®ªà®Ÿà®¿à®•ளாக உளà¯à®³à®©" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "உடà¯à®šà¯à®´à®²à¯ எலà¯à®²à¯ˆ அடையபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯." + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "செலà¯à®²à®¾à®¤ பà¯à®¤à¯ வரி கà¯à®±à®¿à®•ளின௠கூடà¯à®Ÿà¯" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "தவறான ஆஃபà¯à®šà¯†à®Ÿà¯" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "கà¯à®±à¯à®•ிய utf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "உடà¯à®šà¯à®´à®²à¯ சà¯à®´à®±à¯à®šà®¿" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "தெரியாத தவறà¯" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ at end of pattern" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c at end of pattern" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "\\ கà¯à®•௠அடà¯à®¤à¯à®¤à¯ அடையாளம௠காணபà¯à®ªà®Ÿà®¾à®¤ எழà¯à®¤à¯à®¤à¯à®•à¯à®•à¯à®±à®¿" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} தகà¯à®¤à®¿à®¯à®¾à®³à®°à®¿à®²à¯ செயலிழகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®µà¯ˆà®¯à®¿à®©à¯ எணà¯à®£à®¿à®•à¯à®•ைகளà¯" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "நிறையிலà¯{} எணà¯à®•ள௠மிக பெரிதாக உளà¯à®³à®©" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "எண௠வகà¯à®ªà¯à®ªà¯à®•à¯à®•ாக ] விடிபடà¯à®Ÿà®µà¯ˆà®•ளை à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¯à®šà¯ செயà¯à®¤à®²à¯" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "எண௠வகà¯à®ªà¯à®ªà®¿à®²à¯ தவறான வரிசைமà¯à®±à¯ˆà®¯à¯ˆ தவிரà¯à®¤à¯à®¤à®²à¯" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "எழà¯à®¤à¯à®¤à¯ வகà¯à®ªà¯à®ªà®¿à®²à¯ வரமà¯à®ªà¯ செயலிழகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "மீணà¯à®Ÿà¯à®®à¯ செயà¯à®µà®¤à®±à¯à®•௠எதà¯à®µà¯à®®à®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "எதிரà¯à®ªà®¾à®°à®¾à®¤ திரà¯à®®à¯à®ªà¯à®¤à®²à¯" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? அலà¯à®²à®¤à¯ (?- கà¯à®•à¯à®ªà¯ பிறக௠அடையாளம௠காணபà¯à®ªà®Ÿà®¾à®¤ எழà¯à®¤à¯à®¤à¯à®•à¯à®•à¯à®±à®¿" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "" +"POSIX என பெயரிடபà¯à®ªà®Ÿà¯à®Ÿ வகà¯à®ªà¯à®ªà¯à®•ள௠வகà¯à®ªà¯à®ªà®¿à®±à¯à®•à¯à®³à¯ மடà¯à®Ÿà¯à®®à¯ தான௠தà¯à®£à¯ˆà®ªà¯à®°à®¿à®¯à¯à®®à¯ " + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "விடà¯à®ªà¯à®ªà®Ÿà¯à®Ÿ à®®à¯à®Ÿà®¿à®¤à¯à®¤à®²à¯ )" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "இலà¯à®²à®¾à®¤ தà¯à®£à¯ˆ தோறà¯à®±à®¤à¯à®¤à®¿à®±à¯à®•ான கà¯à®±à®¿à®ªà¯à®ªà¯" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "கடà¯à®Ÿà®³à¯ˆà®•à¯à®•௠பிறக௠) தவறியதà¯" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "சà¯à®°à¯à®™à¯à®•à¯à®±à®¿à®¤à¯ தொடர௠மிகப௠பெரியதà¯" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "நினைவிறà¯à®•௠கொணà¯à®Ÿà¯ வரà¯à®µà®¤à®¿à®²à¯ தோலà¯à®µà®¿" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") திறகà¯à®•ாமல௠(" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "அதிக கà¯à®±à®¿à®¯à¯€à®Ÿà¯" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "அடையாளம௠காணமà¯à®Ÿà®¿à®¯à®¾à®¤ எணà¯à®£à®¿à®±à¯à®•௠பிறக௠(?<" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind வலியà¯à®±à¯à®¤à¯à®¤à¯à®¤à®²à¯ நிலையான நீளதà¯à®¤à®¿à®²à¯ இலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "தவறான எண௠அலà¯à®²à®¤à¯ பெயரà¯à®•à¯à®•௠பிறக௠(?(" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "நிபநà¯à®¤à®©à¯ˆà®•à¯à®•à¯à®Ÿà¯à®ªà®Ÿà¯à®Ÿ கà¯à®´à¯ இரணà¯à®Ÿà¯à®•à¯à®•à¯à®®à¯ மேறà¯à®ªà®Ÿà¯à®Ÿ கிளைகளை பெறà¯à®±à¯à®³à¯à®³à®¤à¯" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "பின௠வலியà¯à®±à¯à®¤à¯à®¤à¯à®¤à®²à¯ எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®•ிறத௠(?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R அலà¯à®²à®¤à¯ (?[+-]இவறà¯à®±à®¾à®²à¯ எணà¯à®•ள௠பினà¯à®¤à¯Šà®Ÿà®°à®ªà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯ )" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "தெரியாத POSIX வகà¯à®ªà¯à®ªà¯ பெயரà¯" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "POSIX collating elements are not supported" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "எணà¯à®£à®¿à®©à¯ மதிபà¯à®ªà¯ \\x{...} இடைவிடா வரிசையில௠மிகபà¯à®ªà¯†à®°à®¿à®¤à®¾à®• உளà¯à®³à®¤à¯" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "தவறான நிபநà¯à®¤à®©à¯ˆ (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C à® lookbehind ல௠வலியà¯à®±à¯à®¤à¯à®¤ அனà¯à®®à®¤à®¿à®¯à®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "\\L, \\l, \\N{name}, \\U, \\u ஆகிய எஸà¯à®•ேப௠கà¯à®±à®¿à®•ளà¯à®•à¯à®•௠ஆதரவிலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "கடà¯à®Ÿà®¾à®¯à®®à®¿à®²à¯à®²à®¾à®®à®²à¯ மறà¯à®šà¯à®´à®±à¯à®šà®¿ அழைபà¯à®ªà¯ சà¯à®±à¯à®±à®¾à®¤à¯" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "அடையாளம௠காணமà¯à®Ÿà®¿à®¯à®¾à®¤ எணà¯à®£à®¿à®±à¯à®•௠பிறக௠(?P" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "subpattern பெயரில௠மà¯à®Ÿà®¿à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ விடà¯à®ªà®Ÿà¯à®Ÿà®µà¯ˆà®•ளà¯" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "இரணà¯à®Ÿà¯ பெயரிடபà¯à®ªà®Ÿà¯à®Ÿ subpatterns களà¯à®®à¯ ஒரே பெயரை பெறà¯à®±à¯à®³à¯à®³à®¤à¯" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "தவறானத௠\\P அலà¯à®²à®¤à¯ \\p இடைவிடா வரிசையானதà¯" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "பின௠தெரியாத இயலà¯à®ªà®¿à®©à¯ பெயர௠\\P அலà¯à®²à®¤à¯ \\p" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "subpattern ன௠பெயர௠மிக நீளமானத௠(அதிகபடà¯à®šà®®à¯ 32 எணà¯à®•ளà¯)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "subpatterns கà¯à®•௠நிறைய பெயரà¯à®•ள௠உளà¯à®³à®¤à¯ (அதிகபடà¯à®šà®®à¯ 10,000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "எணà¯à®® மதிபà¯à®ªà¯ \\377஠விட அதிகமà¯" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "overran கைமà¯à®ªà¯ˆà®²à¯ பணியிடமà¯" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "à®®à¯à®©à¯à®ªà¯ சோதிகà¯à®•பà¯à®ªà®Ÿà¯à®Ÿ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿ தà¯à®£à¯ˆ தோறà¯à®±à®®à¯ இலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE கà¯à®´à¯ ஒனà¯à®±à¯à®•à¯à®•௠மேறà¯à®ªà®Ÿà¯à®Ÿ கிளைகளை கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "தொடரà¯à®šà®¿à®¯à®±à¯à®± NEWLINE விரà¯à®ªà¯à®ªà®™à¯à®•ளà¯" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ஠அடà¯à®¤à¯à®¤à¯ அடைபà¯à®ªà¯à®•à¯à®•à¯à®±à®¿à®•à¯à®•à¯à®³à¯ இடபà¯à®ªà®Ÿà¯à®Ÿ அலà¯à®²à®¤à¯ à®®à¯à®•à¯à®•ோண அடைபà¯à®ªà¯à®•௠" +"கà¯à®±à®¿à®•à¯à®•à¯à®³à¯ இடபà¯à®ªà®Ÿà¯à®Ÿ " +"அலà¯à®²à®¤à¯ மேறà¯à®•ோள௠கà¯à®±à®¿à®•à¯à®•à¯à®³à¯ இடபà¯à®ªà®Ÿà¯à®Ÿ பெயரோ எணà¯à®£à¯‹ அலà¯à®²à®¤à¯ எளிய எணà¯à®£à¯‹ இலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "எணà¯à®£à¯à®³à¯à®³ கà¯à®±à®¿à®ªà¯à®ªà¯ பூசà¯à®šà®¿à®¯à®®à®¾à®• இரà¯à®•à¯à®•கà¯à®•ூடாதà¯" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" +"(*ACCEPT), (*FAIL) அலà¯à®²à®¤à¯ (*COMMIT) கà¯à®•௠அளவà¯à®°à¯à®µà¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤ அனà¯à®®à®¤à®¿à®¯à®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) அடையாளம௠காணபà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "எண௠மிகப௠பெரியதà¯" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& கà¯à®•௠பிறக௠subpattern பெயர௠இலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ கà¯à®•à¯à®ªà¯ பிறக௠எண௠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "JavaScript இணகà¯à®•ப௠பயனà¯à®®à¯à®±à¯ˆà®¯à®¿à®²à¯ ] ஒர௠தவறான தரவ௠எழà¯à®¤à¯à®¤à¯à®•à¯à®•à¯à®±à®¿" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" +"ஒரே எணà¯à®£à®¿à®©à¯ subpatternகளà¯à®•à¯à®•ான இரணà¯à®Ÿà¯ வெவà¯à®µà¯‡à®±à¯ பெயரà¯à®•ளà¯à®•à¯à®•௠அனà¯à®®à®¤à®¿ இலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) கà¯à®•௠ஒர௠பணà¯à®ªà¯à®°à¯ இரà¯à®¨à¯à®¤à®¾à®• வேணà¯à®Ÿà¯à®®à¯" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c கà¯à®•௠அடà¯à®¤à¯à®¤à¯ ஒர௠ASCII எழà¯à®¤à¯à®¤à¯à®•à¯à®•à¯à®±à®¿ இடமà¯à®ªà¯†à®± வேணà¯à®Ÿà¯à®®à¯" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k வை அடà¯à®¤à¯à®¤à¯ அடைபà¯à®ªà¯à®•à¯à®•à¯à®±à®¿à®•à¯à®•à¯à®³à¯ அமைநà¯à®¤, à®…à®®à¯à®ªà¯ அடைபà¯à®ªà¯à®•à¯à®•à¯à®±à®¿à®•à¯à®•à¯à®³à¯ அமைநà¯à®¤ " +"அலà¯à®²à®¤à¯ மேறà¯à®•ோள௠" +"கà¯à®±à®¿à®•à¯à®•à¯à®³à¯ அமைநà¯à®¤ பெயர௠இலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "கிளாஸà¯à®•à¯à®•à¯à®³à¯ \\N கà¯à®•௠ஆதரவிலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "à®®à¯à®©à¯à®©à®©à¯à®ªà¯à®ªà®²à¯ கà¯à®±à®¿à®ªà¯à®ªà¯à®•ள௠அதிகமாக உளà¯à®³à®©" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP) அலà¯à®²à®¤à¯ (*THEN) இல௠பெயர௠மிக நீளமாக உளà¯à®³à®¤à¯" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... தொடரில௠உளà¯à®³ எழà¯à®¤à¯à®¤à¯à®•à¯à®•à¯à®±à®¿ மதிபà¯à®ªà¯ மிக நீளமாக உளà¯à®³à®¤à¯" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "வழகà¯à®•மான கூறà¯à®±à¯ˆ பொரà¯à®¤à¯à®¤à¯à®µà®¤à®¿à®²à¯ பிழை%s: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "பிசிஆரà¯à®ˆ நூலகம௠யூடிஎஃபà¯8 ஆதரவ௠இலà¯à®²à®¾à®®à®²à¯ தொகà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯." + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "பிசிஆரà¯à®ˆ நூலகம௠யூடிஎஃபà¯8 பணà¯à®ªà¯à®•ள௠ஆதரவ௠இலà¯à®²à®¾à®®à®²à¯ தொகà¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯." + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "" +"PCRE லைபà¯à®°à®°à®¿à®¯à®¾à®©à®¤à¯ இணகà¯à®•மறà¯à®± விரà¯à®ªà¯à®ªà®™à¯à®•ளைக௠கொணà¯à®Ÿà¯ கமà¯à®ªà¯ˆà®²à¯ செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "இயலà¯à®ªà®¾à®© கூறà¯à®±à¯ %s ஠தொகà¯à®•à¯à®•à¯à®®à¯à®ªà¯‹à®¤à¯ %d வரியà¯à®°à¯à®µà®¿à®²à¯ பிழை: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "இயலà¯à®ªà®¾à®© கூறà¯à®±à¯ ஠உகநà¯à®¤à®¤à®¾à®•à¯à®•à¯à®®à¯à®ªà¯‹à®¤à¯ பிழை:%s: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "பதினà¯à®©à®±à¯à®® எண௠அலà¯à®²à®¤à¯ '}' எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯." + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "பதினà¯à®©à®±à¯à®® எண௠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯." + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "கà¯à®±à®¿à®¯à¯€à®Ÿà¯à®Ÿà¯à®°à¯à®µà®¾à®© சமரà¯à®ªà®£à®¤à¯à®¤à®¿à®²à¯ '<' ஠காணவிலà¯à®²à¯ˆ" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¯à®¾à®¤ உளà¯à®³à¯€à®Ÿà¯à®ªà¯ மேறà¯à®•ோளà¯" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "பூஜà¯à®¯ நீள உளà¯à®³à¯€à®Ÿà¯à®ªà¯ மேறà¯à®•ோளà¯" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "எண௠எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "சடà¯à®Ÿà®µà®¿à®°à¯‹à®¤ உளà¯à®³à¯€à®Ÿà¯à®ªà¯ மேறà¯à®•ோளà¯" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "அனாதையான கடைசி '\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "தெரியாத வெளியேறà¯à®± வரிசைமà¯à®±à¯ˆ" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "மாறà¯à®±à¯ உரை \"%s\" ஠பகà¯à®•à¯à®•ையில௠பிழை வரியà¯à®°à¯ %lu இலà¯: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "மேறà¯à®•ளிதà¯à®¤ உரை ஓர௠\" -உடன௠தொடஙà¯à®•விலà¯à®²à¯ˆ" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "'கடà¯à®Ÿà®³à¯ˆ வடியில௠அலà¯à®²à®¤à¯ வேற௠மேறà¯à®•ளிதà¯à®¤ உரையில௠பொரà¯à®¤à¯à®¤à®®à®±à¯à®± \" " + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "'\\' வரியà¯à®°à¯à®•à¯à®•௠பினà¯à®ªà¯ உரை à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯. (கடைசி உரை: '%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"%c கà¯à®•௠பொரà¯à®¤à¯à®¤à®®à®¾à®© மேறà¯à®•ோள௠கணà¯à®Ÿà¯à®ªà®¿à®Ÿà®¿à®ªà¯à®ªà®¤à®Ÿà¯à®•௠மà¯à®©à¯ உரை à®®à¯à®Ÿà®¿à®µà®Ÿà¯ˆà®¨à¯à®¤à®¤à¯. (உரை: '%" +"s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "உரை வெறà¯à®±à®¾ இரà¯à®¨à¯à®¤à®¤à¯ (அலà¯à®²à®¤à¯ வெணà¯à®µà¯†à®³à®¿ மடà¯à®Ÿà¯à®®à¯‡)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "(%s) சேயà¯-செயலில௠இரà¯à®¨à¯à®¤à¯ தரவ௠வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"(%s) சேயà¯-செயலில௠இரà¯à®¨à¯à®¤à¯ தரவ௠வாசிகà¯à®•à¯à®®à¯ போதà¯, select()'டில௠எதிரà¯à®ªà®¾à®°à®¾à®¤ பிழை" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "(%s) waitpid()'டில௠எதிரà¯à®ªà®¾à®°à®¾à®¤ பிழை" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "சேய௠உறà¯à®ªà¯à®ªà¯ செயலாகà¯à®•ம௠%ld கà¯à®±à®¿à®¯à¯€à®Ÿà¯à®Ÿà¯à®Ÿà®©à¯ வெளியேறியதà¯" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "சேய௠உறà¯à®ªà¯à®ªà¯ செயலாகà¯à®•ம௠%ld சிகà¯à®©à®²à®¿à®©à®¾à®²à¯ à®®à¯à®Ÿà®¿à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "சேய௠உறà¯à®ªà¯à®ªà¯ செயலாகà¯à®•ம௠%ld சிகà¯à®©à®²à®¿à®©à®¾à®²à¯ நிறà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "சேய௠உறà¯à®ªà¯à®ªà¯ செயலாகà¯à®•ம௠இயலà¯à®ªà®±à¯à®± à®®à¯à®±à¯ˆà®¯à®¿à®²à¯ வெளியேறியதà¯" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "(%s) சேய௠கழாயà¯à®¤à¯ தொடரில௠இரà¯à®¨à¯à®¤à¯ வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) தொடஙà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "'%s' (%s) அடைவà¯à®•à¯à®•௠போக à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "\"%s\" (%s) சேயà¯-செயலை இயகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "சேய௠(%s) செயலகதà¯à®¤à®¿à®©à¯ வெளியீடலை அலà¯à®²à®¤à¯ உளà¯à®³à®Ÿà®²à¯ˆ திசை-மாறà¯à®±à¯à®®à¯à®ªà¯‹à®¤à¯ பிழை" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "சேய௠(%s) செயலகதà¯à®¤à¯ˆ தொடஙà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "சேய௠செயல௠\"%s\" இயகà¯à®•à¯à®®à¯à®ªà¯‹à®¤à¯ தெரியாத பிழை" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Failed to read enough data from child pid pipe (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "சேய௠செயலில௠இரà¯à®¨à¯à®¤à¯ தரவ௠வாசிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "(%s) சேயà¯-செயலிடன௠தொடரà¯à®ªà¯ கொலà¯à®² கழாயà¯à®¤à¯-தொடரைப௠படைகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "(%s) சேயà¯-செயலை இயகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "தவறான நிரல௠பெயரà¯: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%dல௠மதிபà¯à®ªà®°à¯ வெகà¯à®Ÿà®¾à®°à®¿à®²à¯ தவறான சரமà¯: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "சூழலில௠தவறான சரமà¯: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "தவறான பணி செயà¯à®¯à¯à®®à¯ அடைவà¯: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "உதவியாளர௠நிலையை இயகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" + +#: ../glib/gutf8.c:780 +msgid "Failed to allocate memory" +msgstr "நினைவகதà¯à®¤à¯ˆ ஒதà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 கà¯à®•௠வரியà¯à®°à¯ வீசà¯à®šà¯ எலà¯à®²à¯ˆà®•à¯à®•௠வெளியே" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "உரையாடல௠உளà¯à®³à¯€à®Ÿà¯à®Ÿà®¿à®²à¯ தவறான வரிசை" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 கà¯à®•௠வரியà¯à®°à¯ வீசà¯à®šà¯ எலà¯à®²à¯ˆà®•à¯à®•௠வெளியே" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u பைடà¯" +msgstr[1] "%u பைடà¯à®•ளà¯" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s பைடà¯" +msgstr[1] "%s பைடà¯à®•ளà¯" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "ஜனவரி" + +msgctxt "full month name with day" +msgid "February" +msgstr "பிபà¯à®°à®µà®°à®¿" + +msgctxt "full month name with day" +msgid "March" +msgstr "மாரà¯à®šà¯" + +msgctxt "full month name with day" +msgid "April" +msgstr "à®à®ªà¯à®°à®²à¯" + +msgctxt "full month name with day" +msgid "May" +msgstr "மே" + +msgctxt "full month name with day" +msgid "June" +msgstr "ஜூனà¯" + +msgctxt "full month name with day" +msgid "July" +msgstr "ஜூலை" + +msgctxt "full month name with day" +msgid "August" +msgstr "ஆகஸà¯à®Ÿà¯" + +msgctxt "full month name with day" +msgid "September" +msgstr "செபà¯à®Ÿà®®à¯à®ªà®°à¯" + +msgctxt "full month name with day" +msgid "October" +msgstr "அகà¯à®Ÿà¯‹à®ªà®°à¯" + +msgctxt "full month name with day" +msgid "November" +msgstr "நவமà¯à®ªà®°à¯" + +msgctxt "full month name with day" +msgid "December" +msgstr "டிசமà¯à®ªà®°à¯" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ஜன" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "பிபà¯" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "மாரà¯" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "à®à®ªà¯" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "மே" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "ஜூனà¯" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "ஜூலை" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ஆகஸà¯" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "செபà¯" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "அகà¯" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "நவà¯" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "டிசமà¯" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "xmllint கொணà¯à®Ÿà¯ உளà¯à®³à¯€à®Ÿà¯à®Ÿà¯à®•௠கோபà¯à®ªà¯ˆà®šà¯ செயலாகà¯à®•à¯à®µà®¤à®¿à®²à¯ பிழை:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata வைக௠கொணà¯à®Ÿà¯ உளà¯à®³à¯€à®Ÿà¯à®Ÿà¯à®•௠கோபà¯à®ªà¯ˆà®šà¯ செயலாகà¯à®•à¯à®µà®¤à®¿à®²à¯ பிழை:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "விடà¯à®ªà¯à®ªà®Ÿà¯à®Ÿ பிழையைப௠பெற à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "'%s' கோபà¯à®ªà®¿à®©à¯ˆ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: fdopen() செயலிழநà¯à®¤à®¤à¯: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "கோபà¯à®ªà¯ '%s' எழà¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: fflush() செயலிழநà¯à®¤à®¤à¯: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "'%s'கோபà¯à®ªà®¿à®©à¯ˆ மூட à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ: fclose() செயலிழநà¯à®¤à®¤à¯: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "'%s' கà¯à®•௠மà¯à®´à¯à®®à¯ˆà®¯à®¿à®²à¯à®²à®¾à®¤ தரவ௠பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "SO_PASSCRED ஆனத௠சாகà¯à®•ெடà¯à®Ÿà®¿à®±à¯à®•ாக செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯ எதிரà¯à®ªà®¾à®°à®¾à®¤ விரà¯à®ªà¯à®ª நீளம௠" +#~ "சரிபாரà¯à®•à¯à®•à¯à®®à¯ போத௠இரà¯à®•à¯à®•à¯à®®à¯. எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•பà¯à®ªà®Ÿà¯à®Ÿ %d பைடà¯à®Ÿà¯à®•ளà¯, %d பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "காலியான தà¯à®£à¯ˆ சரஙà¯à®•ளà¯à®•à¯à®•௠பணியிட எலà¯à®²à¯ˆ அடையபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯." + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "case-changing escapes (\\l, \\L, \\u, \\U) இஙà¯à®•௠அனà¯à®®à®¤à®¿ இலà¯à®²à¯ˆ" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE கà¯à®´à¯à®µà¯ˆ மீணà¯à®Ÿà¯à®®à¯ அமைகà¯à®• அனà¯à®®à®¤à®¿ இலà¯à®²à¯ˆ" + +#~ msgid "File is empty" +#~ msgstr "கோபà¯à®ªà¯ வெறà¯à®±à®¾à®• உளà¯à®³à®¤à¯" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "%s'விசையை விசை கோபà¯à®ªà¯ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯ அத௠கொணà¯à®Ÿà¯à®³à¯à®³ மதிபà¯à®ªà®¿à®©à¯ˆ மாறà¯à®± à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯." + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "அசாதாரண நிரல௠மà¯à®Ÿà®¿à®µà¯ கடà¯à®Ÿà®³à¯ˆ வரி '%s'஠ஸà¯à®ªà¯‡à®©à®¿à®™à¯ செயà¯à®•ிறதà¯: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "" +#~ "கடà¯à®Ÿà®³à¯ˆ வரி '%s' ஆனத௠பூஜà¯à®œà®¿à®¯à®®à®¿à®²à¯à®²à®¾à®¤ வெளியேற௠நிலை %d உடன௠வெளியேறியதà¯: %s" + +#~ msgid "This option will be removed soon." +#~ msgstr "இநà¯à®¤ விரà¯à®ªà¯à®ªà®®à®¾à®©à®¤à¯ விரைவில௠நீகà¯à®•பà¯à®ªà®Ÿà¯à®®à¯." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "'%s' கோபà¯à®ªà¯ˆ தà¯à®µà®•à¯à®•à¯à®µà®¤à®¿à®²à¯ பிழை : %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s'கà¯à®•௠சேவை பதிவ௠இலà¯à®²à¯ˆ" + +#~ msgid "Error connecting: " +#~ msgstr "இணைகà¯à®•à¯à®®à¯ போத௠பிழை:" + +#~ msgid "Error connecting: %s" +#~ msgstr "இணைகà¯à®•à¯à®®à¯ போத௠பிழை: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "SOCKSv4 செயலà¯à®ªà®¾à®Ÿà®¾à®©à®¤à¯ பயனரà¯à®ªà¯†à®¯à®°à®¿à®©à¯ %i எழà¯à®¤à¯à®¤à¯à®•à¯à®•ளà¯à®•à¯à®•௠வரமà¯à®ªà®¾à®•ிறதà¯" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKSv4a செயலà¯à®ªà®¾à®Ÿà®¾à®©à®¤à¯ பà¯à®°à®µà®²à®ªà¯à®ªà¯†à®¯à®°à®¿à®©à¯ %i எழà¯à®¤à¯à®¤à¯à®•à¯à®•ளà¯à®•à¯à®•௠வரமà¯à®ªà®¾à®•ிறதà¯" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "unix லிரà¯à®¨à¯à®¤à¯ வாசிபà¯à®ªà®¤à®¿à®²à¯ பிழை: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "unix ஠மூடà¯à®µà®¤à®¿à®²à¯ பிழை: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "யà¯à®©à®¿à®•à¯à®¸à®¿à®²à¯ எழà¯à®¤à¯à®®à¯ போத௠பிழை: %s" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "அடைவில௠அடைவை நகரà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "உரையாடல௠உளà¯à®³à¯€à®Ÿà¯à®Ÿà®¿à®²à¯ தவறான வரிசை" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "அதிகபடà¯à®š தரவ௠அணி வரமà¯à®ªà¯ˆ அடைநà¯à®¤à®¤à¯" + +#~ msgid "do not hide entries" +#~ msgstr "உளà¯à®³à¯€à®Ÿà¯à®•ளை மறைகà¯à®•ாதே" + +#~ msgid "use a long listing format" +#~ msgstr "நீணà¯à®Ÿ படà¯à®Ÿà®¿à®¯à®²à®¿à®Ÿà¯à®®à¯ à®®à¯à®±à¯ˆà®¯à¯ˆ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯" diff --git a/po/te.po b/po/te.po new file mode 100644 index 0000000..045a12c --- /dev/null +++ b/po/te.po @@ -0,0 +1,4804 @@ +# translation of glib.master.te.po to Telugu +# Telugu translation of glib +# Copyright (C) 2012 Swecha telugu localisation Team +# This file is distributed under the same license as the GLIB package. +# +# +# +# వికà±à°°à°‚ ఫణీందà±à°° , 2005. +# దండౠపà±à°°à°¸à°¾à°¦à± , 2005. +# రమణ సాయి , 2005. +# Krishna Babu K , 2008, 2009, 2012, 2013, 2014. +# Sasi Bhushan Boddepalli , 2012. +# Praveen Illa (swecha team), 2012. +# GVS.Giri (swecha team),2012. +# Sasi Bhushan Boddepalli <>, 2012. +msgid "" +msgstr "" +"Project-Id-Version: glib.master.te\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-23 05:55+0000\n" +"PO-Revision-Date: 2014-09-23 19:30+0530\n" +"Last-Translator: Krishnababu Krothapalli \n" +"Language-Team: Telugu \n" +"Language: te\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: ../gio/gapplication.c:514 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"GApplication సేవా రీతి (D-బసౠసేవా దసà±à°¤à±à°°à°¾à°²à± à°¨à±à°‚à°¡à°¿ ఉపయోగించà±) à°ªà±à°°à°µà±‡à°¶à°ªà±†à°Ÿà±à°Ÿà±à°®à±" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "GApplication options" +msgstr "GApplication à°à°šà±à°šà°¿à°•ాలà±" + +#: ../gio/gapplication.c:519 +#| msgid "Application Options:" +msgid "Show GApplication options" +msgstr "GApplication à°à°šà±à°šà°¿à°•ాలౠచూపà±" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:485 ../gio/gsettings-tool.c:508 +msgid "Print help" +msgstr "సహాయం à°®à±à°¦à±à°°à°£" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:486 +#: ../gio/gresource-tool.c:554 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gapplication-tool.c:49 +#| msgid "Print address" +msgid "Print version" +msgstr "వరà±à°·à°¨à± à°®à±à°¦à±à°°à°¿à°‚à°šà±" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:514 +msgid "Print version information and exit" +msgstr "వరà±à°·à°¨à± సమాచారం à°®à±à°¦à±à°°à°¿à°‚à°šà°¿ నిషà±à°•à±à°°à°®à°¿à°‚à°šà±" + +#: ../gio/gapplication-tool.c:52 +#| msgid "Can't find application" +msgid "List applications" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨à°®à±à°¨à±à°²à± జాబితాచేయి" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "à°•à±à°°à°¿à°¯à°¾à°¸à±€à°²à°ªà°°à±à°šà°—à°² సంసà±à°¥à°¾à°ªà°¿à°¤ D-బసౠఅనà±à°µà°°à±à°¤à°¨à°¾à°² జాబిత (.desktop దసà±à°¤à±à°°à°¾à°²à°¤à±‹)" + +#: ../gio/gapplication-tool.c:55 +#| msgid "Can't find application" +msgid "Launch an application" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨à°®à±à°¨à± దించà±" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨à°‚ దించౠ(తెరà±à°šà±à°Ÿà°•à± à°à°šà±à°šà°¿à°• ఫైళà±à°³à°¤à±‹)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "à°’à°• à°šà°°à±à°¯à°¨à± à°•à±à°°à°¿à°¯à°¾à°¶à±€à°²à°ªà°°à°šà±" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨à°‚పై à°’à°• à°šà°°à±à°¯à°¨à± à°ªà±à°°à±‡à°°à±‡à°ªà°¿à°‚à°šà±" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹à°¨à°¿ à°šà°°à±à°¯à°²à± జాబితాచేయి" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "à°’à°• à°…à°¨à±à°µà°°à±à°¤à°¨à°‚ కొరకౠసà±à°Ÿà°¾à°Ÿà°¿à°•à± à°šà°°à±à°¯à°²à°¨à± జాబితాచేయి (.desktop ఫైలౠనà±à°‚à°¡à°¿)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "కమాండà±" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "దీనికొరకౠవివరణాతà±à°®à°• సహాయం à°®à±à°¦à±à°°à°¿à°‚à°šà±à°Ÿà°•à±" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨ à°à°¡à±†à°‚టిఫైరౠD-బసౠఫారà±à°®à°¾à°Ÿà±â€Œà°²à±‹ (ఉదా: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:492 +#: ../gio/gresource-tool.c:558 +msgid "FILE" +msgstr "FILE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "à°à°šà±à°šà°¿à°• సారూపà±à°¯ లేక సారూపà±à°¯ దసà±à°¤à±à°°à°ªà±à°ªà±‡à°°à±à°²à±, లేదా తెరà±à°šà±à°Ÿà°•à± URIà°²à±" + +#: ../gio/gapplication-tool.c:73 +#| msgid "SECTION" +msgid "ACTION" +msgstr "à°šà°°à±à°¯" + +#: ../gio/gapplication-tool.c:73 +#| msgid "Destination name to introspect" +msgid "The action name to invoke" +msgstr "à°ªà±à°°à±‡à°°à±‡à°ªà°¿à°‚à°šà±à°Ÿà°•à± à°šà°°à±à°¯ పేరà±" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "పారామితి" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "à°šà°°à±à°¯à°¾ à°ªà±à°°à±‡à°°à°•ానికి à°à°šà±à°šà°¿à°• పారామితి, GVariant ఫారà±à°®à°¾à°Ÿà± నందà±" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:523 +#: ../gio/gsettings-tool.c:594 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "తెలియని ఆదేశం %s\n" + +#: ../gio/gapplication-tool.c:101 +#| msgid "Usage:" +msgid "Usage:\n" +msgstr "వాడà±à°•:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:548 +#: ../gio/gsettings-tool.c:628 +msgid "Arguments:\n" +msgstr "వాదనలà±:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "ఆదేశాలà±:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"వివరణాతà±à°®à°• సహాయం పొందడానికి '%s help COMMAND' ఉపయోగించà±.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"నేరà±à°—à°¾ à°…à°¨à±à°¸à°°à°¿à°‚చడానికి %s ఆదేశానికి à°’à°• à°…à°¨à±à°µà°°à±à°¤à°¨ à°à°¡à°¿ కావాలి\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +#| msgid "invalid GVariant type string '%s'" +msgid "invalid application id: '%s'\n" +msgstr "చెలà±à°²à°¨à°¿ à°…à°¨à±à°µà°°à±à°¤à°¨ à°à°¡à°¿: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' ఆరà±à°—à±à°®à±†à°‚à°Ÿà±à°²à°¨à± తీసà±à°•ోదà±\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +#| msgid "Could not connect to %s: " +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus à°•à± à°…à°¨à±à°¸à°‚ధానం కాలేదà±: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +#| msgid "Error sending message: %s" +msgid "error sending %s message to application: %s\n" +msgstr "%s సందేశం à°…à°¨à±à°µà°°à±à°¤à°¨à°®à±à°•ౠపంపà±à°Ÿà°²à±‹ దోషం: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨ à°à°¡à°¿ తరà±à°µà°¾à°¤ à°šà°°à±à°¯ పేరౠతపà±à°ªà°• ఇవà±à°µà°¾à°²à°¿\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"చెలà±à°²à°¨à°¿ à°šà°°à±à°¯ పేరà±: '%s'\n" +"à°šà°°à±à°¯ పేరà±à°²à± తపà±à°ªà°•à±à°‚à°¡à°¾ à°…à°•à±à°·à°°à°¾à°²à±à°¸à°‚à°–à±à°¯à°²à±, '-' and '.' మాతà±à°°à°®à±‡ అయివà±à°‚డాలి\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +#| msgid "Error parsing parameter %d: %s\n" +msgid "error parsing action parameter: %s\n" +msgstr "à°šà°°à±à°¯à°¾ పారామితి పారà±à°¸à°¿à°‚గౠనందౠదోషం: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "à°šà°°à±à°¯à°²à± à°—à°°à°¿à°·à±à°Ÿà°‚à°—à°¾ à°’à°• పారామితి మాతà±à°°à°®à±‡ ఆమోదించà±à°¨à±\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "జాబితా-à°šà°°à±à°¯à°² ఆదేశం à°…à°¨à±à°µà°°à±à°¤à°¨ à°à°¡à°¿ మాతà±à°°à°®à±‡ తీసà±à°•ొనà±à°¨à±" + +#: ../gio/gapplication-tool.c:421 +#, c-format +#| msgid "Unable to find terminal required for application" +msgid "unable to find desktop file for application %s\n" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨à°‚ %s కొరకౠడెసà±à°•à±â€Œà°Ÿà°¾à°ªà± దసà±à°¤à±à°°à°®à± à°•à°¨à±à°—ొనలేదà±\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +#| msgid "" +#| "Unknown command %s\n" +#| "\n" +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"à°—à±à°°à±à°¤à°¿à°‚చని ఆదేశం: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:370 +#: ../gio/ginputstream.c:608 ../gio/ginputstream.c:828 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:823 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "చాలపెదà±à°¦ లెకà±à°•ింపౠవిలà±à°µ %sకౠపంపబడింది" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "ఆధార à°ªà±à°°à°µà°¾à°¹à°‚ కౠమదà±à°¦à°¤à± లేదౠఅరà±à°¥à°¿à°‚à°šà±" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBuffered ఇనà±à°ªà±à°Ÿà± à°ªà±à°°à°µà°¾à°¹ ఖండించౠసాధà±à°¯à°‚ కాదà±" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1017 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1464 +msgid "Stream is already closed" +msgstr "à°¸à±à°Ÿà±à°°à±€à°®à± యిపà±à°ªà°Ÿà°¿à°•ే మూయబడింది" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "ఆధార à°ªà±à°°à°µà°¾à°¹à°‚ కౠమదà±à°¦à°¤à± లేదౠఖండించà±" + +#: ../gio/gcancellable.c:310 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "ఆపరేషనౠరదà±à°¦à±ˆà°¨à°¦à°¿" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "చెలà±à°²à±à°¬à°¾à°Ÿà±à°²à±‹ లేని à°…à°‚à°¶à°‚, initialized లేదà±" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "ఇనà±à°ªà±à°Ÿà± లో అసంపూరà±à°£à°‚ మలà±à°Ÿà°¿à°¬à±†à±–à°Ÿà± à°•à±à°°à°®à°‚" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "à°—à°®à±à°¯à°‚ లేని తగినంత à°¸à±à°¥à°²à°‚" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "à°Žà°—à±à°¬à°¡à°¿ బైటౠకà±à°°à°®à°‚నౠపరివరà±à°¤à°¿à°‚à°šà±à°Ÿ నిసà±à°¸à°¾à°°à°®à°—à±à°¨à±" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "పరివరà±à°¤à°¨à°‚ నందౠదోషం కలదà±: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "à°°à°¦à±à°¦à±à°šà±‡à°¯à°—లిగిన సిదà±à°¦à±€à°•à°°à°£ మదà±à°¦à°¤à±€à°¯à°¬à°¡à°¦à±" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "à°…à°•à±à°·à°°à°®à°¾à°²à°²à±Š à°•à°² '%s' à°¨à±à°‚à°¡à°¿ '%s' కౠపరివరà±à°¤à°¿à°‚చడానికి సహకరించదà±" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' à°¨à±à°‚à°¡à°¿ '%s' కౠపరివరà±à°¤à°¿à°‚à°šà°¡à°‚ సాధà±à°¯à°‚ కాదౠ" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s à°°à°•à°®à±" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "తెలియని à°°à°•à°®à±" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s దసà±à°¤à±à°°à°®à±à°°à°•à°®à±" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials à°ˆ OS లో అమలౠకాలేదà±" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "మీ వేదిక à°Žà°Ÿà±à°µà°‚à°Ÿà°¿ GCredentials మదà±à°¦à°¤à± ఉంది" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials à°ˆ OS పైన à°ªà±à°°à±‹à°¸à±†à°¸à± à°à°¡à°¿ కలిగివà±à°‚à°¡à°¦à±" + +#: ../gio/gcredentials.c:565 +#| msgid "GCredentials is not implemented on this OS" +msgid "Credentials spoofing is not possible on this OS" +msgstr "à°ˆ OS పైన à°•à±à°°à±†à°¡à±†à°¨à±à°·à°¿à°¯à°²à±à°¸à± à°¸à±à°ªà±‚ఫింగౠసాధà±à°¯à°ªà°¡à°¦à±" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "à°¸à±à°Ÿà±à°°à±€à°®à± యొకà±à°• à°…à°¨à±à°•ోని à°¤à±à°µà°°à°¿à°¤ à°®à±à°—à°¿à°‚à°ªà±" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "మదà±à°¦à°¤à± లేని à°•à±€ '%s 'à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°ªà±à°°à°µà±‡à°¶à°‚ లో'%s'" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"à°šà°¿à°°à±à°¨à°¾à°®à°¾ '%s 'చెలà±à°²à°¦à± (సరిగà±à°—à°¾ మారà±à°—à°‚, tmpdir లేదా నైరూపà±à°¯ కీలనౠఒక అవసరం)" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°ªà±à°°à°µà±‡à°¶à°‚ లో à°…à°°à±à°§à°‚ à°•à±€ / విలà±à°µ జంట కలయిక '%s '" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ '%s లో లోపం '- పోరà±à°Ÿà± à°—à±à°£à°‚ సరిగà±à°—à°¾ లేదà±" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ '%s లో లోపం '- à°•à±à°Ÿà±à°‚బం à°—à±à°£à°‚ సరిగà±à°—à°¾ లేదà±" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ మూలకం '%s ' కోలనౠ(:) కలిగి లేదà±" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "à°•à±€/విలà±à°µ జత %d, '%s ', à°šà°¿à°°à±à°¨à°¾à°®à°¾ మూలకం లో '%s' ఈకà±à°µà°²à± సైనౠకలిగిలేదà±" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"à°šà°¿à°°à±à°¨à°¾à°®à°¾ మూలకం లో à°•à±€ / విలà±à°µ జంట%d లో లోపం unescaping à°•à±€ లేదా విలà±à°µ, '%s ''%s'" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"à°šà°¿à°°à±à°¨à°¾à°®à°¾ '%s 'లో లోపం - unix రవాణా కీలనౠసరిగà±à°—à°¾ à°’à°• అవసరం' మారà±à°—à°‚ 'లేదా " +"'నైరూపà±à°¯' అమరà±à°šà°µà°šà±à°šà±à°¨à±" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ '%s లో లోపం '- హోసà±à°Ÿà± à°—à±à°£à°‚ తపà±à°ªà°¿à°ªà±‹à°¯à°¿à°¨ లేదా తపà±à°ªà±à°¡à± ఉంది" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ లో లోపం '%s '- పోరà±à°Ÿà± à°—à±à°£à°‚ తపà±à°ªà°¿à°ªà±‹à°¯à°¿à°¨ లేదా తపà±à°ªà±à°¡à± ఉంది" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ లో లోపం '%s '- noncefile à°—à±à°£à°‚ లేదౠలేదా తపà±à°ªà±à°¡à±" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "à°…à°¨à±à°¸à°‚ధానమగà±à°Ÿà°²à±‹ దోషమà±:" + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "తెలియదౠలేదా మదà±à°¦à°¤à± రవాణా '%s 'à°šà°¿à°°à±à°¨à°¾à°®à°¾'%s కోసం'" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "లోపం à°ªà±à°°à°¾à°°à°‚à°­ సమయమౠఫైలౠ'%s ':%s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "ఫైలౠ'%s': %s à°šà°¦à±à°µà±à°Ÿà°²à±‹ దోషం" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "సమయ ఫైలౠ'%s ', 16 బైటà±à°²à± అంచనా, à°¨à±à°‚à°¡à°¿ చదవడంలో లోపం %d వచà±à°šà°¿à°‚ది" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "సమయమౠఫైలౠ'%s 'à°ªà±à°°à°µà°¾à°¹à°¾à°¨à°¿à°•à°¿ విషయాలౠవà±à°°à°¾à°¯à°¡à°‚ లోపం:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "ఇచà±à°šà°¿à°¨ à°šà°¿à°°à±à°¨à°¾à°®à°¾ ఖాళీగా ఉంది" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "uid అమరà±à°šà±à°¨à°ªà±à°ªà±à°¡à± సందేశ బసౠవిసà±à°¤à°°à°¿à°‚పలేమà±" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "à°’à°• యంతà±à°°à°‚-id లేకà±à°‚à°¡à°¾ à°’à°• సందేశానà±à°¨à°¿ బసà±à°¸à± à°µà±à°¯à°¾à°ªà°¿à°¸à±à°¤à°¾à°¯à°¿ సాధà±à°¯à°‚ కాదà±:" + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "లోపం ఆవిరà±à°­à°¾à°µà°¾à°¨à°¿à°•à°¿ కారణమైంది కమాండౠలైనౠ'%s ':" + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(à°ˆ విండోనౠమూసివేసి à° à°…à°•à±à°·à°° టైపౠచేయండి)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "సమావేశంలో నడà±à°¸à±à°¤à±‹à°‚ది లేదౠdbus, మరియౠసà±à°µà°¯à°‚ à°ªà±à°°à°¾à°°à°‚à°­à°‚ విఫలమైంది" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "సెషనౠబసà±à°¸à± à°šà°¿à°°à±à°¨à°¾à°®à°¾ (à°ˆ OS కోసం అమలౠకాలేదà±) à°•à°¨à±à°—ొనలేదà±" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"చరరాశి DBUS_STARTER_BUS_TYPE పరà±à°¯à°¾à°µà°°à°£à°‚ à°¨à±à°‚à°šà°¿ బసà±à°¸à± à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°•à°¨à±à°—ొనలేదౠ- " +"తెలియని విలà±à°µ '%s '" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"బసà±à°¸à± à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°•à°¨à±à°—ొనలేదౠఎందà±à°•ంటే DBUS_STARTER_BUS_TYPE పరà±à°¯à°¾à°µà°°à°£à°‚ వేరియబà±à°²à± " +"సెటౠలేదà±" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "తెలియని బసà±à°¸à± à°°à°•à°‚%d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "à°’à°• లైనౠచదివి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°¸à±à°¤à±à°¨à±à°¨ కంటెంటౠఊహించని లేకపోవడం" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "à°ªà±à°°à°¯à°¤à±à°¨à°¿à°¸à±à°¤à±à°¨à±à°¨ కంటెంటౠఊహించని లేకపోవడం (à°¸à±à°°à°•à±à°·à°¿à°¤à°‚à°—à°¾) à°’à°• లైనౠచదివి" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"(à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹:%s): à°…à°¨à±à°¨à±€ à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ à°ªà±à°°à°¾à°®à°¾à°£à±€à°•à°°à°£ విధానాల (%s à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చాడà±) " +"అలిసిపోయిన" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver à°¦à±à°µà°¾à°°à°¾ à°°à°¦à±à°¦à± à°…à°¯à±à°¯à°¿à°‚ది :: అధికారం-అధికారం-పీరà±" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "డైరెకà±à°Ÿà°°à±€ '%s' కొరకౠసమాచారం పొందà±à°¨à°ªà±à°ªà±à°¡à± దోషమà±: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"డైరెకà±à°Ÿà°°à±€ '%s'à°¨ à°…à°¨à±à°®à°¤à±à°²à± తపà±à°ªà±à°¡à± ఉనà±à°¨à°¾à°¯à°¿. ఊహించిన రీతిలో 0700, 0%o వచà±à°šà°¿à°‚ది" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "డైరెకà±à°Ÿà°°à±€ '%s 'సృషà±à°Ÿà°¿à°‚చడంలో లోపం:%s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "పఠనం కోసం '%s 'keyring లోపం à°ªà±à°°à°¾à°°à°‚à°­:" + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "లైనౠ%d కంటెంటౠ'%s' తో' %s వదà±à°¦ keyring వదà±à°¦ సరిగà±à°—à°¾ లేదà±" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"లైనౠ%d కంటెంటౠ'%s' తో '%s వదà±à°¦ keyring యొకà±à°• మొదటి టోకెనౠసరిగà±à°—à°¾ లేదà±" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"వరà±à°¸ %d కంటెంటౠ'%s' తో '%s' వదà±à°¦ keyring యొకà±à°• రెండవ టోకెనౠసరిగà±à°—à°¾ లేదà±" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "keyringలో id %d తో '%s' వదà±à°¦ à°•à±à°•à±€ à°•à°¨à±à°—ొనలేదà±" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "లోపం తొలగించడంలో కాలం చెలà±à°²à°¿à°¨ లాకౠఫైలౠ'%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "%s లాకౠఫైలౠసృషà±à°Ÿà°¿à°‚à°šà±à°Ÿà°²à±‹ దోషం: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "లోపం à°®à±à°—ింపౠ(unlinked) లాకౠఫైలౠ'%s':%s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "లోపం unlinking లాకౠఫైలౠ'%s ':%s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "à°°à°šà°¨ కోసం '%s' keyring లోపం à°ªà±à°°à°¾à°°à°‚à°­:" + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(అదనంగా, కోసం లాకౠవిడà±à°¦à°² '%s' కూడా విఫలమైంది: %s)" + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "కనెకà±à°·à°¨à± మూసివేయబడింది" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "సమయం à°®à±à°—ిసింది à°¸à±à°¥à°¾à°¨à°¾à°¨à°¿à°•à°¿ చేరà±à°•à±à°‚ది" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"à°’à°• à°•à±à°²à°¯à°¿à°‚à°Ÿà±-వైపౠకనెకà±à°·à°¨à± నిరà±à°®à°¿à°‚చడానికి ఉనà±à°¨à°ªà±à°ªà±à°¡à± మదà±à°¦à°¤à± లేని జెండాలౠ" +"à°Žà°¦à±à°°à±à°•ొంది" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"మారà±à°—à°‚%s వదà±à°¦ వసà±à°¤à±à°µà± మీద à°…à°Ÿà±à°µà°‚à°Ÿà°¿ ఇంటరà±à°«à±‡à°¸à± 'org.freedesktop.DBus.Properties '" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "à°…à°Ÿà±à°µà°‚à°Ÿà°¿ ఆసà±à°¤à°¿ '%s '" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "ఆసà±à°¤à°¿ '%s 'రీడబà±à°²à± కాదà±" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "ఆసà±à°¤à°¿ '%s 'à°µà±à°°à±ˆà°Ÿà°¬à±à°²à± కాదà±" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "సెటà±à°Ÿà°¿à°‚à°—à±à°²à±‹ లోపం ఆసà±à°¤à°¿ '%s ': ఊహించినది à°°à°•à°‚'%s' కానీ వచà±à°šà°¿à°‚ది '%s '" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "à°…à°Ÿà±à°µà°‚à°Ÿà°¿ ఇంటరà±à°«à±‡à°¸à± '%s '" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "à°…à°Ÿà±à°µà°‚à°Ÿà°¿ ఇంటరà±à°«à±‡à°¸à±" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "à°…à°Ÿà±à°µà°‚à°Ÿà°¿ ఇంటరà±à°«à±‡à°¸à± '%s 'మారà±à°—à°‚%s వదà±à°¦ వసà±à°¤à±à°µà± à°¨" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "à°…à°Ÿà±à°µà°‚à°Ÿà°¿ పదà±à°§à°¤à°¿ '%s'" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "సందేశం యొకà±à°• పదà±à°§à°¤à°¿, '%s ', సరిపోలడం లేదౠఅంచనా à°°à°•à°‚'%s'" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "à°’à°• వసà±à°¤à±à°µà± ఇపà±à°ªà°Ÿà°¿à°•ే %s వదà±à°¦ ఇంటరà±à°«à±‡à°¸à± %s కోసం à°Žà°—à±à°®à°¤à°¿ ఉంది" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "పదà±à°§à°¤à°¿ '%s 'తిరిగి à°°à°•à°‚'%s', కానీ అంచనా '%s'" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "పదà±à°§à°¤à°¿ '%s 'ఇంటరà±à°«à±‡à°¸à± à°¨'%s' సంతకం '%s 'లేదౠతో" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "à°’à°• subtree ఇపà±à°ªà°Ÿà°¿à°•ే %s కోసం à°Žà°—à±à°®à°¤à°¿ ఉంది" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "à°°à°•à°‚ చెలà±à°²à°¦à±" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL సందేశం: PATH లేదా సభà±à°¯à±à°² శీరà±à°·à°¿à°• ఫీలà±à°¡à± లేదà±" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN సందేశం: REPLY_SERIAL శీరà±à°·à°¿à°• ఫీలà±à°¡à± లేదà±" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR సందేశం: REPLY_SERIAL లేదా ERROR_NAME శీరà±à°·à°¿à°• ఫీలà±à°¡à± లేదà±" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "సిగà±à°¨à°²à± సందేశం: PATH, ఇంటరà±à°«à±‡à°¸à± లేదా సభà±à°¯à±à°² శీరà±à°·à°¿à°• ఫీలà±à°¡à± లేదà±" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"సిగà±à°¨à°²à± సందేశం: PATH శీరà±à°·à°¿à°• field à°ªà±à°°à°¤à±à°¯à±‡à°•ించబడిన విలà±à°µ / org ఉపయోగించి / " +"ఉందిfreedesktop/" +"DBus/ à°¸à±à°¥à°¾à°¨à°¿à°•" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"సిగà±à°¨à°²à± సందేశం: ఇంటరà±à°«à±‡à°¸à± శీరà±à°·à°¿à°• ఫీలà±à°¡à± à°ªà±à°°à°¤à±à°¯à±‡à°•ించబడిన విలà±à°µ org " +"ఉపయోగిసà±à°¤à±‹à°‚ది freedesktop.DBus." +"Local" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu బైటౠచదవడానికి కావలెనౠకానీ %lu వచà±à°šà°¿à°‚ది" +msgstr[1] "%lu బైటà±à°²à± చదవడానికి కావలెనౠకానీ %lu వచà±à°šà°¾à°¯à°¿" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "à°¸à±à°Ÿà±à°°à°¿à°‚à°—à± '%s'తరà±à°µà°¾à°¤ NUL బైటౠఅంచనా కానీ బైటౠ%d దొరకలేదà±" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"ఊహించిన చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ UTF-8 string కానీ బైటౠఆఫà±à°¸à±†à°Ÿà± %d వదà±à°¦ చెలà±à°²à°¨à°¿ " +"బైటà±à°²à± దొరకలేదà±(à°¸à±à°Ÿà±à°°à°¿à°‚గౠయొకà±à°• " +"పొడవౠ%d ఉంటà±à°‚ది). చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ UTF-8 string అపౠఆ సమయం వరకౠఉంది'%s'" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "à°…à°¨à±à°µà°¯à°¿à°‚à°šà°¡à°‚ విలà±à°µ '%s 'à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ D-బసౠవసà±à°¤à±à°µà± మారà±à°—à°‚ కాదà±" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "à°…à°¨à±à°µà°¯à°¿à°‚à°šà°¡à°‚ విలà±à°µ '%s 'à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ D-బసౠసంతకం కాదౠ" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"పొడవౠ%u బైటౠయొకà±à°• à°Žà°¦à±à°°à±à°•ొంది à°…à°°à±à°°à±‡. à°—à°°à°¿à°·à±à°  పొడవౠ2 << 26 బైటà±à°²à± (64 MiB) " +"ఉంది." +msgstr[1] "" +"పొడవౠ%u బైటà±à°²à± యొకà±à°• à°Žà°¦à±à°°à±à°•ొంది à°…à°°à±à°°à±‡. à°—à°°à°¿à°·à±à°  పొడవౠ2 << 26 బైటà±à°²à± (64 " +"MiB) ఉంది." + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"'a%c' రకపౠఎనà±â€Œà°•ౌంటరà±à°¡à± ఎరే, %u బైటà±à°² à°—à±à°£à°¿à°œà°¾à°¨à°¿à°•à°¿ సమాన పొడవà±à°¨à± కోరà±à°•à±à°‚టోంది, " +"కాని %u బైటà±à°² పొడవౠమాతà±à°°à°®à±‡ లభà±à°¯à°®à±ˆà°‚ది" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" +"à°…à°¨à±à°µà°¯à°¿à°‚à°šà°¡à°‚ విలà±à°µ '%s 'వేరియంటౠకొరకౠఒక చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ D-బసౠసంతకం కాదà±" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"D-బసౠవైరౠఫారà±à°®à°¾à°Ÿà± à°¨à±à°‚à°¡à°¿ à°°à°•à°‚ à°¸à±à°Ÿà±à°°à°¿à°‚à°—à± '%s 'తో GVariant deserializing లోపం" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"చెలà±à°²à°¨à°¿ endianness విలà±à°µ. కానీ అంచనా 0x6c ('à°Žà°²à±') లేదా 0x42 ('B') విలà±à°µ " +"దొరకలేదà±0x%02x" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "చెలà±à°²à°¨à°¿ à°ªà±à°°à°§à°¾à°¨ à°ªà±à°°à±‹à°Ÿà±‹à°•ాలౠవెరà±à°·à°¨à±. 1 అంచనా కాని %d దొరకలేదà±" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "సంతకం '%s 'తో సంతకం శీరà±à°·à°¿à°• కానీ దొరకలేదౠసందేశ భాగం ఖాళీగా ఉంది" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" +"à°…à°¨à±à°µà°¯à°¿à°‚à°šà°¡à°‚ విలà±à°µ '%s 'à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ D-బసౠసంతకం (శరీరం కోసం) కాదà±" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "సందేశం కాని సందేశ భాగం లో కాదౠసంతకం శీరà±à°·à°¿à°• %u బైటౠఉంది" +msgstr[1] "సందేశం ఠసంతకం శీరà±à°·à°¿à°• కాని సందేశ భాగం %u బైటà±à°²à±" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "సందేశం deserialize సాధà±à°¯à°‚ కాదà±:" + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "తో GVariant serializing లోపం à°°à°•à°‚ à°¸à±à°Ÿà±à°°à°¿à°‚à°—à± '%s 'D-బసౠవైరౠఆకృతికి" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"సందేశం%d ఫైలౠసూచికలౠకలిగి ఉంది కాని శీరà±à°·à°¿à°• ఫీలà±à°¡à± %d ఫైలౠ" +"సూచిసà±à°¤à±à°‚దిసూచికలà±" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "సందేశం serialize సాధà±à°¯à°‚ కాదà±:" + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "సందేశ భాగం సంతకం '%s 'కలిగి ఉంది కాని సంఖà±à°¯ సంతకం శీరà±à°·à°¿à°• ఉంది" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "సందేశ భాగం à°°à°•à°‚ లేదౠసంతకం '%s' కానీ శీరà±à°·à°¿à°• à°•à±à°·à±‡à°¤à±à°°à°‚లో సంతకం'%s' ఉంది" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "సందేశ భాగం ఖాళీగా ఉంది కానీ శీరà±à°·à°¿à°• à°•à±à°·à±‡à°¤à±à°°à°‚లో సంతకం (%s) 'ఉంది '" + +#: ../gio/gdbusmessage.c:3282 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "à°°à°•à°‚ '%s యొకà±à°• శరీరం తో లోపం తిరిగి '" + +#: ../gio/gdbusmessage.c:3290 +msgid "Error return with empty body" +msgstr "ఖాళీ శరీరంతో లోపం తిరిగి" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "హారà±à°¡à±à°µà±‡à°°à± à°¸à±à°¥à±‚à°² వివరంపొందడం సాధà±à°¯à°‚ కాలేదౠ%s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "/var/lib/dbus/machine-id లేదా /etc/machine-id లోడౠచేయà±à°Ÿà°²à±‹ విఫలమైంది: " + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s యొకà±à°• లోపం కాలౠStartServiceByName: " + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "ఊహించని సమాధానం %d StartServiceByName (\"%s\") పదà±à°¦à°¤à°¿ à°¨à±à°‚à°¡à°¿" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"పదà±à°§à°¤à°¿ ఇనà±à°µà±‹à°•ౠకాదà±; à°ªà±à°°à°¾à°•à±à°¸à±€ à°’à°• యజమాని లేకà±à°‚à°¡à°¾ à°’à°• well-తెలిసిన పేరౠకోసం " +"మరియà±à°ªà±à°°à°¾à°•à±à°¸à±€ " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START జెండా నిరà±à°®à°¿à°‚చబడింది" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "మదà±à°¦à°¤à± లేదౠనైరూపà±à°¯ నేమౠసà±à°ªà±‡à°¸à±" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "à°¸à±à°Ÿà±à°°à°¿à°‚à°—à± '%s 'à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ D-బసౠGUID కాదà±" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "సమయ ఫైలà±%s: '%s 'వదà±à°¦ రాయడం లోపం " + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "à°¸à±à°Ÿà±à°°à°¿à°‚à°—à± '%s 'à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ D-బసౠGUID కాదౠ" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "మదà±à°¦à°¤à°¿à°µà±à°µà°¨à°¿ రవాణా '%s వినండి కాదౠ'" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"ఆదేశాలà±:\n" +" సహాయం à°ˆ సమాచారానà±à°¨à°¿ చూపించà±\n" +" ఇంటà±à°°à±‹à°¸à±à°ªà±†à°•à±à°Ÿà± తననౠతానౠపరిశీలించà±à°•ొనౠఒక రిమోటౠవసà±à°¤à±à°µà± \n" +" మానిటరౠఒక à°¸à±à°¦à±‚à°° వసà±à°¤à±à°µà± పరà±à°¯à°µà±‡à°•à±à°·à°£\n" +" కాలౠసà±à°¦à±‚à°° వసà±à°¤à±à°µà± పై à°’à°• పదà±à°§à°¤à°¿ ఇనà±à°µà±‹à°•ౠకాలà±\n" +" ఎమిటౠఒక సిగà±à°¨à°²à± విడà±à°¦à°² చేసà±à°¤à°¾à°¯à°¿ విడà±à°¦à°² చేసà±à°¤à°¾à°¯à°¿\n" +"\n" +"à°ªà±à°°à°¤à°¿ ఆదేశంపై సహాయం పొందడానికి \"%s COMMAND --help\" వాడండి\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "దోషం కలదౠ:%s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "లోపం à°…à°¨à±à°µà°¯ బయటకౠరావటం XML: %s \n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "à°µà±à°¯à°µà°¸à±à°¥ బసà±à°¸à± à°…à°¨à±à°¸à°‚ధానమగà±à°Ÿà°•à±" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "సెషనౠబసà±à°¸à± à°…à°¨à±à°¸à°‚ధానమగà±à°Ÿà°•à±" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "ఇచà±à°šà°¿à°¨ D-బసౠచిరà±à°¨à°¾à°®à°¾ à°…à°¨à±à°¸à°‚ధానమగà±à°Ÿà°•à±" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "à°…à°¨à±à°¸à°‚ధానమౠమà±à°—ింపౠసà±à°¥à°²à°‚ ఎంపికలà±:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "à°…à°¨à±à°¸à°‚ధానమౠచివరి పాయింటౠతెలిపిన ఎంపికలà±" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "పేరà±à°•ొనలేదౠఅనà±à°¸à°‚ధానమౠచివరి పాయింటà±" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "పేరà±à°•ొనà±à°¨ బహà±à°³ à°…à°¨à±à°¸à°‚ధానమౠఅంతà±à°¯ బిందà±à°µà±à°²" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "హెచà±à°šà°°à°¿à°•: ఆతà±à°® పరిశీలన డేటా à°ªà±à°°à°•ారం, ఇంటరà±à°«à±‡à°¸à± '%s' లేదౠ\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "హెచà±à°šà°°à°¿à°•: ఆతà±à°® పరిశీలన డేటా à°ªà±à°°à°•ారం, పదà±à°§à°¤à°¿ '%s' లేదౠఇంటరà±à°«à±‡à°¸à± '%s'\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "సంకేతం కోసం ఇచà±à°šà°¾à°ªà±‚రితం à°—à°®à±à°¯à°‚ (à°ªà±à°°à°¤à±à°¯à±‡à°• పేరà±)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "à°¨ సంకేతం విడà±à°¦à°² చేసà±à°¤à°¾à°¯à°¿ కౠవసà±à°¤à±à°µà± మారà±à°—à°‚" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "సంకేతం మరియౠఅంతరà±à°®à±à°–à°‚ పేరà±" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "à°’à°• సంకేతం విడà±à°¦à°² చేసà±à°¤à°¾à°¯à°¿." + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "à°…à°¨à±à°¸à°‚ధానించà±à°Ÿà°²à±‹ దోషం: %s \n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "లోపం: వసà±à°¤à±à°µà± మారà±à°—à°‚ పేరà±à°•ొనబడలేదà±.\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "దోషం: %s à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ వసà±à°¤à±à°µà± మారà±à°—à°‚ లేదà±\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "లోపం: సంకేతం పేరà±à°•ొనబడలేదౠ\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "దోషం: సంకేతం à°…à°¨à±à°¨à°¦à°¿ పూరà±à°¤à°¿à°—à°¾-ఉతà±à°¤à±€à°°à±à°£à°®à±ˆà°¨ పేరౠకావలెనà±.\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "దోషం: %s à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ అంతరà±à°®à±à°–à°‚ పేరౠకాదౠ\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "దోషం: %s à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ సభà±à°¯à±à°¡à± పేరౠకాదౠ\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "లోపం: %s à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ à°ªà±à°°à°¤à±à°¯à±‡à°• బసà±à°¸à± పేరౠకాదà±.\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "లోపం à°…à°¨à±à°µà°¯ పారామితి %d: %s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "à°…à°¨à±à°¸à°‚ధానమà±à°¨à± లోపం ఒరవడిఅనà±à°¸à°‚ధానమà±à°¨à± : %s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "à°¨ పదà±à°§à°¤à°¿ à°…à°°à±à°¥à°¿à°‚చడానికి à°—à°®à±à°¯à°‚ పేరà±" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "à°¨ పదà±à°§à°¤à°¿ à°…à°°à±à°¥à°¿à°‚చడానికి వసà±à°¤à±à°µà± మారà±à°—à°‚" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "పదà±à°§à°¤à°¿ మరియౠఅంతరà±à°®à±à°–à°‚ పేరà±" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "సెకండà±à°²à°²à±‹ à°—à°¡à±à°µà± à°®à±à°—ిసింది" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "à°’à°• మారà±à°®à±‚à°² వసà±à°¤à±à°µà± à°’à°• పదà±à°§à°¤à°¿ à°…à°°à±à°¥à°¿à°‚చడానికి." + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "లోపం: à°—à°®à±à°¯à°‚ పేరà±à°•ొనà±à°¨ లేదౠ\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "లోపం: వసà±à°¤à±à°µà± మారà±à°—à°‚ పేరà±à°•ొనà±à°¨ లేదౠ\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "లోపం: మెథడౠపేరౠపేరà±à°•ొనà±à°¨ లేదౠ\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "లోపం: పదà±à°§à°¤à°¿ పేరౠ'%s' చెలà±à°²à°¦à± \n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "" +" à°’à°• దోషం నౠఅనà±à°µà°¯à°¿à°‚చడంలో %d పారà±à°¸à±€à°‚గౠపారామితి.à°† దోషం దీనికి సంబంధించినది:'%" +"s':%s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "à°—à°®à±à°¯à°‚ పేరౠతననౠతానౠపరిశీలించà±à°•ొనౠకà±" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "à°—à°®à±à°¯à°‚ పేరౠతననౠతానౠపరిశీలించà±à°•ొనౠకà±" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "à°®à±à°¦à±à°°à°£ XML" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "పిలà±à°²à°²à± పరిశీలించà±à°•ొనà±" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "కేవలం లకà±à°·à°£à°¾à°²à± à°®à±à°¦à±à°°à°¿à°‚చవచà±à°šà±" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "à°’à°• మారà±à°®à±‚à°² వసà±à°¤à±à°µà± పరిశీలించà±à°•ొ." + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "పరà±à°¯à°µà±‡à°•à±à°·à°¿à°‚à°šà±à°Ÿà°•à± à°—à°®à±à°¯à°‚ పేరà±" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "పరà±à°¯à°µà±‡à°•à±à°·à°¿à°‚à°šà±à°Ÿà°•ౠవసà±à°¤à±à°µà± మారà±à°—à°‚" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "à°’à°• మారà±à°®à±‚à°² వసà±à°¤à±à°µà± పరà±à°¯à°µà±‡à°•à±à°·à°¿à°‚చడానికి" + +#: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4525 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "నామమà±à°²à±‡à°¨à°¿" + +#: ../gio/gdesktopappinfo.c:2410 +msgid "Desktop file didn't specify Exec field" +msgstr "డెసà±à°•à±à°Ÿà°¾à°ªà± దసà±à°¤à±à°°à°®à± Exec à°•à±à°·à±‡à°¤à±à°°à°®à±à°¨à± తెలà±à°ªà°²à±‡à°¦à±" + +#: ../gio/gdesktopappinfo.c:2695 +msgid "Unable to find terminal required for application" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨à°‚కౠకావలిసిన â€à°Ÿà±†à°°à±à°®à°¿à°¨à°²à±â€Œà°¨à± à°•à°¨à±à°—ొనలేక పోయింది" + +#: ../gio/gdesktopappinfo.c:3116 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "వినియోగదారి à°…à°¨à±à°µà°°à±à°¤à°¨ ఆకృతీకరణ సంచయం %sనౠసృషà±à°Ÿà°¿à°‚చలేకపోయింది: %s" + +#: ../gio/gdesktopappinfo.c:3120 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "వినియోగదారి MIME ఆకృతీకరణ సంచయం %sనౠసృషà±à°Ÿà°¿à°‚చలేకపోయింది: %s" + +#: ../gio/gdesktopappinfo.c:3360 ../gio/gdesktopappinfo.c:3384 +msgid "Application information lacks an identifier" +msgstr "దరఖాసà±à°¤à± సమాచారం à°’à°• à°—à±à°°à±à°¤à°¿à°‚చే లేదà±" + +#: ../gio/gdesktopappinfo.c:3617 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "వినియోగదారి డెసà±à°•à±à°Ÿà°¾à°ªà± దసà±à°¤à±à°°à°®à±à°¨à± సృషà±à°Ÿà°¿à°‚చలేకపోయింది %s" + +#: ../gio/gdesktopappinfo.c:3751 +#, c-format +msgid "Custom definition for %s" +msgstr "%s కొరకౠమలిచిన నిరà±à°µà°šà°¨à°®à±" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "à°¡à±à°°à±ˆà°µà± బయటకà±à°ªà°‚à°ªà±à°¦à°¾à°¨à°¿à°¨à°¿ చేయలేదà±" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" +"à°¡à±à°°à±ˆà°µà± బయటకà±à°ªà°‚పౠలేదా ఆపరేషనà±â€Œà°¤à±‹_బయటకà±_పంపౠవిలà±à°µà°¨à± అభివృదà±à°¦à°¿à°ªà°°à°šà°²à±‡à°• పోయింది" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "మాధà±à°¯à°®à°‚ కొరకౠఎనà±à°¨à°¿à°•నౠడà±à°°à±ˆà°µà± చేయలేదà±" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "à°¡à±à°°à±ˆà°µà± à°ªà±à°°à°¾à°°à°‚à°­à°®à±à°¨à± అభివృదà±à°¦à°¿ పరచలేకపోయింది" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "ఆపà±à°Ÿà°¨à± à°¡à±à°°à±ˆà°µà± అభివృదà±à°¦à°¿ పరచలేకపోయింది" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS మదà±à°¦à°¤à± à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేదà±" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem à°Žà°¨à±à°•ోడింగౠయొకà±à°• వరà±à°·à°¨à± %dనౠసంభాలించలేదà±" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem à°Žà°¨à±à°•ోడింగà±â€Œà°¨à°‚దౠటోకెనà±à°¸à± (%d)యొకà±à°• తపà±à°ªà±à°—ావà±à°¨à±à°¨ సంఖà±à°¯" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon à°Žà°¨à±à°•ోడింగౠయొకà±à°• వరà±à°·à°¨à± %dనౠసంభాలించలేదà±" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon à°Žà°¨à±à°•ోడింగà±â€Œà°¨à°‚దౠటోకెనà±à°¸à± (%d)యొకà±à°• తపà±à°ªà±à°—ావà±à°¨à±à°¨ సంఖà±à°¯" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon కొరకౠGEmblem కావలసివà±à°‚ది" + +#: ../gio/gfile.c:956 ../gio/gfile.c:1194 ../gio/gfile.c:1332 +#: ../gio/gfile.c:1570 ../gio/gfile.c:1625 ../gio/gfile.c:1683 +#: ../gio/gfile.c:1767 ../gio/gfile.c:1824 ../gio/gfile.c:1888 +#: ../gio/gfile.c:1943 ../gio/gfile.c:3591 ../gio/gfile.c:3646 +#: ../gio/gfile.c:3853 ../gio/gfile.c:3895 ../gio/gfile.c:4358 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7748 ../gio/gfile.c:7838 ../gio/gfile.c:7922 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "ఆపరేషనౠమదà±à°¦à°¤à±€à°¯à°¬à°¡à°²à±‡à°¦à±" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1455 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "వినియోగదారికి దృగà±à°—ోచరమగౠమౌంటౠలేదà±" + +#: ../gio/gfile.c:2502 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "డైరెకà±à°Ÿà°°à±€à°¨à°‚దౠనకలౠతీయలేదà±" + +#: ../gio/gfile.c:2562 +msgid "Can't copy directory over directory" +msgstr "డైరెకà±à°Ÿà°°à±€à°¨à°¿ డైరెకà±à°Ÿà°°à±€à°•à°¿ నకలౠతీయలేమà±" + +#: ../gio/gfile.c:2570 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "లకà±à°·à±à°¯à°ªà± దసà±à°¤à±à°°à°®à± à°µà±à°‚ది" + +#: ../gio/gfile.c:2589 +msgid "Can't recursively copy directory" +msgstr "డైరెకà±à°Ÿà°°à±€à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°®à±à°—à°¾ నకలà±à°¤à±€à°¯à°²à±‡à°¦à±" + +#: ../gio/gfile.c:2871 +msgid "Splice not supported" +msgstr "à°…à°¤à±à°•à±à°ªà±†à°Ÿà±à°Ÿà± మదà±à°¦à°¤à± లేదౠ" + +#: ../gio/gfile.c:2875 +#, c-format +msgid "Error splicing file: %s" +msgstr "లోపం splicing ఫైలà±: %s" + +#: ../gio/gfile.c:3006 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "నకలౠతీయà±à°Ÿ (reflink/clone) మౌంటà±à°¸à± మదà±à°¯à°¨ తోడà±à°ªà°¾à°Ÿà±à°¨à±€à°¯à°¦à±" + +#: ../gio/gfile.c:3010 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "నకలౠతీయà±à°Ÿ (reflink/clone) తోడà±à°ªà°¾à°Ÿà± లేదౠలేదా చెలà±à°²à°¨à°¿à°¦à°¿" + +#: ../gio/gfile.c:3015 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "నకలౠతీయà±à°Ÿ (reflink/clone) తోడà±à°ªà°¾à°Ÿà± లేదౠలేదా పనిచేయà±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gfile.c:3078 +msgid "Can't copy special file" +msgstr "à°ªà±à°°à°¤à±à°¯à±‡à°• దసà±à°¤à±à°°à°®à±à°¨à± నకలà±à°¤à±€à°¯à°²à±‡à°¦à±" + +#: ../gio/gfile.c:3843 +msgid "Invalid symlink value given" +msgstr "చెలà±à°²à°¨à°¿ సిమà±â€Œà°²à°¿à°‚కౠవిలà±à°µ యివà±à°µà°¬à°¡à°¿à°¨à°¦à°¿" + +#: ../gio/gfile.c:4004 +msgid "Trash not supported" +msgstr "à°Ÿà±à°°à°¾à°·à± మదà±à°¦à°¤à±€à°¯à°²à±‡à°¦à±" + +#: ../gio/gfile.c:4116 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "దసà±à°¤à±à°°à°®à± నామమà±à°²à± '%c'ని కలిగిలేవà±" + +#: ../gio/gfile.c:6540 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "వాలà±à°¯à±‚మౠమౌంటà±â€Œà°¨à± చేయలేకపోయింది" + +#: ../gio/gfile.c:6649 +msgid "No application is registered as handling this file" +msgstr "à°ˆ దసà±à°¤à±à°°à°®à± సంబాలించà±à°¤à±à°¨à±à°¨à°Ÿà±à°²à± యెటà±à°µà°‚à°Ÿà°¿ à°…à°¨à±à°µà°°à±à°¤à°¨à°®à± నమోదà±à°•ాలేదà±" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "à°Žà°¨à±à°¯à±‚మరేటరౠమూయబడినది" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "దసà±à°¤à±à°° యెనà±à°¯à±‚మరేటరౠయిపà±à°ªà°Ÿà°¿à°•ే వొక ఆపరేషనà±â€Œà°¨à± కలిగివà±à°‚ది" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "దసà±à°¤à±à°° యెనà±à°¯à±‚మరేటరౠయిపà±à°ªà°Ÿà°¿à°•ే మూయబడివà±à°‚ది" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon à°Žà°¨à±à°•ోడింగౠయొకà±à°• వరà±à°·à°¨à± %dనౠసంభాలించలేదà±" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon కొరకౠతపà±à°ªà±à°—ావà±à°¨à±à°¨ ఇనà±à°ªà±à°Ÿà± డాటా" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "à°¸à±à°Ÿà±à°°à±€à°®à± à°•à±à°µà°°à±€ సమాచారంనౠమదà±à°¦à°¤à±€à°¯à±à°Ÿà°²à±‡à°¦à± (_i)" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "సీకౠసà±à°Ÿà±à°°à±€à°®à±â€Œà°ªà±ˆà°¨ మదà±à°¦à°¤à±€à°¯à±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "à°Ÿà±à°°à°‚కేటౠఇనà±â€Œà°ªà±à°Ÿà± à°¸à±à°Ÿà±à°°à±€à°®à±â€Œà°ªà±ˆà°¨ à°…à°¨à±à°®à°¤à°¿à°‚చబడà±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "à°¸à±à°Ÿà±à°°à±€à°®à±â€Œà°ªà±ˆà°¨ à°Ÿà±à°°à°‚కేటౠమదà±à°¦à°¤à±€à°¯à±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "తపà±à°ªà±à°¡à± సంఖà±à°¯à°¾ టోకెనà±à°²à± (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "à°•à±à°²à°¾à°¸à± నామమౠ%s కొరకౠఠరకమà±à°²à±‡à°¦à±" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "రకమౠ%s GIcon యింటరà±â€Œà°«à±‡à°¸à±â€Œà°¨à± తయారà±à°šà±‡à°¯à°²à±‡à°¦à±" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "రకమౠ%s వరà±à°—ీకరించబడలేదà±" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "తపà±à°ªà±à°—ావà±à°¨à±à°¨ వరà±à°·à°¨à± సంఖà±à°¯: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "GIcon యింటరà±à°«à±‡à°¸à± పైన రకమౠ%s à°…à°¨à±à°¨à°¦à°¿ from_tokens()నౠతయారà±à°šà±‡à°¯à°²à±‡à°¦à±" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "à°ªà±à°°à°¤à°¿à°® యెనà±à°•ోడింగౠయొకà±à°• పంపిణీచేయబడిన వరà±à°·à°¨à±â€Œà°¨à± సంభాలించలేదà±" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "à° à°šà°¿à°°à±à°¨à°¾à°®à°¾ తెలà±à°ªà°²à±‡à°¦à±" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ కొరకౠ%u మరీ పొడవà±à°—à°¾ à°µà±à°‚ది" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "à°ªà±à°°à°¿à°«à°¿à°•à±à°¸à± పొడవౠదాటి బిటà±à°¸à±à°¨à± à°šà°¿à°°à±à°¨à°¾à°®à°¾ కలిగివà±à°‚ది" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "'%s' నౠIP à°šà°¿à°°à±à°¨à°¾à°®à°¾ మాసà±à°•à±à°µà°²à±† పారà±à°¸à± చేయలేకపోయింది" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "సాకెటౠచిరà±à°¨à°¾à°®à°¾ కొరకౠసరిపోవà±à°¨à°‚à°¤ జాగాలేదà±" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "మదà±à°¦à°¤à±€à°¯à°¨à°¿ సాకెటౠచిరà±à°¨à°¾à°®à°¾" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "ఇనà±â€Œà°ªà±à°Ÿà± à°¸à±à°Ÿà±à°°à±€à°®à± à°šà°¦à±à°µà±à°Ÿà°¨à± అభివృదà±à°¦à°¿ చేయà±à°Ÿà°²à±‡à°¦à±" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1027 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1474 +msgid "Stream has outstanding operation" +msgstr "à°ˆ à°¸à±à°Ÿà±à°°à±€à°®à± యిపà±à°ªà°Ÿà°¿à°•ే వొక ఆపరేషనà±â€Œà°¨à± కలిగివà±à°‚ది" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "మూలకం <%s> <%s> లోపల à°…à°¨à±à°®à°¤à°¿ లేదà±" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "మూలకం <%s> toplevel వదà±à°¦ à°…à°¨à±à°®à°¤à°¿ లేదà±" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "వనరౠనందౠఫైలౠ%s బహౠపరà±à°¯à°¾à°¯à°¾à°²à± కనిపించెనà±" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "à°à°¦à±ˆà°¨à°¾ వనరౠడైరెకà±à°Ÿà°°à±€à°¨à°‚దౠ'%s' à°—à±à°°à±à°¤à°¿à°‚à°šà±à°Ÿà°²à±‹ విఫలమైంది" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "à°ªà±à°°à°¸à±à°¤à±à°¤ డైరెకà±à°Ÿà°°à±€ నందౠ'%s' à°—à±à°°à±à°¤à°¿à°‚à°šà±à°Ÿà°•ౠవిఫలమయà±à°¯à±†à°¨à±" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "తెలియని నిరà±à°µà°°à±à°¤à°¨ à°à°šà±à°šà°¿à°•à°‚ \"%s\"" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "తాతà±à°•ాలిక ఫైలౠసృషà±à°Ÿà°¿à°‚à°šà±à°Ÿà°•ౠవిఫలమైంది: %s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "ఫైలౠ%s à°šà°¦à±à°µà±à°Ÿà°²à±‹ దోషం: %s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "ఫైలౠ%s à°•à±à°¦à°¿à°‚à°šà±à°Ÿà°²à±‹ దోషం" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "టెకà±à°¸à±à°Ÿà± <%s> లోపల కనిపించక పోవచà±à°šà±" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "à°…à°µà±à°Ÿà±à°ªà±à°Ÿà± ఫైలౠపేరà±" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" +"à°Žà°šà°Ÿà°¨à±à°‚à°¡à°¿ ఫైళà±à°³à± à°šà°¦à±à°µà°¬à°¡à±à°¨à±‹ à°† డైరెకà±à°Ÿà°°à±€à°²à± (à°…à°ªà±à°°à°®à±‡à°¯à°‚à°—à°¾ à°¸à±à°¥à°¾à°¨à°¿à°• డైరెకà±à°Ÿà°°à±€à°¨à°•à±)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "డైరెకà±à°Ÿà°°à±€" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"లకà±à°·à±à°¯à°ªà± ఫైలà±â€Œà°ªà±‡à°°à± పొడిగింపౠచేత యెంపికచేసిన ఫారà±à°®à°¾à°Ÿà±â€Œà°²à±‹ à°…à°µà±à°Ÿà±à°ªà±à°Ÿà± జనియింపచేయి" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "మూలపౠయెగà±à°µà°¸à±‚à°šà°¿ జనియింపచేయి" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" +"మీ కోడౠలోనికి వనరౠఫైలà±à°¨à°•ౠలింకౠచేయà±à°Ÿà°•à± à°µà±à°ªà°¯à±‹à°—ించౠసోరà±à°¸à±à°•ోడౠజనియింపచేయి" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "ఆధార జాబితానౠజనియింపచేయి" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "వనరౠసà±à°µà°¯à°‚చాలకంగా సృషà±à°Ÿà°¿à°‚à°šà°¿ మరియౠనమోదౠచేయవదà±à°¦à±" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "à°«à°‚à°•à±à°·à°¨à±à°²à°¨à± యెగà±à°®à°¤à°¿ చేయవదà±à°¦à±; వాటిని à°ªà±à°°à°•à°Ÿà°¿à°‚à°šà± G_GNUC_INTERNAL" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "జనియింపచేసిన సోరà±à°¸à± కోడౠకొరకౠవà±à°ªà°¯à±‹à°—à°¿à°‚à°šà°¿à°¨ C à°—à±à°°à±à°¤à°¿à°‚à°ªà±à°•ారి" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"వనరౠవివరణమà±à°¨à± వనరౠఫైలà±à°¨à°•à± à°µà±à°‚à°šà±à°®à±.\n" +"వనరౠవివరణమౠఫైళà±à°²à± .gresource.xml పొడిగింపà±à°¨à± కలిగివà±à°‚టాయి,\n" +"మరియౠమరియౠవనరౠఫైలౠ.gresource à°—à°¾ పిలà±à°šà± పొడిగింపà±à°¨à± కలిగివà±à°‚à°¡à±à°¨à±." + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "మీరౠఖచà±à°šà°¿à°¤à°‚à°—à°¾ వొక ఫైలౠపేరౠయివà±à°µà°¾à°²à°¿\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "ఖాళీ పేరà±à°²à± à°…à°¨à±à°®à°¤à°¿ లేదà±" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "చెలà±à°²à°¨à°¿ పేరౠ'%s': పేరà±à°²à± à°’à°• à°šà°¿à°¨à±à°¨ à°…à°•à±à°·à°°à°‚తో à°ªà±à°°à°¾à°°à°‚భమవà±à°¤à°¾à°¯à°¿ తపà±à°ªà°•" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"చెలà±à°²à°¨à°¿ పేరౠ'%s': చెలà±à°²à°¨à°¿ à°…à°•à±à°·à°°à°‚ '%c'; à°šà°¿à°¨à±à°¨ à°…à°•à±à°·à°°à°¾à°²à± మాతà±à°°à°®à±‡, నంబరà±à°²à± మరియౠ" +"హైఫనౠ('-') " +"à°…à°¨à±à°®à°¤à°¿à°‚చబడతాయి." + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "చెలà±à°²à°¨à°¿ పేరౠ'%s': రెండౠవరà±à°¸ హైఫనà±à°²à± ('--') à°…à°¨à±à°®à°¤à°¿à°‚చబడవà±." + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "చెలà±à°²à°¨à°¿ పేరౠ'%s': చివరి à°…à°•à±à°·à°°à°‚ ('-') కాలేకపోవచà±à°šà±." + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "చెలà±à°²à°¨à°¿ పేరౠ'%s': à°—à°°à°¿à°·à±à°  పొడవౠ1024 ఉంది" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr "<పిలà±à°²à°² పేరౠ= '%s'>ఇపà±à°ªà°Ÿà°¿à°•ే తెలà±à°ªà°¬à°¡à°¿à°¨" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "కీలనౠ'list-of' à°¸à±à°•ీమాకౠజతచేయలేమà±" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr "<కీలక పేరౠ= '%s'>ఇపà±à°ªà°Ÿà°¿à°•ే తెలà±à°ªà°¬à°¡à°¿à°¨" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" లో నీడలౠ; ఉపయోగం " +"విలà±à°µ సవరించడానికి" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "సరిగà±à°—à°¾ 'à°°à°•à°‚' à°’à°•à°Ÿà°¿, 'enum' లేదా 'జెండాలà±' à°’à°• లకà±à°·à°£à°‚ à°—à°¾ తపà±à°ªà°• à°•à±" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id = '%s'> లేదౠ(ఇంకా) నిరà±à°µà°šà°¿à°‚చింది." + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "GVariant à°°à°•à°‚ à°¸à±à°Ÿà±à°°à°¿à°‚à°—à± '%s' నిలిపివేసిన" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr " ఇచà±à°šà°¿à°¨ కాని à°¸à±à°•ీమ à°à°¦à±†à±–నా పొడిగిసà±à°¤à±‚ లేదà±" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "తొలగించకండి à°Žà°Ÿà±à°µà°‚à°Ÿà°¿ " + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " ఇపà±à°ªà°Ÿà°¿à°•ే తెలà±à°ªà°¬à°¡à°¿à°¨" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr "ఇపà±à°ªà°Ÿà°¿à°•ే పేరà±à°•ొనà±à°¨ " + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " ఇంకా ఇపà±à°ªà°Ÿà°¿à°•à°¿ లేని à°¸à±à°•ీమా '%s' విసà±à°¤à°°à°¿à°‚à°ªà±à°¨à±" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " ఇంకా ఇపà±à°ªà°Ÿà°¿à°•à°¿ లేని à°¸à±à°•ీమా '%s' యొకà±à°• జాబితా" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "à°’à°• మారà±à°—ానà±à°¨à°¿ à°’à°• à°¸à±à°•ీమ జాబితా ఉండకూడదà±" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "à°’à°• మారà±à°—ానà±à°¨à°¿ à°’à°• à°¸à±à°•ీమ విసà±à°¤à°°à°¿à°‚చడానికి కాదà±" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " à°’à°• జాబితా కాదౠఇది à°µà±à°¯à°¾à°ªà°¿à°‚à°šà°¿ జాబితా" + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" విసà±à°¤à°°à°¿à°‚à°šà°¿ కానీ " +"'%s'విసà±à°¤à°°à°¿à°‚చడానికి లేదౠ'%s'" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "à°’à°• మారà±à°—, వాడితేనే, à°ªà±à°°à°¾à°°à°‚భమవà±à°¤à°¾à°¯à°¿ మరియౠఒక à°¸à±à°²à°¾à°·à± తో అంతం చేయాలి" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "à°’à°• జాబితా యొకà±à°• మారà±à°—à°‚ ':/' తో అంతం చేయాలి" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id = '%s'> ఇపà±à°ªà°Ÿà°¿à°•ే తెలà±à°ªà°¬à°¡à°¿à°¨" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "మూలకం <%s> పైసà±à°¥à°¾à°¯à°¿ వదà±à°¦ à°…à°¨à±à°®à°¤à°¿à°‚చబడదà±" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "-- కఠినమైన పేరà±à°•ొనà±à°¨ జరిగినది; నిషà±à°•à±à°°à°®à°¿à°‚చే \n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "à°ˆ మొతà±à°¤à°‚ ఫైలౠవిసà±à°®à°°à°¿à°‚చబడింది.\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "à°ˆ ఫైలౠవిసà±à°®à°°à°¿à°¸à±à°¤à±à°¨à±à°¨à°¾à°®à±.\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "à°…à°Ÿà±à°µà°‚à°Ÿà°¿ కీలక '%s 'à°¸à±à°•ీమ లో '%s' à°—à°¾ ఓవరà±à°°à±†à±–డౠఫైలౠలో పేరà±à°•ొనà±à°¨ '%s '" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr ";. à°ˆ à°•à±€ కోసం ఓవరà±à°°à±†à±–డౠవిసà±à°®à°°à°¿à°¸à±à°¤à±‚ \n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " మరియౠకఠినమైన పేరà±à°•ొనà±à°¨ జరిగినది; నిషà±à°•à±à°°à°®à°¿à°‚చే.\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"à°•à±€ '%s' నౠసà±à°•ీమా '%s' నందౠవోవరà±â€Œà°°à±ˆà°¡à± ఫైలౠ'%s' నందౠతెలిపినటà±à°²à± పారà±à°¸à± " +"చేయà±à°Ÿà°²à±‹ దోషం: %s." + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "à°ˆ à°•à±€ కోసం ఓవరà±à°°à±†à±–డౠవిసà±à°®à°°à°¿à°‚à°šà°¡à°‚. \n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"à°•à±€ '%s' కోసం à°¸à±à°•ీమా'%s' నందౠఓవరà±à°°à±†à±–డౠఫైలౠ'%s' నందౠవోవరౠరైడౠసà±à°•ీమలో " +"ఇవà±à°µà°¬à°¡à°¿à°¨ పరిధికి బయటవà±à°‚ది" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"కీలక '%s కోసం తొలగించకండి 'à°¸à±à°•ీమ లో'%s' ఓవరà±à°°à±†à±–డౠఫైలౠ'%s'లో లేదà±à°šà±†à°²à±à°²à±à°¬à°¾à°Ÿà± " +"à°…à°¯à±à°¯à±‡ ఎంపికలౠయొకà±à°• " +"జాబితా" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled ఫైలౠనిలà±à°µ చేయడానికి ఇకà±à°•à°¡" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "à°¸à±à°•ీమాసౠఠలోపాలనౠవిసà±à°®à°°à°¿à°‚à°šà±" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "Gschema.compiled ఫైలౠవà±à°°à°¾à°¯à°¡à°‚ లేదà±" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "కీలక పేరౠఆంకà±à°·à°²à± అమలౠలేదà±" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"à°’à°• à°¸à±à°•ీమ కాషె à°…à°¨à±à°¨à°¿ GSettings à°¸à±à°•ీమ ఫైళà±à°²à± కంఫైలà±.\n" +"à°¸à±à°•ీమ ఫైళà±à°²à± పొడిగింపౠకలిగి ఉంటà±à°‚ది. Gschema.xml,\n" +"మరియౠకాషె ఫైలౠgschemas.compiled అని పిలà±à°¸à±à°¤à°¾à°°à±." + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "మీరౠసరిగà±à°—à°¾ à°’à°• డైరెకà±à°Ÿà°°à±€ పేరౠఇవà±à°µà°¾à°²à°¿\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "à° à°¸à±à°•ీమ ఫైళà±à°²à± దొరకలేదà±:" + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "à°à°®à±€ చేయడం.\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "తొలగించబడింది ఉనà±à°¨ à°…à°µà±à°Ÿà±à°ªà±à°Ÿà± ఫైలà±.\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "à°…à°ªà±à°°à°®à±‡à°¯ à°¸à±à°¥à°¾à°¨à°¿à°• మానిటరౠరకమà±à°¨à± à°•à°¨à±à°—ొనలేక పోయింది" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "చెలà±à°²à°¨à°¿ ఫైలà±à°ªà±‡à°°à± %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "దసà±à°¤à±à°°à°µà±à°¯à°µà°¸à±à°¥ సమాచారంనౠకనà±à°—ొనà±à°Ÿà°²à±‹ దోషమౠ: %s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "రూటౠడైరెకà±à°Ÿà°°à±€à°¨à°¿ à°ªà±à°¨à°ƒà°¨à°¾à°®à°•à°°à°£ చేయలేమà±" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°¨à± à°ªà±à°¨à°ƒà°¨à°¾à°®à°•à°°à°£ చేయà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "ఫైలౠపేరౠకాదà±, ఫైలౠపేరౠఇపà±à°ªà°Ÿà°¿à°•ే ఉంది" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "చెలà±à°²à°¨à°¿ దసà±à°¤à±à°°à°¨à°¾à°®à°®à±" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "డెరెకà±à°Ÿà°°à±€à°¨à°¿ తెరà±à°µà°²à±‡à°®à±" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°¨à± తెరà±à°šà±à°Ÿà°²à±‹ దోషమౠ: %s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°¨à± తొలగించà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°¨à± à°Ÿà±à°°à°¾à°·à± చేయà±à°Ÿà°²à±‹ దోషమౠ: %s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "à°Ÿà±à°°à°¾à°·à± డెరెకà±à°Ÿà°°à±€(dir)నౠసృషà±à°Ÿà°¿à°‚చలేక పోయింది %s: %s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "à°Ÿà±à°°à°¾à°·à± కొరకౠపైసà±à°¥à°¾à°¯à°¿ డైరెకà±à°Ÿà°°à±€à°¨à°¿ à°•à°¨à±à°—ొనలేక పోయింది" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "à°Ÿà±à°°à°¾à°·à± డైరెకà±à°Ÿà±€à°¨à°¿ à°•à°¨à±à°—ోనలేక పోయింది లేదా సృషà±à°Ÿà°¿à°‚చలేక పోయింది" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "à°Ÿà±à°°à°¾à°·à°¿à°‚గౠసమాచారపౠదసà±à°¤à±à°°à°®à±à°¨à± సృషà±à°Ÿà°¿à°‚చలేక పోయింది: %s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°¨à± à°Ÿà±à°°à°¾à°·à± చేయలేక పోయింది: %s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "అంతరà±à°—à°¤ దోషమà±" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "డెరెకà±à°Ÿà°°à±€à°¨à°¿ సృషà±à°Ÿà°¿à°‚à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ఫైలà±à°¸à°¿à°¸à±à°Ÿà°®à± సింబాలికౠలింకà±à°²à± మదà±à°¦à°¤à± ఇవà±à°µà°¦à±" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "à°šà°¿à°¹à±à°¨à°°à±‚à°ª లింకà±à°¨à± చేయà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°¨à± à°•à°¦à±à°ªà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "డెరెకà±à°Ÿà°°à±€à°¨à°¿ డెరెకà±à°Ÿà°°à±€à°•à°¿ à°•à°¦à±à°ªà°²à±‡à°®à±" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "à°¬à±à°¯à°¾à°•పౠదసà±à°¤à±à°°à°®à± సృషà±à°Ÿà±€à°•à°°à°£ విఫలమైంది" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "టారà±à°—ెటౠదసà±à°¤à±à°°à°®à±à°¨à± తొలగించà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "మౌంటà±à°¸à±â€ మధà±à°¯ కదలిక మదà±à°¦à°¤à±€à°¯à°¬à°¡à°¦à±" + +#: ../gio/glocalfile.c:2603 +#, c-format +#| msgid "Could not load schemas from %s: %s\n" +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s యొకà±à°• à°¡à°¿à°¸à±à°•ౠవినిమయానà±à°¨à°¿ నిరà±à°£à°¯à°¿à°‚చలేదà±: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "యాటà±à°°à°¿à°¬à±à°¯à±‚టౠవిలà±à°µ తపà±à°ªà°• NULL-కాకూడదà±" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "చెలà±à°²à°¨à°¿ యాటà±à°°à°¿à°¬à±à°¯à±‚టౠరకమౠ(à°¸à±à°Ÿà±à°°à°¿à°‚గౠఊహించినది)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "పొడిగించిన యాటà±à°°à°¿à°¬à±à°¯à±‚టౠచెలà±à°²à°¨à°¿ నామమà±" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "పొడిగించిన యాటà±à°°à°¿à°¬à±à°¯à±‚టౠఅమరà±à°šà±à°Ÿà°²à±‹ దోషమౠ'%s': %s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr " (చెలà±à°²à°¨à°¿ యెనà±à°•ోడింగà±)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "ఫైలౠ'%s' కొరకౠసమాచారంనౠపొందà±à°Ÿà°²à±‹ దోషం: %s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "ఫైలౠవివరణి కొరకౠసమాచారంనౠపొందà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "చెలà±à°²à°¨à°¿ యాటà±à°°à°¿à°¬à±à°¯à±‚టౠరకమౠ(uint32 à°…à°¨à±à°•ోబడినది)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "చెలà±à°²à°¨à°¿ యాటà±à°°à°¿à°¬à±à°¯à±‚టౠరకమౠ(uint64 à°…à°¨à±à°•ోబడినది)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "చెలà±à°²à°¨à°¿ యాటà±à°°à°¿à°¬à±à°¯à±‚టౠరకమౠ(బైటౠసà±à°Ÿà±à°°à°¿à°‚à°—à± à°…à°¨à±à°•ోబడినది)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "సిమà±â€Œà°²à°¿à°‚à°•à±à°² నందౠఅనà±à°®à°¤à±à°²à°¨à± అమరà±à°šà°²à±‡à°¦à±" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "à°…à°¨à±à°®à°¤à±à°²à°¨à± అమరà±à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "యజమానిని అమరà±à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "సిమà±â€Œà°²à°¿à°‚కౠతపà±à°ªà°• NULL-కాకూడదà±" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "సింమà±â€Œà°²à°¿à°‚కౠఅమరà±à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "సింమà±â€Œà°²à°¿à°‚కౠఅమరà±à°šà±à°Ÿà°²à±‹ దోషమà±: దసà±à°¤à±à°°à°®à± సిమà±â€Œà°²à°¿à°‚కౠకాదà±" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "సవరణ లేదా యాకà±à°¸à±†à°¸à± సమయం అమరà±à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux సందరà±à°­à°‚ తపà±à°ªà°• NULL-కాకూడదà±" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux సందరà±à°­à°‚ అమరà±à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "SELinux à°ˆ సిసà±à°Ÿà°®à±â€Œà°ªà±ˆà°¨ చేతనపరచ బడిలేదà±" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "యాటà±à°°à°¿à°¬à±à°¯à±‚à°Ÿà± %sనౠఅమరà±à°šà±à°Ÿ మదà±à°¦à°¤à±€à°¯à±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "దసà±à°¤à±à°°à°®à± à°¨à±à°‚à°¡à°¿ à°šà°¦à±à°µà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°•ౠచూడà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "దసà±à°¤à±à°°à°®à± మూయà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "à°…à°ªà±à°°à°®à±‡à°¯ à°¸à±à°¥à°¾à°¨à°¿à°• దసà±à°¤à±à°°à°ªà± మానిటరౠరకమà±à°¨à± à°•à°¨à±à°—ొనలేక పోయింది" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°•à± à°µà±à°°à°¾à°¯à±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "పాత à°¬à±à°¯à°¾à°•పౠలింకà±à°¨à± తొలగించà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "à°¬à±à°¯à°¾à°•పౠనకలà±à°¨à± సృషà±à°Ÿà°¿à°‚à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "తాతà±à°•ాలిక దసà±à°¤à±à°°à°®à±à°¨à± à°ªà±à°¨à°ƒà°¨à°¾à°®à°•à°°à°£ చేయà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "దసà±à°¤à±à°°à°®à±à°¨à± à°Ÿà±à°°à°‚కేటà±â€Œ చేయà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "దసà±à°¤à±à°°à°®à± '%s'నౠతెరà±à°µà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "లకà±à°·à±à°¯à°ªà± దసà±à°¤à±à°°à°®à± వొక డైరెకà±à°Ÿà°°à±€" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "లకà±à°·à±à°¯à°ªà± దసà±à°¤à±à°°à°®à± వొక సాదారణ దసà±à°¤à±à°°à°®à±à°•ాదà±" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "à°† దసà±à°¤à±à°°à°®à± బహిరà±à°—తమà±à°—à°¾ మారà±à°šà°¬à°¡à°¿à°¨à°¦à°¿" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "పాత దసà±à°¤à±à°°à°®à±à°¨à± తొలగించà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "చెలà±à°²à°¨à°¿ GSeekType పంపిణీచేయబడింది" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "చెలà±à°²à°¨à°¿ యెదà±à°°à±à°šà±‚పౠఅభà±à°¯à°°à±à°§à°¨" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStreamనౠకà±à°¦à°¿à°‚à°š లేమà±" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "మెమోరీ à°…à°µà±à°Ÿà±â€Œà°ªà±à°Ÿà± à°¸à±à°Ÿà±à°°à±€à°®à± à°ªà±à°¨à°ƒà°ªà°°à°¿à°®à°¾à°£à°®à± చేయలేమà±" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "మెమోరీ à°…à°µà±à°Ÿà±â€Œà°ªà±à°Ÿà± à°¸à±à°Ÿà±à°°à±€à°®à±â€Œà°¨à± à°ªà±à°¨à°ƒà°ªà°°à°¿à°®à°¾à°£à°®à± చేయà±à°Ÿà°²à±‹ విఫలమైంది" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"à°µà±à°°à±†à±–à°Ÿà± à°ªà±à°°à°¾à°¸à±†à°¸à± అవసరం మెమరీ పరిమాణానà±à°¨à°¿ à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ కంటే పెదà±à°¦à°¦à°¿à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°¸à±à°¥à°²à°‚" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "కోరà±à°•à±à°‚టారౠఅభà±à°¯à°°à±à°¥à°¿à°‚à°šà°¿à°¨ à°¸à±à°Ÿà±à°°à±€à°®à± à°ªà±à°°à°¾à°°à°‚భంలో à°®à±à°‚à°¦à±" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "à°¸à±à°Ÿà±à°°à±€à°®à± à°®à±à°—ింపౠదాటి కోరà±à°•à±à°‚టారౠఅభà±à°¯à°°à±à°¥à°¿à°‚à°šà°¿à°¨" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "మౌంటౠతెరవండి అమలౠలేదౠ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "మౌంటౠనిషà±à°•à±à°°à°®à°£à°¨à± అభివృదà±à°¦à°¿ చేయà±à°Ÿà°²à±‡à°¦à±" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "à°…à°¨à±â€Œà°®à±Œà°‚టౠలేదా ఆపరేషనà±_తో_à°…à°¨à±â€Œà°®à±Œà°‚à°Ÿà±â€Œà°¨à± మౌంటౠఅభివృదà±à°¦à°¿ పరచలేదà±" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "మౌంటౠబయటకà±à°ªà°‚పౠలేదా ఆపరేషనà±â€Œà°¤à±‹_బయటకà±_పంపà±à°¨à± అభివృదà±à°¦à°¿à°ªà°°à°šà±à°Ÿà°²à±‡à°¦à±" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "మౌంటౠరీమౌంటà±â€Œà°¨à± అభివృదà±à°¦à°¿ చేయà±à°Ÿà°²à±‡à°¦à±" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "సారమౠరకం ఊహింపà±à°¨à± మౌంటౠఅభివృదà±à°¦à°¿à°šà±‡à°¯à±à°Ÿà°²à±‡à°¦à±" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "à°à°•కాల సారమౠరకం ఊహింపà±à°¨à± మౌంటౠఅభివృదà±à°¦à°¿ చేయà±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gnetworkaddress.c:338 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "హోసà±à°Ÿà±à°¨à°¾à°®à°®à± '%s' కలిగివà±à°‚ది '[' but not ']'" + +#: ../gio/gnetworkmonitorbase.c:189 ../gio/gnetworkmonitorbase.c:292 +msgid "Network unreachable" +msgstr "నెటà±à°µà°°à±à°•ౠచేరà±à°•ోవà±à°Ÿà±à°²à±‡à°¦à±" + +#: ../gio/gnetworkmonitorbase.c:227 ../gio/gnetworkmonitorbase.c:257 +msgid "Host unreachable" +msgstr "అతిథేయి చేరà±à°•ోవà±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "నెటà±à°µà°°à±à°•ౠమానిటరౠసృషà±à°Ÿà°¿à°‚చలేక పోయింది: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "నెటà±à°µà°°à±à°•ౠమానిటరౠసృషà±à°Ÿà°¿à°‚చలేక పోయింది:" + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "నెటà±à°µà°°à±à°•à± à°¸à±à°¥à°¿à°¤à°¿à°¨à°¿ పొందలేక పోయింది: " + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:550 +msgid "Output stream doesn't implement write" +msgstr "à°…à°µà±à°Ÿà±â€Œà°ªà±à°Ÿà± à°¸à±à°Ÿà±à°°à±€à°®à± à°µà±à°°à°¾à°¯à±à°Ÿà°¨à± అభివృదà±à°¦à°¿à°šà±‡à°¯à±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/goutputstream.c:511 ../gio/goutputstream.c:1028 +msgid "Source stream is already closed" +msgstr "మూల à°¸à±à°Ÿà±à°°à±€à°®à± యిపà±à°ªà°Ÿà°¿à°•ే మూయబడివà±à°‚ది" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' పరిషà±à°•à°°à°¿à°‚à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "'%s' వదà±à°¦ వనరౠలేదà±" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "'%s' వదà±à°¦ వనరౠడీకంపà±à°°à±†à°¸à± à°…à°—à±à°Ÿà°•ౠవిఫలమైంది" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "'%s' వదà±à°¦à°—à°² వనరౠడైరెకà±à°Ÿà°°à±€ కాదà±" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "ఇనà±â€Œà°ªà±à°Ÿà± à°¸à±à°Ÿà±à°°à±€à°®à± సీకà±â€Œà°¨à± అభివృదà±à°¦à°¿ చేయà±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gresource-tool.c:491 +msgid "List sections containing resources in an elf FILE" +msgstr "జాబితా విభాగాలౠవనరà±à°²à°¨à± elf ఫైలà±à°¨à°‚దౠకలిగివà±à°¨à±à°¨à°¾à°¯à°¿" + +#: ../gio/gresource-tool.c:497 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"వనరà±à°² జాబితా\n" +"విభాగమౠయీయబడితే, à°ˆ విభాగమౠనందలి వనరà±à°²à± మాతà±à°°à°®à±‡ జాబితాచేయి\n" +"పాతౠయీయబడితే, సరిపోలిన వనరà±à°²à°¨à± మాతà±à°°à°®à±‡ జాబితాచేయి" + +#: ../gio/gresource-tool.c:500 ../gio/gresource-tool.c:510 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:501 ../gio/gresource-tool.c:511 +#: ../gio/gresource-tool.c:518 +msgid "SECTION" +msgstr "విభాగమà±" + +#: ../gio/gresource-tool.c:506 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"వనరà±à°²à°¨à± వివరాలతో జాబితాచేయి\n" +"విభాగమౠయీయబడితే, à°ˆ విభాగమౠనందలి వనరà±à°²à°¨à± మాతà±à°°à°®à±‡ జాబితాచేయి\n" +"పాతౠయీయబడితే, సరిపోలిన వనరà±à°²à°¨à± మాతà±à°°à°®à±‡ జాబితాచేయి\n" +"వివరాలౠవిభాగమà±, పరిమాణం మరియౠకంపà±à°°à±†à°·à°¨à± నౠకలిగివà±à°‚à°¡à±à°¨à±" + +#: ../gio/gresource-tool.c:516 +msgid "Extract a resource file to stdout" +msgstr "వనరౠఫైలà±à°¨à± stdout పైనకౠతెమà±à°®à±" + +#: ../gio/gresource-tool.c:517 +msgid "FILE PATH" +msgstr "ఫైలౠపాతà±" + +#: ../gio/gresource-tool.c:531 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"వాడà±à°•:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help à°ˆ సమాచారమà±à°¨à± చూపà±à°®à±\n" +" sections \n" +" list వనరà±à°²à°¨à± జాబితాచేయà±à°¨à±\n" +" details వనరà±à°²à°¨à± వివరమà±à°²à°¤à±‹ జాబితాచేయà±à°¨à±\n" +" extract à°’à°• వనరà±à°¨à± బయటకà±à°¤à±†à°šà±à°šà±à°¨à±\n" +"\n" +"విశదీకృత సహాయం కొరకౠ'gresource help COMMAND' à°µà±à°ªà°¯à±‹à°—à°¿à°‚à°šà±.\n" +"\n" + +#: ../gio/gresource-tool.c:545 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"వాడà±à°•:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:552 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION à°’à°• (à°à°šà±à°šà°¿à°•) elf విభాగం పేరà±\n" + +#: ../gio/gresource-tool.c:556 ../gio/gsettings-tool.c:635 +msgid " COMMAND The (optional) command to explain\n" +msgstr "కమాండౠ(à°à°šà±à°›à°¿à°•) ఆదేశం వివరించటానికి \n" + +#: ../gio/gresource-tool.c:562 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE à°’à°• elf ఫైలౠ(à°’à°• బైనరీ ఫైలౠలేదా భాగసà±à°µà°¾à°®à±à°¯ లైబà±à°°à°°à±€)\n" + +#: ../gio/gresource-tool.c:565 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE à°’à°• elf ఫైలౠ(à°’à°• బైనరీ లేదా భాగసà±à°µà°¾à°®à±à°¯ లైబà±à°°à°°à±€)\n" +" లేదా కంపైలà±à°¡à± వనరౠఫైలà±\n" + +#: ../gio/gresource-tool.c:569 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:571 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH à°’à°• (à°à°šà±à°šà°¿à°•) వనరౠపాతౠ(బహà±à°¶à°¾ పాకà±à°·à°¿à°•)\n" + +#: ../gio/gresource-tool.c:572 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:574 +msgid " PATH A resource path\n" +msgstr " PATH à°’à°• వనరౠపాతà±\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "కాదౠఅలాంటి పథకం '%s' \n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "à°¸à±à°•ీమ '%s' relocatable కాదౠ(మారà±à°—à°‚ పేరà±à°•ొనà±à°¨ ఉండకూడదà±) \n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "à°¸à±à°•ీమ '%s' relocatable (మారà±à°—à°‚ తపà±à°ªà°•) ఉంది\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "ఇచà±à°šà°¿à°¨ ఖాళీ మారà±à°—à°‚.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "పాతౠఒక à°¸à±à°²à°¾à°·à± (/) à°ªà±à°°à°¾à°°à°‚భమవà±à°¤à°¾à°¯à°¿ తపà±à°ªà°•\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "పాతౠఒక à°¸à±à°²à°¾à°·à± (/) తో అంతం చేయాలి\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "పాతౠరెండౠసమీప slashes (/ /) ఉండకూడదà±\n" + +#: ../gio/gsettings-tool.c:477 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "యివà±à°µà°¬à°¡à°¿à°¨ విలà±à°µ చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ పరిధి బయట ఉంది\n" + +#: ../gio/gsettings-tool.c:484 +#, c-format +#| msgid "Key %s is not writable\n" +msgid "The key is not writable\n" +msgstr "à°•à±€ à°µà±à°°à°¾à°¯à°¦à°—ది కాదà±\n" + +#: ../gio/gsettings-tool.c:520 +msgid "List the installed (non-relocatable) schemas" +msgstr "à°µà±à°¯à°µà°¸à±à°¥à°¾à°ªà°¿à°¤ (non-relocatable) à°¸à±à°•ీమాసౠజాబితా" + +#: ../gio/gsettings-tool.c:526 +msgid "List the installed relocatable schemas" +msgstr "ఇనà±à°¸à±à°Ÿà°¾à°²à± relocatable à°¸à±à°•ీమాసౠజాబితా" + +#: ../gio/gsettings-tool.c:532 +msgid "List the keys in SCHEMA" +msgstr "à°¸à±à°•ీమ లో కీలనౠజాబితా" + +#: ../gio/gsettings-tool.c:533 ../gio/gsettings-tool.c:539 +#: ../gio/gsettings-tool.c:576 +msgid "SCHEMA[:PATH]" +msgstr "షెడà±à°¯à±‚లౠ[: PATH]" + +#: ../gio/gsettings-tool.c:538 +msgid "List the children of SCHEMA" +msgstr "à°¸à±à°•ీమ పిలà±à°²à°²à°•ౠజాబితా" + +#: ../gio/gsettings-tool.c:544 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"జాబితా కీలౠమరియౠవిలà±à°µà°²à±, à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚à°—à°¾ \n" +"సంఖà±à°¯ à°¸à±à°•ీమ ఇవà±à°µà°¬à°¡à±à°¤à±à°‚ది ఒకవేళ à°…à°¨à±à°¨à°¿ కీలనౠజాబితా\n" + +#: ../gio/gsettings-tool.c:546 +msgid "[SCHEMA[:PATH]]" +msgstr "[చారà±à°Ÿà± [: PATH]]" + +#: ../gio/gsettings-tool.c:551 +msgid "Get the value of KEY" +msgstr "à°•à±€ విలà±à°µ పొందండి" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:570 ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY" +msgstr "షెడà±à°¯à±‚లౠ[: PATH] KEY" + +#: ../gio/gsettings-tool.c:557 +msgid "Query the range of valid values for KEY" +msgstr "à°•à±€ కోసం చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ విలà±à°µà°²à± పరిధి విచారిసà±à°¤à°¾à°°à±" + +#: ../gio/gsettings-tool.c:563 +msgid "Set the value of KEY to VALUE" +msgstr "VALUE à°•à±€ యొకà±à°• విలà±à°µ అమరà±à°šà±" + +#: ../gio/gsettings-tool.c:564 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "à°¸à±à°•ీమ [: PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:569 +msgid "Reset KEY to its default value" +msgstr "దాని సాధారణ విలà±à°µ à°•à±€ రీసెటà±" + +#: ../gio/gsettings-tool.c:575 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "à°¸à±à°•ీమ వారి లకౠఅనà±à°¨à°¿ కీలనౠరీసెటà±" + +#: ../gio/gsettings-tool.c:581 +msgid "Check if KEY is writable" +msgstr "KEY రైటబà±à°²à± ఉంటే తనిఖీ" + +#: ../gio/gsettings-tool.c:587 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"మారà±à°ªà±à°²à± KEY పరà±à°¯à°µà±‡à°•à±à°·à°¿à°‚చడానికి.\n" +"à° KEY పేరà±à°•ొనà±à°¨ ఉంటే, à°¸à±à°•ీమ à°…à°¨à±à°¨à°¿ కీలనౠమానిటరà±.\n" +"వాడà±à°• ^ సి పరà±à°¯à°µà±‡à°•à±à°·à°£ ఆపడానికి.\n" + +#: ../gio/gsettings-tool.c:590 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:602 +#| msgid "" +#| "Usage:\n" +#| " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +#| "\n" +#| "Commands:\n" +#| " help Show this information\n" +#| " list-schemas List installed schemas\n" +#| " list-relocatable-schemas List relocatable schemas\n" +#| " list-keys List keys in a schema\n" +#| " list-children List children of a schema\n" +#| " list-recursively List keys and values, recursively\n" +#| " range Queries the range of a key\n" +#| " get Get the value of a key\n" +#| " set Set the value of a key\n" +#| " reset Reset the value of a key\n" +#| " reset-recursively Reset all values in a given schema\n" +#| " writable Check if a key is writable\n" +#| " monitor Watch for changes\n" +#| "\n" +#| "Use 'gsettings help COMMAND' to get detailed help.\n" +#| "\n" +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"వాడà±à°•:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"ఆదేశాలà±:\n" +" help à°ˆ సమాచారానà±à°¨à°¿ చూపించà±\n" +" list-schemas సంసà±à°¥à°¾à°ªà°¿à°‚à°šà°¿à°¨ à°¸à±à°•ీమాలనౠజాబితా చేయà±à°¨à±\n" +" list-relocatable-schemas relocatable à°¸à±à°•ీమాసౠజాబితాచేయà±à°¨à±\n" +" list-keys à°¸à±à°•ీమà±à°²à±‹à°¨à°¿ కీలనౠజాబితాచేయà±à°¨à±\n" +" list-children à°¸à±à°•ీమౠచిలà±à°¡à±à°°à°¨à± జాబితాచేయà±à°¨à±\n" +" list-recursively కీలనౠమరియౠవిలà±à°µà°¨à± జాబితాచేయà±à°¨à±, à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚à°—à°¾\n" +" range à°•à±€ విసà±à°¤à±ƒà°¤à°¿à°¨à°¿ à°ªà±à°°à°¶à±à°¨à°¿à°‚à°šà±à°¨à±\n" +" get à°•à±€ యొకà±à°• విలà±à°µà°¨à± పొందà±à°¨à±\n" +" set à°•à±€ విలà±à°µà°¨à± à°µà±à°‚à°šà±à°¨à±\n" +" reset à°•à±€ విలà±à°µà°¨à± తిరిగివà±à°‚à°šà±à°¨à±\n" +" reset-recursively ఇచà±à°šà°¿à°¨ à°¸à±à°•ీమా నందలి à°…à°¨à±à°¨à°¿ విలà±à°µà°²à°¨à± తిరిగివà±à°‚à°šà±à°¨à±\n" +" writable à°•à±€ à°µà±à°°à°¾à°¯à°¦à°—à±à°¨à°¦à°¾ లేదా అనేది పరిశీలించà±à°¨à±\n" +" monitor మారà±à°ªà±à°²à°¨à± పరà±à°¯à°µà±‡à°•à±à°·à°¿à°‚à°šà±à°¨à±\n" +"\n" +"విశదీకృత సహాయం కొరకౠ'gsettings help COMMAND' à°µà±à°ªà°¯à±‹à°—à°¿à°‚à°šà±.\n" +"\n" + +#: ../gio/gsettings-tool.c:625 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"వాడà±à°•:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:631 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR అదనపౠసà±à°•ీమాలనౠఅనà±à°µà±‡à°·à°¿à°‚à°šà±à°Ÿà°•ౠవొక డైరకà±à°Ÿà°°à±€\n" + +#: ../gio/gsettings-tool.c:639 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" à°¸à±à°•ీమ యొకà±à°• పథకం పేరà±\n" +" PATH మారà±à°—à°‚, relocatable à°¸à±à°•ీమాసౠకోసం \n" + +#: ../gio/gsettings-tool.c:644 +msgid " KEY The (optional) key within the schema\n" +msgstr "à°¸à±à°•ీమ లోపల à°•à±€ (ఆపà±à°·à°¨à°²à±) కీలక \n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The key within the schema\n" +msgstr "à°¸à±à°•ీమ లోపల KEY కీలక \n" + +#: ../gio/gsettings-tool.c:652 +msgid " VALUE The value to set\n" +msgstr "అమరà±à°šà°µà°²à°¸à°¿à°¨ విలà±à°µ VALUE\n" + +#: ../gio/gsettings-tool.c:707 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s à°¨à±à°‚à°¡à°¿ à°¸à±à°•ీమాలనౠలోడౠచేయలేదà±: %s\n" + +#: ../gio/gsettings-tool.c:769 +#, c-format +msgid "Empty schema name given\n" +msgstr "ఖాళీ à°¸à±à°•ీమ పేరౠఇవà±à°µà°¬à°¡à°¿à°‚ది \n" + +#: ../gio/gsettings-tool.c:798 +#, c-format +msgid "No such key '%s'\n" +msgstr "'%s' వంటి à°•à±€ లేదà±\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "చెలà±à°²à°¨à°¿ సాకెటà±, సిదà±à°¦à°ªà°°à°šà°²à±‡à°¦à±" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "చెలà±à°²à°¨à°¿ సాకెటà±, దీని కారణంగా సదà±à°¦à±€à°•à°°à°£ విఫలమైంది: %s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "సాకెటౠయిపà±à°ªà°Ÿà°¿à°•ే మూయబడింది" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "సాకెటౠI / O సమయం à°®à±à°—ిసింది" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd à°¨à±à°‚à°¡à°¿ GSocket సృషà±à°Ÿà°¿à°¸à±à°¤à±‹à°‚ది: %s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "సాకెటà±â€Œà°¨à± సృషà±à°Ÿà°¿à°‚చలేక పోయింది: %s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "అపరిచిత à°•à±à°Ÿà±à°‚బం తెలà±à°ªà°¬à°¡à°¿à°‚ది" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "తెలియని à°ªà±à°°à±‹à°Ÿà±‹à°•ాలౠతెలà±à°ªà°¬à°¡à°¿à°‚ది" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "à°¸à±à°¥à°¾à°¨à°¿à°• à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à± పొందలేక పోయింది: %s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "దూరసà±à°¥ à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à± పొందలేక పోయింది: %s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "%s వినలేక పోయింది" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾à°•ౠబందనం à°…à°—à±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "మలà±à°Ÿà±€à°•ాసà±à°Ÿà± సమూహంకౠజేరà±à°Ÿà°²à±‹ దోషం: %s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "మలà±à°Ÿà±€à°•ాసà±à°Ÿà± సమూహంకౠవదà±à°²à±à°Ÿà°²à±‹ దోషం: %s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "వనరà±-à°ªà±à°°à°¤à±à°¯à±‡à°• మలà±à°Ÿà±€à°•ాసà±à°Ÿà± కొరకౠతోడà±à°ªà°¾à°Ÿà±à°²à±‡à°¦à±" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "à°…à°¨à±à°¸à°‚ధానమà±à°¨à± ఆమోదించà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "à°…à°¨à±à°¸à°‚ధానమౠపà±à°°à±‹à°—తిలోవà±à°‚ది" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "వాయిదావà±à°¨à±à°¨ దోషమà±à°¨à± పొందలేక పోయింది:" + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "డాటా à°¸à±à°µà±€à°•à°°à°¿à°‚à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "డాటా పంపà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "మూసివేతనౠకరంటౠపà±à°²à°—à±à°—ౠపెటà±à°Ÿà±‡ చోటౠసాధà±à°¯à°‚ కాదà±:%s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "సాకెటౠమూయà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "సాకెటౠపరిసà±à°¥à°¿à°¤à°¿ కోరకౠవేచివà±à°‚ది: %s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "సందేశమà±à°¨à± పంపà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "విండోసౠనందౠGSocketControlMessage తోడà±à°ªà°¾à°Ÿà±à°²à±‡à°¦à±" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "సందేశమà±à°¨à± à°¸à±à°µà±€à°•à°°à°¿à°‚à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gsocket.c:4516 +#, c-format +#| msgid "Unable to create socket: %s" +msgid "Unable to read socket credentials: %s" +msgstr "సాకెటà±â€Œà°¨à± à°•à±à°°à±†à°¡à±†à°¨à±à°·à°¿à°¯à°²à±à°¸à± à°šà°¦à±à°µà°²à±‡à°• పోయింది: %s" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g(_s)తోరà±à°°_get_credentials à°ˆ OS కోసం అమలౠకాలేదà±" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "à°ªà±à°°à±‹à°•à±à°¸à±€ సేవిక %sà°•à± à°…à°¨à±à°¸à°‚ధానం కాలేకపోయింది: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s à°•à± à°…à°¨à±à°¸à°‚ధానం కాలేక పోయింది: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "à°…à°¨à±à°¸à°‚ధానం కాలేక పోయింది: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1603 +msgid "Unknown error on connect" +msgstr "à°…à°¨à±à°¸à°‚ధానమà±à°¨à°‚దౠతెలియని దోషమà±" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1538 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "TCP-కాని à°…à°¨à±à°¸à°‚ధానంలో à°ªà±à°°à±‹à°•à±à°¸à±€à°¯à°¿à°‚గౠతోడà±à°ªà°¾à°Ÿà±à°²à±‡à°¦à±." + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1559 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "à°ªà±à°°à°¾à°•à±à°¸à±€ à°ªà±à°°à±‹à°Ÿà±‹à°•ాలౠ'%s' మదà±à°¦à°¤à± లేదà±." + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "లిజనరౠయిపà±à°ªà°Ÿà°¿à°•ే మూసివేయబడింది" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "జతచేసిన సాకెటౠమూయబడింది" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 IPv6 à°šà°¿à°°à±à°¨à°¾à°®à°¾ '%s' మదà±à°¦à°¤à± ఇవà±à°µà°¦à±" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "SOCKSv4 నిబందన కొరకౠవాడà±à°•రిపేరౠమరీ పొడవà±à°—à°¾ à°µà±à°‚ది" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "అతిథేయిపేరౠ'%s' à°…à°¨à±à°¨à°¦à°¿ SOCKSv4 నిబందనకౠమరీ పొడవà±à°—à°¾ à°µà±à°‚ది" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "సేవిక à°’à°• SOCKSv4 à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à± కాదà±." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 సరà±à°µà°°à± à°¦à±à°µà°¾à°°à°¾ à°…à°¨à±à°¸à°‚ధానమౠతిరసà±à°•రించబడింది" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "సేవిక à°’à°• SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à± కాదà±." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ à°ªà±à°°à°®à°¾à°£à±€à°•à°°à°£ అవసరం." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ à°¦à±à°µà°¾à°°à°¾ మదà±à°¦à°¤à± లేని à°’à°• à°ªà±à°°à°¾à°®à°¾à°£à°¿à°• పదà±à°§à°¤à°¿à°¨à°¿ అవసరంGlib." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "SOCKSv5 నిబందనకౠవాడà±à°•రిపేరౠలేదా సంకేతపదం మరీ పొడవà±à°—à°¾ à°µà±à°‚ది." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 à°ªà±à°°à°®à°¾à°£à±€à°•à°°à°£ వరà±à°¡à± కారణంగా విఫలమైంది" + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "అతిథేయిపేరౠ'%s' à°…à°¨à±à°¨à°¦à°¿ SOCKSv5 నిబందనకౠమరీ పొడవà±à°—à°¾ à°µà±à°‚ది" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à± తెలియని à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°°à°•à°‚ ఉపయోగిసà±à°¤à±à°‚ది." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "అంతరà±à°—à°¤ SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à± లోపం." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Ruleset à°¦à±à°µà°¾à°°à°¾ SOCKSv5 à°…à°¨à±à°¸à°‚ధానమౠఅనà±à°®à°¤à°¿ లేదà±." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 సరà±à°µà°°à± à°¦à±à°µà°¾à°°à°¾ à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేదౠహోసà±à°Ÿà± చేయండి." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ à°¦à±à°µà°¾à°°à°¾ వరà±à°•à± à°…à°‚à°¦à±à°¬à°¾à°Ÿà± లేదà±." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "à°…à°¨à±à°¸à°‚ధానమౠSOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ à°¦à±à°µà°¾à°°à°¾ నిరాకరించారà±." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ 'à°…à°¨à±à°¸à°‚ధానిసà±à°¤à°¾à°¯à°¿' ఆదేశానà±à°¨à°¿ మదà±à°¦à°¤à± ఇవà±à°µà°¦à±." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°°à°•à°‚ అందించిన మదà±à°¦à°¤à± ఇవà±à°µà°¦à±." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "తెలియని SOCKSv5 à°ªà±à°°à°¾à°•à±à°¸à±€ లోపం." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon à°Žà°¨à±à°•ోడింగà±à°¯à±Šà°•à±à°• వరà±à°·à°¨à± %dనౠసంభాలించలేదà±" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "చెలà±à°²à±‡ à°šà°¿à°°à±à°¨à°¾à°®à°¾ కనబడలేదà±" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "à°µà±à°¯à°¤à°¿à°°à±‡à°•-పరిషà±à°•ారమà±à°²à±‹ దోషమౠ'%s': %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "'%s' కోసం à°…à°­à±à°¯à°°à±à°§à°¨ à°°à°•à°‚ సంఖà±à°¯ DNS రికారà±à°¡à± " + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "తాతà±à°•ాలికంగా '%s' పరిషà±à°•రించలేదà±" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "%s పరిషà±à°•à°°à°¿à°‚à°šà±à°Ÿà°²à±‹ దోషమà±" + +#: ../gio/gtlscertificate.c:247 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-encoded à°µà±à°¯à°•à±à°¤à°¿à°—à°¤ కీనౠడీకà±à°°à°¿à°ªà±à°Ÿà± చేయలేదà±" + +#: ../gio/gtlscertificate.c:252 +msgid "No PEM-encoded private key found" +msgstr "à°à°µà±€ దొరకలేదౠpem-కోడౠఅయిన à°ªà±à°°à±†à±–వేటౠకీ" + +#: ../gio/gtlscertificate.c:262 +msgid "Could not parse PEM-encoded private key" +msgstr "Pem-కోడౠఅయిన à°ªà±à°°à±†à±–వేటౠకీ à°…à°¨à±à°µà°¯à°¿à°‚à°šà°¡à°‚ సాధà±à°¯à°‚ కాదà±" + +#: ../gio/gtlscertificate.c:287 +msgid "No PEM-encoded certificate found" +msgstr "à°à°µà±€ దొరకలేదౠpem-కోడౠఅయిన సరà±à°Ÿà°¿à°«à°¿à°•ేటà±" + +#: ../gio/gtlscertificate.c:296 +msgid "Could not parse PEM-encoded certificate" +msgstr "Pem-కోడౠఅయిన సరà±à°Ÿà°¿à°«à°¿à°•ేటౠఅనà±à°µà°¯à°¿à°‚à°šà°¡à°‚ సాధà±à°¯à°‚ కాదà±" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"à°ˆ మీ ఆకà±à°¸à±†à°¸à± à°®à±à°‚దౠసరిగà±à°—à°¾ పాసà±à°µà°°à±à°¡à±à°¨à± ఎంటరౠచివరి అవకాశం ఉందిలాకౠ" +"చేయబడà±à°¤à±à°‚ది." + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"ఎంటరౠఅనేక వరà±à°¡à± ఉనà±à°¨à°¾à°¯à°¿, మరియౠమీ ఆకà±à°¸à±†à°¸à± లాకౠచేయబడà±à°¤à±à°‚దిమరింత వైఫలà±à°¯à°¾à°²à± " +"తరà±à°µà°¾à°¤ బయటకà±." + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "నమోదౠచేసిన పాసౠవరà±à°¡à± సరియైనది కాదà±." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "1 నింయంతà±à°°à°£ సందేశమౠఅనà±à°•ొంది, %d పొందింది" +msgstr[1] "1 నింయంతà±à°°à°£ సందేశమౠఅనà±à°•ొంది, %d పొందింది" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "ఊహించని యానà±à°¸à°¿à°²à±à°²à°°à°¿ డాటా à°°à°•à°®à±" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "à°’à°• fd ఊహించినది, అయితే %d పొందింది\n" +msgstr[1] "à°’à°• fd ఊహించినది, అయితే %d పొందింది\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "చెలà±à°²à°¨à°¿ fd à°¸à±à°µà±€à°•రించినది" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "ఆధారాలనౠపంపడంలో లోపం:" + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" +" SO(_P) పాసà±à°•à±à°°à±†à°¡à± ఉంటే తనిఖీ చేసేటపà±à°ªà±à°¡à± లోపం సాకెటౠ%s: కోసం ఉపయోగించ బడింది" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "లోపం ఎనేబà±à°²à± SO_PASSCRED:%s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"ఆధారాలనౠఅందà±à°•ోవటానికి ఒకే బైటౠచదà±à°µà± కానీ à°¸à±à°¨à±à°¨à°¾ బైటà±à°²à± చదవడానికి " +"à°Žà°•à±à°¸à±à°ªà±†à°•à±à°Ÿà°¿à°‚à°—à±" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "నియంతà±à°°à°£ సందేశం వసà±à°¤à±à°‚దని వాళà±à°³à°•à±, కానీ%d సంపాదించà±à°•à±à°¨à±à°¨à°¾à°°à±" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED నిలిపివేసిన లోపం అయితే:%s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ఫైలౠవివరిణి à°¨à±à°‚à°¡à°¿ à°šà°¦à±à°µà±à°Ÿà°²à±‹ దోషం: %s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ఫైలౠవివరిణిని మూయà±à°Ÿà°²à±‹ దోషం: %s" + +#: ../gio/gunixmounts.c:2054 ../gio/gunixmounts.c:2107 +msgid "Filesystem root" +msgstr "దసà±à°¤à±à°°à°µà±à°¯à°µà°¸à±à°¥ రూటà±" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ఫైలౠవివరిణికి à°µà±à°°à°¾à°¯à±à°Ÿà°²à±‹ దోషం: %s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"ఆబà±â€Œà°¸à±à°Ÿà±à°°à°¾à°•à±à°Ÿà± à°¯à±à°¨à°¿à°•à±à°¸à± డొమైనౠసాకెటౠచిరà±à°¨à°¾à°®à°¾à°²à°•à± à°ˆ సిసà±à°Ÿà°®à± నందౠతోడà±à°ªà°¾à°Ÿà±à°²à±‡à°¦à±" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "వాలà±à°¯à±‚మౠనిషà±à°•à±à°°à°®à°£à°¿à°¨à°¿ అభివృదà±à°¦à°¿ చేయలేదà±" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" +"బయటకà±à°ªà°‚పౠలేదా ఆపరేషనà±_తో_బయటకà±à°ªà°‚పౠఅనà±à°¦à°¾à°¨à°¿à°¨à°¿ వాలà±à°¯à±‚మౠఅభివృదà±à°¦à°¿ పరచà±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨à°®à±à°¨à± à°•à°¨à±à°—ొన లేదà±" + +#: ../gio/gwin32appinfo.c:306 +#, c-format +msgid "Error launching application: %s" +msgstr "à°…à°¨à±à°µà°°à±à°¤à°¨à°‚నౠఆరంభించà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gwin32appinfo.c:342 +msgid "URIs not supported" +msgstr "URIలౠమదà±à°¦à°¤à±€à°¯à±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gwin32appinfo.c:364 +msgid "association changes not supported on win32" +msgstr "win32 నందౠసహసంభంద మారà±à°ªà±à°²à± మదà±à°¦à°¤à±€à°¯à±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gwin32appinfo.c:376 +msgid "Association creation not supported on win32" +msgstr "win32 నందౠసహసంభంద సృషà±à°Ÿà±€à°•à°°à°£ మదà±à°¦à°¤à±€à°¯à±à°Ÿà°²à±‡à°¦à±" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "%s: à°…à°¦à±à°ªà± చేయగ వచà±à°šà°¿à°¨ చదవడంలో లోపం" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "à°¹à±à°¯à°¾à°‚డిలౠమూయà±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "à°¹à±à°¯à°¾à°‚డిలౠవà±à°°à°¾à°¯à±à°Ÿà°²à±‹ దోషమà±: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "మెమోరీ అయిపోయింది" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "అంతరà±à°—à°¤ దోషమà±: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "మరింత ఇనà±à°ªà±à°Ÿà± అవసరం" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "చెలà±à°²à°¨à°¿ à°•à±à°¦à°¿à°‚చబడిన డేటా" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ లో వినండి " + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "GTestDbus తో à°…à°¨à±à°¸à°‚ధానం కోసం, నిరà±à°²à°•à±à°·à±à°¯à°‚" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°®à±à°¦à±à°°à°¿à°‚à°šà± " + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "షెలౠరీతిలో à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°®à±à°¦à±à°°à°¿à°‚à°šà± " + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "à°’à°• dbus సేవనౠనడà±à°ªà±à°®à±" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "తపà±à°ªà± args\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "మూలకం '%2$s'à°•à± à°…à°¨à±à°•ోని యాటà±à°°à°¿à°¬à±à°¯à±‚à°Ÿà± '%1$s'" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "మూలకం '%2$s'యొకà±à°• యాటà±à°°à°¿à°¬à±à°¯à±‚à°Ÿà± '%1$s' కనబడలేదà±" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "à°…à°¨à±à°•ోని టాగౠ'%s', à°…à°¨à±à°•à±à°¨à±à°¨ టాగౠ'%s'" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "à°…à°¨à±à°•ోని టాగౠ'%s' దీని లోపల '%s'" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "డాటా dirsనందౠయెటà±à°µà°‚à°Ÿà°¿ విలà±à°µà±ˆà°¨ à°ªà±à°¸à±à°¤à°•à°—à±à°°à±à°¤à± దసà±à°¤à±à°°à°®à± కనబడలేదà±" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI '%s'కౠయిపà±à°ªà°Ÿà°¿à°•ే à°’à°• à°ªà±à°¸à±à°¤à°•à°—à±à°°à±à°¤à± à°µà±à°‚ది" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI '%s'కొరకౠయెటà±à°µà°‚à°Ÿà°¿ à°ªà±à°¸à±à°¤à°•à°—à±à°°à±à°¤à± కనబడలేదà±" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI '%s'కొరకౠపà±à°¸à±à°¤à°•à°—à±à°°à±à°¤à±à°¨à°‚దౠయెటà±à°µà°‚à°Ÿà°¿ MIME రకమౠనిరà±à°µà°šà°¿à°‚చలేదà±" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI '%s'కొరకౠపà±à°¸à±à°¤à±à°•à°—à±à°°à±à°¤à±à°¨à°‚దౠయెటà±à°µà°‚à°Ÿà°¿ à°µà±à°¯à°•à±à°¤à°¿à°—à°¤ జెండా నిరà±à°µà°šà°¿à°‚చలేదà±" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI '%s'కొరకౠపà±à°¸à±à°¤à°•à°—à±à°°à±à°¤à±à°¨à°‚దౠయెటà±à°µà°‚à°Ÿà°¿ సమూహమà±à°²à± అమరà±à°šà°²à±‡à°¦à±" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "à°Žà°Ÿà±à°µà°‚à°Ÿà°¿ à°…à°¨à±à°µà°°à±à°¤à°¨à°®à± '%s' నామమà±à°¤à±‹ à°ªà±à°¸à±à°¤à°•à°—à±à°°à±à°¤à±à°¨à± '%s'కొరకౠనమోదà±à°šà±‡à°¯à°²à±‡à°¦à±" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "exec వరà±à°¸ '%s'నౠURI '%s'తో పొడిగించà±à°Ÿà°•ౠవిఫలమైంది" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "చివరి à°Žà°—à±à°¬à°¡à°¿ నందౠపాకà±à°·à°¿à°•à°®à±à°—à°¾ à°…à°•à±à°·à°° à°•à±à°°à°®à°®à± కలదà±." + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "ఫాలౠబà±à°¯à°¾à°•à± '%s' నౠ'%s'" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "\"ఫైలà±\" యోచననౠఉపయోగించిన à°¯à±à°†à°°à±à° '%s' సంపూరà±à°£à°®à±ˆà°¨ à°¯à±à°†à°°à±à° కాదà±" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "à°¸à±à°¥à°¾à°¨à°¿à°• à°¯à±à°†à°°à±à° '%s' '#' నౠకలà±à°ªà±à°•ొనియండలెదౠ" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr " '%s' à°¯à±à°†à°°à±à° నిసà±à°¸à°¾à°°à°®à±" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "ఆతిథà±à°¯ నామం యొకà±à°• à°¯à±à°†à°°à±à° '%s' నిసà±à°¸à°¾à°°à°®à±" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "à°¯à±à°†à°°à±à° '%s' నిసà±à°¸à°¾à°°à°®à±ˆà°¨ à°Žà°¸à±à°•ేపౠఅకà±à°·à°°à°¾à°²à± కలిగియà±à°¨à±à°¨à°¾à°¯à°¿." + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr " '%s' à°¤à±à°°à±‹à°µ నామం సరిà°à°¨à°¦à°¿ కాదà±." + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "నిసà±à°¸à°¾à°°à°®à±ˆà°¨ ఆతిథà±à°¯ నామమà±" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "à°‰." + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "సా." + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %b %e %H:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "జనవరి" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "à°«à°¿à°¬à±à°°à°µà°°à°¿" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "మారà±à°šà°¿" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "à°à°ªà±à°°à°¿à°²à±" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "మే" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "జూనà±" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "జూలై" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "ఆగషà±à°Ÿà±" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "సెపà±à°Ÿà±†à°‚బరà±" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "à°…à°•à±à°Ÿà±‹à°¬à°°à±" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "నవంబరà±" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "డిసెంబరà±" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "జనవరి" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "à°«à°¿à°¬à±à°°à°µà°°à°¿" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "మారà±à°šà°¿" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "à°à°ªà±à°°à°¿à°²à±" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "మే" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "జూనà±" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "జూలై" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ఆగషà±à°Ÿà±" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "సెపà±à°Ÿà±†à°‚బరà±" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "à°…à°•à±à°Ÿà±‹à°¬à°°à±" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "నవంబరà±" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "డిసెంబరà±" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "సోమవారం" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "మంగళవారం" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "à°¬à±à°§à°µà°¾à°°à°‚" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "à°—à±à°°à±à°µà°¾à°°à°‚" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "à°¶à±à°•à±à°°à°µà°¾à°°à°‚" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "శనివారం" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "ఆదివారం" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "సోమ" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "మంగళ" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "à°¬à±à°§" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "à°—à±à°°à±" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "à°¶à±à°•à±à°°" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "శని" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ఆది" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr " వివరణ తెరచà±à°Ÿà°²à±‹ దోషం '%s': %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "%lu బైటà±à°¨à°¿ ఫైలౠ\"%s\" à°šà°¦à±à°µà±à°Ÿà°•ౠఇవà±à°µà°²à±‡à°®à±" +msgstr[1] "%lu బైటà±à°²à°¨à°¿ ఫైలౠ\"%s\" à°šà°¦à±à°µà±à°Ÿà°•ౠఇవà±à°µà°²à±‡à°®à±" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "ఫైలౠ'%s': %s à°šà°¦à±à°µà±à°Ÿà°²à±‹ దోషం" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "దసà±à°¤à±à°°à°®à± \"%s\" చాలా పెదà±à°¦à°¦à°¿" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr " ఫైలౠ'%s': %s à°¨à±à°‚à°¡à°¿ à°šà°¦à±à°µà±à°Ÿà°²à±‹ విఫలమైనారà±" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr " ఫైలౠ'%s': %s తెరà±à°šà±à°Ÿà°²à±‹ విఫలమైనారà±" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "దసà±à°¤à±à°° ఆపాదనలౠవిఫలమగà±à°¨à± '%s': à°Žà°«à± à°¸à±à°Ÿà°¾à°Ÿà±() విఫలమైనది: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "ఫైలౠ'%s' తెరà±à°šà±à°Ÿà°²à±‹ విఫలమైనారà±: ఎఫౠడిఓపనà±() విఫలమైనది: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"దసà±à°¤à±à°°à°®à±à°¨à± '%s'à°¨à±à°‚à°¡à°¿ '%s'à°•à± à°ªà±à°¨à°ƒà°¨à°¾à°®à°•à°°à°£ చేయà±à°Ÿà°²à±‹ విఫలమైంది: g_rename() " +"విఫలమైంది: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr " '%s' దసà±à°¤à±à°°à°®à±à°¨à± సృషà±à°Ÿà°¿à°‚à°šà±à°Ÿà°²à±‹ విఫలమయినావà±. :%s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "ఫైలౠ'%s'à°•à± à°µà±à°°à°¾à°¯à°Ÿà°²à±‹ విఫలమైంది: write() విఫలమైంది: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "దసà±à°¤à±à°°à°®à± '%s'à°•à± à°µà±à°°à°¾à°¯à°Ÿà°²à±‹ విఫలమైంది: fsync() విఫలమైంది:%s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "ఉనà±à°¨ దసà±à°¤à±à°°à°®à± '%s' తొలగించబడ లేకపోయింది: g_unlink() విఫలమైంది: %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr " '%s' మాదిరి, '%s' కలిగియà±à°‚డలెదà±. " + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "మాదిరి '%s' XXXXXX కలిగిలేదà±" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr " '%s' à°šà°¿à°¹à±à°¨ పూరితజోడి à°šà°¦à±à°µà±à°Ÿà°²à±‹ విఫలమయినావౠ: %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "à°šà°¿à°¹à±à°¨ పూరితజోడి సహకరించలెదà±. " + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "à°•à°¨à±à°µà°°à±à°Ÿà°°à±â€Œà°¨à± '%s' à°¨à±à°‚à°¡à°¿ '%s'కౠతెరà±à°µà°²à±‡à°•పోయింది: %s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr " జి_à°à°“_ఛానెలà±_రీడà±_లైనà±_à°¸à±à°°à±à°Ÿà°¿à°‚à°—à± à°®à±à°¡à°¿ à°šà°¦à±à°µà± సాధà±à°¯à°ªà°¡à°¦à± " + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr " మిగిలిన దతà±à°¤à°¾à°‚à°¶à°®à±à°¨à± రీడౠబఫరౠలో పరివరà±à°¤à°¿à°‚చలెమౠ" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr " పూరà±à°¤à°¿à°•ాని à°…à°•à±à°·à°°à°¾à°¨à±à°¨à°¿ à°ªà±à°°à°¸à°¾à°° మారà±à°—à°‚ à°®à±à°—à°¿à°‚à°šà±à°¨à±. " + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "జి_à°à°“_ఛానెలà±_రీడà±_లైనà±_à°Žà°‚à°¡à± à°®à±à°¡à°¿ à°šà°¦à±à°µà± సాధà±à°¯à°ªà°¡à°¦à±" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "శోధన dirsనందౠవిలà±à°µà±ˆà°¨ à°•à±€ దసà±à°¤à±à°°à°®à± కనబడలేదà±" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "à°•à±à°°à°®à°¬à°¦à±à°¦à°®à±ˆà°¨ ఫైలౠకాదà±" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"à°à°¦à±ˆà°¤à±‡ మీట-విలà±à°µà°²à± , à°—à±à°°à±‚పౠ,లేక à°µà±à°¯à°¾à°–à±à°¯ కాదో అది మీట ఫైలà±à°²à±‹ లైనౠ'%s' " +"కలిగియà±à°¨à±à°¨à°¦à°¿" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "చెలà±à°²à°¨à°¿ à°—à±à°°à±‚పౠనామమౠ: %s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr " మీట ఫైలౠసమà±à°¦à°¾à°¯à°‚తో à°ªà±à°°à°¾à°°à°‚భమవలెదà±. " + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "చెలà±à°²à°¨à°¿ à°•à±€ నామమౠ:%s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr " మీట ఫైలౠకలిగియà±à°¨à±à°¨ సంకేతరచన '%s' సహకరించదౠ" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1692 ../glib/gkeyfile.c:3072 +#: ../glib/gkeyfile.c:3138 ../glib/gkeyfile.c:3264 ../glib/gkeyfile.c:3397 +#: ../glib/gkeyfile.c:3539 ../glib/gkeyfile.c:3768 ../glib/gkeyfile.c:3835 +#, c-format +msgid "Key file does not have group '%s'" +msgstr " మీట ఫైలౠసమà±à°¦à°¾à°¯à°‚ '%s' నౠకలిగియà±à°‚డలేదౠ" + +#: ../glib/gkeyfile.c:1704 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "మీట ఫైలౠ'%s' తాళంనౠకలిగియà±à°‚డలేదà±. " + +#: ../glib/gkeyfile.c:1811 ../glib/gkeyfile.c:1927 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "'%s' మీట ఫైలౠయొకà±à°• మీటనౠకలిగియà±à°¨à±à°¨à°¦à°¿,దాని విలà±à°µ '%s' à°¯à±à°Ÿà°¿à°«à±-8 " + +#: ../glib/gkeyfile.c:1831 ../glib/gkeyfile.c:1947 ../glib/gkeyfile.c:2316 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"à°•à±€ దసà±à°¤à±à°°à°®à± ఇంటరà±â€Œà°ªà±à°°à±€à°Ÿà± కాలేనటà±à°µà°‚à°Ÿà°¿ విలà±à°µà°¨à± కలిగివà±à°¨à±à°¨ à°•à±€ '%s'నౠకలిగివà±à°‚ది." + +#: ../glib/gkeyfile.c:2533 ../glib/gkeyfile.c:2901 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"'%s' కీనౠ'%s' సమూహం నందౠకలిగివà±à°¨à±à°¨ కీఫైలౠయింటరà±â€Œà°ªà±à°°à±†à°Ÿà± చేయలేని విలà±à°µà°¨à± " +"కలిగివà±à°‚ది." + +#: ../glib/gkeyfile.c:2611 ../glib/gkeyfile.c:2688 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "à°•à±€ '%s' సమూహం '%s' నందౠ'%s' విలà±à°µà°¨à± కలిగివà±à°‚ది కాని %s కావాలి" + +#: ../glib/gkeyfile.c:3087 ../glib/gkeyfile.c:3279 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "'%s' మీట ఫైలౠయొకà±à°• మీట నౠగà±à°°à±‚పౠ'%s' లో కలిగియà±à°‚డలేదౠ" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr " మీట ఫైలౠగీత చివర à°Žà°¸à±à°ªà±‡à°ªà± à°…à°•à±à°·à°°à°®à± కలదà±" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr " '%s' మీట ఫైలౠనిసà±à°¸à°¾à°°à°®à±ˆà°¨ à°Žà°¸à±à°ªà±‡à°ªà± వరà±à°¸ కలదౠ" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "'%s' విలà±à°µà°¨à± సంఖà±à°¯ à°—à°¾ à°šà°¦à±à°µà±à°Ÿà°•ౠసాధà±à°¯à°ªà°¡à°¦à±." + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "పూరà±à°£à°¾à°‚à°•à°‚ విలà±à°µ '%s' విసà±à°°à±ƒà°¤à°¿à°²à±‹ లేదà±" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "'%s' విలà±à°µà°¨à± à°«à±à°²à±‹à°Ÿà± సంఖà±à°¯à°—à°¾ à°šà°¦à±à°µà±à°Ÿà°•ౠసాధà±à°¯à°ªà°¡à°¦à±." + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "%s' విలà±à°µà°¨à± à°¬à±à°²à°¿à°¯à°¨à± à°—à°¾ à°šà°¦à±à°µà±à°Ÿà°•ౠసాధà±à°¯à°ªà°¡à°¦à±." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "" +"'%s%s%s%s' ఫైలౠయొకà±à°• యాటà±à°°à°¿à°¬à±à°¯à±‚à°Ÿà±à°²à°¨à± పొందà±à°Ÿà°²à±‹ విఫలమైంది: fstat() విఫలమైంది: %" +"s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s కౠమాపౠఅగà±à°Ÿà°²à±‹ విఫలమైంది: mmap() విఫలమైంది: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "దసà±à°¤à±à°°à°®à± '%s'నౠతెరà±à°µà±à°Ÿà°²à±‹ విఫలమైంది: open() విఫలమైంది: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "వరà±à°¸ %d à°…à°•à±à°·à°°à°®à± %d పై దోషమà±: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "నామమà±à°¨à°‚దౠచెలà±à°²à°¨à°¿ UTF-8 à°Žà°¨à±à°•ోడెడౠపాఠà±à°¯à°®à± - చెలà±à°²à°¨à°¿à°¦à°¿ '%s'" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' చెలà±à°²à±à°¨à°Ÿà±à°µà°‚à°Ÿà°¿ పేరౠకాదౠ" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' చెలà±à°²à±à°¨à°Ÿà±à°µà°‚à°Ÿà°¿ పేరౠకాదà±: '%c'" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d వరà±à°¸à°²à±‹ దోషం కలదౠ: %s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"à°…à°•à±à°·à°°à°®à±à°²à±‹ అంకె కలిగియà±à°¨à±à°¨à°‚à°¦à±à°µà°²à°¨ '%-.*s', పారà±à°¸à°¿à°‚గౠవిఫలమైనది.దాదాపà±à°—à°¾ à°…à°‚à°•à±à°¯ " +"భారీగా ఉనà±à°¨à°¦à°¿ -నివేదన " +"(ఉదాహరణకౠ: ê )" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"à°…à°•à±à°·à°° నివేదన సెమికోలనౠతో à°®à±à°—ియలేదà±; దాదాపà±à°—à°¾ యిది ఉపయెగించండి యాంపరౠసెండౠ" +"à°…à°•à±à°·à°°à°‚ తో à°ªà±à°°à°¾à°°à°‚భమవరాదౠ- " +"à°Žà°¸à±à°¸à±‡à°ªà± యాంపరౠసెండౠయాజౠ&యాంపౠ" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "à°…à°•à±à°·à°° నివేదన '%-.*s' à°…à°¨à±à°®à°¤à°¿à°‚చబడిన à°…à°•à±à°·à°°à°®à± ఎనౠకోడౠఅవà±à°µà°¦à±." + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +" ఖాశి à°µà±à°¯à°·à±à°Ÿà°¿ '&;' చూడబడినది; వరà±à°¤à°¿à°‚à°šà± à°µà±à°¯à°·à±à°Ÿà°¿à°²à±: & " < > " +"'" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "మూలకమౠనామమౠ'%-.*s' తెలిసినది కాదà±" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +" à°µà±à°¯à°·à±à°Ÿà°¿ సెమికోలనౠతో పూరà±à°¤à°µà°²à±‡à°¦à±; దాదాపà±à°—à°¾ యాంపరౠసెండౠఉపయెగించవలెనౠ" +"à°…à°•à±à°·à°°à°®à± దాదాపà±à°—à°¾ -' à°Žà°¸à±à°•ేపౠ" +"యంపరౠసెండౠయాజౠ&యాంపà±;' తో à°ªà±à°°à°¾à°°à°‚భమవలేదà±. " + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "పతà±à°°à°‚ తపà±à°ªà°¨à°¿à°¸à°°à°¿à°—à°¾ à°’à°• మూలకంతో à°ªà±à°°à°¾à°°à°‚భమవలెనౠ(ఉదా. <à°¬à±à°•à±>)" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +" '<' తో à°ªà±à°°à°¾à°°à°‚భమగౠ'%s' à°…à°¨à±à°¨à°¦à°¿ సరరిà°à°¨ à°…à°•à±à°·à°°à°‚ కాదౠ; యిది మూలక నామంతో " +"à°ªà±à°°à°¾à°°à°‚భమవలేదà±. " + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "బేసి à°…à°•à±à°·à°°à°®à± '%s', ఖాళీ-మూలకపౠటాగౠ'%s'నౠమà±à°—à°¿à°‚à°šà±à°Ÿà°•à± '>' à°…à°¨à±à°•ొనబడింది" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "బేసి à°…à°•à±à°·à°°à°®à± '%s', ఊహించిన '=' తరà±à°µà°¾à°¤ '%s' ఆపాదించౠనామం '%s' మూలకం " + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"'%s' ఊహించిన బేసి à°…à°•à±à°·à°°à°®à± '>' లేక '/' చివరి à°°à±à°°à°‚à°­ బొందౠఅకà±à°·à°°à°®à± మాలకం %sలేక " +"ఇచà±à°šà°¾à°ªà±‚à°°à±à°µà°• " +"ఆపాదన; దాదాపà±à°—à°¾ ఆపాదన నామంలో అనరà±à°¹à°®à±ˆà°¨ à°…à°•à±à°·à°°à°‚ ఉపమెగించినావà±" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"బేసి à°…à°•à±à°·à°°à°®à± '%s', ఊహించిన తెరచిన à°•à±à°µà±‹à°Ÿà± à°šà°¿à°¹à±à°¨à°‚ తరాత ఇచà±à°šà°¿à°¨ ఆపాదన విలà±à°µ '%s' " +"మూతకమౠ'%s'" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' is not a valid character following the close element name '%s'; the " +"allowed character is '>'" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr " '%s' మూలకం మూయబడినది, à°ªà±à°°à°¸à±à°§à±à°¤à°‚ ఠమూలకమౠతెరచియà±à°‚డలెదౠ" + +# ../glib/gmarkup.c:1588 +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "'%s' మూలకం మూయబడినది, కాని à°ªà±à°°à°¸à±à°§à±à°¤à°‚ తెరà±à°µ బడిన మూలకం '%s'" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr " పతà±à°°à°‚ ఖాలిగా ఉనà±à°¨à°¦à°¿ లేక à°’à°• వైటౠసà±à°ªà±‡à°¸à± కలిగి à°¯à±à°¨à±à°¨à°¦à°¿. " + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "పతà±à°°à°‚ చివర కోణ à°•à±à°‚డలీకరణమà±'<' వెంటనె అనవసరమà±à°—à°¾ à°®à±à°—ింపౠఅయినది" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"మూలకమà±à°²à± ఇంకనౠతెరచియà±à°¨à±à°¨ పతà±à°°à°‚ ఊహించని విధంగా అంతమైనది- '%s' చివరిది మూలకమౠ" +"తెరచబడినది" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"పతà±à°°à°‚ ఊహించని విధంగా అంతమైనది,మూసిన కోణకà±à°‚డశికరణం అంతమౠచూచà±à°Ÿà°•ౠఊహించబడినది " +"బొందౠ<%s/>" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr " పతà±à°°à°‚ చివర ఊహించని మూలకనామం కలదౠ" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "పతà±à°°à°‚ చివర ఊహించని ఆపాదననామం కలదà±" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "పతà±à°°à°‚ చివర ఊహించని తెరచిన బొందౠకలదà±." + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +" '=' à°šà°¿à°¹à±à°¨à°®à± తరà±à°µà°¾à°¤ యాటà±à°°à°¿à°¬à±à°¯à±‚టౠనామమà±à°¨à± à°…à°¨à±à°¸à°°à°¿à°¸à±à°¤à±‚ యాటà±à°°à°¿à°¬à±à°¯à±‚టౠవిలà±à°µà°²à±‡à°•à±à°‚à°¡à°¾ " +"పతà±à°°à°®à± à°…à°¨à±à°•ోకà±à°‚à°¡à°¾ " +"à°®à±à°—ించబడింది." + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr " లోపల ఆపాదన విలà±à°µ ఉనà±à°¨à°ªà±à°¡à± పాఠం ఊహించకà±à°‚à°¡à°¾ à°®à±à°—ింపౠఅయినది " + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr " '%s'మూలకమౠయోకà±à°• మూసిన బొందౠఊహించకà±à°‚à°¡à°¾ పాఠం à°®à±à°—ింపౠఅయినది " + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr " లోపల à°µà±à°¯à°¾à°–à±à°¯ à°•à±à°°à°®à°—తి ఆదేశం ఉండగా ఊహించకà±à°‚à°¡à°¾ పాఠం à°®à±à°—ింపౠఅయినది " + +#: ../glib/goption.c:795 +msgid "Usage:" +msgstr "వినిమయం:" + +#: ../glib/goption.c:795 +msgid "[OPTION...]" +msgstr "[ఇచà±à°šà°¾à°ªà±‚à°°à±à°µà°°à°•à°‚...]" + +#: ../glib/goption.c:911 +msgid "Help Options:" +msgstr "సహాయ ఇచà±à°›à°¾à°ªà±‚à°°à±à°µà°•ాలà±:" + +#: ../glib/goption.c:912 +msgid "Show help options" +msgstr "సహాయ ఇచà±à°›à°¾à°ªà±‚à°°à±à°µà°•ాలనౠచూపించà±à°Ÿ" + +#: ../glib/goption.c:918 +msgid "Show all help options" +msgstr "సహాయ ఇచà±à°›à°¾à°ªà±‚à°°à±à°µà°•ాలనà±à°¨à°¿à°‚టని చూపించà±à°Ÿ" + +#: ../glib/goption.c:980 +msgid "Application Options:" +msgstr "కారà±à°¯à°•à±à°·à±‡à°¤à±à°° ఇచà±à°›à°¾à°ªà±‚à°°à±à°µà°•ాలౠ:" + +#: ../glib/goption.c:1044 ../glib/goption.c:1114 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "పూరà±à°£à°¾à°‚à°•à°‚ విలà±à°µ %sనౠ%s కొరకౠపారà±à°¸à±â€ చేయలేదà±" + +#: ../glib/goption.c:1054 ../glib/goption.c:1122 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr " పూరà±à°£à°¾à°‚à°•à°‚ విలà±à°µ '%s' లో విసà±à°°à±ƒà°¤à°¿ లో లేని %s " + +#: ../glib/goption.c:1079 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "à°¡à°¬à±à°²à± విలà±à°µ '%s'నౠ%sకొరకౠపారà±à°¶à±â€â€Œà°šà±‡à°¯à°²à±‡à°¦à±" + +#: ../glib/goption.c:1087 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "à°¡à°¬à±à°²à± విలà±à°µ '%s' à°…à°¨à±à°¨à°¦à°¿ %sకొరకౠవà±à°¯à°¾à°ªà±à°¤à°¿à°²à±‹ లేదà±" + +#: ../glib/goption.c:1373 ../glib/goption.c:1452 +#, c-format +msgid "Error parsing option %s" +msgstr "à°à°šà±à°šà°¿à°•à°‚ పారà±à°¶à°¿à°‚à°—à±â€Œà°²à±‹ దోషమౠ%s" + +#: ../glib/goption.c:1483 ../glib/goption.c:1596 +#, c-format +msgid "Missing argument for %s" +msgstr "%s కొరకౠతపà±à°ªà°¿à°ªà±‹à°¯à°¿à°¨ ఆరà±à°—à±à°®à±†à°‚à°Ÿà±" + +#: ../glib/goption.c:2057 +#, c-format +msgid "Unknown option %s" +msgstr "తెలియని ఇచà±à°›à°¾à°ªà±‚à°°à±à°µà°•మౠ%s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "పాడైన ఆబà±à°œà°•à±à°Ÿà±" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "అతరà±à°—à°¤ దోషమౠలేదా పాడైన ఆబà±à°œà°•à±à°Ÿà±" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "మెమోరీ అయిపోయింది" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "à°¬à±à°¯à°¾à°•à±â€Œà°Ÿà±à°°à°¾à°•ింగౠపరిమితి చేరà±à°•ొంది" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "పాకà±à°·à°¿à°• సరిజోడికి మదà±à°¦à°¤à±€à°¯à°¨à°¿ à°…à°‚à°¶à°®à±à°²à°¨à± మాదిరి కలిగివà±à°‚ది" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "పాకà±à°·à°¿à°• సరిజోడికి నియమాలౠమదà±à°¦à°¤à±€à°¯à°¨à°¿ కారణంగా à°¬à±à°¯à°¾à°•ౠరిఫరెనà±à°¸à±â€" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°ªà± పరిమితి చేరినది" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "కొతà±à°¤à°µà°°à±à°¸ జెండాలయొకà±à°• చెలà±à°²à°¨à°¿ మిశà±à°°à°®à°‚" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "à°¬à±à°¯à°¾à°¡à± ఆఫà±â€Œà°¸à±†à°Ÿà±" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "లఘౠutf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "à°ªà±à°¨à°°à°¾à°µà±ƒà°¤ ఆవృతం" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "తెలియని దోషమà±" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ మాదిరి చివర వదà±à°¦" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c మాదిరి చివరవదà±à°¦" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "à°—à±à°°à±à°¤à°¿à°‚చబడని à°…à°•à±à°·à°°à°®à± à°…à°¨à±à°¸à°°à°¿à°¸à±à°¤à±‹à°‚ది \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} à°•à±à°µà°¾à°‚టిఫైరà±â€Œà°²à±‹ à°•à±à°°à°®à°®à± బయటవà±à°¨à±à°¨ సంఖà±à°¯à°²à±" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} à°•à±à°µà°¾à°‚టిఫైరà±â€Œà°²à±‹ పెదà±à°¦à°—ావà±à°¨à±à°¨ సంఖà±à°¯" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "à°…à°•à±à°·à°°à°ªà± à°•à±à°²à°¾à°¸à±â€Œà°•à± ] à°®à±à°—ింపౠతపà±à°ªà°¿à°ªà±‹à°¯à°¿à°¨à°¦à°¿" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "à°…à°•à±à°·à°°à°ªà± à°•à±à°²à°¾à°¸à±â€Œà°¨à°‚దౠచెలà±à°²à°¨à°¿ à°Žà°¸à±à°•ేపౠఅనà±à°•à±à°°à°®à°®à±" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "à°…à°•à±à°·à°°à°ªà± à°•à±à°²à°¾à°¸à±â€Œà°¨à°‚దౠవà±à°¯à°¾à°ªà±à°¤à°¿ à°•à±à°°à°®à°®à±à°•ౠబయటవà±à°‚ది" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "మళà±à°³à±€à°šà±‡à°¯à±à°Ÿà°•ౠయేమీలేదà±" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "à°…à°¨à±à°•ోని ఆవృతమà±" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "(? లేదా (?- తరà±à°µà°¾à°¤ à°—à±à°°à±à°¤à°¿à°‚à°ªà±à°²à±‡à°¨à°¿ à°…à°•à±à°·à°°à°®à±" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX నామపౠకà±à°²à°¾à°¸à±†à°¸à± à°•à±à°²à°¾à°¸à± లోపల మాతà±à°°à°®à±‡ మదà±à°¦à°¤à±à°¨à°¿à°¸à±à°¤à°¾à°¯à°¿" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "à°®à±à°—à°¿à°‚à°šà±à°¨à°¦à°¿ ) తపà±à°ªà°¿à°ªà±‹à°¯à°¿à°‚ది" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "లేని à°µà±à°ªà°®à°¾à°¦à°¿à°°à°¿à°•à°¿ రిఫరెనà±à°¸à±â€" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "à°µà±à°¯à°¾à°–à±à°¯à°¾à°¨à°‚ తరà±à°µà°¾à°¤ తపà±à°ªà°¿à°ªà±‹à°¯à°¿à°¨ )" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "సాదారణ సమీకరణం చాలా పెదà±à°¦à°¦à°¿" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "మెమొరి పొందà±à°Ÿà°²à±‹ విఫలమైంది" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") తెరిచిన ( లేకà±à°‚à°¡à°¾" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "కోడౠవోవరà±â€Œà°«à±à°²à±‹" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "(?< తరà±à°µà°¾à°¤ à°—à±à°°à±à°¤à°¿à°‚చని à°…à°•à±à°·à°°à°®à±" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "వెనà±à°•చూడండి చెపà±à°ªà°¿à°¨à°®à°¾à°Ÿ నిరà±à°§à°°à°¿à°¤ పోడవà±à°²à±‡à°¦à±" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "(?( తరà±à°µà°¾à°¤ తపà±à°ªà±à°—ావà±à°¨à±à°¨ సంఖà±à°¯ లేదా నామమà±" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "నియమరూపక సమూహం రెండà±à°•à°¨à±à°¨à°¾ యెకà±à°•à±à°µ శాఖలనౠకలిగివà±à°‚ది" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "(?( తరà±à°µà°¾à°¤ చెపà±à°ªà±‡à°®à°¾à°Ÿ à°…à°¨à±à°•ోబడినది" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R లేదా (?[+-]అంకెలౠతపà±à°ªà°• ) à°…à°¨à±à°¸à°°à°¿à°‚చాలి" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "తెలియని POSIX తరగతి నామమà±" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "POSIX à°–à°‚à°¡à°¿à°‚à°šà±à°•ొనౠమూలకాలౠమదà±à°¦à°¤à±€à°¯à°¬à°¡à°µà±" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} à°…à°¨à±à°•à±à°°à°®à°®à±à°¨à°‚దలి à°…à°•à±à°·à°°à°ªà± విలà±à°µ చాలా పెదà±à°¦à°¦à°¿" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "చెలà±à°²à°¨à°¿ నియమమౠ(?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "వెనà±à°• చెపà±à°ªà°¿à°¨ దానిలో \\C à°…à°¨à±à°®à°¤à°¿à°‚చబడదà±" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, మరియౠ\\u తోడà±à°ªà°¾à°Ÿà±à°²à±‡à°¦à±" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "à°ªà±à°¨à°°à°¾à°µà±ƒà°¤ కాలౠఅనంతంగా లూపà±â€Œà°•ాగలదà±" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "(?P తరà±à°µà°¾à°¤ à°—à±à°°à±à°¤à°¿à°‚చని à°…à°•à±à°·à°°à°®à±" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "ఉపమాదిరి నామమà±à°¨à°‚దౠతపà±à°ªà°¿à°ªà±‹à°¯à°¿à°¨ à°®à±à°—à°¿à°‚à°ªà±" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "రెండౠనామాల à°µà±à°ªà°®à°¾à°¦à°¿à°°à°¿à°²à± ఒకే నామమà±à°¨à± కలిగివà±à°¨à±à°¨à°¾à°¯à°¿" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "తపà±à°ªà±à°—ావà±à°¨à±à°¨ \\P లేదా \\p à°…à°¨à±à°•à±à°°à°®à°®à±" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "\\P లేదా \\p తరà±à°µà°¾à°¤ తెలియని లకà±à°·à°£à°®à± నామమà±" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ఉపమాదిరి నామమౠమరీ పెదà±à°¦à°¦à°¿ (à°—à°°à°¿à°·à±à° à°‚ 32 à°…à°•à±à°·à°°à°®à±à°²à±)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "నామమౠగలిగిన చాలా à°µà±à°ªà°®à°¾à°¦à°¿à°°à°¿à°²à± (à°—à°°à°¿à°·à±à° à°‚à°—à°¾ 10,000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "à°…à°·à±à°Ÿà°¾à°‚à°¶ విలà±à°µ \\377 à°•à°¨à±à°¨ పెదà±à°¦à°¦à°¿" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "మించిపోయిన నిరà±à°µà°°à±à°¤à°¨à°¾ పనితలం" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "à°®à±à°‚à°¦à±à°—à°¾-పరిశీలించిన రిఫరెనà±à°¸à±à°¡à± à°µà±à°ªà°®à°¾à°¦à°¿à°°à°¿ కనబడలేదà±" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "నిరà±à°µà°šà°¿à°‚à°šà°¿à°¨ సమూహం వొకటికనà±à°¨à°¾ యెకà±à°•à±à°µ శాఖలనౠకలిగివà±à°‚ది" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "à°…à°¸à±à°¥à°¿à°°à°¤à±à°µ NEWLINE à°à°šà±à°šà°¿à°•ాలà±" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g à°¬à±à°°à±‡à°¸à±â€Œà°¡à±, à°à°‚à°—à°¿à°²à±-à°¬à±à°°à°¾à°•ెటెడà±, లేదా కోటెడౠపేరౠలేదా సంఖà±à°¯, లేదా సాదా " +"సంఖà±à°¯ చే à°…à°¨à±à°¸à°°à°¿à°‚పబడదà±" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "రిఫరెనà±à°¸à± చేయబడà±à°¤à±à°¨à±à°¨ సంఖà±à°¯ à°¸à±à°¨à±à°¨à°¾ కారాదà±" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" +"ఆరà±à°—à±à°®à±†à°‚à°Ÿà± à°…à°¨à±à°¨à°¦à°¿ (*ACCEPT), (*FAIL), లేదా (*COMMIT) కొరకై à°…à°¨à±à°®à°¤à°¿à°‚చబడదà±" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) à°—à±à°°à±à°¤à°¿à°‚చబడలేదà±" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "సంఖà±à°¯ మరీ పెదà±à°¦à°¦à°¿" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& తరà±à°µà°¾à°¤ à°µà±à°ªà°®à°¾à°¦à°¿à°°à°¿ పేరౠలేదà±" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ తరà±à°µà°¾à°¤à°¨à±‡ అంకె రావలెనà±" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "JavaScript సారూపà±à°¯à°¤à°¾ రీతినందౠ] చెలà±à°²à°¨à°¿ దతà±à°¤à°¾à°‚à°¶ à°…à°•à±à°·à°°à°‚" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ఒకే సంఖà±à°¯ యొకà±à°• à°µà±à°ªà°®à°¾à°¦à°¿à°°à°¿à°² కొరకౠవేరà±à°µà±‡à°°à± పేరà±à°²à± à°…à°¨à±à°®à°¤à°¿à°‚చబడవà±" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) తపà±à°ªà°• వొక ఆరà±à°—à±à°®à±†à°‚టౠకలిగివà±à°‚డాలి" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c తపà±à°ªà°• ASCII à°…à°•à±à°·à°°à°‚చే à°…à°¨à±à°¸à°°à°¿à°‚చబడాలి" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k à°¬à±à°°à±‡à°¸à±â€Œà°¡à± లేదా à°à°‚à°—à°¿à°²à±-à°¬à±à°°à°¾à°•ెటà±, లేదా కోటెడౠపేరౠచే à°…à°¨à±à°¸à°°à°¿à°‚పబడదà±" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "à°’à°• తరగతి నందౠ\\N తోడà±à°ªà°¾à°Ÿà±à°¨à±€à°¯à°¦à±" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "చాలా ఫారà±à°µà°¾à°°à±à°¡à± రిఫరెనà±à°¸à±à°²à±" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP), నందౠ(*THEN) పేరౠచాలా పెదà±à°¦à°—ావà±à°‚ది" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... వరà±à°¸à°•à±à°°à°®à°‚ నందలి à°…à°•à±à°·à°° విలà±à°µ మరీ పెదà±à°¦à°¦à°¿" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "సాదారణ సమీకరణమà±à°¨à± సరిజోడి చేసà±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± దోషమౠ%s: %s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE లైబà±à°°à°°à±€ UTF-8 మదà±à°¦à°¤à±à°²à±‡à°•à±à°‚à°¡à°¾ నిరà±à°µà°°à±à°¤à°¿à°‚చబడింది" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE లైబà±à°°à°°à±€ UTF8 లకà±à°·à°£à°®à±à°² మదà±à°¦à°¤à±à°²à±‡à°•à±à°‚à°¡à°¾ నిరà±à°µà°°à±à°¤à°¿à°‚చబడింది" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE లైబà±à°°à°°à±€ సారూపà±à°¯à°¤à°²à±‡à°¨à°¿ à°à°šà±à°šà°¿à°•ాలతో నిరà±à°µà°°à±à°¤à°¿à°‚చబడెనà±" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "సాదారణ సమీకరణమౠ%sనౠఅకà±à°·à°°à°®à± %dవదà±à°¦ నిరà±à°µà°°à±à°¤à°¿à°¸à±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± దోషమà±: %s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "సాదారణ సమీకరణమౠ%sనౠమెరà±à°—à±à°ªà°°à±à°¸à±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± దోషమà±: %s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "హెగà±à°œà°¾à°¡à±†à°¸à°¿à°®à°²à± డిజిటౠలేదా '}' à°…à°¨à±à°•ోబడింది" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "హెగà±à°œà°¾à°¡à±†à°¸à°¿à°®à°²à± అంకె à°…à°¨à±à°•ోబడింది" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "à°šà°¿à°¹à±à°¨à°°à±‚à°ª రిఫరెనà±à°¸à±à°¨à°‚దౠ'<' తపà±à°ªà°¿à°ªà±‹à°¯à°¿à°¨à°¦à°¿" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "పూరà±à°¤à°¿à°•ాని à°šà°¿à°¹à±à°¨à°°à±‚à°ª రెఫరెనà±à°¸à±" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "à°¸à±à°¨à±à°¨à°¾-పొడవౠచిహà±à°¨à°°à±‚à°ª రిఫరెనà±à°¸à±" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "అంకె à°…à°¨à±à°•ోబడినది" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "సరికాని à°šà°¿à°¹à±à°¨à°°à±‚à°ª రిఫరెనà±à°¸à±" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "à°¸à±à°Ÿà±à°°à±‡ ఫైనలౠ'\\'" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "తెలియని యెసà±à°•ేపౠఅనà±à°•à±à°°à°®à°®à±" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "à°ªà±à°¨à°ƒà°¸à±à°¥à°¨ పాఠà±à°¯à°®à± \"%s\"నౠఅకà±à°·à°°à°‚ %lu వదà±à°¦ పారà±à°¶à±â€â€Œà°šà±‡à°¸à±à°¤à±à°‚టే దోషమà±: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "కోటెడౠపాఠం కొటేషనౠచిహà±à°¨à°‚తో à°ªà±à°°à°¾à°°à°‚భవరాదà±" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr " కమాండౠలైనౠలేద à°·à°²à±_కోటెడౠపాఠం లో సామà±à°¯à°‚లేని కొటేషనౠచిహà±à°¨à°‚ కలదౠ" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "పాఠం '\\' à°…à°•à±à°·à°°à°®à± వెంటనె à°®à±à°—ింపౠఅయినది. (à°ˆ పాఠమౠ'%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"సామà±à°¯à°®à±ˆà°¨ కొటేషనౠచిహà±à°¨à°‚ %c లభించకమà±à°‚దె పాఠం à°®à±à°—ింపౠఅయినది . (à°ˆ పాఠమà±'%s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "పాఠం à°à°®à°¿ లేదౠ(లేక à°’à°• వైటౠసà±à°ªà±‡à°¸à± కలదà±)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "(%s) శిశౠకారà±à°¯à°‚ à°¨à±à°‚à°¡à°¿ వివరమౠచదà±à°µà±à°Ÿà°²à±‹ విఫలమయినావౠ" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +" శిశౠకారà±à°¯à°‚ (%s) à°¨à±à°‚à°¡à°¿ పాఠం à°šà°¦à±à°µà±à°Ÿà°²à±‹ సెలెకà±à°Ÿà±() లో ఊహించని దోషం కలదà±. " + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "వెయిటౠపిడà±() లో ఊహించని దోషం కలదà±(%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "%ld కోడà±â€Œ తో చైలà±à°¡à± à°ªà±à°°à±‹à°¸à±†à°¸à± నిషà±à°•à±à°°à°®à°¿à°‚చెనà±" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "సంకేతం %ld తో చెలà±à°¡à± à°ªà±à°°à±‹à°¸à±†à°¸à± అంతంచేయబడెనà±" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "సంకేతం %ld తో చైలà±à°¡à± à°ªà±à°°à±‹à°¸à±†à°¸à± ఆపివేయబడెనà±" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "చైలà±à°¡à± à°ªà±à°°à±‹à°¸à±†à°¸à± అసహజంగా నిషà±à°•à±à°°à°®à°¿à°‚చెనà±" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr " శిశౠపైపౠనà±à°‚à°¡à°¿ à°šà°¦à±à°µà±à°Ÿà°²à±‹ విఫలమయినావà±(%s)" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) ఫోరà±à°•ౠవిఫలమయినది " + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr " '%s' (%s) వివరణ మారà±à°šà±à°Ÿà°²à±‹ విఫలమయినావౠ" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr " \"%s\" à°¶à°¿à°¶à±à°•ారà±à°¯à°‚ నిరà±à°µà°°à±à°¤à°¿à°‚à°šà±à°Ÿà°²à±‹ విఫలమయినావౠ(%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"à°Žà°—à±à°¬à°¡à°¿à°•à°¿ రిడైరెకà±à°Ÿà± చేయà±à°Ÿà°²à±‹ విఫలమైనది లేక శిశౠకారà±à°¯à°‚ యొకà±à°• దిగà±à°¬à°¡à°¿ (%s)" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr " (%s) à°¶à°¿à°¶à±à°•ారà±à°¯à°‚ యెకà±à°• ఫోరà±à°•ౠవిఫలమయినది " + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr " \"%s\" à°¶à°¿à°¶à±à°•ారà±à°¯à°‚ నిరà±à°µà°°à±à°¤à°¿à°‚à°šà±à°Ÿà°²à±‹ తెలియని ధోషం కలదౠ" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "శిశౠపిడౠపైపౠ(%s) à°¨à±à°‚à°¡à°¿ సరిపడà±à°¨à°‚à°¤ à°šà°¦à±à°µà±à°Ÿà°²à±‹ విఫలమైనావà±. " + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr " శిశౠకారà±à°¯à°‚ à°¨à±à°‚à°¡à°¿ à°šà°¦à±à°µà±à°Ÿà°²à±‹ విఫలమయినావౠ" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr " (%s) శిశౠకారà±à°¯à°‚ తో తెలియచేయà±à°Ÿà°•ౠపైపౠనౠసృషà±à°Ÿà°¿à°‚à°šà±à°Ÿà°²à±‹ విఫలమైనావౠ" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "(%s) శిశౠకారà±à°¯à°‚ నిరà±à°µà°°à±à°¤à°¿à°‚à°šà±à°Ÿà°²à±‹ విఫలమయినావౠ" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "చెలà±à°²à°¨à°¿ à°ªà±à°°à±‹à°—à±à°°à°¾à°®à± నామమà±: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "ఆరà±à°—à±à°®à±†à°‚టౠశీరà±à°·à°®à±à°²à±‹ %dవదà±à°¦ చెలà±à°²à°¨à°¿ à°¸à±à°Ÿà±à°°à°¿à°‚à°—à±: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "à°Žà°¨à±à°µà°¿à°°à°¾à°¨à±â€Œà°®à±†à°‚టౠనందౠచెలà±à°²à°¨à°¿ à°¸à±à°Ÿà±à°°à°¿à°‚à°—à±: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "చెలà±à°²à°¨à°¿ పనిచేయà±à°šà±à°¨à±à°¨ డైరెకà±à°Ÿà°°à°¿: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "సహాయ కారà±à°¯à°•à±à°°à°®à°‚ నిరà±à°µà°°à±à°¤à°¿à°‚à°šà±à°Ÿà°²à±‹ విఫలమైంది (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +" శిశౠకారà±à°¯à°‚ à°¨à±à°‚à°¡à°¿ జి_à°à°“_ఛానెలà±_వినà±à±©à±¨32_పోలà±() పాఠం నౠచదà±à°µà±à°Ÿà°²à±‹ ఊహించని " +"దోషం కలదà±" + +#: ../glib/gutf8.c:780 +#| msgid "failed to get memory" +msgid "Failed to allocate memory" +msgstr "మెమొరి కేటాయింటలో విఫలమైంది" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "à°…à°•à±à°·à°°à°®à± à°¯à±à°Ÿà°¿à°«à±-8 à°¶à±à°°à±‡à°£à°¿à°¯à°‚దౠలేదౠ" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "పరివరà±à°¤à°¨ à°Žà°—à±à°¬à°¡à°¿ వరà±à°¸ నిసà±à°¸à°¾à°°à°®à± " + +# ../glib/gutf8.c:1382 ../glib/gutf8.c:1478 +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "à°…à°•à±à°·à°°à°®à± UTF-16 à°¶à±à°°à±‡à°£à°¿à°¯à°‚దౠలేదà±" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u బైటà±" +msgstr[1] "%u బైటà±à°²à±" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f piB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f KB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f KB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f pB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s బైటà±" +msgstr[1] "%s బైటà±à°²à±" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "జనవరి" + +msgctxt "full month name with day" +msgid "February" +msgstr "à°«à°¿à°¬à±à°°à°µà°°à°¿" + +msgctxt "full month name with day" +msgid "March" +msgstr "మారà±à°šà°¿" + +msgctxt "full month name with day" +msgid "April" +msgstr "à°à°ªà±à°°à°¿à°²à±" + +msgctxt "full month name with day" +msgid "May" +msgstr "మే" + +msgctxt "full month name with day" +msgid "June" +msgstr "జూనà±" + +msgctxt "full month name with day" +msgid "July" +msgstr "జూలై" + +msgctxt "full month name with day" +msgid "August" +msgstr "ఆగషà±à°Ÿà±" + +msgctxt "full month name with day" +msgid "September" +msgstr "సెపà±à°Ÿà±†à°‚బరà±" + +msgctxt "full month name with day" +msgid "October" +msgstr "à°…à°•à±à°Ÿà±‹à°¬à°°à±" + +msgctxt "full month name with day" +msgid "November" +msgstr "నవంబరà±" + +msgctxt "full month name with day" +msgid "December" +msgstr "డిసెంబరà±" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "జనవరి" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "à°«à°¿à°¬à±à°°à°µà°°à°¿" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "మారà±à°šà°¿" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "à°à°ªà±à°°à°¿à°²à±" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "మే" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "జూనà±" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "జూలై" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ఆగషà±à°Ÿà±" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "సెపà±à°Ÿà±†à°‚బరà±" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "à°…à°•à±à°Ÿà±‹à°¬à°°à±" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "నవంబరà±" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "డిసెంబరà±" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "xmllint తో యినà±à°ªà±à°Ÿà± ఫైలౠనిరà±à°µà°°à±à°¤à°¿à°‚à°šà±à°Ÿà°²à±‹ దోషం:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "to-pixdata తో యినà±à°ªà±à°Ÿà± ఫైలౠనిరà±à°µà°°à±à°¤à°¿à°‚à°šà±à°Ÿà°²à±‹ దోషం:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "వాయిదావà±à°¨à±à°¨ దోషమà±à°¨à± పొందలేక పోయింది: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "దసà±à°¤à±à°°à°®à± '%s'నౠవà±à°°à°¾à°¯à°Ÿà±à°•ొరకౠతెరà±à°šà±à°Ÿà°²à±‹ విఫలమైంది: fdopen() విఫలమైంది:%s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "దసà±à°¤à±à°°à°®à± '%s'à°•à± à°µà±à°°à°¾à°¯à±à°Ÿà°•ౠవిఫలమైంది: fflush() విఫలమైంది: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "దసà±à°¤à±à°°à°®à± '%s'నౠమూయà±à°Ÿà°²à±‹ విఫలమైంది: fclose() విఫలమైంది: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "అసంపూరà±à°£à°‚ సమాచారానà±à°¨à°¿ పొందింది '%s' కొరకౠ" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "ఊహించని ఎంపికనౠపొడవౠSO_PASSCRED ఎనేబà±à°²à± ఒకవేళ చూడà±à°¡à°‚లోకరంటౠపà±à°²à°—à±à°—ౠపెటà±à°Ÿà±‡ చోటà±. " +#~ "ఆశించబడింది%d బైటà±à°²à±,%d వచà±à°šà°¿à°‚ది" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "అసాధారణ కారà±à°¯à°•à±à°°à°®à°‚ à°®à±à°—ింపౠఆవిరà±à°­à°¾à°µà°¾à°¨à°¿à°•à°¿ కారణమైంది కమాండౠలైనౠ'%s ':%s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "కమాండౠలైనౠ'%s 'non-à°¸à±à°¨à±à°¨à°¾ నిషà±à°•à±à°°à°®à°£ à°¸à±à°¥à°¿à°¤à°¿%d తో exited:%s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "ఖాళీ à°µà±à°ªà°¸à±à°Ÿà±à°°à°¿à°‚à°—à±à°¸à±â€ కొరకౠపనితలం పరిమితి చేరినది" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "కేసà±-మరలà±à°ªà± యెసà±à°•ేపà±à°¸à±â€ (\\l, \\L, \\u, \\U) యికà±à°•à°¡ à°…à°¨à±à°®à°¤à°¿à°‚చబడవà±" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "నిరà±à°µà°šà°¿à°‚చౠసమూహంనౠమళà±à°³à±€à°šà±‡à°¯à±à°Ÿ à°…à°¨à±à°®à°¤à°¿à°‚చబడదà±" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' కొరకౠఠసేవ రికారà±à°¡à±ˆà°²à±‡à°¦à±" + +#~ msgid "File is empty" +#~ msgstr " కాళీ దసà±à°¤à±à°°à°‚ " + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "'%s' మీట దసà±à°¤à±à°°à°‚ యొకà±à°• మీట నౠకలిగియà±à°¨à±à°¨à°¦à°¿,దాని విలà±à°µà°¨à± à°šà°¦à±à°µà±à°Ÿà°•ౠసాధà±à°¯à°ªà°¡à°¦à±." + +#~ msgid "This option will be removed soon." +#~ msgstr "à°ˆ à°à°šà±à°›à°¿à°•à°‚ వెంటనే తొలగించబడతాయి." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "దసà±à°¤à±à°°à°®à± '%s'నౠపà±à°°à°¾à°°à°‚à°­à°¿à°‚à°šà±à°Ÿà°²à±‹ దోషమà±: %s" + +#~ msgid "Error connecting: " +#~ msgstr "à°…à°¨à±à°¸à°‚ధానమగà±à°Ÿà°²à±‹ దోషమà±:" + +#~ msgid "Error connecting: %s" +#~ msgstr "%sà°•à± à°…à°¨à±à°¸à°‚ధానమగà±à°Ÿà°²à±‹ దోషమà±" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "%i à°…à°•à±à°·à°°à°¾à°² SOCKSv4 అమలౠపరిమితà±à°²à± యూజరà±à°ªà±‡à°°à±" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKSv4a అమలౠ%i à°…à°•à±à°·à°°à°¾à°² హోసà±à°Ÿà±à°ªà±‡à°°à± పరిమితం" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "à°¯à±à°¨à°¿à°•à±à°¸à±â€â€Œà°¨à±à°‚à°¡à°¿ à°šà°¦à±à°µà±à°Ÿà°²à±‹ దోషమà±: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "à°¯à±à°¨à°¿à°•à±à°¸à±â€â€Œà°¨à± మూయà±à°Ÿà°²à±‹ దోషమà±: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "à°¯à±à°¨à°¿à°•à±à°¸à±â€â€Œà°•à± à°µà±à°°à°¾à°¯à±à°Ÿà°²à±‹ దోషమà±: %s" + +#~ msgid "Do not give error for empty directory" +#~ msgstr "ఖాళీ డైరెకà±à°Ÿà°°à±€ కోసం దోషానà±à°¨à°¿ ఇసà±à°¤à±à°‚ది లేదà±" + +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "ఇనà±à°ªà±à°Ÿà± లో చెలà±à°²à°¨à°¿ UTF-8 à°•à±à°°à°®à°‚ " + +#~ msgid "Reached maximum data array limit" +#~ msgstr "à°—à°°à°¿à°·à±à°  డాటా యెరే పరిమితిని చేరినది" + +#~ msgid "do not hide entries" +#~ msgstr "à°ªà±à°°à°µà±‡à°¶à°¾à°²à°¨à± మరà±à°—à±à°ªà°°à°šà°µà°¦à±à°¦à±" + +#~ msgid "use a long listing format" +#~ msgstr "పొడవైన జాబితాకరణ రూపానà±à°¨à°¿ ఉపయోగించà±à°®à±" diff --git a/po/tg.po b/po/tg.po new file mode 100644 index 0000000..ed674fe --- /dev/null +++ b/po/tg.po @@ -0,0 +1,4258 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Victor Ibragimov , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: Tajik Gnome\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-03-13 13:41+0000\n" +"PO-Revision-Date: 2013-01-21 18:05+0500\n" +"Last-Translator: Victor Ibragimov \n" +"Language-Team: \n" +"Language: tg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../gio/gbufferedinputstream.c:427 ../gio/gbufferedinputstream.c:506 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:377 +#: ../gio/ginputstream.c:615 ../gio/ginputstream.c:833 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:732 +#: ../gio/gpollableinputstream.c:207 ../gio/gpollableoutputstream.c:208 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:899 ../gio/gbufferedoutputstream.c:581 +#: ../gio/gdataoutputstream.c:568 +msgid "Seek not supported on base stream" +msgstr "" + +#: ../gio/gbufferedinputstream.c:945 +msgid "Cannot truncate GBufferedInputStream" +msgstr "" + +#: ../gio/gbufferedinputstream.c:990 ../gio/ginputstream.c:1023 +#: ../gio/giostream.c:291 ../gio/goutputstream.c:1334 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gbufferedoutputstream.c:618 ../gio/gdataoutputstream.c:598 +msgid "Truncate not supported on base stream" +msgstr "" + +#: ../gio/gcancellable.c:318 ../gio/gdbusconnection.c:1885 +#: ../gio/gdbusconnection.c:1977 ../gio/gdbusprivate.c:1421 +#: ../gio/glocalfile.c:2172 ../gio/gsimpleasyncresult.c:843 +#: ../gio/gsimpleasyncresult.c:869 +#, fuzzy, c-format +msgid "Operation was cancelled" +msgstr "Ðмалиёт бекор шудааÑÑ‚" + +#: ../gio/gcharsetconverter.c:262 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:283 ../gio/gcharsetconverter.c:311 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:317 ../gio/gcharsetconverter.c:326 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:344 ../gio/gdatainputstream.c:854 +#: ../gio/gdatainputstream.c:1264 ../glib/gconvert.c:764 +#: ../glib/gconvert.c:1156 ../glib/giochannel.c:1586 ../glib/giochannel.c:1628 +#: ../glib/giochannel.c:2472 ../glib/gutf8.c:833 ../glib/gutf8.c:1284 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../gio/gcharsetconverter.c:349 ../glib/gconvert.c:772 +#: ../glib/gconvert.c:1081 ../glib/giochannel.c:1593 ../glib/giochannel.c:2484 +#, c-format +msgid "Error during conversion: %s" +msgstr "" + +#: ../gio/gcharsetconverter.c:446 ../gio/gsocket.c:991 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcharsetconverter.c:457 ../glib/gconvert.c:564 +#: ../glib/gconvert.c:642 ../glib/giochannel.c:1414 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" + +#: ../gio/gcharsetconverter.c:461 ../glib/gconvert.c:568 +#: ../glib/gconvert.c:646 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "" + +#: ../gio/gcontenttype.c:335 +#, fuzzy, c-format +msgid "%s type" +msgstr "Ðамуди %s" + +#: ../gio/gcontenttype-win32.c:162 +msgid "Unknown type" +msgstr "Ðамуди номаълум" + +#: ../gio/gcontenttype-win32.c:163 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcredentials.c:264 ../gio/gcredentials.c:528 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:438 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gcredentials.c:480 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:150 ../gio/gdbusaddress.c:238 +#: ../gio/gdbusaddress.c:319 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:177 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:190 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:253 ../gio/gdbusaddress.c:334 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:264 ../gio/gdbusaddress.c:345 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:454 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:475 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:489 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:567 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:603 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:617 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:631 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:652 +msgid "Error auto-launching: " +msgstr "" + +#: ../gio/gdbusaddress.c:660 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:696 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:714 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:723 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "" + +#: ../gio/gdbusaddress.c:741 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "" + +#: ../gio/gdbusaddress.c:960 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1030 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "" + +#: ../gio/gdbusaddress.c:1037 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1079 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "" + +#: ../gio/gdbusaddress.c:1296 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "" + +#: ../gio/gdbusaddress.c:1421 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "" + +#: ../gio/gdbusaddress.c:1442 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1541 ../gio/gdbusconnection.c:6757 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1550 ../gio/gdbusconnection.c:6766 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1560 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:298 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:342 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:513 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1175 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:719 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:733 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:747 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:537 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:569 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:599 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:686 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:883 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:597 ../gio/gdbusconnection.c:2440 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1930 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2562 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:4065 ../gio/gdbusconnection.c:4381 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4136 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4231 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4243 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:4254 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4324 ../gio/gdbusconnection.c:6200 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4508 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4726 ../gio/gdbusconnection.c:6706 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4781 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4812 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5032 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:5230 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:6311 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6430 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:1271 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:1282 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1293 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1305 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1318 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:1326 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1334 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:1383 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "" + +#: ../gio/gdbusmessage.c:1398 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1417 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1619 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1643 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1851 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1875 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2062 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:2075 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:2131 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:2145 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:2175 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:2185 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2506 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2643 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2651 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2695 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2705 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2721 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:3271 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:3279 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:2069 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "" + +#: ../gio/gdbusprivate.c:2114 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1640 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1663 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2763 ../gio/gdbusproxy.c:2900 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:709 +msgid "Abstract name space not supported" +msgstr "" + +#: ../gio/gdbusserver.c:796 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:874 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "" + +#: ../gio/gdbusserver.c:1043 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1083 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:92 +#, fuzzy +msgid "COMMAND" +msgstr "ФÐРМОÐ" + +#: ../gio/gdbus-tool.c:97 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:166 ../gio/gdbus-tool.c:222 ../gio/gdbus-tool.c:294 +#: ../gio/gdbus-tool.c:318 ../gio/gdbus-tool.c:701 ../gio/gdbus-tool.c:1020 +#: ../gio/gdbus-tool.c:1453 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Хатогӣ: %s\n" + +#: ../gio/gdbus-tool.c:177 ../gio/gdbus-tool.c:235 ../gio/gdbus-tool.c:1469 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:353 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:354 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:364 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:365 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:387 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:397 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:467 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:476 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:538 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:539 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:540 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:572 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:606 ../gio/gdbus-tool.c:832 ../gio/gdbus-tool.c:1559 +#: ../gio/gdbus-tool.c:1791 +#, c-format +msgid "Error connecting: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:618 +#, fuzzy, c-format +msgid "Error: object path not specified.\n" +msgstr "Хатогӣ: object path not specified.\n" + +#: ../gio/gdbus-tool.c:623 ../gio/gdbus-tool.c:893 ../gio/gdbus-tool.c:1617 +#: ../gio/gdbus-tool.c:1850 +#, fuzzy, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Хатогӣ: %s is not a valid object path\n" + +#: ../gio/gdbus-tool.c:629 +#, fuzzy, c-format +msgid "Error: signal not specified.\n" +msgstr "Хатогӣ: signal not specified.\n" + +#: ../gio/gdbus-tool.c:636 +#, fuzzy, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "Хатогӣ: signal must be the fully-qualified name.\n" + +#: ../gio/gdbus-tool.c:644 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Хатогӣ: %s is not a valid interface name\n" + +#: ../gio/gdbus-tool.c:650 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Хатогӣ: %s is not a valid member name\n" + +#: ../gio/gdbus-tool.c:656 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Хатогӣ: %s is not a valid unique bus name.\n" + +#: ../gio/gdbus-tool.c:679 ../gio/gdbus-tool.c:992 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:708 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:735 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:736 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:737 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:738 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:777 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:852 ../gio/gdbus-tool.c:1578 ../gio/gdbus-tool.c:1810 +#, fuzzy, c-format +msgid "Error: Destination is not specified\n" +msgstr "Хатогӣ: Destination is not specified\n" + +#: ../gio/gdbus-tool.c:873 ../gio/gdbus-tool.c:1597 +#, fuzzy, c-format +msgid "Error: Object path is not specified\n" +msgstr "Хатогӣ: Object path is not specified\n" + +#: ../gio/gdbus-tool.c:908 +#, fuzzy, c-format +msgid "Error: Method name is not specified\n" +msgstr "Хатогӣ: Method name is not specified\n" + +#: ../gio/gdbus-tool.c:919 +#, fuzzy, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "Хатогӣ: Method name '%s' is invalid\n" + +#: ../gio/gdbus-tool.c:984 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "" + +#: ../gio/gdbus-tool.c:1416 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1417 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1418 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1419 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1420 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1511 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1709 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1710 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1743 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:625 ../gio/gwin32appinfo.c:221 +#, fuzzy +msgid "Unnamed" +msgstr "Беном" + +#: ../gio/gdesktopappinfo.c:1038 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1326 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1628 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1632 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1872 ../gio/gdesktopappinfo.c:1896 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2128 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2252 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:394 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:472 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:548 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:753 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:855 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:367 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:377 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:400 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:917 ../gio/gfile.c:1156 ../gio/gfile.c:1295 +#: ../gio/gfile.c:1535 ../gio/gfile.c:1590 ../gio/gfile.c:1648 +#: ../gio/gfile.c:1732 ../gio/gfile.c:1789 ../gio/gfile.c:1853 +#: ../gio/gfile.c:1908 ../gio/gfile.c:3468 ../gio/gfile.c:3523 +#: ../gio/gfile.c:3669 ../gio/gfile.c:3711 ../gio/gfile.c:4113 +#: ../gio/gfile.c:4525 ../gio/gfile.c:4610 ../gio/gfile.c:4700 +#: ../gio/gfile.c:4797 ../gio/gfile.c:4884 ../gio/gfile.c:4985 +#: ../gio/gfile.c:5258 ../gio/gfile.c:5536 ../gio/gfile.c:5590 +#: ../gio/gfile.c:7135 ../gio/gfile.c:7225 ../gio/gfile.c:7309 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "Кор даÑтгирӣ карда намешавад" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1419 ../gio/glocalfile.c:1096 ../gio/glocalfile.c:1107 +#: ../gio/glocalfile.c:1120 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2474 ../gio/glocalfile.c:2328 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2534 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2542 ../gio/glocalfile.c:2337 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2561 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2825 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2829 +#, c-format +msgid "Error splicing file: %s" +msgstr "" + +#: ../gio/gfile.c:2960 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" + +#: ../gio/gfile.c:2964 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "" + +#: ../gio/gfile.c:2969 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "" + +#: ../gio/gfile.c:3029 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3659 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3819 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3870 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6258 ../gio/gvolume.c:365 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6367 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:204 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:211 ../gio/gfileenumerator.c:270 +#: ../gio/gfileenumerator.c:367 ../gio/gfileenumerator.c:467 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:358 ../gio/gfileenumerator.c:458 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:237 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:247 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:400 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:503 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:331 ../gio/gfileiostream.c:383 +#: ../gio/gfileoutputstream.c:377 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:375 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:459 ../gio/gfileoutputstream.c:453 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:428 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "" + +#: ../gio/ginetaddressmask.c:184 +msgid "No address specified" +msgstr "" + +#: ../gio/ginetaddressmask.c:192 +#, c-format +msgid "Length %u is too long for address" +msgstr "" + +#: ../gio/ginetaddressmask.c:225 +msgid "Address has bits set beyond prefix length" +msgstr "" + +#: ../gio/ginetaddressmask.c:304 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "" + +#: ../gio/ginetsocketaddress.c:206 ../gio/ginetsocketaddress.c:223 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:238 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1033 ../gio/giostream.c:301 +#: ../gio/goutputstream.c:1344 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/glib-compile-resources.c:145 ../gio/glib-compile-schemas.c:1459 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:149 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-resources.c:239 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:252 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "" + +#: ../gio/glib-compile-resources.c:263 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "" + +#: ../gio/glib-compile-resources.c:291 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "" + +#: ../gio/glib-compile-resources.c:310 ../gio/glib-compile-resources.c:370 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:340 +#, c-format +msgid "" +"Error processing input file with xmllint:\n" +"%s" +msgstr "" + +#: ../gio/glib-compile-resources.c:396 +#, c-format +msgid "" +"Error processing input file with to-pixdata:\n" +"%s" +msgstr "" + +#: ../gio/glib-compile-resources.c:410 +#, c-format +msgid "Error reading file %s: %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:430 +#, c-format +msgid "Error compressing file %s" +msgstr "" + +#: ../gio/glib-compile-resources.c:494 ../gio/glib-compile-schemas.c:1571 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#: ../gio/glib-compile-resources.c:619 +msgid "name of the output file" +msgstr "" + +#: ../gio/glib-compile-resources.c:619 ../gio/glib-compile-resources.c:650 +#: ../gio/gresource-tool.c:482 ../gio/gresource-tool.c:548 +#, fuzzy +msgid "FILE" +msgstr "ФÐЙЛ" + +#: ../gio/glib-compile-resources.c:620 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "" + +#: ../gio/glib-compile-resources.c:620 ../gio/glib-compile-schemas.c:1999 +#: ../gio/glib-compile-schemas.c:2028 +#, fuzzy +msgid "DIRECTORY" +msgstr "ДИРЕКТОРИЯ" + +#: ../gio/glib-compile-resources.c:621 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" + +#: ../gio/glib-compile-resources.c:622 +msgid "Generate source header" +msgstr "" + +#: ../gio/glib-compile-resources.c:623 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "" + +#: ../gio/glib-compile-resources.c:624 +msgid "Generate dependency list" +msgstr "" + +#: ../gio/glib-compile-resources.c:625 +msgid "Don't automatically create and register resource" +msgstr "" + +#: ../gio/glib-compile-resources.c:626 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "" + +#: ../gio/glib-compile-resources.c:627 +msgid "C identifier name used for the generated source code" +msgstr "" + +#: ../gio/glib-compile-resources.c:653 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" + +#: ../gio/glib-compile-resources.c:669 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:778 +msgid "empty names are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:788 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:800 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:809 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:818 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:921 +msgid "cannot add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:932 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:950 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:961 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:980 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:995 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1025 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1038 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1046 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1117 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1129 +#, c-format +msgid " extends not-yet-existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1145 +#, c-format +msgid " is list of not-yet-existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1153 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1173 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1183 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1200 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1207 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1239 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1463 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1757 ../gio/glib-compile-schemas.c:1828 +#: ../gio/glib-compile-schemas.c:1904 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1765 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1824 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1864 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1870 ../gio/glib-compile-schemas.c:1928 +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1874 ../gio/glib-compile-schemas.c:1932 +#: ../gio/glib-compile-schemas.c:1960 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1900 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1918 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1946 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1999 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2000 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2001 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2002 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:2047 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2086 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2089 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2092 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:252 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:597 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "" + +#: ../gio/glocalfile.c:974 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "" + +#: ../gio/glocalfile.c:1142 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1162 ../gio/glocalfile.c:1188 +#, c-format +msgid "Error renaming file: %s" +msgstr "" + +#: ../gio/glocalfile.c:1171 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1184 ../gio/glocalfile.c:2201 ../gio/glocalfile.c:2230 +#: ../gio/glocalfile.c:2390 ../gio/glocalfileoutputstream.c:575 +#: ../gio/glocalfileoutputstream.c:628 ../gio/glocalfileoutputstream.c:673 +#: ../gio/glocalfileoutputstream.c:1161 +msgid "Invalid filename" +msgstr "" + +#: ../gio/glocalfile.c:1351 ../gio/glocalfile.c:1375 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1359 +#, c-format +msgid "Error opening file: %s" +msgstr "" + +#: ../gio/glocalfile.c:1500 +#, c-format +msgid "Error removing file: %s" +msgstr "" + +#: ../gio/glocalfile.c:1880 +#, c-format +msgid "Error trashing file: %s" +msgstr "" + +#: ../gio/glocalfile.c:1903 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "" + +#: ../gio/glocalfile.c:1924 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:2003 ../gio/glocalfile.c:2023 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:2057 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2086 ../gio/glocalfile.c:2091 ../gio/glocalfile.c:2171 +#: ../gio/glocalfile.c:2178 +#, c-format +msgid "Unable to trash file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2179 ../glib/gregex.c:280 +#, fuzzy +msgid "internal error" +msgstr "хатогии дохилӣ" + +#: ../gio/glocalfile.c:2205 +#, c-format +msgid "Error creating directory: %s" +msgstr "" + +#: ../gio/glocalfile.c:2234 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "" + +#: ../gio/glocalfile.c:2238 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "" + +#: ../gio/glocalfile.c:2300 ../gio/glocalfile.c:2394 +#, c-format +msgid "Error moving file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2323 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2350 ../gio/glocalfileoutputstream.c:959 +#: ../gio/glocalfileoutputstream.c:973 ../gio/glocalfileoutputstream.c:988 +#: ../gio/glocalfileoutputstream.c:1004 ../gio/glocalfileoutputstream.c:1018 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2369 +#, c-format +msgid "Error removing target file: %s" +msgstr "" + +#: ../gio/glocalfile.c:2383 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:722 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:729 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:736 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:776 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1542 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1734 ../gio/glocalfileoutputstream.c:837 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:1980 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2025 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2062 ../gio/glocalfileinfo.c:2081 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:2116 +msgid "Cannot set permissions on symlinks" +msgstr "" + +#: ../gio/glocalfileinfo.c:2132 +#, c-format +msgid "Error setting permissions: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2183 +#, c-format +msgid "Error setting owner: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2206 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2216 ../gio/glocalfileinfo.c:2235 +#: ../gio/glocalfileinfo.c:2246 +#, c-format +msgid "Error setting symlink: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2225 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2351 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2374 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2389 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "" + +#: ../gio/glocalfileinfo.c:2396 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2488 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:186 ../gio/glocalfileoutputstream.c:726 +#, c-format +msgid "Error reading from file: %s" +msgstr "" + +#: ../gio/glocalfileinputstream.c:217 ../gio/glocalfileinputstream.c:229 +#: ../gio/glocalfileinputstream.c:336 ../gio/glocalfileoutputstream.c:464 +#: ../gio/glocalfileoutputstream.c:1036 +#, c-format +msgid "Error seeking in file: %s" +msgstr "" + +#: ../gio/glocalfileinputstream.c:258 ../gio/glocalfileoutputstream.c:254 +#: ../gio/glocalfileoutputstream.c:348 +#, c-format +msgid "Error closing file: %s" +msgstr "" + +#: ../gio/glocalfilemonitor.c:176 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:234 +#: ../gio/glocalfileoutputstream.c:747 +#, c-format +msgid "Error writing to file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:281 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:295 ../gio/glocalfileoutputstream.c:308 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:326 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:510 ../gio/glocalfileoutputstream.c:1087 +#, c-format +msgid "Error truncating file: %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:581 ../gio/glocalfileoutputstream.c:634 +#: ../gio/glocalfileoutputstream.c:679 ../gio/glocalfileoutputstream.c:819 +#: ../gio/glocalfileoutputstream.c:1068 ../gio/glocalfileoutputstream.c:1167 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:850 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:855 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:867 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1052 +#, c-format +msgid "Error removing old file: %s" +msgstr "" + +#: ../gio/gmemoryinputstream.c:476 ../gio/gmemoryoutputstream.c:739 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:486 +msgid "Invalid seek request" +msgstr "" + +#: ../gio/gmemoryinputstream.c:510 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:544 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:560 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:648 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:749 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:758 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:395 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:471 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:549 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:634 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:722 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:803 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:354 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/gnetworkmonitorbase.c:195 ../gio/gnetworkmonitorbase.c:298 +msgid "Network unreachable" +msgstr "" + +#: ../gio/gnetworkmonitorbase.c:233 ../gio/gnetworkmonitorbase.c:263 +msgid "Host unreachable" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:98 ../gio/gnetworkmonitornetlink.c:110 +#: ../gio/gnetworkmonitornetlink.c:129 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:119 +msgid "Could not create network monitor: " +msgstr "" + +#: ../gio/gnetworkmonitornetlink.c:177 +msgid "Could not get network status: " +msgstr "" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:464 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:425 ../gio/goutputstream.c:950 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:454 +#: ../gio/gresourcefile.c:555 ../gio/gresourcefile.c:657 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "" + +#: ../gio/gresourcefile.c:653 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "" + +#: ../gio/gresourcefile.c:861 +msgid "Input stream doesn't implement seek" +msgstr "" + +#: ../gio/gresource-tool.c:475 ../gio/gsettings-tool.c:529 +msgid "Print help" +msgstr "" + +#: ../gio/gresource-tool.c:476 ../gio/gresource-tool.c:544 +#, fuzzy +msgid "[COMMAND]" +msgstr "[ФÐРМОÐ]" + +#: ../gio/gresource-tool.c:481 +msgid "List sections containing resources in an elf FILE" +msgstr "" + +#: ../gio/gresource-tool.c:487 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" + +#: ../gio/gresource-tool.c:490 ../gio/gresource-tool.c:500 +msgid "FILE [PATH]" +msgstr "" + +#: ../gio/gresource-tool.c:491 ../gio/gresource-tool.c:501 +#: ../gio/gresource-tool.c:508 +#, fuzzy +msgid "SECTION" +msgstr "ҚИСМÐТ" + +#: ../gio/gresource-tool.c:496 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" + +#: ../gio/gresource-tool.c:506 +msgid "Extract a resource file to stdout" +msgstr "" + +#: ../gio/gresource-tool.c:507 +msgid "FILE PATH" +msgstr "" + +#: ../gio/gresource-tool.c:513 ../gio/gsettings-tool.c:609 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:521 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:535 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gresource-tool.c:538 ../gio/gsettings-tool.c:642 +#, fuzzy +msgid "Arguments:\n" +msgstr "Ðргументҳо:\n" + +#: ../gio/gresource-tool.c:542 +msgid " SECTION An (optional) elf section name\n" +msgstr "" + +#: ../gio/gresource-tool.c:546 ../gio/gsettings-tool.c:649 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gresource-tool.c:552 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr "" + +#: ../gio/gresource-tool.c:555 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" + +#: ../gio/gresource-tool.c:559 +#, fuzzy +msgid "[PATH]" +msgstr "[МÐСИР]" + +#: ../gio/gresource-tool.c:561 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" + +#: ../gio/gresource-tool.c:562 +#, fuzzy +msgid "PATH" +msgstr "МÐСИР" + +#: ../gio/gresource-tool.c:564 +msgid " PATH A resource path\n" +msgstr "" + +#: ../gio/gsettings-tool.c:57 ../gio/gsettings-tool.c:78 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:63 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:84 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:116 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:137 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:502 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:535 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:541 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:547 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:548 ../gio/gsettings-tool.c:554 +#: ../gio/gsettings-tool.c:591 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:553 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:559 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:561 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:566 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:567 ../gio/gsettings-tool.c:573 +#: ../gio/gsettings-tool.c:585 ../gio/gsettings-tool.c:597 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:572 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:578 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:579 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:584 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:590 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:596 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:602 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:605 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:617 +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:639 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:645 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:653 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:658 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:662 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:666 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:725 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "" + +#: ../gio/gsettings-tool.c:784 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:311 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:318 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:326 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:334 ../gio/gsocket.c:3525 ../gio/gsocket.c:3580 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:481 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "" + +#: ../gio/gsocket.c:509 ../gio/gsocket.c:563 ../gio/gsocket.c:570 +#, c-format +msgid "Unable to create socket: %s" +msgstr "" + +#: ../gio/gsocket.c:563 +msgid "Unknown family was specified" +msgstr "" + +#: ../gio/gsocket.c:570 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1728 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1771 +#, c-format +msgid "could not get remote address: %s" +msgstr "" + +#: ../gio/gsocket.c:1832 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1904 +#, c-format +msgid "Error binding to address: %s" +msgstr "" + +#: ../gio/gsocket.c:1957 ../gio/gsocket.c:1994 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "" + +#: ../gio/gsocket.c:1958 ../gio/gsocket.c:1995 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "" + +#: ../gio/gsocket.c:1959 +msgid "No support for source-specific multicast" +msgstr "" + +#: ../gio/gsocket.c:2178 +#, c-format +msgid "Error accepting connection: %s" +msgstr "" + +#: ../gio/gsocket.c:2299 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:2346 +msgid "Unable to get pending error: " +msgstr "" + +#: ../gio/gsocket.c:2512 +#, c-format +msgid "Error receiving data: %s" +msgstr "" + +#: ../gio/gsocket.c:2690 +#, c-format +msgid "Error sending data: %s" +msgstr "" + +#: ../gio/gsocket.c:2804 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "" + +#: ../gio/gsocket.c:2883 +#, c-format +msgid "Error closing socket: %s" +msgstr "" + +#: ../gio/gsocket.c:3518 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3796 ../gio/gsocket.c:3877 +#, c-format +msgid "Error sending message: %s" +msgstr "" + +#: ../gio/gsocket.c:3821 +msgid "GSocketControlMessage not supported on Windows" +msgstr "" + +#: ../gio/gsocket.c:4155 ../gio/gsocket.c:4290 +#, c-format +msgid "Error receiving message: %s" +msgstr "" + +#: ../gio/gsocket.c:4372 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "" + +#: ../gio/gsocket.c:4391 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:177 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "" + +#: ../gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to %s: " +msgstr "" + +#: ../gio/gsocketclient.c:193 +msgid "Could not connect: " +msgstr "" + +#: ../gio/gsocketclient.c:1072 ../gio/gsocketclient.c:1636 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:1125 ../gio/gsocketclient.c:1574 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:1151 ../gio/gsocketclient.c:1595 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:120 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:138 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:155 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "" + +#: ../gio/gsocks4aproxy.c:181 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:188 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:326 +#: ../gio/gsocks5proxy.c:336 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "" + +#: ../gio/gsocks5proxy.c:238 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:288 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "" + +#: ../gio/gsocks5proxy.c:350 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:357 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:363 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:370 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:376 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:382 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:388 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:394 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:400 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gthreadedresolver.c:110 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "" + +#: ../gio/gthreadedresolver.c:195 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "" + +#: ../gio/gthreadedresolver.c:397 ../gio/gthreadedresolver.c:571 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "" + +#: ../gio/gthreadedresolver.c:402 ../gio/gthreadedresolver.c:576 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gthreadedresolver.c:407 ../gio/gthreadedresolver.c:581 +#, c-format +msgid "Error resolving '%s'" +msgstr "" + +#: ../gio/gtlscertificate.c:248 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:253 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:263 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:288 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:297 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:548 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:172 ../gio/gunixconnection.c:558 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:190 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:206 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:342 +msgid "Error sending credentials: " +msgstr "" + +#: ../gio/gunixconnection.c:490 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:505 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixconnection.c:534 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:572 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:596 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:382 ../gio/gunixinputstream.c:403 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:436 ../gio/gunixoutputstream.c:422 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "" + +#: ../gio/gunixmounts.c:1983 ../gio/gunixmounts.c:2036 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:368 ../gio/gunixoutputstream.c:389 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:439 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:516 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:308 +#, c-format +msgid "Error launching application: %s" +msgstr "" + +#: ../gio/gwin32appinfo.c:344 +msgid "URIs not supported" +msgstr "" + +#: ../gio/gwin32appinfo.c:366 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:378 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:355 +#, c-format +msgid "Error reading from handle: %s" +msgstr "" + +#: ../gio/gwin32inputstream.c:387 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "" + +#: ../gio/gwin32outputstream.c:343 +#, c-format +msgid "Error writing to handle: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "Ҳофиза кофӣ неÑÑ‚" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "Хатогии дохилӣ: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "" + +#: ../glib/gbookmarkfile.c:760 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:771 ../glib/gbookmarkfile.c:842 +#: ../glib/gbookmarkfile.c:852 ../glib/gbookmarkfile.c:959 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1129 ../glib/gbookmarkfile.c:1194 +#: ../glib/gbookmarkfile.c:1258 ../glib/gbookmarkfile.c:1268 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1154 ../glib/gbookmarkfile.c:1168 +#: ../glib/gbookmarkfile.c:1236 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1798 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:1999 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2045 ../glib/gbookmarkfile.c:2203 +#: ../glib/gbookmarkfile.c:2288 ../glib/gbookmarkfile.c:2368 +#: ../glib/gbookmarkfile.c:2453 ../glib/gbookmarkfile.c:2536 +#: ../glib/gbookmarkfile.c:2614 ../glib/gbookmarkfile.c:2693 +#: ../glib/gbookmarkfile.c:2735 ../glib/gbookmarkfile.c:2832 +#: ../glib/gbookmarkfile.c:2952 ../glib/gbookmarkfile.c:3142 +#: ../glib/gbookmarkfile.c:3218 ../glib/gbookmarkfile.c:3386 +#: ../glib/gbookmarkfile.c:3475 ../glib/gbookmarkfile.c:3565 +#: ../glib/gbookmarkfile.c:3693 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2377 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2462 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2841 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3239 ../glib/gbookmarkfile.c:3396 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3419 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "" + +#: ../glib/gconvert.c:803 ../glib/gutf8.c:829 ../glib/gutf8.c:1039 +#: ../glib/gutf8.c:1176 ../glib/gutf8.c:1280 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1053 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1871 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1881 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1898 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1910 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1926 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2021 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "" + +#: ../glib/gconvert.c:2031 +msgid "Invalid hostname" +msgstr "" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:219 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "January" +msgstr "Январ" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "February" +msgstr "Феврал" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "March" +msgstr "Март" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "April" +msgstr "Ðпрел" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "May" +msgstr "Май" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "June" +msgstr "Июн" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "July" +msgstr "Июл" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "August" +msgstr "ÐвгуÑÑ‚" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "September" +msgstr "СентÑбр" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "October" +msgstr "ОктÑбр" + +#: ../glib/gdatetime.c:252 +msgctxt "full month name" +msgid "November" +msgstr "ÐоÑбр" + +#: ../glib/gdatetime.c:254 +msgctxt "full month name" +msgid "December" +msgstr "Декабр" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Янв" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Фев" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Мар" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Ðпр" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Май" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Июн" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Июл" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ðвг" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Сен" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Окт" + +#: ../glib/gdatetime.c:289 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ÐоÑ" + +#: ../glib/gdatetime.c:291 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Дек" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Душанбе" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Сешанбе" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Чоршанбе" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Панҷшанбе" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Ҷумъа" + +#: ../glib/gdatetime.c:316 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Шанбе" + +#: ../glib/gdatetime.c:318 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Якшанбе" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "" + +#: ../glib/gdatetime.c:343 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "" + +#: ../glib/gdatetime.c:345 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Офтоб" + +#: ../glib/gdir.c:120 ../glib/gdir.c:143 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:671 ../glib/gfileutils.c:759 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "" + +#: ../glib/gfileutils.c:686 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:700 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Файли \"%s\" хеле калон аÑÑ‚" + +#: ../glib/gfileutils.c:783 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:834 ../glib/gfileutils.c:921 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:851 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:885 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:993 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1035 ../glib/gfileutils.c:1593 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:1049 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1074 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1093 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1137 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1161 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1282 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1556 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "" + +#: ../glib/gfileutils.c:1569 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Қолиби '%s' дорои XXXXXX намебошад" + +#: ../glib/gfileutils.c:2097 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:2118 +msgid "Symbolic links not supported" +msgstr "" + +#: ../glib/giochannel.c:1418 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "" + +#: ../glib/giochannel.c:1763 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1810 ../glib/giochannel.c:2068 +#: ../glib/giochannel.c:2155 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1891 ../glib/giochannel.c:1968 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1954 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gkeyfile.c:722 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:758 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:1158 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:1215 +#, c-format +msgid "Invalid group name: %s" +msgstr "" + +#: ../glib/gkeyfile.c:1237 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:1263 +#, c-format +msgid "Invalid key name: %s" +msgstr "" + +#: ../glib/gkeyfile.c:1290 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1533 ../glib/gkeyfile.c:1695 ../glib/gkeyfile.c:3073 +#: ../glib/gkeyfile.c:3139 ../glib/gkeyfile.c:3265 ../glib/gkeyfile.c:3398 +#: ../glib/gkeyfile.c:3540 ../glib/gkeyfile.c:3770 ../glib/gkeyfile.c:3837 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1707 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1814 ../glib/gkeyfile.c:1930 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1834 ../glib/gkeyfile.c:1950 ../glib/gkeyfile.c:2319 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2536 ../glib/gkeyfile.c:2902 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2614 ../glib/gkeyfile.c:2690 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "" + +#: ../glib/gkeyfile.c:3088 ../glib/gkeyfile.c:3280 ../glib/gkeyfile.c:3848 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:4080 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:4102 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:4244 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:4258 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:4291 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:4315 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../glib/gmappedfile.c:130 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "" + +#: ../glib/gmappedfile.c:196 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "" + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "\"%s\" номи беÑътибор мебошад" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "\"%s\" номи беÑътибор мебошад: \"%c\"" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "" + +#: ../glib/gmarkup.c:682 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:694 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:720 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:758 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:766 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:771 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1119 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1159 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1227 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1352 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1396 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1529 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1576 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1585 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1753 +msgid "Document was empty or contained only whitespace" +msgstr "" + +#: ../glib/gmarkup.c:1767 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1775 ../glib/gmarkup.c:1820 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1783 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1789 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1795 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1800 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1806 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1813 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1829 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/goption.c:754 +msgid "Usage:" +msgstr "ИÑтифодабарӣ:" + +#: ../glib/goption.c:754 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:864 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:865 +msgid "Show help options" +msgstr "" + +#: ../glib/goption.c:871 +msgid "Show all help options" +msgstr "" + +#: ../glib/goption.c:933 +msgid "Application Options:" +msgstr "" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1979 +#, c-format +msgid "Unknown option %s" +msgstr "" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "ҳофизаи кофӣ неÑÑ‚" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "хатогии номаълум" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1899 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1319 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1323 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1331 +msgid "PCRE library is compiled with incompatible options" +msgstr "" + +#: ../glib/gregex.c:1390 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "" + +#: ../glib/gregex.c:1432 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2331 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2387 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2396 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2403 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2414 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2432 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2494 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2498 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2508 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:88 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:178 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:574 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:581 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:593 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn.c:203 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:362 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:853 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "" + +#: ../glib/gspawn.c:861 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:868 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "" + +#: ../glib/gspawn.c:875 +#, c-format +msgid "Child process exited abnormally" +msgstr "" + +#: ../glib/gspawn.c:1280 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn.c:1348 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: ../glib/gspawn.c:1496 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "" + +#: ../glib/gspawn.c:1506 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1516 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1525 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1533 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" + +#: ../glib/gspawn.c:1557 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gspawn.c:1630 ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gutf8.c:907 +msgid "Character out of range for UTF-8" +msgstr "" + +#: ../glib/gutf8.c:1007 ../glib/gutf8.c:1016 ../glib/gutf8.c:1146 +#: ../glib/gutf8.c:1155 ../glib/gutf8.c:1294 ../glib/gutf8.c:1390 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1305 ../glib/gutf8.c:1401 +msgid "Character out of range for UTF-16" +msgstr "" + +#: ../glib/gutils.c:2183 ../glib/gutils.c:2210 ../glib/gutils.c:2314 +#, fuzzy, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "Байт" +msgstr[1] "" + +#: ../glib/gutils.c:2189 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f КБ" + +#: ../glib/gutils.c:2191 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f МБ" + +#: ../glib/gutils.c:2194 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f ГБ" + +#: ../glib/gutils.c:2197 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f ТБ" + +#: ../glib/gutils.c:2200 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f ПБ" + +#: ../glib/gutils.c:2203 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f ЕБ" + +#: ../glib/gutils.c:2216 +#, c-format +msgid "%.1f kB" +msgstr "%.1f КБ" + +#: ../glib/gutils.c:2219 ../glib/gutils.c:2332 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#: ../glib/gutils.c:2222 ../glib/gutils.c:2337 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#: ../glib/gutils.c:2224 ../glib/gutils.c:2342 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ТБ" + +#: ../glib/gutils.c:2227 ../glib/gutils.c:2347 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ПБ" + +#: ../glib/gutils.c:2230 ../glib/gutils.c:2352 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ЕБ" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2267 +#, fuzzy, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "Байт" +msgstr[1] "" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2327 +#, c-format +msgid "%.1f KB" +msgstr "%.1f КБ" + +msgctxt "full month name with day" +msgid "January" +msgstr "Январ" + +msgctxt "full month name with day" +msgid "February" +msgstr "Феврал" + +msgctxt "full month name with day" +msgid "March" +msgstr "Март" + +msgctxt "full month name with day" +msgid "April" +msgstr "Ðпрел" + +msgctxt "full month name with day" +msgid "May" +msgstr "Май" + +msgctxt "full month name with day" +msgid "June" +msgstr "Июн" + +msgctxt "full month name with day" +msgid "July" +msgstr "Июл" + +msgctxt "full month name with day" +msgid "August" +msgstr "ÐвгуÑÑ‚" + +msgctxt "full month name with day" +msgid "September" +msgstr "СентÑбр" + +msgctxt "full month name with day" +msgid "October" +msgstr "ОктÑбр" + +msgctxt "full month name with day" +msgid "November" +msgstr "ÐоÑбр" + +msgctxt "full month name with day" +msgid "December" +msgstr "Декабр" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Янв" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Фев" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Мар" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Ðпр" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Май" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Июн" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Июл" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ðвг" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Сен" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Окт" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ÐоÑ" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Дек" diff --git a/po/th.po b/po/th.po new file mode 100644 index 0000000..af24ea8 --- /dev/null +++ b/po/th.po @@ -0,0 +1,5510 @@ +# Thai translation of glib. +# Copyright (C) 2005-2016 Free Software Foundation, Inc. +# This file is distributed under the same license as the glib package. +# Theppitak Karoonboonyanan , 2005-2010, 2013-2014. +# Akom Chotiphantawanon , 2015-2016. +# +msgid "" +msgstr "" +"Project-Id-Version: glib 2.35.9\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2016-08-25 18:43+0000\n" +"PO-Revision-Date: 2016-08-31 16:21+0700\n" +"Last-Translator: Akom Chotiphantawanon \n" +"Language-Team: Thai \n" +"Language: th\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Gtranslator 2.91.6\n" + +#: ../gio/gapplication.c:493 +msgid "GApplication options" +msgstr "ตัวเลือà¸à¸‚อง GApplication:" + +#: ../gio/gapplication.c:493 +msgid "Show GApplication options" +msgstr "à¹à¸ªà¸”งตัวเลือà¸à¸‚อง GApplication" + +#: ../gio/gapplication.c:538 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "เข้าสู่โหมดบริà¸à¸²à¸£ GApplication (ใช้จาà¸à¹à¸Ÿà¹‰à¸¡à¸šà¸£à¸´à¸à¸²à¸£ D-Bus)" + +#: ../gio/gapplication.c:550 +msgid "Override the application's ID" +msgstr "à¸à¸³à¸«à¸™à¸”ค่าทับ ID ของโปรà¹à¸à¸£à¸¡" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gio-tool.c:209 ../gio/gresource-tool.c:488 +#: ../gio/gsettings-tool.c:520 +msgid "Print help" +msgstr "à¹à¸ªà¸”งวิธีใช้" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:489 +#: ../gio/gresource-tool.c:557 +msgid "[COMMAND]" +msgstr "[คำสั่ง]" + +#: ../gio/gapplication-tool.c:49 ../gio/gio-tool.c:210 +msgid "Print version" +msgstr "à¹à¸ªà¸”งรุ่น" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:526 +msgid "Print version information and exit" +msgstr "à¹à¸ªà¸”งรุ่นของโปรà¹à¸à¸£à¸¡à¹à¸¥à¹‰à¸§à¸ˆà¸šà¸à¸²à¸£à¸—ำงาน" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "à¹à¸ªà¸”งรายชื่อโปรà¹à¸à¸£à¸¡" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "à¹à¸ªà¸”งรายชื่อของโปรà¹à¸à¸£à¸¡à¸—ี่สามารถเรียà¸à¸œà¹ˆà¸²à¸™ D-Bus (โดยใช้à¹à¸Ÿà¹‰à¸¡ .desktop) ที่ติดตั้งไว้" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "เรียà¸à¹‚ปรà¹à¸à¸£à¸¡à¸—ำงาน" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "เรียà¸à¹‚ปรà¹à¸à¸£à¸¡à¸—ำงาน (โดยอาจระบุà¹à¸Ÿà¹‰à¸¡à¸—ี่จะเปิดด้วยà¸à¹‡à¹„ด้)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [à¹à¸Ÿà¹‰à¸¡...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "เรียà¸à¸à¸²à¸£à¸à¸£à¸°à¸—ำ" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "เรียà¸à¸à¸²à¸£à¸à¸£à¸°à¸—ำà¸à¸±à¸šà¸•ัวโปรà¹à¸à¸£à¸¡" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID à¸à¸²à¸£à¸à¸£à¸°à¸—ำ [พารามิเตอร์]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "à¹à¸ªà¸”งรายชื่อà¸à¸²à¸£à¸à¸£à¸°à¸—ำที่ใช้ได้" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "à¹à¸ªà¸”งรายชื่อà¸à¸²à¸£à¸à¸£à¸°à¸—ำที่ตายตัวสำหรับโปรà¹à¸à¸£à¸¡à¸«à¸™à¸¶à¹ˆà¸‡à¹† (จาà¸à¹à¸Ÿà¹‰à¸¡ .desktop)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 ../gio/gio-tool.c:206 +msgid "COMMAND" +msgstr "คำสั่ง" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "คำสั่งที่ต้องà¸à¸²à¸£à¹à¸ªà¸”งรายละเอียดวิธีใช้" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "ชื่อประจำตัวของโปรà¹à¸à¸£à¸¡à¹ƒà¸™à¸£à¸¹à¸›à¹à¸šà¸šà¸‚อง D-Bus (เช่น: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:620 +#: ../gio/glib-compile-resources.c:626 ../gio/glib-compile-resources.c:652 +#: ../gio/gresource-tool.c:495 ../gio/gresource-tool.c:561 +msgid "FILE" +msgstr "à¹à¸Ÿà¹‰à¸¡" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "ชื่อà¹à¸Ÿà¹‰à¸¡à¹à¸šà¸šà¸ªà¸±à¸¡à¸žà¸±à¸—ธ์หรือพาธเต็ม หรือ URI ที่จะเปิด (มีหรือไม่à¸à¹‡à¹„ด้)" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำที่จะเรียà¸" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "พารามิเตอร์" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "พารามิเตอร์ของà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸à¸²à¸£à¸à¸£à¸°à¸—ำ ในรูปà¹à¸šà¸š GVariant (มีหรือไม่à¸à¹‡à¹„ด้)" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:526 +#: ../gio/gsettings-tool.c:612 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"ไม่รู้จัà¸à¸„ำสั่ง %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "วิธีใช้:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:551 +#: ../gio/gsettings-tool.c:647 +msgid "Arguments:\n" +msgstr "อาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์:\n" + +#: ../gio/gapplication-tool.c:133 ../gio/gio-tool.c:206 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "คำสั่ง:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"สั่ง '%s help COMMAND' เพื่อดูรายละเอียดวิธีใช้\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"คำสั่ง %s ต้องตามด้วยชื่อประจำตัวของโปรà¹à¸à¸£à¸¡à¸—ันที\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "ชื่อประจำตัวของโปรà¹à¸à¸£à¸¡à¹„ม่ถูà¸à¸•้อง: '%s'\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"'%s' ไม่ต้องà¸à¸²à¸£à¸­à¸²à¸£à¹Œà¸à¸´à¸§à¹€à¸¡à¸™à¸•์\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "ไม่สามารถเชื่อมต่อà¸à¸±à¸š D-Bus: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะส่งข้อความ %s ไปยังโปรà¹à¸à¸£à¸¡: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "ต้องมีชื่อà¸à¸²à¸£à¸à¸£à¸°à¸—ำตามหลังชื่อประจำตัวของโปรà¹à¸à¸£à¸¡\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"ชื่อà¸à¸²à¸£à¸à¸£à¸°à¸—ำไม่ถูà¸à¸•้อง: '%s'\n" +"ชื่อà¸à¸²à¸£à¸à¸£à¸°à¸—ำต้องประà¸à¸­à¸šà¸”้วยตัวอัà¸à¸©à¸£, ตัวเลข, '-' à¹à¸¥à¸° '.' เท่านั้น\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¹à¸ˆà¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์ของà¸à¸²à¸£à¸à¸£à¸°à¸—ำ: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำรับพารามิเตอร์ไม่เà¸à¸´à¸™à¸«à¸™à¸¶à¹ˆà¸‡à¸•ัว\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "คำสั่ง list-actions รับเพียงชื่อประจำตัวของโปรà¹à¸à¸£à¸¡à¹€à¸—่านั้น" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "หาà¹à¸Ÿà¹‰à¸¡à¹€à¸”สà¸à¹Œà¸—็อปสำหรับโปรà¹à¸à¸£à¸¡ %s ไม่พบ\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"พบคำสั่งที่ไม่รู้จัà¸: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:179 ../gio/ginputstream.c:379 +#: ../gio/ginputstream.c:617 ../gio/ginputstream.c:1019 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:834 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "มีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸„่า count ที่สูงเà¸à¸´à¸™à¹„ปมาให้ %s" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "สตรีมà¸à¸²à¸™à¹„ม่รองรับà¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸­à¸™à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸­à¹ˆà¸²à¸™à¹€à¸‚ียน" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "ไม่สามารถตัดท้าย GBufferedInputStream ทิ้ง" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1208 +#: ../gio/giostream.c:300 ../gio/goutputstream.c:1660 +msgid "Stream is already closed" +msgstr "สตรีมถูà¸à¸›à¸´à¸”ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "สตรีมà¸à¸²à¸™à¹„ม่รองรับà¸à¸²à¸£à¸•ัดท้ายทิ้ง" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1849 +#: ../gio/gdbusprivate.c:1377 ../gio/gsimpleasyncresult.c:870 +#: ../gio/gsimpleasyncresult.c:896 +#, c-format +msgid "Operation was cancelled" +msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำถูà¸à¸¢à¸à¹€à¸¥à¸´à¸" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "อ็อบเจà¸à¸•์ผิดพลาด ยังไม่ได้ตั้งค่าเริ่มต้น" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "มีลำดับไบต์ที่ไม่สมบูรณ์ในข้อมูลเข้า" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "มีที่ว่างไม่พอที่ปลายทาง" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1257 ../glib/gconvert.c:438 ../glib/gconvert.c:845 +#: ../glib/giochannel.c:1556 ../glib/giochannel.c:1598 +#: ../glib/giochannel.c:2442 ../glib/gutf8.c:855 ../glib/gutf8.c:1308 +msgid "Invalid byte sequence in conversion input" +msgstr "มีลำดับไบต์ที่ไม่ถูà¸à¸•้องในข้อมูลที่ป้อนให้ตัวà¹à¸›à¸¥à¸‡à¸£à¸«à¸±à¸ª" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 ../glib/gconvert.c:770 +#: ../glib/giochannel.c:1563 ../glib/giochannel.c:2454 +#, c-format +msgid "Error during conversion: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดระหว่างà¹à¸›à¸¥à¸‡à¸£à¸«à¸±à¸ª: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:1078 +msgid "Cancellable initialization not supported" +msgstr "ไม่รองรับà¸à¸²à¸£à¸•ั้งค่าเริ่มต้นà¹à¸šà¸šà¸¢à¸à¹€à¸¥à¸´à¸à¹„ด้" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1384 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "ไม่รองรับà¸à¸²à¸£à¹à¸›à¸¥à¸‡à¸£à¸«à¸±à¸ªà¸­à¸±à¸à¸‚ระจาภ'%s' ไปเป็น '%s'" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "ไม่สามารถเปิดตัวà¹à¸›à¸¥à¸‡à¸£à¸«à¸±à¸ªà¸­à¸±à¸à¸‚ระจาภ'%s' ไปเป็น '%s' ได้" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "ชนิด %s" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "ชนิดข้อมูลไม่รู้จัà¸" + +#: ../gio/gcontenttype-win32.c:162 +#, c-format +msgid "%s filetype" +msgstr "ชนิดà¹à¸Ÿà¹‰à¸¡ %s" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "ยังไม่รองรับ GCredentials ในระบบปà¸à¸´à¸šà¸±à¸•ิà¸à¸²à¸£à¸™à¸µà¹‰" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "ไม่รองรับ GCredentials สำหรับà¹à¸žà¸¥à¸•ฟอร์มของคุณ" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials ไม่มีข้อมูล ID ของโพรเซสในระบบปà¸à¸´à¸šà¸±à¸•ิà¸à¸²à¸£à¸™à¸µà¹‰" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "ไม่สามารถปลอมà¹à¸›à¸¥à¸‡à¸‚้อมูลลับในระบบปà¸à¸´à¸šà¸±à¸•ิà¸à¸²à¸£à¸™à¸µà¹‰à¹„ด้" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "พบจุดจบสตรีมà¸à¹ˆà¸­à¸™à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gdbusaddress.c:153 ../gio/gdbusaddress.c:241 +#: ../gio/gdbusaddress.c:322 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "ไม่รองรับคีย์ '%s' ในรายà¸à¸²à¸£à¸—ี่อยู่ '%s'" + +#: ../gio/gdbusaddress.c:180 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "ที่อยู่ '%s' ใช้à¸à¸²à¸£à¹„ม่ได้ (ต้องมีคีย์ path, tmpdir หรือ abstract ดัวใดตัวหนึ่ง)" + +#: ../gio/gdbusaddress.c:193 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "คู่คีย์/ค่าไม่มีความหมายในรายà¸à¸²à¸£à¸—ี่อยู่ '%s'" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "พบข้อผิดพลาดในที่อยู่ '%s' - ค่าพอร์ตผิดรูปà¹à¸šà¸š" + +#: ../gio/gdbusaddress.c:267 ../gio/gdbusaddress.c:348 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "พบข้อผิดพลาดในที่อยู่ '%s' - ค่า family ผิดรูปà¹à¸šà¸š" + +#: ../gio/gdbusaddress.c:457 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "อิลิเมนต์ที่อยู่ '%s' ไม่มีทวิภาค (:)" + +#: ../gio/gdbusaddress.c:478 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "คู่คีย์/ค่าที่ %d ('%s') ในอิลิเมนต์ที่อยู่ '%s' ไม่มีเครื่องหมายเท่าà¸à¸±à¸š" + +#: ../gio/gdbusaddress.c:492 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะถอดรหัสหลีà¸à¸‚องคีย์หรือค่าในคู่คีย์/ค่าที่ %d ('%s') ในอิลิเมนต์ที่อยู่ '%s'" + +#: ../gio/gdbusaddress.c:570 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"พบข้อผิดพลาดในที่อยู่ '%s' - ช่องขนส่งของยูนิà¸à¸‹à¹Œà¸•้องมีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”คีย์ 'path' หรือ 'abstract' " +"ตัวใดตัวหนึ่ง" + +#: ../gio/gdbusaddress.c:606 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "พบข้อผิดพลาดในที่อยู่ '%s' - ค่า host ขาดหายไปหรือผิดรูปà¹à¸šà¸š" + +#: ../gio/gdbusaddress.c:620 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "พบข้อผิดพลาดในที่อยู่ '%s' - ค่า port ขาดหายไปหรือผิดรูปà¹à¸šà¸š" + +#: ../gio/gdbusaddress.c:634 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "พบข้อผิดพลาดในที่อยู่ '%s' - ค่า noncefile ขาดหายไปหรือผิดรูปà¹à¸šà¸š" + +#: ../gio/gdbusaddress.c:655 +msgid "Error auto-launching: " +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเรียà¸à¸—ำงานอัตโนมัติ: " + +#: ../gio/gdbusaddress.c:663 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "ไม่รู้จัà¸à¸«à¸£à¸·à¸­à¹„ม่รองรับà¸à¸²à¸£à¸‚นส่ง '%s' สำหรับที่อยู่ '%s'" + +#: ../gio/gdbusaddress.c:699 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดà¹à¸Ÿà¹‰à¸¡à¹€à¸‰à¸žà¸²à¸°à¸à¸²à¸¥ '%s': %s" + +#: ../gio/gdbusaddress.c:717 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านà¹à¸Ÿà¹‰à¸¡à¹€à¸‰à¸žà¸²à¸°à¸à¸²à¸¥ '%s': %s" + +#: ../gio/gdbusaddress.c:726 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านà¹à¸Ÿà¹‰à¸¡à¹€à¸‰à¸žà¸²à¸°à¸à¸²à¸¥ '%s' ต้องà¸à¸²à¸£ 16 ไบต์à¹à¸•่ได้รับ %d ไบต์" + +#: ../gio/gdbusaddress.c:744 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเขียนข้อมูลของà¹à¸Ÿà¹‰à¸¡à¹€à¸‰à¸žà¸²à¸°à¸à¸²à¸¥ '%s' ลงในสตรีม:" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "ที่อยู่ที่à¸à¸³à¸«à¸™à¸”ว่างเปล่า" + +#: ../gio/gdbusaddress.c:1064 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "ไม่สามารถสร้างโพรเซสสำหรับบัสข้อความในขณะที่มีà¸à¸²à¸£ setuid" + +#: ../gio/gdbusaddress.c:1071 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "ไม่สามารถสร้างโพรเซสสำหรับบัสข้อความโดยไม่มี ID ของเครื่อง: " + +#: ../gio/gdbusaddress.c:1078 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "ไม่สามารถเรียภD-Bus à¹à¸šà¸šà¸­à¸±à¸•โนมัติโดยไม่มีค่า $DISPLAY ของ X11 ได้" + +#: ../gio/gdbusaddress.c:1120 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะสร้างโพรเซสสำหรับบรรทัดคำสั่ง '%s': " + +#: ../gio/gdbusaddress.c:1337 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(à¸à¸”ปุ่มใดๆ เพื่อปิดหน้าต่างนี้)\n" + +#: ../gio/gdbusaddress.c:1489 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "dbus ของวาระไม่ได้ทำงานอยู่ à¹à¸¥à¸°à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸—ำงานอัตโนมัติà¸à¹‡à¸¥à¹‰à¸¡à¹€à¸«à¸¥à¸§" + +#: ../gio/gdbusaddress.c:1500 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "ไม่สามารถà¸à¸³à¸«à¸™à¸”ที่อยู่ของบัสของวาระได้ (ยังไม่รองรับสำหรับระบบปà¸à¸´à¸šà¸±à¸•ิà¸à¸²à¸£à¸™à¸µà¹‰)" + +#: ../gio/gdbusaddress.c:1635 ../gio/gdbusconnection.c:7133 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"ไม่สามารถà¸à¸³à¸«à¸™à¸”ที่อยู่ของบัสจาà¸à¸•ัวà¹à¸›à¸£à¸ à¸²à¸§à¸°à¹à¸§à¸”ล้อม DBUS_STARTER_BUS_TYPE ได้ - ไม่รู้จัà¸à¸„่า " +"'%s'" + +#: ../gio/gdbusaddress.c:1644 ../gio/gdbusconnection.c:7142 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"ไม่สามารถà¸à¸³à¸«à¸™à¸”ที่อยู่ของบัสเนื่องจาà¸à¹„ม่มีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ตัวà¹à¸›à¸£à¸ à¸²à¸§à¸°à¹à¸§à¸”ล้อม DBUS_STARTER_BUS_TYPE " +"ไว้" + +#: ../gio/gdbusaddress.c:1654 +#, c-format +msgid "Unknown bus type %d" +msgstr "ไม่รู้จัà¸à¸Šà¸™à¸´à¸”บัส %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "ไม่มีเนื้อหาให้อ่านขณะพยายามอ่านหนึ่งบรรทัด" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "ไม่มีเนื้อหาให้อ่านขณะพยายามอ่านหนึ่งบรรทัด (อย่างปลอดภัย)" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "ได้ลองà¸à¸¥à¹„à¸à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•ัวบุคคลที่มีทั้งหมดà¹à¸¥à¹‰à¸§ (ที่ลอง: %s) (ที่มี: %s)" + +#: ../gio/gdbusauth.c:1173 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "ถูà¸à¸¢à¸à¹€à¸¥à¸´à¸à¸œà¹ˆà¸²à¸™ GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านข้อมูลของไดเรà¸à¸—อรี '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”สิทธิ์ของไดเรà¸à¸—อรี '%s' ผิดรูปà¹à¸šà¸š ต้องà¸à¸²à¸£ 0700 à¹à¸•่พบ 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะสร้างไดเรà¸à¸—อรี '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดพวงà¸à¸¸à¸à¹à¸ˆ '%s' เพื่ออ่าน: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "บรรทัด %d ของพวงà¸à¸¸à¸à¹à¸ˆà¸—ี่ '%s' ซึ่งมีเนื้อหา '%s' ผิดรูปà¹à¸šà¸š" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "โทเคนà¹à¸£à¸à¸‚องบรรทัด %d ของพวงà¸à¸¸à¸à¹à¸ˆà¸—ี่ '%s' ซึ่งมีเนื้อหา '%s' ผิดรูปà¹à¸šà¸š" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "โทเคนที่สองของบรรทัด %d ของพวงà¸à¸¸à¸à¹à¸ˆà¸—ี่ '%s' ซึ่งมีเนื้อหา '%s' ผิดรูปà¹à¸šà¸š" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "ไม่พบคุà¸à¸à¸µà¹‰à¸—ี่มี ID %d ในพวงà¸à¸¸à¸à¹à¸ˆà¸—ี่ '%s'" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะลบà¹à¸Ÿà¹‰à¸¡à¸¥à¹‡à¸­à¸„ '%s' ที่ตาย: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะสร้างà¹à¸Ÿà¹‰à¸¡à¸¥à¹‡à¸­à¸„ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะปิดà¹à¸Ÿà¹‰à¸¡à¸¥à¹‡à¸­à¸„ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะลบà¹à¸Ÿà¹‰à¸¡à¸¥à¹‡à¸­à¸„ '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดพวงà¸à¸¸à¸à¹à¸ˆ '%s' เพื่ออ่าน: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(นอà¸à¸ˆà¸²à¸à¸™à¸µà¹‰ à¸à¸²à¸£à¸›à¸¥à¸”à¹à¸Ÿà¹‰à¸¡à¸¥à¹‡à¸­à¸„สำหรับ '%s' à¸à¹‡à¸¥à¹‰à¸¡à¹€à¸«à¸¥à¸§: %s)" + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2377 +msgid "The connection is closed" +msgstr "à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อถูà¸à¸›à¸´à¸”ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/gdbusconnection.c:1879 +msgid "Timeout was reached" +msgstr "หมดเวลาคอย" + +#: ../gio/gdbusconnection.c:2499 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "พบà¹à¸Ÿà¸¥à¹‡à¸à¸—ี่ไม่รองรับขณะสร้างà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อà¸à¸±à¹ˆà¸‡à¸¥à¸¹à¸à¸‚่าย" + +#: ../gio/gdbusconnection.c:4109 ../gio/gdbusconnection.c:4456 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "ไม่มีอินเทอร์เฟซ 'org.freedesktop.DBus.Properties' ในออบเจ็à¸à¸•์ที่พาธ %s" + +#: ../gio/gdbusconnection.c:4251 +#, c-format +msgid "No such property '%s'" +msgstr "ไม่มีคุณสมบัติ '%s'" + +#: ../gio/gdbusconnection.c:4263 +#, c-format +msgid "Property '%s' is not readable" +msgstr "คุณสมบัติ '%s' ไม่สามารถอ่านได้" + +#: ../gio/gdbusconnection.c:4274 +#, c-format +msgid "Property '%s' is not writable" +msgstr "คุณสมบัติ '%s' ไม่สามารถเขียนได้" + +#: ../gio/gdbusconnection.c:4294 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸”คุณสมบัติ '%s': ต้องà¸à¸²à¸£à¸Šà¸™à¸´à¸” '%s' à¹à¸•่ได้รับ '%s'" + +#: ../gio/gdbusconnection.c:4399 ../gio/gdbusconnection.c:6573 +#, c-format +msgid "No such interface '%s'" +msgstr "ไม่มีอินเทอร์เฟซ '%s'" + +#: ../gio/gdbusconnection.c:4607 +msgid "No such interface" +msgstr "ไม่มีอินเทอร์เฟซที่ว่า" + +#: ../gio/gdbusconnection.c:4825 ../gio/gdbusconnection.c:7082 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "ไม่มีอินเทอร์เฟซ '%s' ในออบเจ็à¸à¸•์ที่พาธ %s" + +#: ../gio/gdbusconnection.c:4923 +#, c-format +msgid "No such method '%s'" +msgstr "ไม่มีเมธอด '%s'" + +#: ../gio/gdbusconnection.c:4954 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "ชนิดของข้อความ '%s' ไม่ตรงà¸à¸±à¸šà¸Šà¸™à¸´à¸” '%s' ที่ต้องà¸à¸²à¸£" + +#: ../gio/gdbusconnection.c:5152 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "มีออบเจ็à¸à¸•์ที่ส่งออà¸à¹„ปà¹à¸¥à¹‰à¸§à¸ªà¸³à¸«à¸£à¸±à¸šà¸­à¸´à¸™à¹€à¸—อร์เฟซ %s ที่ %s" + +#: ../gio/gdbusconnection.c:5378 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "ไม่สามารถดึงค่าคุณสมบัติ %s.%s" + +#: ../gio/gdbusconnection.c:5434 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "ไม่สามารถà¸à¸³à¸«à¸™à¸”ค่าคุณสมบัติ %s.%s" + +#: ../gio/gdbusconnection.c:5610 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "เมธอด '%s' คืนค่าชนิด '%s' à¹à¸•่ควรเป็น '%s'" + +#: ../gio/gdbusconnection.c:6684 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "ไม่มีเมธอด '%s' ในอินเทอร์เฟซ '%s' ซึ่งมีลายเซ็น '%s'" + +#: ../gio/gdbusconnection.c:6805 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "มีต้นไม้ย่อยที่ส่งออà¸à¹„ปà¹à¸¥à¹‰à¸§à¸ªà¸³à¸«à¸£à¸±à¸š %s" + +#: ../gio/gdbusmessage.c:1244 +msgid "type is INVALID" +msgstr "ชนิดเป็น INVALID" + +#: ../gio/gdbusmessage.c:1255 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "ข้อความ METHOD_CALL: ข้อมูลส่วนหัว PATH หรือ MEMBER ขาดหายไป" + +#: ../gio/gdbusmessage.c:1266 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "ข้อความ METHOD_RETURN: ข้อมูลส่วนหัว REPLY_SERIAL ขาดหายไป" + +#: ../gio/gdbusmessage.c:1278 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ข้อความ ERROR: ข้อมูลส่วนหัว REPLY_SERIAL หรือ ERROR_NAME ขาดหายไป" + +#: ../gio/gdbusmessage.c:1291 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "ข้อความ SIGNAL: ข้อมูลส่วนหัว PATH, INTERFACE หรือ MEMBER ขาดหายไป" + +#: ../gio/gdbusmessage.c:1299 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "ข้อความ SIGNAL: ข้อมูลส่วนหัว PATH ใช้ค่า /org/freedesktop/DBus/Local ที่สงวนไว้" + +#: ../gio/gdbusmessage.c:1307 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"ข้อความ SIGNAL: ข้อมูลส่วนหัว INTERFACE ใช้ค่า org.freedesktop.DBus.Local ที่สงวนไว้" + +#: ../gio/gdbusmessage.c:1355 ../gio/gdbusmessage.c:1415 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "ต้องà¸à¸²à¸£à¸­à¹ˆà¸²à¸™ %lu ไบต์ à¹à¸•่ได้รับเพียง %lu" + +#: ../gio/gdbusmessage.c:1369 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "ต้องà¸à¸²à¸£à¹„บต์ NUL หลังสตริง '%s' à¹à¸•่พบไบต์ %d" + +#: ../gio/gdbusmessage.c:1388 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"ต้องà¸à¸²à¸£à¸ªà¸•ริง UTF-8 ที่ถูà¸à¸•้องตามรูปà¹à¸šà¸š à¹à¸•่พบไบต์ที่ผิดรูปà¹à¸šà¸šà¸—ี่ออฟเซ็ต %d (ความยาวของสตริงคือ " +"%d) ข้อความ UTF-8 ที่ถูà¸à¸•้องนับจนถึงจุดดังà¸à¸¥à¹ˆà¸²à¸§à¸„ือ '%s'" + +#: ../gio/gdbusmessage.c:1587 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "ค่า '%s' ที่à¹à¸ˆà¸‡à¹„ด้ไม่ใช่พาธของออบเจ็à¸à¸•์ D-Bus ที่ใช้à¸à¸²à¸£à¹„ด้" + +#: ../gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "ค่า '%s' ที่à¹à¸ˆà¸‡à¹„ด้ไม่ใช่ลายเซ็น D-Bus ที่ใช้à¸à¸²à¸£à¹„ด้" + +#: ../gio/gdbusmessage.c:1656 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "พบà¹à¸­à¸£à¹Œà¹€à¸£à¸¢à¹Œà¸„วามยาว %u ไบต์ ความยาวสูงสุดที่ใช้ได้คือ 2<<26 ไบต์ (64 MiB)" + +#: ../gio/gdbusmessage.c:1676 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "พบà¹à¸­à¸£à¹Œà¹€à¸£à¸¢à¹Œà¸Šà¸™à¸´à¸” 'a%c' ซึ่งควรมีความยาวเป็นจำนวนเท่าของ %u ไบต์ à¹à¸•่พบว่ายาว %u ไบต์" + +#: ../gio/gdbusmessage.c:1843 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "ค่า '%s' ที่à¹à¸ˆà¸‡à¹„ด้จาภvariant ไม่ใช่ลายเซ็น D-Bus ที่ใช้à¸à¸²à¸£à¹„ด้" + +#: ../gio/gdbusmessage.c:1867 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"เà¸à¸´à¸”ข้อผิดพลาดขณะถอดลำดับข้อมูล GVariant ด้วยชนิดสตริง '%s' จาà¸à¸£à¸¹à¸›à¹à¸šà¸šà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸ªà¸²à¸¢à¸‚อง D-" +"Bus" + +#: ../gio/gdbusmessage.c:2051 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "ค่าของชนิด endian ไม่ถูà¸à¸•้อง ต้องà¸à¸²à¸£ 0x6c ('l') หรือ 0x42 ('B') à¹à¸•่พบค่า 0x%02x" + +#: ../gio/gdbusmessage.c:2064 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "รุ่นหลัà¸à¸‚องโพรโทคอลไม่ถูà¸à¸•้อง ต้องà¸à¸²à¸£à¸„่า 1 à¹à¸•่พบค่า %d" + +#: ../gio/gdbusmessage.c:2120 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "พบส่วนหัวลายเซ็นซึ่งมีลายเซ็น '%s' à¹à¸•่ตัวเนื้อความว่างเปล่า" + +#: ../gio/gdbusmessage.c:2134 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "ค่า '%s' ที่à¹à¸ˆà¸‡à¹„ด้ไม่ใช่ลายเซ็น D-Bus ที่ใช้à¸à¸²à¸£à¹„ด้ (สำหรับเนื้อความ)" + +#: ../gio/gdbusmessage.c:2164 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "ไม่พบส่วนหัวลายเซ็นในข้อความ à¹à¸•่à¸à¸¥à¸±à¸šà¸¡à¸µà¹€à¸™à¸·à¹‰à¸­à¸„วามยาว %u ไบต์" + +#: ../gio/gdbusmessage.c:2174 +msgid "Cannot deserialize message: " +msgstr "ไม่สามารถถอดลำดับข้อความ: " + +#: ../gio/gdbusmessage.c:2515 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"เà¸à¸´à¸”ข้อผิดพลาดขณะเข้าลำดับข้อมูล GVariant ด้วยชนิดสตริง '%s' ไปเป็นรูปà¹à¸šà¸šà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸ªà¸²à¸¢à¸‚อง D-" +"Bus" + +#: ../gio/gdbusmessage.c:2652 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "ข้อความมี file descriptor %d อัน à¹à¸•่ข้อมูลส่วนหัวระบุ file descriptor %d อัน" + +#: ../gio/gdbusmessage.c:2660 +msgid "Cannot serialize message: " +msgstr "ไม่สามารถเข้าลำดับข้อความ: " + +#: ../gio/gdbusmessage.c:2704 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "เนื้อความมีลายเซ็น '%s' à¹à¸•่à¸à¸¥à¸±à¸šà¹„ม่มีส่วนหัวลายเซ็น" + +#: ../gio/gdbusmessage.c:2714 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "เนื้อความมีลายเซ็นของชนิดเป็น '%s' à¹à¸•่ลายเซ็นที่ส่วนหัวà¸à¸¥à¸±à¸šà¹€à¸›à¹‡à¸™ %s" + +#: ../gio/gdbusmessage.c:2730 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "เนื้อความว่างเปล่า à¹à¸•่ลายเซ็นที่ส่วนหัวเป็น '(%s)'" + +#: ../gio/gdbusmessage.c:3283 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "ได้รับข้อผิดพลาดโดยมีเนื้อความชนิด '%s'" + +#: ../gio/gdbusmessage.c:3291 +msgid "Error return with empty body" +msgstr "ได้รับข้อผิดพลาดโดยเนื้อความว่างเปล่า" + +#: ../gio/gdbusprivate.c:2038 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "อ่านโพรไฟล์ของฮาร์ดà¹à¸§à¸£à¹Œà¹„ม่สำเร็จ: %s" + +#: ../gio/gdbusprivate.c:2083 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "ไม่สามารถโหลด /var/lib/dbus/machine-id หรือ /etc/machine-id: " + +#: ../gio/gdbusproxy.c:1611 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเรียภStartServiceByName สำหรับ %s: " + +#: ../gio/gdbusproxy.c:1634 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "ได้รับคำตอบ %d ที่ไม่คาดหมายจาà¸à¹€à¸¡à¸˜à¸­à¸” StartServiceByName(\"%s\")" + +#: ../gio/gdbusproxy.c:2713 ../gio/gdbusproxy.c:2847 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"ไม่สามารถเรียà¸à¹€à¸¡à¸˜à¸­à¸” พร็อà¸à¸‹à¸µà¹ƒà¸Šà¹‰à¸ªà¸³à¸«à¸£à¸±à¸šà¸Šà¸·à¹ˆà¸­à¸—ี่เป็นที่รู้จัà¸à¹‚ดยไม่มีเจ้าของ " +"à¹à¸¥à¸°à¸žà¸£à¹‡à¸­à¸à¸‹à¸µà¸–ูà¸à¸ªà¸£à¹‰à¸²à¸‡à¸¡à¸²à¹‚ดยใช้à¹à¸Ÿà¸¥à¹‡à¸ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "ไม่รองรับ abstract name space" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "ไม่สามารถระบุà¹à¸Ÿà¹‰à¸¡à¹€à¸‰à¸žà¸²à¸°à¸à¸²à¸¥à¸‚ณะสร้างเซิร์ฟเวอร์" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเขียนà¹à¸Ÿà¹‰à¸¡à¹€à¸‰à¸žà¸²à¸°à¸à¸²à¸¥à¸—ี่ '%s': %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "สตริง '%s' ไม่ใช่ GUID ของ D-Bus ที่ใช้ได้" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "ไม่สามารถรอรับà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อผ่านช่องขนส่ง '%s' ที่ไม่รองรับ" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"คำสั่ง:\n" +" help à¹à¸ªà¸”งข้อความวิธีใช้นี้\n" +" introspect สำรวจตรวจตราออบเจ็à¸à¸•์ระยะไà¸à¸¥\n" +" monitor เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•ออบเจ็à¸à¸•์ระยะไà¸à¸¥\n" +" call เรียà¸à¹€à¸¡à¸˜à¸­à¸”ที่ออบเจ็à¸à¸•์ระยะไà¸à¸¥\n" +" emit ยิงสัà¸à¸à¸²à¸“\n" +"\n" +"ใช้ \"%s คำสั่ง --help\" เพื่อขอดูวิธีใช้ของà¹à¸•่ละคำสั่ง\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:226 ../gio/gdbus-tool.c:298 +#: ../gio/gdbus-tool.c:322 ../gio/gdbus-tool.c:724 ../gio/gdbus-tool.c:1067 +#: ../gio/gdbus-tool.c:1509 ../gio/gio-tool-rename.c:84 +#, c-format +msgid "Error: %s\n" +msgstr "ข้อผิดพลาด: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:239 ../gio/gdbus-tool.c:1525 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¹à¸ˆà¸‡ XML ของ introspection: %s\n" + +#: ../gio/gdbus-tool.c:208 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "ข้อผิดพลาด: %s ไม่ใช่ชื่อที่ใช้ได้\n" + +#: ../gio/gdbus-tool.c:356 +msgid "Connect to the system bus" +msgstr "เชื่อมต่อไปยังบัสของระบบ" + +#: ../gio/gdbus-tool.c:357 +msgid "Connect to the session bus" +msgstr "เชื่อมต่อไปยังบัสของวาระ" + +#: ../gio/gdbus-tool.c:358 +msgid "Connect to given D-Bus address" +msgstr "เชื่อมต่อไปยังที่อยู่ D-Bus ที่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gdbus-tool.c:368 +msgid "Connection Endpoint Options:" +msgstr "ตัวเลือà¸à¸ªà¸³à¸«à¸£à¸±à¸šà¸ˆà¸¸à¸”ปลายของà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ:" + +#: ../gio/gdbus-tool.c:369 +msgid "Options specifying the connection endpoint" +msgstr "ตัวเลือà¸à¸ªà¸³à¸«à¸£à¸±à¸šà¸£à¸°à¸šà¸¸à¸ˆà¸¸à¸”ปลายของà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ" + +#: ../gio/gdbus-tool.c:391 +#, c-format +msgid "No connection endpoint specified" +msgstr "ไม่ได้ระบุจุดปลายของà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ" + +#: ../gio/gdbus-tool.c:401 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸à¸ˆà¸¸à¸”ปลายของà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อหลายจุด" + +#: ../gio/gdbus-tool.c:471 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "คำเตือน: ตามข้อมูล introspection à¹à¸¥à¹‰à¸§ ไม่มีอินเทอร์เฟซ '%s' อยู่\n" + +#: ../gio/gdbus-tool.c:480 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "คำเตือน: ตามข้อมูล introspection à¹à¸¥à¹‰à¸§ ไม่มีเมธอด '%s' ในอินเทอร์เฟซ '%s'\n" + +#: ../gio/gdbus-tool.c:542 +msgid "Optional destination for signal (unique name)" +msgstr "ปลายทางของสัà¸à¸à¸²à¸“ ถ้าต้องà¸à¸²à¸£ (เป็นชื่อเอà¸à¸¥à¸±à¸à¸©à¸“์)" + +#: ../gio/gdbus-tool.c:543 +msgid "Object path to emit signal on" +msgstr "พาธของออบเจ็à¸à¸•์ที่จะยิงสัà¸à¸à¸²à¸“ไป" + +#: ../gio/gdbus-tool.c:544 +msgid "Signal and interface name" +msgstr "สัà¸à¸à¸²à¸“à¹à¸¥à¸°à¸Šà¸·à¹ˆà¸­à¸­à¸´à¸™à¹€à¸—อร์เฟซ" + +#: ../gio/gdbus-tool.c:578 +msgid "Emit a signal." +msgstr "ยิงสัà¸à¸à¸²à¸“" + +#: ../gio/gdbus-tool.c:612 ../gio/gdbus-tool.c:857 ../gio/gdbus-tool.c:1615 +#: ../gio/gdbus-tool.c:1850 +#, c-format +msgid "Error connecting: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเชื่อมต่อ: %s\n" + +#: ../gio/gdbus-tool.c:624 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "ข้อผิดพลาด: ไม่ได้ระบุพาธของออบเจ็à¸à¸•์\n" + +#: ../gio/gdbus-tool.c:629 ../gio/gdbus-tool.c:924 ../gio/gdbus-tool.c:1680 +#: ../gio/gdbus-tool.c:1916 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "ข้อผิดพลาด: %s ไม่ใช่พาธของออบเจ็à¸à¸•์ที่ใช้ได้\n" + +#: ../gio/gdbus-tool.c:635 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "ข้อผิดพลาด: ไม่ได้ระบุสัà¸à¸à¸²à¸“\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "ข้อผิดพลาด: สัà¸à¸à¸²à¸“ต้องเป็นชื่อที่มีโดเมนเต็ม\n" + +#: ../gio/gdbus-tool.c:650 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "ข้อผิดพลาด: %s ไม่ใช่ชื่ออินเทอร์เฟซที่ใช้ได้\n" + +#: ../gio/gdbus-tool.c:656 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "ข้อผิดพลาด: %s ไม่ใช่ชื่อสมาชิà¸à¸—ี่ใช้ได้\n" + +#: ../gio/gdbus-tool.c:662 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "ข้อผิดพลาด: %s ไม่ใช่ชื่อบัสที่ใช้ได้\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:699 ../gio/gdbus-tool.c:1036 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¹à¸ˆà¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์ %d: %s\n" + +#: ../gio/gdbus-tool.c:731 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะปล่อยข้อมูลคงค้างของà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ: %s\n" + +#: ../gio/gdbus-tool.c:758 +msgid "Destination name to invoke method on" +msgstr "ชื่อปลายทางที่จะเรียà¸à¹€à¸¡à¸˜à¸­à¸”" + +#: ../gio/gdbus-tool.c:759 +msgid "Object path to invoke method on" +msgstr "พาธของออบเจ็à¸à¸•์ที่จะเรียà¸à¹€à¸¡à¸˜à¸­à¸”" + +#: ../gio/gdbus-tool.c:760 +msgid "Method and interface name" +msgstr "ชื่อเมธอดà¹à¸¥à¸°à¸­à¸´à¸™à¹€à¸—อร์เฟซ" + +#: ../gio/gdbus-tool.c:761 +msgid "Timeout in seconds" +msgstr "à¸à¸³à¸«à¸™à¸”เวลาคอยเป็นวินาที" + +#: ../gio/gdbus-tool.c:802 +msgid "Invoke a method on a remote object." +msgstr "เรียà¸à¹€à¸¡à¸˜à¸­à¸”ที่ออบเจ็à¸à¸•์ระยะไà¸à¸¥" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1634 ../gio/gdbus-tool.c:1869 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "ข้อผิดพลาด: ไม่ได้ระบุปลายทาง\n" + +#: ../gio/gdbus-tool.c:889 ../gio/gdbus-tool.c:1651 ../gio/gdbus-tool.c:1881 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "ข้อผิดพลาด: %s ไม่ใช่ชื่อบัสที่ใช้ได้\n" + +#: ../gio/gdbus-tool.c:904 ../gio/gdbus-tool.c:1660 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "ข้อผิดพลาด: ไม่ได้ระบุพาธของออบเจ็à¸à¸•์\n" + +#: ../gio/gdbus-tool.c:939 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "ข้อผิดพลาด: ไม่ได้ระบุชื่อเมธอด\n" + +#: ../gio/gdbus-tool.c:950 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "ข้อผิดพลาด: ชื่อเมธอด '%s' ไม่ใช่ชื่อที่ใช้ได้\n" + +#: ../gio/gdbus-tool.c:1028 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¹à¸ˆà¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•อร์ %d ซึ่งเป็นชนิด '%s': %s\n" + +#: ../gio/gdbus-tool.c:1472 +msgid "Destination name to introspect" +msgstr "ชื่อปลายทางที่จะสำรวจตรวจตรา" + +#: ../gio/gdbus-tool.c:1473 +msgid "Object path to introspect" +msgstr "พาธของออบเจ็à¸à¸•์ที่จะสำรวจตรวจตรา" + +#: ../gio/gdbus-tool.c:1474 +msgid "Print XML" +msgstr "à¹à¸ªà¸”ง XML" + +#: ../gio/gdbus-tool.c:1475 +msgid "Introspect children" +msgstr "สำรวจตรวจตราออบเจ็à¸à¸•์ลูà¸à¸”้วย" + +#: ../gio/gdbus-tool.c:1476 +msgid "Only print properties" +msgstr "à¹à¸ªà¸”งคุณสมบัติเท่านั้น" + +#: ../gio/gdbus-tool.c:1567 +msgid "Introspect a remote object." +msgstr "สำรวจตรวจตราออบเจ็à¸à¸•์ระยะไà¸à¸¥" + +#: ../gio/gdbus-tool.c:1772 +msgid "Destination name to monitor" +msgstr "ชื่อปลายทางที่จะเà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•" + +#: ../gio/gdbus-tool.c:1773 +msgid "Object path to monitor" +msgstr "พาธของออบเจ็à¸à¸•์ที่จะเà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•" + +#: ../gio/gdbus-tool.c:1802 +msgid "Monitor a remote object." +msgstr "เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•ออบเจ็à¸à¸•์ระยะไà¸à¸¥" + +#: ../gio/gdesktopappinfo.c:1994 ../gio/gdesktopappinfo.c:4501 +msgid "Unnamed" +msgstr "ไม่มีชื่อ" + +#: ../gio/gdesktopappinfo.c:2404 +msgid "Desktop file didn't specify Exec field" +msgstr "à¹à¸Ÿà¹‰à¸¡à¹€à¸”สà¸à¹Œà¸—็อปไม่ได้ระบุเขตข้อมูล Exec" + +#: ../gio/gdesktopappinfo.c:2689 +msgid "Unable to find terminal required for application" +msgstr "หาเทอร์มินัลซึ่งต้องใช้ในà¸à¸²à¸£à¹€à¸›à¸´à¸”โปรà¹à¸à¸£à¸¡à¹„ม่พบ" + +#: ../gio/gdesktopappinfo.c:3097 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "ไม่สามารถสร้างโฟลเดอร์ %s สำหรับเà¸à¹‡à¸šà¸„่าตั้งโปรà¹à¸à¸£à¸¡à¸‚องผู้ใช้: %s" + +#: ../gio/gdesktopappinfo.c:3101 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "ไม่สามารถสร้างโฟลเดอร์ %s สำหรับเà¸à¹‡à¸šà¸„่าตั้ง MIME ของผู้ใช้: %s" + +#: ../gio/gdesktopappinfo.c:3341 ../gio/gdesktopappinfo.c:3365 +msgid "Application information lacks an identifier" +msgstr "ขาดชื่อในข้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¹‚ปรà¹à¸à¸£à¸¡" + +#: ../gio/gdesktopappinfo.c:3599 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "ไม่สามารถสร้างà¹à¸Ÿà¹‰à¸¡à¹€à¸”สà¸à¹Œà¸—็อป %s สำหรับผู้ใช้" + +#: ../gio/gdesktopappinfo.c:3733 +#, c-format +msgid "Custom definition for %s" +msgstr "ข้อà¸à¸³à¸«à¸™à¸”à¸à¸³à¸«à¸™à¸”เองสำหรับ %s" + +#: ../gio/gdrive.c:417 +msgid "drive doesn't implement eject" +msgstr "ไดรว์ไม่รองรับคำสั่งดันà¹à¸œà¹ˆà¸™à¸­à¸­à¸" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:495 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "ไดรว์ไม่รองรับคำสั่ง eject หรือ eject_with_operation" + +#: ../gio/gdrive.c:571 +msgid "drive doesn't implement polling for media" +msgstr "ไดรว์ไม่รองรับคำสั่งวนตรวจสื่อ" + +#: ../gio/gdrive.c:776 +msgid "drive doesn't implement start" +msgstr "ไดรว์ไม่รองรับคำสั่ง start" + +#: ../gio/gdrive.c:878 +msgid "drive doesn't implement stop" +msgstr "ไดรว์ไม่รองรับคำสั่ง stop" + +#: ../gio/gdummytlsbackend.c:195 ../gio/gdummytlsbackend.c:317 +#: ../gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "ไม่มีà¸à¸²à¸£à¸£à¸­à¸‡à¸£à¸±à¸š TLS" + +#: ../gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "ไม่มีà¸à¸²à¸£à¸£à¸­à¸‡à¸£à¸±à¸š DTLS" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "ไม่สามารถจัดà¸à¸²à¸£à¸à¸±à¸šà¸£à¸«à¸±à¸ªà¸‚อง GEmblem รุ่น %d ได้" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "จำนวนโทเคนในรหัสของ GEmblem (%d) ไม่ถูà¸à¸•้อง" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "ไม่สามารถจัดà¸à¸²à¸£à¸à¸±à¸šà¸£à¸«à¸±à¸ªà¸‚อง GEmblemedIcon รุ่น %d ได้" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "จำนวนโทเคนในรหัสของ GEmblemedIcon (%d) ไม่ถูà¸à¸•้อง" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "ต้องà¸à¸²à¸£à¸‚้อมูล GEmblem สำหรับ GEmblemedIcon" + +#: ../gio/gfile.c:969 ../gio/gfile.c:1207 ../gio/gfile.c:1345 +#: ../gio/gfile.c:1583 ../gio/gfile.c:1638 ../gio/gfile.c:1696 +#: ../gio/gfile.c:1780 ../gio/gfile.c:1837 ../gio/gfile.c:1901 +#: ../gio/gfile.c:1956 ../gio/gfile.c:3604 ../gio/gfile.c:3659 +#: ../gio/gfile.c:3895 ../gio/gfile.c:3937 ../gio/gfile.c:4405 +#: ../gio/gfile.c:4816 ../gio/gfile.c:4901 ../gio/gfile.c:4991 +#: ../gio/gfile.c:5088 ../gio/gfile.c:5175 ../gio/gfile.c:5276 +#: ../gio/gfile.c:7817 ../gio/gfile.c:7907 ../gio/gfile.c:7991 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "ไม่รองรับà¸à¸²à¸£à¸à¸£à¸°à¸—ำนี้" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: ../gio/gfile.c:1468 +msgid "Containing mount does not exist" +msgstr "ไม่มีจุดเมานท์ที่บรรจุà¹à¸Ÿà¹‰à¸¡à¸­à¸¢à¸¹à¹ˆ" + +#: ../gio/gfile.c:2515 ../gio/glocalfile.c:2374 +msgid "Can't copy over directory" +msgstr "ไม่สามารถคัดลอà¸à¸—ับไดเรà¸à¸—อรี" + +#: ../gio/gfile.c:2575 +msgid "Can't copy directory over directory" +msgstr "ไม่สามารถคัดลอà¸à¹„ดเรà¸à¸—อรีทับไดเรà¸à¸—อรี" + +#: ../gio/gfile.c:2583 +msgid "Target file exists" +msgstr "มีà¹à¸Ÿà¹‰à¸¡à¸›à¸¥à¸²à¸¢à¸—างอยู่à¸à¹ˆà¸­à¸™à¹à¸¥à¹‰à¸§" + +#: ../gio/gfile.c:2602 +msgid "Can't recursively copy directory" +msgstr "ไม่สามารถคัดลอà¸à¹„ดเรà¸à¸—อรีทั้งยวง" + +#: ../gio/gfile.c:2884 +msgid "Splice not supported" +msgstr "ไม่รองรับà¸à¸²à¸£à¸•่อถ่าย (splice)" + +#: ../gio/gfile.c:2888 +#, c-format +msgid "Error splicing file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะต่อถ่าย (splice) à¹à¸Ÿà¹‰à¸¡: %s" + +#: ../gio/gfile.c:3019 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "ไม่รองรับà¸à¸²à¸£à¸„ัดลอภ(เชื่อมโยง/สำเนา) à¹à¸Ÿà¹‰à¸¡à¸‚้ามอุปà¸à¸£à¸“์" + +#: ../gio/gfile.c:3023 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "ไม่รองรับà¸à¸²à¸£à¸„ัดลอภ(เชื่อมโยง/สำเนา) à¹à¸Ÿà¹‰à¸¡ หรือสั่งà¸à¸²à¸£à¹„ม่ถูà¸à¸•้อง" + +#: ../gio/gfile.c:3028 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "ไม่รองรับà¸à¸²à¸£à¸„ัดลอภ(เชื่อมโยง/สำเนา) à¹à¸Ÿà¹‰à¸¡ หรือไม่ทำงาน" + +#: ../gio/gfile.c:3091 +msgid "Can't copy special file" +msgstr "ไม่สามารถคัดลอà¸à¹à¸Ÿà¹‰à¸¡à¸žà¸´à¹€à¸¨à¸©à¹„ด้" + +#: ../gio/gfile.c:3885 +msgid "Invalid symlink value given" +msgstr "ได้รับชื่อ symlink ที่ใช้à¸à¸²à¸£à¹„ม่ได้" + +#: ../gio/gfile.c:4046 +msgid "Trash not supported" +msgstr "ไม่รองรับà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸–ังขยะ" + +#: ../gio/gfile.c:4158 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ชื่อà¹à¸Ÿà¹‰à¸¡à¸ˆà¸°à¸¡à¸µà¸­à¸±à¸à¸‚ระ '%c' ไม่ได้" + +#: ../gio/gfile.c:6604 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "โวลุมไม่รองรับà¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์" + +#: ../gio/gfile.c:6713 +msgid "No application is registered as handling this file" +msgstr "ไม่มีโปรà¹à¸à¸£à¸¡à¸—ี่ลงทะเบียนสำหรับจัดà¸à¸²à¸£à¹à¸Ÿà¹‰à¸¡à¸›à¸£à¸°à¹€à¸ à¸—นี้ไว้" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "ตัวà¹à¸ˆà¸‡à¸™à¸±à¸šà¸–ูà¸à¸›à¸´à¸”" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "ตัวà¹à¸ˆà¸‡à¸™à¸±à¸šà¹à¸Ÿà¹‰à¸¡à¸¡à¸µà¸à¸²à¸£à¸à¸£à¸°à¸—ำค้างอยู่" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "ตัวà¹à¸ˆà¸‡à¸™à¸±à¸šà¹à¸Ÿà¹‰à¸¡à¸–ูà¸à¸›à¸´à¸”ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "ไม่สามารถจัดà¸à¸²à¸£à¸à¸±à¸šà¸£à¸«à¸±à¸ªà¸‚อง GFileIcon รุ่น %d ได้" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "ข้อมูลเข้าของ GFileIcon ผิดรูปà¹à¸šà¸š" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "สตรีมไม่รองรับ query_info" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "สตรีมไม่รองรับà¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸­à¸™à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸­à¹ˆà¸²à¸™à¹€à¸‚ียน" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "สตรีมข้อมูลเข้าไม่สามารถตัดท้ายทิ้งได้" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "สตรีมไม่รองรับà¸à¸²à¸£à¸•ัดท้ายทิ้ง" + +#: ../gio/ghttpproxy.c:136 +msgid "Bad HTTP proxy reply" +msgstr "พบคำตอบที่ผิดรูปà¹à¸šà¸šà¸ˆà¸²à¸à¸žà¸£à¹‡à¸­à¸à¸‹à¸µ HTTP" + +#: ../gio/ghttpproxy.c:152 +msgid "HTTP proxy connection not allowed" +msgstr "ไม่ได้รับอนุà¸à¸²à¸•ให้เชื่อมต่อพร็อà¸à¸‹à¸µ HTTP" + +#: ../gio/ghttpproxy.c:157 +msgid "HTTP proxy authentication failed" +msgstr "ยืนยันตัวบุคคลà¸à¸±à¸šà¸žà¸£à¹‡à¸­à¸à¸‹à¸µ HTTP ไม่สำเร็จ" + +#: ../gio/ghttpproxy.c:160 +msgid "HTTP proxy authentication required" +msgstr "พร็อà¸à¸‹à¸µ HTTP ต้องà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•ัวบุคคล" + +#: ../gio/ghttpproxy.c:164 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "เชื่อมต่อพร็อà¸à¸‹à¸µ HTTP ไม่สำเร็จ: %i" + +#: ../gio/ghttpproxy.c:260 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "เซิร์ฟเวอร์พร็อà¸à¸‹à¸µ HTTP ปิดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อà¸à¸°à¸—ันหัน" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "จำนวนโทเคน (%d) ไม่ถูà¸à¸•้อง" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "ไม่มีชนิดสำหรับคลาสชื่อ %s" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "ชนิด %s ไม่ได้ทำอินเทอร์เฟซ GIcon" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "ชนิด %s ไม่ได้เป็นคลาส" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "เลขรุ่นมีรูปà¹à¸šà¸šà¹„ม่ถูà¸à¸•้อง: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "ชนิด %s ไม่ได้ทำ from_tokens() ของอินเทอร์เฟซ GIcon" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "ไม่สามารถจัดà¸à¸²à¸£à¸à¸±à¸šà¸£à¸«à¸±à¸ªà¸‚องไอคอนรุ่นที่ระบุได้" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "ไม่ได้ระบุที่อยู่" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "ความยาว %u ยาวเà¸à¸´à¸™à¹„ปสำหรับที่อยู่" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ที่อยู่มีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”บิตที่เà¸à¸´à¸™à¸„วามยาวของ prefix" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "ไม่สามารถà¹à¸ˆà¸‡ '%s' ในà¸à¸²à¸™à¸°à¹à¸¡à¸ªà¸à¹Œà¸‚องที่อยู่ไอพี" + +#: ../gio/ginetsocketaddress.c:203 ../gio/ginetsocketaddress.c:220 +#: ../gio/gnativesocketaddress.c:106 ../gio/gunixsocketaddress.c:216 +msgid "Not enough space for socket address" +msgstr "มีที่ว่างไม่พอสำหรับที่อยู่ซ็อà¸à¹€à¸à¹‡à¸•" + +#: ../gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "ไม่รองรับที่อยู่ซ็อà¸à¹€à¸à¹‡à¸•" + +#: ../gio/ginputstream.c:188 +msgid "Input stream doesn't implement read" +msgstr "สตรีมข้อมูลเข้ายังไม่รองรับà¸à¸²à¸£à¸­à¹ˆà¸²à¸™" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1218 ../gio/giostream.c:310 +#: ../gio/goutputstream.c:1670 +msgid "Stream has outstanding operation" +msgstr "สตรีมมีà¸à¸²à¸£à¸à¸£à¸°à¸—ำค้างอยู่" + +#: ../gio/gio-tool.c:142 +msgid "Copy with file" +msgstr "คัดลอà¸à¹„ปพร้อมà¸à¸±à¸šà¹à¸Ÿà¹‰à¸¡" + +#: ../gio/gio-tool.c:146 +msgid "Keep with file when moved" +msgstr "ติดตามไปà¸à¸±à¸šà¹à¸Ÿà¹‰à¸¡à¹€à¸¡à¸·à¹ˆà¸­à¸¢à¹‰à¸²à¸¢" + +#: ../gio/gio-tool.c:187 +msgid "'version' takes no arguments" +msgstr "'version' ไม่รับอาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์" + +#: ../gio/gio-tool.c:189 ../gio/gio-tool.c:205 ../glib/goption.c:857 +msgid "Usage:" +msgstr "วิธีใช้:" + +#: ../gio/gio-tool.c:192 +msgid "Print version information and exit." +msgstr "à¹à¸ªà¸”งรุ่นของโปรà¹à¸à¸£à¸¡à¹à¸¥à¹‰à¸§à¸ˆà¸šà¸à¸²à¸£à¸—ำงาน" + +#: ../gio/gio-tool.c:208 +msgid "Commands:" +msgstr "คำสั่ง:" + +#: ../gio/gio-tool.c:211 +msgid "Concatenate files to standard output" +msgstr "à¹à¸ªà¸”งà¹à¸Ÿà¹‰à¸¡à¸•่างๆ ต่อà¸à¸±à¸™à¸­à¸­à¸à¸—างเอาต์พุตมาตรà¸à¸²à¸™" + +#: ../gio/gio-tool.c:212 +msgid "Copy one or more files" +msgstr "คัดลอà¸à¹à¸Ÿà¹‰à¸¡à¸•ั้งà¹à¸•่หนึ่งà¹à¸Ÿà¹‰à¸¡à¸‚ึ้นไป" + +#: ../gio/gio-tool.c:213 +msgid "Show information about locations" +msgstr "à¹à¸ªà¸”งข้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gio-tool.c:214 +msgid "List the contents of locations" +msgstr "à¹à¸ªà¸”งเนื้อหาของตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gio-tool.c:215 +msgid "Get or set the handler for a mimetype" +msgstr "อ่านหรือตั้งค่าตัวจัดà¸à¸²à¸£à¸ªà¸³à¸«à¸£à¸±à¸š mimetype" + +#: ../gio/gio-tool.c:216 +msgid "Create directories" +msgstr "สร้างไดเรà¸à¸—อรี" + +#: ../gio/gio-tool.c:217 +msgid "Monitor files and directories for changes" +msgstr "เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸‚องà¹à¸Ÿà¹‰à¸¡à¹à¸¥à¸°à¹„ดเรà¸à¸—อรี" + +#: ../gio/gio-tool.c:218 +msgid "Mount or unmount the locations" +msgstr "เมานท์หรือเลิà¸à¹€à¸¡à¸²à¸™à¸—์ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gio-tool.c:219 +msgid "Move one or more files" +msgstr "ย้ายà¹à¸Ÿà¹‰à¸¡à¸•ั้งà¹à¸•่หนึ่งà¹à¸Ÿà¹‰à¸¡à¸‚ึ้นไป" + +#: ../gio/gio-tool.c:220 +msgid "Open files with the default application" +msgstr "เปิดà¹à¸Ÿà¹‰à¸¡à¸”้วยโปรà¹à¸à¸£à¸¡à¸›à¸£à¸´à¸¢à¸²à¸¢" + +#: ../gio/gio-tool.c:221 +msgid "Rename a file" +msgstr "เปลี่ยนชื่อà¹à¸Ÿà¹‰à¸¡" + +#: ../gio/gio-tool.c:222 +msgid "Delete one or more files" +msgstr "ลบà¹à¸Ÿà¹‰à¸¡à¸•ั้งà¹à¸•่หนึ่งà¹à¸Ÿà¹‰à¸¡à¸‚ึ้นไป" + +#: ../gio/gio-tool.c:223 +msgid "Read from standard input and save" +msgstr "อ่านจาà¸à¸­à¸´à¸™à¸žà¸¸à¸•มาตรà¸à¸²à¸™à¹à¸¥à¸°à¸šà¸±à¸™à¸—ึà¸" + +#: ../gio/gio-tool.c:224 +msgid "Set a file attribute" +msgstr "à¸à¸³à¸«à¸™à¸”à¹à¸­à¸•ทริบิวต์ของà¹à¸Ÿà¹‰à¸¡" + +#: ../gio/gio-tool.c:225 +msgid "Move files or directories to the trash" +msgstr "ย้ายà¹à¸Ÿà¹‰à¸¡à¸«à¸£à¸·à¸­à¹„ดเรà¸à¸—อรีไปลงถังขยะ" + +#: ../gio/gio-tool.c:226 +msgid "Lists the contents of locations in a tree" +msgstr "à¹à¸ªà¸”งเนื้อหาของตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸³à¸«à¸™à¸”ในà¹à¸šà¸šà¸•้นไม้" + +#: ../gio/gio-tool.c:228 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "สั่ง %s เพื่อดูรายละเอียดวิธีใช้\n" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-cat.c:124 ../gio/gio-tool-info.c:278 +#: ../gio/gio-tool-list.c:165 ../gio/gio-tool-mkdir.c:48 +#: ../gio/gio-tool-monitor.c:37 ../gio/gio-tool-monitor.c:39 +#: ../gio/gio-tool-monitor.c:41 ../gio/gio-tool-monitor.c:43 +#: ../gio/gio-tool-monitor.c:202 ../gio/gio-tool-mount.c:1132 +#: ../gio/gio-tool-open.c:45 ../gio/gio-tool-remove.c:48 +#: ../gio/gio-tool-rename.c:45 ../gio/gio-tool-set.c:89 +#: ../gio/gio-tool-trash.c:81 ../gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡" + +#: ../gio/gio-tool-cat.c:129 +msgid "Concatenate files and print to standard output." +msgstr "พิมพ์เนื้อหาของà¹à¸Ÿà¹‰à¸¡à¸•่างๆ เรียงต่อà¸à¸±à¸™à¸­à¸­à¸à¸—างเอาต์พุตมาตรà¸à¸²à¸™" + +#: ../gio/gio-tool-cat.c:131 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat ทำงานเหมือนà¸à¸±à¸š cat ดั้งเดิม à¹à¸•่ใช้ตำà¹à¸«à¸™à¹ˆà¸‡ GIO\n" +"à¹à¸—นà¹à¸Ÿà¹‰à¸¡à¹ƒà¸™à¹€à¸„รื่อง: ตัวอย่างเช่น คุณสามารถใช้ตำà¹à¸«à¸™à¹ˆà¸‡à¸­à¸¢à¹ˆà¸²à¸‡\n" +"smb://server/resource/file.txt ได้" + +#: ../gio/gio-tool-cat.c:151 +msgid "No files given" +msgstr "ไม่ได้ระบุà¹à¸Ÿà¹‰à¸¡à¹ƒà¸”ๆ" + +#: ../gio/gio-tool-copy.c:42 ../gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "ไม่มีไดเรà¸à¸—อรีปลายทาง" + +#: ../gio/gio-tool-copy.c:43 ../gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "à¹à¸ªà¸”งความคืบหน้า" + +#: ../gio/gio-tool-copy.c:44 ../gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "ถามà¸à¹ˆà¸­à¸™à¹€à¸‚ียนทับ" + +#: ../gio/gio-tool-copy.c:45 +msgid "Preserve all attributes" +msgstr "รัà¸à¸©à¸²à¹à¸­à¸•ทริบิวต์ไว้ทั้งหมด" + +#: ../gio/gio-tool-copy.c:46 ../gio/gio-tool-move.c:41 +#: ../gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "สำรองà¹à¸Ÿà¹‰à¸¡à¸›à¸¥à¸²à¸¢à¸—างที่มีอยู่เดิมด้วย" + +#: ../gio/gio-tool-copy.c:47 +msgid "Never follow symbolic links" +msgstr "ไม่ต้องเดินไปตามลิงà¸à¹Œà¸ªà¸±à¸à¸¥à¸±à¸à¸©à¸“์" + +#: ../gio/gio-tool-copy.c:72 ../gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "ถ่ายโอนà¹à¸¥à¹‰à¸§ %s จาภ%s (%s/s)" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ต้นทาง" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-copy.c:98 ../gio/gio-tool-move.c:94 +#: ../gio/gio-tool-save.c:165 +msgid "DESTINATION" +msgstr "ปลายทาง" + +#: ../gio/gio-tool-copy.c:103 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "คัดลอà¸à¹à¸Ÿà¹‰à¸¡à¸•ั้งà¹à¸•่หนึ่งà¹à¸Ÿà¹‰à¸¡à¸‚ึ้นไปจาภ\"ต้นทาง\" ไปยัง \"ปลายทาง\"" + +#: ../gio/gio-tool-copy.c:105 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy ทำงานคล้ายà¸à¸±à¸š cp ดั้งเดิม à¹à¸•่ใช้ตำà¹à¸«à¸™à¹ˆà¸‡ GIO\n" +"à¹à¸—นà¹à¸Ÿà¹‰à¸¡à¹ƒà¸™à¹€à¸„รื่อง: ตัวอย่างเช่น คุณสามารถใช้ตำà¹à¸«à¸™à¹ˆà¸‡à¸­à¸¢à¹ˆà¸²à¸‡\n" +"smb://server/resource/file.txt ได้" + +#: ../gio/gio-tool-copy.c:143 +#, c-format +msgid "Destination %s is not a directory" +msgstr "ปลายทาง %s ไม่ใช่ไดเรà¸à¸—อรี" + +#: ../gio/gio-tool-copy.c:187 ../gio/gio-tool-move.c:181 +#, c-format +msgid "%s: overwrite '%s'? " +msgstr "%s: เขียนทับ '%s' หรือไม่? " + +#: ../gio/gio-tool-info.c:34 +msgid "List writable attributes" +msgstr "à¹à¸ªà¸”งà¹à¸­à¸•ทริบิวต์ที่เขียนได้" + +#: ../gio/gio-tool-info.c:35 +msgid "Get file system info" +msgstr "อ่านข้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸£à¸°à¸šà¸šà¹à¸Ÿà¹‰à¸¡" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "The attributes to get" +msgstr "à¹à¸­à¸•ทริบิวต์ต่างๆ ที่จะอ่าน" + +#: ../gio/gio-tool-info.c:36 ../gio/gio-tool-list.c:35 +msgid "ATTRIBUTES" +msgstr "à¹à¸­à¸•ทริบิวต์" + +#: ../gio/gio-tool-info.c:37 ../gio/gio-tool-list.c:38 ../gio/gio-tool-set.c:34 +msgid "Don't follow symbolic links" +msgstr "ไม่เดินไปตามลิงà¸à¹Œà¸ªà¸±à¸à¸¥à¸±à¸à¸©à¸“์" + +#: ../gio/gio-tool-info.c:75 +#, c-format +msgid "attributes:\n" +msgstr "à¹à¸­à¸•ทริบิวต์:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:127 +#, c-format +msgid "display name: %s\n" +msgstr "ชื่อสำหรับà¹à¸ªà¸”งผล: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: ../gio/gio-tool-info.c:132 +#, c-format +msgid "edit name: %s\n" +msgstr "ชื่อสำหรับà¹à¸à¹‰à¹„ข: %s\n" + +#: ../gio/gio-tool-info.c:138 +#, c-format +msgid "name: %s\n" +msgstr "ชื่อ: %s\n" + +#: ../gio/gio-tool-info.c:145 +#, c-format +msgid "type: %s\n" +msgstr "ชนิด: %s\n" + +#: ../gio/gio-tool-info.c:151 +#, c-format +msgid "size: " +msgstr "ขนาด: " + +#: ../gio/gio-tool-info.c:156 +#, c-format +msgid "hidden\n" +msgstr "ซ่อน\n" + +#: ../gio/gio-tool-info.c:159 +#, c-format +msgid "uri: %s\n" +msgstr "URI: %s\n" + +#: ../gio/gio-tool-info.c:221 +#, c-format +msgid "Error getting writable attributes: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านข้อมูลà¹à¸­à¸•ทริบิวต์ที่เขียนได้: %s\n" + +#: ../gio/gio-tool-info.c:226 +#, c-format +msgid "Settable attributes:\n" +msgstr "à¹à¸­à¸•ทริบิวต์ที่à¸à¸³à¸«à¸™à¸”ค่าได้:\n" + +#: ../gio/gio-tool-info.c:249 +#, c-format +msgid "Writable attribute namespaces:\n" +msgstr "namespace ของà¹à¸­à¸•ทริบิวต์ที่เขียนได้:\n" + +#: ../gio/gio-tool-info.c:283 +msgid "Show information about locations." +msgstr "à¹à¸ªà¸”งข้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸•ำà¹à¸«à¸™à¹ˆà¸‡" + +#: ../gio/gio-tool-info.c:285 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by '*', which matches all attributes" +msgstr "" +"gio info ทำงานคล้ายà¸à¸±à¸š ls ดั้งเดิม à¹à¸•่ใช้ตำà¹à¸«à¸™à¹ˆà¸‡ GIO\n" +"à¹à¸—นà¹à¸Ÿà¹‰à¸¡à¹ƒà¸™à¹€à¸„รื่อง: ตัวอย่างเช่น คุณสามารถใช้ตำà¹à¸«à¸™à¹ˆà¸‡à¸­à¸¢à¹ˆà¸²à¸‡\n" +"smb://server/resource/file.txt ได้ à¹à¸­à¸•ทริบิวต์ของà¹à¸Ÿà¹‰à¸¡\n" +"สามารถระบุด้วยชื่อ GIO เช่น standard::icon หรือเพียงà¹à¸„่\n" +"namespace เช่น unix หรือใช้ '*' ซึ่งจะหมายถึงà¹à¸­à¸•ทริบิวต์ทั้งหมด" + +#: ../gio/gio-tool-info.c:307 ../gio/gio-tool-mkdir.c:74 +msgid "No locations given" +msgstr "ไม่ได้ระบุตำà¹à¸«à¸™à¹ˆà¸‡à¹ƒà¸”ๆ" + +#: ../gio/gio-tool-list.c:36 ../gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "à¹à¸ªà¸”งà¹à¸Ÿà¹‰à¸¡à¸‹à¹ˆà¸­à¸™" + +#: ../gio/gio-tool-list.c:37 +msgid "Use a long listing format" +msgstr "ใช้รูปà¹à¸šà¸šà¸£à¸²à¸¢à¸à¸²à¸£à¹à¸šà¸šà¸¢à¸²à¸§" + +#: ../gio/gio-tool-list.c:39 +msgid "Print full URIs" +msgstr "พิมพ์ URI à¹à¸šà¸šà¹€à¸•็ม" + +#: ../gio/gio-tool-list.c:170 +msgid "List the contents of the locations." +msgstr "à¹à¸ªà¸”งเนื้อหาของตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gio-tool-list.c:172 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list ทำงานคล้ายà¸à¸±à¸š ls ดั้งเดิม à¹à¸•่ใช้ตำà¹à¸«à¸™à¹ˆà¸‡ GIO\n" +"à¹à¸—นà¹à¸Ÿà¹‰à¸¡à¹ƒà¸™à¹€à¸„รื่อง: ตัวอย่างเช่น คุณสามารถใช้ตำà¹à¸«à¸™à¹ˆà¸‡à¸­à¸¢à¹ˆà¸²à¸‡\n" +"smb://server/resource/file.txt ได้ à¹à¸­à¸•ทริบิวต์ของà¹à¸Ÿà¹‰à¸¡\n" +"สามารถระบุด้วยชื่อ GIO เช่น standard::icon" + +#. Translators: commandline placeholder +#: ../gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: ../gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "ตัวจัดà¸à¸²à¸£" + +#: ../gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "อ่านหรือตั้งค่าตัวจัดà¸à¸²à¸£à¸ªà¸³à¸«à¸£à¸±à¸š mimetype" + +#: ../gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"ถ้าไม่ได้ระบุตัวจัดà¸à¸²à¸£ จะà¹à¸ªà¸”งรายชื่อโปรà¹à¸à¸£à¸¡à¸—ี่ลงทะเบียนไว้à¹à¸¥à¸°à¸—ี่à¹à¸™à¸°à¸™à¸³\n" +"สำหรับ mimetype ที่à¸à¸³à¸«à¸™à¸” ถ้าระบุตัวจัดà¸à¸²à¸£ จะà¸à¸³à¸«à¸™à¸”ตัวจัดà¸à¸²à¸£à¸™à¸±à¹‰à¸™\n" +"เป็นตัวจัดà¸à¸²à¸£à¸›à¸£à¸´à¸¢à¸²à¸¢à¸ªà¸³à¸«à¸£à¸±à¸š mimetype ที่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gio-tool-mime.c:98 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "ต้องระบุ mimetype รายà¸à¸²à¸£à¹€à¸”ียว à¹à¸¥à¸°à¸­à¸²à¸ˆà¸£à¸°à¸šà¸¸à¸•ัวจัดà¸à¸²à¸£à¸”้วย" + +#: ../gio/gio-tool-mime.c:113 +#, c-format +msgid "No default applications for '%s'\n" +msgstr "ไม่มีโปรà¹à¸à¸£à¸¡à¸›à¸£à¸´à¸¢à¸²à¸¢à¸ªà¸³à¸«à¸£à¸±à¸š '%s'\n" + +#: ../gio/gio-tool-mime.c:119 +#, c-format +msgid "Default application for '%s': %s\n" +msgstr "โปรà¹à¸à¸£à¸¡à¸›à¸£à¸´à¸¢à¸²à¸¢à¸ªà¸³à¸«à¸£à¸±à¸š '%s': %s\n" + +#: ../gio/gio-tool-mime.c:124 +#, c-format +msgid "Registered applications:\n" +msgstr "โปรà¹à¸à¸£à¸¡à¸—ี่ลงทะเบียนไว้:\n" + +#: ../gio/gio-tool-mime.c:126 +#, c-format +msgid "No registered applications\n" +msgstr "ไม่มีโปรà¹à¸à¸£à¸¡à¸—ี่ลงทะเบียนไว้\n" + +#: ../gio/gio-tool-mime.c:137 +#, c-format +msgid "Recommended applications:\n" +msgstr "โปรà¹à¸à¸£à¸¡à¸—ี่à¹à¸™à¸°à¸™à¸³:\n" + +#: ../gio/gio-tool-mime.c:139 +#, c-format +msgid "No recommended applications\n" +msgstr "ไม่มีโปรà¹à¸à¸£à¸¡à¸—ี่à¹à¸™à¸°à¸™à¸³\n" + +#: ../gio/gio-tool-mime.c:159 +#, c-format +msgid "Failed to load info for handler '%s'\n" +msgstr "โหลดข้อมูลสำหรับตัวจัดà¸à¸²à¸£ '%s' ไม่สำเร็จ\n" + +#: ../gio/gio-tool-mime.c:165 +#, c-format +msgid "Failed to set '%s' as the default handler for '%s': %s\n" +msgstr "à¸à¸³à¸«à¸™à¸” '%s' เป็นตัวจัดà¸à¸²à¸£à¸›à¸£à¸´à¸¢à¸²à¸¢à¸ªà¸³à¸«à¸£à¸±à¸š '%s' ไม่สำเร็จ: %s\n" + +#: ../gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "สร้างไดเรà¸à¸—อรีà¹à¸¡à¹ˆà¸”้วย" + +#: ../gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "สร้างไดเรà¸à¸—อรี" + +#: ../gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir ทำงานคล้ายà¸à¸±à¸š mkdir ดั้งเดิม à¹à¸•่ใช้ตำà¹à¸«à¸™à¹ˆà¸‡ GIO\n" +"à¹à¸—นà¹à¸Ÿà¹‰à¸¡à¹ƒà¸™à¹€à¸„รื่อง: ตัวอย่างเช่น คุณสามารถใช้ตำà¹à¸«à¸™à¹ˆà¸‡à¸­à¸¢à¹ˆà¸²à¸‡\n" +"smb://server/resource/mydir ได้" + +#: ../gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•ไดเรà¸à¸—อรี (ค่าปริยาย: ขึ้นอยู่à¸à¸±à¸šà¸Šà¸™à¸´à¸”)" + +#: ../gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•à¹à¸Ÿà¹‰à¸¡ (ค่าปริยาย: ขึ้นอยู่à¸à¸±à¸šà¸Šà¸™à¸´à¸”)" + +#: ../gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•à¹à¸Ÿà¹‰à¸¡à¹‚ดยตรง (สังเà¸à¸•à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸—ี่เà¸à¸´à¸”ขึ้นโดยทาง hardlink)" + +#: ../gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn't report changes" +msgstr "เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•à¹à¸Ÿà¹‰à¸¡à¹‚ดยตรง à¹à¸•่ไม่รายงานà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡" + +#: ../gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "รายงานà¸à¸²à¸£à¸¢à¹‰à¸²à¸¢à¹à¸¥à¸°à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸Šà¸·à¹ˆà¸­à¹€à¸›à¹‡à¸™à¹€à¸«à¸•ุà¸à¸²à¸£à¸“์à¸à¸²à¸£à¸¥à¸š/สร้างอย่างง่าย" + +#: ../gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "เà¸à¹‰à¸²à¸”ูเหตุà¸à¸²à¸£à¸“์à¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์" + +#: ../gio/gio-tool-monitor.c:207 +msgid "Monitor files or directories for changes." +msgstr "เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•à¹à¸Ÿà¹‰à¸¡à¸«à¸£à¸·à¸­à¹„ดเรà¸à¸—อรีเพื่อดูà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡" + +#: ../gio/gio-tool-mount.c:58 +msgid "Mount as mountable" +msgstr "เมาทน์ตามที่à¸à¸³à¸«à¸™à¸”ให้เมานท์ได้" + +#: ../gio/gio-tool-mount.c:59 +msgid "Mount volume with device file" +msgstr "เมาทน์โวลุมด้วยà¹à¸Ÿà¹‰à¸¡à¸­à¸¸à¸›à¸à¸£à¸“์" + +#: ../gio/gio-tool-mount.c:59 +msgid "DEVICE" +msgstr "DEVICE" + +#: ../gio/gio-tool-mount.c:60 +msgid "Unmount" +msgstr "เลิà¸à¹€à¸¡à¸²à¸™à¸—์" + +#: ../gio/gio-tool-mount.c:61 +msgid "Eject" +msgstr "เอาสื่อออà¸" + +#: ../gio/gio-tool-mount.c:62 +msgid "Unmount all mounts with the given scheme" +msgstr "เลิà¸à¹€à¸¡à¸²à¸™à¸—์จุดเมานท์ทั้งหมดที่มี scheme ที่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gio-tool-mount.c:62 +msgid "SCHEME" +msgstr "SCHEME" + +#: ../gio/gio-tool-mount.c:63 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "ละเลยà¸à¸²à¸£à¸à¸£à¸°à¸—ำสำคัà¸à¸à¸±à¸šà¹à¸Ÿà¹‰à¸¡à¸‚ณะเลิà¸à¹€à¸¡à¸²à¸™à¸—์หรือเอาสื่อออà¸" + +#: ../gio/gio-tool-mount.c:64 +msgid "Use an anonymous user when authenticating" +msgstr "ใช้ผู้ใช้นิรนามในà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•ัวบุคคล" + +#. Translator: List here is a verb as in 'List all mounts' +#: ../gio/gio-tool-mount.c:66 +msgid "List" +msgstr "à¹à¸ªà¸”งรายชื่อ" + +#: ../gio/gio-tool-mount.c:67 +msgid "Monitor events" +msgstr "เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•เหตุà¸à¸²à¸£à¸“์ต่างๆ" + +#: ../gio/gio-tool-mount.c:68 +msgid "Show extra information" +msgstr "à¹à¸ªà¸”งข้อมูลเพิ่มเติม" + +#: ../gio/gio-tool-mount.c:246 ../gio/gio-tool-mount.c:276 +#, c-format +msgid "Error mounting location: Anonymous access denied\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเมานท์ตำà¹à¸«à¸™à¹ˆà¸‡: à¸à¸²à¸£à¹€à¸‚้าถึงà¹à¸šà¸šà¸™à¸´à¸£à¸™à¸²à¸¡à¸–ูà¸à¸›à¸à¸´à¹€à¸ªà¸˜\n" + +#: ../gio/gio-tool-mount.c:248 ../gio/gio-tool-mount.c:278 +#, c-format +msgid "Error mounting location: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเมานท์ตำà¹à¸«à¸™à¹ˆà¸‡: %s\n" + +#: ../gio/gio-tool-mount.c:341 +#, c-format +msgid "Error unmounting mount: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเลิà¸à¹€à¸¡à¸²à¸™à¸—์จุดเมานท์: %s\n" + +#: ../gio/gio-tool-mount.c:366 ../gio/gio-tool-mount.c:419 +#, c-format +msgid "Error finding enclosing mount: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะหาจุดเมานท์ที่บรรจุ: %s\n" + +#: ../gio/gio-tool-mount.c:394 +#, c-format +msgid "Error ejecting mount: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเอาสื่อที่จุดเมานท์ออà¸: %s\n" + +#: ../gio/gio-tool-mount.c:875 +#, c-format +msgid "Error mounting %s: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเมานท์ %s: %s\n" + +#: ../gio/gio-tool-mount.c:891 +#, c-format +msgid "Mounted %s at %s\n" +msgstr "เมานท์ %s ที่ %s à¹à¸¥à¹‰à¸§\n" + +#: ../gio/gio-tool-mount.c:941 +#, c-format +msgid "No volume for device file %s\n" +msgstr "ไม่มีโวลุมสำหรับà¹à¸Ÿà¹‰à¸¡à¸­à¸¸à¸›à¸à¸£à¸“์ %s\n" + +#: ../gio/gio-tool-mount.c:1136 +msgid "Mount or unmount the locations." +msgstr "เมานท์หรือเลิà¸à¹€à¸¡à¸²à¸™à¸—์ตำà¹à¸«à¸™à¹ˆà¸‡" + +#: ../gio/gio-tool-move.c:42 +msgid "Don't use copy and delete fallback" +msgstr "ไม่ใช้วิธีà¸à¸²à¸£à¸ªà¸³à¸£à¸­à¸‡à¸”้วยà¸à¸²à¸£à¸„ัดลอà¸à¹à¸¥à¸°à¸¥à¸š" + +#: ../gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "ย้ายà¹à¸Ÿà¹‰à¸¡à¸•ั้งà¹à¸•่หนึ่งà¹à¸Ÿà¹‰à¸¡à¸‚ึ้นไปจาภ\"ต้นทาง\" ไปยัง \"ปลายทาง\"" + +#: ../gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move ทำงานคล้ายà¸à¸±à¸š mv ดั้งเดิม à¹à¸•่ใช้ตำà¹à¸«à¸™à¹ˆà¸‡ GIO\n" +"à¹à¸—นà¹à¸Ÿà¹‰à¸¡à¹ƒà¸™à¹€à¸„รื่อง: ตัวอย่างเช่น คุณสามารถใช้ตำà¹à¸«à¸™à¹ˆà¸‡à¸­à¸¢à¹ˆà¸²à¸‡\n" +"smb://server/resource/file.txt ได้" + +#: ../gio/gio-tool-move.c:139 +#, c-format +msgid "Target %s is not a directory" +msgstr "ปลายทาง %s ไม่ใช่ไดเรà¸à¸—อรี" + +#: ../gio/gio-tool-open.c:50 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"เปิดà¹à¸Ÿà¹‰à¸¡à¸”้วยโปรà¹à¸à¸£à¸¡à¸›à¸£à¸´à¸¢à¸²à¸¢à¸—ี่ลงทะเบียนไว้\n" +"สำหรับจัดà¸à¸²à¸£à¹à¸Ÿà¹‰à¸¡à¸Šà¸™à¸´à¸”นี้" + +#: ../gio/gio-tool-open.c:69 +msgid "No files to open" +msgstr "ไม่มีà¹à¸Ÿà¹‰à¸¡à¸—ี่จะเปิด" + +#: ../gio/gio-tool-remove.c:31 ../gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "ไม่ต้องสนใจà¹à¸Ÿà¹‰à¸¡à¸—ี่ไม่มีอยู่ ไม่ต้องถาม" + +#: ../gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "ลบà¹à¸Ÿà¹‰à¸¡à¸—ี่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gio-tool-remove.c:70 +msgid "No files to delete" +msgstr "ไม่มีà¹à¸Ÿà¹‰à¸¡à¸—ี่จะลบ" + +#: ../gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "ชื่อ" + +#: ../gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "เปลี่ยนชื่อà¹à¸Ÿà¹‰à¸¡" + +#: ../gio/gio-tool-rename.c:68 +msgid "Missing argument" +msgstr "อาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์ไม่ครบ" + +#: ../gio/gio-tool-rename.c:73 ../gio/gio-tool-save.c:192 +#: ../gio/gio-tool-set.c:134 +msgid "Too many arguments" +msgstr "อาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์เà¸à¸´à¸™" + +#: ../gio/gio-tool-rename.c:91 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "เปลี่ยนชื่อสำเร็จà¹à¸¥à¹‰à¸§ URI ใหม่: %s\n" + +#: ../gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "สร้างเมื่อไม่มีอยู่เท่านั้น" + +#: ../gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "เขียนต่อท้ายà¹à¸Ÿà¹‰à¸¡" + +#: ../gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "เมื่อสร้างà¹à¸Ÿà¹‰à¸¡ ให้จำà¸à¸±à¸”à¸à¸²à¸£à¹€à¸‚้าถึงเฉพาะสำหรับผู้ใช้ปัจจุบัน" + +#: ../gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "เมื่อà¹à¸—นที่ ให้à¹à¸—นที่เสมือนหนึ่งปลายทางไม่มีอยู่" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "พิมพ์ etag ค่าใหม่เมื่อจบà¸à¸²à¸£à¸—ำงาน" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "etag ของà¹à¸Ÿà¹‰à¸¡à¸—ี่จะถูà¸à¹€à¸‚ียนทับ" + +#: ../gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: ../gio/gio-tool-save.c:145 +#, c-format +msgid "Etag not available\n" +msgstr "à¹à¸Ÿà¹‰à¸¡à¹„ม่มี etag\n" + +#: ../gio/gio-tool-save.c:168 +msgid "Read from standard input and save to DEST." +msgstr "อ่านข้อมูลจาà¸à¸­à¸´à¸™à¸žà¸¸à¸•มาตรà¸à¸²à¸™à¹à¸¥à¹‰à¸§à¸šà¸±à¸™à¸—ึà¸à¸¥à¸‡ \"ปลายทาง\"" + +#: ../gio/gio-tool-save.c:186 +msgid "No destination given" +msgstr "ไม่ได้ระบุปลายทาง" + +#: ../gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "ชนิดของà¹à¸­à¸•ทริบิวต์" + +#: ../gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "ชนิด" + +#: ../gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "à¹à¸­à¸•ทริบิวต์" + +#: ../gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "ค่า" + +#: ../gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "à¸à¸³à¸«à¸™à¸”à¹à¸­à¸•ทริบิวต์à¹à¸Ÿà¹‰à¸¡à¸‚องตำà¹à¸«à¸™à¹ˆà¸‡" + +#: ../gio/gio-tool-set.c:111 +msgid "Location not specified" +msgstr "ไม่ได้ระบุตำà¹à¸«à¸™à¹ˆà¸‡" + +#: ../gio/gio-tool-set.c:119 +msgid "Attribute not specified" +msgstr "ไม่ได้ระบุà¹à¸­à¸•ทริบิวต์" + +#: ../gio/gio-tool-set.c:128 +msgid "Value not specified" +msgstr "ไม่ได้ระบุค่า" + +#: ../gio/gio-tool-set.c:176 +#, c-format +msgid "Invalid attribute type %s\n" +msgstr "ชนิดของà¹à¸­à¸•ทริบิวต์ %s ไม่ถูà¸à¸•้อง\n" + +#: ../gio/gio-tool-set.c:189 +#, c-format +msgid "Error setting attribute: %s\n" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸”ค่าà¹à¸­à¸•ทริบิวต์: %s\n" + +#: ../gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "เทถังขยะ" + +#: ../gio/gio-tool-trash.c:86 +msgid "Move files or directories to the trash." +msgstr "ย้ายà¹à¸Ÿà¹‰à¸¡à¸«à¸£à¸·à¸­à¹„ดเรà¸à¸—อรีไปลงถังขยะ" + +#: ../gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "เดินไปตามลิงà¸à¹Œà¸ªà¸±à¸à¸¥à¸±à¸à¸©à¸“์, จุดเมานท์ à¹à¸¥à¸°à¸ˆà¸¸à¸”ลัดต่างๆ" + +#: ../gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "à¹à¸ªà¸”งเนื้อหาของไดเรà¸à¸—อรีในรูปà¹à¸šà¸šà¸„ล้ายโครงสร้างต้นไม้" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1491 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "อิลิเมนต์ <%s> ไม่สามารถอยู่ใน <%s> ได้" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "อิลิเมนต์ <%s> ไม่สามารถอยู่ที่ระดับบนสุดได้" + +#: ../gio/glib-compile-resources.c:237 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "à¹à¸Ÿà¹‰à¸¡ %s ปราà¸à¸à¸«à¸¥à¸²à¸¢à¸„รั้งในทรัพยาà¸à¸£" + +#: ../gio/glib-compile-resources.c:248 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "ไม่พบ '%s' ในไดเรà¸à¸—อรีซอร์สใดๆ" + +#: ../gio/glib-compile-resources.c:259 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "ไม่พบ '%s' ในไดเรà¸à¸—อรีปัจจุบัน" + +#: ../gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "ไม่รู้จัà¸à¸•ัวเลือภ\"%s\" ของà¸à¸²à¸£à¸›à¸£à¸°à¸¡à¸§à¸¥à¸œà¸¥" + +#: ../gio/glib-compile-resources.c:308 ../gio/glib-compile-resources.c:354 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "สร้างà¹à¸Ÿà¹‰à¸¡à¸Šà¸±à¹ˆà¸§à¸„ราวไม่สำเร็จ: %s" + +#: ../gio/glib-compile-resources.c:382 +#, c-format +msgid "Error reading file %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านà¹à¸Ÿà¹‰à¸¡ %s: %s" + +#: ../gio/glib-compile-resources.c:402 +#, c-format +msgid "Error compressing file %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะบีบอัดà¹à¸Ÿà¹‰à¸¡ %s" + +#: ../gio/glib-compile-resources.c:469 ../gio/glib-compile-schemas.c:1603 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "ไม่สามารถมีข้อความอยู่ใน <%s> ได้" + +#: ../gio/glib-compile-resources.c:620 +msgid "name of the output file" +msgstr "ชื่อของà¹à¸Ÿà¹‰à¸¡à¸œà¸¥à¸¥à¸±à¸žà¸˜à¹Œ" + +#: ../gio/glib-compile-resources.c:621 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "ไดเรà¸à¸—อรีที่จะอ่านà¹à¸Ÿà¹‰à¸¡à¸•่างๆ (ค่าปริยายคือไดเรà¸à¸—อรีปัจจุบัน)" + +#: ../gio/glib-compile-resources.c:621 ../gio/glib-compile-schemas.c:2036 +#: ../gio/glib-compile-schemas.c:2065 +msgid "DIRECTORY" +msgstr "ไดเรà¸à¸—อรี" + +#: ../gio/glib-compile-resources.c:622 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "สร้างผลลัพธ์ในรูปà¹à¸šà¸šà¸—ี่à¸à¸³à¸«à¸™à¸”โดยนามสà¸à¸¸à¸¥à¸‚องà¹à¸Ÿà¹‰à¸¡à¸œà¸¥à¸¥à¸±à¸žà¸˜à¹Œ" + +#: ../gio/glib-compile-resources.c:623 +msgid "Generate source header" +msgstr "สร้างข้อมูลส่วนหัวของซอร์ส" + +#: ../gio/glib-compile-resources.c:624 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "สร้างซอร์สโค้ดที่จะใช้เชื่อมโยงà¹à¸Ÿà¹‰à¸¡à¸—รัพยาà¸à¸£à¹€à¸‚้าในโค้ดของคุณ" + +#: ../gio/glib-compile-resources.c:625 +msgid "Generate dependency list" +msgstr "สร้างรายชื่อสิ่งที่โค้ดจำเป็นต้องใช้" + +#: ../gio/glib-compile-resources.c:626 +msgid "name of the dependency file to generate" +msgstr "ชื่อของà¹à¸Ÿà¹‰à¸¡à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­à¸ªà¸´à¹ˆà¸‡à¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้องใช้ที่จะสร้าง" + +#: ../gio/glib-compile-resources.c:627 +msgid "Don't automatically create and register resource" +msgstr "ไม่ต้องสร้างà¹à¸¥à¸°à¸¥à¸‡à¸—ะเบียนทรัพยาà¸à¸£à¹‚ดยอัตโนมัติ" + +#: ../gio/glib-compile-resources.c:628 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "ไม่ต้องส่งออà¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™à¸•่างๆ à¹à¸•่ประà¸à¸²à¸¨à¹€à¸›à¹‡à¸™ G_GNUC_INTERNAL" + +#: ../gio/glib-compile-resources.c:629 +msgid "C identifier name used for the generated source code" +msgstr "ชื่ออ้างอิงภาษาซีที่จะใช้ในซอร์สโค้ดที่สร้างขึ้น" + +#: ../gio/glib-compile-resources.c:655 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"คอมไพล์ข้อà¸à¸³à¸«à¸™à¸”ทรัพยาà¸à¸£à¹ƒà¸«à¹‰à¹€à¸›à¹‡à¸™à¹à¸Ÿà¹‰à¸¡à¸—รัพยาà¸à¸£\n" +"à¹à¸Ÿà¹‰à¸¡à¸‚้อà¸à¸³à¸«à¸™à¸”ทรัพยาà¸à¸£à¸ˆà¸°à¸¡à¸µà¸™à¸²à¸¡à¸ªà¸à¸¸à¸¥à¹€à¸›à¹‡à¸™ .gresource.xml\n" +"à¹à¸¥à¸°à¹à¸Ÿà¹‰à¸¡à¸—รัพยาà¸à¸£à¸ˆà¸°à¸¡à¸µà¸™à¸²à¸¡à¸ªà¸à¸¸à¸¥à¹€à¸›à¹‡à¸™ .gresource" + +#: ../gio/glib-compile-resources.c:671 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "คุณควรระบุชื่อà¹à¸Ÿà¹‰à¸¡à¹à¸Ÿà¹‰à¸¡à¹€à¸”ียว\n" + +#: ../gio/glib-compile-schemas.c:784 +msgid "empty names are not permitted" +msgstr "ห้ามใช้ชื่อว่างเปล่า" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "ชื่อ '%s' ใช้ไม่ได้: ชื่อต้องขี้นต้นด้วยตัวพิมพ์เล็à¸" + +#: ../gio/glib-compile-schemas.c:806 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"ชื่อ '%s' ใช้ไม่ได้: อัà¸à¸‚ระ '%c' ใช้ไม่ได้ ใช้ได้เฉพาะตัวพิมพ์เล็à¸, ตัวเลข à¹à¸¥à¸°à¸¢à¸±à¸•ิภังค์ ('-') " +"เท่านั้น" + +#: ../gio/glib-compile-schemas.c:815 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "ชื่อ '%s' ใช้ไม่ได้: ใช้ยัติภังค์สองตัวติดà¸à¸±à¸™ ('--') ไม่ได้" + +#: ../gio/glib-compile-schemas.c:824 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "ชื่อ '%s' ใข้ไม่ได้: อัà¸à¸‚ระสุดท้ายจะเป็นยัติภังค์ ('-') ไม่ได้" + +#: ../gio/glib-compile-schemas.c:832 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "ชื่อ '%s' ใช้ไม่ได้: ความยาวสูงสุดคือ 1024" + +#: ../gio/glib-compile-schemas.c:901 +#, c-format +msgid " already specified" +msgstr " ถูà¸à¸£à¸°à¸šà¸¸à¹„ปà¹à¸¥à¹‰à¸§" + +#: ../gio/glib-compile-schemas.c:927 +msgid "cannot add keys to a 'list-of' schema" +msgstr "ไม่สามารถเพิ่มคีย์ใน schema 'list-of'" + +#: ../gio/glib-compile-schemas.c:938 +#, c-format +msgid " already specified" +msgstr " ถูà¸à¸£à¸°à¸šà¸¸à¹„ปà¹à¸¥à¹‰à¸§" + +#: ../gio/glib-compile-schemas.c:956 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" ทับซ้อนà¸à¸±à¸š ใน ; ใช้ " +"หาà¸à¸•้องà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸„่า" + +#: ../gio/glib-compile-schemas.c:967 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "ต้องระบุ 'type', 'enum' หรือ 'flags' อย่างใดอย่างหนึ่ง ให้เป็นà¹à¸­à¸•ทริบิวต์ของ " + +#: ../gio/glib-compile-schemas.c:986 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (ยัง) ไม่ได้à¸à¸³à¸«à¸™à¸”" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "สตริงระบุชนิดของ GVariant '%s' ใช้à¸à¸²à¸£à¹„ม่ได้" + +#: ../gio/glib-compile-schemas.c:1031 +msgid " given but schema isn't extending anything" +msgstr "มี à¹à¸•่ schema ไม่ได้ขยายสิ่งใดเลย" + +#: ../gio/glib-compile-schemas.c:1044 +#, c-format +msgid "no to override" +msgstr "ไม่มี ที่จะทับค่า" + +#: ../gio/glib-compile-schemas.c:1052 +#, c-format +msgid " already specified" +msgstr "มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸ ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/glib-compile-schemas.c:1125 +#, c-format +msgid " already specified" +msgstr "มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸ ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/glib-compile-schemas.c:1137 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " ขยาย schema '%s' ที่ยังไม่มีอยู่" + +#: ../gio/glib-compile-schemas.c:1153 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " เป็นลิสต์ของ '%s' ที่ยังไม่มีอยู่" + +#: ../gio/glib-compile-schemas.c:1161 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "ไม่สามารถเป็นลิสต์ของ schema ที่มีพาธ" + +#: ../gio/glib-compile-schemas.c:1171 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "ไม่สามารถขยาย schema ที่มีพาธ" + +#: ../gio/glib-compile-schemas.c:1181 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " เป็นลิสต์ à¹à¸•่ขยาย ซึ่งไม่ใช่ลิสต์" + +#: ../gio/glib-compile-schemas.c:1191 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" ขยาย à¹à¸•่ '%s' " +"ไม่ได้ขยาย '%s'" + +#: ../gio/glib-compile-schemas.c:1208 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "ถ้ามีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”พาธ พาธจะต้องขึ้นต้นà¹à¸¥à¸°à¸¥à¸‡à¸—้ายด้วยขีดทับ" + +#: ../gio/glib-compile-schemas.c:1215 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "พาธของลิสต์ต้องลงท้ายด้วย ':/'" + +#: ../gio/glib-compile-schemas.c:1247 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸ <%s id='%s'> ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/glib-compile-schemas.c:1397 ../gio/glib-compile-schemas.c:1413 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "สามารถมีอิลิเมนต์ <%s> เพียงอิลิเมนต์เดียวเท่านั้นใน <%s>" + +#: ../gio/glib-compile-schemas.c:1495 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "อิลิเมนต์ <%s> ไม่สามารถอยู่ที่ระดับบนสุดได้" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1794 ../gio/glib-compile-schemas.c:1865 +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸ --strict ดังนั้นจะจบà¸à¸²à¸£à¸—ำงานตรงนี้\n" + +#: ../gio/glib-compile-schemas.c:1802 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "จะละเลยà¹à¸Ÿà¹‰à¸¡à¸™à¸µà¹‰à¸—ั้งà¹à¸Ÿà¹‰à¸¡\n" + +#: ../gio/glib-compile-schemas.c:1861 +#, c-format +msgid "Ignoring this file.\n" +msgstr "จะละเลยà¹à¸Ÿà¹‰à¸¡à¸™à¸µà¹‰\n" + +#: ../gio/glib-compile-schemas.c:1901 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "ไม่มีคีย์ '%s' ใน schema '%s' ตามที่ระบุในà¹à¸Ÿà¹‰à¸¡à¸—ับค่า '%s'" + +#: ../gio/glib-compile-schemas.c:1907 ../gio/glib-compile-schemas.c:1965 +#: ../gio/glib-compile-schemas.c:1993 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; จะละเลยà¸à¸²à¸£à¸—ับค่าสำหรับคีย์นี้\n" + +#: ../gio/glib-compile-schemas.c:1911 ../gio/glib-compile-schemas.c:1969 +#: ../gio/glib-compile-schemas.c:1997 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " à¹à¸¥à¸°à¸¡à¸µà¸à¸²à¸£à¸£à¸°à¸šà¸¸ --strict ดังนั้นจะจบà¸à¸²à¸£à¸—ำงานตรงนี้\n" + +#: ../gio/glib-compile-schemas.c:1927 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¹à¸ˆà¸‡à¸„ีย์ '%s' ใน schema '%s' ตามที่ระบุในà¹à¸Ÿà¹‰à¸¡à¸—ับค่า '%s': %s" + +#: ../gio/glib-compile-schemas.c:1937 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "จะละเลยà¸à¸²à¸£à¸—ับค่าสำหรับคีย์นี้\n" + +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"à¸à¸²à¸£à¸—ับค่าสำหรับคีย์ '%s' ใน schema '%s' ในà¹à¸Ÿà¹‰à¸¡à¸—ับค่า '%s' อยู่นอà¸à¸Šà¹ˆà¸§à¸‡à¸—ี่à¸à¸³à¸«à¸™à¸”ใน schema" + +#: ../gio/glib-compile-schemas.c:1983 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"à¸à¸²à¸£à¸—ับค่าสำหรับคีย์ '%s' ใน schema '%s' ในà¹à¸Ÿà¹‰à¸¡à¸—ับค่า '%s' ไม่อยู่ในรายชื่อของตัวเลือà¸à¸—ี่ใช้ได้" + +#: ../gio/glib-compile-schemas.c:2036 +msgid "where to store the gschemas.compiled file" +msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่จะเà¸à¹‡à¸šà¹à¸Ÿà¹‰à¸¡ gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2037 +msgid "Abort on any errors in schemas" +msgstr "ล้มเลิà¸à¸à¸²à¸£à¸—ำงานเมื่อพบข้อผิดพลาดใดๆ ใน schema" + +#: ../gio/glib-compile-schemas.c:2038 +msgid "Do not write the gschema.compiled file" +msgstr "ไม่ต้องเขียนà¹à¸Ÿà¹‰à¸¡ gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2039 +msgid "Do not enforce key name restrictions" +msgstr "ไม่ต้องบังคับใช้ข้อà¸à¸³à¸«à¸™à¸”ของชื่อคีย์" + +#: ../gio/glib-compile-schemas.c:2068 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"คอมไพล์à¹à¸Ÿà¹‰à¸¡ schema ของ GSettings ทั้งหมดลงในà¹à¸„ชของ schema\n" +"à¹à¸Ÿà¹‰à¸¡ schema ต้องมีนามสà¸à¸¸à¸¥à¹€à¸›à¹‡à¸™ .gschema.xml\n" +"à¹à¸¥à¸°à¹à¸Ÿà¹‰à¸¡à¹à¸„ชจะมีชื่อเป็น gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "คุณต้องระบุชื่อไดเรà¸à¸—อรีชื่อเดียว\n" + +#: ../gio/glib-compile-schemas.c:2123 +#, c-format +msgid "No schema files found: " +msgstr "ไม่พบà¹à¸Ÿà¹‰à¸¡ schema: " + +#: ../gio/glib-compile-schemas.c:2126 +#, c-format +msgid "doing nothing.\n" +msgstr "ไม่ทำอะไร\n" + +#: ../gio/glib-compile-schemas.c:2129 +#, c-format +msgid "removed existing output file.\n" +msgstr "ลบà¹à¸Ÿà¹‰à¸¡à¸œà¸¥à¸¥à¸±à¸žà¸˜à¹Œà¸—ี่มีอยู่ทิ้งà¹à¸¥à¹‰à¸§\n" + +#: ../gio/glocalfile.c:642 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "ชื่อà¹à¸Ÿà¹‰à¸¡ %s ผิดรูปà¹à¸šà¸š" + +#: ../gio/glocalfile.c:1036 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านข้อมูลระบบà¹à¸Ÿà¹‰à¸¡à¸ªà¸³à¸«à¸£à¸±à¸š %s: %s" + +#: ../gio/glocalfile.c:1175 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "ไม่พบจุดเมานท์ที่บรรจุà¹à¸Ÿà¹‰à¸¡ %s" + +#: ../gio/glocalfile.c:1198 +msgid "Can't rename root directory" +msgstr "ไม่สามารถเปลี่ยนชื่อไดเรà¸à¸—อรีราà¸" + +#: ../gio/glocalfile.c:1216 ../gio/glocalfile.c:1239 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปลี่ยนชื่อà¹à¸Ÿà¹‰à¸¡ %s: %s" + +#: ../gio/glocalfile.c:1223 +msgid "Can't rename file, filename already exists" +msgstr "ไม่สามารถเปลี่ยนชื่อà¹à¸Ÿà¹‰à¸¡ เนื่องจาà¸à¸¡à¸µà¹à¸Ÿà¹‰à¸¡à¸Šà¸·à¹ˆà¸­à¹€à¸”ียวà¸à¸±à¸™à¸­à¸¢à¸¹à¹ˆà¸à¹ˆà¸­à¸™à¹à¸¥à¹‰à¸§" + +#: ../gio/glocalfile.c:1236 ../gio/glocalfile.c:2250 ../gio/glocalfile.c:2278 +#: ../gio/glocalfile.c:2435 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "ชื่อà¹à¸Ÿà¹‰à¸¡à¸œà¸´à¸”รูปà¹à¸šà¸š" + +#: ../gio/glocalfile.c:1403 ../gio/glocalfile.c:1418 +#, c-format +msgid "Error opening file %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดà¹à¸Ÿà¹‰à¸¡ %s: %s" + +#: ../gio/glocalfile.c:1543 +#, c-format +msgid "Error removing file %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะลบà¹à¸Ÿà¹‰à¸¡ %s: %s" + +#: ../gio/glocalfile.c:1926 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะทิ้งà¹à¸Ÿà¹‰à¸¡ %s ลงถังขยะ: %s" + +#: ../gio/glocalfile.c:1949 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "สร้างไดเรà¸à¸—อรีถังขยะ '%s' ไม่สำเร็จ: %s" + +#: ../gio/glocalfile.c:1969 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "หาไดเรà¸à¸—อรีระดับบนสุดสำหรับทิ้ง %s ลงถังขยะไม่สำเร็จ" + +#: ../gio/glocalfile.c:2048 ../gio/glocalfile.c:2068 +#, c-format +msgid "Unable to find or create trash directory for %s" +msgstr "หาหรือสร้างไดเรà¸à¸—อรีถังขยะสำหรับ %s ไม่สำเร็จ" + +#: ../gio/glocalfile.c:2102 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "สร้างà¹à¸Ÿà¹‰à¸¡à¸‚้อมูลà¸à¸²à¸£à¸—ิ้งขยะสำหรับ %s ไม่สำเร็จ: %s" + +#: ../gio/glocalfile.c:2161 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "ไม่สามารถทิ้งà¹à¸Ÿà¹‰à¸¡ %s ลงถังขยะโดยข้ามขอบเขตของระบบà¹à¸Ÿà¹‰à¸¡" + +#: ../gio/glocalfile.c:2165 ../gio/glocalfile.c:2221 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "ทิ้งà¹à¸Ÿà¹‰à¸¡ %s ลงถังขยะไม่สำเร็จ: %s" + +#: ../gio/glocalfile.c:2227 +#, c-format +msgid "Unable to trash file %s" +msgstr "ทิ้งà¹à¸Ÿà¹‰à¸¡ %s ลงถังขยะไม่สำเร็จ" + +#: ../gio/glocalfile.c:2253 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะสร้างไดเรà¸à¸—อรี %s: %s" + +#: ../gio/glocalfile.c:2282 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ระบบà¹à¸Ÿà¹‰à¸¡à¹„ม่รองรับลิงà¸à¹Œà¸ªà¸±à¸à¸¥à¸±à¸à¸©à¸“์" + +#: ../gio/glocalfile.c:2285 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะสร้างลิงà¸à¹Œà¸ªà¸±à¸à¸¥à¸±à¸à¸©à¸“์ %s: %s" + +#: ../gio/glocalfile.c:2291 ../glib/gfileutils.c:2064 +msgid "Symbolic links not supported" +msgstr "ไม่รองรับลิงà¸à¹Œà¸ªà¸±à¸à¸¥à¸±à¸à¸©à¸“์" + +#: ../gio/glocalfile.c:2346 ../gio/glocalfile.c:2381 ../gio/glocalfile.c:2438 +#, c-format +msgid "Error moving file %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะย้ายà¹à¸Ÿà¹‰à¸¡ %s: %s" + +#: ../gio/glocalfile.c:2369 +msgid "Can't move directory over directory" +msgstr "ไม่สามารถย้ายไดเรà¸à¸—อรีทับไดเรà¸à¸—อรี" + +#: ../gio/glocalfile.c:2395 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:971 ../gio/glocalfileoutputstream.c:985 +msgid "Backup file creation failed" +msgstr "สร้างà¹à¸Ÿà¹‰à¸¡à¸ªà¸³à¸£à¸­à¸‡à¹„ม่สำเร็จ" + +#: ../gio/glocalfile.c:2414 +#, c-format +msgid "Error removing target file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะลบà¹à¸Ÿà¹‰à¸¡à¸›à¸¥à¸²à¸¢à¸—าง: %s" + +#: ../gio/glocalfile.c:2428 +msgid "Move between mounts not supported" +msgstr "ไม่รองรับà¸à¸²à¸£à¸¢à¹‰à¸²à¸¢à¹à¸Ÿà¹‰à¸¡à¸‚้ามอุปà¸à¸£à¸“์" + +#: ../gio/glocalfile.c:2619 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "ไม่สามารถพิจารณาà¸à¸²à¸£à¹ƒà¸Šà¹‰à¹€à¸™à¸·à¹‰à¸­à¸—ี่ดิสà¸à¹Œà¸‚อง %s: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "ค่าà¹à¸­à¸•ทริบิวต์ต้องไม่ใช่ตัวชี้ศูนย์" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "ชนิดของà¹à¸­à¸•ทริบิวต์ใช้à¸à¸²à¸£à¹„ม่ได้ (ต้องà¸à¸²à¸£à¸ªà¸•ริง)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "ชื่อà¹à¸­à¸•ทริบิวต์ส่วนขยายเพิ่มใช้à¸à¸²à¸£à¹„ม่ได้" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸”à¹à¸­à¸•ทริบิวต์ส่วนขยาย '%s': %s" + +#: ../gio/glocalfileinfo.c:1575 +msgid " (invalid encoding)" +msgstr " (รหัสอัà¸à¸‚ระไม่ถูà¸à¸•้อง)" + +#: ../gio/glocalfileinfo.c:1766 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านข้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¹à¸Ÿà¹‰à¸¡ '%s': %s" + +#: ../gio/glocalfileinfo.c:2017 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านข้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸š file descriptor: %s" + +#: ../gio/glocalfileinfo.c:2062 +msgid "Invalid attribute type (uint32 expected)" +msgstr "ชนิดของà¹à¸­à¸•ทริบิวต์ไม่ถูà¸à¸•้อง (ต้องà¸à¸²à¸£ uint32)" + +#: ../gio/glocalfileinfo.c:2080 +msgid "Invalid attribute type (uint64 expected)" +msgstr "ชนิดของà¹à¸­à¸•ทริบิวต์ไม่ถูà¸à¸•้อง (ต้องà¸à¸²à¸£ uint64)" + +#: ../gio/glocalfileinfo.c:2099 ../gio/glocalfileinfo.c:2118 +msgid "Invalid attribute type (byte string expected)" +msgstr "ชนิดของà¹à¸­à¸•ทริบิวต์ไม่ถูà¸à¸•้อง (ต้องà¸à¸²à¸£à¸ªà¸•ริงของไบต์)" + +#: ../gio/glocalfileinfo.c:2153 +msgid "Cannot set permissions on symlinks" +msgstr "ไม่สามารถà¸à¸³à¸«à¸™à¸”สิทธิ์ให้à¸à¸±à¸š symlink ได้" + +#: ../gio/glocalfileinfo.c:2169 +#, c-format +msgid "Error setting permissions: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸”สิทธิ์: %s" + +#: ../gio/glocalfileinfo.c:2220 +#, c-format +msgid "Error setting owner: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸”เจ้าของ: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "symlink must be non-NULL" +msgstr "symlink ต้องไม่ใช่ตัวชี้ศูนย์" + +#: ../gio/glocalfileinfo.c:2253 ../gio/glocalfileinfo.c:2272 +#: ../gio/glocalfileinfo.c:2283 +#, c-format +msgid "Error setting symlink: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸” symlink: %s" + +#: ../gio/glocalfileinfo.c:2262 +msgid "Error setting symlink: file is not a symlink" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸” symlink: à¹à¸Ÿà¹‰à¸¡à¹„ม่ใช่ symlink" + +#: ../gio/glocalfileinfo.c:2388 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸”เวลาเปลี่ยนà¹à¸›à¸¥à¸‡à¸«à¸£à¸·à¸­à¹€à¸‚้าถึง: %s" + +#: ../gio/glocalfileinfo.c:2411 +msgid "SELinux context must be non-NULL" +msgstr "SELinux context ต้องไม่ใช่ตัวชี้ศูนย์" + +#: ../gio/glocalfileinfo.c:2426 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¸à¸³à¸«à¸™à¸” SELinux context: %s" + +#: ../gio/glocalfileinfo.c:2433 +msgid "SELinux is not enabled on this system" +msgstr "ไม่ได้เปิดใช้งาน SELinux ในระบบนี้" + +#: ../gio/glocalfileinfo.c:2525 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "ไม่รองรับà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”à¹à¸­à¸•ทริบิวต์ %s" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านข้อมูลจาà¸à¹à¸Ÿà¹‰à¸¡: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1003 +#, c-format +msgid "Error seeking in file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเลื่อนตำà¹à¸«à¸™à¹ˆà¸‡à¸­à¹ˆà¸²à¸™à¹€à¸‚ียนà¹à¸Ÿà¹‰à¸¡: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะปิดà¹à¸Ÿà¹‰à¸¡: %s" + +#: ../gio/glocalfilemonitor.c:840 +msgid "Unable to find default local file monitor type" +msgstr "ไม่สามารถหาชนิดปริยายของà¸à¸²à¸£à¹€à¸à¹‰à¸²à¸¡à¸­à¸‡à¹à¸Ÿà¹‰à¸¡à¹ƒà¸™à¹€à¸„รื่อง" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเขียนข้อมูลลงà¹à¸Ÿà¹‰à¸¡: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะลบà¹à¸Ÿà¹‰à¸¡à¸ªà¸³à¸£à¸­à¸‡à¹€à¸à¹ˆà¸²: %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะสร้างสำเนาสำรอง: %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปลี่ยนชื่อà¹à¸Ÿà¹‰à¸¡à¸ªà¸³à¸£à¸­à¸‡: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1054 +#, c-format +msgid "Error truncating file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะตัดท้ายà¹à¸Ÿà¹‰à¸¡à¸—ิ้ง: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1035 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดà¹à¸Ÿà¹‰à¸¡ '%s': %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸›à¸¥à¸²à¸¢à¸—างเป็นไดเรà¸à¸—อรี" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸›à¸¥à¸²à¸¢à¸—างไม่ใช่à¹à¸Ÿà¹‰à¸¡à¸›à¸à¸•ิ" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸–ูà¸à¹à¸à¹‰à¹„ขโดยโปรà¹à¸à¸£à¸¡à¸­à¸·à¹ˆà¸™" + +#: ../gio/glocalfileoutputstream.c:1019 +#, c-format +msgid "Error removing old file: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะลบà¹à¸Ÿà¹‰à¸¡à¹€à¸”ิม: %s" + +#: ../gio/gmemoryinputstream.c:474 ../gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "ได้รับค่า GSeekType ที่ใช้à¸à¸²à¸£à¹„ม่ได้" + +#: ../gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "คำสั่งเลื่อนตำà¹à¸«à¸™à¹ˆà¸‡à¸­à¹ˆà¸²à¸™à¹€à¸‚ียนผิดเงื่อนไข" + +#: ../gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "ไม่สามารถตัดท้าย GMemoryInputStream ทิ้ง" + +#: ../gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "สตรีมข้อมูลออà¸à¹ƒà¸™à¸«à¸™à¹ˆà¸§à¸¢à¸„วามจำไม่สามารถเปลี่ยนขนาดได้" + +#: ../gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "เปลี่ยนขนาดสตรีมข้อมูลออà¸à¹ƒà¸™à¸«à¸™à¹ˆà¸§à¸¢à¸„วามจำไม่สำเร็จ" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "ปริมาณหน่วยความจำที่ต้องà¸à¸²à¸£à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¹€à¸‚ียนใหà¸à¹ˆà¹€à¸à¸´à¸™à¸‚อบเขตของà¹à¸­à¸”เดรสที่มี" + +#: ../gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "มีà¸à¸²à¸£à¸£à¹‰à¸­à¸‡à¸‚อให้เลื่อนตำà¹à¸«à¸™à¹ˆà¸‡à¹„ปà¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²à¸ˆà¸¸à¸”เริ่มต้นของสตรีม" + +#: ../gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "มีà¸à¸²à¸£à¸£à¹‰à¸­à¸‡à¸‚อให้เลื่อนตำà¹à¸«à¸™à¹ˆà¸‡à¹€à¸¥à¸¢à¸ˆà¸¸à¸”สิ้นสุดของสตรีมออà¸à¹„ป" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "à¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์นี้ยังไม่รองรับคำสั่ง \"unmount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "à¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์นี้ยังไม่รองรับคำสั่ง \"eject\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "à¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์นี้ยังไม่รองรับคำสั่ง \"unmount\" หรือ \"unmount_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "à¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์นี้ยังไม่รองรับคำสั่ง \"eject\" หรือ \"eject_with_operation\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "à¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์นี้ยังไม่รองรับคำสั่ง \"remount\"" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "à¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์นี้ยังไม่รองรับà¸à¸²à¸£à¹€à¸”าชนิดเนื้อหา" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "à¸à¸²à¸£à¹€à¸¡à¸²à¸™à¸—์นี้ยังไม่รองรับà¸à¸²à¸£à¹€à¸”าชนิดเนื้อหาà¹à¸šà¸šà¸‹à¸´à¸‡à¹‚ครนัส" + +#: ../gio/gnetworkaddress.c:378 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "ชื่อโฮสต์ '%s' มี '[' à¹à¸•่ไม่มี ']'" + +#: ../gio/gnetworkmonitorbase.c:206 ../gio/gnetworkmonitorbase.c:310 +msgid "Network unreachable" +msgstr "ไม่สามารถติดต่อเครือข่ายได้" + +#: ../gio/gnetworkmonitorbase.c:244 ../gio/gnetworkmonitorbase.c:274 +msgid "Host unreachable" +msgstr "ไม่สามารถติดต่อโฮสต์ได้" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "ไม่สามารถสร้างตัวเà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•เครือข่าย: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "ไม่สามารถสร้างตัวเà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•เครือข่าย: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "ไม่สามารถอ่านสถานะของเครือข่ายได้: " + +#: ../gio/gnetworkmonitornm.c:326 +#, c-format +msgid "NetworkManager version too old" +msgstr "รุ่นของ NetworkManager เà¸à¹ˆà¸²à¹€à¸à¸´à¸™à¹„ป" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:560 +msgid "Output stream doesn't implement write" +msgstr "สตรีมข้อมูลออà¸à¸¢à¸±à¸‡à¹„ม่รองรับà¸à¸²à¸£à¹€à¸‚ียนข้อมูล" + +#: ../gio/goutputstream.c:521 ../gio/goutputstream.c:1224 +msgid "Source stream is already closed" +msgstr "สตรีมต้นทางถูà¸à¸›à¸´à¸”ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/gresolver.c:330 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดหาที่อยู่ '%s': %s" + +#: ../gio/gresource.c:595 ../gio/gresource.c:846 ../gio/gresource.c:863 +#: ../gio/gresource.c:987 ../gio/gresource.c:1059 ../gio/gresource.c:1132 +#: ../gio/gresource.c:1202 ../gio/gresourcefile.c:453 +#: ../gio/gresourcefile.c:576 ../gio/gresourcefile.c:713 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "ไม่มีทรัพยาà¸à¸£à¸­à¸¢à¸¹à¹ˆà¸—ี่ '%s'" + +#: ../gio/gresource.c:760 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "คลายบีบอัดทรัพยาà¸à¸£à¸—ี่ '%s' ไม่สำเร็จ" + +#: ../gio/gresourcefile.c:709 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "ทรัพยาà¸à¸£à¸—ี่ '%s' ไม่ใช่ไดเรà¸à¸—อรี" + +#: ../gio/gresourcefile.c:917 +msgid "Input stream doesn't implement seek" +msgstr "สตรีมข้อมูลเข้ายังไม่รองรับà¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸­à¸™à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸­à¹ˆà¸²à¸™/เขียน" + +#: ../gio/gresource-tool.c:494 +msgid "List sections containing resources in an elf FILE" +msgstr "à¹à¸ªà¸”งรายชื่อหัวข้อย่อยที่บรรจุทรัพยาà¸à¸£à¹ƒà¸™à¹à¸Ÿà¹‰à¸¡ ELF" + +#: ../gio/gresource-tool.c:500 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"à¹à¸ªà¸”งรายชื่อทรัพยาà¸à¸£\n" +"ถ้ามีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”หัวข้อ à¸à¹‡à¸ˆà¸°à¹à¸ªà¸”งเฉพาะทรัพยาà¸à¸£à¸—ี่อยู่ในหัวข้อที่à¸à¸³à¸«à¸™à¸”\n" +"ถ้ามีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”พาธ à¸à¹‡à¸ˆà¸°à¹à¸ªà¸”งเฉพาะทรัพยาà¸à¸£à¸—ี่ตรงตามที่à¸à¸³à¸«à¸™à¸”" + +#: ../gio/gresource-tool.c:503 ../gio/gresource-tool.c:513 +msgid "FILE [PATH]" +msgstr "à¹à¸Ÿà¹‰à¸¡ [พาธ]" + +#: ../gio/gresource-tool.c:504 ../gio/gresource-tool.c:514 +#: ../gio/gresource-tool.c:521 +msgid "SECTION" +msgstr "หัวข้อ" + +#: ../gio/gresource-tool.c:509 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"à¹à¸ªà¸”งรายชื่อทรัพยาà¸à¸£à¸žà¸£à¹‰à¸­à¸¡à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”\n" +"ถ้ามีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”หัวข้อ à¸à¹‡à¸ˆà¸°à¹à¸ªà¸”งเฉพาะทรัพยาà¸à¸£à¸—ี่อยู่ในหัวข้อที่à¸à¸³à¸«à¸™à¸”\n" +"ถ้ามีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”พาธ à¸à¹‡à¸ˆà¸°à¹à¸ªà¸”งเฉพาะทรัพยาà¸à¸£à¸—ี่ตรงตามที่à¸à¸³à¸«à¸™à¸”\n" +"รายละเอียดที่à¹à¸ªà¸”ง ได้à¹à¸à¹ˆ หัวข้อ, ขนาด à¹à¸¥à¸°à¸à¸²à¸£à¸šà¸µà¸šà¸­à¸±à¸” เป็นต้น" + +#: ../gio/gresource-tool.c:519 +msgid "Extract a resource file to stdout" +msgstr "à¹à¸•à¸à¹à¸Ÿà¹‰à¸¡à¸—รัพยาà¸à¸£à¸­à¸­à¸à¸—างเอาต์พุตมาตรà¸à¸²à¸™" + +#: ../gio/gresource-tool.c:520 +msgid "FILE PATH" +msgstr "à¹à¸Ÿà¹‰à¸¡ พาธ" + +#: ../gio/gresource-tool.c:534 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"วิธีใช้:\n" +" gresource [--section หัวข้อ] คำสั่ง [อาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์...]\n" +"\n" +"คำสั่ง:\n" +" help à¹à¸ªà¸”งข้อความวิธีใช้นี้\n" +" sections à¹à¸ªà¸”งหัวข้อต่างๆ ของทรัพยาà¸à¸£\n" +" list à¹à¸ªà¸”งรายชื่อทรัพยาà¸à¸£\n" +" details à¹à¸ªà¸”งรายชื่อทรัพยาà¸à¸£à¸žà¸£à¹‰à¸­à¸¡à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”\n" +" extract à¹à¸•à¸à¸—รัพยาà¸à¸£à¸ˆà¸²à¸à¸à¸²à¸£à¸šà¸µà¸šà¸­à¸±à¸”\n" +"\n" +"เรียภ'gresource help คำสั่ง' เพื่อดูวิธีใช้อย่างละเอียด\n" +"\n" + +#: ../gio/gresource-tool.c:548 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"วิธีใช้:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:555 +msgid " SECTION An (optional) elf section name\n" +msgstr " หัวข้อ ชื่อหัวข้อ ELF (ระบุหรือไม่à¸à¹‡à¹„ด้)\n" + +#: ../gio/gresource-tool.c:559 ../gio/gsettings-tool.c:654 +msgid " COMMAND The (optional) command to explain\n" +msgstr " คำสั่ง คำสั่งที่ต้องà¸à¸²à¸£à¹ƒà¸«à¹‰à¸­à¸˜à¸´à¸šà¸²à¸¢ (ระบุหรือไม่à¸à¹‡à¹„ด้)\n" + +#: ../gio/gresource-tool.c:565 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " à¹à¸Ÿà¹‰à¸¡ à¹à¸Ÿà¹‰à¸¡ ELF (ไบนารีหรือไลบรารีใช้ร่วม)\n" + +#: ../gio/gresource-tool.c:568 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" à¹à¸Ÿà¹‰à¸¡ à¹à¸Ÿà¹‰à¸¡ ELF (ไบนารีหรือไลบรารีใช้ร่วม)\n" +" หรือทรัพยาà¸à¸£à¸—ี่คอมไพล์à¹à¸¥à¹‰à¸§\n" + +#: ../gio/gresource-tool.c:572 +msgid "[PATH]" +msgstr "[พาธ]" + +#: ../gio/gresource-tool.c:574 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " พาธ พาธของทรัพยาà¸à¸£ (ระบุหรือไม่à¸à¹‡à¹„ด้) (อาจระบุเพียงบางส่วนà¸à¹‡à¹„ด้)\n" + +#: ../gio/gresource-tool.c:575 +msgid "PATH" +msgstr "พาธ" + +#: ../gio/gresource-tool.c:577 +msgid " PATH A resource path\n" +msgstr " พาธ พาธของทรัพยาà¸à¸£\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#: ../gio/gsettings-tool.c:851 +#, c-format +msgid "No such schema '%s'\n" +msgstr "ไม่มี schema '%s'\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "schema '%s' ไม่สามารถย้ายที่ได้ (ต้องไม่ระบุพาธ)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "schema '%s' สามารถย้ายที่ได้ (ต้องระบุพาธ)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "พาธที่à¸à¸³à¸«à¸™à¸”มาว่างเปล่า\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "พาธต้องขึ้นต้นด้วยขีดทับ (/)\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "พาธต้องลงท้ายด้วยขีดทับ (/)\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "พาธต้องไม่มีขีดทับสองตัวติดà¸à¸±à¸™ (//)\n" + +#: ../gio/gsettings-tool.c:489 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "ค่าที่à¸à¸³à¸«à¸™à¸”มาอยู่นอà¸à¸Šà¹ˆà¸§à¸‡à¸—ี่ใช้ได้\n" + +#: ../gio/gsettings-tool.c:496 +#, c-format +msgid "The key is not writable\n" +msgstr "คีย์นี้ไม่สามารถเขียนได้\n" + +#: ../gio/gsettings-tool.c:532 +msgid "List the installed (non-relocatable) schemas" +msgstr "à¹à¸ªà¸”งรายชื่อ schema (ที่ย้ายที่ไม่ได้) ที่ติดตั้งไว้" + +#: ../gio/gsettings-tool.c:538 +msgid "List the installed relocatable schemas" +msgstr "à¹à¸ªà¸”งรายชื่อ schema ที่ย้ายที่ได้ที่ติดตั้งไว้" + +#: ../gio/gsettings-tool.c:544 +msgid "List the keys in SCHEMA" +msgstr "à¹à¸ªà¸”งคีย์ต่างๆ ใน SCHEMA" + +#: ../gio/gsettings-tool.c:545 ../gio/gsettings-tool.c:551 +#: ../gio/gsettings-tool.c:594 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:550 +msgid "List the children of SCHEMA" +msgstr "à¹à¸ªà¸”งโหนดลูà¸à¸•่างๆ ของ SCHEMA" + +#: ../gio/gsettings-tool.c:556 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"à¹à¸ªà¸”งคีย์à¹à¸¥à¸°à¸„่าต่างๆ à¹à¸šà¸šà¹„ล่ลงทุà¸à¸¥à¸³à¸”ับชั้น\n" +"ถ้าไม่ระบุ SCHEMA à¸à¹‡à¸ˆà¸°à¹à¸ªà¸”งคีย์ทั้งหมด\n" + +#: ../gio/gsettings-tool.c:558 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:563 +msgid "Get the value of KEY" +msgstr "อ่านค่าของ KEY" + +#: ../gio/gsettings-tool.c:564 ../gio/gsettings-tool.c:570 +#: ../gio/gsettings-tool.c:576 ../gio/gsettings-tool.c:588 +#: ../gio/gsettings-tool.c:600 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:569 +msgid "Query the range of valid values for KEY" +msgstr "สอบถามช่วงของค่าต่างๆ ที่ใช้ได้สำหรับ KEY" + +#: ../gio/gsettings-tool.c:575 +msgid "Query the description for KEY" +msgstr "สอบถามคำบรรยายของ KEY" + +#: ../gio/gsettings-tool.c:581 +msgid "Set the value of KEY to VALUE" +msgstr "à¸à¸³à¸«à¸™à¸”ค่าของ KEY ให้เป็น VALUE" + +#: ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:587 +msgid "Reset KEY to its default value" +msgstr "ล้างค่า KEY ให้เป็นค่าปริยาย" + +#: ../gio/gsettings-tool.c:593 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "ล้างค่า KEY ทั้งหมดใน SCHEMA ให้เป็นค่าปริยาย" + +#: ../gio/gsettings-tool.c:599 +msgid "Check if KEY is writable" +msgstr "ตรวจสอบว่า KEY สามารถเขียนได้หรือไม่" + +#: ../gio/gsettings-tool.c:605 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹ƒà¸™ KEY\n" +"ถ้าไม่ระบุ KEY à¸à¹‡à¸ˆà¸°à¹€à¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•ทุà¸à¸„ีย์ใน SCHEMA\n" +"à¸à¸” ^C เมื่อต้องà¸à¸²à¸£à¸«à¸¢à¸¸à¸”เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•\n" + +#: ../gio/gsettings-tool.c:608 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:620 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"วิธีใช้:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"คำสั่ง:\n" +" help à¹à¸ªà¸”งข้อความวิธีใช้นี้\n" +" list-schemas à¹à¸ªà¸”งรายชื่อ schema ที่ติดตั้งไว้\n" +" list-relocatable-schemas à¹à¸ªà¸”งรายชื่อ schema ที่ย้ายที่ได้\n" +" list-keys à¹à¸ªà¸”งคีย์ต่างๆ ใน schema\n" +" list-children à¹à¸ªà¸”งโหนดลูà¸à¸•่างๆ ของ schema\n" +" list-recursively à¹à¸ªà¸”งคีย์à¹à¸¥à¸°à¸„่าต่างๆ à¹à¸šà¸šà¹„ล่ลงทุà¸à¸¥à¸³à¸”ับชั้น\n" +" range สอบถามช่วงของค่าสำหรับคีย์\n" +" describe สอบถามคำบรรยายของคีย์\n" +" get อ่านค่าของคีย์\n" +" set à¸à¸³à¸«à¸™à¸”ค่าของคีย์\n" +" reset ล้างค่าของคีย์\n" +" reset-recursively ล้างค่าทั้งหมดใน schema ที่à¸à¸³à¸«à¸™à¸”\n" +" writable ตรวจสอบว่าคีย์สามารถเขียนได้หรือไม่\n" +" monitor เà¸à¹‰à¸²à¸ªà¸±à¸‡à¹€à¸à¸•à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡\n" +"\n" +"เรียภ'gsettings help <คำสั่ง>' เพื่อดูวิธีใช้อย่างละเอียด\n" +"\n" + +#: ../gio/gsettings-tool.c:644 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"วิธีใช้:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:650 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR ไดเรà¸à¸—อรีที่จะค้นหา schema เพิ่มเติม\n" + +#: ../gio/gsettings-tool.c:658 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA ชื่อของ schema\n" +" PATH พาธ สำหรับ schema ที่ย้ายที่ได้\n" + +#: ../gio/gsettings-tool.c:663 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY คีย์ใน schema (ระบุหรือไม่à¸à¹‡à¹„ด้)\n" + +#: ../gio/gsettings-tool.c:667 +msgid " KEY The key within the schema\n" +msgstr " KEY คีย์ใน schema\n" + +#: ../gio/gsettings-tool.c:671 +msgid " VALUE The value to set\n" +msgstr " VALUE ค่าที่จะà¸à¸³à¸«à¸™à¸”\n" + +#: ../gio/gsettings-tool.c:726 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "ไม่สามารถโหลด schema จาภ%s: %s\n" + +#: ../gio/gsettings-tool.c:738 +#, c-format +msgid "No schemas installed\n" +msgstr "ไม่ได้ติดตั้ง schema ไว้\n" + +#: ../gio/gsettings-tool.c:809 +#, c-format +msgid "Empty schema name given\n" +msgstr "ชื่อ schema ที่à¸à¸³à¸«à¸™à¸”มาว่างเปล่า\n" + +#: ../gio/gsettings-tool.c:864 +#, c-format +msgid "No such key '%s'\n" +msgstr "ไม่มีคีย์ '%s'\n" + +#: ../gio/gsocket.c:364 +msgid "Invalid socket, not initialized" +msgstr "ซ็อà¸à¹€à¸à¹‡à¸•ผิดพลาด ยังไม่ได้ตั้งค่าเริ่มต้น" + +#: ../gio/gsocket.c:371 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ซ็อà¸à¹€à¸à¹‡à¸•ผิดพลาด ตั้งค่าเริ่มต้นไม่สำเร็จเนื่องจาà¸: %s" + +#: ../gio/gsocket.c:379 +msgid "Socket is already closed" +msgstr "ซ็อà¸à¹€à¸à¹‡à¸•ถูà¸à¸›à¸´à¸”ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/gsocket.c:394 ../gio/gsocket.c:2751 ../gio/gsocket.c:3897 +#: ../gio/gsocket.c:3952 +msgid "Socket I/O timed out" +msgstr "à¸à¸²à¸£à¸­à¹ˆà¸²à¸™/เขียนซ็อà¸à¹€à¸à¹‡à¸•หมดเวลาคอย" + +#: ../gio/gsocket.c:526 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ขณะสร้าง GSocket จาภfd: %s" + +#: ../gio/gsocket.c:554 ../gio/gsocket.c:608 ../gio/gsocket.c:615 +#, c-format +msgid "Unable to create socket: %s" +msgstr "สร้างซ็อà¸à¹€à¸à¹‡à¸•ไม่สำเร็จ: %s" + +#: ../gio/gsocket.c:608 +msgid "Unknown family was specified" +msgstr "มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸ family ที่ไม่รู้จัà¸" + +#: ../gio/gsocket.c:615 +msgid "Unknown protocol was specified" +msgstr "มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸à¹‚พรโทคอลที่ไม่รู้จัà¸" + +#: ../gio/gsocket.c:1104 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "ไม่สามารถใช้à¸à¸²à¸£à¸à¸£à¸°à¸—ำ datagram à¸à¸±à¸šà¸‹à¹‡à¸­à¸à¹€à¸à¹‡à¸•ที่ไม่ได้เป็น datagram ได้" + +#: ../gio/gsocket.c:1121 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "ไม่สามารถใช้à¸à¸²à¸£à¸à¸£à¸°à¸—ำ datagram à¸à¸±à¸šà¸‹à¹‡à¸­à¸à¹€à¸à¹‡à¸•ที่มีà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”เวลาคอยได้" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "could not get local address: %s" +msgstr "ไม่สามารถหาที่อยู่à¸à¸±à¹ˆà¸‡à¸™à¸µà¹‰à¹„ด้: %s" + +#: ../gio/gsocket.c:1968 +#, c-format +msgid "could not get remote address: %s" +msgstr "ไม่สามารถหาที่อยู่à¸à¸±à¹ˆà¸‡à¹‚น้นได้: %s" + +#: ../gio/gsocket.c:2034 +#, c-format +msgid "could not listen: %s" +msgstr "ไม่สามารถ listen: %s" + +#: ../gio/gsocket.c:2133 +#, c-format +msgid "Error binding to address: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะ bind à¸à¸±à¸šà¸—ี่อยู่: %s" + +#: ../gio/gsocket.c:2248 ../gio/gsocket.c:2285 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเข้าร่วมà¸à¸¥à¸¸à¹ˆà¸¡à¸¡à¸±à¸¥à¸•ิà¹à¸„สต์: %s" + +#: ../gio/gsocket.c:2249 ../gio/gsocket.c:2286 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะออà¸à¸ˆà¸²à¸à¸à¸¥à¸¸à¹ˆà¸¡à¸¡à¸±à¸¥à¸•ิà¹à¸„สต์: %s" + +#: ../gio/gsocket.c:2250 +msgid "No support for source-specific multicast" +msgstr "ไม่รองรับมัลติà¹à¸„สต์à¹à¸šà¸šà¹€à¸ˆà¸²à¸°à¸ˆà¸‡à¹à¸«à¸¥à¹ˆà¸‡" + +#: ../gio/gsocket.c:2470 +#, c-format +msgid "Error accepting connection: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะรับà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ: %s" + +#: ../gio/gsocket.c:2593 +msgid "Connection in progress" +msgstr "à¸à¸³à¸¥à¸±à¸‡à¸­à¸¢à¸¹à¹ˆà¸£à¸°à¸«à¸§à¹ˆà¸²à¸‡à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ" + +#: ../gio/gsocket.c:2644 +msgid "Unable to get pending error: " +msgstr "อ่านข้อผิดพลาดที่คั่งค้างอยู่ไม่สำเร็จ: " + +#: ../gio/gsocket.c:2816 +#, c-format +msgid "Error receiving data: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะรับข้อมูล: %s" + +#: ../gio/gsocket.c:3013 +#, c-format +msgid "Error sending data: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะส่งข้อมูล: %s" + +#: ../gio/gsocket.c:3200 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ปิดà¸à¸²à¸£à¸—ำงานซ็อà¸à¹€à¸à¹‡à¸•ไม่สำเร็จ: %s" + +#: ../gio/gsocket.c:3281 +#, c-format +msgid "Error closing socket: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะปิดซ็อà¸à¹€à¸à¹‡à¸•: %s" + +#: ../gio/gsocket.c:3890 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "à¸à¸³à¸¥à¸±à¸‡à¸£à¸­à¹€à¸‡à¸·à¹ˆà¸­à¸™à¹„ขของซ็อà¸à¹€à¸à¹‡à¸•: %s" + +#: ../gio/gsocket.c:4362 ../gio/gsocket.c:4442 ../gio/gsocket.c:4620 +#, c-format +msgid "Error sending message: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะส่งข้อความ: %s" + +#: ../gio/gsocket.c:4386 +msgid "GSocketControlMessage not supported on Windows" +msgstr "ไม่รองรับ GSocketControlMessage บนวินโดวส์" + +#: ../gio/gsocket.c:4839 ../gio/gsocket.c:4912 ../gio/gsocket.c:5139 +#, c-format +msgid "Error receiving message: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะรับข้อความ: %s" + +#: ../gio/gsocket.c:5411 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "อ่านข้อมูลลับของซ็อà¸à¹€à¸à¹‡à¸•ไม่สำเร็จ: %s" + +#: ../gio/gsocket.c:5420 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "ยังไม่รองรับ g_socket_get_credentials สำหรับระบบปà¸à¸´à¸šà¸±à¸•ิà¸à¸²à¸£à¸™à¸µà¹‰" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "ไม่สามารถเชื่อมต่อไปยังเซิร์ฟเวอร์พร็อà¸à¸‹à¸µ %s: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "ไม่สามารถเชื่อมต่อไปยัง %s: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "ไม่สามารถเชื่อมต่อ: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดไม่ทราบสาเหตุขณะเชื่อมต่อ" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "ไม่รองรับà¸à¸²à¸£à¸—ำพร็อà¸à¸‹à¸µà¸œà¹ˆà¸²à¸™à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อที่ไม่ใช่ TCP" + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "ไม่รองรับโพรโทคอล '%s' สำหรับพร็อà¸à¸‹à¸µ" + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "Listener ถูà¸à¸›à¸´à¸”ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "ซ็อà¸à¹€à¸à¹‡à¸•ที่เพิ่มถูà¸à¸›à¸´à¸”ไปà¹à¸¥à¹‰à¸§" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 ไม่รองรับที่อยู่ IPv6 '%s'" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "ชื่อผู้ใช้ยาวเà¸à¸´à¸™à¹„ปสำหรับโพรโทคอล SOCKSv4" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "ชื่อโฮสต์ '%s' ยาวเà¸à¸´à¸™à¹„ปสำหรับโพรโทคอล SOCKSv4" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "เซิร์ฟเวอร์ไม่ได้เป็นพร็อà¸à¸‹à¸µà¸ªà¸³à¸«à¸£à¸±à¸š SOCKSv4" + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อผ่านเซิร์ฟเวอร์ SOCKSv4 ถูà¸à¸›à¸à¸´à¹€à¸ªà¸˜" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "เซิร์ฟเวอร์ไม่ได้เป็นพร็อà¸à¸‹à¸µà¸ªà¸³à¸«à¸£à¸±à¸š SOCKSv5" + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "พร็อà¸à¸‹à¸µ SOCKSv5 ต้องà¸à¸²à¸£à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•ัวบุคคล" + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "พร็อà¸à¸‹à¸µ SOCKSv5 ต้องà¸à¸²à¸£à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•ัวบุคคลด้วยวิธีที่ GLib ไม่รองรับ" + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "ชื่อผู้ใช้หรือรหัสผ่านยาวเà¸à¸´à¸™à¹„ปสำหรับโพรโทคอล SOCKSv5" + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•ัวบุคคลของ SOCKSv5 ล้มเหลว เพราะชื่อผู้ใช้หรือรหัสผ่านไม่ถูà¸à¸•้อง" + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "ชื่อโฮสต์ '%s' ยาวเà¸à¸´à¸™à¹„ปสำหรับโพรโทคอล SOCKSv5" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "เซิร์ฟเวอร์พร็อà¸à¸‹à¸µ SOCKSv5 ใช้ที่อยู่ที่ไม่ทราบชนิด" + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "เà¸à¸´à¸”ข้อผิดพลาดภายในของเซิร์ฟเวอร์พร็อà¸à¸‹à¸µ SOCKSv5" + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "ชุดà¸à¸Žà¹€à¸à¸“ฑ์ไม่อนุà¸à¸²à¸•ให้เชื่อมต่อ SOCKSv5" + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "ไม่สามารถติดต่อโฮสต์ผ่านเซิร์ฟเวอร์ SOCKSv5 ได้" + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "ไม่สามารถติดต่อเครือข่ายผ่านพร็อà¸à¸‹à¸µ SOCKSv5" + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อผ่านพร็อà¸à¸‹à¸µ SOCKSv5 ถูà¸à¸›à¸à¸´à¹€à¸ªà¸˜" + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "พร็อà¸à¸‹à¸µ SOCKSv5 ไม่รองรับคำสั่ง 'connect'" + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "พร็อà¸à¸‹à¸µ SOCKSv5 ไม่รองรับที่อยู่ชนิดที่à¸à¸³à¸«à¸™à¸”มา" + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "เà¸à¸´à¸”ข้อผิดพลาดไม่ทราบสาเหตุที่พร็อà¸à¸‹à¸µ SOCKSv5" + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "ไม่สามารถจัดà¸à¸²à¸£à¸à¸±à¸šà¸£à¸«à¸±à¸ªà¸‚อง GThemedIcon รุ่น %d ได้" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "ไม่พบที่อยู่ที่ถูà¸à¸•้อง" + +#: ../gio/gthreadedresolver.c:213 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดหาที่อยู่ '%s' ย้อนà¸à¸¥à¸±à¸š: %s" + +#: ../gio/gthreadedresolver.c:550 ../gio/gthreadedresolver.c:630 +#: ../gio/gthreadedresolver.c:728 ../gio/gthreadedresolver.c:778 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "ไม่มีระเบียน DNS ชนิดที่ร้องขอสำหรับ '%s'" + +#: ../gio/gthreadedresolver.c:555 ../gio/gthreadedresolver.c:733 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "ไม่สามารถเปิดหาที่อยู่ '%s' ได้ชั่วคราว" + +#: ../gio/gthreadedresolver.c:560 ../gio/gthreadedresolver.c:738 +#, c-format +msgid "Error resolving '%s'" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดหาที่อยู่ '%s'" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "ไม่สามารถถอดรหัสลับà¸à¸¸à¸à¹à¸ˆà¸ªà¹ˆà¸§à¸™à¸•ัวที่ลงรหัสà¹à¸šà¸š PEM" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "ไม่พบà¸à¸¸à¸à¹à¸ˆà¸ªà¹ˆà¸§à¸™à¸•ัวที่ลงรหัสà¹à¸šà¸š PEM" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "ไม่สามารถà¹à¸ˆà¸‡à¸à¸¸à¸à¹à¸ˆà¸ªà¹ˆà¸§à¸™à¸•ัวที่ลงรหัสà¹à¸šà¸š PEM" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "ไม่พบใบรับรองที่ลงรหัสà¹à¸šà¸š PEM" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "ไม่สามารถà¹à¸ˆà¸‡à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸—ี่ลงรหัสà¹à¸šà¸š PEM" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "นี่เป็นโอà¸à¸²à¸ªà¸ªà¸¸à¸”ท้ายที่คุณจะป้อนรหัสผ่านให้ถูà¸à¸•้อง à¸à¹ˆà¸­à¸™à¸—ี่à¸à¸²à¸£à¹€à¸‚้าถึงของคุณจะถูà¸à¸¥à¹‡à¸­à¸„" + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "รหัสผ่านผิดหลายครั้ง à¸à¸²à¸£à¹€à¸‚้าถึงของคุณจะถูà¸à¸¥à¹‡à¸­à¸„ในที่สุดถ้าคุณยังป้อนผิดอยู่" + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "รหัสผ่านไม่ถูà¸à¸•้อง" + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:561 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "ต้องà¸à¸²à¸£à¸‚้อความควบคุม 1 ข้อความ à¹à¸•่ได้รับ %d ข้อความ" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:573 +msgid "Unexpected type of ancillary data" +msgstr "พบข้อมูลช่วยเป็นชนิดที่ไม่คาดหมาย" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "ต้องà¸à¸²à¸£ fd หนึ่งรายà¸à¸²à¸£ à¹à¸•่ได้รับ %d รายà¸à¸²à¸£\n" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "ได้รับ fd ที่ไม่ถูà¸à¸•้อง" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะส่งข้อมูลลับ: " + +#: ../gio/gunixconnection.c:503 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะตรวจสอบว่าเปิดใช้ SO_PASSCRED à¸à¸±à¸šà¸‹à¹‡à¸­à¸à¹€à¸à¹‡à¸•หรือไม่: %s" + +#: ../gio/gunixconnection.c:518 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดใช้ SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:547 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "ต้องà¸à¸²à¸£à¸­à¹ˆà¸²à¸™à¸«à¸™à¸¶à¹ˆà¸‡à¹„บต์เพื่อรับข้อมูลลับ à¹à¸•่ไม่ได้รับสัà¸à¹„บต์" + +#: ../gio/gunixconnection.c:587 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "ไม่ต้องà¸à¸²à¸£à¸‚้อความควบคุม à¹à¸•่ได้รับ %d ข้อความ" + +#: ../gio/gunixconnection.c:611 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะปิด SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:369 ../gio/gunixinputstream.c:390 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านจาภfile descriptor: %s" + +#: ../gio/gunixinputstream.c:423 ../gio/gunixoutputstream.c:409 +#: ../gio/gwin32inputstream.c:217 ../gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะปิด file descriptor: %s" + +#: ../gio/gunixmounts.c:2329 ../gio/gunixmounts.c:2382 +msgid "Filesystem root" +msgstr "ราà¸à¸£à¸°à¸šà¸šà¹à¸Ÿà¹‰à¸¡" + +#: ../gio/gunixoutputstream.c:355 ../gio/gunixoutputstream.c:376 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเขียนลง file descriptor: %s" + +#: ../gio/gunixsocketaddress.c:239 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "ระบบนี้ไม่รองรับที่อยู่ UNIX domain socket à¹à¸šà¸š abstract" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "โวลุมยังไม่รองรับà¸à¸²à¸£à¸”ันสื่อออà¸" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "โวลุมยังไม่รองรับคำสั่ง eject หรือ eject_with_operation" + +#: ../gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านจาภhandle: %s" + +#: ../gio/gwin32inputstream.c:232 ../gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะปิด handle: %s" + +#: ../gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเขียนลง handle: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "หน่วยความจำไม่พอ" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "ข้อผิดพลาดภายใน: %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "ต้องà¸à¸²à¸£à¸‚้อมูลเข้าเพิ่มเติม" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "ข้อมูลบีบอัดผิดรูปà¹à¸šà¸š" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ที่อยู่ที่จะใช้รอรับà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "ไม่สนใจ มีเพื่อให้เข้าà¸à¸±à¸™à¹„ด้à¸à¸±à¸š GTestDbus" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "à¹à¸ªà¸”งที่อยู่" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "à¹à¸ªà¸”งที่อยู่ในà¹à¸šà¸šà¹€à¸Šà¸¥à¸¥à¹Œ" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "ทำงานเป็นบริà¸à¸²à¸£ dbus" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "อาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์ไม่ถูà¸à¸•้อง\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "พบà¹à¸­à¸•ทริบิวต์ '%s' ที่ไม่ต้องà¸à¸²à¸£ สำหรับอิลิเมนต์ '%s'" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "ไม่พบà¹à¸­à¸•ทริบิวต์ '%s' สำหรับอิลิเมนต์ '%s'" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "พบà¹à¸—็ภ'%s' ที่ไม่ต้องà¸à¸²à¸£ ขณะที่ต้องà¸à¸²à¸£à¹à¸—็ภ'%s'" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "พบà¹à¸—็ภ'%s' ที่ไม่ต้องà¸à¸²à¸£à¸ à¸²à¸¢à¹ƒà¸™ '%s'" + +#: ../glib/gbookmarkfile.c:1757 +msgid "No valid bookmark file found in data dirs" +msgstr "ไม่พบà¹à¸Ÿà¹‰à¸¡à¸—ี่คั่นหน้าที่ใช้à¸à¸²à¸£à¹„ด้ในไดเรà¸à¸—อรีข้อมูล" + +#: ../glib/gbookmarkfile.c:1958 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "มีที่คั่นหน้าสำหรับ URI '%s' อยู่à¸à¹ˆà¸­à¸™à¹à¸¥à¹‰à¸§" + +#: ../glib/gbookmarkfile.c:2004 ../glib/gbookmarkfile.c:2162 +#: ../glib/gbookmarkfile.c:2247 ../glib/gbookmarkfile.c:2327 +#: ../glib/gbookmarkfile.c:2412 ../glib/gbookmarkfile.c:2495 +#: ../glib/gbookmarkfile.c:2573 ../glib/gbookmarkfile.c:2652 +#: ../glib/gbookmarkfile.c:2694 ../glib/gbookmarkfile.c:2791 +#: ../glib/gbookmarkfile.c:2911 ../glib/gbookmarkfile.c:3101 +#: ../glib/gbookmarkfile.c:3177 ../glib/gbookmarkfile.c:3345 +#: ../glib/gbookmarkfile.c:3434 ../glib/gbookmarkfile.c:3523 +#: ../glib/gbookmarkfile.c:3639 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "ไม่พบที่คั่นหน้าสำหรับ URI '%s'" + +#: ../glib/gbookmarkfile.c:2336 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "ไม่ได้à¸à¸³à¸«à¸™à¸”ชนิด MIME ไว้ในที่คั่นหน้าสำหรับ URI '%s'" + +#: ../glib/gbookmarkfile.c:2421 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "ไม่ได้à¸à¸³à¸«à¸™à¸”à¹à¸Ÿà¸¥à¹‡à¸à¸ªà¹ˆà¸§à¸™à¸•ัวไว้ในที่คั่นหน้าสำหรับ URI '%s'" + +#: ../glib/gbookmarkfile.c:2800 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "ไม่ได้à¸à¸³à¸«à¸™à¸”à¸à¸¥à¸¸à¹ˆà¸¡à¹„ว้ในที่คั่นหน้าสำหรับ URI '%s'" + +#: ../glib/gbookmarkfile.c:3198 ../glib/gbookmarkfile.c:3355 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "ไม่มีโปรà¹à¸à¸£à¸¡à¸›à¸£à¸°à¸¢à¸¸à¸à¸•์ชื่อ '%s' ที่ลงทะเบียนที่คั่นหน้าสำหรับ '%s' ไว้" + +#: ../glib/gbookmarkfile.c:3378 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "à¸à¸£à¸°à¸ˆà¸²à¸¢à¸šà¸£à¸£à¸—ัดคำสั่ง '%s' ด้วย URI '%s' ไม่สำเร็จ" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:851 ../glib/gutf8.c:1063 +#: ../glib/gutf8.c:1200 ../glib/gutf8.c:1304 +msgid "Partial character sequence at end of input" +msgstr "มีลำดับไบต์ไม่เต็มอัà¸à¸‚ระอยู่ที่ท้ายข้อมูลเข้า" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "ไม่สามารถà¹à¸›à¸¥à¸‡à¸ªà¸•ริงซ่อมเสริม '%s' ให้เป็นรหัส '%s' ได้" + +#: ../glib/gconvert.c:1567 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI '%s' ไม่ใช่ URI สัมบูรณ์ที่ใช้ scheme \"file\"" + +#: ../glib/gconvert.c:1577 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "URI ของà¹à¸Ÿà¹‰à¸¡à¸—้องถิ่น '%s' ต้องไม่มี '#'" + +#: ../glib/gconvert.c:1594 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI '%s' ใช้ไม่ได้" + +#: ../glib/gconvert.c:1606 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "ชื่อโฮสต์ของ URI '%s' ใช้ไม่ได้" + +#: ../glib/gconvert.c:1622 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI '%s' มีอัà¸à¸‚ระหลีà¸à¸—ี่ไม่ถูà¸à¸•้อง" + +#: ../glib/gconvert.c:1717 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "ชื่อพาธ '%s' ไม่ใช่พาธเต็ม" + +#: ../glib/gconvert.c:1727 +msgid "Invalid hostname" +msgstr "ชื่อโฮสต์ผิดรูปà¹à¸šà¸š" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %e %b %Ey, %H:%M:%S" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%Ey" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "มà¸à¸£à¸²à¸„ม" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "à¸à¸¸à¸¡à¸ à¸²à¸žà¸±à¸™à¸˜à¹Œ" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "มีนาคม" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "เมษายน" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "พฤษภาคม" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "มิถุนายน" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "à¸à¸£à¸à¸Žà¸²à¸„ม" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "สิงหาคม" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "à¸à¸±à¸™à¸¢à¸²à¸¢à¸™" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "ตุลาคม" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "พฤศจิà¸à¸²à¸¢à¸™" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "ธันวาคม" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "ม.ค." + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "à¸.พ." + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "มี.ค." + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "เม.ย." + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "พ.ค." + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "มิ.ย." + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "à¸.ค." + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "ส.ค." + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "à¸.ย." + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "ต.ค." + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "พ.ย." + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ธ.ค." + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "จันทร์" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "อังคาร" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "พุธ" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "พฤหัสบดี" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "ศุà¸à¸£à¹Œ" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "เสาร์" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "อาทิตย์" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "จ." + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "อ." + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "พ." + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "พฤ." + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ศ." + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "ส." + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "อา." + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดไดเรà¸à¸—อรี '%s': %s" + +#: ../glib/gfileutils.c:701 ../glib/gfileutils.c:793 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "ไม่สามารถจองหน่วยความจำ %lu ไบต์เพื่ออ่านà¹à¸Ÿà¹‰à¸¡ \"%s\"" + +#: ../glib/gfileutils.c:718 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านà¹à¸Ÿà¹‰à¸¡ '%s': %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "File \"%s\" is too large" +msgstr "à¹à¸Ÿà¹‰à¸¡ \"%s\" ใหà¸à¹ˆà¹€à¸à¸´à¸™à¹„ป" + +#: ../glib/gfileutils.c:818 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "อ่านข้อมูลจาà¸à¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: %s" + +#: ../glib/gfileutils.c:866 ../glib/gfileutils.c:938 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "เปิดà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: %s" + +#: ../glib/gfileutils.c:878 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "อ่านà¹à¸­à¸•ทริบิวต์ของà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: fstat() ล้มเหลว: %s" + +#: ../glib/gfileutils.c:908 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "เปิดà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: fdopen() ล้มเหลว: %s" + +#: ../glib/gfileutils.c:1007 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "เปลี่ยนชื่อà¹à¸Ÿà¹‰à¸¡ '%s' ไปเป็น '%s' ไม่สำเร็จ: g_rename() ล้มเหลว: %s" + +#: ../glib/gfileutils.c:1042 ../glib/gfileutils.c:1541 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "สร้างà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: %s" + +#: ../glib/gfileutils.c:1069 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "เขียนà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: write() ล้มเหลว: %s" + +#: ../glib/gfileutils.c:1112 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "เขียนà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: fsync() ล้มเหลว: %s" + +#: ../glib/gfileutils.c:1236 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "ไม่สามารถลบà¹à¸Ÿà¹‰à¸¡ '%s' ที่มีอยู่ได้: g_unlink() ล้มเหลว: %s" + +#: ../glib/gfileutils.c:1507 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "à¹à¸¡à¹ˆà¹à¸šà¸š '%s' ใช้ไม่ได้ ไม่ควรมี '%s'" + +#: ../glib/gfileutils.c:1520 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "à¹à¸¡à¹ˆà¹à¸šà¸š '%s' ไม่มี XXXXXX" + +#: ../glib/gfileutils.c:2045 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "อ่านลิงà¸à¹Œà¸ªà¸±à¸à¸¥à¸±à¸à¸©à¸“์ '%s' ไม่สำเร็จ: %s" + +#: ../glib/giochannel.c:1388 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "ไม่สามารถเปิดตัวà¹à¸›à¸¥à¸‡à¸£à¸«à¸±à¸ªà¸­à¸±à¸à¸‚ระจาภ'%s' ไปเป็น '%s' ได้: %s" + +#: ../glib/giochannel.c:1733 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "ไม่สามารถอ่านข้อมูลà¹à¸šà¸šà¸”ิบใน g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1780 ../glib/giochannel.c:2038 +#: ../glib/giochannel.c:2125 +msgid "Leftover unconverted data in read buffer" +msgstr "มีข้อมูลตà¸à¸„้างไม่ได้à¹à¸›à¸¥à¸‡à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸šà¸±à¸Ÿà¹€à¸Ÿà¸­à¸£à¹Œà¸ªà¸³à¸«à¸£à¸±à¸šà¸­à¹ˆà¸²à¸™" + +#: ../glib/giochannel.c:1861 ../glib/giochannel.c:1938 +msgid "Channel terminates in a partial character" +msgstr "à¹à¸Šà¸™à¹€à¸™à¸¥à¸ˆà¸šà¸”้วยข้อมูลไม่เต็มอัà¸à¸‚ระ" + +#: ../glib/giochannel.c:1924 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "ไม่สามารถอ่านข้อมูลà¹à¸šà¸šà¸”ิบใน g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:737 +msgid "Valid key file could not be found in search dirs" +msgstr "ไม่พบà¹à¸Ÿà¹‰à¸¡à¸„ีย์ที่ใช้à¸à¸²à¸£à¹„ด้ในไดเรà¸à¸—อรีà¹à¸«à¸¥à¹ˆà¸‡à¸„้นหา" + +#: ../glib/gkeyfile.c:773 +msgid "Not a regular file" +msgstr "ไม่ใช่à¹à¸Ÿà¹‰à¸¡à¸›à¸à¸•ิ" + +#: ../glib/gkeyfile.c:1204 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์มีบรรทัด '%s' ซึ่งไม่ใช่รูปà¹à¸šà¸šà¸„ู่คีย์-ค่า, à¸à¸¥à¸¸à¹ˆà¸¡, หรือหมายเหตุ ที่ถูà¸à¸•้อง" + +#: ../glib/gkeyfile.c:1261 +#, c-format +msgid "Invalid group name: %s" +msgstr "ชื่อà¸à¸¥à¸¸à¹ˆà¸¡à¸œà¸´à¸”รูปà¹à¸šà¸š: %s" + +#: ../glib/gkeyfile.c:1283 +msgid "Key file does not start with a group" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์ไม่ได้ขึ้นต้นด้วยà¸à¸¥à¸¸à¹ˆà¸¡" + +#: ../glib/gkeyfile.c:1309 +#, c-format +msgid "Invalid key name: %s" +msgstr "ชื่อคีย์ผิดรูปà¹à¸šà¸š: %s" + +#: ../glib/gkeyfile.c:1336 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์มีเนื้อหาเป็นรหัสอัà¸à¸‚ระ '%s' ซึ่งไม่รองรับ" + +#: ../glib/gkeyfile.c:1579 ../glib/gkeyfile.c:1752 ../glib/gkeyfile.c:3130 +#: ../glib/gkeyfile.c:3193 ../glib/gkeyfile.c:3323 ../glib/gkeyfile.c:3453 +#: ../glib/gkeyfile.c:3597 ../glib/gkeyfile.c:3826 ../glib/gkeyfile.c:3893 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์ไม่มีà¸à¸¥à¸¸à¹ˆà¸¡ '%s'" + +#: ../glib/gkeyfile.c:1707 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์ไม่มีคีย์ '%s' ในà¸à¸¥à¸¸à¹ˆà¸¡ '%s'" + +#: ../glib/gkeyfile.c:1869 ../glib/gkeyfile.c:1985 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์มีคีย์ '%s' ซึ่งมีค่า '%s' ซึ่งไม่ใช่รูปà¹à¸šà¸š UTF-8" + +#: ../glib/gkeyfile.c:1889 ../glib/gkeyfile.c:2005 ../glib/gkeyfile.c:2374 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์มีคีย์ '%s' ซึ่งมีค่าที่ไม่สามารถตีความได้" + +#: ../glib/gkeyfile.c:2591 ../glib/gkeyfile.c:2959 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์มีคีย์ '%s' ในà¸à¸¥à¸¸à¹ˆà¸¡ '%s' ซึ่งมีค่าที่ไม่สามารถตีความได้" + +#: ../glib/gkeyfile.c:2669 ../glib/gkeyfile.c:2746 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "คีย์ '%s' ในà¸à¸¥à¸¸à¹ˆà¸¡ '%s' มีค่า '%s' à¹à¸•่ต้องà¸à¸²à¸£à¸„่า %s" + +#: ../glib/gkeyfile.c:4133 +msgid "Key file contains escape character at end of line" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์มีอัà¸à¸‚ระหลีà¸à¸—ี่ท้ายบรรทัด" + +#: ../glib/gkeyfile.c:4155 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์มีลำดับหลีภ'%s' ที่ไม่ถูà¸à¸•้อง" + +#: ../glib/gkeyfile.c:4297 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "ค่า '%s' ไม่สามารถตีความเป็นตัวเลขได้" + +#: ../glib/gkeyfile.c:4311 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "ค่าจำนวนเต็ม '%s' ออà¸à¸™à¸­à¸à¸Šà¹ˆà¸§à¸‡" + +#: ../glib/gkeyfile.c:4344 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "ค่า '%s' ไม่สามารถตีความเป็นตัวเลข float ได้" + +#: ../glib/gkeyfile.c:4383 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "ค่า '%s' ไม่สามารถตีความเป็นบูลีนได้" + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "อ่านà¹à¸­à¸•ทริบิวต์ของà¹à¸Ÿà¹‰à¸¡ '%s%s%s%s' ไม่สำเร็จ: fstat() ล้มเหลว: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "à¹à¸¡à¹‡à¸›à¹à¸Ÿà¹‰à¸¡ '%s%s%s%s' ไม่สำเร็จ: mmap() ล้มเหลว: %s" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "เปิดà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: open() ล้มเหลว: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "มีข้อผิดพลาดที่บรรทัด %d อัà¸à¸‚ระที่ %d: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "พบข้อความลงรหัส UTF-8 ไม่ถูà¸à¸•้องในชื่อ - ข้อความที่ผิด: '%s'" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "'%s' ไม่ใช่ชื่อที่ใช้ได้" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "'%s' ไม่ใช่ชื่อที่ใช้ได้: '%c'" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "มีข้อผิดพลาดที่บรรทัด %d: %s" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"ไม่สามารถà¹à¸ˆà¸‡ '%-.*s' ซึ่งควรจะเป็นตัวเลขภายในตัวอ้างอิงอัà¸à¸‚ระ (เช่น ê) " +"เป็นไปได้ว่าตัวเลขอาจจะมาà¸à¹€à¸à¸´à¸™à¹„ป" + +#: ../glib/gmarkup.c:688 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"ตัวอ้างอิงอัà¸à¸‚ระไม่ได้ปิดด้วยอัฒภาค เป็นไปได้สูงที่คุณอาจใช้ ampersand โดยไม่ได้จงใจให้เริ่มเอนทิตี " +"ถ้าใช่ à¸à¹‡à¸ˆà¸‡à¸«à¸¥à¸µà¸ ampersand โดยà¹à¸—นด้วย & เสีย" + +#: ../glib/gmarkup.c:714 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "ตัวอ้างอิงอัà¸à¸‚ระ '%-.*s' ไม่ได้ลงรหัสอัà¸à¸‚ระที่อนุà¸à¸²à¸•ให้ใช้ได้" + +#: ../glib/gmarkup.c:752 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "พบเอนทิตีว่างเปล่า '&;' ซึ่งไม่ถูà¸à¸•้อง ค่าที่ใช้ได้คือ: & " < > '" + +#: ../glib/gmarkup.c:760 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "ไม่รู้จัà¸à¹€à¸­à¸™à¸—ิตีชื่อ '%-.*s'" + +#: ../glib/gmarkup.c:765 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"เอนทิตีไม่ได้ปิดด้วยอัฒภาค เป็นไปได้สูงที่คุณอาจใช้ ampersand โดยไม่ได้จงใจให้เริ่มเอนทิตี ถ้าใช่ " +"à¸à¹‡à¸ˆà¸‡à¸«à¸¥à¸µà¸ ampersand โดยà¹à¸—นด้วย & เสีย" + +#: ../glib/gmarkup.c:1171 +msgid "Document must begin with an element (e.g. )" +msgstr "เอà¸à¸ªà¸²à¸£à¸•้องเริ่มด้วยอิลิเมนต์ (เช่น )" + +#: ../glib/gmarkup.c:1211 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "'%s' ไม่ใช่อัà¸à¸‚ระที่ใช้ตามหลัง '<' ได้ จึงไม่สามารถใช้ขึ้นต้นชื่ออิลิเมนต์ได้" + +#: ../glib/gmarkup.c:1253 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "พบอัà¸à¸‚ระà¹à¸›à¸¥à¸à¸›à¸¥à¸­à¸¡ '%s' ในขณะที่มองหาอัà¸à¸‚ระ '>' ที่จะมาปิดà¹à¸—็à¸à¸­à¸´à¸¥à¸´à¹€à¸¡à¸™à¸•์เปล่า '%s'" + +#: ../glib/gmarkup.c:1334 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"พบอัà¸à¸‚ระà¹à¸›à¸¥à¸à¸›à¸¥à¸­à¸¡ '%s' ในขณะที่à¸à¸³à¸¥à¸±à¸‡à¸¡à¸­à¸‡à¸«à¸² '=' หลังชื่อà¹à¸­à¸•ทริบิวต์ '%s' ของอิลิเมนต์ '%s'" + +#: ../glib/gmarkup.c:1375 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"พบอัà¸à¸‚ระà¹à¸›à¸¥à¸à¸›à¸¥à¸­à¸¡ '%s' ในขณะที่à¸à¸³à¸¥à¸±à¸‡à¸¡à¸­à¸‡à¸«à¸² '>' หรือ '/' ที่จะมาปิดà¹à¸—็à¸à¸•ั้งต้นของอิลิเมนต์ " +"'%s' หรือไม่à¸à¹‡à¹€à¸›à¹‡à¸™à¹à¸­à¸•ทริบิวต์ เป็นไปได้ว่าคุณà¸à¸³à¸¥à¸±à¸‡à¹ƒà¸Šà¹‰à¸­à¸±à¸à¸‚ระที่ใช้ไม่ได้ในชื่อà¹à¸­à¸•ทริบิวต์" + +#: ../glib/gmarkup.c:1419 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"พบอัà¸à¸‚ระà¹à¸›à¸¥à¸à¸›à¸¥à¸­à¸¡ '%s' ในขณะที่à¸à¸³à¸¥à¸±à¸‡à¸¡à¸­à¸‡à¸«à¸²à¸­à¸±à¸à¸›à¸£à¸°à¸à¸²à¸¨à¹€à¸›à¸´à¸”หลัง '=' " +"ในà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าให้à¸à¸±à¸šà¹à¸­à¸•ทริบิวต์ '%s' ของอิลิเมนต์ '%s'" + +#: ../glib/gmarkup.c:1552 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "'%s' ไม่ใช่อัà¸à¸‚ระที่ใช้ตามหลังชื่ออิลิเมนต์ '%s' ในà¹à¸—็à¸à¸›à¸´à¸”ได้ อัà¸à¸‚ระเดียวที่อนุà¸à¸²à¸•คือ '>'" + +#: ../glib/gmarkup.c:1599 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "พบà¸à¸²à¸£à¸›à¸´à¸”อิลิเมนต์ '%s' à¹à¸•่ไม่มีอิลิเมนต์ใดเปิดอยู่" + +#: ../glib/gmarkup.c:1608 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "พบà¸à¸²à¸£à¸›à¸´à¸”อิลิเมนต์ '%s' à¹à¸•่อิลิเมนต์ที่เปิดอยู่คือ '%s'" + +#: ../glib/gmarkup.c:1761 +msgid "Document was empty or contained only whitespace" +msgstr "เอà¸à¸ªà¸²à¸£à¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸² หรือมีà¹à¸•่อัà¸à¸‚ระช่องว่าง" + +#: ../glib/gmarkup.c:1775 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิหลังจาà¸à¸§à¸‡à¹€à¸¥à¹‡à¸šà¹à¸«à¸¥à¸¡ '<'" + +#: ../glib/gmarkup.c:1783 ../glib/gmarkup.c:1828 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิ โดยยังมีอิลิเมนต์เปิดอยู่ - '%s' คืออิลิเมนต์ที่เปิดล่าสุด" + +#: ../glib/gmarkup.c:1791 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิ ในขณะที่à¸à¸³à¸¥à¸±à¸‡à¸¡à¸­à¸‡à¸«à¸²à¸§à¸‡à¹€à¸¥à¹‡à¸šà¹à¸«à¸¥à¸¡à¸—ี่จะมาปิดà¹à¸—็ภ<%s/>" + +#: ../glib/gmarkup.c:1797 +msgid "Document ended unexpectedly inside an element name" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิระหว่างà¸à¸¥à¸²à¸‡à¸Šà¸·à¹ˆà¸­à¸­à¸´à¸¥à¸´à¹€à¸¡à¸™à¸•์" + +#: ../glib/gmarkup.c:1803 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิระหว่างà¸à¸¥à¸²à¸‡à¸Šà¸·à¹ˆà¸­à¹à¸­à¸•ทริบิวต์" + +#: ../glib/gmarkup.c:1808 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิระหว่างà¸à¸¥à¸²à¸‡à¹à¸—็à¸à¹€à¸›à¸´à¸”อิลิเมนต์" + +#: ../glib/gmarkup.c:1814 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิหลังจาà¸à¹€à¸„รื่องหมาย '=' หลังชื่อà¹à¸­à¸•ทริบิวต์ โดยไม่มีค่าของà¹à¸­à¸•ทริบิวต์" + +#: ../glib/gmarkup.c:1821 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิระหว่างà¸à¸¥à¸²à¸‡à¸„่าà¹à¸­à¸•ทริบิวต์" + +#: ../glib/gmarkup.c:1837 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิระหว่างà¸à¸¥à¸²à¸‡à¹à¸—็à¸à¸›à¸´à¸”สำหรับอิลิเมนต์ '%s'" + +#: ../glib/gmarkup.c:1843 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "เอà¸à¸ªà¸²à¸£à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิระหว่างà¸à¸¥à¸²à¸‡à¸«à¸¡à¸²à¸¢à¹€à¸«à¸•ุหรือคำสั่งประมวลผล" + +#: ../glib/goption.c:861 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:977 +msgid "Help Options:" +msgstr "ตัวเลือà¸à¹à¸ªà¸”งวิธีใช้:" + +#: ../glib/goption.c:978 +msgid "Show help options" +msgstr "à¹à¸ªà¸”งวิธีใช้ตัวเลือà¸à¸•่างๆ" + +#: ../glib/goption.c:984 +msgid "Show all help options" +msgstr "à¹à¸ªà¸”งวิธีใช้ตัวเลือà¸à¸•่างๆ ทั้งหมด" + +#: ../glib/goption.c:1047 +msgid "Application Options:" +msgstr "ตัวเลือà¸à¸‚องโปรà¹à¸à¸£à¸¡:" + +#: ../glib/goption.c:1049 +msgid "Options:" +msgstr "ตัวเลือà¸:" + +#: ../glib/goption.c:1113 ../glib/goption.c:1183 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "ไม่สามารถà¹à¸ˆà¸‡à¸„่าจำนวนเต็ม '%s' สำหรับ %s" + +#: ../glib/goption.c:1123 ../glib/goption.c:1191 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "ค่าจำนวนเต็ม '%s' สำหรับ %s ออà¸à¸™à¸­à¸à¸Šà¹ˆà¸§à¸‡à¸—ี่à¸à¸³à¸«à¸™à¸”" + +#: ../glib/goption.c:1148 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "ไม่สามารถà¹à¸ˆà¸‡à¸„่า double '%s' สำหรับ %s" + +#: ../glib/goption.c:1156 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "ค่า double '%s' สำหรับ %s ออà¸à¸™à¸­à¸à¸Šà¹ˆà¸§à¸‡à¸—ี่à¸à¸³à¸«à¸™à¸”" + +#: ../glib/goption.c:1442 ../glib/goption.c:1521 +#, c-format +msgid "Error parsing option %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¹à¸ˆà¸‡à¸•ัวเลือà¸: %s" + +#: ../glib/goption.c:1552 ../glib/goption.c:1665 +#, c-format +msgid "Missing argument for %s" +msgstr "ขาดอาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์สำหรับ %s" + +#: ../glib/goption.c:2126 +#, c-format +msgid "Unknown option %s" +msgstr "ไม่รู้จัà¸à¸•ัวเลือภ%s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "ออบเจà¸à¸•์เสียหาย" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "ข้อผิดพลาดภายในหรือออบเจà¸à¸•์เสียหาย" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "หน่วยความจำเต็ม" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "เà¸à¸´à¸™à¸‚อบเขตà¸à¸²à¸£à¸–อยคืน" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "à¹à¸žà¸•เทิร์นมีรายà¸à¸²à¸£à¸—ี่ไม่รองรับในà¸à¸²à¸£à¸ˆà¸±à¸šà¸„ู่ทีละส่วน" + +#: ../glib/gregex.c:281 +msgid "internal error" +msgstr "ข้อผิดพลาดภายใน" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "ไม่รองรับà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¸¢à¹‰à¸­à¸™à¸à¸¥à¸±à¸šà¹€à¸›à¹‡à¸™à¹€à¸‡à¸·à¹ˆà¸­à¸™à¹„ขในà¸à¸²à¸£à¸ˆà¸±à¸šà¸„ู่ทีละส่วน" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "เà¸à¸´à¸™à¸‚อบเขตà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸•ัวเอง" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "ชุดของà¹à¸Ÿà¸¥à¹‡à¸à¸à¸²à¸£à¸‚ึ้นบรรทัดใหม่มีค่าไม่เข้าà¸à¸±à¸™" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "ออฟเซ็ตไม่ถูà¸à¸•้อง" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "UTF-8 ไม่ครบอัà¸à¸‚ระ" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "เà¸à¸´à¸”วงวนเรียà¸à¸•ัวเอง" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "ข้อผิดพลาดไม่ทราบสาเหตุ" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "พบ \\ ที่ท้ายà¹à¸žà¸•เทิร์น" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "พบ \\c ที่ท้ายà¹à¸žà¸•เทิร์น" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "พบอัà¸à¸‚ระที่ไม่รู้จัà¸à¸•ามหลัง \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "ค่าตัวเลขผิดพลาดในตัวระบุปริมาณ {}" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "ค่าตัวเลขสูงเà¸à¸´à¸™à¹„ปในตัวระบุปริมาณ {}" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "ไม่มี ] ปิดในคลาสอัà¸à¸‚ระ" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "มีลำดับอัà¸à¸‚ระหลีà¸à¸—ี่ไม่ถูà¸à¸•้องในคลาสอัà¸à¸‚ระ" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "ค่าช่วงผิดพลาดในคลาสอัà¸à¸‚ระ" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "ไม่มีสิ่งที่จะซ้ำ" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "พบà¸à¸²à¸£à¸‹à¹‰à¸³à¸—ี่ไม่คาดหมาย" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "พบอัà¸à¸‚ระที่ไม่รู้จัà¸à¸«à¸¥à¸±à¸‡ (? หรือ (?-" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "ใช้ชื่อคลาสอัà¸à¸‚ระของ POSIX ได้ในคลาสเท่านั้น" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "ไม่มี ) ปิด" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "มีà¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸–ึงà¹à¸žà¸•เทิร์นย่อยที่ไม่มีอยู่" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "ไม่มี ) หลังหมายเหตุ" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "นิพจน์เรà¸à¸à¸´à¸§à¸¥à¸²à¸£à¹Œà¸¢à¸²à¸§à¹€à¸à¸´à¸™à¹„ป" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "จองหน่วยความจำไม่สำเร็จ" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr "พบ ) โดยไม่มี ( เปิด" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "โค้ดล้น" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "พบอัà¸à¸‚ระที่ไม่รู้จัà¸à¸«à¸¥à¸±à¸‡ (?<" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "à¹à¸žà¸•เทิร์นตรวจค่าย้อนไม่ได้มีความยาวคงที่" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "ตัวเลขหรือชื่อผิดรูปà¹à¸šà¸šà¸«à¸¥à¸±à¸‡ (?(" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "à¸à¸¥à¸¸à¹ˆà¸¡à¹€à¸‡à¸·à¹ˆà¸­à¸™à¹„ขมีทางเลือà¸à¸—ี่เป็นไปได้มาà¸à¸à¸§à¹ˆà¸²à¸ªà¸­à¸‡à¸—าง" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "ต้องà¸à¸²à¸£à¹à¸žà¸•เทิร์นตรวจค่าหลัง (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R หรือ (?[+-]ตัวเลข ต้องตามด้วย ) เสมอ" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "พบชื่อคลาสของ POSIX ที่ไม่รู้จัà¸" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "ไม่รองรับ collating element ของ POSIX" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "ค่าอัà¸à¸‚ระในลำดับ \\x{...} มีค่าสูงเà¸à¸´à¸™à¹„ป" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "เงื่อนไข (?(0) ใช้ไม่ได้" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "ใช้ \\C ในà¹à¸žà¸•เทิร์นตรวจค่าย้อนไม่ได้" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "ไม่รองรับรหัสหลีภ\\L, \\l, \\N{ชื่อ}, \\U, à¹à¸¥à¸° \\u" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸•ัวเองมีโอà¸à¸²à¸ªà¸§à¸™à¸£à¸­à¸šà¹„ม่รู้จบ" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "พบอัà¸à¸‚ระที่ไม่รู้จัà¸à¸«à¸¥à¸±à¸‡ (?P" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "ไม่มีตัวปิดในชื่อà¹à¸žà¸•เทิร์นย่อย" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "มีà¹à¸žà¸•เทิร์นย่อยชื่อซ้ำà¸à¸±à¸™" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "ลำดับ \\P หรือ \\p ผิดรูปà¹à¸šà¸š" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "พบชื่อคุณสมบัติที่ไม่รู้จัà¸à¸«à¸¥à¸±à¸‡ \\P หรือ \\p" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "ชื่อà¹à¸žà¸•เทิร์นย่อยยาวเà¸à¸´à¸™à¹„ป (ความยาวสูงสุดคือ 32 อัà¸à¸‚ระ)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "มีà¹à¸žà¸•เทิร์นย่อยมาà¸à¹€à¸à¸´à¸™à¹„ป (สูงสุดได้ 10,000 à¹à¸žà¸•เทิร์น)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "ค่าเลขà¸à¸²à¸™à¹à¸›à¸”สูงà¸à¸§à¹ˆà¸² \\377" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "ใช้พื้นที่ทำงานสำหรับà¸à¸²à¸£à¸„อมไพล์หมดà¹à¸¥à¹‰à¸§" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "ไม่พบà¹à¸žà¸•เทิร์นย่อยที่ตรวจสอบไปà¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²à¸—ี่อ้างถึง" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "à¸à¸¥à¸¸à¹ˆà¸¡ DEFINE มีทางเลือà¸à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸«à¸™à¸¶à¹ˆà¸‡à¸—าง" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "ตัวเลือภNEWLINE ขัดà¹à¸¢à¹‰à¸‡à¸à¸±à¸™à¹€à¸­à¸‡" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g ไม่ได้ตามด้วยชื่อหรือตัวเลขในวงเล็บปีà¸à¸à¸² ในวงเล็บà¹à¸«à¸¥à¸¡ หรือในเครื่องหมายคำพูด " +"หรือไม่ได้ตามด้วยตัวเลขล้วน" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "à¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¸”้วยตัวเลขต้องไม่ใช่ศูนย์" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "ห้ามใช้อาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์สำหรับ (*ACCEPT), (*FAIL), หรือ (*COMMIT)" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "ไม่รู้จัภ(*VERB)" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "ตัวเลขใหà¸à¹ˆà¹€à¸à¸´à¸™à¹„ป" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "ไม่มีà¹à¸žà¸•เทิร์นย่อยหลัง (?&" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "ต้องà¸à¸²à¸£à¸•ัวเลขหลัง (?+" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] เป็นอัà¸à¸‚ระข้อมูลที่ใช้ไม่ได้ในโหมดเข้าà¸à¸±à¸™à¸à¸±à¸šà¸ˆà¸²à¸§à¸²à¸ªà¸„ริปต์" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ไม่อนุà¸à¸²à¸•ให้ใช้ชื่อที่ต่างà¸à¸±à¸™à¸ªà¸³à¸«à¸£à¸±à¸šà¹à¸žà¸•เทิร์นย่อยของจำนวนเดียวà¸à¸±à¸™" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) ต้องมีอาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c ต้องตามด้วยอัà¸à¸‚ระà¹à¸­à¸ªà¸à¸µ" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k ไม่ได้ตามด้วยชื่อในวงเล็บปีà¸à¸à¸² ในวงเล็บà¹à¸«à¸¥à¸¡ หรือในเครื่องหมายคำพูด" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "ไม่รองรับ \\N ในคลาส" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "มีà¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¹„ปข้างหน้ามาà¸à¹€à¸à¸´à¸™à¹„ป" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "ชื่อยาวเà¸à¸´à¸™à¹„ปใน (*MARK), (*PRUNE), (*SKIP), หรือ (*THEN)" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "ค่าอัà¸à¸‚ระในลำดับ \\u.... มีค่าสูงเà¸à¸´à¸™à¹„ป" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1977 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะจับคู่นิพจน์เรà¸à¸à¸´à¸§à¸¥à¸²à¸£à¹Œ %s: %s" + +#: ../glib/gregex.c:1317 +msgid "PCRE library is compiled without UTF8 support" +msgstr "ไลบรารี PCRE ถูà¸à¸„อมไพล์มาà¹à¸šà¸šà¹„ม่รองรับ UTF8" + +#: ../glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "ไลบรารี PCRE ถูà¸à¸„อมไพล์มาà¹à¸šà¸šà¹„ม่รองรับคุณสมบัติ UTF8" + +#: ../glib/gregex.c:1329 +msgid "PCRE library is compiled with incompatible options" +msgstr "ไลบรารี PCRE ถูà¸à¸„อมไพล์มาด้วยตัวเลือà¸à¸—ี่ไม่เข้าà¸à¸±à¸™" + +#: ../glib/gregex.c:1358 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะออปติไมซ์นิพจน์เรà¸à¸à¸´à¸§à¸¥à¸²à¸£à¹Œ %s: %s" + +#: ../glib/gregex.c:1438 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¹à¸ˆà¸‡à¸™à¸´à¸žà¸ˆà¸™à¹Œà¹€à¸£à¸à¸à¸´à¸§à¸¥à¸²à¸£à¹Œ %s ที่อัà¸à¸‚ระที่ %d: %s" + +#: ../glib/gregex.c:2413 +msgid "hexadecimal digit or '}' expected" +msgstr "ต้องà¸à¸²à¸£à¹€à¸¥à¸‚à¸à¸²à¸™à¸ªà¸´à¸šà¸«à¸à¸«à¸£à¸·à¸­ '}'" + +#: ../glib/gregex.c:2429 +msgid "hexadecimal digit expected" +msgstr "ต้องà¸à¸²à¸£à¹€à¸¥à¸‚à¸à¸²à¸™à¸ªà¸´à¸šà¸«à¸" + +#: ../glib/gregex.c:2469 +msgid "missing '<' in symbolic reference" +msgstr "ไม่มี '<' ในตัวอ้างอิงสัà¸à¸¥à¸±à¸à¸©à¸“์" + +#: ../glib/gregex.c:2478 +msgid "unfinished symbolic reference" +msgstr "ตัวอ้างอิงสัà¸à¸¥à¸±à¸à¸©à¸“์ไม่สมบูรณ์" + +#: ../glib/gregex.c:2485 +msgid "zero-length symbolic reference" +msgstr "ตัวอ้างอิงสัà¸à¸¥à¸±à¸à¸©à¸“์มีความยาวเป็นศูนย์" + +#: ../glib/gregex.c:2496 +msgid "digit expected" +msgstr "ต้องà¸à¸²à¸£à¸•ัวเลข" + +#: ../glib/gregex.c:2514 +msgid "illegal symbolic reference" +msgstr "ตัวอ้างอิงสัà¸à¸¥à¸±à¸à¸©à¸“์ไม่ถูà¸à¸•้อง" + +#: ../glib/gregex.c:2576 +msgid "stray final '\\'" +msgstr "'\\' ปราศจาà¸à¸‚้อมูลอยู่ที่ท้ายสตริง" + +#: ../glib/gregex.c:2580 +msgid "unknown escape sequence" +msgstr "ลำดับอัà¸à¸‚ระหลีà¸à¹„ม่รู้จัà¸" + +#: ../glib/gregex.c:2590 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะà¹à¸ˆà¸‡à¸‚้อความสำหรับà¹à¸—นที่ \"%s\" ที่อัà¸à¸‚ระที่ %lu: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "ข้อความคำพูดไม่ได้ขึ้นต้นด้วยอัà¸à¸›à¸£à¸°à¸à¸²à¸¨" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "พบอัà¸à¸›à¸£à¸°à¸à¸²à¸¨à¹„ม่เข้าคู่ในบรรทัดคำสั่งหรือข้อความคำพูดของเชลล์" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "ข้อความจบทันทีหลังอัà¸à¸‚ระ '\\' (ข้อความที่ว่าคือ '%s')" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "ข้อความจบเสียà¸à¹ˆà¸­à¸™à¸ˆà¸°à¸žà¸šà¸­à¸±à¸à¸›à¸£à¸°à¸à¸²à¸¨à¸—ี่เข้าคู่à¸à¸±à¸š %c (ข้อความที่ว่าคือ '%s')" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "ข้อความว่างเปล่า (หรือมีà¹à¸•่อัà¸à¸‚ระช่องว่าง)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "อ่านข้อมูลจาà¸à¹‚พรเซสลูà¸à¹„ม่สำเร็จ (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดไม่คาดหมายใน select() ระหว่างอ่านข้อมูลจาà¸à¹‚พรเซสลูภ(%s)" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดไม่คาดหมายใน waitpid() (%s)" + +#: ../glib/gspawn.c:844 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "โพรเซสลูà¸à¸ˆà¸šà¸à¸²à¸£à¸—ำงานด้วยรหัส %ld" + +#: ../glib/gspawn.c:852 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "โพรเซสลูà¸à¸–ูà¸à¸†à¹ˆà¸²à¸”้วยสัà¸à¸à¸²à¸“ %ld" + +#: ../glib/gspawn.c:859 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "โพรเซสลูà¸à¸–ูà¸à¸«à¸¢à¸¸à¸”ด้วยสัà¸à¸à¸²à¸“ %ld" + +#: ../glib/gspawn.c:866 +#, c-format +msgid "Child process exited abnormally" +msgstr "โพรเซสลูà¸à¸ˆà¸šà¸à¸²à¸£à¸—ำงานà¹à¸šà¸šà¹„ม่ปà¸à¸•ิ" + +#: ../glib/gspawn.c:1271 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "อ่านข้อมูลจาà¸à¹„ปป์จาà¸à¹‚พรเซสลูà¸à¹„ม่สำเร็จ (%s)" + +#: ../glib/gspawn.c:1341 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork ไม่สำเร็จ (%s)" + +#: ../glib/gspawn.c:1490 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "เข้าไปที่ไดเรà¸à¸—อรี '%s' ไม่สำเร็จ (%s)" + +#: ../glib/gspawn.c:1500 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "ดำเนินงานโพรเซสลูภ\"%s\" ไม่สำเร็จ (%s)" + +#: ../glib/gspawn.c:1510 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "เปลี่ยนทิศทางข้อมูลเข้าหรือออà¸à¸ˆà¸²à¸à¹‚พรเซสลูà¸à¹„ม่สำเร็จ (%s)" + +#: ../glib/gspawn.c:1519 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "fork โพรเซสลูà¸à¹„ม่สำเร็จ (%s)" + +#: ../glib/gspawn.c:1527 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "เà¸à¸´à¸”ข้อผิดพลาดไม่ทราบสาเหตุขณะดำเนินงานโพรเซสลูภ\"%s\"" + +#: ../glib/gspawn.c:1551 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "อ่านข้อมูลจาà¸à¹„ปป์จาà¸à¹‚พรเซสลูà¸à¹„ด้ไม่เพียงพอ (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "อ่านข้อมูลจาà¸à¹‚พรเซสลูà¸à¹„ม่สำเร็จ" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "สร้างไปป์เพื่อสื่อสารà¸à¸±à¸šà¹‚พรเซสลูà¸à¹„ม่สำเร็จ (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "ดำเนินงานโพรเซสลูà¸à¹„ม่สำเร็จ (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "ชื่อโปรà¹à¸à¸£à¸¡à¸œà¸´à¸”รูปà¹à¸šà¸š: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "สตริงผิดรูปà¹à¸šà¸šà¹ƒà¸™à¹€à¸§à¸à¹€à¸•อร์ของอาร์à¸à¸´à¸§à¹€à¸¡à¸™à¸•์ที่ตำà¹à¸«à¸™à¹ˆà¸‡ %d: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "สตริงผิดรูปà¹à¸šà¸šà¹ƒà¸™à¸•ัวà¹à¸›à¸£à¸ªà¸ à¸²à¸žà¹à¸§à¸”ล้อม: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ไดเรà¸à¸—อรีใช้งานมีรูปà¹à¸šà¸šà¹„ม่ถูà¸à¸•้อง: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ดำเนินงานโปรà¹à¸à¸£à¸¡à¸Šà¹ˆà¸§à¸¢à¹„ม่สำเร็จ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"เà¸à¸´à¸”ข้อผิดพลาดไม่คาดหมายใน g_io_channel_win32_poll() ระหว่างอ่านข้อมูลจาà¸à¹‚พรเซสลูà¸" + +#: ../glib/gutf8.c:797 +msgid "Failed to allocate memory" +msgstr "จองหน่วยความจำไม่สำเร็จ" + +#: ../glib/gutf8.c:930 +msgid "Character out of range for UTF-8" +msgstr "อัà¸à¸‚ระอยู่นอà¸à¸Šà¹ˆà¸§à¸‡à¸‚อง UTF-8" + +#: ../glib/gutf8.c:1031 ../glib/gutf8.c:1040 ../glib/gutf8.c:1170 +#: ../glib/gutf8.c:1179 ../glib/gutf8.c:1318 ../glib/gutf8.c:1415 +msgid "Invalid sequence in conversion input" +msgstr "มีลำดับข้อมูลที่ไม่ถูà¸à¸•้องในข้อมูลที่ป้อนให้ตัวà¹à¸›à¸¥à¸‡à¸£à¸«à¸±à¸ª" + +#: ../glib/gutf8.c:1329 ../glib/gutf8.c:1426 +msgid "Character out of range for UTF-16" +msgstr "อัà¸à¸‚ระอยู่นอà¸à¸Šà¹ˆà¸§à¸‡à¸‚อง UTF-16" + +#: ../glib/gutils.c:2139 ../glib/gutils.c:2166 ../glib/gutils.c:2272 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ไบต์" + +#: ../glib/gutils.c:2145 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2147 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2150 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2153 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2156 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2159 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2172 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2175 ../glib/gutils.c:2290 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2178 ../glib/gutils.c:2295 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2180 ../glib/gutils.c:2300 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2183 ../glib/gutils.c:2305 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2186 ../glib/gutils.c:2310 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2223 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ไบต์" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2285 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "มà¸à¸£à¸²à¸„ม" + +msgctxt "full month name with day" +msgid "February" +msgstr "à¸à¸¸à¸¡à¸ à¸²à¸žà¸±à¸™à¸˜à¹Œ" + +msgctxt "full month name with day" +msgid "March" +msgstr "มีนาคม" + +msgctxt "full month name with day" +msgid "April" +msgstr "เมษายน" + +msgctxt "full month name with day" +msgid "May" +msgstr "พฤษภาคม" + +msgctxt "full month name with day" +msgid "June" +msgstr "มิถุนายน" + +msgctxt "full month name with day" +msgid "July" +msgstr "à¸à¸£à¸à¸Žà¸²à¸„ม" + +msgctxt "full month name with day" +msgid "August" +msgstr "สิงหาคม" + +msgctxt "full month name with day" +msgid "September" +msgstr "à¸à¸±à¸™à¸¢à¸²à¸¢à¸™" + +msgctxt "full month name with day" +msgid "October" +msgstr "ตุลาคม" + +msgctxt "full month name with day" +msgid "November" +msgstr "พฤศจิà¸à¸²à¸¢à¸™" + +msgctxt "full month name with day" +msgid "December" +msgstr "ธันวาคม" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "ม.ค." + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "à¸.พ." + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "มี.ค." + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "เม.ย." + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "พ.ค." + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "มิ.ย." + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "à¸.ค." + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "ส.ค." + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "à¸.ย." + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "ต.ค." + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "พ.ย." + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ธ.ค." + +#~ msgid "Error renaming file: %s" +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปลี่ยนชื่อà¹à¸Ÿà¹‰à¸¡: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเปิดà¹à¸Ÿà¹‰à¸¡: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะสร้างไดเรà¸à¸—อรี: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "ไม่รองรับà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยงสำหรับ win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "ไม่รองรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยงสำหรับ win32" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "ไม่สามารถหาชนิดปริยายของà¸à¸²à¸£à¹€à¸à¹‰à¸²à¸¡à¸­à¸‡à¹„ดเรà¸à¸—อรีในเครื่อง" + +#~ msgid "URIs not supported" +#~ msgstr "ไม่รองรับ URI" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์ไม่มีคีย์ '%s'" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "เà¸à¸´à¸”ข้อผิดพลาดขณะประมวลผลà¹à¸Ÿà¹‰à¸¡à¸‚าเข้าด้วย xmllint:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "เà¸à¸´à¸”ข้อผิดพลาดขณะประมวลผลà¹à¸Ÿà¹‰à¸¡à¸‚าเข้าด้วย to-pixdata:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "ไม่สามารถอ่านข้อผิดพลาดที่คั่งค้างอยู่ได้: %s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "เปิดà¹à¸Ÿà¹‰à¸¡ '%s' เพื่อเขียนไม่สำเร็จ: fdopen() ล้มเหลว: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "เขียนà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: fflush() ล้มเหลว: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "ปิดà¹à¸Ÿà¹‰à¸¡ '%s' ไม่สำเร็จ: fclose() ล้มเหลว: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "เà¸à¸´à¸™à¸‚อบเขตพื้นที่ทำงานสำหรับสตริงย่อยเปล่า" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "ห้ามใช้รหัสหลีà¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸•ัวพิมพ์ใหà¸à¹ˆ-เล็ภ(\\l, \\L, \\u, \\U) ที่ตำà¹à¸«à¸™à¹ˆà¸‡à¸™à¸µà¹‰" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "ซ้ำà¸à¸¥à¸¸à¹ˆà¸¡ DEFINE ไม่ได้" + +#~ msgid "File is empty" +#~ msgstr "à¹à¸Ÿà¹‰à¸¡à¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "à¹à¸Ÿà¹‰à¸¡à¸„ีย์มีคีย์ '%s' ซึ่งมีค่าที่ไม่สามารถตีความได้" + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะ stat à¹à¸Ÿà¹‰à¸¡ '%s': %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "ไม่มีข้อมูลบริà¸à¸²à¸£à¸ªà¸³à¸«à¸£à¸±à¸š '%s'" + +#~ msgid "Error connecting: " +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเชื่อมต่อ: " + +#~ msgid "Error connecting: %s" +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเชื่อมต่อ: %s" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะอ่านà¹à¸Ÿà¹‰à¸¡à¸¢à¸¹à¸™à¸´à¸à¸‹à¹Œ: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะเขียนข้อมูลลงà¹à¸Ÿà¹‰à¸¡à¸¢à¸¹à¸™à¸´à¸à¸‹à¹Œ: %s" + +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "มีลำดับ UTF-8 ที่ไม่ถูà¸à¸•้องในข้อมูลเข้า" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "มาถึงขีดจำà¸à¸±à¸”สูงสุดของà¹à¸­à¸£à¹Œà¹€à¸£à¸¢à¹Œà¸‚้อมูลà¹à¸¥à¹‰à¸§" + +#~ msgid "do not hide entries" +#~ msgstr "ไม่ต้องซ่อนรายà¸à¸²à¸£à¹ƒà¸”" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "อัà¸à¸‚ระ '%s' ไม่สามารถใช้ขึ้นต้นชื่อเอนทิตีได้ อัà¸à¸‚ระ & ใช้เริ่มเอนทิตี ถ้าเครื่องหมาย " +#~ "ampersand นี้ไม่ได้เจตนาให้เป็นเอนทิตี ต้องหลีà¸à¹‚ดยà¹à¸—นด้วย &" + +#~ msgid "Character '%s' is not valid inside an entity name" +#~ msgstr "อัà¸à¸‚ระ '%s' ใช้ในชื่อเอนทิตีไม่ได้" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "ตัวอ้างอิงอัà¸à¸‚ระว่างเปล่า ควรจะมีตัวเลข เช่น dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "ตัวอ้างอิงเอนทิตีไม่สมบูรณ์" + +#~ msgid "Unfinished character reference" +#~ msgstr "ตัวอ้างอิงอัà¸à¸‚ระไม่สมบูรณ์" + +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "ข้อความลงรหัส UTF-8 ไม่ถูà¸à¸•้อง - ลำดับซ้อนเหลื่อมà¸à¸±à¸™" + +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "ข้อความลงรหัส UTF-8 ไม่ถูà¸à¸•้อง - ไม่ได้เริ่มด้วยไบต์ที่เป็นต้นอัà¸à¸‚ระ" + +#~ msgid "file" +#~ msgstr "à¹à¸Ÿà¹‰à¸¡" + +#~ msgid "The file containing the icon" +#~ msgstr "à¹à¸Ÿà¹‰à¸¡à¸—ี่เà¸à¹‡à¸šà¹„อคอน" + +#~ msgid "name" +#~ msgstr "ชื่อ" + +#~ msgid "An array containing the icon names" +#~ msgstr "à¹à¸­à¸£à¹Œà¹€à¸£à¸¢à¹Œà¹€à¸à¹‡à¸šà¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­à¸‚องไอคอน" + +#~ msgid "" +#~ "Whether to use default fallbacks found by shortening the name at '-' " +#~ "characters. Ignores names after the first if multiple names are given." +#~ msgstr "" +#~ "à¸à¸³à¸«à¸™à¸”ว่าจะใช้ fallback ปริยายซึ่งหาได้โดยตัดท้ายชื่อที่อัà¸à¸‚ระ '-' หรือไม่ ถ้ามีหลายชื่อ " +#~ "จะใช้เพียงชื่อà¹à¸£à¸à¹€à¸—่านั้น" + +#~ msgid "File descriptor" +#~ msgstr "File descriptor" + +#~ msgid "The file descriptor to read from" +#~ msgstr "File descriptor ที่จะอ่าน" + +#~ msgid "Close file descriptor" +#~ msgstr "ปิด file descriptor" + +#~ msgid "Whether to close the file descriptor when the stream is closed" +#~ msgstr "à¸à¸³à¸«à¸™à¸”ว่าจะปิด file descriptor ด้วยหรือไม่ เมื่อปิดสตรีม" + +#~ msgid "Error creating backup link: %s" +#~ msgstr "เà¸à¸´à¸”ข้อผิดพลาดขณะสร้างลิงà¸à¹Œà¸ªà¸³à¸£à¸­à¸‡: %s" + +#~ msgid "Can't load just created desktop file" +#~ msgstr "ไม่สามารถเรียà¸à¹à¸Ÿà¹‰à¸¡à¹€à¸”สà¸à¹Œà¸—็อปที่เพิ่งสร้าง" + +#~ msgid "Target file already exists" +#~ msgstr "มีà¹à¸Ÿà¹‰à¸¡à¸›à¸¥à¸²à¸¢à¸—างชื่อนี้อยู่à¸à¹ˆà¸­à¸™à¹à¸¥à¹‰à¸§" + +#~ msgid "Too large count value passed to g_input_stream_read_async" +#~ msgstr "มีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸„่า count ที่สูงเà¸à¸´à¸™à¹„ปมาให้ g_input_stream_read_async" + +#~ msgid "Too large count value passed to g_input_stream_skip" +#~ msgstr "มีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸„่า count ที่สูงเà¸à¸´à¸™à¹„ปมาให้ g_input_stream_skip" + +#~ msgid "Too large count value passed to g_input_stream_skip_async" +#~ msgstr "มีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸„่า count ที่สูงเà¸à¸´à¸™à¹„ปมาให้ g_input_stream_skip_async" + +#~ msgid "Too large count value passed to g_output_stream_write" +#~ msgstr "มีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸„่า count ที่สูงเà¸à¸´à¸™à¹„ปมาให้ g_output_stream_write" + +#~ msgid "Too large count value passed to g_output_stream_write_async" +#~ msgstr "มีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸„่า count ที่สูงเà¸à¸´à¸™à¹„ปมาให้ g_output_stream_write_async" + +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "ไม่สามารถเปลี่ยนโหมดของà¹à¸Ÿà¹‰à¸¡à¹„ด้: fork() ล้มเหลว: %s" + +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "ไม่สามารถเปลี่ยนโหมดของà¹à¸Ÿà¹‰à¸¡à¹„ด้: chmod() ล้มเหลว: %s" + +#~ msgid "Could not change file mode: Child terminated by signal: %s" +#~ msgstr "ไม่สามารถเปลี่ยนโหมดของà¹à¸Ÿà¹‰à¸¡à¹„ด้: โพรเซสลูà¸à¸ˆà¸šà¹‚ดยสัà¸à¸à¸²à¸“: %s" + +#~ msgid "Could not change file mode: Child terminated abnormally" +#~ msgstr "ไม่สามารถเปลี่ยนโหมดของà¹à¸Ÿà¹‰à¸¡à¹„ด้: โพรเซสลูà¸à¸ˆà¸šà¹à¸šà¸šà¸œà¸´à¸”ปà¸à¸•ิ" diff --git a/po/tl.po b/po/tl.po new file mode 100644 index 0000000..35b5213 --- /dev/null +++ b/po/tl.po @@ -0,0 +1,3870 @@ +# Tagalog translation of glib. +# Copyright (C) 2005 +# This file is distributed under the same license as the glib package. +# Eric Pareja , 2005. +# +# +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2005-12-01 17:31+0800\n" +"Last-Translator: Eric Pareja \n" +"Language-Team: Tagalog \n" +"Language: tl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, fuzzy, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" +"Kakaibang karakter '%s', inasahan na '=' matapos ng pangalang attribute '%s' " +"ng elementong '%s'" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +#, fuzzy +msgid "No valid bookmark file found in data dirs" +msgstr "Walang mahanap na talaksang susi sa mga dir ng datos" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Sawi ang pagbasa ng symbolic link '%s': %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Pagsalin mula sa character set '%s' patungong '%s' ay hindi suportado" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Hindi mabuksan ang converter mula '%s' tungong '%s'" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Hindi tanggap na byte sequence sa conversion input" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Hindi kumpletong karakter sequence sa dulo ng input" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Hindi maka-balik '%s' sa codeset '%s'" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "Ang URI '%s' ay hindi absolute URI na gamit ang paraang \"file\"" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "Ang lokal na talaksang URI '%s' ay hindi maaaring maglaman ng '#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "Ang URI '%s' ay hindi tanggap" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Ang hostname ng URI '%s' ay hindi tanggap" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "Ang URI '%s' ay may hindi tanggap na escaped karakter" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Ang pathname '%s' ay hindi absolute path" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Hindi tanggap na hostname" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %r %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%r" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "Enero" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "Pebrero" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Marso" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "Abril" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "Mayo" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "Hunyo" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "Hulyo" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Ene" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Peb" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Abr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "May" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Hun" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Hul" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Lunes" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Martes" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Miyerkoles" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Huwebes" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Biyernes" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Sabado" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Linggo" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Lun" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Mar" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Miy" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Huw" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Biy" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Sab" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Lin" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Error sa pagbukas ng directory '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Hindi makapag-tabi ng %lu byte upang basahin ang talaksang \"%s\"" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Sawi ang pagbabasa ng talaksang '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Sawi ang pagbukas ng talaksang '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" +"Sawi ang pagkuha ng mga attribute ng talaksang '%s': sawi ang fstat(): %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Sawi ang pagbukas ng talaksang '%s': sawi ang fdopen(): %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"Bigo ang papalit ng pangalan ng talaksang '%s' sa '%s': bigo ang g_rename(): " +"%s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Sawi ang paglikha ng talaksang '%s': %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "" +"Bigo ang pagbukas ng talaksang '%s' para sa pagsusulat: bigo ang fdopen(): %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Bigo sa pagsusulat ng talaksang '%s': bigo ang fwrite(): %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Bigo sa pagsusulat ng talaksang '%s': bigo ang fwrite(): %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Bigo sa pagsusulat ng talaksang '%s': bigo ang fwrite(): %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Bigo ang pagsara ng talaksang '%s': bigo ang fclose(): %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "Hindi matanggal ang talaksang '%s': bigo ang g_unlink(): %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Hindi tanggap ang template '%s', wala dapat na '%s'" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Hindi XXXXXX ang dulo ng template '%s'" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Sawi ang pagbasa ng symbolic link '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Hindi mabuksan ang converter mula '%s' patungong '%s': %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Hindi mabasa ng hilaw ang g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "May natirang hindi na-convert na datos sa read buffer" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Nagwakas sa partial karakter ang channel" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Hindi makapagbasa ng hilaw sa g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Bigo ang pagbukas ng talaksang '%s': bigo ang open(): %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "" +"Bigo ang pagreserba ng memory para sa talaksang '%s': bigo ang mmap(): %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "Error sa linya %d char %d: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Hindi tanggap na tekstong encoded ng UTF-8" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Error sa linya %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Sawi sa pag-parse ng '%-.*s', na dapat ay numero sa loob ng reference sa " +"karakter (halimbawa ay ê) - maaaring ang numero ay sobra ang laki" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Ang reference sa karakter ay hindi nagtapos sa puntukoma; malamang ay " +"gumamit kayo ng ampersand na karakter na hindi sinadyang mag-umpisa ng " +"entity - itaglay ang ampersand bilang &" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" +"Reference sa karakter '%-.*s' ay hindi nag-encode ng tanggap na karakter" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Walang laman na entity '&' ay nakita; tanggap na mga entity ay: & " " +"< > '" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Pangalan ng entity '%s' ay hindi kilala" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Hindi nagtapos ang entity sa puntukoma; malamang ay gumamit kayo ng " +"ampersand karakter na hindi sinasadyang mag-umpisa ng entity - itaglay ang " +"ampersand ng &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Kailangang mag-umpisa ang dokumento ng elemento (hal. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' ay hindi tanggap na karakter matapos ng '<' na karakter; hindi ito " +"maaaring mag-umpisa ng pangalang elemento" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Kakaibang karakter '%s', inasahan na '>' karakter ang pambungad ng pambukas " +"na tag ng elementong '%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Kakaibang karakter '%s', inasahan na '=' matapos ng pangalang attribute '%s' " +"ng elementong '%s'" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Kakaibang karakter '%s', inasahan na '>' o '/' na karakter ang pambungad ng " +"pangbukas na tag ng elementong '%s' o attribute; maaaring gumamit kayo ng " +"hindi tanggap na karakter sa pangalang attribute" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Kakaibang karakter '%s', inasahan na pambukas na quote mark matapos ng " +"equals sign kapag nagbigay ng halaga para sa attribute '%s' ng elementong " +"'%s'" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"Hindi tanggap na karakter ang '%s' matapos ang pangsara ng pangalang " +"elemento '%s'; ang tinatanggap na karakter ay '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Sinarhan ang elementong '%s', walang bukas na elemento." + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"Sinarhan ang elementong '%s', ngunit ang kasalukuyang elementong bukas ay " +"'%s'" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Walang laman ang dokumento o naglalaman lamang ito ng puwang" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento matapos lamang ng pangbukas na " +"angle bracket '<'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento na may mga bukas na elemento - " +"'%s' ay ang huling elementong binuksan" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento, inasahan na makita ang angle " +"bracket na pang-sara ng tag <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento sa loob ng pangalan ng elemento" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento sa loob ng pangalan ng attribute" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento sa loob ng pagbukas na tag ng " +"elemento." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento matapos ang equal sign na sumunod " +"sa pangalan ng attribute; walang halaga ang attribute" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento habang nasa loob ng halagang " +"attribute" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"Nagwakas ang dokumento ng hindi inaasahan sa loob ng tag ng pagsara para sa " +"elementong '%s'" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Nagwakas ang dokumento ng hindi inaasahan sa loob ng komento o utos ng " +"pagproseso" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "Nagwakas sa partial karakter ang channel" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "Hindi tanggap na byte sequence sa conversion input" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "Hindi tapos na reference sa karakter" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "Hindi tapos na reference sa karakter" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "Hindi tapos na reference sa karakter" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Error sa linya %d char %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "Hindi tapos na reference sa entity" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Ang binanggit na teksto ay hindi nag-umpisa sa quotation mark" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Walang kapares na quotation mark sa command line o ibang shell na teksto." + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Nagwakas ang teksto matapos ng karakter na '\\'. (Ang teksto ay '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"Nagwakas ang teksto bago nakahanap ng kapares na quote para sa %c. (Ang " +"teksto ay '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Ang teksto ay walang laman (o naglaman lamang ng puwang)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Sawi sa pagbasa ng datos mula sa prosesong anak" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Sawi sa paglikha ng pipe para makausap ang prosesong anak (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Sawi sa pagbasa mula sa child pipe (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Sawi sa paglipat sa directory '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Sawi sa pagtakbo ng prosesong anak (%s)" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Imbalidong pangalan ng programa: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Imbalidong string sa argument vector sa %d: %s" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Imbalidong string sa kapaligiran: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Imbalidong working directory: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Bigo sa pagtakbo ng programang katulong (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Hindi inaasahang error sa g_io_channel_win32_poll() sa pagbasa ng datos mula " +"sa prosesong anak" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Sawi sa pagbasa ng datos mula sa prosesong anak (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Hindi inaasahang error sa select() habang nagbabasa ng datos mula sa " +"prosesong anak (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Hindi inaasahang error sa waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Sawi sa pag-fork (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Sawi sa pagtakbo ng prosesong anak \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Sawi sa pag-redirect ng output o input ng prosesong anak (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Sawi sa pag-fork ng prosesong anak (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Hindi kilalang error sa pagpatakbo ng prosesong anak \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Sawi sa pagbasa ng akmang datos mula sa child pid pipe (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Character wala sa sakop ng UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Hindi tanggap na sequence sa conversion input" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Character wala sa sakop ng UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Pag-gamit:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Option ng Tulong:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Ipakita ang option ng tulong" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Ipakita ang option ng tulong" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Option ng Aplikasyon:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Hindi mai-parse ang halagang integer '%s' para sa %s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Halagang integer '%s' para sa %s ay wala sa sakop" + +#: ../glib/goption.c:1032 +#, fuzzy, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Hindi mai-parse ang halagang integer '%s' para sa %s" + +#: ../glib/goption.c:1040 +#, fuzzy, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Halagang integer '%s' para sa %s ay wala sa sakop" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "Error habang nagco-convert: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "Kulang na argumento para sa %s" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Hindi kilalang option %s" + +#: ../glib/gkeyfile.c:366 +#, fuzzy +msgid "Valid key file could not be found in search dirs" +msgstr "Walang mahanap na talaksang susi sa mga dir ng datos" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Hindi karaniwang talaksan" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Walang laman ang talaksan" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Ang talaksang susi ay naglalaman ng linyang '%s' na hindi pares na susi-" +"halaga, grupo, o komento" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "Imbalidong pangalan ng programa: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Ang talaksang susi ay hindi naguumpisa sa isang grupo" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "Imbalidong pangalan ng programa: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Ang talaksang susi ay naglalaman ng hindi suportadong encoding '%s'" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Ang talaksang susi ay walang grupong '%s'" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Ang talaksang susi ay walang susing '%s'" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"Ang talaksang susi ay naglalaman ng susing '%s' na may halagang '%s' na " +"hindi UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" +"Ang talaksang susi ay naglalaman ng susing '%s' na may halagang hindi mabasa." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"Ang talaksang susi ay naglalaman ng susing '%s' na may halagang hindi mabasa." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"Ang talaksang susi ay naglalaman ng susing '%s' sa grupong '%s' na may " +"halaga na hindi mabasa." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Ang talaksang susi ay walang susing '%s' sa grupong '%s'" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Ang talaksang susi ay may escape karakter sa dulo ng linya" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "Ang talaksang susi ay may hindi tanggap na escape sequence '%s'" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Ang halagang '%s' ay hindi mabasa bilang numero." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Halagang integer '%s' ay wala sa sakop" + +#: ../glib/gkeyfile.c:3919 +#, fuzzy, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Ang halagang '%s' ay hindi mabasa bilang numero." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Ang halagang '%s' ay hindi mabasa bilang boolean." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Hindi tanggap na byte sequence sa conversion input" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "Hindi kilalang option %s" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Hindi kilalang option %s" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Error sa pagbukas ng directory '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Error sa pagbukas ng directory '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Error sa linya %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Hindi tanggap ang karakter '%s' sa loob ng pangalan ng entity" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Hindi tanggap ang karakter '%s' sa loob ng pangalan ng entity" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Hindi tanggap ang karakter '%s' sa loob ng pangalan ng entity" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Error sa pagbukas ng directory '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Imbalidong pangalan ng programa: %s" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "Hindi tanggap na hostname" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Sawi ang paglikha ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Sawi ang paglikha ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "Sawi ang paglikha ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Error sa pagbukas ng directory '%s': %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Sawi ang pagbasa ng symbolic link '%s': %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "" +"Nagwakas ng hindi inaasahan ang dokumento sa loob ng pangalan ng attribute" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Error sa pagbukas ng directory '%s': %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "Error sa linya %d: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +#, fuzzy +msgid "Target file is not a regular file" +msgstr "Hindi karaniwang talaksan" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Imbalidong pangalan ng programa: %s" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Hindi kilalang option %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Sawi ang paglikha ng talaksang '%s': %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "Hindi mapalitan ang modo ng talaksan: bigo ang waitpid(): %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Sawi ang paglikha ng talaksang '%s': %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Sawi ang paglikha ng talaksang '%s': %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Hindi suportado ang mga symbolic link" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "Error sa linya %d: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Error habang nagco-convert: %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "Hindi suportado ang mga symbolic link" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Hindi tanggap na hostname" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Hindi tanggap na sequence sa conversion input" + +#, fuzzy +#~ msgid "[FILE...]" +#~ msgstr "[OPTION...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Hindi tanggap ang karakter '%s' sa umpisa ng pangalan ng entity; ang & " +#~ "karakter ang nag-uumpisa ng entity; kung ang ampersand ay hindi dapat " +#~ "maging entity, itaglay ito bilang &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "" +#~ "Walang laman na reference sa karakter; dapat may kasamang numero tulad ng " +#~ "dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Hindi tapos na reference sa entity" + +#~ msgid "Unfinished character reference" +#~ msgstr "Hindi tapos na reference sa karakter" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Hindi tanggap na tekstong encoded ng UTF-8" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Hindi tanggap na tekstong encoded ng UTF-8" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Ang hostname ng URI '%s' ay hindi tanggap" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Ang hostname ng URI '%s' ay hindi tanggap" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Error sa pagbasa ng talaksang '%s': %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Error habang nagco-convert: %s" + +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Hindi mapalitan ang modo ng talaksan: bigo ang fork(): %s" + +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Hindi mapalitan ang modo ng talaksan: bigo ang chmod(): %s" + +#~ msgid "Could not change file mode: Child terminated by signal: %s" +#~ msgstr "" +#~ "Hindi mapalitan ang modo ng talaksan: Hininto ang anak ng hudyat: %s" + +#~ msgid "Could not change file mode: Child terminated abnormally" +#~ msgstr "" +#~ "Hindi mapalitan ang modo ng talaksan: Hininto ng hindi pangkaraniwan ang " +#~ "anay" diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 0000000..94c6069 --- /dev/null +++ b/po/tr.po @@ -0,0 +1,6521 @@ +# Turkish translation of Glib. +# Copyright (C) 2001-2003, 2005, 2007, 2008 Free Software Foundation, Inc. +# +# +# KEMAL YILMAZ , 2001. +# Arman Aksoy , 2003. +# Onur Can ÇAKMAK , 2004, 2006. +# Baris Cicek , 2005, 2007, 2008, 2009. +# Necdet Yücel , 2015. +# Kaan Özdinçer , 2015. +# Muhammet Kara , 2011, 2014, 2015, 2016. +# Serdar SaÄŸlam , 2019. +# Emin Tufan Çetin , 2017, 2018, 2019, 2020, 2021, 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 15:19+0000\n" +"PO-Revision-Date: 2022-03-23 11:03+0300\n" +"Last-Translator: Emin Tufan Çetin \n" +"Language-Team: Türkçe \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.4.3\n" +"X-POOTLE-MTIME: 1433280446.000000\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Öntanımlı uygulama belirleme henüz desteklenmiyor" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Uygulamayı tür için son kullanılan olarak belirleme henüz desteklenmiyor" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication seçenekleri" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "GApplication seçeneklerini göster" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "GApplication servis kipi girin (D-Bus servis dosyalarından kullan)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Uygulama kimliÄŸini çiÄŸne" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Çalışan örneÄŸi deÄŸiÅŸtir" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Yardımı yazdır" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[KOMUT]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "Sürüm yazdır" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "Sürüm bilgisini yazdır ve çık" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "Uygulamaları listele" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Yüklü D-Bus aktive edilebilir uygulamaları listele (.desktop dosyaları ile)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "Uygulama baÅŸlat" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "Uygulamayı baÅŸlat (açılacak isteÄŸe baÄŸlı dosyalarla)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "APPID [DOSYA…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Eylemi etkinleÅŸtir" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Uygulama üzerinde eylem çalıştır" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID EYLEM [PARAMETRE]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "Kullanılabilir eylemleri listele" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "Uygulama için deÄŸiÅŸmeyen eylemleri listele (.desktop dosyalarından)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "KOMUT" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Ayrıntılı yardım yazdırmak için komut" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus biçiminde uygulama tanımlayıcı (örneÄŸin: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "DOSYA" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Açılacak isteÄŸe baÄŸlı göreli ya da mutlak dosya adları veya URI’ler" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "EYLEM" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Çalıştırılacak eylem adı" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "PARAMETRE" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "GVariant biçiminde baÅŸlatma eylemi için isteÄŸe baÄŸlı parametre" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Bilinmeyen komut %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "Kullanım:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Argümanlar:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGÜMANLAR…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Komutlar:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Ayrıntılı yardım almak için “%s help KOMUT†kullanın.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s komutu doÄŸrudan takip için uygulama kimliÄŸi gerektirir\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "geçersiz uygulama kimliÄŸi: “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%s†hiçbir argüman almaz\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "D-Bus veri yoluna baÄŸlanılamıyor: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "uygulamaya %s iletisi gönderilirken hata: %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "uygulama kimliÄŸinden sonra eylem adı verilmelidir\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"geçersiz eylem adı: “%sâ€\n" +"eylem adları yalnızca “-â€, “.â€, harfler ve sayılardan oluÅŸmalıdır\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "eylem parametresi ayrıştırılırken hata: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "eylemler maksimum bir parametre kabul eder\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions komutu yalnızca uygulama kimliÄŸi deÄŸiÅŸkenini alır" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "%s uygulaması için masaüstü dosyası bulunamıyor\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"bilinmeyen komut: %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s için çok büyük sayaç deÄŸeri geçildi" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Taban akış üzerinde arama desteklenmez" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "GBufferedInputStreamsonu kesilemiyor" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Akış zaten kapalı" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Taban akış üzerinde sonunun kesilmesi desteklenmiyor" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "İşlem iptal edildi" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Geçersiz nesne, ilklendirilmemiÅŸ" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Girdide tamamlanmamış çokbaytlı dizi" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Hedefte yeterli alan yok" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Dönüşüm girdisinde geçersiz bayt dizisi" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Dönüşüm sırasında hata oluÅŸtu: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "İptal edilebilir baÅŸlatma desteklenmiyor" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "“%s†karakter kümesinden “%s†karakter kümesine dönüşüm desteklenmiyor" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "“%sâ€den “%sâ€e dönüştürücü açılamıyor" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s türü" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Bilinmeyen tür" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "%s dosya türü" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials geçersiz veri içeriyor" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "Bu iÅŸletim sisteminde GCredentials saÄŸlanmamış" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Platformunuz için GCredentials desteÄŸi yok" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials bu iÅŸletim sisteminde süreç kimliÄŸi içermez" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Bu iÅŸletim sisteminde kimlik sızdırma olanaksızdır" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Beklenmeyen erken akış-sonu" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "“%2$s†adres girdisinde desteklenmeyen anahtar “%1$sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "“%s†adres girdisinde anlamsız anahtar/deÄŸer çifti birleÅŸimi" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"“%s†adresi geçersiz (tam bir yol, dir, tmpdir veya soyut anahtarlar gerekir)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "“%s†adresinde hata — “%s†özniteliÄŸi hatalı oluÅŸturulmuÅŸ" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "“%2$s†adresi için bilinmeyen ya da desteklenmeyen aktarım “%1$sâ€" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "Adres ögesi “%s†iki nokta üst üste (:) içermez" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "“%s†adres ögesindeki aktarım adı boÅŸ olmamalı" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"“%3$s†adres ögesi içindeki, Anahtar/DeÄŸer çifti %1$d, “%2$s†eÅŸittir imi " +"içermiyor" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"“%3$s†adres ögesi içindeki, Anahtar/DeÄŸer çifti %1$d, “%2$s†boÅŸ anahtar " +"olmamalıdır" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"“%3$s†adres ögesindeki, Anahtar/DeÄŸer çifti %1$d, “%2$s†içinde ters kaçış " +"tuÅŸu veya deÄŸeri hatası" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"“%s†adresinde hata — unix aktarımı, “path†veya “abstract†anahtarlarından " +"bir tanesinin kesinlikle ayarlanmış olmasını gerektirir" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "“%s†adresinde hata — host özniteliÄŸi eksik ya da hatalı oluÅŸturulmuÅŸ" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"“%s†adresinde hata — baÄŸlantı noktası özniteliÄŸi eksik ya da hatalı " +"oluÅŸturulmuÅŸ" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"“%s†adresinde hata — noncefile özniteliÄŸi eksik ya da hatalı oluÅŸturulmuÅŸ" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "KendiliÄŸinden baÅŸlatmada hata: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "Tek seferlik dosya “%s†açılırken hata: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "Tek seferlik dosya “%s†okunurken hata: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "Tek seferlik dosya “%s†okunurken hata, beklenen 16 bayt, alınan %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "“%s†tek seferlik dosyasının akış için içeriklerini yazmada hata:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Verilen adres boÅŸ" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "AT_SECURE belirtildiÄŸinde ileti veri yolu oluÅŸturulamaz" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "machine-id olmadan ileti veri yolu oluÅŸturulamıyor: " + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "X11 $DISPLAY olmadan D-BUS kendiliÄŸinden baÅŸlatılamaz" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "“%s†komut satırı oluÅŸturulurken hata: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Oturum veri yolu adresi saptanamıyor (bu iÅŸletim sistemi için uygulanmadı)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"DBUS_STARTER_BUS_TYPE ortam deÄŸiÅŸkeninden veri yolu adresi saptanamıyor — " +"bilinmeyen deÄŸer “%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"DBUS_STARTER_BUS_TYPE ortam deÄŸiÅŸkenine deÄŸer atanmadığından dolayı veri " +"yolu adresi belirlenemiyor" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Bilinmeyen veriyolu türü %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Satır okunmaya çalışılırken beklenmeyen içerik eksikliÄŸi" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Satır okunmaya çalışılırken (güvenli) beklenmeyen içerik eksikliÄŸi" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Tüm olası kimlik doÄŸrulama yöntemleri tükendi (denenen: %s) (kullanılabilir: " +"%s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Kullanıcı kimlikleri eÅŸ ve sunucu için aynı olmalıdır" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer yolu ile iptal edildi" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "“%s†dizini için bilgi alınırken hata: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "" +"“%s†dizini üzerindeki izinler bozulmuÅŸtur. 0700 kipi beklenmiÅŸtir, ama 0%o " +"alınmıştır" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "“%s†dizini oluÅŸturulurken hata: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "İşlem desteklenmiyor" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "Okumak için “%s†anahtarlığı açılırken hata: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%3$s†içerikli “%2$s†konumundaki anahtarlığın %1$d. satırı bozulmuÅŸ" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"“%3$s†içerikli “%2$s†konumundaki anahtarlığın %1$d. satırının ilk " +"belirteci bozulmuÅŸ" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"“%3$s†içerikli “%2$s†konumundaki anahtarlığın %1$d. satırının ikinci " +"belirteci bozulmuÅŸ" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "“%2$s†konumundaki anahtarlıkta %1$d kimlikli çerez bulunamadı" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "Kilit dosyası “%s†oluÅŸturulurken hata: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "Eski kilit dosyası “%s†silinirken hata: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "(BaÄŸlantısı olmayan) kilit dosyası “%s†kapatılırken hata: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "“%s†kilit dosyasının baÄŸlantısı kaldırılırken hata: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "“%s†anahtarlığını yazma için açarken hata: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Ayrıca, “%s†için kilidi açma baÅŸarısız oldu: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "BaÄŸlantı kapalı" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Zaman aşımı gerçekleÅŸti" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"İstemci taraflı baÄŸlantı kurulurken desteklenmeyen etiketlerle karşılaşıldı" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"%s yolundaki nesnede “org.freedesktop.DBus.Properties†gibi bir arayüz yok" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "“%s†gibi bir özellik yok" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "“%s†özelliÄŸi okunabilir deÄŸil" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "“%s†özelliÄŸi yazılabilir deÄŸil" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "“%s†özelliÄŸi ayarlanırken hata: “%s†türü beklendi, “%s†elde edildi" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "“%s†gibi bir arabirim yok" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "%2$s yolundaki nesnede “%1$s†gibi bir arayüz yok" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "“%s†gibi bir anahtar yok" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "“%s†iletisinin türü, beklenen “%s†türü ile örtüşmüyor" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "%2$s konumundaki %1$s arayüzü için bir nesne zaten dışa aktarıldı" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "%s.%s özelliÄŸi alınamadı" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "%s.%s özelliÄŸi ayarlanamadı" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "“%s†yöntemi “%s†türü döndürdü, ancak “%s†bekleniyordu" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "“%3$s†imzalı “%2$s†arayüzü üzerinde “%1$s†yöntemi yok" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "%s için bir alt aÄŸaç zaten dışa aktarılmış" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Nesne, “%s†yolunda yok" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "tür GEÇERSİZ" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL iletisi: PATH ya da MEMBER baÅŸlık alanı eksik" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN iletisi: REPLY_SERIAL baÅŸlık alanı eksik" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR iletisi: REPLY_SERIAL ya da ERROR_NAME baÅŸlık alanı eksik" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL iletisi: PATH, INTERFACE ya da MEMBER baÅŸlık alanı eksik" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"SIGNAL iletisi: PATH baÅŸlık alanı, ayrılmış olan /org/freedesktop/DBus/Local " +"deÄŸerini kullanıyor" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL iletisi: INTERFACE baÅŸlık alanı, ayrılmış olan org.freedesktop.DBus." +"Local deÄŸerini kullanıyor" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu bayt okumak istendi ancak yalnızca %lu var" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "“%s†dizgesinden sonra NUL baytı beklendi, ama %d baytı bulundu" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Geçerli bir UTF-8 dizgesi beklendi ama %d bayt konumunda geçersiz baytlar " +"bulundu (dizge uzunluÄŸu %d). Bu noktaya kadar geçerli olan dizge ÅŸudur: “%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "DeÄŸer çok derine yuvalanmış" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Ayrıştırılan deÄŸer “%sâ€, geçerli bir D-Bus nesne yolu deÄŸil" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Ayrıştırılan deÄŸer “%sâ€, geçerli bir D-Bus imzası deÄŸil" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"%u bayt uzunluÄŸunda dizi ile karşılaşıldı. Olabilecek en çok uzunluk 2<<26 " +"bayt (64 MiB)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"“a%c†türünde dizi ile karşılaşıldı, birden çok %u bayt uzunluÄŸu " +"beklenmektedir ancak %u bayt uzunluk bulundu" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "D-Bus’ta boÅŸ yapılara (demetler) izin verilmez" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Varyant için ayrıştırılmış “%s†deÄŸeri geçeriz bir D-Bus imzasıdır" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"GVariant, D-Bus tel biçiminden “%s†dizge türüyle geri dönüştürülürken hata" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Geçersiz endian deÄŸeri. 0x6c (“lâ€) veya 0x42 (“Bâ€) bekleniyordu ancak 0x%02x " +"deÄŸeri bulundu" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Geçersiz önemli iletiÅŸim kuralı sürümü. 1 beklendi, %d bulundu" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "İmza baÅŸlığı bulundu, ancak tür imzası deÄŸil" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "“%s†imzalı bir imza baÅŸlığı bulundu ama ileti gövdesi boÅŸ" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Ayrıştırılan deÄŸer “%s†geçerli bir D-Bus imzası deÄŸil (gövde için)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "İletide imza baÅŸlığı yok ancak ileti gövdesi %u bayt" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "İleti geri dönüştürülemiyor: " + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "GVariant, D-Bus tel biçimine “%s†dizge türüyle dönüştürülürken hata" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "İletideki dosya açıklayıcı sayısı (%d) baÅŸlık alanından (%d) farklı" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "İleti dönüştürülemiyor: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "İleti gövdesi “%s†imzasına sahip ancak imza baÅŸlığı yok" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"İleti gövdesi “%s†tür imzasına sahip ancak baÅŸlık alanındaki imza “%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "İleti gövdesi boÅŸ, ancak baÅŸlık alanındaki imza “(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "“%s†türünden bir gövdeyle dönüş hatası" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "BoÅŸ gövdeyle dönüş hatası" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Pencereyi kapatmak için herhangi bir karakter girin)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Dbus oturumu çalışmıyor ve kendiliÄŸinden baÅŸlatma baÅŸarısız oldu" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Donanım profili alınamıyor: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "%s ya da %s yüklenemedi: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s için StartServiceByName çaÄŸrısında hata: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "StartServiceByName %d yönteminden beklenmeyen yanıt (\"%s\")" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Yöntem çaÄŸrılamıyor; vekil sunucu, sahibi olmayan bilindik %s adı için ve " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START bayrağı ile oluÅŸturuldu" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Soyut ad alanı desteklenmiyor" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Bir sunucu oluÅŸturulurken nonce dosyası belirtilemez" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "“%s†konumundaki tek seferlik dosyaya yazma hatası: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "“%s†dizgesi, geçerli bir D-Bus GUID deÄŸil" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Desteklenmeyen aktarım “%s†üzerinde dinlenemiyor" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Komutlar:\n" +" help Bu bilgiyi gösterir\n" +" introspect Uzak nesneye iç gözlem yap\n" +" monitor Uzak nesneyi gözlemle\n" +" call Uzak nesne üzerinde yöntem çağır\n" +" emit Sinyal yay\n" +" wait Veri yolu adının belirmesini bekle\n" +"\n" +"Her komutla ilgili yardım almak için “%s KOMUT --help†kullan.\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Hata: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "İç gözlem XML’ini ayrıştırmada hata: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Hata: %s geçerli bir ad deÄŸil\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Hata: %s geçerli bir nesne yolu deÄŸil\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Sistem veriyoluna baÄŸlan" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Oturum veriyoluna baÄŸlan" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Verilen D-Bus adresine baÄŸlan" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "BaÄŸlantı Uç Noktası Seçenekleri:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "BaÄŸlantı uç noktasını belirleyen seçenekler" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "BaÄŸlantı uç noktası belirtilmedi" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Birden çok baÄŸlantı uç noktası belirtildi" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "Uyarı: İç gözlem verilerine göre, “%s†arayüzü yok\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "Uyarı: İç gözlem verilerine göre, “%s†yöntemi “%s†arayüzünde yok\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Sinyal için isteÄŸe baÄŸlı hedef nokta (eÅŸsiz ad)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Üzerinde sinyal yaymak için nesne yolu" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Sinyal ve arayüz adı" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "Bir sinyal yayınla." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "BaÄŸlanırken hata: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Hata: %s geçerli bir özgün veriyolu adı deÄŸil\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Hata: Nesne yolu belirtilmedi\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Hata: Sinyal adı belirtilmedi\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Hata: Sinyal adı “%s†geçersiz\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Hata: %s geçerli bir arayüz adı deÄŸil\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Hata: %s geçerli bir üye adı deÄŸil\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "%d parametresini ayrıştırırken hata oluÅŸtu: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "BaÄŸlantı boÅŸaltılırken hata: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Üzerinde yöntem çalıştırılacak hedef nokta adı" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Yöntemin üzerinde çalıştırılacağı nesne yolu" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Yöntem ve arayüz adı" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Saniye cinsinden zaman aşımı" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "EtkileÅŸimli yetkilendirmeye izin ver" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Uzak bir nesne üzerinde yöntem çalıştır." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Hata: Hedef belirtilmedi\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Hata: %s geçerli bir veri yolu adı deÄŸil\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Hata: Yöntem adı belirtilmedi\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Hata: Yöntem adı “%s†geçersiz\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "“%2$s†türünün %1$d parametresi ayrıştırılırken hata: %3$s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "%d iÅŸleyici eklenemedi: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "İç gözlem için hedef nokta adı" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "İç gözlem yapılacak nesne yolu" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "XML yazdır" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "Alt iç gözlemi" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Yalnızca özellikleri yazdır" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Uzak nesneye iç gözlem yap." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Gözlemlenecek hedefin adı" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Gözlemlenecek nesne yolu" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "Uzak nesneyi gözlemle." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "Hata: non-message-bus gözlemlenemiyor\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "Bir diÄŸeri (tanınmış ad) için beklemeden önce aktifleÅŸtirilecek hizmet" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Bir hatayla çıkılmadan önce beklenecek zaman aşımı süresi (saniye); zaman " +"aşımı olmaması için 0 (öntanımlı)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[SEÇENEK…] VERİYOLU-ADI" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Veri yolu adının belirmesini bekle." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Hata: AktifleÅŸtirilecek hizmet belirtilmelidir.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Hata: Beklenecek hizmet belirtilmelidir.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Hata: Çok fazla argüman.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Hata: %s geçerli bilinen bir veri yolu adı deÄŸil.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Hata ayıklama ayarlarını deÄŸiÅŸtirmeye yetkili deÄŸil" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Adlandırılmamış" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "Desktop dosyası Exec alanı belirtmemiÅŸ" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Uygulama için gerekli uçbirim bulunamadı" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Kullanıcı uygulaması yapılandırma klasörü %s oluÅŸturulamıyor: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Kullanıcı MIME yapılandırma klasörü %s oluÅŸturulamıyor: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "Uygulama bilgisinde tanımlayıcı eksik" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Kullanıcı masaüstü dosyası %s oluÅŸturulamıyor" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "%s için özel tanım" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "sürücü çıkartmayı uygulamıyor" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "sürücü eject veya eject_with_operation uygulamıyor" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "sürücü ortam için yoklamayı uygulamıyor" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "sürücü start uygulamıyor" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "sürücü stop uygulamıyor" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS arka yüzü, TLS baÄŸlanım geri alımı gerçeklemiyor" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS desteÄŸi kullanılabilir deÄŸil" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS desteÄŸi kullanılabilir deÄŸil" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "GEmblem kodlamasının %d sürümü iÅŸlenemiyor" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem kodlaması içerisinde bozuk belirteç sayısı (%d)" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon kodlamasının %d sürümü iÅŸlenemiyor" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon kodlaması içerisinde bozuk belirteç sayısı (%d)" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon için bir Gemblem beklendi" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "BaÄŸlama yok" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Dizin üzerine kopyalanamıyor" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Dizin dizin üzerine kopyalanamıyor" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Hedef dosya var" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Dizin iç içe kopyalanamıyor" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "Splice desteklenmiyor" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Dosya uç uca eklenirken hata: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "" +"BaÄŸlı sistemler arasında kopyalama (referans baÄŸlantı/çoÄŸaltmak) " +"desteklenmiyor" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Kopyalama desteklenmiyor ya da geçersiz" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "Kopyalama (baÄŸlama/klonlama) destenlenmiyor ya da çalışmadı" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Özel dosya kopyalanamıyor" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Geçersiz simgesel baÄŸ deÄŸeri verildi" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Simgesel baÄŸlar desteklenmiyor" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Çöp desteklenmiyor" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Dosya adları “%c†içeremez" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "bölüm, baÄŸlamayı yerine getirmiyor" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Bu dosyayı iÅŸleme amacıyla kayıtlı uygulama yok" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Enumerator kapalı" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Dosya numaralandırıcı sıra dışı iÅŸleme sahip" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Dosya numaralandırıcı zaten kapalı" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "GFileIcon kodlamasının %d sürümü iÅŸlenemiyor" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon için bozuk girdi verisi" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Akış query_info desteklemiyor" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Atlama akışta desteklenmiyor" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Sonunu kesmeye giriÅŸ akışında izin verilmiyor" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Akış üzerinde sonunun kesilmesi desteklenmiyor" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Geçersiz makine adı" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Bozuk HTTP vekil sunucu yanıtı" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP vekil sunucu baÄŸlantısına izin verilmiyor" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP vekil sunucu kimlik doÄŸrulaması baÅŸarısız" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP vekil sunucu kimlik doÄŸrulaması gerekli" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP vekil sunucu baÄŸlantısı baÅŸarısız: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP vekil sunucu yanıtı çok büyük" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP vekil sunucusu baÄŸlantıyı beklenmedik biçimde kesti." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Yanlış belirteç sayısı (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "Sınıf adı %s için tür yok" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s türü GIcon arayüzü uygulamıyor" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "%s türü sınıflandırılmış deÄŸil" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Bozuk sürüm numarası: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s türü GIcon arayüzü üzerinde from_tokens() uygulamıyor" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Simge kodlamasının verilen sürümü iÅŸlenemiyor" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Belirtilen hiçbir adres yok" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Adres için %u uzunluÄŸu çok uzun" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Adres önek uzunluÄŸundan daha çok bite sahiptir" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "“%sâ€, IP adresi maskesi olarak ayrıştırılamadı" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Yuva adresi için yeterli alan yok" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Desteklenmeyen yuva adresi" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "GiriÅŸ akımı okumayı uygulamıyor" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Akışın sıra dışı iÅŸlemi var" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Dosyayla kopyala" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "Taşındığında dosyayla tut" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“version†hiçbir argüman almaz" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "Kullanım:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "Sürüm bilgisini yazdır ve çık." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Komutlar:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Dosyaları standart çıktıya bitiÅŸtir" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Bir veya daha çok dosya kopyala" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Konumlar hakkında bilgi göster" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "Masaüstü dosyasından uygulama baÅŸlat" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "Konumların içeriklerini listele" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "MIME türü için iÅŸleyici belirle veya al" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Dizinler oluÅŸtur" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Dosyaları ve dizinleri deÄŸiÅŸiklikler için gözlemle" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Konumları baÄŸla veya ayır" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "Bir veya daha çok dosya taşı" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Dosyaları öntanımlı uygulamayla aç" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Dosyayı yeniden adlandır" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Bir veya daha çok dosya sil" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Standart girdiden oku ve kaydet" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Dosya özniteliÄŸi belirle" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "Dosyaları veya dizinleri çöpe taşı" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "Konumların içeriklerini aÄŸaçta listele" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "Ayrıntılı yardım almak için %s kullan.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "stdout’a yazılırken hata" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "KONUM" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "Dosyaları bitiÅŸtir ve standart çıktıya yazdır." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat geleneksel cat aracı gibi çalışır, ancak yerel dosyalar\n" +"yerine GIO konumlarını kullanır: örneÄŸin, smb://sunucu/kaynak/dosya.txt\n" +"gibi bir ÅŸeyi konum olarak kullanabilirsiniz." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Konum verilmedi" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Hedef dizin yok" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "İlerlemeyi göster" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Üzerine yazmadan önce onay iste" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Tüm öznitelikleri koru" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Var olan hedef dosyaları yedekle" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Simgesel baÄŸlantıları asla takip etme" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "Hedef için öntanımlı izinleri kullan" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "%s/%s aktarıldı (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "KAYNAK" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "HEDEF" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Bir veya daha çok dosyayı KAYNAK’tan HEDEF’e taşı." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy geleneksel cp aracı gibi çalışır, ancak yerel dosyalar\n" +"yerine GIO konumlarını kullanır: örneÄŸin, smb://sunucu/kaynak/dosya.txt\n" +"gibi bir ÅŸeyi konum olarak kullanabilirsiniz." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "%s konumu bir dizin deÄŸildir" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: “%s†üzerine yaz? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "Yazılabilir öznitelikleri listele" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Dosya sistemi bilgisi al" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Alınacak öznitelikler" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ÖZNİTELİKLER" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Simgesel baÄŸlantıları takip etme" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "öznitelikler:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "gösterme adı: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "düzenleme adı: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "ad: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "tür: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "boyut: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "gizli\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "yerel yol: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix baÄŸlaması: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Belirlenebilir öznitelikler:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Yazılabilir öznitelik ad boÅŸlukları:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Konumlar hakkında bilgi göster." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info geleneksel ls aracı gibi çalışır, ancak yerel dosyalar\n" +"yerine GIO konumlarını kullanır: örneÄŸin, smb://sunucu/kaynak/dosya.txt\n" +"gibi bir ÅŸeyi konum olarak kullanabilirsiniz. Dosya öznitelikleri\n" +"GIO adıyla birlikte belirtilebilir, örneÄŸin standard::icon; veya yalnızca\n" +"ad boÅŸluÄŸu, örneÄŸin unix; veya tüm öznitelikleri eÅŸleyen “*†gibi" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "MASAUSTU-DOSYASI [DOSYA-ARG …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"Masaüstü dosyasından uygulama baÅŸlat, isteÄŸe baÄŸlı dosya adı argümanları " +"geçir." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Verilen masaüstü dosyası yok" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "BaÅŸlatma komutu, ÅŸu anda bu platformda desteklenmiyor" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "‘%s‘ yüklenemedi: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "‘%s‘ için uygulama bilgisi yüklenemedi" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "‘%s’ uygulaması baÅŸlatılamadı: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Gizli dosyaları göster" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "Uzun listeleme biçimini kullan" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "Gösterme adlarını yazdır" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "Tam URI’leri yazdır" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "Konumların içeriklerini listele." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list geleneksel ls aracı gibi çalışır, ancak yerel dosyalar\n" +"yerine GIO konumlarını kullanır: örneÄŸin, smb://sunucu/kaynak/dosya.txt\n" +"gibi bir ÅŸeyi konum olarak kullanabilirsiniz. Dosya öznitelikleri\n" +"GIO adıyla birlikte belirtilebilir, örneÄŸin standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETÜRÜ" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "İŞLEYİCİ" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Bir MIME türü için iÅŸleyici belirle veya al." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"EÄŸer iÅŸleyici verilmemiÅŸse, MIME türü için kaydedilen ve önerilen\n" +"uygulamaları listeler. EÄŸer iÅŸleyici verildiyse, onu MIME türü için\n" +"öntanımlı olarak belirler." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Bir MIME türünü belirtmelidir, ve belki bir iÅŸleyiciyi" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "“%s†için öntanımlı uygulama yok\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "“%s†için öntanımlı uygulama: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "Kayıtlı uygulamalar:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Kayıtlı uygulama yok\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Önerilen uygulamalar:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Önerilen uygulama yok\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "“%s†iÅŸleyicisinin bilgileri yüklenemedi" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "“%sâ€, “%s†için öntanımlı iÅŸleyici olarak belirlenemedi: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Üst dizinler oluÅŸtur" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Dizinler oluÅŸtur." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir geleneksel mkdir aracı gibi çalışır, ancak yerel dosyalar\n" +"yerine GIO konumlarını kullanır: örneÄŸin, smb://sunucu/kaynak/dizinim\n" +"gibi bir ÅŸeyi konum olarak kullanabilirsiniz." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Bir dizini gözlemle (öntanımlı: türe baÄŸlıdır)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "Bir dosyayı gözlemle (öntanımlı: türe baÄŸlıdır)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"Bir dosyayı doÄŸrudan gözlemle (hard link’ler aracılığıyla yapılan " +"deÄŸiÅŸiklikleri bildirir)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "Bir dosyayı doÄŸrudan gözlemler ama deÄŸiÅŸiklikleri bildirmez" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"Taşımaları ve yeniden adlandırmaları, basit silindi/oluÅŸturuldu eylemleri " +"olarak bildir" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "BaÄŸlama eylemlerini gözlemle" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Dosyaları ve dizinleri deÄŸiÅŸiklikler için gözlemle." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "BaÄŸlanabilir olarak baÄŸla" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Aygıt dosyasıyla veya baÅŸka tanımlayıcıyla bölümü baÄŸla" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "Kimlik" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Ayır" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Çıkart" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Aygıt dosyasıyla sürücüyü durdur" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "AYGIT" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Verilen ÅŸemayla birlikte tüm baÄŸları ayır" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "ÅžEMA" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ayırırken veya çıkarırken tamamlanmamış dosya eylemlerini göz ardı et" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "Yetkilendirirken anonim bir kullanıcı kullan" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "Listele" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "Eylemleri gözlemle" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Ek bilgi göster" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "VeraCrypt bölümünün kilidini kaldırırkenki sayısal PIM" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "TCRYPT gizli bölümü baÄŸla" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "TCRYPT sistem bölümü baÄŸla" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Anonim eriÅŸim engellendi" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Aygıt dosyası için sürücü yok" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Bu kimlik için bölüm yok" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Konumları baÄŸla veya ayır." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Kopyayı kullanma ve geridönüşü sil" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "Bir veya daha çok dosyayı KAYNAK’tan HEDEF’e taşı." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move geleneksel mv aracı gibi çalışır, ancak yerel dosyalar\n" +"yerine GIO konumlarını kullanır: örneÄŸin, smb://sunucu/kaynak/dosya.txt\n" +"gibi bir ÅŸeyi konum olarak kullanabilirsiniz" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "%s hedefi bir dizin deÄŸil" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Dosyaları, bu türden dosyaları iÅŸlemek için\n" +"kaydedilen öntanımlı uygulama ile aç." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Var olmayan dosyaları yok say, asla onay isteme" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Verilen dosyaları sil." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "AD" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Bir dosyayı yeniden adlandır." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Eksik argüman" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Fazla argüman" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "Yeniden adlandırma baÅŸarılı. Yeni uri: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Yalnızca yoksa oluÅŸtur" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "Dosyanın sonuna iliÅŸtir" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "OluÅŸtururken, eriÅŸimi ÅŸimdiki kullanıcıya kısıtla" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "Yerine koyarken, hedef yokmuşçasına yerine koy" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "Sonda yeni bir etag yazdır" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "Dosyanın etag’inin üzerine yazılıyor" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Standart girdiden okuma hatası" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag kullanılabilir deÄŸil\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "Standart girdiden oku ve HEDEF’e kaydet." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Verilen hedef yok" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "ÖzniteliÄŸin türü" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TÜR" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ÖZNİTELİK" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "DEÄžER" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "KONUM’un bir dosya özniteliÄŸini belirle." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Konum belirtilmedi" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Öznitelik belirtilmedi" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "DeÄŸer belirtilmedi" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Geçersiz öznitelik türü “%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Çöpü temizle" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "Çöpteki dosyaları kendi özgün konumlarıyla listele" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Bir dosyayı çöpten kendi özgün konumuna geri yükle (büyük olasılıkla dizini " +"yeniden yaratacak)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Özgün yol bulunamadı" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Özgün konum yeniden yaratılamadı: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Dosya kendi özgün konumuna taşınamadı: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "Dosyaları veya dizinleri çöpe Taşı/Geri Yükle." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"Anımsatma: --restore için, eÄŸer çöpe atılmış dosyanın özgün konumu\n" +"halihazırda varsa, --force belirtilmedikçe üzerine yazılmayacaktır." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Verilen konum trash:/// ile baÅŸlamıyor" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "Simgesel baÄŸlantıları, baÄŸları ve kısayolları takip et" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "Dizinlerin içeriklerini aÄŸaç benzeri biçimde listele." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%2$s> içinde <%1$s> ögesine izin verilmiyor" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> ögesine en üst seviyede izin verilmiyor" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Dosya %s kaynakta birden çok kez görünüyor" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Herhangi bir kaynak dizinde “%s†konumlanamadı" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Geçerli dizinde “%s†konumlanamadı" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Bilinmeyen iÅŸleme seçeneÄŸi “%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "%s ön iÅŸleme istendi, ancak %s belirtilmedi ve %s PATH içinde deÄŸil" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "%s dosyası okuma hatası: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "%s dosyası sıkıştırma hatası" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s> içinde metin bulunamaz" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "Programın sürümünü göster ve çık" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Çıktı dosyasının adı" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"DOSYAʼda belirtilen dosyaların yükleneceÄŸi dizinler (öntanımlı: geçerli " +"dizin)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "DİZİN" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "Hedef dosya adı uzantısı tarafından seçilen biçimde çıktı oluÅŸtur" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Kaynak baÅŸlığı oluÅŸtur" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Kodunuz içinde kaynak dosyasına baÄŸlanmak için kullanılacak kaynak kodu " +"oluÅŸturun" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Bağımlılık listesi oluÅŸtur" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "OluÅŸturulacak bağımlılık dosyasının adı" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "OluÅŸturulan bağımlılık dosyasında sahte hedefleri içer" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Kaynağı kendiliÄŸinden oluÅŸturma ve kaydetme" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "İşlevleri dışarı aktarma; onları G_GNUC_INTERNAL beyan et" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Kaynak verileri C dosyasına gömme; bunun yerine harici olarak baÄŸlandığını " +"varsay" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "C oluÅŸturulan kaynak kod için kullanılan tanımlayıcı ad" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "Hedef C derleyici (öntanımlı: CC ortam deÄŸiÅŸkeni)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Bir kaynak dosyasına kaynak özelliklerini derle.\n" +"Kaynak özellikleri dosyaları .gresource.xml uzantısına sahiptir\n" +"ve kaynak dosyaları uzantısı .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Tam olarak bir adet dosya adı vermelisiniz\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "takma ad en az 2 karakterden oluÅŸmalıdır" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Geçersiz sayısal deÄŸer" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "bayrak deÄŸerlerinin en çok 1 bit seti olmalıdır" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> en az bir içermelidir" + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s>, belirlenen aralık içinde deÄŸil" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s>, belirtilen numaralandırılmış türün geçerli bir üyesi deÄŸildir" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> belirtilen bayrak türlerinden olmayan dizge içeriyor" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s>, içinde olmayan bir dizge içeriyor" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " bu anahtar için zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "“%s†türünün anahtarları için izin verilmiyor" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " belirlenen asgari, azamiden büyük" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "desteklenmeyen l10n kategorisi: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "l10n istendi, ama verilen gettext alanı yok" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "l10n etkinleÅŸtirilmeden deÄŸer için verilen çeviri baÄŸlamı" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "“%s†türünün deÄŸeri ayrıştırılamadı: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +", numaralandırılmış türü olan olarak etiketlenmiÅŸ anahatarlar için " +"belirtilemez" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " bu anahtar için zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "“%s†türünün anahtarları için izin verilmemektedir" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " zaten verilmiÅŸ" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr ", en az bir içermelidir" + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " bu anahtar için zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" yalnızca numaralandırılmış anahtarlar için veya bayrak türleri " +"veya ardında belirtilebilir" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "" +"“%2$s†zaten numaralandırılmış türün bir üyesiyken " +"verildi" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "" +" zaten verildiÄŸinde verildi" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "takma ad hedefi “%sâ€, numaralandırılmış tür içinde deÄŸil" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "takma ad hedefi “%sâ€, içinde deÄŸil" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " en az bir içermelidir" + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "BoÅŸ adlara izin verilmiyor" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Geçersiz ad “%sâ€: adlar küçük harf ile baÅŸlamalıdır" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Geçesiz ad “%sâ€: geçersiz karakter “%câ€; yalnızca küçük harfler, sayılar ve " +"tire (“-â€) imi kullanılabilir" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Geçesiz ad “%sâ€: birbirini izleyen iki tire (“--â€) kullanılamaz" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Geçesiz ad “%sâ€: son karakter tire (“-â€) olamaz." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Geçesiz ad “%sâ€: olabilecek azami uzunluk 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "“list-of†şemasına anahtarlar eklenemiyor" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" dizgesi içindeki " +"dizgesini gölgeler; deÄŸerleri deÄŸiÅŸtirmek için kullanın" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "" +"’e “typeâ€, “enumâ€, ya da “flags†özniteliklerinden bir tanesi " +"kesinlikle belirtilmelidir" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> (henüz) tanımlanmamış." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Geçersiz GVariant tür dizgesi “%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr " verildi, ancak ÅŸema hiçbir ÅŸeyi geniÅŸletmiyor" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Üzerine yazılacak hiçbir yok" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " henüz var olmayan “%s†şemasını geniÅŸletir" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " henüz var olmayan “%s†şemasının bir listesidir" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Yolu olan bir ÅŸemanın listesi olamaz" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Åžema bir yol ile geniÅŸletilemez" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +", liste olmayan 'i geniÅŸleten bir listedir" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +", ’i geniÅŸletir; " +"ancak “%sâ€, “%sâ€i geniÅŸletemez" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "EÄŸer verilmiÅŸse, yol, mutlaka bir taksim ile baÅŸlayıp bitmeli" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "Listenin yolu mutlaka “:/†ile bitmelidir" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"Uyarı: “%s†şeması “%s†yoluna sahip. “/apps/â€, “/desktop/†veya “/system/†" +"ile baÅŸlayan yollar artık kullanılmamaktadır." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> zaten belirtilmiÅŸ" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "<%s> içinde yalnızca bir <%s> ögesi bulunabilir" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "<%s> ögesine en üst düzeyde izin verilmez" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr " ögesi içinde zorunludur" + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "<%s> içinde metin bulunamayabilir" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "Uyarı: ’e tanımlanmamış referans" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "--strict belirtildi; çıkılıyor." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "Bu dosyanın tümü göz ardı edildi." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Bu dosya göz ardı ediliyor." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"“%3$s†dosyasında üzerine yazılacağı belirtilen “%2$s†şemasında “%1$s†gibi " +"bir anahtar yok; bu anahtar için üstüne yazma göz ardı ediliyor." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"“%3$s†dosyasında üzerine yazılacağı belirtilen “%2$s†şemasında “%1$s†gibi " +"bir anahtar yok ve --strict belirtildi; çıkılıyor." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"“%s†şemasında “%s†yerleÅŸik anahtarı için masaüstü başına üstüne yazma " +"saÄŸlanamıyor (üstüne yazma dosyası “%sâ€); bu anahtar için üstüne yazma göz " +"ardı ediliyor." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"“%s†şemasında “%s†yerleÅŸik anahtarı için masaüstü başına üstüne yazma " +"saÄŸlanamıyor (üstüne yazma dosyası “%sâ€) ve --strict belirtildi; çıkılıyor." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"“%3$s†dosyasında üzerine yazılacağı belirtilen “%2$s†şemasında “%1$s†" +"anahtarı ayrıştırmada hata: %4$s. Bu anahtar için üzerine yazma göz ardı " +"ediliyor." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"“%3$s†dosyasında üzerine yazılacağı belirtilen “%2$s†şemasında “%1$s†" +"anahtarı ayrıştırmada hata: %4$s. --strict belirtildi; çıkılıyor." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"“%3$s†üzerine yazma dosyasındaki “%2$s†şemasının “%1$s†anahtarının " +"üzerine yazma, ÅŸemada verilen aralığın dışındadır; bu anahtar için üstüne " +"yazma göz ardı ediliyor." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"“%3$s†üzerine yazma dosyasındaki “%2$s†şemasının “%1$s†anahtarının " +"üzerine yazma, ÅŸemada verilen aralığın dışındadır ve --strict belirtildi; " +"çıkılıyor." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"“%3$s†dosyasındaki “%2$s†şemasının “%1$s†anahtarının üzerine yazma, " +"geçerli seçenekler listesinde deÄŸildir; bu anahtar için üstüne yazma göz " +"ardı ediliyor." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"“%3$s†dosyasındaki “%2$s†şemasının “%1$s†anahtarının üzerine yazma, " +"geçerli seçenekler listesinde deÄŸildir ve --strict belirtildi; çıkılıyor." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "gschemas.compiled dosyasının saklanacağı yer" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "Åžemalardaki herhangi bir hatada iptal et" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled dosyasını yazma" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Anahtar adı kısıtlamalarını zorlama" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Tüm GSettings ÅŸema dosyalarını bir ÅŸema önbelleÄŸi içerisine derle.\n" +"Åžema dosyalarının .gschema.xml uzantısına sahip olmaları gerekir,\n" +"ve önbellek dosyası gschemas.compiled olarak anılır." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Tam olarak bir adet dizin adı vermelisiniz" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Hiç ÅŸema dosyası bulunamadı: hiçbir ÅŸey yapılmıyor." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Hiç ÅŸema dosyası bulunamadı: var olan çıktı dosyası kaldırıldı." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Geçersiz dosya adı %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "%s için dosya sistemi bilgisi alınırken hata: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "%s dosyası için baÄŸlama bulunamadı" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Kök dizini yeniden adlandırılamaz" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "%s dosyası yeniden adlandırılırken hata: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Dosya yeniden adlandırılamıyor, dosya adı zaten var" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Geçersiz dosya adı" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "%s dosyası açılırken hata: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "%s dosyası silinirken hata: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "%s dosyası çöpe atılırken hata: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Çöp dizini %s oluÅŸturulamadı: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "%s çöpe atmak için en üst seviye dizin bulunamıyor" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "Sistem iç baÄŸlarına çöpleme desteklenmiyor" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "%2$s çöpe atılırken %1$s çöp dizini bulunamıyor ya da oluÅŸturulamıyor" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "%s için çöp bilgi dosyası oluÅŸturulamıyor: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "%s dosyası, dosya sistemi sınırları dışına, çöpe atılamıyor" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "%s dosyası çöpe atılamıyor: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "%s dosyası çöpe atılamıyor" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "%s dizini oluÅŸturulurken hata: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Dosya sistemi simgesel baÄŸları desteklemiyor" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "%s simgesel baÄŸlantısı yapılırken hata: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "%s dosyası taşınırken hata: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Dizin dizin üzerine taşınamıyor" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Yedek dosyası oluÅŸturma baÅŸarısız oldu" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Hedef dosya silerken hata: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "BaÄŸlı sistemler arasında taşıma desteklenmiyor" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "%s’in disk kullanımı saptanamadı: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Öznitelik deÄŸeri NULL olmamalı" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Geçersiz öznitelik türü (dizgi beklendi)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Geçersiz geniÅŸletilmiÅŸ öznitelik adı" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "“%s†geniÅŸletilmiÅŸ özniteliÄŸi atanırken hata: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (geçersiz kodlama)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "“%s†dosyası için bilgi alınırken hata: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Dosya tanımlayıcı için bilgi alındığında hata: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Geçersiz öznitelik türü (uint32 beklendi)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Geçersiz öznitelik türü (uint64 beklendi)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Geçersiz öznitelik türü (byte dizisi beklendi)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Simgesel baÄŸlar üzerindeki yetkiler ayarlanamıyor" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "İzinler atanırken hata: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Sahip atanırken hata: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "simgesel baÄŸ NULL olmamalı" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Simgesel baÄŸ atanırken hata: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "Simgesel baÄŸ atanırken hata: dosya bir simgesel baÄŸ deÄŸil" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "UNIX zaman damgası %2$lld için %1$d ek nanosaniye negatif" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "UNIX zaman damgası %2$lld için %1$d ek nano saniye 1 saniyeye ulaÅŸtı" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX zaman damgası %lld 64 bit’e sığmıyor" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"UNIX zaman damgası %lld Windows tarafından desteklenen aralığın dışında" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "“%s†dosya adı UTF-16’ya dönüştürülemedi" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "“%s†dosyası açılamadı: Windows Hatası %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "“%s†dosyasına deÄŸiÅŸtirme veya eriÅŸim süresi atanırken hata: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "DeÄŸiÅŸtirme veya eriÅŸim süresi atanırken hata: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux baÄŸlamı NULL olmamalı" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux bu sistede etkin deÄŸil" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux baÄŸlamı atanırken hata: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Öznitelik %s ataması desteklenmiyor" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Dosyadan okunurken hata: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Dosya kapatılırken hata: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Dosya içinde atlama yapılırken hata: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Öntanımlı yerel dosya izleme türü bulunamadı" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Dosyaya yazılırken hata: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Eski yedek bağı silinirken hata: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Yedek kopyası oluÅŸturulurken hata: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Geçici dosya yeniden adlandırılırken hata: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Dosyanın sonu kesilirken hata: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "“%s†dosyası açılırken hata: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Hedef dosya bir dizin" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Hedef dosya normal dosya deÄŸil" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Dosya dışarıdan deÄŸiÅŸtirilmiÅŸ" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Eski dosya silinirken hata: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Geçersiz GSeekType saÄŸlandı" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Geçersiz atlama isteÄŸi" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream sonu silinemiyor" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Bellek çıktı akışı yeniden boyutlandırılamaz" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Hafız çıktı açışı yeniden boyutlandırma baÅŸarısız oldu" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Yazma iÅŸlemi için gereken bellek miktarı, kullanılabilir adres uzayından " +"daha büyük" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Akış baÅŸlamadan önce arama istendi" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Akışın sonu dışında arama istendi" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "baÄŸlama, “ayır†iÅŸlemini yerine getirmiyor" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "baÄŸlama, “çıkar†iÅŸlemini yerine getirmiyor" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "" +"baÄŸlama, “ayır†veya “unmount_with_operation†iÅŸlemini yerine getirmiyor" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"baÄŸlama, “çıkar†veya “eject_with_operation†iÅŸlemini yerine getirmiyor" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "baÄŸlama, “remount†iÅŸlemini yerine getirmiyor" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "baÄŸlama, içerik türü tahminini yerine getirmiyor" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "baÄŸlama, eÅŸ zamanlı içerik türü tahminini yerine getirmiyor" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "“%s†ana makine adı “[†içeriyor ama “]†içermiyor" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "AÄŸa eriÅŸilemiyor" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Makineye eriÅŸilemiyor" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "AÄŸ izleme oluÅŸturulamadı: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "AÄŸ izleme oluÅŸturulamadı: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "AÄŸ durumu alınamadı: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager çalışmıyor" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager sürümü çok eski" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "Çıktı akışı yazmayı yerine getirmiyor" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "%s için geçilen vektörlerin toplamı çok büyük" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Kaynak akışı zaten kapalı" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "“%s†çözülürken hata: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s uygulanmadı" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Geçersiz alan adı" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "“%s†konumundaki kaynak yok" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "“%s†konumundaki kaynak açılamadı" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "“%s†konumundaki kaynak bir dizin deÄŸildir" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "Girdi akışı aramayı yerine getirmiyor" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "Kaynakları içeren bölümleri bir elf DOSYASINDA listele" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Kaynakları listele\n" +"EÄŸer BÖLÜM verilirse, yalnızca bu bölümün kaynaklarını listele\n" +"EÄŸer YOL verilirse, yalnızca eÅŸleÅŸen kaynakları listele" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "DOSYA [YOL]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "[BÖLÜM]" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Kaynakları ayrıntılarıyla listele\n" +"EÄŸer BÖLÜM verilirse, yalnızca bu bölümdeki kaynakları listele\n" +"EÄŸer YOL verilirse, yalnızca eÅŸleÅŸen kaynakları listele\n" +"Ayrıntılar bölüm, boyut, sıkıştırma bilgilerini içerir" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "Bir kaynak dosyasını stdout konumuna çıkar" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "DOSYA YOLU" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Kullanım:\n" +" gresource [--section BÖLÜM] KOMUT [DEĞİŞKENLER…]\n" +"\n" +"Komutlar:\n" +" help Bu bilgileri gösterir\n" +" sections Kaynak bölümlerini listeler\n" +" list Kaynakları listeler\n" +" details Ayrıntılarıyla kaynakları listeler\n" +" extract Bir kaynağı çıkarır\n" +"\n" +"Ayrıntılı yardım almak için “gresource help KOMUT†komutunu kullan.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Kullanım:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " BÖLÜM (İsteÄŸe BaÄŸlı) Bir elf bölüm adı\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " KOMUT (İsteÄŸe BaÄŸlı) Açıklanacak komut\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " DOSYA Bir elf dosyası (ikili ya da paylaşımlı bir kütüphane)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" DOSYA Bir elf dosyası (ikili ya da paylaşımlı bir kütüphane)\n" +" ya da derlenmiÅŸ bir kaynak dosyası\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[YOL]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " YOL (isteÄŸe baÄŸlı) kaynak yolu (kısmi olabilir)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "YOL" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " YOL Kaynak yolu\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "“%s†gibi bir ÅŸema yok\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "" +"“%s†şeması yeniden konumlandırılabilir deÄŸildir (yol belirtilmemelidir)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "" +"“%s†şeması yer deÄŸiÅŸtirebilirdir (yol mutlaka belirtilmiÅŸ olmalıdır)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "BoÅŸ bir yol girildi.\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "Yol, mutlaka taksim (/) ile baÅŸlamalıdır\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "Yol, mutlaka bir taksim (/) ile bitmelidir\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "Yol, ardışık olan iki taksim (//) içeremez\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "SaÄŸlanan deÄŸer, geçerli aralığın dışında\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Anahtar yazılabilir deÄŸildir\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Yüklü (yeniden konumlandırılamaz) ÅŸemaları listele" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Yeniden yer deÄŸiÅŸtirebilir ÅŸemaları listele" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "ÅžEMA içindeki anahtarları listele" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "ÅžEMA[:YOL]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Alt ÅžEMALARI listele" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Özyinelemeli biçimde anahtar ve deÄŸerleri listele\n" +"EÄŸer hiçbir ÅžEMA verilmediyse, tüm anahtarları listele\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[ÅžEMA[:YOL]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "ANAHTAR deÄŸerini al" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "ÅžEMA[:YOL] ANAHTAR" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "ANAHTAR için geçerli deÄŸerler aralığını sorgula" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "ANAHTAR için açıklamayı sorgula" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "ANAHTAR’ın deÄŸerini DEÄžER’e ata" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "ÅžEMA[:YOL] ANAHTAR DEÄžER" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "ANAHTAR’ı öntanımlı deÄŸerine döndür" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "ÅžEMA içindeki tüm anahtarları öntanımlı deÄŸerlerine döndür" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "ANAHTAR’ın yazılabilir olup olmadığını denetle" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"DeÄŸiÅŸiklikleri için ANAHTAR izleyin.\n" +"EÄŸer hiçbir ANAHTAR belirtilmemiÅŸse, ÅžEMA’daki tüm anahtarları izleyin.\n" +"İzlemeyi durdurmak için ^C kullanın.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "ÅžEMA[:YOL] [ANAHTAR]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"Kullanım:\n" +" gsettings --version\n" +" gsettings [--schemadir ÅžEMA_DİZİNİ] KOMUT [DEĞİŞKENLER…]\n" +"\n" +"Komutlar:\n" +" help Bu bilgiyi gösterir\n" +" list-schemas Yüklü ÅŸemaları listeler\n" +" list-relocatable-schemas Yer deÄŸiÅŸebilen ÅŸemaları listeler\n" +" list-keys Åžemadaki anahtarları listeler\n" +" list-children Åžemanın alt ÅŸemalarını listeler\n" +" list-recursively Özyinelemeli olarak anahtarlar ve deÄŸerleri " +"listeler\n" +" range Anahtarın uzunluÄŸunu sorgular\n" +" get Anahtarın deÄŸerini getirir\n" +" set Anahtarın deÄŸerini ayarlar\n" +" reset Anahtarın deÄŸerini sıfırlar\n" +" reset-recursively Verilen ÅŸemadaki tüm deÄŸerleri sıfırlar\n" +" writable Anahtarın yazılabilirliÄŸini denetler\n" +" monitor DeÄŸiÅŸiklikleri görüntüler\n" +"\n" +"Ayrıntılı yardım için “gsettings help KOMUT†komutunu çalıştırın.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Kullanım:\n" +" gsettings [--schemadir ÅžEMADİZİNİ] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " ÅžEMADİZİNİ Ek ÅŸemaları aramak için bir dizin\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" ÅžEMA Åžemanın adı\n" +" YOL Yol, yeniden konumlandırılabilir ÅŸemalar için\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " ANAHTAR Åžema içinde (isteÄŸe baÄŸlı) anahtar\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " ANAHTAR Åžema içindeki anahtar\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " DEÄžER Ayarlanacak deÄŸer\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s’den ÅŸemalar yüklenemedi: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Hiçbir ÅŸema kurulmadı\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "BoÅŸ ÅŸema adı verildi\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "“%s†gibi bir anahtar yok\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Geçersiz yuva, baÅŸlatılmadı" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Geçersiz yuva, baÅŸlatma baÅŸarısız oldu: %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Yuva zaten kapalı" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Yuva G/Ç zaman aşımı" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "fd’den GSocket oluÅŸturuluyor: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Yuva oluÅŸturulamadı: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Bilinmeyen küme belirtildi" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Bilinmeyen iletiÅŸim kuralı belirtildi" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "Datagram olmayan bir yuva üzerinde datagram iÅŸlemleri kullanılamaz." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Zamanaşımı ayarlanmış bir yuva üzerinde datagram iÅŸlemleri kullanılamaz." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "yerel adres alınamadı: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "uzaktaki adres alınamadı: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "dinlenemedi: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "%s adresine baÄŸlanırken hata: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Çok yöne yayın kümesine katılırken hata: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Çok yöne yayın kümesinden ayrılırken hata: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "KaynaÄŸa-özgü çok yöne yayın desteklenmiyor" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Desteklenmeyen yuva ailesi" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "kaynaÄŸa-özgü bir IPv4 adresi deÄŸil" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Arayüz adı çok uzun" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Arayüz bulunamadı: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "IPv4 kaynaÄŸa-özgü çok yöne yayın desteklenmiyor" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "IPv6 kaynaÄŸa-özgü çok yöne yayın desteklenmiyor" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "BaÄŸlantı kabul edilirken hata: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "BaÄŸlantı devam ediyor" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Bekleyen hata alınamadı: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Veri alırken hata: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Veri gönderirken hata: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Yuva kapatılamadı: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Yuva kapatılırken hata: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Yuva durumu bekleniyor: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "İleti gönderilemedi: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "İleti vektörleri çok geniÅŸ" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "İleti gönderme hatası: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage Windows iÅŸletim sisteminde desteklenmiyor" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "İleti alma hatası: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Yuva kimliÄŸi okunamadı : %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "bu iÅŸletim sistemi için g_socket_get_credentials uygulanmadı" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "%s vekil sunucusuna baÄŸlanılamadı: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s baÄŸlantısı gerçekleÅŸtirilemedi: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "BaÄŸlanılamadı: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "TCP olmayan baÄŸlantılar üzerinden vekil sunucusu desteklenmiyor." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "“%s†vekil iletiÅŸim kuralı desteklenmiyor." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "Dinleyici zaten kapalı" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Eklenen yuva kapalı" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4, “%s†IPv6 adresini desteklemiyor" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Kullanıcı adı SOCKSv4 iletiÅŸim kuralı için çok uzun" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "“%s†makine adı SOCKSv4 iletiÅŸim kuralı için çok uzun" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Bu sunucu bir SOCKSv4 vekil sunucusu deÄŸil." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 sunucusu ile baÄŸlantı, reddedildi" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Sunucu, bir SOCKSv5 vekil sunucusu deÄŸil." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 vekil sunucusu kimlik doÄŸrulaması gerektiriyor." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"SOCKSv5 vekil sunucusu, Glib tarafından desteklenmeyen bir kimlik doÄŸrulama " +"yöntemi istiyor." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Kullanıcı adı ya da parola SOCKSv5 iletiÅŸim kuralı için çok uzun." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Yanlış kullanıcı adı ya da paroladan dolayı SOCKSv5 kimlik doÄŸrulaması " +"baÅŸarısız oldu." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "“%s†makine adı SOCKSv5 iletiÅŸim kuralı için çok uzun" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 vekil sunucusu, bilinmeyen bir adres türü kullanıyor." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "İç SOCKSv5 vekil sunucu hatası." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Kural kümesi tarafından SOCKSv5 baÄŸlantısına izin verilmiyor." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 sunucusu üzerinden makineye ulaşılamıyor." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 vekil sunucusu üzerinden aÄŸa ulaşılamıyor." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 vekil sunucusu üzerinden baÄŸlantı reddedildi." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 vekil sunucusu “connect†komutunu desteklemiyor." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 vekil sunucusu verilen adres türünü desteklemiyor." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Bilinmeyen SOCKSv5 vekil hatası." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Alt süreçle haberleÅŸme için boru yaratılamadı (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Borular bu platformda desteklenmiyor" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon kodlaması %d sürümü iÅŸlenemiyor" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Geçersiz adresler bulundu" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "“%s†tersine çözülürken hata: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "DNS %s kaydı ayrıştırılamadı: kusurlu DNS paketi" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "“%s†için istenen türün DNS kaydı yok" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "Geçici olarak “%s†çözülemiyor" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "“%s†çözerken hata" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Kusurlu DNS paketi" + +#: gio/gthreadedresolver.c:886 +#, c-format +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "“%s†için DNS yanıtı ayrıştırılamadı: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Hiçbir PEM-kodlamalı özel anahtar bulunamadı" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-kodlamalı özel anahtar ÅŸifresi çözülemiyor" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM-kodlamalı özel anahtar ayrıştırılamadı" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "PEM-kodlamalı sertifika bulunamadı" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM-kodlamalı sertifika ayrıştırılamadı" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "Var olan TLS arka ucu PKCS #12 desteklemiyor" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "GTlsBackend, PKCS #11 sertifikası yaratmayı desteklemiyor" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Bu, eriÅŸiminiz kilitlenmeden önce parolanızı doÄŸru girmeniz için son ÅŸanstır." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Girilen birkaç parola hatalı olmuÅŸtur ve daha çok hatalı giriÅŸten sonra " +"eriÅŸiminiz kilitlenecektir." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Girilen parola hatalı." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "FD gönderimi desteklenmiyor" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Beklenen 1 denetim iletisi, alınan %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Yardımcı verinin beklenmeyen türü" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Beklenen bir fd, ancak alınan %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Geçersiz fd alındı" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "FD alımı desteklenmiyor" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "Kimlik bilgileri gönderilirken hata oluÅŸtu: " + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Yuva için SO_PASSCRED’in etkin olup olmadığını denetleme hatası: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED etkinleÅŸtirmede hata: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Kimlik bilgileri almak için bir bayt okunması bekleniyordu, sıfır bayt okundu" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Beklenen denetim iletisi yok ancak %d alındı" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED devre dışı bırakılırken hata: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Dosya tanımlayıcıdan okuma hatası: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Dosya tanımlayıcı kapatılırken hata: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Dosya sistemi kök dizini" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Dosya tanımlayıcıya yazmada hata: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Soyut UNIX alan yuvası adresleri bu sistemde desteklenmiyor" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "bölüm, çıkartmayı yerine getirmiyor" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "bölüm, çıkartmayı veya eject_with_operation’ı yerine getirmiyor" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "İşleyiciden okumada hata: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "İşleyici kapatılırken hata: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "İşleyiciye yazmada hata: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Yeterli bellek yok" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "İç hata: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Daha çok girdi gerekli" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Geçersiz sıkıştırılmış veri" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Dinlemek için adres" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Yok sayılmış, GTestDBUS ile compat için" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Adres yazdır" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Kabuk kipinde adres yazdır" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Bir dbus servisi çalıştır" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Yanlış deÄŸiÅŸkenler\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "“%2$s†ögesi için beklenmeyen “%1$s†özniteliÄŸi" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "“%2$s†ögesinde “%1$s†özniteliÄŸi bulunamadı" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Beklenmeyen etiket “%sâ€, “%s†bekleniyordu" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "“%2$s†içinde beklenmeyen etiket “%1$sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Yer imi dosyasında geçersiz tarih/saat ‘%s’" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Veri dizinlerinde geçerli bir yer imi dosyası bulunamadı" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "“%s†URI’si için bir yer imi zaten var" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "“%s†URI’si için bir yer imi bulunamadı" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "“%s†URI’si için yer iminde hiçbir MIME türü belirtilmedi" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "“%s†URI’si için yer iminde özel bayrak tanımlanmadı" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "“%s†URI’si için yer iminde küme tanımlanmadı" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "“%s†adında hiçbir uygulama “%s†için yer imi kaydetmedi" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Exec satırı “%sâ€, “%s†URI’si ile geniÅŸletilirken baÅŸarısız olundu" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Dönüşüm girdisi içinde temsil edilemez karakter" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Girdinin sonunda parçalı karakter dizisi" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "" +"Geridönüş karakter kümesi “%sâ€, “%s†karakter kümesine dönüştürülemiyor" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Dönüşüm girdisinde gömülü NUL baytı" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Dönüşüm çıktısında gömülü NUL baytı" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "“%s†URI’si, “file†şemasını kullanan kesin bir URI deÄŸil" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "Yerel dosya URI’si “%sâ€, “#†içeremez" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "“%s†URI’si geçersiz" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "“%s†URI’sinin ana makine adı geçersiz" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "“%s†URI’si geçersiz olarak çıkış yapılmış karakterler içeriyor" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "Yol adı “%sâ€, kesin bir yol deÄŸil" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Ocak" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "Şubat" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "Mart" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "Nisan" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "Mayıs" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "Haziran" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "Temmuz" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "AÄŸustos" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "Eylül" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "Ekim" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "Kasım" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "Aralık" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Oca" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Åžub" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Nis" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "May" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Haz" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Tem" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "AÄŸu" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Eyl" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Eki" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Kas" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Ara" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Pazartesi" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Salı" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "ÇarÅŸamba" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "PerÅŸembe" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Cuma" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Cumartesi" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Pazar" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Pzt" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Sal" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Çar" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Per" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Cum" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Cmt" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Paz" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "Ocak" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "Şubat" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "Mart" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "Nisan" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "Mayıs" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "Haziran" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "Temmuz" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "AÄŸustos" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "Eylül" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "Ekim" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "Kasım" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "Aralık" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Oca" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Åžub" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Mar" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Nis" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "May" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Haz" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Tem" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "AÄŸu" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Eyl" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Eki" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Kas" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Ara" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "ÖÖ" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "ÖS" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "“%s†dizini açılamadı: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "%lu bayt “%s†dosyasını okumak için ayrılamadı" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "“%s†dosyası okuma hatası: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "“%s†dosyası çok büyük" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "“%s†dosyasından okuma baÅŸarısız: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "“%s†dosyasını açma baÅŸarısız: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "" +"“%s†dosyasının özniteliklerini alma baÅŸarısız: fstat() baÅŸarısızlığı: %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "“%s†dosyasını açma baÅŸarısız: fdopen() baÅŸarısızlığı: %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "" +"“%s†dosyasının adı “%s†olarak deÄŸiÅŸtirilirken hata: g_rename() " +"baÅŸarısızlığı: %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "“%s†dosyasına yazılamadı: write() baÅŸarısız: %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "“%s†dosyasına yazılamadı: fsync() baÅŸarısız: %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "“%s†dosyasını oluÅŸturma baÅŸarısız: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Var olan dosya “%s†kaldırılamadı: g_unlink() baÅŸarısızlığı: %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "“%s†şablonu geçersiz, “%s†içermemeli" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "“%s†şablonu XXXXXX içermiyor" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "“%s†simgesel bağını okuma baÅŸarısız: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "“%sâ€-“%s†dönüştürücüsü açılamıyor: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string içinde ham okuma yapılamıyor" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Okuma tampon belleÄŸinde kalıntı çevrilmemiÅŸ veri" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Kanal kısmi bir karakterde sonlanıyor" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end içinde ham okuma baÅŸarısız" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Arama dizinlerinde geçerli anahtar dosyası bulunamadı" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Normal dosya deÄŸil" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Anahtar dosyası; anahtar-deÄŸer çifti, küme veya yorum olmayan “%s†satırını " +"içeriyor" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Geçersiz küme adı: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Anahtar dosyası kümeyle baÅŸlamıyor" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Geçersiz anahtar adı: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Anahtar dosya desteklenmeyen “%s†kodlamasını içeriyor" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Anahtar dosyasında “%s†kümesi yok" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Anahtar dosyası, “%2$s†kümesinde “%1$s†anahtarı içermiyor" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "Anahtar dosyası, UTF-8 olmayan “%s†anahtarını “%s†deÄŸeriyle içeriyor" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Anahtar dosyası yorumlanamayan bir deÄŸere sahip olan “%s†anahtarını içerir." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"“%2$s†kümesindeki anahtar dosyası, yorumlanamayan “%1$s†anahtarını " +"içeriyor." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "" +"“%2$s†kümesindeki “%1$s†anahtarı “%4$s†deÄŸerine sahip olması beklenirken " +"“%3$s†deÄŸerine sahip" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Anahtar dosyası satır sonunda çıkış karakteri içeriyor" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "“%s†anahtar dosyası geçersiz çıkış dizisi içeriyor" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "“%s†deÄŸeri bir sayı olarak yorumlanamıyor." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "“%sâ€, tamsayı deÄŸeri aralık dışında" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "“%s†deÄŸeri bir gerçel sayı olarak yorumlanamıyor." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "“%s†deÄŸeri mantıksal deÄŸer olarak yorumlanamıyor." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"“%s%s%s%s†dosyasının özniteliklerini alma baÅŸarısız: fstat() hatası: %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s için eÅŸleme oluÅŸturulamadı: mmap() hatası: %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "“%s†dosyası açılamadı: open() baÅŸarısızlığı: %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Satır %d karakter %d hatalı: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Adda geçersiz UTF-8 kodlu metin — geçerli olmayan “%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%s†geçerli bir ad deÄŸil" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%s†geçerli bir ad deÄŸil: “%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Satır %d hata içeriyor: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Karakter referansı içinde bir rakam olması gereken “%-.*s†ayrıştırılamadı, " +"(örneÄŸin; ê) — rakam çok büyük olabilir" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Karakter referansı noktalı virgül ile bitmemiÅŸ; yüksek olasılıkla bir " +"özvarlık baÅŸlatmak istemeksizin “ve†imi kullandınız — “ve†imini & " +"olarak kullanabilirsiniz" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "Karakter referansı “%-.*s†izin verilen karakteri kodlamıyor" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"BoÅŸ özvarlık “&;†görüldü; geçerli ögeler: & " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Varlık adı “%-.*s†bilinmiyor" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Özvarlık noktalı virgül ile bitmiyor; yüksek olasılıkla bir özvarlık " +"baÅŸlatmak istemeksizin “ve†imi kullandınız — “ve†imini & olarak " +"kullanabilirsiniz" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Belge bir öge ile baÅŸlamalıdır (örneÄŸin )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"“<†karakterinden sonra gelen “%s†geçerli bir karakter deÄŸil; bir öge adı " +"baÅŸlatmamalı" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Tuhaf karakter “%sâ€, “%s†boÅŸ öge etiketinin sonunda “>†karakteri bekledi" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "“%s†ögesinde çok fazla öznitelik var" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Tuhaf karakter “%1$sâ€, “%3$s†ögesinin “%2$s†özniteliÄŸinin sonunda “=†" +"karakteri bekledi" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Tuhaf karakter “%sâ€, “%s†ögesinin baÅŸlangıç etiketini sonlandırmak için " +"“>â€, “/†karakteri veya bir öznitelik bekledi; öznitelik adında geçersiz bir " +"karakter kullanmış olabilirsiniz" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Tuhaf karakter “%1$sâ€, “%3$s†ögesindeki “%2$s†özniteliÄŸi için deÄŸer " +"verildiÄŸinde eÅŸittir iminden sonra tırnak imi beklendi" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"“%sâ€, kapalı öge adı “%s†ardından gelebilecek bir karakter deÄŸil; izin " +"verilen karakter ise “>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "“%s†ögesi kapatılmış, hiçbir öge ÅŸu anda açık deÄŸil" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "“%s†ögesi kapatılmış, ancak “%s†şu an açık olan ögedir" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Belge boÅŸ veya yalnızca boÅŸluk karakteri içeriyor" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "" +"Belge, açık açı parantezi “<†iminden hemen sonra beklenmedik biçimde " +"sonlandı" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Belge, ögeleri hala açıkken beklenmedik biçimde sonlandı - son açılan öge: " +"“%sâ€" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Belge beklenmedik biçimde sonlandı, etiketi bitiren kapalı açı parantezi ile " +"biten <%s/> beklendi" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Belge bir öge adının içinde beklenmedik biçimde sonlandı" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Belge bir öznitelik adı içinde beklenmedik biçimde sonlandı" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Belge bir öge-açma etiketi içinde beklenmedik biçimde sonlandı." + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Belge öznitelik adını takip eden eÅŸittir iminden sonra beklenmedik biçimde " +"sonlandı; öznitelik deÄŸeri yok" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Belge bir öznitelik deÄŸeri içinde iken beklenmedik biçimde sonlandı" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "" +"Belge, “%s†ögesinin kapatma etiketi içinde beklenmedik biçimde sonlandı" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Belge, açık olmayan bir öge için kapatma etiketi içinde beklenmedik biçimde " +"sonlandı" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Belge bir yorum veya iÅŸlem talimatı içindeyken beklenmedik biçimde sonlandı" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[SEÇENEK…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Yardım Seçenekleri:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Yardım seçeneklerini göster" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Tüm yardım seçeneklerini göster" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Uygulama Seçenekleri:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Seçenekler:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "%2$s için tamsayı deÄŸeri “%1$s†ayrıştırılamıyor" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "%2$s için tamsayı deÄŸeri “%1$s†aralık dışında" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "%2$s için double deÄŸeri “%1$s†ayrıştırılamıyor" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "%2$s için double deÄŸeri “%1$s†aralık dışında" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "%s seçeneÄŸi iÅŸlenirken hata" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "%s için argüman eksik" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Bilinmeyen seçenek %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "bozuk nesne" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "iç hata ya da bozuk nesne" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "yetersiz bellek" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "geri takip sınırına ulaşıldı" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "doku (pattern), kısmi eÅŸleme için desteklenmeyen ögeler içeriyor" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "iç hata" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "koÅŸul olarak geri referanslar kısmi eÅŸleme için desteklenmiyor" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "iç içe yineleme sınırına ulaşıldı" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "yeni satır imlerinin geçersiz birleÅŸtirmesi" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "geçersiz ofset" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "kısa utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "yineleme döngüsü" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "bilinmeyen hata" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ desenin sonunda" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c desenin sonunda" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "\\ imini takiben anlaşılamayan karakter" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "sayılar {} niceliÄŸi içerisinde sıra dışı" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "sayılar {} niceliÄŸi içerisinde çok büyük" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "karakter sınıfı için eksik sonlanan ]" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "karakter sınıfında geçersiz dizi" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "karakter sınıfında sıra dışı kapsam" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "yinelenecek bir ÅŸey yok" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "beklenmeyen yineleme" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "(? ya da (?- sonrası tanınmayan karakter" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX adlandırılmış sınıflar yalnızca bir sınıf içinde desteklenir" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "eksik sonlandıran )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "var olmayan alt desene referans" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "açıklama sonrası eksik )" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "düzenli ifade çok uzun" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "bellek alma baÅŸarısız oldu" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr "( olmadan )" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "kod akış taÅŸması" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "(?< sonrası tanımlanmayan karakter" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "geribakma iddiası sabit uzunlukta deÄŸil" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "(?( sonrası bozuk rakam ya da ad" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "koÅŸul kümesi ikiden daha çok dal içeriyor" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "(?( sonrası ifade beklendi" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R ya da (?[+-]basamakları ) ile takip etmelidir" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "bilinmeyen POSIX sınıf adı" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "POSIX karşılaÅŸtırma ögeleri desteklenmiyor" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} dizisi içerisinde karakter deÄŸeri çok büyük" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "geçersiz koÅŸul (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C geriye bakma iddiası içerisinde izin verilmiyor" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "kaçış karakterleri \\L, \\l, \\N{ad}, \\U ve \\u desteklenmiyor" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "yinelemeli çaÄŸrı sonsuz döngü yapamadı" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "(?P sonrası tanımlanmayan karakter" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "alt desen adı içerisinde eksik sonlandırıcı" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "iki adlı alt desenler aynı ada sahip" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "bozulmuÅŸ \\P ya da \\p dizisi" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "\\P ya da \\p sonrası bilinmeyen özellik adı" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "alt desen adı çok uzun (en çok 32 karakter)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "çok fazla adlandırılmış alt desen (en çok 10.000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "sekizlik deÄŸer \\377’den daha büyük" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "derleme çalışma alanı kaplandı" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "önceden denetlenmiÅŸ referanslı alt desen bulunamadı" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE kümesi birden çok dal içeriyor" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "kararsız NEWLINE seçenekleri" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g bir parantezli ad ya da tercihten parentezli sıfır olmayan sayı " +"tarafından takip edilmiyor" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "numaralandırılmış kaynak sıfır olmamalıdır" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "(*ACCEPT), (*FAIL) ya da (*COMMIT) için bir argümana izin verilmez" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "(*VERB) tanınamadı" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "sayı çok büyük" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "(?& den sonra eksik alt desen adı" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "(?+ den sonra sayı beklendi" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] JavaScript uyumluluk kipinde geçersiz bir veri karakteri" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "aynı sayıya izin verilmeyen alt desenler için farklı adlar" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) bir argüman almalı" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c karakteri ASCII karakterleri tarafından takip edilmelidir" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k bir parantezli ad ya da tercihten parentezli sıfır olmayan sayı " +"tarafından takip edilmiyor" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N bir sınıfta desteklenmez" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "çok fazla yönlendirme kaynağı" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK), (*PRUNE), (*SKIP) ya da (*THEN) içinde ad çok uzun" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... dizisindeki karakter deÄŸeri çok büyük" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Düzenli ifade %s eÅŸleÅŸirken hata: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE kütüphanesi UTF8 desteÄŸi olmadan derlenmiÅŸ" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE kütüphanesi UTF8 özellikleri desteÄŸi olmadan derlenmiÅŸ" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE kütüphanesi uyuÅŸmayan seçenekler ile derlenmiÅŸ" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Düzenli ifade %s eniyilemesinde (optimization) hata: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Düzenli ifade %s derlenirken karakter %d hatalı: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "onaltılı rakam ya da “}†beklendi" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "onaltılı rakam beklendi" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "simgesel referansda eksik “<â€" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "tamamlanmamış simgesel referans" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "sıfır-uzunlukta simgesel referans" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "rakam beklendi" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "geçersiz simgesel referans" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "son “\\†kayıp" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "geçersiz çıkış dizisi" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "Yerine koyma metni “%s†iÅŸlenirken karakter %lu hatalı: %s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "Alıntılı metin tırnak imi ile baÅŸlamıyor" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Komut satırında veya diÄŸer kabuk alıntısı metinde eÅŸlenmemiÅŸ tırnak imi" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "Metin “\\†karakterinden hemen sonra bitti. (Metin: “%sâ€)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "%c için eÅŸleÅŸen alıntı bulunmadan metin bitti. (Metin: “%sâ€)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "Metin boÅŸtu (veya yalnızca boÅŸluk içeriyordu)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Alt süreçten bilgi okuma baÅŸarısızlığı (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Alt süreçten bilgi okurken beklenmeyen hata oluÅŸtu (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() (%s) içinde beklenmeyen hata" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Alt iÅŸlem %ld kodu ile sonlandı" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Alt iÅŸlem, %ld sinyali ile sonlandı" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Alt iÅŸlem %ld sinyali ile durduruldu" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Alt iÅŸlem anormal bir biçimde sonlandı" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Alt süreç borusundan okuma baÅŸarısızlığı (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "“%s†alt süreci üretme baÅŸarısız (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Çatallama baÅŸarısızlığı (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "“%s†dizinine deÄŸiÅŸtirme baÅŸarısızlığı (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "“%s†alt süreci çalıştırılırken hata oluÅŸtu (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Dosya tanımlayıcıyı yeniden eÅŸlemek için dosya açılamadı (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Alt süreç için dosya tanımlayıcı çoÄŸaltılamadı (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Alt süreç çatallanamadı (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Alt süreç için dosya tanımlayıcının kapatılması baÅŸarısız (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Alt süreç “%s†çalıştırılırken bilinmeyen hata oluÅŸtu" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Alt süreç borusundan yeterli bilgi okunamadı (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Alt süreçten bilgi okuma baÅŸarısızlığı" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Alt süreç yürütme baÅŸarısızlığı (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Alt süreç dup() yapılamadı (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Geçersiz program adı: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d konumunda argüman vektörü içinde geçersiz dizgi: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Çevre içinde geçersiz dizgi: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Geçersiz çalışma dizini: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Yardımcı program (%s) çalıştırılamadı" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Alt süreçten bilgi okurken g_io_channel_win32_poll() iÅŸleminde beklenmeyen " +"hata" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "BoÅŸ dizge bir sayı deÄŸildir" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%s†iÅŸaretli bir sayı deÄŸil" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "“%s†sayısı sınırların dışındadır [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%s†iÅŸaretsiz bir sayı deÄŸil" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "URI’de geçersiz %-kodlama" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "URI’de kural dışı karakter" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "URI’de UTF-8 olmayan karakterler" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "URI’de geçersiz IPv6 adresi ‘%.*s’" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "URI’de kural dışı kodlanmış IP adresi ‘%.*s’" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "URI’de kural dışı uluslararasılaÅŸtırılmış ana makine adı ‘%.*s’" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "URI’deki ‘%.*s’ baÄŸlantı noktası ayrıştırılamadı" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "URI’deki ‘%.*s’ baÄŸlantı noktası kapsam dışında" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "‘%s’ URI’si mutlak URI deÄŸil" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "‘%s’ URI’sinin ana makine bileÅŸeni yok" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI mutlak deÄŸil ve temel URI saÄŸlanmamış" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "‘=’ ve parametre deÄŸeri eksik" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Bellek ayrılamadı" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Karakter UTF-8 için sınırlarının dışında" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Dönüşüm girdisi içinde geçersiz dizi" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Karakter UTF-16 sınırlarının dışında" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u bayt" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u bit" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s bayt" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s bit" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "/var/lib/dbus/makine-kimliÄŸi veya /etc/makine-kimliÄŸi konumuna " +#~ "yüklenemiyor: " + +#~ msgid "Unknown error on connect" +#~ msgstr "BaÄŸlanırken bilinmeyen bir hata" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "“%s†adresinde hata — grup özniteliÄŸi hatalı oluÅŸturulmuÅŸ" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s, %s konumunda baÄŸlandı\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr "; bu anahtar için üzerine yazma göz ardı ediliyor.\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr " ve --strict belirtilmiÅŸ; çıkılıyor.\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "Bu anahtar için üzerine yazma göz ardı ediliyor.\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "hiçbir ÅŸey yapılmıyor.\n" + +#~ msgid "No such interface '%s'" +#~ msgstr "'%s' gibi bir arayüz yok" + +#~ msgid "No such method '%s'" +#~ msgstr "'%s' gibi bir yöntem yok" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "DBUS_STARTER_BUS_TYPE ortam deÄŸiÅŸkeninden veri yolu adresi saptanamıyor - " +#~ "bilinmeyen deÄŸer '%s'" + +#~ msgid "[ARGS...]" +#~ msgstr "[DEĞİŞKENLER...]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "Geçici dosya oluÅŸturulamadı: %s" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "İleti %d dosya tanımlayıcılarına sahip fakat baÅŸlık alanı %d dosya " +#~ "tanımlayıcılarını gösterir" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "Hata: Nesne yolu belirtilmedi.\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "Hata: sinyal belirtilmedi.\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "Hata: sinyal tam nitelikli ad olmalıdır.\n" + +#, fuzzy +#~| msgid "Error setting extended attribute '%s': %s" +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "GeniÅŸletilmiÅŸ öznitelik '%s' atanırken hata: %s" + +#, fuzzy +#~| msgid "Error launching application: %s" +#~ msgid "Error mounting location: %s\n" +#~ msgstr "Uygulama baÅŸlatılırken hata: %s" + +#, fuzzy +#~| msgid "Error connecting: %s\n" +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "BaÄŸlanırken hata: %s\n" + +#, fuzzy +#~| msgid "Error closing unix: %s" +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "Unix kapatılırken hata: %s" + +#, fuzzy +#~| msgid "Error setting owner: %s" +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "Sahip atanırken hata: %s" + +#, fuzzy +#~| msgid "Error connecting: %s\n" +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "BaÄŸlanırken hata: %s\n" + +#, fuzzy +#~| msgid "Error setting extended attribute '%s': %s" +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "GeniÅŸletilmiÅŸ öznitelik '%s' atanırken hata: %s" + +#~ msgid "Error renaming file: %s" +#~ msgstr "Dosya yeniden adlandırılırken hata: %s" + +#~ msgid "Error opening file: %s" +#~ msgstr "Dosya açılırken hata: %s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "Dizin oluÅŸturulurken hata: %s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "'%s' dosyası okunurken hata: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "eÅŸleÅŸtirme deÄŸiÅŸimleri win32 üzerinde desteklenmiyor" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "EÅŸleÅŸtirme oluÅŸturulması win32 üzerinde desteklenmiyor" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Öntanımlı yerel dizin izleme tipi bulunamadı" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Anahtar dosyasında '%s' anahtarı yok" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "'%s' dosyası yazma için açılamadı: fdopen() baÅŸarısızlığı: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Dosya '%s' yazılamadı: fflush() baÅŸarısız: %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "'%s' dosyası kapatılamadı: fclose() baÅŸarısızlığı: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "boÅŸ alt dizgiler için çalışma alanı sınırına ulaşıldı" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "büyük küçük harf deÄŸiÅŸtiren kaçış karakterleri (\\l, \\L, \\u, \\U) " +#~ "burada kullanılamaz" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "bir DEFINE grubunu tekrarlamaya izin verilmiyor" + +#~ msgid "File is empty" +#~ msgstr "Dosya boÅŸ" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "Anahtar dosyası deÄŸeri yorumlanamayan '%s' deÄŸerini içeriyor." + +#, fuzzy +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "" +#~ "'%s' komut satırın meydana getirirken program olaÄŸan dışı sonlandı: %s" + +#, fuzzy +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "Komut satırı '%s', sıfır olmayan bir durum ile kapandı %d: %s" + +#, fuzzy +#~ msgid "Error statting directory '%s': %s" +#~ msgstr "'%s' dizininin bilgilerini almada (stat) hata: %s" + +#~ msgid "This option will be removed soon." +#~ msgstr "Bu ÅŸeçenek yakında kaldırılacak." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "'%s' dosyası durumlandırılırken hata: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' için servis kaydı yok" + +#~ msgid "Error connecting: " +#~ msgstr "BaÄŸlarken hata:" + +#~ msgid "Error connecting: %s" +#~ msgstr "BaÄŸlarken hata: %s" + +#, fuzzy +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "SOCKSv4 gerçeklemesi, kullanıcı adını %i karakterle sınırlandırıyor" + +#, fuzzy +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKSv4 gerçeklemesi, makine adını %i karakterle sınırlandırıyor" + +#, fuzzy +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "SO_PASSCRED'in soket için etkin olup olmadığı kontrol edilirken " +#~ "beklenmeyen seçenek uzunluÄŸu. %d bayt bekleniyordu, fakat %d bayt bulundu." + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Unix'den okurken hata: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Unix'e yazılırken hata: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "öö" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "ös" + +#, fuzzy +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "Dönüş deÄŸerinin türü yanlış, '%s' mevcut, fakat '%s' bekleniyordu" + +#, fuzzy +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "%2$s türünden %1$s özelliÄŸi ayarlanmaya çalışılıyor, fakat beklenen " +#~ "arayüze göre tür %3$s" + +#, fuzzy +#~| msgid "failed to get memory" +#~ msgid "Failed to set value\n" +#~ msgstr "ANAHTAR'ın deÄŸerini DEÄžER'e ata" + +#, fuzzy +#~ msgid "Do not give error for empty directory" +#~ msgstr "Dizin dizin üzerine taşınamıyor" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Dönüşüm girdisi içinde geçersiz dizi" + +#~ msgid "Reached maximum data array limit" +#~ msgstr "Azami veri dizisi sınırına ulaşıldı" + +#~ msgid "do not hide entries" +#~ msgstr "giriÅŸleri saklama" diff --git a/po/tt.po b/po/tt.po new file mode 100644 index 0000000..9448f65 --- /dev/null +++ b/po/tt.po @@ -0,0 +1,3751 @@ +# Tatarish translation +# Albert Fazlí , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: libgnome\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2005-11-09 13:19+0300\n" +"Last-Translator: Albert Fazlí \n" +"Language-Team: Tatarish \n" +"Language: tt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "'%s' biremennän uqıp bulmadı: %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "'%s' -› '%s' digän bilge äyländerü totılmí" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "'%s' -› '%s' äyländergeçen açıp bulmadı" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "'%s' digän cirle birem URI'sında '#' bilgese bula almí" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "'%s' digän URI yaraqsız" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "'%s' digän URI'nıñ host adı yaraqsız" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "'%s' digän yul töptän tügel" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Host adı yaraqsız" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %d %b %Y %T" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d.%m.%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "ЯнварÑ" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "ФевралÑ" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "Марта" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "ÐпрелÑ" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "МаÑ" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "ИюнÑ" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "ИюлÑ" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Янв" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Фев" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Мар" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Ðпр" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Май" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Июн" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Июл" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Дышәмбе" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Сишәмбе" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Чәршәәмбе" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Пәнҗешмбе" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Җомга" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Шимбә" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Якшәмбе" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Дыш" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Сиш" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Чәрш" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Пәнҗ" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Җом" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Шим" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Якш" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "'%s' törgägen açıp bulmadı: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "'%s' biremennän uqıp bulmadı: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "'%s' biremen açıp bulmadı: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "'%s' birem üzençälegen belep bulmadı: fstat() uzmadı: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "'%s' biremen açıp bulmadı: fdopen() uzmadı: %s" + +#: ../glib/gfileutils.c:862 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "'%s' birem adın '%s' itep üzgärtep bulmadı: g_rename() uzmadı: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "'%s' biremen yasap bulmadı: %s" + +#: ../glib/gfileutils.c:918 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Yazu öçen '%s' biremen açıp bulmadı: fdopen() uzmadı: %s" + +#: ../glib/gfileutils.c:943 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "'%s' biremen yazıp bulmadı: fwrite() uzmadı: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "'%s' biremen yazıp bulmadı: fwrite() uzmadı: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "'%s' biremen yazıp bulmadı: fwrite() uzmadı: %s" + +#: ../glib/gfileutils.c:1030 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "'%s' biremen yabıp bulmadı: fclose() uzmadı: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "Barlıqtağı '%s' biremen beterep bulmadı: g_unlink() uzmadı: %s" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "'%s' ürçetmäse yaraqsız, eçendä '%s' bula almí" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "'%s' ürçetmäneñ azağında XXXXXX tügel" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "" + +#: ../glib/giochannel.c:1408 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "'%s' -› '%s' äyländergeçen açıp bulmadı: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "'%s' biremen açıp bulmadı: open() uzmadı: %s" + +#: ../glib/gmappedfile.c:229 +#, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "%d. yulnıñ %d. bilgedä xata: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Yazmanıñ UTF-8 bilgelämäse yaraqsız" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "%d. yulda xata: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" + +#: ../glib/gmarkup.c:722 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "İstälek eçtälege yä buÅŸ, yä buÅŸlıq bilgelärennän genä tora" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +msgid "invalid escape sequence in character class" +msgstr "" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "%d. yulnıñ %d. bilgedä xata: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:444 +#, c-format +msgid "Invalid program name: %s" +msgstr "Yazılım adı yaraqsız: %s" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Tirä-yaqta yaraqsız yazma bar: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, c-format +msgid "Invalid working directory: %s" +msgstr "EÅŸ törgäge yaraqsız: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Yärdämçe yazılım eÅŸlätep bulmadı (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "UTF-8 çigennän çıqqan bilge" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "UTF-16 çigennän çıqqan bilge" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Totılu:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[KÖYLÄMÄ...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Yärdäm Köylämäse:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Yärdäm köylämäsen kürsätü" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Yärdäm köylämäsen kürsätü" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Yazılım Köylämäläre:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%2$s öçen '%1$s' digän tulısan bäyäse çiktän uzdı" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, fuzzy, c-format +msgid "Double value '%s' for %s out of range" +msgstr "%2$s öçen '%1$s' digän tulısan bäyäse çiktän uzdı" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "%s öçen köylämä birelmäde" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Bilgesez %s atlı köylämä" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Ğädäti birem tügel" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Birem buÅŸ ikän" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "Yazılım adı yaraqsız: %s" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Açqıç bireme törkem belän baÅŸlanmí" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "Yazılım adı yaraqsız: %s" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Açqıç biremendä '%s' digän totılmaÄŸan bilgelämä" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Açqıç biremendä '%s' törkeme yuq" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Açqıç biremendä '%s' açqıçı yuq" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Açqıç biremendäge '%2$s' törkemendä '%1$s' açqıçı yuq" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "'%s' digän bäyäsen san itep tanıp bulmí." + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "'%s' digän tulısan bäyäse çiktän çıqtı" + +#: ../glib/gkeyfile.c:3919 +#, fuzzy, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "'%s' digän bäyäsen san itep tanıp bulmí." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "'%s' digän bäyäsen yuqbar itep tanıp bulmí." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +msgid "Incomplete multibyte sequence in input" +msgstr "" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "Bilgesez %s atlı köylämä" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Bilgesez %s atlı köylämä" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "'%s' törgägen açıp bulmadı: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "'%s' törgägen açıp bulmadı: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +msgid "Abstract name space not supported" +msgstr "" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "%d. yulda xata: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "" + +#: ../gio/gdbus-tool.c:646 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "'%s' törgägen açıp bulmadı: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +msgid "empty names are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Yazılım adı yaraqsız: %s" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "Host adı yaraqsız" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "'%s' biremen yasap bulmadı: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "'%s' biremen yasap bulmadı: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "'%s' biremen yasap bulmadı: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "'%s' törgägen açıp bulmadı: %s" + +#: ../gio/glocalfile.c:2162 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "'%s' törgägen açıp bulmadı: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "%d. yulda xata: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +#, fuzzy +msgid "Target file is not a regular file" +msgstr "Ğädäti birem tügel" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Yazılım adı yaraqsız: %s" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Bilgesez %s atlı köylämä" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "'%s' biremen yasap bulmadı: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "Birem ısulın üzgärtep bulmadı: waitpid() uzmadı: %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "'%s' biremen yasap bulmadı: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "'%s' biremen yasap bulmadı: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "'%s' -› '%s' digän bilge äyländerü totılmí" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "%d. yulda xata: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Äyländergändä xata çıqtı: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "'%s' biremen uqığanda xata: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Host adı yaraqsız" + +#, fuzzy +#~ msgid "[FILE...]" +#~ msgstr "[KÖYLÄMÄ...]" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Yazmanıñ UTF-8 bilgelämäse yaraqsız" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Yazmanıñ UTF-8 bilgelämäse yaraqsız" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "'%s' digän URI'nıñ host adı yaraqsız" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "'%s' digän URI'nıñ host adı yaraqsız" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "'%s' biremen uqığanda xata: %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Äyländergändä xata çıqtı: %s" + +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Birem ısulın üzgärtep bulmadı: fork() uzmadı: %s" + +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Birem ısulın üzgärtep bulmadı: chmod() uzmadı: %s" + +#~ msgid "Could not change file mode: Child terminated by signal: %s" +#~ msgstr "Birem ısulın üzgärtep bulmadı: Balanı ımlaw özderde: %s" + +#~ msgid "Could not change file mode: Child terminated abnormally" +#~ msgstr "Birem ısulın üzgärtep bulmadı: Balanı özü tieÅŸleçä bulmadı" diff --git a/po/ug.po b/po/ug.po new file mode 100644 index 0000000..4f796a9 --- /dev/null +++ b/po/ug.po @@ -0,0 +1,4389 @@ +# Uyghur translation for glib. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Gheyret Kenji,2010. +# Sahran , 2010. +# Zeper , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-03-13 11:48+0000\n" +"PO-Revision-Date: 2013-03-17 13:51+0900\n" +"Last-Translator: Gheyret Kenji \n" +"Language-Team: Uyghur Computer Science Association \n" +"Language: ug\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../gio/gbufferedinputstream.c:427 ../gio/gbufferedinputstream.c:506 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:377 +#: ../gio/ginputstream.c:615 ../gio/ginputstream.c:833 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:732 +#: ../gio/gpollableinputstream.c:207 ../gio/gpollableoutputstream.c:208 +#, c-format +msgid "Too large count value passed to %s" +msgstr "%s ئۇزاتقان ساناق سان قىممەت بەك Ú†ÙˆÚ­" + +#: ../gio/gbufferedinputstream.c:899 ../gio/gbufferedoutputstream.c:581 +#: ../gio/gdataoutputstream.c:568 +msgid "Seek not supported on base stream" +msgstr "ئاساسىي ئÛقىم يۆتكىلىش(Seek) نى قوللىمايدۇ" + +#: ../gio/gbufferedinputstream.c:945 +msgid "Cannot truncate GBufferedInputStream" +msgstr "ئÛقىم GBufferedInputStream نى قىسقارتقىلى بولمىدى" + +#: ../gio/gbufferedinputstream.c:990 ../gio/ginputstream.c:1023 +#: ../gio/giostream.c:291 ../gio/goutputstream.c:1334 +msgid "Stream is already closed" +msgstr "ئÛقىم ئاللىقاچان تاقالغان" + +#: ../gio/gbufferedoutputstream.c:618 ../gio/gdataoutputstream.c:598 +msgid "Truncate not supported on base stream" +msgstr "ئاساسىي ئÛقىم قىسقارتىش(Truncate) نى قوللىمايدۇ" + +#: ../gio/gcancellable.c:318 ../gio/gdbusconnection.c:1885 +#: ../gio/gdbusconnection.c:1977 ../gio/gdbusprivate.c:1421 +#: ../gio/glocalfile.c:2172 ../gio/gsimpleasyncresult.c:843 +#: ../gio/gsimpleasyncresult.c:869 +#, c-format +msgid "Operation was cancelled" +msgstr "مەشغۇلات بىكار قىلىندى" + +#: ../gio/gcharsetconverter.c:262 +msgid "Invalid object, not initialized" +msgstr "ئىناۋەتسىز Ù†Û•Ú­. دەسلەپلەشتۈرۈلمىگەن" + +#: ../gio/gcharsetconverter.c:283 ../gio/gcharsetconverter.c:311 +msgid "Incomplete multibyte sequence in input" +msgstr "كىرگۈزۈشتە تاماملانمىغان ÙƒÛ†Ù¾ بايتلىق ھەرپ قاتارى بار" + +#: ../gio/gcharsetconverter.c:317 ../gio/gcharsetconverter.c:326 +msgid "Not enough space in destination" +msgstr "نىشاندا ÙŠÛØªÛ•رلىك بوشلۇق يوق" + +#: ../gio/gcharsetconverter.c:344 ../gio/gdatainputstream.c:854 +#: ../gio/gdatainputstream.c:1264 ../glib/gconvert.c:764 +#: ../glib/gconvert.c:1156 ../glib/giochannel.c:1586 ../glib/giochannel.c:1628 +#: ../glib/giochannel.c:2472 ../glib/gutf8.c:833 ../glib/gutf8.c:1284 +msgid "Invalid byte sequence in conversion input" +msgstr "ئايلاندۇرۇپ كىرگۈزۈشتە ئىناۋەتسىز بايت قاتارى كۆرۈلدى" + +#: ../gio/gcharsetconverter.c:349 ../glib/gconvert.c:772 +#: ../glib/gconvert.c:1081 ../glib/giochannel.c:1593 ../glib/giochannel.c:2484 +#, c-format +msgid "Error during conversion: %s" +msgstr "ئايلاندۇرۇۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gcharsetconverter.c:446 ../gio/gsocket.c:991 +msgid "Cancellable initialization not supported" +msgstr "Ùورماتلاشنى ئىناۋەتسىز قىلىشقا بولمايدۇ" + +#: ../gio/gcharsetconverter.c:457 ../glib/gconvert.c:564 +#: ../glib/gconvert.c:642 ../glib/giochannel.c:1414 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "ھەرپ بەلگە توپلىمى ‹%s› دىن ‹%s› غا ئايلاندۇرۇشنى قوللىمايدۇ" + +#: ../gio/gcharsetconverter.c:461 ../glib/gconvert.c:568 +#: ../glib/gconvert.c:646 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "‹%s› دىن ‹%s› غا ئايلاندۇرغۇچنى ئاچالمايدۇ" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s تىپ" + +#: ../gio/gcontenttype-win32.c:162 +msgid "Unknown type" +msgstr "نامەلۇم تىپ" + +#: ../gio/gcontenttype-win32.c:163 +#, c-format +msgid "%s filetype" +msgstr "%s ھۆججەت تىپى" + +#: ../gio/gcredentials.c:264 ../gio/gcredentials.c:528 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials نى بۇ مەشغۇلات سىستÛمىسىدا ئىشلەتكىلى بولمايدۇ" + +#: ../gio/gcredentials.c:438 +msgid "There is no GCredentials support for your platform" +msgstr "سىستÛمىڭىز GCredentials نى قوللىمايدۇ" + +#: ../gio/gcredentials.c:480 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "مەزكۇر مەشغۇلات سىستÛمىسىدا GCredentials نىڭ ئىجرا كىملىكى يوق" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "ئويلىشىلمىغان بالدۇرلا ئاخىرلاشقان ئÛقىم بەلگىسى" + +#: ../gio/gdbusaddress.c:150 ../gio/gdbusaddress.c:238 +#: ../gio/gdbusaddress.c:319 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "«%2$s» Ø¦Ø§Ø¯Ø±ÛØ³ تۈرىدىكى قوللىمايدىغان كۇنۇپكا «%1$s»" + +#: ../gio/gdbusaddress.c:177 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "'%s' Ø¦Ø§Ø¯Ø±ÛØ³ ئىناۋەتسىز (بەلگىلەش زۆرۈر بولغان بىر يول، ۋاقىتلىق مۇندەرىجە ياكى ئابستراكت كۇنۇپكا)" + +#: ../gio/gdbusaddress.c:190 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³ تۈرى '%s' دىكى مەنىسى يوق كۇنۇپكا قىممەت جۈپىنىڭ بىرىكمىسى" + +#: ../gio/gdbusaddress.c:253 ../gio/gdbusaddress.c:334 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "'%s' Ø¦Ø§Ø¯Ø±ÛØ³ØªØ§ خاتالىق بار - Ø¦ÛØºÙ‰Ø² خاسلىق Ùورماتىدا خاتالىق بار" + +#: ../gio/gdbusaddress.c:264 ../gio/gdbusaddress.c:345 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "'%s' Ø¦Ø§Ø¯Ø±ÛØ³ØªØ§ خاتالىق بار - ئائىلە (family) خاسلىق Ùورماتىدا خاتالىق بار" + +#: ../gio/gdbusaddress.c:454 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³ ئÛÙ„ÛÙ…Ûنتى '%s' قوش Ú†Ûكىت (:) نى ئۆز ئىچىگە ئالمايدۇ" + +#: ../gio/gdbusaddress.c:475 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³ ئÛÙ„ÛÙ…Ûنتى «%3$s» دىكى %1$d - كۇنۇپكا/قىممەت جۈپى «%2$s»، تەڭلىك بەلگىسىنى ئۆز ئىچىگە ئالمايدۇ" + +#: ../gio/gdbusaddress.c:489 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "كۇنۇپكا/قىممەت جۈپى %dØŒ '%s'Ø¦Ø§Ø¯Ø±ÛØ³ ئÛÙ„ÛÙ…Ûنتى '%s' دىن Ù…Û•Ù†Û• ئۆزگەرتىشتە خاتالىق كۆرۈلدى" + +#: ../gio/gdbusaddress.c:567 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "'%s' Ø¦Ø§Ø¯Ø±ÛØ³ØªØ§ خاتالىق بار - unix يوللاشتا 'path' ياكى 'abstract' دىن بىرىنىڭ كۇنۇپكىسى تەڭشىلىشى لازىم." + +#: ../gio/gdbusaddress.c:603 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "'%s' Ø¦Ø§Ø¯Ø±ÛØ³ØªØ§ خاتالىق بار - ماشىنا خاسلىقى يوقالغان ياكى Ùورماتىدا خاتالىق بار" + +#: ../gio/gdbusaddress.c:617 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "'%s' Ø¦Ø§Ø¯Ø±ÛØ³ØªØ§ خاتالىق بار - Ø¦ÛØºÙ‰Ø² خاسلىقى يوقالغان ياكى Ùورماتىدا خاتالىق بار" + +#: ../gio/gdbusaddress.c:631 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "'%s' Ø¦Ø§Ø¯Ø±ÛØ³ØªØ§ خاتالىق بار - noncefile خاسلىقى يوقالغان ياكى Ùورماتىدا خاتالىق بار" + +#: ../gio/gdbusaddress.c:652 +msgid "Error auto-launching: " +msgstr "ئاپتوماتىك ئىجرا قىلىشتا خاتالىق كۆرۈلدى: " + +#: ../gio/gdbusaddress.c:660 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "«%2$s» Ø¦Ø§Ø¯Ø±ÛØ³Ù‚ا نىسبەتەن نامەلۇم ياكى قوللىمايدىغان يوللاش «%1$s»" + +#: ../gio/gdbusaddress.c:696 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "ۋاقتىنچە ھۆججەت '%s' نى ئاچقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusaddress.c:714 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "ۋاقتىنچە ھۆججەت '%s' نى ئوقۇغاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusaddress.c:723 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "ۋاقتىنچە ھۆججەت '%s' نى ئوقۇغاندا خاتالىق كۆرۈلدى، 16 بايتلىقنى ئويلىغان، %d غا Ø¦ÛØ±Ù‰Ø´ØªÙ‰" + +#: ../gio/gdbusaddress.c:741 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "ۋاقتىنچە ھۆججەت '%s' نىڭ مەزمۇنىنى ئÛقىمغا يازغاندا خاتالىق كۆرۈلدى:" + +#: ../gio/gdbusaddress.c:960 +msgid "The given address is empty" +msgstr "Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† Ø¦Ø§Ø¯Ø±ÛØ³ بوش" + +#: ../gio/gdbusaddress.c:1030 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "setuid ۋاقتىدا ئۇچۇر باش لىنىيىسىنى پەيدا قىلغىلى بولمايدۇ" + +#: ../gio/gdbusaddress.c:1037 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "ماشىنا كىملىكى يوق ئەھۋالدا ئۇچۇر غول لىنىيىسىدىن بىرنى قوزغىتالمايدۇ: " + +#: ../gio/gdbusaddress.c:1079 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "بۇيرۇق قۇرى '%s' نى قوزغاتقاندا خاتالىق كۆرۈلدى: " + +#: ../gio/gdbusaddress.c:1296 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "بۇ كۆزنەكنى Ø¦ÛØªÙ‰Ø´ ئۈچۈن خالىغان بىر ھەرپنى Ø¨ÛØ³Ù‰Ú­.\n" + +#: ../gio/gdbusaddress.c:1421 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "ئەڭگىمە dbus ئىجرا بولمىغان Û‹Û• ئاپتوماتىك قوزغىتىش مەغلۇپ بولدى" + +#: ../gio/gdbusaddress.c:1442 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "ئەڭگىمە غول لىنىيە Ø¦Ø§Ø¯Ø±ÛØ³Ù‰Ù†Ù‰ جەزملىيەلمىدى (بۇ مەشغۇلات سىستÛمىسىدا ØªÛØ®Ù‰ ئەمەلگە ئاشۇرۇلمىغان)" + +#: ../gio/gdbusaddress.c:1541 ../gio/gdbusconnection.c:6757 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "DBUS_STARTER_BUS_TYPE مۇھىت ئۆزگەرگۈچى مىقداردىن غول لىنىيە Ø¦Ø§Ø¯Ø±ÛØ³Ù‰Ù†Ù‰ جەزملىيەلمىدى - نامەلۇم قىممەت '%s'" + +#: ../gio/gdbusaddress.c:1550 ../gio/gdbusconnection.c:6766 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "غول لىنىيە Ø¦Ø§Ø¯Ø±ÛØ³Ù‰Ù†Ù‰ جەزملىيەلمىدى چۈنكى DBUS_STARTER_BUS_TYPE مۇھىت ئۆزگەرگۈچى مىقدار تەڭشەلمىگەن" + +#: ../gio/gdbusaddress.c:1560 +#, c-format +msgid "Unknown bus type %d" +msgstr "نامەلۇم غول لىنىيە تىپى %d" + +#: ../gio/gdbusauth.c:298 +msgid "Unexpected lack of content trying to read a line" +msgstr "بىر قۇرنى ئوقۇشنى سىنىغاندا ئويلىشىلمىغان ÙƒÛ•Ù… مەزمۇن" + +#: ../gio/gdbusauth.c:342 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "بىر قۇرنى (بىخەتەر) ئوقۇشنى سىنىغاندا ئويلىشىلمىغان ÙƒÛ•Ù… مەزمۇن" + +#: ../gio/gdbusauth.c:513 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "ئىشلەتكىلى بولىدىغان ھەممە دەلىللەش Ù…ÛØ®Ø§Ù†Ù‰Ø²Ù…ىنى ئىشلىتىپ بولدى(سىنالغان Ù‚ÛØªÙ‰Ù… سانى: %s) (ئىشلىتىلىشچان: %s)" + +#: ../gio/gdbusauth.c:1175 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "GDBusAuthObserver::authorize-authenticated-peer ئارقىلىق بىكار قىلىندى" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "مۇندەرىجە ‹%s› نىڭ ئۇچۇرىنى ئÛلىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "'%s' مۇندەرىجە ئىمتىيازى خاتالىقى. 0700 نى ئۈمىد قىلىدۇ ئەمما 0%o Ø¦ÛØ±Ù‰Ø´ØªÙ‰" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "مۇندەرىجە '%s' نى قۇرۇۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "ئاچقۇچ ھالقىسى '%s' نى ئوقۇۋاتقاندا خاتالىق كۆرۈلدى: " + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:719 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "%2$s دىكى ئاچقۇچ ھالقىسىنىڭ %1$d قۇرىدا Ùورماتقا ماس كەلمەيدىغان %3$s مەزمۇن بار" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:733 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "%2$s دىكى ئاچقۇچ ھالقىسىنىڭ %1$d قۇرىدىكى بىرىنچى بۇيرۇق تاختىسىدا Ùورماتقا ماس كەلمەيدىغان %3$s مەزمۇن بار" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:747 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "%2$s دىكى ئاچقۇچ ھالقىسىنىڭ %1$d قۇرىدىكى ئىككىنچى بۇيرۇق تاختىسىدا Ùورماتقا ماس كەلمەيدىغان %3$s مەزمۇن بار" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "'%2$s' دىكى ئاچقۇچ ھالقىسىدىن كىملىكى %1$d بولغان cookie نى تاپالمىدى" + +#: ../gio/gdbusauthmechanismsha1.c:537 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "ئۈنۈمىنى يوقاتقان Ù‚Û‡Ù„Û‡Ù¾ ھۆججىتى '%s' نى ئۆچۈرۈۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusauthmechanismsha1.c:569 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Ù‚Û‡Ù„Û‡Ù¾ ھۆججىتى '%s' نى قۇرۇۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusauthmechanismsha1.c:599 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Ù‚Û‡Ù„Û‡Ù¾ ھۆججىتى '%s' نى ÙŠÛپىۋاتقاندا (ئۇلانمىغان) خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Ù‚Û‡Ù„Û‡Ù¾ ھۆججەت '%s' نى ئۇلىنىشىنى بىكار قىلىشتا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusauthmechanismsha1.c:686 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "ئاچقۇچ ھالقىسى '%s' نى ئÛچىپ ÙŠÛØ²Ù‰Û‹Ø§ØªÙ‚اندا خاتالىق كۆرۈلدى: " + +#: ../gio/gdbusauthmechanismsha1.c:883 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(ئۇندىن باشقا، '%s' نىڭ قۇلۇپىنى بوشىتىش مەغلۇپ بولدى: %s) " + +#: ../gio/gdbusconnection.c:597 ../gio/gdbusconnection.c:2440 +msgid "The connection is closed" +msgstr "باغلىنىش تاقالدى" + +#: ../gio/gdbusconnection.c:1930 +msgid "Timeout was reached" +msgstr "مۆھلەتكە يەتتى" + +#: ../gio/gdbusconnection.c:2562 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Ø®ÛØ±Ù‰Ø¯Ø§Ø± تەرەپ باغلىنىشى قۇرغاندا قوللىمايدىغان بەلگىگە يولۇقتى" + +#: ../gio/gdbusconnection.c:4065 ../gio/gdbusconnection.c:4381 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "%s يولدىكى نەڭدە 'org.freedesktop.DBus.Properties' Ø¦ÛØºÙ‰Ø²Ù‰ يوق" + +#: ../gio/gdbusconnection.c:4136 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "'%s' خاسلىق تەڭشەشتە خاتالىق كۆرۈلدى: '%s' ئۈمىد قىلىنغان ئەمما '%s' غا Ø¦ÛØ±Ù‰Ø´ØªÙ‰" + +#: ../gio/gdbusconnection.c:4231 +#, c-format +msgid "No such property '%s'" +msgstr "'%s' بۇنداق خاسلىق يوق" + +#: ../gio/gdbusconnection.c:4243 +#, c-format +msgid "Property '%s' is not readable" +msgstr "'%s' خاسلىقنى ئوقۇغىلى بولمايدۇ" + +#: ../gio/gdbusconnection.c:4254 +#, c-format +msgid "Property '%s' is not writable" +msgstr "'%s' خاسلىقنى يازغىلى بولمايدۇ" + +#: ../gio/gdbusconnection.c:4324 ../gio/gdbusconnection.c:6200 +#, c-format +msgid "No such interface '%s'" +msgstr "'%s' بۇنداق ئارايۈز يوق" + +#: ../gio/gdbusconnection.c:4508 +msgid "No such interface" +msgstr "بۇنداق ئارايۈز يوق" + +#: ../gio/gdbusconnection.c:4726 ../gio/gdbusconnection.c:6706 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "%2$s يولدىكى نەڭدە «%1$s» غا ئوخشاش ئارايۈز يوق" + +#: ../gio/gdbusconnection.c:4781 +#, c-format +msgid "No such method '%s'" +msgstr "بۇنداق ئۇسۇل يوق '%s'" + +#: ../gio/gdbusconnection.c:4812 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "ئۇچۇر تىپى، '%s'ØŒ ئۈمىد قىلغان تىپ '%s' بىلەن ماس كەلمىدى" + +#: ../gio/gdbusconnection.c:5032 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "%2$s دىكى %1$s Ø¦ÛØºÙ‰Ø² نەڭدىن بىرنى چىقاردى" + +#: ../gio/gdbusconnection.c:5230 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "'%s' ئۇسۇل '%s' تىپنى قايتۇردى ئەمما ئۈمىد قىلىنغىنى '%s'" + +#: ../gio/gdbusconnection.c:6311 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "%3$s ئىمزالىق Ø¦ÛØºÙ‰Ø² %2$s دا %1$s ئۇسۇل مەۋجۇت ئەمەس" + +#: ../gio/gdbusconnection.c:6430 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "%s ئۈچۈن تارماق شاخچىدىن بىرنى چىقاردى" + +#: ../gio/gdbusmessage.c:1271 +msgid "type is INVALID" +msgstr "تىپى ئىناۋەتسىز" + +#: ../gio/gdbusmessage.c:1282 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL ئۇچۇرى: PATH ياكى MEMBER Ø¨ÛØ´Ù‰ سۆز بۆلىكى ÙƒÛ•Ù…" + +#: ../gio/gdbusmessage.c:1293 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN ئۇچۇرى: REPLY_SERIAL Ø¨ÛØ´Ù‰ سۆز بۆلىكى ÙƒÛ•Ù…" + +#: ../gio/gdbusmessage.c:1305 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "خاتالىق ئۇچۇرى: REPLY_SERIAL ياكى ERROR_NAME Ø¨ÛØ´Ù‰ سۆز بۆلىكى ÙƒÛ•Ù…" + +#: ../gio/gdbusmessage.c:1318 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "سىگنال ئۇچۇرى: PATH ØŒ INTERFACE ياكى MEMBER Ø¨ÛØ´Ù‰ سۆز بۆلىكى ÙƒÛ•Ù…" + +#: ../gio/gdbusmessage.c:1326 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "سىگنال ئۇچۇرى: PATH Ø¨ÛØ´Ù‰ سۆز بۆلىكى قالدۇرۇلغان قىممەتنى ئىشلىتىۋاتىدۇ/org/freedesktop/DBus/Local" + +#: ../gio/gdbusmessage.c:1334 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "سىگنال ئۇچۇرى: INTERFACE Ø¨ÛØ´Ù‰ سۆز بۆلىكى قالدۇرۇلغان قىممەتنى ئىشلىتىۋاتىدۇ org.freedesktop.DBus.Local" + +#: ../gio/gdbusmessage.c:1383 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "%lu بايتنى ئوقۇشنى ئۈمىد قىلغان ئەمما %lu نىلا ئوقۇدى" + +#: ../gio/gdbusmessage.c:1398 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "'%s' نىڭ كەينىدىن ئۈمىد قىلىنغىنى NUL بايت ئەمما Ø¦ÛØ±Ù‰Ø´ÙƒÙ‰Ù†Ù‰ بايت %d" + +#: ../gio/gdbusmessage.c:1417 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "ئىناۋەتلىك UTF-8 تÛكىستىنى ئۈمىد قىلغان ئەمما ھەرپ Ø¦ÛØºÙ‰Ø´Ù†Ù‰Ú­ %d ئورنىدا (ھەرپ تÛكىستنىڭ ئۇزۇنلۇقى %d) ئىناۋەتسىز تÛكىستكە يولۇقتى. بۇ نۇقتىنىڭ ئىناۋەتلىك UTF-8 تÛكىستى ئەسلىدە '%s'" + +#: ../gio/gdbusmessage.c:1619 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "تەھلىل قىلغان قىممەت '%s' ئىناۋەتلىك D-Bus Ù†Û•Ú­ يولى ئەمەس" + +#: ../gio/gdbusmessage.c:1643 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "تەھلىل قىلغان قىممەت '%s' ئىناۋەتلىك D-Bus ئىمزاسى ئەمەس" + +#: ../gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "ئۇزۇنلۇقى %u بايت بولغان سانلار قاتارىغا يولۇقتى، ئەڭ ئۇزۇن ئۇزۇنلۇقى 2<<26 بايت (64 Ù…Ûگابايت)" + +#: ../gio/gdbusmessage.c:1851 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "تەھلىل قىلغان شالغۇت خاسلىق قىممەت '%s' ئىناۋەتلىك D-Bus ئىمزاسى ئەمەس" + +#: ../gio/gdbusmessage.c:1875 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "D-Bus سىزىق Ùورماتىدا تىپ تÛكىستى '%s' نى ئىشلىتىپ قارشى تەرتىپلەشتۈرۈشتە GVariant قىلغاندا خاتالىق كۆرۈلدى" + +#: ../gio/gdbusmessage.c:2062 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "ئىناۋەتسىز تەرتىپ قىممىتى. 0x6c ('l') ياكى 0x42 ('B') نىڭ ئورنىغا 0x%02x قىممەت بايقالدى" + +#: ../gio/gdbusmessage.c:2075 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "ئىناۋەتسىز ئاساسىي ÙƒÛلىشىم نەشرى. 1 ئۈمىد قىلىنغان ئەمما %d بايقالدى" + +#: ../gio/gdbusmessage.c:2131 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "Ø¨ÛØ´Ù‰Ø¯Ø§ '%s' ئىمزاسى بار ئەمما ئۇچۇر گەۋدىسى بوش" + +#: ../gio/gdbusmessage.c:2145 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "'%s' يەشكەن قىممەت D-Bus ئىمزاسىنىڭ ئىناۋەتلىك قىممىتى ئەمەس (ئۇچۇر گەۋدىسىگە نىسبەتەن)" + +#: ../gio/gdbusmessage.c:2175 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "ئۇچۇردا ئىمزا Ø¨ÛØ´Ù‰ يوق ئەمما ئۇچۇر گەۋدىسى %u بايت" + +#: ../gio/gdbusmessage.c:2185 +msgid "Cannot deserialize message: " +msgstr "ئۇچۇرنى ÙŠÛØ´Û•لمىدى: " + +#: ../gio/gdbusmessage.c:2506 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "D-Bus سىزىق Ùورماتىدا تىپ تÛكىستى '%s' نى ئىشلىتىپ GVariant تەرتىپلەشتۈرۈشتە خاتالىق كۆرۈلدى" + +#: ../gio/gdbusmessage.c:2643 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "ئۇچۇردا %d ھۆججەت چۈشەندۈرۈش بەلگىسى بار ئەمما باش قىسمى %d ھۆججەت چۈشەندۈرۈشىنى كۆرسەتتى" + +#: ../gio/gdbusmessage.c:2651 +msgid "Cannot serialize message: " +msgstr "ئۇچۇرنى تەرتىپلەشتۈرەلمىدى: " + +#: ../gio/gdbusmessage.c:2695 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "ئۇچۇر گەۋدىسىدە ئىمزا '%s' بار ئەمما Ø¨ÛØ´Ù‰Ø¯Ø§ ئىمزا يوق" + +#: ../gio/gdbusmessage.c:2705 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "ئۇچۇر گەۋدىسىدە تىپ ئىمزا '%s'بار ئەمما Ø¨ÛØ´Ù‰Ø¯Ù‰ÙƒÙ‰ ئىمزا '%s'" + +#: ../gio/gdbusmessage.c:2721 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "ئۇچۇر گەۋدىسى بوش ئەمما Ø¨ÛØ´Ù‰Ø¯Ù‰ÙƒÙ‰ سۆز بۆلىكىدىكى ئىمزا '%s'" + +#: ../gio/gdbusmessage.c:3271 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "گەۋدە تىپى '%s' غا قايتقاندا خاتالىق كۆرۈلدى" + +#: ../gio/gdbusmessage.c:3279 +msgid "Error return with empty body" +msgstr "بوش گەۋدىگە قايتقاندا خاتالىق كۆرۈلدى" + +#: ../gio/gdbusprivate.c:2069 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "قاتتىق Ø¯ÛØªØ§Ù„ سەپلىكى(profile) نى ئالغىلى بولمىدى: %s" + +#: ../gio/gdbusprivate.c:2114 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "/var/lib/dbus/machine-id ياكى /etc/machine-id نى ئوقۇغىلى بولمىدى: " + +#: ../gio/gdbusproxy.c:1640 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "%s ئۈچۈن StartServiceByName نى چاقىرغاندا خاتالىق كۆرۈلدى: " + +#: ../gio/gdbusproxy.c:1663 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "StartServiceByName(\"%2$s\") ئۇسۇلىدىن تاسادىپىي جاۋاب %1$d غا Ø¦ÛØ±Ù‰Ø´ØªÙ‰" + +#: ../gio/gdbusproxy.c:2763 ../gio/gdbusproxy.c:2900 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "ئۇسۇلنى چاقىرالمايدۇ؛ ۋاكالەتچى ÙƒÛ†Ù¾ ئۇچرايدىغان ئىگىدارى يوق ئات، ئەمما ۋاكالەتچى G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START بەلگىسىنى ئىشلىتىپ قۇرىدۇ" + +#: ../gio/gdbusserver.c:709 +msgid "Abstract name space not supported" +msgstr "ئابستراكت ئات بوشلۇقىنى قوللىمايدۇ" + +#: ../gio/gdbusserver.c:796 +msgid "Cannot specify nonce file when creating a server" +msgstr "مۇلازىمەت قۇرغاندا ۋاقتىنچە ھۆججەتنى بەلگىلىيەلمەيدۇ" + +#: ../gio/gdbusserver.c:874 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "'%s' دىكى ۋاقتىنچە ھۆججەتنى يازغاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gdbusserver.c:1043 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "'%s' تÛكىستى ئىناۋەتلىك D-Bus GUID ئەمەس" + +#: ../gio/gdbusserver.c:1083 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "قوللىمايدىغان يوللاش '%s' نى تىڭشىيالمايدۇ" + +#: ../gio/gdbus-tool.c:92 +msgid "COMMAND" +msgstr "بۇيرۇق" + +#: ../gio/gdbus-tool.c:97 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "بۇيرۇقلار:\n" +" help مەزكۇر ئۇچۇرنى كۆرسىتىدۇ\n" +" introspect يىراقتىكى بىر Ù†Û•Ú­\n" +" monitor يىراقتىكى بىر نەڭنى كۆزىتىدۇ\n" +" call يىراقتىكى نەڭنىڭ بىر ئۇسۇلىنى چاقىرىدۇ\n" +" emit سىگنال تارقىتىدۇ\n" +"\n" +" \"%s COMMAND --help\" نى ئىشلىتىپ ھەر بىر بۇيرۇقنىڭ ياردىمىگە Ø¦ÛØ±Ù‰Ø´Ù‰Ø¯Û‡.\n" + +#: ../gio/gdbus-tool.c:166 ../gio/gdbus-tool.c:222 ../gio/gdbus-tool.c:294 +#: ../gio/gdbus-tool.c:318 ../gio/gdbus-tool.c:701 ../gio/gdbus-tool.c:1020 +#: ../gio/gdbus-tool.c:1453 +#, c-format +msgid "Error: %s\n" +msgstr "خاتالىق: %s\n" + +#: ../gio/gdbus-tool.c:177 ../gio/gdbus-tool.c:235 ../gio/gdbus-tool.c:1469 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "introspection XML نى ÙŠÛØ´Ù‰Ø´ØªÛ• خاتالىق كۆرۈلدى: %s\n" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to the system bus" +msgstr "سىستÛما باش لىنىيىسىگە باغلىنىدۇ" + +#: ../gio/gdbus-tool.c:353 +msgid "Connect to the session bus" +msgstr "ئەڭگىمە باش لىنىيىسىگە باغلىنىدۇ" + +#: ../gio/gdbus-tool.c:354 +msgid "Connect to given D-Bus address" +msgstr "Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† D-Bus Ø¦Ø§Ø¯Ø±ÛØ³Ù‚ا باغلىنىدۇ" + +#: ../gio/gdbus-tool.c:364 +msgid "Connection Endpoint Options:" +msgstr "باغلىنىشنىڭ ئاخىرقى نۇقتا تاللانمىسى:" + +#: ../gio/gdbus-tool.c:365 +msgid "Options specifying the connection endpoint" +msgstr "باغلىنىش ئاخىرقى نۇقتىسىنىڭ تاللانمىسى بەلگىلىنىدۇ" + +#: ../gio/gdbus-tool.c:387 +#, c-format +msgid "No connection endpoint specified" +msgstr "باغلىنىش ئاخىرقى نۇقتىسى بەلگىلەنمىگەن" + +#: ../gio/gdbus-tool.c:397 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "ÙƒÛ†Ù¾ باغلىنىش ئاخىرقى نۇقتىسى بەلگىلەندى" + +#: ../gio/gdbus-tool.c:467 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "ئاگاھلاندۇرۇش: ئۆزىنى تەكشۈرۈش سانلىق-مەلۇماتىغا ئاساسەن '%s' Ø¦ÛØºÙ‰Ø² مەۋجۇت ئەمەس\n" + +#: ../gio/gdbus-tool.c:476 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "ئاگاھلاندۇرۇش: ئۆزىنى تەكشۈرۈش سانلىق-مەلۇماتىغا ئاساسەن '%2$s' Ø¦ÛØºÙ‰Ø²Ø¯Ø§ %1$s ئۇسۇل مەۋجۇت ئەمەس\n" + +#: ../gio/gdbus-tool.c:538 +msgid "Optional destination for signal (unique name)" +msgstr "سىگنالنىڭ ئىختىيارى نىشانى(ئۆزگىچە ئات)" + +#: ../gio/gdbus-tool.c:539 +msgid "Object path to emit signal on" +msgstr "سىگنال تارقىتىدىغان نەڭنىڭ يولى" + +#: ../gio/gdbus-tool.c:540 +msgid "Signal and interface name" +msgstr "سىگنال Û‹Û• ئارايۈزنىڭ ئاتى" + +#: ../gio/gdbus-tool.c:572 +msgid "Emit a signal." +msgstr "سىگنال تارقىتىدۇ." + +#: ../gio/gdbus-tool.c:606 ../gio/gdbus-tool.c:832 ../gio/gdbus-tool.c:1559 +#: ../gio/gdbus-tool.c:1791 +#, c-format +msgid "Error connecting: %s\n" +msgstr "باغلىنىشتا خاتالىق كۆرۈلدى: %s\n" + +#: ../gio/gdbus-tool.c:618 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "خاتالىق: Ù†Û•Ú­ يولى بەلگىلەنمىگەن.\n" + +#: ../gio/gdbus-tool.c:623 ../gio/gdbus-tool.c:893 ../gio/gdbus-tool.c:1617 +#: ../gio/gdbus-tool.c:1850 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "خاتالىق: %s ئىناۋەتلىك Ù†Û•Ú­ يولى ئەمەس\n" + +#: ../gio/gdbus-tool.c:629 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "خاتالىق: سىگنال بەلگىلەنمىگەن.\n" + +#: ../gio/gdbus-tool.c:636 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "خاتالىق: سىگنال ئاتى چوقۇم تولۇق ئۆلچەملىك بولۇشى ÙƒÛØ±Û•Ùƒ.\n" + +#: ../gio/gdbus-tool.c:644 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "خاتالىق: %s ئىناۋەتلىك ئارايۈز ئاتى ئەمەس\n" + +#: ../gio/gdbus-tool.c:650 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "خاتالىق: %s ئىناۋەتلىك ئەزا ئاتى ئەمەس\n" + +#: ../gio/gdbus-tool.c:656 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "خاتالىق: %s ئىناۋەتلىك ئۆزگىچە باش لىنىيە ئاتى ئەمەس\n" + +#: ../gio/gdbus-tool.c:679 ../gio/gdbus-tool.c:992 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Ù¾Ø§Ø±Ø§Ù…ÛØªÙ‰Ø± %d تەھلىل قىلىۋاتقاندا خاتالىق كۆرۈلدى: %s\n" + +#: ../gio/gdbus-tool.c:708 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "باغلىنىشنى ئاقتۇرۇۋاتقاندا خاتالىق كۆرۈلدى: %s\n" + +#: ../gio/gdbus-tool.c:735 +msgid "Destination name to invoke method on" +msgstr "ئۇسۇلنىڭ نىشان ئاتىنى چاقىرىدۇ" + +#: ../gio/gdbus-tool.c:736 +msgid "Object path to invoke method on" +msgstr "ئۇسۇلنىڭ Ù†Û•Ú­ يولىنى چاقىرىدۇ" + +#: ../gio/gdbus-tool.c:737 +msgid "Method and interface name" +msgstr "ئۇسۇل Û‹Û• Ø¦ÛØºÙ‰Ø²Ù†Ù‰Ú­ ئاتى" + +#: ../gio/gdbus-tool.c:738 +msgid "Timeout in seconds" +msgstr "سÛكۇنتتا مۆھلەت توشىدۇ" + +#: ../gio/gdbus-tool.c:777 +msgid "Invoke a method on a remote object." +msgstr "يىراقتىكى نەڭدە ئۇسۇلدىن بىرنى چاقىرىدۇ." + +#: ../gio/gdbus-tool.c:852 ../gio/gdbus-tool.c:1578 ../gio/gdbus-tool.c:1810 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "خاتالىق: نىشان بەلگىلەنمىگەن\n" + +#: ../gio/gdbus-tool.c:873 ../gio/gdbus-tool.c:1597 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "خاتالىق: Ù†Û•Ú­ يولى بەلگىلەنمىگەن\n" + +#: ../gio/gdbus-tool.c:908 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "خاتالىق: Method ئاتى بەلگىلەنمىگەن\n" + +#: ../gio/gdbus-tool.c:919 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "خاتالىق: ئۇسۇل ئاتى '%s' ئىناۋەتسىز\n" + +#: ../gio/gdbus-tool.c:984 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "%2$s تىپنىڭ Ù¾Ø§Ø±Ø§Ù…ÛØªÙ‰Ø±Ù‰ %1$d نى تەھلىل قىلغاندا خاتالىق كۆرۈلدى: %3$s\n" + +#: ../gio/gdbus-tool.c:1416 +msgid "Destination name to introspect" +msgstr "ئۆزىنى تەكشۈرىدىغان نىشان ئات" + +#: ../gio/gdbus-tool.c:1417 +msgid "Object path to introspect" +msgstr "ئۆزىنى تەكشۈرىدىغان Ù†Û•Ú­ يولى" + +#: ../gio/gdbus-tool.c:1418 +msgid "Print XML" +msgstr "XML باس" + +#: ../gio/gdbus-tool.c:1419 +msgid "Introspect children" +msgstr "ئۆزىنى تەكشۈرىدىغان بالا" + +#: ../gio/gdbus-tool.c:1420 +msgid "Only print properties" +msgstr "Ø¨ÛØ³Ù‰Ø´ خاسلىقلىرىلا" + +#: ../gio/gdbus-tool.c:1511 +msgid "Introspect a remote object." +msgstr "ئۆزىنى تەكشۈرىدىغان يىراقتىكى Ù†Û•Ú­." + +#: ../gio/gdbus-tool.c:1709 +msgid "Destination name to monitor" +msgstr "كۆزىتىدىغان نىشاننىڭ ئاتى" + +#: ../gio/gdbus-tool.c:1710 +msgid "Object path to monitor" +msgstr "كۆزىتىدىغان نەڭنىڭ يولى" + +#: ../gio/gdbus-tool.c:1743 +msgid "Monitor a remote object." +msgstr "يىراقتىكى نەڭنى كۆزىتىدۇ." + +#: ../gio/gdesktopappinfo.c:625 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "ئاتسىز" + +#: ../gio/gdesktopappinfo.c:1038 +msgid "Desktop file didn't specify Exec field" +msgstr "ئۈستەلئۈستى ھۆججىتى Exec سۆز بۆلىكىنى بەلگىلىمىگەن" + +#: ../gio/gdesktopappinfo.c:1326 +msgid "Unable to find terminal required for application" +msgstr "قوللىنىشچان پروگرامما ئÛھتىياجلىق ØªÛØ±Ù…ىنالنى تاپالمايدۇ" + +#: ../gio/gdesktopappinfo.c:1628 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "ئىشلەتكۈچى قوللىنىشچان پروگرامما قىسقۇچى %s نى قۇرالمايدۇ: %s" + +#: ../gio/gdesktopappinfo.c:1632 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "ئىشلەتكۈچى MIME سەپلىمە قىسقۇچى %s نى قۇرالمايدۇ: %s" + +#: ../gio/gdesktopappinfo.c:1872 ../gio/gdesktopappinfo.c:1896 +msgid "Application information lacks an identifier" +msgstr "پروگرامما ئۇچۇرىدا كىملىك يوق" + +#: ../gio/gdesktopappinfo.c:2128 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "ئىشلەتكۈچى ئۈستەلئۈستى ھۆججەت %s نى قۇرالمايدۇ" + +#: ../gio/gdesktopappinfo.c:2252 +#, c-format +msgid "Custom definition for %s" +msgstr "%s ئۈچۈن ئۆزلەشتۈرۈلگەن بەلگىلەش" + +#: ../gio/gdrive.c:394 +msgid "drive doesn't implement eject" +msgstr "قوزغاتقۇچ قاڭقىتىش مەشغۇلاتىنى ئىشقا ئاشۇرالمىدى" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:472 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "قوزغاتقۇچ eject ياكى eject_with_operation نى ئىشقا ئاشۇرالمىدى" + +#: ../gio/gdrive.c:548 +msgid "drive doesn't implement polling for media" +msgstr "قوزغاتقۇچ ۋاسىتە نۆۋەتلەشتۈرۈشنى ئىشقا ئاشۇرالمىدى" + +#: ../gio/gdrive.c:753 +msgid "drive doesn't implement start" +msgstr "قوزغاتقۇچ start نى ئىشقا ئاشۇرالمىدى" + +#: ../gio/gdrive.c:855 +msgid "drive doesn't implement stop" +msgstr "قوزغاتقۇچ stop نى ئىشقا ئاشۇرالمىدى" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "TLS نى قوللاشنى ئىشلەتكىلى بولمايدۇ." + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "GEmblem كودلاشنىڭ %d نەشرىنى بىر تەرەپ قىلالمىدى" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem كودلاشتا ناتوغرا بەلگە سانى مەۋجۇت (%d)" + +#: ../gio/gemblemedicon.c:367 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "GEmblemedIcon كودلاشنىڭ %d نەشرىنى بىر تەرەپ قىلالمايدۇ" + +#: ../gio/gemblemedicon.c:377 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon كودلاشتا ناتوغرا بەلگە سانى (%d)" + +#: ../gio/gemblemedicon.c:400 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon ئۈچۈن بىر GEmblem ئۈمىد قىلىندى" + +#: ../gio/gfile.c:917 ../gio/gfile.c:1156 ../gio/gfile.c:1295 +#: ../gio/gfile.c:1535 ../gio/gfile.c:1590 ../gio/gfile.c:1648 +#: ../gio/gfile.c:1732 ../gio/gfile.c:1789 ../gio/gfile.c:1853 +#: ../gio/gfile.c:1908 ../gio/gfile.c:3468 ../gio/gfile.c:3523 +#: ../gio/gfile.c:3669 ../gio/gfile.c:3711 ../gio/gfile.c:4113 +#: ../gio/gfile.c:4525 ../gio/gfile.c:4610 ../gio/gfile.c:4700 +#: ../gio/gfile.c:4797 ../gio/gfile.c:4884 ../gio/gfile.c:4985 +#: ../gio/gfile.c:5258 ../gio/gfile.c:5536 ../gio/gfile.c:5590 +#: ../gio/gfile.c:7135 ../gio/gfile.c:7225 ../gio/gfile.c:7309 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "مەشغۇلاتنى قوللىمايدۇ" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1419 ../gio/glocalfile.c:1096 ../gio/glocalfile.c:1107 +#: ../gio/glocalfile.c:1120 +msgid "Containing mount does not exist" +msgstr "ئۆز ئىچىگە ئالغان ئÛگەرلەش مەۋجۇت ئەمەس" + +#: ../gio/gfile.c:2474 ../gio/glocalfile.c:2328 +msgid "Can't copy over directory" +msgstr "مۇندەرىجە ھالقىپ كۆچۈرەلمەيدۇ" + +#: ../gio/gfile.c:2534 +msgid "Can't copy directory over directory" +msgstr "مۇندەرىجىنى مۇندەرىجىگە كۆچۈرەلمىدى" + +#: ../gio/gfile.c:2542 ../gio/glocalfile.c:2337 +msgid "Target file exists" +msgstr "نىشان ھۆججەت مەۋجۇت" + +#: ../gio/gfile.c:2561 +msgid "Can't recursively copy directory" +msgstr "مۇندەرىجىنى قايتىلانما كۆچۈرەلمەيدۇ" + +#: ../gio/gfile.c:2825 +msgid "Splice not supported" +msgstr "جىپسىلاشنى قوللىمايدۇ" + +#: ../gio/gfile.c:2829 +#, c-format +msgid "Error splicing file: %s" +msgstr "ھۆججەت جىپسىلىغاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gfile.c:2960 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "ئÛگەرلەشلەر ئارىسىدا كۆچۈرۈش(reflink/clone) نى قوللىمايدۇ" + +#: ../gio/gfile.c:2964 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "كۆچۈرۈش(reflink/clone) نى قوللىمايدۇ ياكى ئىناۋەتسىز" + +#: ../gio/gfile.c:2969 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "كۆچۈرۈش(reflink/clone) نى قوللىمايدۇ ياكى ئىشلىمىدى" + +#: ../gio/gfile.c:3029 +msgid "Can't copy special file" +msgstr "ئالاھىدە ھۆججەتنى كۆچۈرەلمەيدۇ" + +#: ../gio/gfile.c:3659 +msgid "Invalid symlink value given" +msgstr "Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† بەلگە ئۇلىنىش قىممىتى ئىناۋەتسىز" + +#: ../gio/gfile.c:3819 +msgid "Trash not supported" +msgstr "ئەخلەتخانىنى قوللىمايدۇ" + +#: ../gio/gfile.c:3870 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "ھۆججەت ئاتىدا '%c' بولسا بولمايدۇ" + +#: ../gio/gfile.c:6258 ../gio/gvolume.c:365 +msgid "volume doesn't implement mount" +msgstr "دىسكىنى ئÛگەرلىگىلى بولمايدۇ" + +#: ../gio/gfile.c:6367 +msgid "No application is registered as handling this file" +msgstr "بۇ خىل ھۆججەتنى بىر تەرەپ قىلىش ئۈچۈن ئۈچۈن خەتلىگەن مۇناسىپ قوللىنىشچان پروگرامما يوق" + +#: ../gio/gfileenumerator.c:204 +msgid "Enumerator is closed" +msgstr "سانىغۇچ تاقالغان" + +#: ../gio/gfileenumerator.c:211 ../gio/gfileenumerator.c:270 +#: ../gio/gfileenumerator.c:367 ../gio/gfileenumerator.c:467 +msgid "File enumerator has outstanding operation" +msgstr "ھۆججەت سانىغۇچتا بىنورمال مەشغۇلات بار" + +#: ../gio/gfileenumerator.c:358 ../gio/gfileenumerator.c:458 +msgid "File enumerator is already closed" +msgstr "ھۆججەت سانىغۇچ تاقالغان" + +#: ../gio/gfileicon.c:237 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "GFileIcon كودلاشنىڭ نەشرى %d نى بىر تەرەپ قىلالمىدى" + +#: ../gio/gfileicon.c:247 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon غا كىرگۈزگەن سانلىق-مەلۇمات Ùورماتى خاتا" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:400 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:503 +msgid "Stream doesn't support query_info" +msgstr "ئÛقىم query_info نى قوللىمايدۇ" + +#: ../gio/gfileinputstream.c:331 ../gio/gfileiostream.c:383 +#: ../gio/gfileoutputstream.c:377 +msgid "Seek not supported on stream" +msgstr "ئÛقىم ئىزدەشنى قوللىمايدۇ" + +#: ../gio/gfileinputstream.c:375 +msgid "Truncate not allowed on input stream" +msgstr "كىرگۈزۈش ئÛقىمى ئۈزۈشنى قوللىمايدۇ" + +#: ../gio/gfileiostream.c:459 ../gio/gfileoutputstream.c:453 +msgid "Truncate not supported on stream" +msgstr "ئÛقىم ئۈزۈشنى قوللىمايدۇ" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "خاتا بەلگە سانى (%d)" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "خىل ئاتى %s نىڭ تىپى يوق" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "%s تىپ GIcon Ø¦ÛØºÙ‰Ø²Ù†Ù‰ ئەمەلگە ئاشۇرالمىدى" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "%s تىپ خىل ئەمەس" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "خاتا نەشر نومۇرى: %s" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "%s تىپ GIcon Ø¦ÛØºÙ‰Ø²Ù†Ù‰Ú­ from_tokens() ئۇسۇلىنى ئەمەلگە ئاشۇرالمىدى" + +#: ../gio/gicon.c:428 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "تەمىنلەنگەن سىنبەلگە كودلاش نەشرىنى بىر تەرەپ قىلالمىدى" + +#: ../gio/ginetaddressmask.c:184 +msgid "No address specified" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³ كۆرسىتىلمىگەن" + +#: ../gio/ginetaddressmask.c:192 +#, c-format +msgid "Length %u is too long for address" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³ ئۈچۈن %u بەك ئۇزۇن" + +#: ../gio/ginetaddressmask.c:225 +msgid "Address has bits set beyond prefix length" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³ØªØ§ ئالدى قوشۇلغۇچىنىڭ ئۇزۇنلۇقىدىن Ø¦ÛØ´Ù‰Ù¾ كەتكەن بىت بار" + +#: ../gio/ginetaddressmask.c:304 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "‹%s› نى IP Ø¦Ø§Ø¯Ø±ÛØ³ ماسكىسى دەپ قاراپ تەھلىل قىلغىلى بولمىدى" + +#: ../gio/ginetsocketaddress.c:206 ../gio/ginetsocketaddress.c:223 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "ئوقۇر Ø¦Ø§Ø¯Ø±ÛØ³Ù‰ ئۈچۈن ÙŠÛØªÛ•رلىك بوشلۇق يوق" + +#: ../gio/ginetsocketaddress.c:238 +msgid "Unsupported socket address" +msgstr "قوللىمايدىغان ئوقۇر Ø¦Ø§Ø¯Ø±ÛØ³Ù‰" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "كىرگۈزۈش ئÛقىمىنى ئوقۇشنى ئەمەلگە ئاشۇرالمىدى" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1033 ../gio/giostream.c:301 +#: ../gio/goutputstream.c:1344 +msgid "Stream has outstanding operation" +msgstr "ئÛقىمدا Ú¾Û•Ù„ بولمىغان مەشغۇلات بار" + +#: ../gio/glib-compile-resources.c:145 ../gio/glib-compile-schemas.c:1459 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "ئÛÙ„ÛÙ…Ûنت <%s> نى <%s> نىڭ ئىچىدە ئىشلەتكىلى بولمايدۇ" + +#: ../gio/glib-compile-resources.c:149 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "ئۈستى قەۋەتتە <%s> ئÛÙ„ÛÙ…Ûنتقا يول قويۇلمايدۇ" + +#: ../gio/glib-compile-resources.c:239 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "مەنبەنىڭ ئىچىدە ھۆججەت %s بىر قانچە يەردە بار ئىكەن" + +#: ../gio/glib-compile-resources.c:252 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "خالىغان بىر ئەسلى مۇندەرىجىدىكى ‹%s› نىڭ ئورنىنى بەلگىلەش مەغلۇپ بولدى" + +#: ../gio/glib-compile-resources.c:263 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "نۆۋەتتىكى مۇندەرىجىدىكى ‹%s› نىڭ ئورنىنى بەلگىلەش مەغلۇپ بولدى" + +#: ../gio/glib-compile-resources.c:291 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "نامەلۇم بىر تەرەپ قىلىش تاللانمىسى «%s»" + +#: ../gio/glib-compile-resources.c:310 ../gio/glib-compile-resources.c:370 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "ۋاقىتلىق ھۆججەت قۇرۇش مەغلۇپ بولدى: %s" + +#: ../gio/glib-compile-resources.c:340 +#, c-format +msgid "" +"Error processing input file with xmllint:\n" +"%s" +msgstr "كىرىش ھۆججىتىنى xmllint ئارقىلىق بىر تەرەپ قىلىشتا خاتالىق كۆرۈلدى:\n" +"%s" + +#: ../gio/glib-compile-resources.c:396 +#, c-format +msgid "" +"Error processing input file with to-pixdata:\n" +"%s" +msgstr "كىرىش ھۆججىتىنى to-pixdata ئارقىلىق بىر تەرەپ قىلىشتا خاتالىق كۆرۈلدى:\n" +"%s" + +#: ../gio/glib-compile-resources.c:410 +#, c-format +msgid "Error reading file %s: %s" +msgstr "ھۆججەت %s ئوقۇشتا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glib-compile-resources.c:430 +#, c-format +msgid "Error compressing file %s" +msgstr "ھۆججەت %s نى Ù¾Ø±ÛØ³Ù„اشتا خاتالىق كۆرۈلدى" + +#: ../gio/glib-compile-resources.c:494 ../gio/glib-compile-schemas.c:1571 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s> ئىچىدە تÛكىست كۆرۈلمەسلىكى لازىم" + +#: ../gio/glib-compile-resources.c:619 +msgid "name of the output file" +msgstr "چىقىرىش ھۆججىتىنىڭ ئاتى" + +#: ../gio/glib-compile-resources.c:619 ../gio/glib-compile-resources.c:650 +#: ../gio/gresource-tool.c:482 ../gio/gresource-tool.c:548 +msgid "FILE" +msgstr "FILE" + +#: ../gio/glib-compile-resources.c:620 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "ھۆججەتلەرنى ئوقۇيدىغان مۇندەرىجىلەر (ئادەتتە نۆۋەتتىكى مۇندەرىجە كۆڭۈلدىكى قىلىپ ئىشلىتىلىدۇ)" + +#: ../gio/glib-compile-resources.c:620 ../gio/glib-compile-schemas.c:1999 +#: ../gio/glib-compile-schemas.c:2028 +msgid "DIRECTORY" +msgstr "DIRECTORY" + +#: ../gio/glib-compile-resources.c:621 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "تاللانغان نىشان ھۆججەتنىڭ ÙƒÛڭەيتىلمە ئاتىغا ئاساسەن چىقىرىش پىچىمىنى ھاسىل قىلىدۇ" + +#: ../gio/glib-compile-resources.c:622 +msgid "Generate source header" +msgstr "مەنبە ماۋزۇسىنى ھاسىللاش" + +#: ../gio/glib-compile-resources.c:623 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "كود ئىچىگە بايلىق ھۆججىتىنىڭ ئۇلانمىسىنى ئىپادىلەيدىغان مەنبە كودى ھاسىللاش" + +#: ../gio/glib-compile-resources.c:624 +msgid "Generate dependency list" +msgstr "بÛقىنىش تىزىمىنى ھاسىللاش" + +#: ../gio/glib-compile-resources.c:625 +msgid "Don't automatically create and register resource" +msgstr "مەنبەنى ئاپتوماتىك ھاسىللىمىسۇن Û‹Û• خەتلەتمىسۇن" + +#: ../gio/glib-compile-resources.c:626 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "Ùۇنكسىيىلەرنى ئÛكسپورت قىلمىسۇن؛ ئۇنى G_GNUC_INTERNAL قىلىپ جاكارلىسۇن" + +#: ../gio/glib-compile-resources.c:627 +msgid "C identifier name used for the generated source code" +msgstr "ھاسىل قىلىنغان مەنبە كودى ئۈچۈن ئىشلىتىلىدىغان C كىملىك(identifier) ئاتى" + +#: ../gio/glib-compile-resources.c:653 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "بايلىق بەلگىلىمىسىنى(specification) بايلىق ھۆججىتىگە يۇغۇرىدۇ.\n" +"بايلىق بەلگىلىمىسى ھۆججىتىنىڭ ÙƒÛڭەيتىلمە ئاتى .gresource.xml بولۇپ، \n" +"بايلىق ھۆججىتىنىڭ ÙƒÛڭەيتىلمە ئاتى .gresource بولىدۇ." + +#: ../gio/glib-compile-resources.c:669 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "سىز پەقەت Û‹Û• پەقەت بىرلا ھۆججەت ئاتى Ø¨ÛØ±Ù‰Ø´Ù‰Ú­Ù‰Ø² لازىم\n" + +#: ../gio/glib-compile-schemas.c:778 +msgid "empty names are not permitted" +msgstr "بوش ئاتقا يول قويۇلمايدۇ" + +#: ../gio/glib-compile-schemas.c:788 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "ئىناۋەتسىز ئات ‹%s›: ئات چوقۇم كىچىك ھەرپتىن باشلىنىدۇ" + +#: ../gio/glib-compile-schemas.c:800 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "ئىناۋەتسىز ئات '%s': ئىناۋەتسىز ھەرپ ب'%c'Ø› پەقەت كىچىك ھەرپ، رەقەم Û‹Û• سىزىق('-') نىلا ئىشلىتىشكە بولىدۇ." + +#: ../gio/glib-compile-schemas.c:809 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "ئىناۋەتسىز ئات ‹%s›: ئىككى تۇتاش سىزىق ('--')نى ئىشلىتىشكە يول قويمايدۇ." + +#: ../gio/glib-compile-schemas.c:818 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "ئىناۋەتسىز ئات ‹%s›: ئەڭ ئاخىرقى ھەرپ سىزىق ('-') بولماسلىقى لازىم." + +#: ../gio/glib-compile-schemas.c:826 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "ئىناۋەتسىز ئات ‹%s›: ئەڭ Ú†ÙˆÚ­ ئۇزۇنلۇقى 1024" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr " ئاللىقاچان بÛكىتىلگەن" + +#: ../gio/glib-compile-schemas.c:921 +msgid "cannot add keys to a 'list-of' schema" +msgstr "'list-of' لايىھىگە كۇنۇپكا قوشالمىدى" + +#: ../gio/glib-compile-schemas.c:932 +#, c-format +msgid " already specified" +msgstr " ئاللىقاچان بÛكىتىلگەن" + +#: ../gio/glib-compile-schemas.c:950 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr " دىكى بىلەن نىڭ سايىسى؛ نى ئىشلىتىپ قىممىتى ئۆزگەرتىلىدۇ" + +#: ../gio/glib-compile-schemas.c:961 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "'type'ØŒ 'enum' ياكى 'flags' تە چوقۇم دەپ بەلگىلەنگەن خاسلىق بولۇشى لازىم" + +#: ../gio/glib-compile-schemas.c:980 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> ØªÛØ®Ù‰ بەلگىلەنمىگەن" + +#: ../gio/glib-compile-schemas.c:995 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "ئىناۋەتسىز GVariant تىپلىق تÛكىست ‹%s›" + +#: ../gio/glib-compile-schemas.c:1025 +msgid " given but schema isn't extending anything" +msgstr " Ø¨ÛØ±Ù‰Ù„دى ئەمما لايىھە ÙƒÛڭەيتىلمىدى" + +#: ../gio/glib-compile-schemas.c:1038 +#, c-format +msgid "no to override" +msgstr "قاپلايدىغان يوق" + +#: ../gio/glib-compile-schemas.c:1046 +#, c-format +msgid " already specified" +msgstr " ئاللىقاچان بÛكىتىلگەن" + +#: ../gio/glib-compile-schemas.c:1117 +#, c-format +msgid " already specified" +msgstr "ئاللىقاچان بÛكىتىلگەن" + +#: ../gio/glib-compile-schemas.c:1129 +#, c-format +msgid " extends not-yet-existing schema '%s'" +msgstr " مەۋجۇت بولمىغان لايىھە '%s' نى ÙƒÛڭەيتتى" + +#: ../gio/glib-compile-schemas.c:1145 +#, c-format +msgid " is list of not-yet-existing schema '%s'" +msgstr " ØªÛØ®Ù‰ مەۋجۇت بولمىغان لايىھە '%s' نىڭ تىزىمى" + +#: ../gio/glib-compile-schemas.c:1153 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "بىر تۈركۈم يولى بار لايىھە بولسا بولمايدۇ" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "يول ÙƒÛڭەيتىلگەن لايىھىنى ئىشلىتەلمەيدۇ" + +#: ../gio/glib-compile-schemas.c:1173 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " تىزىم، ÙƒÛڭەيتىلگەن تىزىم ئەمەس" + +#: ../gio/glib-compile-schemas.c:1183 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr " ÙƒÛڭەيتىلمە ئەمما ‹%s› بولسا ‹%s› نى ÙƒÛڭەيتمەيدۇ" + +#: ../gio/glib-compile-schemas.c:1200 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "بىر يول، ئەگەر Ø¨ÛØ±Ù‰Ù„سە ئۇنداقتا يانتۇ سىزىق (/) بىلەن باشلىنىپ ئاخىرلىشىدۇ" + +#: ../gio/glib-compile-schemas.c:1207 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "بىر تىزىمنىڭ يولى چوقۇم ':/' بىلەن ئاخىرلىشىدۇ" + +#: ../gio/glib-compile-schemas.c:1239 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> ئاللىقاچان بەلگىلەنگەن" + +#: ../gio/glib-compile-schemas.c:1463 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "يۇقىرى قەۋەتتە <%s> ئÛÙ„ÛÙ…Ûنتقا يول قويۇلمايدۇ" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1757 ../gio/glib-compile-schemas.c:1828 +#: ../gio/glib-compile-schemas.c:1904 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict بەلگىلەندى؛ Ú†Ûكىنىۋاتىدۇ.\n" + +#: ../gio/glib-compile-schemas.c:1765 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "پۈتكۈل ھۆججەتكە پەرۋا قىلمىدى.\n" + +#: ../gio/glib-compile-schemas.c:1824 +#, c-format +msgid "Ignoring this file.\n" +msgstr "بۇ ھۆججەتكە پەرۋا قىلمايدۇ.\n" + +#: ../gio/glib-compile-schemas.c:1864 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "%3$s قاپلاش ھۆججىتىدە بەلگىلەنگەن لايىھە '%2$s' دا %1$s كۇنۇپكا يوق" + +#: ../gio/glib-compile-schemas.c:1870 ../gio/glib-compile-schemas.c:1928 +#: ../gio/glib-compile-schemas.c:1956 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "Ø› بۇ كۇنۇپكىنى قاپلاشقا پەرۋا قىلمايدۇ.\n" + +#: ../gio/glib-compile-schemas.c:1874 ../gio/glib-compile-schemas.c:1932 +#: ../gio/glib-compile-schemas.c:1960 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr " ھەمدە --strict بەلگىلەندى؛ Ú†Ûكىنىۋاتىدۇ.\n" + +#: ../gio/glib-compile-schemas.c:1890 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "%3$s قاپلاش ھۆججىتىدە بەلگىلەنگەن '%2$s' دىكى %1$s كۇنۇپكىنى تەھلىل قىلىشتا خاتالىق كۆرۈلدى: %4$s" + +#: ../gio/glib-compile-schemas.c:1900 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "بۇ كۇنۇپكىنى قاپلاشقا پەرۋا قىلمايدۇ.\n" + +#: ../gio/glib-compile-schemas.c:1918 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "%3$s قاپلاش ھۆججىتىدىكى لايىھە '%2$s' دىكى %1$s ئاچقۇچىنى قاپلاش لايىھىدە Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† دائىرىدىن چىقىپ كەتكەن" + +#: ../gio/glib-compile-schemas.c:1946 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "%3$s قاپلاش ھۆججىتىدىكى لايىھە '%2$s' دىكى %1$s كۇنۇپكىنىڭ قاپلىغان قىممىتى ئىناۋەتلىك قىممەت دائىرىسى ئىچىدە" + +#: ../gio/glib-compile-schemas.c:1999 +msgid "where to store the gschemas.compiled file" +msgstr "gschemas.compiled ھۆججەت Ù†Û•Ú¯Û• ساقلىنىدۇ" + +#: ../gio/glib-compile-schemas.c:2000 +msgid "Abort on any errors in schemas" +msgstr "لايىھىدە ھەر قانداق خاتالىق كۆرۈلسە ئۈزىدۇ" + +#: ../gio/glib-compile-schemas.c:2001 +msgid "Do not write the gschema.compiled file" +msgstr "gschema.compiled ھۆججەتكە يازمايدۇ" + +#: ../gio/glib-compile-schemas.c:2002 +msgid "Do not enforce key name restrictions" +msgstr "كۇنۇپكا ئاتىنىڭ چەكلىمىسىنى مەجبۇرلىمايدۇ" + +#: ../gio/glib-compile-schemas.c:2031 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "بارلىق GSettings لايىھە ھۆججەتنى لايىھە غەملەككە تەرجىمە-تەھرىرلەيدۇ.\n" +"ÙƒÛڭەيتىلگەن .gschema.xml نى ئىشلىتىشتە، لايىھە ھۆججىتى بولۇشى لازىم، غەملەك ھۆججىتى gschemas.compiled دەپ ئاتىلىدۇ." + +#: ../gio/glib-compile-schemas.c:2047 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "سىز پەقەت Û‹Û• پەقەت بىرلا مۇندەرىجە ئاتى Ø¨ÛØ±Ù‰Ø´Ù‰Ú­Ù‰Ø² لازىم\n" + +#: ../gio/glib-compile-schemas.c:2086 +#, c-format +msgid "No schema files found: " +msgstr "لايىھە ھۆججىتى تÛپىلمىدى: " + +#: ../gio/glib-compile-schemas.c:2089 +#, c-format +msgid "doing nothing.\n" +msgstr "Ú¾ÛÚ†Ù†ÛÙ…Û• قىلما.\n" + +#: ../gio/glib-compile-schemas.c:2092 +#, c-format +msgid "removed existing output file.\n" +msgstr "مەۋجۇت چىقارغان ھۆججەت Ú†Ù‰Ù‚Ù‰Ø±Ù‰Û‹ÛØªÙ‰Ù„دى.\n" + +#: ../gio/glocaldirectorymonitor.c:252 +msgid "Unable to find default local directory monitor type" +msgstr "كۆڭۈلدىكى يەرلىك مۇندەرىجە كۆزەتكۈچ تىپىنى تاپالمىدى" + +#: ../gio/glocalfile.c:597 ../gio/win32/gwinhttpfile.c:422 +#, c-format +msgid "Invalid filename %s" +msgstr "ئىناۋەتسىز ھۆججەت ئاتى %s" + +#: ../gio/glocalfile.c:974 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "ھۆججەت سىستÛمىسى ئۇچۇرلىرىنى ئÛلىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfile.c:1142 +msgid "Can't rename root directory" +msgstr "غول مۇندەرىجە ئاتىنى ئۆزگەرتكىلى بولمايدۇ" + +#: ../gio/glocalfile.c:1162 ../gio/glocalfile.c:1188 +#, c-format +msgid "Error renaming file: %s" +msgstr "ھۆججەت ئاتىنى ئۆزگەرتىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfile.c:1171 +msgid "Can't rename file, filename already exists" +msgstr "ئاتىنى ئۆزگەرتكىلى بولمىدى، ھۆججەت مەۋجۇت ئىكەن" + +#: ../gio/glocalfile.c:1184 ../gio/glocalfile.c:2201 ../gio/glocalfile.c:2230 +#: ../gio/glocalfile.c:2390 ../gio/glocalfileoutputstream.c:575 +#: ../gio/glocalfileoutputstream.c:628 ../gio/glocalfileoutputstream.c:673 +#: ../gio/glocalfileoutputstream.c:1161 +msgid "Invalid filename" +msgstr "ئىناۋەتسىز ھۆججەت ئاتى" + +#: ../gio/glocalfile.c:1351 ../gio/glocalfile.c:1375 +msgid "Can't open directory" +msgstr "مۇندەرىجە ئاچالمىدى" + +#: ../gio/glocalfile.c:1359 +#, c-format +msgid "Error opening file: %s" +msgstr "ھۆججەت ئÛچىش خاتالىقى: %s" + +#: ../gio/glocalfile.c:1500 +#, c-format +msgid "Error removing file: %s" +msgstr "ھۆججەتنى ئۆچۈرۈۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfile.c:1880 +#, c-format +msgid "Error trashing file: %s" +msgstr "ھۆججەتنى ئەخلەتخانىغا يۆتكەش خاتالىقى: %s" + +#: ../gio/glocalfile.c:1903 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "ئەخلەتخانا مۇندەرىجىسى %s نى قۇرالمايدۇ: %s" + +#: ../gio/glocalfile.c:1924 +msgid "Unable to find toplevel directory for trash" +msgstr "ئەخلەتخانىنىڭ ئەڭ يۇقىرى دەرىجىدىكى مۇندەرىجىنى تاپالمايدۇ" + +#: ../gio/glocalfile.c:2003 ../gio/glocalfile.c:2023 +msgid "Unable to find or create trash directory" +msgstr "ئەخلەتخانا مۇندەرىجىسى قۇرالمايدۇ ياكى تاپالمايدۇ" + +#: ../gio/glocalfile.c:2057 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "ئەخلەتخانا ئۇچۇر ھۆججىتىنى قۇرالمايدۇ: %s" + +#: ../gio/glocalfile.c:2086 ../gio/glocalfile.c:2091 ../gio/glocalfile.c:2171 +#: ../gio/glocalfile.c:2178 +#, c-format +msgid "Unable to trash file: %s" +msgstr "ھۆججەتنى ئەخلەتخانىغا يۆتكىيەلمەيدۇ: %s" + +#: ../gio/glocalfile.c:2179 ../glib/gregex.c:280 +msgid "internal error" +msgstr "ئىچكى خاتالىق" + +#: ../gio/glocalfile.c:2205 +#, c-format +msgid "Error creating directory: %s" +msgstr "مۇندەرىجە قۇرۇش خاتالىقى: %s" + +#: ../gio/glocalfile.c:2234 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ھۆججەت سىستÛمىسى بەلگە ئۇلانمىسىنى قوللىمايدۇ" + +#: ../gio/glocalfile.c:2238 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "بەلگە ئۇلانما قۇرۇشتا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfile.c:2300 ../gio/glocalfile.c:2394 +#, c-format +msgid "Error moving file: %s" +msgstr "ھۆججەت يۆتكەش خاتالىقى: %s" + +#: ../gio/glocalfile.c:2323 +msgid "Can't move directory over directory" +msgstr "مۇندەرىجىنى مۇندەرىجىگە يۆتكىيەلمەيدۇ" + +#: ../gio/glocalfile.c:2350 ../gio/glocalfileoutputstream.c:959 +#: ../gio/glocalfileoutputstream.c:973 ../gio/glocalfileoutputstream.c:988 +#: ../gio/glocalfileoutputstream.c:1004 ../gio/glocalfileoutputstream.c:1018 +msgid "Backup file creation failed" +msgstr "زاپاس ھۆججەت قۇرالمىدى" + +#: ../gio/glocalfile.c:2369 +#, c-format +msgid "Error removing target file: %s" +msgstr "نىشان ھۆججەت يۆتكەۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfile.c:2383 +msgid "Move between mounts not supported" +msgstr "ئÛگەرلەشلەر ئارىسىدا يۆتكەشنى قوللىمايدۇ" + +#: ../gio/glocalfileinfo.c:722 +msgid "Attribute value must be non-NULL" +msgstr "خاسلىق قىممىتى NULL بولمىسۇن" + +#: ../gio/glocalfileinfo.c:729 +msgid "Invalid attribute type (string expected)" +msgstr "ئىناۋەتسىز خاسلىق تىپى (تÛكىست «string»بولۇشى لازىم)" + +#: ../gio/glocalfileinfo.c:736 +msgid "Invalid extended attribute name" +msgstr "ئىناۋەتسىز ÙƒÛڭەيتىلگەن خاسلىق ئاتى" + +#: ../gio/glocalfileinfo.c:776 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "ÙƒÛڭەيتىلگەن خاسلىق ‹%s›نى تەڭشەۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinfo.c:1548 +msgid " (invalid encoding)" +msgstr " (ئىناۋەتسىز كودلاش)" + +#: ../gio/glocalfileinfo.c:1740 ../gio/glocalfileoutputstream.c:837 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "ھۆججەت ‹%s› نىڭ ئۇچۇرىنى ئÛلىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinfo.c:1986 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "ھۆججەت چۈشەندۈرگۈچ ئۇچۇرىنى ئÛلىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinfo.c:2031 +msgid "Invalid attribute type (uint32 expected)" +msgstr "ئىناۋەتسىز خاسلىق تىپى (uint32 بولۇشى لازىم)" + +#: ../gio/glocalfileinfo.c:2049 +msgid "Invalid attribute type (uint64 expected)" +msgstr "ئىناۋەتسىز خاسلىق تىپى (uint64 بولۇشى لازىم)" + +#: ../gio/glocalfileinfo.c:2068 ../gio/glocalfileinfo.c:2087 +msgid "Invalid attribute type (byte string expected)" +msgstr "ئىناۋەتسىز خاسلىق تىپى (بايتلىق تÛكىست «byte string»بولۇشى لازىم)" + +#: ../gio/glocalfileinfo.c:2122 +msgid "Cannot set permissions on symlinks" +msgstr "بەلگە ئۇلانمىنىڭ ئىمتىيازىنى بەلگىلىگىلى بولمايدۇ" + +#: ../gio/glocalfileinfo.c:2138 +#, c-format +msgid "Error setting permissions: %s" +msgstr "ئىمتىيازلارنى بÛكىتىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinfo.c:2189 +#, c-format +msgid "Error setting owner: %s" +msgstr "ئىگىسىنى بÛكىتىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinfo.c:2212 +msgid "symlink must be non-NULL" +msgstr "بەلگە ئۇلانما چوقۇم NULL بولمىسۇن" + +#: ../gio/glocalfileinfo.c:2222 ../gio/glocalfileinfo.c:2241 +#: ../gio/glocalfileinfo.c:2252 +#, c-format +msgid "Error setting symlink: %s" +msgstr "symlink نى بÛكىتىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinfo.c:2231 +msgid "Error setting symlink: file is not a symlink" +msgstr "symlink نى بÛكىتىۋاتقاندا خاتالىق كۆرۈلدى: ھۆججەت symlink ئەمەس" + +#: ../gio/glocalfileinfo.c:2357 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "زىيارەت ۋاقتى ياكى تەڭشەكنى ئۆزگەرتىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinfo.c:2380 +msgid "SELinux context must be non-NULL" +msgstr "SELinux تىل مۇھىتى NULL بولمىسۇن" + +#: ../gio/glocalfileinfo.c:2395 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "SELinux تىل مۇھىتى تەڭشەۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinfo.c:2402 +msgid "SELinux is not enabled on this system" +msgstr "بۇ سىستÛمىدا SELinux قوزغىتىلمىغان" + +#: ../gio/glocalfileinfo.c:2494 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "%s خاسلىقنى تەڭشەشنى قوللىمايدۇ" + +#: ../gio/glocalfileinputstream.c:186 ../gio/glocalfileoutputstream.c:726 +#, c-format +msgid "Error reading from file: %s" +msgstr "ھۆججەتتىن ئوقۇۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinputstream.c:217 ../gio/glocalfileinputstream.c:229 +#: ../gio/glocalfileinputstream.c:336 ../gio/glocalfileoutputstream.c:464 +#: ../gio/glocalfileoutputstream.c:1036 +#, c-format +msgid "Error seeking in file: %s" +msgstr "ھۆججەتتە ئورۇن بەلگىلەۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileinputstream.c:258 ../gio/glocalfileoutputstream.c:254 +#: ../gio/glocalfileoutputstream.c:348 +#, c-format +msgid "Error closing file: %s" +msgstr "ھۆججەتنى ÙŠÛپىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfilemonitor.c:176 +msgid "Unable to find default local file monitor type" +msgstr "كۆڭۈلدىكى يەرلىك ھۆججەت كۆزەتكۈچ تىپىنى تاپالمايدۇ" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:234 +#: ../gio/glocalfileoutputstream.c:747 +#, c-format +msgid "Error writing to file: %s" +msgstr "ھۆججەتكە ÙŠÛØ²Ù‰Û‹Ø§ØªÙ‚اندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileoutputstream.c:281 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "كونا زاپاسنىڭ ئۇلانمىسىنى ئۆچۈرۈۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileoutputstream.c:295 ../gio/glocalfileoutputstream.c:308 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "زاپاس نۇسخا قۇرۇۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileoutputstream.c:326 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "ۋاقىتلىق ھۆججەت ئاتىنى ئۆزگەرتىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileoutputstream.c:510 ../gio/glocalfileoutputstream.c:1087 +#, c-format +msgid "Error truncating file: %s" +msgstr "ھۆججەت ئۈزۈۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileoutputstream.c:581 ../gio/glocalfileoutputstream.c:634 +#: ../gio/glocalfileoutputstream.c:679 ../gio/glocalfileoutputstream.c:819 +#: ../gio/glocalfileoutputstream.c:1068 ../gio/glocalfileoutputstream.c:1167 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "ھۆججەت ‹%s› نى ئÛچىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/glocalfileoutputstream.c:850 +msgid "Target file is a directory" +msgstr "نىشان ھۆججەت مۇندەرىجە" + +#: ../gio/glocalfileoutputstream.c:855 +msgid "Target file is not a regular file" +msgstr "نىشان ھۆججەت ئادەتتىكى ھۆججەت ئەمەس" + +#: ../gio/glocalfileoutputstream.c:867 +msgid "The file was externally modified" +msgstr "ھۆججەتنى باشقا پروگرامما ئۆزگەرتكەن" + +#: ../gio/glocalfileoutputstream.c:1052 +#, c-format +msgid "Error removing old file: %s" +msgstr "كونا ھۆججەتنى ئۆچۈرۈۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gmemoryinputstream.c:476 ../gio/gmemoryoutputstream.c:739 +msgid "Invalid GSeekType supplied" +msgstr "تەمىنلەنگەن GSeekType ئىناۋەتسىز" + +#: ../gio/gmemoryinputstream.c:486 +msgid "Invalid seek request" +msgstr "ئىناۋەتسىز ئىزدەش ئىلتىماسى" + +#: ../gio/gmemoryinputstream.c:510 +msgid "Cannot truncate GMemoryInputStream" +msgstr "GMemoryInputStream ئۈزەلمەيدۇ" + +#: ../gio/gmemoryoutputstream.c:544 +msgid "Memory output stream not resizable" +msgstr "ئەسلەك چىقىرىش ئÛقىمىنىڭ چوڭلۇقىنى ئۆزگەرتكىلى بولمايدۇ" + +#: ../gio/gmemoryoutputstream.c:560 +msgid "Failed to resize memory output stream" +msgstr "ئەسلەك چىقىرىش ئÛقىم چوڭلۇقىنى ئۆزگەرتەلمىدى" + +#: ../gio/gmemoryoutputstream.c:648 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "ÙŠÛØ²Ù‰Ø´Ù‚ا ئÛھتىياجلىق ئەسلەكنى بىر تەرەپ قىلىشتا ئىشلىتىلىشچان بوشلۇقتىن ھالقىپ كەتتى" + +#: ../gio/gmemoryoutputstream.c:749 +msgid "Requested seek before the beginning of the stream" +msgstr "ئىلتىماس قىلغان ئورۇن بÛكىتىش قىممىتى ئÛقىم باشلىنىشىدىن ئىلگىرى" + +#: ../gio/gmemoryoutputstream.c:758 +msgid "Requested seek beyond the end of the stream" +msgstr "ئىلتىماس قىلغان ئورۇن بÛكىتىش قىممىتى ئÛقىم ئاخىرلىشىشتىن ÙƒÛيىن" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:395 +msgid "mount doesn't implement \"unmount\"" +msgstr "ئÛگەرلەش \"unmount\" نى ئىشقا ئاشۇرالمىدى" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:471 +msgid "mount doesn't implement \"eject\"" +msgstr "ئÛگەرلەش \"eject\" مەشغۇلاتىنى ئىشقا ئاشۇرالمىدى" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:549 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "ئÛگەرلەش \"unmount\" ياكى \"unmount_with_operation\" نى ئىشقا ئاشۇرالمىدى" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:634 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "ئÛگەرلەش \"eject\" ياكى \"eject_with_operation\" نى ئىشقا ئاشۇرالمىدى" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:722 +msgid "mount doesn't implement \"remount\"" +msgstr "ئÛگەرلەش \"remount\" نى ئىشقا ئاشۇرالمىدى" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:803 +msgid "mount doesn't implement content type guessing" +msgstr "ئÛگەرلەش مەزمۇن تىپى مۆلچەرلەشنى ئىشقا ئاشۇرالمىدى" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "ئÛگەرلەش قەدەمداش مەزمۇن تىپى مۆلچەرلەشنى ئىشقا ئاشۇرالمىدى" + +#: ../gio/gnetworkaddress.c:354 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "ماشىنا ئاتى ‹%s› دا '[' بار ئەمما ']' يوق" + +#: ../gio/gnetworkmonitorbase.c:195 ../gio/gnetworkmonitorbase.c:298 +msgid "Network unreachable" +msgstr "تورغا ÙŠÛØªÛ•لمەيدۇ" + +#: ../gio/gnetworkmonitorbase.c:233 ../gio/gnetworkmonitorbase.c:263 +msgid "Host unreachable" +msgstr "ماشىنىغا ÙŠÛØªÛ•لمەيدۇ" + +#: ../gio/gnetworkmonitornetlink.c:98 ../gio/gnetworkmonitornetlink.c:110 +#: ../gio/gnetworkmonitornetlink.c:129 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "تور كۆزەتكۈچ قۇرغىلى بولمىدى: %s" + +#: ../gio/gnetworkmonitornetlink.c:119 +msgid "Could not create network monitor: " +msgstr "تور كۆزەتكۈچ قۇرغىلى بولمىدى: " + +#: ../gio/gnetworkmonitornetlink.c:177 +msgid "Could not get network status: " +msgstr "تور ھالىتىنى ئالغىلى بولمىدى: " + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:464 +msgid "Output stream doesn't implement write" +msgstr "چىقىرىش ئÛقىمىدا ÙŠÛØ²Ù‰Ø´Ù†Ù‰ ئىشلەتكىلى بولمايدۇ" + +#: ../gio/goutputstream.c:425 ../gio/goutputstream.c:950 +msgid "Source stream is already closed" +msgstr "مەنبە ئÛقىم ئاللىبۇرۇن ÙŠÛپىلغان" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:454 +#: ../gio/gresourcefile.c:555 ../gio/gresourcefile.c:657 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "‹%s'› يەردىكى مەنبە مەۋجۇت ئەمەس" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "‹%s'› يەردىكى مەنبەنى ÙŠÛيىش مەغلۇپ بولدى" + +#: ../gio/gresourcefile.c:653 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "‹%s'› يەردىكى مەنبە مۇندەرىجە ئەمەس" + +#: ../gio/gresourcefile.c:861 +msgid "Input stream doesn't implement seek" +msgstr "كىرگۈزۈش ئÛقىمىدا ئىزدەشنى ئىشلەتكىلى بولمايدۇ" + +#: ../gio/gresource-tool.c:475 ../gio/gsettings-tool.c:529 +msgid "Print help" +msgstr "Ø¨ÛØ³Ù‰Ø´ ياردىمى" + +#: ../gio/gresource-tool.c:476 ../gio/gresource-tool.c:544 +msgid "[COMMAND]" +msgstr "[COMMAND]" + +#: ../gio/gresource-tool.c:481 +msgid "List sections containing resources in an elf FILE" +msgstr "بىر elf FILE(ھۆججەت) ئىچىدىكى مەنبەلەرنىڭ بۆلەكلىرىنى تىزىپ كۆرسىتىدۇ" + +#: ../gio/gresource-tool.c:487 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "مەنبەلەر تىزىمى\n" +"ئەگەر SECTION Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† بولسا، مۇشۇ بۆلەك ئىچىدىكى مەنبەلەر تىزىمىنىلا كۆرسىتىدۇ\n" +"ئەگەر PATH Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† بولسا، ماس ÙƒÛ•Ù„Ú¯Û•Ù† مەنبەلەر تىزىمىنىلا كۆرسىتىدۇ" + +#: ../gio/gresource-tool.c:490 ../gio/gresource-tool.c:500 +msgid "FILE [PATH]" +msgstr "FILE [PATH]" + +#: ../gio/gresource-tool.c:491 ../gio/gresource-tool.c:501 +#: ../gio/gresource-tool.c:508 +msgid "SECTION" +msgstr "SECTION" + +#: ../gio/gresource-tool.c:496 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "مەنبەلەر تىزىمىنى تەپسىلىي كۆرسىتىش\n" +"ئەگەر SECTION Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† بولسا، مۇشۇ بۆلەك ئىچىدىكى مەنبەلەر تىزىمىنىلا كۆرسىتىدۇ\n" +"ئەگەر PATH Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† بولسا، ماس ÙƒÛ•Ù„Ú¯Û•Ù† مەنبەلەر تىزىمىنىلا كۆرسىتىدۇ\n" +"تەپسىلاتلار ئىچىدە بۆلەك، Ú†ÙˆÚ­Ù„Û‡Ù‚ØŒ Û‹Û• Ù¾Ø±ÛØ³Ù„اش بار" + +#: ../gio/gresource-tool.c:506 +msgid "Extract a resource file to stdout" +msgstr "مەنبە ھۆججىتىنى ئۆلچەملىك چىقىرىشقا يايسۇن" + +#: ../gio/gresource-tool.c:507 +msgid "FILE PATH" +msgstr "FILE PATH" + +#: ../gio/gresource-tool.c:513 ../gio/gsettings-tool.c:609 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "نامەلۇم بۇيرۇق %s\n" +"\n" + +#: ../gio/gresource-tool.c:521 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "ئىشلىتىش ئۇسۇلى:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"بۇيرۇقلار:\n" +" help مەزكۇر ئۇچۇرنى كۆرسىتىدۇ\n" +" sections مەنبەلەرنىڭ بۆلەكلىرىنى كۆرسىتىدۇ\n" +" list مەنبەلەرنى كۆرسىتىدۇ\n" +" details مەنبەلەرنى تەپسىلاتى بىلەن قوشۇپ كۆرسىتىدۇ\n" +" extract مەنبەلەرنى يايىدۇ\n" +"\n" +"تەپسىلىي ياردەم ئۈچۈن 'gresource help COMMAND' نى ئىشلىتىڭ.\n" +"\n" + +#: ../gio/gresource-tool.c:535 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "ئىشلىتىش ئۇسۇلى:\n" +"gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:538 ../gio/gsettings-tool.c:642 +msgid "Arguments:\n" +msgstr "ئەركىن ئۆزگەرگۈچى:\n" + +#: ../gio/gresource-tool.c:542 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION بولسا (ئىختىيارىي) elf بۆلىكىنىڭ ئاتى\n" + +#: ../gio/gresource-tool.c:546 ../gio/gsettings-tool.c:649 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND بۇيرۇقتا چۈشەندۈرۈلىدۇ(تاللاشچان)\n" + +#: ../gio/gresource-tool.c:552 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE بولسا بىر elf ھۆججىتى (بىر ئىجرا بولىدىغان پروگرامما ياكى ھەمبەھىرلەنگەن ئامبار)\n" + +#: ../gio/gresource-tool.c:555 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr " FILE بولسا بىر elf ھۆججىتى (بىر ئىجرا بولىدىغان پروگرامما ياكى ھەمبەھىرلەنگەن ئامبار)\n" +" ياكى يۇغۇرۇلغان مەنبە ھۆججىتى\n" + +#: ../gio/gresource-tool.c:559 +msgid "[PATH]" +msgstr "[PATH]" + +#: ../gio/gresource-tool.c:561 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH بولسا (ئىختىيارىي) مەنبەنىڭ يولى (قىسمى يول بولسىمۇ بولىدۇ)\n" + +#: ../gio/gresource-tool.c:562 +msgid "PATH" +msgstr "PATH" + +#: ../gio/gresource-tool.c:564 +msgid " PATH A resource path\n" +msgstr " PATH مەنبەنىڭ يولى\n" + +#: ../gio/gsettings-tool.c:57 ../gio/gsettings-tool.c:78 +#, c-format +msgid "No such schema '%s'\n" +msgstr "‹%s› دەك لايىھە يوق\n" + +#: ../gio/gsettings-tool.c:63 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "‹%s› لايىھىنى قايتا نىشان بەلگىلىگىلى بولمايدۇ (چوقۇم يول بەلگىلىنىشى لازىم)\n" + +#: ../gio/gsettings-tool.c:84 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "‹%s› لايىھىنى قايتا نىشان بەلگىلىگىلى بولىدۇ (چوقۇم يول بەلگىلىنىشى لازىم)\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Empty path given.\n" +msgstr "Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† يول قۇرۇق.\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "يول چوقۇم يانتۇ سىزىق '/' بىلەن باشلىنىشى لازىم\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "يول چوقۇم يانتۇ سىزىق '/' بىلەن ئاخىرلىشىشى لازىم\n" + +#: ../gio/gsettings-tool.c:116 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "ئاتتا ئارقىمۇ ئارقا ئىككى يانتۇ سىزىق (//) بولماسلىقى لازىم\n" + +#: ../gio/gsettings-tool.c:137 +#, c-format +msgid "No such key '%s'\n" +msgstr "‹%s› دەك كۇنۇپكا يوق\n" + +#: ../gio/gsettings-tool.c:502 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "تەمىنلەنگەن قىممەت ئىناۋەتلىك دائىرىدە ئەمەس\n" + +#: ../gio/gsettings-tool.c:535 +msgid "List the installed (non-relocatable) schemas" +msgstr "ئورنىتىلغان (قايتا نىشان بەلگىلىگىلى بولمايدىغان) لايىھە تىزىمىنى كۆرسىتىدۇ" + +#: ../gio/gsettings-tool.c:541 +msgid "List the installed relocatable schemas" +msgstr "ئورنىتىلغان قايتا نىشان بەلگىلىگىلى بولىدىغان لايىھە تىزىمىنى كۆرسىتىدۇ" + +#: ../gio/gsettings-tool.c:547 +msgid "List the keys in SCHEMA" +msgstr "SCHEMA دىكى كۇنۇپكا تىزىمىنى كۆرسىتىدۇ" + +#: ../gio/gsettings-tool.c:548 ../gio/gsettings-tool.c:554 +#: ../gio/gsettings-tool.c:591 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:553 +msgid "List the children of SCHEMA" +msgstr "SCHEMA دىكى تارماق نەڭنى كۆرسىتىدۇ" + +#: ../gio/gsettings-tool.c:559 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "ئاچقۇچ Û‹Û• قىممەتنى چوڭقۇرلاپ كۆرسىتىدۇ\n" +"ئەگەر SCHEMA Ø¨ÛØ±Ù‰Ù„مىگەن بولسا بارلىق ئاچقۇچلارنى كۆرسىتىدۇ\n" + +#: ../gio/gsettings-tool.c:561 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:566 +msgid "Get the value of KEY" +msgstr "كۇنۇپكا قىممىتىگە Ø¦ÛØ±Ù‰Ø´Ù‰Ø¯Û‡" + +#: ../gio/gsettings-tool.c:567 ../gio/gsettings-tool.c:573 +#: ../gio/gsettings-tool.c:585 ../gio/gsettings-tool.c:597 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:572 +msgid "Query the range of valid values for KEY" +msgstr "KEY نىڭ ئىناۋەتلىك قىممەت دائىرىسىنى سۈرۈشتۈرىدۇ" + +#: ../gio/gsettings-tool.c:578 +msgid "Set the value of KEY to VALUE" +msgstr "KEY نىڭ قىممىتىنى VALUE قىلىپ تەڭشەيدۇ" + +#: ../gio/gsettings-tool.c:579 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:584 +msgid "Reset KEY to its default value" +msgstr "KEY نى كۆڭۈلدىكى قىممەتكە ئەسلىگە قايتۇرىدۇ" + +#: ../gio/gsettings-tool.c:590 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "SCHEMA دىكى ھەممە كۇنۇپكا قىممىتىنى كۆڭۈلدىكىگە قايتۇر" + +#: ../gio/gsettings-tool.c:596 +msgid "Check if KEY is writable" +msgstr "KEY نىڭ ÙŠÛØ²Ù‰Ø´Ú†Ø§Ù† ياكى ئەمەسلىكىنى تەكشۈرىدۇ" + +#: ../gio/gsettings-tool.c:602 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "KEY ئۆزگىرىشىنى كۆزىتىدۇ.\n" +"ئەگەر KEY بەلگىلەنمىگەن بولسا ئۇنداقتا SCHEMA دىكى ھەممە كۇنۇپكىنى كۆزىتىدۇ. \n" +"^C دا كۆزىتىشنى توختىتىدۇ.\n" + +#: ../gio/gsettings-tool.c:605 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:617 +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "ئىشلىتىش ئۇسۇلى:\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"بۇيرۇقلار:\n" +" help بۇ ئۇچۇرنى كۆرسىتىدۇ\n" +" list-schemas ئورنىتىلغان لايىھىلەرنى كۆرسىتىدۇ\n" +" list-relocatable-schemas قايتا ئورۇنلاشتۇرۇشقا بولىدىغان لايىھىلەرنى كۆرسىتىدۇ\n" +" list-keys لايىھە ئىچىدىكى ئاچقۇچلارنى كۆرسىتىدۇ\n" +" list-children لايىھىنىڭ باللىرىنى كۆرسىتىدۇ\n" +" list-recursively ئاچقۇچ Û‹Û• قىممىتىنى چوڭقۇرلاپ(recursively) كۆرسىتىدۇ\n" +" range ئاچقۇچنىڭ دائىرىسىنى سۈرۈشتۈرىدۇ\n" +" get ئاچقۇچنىڭ قىممىتىنى ئالىدۇ\n" +" set ئاچقۇچقا قىممەت Ø¨ÛØ±Ù‰Ø¯Û‡\n" +" reset ئاچقۇچنىڭ قىممىتىنى ئەسلىگە قايتۇرىدۇ\n" +" reset-recursively لايىھە ئىچىدىكى بارلىق قىممەتلەرنى ئەسلىگە قايتۇرىدۇ\n" +" writable ئاچقۇچقا يازغىلى بولامدۇ تەكشۈرىدۇ\n" +" monitor ئۆزگىرىشلەرنى كۆزىتىدۇ\n" +"\n" +"تەپسىلىي ياردەم ئۈچۈن 'gsettings help COMMAND' نى ئىشلىتىڭ..\n" +"\n" + +#: ../gio/gsettings-tool.c:639 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "ئىشلىتىش ئۇسۇلى:\n" +"gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:645 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR قوشۇمچە لايىھىلەرنى ئىزدەيدىغان مۇندەرىجە\n" + +#: ../gio/gsettings-tool.c:653 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr " SCHEMA لايىھىنىڭ ئاتى\n" +" PATH قايتا نىشان بەلگىلىگىلى بولىدىغان يول\n" + +#: ../gio/gsettings-tool.c:658 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY لايىھە(تاللاشچان)دىكى كۇنۇپكا\n" + +#: ../gio/gsettings-tool.c:662 +msgid " KEY The key within the schema\n" +msgstr " KEY لايىھىدىكى كۇنۇپكا\n" + +#: ../gio/gsettings-tool.c:666 +msgid " VALUE The value to set\n" +msgstr " VALUE تەڭشەيدىغان قىممەت\n" + +#: ../gio/gsettings-tool.c:725 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "%s نىڭدىن لايىھىلەرنى ئوقۇغىلى بولمىدى: %s\n" + +#: ../gio/gsettings-tool.c:784 +#, c-format +msgid "Empty schema name given\n" +msgstr "Ø¨ÛØ±Ù‰Ù„Ú¯Û•Ù† لايىھە ئاتى بوش\n" + +#: ../gio/gsocket.c:311 +msgid "Invalid socket, not initialized" +msgstr "socket ئىناۋەتسىز، دەسلەپلەشتۈرۈلمىگەن" + +#: ../gio/gsocket.c:318 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "ئىناۋەتسىز ئوقۇر، دەسلەپلەشتۈرەلمىگەنلىكنىڭ سەۋەبى: %s" + +#: ../gio/gsocket.c:326 +msgid "Socket is already closed" +msgstr "ئوقۇر تاقالغان" + +#: ../gio/gsocket.c:334 ../gio/gsocket.c:3525 ../gio/gsocket.c:3580 +msgid "Socket I/O timed out" +msgstr "ئوقۇر I/O مۆھلىتى ئۆتتى" + +#: ../gio/gsocket.c:481 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ھۆججەت چۈشەندۈرۈش بەلگىسىدىن GSocket قۇرۇۋاتىدۇ: %s" + +#: ../gio/gsocket.c:509 ../gio/gsocket.c:563 ../gio/gsocket.c:570 +#, c-format +msgid "Unable to create socket: %s" +msgstr "ئوقۇر قۇرالمايدۇ: %s" + +#: ../gio/gsocket.c:563 +msgid "Unknown family was specified" +msgstr "كۆرسىتىلگەن ئائىلە ناتونۇش" + +#: ../gio/gsocket.c:570 +msgid "Unknown protocol was specified" +msgstr "نامەلۇم ÙƒÛلىشىم بەلگىلەندى" + +#: ../gio/gsocket.c:1728 +#, c-format +msgid "could not get local address: %s" +msgstr "يەرلىك Ø¦Ø§Ø¯Ø±ÛØ³Ù‚ا Ø¦ÛØ±Ù‰Ø´Û•لمىدى: %s" + +#: ../gio/gsocket.c:1771 +#, c-format +msgid "could not get remote address: %s" +msgstr "يىراقتىكى Ø¦Ø§Ø¯Ø±ÛØ³Ù‚ا Ø¦ÛØ±Ù‰Ø´Û•لمىدى: %s" + +#: ../gio/gsocket.c:1832 +#, c-format +msgid "could not listen: %s" +msgstr "تىڭشىيالمىدى: %s" + +#: ../gio/gsocket.c:1904 +#, c-format +msgid "Error binding to address: %s" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³Ù‚ا باغلاۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:1957 ../gio/gsocket.c:1994 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "multicast گۇرۇپپىسىغا قوشۇلۇشتا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:1958 ../gio/gsocket.c:1995 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "multicast گۇرۇپپىسىدىن ئايرىلىشتا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:1959 +msgid "No support for source-specific multicast" +msgstr "مەنبەسى-كۆرسىتىلگەن(source-specific) multicast نى قوللىمايدۇ" + +#: ../gio/gsocket.c:2178 +#, c-format +msgid "Error accepting connection: %s" +msgstr "باغلىنىشنى قوبۇل قىلىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:2299 +msgid "Connection in progress" +msgstr "باغلىنىۋاتىدۇ" + +#: ../gio/gsocket.c:2346 +msgid "Unable to get pending error: " +msgstr "Ú¾Û•Ù„ بولمىغان خاتالىققا Ø¦ÛØ±Ù‰Ø´ÙƒÙ‰Ù„Ù‰ بولمىدى: %s " + +#: ../gio/gsocket.c:2512 +#, c-format +msgid "Error receiving data: %s" +msgstr "سانلىق-مەلۇمات قوبۇل قىلىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:2690 +#, c-format +msgid "Error sending data: %s" +msgstr "سانلىق-مەلۇمات يوللاۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:2804 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ئوقۇرنى تاقىغىلى بولمىدى: %s" + +#: ../gio/gsocket.c:2883 +#, c-format +msgid "Error closing socket: %s" +msgstr "Ø³ÙˆÙƒÛØªÙ†Ù‰ ÙŠÛپىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:3518 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ئوقۇر ھالىتىنى كۈتۈۋاتىدۇ: %s" + +#: ../gio/gsocket.c:3796 ../gio/gsocket.c:3877 +#, c-format +msgid "Error sending message: %s" +msgstr "ئۇچۇر يوللاۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:3821 +msgid "GSocketControlMessage not supported on Windows" +msgstr "windows تا GSocketControlMessage نى ئىشلەتكىلى بولمايدۇ" + +#: ../gio/gsocket.c:4155 ../gio/gsocket.c:4290 +#, c-format +msgid "Error receiving message: %s" +msgstr "ئۇچۇر قوبۇل قىلىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gsocket.c:4372 +#, c-format +msgid "Unable to get pending error: %s" +msgstr "Ú¾Û•Ù„ بولمىغان خاتالىققا Ø¦ÛØ±Ù‰Ø´Û•لمەيدۇ: %s" + +#: ../gio/gsocket.c:4391 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "بۇ مەشغۇلات سىستÛمىسىدا g_socket_get_credentials ئەمەلگە ئاشمىغان" + +#: ../gio/gsocketclient.c:177 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "ۋاكالەتچى Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø±Ù‰ %s غا باغلىنالمىدى: " + +#: ../gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to %s: " +msgstr "%s غا باغلانغىلى بولمىدى: " + +#: ../gio/gsocketclient.c:193 +msgid "Could not connect: " +msgstr "باغلانغىلى بولمىدى: " + +#: ../gio/gsocketclient.c:1072 ../gio/gsocketclient.c:1636 +msgid "Unknown error on connect" +msgstr "باغلانغاندا نامەلۇم خاتالىق كۆرۈلدى" + +#: ../gio/gsocketclient.c:1125 ../gio/gsocketclient.c:1574 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "TCP باشلىنىشتىن باشقىلىرىدا ۋاكالەتچىنى ئىشلەتكىلى بولمايدۇ." + +#: ../gio/gsocketclient.c:1151 ../gio/gsocketclient.c:1595 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "‹%s› ۋاكالەتچى ÙƒÛلىشىمىنى قوللىمايدۇ." + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "تىڭشىغۇچ تاقالغان" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "قوشۇلغان ئوقۇر ÙŠÛپىلدى" + +#: ../gio/gsocks4aproxy.c:120 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "IPv6 Ø¦Ø§Ø¯Ø±ÛØ³ ‹%s› نى SOCKSv4 قوللىمايدۇ" + +#: ../gio/gsocks4aproxy.c:138 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "ئىشلەتكۈچى ئاتى SOCKSv4 ÙƒÛلىشىمىگە نىسبەتەن بەك ئۇزۇن" + +#: ../gio/gsocks4aproxy.c:155 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "ÙƒÙˆÙ…Ù¾ÙŠÛ‡ØªÛØ± ئاتى ‹%s› ÙƒÛلىشىم SOCKSv4 غا نىسبەتەن بەك ئۇزۇن" + +#: ../gio/gsocks4aproxy.c:181 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "بۇ Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø± SOCKSv4 ۋاكالەتچى Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø± ئەمەس." + +#: ../gio/gsocks4aproxy.c:188 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "SOCKSv4 Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø±Ù‰ ئارقىلىق باغلىنىش رەت قىلىندى" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:326 +#: ../gio/gsocks5proxy.c:336 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "بۇ Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø± SOCKSv5 ۋاكالەتچى Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø± ئەمەس." + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 ۋاكالەتچى Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø± دەلىللەشكە ئÛھتىياجلىق." + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "بۇ SOCKSv5 باغلىنىشقا GLib قوللىمايدىغان دەلىللەش ئۇسۇلىغا ئÛھتىياجلىق." + +#: ../gio/gsocks5proxy.c:208 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "ئىشلەتكۈچى ئاتى ياكى ئىم SOCKSv5 ÙƒÛلىشىمىگە نىسبەتەن بەك ئۇزۇن." + +#: ../gio/gsocks5proxy.c:238 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 دەلىللىيەلمىدى ئىشلەتكۈچى ئاتى ياكى ئىم خاتا." + +#: ../gio/gsocks5proxy.c:288 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "ÙƒÙˆÙ…Ù¾ÙŠÛ‡ØªÛØ± ئاتى ‹%s› ÙƒÛلىشىم SOCKSv5 غا نىسبەتەن بەك ئۇزۇن" + +#: ../gio/gsocks5proxy.c:350 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 ۋاكالەتچى Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø± نامەلۇم Ø¦Ø§Ø¯Ø±ÛØ³ تىپى ئىشلەتكەن." + +#: ../gio/gsocks5proxy.c:357 +msgid "Internal SOCKSv5 proxy server error." +msgstr "ئىچكى SOCKSv5 ۋاكالەتچى Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø± خاتا." + +#: ../gio/gsocks5proxy.c:363 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "قائىدە SOCKSv5 باغلىنىشى ئىشلىتىشكە يول قويمايدۇ." + +#: ../gio/gsocks5proxy.c:370 +msgid "Host unreachable through SOCKSv5 server." +msgstr "SOCKSv5 Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø±Ù‰Ø¯Ù‰Ù† باش ئاپپاراتنى كۆرگىلى بولمايدۇ" + +#: ../gio/gsocks5proxy.c:376 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "SOCKSv5 ۋاكالەتچى Ù…Û‡Ù„Ø§Ø²Ù‰Ù…ÛØªÙ‰Ø±Ù‰Ø¯Ù‰Ù† تور كۆرۈنمىدى." + +#: ../gio/gsocks5proxy.c:382 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "SOCKSv5 ئارقىلىق باغلىنىش رەت قىلىندى." + +#: ../gio/gsocks5proxy.c:388 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 ۋاكالەتچى 'connect' بۇيرۇقىنى قوللىمايدۇ." + +#: ../gio/gsocks5proxy.c:394 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 ۋاكالەتچى تەمىنلەنگەن Ø¦Ø§Ø¯Ø±ÛØ³ تىپىنى قوللىمايدۇ." + +#: ../gio/gsocks5proxy.c:400 +msgid "Unknown SOCKSv5 proxy error." +msgstr "نامەلۇم SOCKSv5 ۋاكالەتچى خاتالىقى." + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "GThemedIcon كودلاشنىڭ %d نەشرىنى بىر تەرەپ قىلالمايدۇ" + +#: ../gio/gthreadedresolver.c:110 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "‹%s› خاتا تەھلىلى: %s" + +#: ../gio/gthreadedresolver.c:195 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "‹%s› ئەكسى تەھلىل خاتالىقى: %s" + +#: ../gio/gthreadedresolver.c:397 ../gio/gthreadedresolver.c:571 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "ئىلتىماس قىلىنغان تىپ ‹%s› غا ماس ÙƒÛلىدىغان DNS خاتىرىسى يوق" + +#: ../gio/gthreadedresolver.c:402 ../gio/gthreadedresolver.c:576 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "‹%s› ۋاقىتلىق تەھلىل قىلالمايدۇ" + +#: ../gio/gthreadedresolver.c:407 ../gio/gthreadedresolver.c:581 +#, c-format +msgid "Error resolving '%s'" +msgstr "‹%s› تەھلىل قىلىۋاتقاندا خاتالىق كۆرۈلدى" + +#: ../gio/gtlscertificate.c:248 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM بىلەن كودلانغان شەخسىي ئاچقۇچنى شىÙىرسىزلىغىلى بولمىدى" + +#: ../gio/gtlscertificate.c:253 +msgid "No PEM-encoded private key found" +msgstr "PEM بىلەن كودلانغان شەخسىي ئاچقۇچ تÛپىلمىدى" + +#: ../gio/gtlscertificate.c:263 +msgid "Could not parse PEM-encoded private key" +msgstr "PEM بىلەن كودلانغان شەخسىي ئاچقۇچنى ÙŠÛØ´Û•لمىدى" + +#: ../gio/gtlscertificate.c:288 +msgid "No PEM-encoded certificate found" +msgstr "PEM بىلەن كودلانغان گۇۋاھنامە تÛپىلمىدى" + +#: ../gio/gtlscertificate.c:297 +msgid "Could not parse PEM-encoded certificate" +msgstr "PEM بىلەن كودلانغان گۇۋاھنامىنى ÙŠÛØ´Û•لمىدى" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "بۇ سىزنىڭ ئەڭ ئاخىرقى پۇرسىتىڭىز. ÙŠÛ•Ù†Û• خاتالاشسىڭىز قۇلۇپلىنىپ قالىدۇ." + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "بىر قانچە Ù‚ÛØªÙ‰Ù… خاتالاشتىڭىز. ÙŠÛ•Ù†Û• خاتالاشسىڭىز قۇلۇپلىنىپ قالىدۇ." + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "كىرگۈزگەن ئىم توغرا ئەمەس." + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:548 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "تىزگىن ئۇچۇرىدىن بىرنى ئۈمىد قىلغان ئەمما %d غا Ø¦ÛØ±Ù‰Ø´ØªÙ‰" + +#: ../gio/gunixconnection.c:172 ../gio/gunixconnection.c:558 +msgid "Unexpected type of ancillary data" +msgstr "ئويلىشىلمىغان قوشۇمچە سانلىق-مەلۇمات تىپى" + +#: ../gio/gunixconnection.c:190 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "ھۆججەت چۈشەندۈرۈش بەلگىسىدىن بىرنى ئۈمىد قىلغان ئەمما %d غا Ø¦ÛØ±Ù‰Ø´ØªÙ‰\n" + +#: ../gio/gunixconnection.c:206 +msgid "Received invalid fd" +msgstr "ئىناۋەتسىز ھۆججەت چۈشەندۈرۈش بەلگىسى تاپشۇرۇۋالدى" + +#: ../gio/gunixconnection.c:342 +msgid "Error sending credentials: " +msgstr "ئىسپاتنامە يوللاش خاتالىقى: " + +#: ../gio/gunixconnection.c:490 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "ئوقۇر SO_PASSCRED نى قوزغاتقان ياكى قوزغاتمىغانلىقىنى تەكشۈرۈۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gunixconnection.c:505 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED نى قوزغىتىۋاتقاندا(ئىناۋەتلىك قىلىۋاتقاندا)خاتالىق كۆرۈلدى: %s" + +#: ../gio/gunixconnection.c:534 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "قوبۇللىغان ئىسپاتنامىگە بىر بايت ئوقۇشنى ئۈمىد قىلغان ئەمما 0 بايت ئوقۇدى" + +#: ../gio/gunixconnection.c:572 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "تىزگىن ئۇچۇرىنى ئۈمىد قىلمىغان ئىدى، ئەمما %d غا Ø¦ÛØ±Ù‰Ø´ØªÙ‰" + +#: ../gio/gunixconnection.c:596 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "SO_PASSCRED نى چەكلەۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gunixinputstream.c:382 ../gio/gunixinputstream.c:403 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "ھۆججەت چۈشەندۈرگۈچتىن ئوقۇشتا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gunixinputstream.c:436 ../gio/gunixoutputstream.c:422 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "ھۆججەت چۈشەندۈرگۈچنى ÙŠÛپىشتا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gunixmounts.c:1983 ../gio/gunixmounts.c:2036 +msgid "Filesystem root" +msgstr "ھۆججەت سىستÛمىسى غولى" + +#: ../gio/gunixoutputstream.c:368 ../gio/gunixoutputstream.c:389 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "ھۆججەت چۈشەندۈرگۈچكە ÙŠÛØ²Ù‰Ø´ØªØ§ خاتالىق كۆرۈلدى: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "بۇ سىستÛما ئابستراكت unix دائىرە ئوقۇر Ø¦Ø§Ø¯Ø±ÛØ³Ù‰Ù†Ù‰ قوللىمايدۇ" + +#: ../gio/gvolume.c:439 +msgid "volume doesn't implement eject" +msgstr "دىسكىنى قاڭقىتالمىدى" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:516 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "دىسكىغا eject ياكى eject_with_operation نى ئىجرا قىلالمىدى" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "پروگراممىنى تاپقىلى بولمىدى" + +#: ../gio/gwin32appinfo.c:308 +#, c-format +msgid "Error launching application: %s" +msgstr "پروگراممىنى ئىجرا قىلىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gwin32appinfo.c:344 +msgid "URIs not supported" +msgstr "URI نى قوللىمايدۇ" + +#: ../gio/gwin32appinfo.c:366 +msgid "association changes not supported on win32" +msgstr "win32 باغلىنىشلىق ئۆزگەرتىشنى قوللىمايدۇ" + +#: ../gio/gwin32appinfo.c:378 +msgid "Association creation not supported on win32" +msgstr "win32 باغلىنىشلىق قۇرۇشنى قوللىمايدۇ" + +#: ../gio/gwin32inputstream.c:355 +#, c-format +msgid "Error reading from handle: %s" +msgstr "handle دىن ئوقۇۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../gio/gwin32inputstream.c:387 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "تۇتقا ÙŠÛپىش خاتالىقى: %s" + +#: ../gio/gwin32outputstream.c:343 +#, c-format +msgid "Error writing to handle: %s" +msgstr "تۇتقا ÙŠÛØ²Ù‰Ø´ خاتالىقى: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "ÙŠÛØªÛ•رلىك ئەسلەك يوق" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "ئىچكى خاتالىق: %s" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "ØªÛØ®Ù‰Ù…Û‡ ÙƒÛ†Ù¾ كىرگۈزۈشكە ئÛھتىياجلىق" + +#: ../gio/gzlibdecompressor.c:342 +msgid "Invalid compressed data" +msgstr "ئىناۋەتسىز Ù¾Ø±ÛØ³Ù„انغان سانلىق-مەلۇمات" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "تىڭشايدىغان Ø¦Ø§Ø¯Ø±ÛØ³" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³Ù‰Ù†Ù‰ Ø¨ÛØ³Ù‰Ø´" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Ø¦Ø§Ø¯Ø±ÛØ³Ù‰Ù†Ù‰ shell ھالەتتە باسىدۇ" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "بىر دانە dbus مۇلازىمىتىنى ئىجرا قىلىدۇ" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "خاتا Ù¾Ø§Ø±Ø§Ù…ÛØªÙ‰Ø±Ù„ار\n" + +#: ../glib/gbookmarkfile.c:760 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "«%2$s» ئÛÙ„ÛÙ…Ûنتنىڭ ئويلىشىلمىغان خاسلىقى «%1$s»" + +#: ../glib/gbookmarkfile.c:771 ../glib/gbookmarkfile.c:842 +#: ../glib/gbookmarkfile.c:852 ../glib/gbookmarkfile.c:959 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "«%2$s» ئÛÙ„ÛÙ…Ûنتنىڭ خاسلىقى «%1$s» تÛپىلمىدى" + +#: ../glib/gbookmarkfile.c:1129 ../glib/gbookmarkfile.c:1194 +#: ../glib/gbookmarkfile.c:1258 ../glib/gbookmarkfile.c:1268 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "ئويلىشىلمىغان بەلگە ‹%s›، بەلگە ‹%s› زۆرۈر" + +#: ../glib/gbookmarkfile.c:1154 ../glib/gbookmarkfile.c:1168 +#: ../glib/gbookmarkfile.c:1236 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "«%2$s» دىكى ئويلىشىلمىغان بەلگە «%1$s»" + +#: ../glib/gbookmarkfile.c:1798 +msgid "No valid bookmark file found in data dirs" +msgstr "سانلىق-مەلۇمات مۇندەرىجىسىدە ئىناۋەتلىك خەتكۈش ھۆججىتى تÛپىلمىدى" + +#: ../glib/gbookmarkfile.c:1999 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI ‹%s› نىڭ خەتكۈچى مەۋجۇت" + +#: ../glib/gbookmarkfile.c:2045 ../glib/gbookmarkfile.c:2203 +#: ../glib/gbookmarkfile.c:2288 ../glib/gbookmarkfile.c:2368 +#: ../glib/gbookmarkfile.c:2453 ../glib/gbookmarkfile.c:2536 +#: ../glib/gbookmarkfile.c:2614 ../glib/gbookmarkfile.c:2693 +#: ../glib/gbookmarkfile.c:2735 ../glib/gbookmarkfile.c:2832 +#: ../glib/gbookmarkfile.c:2952 ../glib/gbookmarkfile.c:3142 +#: ../glib/gbookmarkfile.c:3218 ../glib/gbookmarkfile.c:3386 +#: ../glib/gbookmarkfile.c:3475 ../glib/gbookmarkfile.c:3565 +#: ../glib/gbookmarkfile.c:3693 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "URI ‹%s› نىڭ خەتكۈچى تÛپىلمىدى" + +#: ../glib/gbookmarkfile.c:2377 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI ‹%s› نىڭ خەتكۈچى MIME تىپىنى بەلگىلىمىگەن" + +#: ../glib/gbookmarkfile.c:2462 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI ‹%s› نىڭ خەتكۈچى شەخسىي تۇغنى بەلگىلىمىگەن" + +#: ../glib/gbookmarkfile.c:2841 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI ‹%s› نىڭ خەتكۈچى گۇرۇپپا بەلگىلىمىگەن" + +#: ../glib/gbookmarkfile.c:3239 ../glib/gbookmarkfile.c:3396 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "‹%s› ئاتلىق پروگرامما ‹%s› غا خەتكۈش خەتلەتمىگەن" + +#: ../glib/gbookmarkfile.c:3419 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "URI '%2$s' ئارقىلىق exec قۇر '%1$s' نى يايالمىدى" + +#: ../glib/gconvert.c:803 ../glib/gutf8.c:829 ../glib/gutf8.c:1039 +#: ../glib/gutf8.c:1176 ../glib/gutf8.c:1280 +msgid "Partial character sequence at end of input" +msgstr "كىرگۈزۈشنىڭ ئاخىرىدا تاماملانمىغان ھەرپ قاتارى كۆرۈلدى" + +#: ../glib/gconvert.c:1053 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "زاپاس ھەرپ بەلگە توپلىمى ‹%s›نى ‹%s› غا ئايلاندۇرالمايدۇ" + +#: ../glib/gconvert.c:1871 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI ‹%s› بولسا \"file\" Ùورماتىدىكى مۇتلەق URI ئەمەس" + +#: ../glib/gconvert.c:1881 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "يەرلىك ھۆججەت URI ‹%s› دا '#' نى ئۆز ئىچىگە ئالمايدۇ" + +#: ../glib/gconvert.c:1898 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "بۇ URI ‹%s› ئىناۋەتسىز" + +#: ../glib/gconvert.c:1910 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI دىكى ماشىنا ئاتى ‹%s› ئىناۋەتسىز" + +#: ../glib/gconvert.c:1926 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI ‹%s› دا ئىناۋەتسىز بولغان ÙƒÛ†Ú†Ù…Û• مەنىدىكى ھەرپ بار" + +#: ../glib/gconvert.c:2021 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "‹%s› يول ئىسمى مۇتلەق يول ئەمەس" + +#: ../glib/gconvert.c:2031 +msgid "Invalid hostname" +msgstr "باش ماشىنا ئاتى ئىناۋەتسىز" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:205 +msgctxt "GDateTime" +msgid "AM" +msgstr "Ú† ب" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "PM" +msgstr "Ú† Ùƒ" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Y-%m-%dT%T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d-%m-%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:219 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%-I:%M:%S %p" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "January" +msgstr "قەھرىتان" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "February" +msgstr "ھۇت" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "March" +msgstr "نەۋرۇز" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "April" +msgstr "ئۈمىد" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "May" +msgstr "باھار" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "June" +msgstr "سەپەر" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "July" +msgstr "چىللە" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "August" +msgstr "تومۇز" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "September" +msgstr "مىزان" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "October" +msgstr "ئوغۇز" + +#: ../glib/gdatetime.c:252 +msgctxt "full month name" +msgid "November" +msgstr "ئوغلاق" + +#: ../glib/gdatetime.c:254 +msgctxt "full month name" +msgid "December" +msgstr "ÙƒÛ†Ù†Û•Ùƒ" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "قەھرىتان" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "ھۇت" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "نەۋرۇز" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "ئومۇت" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "May" +msgstr "باھار" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "سەپەر" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "چىللە" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "تومۇز" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "مىزان" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "ئوغۇز" + +#: ../glib/gdatetime.c:289 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "ئوغلاق" + +#: ../glib/gdatetime.c:291 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "ÙƒÛ†Ù†Û•Ùƒ" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Monday" +msgstr "دۈشەنبە" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "سەيشەنبە" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "چارشەنبە" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "پەيشەنبە" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Friday" +msgstr "جۈمە" + +#: ../glib/gdatetime.c:316 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "شەنبە" + +#: ../glib/gdatetime.c:318 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "يەكشەنبە" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "د" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "س" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Ú†" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Ù¾" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "ج" + +#: ../glib/gdatetime.c:343 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Ø´" + +#: ../glib/gdatetime.c:345 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "ÙŠ" + +#: ../glib/gdir.c:120 ../glib/gdir.c:143 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "مۇندەرىجە ‹%s› نى ئÛچىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#: ../glib/gfileutils.c:671 ../glib/gfileutils.c:759 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "%lu بايت تەقسىملىيەلمىدى(ھۆججەت «%s» نى ئوقۇش ئۈچۈن)" + +#: ../glib/gfileutils.c:686 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "ھۆججەت ‹%s› ئوقۇشتا خاتالىق كۆرۈلدى: %s" + +#: ../glib/gfileutils.c:700 +#, c-format +msgid "File \"%s\" is too large" +msgstr "ھۆججەت «%s» بەك Ú†ÙˆÚ­" + +#: ../glib/gfileutils.c:783 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "ھۆججەت ‹%s› دىن ئوقۇش مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:834 ../glib/gfileutils.c:921 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "ھۆججەت «%s» نى ئاچالمىدى: %s" + +#: ../glib/gfileutils.c:851 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "ھۆججەت ‹%s› نىڭ خاسلىقلىرىغا Ø¦ÛØ±Ù‰Ø´Ù‰Ø´ مەغلۇپ بولدى:fstat() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:885 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "ھۆججەت ‹%s› نى ئÛچىش مەغلۇپ بولدى: fdopen() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:993 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "ئاتىنى ‹%s› دىن ‹%s› غا ئۆزگەرتىش مەغلۇپ بولدى: g_rename() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:1035 ../glib/gfileutils.c:1593 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "ھۆججەت ‹%s› قۇرۇش مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:1049 +#, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "‹%s› ھۆججەتنى ئÛچىپ يازالمىدى: fdopen() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:1074 +#, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "ھۆججەت ‹%s› نى ÙŠÛØ²Ù‰Ø´ مەغلۇپ بولدى: fwrite() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:1093 +#, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "ھۆججەت ‹%s› نى ÙŠÛØ²Ù‰Ø´ مەغلۇپ بولدى: fflush() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:1137 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "ھۆججەت ‹%s› نى ÙŠÛØ²Ù‰Ø´ مەغلۇپ بولدى: fsync() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:1161 +#, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "ھۆججەت ‹%s› نى ÙŠÛپىش مەغلۇپ بولدى: fclose() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:1282 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "‹%s› مەۋجۇت ھۆججەتنى Ú†Ù‰Ù‚Ù‰Ø±Ù‰Û‹ÛØªÛ•لمەيدۇ: g_unlink() مەغلۇپ بولدى: %s" + +#: ../glib/gfileutils.c:1556 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "‹%s› Ù‚Ûلىپ ئىناۋەتسىز، ‹%s› نى ئۆز ئىچىگە ئالمايدۇ." + +#: ../glib/gfileutils.c:1569 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "‹%s› Ù‚Ûلىپ XXXXXX نى ئۆز ئىچىگە ئالمايدۇ" + +#: ../glib/gfileutils.c:2097 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "بەلگە ئۇلانمىسى ‹%s› نى ئوقۇيالمىدى: %s" + +#: ../glib/gfileutils.c:2118 +msgid "Symbolic links not supported" +msgstr "بەلگە ئۇلانمىسىنى قوللىمايدۇ" + +#: ../glib/giochannel.c:1418 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "‹%s› دىن ‹%s› غا ئايلاندۇرغۇچنى ئاچالمايدۇ: %s" + +#: ../glib/giochannel.c:1763 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string Ùۇنكسىيىسى ئەسلى Ù¾ÛØªÙ‰ ئوقۇيالمىدى" + +#: ../glib/giochannel.c:1810 ../glib/giochannel.c:2068 +#: ../glib/giochannel.c:2155 +msgid "Leftover unconverted data in read buffer" +msgstr "يىغلەكتە ساقلىنىپ قالغان ئايلاندۇرۇلمىغان سانلىق-مەلۇماتنى ئوقۇۋاتىدۇ" + +#: ../glib/giochannel.c:1891 ../glib/giochannel.c:1968 +msgid "Channel terminates in a partial character" +msgstr "قانال ئاخىرلاشمىغان ھەرپتە توختىدى" + +#: ../glib/giochannel.c:1954 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end Ùۇنكسىيىسى ئەسلى Ù¾ÛØªÙ‰ ئوقۇيالمىدى" + +#: ../glib/gkeyfile.c:722 +msgid "Valid key file could not be found in search dirs" +msgstr "ئىزدەش مۇندەرىجىسىدە ئىناۋەتلىك ئاچقۇچ ھۆججىتىنى تاپالمىدى" + +#: ../glib/gkeyfile.c:758 +msgid "Not a regular file" +msgstr "ئادەتتىكى ھۆججەت ئەمەس" + +#: ../glib/gkeyfile.c:1158 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "ئاچقۇچ ھۆججەتتىكى قۇر ‹%s› ئاچقۇچ-قىممەت جۈپى، گۇرۇپپا ياكى ئىزاھات ئەمەس" + +#: ../glib/gkeyfile.c:1215 +#, c-format +msgid "Invalid group name: %s" +msgstr "ئىناۋەتسىز گۇرۇپپا ئاتى: %s" + +#: ../glib/gkeyfile.c:1237 +msgid "Key file does not start with a group" +msgstr "ئاچقۇچ ھۆججەت گۇرۇپپىدىن باشلانمايدۇ" + +#: ../glib/gkeyfile.c:1263 +#, c-format +msgid "Invalid key name: %s" +msgstr "ئاچقۇچ ئاتى ئىناۋەتسىز: %s" + +#: ../glib/gkeyfile.c:1290 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "ئاچقۇچ ھۆججەت قوللىمايدىغان كودلاش ‹%s› نى ئۆز ئىچىگە ئالغان" + +#: ../glib/gkeyfile.c:1533 ../glib/gkeyfile.c:1695 ../glib/gkeyfile.c:3073 +#: ../glib/gkeyfile.c:3139 ../glib/gkeyfile.c:3265 ../glib/gkeyfile.c:3398 +#: ../glib/gkeyfile.c:3540 ../glib/gkeyfile.c:3770 ../glib/gkeyfile.c:3837 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "ئاچقۇچ ھۆججەتنىڭ گۇرۇپپا ‹%s› سى يوق" + +#: ../glib/gkeyfile.c:1707 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "ئاچقۇچ ھۆججەتتە ‹%s› ئاچقۇچ يوق" + +#: ../glib/gkeyfile.c:1814 ../glib/gkeyfile.c:1930 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "ئاچقۇچ ھۆججەت ‹%s› ئاچقۇچىنى ئۆز ئىچىگە ئالغان، ئۇنىڭ قىممىتى ‹%s› بولسا UTF-8 ئەمەس" + +#: ../glib/gkeyfile.c:1834 ../glib/gkeyfile.c:1950 ../glib/gkeyfile.c:2319 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "ئاچقۇچ ھۆججەت ‹%s› ئاچقۇچىنى ئۆز ئىچىگە ئالغان، ئۇنىڭ قىممىتىنى ئىزاھلىيالمىدى." + +#: ../glib/gkeyfile.c:2536 ../glib/gkeyfile.c:2902 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "ئاچقۇچ ھۆججەتنىڭ «%2$s» گۇرۇپپىسىدىكى ئاچقۇچ «%1$s» نىڭ قىممىتىنى ئىزاھلىغىلى بولمىدى" + +#: ../glib/gkeyfile.c:2614 ../glib/gkeyfile.c:2690 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "ئاچقۇچ ‹%s› (گۇرۇپپا ‹%s› دىكى) نىڭ قىممىتى ‹%s› ئىكەن، ‹%s› بولسا بولاتتى" + +#: ../glib/gkeyfile.c:3088 ../glib/gkeyfile.c:3280 ../glib/gkeyfile.c:3848 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "ئاچقۇچ ھۆججەتنىڭ «%2$s» گۇرۇپپىسىدا «%1$s» ئاچقۇچىنى ئۆز ئىچىگە ئالغان" + +#: ../glib/gkeyfile.c:4080 +msgid "Key file contains escape character at end of line" +msgstr "ئاچقۇچ ھۆججەت قۇر ئاخىرىدا ÙƒÛ†Ú†Ù…Û• مەنىدىكى ھەرپ بار" + +#: ../glib/gkeyfile.c:4102 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "ئاچقۇچ ھۆججەتتە ئىناۋەتسىز ÙƒÛ†Ú†Ù…Û• مەنىدىكى تەرتىپ ‹%s› نى ئۆز ئىچىگە ئالغان" + +#: ../glib/gkeyfile.c:4244 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "‹%s› قىممەتنى سان دەپ ئىزاھلىيالمىدى." + +#: ../glib/gkeyfile.c:4258 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "پۈتۈن سان قىممىتى ‹%s› چەكتىن Ø¦ÛØ´Ù‰Ù¾ كەتتى" + +#: ../glib/gkeyfile.c:4291 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "‹%s› قىممەتنى لەيلىمە سان دەپ ئىزاھلىيالمىدى." + +#: ../glib/gkeyfile.c:4315 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "‹%s› قىممەتنى بۇلىئان قىممىتى دەپ ئىزاھلىيالمىدى." + +#: ../glib/gmappedfile.c:130 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "ھۆججەت ‹%s%s%s%s› نىڭ خاسلىقلىرىغا Ø¦ÛØ±Ù‰Ø´Ù‰Ø´ مەغلۇپ بولدى:fstat() مەغلۇپ بولدى: %s" + +#: ../glib/gmappedfile.c:196 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "%s%s%s%s غا خەرىتىلىيەلمىدى: mmap() مەغلۇپ بولدى: %s" + +#: ../glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "ھۆججەت ‹%s› نى ئÛچىش مەغلۇپ بولدى: open() مەغلۇپ بولدى: %s" + +#: ../glib/gmarkup.c:397 ../glib/gmarkup.c:439 +#, c-format +msgid "Error on line %d char %d: " +msgstr "قۇر %d ھەرپ %d دىكى خاتالىق: " + +#: ../glib/gmarkup.c:461 ../glib/gmarkup.c:544 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "ئىناۋەتسىز UTF-8 بىلەن كودلانغان تÛكىست ئاتىدا - ‹%s› ئىناۋەتسىز" + +#: ../glib/gmarkup.c:472 +#, c-format +msgid "'%s' is not a valid name" +msgstr "‹%s› ئىناۋەتلىك ئات ئەمەس" + +#: ../glib/gmarkup.c:488 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "‹%s› ئىناۋەتلىك ئات ئەمەس: '%c'" + +#: ../glib/gmarkup.c:598 +#, c-format +msgid "Error on line %d: %s" +msgstr "قۇر %d دىكى خاتالىق:%s" + +#: ../glib/gmarkup.c:682 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "'%-.*s' نى تەھلىل قىلىش مەغلۇپ بولدى، ئۇ ھەرپ نەقىلىدىكى سان (مەسىلەن، ê) - بەلكىم ئۇ سان بەك Ú†ÙˆÚ­ بولۇپ كەتكەن بولۇشى مۇمكىن" + +#: ../glib/gmarkup.c:694 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "ھەرپ نەقىلى Ú†Ûكىتلىك Ù¾Û•Ø´ بىلەن ئاخىرلاشمىغان؛ بەلكىم ئەمەلىي گەۋدە ئىشلەتمەي & بەلگىسى ئىشلەتكەن بولۇشىڭىز ئÛھتىمالغا بەك ÙŠÛقىن - بۇ & غا ئۆزگىرىدۇ" + +#: ../glib/gmarkup.c:720 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "ھەرپ نەقىلى '%-.*s' يول قويۇلغان كودلاش ئەمەس" + +#: ../glib/gmarkup.c:758 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "بوش ئەمەلىي گەۋدە '&;' بايقالدى. ئىناۋەتلىك ئەمەلىي گەۋدە: & " < > '" + +#: ../glib/gmarkup.c:766 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "نامەلۇم ئەمەلىي گەۋدە ئاتى '%-.*s'" + +#: ../glib/gmarkup.c:771 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "ئەمەلىي گەۋدە Ú†Ûكىتلىك Ù¾Û•Ø´ بىلەن ئاخىرلاشمىغان. سىز ئەمەلىي گەۋدە ئىشلەتمەي & بەلگىسى ئىشلەتكەن بولۇشىڭىز ئÛھتىمالغا ÙŠÛقىن - & بۇ & غا ئۆزگىرىدۇ" + +#: ../glib/gmarkup.c:1119 +msgid "Document must begin with an element (e.g. )" +msgstr "پۈتۈك چوقۇم بىر ئÛÙ„ÛÙ…Ûنت بىلەن باشلىنىشى ÙƒÛØ±Û•Ùƒ(مەسىلەن دÛگەندەك)" + +#: ../glib/gmarkup.c:1159 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "‹%s› ھەرپ '<' نىڭ ئارقىسىدا كۆرۈلسە ئىناۋەتسىز ھەرپ؛ ئۇ ئÛÙ„ÛÙ…Ûنتنىڭ Ø¨ÛØ´Ù‰ بولالمايدۇ" + +#: ../glib/gmarkup.c:1227 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "‹%s› ھەرپ ئىناۋەتسىز، '>' بەلگىسى بىلەن بوش ئÛÙ„ÛÙ…Ûنت بەلگىسى ‹%s› نى ئاخىرلاشتۇرىدۇ" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "‹%s› ھەرپ ئىناۋەتسىز، خاسلىق ئاتى‹%s› (ئÛÙ„ÛÙ…Ûنت ‹%s›) نىڭ كەينىدە '=' ھەرپ بولىدۇ" + +#: ../glib/gmarkup.c:1352 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "‹%s› ھەرپ ئىناۋەتسىز، باشلىنىش بەلگىسى ‹%s› ئÛÙ„ÛÙ…Ûنت '>' ياكى '/' بىلەن ئاخىرلىشىدۇ ياكى Ø´Û‡ ئÛÙ„ÛÙ…Ûنتنىڭ خاسلىقى ئەگىشىپ ÙƒÛلىدۇ؛ بەلكىم خاسلىق ئاتىدا ئىناۋەتسىز ھەرپ ئىشلەتكەن بولۇشىڭىز مۇمكىن" + +#: ../glib/gmarkup.c:1396 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "‹%s› ھەرپ ئىناۋەتسىز، خاسلىق ‹%s› (ئÛÙ„ÛÙ…Ûنت ‹%s›)قا قىممەت بەرگەندە، تەڭلىك بەلگىسىنىڭ ئارقىسىدا قوش Ù¾Û•Ø´ ÙƒÛلىدۇ" + +#: ../glib/gmarkup.c:1529 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "‹%s› ئاخىرلاشقان ئÛÙ„ÛÙ…Ûنت ئاتى ‹%s› نىڭ كەينىدە كۆرۈلسە ئىناۋەتسىز؛ يول قويىدىغان ھەرپ '>'" + +#: ../glib/gmarkup.c:1576 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "ئÛÙ„ÛÙ…Ûنت ‹%s› ÙŠÛپىلدى، بىراق ھازىر Ú¾Ûچقانداق ئÛÙ„ÛÙ…Ûنت ئÛچىلمىغان" + +#: ../glib/gmarkup.c:1585 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "ئÛÙ„ÛÙ…Ûنت ‹%s› ÙŠÛپىلدى، بىراق ھازىر ئÛÙ„ÛÙ…Ûنت ‹%s› ئÛچىلغان ئىدى" + +#: ../glib/gmarkup.c:1753 +msgid "Document was empty or contained only whitespace" +msgstr "پۈتۈك بوش ياكى ئۇنىڭدا بوشلۇق بەلگىلىرىلا بار" + +#: ../glib/gmarkup.c:1767 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "پۈتۈك ئÛچىلغان تىرناق '<' تىن ÙƒÛيىن تاسادىپىي ئاخىرلاشتى" + +#: ../glib/gmarkup.c:1775 ../glib/gmarkup.c:1820 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "پۈتۈك ØªÛØ®Ù‰ ئاخىرلاشمىغان ئÛÙ„ÛÙ…Ûنت مەۋجۇت ئەھۋالدا تاسادىپىي ئاخىرلاشتى - ئەڭ ئاخىرقى ئاخىرلاشمىغان ئÛÙ„ÛÙ…Ûنت ‹%s›" + +#: ../glib/gmarkup.c:1783 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "پۈتۈك تاسادىپىي ئاخىرلاشتى، ئوڭ تىرناق بىلەن بەلگە<%s/> ئاخىرلىشىشى ÙƒÛØ±Û•Ùƒ ئىدى" + +#: ../glib/gmarkup.c:1789 +msgid "Document ended unexpectedly inside an element name" +msgstr "پۈتۈك ئÛÙ„ÛÙ…Ûنت ئاتىدا تاسادىپىي ئاخىرلاشتى" + +#: ../glib/gmarkup.c:1795 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "پۈتۈك خاسلىق ئاتىدا تاسادىپىي ئاخىرلاشتى" + +#: ../glib/gmarkup.c:1800 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "پۈتۈك ئÛÙ„ÛÙ…Ûنت باشلاش بەلگىسىدە تاسادىپىي ئاخىرلاشتى." + +#: ../glib/gmarkup.c:1806 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "پۈتۈك خاسلىق ئاتىنىڭ ئارقىسىغا ئەگەشكەن تەڭلىك بەلگىسىدىن ÙƒÛيىن تاسادىپىي ئاخىرلاشتى؛ خاسلىق قىممىتى يوق" + +#: ../glib/gmarkup.c:1813 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "پۈتۈك خاسلىق قىممىتىدە تاسادىپىي ئاخىرلاشتى" + +#: ../glib/gmarkup.c:1829 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "پۈتۈك ئÛÙ„ÛÙ…Ûنت ‹%s› نىڭ ئاخىرلىشىش بەلگىسىدە تاسادىپىي ئاخىرلاشتى" + +#: ../glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "پۈتۈك ئىزاھات ياكى بۇيرۇقنى بىر تەرەپ قىلىۋاتقاندا تاسادىپىي ئاخىرلاشتى" + +#: ../glib/goption.c:754 +msgid "Usage:" +msgstr "ئىشلىتىش ئۇسۇلى:" + +#: ../glib/goption.c:754 +msgid "[OPTION...]" +msgstr "[تاللانما…]" + +#: ../glib/goption.c:864 +msgid "Help Options:" +msgstr "ياردەم تاللانمىسى:" + +#: ../glib/goption.c:865 +msgid "Show help options" +msgstr "ياردەم تاللانمىلىرىنى كۆرسەت" + +#: ../glib/goption.c:871 +msgid "Show all help options" +msgstr "ھەممە ياردەم تاللانمىلىرىنى كۆرسەت" + +#: ../glib/goption.c:933 +msgid "Application Options:" +msgstr "پروگرامما تاللانمىلىرى:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "%2$s ئىشلىتىدىغان پۈتۈن سان '%1$s' نى بىر تەرەپ قىلالمايدۇ" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%2$s ئىشلىتىدىغان پۈتۈن سان '%1$s' دائىرىدىن ھالقىپ كەتتى" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "%2$s ئىشلىتىدىغان قوش ئÛنىقلىقتىكى قىممەت '%1$s' نى بىر تەرەپ قىلالمايدۇ" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "%2$s ئىشلىتىدىغان قوش ئÛنىقلىقتىكى قىممەت '%1$s' دائىرىدىن ھالقىپ كەتتى" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, c-format +msgid "Error parsing option %s" +msgstr "تاللانما %s نى تەھلىل قىلىۋاتقاندا خاتالىق كۆرۈلدى" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "%s نىڭ ئەركىن ئۆزگەرگۈچىسى ÙƒÛ•Ù…" + +#: ../glib/goption.c:1979 +#, c-format +msgid "Unknown option %s" +msgstr "نامەلۇم تاللانما %s" + +#: ../glib/gregex.c:257 +msgid "corrupted object" +msgstr "ئىناۋەتسىز Ù†Û•Ú­" + +#: ../glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "ئىچكى خاتالىق ياكى ئىناۋەتسىز Ù†Û•Ú­" + +#: ../glib/gregex.c:261 +msgid "out of memory" +msgstr "ئەسلەك ÙŠÛØªÙ‰Ø´Ù…ىدى" + +#: ../glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "ئەسلىگە قايتىش Ú†Ûكىگە يەتتى" + +#: ../glib/gregex.c:278 ../glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "ئىپادە قىسمەن ماس كەلمەيدىغان قوللاش تۈرىنى ئۆز ئىچىگە ئالغان" + +#: ../glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "تولۇق ماس كەلمىگەندە شەرتنىڭ ئەسلىگە قايتىش نەقىلى سۈپىتىدە قوللىمايدۇ." + +#: ../glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "قايتىلانما جەريان Ú†Ûكىگە يەتتى" + +#: ../glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "ئىناۋەتسىز بولغان ÙŠÛÚ­Ù‰ قۇر بەلگىسىنىڭ بىرىكمىسى" + +#: ../glib/gregex.c:301 +msgid "bad offset" +msgstr "خاتا Ø¦ÛØºÙ‰Ø´" + +#: ../glib/gregex.c:303 +msgid "short utf8" +msgstr "قىسقا utf8" + +#: ../glib/gregex.c:305 +msgid "recursion loop" +msgstr "چوڭقۇرلاپ تەكرارلاش" + +#: ../glib/gregex.c:309 +msgid "unknown error" +msgstr "نامەلۇم خاتالىق" + +#: ../glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ ئىپادە ئاخىرىدا" + +#: ../glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c ئىپادە ئاخىرىدا" + +#: ../glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "\\ نىڭ كەينىدىكى ھەرپنى تونۇغىلى بولمىدى" + +#: ../glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "{} نىڭ ئىچىدىكى سانلارنىڭ تەرتىپى ئالمىشىپ Ù‚Ûلىپتۇ" + +#: ../glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "{} ئىچىدىكى سان بەك Ú†ÙˆÚ­" + +#: ../glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "] ھەرپ خىلىنىڭ تاماملىنىشى ÙƒÛ•Ù…" + +#: ../glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "ھەرپ خىلىدا ئىناۋەتسىز ÙƒÛ†Ú†Ù…Û• مەنىدىكى قاتار بار" + +#: ../glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "ھەرپ خىلىنىڭ دائىرە تەرتىپى ئالمىشىپ Ù‚Ûلىپتۇ" + +#: ../glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "تەكرارلايدىغان Ú¾ÛÚ†Ù†ÛÙ…Û• يوق" + +#: ../glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "تاسادىپىي تەكرارلىق" + +#: ../glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "(? نىڭ ياكى (?- كەينىدە تونۇيالمايدىغان ھەرپ بار" + +#: ../glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "پەقەت خىلدا POSIX ئاتاشتىكى خىلنىلا قوللايدۇ" + +#: ../glib/gregex.c:366 +msgid "missing terminating )" +msgstr "ئاخىرلىشىدىغان ) ÙƒÛ•Ù…" + +#: ../glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "مەۋجۇت بولمىغان تارماق ئىپادە نەقىل قىلىندى" + +#: ../glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "ئىزاھاتتىن ÙƒÛيىن ) ÙƒÛ•Ù…" + +#: ../glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "مۇنتىزىم ئىپادە بەك Ú†ÙˆÚ­" + +#: ../glib/gregex.c:378 +msgid "failed to get memory" +msgstr "ئەسلەككە Ø¦ÛØ±Ù‰Ø´Û•لمىدى" + +#: ../glib/gregex.c:382 +msgid ") without opening (" +msgstr ") ئÛچىلغان ( ÙƒÛ•Ù…" + +#: ../glib/gregex.c:386 +msgid "code overflow" +msgstr "كود ھالقىشى" + +#: ../glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "(?< نىڭ كەينىدە تونۇيالمايدىغان ھەرپ بار" + +#: ../glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind Ú¾Û†ÙƒÛˆÙ… مۇقىم ئۇزۇنلۇقتا ئەمەس" + +#: ../glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "(?( كەينىدە شەكلى خاتا بولغان سان ياكى ئات بار" + +#: ../glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "شەرت گۇرۇپپىسى ئىككىدىن ئارتۇق تارماقنى ئۆز ئىچىگە ئالغان" + +#: ../glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "(?( كەينىدە Ú¾Û†ÙƒÛˆÙ… بولۇشى لازىم" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R or (?[+-]سان چوقۇم ØŸ غا ئەگىشىدۇ)" + +#: ../glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "نامەلۇم ناتونۇش POSIX خىل ئاتى" + +#: ../glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "POSIX توپلانما ئÛÙ„ÛÙ…Ûنتنى قوللىمايدۇ" + +#: ../glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} قاتاردىكى ھەرپنىڭ قىممىتى بەك Ú†ÙˆÚ­" + +#: ../glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "ئىناۋەتسىز شەرت (?(0)" + +#: ../glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "lookbehind ھۆكۈمدە \\C ئىشلىتىشكە يول قويۇلمايدۇ" + +#: ../glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "بۇ \\LØŒ \\lØŒ \\N{name}ØŒ \\UØŒ Û‹Û• \\u لارنى قاچۇرۇشنى ئىشلەتكىلى بولمايدۇ" + +#: ../glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "قايتىلانما چاقىرىش چەكسىز دەۋرىيلىكنى كەلتۈرۈپ چىقارغان بولۇشى مۇمكىن" + +#: ../glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "(?P نىڭ كەينىدە تونۇيالمايدىغان ھەرپ بار" + +#: ../glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "تارماق ئىپادە ئاتىدا ئاخىرلاشتۇرۇش بەلگىسى ÙƒÛ•Ù…" + +#: ../glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "ئاتى بار ئىككى ئىپادە ئوخشاش ئاتلىق" + +#: ../glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "شەكلى خاتا \\P ياكى \\p قاتار" + +#: ../glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "\\P ياكى \\p نىڭ كەينىدە نامەلۇم خاسلىق ئاتى بار" + +#: ../glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "تارماق ئىپادە ئاتى بەك ئۇزۇن (ئەڭ ÙƒÛ†Ù¾ بولغاندا 32 ھەرپ)" + +#: ../glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "ئات بار ئىپادە بەك ÙƒÛ†Ù¾(ئەڭ ÙƒÛ†Ù¾ بولغاندا 10,000)" + +#: ../glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "سەككىزلىك سىستÛمىدىكى قىممىتى \\377 دىن Ú†ÙˆÚ­" + +#: ../glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "تەرجىمە خىزمەت رايونى دائىرىدىن ھالقىپ كەتتى" + +#: ../glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "ئىلگىرى تەكشۈرگەن نەقىل ئالغان تارماق ئىپادىنى تاپالمىدى" + +#: ../glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE گۇرۇپپا بىردىن ÙƒÛ†Ù¾ تارماقنى ئۆز ئىچىگە ئالغان" + +#: ../glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "زىددىيەتلىك NEWLINE تاللانما" + +#: ../glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" + +#: ../glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "رەقەملىك پايدىلانما Ù†Û†Ù„ بولسا بولمايدۇ" + +#: ../glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "ئادەتتە (*ACCEPT)ØŒ (*FAIL)ØŒ (*COMMIT) لارغا Ù¾Ø§Ø±Ø§Ù…ÛØªÙ‰Ø± ÙƒÛØ±Û•Ùƒ ئەمەس" + +#: ../glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) نى تونۇمايدۇ" + +#: ../glib/gregex.c:489 +msgid "number is too big" +msgstr "سان بەك Ú†ÙˆÚ­" + +#: ../glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "(?& نىڭ كەينىدىكى بالا ئەندىزە يوق" + +#: ../glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "(?+ نىڭ كەينىدە رەقەم بولۇشى ÙƒÛØ±Û•Ùƒ" + +#: ../glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "JavaScript بىلەن ماسلىشىشچان ھالەتتە ] بولسا ئىناۋەتسىز ھەرپ" + +#: ../glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ئوخشاش سانلارنىڭ قوشۇمچە ئەندىزىلىرىنىڭ ئاتلىرىنىڭ ھەر خىل بولۇشىغا يول قويۇلمايدۇ" + +#: ../glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "ئادەتتە (*MARK) نىڭ چوقۇم Ù¾Ø§Ø±Ø§Ù…ÛØªÙ‰Ø±Ù‰ بولۇشى ÙƒÛØ±Û•Ùƒ" + +#: ../glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "ئادەتتە \\c چوقۇم ASCII ھەرپىنىڭ كەينىگە ÙƒÛلىشى ÙƒÛØ±Û•Ùƒ" + +#: ../glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" + +#: ../glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "تىپ(class) تا \\N نى ئىشلەتكىلى بولمايدۇ" + +#: ../glib/gregex.c:516 +msgid "too many forward references" +msgstr "" + +#: ../glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "(*MARK)ØŒ (*PRUNE)ØŒ (*SKIP)ØŒ (*THEN) نىڭدىكى ئات بەك ئۇزۇن" + +#: ../glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... قاتارىدىكى ھەرپنىڭ قىممىتى بەك Ú†ÙˆÚ­" + +#: ../glib/gregex.c:745 ../glib/gregex.c:1899 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "مۇنتىزىم ئىپادە %s بىلەن ماسلىشىشتا خاتالىق كۆرۈلدى: %s" + +#: ../glib/gregex.c:1319 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE ئامبار تەرجىمە قىلغاندا UTF8 قوللاشنى ئۆز ئىچىگە ئالمىغان" + +#: ../glib/gregex.c:1323 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE ئامبار تەرجىمە قىلغاندا UTF8 خاسلىق قوللاشنى ئۆز ئىچىگە ئالمىغان" + +#: ../glib/gregex.c:1331 +msgid "PCRE library is compiled with incompatible options" +msgstr "بۇ PCRE ئامبىرى نۇرغۇن زىت(incompatible) تاللانمىلار بىلەن يۇغۇرۇلغان" + +#: ../glib/gregex.c:1390 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "%2$d ھەرپتىكى مۇنتىزىم ئىپادە %1$s نى تەرجىمە قىلغاندا خاتالىق كۆرۈلدى: %3$s" + +#: ../glib/gregex.c:1432 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "مۇنتىزىم ئىپادە %s نى ئەلالاشتۇرغاندا خاتالىق كۆرۈلدى: %s" + +#: ../glib/gregex.c:2331 +msgid "hexadecimal digit or '}' expected" +msgstr "ئون ئالتىلىك سىستÛمىدىكى سان ياكى '}' تەلەپ قىلىدۇ" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit expected" +msgstr "ئون ئالتىلىك سىستÛمىدىكى ساننى تەلەپ قىلىدۇ" + +#: ../glib/gregex.c:2387 +msgid "missing '<' in symbolic reference" +msgstr "بەلگە نەقىلىدە '<' ÙƒÛ•Ù…" + +#: ../glib/gregex.c:2396 +msgid "unfinished symbolic reference" +msgstr "تاماملانمىغان بەلگە نەقىل" + +#: ../glib/gregex.c:2403 +msgid "zero-length symbolic reference" +msgstr "Ù†Û†Ù„ كەڭلىكتىكى بەلگە نەقىل" + +#: ../glib/gregex.c:2414 +msgid "digit expected" +msgstr "رەقەم تەلەپ قىلىنىدۇ" + +#: ../glib/gregex.c:2432 +msgid "illegal symbolic reference" +msgstr "قانۇنسىز بەلگە نەقىلى" + +#: ../glib/gregex.c:2494 +msgid "stray final '\\'" +msgstr "ئەڭ ئاخىرقى '\\' يوقالغان" + +#: ../glib/gregex.c:2498 +msgid "unknown escape sequence" +msgstr "نامەلۇم ÙƒÛ†Ú†Ù…Û• مەنىلىك تەرتىپ" + +#: ../glib/gregex.c:2508 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "ئالماشتۇرىدىغان تÛكىست «%s» نى تەھلىل قىلغاندا %lu ھەرپتە خاتالىق كۆرۈلدى: %s" + +#: ../glib/gshell.c:88 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "نەقىل ئالغان تÛكىست نەقىل بەلگىسىدىن باشلانمىغان" + +#: ../glib/gshell.c:178 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "بۇيرۇق قۇرى ياكى باشقا shell نەقىل تÛكىستىدە ماسلاشمىغان نەقىل كۆرۈلدى" + +#: ../glib/gshell.c:574 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "تÛكىست '\\' ھەرپتىن ÙƒÛيىن ئاخىرلىشىدۇ.(تÛكىست ‹%s›)" + +#: ../glib/gshell.c:581 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "تÛكىست %c بىلەن ماسلىشىدىغان نەقىل بەلگىسىنى تÛپىشتىن ئىلگىرى ئاخىرلىشىدۇ.(تÛكىست ‹%s›)" + +#: ../glib/gshell.c:593 +msgid "Text was empty (or contained only whitespace)" +msgstr "تÛكىست بوش (ياكى بوش ھەرپنىلا ئۆز ئىچىگە ئالىدۇ)" + +#: ../glib/gspawn.c:203 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "(%s) تارماق ئىجرادىن سانلىق-مەلۇمات ئوقۇيالمىدى" + +#: ../glib/gspawn.c:362 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "ئىجرا (%s) دىن سانلىق-مەلۇمات ئوقۇۋاتقاندا select() دا تاسادىپىي خاتالىق كۆرۈلدى" + +#: ../glib/gspawn.c:853 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "بالا ئىجرا %ld دÛÚ¯Û•Ù† كود بىلەن Ú†Ûكىنىپ كەتتى" + +#: ../glib/gspawn.c:861 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "بالا ئىجرانى سىگنال %ld ئۆلتۈردى" + +#: ../glib/gspawn.c:868 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "بالا ئىجرانى سىگنال %ld توختاتتى" + +#: ../glib/gspawn.c:875 +#, c-format +msgid "Child process exited abnormally" +msgstr "بالا ئىجرا بىنورمال Ú†Ûكىنىپ كەتتى." + +#: ../glib/gspawn.c:1280 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "تارماق تۇرۇبىدىن ئوقۇيالمىدى (%s)" + +#: ../glib/gspawn.c:1348 +#, c-format +msgid "Failed to fork (%s)" +msgstr "(%s) نى ئاچىلاش مەغلۇپ بولدى" + +#: ../glib/gspawn.c:1496 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "مۇندەرىجە ‹%s› (%s)ئى ئۆزگەرتىش مەغلۇپ بولدى" + +#: ../glib/gspawn.c:1506 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "تارماق ئىجرا «%s» نى ئىجرا قىلالمىدى (%s)" + +#: ../glib/gspawn.c:1516 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "قايتا نىشانلانغان تارماق ئىجرا (%s)نىڭ كىرگۈزۈش ياكى چىقىرىشىدا خاتالىق كۆرۈلدى" + +#: ../glib/gspawn.c:1525 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "تارماق ئىجرا (%s) نى ئاچىلاش مەغلۇپ بولدى" + +#: ../glib/gspawn.c:1533 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "تارماق ئىجرا «%s» نى ئىجرا قىلغاندا نامەلۇم خاتالىق كۆرۈلدى" + +#: ../glib/gspawn.c:1557 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "تارماق تۇرۇبا (%s) دىن ÙŠÛØªÛ•رلىك سانلىق-مەلۇمات ئوقۇشتا خاتالىق كۆرۈلدى" + +#: ../glib/gspawn.c:1630 ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "تارماق ئىجرا بىلەن ئالاقە قىلىدىغان تۇرۇبا قۇرالمىدى (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "تارماق ئىجرادىن سانلىق-مەلۇمات ئوقۇيالمىدى" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "تارماق ئىجرانى ئىجرا قىلالمىدى (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "پروگرامما ئاتى ئىناۋەتسىز: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d دىكى Ù¾Ø§Ø±Ø§Ù…ÛØªÙ‰Ø±Ø¯Ø§ ئىناۋەتسىز تÛكىست بار: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "مۇھىتتىكى تÛكىست ئىناۋەتسىز: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "ئىناۋەتسىز خىزمەت مۇندەرىجىسى: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "ياردەمچى پروگرامما (%s) نى ئىجرا قىلالمىدى" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "g_io_channel_win32_poll() تارماق ئىجرادىن سانلىق-مەلۇمات ئوقۇۋاتقاندا تاسادىپىي خاتالىق كۆرۈلدى" + +#: ../glib/gutf8.c:907 +msgid "Character out of range for UTF-8" +msgstr "ھەرپ UTF-8 دائىرىسىدىن ھالقىپ كەتتى" + +#: ../glib/gutf8.c:1007 ../glib/gutf8.c:1016 ../glib/gutf8.c:1146 +#: ../glib/gutf8.c:1155 ../glib/gutf8.c:1294 ../glib/gutf8.c:1390 +msgid "Invalid sequence in conversion input" +msgstr "ئايلاندۇرۇپ كىرگۈزۈشتە ئىناۋەتسىز تەرتىپ كۆرۈلدى" + +#: ../glib/gutf8.c:1305 ../glib/gutf8.c:1401 +msgid "Character out of range for UTF-16" +msgstr "ھەرپ UTF-16 دائىرىسىدىن ھالقىپ كەتتى" + +#: ../glib/gutils.c:2183 ../glib/gutils.c:2210 ../glib/gutils.c:2314 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u بايت" + +#: ../glib/gutils.c:2189 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f كىلوبايت" + +#: ../glib/gutils.c:2191 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f Ù…Ûگابايت" + +#: ../glib/gutils.c:2194 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f گىگابايت" + +#: ../glib/gutils.c:2197 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f ØªÛØ±Ø§Ø¨Ø§ÙŠØª" + +#: ../glib/gutils.c:2200 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f Ù¾ÛØªØ§Ø¨Ø§ÙŠØª" + +#: ../glib/gutils.c:2203 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f ئÛكسابايت" + +#: ../glib/gutils.c:2216 +#, c-format +msgid "%.1f kB" +msgstr "%.1f كىلوبايت" + +#: ../glib/gutils.c:2219 ../glib/gutils.c:2332 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Ù…Ûگابايت" + +#: ../glib/gutils.c:2222 ../glib/gutils.c:2337 +#, c-format +msgid "%.1f GB" +msgstr "%.1f گىگابايت" + +#: ../glib/gutils.c:2224 ../glib/gutils.c:2342 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ØªÛØ±Ø§Ø¨Ø§ÙŠØª" + +#: ../glib/gutils.c:2227 ../glib/gutils.c:2347 +#, c-format +msgid "%.1f PB" +msgstr "%.1f Ù¾ÛØªØ§Ø¨Ø§ÙŠØª" + +#: ../glib/gutils.c:2230 ../glib/gutils.c:2352 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ئÛكسابايت" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2267 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s بايت" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2327 +#, c-format +msgid "%.1f KB" +msgstr "%.1f كىلوبايت" + +msgctxt "full month name with day" +msgid "January" +msgstr "قەھرىتان" + +msgctxt "full month name with day" +msgid "February" +msgstr "ھۇت" + +msgctxt "full month name with day" +msgid "March" +msgstr "نەۋرۇز" + +msgctxt "full month name with day" +msgid "April" +msgstr "ئۈمىد" + +msgctxt "full month name with day" +msgid "May" +msgstr "باھار" + +msgctxt "full month name with day" +msgid "June" +msgstr "سەپەر" + +msgctxt "full month name with day" +msgid "July" +msgstr "چىللە" + +msgctxt "full month name with day" +msgid "August" +msgstr "تومۇز" + +msgctxt "full month name with day" +msgid "September" +msgstr "مىزان" + +msgctxt "full month name with day" +msgid "October" +msgstr "ئوغۇز" + +msgctxt "full month name with day" +msgid "November" +msgstr "ئوغلاق" + +msgctxt "full month name with day" +msgid "December" +msgstr "ÙƒÛ†Ù†Û•Ùƒ" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "قەھرىتان" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "ھۇت" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "نەۋرۇز" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "ئومۇت" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "باھار" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "سەپەر" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "چىللە" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "تومۇز" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "مىزان" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "ئوغۇز" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "ئوغلاق" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "ÙƒÛ†Ù†Û•Ùƒ" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "بۇيرۇق '%s' بىنورمال پروگرامما توختىتىلدى: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "'%s' بۇيرۇق Ù†Û†Ù„ بولمىغان ھالەتتىكى سان %d Ú†Ûكىندى: %s" + +#~ msgid "No service record for '%s'" +#~ msgstr "'%s' نىڭ خاتىرىلەش مۇلازىمىتى يوق" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "ئوقۇر SO_PASSCRED نى قوزغاتقان ياكى قوزغاتمىغانلىقىنى تەكشۈرۈۋاتقاندا " +#~ "ئويلىشىلمىغان تاللانما ئۇزۇنلۇقى كۆرۈلدى. %d بايت ئۈمىد قىلغان ئەمما %d " +#~ "غا Ø¦ÛØ±Ù‰Ø´ØªÙ‰" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "بوش تارماق تÛكىستنىڭ خىزمەت بوشلۇقى Ú†Ûكىگە يەتتى" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "بۇ جايدا Ú†ÙˆÚ­ كىچىك ÙŠÛØ²Ù‰Ù„ىشنى ئالماشتۇرىدىغان بەلگە ئىشلىتىشكە يول قويمايدۇ" +#~ "(\\l, \\L, \\u, \\U)" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "DEFINE گۇرۇپپىنى تەكرارلاشقا يول قويۇلمايدۇ" + +#~ msgid "Unexpected error in waitpid() (%s)" +#~ msgstr "waitpid() دا تاسادىپىي خاتالىق كۆرۈلدى (%s)" + +#~ msgid "File is empty" +#~ msgstr "ھۆججەت بوش" + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "ئاچقۇچ ھۆججەت '%s' كۇنۇپكىنى ئۆز ئىچىگە ئالغان، ئۇنىڭ قىممىتىنى " +#~ "ئىزاھلىيالمىدى." + +#~ msgid "This option will be removed soon." +#~ msgstr "بۇ تاللانما پات ئارىدا ئۆچۈرۈلىدۇ." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "'%s' ھۆججەت ھالىتىگە Ø¦ÛØ±Ù‰Ø´Ù‰Û‹Ø§ØªÙ‚اندا خاتالىق كۆرۈلدى: %s" + +#~ msgid "Error connecting: " +#~ msgstr "باغلىنىۋاتقاندا خاتالىق كۆرۈلدى: " + +#~ msgid "Error connecting: %s" +#~ msgstr "باغلىنىشتا خاتالىق كۆرۈلدى: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "SOCKSv4 ئەمەلگە ئاشۇرۇشتا ئىشلەتكۈچى ئاتى %i ھەرپتە چەكلىنىدۇ" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKSv4 ئەمەلگە ئاشۇرۇشتا ماشىنا ئاتى %i ھەرپتە چەكلىنىدۇ" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "unix دىن ئوقۇۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "unix نى ÙŠÛپىۋاتقاندا خاتالىق كۆرۈلدى: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "unix قا ÙŠÛØ²Ù‰Û‹Ø§ØªÙ‚اندا خاتالىق كۆرۈلدى: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "Ú† ب" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "Ú† Ùƒ" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "قايتۇرغان قىممەت تىپى خاتا، Ø¦ÛØ±Ù‰Ø´Ù‰Ù„گىنى '%s'ØŒ ئۈمىد قىلىنغىنى '%s'" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "%s تىپنىڭ خاسلىقى %s نى تەڭشەشنى سىناۋاتىدۇ ئەمما ئۈمىد قىلغان Ø¦ÛØºÙ‰Ø² Û‹Û• " +#~ "تىپى %s" diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 0000000..548c0e9 --- /dev/null +++ b/po/uk.po @@ -0,0 +1,6381 @@ +# Ukrainian translation of GLIB library. +# Copyright (C) 2001-2004 Free Software Foundation, Inc. +# +# Yuri Syrota , 2001, 2004. +# Maxim Dziumanenko , 2004-2009. +# wanderlust , 2009. +# Mykola Tkach , 2014. +# Yuri Chornoivan , 2020, 2021, 2022. +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-03-22 15:19+0000\n" +"PO-Revision-Date: 2022-03-22 17:45+0200\n" +"Last-Translator: Yuri Chornoivan \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 20.12.0\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "Підтримки вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ñ— програми ще не передбачено" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "" +"Підтримки вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸, Ñк оÑтанньої викориÑтаної Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ñƒ, ще не " +"передбачено" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "Параметри GApplication" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "Показати параметри GApplication" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"ЗапуÑтити GApplication у режимі ÑервіÑу (викориÑтовувати з ÑервіÑних файлів " +"D-Bus)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "Перевизначити ідентифікатор програми" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "Замінити запущений екземплÑÑ€" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "Ðадрукувати довідку" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[КОМÐÐДÐ]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "ВивеÑти номер верÑÑ–Ñ—" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "ВивеÑти інформацію про верÑÑ–ÑŽ Ñ– вийти" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "ВивеÑти ÑпиÑок програм" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"ВивеÑти перелік вÑтановлених придатних до активації за D-Bus програм (за " +"файлами desktop)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "ЗапуÑтити програму" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "ЗапуÑтити програму (із необов'Ñзковим відкриттÑм файлів)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "ІД_ПРОГРÐМИ [ФÐЙЛ…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "Ðктивувати дію" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "Викликати дію програми" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "ІД_ПРОГРÐМИ ДІЯ [ПÐРÐМЕТР]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "ВивеÑти перелік доÑтупних дій" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "ВивеÑти перелік Ñтатичних дій Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸ (з desktop-файла)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "ІД_ПРОГРÐМИ" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "КОМÐÐДÐ" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "Команда, за Ñкою виводитьÑÑ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð° довідка" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Ідентифікатор програми у форматі D-Bus (напр.: org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "ФÐЙЛ" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "" +"Ðеобов'Ñзкові відноÑні або абÑолютні назви файлів чи адреÑи URI Ð´Ð»Ñ " +"відкриваннÑ" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "ДІЯ" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "Ðазва дії, Ñку Ñлід викликати" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "ПÐРÐМЕТР" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Ðеобов'Ñзковий параметр Ð´Ð»Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑƒ дії у форматі GVariant" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Ðевідома команда %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "ВикориÑтаннÑ:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "Ðргументи:\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ПÐРÐМЕТРИ…]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "Команди:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"СкориÑтайтеÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾ÑŽ «%s help КОМÐÐДл Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð¾Ñ— довідки.\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"команді %s потрібен ідентифікатор програми\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "некоректний ідентифікатор програми: «%s»\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"«%s» не приймає аргументів\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "неможливо під'єднатиÑÑ Ð´Ð¾ D-Bus: %s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "помилка надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ %s до програми %s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "назву дії Ñлід вказувати піÑÐ»Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ‚Ð¾Ñ€Ð° програми\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"некоректна назва дії: «%s»\n" +"Ðазва дії може ÑкладатиÑÑ Ð»Ð¸ÑˆÐµ з літер, цифр Ñ– Ñимволів «-» Ñ– «.»\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "помилка розбору параметра дії: %s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "дії приймають макÑимум один параметр\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "команда list-actions приймає лише ідентифікатор програми" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ desktop-файл Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸ %s\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"нерозпізнана команда %s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "До %s передано надто велике Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ°" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "Перехід у базовому потоці не підтримуєтьÑÑ" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Ðе вдалоÑÑ ÑƒÑ€Ñ–Ð·Ð°Ñ‚Ð¸ GMemoryInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "Потік вже закрито" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Ð£Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ Ñƒ базовому потоці" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1857 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "Операцію ÑкаÑовано" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Ðеправильний об'єкт, не ініціалізований" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Ðеправильна багатобайтова поÑлідовніÑть у перетворюваних вхідних даних" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Бракує проÑтору Ð´Ð»Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñƒ" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "Ðеправильна поÑлідовніÑть байтів у перетворюваних вхідних даних" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ: %s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "Ð†Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð· можливіÑтю ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "Підтримки Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð· набору Ñимволів «%s» у «%s» не передбачено" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ модуль Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð· «%s» у «%s»" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "тип %s" + +#: gio/gcontenttype-win32.c:196 +msgid "Unknown type" +msgstr "Ðевідомий тип" + +#: gio/gcontenttype-win32.c:198 +#, c-format +msgid "%s filetype" +msgstr "тип файлів %s" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "У GCredentials міÑÑ‚ÑтьÑÑ Ð½ÐµÐºÐ¾Ñ€ÐµÐºÑ‚Ð½Ñ– дані" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "Тип GCredentials не реалізовано Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— ОС" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "Підтримки GCredentials Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ñ— платформи не передбачено" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "Тип GCredentials не міÑтить ідентифікатора процеÑу Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— ОС" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Спуфінг облікових даних неможливий у цій ОС" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Ðеочікуваний передчаÑний кінець потоку" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "Ðепідтримуваний ключ «%s» у елементі адреÑи «%s»" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "БеззміÑтовна ÐºÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ–Ñ ÐºÐ»ÑŽÑ‡/Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ елементі адреÑи «%s»" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "" +"Ðеправильна адреÑа «%s» (потрібен шлÑÑ…, каталог, тимчаÑовий каталог або один " +"з абÑтрактних ключів)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "Помилка в адреÑÑ– «%s» — неправильне Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð° «%s»" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "Ðевідомий або непідтримуваний канал Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Â«%s» Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи «%s»" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "У елементі адреÑи «%s» немає двокрапки (:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "Ðазва каналу Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Ñƒ елементі адреÑи «%s» має бути непорожньою" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "" +"Пара ключ/Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %d, «%s», у елементі адреÑи «%s» не міÑтить знака рівноÑті" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "" +"Пара ключ/Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %d, «%s», у елементі адреÑи «%s» має міÑтити непорожній " +"ключ" + +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "" +"Помилка знÑÑ‚Ñ‚Ñ ÐµÐºÑ€Ð°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° або Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ парі ключ/Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %d, «%s», " +"у елементі адреÑи «%s»" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "" +"Помилка у адреÑÑ– «%s» — Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ñпорту unix потрібен лише один вÑтановлений " +"ключ «path» або «abstract»" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "" +"Помилка у адреÑÑ– «%s» — немає атрибута вузла або вказано Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ " +"помилковому форматі" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "" +"Помилка в адреÑÑ– «%s» — атрибут не вказано атрибут порту або помилкове " +"Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð°" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "" +"Помилка в адреÑÑ– «%s» — атрибут не вказано атрибут noncefile або помилкове " +"Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð°" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "Помилка автоматичного запуÑку: " + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при відкриванні nonce-файла «%s»: %s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при читанні nonce-файла «%s»: %s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "" +"СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при читанні nonce-файла «%s», очікувалоÑÑ 16 байтів, " +"отримано %d" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° запиÑу вміÑту nonce-файла «%s» до потоку:" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "Вказана адреÑа порожнÑ" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "Ðеможливо породити Ð¿Ñ€Ð¾Ñ†ÐµÑ ÑˆÐ¸Ð½Ð¸ повідомлень, Ñкщо вÑтановлено AT_SECURE" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Ðеможливо породити Ð¿Ñ€Ð¾Ñ†ÐµÑ ÑˆÐ¸Ð½Ð¸ повідомлень без ідентифікатора машини:" + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "Ðеможливо автоматично запуÑкати D-Bus без $DISPLAY у X11" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "Помилка запуÑку Ñ€Ñдка команди «%s»: " + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Ðе вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ адреÑу ÑеанÑової шини (не реалізовано Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— ОС)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7318 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "" +"Ðе вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ адреÑу шини зі Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ— Ñередовища " +"DBUS_STARTER_BUS_TYPE — невідоме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s»" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7327 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Ðе вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ адреÑу шини, оÑкільки Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ— Ñередовища " +"DBUS_STARTER_BUS_TYPE не вÑтановлено" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "Ðевідомий тип шини %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "Ðеочікувана відÑутніÑть вміÑту при читанні Ñ€Ñдка" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Ðеочікувана відÑутніÑть вміÑту при (надійному) читанні Ñ€Ñдка" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Перепробувані уÑÑ– доÑтупні механізми автентифікації (проведено: %s) " +"(доÑтупно: %s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "Ідентифікатори кориÑтувача Ð´Ð»Ñ Ð²ÑƒÐ·Ð»Ð° Ñ– Ñервера мають бути однаковими" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "СкаÑовано через GDBusAuthObserver::authorize-authenticated-peer" + +#: gio/gdbusauthmechanismsha1.c:300 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "Помилка при отриманні відомоÑтей Ð´Ð»Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ñƒ «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:315 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "Помилкові права на каталог «%s». Очікуваний режим — 0700, отримано 0%o" + +#: gio/gdbusauthmechanismsha1.c:348 gio/gdbusauthmechanismsha1.c:359 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при Ñтворенні каталогу «%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:361 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ" + +#: gio/gdbusauthmechanismsha1.c:404 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при відкриванні зв'Ñзки ключів «%s» на читаннÑ: " + +#: gio/gdbusauthmechanismsha1.c:427 gio/gdbusauthmechanismsha1.c:769 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Ðекоректне Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ Ñ€Ñдку %d у зв'Ñзці ключів у «%s» з вміÑтом «%s»" + +#: gio/gdbusauthmechanismsha1.c:441 gio/gdbusauthmechanismsha1.c:783 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Ðекоректне Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÑˆÐ¾Ñ— лекÑеми у Ñ€Ñдку %d у зв'Ñзці ключів у «%s» з " +"вміÑтом «%s»" + +#: gio/gdbusauthmechanismsha1.c:455 gio/gdbusauthmechanismsha1.c:797 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "" +"Ðекоректне Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ñ€ÑƒÐ³Ð¾Ñ— лекÑеми у Ñ€Ñдку %d у зв'Ñзці ключів у «%s» з " +"вміÑтом «%s»" + +#: gio/gdbusauthmechanismsha1.c:479 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ куки з ідентифікатором %d у зв'Ñзці ключів «%s»" + +#: gio/gdbusauthmechanismsha1.c:536 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при Ñтворенні файла Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Â«%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:609 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при вилученні заÑтарілого файла Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Â«%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:648 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "" +"СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при закриванні (від'єднаного) файла Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Â«%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:659 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при вилученні файла Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Â«%s»: %s" + +#: gio/gdbusauthmechanismsha1.c:736 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при відкриванні зв'Ñзки ключів «%s» Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу: " + +#: gio/gdbusauthmechanismsha1.c:930 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(Також, не вдалоÑÑ Ð²Ð¸Ð²Ñ–Ð»ÑŒÐ½Ð¸Ñ‚Ð¸ Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Â«%s»: %s) " + +#: gio/gdbusconnection.c:588 gio/gdbusconnection.c:2402 +msgid "The connection is closed" +msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¾" + +#: gio/gdbusconnection.c:1887 +msgid "Timeout was reached" +msgstr "Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ñ‡ÐµÑ€Ð¿Ð°Ð½Ð¾" + +#: gio/gdbusconnection.c:2525 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "При Ñтворенні клієнтÑького з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ð¸Ñвлено непідтримувані прапорці" + +#: gio/gdbusconnection.c:4253 gio/gdbusconnection.c:4607 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "" +"Ð†Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Â«org.freedesktop.DBus.Properties» Ð´Ð»Ñ ÑˆÐ»Ñху об'єкта %s не знайдено" + +#: gio/gdbusconnection.c:4398 +#, c-format +msgid "No such property “%sâ€" +msgstr "Ðемає влаÑтивоÑті «%s»" + +#: gio/gdbusconnection.c:4410 +#, c-format +msgid "Property “%s†is not readable" +msgstr "ВлаÑтивіÑть «%s» недоÑтупна Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ" + +#: gio/gdbusconnection.c:4421 +#, c-format +msgid "Property “%s†is not writable" +msgstr "ВлаÑтивіÑть «%s» недоÑтупна Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу" + +#: gio/gdbusconnection.c:4441 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "" +"Помилка вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð»Ð°ÑтивоÑті «%s». Мало бути викориÑтано тип «%s», але " +"отримано «%s»" + +#: gio/gdbusconnection.c:4546 gio/gdbusconnection.c:4761 +#: gio/gdbusconnection.c:6744 +#, c-format +msgid "No such interface “%sâ€" +msgstr "Ðемає інтерфейÑу «%s»" + +#: gio/gdbusconnection.c:4983 gio/gdbusconnection.c:7258 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "Ðемає інтерфейÑу «%s» на об'єкті зі шлÑхом %s" + +#: gio/gdbusconnection.c:5084 +#, c-format +msgid "No such method “%sâ€" +msgstr "Ðемає методу «%s»" + +#: gio/gdbusconnection.c:5115 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "Тип Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Â«%s» не збігаєтьÑÑ Ð· очікуваним типом «%s»" + +#: gio/gdbusconnection.c:5318 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Об'єкт інтерфейÑу %s вже екÑпортовано Ñк %s" + +#: gio/gdbusconnection.c:5545 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ влаÑтивіÑть %s.%s" + +#: gio/gdbusconnection.c:5601 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Ðе вдалоÑÑ Ð²Ñтановити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð»Ð°ÑтивоÑті %s.%s" + +#: gio/gdbusconnection.c:5780 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "Метод «%s» повернув тип «%s», але очікувалоÑÑ Â«%s»" + +#: gio/gdbusconnection.c:6856 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "Методу «%s» інтерфейÑу «%s» з підпиÑом «%s» не Ñ–Ñнує" + +#: gio/gdbusconnection.c:6977 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Піддерево вже екÑпортовано Ð´Ð»Ñ %s" + +#: gio/gdbusconnection.c:7266 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "Об'єкта зі шлÑхом «%s» не Ñ–Ñнує" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "ÐЕПРÐВИЛЬÐИЙ тип" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ METHOD_CALL: немає Ð¿Ð¾Ð»Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° PATH або MEMBER" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ METHOD_RETURN: немає Ð¿Ð¾Ð»Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° REPLY_SERIAL" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ERROR: немає Ð¿Ð¾Ð»Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° REPLY_SERIAL або ERROR_NAME" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ SIGNAL: немає Ð¿Ð¾Ð»Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° PATH, INTERFACE або MEMBER" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ SIGNAL: поле заголовка PATH викориÑтовує зарезервоване " +"Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ /org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ SIGNAL: поле заголовка INTERFACE викориÑтовує зарезервоване " +"Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Потрібно було прочитати %lu байт, але прочитано лише %lu" +msgstr[1] "Потрібно було прочитати %lu байти, але прочитано лише %lu" +msgstr[2] "Потрібно було прочитати %lu байтів, але прочитано лише %lu" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "Мало бути викориÑтано байт NUL піÑÐ»Ñ Ñ€Ñдка «%s», але знайдено байт %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"Мало бути вказано коректний Ñ€Ñдок UTF-8, але виÑвлено неприпуÑтимі байти " +"(Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ %d, довжина Ñ€Ñдка %d). Коректний Ñ€Ñдок UTF-8 аж до цієї миті був " +"таким: «%s»" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "Рівень вкладеноÑті Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ” надто виÑоким" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "Оброблене Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» не Ñ” припуÑтимим шлÑхом до об'єкта D-Bus" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "Оброблене Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» не Ñ” припуÑтимим підпиÑом D-Bus" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +"ВиÑвлено маÑив довжиною %u байт. МакÑимальна довжина дорівнює 2<<26 байт (64 " +"МіБ)." +msgstr[1] "" +"ВиÑвлено маÑив довжиною %u байти. МакÑимальна довжина дорівнює 2<<26 байт " +"(64 МіБ)." +msgstr[2] "" +"ВиÑвлено маÑив довжиною %u байтів. МакÑимальна довжина дорівнює 2<<26 байт " +"(64 МіБ)." + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"ВиÑвлено маÑив типу «a%c». ОчікувалоÑÑ, що довжина буде кратною до %u " +"байтів, втім, виÑвлено довжину %u байтів" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "Ðе можна викориÑтовувати порожні Ñтруктури (кортежі) у D-Bus" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "Оброблене Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» Ð´Ð»Ñ Ð²Ð°Ñ€Ñ–Ð°Ð½Ñ‚Ð° не Ñ” припуÑтимим підпиÑом D-Bus" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "" +"Помилка деÑеріалізації GVariant з типом Ñ€Ñдка «%s» з формату D-Bus wire" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "" +"Ðеправильний порÑдок байтів у значенні. Мало бути 0x6c («l») або 0x42 («B»), " +"але знайдено Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" +"Ðеправильний Ñтарший номер верÑÑ–Ñ— протоколу. ОчікувавÑÑ 1, але знайдено %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "" +"ВиÑвлено заголовок підпиÑу, але цей заголовок не належить до типу підпиÑів" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "" +"Знайдено заголовок підпиÑу з підпиÑом «%s», але вміÑÑ‚ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ” порожнім" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "Оброблене Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» не Ñ” припуÑтимим підпиÑом D-Bus (Ð´Ð»Ñ Ð²Ð¼Ñ–Ñту)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"ВідÑутній заголовок підпиÑу у повідомленні, але тіло Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¹Ð¼Ð°Ñ” %u " +"байт" +msgstr[1] "" +"ВідÑутній заголовок підпиÑу у повідомленні, але тіло Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¹Ð¼Ð°Ñ” %u " +"байти" +msgstr[2] "" +"ВідÑутній заголовок підпиÑу у повідомленні, але тіло Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¹Ð¼Ð°Ñ” %u " +"байтів" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ деÑеріалізацію повідомленнÑ:" + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "Помилка Ñеріалізації GVariant з типом Ñ€Ñдка «%s» у формат D-Bus wire" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"КількіÑть деÑкрипторів файлів у повідомленні (%d) відрізнÑєтьÑÑ Ð²Ñ–Ð´ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ " +"у полі заголовка (%d)" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "Ðе вдалоÑÑ Ñеріалізувати повідомленнÑ: " + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "ВміÑÑ‚ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð°Ñ” Ð¿Ñ–Ð´Ð¿Ð¸Ñ Â«%s», але немає заголовка підпиÑу" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "" +"ВміÑÑ‚ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð°Ñ” тип підпиÑу «%s», але Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñу у полі " +"заголовка дорівнює «%s»" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "" +"ВміÑÑ‚ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ–Ð¹, але Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñу у полі заголовка дорівнює " +"«(%s)»" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "Повернуто помилку Ð´Ð»Ñ Ð²Ð¼Ñ–Ñту типу «%s»" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "Повернена помилка з порожнім тілом" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Щоб закрити це вікно, уведіть будь-Ñкий Ñимвол)\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Ð¡ÐµÐ°Ð½Ñ dbus не запущений, Ñ– автозапуÑк не виконавÑÑ" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ профіль апаратури: %s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ %s або %s: " + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Помилка виклику StartServiceByName Ð´Ð»Ñ %s: " + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Ðеочікувана відповідь %d з методу StartServiceByName(«%s»)" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Ðе вдалоÑÑ Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñ‚Ð¸ метод; у прокÑÑ– з добре відомою назвою %s немає " +"влаÑника Ñ– прокÑÑ– було побудовано із прапорцем " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "Підтримки абÑтрактних проÑторів назв не передбачено" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "Ðе вдалоÑÑ Ð²ÐºÐ°Ð·Ð°Ñ‚Ð¸ nonce-файл при Ñтворенні Ñервера" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при запиÑу до nonce-файла у «%s»: %s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "РÑдок «%s» не Ñ” припуÑтимим GUID D-Bus" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "Ðеможливо очікувати на дані на каналі Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Â«%s», Ñкого не Ñ–Ñнує" + +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"Команди:\n" +" help Показати цю довідку\n" +" introspect ІнтроÑпектувати віддалений об'єкт\n" +" monitor Стежити за віддаленим об'єктом\n" +" call Викликати метод віддаленого об'єкту\n" +" emit ÐадіÑлати Ñигнал\n" +" wait Очікувати на поÑву назви шини\n" +"\n" +"Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð²Ñ–Ð´ÐºÐ¸ за командою викориÑтовуйте «%s КОМÐÐДР--help».\n" + +#: gio/gdbus-tool.c:202 gio/gdbus-tool.c:274 gio/gdbus-tool.c:346 +#: gio/gdbus-tool.c:370 gio/gdbus-tool.c:860 gio/gdbus-tool.c:1245 +#: gio/gdbus-tool.c:1733 +#, c-format +msgid "Error: %s\n" +msgstr "Помилка: %s\n" + +#: gio/gdbus-tool.c:213 gio/gdbus-tool.c:287 gio/gdbus-tool.c:1749 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ інтроÑпекції XML: %s\n" + +#: gio/gdbus-tool.c:251 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Помилка: %s не Ñ” припуÑтимою назвою\n" + +#: gio/gdbus-tool.c:256 gio/gdbus-tool.c:746 gio/gdbus-tool.c:1064 +#: gio/gdbus-tool.c:1899 gio/gdbus-tool.c:2139 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Помилка: %s не Ñ” припуÑтимим об'єктним шлÑхом\n" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the system bus" +msgstr "Під'єднатиÑÑ Ð´Ð¾ ÑиÑтемної шини" + +#: gio/gdbus-tool.c:405 +msgid "Connect to the session bus" +msgstr "Під'єднатиÑÑ Ð´Ð¾ кориÑтувацької шини" + +#: gio/gdbus-tool.c:406 +msgid "Connect to given D-Bus address" +msgstr "Під'єднатиÑÑ Ð´Ð¾ вказаної адреÑи D-Bus" + +#: gio/gdbus-tool.c:416 +msgid "Connection Endpoint Options:" +msgstr "Параметри кінцевої точки з'єднаннÑ:" + +#: gio/gdbus-tool.c:417 +msgid "Options specifying the connection endpoint" +msgstr "Параметри, що визначають кінцеву точку з'єднаннÑ" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "No connection endpoint specified" +msgstr "Кінцева точка з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ðµ вказана" + +#: gio/gdbus-tool.c:450 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Вказано декілька кінцевих точок з'єднаннÑ" + +#: gio/gdbus-tool.c:523 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "ПопередженнÑ: згідно з даними інтроÑпекції, інтерфейÑу «%s» не Ñ–Ñнує\n" + +#: gio/gdbus-tool.c:532 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "" +"ПопередженнÑ: згідно з даними інтроÑпекції, методу «%s» в інтерфейÑÑ– «%s» не " +"Ñ–Ñнує\n" + +#: gio/gdbus-tool.c:594 +msgid "Optional destination for signal (unique name)" +msgstr "Ðеобов'Ñзковий отримувач Ñигналу (унікальна назва)" + +#: gio/gdbus-tool.c:595 +msgid "Object path to emit signal on" +msgstr "Об'єктний шлÑÑ…, Ð´Ð»Ñ Ð²Ð¸Ð¿ÑƒÑку Ñигналу" + +#: gio/gdbus-tool.c:596 +msgid "Signal and interface name" +msgstr "Ðазва Ñигналу Ñ– інтерфейÑу" + +#: gio/gdbus-tool.c:629 +msgid "Emit a signal." +msgstr "ПоÑлати Ñигнал." + +#: gio/gdbus-tool.c:684 gio/gdbus-tool.c:1001 gio/gdbus-tool.c:1836 +#: gio/gdbus-tool.c:2068 gio/gdbus-tool.c:2288 +#, c-format +msgid "Error connecting: %s\n" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при з'єднанні: %s\n" + +#: gio/gdbus-tool.c:704 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Помилка: %s не Ñ” припуÑтимою унікальною назвою шини.\n" + +#: gio/gdbus-tool.c:723 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1879 +msgid "Error: Object path is not specified\n" +msgstr "Помилка: не вказано об'єктний шлÑÑ…\n" + +#: gio/gdbus-tool.c:766 +msgid "Error: Signal name is not specified\n" +msgstr "Помилка: не вказано назви Ñигналу\n" + +#: gio/gdbus-tool.c:780 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "Помилка: некоректна назва Ñигналу «%s»\n" + +#: gio/gdbus-tool.c:792 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Помилка: %s не Ñ” припуÑтимою назвою інтерфейÑу\n" + +#: gio/gdbus-tool.c:798 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Помилка: %s не Ñ” припуÑтимою назвою члену\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:835 gio/gdbus-tool.c:1176 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ параметра %d: %s\n" + +#: gio/gdbus-tool.c:867 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при Ñкиданні під'єднаннÑ: %s\n" + +#: gio/gdbus-tool.c:895 +msgid "Destination name to invoke method on" +msgstr "Ðазва призначеннÑ, Ð´Ð»Ñ Ñкого викликаєтьÑÑ Ð¼ÐµÑ‚Ð¾Ð´" + +#: gio/gdbus-tool.c:896 +msgid "Object path to invoke method on" +msgstr "Об'єктний шлÑÑ…, Ð´Ð»Ñ Ñкого викликаєтьÑÑ Ð¼ÐµÑ‚Ð¾Ð´" + +#: gio/gdbus-tool.c:897 +msgid "Method and interface name" +msgstr "Ðазва методу або інтерфейÑу" + +#: gio/gdbus-tool.c:898 +msgid "Timeout in seconds" +msgstr "Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ Ñекундах" + +#: gio/gdbus-tool.c:899 +msgid "Allow interactive authorization" +msgstr "Дозволити інтерактивне уповноваженнÑ" + +#: gio/gdbus-tool.c:946 +msgid "Invoke a method on a remote object." +msgstr "Викликає метод на віддаленому об'єкті." + +#: gio/gdbus-tool.c:1018 gio/gdbus-tool.c:1853 gio/gdbus-tool.c:2093 +msgid "Error: Destination is not specified\n" +msgstr "Помилка: не вказано призначеннÑ\n" + +#: gio/gdbus-tool.c:1029 gio/gdbus-tool.c:1870 gio/gdbus-tool.c:2104 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Помилка: %s не Ñ” припуÑтимою назвою шини\n" + +#: gio/gdbus-tool.c:1079 +msgid "Error: Method name is not specified\n" +msgstr "Помилка: не вказано назви методу\n" + +#: gio/gdbus-tool.c:1090 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "Помилка: некоректна назва методу «%s»\n" + +#: gio/gdbus-tool.c:1168 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ параметра %d типу «%s»: %s\n" + +#: gio/gdbus-tool.c:1194 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "Помилка під Ñ‡Ð°Ñ Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚Ð° ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ %d: %s\n" + +#: gio/gdbus-tool.c:1695 +msgid "Destination name to introspect" +msgstr "Ðазва Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ–Ð½Ñ‚Ñ€Ð¾Ñпекції" + +#: gio/gdbus-tool.c:1696 +msgid "Object path to introspect" +msgstr "Об'єктний шлÑÑ… Ð´Ð»Ñ Ñ–Ð½Ñ‚Ñ€Ð¾Ñпекції" + +#: gio/gdbus-tool.c:1697 +msgid "Print XML" +msgstr "Ðадрукувати XML" + +#: gio/gdbus-tool.c:1698 +msgid "Introspect children" +msgstr "ІнтроÑÐ¿ÐµÐºÑ†Ñ–Ñ Ð½Ð°Ñ‰Ð°Ð´ÐºÐ°" + +#: gio/gdbus-tool.c:1699 +msgid "Only print properties" +msgstr "Лише влаÑтивоÑті друку" + +#: gio/gdbus-tool.c:1788 +msgid "Introspect a remote object." +msgstr "Виконати інтроÑпекцію віддаленого об'єкту." + +#: gio/gdbus-tool.c:1994 +msgid "Destination name to monitor" +msgstr "Ðазва Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑпоÑтеріганнÑ" + +#: gio/gdbus-tool.c:1995 +msgid "Object path to monitor" +msgstr "Об'єктний шлÑÑ… Ð´Ð»Ñ ÑпоÑтеріганнÑ" + +#: gio/gdbus-tool.c:2020 +msgid "Monitor a remote object." +msgstr "СпоÑтерігати за віддаленим об'єктом." + +#: gio/gdbus-tool.c:2078 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "" +"Помилка: ÑпоÑÑ‚ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð° з'єднаннÑм, Ñке не належить до типу message-bus, Ñ” " +"неможливим\n" + +#: gio/gdbus-tool.c:2202 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "" +"Служба, Ñку Ñлід активувати, перш ніж очікувати на іншу (добре відома назва)" + +#: gio/gdbus-tool.c:2205 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ виходу із Ñтаном помилки (у Ñекундах); 0 — не очікувати " +"(типова поведінка)" + +#: gio/gdbus-tool.c:2253 +msgid "[OPTION…] BUS-NAME" +msgstr "[ПÐРÐМЕТР…] ÐÐЗВÐ-ШИÐИ" + +#: gio/gdbus-tool.c:2254 +msgid "Wait for a bus name to appear." +msgstr "Очікувати на поÑву назви шини." + +#: gio/gdbus-tool.c:2330 +msgid "Error: A service to activate for must be specified.\n" +msgstr "Помилка: має бути вказано Ñлужбу Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ—.\n" + +#: gio/gdbus-tool.c:2335 +msgid "Error: A service to wait for must be specified.\n" +msgstr "Помилка: має бути вказано Ñлужбу Ð´Ð»Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ.\n" + +#: gio/gdbus-tool.c:2340 +msgid "Error: Too many arguments.\n" +msgstr "Помилка: забагато аргументів.\n" + +#: gio/gdbus-tool.c:2348 gio/gdbus-tool.c:2355 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "Помилка: %s не Ñ” припуÑтимим добре відомою назвою шини.\n" + +#: gio/gdebugcontrollerdbus.c:358 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "Ðе уповноважено змінювати параметри діагноÑтики" + +#: gio/gdesktopappinfo.c:2178 gio/gdesktopappinfo.c:5105 +msgid "Unnamed" +msgstr "Без назви" + +#: gio/gdesktopappinfo.c:2588 +msgid "Desktop file didn’t specify Exec field" +msgstr "У desktop-файлі не визначено Ð¿Ð¾Ð»Ñ Exec" + +#: gio/gdesktopappinfo.c:2896 +msgid "Unable to find terminal required for application" +msgstr "Ðеможливо знайти термінал, що потрібен програмі" + +#: gio/gdesktopappinfo.c:3625 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "Ðе вдалоÑÑ Ñтворити теку параметрів програми %s: %s" + +#: gio/gdesktopappinfo.c:3629 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "Ðе вдалоÑÑ Ñтворити теку параметрів MIME %s: %s" + +#: gio/gdesktopappinfo.c:3871 gio/gdesktopappinfo.c:3895 +msgid "Application information lacks an identifier" +msgstr "У інформації про програму не вказано ідентифікатор" + +#: gio/gdesktopappinfo.c:4131 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "Ðе вдалоÑÑ Ñтворити Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача desktop-файл %s" + +#: gio/gdesktopappinfo.c:4267 +#, c-format +msgid "Custom definition for %s" +msgstr "ВлаÑне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "Ð´Ð»Ñ Ð´Ð¸Ñка не реалізовано функцію Ð²Ð¸ÑˆÑ‚Ð¾Ð²Ñ…ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾ÑÑ–Ñ" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "Ð´Ð»Ñ Ð´Ð¸Ñка не реалізовано операцію «eject» або «eject_with_operation»" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "Ð´Ð»Ñ Ð´Ð¸Ñка не реалізовано Ð¾Ð¿Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾ÑÑ–Ñ Ð´Ð°Ð½Ð¸Ñ…" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "Ð´Ð»Ñ Ð´Ð¸Ñка не реалізовано функцію запуÑку" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "Ð´Ð»Ñ Ð´Ð¸Ñка не реалізовано функції зупинки" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "У модулі TLS не реалізовано Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¸Ð²'Ñзки TLS" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "Підтримка TLS недоÑтупна" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "Підтримка DTLS Ñ” недоÑтупною" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "Ðе вдалоÑÑ Ð¾Ð¿Ñ€Ð°Ñ†ÑŽÐ²Ð°Ñ‚Ð¸ верÑÑ–ÑŽ %d ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ GEmblem" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Ðеправильна кількіÑть лекÑем (%d) у кодуванні GEmblem" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ верÑÑ–ÑŽ %d ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ GEmblemedIcon" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Ðеправильна кількіÑть лекÑем (%d) у кодуванні GEmblemedIcon" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "ОчікуєтьÑÑ GEmblem Ð´Ð»Ñ GEmblemedIcon" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "Вкладена точка Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ Ñ–Ñнує" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "Ðе можна копіювати із заміною каталогу" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "Ðе можна копіювати каталог поверх іншого каталогу" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "Цільовий файл Ñ–Ñнує" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "Ðе вдалоÑÑ Ñкопіювати каталог рекурÑивно" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "Помилка при розрізанні файла: %s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ (reflink/clone) між точками Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ (reflink/clone) не підтримуєтьÑÑ Ð°Ð±Ð¾ некоректне" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "" +"Підтримки ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ (reflink/clone) не передбачено або ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð½Ðµ працює" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "Ðе вдалоÑÑ Ñкопіювати Ñпеціальний файл" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "Ðеправильне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñимвольного поÑиланнÑ" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "Символічні поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ðµ підтримуютьÑÑ" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "Смітник не підтримуєтьÑÑ" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "Ðазви файлів не можуть міÑтити Ñимволу «%c»" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "Ð´Ð»Ñ Ñ‚Ð¾Ð¼Ñƒ не реалізовано операцію монтуваннÑ" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "Програм Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ таких файлів не зареєÑтровано" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Лічильник закрито" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Лічильник файлів має невиконані операції" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Лічильник файлів вже закритий" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "Підтримки верÑÑ–Ñ— %d ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ GFileIcon не передбачено" + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "Ðеправильні вхідні дані GFileIcon" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "Ð”Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ не передбачено підтримки query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ñ–Ñ— не підтримуєтьÑÑ Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑ–Ð²" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ ÑƒÑ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ Ð´Ð»Ñ Ð²Ñ…Ñ–Ð´Ð½Ð¾Ð³Ð¾ потоку" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ ÑƒÑ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "Ðеправильна назва вузла" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "Помилкова відповідь прокÑÑ–-Ñервера HTTP" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· викориÑтаннÑм прокÑÑ–-Ñервера HTTP заборонено" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ð¹Ñ‚Ð¸ Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ð° прокÑÑ–-Ñервері HTTP" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "Слід пройти Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ð° прокÑÑ–-Ñервері HTTP" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Ðе вдалоÑÑ Ð²Ñтановити з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ–Ð· прокÑÑ–-Ñервером HTTP: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "Відповідь HTTP-прокÑÑ– Ñ” надто великою" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "ПрокÑÑ–-Ñервер HTTP неÑподівано розірвав з'єднаннÑ." + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Ðеправильна кількіÑть лекÑем (%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "ВідÑутній тип назви клаÑу %s" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Ð”Ð»Ñ Ñ‚Ð¸Ð¿Ñƒ %s не реалізовано Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ GIcon" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "Тип %s не клаÑифікований" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "Ðеправильний номер верÑÑ–Ñ—: %s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Ð”Ð»Ñ Ñ‚Ð¸Ð¿Ñƒ %s не реалізовано from_tokens() у інтерфейÑÑ– GIcon" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ вказану верÑÑ–ÑŽ ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–ÐºÑ‚Ð¾Ð³Ñ€Ð°Ð¼Ð¸" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "ÐдреÑа не вказана" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð¸ %u завелике Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "У адреÑÑ– вÑтановлені біти поза межами довжини префікÑу" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ «%s» Ñк маÑку IP-адреÑ" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "Бракує проÑтору Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи Ñокету" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Ðепідтримувана адреÑа Ñокету" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "Ð”Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ вхідних даних не реалізовано читаннÑ" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "Ð”Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ Ñ” незавершена операціÑ" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "Копіювати з файлом" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "ПереÑунути з файлом" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "«version» не потребує параметрів" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "ВикориÑтаннÑ:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "ВивеÑти верÑÑ–ÑŽ та вийти." + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "Команди:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "Об'єднати файли до Ñтандартного виведеннÑ" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "Копіювати один або декілька файлів" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "Показати відомоÑті щодо міÑць" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "ЗапуÑтити програму з файла desktop" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "ВивеÑти ÑпиÑок вміÑту міÑць" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "Отримати або вÑтановити обробник Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ñƒ MIME" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "Створити каталоги" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "Стежити за змінами у файлах Ñ– каталогах" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "Змонтувати або демонтувати міÑцÑ" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "ПереÑунути один або декілька файлів" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "Відкрити файли за допомогою типової програми" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "Перейменувати файл" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "Вилучити один або декілька файлів" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "Прочитати дані зі Ñтандартного джерела даних Ñ– зберегти Ñ—Ñ…" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "Ð’Ñтановити атрибут файла" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "ПереÑунути файли або каталоги до Ñмітника" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "ВивеÑти ÑпиÑок вміÑту уÑÑ–Ñ… міÑць у ієрархії" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "СкориÑтайтеÑÑ %s, щоб дізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ.\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "Помилка при запиÑÑ– до Ñтандартного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ (stdout)" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "МІСЦЕ" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "З'єднати файли Ñ– вивеÑти дані до Ñтандартного виведеннÑ." + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat працює подібно до звичайної програми cat, але викориÑтовує міÑцÑ\n" +"GIO заміÑть локальних файлів. Ðаприклад, ви можете вказати Ñк міÑце\n" +"щоÑÑŒ таке: smb://Ñервер/реÑурÑ/файл.txt." + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "Ðе вказано міÑць" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "Ðемає каталогу призначеннÑ" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "Показувати поÑтуп" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "Запитувати перед перезапиÑом" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "Зберегти уÑÑ– атрибути" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "Створити резервні копії наÑвних файлів призначеннÑ" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "Ðіколи не переходити за Ñимволічними поÑиланнÑми" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "ВикориÑтовувати типові права доÑтупу Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "ПеренеÑено %s з %s (%s/Ñ)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "ДЖЕРЕЛО" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "ПРИЗÐÐЧЕÐÐЯ" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "Копіювати один або декілька файлів з ДЖЕРЕЛО до ПРИЗÐÐЧЕÐÐЯ." + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy працює подібно до звичайної програми cp, але викориÑтовує міÑцÑ\n" +"GIO заміÑть локальних файлів. Ðаприклад, ви можете вказати Ñк міÑце\n" +"щоÑÑŒ таке: smb://Ñервер/реÑурÑ/файл.txt." + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s не Ñ” каталогом" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s: перепиÑати «%s»? " + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "ВивеÑти ÑпиÑок придатних до запиÑу атрибутів" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "Отримати відомоÑті щодо файлової ÑиÑтеми" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "Ðтрибути, Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñких Ñлід отримати" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ÐТРИБУТИ" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "Ðе переходити за Ñимволічними поÑиланнÑми" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "атрибути:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "показана назва: %s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "редагована назва: %s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "назва: %s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "тип: %s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "розмір: " + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "прихований\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "адреÑа: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "локальний шлÑÑ…: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "точка Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ unix: %s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "Придатні до вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "Придатні до запиÑу проÑтори назв атрибутів:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "Показати відомоÑті щодо міÑць." + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info працює подібно до звичайної програми ls, але викориÑтовує міÑцÑ\n" +"GIO заміÑть локальних файлів. Ðаприклад, ви можете вказати Ñк міÑце\n" +"щоÑÑŒ таке: smb://Ñервер/реÑурÑ/файл.txt. Ðтрибути файла можна задавати\n" +"за їхніми назвами GIO, — наприклад, standard::icon, — або проÑто за " +"проÑтором\n" +"назв, — наприклад, unix, — або проÑто «*», тобто обробити уÑÑ– атрибути." + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "ФÐЙЛ-DESKTOP [ÐРГУМЕÐТ-ФÐЙЛ …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "" +"ЗапуÑтити програму з файла desktop, передавши їй необов'Ñзкові аргументи — " +"назви файлів." + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "Ðе вказано файла desktop" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "" +"Ðа цій платформі у поточній верÑÑ–Ñ— не передбачено можливоÑті Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ " +"команди запуÑку" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ «%s»: %s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ дані програми Ð´Ð»Ñ Â«%s»" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити програму «%s»: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "Показати приховані файли" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "ВикориÑтовувати довгий формат ÑпиÑку" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "ВивеÑти показані назви" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "ВивеÑти повні адреÑи" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "ВивеÑти ÑпиÑок вміÑту міÑць." + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list працює подібно до звичайної програми ls, але викориÑтовує міÑцÑ\n" +"GIO заміÑть локальних файлів. Ðаприклад, ви можете вказати Ñк міÑце\n" +"щоÑÑŒ таке: smb://Ñервер/реÑурÑ/файл.txt. Ðтрибути файла можна задавати\n" +"за їхніми назвами GIO, — наприклад, standard::icon." + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "ТИП_MIME" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "ОБРОБÐИК" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "Отримати або вÑтановити обробник Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ñƒ MIME." + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"Якщо обробника не вказано, буде виведено ÑпиÑок зареєÑтрованих Ñ–\n" +"рекомендованих програм Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ñƒ MIME. Якщо вказано обробник, його буде\n" +"вÑтановлено Ñк типовий обробник Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ñƒ MIME." + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "Слід вказати один тип MIME Ñ–, можливо, один обробник" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "Ðемає типової програми Ð´Ð»Ñ Â«%s»\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "Типова програма Ð´Ð»Ñ Â«%s»: %s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "ЗареєÑтровані програми:\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "Ðемає зареєÑтрованих програм\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "Рекомендовані програми:\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "Ðемає рекомендованих програм\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ відомоÑті Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ° «%s»" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "Ðе вдалоÑÑ Ð²Ñтановити «%s» Ñк типовий обробник Ð´Ð»Ñ Â«%s»: %s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "Створювати батьківÑькі каталоги" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "Створити каталоги." + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir працює подібно до звичайної програми mkdir, але викориÑтовує " +"міÑцÑ\n" +"GIO заміÑть локальних файлів Ðаприклад, ви можете вказати Ñк міÑце\n" +"щоÑÑŒ таке: smb://Ñервер/реÑурÑ/каталог." + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "Стежити за каталогом (типова поведінка залежить від типу)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "СпоÑтерігати за файлом (типова поведінка залежить від типу)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "" +"СпоÑтерігати за файлом безпоÑередньо (зауважувати зміни, Ñкі внеÑено за " +"допомогою жорÑтких поÑилань)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "СпоÑтерігати за файлом безпоÑередньо, але не повідомлÑти про зміни" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "" +"ПовідомлÑти про переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð° Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñк про проÑті події " +"Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ñ– ÑтвореннÑ" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "СпоÑтерігати за подіÑми монтуваннÑ" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "Стежити за змінами у файлах Ñ– каталогах." + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "Монтувати Ñк монтований" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "Змонтувати том за вказаним файлом приÑтрою або іншим ідентифікатором" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "Ід." + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "Демонтувати" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "Виштовхнути" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "Зупинити роботу диÑка за вказаним файлом приÑтрою" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "ПРИСТРІЙ" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "Демонтувати уÑÑ– точки Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° заданою Ñхемою" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "СХЕМÐ" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "Ігнорувати незвичні дії з файлами при демонтуванні або виштовхуванні" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "ВикориÑтовувати анонімний обліковий Ð·Ð°Ð¿Ð¸Ñ Ð¿Ñ€Ð¸ розпізнаванні" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "СпиÑок" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "СпоÑтерігати за подіÑми" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "Показати додаткові відомоÑті" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "ЧиÑловий PIM при розблокуванні тому VeraCrypt" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "Змонтувати прихований том TCRYPT" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "Змонтувати ÑиÑтемний том TCRYPT" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "Ðнонімний доÑтуп заборонено" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "Ðемає диÑка Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° диÑка" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "Ðемає тому із вказаним ідентифікатором" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "Змонтувати або демонтувати міÑцÑ." + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "Ðе викориÑтовувати резервних варіантів ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ– вилученнÑ" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "ПереÑунути один або декілька файлів з ДЖЕРЕЛО до ПРИЗÐÐЧЕÐÐЯ." + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move працює подібно до звичайної програми mv, але викориÑтовує міÑцÑ\n" +"GIO заміÑть локальних файлів. Ðаприклад, ви можете вказати Ñк міÑце\n" +"щоÑÑŒ таке: smb://Ñервер/реÑурÑ/файл.txt" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s не Ñ” каталогом" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"Відкрити файли за допомогою типової програми, Ñку\n" +"зареєÑтровано Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ файлів відповідного типу." + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "Ігнорувати файли, Ñких не Ñ–Ñнує — не запитувати кориÑтувача" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "Вилучити вказані файли." + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "ÐÐЗВÐ" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "Перейменувати файл." + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "Пропущено аргумент" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "Забагато аргументів" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "УÑпішно перейменовано. Ðова адреÑа: %s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "Створювати, лише Ñкщо не Ñ–Ñнує" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "ДопиÑати наприкінці файла" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "При Ñтворенні обмежити доÑтуп до даних поточним кориÑтувачем" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "При заміні замінювати так, наче Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ Ñ–Ñнувало" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "ВивеÑти новий etag наприкінці" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "etag файла, Ñкий буде перезапиÑано" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ñ– Ñтандартного джерела даних" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag Ñ” недоÑтупним\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "" +"Прочитати дані зі Ñтандартного джерела даних Ñ– зберегти Ñ—Ñ… до ПРИЗÐÐЧЕÐÐЯ." + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "Ðе вказано призначеннÑ" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "Тип атрибута" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "ТИП" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ÐТРИБУТ" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "ЗÐÐЧЕÐÐЯ" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "Ð’Ñтановити атрибут файла Ð´Ð»Ñ ÐœÐ†Ð¡Ð¦Ð•." + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "Ðе вказано міÑцÑ" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "Ðе вказано атрибута" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "Ðе вказано значеннÑ" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "Ðекоректний тип атрибута «%s»" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "Спорожнити Ñмітник" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "" +"ВивеÑти ÑпиÑок файлів у Ñмітнику із зазначеннÑм початкових міÑць зберіганнÑ" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "" +"Відновити файл зі Ñмітника до його початкового Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ (з можливим " +"повторним ÑтвореннÑм каталогу)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ початковий шлÑÑ…" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "Ðе вдалоÑÑ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾ Ñтворити початкове міÑце: " + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑунути файл до його початкового міÑцÑ: " + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "ПереÑунути/Відновити файли або каталоги до Ñмітника." + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"ЗауваженнÑ: Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ñ‡Ð° --restore, Ñкщо початкове міÑце файла зі " +"Ñмітника \n" +"вже зайнÑто, його не буде перезапиÑано, Ñкщо не вказано параметр --force." + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "Вказане міÑце не починаєтьÑÑ Ð· trash:///" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "" +"Переходити за Ñимволічними поÑиланнÑми, до змонтованих тек та за ÑкороченнÑми" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "ВивеÑти вміÑÑ‚ каталогів у форматі ієрархії." + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Елемент <%s> не може бути вÑередині <%s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Елемент <%s> не може бути Ñамим горішнім" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Файл %s вказано у реÑурÑÑ– декілька разів" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "Ðе вдалоÑÑ Ð²Ð¸Ñвити «%s» у каталозі-джерелі" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "Ðе вдалоÑÑ Ð²Ð¸Ñвити «%s» у поточному каталозі" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "Ðевідомий параметр обробки «%s»" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "" +"ÐадіÑлано запит щодо попередньої обробки %s, але не вÑтановлено %s, а %s " +"немає Ñеред каталогів PATH" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Помилка при читанні файла %s: %s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "Помилка при ÑтиÑненні файла %s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "текÑÑ‚ не може бути вÑередині <%s>" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "ВивеÑти дані щодо верÑÑ–Ñ— програми Ñ– завершити роботу" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "Ðазва вихідного файла" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Каталоги Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð², на Ñкі поÑилаєтьÑÑ Ð¤ÐЙЛ (типово поточний " +"каталог)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "КÐТÐЛОГ" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Генерувати результат у форматі, Ñкий відповідає ÑуфікÑу назви файла " +"призначеннÑ" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "Генерувати джерельний заголовок" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "" +"Генерувати початковий код, Ñкий викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð·Ð²'Ñзку з файлом " +"реÑурÑів вашого коду" + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "Генерувати перелік залежноÑтей" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "Ðазва файла залежноÑтей, Ñкий Ñлід Ñтворити" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "Включити фіктивні Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ Ñтворений файл залежноÑтей" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "Ðе Ñтворювати або реєÑтрувати реÑÑƒÑ€Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "Ðе екÑпортувати функції; оголоÑити Ñ—Ñ… Ñк G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Ðе вбудовувати дані реÑурÑу до файла Сі; припуÑкати його зовнішнє " +"компонуваннÑ" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "" +"Ðазва C-ідентифікатора, Ñкий викориÑтовуватиметьÑÑ Ð´Ð»Ñ Ð¿Ð¾Ñ€Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ " +"початкового коду" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "" +"КомпілÑтор C Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (типове значеннÑ: вміÑÑ‚ змінної Ñередовища CC)" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Компілювати Ñпецифікацію реÑурÑів у файл реÑурÑів.\n" +"Файли Ñпецифікації реÑурÑів мають Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ .gresource.xml,\n" +"а файл реÑурÑу має Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ .gresource." + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "Вам Ñлід вказати точно одну назву файла\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "пÑевдонім має ÑкладатиÑÑ Ð¿Ñ€Ð¸Ð½Ð°Ð¹Ð¼Ð½Ñ– з 2 Ñимволів" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "Ðекоректне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñимволічного поÑиланнÑ" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " вже вказано" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' вже вказано" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "у значеннÑÑ… прапорців має бути вÑтановлено не більше одного біта" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> має міÑтити принаймні один елемент " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> не міÑтитьÑÑ Ñƒ вказаному діапазоні" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> не Ñ” коректним членом вказаного нумерованого типу" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> міÑтить Ñ€Ñдок, Ñкого немає у вказаному типі прапорців" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> міÑтить Ñ€Ñдок, Ñкого немає у " + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа вже вказано" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " не можна викориÑтовувати Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² типу «%s»" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr "вказане мінімальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰ÑƒÑ” макÑимальне" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "непідтримувана ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ l10n: %s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "надіÑлано запит щодо l10n, але не вказано домен gettext" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "вказано контекÑÑ‚ перекладу Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð±ÐµÐ· Ð²Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð¸Ð¿Ñƒ «%s»: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" не можна вказувати Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð², Ñкі позначено Ñк такі, що мають " +"нумерований тип" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа вже вказано" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " не можна викориÑтовувати Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² типу «%s»" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " вже задано" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " має міÑтити принаймні один елемент " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа вже вказано" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" можна вказувати лише Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² із нумерованими типами або типами " +"прапорців чи піÑÐ»Ñ " + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "Вказано , коли «%s» вже Ñ” членом нумерованого типу" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "Вказано , коли вже вказано " + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " вже вказано" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ð»ÑŒÑ‚ÐµÑ€Ð½Ð°Ñ‚Ð¸Ð²Ð½Ð¾Ñ— назви «%s» не належить до нумерованого типу" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ð»ÑŒÑ‚ÐµÑ€Ð½Ð°Ñ‚Ð¸Ð²Ð¸ «%s» немає у " + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " має міÑтити принаймні один елемент " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "Ðе можна викориÑтовувати порожні назви" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "Ðекоректна назва «%s»: назви мають починатиÑÑ Ð· малої літери" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "" +"Ðекоректна назва «%s»: некоректний Ñимвол «%c». Можна викориÑтовувати лише " +"малі літери, чиÑла Ñ– Ð´ÐµÑ„Ñ–Ñ («-»)." + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "Ðекоректна назва «%s»: не можна вказувати два дефіÑи одночаÑно («--»)." + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "Ðекоректна назва «%s»: оÑтанній Ñимвол не може бути дефіÑом («-»)." + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "Ðекоректна назва «%s»: довжина має бути не більшою за 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " вже вказано" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "Ðе вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ ключі до Ñхеми «list-of»" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " вже вказано" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" відтінює у ; Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½ÑŽÐ²Ð°Ð½Ð½Ñ " +"Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸Ñтовуйте " + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "Як атрибут можна вказати лише «type», «enum» або «flags»" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> не визначено (поки)." + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "Ðекоректний Ñ€Ñдок типу GVariant «%s»" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "Вказано , але Ñхема нічого не розширює" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "Ðемає Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " вже вказано" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " вже вказано" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " розширює Ñхему, Ñкої ще не Ñ–Ñнує — «%s»" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " Ñ” ÑпиÑком Ñхеми, Ñкої ще не Ñ–Ñнує — «%s»" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "Ðе може бути ÑпиÑком Ñхеми зі шлÑхом" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·ÑˆÐ¸Ñ€Ð¸Ñ‚Ð¸ Ñхему шлÑхом" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" Ñ” переліком, що розширює , Ñкий не Ñ” " +"переліком" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" розширює , але " +"«%s» не розширює «%s»" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "" +"Якщо вказано шлÑÑ…, його Ð·Ð°Ð¿Ð¸Ñ Ð¼Ð°Ñ” починатиÑÑ Ñ– закінчуватиÑÑ Ñимволом " +"похилої риÑки" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "ШлÑÑ… у переліку має завершуватиÑÑ Ð½Ð° «:/»" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"ПопередженнÑ: Ñхема «%s» має шлÑÑ… «%s». ШлÑхи, що починаютьÑÑ Ð· «/apps/», «/" +"desktop/» та «/system/» вважаютьÑÑ Ð·Ð°Ñтарілими." + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> вже вказано" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Можна викориÑтовувати лише один елемент <%s> вÑередині <%s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Елемент <%s> не може бути Ñамим горішнім" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr "Потрібен елемент у " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "ТекÑÑ‚ може не показуватиÑÑŒ уÑередині «%s»" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "ПопередженнÑ: невизначене поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° " + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "Було вказано параметр --strict; перериваємо обробку." + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "УвеÑÑŒ вміÑÑ‚ файла було проігноровано." + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "Ігноруємо цей файл." + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"Ключа «%s» у Ñхемі «%s» немає, хоч вказаний у файлі замін «%s»; ігноруємо " +"Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа." + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"Ðемає ключа «%s» у Ñхемі «%s», Ñку вказано у файлі замін «%s», а вказано " +"параметр --strict — перериваємо обробку." + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"Ðе вдалоÑÑ Ð½Ð°Ð´Ð°Ñ‚Ð¸ окремих перевизначень Ð´Ð»Ñ Ð¾ÐºÑ€ÐµÐ¼Ð¸Ñ… файлів desktop Ð´Ð»Ñ " +"локалізованого ключа «%s» у Ñхемі «%s» (файл замін «%s»); ігноруємо заміну " +"Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа." + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"Ðе вдалоÑÑ Ð½Ð°Ð´Ð°Ñ‚Ð¸ заміни Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ñ–Ð·Ð¾Ð²Ð°Ð½Ð¾Ð³Ð¾ ключа «%s» у Ñхемі «%s» (файл " +"заміни «%s»), а було задано --strict — перериваємо обробку." + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"Помилка під Ñ‡Ð°Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ ключа «%s» у Ñхемі «%s», Ñку визначено у файлі замін " +"«%s»: %s. Ігноруємо заміну Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа." + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"Помилка обробки ключа «%s» у Ñхемі «%s», Ñку визначено у файлі замін «%s»: " +"%s. Було задано --strict — перериваємо обробку." + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"Заміна ключа «%s» у Ñхемі «%s» відповідно до файла замін «%s» не належить до " +"вказаного у Ñхемі діапазону — ігноруємо Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа." + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"Заміна ключа «%s» у Ñхемі «%s» відповідно до файла замін «%s» не належить до " +"вказаного у Ñхемі діапазону, а було задано --strict — перериваємо обробку." + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"Заміна ключа «%s» у Ñхемі «%s» відповідно до файла замін «%s» не належить " +"до ÑпиÑку припуÑтимих значень; ігноруємо Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа." + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"Заміна ключа «%s» у Ñхемі «%s» відповідно до файла замін «%s» не належить до " +"ÑпиÑку коректних варіантів, а задано параметр --strict — перериваємо обробку." + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "МіÑце Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° gschemas.compiled" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "ЗупинÑти роботу при виникненні помилок у Ñхемах" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "Ðе запиÑувати файл gschema.compiled" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "Ðе вÑтановлювати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° назву ключа" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Компілювати уÑÑ– файли Ñхеми GSettings у кеш Ñхеми.\n" +"Файли Ñхеми потрібні Ð´Ð»Ñ Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ .gschema.xml,\n" +"а файл кешу зветьÑÑ gschemas.compiled." + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "Вам Ñлід вказати точно одну назву каталогу" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "Ðе знайдено файлів Ñхем: нічого не робимо." + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "Ðе знайдено файлів Ñхеми: вилучено наÑвний файл виведених даних." + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "Ðекоректна назва файла %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "Помилка при отриманні відомоÑтей щодо файлової ÑиÑтеми Ð´Ð»Ñ %s: %s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "Вкладена точка Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° %s не Ñ–Ñнує" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "Ðе можна перейменовувати кореневий каталог" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "Помилка при перейменуванні файла %s: %s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ файл, файл із також назвою вже Ñ–Ñнує" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "Ðекоректна назва файла" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "Помилка при відкритті файла «%s»: %s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби вилучити файл %s: %s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби надіÑлати файл %s до Ñмітника: %s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "Помилка при Ñтворенні каталогу Ñмітника %s: %s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ каталог верхнього Ñ€Ñ–Ð²Ð½Ñ Ð´Ð»Ñ Ñмітника %s" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "" +"Підтримки надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð¾ Ñмітника на внутрішніх точках Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑиÑтеми не " +"передбачено" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ або Ñтворити каталог Ñмітника %s Ð´Ð»Ñ Ð²Ð¸ÐºÐ¸Ð´Ð°Ð½Ð½Ñ %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "" +"Ðе вдалоÑÑ Ñтворити файл відомоÑтей щодо надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð¾ Ñмітника Ð´Ð»Ñ %s: %s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "Ðе вдалоÑÑ Ð½Ð°Ð´Ñ–Ñлати файл %s до Ñмітника за межами файлової ÑиÑтеми" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити файл до Ñмітника %s: %s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити файл до Ñмітника %s" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при Ñтворенні каталогу «%s»: %s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Файлова ÑиÑтема не підтримує Ñимволічні поÑиланнÑ" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "Помилка при Ñтворенні Ñимволічного поÑÐ¸Ð»Ð°Ð½Ð½Ñ %s: %s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "Помилка при переміщенні файла %s: %s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити каталог поверх каталогу" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "Помилка при Ñтворенні файла резервної копії" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "Помилка при зчитуванні файла призначеннÑ: %s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¼Ñ–Ð¶ різними точками Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ викориÑÑ‚Ð°Ð½Ð½Ñ Ð´Ð¸Ñка %s: %s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð° не може бути NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "Ðекоректний тип атрибута (очікувавÑÑ Ñ€Ñдок)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "Ðеправильна назва розширеного атрибута" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "Помилка при вÑтановленні розширеного атрибута «%s»: %s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (неправильне кодуваннÑ)" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "Помилка при отриманні інформації про файл «%s»: %s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Помилка при отриманні інформації про файловий деÑкриптор: %s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Ðеправильний тип атрибута (очікувавÑÑ uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Ðеправильний тип атрибута (очікувавÑÑ uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "Ðеправильний тип атрибута (очікувавÑÑ Ñ€Ñдок байтів)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "Помилка при вÑтановленні прав доÑтупу на Ñимволічне поÑиланнÑ" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Помилка вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð² доÑтупу: %s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "Помилка вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð»Ð°Ñник: %s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "Ñимвольне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ðµ може мати Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ NULL" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Помилка при вÑтановленні Ñимволічного поÑиланнÑ: %s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "" +"помилка при вÑтановленні Ñимволічного поÑиланнÑ: файл не Ñ” Ñимволічним " +"поÑиланнÑм" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "Зайві наноÑекунди %d у чаÑовій позначці UNIX %lld Ñ” від'ємними" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "" +"Зайві наноÑекунди %d у чаÑовій позначці UNIX %lld доÑÑгли Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ одну " +"Ñекунду" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "ЧаÑова позначка UNIX %lld не вкладаєтьÑÑ Ñƒ 64 біти" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "" +"ЧаÑова позначка UNIX %lld лежить поза діапазоном, підтримку Ñкого " +"передбачено у Windows" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "Ðазву файла «%s» неможливо перетворити на назву у кодуванні UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл «%s»: помилка Windows %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "Помилка при вÑтановленні чаÑу зміни або доÑтупу Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»: %lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Помилка при вÑтановленні чаÑу зміни або доÑтупу: %s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "КонтекÑÑ‚ SELinux не може Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ NULL" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "SELinux не увімкнено у цій ÑиÑтемі" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Помилка при вÑтановленні контекÑту SELinux: %s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Підтримки вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð° %s не передбачено" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "Помилка при читанні файла: %s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "Помилка при закриванні файла: %s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Помилка при вÑтановленні позиції у файлі: %s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ типовий різновид монітора локального файла" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "Помилка при запиÑÑ– до файла: %s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Помилка при видаленні Ñтарої резервної копії поÑиланнÑ: %s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Помилка при Ñтворенні резервної копії: %s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Помилка при перейменуванні тимчаÑового файла: %s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1239 +#, c-format +msgid "Error truncating file: %s" +msgstr "Помилка при обрізанні файла: %s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1220 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "Помилка при відкритті файла «%s»: %s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "Цільовий файл Ñ” каталогом" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "Цільовий файл не Ñ” звичайним файлом" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "Файл був змінений іншою програмою" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "Помилка при видаленні Ñтарого файла: %s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "Вказано неправильний GSeekType" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "Ðеправильний тип операції зміни позиції у файлі" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Ðе можна уÑікати GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "Ðе можна змінювати розмір потоку виводу у пам'Ñть" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "Помилка при зміні розміру потоку виводу у пам'Ñть" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"КількіÑть пам'Ñті, потрібна Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу запиÑу, більша ніж доÑтупний " +"адреÑний проÑтір" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "Виконувати Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð½Ð° початок потоку" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "Виконувати Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð½Ð° кінець потоку" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ реалізовано операцію «unmount»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ реалізовано операцію Ð²Ð¸ÑˆÑ‚Ð¾Ð²Ñ…ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾ÑÑ–Ñ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "У mount не реалізовано функцію «unmount» або «unmount_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "" +"Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ реалізовано операцію «eject» або " +"«eject_with_operation»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ реалізовано «remount»" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "" +"Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ реалізовано автоматичне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð¸Ð¿Ñƒ контекÑту" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "" +"Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð¼Ð¾Ð½Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ реалізовано автоматичне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð¸Ð¿Ñƒ Ñинхронного " +"зміÑту" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "Ðазва вузла «%s» міÑтить «[», але не міÑтить «]»" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "Мережа недоÑтупна" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "Вузол Ñ” недоÑтупним" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "Ðе вдалоÑÑ Ñтворити мережевий монітор: %s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "Ðе вдалоÑÑ Ñтворити мережевий монітор: " + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ Ñтан мережі: " + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager не запущено" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "ВерÑÑ–Ñ NetworkManager Ñ” надто Ñтарою" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "У потоці виводу не реалізовано операції запиÑу" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Сума векторів, Ñку передано до %s, Ñ” надто великою" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "Вхідний потік вже закритий" + +#. Translators: the first placeholder is a domain name, the +#. * second is an error message +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "Помилка Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ на адреÑу «%s»: %s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s не реалізовано" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "Ðекоректний домен" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "РеÑурÑу у «%s» не Ñ–Ñнує" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ñ‚Ð¸ реÑÑƒÑ€Ñ Ð· «%s»" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "РеÑÑƒÑ€Ñ Ñƒ «%s» не Ñ” каталогом" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "У потоці вхідних даних не передбачено позиціюваннÑ" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "ВивеÑти розділи, що міÑÑ‚Ñть реÑурÑи у elf-ФÐЙЛІ" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Вивід переліку реÑурÑів\n" +"Якщо вказано РОЗДІЛ, то виводитьÑÑ Ð¿ÐµÑ€ÐµÐ»Ñ–Ðº реÑурÑів лише з цього розділу\n" +"Якщо вказано ШЛЯХ, то виводитьÑÑ Ð¿ÐµÑ€ÐµÐ»Ñ–Ðº реÑурÑів, що збігаютьÑÑ" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "ФÐЙЛ [ШЛЯХ]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "РОЗДІЛ" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Ð’Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ ÑпиÑку реÑурÑів з подробицÑми\n" +"Якщо вказано РОЗДІЛ, буде виведено ÑпиÑок реÑурÑів лише з цього розділу\n" +"Якщо вказано ШЛЯХ, буде виведено ÑпиÑок відповідних реÑурÑів\n" +"Додатково буде виведено розділ, розмір Ñ– ÑтиÑненнÑ" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "ВитÑгнути файл реÑурÑу у stdout" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "ФÐЙЛ ШЛЯХ" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ВикориÑтаннÑ:\n" +" gresource [--section РОЗДІЛ] КОМÐÐДР[ÐРГУМЕÐТИ…]\n" +"\n" +"Команди:\n" +" help Показати цю довідку\n" +" sections ВивеÑти розділи з реÑурÑами\n" +" list ВивеÑти реÑурÑи\n" +" details ВивеÑти реÑурÑи з подробицÑми\n" +" extract ВитÑгнути реÑурÑ\n" +"\n" +"Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð²Ñ–Ð´ÐºÐ¸ ÑкориÑтайтеÑÑ Â«gresource help КОМÐÐДл.\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ВикориÑтаннÑ:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " РОЗДІЛ Ðазва розділу elf (необов'Ñзкова)\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " КОМÐÐДРКоманда Ð´Ð»Ñ Ð¿Ð¾ÑÑÐ½ÐµÐ½Ð½Ñ (необов'Ñзковий)\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " ФÐЙЛ Файл elf (виконуваний або Ñпільна бібліотека)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" ФÐЙЛ Файл elf (виконуваний або Ñпільна бібліотека)\n" +" або Ñкомпільований файл реÑурÑів\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[ШЛЯХ]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr "" +" ШЛЯХ ШлÑÑ… реÑурÑу (необов'Ñзковий, можна вказати лише чаÑтину)\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "ШЛЯХ" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " ШЛЯХ ШлÑÑ… реÑурÑу\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "Ðемає Ñхеми «%s»\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "Схема «%s» не Ñ” переміщуваною (не Ñлід вказувати шлÑÑ…)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "Схема «%s» Ñ” переміщуваною (повинен бути вказаний шлÑÑ…)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "Вказано порожній шлÑÑ….\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "ШлÑÑ… повинен починатиÑÑ Ñимволом коÑої риÑки (/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "ШлÑÑ… повинен закінчуватиÑÑ Ñимволом коÑої риÑки (/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "У шлÑху не повинно бути дві ÑтоÑчих порÑд коÑих риÑок (//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "Ðадана величина лежить поза діапазоном припуÑтимих значень\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "Ключ недоÑтупний Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "Перелік вÑтановлених (непереміщуваних) Ñхем" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "Перелік вÑтановлених переміщуваних Ñхем" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "Перелік ключів у СХЕМІ" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "СХЕМÐ[:ШЛЯХ]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "Перелік нащадків СХЕМИ" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Перерахувати ключі Ñ– Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€ÐµÐºÑƒÑ€Ñивно\n" +"Якщо вказана СХЕМÐ, то перерахувати уÑÑ– ключі\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "[СХЕМÐ[:ШЛЯХ]]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "Отримати Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐšÐ›Ð®Ð§Ð" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "СХЕМÐ[:ШЛЯХ] КЛЮЧ" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "Запитати діапазон припуÑтимих значень КЛЮЧÐ" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "Запитати Ð¾Ð¿Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð° КЛЮЧ" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "ПривлаÑнити величину ЗÐÐЧЕÐÐЯ КЛЮЧУ" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "СХЕМÐ[:ШЛЯХ] КЛЮЧ ЗÐÐЧЕÐÐЯ" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "Призначити КЛЮЧУ його типове значеннÑ" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Скинути уÑÑ– ключі у СХЕМІ у Ñ—Ñ… типові значеннÑ" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "Перевірити, що КЛЮЧ доÑтупний Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Стежити за змінами КЛЮЧÐ.\n" +"Якщо КЛЮЧ не вказано, то Ñтежити за уÑіма ключами СХЕМИ.\n" +"Ð”Ð»Ñ Ð·ÑƒÐ¿Ð¸Ð½ÐºÐ¸ ÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸Ñтовуйте ^C.\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "СХЕМÐ[:ШЛЯХ] [КЛЮЧ]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"ВикориÑтаннÑ:\n" +" gsettings --version\n" +" gsettings [--schemadir КÐТÐЛОГ_СХЕМ] КОМÐÐДР[ÐРГУМЕÐТИ…]\n" +"\n" +"Команди:\n" +" help Показати цю довідку\n" +" list-schemas Перелік вÑтановлених Ñхем\n" +" list-relocatable-schemas Перелік переміщуваних Ñхем\n" +" list-keys Перелік ключів Ñхеми\n" +" list-children Перелік нащадків Ñхеми\n" +" list-recursively Перелік ключів Ñ– значень, рекурÑивно\n" +" range Запитати діапазон значень ключа\n" +" describe Запитати Ð¾Ð¿Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð°\n" +" get Отримати Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð°\n" +" set Змінити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð°\n" +" reset Скинути Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð°\n" +" reset-recursively Скинути уÑÑ– Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ вказаній Ñхемі\n" +" writable Перевірити ключ на запиÑ\n" +" monitor Стежити за змінами\n" +"\n" +"Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð¾Ñ— довідки викориÑтовуйте команду «gsettings help " +"КОМÐÐДл.\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"ВикориÑтаннÑ:\n" +" gsettings [--schemadir КÐТÐЛОГ_СХЕМ] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " КÐТ_СХЕМ Каталог Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ додаткових Ñхем\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" СХЕМРІдентифікатор Ñхеми\n" +" ШЛЯХ ШлÑÑ…, Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÑƒÐ²Ð°Ð½Ð¸Ñ… Ñхем\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " КЛЮЧ (Ðеобов'Ñзковий) ключ Ñхеми\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " КЛЮЧ Ключ Ñхеми\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " ЗÐÐЧЕÐÐЯ ЗначеннÑ, що привлаÑнюєтьÑÑ\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ Ñхеми з «%s»: %s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "Схем не вÑтановлено\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "Вказано порожню назву Ñхеми\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "Ðемає ключа «%s»\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "Ðеправильний Ñокет, не ініціалізований" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "Ðеправильний Ñокет, помилка ініціалізації через : %s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "Сокет вже закритий" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "Перевищено Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð²Ð¾Ð´Ñƒ-виводу Ñокета" + +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ GSocket з fd: %s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Ðе вдалоÑÑ Ñтворити Ñокет: %s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "Вказано невідому родину" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "Вказано невідомий протокол" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Ðеможливо ÑкориÑтатиÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñми із датаграмами на Ñокеті без датаграм." + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Ðеможливо ÑкориÑтатиÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñми із датаграмами на Ñокеті із вÑтановленим " +"чаÑом очікуваннÑ." + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "не вдаєтьÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ локальну адреÑу: %s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "не вдаєтьÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ віддалену адреÑу: %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "не вдаєтьÑÑ Ð¿Ñ€Ð¾Ñлухати: %s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "Помилка прив'ÑÐ·ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ адреÑи %s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Помилка при вÑтупі до мультикаÑтової групи: %s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Помилка при виході з мультикаÑтової групи: %s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "ВідÑÑƒÑ‚Ð½Ñ Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼ÐºÐ° мультикаÑта по джерелу" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "Ðепідтримуване ÑімейÑтво Ñокетів" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "source-specific не Ñ” адреÑою IPv4" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "Ðазва інтерфейÑу Ñ” надто довгою" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "Ðе знайдено інтерфейÑу: %s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "" +"Підтримки Ñпецифічної Ð´Ð»Ñ Ð´Ð¶ÐµÑ€ÐµÐ»Ð° неÑпрÑмованої транÑлÑції Ð´Ð»Ñ IPv4 не " +"передбачено" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "" +"Підтримки Ñпецифічної Ð´Ð»Ñ Ð´Ð¶ÐµÑ€ÐµÐ»Ð° неÑпрÑмованої транÑлÑції Ð´Ð»Ñ IPv6 не " +"передбачено" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Помилка при прийнÑтті з'єднаннÑ: %s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ‚Ñ€Ð¸Ð²Ð°Ñ”" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ помилку очікуваннÑ: " + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "Помилка при отриманні даних: %s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "Помилка при надÑиланні даних: %s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð¼ÐºÐ½ÑƒÑ‚Ð¸ Ñокет: %s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "Помилка при закриванні Ñокету: %s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "ОчікуєтьÑÑ ÑƒÐ¼Ð¾Ð²Ð° Ñокету: %s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "Ðе вдалоÑÑ Ð½Ð°Ð´Ñ–Ñлати повідомленнÑ: %s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "Вектори Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ” надто великими" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "Помилка при надÑиланні повідомленнÑ: %s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage не підтримуєтьÑÑ Ñƒ windows" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "Помилка при отриманні повідомленнÑ: %s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ Ð¿Ð¾Ð²Ð½Ð¾Ð²Ð°Ð¶ÐµÐ½Ð½Ñ Ñокета: %s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ g_socket_get_credentials не реалізована у цій ОС" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´'єднатиÑÑ Ð´Ð¾ прокÑÑ–-Ñервера %s: " + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´'єднатиÑÑ Ð´Ð¾ %s: " + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´'єднатиÑÑ Ð´Ð¾: " + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "" +"Підтримки Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… за допомогою прокÑÑ–-Ñервера через не-TCP " +"з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ðµ передбачено." + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "Підтримки протоколу прокÑÑ– «%s» не передбачено." + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "ПроÑлуховувач з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ð¶Ðµ завершивÑÑ" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "Доданий Ñокет закритий" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "Ð”Ð»Ñ SOCKSv4 не передбачено підтримки адреÑи IPv6 «%s»" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача задовге Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ñƒ SOCKSv4" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "Ðазва вузла «%s» задовга Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ñƒ SOCKSv4" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Сервер не Ñ” прокÑÑ–-Ñервером SOCKSv4." + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· Ñервер SOCKSv4 було відхилено" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Сервер не Ñ” прокÑÑ–-Ñервером SOCKSv5." + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "ПрокÑÑ– SOCKSv5 вимагає автентифікацію." + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Ð”Ð»Ñ Ð¿Ñ€Ð¾ÐºÑÑ– SOCKSv5 потрібен метод автентифікації, Ñкий не підтримуєтьÑÑ GLib." + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача або пароль задовгі Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ñƒ SOCKSv5." + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" +"Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ð¹Ñ‚Ð¸ автентифікацію SOCKSv5 через неправильне ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача " +"або пароль." + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "Ðазва вузла «%s» задовга Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ñƒ SOCKSv5" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "ПрокÑÑ–-Ñервер SOCKSv5 викориÑтовує невідомий тип адреÑи." + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° прокÑÑ–-Ñервера SOCKSv5." + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ SOCKSv5 заборонено набором правил." + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Ðемає доÑтупу до вузла через Ñервер SOCKSv5." + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Мережа недоÑтупна через прокÑÑ– SOCKSv5." + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Під'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· прокÑÑ– SOCKSv5 відхилено." + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "" +"Ð”Ð»Ñ Ð¿Ñ€Ð¾ÐºÑÑ–-Ñерверів SOCKSv5 не передбачено підтримки команди «connect»." + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "ПрокÑÑ– SOCKSv5 не підтримує пропонований тип адреÑи." + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Ðевідома помилка прокÑÑ– SOCKSv5." + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ Ð´Ð»Ñ Ð¾Ð±Ð¼Ñ–Ð½Ñƒ з дочірнім процеÑом (%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "Ðа цій платформі підтримки конвеєрів не передбачено" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ верÑÑ–ÑŽ %d ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ GThemedIcon" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "Ðе знайдено коректних адреÑ" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "Помилка зворотного Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ за адреÑою «%s»: %s" + +#. Translators: the placeholder is a DNS record type, such as ‘MX’ or ‘SRV’ +#: gio/gthreadedresolver.c:550 gio/gthreadedresolver.c:572 +#: gio/gthreadedresolver.c:610 gio/gthreadedresolver.c:657 +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:698 +#, c-format +msgid "Error parsing DNS %s record: malformed DNS packet" +msgstr "" +"Помилка під Ñ‡Ð°Ñ Ñпроби обробити Ð·Ð°Ð¿Ð¸Ñ DNS %s: помилкове Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°ÐºÐµÑ‚Ð°" +" DNS" + +#: gio/gthreadedresolver.c:756 gio/gthreadedresolver.c:893 +#: gio/gthreadedresolver.c:991 gio/gthreadedresolver.c:1041 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "Ðемає запиÑу DNS з запитуваним типом «%s»" + +#: gio/gthreadedresolver.c:761 gio/gthreadedresolver.c:996 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "ТимчаÑово неможливо розв'Ñзати «%s»" + +#: gio/gthreadedresolver.c:766 gio/gthreadedresolver.c:1001 +#: gio/gthreadedresolver.c:1111 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "Помилка при розв'Ñзанні імені «%s»" + +#: gio/gthreadedresolver.c:780 gio/gthreadedresolver.c:804 +#: gio/gthreadedresolver.c:829 gio/gthreadedresolver.c:844 +msgid "Malformed DNS packet" +msgstr "Помилкове Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°ÐºÐµÑ‚Ð° DNS" + +#: gio/gthreadedresolver.c:886 +#, c-format +#| msgid "Failed to read from file “%sâ€: %s" +msgid "Failed to parse DNS response for “%sâ€: " +msgstr "Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ відповідь DNS Ð´Ð»Ñ Â«%s»: " + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "Ðе знайдено Ñекретний ключ у форматі PEM" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ñ‚Ð¸ Ñекретний ключ у форматі PEM" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ Ñекретний ключ у форматі PEM" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "Ðе знайдено Ñертифікат у форматі PEM" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ Ñертифікат у форматі PEM" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "У поточному модулі обробки TLS не передбачено підтримки PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "" +"У цьому GTlsBackend не передбачено підтримки ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñертифікатів PKCS #11" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Це оÑÑ‚Ð°Ð½Ð½Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ñ–Ñть правильно увеÑти пароль перед тим, Ñк доÑтуп буде " +"заблоковано." + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Пароль було декілька разів введено неправильно, піÑÐ»Ñ Ð½Ð°Ñтупних відмов ваш " +"доÑтуп буде заблоковано." + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "Уведено неправильний пароль." + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "Підтримки надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´ÐµÑкриптора файла не передбачено" + +# c-format +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "ОчікуєтьÑÑ 1 контрольне повідомленнÑ, отримано %d" +msgstr[1] "ОчікуєтьÑÑ 1 контрольне повідомленнÑ, отримано %d" +msgstr[2] "ОчікуєтьÑÑ 1 контрольне повідомленнÑ, отримано %d" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "Ðеочікуваний тип допоміжних даних" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "ОчікуєтьÑÑ Ð¾Ð´Ð¸Ð½ файловий деÑкриптор але отримано %d\n" +msgstr[1] "ОчікуєтьÑÑ Ð¾Ð´Ð¸Ð½ файловий деÑкриптор але отримано %d\n" +msgstr[2] "ОчікуєтьÑÑ Ð¾Ð´Ð¸Ð½ файловий деÑкриптор але отримано %d\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "Отримано неправильний fd" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "Підтримки Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´ÐµÑкриптора файла не передбачено" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при відправленні мандату:" + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при перевірці Ð²Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ SO_PASSCRED Ð´Ð»Ñ Ñокета: %s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при вмиканні SO_PASSCRED: %s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"ОчікувалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ один байт ідентифікаційної інформації (credentials), " +"але не прочитано жодного байту" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Контрольне Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð½Ðµ очікувалоÑÑ, але отримано %d" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при вимкненні SO_PASSCRED: %s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Помилка при читанні з файлового деÑкриптора: %s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Помилка при закритті файлового деÑкриптора: %s" + +#: gio/gunixmounts.c:2809 gio/gunixmounts.c:2862 +msgid "Filesystem root" +msgstr "Корінь файлової ÑиÑтеми" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Помилка при запиÑу у файловий деÑкриптор: %s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "" +"ÐбÑтрактні адреÑи доменних Ñокетів UNIX не підтримуютьÑÑ Ð½Ð° цій ÑиÑтемі" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "Ð´Ð»Ñ Ñ‚Ð¾Ð¼Ñƒ не реалізовано операції Ð²Ð¸ÑˆÑ‚Ð¾Ð²Ñ…ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾ÑÑ–Ñ" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "" +"Ð´Ð»Ñ Ñ‚Ð¾Ð¼Ñƒ не реалізовано підтримку Ð²Ð¸ÑˆÑ‚Ð¾Ð²Ñ…ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾ÑÑ–Ñ Ð°Ð±Ð¾ ж Ð²Ð¸ÑˆÑ‚Ð¾Ð²Ñ…ÑƒÐ²Ð°Ð½Ð½Ñ Ð· " +"операцією" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при читанні з деÑкриптора: %s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при закритті деÑкриптора: %s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при запиÑу у деÑкриптор: %s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Бракує пам'Ñті" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: %s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Потрібно більше вхідних даних" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Ðеправильно ÑтиÑнені дані" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "ПроÑлуховувана адреÑа" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "ІгноруєтьÑÑ, Ð´Ð»Ñ ÑуміÑноÑті з GTestDbus" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Ðадрукувати адреÑу" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "Ðадрукувати адреÑу у режимі оболонки" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "ЗапуÑк Ñлужби dbus" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "Ðеправильні параметри\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "Ðеочікуваний атрибут «%s» Ð´Ð»Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚Ð° «%s»" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "Ðтрибута «%s» Ð´Ð»Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚Ð° «%s» не Ñ–Ñнує" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "Ðеочікуваний теґ «%s», мало бути викориÑтано теґ «%s»" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "Ðеочікуваний теґ «%s» у «%s»" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "Ðекоректний Ð·Ð°Ð¿Ð¸Ñ Ð´Ð°Ñ‚Ð¸ Ñ– чаÑу «%s» у файлі закладок" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ правильний файл закладок у каталогах даних" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "Файл закладок Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи «%s» вже Ñ–Ñнує" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "Ðе знайдено закладки Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи «%s»" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "Ðе визначено тип MIME у закладці Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи «%s»" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "Ðе вказано приватну ознаку у закладці Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи «%s»" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "Ðе вÑтановлено групи у закладці Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи «%s»" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "Ðе зареєÑтровано програму з назвою «%s» Ð´Ð»Ñ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÐ¸ «%s»" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "Помилка Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ñ€Ñдка виконуваного файла «%s» Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑи «%s»" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "Ðевідтворюваний Ñимвол у вхідних даних перетвореннÑ" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "Ðезавершена Ñимвольна поÑлідовніÑть на кінці вводу" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "Ðеможливо коректно перетворити Ñимвол «%s» у Ñимвол з набору «%s»" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "Вбудований нульовий байт у вхідних даних перетвореннÑ" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "Вбудований нульовий байт у результатах перетвореннÑ" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "ÐдреÑа «%s» не Ñ” абÑолютною адреÑою із викориÑтаннÑм Ñхеми «file»" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "ÐдреÑа «%s» локального файла не може міÑтити Ñимвол «#»" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "Ðекоректна адреÑа «%s»" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "Ðеправильна назва вузла в URI «%s»" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "Ідентифікатор URI «%s» міÑтить неправильно екранований Ñимвол" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "ШлÑÑ… «%s» не Ñ” абÑолютним" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %b %e %H:%M:%S %Y" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%m/%d/%y" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "Ñічень" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "лютий" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "березень" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "квітень" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "травень" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "червень" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "липень" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "Ñерпень" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "вереÑень" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "жовтень" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "лиÑтопад" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "грудень" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Ñіч" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "лют" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "бер" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "кві" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "тра" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "чер" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "лип" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Ñерп" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "вер" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "жовт" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "лиÑÑ‚" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "груд" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "понеділок" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "вівторок" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Ñереда" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "четвер" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "п'ÑтницÑ" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Ñубота" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "неділÑ" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "пн" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "вт" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "ÑÑ€" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "чт" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "пт" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Ñб" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "нд" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "ÑічнÑ" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "лютого" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "березнÑ" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "квітнÑ" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "травнÑ" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "червнÑ" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "липнÑ" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "ÑерпнÑ" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "вереÑнÑ" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "жовтнÑ" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "лиÑтопада" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "груднÑ" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Ñіч" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "лют" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "бер" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "квіт" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "трав" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "черв" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "лип" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Ñерп" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "вер" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "жовт" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "лиÑÑ‚" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "груд" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "Помилка Ð²Ñ–Ð´ÐºÑ€Ð¸Ð²Ð°Ð½Ð½Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ñƒ «%s»: %s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "Ðе вдалоÑÑ Ð²Ð¸Ð´Ñ–Ð»Ð¸Ñ‚Ð¸ %lu байт Ð´Ð»Ñ Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»" +msgstr[1] "Ðе вдалоÑÑ Ð²Ð¸Ð´Ñ–Ð»Ð¸Ñ‚Ð¸ %lu байтів Ð´Ð»Ñ Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»" +msgstr[2] "Ðе вдалоÑÑ Ð²Ð¸Ð´Ñ–Ð»Ð¸Ñ‚Ð¸ %lu байтів Ð´Ð»Ñ Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "Помилка при читанні файла «%s»: %s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "Файл «%s» занадто великий" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "Помилка Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð· файла «%s»: %s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл «%s»: %s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "Помилка Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ñ–Ð² файла «%s»: помилка fstat(): %s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "Помилка Ð²Ñ–Ð´ÐºÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»: помилка fdopen(): %s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "Помилка Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° «%s» на «%s»: помилка g_rename(): %s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати файл «%s»: збій у функції write(): %s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "Помилка запиÑу у файл «%s»: помилка fsync(): %s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»: %s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð»ÑƒÑ‡Ð¸Ñ‚Ð¸ наÑвний файл «%s»: помилка g_unlink(): %s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "Шаблон «%s» неправильний, бо не може міÑтити «%s»" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "Шаблон «%s» не міÑтить XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñимволічного поÑÐ¸Ð»Ð°Ð½Ð½Ñ Â«%s»: %s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ модуль Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð· «%s» у «%s»: %s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "" +"Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ безпоÑереднє Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ функції " +"g_io_channel_read_line_string" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "Ð’ буфері Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð»Ð¸ÑˆÐ¸Ð»Ð¸ÑÑŒ не перетворені дані" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "Канал завершуєтьÑÑ Ð½Ð° неповному Ñимволі" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "" +"Ðе можна виконувати безпоÑереднє Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ функції " +"g_io_channel_read_to_end" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ правильний ключовий файл у каталогах ключів" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "Ðе Ñ” звичайним файлом" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "" +"Файл ключа міÑтить Ñ€Ñдок «%s», Ñкий не Ñ” парою ключ-значеннÑ, групою або " +"коментарем" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "Ðеправильна назва групи: %s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "Ключовий файл не починаєтьÑÑ Ð· групи" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "Ðеправильна назва ключа: %.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "Файл ключа міÑтить кодуваннÑ, підтримки Ñкого не передбачено — «%s»" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "Файл ключа не міÑтить групи «%s»" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "Файл ключа не міÑтить ключ «%s» у групі «%s»" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "" +"Файл ключа міÑтить ключ «%s» зі значеннÑм «%s», ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ñкого не Ñ” " +"кодуваннÑм UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "" +"Ключ «%s» з файла ключів міÑтить значеннÑ, Ñке не вдаєтьÑÑ Ð¿Ñ€Ð¾Ð°Ð½Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸." + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "" +"Файл ключів міÑтить ключ «%s» у групі «%s», Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñкого не вдалоÑÑ " +"розпізнати." + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° «%s» у групі «%s» дорівнює «%s», але очікувалоÑÑ Â«%s»" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "Ключовий файл міÑтить escape-Ñимвол наприкінці Ñ€Ñдка" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "Файл ключа міÑтить неправильну поÑлідовніÑть ÐµÐºÑ€Ð°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Â«%s»" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» Ñк чиÑло." + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "ЧиÑлове ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» поза межами діапазону" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» не вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ на чиÑло з рухомою комою." + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» Ñк логічне значеннÑ." + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "" +"Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ атрибути файла «%s%s%s%s»: збій у функції fstat(): %s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Ðе вдалоÑÑ Ð¿Ð¾ÐºÐ°Ð·Ð°Ñ‚Ð¸ файл «%s%s%s%s»: збій у функції mmap(): %s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "Помилка Ð²Ñ–Ð´ÐºÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° «%s»: помилка open(): %s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Помилка в Ñ€Ñдку %d на Ñимволі %d: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "Ðекоректний текÑÑ‚ у кодуванні UTF-8 у назві — не Ñ” коректним «%s»" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "«%s» не Ñ” коректною назвою" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "«%s» не Ñ” коректною назвою: «%c»" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "Помилка в Ñ€Ñдку %d: %s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Помилка аналізу виразу «%-.*s», де має бути чиÑло у Ñимволічному поÑиланні " +"(наприклад, ê). Можливо, чиÑло Ñ” надто великим." + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° Ñимвол не закінчуєтьÑÑ ÐºÑ€Ð°Ð¿ÐºÐ¾ÑŽ з комою, Ñхоже Ñимвол \"&\" було " +"викориÑтано не Ð´Ð»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ предиката – екрануйте його Ñк &." + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° Ñимвол «%-.*s» не визначає жоден дозволений Ñимвол" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "" +"ВиÑвлено порожній предикат «&;»; допуÑтимими предикатами Ñ”: & " " +"< > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "Ðазва предиката «%-.*s» Ñ” невідомою програмі" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Предикат не закінчуєтьÑÑ ÐºÑ€Ð°Ð¿ÐºÐ¾ÑŽ з комою; очевидно, що Ñимвол & було " +"викориÑтано не Ð´Ð»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ предиката – екрануйте його Ñк &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "Документ має починатиÑÑ Ð· елемента (наприклад, )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "" +"Символ «%s» не можна вживати піÑÐ»Ñ Ñимволу «<», він не може починати назву " +"елемента" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "" +"Зайвий Ñимвол «%s», очікувавÑÑ Ñимвол «>» Ð´Ð»Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÒ‘Ñƒ порожнього " +"елементу «%s»" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "Забагато атрибутів у елементі «%s»" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "" +"Зайвий Ñимвол «%s», очікувавÑÑ Ñимвол «=» піÑÐ»Ñ Ð½Ð°Ð·Ð²Ð¸ ознаки «%s» елемента " +"«%s»" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Зайвий Ñимвол «%s», очікувалиÑÑŒ Ñимволи «>» чи «/», Ð´Ð»Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ð³Ð¾ " +"теґу елемента «%s», чи додаткова ознака; можливо, було викориÑтано " +"неприпуÑтимий Ñимвол в назві ознаки" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"Зайвий Ñимвол «%s», мало бути вказано початкові лапки піÑÐ»Ñ Ð·Ð½Ð°ÐºÑƒ рівноÑті " +"на приÑвоєнні Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¾Ð·Ð½Ð°Ñ†Ñ– «%s» елемента «%s»" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "" +"Символ «%s» неприпуÑтимий на закритті назви елемента «%s»; припуÑтимим " +"Ñимволом Ñ” «>»" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "Було закрито не відкритий елемент «%s»" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "Було закрито елемент «%s», але зараз відрито елемент «%s»" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "Документ порожній чи міÑтить лише пропуÑки" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "Документ раптово закінчивÑÑ Ð²Ñ–Ð´Ñ€Ð°Ð·Ñƒ піÑÐ»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— кутової дужки «<»" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "" +"Документ раптово закінчивÑÑ, коли деÑкі елементи ще були відкритими – «%s» " +"був оÑтаннім відкритим елементом" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Документ раптово закінчивÑÑ, очікувалаÑÑŒ кінцева кутова дужка Ð´Ð»Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ " +"теґу <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "Документ раптово закінчивÑÑ Ð¿Ð¾Ñеред назви елемента" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Документ раптово закінчивÑÑ Ð¿Ð¾Ñеред назви ознаки" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Документ раптово закінчивÑÑ Ñƒ Ñередині теґу, що відкривав елемент" + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Документ раптово закінчивÑÑ Ð¿Ñ–ÑÐ»Ñ Ð·Ð½Ð°ÐºÐ° рівноÑті, що йшов за назвою ознаки; " +"Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¾Ð·Ð½Ð°ÐºÐ¸ не вказано" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Документ раптово закінчивÑÑ Ð¿Ð¾Ñеред Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¾Ð·Ð½Ð°ÐºÐ¸" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "Документ раптово закінчивÑÑ Ñƒ Ñередині теґу, що закривав елемент «%s»" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "Документ раптово закінчивÑÑ Ñƒ Ñередині теґу Ð´Ð»Ñ Ð½ÐµÐ²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¾Ð³Ð¾ елемента" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "Документ раптово закінчивÑÑ Ñƒ Ñередині коментарю чи інÑтрукції обробки" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[ПÐРÐМЕТР…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "Параметри довідки:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "Показати параметри довідки" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "Показати уÑÑ– параметри довідки" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "Параметри програми:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "Параметри:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ чиÑлове ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» Ð´Ð»Ñ %s" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "ЧиÑлове ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s» Ð´Ð»Ñ %s поза межами діапазону" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ чиÑлове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð´Ð²Ñ–Ð¹Ð½Ð¾Ñ— точноÑті «%s» Ð´Ð»Ñ %s" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "ЧиÑлове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð´Ð²Ñ–Ð¹Ð½Ð¾Ñ— точноÑті «%s» Ð´Ð»Ñ %s поза межами діапазону" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "Помилка розбору параметра %s" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "ВідÑутній аргумент %s" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "Ðевідомий параметр %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "пошкоджений об'єкт" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° або пошкоджений об'єкт" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "недоÑтатньо пам'Ñті" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "закінчилоÑÑ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¾Ð³Ð¾ ходу" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "" +"шаблон міÑтить елементи, Ñкі не підтримуютьÑÑ Ð¿Ñ€Ð¸ пошуку чаÑткової " +"відповідноÑті" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "" +"умови у виглÑді зворотних поÑилань при пошуку чаÑткової відповідноÑті не " +"підтримуютьÑÑ" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "доÑÑгнуто межу рекурÑÑ–Ñ—" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "некоректна ÐºÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ–Ñ Ð¾Ð·Ð½Ð°Ðº Ð¿ÐµÑ€ÐµÐ²ÐµÐ´ÐµÐ½Ð½Ñ Ñ€Ñдка" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "неправильне зміщеннÑ" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "короткий utf8" + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "Ð·Ð°Ñ†Ð¸ÐºÐ»ÑŽÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÐºÑƒÑ€ÑÑ–Ñ—" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "невідома помилка" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ наприкінці шаблону" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "\\c наприкінці шаблону" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "нерозпізнаний Ñимвол Ñлідує за \\" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "неправильний порÑдок чиÑел у Ñпецифікаторі {}" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "надто велике чиÑло у Ñпецифікаторі {}" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "відÑутній завершальний Ñимвол ] Ð´Ð»Ñ ÐºÐ»Ð°Ñу Ñимволів" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "Ðеправильна escape-поÑлідовніÑть у клаÑÑ– Ñимволів" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "неправильний порÑдок у діапазоні у клаÑÑ– Ñимволів" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "немає що повторювати" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "неочікуваний повтор" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "нерозпізнаний Ñимвол піÑÐ»Ñ (? або (?-" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "назви клаÑів у Ñтилі POSIX підтримуютьÑÑ Ð»Ð¸ÑˆÐµ у межах клаÑÑ–" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "відÑутній завершальний Ñимвол )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° вкладений шаблон, Ñкого не Ñ–Ñнує" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "відÑÑƒÑ‚Ð½Ñ Ð´ÑƒÐ¶ÐºÐ° ) піÑÐ»Ñ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "задовгий регулÑрний вираз" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "не вдаєтьÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ пам'Ñть" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") без початкової дужки (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÐºÐ¾Ð´Ñƒ" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "нерозпізнаний Ñимвол піÑÐ»Ñ (?<" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ lookbehind має не фікÑовану довжину" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "неправильне чиÑло або назва піÑÐ»Ñ (?(" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "група умови міÑтить більше ніж дві гілки" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "піÑÐ»Ñ (?( очікуєтьÑÑ Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(за ?R або (?[+-]цифри має бути вказано дужку )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "невідома POSIX-назва клаÑу" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "елементи порівнÑÐ½Ð½Ñ Ñƒ Ñтилі POSIX не підтримуютьÑÑ" + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñимволу у поÑлідовноÑті \\x{...} надто велике" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "неправильний вираз (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C неприпуÑтимий у твердженні lookbehind" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "ÐµÐºÑ€Ð°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ \\L, \\l, \\N{name}, \\U Ñ– \\u не підтримуєтьÑÑ" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "рекурÑивний виклик може увійти у неÑкінчений цикл" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "нерозпізнаний Ñимвол піÑÐ»Ñ (?P" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "відÑутній завершальний Ñимвол у назві вкладеного шаблону" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "два іменовані вкладені шаблони мають однакову назву" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "неправильна поÑлідовніÑть \\P чи \\p" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "невідома назва влаÑтивоÑті піÑÐ»Ñ \\P чи \\p" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "вкладена назва шаблону надто довга (макÑимум 32 Ñимволів)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "надто багато іменованих вкладених шаблонів (макÑимум 10,000)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "віÑімкове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð±Ñ–Ð»ÑŒÑˆÐµ ніж \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸ компілÑції робочого проÑтору" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "" +"раніше перевірений вкладений шаблон, на Ñкий йде поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ðµ знайдений" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "група DEFINE міÑтить більш ніж одну гілку" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "неузгоджені параметри NEWLINE" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g не ÑупроводжуєтьÑÑ Ð½Ð°Ð·Ð²Ð¾ÑŽ або чиÑлом у дужках, кутових дужках або " +"лапках, або проÑто чиÑлом" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "номерне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ðµ може бути нулем" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "не можна вказувати параметр Ð´Ð»Ñ (*ACCEPT), (*FAIL) або (*COMMIT)" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (*VERB) не розпізнано" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "завелике чиÑло" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "немає назви підшаблону піÑÐ»Ñ (?&" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "очікувалаÑÑ Ñ†Ð¸Ñ„Ñ€Ð° піÑÐ»Ñ (?+" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "не можна викориÑтовувати Ñимвол ] у режимі ÑуміÑноÑті із JavaScript" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "" +"не припуÑкаєтьÑÑ Ð²Ð¸ÐºÐ¾Ñ€Ð¸Ñтовувати різні імена Ð´Ð»Ñ Ð¿Ñ–Ð´ÑˆÐ°Ð±Ð»Ð¾Ð½Ñ–Ð² з однаковим " +"номером" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "Ð´Ð»Ñ (*MARK) потрібен параметр" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "за \\з повинен бути Ñимвол ASCII" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "за \\k не Ñлідує назва у дужках, кутових дужках або лапках" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "\\N у клаÑÑ– не підтримуєтьÑÑ" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "забагато прÑмих поÑилань" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "задовга назва у (*MARK), (*PRUNE), (*SKIP) або (*THEN)" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "завелике Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñимволу у \\u…" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ відповідноÑті регулÑрному виразу %s: %s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Бібліотека PCRE не підтримує UTF8" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Бібліотека PCRE не підтримує влаÑтивоÑті у кодуванні UTF8" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "Бібліотека PCRE зібрана з неÑуміÑними параметрами" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "При оптимізації регулÑрного виразу %s виникла помилка: %s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Помилка при компілÑції регулÑрного виразу %s на Ñимволі %d: %s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "мало бути викориÑтано шіÑтнадцÑткову цифру або Ñимвол «}»" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "очікуєтьÑÑ ÑˆÑ–ÑтнадцÑткова цифра" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "у Ñимволічному поÑиланні пропущено «<»" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "незакінчене Ñимвольне поÑиланнÑ" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "Ñимвольне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½ÑƒÐ»ÑŒÐ¾Ð²Ð¾Ñ— довжини" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "очікуєтьÑÑ Ñ†Ð¸Ñ„Ñ€Ð°" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "некоректне Ñимвольне поÑиланнÑ" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "відкидати кінцеві «\\»" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "невідома escape-поÑлідовніÑть" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "" +"Під Ñ‡Ð°Ñ Ñ€Ð¾Ð·Ð±Ð¾Ñ€Ñƒ текÑту заміни «%s» ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° у Ñимволі з номером %lu: " +"%s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "ТекÑÑ‚ в лапках не починаєтьÑÑ Ð· лапок" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "Ðевідповідні лапки у командному Ñ€Ñдку чи іншому текÑті оболонки" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "ТекÑÑ‚ закінчивÑÑ Ð¿ÐµÑ€ÐµÐ´ Ñимволом «\\». (ТекÑÑ‚ був таким: «%s»)" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "" +"ТекÑÑ‚ закінчивÑÑ Ð¿ÐµÑ€ÐµÐ´ відповідними лапками Ð´Ð»Ñ %c. (ТекÑÑ‚ був таким: «%s»)" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "ТекÑÑ‚ порожній (чи міÑтить лише пропуÑки)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Помилка Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… з дочірнього процеÑу (%s)" + +#: glib/gspawn.c:462 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "Ðеочікувана помилка під Ñ‡Ð°Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… з дочірнього процеÑу (%s)" + +#: glib/gspawn.c:547 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Ðеочікувана помилка у waitpid() (%s)" + +#: glib/gspawn.c:1175 glib/gspawn-win32.c:1438 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Дочірній Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð·Ð°ÐºÑ–Ð½Ñ‡Ð¸Ð²ÑÑ Ð· кодом %ld" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Дочірній Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð²Ð±Ð¸Ñ‚Ð¸Ð¹ за Ñигналом %ld" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Дочірній Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð·ÑƒÐ¿Ð¸Ð½ÐµÐ½Ð¸Ð¹ за Ñигналом %ld" + +#: glib/gspawn.c:1197 +#, c-format +msgid "Child process exited abnormally" +msgstr "Дочірній Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð°Ð²Ð°Ñ€Ñ–Ð¹Ð½Ð¾ закінчив роботу" + +#: glib/gspawn.c:1890 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Помилка Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð· дочірнього каналу (%s)" + +#: glib/gspawn.c:2253 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити дочірній Ð¿Ñ€Ð¾Ñ†ÐµÑ Â«%s» (%s)" + +#: glib/gspawn.c:2370 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу (%s)" + +#: glib/gspawn.c:2530 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "Ðе вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ каталог на «%s» (%s)" + +#: glib/gspawn.c:2540 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ дочірній Ð¿Ñ€Ð¾Ñ†ÐµÑ Â«%s» (%s)" + +#: glib/gspawn.c:2550 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð¸ прив'Ñзки деÑкриптора файла (%s)" + +#: glib/gspawn.c:2558 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "Ðе вдалоÑÑ Ð·Ð´ÑƒÐ±Ð»ÑŽÐ²Ð°Ñ‚Ð¸ деÑкриптор файла Ð´Ð»Ñ Ð´Ð¾Ñ‡Ñ–Ñ€Ð½ÑŒÐ¾Ð³Ð¾ процеÑу (%s)" + +#: glib/gspawn.c:2567 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Помилка запуÑку дочірнього процеÑу (%s)" + +#: glib/gspawn.c:2575 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ деÑкриптор файла Ð´Ð»Ñ Ð´Ð¾Ñ‡Ñ–Ñ€Ð½ÑŒÐ¾Ð³Ð¾ процеÑу (%s)" + +#: glib/gspawn.c:2583 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "Ðевідома помилка Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð´Ð¾Ñ‡Ñ–Ñ€Ð½ÑŒÐ¾Ð³Ð¾ процеÑу «%s»" + +#: glib/gspawn.c:2607 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Ðе вдалоÑÑ Ð·Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ доÑтатню кількіÑть даних з дочірнього каналу (%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "Помилка Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… з дочірнього процеÑу" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:521 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Помилка Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð´Ð¾Ñ‡Ñ–Ñ€Ð½ÑŒÐ¾Ð³Ð¾ процеÑу (%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ dup() у дочірньому процеÑÑ– (%s)" + +#: glib/gspawn-win32.c:471 +#, c-format +msgid "Invalid program name: %s" +msgstr "Ðеправильна назва програми: %s" + +#: glib/gspawn-win32.c:481 glib/gspawn-win32.c:807 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Ðеправильний Ñ€Ñдок у векторі аргументів %d: %s" + +#: glib/gspawn-win32.c:492 glib/gspawn-win32.c:823 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Ðеправильний Ñ€Ñдок у Ñередовищі: %s" + +#: glib/gspawn-win32.c:803 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Ðеправильний робочий каталог: %s" + +#: glib/gspawn-win32.c:868 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ допоміжну програму (%s)" + +#: glib/gspawn-win32.c:1096 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Ðеочікувана помилка в зчитуванні даних з дочірнього процеÑу через " +"g_io_channel_win32_poll() " + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "Порожній Ñ€Ñдок не Ñ” чиÑлом" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "«%s» не Ñ” чиÑлом зі знаком" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "ЧиÑло «%s» не належить до діапазону [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "«%s» не Ñ” чиÑлом без знаку" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "Ðекоректне %-eÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð² адреÑÑ–" + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "Ðекоректний Ñимвол в адреÑÑ–" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "Символи поза UTF-8 в адреÑÑ–" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "Ðекоректна IPv6-адреÑа «%.*s» в адреÑÑ–" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "Помилкове ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ IP-адреÑи «%.*s» в адреÑÑ–" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "Ðазва вузла із некоректними Ñимволами «%.*s» у адреÑÑ–" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "Ðе вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ Ð·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ñ€Ñ‚Ñƒ «%.*s» в адреÑÑ–" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "Порт «%.*s» в адреÑÑ– не належить до припуÑтимого діапазону" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "ÐдреÑа «%s» не Ñ” абÑолютною адреÑою" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "Ð’ адреÑÑ– «%s» немає компонента вузла" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "ÐдреÑа не Ñ” абÑолютною, Ñ– не вказано базової адреÑи" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "Пропущено «=» Ñ– Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ñ–Ð»Ð¸Ñ‚Ð¸ пам'Ñть" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "Символ не входить в набір UTF-8" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "Ðеправильна поÑлідовніÑть у перетворюваному вводі" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "Символ не входить в набір UTF-16" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f кБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ТБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ПБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ЕБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f КіБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f МіБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f ГіБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f ТіБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f ПіБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f ЕіБ" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f кбіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Мбіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Гбіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Тбіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Пбіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Ебіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Кібіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Мібіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Гібіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Тібіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Пібіт" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Еібіт" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u байт" +msgstr[1] "%u байти" +msgstr[2] "%u байтів" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u байт" +msgstr[1] "%u бітів" +msgstr[2] "%u байтів" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s байт" +msgstr[1] "%s байти" +msgstr[2] "%s байтів" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s біт" +msgstr[1] "%s біти" +msgstr[2] "%s бітів" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f КБ" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ТБ" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ПБ" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ЕБ" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "" +#~ "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ /var/lib/dbus/machine-id або /etc/machine-id: " + +#~ msgid "Unknown error on connect" +#~ msgstr "Ðевідома помилка при з'єднанні" diff --git a/po/vi.po b/po/vi.po new file mode 100644 index 0000000..bec6e5b --- /dev/null +++ b/po/vi.po @@ -0,0 +1,4891 @@ +# Vietnamese translation for GLib. +# Bản dịch tiếng Việt dành cho GLib. +# Copyright © 2016 GNOME i18n Project for Vietnamese. +# This file is distributed under the same license as the glib package. +# T.M.Thanh , 2002. +# Clytie Siddall , 2005-2010. +# Nguyá»…n Thái Ngá»c Duy , 2009-2013. +# Trần Ngá»c Quân , 2014, 2015, 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2016-03-26 19:51+0000\n" +"PO-Revision-Date: 2016-03-27 08:18+0700\n" +"Last-Translator: Trần Ngá»c Quân \n" +"Language-Team: Vietnamese \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Gtranslator 2.91.7\n" + +#: ../gio/gapplication.c:493 +msgid "GApplication options" +msgstr "Tùy chá»n GApplication" + +#: ../gio/gapplication.c:493 +msgid "Show GApplication options" +msgstr "Hiển thị tùy chá»n GApplication" + +#: ../gio/gapplication.c:538 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "" +"Nhập vào chế độ dịch vụ GApplication (dùng từ các tập tin dịch vụ D-Bus)" + +#: ../gio/gapplication.c:550 +msgid "Override the application's ID" +msgstr "Äè lên Mà Sá» cá»§a ứng dụng" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:488 ../gio/gsettings-tool.c:512 +msgid "Print help" +msgstr "In trợ giúp" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:489 +#: ../gio/gresource-tool.c:557 +msgid "[COMMAND]" +msgstr "[LỆNH]" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "Hiển thị phiên bản" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:518 +msgid "Print version information and exit" +msgstr "Hiển thị thông tin phiên bản rồi thoát" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "Liệt kê ứng dụng" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "" +"Liệt kê các ứng dụng có thể kích hoạt từ D-Bus (bằng các tập tin .desktop)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "Khởi chạy má»™t ứng dụng" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "Khởi chạy ứng dụng (vá»›i các tập tin tùy chá»n cần mở)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "MÃSá»á»¨NGDỤNG [TẬP TIN…]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "Kích hoạt má»™t thao tác" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "Gá»i má»™t thao tác trên ứng dụng" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "MÃSá»á»¨NGDỤNG THAOTÃC [Äá»ISá»]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "Liệt kê các thao tác sẵn có" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "Liệt kê các thao tác tÄ©nh cho má»™t ứng dụng (từ tập tin .desktop)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "MÃSá»á»¨NGDỤNG" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "LỆNH" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "Lệnh để hiển thị trợ giúp chi tiết cho" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "Äịnh danh ứng dụng theo định dạng D-Bus (vd: org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:592 +#: ../gio/glib-compile-resources.c:623 ../gio/gresource-tool.c:495 +#: ../gio/gresource-tool.c:561 +msgid "FILE" +msgstr "TẬP_TIN" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "Các tên tập tin tùy chá»n dạng tương đối hay tuyệt đối, hay URI muốn mở" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "THAOTÃC" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "Tên thao tác cần gá»i" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "Äá»ISá»" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "Tham số tùy chá»n cho gá»i thao tác, theo định dạng GVariant" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:526 +#: ../gio/gsettings-tool.c:598 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"Không biết lệnh “%sâ€\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "Cách dùng:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:551 +#: ../gio/gsettings-tool.c:632 +msgid "Arguments:\n" +msgstr "Äối số:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[Äá»I Sá»â€¦]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "Lệnh:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Gõ lệnh “%s help LỆNH†để biết thêm chi tiết.\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"lệnh %s cần má»™t mã số ứng dụng trá»±c tiếp sau đây\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "mã số ứng dụng không hợp lệ “%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"“%s†chẳng nhận đối số nào\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "không thể kết nối đến D-Bus: %s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "gặp lá»—i khi Ä‘ang gá»­i %s thông Ä‘iệp tá»›i ứng dụng: %s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "tên thao tác phải được đưa ra sau mã số ứng dụng\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"tên thao tác không hợp lệ: “%sâ€\n" +"tên thao tác chỉ có thể bao gồm chữ cái, “-†and “.â€\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "Gặp lá»—i khi phân tích tham số thao tác: %s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "thao tác chỉ chấp nhận nhiá»u nhất là má»™t đối số\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "lệnh list-actions chỉ nhận mã số ứng dụng" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "Không tìm thấy tập tin desktop cho ứng dụng %s\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"không nhận ra lệnh: %s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:179 ../gio/ginputstream.c:379 +#: ../gio/ginputstream.c:617 ../gio/ginputstream.c:1016 +#: ../gio/goutputstream.c:203 ../gio/goutputstream.c:834 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "Giá trị đếm quá lá»›n được gá»­i cho %s" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "" +"Chức năng seek (di chuyển vị trí Ä‘á»c) không được há»— trợ trên luồng cÆ¡ bản" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "Không thể cắt GBufferedInputStream" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1205 +#: ../gio/giostream.c:300 ../gio/goutputstream.c:1658 +msgid "Stream is already closed" +msgstr "Luồng đã bị đóng" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "Không cho phép cắt ngắn luồng cÆ¡ sở" + +#: ../gio/gcancellable.c:317 ../gio/gdbusconnection.c:1847 +#: ../gio/gdbusprivate.c:1375 ../gio/glocalfile.c:2220 +#: ../gio/gsimpleasyncresult.c:870 ../gio/gsimpleasyncresult.c:896 +#, c-format +msgid "Operation was cancelled" +msgstr "Thao tác bị thôi" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "Äối tượng không hợp lệ, chưa được khởi tạo" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "Gặp dãy byte không hoàn thiện trong đầu vào" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "Không đủ chá»— trống ở đích đến" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 ../glib/gconvert.c:845 +#: ../glib/giochannel.c:1556 ../glib/giochannel.c:1598 +#: ../glib/giochannel.c:2442 ../glib/gutf8.c:853 ../glib/gutf8.c:1306 +msgid "Invalid byte sequence in conversion input" +msgstr "dãy byte không hợp lệ trong phần đầu vào chuyển đổi" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 ../glib/gconvert.c:770 +#: ../glib/giochannel.c:1563 ../glib/giochannel.c:2454 +#, c-format +msgid "Error during conversion: %s" +msgstr "Gặp lá»—i khi chuyển đổi: %s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:1078 +msgid "Cancellable initialization not supported" +msgstr "Không há»— trợ thao tác khởi động có thể há»§y bá»" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1384 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Không há»— trợ việc chuyển từ đặt ký tá»± “%s†thành “%sâ€" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Không thể mở trình chuyển đổi từ “%s†sang “%sâ€" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "kiểu %s" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "Không rõ kiểu" + +#: ../gio/gcontenttype-win32.c:162 +#, c-format +msgid "%s filetype" +msgstr "kiểu tập tin %s" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials không được há»— trợ trên hệ Ä‘iá»u hành này" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "Không có há»— trợ GCredentials trên hệ Ä‘iá»u hành cá»§a bạn" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials không chứa ID tiến trình trên hệ Ä‘iá»u hành này" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "Lừa đảo chứng thư là không thể trên HDH này" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "Kết thúc luồng sá»›m bất thưá»ng" + +#: ../gio/gdbusaddress.c:153 ../gio/gdbusaddress.c:241 +#: ../gio/gdbusaddress.c:322 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "Khóa không há»— trợ “%s†ở đầu nhập địa chỉ “%sâ€" + +#: ../gio/gdbusaddress.c:180 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"Äịa chỉ “%s†không hợp lệ (cần chính xác má»™t đưá»ng dẫn, tmpdir hoặc khóa " +"tổng quát)" + +#: ../gio/gdbusaddress.c:193 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "Cặp khóa/giá trị vô nghÄ©a ở địa chỉ “%sâ€" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "Có lá»—i ở địa chỉ “%s†- thuá»™c tính cổng sai dạng" + +#: ../gio/gdbusaddress.c:267 ../gio/gdbusaddress.c:348 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "Có lá»—i ở địa chỉ “%s†- thuá»™c tính há» (family) sai dạng" + +#: ../gio/gdbusaddress.c:457 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "Thành phần địa chỉ “%s†không chứa dấu hai chấm (:)" + +#: ../gio/gdbusaddress.c:478 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "Cặp khóa/giá trị %d, “%s†ở địa chỉ “%s†không chứa dấu bằng" + +#: ../gio/gdbusaddress.c:492 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" +"Lá»—i unescape khóa hoặc giá trị trong cặp khóa/giá trị %d, “%sâ€, ở địa chỉ " +"“%sâ€" + +#: ../gio/gdbusaddress.c:570 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" +"Có lá»—i ở địa chỉ “%s†- phương thức vận chuyển unix cần đặt chính xác má»™t " +"trong những khóa “path†hoặc “abstractâ€" + +#: ../gio/gdbusaddress.c:606 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "Có lá»—i ở địa chỉ “%s†- thuá»™c tính máy thiếu hoặc sai dạng" + +#: ../gio/gdbusaddress.c:620 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "Có lá»—i ở địa chỉ “%s†- thuá»™c tính cổng thiếu hoặc sai dạng" + +#: ../gio/gdbusaddress.c:634 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "Có lá»—i ở địa chỉ “%s†- thuá»™c tính noncefile thiếu hoặc sai dạng" + +#: ../gio/gdbusaddress.c:655 +msgid "Error auto-launching: " +msgstr "Gặp lá»—i khi tá»± động khởi động: " + +#: ../gio/gdbusaddress.c:663 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" +"Phương thức vận chuyển “%s†cho địa chỉ “%s†không được há»— trợ, hoặc không " +"nhận ra" + +#: ../gio/gdbusaddress.c:699 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Gặp lá»—i khi mở nonce-file “%sâ€: %s" + +#: ../gio/gdbusaddress.c:717 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Gặp lá»—i khi Ä‘á»c nonce-file “%sâ€: %s" + +#: ../gio/gdbusaddress.c:726 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Gặp lá»—i khi Ä‘á»c nonce-file “%sâ€, cần 16 byte, nhưng lại nhận được %d" + +#: ../gio/gdbusaddress.c:744 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Gặp lá»—i khi ghi ná»™i dung nonce-file “%s†vào luồng:" + +#: ../gio/gdbusaddress.c:950 +msgid "The given address is empty" +msgstr "Äịa chỉ đã cho bị rá»—ng" + +#: ../gio/gdbusaddress.c:1063 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "Không thể tạo tuyến thông Ä‘iệp vá»›i setuid" + +#: ../gio/gdbusaddress.c:1070 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "Không thể tạo tuyến thông Ä‘iệp mà không có machine-id: " + +#: ../gio/gdbusaddress.c:1112 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "Gặp lá»—i khi chạy dòng lệnh “%sâ€: " + +#: ../gio/gdbusaddress.c:1329 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(Nhập ký tá»± bất kỳ để đóng cá»­a sổ)\n" + +#: ../gio/gdbusaddress.c:1481 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "Dbus cho phiên làm việc chưa chạy, tá»± động chạy thất bại" + +#: ../gio/gdbusaddress.c:1492 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" +"Không thể xác định địa chỉ tuyến phiên làm việc (chưa được há»— trợ trên hệ " +"Ä‘iá»u hành này)" + +#: ../gio/gdbusaddress.c:1627 ../gio/gdbusconnection.c:7128 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" +"Không thể xác định địa chỉ tuyến từ biến môi trưá»ng DBUS_STARTER_BUS_TYPE - " +"giá trị lạ “%sâ€" + +#: ../gio/gdbusaddress.c:1636 ../gio/gdbusconnection.c:7137 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Không thể xác định địa chỉ tuyến vì không có biến môi trưá»ng " +"DBUS_STARTER_BUS_TYPE" + +#: ../gio/gdbusaddress.c:1646 +#, c-format +msgid "Unknown bus type %d" +msgstr "Không rõ kiểu tuyến %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "Ná»™i dung bị thiếu bất thưá»ng khi Ä‘á»c má»™t dòng" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "Ná»™i dung bị thiếu bất thưá»ng khi Ä‘á»c (an toàn) má»™t dòng" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "Hết phương thức xác thá»±c hiện có (thá»­: %s) (còn: %s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "Äã há»§y thông qua GDBusAuthObserver::authorize-authenticated-peer" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "Gặp lá»—i khi lấy thông tin thư mục “%sâ€: %s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" +"Quyá»n cá»§a thư mục “%s†sai dạng. Giá trị là 0%o trong khi lẽ ra phải là 0700." + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "Gặp lá»—i khi tạo thư mục “%sâ€: %s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Gặp lá»—i khi mở chùm chìa khóa “%s†để Ä‘á»c: " + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "Dòng %d cá»§a keyring tại “%s†vá»›i ná»™i dung “%s†bị dị dạng" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"Token đầu tiên cá»§a dòng %d cá»§a keyring tại “%s†vá»›i ná»™i dung “%s†bị dị dạng" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" +"Token thứ hai cá»§a dòng %d cá»§a keyring tại “%s†vá»›i ná»™i dung “%s†bị dị dạng" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "Không tìm thấy cookie vá»›i id %d trong chùm chìa khóa ở “%sâ€" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Gặp lá»—i khi xóa tập tin khóa không dùng nữa “%sâ€: %s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Gặp lá»—i khi tạo tập tin khóa “%sâ€: %s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Gặp lá»—i khi đóng (unlink) tập tin khóa “%sâ€: %s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Gặp lá»—i xóa tập tin khóa “%sâ€: %s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Gặp lá»—i khi mở keyring “%s†để ghi: " + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(Ngoài ra, giải phóng khóa cho “%s†cÅ©ng thất bại: %s)" + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2373 +msgid "The connection is closed" +msgstr "Kết nối bị đóng lại" + +#: ../gio/gdbusconnection.c:1877 +msgid "Timeout was reached" +msgstr "Äã vượt qua thá»i gian chá»" + +#: ../gio/gdbusconnection.c:2495 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "Phát hiện cá» không há»— trợ khi tạo kết nối phía client" + +#: ../gio/gdbusconnection.c:4105 ../gio/gdbusconnection.c:4452 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" +"Không có giao diện “org.freedesktop.DBus.Properties†trên đối tượng tại " +"đưá»ng dẫn %s" + +#: ../gio/gdbusconnection.c:4247 +#, c-format +msgid "No such property '%s'" +msgstr "Không có thuá»™c tính “%sâ€" + +#: ../gio/gdbusconnection.c:4259 +#, c-format +msgid "Property '%s' is not readable" +msgstr "Thuá»™c tính “%s†không Ä‘á»c được" + +#: ../gio/gdbusconnection.c:4270 +#, c-format +msgid "Property '%s' is not writable" +msgstr "Thuá»™c tính “%s†không ghi được" + +#: ../gio/gdbusconnection.c:4290 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" +"Gặp lá»—i khi đặt thuá»™c tính “%sâ€: nhận được “%s†trong khi lẽ ra phải là “%sâ€" + +#: ../gio/gdbusconnection.c:4395 ../gio/gdbusconnection.c:6568 +#, c-format +msgid "No such interface '%s'" +msgstr "Không có giao diện “%sâ€" + +#: ../gio/gdbusconnection.c:4603 +msgid "No such interface" +msgstr "Không có giao diện như vậy" + +#: ../gio/gdbusconnection.c:4821 ../gio/gdbusconnection.c:7077 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "Không có giao diện “%s†trên đối tượng tại đưá»ng dẫn %s" + +#: ../gio/gdbusconnection.c:4919 +#, c-format +msgid "No such method '%s'" +msgstr "Không có phương thức “%sâ€" + +#: ../gio/gdbusconnection.c:4950 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "Kiểu thông Ä‘iệp, “%sâ€, không khá»›p vá»›i kiểu Ä‘ang cần “%sâ€" + +#: ../gio/gdbusconnection.c:5148 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "Äối tượng đã được xuất cho giao diện %s tại %s rồi" + +#: ../gio/gdbusconnection.c:5374 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "Không thể lấy lại thuá»™c tính %s.%s" + +#: ../gio/gdbusconnection.c:5430 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "Không thể đặt thuá»™c tính %s.%s" + +#: ../gio/gdbusconnection.c:5606 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "Phương thức “%s†trả vá» kiểu “%sâ€, nhưng Ä‘ang muốn “%sâ€" + +#: ../gio/gdbusconnection.c:6679 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "Phương thức “%s†trên giao diện “%s†vá»›i ký hiệu “%s†không tồn tại" + +#: ../gio/gdbusconnection.c:6800 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "Cây con đã được xuất cho %s" + +#: ../gio/gdbusmessage.c:1244 +msgid "type is INVALID" +msgstr "kiểu KHÔNG HỢP LỆ" + +#: ../gio/gdbusmessage.c:1255 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" +"Thông Ä‘iệp METHOD_CALL: thiếu trưá»ng PATH (đưá»ng dẫn) hoặc MEMBER (thành " +"viên) ở phần đầu" + +#: ../gio/gdbusmessage.c:1266 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "Thông Ä‘iệp METHOD_RETURN: thiếu trưá»ng REPLY_SERIAL trong header" + +#: ../gio/gdbusmessage.c:1278 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" +"Thông Ä‘iệp ERROR: thiếu trưá»ng REPLY_SERIAL hoặc ERROR_NAME trong header" + +#: ../gio/gdbusmessage.c:1291 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" +"Thông Ä‘iệp SIGNAL: thiếu trưá»ng PATH, INTERFACE hoặc MEMBER trong header" + +#: ../gio/gdbusmessage.c:1299 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Thông Ä‘iệp SIGNAL: trưá»ng PATH dùng giá trị dành riêng /org/freedesktop/DBus/" +"Local" + +#: ../gio/gdbusmessage.c:1307 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Thông Ä‘iệp SIGNAL: trưá»ng INTERFACE dùng giá trị dành riêng org.freedesktop." +"DBus.Local" + +#: ../gio/gdbusmessage.c:1355 ../gio/gdbusmessage.c:1415 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "Muốn Ä‘á»c %lu byte nhưng chỉ nhận được %lu" + +#: ../gio/gdbusmessage.c:1369 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "Chá» byte NUL sau chuá»—i “%s†nhưng lại nhận byte %d" + +#: ../gio/gdbusmessage.c:1388 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" +"Muốn chuá»—i UTF-8 hợp lệ nhưng nhận được dãy byte không hợp lệ từ vị trí %d " +"(độ dài chuá»—i là %d). Chuá»—i UTF-8 hợp lệ dài nhất là “%sâ€" + +#: ../gio/gdbusmessage.c:1587 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" +"Giá trị đã phân tích “%s†không phải là đưá»ng dẫn đối tượng D-Bus hợp lệ" + +#: ../gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "Giá trị đã phân tích “%s†không phải là ký hiệu D-Bus hợp lệ" + +#: ../gio/gdbusmessage.c:1656 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "Phát hiện mảng dài %u byte. Äá»™ dài tối Ä‘a là 2<<26 byte (64 MiB)." + +#: ../gio/gdbusmessage.c:1676 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Chạm trán mảng cá»§a kiểu “a%câ€, cần có chiá»u dài là bá»™i số cá»§a %u byte, nhưng " +"lại nhận được chỉ %u byte chiá»u dài" + +#: ../gio/gdbusmessage.c:1843 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" +"Giá trị đã phân tích “%s†cho biến thể không phải là ký hiệu D-Bus hợp lệ" + +#: ../gio/gdbusmessage.c:1867 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" +"Gặp lá»—i khi thôi tuần tá»± hóa GVariant vá»›i kiểu chuá»—i “%s†từ định dạng D-Bus" + +#: ../gio/gdbusmessage.c:2051 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" +"Giá trị endianness không hợp lệ. Chá» 0x6c (“lâ€) hoặc 0x42 (“Bâ€) nhưng nhận " +"được 0x%02x" + +#: ../gio/gdbusmessage.c:2064 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "Phiên bản chính cá»§a phương thức không hợp lệ. Cần 1 nhưng lại nhận %d" + +#: ../gio/gdbusmessage.c:2120 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "Ký phần đầu vá»›i chữ ký “%s†nhưng phần thân trống rá»—ng" + +#: ../gio/gdbusmessage.c:2134 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" +"Giá trị đã phân tích “%s†không phải là chữ ký D-Bus hợp lệ (cho phần thân)" + +#: ../gio/gdbusmessage.c:2164 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +"Không có chữ ký ở phần đầu trong thông Ä‘iệp, nhưng phần thân thông Ä‘iệp có " +"%u byte" + +#: ../gio/gdbusmessage.c:2174 +msgid "Cannot deserialize message: " +msgstr "Không thể bá» tuần tá»± hóa thông Ä‘iệp: " + +#: ../gio/gdbusmessage.c:2515 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" +"Gặp lá»—i khi tuần tá»± hóa GVariant vá»›i kiểu chuá»—i “%s†sang định dạng D-Bus" + +#: ../gio/gdbusmessage.c:2652 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" +"Thông Ä‘iệp có %d bá»™ mô tả tập tin nhưng header chỉ ra %d bá»™ mô tả tập tin" + +#: ../gio/gdbusmessage.c:2660 +msgid "Cannot serialize message: " +msgstr "Không thể tuần tá»± hóa thông Ä‘iệp: " + +#: ../gio/gdbusmessage.c:2704 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" +"Phần thân thông Ä‘iệp có chữ ký “%s†nhưng không có phần đầu lại không có" + +#: ../gio/gdbusmessage.c:2714 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "Phần thân thông Ä‘iệp có chữ ký “%s†nhưng phần đầu lại có ký “%sâ€" + +#: ../gio/gdbusmessage.c:2730 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "Thân thông Ä‘iệp trống rá»—ng như chữ ký trong phần đầu là “(%s)â€" + +#: ../gio/gdbusmessage.c:3283 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "Lá»—i trả vá» thân cá»§a kiểu “%sâ€" + +#: ../gio/gdbusmessage.c:3291 +msgid "Error return with empty body" +msgstr "Lá»—i trả vá» thân trống rá»—ng" + +#: ../gio/gdbusprivate.c:2036 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "Không thể lấy hồ sÆ¡ phần cứng: %s" + +#: ../gio/gdbusprivate.c:2081 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "Không thể nạp /var/lib/dbus/machine-id hoặc /etc/machine-id: " + +#: ../gio/gdbusproxy.c:1610 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "Gặp lá»—i khi gá»i StartServiceByName cho %s: " + +#: ../gio/gdbusproxy.c:1633 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "Trả lá»i %d không mong đợi từ hàm StartServiceByName(\"%s)" + +#: ../gio/gdbusproxy.c:2709 ../gio/gdbusproxy.c:2843 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Không thể gá»i hàm; á»§y nhiệm chỉ dành cho nhá»­ng tên đã biết không có sở hữu " +"và á»§y nhiệm được xây dá»±ng vá»›i cá» G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "Không há»— trợ vùng tên tổng quát" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "Không thể chỉ định nonce-file khi tạo máy chá»§" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Gặp lá»—i khi ghi tập tin dịp này “%sâ€: %s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "Chuá»—i “%s†không phải là má»™t GUID D-BUS hợp lệ" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "Không thể lắng nghe trên phương thức vận chuyển không há»— trợ “%sâ€" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"Lệnh:\n" +" help Hiện những thông tin này\n" +" introspect Xem xét đối tượng từ xa\n" +" monitor Theo dõi đối tượng từ xa\n" +" call Gá»i hàm trên đối tượng từ xa\n" +" emit Phát tín hiệu\n" +"\n" +"Dùng \"%s LỆNH --help\" để có trợ giúp cá»§a từng lệnh.\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:226 ../gio/gdbus-tool.c:298 +#: ../gio/gdbus-tool.c:322 ../gio/gdbus-tool.c:711 ../gio/gdbus-tool.c:1043 +#: ../gio/gdbus-tool.c:1477 +#, c-format +msgid "Error: %s\n" +msgstr "Lá»—i: %s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:239 ../gio/gdbus-tool.c:1493 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Gặp lá»—i khi phân tích ná»™i quan XML: %s\n" + +#: ../gio/gdbus-tool.c:208 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "Lá»—i: %s không phải là má»™t cái tên hợp lệ\n" + +#: ../gio/gdbus-tool.c:356 +msgid "Connect to the system bus" +msgstr "Không thể kết nối vào tuyến hệ thống" + +#: ../gio/gdbus-tool.c:357 +msgid "Connect to the session bus" +msgstr "Không thể kết nối vào tuyến phiên làm việc" + +#: ../gio/gdbus-tool.c:358 +msgid "Connect to given D-Bus address" +msgstr "Kết nối đến địa chỉ D-Bus đã cho" + +#: ../gio/gdbus-tool.c:368 +msgid "Connection Endpoint Options:" +msgstr "Tùy chá»n đầu kết nối:" + +#: ../gio/gdbus-tool.c:369 +msgid "Options specifying the connection endpoint" +msgstr "Tùy chá»n chỉ định đầu nối" + +#: ../gio/gdbus-tool.c:391 +#, c-format +msgid "No connection endpoint specified" +msgstr "Chưa chỉ định đầu nối" + +#: ../gio/gdbus-tool.c:401 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "Chỉ định nhiá»u đầu nối" + +#: ../gio/gdbus-tool.c:471 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "Chú ý: theo dữ liệu ná»™i quan, giao diện “%s†không tồn tại\n" + +#: ../gio/gdbus-tool.c:480 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" +"Chú ý: theo dữ liệu ná»™i quan, phương thức “%s†không tồn tại trên giao diện " +"“%sâ€\n" + +#: ../gio/gdbus-tool.c:542 +msgid "Optional destination for signal (unique name)" +msgstr "Äích tùy chá»n cho tín hiệu (tên duy nhất)" + +#: ../gio/gdbus-tool.c:543 +msgid "Object path to emit signal on" +msgstr "ÄÆ°á»ng dẫn để phát tín hiệu" + +#: ../gio/gdbus-tool.c:544 +msgid "Signal and interface name" +msgstr "Tên phương thức vào giao diện" + +#: ../gio/gdbus-tool.c:576 +msgid "Emit a signal." +msgstr "Phát tín hiệu." + +#: ../gio/gdbus-tool.c:610 ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1583 +#: ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error connecting: %s\n" +msgstr "Gặp lá»—i khi kết nối: %s\n" + +#: ../gio/gdbus-tool.c:622 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "Lá»—i: chưa chỉ định đưá»ng dẫn đối tượng.\n" + +#: ../gio/gdbus-tool.c:627 ../gio/gdbus-tool.c:909 ../gio/gdbus-tool.c:1648 +#: ../gio/gdbus-tool.c:1884 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "Lá»—i: “%s†không phải là đưá»ng dẫn đối tượng hợp lệ\n" + +#: ../gio/gdbus-tool.c:633 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "Lá»—i: chưa chỉ định tín hiệu.\n" + +#: ../gio/gdbus-tool.c:640 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "Lá»—i: tín hiệu phải có tên đầy đủ.\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Lá»—i: %s không phải là tên giao tiếp hợp lệ\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Lá»—i: %s không phải là tên thành viên hợp lệ\n" + +#: ../gio/gdbus-tool.c:660 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Lá»—i: %s không phải là tên bus duy nhất hợp lệ\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:687 ../gio/gdbus-tool.c:1011 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Gặp lá»—i khi phân tích tham số %d: %s\n" + +#: ../gio/gdbus-tool.c:718 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "Gặp lá»—i khi tống kết nối: %s\n" + +#: ../gio/gdbus-tool.c:745 +msgid "Destination name to invoke method on" +msgstr "Tên đích để gá»i phương thức trên đó" + +#: ../gio/gdbus-tool.c:746 +msgid "Object path to invoke method on" +msgstr "ÄÆ°á»ng dẫn đối tượng để gá»i phương thức trên đó" + +#: ../gio/gdbus-tool.c:747 +msgid "Method and interface name" +msgstr "Tên phương thức vào giao diện" + +#: ../gio/gdbus-tool.c:748 +msgid "Timeout in seconds" +msgstr "Thá»i hạn theo giây" + +#: ../gio/gdbus-tool.c:787 +msgid "Invoke a method on a remote object." +msgstr "Gá»i hàm trên đối tượng từ xa." + +#: ../gio/gdbus-tool.c:862 ../gio/gdbus-tool.c:1602 ../gio/gdbus-tool.c:1837 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "Lá»—i: Chưa chỉ định đích\n" + +#: ../gio/gdbus-tool.c:874 ../gio/gdbus-tool.c:1619 ../gio/gdbus-tool.c:1849 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "Lá»—i: %s không phải là cái tên bus hợp lệ\n" + +#: ../gio/gdbus-tool.c:889 ../gio/gdbus-tool.c:1628 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "Lá»—i: Chưa chỉ định đưá»ng dẫn đối tượng\n" + +#: ../gio/gdbus-tool.c:924 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "Lá»—i: Chưa chỉ định tên phương thức\n" + +#: ../gio/gdbus-tool.c:935 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "Lá»—i: Tên phương thức “%s†không hợp lệ\n" + +#: ../gio/gdbus-tool.c:1003 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Gặp lá»—i khi phân tích tham số %d kiểu “%sâ€: %s\n" + +#: ../gio/gdbus-tool.c:1440 +msgid "Destination name to introspect" +msgstr "Tên đích cần xem xét" + +#: ../gio/gdbus-tool.c:1441 +msgid "Object path to introspect" +msgstr "ÄÆ°á»ng dẫn đối tượng cần xem xét" + +#: ../gio/gdbus-tool.c:1442 +msgid "Print XML" +msgstr "In XML" + +#: ../gio/gdbus-tool.c:1443 +msgid "Introspect children" +msgstr "Xem xét con" + +#: ../gio/gdbus-tool.c:1444 +msgid "Only print properties" +msgstr "Chỉ in thuá»™c tính" + +#: ../gio/gdbus-tool.c:1535 +msgid "Introspect a remote object." +msgstr "Xem xét đối tượng từ xa." + +#: ../gio/gdbus-tool.c:1740 +msgid "Destination name to monitor" +msgstr "Tên đích cần theo dõi" + +#: ../gio/gdbus-tool.c:1741 +msgid "Object path to monitor" +msgstr "ÄÆ°á»ng dẫn đối tượng cần theo dõi" + +#: ../gio/gdbus-tool.c:1770 +msgid "Monitor a remote object." +msgstr "Theo dõi đối tượng từ xa." + +#: ../gio/gdesktopappinfo.c:1993 ../gio/gdesktopappinfo.c:4503 +msgid "Unnamed" +msgstr "Không có tên" + +#: ../gio/gdesktopappinfo.c:2402 +msgid "Desktop file didn't specify Exec field" +msgstr "Tập tin Desktop không ghi rõ trưá»ng Exec (thá»±c hiện lệnh)" + +#: ../gio/gdesktopappinfo.c:2687 +msgid "Unable to find terminal required for application" +msgstr "Không tìm thấy thiết bị cuối cần thiết cho ứng dụng" + +#: ../gio/gdesktopappinfo.c:3099 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "Không thể tạo thư mục cấu hình ứng dụng ngưá»i dùng %s: %s" + +#: ../gio/gdesktopappinfo.c:3103 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "Không thể tạo thư mục cấu hình MIME ngưá»i dùng %s: %s" + +#: ../gio/gdesktopappinfo.c:3343 ../gio/gdesktopappinfo.c:3367 +msgid "Application information lacks an identifier" +msgstr "Thông tin ứng dụng thiếu định danh" + +#: ../gio/gdesktopappinfo.c:3601 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "Không thể tạo tập tin desktop %s" + +#: ../gio/gdesktopappinfo.c:3735 +#, c-format +msgid "Custom definition for %s" +msgstr "Äịnh nghÄ©a riêng cho %s" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "ổ đĩa không có chức năng đẩy ra" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" +"ổ đĩa không thá»±c hiện chức năng đẩy ra (eject hoặc eject_with_operation)" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "ổ đĩa không thá»±c hiện chức năng thăm dò có phương tiện không" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "ổ đĩa không thá»±c hiện chức năng chạy (start)" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "ổ đĩa không thá»±c hiện chức năng dừng (stop)" + +#: ../gio/gdummytlsbackend.c:195 ../gio/gdummytlsbackend.c:317 +#: ../gio/gdummytlsbackend.c:509 +msgid "TLS support is not available" +msgstr "Không há»— trợ TLS" + +#: ../gio/gdummytlsbackend.c:419 +msgid "DTLS support is not available" +msgstr "Không há»— trợ DTLS" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "Không thể quản lý phiên bản %d cá»§a bảng mã GEmblem" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "Bảng mã GEmblem chứa số các hiệu bài dạng sai (%d)" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "Không thể quản lý phiên bản %d cá»§a bảng mã GEmblemedIcon" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "Bảng mã GEmblemedIcon chứa số các hiệu bài dạng sai (%d)" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "Mong đợi má»™t GEmblem cho GEmblemedIcon" + +#: ../gio/gfile.c:969 ../gio/gfile.c:1207 ../gio/gfile.c:1345 +#: ../gio/gfile.c:1583 ../gio/gfile.c:1638 ../gio/gfile.c:1696 +#: ../gio/gfile.c:1780 ../gio/gfile.c:1837 ../gio/gfile.c:1901 +#: ../gio/gfile.c:1956 ../gio/gfile.c:3604 ../gio/gfile.c:3659 +#: ../gio/gfile.c:3894 ../gio/gfile.c:3936 ../gio/gfile.c:4404 +#: ../gio/gfile.c:4815 ../gio/gfile.c:4900 ../gio/gfile.c:4990 +#: ../gio/gfile.c:5087 ../gio/gfile.c:5174 ../gio/gfile.c:5275 +#: ../gio/gfile.c:7796 ../gio/gfile.c:7886 ../gio/gfile.c:7970 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "Thao tác không được há»— trợ" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1468 ../gio/glocalfile.c:1134 ../gio/glocalfile.c:1145 +#: ../gio/glocalfile.c:1158 +msgid "Containing mount does not exist" +msgstr "Bá»™ gắn chứa không tồn tại" + +#: ../gio/gfile.c:2515 ../gio/glocalfile.c:2376 +msgid "Can't copy over directory" +msgstr "Không thể sao chép đè lên thư mục" + +#: ../gio/gfile.c:2575 +msgid "Can't copy directory over directory" +msgstr "Không thể sao chép thư mục đè lên thư mục" + +#: ../gio/gfile.c:2583 ../gio/glocalfile.c:2385 +msgid "Target file exists" +msgstr "Tập tin đích đã có" + +#: ../gio/gfile.c:2602 +msgid "Can't recursively copy directory" +msgstr "Không thể sao chép đệ quy thư mục" + +#: ../gio/gfile.c:2884 +msgid "Splice not supported" +msgstr "Chức năng nối bện không được há»— trợ" + +#: ../gio/gfile.c:2888 +#, c-format +msgid "Error splicing file: %s" +msgstr "Gặp lá»—i khi nối bện tập tin: %s" + +#: ../gio/gfile.c:3019 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "Chép (reflink/clone) giữa các Ä‘iểm gắn kết không được há»— trợ" + +#: ../gio/gfile.c:3023 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "Chép (reflink/clone) không được há»— trợ hoặc không hợp lệ" + +#: ../gio/gfile.c:3028 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "Chép (reflink/clone) không được há»— trợ hoặc không chạy" + +#: ../gio/gfile.c:3091 +msgid "Can't copy special file" +msgstr "Không thể sao chép tập tin đặc biệt" + +#: ../gio/gfile.c:3884 +msgid "Invalid symlink value given" +msgstr "ÄÆ°a ra giá trị liên kết má»m không hợp lệ" + +#: ../gio/gfile.c:4045 +msgid "Trash not supported" +msgstr "Thùng rác không được há»— trợ" + +#: ../gio/gfile.c:4157 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "Tên tập tin không thể chứa “%câ€" + +#: ../gio/gfile.c:6586 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "hàm volume (khối tin) không thá»±c hiện chức năng mount (gắn)" + +#: ../gio/gfile.c:6695 +msgid "No application is registered as handling this file" +msgstr "Không có ứng dụng đăng ký xá»­ lý tập tin này" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "Bá»™ đếm bị đóng" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "Bá»™ đếm tập tin có thao tác còn chạy" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "Bá»™ đếm tập tin đã bị đóng" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "Không thể quản lý phiên bản %d cá»§a bảng mã GFileIcon" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "Dữ liệu đầu vào có dạng sai cho GFileIcon" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "Luồng không há»— trợ hàm “query_infoâ€" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "Chức năng seek (di chuyển vị trí Ä‘á»c) không được há»— trợ trên luồng" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "Không cho phép cắt ngắn luồng nhập vào" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "Không cho phép cắt ngắn luồng" + +#: ../gio/ghttpproxy.c:136 +msgid "Bad HTTP proxy reply" +msgstr "Trả lá»i á»§y nhiệm HTTP sai" + +#: ../gio/ghttpproxy.c:152 +msgid "HTTP proxy connection not allowed" +msgstr "Không cho phép kết nối á»§y nhiệm HTTP" + +#: ../gio/ghttpproxy.c:157 +msgid "HTTP proxy authentication failed" +msgstr "Gặp lá»—i khi xác thá»±c á»§y nhiệm HTTP" + +#: ../gio/ghttpproxy.c:160 +msgid "HTTP proxy authentication required" +msgstr "Cần xác thá»±c á»§y nhiệm HTTP" + +#: ../gio/ghttpproxy.c:164 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "Kết nối á»§y nhiệm HTTP gặp lá»—i: %i" + +#: ../gio/ghttpproxy.c:260 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "Máy phục vụ á»§y nhiệm HTTP đã đóng bất ngá»." + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "Số các hiệu bài không đúng (%d)" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "Không có kiểu cho tên lá»›p %s" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "Kiểu %s không thá»±c hiện giao diện GIcon" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "Kiểu %s không được đặt lá»›p" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "Số thứ tá»± phiên bản dạng sai: %s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "Kiểu %s không thá»±c hiện “from_tokens()†trên giao diện GIcon" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "Không thể quản lý phiên bản đã cung cấp cá»§a bảng mã biểu tượng" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "Chưa chỉ định địa chỉ" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "%u là quá dài cho địa chỉ" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "Äịa chỉ đặt bit vượt độ dài tiá»n tố" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "không thể phân tích “%s†làm mặt nạ địa chỉ IP" + +#: ../gio/ginetsocketaddress.c:203 ../gio/ginetsocketaddress.c:220 +#: ../gio/gnativesocketaddress.c:106 ../gio/gunixsocketaddress.c:216 +msgid "Not enough space for socket address" +msgstr "Không đủ không gian cho địa chỉ ổ cắm mạng" + +#: ../gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "Äịa chỉ ổ cắm mạng không há»— trợ" + +#: ../gio/ginputstream.c:188 +msgid "Input stream doesn't implement read" +msgstr "Luồng nhập vào không thá»±c hiện chức năng Ä‘á»c" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1215 ../gio/giostream.c:310 +#: ../gio/goutputstream.c:1668 +msgid "Stream has outstanding operation" +msgstr "Luồng có thao tác còn chạy" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1491 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "Không cho phép phần tá»­ <%s> bên trong <%s>" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "Không cho phép phần tá»­ <%s> ở cấp cao nhất" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "Tập tin %s xuất hiện nhiá»u lần trong tài nguyên" + +#: ../gio/glib-compile-resources.c:247 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "Gặp lá»—i khi định vị “%s†trong thư mục nguồn" + +#: ../gio/glib-compile-resources.c:258 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "Gặp lá»—i khi định vị “%s†trong thư mục hiện thá»i" + +#: ../gio/glib-compile-resources.c:287 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "Không biết tùy chá»n xá»­ lý \"%s\"" + +#: ../gio/glib-compile-resources.c:305 ../gio/glib-compile-resources.c:351 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "Không tạo được tập tin tạm: %s" + +#: ../gio/glib-compile-resources.c:379 +#, c-format +msgid "Error reading file %s: %s" +msgstr "Gặp lá»—i khi Ä‘á»c tập tin %s: %s" + +#: ../gio/glib-compile-resources.c:399 +#, c-format +msgid "Error compressing file %s" +msgstr "Gặp lá»—i khi nén tập tin %s" + +#: ../gio/glib-compile-resources.c:467 ../gio/glib-compile-schemas.c:1603 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "văn bản không thể xuất hiện bên trong <%s>" + +#: ../gio/glib-compile-resources.c:592 +msgid "name of the output file" +msgstr "tên tập tin xuất" + +#: ../gio/glib-compile-resources.c:593 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "Thư mục chứa tập tin cần Ä‘á»c (mặc định là thư mục hiện thá»i)" + +#: ../gio/glib-compile-resources.c:593 ../gio/glib-compile-schemas.c:2036 +#: ../gio/glib-compile-schemas.c:2065 +msgid "DIRECTORY" +msgstr "THƯ MỤC" + +#: ../gio/glib-compile-resources.c:594 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "" +"Phát sinh kết quả theo định dạng chá»n theo phần mở rá»™ng tên tập tin đích" + +#: ../gio/glib-compile-resources.c:595 +msgid "Generate source header" +msgstr "Phát sinh header mã nguồn" + +#: ../gio/glib-compile-resources.c:596 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "Phát sinh mã nguồn để liên kết trong tập tin tài nguyên vào mã cá»§a bạn" + +#: ../gio/glib-compile-resources.c:597 +msgid "Generate dependency list" +msgstr "Phát sinh danh sách phụ thuá»™c" + +#: ../gio/glib-compile-resources.c:598 +msgid "Don't automatically create and register resource" +msgstr "Không tá»± động tạo và đăng ký tài nguyên" + +#: ../gio/glib-compile-resources.c:599 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "Không xuất hàm; khai báo là G_GNUC_INTERNAL" + +#: ../gio/glib-compile-resources.c:600 +msgid "C identifier name used for the generated source code" +msgstr "Tên định danh C cho mã nguồn phát sinh" + +#: ../gio/glib-compile-resources.c:626 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"Biên dịch đặc tả tài nguyên thành tập tin tài nguyên.\n" +"Tập tin đặc tả tài nguyên có Ä‘uôi .gresource.xml,\n" +"và tập tin tài nguyên có Ä‘uôi .gresource." + +#: ../gio/glib-compile-resources.c:642 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "Bạn nên đưa chính xác má»™t tên tập tin\n" + +#: ../gio/glib-compile-schemas.c:784 +msgid "empty names are not permitted" +msgstr "không cho phép tên rá»—ng" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "tên không hợp lệ “%sâ€: tên phải bắt đầu bằng chữ thưá»ng" + +#: ../gio/glib-compile-schemas.c:806 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "" +"tên không hợp lệ “%sâ€: ký tá»± không hợp lệ “%c'; chỉ được dùng chữ thưá»ng, số " +"hoặc dấu gạch ngang (“-â€)." + +#: ../gio/glib-compile-schemas.c:815 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "" +"tên không hợp lệ “%sâ€: không được dùng hai gạch ngang liên tiếp (“--â€)." + +#: ../gio/glib-compile-schemas.c:824 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "tên không hợp lệ “%sâ€: ký tá»± cuối không thể là gạch ngang (“-â€)." + +#: ../gio/glib-compile-schemas.c:832 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "tên không hợp lệ “%sâ€: độ dài tối Ä‘a là 1024" + +#: ../gio/glib-compile-schemas.c:901 +#, c-format +msgid " already specified" +msgstr " đã được định nghÄ©a rồi" + +#: ../gio/glib-compile-schemas.c:927 +msgid "cannot add keys to a 'list-of' schema" +msgstr "không thể thêm khóa vào lược đồ “list-ofâ€" + +#: ../gio/glib-compile-schemas.c:938 +#, c-format +msgid " already specified" +msgstr " đã được định nghÄ©a rồi" + +#: ../gio/glib-compile-schemas.c:956 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" che trong ; dùng " +"để thay đổi giá trị" + +#: ../gio/glib-compile-schemas.c:967 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" +"thuá»™c tính cá»§a chỉ có thể là duy nhất má»™t trong “typeâ€, “enum†hoặc " +"“flagsâ€" + +#: ../gio/glib-compile-schemas.c:986 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id=“%sâ€> chưa định nghÄ©a." + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "kiểu chuá»—i GVariant không hợp lệ “%sâ€" + +#: ../gio/glib-compile-schemas.c:1031 +msgid " given but schema isn't extending anything" +msgstr " được ghi nhưng lược đồ không có gì để mở rá»™ng" + +#: ../gio/glib-compile-schemas.c:1044 +#, c-format +msgid "no to override" +msgstr "không có để ghi đè" + +#: ../gio/glib-compile-schemas.c:1052 +#, c-format +msgid " already specified" +msgstr " đã được định nghÄ©a rồi" + +#: ../gio/glib-compile-schemas.c:1125 +#, c-format +msgid " already specified" +msgstr " đã được định nghÄ©a rồi" + +#: ../gio/glib-compile-schemas.c:1137 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "mở rá»™ng chưa có trong lược đồ “%sâ€" + +#: ../gio/glib-compile-schemas.c:1153 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " là danh sách cá»§a lược đồ chưa tồn tại “%sâ€" + +#: ../gio/glib-compile-schemas.c:1161 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "Không thể là danh sách cá»§a lược đồ hoặc đưá»ng dẫn" + +#: ../gio/glib-compile-schemas.c:1171 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "Không thể mở rá»™ng lược đồ vá»›i má»™t đưá»ng dẫn" + +#: ../gio/glib-compile-schemas.c:1181 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" +" là danh sách, mở rá»™ng không phải là má»™t " +"danh sách" + +#: ../gio/glib-compile-schemas.c:1191 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" +" mở rá»™ng nhưng " +"“%s†không mở rá»™ng “%sâ€" + +#: ../gio/glib-compile-schemas.c:1208 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "đưá»ng dẫn nếu có phải bắt đầu bằng dấu “/â€" + +#: ../gio/glib-compile-schemas.c:1215 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "đưá»ng dẫn danh sách phải bắt đầu bằng “:/â€" + +#: ../gio/glib-compile-schemas.c:1247 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id=“%sâ€> đã được định nghÄ©a rồi" + +#: ../gio/glib-compile-schemas.c:1397 ../gio/glib-compile-schemas.c:1413 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "Chỉ cho phép má»™t phần tá»­ <%s> bên trong <%s>" + +#: ../gio/glib-compile-schemas.c:1495 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "Không cho phép phần tá»­ <%s> ở cấp cao nhất" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1794 ../gio/glib-compile-schemas.c:1865 +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "--strict đã được chỉ định; Ä‘ang thoát.\n" + +#: ../gio/glib-compile-schemas.c:1802 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "Toàn bá»™ tập tin này bị bá» qua.\n" + +#: ../gio/glib-compile-schemas.c:1861 +#, c-format +msgid "Ignoring this file.\n" +msgstr "Bá» qua tập tin này.\n" + +#: ../gio/glib-compile-schemas.c:1901 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" +"Không có khóa “%s†trong lược đồ “%s†như được định nghÄ©a trong tập tin ghi " +"đè “%sâ€" + +#: ../gio/glib-compile-schemas.c:1907 ../gio/glib-compile-schemas.c:1965 +#: ../gio/glib-compile-schemas.c:1993 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "; bá» qua ghi đè cho khóa này.\n" + +#: ../gio/glib-compile-schemas.c:1911 ../gio/glib-compile-schemas.c:1969 +#: ../gio/glib-compile-schemas.c:1997 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "và có dùng --strict; thoát.\n" + +#: ../gio/glib-compile-schemas.c:1927 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "" +"lá»—i phân tích khóa “%s†trong lược đồ “%s†như định nghÄ©a trong tập tin ghi " +"đè “%sâ€: %s." + +#: ../gio/glib-compile-schemas.c:1937 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "Bá» qua ghi đè khóa này.\n" + +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "" +"ghi đè khóa “%s†trong lược đồ “%s†trong tập tin ghi đè “%s†ngoài phạm vi " +"lược đồ" + +#: ../gio/glib-compile-schemas.c:1983 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" +"ghi đè khóa “%s†trong lược đồ “%s†trong tập tin ghi đè “%s†không nằm " +"trong danh sách lá»±a chá»n hợp lệ" + +#: ../gio/glib-compile-schemas.c:2036 +msgid "where to store the gschemas.compiled file" +msgstr "nÆ¡i lưu tập tin gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2037 +msgid "Abort on any errors in schemas" +msgstr "Buá»™c há»§y nếu gặp bất cứ lá»—i gì trong lược đồ" + +#: ../gio/glib-compile-schemas.c:2038 +msgid "Do not write the gschema.compiled file" +msgstr "Không ghi tập tin gschemas.compiled" + +#: ../gio/glib-compile-schemas.c:2039 +msgid "Do not enforce key name restrictions" +msgstr "Không áp đặt ràng buá»™c tên khóa" + +#: ../gio/glib-compile-schemas.c:2068 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"Biên dịch tất cả tập tin lược đồ GSettings đệm lược đồ.\n" +"Tập tin lược đồ cần có phần mở rá»™ng .gschema.xml,\n" +"và tập tin nhá»› đệm tên là gschemas.compiled." + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "Bạn nên đưa chính xác má»™t tên thư mục\n" + +#: ../gio/glib-compile-schemas.c:2123 +#, c-format +msgid "No schema files found: " +msgstr "Không tìm thấy tập tin lược đồ: " + +#: ../gio/glib-compile-schemas.c:2126 +#, c-format +msgid "doing nothing.\n" +msgstr "không làm gì cả.\n" + +#: ../gio/glib-compile-schemas.c:2129 +#, c-format +msgid "removed existing output file.\n" +msgstr "đã xóa tập tin kết xuất hiện có.\n" + +#: ../gio/glocalfile.c:635 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "Tên tập tin không hợp lệ: %s" + +#: ../gio/glocalfile.c:1012 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "Gặp lá»—i khi lấy tập tin vá» hệ thống tập tin: %s" + +#: ../gio/glocalfile.c:1180 +msgid "Can't rename root directory" +msgstr "Không thể thay đổi tên cá»§a thư mục gốc" + +#: ../gio/glocalfile.c:1200 ../gio/glocalfile.c:1226 +#, c-format +msgid "Error renaming file: %s" +msgstr "Gặp lá»—i khi thay đổi tên cá»§a tập tin: %s" + +#: ../gio/glocalfile.c:1209 +msgid "Can't rename file, filename already exists" +msgstr "Không thể đổi tên tập tin, tên tập tin đã có" + +#: ../gio/glocalfile.c:1222 ../gio/glocalfile.c:2249 ../gio/glocalfile.c:2278 +#: ../gio/glocalfile.c:2438 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "Tên tập tin không hợp lệ" + +#: ../gio/glocalfile.c:1389 ../gio/glocalfile.c:1413 +msgid "Can't open directory" +msgstr "Không thể mở thư mục" + +#: ../gio/glocalfile.c:1397 +#, c-format +msgid "Error opening file: %s" +msgstr "Gặp lá»—i khi mở tập tin: %s" + +#: ../gio/glocalfile.c:1538 +#, c-format +msgid "Error removing file: %s" +msgstr "Gặp lá»—i khi gỡ bá» tập tin: %s" + +#: ../gio/glocalfile.c:1922 +#, c-format +msgid "Error trashing file: %s" +msgstr "Gặp lá»—i khi chuyển tập tin vào thùng rác: %s" + +#: ../gio/glocalfile.c:1945 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Không thể tạo thư mục thùng rác %s: %s" + +#: ../gio/glocalfile.c:1966 +msgid "Unable to find toplevel directory for trash" +msgstr "Không tìm thấy thư mục cấp đầu cho thùng rác" + +#: ../gio/glocalfile.c:2045 ../gio/glocalfile.c:2065 +msgid "Unable to find or create trash directory" +msgstr "Không tìm thấy hay không thể tạo thư mục thùng rác" + +#: ../gio/glocalfile.c:2099 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Không thể tạo tập tin thông tin thùng rác: %s" + +#: ../gio/glocalfile.c:2157 ../gio/glocalfile.c:2162 ../gio/glocalfile.c:2219 +#: ../gio/glocalfile.c:2226 +#, c-format +msgid "Unable to trash file: %s" +msgstr "Không thể chuyển tập tin vào thùng rác: %s" + +#: ../gio/glocalfile.c:2227 ../glib/gregex.c:281 +msgid "internal error" +msgstr "lá»—i ná»™i bá»™" + +#: ../gio/glocalfile.c:2253 +#, c-format +msgid "Error creating directory: %s" +msgstr "Gặp lá»—i khi tạo thư mục: %s" + +#: ../gio/glocalfile.c:2282 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Hệ tậo tin không há»— trợ liên kết má»m" + +#: ../gio/glocalfile.c:2286 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "Gặp lá»—i khi tạo liên kết má»m: %s" + +#: ../gio/glocalfile.c:2348 ../gio/glocalfile.c:2442 +#, c-format +msgid "Error moving file: %s" +msgstr "Gặp lá»—i khi di chuyển tập tin: %s" + +#: ../gio/glocalfile.c:2371 +msgid "Can't move directory over directory" +msgstr "Không thể di chuyển thư mục đè lên thư mục" + +#: ../gio/glocalfile.c:2398 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "Gặp lá»—i khi tạo tập tin sao lưu" + +#: ../gio/glocalfile.c:2417 +#, c-format +msgid "Error removing target file: %s" +msgstr "Gặp lá»—i khi gỡ bá» tập tin đích: %s" + +#: ../gio/glocalfile.c:2431 +msgid "Move between mounts not supported" +msgstr "Không há»— trợ chức năng di chuyển giữa các bá»™ gắn" + +#: ../gio/glocalfile.c:2623 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "Không thể dò tìm dung lượng đĩa tiêu dùng cá»§a %s: %s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "Giá trị thuá»™c tính phải có giá trị" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "Kiểu thuá»™c tính không hợp lệ (mong đợi chuá»—i)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "Tên thuá»™c tính đã mở rá»™ng không hợp lệ" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Gặp lá»—i khi đặt thuá»™c tính đã mở rá»™ng “%sâ€: %s" + +#: ../gio/glocalfileinfo.c:1575 +msgid " (invalid encoding)" +msgstr " (bảng mã không hợp lệ)" + +#: ../gio/glocalfileinfo.c:1766 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "Gặp lá»—i khi lấy thông tin cho tập tin “%sâ€: %s" + +#: ../gio/glocalfileinfo.c:2017 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "Gặp lá»—i khi lấy thông tin cho bá»™ mô tả tập tin: %s" + +#: ../gio/glocalfileinfo.c:2062 +msgid "Invalid attribute type (uint32 expected)" +msgstr "Kiểu thuá»™c tính không hợp lệ (mong đợi uint32)" + +#: ../gio/glocalfileinfo.c:2080 +msgid "Invalid attribute type (uint64 expected)" +msgstr "Kiểu thuá»™c tính không hợp lệ (mong đợi uint64)" + +#: ../gio/glocalfileinfo.c:2099 ../gio/glocalfileinfo.c:2118 +msgid "Invalid attribute type (byte string expected)" +msgstr "Kiểu thuá»™c tính không hợp lệ (mong đợi chuá»—i byte)" + +#: ../gio/glocalfileinfo.c:2153 +msgid "Cannot set permissions on symlinks" +msgstr "Gặp lá»—i khi đặt quyá»n hạn cho liên kết má»m" + +#: ../gio/glocalfileinfo.c:2169 +#, c-format +msgid "Error setting permissions: %s" +msgstr "Gặp lá»—i khi đặt quyá»n hạn: %s" + +#: ../gio/glocalfileinfo.c:2220 +#, c-format +msgid "Error setting owner: %s" +msgstr "Gặp lá»—i khi đặt ngưá»i sở hữu: %s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "symlink must be non-NULL" +msgstr "liên kết má»m phải có giá trị" + +#: ../gio/glocalfileinfo.c:2253 ../gio/glocalfileinfo.c:2272 +#: ../gio/glocalfileinfo.c:2283 +#, c-format +msgid "Error setting symlink: %s" +msgstr "Gặp lá»—i khi đặt liên kết má»m: %s" + +#: ../gio/glocalfileinfo.c:2262 +msgid "Error setting symlink: file is not a symlink" +msgstr "Gặp lá»—i khi đặt liên kết má»m: tập tin không phải là liên kết má»m" + +#: ../gio/glocalfileinfo.c:2388 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "Gặp lá»—i khi đặt thá»i gian sá»­a đổi hoặc truy cập: %s" + +#: ../gio/glocalfileinfo.c:2411 +msgid "SELinux context must be non-NULL" +msgstr "Ngữ cảnh SELinux phải khác NULL" + +#: ../gio/glocalfileinfo.c:2426 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "Gặp lá»—i khi đặt ngữ cảnh SELinux: %s" + +#: ../gio/glocalfileinfo.c:2433 +msgid "SELinux is not enabled on this system" +msgstr "SELinux chưa được bật trên hệ thống này" + +#: ../gio/glocalfileinfo.c:2525 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "Không há»— trợ chức năng đặt thuá»™c tính %s" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "Gặp lá»—i khi Ä‘á»c từ tập tin: %s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "Gặp lá»—i khi tìm nÆ¡i trong tập tin: %s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "Gặp lá»—i khi đóng tập tin: %s" + +#: ../gio/glocalfilemonitor.c:840 +msgid "Unable to find default local file monitor type" +msgstr "Không tìm thấy kiểu theo dõi tập tin cục bá»™ mặc định" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "Gặp lá»—i khi ghi vào tập tin: %s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "Gặp lá»—i khi gỡ bá» liên kết sao lưu cÅ© : %s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "Gặp lá»—i khi tạo bản sao lưu : %s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "Gặp lá»—i khi thay đổi tên cá»§a tập tin tạm thá»i: %s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "Gặp lá»—i khi cắt ngắn tập tin: %s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "Gặp lá»—i khi mở tập tin “%sâ€: %s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "Tập tin đích là má»™t thư mục" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "Tập tin đích không phải là má»™t tập tin bình thưá»ng" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "Tập tin đã bị sá»­a đổi bên ngoài" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "Gặp lá»—i khi xóa tập tin cÅ©: %s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "GSeekType được cung cấp không hợp lệ" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "Yêu cầu tìm không hợp lệ" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "Không thể cắt GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "Luồng ra bá»™ nhá»› không thể thay đổi kích thước" + +#: ../gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "Gặp lá»—i khi thay đổi kích thước luồng ra bá»™ nhá»›" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Việc ghi này yêu cầu má»™t vùng nhá»› lá»›n hÆ¡n sức chứa địa chỉ sẵn có hiện tại" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "Äã yêu cầu tìm nÆ¡i đằng trước đầu cá»§a luồng" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "Äã yêu cầu tìm nÆ¡i đằng sau cuối cá»§a luồng" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "hàm mount (gắn) không thá»±c hiện hàm \"unmount\" (bá» gắn)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "hàm mount (gắn) không thá»±c hiện hàm \"eject\" (đầy ra)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" +"hàm mount (gắn) không thá»±c hiện hàm \"unmount\" hoặc \"unmount_with_operation" +"\" (bá» gắn)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" +"hàm mount (gắn) không thá»±c hiện hàm \"eject\" hoặc \"eject_with_operation" +"\" (đầy ra)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "hàm mount (gắn) không thá»±c hiện hàm \"remount\" (gắn lại)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "hàm mount (gắn) không thá»±c hiện Ä‘oán ná»™i dung" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "hàm mount (gắn) không thá»±c hiện Ä‘oán ná»™i dung đồng bá»™" + +#: ../gio/gnetworkaddress.c:378 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "Tên máy “%s†có chứa “[†nhưng không có “]â€" + +#: ../gio/gnetworkmonitorbase.c:206 ../gio/gnetworkmonitorbase.c:309 +msgid "Network unreachable" +msgstr "Mạng không thể tiếp cận" + +#: ../gio/gnetworkmonitorbase.c:244 ../gio/gnetworkmonitorbase.c:274 +msgid "Host unreachable" +msgstr "Máy không thể tiếp cận" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "không thể tạo trình theo dõi mạng: %s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "Không thể tạo bá»™ theo dõi mạng: " + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "Không thể lấy trạng thái mạng: " + +#: ../gio/gnetworkmonitornm.c:326 +#, c-format +msgid "NetworkManager version too old" +msgstr "Phiên bản cá»§a Trình quản lý mạng là quá cÅ©" + +#: ../gio/goutputstream.c:212 ../gio/goutputstream.c:560 +msgid "Output stream doesn't implement write" +msgstr "Luồng xuất không thá»±c hiện hàm write (ghi)" + +#: ../gio/goutputstream.c:521 ../gio/goutputstream.c:1222 +msgid "Source stream is already closed" +msgstr "Luồng nguồn đã bị đóng" + +#: ../gio/gresolver.c:330 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "Gặp lá»—i khi phân giải “%sâ€: %s" + +#: ../gio/gresource.c:304 ../gio/gresource.c:555 ../gio/gresource.c:572 +#: ../gio/gresource.c:693 ../gio/gresource.c:762 ../gio/gresource.c:823 +#: ../gio/gresource.c:903 ../gio/gresourcefile.c:453 ../gio/gresourcefile.c:576 +#: ../gio/gresourcefile.c:713 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "Tài nguyên tại “%s†không tồn tại" + +#: ../gio/gresource.c:469 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "Tài nguyên tại “%s†gặp lá»—i giải nén" + +#: ../gio/gresourcefile.c:709 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "Tài nguyên tại “%s†không phải là thư mục" + +#: ../gio/gresourcefile.c:917 +msgid "Input stream doesn't implement seek" +msgstr "Luồng nhập vào không thá»±c hiện chức năng seek" + +#: ../gio/gresource-tool.c:494 +msgid "List sections containing resources in an elf FILE" +msgstr "Danh sách phần chứa tài nguyên cá»§a tập tin elf" + +#: ../gio/gresource-tool.c:500 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"Danh sách tài nguyên\n" +"Nếu chỉ định phần, chỉ liệt kê tài nguyên cá»§a phần đó\n" +"Nếu chỉ định đưá»ng dẫn, chỉ liệt kê tài nguyên khá»›p" + +#: ../gio/gresource-tool.c:503 ../gio/gresource-tool.c:513 +msgid "FILE [PATH]" +msgstr "TẬP-TIN [ÄÆ¯á»œNG-DẪN]" + +#: ../gio/gresource-tool.c:504 ../gio/gresource-tool.c:514 +#: ../gio/gresource-tool.c:521 +msgid "SECTION" +msgstr "PHẦN" + +#: ../gio/gresource-tool.c:509 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"Danh sách tài nguyên chi tiết\n" +"Nếu chỉ định phần, chỉ liệt kê tài nguyên cá»§a phần đó\n" +"Nếu chỉ định đưá»ng dẫn, chỉ liệt kê tài nguyên khá»›p\n" +"Chi tiết bao gồm phần, kích thước và nén" + +#: ../gio/gresource-tool.c:519 +msgid "Extract a resource file to stdout" +msgstr "Trích tập tin tài nguyên ra đầu ra" + +#: ../gio/gresource-tool.c:520 +msgid "FILE PATH" +msgstr "ÄÆ¯á»œNG DẪN" + +#: ../gio/gresource-tool.c:534 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Cách dùng:\n" +" gresource [--section PHẦN] LỆNH [THAM-Sá»â€¦]\n" +"\n" +"Lệnh:\n" +" help Hiện thông tin này\n" +" sections Liệt kê các phần tài nguyên\n" +" list Liệt kê tài nguyên\n" +" details Liêt kê tài nguyên chi tiết\n" +" extract Trích tài nguyên\n" +"\n" +"Dùng “gresource help LỆNH†để biết chi tiết.\n" +"\n" + +#: ../gio/gresource-tool.c:548 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Cách dùng:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:555 +msgid " SECTION An (optional) elf section name\n" +msgstr " PHẦN Tên phần elf (tùy chá»n)\n" + +#: ../gio/gresource-tool.c:559 ../gio/gsettings-tool.c:639 +msgid " COMMAND The (optional) command to explain\n" +msgstr " LỆNH Lệnh để giải thích (tùy chá»n)\n" + +#: ../gio/gresource-tool.c:565 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " TẬP TIN Tẹn tập tin elf (chương trình hoặc thư viện)\n" + +#: ../gio/gresource-tool.c:568 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" TẬP TIN Tập tin elf (chương trình hoặc thư viện)\n" +" hoặc tập tin tài nguyên đã biên dịch\n" + +#: ../gio/gresource-tool.c:572 +msgid "[PATH]" +msgstr "[ÄÆ¯á»œNG DẪN]" + +#: ../gio/gresource-tool.c:574 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " ÄÆ¯á»œNG DẪN (Má»™t phần) ÄÆ°á»ng dẫn tài nguyên (tùy chá»n)\n" + +#: ../gio/gresource-tool.c:575 +msgid "PATH" +msgstr "ÄÆ¯á»œNG DẪN" + +#: ../gio/gresource-tool.c:577 +msgid " PATH A resource path\n" +msgstr " ÄÆ¯á»œNG DẪN ÄÆ°á»ng dẫn tài nguyên\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#: ../gio/gsettings-tool.c:830 +#, c-format +msgid "No such schema '%s'\n" +msgstr "Không có lược đồ “%sâ€\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "Lược đồ “%s†không thể tái định vị (không cần chỉ định đưá»ng dấn)\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "Lược đồ “%s†có thể tái định vị (cần chỉ định đưá»ng dẫn)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "ÄÆ°á»ng dẫn rá»—ng.\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "ÄÆ°á»ng dẫn phải bắt đầu bằng dấu “/â€\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "ÄÆ°á»ng dẫn phải kết thúc bằng dấu “/â€\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "ÄÆ°á»ng dẫn không được chứa hai dấu gạch chéo liên tiếp (//)\n" + +#: ../gio/gsettings-tool.c:481 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "Giá trị cung cấp ngoài phạm vi hợp lệ\n" + +#: ../gio/gsettings-tool.c:488 +#, c-format +msgid "The key is not writable\n" +msgstr "Khóa không ghi được\n" + +#: ../gio/gsettings-tool.c:524 +msgid "List the installed (non-relocatable) schemas" +msgstr "Danh sách lược đồ (không thể tái định vị) đã cài đặt" + +#: ../gio/gsettings-tool.c:530 +msgid "List the installed relocatable schemas" +msgstr "Danh sách lược đồ (có thể thể tái định vị) đã cài đặt" + +#: ../gio/gsettings-tool.c:536 +msgid "List the keys in SCHEMA" +msgstr "Liệt kê khóa trong lược đồ" + +#: ../gio/gsettings-tool.c:537 ../gio/gsettings-tool.c:543 +#: ../gio/gsettings-tool.c:580 +msgid "SCHEMA[:PATH]" +msgstr "LƯỢC_Äá»’[:ÄÆ¯á»œNG DẪN]" + +#: ../gio/gsettings-tool.c:542 +msgid "List the children of SCHEMA" +msgstr "Liệt kê con cá»§a LƯỢC_Äá»’" + +#: ../gio/gsettings-tool.c:548 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"Danh sách khóa và giá trị, đệ quy\n" +"Nếu không cho LƯỢC_Äá»’, liệt kê má»i khóa\n" + +#: ../gio/gsettings-tool.c:550 +msgid "[SCHEMA[:PATH]]" +msgstr "[LƯỢC_Äá»’[:ÄÆ¯á»œNG DẪN]]" + +#: ../gio/gsettings-tool.c:555 +msgid "Get the value of KEY" +msgstr "Lấy giá trị cá»§a KHÓA" + +#: ../gio/gsettings-tool.c:556 ../gio/gsettings-tool.c:562 +#: ../gio/gsettings-tool.c:574 ../gio/gsettings-tool.c:586 +msgid "SCHEMA[:PATH] KEY" +msgstr "LƯỢCÄá»’[:ÄÆ¯á»œNG DẪN] KHÓA" + +#: ../gio/gsettings-tool.c:561 +msgid "Query the range of valid values for KEY" +msgstr "Truy vấn khoảng giá trị hợp lệ cho KHÓA" + +#: ../gio/gsettings-tool.c:567 +msgid "Set the value of KEY to VALUE" +msgstr "Äặt giá trị GIà TRỊ cho KHÓA" + +#: ../gio/gsettings-tool.c:568 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "LƯỢCÄá»’[:ÄÆ¯á»œNG DẪN] KHÓA GIÃ-TRỊ" + +#: ../gio/gsettings-tool.c:573 +msgid "Reset KEY to its default value" +msgstr "Phục hồi giá trị mặc định cho KHÓA" + +#: ../gio/gsettings-tool.c:579 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "Phục hồi má»i khóa trong LƯỢCÄá»’ vá» mặc định" + +#: ../gio/gsettings-tool.c:585 +msgid "Check if KEY is writable" +msgstr "Kiểm tra quyá»n ghi cá»§a KHÓA" + +#: ../gio/gsettings-tool.c:591 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"Theo dõi thay đổi cá»§a KHÓA.\n" +"Nếu không chỉ định KHÓA, theo dõi má»i khóa trong LƯỢCÄá»’.\n" +"Nhấn ^C để ngưng.\n" + +#: ../gio/gsettings-tool.c:594 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "LƯỢCÄá»’[:ÄÆ¯á»œNGDẪN] [KHÓA]" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"Cách dùng:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] LỆNH [Äá»I Sá»â€¦]\n" +"\n" +"Commands:\n" +" help Hiện thông tin này\n" +" list-schemas Liệt kê lược đồ đã cài đặt\n" +" list-relocatable-schemas Liệt kê lược đồ có thể tái định vị\n" +" list-keys Liệt kê khóa trong lược đồ\n" +" list-children Liệt kê khóa con trong lược đồ\n" +" list-recursively Liệt kê khóa và giá trị đệ quy\n" +" range Truy vấn má»™t vùng khóa\n" +" get Lấy giá trị khóa\n" +" set Äặt giá trị khóa\n" +" reset Äặt lại giá trị khóa\n" +" reset-recursively Äặt lại má»i giá trị khóa trong lược đồ\n" +" writable Kiểm tra khóa có ghi được không\n" +" monitor Theo dõi thay đổi\n" +"\n" +"Dùng “gsettings help LỆNH†để biết chi tiết.\n" +"\n" + +#: ../gio/gsettings-tool.c:629 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"Cách dùng:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:635 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR Thư mục cần tìm lược đồ bổ sung\n" + +#: ../gio/gsettings-tool.c:643 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" LƯỢC_Äá»’ Tên lược đồ\n" +" PATH ÄÆ°á»ng dẫn, cho lược đồ tái định vị\n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY Khóa trong lược đồ (tùy chá»n)\n" + +#: ../gio/gsettings-tool.c:652 +msgid " KEY The key within the schema\n" +msgstr " KEY Khóa trong lược đồ\n" + +#: ../gio/gsettings-tool.c:656 +msgid " VALUE The value to set\n" +msgstr " VALUE Giá trị cần đặt\n" + +#: ../gio/gsettings-tool.c:711 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "Không thể tải lược đồ từ “%sâ€: %s\n" + +#: ../gio/gsettings-tool.c:723 +#, c-format +msgid "No schemas installed\n" +msgstr "Chưa cài đặt lược đồ nào\n" + +#: ../gio/gsettings-tool.c:788 +#, c-format +msgid "Empty schema name given\n" +msgstr "Tên lược đồ rá»—ng\n" + +#: ../gio/gsettings-tool.c:843 +#, c-format +msgid "No such key '%s'\n" +msgstr "Không có khóa “%sâ€\n" + +#: ../gio/gsocket.c:364 +msgid "Invalid socket, not initialized" +msgstr "á»” cắm mạng không hợp lệ, chưa được khởi tạo" + +#: ../gio/gsocket.c:371 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "á»” cắm mạng không hợp lệ, khởi động thất bại vì: %s" + +#: ../gio/gsocket.c:379 +msgid "Socket is already closed" +msgstr "á»” cắm mạng đã được đóng" + +#: ../gio/gsocket.c:394 ../gio/gsocket.c:2751 ../gio/gsocket.c:3896 +#: ../gio/gsocket.c:3951 +msgid "Socket I/O timed out" +msgstr "Hết giá» á»” cắm mạng I/O" + +#: ../gio/gsocket.c:526 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "Ä‘ang tạo GSocket từ fd: %s" + +#: ../gio/gsocket.c:554 ../gio/gsocket.c:608 ../gio/gsocket.c:615 +#, c-format +msgid "Unable to create socket: %s" +msgstr "Không thể tạo ổ cắm mạng: %s" + +#: ../gio/gsocket.c:608 +msgid "Unknown family was specified" +msgstr "Không biết hỠđã cho" + +#: ../gio/gsocket.c:615 +msgid "Unknown protocol was specified" +msgstr "Không biết giao thức đã cho" + +#: ../gio/gsocket.c:1104 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "" +"Không thể dùng thao tác datagram vá»›i má»™t ổ cắm mạng không-phải-datagram." + +#: ../gio/gsocket.c:1121 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "" +"Không thể dùng thao tác datagram vá»›i má»™t ổ cắm mạng vá»›i đặt thá»i hạn chá» tối " +"Ä‘a." + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "could not get local address: %s" +msgstr "không thể lấy địa chỉ cục bá»™: %s" + +#: ../gio/gsocket.c:1968 +#, c-format +msgid "could not get remote address: %s" +msgstr "không thể lấy địa chỉ ở xa: %s" + +#: ../gio/gsocket.c:2034 +#, c-format +msgid "could not listen: %s" +msgstr "không thể lắng nghe: %s" + +#: ../gio/gsocket.c:2133 +#, c-format +msgid "Error binding to address: %s" +msgstr "Lá»—i liên kết địa chỉ: %s" + +#: ../gio/gsocket.c:2248 ../gio/gsocket.c:2285 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "Gặp lá»—i khi tham gia nhóm multicast: %s" + +#: ../gio/gsocket.c:2249 ../gio/gsocket.c:2286 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "Gặp lá»—i khi rá»i nhóm multicast: %s" + +#: ../gio/gsocket.c:2250 +msgid "No support for source-specific multicast" +msgstr "Không há»— trợ multicast nguồn chỉ định" + +#: ../gio/gsocket.c:2470 +#, c-format +msgid "Error accepting connection: %s" +msgstr "Gặp lá»—i khi chấp nhận kết nối: %s" + +#: ../gio/gsocket.c:2593 +msgid "Connection in progress" +msgstr "Kết nối Ä‘ang hình thành" + +#: ../gio/gsocket.c:2644 +msgid "Unable to get pending error: " +msgstr "Không thể lấy lá»—i Ä‘ang chá»: " + +#: ../gio/gsocket.c:2816 +#, c-format +msgid "Error receiving data: %s" +msgstr "Gặp lá»—i khi nhận dữ liệu: %s" + +#: ../gio/gsocket.c:3013 +#, c-format +msgid "Error sending data: %s" +msgstr "Gặp lá»—i khi gá»­i dữ liệu: %s" + +#: ../gio/gsocket.c:3200 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Không thể tắt ổ cắm mạng: %s" + +#: ../gio/gsocket.c:3281 +#, c-format +msgid "Error closing socket: %s" +msgstr "Gặp lá»—i khi đóng ổ cắm mạng: %s" + +#: ../gio/gsocket.c:3889 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "Äang chỠổ cắm mạng: %s" + +#: ../gio/gsocket.c:4361 ../gio/gsocket.c:4441 ../gio/gsocket.c:4619 +#, c-format +msgid "Error sending message: %s" +msgstr "Gặp lá»—i khi gá»­i thông Ä‘iệp: %s" + +#: ../gio/gsocket.c:4385 +msgid "GSocketControlMessage not supported on Windows" +msgstr "GSocketControlMessage không được há»— trợ trên Windows" + +#: ../gio/gsocket.c:4840 ../gio/gsocket.c:4913 ../gio/gsocket.c:5140 +#, c-format +msgid "Error receiving message: %s" +msgstr "Gặp lá»—i khi nhận thông Ä‘iệp: %s" + +#: ../gio/gsocket.c:5412 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "Không thể Ä‘á»c giấy á»§y nhiệm ổ cắm mạng: %s" + +#: ../gio/gsocket.c:5421 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials không được há»— trợ trên hệ Ä‘iá»u hành này" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "Không thể kết nối đến máy á»§y nhiệm %s: " + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "Không thể kết nối đến %s: " + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "không thể kết nối: " + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1599 +msgid "Unknown error on connect" +msgstr "Gặp lá»—i chưa biết lạ khi kết nối" + +#: ../gio/gsocketclient.c:1081 ../gio/gsocketclient.c:1535 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "Không há»— trợ á»§y nhiệm thông qua kết nối không phải TCP." + +#: ../gio/gsocketclient.c:1110 ../gio/gsocketclient.c:1561 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Không há»— trợ giao thức á»§y nhiệm “%sâ€." + +#: ../gio/gsocketlistener.c:218 +msgid "Listener is already closed" +msgstr "Bên lắng nghe đã đóng" + +#: ../gio/gsocketlistener.c:264 +msgid "Added socket is closed" +msgstr "á»” cắm mạng được thêm đã đóng" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 không há»— trợ địa chỉ IPv6 “%sâ€" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "Tên ngưá»i dùng hoặc mật khẩu quá dài cho giao thức SOCKSv4" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "Tên máy “%s†quá dài đối cho giao thức SOCKSv4" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "Máy chá»§ không phải là máy á»§y nhiệm SOCKSv4." + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "Kết nối qua máy chá»§ SOCKSv4 bị từ chối" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "Máy chá»§ không phải máy SOCKSv5." + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "Máy á»§y nhiệm SOCKSv5 cần xác thá»±c." + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" +"Máy á»§y nhiệm SOCKSv5 cần dùng phương thức xác thá»±c không được há»— trợ bởi " +"GLib." + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "Tên ngưá»i dùng hoặc mật khẩu quá dài cho giao thức SOCKSv5." + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "Xác thá»±c SOCKSv5 thất bại vì sai tên ngưá»i dùng hoặc mật khẩu." + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "Tên máy “%s†quá dài cho giao thức SOCKSv5" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "Máy chá»§ á»§y nhiệm SOCKSv5 dùng kiểu địa chỉ lạ." + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "Lá»—i ná»™i bá»™ máy chá»§ SOCKSv5." + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "Không cho phép kết nối SOCKSv5 dá»±a theo tập quy tắc." + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "Không thể tiếp cận thông qua máy chá»§ SOCKSv5." + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "Không thể tiếp cận mạng thông qua máy chá»§ SOCKSv5." + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "Kết nối bị từ chối thông qua máy chá»§ SOCKSv5." + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "Ủy nhiệm SOCKSv5 không há»— trợ lệnh “connect†(kết nối)." + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "Ủy nhiệm SOCKSv5 không há»— trợ kiểu địa chỉ cung cấp." + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "Lá»—i á»§y nhiệm SOCKSv5 lạ." + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "Không thể quản lý phiên bản %d cá»§a bảng mã GThemedIcon" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "Không tìm thấy địa chỉ hợp lệ nào" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Gặp lá»—i khi phân giải ngược “%sâ€: %s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "Không có loại bản ghi DNS được yêu cầu cho “%sâ€" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "Tạm thá»i không thể phân giải “%sâ€" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "Gặp lá»—i khi phân giải “%sâ€" + +#: ../gio/gtlscertificate.c:250 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Không thể giải mã khóa riêng mã hóa dạng PEM" + +#: ../gio/gtlscertificate.c:255 +msgid "No PEM-encoded private key found" +msgstr "Không tìm thấy khóa riêng mã hóa dạng PEM" + +#: ../gio/gtlscertificate.c:265 +msgid "Could not parse PEM-encoded private key" +msgstr "Không thể phân tích khóa riêng mã hóa dạng PEM" + +#: ../gio/gtlscertificate.c:290 +msgid "No PEM-encoded certificate found" +msgstr "Không tìm thấy chứng nhận mã hóa dạng PEM" + +#: ../gio/gtlscertificate.c:299 +msgid "Could not parse PEM-encoded certificate" +msgstr "Không thể phân tích chứng nhận mã hóa dạng PEM" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "Äây là cÆ¡ há»™i cuối để nhập đúng mật khẩu trước khi truy cập bị khóa." + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" +"Mật khẩu nhập sai đã vài lần, truy cập cá»§a bạn sẽ bị khóa để ngăn lá»—i có thể " +"xảy ra." + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "Mật khẩu nhập sai." + +#: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:561 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "Cần má»™t thông Ä‘iệp Ä‘iá»u khiển, nhưng lại nhận được %d" + +#: ../gio/gunixconnection.c:182 ../gio/gunixconnection.c:573 +msgid "Unexpected type of ancillary data" +msgstr "Gặp dữ liệu bổ sung kiểu bất thưá»ng" + +#: ../gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "Cần má»™t fd, nhưng lại nhận được %d\n" + +#: ../gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "Nhận fd không hợp lệ" + +#: ../gio/gunixconnection.c:355 +msgid "Error sending credentials: " +msgstr "Gặp lá»—i khi gá»­i giấy á»§y nhiệm: " + +#: ../gio/gunixconnection.c:503 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "Gặp lá»—i khi kiểm tra nếu SO_PASSCRED được bật cho ổ cắm mạng: %s" + +#: ../gio/gunixconnection.c:518 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Gặp lá»—i khi bật SO_PASSCRED: %s" + +#: ../gio/gunixconnection.c:547 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Cần Ä‘á»c má»™t byte duy nhất để nhận giấy á»§y nhiệm nhưng không Ä‘á»c được byte nào" + +#: ../gio/gunixconnection.c:587 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "Chá» thông Ä‘iệp Ä‘iá»u khiển, nhận được %d" + +#: ../gio/gunixconnection.c:611 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "Gặp lá»—i khi khi tắt SO_PASSCRED: %s" + +#: ../gio/gunixinputstream.c:369 ../gio/gunixinputstream.c:390 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "Gặp lá»—i khi Ä‘á»c từ bá»™ mô tả tập tin: %s" + +#: ../gio/gunixinputstream.c:423 ../gio/gunixoutputstream.c:409 +#: ../gio/gwin32inputstream.c:217 ../gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "Gặp lá»—i khi đóng bá»™ mô tả tập tin: %s" + +#: ../gio/gunixmounts.c:2099 ../gio/gunixmounts.c:2152 +msgid "Filesystem root" +msgstr "Gốc hệ thống tập tin" + +#: ../gio/gunixoutputstream.c:355 ../gio/gunixoutputstream.c:376 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "Gặp lá»—i khi ghi vào bá»™ mô tả tập tin: %s" + +#: ../gio/gunixsocketaddress.c:239 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "Äịa chỉ ổ cắm mạng UNIX trừu tượng không được há»— trợ trên hệ thống này" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "hàm volume (khối tin) không thá»±c hiện hàm eject (đầy ra)" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" +"hàm volume (khối tin) không thá»±c hiện hàm \"eject\" hoặc " +"\"eject_with_operation\" (đầy ra)" + +#: ../gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "Gặp lá»—i khi Ä‘á»c từ handle: %s" + +#: ../gio/gwin32inputstream.c:232 ../gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "Gặp lá»—i khi đóng handle: %s" + +#: ../gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "Gặp lá»—i khi ghi vào handle: %s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "Không đủ bá»™ nhá»›" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "Lá»—i ná»™i bá»™ : %s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "Cần thêm đầu vào" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "Sai nén dữ liệu" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "Äịa chỉ cần lắng nghe" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "Bá» qua, mục đích tương thích vá»›i GTestDbus" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "Äịa chỉ in" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "In địa chỉ trong chế độ hệ vá»" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "Chạy dịch vụ dbus" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "Tham số sai\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "Thuá»™c tính bất thưá»ng “%s†cho phần tá»­ “%sâ€" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "Không tìm thấy thuá»™c tính “%s†cá»§a phần tá»­ “%sâ€" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "Thẻ bất thưá»ng “%sâ€, mong đợi thẻ “%sâ€" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "Thẻ bất thưá»ng “%s†bên trong “%sâ€" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "Không tìm thấy tập tin liên kết lưu hợp lệ trong các thư mục dữ liệu" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "Má»™t liên kết lưu URI “%s†đã có" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "Không tìm thấy liên kết lưu URI “%sâ€" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "Chưa chỉ định kiểu MIME trong liên kết lưu URI “%sâ€" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "Chưa chỉ định cá» riêng trong liên kết lưu URI “%sâ€" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "Chưa đặt nhóm trong liên kết lưu URI “%sâ€" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "Không có ứng dụng tên “%s†đã đăng ký má»™t liên kết lưu “%sâ€" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Gặp lá»—i khi mở rá»™ng dòng thá»±c hiện “%s†bằng URI “%sâ€" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:849 ../glib/gutf8.c:1061 +#: ../glib/gutf8.c:1198 ../glib/gutf8.c:1302 +msgid "Partial character sequence at end of input" +msgstr "Character sequence riêng phần ở cuối đầu vào" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Không thể chuyển đổi fallback “%s†thành codeset “%sâ€" + +#: ../glib/gconvert.c:1567 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI “%s†không phải URI tuyệt đối sá»­ dụng lược đồ tập tin" + +#: ../glib/gconvert.c:1577 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "URI tập tin cục bá»™ “%s†có thể không bao gồm “#â€" + +#: ../glib/gconvert.c:1594 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI “%s†không hợp lệ" + +#: ../glib/gconvert.c:1606 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Tên chá»§ cá»§a URI “%s†không hợp lệ" + +#: ../glib/gconvert.c:1622 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI “%s†chứa không hợp lệ các ký tá»± thoát" + +#: ../glib/gconvert.c:1717 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Tên đưá»ng dẫn “%s†không phải má»™t đưá»ng dẫn tuyệt đối" + +#: ../glib/gconvert.c:1727 +msgid "Invalid hostname" +msgstr "Tên chá»§ không hợp lệ" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%A, %d %B năm %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M %p" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "Tháng giêng" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "Tháng hai" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "Tháng ba" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "Tháng tư" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "Tháng năm" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "Tháng sáu" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "Tháng bảy" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "Tháng tám" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "Tháng chín" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "Tháng mưá»i" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "Tháng mưá»i má»™t" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "Tháng mưá»i hai" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Th1" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Th2" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Th3" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Th4" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Th5" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Th6" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Th7" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "Th8" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "Th9" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "Th10" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "Th11" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "Th12" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "Thứ hai" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "Thứ ba" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "Thứ tư" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "Thứ năm" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "Thứ sáu" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "Thứ bảy" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "Chá»§ Nhật" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "T2" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "T3" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "T4" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "T5" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "T6" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "T7" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "CN" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Gặp lá»—i khi khi mở thư mục “%sâ€: %s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "Không thể cấp phát %lu byte để Ä‘á»c tập tin \"%s\"" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Gặp lá»—i khi khi Ä‘á»c tập tin “%sâ€: %s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "Tập tin \"%s\" quá lá»›n" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Không Ä‘á»c được từ tập tin “%sâ€: %s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Gặp lá»—i khi khi mở tập tin “%sâ€: %s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "Không lấy được các thuá»™c tính cá»§a tập tin “%sâ€: fstat() không được: %s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Không mở được tập tin “%sâ€: fdopen() không được: %s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "" +"Không đổi tên tập tin “%s†thành “%s†được: “g_rename()†không được: %s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Không tạo được tập tin “%sâ€: %s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "Việc ghi tập tin “%s†gặp lá»—i: write() gặp lá»—i: %s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Gặp lá»—i khi ghi tập tin “%sâ€: lá»—i fsync(): %s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "Không thể gỡ bá» tập tin tồn tại “%sâ€: “g_unlink()†thất bại: %s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Mẫu “%s†không hợp lệ, không được chứa “%sâ€" + +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Biểu mẫu “%s†không chứa XXXXXX" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Gặp lá»—i khi Ä‘á»c liên kết má»m “%sâ€: %s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "Không há»— trợ liên kết má»m" + +#: ../glib/giochannel.c:1388 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Không thể mở bá»™ chuyển đổi từ “%s†sang “%sâ€: %s" + +#: ../glib/giochannel.c:1733 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "Không thể thá»±c hiện Ä‘á»c thô trong g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1780 ../glib/giochannel.c:2038 +#: ../glib/giochannel.c:2125 +msgid "Leftover unconverted data in read buffer" +msgstr "Äể lại dữ liệu chưa được chuyển đổi trong buffer Ä‘á»c" + +#: ../glib/giochannel.c:1861 ../glib/giochannel.c:1938 +msgid "Channel terminates in a partial character" +msgstr "Kênh tận hết trong ký tá»± riêng phần" + +#: ../glib/giochannel.c:1924 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "Không thể thá»±c hiện Ä‘á»c thô trong g_io_channel_read_to_end" + +#: ../glib/gkeyfile.c:737 +msgid "Valid key file could not be found in search dirs" +msgstr "Không tìm thấy tập tin khóa hợp lệ nằm trong thư mục tìm kiếm" + +#: ../glib/gkeyfile.c:773 +msgid "Not a regular file" +msgstr "Không phải là má»™t tập tin thông thưá»ng" + +#: ../glib/gkeyfile.c:1174 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Tập tin khóa chứa dòng “%s†mà không phải là cặp giá trị khóa, nhóm, hoặc " +"chú thích." + +#: ../glib/gkeyfile.c:1231 +#, c-format +msgid "Invalid group name: %s" +msgstr "Tên nhóm không hợp lệ: %s" + +#: ../glib/gkeyfile.c:1253 +msgid "Key file does not start with a group" +msgstr "Tập tin khóa không bắt đầu vá»›i nhóm." + +#: ../glib/gkeyfile.c:1279 +#, c-format +msgid "Invalid key name: %s" +msgstr "Tên khóa không hợp lệ: %s" + +#: ../glib/gkeyfile.c:1306 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Tập tin khóa chứa bảng mã không được há»— trợ “%sâ€." + +#: ../glib/gkeyfile.c:1549 ../glib/gkeyfile.c:1722 ../glib/gkeyfile.c:3100 +#: ../glib/gkeyfile.c:3163 ../glib/gkeyfile.c:3293 ../glib/gkeyfile.c:3423 +#: ../glib/gkeyfile.c:3567 ../glib/gkeyfile.c:3796 ../glib/gkeyfile.c:3863 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Tập tin khóa không có nhóm “%sâ€." + +#: ../glib/gkeyfile.c:1677 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Tập tin khóa không chứa khóa “%s†trong nhóm “%sâ€." + +#: ../glib/gkeyfile.c:1839 ../glib/gkeyfile.c:1955 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "Tập tin khóa chứa khóa “%s†có giá trị “%s†không phải là UTF-8." + +#: ../glib/gkeyfile.c:1859 ../glib/gkeyfile.c:1975 ../glib/gkeyfile.c:2344 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "Không thể phân tích giá trị “%s†chứa trong tập tin khóa." + +#: ../glib/gkeyfile.c:2561 ../glib/gkeyfile.c:2929 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "" +"Tập tin khóa chứa khóa “%s†trong nhóm “%s†có giá trị không thể diá»…n giải." + +#: ../glib/gkeyfile.c:2639 ../glib/gkeyfile.c:2716 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "Khóa “%s†trong nhóm “%s†có giá trị “%s†trong khi cần %s" + +#: ../glib/gkeyfile.c:4103 +msgid "Key file contains escape character at end of line" +msgstr "Tập tin khóa chứa ký tá»± thoạt tại kết thức dòng." + +#: ../glib/gkeyfile.c:4125 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "URI “%s†chứa không hợp lệ các ký tá»± thoát" + +#: ../glib/gkeyfile.c:4267 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Không thể giải dịch giá trị “%s†dạng con số." + +#: ../glib/gkeyfile.c:4281 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "Giá trị số nguyên “%s†ở ngoài phạm vi" + +#: ../glib/gkeyfile.c:4314 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Không thể giải dịch giá trị “%s†dạng con số thá»±c dấu chấm động." + +#: ../glib/gkeyfile.c:4351 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Không thể giải dịch giá trị “%s†dạng lô-gíc (đúng/sai)." + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "Không lấy được các thuá»™c tính cá»§a tập tin “%s%s%s%sâ€: fstat() lá»—i: %s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "Không ánh xạ được tập tin “%s%s%s%sâ€: mmap() lá»—i: %s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Không mở được tập tin “%sâ€: fdopen() không được: %s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "Lá»—i trên dòng %d ký tá»± %d: " + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Văn bản được mã hóa UTF-8 không hợp lệ “%sâ€" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "“%s†không phải là tên hợp lệ" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "“%s†không phải là tên hợp lệ: “%câ€" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "Lá»—i trên dòng %d: %s" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Không phân tách được “%-.*sâ€, nó nên là má»™t con số bên trong má»™t tham chiếu " +"ký tá»± (v.d. “êâ€) — có lẽ con số quá lá»›n." + +#: ../glib/gmarkup.c:688 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Tham chiếu ký tá»± đã không kết thúc bằng dấu chấm phẩy; dưá»ng như bạn đã dùng " +"má»™t ký tá»± (và) mà không phải để bắt đầu má»™t thá»± thể - thoát dấu (và) như là " +"&" + +#: ../glib/gmarkup.c:714 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Tham chiếu ký tá»± “%-.*s†không mã hóa má»™t ký tá»± cho phép." + +#: ../glib/gmarkup.c:752 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Thá»±c thể trống “&;†được thấy; những mục nhập hợp lệ là: & " < " +"> '" + +#: ../glib/gmarkup.c:760 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Thá»±c thể lạ “%-.*sâ€" + +#: ../glib/gmarkup.c:765 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Thá»±c thể đã không kết thúc bằng dấu chấm phẩy; dưá»ng như bạn đã dùng ký tá»± " +"(và) mà không phải để bắt đầu má»™t thá»± thể - thoát khá»i dấu (và) như là &" + +#: ../glib/gmarkup.c:1171 +msgid "Document must begin with an element (e.g. )" +msgstr "Tài liệu phải bắt đầu bằng má»™t phần tá»­ (vd: )" + +#: ../glib/gmarkup.c:1211 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"“%s†không phải má»™t ký tá»± hợp lệ Ä‘i theo ký tá»± “<†; nó có thể không bắt đầu " +"tên phần tá»­" + +#: ../glib/gmarkup.c:1253 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Ký tá»± lẻ “%sâ€, cần má»™t dấu ngoặc nhá»n đóng “>†để kết thúc thẻ rá»—ng “%sâ€" + +#: ../glib/gmarkup.c:1334 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "Ký tá»± lẻ “%sâ€, cần má»™t “=†sau tên thuá»™c tính “%s†cá»§a phần tá»­ “%sâ€" + +#: ../glib/gmarkup.c:1375 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Ký tá»± lẻ “%sâ€, cần má»™t ký tá»± “>†hay “/†để kết thúc thẻ khởi đầu cá»§a phần " +"tá»­ “%sâ€, hay tùy ý má»™t thuá»™c tính; có lẽ bạn đã dùng má»™t ký tá»± bát hợp lệ " +"trong má»™t tên thuá»™c tính" + +#: ../glib/gmarkup.c:1419 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Ký tá»± lẻ “%s†, mong muốn má»™t dấu ngoặc kép sau dấu bằng khi nhận giá trị " +"cho thuá»™c tính “%s†cá»§a phần tá»­ “%sâ€" + +#: ../glib/gmarkup.c:1552 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"“%s†không phải má»™t ký tá»± hợp lệ Ä‘i theo tên phần tá»­ đóng “%s'; ký tá»± được " +"phép là “>â€" + +#: ../glib/gmarkup.c:1599 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Phần tá»­ “%s†đã được đóng, không có phần tá»­ mở hiện thá»i" + +#: ../glib/gmarkup.c:1608 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "Phần tá»­ “%s†đã được đóng, nhưng phần tá»­ mở hiện thá»i là “%sâ€" + +#: ../glib/gmarkup.c:1761 +msgid "Document was empty or contained only whitespace" +msgstr "Tài liệu trống hay chỉ chứa không gian trống" + +#: ../glib/gmarkup.c:1775 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Tài liệu đã kết thúc không mong muốn ngay sau má»™t dấu ngoặc nhá»n mở “<â€" + +#: ../glib/gmarkup.c:1783 ../glib/gmarkup.c:1828 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Tài liệu đã kết thúc không mong muốn vá»›i các phần tá»­ vẫn còn mở - “%s†là " +"phần tá»­ đã mở cuối cùng" + +#: ../glib/gmarkup.c:1791 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Tài liệu kết thúc không mong muốn, được cho là thấy dấu ngoặc nhá»n kết thúc " +"tag <%s/>" + +#: ../glib/gmarkup.c:1797 +msgid "Document ended unexpectedly inside an element name" +msgstr "Tài liệu được kết thúc không mong muốn bên trong tên phần tá»­" + +#: ../glib/gmarkup.c:1803 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Tài liệu được kết thúc không mong muốn bên trong tên thuá»™c tính" + +#: ../glib/gmarkup.c:1808 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Tài liệu được kết thúc không mong muốn bên trong tag cá»§a phần tá»­ mở." + +#: ../glib/gmarkup.c:1814 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Tài liệu kết thúc không mong muốn sau dấu bằng Ä‘i theo má»™t tên thuá»™c tính; " +"không có giá trị thuá»™c tính" + +#: ../glib/gmarkup.c:1821 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" +"Tài liệu được kết thúc không mong muốn trong khi nằm trong má»™t giá trị thuá»™c " +"tính" + +#: ../glib/gmarkup.c:1837 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"Tài liệu được kết thúc không mong muốn bên trong tag đóng cho phần tá»­ “%sâ€" + +#: ../glib/gmarkup.c:1843 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Tài liệu được kết thúc không mong muốn bên trong má»™t ghi chú hay hướng dẫn " +"tiến trình" + +#: ../glib/goption.c:857 +msgid "Usage:" +msgstr "Cách dùng:" + +#: ../glib/goption.c:861 +msgid "[OPTION...]" +msgstr "[TÙY_CHỌN…]" + +#: ../glib/goption.c:977 +msgid "Help Options:" +msgstr "Tùy chá»n trợ giúp:" + +#: ../glib/goption.c:978 +msgid "Show help options" +msgstr "Hiển thị các tùy chá»n trợ giúp" + +#: ../glib/goption.c:984 +msgid "Show all help options" +msgstr "Hiển thị má»i tùy chá»n trợ giúp" + +#: ../glib/goption.c:1047 +msgid "Application Options:" +msgstr "Tùy chá»n ứng dụng:" + +#: ../glib/goption.c:1049 +msgid "Options:" +msgstr "Tùy chá»n:" + +#: ../glib/goption.c:1113 ../glib/goption.c:1183 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Không phân tách giá trị số nguyên “%s†cho %s." + +#: ../glib/goption.c:1123 ../glib/goption.c:1191 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Giá trị số nguyên “%s†cho %s ở ngoài phạm vi." + +#: ../glib/goption.c:1148 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Không thể phân tích cú pháp giá trị số chính đôi “%s†cho %s" + +#: ../glib/goption.c:1156 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Giá trị số chính đôi “%s†cho %s ở ngoài phạm vi" + +#: ../glib/goption.c:1442 ../glib/goption.c:1521 +#, c-format +msgid "Error parsing option %s" +msgstr "Gặp lá»—i khi phân tích tùy chá»n %s" + +#: ../glib/goption.c:1552 ../glib/goption.c:1665 +#, c-format +msgid "Missing argument for %s" +msgstr "Thiếu đối số cho %s" + +#: ../glib/goption.c:2126 +#, c-format +msgid "Unknown option %s" +msgstr "Không biết tùy chá»n %s." + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "đối tượng bị há»ng" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "lá»—i ná»™i bá»™ hay đối tượng bị há»ng" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "hết bá»™ nhá»›" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "không thể rút lùi nữa" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "mẫu chứa mục không được há»— trợ khi khá»›p bá»™ phận" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "khi khá»›p bá»™ phận, không há»— trợ rút lui làm Ä‘iá»u kiện" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "đã đến mức giá»›i hạn đệ quy" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "kết hợp cá» dòng má»›i má»™t cách không hợp lệ" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "độ lệch sai" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "utf8 ngắn" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "vòng lặp đệ quy" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "lá»—i lạ" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ ở kết thúc cá»§a mẫu" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c ở kết thúc cá»§a mẫu" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "có ký tá»± lạ phía sau \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "các con số không theo thứ tá»± đúng trong chuá»—i hạn định số lượng {}" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "con số quá lá»›n trong chuá»—i hạn định số lượng {}" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "thiếu ] chấm dứt cho lá»›p ký tá»±" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "gặp dãy thoát không hợp lệ trong lá»›p ký tá»±" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "phạm vi không theo thứ tá»± đúng trong lá»›p ký tá»±" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "không có gì cần lặp lại" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "lặp lại bất thưá»ng" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "không nhận dạng ký tá»± nằm sau (? hoặc (?-" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "Lá»›p POSIX có tên chỉ được há»— trợ bên trong lá»›p" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "thiếu dấu chấm dứt )" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "tham chiếu đến mẫu phụ không tồn tại" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "thiếu ) nằm sau chú thích" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "biểu thức chính quy quá lá»›n" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "không lấy được bá»™ nhá»›" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr "có ) mà không có ( mở đầu" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "tràn mã" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "không nhận dạng ký tá»± nằm sau (?<" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "khẳng định lookbehind (thấy ở sau) không có độ dài cố định" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "có con số hay tên dạng sai nằm sau (?(" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "nhóm Ä‘iá»u kiện chứa nhiá»u hÆ¡n hai nhánh" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "mong đợi khẳng định nằm sau (?(" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R hay (?[+-]chữ số phải có ) theo sau" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "không rõ tên lá»›p POSIX" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "Không há»— trợ phần tá»­ đối chiếu POSIX" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "dãy \\x{…} chứa giá trị ký tá»± quá lá»›n" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "Ä‘iá»u kiện không hợp lệ (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "\\C không được phép trong khẳng định lookbehind (thấy ở sau)" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "không há»— trợ thoát \\L, \\l, \\N{tên}, \\U và \\u" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "lá»i gá»i đệ quy có thể bị lặp vô hạn" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "không nhận dạng ký tá»± nằm sau (?P" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "thiếu dấu chấm dứt trong tên mẫu phụ" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "hai mẫu phụ có tên cÅ©ng có cùng má»™t tên" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "dãy \\P hay \\p dạng sai" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "có tên thuá»™c tính không rõ nằm sau \\P hay \\p" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "tên mẫu phụ quá dài (tối Ä‘a 32 ký tá»±)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "quá nhiá»u mẫu phụ có tên (tối Ä‘a 10 000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "giá trị bát phân lá»›n hÆ¡n \\377" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "tràn vùng làm việc biên dịch" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "không tìm thấy mẫu phụ đã tham chiếu mà đã kiểm tra trước" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "nhóm DEFINE (định nghÄ©a) chứa nhiá»u hÆ¡n má»™t nhánh" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "các tùy chá»n NEWLINE (dòng má»›i) không thống nhất vá»›i nhau" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g không Ä‘i trước má»™t tên có dấu ngoặc móc, ngoặc vuông, tên hoặc số trích " +"dẫn hoặc má»™t con số không phải số thuần túy" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "tham chiếu đánh số phải khác không" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "không chấp nhận đối số cho (*ACCEPT), (*FAIL) hoặc (*COMMIT)" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "không nhận ra (*VERB)" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "số quá lá»›n" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "thiếu tên mẫu phụ sau (?&" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "cần má»™t chữ số sau (?+" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] là kí tá»± không hợp lệ trong chế độ tương thích JavaScript" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "không cho phép tên khác nhau cho mẫu con trong cùng số" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) phải có đối số" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c phải theo sau là má»™t kí tá»± ASCII" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "" +"\\k không Ä‘i trước má»™t tên có dấu ngoặc móc, ngoặc vuông, tên trích dẫn" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N không được há»— trợ trong lá»›p" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "quá nhiá»u tham chiếu tá»›i" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "tên quá dài trong (*MARK), (*PRUNE), (*SKIP) hoặc (*THEN)" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "dãy \\u… chứa giá trị ký tá»± quá lá»›n" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1973 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "Gặp lá»—i trong khi khá»›p biểu thức chính quy %s: %s" + +#: ../glib/gregex.c:1317 +msgid "PCRE library is compiled without UTF8 support" +msgstr "Thư viện PCRE đã biên dịch không có khả năng há»— trợ UTF-8" + +#: ../glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "Thư viện PCRE đã biên dịch không có khả năng há»— trợ thuá»™c tính UTF-8" + +#: ../glib/gregex.c:1329 +msgid "PCRE library is compiled with incompatible options" +msgstr "Thư viện PCRE đã biên dịch vá»›i tùy chá»n không tương thích" + +#: ../glib/gregex.c:1358 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "Gặp lá»—i trong khi tối hưu hóa biểu thức chính quy %s: %s" + +#: ../glib/gregex.c:1438 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Gặp lá»—i trong khi biên dịch biểu thức chính quy %s ở ký tá»± %d: %s" + +#: ../glib/gregex.c:2409 +msgid "hexadecimal digit or '}' expected" +msgstr "cần chữ số thập lục hay dấu ngoặc móc đóng “}â€" + +#: ../glib/gregex.c:2425 +msgid "hexadecimal digit expected" +msgstr "cần chữ số thập lục" + +#: ../glib/gregex.c:2465 +msgid "missing '<' in symbolic reference" +msgstr "thiếu dấu ngoặc nhá»n mở “<†trong tham chiếu ký hiệu" + +#: ../glib/gregex.c:2474 +msgid "unfinished symbolic reference" +msgstr "tham chiếu ký hiệu chưa hoàn thành" + +#: ../glib/gregex.c:2481 +msgid "zero-length symbolic reference" +msgstr "tham chiếu ký hiệu có độ dài số không" + +#: ../glib/gregex.c:2492 +msgid "digit expected" +msgstr "đợi chữ số" + +#: ../glib/gregex.c:2510 +msgid "illegal symbolic reference" +msgstr "tham chiếu ký hiệu không cho phép" + +#: ../glib/gregex.c:2572 +msgid "stray final '\\'" +msgstr "dấu gạch ngược kết thúc rải rác “\\â€" + +#: ../glib/gregex.c:2576 +msgid "unknown escape sequence" +msgstr "dãy thoát lạ" + +#: ../glib/gregex.c:2586 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "Gặp lá»—i trong khi phân tách văn bản thay thế “%s†ở ký tá»± %lu: %s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Văn bản trích dẫn không bắt đầu bằng má»™t dấu trích dẫn" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Dấu ngoặc kép không ăn khá»›p trong dòng lệnh hay má»™t shell-quoted text khác" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Văn bản được kết thúc ngay sau ký tá»± “\\â€. (văn bản đã là “%sâ€)" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"Text đã kết thúc trước khi làm khá»›p dấu ngoặc kép cho %c. (text là “%sâ€)" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "Văn bản trống (hay chỉ gồm các ký tá»± trắng)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Không Ä‘á»c được dữ liệu từ tiến trình con (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "Lá»—i không mong muốn trong select() Ä‘á»c dữ liệu từ tiến trình con (%s)" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Lá»—i không mong muốn trong waitpid() (%s)" + +#: ../glib/gspawn.c:844 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "Tiến trình con thoát vá»›i mã %ld" + +#: ../glib/gspawn.c:852 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "Tiến trình con bị giết bằng tín hiệu %ld" + +#: ../glib/gspawn.c:859 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "Tiến trình con bị dừng bằng tín hiệu %ld" + +#: ../glib/gspawn.c:866 +#, c-format +msgid "Child process exited abnormally" +msgstr "Tiến trình con thoát bất thưá»ng" + +#: ../glib/gspawn.c:1271 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Không Ä‘á»c được từ đưá»ng ống dẫn lệnh con (%s)" + +#: ../glib/gspawn.c:1341 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Không rẽ nhánh được (%s)" + +#: ../glib/gspawn.c:1490 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Không thay đổi được thư mục “%s†(%s)" + +#: ../glib/gspawn.c:1500 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Không thá»± thi được tiến trình con \"%s\" (%s)" + +#: ../glib/gspawn.c:1510 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "Không gá»­i được lần nữa đầu ra hay đầu vào cá»§a tiến trình con (%s)" + +#: ../glib/gspawn.c:1519 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Không rẽ nhánh được tiến trình con (%s)" + +#: ../glib/gspawn.c:1527 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Gặp lá»—i chưa biết khi thá»±c thi tiến trình con \"%s\"" + +#: ../glib/gspawn.c:1551 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "Không Ä‘á»c được đủ dữ liệu từ pid pipe con(%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "Không Ä‘á»c được dữ liệu từ tiến trình con" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "Không tạo được pipe để liên lạc vá»›i tiến trình con (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Không thá»±c thi được tiến trình con (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "Tên chương trình không hợp lệ: %s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "Gặp chuá»—i không hợp lệ trong véc-tÆ¡ đối số tại %d: %s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "Gặp chuá»—i không hợp lệ trong môi trưá»ng: %s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "Thư mục làm việc không hợp lệ: %s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Gặp lá»—i khi thá»±c thi chương trình bổ trợ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Gặp lá»—i không mong muốn trong g_io_channel_win32_poll() Ä‘á»c dữ liệu từ tiến " +"trình con" + +#: ../glib/gutf8.c:795 +msgid "Failed to allocate memory" +msgstr "Gặp lá»—i khi cấp phát bá»™ nhá»›" + +#: ../glib/gutf8.c:928 +msgid "Character out of range for UTF-8" +msgstr "Ký tá»± nằm ngoài vùng UTF-8" + +#: ../glib/gutf8.c:1029 ../glib/gutf8.c:1038 ../glib/gutf8.c:1168 +#: ../glib/gutf8.c:1177 ../glib/gutf8.c:1316 ../glib/gutf8.c:1413 +msgid "Invalid sequence in conversion input" +msgstr "Sequence bất hợp lệ trong đầu vào chuyển đổi" + +#: ../glib/gutf8.c:1327 ../glib/gutf8.c:1424 +msgid "Character out of range for UTF-16" +msgstr "Ký tá»± nằm ngoài vùng UTF-16" + +#: ../glib/gutils.c:2133 ../glib/gutils.c:2160 ../glib/gutils.c:2266 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u byte" + +#: ../glib/gutils.c:2139 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2141 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2144 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2147 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2150 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2153 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2166 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2169 ../glib/gutils.c:2284 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2172 ../glib/gutils.c:2289 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2174 ../glib/gutils.c:2294 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2177 ../glib/gutils.c:2299 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2180 ../glib/gutils.c:2304 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2217 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s byte" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2279 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "Tháng giêng" + +msgctxt "full month name with day" +msgid "February" +msgstr "Tháng hai" + +msgctxt "full month name with day" +msgid "March" +msgstr "Tháng ba" + +msgctxt "full month name with day" +msgid "April" +msgstr "Tháng tư" + +msgctxt "full month name with day" +msgid "May" +msgstr "Tháng năm" + +msgctxt "full month name with day" +msgid "June" +msgstr "Tháng sáu" + +msgctxt "full month name with day" +msgid "July" +msgstr "Tháng bảy" + +msgctxt "full month name with day" +msgid "August" +msgstr "Tháng tám" + +msgctxt "full month name with day" +msgid "September" +msgstr "Tháng chín" + +msgctxt "full month name with day" +msgid "October" +msgstr "Tháng mưá»i" + +msgctxt "full month name with day" +msgid "November" +msgstr "Tháng mưá»i má»™t" + +msgctxt "full month name with day" +msgid "December" +msgstr "Tháng mưá»i hai" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "Th1" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "Th2" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "Th3" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "Th4" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "Th5" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "Th6" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "Th7" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "Th8" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "Th9" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "Th10" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "Th11" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "Th12" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "Không tìm thấy kiểu theo dõi thư mục cục bá»™ mặc định" + +#~ msgid "Can't find application" +#~ msgstr "Không tìm thấy ứng dụng" + +#~ msgid "Error launching application: %s" +#~ msgstr "Gặp lá»—i khi khởi chạy ứng dụng: %s" + +#~ msgid "association changes not supported on win32" +#~ msgstr "các thay đổi liên quan không được há»— trợ trên win32" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "chức năng tạo sá»± liên quan không được há»— trợ trên win32" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "Tập tin khóa không có khóa “%sâ€." + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "Lá»—i xá»­ lý tập tin nhập vá»›i xmllint:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "Lá»—i xá»­ lý tập tin nhập vá»›i to-pixdata:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "Không thể lấy lá»—i Ä‘ang chá»: %s" + +#~ msgid "URIs not supported" +#~ msgstr "Không há»— trợ địa chỉ URI" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "Không mở được tập tin “%sâ€: fdopen() không được: %s" + +#~ msgid "Failed to write file '%s': fflush() failed: %s" +#~ msgstr "Lá»—i ghi tập tin “%sâ€: lá»—i fflush(): %s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "Không mở được tập tin “%sâ€: fdopen() không được: %s" + +#~ msgid "Incomplete data received for '%s'" +#~ msgstr "Nhận dữ liệu không hoàn chỉnh cho “%sâ€" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Chiá»u dài tùy chá»n bất thưá»ng khi kiểm tra SO_PASSCRED có được bật cho " +#~ "socket. Chá» %d byte, nhận %d" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "Chương trình kết thúc bất thưá»ng khi chạy lệnh “%s: %s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "Lệnh “%s†thoát vá»›i mã khác không %d: %s" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "vùng làm việc không thể chứa chuá»—i con rá»—ng nữa" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "" +#~ "ở đây thì không cho phép ký tá»± thoát thay đổi chữ hoa/thưá»ng (\\l, \\L, " +#~ "\\u, \\U)" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "không cho phép lặp lại má»™t nhóm DEFINE (định nghÄ©a)" + +#~ msgid "No service record for '%s'" +#~ msgstr "Không có bản ghi dịch vụ (service record) cho “%sâ€" + +#~ msgid "File is empty" +#~ msgstr "Tập tin rá»—ng." + +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "Tập tin khóa chứa khóa “%s†có giá trị không có khả năng giải dịch." + +#~ msgid "This option will be removed soon." +#~ msgstr "Tùy chá»n này sẽ sá»›m bị bá»." + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "Gặp lá»—i khi lấy trạng thái vá» tập tin “%sâ€: %s" + +#~ msgid "Error connecting: " +#~ msgstr "Lá»—i kết nối: " + +#~ msgid "Error connecting: %s" +#~ msgstr "Lá»—i kết nối: %s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "Bản SOCKSv4 giá»›i hạn tên ngưá»i dùng trong %i ký tá»±" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "Bản SOCKSv4 giá»›i hạn tên máy trong %i ký tá»±" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "Gặp lá»—i khi Ä‘á»c từ UNIX: %s" + +#~ msgid "Error closing unix: %s" +#~ msgstr "Gặp lá»—i khi đóng UNIX: %s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "Gặp lá»—i khi ghi vào UNIX: %s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "am" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "pm" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "Kiểu giá trị trả vá» không đúng, nhận “%s†nhưng muốn “%sâ€" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "Thá»­ đặt thuá»™c tính %s cá»§a kiểu %s nhưng theo giao diện muốn dùng thì kiểu " +#~ "là %s" + +#~ msgid "The nonce-file '%s' was %" +#~ msgstr "nonce-file “%s†là %" + +#~ msgid "Encountered array of length %" +#~ msgstr "Bắt gặp mảng dài %" + +#~ msgid "Error writing first 16 bytes of message to socket: " +#~ msgstr "Lá»—i ghi 16 byte đầu tiên cá»§a thông Ä‘iệp vào socket: " + +#~ msgid "Do not give error for empty directory" +#~ msgstr "Không thông báo lá»—i vá»›i thư mục rá»—ng" + +#~ msgid "" +#~ "Commands:\n" +#~ " help Show this information\n" +#~ " get Get the value of a key\n" +#~ " set Set the value of a key\n" +#~ " monitor Monitor a key for changes\n" +#~ " writable Check if a key is writable\n" +#~ "\n" +#~ "Use '%s COMMAND --help' to get help for individual commands.\n" +#~ msgstr "" +#~ "Lệnh:\n" +#~ " help Hiện những thông tin này\n" +#~ " get Lấy giá trị cá»§a khóa\n" +#~ " set Äặt giá trị cho khóa\n" +#~ " monitor Theo dõi thay đổi cá»§a khóa\n" +#~ " writable Kiểm tra khóa ghi được không\n" +#~ "\n" +#~ "Dùng “%s LỆNH --help†để biết thêm chi tiết.\n" + +#~ msgid "Specify the path for the schema" +#~ msgstr "Chỉ định đưá»ng dẫn cho lược đồ" + +#~ msgid "" +#~ "Arguments:\n" +#~ " SCHEMA The id of the schema\n" +#~ " KEY The name of the key\n" +#~ " VALUE The value to set key to, as a serialized GVariant\n" +#~ msgstr "" +#~ "Äối số:\n" +#~ " SCHEMA id cá»§a schema\n" +#~ " KEY Tên khóa\n" +#~ " VALUE Giá trị cần đặt, theo kiểu GVariant tuần tá»± hóa\n" + +#~ msgid "" +#~ "Monitor KEY for changes and print the changed values.\n" +#~ "Monitoring will continue until the process is terminated." +#~ msgstr "" +#~ "Theo dõi các thay đổi trên KHÓA và in ra.\n" +#~ "Theo dõi sẽ tiếp tục đến khi tiến trình kết thúc." diff --git a/po/wa.po b/po/wa.po new file mode 100644 index 0000000..80798a3 --- /dev/null +++ b/po/wa.po @@ -0,0 +1,3770 @@ +# Translation into the walloon language. +# +# Si vos voloz donner on côp di spale pol ratournaedje di Gnome (ou des +# ôtes libes programes) sicrijhoz-mu a l' adresse emile +# ; nos avans co brÃ¥mint di l' ovraedje a fé. +# +# Copyright (C) 2001 Free Software Foundation, Inc. +# Pablo Saratxaga , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2004-05-03 14:40+0200\n" +"Last-Translator: Pablo Saratxaga \n" +"Language-Team: Walloon \n" +"Language: wa\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" + +#: ../glib/gbookmarkfile.c:780 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Dji n' a savou lére li loyén simbolike «%s»: %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "Li cviersaedje di l' ecôdaede «%s» viè «%s» n' est nén sopoirté" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Dji n' a savou drovi l' cvierseu di «%s» viè «%s»" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Secwince d' octets nén valide e l' intrêye do cviersaedje" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "" + +#: ../glib/gconvert.c:1886 +#, fuzzy, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "Li tchmin «%s» n' est nén on tchmin absolou" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Li tchmin «%s» n' est nén on tchmin absolou" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "No d' lodjoe nén valide" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "Li %A %d di %B %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %p" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "djanvî" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "fevrî" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "mÃ¥ss" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "avri" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "may" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "djun" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "djulete" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "dja" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "fev" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "mÃ¥s" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "avr" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "may" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "djn" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "djl" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "londi" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "mÃ¥rdi" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "mierkidi" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "djudi" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "vénrdi" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "semdi" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "dimegne" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "lon" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "mÃ¥r" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "mie" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "dju" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "vén" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "sem" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "dim" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Ã…k n' a nén stî tot drovant l' ridant «%s»: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Dji n' a savou alouwer %lu octets po lére li fitchî «%s»" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Dji n' a nén savou lére li fitchî «%s»: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" +"Dji n' a nén savou aveur les atributs do fitchî «%s»: fstat() a fwait " +"berwete: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gfileutils.c:862 +#, fuzzy, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Dji n' a savou askepyî l' fitchî «%s»: %s" + +#: ../glib/gfileutils.c:918 +#, fuzzy, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gfileutils.c:943 +#, fuzzy, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gfileutils.c:1030 +#, fuzzy, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "Li patron «%s» n' est nén valide, i n' doet nén aveur on «%s»" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "Li patron «%s» èn finixh nén avou XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Dji n' a savou lére li loyén simbolike «%s»: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../glib/giochannel.c:1408 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Dji n' a savou drovi l' cvierseu di «%s» viè «%s»: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" + +#: ../glib/gmappedfile.c:150 +#, fuzzy, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gmappedfile.c:229 +#, fuzzy, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "Aroke el roye %d caractere %d: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Tecse ecôdé en UTF-8 nén valide" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Aroke el roye %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Vude intité «&;» di trovêye; les intités valides sont: & " < " +"> '" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Li no d' intité «%s» n' est nén cnoxhou" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"L' intité èn finixh nén avou on pont-coma; probÃ¥blumint k' vos avoz eployî " +"on caractere ampersande sins vleur sicrire ene intité, dins ç' cas el fÃ¥t " +"scrire insi: « ↦ »" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Li documint doet cmincî avou èn elemint (eg: )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" + +#: ../glib/gmarkup.c:1186 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Li documint esteut vude ou avou seulmint des blancs" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +msgid "missing terminating ] for character class" +msgstr "" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "Secwince d' octets nén valide e l' intrêye do cviersaedje" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +msgid "unrecognized character after (?" +msgstr "" + +#: ../glib/gregex.c:299 +msgid "unrecognized character after (?<" +msgstr "" + +#: ../glib/gregex.c:303 +msgid "unrecognized character after (?P" +msgstr "" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Aroke el roye %d caractere %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +msgid "unfinished symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Li tecse esteut vude (ou avou seulmint des blancs)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Dji n' a savou lére do process efant" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Dji n' a savou lére del buze efant (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Dji n' a savou candjî viè l' ridant «%s» (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Dji n' a savou enonder l' process efant (%s)" + +#: ../glib/gspawn-win32.c:444 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "No d' lodjoe nén valide" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, fuzzy, c-format +msgid "Invalid string in environment: %s" +msgstr "Secwince nén valide e l' intrêye do cviersaedje" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, fuzzy, c-format +msgid "Invalid working directory: %s" +msgstr "Ã…k n' a nén stî tot drovant l' ridant «%s»: %s" + +#: ../glib/gspawn-win32.c:783 +#, fuzzy, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Dji n' a savou enonder l' aidant programe" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Dji n' a savou fé on fork() (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Dji n' a savou enonder l' process efant «%s» (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Dji n' a savou fé on fork do process efant (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Aroke nén cnoxhowe tot-z enondant l' processus efant «%s»" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Caractere foû fortchete po l' ecôdaedje UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Secwince nén valide e l' intrêye do cviersaedje" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Caractere foû fortchete po l' ecôdaedje UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "No d' lodjoe nén valide" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "No d' lodjoe nén valide" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Secwince d' octets nén valide e l' intrêye do cviersaedje" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Ã…k n' a nén stî tot drovant l' ridant «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Ã…k n' a nén stî tot drovant l' ridant «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Aroke el roye %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Li caractere «%s» n' est nén valide dins on no d' intité" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Li caractere «%s» n' est nén valide dins on no d' intité" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Li caractere «%s» n' est nén valide dins on no d' intité" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Ã…k n' a nén stî tot drovant l' ridant «%s»: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "No d' lodjoe nén valide" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "No d' lodjoe nén valide" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Dji n' a savou askepyî l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Dji n' a savou askepyî l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "Dji n' a savou askepyî l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Ã…k n' a nén stî tot drovant l' ridant «%s»: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Dji n' a savou lére li loyén simbolike «%s»: %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +msgid "Invalid extended attribute name" +msgstr "" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Ã…k n' a nén stî tot drovant l' ridant «%s»: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "Aroke el roye %d: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "No d' lodjoe nén valide" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Dji n' a savou askepyî l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "Dji n' a savou alouwer %lu octets po lére li fitchî «%s»" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Dji n' a savou askepyî l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Dji n' a savou askepyî l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "Aroke el roye %d: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "Loyéns simbolikes nén sopoirtés" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "No d' lodjoe nén valide" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Secwince nén valide e l' intrêye do cviersaedje" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Li caractere «%s» n' est nén valide Ã¥ cmince do no d' ene intité; le " +#~ "caractere & cmince ene intité; si ç' caractere ampersande doet esse hÃ¥yné " +#~ "té ké, adon el fÃ¥t scrire come « & »" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Tecse ecôdé en UTF-8 nén valide" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Tecse ecôdé en UTF-8 nén valide" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Ã…k n' a nén stî tot léjhant l' fitchî «%s»: %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Ã…k n' a nén stî tot cviersant: %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "Dji n' a savou drovi li fitchî «%s»: fdopen() a fwait berwete: %s" diff --git a/po/xh.po b/po/xh.po new file mode 100644 index 0000000..29f1959 --- /dev/null +++ b/po/xh.po @@ -0,0 +1,3859 @@ +# Xhosa translation of glib +# Copyright (C) 2005 Canonical Ltd. +# This file is distributed under the same license as the glib package. +# Translation by Canonical Ltd with thanks to +# Translation World CC in South Africa, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2005-02-08 12:31+0200\n" +"Last-Translator: Canonical Ltd \n" +"Language-Team: Xhosa \n" +"Language: xh\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, fuzzy, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" +"Uphawu olutenxileyo '%s', lulindele '=' emva kwegama lophawu '%s' " +"lwesiqalelo '%s'" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +#, fuzzy +msgid "No valid bookmark file found in data dirs" +msgstr "" +"Iqhosha elisebenzayo lefayili alifumanekanga kwidata yoovimba beefayili" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "Akuphumelelanga ukufunda ikhonkco elingumfuziselo '%s': %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "" +"Uguqulo ukusuka kwingqokelela yeempawu '%s' ukuya kwi '%s' ayixhaswanga" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "Akukwazekanga ukuvula isiguquli ukusuka ku '%s' ukuya ku '%s'" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "Ulandelelwano olungasebenziyo lwe-byte kungeniso-lwazi yenguqulo" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "Inxalenye yophawu lolandelelwano ekupheleni kongeniso-lwazi" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "Akukwazeki ukuguqula i-fallback '%s' kwiseti yekhowudi '%s'" + +#: ../glib/gconvert.c:1886 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "I-URI '%s' asiyiyo i-URI ngokupheleleyo esebenzisa indlela ye \"file\"" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "I-URI yefayili yendawo '%s' kunokwenzeka ingaquki i-'#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "Ayisebenzi i-'%s' yeURI" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "Igama lomququzeleli weURI '%s' alisebenzi" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "I-URI '%s' iqulethe iimpawu ezisindileyo ezingasebenziyo" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "Igama lendlela yothungelwano '%s' akuyiyo kuphela indlela" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "Igama lomququzeleli elingasebenziyo" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%a %-e %b %Y %T %Z" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%Y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%T" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "eyoMqungu" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "eyoMdumba" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "eyoKwindla" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "uTshazimpuzi" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "uCanzibe" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "eyeSilimela" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "eyeKhala" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "Mqu" + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "Mdu" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "Kwi" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "Tsh" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "Can" + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "Sil" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "Kha" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "uMvulo" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "lwesiBini" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "lwesiThathu" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ulweSine" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "lwesiHlanu" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "uMgqibelo" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "iCawa" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "Mvu" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "Bin" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "Tha" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "Sin" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "Hla" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "Mgq" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "Caw" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "Impazamo yokuvula uvimba weefayili '%s': %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "Akwazekanga ukwaba %lu ii-byte ukufunda ifayili \"%s\"" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "Akuphumelelekanga ukufunda ifayili '%s': %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "" +"Akuphumelelekanga ukufumana iimpawu zefayili '%s': fstat() " +"akuphumelelekanga: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gfileutils.c:862 +#, fuzzy, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "Akuphumelelekanga ukudala ifayili '%s': %s" + +#: ../glib/gfileutils.c:918 +#, fuzzy, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gfileutils.c:943 +#, fuzzy, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gfileutils.c:1030 +#, fuzzy, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "I-Template '%s' ayisebenzi, kufuneka ingaqulathi i '%s'" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "I-Template '%s' ayipheli ngo XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "Akuphumelelanga ukufunda ikhonkco elingumfuziselo '%s': %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../glib/giochannel.c:1408 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "Akukwazekanga ukuvula isiguquli ukusuka ku '%s' ukuya ku '%s': %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "" +"Akukwazeki ukwenza ukufunda okungalungiswanga kwi " +"g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "Intsalela yedata engaguqulwanga kwisigcini sethutyana sokufunda" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "Isiqhagamshelanisi siphelela inxalenye yophawu" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "" +"Akukwazeki ukwenza ukufunda okungalungiswanga kwi g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, fuzzy, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gmappedfile.c:229 +#, fuzzy, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "Impazamo emgceni %d uphawu %d: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "Umbhalo onxulumanisayo ongasebenziyo we- UTF-8" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "Impazamo emgceni %d: %s" + +#: ../glib/gmarkup.c:638 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"Akuphumelelanga ukwahlula ngezijungqe '%-.*s', obekufanele ukuba ngumvo " +"ngaphakathi kophawu lokuthumela (ê umzekelo) - mhlawumbi umvo mkhulu " +"kakhulu" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"Uphawu lokuthumela aluphelelanga ngechaphaza-msila; mhlawumbi usebenzise " +"uphawu lwe- ampersand ungenanjongo yokuqala into ezimeleyo - phepha i- " +"ampersand njenge &" + +#: ../glib/gmarkup.c:676 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "Uphawu lokuthumela '%-.*s' alulunxulumanisi uphawu olunemvume" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"Into ezimeleyo eze '&;' ebonwayo; izinto ezizimeleyo ezisebenzayo: & " +"" < > '" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "Igama lento ezimeleyo '%s' alaziwa" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"Into ezimeleyo ayiphelelanga ngechaphaza-msila; mhlawumbi usebenzise uphawu " +"lwe- ampersand ungazimiselanga ukuqala into ezimeleyo - phepha i- ampersand " +"njenge &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "Uxwebhu kufuneka luqale ngesiqalelo (umzkl. )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' asilophawu elisebenzayo elilandela u '<' uphawu; linokungaqali igama " +"lesiqalelo" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"Uphawu olutenxileyo '%s', lulindele '>' uphawu lokuphelisa ilebhile " +"yokuqalisa isiqalelo '%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"Uphawu olutenxileyo '%s', lulindele '=' emva kwegama lophawu '%s' " +"lwesiqalelo '%s'" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Uphawu olutenxileyo '%s', lulindele '>' okanye '/' uphawu lokuphelisa " +"ilebhile yokuqala isiqalelo '%s', okanye ngokhetho lophawu; mhlawumbi " +"usebenzise uphawu olungasebenziyo kwigama lophawu" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"Uphawu olutenxileyo '%s', lulindele uphawu locaphulo oluvulekileyo emva " +"kweempawu zokulingana xa kunikwa ixabiso lophawu '%s' lwesiqalelo '%s'" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' asilophawu olusebenzayo ukulandela igama lesiqalelo elikufuphi '%s'; " +"uphawu oluvunyelweyo lolu '>'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "Isiqalelo '%s' besivaliwe, akukho siqalelo sivuliweyo njengangoku" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "" +"Isiqalelo '%s' besivaliwe, kodwa isiqalelo esivuliweyo njengangoku sesi '%s'" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "Uxwebhu beluze okanye luqulathe isikhewu esimhlophe kuphela" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "" +"Uxwebhu luphele ngesiquphe kanye emva kwesibiyeli sedolo elivulekileyo '<'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"Uxwebhu luphele ngesiquphe xeshikweni iziqalelo bezisavulile - '%s' " +"isiqalelo sokugqibela besivuliwe" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Uxwebhu luphele ngesiquphe, kulindelwe ukubona isibiyeli sedolo elivaliweyo " +"esiphelisa ilebhile <%s/>" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "Uxwebhu luphele ngesiquphe ngaphakathi kwegama lesiqalelo" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "Uxwebhu luphele ngesiquphe ngaphakathi kwegama lophawu" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "Uxwebhu luphele ngesiquphe ngaphakathi kwelebhile evula isiqalelo." + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Uxwebhu luphele ngesiquphe emva kokuba uphawu lokulingana lulandele igama " +"lophawu; kungekho xabiso lophawu" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "Uxwebhu luphele ngesiquphe xeshikweni lungaphakathi kwexabiso lophawu" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"Uxwebhu luphele ngesiquphe ngaphakathi kwelebhile evaliweyo yesiqalelo '%s'" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"Uxwebhu luphele ngesiquphe ngaphaikathi komyalelo wezimvo okanye inkqubo" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "Isiqhagamshelanisi siphelela inxalenye yophawu" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "Ulandelelwano olungasebenziyo lwe-byte kungeniso-lwazi yenguqulo" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "Uphawu lokuthumela olungagqitywanga" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "Uphawu lokuthumela olungagqitywanga" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "Uphawu lokuthumela olungagqitywanga" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +#, fuzzy +msgid "POSIX collating elements are not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "Impazamo emgceni %d uphawu %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "Into ezimeleyo yokuthumela engagqitywanga" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "Umbhalo ocatshuliweyo awuqali ngophawu locaphulo" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "" +"Uphawu locaphulo olungangqinelaniyo kumgca womyalelo okanye omnye umbhalo " +"ocatshuliweyo" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "Umbhalo uphele nje emva kophawu '\\'. (Umbhalo ubu '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"Umbhalo uphele phambi kokuba ucaphulo olungqinelanayo lufunyanwe malunga %c. " +"(Umbhalo ubu '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "Umbhalo ubuze (okanye uqulethe isithuba esimhlophe kuphela)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "Akuphumelelekanga ukufunda idata kwinkqubo yomntwana" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "" +"Akuphumelelekanga ukudala uthungelwano lokunxibelelana nenkqubo yomntwana " +"(%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "Akuphumelelekanga ukufunda kuthungelwano lomntwana (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "Akuphumelelekanga ukuguqukela kuvimba weefayili '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "Akuphumelelekanga ukuphumeza inkqubo yomntwana (%s)" + +#: ../glib/gspawn-win32.c:444 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "Igama lomququzeleli elingasebenziyo" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, fuzzy, c-format +msgid "Invalid string in environment: %s" +msgstr "Ulandelelwano olungasebenziyo kwinguqulo yongeniso-lwazi" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, fuzzy, c-format +msgid "Invalid working directory: %s" +msgstr "Impazamo yokuvula uvimba weefayili '%s': %s" + +#: ../glib/gspawn-win32.c:783 +#, fuzzy, c-format +msgid "Failed to execute helper program (%s)" +msgstr "Akuphumelelekanga ukuphumeza inkqubo yomncedi" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Impazamo engalindelekanga kwi g_io_channel_win32_poll() yokufunda idata " +"kwinkqubo yomntwana" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "Akuphumelelekanga ukufunda idata kwinkqubo yomntwana (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "" +"Impazamo engalindelekanga select() lokufunda idata kwinkqubo yomntwana (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "Impazamo engalindelekanga kwi-waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "Akuphumelelekanga ukudala inkqubo entsha (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "Akuphumelelekanga ukuphumeza inkqubo yomntwana \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "" +"Akuphumelelekanga ukuyalela kwakhona ungeniso nophumezo lolwazi kwinkqubo " +"yomntwana (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "Akuphumelelekanga ukudala inkqubo entsha yomntwana (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "Impazamo engaziwayo yokuphumeza inkqubo yomntwana \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "" +"Akuphumelelekanga ukufunda ngokwaneleyo idata evela kuthungelwano nomntwana " +"(%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "Uphawu lungaphandle kwesigaba se-UTF-8" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "Ulandelelwano olungasebenziyo kwinguqulo yongeniso-lwazi" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "Uphawu lungaphandle kwesigaba se-UTF-16" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "Ukusetyenziswa:" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "[OPTION...]" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "Uncedo lokunokukhethwa:" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "Bonisa amancedo anokukhethwa" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "Bonisa onke amancedo anokukhethwa" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "Iindlela zokusebenza ezinokukhethwa:" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, fuzzy, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "Akukwazeki ukwahlula ngezijungqe ixabiso lanani elimbaxa '%s' for --%s" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "Ixabiso lenani elimbaxa '%s' le %s lingaphaya kwesigaba" + +#: ../glib/goption.c:1032 +#, fuzzy, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "Akukwazeki ukwahlula ngezijungqe ixabiso lanani elimbaxa '%s' for --%s" + +#: ../glib/goption.c:1040 +#, fuzzy, c-format +msgid "Double value '%s' for %s out of range" +msgstr "Ixabiso lenani elimbaxa '%s' le %s lingaphaya kwesigaba" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "Ukhetho olungaziwayo %s" + +#: ../glib/gkeyfile.c:366 +#, fuzzy +msgid "Valid key file could not be found in search dirs" +msgstr "" +"Iqhosha elisebenzayo lefayili alifumanekanga kwidata yoovimba beefayili" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "Asiyofayili esebenza rhoqo" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "Ifayili ize" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" +"Ifayili engundoqo iqulethe umgca '%s' ongesiso isibini sexabiso okanye " +"isindululo" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "Igama lomququzeleli elingasebenziyo" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "Ifayili engundoqo ayiqali ngeqela" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "Igama lomququzeleli elingasebenziyo" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "Ifayili engundoqo iqulethe unxulumano olungaxhaswanga '%s'" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "Ifayili engundoqo ayinalo iqela '%s'" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "Ifayili engundoqo ayinalo iqhosha '%s'" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" +"Ifayili engundoqo iqulethe iqhosa '%s' elinexabiso '%s' elingeyiyo UTF-8" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" +"Ifayili engundoqo iqulethe iqhosha '%s' elinexabiso elingekhe lichazwe." + +#: ../glib/gkeyfile.c:1566 +#, fuzzy, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" +"Ifayili engundoqo iqulethe iqhosha '%s' elinexabiso elingekhe lichazwe." + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" +"Ifayili engundoqo iqulethe iqhosha '%s' kwiqela '%s' elinexabiso elingekhe " +"lichazwe." + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "Ifayili engundoqo ayinalo iqhosha '%s' eqeleni '%s'" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "Ifayili engundoqo iqulethe uphawu lokuphepha ekupheleni komgca" + +#: ../glib/gkeyfile.c:3730 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "" +"Ifayili engundoqo iqulethe ulandelelwano olungasebenziyo lokuphepha '%s'" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "Ixabiso '%s' alinakho ukuchazwa njengenani." + +#: ../glib/gkeyfile.c:3886 +#, fuzzy, c-format +msgid "Integer value '%s' out of range" +msgstr "Ixabiso lenani elimbaxa '%s' le %s lingaphaya kwesigaba" + +#: ../glib/gkeyfile.c:3919 +#, fuzzy, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "Ixabiso '%s' alinakho ukuchazwa njengenani." + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "Ixabiso '%s' alinakho ukuchazwa njenge-boolean." + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "Ulandelelwano olungasebenziyo lwe-byte kungeniso-lwazi yenguqulo" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +#, fuzzy +msgid "Cancellable initialization not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../gio/gcontenttype.c:180 +#, fuzzy +msgid "Unknown type" +msgstr "Ukhetho olungaziwayo %s" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, fuzzy, c-format +msgid "Unknown bus type %d" +msgstr "Ukhetho olungaziwayo %s" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "Impazamo yokuvula uvimba weefayili '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "Impazamo yokuvula uvimba weefayili '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +#, fuzzy +msgid "Abstract name space not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "Impazamo emgceni %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "Uphawu '%s' alusebenzi ngaphakathi kwegama lento ezimeleyo" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "Uphawu '%s' alusebenzi ngaphakathi kwegama lento ezimeleyo" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "Uphawu '%s' alusebenzi ngaphakathi kwegama lento ezimeleyo" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "Impazamo yokuvula uvimba weefayili '%s': %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +#, fuzzy +msgid "Operation not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +#, fuzzy +msgid "Splice not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +#, fuzzy +msgid "Trash not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +#, fuzzy +msgid "empty names are not permitted" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "Igama lomququzeleli elingasebenziyo" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "Igama lomququzeleli elingasebenziyo" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "Akuphumelelekanga ukudala ifayili '%s': %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "Akuphumelelekanga ukudala ifayili '%s': %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "Akuphumelelekanga ukudala ifayili '%s': %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "Impazamo yokuvula uvimba weefayili '%s': %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "Akuphumelelanga ukufunda ikhonkco elingumfuziselo '%s': %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "Uxwebhu luphele ngesiquphe ngaphakathi kwegama lophawu" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "Impazamo yokuvula uvimba weefayili '%s': %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "Impazamo emgceni %d: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, fuzzy, c-format +msgid "Setting attribute %s not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +#, fuzzy +msgid "Target file is not a regular file" +msgstr "Asiyofayili esebenza rhoqo" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "Igama lomququzeleli elingasebenziyo" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, fuzzy, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "Ukhetho olungaziwayo %s" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "Akuphumelelekanga ukudala ifayili '%s': %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "Akwazekanga ukwaba %lu ii-byte ukufunda ifayili \"%s\"" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "Akuphumelelekanga ukudala ifayili '%s': %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "Akuphumelelekanga ukudala ifayili '%s': %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "Impazamo emgceni %d: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "Impazamo ngelixa lenguqulo: %s" + +#: ../gio/gwin32appinfo.c:335 +#, fuzzy +msgid "URIs not supported" +msgstr "Ikhonkco elingumfuziselo alixhaswanga" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "Impazamo yokufunda ifayili '%s': %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "Igama lomququzeleli elingasebenziyo" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "Ulandelelwano olungasebenziyo kwinguqulo yongeniso-lwazi" + +#, fuzzy +#~ msgid "[FILE...]" +#~ msgstr "[OPTION...]" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "Uphawu '%s' alusebenzi ekuqaleni kwegama lento ezimeleyo; u-& uphawu " +#~ "uqala into ezimeleyo; ukuba le ampersand ayifanelanga ukuba yinto " +#~ "ezimeleyo, yiphephise njenge &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "Uphawu lokuthumela oluze; kufuneka luquke umvo ofana nalo dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "Into ezimeleyo yokuthumela engagqitywanga" + +#~ msgid "Unfinished character reference" +#~ msgstr "Uphawu lokuthumela olungagqitywanga" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "Umbhalo onxulumanisayo ongasebenziyo we- UTF-8" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "Umbhalo onxulumanisayo ongasebenziyo we- UTF-8" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "Igama lomququzeleli weURI '%s' alisebenzi" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "Igama lomququzeleli weURI '%s' alisebenzi" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "Impazamo yokufunda ifayili '%s': %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "Impazamo ngelixa lenguqulo: %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "" +#~ "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "" +#~ "Akuphumelelekanga ukuvula ifayili '%s': fdopen() akuphumelelekanga: %s" diff --git a/po/yi.po b/po/yi.po new file mode 100644 index 0000000..997f5bb --- /dev/null +++ b/po/yi.po @@ -0,0 +1,3817 @@ +# Yiddish version +# Copyright (C) 2003 Free Software Foundation, Inc. +# Raphael Finkel , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: 1.0\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2011-09-04 23:56-0400\n" +"PO-Revision-Date: 2003-03-19\n" +"Last-Translator: Raphael Finkel \n" +"Language-Team: Yiddish \n" +"Language: yi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../glib/gbookmarkfile.c:780 +#, fuzzy, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "" +"מ×ָדנע שריפֿטצײכן '%s'; דערװ×ַרט ×Ö· '=' שריפֿטצײכן × ×ָך ×ַטריבוט־נ×ָמען %s ×¤Ö¿×•× ×¢× " +"עלעמענט '%s'" + +#: ../glib/gbookmarkfile.c:791 ../glib/gbookmarkfile.c:862 +#: ../glib/gbookmarkfile.c:872 ../glib/gbookmarkfile.c:979 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1214 +#: ../glib/gbookmarkfile.c:1278 ../glib/gbookmarkfile.c:1288 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "" + +#: ../glib/gbookmarkfile.c:1174 ../glib/gbookmarkfile.c:1188 +#: ../glib/gbookmarkfile.c:1256 ../glib/gbookmarkfile.c:1308 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:1834 +msgid "No valid bookmark file found in data dirs" +msgstr "" + +#: ../glib/gbookmarkfile.c:2035 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "" + +#: ../glib/gbookmarkfile.c:2081 ../glib/gbookmarkfile.c:2239 +#: ../glib/gbookmarkfile.c:2324 ../glib/gbookmarkfile.c:2404 +#: ../glib/gbookmarkfile.c:2489 ../glib/gbookmarkfile.c:2572 +#: ../glib/gbookmarkfile.c:2650 ../glib/gbookmarkfile.c:2729 +#: ../glib/gbookmarkfile.c:2771 ../glib/gbookmarkfile.c:2868 +#: ../glib/gbookmarkfile.c:2994 ../glib/gbookmarkfile.c:3184 +#: ../glib/gbookmarkfile.c:3260 ../glib/gbookmarkfile.c:3425 +#: ../glib/gbookmarkfile.c:3514 ../glib/gbookmarkfile.c:3604 +#: ../glib/gbookmarkfile.c:3732 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2413 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2498 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:2877 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3278 ../glib/gbookmarkfile.c:3435 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "" + +#: ../glib/gbookmarkfile.c:3458 +#, fuzzy, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../glib/gconvert.c:567 ../glib/gconvert.c:645 ../glib/giochannel.c:1404 +#: ../gio/gcharsetconverter.c:458 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "פֿ×ַרװ×ַנדלונג פֿון ×§×ָדירונג %s צו %s ניט געשטיצט" + +#: ../glib/gconvert.c:571 ../glib/gconvert.c:649 +#: ../gio/gcharsetconverter.c:462 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "ניט געקענט עפֿענען פֿ×ַרװ×ַנדלער פֿון %s צו %s: %s" + +#: ../glib/gconvert.c:768 ../glib/gconvert.c:1162 ../glib/giochannel.c:1576 +#: ../glib/giochannel.c:1618 ../glib/giochannel.c:2461 ../glib/gutf8.c:1012 +#: ../glib/gutf8.c:1463 ../gio/gcharsetconverter.c:345 +#: ../gio/gdatainputstream.c:854 ../gio/gdatainputstream.c:1291 +msgid "Invalid byte sequence in conversion input" +msgstr "×ומלעקסיק ×ַכטעלע־סעײַװענץ ×ין פֿ×ַרװ×ַנדלונג ×ַרױסשרײַב" + +#: ../glib/gconvert.c:777 ../glib/gconvert.c:1087 ../glib/giochannel.c:1583 +#: ../glib/giochannel.c:2473 ../gio/gcharsetconverter.c:350 +#, c-format +msgid "Error during conversion: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../glib/gconvert.c:809 ../glib/gutf8.c:1008 ../glib/gutf8.c:1218 +#: ../glib/gutf8.c:1355 ../glib/gutf8.c:1459 +msgid "Partial character sequence at end of input" +msgstr "×”×ַלבע ×›×ַר×ַקטער־סעקװענץ ×¦×•× ×¡×•×£ פֿון ×ַרײַנשרײַב" + +#: ../glib/gconvert.c:1059 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "ניט געקענט פֿ×ַרװ×ַנדלען גרונטב×ַטרעף %s צו ×§×ָדירונג %s" + +#: ../glib/gconvert.c:1886 +#, fuzzy, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "דער URI %s ××™×– ניט ×ַבס×ָלוט לױט דער טעקע־סכעמע" + +#: ../glib/gconvert.c:1896 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "דער ל×ָק×ַלער טעקע־URI %s ט×ָר ניט כּולל זײַן ×Ö· '#'" + +#: ../glib/gconvert.c:1913 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "דער URI %s ××™×– ×ומלעקסיק" + +#: ../glib/gconvert.c:1925 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "דער מ×ַשין־נ×ָמען ×¤Ö¿×•× ×¢× URI %s ××™×– ×ומלעקסיק" + +#: ../glib/gconvert.c:1941 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "דער URI %s ××™×– כּולל ×ומלעקסיקע פּליטה־כ×ַר×ַקטערס" + +#: ../glib/gconvert.c:2036 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "די פּ×ַפּקע־רשימה %s ××™×– ניט ×ַבס×ָלוט" + +#: ../glib/gconvert.c:2046 +msgid "Invalid hostname" +msgstr "×ומלעקסיקער מ×ַשין־נ×ָמען" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:202 +msgctxt "GDateTime" +msgid "AM" +msgstr "AM" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:204 +msgctxt "GDateTime" +msgid "PM" +msgstr "PM" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:207 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Z %H:%M:%S %Y %b %d %a" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:210 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%d/%m/%y" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:213 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:216 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%I:%M:%S %P" + +#: ../glib/gdatetime.c:229 +msgctxt "full month name" +msgid "January" +msgstr "×™×ַנו×ַר" + +#: ../glib/gdatetime.c:231 +msgctxt "full month name" +msgid "February" +msgstr "פֿעברו×ַר" + +#: ../glib/gdatetime.c:233 +msgctxt "full month name" +msgid "March" +msgstr "מ×ַרץ" + +#: ../glib/gdatetime.c:235 +msgctxt "full month name" +msgid "April" +msgstr "×ַפּריל" + +#: ../glib/gdatetime.c:237 +msgctxt "full month name" +msgid "May" +msgstr "מײַ" + +#: ../glib/gdatetime.c:239 +msgctxt "full month name" +msgid "June" +msgstr "יוני" + +#: ../glib/gdatetime.c:241 +msgctxt "full month name" +msgid "July" +msgstr "יולי" + +#: ../glib/gdatetime.c:243 +msgctxt "full month name" +msgid "August" +msgstr "" + +#: ../glib/gdatetime.c:245 +msgctxt "full month name" +msgid "September" +msgstr "" + +#: ../glib/gdatetime.c:247 +msgctxt "full month name" +msgid "October" +msgstr "" + +#: ../glib/gdatetime.c:249 +msgctxt "full month name" +msgid "November" +msgstr "" + +#: ../glib/gdatetime.c:251 +msgctxt "full month name" +msgid "December" +msgstr "" + +#: ../glib/gdatetime.c:266 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "×™×Ö·× " + +#: ../glib/gdatetime.c:268 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "פֿעב" + +#: ../glib/gdatetime.c:270 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "מ×ַר" + +#: ../glib/gdatetime.c:272 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "×ַפּר" + +#: ../glib/gdatetime.c:274 +msgctxt "abbreviated month name" +msgid "May" +msgstr "מײַ " + +#: ../glib/gdatetime.c:276 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "יונ" + +#: ../glib/gdatetime.c:278 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "יול" + +#: ../glib/gdatetime.c:280 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "" + +#: ../glib/gdatetime.c:282 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "" + +#: ../glib/gdatetime.c:284 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "" + +#: ../glib/gdatetime.c:286 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "" + +#: ../glib/gdatetime.c:288 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "" + +#: ../glib/gdatetime.c:303 +msgctxt "full weekday name" +msgid "Monday" +msgstr "מ×ָנטיק" + +#: ../glib/gdatetime.c:305 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "דינסטיק" + +#: ../glib/gdatetime.c:307 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "מיטװ×ָך" + +#: ../glib/gdatetime.c:309 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "ד×ָנערשטיק" + +#: ../glib/gdatetime.c:311 +msgctxt "full weekday name" +msgid "Friday" +msgstr "פֿרײַטיק" + +#: ../glib/gdatetime.c:313 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "שבת" + +#: ../glib/gdatetime.c:315 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "זונטיק" + +#: ../glib/gdatetime.c:330 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "מ×ָנ'" + +#: ../glib/gdatetime.c:332 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "דינ'" + +#: ../glib/gdatetime.c:334 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "מיט'" + +#: ../glib/gdatetime.c:336 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "ד×ָנ'" + +#: ../glib/gdatetime.c:338 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "פֿרײַ'" + +#: ../glib/gdatetime.c:340 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "שבת" + +#: ../glib/gdatetime.c:342 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "זונ'" + +#: ../glib/gdir.c:115 ../glib/gdir.c:138 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "דורכפֿ×ַל ×ין עפֿענען פּ×ַפּקע %s: %s" + +#: ../glib/gfileutils.c:540 ../glib/gfileutils.c:628 +#, c-format +msgid "Could not allocate %lu bytes to read file \"%s\"" +msgstr "ניט געקענט ×ױסטײלן %lu ×ַכטעלעך צו לײענען טעקע %s" + +#: ../glib/gfileutils.c:555 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../glib/gfileutils.c:569 +#, c-format +msgid "File \"%s\" is too large" +msgstr "" + +#: ../glib/gfileutils.c:652 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "ניט געקענט לײענען טעקע %s: %s" + +#: ../glib/gfileutils.c:703 ../glib/gfileutils.c:790 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "ניט געקענט עפֿענען טעקע '%s': %s" + +#: ../glib/gfileutils.c:720 ../glib/gmappedfile.c:169 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "ניט געקענט ב×ַקומען ×ַטריבוטן פֿון טעקע %s: fstat() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gfileutils.c:754 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gfileutils.c:862 +#, fuzzy, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gfileutils.c:904 ../glib/gfileutils.c:1449 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../glib/gfileutils.c:918 +#, fuzzy, c-format +msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gfileutils.c:943 +#, fuzzy, c-format +msgid "Failed to write file '%s': fwrite() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gfileutils.c:962 +#, fuzzy, c-format +msgid "Failed to write file '%s': fflush() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gfileutils.c:1006 +#, fuzzy, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gfileutils.c:1030 +#, fuzzy, c-format +msgid "Failed to close file '%s': fclose() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gfileutils.c:1152 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "" + +#: ../glib/gfileutils.c:1412 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "מוסטער %s ×ומלעקסיק, ט×ָר ניט כּולל זײַן %s" + +#: ../glib/gfileutils.c:1425 +#, fuzzy, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "מוסטער %s ענדיקט זיך ניט מיט XXXXXX" + +#: ../glib/gfileutils.c:2001 ../glib/gfileutils.c:2029 +#: ../glib/gfileutils.c:2134 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2007 +#, c-format +msgid "%.1f KiB" +msgstr "" + +#: ../glib/gfileutils.c:2010 +#, c-format +msgid "%.1f MiB" +msgstr "" + +#: ../glib/gfileutils.c:2013 +#, c-format +msgid "%.1f GiB" +msgstr "" + +#: ../glib/gfileutils.c:2016 +#, c-format +msgid "%.1f TiB" +msgstr "" + +#: ../glib/gfileutils.c:2019 +#, c-format +msgid "%.1f PiB" +msgstr "" + +#: ../glib/gfileutils.c:2022 +#, c-format +msgid "%.1f EiB" +msgstr "" + +#: ../glib/gfileutils.c:2035 +#, c-format +msgid "%.1f kB" +msgstr "" + +#: ../glib/gfileutils.c:2038 ../glib/gfileutils.c:2147 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: ../glib/gfileutils.c:2041 ../glib/gfileutils.c:2152 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: ../glib/gfileutils.c:2044 ../glib/gfileutils.c:2157 +#, c-format +msgid "%.1f TB" +msgstr "" + +#: ../glib/gfileutils.c:2047 ../glib/gfileutils.c:2162 +#, c-format +msgid "%.1f PB" +msgstr "" + +#: ../glib/gfileutils.c:2050 ../glib/gfileutils.c:2167 +#, c-format +msgid "%.1f EB" +msgstr "" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gfileutils.c:2087 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../glib/gfileutils.c:2142 +#, c-format +msgid "%.1f KB" +msgstr "" + +#: ../glib/gfileutils.c:2210 +#, fuzzy, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../glib/gfileutils.c:2231 +msgid "Symbolic links not supported" +msgstr "" + +#: ../glib/giochannel.c:1408 +#, fuzzy, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "ניט געקענט עפֿענען פֿ×ַרװ×ַנדלער פֿון %s צו %s: %s" + +#: ../glib/giochannel.c:1753 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "ניט געקענט מ×ַכן ×Ö· רױ־לײען ×ין g_io_channel_read_line_string" + +#: ../glib/giochannel.c:1800 ../glib/giochannel.c:2057 +#: ../glib/giochannel.c:2144 +msgid "Leftover unconverted data in read buffer" +msgstr "×יבעריקע ניט־פֿ×ַרװ×ַנדלטע ד×ַטן ×ין לײען־ב×Ö·×”×ַלט×ָרט" + +#: ../glib/giochannel.c:1881 ../glib/giochannel.c:1958 +msgid "Channel terminates in a partial character" +msgstr "×§×Ö·× ×ַל ענדיקט זיך מיט ×Ö· ×”×ַלבן שריפֿטצײכן" + +#: ../glib/giochannel.c:1944 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "ניט געקענט מ×ַכן ×Ö· רױ־לײען ×ין g_io_channel_read_to_end" + +#: ../glib/gmappedfile.c:150 +#, fuzzy, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gmappedfile.c:229 +#, fuzzy, c-format +msgid "Failed to map file '%s': mmap() failed: %s" +msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#: ../glib/gmarkup.c:355 ../glib/gmarkup.c:396 +#, fuzzy, c-format +msgid "Error on line %d char %d: " +msgstr "דורכפֿ×ַל ××±×£ שורה %d פּ×ָזיציע %d: %s" + +#: ../glib/gmarkup.c:418 ../glib/gmarkup.c:501 +#, fuzzy, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "×ומלעקסיק UTFÖ¾8 ×§×ָדירטער טעקסט" + +#: ../glib/gmarkup.c:429 +#, c-format +msgid "'%s' is not a valid name " +msgstr "" + +#: ../glib/gmarkup.c:445 +#, c-format +msgid "'%s' is not a valid name: '%c' " +msgstr "" + +#: ../glib/gmarkup.c:554 +#, c-format +msgid "Error on line %d: %s" +msgstr "דורכפֿ×ַל ××±×£ שורה %d: %s" + +#: ../glib/gmarkup.c:638 +#, fuzzy, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "" +"דורכפֿ×ַל ×ין ×Ö·× ×ַליזירן '%s', ×°×ָס ×–×ָל ×”×ָבן ×Ö· ציפֿער ×ין דער שריפֿטצײכן־רעפֿערענץ " +"(למשל ê); ×פֿשר ××™×– דער ציפֿער צו גרױס" + +#: ../glib/gmarkup.c:650 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "" +"שריפֿטצײכן־רעפֿערענץ ×”×ָט זיך ניט געענדיקט מיט קײן \";\". ×ž×¡×ªÖ¼×ž× ×”×ָט מען געשריבן " +"×ַן & שריפֿטצײכן ×ָן דער ×›Ö¼×°× ×” ×ָנצוהײבן ×ַן ×ײנס. × ×ָרמ×ַליר & ×°×™ &" + +#: ../glib/gmarkup.c:676 +#, fuzzy, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "שריפֿטצײכן־רעפֿערענץ '%s' ×§×ָדירט ניט קײן דערל×ָזטן שריפֿטצײכן" + +#: ../glib/gmarkup.c:714 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "" +"לײדיקער ×ײנס '&;' געזען; לעקסיקע ×ײנסן זײַנען: & " < > '" + +#: ../glib/gmarkup.c:722 +#, fuzzy, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "×ײנסנ×ָמען %s ××™×– ניט ב×Ö·×§×ַנט" + +#: ../glib/gmarkup.c:727 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "" +"×ײנס ×”×ָט זיך ניט געענדיקט מיט קײן \";\". ×ž×¡×ªÖ¼×ž× ×”×ָט מען געשריבן ×ַן & " +"שריפֿטצײכן ×ָן דער ×›Ö¼×°× ×” ×ָנצוהײבן ×ַן ×ײנס. × ×ָרמ×ַליר & ×°×™ &" + +#: ../glib/gmarkup.c:1078 +msgid "Document must begin with an element (e.g. )" +msgstr "ד×ָקומענט מוז ×ָנהײבן מיט ×ַן עלעמענט (×°×™ למשל )" + +#: ../glib/gmarkup.c:1118 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "" +"'%s' ×יך ניט קײן לעקסיקער שריפֿטצײכן × ×ָך ×Ö· '‪<‬' שריפֿטצײכן;עס ט×ָר ניט ×ָנהײבן " +"קײן ×ײנסנ×ָמען" + +#: ../glib/gmarkup.c:1186 +#, fuzzy, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "" +"מ×ָדנע שריפֿטצײכן '%s'; דערװ×ַרט ×Ö· '‪>‬' שריפֿטצײכן צו ענדיקן ×“×¢× ×ָנהײב־הענטל " +"×¤Ö¿×•× ×¢× ×¢×œ×¢×ž×¢× ×˜ '%s'" + +#: ../glib/gmarkup.c:1270 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "" +"מ×ָדנע שריפֿטצײכן '%s'; דערװ×ַרט ×Ö· '=' שריפֿטצײכן × ×ָך ×ַטריבוט־נ×ָמען %s ×¤Ö¿×•× ×¢× " +"עלעמענט '%s'" + +#: ../glib/gmarkup.c:1311 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"מ×ָדנע שריפֿטצײכן '%s'; דערװ×ַרט ×Ö· '‪>‬' ×ָדער '/' שריפֿטצײכן צו ענדיקן ×“×¢× ×ָנהײב־" +"הענטל ×¤Ö¿×•× ×¢× ×¢×œ×¢×ž×¢× ×˜ '%s'; ×פֿשר ×”×ָט מען געלײגט ×ַן ×ומלעקסיקן שריפֿטצײכן ×ין ×ַן " +"×ַטריבוט־נ×ָמען" + +#: ../glib/gmarkup.c:1355 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "" +"מ×ָדנע שריפֿטצײכן '%s'; דערװ×ַרט ×Ö· '\"' × ×ָך ×“×¢× '=' צו ב×ַשטעטיקן ×“×¢× ×‘×ַטרעף פֿון " +"×ַטריבוט '%s' ×¤Ö¿×•× ×¢× ×¢×œ×¢×ž×¢× ×˜ '%s'" + +#: ../glib/gmarkup.c:1488 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "" +"'%s' ××™×– ניט קײן לעקסיקער שריפֿטצײכן × ×ָך ×“×¢× ×©×œ×ָס־עלעמענט × ×ָמען '%s'; מען מוז " +"שטעלן '‪>‬'" + +#: ../glib/gmarkup.c:1535 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "עלעמענט '%s' ××™×– פֿ×ַרמ×ַכט; קײן עלעמענט ××™×– דערװײַל ×ָפֿן" + +#: ../glib/gmarkup.c:1544 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "עלעמענט '%s' ××™×– פֿ×ַרמ×ַכט; דער ×יצטיקער ×ָפֿענער עלעמענט ××™×– '%s'" + +#: ../glib/gmarkup.c:1712 +msgid "Document was empty or contained only whitespace" +msgstr "ד×ָקומענט ××™×– פּוסט ×ָדער ××™×– כּולל בלױז לײדיק ×ָרט" + +#: ../glib/gmarkup.c:1726 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט × ×ָך ×ַן עפֿן־צײכן '‪<‬'" + +#: ../glib/gmarkup.c:1734 ../glib/gmarkup.c:1779 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "" +"ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט מיט ×ָפֿענע עלעמענטן; '%s' ××™×– געװען דער " +"לעצט־געעפֿנטער עלעמענט" + +#: ../glib/gmarkup.c:1742 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט; דערװ×ַרט ×Ö· של×ָס־צײכן '‪>‬' צו ענדיקן ×“×¢× " +"הענטל ‪<%s/>‬" + +#: ../glib/gmarkup.c:1748 +msgid "Document ended unexpectedly inside an element name" +msgstr "ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט ×ין דרינען פֿון ×ַן עלעמענט־נ×ָמען" + +#: ../glib/gmarkup.c:1754 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט ×ין דרינען פֿון ×ַן ×ַטריבוט־נ×ָמען" + +#: ../glib/gmarkup.c:1759 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט ×ין דרינען פֿון ×ַן עלעמענט־עפֿן הענטל" + +#: ../glib/gmarkup.c:1765 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט × ×ָך ×“×¢× '=' שריפֿטצײכן × ×ָך ×ַן ×ַטריבוט־" +"× ×ָמען ×ָן קײן ×ַטריבוט־ב×ַטרעף" + +#: ../glib/gmarkup.c:1772 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט ×ין דרינען פֿון ×ַן ×ַטריבוט־ב×ַטרעף" + +#: ../glib/gmarkup.c:1788 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "" +"ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט ×ין דרינען פֿון ×“×¢× ×©×œ×ָס־הענטל פֿון עלעמענט " +"'%s'" + +#: ../glib/gmarkup.c:1794 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "" +"ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט ×ין דרינען פֿון ×Ö· ×§×ָמענט×ַר ×ָדער ×Ö· ב×Ö·×ַרבעטן־" +"ב×ַפֿעל" + +#: ../glib/gregex.c:189 +msgid "corrupted object" +msgstr "" + +#: ../glib/gregex.c:191 +msgid "internal error or corrupted object" +msgstr "" + +#: ../glib/gregex.c:193 +msgid "out of memory" +msgstr "" + +#: ../glib/gregex.c:198 +msgid "backtracking limit reached" +msgstr "" + +#: ../glib/gregex.c:210 ../glib/gregex.c:218 +msgid "the pattern contains items not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:212 ../gio/glocalfile.c:2107 +msgid "internal error" +msgstr "" + +#: ../glib/gregex.c:220 +msgid "back references as conditions are not supported for partial matching" +msgstr "" + +#: ../glib/gregex.c:229 +msgid "recursion limit reached" +msgstr "" + +#: ../glib/gregex.c:231 +msgid "workspace limit for empty substrings reached" +msgstr "" + +#: ../glib/gregex.c:233 +msgid "invalid combination of newline flags" +msgstr "" + +#: ../glib/gregex.c:235 +msgid "bad offset" +msgstr "" + +#: ../glib/gregex.c:237 +msgid "short utf8" +msgstr "" + +#: ../glib/gregex.c:241 +msgid "unknown error" +msgstr "" + +#: ../glib/gregex.c:261 +msgid "\\ at end of pattern" +msgstr "" + +#: ../glib/gregex.c:264 +msgid "\\c at end of pattern" +msgstr "" + +#: ../glib/gregex.c:267 +msgid "unrecognized character follows \\" +msgstr "" + +#: ../glib/gregex.c:274 +msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +msgstr "" + +#: ../glib/gregex.c:277 +msgid "numbers out of order in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:280 +msgid "number too big in {} quantifier" +msgstr "" + +#: ../glib/gregex.c:283 +#, fuzzy +msgid "missing terminating ] for character class" +msgstr "×§×Ö·× ×ַל ענדיקט זיך מיט ×Ö· ×”×ַלבן שריפֿטצײכן" + +#: ../glib/gregex.c:286 +#, fuzzy +msgid "invalid escape sequence in character class" +msgstr "×ומלעקסיק ×ַכטעלע־סעײַװענץ ×ין פֿ×ַרװ×ַנדלונג ×ַרױסשרײַב" + +#: ../glib/gregex.c:289 +msgid "range out of order in character class" +msgstr "" + +#: ../glib/gregex.c:292 +msgid "nothing to repeat" +msgstr "" + +#: ../glib/gregex.c:295 +#, fuzzy +msgid "unrecognized character after (?" +msgstr "ניט־געענדיקט שריפֿטצײכן־רעפֿערענץ" + +#: ../glib/gregex.c:299 +#, fuzzy +msgid "unrecognized character after (?<" +msgstr "ניט־געענדיקט שריפֿטצײכן־רעפֿערענץ" + +#: ../glib/gregex.c:303 +#, fuzzy +msgid "unrecognized character after (?P" +msgstr "ניט־געענדיקט שריפֿטצײכן־רעפֿערענץ" + +#: ../glib/gregex.c:306 +msgid "POSIX named classes are supported only within a class" +msgstr "" + +#: ../glib/gregex.c:309 +msgid "missing terminating )" +msgstr "" + +#: ../glib/gregex.c:313 +msgid ") without opening (" +msgstr "" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:320 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "" + +#: ../glib/gregex.c:323 +msgid "reference to non-existent subpattern" +msgstr "" + +#: ../glib/gregex.c:326 +msgid "missing ) after comment" +msgstr "" + +#: ../glib/gregex.c:329 +msgid "regular expression too large" +msgstr "" + +#: ../glib/gregex.c:332 +msgid "failed to get memory" +msgstr "" + +#: ../glib/gregex.c:335 +msgid "lookbehind assertion is not fixed length" +msgstr "" + +#: ../glib/gregex.c:338 +msgid "malformed number or name after (?(" +msgstr "" + +#: ../glib/gregex.c:341 +msgid "conditional group contains more than two branches" +msgstr "" + +#: ../glib/gregex.c:344 +msgid "assertion expected after (?(" +msgstr "" + +#: ../glib/gregex.c:347 +msgid "unknown POSIX class name" +msgstr "" + +#: ../glib/gregex.c:350 +msgid "POSIX collating elements are not supported" +msgstr "" + +#: ../glib/gregex.c:353 +msgid "character value in \\x{...} sequence is too large" +msgstr "" + +#: ../glib/gregex.c:356 +msgid "invalid condition (?(0)" +msgstr "" + +#: ../glib/gregex.c:359 +msgid "\\C not allowed in lookbehind assertion" +msgstr "" + +#: ../glib/gregex.c:362 +msgid "recursive call could loop indefinitely" +msgstr "" + +#: ../glib/gregex.c:365 +msgid "missing terminator in subpattern name" +msgstr "" + +#: ../glib/gregex.c:368 +msgid "two named subpatterns have the same name" +msgstr "" + +#: ../glib/gregex.c:371 +msgid "malformed \\P or \\p sequence" +msgstr "" + +#: ../glib/gregex.c:374 +msgid "unknown property name after \\P or \\p" +msgstr "" + +#: ../glib/gregex.c:377 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "" + +#: ../glib/gregex.c:380 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "" + +#: ../glib/gregex.c:383 +msgid "octal value is greater than \\377" +msgstr "" + +#: ../glib/gregex.c:386 +msgid "DEFINE group contains more than one branch" +msgstr "" + +#: ../glib/gregex.c:389 +msgid "repeating a DEFINE group is not allowed" +msgstr "" + +#: ../glib/gregex.c:392 +msgid "inconsistent NEWLINE options" +msgstr "" + +#: ../glib/gregex.c:395 +msgid "" +"\\g is not followed by a braced name or an optionally braced non-zero number" +msgstr "" + +#: ../glib/gregex.c:400 +msgid "unexpected repeat" +msgstr "" + +#: ../glib/gregex.c:404 +msgid "code overflow" +msgstr "" + +#: ../glib/gregex.c:408 +msgid "overran compiling workspace" +msgstr "" + +#: ../glib/gregex.c:412 +msgid "previously-checked referenced subpattern not found" +msgstr "" + +#: ../glib/gregex.c:630 ../glib/gregex.c:1753 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:1206 +msgid "PCRE library is compiled without UTF8 support" +msgstr "" + +#: ../glib/gregex.c:1215 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "" + +#: ../glib/gregex.c:1271 +#, fuzzy, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "דורכפֿ×ַל ××±×£ שורה %d פּ×ָזיציע %d: %s" + +#: ../glib/gregex.c:1307 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "" + +#: ../glib/gregex.c:2183 +msgid "hexadecimal digit or '}' expected" +msgstr "" + +#: ../glib/gregex.c:2199 +msgid "hexadecimal digit expected" +msgstr "" + +#: ../glib/gregex.c:2239 +msgid "missing '<' in symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2248 +#, fuzzy +msgid "unfinished symbolic reference" +msgstr "ניט־געענדיקט ×ײנס־רעפֿערענץ" + +#: ../glib/gregex.c:2255 +msgid "zero-length symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2266 +msgid "digit expected" +msgstr "" + +#: ../glib/gregex.c:2284 +msgid "illegal symbolic reference" +msgstr "" + +#: ../glib/gregex.c:2346 +msgid "stray final '\\'" +msgstr "" + +#: ../glib/gregex.c:2350 +msgid "unknown escape sequence" +msgstr "" + +#: ../glib/gregex.c:2360 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "" + +#: ../glib/gshell.c:91 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "ציטירטער טעקסט הײבט ניט ×ָן מיט קײן גענדזן־פֿיסל" + +#: ../glib/gshell.c:181 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "גענדזן־פֿיסל ×ָן ×Ö· ×–×™×°×’ ×ין ב×ַפֿעל־שורה ×ָדער ×ַנדער ציטירטן טעקסט" + +#: ../glib/gshell.c:559 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "" +"טעקסט ×”×ָט זיך געענדיקט ב×ַלד × ×ָך ×Ö· '\\' שריפֿטצײכן. (דער טעקסט ××™×– געװען '%s')" + +#: ../glib/gshell.c:566 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "" +"טעקסט ×”×ָט זיך געענדיקט ×ײדער ×Ö· ×–×™×°×’ צו ×“×¢× ×’×¢× ×“×–×ŸÖ¾×¤Ö¿×™×¡×œ ‪%c‬. (דער טעקסט ××™×– " +"געװען '%s')" + +#: ../glib/gshell.c:578 +msgid "Text was empty (or contained only whitespace)" +msgstr "טעקסט ××™×– געװען פּוסט (×ָדער ××™×– כּולל בלױס לײדיק ×ָרט)" + +#: ../glib/gspawn-win32.c:282 +msgid "Failed to read data from child process" +msgstr "ניט געקענט לײענען ד×ַטן פֿון קינדפּר×ָצעס" + +#: ../glib/gspawn-win32.c:299 ../glib/gspawn.c:1517 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "דורכפֿ×ַל ×ין ש×ַפֿן רער צוליב ×§×ָמוניקירן מיט קינדפּר×ָצעס (%s)" + +#: ../glib/gspawn-win32.c:338 ../glib/gspawn-win32.c:346 ../glib/gspawn.c:1170 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "דורכפֿ×ַל ×ין לײענע פֿון ×Ö· ינדרער (%s)" + +#: ../glib/gspawn-win32.c:369 ../glib/gspawn.c:1383 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "דורכפֿ×ַל ×ין זיך קערן צו פּ×ַפּקע '%s' (%s)" + +#: ../glib/gspawn-win32.c:375 ../glib/gspawn-win32.c:494 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "דורכפֿ×ַל ×ין ב×Ö·×ַרבעטן קינדפּר×ָצעס (%s)" + +#: ../glib/gspawn-win32.c:444 +#, fuzzy, c-format +msgid "Invalid program name: %s" +msgstr "×ומלעקסיקער מ×ַשין־נ×ָמען" + +#: ../glib/gspawn-win32.c:454 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "" + +#: ../glib/gspawn-win32.c:465 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1311 +#, fuzzy, c-format +msgid "Invalid string in environment: %s" +msgstr "×ומלעקסיקער סעקװענץ ×ין פֿ×ַרװ×ַנדל־×ַרײַנשרײַב" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1259 +#, fuzzy, c-format +msgid "Invalid working directory: %s" +msgstr "דורכפֿ×ַל ×ין עפֿענען פּ×ַפּקע %s: %s" + +#: ../glib/gspawn-win32.c:783 +#, fuzzy, c-format +msgid "Failed to execute helper program (%s)" +msgstr "דורכפֿ×ַל ×ין ב×Ö·×ַרבעטן הילף־פּר×ָגר×Ö·×" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"×ומדערװ×ַרטער דורכפֿ×ַל ×ין g_io_channel_win32_poll() בשעת לײענען ד×ַטן פֿון ×Ö· " +"קינדפּר×ָצעס" + +#: ../glib/gspawn.c:207 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "דורכפֿ×ַל ×ין לײענען ד×ַטן פֿון ×Ö· קינדפּר×ָצעס (%s)" + +#: ../glib/gspawn.c:347 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "×ומדערװ×ַרטער דורכפֿ×ַל ×ין select() לײענען ד×ַטן פֿון ×Ö· קינדפּר×ָצעס (%s)" + +#: ../glib/gspawn.c:432 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "×ומדערװ×ַרטער דורכפֿ×ַל ×ין waitpid() (%s)" + +#: ../glib/gspawn.c:1237 +#, c-format +msgid "Failed to fork (%s)" +msgstr "דורכפֿ×ַל ×ין קל×ָנירן (%s)" + +#: ../glib/gspawn.c:1393 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "דורכפֿ×ַל ×ין ב×Ö·×ַרבעטן קינדפּר×ָצעס \"%s\" (%s)" + +#: ../glib/gspawn.c:1403 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "דורכפֿ×ַל ×ין װידערצילן ×ַרױסשרײַב ×ָדער ×ַרײַנשרײַב פֿון קינדפּר×ָצעס (%s)" + +#: ../glib/gspawn.c:1412 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "דורכפֿ×ַל ×ין קל×ָנירן קינדפּר×ָצעס (%s)" + +#: ../glib/gspawn.c:1420 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "×ומב×Ö·×§×ַנטער דורכפֿ×ַל ×ין ב×Ö·×ַרבעטן קינדפּר×ָצעס \"%s\"" + +#: ../glib/gspawn.c:1444 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "דורכפֿ×ַל ×ין לײענען גענוג ד×ַטן פֿון קינד pid-רער (%s)" + +#: ../glib/gutf8.c:1086 +msgid "Character out of range for UTF-8" +msgstr "שריפֿטצײכן ניט ×ין דער UTFÖ¾8 ×’×ַמע" + +#: ../glib/gutf8.c:1186 ../glib/gutf8.c:1195 ../glib/gutf8.c:1325 +#: ../glib/gutf8.c:1334 ../glib/gutf8.c:1473 ../glib/gutf8.c:1569 +msgid "Invalid sequence in conversion input" +msgstr "×ומלעקסיקער סעקװענץ ×ין פֿ×ַרװ×ַנדל־×ַרײַנשרײַב" + +#: ../glib/gutf8.c:1484 ../glib/gutf8.c:1580 +msgid "Character out of range for UTF-16" +msgstr "שריפֿטצײכן ניט ×ין דער UTFÖ¾16 ×’×ַמע" + +#: ../glib/goption.c:760 +msgid "Usage:" +msgstr "" + +#: ../glib/goption.c:760 +msgid "[OPTION...]" +msgstr "" + +#: ../glib/goption.c:866 +msgid "Help Options:" +msgstr "" + +#: ../glib/goption.c:867 +msgid "Show help options" +msgstr "" + +#: ../glib/goption.c:873 +msgid "Show all help options" +msgstr "" + +#: ../glib/goption.c:935 +msgid "Application Options:" +msgstr "" + +#: ../glib/goption.c:997 ../glib/goption.c:1067 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1007 ../glib/goption.c:1075 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1032 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "" + +#: ../glib/goption.c:1040 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "" + +#: ../glib/goption.c:1303 ../glib/goption.c:1382 +#, fuzzy, c-format +msgid "Error parsing option %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../glib/goption.c:1413 ../glib/goption.c:1526 +#, c-format +msgid "Missing argument for %s" +msgstr "" + +#: ../glib/goption.c:1957 +#, c-format +msgid "Unknown option %s" +msgstr "" + +#: ../glib/gkeyfile.c:366 +msgid "Valid key file could not be found in search dirs" +msgstr "" + +#: ../glib/gkeyfile.c:401 +msgid "Not a regular file" +msgstr "" + +#: ../glib/gkeyfile.c:409 +msgid "File is empty" +msgstr "" + +#: ../glib/gkeyfile.c:768 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "" + +#: ../glib/gkeyfile.c:828 +#, fuzzy, c-format +msgid "Invalid group name: %s" +msgstr "×ומלעקסיקער מ×ַשין־נ×ָמען" + +#: ../glib/gkeyfile.c:850 +msgid "Key file does not start with a group" +msgstr "" + +#: ../glib/gkeyfile.c:876 +#, fuzzy, c-format +msgid "Invalid key name: %s" +msgstr "×ומלעקסיקער מ×ַשין־נ×ָמען" + +#: ../glib/gkeyfile.c:903 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1149 ../glib/gkeyfile.c:1311 ../glib/gkeyfile.c:2686 +#: ../glib/gkeyfile.c:2752 ../glib/gkeyfile.c:2887 ../glib/gkeyfile.c:3020 +#: ../glib/gkeyfile.c:3162 ../glib/gkeyfile.c:3394 ../glib/gkeyfile.c:3463 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1323 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:1430 ../glib/gkeyfile.c:1546 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "" + +#: ../glib/gkeyfile.c:1450 ../glib/gkeyfile.c:1934 +#, c-format +msgid "Key file contains key '%s' which has value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:1566 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2151 ../glib/gkeyfile.c:2515 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has value that cannot be " +"interpreted." +msgstr "" + +#: ../glib/gkeyfile.c:2701 ../glib/gkeyfile.c:2902 ../glib/gkeyfile.c:3474 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "" + +#: ../glib/gkeyfile.c:3708 +msgid "Key file contains escape character at end of line" +msgstr "" + +#: ../glib/gkeyfile.c:3730 +#, fuzzy, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "דער URI %s ××™×– כּולל ×ומלעקסיקע פּליטה־כ×ַר×ַקטערס" + +#: ../glib/gkeyfile.c:3872 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "" + +#: ../glib/gkeyfile.c:3886 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "" + +#: ../glib/gkeyfile.c:3919 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "" + +#: ../glib/gkeyfile.c:3943 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "" + +#: ../gio/gbufferedinputstream.c:411 ../gio/gbufferedinputstream.c:492 +#: ../gio/ginputstream.c:185 ../gio/ginputstream.c:317 +#: ../gio/ginputstream.c:556 ../gio/ginputstream.c:680 +#: ../gio/goutputstream.c:198 ../gio/goutputstream.c:732 +#, c-format +msgid "Too large count value passed to %s" +msgstr "" + +#: ../gio/gbufferedinputstream.c:881 ../gio/ginputstream.c:888 +#: ../gio/giostream.c:306 ../gio/goutputstream.c:1206 +msgid "Stream is already closed" +msgstr "" + +#: ../gio/gcancellable.c:321 ../gio/gdbusconnection.c:1640 +#: ../gio/gdbusconnection.c:1729 ../gio/gdbusconnection.c:1916 +#: ../gio/glocalfile.c:2100 ../gio/gsimpleasyncresult.c:814 +#: ../gio/gsimpleasyncresult.c:840 +msgid "Operation was cancelled" +msgstr "" + +#: ../gio/gcharsetconverter.c:263 +msgid "Invalid object, not initialized" +msgstr "" + +#: ../gio/gcharsetconverter.c:284 ../gio/gcharsetconverter.c:312 +#, fuzzy +msgid "Incomplete multibyte sequence in input" +msgstr "×ומלעקסיק ×ַכטעלע־סעײַװענץ ×ין פֿ×ַרװ×ַנדלונג ×ַרױסשרײַב" + +#: ../gio/gcharsetconverter.c:318 ../gio/gcharsetconverter.c:327 +msgid "Not enough space in destination" +msgstr "" + +#: ../gio/gcharsetconverter.c:447 ../gio/gsocket.c:854 +msgid "Cancellable initialization not supported" +msgstr "" + +#: ../gio/gcontenttype.c:180 +msgid "Unknown type" +msgstr "" + +#: ../gio/gcontenttype.c:181 +#, c-format +msgid "%s filetype" +msgstr "" + +#: ../gio/gcontenttype.c:680 +#, c-format +msgid "%s type" +msgstr "" + +#: ../gio/gcredentials.c:273 ../gio/gcredentials.c:495 +msgid "GCredentials is not implemented on this OS" +msgstr "" + +#: ../gio/gcredentials.c:447 +msgid "There is no GCredentials support for your platform" +msgstr "" + +#: ../gio/gdatainputstream.c:311 +msgid "Unexpected early end-of-stream" +msgstr "" + +#: ../gio/gdbusaddress.c:142 ../gio/gdbusaddress.c:230 +#: ../gio/gdbusaddress.c:311 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:169 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" + +#: ../gio/gdbusaddress.c:182 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:245 ../gio/gdbusaddress.c:326 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:256 ../gio/gdbusaddress.c:337 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:446 +#, c-format +msgid "Address element '%s', does not contain a colon (:)" +msgstr "" + +#: ../gio/gdbusaddress.c:467 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s', does not contain an equal " +"sign" +msgstr "" + +#: ../gio/gdbusaddress.c:481 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:559 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "" + +#: ../gio/gdbusaddress.c:595 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:609 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "" + +#: ../gio/gdbusaddress.c:644 +#, fuzzy +msgid "Error auto-launching: " +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusaddress.c:652 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:688 +#, fuzzy, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusaddress.c:706 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusaddress.c:715 +#, fuzzy, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusaddress.c:733 +#, fuzzy, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusaddress.c:951 +msgid "The given address is empty" +msgstr "" + +#: ../gio/gdbusaddress.c:1020 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "" + +#: ../gio/gdbusaddress.c:1057 +#, fuzzy, c-format +msgid "Error spawning command line '%s': " +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusaddress.c:1068 +#, c-format +msgid "Abnormal program termination spawning command line '%s': %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1082 +#, c-format +msgid "Command line '%s' exited with non-zero exit status %d: %s" +msgstr "" + +#: ../gio/gdbusaddress.c:1155 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "" + +#: ../gio/gdbusaddress.c:1254 ../gio/gdbusconnection.c:6409 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "" + +#: ../gio/gdbusaddress.c:1263 ../gio/gdbusconnection.c:6418 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" + +#: ../gio/gdbusaddress.c:1273 +#, c-format +msgid "Unknown bus type %d" +msgstr "" + +#: ../gio/gdbusauth.c:288 +msgid "Unexpected lack of content trying to read a line" +msgstr "" + +#: ../gio/gdbusauth.c:332 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "" + +#: ../gio/gdbusauth.c:503 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" + +#: ../gio/gdbusauth.c:1159 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:266 +#, fuzzy, c-format +msgid "Error statting directory '%s': %s" +msgstr "דורכפֿ×ַל ×ין עפֿענען פּ×ַפּקע %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:278 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:299 +#, fuzzy, c-format +msgid "Error creating directory '%s': %s" +msgstr "דורכפֿ×ַל ×ין עפֿענען פּ×ַפּקע %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:382 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:406 ../gio/gdbusauthmechanismsha1.c:718 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:420 ../gio/gdbusauthmechanismsha1.c:732 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:435 ../gio/gdbusauthmechanismsha1.c:746 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:459 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "" + +#: ../gio/gdbusauthmechanismsha1.c:536 +#, fuzzy, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:568 +#, fuzzy, c-format +msgid "Error creating lock file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:598 +#, fuzzy, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:608 +#, fuzzy, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:685 +#, fuzzy, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusauthmechanismsha1.c:882 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "" + +#: ../gio/gdbusconnection.c:1150 ../gio/gdbusconnection.c:1376 +#: ../gio/gdbusconnection.c:1415 ../gio/gdbusconnection.c:1740 +msgid "The connection is closed" +msgstr "" + +#: ../gio/gdbusconnection.c:1684 +msgid "Timeout was reached" +msgstr "" + +#: ../gio/gdbusconnection.c:2306 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" + +#: ../gio/gdbusconnection.c:3770 ../gio/gdbusconnection.c:4086 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:3841 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3936 +#, c-format +msgid "No such property '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:3948 +#, c-format +msgid "Property '%s' is not readable" +msgstr "" + +#: ../gio/gdbusconnection.c:3959 +#, c-format +msgid "Property '%s' is not writable" +msgstr "" + +#: ../gio/gdbusconnection.c:4029 ../gio/gdbusconnection.c:5853 +#, c-format +msgid "No such interface '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4213 +msgid "No such interface" +msgstr "" + +#: ../gio/gdbusconnection.c:4432 ../gio/gdbusconnection.c:6359 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4484 +#, c-format +msgid "No such method '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4515 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:4734 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "" + +#: ../gio/gdbusconnection.c:4932 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "" + +#: ../gio/gdbusconnection.c:5964 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "" + +#: ../gio/gdbusconnection.c:6082 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "" + +#: ../gio/gdbusmessage.c:859 +msgid "type is INVALID" +msgstr "" + +#: ../gio/gdbusmessage.c:870 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:881 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:893 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:906 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "" + +#: ../gio/gdbusmessage.c:914 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" + +#: ../gio/gdbusmessage.c:922 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" + +#: ../gio/gdbusmessage.c:998 +#, c-format +msgid "Wanted to read %lu byte but got EOF" +msgid_plural "Wanted to read %lu bytes but got EOF" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1025 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:1038 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1242 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "" + +#: ../gio/gdbusmessage.c:1268 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1324 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1490 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "" + +#: ../gio/gdbusmessage.c:1517 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:1705 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "" + +#: ../gio/gdbusmessage.c:1719 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "" + +#: ../gio/gdbusmessage.c:1776 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "" + +#: ../gio/gdbusmessage.c:1790 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "" + +#: ../gio/gdbusmessage.c:1821 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "" +msgstr[1] "" + +#: ../gio/gdbusmessage.c:1831 +msgid "Cannot deserialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2163 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "" + +#: ../gio/gdbusmessage.c:2303 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "" + +#: ../gio/gdbusmessage.c:2311 +msgid "Cannot serialize message: " +msgstr "" + +#: ../gio/gdbusmessage.c:2355 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "" + +#: ../gio/gdbusmessage.c:2365 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is '" +"%s'" +msgstr "" + +#: ../gio/gdbusmessage.c:2381 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "" + +#: ../gio/gdbusmessage.c:2938 +#, fuzzy, c-format +msgid "Error return with body of type '%s'" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusmessage.c:2946 +msgid "Error return with empty body" +msgstr "" + +#: ../gio/gdbusprivate.c:1736 +msgid "Unable to load /var/lib/dbus/machine-id: " +msgstr "" + +#: ../gio/gdbusproxy.c:1489 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "" + +#: ../gio/gdbusproxy.c:1510 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "" + +#: ../gio/gdbusproxy.c:2600 ../gio/gdbusproxy.c:2734 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" + +#: ../gio/gdbusserver.c:711 +msgid "Abstract name space not supported" +msgstr "" + +#: ../gio/gdbusserver.c:798 +msgid "Cannot specify nonce file when creating a server" +msgstr "" + +#: ../gio/gdbusserver.c:875 +#, fuzzy, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbusserver.c:1042 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "" + +#: ../gio/gdbusserver.c:1082 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "" + +#: ../gio/gdbus-tool.c:88 +msgid "COMMAND" +msgstr "" + +#: ../gio/gdbus-tool.c:93 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:162 ../gio/gdbus-tool.c:218 ../gio/gdbus-tool.c:290 +#: ../gio/gdbus-tool.c:314 ../gio/gdbus-tool.c:691 ../gio/gdbus-tool.c:1010 +#: ../gio/gdbus-tool.c:1443 +#, fuzzy, c-format +msgid "Error: %s\n" +msgstr "דורכפֿ×ַל ××±×£ שורה %d: %s" + +#: ../gio/gdbus-tool.c:173 ../gio/gdbus-tool.c:231 ../gio/gdbus-tool.c:1459 +#, fuzzy, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/gdbus-tool.c:348 +msgid "Connect to the system bus" +msgstr "" + +#: ../gio/gdbus-tool.c:349 +msgid "Connect to the session bus" +msgstr "" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to given D-Bus address" +msgstr "" + +#: ../gio/gdbus-tool.c:360 +msgid "Connection Endpoint Options:" +msgstr "" + +#: ../gio/gdbus-tool.c:361 +msgid "Options specifying the connection endpoint" +msgstr "" + +#: ../gio/gdbus-tool.c:383 +#, c-format +msgid "No connection endpoint specified" +msgstr "" + +#: ../gio/gdbus-tool.c:393 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "" + +#: ../gio/gdbus-tool.c:463 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "" + +#: ../gio/gdbus-tool.c:472 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "" + +#: ../gio/gdbus-tool.c:534 +msgid "Optional destination for signal (unique name)" +msgstr "" + +#: ../gio/gdbus-tool.c:535 +msgid "Object path to emit signal on" +msgstr "" + +#: ../gio/gdbus-tool.c:536 +msgid "Signal and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:568 +msgid "Emit a signal." +msgstr "" + +#: ../gio/gdbus-tool.c:602 ../gio/gdbus-tool.c:822 ../gio/gdbus-tool.c:1549 +#: ../gio/gdbus-tool.c:1781 +#, fuzzy, c-format +msgid "Error connecting: %s\n" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gdbus-tool.c:614 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:619 ../gio/gdbus-tool.c:883 ../gio/gdbus-tool.c:1607 +#: ../gio/gdbus-tool.c:1840 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "" + +#: ../gio/gdbus-tool.c:625 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "" + +#: ../gio/gdbus-tool.c:634 +#, fuzzy, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "שריפֿטצײכן %s ××™×– ×ומלעקסיק ×ין מיטן פֿון ×ַן ×ײנסנ×ָמען" + +#: ../gio/gdbus-tool.c:640 +#, fuzzy, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "שריפֿטצײכן %s ××™×– ×ומלעקסיק ×ין מיטן פֿון ×ַן ×ײנסנ×ָמען" + +#: ../gio/gdbus-tool.c:646 +#, fuzzy, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "שריפֿטצײכן %s ××™×– ×ומלעקסיק ×ין מיטן פֿון ×ַן ×ײנסנ×ָמען" + +#: ../gio/gdbus-tool.c:669 ../gio/gdbus-tool.c:982 +#, fuzzy, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/gdbus-tool.c:698 +#, fuzzy, c-format +msgid "Error flushing connection: %s\n" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/gdbus-tool.c:725 +msgid "Destination name to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:726 +msgid "Object path to invoke method on" +msgstr "" + +#: ../gio/gdbus-tool.c:727 +msgid "Method and interface name" +msgstr "" + +#: ../gio/gdbus-tool.c:728 +msgid "Timeout in seconds" +msgstr "" + +#: ../gio/gdbus-tool.c:767 +msgid "Invoke a method on a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:842 ../gio/gdbus-tool.c:1568 ../gio/gdbus-tool.c:1800 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:863 ../gio/gdbus-tool.c:1587 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:898 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "" + +#: ../gio/gdbus-tool.c:909 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "" + +#: ../gio/gdbus-tool.c:974 +#, fuzzy, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "דורכפֿ×ַל ×ין עפֿענען פּ×ַפּקע %s: %s" + +#: ../gio/gdbus-tool.c:1406 +msgid "Destination name to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1407 +msgid "Object path to introspect" +msgstr "" + +#: ../gio/gdbus-tool.c:1408 +msgid "Print XML" +msgstr "" + +#: ../gio/gdbus-tool.c:1409 +msgid "Introspect children" +msgstr "" + +#: ../gio/gdbus-tool.c:1410 +msgid "Only print properties" +msgstr "" + +#: ../gio/gdbus-tool.c:1501 +msgid "Introspect a remote object." +msgstr "" + +#: ../gio/gdbus-tool.c:1699 +msgid "Destination name to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1700 +msgid "Object path to monitor" +msgstr "" + +#: ../gio/gdbus-tool.c:1733 +msgid "Monitor a remote object." +msgstr "" + +#: ../gio/gdesktopappinfo.c:572 ../gio/gwin32appinfo.c:221 +msgid "Unnamed" +msgstr "" + +#: ../gio/gdesktopappinfo.c:969 +msgid "Desktop file didn't specify Exec field" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1250 +msgid "Unable to find terminal required for application" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1515 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1519 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:1785 ../gio/gdesktopappinfo.c:1809 +msgid "Application information lacks an identifier" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2033 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "" + +#: ../gio/gdesktopappinfo.c:2149 +#, c-format +msgid "Custom definition for %s" +msgstr "" + +#: ../gio/gdrive.c:363 +msgid "drive doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:444 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gdrive.c:521 +msgid "drive doesn't implement polling for media" +msgstr "" + +#: ../gio/gdrive.c:728 +msgid "drive doesn't implement start" +msgstr "" + +#: ../gio/gdrive.c:831 +msgid "drive doesn't implement stop" +msgstr "" + +#: ../gio/gdummytlsbackend.c:168 ../gio/gdummytlsbackend.c:288 +#: ../gio/gdummytlsbackend.c:378 +msgid "TLS support is not available" +msgstr "" + +#: ../gio/gemblem.c:324 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "" + +#: ../gio/gemblem.c:334 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:368 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:378 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "" + +#: ../gio/gemblemedicon.c:401 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "" + +#: ../gio/gfile.c:871 ../gio/gfile.c:1102 ../gio/gfile.c:1237 +#: ../gio/gfile.c:1474 ../gio/gfile.c:1528 ../gio/gfile.c:1585 +#: ../gio/gfile.c:1668 ../gio/gfile.c:1723 ../gio/gfile.c:1783 +#: ../gio/gfile.c:1837 ../gio/gfile.c:3307 ../gio/gfile.c:3361 +#: ../gio/gfile.c:3493 ../gio/gfile.c:3534 ../gio/gfile.c:3864 +#: ../gio/gfile.c:4266 ../gio/gfile.c:4352 ../gio/gfile.c:4441 +#: ../gio/gfile.c:4539 ../gio/gfile.c:4626 ../gio/gfile.c:4720 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5308 ../gio/gfile.c:5373 +#: ../gio/gfile.c:6947 ../gio/gfile.c:7037 ../gio/gfile.c:7123 +#: ../gio/win32/gwinhttpfile.c:439 +msgid "Operation not supported" +msgstr "" + +#. Translators: This is an error message when trying to find the +#. * enclosing (user visible) mount of a file, but none exists. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1358 ../gio/glocalfile.c:1051 ../gio/glocalfile.c:1062 +#: ../gio/glocalfile.c:1075 +msgid "Containing mount does not exist" +msgstr "" + +#: ../gio/gfile.c:2411 ../gio/glocalfile.c:2256 +msgid "Can't copy over directory" +msgstr "" + +#: ../gio/gfile.c:2472 +msgid "Can't copy directory over directory" +msgstr "" + +#: ../gio/gfile.c:2480 ../gio/glocalfile.c:2265 +msgid "Target file exists" +msgstr "" + +#: ../gio/gfile.c:2498 +msgid "Can't recursively copy directory" +msgstr "" + +#: ../gio/gfile.c:2758 +msgid "Splice not supported" +msgstr "" + +#: ../gio/gfile.c:2762 +#, fuzzy, c-format +msgid "Error splicing file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gfile.c:2909 +msgid "Can't copy special file" +msgstr "" + +#: ../gio/gfile.c:3483 +msgid "Invalid symlink value given" +msgstr "" + +#: ../gio/gfile.c:3577 +msgid "Trash not supported" +msgstr "" + +#: ../gio/gfile.c:3626 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "" + +#: ../gio/gfile.c:6006 ../gio/gvolume.c:332 +msgid "volume doesn't implement mount" +msgstr "" + +#: ../gio/gfile.c:6117 +msgid "No application is registered as handling this file" +msgstr "" + +#: ../gio/gfileenumerator.c:205 +msgid "Enumerator is closed" +msgstr "" + +#: ../gio/gfileenumerator.c:212 ../gio/gfileenumerator.c:271 +#: ../gio/gfileenumerator.c:371 ../gio/gfileenumerator.c:480 +msgid "File enumerator has outstanding operation" +msgstr "" + +#: ../gio/gfileenumerator.c:361 ../gio/gfileenumerator.c:470 +msgid "File enumerator is already closed" +msgstr "" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "" + +#: ../gio/gfileinputstream.c:154 ../gio/gfileinputstream.c:420 +#: ../gio/gfileiostream.c:170 ../gio/gfileoutputstream.c:169 +#: ../gio/gfileoutputstream.c:523 +msgid "Stream doesn't support query_info" +msgstr "" + +#: ../gio/gfileinputstream.c:335 ../gio/gfileiostream.c:387 +#: ../gio/gfileoutputstream.c:381 +msgid "Seek not supported on stream" +msgstr "" + +#: ../gio/gfileinputstream.c:379 +msgid "Truncate not allowed on input stream" +msgstr "" + +#: ../gio/gfileiostream.c:463 ../gio/gfileoutputstream.c:457 +msgid "Truncate not supported on stream" +msgstr "" + +#: ../gio/gicon.c:284 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "" + +#: ../gio/gicon.c:304 +#, c-format +msgid "No type for class name %s" +msgstr "" + +#: ../gio/gicon.c:314 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:325 +#, c-format +msgid "Type %s is not classed" +msgstr "" + +#: ../gio/gicon.c:339 +#, c-format +msgid "Malformed version number: %s" +msgstr "" + +#: ../gio/gicon.c:353 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "" + +#: ../gio/gicon.c:430 +msgid "Can't handle the supplied version the icon encoding" +msgstr "" + +#: ../gio/ginputstream.c:194 +msgid "Input stream doesn't implement read" +msgstr "" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:898 ../gio/giostream.c:316 +#: ../gio/goutputstream.c:1216 +msgid "Stream has outstanding operation" +msgstr "" + +#: ../gio/ginetsocketaddress.c:181 ../gio/ginetsocketaddress.c:198 +#: ../gio/gunixsocketaddress.c:221 +msgid "Not enough space for socket address" +msgstr "" + +#: ../gio/ginetsocketaddress.c:211 +msgid "Unsupported socket address" +msgstr "" + +#: ../gio/glib-compile-schemas.c:741 +msgid "empty names are not permitted" +msgstr "" + +#: ../gio/glib-compile-schemas.c:751 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "" + +#: ../gio/glib-compile-schemas.c:763 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and dash ('-') are permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:772 +#, c-format +msgid "invalid name '%s': two successive dashes ('--') are not permitted." +msgstr "" + +#: ../gio/glib-compile-schemas.c:781 +#, c-format +msgid "invalid name '%s': the last character may not be a dash ('-')." +msgstr "" + +#: ../gio/glib-compile-schemas.c:789 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "" + +#: ../gio/glib-compile-schemas.c:858 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:884 +msgid "can not add keys to a 'list-of' schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:895 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:913 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" + +#: ../gio/glib-compile-schemas.c:924 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "" + +#: ../gio/glib-compile-schemas.c:943 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "" + +#: ../gio/glib-compile-schemas.c:958 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:988 +msgid " given but schema isn't extending anything" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1001 +#, c-format +msgid "no to override" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1009 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1080 +#, c-format +msgid " already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1092 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1108 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1116 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1126 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1136 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1146 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1163 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1170 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1196 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1416 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1420 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1511 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1696 ../gio/glib-compile-schemas.c:1767 +#: ../gio/glib-compile-schemas.c:1843 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1704 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1763 +#, c-format +msgid "Ignoring this file.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1803 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1809 ../gio/glib-compile-schemas.c:1867 +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1813 ../gio/glib-compile-schemas.c:1871 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1829 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': " +"%s. " +msgstr "" + +#: ../gio/glib-compile-schemas.c:1839 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1857 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is out of the " +"range given in the schema" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 +msgid "where to store the gschemas.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1939 ../gio/glib-compile-schemas.c:1970 +msgid "DIRECTORY" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1940 +msgid "Abort on any errors in schemas" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1941 +msgid "Do not write the gschema.compiled file" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1942 +msgid "This option will be removed soon." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1943 +msgid "Do not enforce key name restrictions" +msgstr "" + +#: ../gio/glib-compile-schemas.c:1973 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" + +#: ../gio/glib-compile-schemas.c:1989 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2028 +#, c-format +msgid "No schema files found: " +msgstr "" + +#: ../gio/glib-compile-schemas.c:2031 +#, c-format +msgid "doing nothing.\n" +msgstr "" + +#: ../gio/glib-compile-schemas.c:2034 +#, c-format +msgid "removed existing output file.\n" +msgstr "" + +#: ../gio/glocaldirectorymonitor.c:287 +msgid "Unable to find default local directory monitor type" +msgstr "" + +#: ../gio/glocalfile.c:571 ../gio/win32/gwinhttpfile.c:422 +#, fuzzy, c-format +msgid "Invalid filename %s" +msgstr "×ומלעקסיקער מ×ַשין־נ×ָמען" + +#: ../gio/glocalfile.c:948 +#, fuzzy, c-format +msgid "Error getting filesystem info: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfile.c:1097 +msgid "Can't rename root directory" +msgstr "" + +#: ../gio/glocalfile.c:1117 ../gio/glocalfile.c:1143 +#, fuzzy, c-format +msgid "Error renaming file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfile.c:1126 +msgid "Can't rename file, filename already exists" +msgstr "" + +#: ../gio/glocalfile.c:1139 ../gio/glocalfile.c:2129 ../gio/glocalfile.c:2158 +#: ../gio/glocalfile.c:2318 ../gio/glocalfileoutputstream.c:571 +#: ../gio/glocalfileoutputstream.c:624 ../gio/glocalfileoutputstream.c:669 +#: ../gio/glocalfileoutputstream.c:1157 +#, fuzzy +msgid "Invalid filename" +msgstr "×ומלעקסיקער מ×ַשין־נ×ָמען" + +#: ../gio/glocalfile.c:1300 +#, fuzzy, c-format +msgid "Error opening file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfile.c:1316 +msgid "Can't open directory" +msgstr "" + +#: ../gio/glocalfile.c:1441 +#, fuzzy, c-format +msgid "Error removing file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfile.c:1808 +#, fuzzy, c-format +msgid "Error trashing file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfile.c:1831 +#, fuzzy, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../gio/glocalfile.c:1852 +msgid "Unable to find toplevel directory for trash" +msgstr "" + +#: ../gio/glocalfile.c:1931 ../gio/glocalfile.c:1951 +msgid "Unable to find or create trash directory" +msgstr "" + +#: ../gio/glocalfile.c:1985 +#, fuzzy, c-format +msgid "Unable to create trashing info file: %s" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../gio/glocalfile.c:2014 ../gio/glocalfile.c:2019 ../gio/glocalfile.c:2099 +#: ../gio/glocalfile.c:2106 +#, fuzzy, c-format +msgid "Unable to trash file: %s" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../gio/glocalfile.c:2133 +#, fuzzy, c-format +msgid "Error creating directory: %s" +msgstr "דורכפֿ×ַל ×ין עפֿענען פּ×ַפּקע %s: %s" + +#: ../gio/glocalfile.c:2162 +#, fuzzy, c-format +msgid "Filesystem does not support symbolic links" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../gio/glocalfile.c:2166 +#, fuzzy, c-format +msgid "Error making symbolic link: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/glocalfile.c:2228 ../gio/glocalfile.c:2322 +#, fuzzy, c-format +msgid "Error moving file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfile.c:2251 +msgid "Can't move directory over directory" +msgstr "" + +#: ../gio/glocalfile.c:2278 ../gio/glocalfileoutputstream.c:955 +#: ../gio/glocalfileoutputstream.c:969 ../gio/glocalfileoutputstream.c:984 +#: ../gio/glocalfileoutputstream.c:1000 ../gio/glocalfileoutputstream.c:1014 +msgid "Backup file creation failed" +msgstr "" + +#: ../gio/glocalfile.c:2297 +#, fuzzy, c-format +msgid "Error removing target file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfile.c:2311 +msgid "Move between mounts not supported" +msgstr "" + +#: ../gio/glocalfileinfo.c:719 +msgid "Attribute value must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:726 +msgid "Invalid attribute type (string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:733 +#, fuzzy +msgid "Invalid extended attribute name" +msgstr "ד×ָקומענט ענדיקט זיך ×ומגעריכטערהײט ×ין דרינען פֿון ×ַן ×ַטריבוט־נ×ָמען" + +#: ../gio/glocalfileinfo.c:773 +#, fuzzy, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "דורכפֿ×ַל ×ין עפֿענען פּ×ַפּקע %s: %s" + +#: ../gio/glocalfileinfo.c:1482 ../gio/glocalfileoutputstream.c:833 +#, fuzzy, c-format +msgid "Error stating file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileinfo.c:1566 +msgid " (invalid encoding)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1768 +#, fuzzy, c-format +msgid "Error stating file descriptor: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileinfo.c:1813 +msgid "Invalid attribute type (uint32 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1831 +msgid "Invalid attribute type (uint64 expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1850 ../gio/glocalfileinfo.c:1869 +msgid "Invalid attribute type (byte string expected)" +msgstr "" + +#: ../gio/glocalfileinfo.c:1904 +#, fuzzy +msgid "Cannot set permissions on symlinks" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/glocalfileinfo.c:1920 +#, fuzzy, c-format +msgid "Error setting permissions: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/glocalfileinfo.c:1971 +#, fuzzy, c-format +msgid "Error setting owner: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/glocalfileinfo.c:1994 +msgid "symlink must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2004 ../gio/glocalfileinfo.c:2023 +#: ../gio/glocalfileinfo.c:2034 +#, fuzzy, c-format +msgid "Error setting symlink: %s" +msgstr "דורכפֿ×ַל ××±×£ שורה %d: %s" + +#: ../gio/glocalfileinfo.c:2013 +msgid "Error setting symlink: file is not a symlink" +msgstr "" + +#: ../gio/glocalfileinfo.c:2139 +#, fuzzy, c-format +msgid "Error setting modification or access time: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/glocalfileinfo.c:2162 +msgid "SELinux context must be non-NULL" +msgstr "" + +#: ../gio/glocalfileinfo.c:2177 +#, fuzzy, c-format +msgid "Error setting SELinux context: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/glocalfileinfo.c:2184 +msgid "SELinux is not enabled on this system" +msgstr "" + +#: ../gio/glocalfileinfo.c:2276 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "" + +#: ../gio/glocalfileinputstream.c:185 ../gio/glocalfileoutputstream.c:722 +#, fuzzy, c-format +msgid "Error reading from file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileinputstream.c:216 ../gio/glocalfileinputstream.c:228 +#: ../gio/glocalfileinputstream.c:340 ../gio/glocalfileoutputstream.c:470 +#: ../gio/glocalfileoutputstream.c:1032 +#, fuzzy, c-format +msgid "Error seeking in file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileinputstream.c:261 ../gio/glocalfileoutputstream.c:256 +#: ../gio/glocalfileoutputstream.c:351 +#, fuzzy, c-format +msgid "Error closing file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfilemonitor.c:212 +msgid "Unable to find default local file monitor type" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:202 ../gio/glocalfileoutputstream.c:235 +#: ../gio/glocalfileoutputstream.c:743 +#, fuzzy, c-format +msgid "Error writing to file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileoutputstream.c:283 +#, fuzzy, c-format +msgid "Error removing old backup link: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/glocalfileoutputstream.c:297 ../gio/glocalfileoutputstream.c:310 +#, fuzzy, c-format +msgid "Error creating backup copy: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileoutputstream.c:328 +#, fuzzy, c-format +msgid "Error renaming temporary file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileoutputstream.c:516 ../gio/glocalfileoutputstream.c:1083 +#, fuzzy, c-format +msgid "Error truncating file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileoutputstream.c:577 ../gio/glocalfileoutputstream.c:630 +#: ../gio/glocalfileoutputstream.c:675 ../gio/glocalfileoutputstream.c:815 +#: ../gio/glocalfileoutputstream.c:1064 ../gio/glocalfileoutputstream.c:1163 +#, fuzzy, c-format +msgid "Error opening file '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/glocalfileoutputstream.c:846 +msgid "Target file is a directory" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:851 +msgid "Target file is not a regular file" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:863 +msgid "The file was externally modified" +msgstr "" + +#: ../gio/glocalfileoutputstream.c:1048 +#, fuzzy, c-format +msgid "Error removing old file: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gmemoryinputstream.c:486 ../gio/gmemoryoutputstream.c:746 +msgid "Invalid GSeekType supplied" +msgstr "" + +#: ../gio/gmemoryinputstream.c:496 +#, fuzzy +msgid "Invalid seek request" +msgstr "×ומלעקסיקער מ×ַשין־נ×ָמען" + +#: ../gio/gmemoryinputstream.c:520 +msgid "Cannot truncate GMemoryInputStream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:496 +msgid "Memory output stream not resizable" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:512 +msgid "Failed to resize memory output stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:600 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:756 +msgid "Requested seek before the beginning of the stream" +msgstr "" + +#: ../gio/gmemoryoutputstream.c:765 +msgid "Requested seek beyond the end of the stream" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:363 +msgid "mount doesn't implement \"unmount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:442 +msgid "mount doesn't implement \"eject\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:523 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:611 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:701 +msgid "mount doesn't implement \"remount\"" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:785 +msgid "mount doesn't implement content type guessing" +msgstr "" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:874 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "" + +#: ../gio/gnetworkaddress.c:322 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "" + +#: ../gio/goutputstream.c:207 ../gio/goutputstream.c:411 +msgid "Output stream doesn't implement write" +msgstr "" + +#: ../gio/goutputstream.c:372 ../gio/goutputstream.c:855 +msgid "Source stream is already closed" +msgstr "" + +#: ../gio/gresolver.c:779 +#, fuzzy, c-format +msgid "Error resolving '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gresolver.c:829 +#, fuzzy, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gresolver.c:864 ../gio/gresolver.c:943 +#, c-format +msgid "No service record for '%s'" +msgstr "" + +#: ../gio/gresolver.c:869 ../gio/gresolver.c:948 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "" + +#: ../gio/gresolver.c:874 ../gio/gresolver.c:953 +#, fuzzy, c-format +msgid "Error resolving '%s'" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsettings-tool.c:60 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:65 ../gio/gsettings-tool.c:82 +#, c-format +msgid "No such schema '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:77 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "" + +#: ../gio/gsettings-tool.c:131 +#, c-format +msgid "No such key '%s'\n" +msgstr "" + +#: ../gio/gsettings-tool.c:504 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "" + +#: ../gio/gsettings-tool.c:533 +msgid "Print help" +msgstr "" + +#: ../gio/gsettings-tool.c:539 +msgid "List the installed (non-relocatable) schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:545 +msgid "List the installed relocatable schemas" +msgstr "" + +#: ../gio/gsettings-tool.c:551 +msgid "List the keys in SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:595 +msgid "SCHEMA[:PATH]" +msgstr "" + +#: ../gio/gsettings-tool.c:557 +msgid "List the children of SCHEMA" +msgstr "" + +#: ../gio/gsettings-tool.c:563 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" + +#: ../gio/gsettings-tool.c:565 +msgid "[SCHEMA[:PATH]]" +msgstr "" + +#: ../gio/gsettings-tool.c:570 +msgid "Get the value of KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:571 ../gio/gsettings-tool.c:577 +#: ../gio/gsettings-tool.c:589 ../gio/gsettings-tool.c:601 +msgid "SCHEMA[:PATH] KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:576 +msgid "Query the range of valid values for KEY" +msgstr "" + +#: ../gio/gsettings-tool.c:582 +msgid "Set the value of KEY to VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:583 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "" + +#: ../gio/gsettings-tool.c:588 +msgid "Reset KEY to its default value" +msgstr "" + +#: ../gio/gsettings-tool.c:594 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "" + +#: ../gio/gsettings-tool.c:600 +msgid "Check if KEY is writable" +msgstr "" + +#: ../gio/gsettings-tool.c:606 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" + +#: ../gio/gsettings-tool.c:609 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "" + +#: ../gio/gsettings-tool.c:613 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:621 +msgid "" +"Usage:\n" +" gsettings COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:643 +#, c-format +msgid "" +"Usage:\n" +" gsettings %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" + +#: ../gio/gsettings-tool.c:648 +msgid "Arguments:\n" +msgstr "" + +#: ../gio/gsettings-tool.c:652 +msgid " COMMAND The (optional) command to explain\n" +msgstr "" + +#: ../gio/gsettings-tool.c:656 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" + +#: ../gio/gsettings-tool.c:661 +msgid " KEY The (optional) key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:665 +msgid " KEY The key within the schema\n" +msgstr "" + +#: ../gio/gsettings-tool.c:669 +msgid " VALUE The value to set\n" +msgstr "" + +#: ../gio/gsettings-tool.c:766 +#, c-format +msgid "Empty schema name given\n" +msgstr "" + +#: ../gio/gsocket.c:275 +msgid "Invalid socket, not initialized" +msgstr "" + +#: ../gio/gsocket.c:282 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "" + +#: ../gio/gsocket.c:290 +msgid "Socket is already closed" +msgstr "" + +#: ../gio/gsocket.c:298 ../gio/gsocket.c:2798 ../gio/gsocket.c:2842 +msgid "Socket I/O timed out" +msgstr "" + +#: ../gio/gsocket.c:464 +#, fuzzy, c-format +msgid "creating GSocket from fd: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:498 ../gio/gsocket.c:514 +#, fuzzy, c-format +msgid "Unable to create socket: %s" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../gio/gsocket.c:498 +msgid "Unknown protocol was specified" +msgstr "" + +#: ../gio/gsocket.c:1268 +#, c-format +msgid "could not get local address: %s" +msgstr "" + +#: ../gio/gsocket.c:1311 +#, fuzzy, c-format +msgid "could not get remote address: %s" +msgstr "ניט געקענט ×ױסטײלן %lu ×ַכטעלעך צו לײענען טעקע %s" + +#: ../gio/gsocket.c:1372 +#, c-format +msgid "could not listen: %s" +msgstr "" + +#: ../gio/gsocket.c:1446 +#, fuzzy, c-format +msgid "Error binding to address: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:1566 +#, fuzzy, c-format +msgid "Error accepting connection: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/gsocket.c:1683 +#, fuzzy +msgid "Error connecting: " +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:1688 +msgid "Connection in progress" +msgstr "" + +#: ../gio/gsocket.c:1695 +#, fuzzy, c-format +msgid "Error connecting: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:1738 ../gio/gsocket.c:3579 +#, fuzzy, c-format +msgid "Unable to get pending error: %s" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../gio/gsocket.c:1875 +#, fuzzy, c-format +msgid "Error receiving data: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:2050 +#, fuzzy, c-format +msgid "Error sending data: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:2163 +#, fuzzy, c-format +msgid "Unable to shutdown socket: %s" +msgstr "ניט געקענט ש×ַפֿן טעקע %s: %s" + +#: ../gio/gsocket.c:2242 +#, fuzzy, c-format +msgid "Error closing socket: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:2791 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "" + +#: ../gio/gsocket.c:3056 ../gio/gsocket.c:3137 +#, fuzzy, c-format +msgid "Error sending message: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:3081 +msgid "GSocketControlMessage not supported on windows" +msgstr "" + +#: ../gio/gsocket.c:3358 ../gio/gsocket.c:3494 +#, fuzzy, c-format +msgid "Error receiving message: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gsocket.c:3598 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "" + +#: ../gio/gsocketclient.c:798 ../gio/gsocketclient.c:1368 +msgid "Unknown error on connect" +msgstr "" + +#: ../gio/gsocketclient.c:836 ../gio/gsocketclient.c:1252 +msgid "Trying to proxy over non-TCP connection is not supported." +msgstr "" + +#: ../gio/gsocketclient.c:858 ../gio/gsocketclient.c:1277 +#, fuzzy, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "פֿ×ַרװ×ַנדלונג פֿון ×§×ָדירונג %s צו %s ניט געשטיצט" + +#: ../gio/gsocketlistener.c:191 +msgid "Listener is already closed" +msgstr "" + +#: ../gio/gsocketlistener.c:232 +msgid "Added socket is closed" +msgstr "" + +#: ../gio/gsocks4aproxy.c:121 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "" + +#: ../gio/gsocks4aproxy.c:139 +#, c-format +msgid "SOCKSv4 implementation limits username to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:157 +#, c-format +msgid "SOCKSv4a implementation limits hostname to %i characters" +msgstr "" + +#: ../gio/gsocks4aproxy.c:183 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "" + +#: ../gio/gsocks4aproxy.c:190 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "" + +#: ../gio/gsocks5proxy.c:155 ../gio/gsocks5proxy.c:328 +#: ../gio/gsocks5proxy.c:338 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "" + +#: ../gio/gsocks5proxy.c:169 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "" + +#: ../gio/gsocks5proxy.c:179 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "" + +#: ../gio/gsocks5proxy.c:208 +#, c-format +msgid "Username or password is too long for SOCKSv5 protocol (max. is %i)." +msgstr "" + +#: ../gio/gsocks5proxy.c:239 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "" + +#: ../gio/gsocks5proxy.c:289 +#, c-format +msgid "Hostname '%s' too long for SOCKSv5 protocol (maximum is %i bytes)" +msgstr "" + +#: ../gio/gsocks5proxy.c:352 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:359 +msgid "Internal SOCKSv5 proxy server error." +msgstr "" + +#: ../gio/gsocks5proxy.c:365 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "" + +#: ../gio/gsocks5proxy.c:372 +msgid "Host unreachable through SOCKSv5 server." +msgstr "" + +#: ../gio/gsocks5proxy.c:378 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:384 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "" + +#: ../gio/gsocks5proxy.c:390 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "" + +#: ../gio/gsocks5proxy.c:396 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "" + +#: ../gio/gsocks5proxy.c:402 +msgid "Unknown SOCKSv5 proxy error." +msgstr "" + +#: ../gio/gthemedicon.c:498 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "" + +#: ../gio/gtlscertificate.c:226 +msgid "No PEM-encoded private key found" +msgstr "" + +#: ../gio/gtlscertificate.c:235 +msgid "Could not parse PEM-encoded private key" +msgstr "" + +#: ../gio/gtlscertificate.c:260 +msgid "No PEM-encoded certificate found" +msgstr "" + +#: ../gio/gtlscertificate.c:269 +msgid "Could not parse PEM-encoded certificate" +msgstr "" + +#: ../gio/gtlspassword.c:114 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" + +#: ../gio/gtlspassword.c:116 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "" + +#: ../gio/gtlspassword.c:118 +msgid "The password entered is incorrect." +msgstr "" + +#: ../gio/gunixconnection.c:164 ../gio/gunixconnection.c:521 +#, c-format +msgid "Expecting 1 control message, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:177 ../gio/gunixconnection.c:531 +msgid "Unexpected type of ancillary data" +msgstr "" + +#: ../gio/gunixconnection.c:195 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgstr "" + +#: ../gio/gunixconnection.c:211 +msgid "Received invalid fd" +msgstr "" + +#: ../gio/gunixconnection.c:371 +#, fuzzy +msgid "Error sending credentials: " +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gunixconnection.c:452 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "" + +#: ../gio/gunixconnection.c:461 +#, c-format +msgid "" +"Unexpected option length while checking if SO_PASSCRED is enabled for " +"socket. Expected %d bytes, got %d" +msgstr "" + +#: ../gio/gunixconnection.c:478 +#, fuzzy, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gunixconnection.c:509 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" + +#: ../gio/gunixconnection.c:545 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "" + +#: ../gio/gunixconnection.c:571 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "" + +#: ../gio/gunixinputstream.c:368 ../gio/gunixinputstream.c:388 +#: ../gio/gunixinputstream.c:466 +#, fuzzy, c-format +msgid "Error reading from unix: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gunixinputstream.c:421 ../gio/gunixinputstream.c:601 +#: ../gio/gunixoutputstream.c:407 ../gio/gunixoutputstream.c:556 +#, fuzzy, c-format +msgid "Error closing unix: %s" +msgstr "דורכפֿ×ַל ××±×£ שורה %d: %s" + +#: ../gio/gunixmounts.c:1900 ../gio/gunixmounts.c:1937 +msgid "Filesystem root" +msgstr "" + +#: ../gio/gunixoutputstream.c:353 ../gio/gunixoutputstream.c:374 +#: ../gio/gunixoutputstream.c:452 +#, fuzzy, c-format +msgid "Error writing to unix: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/gunixsocketaddress.c:244 +msgid "Abstract unix domain socket addresses not supported on this system" +msgstr "" + +#: ../gio/gvolume.c:408 +msgid "volume doesn't implement eject" +msgstr "" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:488 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "" + +#: ../gio/gwin32appinfo.c:276 +msgid "Can't find application" +msgstr "" + +#: ../gio/gwin32appinfo.c:299 +#, fuzzy, c-format +msgid "Error launching application: %s" +msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#: ../gio/gwin32appinfo.c:335 +msgid "URIs not supported" +msgstr "" + +#: ../gio/gwin32appinfo.c:357 +msgid "association changes not supported on win32" +msgstr "" + +#: ../gio/gwin32appinfo.c:369 +msgid "Association creation not supported on win32" +msgstr "" + +#: ../gio/gwin32inputstream.c:318 +#, fuzzy, c-format +msgid "Error reading from handle: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gwin32inputstream.c:348 ../gio/gwin32outputstream.c:348 +#, fuzzy, c-format +msgid "Error closing handle: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gwin32outputstream.c:318 +#, fuzzy, c-format +msgid "Error writing to handle: %s" +msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#: ../gio/gzlibcompressor.c:396 ../gio/gzlibdecompressor.c:349 +msgid "Not enough memory" +msgstr "" + +#: ../gio/gzlibcompressor.c:403 ../gio/gzlibdecompressor.c:356 +#, c-format +msgid "Internal error: %s" +msgstr "" + +#: ../gio/gzlibcompressor.c:416 ../gio/gzlibdecompressor.c:370 +msgid "Need more input" +msgstr "" + +#: ../gio/gzlibdecompressor.c:342 +#, fuzzy +msgid "Invalid compressed data" +msgstr "×ומלעקסיקער מ×ַשין־נ×ָמען" + +#, fuzzy +#~ msgid "Invalid UTF-8 sequence in input" +#~ msgstr "×ומלעקסיקער סעקװענץ ×ין פֿ×ַרװ×ַנדל־×ַרײַנשרײַב" + +#~ msgid "" +#~ "Character '%s' is not valid at the start of an entity name; the & " +#~ "character begins an entity; if this ampersand isn't supposed to be an " +#~ "entity, escape it as &" +#~ msgstr "" +#~ "שריפֿטצײכן %s ××™×– ניט לעקסיק ×¦×•× ×ָנהײב פֿון ×ַן ×ײנסנ×ָמען; דער & שריפֿטצײכן " +#~ "הײבט ×ַן ×ײנס ×ָן; ×ױב מיט ×“×¢× ×“×ָזיקן & מײנט מען ניט קײן ×ײנס, × ×ָרמ×ַליר ××™× " +#~ "×°×™ &" + +#~ msgid "Empty character reference; should include a digit such as dž" +#~ msgstr "נוליקע שריפֿטצײכן־רעפֿערענץ; מוז כּולל זײַן ×Ö· ציפֿער, ×°×™ dž" + +#~ msgid "Unfinished entity reference" +#~ msgstr "ניט־געענדיקט ×ײנס־רעפֿערענץ" + +#~ msgid "Unfinished character reference" +#~ msgstr "ניט־געענדיקט שריפֿטצײכן־רעפֿערענץ" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - overlong sequence" +#~ msgstr "×ומלעקסיק UTFÖ¾8 ×§×ָדירטער טעקסט" + +#, fuzzy +#~ msgid "Invalid UTF-8 encoded text - not a start char" +#~ msgstr "×ומלעקסיק UTFÖ¾8 ×§×ָדירטער טעקסט" + +#, fuzzy +#~ msgid "The file containing the icon" +#~ msgstr "דער מ×ַשין־נ×ָמען ×¤Ö¿×•× ×¢× URI %s ××™×– ×ומלעקסיק" + +#, fuzzy +#~ msgid "The name of the icon" +#~ msgstr "דער מ×ַשין־נ×ָמען ×¤Ö¿×•× ×¢× URI %s ××™×– ×ומלעקסיק" + +#, fuzzy +#~ msgid "Close file descriptor" +#~ msgstr "דורכפֿ×ַל ×ין לײענען טעקע %s: %s" + +#, fuzzy +#~ msgid "Error creating backup link: %s" +#~ msgstr "דורכפֿ×ַל בשעת פֿ×ַרװ×ַנדלונג: %s" + +#, fuzzy +#~ msgid "Could not change file mode: fork() failed: %s" +#~ msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#, fuzzy +#~ msgid "Could not change file mode: chmod() failed: %s" +#~ msgstr "ניט געקענט עפֿענען טעקע %s: fdopen() ××™×– דורכגעפֿ×ַלן: %s" + +#~ msgid "Incorrect message size" +#~ msgstr "ניט־ריכטיקע ×ָנז×ָגגרײס" + +#~ msgid "Socket error" +#~ msgstr "ס×ָקעט־דורכפֿ×ַל" diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..4fc0b68 --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,6358 @@ +# Simplified Chinese translation for glib. +# Copyright (C) 2001-2021 glib's COPYRIGHT HOLDER +# This file is distributed under the same license as glib package. +# He Qiangqiang , 2001. +# Funda Wang , 2004, 2005. +# yetist , 2007. +# Deng Xiyue , 2008, 2009. +# Aron Xu , 2009, 2010. +# Dark Blue , 2010. +# Tao Wang , 2010. +# Aron Xu , 2010. +# wei Li , 2011. +# Lele Long , 2011. +# Mike Manilone , 2012. +# keyring , 2013. +# Tong Hui , 2014. +# Mingye Wang , 2015, 2016. +# Mingcong Bai , 2015, 2016, 2018. +# Dingzhong Chen , 2018-2021. +# lumingzh , 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2022-02-14 13:48+0000\n" +"PO-Revision-Date: 2022-02-15 19:09+0800\n" +"Last-Translator: lumingzh \n" +"Language-Team: Chinese - China \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: Gtranslator 41.0\n" + +#: gio/gappinfo.c:333 +msgid "Setting default applications not supported yet" +msgstr "æš‚ä¸æ”¯æŒè®¾ç½®é»˜è®¤åº”用程åº" + +#: gio/gappinfo.c:366 +msgid "Setting application as last used for type not supported yet" +msgstr "æš‚ä¸æ”¯æŒè®¾ç½®ä¸Šæ¬¡ç”¨æ¥æ‰“开文件类型的应用程åº" + +#: gio/gapplication.c:497 +msgid "GApplication options" +msgstr "GApplication 选项" + +#: gio/gapplication.c:497 +msgid "Show GApplication options" +msgstr "显示 GApplication 选项" + +#: gio/gapplication.c:542 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "进入 GApplication æœåŠ¡æ¨¡å¼ï¼ˆä»Ž D-Bus æœåŠ¡æ–‡ä»¶ä¸­è°ƒç”¨ï¼‰" + +#: gio/gapplication.c:554 +msgid "Override the application’s ID" +msgstr "è¦†ç›–åº”ç”¨ç¨‹åº ID" + +#: gio/gapplication.c:566 +msgid "Replace the running instance" +msgstr "替代è¿è¡Œä¸­çš„实例" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:494 gio/gsettings-tool.c:584 +msgid "Print help" +msgstr "打å°å¸®åŠ©" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:495 gio/gresource-tool.c:563 +msgid "[COMMAND]" +msgstr "[命令]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "打å°ç‰ˆæœ¬" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:590 +msgid "Print version information and exit" +msgstr "打å°ç‰ˆæœ¬ä¿¡æ¯å¹¶é€€å‡º" + +#: gio/gapplication-tool.c:53 +msgid "List applications" +msgstr "列出应用程åº" + +#: gio/gapplication-tool.c:54 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "列出已安装的 D-Bus å¯ä»¥æ¿€æ´»çš„应用程åºï¼ˆæ ¹æ® .desktop文件)" + +#: gio/gapplication-tool.c:57 +msgid "Launch an application" +msgstr "å¯åŠ¨ä¸€ä¸ªåº”ç”¨ç¨‹åº" + +#: gio/gapplication-tool.c:58 +msgid "Launch the application (with optional files to open)" +msgstr "å¯åŠ¨åº”ç”¨ç¨‹åºï¼ˆå¯é€‰æ‰“开文件)" + +#: gio/gapplication-tool.c:59 +msgid "APPID [FILE…]" +msgstr "应用ID [文件…]" + +#: gio/gapplication-tool.c:61 +msgid "Activate an action" +msgstr "激活一个æ“作" + +#: gio/gapplication-tool.c:62 +msgid "Invoke an action on the application" +msgstr "在应用程åºä¸Šè°ƒç”¨ä¸€ä¸ªæ“作" + +#: gio/gapplication-tool.c:63 +msgid "APPID ACTION [PARAMETER]" +msgstr "应用ID æ“作 [傿•°]" + +#: gio/gapplication-tool.c:65 +msgid "List available actions" +msgstr "列出å¯ç”¨çš„æ“ä½œ" + +#: gio/gapplication-tool.c:66 +msgid "List static actions for an application (from .desktop file)" +msgstr "列出一个应用程åºçš„陿€æ“作(æ¥è‡ª .desktop 文件)" + +#: gio/gapplication-tool.c:67 gio/gapplication-tool.c:73 +msgid "APPID" +msgstr "应用ID" + +#: gio/gapplication-tool.c:72 gio/gapplication-tool.c:135 gio/gdbus-tool.c:106 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "命令" + +#: gio/gapplication-tool.c:72 +msgid "The command to print detailed help for" +msgstr "è¦æ‰“å°å…¶è¯¦ç»†å¸®åŠ©çš„å‘½ä»¤" + +#: gio/gapplication-tool.c:73 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus æ ¼å¼çš„åº”ç”¨ç¨‹åºæ ‡è¯†ç¬¦ï¼ˆæ¯”如:org.example.viewer)" + +#: gio/gapplication-tool.c:74 gio/glib-compile-resources.c:820 +#: gio/glib-compile-resources.c:826 gio/glib-compile-resources.c:855 +#: gio/gresource-tool.c:501 gio/gresource-tool.c:567 +msgid "FILE" +msgstr "文件" + +#: gio/gapplication-tool.c:74 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "å¯é€‰è¦æ‰“开的相对或ç»å¯¹æ–‡ä»¶å或 URI" + +#: gio/gapplication-tool.c:75 +msgid "ACTION" +msgstr "æ“作" + +#: gio/gapplication-tool.c:75 +msgid "The action name to invoke" +msgstr "è¦è°ƒç”¨çš„æ“ä½œåç§°" + +#: gio/gapplication-tool.c:76 +msgid "PARAMETER" +msgstr "傿•°" + +#: gio/gapplication-tool.c:76 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "å¯é€‰çš„æ“ä½œè°ƒç”¨å‚æ•°ï¼ŒGVariant æ ¼å¼" + +#: gio/gapplication-tool.c:98 gio/gresource-tool.c:532 gio/gsettings-tool.c:676 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"未知命令 %s\n" +"\n" + +#: gio/gapplication-tool.c:103 +msgid "Usage:\n" +msgstr "用法:\n" + +#: gio/gapplication-tool.c:116 gio/gresource-tool.c:557 +#: gio/gsettings-tool.c:711 +msgid "Arguments:\n" +msgstr "傿•°ï¼š\n" + +#: gio/gapplication-tool.c:135 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[傿•°â€¦]" + +#: gio/gapplication-tool.c:136 +#, c-format +msgid "Commands:\n" +msgstr "命令:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:148 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"使用“%s help 命令â€èŽ·å–详细帮助。\n" +"\n" + +#: gio/gapplication-tool.c:167 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s 命令需è¦ç›´æŽ¥è·Ÿä¸€ä¸ªåº”ç”¨ç¨‹åº ID\n" +"\n" + +#: gio/gapplication-tool.c:173 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "æ— æ•ˆçš„åº”ç”¨ç¨‹åº ID:“%sâ€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:184 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"“%sâ€ä¸æŽ¥å—傿•°\n" +"\n" + +#: gio/gapplication-tool.c:268 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "无法连接到 D-Bus:%s\n" + +#: gio/gapplication-tool.c:288 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "给应用程åºå‘é€ %s æ¶ˆæ¯æ—¶å‡ºé”™ï¼š%s\n" + +#: gio/gapplication-tool.c:319 +msgid "action name must be given after application id\n" +msgstr "æ“作åå¿…é¡»åœ¨åº”ç”¨ç¨‹åº ID åŽç»™å‡º\n" + +#: gio/gapplication-tool.c:327 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"无效的æ“作å:“%sâ€\n" +"æ“作ååªèƒ½ç”±å­—æ¯æ•°å­—ã€â€œ-â€å’Œâ€œ.â€ç»„æˆ\n" + +#: gio/gapplication-tool.c:346 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "è§£æžæ“ä½œå‚æ•°æ—¶å‡ºé”™ï¼š%s\n" + +#: gio/gapplication-tool.c:358 +msgid "actions accept a maximum of one parameter\n" +msgstr "æ“作最多接å—ä¸€ä¸ªå‚æ•°\n" + +#: gio/gapplication-tool.c:413 +msgid "list-actions command takes only the application id" +msgstr "list-actions 命令åªèƒ½æŽ¥å—应用程åºçš„ ID" + +#: gio/gapplication-tool.c:423 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "找ä¸åˆ°ä¸Žåº”ç”¨ç¨‹åº %s å¯¹åº”çš„æ¡Œé¢æ–‡ä»¶\n" + +#: gio/gapplication-tool.c:468 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"未识别的命令:%s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:648 +#: gio/ginputstream.c:1050 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "传递给 %s 的计数值太大" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "基æµä¸æ”¯æŒå®šä½" + +#: gio/gbufferedinputstream.c:938 +msgid "Cannot truncate GBufferedInputStream" +msgstr "无法截断 GBufferedInputStream" + +#: gio/gbufferedinputstream.c:983 gio/ginputstream.c:1239 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "æµå·²ç»å…³é—­" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "基æµä¸æ”¯æŒæˆªæ–­" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1873 gio/gdbusprivate.c:1418 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "æ“ä½œè¢«å–æ¶ˆ" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "无效的对象,未åˆå§‹åŒ–" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "输入中有ä¸å®Œæ•´çš„多字节åºåˆ—" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "目标ä½ç½®æ²¡æœ‰è¶³å¤Ÿçš„空间" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1266 glib/gconvert.c:449 glib/gconvert.c:879 +#: glib/giochannel.c:1573 glib/giochannel.c:1615 glib/giochannel.c:2470 +#: glib/gutf8.c:890 glib/gutf8.c:1344 +msgid "Invalid byte sequence in conversion input" +msgstr "转æ¢è¾“入中有无效的字符åºåˆ—" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:457 glib/gconvert.c:793 +#: glib/giochannel.c:1580 glib/giochannel.c:2482 +#, c-format +msgid "Error during conversion: %s" +msgstr "转æ¢è¿‡ç¨‹ä¸­å‡ºé”™ï¼š%s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1147 +msgid "Cancellable initialization not supported" +msgstr "䏿”¯æŒå¯æ’¤é”€çš„åˆå§‹åŒ–" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:322 glib/giochannel.c:1401 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "䏿”¯æŒä»Žå­—符集“%sâ€åˆ°â€œ%sâ€çš„转æ¢" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:326 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "无法打开从“%sâ€åˆ°â€œ%sâ€çš„转æ¢å™¨" + +#: gio/gcontenttype.c:470 +#, c-format +msgid "%s type" +msgstr "%s 类型" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "未知类型" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s 文件类型" + +#: gio/gcredentials.c:335 +msgid "GCredentials contains invalid data" +msgstr "GCredentials åŒ…å«æ— æ•ˆæ•°æ®" + +#: gio/gcredentials.c:395 gio/gcredentials.c:686 +msgid "GCredentials is not implemented on this OS" +msgstr "æ­¤æ“作系统上没有实现 GCredentials" + +#: gio/gcredentials.c:550 gio/gcredentials.c:568 +msgid "There is no GCredentials support for your platform" +msgstr "您的平å°å°šä¸æ”¯æŒ GCredentials" + +#: gio/gcredentials.c:626 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "æ­¤æ“作系统上的 GCredentials 未包å«ä¸€ä¸ªè¿›ç¨‹ ID" + +#: gio/gcredentials.c:680 +msgid "Credentials spoofing is not possible on this OS" +msgstr "æ­¤æ“作系统上无法进行è¯ä¹¦æ¬ºéª—" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "éžé¢„期的过早的æµç»“æŸç¬¦" + +#: gio/gdbusaddress.c:162 gio/gdbusaddress.c:236 gio/gdbusaddress.c:325 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "åœ°å€æ¡ç›®â€œ%2$sâ€ä¸­æœ‰æœªæ”¯æŒçš„键“%1$sâ€" + +#: gio/gdbusaddress.c:175 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "åœ°å€æ¡ç›®â€œ%sâ€ä¸­æœ‰æ— æ„义的键/值对组åˆ" + +#: gio/gdbusaddress.c:184 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "地å€â€œ%sâ€æ— æ•ˆï¼ˆéœ€è¦æŒ‡å®šä¸€ä¸ªä¸”仅一个的路径ã€ç›®å½•ã€ä¸´æ—¶ç›®å½•或抽象键)" + +#: gio/gdbusaddress.c:251 gio/gdbusaddress.c:262 gio/gdbusaddress.c:277 +#: gio/gdbusaddress.c:340 gio/gdbusaddress.c:351 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "地å€â€œ%sâ€ä¸­æœ‰é”™è¯¯â€”—\"%s\"属性格å¼é”™è¯¯" + +#: gio/gdbusaddress.c:421 gio/gdbusaddress.c:680 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "传输“%sâ€å¯¹äºŽåœ°å€â€œ%sâ€æœªçŸ¥æˆ–䏿”¯æŒ" + +#: gio/gdbusaddress.c:465 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "地å€å…ƒç´ â€œ%sâ€æœªåŒ…å«å†’å·ï¼ˆ:)" + +#: gio/gdbusaddress.c:474 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "地å€å…ƒç´ â€œ%sâ€ä¸­çš„传输åç§°ä¸èƒ½ä¸ºç©º" + +#: gio/gdbusaddress.c:495 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "地å€å…ƒç´ â€œ%3$sâ€ä¸­çš„第 %1$d 个键/值对 “%2$sâ€æœªåŒ…å«ç­‰å·" + +#: gio/gdbusaddress.c:506 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "地å€å…ƒç´ â€œ%3$sâ€ä¸­çš„第 %1$d 个键/值对 “%2$sâ€ä¸èƒ½æœ‰ç©ºçš„é”®" + +# 改掉顿å·ï¼Œå› å…¶ä¸æ˜¯å¹¶åˆ—关系 +#: gio/gdbusaddress.c:520 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "在地å€å…ƒç´ â€œ%3$sâ€ä¸­ï¼Œå¯¹é”®/值对 %1$d,“%2$sâ€å–消转义键或值时出错" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "地å€â€œ%sâ€ä¸­æœ‰é”™è¯¯â€”—UNIX 传输需è¦â€œpathâ€æˆ–“abstractâ€ä¹‹ä¸€çš„键被设置" + +#: gio/gdbusaddress.c:623 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "地å€â€œ%sâ€ä¸­æœ‰é”™è¯¯â€”—主机属性丢失或格å¼é”™è¯¯" + +#: gio/gdbusaddress.c:637 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "地å€â€œ%sâ€ä¸­æœ‰é”™è¯¯â€”—端å£å±žæ€§ä¸¢å¤±æˆ–æ ¼å¼é”™è¯¯" + +#: gio/gdbusaddress.c:651 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "地å€â€œ%sâ€ä¸­æœ‰é”™è¯¯â€”—临时文件属性丢失或格å¼é”™è¯¯" + +#: gio/gdbusaddress.c:672 +msgid "Error auto-launching: " +msgstr "自动å¯åŠ¨å‡ºé”™ï¼š" + +#: gio/gdbusaddress.c:725 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "打开临时文件“%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/gdbusaddress.c:744 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "读å–临时文件“%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/gdbusaddress.c:753 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "读å–临时文件“%sâ€æ—¶å‡ºé”™ï¼Œé¢„计 16 个字节,得到 %d 个" + +#: gio/gdbusaddress.c:771 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "写入临时文件“%sâ€çš„å†…å®¹åˆ°æµæ—¶å‡ºé”™ï¼š" + +#: gio/gdbusaddress.c:986 +msgid "The given address is empty" +msgstr "给定的地å€ä¸ºç©º" + +#: gio/gdbusaddress.c:1099 +#, c-format +msgid "Cannot spawn a message bus when AT_SECURE is set" +msgstr "无法在已设置 AT_SECURE æ—¶å¯åŠ¨ä¸€æ¡æ¶ˆæ¯æ€»çº¿" + +#: gio/gdbusaddress.c:1106 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "无法在无机器 ID 时生æˆä¸€æ¡æ¶ˆæ¯æ€»çº¿ï¼š" + +#: gio/gdbusaddress.c:1113 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "无法在没有 X11 $DISPLAY 的情况下自动å¯åЍ D-Bus" + +#: gio/gdbusaddress.c:1155 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "生æˆå¹¶è¿è¡Œå‘½ä»¤è¡Œâ€œ%sâ€æ—¶å‡ºé”™ï¼š" + +#: gio/gdbusaddress.c:1224 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "æ— æ³•ç¡®å®šä¼šè¯æ€»çº¿åœ°å€ï¼ˆå°šæœªåœ¨æ­¤æ“作系统上实现)" + +#: gio/gdbusaddress.c:1373 gio/gdbusconnection.c:7334 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "无法从 DBUS_STARTER_BUS_TYPE 环境å˜é‡ç¡®å®šæ€»çº¿åœ°å€â€”—未知的值“%sâ€" + +#: gio/gdbusaddress.c:1382 gio/gdbusconnection.c:7343 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "无法确定总线地å€ï¼Œå› ä¸ºçŽ¯å¢ƒå˜é‡ DBUS_STARTER_BUS_TYPE 未设置" + +#: gio/gdbusaddress.c:1392 +#, c-format +msgid "Unknown bus type %d" +msgstr "未知的总线类型 %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "试图读å–一行时,异常地缺失内容" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "试图(安全地)读å–一行时,异常地缺失内容" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "用尽了所有å¯ç”¨çš„è®¤è¯æœºåˆ¶ï¼ˆå·²å°è¯•:%s)(å¯ç”¨çš„:%s)" + +#: gio/gdbusauth.c:1171 +msgid "User IDs must be the same for peer and server" +msgstr "对等端和æœåŠ¡å™¨ç«¯çš„ç”¨æˆ· ID 必须相åŒ" + +#: gio/gdbusauth.c:1183 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "通过 GDBusAuthObserver::authorize-authenticated-peer å–æ¶ˆ" + +#: gio/gdbusauthmechanismsha1.c:299 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "获å–目录“%sâ€ä¿¡æ¯æ—¶å‘生错误:%s" + +#: gio/gdbusauthmechanismsha1.c:314 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "目录“%sâ€æƒé™é”™è¯¯ã€‚期望 0700,得到 0%o" + +#: gio/gdbusauthmechanismsha1.c:347 gio/gdbusauthmechanismsha1.c:358 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "创建目录“%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/gdbusauthmechanismsha1.c:360 gio/gfile.c:1080 gio/gfile.c:1318 +#: gio/gfile.c:1456 gio/gfile.c:1694 gio/gfile.c:1749 gio/gfile.c:1807 +#: gio/gfile.c:1891 gio/gfile.c:1948 gio/gfile.c:2012 gio/gfile.c:2067 +#: gio/gfile.c:3772 gio/gfile.c:3912 gio/gfile.c:4205 gio/gfile.c:4675 +#: gio/gfile.c:5086 gio/gfile.c:5171 gio/gfile.c:5261 gio/gfile.c:5358 +#: gio/gfile.c:5445 gio/gfile.c:5546 gio/gfile.c:8375 gio/gfile.c:8465 +#: gio/gfile.c:8549 gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "䏿”¯æŒè¯¥æ“作" + +#: gio/gdbusauthmechanismsha1.c:403 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "打开密钥环“%sâ€ä»¥è¯»å–时出错:" + +#: gio/gdbusauthmechanismsha1.c:426 gio/gdbusauthmechanismsha1.c:748 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%2$sâ€å¤„的密钥环第 %1$d 行有ä¸ç¬¦åˆæ ¼å¼çš„内容“%3$sâ€" + +#: gio/gdbusauthmechanismsha1.c:440 gio/gdbusauthmechanismsha1.c:762 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%2$sâ€å¤„的密钥环第 %1$d 行第一个令牌有ä¸ç¬¦åˆæ ¼å¼çš„内容“%3$sâ€" + +#: gio/gdbusauthmechanismsha1.c:454 gio/gdbusauthmechanismsha1.c:776 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "“%2$sâ€å¤„的密钥环第 %1$d 行第二个令牌有ä¸ç¬¦åˆæ ¼å¼çš„内容“%3$sâ€" + +#: gio/gdbusauthmechanismsha1.c:478 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "未在“%2$sâ€å¤„的密钥环中找到 ID 为 %1$d çš„ cookie" + +#: gio/gdbusauthmechanismsha1.c:524 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "åˆ›å»ºé”æ–‡ä»¶â€œ%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/gdbusauthmechanismsha1.c:588 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "åˆ é™¤è¿‡æ—¶çš„é”æ–‡ä»¶â€œ%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/gdbusauthmechanismsha1.c:627 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "å…³é—­ï¼ˆæœªé“¾æŽ¥çš„ï¼‰é”æ–‡ä»¶â€œ%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/gdbusauthmechanismsha1.c:638 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "删除(unlinkï¼‰é”æ–‡ä»¶â€œ%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/gdbusauthmechanismsha1.c:715 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "打开钥匙环“%sâ€ä»¥å†™å…¥æ—¶å‡ºé”™ï¼š" + +#: gio/gdbusauthmechanismsha1.c:909 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(此外,解除“%sâ€çš„é”定也失败了:%s) " + +#: gio/gdbusconnection.c:604 gio/gdbusconnection.c:2418 +msgid "The connection is closed" +msgstr "连接已关闭" + +#: gio/gdbusconnection.c:1903 +msgid "Timeout was reached" +msgstr "已到超时é™åˆ¶" + +#: gio/gdbusconnection.c:2541 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "构建客户端连接时é‡åˆ°ä¸æ”¯æŒçš„æ ‡å¿—" + +#: gio/gdbusconnection.c:4269 gio/gdbusconnection.c:4623 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "路径 %s 的对象上没有“org.freedesktop.DBus.Propertiesâ€æŽ¥å£" + +#: gio/gdbusconnection.c:4414 +#, c-format +msgid "No such property “%sâ€" +msgstr "无此属性“%sâ€" + +#: gio/gdbusconnection.c:4426 +#, c-format +msgid "Property “%s†is not readable" +msgstr "属性“%sâ€ä¸å¯è¯»" + +#: gio/gdbusconnection.c:4437 +#, c-format +msgid "Property “%s†is not writable" +msgstr "属性“%sâ€ä¸å¯å†™" + +#: gio/gdbusconnection.c:4457 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "设置属性“%sâ€æ—¶å‡ºé”™ï¼šæœŸæœ›â€œ%sâ€ç±»åž‹ä½†å¾—到了“%sâ€ç±»åž‹" + +#: gio/gdbusconnection.c:4562 gio/gdbusconnection.c:4777 +#: gio/gdbusconnection.c:6760 +#, c-format +msgid "No such interface “%sâ€" +msgstr "无此接å£â€œ%sâ€" + +#: gio/gdbusconnection.c:4999 gio/gdbusconnection.c:7274 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "在路径 %s 的对象上没有“%sâ€æŽ¥å£" + +#: gio/gdbusconnection.c:5100 +#, c-format +msgid "No such method “%sâ€" +msgstr "没有“%sâ€è¿™ä¸ªæ–¹æ³•" + +#: gio/gdbusconnection.c:5131 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "消æ¯çš„类型“%sâ€ï¼Œä¸Žé¢„期的类型“%sâ€ä¸åŒ¹é…" + +#: gio/gdbusconnection.c:5334 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "已为 %2$s å¤„çš„æŽ¥å£ %1$s 导出了一个对象" + +#: gio/gdbusconnection.c:5561 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "无法检索属性 %s.%s" + +#: gio/gdbusconnection.c:5617 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "无法设置属性 %s.%s" + +#: gio/gdbusconnection.c:5796 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "方法“%sâ€è¿”回类型“%sâ€ï¼Œä½†é¢„期的是“%sâ€" + +#: gio/gdbusconnection.c:6872 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "带有“%3$sâ€ç­¾å的接å£â€œ%2$sâ€ä¸Šä¸å­˜åœ¨â€œ%1$sâ€æ–¹æ³•" + +#: gio/gdbusconnection.c:6993 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "å·²ç»ä¸º %s å¯¼å‡ºä¸€ä¸ªå­æ ‘" + +#: gio/gdbusconnection.c:7282 +#, c-format +msgid "Object does not exist at path “%sâ€" +msgstr "对象在路径“%sâ€å¤„ä¸å­˜åœ¨" + +#: gio/gdbusmessage.c:1301 +msgid "type is INVALID" +msgstr "类型无效" + +#: gio/gdbusmessage.c:1312 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL 消æ¯ï¼šPATH 或 MEMBER 首部字段缺失" + +#: gio/gdbusmessage.c:1323 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN 消æ¯ï¼šREPLY_SERIAL 首部字段缺失" + +#: gio/gdbusmessage.c:1335 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "错误消æ¯ï¼šREPLY_SERIAL 或 ERROR_NAME 首部字段缺失" + +#: gio/gdbusmessage.c:1348 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "ä¿¡å·æ¶ˆæ¯ï¼šPATHã€INTERFACE 或 MEMBER METHOD_RETURN缺失" + +#: gio/gdbusmessage.c:1356 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "ä¿¡å·æ¶ˆæ¯ï¼šPATH 首部字段正在使用ä¿ç•™å€¼ /org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1364 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "ä¿¡å·æ¶ˆæ¯ï¼šINTERFACE 首部字段正在使用ä¿ç•™å€¼ org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1412 gio/gdbusmessage.c:1472 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "æœŸæœ›è¯»å– %lu 个字节但åªå¾—到 %lu 个" + +#: gio/gdbusmessage.c:1426 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "期望“%sâ€åŽä¸º NUL 字节但找到了字节 %d" + +#: gio/gdbusmessage.c:1445 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"期望得到有效的 UTF-8 字符串,但在字节åç§» %d 处(字符串长度为 %d)找到了无效" +"的字节。该点的有效 UTF-8 字符串曾是“%sâ€" + +#: gio/gdbusmessage.c:1509 gio/gdbusmessage.c:1785 gio/gdbusmessage.c:1996 +msgid "Value nested too deeply" +msgstr "值嵌套过深" + +#: gio/gdbusmessage.c:1677 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "已解æžçš„值“%sâ€ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus 对象路径" + +#: gio/gdbusmessage.c:1701 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "已解æžçš„值“%sâ€ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus ç­¾å" + +#: gio/gdbusmessage.c:1752 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "é‡åˆ°é•¿åº¦ä¸º %u 字节的数组。最大长度应为 2<<26 字节(64 MiB)。" + +#: gio/gdbusmessage.c:1772 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"é‡åˆ°ç±»åž‹ä¸ºâ€œa%câ€çš„æ•°ç»„,需è¦é•¿åº¦ä¸º %u å­—èŠ‚çš„å€æ•°ï¼Œä½†æ˜¯æ‰¾åˆ°çš„长度为 %u 字节" + +#: gio/gdbusmessage.c:1926 gio/gdbusmessage.c:2645 +msgid "Empty structures (tuples) are not allowed in D-Bus" +msgstr "D-Bus 中ä¸å…许空结构(tuples)" + +#: gio/gdbusmessage.c:1980 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "å˜é‡çš„已解æžå€¼â€œ%sâ€ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus ç­¾å" + +#: gio/gdbusmessage.c:2021 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "从 D-Bus 线格å¼ä»¥ç±»åž‹å­—符串“%sâ€ååºåˆ—化 GVariant æ—¶å‘生错误" + +#: gio/gdbusmessage.c:2206 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "无效的字节åºå€¼ã€‚期望为 0x6c(“lâ€ï¼‰æˆ– 0x42(“Bâ€ï¼‰ä½†æ‰¾åˆ°å€¼ 0x%02x" + +#: gio/gdbusmessage.c:2225 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "无效的主å议版本。期望 1,但是找到了 %d" + +#: gio/gdbusmessage.c:2283 gio/gdbusmessage.c:2881 +msgid "Signature header found but is not of type signature" +msgstr "找到了签å首部但ä¸å±žäºŽç±»åž‹ç­¾å" + +#: gio/gdbusmessage.c:2295 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "å‘现签å“%sâ€çš„ç­¾å首部,但消æ¯ä¸»ä½“为空" + +#: gio/gdbusmessage.c:2310 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "已解æžçš„值“%sâ€ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus ç­¾å(针对消æ¯ä¸»ä½“)" + +#: gio/gdbusmessage.c:2342 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "消æ¯ä¸­æ²¡æœ‰ç­¾å首部,但消æ¯ä¸»ä½“为 %u 字节" + +#: gio/gdbusmessage.c:2352 +msgid "Cannot deserialize message: " +msgstr "无法ååºåˆ—化消æ¯ï¼š" + +#: gio/gdbusmessage.c:2698 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "以类型字符串“%sâ€åºåˆ—化 GVariant 到 D-Bus çº¿æ ¼å¼æ—¶å‘生错误" + +#: gio/gdbusmessage.c:2835 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "消æ¯ä¸­çš„æ–‡ä»¶æè¿°ç¬¦æ•°é‡ï¼ˆ%d)与首部字段中的(%d)ä¸åŒ" + +#: gio/gdbusmessage.c:2843 +msgid "Cannot serialize message: " +msgstr "无法åºåˆ—化消æ¯ï¼š" + +#: gio/gdbusmessage.c:2896 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "消æ¯ä¸»ä½“有签å“%sâ€ä½†æ˜¯æ²¡æœ‰ç­¾å首部" + +#: gio/gdbusmessage.c:2906 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "消æ¯ä¸»ä½“有类型签å“%sâ€ä½†é¦–部字段的签å为“%sâ€" + +#: gio/gdbusmessage.c:2922 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "消æ¯ä¸»ä½“为空,但首部字段的签å为“(%s)â€" + +#: gio/gdbusmessage.c:3477 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "出错,返回了“%sâ€ç±»åž‹çš„主体" + +#: gio/gdbusmessage.c:3485 +msgid "Error return with empty body" +msgstr "出错,返回了空的主体" + +#: gio/gdbusprivate.c:2185 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(按任æ„键关闭本窗å£ï¼‰\n" + +#: gio/gdbusprivate.c:2371 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "dbus ä¼šè¯æœªè¿è¡Œï¼Œè‡ªåЍå¯åŠ¨å¤±è´¥" + +#: gio/gdbusprivate.c:2394 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "无法获å–硬件é…置文件:%s" + +#. Translators: Both placeholders are file paths +#: gio/gdbusprivate.c:2445 +#, c-format +msgid "Unable to load %s or %s: " +msgstr "无法载入 %s 或 %s:" + +#: gio/gdbusproxy.c:1573 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "为 %s 调用 StartServiceByName 时出错:" + +#: gio/gdbusproxy.c:1596 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "从 StartServiceByName(\"%2$s\") 方法获得æ„å¤–å›žå¤ %1$d" + +#: gio/gdbusproxy.c:2707 gio/gdbusproxy.c:2842 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"无法调用方法;代ç†å称为常è§çš„æ— æ‰€æœ‰è€…çš„åç§° %s,且代ç†ä½¿ç”¨ " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START 标记构建" + +#: gio/gdbusserver.c:767 +msgid "Abstract namespace not supported" +msgstr "䏿”¯æŒæŠ½è±¡å‘½å空间" + +#: gio/gdbusserver.c:860 +msgid "Cannot specify nonce file when creating a server" +msgstr "创建æœåŠ¡å™¨æ—¶æ— æ³•æŒ‡å®šä¸´æ—¶æ–‡ä»¶" + +#: gio/gdbusserver.c:942 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "写入“%sâ€å¤„的临时文件时出错:%s" + +#: gio/gdbusserver.c:1117 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "字符串“%sâ€ä¸æ˜¯æœ‰æ•ˆ D-Bus GUID" + +#: gio/gdbusserver.c:1157 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "无法监å¬ä¸æ”¯æŒçš„传输“%sâ€" + +# 统一翻译 +#: gio/gdbus-tool.c:111 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"命令:\n" +" help 显示本信æ¯\n" +" introspect Introspect 一个远程对象\n" +" monitor 监视一个远程对象\n" +" call 调用远程对象的一个方法\n" +" emit å‘出一个信å·\n" +" wait 等待总线å称出现\n" +"\n" +"使用“%s 命令 --helpâ€ä»¥èŽ·å¾—æ¯ä¸€ä¸ªå‘½ä»¤çš„帮助。\n" + +#: gio/gdbus-tool.c:201 gio/gdbus-tool.c:273 gio/gdbus-tool.c:345 +#: gio/gdbus-tool.c:369 gio/gdbus-tool.c:859 gio/gdbus-tool.c:1244 +#: gio/gdbus-tool.c:1732 +#, c-format +msgid "Error: %s\n" +msgstr "错误:%s\n" + +#: gio/gdbus-tool.c:212 gio/gdbus-tool.c:286 gio/gdbus-tool.c:1748 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "è§£æž Introspection XML 时出错:%s\n" + +#: gio/gdbus-tool.c:250 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "错误:%s 䏿˜¯æœ‰æ•ˆçš„åç§°\n" + +#: gio/gdbus-tool.c:255 gio/gdbus-tool.c:745 gio/gdbus-tool.c:1063 +#: gio/gdbus-tool.c:1898 gio/gdbus-tool.c:2138 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "错误:%s 䏿˜¯æœ‰æ•ˆçš„对象路径\n" + +#: gio/gdbus-tool.c:403 +msgid "Connect to the system bus" +msgstr "连接到系统总线" + +#: gio/gdbus-tool.c:404 +msgid "Connect to the session bus" +msgstr "è¿žæŽ¥åˆ°ä¼šè¯æ€»çº¿" + +#: gio/gdbus-tool.c:405 +msgid "Connect to given D-Bus address" +msgstr "连接到给定的 D-Bus 地å€" + +#: gio/gdbus-tool.c:415 +msgid "Connection Endpoint Options:" +msgstr "连接端点选项:" + +#: gio/gdbus-tool.c:416 +msgid "Options specifying the connection endpoint" +msgstr "指定连接端点的选项" + +# 没有>未,消歧义 +#: gio/gdbus-tool.c:439 +#, c-format +msgid "No connection endpoint specified" +msgstr "未指定连接的端点" + +#: gio/gdbus-tool.c:449 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "指定了多个连接端点" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "è­¦å‘Šï¼šæ ¹æ® Introspection æ•°æ®ï¼ŒæŽ¥å£â€œ%sâ€ä¸å­˜åœ¨\n" + +#: gio/gdbus-tool.c:531 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "è­¦å‘Šï¼šæ ¹æ® Introspection æ•°æ®ï¼ŒæŽ¥å£â€œ%2$sâ€ä¸­ä¸å­˜åœ¨æ–¹æ³•“%1$sâ€\n" + +#: gio/gdbus-tool.c:593 +msgid "Optional destination for signal (unique name)" +msgstr "ä¿¡å·çš„å¯é€‰ç›®æ ‡ä½ç½®ï¼ˆå”¯ä¸€å称)" + +#: gio/gdbus-tool.c:594 +msgid "Object path to emit signal on" +msgstr "è¦è§¦å‘ä¿¡å·çš„对象路径" + +#: gio/gdbus-tool.c:595 +msgid "Signal and interface name" +msgstr "ä¿¡å·å’ŒæŽ¥å£åç§°" + +#: gio/gdbus-tool.c:628 +msgid "Emit a signal." +msgstr "å‘å°„ä¿¡å·ã€‚" + +#: gio/gdbus-tool.c:683 gio/gdbus-tool.c:1000 gio/gdbus-tool.c:1835 +#: gio/gdbus-tool.c:2067 gio/gdbus-tool.c:2287 +#, c-format +msgid "Error connecting: %s\n" +msgstr "连接时出错:%s\n" + +#: gio/gdbus-tool.c:703 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "错误:%s 䏿˜¯æœ‰æ•ˆçš„唯一总线å。\n" + +#: gio/gdbus-tool.c:722 gio/gdbus-tool.c:1043 gio/gdbus-tool.c:1878 +msgid "Error: Object path is not specified\n" +msgstr "错误:未指定对象路径\n" + +#: gio/gdbus-tool.c:765 +msgid "Error: Signal name is not specified\n" +msgstr "错误:未指定信å·å\n" + +#: gio/gdbus-tool.c:779 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "错误:信å·å“%sâ€æ— æ•ˆ\n" + +#: gio/gdbus-tool.c:791 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "错误:%s 䏿˜¯æœ‰æ•ˆçš„æŽ¥å£å称。\n" + +#: gio/gdbus-tool.c:797 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "错误:%s 䏿˜¯æœ‰æ•ˆçš„æˆå‘˜å称。\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:834 gio/gdbus-tool.c:1175 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "è§£æžç¬¬ %d 个选项时出错:%s\n" + +#: gio/gdbus-tool.c:866 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "刷新连接时出错:%s\n" + +#: gio/gdbus-tool.c:894 +msgid "Destination name to invoke method on" +msgstr "调用方法的目标ä½ç½®åç§°" + +#: gio/gdbus-tool.c:895 +msgid "Object path to invoke method on" +msgstr "调用方法的对象路径" + +#: gio/gdbus-tool.c:896 +msgid "Method and interface name" +msgstr "方法和接å£åç§°" + +#: gio/gdbus-tool.c:897 +msgid "Timeout in seconds" +msgstr "超时(以秒计)" + +#: gio/gdbus-tool.c:898 +msgid "Allow interactive authorization" +msgstr "å…è®¸äº¤äº’å¼æŽˆæƒ" + +#: gio/gdbus-tool.c:945 +msgid "Invoke a method on a remote object." +msgstr "在远程对象上调用一个方法。" + +#: gio/gdbus-tool.c:1017 gio/gdbus-tool.c:1852 gio/gdbus-tool.c:2092 +msgid "Error: Destination is not specified\n" +msgstr "错误:未指定目标ä½ç½®åç§°\n" + +#: gio/gdbus-tool.c:1028 gio/gdbus-tool.c:1869 gio/gdbus-tool.c:2103 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "错误:%s 䏿˜¯æœ‰æ•ˆçš„æ€»çº¿åç§°\n" + +#: gio/gdbus-tool.c:1078 +msgid "Error: Method name is not specified\n" +msgstr "é”™è¯¯ï¼šæ–¹æ³•åæ²¡æœ‰æŒ‡å®š\n" + +#: gio/gdbus-tool.c:1089 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "错误:方法å“%sâ€æ— æ•ˆ\n" + +#: gio/gdbus-tool.c:1167 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "è§£æž\"%2$s\"类型的第 %1$d ä¸ªå‚æ•°æ—¶å‘生错误:%3$s\n" + +#: gio/gdbus-tool.c:1193 +#, c-format +msgid "Error adding handle %d: %s\n" +msgstr "æ·»åŠ å¥æŸ„ %d 时出错:%s\n" + +#: gio/gdbus-tool.c:1694 +msgid "Destination name to introspect" +msgstr "è¦ Introspect 的目标ä½ç½®åç§°" + +#: gio/gdbus-tool.c:1695 +msgid "Object path to introspect" +msgstr "è¦ Introspect 的对象路径" + +#: gio/gdbus-tool.c:1696 +msgid "Print XML" +msgstr "输出 XML" + +#: gio/gdbus-tool.c:1697 +msgid "Introspect children" +msgstr "Introspect å­å¯¹è±¡" + +#: gio/gdbus-tool.c:1698 +msgid "Only print properties" +msgstr "åªæ‰“å°å±žæ€§" + +# 跟命令行里的统一翻译 +#: gio/gdbus-tool.c:1787 +msgid "Introspect a remote object." +msgstr "Introspect 一个远程对象。" + +#: gio/gdbus-tool.c:1993 +msgid "Destination name to monitor" +msgstr "è¦ç›‘视的目标ä½ç½®åç§°" + +#: gio/gdbus-tool.c:1994 +msgid "Object path to monitor" +msgstr "è¦ç›‘视的对象路径" + +#: gio/gdbus-tool.c:2019 +msgid "Monitor a remote object." +msgstr "监视一个远程对象。" + +#: gio/gdbus-tool.c:2077 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "错误:无法监视 non-message-bus 连接\n" + +#: gio/gdbus-tool.c:2201 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "在等待å¦ä¸€æœåŠ¡å‰è¦æ¿€æ´»çš„æœåŠ¡ï¼ˆå¸¸è§å称)" + +#: gio/gdbus-tool.c:2204 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "出现错误退出å‰çš„超时(秒); 0 为无超时(默认)" + +#: gio/gdbus-tool.c:2252 +msgid "[OPTION…] BUS-NAME" +msgstr "[选项…] 总线åç§°" + +#: gio/gdbus-tool.c:2253 +msgid "Wait for a bus name to appear." +msgstr "等待总线å称出现。" + +#: gio/gdbus-tool.c:2329 +msgid "Error: A service to activate for must be specified.\n" +msgstr "é”™è¯¯ï¼šæœªæŒ‡å®šéœ€è¦æ¿€æ´»çš„æœåŠ¡å称。\n" + +#: gio/gdbus-tool.c:2334 +msgid "Error: A service to wait for must be specified.\n" +msgstr "错误:未指定需è¦ç­‰å¾…çš„æœåŠ¡å称。\n" + +#: gio/gdbus-tool.c:2339 +msgid "Error: Too many arguments.\n" +msgstr "é”™è¯¯ï¼šå‚æ•°è¿‡å¤šã€‚\n" + +#: gio/gdbus-tool.c:2347 gio/gdbus-tool.c:2354 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "错误:%s 䏿˜¯æœ‰æ•ˆçš„æ€»çº¿å称。\n" + +#: gio/gdebugcontrollerdbus.c:203 +#, c-format +msgid "Not authorized to change debug settings" +msgstr "未获认è¯ä»¥æ›´æ”¹è°ƒè¯•设置" + +#: gio/gdesktopappinfo.c:2174 gio/gdesktopappinfo.c:5099 +msgid "Unnamed" +msgstr "未命å" + +#: gio/gdesktopappinfo.c:2584 +msgid "Desktop file didn’t specify Exec field" +msgstr "æ¡Œé¢æ–‡ä»¶æœªæŒ‡å®š Exec 字段" + +#: gio/gdesktopappinfo.c:2892 +msgid "Unable to find terminal required for application" +msgstr "无法找到应用程åºéœ€è¦çš„终端" + +#: gio/gdesktopappinfo.c:3619 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "无法创建用户应用程åºé…置文件夹 %s:%s" + +#: gio/gdesktopappinfo.c:3623 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "无法创建用户 MIME é…置文件夹 %s:%s" + +#: gio/gdesktopappinfo.c:3865 gio/gdesktopappinfo.c:3889 +msgid "Application information lacks an identifier" +msgstr "应用程åºä¿¡æ¯ç¼ºå°‘标志符" + +#: gio/gdesktopappinfo.c:4125 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "æ— æ³•åˆ›å»ºç”¨æˆ·æ¡Œé¢æ–‡ä»¶ %s" + +#: gio/gdesktopappinfo.c:4261 +#, c-format +msgid "Custom definition for %s" +msgstr "%s 的自定义" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "驱动器未实现弹出" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "驱动器未实现弹出或 eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "驱动器未实现介质的轮询" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "驱动器未实现å¯åЍ" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "é©±åŠ¨å™¨æœªå®žçŽ°åœæ­¢" + +#: gio/gdtlsconnection.c:1186 gio/gtlsconnection.c:955 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS åŽç«¯æ²¡æœ‰å®žçް TLS 绑定获å–" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS 支æŒä¸å¯ç”¨" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS 支æŒä¸å¯ç”¨" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "无法处ç†ç‰ˆæœ¬ä¸º %d çš„ GEmblem ç¼–ç " + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem ç¼–ç ä¸­æœ‰ä¸æ­£ç¡®çš„ç¬¦å·æ•°é‡ï¼ˆ%d)" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "无法处ç†ç‰ˆæœ¬ä¸º %d çš„ GEmblemedIcon ç¼–ç " + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon ç¼–ç ä¸­æœ‰ä¸æ­£ç¡®çš„ç¬¦å·æ•°é‡ï¼ˆ%d)" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "GEmblemedIcon 中应为 GEmblem" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1579 +msgid "Containing mount does not exist" +msgstr "包å«çš„æŒ‚è½½ä¸å­˜åœ¨" + +#: gio/gfile.c:2626 gio/glocalfile.c:2486 +msgid "Can’t copy over directory" +msgstr "无法跨目录å¤åˆ¶" + +#: gio/gfile.c:2686 +msgid "Can’t copy directory over directory" +msgstr "无法跨目录å¤åˆ¶åˆ°ç›®å½•" + +#: gio/gfile.c:2694 +msgid "Target file exists" +msgstr "目标文件已存在" + +#: gio/gfile.c:2713 +msgid "Can’t recursively copy directory" +msgstr "无法递归å¤åˆ¶ç›®å½•" + +#: gio/gfile.c:3014 +msgid "Splice not supported" +msgstr "䏿”¯æŒæ‹¼æŽ¥" + +#: gio/gfile.c:3018 +#, c-format +msgid "Error splicing file: %s" +msgstr "拼接文件时出错:%s" + +#: gio/gfile.c:3170 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "䏿”¯æŒåœ¨æŒ‚载之间å¤åˆ¶ï¼ˆreflink/clone)" + +#: gio/gfile.c:3174 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "å¤åˆ¶ï¼ˆreflink/clone)æ“ä½œä¸æ”¯æŒæˆ–无效" + +#: gio/gfile.c:3179 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "å¤åˆ¶ï¼ˆreflink/clone)æ“ä½œä¸æ”¯æŒæˆ–者失败" + +#: gio/gfile.c:3244 +msgid "Can’t copy special file" +msgstr "无法å¤åˆ¶ç‰¹æ®Šæ–‡ä»¶" + +#: gio/gfile.c:4138 +msgid "Invalid symlink value given" +msgstr "给定的符å·é“¾æŽ¥å€¼æ— æ•ˆ" + +#: gio/gfile.c:4148 glib/gfileutils.c:2333 +msgid "Symbolic links not supported" +msgstr "䏿”¯æŒç¬¦å·é“¾æŽ¥" + +#: gio/gfile.c:4316 +msgid "Trash not supported" +msgstr "䏿”¯æŒå›žæ”¶ç«™" + +#: gio/gfile.c:4428 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "文件åä¸èƒ½åŒ…å«â€œ%câ€" + +#: gio/gfile.c:7028 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "å·æœªå®žçŽ°æŒ‚è½½" + +#: gio/gfile.c:7142 gio/gfile.c:7190 +msgid "No application is registered as handling this file" +msgstr "æ²¡æœ‰åº”ç”¨ç¨‹åºæ³¨å†Œä¸ºå¤„ç†æ­¤æ–‡ä»¶çš„" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "枚举器已关闭" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "文件枚举器有异常æ“作" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "文件枚举器已关闭" + +#: gio/gfileicon.c:250 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "无法处ç†ç‰ˆæœ¬ä¸º %d çš„ GFileIcon ç¼–ç " + +#: gio/gfileicon.c:260 +msgid "Malformed input data for GFileIcon" +msgstr "GFileIcon æœ‰ä¸æ­£ç¡®çš„输入数æ®" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "æµä¸æ”¯æŒ query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "æµä¸æ”¯æŒå®šä½" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "输入æµä¸å…许截断" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "æµä¸æ”¯æŒæˆªæ–­" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:458 gio/gresolver.c:611 +#: glib/gconvert.c:1825 +msgid "Invalid hostname" +msgstr "无效的主机å" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "错误的 HTTP 代ç†å›žå¤" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "ä¸å…许 HTTP 代ç†è¿žæŽ¥" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP 代ç†è®¤è¯å¤±è´¥" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP 代ç†éœ€è¦è®¤è¯" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "连接到 HTTP 代ç†å¤±è´¥: %i" + +#: gio/ghttpproxy.c:266 +msgid "HTTP proxy response too big" +msgstr "HTTP 代ç†å“应过大" + +#: gio/ghttpproxy.c:283 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP ä»£ç†æœåС噍æ„外关闭连接。" + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "é”™è¯¯çš„ç¬¦å·æ•°é‡ï¼ˆ%d)" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "ç±»å %s 没有类型" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "类型 %s 没有实现 GIcon 接å£" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "类型 %s 䏿˜¯ç±»" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "䏿­£ç¡®çš„版本å·ï¼š%s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "类型 %s 没有实现 GIcon 接å£çš„ from_tokens() 方法" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "æ— æ³•å¤„ç†æä¾›ç‰ˆæœ¬çš„å›¾æ ‡ç¼–ç " + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "没有指定地å€" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "å¯¹åœ°å€æ¥è¯´é•¿åº¦ %u 太长了" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "åœ°å€æœ‰äº›ä½è®¾ç½®å¾—超出了å‰ç¼€é•¿åº¦" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "ä¸èƒ½å°†â€œ%sâ€è§£æžä¸º IP åœ°å€æŽ©ç " + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:228 +msgid "Not enough space for socket address" +msgstr "没有足够的空间用于套接字地å€" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "䏿”¯æŒçš„套接字地å€" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "è¾“å…¥æµæœªå®žçŽ°è¯»å–" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1249 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "æµæœ‰å¼‚常æ“作" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "å¤åˆ¶æ–‡ä»¶æ—¶ä¿ç•™" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "移动时与文件一起" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "“versionâ€ä¸æŽ¥å—傿•°" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "用法:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "打å°ç‰ˆæœ¬ä¿¡æ¯å¹¶é€€å‡ºã€‚" + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "命令:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "串接文件,写到标准输出" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "å¤åˆ¶æ–‡ä»¶" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "显示关于ä½ç½®çš„ä¿¡æ¯" + +#: gio/gio-tool.c:232 +msgid "Launch an application from a desktop file" +msgstr "ä»Žæ¡Œé¢æ–‡ä»¶å¯åŠ¨åº”ç”¨ç¨‹åº" + +#: gio/gio-tool.c:233 +msgid "List the contents of locations" +msgstr "列出æŸä½ç½®çš„内容" + +#: gio/gio-tool.c:234 +msgid "Get or set the handler for a mimetype" +msgstr "èŽ·å–æˆ–设置æŸç§ MIME 类型的处ç†ç¨‹åº" + +#: gio/gio-tool.c:235 +msgid "Create directories" +msgstr "创建目录" + +#: gio/gio-tool.c:236 +msgid "Monitor files and directories for changes" +msgstr "监视文件和目录的更改" + +#: gio/gio-tool.c:237 +msgid "Mount or unmount the locations" +msgstr "挂载或å¸è½½ä½ç½®" + +#: gio/gio-tool.c:238 +msgid "Move one or more files" +msgstr "移动文件" + +#: gio/gio-tool.c:239 +msgid "Open files with the default application" +msgstr "用默认应用打开文件" + +#: gio/gio-tool.c:240 +msgid "Rename a file" +msgstr "é‡å‘½å文件" + +#: gio/gio-tool.c:241 +msgid "Delete one or more files" +msgstr "删除文件" + +#: gio/gio-tool.c:242 +msgid "Read from standard input and save" +msgstr "从标准输入读å–å¹¶ä¿å­˜" + +#: gio/gio-tool.c:243 +msgid "Set a file attribute" +msgstr "设置文件属性" + +#: gio/gio-tool.c:244 +msgid "Move files or directories to the trash" +msgstr "移动文件或目录到回收站" + +#: gio/gio-tool.c:245 +msgid "Lists the contents of locations in a tree" +msgstr "在树中列出æŸä½ç½®çš„内容" + +#: gio/gio-tool.c:247 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "使用 %s 以获å–详细帮助。\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "写入到标准输出时出错" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:340 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:204 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:220 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "ä½ç½®" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "串接文件,写到标准输出。" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat 如传统 cat 程åºé‚£æ ·å·¥ä½œï¼Œä½†ä½¿ç”¨ GIO ä½ç½®è€Œéžæœ¬åœ°æ–‡ä»¶ï¼š\n" +"例如,你å¯ä»¥æŒ‡å®š smb://server/resource/file.txt 之类的ä½ç½®ã€‚" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:371 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:229 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:303 +msgid "No locations given" +msgstr "未给定ä½ç½®" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "无目标目录" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "显示进度" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "è¦†ç›–å‰æç¤º" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "ä¿ç•™æ‰€æœ‰å±žæ€§" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "备份现有的目标文件" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "从ä¸è·Ÿéšç¬¦å·é“¾æŽ¥" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "对目标使用默认æƒé™" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "å·²å¤åˆ¶ %2$s 中的 %1$s(%3$s/秒)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "æ¥æº" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "目标" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "将一个或多个文件从æºå¤´å¤åˆ¶åˆ°ç›®æ ‡ã€‚" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy 如传统 cp 程åºé‚£æ ·å·¥ä½œï¼Œä½†ä½¿ç”¨ GIO ä½ç½®è€Œéžæœ¬åœ°æ–‡ä»¶ï¼š\n" +"例如,你å¯ä»¥æŒ‡å®š smb://server/resource/file.txt 之类的ä½ç½®ã€‚" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "目标“%sâ€ä¸æ˜¯ç›®å½•" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s:è¦è¦†ç›–“%sâ€å—?" + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "列出å¯å†™å±žæ€§" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "èŽ·å–æ–‡ä»¶ç³»ç»Ÿä¿¡æ¯" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "è¦èŽ·å–的属性" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "属性" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "ä¸è¦è·Ÿéšç¬¦å·é“¾æŽ¥" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "属性:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "显示å称:%s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "编辑å称:%s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "å称:%s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "类型:%s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "大å°ï¼š" + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "éšè—\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri:%s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "本地路径: %s\n" + +#: gio/gio-tool-info.c:205 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "UNIX 挂载:%s%s %s %s %s\n" + +#: gio/gio-tool-info.c:286 +msgid "Settable attributes:\n" +msgstr "å¯è®¾ç½®çš„属性:\n" + +#: gio/gio-tool-info.c:310 +msgid "Writable attribute namespaces:\n" +msgstr "å¯å†™çš„属性命å空间:\n" + +#: gio/gio-tool-info.c:345 +msgid "Show information about locations." +msgstr "显示ä½ç½®ä¿¡æ¯ã€‚" + +#: gio/gio-tool-info.c:347 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info 如传统 ls 程åºé‚£æ ·å·¥ä½œï¼Œä½†ä½¿ç”¨ GIO ä½ç½®è€Œéžæœ¬åœ°æ–‡ä»¶ï¼š\n" +"例如,你å¯ä»¥æŒ‡å®š smb://server/resource/file.txt 之类的ä½ç½®ã€‚è¦æŒ‡å®š\n" +"文件属性,å¯ä½¿ç”¨å…¶ GIO å称(如 standard::icon),也å¯ä»¥ä½¿ç”¨å‘½å\n" +"空间(如 unix),也å¯ä½¿ç”¨â€œ*â€åŒ¹é…全部" + +#. Translators: commandline placeholder +#: gio/gio-tool-launch.c:54 +msgid "DESKTOP-FILE [FILE-ARG …]" +msgstr "æ¡Œé¢æ–‡ä»¶ [æ–‡ä»¶å‚æ•° …]" + +#: gio/gio-tool-launch.c:57 +msgid "" +"Launch an application from a desktop file, passing optional filename " +"arguments to it." +msgstr "ä»Žæ¡Œé¢æ–‡ä»¶å¯åŠ¨åº”ç”¨ç¨‹åºï¼Œå¹¶å‘其传递å¯é€‰çš„æ–‡ä»¶å傿•°ã€‚" + +#: gio/gio-tool-launch.c:77 +msgid "No desktop file given" +msgstr "æœªç»™å®šæ¡Œé¢æ–‡ä»¶" + +#: gio/gio-tool-launch.c:85 +msgid "The launch command is not currently supported on this platform" +msgstr "当å‰å¹³å°å°šä¸æ”¯æŒè¯¥å¯åЍ命令" + +#: gio/gio-tool-launch.c:98 +#, c-format +msgid "Unable to load ‘%s‘: %s" +msgstr "无法加载“%sâ€ï¼š%s" + +#: gio/gio-tool-launch.c:107 +#, c-format +msgid "Unable to load application information for ‘%s‘" +msgstr "无法加载“%sâ€çš„应用程åºä¿¡æ¯" + +#: gio/gio-tool-launch.c:119 +#, c-format +msgid "Unable to launch application ‘%s’: %s" +msgstr "无法å¯åŠ¨åº”ç”¨ç¨‹åºâ€œ%sâ€: %s" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "显示éšè—文件" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "使用长列表格å¼" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "显示åç§°" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "显示完整 URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "列出ä½ç½®ä¸­çš„内容。" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list 如传统 ls 程åºé‚£æ ·å·¥ä½œï¼Œä½†ä½¿ç”¨ GIO ä½ç½®è€Œéžæœ¬åœ°æ–‡ä»¶ï¼š\n" +"例如,你å¯ä»¥æŒ‡å®š smb://server/resource/file.txt 之类的ä½ç½®ã€‚è¦æŒ‡å®š\n" +"文件属性,å¯ä½¿ç”¨å…¶ GIO å称(如 standard::icon)" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIME 类型" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "处ç†ç¨‹åº" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "èŽ·å–æˆ–设置æŸä¸€ MIME 类型的处ç†ç¨‹åºã€‚" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"如果没有给定的处ç†ç¨‹åºï¼Œåˆ—出 MIME 类型已注册和推èçš„\n" +"应用程åºã€‚如果已给定处ç†ç¨‹åºï¼Œå®ƒå°†è¢«è®¾ä¸º MIME 类型的\n" +"默认应用程åºã€‚" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "必须指定一个 MIME 类型,也å¯åŒæ—¶æŒ‡å®šå¤„ç†ç¨‹åº" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "未设置用于“%sâ€çš„默认应用程åº\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "用于“%sâ€çš„默认应用程åºï¼š%s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "已注册的应用程åºï¼š\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "无已注册的应用程åº\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "推è的应用程åºï¼š\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "无推è的应用程åº\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "载入处ç†ç¨‹åºâ€œ%sâ€çš„ä¿¡æ¯å¤±è´¥" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "将“%sâ€è®¾ç½®ä¸ºâ€œ%sâ€çš„默认处ç†ç¨‹åºå¤±è´¥ï¼š%s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "创建上级目录" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "创建目录。" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir 如传统 mkdir 程åºé‚£æ ·å·¥ä½œï¼Œä½†ä½¿ç”¨ GIO ä½ç½®è€Œéžæœ¬åœ°æ–‡ä»¶ï¼š\n" +"例如,你å¯ä»¥æŒ‡å®š smb://server/resource/mydir 之类的ä½ç½®ã€‚" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "监视目录(默认:å–决于类型)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "监视文件(默认:å–决于类型)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "直接监视文件(通过硬链接通知更改)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "ç›´æŽ¥ç›‘è§†æ–‡ä»¶ï¼Œä½†ä¸æŠ¥å‘Šæ›´æ”¹" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "将移动和é‡å‘½å报告为简å•的删除/创建事件" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "监视挂载事件" + +#: gio/gio-tool-monitor.c:209 +msgid "Monitor files or directories for changes." +msgstr "监视文件和目录更改。" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "æŒ‚è½½ä¸ºå¯æŒ‚载项" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "使用设备文件或其他标识挂载å·" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "å¸è½½" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "弹出" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "ä½¿ç”¨è®¾å¤‡æ–‡ä»¶åœæ­¢é©±åЍ噍" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "设备" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "按给定方案里å¸è½½æ‰€æœ‰æŒ‚载项" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "方案" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "å¸è½½æˆ–弹出时忽略正在进行的文件æ“作" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "è®¤è¯æ—¶ä½¿ç”¨åŒ¿å用户" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "列出" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "监视事件" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "显示附加信æ¯" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "è§£é” VeraCrypt å·çš„æ•°å­— PIM" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "挂载 TCRYPT éšè—å·" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "挂载 TCRYPT 系统å·" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "匿å访问被拒ç»" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "没有对应设备文件的驱动器" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "没有对应IDçš„å·" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "挂载或å¸è½½ä½ç½®ã€‚" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "ä¸è¦ä½¿ç”¨å¤åˆ¶å’Œåˆ é™¤æ›¿ä»£æ–¹æ¡ˆ" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "将一个或多个文件从æºå¤´å¤åˆ¶åˆ°ç›®æ ‡ã€‚" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move 如传统 mv 程åºé‚£æ ·å·¥ä½œï¼Œä½†ä½¿ç”¨ GIO ä½ç½®è€Œéžæœ¬åœ°æ–‡ä»¶ï¼š\n" +"例如,你å¯ä»¥æŒ‡å®š smb://server/resource/file.txt 之类的ä½ç½®" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "目标 %s 䏿˜¯ç›®å½•" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"ä½¿ç”¨å·²æ³¨å†Œä¸ºå¤„ç†æ­¤ç±»åž‹æ–‡ä»¶çš„\n" +"é»˜è®¤åº”ç”¨ç¨‹åºæ‰“开文件。" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:33 +msgid "Ignore nonexistent files, never prompt" +msgstr "忽略ä¸å­˜åœ¨çš„æ–‡ä»¶ï¼Œä»Žä¸æç¤º" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "删除指定文件。" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "åç§°" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "é‡å‘½å文件。" + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "ç¼ºå°‘å‚æ•°" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "傿•°è¿‡å¤š" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "é‡å‘½åæˆåŠŸã€‚æ–° uri:%s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "ä¸å­˜åœ¨æ—¶æ‰åˆ›å»º" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "追加到文件末尾" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "创建时é™åˆ¶å½“å‰ç”¨æˆ·çš„访问" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "æ›¿æ¢æ—¶å‡å®šç›®æ ‡ä¸å­˜åœ¨" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "åœ¨æœ«å°¾æ‰“å°æ–° etag" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "文件的 etag 被覆盖" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "è¯»å–æ ‡å‡†è¾“入时出错" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag ä¸å¯ç”¨\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "è¯»å–æ ‡å‡†è¾“入并ä¿å­˜åˆ°ç›®æ ‡ã€‚" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "未给定目标" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "属性类型" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "类型" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "属性" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "值" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "设置ä½ç½®çš„æ–‡ä»¶å±žæ€§ã€‚" + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "未指定ä½ç½®" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "未指定属性" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "未指定值" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "无效的属性类型“%sâ€" + +#: gio/gio-tool-trash.c:34 +msgid "Empty the trash" +msgstr "清空回收站" + +#: gio/gio-tool-trash.c:35 +msgid "List files in the trash with their original locations" +msgstr "列出回收站中的文件以åŠå®ƒä»¬çš„原始ä½ç½®" + +#: gio/gio-tool-trash.c:36 +msgid "" +"Restore a file from trash to its original location (possibly recreating the " +"directory)" +msgstr "还原回收站文件到它的原始ä½ç½®ï¼ˆå¦‚果需è¦ï¼Œåˆ›å»ºæ–°ç›®å½•)" + +#: gio/gio-tool-trash.c:106 +msgid "Unable to find original path" +msgstr "无法找到原始路径" + +#: gio/gio-tool-trash.c:123 +msgid "Unable to recreate original location: " +msgstr "无法创建原始ä½ç½®ï¼š" + +#: gio/gio-tool-trash.c:136 +msgid "Unable to move file to its original location: " +msgstr "无法移动文件回它的原始ä½ç½®ï¼š" + +#: gio/gio-tool-trash.c:225 +msgid "Move/Restore files or directories to the trash." +msgstr "移动/还原文件或目录到回收站。" + +#: gio/gio-tool-trash.c:227 +msgid "" +"Note: for --restore switch, if the original location of the trashed file \n" +"already exists, it will not be overwritten unless --force is set." +msgstr "" +"注æ„:对于 --restore 开关,如果回收站中的文件的原始路径已ç»å­˜åœ¨ï¼Œ\n" +"除éžé¢å¤–指定了 --force 傿•°ï¼Œå·²å­˜åœ¨çš„æ–‡ä»¶å°†ä¸ä¼šè¢«è¦†ç›–。" + +#: gio/gio-tool-trash.c:258 +msgid "Location given doesn't start with trash:///" +msgstr "给定的ä½ç½®æ²¡æœ‰ä»¥ trash:/// 开头" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "跟踪符å·é“¾æŽ¥ã€æŒ‚载点åŠå¿«æ·æ–¹å¼" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "使用树状格å¼åˆ—出目录内容。" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "在 <%2$s> 中ä¸å…许元素 <%1$s>" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "顶层中ä¸å…许元素 <%s>" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "文件 %s 在资æºä¸­å‡ºçŽ°äº†å¤šæ¬¡" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "在所有æºç›®å½•中定ä½â€œ%sâ€å¤±è´¥" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "在当å‰ç›®å½•定ä½â€œ%sâ€å¤±è´¥" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "未知的处ç†é€‰é¡¹â€œ%sâ€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "请求了 %s 预处ç†ï¼Œä½†æœªè®¾å®š %s,且 %s ä¸åœ¨ PATH 内" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "è¯»å–æ–‡ä»¶ %s 出错:%s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "压缩文件时出错:%s" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "<%s> 内ä¸åº”出现文本" + +#: gio/glib-compile-resources.c:819 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "显示程åºç‰ˆæœ¬å¹¶é€€å‡º" + +#: gio/glib-compile-resources.c:820 +msgid "Name of the output file" +msgstr "输出文件的åç§°" + +#: gio/glib-compile-resources.c:821 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "FILE 中引用的è¦ä»Žå…¶ä¸­è½½å…¥æ–‡ä»¶çš„目录(默认为当å‰ç›®å½•)" + +#: gio/glib-compile-resources.c:821 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "目录" + +#: gio/glib-compile-resources.c:822 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "ä»¥ç›®æ ‡æ–‡ä»¶æ‰©å±•åæ‰€é€‰æ‹©çš„æ ¼å¼ç”Ÿæˆè¾“出" + +#: gio/glib-compile-resources.c:823 +msgid "Generate source header" +msgstr "ç”Ÿæˆæºç å¤´æ–‡ä»¶" + +#: gio/glib-compile-resources.c:824 +msgid "Generate source code used to link in the resource file into your code" +msgstr "生æˆç”¨äºŽå°†èµ„æºæ–‡ä»¶é“¾æŽ¥åˆ°æ‚¨ä»£ç çš„æºä»£ç " + +#: gio/glib-compile-resources.c:825 +msgid "Generate dependency list" +msgstr "生æˆä¾èµ–关系列表" + +#: gio/glib-compile-resources.c:826 +msgid "Name of the dependency file to generate" +msgstr "è¦ç”Ÿæˆçš„ä¾èµ–文件åç§°" + +#: gio/glib-compile-resources.c:827 +msgid "Include phony targets in the generated dependency file" +msgstr "在生æˆçš„ä¾èµ–关系文件中包å«ä¼ªç›®æ ‡" + +#: gio/glib-compile-resources.c:828 +msgid "Don’t automatically create and register resource" +msgstr "ä¸è¦è‡ªåŠ¨åˆ›å»ºå’Œæ³¨å†Œèµ„æº" + +#: gio/glib-compile-resources.c:829 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "ä¸è¦å¯¼å‡ºå‡½æ•°ï¼›è¯·å°†å®ƒä»¬å£°æ˜Žä¸º G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:830 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "ä¸è¦åœ¨ C æ–‡ä»¶é‡ŒåµŒå…¥èµ„æºæ•°æ®ï¼›è€Œå‡å®šå®ƒæ˜¯ä»¥å¤–部连接的" + +#: gio/glib-compile-resources.c:831 +msgid "C identifier name used for the generated source code" +msgstr "用于生æˆçš„æºä»£ç çš„ C 标识符åç§°" + +#: gio/glib-compile-resources.c:832 +msgid "The target C compiler (default: the CC environment variable)" +msgstr "目标 C 编译器(默认:CC 环境å˜é‡ï¼‰" + +#: gio/glib-compile-resources.c:858 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"将一份资æºè§„æ ¼ç¼–è¯‘ä¸ºèµ„æºæ–‡ä»¶ã€‚\n" +"资æºè§„格文件以 .gresource.xml 为扩展å,\n" +"èµ„æºæ–‡ä»¶ä»¥ .gresource 为扩展å。" + +#: gio/glib-compile-resources.c:880 +msgid "You should give exactly one file name\n" +msgstr "您应该给定一个且åªèƒ½ä¸€ä¸ªæ–‡ä»¶å\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "昵称必须至少 2 个字符" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "无效的数值" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " 已指定" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' 已指定" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "标志值最多åªèƒ½è®¾ç½® 1 ä½" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> 必须包å«è‡³å°‘一个 " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> ä¸åœ¨æŒ‡å®šçš„范围内" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> 䏿˜¯æŒ‡å®šæžšä¸¾ç±»åž‹çš„æœ‰æ•ˆæˆå‘˜" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> 包å«äº†ä¸åœ¨æŒ‡å®šæ ‡å¿—类型里的字符串" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> 包å«äº†ä¸åœ¨ 里的字符串" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr "此键已被指定为 " + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "“%sâ€ç±»åž‹çš„é”®ä¸å…许 " + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " 指定的最å°å€¼æ¯”最大值还大" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "䏿”¯æŒçš„ l10n 目录:%s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "已请求 l10n,但未给定 gettext 域" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "值给定的翻译上下文未å¯ç”¨ l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "è§£æžç±»åž‹â€œ%sâ€çš„ 值失败:" + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "无法为标记为枚举类型的键指定 " + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr "此键已被指定为 " + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr "“%sâ€ç±»åž‹çš„é”®ä¸å…许 " + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " 已给定" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " 必须包å«è‡³å°‘一个 " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr "此键已被指定为 " + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr " åªèƒ½è¢«æŒ‡å®šåœ¨æžšä¸¾æˆ–标志类型的键上,或是在 之åŽçš„é”®" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "给定了 ,但“%sâ€å·²ç»æ˜¯æžšä¸¾ç±»åž‹çš„æˆå‘˜" + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "给定了 ,但 已给定" + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " 已指定" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "别å目标“%sâ€ä¸åœ¨æžšä¸¾ç±»åž‹å†…" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "别å目标“%sâ€ä¸åœ¨ 内" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " 必须包å«è‡³å°‘一个 " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "ä¸å…许空åç§°" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "无效å称“%sâ€ï¼šå称必须以å°å†™å­—æ¯å¼€å§‹" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "无效å称“%sâ€ï¼šæ— æ•ˆçš„字符“%câ€ï¼›ä»…å…许使用å°å†™å­—æ¯ã€æ•°å­—和连字符(“-â€ï¼‰" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "无效å称“%sâ€ï¼šä¸å…许使用连续的连字符(“--â€ï¼‰" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "无效å称“%sâ€ï¼šæœ€åŽä¸€ä¸ªå­—符串ä¸åº”为连字符(“-â€ï¼‰ã€‚" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "无效å称“%sâ€ï¼šæœ€å¤§é•¿åº¦ä¸º 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " 已指定" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "无法添加键到一个“list-ofâ€æž¶æž„" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " 已指定" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" 与 在 é‡åˆ; 请使用 " +" 修改其值" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "“typeâ€ã€â€œenumâ€æˆ–“flagsâ€ä¸­å¿…须有一个被指定为 的属性" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> 尚未定义。" + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "无效的 GVariant 类型字符串“%sâ€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "已给定 但架构并未扩展" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "æ—  å¯è¦†ç›–" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " 已指定" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " 已指定" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " 扩展了尚ä¸å­˜åœ¨çš„æž¶æž„“%sâ€" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " 是尚ä¸å­˜åœ¨çš„æž¶æž„“%sâ€çš„列表" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "ä¸èƒ½æ˜¯å¸¦æœ‰è·¯å¾„架构的列表" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "无法扩展带有路径的架构" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " 是一个列表,扩展的 䏿˜¯åˆ—表" + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" 扩展 ,但“%sâ€ä¸æ‰©" +"展“%sâ€" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "一个路径,如果给定则必须以斜线(/)开始和结æŸ" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "一个列表的路径必须以“:/â€ç»“æŸ" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"警告:架构“%sâ€å¸¦æœ‰è·¯å¾„“%sâ€ã€‚以“/apps/â€ã€â€œ/desktop/â€æˆ–“/system/â€å¼€å¤´çš„路径已弃" +"用。" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> 已指定" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "在 <%2$s> 中仅å…许一个æˆå‘˜ <%1$s>" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "顶层中ä¸å…许元素 <%s>" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr " 里ä¸éœ€è¦å…ƒç´  " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "<%s> 内ä¸åº”出现文本" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "警告:到 的引用未定义" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "指定了 --strict;正在退出。" + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "整个文件被忽略。" + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "正在忽略此文件。" + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "覆盖文件“%3$sâ€ä¸­æŒ‡å®šçš„æž¶æž„“%2$sâ€ä¸­æ²¡æœ‰é”®â€œ%1$sâ€ï¼›æ­£åœ¨å¿½ç•¥å¯¹æ­¤é”®çš„覆盖。" + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"覆盖文件“%3$sâ€ä¸­æŒ‡å®šçš„æž¶æž„“%2$sâ€ä¸­æ²¡æœ‰é”®â€œ%1$sâ€å¹¶ä¸”已指定 --strict;正在退出。" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"无法为架构“%2$sâ€ä¸­çš„局部键“%1$sâ€æä¾›æ¯ä¸ªæ¡Œé¢çš„覆盖(覆盖文件“%3$sâ€ï¼‰ï¼›æ­£åœ¨å¿½" +"略对此键的覆盖。" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"无法为架构“%2$sâ€ä¸­çš„局部键“%1$sâ€æä¾›æ¯ä¸ªæ¡Œé¢çš„覆盖(覆盖文件“%3$sâ€ï¼‰å¹¶ä¸”已指" +"定 --strict;正在退出。" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"è§£æžè¦†ç›–文件“%3$sâ€æ‰€æŒ‡å®šæž¶æž„“%2$sâ€ä¸­çš„键“%1$sâ€æ—¶å‡ºé”™ï¼š%4$s。正在忽略对此键的" +"覆盖。" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"è§£æžè¦†ç›–文件“%3$sâ€æ‰€æŒ‡å®šæž¶æž„“%2$sâ€ä¸­çš„键“%1$sâ€æ—¶å‡ºé”™ï¼š%4$s。已指定 --strictï¼›" +"正在退出。" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"覆盖文件“%3$sâ€ä¸­æž¶æž„“%2$sâ€çš„键“%1$sâ€çš„覆盖超出了架构给出的范围;正在忽略对此" +"键的覆盖。" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"覆盖文件“%3$sâ€ä¸­æž¶æž„“%2$sâ€çš„键“%1$sâ€çš„覆盖超出了架构给出的范围并且已指定 --" +"strict;正在退出。" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"覆盖文件“%3$sâ€ä¸­æž¶æž„“%2$sâ€çš„键“%1$sâ€çš„覆盖的值ä¸åœ¨æœ‰æ•ˆå€¼åˆ—表内;正在忽略对此" +"键的覆盖。" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"覆盖文件“%3$sâ€ä¸­æž¶æž„“%2$sâ€çš„键“%1$sâ€çš„覆盖的值ä¸åœ¨æœ‰æ•ˆå€¼åˆ—表内并且已指定 --" +"strict;正在退出。" + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "gschemas.compiled 文件存储于何处" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "在架构里出现任何错误时中止" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "ä¸è¦å¯¹ gschema.compiled 进行写æ“作" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "ä¸è¦å¼ºåˆ¶é”®åçš„é™åˆ¶" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"编译所有的 GSettings 架构文件为架构缓存。\n" +"è¦ä½¿ç”¨æ‰©å±• .gschema.xmlï¼Œéœ€è¦æœ‰æž¶æž„文件,\n" +"缓存文件被称为 gschemas.compiled。" + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "您应该给出一个且仅一个的目录å" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "未找到架构文件:无事å¯åšã€‚" + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "未找到架构文件:已删除存在的输出文件。" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "无效的文件å %s" + +#: gio/glocalfile.c:982 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "è¯»å– %s æ–‡ä»¶ç³»ç»Ÿä¿¡æ¯æ—¶å‡ºé”™ï¼š%s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1123 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "找ä¸åˆ°æ–‡ä»¶ %s 包å«çš„æŒ‚è½½" + +#: gio/glocalfile.c:1146 +msgid "Can’t rename root directory" +msgstr "无法é‡å‘½å根目录" + +#: gio/glocalfile.c:1164 gio/glocalfile.c:1187 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "é‡å‘½å文件 %s 时出错:%s" + +#: gio/glocalfile.c:1171 +msgid "Can’t rename file, filename already exists" +msgstr "无法é‡å‘½å文件,该文件å已存在" + +#: gio/glocalfile.c:1184 gio/glocalfile.c:2380 gio/glocalfile.c:2408 +#: gio/glocalfile.c:2547 gio/glocalfileoutputstream.c:656 +msgid "Invalid filename" +msgstr "无效的文件å" + +#: gio/glocalfile.c:1352 gio/glocalfile.c:1363 +#, c-format +msgid "Error opening file %s: %s" +msgstr "打开文件 %s 时出错:%s" + +#: gio/glocalfile.c:1488 +#, c-format +msgid "Error removing file %s: %s" +msgstr "删除文件 %s 时出错:%s" + +#: gio/glocalfile.c:1982 gio/glocalfile.c:1993 gio/glocalfile.c:2020 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "将文件 %s 丢到回收站时出错:%s" + +#: gio/glocalfile.c:2040 +#, c-format +msgid "Unable to create trash directory %s: %s" +msgstr "无法创建回收站目录 %s:%s" + +#: gio/glocalfile.c:2061 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "找ä¸åˆ°å›žæ”¶ç«™ %s 的顶级目录" + +#: gio/glocalfile.c:2069 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "䏿”¯æŒåœ¨ç³»ç»Ÿå†…部挂载上的丢弃到回收站æ“作" + +#: gio/glocalfile.c:2155 gio/glocalfile.c:2183 +#, c-format +msgid "Unable to find or create trash directory %s to trash %s" +msgstr "无法找到或创建回收站目录 %s æ¥ä¸¢å¼ƒ %s" + +#: gio/glocalfile.c:2229 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "为 %s åˆ›å»ºå›žæ”¶ç«™ä¿¡æ¯æ–‡ä»¶å¤±è´¥ï¼š%s" + +#: gio/glocalfile.c:2291 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "无法跨越文件系统边界将文件 %s 丢到回收站" + +#: gio/glocalfile.c:2295 gio/glocalfile.c:2351 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "无法将文件 %s 丢到回收站:%s" + +#: gio/glocalfile.c:2357 +#, c-format +msgid "Unable to trash file %s" +msgstr "无法将文件 %s 丢到回收站" + +#: gio/glocalfile.c:2383 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "创建目录 %s 时出错:%s" + +#: gio/glocalfile.c:2412 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "æ–‡ä»¶ç³»ç»Ÿä¸æ”¯æŒç¬¦å·é“¾æŽ¥" + +#: gio/glocalfile.c:2415 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "创建符å·é“¾æŽ¥ %s 时出错:%s" + +#: gio/glocalfile.c:2458 gio/glocalfile.c:2493 gio/glocalfile.c:2550 +#, c-format +msgid "Error moving file %s: %s" +msgstr "移动文件 %s 时出错:%s" + +#: gio/glocalfile.c:2481 +msgid "Can’t move directory over directory" +msgstr "无法将目录移动到目录" + +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:1108 +#: gio/glocalfileoutputstream.c:1122 gio/glocalfileoutputstream.c:1137 +#: gio/glocalfileoutputstream.c:1154 gio/glocalfileoutputstream.c:1168 +msgid "Backup file creation failed" +msgstr "备份文件创建失败" + +#: gio/glocalfile.c:2526 +#, c-format +msgid "Error removing target file: %s" +msgstr "移除目标文件出错:%s" + +#: gio/glocalfile.c:2540 +msgid "Move between mounts not supported" +msgstr "䏿”¯æŒåœ¨æŒ‚载之间移动" + +#: gio/glocalfile.c:2714 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "无法确定 %s çš„ç£ç›˜ä½¿ç”¨æƒ…况:%s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "属性值必须为éžç©º" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "无效的属性类型(应为字符串)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "无效的扩展属性å" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "设置扩展属性“%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/glocalfileinfo.c:1709 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr " (无效的编ç ï¼‰" + +#: gio/glocalfileinfo.c:1868 gio/glocalfileoutputstream.c:943 +#: gio/glocalfileoutputstream.c:995 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "èŽ·å–æ–‡ä»¶â€œ%sâ€çš„ä¿¡æ¯æ—¶å‡ºé”™ï¼š%s" + +#: gio/glocalfileinfo.c:2134 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "èŽ·å–æ–‡ä»¶æè¿°ç¬¦çš„ä¿¡æ¯æ—¶å‡ºé”™ï¼š%s" + +#: gio/glocalfileinfo.c:2179 +msgid "Invalid attribute type (uint32 expected)" +msgstr "无效的属性类型(应为 uint32)" + +#: gio/glocalfileinfo.c:2197 +msgid "Invalid attribute type (uint64 expected)" +msgstr "无效的属性类型(应为 uint64)" + +#: gio/glocalfileinfo.c:2216 gio/glocalfileinfo.c:2235 +msgid "Invalid attribute type (byte string expected)" +msgstr "无效的属性类型(应为字节字符串)" + +#: gio/glocalfileinfo.c:2282 +msgid "Cannot set permissions on symlinks" +msgstr "无法为符å·é“¾æŽ¥è®¾ç½®æƒé™" + +#: gio/glocalfileinfo.c:2298 +#, c-format +msgid "Error setting permissions: %s" +msgstr "设置访问æƒé™å‡ºé”™ï¼š%s" + +#: gio/glocalfileinfo.c:2349 +#, c-format +msgid "Error setting owner: %s" +msgstr "设置所有者出错:%s" + +#: gio/glocalfileinfo.c:2372 +msgid "symlink must be non-NULL" +msgstr "符å·é“¾æŽ¥å¿…须是éžç©º" + +#: gio/glocalfileinfo.c:2382 gio/glocalfileinfo.c:2401 +#: gio/glocalfileinfo.c:2412 +#, c-format +msgid "Error setting symlink: %s" +msgstr "设置符å·é“¾æŽ¥å‡ºé”™ï¼š%s" + +#: gio/glocalfileinfo.c:2391 +msgid "Error setting symlink: file is not a symlink" +msgstr "设定符å·é“¾æŽ¥å‡ºé”™ï¼šæ–‡ä»¶ä¸æ˜¯ç¬¦å·é“¾æŽ¥" + +#: gio/glocalfileinfo.c:2463 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "é¢å¤–的纳秒数字 %d 在 UNIX 时间戳 %lld 中是负值" + +#: gio/glocalfileinfo.c:2472 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "é¢å¤–的纳秒数字 %d 在 UNIX 时间戳 %lld 中长度已达到一秒钟" + +#: gio/glocalfileinfo.c:2482 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX 时间戳 %lld 无法作为 64 比特数æ®å­˜å‚¨" + +#: gio/glocalfileinfo.c:2493 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "UNIX 时间戳 %lld ä½äºŽ Windows 所支æŒçš„范围之外" + +#: gio/glocalfileinfo.c:2570 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "文件å“%sâ€ä¸èƒ½è½¬æ¢ä¸º UTF-16" + +#: gio/glocalfileinfo.c:2589 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "无法打开文件“%sâ€ï¼šWindows 错误 %lu" + +#: gio/glocalfileinfo.c:2602 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "设置文件“%sâ€çš„修改或访问时间时出错:%lu" + +#: gio/glocalfileinfo.c:2703 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "设置修改或访问时间时出错:%s" + +#: gio/glocalfileinfo.c:2726 +msgid "SELinux context must be non-NULL" +msgstr "SELinux 上下文必须是éžç©º" + +#: gio/glocalfileinfo.c:2733 +msgid "SELinux is not enabled on this system" +msgstr "此系统尚未å¯ç”¨ SELinux" + +#: gio/glocalfileinfo.c:2743 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "设置 SELinux 上下文出错:%s" + +#: gio/glocalfileinfo.c:2836 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "䏿”¯æŒè®¾ç½®å±žæ€§ %s" + +#: gio/glocalfileinputstream.c:163 gio/glocalfileoutputstream.c:801 +#, c-format +msgid "Error reading from file: %s" +msgstr "è¯»å–æ–‡ä»¶å‡ºé”™ï¼š%s" + +#: gio/glocalfileinputstream.c:194 gio/glocalfileoutputstream.c:353 +#: gio/glocalfileoutputstream.c:447 +#, c-format +msgid "Error closing file: %s" +msgstr "关闭文件出错:%s" + +#: gio/glocalfileinputstream.c:272 gio/glocalfileoutputstream.c:563 +#: gio/glocalfileoutputstream.c:1186 +#, c-format +msgid "Error seeking in file: %s" +msgstr "åœ¨æ–‡ä»¶ä¸­å®šä½æ—¶å‡ºé”™ï¼š%s" + +#: gio/glocalfilemonitor.c:866 +msgid "Unable to find default local file monitor type" +msgstr "无法找到默认的本地文件监视器类型" + +#: gio/glocalfileoutputstream.c:220 gio/glocalfileoutputstream.c:298 +#: gio/glocalfileoutputstream.c:334 gio/glocalfileoutputstream.c:822 +#, c-format +msgid "Error writing to file: %s" +msgstr "写入文件出错:%s" + +#: gio/glocalfileoutputstream.c:380 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "移除旧的备份链接出错:%s" + +#: gio/glocalfileoutputstream.c:394 gio/glocalfileoutputstream.c:407 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "创建备份拷è´ï¼š%s" + +#: gio/glocalfileoutputstream.c:425 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "é‡å‘½å临时文件出错:%s" + +#: gio/glocalfileoutputstream.c:609 gio/glocalfileoutputstream.c:1237 +#, c-format +msgid "Error truncating file: %s" +msgstr "截断文件出错:%s" + +#: gio/glocalfileoutputstream.c:662 gio/glocalfileoutputstream.c:907 +#: gio/glocalfileoutputstream.c:1218 gio/gsubprocess.c:229 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "打开文件“%sâ€å‡ºé”™ï¼š%s" + +#: gio/glocalfileoutputstream.c:957 +msgid "Target file is a directory" +msgstr "目标文件是目录" + +#: gio/glocalfileoutputstream.c:971 +msgid "Target file is not a regular file" +msgstr "ç›®æ ‡æ–‡ä»¶ä¸æ˜¯æ™®é€šæ–‡ä»¶" + +#: gio/glocalfileoutputstream.c:1013 +msgid "The file was externally modified" +msgstr "文件已ç»è¢«å…¶ä»–程åºä¿®æ”¹" + +#: gio/glocalfileoutputstream.c:1202 +#, c-format +msgid "Error removing old file: %s" +msgstr "移除旧文件出错:%s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:762 +msgid "Invalid GSeekType supplied" +msgstr "æä¾›çš„ GSeekType 无效" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "无效的æœå¯»è¯·æ±‚" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "无法截断 GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:568 +msgid "Memory output stream not resizable" +msgstr "å†…å­˜è¾“å‡ºæµæ— æ³•改å˜å¤§å°" + +#: gio/gmemoryoutputstream.c:584 +msgid "Failed to resize memory output stream" +msgstr "改å˜å†…存输出æµå¤§å°å¤±è´¥" + +#: gio/gmemoryoutputstream.c:663 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "处ç†å†™å…¥æ‰€éœ€è¦çš„内存超过了å¯ç”¨çš„空间" + +#: gio/gmemoryoutputstream.c:772 +msgid "Requested seek before the beginning of the stream" +msgstr "请求的定ä½å€¼åœ¨æµçš„开始之å‰" + +#: gio/gmemoryoutputstream.c:787 +msgid "Requested seek beyond the end of the stream" +msgstr "请求的定ä½å€¼åœ¨æµçš„结æŸä¹‹åŽ" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "挂载未实现“unmountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "挂载未实现“ejectâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "挂载未实现“unmountâ€æˆ–“unmount_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "挂载未实现“ejectâ€æˆ–“eject_with_operationâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "挂载未实现“remountâ€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "挂载未实现内容类型猜测" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "æŒ‚è½½æœªå®žçŽ°åŒæ­¥å†…容类型猜测" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "主机å“%sâ€åŒ…å«â€œ[â€ä½†æ˜¯ç¼ºå°‘“]â€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "网络ä¸å¯è¾¾" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "主机ä¸å¯è¾¾" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "ä¸èƒ½åˆ›å»ºç½‘络监视器:%s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "无法创建网络监视器:" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "无法获å–网络状æ€ï¼š" + +#: gio/gnetworkmonitornm.c:311 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager 未在è¿è¡Œ" + +#: gio/gnetworkmonitornm.c:322 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager 版本太è€" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "è¾“å‡ºæµæœªå®žçް写入" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "传递给 %s çš„å‘é‡å’Œå¤ªå¤§" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "æºæµå·²ç»å…³é—­" + +#: gio/gresolver.c:401 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "è§£æžâ€œ%sâ€æ—¶å‡ºé”™ï¼š%s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:470 gio/gresolver.c:630 +#, c-format +msgid "%s not implemented" +msgstr "%s 尚未实现" + +#: gio/gresolver.c:999 gio/gresolver.c:1051 +msgid "Invalid domain" +msgstr "无效的域" + +#: gio/gresource.c:681 gio/gresource.c:943 gio/gresource.c:983 +#: gio/gresource.c:1107 gio/gresource.c:1179 gio/gresource.c:1253 +#: gio/gresource.c:1334 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "ä½äºŽâ€œ%sâ€çš„资æºä¸å­˜åœ¨" + +#: gio/gresource.c:848 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "解压ä½äºŽâ€œ%sâ€çš„资æºå¤±è´¥" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "“%sâ€å¤„的资æºä¸æ˜¯ä¸€ä¸ªç›®å½•" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "è¾“å…¥æµæœªå®žçŽ°å®šä½" + +#: gio/gresource-tool.c:500 +msgid "List sections containing resources in an elf FILE" +msgstr "列出 elf 文件中包å«èµ„æºçš„æ®µ" + +#: gio/gresource-tool.c:506 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"列出资æº\n" +"如果指定了段,则仅在此段中列出资æº\n" +"如果指定了路径,则仅列出匹é…的资æº" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 +msgid "FILE [PATH]" +msgstr "文件 [路径]" + +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 gio/gresource-tool.c:527 +msgid "SECTION" +msgstr "段" + +#: gio/gresource-tool.c:515 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"列出资æºå’Œè¯¦ç»†ä¿¡æ¯\n" +"如果指定了段,则仅列出此段中的资æº\n" +"如果指定了文件,则仅列出匹é…的资æº\n" +"详细信æ¯åŒ…括段ã€å¤§å°å’ŒåŽ‹ç¼©æƒ…å†µ" + +#: gio/gresource-tool.c:525 +msgid "Extract a resource file to stdout" +msgstr "æå–ä¸€ä¸ªèµ„æºæ–‡ä»¶åˆ°æ ‡å‡†è¾“出" + +#: gio/gresource-tool.c:526 +msgid "FILE PATH" +msgstr "文件 路径" + +#: gio/gresource-tool.c:540 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"用法:\n" +" gresource [--section 段] 命令 [傿•°â€¦]\n" +"\n" +"命令:\n" +" help 显示此信æ¯\n" +" sections åˆ—å‡ºèµ„æºæ®µ\n" +" list 列出资æº\n" +" details 列出资æºå’Œè¯¦ç»†ä¿¡æ¯\n" +" extract æå–æŸä¸ªèµ„æº\n" +"\n" +"使用“gresoure help 命令â€èŽ·å–详细帮助。\n" +"\n" + +#: gio/gresource-tool.c:554 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"用法:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:561 +msgid " SECTION An (optional) elf section name\n" +msgstr " 段 一个 elf 段å(å¯é€‰ï¼‰\n" + +#: gio/gresource-tool.c:565 gio/gsettings-tool.c:718 +msgid " COMMAND The (optional) command to explain\n" +msgstr " 命令 è¦è§£é‡Šçš„命令(å¯é€‰ï¼‰\n" + +#: gio/gresource-tool.c:571 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " 文件 一个 elf æ–‡ä»¶ï¼ˆå¯æ‰§è¡Œæ–‡ä»¶æˆ–共享库)\n" + +#: gio/gresource-tool.c:574 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" 文件 一个 elf æ–‡ä»¶ï¼ˆå¯æ‰§è¡Œæ–‡ä»¶æˆ–共享库)\n" +" æˆ–å·²ç¼–è¯‘çš„èµ„æºæ–‡ä»¶\n" + +#: gio/gresource-tool.c:578 +msgid "[PATH]" +msgstr "[路径]" + +#: gio/gresource-tool.c:580 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " 路径 (部分)资æºè·¯å¾„(å¯é€‰ï¼‰\n" + +#: gio/gresource-tool.c:581 +msgid "PATH" +msgstr "路径" + +#: gio/gresource-tool.c:583 +msgid " PATH A resource path\n" +msgstr " 路径 一个资æºè·¯å¾„\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:923 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "没有“%sâ€è¿™ä¸ªæž¶æž„\n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "“%sâ€æž¶æž„ä¸å¯é‡å®šä½ï¼ˆå¿…须指定路径)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "“%sâ€æž¶æž„å¯é‡å®šä½ï¼ˆå¿…须指定路径)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "给定的路径为空。\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "路径必须以斜æ å¼€å¤´ï¼ˆ/)\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "路径必须以斜æ ç»“æŸï¼ˆ/)\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "路径中ä¸èƒ½åŒ…å«è¿žç»­ä¸¤ä¸ªæ–œæ ï¼ˆ//)\n" + +#: gio/gsettings-tool.c:553 +msgid "The provided value is outside of the valid range\n" +msgstr "æä¾›çš„值ä¸åœ¨æœ‰æ•ˆèŒƒå›´å†…\n" + +#: gio/gsettings-tool.c:560 +msgid "The key is not writable\n" +msgstr "é”®ä¸å¯å†™\n" + +#: gio/gsettings-tool.c:596 +msgid "List the installed (non-relocatable) schemas" +msgstr "列出已安装的(ä¸å¯é‡å®šä½çš„)架构" + +#: gio/gsettings-tool.c:602 +msgid "List the installed relocatable schemas" +msgstr "列出安装的å¯é‡å®šä½çš„æž¶æž„" + +#: gio/gsettings-tool.c:608 +msgid "List the keys in SCHEMA" +msgstr "列出架构中的键" + +#: gio/gsettings-tool.c:609 gio/gsettings-tool.c:615 gio/gsettings-tool.c:658 +msgid "SCHEMA[:PATH]" +msgstr "æž¶æž„[:路径]" + +#: gio/gsettings-tool.c:614 +msgid "List the children of SCHEMA" +msgstr "列出架构的å­å¯¹è±¡" + +#: gio/gsettings-tool.c:620 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"递归列出键和值\n" +"如果没有给出架构,列出所有键\n" + +#: gio/gsettings-tool.c:622 +msgid "[SCHEMA[:PATH]]" +msgstr "æž¶æž„[:路径]" + +#: gio/gsettings-tool.c:627 +msgid "Get the value of KEY" +msgstr "获å–键的值" + +#: gio/gsettings-tool.c:628 gio/gsettings-tool.c:634 gio/gsettings-tool.c:640 +#: gio/gsettings-tool.c:652 gio/gsettings-tool.c:664 +msgid "SCHEMA[:PATH] KEY" +msgstr "æž¶æž„[:路径] é”®" + +#: gio/gsettings-tool.c:633 +msgid "Query the range of valid values for KEY" +msgstr "查询键的有效值范围" + +#: gio/gsettings-tool.c:639 +msgid "Query the description for KEY" +msgstr "查询键的æè¿°" + +#: gio/gsettings-tool.c:645 +msgid "Set the value of KEY to VALUE" +msgstr "将键的值设为给定的键值" + +#: gio/gsettings-tool.c:646 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "æž¶æž„[:路径] é”® 键值" + +#: gio/gsettings-tool.c:651 +msgid "Reset KEY to its default value" +msgstr "将键é‡è®¾ä¸ºé»˜è®¤å€¼" + +#: gio/gsettings-tool.c:657 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "é‡ç½®æž¶æž„中所有键为默认值" + +#: gio/gsettings-tool.c:663 +msgid "Check if KEY is writable" +msgstr "查看键是å¦å¯å†™" + +#: gio/gsettings-tool.c:669 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"监视键的更改。\n" +"如果没有指定键,则监视架构中的所有键。\n" +"使用 ^C åœæ­¢ç›‘视。\n" + +#: gio/gsettings-tool.c:672 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "æž¶æž„[:路径] [é”®]" + +#: gio/gsettings-tool.c:684 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"用法:\n" +" gsettings --version\n" +" gsettings [--schemadir 架构目录] 命令 [傿•°â€¦]\n" +"\n" +"命令:\n" +" help 显示此信æ¯\n" +" list-schemas 列出安装了的架构\n" +" list-relocatable-schemas 列出å¯é‡å®šä½çš„æž¶æž„\n" +" list-keys 列出æŸä¸ªæž¶æž„中的键\n" +" list-children 列出æŸä¸ªæž¶æž„çš„å­å¯¹è±¡\n" +" list-recursively 递归地列出键和值\n" +" range 查询æŸä¸ªé”®çš„范围\n" +" describe 查询æŸä¸ªé”®çš„æè¿°\n" +" get èŽ·å–æŸä¸ªé”®å€¼\n" +" set 设置æŸä¸ªé”®å€¼\n" +" reset é‡è®¾æŸä¸ªé”®å€¼\n" +" reset-recursively é‡è®¾æŒ‡å®šæž¶æž„中的所有值\n" +" writable 检查æŸä¸ªé”®æ˜¯å¦å¯å†™\n" +" monitor 监视更改\n" +"\n" +"使用“gsettings help å‘½ä»¤â€æŸ¥çœ‹è¯¦ç»†çš„帮助。\n" +"\n" + +#: gio/gsettings-tool.c:708 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"用法:\n" +" gsettings [--schemadir 架构目录] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:714 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " 架构目录 一个用于æœç´¢é™„加架构的目录\n" + +#: gio/gsettings-tool.c:722 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" æž¶æž„ 架构的åç§°\n" +" 路径 å¯é‡å®šä½æž¶æž„的路径\n" + +#: gio/gsettings-tool.c:727 +msgid " KEY The (optional) key within the schema\n" +msgstr " é”® 架构中(å¯é€‰ï¼‰çš„é”®\n" + +#: gio/gsettings-tool.c:731 +msgid " KEY The key within the schema\n" +msgstr " é”® 架构中的键\n" + +#: gio/gsettings-tool.c:735 +msgid " VALUE The value to set\n" +msgstr " 键值 è¦è®¾çš„值\n" + +#: gio/gsettings-tool.c:790 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "无法从 %s 加载架构:%s\n" + +#: gio/gsettings-tool.c:802 +msgid "No schemas installed\n" +msgstr "没有安装架构\n" + +#: gio/gsettings-tool.c:881 +msgid "Empty schema name given\n" +msgstr "给定了空的架构åç§°\n" + +#: gio/gsettings-tool.c:936 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "没有“%sâ€è¿™ä¸ªé”®\n" + +#: gio/gsocket.c:417 +msgid "Invalid socket, not initialized" +msgstr "无效的套接字,尚未åˆå§‹åŒ–" + +#: gio/gsocket.c:424 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "无效的套接字,åˆå§‹åŒ–失败的原因是:%s" + +#: gio/gsocket.c:432 +msgid "Socket is already closed" +msgstr "套接字已ç»å…³é—­" + +#: gio/gsocket.c:447 gio/gsocket.c:3194 gio/gsocket.c:4427 gio/gsocket.c:4485 +msgid "Socket I/O timed out" +msgstr "套接字 I/O è¶…æ—¶" + +# "fd" is abbr. of "File Descriptor", 文件æè¿°ç¬¦ +#: gio/gsocket.c:582 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "正在从文件æè¿°ç¬¦åˆ›å»º GSocket:%s" + +#: gio/gsocket.c:611 gio/gsocket.c:675 gio/gsocket.c:682 +#, c-format +msgid "Unable to create socket: %s" +msgstr "无法创建套接字:%s" + +#: gio/gsocket.c:675 +msgid "Unknown family was specified" +msgstr "指定了未知åè®®æ—" + +#: gio/gsocket.c:682 +msgid "Unknown protocol was specified" +msgstr "指定了未知åè®®" + +#: gio/gsocket.c:1173 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "æ— æ³•åœ¨éžæ•°æ®æŠ¥å¥—æŽ¥å­—ä¸Šä½¿ç”¨æ•°æ®æŠ¥æ“作。" + +#: gio/gsocket.c:1190 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "æ— æ³•åœ¨å·²è®¾ç½®è¶…æ—¶çš„å¥—æŽ¥å­—ä¸Šä½¿ç”¨æ•°æ®æŠ¥æ“作。" + +#: gio/gsocket.c:1997 +#, c-format +msgid "could not get local address: %s" +msgstr "æ— æ³•èŽ·å–æœ¬åœ°åœ°å€ï¼š%s" + +#: gio/gsocket.c:2043 +#, c-format +msgid "could not get remote address: %s" +msgstr "无法获å–远程地å€ï¼š %s" + +#: gio/gsocket.c:2109 +#, c-format +msgid "could not listen: %s" +msgstr "无法监å¬ï¼š%s" + +#: gio/gsocket.c:2213 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "ç»‘å®šåœ°å€æ—¶å‡ºé”™ï¼š%s: %s" + +#: gio/gsocket.c:2389 gio/gsocket.c:2426 gio/gsocket.c:2536 gio/gsocket.c:2561 +#: gio/gsocket.c:2624 gio/gsocket.c:2682 gio/gsocket.c:2700 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "加入多播组时出错:%s" + +#: gio/gsocket.c:2390 gio/gsocket.c:2427 gio/gsocket.c:2537 gio/gsocket.c:2562 +#: gio/gsocket.c:2625 gio/gsocket.c:2683 gio/gsocket.c:2701 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "退出多播组时出错:%s" + +#: gio/gsocket.c:2391 +msgid "No support for source-specific multicast" +msgstr "䏿”¯æŒæŒ‡å®šæºçš„多播" + +#: gio/gsocket.c:2538 +msgid "Unsupported socket family" +msgstr "䏿”¯æŒçš„套接字家æ—" + +#: gio/gsocket.c:2563 +msgid "source-specific not an IPv4 address" +msgstr "指定æºä¸æ˜¯ IPv4 地å€" + +#: gio/gsocket.c:2587 +#, c-format +msgid "Interface name too long" +msgstr "接å£å太长" + +#: gio/gsocket.c:2600 gio/gsocket.c:2650 +#, c-format +msgid "Interface not found: %s" +msgstr "未找到接å£ï¼š%s" + +#: gio/gsocket.c:2626 +msgid "No support for IPv4 source-specific multicast" +msgstr "䏿”¯æŒ IPv4 指定æºçš„多播" + +#: gio/gsocket.c:2684 +msgid "No support for IPv6 source-specific multicast" +msgstr "䏿”¯æŒ IPv6 指定æºçš„多播" + +#: gio/gsocket.c:2893 +#, c-format +msgid "Error accepting connection: %s" +msgstr "接å—连接时出错:%s" + +#: gio/gsocket.c:3019 +msgid "Connection in progress" +msgstr "连接进行中" + +#: gio/gsocket.c:3070 +msgid "Unable to get pending error: " +msgstr "æ— æ³•èŽ·å–æœªå†³çš„错误:" + +#: gio/gsocket.c:3259 +#, c-format +msgid "Error receiving data: %s" +msgstr "æŽ¥æ”¶æ•°æ®æ—¶å‡ºé”™ï¼š%s" + +#: gio/gsocket.c:3456 +#, c-format +msgid "Error sending data: %s" +msgstr "å‘逿•°æ®æ—¶å‡ºé”™ï¼š%s" + +#: gio/gsocket.c:3643 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "无法关闭套接字:%s" + +#: gio/gsocket.c:3724 +#, c-format +msgid "Error closing socket: %s" +msgstr "关闭套接字时出错:%s" + +#: gio/gsocket.c:4420 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "等待套接字状æ€ï¼š%s" + +#: gio/gsocket.c:4810 gio/gsocket.c:4826 gio/gsocket.c:4839 +#, c-format +msgid "Unable to send message: %s" +msgstr "无法å‘é€ä¿¡æ¯ï¼š%s" + +#: gio/gsocket.c:4811 gio/gsocket.c:4827 gio/gsocket.c:4840 +msgid "Message vectors too large" +msgstr "ä¿¡æ¯å‘é‡è¿‡å¤§" + +#: gio/gsocket.c:4856 gio/gsocket.c:4858 gio/gsocket.c:5005 gio/gsocket.c:5090 +#: gio/gsocket.c:5268 gio/gsocket.c:5308 gio/gsocket.c:5310 +#, c-format +msgid "Error sending message: %s" +msgstr "å‘é€ä¿¡æ¯æ—¶å‡ºé”™ï¼š%s" + +#: gio/gsocket.c:5032 +msgid "GSocketControlMessage not supported on Windows" +msgstr "Windows 䏿”¯æŒ GSocketControlMessage" + +#: gio/gsocket.c:5505 gio/gsocket.c:5581 gio/gsocket.c:5807 +#, c-format +msgid "Error receiving message: %s" +msgstr "接å—ä¿¡æ¯æ—¶å‡ºé”™ï¼š%s" + +#: gio/gsocket.c:6090 gio/gsocket.c:6101 gio/gsocket.c:6164 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "无法读å–套接字认è¯ä¿¡æ¯ï¼š%s" + +#: gio/gsocket.c:6173 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "æ­¤æ“作系统上没有实现 g_socket_get_credentials" + +#: gio/gsocketclient.c:191 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "æ— æ³•è¿žæŽ¥åˆ°ä»£ç†æœåС噍 %s:" + +#: gio/gsocketclient.c:205 +#, c-format +msgid "Could not connect to %s: " +msgstr "无法连接到 %s:" + +#: gio/gsocketclient.c:207 +msgid "Could not connect: " +msgstr "无法连接:" + +#: gio/gsocketclient.c:1202 gio/gsocketclient.c:1793 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "䏿”¯æŒé€šè¿‡éž TCP 连接的代ç†ã€‚" + +#: gio/gsocketclient.c:1234 gio/gsocketclient.c:1822 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "䏿”¯æŒä»£ç†å议“%sâ€ã€‚" + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "监å¬å™¨å·²å…³é—­" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "添加的套接字已关闭" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 䏿”¯æŒ IPv6 地å€â€œ%sâ€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "用户å对于 SOCKSv4 å议太长" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "主机å“%sâ€å¯¹äºŽ SOCKSv4 å议过长" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "æ­¤æœåС噍䏿˜¯ SOCKSv4 ä»£ç†æœåŠ¡å™¨ã€‚" + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "通过 SOCKSv4 æœåŠ¡å™¨è¿žæŽ¥è¢«æ‹’ç»" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "æ­¤æœåС噍䏿˜¯ SOCKSv5 ä»£ç†æœåŠ¡å™¨ã€‚" + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKSv5 ä»£ç†æœåŠ¡å™¨éœ€è¦è®¤è¯ã€‚" + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "æ­¤ SOCKSv5 连接需è¦ä¸€ç§ GLib 䏿”¯æŒçš„è®¤è¯æ–¹æ³•。" + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "ç”¨æˆ·åæˆ–密ç å¯¹äºŽ SOCKSv5 å议太长。" + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 认è¯å¤±è´¥ï¼šç”¨æˆ·å或密ç é”™è¯¯ã€‚" + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "主机å“%sâ€å¯¹äºŽ SOCKSv5 å议过长" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 ä»£ç†æœåŠ¡å™¨ä½¿ç”¨æœªçŸ¥åœ°å€ç±»åž‹ã€‚" + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "SOCKSv5 ä»£ç†æœåŠ¡å™¨å†…éƒ¨é”™è¯¯ã€‚" + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "规则集ä¸å…许 SOCKSv5 连接。" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "通过 SOCKSv5 æœåŠ¡å™¨ä¸»æœºä¸å¯è¾¾ã€‚" + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "通过 SOCKSv5 代ç†ç½‘络ä¸å¯è¾¾ã€‚" + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "通过 SOCKSv5 代ç†è¿žæŽ¥è¢«æ‹’ç»ã€‚" + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 代ç†ä¸æ”¯æŒâ€œconnectâ€å‘½ä»¤ã€‚" + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 代ç†ä¸æ”¯æŒæä¾›çš„地å€ç±»åž‹ã€‚" + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "未知 SOCKSv5 代ç†é”™è¯¯ã€‚" + +#: gio/gtestdbus.c:612 glib/gspawn-win32.c:314 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "创建与å­è¿›ç¨‹é€šè®¯çš„管é“失败(%s)" + +#: gio/gtestdbus.c:619 +#, c-format +msgid "Pipes are not supported in this platform" +msgstr "此平å°ä¸æ”¯æŒç®¡é“(pipe)" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "无法处ç†ç‰ˆæœ¬ä¸º %d çš„ GThemedIcon ç¼–ç " + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "找ä¸åˆ°åˆæ³•的地å€" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "åå‘è§£æžâ€œ%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "没有“%sâ€æ‰€è¯·æ±‚类型的 DNS 记录" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "暂时无法解æžâ€œ%sâ€" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "è§£æžâ€œ%sâ€æ—¶å‡ºé”™" + +#: gio/gtlscertificate.c:478 +msgid "No PEM-encoded private key found" +msgstr "未找到 PEM 加密的ç§é’¥" + +#: gio/gtlscertificate.c:488 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "无法解密 PEM 加密的ç§é’¥" + +#: gio/gtlscertificate.c:499 +msgid "Could not parse PEM-encoded private key" +msgstr "æ— æ³•è§£æž PEM 加密的ç§é’¥" + +#: gio/gtlscertificate.c:526 +msgid "No PEM-encoded certificate found" +msgstr "未找到 PEM 加密的è¯ä¹¦" + +#: gio/gtlscertificate.c:535 +msgid "Could not parse PEM-encoded certificate" +msgstr "æ— æ³•è§£æž PEM 加密的è¯ä¹¦" + +#: gio/gtlscertificate.c:796 +msgid "The current TLS backend does not support PKCS #12" +msgstr "当å‰çš„ TLS åŽç«¯ä¸æ”¯æŒ PKCS #12" + +#: gio/gtlscertificate.c:1013 +msgid "This GTlsBackend does not support creating PKCS #11 certificates" +msgstr "本 GTlsBackend 䏿”¯æŒåˆ›å»º PKCS #11 è¯ä¹¦" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "这是您的访问被é”å®šå‰æœ€åŽä¸€æ¬¡æœºä¼šè¾“入正确的密ç ã€‚" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "密ç å¤šæ¬¡è¾“入错误,您的访问将在数次错误输入åŽé”定。" + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "输入的密ç ä¸æ­£ç¡®ã€‚" + +#: gio/gunixconnection.c:125 +msgid "Sending FD is not supported" +msgstr "䏿”¯æŒå‘é€ FD" + +#: gio/gunixconnection.c:178 gio/gunixconnection.c:596 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "应为 1 个控件消æ¯ï¼Œå´å¾—到 %d 个" + +#: gio/gunixconnection.c:194 gio/gunixconnection.c:608 +msgid "Unexpected type of ancillary data" +msgstr "éžé¢„期的辅助数æ®ç±»åž‹" + +#: gio/gunixconnection.c:212 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "应为 1 个文件æè¿°ç¬¦ï¼Œå´å¾—到 %d 个\n" + +#: gio/gunixconnection.c:231 +msgid "Received invalid fd" +msgstr "收到无效文件æè¿°ç¬¦" + +#: gio/gunixconnection.c:238 +msgid "Receiving FD is not supported" +msgstr "䏿”¯æŒæŽ¥æ”¶ FD" + +#: gio/gunixconnection.c:380 +msgid "Error sending credentials: " +msgstr "å‘é€å‡­æ®æ—¶å‡ºé”™ï¼š" + +#: gio/gunixconnection.c:537 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "检查套接字是å¦å¯ç”¨ SO_PASSCRED 时出错:%s" + +#: gio/gunixconnection.c:553 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "å¯ç”¨ SO_PASSCRED 时出错:%s" + +#: gio/gunixconnection.c:582 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "期望为接收è¯ä¹¦è¯»åˆ°å•个字节但是åªè¯»åˆ°äº† 0 字节" + +#: gio/gunixconnection.c:622 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "未期望控制信æ¯ï¼Œå´å¾—到 %d 个" + +#: gio/gunixconnection.c:647 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "ç¦ç”¨ SO_PASSCRED 时出错:%s" + +#: gio/gunixinputstream.c:357 gio/gunixinputstream.c:378 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "从文件æè¿°ç¬¦è¯»å–时出错:%s" + +#: gio/gunixinputstream.c:411 gio/gunixoutputstream.c:520 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "关闭文件æè¿°ç¬¦æ—¶å‡ºé”™ï¼š%s" + +#: gio/gunixmounts.c:2782 gio/gunixmounts.c:2835 +msgid "Filesystem root" +msgstr "文件系统根目录" + +#: gio/gunixoutputstream.c:357 gio/gunixoutputstream.c:377 +#: gio/gunixoutputstream.c:464 gio/gunixoutputstream.c:484 +#: gio/gunixoutputstream.c:630 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "写入文件æè¿°ç¬¦æ—¶å‡ºé”™ï¼š%s" + +#: gio/gunixsocketaddress.c:251 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "æœ¬ç³»ç»Ÿä¸æ”¯æŒæŠ½è±¡ Unix 域套接字地å€" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "å·æœªå®žçŽ°å¼¹å‡º" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "å·æœªå®žçŽ°å¼¹å‡ºæˆ– eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "读å–奿Ÿ„时出错:%s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "关闭奿Ÿ„时出错:%s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "写入奿Ÿ„时出错:%s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "内存ä¸è¶³" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "内部错误:%s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "éœ€è¦æ›´å¤šè¾“å…¥" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "无效的压缩数æ®" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "è¦ç›‘å¬çš„地å€" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "已忽略,以与 GTestDbus 兼容" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "打å°åœ°å€" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "在 shell 模å¼ä¸­æ‰“å°åœ°å€" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "è¿è¡Œä¸€ä¸ª dbus æœåŠ¡" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "傿•°é”™è¯¯\n" + +#: glib/gbookmarkfile.c:777 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "元素“%2$sâ€çš„æ„å¤–å±žæ€§â€œ%1$sâ€" + +#: glib/gbookmarkfile.c:788 glib/gbookmarkfile.c:868 glib/gbookmarkfile.c:878 +#: glib/gbookmarkfile.c:991 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "元素“%2$sâ€çš„属性“%1$sâ€æœªæ‰¾åˆ°" + +#: glib/gbookmarkfile.c:1200 glib/gbookmarkfile.c:1265 +#: glib/gbookmarkfile.c:1329 glib/gbookmarkfile.c:1339 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "æ„外标签“%sâ€ï¼Œéœ€è¦æ ‡ç­¾â€œ%sâ€" + +#: glib/gbookmarkfile.c:1225 glib/gbookmarkfile.c:1239 +#: glib/gbookmarkfile.c:1307 glib/gbookmarkfile.c:1353 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "“%2$sâ€ä¸­æœ‰æ„外标签“%1$sâ€" + +#: glib/gbookmarkfile.c:1633 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "书签文件中有无效的日期/时间“%sâ€" + +#: glib/gbookmarkfile.c:1836 +msgid "No valid bookmark file found in data dirs" +msgstr "æ•°æ®ç›®å½•中没有找到有效的书签文件" + +#: glib/gbookmarkfile.c:2037 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "URI“%sâ€çš„书签已ç»å­˜åœ¨" + +#: glib/gbookmarkfile.c:2086 glib/gbookmarkfile.c:2244 +#: glib/gbookmarkfile.c:2329 glib/gbookmarkfile.c:2409 +#: glib/gbookmarkfile.c:2494 glib/gbookmarkfile.c:2628 +#: glib/gbookmarkfile.c:2761 glib/gbookmarkfile.c:2896 +#: glib/gbookmarkfile.c:2938 glib/gbookmarkfile.c:3035 +#: glib/gbookmarkfile.c:3156 glib/gbookmarkfile.c:3350 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3710 +#: glib/gbookmarkfile.c:3799 glib/gbookmarkfile.c:3888 +#: glib/gbookmarkfile.c:4007 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "未找到 URI“%sâ€çš„书签" + +#: glib/gbookmarkfile.c:2418 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "URI“%sâ€çš„书签未定义 MIME 类型" + +#: glib/gbookmarkfile.c:2503 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "URI“%sâ€çš„ä¹¦ç­¾æœªå®šä¹‰ç§æœ‰æ ‡å¿—" + +#: glib/gbookmarkfile.c:3044 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI“%sâ€çš„书签未设定组" + +#: glib/gbookmarkfile.c:3512 glib/gbookmarkfile.c:3720 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "没有å为“%sâ€çš„应用程åºä¸ºâ€œ%sâ€æ³¨å†Œäº†ä¹¦ç­¾" + +#: glib/gbookmarkfile.c:3743 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "用 URI“%2$sâ€å±•å¼€ exec 行“%1$sâ€å¤±è´¥" + +#: glib/gconvert.c:468 +msgid "Unrepresentable character in conversion input" +msgstr "转æ¢è¾“入中出现无法表达的字符" + +#: glib/gconvert.c:495 glib/gutf8.c:886 glib/gutf8.c:1099 glib/gutf8.c:1236 +#: glib/gutf8.c:1340 +msgid "Partial character sequence at end of input" +msgstr "输入末尾出现未尽字符åºåˆ—" + +#: glib/gconvert.c:764 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "无法转æ¢åŽå¤‡å­—符集“%sâ€åˆ°å­—符集“%sâ€" + +#: glib/gconvert.c:936 +msgid "Embedded NUL byte in conversion input" +msgstr "转æ¢è¾“入中出现嵌入的 NUL 字节" + +#: glib/gconvert.c:957 +msgid "Embedded NUL byte in conversion output" +msgstr "转æ¢è¾“出中出现嵌入的 NUL 字节" + +#: glib/gconvert.c:1688 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI“%sâ€ä¸æ˜¯ä½¿ç”¨â€œfileâ€æ–¹æ¡ˆçš„ç»å¯¹ URI" + +#: glib/gconvert.c:1698 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "本地文件 URI“%sâ€ä¸èƒ½åŒ…å«â€œ#â€" + +#: glib/gconvert.c:1715 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI“%sâ€æ— æ•ˆ" + +#: glib/gconvert.c:1727 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI“%sâ€ä¸­çš„ä¸»æœºåæ— æ•ˆ" + +#: glib/gconvert.c:1743 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI“%sâ€ä¸­åŒ…嫿— æ•ˆçš„转义字符" + +#: glib/gconvert.c:1815 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "路径å“%sâ€ä¸æ˜¯ç»å¯¹è·¯å¾„" + +# å‚考 coreutils 里 date 的翻译,时间格å¼åº”è¯¥ä¿æŒâ€œ%H:%M:%Sâ€ï¼Œå¦‚æžœè¦ä½¿ç”¨å•ä½ï¼Œé‚£ä¹ˆâ€œ%Hæ—¶%M分%Sç§’â€åº”该去掉å ä½çš„ 0,ä¸ç„¶å°±ä¼šå‡ºçŽ°â€œ08æ—¶01分01ç§’â€è¿™ç§è¡¨è¾¾ã€‚因此我认为应该直接使用“%H:%M:%Sâ€æ ¼å¼ã€‚ +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Yå¹´%-m月%-dæ—¥ %A %H:%M:%S" + +# 原æ¥çš„æ ¼å¼æ˜¯â€œ%y/%m/%dâ€ï¼Œä½†â€œ/â€è¿™ä¸ªç¬¦å·ä¼šæœ‰è¯¯è§£ã€‚æ‰€ä»¥æ¢æˆåˆ†éš”符。 +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%Y-%m-%d" + +# è·Ÿå…¶ä»–æ—¶é—´æ ¼å¼ä¸ç»Ÿä¸€ +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:232 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +# åŒä¸Šé¢ï¼ŒåŽ»æŽ‰äº†æ—¶åˆ†ç§’å•ä½ã€‚ +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:235 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%p %I:%M:%S" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "January" +msgstr "一月" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "February" +msgstr "二月" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "March" +msgstr "三月" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "April" +msgstr "四月" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "May" +msgstr "五月" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "June" +msgstr "六月" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "July" +msgstr "七月" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "August" +msgstr "八月" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "September" +msgstr "乿œˆ" + +#: glib/gdatetime.c:292 +msgctxt "full month name" +msgid "October" +msgstr "åæœˆ" + +#: glib/gdatetime.c:294 +msgctxt "full month name" +msgid "November" +msgstr "å一月" + +#: glib/gdatetime.c:296 +msgctxt "full month name" +msgid "December" +msgstr "å二月" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "一月" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "二月" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "三月" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "四月" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "May" +msgstr "五月" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "六月" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "七月" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "八月" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "乿œˆ" + +#: glib/gdatetime.c:346 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "åæœˆ" + +#: glib/gdatetime.c:348 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "å一月" + +#: glib/gdatetime.c:350 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "å二月" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Monday" +msgstr "星期一" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "星期二" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "星期三" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "星期四" + +#: glib/gdatetime.c:373 +msgctxt "full weekday name" +msgid "Friday" +msgstr "星期五" + +#: glib/gdatetime.c:375 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "星期六" + +#: glib/gdatetime.c:377 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "星期日" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "周一" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "周二" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "周三" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "周四" + +#: glib/gdatetime.c:400 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "周五" + +#: glib/gdatetime.c:402 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "周六" + +#: glib/gdatetime.c:404 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "周日" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "January" +msgstr "一月" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "February" +msgstr "二月" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "March" +msgstr "三月" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "April" +msgstr "四月" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "May" +msgstr "五月" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "June" +msgstr "六月" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "July" +msgstr "七月" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "August" +msgstr "八月" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "September" +msgstr "乿œˆ" + +#: glib/gdatetime.c:486 +msgctxt "full month name with day" +msgid "October" +msgstr "åæœˆ" + +#: glib/gdatetime.c:488 +msgctxt "full month name with day" +msgid "November" +msgstr "å一月" + +#: glib/gdatetime.c:490 +msgctxt "full month name with day" +msgid "December" +msgstr "å二月" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "一月" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "二月" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "三月" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "四月" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "五月" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "六月" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "七月" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "八月" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "乿œˆ" + +#: glib/gdatetime.c:573 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "åæœˆ" + +#: glib/gdatetime.c:575 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "å一月" + +#: glib/gdatetime.c:577 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "å二月" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:594 +msgctxt "GDateTime" +msgid "AM" +msgstr "上åˆ" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:597 +msgctxt "GDateTime" +msgid "PM" +msgstr "下åˆ" + +#: glib/gdir.c:156 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "打开目录“%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: glib/gfileutils.c:733 glib/gfileutils.c:825 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "æ— æ³•åˆ†é… %lu å­—èŠ‚ä»¥è¯»å–æ–‡ä»¶â€œ%sâ€" + +#: glib/gfileutils.c:750 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "è¯»å–æ–‡ä»¶â€œ%sâ€æ—¶å‡ºé”™ï¼š%s" + +#: glib/gfileutils.c:786 +#, c-format +msgid "File “%s†is too large" +msgstr "文件“%sâ€è¿‡å¤§" + +#: glib/gfileutils.c:850 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "è¯»å–æ–‡ä»¶â€œ%sâ€å¤±è´¥ï¼š%s" + +#: glib/gfileutils.c:900 glib/gfileutils.c:975 glib/gfileutils.c:1447 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "打开文件“%sâ€å¤±è´¥ï¼š%s" + +#: glib/gfileutils.c:913 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "获得文件“%sâ€çš„属性失败:fstat() 失败:%s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "打开文件“%sâ€å¤±è´¥ï¼šfdopen() 失败:%s" + +#: glib/gfileutils.c:1045 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "将文件“%sâ€é‡å‘½å为“%sâ€å¤±è´¥ï¼šg_rename() 失败:%s" + +#: glib/gfileutils.c:1154 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "写入文件“%sâ€å¤±è´¥ï¼šwrite() 失败:%s" + +#: glib/gfileutils.c:1175 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "写入文件“%sâ€å¤±è´¥ï¼šfsync() 失败:%s" + +#: glib/gfileutils.c:1336 glib/gfileutils.c:1751 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "创建文件“%sâ€å¤±è´¥ï¼š%s" + +#: glib/gfileutils.c:1381 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "无法删除已有文件“%sâ€ï¼šg_unlink() 失败:%s" + +#: glib/gfileutils.c:1716 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "模æ¿â€œ%sâ€æ— æ•ˆï¼Œä¸åº”该包å«â€œ%sâ€" + +#: glib/gfileutils.c:1729 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "模æ¿â€œ%sâ€ä¸åŒ…å« XXXXXX" + +#: glib/gfileutils.c:2289 glib/gfileutils.c:2318 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "读å–符å·é“¾æŽ¥â€œ%sâ€å¤±è´¥ï¼š%s" + +#: glib/giochannel.c:1405 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "无法打开从“%sâ€åˆ°â€œ%sâ€çš„转æ¢å™¨ï¼š%s" + +#: glib/giochannel.c:1758 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "g_io_channel_read_line_string 函数无法进行原始读å–" + +#: glib/giochannel.c:1805 glib/giochannel.c:2063 glib/giochannel.c:2150 +msgid "Leftover unconverted data in read buffer" +msgstr "åœ¨è¯»ç¼“å†²é‡Œç•™æœ‰æœªè½¬æ¢æ•°æ®" + +#: glib/giochannel.c:1886 glib/giochannel.c:1963 +msgid "Channel terminates in a partial character" +msgstr "通é“终止于未尽字符" + +#: glib/giochannel.c:1949 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end 函数无法进行原始读å–" + +#: glib/gkeyfile.c:794 +msgid "Valid key file could not be found in search dirs" +msgstr "在æœç´¢ç›®å½•中无法找到有效的键文件" + +#: glib/gkeyfile.c:831 +msgid "Not a regular file" +msgstr "䏿˜¯æ™®é€šæ–‡ä»¶" + +#: glib/gkeyfile.c:1289 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "键文件包å«ä¸æ˜¯é”®-值对ã€ç»„或注释的行“%sâ€" + +#: glib/gkeyfile.c:1346 +#, c-format +msgid "Invalid group name: %s" +msgstr "无效的组å:%s" + +#: glib/gkeyfile.c:1370 +msgid "Key file does not start with a group" +msgstr "键文件ä¸ä»¥ç»„开始" + +#: glib/gkeyfile.c:1394 +#, c-format +msgid "Invalid key name: %.*s" +msgstr "无效的键å:%.*s" + +#: glib/gkeyfile.c:1422 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "键文件包å«ä¸æ”¯æŒçš„ç¼–ç â€œ%sâ€" + +#: glib/gkeyfile.c:1677 glib/gkeyfile.c:1850 glib/gkeyfile.c:3297 +#: glib/gkeyfile.c:3361 glib/gkeyfile.c:3491 glib/gkeyfile.c:3623 +#: glib/gkeyfile.c:3769 glib/gkeyfile.c:4004 glib/gkeyfile.c:4071 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "键文件没有组“%sâ€" + +#: glib/gkeyfile.c:1805 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "键文件在组“%2$sâ€ä¸­æ²¡æœ‰é”®â€œ%1$sâ€" + +#: glib/gkeyfile.c:1967 glib/gkeyfile.c:2083 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "键文件包å«é”®â€œ%sâ€ï¼Œå…¶å€¼â€œ%sâ€ä¸æ˜¯ UTF-8" + +#: glib/gkeyfile.c:1987 glib/gkeyfile.c:2103 glib/gkeyfile.c:2542 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "键文件包å«é”®â€œ%sâ€ï¼Œå…¶å€¼æ— æ³•è§£æžã€‚" + +#: glib/gkeyfile.c:2757 glib/gkeyfile.c:3126 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "键文件包å«ç»„“%2$sâ€ä¸­çš„键“%1$sâ€ï¼Œå…¶å€¼æ— æ³•解释。" + +#: glib/gkeyfile.c:2835 glib/gkeyfile.c:2912 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "组“%2$sâ€ä¸­çš„键“%1$sâ€çš„值为“%3$sâ€ï¼Œåº”为 %4$s" + +#: glib/gkeyfile.c:4324 +msgid "Key file contains escape character at end of line" +msgstr "é”®æ–‡ä»¶åœ¨è¡Œå°¾å«æœ‰è½¬ä¹‰å­—符" + +#: glib/gkeyfile.c:4346 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "é”®æ–‡ä»¶ä¸­åŒ…å«æ— æ•ˆçš„转义åºåˆ—“%sâ€" + +#: glib/gkeyfile.c:4491 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "无法将值“%sâ€è§£é‡Šä¸ºæ•°å€¼ã€‚" + +#: glib/gkeyfile.c:4505 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "整数值“%sâ€è¶…出范围" + +#: glib/gkeyfile.c:4538 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "无法将值“%sâ€è§£é‡Šä¸ºæµ®ç‚¹æ•°ã€‚" + +#: glib/gkeyfile.c:4577 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "无法将值“%sâ€è§£é‡Šä¸ºå¸ƒå°”值。" + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "èŽ·å–æ–‡ä»¶â€œ%s%s%s%sâ€çš„属性失败 : fstat() 失败:%s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "映射 %s%s%s%s 失败:mmap() 失败:%s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "打开文件“%sâ€å¤±è´¥ï¼šopen() 失败:%s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "第 %d 行第 %d 个字符出错: " + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "åç§°åŒ…å«æ— æ•ˆçš„ UTF-8 ç¼–ç æ–‡æœ¬â€”—无效的“%sâ€" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "“%sâ€ä¸æ˜¯æœ‰æ•ˆçš„åç§°" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "“%sâ€ä¸æ˜¯æœ‰æ•ˆçš„å称:“%câ€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "第 %d 行出错:%s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"è§£æžâ€œ%-.*sâ€å¤±è´¥ã€‚它应该是字符引用中的数字(如 ê)——å¯èƒ½è¯¥æ•°å­—太大了" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"字符引用没有以分å·ç»“æŸã€‚很å¯èƒ½æ‚¨ä½¿ç”¨äº†ä¸Žå·ï¼ˆ&)字符而åˆä¸æ˜¯ä¸€ä¸ªå®žä½“——将这个与" +"å·å˜ä¸º &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "字符引用“%-.*sâ€æ²¡æœ‰ç¼–ç ä¸€ä¸ªå…许的字符" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "å‘现空的实体“&;â€ã€‚有效的实体为:& " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "未知的实体å“%-.*sâ€" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"实体没有以分å·ç»“æŸã€‚很å¯èƒ½æ‚¨ä½¿ç”¨äº†ä¸Žå·ï¼ˆ&)字符而åˆä¸æ˜¯ä¸€ä¸ªå®žä½“——将这个与å·å˜" +"为 &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "文档必须以一个元素开始(例如 )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "“%sâ€å‡ºçŽ°åœ¨å­—ç¬¦â€œ<â€åŽæ˜¯æ— æ•ˆå­—符;它ä¸èƒ½ä½œä¸ºå…ƒç´ å的开头" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "字符“%sâ€æ— æ•ˆï¼Œåº”该以字符“>â€æ¥ç»“æŸç©ºå…ƒç´ æ ‡è®°â€œ%sâ€" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "元素“%sâ€ä¸­æœ‰è¿‡å¤šå‚æ•°" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "字符“%sâ€æ— æ•ˆï¼Œåœ¨å±žæ€§å“%sâ€ï¼ˆå…ƒç´ â€œ%sâ€ï¼‰çš„åŽåº”该是字符“=â€" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"字符“%sâ€æ— æ•ˆï¼Œåº”该以“>â€æˆ–“/â€ç»“æŸå…ƒç´ â€œ%sâ€çš„起始标记,或紧跟该元素的属性;å¯èƒ½" +"您在属性å中使用了无效字符" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "字符“%1$sâ€æ— æ•ˆï¼Œåœ¨ç»™å…ƒç´ â€œ%3$sâ€çš„属性“%2$sâ€èµ‹å€¼æ—¶ï¼Œç­‰å·åŽåº”该是å‰å¼•å·" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "“%sâ€å­—符出现在闭åˆå…ƒç´ å“%sâ€åŽæ— æ•ˆï¼›å…许的字符是“>â€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "元素“%sâ€å·²ç»é—­åˆï¼Œå½“剿²¡æœ‰å¼€æ”¾çš„元素" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "元素“%sâ€å·²ç»é—­åˆï¼Œå½“å‰ä»å¼€æ”¾çš„元素是“%sâ€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "文档为空或仅å«ç©ºç™½å­—符" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "文档在一个左尖括å·â€œ<â€åŽæ„外结æŸ" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "文档在元素ä»å¼€æ”¾å¤„æ„外结æŸâ€”â€”æœ€åŽæœªç»“æŸçš„元素是“%sâ€" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "文档æ„外结æŸï¼Œåº”该以å³å°–括å·â€œ>â€æ¥ç»“æŸæ ‡è®° <%s/>" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "文档在元素å中æ„外结æŸ" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "文档在属性å中æ„外结æŸ" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "文档在元素ä»å¼€æ”¾çš„æ ‡è®°ä¸­æ„外结æŸã€‚" + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "文档在跟在属性ååŽçš„ç­‰å·åŽæ„外结æŸï¼›æ²¡æœ‰å±žæ€§å€¼" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "文档在属性值中æ„外结æŸ" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "文档在元素“%sâ€çš„é—­åˆæ ‡è®°ä¸­æ„外结æŸ" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "æ–‡æ¡£åœ¨æ— èµ·å§‹å…ƒç´ çš„é—­åˆæ ‡è®°ä¸­æ„外结æŸ" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "æ–‡æ¡£åœ¨æ³¨é‡Šæˆ–å¤„ç†æŒ‡ä»¤ä¸­æ„外结æŸ" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[选项…]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "帮助选项:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "显示帮助选项" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "显示全部帮助选项" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "应用程åºé€‰é¡¹ï¼š" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "选项:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "æ— æ³•è§£æž %2$s 的整数值“%1$sâ€" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "%2$s 所用的整数值“%1$sâ€è¶…出范围" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "æ— æ³•è§£æž %2$s çš„åŒç²¾åº¦å€¼â€œ%1$sâ€" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "%2$s 所用的åŒç²¾åº¦å€¼â€œ%1$sâ€è¶…出范围" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "è§£æžé€‰é¡¹ %s 时出错" + +#: glib/goption.c:1561 glib/goption.c:1674 +#, c-format +msgid "Missing argument for %s" +msgstr "缺少 %s çš„å‚æ•°" + +#: glib/goption.c:2184 +#, c-format +msgid "Unknown option %s" +msgstr "未知选项 %s" + +#: glib/gregex.c:255 +msgid "corrupted object" +msgstr "无效对象" + +#: glib/gregex.c:257 +msgid "internal error or corrupted object" +msgstr "内部错误或者无效对象" + +#: glib/gregex.c:259 +msgid "out of memory" +msgstr "内存ä¸è¶³" + +#: glib/gregex.c:264 +msgid "backtracking limit reached" +msgstr "达到回溯上é™" + +#: glib/gregex.c:276 glib/gregex.c:284 +msgid "the pattern contains items not supported for partial matching" +msgstr "表达å¼åŒ…å«ä¸è¢«éƒ¨åˆ†åŒ¹é…支æŒçš„项" + +#: glib/gregex.c:278 +msgid "internal error" +msgstr "内部错误" + +#: glib/gregex.c:286 +msgid "back references as conditions are not supported for partial matching" +msgstr "ä¸å®Œå…¨åŒ¹é…时作为æ¡ä»¶çš„åŽå‘引用ä¸è¢«æ”¯æŒ" + +#: glib/gregex.c:295 +msgid "recursion limit reached" +msgstr "达到递归上é™" + +#: glib/gregex.c:297 +msgid "invalid combination of newline flags" +msgstr "无效的新行标志组åˆ" + +#: glib/gregex.c:299 +msgid "bad offset" +msgstr "错误的å移值" + +#: glib/gregex.c:301 +msgid "short utf8" +msgstr "UTF-8 短编ç " + +#: glib/gregex.c:303 +msgid "recursion loop" +msgstr "递归循环" + +#: glib/gregex.c:307 +msgid "unknown error" +msgstr "未知错误" + +#: glib/gregex.c:327 +msgid "\\ at end of pattern" +msgstr "\\ åœ¨è¡¨è¾¾å¼æœ«å°¾" + +#: glib/gregex.c:330 +msgid "\\c at end of pattern" +msgstr "è¡¨è¾¾å¼æœ«å°¾çš„ \\c" + +#: glib/gregex.c:333 +msgid "unrecognized character following \\" +msgstr "\\ åŽæœ‰æ— æ³•识别的字符" + +#: glib/gregex.c:336 +msgid "numbers out of order in {} quantifier" +msgstr "{} é‡è¯é‡Œçš„æ•°å­—次åºé¢ å€’了" + +#: glib/gregex.c:339 +msgid "number too big in {} quantifier" +msgstr "{} é‡è¯é‡Œçš„æ•°å­—太大了" + +#: glib/gregex.c:342 +msgid "missing terminating ] for character class" +msgstr "字符类缺少终结的 ]" + +#: glib/gregex.c:345 +msgid "invalid escape sequence in character class" +msgstr "å­—ç¬¦ç±»åŒ…å«æ— æ•ˆçš„转义åºåˆ—" + +#: glib/gregex.c:348 +msgid "range out of order in character class" +msgstr "字符类的范围次åºé¢ å€’" + +#: glib/gregex.c:351 +msgid "nothing to repeat" +msgstr "没有å¯ä»¥é‡å¤çš„内容" + +#: glib/gregex.c:355 +msgid "unexpected repeat" +msgstr "éžé¢„期的é‡å¤" + +#: glib/gregex.c:358 +msgid "unrecognized character after (? or (?-" +msgstr "(? 或 (?- åŽæœ‰æ— æ³•识别的字符" + +#: glib/gregex.c:361 +msgid "POSIX named classes are supported only within a class" +msgstr "åªæœ‰ç±»é‡Œæ”¯æŒ POSIX 命å的类" + +#: glib/gregex.c:364 +msgid "missing terminating )" +msgstr "缺少结æŸçš„ )" + +#: glib/gregex.c:367 +msgid "reference to non-existent subpattern" +msgstr "引用了ä¸å­˜åœ¨çš„å­è¡¨è¾¾å¼" + +#: glib/gregex.c:370 +msgid "missing ) after comment" +msgstr "注释åŽç¼ºå°‘ )" + +#: glib/gregex.c:373 +msgid "regular expression is too large" +msgstr "正则表达å¼è¿‡é•¿" + +#: glib/gregex.c:376 +msgid "failed to get memory" +msgstr "获å–内存失败" + +#: glib/gregex.c:380 +msgid ") without opening (" +msgstr ") 没有起始的 (" + +#: glib/gregex.c:384 +msgid "code overflow" +msgstr "ä»£ç æº¢å‡º" + +#: glib/gregex.c:388 +msgid "unrecognized character after (?<" +msgstr "(?< åŽæœ‰æ— æ³•识别的字符" + +#: glib/gregex.c:391 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind æ–­è¨€ä¸æ˜¯å®šé•¿çš„" + +#: glib/gregex.c:394 +msgid "malformed number or name after (?(" +msgstr "(?( åŽæœ‰å½¢å¼ä¸æ­£ç¡®çš„æ•°å­—或åç§°" + +#: glib/gregex.c:397 +msgid "conditional group contains more than two branches" +msgstr "æ¡ä»¶ç»„包å«äº†è¶…过两个分支" + +#: glib/gregex.c:400 +msgid "assertion expected after (?(" +msgstr "(?( åŽåº”该有断言" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:407 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R 或 (?[+-]æ•°å­— å¿…é¡»è·Ÿç€ )" + +#: glib/gregex.c:410 +msgid "unknown POSIX class name" +msgstr "未知的 POSIX ç±»å" + +#: glib/gregex.c:413 +msgid "POSIX collating elements are not supported" +msgstr "䏿”¯æŒ POSIX æ•´ç†å…ƒç´ " + +#: glib/gregex.c:416 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{...} åºåˆ—里的字符值太大了" + +#: glib/gregex.c:419 +msgid "invalid condition (?(0)" +msgstr "无效的æ¡ä»¶ (?(0)" + +#: glib/gregex.c:422 +msgid "\\C not allowed in lookbehind assertion" +msgstr "lookbehind 断言里ä¸å…许使用 \\C" + +#: glib/gregex.c:429 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "䏿”¯æŒå¯¹ \\Lã€\\lã€\\N{name}ã€\\Uã€\\u 进行转义" + +#: glib/gregex.c:432 +msgid "recursive call could loop indefinitely" +msgstr "递归调用å¯èƒ½å¯¼è‡´æ— é™å¾ªçޝ" + +#: glib/gregex.c:436 +msgid "unrecognized character after (?P" +msgstr "(?P 有无法识别的字符" + +#: glib/gregex.c:439 +msgid "missing terminator in subpattern name" +msgstr "å­è¡¨è¾¾å¼å里缺少终结符" + +#: glib/gregex.c:442 +msgid "two named subpatterns have the same name" +msgstr "两个有åå­è¡¨è¾¾å¼æœ‰ç›¸åŒçš„åç§°" + +#: glib/gregex.c:445 +msgid "malformed \\P or \\p sequence" +msgstr "å½¢å¼ä¸æ­£ç¡®çš„ \\P 或 \\p åºåˆ—" + +#: glib/gregex.c:448 +msgid "unknown property name after \\P or \\p" +msgstr "\\P 或 \\p åŽæœ‰æœªçŸ¥çš„属性å" + +#: glib/gregex.c:451 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "å­è¡¨è¾¾å¼å太长了(最多 32 个字符)" + +#: glib/gregex.c:454 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "有åå­è¡¨è¾¾å¼å¤ªå¤šäº†ï¼ˆæœ€å¤š 10,000 个)" + +#: glib/gregex.c:457 +msgid "octal value is greater than \\377" +msgstr "八进制值大于 \\377" + +#: glib/gregex.c:461 +msgid "overran compiling workspace" +msgstr "编译工作区超出正常范围" + +#: glib/gregex.c:465 +msgid "previously-checked referenced subpattern not found" +msgstr "æœªæ‰¾åˆ°ä¹‹å‰æ£€æŸ¥è¿‡çš„引用过的å­è¡¨è¾¾å¼" + +#: glib/gregex.c:468 +msgid "DEFINE group contains more than one branch" +msgstr "定义组包å«å¤šäºŽä¸€ä¸ªçš„分支" + +#: glib/gregex.c:471 +msgid "inconsistent NEWLINE options" +msgstr "ä¸ä¸€è‡´çš„æ¢è¡Œé€‰é¡¹" + +#: glib/gregex.c:474 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "\\g åŽæ²¡æœ‰èŠ±æ‹¬å·ã€å°–æ‹¬å·æˆ–引巿‹¬èµ·æ¥çš„å称或数字,或纯数字" + +#: glib/gregex.c:478 +msgid "a numbered reference must not be zero" +msgstr "ç¼–å·å¼•用ä¸èƒ½ä¸º 0" + +#: glib/gregex.c:481 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "(*ACCEPT)ã€(*FAIL) å’Œ (*COMMIT) ä¸å…è®¸å¸¦å‚æ•°" + +#: glib/gregex.c:484 +msgid "(*VERB) not recognized" +msgstr "无法识别 (*VERB)" + +#: glib/gregex.c:487 +msgid "number is too big" +msgstr "数字太大" + +#: glib/gregex.c:490 +msgid "missing subpattern name after (?&" +msgstr "(?& åŽç¼ºå°‘å­è¡¨è¾¾å¼å" + +#: glib/gregex.c:493 +msgid "digit expected after (?+" +msgstr "(?+ åŽåº”为数字" + +#: glib/gregex.c:496 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "Javascript 兼容模å¼ä¸­ï¼Œ] æ˜¯éžæ³•æ•°æ®å­—符" + +#: glib/gregex.c:499 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ä¸å…许两个å·ç ç›¸åŒçš„å­è¡¨è¾¾å¼æœ‰ä¸åŒçš„åç§°" + +#: glib/gregex.c:502 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) å¿…é¡»æœ‰ä¸€ä¸ªå‚æ•°" + +#: glib/gregex.c:505 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c åŽé¢å¿…须跟一个 ASCII 字符" + +#: glib/gregex.c:508 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k åŽæ²¡æœ‰ç”¨èŠ±æ‹¬å·ã€å°–æ‹¬å·æˆ–引巿‹¬èµ·æ¥çš„åç§°" + +#: glib/gregex.c:511 +msgid "\\N is not supported in a class" +msgstr "ç±»ä¸­ä¸æ”¯æŒ \\N" + +#: glib/gregex.c:514 +msgid "too many forward references" +msgstr "太多å‰å‘引用" + +#: glib/gregex.c:517 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "在 (*MARK)ã€(*PRUNE)ã€(*SKIP) 或者 (*THEN) 中的å称太长" + +#: glib/gregex.c:520 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... åºåˆ—里的字符值太大了" + +#: glib/gregex.c:743 glib/gregex.c:1988 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "åŒ¹é…æ­£åˆ™è¡¨è¾¾å¼ %s 时出错:%s" + +#: glib/gregex.c:1321 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE åº“ç¼–è¯‘æ—¶æœªåŒ…å« UTF8 支æŒ" + +#: glib/gregex.c:1325 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE åº“ç¼–è¯‘æ—¶æœªåŒ…å« UTF8 属性支æŒ" + +#: glib/gregex.c:1333 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE 库编译时使用了ä¸å…¼å®¹çš„选项" + +#: glib/gregex.c:1362 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "ä¼˜åŒ–æ­£åˆ™è¡¨è¾¾å¼ %s 时出错:%s" + +#: glib/gregex.c:1442 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "ç¼–è¯‘æ­£åˆ™è¡¨è¾¾å¼ %s 到字符 %d 处时出错:%s" + +#: glib/gregex.c:2427 +msgid "hexadecimal digit or “}†expected" +msgstr "期望å六进制数或“}â€" + +#: glib/gregex.c:2443 +msgid "hexadecimal digit expected" +msgstr "期望å六进制数" + +#: glib/gregex.c:2483 +msgid "missing “<†in symbolic reference" +msgstr "在符å·å¼•用中缺少“<â€" + +#: glib/gregex.c:2492 +msgid "unfinished symbolic reference" +msgstr "未完æˆçš„符å·å¼•用" + +#: glib/gregex.c:2499 +msgid "zero-length symbolic reference" +msgstr "零长符å·å¼•用" + +#: glib/gregex.c:2510 +msgid "digit expected" +msgstr "期望数字" + +#: glib/gregex.c:2528 +msgid "illegal symbolic reference" +msgstr "éžæ³•的符å·å¼•用" + +#: glib/gregex.c:2591 +msgid "stray final “\\â€" +msgstr "丢失了最åŽçš„“\\â€" + +#: glib/gregex.c:2595 +msgid "unknown escape sequence" +msgstr "未知的转义åºåˆ—" + +#: glib/gregex.c:2605 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "è§£æžæ›¿æ¢æ–‡æœ¬â€œ%sâ€åˆ°å­—符 %lu 处时出错:%s" + +#: glib/gshell.c:96 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "引用的文本ä¸ä»¥å¼•å·å¼€å¤´" + +#: glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "命令行或其他 shell 引用文本中出现ä¸åŒ¹é…的引å·" + +#: glib/gshell.c:592 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "文本在一个“\\â€å­—符åŽç»“æŸã€‚(文本为“%sâ€ï¼‰" + +#: glib/gshell.c:599 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "在找到为 %c 匹é…的引用之å‰ï¼Œæ–‡æœ¬å·²ç»“æŸã€‚(文本为“%sâ€ï¼‰" + +#: glib/gshell.c:611 +msgid "Text was empty (or contained only whitespace)" +msgstr "文本为空(或仅å«ç©ºç™½å­—符)" + +#: glib/gspawn.c:310 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "从å­è¿›ç¨‹ä¸­è¯»å–æ•°æ®å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn.c:461 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "在从å­è¿›ç¨‹ä¸­è¯»å–æ•°æ®æ—¶å‡ºçŽ°å¼‚å¸¸é”™è¯¯ï¼ˆ%s)" + +#: glib/gspawn.c:546 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() 出现异常错误(%s)" + +#: glib/gspawn.c:1168 glib/gspawn-win32.c:1426 +#, c-format +msgid "Child process exited with code %ld" +msgstr "å­è¿›ç¨‹å·²é€€å‡ºï¼Œä»£ç  %ld" + +#: glib/gspawn.c:1176 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "å­è¿›ç¨‹å·²ç”±ä¿¡å· %ld æ€æ­»" + +#: glib/gspawn.c:1183 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "å­è¿›ç¨‹å·²ç”±ä¿¡å· %ld åœæ­¢" + +#: glib/gspawn.c:1190 +#, c-format +msgid "Child process exited abnormally" +msgstr "å­è¿›ç¨‹å¼‚常中止" + +#: glib/gspawn.c:1881 glib/gspawn-win32.c:353 glib/gspawn-win32.c:361 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "从å­ç®¡é“中读å–失败(%s)" + +#: glib/gspawn.c:2241 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "生æˆå­è¿›ç¨‹â€œ%sâ€å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn.c:2358 +#, c-format +msgid "Failed to fork (%s)" +msgstr "fork 失败(%s)" + +#: glib/gspawn.c:2518 glib/gspawn-win32.c:384 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "切æ¢åˆ°ç›®å½•“%sâ€å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn.c:2528 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "执行å­è¿›ç¨‹â€œ%sâ€å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn.c:2538 +#, c-format +msgid "Failed to open file to remap file descriptor (%s)" +msgstr "æ‰“å¼€æ–‡ä»¶ä»¥é‡æ–°æ˜ å°„文件æè¿°ç¬¦å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn.c:2546 +#, c-format +msgid "Failed to duplicate file descriptor for child process (%s)" +msgstr "为å­è¿›ç¨‹å¤åˆ¶æ–‡ä»¶æè¿°ç¬¦å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn.c:2555 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "fork å­è¿›ç¨‹å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn.c:2563 +#, c-format +msgid "Failed to close file descriptor for child process (%s)" +msgstr "为å­è¿›ç¨‹å…³é—­æ–‡ä»¶æè¿°ç¬¦å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn.c:2571 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "执行å­è¿›ç¨‹â€œ%sâ€æ—¶å‡ºçŽ°æœªçŸ¥é”™è¯¯" + +#: glib/gspawn.c:2595 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "从å­è¿›ç¨‹ç®¡é“中读å–足够的数æ®å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn-win32.c:297 +msgid "Failed to read data from child process" +msgstr "从å­è¿›ç¨‹ä¸­è¯»å–æ•°æ®å¤±è´¥" + +#: glib/gspawn-win32.c:390 glib/gspawn-win32.c:395 glib/gspawn-win32.c:519 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "执行å­è¿›ç¨‹å¤±è´¥ï¼ˆ%s)" + +#: glib/gspawn-win32.c:400 +#, c-format +msgid "Failed to dup() in child process (%s)" +msgstr "在å­è¿›ç¨‹ä¸­ dup() 失败(%s)" + +#: glib/gspawn-win32.c:469 +#, c-format +msgid "Invalid program name: %s" +msgstr "无效的程åºå:%s" + +#: glib/gspawn-win32.c:479 glib/gspawn-win32.c:797 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "%d å¤„çš„å‚æ•°å‘é‡ä¸­æœ‰æ— æ•ˆçš„字符串:%s" + +#: glib/gspawn-win32.c:490 glib/gspawn-win32.c:813 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "环境中有无效的字符串:%s" + +#: glib/gspawn-win32.c:793 +#, c-format +msgid "Invalid working directory: %s" +msgstr "无效的工作目录:%s" + +#: glib/gspawn-win32.c:858 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "执行助手程åºï¼ˆ%s)失败" + +#: glib/gspawn-win32.c:1086 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "g_io_channel_win32_poll() 从å­è¿›ç¨‹ä¸­è¯»å–æ•°æ®æ—¶å‡ºçŽ°å¼‚å¸¸é”™è¯¯" + +#: glib/gstrfuncs.c:3351 glib/gstrfuncs.c:3453 +msgid "Empty string is not a number" +msgstr "ç©ºå­—ç¬¦ä¸²ä¸æ˜¯æ•°å­—" + +#: glib/gstrfuncs.c:3375 +#, c-format +msgid "“%s†is not a signed number" +msgstr "“%sâ€ä¸æ˜¯æœ‰æ•ˆçš„æœ‰ç¬¦å·æ•°å€¼" + +#: glib/gstrfuncs.c:3385 glib/gstrfuncs.c:3489 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "数字“%sâ€è¶Šç•Œ [%s, %s]" + +#: glib/gstrfuncs.c:3479 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "“%sâ€ä¸æ˜¯æœ‰æ•ˆçš„æ— ç¬¦å·æ•°å€¼" + +#: glib/guri.c:315 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "URI 中无效的 %-ç¼–ç " + +#: glib/guri.c:332 +msgid "Illegal character in URI" +msgstr "URI ä¸­æœ‰éžæ³•字符" + +#: glib/guri.c:366 +msgid "Non-UTF-8 characters in URI" +msgstr "URI ä¸­å­˜åœ¨éž UTF-8 字符" + +#: glib/guri.c:546 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "URI 中无效的 IPv6 地å€â€œ%.*sâ€" + +#: glib/guri.c:601 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "URI ä¸­æœ‰ç¼–ç æ–¹å¼éžæ³•çš„ IP 地å€â€œ%.*sâ€" + +#: glib/guri.c:613 +#, c-format +msgid "Illegal internationalized hostname ‘%.*s’ in URI" +msgstr "URI ä¸­æœ‰éžæ³•的国际化主机å“%.*sâ€" + +#: glib/guri.c:645 glib/guri.c:657 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "æ— æ³•è§£æž URI 中的端å£â€œ%.*sâ€" + +#: glib/guri.c:664 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "URI 中的端å£â€œ%.*sâ€è¶…出范围" + +#: glib/guri.c:1224 glib/guri.c:1288 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "URI“%sâ€ä¸æ˜¯ç»å¯¹ URI" + +#: glib/guri.c:1230 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "URI“%sâ€æ²¡æœ‰ä¸»æœºéƒ¨åˆ†" + +#: glib/guri.c:1460 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI 䏿˜¯ç»å¯¹çš„,且未æä¾› base URI" + +#: glib/guri.c:2238 +msgid "Missing ‘=’ and parameter value" +msgstr "缺少“=â€å’Œå‚数值" + +#: glib/gutf8.c:832 +msgid "Failed to allocate memory" +msgstr "分é…内存失败" + +#: glib/gutf8.c:965 +msgid "Character out of range for UTF-8" +msgstr "字符超出 UTF-8 范围" + +#: glib/gutf8.c:1067 glib/gutf8.c:1076 glib/gutf8.c:1206 glib/gutf8.c:1215 +#: glib/gutf8.c:1354 glib/gutf8.c:1451 +msgid "Invalid sequence in conversion input" +msgstr "转æ¢è¾“入中出现无效åºåˆ—" + +#: glib/gutf8.c:1365 glib/gutf8.c:1462 +msgid "Character out of range for UTF-16" +msgstr "字符超出 UTF-16 范围" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2849 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2851 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2853 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2855 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2857 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2859 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2863 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2865 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2867 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2869 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2871 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2873 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2877 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2879 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2881 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2883 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2885 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2887 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2891 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2893 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2895 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2897 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2899 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2901 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2935 glib/gutils.c:3052 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u 字节" + +#: glib/gutils.c:2939 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u ä½" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:3006 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s 字节" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:3011 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s ä½" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:3065 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:3070 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:3075 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:3080 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:3085 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3090 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +#~ msgstr "无法加载 /var/lib/dbus/machine-id 或 /etc/machine-id:" + +#~ msgid "Unknown error on connect" +#~ msgstr "连接时出现未知错误" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "地å€â€œ%sâ€ä¸­æœ‰é”™è¯¯â€”—åè®®æ—属性格å¼é”™è¯¯" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "已将 %s 挂载在 %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr ";忽略对此键的覆盖。\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr "并且指定了 --strict;退出。\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "忽略对此键的覆盖。\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "什么都没åšã€‚\n" + +#~ msgid "No such method '%s'" +#~ msgstr "无此方法“%sâ€" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "无法从 DBUS_STARTER_BUS_TYPE 环境å˜é‡ç¡®å®šæ€»çº¿åœ°å€â€”—未知的值“%sâ€" + +#~ msgid "[ARGS...]" +#~ msgstr "[傿•°...]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "创建临时文件失败:%s" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "æ¶ˆæ¯æ‹¥æœ‰ %d 个文件æè¿°ç¬¦ï¼Œä½†æ˜¯å¤´åŒºåŸŸæŒ‡å‡º %d 个文件æè¿°ç¬¦" + +#~ msgid "Error: object path not specified.\n" +#~ msgstr "错误:没有指定对象路径。\n" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "错误:没有指定对象。\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "错误:信å·å¿…须是完全é™å®šå。\n" + +#~ msgid "Error opening nonce file '%s': %s" +#~ msgstr "打开临时文件“%sâ€æ—¶å‡ºé”™ï¼š%s" + +#~ msgid "Error creating directory '%s': %s" +#~ msgstr "创建目录“%sâ€æ—¶å‡ºé”™ï¼š%s" + +#~ msgid "No such interface" +#~ msgstr "无此接å£" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "获å–å¯å†™å±žæ€§å‡ºé”™ï¼š%s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "挂载ä½ç½®å‡ºé”™ï¼š%s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "å¸è½½æŒ‚载点出错:%s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "å¯»æ‰¾é—­åˆæŒ‚载出错:%s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "弹出挂载出错:%s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "挂载 %s 出错:%s\n" + +#~ msgid "No files to open" +#~ msgstr "æ²¡æœ‰è¦æ‰“开的文件" + +#~ msgid "No files to delete" +#~ msgstr "没有è¦åˆ é™¤çš„æ–‡ä»¶" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "设置属性出错:%s\n" + +#~ msgid "Error opening file '%s': %s" +#~ msgstr "打开文件“%sâ€æ—¶å‡ºé”™ï¼š%s" + +#~ msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +#~ msgstr "挂载未实现“unmountâ€æˆ–“unmount_with_operationâ€" + +#~ msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +#~ msgstr "挂载未实现“ejectâ€æˆ–“eject_with_operationâ€" + +#~ msgid "Error opening directory '%s': %s" +#~ msgstr "打开目录“%sâ€æ—¶å‘生错误:%s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "è¯»å–æ–‡ä»¶â€œ%sâ€å‡ºé”™ï¼š%s" + +#~ msgid "Failed to write file '%s': fsync() failed: %s" +#~ msgstr "写入文件“%sâ€å¤±è´¥ï¼šfsync() 失败:%s" + +#~ msgid "" +#~ "Key file contains key '%s' which has a value that cannot be interpreted." +#~ msgstr "键文件包å«é”®â€œ%sâ€ï¼Œå…¶å€¼æ— æ³•解释。" + +#~ msgid "Failed to execute child process \"%s\" (%s)" +#~ msgstr "执行å­è¿›ç¨‹â€œ%s\"失败(%s)" + +#~ msgid "Error renaming file: %s" +#~ msgstr "é‡å‘½å文件时出错:%s" + +#~ msgid "Can't open directory" +#~ msgstr "无法打开目录" + +#~ msgid "Error opening file: %s" +#~ msgstr "打开文件时出错:%s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "创建目录时出错:%s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "无法找到默认的本地目录监视器类型" + +#~ msgid "association changes not supported on win32" +#~ msgstr "win32 䏿”¯æŒå…³è”的修改" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "win32 䏿”¯æŒå…³è”的创建" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "键文件没有键“%sâ€" + +#~ msgid "" +#~ "Error processing input file with xmllint:\n" +#~ "%s" +#~ msgstr "" +#~ "用 xmllint 处ç†è¾“入文件出错:\n" +#~ "%s" + +#~ msgid "" +#~ "Error processing input file with to-pixdata:\n" +#~ "%s" +#~ msgstr "" +#~ "用 to-pixdata 处ç†è¾“入文件出错:\n" +#~ "%s" + +#~ msgid "Unable to get pending error: %s" +#~ msgstr "æ— æ³•èŽ·å–æœªå†³çš„错误:%s" + +#~ msgid "Failed to open file '%s' for writing: fdopen() failed: %s" +#~ msgstr "打开文件“%sâ€å†™å…¥å¤±è´¥ï¼šfdopen() 失败:%s" + +#~ msgid "Failed to close file '%s': fclose() failed: %s" +#~ msgstr "关闭文件“%sâ€å¤±è´¥ï¼šfclose() 失败:%s" + +#~ msgid "Abnormal program termination spawning command line '%s': %s" +#~ msgstr "命令 %s éžæ­£å¸¸ç¨‹åºç»ˆæ­¢ï¼š%s" + +#~ msgid "Command line '%s' exited with non-zero exit status %d: %s" +#~ msgstr "命令 %s 以éžé›¶çŠ¶æ€æ•° %d 退出:%s" + +#~ msgid "No service record for '%s'" +#~ msgstr "没有“%sâ€çš„æœåŠ¡è®°å½•" + +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "检查套接字是å¦å¯ç”¨ SO_PASSCRED 时选项长度异常。期望 %d 字节,获得了 %d" + +#~ msgid "workspace limit for empty substrings reached" +#~ msgstr "达到空å­ä¸²çš„工作空间é™åˆ¶" + +#~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" +#~ msgstr "这里ä¸å…许使用改å˜å¤§å°å†™çš„转义符(\\l, \\L, \\u, \\U)" + +#~ msgid "repeating a DEFINE group is not allowed" +#~ msgstr "ä¸å…许é‡å¤ DEFINE 组" + +#~ msgid "File is empty" +#~ msgstr "文件为空" + +#~ msgid "This option will be removed soon." +#~ msgstr "此选项将在ä¸ä¹…删除。" + +#~ msgid "Error stating file '%s': %s" +#~ msgstr "èŽ·å–æ–‡ä»¶â€œ%sâ€çжæ€å‡ºé”™ï¼š%s" + +#~ msgid "Error connecting: " +#~ msgstr "连接出错:" + +#~ msgid "Error connecting: %s" +#~ msgstr "连接时出错:%s" + +#~ msgid "SOCKSv4 implementation limits username to %i characters" +#~ msgstr "SOCKv4 的实现é™åˆ¶ç”¨æˆ·å在 %i 个字符串内" + +#~ msgid "SOCKSv4a implementation limits hostname to %i characters" +#~ msgstr "SOCKv4a 的实现é™åˆ¶ä¸»æœºå在 %i 个字符串内" + +#~ msgid "Error reading from unix: %s" +#~ msgstr "è¯»å– unix 出错:%s" + +#~ msgid "Error writing to unix: %s" +#~ msgstr "写入 unix 出错:%s" + +#~ msgctxt "GDateTime" +#~ msgid "am" +#~ msgstr "上" + +#~ msgctxt "GDateTime" +#~ msgid "pm" +#~ msgstr "下" + +#~ msgid "Type of return value is incorrect, got '%s', expected '%s'" +#~ msgstr "è¿”å›žå€¼ç±»åž‹ä¸æ­£ç¡®ï¼ŒèŽ·å¾—äº†â€œ%sâ€ï¼Œä½†æ˜¯æœŸæœ›â€œ%sâ€" + +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "å°è¯•设置类型 %s 的属性 %sï¼Œä½†æ˜¯æ ¹æ®æœŸæœ›çš„æŽ¥å£ï¼Œç±»åž‹æ˜¯ %s" diff --git a/po/zh_HK.po b/po/zh_HK.po new file mode 100644 index 0000000..e37b567 --- /dev/null +++ b/po/zh_HK.po @@ -0,0 +1,4527 @@ +# Chinese (Hong Kong) translation for glib 2.x +# Copyright (C) 2001, 02, 03, 05, 07 Free Software Foundation, Inc. +# XML glossary from http://xml.ascc.net/zh/big5/gloss.html +# Chao-Hsiung Liao , 2005, 2010. +# Abel Cheung , 2001-2003, 2005. +# Woodman Tuen , 2005-07. +# Wei-Lun Chao , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: glib 2.31.21\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-08-20 17:54+0000\n" +"PO-Revision-Date: 2014-08-21 17:05+0800\n" +"Last-Translator: Chao-Hsiung Liao \n" +"Language-Team: Chinese (Hong Kong) \n" +"Language: zh_HK\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.6.5\n" + +#: ../gio/gapplication.c:514 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "進入 GApplication æœå‹™æ¨¡å¼ (用於來自 D-Bus æœå‹™æª”案)" + +#: ../gio/gapplication.c:519 +msgid "GApplication options" +msgstr "GApplication é¸é …" + +#: ../gio/gapplication.c:519 +msgid "Show GApplication options" +msgstr "顯示 GApplication é¸é …" + +#: ../gio/gapplication-tool.c:45 ../gio/gapplication-tool.c:46 +#: ../gio/gresource-tool.c:481 ../gio/gsettings-tool.c:508 +msgid "Print help" +msgstr "顯示求助" + +#: ../gio/gapplication-tool.c:47 ../gio/gresource-tool.c:482 +#: ../gio/gresource-tool.c:550 +msgid "[COMMAND]" +msgstr "[指令]" + +#: ../gio/gapplication-tool.c:49 +msgid "Print version" +msgstr "顯示版本" + +#: ../gio/gapplication-tool.c:50 ../gio/gsettings-tool.c:514 +msgid "Print version information and exit" +msgstr "輸出版本資訊並離開" + +#: ../gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "列出應用程å¼" + +#: ../gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "列出已安è£å¯ä½¿ç”¨ D-Bus çš„æ‡‰ç”¨ç¨‹å¼ (根據 .desktop 檔案)" + +#: ../gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "執行應用程å¼" + +#: ../gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "åŸ·è¡Œæ‡‰ç”¨ç¨‹å¼ (鏿“‡æ€§åŠ ä¸Šè¦é–‹å•Ÿçš„æª”案)" + +#: ../gio/gapplication-tool.c:57 +msgid "APPID [FILE...]" +msgstr "APPID [FILE...]" + +#: ../gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "讓動作生效" + +#: ../gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "呼嫿‡‰ç”¨ç¨‹å¼çš„動作" + +#: ../gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: ../gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "列出å¯ç”¨çš„動作" + +#: ../gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "列出應用程å¼çš„éœæ…‹å‹•作 (從 .desktop 檔案)" + +#: ../gio/gapplication-tool.c:65 ../gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: ../gio/gapplication-tool.c:70 ../gio/gapplication-tool.c:133 +#: ../gio/gdbus-tool.c:90 +msgid "COMMAND" +msgstr "指令" + +#: ../gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "顯示詳細求助的指令" + +#: ../gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus æ ¼å¼çš„æ‡‰ç”¨ç¨‹å¼è¾¨åˆ¥ç¢¼(例如:org.example.viewer)" + +#: ../gio/gapplication-tool.c:72 ../gio/glib-compile-resources.c:589 +#: ../gio/glib-compile-resources.c:620 ../gio/gresource-tool.c:488 +#: ../gio/gresource-tool.c:554 +msgid "FILE" +msgstr "FILE" + +#: ../gio/gapplication-tool.c:72 +msgid "Optional relative or relative filenames, or URIs to open" +msgstr "鏿“‡æ€§ç›¸é—œæˆ–相關的檔案å稱,或è¦é–‹å•Ÿçš„ URI" + +#: ../gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "動作" + +#: ../gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "è¦å‘¼å«çš„動作å稱" + +#: ../gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "åƒæ•¸" + +#: ../gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "å‹•ä½œå‘¼å«æ™‚鏿“‡æ€§çš„åƒæ•¸ï¼Œä»¥ GVariant æ ¼å¼" + +#: ../gio/gapplication-tool.c:96 ../gio/gresource-tool.c:519 +#: ../gio/gsettings-tool.c:594 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"䏿˜ŽæŒ‡ä»¤ %s\n" +"\n" + +#: ../gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "用法:\n" + +#: ../gio/gapplication-tool.c:114 ../gio/gresource-tool.c:544 +#: ../gio/gsettings-tool.c:628 +msgid "Arguments:\n" +msgstr "引數:\n" + +#: ../gio/gapplication-tool.c:133 +msgid "[ARGS...]" +msgstr "[ARGS...]" + +#: ../gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "指令:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: ../gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use '%s help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"使用「'%s help COMMANDã€ä»¥å–得詳細的求助。\n" +"\n" + +#: ../gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s æŒ‡ä»¤éœ€è¦æ‡‰ç”¨ç¨‹å¼ id 直接跟隨\n" +"\n" + +#: ../gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: '%s'\n" +msgstr "ç„¡æ•ˆçš„æ‡‰ç”¨ç¨‹å¼ id:「%sã€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: ../gio/gapplication-tool.c:182 +#, c-format +msgid "" +"'%s' takes no arguments\n" +"\n" +msgstr "" +"「%sã€ä¸éœ€è¦å¼•數\n" +"\n" + +#: ../gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "無法連接到 D-Bus:%s\n" + +#: ../gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "å‚³é€ %s 訊æ¯åˆ°æ‡‰ç”¨ç¨‹å¼æ™‚發生錯誤:%s\n" + +#: ../gio/gapplication-tool.c:317 +#, c-format +msgid "action name must be given after application id\n" +msgstr "動作åç¨±å¿…é ˆåœ¨æ‡‰ç”¨ç¨‹å¼ id 之後\n" + +#: ../gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: '%s'\n" +"action names must consist of only alphanumerics, '-' and '.'\n" +msgstr "" +"無效的動作å稱:「%sã€\n" +"動作å稱必須åªç”±å­—æ¯ã€ã€Œ-ã€å’Œã€Œ.ã€çµ„æˆ\n" + +#: ../gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "è§£æžå‹•ä½œåƒæ•¸æ™‚發生錯誤:%s\n" + +#: ../gio/gapplication-tool.c:356 +#, c-format +msgid "actions accept a maximum of one parameter\n" +msgstr "動作最大åªèƒ½æŽ¥å—ä¸€å€‹åƒæ•¸\n" + +#: ../gio/gapplication-tool.c:411 +#, c-format +msgid "list-actions command takes only the application id" +msgstr "list-actions æŒ‡ä»¤åªæŽ¥å—æ‡‰ç”¨ç¨‹å¼ id" + +#: ../gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "無法找到應用程å¼çš„æ¡Œé¢æª”案 %s\n" + +#: ../gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"無法辨識的指令:%s\n" +"\n" + +#: ../gio/gbufferedinputstream.c:420 ../gio/gbufferedinputstream.c:498 +#: ../gio/ginputstream.c:176 ../gio/ginputstream.c:370 +#: ../gio/ginputstream.c:608 ../gio/ginputstream.c:828 +#: ../gio/goutputstream.c:200 ../gio/goutputstream.c:823 +#: ../gio/gpollableinputstream.c:205 ../gio/gpollableoutputstream.c:206 +#, c-format +msgid "Too large count value passed to %s" +msgstr "傳給 %s 的計數值太大" + +#: ../gio/gbufferedinputstream.c:891 ../gio/gbufferedoutputstream.c:575 +#: ../gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "䏿”¯æ´åœ¨åŸºç¤Žä¸²æµä¸­æœå°‹" + +#: ../gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "ä¸èƒ½æˆªçŸ­ GBufferedInputStream" + +#: ../gio/gbufferedinputstream.c:982 ../gio/ginputstream.c:1017 +#: ../gio/giostream.c:277 ../gio/goutputstream.c:1464 +msgid "Stream is already closed" +msgstr "串æµå·²ç¶“關閉" + +#: ../gio/gbufferedoutputstream.c:612 ../gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "在基礎串æµä¸­ä¸æ”¯æ´æˆªçŸ­(truncate)" + +#: ../gio/gcancellable.c:310 ../gio/gdbusconnection.c:1896 +#: ../gio/gdbusconnection.c:1989 ../gio/gdbusprivate.c:1417 +#: ../gio/glocalfile.c:2181 ../gio/gsimpleasyncresult.c:830 +#: ../gio/gsimpleasyncresult.c:856 +#, c-format +msgid "Operation was cancelled" +msgstr "æ“ä½œå·²è¢«å–æ¶ˆ" + +#: ../gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "無效的物件,尚未åˆå§‹åŒ–" + +#: ../gio/gcharsetconverter.c:281 ../gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "在輸入中出ç¾ä¸å®Œæ•´çš„多ä½å…ƒçµ„次åº" + +#: ../gio/gcharsetconverter.c:315 ../gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "在目的端中沒有足夠的空間" + +#: ../gio/gcharsetconverter.c:342 ../gio/gdatainputstream.c:848 +#: ../gio/gdatainputstream.c:1256 ../glib/gconvert.c:438 +#: ../glib/gconvert.c:845 ../glib/giochannel.c:1557 ../glib/giochannel.c:1599 +#: ../glib/giochannel.c:2443 ../glib/gutf8.c:837 ../glib/gutf8.c:1289 +msgid "Invalid byte sequence in conversion input" +msgstr "轉æ›è¼¸å…¥è³‡æ–™æ™‚é‡åˆ°ä¸æ­£ç¢ºçš„ä½å…ƒçµ„組åˆ" + +#: ../gio/gcharsetconverter.c:347 ../glib/gconvert.c:446 +#: ../glib/gconvert.c:770 ../glib/giochannel.c:1564 ../glib/giochannel.c:2455 +#, c-format +msgid "Error during conversion: %s" +msgstr "è½‰æ›æ™‚發生錯誤:%s" + +#: ../gio/gcharsetconverter.c:444 ../gio/gsocket.c:985 +msgid "Cancellable initialization not supported" +msgstr "䏿”¯æ´å¯å–消的åˆå§‹åŒ–" + +#: ../gio/gcharsetconverter.c:454 ../glib/gconvert.c:321 +#: ../glib/giochannel.c:1385 +#, c-format +msgid "Conversion from character set '%s' to '%s' is not supported" +msgstr "䏿”¯æ´å°‡å­—符集‘%sâ€™è½‰æ›æˆâ€˜%s’" + +#: ../gio/gcharsetconverter.c:458 ../glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from '%s' to '%s'" +msgstr "無法將‘%s’轉æ›è‡³â€˜%s’" + +#: ../gio/gcontenttype.c:335 +#, c-format +msgid "%s type" +msgstr "%s 類型" + +#: ../gio/gcontenttype-win32.c:160 +msgid "Unknown type" +msgstr "䏿˜Žçš„類型" + +#: ../gio/gcontenttype-win32.c:161 +#, c-format +msgid "%s filetype" +msgstr "%s 檔案類型" + +#: ../gio/gcredentials.c:312 ../gio/gcredentials.c:571 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials 沒有在這個 OS 上實作" + +#: ../gio/gcredentials.c:467 +msgid "There is no GCredentials support for your platform" +msgstr "你的平臺沒有 GCredentials 支æ´" + +#: ../gio/gcredentials.c:513 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials 沒有包å«åœ¨é€™å€‹ OS ä¸Šçš„ç¨‹åº ID" + +#: ../gio/gcredentials.c:565 +msgid "Credentials spoofing is not possible on this OS" +msgstr "在這個 OS 無法åšåˆ°è­‰æ›¸å½è£" + +#: ../gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "æœªé æœŸçš„串æµéŽæ—©çµæŸ" + +#: ../gio/gdbusaddress.c:148 ../gio/gdbusaddress.c:236 +#: ../gio/gdbusaddress.c:317 +#, c-format +msgid "Unsupported key '%s' in address entry '%s'" +msgstr "ä½å€é …目「%2$sã€æœ‰ä¸æ”¯æ´çš„設定éµã€Œ%1$sã€" + +#: ../gio/gdbusaddress.c:175 +#, c-format +msgid "" +"Address '%s' is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "ä½å€ã€Œ%sã€æ˜¯ç„¡æ•ˆçš„ï¼ˆéœ€è¦æœ‰æ˜Žç¢ºçš„ pathã€tmpdir 或 abstract 設定éµä¹‹ä¸€ï¼‰" + +#: ../gio/gdbusaddress.c:188 +#, c-format +msgid "Meaningless key/value pair combination in address entry '%s'" +msgstr "在ä½å€é …「%sã€æœ‰ç„¡æ„義的設定éµ/數值組åˆé…å°" + +#: ../gio/gdbusaddress.c:251 ../gio/gdbusaddress.c:332 +#, c-format +msgid "Error in address '%s' - the port attribute is malformed" +msgstr "ä½å€ã€Œ%sã€æœ‰éŒ¯èª¤ - port 屬性的格å¼ä¸è‰¯" + +#: ../gio/gdbusaddress.c:262 ../gio/gdbusaddress.c:343 +#, c-format +msgid "Error in address '%s' - the family attribute is malformed" +msgstr "ä½å€ã€Œ%sã€æœ‰éŒ¯èª¤ - family 屬性的格å¼ä¸è‰¯" + +#: ../gio/gdbusaddress.c:452 +#, c-format +msgid "Address element '%s' does not contain a colon (:)" +msgstr "ä½å€å…ƒç´ ã€Œ%sã€ï¼Œä¸¦æœªåŒ…å«åˆ†è™Ÿ (:)" + +#: ../gio/gdbusaddress.c:473 +#, c-format +msgid "" +"Key/Value pair %d, '%s', in address element '%s' does not contain an equal " +"sign" +msgstr "設定éµ/數值é…å° %d,「%sã€ï¼Œæ–¼ä½å€å…ƒç´ ã€Œ%sã€ï¼Œä¸¦æœªåŒ…å«ç­‰æ–¼ç¬¦è™Ÿ" + +#: ../gio/gdbusaddress.c:487 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, '%s', in address element " +"'%s'" +msgstr "在設定éµ/數值é…å° %d,「%sã€ï¼Œä½å€å…ƒç´ ã€Œ%sã€ä¸­æœ‰éŒ¯èª¤çš„å轉義設定éµ" + +#: ../gio/gdbusaddress.c:565 +#, c-format +msgid "" +"Error in address '%s' - the unix transport requires exactly one of the keys " +"'path' or 'abstract' to be set" +msgstr "ä½å€ã€Œ%sã€æœ‰éŒ¯èª¤ - unix å‚³è¼¸éœ€è¦æ˜Žç¢ºçš„設定一個「pathã€æˆ–「abstractã€è¨­å®šéµ" + +#: ../gio/gdbusaddress.c:601 +#, c-format +msgid "Error in address '%s' - the host attribute is missing or malformed" +msgstr "ä½å€ã€Œ%sã€æœ‰éŒ¯èª¤ - host 屬性éºå¤±æˆ–æ ¼å¼ä¸è‰¯" + +#: ../gio/gdbusaddress.c:615 +#, c-format +msgid "Error in address '%s' - the port attribute is missing or malformed" +msgstr "ä½å€ã€Œ%sã€æœ‰éŒ¯èª¤ - port 屬性éºå¤±æˆ–æ ¼å¼ä¸è‰¯" + +#: ../gio/gdbusaddress.c:629 +#, c-format +msgid "Error in address '%s' - the noncefile attribute is missing or malformed" +msgstr "ä½å€ã€Œ%sã€æœ‰éŒ¯èª¤ - noncefile 屬性éºå¤±æˆ–æ ¼å¼ä¸è‰¯" + +#: ../gio/gdbusaddress.c:650 +msgid "Error auto-launching: " +msgstr "自動執行失敗:" + +#: ../gio/gdbusaddress.c:658 +#, c-format +msgid "Unknown or unsupported transport '%s' for address '%s'" +msgstr "ä½å€ã€Œ%2$sã€æœ‰ä¸æ˜Žæˆ–䏿”¯æ´çš„傳輸「%1$sã€" + +#: ../gio/gdbusaddress.c:694 +#, c-format +msgid "Error opening nonce file '%s': %s" +msgstr "開啟臨時檔案「%sã€æ™‚發生錯誤:%s" + +#: ../gio/gdbusaddress.c:712 +#, c-format +msgid "Error reading from nonce file '%s': %s" +msgstr "讀å–臨時檔案「%sã€æ™‚發生錯誤:%s" + +#: ../gio/gdbusaddress.c:721 +#, c-format +msgid "Error reading from nonce file '%s', expected 16 bytes, got %d" +msgstr "讀å–臨時檔案「%sã€æ™‚ç™¼ç”ŸéŒ¯èª¤ï¼Œé æœŸç‚º 16 ä½å…ƒçµ„,å»å¾—到 %d" + +#: ../gio/gdbusaddress.c:739 +#, c-format +msgid "Error writing contents of nonce file '%s' to stream:" +msgstr "寫入臨時檔案「%sã€çš„å…§å®¹åˆ°ä¸²æµæ™‚發生錯誤:" + +#: ../gio/gdbusaddress.c:958 +msgid "The given address is empty" +msgstr "指定的ä½å€æ˜¯ç©ºç™½çš„" + +#: ../gio/gdbusaddress.c:1028 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "在 setuid 時ä¸èƒ½ç”¢ç”Ÿè¨Šæ¯åŒ¯æµæŽ’" + +#: ../gio/gdbusaddress.c:1035 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "沒有 machine-id ä¸èƒ½ç”¢ç”Ÿè¨Šæ¯åŒ¯æµæŽ’:" + +#: ../gio/gdbusaddress.c:1077 +#, c-format +msgid "Error spawning command line '%s': " +msgstr "產生命令列「%sã€æ™‚出ç¾éŒ¯èª¤ï¼š" + +#: ../gio/gdbusaddress.c:1294 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(輸入任何字符以關閉這個視窗)\n" + +#: ../gio/gdbusaddress.c:1425 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "作業階段 dbus 尚未執行,且自動執行失敗" + +#: ../gio/gdbusaddress.c:1446 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "ä¸èƒ½åˆ¤æ–·ä½œæ¥­éšŽæ®µåŒ¯æµæŽ’ä½å€ï¼ˆæ²’有在這個 OS 實作)" + +#: ../gio/gdbusaddress.c:1546 ../gio/gdbusconnection.c:6931 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"- unknown value '%s'" +msgstr "ä¸èƒ½å¾ž DBUS_STARTER_BUS_TYPE ç’°å¢ƒè®Šæ•¸åˆ¤æ–·åŒ¯æµæŽ’ä½å€ - 䏿˜Žçš„æ•¸å€¼ã€Œ%sã€" + +#: ../gio/gdbusaddress.c:1555 ../gio/gdbusconnection.c:6940 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "ä¸èƒ½åˆ¤æ–·åŒ¯æµæŽ’ä½å€ï¼Œå› ç‚ºå°šæœªè¨­å®š DBUS_STARTER_BUS_TYPE 環境變數" + +#: ../gio/gdbusaddress.c:1565 +#, c-format +msgid "Unknown bus type %d" +msgstr "䏿˜Žçš„åŒ¯æµæŽ’é¡žåž‹ %d" + +#: ../gio/gdbusauth.c:293 +msgid "Unexpected lack of content trying to read a line" +msgstr "æœªé æœŸçš„內容缺ä¹å˜—試讀å–行" + +#: ../gio/gdbusauth.c:337 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "æœªé æœŸçš„內容缺ä¹å˜—試(安全的)讀å–行" + +#: ../gio/gdbusauth.c:508 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "竭盡所有å¯ç”¨çš„æ ¸å°æ©Ÿåˆ¶ (已嘗試:%s) (å¯ç”¨ï¼š%s)" + +#: ../gio/gdbusauth.c:1170 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "å·²é€éŽ GDBusAuthObserver::authorize-authenticated-peer å–æ¶ˆ" + +#: ../gio/gdbusauthmechanismsha1.c:261 +#, c-format +msgid "Error when getting information for directory '%s': %s" +msgstr "從目錄「%sã€å–得資訊時發生錯誤:%s" + +#: ../gio/gdbusauthmechanismsha1.c:273 +#, c-format +msgid "" +"Permissions on directory '%s' are malformed. Expected mode 0700, got 0%o" +msgstr "目錄「%sã€çš„æ¬Šé™æ ¼å¼ä¸‹è‰¯ã€‚é æœŸçš„æ¨¡å¼ç‚º 0700,å»å¾—到 0%o" + +#: ../gio/gdbusauthmechanismsha1.c:294 +#, c-format +msgid "Error creating directory '%s': %s" +msgstr "建立目錄「%sã€æ™‚發生錯誤:%s" + +#: ../gio/gdbusauthmechanismsha1.c:377 +#, c-format +msgid "Error opening keyring '%s' for reading: " +msgstr "開啟密碼匙圈「%sã€è®€å–時發生錯誤:" + +#: ../gio/gdbusauthmechanismsha1.c:401 ../gio/gdbusauthmechanismsha1.c:714 +#, c-format +msgid "Line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "使–¼ã€Œ%2$sã€å…§å®¹ã€Œ%3$sã€çš„密碼匙圈第 %1$d 列格å¼ä¸è‰¯" + +#: ../gio/gdbusauthmechanismsha1.c:415 ../gio/gdbusauthmechanismsha1.c:728 +#, c-format +msgid "" +"First token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "使–¼ã€Œ%2$sã€å…§å®¹ã€Œ%3$sã€çš„密碼匙圈第 %1$d 列第一記號格å¼ä¸è‰¯" + +#: ../gio/gdbusauthmechanismsha1.c:430 ../gio/gdbusauthmechanismsha1.c:742 +#, c-format +msgid "" +"Second token of line %d of the keyring at '%s' with content '%s' is malformed" +msgstr "使–¼ã€Œ%2$sã€å…§å®¹ã€Œ%3$sã€çš„密碼匙圈第 %1$d 列第二記號格å¼ä¸è‰¯" + +#: ../gio/gdbusauthmechanismsha1.c:454 +#, c-format +msgid "Didn't find cookie with id %d in the keyring at '%s'" +msgstr "在「%2$sã€å¯†ç¢¼åŒ™åœˆæ‰¾ä¸åˆ° id %1$d çš„ cookie" + +#: ../gio/gdbusauthmechanismsha1.c:532 +#, c-format +msgid "Error deleting stale lock file '%s': %s" +msgstr "刪除舊的鎖定檔案「%sã€æ™‚發生錯誤:%s" + +#: ../gio/gdbusauthmechanismsha1.c:564 +#, c-format +msgid "Error creating lock file '%s': %s" +msgstr "建立鎖定檔案「%sã€æ™‚發生錯誤:%s" + +#: ../gio/gdbusauthmechanismsha1.c:594 +#, c-format +msgid "Error closing (unlinked) lock file '%s': %s" +msgstr "é—œé–‰ï¼ˆå–æ¶ˆé€£çµï¼‰éŽ–å®šæª”æ¡ˆæ™‚ç™¼ç”ŸéŒ¯èª¤ã€Œ%sã€ï¼š%s" + +#: ../gio/gdbusauthmechanismsha1.c:604 +#, c-format +msgid "Error unlinking lock file '%s': %s" +msgstr "å–æ¶ˆé€£çµéŽ–å®šæª”æ¡ˆæ™‚ç™¼ç”ŸéŒ¯èª¤ã€Œ%sã€ï¼š%s" + +#: ../gio/gdbusauthmechanismsha1.c:681 +#, c-format +msgid "Error opening keyring '%s' for writing: " +msgstr "開啟密碼匙圈「%sã€å¯«å…¥æ™‚發生錯誤:" + +#: ../gio/gdbusauthmechanismsha1.c:878 +#, c-format +msgid "(Additionally, releasing the lock for '%s' also failed: %s) " +msgstr "(å¦å¤–,釋放「%sã€çš„鎖定失敗:%s)" + +#: ../gio/gdbusconnection.c:612 ../gio/gdbusconnection.c:2455 +msgid "The connection is closed" +msgstr "這個連線已關閉" + +#: ../gio/gdbusconnection.c:1942 +msgid "Timeout was reached" +msgstr "å·²é”逾時時間" + +#: ../gio/gdbusconnection.c:2577 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "當建立客戶端連線時é‡åˆ°ä¸æ”¯æ´çš„æ——標" + +#: ../gio/gdbusconnection.c:4157 ../gio/gdbusconnection.c:4504 +#, c-format +msgid "" +"No such interface 'org.freedesktop.DBus.Properties' on object at path %s" +msgstr "在路徑 %s 的物件沒有「org.freedesktop.DBus.Propertiesã€é€™å€‹ä»‹é¢" + +#: ../gio/gdbusconnection.c:4299 +#, c-format +msgid "No such property '%s'" +msgstr "沒有這個屬性「%sã€" + +#: ../gio/gdbusconnection.c:4311 +#, c-format +msgid "Property '%s' is not readable" +msgstr "屬性「%sã€ç„¡æ³•讀å–" + +#: ../gio/gdbusconnection.c:4322 +#, c-format +msgid "Property '%s' is not writable" +msgstr "屬性「%sã€ç„¡æ³•寫入" + +#: ../gio/gdbusconnection.c:4342 +#, c-format +msgid "Error setting property '%s': Expected type '%s' but got '%s'" +msgstr "設定屬性「%sã€éŒ¯èª¤ï¼šé æœŸçš„類型為「%sã€ä½†å¾—到「%sã€" + +#: ../gio/gdbusconnection.c:4447 ../gio/gdbusconnection.c:6371 +#, c-format +msgid "No such interface '%s'" +msgstr "沒有這個介é¢ã€Œ%sã€" + +#: ../gio/gdbusconnection.c:4655 +msgid "No such interface" +msgstr "沒有這個介é¢" + +#: ../gio/gdbusconnection.c:4873 ../gio/gdbusconnection.c:6880 +#, c-format +msgid "No such interface '%s' on object at path %s" +msgstr "在路徑 %2$s 的物件沒有「%1$sã€é€™å€‹ä»‹é¢" + +#: ../gio/gdbusconnection.c:4971 +#, c-format +msgid "No such method '%s'" +msgstr "沒有這個方法「%sã€" + +#: ../gio/gdbusconnection.c:5002 +#, c-format +msgid "Type of message, '%s', does not match expected type '%s'" +msgstr "訊æ¯çš„類型,「%sã€ï¼Œä¸ç¬¦åˆé æœŸçš„類型「%sã€" + +#: ../gio/gdbusconnection.c:5200 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "æœ‰ç‰©ä»¶å·²ç‚ºä»‹é¢ %s 匯出於 %s" + +#: ../gio/gdbusconnection.c:5399 +#, c-format +msgid "Method '%s' returned type '%s', but expected '%s'" +msgstr "方法「%sã€å‚³å›žé¡žåž‹ã€Œ%sã€ï¼Œä½†é æœŸç‚ºã€Œ%sã€" + +#: ../gio/gdbusconnection.c:6482 +#, c-format +msgid "Method '%s' on interface '%s' with signature '%s' does not exist" +msgstr "介é¢ã€Œ%2$sã€ç°½ç½²ã€Œ%3$sã€çš„æ–¹æ³•「%1$sã€ä¸å­˜åœ¨" + +#: ../gio/gdbusconnection.c:6603 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "å­æ¨¹ç‹€ç›®éŒ„已為 %s 匯出" + +#: ../gio/gdbusmessage.c:1246 +msgid "type is INVALID" +msgstr "類型為無效" + +#: ../gio/gdbusmessage.c:1257 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL 訊æ¯ï¼šç¼ºå°‘ PATH 或 MEMBER 標頭欄ä½" + +#: ../gio/gdbusmessage.c:1268 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN 訊æ¯ï¼šç¼ºå°‘ REPLY_SERIAL 標頭欄ä½" + +#: ../gio/gdbusmessage.c:1280 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR 訊æ¯ï¼šç¼ºå°‘ REPLY_SERIAL 或 ERROR_NAME 標頭欄ä½" + +#: ../gio/gdbusmessage.c:1293 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL 訊æ¯ï¼šç¼ºå°‘ PATHã€INTERFACE 或 MEMBER 標頭欄ä½" + +#: ../gio/gdbusmessage.c:1301 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "SIGNAL 訊æ¯ï¼šPATH 標頭欄ä½ä½¿ç”¨äº†ä¿ç•™çš„æ•¸å€¼ /org/freedesktop/DBus/Local" + +#: ../gio/gdbusmessage.c:1309 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "SIGNAL 訊æ¯ï¼šINTERFACE 標頭欄ä½ä½¿ç”¨äº†ä¿ç•™çš„æ•¸å€¼ org.freedesktop.DBus.Local" + +#: ../gio/gdbusmessage.c:1357 ../gio/gdbusmessage.c:1417 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "å˜—è©¦è®€å– %lu ä½å…ƒçµ„å»åªå¾—到 %lu" + +#: ../gio/gdbusmessage.c:1371 +#, c-format +msgid "Expected NUL byte after the string '%s' but found byte %d" +msgstr "é æœŸåœ¨å­—串「%sã€ä¹‹å¾Œç‚º NUL ä½å…ƒçµ„,但是發ç¾ä½å…ƒçµ„ %d" + +#: ../gio/gdbusmessage.c:1390 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was '%s'" +msgstr "é æœŸç‚ºæœ‰æ•ˆçš„ UTF-8 字串但是在ä½å…ƒçµ„ %d 處發ç¾ç„¡æ•ˆçš„ä½å…ƒçµ„(字串的長度為 %d)。到那一點之å‰çš„æœ‰æ•ˆ UTF-8 字串為「%sã€" + +#: ../gio/gdbusmessage.c:1589 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus object path" +msgstr "å·²è§£æžæ•¸å€¼ã€Œ%sã€ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus 物件路徑" + +#: ../gio/gdbusmessage.c:1611 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature" +msgstr "å·²è§£æžæ•¸å€¼ã€Œ%sã€ä¸æ˜¯ä¸€å€‹æœ‰æ•ˆçš„ D-Bus 簽署" + +#: ../gio/gdbusmessage.c:1658 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "é‡åˆ°é•·åº¦ç‚º %u ä½å…ƒçµ„的陣列。最大長度為 2<<26 ä½å…ƒçµ„ (64 MiB)。" + +#: ../gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of type 'a%c', expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "é‡åˆ°é¡žåž‹ã€Œa%cã€çš„é™£åˆ—ï¼Œé æœŸé•·åº¦æ‡‰ç‚º %u ä½å…ƒçµ„çš„å€æ•¸ï¼Œä½†ç™¼ç¾é•·åº¦ç‚º %u ä½å…ƒçµ„" + +#: ../gio/gdbusmessage.c:1845 +#, c-format +msgid "Parsed value '%s' for variant is not a valid D-Bus signature" +msgstr "å·²åˆ†æžæ•¸å€¼ã€Œ%sã€ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus 簽署" + +#: ../gio/gdbusmessage.c:1869 +#, c-format +msgid "" +"Error deserializing GVariant with type string '%s' from the D-Bus wire format" +msgstr "從 D-Bus 線性格å¼ä»¥é¡žåž‹å­—串「%sã€ååºåˆ—化 GVariant 時發生錯誤" + +#: ../gio/gdbusmessage.c:2053 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c ('l') or 0x42 ('B') but found value " +"0x%02x" +msgstr "無效的ä½å…ƒçµ„é †åºæ•¸å€¼ã€‚é æœŸç‚º 0x6c「Iã€æˆ– 0x42「Bã€å»å¾—到數值 0x%02x" + +#: ../gio/gdbusmessage.c:2066 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "無效的主通訊å”å®šç‰ˆæœ¬ã€‚é æœŸç‚º 1 但找到 %d" + +#: ../gio/gdbusmessage.c:2122 +#, c-format +msgid "Signature header with signature '%s' found but message body is empty" +msgstr "發ç¾ç°½ç½²ã€Œ%sã€çš„簽署標頭但訊æ¯ä¸»é«”是空的" + +#: ../gio/gdbusmessage.c:2136 +#, c-format +msgid "Parsed value '%s' is not a valid D-Bus signature (for body)" +msgstr "å·²è§£æžæ•¸å€¼ã€Œ%sã€ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus 簽署 (於主體)" + +#: ../gio/gdbusmessage.c:2166 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "在訊æ¯ä¸­æ²’有簽署標頭但訊æ¯ä¸»é«”有 %u ä½å…ƒçµ„" + +#: ../gio/gdbusmessage.c:2176 +msgid "Cannot deserialize message: " +msgstr "ä¸èƒ½ååºåˆ—化訊æ¯ï¼š" + +#: ../gio/gdbusmessage.c:2517 +#, c-format +msgid "" +"Error serializing GVariant with type string '%s' to the D-Bus wire format" +msgstr "從 D-Bus 線性格å¼ä»¥é¡žåž‹å­—串「%sã€åºåˆ—化 GVariant 時發生錯誤" + +#: ../gio/gdbusmessage.c:2654 +#, c-format +msgid "" +"Message has %d file descriptors but the header field indicates %d file " +"descriptors" +msgstr "è¨Šæ¯æœ‰ %d 檔案æè¿°ç¬¦ä½†æ¨™é ­æ¬„ä½è¡¨ç¤ºæœ‰ %d 檔案æè¿°ç¬¦" + +#: ../gio/gdbusmessage.c:2662 +msgid "Cannot serialize message: " +msgstr "ä¸èƒ½åºåˆ—化訊æ¯ï¼š" + +#: ../gio/gdbusmessage.c:2706 +#, c-format +msgid "Message body has signature '%s' but there is no signature header" +msgstr "訊æ¯ä¸»é«”有簽署「%sã€ä½†æ˜¯æ²’有簽署標頭" + +#: ../gio/gdbusmessage.c:2716 +#, c-format +msgid "" +"Message body has type signature '%s' but signature in the header field is " +"'%s'" +msgstr "訊æ¯ä¸»é«”有類型簽署「%sã€ä½†æ˜¯æ¨™é ­æ¬„ä½ä¸­çš„簽署為「%sã€" + +#: ../gio/gdbusmessage.c:2732 +#, c-format +msgid "Message body is empty but signature in the header field is '(%s)'" +msgstr "訊æ¯ä¸»é«”是空的但是標頭欄ä½ä¸­çš„簽署為「%sã€" + +#: ../gio/gdbusmessage.c:3282 +#, c-format +msgid "Error return with body of type '%s'" +msgstr "傳回類型「%sã€ä¸»é«”時發生錯誤" + +#: ../gio/gdbusmessage.c:3290 +msgid "Error return with empty body" +msgstr "傳回空白主體錯誤" + +#: ../gio/gdbusprivate.c:2067 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "無法å–得硬件設定組åˆï¼š%s" + +#: ../gio/gdbusprivate.c:2112 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "無法載入 /var/lib/dbus/machine-id 或 /etc/machine-id:" + +#: ../gio/gdbusproxy.c:1630 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "å‘¼å« %s StartServiceByName 時發生錯誤:" + +#: ../gio/gdbusproxy.c:1653 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "來自 StartServiceByName(\"%2$s\") æ–¹æ³•çš„æœªé æœŸå›žæ‡‰ %1$d" + +#: ../gio/gdbusproxy.c:2754 ../gio/gdbusproxy.c:2891 +msgid "" +"Cannot invoke method; proxy is for a well-known name without an owner and " +"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "ä¸èƒ½å‘¼å«æ–¹æ³•ï¼›proxy æ˜¯æ²’æœ‰æ“æœ‰è€…的知åå稱,而 proxy 是以 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START 旗標建立的" + +#: ../gio/gdbusserver.c:708 +msgid "Abstract name space not supported" +msgstr "䏿”¯æ´æŠ½è±¡å‘½å空間" + +#: ../gio/gdbusserver.c:795 +msgid "Cannot specify nonce file when creating a server" +msgstr "當建立伺æœå™¨æ™‚ä¸èƒ½æŒ‡å®šè‡¨æ™‚檔案" + +#: ../gio/gdbusserver.c:873 +#, c-format +msgid "Error writing nonce file at '%s': %s" +msgstr "在「%sã€å¯«å…¥è‡¨æ™‚檔案時發生錯誤:%s" + +#: ../gio/gdbusserver.c:1044 +#, c-format +msgid "The string '%s' is not a valid D-Bus GUID" +msgstr "字串「%sã€ä¸æ˜¯ä¸€å€‹æœ‰æ•ˆçš„ D-Bus GUID" + +#: ../gio/gdbusserver.c:1084 +#, c-format +msgid "Cannot listen on unsupported transport '%s'" +msgstr "ä¸èƒ½è½å–䏿”¯æ´çš„傳輸「%sã€" + +#: ../gio/gdbus-tool.c:95 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +"\n" +"Use \"%s COMMAND --help\" to get help on each command.\n" +msgstr "" +"指令:\n" +" help 顯示這個資訊\n" +" introspect 檢查é ç«¯ç‰©ä»¶\n" +" monitor 監控é ç«¯ç‰©ä»¶\n" +" call 呼å«é ç«¯ç‰©ä»¶çš„æ–¹æ³•\n" +" emit 發出信號\n" +"\n" +"使用「%s COMMAND --helpã€ä¾†å–å¾—æ¯å€‹æŒ‡ä»¤çš„æ±‚助資訊。\n" + +#: ../gio/gdbus-tool.c:164 ../gio/gdbus-tool.c:220 ../gio/gdbus-tool.c:292 +#: ../gio/gdbus-tool.c:316 ../gio/gdbus-tool.c:705 ../gio/gdbus-tool.c:1031 +#: ../gio/gdbus-tool.c:1465 +#, c-format +msgid "Error: %s\n" +msgstr "錯誤:%s\n" + +#: ../gio/gdbus-tool.c:175 ../gio/gdbus-tool.c:233 ../gio/gdbus-tool.c:1481 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "è§£æžæª¢è¨Ž XML 時出ç¾éŒ¯èª¤ï¼š%s\n" + +#: ../gio/gdbus-tool.c:350 +msgid "Connect to the system bus" +msgstr "é€£ç·šåˆ°ç³»çµ±åŒ¯æµæŽ’" + +#: ../gio/gdbus-tool.c:351 +msgid "Connect to the session bus" +msgstr "é€£ç·šåˆ°ä½œæ¥­éšŽæ®µåŒ¯æµæŽ’" + +#: ../gio/gdbus-tool.c:352 +msgid "Connect to given D-Bus address" +msgstr "連線到指定的 D-Bus ä½å€" + +#: ../gio/gdbus-tool.c:362 +msgid "Connection Endpoint Options:" +msgstr "連線端點é¸é …:" + +#: ../gio/gdbus-tool.c:363 +msgid "Options specifying the connection endpoint" +msgstr "指定連線端點的é¸é …" + +#: ../gio/gdbus-tool.c:385 +#, c-format +msgid "No connection endpoint specified" +msgstr "沒有指定連線端點" + +#: ../gio/gdbus-tool.c:395 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "指定了多é‡é€£ç·šç«¯é»ž" + +#: ../gio/gdbus-tool.c:465 +#, c-format +msgid "" +"Warning: According to introspection data, interface '%s' does not exist\n" +msgstr "警告:根據檢討資料,介é¢ã€Œ%sã€ä¸å­˜åœ¨\n" + +#: ../gio/gdbus-tool.c:474 +#, c-format +msgid "" +"Warning: According to introspection data, method '%s' does not exist on " +"interface '%s'\n" +msgstr "警告:根據檢討資料,介é¢ã€Œ%2$sã€çš„æ–¹æ³•「%1$sã€ä¸å­˜åœ¨\n" + +#: ../gio/gdbus-tool.c:536 +msgid "Optional destination for signal (unique name)" +msgstr "ä¿¡è™Ÿçš„é¸æ“‡æ€§ç›®çš„端 (ç¨ç‰¹å稱)" + +#: ../gio/gdbus-tool.c:537 +msgid "Object path to emit signal on" +msgstr "è¦ç™¼å‡ºä¿¡è™Ÿçš„物件路徑" + +#: ../gio/gdbus-tool.c:538 +msgid "Signal and interface name" +msgstr "信號和介é¢å稱" + +#: ../gio/gdbus-tool.c:570 +msgid "Emit a signal." +msgstr "發出信號。" + +#: ../gio/gdbus-tool.c:604 ../gio/gdbus-tool.c:836 ../gio/gdbus-tool.c:1571 +#: ../gio/gdbus-tool.c:1799 +#, c-format +msgid "Error connecting: %s\n" +msgstr "連線錯誤:%s\n" + +#: ../gio/gdbus-tool.c:616 +#, c-format +msgid "Error: object path not specified.\n" +msgstr "錯誤:沒有指定物件路徑。\n" + +#: ../gio/gdbus-tool.c:621 ../gio/gdbus-tool.c:897 ../gio/gdbus-tool.c:1629 +#: ../gio/gdbus-tool.c:1858 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„物件路徑\n" + +#: ../gio/gdbus-tool.c:627 +#, c-format +msgid "Error: signal not specified.\n" +msgstr "錯誤:尚未指定信號。\n" + +#: ../gio/gdbus-tool.c:634 +#, c-format +msgid "Error: signal must be the fully-qualified name.\n" +msgstr "錯誤:信號必須為完全åˆè¦å®šçš„å稱。\n" + +#: ../gio/gdbus-tool.c:642 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„介é¢å稱\n" + +#: ../gio/gdbus-tool.c:648 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„æˆå“¡å稱\n" + +#: ../gio/gdbus-tool.c:654 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„ç¨ç‰¹åŒ¯æµæŽ’å稱。\n" + +#. Use the original non-"parse-me-harder" error +#: ../gio/gdbus-tool.c:681 ../gio/gdbus-tool.c:999 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "è§£æžåƒæ•¸ %d 時發生錯誤:%s\n" + +#: ../gio/gdbus-tool.c:712 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "清除連線時發生錯誤:%s\n" + +#: ../gio/gdbus-tool.c:739 +msgid "Destination name to invoke method on" +msgstr "è¦å‘¼å«æ–¹æ³•的目的端å稱" + +#: ../gio/gdbus-tool.c:740 +msgid "Object path to invoke method on" +msgstr "è¦å‘¼å«æ–¹æ³•的物件路徑" + +#: ../gio/gdbus-tool.c:741 +msgid "Method and interface name" +msgstr "方法和介é¢å稱" + +#: ../gio/gdbus-tool.c:742 +msgid "Timeout in seconds" +msgstr "逾時時間(ç§’)" + +#: ../gio/gdbus-tool.c:781 +msgid "Invoke a method on a remote object." +msgstr "呼å«é ç«¯ç‰©ä»¶çš„æ–¹æ³•。" + +#: ../gio/gdbus-tool.c:856 ../gio/gdbus-tool.c:1590 ../gio/gdbus-tool.c:1818 +#, c-format +msgid "Error: Destination is not specified\n" +msgstr "錯誤:尚未指定目的端\n" + +#: ../gio/gdbus-tool.c:877 ../gio/gdbus-tool.c:1609 +#, c-format +msgid "Error: Object path is not specified\n" +msgstr "錯誤:沒有指定物件路徑\n" + +#: ../gio/gdbus-tool.c:912 +#, c-format +msgid "Error: Method name is not specified\n" +msgstr "錯誤:沒有指定方法å稱\n" + +#: ../gio/gdbus-tool.c:923 +#, c-format +msgid "Error: Method name '%s' is invalid\n" +msgstr "錯誤:方法å稱「%sã€æ˜¯ç„¡æ•ˆçš„\n" + +#: ../gio/gdbus-tool.c:991 +#, c-format +msgid "Error parsing parameter %d of type '%s': %s\n" +msgstr "è§£æžé¡žåž‹ã€Œ%2$sã€çš„åƒæ•¸ %1$d 時發生錯誤:%3$s\n" + +#: ../gio/gdbus-tool.c:1428 +msgid "Destination name to introspect" +msgstr "è¦æª¢è¨Žçš„目的端å稱" + +#: ../gio/gdbus-tool.c:1429 +msgid "Object path to introspect" +msgstr "è¦æª¢è¨Žçš„物件路徑" + +#: ../gio/gdbus-tool.c:1430 +msgid "Print XML" +msgstr "顯示 XML" + +#: ../gio/gdbus-tool.c:1431 +msgid "Introspect children" +msgstr "Introspect å­é …ç›®" + +#: ../gio/gdbus-tool.c:1432 +msgid "Only print properties" +msgstr "åªæœ‰åˆ—å°å±¬æ€§" + +#: ../gio/gdbus-tool.c:1523 +msgid "Introspect a remote object." +msgstr "檢討é ç«¯ç‰©ä»¶ã€‚" + +#: ../gio/gdbus-tool.c:1721 +msgid "Destination name to monitor" +msgstr "è¦ç›£æŽ§çš„目的端å稱" + +#: ../gio/gdbus-tool.c:1722 +msgid "Object path to monitor" +msgstr "è¦ç›£æŽ§çš„物件路徑" + +#: ../gio/gdbus-tool.c:1751 +msgid "Monitor a remote object." +msgstr "監控é ç«¯ç‰©ä»¶ã€‚" + +#: ../gio/gdesktopappinfo.c:1919 ../gio/gdesktopappinfo.c:4440 +#: ../gio/gwin32appinfo.c:219 +msgid "Unnamed" +msgstr "未命åçš„" + +#: ../gio/gdesktopappinfo.c:2328 +msgid "Desktop file didn't specify Exec field" +msgstr "桌é¢(Desktop)檔案未指定 Exec 欄ä½" + +#: ../gio/gdesktopappinfo.c:2613 +msgid "Unable to find terminal required for application" +msgstr "無法找到應用程å¼è¦æ±‚的終端機" + +#: ../gio/gdesktopappinfo.c:3034 +#, c-format +msgid "Can't create user application configuration folder %s: %s" +msgstr "ä¸èƒ½å»ºç«‹ä½¿ç”¨è€…應用程å¼çµ„態資料夾 %s:%s" + +#: ../gio/gdesktopappinfo.c:3038 +#, c-format +msgid "Can't create user MIME configuration folder %s: %s" +msgstr "ä¸èƒ½å»ºç«‹ä½¿ç”¨è€… MIME 組態資料夾 %s:%s" + +#: ../gio/gdesktopappinfo.c:3278 ../gio/gdesktopappinfo.c:3302 +msgid "Application information lacks an identifier" +msgstr "應用程å¼è³‡è¨Šç¼ºå°‘識別碼" + +#: ../gio/gdesktopappinfo.c:3535 +#, c-format +msgid "Can't create user desktop file %s" +msgstr "ä¸èƒ½å»ºç«‹ä½¿ç”¨è€…æ¡Œé¢æª”案 %s" + +#: ../gio/gdesktopappinfo.c:3669 +#, c-format +msgid "Custom definition for %s" +msgstr "è‡ªé¸ %s 的定義" + +#: ../gio/gdrive.c:392 +msgid "drive doesn't implement eject" +msgstr "è£ç½®ç„¡æ³•實作退出功能(eject)" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gdrive.c:470 +msgid "drive doesn't implement eject or eject_with_operation" +msgstr "è£ç½®ç„¡æ³•實作退出功能(eject) 或 eject_with_operation" + +#: ../gio/gdrive.c:546 +msgid "drive doesn't implement polling for media" +msgstr "è£ç½®ç„¡æ³•實作媒體的輪詢" + +#: ../gio/gdrive.c:751 +msgid "drive doesn't implement start" +msgstr "è£ç½®ç„¡æ³•實作啟動功能(start)" + +#: ../gio/gdrive.c:853 +msgid "drive doesn't implement stop" +msgstr "è£ç½®ç„¡æ³•å¯¦ä½œåœæ­¢åŠŸèƒ½(stop)" + +#: ../gio/gdummytlsbackend.c:189 ../gio/gdummytlsbackend.c:311 +#: ../gio/gdummytlsbackend.c:401 +msgid "TLS support is not available" +msgstr "TLS 支æ´ç„¡æ³•使用" + +#: ../gio/gemblem.c:323 +#, c-format +msgid "Can't handle version %d of GEmblem encoding" +msgstr "ä¸èƒ½è™•ç†ç‰ˆæœ¬ç‚º %d çš„ GEmblem 編碼" + +#: ../gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem 編碼中記號 (%d) çš„æ•¸é‡æ ¼å¼ä¸æ­£ç¢º" + +#: ../gio/gemblemedicon.c:362 +#, c-format +msgid "Can't handle version %d of GEmblemedIcon encoding" +msgstr "ä¸èƒ½è™•ç†ç‰ˆæœ¬ç‚º %d çš„ GEmblemedIcon 編碼" + +#: ../gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon 編碼中記號 (%d) çš„æ•¸é‡æ ¼å¼ä¸æ­£ç¢º" + +#: ../gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "é æœŸç‚º GEmblemedIcon çš„ GEmblem" + +#: ../gio/gfile.c:956 ../gio/gfile.c:1194 ../gio/gfile.c:1332 +#: ../gio/gfile.c:1570 ../gio/gfile.c:1625 ../gio/gfile.c:1683 +#: ../gio/gfile.c:1767 ../gio/gfile.c:1824 ../gio/gfile.c:1888 +#: ../gio/gfile.c:1943 ../gio/gfile.c:3591 ../gio/gfile.c:3646 +#: ../gio/gfile.c:3853 ../gio/gfile.c:3895 ../gio/gfile.c:4358 +#: ../gio/gfile.c:4769 ../gio/gfile.c:4854 ../gio/gfile.c:4944 +#: ../gio/gfile.c:5041 ../gio/gfile.c:5128 ../gio/gfile.c:5229 +#: ../gio/gfile.c:7748 ../gio/gfile.c:7838 ../gio/gfile.c:7922 +#: ../gio/win32/gwinhttpfile.c:437 +msgid "Operation not supported" +msgstr "䏿”¯æ´çš„æ“ä½œ" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#. Translators: This is an error message when trying to +#. * find the enclosing (user visible) mount of a file, but +#. * none exists. +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#: ../gio/gfile.c:1455 ../gio/glocalfile.c:1103 ../gio/glocalfile.c:1114 +#: ../gio/glocalfile.c:1127 +msgid "Containing mount does not exist" +msgstr "包å«äº†ä¸å­˜åœ¨çš„æŽ›è¼‰é»ž" + +#: ../gio/gfile.c:2502 ../gio/glocalfile.c:2337 +msgid "Can't copy over directory" +msgstr "ä¸èƒ½è¤‡è£½æ•´å€‹ç›®éŒ„" + +#: ../gio/gfile.c:2562 +msgid "Can't copy directory over directory" +msgstr "ä¸èƒ½å°‡ç›®éŒ„複製到目錄上" + +#: ../gio/gfile.c:2570 ../gio/glocalfile.c:2346 +msgid "Target file exists" +msgstr "目標檔案已存在" + +#: ../gio/gfile.c:2589 +msgid "Can't recursively copy directory" +msgstr "ä¸èƒ½éžå»»è¤‡è£½ç›®éŒ„" + +#: ../gio/gfile.c:2871 +msgid "Splice not supported" +msgstr "䏿”¯æ´æ‹¼æŽ¥" + +#: ../gio/gfile.c:2875 +#, c-format +msgid "Error splicing file: %s" +msgstr "拼接檔案時發生錯誤:%s" + +#: ../gio/gfile.c:3006 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "䏿”¯æ´åœ¨æŽ›è¼‰é»žä¹‹é–“複製 (åƒç…§é€£çµ/é‡è£½)" + +#: ../gio/gfile.c:3010 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "複製 (åƒç…§é€£çµ/é‡è£½) 䏿”¯æ´æˆ–無效" + +#: ../gio/gfile.c:3015 +msgid "Copy (reflink/clone) is not supported or didn't work" +msgstr "複製 (åƒç…§é€£çµ/é‡è£½) 䏿”¯æ´æˆ–無法é‹ä½œ" + +#: ../gio/gfile.c:3078 +msgid "Can't copy special file" +msgstr "ä¸èƒ½è¤‡è£½ç‰¹æ®Šçš„æª”案" + +#: ../gio/gfile.c:3843 +msgid "Invalid symlink value given" +msgstr "æä¾›äº†ç„¡æ•ˆçš„符號連çµå€¼" + +#: ../gio/gfile.c:4004 +msgid "Trash not supported" +msgstr "䏿”¯æ´å›žæ”¶ç­’" + +#: ../gio/gfile.c:4116 +#, c-format +msgid "File names cannot contain '%c'" +msgstr "檔案å稱ä¸èƒ½åŒ…å«ã€Œ%cã€" + +#: ../gio/gfile.c:6540 ../gio/gvolume.c:363 +msgid "volume doesn't implement mount" +msgstr "儲存å€å°šæœªå¯¦ä½œæŽ›è¼‰åŠŸèƒ½" + +#: ../gio/gfile.c:6649 +msgid "No application is registered as handling this file" +msgstr "沒有應用程å¼è¨»å†Šç‚ºç”¨ä»¥è™•ç†é€™å€‹æª”案" + +#: ../gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "檔案列舉器(enumerator)已關閉" + +#: ../gio/gfileenumerator.c:219 ../gio/gfileenumerator.c:278 +#: ../gio/gfileenumerator.c:377 ../gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "檔案列舉器(enumerator)有異常æ“作" + +#: ../gio/gfileenumerator.c:368 ../gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "檔案列舉器(enumerator)已經關閉" + +#: ../gio/gfileicon.c:236 +#, c-format +msgid "Can't handle version %d of GFileIcon encoding" +msgstr "ä¸èƒ½è™•ç†ç‰ˆæœ¬ç‚º %d çš„ GFileIcon 編碼" + +#: ../gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "給 GFileIcon 的輸入資料格å¼ä¸è‰¯" + +#: ../gio/gfileinputstream.c:149 ../gio/gfileinputstream.c:394 +#: ../gio/gfileiostream.c:167 ../gio/gfileoutputstream.c:164 +#: ../gio/gfileoutputstream.c:497 +msgid "Stream doesn't support query_info" +msgstr "串æµä¸æ”¯æ´ query_info" + +#: ../gio/gfileinputstream.c:325 ../gio/gfileiostream.c:379 +#: ../gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "䏿”¯æ´åœ¨ä¸²æµä¸­æœå°‹" + +#: ../gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "在輸入串æµä¸­ä¸å…許截短(truncate)" + +#: ../gio/gfileiostream.c:455 ../gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "在串æµä¸­ä¸æ”¯æ´æˆªçŸ­(truncate)" + +#: ../gio/gicon.c:290 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "è¨˜è™Ÿæ•¸é‡ (%d) 錯誤" + +#: ../gio/gicon.c:310 +#, c-format +msgid "No type for class name %s" +msgstr "類別å稱 %s 沒有類型" + +#: ../gio/gicon.c:320 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "類型 %s 沒有實作 GIcon 介é¢" + +#: ../gio/gicon.c:331 +#, c-format +msgid "Type %s is not classed" +msgstr "類型 %s 尚未歸類" + +#: ../gio/gicon.c:345 +#, c-format +msgid "Malformed version number: %s" +msgstr "æ ¼å¼ä¸è‰¯çš„版本號碼:%s" + +#: ../gio/gicon.c:359 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "類型 %s 沒有實作 GIcon 介é¢çš„ from_tokens()" + +#: ../gio/gicon.c:461 +msgid "Can't handle the supplied version of the icon encoding" +msgstr "ä¸èƒ½è™•ç†æä¾›çš„åœ–ç¤ºç·¨ç¢¼ç‰ˆæœ¬" + +#: ../gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "尚未指定ä½å€" + +#: ../gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "長度 %u å°ä½å€ä¾†èªªå¤ªé•·äº†" + +#: ../gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ä½å€åœ¨ prefix length 後有ä½å…ƒè¨­å®š" + +#: ../gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse '%s' as IP address mask" +msgstr "無法解æžã€Œ%sã€åšç‚º IP ä½å€é®ç½©" + +#: ../gio/ginetsocketaddress.c:196 ../gio/ginetsocketaddress.c:213 +#: ../gio/gunixsocketaddress.c:209 +msgid "Not enough space for socket address" +msgstr "socket ä½å€æ²’有足夠的空間" + +#: ../gio/ginetsocketaddress.c:228 +msgid "Unsupported socket address" +msgstr "䏿”¯æ´çš„ socket ä½å€" + +#: ../gio/ginputstream.c:185 +msgid "Input stream doesn't implement read" +msgstr "輸入串æµå°šæœªå¯¦ä½œè®€å–" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: ../gio/ginputstream.c:1027 ../gio/giostream.c:287 +#: ../gio/goutputstream.c:1474 +msgid "Stream has outstanding operation" +msgstr "ä¸²æµæœ‰ç•°å¸¸æ“作" + +#: ../gio/glib-compile-resources.c:142 ../gio/glib-compile-schemas.c:1453 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "元素 <%s> ä¸å¯å‡ºç¾åœ¨ <%s> å…§" + +#: ../gio/glib-compile-resources.c:146 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "元素 <%s> ä¸å…許在頂端層級" + +#: ../gio/glib-compile-resources.c:236 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "檔案 %s 似乎在這個資æºå‡ºå‡ºç¾å¤šæ¬¡" + +#: ../gio/glib-compile-resources.c:249 +#, c-format +msgid "Failed to locate '%s' in any source directory" +msgstr "無法在任何來æºç›®éŒ„中定ä½ã€Œ%sã€" + +#: ../gio/glib-compile-resources.c:260 +#, c-format +msgid "Failed to locate '%s' in current directory" +msgstr "無法在目å‰çš„目錄中定ä½ã€Œ%sã€" + +#: ../gio/glib-compile-resources.c:288 +#, c-format +msgid "Unknown processing option \"%s\"" +msgstr "䏿˜Žçš„置處ç†é¸é …「%sã€" + +#: ../gio/glib-compile-resources.c:306 ../gio/glib-compile-resources.c:352 +#, c-format +msgid "Failed to create temp file: %s" +msgstr "無法建立暫存檔案:%s" + +#: ../gio/glib-compile-resources.c:380 +#, c-format +msgid "Error reading file %s: %s" +msgstr "è®€å–æª”案 %s 時發生錯誤:%s" + +#: ../gio/glib-compile-resources.c:400 +#, c-format +msgid "Error compressing file %s" +msgstr "壓縮檔案 %s 時發生錯誤" + +#: ../gio/glib-compile-resources.c:464 ../gio/glib-compile-schemas.c:1565 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "在 <%s> å…§ä¸èƒ½å‡ºç¾æ–‡å­—" + +#: ../gio/glib-compile-resources.c:589 +msgid "name of the output file" +msgstr "輸出檔案的å稱" + +#: ../gio/glib-compile-resources.c:590 +msgid "" +"The directories where files are to be read from (default to current " +"directory)" +msgstr "ç”¨ä¾†è®€å–æª”案的目錄 (é è¨­ç‚ºç›®å‰çš„目錄)" + +#: ../gio/glib-compile-resources.c:590 ../gio/glib-compile-schemas.c:1994 +#: ../gio/glib-compile-schemas.c:2023 +msgid "DIRECTORY" +msgstr "目錄" + +#: ../gio/glib-compile-resources.c:591 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "以目標檔案å稱的延伸檔å來鏿“‡è¦ç”¢ç”Ÿè¼¸å‡ºçš„æ ¼å¼" + +#: ../gio/glib-compile-resources.c:592 +msgid "Generate source header" +msgstr "ç”¢ç”Ÿä¾†æºæ¨™é ­" + +#: ../gio/glib-compile-resources.c:593 +msgid "Generate sourcecode used to link in the resource file into your code" +msgstr "產生原始碼用來連çµè³‡æºæª”到你的程å¼ç¢¼ä¸­" + +#: ../gio/glib-compile-resources.c:594 +msgid "Generate dependency list" +msgstr "產生相根據性清單" + +#: ../gio/glib-compile-resources.c:595 +msgid "Don't automatically create and register resource" +msgstr "ä¸è¦è‡ªå‹•建立與註冊資æº" + +#: ../gio/glib-compile-resources.c:596 +msgid "Don't export functions; declare them G_GNUC_INTERNAL" +msgstr "ä¸ç”¨åŒ¯å‡ºå‡½æ•¸ï¼›å®£å‘Šä»–們為 G_GNUC_INTERNAL" + +#: ../gio/glib-compile-resources.c:597 +msgid "C identifier name used for the generated source code" +msgstr "用於產生原始碼的 C 識別碼å稱" + +#: ../gio/glib-compile-resources.c:623 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"將資æºè¦æ ¼ç·¨è­¯é€²è³‡æºæª”。\n" +"資æºè¦æ ¼æª”案的延伸檔å必須為 .gresource.xml,\n" +"è€Œè³‡æºæª”案的延伸檔åå«åš .gresource。" + +#: ../gio/glib-compile-resources.c:639 +#, c-format +msgid "You should give exactly one file name\n" +msgstr "你應該明確指定一個檔案å稱\n" + +#: ../gio/glib-compile-schemas.c:772 +msgid "empty names are not permitted" +msgstr "ä¸å…許空åå稱" + +#: ../gio/glib-compile-schemas.c:782 +#, c-format +msgid "invalid name '%s': names must begin with a lowercase letter" +msgstr "無效的å稱「%sã€ï¼šå稱必須以å°å¯«å­—æ¯é–‹é ­" + +#: ../gio/glib-compile-schemas.c:794 +#, c-format +msgid "" +"invalid name '%s': invalid character '%c'; only lowercase letters, numbers " +"and hyphen ('-') are permitted." +msgstr "無效的å稱「%sã€ï¼šç„¡æ•ˆçš„字符「%cã€ï¼›åªå…許å°å¯«å­—æ¯ã€æ•¸å­—和破折號 ('-')。" + +#: ../gio/glib-compile-schemas.c:803 +#, c-format +msgid "invalid name '%s': two successive hyphens ('--') are not permitted." +msgstr "無效的å稱「%sã€ï¼šä¸å…許兩個破折號 ('--')。" + +#: ../gio/glib-compile-schemas.c:812 +#, c-format +msgid "invalid name '%s': the last character may not be a hyphen ('-')." +msgstr "無效的å稱「%sã€ï¼šæœ€å¾Œä¸€å€‹å­—符ä¸èƒ½æ˜¯ç ´æŠ˜è™Ÿ ('-')。" + +#: ../gio/glib-compile-schemas.c:820 +#, c-format +msgid "invalid name '%s': maximum length is 1024" +msgstr "無效的å稱「%sã€ï¼šæœ€å¤§é•·åº¦ç‚º 1024" + +#: ../gio/glib-compile-schemas.c:889 +#, c-format +msgid " already specified" +msgstr " 已經指定了" + +#: ../gio/glib-compile-schemas.c:915 +msgid "cannot add keys to a 'list-of' schema" +msgstr "ä¸èƒ½å°‡è¨­å®šéµåŠ å…¥ 'list-of' schema" + +#: ../gio/glib-compile-schemas.c:926 +#, c-format +msgid " already specified" +msgstr " 已經指定了" + +#: ../gio/glib-compile-schemas.c:944 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr " é®è”½ æ–¼ ;使用 來修改數值" + +#: ../gio/glib-compile-schemas.c:955 +#, c-format +msgid "" +"exactly one of 'type', 'enum' or 'flags' must be specified as an attribute " +"to " +msgstr "必須明確指定「typeã€ã€ã€Œenumã€æˆ–「flagsã€ä¹‹ä¸€åšç‚º 的屬性" + +#: ../gio/glib-compile-schemas.c:974 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> 尚未定義。" + +#: ../gio/glib-compile-schemas.c:989 +#, c-format +msgid "invalid GVariant type string '%s'" +msgstr "無效的 GVariant 類型字串「%sã€" + +#: ../gio/glib-compile-schemas.c:1019 +msgid " given but schema isn't extending anything" +msgstr "指定了 但 schema 並未延伸任何æ±è¥¿" + +#: ../gio/glib-compile-schemas.c:1032 +#, c-format +msgid "no to override" +msgstr "沒有 è¦è¦†è“‹" + +#: ../gio/glib-compile-schemas.c:1040 +#, c-format +msgid " already specified" +msgstr " 已經指定了" + +#: ../gio/glib-compile-schemas.c:1111 +#, c-format +msgid " already specified" +msgstr " 已經指定了" + +#: ../gio/glib-compile-schemas.c:1123 +#, c-format +msgid " extends not yet existing schema '%s'" +msgstr " 延伸了尚ä¸å­˜åœ¨çš„ schema「%sã€" + +#: ../gio/glib-compile-schemas.c:1139 +#, c-format +msgid " is list of not yet existing schema '%s'" +msgstr " 是尚ä¸å­˜åœ¨çš„ schema「%sã€çš„æ¸…å–®" + +#: ../gio/glib-compile-schemas.c:1147 +#, c-format +msgid "Can not be a list of a schema with a path" +msgstr "ä¸èƒ½æˆç‚ºæœ‰è·¯å¾‘ schema 的清單" + +#: ../gio/glib-compile-schemas.c:1157 +#, c-format +msgid "Can not extend a schema with a path" +msgstr "ä¸èƒ½å»¶ä¼¸æœ‰è·¯å¾‘çš„ schema" + +#: ../gio/glib-compile-schemas.c:1167 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " 是清單,å»å»¶ä¼¸äº†ä¸æ˜¯æ¸…單的 " + +#: ../gio/glib-compile-schemas.c:1177 +#, c-format +msgid "" +" extends but '%s' " +"does not extend '%s'" +msgstr " 延伸了 但是 '%s' 並未延伸 '%s'" + +#: ../gio/glib-compile-schemas.c:1194 +#, c-format +msgid "a path, if given, must begin and end with a slash" +msgstr "如果指定了路徑,開頭與çµå°¾éƒ½è¦åŠ ä¸Šæ–œç·š" + +#: ../gio/glib-compile-schemas.c:1201 +#, c-format +msgid "the path of a list must end with ':/'" +msgstr "清單的路徑ä¸èƒ½ä»¥â€˜:/’為çµå°¾" + +#: ../gio/glib-compile-schemas.c:1233 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> 已經指定了" + +#: ../gio/glib-compile-schemas.c:1457 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "元素 <%s> ä¸å…許在頂端層級" + +#. Translators: Do not translate "--strict". +#: ../gio/glib-compile-schemas.c:1752 ../gio/glib-compile-schemas.c:1823 +#: ../gio/glib-compile-schemas.c:1899 +#, c-format +msgid "--strict was specified; exiting.\n" +msgstr "並且指定了 --strictï¼›æ­£åœ¨çµæŸã€‚\n" + +#: ../gio/glib-compile-schemas.c:1760 +#, c-format +msgid "This entire file has been ignored.\n" +msgstr "這整個檔案都被忽略了。\n" + +#: ../gio/glib-compile-schemas.c:1819 +#, c-format +msgid "Ignoring this file.\n" +msgstr "忽略這個檔案。\n" + +#: ../gio/glib-compile-schemas.c:1859 +#, c-format +msgid "No such key '%s' in schema '%s' as specified in override file '%s'" +msgstr "在覆蓋檔案「%3$sã€çš„ schema「%2$sã€ä¸­æ²’有指定這個設定éµã€Œ%1$sã€" + +#: ../gio/glib-compile-schemas.c:1865 ../gio/glib-compile-schemas.c:1923 +#: ../gio/glib-compile-schemas.c:1951 +#, c-format +msgid "; ignoring override for this key.\n" +msgstr ";忽略這個設定éµçš„覆蓋。\n" + +#: ../gio/glib-compile-schemas.c:1869 ../gio/glib-compile-schemas.c:1927 +#: ../gio/glib-compile-schemas.c:1955 +#, c-format +msgid " and --strict was specified; exiting.\n" +msgstr "並且指定了 --strictï¼›æ­£åœ¨çµæŸã€‚\n" + +#: ../gio/glib-compile-schemas.c:1885 +#, c-format +msgid "" +"error parsing key '%s' in schema '%s' as specified in override file '%s': %s." +msgstr "在覆蓋檔案「%3$sã€æŒ‡å®šçš„ schema「%2$sã€åˆ†æžè¨­å®šéµã€Œ%1$sã€æ™‚發生錯誤:%4$s。" + +#: ../gio/glib-compile-schemas.c:1895 +#, c-format +msgid "Ignoring override for this key.\n" +msgstr "忽略這個設定éµçš„覆蓋。\n" + +#: ../gio/glib-compile-schemas.c:1913 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is outside the " +"range given in the schema" +msgstr "在覆蓋檔案「%3$sã€ä¸­è¦†è“‹ schema「%2$sã€çš„設定éµã€Œ%1$sã€è¶…出了 schema 指定的範åœ" + +#: ../gio/glib-compile-schemas.c:1941 +#, c-format +msgid "" +"override for key '%s' in schema '%s' in override file '%s' is not in the " +"list of valid choices" +msgstr "在覆蓋檔案「%3$sã€ä¸­è¦†è“‹ schema「%2$sã€çš„設定éµã€Œ%1$sã€ä¸åœ¨æœ‰æ•ˆçš„鏿“‡æ¸…單中" + +#: ../gio/glib-compile-schemas.c:1994 +msgid "where to store the gschemas.compiled file" +msgstr "è¦å°‡ gschemas.compiled 檔案儲存到哪è£" + +#: ../gio/glib-compile-schemas.c:1995 +msgid "Abort on any errors in schemas" +msgstr "在 schema 中有任何錯誤å³ä¸­æ­¢" + +#: ../gio/glib-compile-schemas.c:1996 +msgid "Do not write the gschema.compiled file" +msgstr "ä¸è¦å¯«å…¥ gschemas.compiled 檔案" + +#: ../gio/glib-compile-schemas.c:1997 +msgid "Do not enforce key name restrictions" +msgstr "ä¸è¦å¼·åˆ¶è¨­å®šéµå稱é™åˆ¶" + +#: ../gio/glib-compile-schemas.c:2026 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"將所有的 GSettings schema 檔案編譯為 schema å¿«å–。\n" +"Schema 檔案的延伸檔å必須為 .gschema.xml,\n" +"è€Œå¿«å–æª”案å«åš gschemas.compiled。" + +#: ../gio/glib-compile-schemas.c:2042 +#, c-format +msgid "You should give exactly one directory name\n" +msgstr "你應該明確指定一個目錄å稱\n" + +#: ../gio/glib-compile-schemas.c:2081 +#, c-format +msgid "No schema files found: " +msgstr "找ä¸åˆ° schema 檔案:" + +#: ../gio/glib-compile-schemas.c:2084 +#, c-format +msgid "doing nothing.\n" +msgstr "ä¸åšä»»ä½•事。\n" + +#: ../gio/glib-compile-schemas.c:2087 +#, c-format +msgid "removed existing output file.\n" +msgstr "ç§»é™¤ç¾æœ‰çš„輸出檔案。\n" + +#: ../gio/glocaldirectorymonitor.c:224 +msgid "Unable to find default local directory monitor type" +msgstr "無法找到é è¨­çš„æœ¬åœ°ç«¯ç›®éŒ„監視器類型" + +#: ../gio/glocalfile.c:604 ../gio/win32/gwinhttpfile.c:420 +#, c-format +msgid "Invalid filename %s" +msgstr "無效的檔案å稱 %s" + +#: ../gio/glocalfile.c:981 +#, c-format +msgid "Error getting filesystem info: %s" +msgstr "å–得檔案系統資訊時發生錯誤:%s" + +#: ../gio/glocalfile.c:1149 +msgid "Can't rename root directory" +msgstr "ä¸èƒ½é‡æ–°å‘½å根目錄" + +#: ../gio/glocalfile.c:1169 ../gio/glocalfile.c:1195 +#, c-format +msgid "Error renaming file: %s" +msgstr "釿–°å‘½å檔案時發生錯誤:%s" + +#: ../gio/glocalfile.c:1178 +msgid "Can't rename file, filename already exists" +msgstr "ä¸èƒ½é‡æ–°å‘½å檔案,該檔案å稱已存在" + +#: ../gio/glocalfile.c:1191 ../gio/glocalfile.c:2210 ../gio/glocalfile.c:2239 +#: ../gio/glocalfile.c:2399 ../gio/glocalfileoutputstream.c:549 +msgid "Invalid filename" +msgstr "無效的檔案å稱" + +#: ../gio/glocalfile.c:1358 ../gio/glocalfile.c:1382 +msgid "Can't open directory" +msgstr "ä¸èƒ½é–‹å•Ÿç›®éŒ„" + +#: ../gio/glocalfile.c:1366 +#, c-format +msgid "Error opening file: %s" +msgstr "開啓檔案時發生錯誤:%s" + +#: ../gio/glocalfile.c:1507 +#, c-format +msgid "Error removing file: %s" +msgstr "移除檔案時發生錯誤:%s" + +#: ../gio/glocalfile.c:1887 +#, c-format +msgid "Error trashing file: %s" +msgstr "移動檔案至回收筒時發生錯誤:%s" + +#: ../gio/glocalfile.c:1910 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "無法建立回收筒目錄 %s:%s" + +#: ../gio/glocalfile.c:1931 +msgid "Unable to find toplevel directory for trash" +msgstr "無法找到回收筒的頂端層級目錄" + +#: ../gio/glocalfile.c:2010 ../gio/glocalfile.c:2030 +msgid "Unable to find or create trash directory" +msgstr "無法找到或建立回收筒目錄" + +#: ../gio/glocalfile.c:2064 +#, c-format +msgid "Unable to create trashing info file: %s" +msgstr "無法建立回收筒資訊檔案:%s" + +#: ../gio/glocalfile.c:2095 ../gio/glocalfile.c:2100 ../gio/glocalfile.c:2180 +#: ../gio/glocalfile.c:2187 +#, c-format +msgid "Unable to trash file: %s" +msgstr "無法將檔案移至回收筒:%s" + +#: ../gio/glocalfile.c:2188 ../glib/gregex.c:281 +msgid "internal error" +msgstr "內部的錯誤" + +#: ../gio/glocalfile.c:2214 +#, c-format +msgid "Error creating directory: %s" +msgstr "建立目錄發生錯誤:%s" + +#: ../gio/glocalfile.c:2243 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "æª”æ¡ˆç³»çµ±ä¸æ”¯æ´ç¬¦è™Ÿé€£çµ" + +#: ../gio/glocalfile.c:2247 +#, c-format +msgid "Error making symbolic link: %s" +msgstr "å»ºç«‹ç¬¦è™Ÿé€£çµæ™‚發生錯誤:%s" + +#: ../gio/glocalfile.c:2309 ../gio/glocalfile.c:2403 +#, c-format +msgid "Error moving file: %s" +msgstr "移動檔案時發生錯誤:%s" + +#: ../gio/glocalfile.c:2332 +msgid "Can't move directory over directory" +msgstr "ä¸èƒ½å°‡ç›®éŒ„移動至目錄上" + +#: ../gio/glocalfile.c:2359 ../gio/glocalfileoutputstream.c:925 +#: ../gio/glocalfileoutputstream.c:939 ../gio/glocalfileoutputstream.c:954 +#: ../gio/glocalfileoutputstream.c:970 ../gio/glocalfileoutputstream.c:984 +msgid "Backup file creation failed" +msgstr "建立備份檔案失敗" + +#: ../gio/glocalfile.c:2378 +#, c-format +msgid "Error removing target file: %s" +msgstr "移除目標檔案時發生錯誤:%s" + +#: ../gio/glocalfile.c:2392 +msgid "Move between mounts not supported" +msgstr "䏿”¯æ´åœ¨æŽ›è¼‰é»žä¹‹é–“移動" + +#: ../gio/glocalfile.c:2603 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "無法決定 %s çš„ç£ç¢Ÿä½¿ç”¨é‡ï¼š%s" + +#: ../gio/glocalfileinfo.c:721 +msgid "Attribute value must be non-NULL" +msgstr "屬性數值必須為éž-NULL" + +#: ../gio/glocalfileinfo.c:728 +msgid "Invalid attribute type (string expected)" +msgstr "無效的屬性類型(應為字串值)" + +#: ../gio/glocalfileinfo.c:735 +msgid "Invalid extended attribute name" +msgstr "無效的延伸屬性å稱" + +#: ../gio/glocalfileinfo.c:775 +#, c-format +msgid "Error setting extended attribute '%s': %s" +msgstr "設定延伸屬性「%sã€æ™‚發生錯誤:%s" + +#: ../gio/glocalfileinfo.c:1556 +msgid " (invalid encoding)" +msgstr "(無效的編碼)" + +#: ../gio/glocalfileinfo.c:1747 ../gio/glocalfileoutputstream.c:803 +#, c-format +msgid "Error when getting information for file '%s': %s" +msgstr "å–得檔案「%sã€è³‡è¨Šæ™‚發生錯誤:%s" + +#: ../gio/glocalfileinfo.c:1998 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "å–得檔案æè¿°ç‹€æ…‹è³‡è¨Šæ™‚發生錯誤:%s" + +#: ../gio/glocalfileinfo.c:2043 +msgid "Invalid attribute type (uint32 expected)" +msgstr "無效的屬性類型(應為 uint32 值)" + +#: ../gio/glocalfileinfo.c:2061 +msgid "Invalid attribute type (uint64 expected)" +msgstr "無效的屬性類型(應為 uint64 值)" + +#: ../gio/glocalfileinfo.c:2080 ../gio/glocalfileinfo.c:2099 +msgid "Invalid attribute type (byte string expected)" +msgstr "無效的屬性類型(應為 byte string 值)" + +#: ../gio/glocalfileinfo.c:2134 +msgid "Cannot set permissions on symlinks" +msgstr "ä¸èƒ½è¨­å®šç¬¦è™Ÿé€£çµçš„æ¬Šé™" + +#: ../gio/glocalfileinfo.c:2150 +#, c-format +msgid "Error setting permissions: %s" +msgstr "è¨­å®šæ¬Šé™æ™‚發生錯誤:%s" + +#: ../gio/glocalfileinfo.c:2201 +#, c-format +msgid "Error setting owner: %s" +msgstr "è¨­å®šæ“æœ‰è€…時發生錯誤:%s" + +#: ../gio/glocalfileinfo.c:2224 +msgid "symlink must be non-NULL" +msgstr "符號連çµå¿…須為éž-NULL" + +#: ../gio/glocalfileinfo.c:2234 ../gio/glocalfileinfo.c:2253 +#: ../gio/glocalfileinfo.c:2264 +#, c-format +msgid "Error setting symlink: %s" +msgstr "è¨­å®šç¬¦è™Ÿé€£çµæ™‚發生錯誤:%s" + +#: ../gio/glocalfileinfo.c:2243 +msgid "Error setting symlink: file is not a symlink" +msgstr "è¨­å®šç¬¦è™Ÿé€£çµæ™‚ç™¼ç”ŸéŒ¯èª¤ï¼šæª”æ¡ˆä¸æ˜¯ç¬¦è™Ÿé€£çµ" + +#: ../gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "è¨­å®šä¿®æ”¹æˆ–å­˜å–æ™‚刻時發生錯誤:%s" + +#: ../gio/glocalfileinfo.c:2392 +msgid "SELinux context must be non-NULL" +msgstr "SELinux é—œè¯å¿…須為éž-NULL" + +#: ../gio/glocalfileinfo.c:2407 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "設定 SELinux é—œè¯æ™‚發生錯誤:%s" + +#: ../gio/glocalfileinfo.c:2414 +msgid "SELinux is not enabled on this system" +msgstr "SELinux 在這個系統上並未啟用" + +#: ../gio/glocalfileinfo.c:2506 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "䏿”¯æ´è¨­å®šå±¬æ€§ %s" + +#: ../gio/glocalfileinputstream.c:168 ../gio/glocalfileoutputstream.c:694 +#, c-format +msgid "Error reading from file: %s" +msgstr "å¾žæª”æ¡ˆè®€å–æ™‚發生錯誤:%s" + +#: ../gio/glocalfileinputstream.c:199 ../gio/glocalfileinputstream.c:211 +#: ../gio/glocalfileinputstream.c:225 ../gio/glocalfileinputstream.c:333 +#: ../gio/glocalfileoutputstream.c:456 ../gio/glocalfileoutputstream.c:1002 +#, c-format +msgid "Error seeking in file: %s" +msgstr "在檔案中æœå°‹æ™‚發生錯誤:%s" + +#: ../gio/glocalfileinputstream.c:255 ../gio/glocalfileoutputstream.c:246 +#: ../gio/glocalfileoutputstream.c:340 +#, c-format +msgid "Error closing file: %s" +msgstr "關閉檔案時發生錯誤:%s" + +#: ../gio/glocalfilemonitor.c:145 +msgid "Unable to find default local file monitor type" +msgstr "無法找到é è¨­çš„æœ¬åœ°ç«¯æª”案監視器類型" + +#: ../gio/glocalfileoutputstream.c:194 ../gio/glocalfileoutputstream.c:226 +#: ../gio/glocalfileoutputstream.c:715 +#, c-format +msgid "Error writing to file: %s" +msgstr "寫入至檔案時發生錯誤:%s" + +#: ../gio/glocalfileoutputstream.c:273 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "ç§»é™¤èˆŠå‚™ä»½é€£çµæ™‚發生錯誤:%s" + +#: ../gio/glocalfileoutputstream.c:287 ../gio/glocalfileoutputstream.c:300 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "建立備份複本時發生錯誤:%s" + +#: ../gio/glocalfileoutputstream.c:318 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "釿–°å‘½å暫存檔案時發生錯誤:%s" + +#: ../gio/glocalfileoutputstream.c:502 ../gio/glocalfileoutputstream.c:1053 +#, c-format +msgid "Error truncating file: %s" +msgstr "截短檔案時發生錯誤:%s" + +#: ../gio/glocalfileoutputstream.c:555 ../gio/glocalfileoutputstream.c:785 +#: ../gio/glocalfileoutputstream.c:1034 ../gio/gsubprocess.c:360 +#, c-format +msgid "Error opening file '%s': %s" +msgstr "開啟檔案「%sã€æ™‚發生錯誤:%s" + +#: ../gio/glocalfileoutputstream.c:816 +msgid "Target file is a directory" +msgstr "目標檔案是一個目錄" + +#: ../gio/glocalfileoutputstream.c:821 +msgid "Target file is not a regular file" +msgstr "ç›®æ¨™æª”æ¡ˆä¸æ˜¯æ­£è¦çš„æª”案" + +#: ../gio/glocalfileoutputstream.c:833 +msgid "The file was externally modified" +msgstr "該檔案已被外部程å¼ä¿®æ”¹éŽ" + +#: ../gio/glocalfileoutputstream.c:1018 +#, c-format +msgid "Error removing old file: %s" +msgstr "移除舊檔案時發生錯誤:%s" + +#: ../gio/gmemoryinputstream.c:471 ../gio/gmemoryoutputstream.c:771 +msgid "Invalid GSeekType supplied" +msgstr "æä¾›äº†ç„¡æ•ˆçš„ GSeek 類型" + +#: ../gio/gmemoryinputstream.c:481 +msgid "Invalid seek request" +msgstr "無效的æœå°‹è¦æ±‚" + +#: ../gio/gmemoryinputstream.c:505 +msgid "Cannot truncate GMemoryInputStream" +msgstr "ä¸èƒ½æˆªçŸ­ GMemoryInputStream" + +#: ../gio/gmemoryoutputstream.c:565 +msgid "Memory output stream not resizable" +msgstr "記憶體輸出串æµä¸èƒ½æ”¹è®Šå¤§å°" + +#: ../gio/gmemoryoutputstream.c:581 +msgid "Failed to resize memory output stream" +msgstr "改變記憶體輸出串æµçš„大å°å¤±æ•—" + +#: ../gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "進行寫入所需的記憶體總é¡å¤§æ–¼å¯ç”¨çš„ä½å€ç©ºé–“" + +#: ../gio/gmemoryoutputstream.c:781 +msgid "Requested seek before the beginning of the stream" +msgstr "在串æµçš„開頭之å‰è¦æ±‚çš„æœç´¢" + +#: ../gio/gmemoryoutputstream.c:796 +msgid "Requested seek beyond the end of the stream" +msgstr "在串æµçš„é–‹é ­ä¹‹å¾Œè¦æ±‚çš„æœç´¢" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: ../gio/gmount.c:393 +msgid "mount doesn't implement \"unmount\"" +msgstr "掛載點尚未實作å¸è¼‰(umount)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: ../gio/gmount.c:469 +msgid "mount doesn't implement \"eject\"" +msgstr "掛載點尚未實作退出(eject)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: ../gio/gmount.c:547 +msgid "mount doesn't implement \"unmount\" or \"unmount_with_operation\"" +msgstr "掛載點尚未實作å¸è¼‰(umount)或「umount_with_operationã€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gmount.c:632 +msgid "mount doesn't implement \"eject\" or \"eject_with_operation\"" +msgstr "掛載點尚未實作退出(eject)或「eject_with_operationã€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: ../gio/gmount.c:720 +msgid "mount doesn't implement \"remount\"" +msgstr "æŽ›è¼‰é»žå°šæœªå¯¦ä½œé‡æ–°æŽ›è¼‰(remount)" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:802 +msgid "mount doesn't implement content type guessing" +msgstr "æŽ›è¼‰é»žå°šæœªå¯¦ä½œå…§å®¹é¡žåž‹é æ¸¬" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: ../gio/gmount.c:889 +msgid "mount doesn't implement synchronous content type guessing" +msgstr "æŽ›è¼‰é»žå°šæœªå¯¦ä½œåŒæ­¥å…§å®¹é¡žåž‹é æ¸¬" + +#: ../gio/gnetworkaddress.c:338 +#, c-format +msgid "Hostname '%s' contains '[' but not ']'" +msgstr "主機å稱「%sã€å«æœ‰ '[' but not ']'" + +#: ../gio/gnetworkmonitorbase.c:189 ../gio/gnetworkmonitorbase.c:292 +msgid "Network unreachable" +msgstr "無法連接網絡" + +#: ../gio/gnetworkmonitorbase.c:227 ../gio/gnetworkmonitorbase.c:257 +msgid "Host unreachable" +msgstr "無法連接主機" + +#: ../gio/gnetworkmonitornetlink.c:96 ../gio/gnetworkmonitornetlink.c:108 +#: ../gio/gnetworkmonitornetlink.c:127 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "無法建立網絡監控:%s" + +#: ../gio/gnetworkmonitornetlink.c:117 +msgid "Could not create network monitor: " +msgstr "無法建立網絡監控:" + +#: ../gio/gnetworkmonitornetlink.c:175 +msgid "Could not get network status: " +msgstr "無法å–得網絡狀態:" + +#: ../gio/goutputstream.c:209 ../gio/goutputstream.c:550 +msgid "Output stream doesn't implement write" +msgstr "輸出串æµå°šæœªå¯¦ä½œå¯«å…¥" + +#: ../gio/goutputstream.c:511 ../gio/goutputstream.c:1028 +msgid "Source stream is already closed" +msgstr "來æºä¸²æµå·²ç¶“關閉" + +#: ../gio/gresolver.c:320 ../gio/gthreadedresolver.c:116 +#: ../gio/gthreadedresolver.c:126 +#, c-format +msgid "Error resolving '%s': %s" +msgstr "è§£æžã€Œ%sã€æ™‚發生錯誤:%s" + +#: ../gio/gresource.c:291 ../gio/gresource.c:539 ../gio/gresource.c:556 +#: ../gio/gresource.c:677 ../gio/gresource.c:746 ../gio/gresource.c:807 +#: ../gio/gresource.c:887 ../gio/gresourcefile.c:452 +#: ../gio/gresourcefile.c:553 ../gio/gresourcefile.c:655 +#, c-format +msgid "The resource at '%s' does not exist" +msgstr "「%sã€çš„資æºä¸å­˜åœ¨" + +#: ../gio/gresource.c:456 +#, c-format +msgid "The resource at '%s' failed to decompress" +msgstr "「%sã€çš„資æºç„¡æ³•解壓縮" + +#: ../gio/gresourcefile.c:651 +#, c-format +msgid "The resource at '%s' is not a directory" +msgstr "「%sã€çš„資æºä¸æ˜¯ç›®éŒ„" + +#: ../gio/gresourcefile.c:859 +msgid "Input stream doesn't implement seek" +msgstr "輸入串æµå°šæœªå¯¦ä½œå°‹æ‰¾" + +#: ../gio/gresource-tool.c:487 +msgid "List sections containing resources in an elf FILE" +msgstr "列出 elf FILE 中包å«è³‡æºçš„節å€" + +#: ../gio/gresource-tool.c:493 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"列出資æº\n" +"如果指定 SECTIONï¼Œåªæœƒåˆ—出這個節å€çš„資æº\n" +"如果指定 PATHï¼Œåªæœƒåˆ—出符åˆçš„資æº" + +#: ../gio/gresource-tool.c:496 ../gio/gresource-tool.c:506 +msgid "FILE [PATH]" +msgstr "檔案 [路徑]" + +#: ../gio/gresource-tool.c:497 ../gio/gresource-tool.c:507 +#: ../gio/gresource-tool.c:514 +msgid "SECTION" +msgstr "SECTION" + +#: ../gio/gresource-tool.c:502 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"列出資æºè©³ç´°è³‡æ–™\n" +"如果指定 SECTIONï¼Œåªæœƒåˆ—出這個節å€çš„資æº\n" +"如果指定 PATHï¼Œåªæœƒåˆ—出符åˆçš„資æº\n" +"詳細資料包å«ç¯€å€ã€å¤§å°å’Œå£“縮率" + +#: ../gio/gresource-tool.c:512 +msgid "Extract a resource file to stdout" +msgstr "è§£å£“ç¸®è³‡æºæª”案到 stdout" + +#: ../gio/gresource-tool.c:513 +msgid "FILE PATH" +msgstr "檔案路徑" + +#: ../gio/gresource-tool.c:527 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use 'gresource help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"用法:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"指令:\n" +" help 顯示這個資訊\n" +" sections 列出資æºç¯€å€\n" +" list 列出資æº\n" +" details 列出資æºè©³ç´°è³‡æ–™\n" +" extract 解壓縮資æº\n" +"\n" +"使用 'gresource help COMMAND' 以å–得詳細的說明文件。\n" +"\n" + +#: ../gio/gresource-tool.c:541 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"用法:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gresource-tool.c:548 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION 一個 (鏿“‡æ€§çš„) elf 節å€å稱\n" + +#: ../gio/gresource-tool.c:552 ../gio/gsettings-tool.c:635 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND è¦è§£é‡‹çš„ï¼ˆé¸æ“‡æ€§ï¼‰æŒ‡ä»¤\n" + +#: ../gio/gresource-tool.c:558 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE 一個 elf 檔案 (二元檔或共享程å¼åº«)\n" + +#: ../gio/gresource-tool.c:561 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE 一個 elf 檔案 (二元檔或共享程å¼åº«)\n" +" 或編譯éŽçš„è³‡æºæª”案\n" + +#: ../gio/gresource-tool.c:565 +msgid "[PATH]" +msgstr "[路徑]" + +#: ../gio/gresource-tool.c:567 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH 一個 (鏿“‡æ€§çš„) 資æºè·¯å¾‘ (å¯èƒ½ç‚ºéƒ¨åˆ†)\n" + +#: ../gio/gresource-tool.c:568 +msgid "PATH" +msgstr "路徑" + +#: ../gio/gresource-tool.c:570 +msgid " PATH A resource path\n" +msgstr " PATH 資æºè·¯å¾‘\n" + +#: ../gio/gsettings-tool.c:51 ../gio/gsettings-tool.c:72 +#, c-format +msgid "No such schema '%s'\n" +msgstr "沒有這個 schema「%sã€\n" + +#: ../gio/gsettings-tool.c:57 +#, c-format +msgid "Schema '%s' is not relocatable (path must not be specified)\n" +msgstr "Schema「%sã€ä¸æ˜¯å¯é‡æ–°é…置的(路徑ä¸èƒ½æŒ‡å®šï¼‰\n" + +#: ../gio/gsettings-tool.c:78 +#, c-format +msgid "Schema '%s' is relocatable (path must be specified)\n" +msgstr "Schema「%sã€æ˜¯å¯é‡æ–°é…置的(路徑必須指定)\n" + +#: ../gio/gsettings-tool.c:92 +#, c-format +msgid "Empty path given.\n" +msgstr "指定了空白的路徑。\n" + +#: ../gio/gsettings-tool.c:98 +#, c-format +msgid "Path must begin with a slash (/)\n" +msgstr "路徑ä¸èƒ½ä»¥æ–œç·š (/) é–‹é ­\n" + +#: ../gio/gsettings-tool.c:104 +#, c-format +msgid "Path must end with a slash (/)\n" +msgstr "路徑ä¸èƒ½ä»¥æ–œç·š (/) çµå°¾\n" + +#: ../gio/gsettings-tool.c:110 +#, c-format +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "路徑ä¸èƒ½åŒ…å«å…©å€‹ç›¸é„°çš„æ–œç·š (//)\n" + +#: ../gio/gsettings-tool.c:477 +#, c-format +msgid "The provided value is outside of the valid range\n" +msgstr "æä¾›çš„æ•¸å€¼è¶…出了有效的範åœ\n" + +#: ../gio/gsettings-tool.c:484 +#, c-format +msgid "The key is not writable\n" +msgstr "這個設定éµç„¡æ³•寫入\n" + +#: ../gio/gsettings-tool.c:520 +msgid "List the installed (non-relocatable) schemas" +msgstr "列出已安è£çš„(éž-å¯é‡æ–°é…置)schema" + +#: ../gio/gsettings-tool.c:526 +msgid "List the installed relocatable schemas" +msgstr "列出已安è£çš„å¯é‡æ–°é…ç½® schema" + +#: ../gio/gsettings-tool.c:532 +msgid "List the keys in SCHEMA" +msgstr "列出 SCHEMA 中的設定éµ" + +#: ../gio/gsettings-tool.c:533 ../gio/gsettings-tool.c:539 +#: ../gio/gsettings-tool.c:576 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: ../gio/gsettings-tool.c:538 +msgid "List the children of SCHEMA" +msgstr "列出 SCHEMA çš„å­é …" + +#: ../gio/gsettings-tool.c:544 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"éžè¿´çš„列出設定éµèˆ‡éµå€¼\n" +"如果沒有指定 SCHEMA,列出所有設定éµ\n" + +#: ../gio/gsettings-tool.c:546 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: ../gio/gsettings-tool.c:551 +msgid "Get the value of KEY" +msgstr "å–å¾— KEY 的數值" + +#: ../gio/gsettings-tool.c:552 ../gio/gsettings-tool.c:558 +#: ../gio/gsettings-tool.c:570 ../gio/gsettings-tool.c:582 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: ../gio/gsettings-tool.c:557 +msgid "Query the range of valid values for KEY" +msgstr "查詢 KEY 有效數值的範åœ" + +#: ../gio/gsettings-tool.c:563 +msgid "Set the value of KEY to VALUE" +msgstr "å°‡ KEY 的數值設定為 VALUE" + +#: ../gio/gsettings-tool.c:564 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: ../gio/gsettings-tool.c:569 +msgid "Reset KEY to its default value" +msgstr "å°‡ KEY 設定為é è¨­å€¼" + +#: ../gio/gsettings-tool.c:575 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "å°‡ SCHEMA 的所有設定éµé‡è¨­ç‚ºé è¨­å€¼" + +#: ../gio/gsettings-tool.c:581 +msgid "Check if KEY is writable" +msgstr "檢查 KEY 是å¦å¯å¯«å…¥" + +#: ../gio/gsettings-tool.c:587 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"監控 KEY 的更改。\n" +"如果沒有指定 KEY,會監控 SCHEMA 的所有設定éµã€‚\n" +"使用 ^C å¯åœæ­¢ç›£æŽ§ã€‚\n" + +#: ../gio/gsettings-tool.c:590 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: ../gio/gsettings-tool.c:602 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use 'gsettings help COMMAND' to get detailed help.\n" +"\n" +msgstr "" +"用法:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"指令:\n" +" help 顯示這個資訊\n" +" list-schemas 列出已安è£çš„ schemas\n" +" list-relocatable-schemas 列出å¯é‡æ–°é…置的 schemas\n" +" list-keys 列出 schema 中的設定éµ\n" +" list-children 列出 schema çš„å­é …\n" +" list-recursively éžè¿´åˆ—出設定éµå’Œæ•¸å€¼\n" +" range 查詢設定éµçš„範åœ\n" +" get å–得設定éµçš„æ•¸å€¼\n" +" set 設定設定éµçš„æ•¸å€¼\n" +" reset é‡è¨­è¨­å®šéµçš„æ•¸å€¼\n" +" reset-recursively é‡è¨­æŒ‡å®š schema 的所有數值\n" +" writable æª¢æŸ¥è¨­å®šéµæ˜¯å¦å¯å¯«å…¥\n" +" monitor 監看更改\n" +"\n" +"使用「gsettings help COMMANDã€å–得詳細的說明。\n" +"\n" + +#: ../gio/gsettings-tool.c:625 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"用法:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: ../gio/gsettings-tool.c:631 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR æœå°‹é¡å¤– schema 的目錄\n" + +#: ../gio/gsettings-tool.c:639 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA 這個 schema çš„å稱\n" +" PATH 路徑,用於å¯é‡æ–°é…置的 schema\n" + +#: ../gio/gsettings-tool.c:644 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY schema ä¸­çš„ï¼ˆé¸æ“‡æ€§çš„)設定éµ\n" + +#: ../gio/gsettings-tool.c:648 +msgid " KEY The key within the schema\n" +msgstr " KEY schema 中的設定éµ\n" + +#: ../gio/gsettings-tool.c:652 +msgid " VALUE The value to set\n" +msgstr " VALUE è¦è¨­å®šçš„æ•¸å€¼\n" + +#: ../gio/gsettings-tool.c:707 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "無法載入 %s çš„ schema:%s\n" + +#: ../gio/gsettings-tool.c:769 +#, c-format +msgid "Empty schema name given\n" +msgstr "指定了空的 schema å稱\n" + +#: ../gio/gsettings-tool.c:798 +#, c-format +msgid "No such key '%s'\n" +msgstr "沒有設定éµã€Œ%sã€\n" + +#: ../gio/gsocket.c:266 +msgid "Invalid socket, not initialized" +msgstr "無效的 socket,尚未åˆå§‹åŒ–" + +#: ../gio/gsocket.c:273 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "無效的 socket,åˆå§‹åŒ–失敗原因為:%s" + +#: ../gio/gsocket.c:281 +msgid "Socket is already closed" +msgstr "Socket 已經關閉" + +#: ../gio/gsocket.c:296 ../gio/gsocket.c:3618 ../gio/gsocket.c:3673 +msgid "Socket I/O timed out" +msgstr "Socket I/O 逾時" + +#: ../gio/gsocket.c:443 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "正在從 fd 建立 GSocket:%s" + +#: ../gio/gsocket.c:471 ../gio/gsocket.c:525 ../gio/gsocket.c:532 +#, c-format +msgid "Unable to create socket: %s" +msgstr "無法建立 socket:%s" + +#: ../gio/gsocket.c:525 +msgid "Unknown family was specified" +msgstr "æŒ‡å®šäº†ä¸æ˜Žçš„å­—æ—" + +#: ../gio/gsocket.c:532 +msgid "Unknown protocol was specified" +msgstr "æŒ‡å®šäº†ä¸æ˜Žçš„通訊å”定" + +#: ../gio/gsocket.c:1722 +#, c-format +msgid "could not get local address: %s" +msgstr "無法å–得本地端ä½å€ï¼š%s" + +#: ../gio/gsocket.c:1765 +#, c-format +msgid "could not get remote address: %s" +msgstr "無法å–å¾—é ç«¯ä½å€ï¼š%s" + +#: ../gio/gsocket.c:1826 +#, c-format +msgid "could not listen: %s" +msgstr "無法è½å–:%s" + +#: ../gio/gsocket.c:1925 +#, c-format +msgid "Error binding to address: %s" +msgstr "ç¶å®šè‡³ä½å€æ™‚發生錯誤:%s" + +#: ../gio/gsocket.c:2037 ../gio/gsocket.c:2074 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "加入多點廣播羣組時發生錯誤:%s" + +#: ../gio/gsocket.c:2038 ../gio/gsocket.c:2075 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "離開多點廣播羣組時發生錯誤:%s" + +#: ../gio/gsocket.c:2039 +msgid "No support for source-specific multicast" +msgstr "䏿”¯æ´æŒ‡å®šä¾†æºçš„多點廣播" + +#: ../gio/gsocket.c:2261 +#, c-format +msgid "Error accepting connection: %s" +msgstr "接å—連線時發生錯誤:%s" + +#: ../gio/gsocket.c:2382 +msgid "Connection in progress" +msgstr "連線進行中" + +#: ../gio/gsocket.c:2432 +msgid "Unable to get pending error: " +msgstr "無法å–得未處ç†çš„錯誤:" + +#: ../gio/gsocket.c:2633 +#, c-format +msgid "Error receiving data: %s" +msgstr "接收資料時發生錯誤:%s" + +#: ../gio/gsocket.c:2811 +#, c-format +msgid "Error sending data: %s" +msgstr "傳é€è³‡æ–™æ™‚發生錯誤:%s" + +#: ../gio/gsocket.c:2925 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "無法關閉 socket:%s" + +#: ../gio/gsocket.c:3004 +#, c-format +msgid "Error closing socket: %s" +msgstr "關閉 socket 時發生錯誤:%s" + +#: ../gio/gsocket.c:3611 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "等候 socket 情æ³ï¼š%s" + +#: ../gio/gsocket.c:3897 ../gio/gsocket.c:3978 +#, c-format +msgid "Error sending message: %s" +msgstr "傳é€è¨Šæ¯æ™‚發生錯誤:%s" + +#: ../gio/gsocket.c:3922 +msgid "GSocketControlMessage not supported on Windows" +msgstr "è¦–çª—ä¸æ”¯æ´ GSocketControlMessage" + +#: ../gio/gsocket.c:4259 ../gio/gsocket.c:4394 +#, c-format +msgid "Error receiving message: %s" +msgstr "å–回郵件發生錯誤:%s" + +#: ../gio/gsocket.c:4516 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "ç„¡æ³•è®€å– socket 機密:%s" + +#: ../gio/gsocket.c:4525 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials 沒有在這個 OS 上實作" + +#: ../gio/gsocketclient.c:176 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "無法連線到代ç†ä¼ºæœå™¨ %s:" + +#: ../gio/gsocketclient.c:190 +#, c-format +msgid "Could not connect to %s: " +msgstr "無法連接到 %s:" + +#: ../gio/gsocketclient.c:192 +msgid "Could not connect: " +msgstr "無法連接:" + +#: ../gio/gsocketclient.c:1027 ../gio/gsocketclient.c:1597 +msgid "Unknown error on connect" +msgstr "é€£ç·šæ™‚æœ‰ä¸æ˜Žçš„錯誤" + +#: ../gio/gsocketclient.c:1082 ../gio/gsocketclient.c:1532 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "䏿”¯æ´å˜—試é€éŽéž-TCP 連線使用代ç†ä¼ºæœå™¨ã€‚" + +#: ../gio/gsocketclient.c:1108 ../gio/gsocketclient.c:1553 +#, c-format +msgid "Proxy protocol '%s' is not supported." +msgstr "指定的通訊å”定「%sã€ä¸è¢«æ”¯æ´ã€‚" + +#: ../gio/gsocketlistener.c:188 +msgid "Listener is already closed" +msgstr "è½å–程å¼å·²ç¶“關閉" + +#: ../gio/gsocketlistener.c:234 +msgid "Added socket is closed" +msgstr "加入的 socket 已經關閉" + +#: ../gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address '%s'" +msgstr "SOCKSv4 䏿”¯æ´ IPv6 ä½å€ã€Œ%sã€" + +#: ../gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "使用者åç¨±å° SOCKSv4 通訊å”定" + +#: ../gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv4 protocol" +msgstr "主機å稱「%sã€å° SOCKSv4 通訊å”定來說太長了" + +#: ../gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "伺æœå™¨ä¸æ˜¯ SOCKSv4 代ç†ä¼ºæœå™¨ã€‚" + +#: ../gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "é€éŽ SOCKSv4 伺æœå™¨é€£ç·šè¢«æ‹’絕" + +#: ../gio/gsocks5proxy.c:153 ../gio/gsocks5proxy.c:324 +#: ../gio/gsocks5proxy.c:334 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "伺æœå™¨ä¸æ˜¯ SOCKSv5 代ç†ä¼ºæœå™¨ã€‚" + +#: ../gio/gsocks5proxy.c:167 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKv5 代ç†ä¼ºæœå™¨è¦æ±‚æ ¸å°ã€‚" + +#: ../gio/gsocks5proxy.c:177 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 代ç†éœ€è¦çš„æ ¸å°æ–¹å¼å°šæœªè¢« GLib 支æ´ã€‚" + +#: ../gio/gsocks5proxy.c:206 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "使用者åç¨±æˆ–å¯†ç¢¼å° SOCKSv5 通訊å”定來說太長了。" + +#: ../gio/gsocks5proxy.c:236 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 æ ¸å°ç”±æ–¼éŒ¯èª¤çš„使用者å稱或密碼失敗了。" + +#: ../gio/gsocks5proxy.c:286 +#, c-format +msgid "Hostname '%s' is too long for SOCKSv5 protocol" +msgstr "主機å稱「%sã€å° SOCKSv5 通訊å”定來說太長了" + +#: ../gio/gsocks5proxy.c:348 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 代ç†ä¼ºæœå™¨ä½¿ç”¨äº†ä¸æ˜Žçš„ä½å€é¡žåž‹ã€‚" + +#: ../gio/gsocks5proxy.c:355 +msgid "Internal SOCKSv5 proxy server error." +msgstr "內部的 SOCKSv5 代ç†ä¼ºæœå™¨éŒ¯èª¤ã€‚" + +#: ../gio/gsocks5proxy.c:361 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 連線ä¸è¢«è¦å‰‡çµ„å…許。" + +#: ../gio/gsocks5proxy.c:368 +msgid "Host unreachable through SOCKSv5 server." +msgstr "主機無法é€éŽ SOCKSv5 代ç†ä¼ºæœå™¨æŠµé”。" + +#: ../gio/gsocks5proxy.c:374 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "網絡無法é€éŽ SOCKSv5 代ç†ä¼ºæœå™¨æŠµé”。" + +#: ../gio/gsocks5proxy.c:380 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "é€éŽ SOCKSv5 代ç†ä¼ºæœå™¨é€£ç·šè¢«æ‹’絕。" + +#: ../gio/gsocks5proxy.c:386 +msgid "SOCKSv5 proxy does not support 'connect' command." +msgstr "SOCKSv5 代ç†ä¼ºæœå™¨ä¸æ”¯æ´ã€Œconnectã€æŒ‡ä»¤ã€‚" + +#: ../gio/gsocks5proxy.c:392 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 代ç†ä¼ºæœå™¨ä¸æ”¯æ´æä¾›çš„ä½å€é¡žåž‹ã€‚" + +#: ../gio/gsocks5proxy.c:398 +msgid "Unknown SOCKSv5 proxy error." +msgstr "䏿˜Žçš„ SOCKSv5 代ç†ä¼ºæœå™¨éŒ¯èª¤ã€‚" + +#: ../gio/gthemedicon.c:518 +#, c-format +msgid "Can't handle version %d of GThemedIcon encoding" +msgstr "ä¸èƒ½è™•ç†ç‰ˆæœ¬ç‚º %d çš„ GThemedIcon 編碼" + +#: ../gio/gthreadedresolver.c:118 +msgid "No valid addresses were found" +msgstr "找ä¸åˆ°æœ‰æ•ˆçš„ä½å€" + +#: ../gio/gthreadedresolver.c:211 +#, c-format +msgid "Error reverse-resolving '%s': %s" +msgstr "åå‘è§£æžã€Œ%sã€æ™‚發生錯誤:%s" + +#: ../gio/gthreadedresolver.c:546 ../gio/gthreadedresolver.c:626 +#: ../gio/gthreadedresolver.c:724 ../gio/gthreadedresolver.c:774 +#, c-format +msgid "No DNS record of the requested type for '%s'" +msgstr "「%sã€çš„è¦æ±‚類型沒有 DNS 紀錄" + +#: ../gio/gthreadedresolver.c:551 ../gio/gthreadedresolver.c:729 +#, c-format +msgid "Temporarily unable to resolve '%s'" +msgstr "暫時無法解æžã€Œ%sã€" + +#: ../gio/gthreadedresolver.c:556 ../gio/gthreadedresolver.c:734 +#, c-format +msgid "Error resolving '%s'" +msgstr "è§£æžã€Œ%sã€æ™‚發生錯誤" + +#: ../gio/gtlscertificate.c:247 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "ä¸èƒ½è§£éŽ– PEM 編碼的ç§äººå¯†ç¢¼åŒ™" + +#: ../gio/gtlscertificate.c:252 +msgid "No PEM-encoded private key found" +msgstr "找ä¸åˆ° PEM 編碼的ç§äººå¯†ç¢¼åŒ™" + +#: ../gio/gtlscertificate.c:262 +msgid "Could not parse PEM-encoded private key" +msgstr "ç„¡æ³•è§£æž PEM 編碼的ç§äººå¯†ç¢¼åŒ™" + +#: ../gio/gtlscertificate.c:287 +msgid "No PEM-encoded certificate found" +msgstr "æ‰¾åˆ°éž PEM 編碼的證書" + +#: ../gio/gtlscertificate.c:296 +msgid "Could not parse PEM-encoded certificate" +msgstr "ç„¡æ³•è§£æž PEM 編碼的證書" + +#: ../gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "這是在你的存å–è¢«éŽ–å®šä¹‹å‰æœ€å¾Œè¼¸å…¥å¯†ç¢¼çš„æ©Ÿæœƒã€‚" + +#: ../gio/gtlspassword.c:113 +msgid "" +"Several password entered have been incorrect, and your access will be locked " +"out after further failures." +msgstr "ä½ å·²ç¶“è¼¸å…¥å¤šå…¥ä¸æ­£ç¢ºçš„å¯†ç¢¼ï¼Œå¦‚æžœæŽ¥ä¸‹ä¾†é‚„æ˜¯è¼¸å…¥éŒ¯èª¤å°‡æœƒéŽ–å®šä½ çš„å­˜å–æ¬Šé™ã€‚" + +#: ../gio/gtlspassword.c:115 +msgid "The password entered is incorrect." +msgstr "è¼¸å…¥çš„å¯†ç¢¼æ˜¯ä¸æ­£ç¢ºçš„。" + +#: ../gio/gunixconnection.c:159 ../gio/gunixconnection.c:554 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "é æœŸæœ‰ 1 個控制訊æ¯ï¼Œå»æ”¶åˆ° %d" + +#: ../gio/gunixconnection.c:175 ../gio/gunixconnection.c:566 +msgid "Unexpected type of ancillary data" +msgstr "è¼”åŠ©è³‡æ–™çš„æœªé æœŸé¡žåž‹" + +#: ../gio/gunixconnection.c:193 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "é æœŸæœ‰ 1 個 fdï¼Œå»æ”¶åˆ° %d\n" + +#: ../gio/gunixconnection.c:212 +msgid "Received invalid fd" +msgstr "收到無效的 fd" + +#: ../gio/gunixconnection.c:348 +msgid "Error sending credentials: " +msgstr "傳é€è­‰æ›¸æ™‚發生錯誤:" + +#: ../gio/gunixconnection.c:496 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "檢查 SO_PASSCRED 在 socket 是å¦å•Ÿç”¨æ™‚發生錯誤:%s" + +#: ../gio/gunixconnection.c:511 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "啟用 SO_PASSCRED 時發生錯誤:%s" + +#: ../gio/gunixconnection.c:540 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "é æœŸæŽ¥æ”¶è­‰æ›¸è¦è®€å–單一ä½å…ƒçµ„,但讀å–到零ä½å…ƒçµ„" + +#: ../gio/gunixconnection.c:580 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "䏿˜¯é æœŸçš„æŽ§åˆ¶è¨Šæ¯ï¼Œå»æ”¶åˆ° %d" + +#: ../gio/gunixconnection.c:604 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "åœç”¨ SO_PASSCRED 時發生錯誤:%s" + +#: ../gio/gunixinputstream.c:370 ../gio/gunixinputstream.c:391 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "è®€å–æª”案æè¿°ç‹€æ…‹æ™‚發生錯誤:%s" + +#: ../gio/gunixinputstream.c:424 ../gio/gunixoutputstream.c:410 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "關閉檔案æè¿°ç‹€æ…‹æ™‚發生錯誤:%s" + +#: ../gio/gunixmounts.c:2066 ../gio/gunixmounts.c:2119 +msgid "Filesystem root" +msgstr "根檔案系統" + +#: ../gio/gunixoutputstream.c:356 ../gio/gunixoutputstream.c:377 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "寫入檔案æè¿°ç‹€æ…‹æ™‚發生錯誤:%s" + +#: ../gio/gunixsocketaddress.c:232 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "é€™å€‹ç³»çµ±ä¸æ”¯æŽˆæŠ½è±¡ UNIX 網域 socket ä½å€" + +#: ../gio/gvolume.c:437 +msgid "volume doesn't implement eject" +msgstr "儲存å€å°šæœªå¯¦ä½œé€€å‡º(eject)" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: ../gio/gvolume.c:514 +msgid "volume doesn't implement eject or eject_with_operation" +msgstr "儲存å€å°šæœªå¯¦ä½œé€€å‡º(eject) 或 eject_with_operation" + +#: ../gio/gwin32appinfo.c:274 +msgid "Can't find application" +msgstr "找ä¸åˆ°æ‡‰ç”¨ç¨‹å¼" + +#: ../gio/gwin32appinfo.c:306 +#, c-format +msgid "Error launching application: %s" +msgstr "åŸ·è¡Œæ‡‰ç”¨ç¨‹å¼æ™‚發生錯誤:%s" + +#: ../gio/gwin32appinfo.c:342 +msgid "URIs not supported" +msgstr "䏿”¯æ´ URIs" + +#: ../gio/gwin32appinfo.c:364 +msgid "association changes not supported on win32" +msgstr "é—œè¯æ›´æ”¹åœ¨ win32 ä¸Šä¸æ”¯æ´" + +#: ../gio/gwin32appinfo.c:376 +msgid "Association creation not supported on win32" +msgstr "é—œè¯å»ºç«‹åœ¨ win32 ä¸Šä¸æ”¯æ´" + +#: ../gio/gwin32inputstream.c:344 +#, c-format +msgid "Error reading from handle: %s" +msgstr "從處ç†å™¨è®€å–時發生錯誤:%s" + +#: ../gio/gwin32inputstream.c:388 ../gio/gwin32outputstream.c:375 +#, c-format +msgid "Error closing handle: %s" +msgstr "關閉處ç†å™¨æ™‚發生錯誤:%s" + +#: ../gio/gwin32outputstream.c:331 +#, c-format +msgid "Error writing to handle: %s" +msgstr "寫入至處ç†å™¨æ™‚發生錯誤:%s" + +#: ../gio/gzlibcompressor.c:394 ../gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "沒有足夠的記憶體" + +#: ../gio/gzlibcompressor.c:401 ../gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "內部的錯誤:%s" + +#: ../gio/gzlibcompressor.c:414 ../gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "éœ€è¦æ›´å¤šè¼¸å…¥" + +#: ../gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "無效的壓縮資料" + +#: ../gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "監è½çš„ä½å€" + +#: ../gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "已忽略,用於 GTestDbus 兼容性" + +#: ../gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "顯示ä½å€" + +#: ../gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "以系統殼模å¼é¡¯ç¤ºä½å€" + +#: ../gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "執行 dbus æœå‹™" + +#: ../gio/tests/gdbus-daemon.c:42 +#, c-format +msgid "Wrong args\n" +msgstr "錯誤引數\n" + +#: ../glib/gbookmarkfile.c:755 +#, c-format +msgid "Unexpected attribute '%s' for element '%s'" +msgstr "元件「%2$sã€ä¸­æœ‰æœªé æœŸçš„屬性「%1$sã€" + +#: ../glib/gbookmarkfile.c:766 ../glib/gbookmarkfile.c:837 +#: ../glib/gbookmarkfile.c:847 ../glib/gbookmarkfile.c:954 +#, c-format +msgid "Attribute '%s' of element '%s' not found" +msgstr "找ä¸åˆ°å…ƒä»¶ã€Œ%2$sã€ä¸­çš„屬性「%1$sã€" + +#: ../glib/gbookmarkfile.c:1124 ../glib/gbookmarkfile.c:1189 +#: ../glib/gbookmarkfile.c:1253 ../glib/gbookmarkfile.c:1263 +#, c-format +msgid "Unexpected tag '%s', tag '%s' expected" +msgstr "æœªé æœŸçš„æ¨™ç±¤ã€Œ%sã€ï¼Œæ‡‰ç‚ºæ¨™ç±¤ã€Œ%sã€" + +#: ../glib/gbookmarkfile.c:1149 ../glib/gbookmarkfile.c:1163 +#: ../glib/gbookmarkfile.c:1231 +#, c-format +msgid "Unexpected tag '%s' inside '%s'" +msgstr "「%2$sã€ä¸­æœ‰æœªé æœŸçš„æ¨™ç±¤ã€Œ%1$sã€" + +#: ../glib/gbookmarkfile.c:1756 +msgid "No valid bookmark file found in data dirs" +msgstr "在資料目錄中找ä¸åˆ°æœ‰æ•ˆçš„æ›¸ç±¤æª”案" + +#: ../glib/gbookmarkfile.c:1957 +#, c-format +msgid "A bookmark for URI '%s' already exists" +msgstr "URI「%sã€çš„æ›¸ç±¤å·²ç¶“存在" + +#: ../glib/gbookmarkfile.c:2003 ../glib/gbookmarkfile.c:2161 +#: ../glib/gbookmarkfile.c:2246 ../glib/gbookmarkfile.c:2326 +#: ../glib/gbookmarkfile.c:2411 ../glib/gbookmarkfile.c:2494 +#: ../glib/gbookmarkfile.c:2572 ../glib/gbookmarkfile.c:2651 +#: ../glib/gbookmarkfile.c:2693 ../glib/gbookmarkfile.c:2790 +#: ../glib/gbookmarkfile.c:2910 ../glib/gbookmarkfile.c:3100 +#: ../glib/gbookmarkfile.c:3176 ../glib/gbookmarkfile.c:3344 +#: ../glib/gbookmarkfile.c:3433 ../glib/gbookmarkfile.c:3522 +#: ../glib/gbookmarkfile.c:3638 +#, c-format +msgid "No bookmark found for URI '%s'" +msgstr "找ä¸åˆ° URI「%sã€çš„æ›¸ç±¤" + +#: ../glib/gbookmarkfile.c:2335 +#, c-format +msgid "No MIME type defined in the bookmark for URI '%s'" +msgstr "URI「%sã€æ›¸ç±¤ä¸­æ²’有定義 MIME 類型" + +#: ../glib/gbookmarkfile.c:2420 +#, c-format +msgid "No private flag has been defined in bookmark for URI '%s'" +msgstr "URI「%sã€æ›¸ç±¤ä¸­æ²’æœ‰ç§æœ‰æ——幟" + +#: ../glib/gbookmarkfile.c:2799 +#, c-format +msgid "No groups set in bookmark for URI '%s'" +msgstr "URI「%sã€æ›¸ç±¤ä¸­æ²’有設定羣組" + +#: ../glib/gbookmarkfile.c:3197 ../glib/gbookmarkfile.c:3354 +#, c-format +msgid "No application with name '%s' registered a bookmark for '%s'" +msgstr "沒有å為「%sã€çš„æ‡‰ç”¨ç¨‹å¼è¨»å†Šæ›¸ç±¤ã€Œ%sã€" + +#: ../glib/gbookmarkfile.c:3377 +#, c-format +msgid "Failed to expand exec line '%s' with URI '%s'" +msgstr "以 URI‘%2$s’ 展開 exec 行‘%1$s’失敗" + +#: ../glib/gconvert.c:477 ../glib/gutf8.c:833 ../glib/gutf8.c:1044 +#: ../glib/gutf8.c:1181 ../glib/gutf8.c:1285 +msgid "Partial character sequence at end of input" +msgstr "è¼¸å…¥è³‡æ–™çµæŸæ™‚å­—ç¬¦ä»æœªå®Œæ•´" + +#: ../glib/gconvert.c:742 +#, c-format +msgid "Cannot convert fallback '%s' to codeset '%s'" +msgstr "無法將後備字串‘%sâ€™çš„å­—ç¬¦é›†è½‰æ›æˆâ€˜%s’" + +#: ../glib/gconvert.c:1566 +#, c-format +msgid "The URI '%s' is not an absolute URI using the \"file\" scheme" +msgstr "URI‘%sâ€™ä¸æ˜¯ä½¿ç”¨â€œfileâ€æ ¼å¼çš„çµ•å° URI" + +#: ../glib/gconvert.c:1576 +#, c-format +msgid "The local file URI '%s' may not include a '#'" +msgstr "本機檔案的 URI‘%sâ€™ä¸æ‡‰å«æœ‰â€˜#’" + +#: ../glib/gconvert.c:1593 +#, c-format +msgid "The URI '%s' is invalid" +msgstr "URI‘%s’無效" + +#: ../glib/gconvert.c:1605 +#, c-format +msgid "The hostname of the URI '%s' is invalid" +msgstr "URI‘%s’中的主機å稱無效" + +#: ../glib/gconvert.c:1621 +#, c-format +msgid "The URI '%s' contains invalidly escaped characters" +msgstr "URI‘%sâ€™å«æœ‰ã€Œä¸æ­£ç¢ºè·³å‡ºã€çš„字符" + +#: ../glib/gconvert.c:1716 +#, c-format +msgid "The pathname '%s' is not an absolute path" +msgstr "路徑å稱‘%sâ€™ä¸æ˜¯çµ•å°è·¯å¾‘" + +#: ../glib/gconvert.c:1726 +msgid "Invalid hostname" +msgstr "主機å稱無效" + +#. Translators: 'before midday' indicator +#: ../glib/gdatetime.c:201 +msgctxt "GDateTime" +msgid "AM" +msgstr "上åˆ" + +#. Translators: 'after midday' indicator +#: ../glib/gdatetime.c:203 +msgctxt "GDateTime" +msgid "PM" +msgstr "下åˆ" + +#. Translators: this is the preferred format for expressing the date and the time +#: ../glib/gdatetime.c:206 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "西元%Yå¹´%m月%dæ—¥ (%A) %H時%M分%Sç§’" + +#. Translators: this is the preferred format for expressing the date +#: ../glib/gdatetime.c:209 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%y/%m/%d" + +#. Translators: this is the preferred format for expressing the time +#: ../glib/gdatetime.c:212 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: ../glib/gdatetime.c:215 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%p %I時%M分%Sç§’" + +#: ../glib/gdatetime.c:228 +msgctxt "full month name" +msgid "January" +msgstr "一月" + +#: ../glib/gdatetime.c:230 +msgctxt "full month name" +msgid "February" +msgstr "二月" + +#: ../glib/gdatetime.c:232 +msgctxt "full month name" +msgid "March" +msgstr "三月" + +#: ../glib/gdatetime.c:234 +msgctxt "full month name" +msgid "April" +msgstr "四月" + +#: ../glib/gdatetime.c:236 +msgctxt "full month name" +msgid "May" +msgstr "五月" + +#: ../glib/gdatetime.c:238 +msgctxt "full month name" +msgid "June" +msgstr "六月" + +#: ../glib/gdatetime.c:240 +msgctxt "full month name" +msgid "July" +msgstr "七月" + +#: ../glib/gdatetime.c:242 +msgctxt "full month name" +msgid "August" +msgstr "八月" + +#: ../glib/gdatetime.c:244 +msgctxt "full month name" +msgid "September" +msgstr "乿œˆ" + +#: ../glib/gdatetime.c:246 +msgctxt "full month name" +msgid "October" +msgstr "åæœˆ" + +#: ../glib/gdatetime.c:248 +msgctxt "full month name" +msgid "November" +msgstr "å一月" + +#: ../glib/gdatetime.c:250 +msgctxt "full month name" +msgid "December" +msgstr "å二月" + +#: ../glib/gdatetime.c:265 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "一月" + +#: ../glib/gdatetime.c:267 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "二月" + +#: ../glib/gdatetime.c:269 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "三月" + +#: ../glib/gdatetime.c:271 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "四月" + +#: ../glib/gdatetime.c:273 +msgctxt "abbreviated month name" +msgid "May" +msgstr "五月" + +#: ../glib/gdatetime.c:275 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "六月" + +#: ../glib/gdatetime.c:277 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "七月" + +#: ../glib/gdatetime.c:279 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "八月" + +#: ../glib/gdatetime.c:281 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "乿œˆ" + +#: ../glib/gdatetime.c:283 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "åæœˆ" + +#: ../glib/gdatetime.c:285 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "å一月" + +#: ../glib/gdatetime.c:287 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "å二月" + +#: ../glib/gdatetime.c:302 +msgctxt "full weekday name" +msgid "Monday" +msgstr "星期一" + +#: ../glib/gdatetime.c:304 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "星期二" + +#: ../glib/gdatetime.c:306 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "星期三" + +#: ../glib/gdatetime.c:308 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "星期四" + +#: ../glib/gdatetime.c:310 +msgctxt "full weekday name" +msgid "Friday" +msgstr "星期五" + +#: ../glib/gdatetime.c:312 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "星期六" + +#: ../glib/gdatetime.c:314 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "星期日" + +#: ../glib/gdatetime.c:329 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "週一" + +#: ../glib/gdatetime.c:331 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "週二" + +#: ../glib/gdatetime.c:333 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "週三" + +#: ../glib/gdatetime.c:335 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "週四" + +#: ../glib/gdatetime.c:337 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "週五" + +#: ../glib/gdatetime.c:339 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "週六" + +#: ../glib/gdatetime.c:341 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "週日" + +#: ../glib/gdir.c:155 +#, c-format +msgid "Error opening directory '%s': %s" +msgstr "開啟目錄‘%s’時發生錯誤:%s" + +#: ../glib/gfileutils.c:700 ../glib/gfileutils.c:792 +#, c-format +msgid "Could not allocate %lu byte to read file \"%s\"" +msgid_plural "Could not allocate %lu bytes to read file \"%s\"" +msgstr[0] "無法é…ç½® %lu ä½å…ƒçµ„ä¾†è®€å–æª”案「%sã€" + +#: ../glib/gfileutils.c:717 +#, c-format +msgid "Error reading file '%s': %s" +msgstr "è®€å–æª”案‘%s’時發生錯誤:%s" + +#: ../glib/gfileutils.c:753 +#, c-format +msgid "File \"%s\" is too large" +msgstr "檔案「%sã€å¤ªéŽå·¨å¤§" + +#: ../glib/gfileutils.c:817 +#, c-format +msgid "Failed to read from file '%s': %s" +msgstr "è®€å–æª”案‘%s’失敗:%s" + +#: ../glib/gfileutils.c:865 ../glib/gfileutils.c:937 +#, c-format +msgid "Failed to open file '%s': %s" +msgstr "開啟檔案「%sã€å¤±æ•—:%s" + +#: ../glib/gfileutils.c:877 +#, c-format +msgid "Failed to get attributes of file '%s': fstat() failed: %s" +msgstr "ç²å–檔案‘%s’的屬性失敗:fstat() 失敗:%s" + +#: ../glib/gfileutils.c:907 +#, c-format +msgid "Failed to open file '%s': fdopen() failed: %s" +msgstr "開啟檔案‘%s’失敗:fdopen() 失敗:%s" + +#: ../glib/gfileutils.c:1006 +#, c-format +msgid "Failed to rename file '%s' to '%s': g_rename() failed: %s" +msgstr "檔案å稱由‘%s’改為‘%s’失敗:g_rename() 失敗:%s" + +#: ../glib/gfileutils.c:1041 ../glib/gfileutils.c:1540 +#, c-format +msgid "Failed to create file '%s': %s" +msgstr "建立檔案‘%s’失敗:%s" + +#: ../glib/gfileutils.c:1068 +#, c-format +msgid "Failed to write file '%s': write() failed: %s" +msgstr "無法寫入檔案「%sã€ï¼šwrite() 失敗:%s" + +#: ../glib/gfileutils.c:1111 +#, c-format +msgid "Failed to write file '%s': fsync() failed: %s" +msgstr "無法寫入檔案「%sã€ï¼šfsync() 失敗:%s" + +#: ../glib/gfileutils.c:1235 +#, c-format +msgid "Existing file '%s' could not be removed: g_unlink() failed: %s" +msgstr "ç¾å­˜æª”案‘%s’無法移除:g_unlink() 失敗:%s" + +#: ../glib/gfileutils.c:1506 +#, c-format +msgid "Template '%s' invalid, should not contain a '%s'" +msgstr "樣å¼â€˜%sâ€™ç„¡æ•ˆï¼Œä¸æ‡‰å«æœ‰â€˜%s’" + +# (Abel) this is file template for mktemp/mkstemp +#: ../glib/gfileutils.c:1519 +#, c-format +msgid "Template '%s' doesn't contain XXXXXX" +msgstr "檔案樣å¼â€˜%sâ€™æ²’æœ‰åŒ…å« XXXXXX" + +#: ../glib/gfileutils.c:2038 +#, c-format +msgid "Failed to read the symbolic link '%s': %s" +msgstr "讀å–符號連çµâ€˜%s’失敗:%s" + +#: ../glib/gfileutils.c:2057 +msgid "Symbolic links not supported" +msgstr "䏿”¯æ´ç¬¦è™Ÿé€£çµ" + +#: ../glib/giochannel.c:1389 +#, c-format +msgid "Could not open converter from '%s' to '%s': %s" +msgstr "無法開啟將‘%s’轉æ›è‡³â€˜%s’的轉æ›å™¨ï¼š%s" + +#: ../glib/giochannel.c:1734 +msgid "Can't do a raw read in g_io_channel_read_line_string" +msgstr "在 g_io_channel_read_line_string 中無法讀å–原始資料" + +#: ../glib/giochannel.c:1781 ../glib/giochannel.c:2039 +#: ../glib/giochannel.c:2126 +msgid "Leftover unconverted data in read buffer" +msgstr "用來讀å–資料的緩è¡å€ä¸­ä»æœ‰æœªè½‰æ›çš„資料" + +#: ../glib/giochannel.c:1862 ../glib/giochannel.c:1939 +msgid "Channel terminates in a partial character" +msgstr "在字符未完整之å‰ï¼Œè¼¸å…¥ç®¡é“å·²ç¶“çµæŸ" + +#: ../glib/giochannel.c:1925 +msgid "Can't do a raw read in g_io_channel_read_to_end" +msgstr "g_io_channel_read_to_end 中無法讀å–原始資料" + +#: ../glib/gkeyfile.c:719 +msgid "Valid key file could not be found in search dirs" +msgstr "在資料目錄中找ä¸åˆ°æœ‰æ•ˆçš„è¨­å®šéµæª”案" + +#: ../glib/gkeyfile.c:755 +msgid "Not a regular file" +msgstr "䏿˜¯æ­£è¦çš„æª”案" + +#: ../glib/gkeyfile.c:1155 +#, c-format +msgid "" +"Key file contains line '%s' which is not a key-value pair, group, or comment" +msgstr "è¨­å®šéµæª”案中‘%s’行並éžè¨­å®šéµå€¼é…å°ã€ç¾£çµ„或註解" + +#: ../glib/gkeyfile.c:1212 +#, c-format +msgid "Invalid group name: %s" +msgstr "無效的羣組å稱:%s" + +#: ../glib/gkeyfile.c:1234 +msgid "Key file does not start with a group" +msgstr "è¨­å®šéµæª”案並éžä»¥ç¾£çµ„é–‹é ­" + +#: ../glib/gkeyfile.c:1260 +#, c-format +msgid "Invalid key name: %s" +msgstr "無效的設定éµå稱:%s" + +#: ../glib/gkeyfile.c:1287 +#, c-format +msgid "Key file contains unsupported encoding '%s'" +msgstr "è¨­å®šéµæª”案包å«ä¸æ”¯æ´çš„編碼‘%s’" + +#: ../glib/gkeyfile.c:1530 ../glib/gkeyfile.c:1692 ../glib/gkeyfile.c:3072 +#: ../glib/gkeyfile.c:3138 ../glib/gkeyfile.c:3264 ../glib/gkeyfile.c:3397 +#: ../glib/gkeyfile.c:3539 ../glib/gkeyfile.c:3768 ../glib/gkeyfile.c:3835 +#, c-format +msgid "Key file does not have group '%s'" +msgstr "è¨­å®šéµæª”案沒有羣組‘%s’" + +#: ../glib/gkeyfile.c:1704 +#, c-format +msgid "Key file does not have key '%s'" +msgstr "è¨­å®šéµæª”案沒有設定éµâ€˜%s’" + +#: ../glib/gkeyfile.c:1811 ../glib/gkeyfile.c:1927 +#, c-format +msgid "Key file contains key '%s' with value '%s' which is not UTF-8" +msgstr "è¨­å®šéµæª”案包å«çš„設定éµâ€˜%s’(數值為‘%sâ€™ï¼‰ä¸¦éž UTF-8" + +#: ../glib/gkeyfile.c:1831 ../glib/gkeyfile.c:1947 ../glib/gkeyfile.c:2316 +#, c-format +msgid "" +"Key file contains key '%s' which has a value that cannot be interpreted." +msgstr "è¨­å®šéµæª”案包å«çš„設定éµã€Œ%sã€çš„æ•¸å€¼ç„¡æ³•解譯。" + +#: ../glib/gkeyfile.c:2533 ../glib/gkeyfile.c:2901 +#, c-format +msgid "" +"Key file contains key '%s' in group '%s' which has a value that cannot be " +"interpreted." +msgstr "è¨­å®šéµæª”案包å«çš„羣組「%2$sã€ä¸­è¨­å®šéµã€Œ%1$sã€æ•¸å€¼ç„¡æ³•解譯。" + +#: ../glib/gkeyfile.c:2611 ../glib/gkeyfile.c:2688 +#, c-format +msgid "Key '%s' in group '%s' has value '%s' where %s was expected" +msgstr "羣組「%2$sã€ä¸­è¨­å®šéµã€Œ%1$sã€åŒ…嫿•¸å€¼ã€Œ%3$sã€ï¼Œä½†é æœŸç‚ºã€Œ%4$sã€" + +#: ../glib/gkeyfile.c:3087 ../glib/gkeyfile.c:3279 ../glib/gkeyfile.c:3846 +#, c-format +msgid "Key file does not have key '%s' in group '%s'" +msgstr "è¨­å®šéµæª”案的羣組‘%2$s’中沒有設定éµâ€˜%1$s’" + +#: ../glib/gkeyfile.c:4078 +msgid "Key file contains escape character at end of line" +msgstr "è¨­å®šéµæª”案在行尾包å«è·³å‡ºå­—符" + +#: ../glib/gkeyfile.c:4100 +#, c-format +msgid "Key file contains invalid escape sequence '%s'" +msgstr "è¨­å®šéµæª”æ¡ˆå«æœ‰ä¸æ­£ç¢ºçš„「跳出字符ã€â€˜%s’" + +#: ../glib/gkeyfile.c:4242 +#, c-format +msgid "Value '%s' cannot be interpreted as a number." +msgstr "數值‘%s’ä¸èƒ½è¢«è§£è­¯ç‚ºæ•¸å­—。" + +#: ../glib/gkeyfile.c:4256 +#, c-format +msgid "Integer value '%s' out of range" +msgstr "整數值‘%s’超出範åœ" + +#: ../glib/gkeyfile.c:4289 +#, c-format +msgid "Value '%s' cannot be interpreted as a float number." +msgstr "數值‘%s’ä¸èƒ½è¢«è§£è­¯ç‚ºæµ®é»žæ•¸ã€‚" + +#: ../glib/gkeyfile.c:4313 +#, c-format +msgid "Value '%s' cannot be interpreted as a boolean." +msgstr "數值‘%s’ä¸èƒ½è¢«è§£è­¯ç‚ºé‚輯值。" + +#: ../glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file '%s%s%s%s': fstat() failed: %s" +msgstr "ç²å–檔案 「%s%s%s%sã€çš„屬性失敗:fstat() 失敗:%s" + +#: ../glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "å°æ‡‰æª”案 %s%s%s%s 失敗:mmap() 失敗:%s" + +#: ../glib/gmappedfile.c:261 +#, c-format +msgid "Failed to open file '%s': open() failed: %s" +msgstr "開啟檔案‘%s’失敗:open() 失敗:%s" + +#: ../glib/gmarkup.c:398 ../glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "第 %d 列第 %d 個字發生錯誤:" + +#: ../glib/gmarkup.c:462 ../glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name - not valid '%s'" +msgstr "å稱中無效的 UTF-8 編碼文字 - 䏿˜¯åˆæ³•的「%sã€" + +#: ../glib/gmarkup.c:473 +#, c-format +msgid "'%s' is not a valid name" +msgstr "「%sã€ä¸æ˜¯ä¸€å€‹æœ‰æ•ˆçš„å稱" + +#: ../glib/gmarkup.c:489 +#, c-format +msgid "'%s' is not a valid name: '%c'" +msgstr "「%sã€ä¸æ˜¯ä¸€å€‹æœ‰æ•ˆçš„å稱「%cã€" + +#: ../glib/gmarkup.c:599 +#, c-format +msgid "Error on line %d: %s" +msgstr "第 %d 列發生錯誤:%s" + +#: ../glib/gmarkup.c:683 +#, c-format +msgid "" +"Failed to parse '%-.*s', which should have been a digit inside a character " +"reference (ê for example) - perhaps the digit is too large" +msgstr "無法解æžâ€˜%-.*s’,字符åƒå¼•å…§æ‡‰è©²å«æœ‰æ•¸å­—(例如 ê)─ å¯èƒ½æ˜¯æ•¸å­—太大" + +#: ../glib/gmarkup.c:695 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity - escape ampersand " +"as &" +msgstr "字符åƒå¼•çš„çµæŸéƒ¨åˆ†ä¸æ˜¯åˆ†è™Ÿï¼›å¾ˆå¯èƒ½ä½ æƒ³ä½¿ç”¨ & 字符但未將它變為實體 ─ è«‹å°‡ & 轉æ›ç‚º &" + +#: ../glib/gmarkup.c:721 +#, c-format +msgid "Character reference '%-.*s' does not encode a permitted character" +msgstr "字符åƒå¼•‘%-.*s’無法表示任何能接å—的字符" + +#: ../glib/gmarkup.c:759 +msgid "" +"Empty entity '&;' seen; valid entities are: & " < > '" +msgstr "出ç¾ç©ºç™½çš„實體‘&;’;å¯ç”¨çš„實體為:& " < > '" + +#: ../glib/gmarkup.c:767 +#, c-format +msgid "Entity name '%-.*s' is not known" +msgstr "實體å稱 '%-.*s' æ„ç¾©ä¸æ˜Ž" + +#: ../glib/gmarkup.c:772 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity - escape ampersand as &" +msgstr "å¯¦é«”çš„çµæŸéƒ¨åˆ†ä¸æ˜¯åˆ†è™Ÿï¼›å¾ˆå¯èƒ½ä½ æƒ³ä½¿ç”¨ & 字符但未將它變為實體 ─ è«‹å°‡ & 轉æ›ç‚º &" + +#: ../glib/gmarkup.c:1178 +msgid "Document must begin with an element (e.g. )" +msgstr "文件開始必須為一元素(例如 )" + +#: ../glib/gmarkup.c:1218 +#, c-format +msgid "" +"'%s' is not a valid character following a '<' character; it may not begin an " +"element name" +msgstr "‘<’字符後的‘%sâ€™ä¸æ˜¯æœ‰æ•ˆçš„字符;這樣ä¸å¯èƒ½æ˜¯å…ƒç´ å稱的開始部份" + +#: ../glib/gmarkup.c:1260 +#, c-format +msgid "" +"Odd character '%s', expected a '>' character to end the empty-element tag " +"'%s'" +msgstr "字符「%sã€åªæœ‰ä¸€åŠï¼Œç©ºå…ƒç´ æ¨™ç±¤ã€Œ%sã€çš„çµå°¾æ‡‰è©²ä»¥â€˜>â€™å­—ç¬¦çµæŸ" + +#: ../glib/gmarkup.c:1341 +#, c-format +msgid "" +"Odd character '%s', expected a '=' after attribute name '%s' of element '%s'" +msgstr "ä¸å°‹å¸¸çš„字符‘%s’,屬性å稱‘%s’(屬於元素‘%s’)後應該是‘=’字符" + +#: ../glib/gmarkup.c:1382 +#, c-format +msgid "" +"Odd character '%s', expected a '>' or '/' character to end the start tag of " +"element '%s', or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "ä¸å°‹å¸¸çš„字符‘%s’,元素‘%s’的開始標籤應該以‘>’或‘/’字符終çµï¼Œä¹Ÿå¯ä»¥æ˜¯å±¬æ€§ï¼›æˆ–許你在屬性å稱中使用了無效的字符" + +#: ../glib/gmarkup.c:1426 +#, c-format +msgid "" +"Odd character '%s', expected an open quote mark after the equals sign when " +"giving value for attribute '%s' of element '%s'" +msgstr "ä¸å°‹å¸¸çš„字符‘%s’,當指定屬性‘%s’的值(屬於元素‘%s’)時,等號後應該出ç¾é–‹å¼•號" + +#: ../glib/gmarkup.c:1559 +#, c-format +msgid "" +"'%s' is not a valid character following the characters ''" +msgstr "字符‘%s’是無效的(ä½ç½®åœ¨é—œé–‰å…ƒç´ â€˜%s’末端);å…許的字符為「>ã€" + +#: ../glib/gmarkup.c:1606 +#, c-format +msgid "Element '%s' was closed, no element is currently open" +msgstr "元素‘%s’已關閉,沒有開啟中的元素" + +#: ../glib/gmarkup.c:1615 +#, c-format +msgid "Element '%s' was closed, but the currently open element is '%s'" +msgstr "元素‘%s’已關閉,但開啟中的元素是‘%s’" + +#: ../glib/gmarkup.c:1768 +msgid "Document was empty or contained only whitespace" +msgstr "文件完全空白或åªå«æœ‰ç©ºç™½å­—符" + +#: ../glib/gmarkup.c:1782 +msgid "Document ended unexpectedly just after an open angle bracket '<'" +msgstr "文件在尖角括號‘<’後çªç„¶çµ‚æ­¢" + +#: ../glib/gmarkup.c:1790 ../glib/gmarkup.c:1835 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open - '%s' was the last " +"element opened" +msgstr "在ä»ç„¶æœ‰é–‹å•Ÿä¸­çš„元素時,文件çªç„¶çµæŸ ─‘%s’是最後一個開啟的元素" + +#: ../glib/gmarkup.c:1798 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "文件çªç„¶çµæŸï¼Œæœ¬ä¾†æ‡‰è©²å‡ºç¾ç”¨ä¾†é—œé–‰æ¨™ç±¤ <%s/> 的尖角括號" + +#: ../glib/gmarkup.c:1804 +msgid "Document ended unexpectedly inside an element name" +msgstr "在元素的å稱內,文件çªç„¶çµæŸ" + +#: ../glib/gmarkup.c:1810 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "在屬性å稱內,文件çªç„¶çµæŸ" + +#: ../glib/gmarkup.c:1815 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "在元素的開啟標籤內,文件çªç„¶çµæŸ" + +#: ../glib/gmarkup.c:1821 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "在屬性å稱的等號後,文件çªç„¶çµæŸï¼›æ²’有屬性值" + +#: ../glib/gmarkup.c:1828 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "在屬性值內,文件çªç„¶çµæŸ" + +#: ../glib/gmarkup.c:1844 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element '%s'" +msgstr "在元素‘%s’的關閉標籤內,文件çªç„¶çµæŸ" + +#: ../glib/gmarkup.c:1850 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "åœ¨è¨»è§£æˆ–è™•ç†æŒ‡ç¤ºå…§ï¼Œæ–‡ä»¶çªç„¶çµæŸ" + +#: ../glib/goption.c:795 +msgid "Usage:" +msgstr "用法:" + +#: ../glib/goption.c:795 +msgid "[OPTION...]" +msgstr "[é¸é ……]" + +#: ../glib/goption.c:911 +msgid "Help Options:" +msgstr "說明é¸é …:" + +#: ../glib/goption.c:912 +msgid "Show help options" +msgstr "顯示說明的é¸é …" + +#: ../glib/goption.c:918 +msgid "Show all help options" +msgstr "顯示所有的說明é¸é …" + +#: ../glib/goption.c:980 +msgid "Application Options:" +msgstr "應用程å¼é¸é …:" + +#: ../glib/goption.c:1044 ../glib/goption.c:1114 +#, c-format +msgid "Cannot parse integer value '%s' for %s" +msgstr "無法給 %2$s è§£æžæ•´æ•¸å€¼â€˜%1$s’" + +#: ../glib/goption.c:1054 ../glib/goption.c:1122 +#, c-format +msgid "Integer value '%s' for %s out of range" +msgstr "%2$s 的整數值‘%1$s’超出範åœ" + +#: ../glib/goption.c:1079 +#, c-format +msgid "Cannot parse double value '%s' for %s" +msgstr "無法給 %2$s è§£æžé›™ç²¾åº¦æµ®é»žæ•¸â€˜%1$s’" + +#: ../glib/goption.c:1087 +#, c-format +msgid "Double value '%s' for %s out of range" +msgstr "%2$s 的雙精度浮點數‘%1$s’超出範åœ" + +#: ../glib/goption.c:1373 ../glib/goption.c:1452 +#, c-format +msgid "Error parsing option %s" +msgstr "è§£æž %s é¸é …時發生錯誤" + +#: ../glib/goption.c:1483 ../glib/goption.c:1596 +#, c-format +msgid "Missing argument for %s" +msgstr "缺少 %s çš„åƒæ•¸" + +#: ../glib/goption.c:2057 +#, c-format +msgid "Unknown option %s" +msgstr "䏿˜Žçš„é¸é … %s" + +#: ../glib/gregex.c:258 +msgid "corrupted object" +msgstr "ææ¯€çš„物件" + +#: ../glib/gregex.c:260 +msgid "internal error or corrupted object" +msgstr "å…§éƒ¨éŒ¯èª¤æˆ–ææ¯€çš„物件" + +#: ../glib/gregex.c:262 +msgid "out of memory" +msgstr "記憶體耗盡" + +#: ../glib/gregex.c:267 +msgid "backtracking limit reached" +msgstr "å·²é”回溯上é™" + +#: ../glib/gregex.c:279 ../glib/gregex.c:287 +msgid "the pattern contains items not supported for partial matching" +msgstr "此模å¼åŒ…å«äº†ä¸æ”¯æ´éƒ¨åˆ†æ¯”å°çš„é …ç›®" + +#: ../glib/gregex.c:289 +msgid "back references as conditions are not supported for partial matching" +msgstr "部分比å°ä¸æ”¯æ´ä»¥åå‘åƒç…§ç‚ºæ¢ä»¶" + +#: ../glib/gregex.c:298 +msgid "recursion limit reached" +msgstr "å·²é”éžå»»ä¸Šé™" + +#: ../glib/gregex.c:300 +msgid "invalid combination of newline flags" +msgstr "無效的æ›åˆ—旗標組åˆ" + +#: ../glib/gregex.c:302 +msgid "bad offset" +msgstr "錯誤的åç§»" + +#: ../glib/gregex.c:304 +msgid "short utf8" +msgstr "çŸ­å¼ utf8" + +#: ../glib/gregex.c:306 +msgid "recursion loop" +msgstr "循環廻圈" + +#: ../glib/gregex.c:310 +msgid "unknown error" +msgstr "䏿˜Žçš„錯誤" + +#: ../glib/gregex.c:330 +msgid "\\ at end of pattern" +msgstr "\\ 於模å¼çµå°¾" + +#: ../glib/gregex.c:333 +msgid "\\c at end of pattern" +msgstr "\\c 於模å¼çµå°¾" + +#: ../glib/gregex.c:336 +msgid "unrecognized character following \\" +msgstr "ç„¡æ³•è¾¨è­˜çš„å­—ç¬¦æŽ¥ç€ \\" + +#: ../glib/gregex.c:339 +msgid "numbers out of order in {} quantifier" +msgstr "{} è£çš„æ•¸å­—次åºé¡›å€’了" + +#: ../glib/gregex.c:342 +msgid "number too big in {} quantifier" +msgstr "{} è£çš„æ•¸å­—太大了" + +#: ../glib/gregex.c:345 +msgid "missing terminating ] for character class" +msgstr "å­—ç¬¦é¡žåˆ¥ç¼ºå°‘çµæŸçš„ ]" + +#: ../glib/gregex.c:348 +msgid "invalid escape sequence in character class" +msgstr "字符類別中無效的跳脫åºåˆ—" + +#: ../glib/gregex.c:351 +msgid "range out of order in character class" +msgstr "å­—ç¬¦é¡žåˆ¥çš„ç¯„åœæ¬¡åºé¡›å€’" + +#: ../glib/gregex.c:354 +msgid "nothing to repeat" +msgstr "沒有æ±è¥¿å¯é‡è¤‡" + +#: ../glib/gregex.c:358 +msgid "unexpected repeat" +msgstr "æœªé æœŸçš„é‡è¤‡" + +#: ../glib/gregex.c:361 +msgid "unrecognized character after (? or (?-" +msgstr "在 (? 或 (?- 後無法辨識的字符" + +#: ../glib/gregex.c:364 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX 命å類別åªåœ¨å–®ä¸€é¡žåˆ¥ä¸­æ”¯æ´" + +#: ../glib/gregex.c:367 +msgid "missing terminating )" +msgstr "ç¼ºå°‘çµæŸçš„ )" + +#: ../glib/gregex.c:370 +msgid "reference to non-existent subpattern" +msgstr "åƒç…§ä¸å­˜åœ¨çš„å­æ¨¡å¼" + +#: ../glib/gregex.c:373 +msgid "missing ) after comment" +msgstr "註解後缺少 )" + +#: ../glib/gregex.c:376 +msgid "regular expression is too large" +msgstr "æ­£è¦è¡¨ç¤ºå¼å¤ªå¤§" + +#: ../glib/gregex.c:379 +msgid "failed to get memory" +msgstr "å–得記憶體失敗" + +#: ../glib/gregex.c:383 +msgid ") without opening (" +msgstr ") 沒有開頭的 (" + +#: ../glib/gregex.c:387 +msgid "code overflow" +msgstr "程å¼ç¢¼æº¢æµ" + +#: ../glib/gregex.c:391 +msgid "unrecognized character after (?<" +msgstr "在 (?< 後有無法辨識的字符" + +#: ../glib/gregex.c:394 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind 判斷æç¤º(assertion) 䏿˜¯å›ºå®šçš„長度" + +#: ../glib/gregex.c:397 +msgid "malformed number or name after (?(" +msgstr "(?( 之後有格å¼ä¸æ­£ç¢ºçš„æ•¸å­—或å稱" + +#: ../glib/gregex.c:400 +msgid "conditional group contains more than two branches" +msgstr "æ¢ä»¶å¼ç¾£çµ„包å«äº†å…©å€‹ä»¥ä¸Šçš„分支" + +#: ../glib/gregex.c:403 +msgid "assertion expected after (?(" +msgstr "(?( 後應該有判斷æç¤º(assertion)" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: ../glib/gregex.c:410 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R 或 (?[+-]æ•¸å­—å¿…é ˆæŽ¥ç€ )" + +#: ../glib/gregex.c:413 +msgid "unknown POSIX class name" +msgstr "䏿˜Žçš„ POSIX 類別å稱" + +#: ../glib/gregex.c:416 +msgid "POSIX collating elements are not supported" +msgstr "䏿”¯æ´ POSIX æ•´ç†å…ƒä»¶" + +#: ../glib/gregex.c:419 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{…} åºåˆ—中的字符值太大" + +#: ../glib/gregex.c:422 +msgid "invalid condition (?(0)" +msgstr "無效的æ¢ä»¶ (?(0)" + +#: ../glib/gregex.c:425 +msgid "\\C not allowed in lookbehind assertion" +msgstr "在 lookbehind 判斷æç¤º(assertion) 䏭䏿”¯æ´\\C" + +#: ../glib/gregex.c:432 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, å’Œ \\u 䏿”¯æ´" + +#: ../glib/gregex.c:435 +msgid "recursive call could loop indefinitely" +msgstr "éžå»»å‘¼å«å¯èƒ½è®Šæˆç„¡é™å»»åœˆ" + +#: ../glib/gregex.c:439 +msgid "unrecognized character after (?P" +msgstr "在 (?P 後有無法辨識的字符" + +#: ../glib/gregex.c:442 +msgid "missing terminator in subpattern name" +msgstr "å­æ¨¡å¼åç¨±ä¸­ç¼ºå°‘çµæŸå­—符" + +#: ../glib/gregex.c:445 +msgid "two named subpatterns have the same name" +msgstr "兩個命åçš„å­æ¨¡å¼å…·æœ‰ç›¸åŒçš„å稱" + +#: ../glib/gregex.c:448 +msgid "malformed \\P or \\p sequence" +msgstr "æ ¼å¼ä¸æ­£ç¢ºçš„ \\P 或 \\p åºåˆ—" + +#: ../glib/gregex.c:451 +msgid "unknown property name after \\P or \\p" +msgstr "在 \\P 或 \\p å¾Œæœ‰ä¸æ˜Žçš„屬性å稱" + +#: ../glib/gregex.c:454 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "å­æ¨¡å¼å稱太長(最多 32 字符)" + +#: ../glib/gregex.c:457 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "太多命åçš„å­æ¨¡å¼ï¼ˆæœ€å¤§å€¼ 10,000)" + +#: ../glib/gregex.c:460 +msgid "octal value is greater than \\377" +msgstr "8 進ä½å€¼å¤§æ–¼ \\377" + +#: ../glib/gregex.c:464 +msgid "overran compiling workspace" +msgstr "編譯工作å€è¶…出範åœ" + +#: ../glib/gregex.c:468 +msgid "previously-checked referenced subpattern not found" +msgstr "找ä¸åˆ°é å…ˆæ ¸å–çš„åƒç…§å­å­—串" + +#: ../glib/gregex.c:471 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE 羣組包å«ä¸€å€‹ä»¥ä¸Šçš„分支" + +#: ../glib/gregex.c:474 +msgid "inconsistent NEWLINE options" +msgstr "ä¸ä¸€è‡´çš„ NEWLINE é¸é …" + +#: ../glib/gregex.c:477 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "\\g 並未隨ç€å…·æœ‰å¤§æ‹¬å¼§ã€è§’括弧或引號的å稱或數字或純文字數字" + +#: ../glib/gregex.c:481 +msgid "a numbered reference must not be zero" +msgstr "編號å¼åƒç…§å¿…é ˆä¸ç‚ºé›¶" + +#: ../glib/gregex.c:484 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "引數ä¸å…許用於 (*ACCEPT)ã€(*FAIL) 或 (*COMMIT)" + +#: ../glib/gregex.c:487 +msgid "(*VERB) not recognized" +msgstr "(*VERB) 無法辨識" + +#: ../glib/gregex.c:490 +msgid "number is too big" +msgstr "數字太大" + +#: ../glib/gregex.c:493 +msgid "missing subpattern name after (?&" +msgstr "(?& å¾Œç¼ºå°‘å­æ¨£å¼" + +#: ../glib/gregex.c:496 +msgid "digit expected after (?+" +msgstr "(?+ 後應該有數字" + +#: ../glib/gregex.c:499 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] 在 JavaScript 兼容性模å¼ä¸­æ˜¯ç„¡æ•ˆçš„資料字符" + +#: ../glib/gregex.c:502 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ä¸å…è¨±åŒæ¨£ç·¨è™Ÿçš„å­æ¨£å¼æœ‰ä¸åŒçš„å稱" + +#: ../glib/gregex.c:505 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) 需è¦ä¸€å€‹å¼•數" + +#: ../glib/gregex.c:508 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c å¿…é ˆæŽ¥ç€ ASCII 字符" + +#: ../glib/gregex.c:511 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k 並未隨ç€å…·æœ‰å¤§æ‹¬å¼§ã€è§’括弧或引號的å稱" + +#: ../glib/gregex.c:514 +msgid "\\N is not supported in a class" +msgstr "\\N åœ¨é¡žåˆ¥ä¸­ä¸æ”¯æ´" + +#: ../glib/gregex.c:517 +msgid "too many forward references" +msgstr "有太多的å‘å‰åƒç…§" + +#: ../glib/gregex.c:520 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "å稱在 (*MARK)ã€(*PRUNE)ã€(*SKIP) 或 (*THEN)" + +#: ../glib/gregex.c:523 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... åºåˆ—中的字符值太大" + +#: ../glib/gregex.c:746 ../glib/gregex.c:1915 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "æ¯”å°æ­£è¦è¡¨ç¤ºå¼ %s 發生錯誤:%s" + +#: ../glib/gregex.c:1312 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE 程å¼åº«ä¸¦æœªç·¨è­¯å° UTF8 的支æ´" + +#: ../glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE 程å¼åº«ä¸¦æœªç·¨è­¯å° UTF8 屬性的支æ´" + +#: ../glib/gregex.c:1324 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE 程å¼åº«ä¸¦æœªç·¨è­¯ä¸å…¼å®¹çš„é¸é …" + +#: ../glib/gregex.c:1383 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "編譯正è¦è¡¨ç¤ºå¼ %s 時於第 %d 個字發生錯誤:%s" + +#: ../glib/gregex.c:1425 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "最佳化正è¦è¡¨ç¤ºå¼ %s 時發生錯誤:%s" + +#: ../glib/gregex.c:2347 +msgid "hexadecimal digit or '}' expected" +msgstr "應為 16 進使•¸å­—或「}ã€" + +#: ../glib/gregex.c:2363 +msgid "hexadecimal digit expected" +msgstr "應為 16 進使•¸å­—" + +#: ../glib/gregex.c:2403 +msgid "missing '<' in symbolic reference" +msgstr "在符號åƒç…§ä¸­ç¼ºå°‘「<ã€" + +#: ../glib/gregex.c:2412 +msgid "unfinished symbolic reference" +msgstr "未完æˆçš„符號åƒç…§" + +#: ../glib/gregex.c:2419 +msgid "zero-length symbolic reference" +msgstr "é›¶-長度的符號åƒç…§" + +#: ../glib/gregex.c:2430 +msgid "digit expected" +msgstr "é æœŸæ•¸å­—" + +#: ../glib/gregex.c:2448 +msgid "illegal symbolic reference" +msgstr "ä¸åˆæ³•的符號åƒç…§" + +#: ../glib/gregex.c:2510 +msgid "stray final '\\'" +msgstr "缺少最後的「\\ã€" + +#: ../glib/gregex.c:2514 +msgid "unknown escape sequence" +msgstr "䏿˜Žçš„跳脫åºåˆ—" + +#: ../glib/gregex.c:2524 +#, c-format +msgid "Error while parsing replacement text \"%s\" at char %lu: %s" +msgstr "ç•¶è§£æžæ–¼å­—符 %2$lu çš„å–代文字「%1$sã€æ™‚發生錯誤:%3$s" + +#: ../glib/gshell.c:96 +msgid "Quoted text doesn't begin with a quotation mark" +msgstr "æ‡‰è©²ç”¨å¼•è™Ÿæ‹¬èµ·ä¾†çš„æ–‡å­—ä¸æ˜¯ä»¥æ‹¬è™Ÿç‚ºé–‹å§‹" + +#: ../glib/gshell.c:186 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "指令列或其它標為指令的字串內有ä¸å°ç¨±çš„引號" + +#: ../glib/gshell.c:582 +#, c-format +msgid "Text ended just after a '\\' character. (The text was '%s')" +msgstr "文字在‘\\’字符後就終止了。(文字為‘%s’)" + +#: ../glib/gshell.c:589 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was '%s')" +msgstr "字串完çµå‰ä»æ²’æœ‰å°æ‡‰æ–¼ %c 的引號(字串為‘%s’)" + +#: ../glib/gshell.c:601 +msgid "Text was empty (or contained only whitespace)" +msgstr "文字是空白的(或åªå«æœ‰ç©ºç™½å­—符)" + +#: ../glib/gspawn.c:209 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "無法從副進程讀å–資料 (%s)" + +#: ../glib/gspawn.c:353 +#, c-format +msgid "Unexpected error in select() reading data from a child process (%s)" +msgstr "ç•¶ select() 從å­ç¨‹åºè®€å–è³‡æ–™æ™‚ç™¼ç”Ÿæœªé æœŸçš„錯誤 (%s)" + +#: ../glib/gspawn.c:438 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() ç™¼ç”Ÿæœªé æœŸçš„錯誤 (%s)" + +#: ../glib/gspawn.c:849 ../glib/gspawn-win32.c:1233 +#, c-format +msgid "Child process exited with code %ld" +msgstr "å­ç¨‹åºä»¥ä»£ç¢¼ %ld çµæŸ" + +#: ../glib/gspawn.c:857 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "å­ç¨‹åºè¢«ä¿¡è™Ÿ %ld 中止" + +#: ../glib/gspawn.c:864 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "å­ç¨‹åºè¢«ä¿¡è™Ÿ %ld åœæ­¢" + +#: ../glib/gspawn.c:871 +#, c-format +msgid "Child process exited abnormally" +msgstr "å­ç¨‹åºç•°å¸¸çµæŸ" + +#: ../glib/gspawn.c:1276 ../glib/gspawn-win32.c:339 ../glib/gspawn-win32.c:347 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "無法從管é“讀å–資料 (%s)" + +#: ../glib/gspawn.c:1346 +#, c-format +msgid "Failed to fork (%s)" +msgstr "無法è¡ç”Ÿé€²ç¨‹ (%s)" + +#: ../glib/gspawn.c:1495 ../glib/gspawn-win32.c:370 +#, c-format +msgid "Failed to change to directory '%s' (%s)" +msgstr "無法進入目錄‘%s’(%s)" + +#: ../glib/gspawn.c:1505 +#, c-format +msgid "Failed to execute child process \"%s\" (%s)" +msgstr "無法執行副進程“%sâ€(%s)" + +#: ../glib/gspawn.c:1515 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "ç„¡æ³•å°‡å‰¯é€²ç¨‹çš„è¼¸å‡ºæˆ–è¼¸å…¥é‡æ–°å°Žå‘ (%s)" + +#: ../glib/gspawn.c:1524 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "無法è¡ç”Ÿå‰¯é€²ç¨‹ (%s)" + +#: ../glib/gspawn.c:1532 +#, c-format +msgid "Unknown error executing child process \"%s\"" +msgstr "執行副進程“%sâ€æ™‚ç™¼ç”Ÿä¸æ˜Žçš„錯誤" + +#: ../glib/gspawn.c:1556 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "無法從 child pid pipe 讀å–足夠的資料 (%s)" + +#: ../glib/gspawn-win32.c:283 +msgid "Failed to read data from child process" +msgstr "無法從副進程讀å–資料" + +#: ../glib/gspawn-win32.c:300 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "無法建立管é“來和副進程æºé€š (%s)" + +#: ../glib/gspawn-win32.c:376 ../glib/gspawn-win32.c:495 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "無法執行副進程 (%s)" + +#: ../glib/gspawn-win32.c:445 +#, c-format +msgid "Invalid program name: %s" +msgstr "程å¼å稱無效:%s" + +#: ../glib/gspawn-win32.c:455 ../glib/gspawn-win32.c:722 +#: ../glib/gspawn-win32.c:1297 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "第 %d 個引數中å«ç„¡æ•ˆçš„字串:%s" + +#: ../glib/gspawn-win32.c:466 ../glib/gspawn-win32.c:737 +#: ../glib/gspawn-win32.c:1330 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "環境變數中的字串無效:%s" + +#: ../glib/gspawn-win32.c:718 ../glib/gspawn-win32.c:1278 +#, c-format +msgid "Invalid working directory: %s" +msgstr "無效的工作目錄:%s" + +#: ../glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "無法執行å”åŠ©ç¨‹å¼ (%s)" + +#: ../glib/gspawn-win32.c:997 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "ç•¶ g_io_channel_win32_poll() 從副進程讀å–資料時發生無法é è¨ˆçš„錯誤" + +#: ../glib/gutf8.c:780 +msgid "Failed to allocate memory" +msgstr "é…置記憶體失敗" + +#: ../glib/gutf8.c:912 +msgid "Character out of range for UTF-8" +msgstr "字符ä¸åœ¨ UTF-8 範åœä¹‹å…§" + +#: ../glib/gutf8.c:1012 ../glib/gutf8.c:1021 ../glib/gutf8.c:1151 +#: ../glib/gutf8.c:1160 ../glib/gutf8.c:1299 ../glib/gutf8.c:1396 +msgid "Invalid sequence in conversion input" +msgstr "轉æ›è¼¸å…¥è³‡æ–™æ™‚出ç¾ç„¡æ•ˆçš„字符次åº" + +#: ../glib/gutf8.c:1310 ../glib/gutf8.c:1407 +msgid "Character out of range for UTF-16" +msgstr "字符ä¸åœ¨ UTF-16 範åœä¹‹å…§" + +#: ../glib/gutils.c:2116 ../glib/gutils.c:2143 ../glib/gutils.c:2249 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ä½å…ƒçµ„" + +#: ../glib/gutils.c:2122 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#: ../glib/gutils.c:2124 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#: ../glib/gutils.c:2127 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#: ../glib/gutils.c:2130 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#: ../glib/gutils.c:2133 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#: ../glib/gutils.c:2136 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#: ../glib/gutils.c:2149 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#: ../glib/gutils.c:2152 ../glib/gutils.c:2267 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: ../glib/gutils.c:2155 ../glib/gutils.c:2272 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: ../glib/gutils.c:2157 ../glib/gutils.c:2277 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: ../glib/gutils.c:2160 ../glib/gutils.c:2282 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: ../glib/gutils.c:2163 ../glib/gutils.c:2287 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: ../glib/gutils.c:2200 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ä½å…ƒçµ„" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: ../glib/gutils.c:2262 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +msgctxt "full month name with day" +msgid "January" +msgstr "一月" + +msgctxt "full month name with day" +msgid "February" +msgstr "二月" + +msgctxt "full month name with day" +msgid "March" +msgstr "三月" + +msgctxt "full month name with day" +msgid "April" +msgstr "四月" + +msgctxt "full month name with day" +msgid "May" +msgstr "五月" + +msgctxt "full month name with day" +msgid "June" +msgstr "六月" + +msgctxt "full month name with day" +msgid "July" +msgstr "七月" + +msgctxt "full month name with day" +msgid "August" +msgstr "八月" + +msgctxt "full month name with day" +msgid "September" +msgstr "乿œˆ" + +msgctxt "full month name with day" +msgid "October" +msgstr "åæœˆ" + +msgctxt "full month name with day" +msgid "November" +msgstr "å一月" + +msgctxt "full month name with day" +msgid "December" +msgstr "å二月" + +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "一月" + +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "二月" + +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "三月" + +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "四月" + +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "五月" + +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "六月" + +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "七月" + +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "八月" + +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "乿œˆ" + +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "åæœˆ" + +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "å一月" + +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "å二月" diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100644 index 0000000..dd7951f --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,6068 @@ +# Chinese (Taiwan) translation for glib 2.x +# Copyright (C) 2001, 02, 03, 05, 07, 10, 20 Free Software Foundation, Inc. +# XML glossary from http://xml.ascc.net/zh/big5/gloss.html +# Chao-Hsiung Liao , 2005, 2010. +# Abel Cheung , 2001-2003, 2005. +# Woodman Tuen , 2005-07. +# Wei-Lun Chao , 2010. +# Yi-Jyun Pan , 2020. +msgid "" +msgstr "" +"Project-Id-Version: glib 2.64\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" +"POT-Creation-Date: 2020-10-01 16:40+0000\n" +"PO-Revision-Date: 2020-10-12 22:54+0800\n" +"Last-Translator: Cheng-Chia Tseng \n" +"Language-Team: Chinese (Traditional) \n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.4.1\n" + +#: gio/gapplication.c:500 +msgid "GApplication options" +msgstr "GApplication é¸é …" + +#: gio/gapplication.c:500 +msgid "Show GApplication options" +msgstr "顯示 GApplication é¸é …" + +#: gio/gapplication.c:545 +msgid "Enter GApplication service mode (use from D-Bus service files)" +msgstr "進入 GApplication æœå‹™æ¨¡å¼ (用於來自 D-Bus æœå‹™æª”案)" + +#: gio/gapplication.c:557 +msgid "Override the application’s ID" +msgstr "è¦†è“‹æ­¤æ‡‰ç”¨ç¨‹å¼ ID" + +#: gio/gapplication.c:569 +msgid "Replace the running instance" +msgstr "å–代執行中的實體" + +#: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 +#: gio/gresource-tool.c:493 gio/gsettings-tool.c:567 +msgid "Print help" +msgstr "顯示求助" + +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:494 gio/gresource-tool.c:562 +msgid "[COMMAND]" +msgstr "[指令]" + +#: gio/gapplication-tool.c:49 gio/gio-tool.c:228 +msgid "Print version" +msgstr "顯示版本" + +#: gio/gapplication-tool.c:50 gio/gsettings-tool.c:573 +msgid "Print version information and exit" +msgstr "輸出版本資訊並離開" + +#: gio/gapplication-tool.c:52 +msgid "List applications" +msgstr "列出應用程å¼" + +#: gio/gapplication-tool.c:53 +msgid "List the installed D-Bus activatable applications (by .desktop files)" +msgstr "列出已安è£å¯ä½¿ç”¨ D-Bus çš„æ‡‰ç”¨ç¨‹å¼ (ä¾ .desktop 檔案)" + +#: gio/gapplication-tool.c:55 +msgid "Launch an application" +msgstr "執行應用程å¼" + +#: gio/gapplication-tool.c:56 +msgid "Launch the application (with optional files to open)" +msgstr "åŸ·è¡Œæ‡‰ç”¨ç¨‹å¼ (鏿“‡æ€§åŠ ä¸Šè¦é–‹å•Ÿçš„æª”案)" + +#: gio/gapplication-tool.c:57 +msgid "APPID [FILE…]" +msgstr "APPID [FILE...]" + +#: gio/gapplication-tool.c:59 +msgid "Activate an action" +msgstr "讓動作生效" + +#: gio/gapplication-tool.c:60 +msgid "Invoke an action on the application" +msgstr "呼嫿‡‰ç”¨ç¨‹å¼çš„動作" + +#: gio/gapplication-tool.c:61 +msgid "APPID ACTION [PARAMETER]" +msgstr "APPID ACTION [PARAMETER]" + +#: gio/gapplication-tool.c:63 +msgid "List available actions" +msgstr "列出å¯ç”¨çš„動作" + +#: gio/gapplication-tool.c:64 +msgid "List static actions for an application (from .desktop file)" +msgstr "列出應用程å¼çš„éœæ…‹å‹•作 (從 .desktop 檔案)" + +#: gio/gapplication-tool.c:65 gio/gapplication-tool.c:71 +msgid "APPID" +msgstr "APPID" + +#: gio/gapplication-tool.c:70 gio/gapplication-tool.c:133 gio/gdbus-tool.c:102 +#: gio/gio-tool.c:224 +msgid "COMMAND" +msgstr "指令" + +#: gio/gapplication-tool.c:70 +msgid "The command to print detailed help for" +msgstr "顯示詳細求助的指令" + +#: gio/gapplication-tool.c:71 +msgid "Application identifier in D-Bus format (eg: org.example.viewer)" +msgstr "D-Bus æ ¼å¼çš„æ‡‰ç”¨ç¨‹å¼è­˜åˆ¥ç¢¼ï¼ˆä¾‹å¦‚:org.example.viewer)" + +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:500 gio/gresource-tool.c:566 +msgid "FILE" +msgstr "FILE" + +#: gio/gapplication-tool.c:72 +msgid "Optional relative or absolute filenames, or URIs to open" +msgstr "鏿“‡æ€§ç›¸å°æˆ–絕å°çš„æª”案å稱,或è¦é–‹å•Ÿçš„ URI" + +#: gio/gapplication-tool.c:73 +msgid "ACTION" +msgstr "動作" + +#: gio/gapplication-tool.c:73 +msgid "The action name to invoke" +msgstr "è¦å‘¼å«çš„動作å稱" + +#: gio/gapplication-tool.c:74 +msgid "PARAMETER" +msgstr "åƒæ•¸" + +#: gio/gapplication-tool.c:74 +msgid "Optional parameter to the action invocation, in GVariant format" +msgstr "å‹•ä½œå‘¼å«æ™‚鏿“‡æ€§çš„åƒæ•¸ï¼Œä»¥ GVariant æ ¼å¼" + +#: gio/gapplication-tool.c:96 gio/gresource-tool.c:531 gio/gsettings-tool.c:659 +#, c-format +msgid "" +"Unknown command %s\n" +"\n" +msgstr "" +"䏿˜ŽæŒ‡ä»¤ %s\n" +"\n" + +#: gio/gapplication-tool.c:101 +msgid "Usage:\n" +msgstr "用法:\n" + +#: gio/gapplication-tool.c:114 gio/gresource-tool.c:556 +#: gio/gsettings-tool.c:694 +msgid "Arguments:\n" +msgstr "引數:\n" + +#: gio/gapplication-tool.c:133 gio/gio-tool.c:224 +msgid "[ARGS…]" +msgstr "[ARGS...]" + +#: gio/gapplication-tool.c:134 +#, c-format +msgid "Commands:\n" +msgstr "指令:\n" + +#. Translators: do not translate 'help', but please translate 'COMMAND'. +#: gio/gapplication-tool.c:146 +#, c-format +msgid "" +"Use “%s help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"使用「'%s help COMMANDã€ä»¥å–得詳細的求助。\n" +"\n" + +#: gio/gapplication-tool.c:165 +#, c-format +msgid "" +"%s command requires an application id to directly follow\n" +"\n" +msgstr "" +"%s æŒ‡ä»¤éœ€è¦æ‡‰ç”¨ç¨‹å¼ id 直接跟隨\n" +"\n" + +#: gio/gapplication-tool.c:171 +#, c-format +msgid "invalid application id: “%sâ€\n" +msgstr "ç„¡æ•ˆçš„æ‡‰ç”¨ç¨‹å¼ id:「%sã€\n" + +#. Translators: %s is replaced with a command name like 'list-actions' +#: gio/gapplication-tool.c:182 +#, c-format +msgid "" +"“%s†takes no arguments\n" +"\n" +msgstr "" +"「%sã€ä¸éœ€è¦å¼•數\n" +"\n" + +#: gio/gapplication-tool.c:266 +#, c-format +msgid "unable to connect to D-Bus: %s\n" +msgstr "無法連接到 D-Bus:%s\n" + +#: gio/gapplication-tool.c:286 +#, c-format +msgid "error sending %s message to application: %s\n" +msgstr "å‚³é€ %s 訊æ¯åˆ°æ‡‰ç”¨ç¨‹å¼æ™‚發生錯誤:%s\n" + +#: gio/gapplication-tool.c:317 +msgid "action name must be given after application id\n" +msgstr "動作åç¨±å¿…é ˆåœ¨æ‡‰ç”¨ç¨‹å¼ id 之後\n" + +#: gio/gapplication-tool.c:325 +#, c-format +msgid "" +"invalid action name: “%sâ€\n" +"action names must consist of only alphanumerics, “-†and “.â€\n" +msgstr "" +"無效的動作å稱:「%sã€\n" +"動作å稱必須åªç”±å­—æ¯ã€ã€Œ-ã€å’Œã€Œ.ã€çµ„æˆ\n" + +#: gio/gapplication-tool.c:344 +#, c-format +msgid "error parsing action parameter: %s\n" +msgstr "è§£æžå‹•ä½œåƒæ•¸æ™‚發生錯誤:%s\n" + +#: gio/gapplication-tool.c:356 +msgid "actions accept a maximum of one parameter\n" +msgstr "動作最大åªèƒ½æŽ¥å—ä¸€å€‹åƒæ•¸\n" + +#: gio/gapplication-tool.c:411 +msgid "list-actions command takes only the application id" +msgstr "list-actions æŒ‡ä»¤åªæŽ¥å—æ‡‰ç”¨ç¨‹å¼ id" + +#: gio/gapplication-tool.c:421 +#, c-format +msgid "unable to find desktop file for application %s\n" +msgstr "無法找到應用程å¼çš„æ¡Œé¢æª”案 %s\n" + +#: gio/gapplication-tool.c:466 +#, c-format +msgid "" +"unrecognised command: %s\n" +"\n" +msgstr "" +"無法辨識的指令:%s\n" +"\n" + +#: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 +#: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 +#, c-format +msgid "Too large count value passed to %s" +msgstr "傳給 %s 的計數值太大" + +#: gio/gbufferedinputstream.c:891 gio/gbufferedoutputstream.c:575 +#: gio/gdataoutputstream.c:562 +msgid "Seek not supported on base stream" +msgstr "䏿”¯æ´åœ¨åŸºç¤Žä¸²æµä¸­æœå°‹" + +#: gio/gbufferedinputstream.c:937 +msgid "Cannot truncate GBufferedInputStream" +msgstr "ä¸èƒ½æˆªçŸ­ GBufferedInputStream" + +#: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 +#: gio/goutputstream.c:2198 +msgid "Stream is already closed" +msgstr "串æµå·²ç¶“關閉" + +#: gio/gbufferedoutputstream.c:612 gio/gdataoutputstream.c:592 +msgid "Truncate not supported on base stream" +msgstr "在基礎串æµä¸­ä¸æ”¯æ´æˆªçŸ­(truncate)" + +#: gio/gcancellable.c:319 gio/gdbusconnection.c:1862 gio/gdbusprivate.c:1413 +#: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 +#, c-format +msgid "Operation was cancelled" +msgstr "æ“ä½œå·²è¢«å–æ¶ˆ" + +#: gio/gcharsetconverter.c:260 +msgid "Invalid object, not initialized" +msgstr "無效的物件,尚未åˆå§‹åŒ–" + +#: gio/gcharsetconverter.c:281 gio/gcharsetconverter.c:309 +msgid "Incomplete multibyte sequence in input" +msgstr "在輸入中出ç¾ä¸å®Œæ•´çš„多ä½å…ƒçµ„次åº" + +#: gio/gcharsetconverter.c:315 gio/gcharsetconverter.c:324 +msgid "Not enough space in destination" +msgstr "在目的端中沒有足夠的空間" + +#: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:448 glib/gconvert.c:878 +#: glib/giochannel.c:1564 glib/giochannel.c:1606 glib/giochannel.c:2461 +#: glib/gutf8.c:875 glib/gutf8.c:1328 +msgid "Invalid byte sequence in conversion input" +msgstr "轉æ›è¼¸å…¥è³‡æ–™æ™‚é‡åˆ°ä¸æ­£ç¢ºçš„ä½å…ƒçµ„組åˆ" + +#: gio/gcharsetconverter.c:347 glib/gconvert.c:456 glib/gconvert.c:792 +#: glib/giochannel.c:1571 glib/giochannel.c:2473 +#, c-format +msgid "Error during conversion: %s" +msgstr "è½‰æ›æ™‚發生錯誤:%s" + +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1133 +msgid "Cancellable initialization not supported" +msgstr "䏿”¯æ´å¯å–消的åˆå§‹åŒ–" + +#: gio/gcharsetconverter.c:456 glib/gconvert.c:321 glib/giochannel.c:1392 +#, c-format +msgid "Conversion from character set “%s†to “%s†is not supported" +msgstr "䏿”¯æ´å°‡å­—元集「%sã€è½‰æ›æˆã€Œ%sã€" + +#: gio/gcharsetconverter.c:460 glib/gconvert.c:325 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€" +msgstr "無法開啟「%sã€è‡³ã€Œ%sã€çš„轉æ›" + +#: gio/gcontenttype.c:452 +#, c-format +msgid "%s type" +msgstr "%s 類型" + +#: gio/gcontenttype-win32.c:192 +msgid "Unknown type" +msgstr "䏿˜Žçš„類型" + +#: gio/gcontenttype-win32.c:194 +#, c-format +msgid "%s filetype" +msgstr "%s 檔案類型" + +#: gio/gcredentials.c:323 +msgid "GCredentials contains invalid data" +msgstr "GCredentials 有無效資料" + +#: gio/gcredentials.c:383 gio/gcredentials.c:667 +msgid "GCredentials is not implemented on this OS" +msgstr "GCredentials 沒有在這個 OS 上實作" + +#: gio/gcredentials.c:538 gio/gcredentials.c:556 +msgid "There is no GCredentials support for your platform" +msgstr "您的平臺沒有 GCredentials 支æ´" + +#: gio/gcredentials.c:607 +msgid "GCredentials does not contain a process ID on this OS" +msgstr "GCredentials 沒有包å«åœ¨é€™å€‹ OS ä¸Šçš„ç¨‹åº ID" + +#: gio/gcredentials.c:661 +msgid "Credentials spoofing is not possible on this OS" +msgstr "在這個 OS 無法åšåˆ°æ†‘è­‰å½è£" + +#: gio/gdatainputstream.c:304 +msgid "Unexpected early end-of-stream" +msgstr "æœªé æœŸçš„串æµéŽæ—©çµæŸ" + +#: gio/gdbusaddress.c:158 gio/gdbusaddress.c:232 gio/gdbusaddress.c:321 +#, c-format +msgid "Unsupported key “%s†in address entry “%sâ€" +msgstr "「%2$sã€ä½å€æ¢ç›®æœ‰ä¸æ”¯æ´çš„「%1$sã€éµ" + +#: gio/gdbusaddress.c:171 +#, c-format +msgid "Meaningless key/value pair combination in address entry “%sâ€" +msgstr "在「%sã€ä½å€æ¢ç›®ä¸­æœ‰ç„¡æ„義的éµ/值組åˆé…å°" + +#: gio/gdbusaddress.c:180 +#, c-format +msgid "" +"Address “%s†is invalid (need exactly one of path, dir, tmpdir, or abstract " +"keys)" +msgstr "「%sã€ä½å€ç„¡æ•ˆ (éœ€è¦æœ‰æ˜Žç¢ºçš„ pathã€dirã€tmpdir 或 abstract éµä¹‹ä¸€)" + +#: gio/gdbusaddress.c:247 gio/gdbusaddress.c:258 gio/gdbusaddress.c:273 +#: gio/gdbusaddress.c:336 gio/gdbusaddress.c:347 +#, c-format +msgid "Error in address “%s†— the “%s†attribute is malformed" +msgstr "「%sã€ä½å€æœ‰éŒ¯èª¤ —「%sã€ç‰¹æ€§çš„æ ¼å¼ä¸è‰¯" + +#: gio/gdbusaddress.c:417 gio/gdbusaddress.c:681 +#, c-format +msgid "Unknown or unsupported transport “%s†for address “%sâ€" +msgstr "「%2$sã€ä½å€æœ‰ä¸æ˜Žæˆ–䏿”¯æ´çš„「%1$sã€å‚³è¼¸" + +#: gio/gdbusaddress.c:461 +#, c-format +msgid "Address element “%s†does not contain a colon (:)" +msgstr "「%sã€ä½å€å…ƒç´ ä¸­ä¸¦æœªåŒ…å«åˆ†è™Ÿ (:)" + +#: gio/gdbusaddress.c:470 +#, c-format +msgid "Transport name in address element “%s†must not be empty" +msgstr "「%sã€ä½å€å…ƒç´ ä¸­çš„傳輸å稱ä¸èƒ½ç©ºç™½" + +#: gio/gdbusaddress.c:491 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†does not contain an equal " +"sign" +msgstr "在éµ/值é…å° %d,「%sã€ï¼Œã€Œ%sã€ä½å€å…ƒç´ ä¸­ï¼Œä¸¦æœªåŒ…å«ç­‰æ–¼ç¬¦è™Ÿ" + +#: gio/gdbusaddress.c:502 +#, c-format +msgid "" +"Key/Value pair %d, “%sâ€, in address element “%s†must not have an empty key" +msgstr "在éµ/值é…å° %d,「%sã€ï¼Œã€Œ%sã€ä½å€å…ƒç´ ä¸­ï¼Œä¸èƒ½æœ‰ç©ºç™½çš„éµ" + +#: gio/gdbusaddress.c:516 +#, c-format +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%sâ€, in address element " +"“%sâ€" +msgstr "在éµ/值é…å° %d,「%sã€ï¼Œã€Œ%sã€ä½å€å…ƒç´ ä¸­æœ‰éŒ¯èª¤çš„å轉義éµ" + +#: gio/gdbusaddress.c:588 +#, c-format +msgid "" +"Error in address “%s†— the unix transport requires exactly one of the keys " +"“path†or “abstract†to be set" +msgstr "「%sã€ä½å€æœ‰éŒ¯èª¤ — unix å‚³è¼¸éœ€è¦æ˜Žç¢ºçš„設定一個「pathã€æˆ–「abstractã€éµ" + +#: gio/gdbusaddress.c:624 +#, c-format +msgid "Error in address “%s†— the host attribute is missing or malformed" +msgstr "「%sã€ä½å€æœ‰éŒ¯èª¤ — host 特性éºå¤±æˆ–æ ¼å¼ä¸è‰¯" + +#: gio/gdbusaddress.c:638 +#, c-format +msgid "Error in address “%s†— the port attribute is missing or malformed" +msgstr "「%sã€ä½å€æœ‰éŒ¯èª¤ — port 特性éºå¤±æˆ–æ ¼å¼ä¸è‰¯" + +#: gio/gdbusaddress.c:652 +#, c-format +msgid "Error in address “%s†— the noncefile attribute is missing or malformed" +msgstr "「%sã€ä½å€æœ‰éŒ¯èª¤ — noncefile 特性éºå¤±æˆ–æ ¼å¼ä¸è‰¯" + +#: gio/gdbusaddress.c:673 +msgid "Error auto-launching: " +msgstr "自動執行失敗:" + +#: gio/gdbusaddress.c:726 +#, c-format +msgid "Error opening nonce file “%sâ€: %s" +msgstr "開啟臨時檔案「%sã€æ™‚發生錯誤:%s" + +#: gio/gdbusaddress.c:745 +#, c-format +msgid "Error reading from nonce file “%sâ€: %s" +msgstr "讀å–臨時檔案「%sã€æ™‚發生錯誤:%s" + +#: gio/gdbusaddress.c:754 +#, c-format +msgid "Error reading from nonce file “%sâ€, expected 16 bytes, got %d" +msgstr "讀å–臨時檔案「%sã€æ™‚ç™¼ç”ŸéŒ¯èª¤ï¼Œé æœŸç‚º 16 ä½å…ƒçµ„,å»å¾—到 %d" + +#: gio/gdbusaddress.c:772 +#, c-format +msgid "Error writing contents of nonce file “%s†to stream:" +msgstr "寫入臨時檔案「%sã€çš„å…§å®¹åˆ°ä¸²æµæ™‚發生錯誤:" + +#: gio/gdbusaddress.c:981 +msgid "The given address is empty" +msgstr "指定的ä½å€æ˜¯ç©ºç™½çš„" + +#: gio/gdbusaddress.c:1094 +#, c-format +msgid "Cannot spawn a message bus when setuid" +msgstr "在 setuid 時ä¸èƒ½ç”¢ç”Ÿè¨Šæ¯åŒ¯æµæŽ’" + +#: gio/gdbusaddress.c:1101 +msgid "Cannot spawn a message bus without a machine-id: " +msgstr "沒有 machine-id ä¸èƒ½ç”¢ç”Ÿè¨Šæ¯åŒ¯æµæŽ’:" + +#: gio/gdbusaddress.c:1108 +#, c-format +msgid "Cannot autolaunch D-Bus without X11 $DISPLAY" +msgstr "沒有 X11 $DISPLAY ä¸èƒ½è‡ªå‹•執行 D-Bus " + +#: gio/gdbusaddress.c:1150 +#, c-format +msgid "Error spawning command line “%sâ€: " +msgstr "產生命令列「%sã€æ™‚出ç¾éŒ¯èª¤ï¼š" + +#: gio/gdbusaddress.c:1219 +#, c-format +msgid "Cannot determine session bus address (not implemented for this OS)" +msgstr "ä¸èƒ½åˆ¤æ–·ä½œæ¥­éšŽæ®µåŒ¯æµæŽ’ä½å€ï¼ˆæ²’有在這個 OS 實作)" + +#: gio/gdbusaddress.c:1357 gio/gdbusconnection.c:7192 +#, c-format +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%sâ€" +msgstr "ä¸èƒ½å¾ž DBUS_STARTER_BUS_TYPE ç’°å¢ƒè®Šæ•¸åˆ¤æ–·åŒ¯æµæŽ’ä½å€ — 䏿˜Žçš„「%sã€å€¼" + +#: gio/gdbusaddress.c:1366 gio/gdbusconnection.c:7201 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "ä¸èƒ½åˆ¤æ–·åŒ¯æµæŽ’ä½å€ï¼Œå› ç‚ºå°šæœªè¨­å®š DBUS_STARTER_BUS_TYPE 環境變數" + +#: gio/gdbusaddress.c:1376 +#, c-format +msgid "Unknown bus type %d" +msgstr "䏿˜Žçš„åŒ¯æµæŽ’é¡žåž‹ %d" + +#: gio/gdbusauth.c:294 +msgid "Unexpected lack of content trying to read a line" +msgstr "æœªé æœŸçš„內容缺ä¹å˜—試讀å–行" + +#: gio/gdbusauth.c:338 +msgid "Unexpected lack of content trying to (safely) read a line" +msgstr "æœªé æœŸçš„內容缺ä¹å˜—試(安全的)讀å–行" + +#: gio/gdbusauth.c:482 +#, c-format +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "竭盡所有å¯ç”¨çš„æ ¸å°æ©Ÿåˆ¶ (已嘗試:%s) (å¯ç”¨ï¼š%s)" + +#: gio/gdbusauth.c:1167 +msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" +msgstr "å·²é€éŽ GDBusAuthObserver::authorize-authenticated-peer å–æ¶ˆ" + +#: gio/gdbusauthmechanismsha1.c:296 +#, c-format +msgid "Error when getting information for directory “%sâ€: %s" +msgstr "從目錄「%sã€å–得資訊時發生錯誤:%s" + +#: gio/gdbusauthmechanismsha1.c:311 +#, c-format +msgid "" +"Permissions on directory “%s†are malformed. Expected mode 0700, got 0%o" +msgstr "目錄「%sã€çš„æ¬Šé™æ ¼å¼ä¸‹è‰¯ã€‚é æœŸçš„æ¨¡å¼ç‚º 0700,å»å¾—到 0%o" + +#: gio/gdbusauthmechanismsha1.c:341 +#, c-format +msgid "Error creating directory “%sâ€: %s" +msgstr "建立目錄「%sã€æ™‚發生錯誤:%s" + +#: gio/gdbusauthmechanismsha1.c:386 +#, c-format +msgid "Error opening keyring “%s†for reading: " +msgstr "開啟鑰匙圈「%sã€è®€å–時發生錯誤:" + +#: gio/gdbusauthmechanismsha1.c:409 gio/gdbusauthmechanismsha1.c:731 +#, c-format +msgid "Line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "使–¼ã€Œ%2$sã€å…§å®¹ã€Œ%3$sã€çš„鑰匙圈第 %1$d 列格å¼ä¸è‰¯" + +#: gio/gdbusauthmechanismsha1.c:423 gio/gdbusauthmechanismsha1.c:745 +#, c-format +msgid "" +"First token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "使–¼ã€Œ%2$sã€å…§å®¹ã€Œ%3$sã€çš„鑰匙圈第 %1$d 列第一記號格å¼ä¸è‰¯" + +#: gio/gdbusauthmechanismsha1.c:437 gio/gdbusauthmechanismsha1.c:759 +#, c-format +msgid "" +"Second token of line %d of the keyring at “%s†with content “%s†is malformed" +msgstr "使–¼ã€Œ%2$sã€å…§å®¹ã€Œ%3$sã€çš„鑰匙圈第 %1$d 列第二記號格å¼ä¸è‰¯" + +#: gio/gdbusauthmechanismsha1.c:461 +#, c-format +msgid "Didn’t find cookie with id %d in the keyring at “%sâ€" +msgstr "在「%2$sã€é‘°åŒ™åœˆæ‰¾ä¸åˆ° id %1$d çš„ cookie" + +#: gio/gdbusauthmechanismsha1.c:507 +#, c-format +msgid "Error creating lock file “%sâ€: %s" +msgstr "建立鎖定檔案「%sã€æ™‚發生錯誤:%s" + +#: gio/gdbusauthmechanismsha1.c:571 +#, c-format +msgid "Error deleting stale lock file “%sâ€: %s" +msgstr "刪除舊的鎖定檔案「%sã€æ™‚發生錯誤:%s" + +#: gio/gdbusauthmechanismsha1.c:610 +#, c-format +msgid "Error closing (unlinked) lock file “%sâ€: %s" +msgstr "關閉 (å–æ¶ˆé€£çµ) 鎖定檔案時發生錯誤「%sã€ï¼š%s" + +#: gio/gdbusauthmechanismsha1.c:621 +#, c-format +msgid "Error unlinking lock file “%sâ€: %s" +msgstr "å–æ¶ˆé€£çµéŽ–å®šæª”æ¡ˆæ™‚ç™¼ç”ŸéŒ¯èª¤ã€Œ%sã€ï¼š%s" + +#: gio/gdbusauthmechanismsha1.c:698 +#, c-format +msgid "Error opening keyring “%s†for writing: " +msgstr "開啟鑰匙圈「%sã€å¯«å…¥æ™‚發生錯誤:" + +#: gio/gdbusauthmechanismsha1.c:892 +#, c-format +msgid "(Additionally, releasing the lock for “%s†also failed: %s) " +msgstr "(å¦å¤–,釋放「%sã€çš„鎖定失敗:%s)" + +#: gio/gdbusconnection.c:595 gio/gdbusconnection.c:2391 +msgid "The connection is closed" +msgstr "這個連線已關閉" + +#: gio/gdbusconnection.c:1892 +msgid "Timeout was reached" +msgstr "å·²é”逾時時間" + +#: gio/gdbusconnection.c:2513 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "當建立客戶端連線時é‡åˆ°ä¸æ”¯æ´çš„æ——標" + +#: gio/gdbusconnection.c:4163 gio/gdbusconnection.c:4510 +#, c-format +msgid "" +"No such interface “org.freedesktop.DBus.Properties†on object at path %s" +msgstr "在 %s 路徑的物件沒有「org.freedesktop.DBus.Propertiesã€é€™å€‹ä»‹é¢" + +#: gio/gdbusconnection.c:4305 +#, c-format +msgid "No such property “%sâ€" +msgstr "沒有這個屬性「%sã€" + +#: gio/gdbusconnection.c:4317 +#, c-format +msgid "Property “%s†is not readable" +msgstr "無法讀å–「%sã€å±¬æ€§" + +#: gio/gdbusconnection.c:4328 +#, c-format +msgid "Property “%s†is not writable" +msgstr "無法寫入「%sã€å±¬æ€§" + +#: gio/gdbusconnection.c:4348 +#, c-format +msgid "Error setting property “%sâ€: Expected type “%s†but got “%sâ€" +msgstr "「%sã€å±¬æ€§è¨­å®šéŒ¯èª¤ï¼šé æœŸçš„類型為「%sã€ä½†å¾—到「%sã€" + +#: gio/gdbusconnection.c:4453 gio/gdbusconnection.c:4661 +#: gio/gdbusconnection.c:6632 +#, c-format +msgid "No such interface “%sâ€" +msgstr "沒有這個「%sã€ä»‹é¢" + +#: gio/gdbusconnection.c:4879 gio/gdbusconnection.c:7141 +#, c-format +msgid "No such interface “%s†on object at path %s" +msgstr "在 %2$s 路徑的物件沒有「%1$sã€é€™å€‹ä»‹é¢" + +#: gio/gdbusconnection.c:4977 +#, c-format +msgid "No such method “%sâ€" +msgstr "沒有「%sã€æ–¹æ³•" + +#: gio/gdbusconnection.c:5008 +#, c-format +msgid "Type of message, “%sâ€, does not match expected type “%sâ€" +msgstr "訊æ¯çš„類型,「%sã€ï¼Œä¸ç¬¦åˆé æœŸçš„類型「%sã€" + +#: gio/gdbusconnection.c:5206 +#, c-format +msgid "An object is already exported for the interface %s at %s" +msgstr "æœ‰ç‰©ä»¶å·²ç‚ºä»‹é¢ %s 匯出於 %s" + +#: gio/gdbusconnection.c:5432 +#, c-format +msgid "Unable to retrieve property %s.%s" +msgstr "無法å–回屬性 %s.%s" + +#: gio/gdbusconnection.c:5488 +#, c-format +msgid "Unable to set property %s.%s" +msgstr "無法設定屬性 %s.%s" + +#: gio/gdbusconnection.c:5666 +#, c-format +msgid "Method “%s†returned type “%sâ€, but expected “%sâ€" +msgstr "方法「%sã€å‚³å›žé¡žåž‹ã€Œ%sã€ï¼Œä½†é æœŸç‚ºã€Œ%sã€" + +#: gio/gdbusconnection.c:6743 +#, c-format +msgid "Method “%s†on interface “%s†with signature “%s†does not exist" +msgstr "介é¢ã€Œ%2$sã€ç°½ç« ã€Œ%3$sã€çš„æ–¹æ³•「%1$sã€ä¸å­˜åœ¨" + +#: gio/gdbusconnection.c:6864 +#, c-format +msgid "A subtree is already exported for %s" +msgstr "å­æ¨¹ç‹€ç›®éŒ„已為 %s 匯出" + +#: gio/gdbusmessage.c:1255 +msgid "type is INVALID" +msgstr "類型為無效" + +#: gio/gdbusmessage.c:1266 +msgid "METHOD_CALL message: PATH or MEMBER header field is missing" +msgstr "METHOD_CALL 訊æ¯ï¼šç¼ºå°‘ PATH 或 MEMBER 標頭欄ä½" + +#: gio/gdbusmessage.c:1277 +msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" +msgstr "METHOD_RETURN 訊æ¯ï¼šç¼ºå°‘ REPLY_SERIAL 標頭欄ä½" + +#: gio/gdbusmessage.c:1289 +msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" +msgstr "ERROR 訊æ¯ï¼šç¼ºå°‘ REPLY_SERIAL 或 ERROR_NAME 標頭欄ä½" + +#: gio/gdbusmessage.c:1302 +msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" +msgstr "SIGNAL 訊æ¯ï¼šç¼ºå°‘ PATHã€INTERFACE 或 MEMBER 標頭欄ä½" + +#: gio/gdbusmessage.c:1310 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "SIGNAL 訊æ¯ï¼šPATH 標頭欄ä½ä½¿ç”¨äº†ä¿ç•™çš„值 /org/freedesktop/DBus/Local" + +#: gio/gdbusmessage.c:1318 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"SIGNAL 訊æ¯ï¼šINTERFACE 標頭欄ä½ä½¿ç”¨äº†ä¿ç•™çš„值 org.freedesktop.DBus.Local" + +#: gio/gdbusmessage.c:1366 gio/gdbusmessage.c:1426 +#, c-format +msgid "Wanted to read %lu byte but only got %lu" +msgid_plural "Wanted to read %lu bytes but only got %lu" +msgstr[0] "å˜—è©¦è®€å– %lu ä½å…ƒçµ„å»åªå¾—到 %lu" + +#: gio/gdbusmessage.c:1380 +#, c-format +msgid "Expected NUL byte after the string “%s†but found byte %d" +msgstr "é æœŸåœ¨å­—串「%sã€ä¹‹å¾Œç‚º NUL ä½å…ƒçµ„,但是發ç¾ä½å…ƒçµ„ %d" + +#: gio/gdbusmessage.c:1399 +#, c-format +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%sâ€" +msgstr "" +"é æœŸç‚ºæœ‰æ•ˆçš„ UTF-8 字串但是在ä½å…ƒçµ„ %d 處發ç¾ç„¡æ•ˆçš„ä½å…ƒçµ„ (字串的長度為 %d)。" +"到那一點之å‰çš„æœ‰æ•ˆ UTF-8 字串為「%sã€" + +#: gio/gdbusmessage.c:1463 gio/gdbusmessage.c:1711 gio/gdbusmessage.c:1900 +msgid "Value nested too deeply" +msgstr "å€¼çš„å·¢ç‹€å±¤æ¬¡éŽæ·±" + +#: gio/gdbusmessage.c:1609 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus object path" +msgstr "已解æžã€Œ%sã€å€¼ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus 物件路徑" + +#: gio/gdbusmessage.c:1631 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature" +msgstr "已解æžã€Œ%sã€å€¼ä¸æ˜¯ä¸€å€‹æœ‰æ•ˆçš„ D-Bus 簽章" + +#: gio/gdbusmessage.c:1678 +#, c-format +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgstr[0] "é‡åˆ°é•·åº¦ç‚º %u ä½å…ƒçµ„的陣列。最大長度為 2<<26 ä½å…ƒçµ„ (64 MiB)。" + +#: gio/gdbusmessage.c:1698 +#, c-format +msgid "" +"Encountered array of type “a%câ€, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"é‡åˆ°é¡žåž‹ã€Œa%cã€çš„é™£åˆ—ï¼Œé æœŸé•·åº¦æ‡‰ç‚º %u ä½å…ƒçµ„çš„å€æ•¸ï¼Œä½†ç™¼ç¾é•·åº¦ç‚º %u ä½å…ƒçµ„" + +#: gio/gdbusmessage.c:1884 +#, c-format +msgid "Parsed value “%s†for variant is not a valid D-Bus signature" +msgstr "已解æžã€Œ%sã€å€¼ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus 簽章" + +#: gio/gdbusmessage.c:1925 +#, c-format +msgid "" +"Error deserializing GVariant with type string “%s†from the D-Bus wire format" +msgstr "從 D-Bus 線性格å¼ä»¥é¡žåž‹å­—串「%sã€ååºåˆ—化 GVariant 時發生錯誤" + +#: gio/gdbusmessage.c:2110 +#, c-format +msgid "" +"Invalid endianness value. Expected 0x6c (“lâ€) or 0x42 (“Bâ€) but found value " +"0x%02x" +msgstr "無效的字節順åºå€¼ã€‚é æœŸç‚º 0x6c (「Iã€) 或 0x42 (「Bã€) å»å¾—到值 0x%02x" + +#: gio/gdbusmessage.c:2123 +#, c-format +msgid "Invalid major protocol version. Expected 1 but found %d" +msgstr "無效的主通訊å”å®šç‰ˆæœ¬ã€‚é æœŸç‚º 1 但找到 %d" + +#: gio/gdbusmessage.c:2177 gio/gdbusmessage.c:2773 +msgid "Signature header found but is not of type signature" +msgstr "æ‰¾åˆ°ç°½ç« æ¨™é ­ï¼Œä½†ä¸æ˜¯ä¸€ç¨®é¡žåž‹ç°½ç« " + +#: gio/gdbusmessage.c:2189 +#, c-format +msgid "Signature header with signature “%s†found but message body is empty" +msgstr "發ç¾ç°½ç« ã€Œ%sã€çš„簽章標頭但訊æ¯ä¸»é«”是空的" + +#: gio/gdbusmessage.c:2204 +#, c-format +msgid "Parsed value “%s†is not a valid D-Bus signature (for body)" +msgstr "已解æžã€Œ%sã€å€¼ä¸æ˜¯æœ‰æ•ˆçš„ D-Bus 簽章 (於主體)" + +#: gio/gdbusmessage.c:2236 +#, c-format +msgid "No signature header in message but the message body is %u byte" +msgid_plural "No signature header in message but the message body is %u bytes" +msgstr[0] "在訊æ¯ä¸­æ²’有簽章標頭但訊æ¯ä¸»é«”有 %u ä½å…ƒçµ„" + +#: gio/gdbusmessage.c:2246 +msgid "Cannot deserialize message: " +msgstr "ä¸èƒ½ååºåˆ—化訊æ¯ï¼š" + +#: gio/gdbusmessage.c:2590 +#, c-format +msgid "" +"Error serializing GVariant with type string “%s†to the D-Bus wire format" +msgstr "從 D-Bus 線性格å¼ä»¥é¡žåž‹å­—串「%sã€åºåˆ—化 GVariant 時發生錯誤" + +#: gio/gdbusmessage.c:2727 +#, c-format +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "è¨Šæ¯ (%d) 中的檔案æè¿°ç‹€æ…‹æ•¸é‡è·Ÿæ¨™é ­æ¬„ä½ (%d) çš„ä¸åŒ" + +#: gio/gdbusmessage.c:2735 +msgid "Cannot serialize message: " +msgstr "ä¸èƒ½åºåˆ—化訊æ¯ï¼š" + +#: gio/gdbusmessage.c:2788 +#, c-format +msgid "Message body has signature “%s†but there is no signature header" +msgstr "訊æ¯ä¸»é«”有簽章「%sã€ä½†æ˜¯æ²’有簽章標頭" + +#: gio/gdbusmessage.c:2798 +#, c-format +msgid "" +"Message body has type signature “%s†but signature in the header field is " +"“%sâ€" +msgstr "訊æ¯ä¸»é«”有類型簽章「%sã€ä½†æ˜¯æ¨™é ­æ¬„ä½ä¸­çš„簽章為「%sã€" + +#: gio/gdbusmessage.c:2814 +#, c-format +msgid "Message body is empty but signature in the header field is “(%s)â€" +msgstr "訊æ¯ä¸»é«”是空的但是標頭欄ä½ä¸­çš„簽章為「%sã€" + +#: gio/gdbusmessage.c:3367 +#, c-format +msgid "Error return with body of type “%sâ€" +msgstr "傳回類型「%sã€ä¸»é«”時發生錯誤" + +#: gio/gdbusmessage.c:3375 +msgid "Error return with empty body" +msgstr "傳回空白主體錯誤" + +#: gio/gdbusprivate.c:2244 +#, c-format +msgid "(Type any character to close this window)\n" +msgstr "(輸入任何字元以關閉這個視窗)\n" + +#: gio/gdbusprivate.c:2418 +#, c-format +msgid "Session dbus not running, and autolaunch failed" +msgstr "作業階段 dbus 尚未執行,且自動執行失敗" + +#: gio/gdbusprivate.c:2441 +#, c-format +msgid "Unable to get Hardware profile: %s" +msgstr "無法å–得硬體設定檔:%s" + +#: gio/gdbusprivate.c:2486 +msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " +msgstr "無法載入 /var/lib/dbus/machine-id 或 /etc/machine-id:" + +#: gio/gdbusproxy.c:1562 +#, c-format +msgid "Error calling StartServiceByName for %s: " +msgstr "å‘¼å« %s StartServiceByName 時發生錯誤:" + +#: gio/gdbusproxy.c:1585 +#, c-format +msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" +msgstr "來自 StartServiceByName(\"%2$s\") æ–¹æ³•çš„æœªé æœŸå›žæ‡‰ %1$d" + +#: gio/gdbusproxy.c:2688 gio/gdbusproxy.c:2823 +#, c-format +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"ä¸èƒ½å‘¼å«æ–¹æ³•ï¼›Proxy æ˜¯æ²’æœ‰æ“æœ‰è€…çš„ %s 已知å稱,而 Proxy 以 " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START 旗標建構" + +#: gio/gdbusserver.c:755 +msgid "Abstract namespace not supported" +msgstr "䏿”¯æ´æŠ½è±¡å‘½å空間" + +#: gio/gdbusserver.c:848 +msgid "Cannot specify nonce file when creating a server" +msgstr "當建立伺æœå™¨æ™‚ä¸èƒ½æŒ‡å®šè‡¨æ™‚檔案" + +#: gio/gdbusserver.c:930 +#, c-format +msgid "Error writing nonce file at “%sâ€: %s" +msgstr "在「%sã€å¯«å…¥è‡¨æ™‚檔案時發生錯誤:%s" + +#: gio/gdbusserver.c:1103 +#, c-format +msgid "The string “%s†is not a valid D-Bus GUID" +msgstr "字串「%sã€ä¸æ˜¯ä¸€å€‹æœ‰æ•ˆçš„ D-Bus GUID" + +#: gio/gdbusserver.c:1143 +#, c-format +msgid "Cannot listen on unsupported transport “%sâ€" +msgstr "ä¸èƒ½è½å–䏿”¯æ´çš„傳輸「%sã€" + +#: gio/gdbus-tool.c:107 +#, c-format +msgid "" +"Commands:\n" +" help Shows this information\n" +" introspect Introspect a remote object\n" +" monitor Monitor a remote object\n" +" call Invoke a method on a remote object\n" +" emit Emit a signal\n" +" wait Wait for a bus name to appear\n" +"\n" +"Use “%s COMMAND --help†to get help on each command.\n" +msgstr "" +"指令:\n" +" help 顯示這個資訊\n" +" introspect 檢查é ç«¯ç‰©ä»¶\n" +" monitor 監控é ç«¯ç‰©ä»¶\n" +" call 呼å«é ç«¯ç‰©ä»¶çš„æ–¹æ³•\n" +" emit 發出信號\n" +" wait ç­‰å¾…åŒ¯æµæŽ’å稱出ç¾\n" +" \n" +"使用「%s COMMAND --helpã€ä¾†å–å¾—æ¯å€‹æŒ‡ä»¤çš„æ±‚助資訊。\n" + +#: gio/gdbus-tool.c:197 gio/gdbus-tool.c:264 gio/gdbus-tool.c:336 +#: gio/gdbus-tool.c:360 gio/gdbus-tool.c:850 gio/gdbus-tool.c:1187 +#: gio/gdbus-tool.c:1672 +#, c-format +msgid "Error: %s\n" +msgstr "錯誤:%s\n" + +#: gio/gdbus-tool.c:208 gio/gdbus-tool.c:277 gio/gdbus-tool.c:1688 +#, c-format +msgid "Error parsing introspection XML: %s\n" +msgstr "è§£æžæª¢è¨Ž XML 時出ç¾éŒ¯èª¤ï¼š%s\n" + +#: gio/gdbus-tool.c:246 +#, c-format +msgid "Error: %s is not a valid name\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„å稱\n" + +#: gio/gdbus-tool.c:394 +msgid "Connect to the system bus" +msgstr "é€£ç·šåˆ°ç³»çµ±åŒ¯æµæŽ’" + +#: gio/gdbus-tool.c:395 +msgid "Connect to the session bus" +msgstr "é€£ç·šåˆ°ä½œæ¥­éšŽæ®µåŒ¯æµæŽ’" + +#: gio/gdbus-tool.c:396 +msgid "Connect to given D-Bus address" +msgstr "連線到指定的 D-Bus ä½å€" + +#: gio/gdbus-tool.c:406 +msgid "Connection Endpoint Options:" +msgstr "連線端點é¸é …:" + +#: gio/gdbus-tool.c:407 +msgid "Options specifying the connection endpoint" +msgstr "指定連線端點的é¸é …" + +#: gio/gdbus-tool.c:430 +#, c-format +msgid "No connection endpoint specified" +msgstr "沒有指定連線端點" + +#: gio/gdbus-tool.c:440 +#, c-format +msgid "Multiple connection endpoints specified" +msgstr "指定了多é‡é€£ç·šç«¯é»ž" + +#: gio/gdbus-tool.c:513 +#, c-format +msgid "" +"Warning: According to introspection data, interface “%s†does not exist\n" +msgstr "警告:根據檢討資料,介é¢ã€Œ%sã€ä¸å­˜åœ¨\n" + +#: gio/gdbus-tool.c:522 +#, c-format +msgid "" +"Warning: According to introspection data, method “%s†does not exist on " +"interface “%sâ€\n" +msgstr "警告:根據檢討資料,介é¢ã€Œ%2$sã€çš„æ–¹æ³•「%1$sã€ä¸å­˜åœ¨\n" + +#: gio/gdbus-tool.c:584 +msgid "Optional destination for signal (unique name)" +msgstr "ä¿¡è™Ÿçš„é¸æ“‡æ€§ç›®çš„端 (ç¨ç‰¹å稱)" + +#: gio/gdbus-tool.c:585 +msgid "Object path to emit signal on" +msgstr "è¦ç™¼å‡ºä¿¡è™Ÿçš„物件路徑" + +#: gio/gdbus-tool.c:586 +msgid "Signal and interface name" +msgstr "信號和介é¢å稱" + +#: gio/gdbus-tool.c:619 +msgid "Emit a signal." +msgstr "發出信號。" + +#: gio/gdbus-tool.c:674 gio/gdbus-tool.c:981 gio/gdbus-tool.c:1775 +#: gio/gdbus-tool.c:2007 gio/gdbus-tool.c:2227 +#, c-format +msgid "Error connecting: %s\n" +msgstr "連線錯誤:%s\n" + +#: gio/gdbus-tool.c:694 +#, c-format +msgid "Error: %s is not a valid unique bus name.\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„ç¨ç‰¹åŒ¯æµæŽ’å稱。\n" + +#: gio/gdbus-tool.c:713 gio/gdbus-tool.c:1024 gio/gdbus-tool.c:1818 +msgid "Error: Object path is not specified\n" +msgstr "錯誤:沒有指定物件路徑\n" + +#: gio/gdbus-tool.c:736 gio/gdbus-tool.c:1044 gio/gdbus-tool.c:1838 +#: gio/gdbus-tool.c:2078 +#, c-format +msgid "Error: %s is not a valid object path\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„物件路徑\n" + +#: gio/gdbus-tool.c:756 +msgid "Error: Signal name is not specified\n" +msgstr "錯誤:沒有指定信號å稱\n" + +#: gio/gdbus-tool.c:770 +#, c-format +msgid "Error: Signal name “%s†is invalid\n" +msgstr "錯誤:「%sã€ä¿¡è™Ÿå稱無效\n" + +#: gio/gdbus-tool.c:782 +#, c-format +msgid "Error: %s is not a valid interface name\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„介é¢å稱\n" + +#: gio/gdbus-tool.c:788 +#, c-format +msgid "Error: %s is not a valid member name\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„æˆå“¡å稱\n" + +#. Use the original non-"parse-me-harder" error +#: gio/gdbus-tool.c:825 gio/gdbus-tool.c:1156 +#, c-format +msgid "Error parsing parameter %d: %s\n" +msgstr "è§£æžåƒæ•¸ %d 時發生錯誤:%s\n" + +#: gio/gdbus-tool.c:857 +#, c-format +msgid "Error flushing connection: %s\n" +msgstr "清除連線時發生錯誤:%s\n" + +#: gio/gdbus-tool.c:884 +msgid "Destination name to invoke method on" +msgstr "è¦å‘¼å«æ–¹æ³•的目的端å稱" + +#: gio/gdbus-tool.c:885 +msgid "Object path to invoke method on" +msgstr "è¦å‘¼å«æ–¹æ³•的物件路徑" + +#: gio/gdbus-tool.c:886 +msgid "Method and interface name" +msgstr "方法和介é¢å稱" + +#: gio/gdbus-tool.c:887 +msgid "Timeout in seconds" +msgstr "逾時時間(ç§’)" + +#: gio/gdbus-tool.c:926 +msgid "Invoke a method on a remote object." +msgstr "呼å«é ç«¯ç‰©ä»¶çš„æ–¹æ³•。" + +#: gio/gdbus-tool.c:998 gio/gdbus-tool.c:1792 gio/gdbus-tool.c:2032 +msgid "Error: Destination is not specified\n" +msgstr "錯誤:尚未指定目的端\n" + +#: gio/gdbus-tool.c:1009 gio/gdbus-tool.c:1809 gio/gdbus-tool.c:2043 +#, c-format +msgid "Error: %s is not a valid bus name\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„åŒ¯æµæŽ’å稱\n" + +#: gio/gdbus-tool.c:1059 +msgid "Error: Method name is not specified\n" +msgstr "錯誤:沒有指定方法å稱\n" + +#: gio/gdbus-tool.c:1070 +#, c-format +msgid "Error: Method name “%s†is invalid\n" +msgstr "錯誤:方法å稱「%sã€æ˜¯ç„¡æ•ˆçš„\n" + +#: gio/gdbus-tool.c:1148 +#, c-format +msgid "Error parsing parameter %d of type “%sâ€: %s\n" +msgstr "è§£æžé¡žåž‹ã€Œ%2$sã€çš„åƒæ•¸ %1$d 時發生錯誤:%3$s\n" + +#: gio/gdbus-tool.c:1634 +msgid "Destination name to introspect" +msgstr "è¦æª¢è¨Žçš„目的端å稱" + +#: gio/gdbus-tool.c:1635 +msgid "Object path to introspect" +msgstr "è¦æª¢è¨Žçš„物件路徑" + +#: gio/gdbus-tool.c:1636 +msgid "Print XML" +msgstr "顯示 XML" + +#: gio/gdbus-tool.c:1637 +msgid "Introspect children" +msgstr "Introspect å­é …ç›®" + +#: gio/gdbus-tool.c:1638 +msgid "Only print properties" +msgstr "åªæœ‰åˆ—å°ç‰¹æ€§" + +#: gio/gdbus-tool.c:1727 +msgid "Introspect a remote object." +msgstr "檢查é ç«¯ç‰©ä»¶ã€‚" + +#: gio/gdbus-tool.c:1933 +msgid "Destination name to monitor" +msgstr "è¦ç›£æŽ§çš„目的端å稱" + +#: gio/gdbus-tool.c:1934 +msgid "Object path to monitor" +msgstr "è¦ç›£æŽ§çš„物件路徑" + +#: gio/gdbus-tool.c:1959 +msgid "Monitor a remote object." +msgstr "監控é ç«¯ç‰©ä»¶ã€‚" + +#: gio/gdbus-tool.c:2017 +msgid "Error: can’t monitor a non-message-bus connection\n" +msgstr "錯誤:無法監控éžè¨Šæ¯åŒ¯æµæŽ’的連線\n" + +#: gio/gdbus-tool.c:2141 +msgid "Service to activate before waiting for the other one (well-known name)" +msgstr "在等待其他å‰è¦å•Ÿç”¨çš„æœå‹™ï¼ˆå·²çŸ¥å稱)" + +#: gio/gdbus-tool.c:2144 +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "ç™¼ç”ŸéŒ¯èª¤çµæŸå‰çš„等待逾時(秒);0 表示沒有逾時(é è¨­å€¼ï¼‰" + +#: gio/gdbus-tool.c:2192 +msgid "[OPTION…] BUS-NAME" +msgstr "[OPTION…] BUS-NAME" + +#: gio/gdbus-tool.c:2193 +msgid "Wait for a bus name to appear." +msgstr "ç­‰å¾…åŒ¯æµæŽ’å稱顯示。" + +#: gio/gdbus-tool.c:2269 +msgid "Error: A service to activate for must be specified.\n" +msgstr "éŒ¯èª¤ï¼šéœ€è¦æŒ‡å®šè¦å•Ÿç”¨çš„æœå‹™ã€‚\n" + +#: gio/gdbus-tool.c:2274 +msgid "Error: A service to wait for must be specified.\n" +msgstr "éŒ¯èª¤ï¼šéœ€è¦æŒ‡å®šè¦ç­‰å¾…çš„æœå‹™ã€‚\n" + +#: gio/gdbus-tool.c:2279 +msgid "Error: Too many arguments.\n" +msgstr "錯誤:引數太多。\n" + +#: gio/gdbus-tool.c:2287 gio/gdbus-tool.c:2294 +#, c-format +msgid "Error: %s is not a valid well-known bus name.\n" +msgstr "錯誤:%s 䏿˜¯æœ‰æ•ˆçš„å·²çŸ¥åŒ¯æµæŽ’å稱。\n" + +#: gio/gdesktopappinfo.c:2073 gio/gdesktopappinfo.c:4893 +msgid "Unnamed" +msgstr "未命åçš„" + +#: gio/gdesktopappinfo.c:2483 +msgid "Desktop file didn’t specify Exec field" +msgstr "桌é¢(Desktop)檔案未指定 Exec 欄ä½" + +#: gio/gdesktopappinfo.c:2763 +msgid "Unable to find terminal required for application" +msgstr "無法找到應用程å¼è¦æ±‚的終端機" + +#: gio/gdesktopappinfo.c:3414 +#, c-format +msgid "Can’t create user application configuration folder %s: %s" +msgstr "ä¸èƒ½å»ºç«‹ä½¿ç”¨è€…應用程å¼è¨­å®šè³‡æ–™å¤¾ %s:%s" + +#: gio/gdesktopappinfo.c:3418 +#, c-format +msgid "Can’t create user MIME configuration folder %s: %s" +msgstr "ä¸èƒ½å»ºç«‹ä½¿ç”¨è€… MIME 設定資料夾 %s:%s" + +#: gio/gdesktopappinfo.c:3660 gio/gdesktopappinfo.c:3684 +msgid "Application information lacks an identifier" +msgstr "應用程å¼è³‡è¨Šç¼ºå°‘識別碼" + +#: gio/gdesktopappinfo.c:3920 +#, c-format +msgid "Can’t create user desktop file %s" +msgstr "ä¸èƒ½å»ºç«‹ä½¿ç”¨è€…æ¡Œé¢æª”案 %s" + +#: gio/gdesktopappinfo.c:4056 +#, c-format +msgid "Custom definition for %s" +msgstr "自訂 %s 的定義" + +#: gio/gdrive.c:417 +msgid "drive doesn’t implement eject" +msgstr "è£ç½®ç„¡æ³•實作退出功能(eject)" + +#. Translators: This is an error +#. * message for drive objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gdrive.c:495 +msgid "drive doesn’t implement eject or eject_with_operation" +msgstr "è£ç½®ç„¡æ³•實作退出功能(eject) 或 eject_with_operation" + +#: gio/gdrive.c:571 +msgid "drive doesn’t implement polling for media" +msgstr "è£ç½®ç„¡æ³•實作媒體的輪詢" + +#: gio/gdrive.c:778 +msgid "drive doesn’t implement start" +msgstr "è£ç½®ç„¡æ³•實作啟動功能(start)" + +#: gio/gdrive.c:880 +msgid "drive doesn’t implement stop" +msgstr "è£ç½®ç„¡æ³•å¯¦ä½œåœæ­¢åŠŸèƒ½(stop)" + +#: gio/gdtlsconnection.c:1120 gio/gtlsconnection.c:921 +msgid "TLS backend does not implement TLS binding retrieval" +msgstr "TLS 後端沒有實作 TLS ç¶å®šæ“·å–" + +#: gio/gdummytlsbackend.c:195 gio/gdummytlsbackend.c:321 +#: gio/gdummytlsbackend.c:513 +msgid "TLS support is not available" +msgstr "TLS 支æ´ç„¡æ³•使用" + +#: gio/gdummytlsbackend.c:423 +msgid "DTLS support is not available" +msgstr "DTLS 支æ´ç„¡æ³•使用" + +#: gio/gemblem.c:323 +#, c-format +msgid "Can’t handle version %d of GEmblem encoding" +msgstr "ä¸èƒ½è™•ç†ç‰ˆæœ¬ç‚º %d çš„ GEmblem 編碼" + +#: gio/gemblem.c:333 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblem encoding" +msgstr "GEmblem 編碼中記號 (%d) çš„æ•¸é‡æ ¼å¼ä¸æ­£ç¢º" + +#: gio/gemblemedicon.c:362 +#, c-format +msgid "Can’t handle version %d of GEmblemedIcon encoding" +msgstr "ä¸èƒ½è™•ç†ç‰ˆæœ¬ç‚º %d çš„ GEmblemedIcon 編碼" + +#: gio/gemblemedicon.c:372 +#, c-format +msgid "Malformed number of tokens (%d) in GEmblemedIcon encoding" +msgstr "GEmblemedIcon 編碼中記號 (%d) çš„æ•¸é‡æ ¼å¼ä¸æ­£ç¢º" + +#: gio/gemblemedicon.c:395 +msgid "Expected a GEmblem for GEmblemedIcon" +msgstr "é æœŸç‚º GEmblemedIcon çš„ GEmblem" + +#: gio/gfile.c:1044 gio/gfile.c:1282 gio/gfile.c:1420 gio/gfile.c:1658 +#: gio/gfile.c:1713 gio/gfile.c:1771 gio/gfile.c:1855 gio/gfile.c:1912 +#: gio/gfile.c:1976 gio/gfile.c:2031 gio/gfile.c:3722 gio/gfile.c:3777 +#: gio/gfile.c:4070 gio/gfile.c:4540 gio/gfile.c:4951 gio/gfile.c:5036 +#: gio/gfile.c:5126 gio/gfile.c:5223 gio/gfile.c:5310 gio/gfile.c:5411 +#: gio/gfile.c:8121 gio/gfile.c:8211 gio/gfile.c:8295 +#: gio/win32/gwinhttpfile.c:453 +msgid "Operation not supported" +msgstr "䏿”¯æ´çš„æ“ä½œ" + +#. Translators: This is an error message when +#. * trying to find the enclosing (user visible) +#. * mount of a file, but none exists. +#. +#: gio/gfile.c:1543 +msgid "Containing mount does not exist" +msgstr "包å«äº†ä¸å­˜åœ¨çš„æŽ›è¼‰é»ž" + +#: gio/gfile.c:2590 gio/glocalfile.c:2430 +msgid "Can’t copy over directory" +msgstr "ä¸èƒ½è¤‡è£½æ•´å€‹ç›®éŒ„" + +#: gio/gfile.c:2650 +msgid "Can’t copy directory over directory" +msgstr "ä¸èƒ½å°‡ç›®éŒ„複製到目錄上" + +#: gio/gfile.c:2658 +msgid "Target file exists" +msgstr "目標檔案已存在" + +#: gio/gfile.c:2677 +msgid "Can’t recursively copy directory" +msgstr "ä¸èƒ½éžå»»è¤‡è£½ç›®éŒ„" + +#: gio/gfile.c:2952 +msgid "Splice not supported" +msgstr "䏿”¯æ´æ‹¼æŽ¥" + +#: gio/gfile.c:2956 gio/gfile.c:3001 +#, c-format +msgid "Error splicing file: %s" +msgstr "拼接檔案時發生錯誤:%s" + +#: gio/gfile.c:3117 +msgid "Copy (reflink/clone) between mounts is not supported" +msgstr "䏿”¯æ´åœ¨æŽ›è¼‰é»žä¹‹é–“複製 (åƒç…§é€£çµ/é‡è£½)" + +#: gio/gfile.c:3121 +msgid "Copy (reflink/clone) is not supported or invalid" +msgstr "複製 (åƒç…§é€£çµ/é‡è£½) 䏿”¯æ´æˆ–無效" + +#: gio/gfile.c:3126 +msgid "Copy (reflink/clone) is not supported or didn’t work" +msgstr "複製 (åƒç…§é€£çµ/é‡è£½) 䏿”¯æ´æˆ–無法é‹ä½œ" + +#: gio/gfile.c:3190 +msgid "Can’t copy special file" +msgstr "ä¸èƒ½è¤‡è£½ç‰¹æ®Šçš„æª”案" + +#: gio/gfile.c:4003 +msgid "Invalid symlink value given" +msgstr "æä¾›äº†ç„¡æ•ˆçš„符號連çµå€¼" + +#: gio/gfile.c:4013 glib/gfileutils.c:2349 +msgid "Symbolic links not supported" +msgstr "䏿”¯æ´ç¬¦è™Ÿé€£çµ" + +#: gio/gfile.c:4181 +msgid "Trash not supported" +msgstr "䏿”¯æ´åžƒåœ¾æ¡¶" + +#: gio/gfile.c:4293 +#, c-format +msgid "File names cannot contain “%câ€" +msgstr "檔案å稱ä¸èƒ½åŒ…å«ã€Œ%cã€" + +#: gio/gfile.c:6774 gio/gvolume.c:364 +msgid "volume doesn’t implement mount" +msgstr "儲存å€å°šæœªå¯¦ä½œæŽ›è¼‰åŠŸèƒ½" + +#: gio/gfile.c:6888 gio/gfile.c:6936 +msgid "No application is registered as handling this file" +msgstr "沒有應用程å¼è¨»å†Šç‚ºç”¨ä»¥è™•ç†é€™å€‹æª”案" + +#: gio/gfileenumerator.c:212 +msgid "Enumerator is closed" +msgstr "檔案列舉器(enumerator)已關閉" + +#: gio/gfileenumerator.c:219 gio/gfileenumerator.c:278 +#: gio/gfileenumerator.c:377 gio/gfileenumerator.c:476 +msgid "File enumerator has outstanding operation" +msgstr "檔案列舉器(enumerator)有異常æ“作" + +#: gio/gfileenumerator.c:368 gio/gfileenumerator.c:467 +msgid "File enumerator is already closed" +msgstr "檔案列舉器(enumerator)已經關閉" + +#: gio/gfileicon.c:236 +#, c-format +msgid "Can’t handle version %d of GFileIcon encoding" +msgstr "ä¸èƒ½è™•ç†ç‰ˆæœ¬ç‚º %d çš„ GFileIcon 編碼" + +#: gio/gfileicon.c:246 +msgid "Malformed input data for GFileIcon" +msgstr "給 GFileIcon 的輸入資料格å¼ä¸è‰¯" + +#: gio/gfileinputstream.c:149 gio/gfileinputstream.c:394 +#: gio/gfileiostream.c:167 gio/gfileoutputstream.c:164 +#: gio/gfileoutputstream.c:497 +msgid "Stream doesn’t support query_info" +msgstr "串æµä¸æ”¯æ´ query_info" + +#: gio/gfileinputstream.c:325 gio/gfileiostream.c:379 +#: gio/gfileoutputstream.c:371 +msgid "Seek not supported on stream" +msgstr "䏿”¯æ´åœ¨ä¸²æµä¸­æœå°‹" + +#: gio/gfileinputstream.c:369 +msgid "Truncate not allowed on input stream" +msgstr "在輸入串æµä¸­ä¸å…許截短(truncate)" + +#: gio/gfileiostream.c:455 gio/gfileoutputstream.c:447 +msgid "Truncate not supported on stream" +msgstr "在串æµä¸­ä¸æ”¯æ´æˆªçŸ­(truncate)" + +#: gio/ghttpproxy.c:91 gio/gresolver.c:443 gio/gresolver.c:596 +#: glib/gconvert.c:1778 +msgid "Invalid hostname" +msgstr "主機å稱無效" + +#: gio/ghttpproxy.c:143 +msgid "Bad HTTP proxy reply" +msgstr "錯誤的 HTTP 代ç†ä¼ºæœå™¨å›žæ‡‰" + +#: gio/ghttpproxy.c:159 +msgid "HTTP proxy connection not allowed" +msgstr "HTTP 代ç†ä¼ºæœå™¨é€£ç·šä¸å…許" + +#: gio/ghttpproxy.c:164 +msgid "HTTP proxy authentication failed" +msgstr "HTTP 代ç†ä¼ºæœå™¨æ ¸å°å¤±æ•—" + +#: gio/ghttpproxy.c:167 +msgid "HTTP proxy authentication required" +msgstr "HTTP 代ç†ä¼ºæœå™¨éœ€è¦æ ¸å°" + +#: gio/ghttpproxy.c:171 +#, c-format +msgid "HTTP proxy connection failed: %i" +msgstr "HTTP 代ç†ä¼ºæœå™¨é€£ç·šå¤±æ•—:%i" + +#: gio/ghttpproxy.c:269 +msgid "HTTP proxy server closed connection unexpectedly." +msgstr "HTTP 代ç†ä¼ºæœå™¨æœªé æœŸé—œé–‰é€£ç·šã€‚" + +#: gio/gicon.c:298 +#, c-format +msgid "Wrong number of tokens (%d)" +msgstr "è¨˜è™Ÿæ•¸é‡ (%d) 錯誤" + +#: gio/gicon.c:318 +#, c-format +msgid "No type for class name %s" +msgstr "類別å稱 %s 沒有類型" + +#: gio/gicon.c:328 +#, c-format +msgid "Type %s does not implement the GIcon interface" +msgstr "類型 %s 沒有實作 GIcon 介é¢" + +#: gio/gicon.c:339 +#, c-format +msgid "Type %s is not classed" +msgstr "類型 %s 尚未歸類" + +#: gio/gicon.c:353 +#, c-format +msgid "Malformed version number: %s" +msgstr "æ ¼å¼ä¸è‰¯çš„版本號碼:%s" + +#: gio/gicon.c:367 +#, c-format +msgid "Type %s does not implement from_tokens() on the GIcon interface" +msgstr "類型 %s 沒有實作 GIcon 介é¢çš„ from_tokens()" + +#: gio/gicon.c:469 +msgid "Can’t handle the supplied version of the icon encoding" +msgstr "ä¸èƒ½è™•ç†æä¾›çš„åœ–ç¤ºç·¨ç¢¼ç‰ˆæœ¬" + +#: gio/ginetaddressmask.c:182 +msgid "No address specified" +msgstr "尚未指定ä½å€" + +#: gio/ginetaddressmask.c:190 +#, c-format +msgid "Length %u is too long for address" +msgstr "長度 %u å°ä½å€ä¾†èªªå¤ªé•·äº†" + +#: gio/ginetaddressmask.c:223 +msgid "Address has bits set beyond prefix length" +msgstr "ä½å€åœ¨ prefix length 後有ä½å…ƒè¨­å®š" + +#: gio/ginetaddressmask.c:300 +#, c-format +msgid "Could not parse “%s†as IP address mask" +msgstr "無法解æžã€Œ%sã€åšç‚º IP ä½å€é®ç½©" + +#: gio/ginetsocketaddress.c:203 gio/ginetsocketaddress.c:220 +#: gio/gnativesocketaddress.c:109 gio/gunixsocketaddress.c:220 +msgid "Not enough space for socket address" +msgstr "socket ä½å€æ²’有足夠的空間" + +#: gio/ginetsocketaddress.c:235 +msgid "Unsupported socket address" +msgstr "䏿”¯æ´çš„ socket ä½å€" + +#: gio/ginputstream.c:188 +msgid "Input stream doesn’t implement read" +msgstr "輸入串æµå°šæœªå¯¦ä½œè®€å–" + +#. Translators: This is an error you get if there is already an +#. * operation running against this stream when you try to start +#. * one +#. Translators: This is an error you get if there is +#. * already an operation running against this stream when +#. * you try to start one +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 +msgid "Stream has outstanding operation" +msgstr "ä¸²æµæœ‰ç•°å¸¸æ“作" + +#: gio/gio-tool.c:160 +msgid "Copy with file" +msgstr "複製檔案" + +#: gio/gio-tool.c:164 +msgid "Keep with file when moved" +msgstr "ç§»å‹•æ™‚ä¿æŒæª”案" + +#: gio/gio-tool.c:205 +msgid "“version†takes no arguments" +msgstr "「versionã€ä¸éœ€è¦å¼•數" + +#: gio/gio-tool.c:207 gio/gio-tool.c:223 glib/goption.c:869 +msgid "Usage:" +msgstr "用法:" + +#: gio/gio-tool.c:210 +msgid "Print version information and exit." +msgstr "輸出版本資訊並離開。" + +#: gio/gio-tool.c:226 +msgid "Commands:" +msgstr "指令:" + +#: gio/gio-tool.c:229 +msgid "Concatenate files to standard output" +msgstr "將檔案連接並顯示至標準輸出" + +#: gio/gio-tool.c:230 +msgid "Copy one or more files" +msgstr "複製一或多個檔案" + +#: gio/gio-tool.c:231 +msgid "Show information about locations" +msgstr "顯示ä½ç½®çš„相關資訊" + +#: gio/gio-tool.c:232 +msgid "List the contents of locations" +msgstr "列出ä½ç½®çš„內容" + +#: gio/gio-tool.c:233 +msgid "Get or set the handler for a mimetype" +msgstr "å–得或設定 MIME 類型的處ç†ç¨‹å¼" + +#: gio/gio-tool.c:234 +msgid "Create directories" +msgstr "建立目錄" + +#: gio/gio-tool.c:235 +msgid "Monitor files and directories for changes" +msgstr "監控檔案與目錄的變更" + +#: gio/gio-tool.c:236 +msgid "Mount or unmount the locations" +msgstr "掛載或å¸è¼‰ä½ç½®" + +#: gio/gio-tool.c:237 +msgid "Move one or more files" +msgstr "移動一個或多個檔案" + +#: gio/gio-tool.c:238 +msgid "Open files with the default application" +msgstr "以é è¨­çš„æ‡‰ç”¨ç¨‹å¼é–‹å•Ÿæª”案" + +#: gio/gio-tool.c:239 +msgid "Rename a file" +msgstr "釿–°å‘½å檔案" + +#: gio/gio-tool.c:240 +msgid "Delete one or more files" +msgstr "刪除一個或多個檔案" + +#: gio/gio-tool.c:241 +msgid "Read from standard input and save" +msgstr "從標準輸入讀å–並儲存" + +#: gio/gio-tool.c:242 +msgid "Set a file attribute" +msgstr "設定檔案特性" + +#: gio/gio-tool.c:243 +msgid "Move files or directories to the trash" +msgstr "將檔案或目錄移至垃圾桶" + +#: gio/gio-tool.c:244 +msgid "Lists the contents of locations in a tree" +msgstr "以樹狀圖列出ä½ç½®çš„內容" + +#: gio/gio-tool.c:246 +#, c-format +msgid "Use %s to get detailed help.\n" +msgstr "使用 %s 以å–得詳細的求助。\n" + +#: gio/gio-tool-cat.c:87 +msgid "Error writing to stdout" +msgstr "寫入至標準輸出時發生錯誤" + +#. Translators: commandline placeholder +#: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:333 gio/gio-tool-list.c:172 +#: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 +#: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1199 gio/gio-tool-open.c:70 +#: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 +#: gio/gio-tool-trash.c:90 gio/gio-tool-tree.c:239 +msgid "LOCATION" +msgstr "LOCATION" + +#: gio/gio-tool-cat.c:138 +msgid "Concatenate files and print to standard output." +msgstr "將檔案連接並顯示至標準輸出。" + +#: gio/gio-tool-cat.c:140 +msgid "" +"gio cat works just like the traditional cat utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio cat 類似傳統的 cat 工具程å¼ï¼Œåªæ˜¯ä½¿ç”¨ GIO\n" +"ä½ç½®ä¾†å–代本地端檔案:例如您å¯ä»¥ä½¿ç”¨é¡žä¼¼\n" +" smb://server/resource/file.txt åšç‚ºä½ç½®ã€‚" + +#: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:364 gio/gio-tool-mkdir.c:76 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1250 gio/gio-tool-open.c:96 +#: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:145 +msgid "No locations given" +msgstr "未æä¾›ä½ç½®" + +#: gio/gio-tool-copy.c:43 gio/gio-tool-move.c:38 +msgid "No target directory" +msgstr "䏿˜¯ç›®æ¨™ç›®éŒ„" + +#: gio/gio-tool-copy.c:44 gio/gio-tool-move.c:39 +msgid "Show progress" +msgstr "顯示進度" + +#: gio/gio-tool-copy.c:45 gio/gio-tool-move.c:40 +msgid "Prompt before overwrite" +msgstr "åœ¨è¦†è“‹å‰æç¤º" + +#: gio/gio-tool-copy.c:46 +msgid "Preserve all attributes" +msgstr "ä¿ç•™æ‰€æœ‰ç‰¹æ€§" + +#: gio/gio-tool-copy.c:47 gio/gio-tool-move.c:41 gio/gio-tool-save.c:49 +msgid "Backup existing destination files" +msgstr "備份既有的目的檔案" + +#: gio/gio-tool-copy.c:48 +msgid "Never follow symbolic links" +msgstr "æ°¸ä¸è¿½è¹¤ç¬¦è™Ÿé€£çµ" + +#: gio/gio-tool-copy.c:49 +msgid "Use default permissions for the destination" +msgstr "目的地使用é è¨­æ¬Šé™" + +#: gio/gio-tool-copy.c:74 gio/gio-tool-move.c:67 +#, c-format +msgid "Transferred %s out of %s (%s/s)" +msgstr "已傳輸 %s / %s (%s/s)" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 +msgid "SOURCE" +msgstr "SOURCE" + +#. Translators: commandline placeholder +#: gio/gio-tool-copy.c:100 gio/gio-tool-move.c:94 gio/gio-tool-save.c:160 +msgid "DESTINATION" +msgstr "DESTINATION" + +#: gio/gio-tool-copy.c:105 +msgid "Copy one or more files from SOURCE to DESTINATION." +msgstr "將一或多個檔案從 SOURCE 複製到 DESTINATION。" + +#: gio/gio-tool-copy.c:107 +msgid "" +"gio copy is similar to the traditional cp utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location." +msgstr "" +"gio copy 類似傳統的 cp 工具程å¼ï¼Œåªæ˜¯ä½¿ç”¨ GIO\n" +"ä½ç½®ä¾†å–代本地端檔案:例如您å¯ä»¥ä½¿ç”¨é¡žä¼¼\n" +" smb://server/resource/file.txt åšç‚ºä½ç½®ã€‚" + +#: gio/gio-tool-copy.c:149 +#, c-format +msgid "Destination %s is not a directory" +msgstr "目的端 %s 䏿˜¯ä¸€å€‹ç›®éŒ„" + +#: gio/gio-tool-copy.c:196 gio/gio-tool-move.c:186 +#, c-format +msgid "%s: overwrite “%sâ€? " +msgstr "%s:覆寫「%sã€ï¼Ÿ" + +#: gio/gio-tool-info.c:37 +msgid "List writable attributes" +msgstr "列出å¯å¯«ç‰¹æ€§" + +#: gio/gio-tool-info.c:38 +msgid "Get file system info" +msgstr "å–得檔案系統資訊" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "The attributes to get" +msgstr "è¦å–得的特性" + +#: gio/gio-tool-info.c:39 gio/gio-tool-list.c:36 +msgid "ATTRIBUTES" +msgstr "ATTRIBUTES" + +#: gio/gio-tool-info.c:40 gio/gio-tool-list.c:39 gio/gio-tool-set.c:34 +msgid "Don’t follow symbolic links" +msgstr "ä¸è¦è¿½è¹¤ç¬¦è™Ÿé€£çµ" + +#: gio/gio-tool-info.c:78 +msgid "attributes:\n" +msgstr "特性:\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:134 +#, c-format +msgid "display name: %s\n" +msgstr "顯示å稱:%s\n" + +#. Translators: This is a noun and represents and attribute of a file +#: gio/gio-tool-info.c:139 +#, c-format +msgid "edit name: %s\n" +msgstr "編輯å稱:%s\n" + +#: gio/gio-tool-info.c:145 +#, c-format +msgid "name: %s\n" +msgstr "å稱:%s\n" + +#: gio/gio-tool-info.c:152 +#, c-format +msgid "type: %s\n" +msgstr "類型:%s\n" + +#: gio/gio-tool-info.c:158 +msgid "size: " +msgstr "大å°ï¼š" + +#: gio/gio-tool-info.c:163 +msgid "hidden\n" +msgstr "éš±è—\n" + +#: gio/gio-tool-info.c:166 +#, c-format +msgid "uri: %s\n" +msgstr "uri: %s\n" + +#: gio/gio-tool-info.c:172 +#, c-format +msgid "local path: %s\n" +msgstr "本機路徑:%s\n" + +#: gio/gio-tool-info.c:199 +#, c-format +msgid "unix mount: %s%s %s %s %s\n" +msgstr "unix 掛載:%s%s %s %s %s\n" + +#: gio/gio-tool-info.c:279 +msgid "Settable attributes:\n" +msgstr "å¯è¨­å®šç‰¹æ€§ï¼š\n" + +#: gio/gio-tool-info.c:303 +msgid "Writable attribute namespaces:\n" +msgstr "å¯å¯«å…¥ç‰¹æ€§å‘½å空間:\n" + +#: gio/gio-tool-info.c:338 +msgid "Show information about locations." +msgstr "顯示ä½ç½®çš„相關資訊。" + +#: gio/gio-tool-info.c:340 +msgid "" +"gio info is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon, or just by\n" +"namespace, e.g. unix, or by “*â€, which matches all attributes" +msgstr "" +"gio info 類似傳統的 ls 工具程å¼ï¼Œåªæ˜¯ä½¿ç”¨ GIO\n" +"ä½ç½®ä¾†å–代本地端檔案:例如您å¯ä»¥ä½¿ç”¨é¡žä¼¼\n" +" smb://server/resource/file.txt åšç‚ºä½ç½®ã€‚檔案\n" +"特性å¯ä»¥ä½¿ç”¨å®ƒå€‘çš„ GIO å稱來指定,如 standard::icon\n" +"或åªä½¿ç”¨å‘½åç©ºé–“ï¼Œåƒ unix,或「*ã€æ¯”å°æ‰€æœ‰çš„屬性" + +#: gio/gio-tool-list.c:37 gio/gio-tool-tree.c:32 +msgid "Show hidden files" +msgstr "é¡¯ç¤ºéš±è—æª”案" + +#: gio/gio-tool-list.c:38 +msgid "Use a long listing format" +msgstr "使用長å¼è¡¨åˆ—æ ¼å¼" + +#: gio/gio-tool-list.c:40 +msgid "Print display names" +msgstr "列å°é¡¯ç¤ºå稱" + +#: gio/gio-tool-list.c:41 +msgid "Print full URIs" +msgstr "列å°å®Œæ•´ URI" + +#: gio/gio-tool-list.c:177 +msgid "List the contents of the locations." +msgstr "列出ä½ç½®çš„內容。" + +#: gio/gio-tool-list.c:179 +msgid "" +"gio list is similar to the traditional ls utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location. File attributes can\n" +"be specified with their GIO name, e.g. standard::icon" +msgstr "" +"gio list 類似傳統的 ls 工具程å¼ï¼Œåªæ˜¯ä½¿ç”¨ GIO\n" +"ä½ç½®ä¾†å–代本地端檔案:例如您å¯ä»¥ä½¿ç”¨é¡žä¼¼\n" +" smb://server/resource/file.txt åšç‚ºä½ç½®ã€‚檔案\n" +"特性å¯ä»¥ä½¿ç”¨å®ƒå€‘çš„ GIO å稱來指定,如 standard::icon" + +#. Translators: commandline placeholder +#: gio/gio-tool-mime.c:71 +msgid "MIMETYPE" +msgstr "MIMETYPE" + +#: gio/gio-tool-mime.c:71 +msgid "HANDLER" +msgstr "HANDLER" + +#: gio/gio-tool-mime.c:76 +msgid "Get or set the handler for a mimetype." +msgstr "å–得或設定 MIME-類型的處ç†ç¨‹å¼ã€‚" + +#: gio/gio-tool-mime.c:78 +msgid "" +"If no handler is given, lists registered and recommended applications\n" +"for the mimetype. If a handler is given, it is set as the default\n" +"handler for the mimetype." +msgstr "" +"如果沒有指定處ç†ç¨‹å¼ï¼Œåˆ—出該 MIME 類型註冊與建議的應用程å¼ã€‚\n" +"如果有指定處ç†ç¨‹å¼ï¼Œæœƒå°‡å®ƒè¨­å®šç‚ºæ­¤ MIME 類型的é è¨­\n" +"處ç†ç¨‹å¼ã€‚" + +#: gio/gio-tool-mime.c:100 +msgid "Must specify a single mimetype, and maybe a handler" +msgstr "必須指定一個 MIME 類型,å¯èƒ½æ˜¯ä¸€ç¨®è™•ç†ç¨‹å¼" + +#: gio/gio-tool-mime.c:116 +#, c-format +msgid "No default applications for “%sâ€\n" +msgstr "「%sã€æ²’有é è¨­çš„æ‡‰ç”¨ç¨‹å¼\n" + +#: gio/gio-tool-mime.c:122 +#, c-format +msgid "Default application for “%sâ€: %s\n" +msgstr "「%sã€çš„é è¨­æ‡‰ç”¨ç¨‹å¼ï¼š%s\n" + +#: gio/gio-tool-mime.c:127 +msgid "Registered applications:\n" +msgstr "已註冊的應用程å¼ï¼š\n" + +#: gio/gio-tool-mime.c:129 +msgid "No registered applications\n" +msgstr "沒有註冊的應用程å¼\n" + +#: gio/gio-tool-mime.c:140 +msgid "Recommended applications:\n" +msgstr "建議的應用程å¼ï¼š\n" + +#: gio/gio-tool-mime.c:142 +msgid "No recommended applications\n" +msgstr "沒有建議的應用程å¼\n" + +#: gio/gio-tool-mime.c:162 +#, c-format +msgid "Failed to load info for handler “%sâ€" +msgstr "無法載入處ç†ç¨‹å¼ã€Œ%sã€çš„資訊" + +#: gio/gio-tool-mime.c:168 +#, c-format +msgid "Failed to set “%s†as the default handler for “%sâ€: %s\n" +msgstr "無法將「%sã€è¨­å®šç‚ºã€Œ%sã€çš„é è¨­è™•ç†ç¨‹å¼ï¼š%s\n" + +#: gio/gio-tool-mkdir.c:31 +msgid "Create parent directories" +msgstr "建立上層目錄" + +#: gio/gio-tool-mkdir.c:52 +msgid "Create directories." +msgstr "建立目錄。" + +#: gio/gio-tool-mkdir.c:54 +msgid "" +"gio mkdir is similar to the traditional mkdir utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/mydir as location." +msgstr "" +"gio mkdir 類似傳統的 mkdir 工具程å¼ï¼Œåªæ˜¯ä½¿ç”¨ GIO\n" +"ä½ç½®ä¾†å–代本地端檔案:例如您å¯ä»¥ä½¿ç”¨é¡žä¼¼\n" +" smb://server/resource/file.txt åšç‚ºä½ç½®ã€‚" + +#: gio/gio-tool-monitor.c:37 +msgid "Monitor a directory (default: depends on type)" +msgstr "監控目錄 (é è¨­å€¼ï¸°å–決於類型)" + +#: gio/gio-tool-monitor.c:39 +msgid "Monitor a file (default: depends on type)" +msgstr "監控檔案 (é è¨­å€¼ï¸°å–決於類型)" + +#: gio/gio-tool-monitor.c:41 +msgid "Monitor a file directly (notices changes made via hardlinks)" +msgstr "直接監控檔案 (é€éŽç¡¬é€£çµä¾†æ³¨æ„變更)" + +#: gio/gio-tool-monitor.c:43 +msgid "Monitors a file directly, but doesn’t report changes" +msgstr "直接監控檔案,但ä¸å›žå ±è®Šæ›´" + +#: gio/gio-tool-monitor.c:45 +msgid "Report moves and renames as simple deleted/created events" +msgstr "å›žå ±ç§»å‹•èˆ‡é‡æ–°å‘½å為簡單的刪除/建立事件" + +#: gio/gio-tool-monitor.c:47 +msgid "Watch for mount events" +msgstr "監看掛載事件" + +#: gio/gio-tool-monitor.c:208 +msgid "Monitor files or directories for changes." +msgstr "監控檔案或目錄的變更。" + +#: gio/gio-tool-mount.c:63 +msgid "Mount as mountable" +msgstr "æŽ›è¼‰ç‚ºå¯æŽ›è¼‰å½¢å¼" + +#: gio/gio-tool-mount.c:64 +msgid "Mount volume with device file, or other identifier" +msgstr "以è£ç½®æª”案或其他識別碼掛載儲存å€" + +#: gio/gio-tool-mount.c:64 +msgid "ID" +msgstr "ID" + +#: gio/gio-tool-mount.c:65 +msgid "Unmount" +msgstr "å¸è¼‰" + +#: gio/gio-tool-mount.c:66 +msgid "Eject" +msgstr "退出" + +#: gio/gio-tool-mount.c:67 +msgid "Stop drive with device file" +msgstr "以è£ç½®æª”æ¡ˆåœæ­¢è£ç½®" + +#: gio/gio-tool-mount.c:67 +msgid "DEVICE" +msgstr "DEVICE" + +#: gio/gio-tool-mount.c:68 +msgid "Unmount all mounts with the given scheme" +msgstr "以指定的方å¼å¸è¼‰æ‰€æœ‰çš„æŽ›è¼‰" + +#: gio/gio-tool-mount.c:68 +msgid "SCHEME" +msgstr "SCHEME" + +#: gio/gio-tool-mount.c:69 +msgid "Ignore outstanding file operations when unmounting or ejecting" +msgstr "在å¸è¼‰æˆ–退出時忽略優先的檔案æ“作" + +#: gio/gio-tool-mount.c:70 +msgid "Use an anonymous user when authenticating" +msgstr "æ ¸å°æ™‚使用匿å使用者" + +#. Translator: List here is a verb as in 'List all mounts' +#: gio/gio-tool-mount.c:72 +msgid "List" +msgstr "列出" + +#: gio/gio-tool-mount.c:73 +msgid "Monitor events" +msgstr "監視事件" + +#: gio/gio-tool-mount.c:74 +msgid "Show extra information" +msgstr "顯示é¡å¤–的資訊" + +#: gio/gio-tool-mount.c:75 +msgid "The numeric PIM when unlocking a VeraCrypt volume" +msgstr "解鎖 VeraCrypt å„²å­˜å€æ™‚的數字 PIM" + +#: gio/gio-tool-mount.c:75 +msgid "PIM" +msgstr "PIM" + +#: gio/gio-tool-mount.c:76 +msgid "Mount a TCRYPT hidden volume" +msgstr "掛載 TCRYPT éš±è—儲存å€" + +#: gio/gio-tool-mount.c:77 +msgid "Mount a TCRYPT system volume" +msgstr "éš±è— TCRYPT 系統儲存å€" + +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 +msgid "Anonymous access denied" +msgstr "匿åå­˜å–被拒" + +#: gio/gio-tool-mount.c:522 +msgid "No drive for device file" +msgstr "è£ç½®æª”案沒有è£ç½®" + +#: gio/gio-tool-mount.c:1014 +msgid "No volume for given ID" +msgstr "æä¾›çš„ ID 沒有儲存å€" + +#: gio/gio-tool-mount.c:1203 +msgid "Mount or unmount the locations." +msgstr "掛載或å¸è¼‰ä½ç½®ã€‚" + +#: gio/gio-tool-move.c:42 +msgid "Don’t use copy and delete fallback" +msgstr "ä¸è¦ä½¿ç”¨è¤‡è£½èˆ‡åˆªé™¤å›žé¥‹" + +#: gio/gio-tool-move.c:99 +msgid "Move one or more files from SOURCE to DEST." +msgstr "將一或多個檔案從 SOURCE 移動到 DEST。" + +#: gio/gio-tool-move.c:101 +msgid "" +"gio move is similar to the traditional mv utility, but using GIO\n" +"locations instead of local files: for example, you can use something\n" +"like smb://server/resource/file.txt as location" +msgstr "" +"gio move 類似傳統的 mv 工具程å¼ï¼Œåªæ˜¯ä½¿ç”¨ GIO\n" +"ä½ç½®ä¾†å–代本地端檔案:例如您å¯ä»¥ä½¿ç”¨é¡žä¼¼\n" +" smb://server/resource/file.txt åšç‚ºä½ç½®ã€‚" + +#: gio/gio-tool-move.c:143 +#, c-format +msgid "Target %s is not a directory" +msgstr "目標 %s 䏿˜¯ç›®éŒ„" + +#: gio/gio-tool-open.c:75 +msgid "" +"Open files with the default application that\n" +"is registered to handle files of this type." +msgstr "" +"使用註冊為處ç†è©²æª”案類型的\n" +"é è¨­æ‡‰ç”¨ç¨‹å¼ä¾†é–‹å•Ÿæª”案。" + +#: gio/gio-tool-remove.c:31 gio/gio-tool-trash.c:31 +msgid "Ignore nonexistent files, never prompt" +msgstr "忽略ä¸å­˜åœ¨çš„æª”æ¡ˆï¼Œæ°¸ä¸æç¤º" + +#: gio/gio-tool-remove.c:52 +msgid "Delete the given files." +msgstr "刪除指定的檔案。" + +#: gio/gio-tool-rename.c:45 +msgid "NAME" +msgstr "NAME" + +#: gio/gio-tool-rename.c:50 +msgid "Rename a file." +msgstr "釿–°å‘½å檔案。" + +#: gio/gio-tool-rename.c:70 +msgid "Missing argument" +msgstr "缺少引數" + +#: gio/gio-tool-rename.c:76 gio/gio-tool-save.c:190 gio/gio-tool-set.c:137 +msgid "Too many arguments" +msgstr "引數太多" + +#: gio/gio-tool-rename.c:95 +#, c-format +msgid "Rename successful. New uri: %s\n" +msgstr "釿–°å‘½åæˆåŠŸã€‚æ–°çš„ URI:%s\n" + +#: gio/gio-tool-save.c:50 +msgid "Only create if not existing" +msgstr "åªåœ¨ä¸å­˜åœ¨æ™‚建立" + +#: gio/gio-tool-save.c:51 +msgid "Append to end of file" +msgstr "添加到檔案的çµå°¾" + +#: gio/gio-tool-save.c:52 +msgid "When creating, restrict access to the current user" +msgstr "ç•¶å»ºç«‹æ™‚ï¼Œå­˜å–æ¬Šåƒ…陿–¼ç›®å‰çš„使用者" + +#: gio/gio-tool-save.c:53 +msgid "When replacing, replace as if the destination did not exist" +msgstr "在å–代時,å³ä½¿ç›®çš„端ä¸å­˜åœ¨ä¹Ÿå–代" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:55 +msgid "Print new etag at end" +msgstr "在çµå°¾åˆ—出新的 etag" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:57 +msgid "The etag of the file being overwritten" +msgstr "å³å°‡è¤‡è“‹çš„æª”案 etag" + +#: gio/gio-tool-save.c:57 +msgid "ETAG" +msgstr "ETAG" + +#: gio/gio-tool-save.c:113 +msgid "Error reading from standard input" +msgstr "å¾žæ¨™æº–è¼¸å…¥è®€å–æ™‚發生錯誤" + +#. Translators: The "etag" is a token allowing to verify whether a file has been modified +#: gio/gio-tool-save.c:139 +msgid "Etag not available\n" +msgstr "Etag 無法使用\n" + +#: gio/gio-tool-save.c:163 +msgid "Read from standard input and save to DEST." +msgstr "從標準輸入讀å–並儲存到 DEST。" + +#: gio/gio-tool-save.c:183 +msgid "No destination given" +msgstr "沒有指定目的端" + +#: gio/gio-tool-set.c:33 +msgid "Type of the attribute" +msgstr "特性的類型" + +#: gio/gio-tool-set.c:33 +msgid "TYPE" +msgstr "TYPE" + +#: gio/gio-tool-set.c:89 +msgid "ATTRIBUTE" +msgstr "ATTRIBUTE" + +#: gio/gio-tool-set.c:89 +msgid "VALUE" +msgstr "VALUE" + +#: gio/gio-tool-set.c:93 +msgid "Set a file attribute of LOCATION." +msgstr "設定 LOCATION 的檔案特性。" + +#: gio/gio-tool-set.c:113 +msgid "Location not specified" +msgstr "尚未指定ä½ç½®" + +#: gio/gio-tool-set.c:120 +msgid "Attribute not specified" +msgstr "尚未指定特性" + +#: gio/gio-tool-set.c:130 +msgid "Value not specified" +msgstr "尚未指定值" + +#: gio/gio-tool-set.c:180 +#, c-format +msgid "Invalid attribute type “%sâ€" +msgstr "無效的特性類型「%sã€" + +#: gio/gio-tool-trash.c:32 +msgid "Empty the trash" +msgstr "清ç†åžƒåœ¾æ¡¶" + +#: gio/gio-tool-trash.c:95 +msgid "Move files or directories to the trash." +msgstr "將檔案或目錄移至垃圾桶。" + +#: gio/gio-tool-tree.c:33 +msgid "Follow symbolic links, mounts and shortcuts" +msgstr "追蹤符號連çµã€æŽ›è¼‰å’Œæ·å¾‘" + +#: gio/gio-tool-tree.c:244 +msgid "List contents of directories in a tree-like format." +msgstr "以樹狀格å¼åˆ—出目錄的內容。" + +#: gio/glib-compile-resources.c:140 gio/glib-compile-schemas.c:1514 +#, c-format +msgid "Element <%s> not allowed inside <%s>" +msgstr "<%s> 元素ä¸å¯å‡ºç¾åœ¨ <%s> 之內" + +#: gio/glib-compile-resources.c:144 +#, c-format +msgid "Element <%s> not allowed at toplevel" +msgstr "<%s> 元素ä¸å…許在頂端層級" + +#: gio/glib-compile-resources.c:234 +#, c-format +msgid "File %s appears multiple times in the resource" +msgstr "檔案 %s 似乎在這個資æºå‡ºå‡ºç¾å¤šæ¬¡" + +#: gio/glib-compile-resources.c:245 +#, c-format +msgid "Failed to locate “%s†in any source directory" +msgstr "無法在任何來æºç›®éŒ„中定ä½ã€Œ%sã€" + +#: gio/glib-compile-resources.c:256 +#, c-format +msgid "Failed to locate “%s†in current directory" +msgstr "無法在目å‰çš„目錄中定ä½ã€Œ%sã€" + +#: gio/glib-compile-resources.c:290 +#, c-format +msgid "Unknown processing option “%sâ€" +msgstr "䏿˜Žçš„處ç†é¸é …「%sã€" + +#. Translators: the first %s is a gresource XML attribute, +#. * the second %s is an environment variable, and the third +#. * %s is a command line tool +#. +#: gio/glib-compile-resources.c:310 gio/glib-compile-resources.c:367 +#: gio/glib-compile-resources.c:424 +#, c-format +msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" +msgstr "è¦æ±‚ %s é è™•ç†ï¼Œä½†æœªè¨­å®š %s,且 %s ä¸åœ¨ PATH 中" + +#: gio/glib-compile-resources.c:457 +#, c-format +msgid "Error reading file %s: %s" +msgstr "è®€å–æª”案 %s 時發生錯誤:%s" + +#: gio/glib-compile-resources.c:477 +#, c-format +msgid "Error compressing file %s" +msgstr "壓縮檔案 %s 時發生錯誤" + +#: gio/glib-compile-resources.c:541 +#, c-format +msgid "text may not appear inside <%s>" +msgstr "在 <%s> å…§ä¸èƒ½å‡ºç¾æ–‡å­—" + +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2172 +msgid "Show program version and exit" +msgstr "顯示程å¼çš„版本並離開" + +#: gio/glib-compile-resources.c:738 +msgid "Name of the output file" +msgstr "輸出檔案的å稱" + +#: gio/glib-compile-resources.c:739 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "è¦è¼‰å…¥ FILE 中åƒç…§æª”案的來æºç›®éŒ„(é è¨­ï¼šç›®å‰ç›®éŒ„)" + +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2173 +#: gio/glib-compile-schemas.c:2202 +msgid "DIRECTORY" +msgstr "目錄" + +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" +msgstr "以目標檔案å稱的延伸檔å來鏿“‡è¦ç”¢ç”Ÿè¼¸å‡ºçš„æ ¼å¼" + +#: gio/glib-compile-resources.c:741 +msgid "Generate source header" +msgstr "ç”¢ç”Ÿä¾†æºæ¨™é ­" + +#: gio/glib-compile-resources.c:742 +msgid "Generate source code used to link in the resource file into your code" +msgstr "產生用來連çµè³‡æºæª”至程å¼ç¢¼çš„æºå§‹ç¢¼" + +#: gio/glib-compile-resources.c:743 +msgid "Generate dependency list" +msgstr "ç”¢ç”Ÿç›¸ä¾æ€§æ¸…å–®" + +#: gio/glib-compile-resources.c:744 +msgid "Name of the dependency file to generate" +msgstr "è¦ç”¢ç”Ÿä¹‹ä¾è³´æª”案的å稱" + +#: gio/glib-compile-resources.c:745 +msgid "Include phony targets in the generated dependency file" +msgstr "åœ¨ç”¢ç”Ÿçš„ç›¸ä¾æª”案中包å«å‡ç›®æ¨™" + +#: gio/glib-compile-resources.c:746 +msgid "Don’t automatically create and register resource" +msgstr "ä¸è¦è‡ªå‹•建立與註冊資æº" + +#: gio/glib-compile-resources.c:747 +msgid "Don’t export functions; declare them G_GNUC_INTERNAL" +msgstr "ä¸è¦åŒ¯å‡ºå‡½å¼ï¼›å®£å‘Šä»–們為 G_GNUC_INTERNAL" + +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "ä¸è¦å°‡è³‡æºè³‡æ–™åµŒå…¥ C 檔案;å‡è¨­è³‡æ–™å·²æ”¹åœ¨å¤–部連çµ" + +#: gio/glib-compile-resources.c:749 +msgid "C identifier name used for the generated source code" +msgstr "用於產生æºç¢¼çš„ C 識別碼å稱" + +#: gio/glib-compile-resources.c:775 +msgid "" +"Compile a resource specification into a resource file.\n" +"Resource specification files have the extension .gresource.xml,\n" +"and the resource file have the extension called .gresource." +msgstr "" +"將資æºè¦æ ¼ç·¨è­¯é€²è³‡æºæª”。\n" +"資æºè¦æ ¼æª”案的延伸檔å必須為 .gresource.xml,\n" +"è€Œè³‡æºæª”案的延伸檔åå«åš .gresource。" + +#: gio/glib-compile-resources.c:797 +msgid "You should give exactly one file name\n" +msgstr "您應該明確指定一個檔案å稱\n" + +#: gio/glib-compile-schemas.c:92 +#, c-format +msgid "nick must be a minimum of 2 characters" +msgstr "nick (暱稱) è‡³å°‘éœ€è¦ 2 個字元" + +#: gio/glib-compile-schemas.c:103 +#, c-format +msgid "Invalid numeric value" +msgstr "數字值無效" + +#: gio/glib-compile-schemas.c:111 +#, c-format +msgid " already specified" +msgstr " 已經指定" + +#: gio/glib-compile-schemas.c:119 +#, c-format +msgid "value='%s' already specified" +msgstr "value='%s' 已經指定" + +#: gio/glib-compile-schemas.c:133 +#, c-format +msgid "flags values must have at most 1 bit set" +msgstr "旗標的值至多需è¦è¨­å®š 1 個ä½å…ƒ" + +#: gio/glib-compile-schemas.c:158 +#, c-format +msgid "<%s> must contain at least one " +msgstr "<%s> 必須包å«è‡³å°‘一個 " + +#: gio/glib-compile-schemas.c:314 +#, c-format +msgid "<%s> is not contained in the specified range" +msgstr "<%s> 未包å«åœ¨æŒ‡å®šçš„範åœä¸­" + +#: gio/glib-compile-schemas.c:326 +#, c-format +msgid "<%s> is not a valid member of the specified enumerated type" +msgstr "<%s> éžæŒ‡å®šåˆ—舉類型的有效æˆå“¡" + +#: gio/glib-compile-schemas.c:332 +#, c-format +msgid "<%s> contains string not in the specified flags type" +msgstr "<%s> 包å«ä¸åœ¨æŒ‡å®šæ——標類型中的字串" + +#: gio/glib-compile-schemas.c:338 +#, c-format +msgid "<%s> contains a string not in " +msgstr "<%s> 包å«ä¸åœ¨ 中的字串" + +#: gio/glib-compile-schemas.c:372 +msgid " already specified for this key" +msgstr " 早已指定給此éµ" + +#: gio/glib-compile-schemas.c:390 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ä¸å…許用於「%sã€é¡žåž‹çš„éµ" + +#: gio/glib-compile-schemas.c:407 +#, c-format +msgid " specified minimum is greater than maximum" +msgstr " 指定的最å°å€¼æ¯”最大值還大" + +#: gio/glib-compile-schemas.c:432 +#, c-format +msgid "unsupported l10n category: %s" +msgstr "䏿”¯æ´çš„ l10n 分類:%s" + +#: gio/glib-compile-schemas.c:440 +msgid "l10n requested, but no gettext domain given" +msgstr "è¦æ±‚ l10n,但未æä¾› gettext 領域" + +#: gio/glib-compile-schemas.c:452 +msgid "translation context given for value without l10n enabled" +msgstr "æä¾›çµ¦å€¼çš„翻譯情境未啟用 l10n" + +#: gio/glib-compile-schemas.c:474 +#, c-format +msgid "Failed to parse value of type “%sâ€: " +msgstr "無法解æžã€Œ%sã€é¡žåž‹çš„ 值: " + +#: gio/glib-compile-schemas.c:491 +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr " 無法指定給標記為有列舉的類型的éµ" + +#: gio/glib-compile-schemas.c:500 +msgid " already specified for this key" +msgstr " 早已指定給此éµ" + +#: gio/glib-compile-schemas.c:512 +#, c-format +msgid " not allowed for keys of type “%sâ€" +msgstr " ä¸å…許「%sã€é¡žåž‹çš„éµ" + +#: gio/glib-compile-schemas.c:528 +#, c-format +msgid " already given" +msgstr " 早已指定" + +#: gio/glib-compile-schemas.c:543 +#, c-format +msgid " must contain at least one " +msgstr " è‡³å°‘è¦æœ‰è‡³å°‘一個 " + +#: gio/glib-compile-schemas.c:557 +msgid " already specified for this key" +msgstr " 早已指定給此éµ" + +#: gio/glib-compile-schemas.c:561 +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr " åªèƒ½æŒ‡å®šçµ¦æœ‰åˆ—舉的éµï¼Œæˆ–旗標類型,或在 後" + +#: gio/glib-compile-schemas.c:580 +#, c-format +msgid "" +" given when “%s†is already a member of the enumerated " +"type" +msgstr "當「%sã€å·²ç¶“是列舉類型的æˆå“¡æ™‚,æä¾›äº† " + +#: gio/glib-compile-schemas.c:586 +#, c-format +msgid " given when was already given" +msgstr "ç•¶ æ—©å·²æä¾›æ™‚,æä¾›äº† " + +#: gio/glib-compile-schemas.c:594 +#, c-format +msgid " already specified" +msgstr " 已經指定" + +#: gio/glib-compile-schemas.c:604 +#, c-format +msgid "alias target “%s†is not in enumerated type" +msgstr "「%sã€åˆ¥å目標ä¸åœ¨åˆ—舉類型中" + +#: gio/glib-compile-schemas.c:605 +#, c-format +msgid "alias target “%s†is not in " +msgstr "「%sã€åˆ¥å目標ä¸åœ¨ 中" + +#: gio/glib-compile-schemas.c:620 +#, c-format +msgid " must contain at least one " +msgstr " 必須包å«è‡³å°‘一個 " + +#: gio/glib-compile-schemas.c:797 +msgid "Empty names are not permitted" +msgstr "ä¸å…許空白å稱" + +#: gio/glib-compile-schemas.c:807 +#, c-format +msgid "Invalid name “%sâ€: names must begin with a lowercase letter" +msgstr "無效的å稱「%sã€ï¼šå稱必須以å°å¯«å­—æ¯é–‹é ­" + +#: gio/glib-compile-schemas.c:819 +#, c-format +msgid "" +"Invalid name “%sâ€: invalid character “%câ€; only lowercase letters, numbers " +"and hyphen (“-â€) are permitted" +msgstr "無效的å稱「%sã€ï¼šç„¡æ•ˆçš„字元「%cã€ï¼›åªå…許å°å¯«å­—æ¯ã€æ•¸å­—和破折號 ('-')" + +#: gio/glib-compile-schemas.c:828 +#, c-format +msgid "Invalid name “%sâ€: two successive hyphens (“--â€) are not permitted" +msgstr "無效的å稱「%sã€ï¼šä¸å…許兩個破折號 ('--')" + +#: gio/glib-compile-schemas.c:837 +#, c-format +msgid "Invalid name “%sâ€: the last character may not be a hyphen (“-â€)" +msgstr "無效的å稱「%sã€ï¼šæœ€å¾Œä¸€å€‹å­—å…ƒä¸èƒ½æ˜¯ç ´æŠ˜è™Ÿ ('-')" + +#: gio/glib-compile-schemas.c:845 +#, c-format +msgid "Invalid name “%sâ€: maximum length is 1024" +msgstr "無效的å稱「%sã€ï¼šæœ€å¤§é•·åº¦ç‚º 1024" + +#: gio/glib-compile-schemas.c:917 +#, c-format +msgid " already specified" +msgstr " 已經指定了" + +#: gio/glib-compile-schemas.c:943 +msgid "Cannot add keys to a “list-of†schema" +msgstr "ä¸èƒ½å°‡éµåŠ å…¥ã€Œlist-ofã€schema" + +#: gio/glib-compile-schemas.c:954 +#, c-format +msgid " already specified" +msgstr " 已經指定了" + +#: gio/glib-compile-schemas.c:972 +#, c-format +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" é®è”½ æ–¼ ;使用 來" +"修改值" + +#: gio/glib-compile-schemas.c:983 +#, c-format +msgid "" +"Exactly one of “typeâ€, “enum†or “flags†must be specified as an attribute " +"to " +msgstr "必須明確指定「typeã€ã€ã€Œenumã€æˆ–「flagsã€ä¹‹ä¸€åšç‚º 的特性" + +#: gio/glib-compile-schemas.c:1002 +#, c-format +msgid "<%s id='%s'> not (yet) defined." +msgstr "<%s id='%s'> 尚未定義。" + +#: gio/glib-compile-schemas.c:1017 +#, c-format +msgid "Invalid GVariant type string “%sâ€" +msgstr "無效的 GVariant 類型字串「%sã€" + +#: gio/glib-compile-schemas.c:1047 +msgid " given but schema isn’t extending anything" +msgstr "指定了 但 schema 並未延伸任何æ±è¥¿" + +#: gio/glib-compile-schemas.c:1060 +#, c-format +msgid "No to override" +msgstr "沒有 è¦è¦†è“‹" + +#: gio/glib-compile-schemas.c:1068 +#, c-format +msgid " already specified" +msgstr " 已經指定了" + +#: gio/glib-compile-schemas.c:1141 +#, c-format +msgid " already specified" +msgstr " 已經指定了" + +#: gio/glib-compile-schemas.c:1153 +#, c-format +msgid " extends not yet existing schema “%sâ€" +msgstr " 延伸了尚ä¸å­˜åœ¨çš„「%sã€schema" + +#: gio/glib-compile-schemas.c:1169 +#, c-format +msgid " is list of not yet existing schema “%sâ€" +msgstr " 是尚ä¸å­˜åœ¨çš„「%sã€schema 的清單" + +#: gio/glib-compile-schemas.c:1177 +#, c-format +msgid "Cannot be a list of a schema with a path" +msgstr "ä¸èƒ½æˆç‚ºæœ‰è·¯å¾‘ schema 的清單" + +#: gio/glib-compile-schemas.c:1187 +#, c-format +msgid "Cannot extend a schema with a path" +msgstr "ä¸èƒ½å»¶ä¼¸æœ‰è·¯å¾‘çš„ schema" + +#: gio/glib-compile-schemas.c:1197 +#, c-format +msgid "" +" is a list, extending which is not a list" +msgstr " 是清單,å»å»¶ä¼¸äº†ä¸æ˜¯æ¸…單的 " + +#: gio/glib-compile-schemas.c:1207 +#, c-format +msgid "" +" extends but “%s†" +"does not extend “%sâ€" +msgstr "" +" 延伸了 但是 '%s' " +"並未延伸 '%s'" + +#: gio/glib-compile-schemas.c:1224 +#, c-format +msgid "A path, if given, must begin and end with a slash" +msgstr "如果指定了路徑,開頭與çµå°¾éƒ½å¿…須是斜線" + +#: gio/glib-compile-schemas.c:1231 +#, c-format +msgid "The path of a list must end with “:/â€" +msgstr "清單的路徑必須以「:/ã€ç‚ºçµå°¾" + +#: gio/glib-compile-schemas.c:1240 +#, c-format +msgid "" +"Warning: Schema “%s†has path “%sâ€. Paths starting with “/apps/â€, “/" +"desktop/†or “/system/†are deprecated." +msgstr "" +"警告:「%sã€schema 有「%sã€è·¯å¾‘。“/apps/â€ã€â€œ/desktop/†或 “/system/†開頭的路" +"徑已經棄用。" + +#: gio/glib-compile-schemas.c:1270 +#, c-format +msgid "<%s id='%s'> already specified" +msgstr "<%s id='%s'> 已經指定了" + +#: gio/glib-compile-schemas.c:1420 gio/glib-compile-schemas.c:1436 +#, c-format +msgid "Only one <%s> element allowed inside <%s>" +msgstr "åªæœ‰ä¸€å€‹ <%s> 元素å¯ä»¥åœ¨ <%s> 之內" + +#: gio/glib-compile-schemas.c:1518 +#, c-format +msgid "Element <%s> not allowed at the top level" +msgstr "<%s> 元素ä¸å…許在頂端層級" + +#: gio/glib-compile-schemas.c:1536 +msgid "Element is required in " +msgstr " ä¸­éœ€è¦ å…ƒç´ " + +#: gio/glib-compile-schemas.c:1626 +#, c-format +msgid "Text may not appear inside <%s>" +msgstr "在 <%s> å…§ä¸èƒ½å‡ºç¾æ–‡å­—" + +#: gio/glib-compile-schemas.c:1694 +#, c-format +msgid "Warning: undefined reference to " +msgstr "警告:未定義,åƒè€ƒè‡³ çš„åƒç…§" + +#. Translators: Do not translate "--strict". +#: gio/glib-compile-schemas.c:1833 gio/glib-compile-schemas.c:1912 +msgid "--strict was specified; exiting." +msgstr "指定了 --strictï¼›çµæŸã€‚" + +#: gio/glib-compile-schemas.c:1845 +msgid "This entire file has been ignored." +msgstr "這整個檔案都被忽略了。" + +#: gio/glib-compile-schemas.c:1908 +msgid "Ignoring this file." +msgstr "忽略這個檔案。" + +#: gio/glib-compile-schemas.c:1963 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%sâ€; ignoring " +"override for this key." +msgstr "" +"在覆蓋「%3$sã€æª”案的「%2$sã€schema 中沒有指定這個「%1$sã€éµï¼›å¿½ç•¥æ­¤éµçš„覆蓋。" + +#: gio/glib-compile-schemas.c:1971 +#, c-format +msgid "" +"No such key “%s†in schema “%s†as specified in override file “%s†and --" +"strict was specified; exiting." +msgstr "" +"在覆蓋「%3$sã€æª”案的「%2$sã€schema 中沒有指定這個「%1$sã€éµä¸”指定了 --" +"strictï¼›çµæŸã€‚" + +#: gio/glib-compile-schemas.c:1993 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€); ignoring override for this key." +msgstr "" +"無法在「%2$sã€schema(覆蓋「%3$sã€æª”案)æä¾›æ¯å€‹æ¡Œé¢çš„「%1$sã€åœ¨åœ°åŒ–éµè¦†è“‹ï¼›" +"忽略此éµçš„覆蓋。" + +#: gio/glib-compile-schemas.c:2002 +#, c-format +msgid "" +"Cannot provide per-desktop overrides for localized key “%s†in schema " +"“%s†(override file “%sâ€) and --strict was specified; exiting." +msgstr "" +"無法在「%2$sã€schema(覆蓋「%3$sã€æª”案)æä¾›æ¯å€‹æ¡Œé¢çš„「%1$sã€åœ¨åœ°åŒ–éµè¦†è“‹ï¼Œ" +"而且指定了 --strictï¼›çµæŸã€‚" + +#: gio/glib-compile-schemas.c:2026 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. Ignoring override for this key." +msgstr "" +"在覆蓋「%3$sã€æª”案指定的「%2$sã€schema 分æžã€Œ%1$sã€éµæ™‚發生錯誤:%4$s。忽略此" +"éµçš„覆蓋。" + +#: gio/glib-compile-schemas.c:2038 +#, c-format +msgid "" +"Error parsing key “%s†in schema “%s†as specified in override file “%sâ€: " +"%s. --strict was specified; exiting." +msgstr "" +"在覆蓋「%3$sã€æª”案指定的「%2$sã€schema 分æžã€Œ%1$sã€éµæ™‚發生錯誤:%4$s。指定" +"了 --strictï¼›çµæŸã€‚" + +#: gio/glib-compile-schemas.c:2065 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema; ignoring override for this key." +msgstr "" +"在覆蓋「%3$sã€æª”案中覆蓋「%2$sã€schema 的「%1$sã€éµè¶…出了 schema 指定的範åœï¼›" +"忽略此éµçš„覆蓋。" + +#: gio/glib-compile-schemas.c:2075 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is outside the " +"range given in the schema and --strict was specified; exiting." +msgstr "" +"在覆蓋「%3$sã€æª”案中覆蓋「%2$sã€schema 的「%1$sã€éµè¶…出了 schema 指定的範åœï¼Œ" +"且指定了 --strictï¼›çµæŸã€‚" + +#: gio/glib-compile-schemas.c:2101 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices; ignoring override for this key." +msgstr "" +"在覆蓋「%3$sã€æª”案中覆蓋「%2$sã€schema 的「%1$sã€éµä¸åœ¨æœ‰æ•ˆçš„鏿“‡æ¸…單中;忽略" +"æ­¤éµçš„覆蓋。" + +#: gio/glib-compile-schemas.c:2111 +#, c-format +msgid "" +"Override for key “%s†in schema “%s†in override file “%s†is not in the " +"list of valid choices and --strict was specified; exiting." +msgstr "" +"在覆蓋「%3$sã€æª”案中覆蓋「%2$sã€schema 的「%1$sã€éµä¸åœ¨æœ‰æ•ˆçš„鏿“‡æ¸…單中,且指" +"定了 --strictï¼›çµæŸã€‚" + +#: gio/glib-compile-schemas.c:2173 +msgid "Where to store the gschemas.compiled file" +msgstr "è¦å°‡ gschemas.compiled 檔案儲存到哪裡" + +#: gio/glib-compile-schemas.c:2174 +msgid "Abort on any errors in schemas" +msgstr "在 schema 中有任何錯誤å³ä¸­æ­¢" + +#: gio/glib-compile-schemas.c:2175 +msgid "Do not write the gschema.compiled file" +msgstr "ä¸è¦å¯«å…¥ gschemas.compiled 檔案" + +#: gio/glib-compile-schemas.c:2176 +msgid "Do not enforce key name restrictions" +msgstr "ä¸è¦å¼·åˆ¶éµåé™åˆ¶" + +#: gio/glib-compile-schemas.c:2205 +msgid "" +"Compile all GSettings schema files into a schema cache.\n" +"Schema files are required to have the extension .gschema.xml,\n" +"and the cache file is called gschemas.compiled." +msgstr "" +"將所有的 GSettings schema 檔案編譯為 schema å¿«å–。\n" +"Schema 檔案的延伸檔å必須為 .gschema.xml,\n" +"è€Œå¿«å–æª”案å«åš gschemas.compiled。" + +#: gio/glib-compile-schemas.c:2226 +msgid "You should give exactly one directory name" +msgstr "您應該明確指定一個目錄å稱" + +#: gio/glib-compile-schemas.c:2269 +msgid "No schema files found: doing nothing." +msgstr "找ä¸åˆ° schema 檔案:什麼都ä¸åšã€‚" + +#: gio/glib-compile-schemas.c:2271 +msgid "No schema files found: removed existing output file." +msgstr "找ä¸åˆ° schema æª”æ¡ˆï¼šå·²ç¶“ç§»é™¤ç¾æœ‰çš„輸出檔案。" + +#: gio/glocalfile.c:549 gio/win32/gwinhttpfile.c:436 +#, c-format +msgid "Invalid filename %s" +msgstr "無效的檔案å稱 %s" + +#: gio/glocalfile.c:980 +#, c-format +msgid "Error getting filesystem info for %s: %s" +msgstr "å–å¾— %s 的檔案系統資訊時發生錯誤:%s" + +#. Translators: This is an error message when trying to find +#. * the enclosing (user visible) mount of a file, but none +#. * exists. +#. +#: gio/glocalfile.c:1121 +#, c-format +msgid "Containing mount for file %s not found" +msgstr "包å«äº†æ‰¾ä¸åˆ°çš„æŽ›è¼‰é»žæª”案 %s" + +#: gio/glocalfile.c:1144 +msgid "Can’t rename root directory" +msgstr "ä¸èƒ½é‡æ–°å‘½å根目錄" + +#: gio/glocalfile.c:1162 gio/glocalfile.c:1185 +#, c-format +msgid "Error renaming file %s: %s" +msgstr "è®€å–æª”案 %s 時發生錯誤:%s" + +#: gio/glocalfile.c:1169 +msgid "Can’t rename file, filename already exists" +msgstr "ä¸èƒ½é‡æ–°å‘½å檔案,該檔案å稱已存在" + +#: gio/glocalfile.c:1182 gio/glocalfile.c:2324 gio/glocalfile.c:2352 +#: gio/glocalfile.c:2491 gio/glocalfileoutputstream.c:650 +msgid "Invalid filename" +msgstr "無效的檔案å稱" + +#: gio/glocalfile.c:1350 gio/glocalfile.c:1361 +#, c-format +msgid "Error opening file %s: %s" +msgstr "開啟檔案 %s 時發生錯誤:%s" + +#: gio/glocalfile.c:1486 +#, c-format +msgid "Error removing file %s: %s" +msgstr "移除檔案 %s 時發生錯誤:%s" + +#: gio/glocalfile.c:1969 +#, c-format +msgid "Error trashing file %s: %s" +msgstr "移動檔案 %s 至垃圾桶時發生錯誤:%s" + +#: gio/glocalfile.c:2010 +#, c-format +msgid "Unable to create trash dir %s: %s" +msgstr "無法建立垃圾桶目錄 %s:%s" + +#: gio/glocalfile.c:2030 +#, c-format +msgid "Unable to find toplevel directory to trash %s" +msgstr "無法找到垃圾桶 %s 的頂端層級目錄" + +#: gio/glocalfile.c:2038 +#, c-format +msgid "Trashing on system internal mounts is not supported" +msgstr "䏿”¯æ´åœ¨ç³»çµ±å…§éƒ¨æŽ›è¼‰é»žä½¿ç”¨åžƒåœ¾æ¡¶" + +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 +#, c-format +msgid "Unable to find or create trash directory for %s" +msgstr "無法找到或建立 %s 的垃圾桶目錄" + +#: gio/glocalfile.c:2173 +#, c-format +msgid "Unable to create trashing info file for %s: %s" +msgstr "無法建立 %s 垃圾桶資訊檔案:%s" + +#: gio/glocalfile.c:2235 +#, c-format +msgid "Unable to trash file %s across filesystem boundaries" +msgstr "無法將檔案 %s 跨檔案系統邊界移至垃圾桶" + +#: gio/glocalfile.c:2239 gio/glocalfile.c:2295 +#, c-format +msgid "Unable to trash file %s: %s" +msgstr "無法將檔案 %s 移至垃圾桶:%s" + +#: gio/glocalfile.c:2301 +#, c-format +msgid "Unable to trash file %s" +msgstr "無法將檔案 %s 移至垃圾桶" + +#: gio/glocalfile.c:2327 +#, c-format +msgid "Error creating directory %s: %s" +msgstr "建立目錄 %s 時發生錯誤:%s" + +#: gio/glocalfile.c:2356 +#, c-format +msgid "Filesystem does not support symbolic links" +msgstr "æª”æ¡ˆç³»çµ±ä¸æ”¯æ´ç¬¦è™Ÿé€£çµ" + +#: gio/glocalfile.c:2359 +#, c-format +msgid "Error making symbolic link %s: %s" +msgstr "å»ºç«‹ç¬¦è™Ÿé€£çµ %s 時發生錯誤:%s" + +#: gio/glocalfile.c:2402 gio/glocalfile.c:2437 gio/glocalfile.c:2494 +#, c-format +msgid "Error moving file %s: %s" +msgstr "移動檔案 %s 時發生錯誤:%s" + +#: gio/glocalfile.c:2425 +msgid "Can’t move directory over directory" +msgstr "ä¸èƒ½å°‡ç›®éŒ„移動至目錄上" + +#: gio/glocalfile.c:2451 gio/glocalfileoutputstream.c:1039 +#: gio/glocalfileoutputstream.c:1053 gio/glocalfileoutputstream.c:1068 +#: gio/glocalfileoutputstream.c:1085 gio/glocalfileoutputstream.c:1099 +msgid "Backup file creation failed" +msgstr "建立備份檔案失敗" + +#: gio/glocalfile.c:2470 +#, c-format +msgid "Error removing target file: %s" +msgstr "移除目標檔案時發生錯誤:%s" + +#: gio/glocalfile.c:2484 +msgid "Move between mounts not supported" +msgstr "䏿”¯æ´åœ¨æŽ›è¼‰é»žä¹‹é–“移動" + +#: gio/glocalfile.c:2658 +#, c-format +msgid "Could not determine the disk usage of %s: %s" +msgstr "無法決定 %s çš„ç£ç¢Ÿä½¿ç”¨é‡ï¼š%s" + +#: gio/glocalfileinfo.c:767 +msgid "Attribute value must be non-NULL" +msgstr "特性值必須為éž-NULL" + +#: gio/glocalfileinfo.c:774 +msgid "Invalid attribute type (string expected)" +msgstr "無效的特性類型(應為字串值)" + +#: gio/glocalfileinfo.c:781 +msgid "Invalid extended attribute name" +msgstr "無效的延伸特性å稱" + +#: gio/glocalfileinfo.c:821 +#, c-format +msgid "Error setting extended attribute “%sâ€: %s" +msgstr "設定延伸特性「%sã€æ™‚發生錯誤:%s" + +#: gio/glocalfileinfo.c:1666 gio/win32/gwinhttpfile.c:191 +msgid " (invalid encoding)" +msgstr "(無效的編碼)" + +#: gio/glocalfileinfo.c:1825 gio/glocalfileoutputstream.c:915 +#, c-format +msgid "Error when getting information for file “%sâ€: %s" +msgstr "å–得檔案「%sã€è³‡è¨Šæ™‚發生錯誤:%s" + +#: gio/glocalfileinfo.c:2091 +#, c-format +msgid "Error when getting information for file descriptor: %s" +msgstr "å–得檔案æè¿°ç‹€æ…‹è³‡è¨Šæ™‚發生錯誤:%s" + +#: gio/glocalfileinfo.c:2136 +msgid "Invalid attribute type (uint32 expected)" +msgstr "無效的特性類型(應為 uint32 值)" + +#: gio/glocalfileinfo.c:2154 +msgid "Invalid attribute type (uint64 expected)" +msgstr "無效的特性類型(應為 uint64 值)" + +#: gio/glocalfileinfo.c:2173 gio/glocalfileinfo.c:2192 +msgid "Invalid attribute type (byte string expected)" +msgstr "無效的特性類型(應為 byte string 值)" + +#: gio/glocalfileinfo.c:2239 +msgid "Cannot set permissions on symlinks" +msgstr "ä¸èƒ½è¨­å®šç¬¦è™Ÿé€£çµçš„æ¬Šé™" + +#: gio/glocalfileinfo.c:2255 +#, c-format +msgid "Error setting permissions: %s" +msgstr "è¨­å®šæ¬Šé™æ™‚發生錯誤:%s" + +#: gio/glocalfileinfo.c:2306 +#, c-format +msgid "Error setting owner: %s" +msgstr "è¨­å®šæ“æœ‰è€…時發生錯誤:%s" + +#: gio/glocalfileinfo.c:2329 +msgid "symlink must be non-NULL" +msgstr "符號連çµå¿…須為éž-NULL" + +#: gio/glocalfileinfo.c:2339 gio/glocalfileinfo.c:2358 +#: gio/glocalfileinfo.c:2369 +#, c-format +msgid "Error setting symlink: %s" +msgstr "è¨­å®šç¬¦è™Ÿé€£çµæ™‚發生錯誤:%s" + +#: gio/glocalfileinfo.c:2348 +msgid "Error setting symlink: file is not a symlink" +msgstr "è¨­å®šç¬¦è™Ÿé€£çµæ™‚ç™¼ç”ŸéŒ¯èª¤ï¼šæª”æ¡ˆä¸æ˜¯ç¬¦è™Ÿé€£çµ" + +#: gio/glocalfileinfo.c:2420 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld are negative" +msgstr "UNIX 時間戳 %2$lld 的延伸奈秒 %1$d 是負數" + +#: gio/glocalfileinfo.c:2429 +#, c-format +msgid "Extra nanoseconds %d for UNIX timestamp %lld reach 1 second" +msgstr "UNIX 時間戳 %2$lld 的延伸奈秒 %1$d é” 1 ç§’" + +#: gio/glocalfileinfo.c:2439 +#, c-format +msgid "UNIX timestamp %lld does not fit into 64 bits" +msgstr "UNIX 時間戳 %lld ä¸èƒ½å®Œæ•´æ”¾å…¥ 64 ä½å…ƒ" + +#: gio/glocalfileinfo.c:2450 +#, c-format +msgid "UNIX timestamp %lld is outside of the range supported by Windows" +msgstr "UNIX 時間戳 %lld 超出 Windows 所支æ´çš„範åœ" + +#: gio/glocalfileinfo.c:2514 +#, c-format +msgid "File name “%s†cannot be converted to UTF-16" +msgstr "「%sã€æª”å無法轉æ›ç‚º UTF-16" + +#: gio/glocalfileinfo.c:2533 +#, c-format +msgid "File “%s†cannot be opened: Windows Error %lu" +msgstr "無法開啟「%sã€æª”案:Windows 錯誤 %lu" + +#: gio/glocalfileinfo.c:2546 +#, c-format +msgid "Error setting modification or access time for file “%sâ€: %lu" +msgstr "設定「%sã€æª”æ¡ˆçš„ä¿®æ”¹æˆ–å­˜å–æ™‚間時發生錯誤:%lu" + +#: gio/glocalfileinfo.c:2647 +#, c-format +msgid "Error setting modification or access time: %s" +msgstr "è¨­å®šä¿®æ”¹æˆ–å­˜å–æ™‚刻時發生錯誤:%s" + +#: gio/glocalfileinfo.c:2670 +msgid "SELinux context must be non-NULL" +msgstr "SELinux 情境必須為éž-NULL" + +#: gio/glocalfileinfo.c:2685 +#, c-format +msgid "Error setting SELinux context: %s" +msgstr "設定 SELinux 情境時發生錯誤:%s" + +#: gio/glocalfileinfo.c:2692 +msgid "SELinux is not enabled on this system" +msgstr "SELinux 在這個系統上並未啟用" + +#: gio/glocalfileinfo.c:2784 +#, c-format +msgid "Setting attribute %s not supported" +msgstr "䏿”¯æ´è¨­å®šç‰¹æ€§ %s" + +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:795 +#, c-format +msgid "Error reading from file: %s" +msgstr "å¾žæª”æ¡ˆè®€å–æ™‚發生錯誤:%s" + +#: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 +#: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 +#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:1117 +#, c-format +msgid "Error seeking in file: %s" +msgstr "在檔案中æœå°‹æ™‚發生錯誤:%s" + +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:347 +#: gio/glocalfileoutputstream.c:441 +#, c-format +msgid "Error closing file: %s" +msgstr "關閉檔案時發生錯誤:%s" + +#: gio/glocalfilemonitor.c:865 +msgid "Unable to find default local file monitor type" +msgstr "無法找到é è¨­çš„æœ¬åœ°ç«¯æª”案監視器類型" + +#: gio/glocalfileoutputstream.c:214 gio/glocalfileoutputstream.c:292 +#: gio/glocalfileoutputstream.c:328 gio/glocalfileoutputstream.c:816 +#, c-format +msgid "Error writing to file: %s" +msgstr "寫入至檔案時發生錯誤:%s" + +#: gio/glocalfileoutputstream.c:374 +#, c-format +msgid "Error removing old backup link: %s" +msgstr "ç§»é™¤èˆŠå‚™ä»½é€£çµæ™‚發生錯誤:%s" + +#: gio/glocalfileoutputstream.c:388 gio/glocalfileoutputstream.c:401 +#, c-format +msgid "Error creating backup copy: %s" +msgstr "建立備份複本時發生錯誤:%s" + +#: gio/glocalfileoutputstream.c:419 +#, c-format +msgid "Error renaming temporary file: %s" +msgstr "釿–°å‘½å暫存檔案時發生錯誤:%s" + +#: gio/glocalfileoutputstream.c:603 gio/glocalfileoutputstream.c:1168 +#, c-format +msgid "Error truncating file: %s" +msgstr "截短檔案時發生錯誤:%s" + +#: gio/glocalfileoutputstream.c:656 gio/glocalfileoutputstream.c:894 +#: gio/glocalfileoutputstream.c:1149 gio/gsubprocess.c:380 +#, c-format +msgid "Error opening file “%sâ€: %s" +msgstr "開啟檔案「%sã€æ™‚發生錯誤:%s" + +#: gio/glocalfileoutputstream.c:928 +msgid "Target file is a directory" +msgstr "目標檔案是一個目錄" + +#: gio/glocalfileoutputstream.c:933 +msgid "Target file is not a regular file" +msgstr "ç›®æ¨™æª”æ¡ˆä¸æ˜¯æ­£è¦çš„æª”案" + +#: gio/glocalfileoutputstream.c:945 +msgid "The file was externally modified" +msgstr "該檔案已被外部程å¼ä¿®æ”¹éŽ" + +#: gio/glocalfileoutputstream.c:1133 +#, c-format +msgid "Error removing old file: %s" +msgstr "移除舊檔案時發生錯誤:%s" + +#: gio/gmemoryinputstream.c:474 gio/gmemoryoutputstream.c:772 +msgid "Invalid GSeekType supplied" +msgstr "æä¾›äº†ç„¡æ•ˆçš„ GSeek 類型" + +#: gio/gmemoryinputstream.c:484 +msgid "Invalid seek request" +msgstr "無效的æœå°‹è¦æ±‚" + +#: gio/gmemoryinputstream.c:508 +msgid "Cannot truncate GMemoryInputStream" +msgstr "ä¸èƒ½æˆªçŸ­ GMemoryInputStream" + +#: gio/gmemoryoutputstream.c:567 +msgid "Memory output stream not resizable" +msgstr "記憶體輸出串æµä¸èƒ½æ”¹è®Šå¤§å°" + +#: gio/gmemoryoutputstream.c:583 +msgid "Failed to resize memory output stream" +msgstr "改變記憶體輸出串æµçš„大å°å¤±æ•—" + +#: gio/gmemoryoutputstream.c:673 +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "進行寫入所需的記憶體總é¡å¤§æ–¼å¯ç”¨çš„ä½å€ç©ºé–“" + +#: gio/gmemoryoutputstream.c:782 +msgid "Requested seek before the beginning of the stream" +msgstr "在串æµçš„開頭之å‰è¦æ±‚çš„æœç´¢" + +#: gio/gmemoryoutputstream.c:797 +msgid "Requested seek beyond the end of the stream" +msgstr "在串æµçš„é–‹é ­ä¹‹å¾Œè¦æ±‚çš„æœç´¢" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement unmount. +#: gio/gmount.c:399 +msgid "mount doesn’t implement “unmountâ€" +msgstr "掛載點尚未實作「umountã€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement eject. +#: gio/gmount.c:475 +msgid "mount doesn’t implement “ejectâ€" +msgstr "掛載點尚未實作「ejectã€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of unmount or unmount_with_operation. +#: gio/gmount.c:553 +msgid "mount doesn’t implement “unmount†or “unmount_with_operationâ€" +msgstr "掛載點尚未實作「umountã€æˆ–「umount_with_operationã€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gmount.c:638 +msgid "mount doesn’t implement “eject†or “eject_with_operationâ€" +msgstr "掛載點尚未實作「ejectã€æˆ–「eject_with_operationã€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement remount. +#: gio/gmount.c:726 +msgid "mount doesn’t implement “remountâ€" +msgstr "掛載點尚未實作「remountã€" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:808 +msgid "mount doesn’t implement content type guessing" +msgstr "æŽ›è¼‰é»žå°šæœªå¯¦ä½œå…§å®¹é¡žåž‹é æ¸¬" + +#. Translators: This is an error +#. * message for mount objects that +#. * don't implement content type guessing. +#: gio/gmount.c:895 +msgid "mount doesn’t implement synchronous content type guessing" +msgstr "æŽ›è¼‰é»žå°šæœªå¯¦ä½œåŒæ­¥å…§å®¹é¡žåž‹é æ¸¬" + +#: gio/gnetworkaddress.c:415 +#, c-format +msgid "Hostname “%s†contains “[†but not “]â€" +msgstr "主機å稱「%sã€å«æœ‰ã€Œ[ã€ä½†æ²’有「]ã€" + +#: gio/gnetworkmonitorbase.c:219 gio/gnetworkmonitorbase.c:323 +msgid "Network unreachable" +msgstr "無法連接網路" + +#: gio/gnetworkmonitorbase.c:257 gio/gnetworkmonitorbase.c:287 +msgid "Host unreachable" +msgstr "無法連接主機" + +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 +#, c-format +msgid "Could not create network monitor: %s" +msgstr "無法建立網路監控:%s" + +#: gio/gnetworkmonitornetlink.c:120 +msgid "Could not create network monitor: " +msgstr "無法建立網路監控:" + +#: gio/gnetworkmonitornetlink.c:183 +msgid "Could not get network status: " +msgstr "無法å–得網路狀態:" + +#: gio/gnetworkmonitornm.c:348 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager 未執行" + +#: gio/gnetworkmonitornm.c:359 +#, c-format +msgid "NetworkManager version too old" +msgstr "NetworkManager 版本太舊" + +#: gio/goutputstream.c:232 gio/goutputstream.c:775 +msgid "Output stream doesn’t implement write" +msgstr "輸出串æµå°šæœªå¯¦ä½œå¯«å…¥" + +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "傳入 %s çš„å‘é‡ç¸½å’ŒéŽå¤§" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 +msgid "Source stream is already closed" +msgstr "來æºä¸²æµå·²ç¶“關閉" + +#: gio/gresolver.c:386 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:168 +#, c-format +msgid "Error resolving “%sâ€: %s" +msgstr "è§£æžã€Œ%sã€æ™‚發生錯誤:%s" + +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:455 gio/gresolver.c:615 +#, c-format +msgid "%s not implemented" +msgstr "%s 未實作" + +#: gio/gresolver.c:984 gio/gresolver.c:1036 +msgid "Invalid domain" +msgstr "網域無效" + +#: gio/gresource.c:672 gio/gresource.c:931 gio/gresource.c:970 +#: gio/gresource.c:1094 gio/gresource.c:1166 gio/gresource.c:1239 +#: gio/gresource.c:1320 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresourcefile.c:736 +#, c-format +msgid "The resource at “%s†does not exist" +msgstr "「%sã€çš„資æºä¸å­˜åœ¨" + +#: gio/gresource.c:837 +#, c-format +msgid "The resource at “%s†failed to decompress" +msgstr "「%sã€çš„資æºç„¡æ³•解壓縮" + +#: gio/gresourcefile.c:732 +#, c-format +msgid "The resource at “%s†is not a directory" +msgstr "「%sã€çš„資æºä¸æ˜¯ç›®éŒ„" + +#: gio/gresourcefile.c:940 +msgid "Input stream doesn’t implement seek" +msgstr "輸入串æµå°šæœªå¯¦ä½œå°‹æ‰¾" + +#: gio/gresource-tool.c:499 +msgid "List sections containing resources in an elf FILE" +msgstr "列出 elf FILE 中包å«è³‡æºçš„節å€" + +#: gio/gresource-tool.c:505 +msgid "" +"List resources\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources" +msgstr "" +"列出資æº\n" +"如果指定 SECTIONï¼Œåªæœƒåˆ—出這個節å€çš„資æº\n" +"如果指定 PATHï¼Œåªæœƒåˆ—出符åˆçš„資æº" + +#: gio/gresource-tool.c:508 gio/gresource-tool.c:518 +msgid "FILE [PATH]" +msgstr "檔案 [路徑]" + +#: gio/gresource-tool.c:509 gio/gresource-tool.c:519 gio/gresource-tool.c:526 +msgid "SECTION" +msgstr "SECTION" + +#: gio/gresource-tool.c:514 +msgid "" +"List resources with details\n" +"If SECTION is given, only list resources in this section\n" +"If PATH is given, only list matching resources\n" +"Details include the section, size and compression" +msgstr "" +"列出資æºè©³ç´°è³‡æ–™\n" +"如果指定 SECTIONï¼Œåªæœƒåˆ—出這個節å€çš„資æº\n" +"如果指定 PATHï¼Œåªæœƒåˆ—出符åˆçš„資æº\n" +"詳細資料包å«ç¯€å€ã€å¤§å°å’Œå£“縮率" + +#: gio/gresource-tool.c:524 +msgid "Extract a resource file to stdout" +msgstr "è§£å£“ç¸®è³‡æºæª”案到 stdout" + +#: gio/gresource-tool.c:525 +msgid "FILE PATH" +msgstr "檔案路徑" + +#: gio/gresource-tool.c:539 +msgid "" +"Usage:\n" +" gresource [--section SECTION] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" sections List resource sections\n" +" list List resources\n" +" details List resources with details\n" +" extract Extract a resource\n" +"\n" +"Use “gresource help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"用法:\n" +" gresource [--section SECTION] COMMAND [ARGS...]\n" +"\n" +"指令:\n" +" help 顯示這個資訊\n" +" sections 列出資æºç¯€å€\n" +" list 列出資æº\n" +" details 列出資æºè©³ç´°è³‡æ–™\n" +" extract 解壓縮資æº\n" +"\n" +"使用「gresource help COMMANDã€ä»¥å–得詳細的說明文件。\n" +"\n" + +#: gio/gresource-tool.c:553 +#, c-format +msgid "" +"Usage:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"用法:\n" +" gresource %s%s%s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gresource-tool.c:560 +msgid " SECTION An (optional) elf section name\n" +msgstr " SECTION 一個 (鏿“‡æ€§çš„) elf 節å€å稱\n" + +#: gio/gresource-tool.c:564 gio/gsettings-tool.c:701 +msgid " COMMAND The (optional) command to explain\n" +msgstr " COMMAND è¦è§£é‡‹çš„ï¼ˆé¸æ“‡æ€§ï¼‰æŒ‡ä»¤\n" + +#: gio/gresource-tool.c:570 +msgid " FILE An elf file (a binary or a shared library)\n" +msgstr " FILE 一個 elf 檔案 (二元檔或共享程å¼åº«)\n" + +#: gio/gresource-tool.c:573 +msgid "" +" FILE An elf file (a binary or a shared library)\n" +" or a compiled resource file\n" +msgstr "" +" FILE 一個 elf 檔案 (二元檔或共享程å¼åº«)\n" +" 或編譯éŽçš„è³‡æºæª”案\n" + +#: gio/gresource-tool.c:577 +msgid "[PATH]" +msgstr "[路徑]" + +#: gio/gresource-tool.c:579 +msgid " PATH An (optional) resource path (may be partial)\n" +msgstr " PATH 一個 (鏿“‡æ€§çš„) 資æºè·¯å¾‘ (å¯èƒ½ç‚ºéƒ¨åˆ†)\n" + +#: gio/gresource-tool.c:580 +msgid "PATH" +msgstr "路徑" + +#: gio/gresource-tool.c:582 +msgid " PATH A resource path\n" +msgstr " PATH 資æºè·¯å¾‘\n" + +#: gio/gsettings-tool.c:49 gio/gsettings-tool.c:70 gio/gsettings-tool.c:906 +#, c-format +msgid "No such schema “%sâ€\n" +msgstr "沒有這個「%sã€schema \n" + +#: gio/gsettings-tool.c:55 +#, c-format +msgid "Schema “%s†is not relocatable (path must not be specified)\n" +msgstr "「%sã€schema ä¸å¯é‡æ–°é…ç½®ä½ç½® (路徑ä¸èƒ½æŒ‡å®š)\n" + +#: gio/gsettings-tool.c:76 +#, c-format +msgid "Schema “%s†is relocatable (path must be specified)\n" +msgstr "「%sã€schema å¯é‡æ–°é…ç½®ä½ç½® (路徑必須指定)\n" + +#: gio/gsettings-tool.c:90 +msgid "Empty path given.\n" +msgstr "指定了空白的路徑。\n" + +#: gio/gsettings-tool.c:96 +msgid "Path must begin with a slash (/)\n" +msgstr "路徑必須以斜線 (/) é–‹é ­\n" + +#: gio/gsettings-tool.c:102 +msgid "Path must end with a slash (/)\n" +msgstr "路徑必須以斜線 (/) çµå°¾\n" + +#: gio/gsettings-tool.c:108 +msgid "Path must not contain two adjacent slashes (//)\n" +msgstr "路徑ä¸èƒ½åŒ…å«å…©å€‹ç›¸é„°çš„æ–œç·š (//)\n" + +#: gio/gsettings-tool.c:536 +msgid "The provided value is outside of the valid range\n" +msgstr "æä¾›çš„值超出了有效的範åœ\n" + +#: gio/gsettings-tool.c:543 +msgid "The key is not writable\n" +msgstr "這個éµç„¡æ³•寫入\n" + +#: gio/gsettings-tool.c:579 +msgid "List the installed (non-relocatable) schemas" +msgstr "列出已安è£çš„(éž-å¯é‡æ–°é…置)schema" + +#: gio/gsettings-tool.c:585 +msgid "List the installed relocatable schemas" +msgstr "列出已安è£çš„å¯é‡æ–°é…ç½® schema" + +#: gio/gsettings-tool.c:591 +msgid "List the keys in SCHEMA" +msgstr "列出 SCHEMA 中的éµ" + +#: gio/gsettings-tool.c:592 gio/gsettings-tool.c:598 gio/gsettings-tool.c:641 +msgid "SCHEMA[:PATH]" +msgstr "SCHEMA[:PATH]" + +#: gio/gsettings-tool.c:597 +msgid "List the children of SCHEMA" +msgstr "列出 SCHEMA çš„å­é …" + +#: gio/gsettings-tool.c:603 +msgid "" +"List keys and values, recursively\n" +"If no SCHEMA is given, list all keys\n" +msgstr "" +"éžè¿´çš„列出éµèˆ‡å€¼\n" +"如果沒有指定 SCHEMA,列出所有éµ\n" + +#: gio/gsettings-tool.c:605 +msgid "[SCHEMA[:PATH]]" +msgstr "[SCHEMA[:PATH]]" + +#: gio/gsettings-tool.c:610 +msgid "Get the value of KEY" +msgstr "å–å¾— KEY 的值" + +#: gio/gsettings-tool.c:611 gio/gsettings-tool.c:617 gio/gsettings-tool.c:623 +#: gio/gsettings-tool.c:635 gio/gsettings-tool.c:647 +msgid "SCHEMA[:PATH] KEY" +msgstr "SCHEMA[:PATH] KEY" + +#: gio/gsettings-tool.c:616 +msgid "Query the range of valid values for KEY" +msgstr "查詢 KEY 有效值的範åœ" + +#: gio/gsettings-tool.c:622 +msgid "Query the description for KEY" +msgstr "查詢 KEY 有效值的範åœ" + +#: gio/gsettings-tool.c:628 +msgid "Set the value of KEY to VALUE" +msgstr "å°‡ KEY 的值設定為 VALUE" + +#: gio/gsettings-tool.c:629 +msgid "SCHEMA[:PATH] KEY VALUE" +msgstr "SCHEMA[:PATH] KEY VALUE" + +#: gio/gsettings-tool.c:634 +msgid "Reset KEY to its default value" +msgstr "å°‡ KEY 設定為é è¨­å€¼" + +#: gio/gsettings-tool.c:640 +msgid "Reset all keys in SCHEMA to their defaults" +msgstr "å°‡ SCHEMA 的所有éµé‡è¨­ç‚ºé è¨­å€¼" + +#: gio/gsettings-tool.c:646 +msgid "Check if KEY is writable" +msgstr "檢查 KEY 是å¦å¯å¯«å…¥" + +#: gio/gsettings-tool.c:652 +msgid "" +"Monitor KEY for changes.\n" +"If no KEY is specified, monitor all keys in SCHEMA.\n" +"Use ^C to stop monitoring.\n" +msgstr "" +"監控 KEY 的變更。\n" +"如果沒有指定 KEY,會監控 SCHEMA 的所有éµã€‚\n" +"使用 ^C å¯åœæ­¢ç›£æŽ§ã€‚\n" + +#: gio/gsettings-tool.c:655 +msgid "SCHEMA[:PATH] [KEY]" +msgstr "SCHEMA[:PATH] [KEY]" + +#: gio/gsettings-tool.c:667 +msgid "" +"Usage:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n" +"\n" +"Commands:\n" +" help Show this information\n" +" list-schemas List installed schemas\n" +" list-relocatable-schemas List relocatable schemas\n" +" list-keys List keys in a schema\n" +" list-children List children of a schema\n" +" list-recursively List keys and values, recursively\n" +" range Queries the range of a key\n" +" describe Queries the description of a key\n" +" get Get the value of a key\n" +" set Set the value of a key\n" +" reset Reset the value of a key\n" +" reset-recursively Reset all values in a given schema\n" +" writable Check if a key is writable\n" +" monitor Watch for changes\n" +"\n" +"Use “gsettings help COMMAND†to get detailed help.\n" +"\n" +msgstr "" +"用法:\n" +" gsettings --version\n" +" gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n" +"\n" +"指令:\n" +" help 顯示這個資訊\n" +" list-schemas 列出已安è£çš„ schema\n" +" list-relocatable-schemas 列出å¯é‡æ–°é…置的 schema\n" +" list-keys 列出 schema 中的éµ\n" +" list-children 列出 schema çš„å­é …\n" +" list-recursively éžè¿´åˆ—出éµå’Œå€¼\n" +" range 查詢éµçš„範åœ\n" +" get å–å¾—éµçš„值\n" +" set 設定éµçš„值\n" +" reset é‡è¨­éµçš„值\n" +" reset-recursively é‡è¨­æŒ‡å®š schema 的所有值\n" +" writable æª¢æŸ¥éµæ˜¯å¦å¯å¯«å…¥\n" +" monitor 監看變更\n" +"\n" +"使用「gsettings help COMMANDã€å–得詳細的說明。\n" +"\n" + +#: gio/gsettings-tool.c:691 +#, c-format +msgid "" +"Usage:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" +msgstr "" +"用法:\n" +" gsettings [--schemadir SCHEMADIR] %s %s\n" +"\n" +"%s\n" +"\n" + +#: gio/gsettings-tool.c:697 +msgid " SCHEMADIR A directory to search for additional schemas\n" +msgstr " SCHEMADIR æœå°‹é¡å¤– schema 的目錄\n" + +#: gio/gsettings-tool.c:705 +msgid "" +" SCHEMA The name of the schema\n" +" PATH The path, for relocatable schemas\n" +msgstr "" +" SCHEMA 這個 schema çš„å稱\n" +" PATH 路徑,用於å¯é‡æ–°é…置的 schema\n" + +#: gio/gsettings-tool.c:710 +msgid " KEY The (optional) key within the schema\n" +msgstr " KEY schema ä¸­çš„ï¼ˆé¸æ“‡æ€§çš„)éµ\n" + +#: gio/gsettings-tool.c:714 +msgid " KEY The key within the schema\n" +msgstr " KEY schema 中的éµ\n" + +#: gio/gsettings-tool.c:718 +msgid " VALUE The value to set\n" +msgstr " VALUE è¦è¨­å®šçš„值\n" + +#: gio/gsettings-tool.c:773 +#, c-format +msgid "Could not load schemas from %s: %s\n" +msgstr "無法載入 %s çš„ schema:%s\n" + +#: gio/gsettings-tool.c:785 +msgid "No schemas installed\n" +msgstr "å°šæœªå®‰è£ schema\n" + +#: gio/gsettings-tool.c:864 +msgid "Empty schema name given\n" +msgstr "指定了空的 schema å稱\n" + +#: gio/gsettings-tool.c:919 +#, c-format +msgid "No such key “%sâ€\n" +msgstr "沒有「%sã€éµ\n" + +#: gio/gsocket.c:413 +msgid "Invalid socket, not initialized" +msgstr "無效的 socket,尚未åˆå§‹åŒ–" + +#: gio/gsocket.c:420 +#, c-format +msgid "Invalid socket, initialization failed due to: %s" +msgstr "無效的 socket,åˆå§‹åŒ–失敗原因為:%s" + +#: gio/gsocket.c:428 +msgid "Socket is already closed" +msgstr "Socket 已經關閉" + +#: gio/gsocket.c:443 gio/gsocket.c:3180 gio/gsocket.c:4403 gio/gsocket.c:4461 +msgid "Socket I/O timed out" +msgstr "Socket I/O 逾時" + +#: gio/gsocket.c:578 +#, c-format +msgid "creating GSocket from fd: %s" +msgstr "正在從 fd 建立 GSocket:%s" + +#: gio/gsocket.c:607 gio/gsocket.c:661 gio/gsocket.c:668 +#, c-format +msgid "Unable to create socket: %s" +msgstr "無法建立 socket:%s" + +#: gio/gsocket.c:661 +msgid "Unknown family was specified" +msgstr "æŒ‡å®šäº†ä¸æ˜Žçš„å­—æ—" + +#: gio/gsocket.c:668 +msgid "Unknown protocol was specified" +msgstr "æŒ‡å®šäº†ä¸æ˜Žçš„通訊å”定" + +#: gio/gsocket.c:1159 +#, c-format +msgid "Cannot use datagram operations on a non-datagram socket." +msgstr "ä¸èƒ½åœ¨éžè³‡æ–™é›»å ± socket 上使用資料電報æ“作。" + +#: gio/gsocket.c:1176 +#, c-format +msgid "Cannot use datagram operations on a socket with a timeout set." +msgstr "ä¸èƒ½åœ¨æœ‰é€¾æ™‚設定 socket 上使用資料電報æ“作。" + +#: gio/gsocket.c:1983 +#, c-format +msgid "could not get local address: %s" +msgstr "無法å–得本地端ä½å€ï¼š%s" + +#: gio/gsocket.c:2029 +#, c-format +msgid "could not get remote address: %s" +msgstr "無法å–å¾—é ç«¯ä½å€ï¼š%s" + +#: gio/gsocket.c:2095 +#, c-format +msgid "could not listen: %s" +msgstr "無法è½å–:%s" + +#: gio/gsocket.c:2199 +#, c-format +msgid "Error binding to address %s: %s" +msgstr "ç¶å®šè‡³ %s ä½å€æ™‚發生錯誤:%s" + +#: gio/gsocket.c:2375 gio/gsocket.c:2412 gio/gsocket.c:2522 gio/gsocket.c:2547 +#: gio/gsocket.c:2610 gio/gsocket.c:2668 gio/gsocket.c:2686 +#, c-format +msgid "Error joining multicast group: %s" +msgstr "加入多點廣播群組時發生錯誤:%s" + +#: gio/gsocket.c:2376 gio/gsocket.c:2413 gio/gsocket.c:2523 gio/gsocket.c:2548 +#: gio/gsocket.c:2611 gio/gsocket.c:2669 gio/gsocket.c:2687 +#, c-format +msgid "Error leaving multicast group: %s" +msgstr "離開多點廣播群組時發生錯誤:%s" + +#: gio/gsocket.c:2377 +msgid "No support for source-specific multicast" +msgstr "䏿”¯æ´æŒ‡å®šä¾†æºçš„多點廣播" + +#: gio/gsocket.c:2524 +msgid "Unsupported socket family" +msgstr "䏿”¯æ´çš„ socket å®¶æ—" + +#: gio/gsocket.c:2549 +msgid "source-specific not an IPv4 address" +msgstr "指定來æºä¸æ˜¯ IPv4 ä½å€" + +#: gio/gsocket.c:2573 +#, c-format +msgid "Interface name too long" +msgstr "介é¢å稱éŽé•·" + +#: gio/gsocket.c:2586 gio/gsocket.c:2636 +#, c-format +msgid "Interface not found: %s" +msgstr "找ä¸åˆ°ä»‹é¢ï¼š%s" + +#: gio/gsocket.c:2612 +msgid "No support for IPv4 source-specific multicast" +msgstr "䏿”¯æ´ IPv4 指定來æºçš„多點廣播" + +#: gio/gsocket.c:2670 +msgid "No support for IPv6 source-specific multicast" +msgstr "䏿”¯æ´ IPv6 指定來æºçš„多點廣播" + +#: gio/gsocket.c:2879 +#, c-format +msgid "Error accepting connection: %s" +msgstr "接å—連線時發生錯誤:%s" + +#: gio/gsocket.c:3005 +msgid "Connection in progress" +msgstr "連線進行中" + +#: gio/gsocket.c:3056 +msgid "Unable to get pending error: " +msgstr "無法å–得未處ç†çš„錯誤:" + +#: gio/gsocket.c:3245 +#, c-format +msgid "Error receiving data: %s" +msgstr "接收資料時發生錯誤:%s" + +#: gio/gsocket.c:3442 +#, c-format +msgid "Error sending data: %s" +msgstr "傳é€è³‡æ–™æ™‚發生錯誤:%s" + +#: gio/gsocket.c:3629 +#, c-format +msgid "Unable to shutdown socket: %s" +msgstr "無法關閉 socket:%s" + +#: gio/gsocket.c:3710 +#, c-format +msgid "Error closing socket: %s" +msgstr "關閉 socket 時發生錯誤:%s" + +#: gio/gsocket.c:4396 +#, c-format +msgid "Waiting for socket condition: %s" +msgstr "等候 socket 情æ³ï¼š%s" + +#: gio/gsocket.c:4774 gio/gsocket.c:4776 gio/gsocket.c:4923 gio/gsocket.c:5008 +#: gio/gsocket.c:5186 gio/gsocket.c:5226 gio/gsocket.c:5228 +#, c-format +msgid "Error sending message: %s" +msgstr "傳é€è¨Šæ¯æ™‚發生錯誤:%s" + +#: gio/gsocket.c:4950 +msgid "GSocketControlMessage not supported on Windows" +msgstr "è¦–çª—ä¸æ”¯æ´ GSocketControlMessage" + +#: gio/gsocket.c:5419 gio/gsocket.c:5492 gio/gsocket.c:5718 +#, c-format +msgid "Error receiving message: %s" +msgstr "å–回郵件發生錯誤:%s" + +#: gio/gsocket.c:5990 gio/gsocket.c:6038 +#, c-format +msgid "Unable to read socket credentials: %s" +msgstr "ç„¡æ³•è®€å– socket 機密:%s" + +#: gio/gsocket.c:6047 +msgid "g_socket_get_credentials not implemented for this OS" +msgstr "g_socket_get_credentials 沒有在這個 OS 上實作" + +#: gio/gsocketclient.c:182 +#, c-format +msgid "Could not connect to proxy server %s: " +msgstr "無法連線到代ç†ä¼ºæœå™¨ %s:" + +#: gio/gsocketclient.c:196 +#, c-format +msgid "Could not connect to %s: " +msgstr "無法連接到 %s:" + +#: gio/gsocketclient.c:198 +msgid "Could not connect: " +msgstr "無法連接:" + +#: gio/gsocketclient.c:1037 gio/gsocketclient.c:1866 +msgid "Unknown error on connect" +msgstr "é€£ç·šæ™‚æœ‰ä¸æ˜Žçš„錯誤" + +#: gio/gsocketclient.c:1091 gio/gsocketclient.c:1668 +msgid "Proxying over a non-TCP connection is not supported." +msgstr "䏿”¯æ´å˜—試é€éŽéž-TCP 連線使用代ç†ä¼ºæœå™¨ã€‚" + +#: gio/gsocketclient.c:1120 gio/gsocketclient.c:1698 +#, c-format +msgid "Proxy protocol “%s†is not supported." +msgstr "指定的通訊å”定「%sã€ä¸è¢«æ”¯æ´ã€‚" + +#: gio/gsocketlistener.c:230 +msgid "Listener is already closed" +msgstr "è½å–程å¼å·²ç¶“關閉" + +#: gio/gsocketlistener.c:276 +msgid "Added socket is closed" +msgstr "加入的 socket 已經關閉" + +#: gio/gsocks4aproxy.c:118 +#, c-format +msgid "SOCKSv4 does not support IPv6 address “%sâ€" +msgstr "SOCKSv4 䏿”¯æ´ IPv6 ä½å€ã€Œ%sã€" + +#: gio/gsocks4aproxy.c:136 +msgid "Username is too long for SOCKSv4 protocol" +msgstr "使用者åç¨±å° SOCKSv4 通訊å”定" + +#: gio/gsocks4aproxy.c:153 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv4 protocol" +msgstr "主機å稱「%sã€å° SOCKSv4 通訊å”定來說太長了" + +#: gio/gsocks4aproxy.c:179 +msgid "The server is not a SOCKSv4 proxy server." +msgstr "伺æœå™¨ä¸æ˜¯ SOCKSv4 代ç†ä¼ºæœå™¨ã€‚" + +#: gio/gsocks4aproxy.c:186 +msgid "Connection through SOCKSv4 server was rejected" +msgstr "é€éŽ SOCKSv4 伺æœå™¨é€£ç·šè¢«æ‹’絕" + +#: gio/gsocks5proxy.c:153 gio/gsocks5proxy.c:338 gio/gsocks5proxy.c:348 +msgid "The server is not a SOCKSv5 proxy server." +msgstr "伺æœå™¨ä¸æ˜¯ SOCKSv5 代ç†ä¼ºæœå™¨ã€‚" + +#: gio/gsocks5proxy.c:167 gio/gsocks5proxy.c:184 +msgid "The SOCKSv5 proxy requires authentication." +msgstr "SOCKv5 代ç†ä¼ºæœå™¨è¦æ±‚æ ¸å°ã€‚" + +#: gio/gsocks5proxy.c:191 +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." +msgstr "SOCKSv5 代ç†éœ€è¦çš„æ ¸å°æ–¹å¼å°šæœªè¢« GLib 支æ´ã€‚" + +#: gio/gsocks5proxy.c:220 +msgid "Username or password is too long for SOCKSv5 protocol." +msgstr "使用者åç¨±æˆ–å¯†ç¢¼å° SOCKSv5 通訊å”定來說太長了。" + +#: gio/gsocks5proxy.c:250 +msgid "SOCKSv5 authentication failed due to wrong username or password." +msgstr "SOCKSv5 æ ¸å°ç”±æ–¼éŒ¯èª¤çš„使用者å稱或密碼失敗了。" + +#: gio/gsocks5proxy.c:300 +#, c-format +msgid "Hostname “%s†is too long for SOCKSv5 protocol" +msgstr "主機å稱「%sã€å° SOCKSv5 通訊å”定來說太長了" + +#: gio/gsocks5proxy.c:362 +msgid "The SOCKSv5 proxy server uses unknown address type." +msgstr "SOCKSv5 代ç†ä¼ºæœå™¨ä½¿ç”¨äº†ä¸æ˜Žçš„ä½å€é¡žåž‹ã€‚" + +#: gio/gsocks5proxy.c:369 +msgid "Internal SOCKSv5 proxy server error." +msgstr "內部的 SOCKSv5 代ç†ä¼ºæœå™¨éŒ¯èª¤ã€‚" + +#: gio/gsocks5proxy.c:375 +msgid "SOCKSv5 connection not allowed by ruleset." +msgstr "SOCKSv5 連線ä¸è¢«è¦å‰‡çµ„å…許。" + +#: gio/gsocks5proxy.c:382 +msgid "Host unreachable through SOCKSv5 server." +msgstr "主機無法é€éŽ SOCKSv5 代ç†ä¼ºæœå™¨æŠµé”。" + +#: gio/gsocks5proxy.c:388 +msgid "Network unreachable through SOCKSv5 proxy." +msgstr "網路無法é€éŽ SOCKSv5 代ç†ä¼ºæœå™¨æŠµé”。" + +#: gio/gsocks5proxy.c:394 +msgid "Connection refused through SOCKSv5 proxy." +msgstr "é€éŽ SOCKSv5 代ç†ä¼ºæœå™¨é€£ç·šè¢«æ‹’絕。" + +#: gio/gsocks5proxy.c:400 +msgid "SOCKSv5 proxy does not support “connect†command." +msgstr "SOCKSv5 代ç†ä¼ºæœå™¨ä¸æ”¯æ´ã€Œconnectã€æŒ‡ä»¤ã€‚" + +#: gio/gsocks5proxy.c:406 +msgid "SOCKSv5 proxy does not support provided address type." +msgstr "SOCKSv5 代ç†ä¼ºæœå™¨ä¸æ”¯æ´æä¾›çš„ä½å€é¡žåž‹ã€‚" + +#: gio/gsocks5proxy.c:412 +msgid "Unknown SOCKSv5 proxy error." +msgstr "䏿˜Žçš„ SOCKSv5 代ç†ä¼ºæœå™¨éŒ¯èª¤ã€‚" + +#: gio/gthemedicon.c:595 +#, c-format +msgid "Can’t handle version %d of GThemedIcon encoding" +msgstr "ä¸èƒ½è™•ç†ç‰ˆæœ¬ç‚º %d çš„ GThemedIcon 編碼" + +#: gio/gthreadedresolver.c:152 +msgid "No valid addresses were found" +msgstr "找ä¸åˆ°æœ‰æ•ˆçš„ä½å€" + +#: gio/gthreadedresolver.c:337 +#, c-format +msgid "Error reverse-resolving “%sâ€: %s" +msgstr "åå‘è§£æžã€Œ%sã€æ™‚發生錯誤:%s" + +#: gio/gthreadedresolver.c:676 gio/gthreadedresolver.c:755 +#: gio/gthreadedresolver.c:853 gio/gthreadedresolver.c:903 +#, c-format +msgid "No DNS record of the requested type for “%sâ€" +msgstr "「%sã€çš„è¦æ±‚類型沒有 DNS 紀錄" + +#: gio/gthreadedresolver.c:681 gio/gthreadedresolver.c:858 +#, c-format +msgid "Temporarily unable to resolve “%sâ€" +msgstr "暫時無法解æžã€Œ%sã€" + +#: gio/gthreadedresolver.c:686 gio/gthreadedresolver.c:863 +#: gio/gthreadedresolver.c:973 +#, c-format +msgid "Error resolving “%sâ€" +msgstr "è§£æžã€Œ%sã€æ™‚發生錯誤" + +#: gio/gtlscertificate.c:243 +msgid "No PEM-encoded private key found" +msgstr "找ä¸åˆ° PEM 編碼的ç§é‘°" + +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "ä¸èƒ½è§£éŽ– PEM 編碼的ç§é‘°" + +#: gio/gtlscertificate.c:264 +msgid "Could not parse PEM-encoded private key" +msgstr "ç„¡æ³•è§£æž PEM 編碼的ç§é‘°" + +#: gio/gtlscertificate.c:291 +msgid "No PEM-encoded certificate found" +msgstr "æ‰¾åˆ°éž PEM 編碼的憑證" + +#: gio/gtlscertificate.c:300 +msgid "Could not parse PEM-encoded certificate" +msgstr "ç„¡æ³•è§£æž PEM 編碼的憑證" + +#: gio/gtlspassword.c:111 +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "這是在您的存å–è¢«éŽ–å®šä¹‹å‰æœ€å¾Œè¼¸å…¥å¯†ç¢¼çš„æ©Ÿæœƒã€‚" + +#. Translators: This is not the 'This is the last chance' string. It is +#. * displayed when more than one attempt is allowed. +#: gio/gtlspassword.c:115 +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"æ‚¨å·²ç¶“è¼¸å…¥å¤šå…¥ä¸æ­£ç¢ºçš„å¯†ç¢¼ï¼Œå¦‚æžœæŽ¥ä¸‹ä¾†é‚„æ˜¯è¼¸å…¥éŒ¯èª¤å°‡æœƒéŽ–å®šæ‚¨çš„å­˜å–æ¬Šé™ã€‚" + +#: gio/gtlspassword.c:117 +msgid "The password entered is incorrect." +msgstr "è¼¸å…¥çš„å¯†ç¢¼æ˜¯ä¸æ­£ç¢ºçš„。" + +#: gio/gunixconnection.c:166 gio/gunixconnection.c:579 +#, c-format +msgid "Expecting 1 control message, got %d" +msgid_plural "Expecting 1 control message, got %d" +msgstr[0] "é æœŸæœ‰ 1 個控制訊æ¯ï¼Œå»æ”¶åˆ° %d" + +#: gio/gunixconnection.c:182 gio/gunixconnection.c:591 +msgid "Unexpected type of ancillary data" +msgstr "è¼”åŠ©è³‡æ–™çš„æœªé æœŸé¡žåž‹" + +#: gio/gunixconnection.c:200 +#, c-format +msgid "Expecting one fd, but got %d\n" +msgid_plural "Expecting one fd, but got %d\n" +msgstr[0] "é æœŸæœ‰ 1 個 fdï¼Œå»æ”¶åˆ° %d\n" + +#: gio/gunixconnection.c:219 +msgid "Received invalid fd" +msgstr "收到無效的 fd" + +#: gio/gunixconnection.c:363 +msgid "Error sending credentials: " +msgstr "傳逿†‘證時發生錯誤:" + +#: gio/gunixconnection.c:520 +#, c-format +msgid "Error checking if SO_PASSCRED is enabled for socket: %s" +msgstr "檢查 SO_PASSCRED 在 socket 是å¦å•Ÿç”¨æ™‚發生錯誤:%s" + +#: gio/gunixconnection.c:536 +#, c-format +msgid "Error enabling SO_PASSCRED: %s" +msgstr "啟用 SO_PASSCRED 時發生錯誤:%s" + +#: gio/gunixconnection.c:565 +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "é æœŸæŽ¥æ”¶æ†‘è­‰è¦è®€å–單一ä½å…ƒçµ„,但讀å–到零ä½å…ƒçµ„" + +#: gio/gunixconnection.c:605 +#, c-format +msgid "Not expecting control message, but got %d" +msgstr "䏿˜¯é æœŸçš„æŽ§åˆ¶è¨Šæ¯ï¼Œå»æ”¶åˆ° %d" + +#: gio/gunixconnection.c:630 +#, c-format +msgid "Error while disabling SO_PASSCRED: %s" +msgstr "åœç”¨ SO_PASSCRED 時發生錯誤:%s" + +#: gio/gunixinputstream.c:362 gio/gunixinputstream.c:383 +#, c-format +msgid "Error reading from file descriptor: %s" +msgstr "è®€å–æª”案æè¿°ç‹€æ…‹æ™‚發生錯誤:%s" + +#: gio/gunixinputstream.c:416 gio/gunixoutputstream.c:525 +#: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 +#, c-format +msgid "Error closing file descriptor: %s" +msgstr "關閉檔案æè¿°ç‹€æ…‹æ™‚發生錯誤:%s" + +#: gio/gunixmounts.c:2755 gio/gunixmounts.c:2808 +msgid "Filesystem root" +msgstr "根檔案系統" + +#: gio/gunixoutputstream.c:362 gio/gunixoutputstream.c:382 +#: gio/gunixoutputstream.c:469 gio/gunixoutputstream.c:489 +#: gio/gunixoutputstream.c:635 +#, c-format +msgid "Error writing to file descriptor: %s" +msgstr "寫入檔案æè¿°ç‹€æ…‹æ™‚發生錯誤:%s" + +#: gio/gunixsocketaddress.c:243 +msgid "Abstract UNIX domain socket addresses not supported on this system" +msgstr "é€™å€‹ç³»çµ±ä¸æ”¯æŽˆæŠ½è±¡ UNIX 網域 socket ä½å€" + +#: gio/gvolume.c:438 +msgid "volume doesn’t implement eject" +msgstr "儲存å€å°šæœªå¯¦ä½œé€€å‡º(eject)" + +#. Translators: This is an error +#. * message for volume objects that +#. * don't implement any of eject or eject_with_operation. +#: gio/gvolume.c:515 +msgid "volume doesn’t implement eject or eject_with_operation" +msgstr "儲存å€å°šæœªå¯¦ä½œé€€å‡º(eject) 或 eject_with_operation" + +#: gio/gwin32inputstream.c:185 +#, c-format +msgid "Error reading from handle: %s" +msgstr "從處ç†å™¨è®€å–時發生錯誤:%s" + +#: gio/gwin32inputstream.c:232 gio/gwin32outputstream.c:219 +#, c-format +msgid "Error closing handle: %s" +msgstr "關閉處ç†å™¨æ™‚發生錯誤:%s" + +#: gio/gwin32outputstream.c:172 +#, c-format +msgid "Error writing to handle: %s" +msgstr "寫入至處ç†å™¨æ™‚發生錯誤:%s" + +#: gio/gzlibcompressor.c:394 gio/gzlibdecompressor.c:347 +msgid "Not enough memory" +msgstr "沒有足夠的記憶體" + +#: gio/gzlibcompressor.c:401 gio/gzlibdecompressor.c:354 +#, c-format +msgid "Internal error: %s" +msgstr "內部的錯誤:%s" + +#: gio/gzlibcompressor.c:414 gio/gzlibdecompressor.c:368 +msgid "Need more input" +msgstr "éœ€è¦æ›´å¤šè¼¸å…¥" + +#: gio/gzlibdecompressor.c:340 +msgid "Invalid compressed data" +msgstr "無效的壓縮資料" + +#: gio/tests/gdbus-daemon.c:18 +msgid "Address to listen on" +msgstr "監è½çš„ä½å€" + +#: gio/tests/gdbus-daemon.c:19 +msgid "Ignored, for compat with GTestDbus" +msgstr "已忽略,用於 GTestDbus 相容性" + +#: gio/tests/gdbus-daemon.c:20 +msgid "Print address" +msgstr "顯示ä½å€" + +#: gio/tests/gdbus-daemon.c:21 +msgid "Print address in shell mode" +msgstr "以系統殼模å¼é¡¯ç¤ºä½å€" + +#: gio/tests/gdbus-daemon.c:28 +msgid "Run a dbus service" +msgstr "執行 dbus æœå‹™" + +#: gio/tests/gdbus-daemon.c:42 +msgid "Wrong args\n" +msgstr "錯誤引數\n" + +#: glib/gbookmarkfile.c:768 +#, c-format +msgid "Unexpected attribute “%s†for element “%sâ€" +msgstr "「%2$sã€å…ƒç´ ä¸­æœ‰æœªé æœŸçš„「%1$sã€ç‰¹æ€§" + +#: glib/gbookmarkfile.c:779 glib/gbookmarkfile.c:859 glib/gbookmarkfile.c:869 +#: glib/gbookmarkfile.c:982 +#, c-format +msgid "Attribute “%s†of element “%s†not found" +msgstr "找ä¸åˆ°ã€Œ%2$sã€å…ƒç´ ä¸­çš„「%1$sã€ç‰¹æ€§" + +#: glib/gbookmarkfile.c:1191 glib/gbookmarkfile.c:1256 +#: glib/gbookmarkfile.c:1320 glib/gbookmarkfile.c:1330 +#, c-format +msgid "Unexpected tag “%sâ€, tag “%s†expected" +msgstr "æœªé æœŸã€Œ%sã€æ¨™ç±¤ï¼Œæ‡‰ç‚ºã€Œ%sã€æ¨™ç±¤" + +#: glib/gbookmarkfile.c:1216 glib/gbookmarkfile.c:1230 +#: glib/gbookmarkfile.c:1298 glib/gbookmarkfile.c:1344 +#, c-format +msgid "Unexpected tag “%s†inside “%sâ€" +msgstr "「%2$sã€ä¸­æœ‰æœªé æœŸçš„「%1$sã€æ¨™ç±¤" + +#: glib/gbookmarkfile.c:1624 +#, c-format +msgid "Invalid date/time ‘%s’ in bookmark file" +msgstr "書籤檔案中的「%sã€æ—¥æœŸ/時間無效" + +#: glib/gbookmarkfile.c:1827 +msgid "No valid bookmark file found in data dirs" +msgstr "在資料目錄中找ä¸åˆ°æœ‰æ•ˆçš„æ›¸ç±¤æª”案" + +#: glib/gbookmarkfile.c:2028 +#, c-format +msgid "A bookmark for URI “%s†already exists" +msgstr "URI「%sã€çš„æ›¸ç±¤å·²ç¶“存在" + +#: glib/gbookmarkfile.c:2077 glib/gbookmarkfile.c:2235 +#: glib/gbookmarkfile.c:2320 glib/gbookmarkfile.c:2400 +#: glib/gbookmarkfile.c:2485 glib/gbookmarkfile.c:2619 +#: glib/gbookmarkfile.c:2752 glib/gbookmarkfile.c:2887 +#: glib/gbookmarkfile.c:2929 glib/gbookmarkfile.c:3026 +#: glib/gbookmarkfile.c:3147 glib/gbookmarkfile.c:3341 +#: glib/gbookmarkfile.c:3482 glib/gbookmarkfile.c:3701 +#: glib/gbookmarkfile.c:3790 glib/gbookmarkfile.c:3879 +#: glib/gbookmarkfile.c:3998 +#, c-format +msgid "No bookmark found for URI “%sâ€" +msgstr "找ä¸åˆ° URI「%sã€çš„æ›¸ç±¤" + +#: glib/gbookmarkfile.c:2409 +#, c-format +msgid "No MIME type defined in the bookmark for URI “%sâ€" +msgstr "URI「%sã€æ›¸ç±¤ä¸­æ²’有定義 MIME 類型" + +#: glib/gbookmarkfile.c:2494 +#, c-format +msgid "No private flag has been defined in bookmark for URI “%sâ€" +msgstr "URI「%sã€æ›¸ç±¤ä¸­æ²’æœ‰ç§æœ‰æ——幟" + +#: glib/gbookmarkfile.c:3035 +#, c-format +msgid "No groups set in bookmark for URI “%sâ€" +msgstr "URI「%sã€æ›¸ç±¤ä¸­æ²’有設定群組" + +#: glib/gbookmarkfile.c:3503 glib/gbookmarkfile.c:3711 +#, c-format +msgid "No application with name “%s†registered a bookmark for “%sâ€" +msgstr "沒有å為「%sã€çš„æ‡‰ç”¨ç¨‹å¼è¨»å†Šæ›¸ç±¤ã€Œ%sã€" + +#: glib/gbookmarkfile.c:3734 +#, c-format +msgid "Failed to expand exec line “%s†with URI “%sâ€" +msgstr "以 URI「%2$sã€å±•é–‹ exec 列「%1$sã€å¤±æ•—" + +#: glib/gconvert.c:467 +msgid "Unrepresentable character in conversion input" +msgstr "轉æ›è¼¸å…¥è³‡æ–™æ™‚出ç¾ç„¡æ³•表示的字元" + +#: glib/gconvert.c:494 glib/gutf8.c:871 glib/gutf8.c:1083 glib/gutf8.c:1220 +#: glib/gutf8.c:1324 +msgid "Partial character sequence at end of input" +msgstr "è¼¸å…¥è³‡æ–™çµæŸæ™‚å­—å…ƒä»æœªå®Œæ•´" + +#: glib/gconvert.c:763 +#, c-format +msgid "Cannot convert fallback “%s†to codeset “%sâ€" +msgstr "無法將後備字串「%sã€çš„å­—å…ƒé›†è½‰æ›æˆã€Œ%sã€" + +#: glib/gconvert.c:935 +msgid "Embedded NUL byte in conversion input" +msgstr "轉æ›è¼¸å…¥è³‡æ–™æ™‚出ç¾å…§åµŒçš„ NUL ä½å…ƒçµ„" + +#: glib/gconvert.c:956 +msgid "Embedded NUL byte in conversion output" +msgstr "轉æ›è¼¸å‡ºè³‡æ–™æ™‚出ç¾å…§åµŒçš„ NUL ä½å…ƒçµ„" + +#: glib/gconvert.c:1641 +#, c-format +msgid "The URI “%s†is not an absolute URI using the “file†scheme" +msgstr "URI「%sã€ä¸æ˜¯ä½¿ç”¨ã€Œfileã€æ ¼å¼çš„çµ•å° URI" + +#: glib/gconvert.c:1651 +#, c-format +msgid "The local file URI “%s†may not include a “#â€" +msgstr "本機檔案的 URI「%sã€ä¸æ‡‰å«æœ‰ã€Œ#ã€" + +#: glib/gconvert.c:1668 +#, c-format +msgid "The URI “%s†is invalid" +msgstr "URI「%sã€ç„¡æ•ˆ" + +#: glib/gconvert.c:1680 +#, c-format +msgid "The hostname of the URI “%s†is invalid" +msgstr "URI「%sã€ä¸­çš„主機å稱無效" + +#: glib/gconvert.c:1696 +#, c-format +msgid "The URI “%s†contains invalidly escaped characters" +msgstr "URI「%sã€å«æœ‰ã€Œä¸æ­£ç¢ºè·³å‡ºã€çš„å­—å…ƒ" + +#: glib/gconvert.c:1768 +#, c-format +msgid "The pathname “%s†is not an absolute path" +msgstr "路徑å稱「%sã€ä¸æ˜¯çµ•å°è·¯å¾‘" + +#. Translators: this is the preferred format for expressing the date and the time +#: glib/gdatetime.c:220 +msgctxt "GDateTime" +msgid "%a %b %e %H:%M:%S %Y" +msgstr "%Yå¹´%m月%dæ—¥ (%A) %H時%M分%Sç§’" + +#. Translators: this is the preferred format for expressing the date +#: glib/gdatetime.c:223 +msgctxt "GDateTime" +msgid "%m/%d/%y" +msgstr "%y/%m/%d" + +#. Translators: this is the preferred format for expressing the time +#: glib/gdatetime.c:226 +msgctxt "GDateTime" +msgid "%H:%M:%S" +msgstr "%H:%M:%S" + +#. Translators: this is the preferred format for expressing 12 hour time +#: glib/gdatetime.c:229 +msgctxt "GDateTime" +msgid "%I:%M:%S %p" +msgstr "%p %I時%M分%Sç§’" + +#. Translators: Some languages (Baltic, Slavic, Greek, and some more) +#. * need different grammatical forms of month names depending on whether +#. * they are standalone or in a complete date context, with the day +#. * number. Some other languages may prefer starting with uppercase when +#. * they are standalone and with lowercase when they are in a complete +#. * date context. Here are full month names in a form appropriate when +#. * they are used standalone. If your system is Linux with the glibc +#. * version 2.27 (released Feb 1, 2018) or newer or if it is from the BSD +#. * family (which includes OS X) then you can refer to the date command +#. * line utility and see what the command `date +%OB' produces. Also in +#. * the latest Linux the command `locale alt_mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. Note that in most of the languages (western European, +#. * non-European) there is no difference between the standalone and +#. * complete date form. +#. +#: glib/gdatetime.c:268 +msgctxt "full month name" +msgid "January" +msgstr "一月" + +#: glib/gdatetime.c:270 +msgctxt "full month name" +msgid "February" +msgstr "二月" + +#: glib/gdatetime.c:272 +msgctxt "full month name" +msgid "March" +msgstr "三月" + +#: glib/gdatetime.c:274 +msgctxt "full month name" +msgid "April" +msgstr "四月" + +#: glib/gdatetime.c:276 +msgctxt "full month name" +msgid "May" +msgstr "五月" + +#: glib/gdatetime.c:278 +msgctxt "full month name" +msgid "June" +msgstr "六月" + +#: glib/gdatetime.c:280 +msgctxt "full month name" +msgid "July" +msgstr "七月" + +#: glib/gdatetime.c:282 +msgctxt "full month name" +msgid "August" +msgstr "八月" + +#: glib/gdatetime.c:284 +msgctxt "full month name" +msgid "September" +msgstr "乿œˆ" + +#: glib/gdatetime.c:286 +msgctxt "full month name" +msgid "October" +msgstr "åæœˆ" + +#: glib/gdatetime.c:288 +msgctxt "full month name" +msgid "November" +msgstr "å一月" + +#: glib/gdatetime.c:290 +msgctxt "full month name" +msgid "December" +msgstr "å二月" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a complete +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. However, as these names are abbreviated +#. * the grammatical difference is visible probably only in Belarusian +#. * and Russian. In other languages there is no difference between +#. * the standalone and complete date form when they are abbreviated. +#. * If your system is Linux with the glibc version 2.27 (released +#. * Feb 1, 2018) or newer then you can refer to the date command line +#. * utility and see what the command `date +%Ob' produces. Also in +#. * the latest Linux the command `locale ab_alt_mon' in your native +#. * locale produces a complete list of month names almost ready to copy +#. * and paste here. Note that this feature is not yet supported by any +#. * other platform. Here are abbreviated month names in a form +#. * appropriate when they are used standalone. +#. +#: glib/gdatetime.c:322 +msgctxt "abbreviated month name" +msgid "Jan" +msgstr "一月" + +#: glib/gdatetime.c:324 +msgctxt "abbreviated month name" +msgid "Feb" +msgstr "二月" + +#: glib/gdatetime.c:326 +msgctxt "abbreviated month name" +msgid "Mar" +msgstr "三月" + +#: glib/gdatetime.c:328 +msgctxt "abbreviated month name" +msgid "Apr" +msgstr "四月" + +#: glib/gdatetime.c:330 +msgctxt "abbreviated month name" +msgid "May" +msgstr "五月" + +#: glib/gdatetime.c:332 +msgctxt "abbreviated month name" +msgid "Jun" +msgstr "六月" + +#: glib/gdatetime.c:334 +msgctxt "abbreviated month name" +msgid "Jul" +msgstr "七月" + +#: glib/gdatetime.c:336 +msgctxt "abbreviated month name" +msgid "Aug" +msgstr "八月" + +#: glib/gdatetime.c:338 +msgctxt "abbreviated month name" +msgid "Sep" +msgstr "乿œˆ" + +#: glib/gdatetime.c:340 +msgctxt "abbreviated month name" +msgid "Oct" +msgstr "åæœˆ" + +#: glib/gdatetime.c:342 +msgctxt "abbreviated month name" +msgid "Nov" +msgstr "å一月" + +#: glib/gdatetime.c:344 +msgctxt "abbreviated month name" +msgid "Dec" +msgstr "å二月" + +#: glib/gdatetime.c:359 +msgctxt "full weekday name" +msgid "Monday" +msgstr "星期一" + +#: glib/gdatetime.c:361 +msgctxt "full weekday name" +msgid "Tuesday" +msgstr "星期二" + +#: glib/gdatetime.c:363 +msgctxt "full weekday name" +msgid "Wednesday" +msgstr "星期三" + +#: glib/gdatetime.c:365 +msgctxt "full weekday name" +msgid "Thursday" +msgstr "星期四" + +#: glib/gdatetime.c:367 +msgctxt "full weekday name" +msgid "Friday" +msgstr "星期五" + +#: glib/gdatetime.c:369 +msgctxt "full weekday name" +msgid "Saturday" +msgstr "星期六" + +#: glib/gdatetime.c:371 +msgctxt "full weekday name" +msgid "Sunday" +msgstr "星期日" + +#: glib/gdatetime.c:386 +msgctxt "abbreviated weekday name" +msgid "Mon" +msgstr "週一" + +#: glib/gdatetime.c:388 +msgctxt "abbreviated weekday name" +msgid "Tue" +msgstr "週二" + +#: glib/gdatetime.c:390 +msgctxt "abbreviated weekday name" +msgid "Wed" +msgstr "週三" + +#: glib/gdatetime.c:392 +msgctxt "abbreviated weekday name" +msgid "Thu" +msgstr "週四" + +#: glib/gdatetime.c:394 +msgctxt "abbreviated weekday name" +msgid "Fri" +msgstr "週五" + +#: glib/gdatetime.c:396 +msgctxt "abbreviated weekday name" +msgid "Sat" +msgstr "週六" + +#: glib/gdatetime.c:398 +msgctxt "abbreviated weekday name" +msgid "Sun" +msgstr "週日" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are full month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. If your system is Linux with the glibc version 2.27 +#. * (released Feb 1, 2018) or newer or if it is from the BSD family +#. * (which includes OS X) then you can refer to the date command line +#. * utility and see what the command `date +%B' produces. Also in +#. * the latest Linux the command `locale mon' in your native locale +#. * produces a complete list of month names almost ready to copy and +#. * paste here. In older Linux systems due to a bug the result is +#. * incorrect in some languages. Note that in most of the languages +#. * (western European, non-European) there is no difference between the +#. * standalone and complete date form. +#. +#: glib/gdatetime.c:462 +msgctxt "full month name with day" +msgid "January" +msgstr "一月" + +#: glib/gdatetime.c:464 +msgctxt "full month name with day" +msgid "February" +msgstr "二月" + +#: glib/gdatetime.c:466 +msgctxt "full month name with day" +msgid "March" +msgstr "三月" + +#: glib/gdatetime.c:468 +msgctxt "full month name with day" +msgid "April" +msgstr "四月" + +#: glib/gdatetime.c:470 +msgctxt "full month name with day" +msgid "May" +msgstr "五月" + +#: glib/gdatetime.c:472 +msgctxt "full month name with day" +msgid "June" +msgstr "六月" + +#: glib/gdatetime.c:474 +msgctxt "full month name with day" +msgid "July" +msgstr "七月" + +#: glib/gdatetime.c:476 +msgctxt "full month name with day" +msgid "August" +msgstr "八月" + +#: glib/gdatetime.c:478 +msgctxt "full month name with day" +msgid "September" +msgstr "乿œˆ" + +#: glib/gdatetime.c:480 +msgctxt "full month name with day" +msgid "October" +msgstr "åæœˆ" + +#: glib/gdatetime.c:482 +msgctxt "full month name with day" +msgid "November" +msgstr "å一月" + +#: glib/gdatetime.c:484 +msgctxt "full month name with day" +msgid "December" +msgstr "å二月" + +#. Translators: Some languages need different grammatical forms of +#. * month names depending on whether they are standalone or in a full +#. * date context, with the day number. Some may prefer starting with +#. * uppercase when they are standalone and with lowercase when they are +#. * in a full date context. Here are abbreviated month names in a form +#. * appropriate when they are used in a full date context, with the +#. * day number. However, as these names are abbreviated the grammatical +#. * difference is visible probably only in Belarusian and Russian. +#. * In other languages there is no difference between the standalone +#. * and complete date form when they are abbreviated. If your system +#. * is Linux with the glibc version 2.27 (released Feb 1, 2018) or newer +#. * then you can refer to the date command line utility and see what the +#. * command `date +%b' produces. Also in the latest Linux the command +#. * `locale abmon' in your native locale produces a complete list of +#. * month names almost ready to copy and paste here. In other systems +#. * due to a bug the result is incorrect in some languages. +#. +#: glib/gdatetime.c:549 +msgctxt "abbreviated month name with day" +msgid "Jan" +msgstr "一月" + +#: glib/gdatetime.c:551 +msgctxt "abbreviated month name with day" +msgid "Feb" +msgstr "二月" + +#: glib/gdatetime.c:553 +msgctxt "abbreviated month name with day" +msgid "Mar" +msgstr "三月" + +#: glib/gdatetime.c:555 +msgctxt "abbreviated month name with day" +msgid "Apr" +msgstr "四月" + +#: glib/gdatetime.c:557 +msgctxt "abbreviated month name with day" +msgid "May" +msgstr "五月" + +#: glib/gdatetime.c:559 +msgctxt "abbreviated month name with day" +msgid "Jun" +msgstr "六月" + +#: glib/gdatetime.c:561 +msgctxt "abbreviated month name with day" +msgid "Jul" +msgstr "七月" + +#: glib/gdatetime.c:563 +msgctxt "abbreviated month name with day" +msgid "Aug" +msgstr "八月" + +#: glib/gdatetime.c:565 +msgctxt "abbreviated month name with day" +msgid "Sep" +msgstr "乿œˆ" + +#: glib/gdatetime.c:567 +msgctxt "abbreviated month name with day" +msgid "Oct" +msgstr "åæœˆ" + +#: glib/gdatetime.c:569 +msgctxt "abbreviated month name with day" +msgid "Nov" +msgstr "å一月" + +#: glib/gdatetime.c:571 +msgctxt "abbreviated month name with day" +msgid "Dec" +msgstr "å二月" + +#. Translators: 'before midday' indicator +#: glib/gdatetime.c:588 +msgctxt "GDateTime" +msgid "AM" +msgstr "上åˆ" + +#. Translators: 'after midday' indicator +#: glib/gdatetime.c:591 +msgctxt "GDateTime" +msgid "PM" +msgstr "下åˆ" + +#: glib/gdir.c:154 +#, c-format +msgid "Error opening directory “%sâ€: %s" +msgstr "開啟目錄「%sã€æ™‚發生錯誤:%s" + +#: glib/gfileutils.c:737 glib/gfileutils.c:829 +#, c-format +msgid "Could not allocate %lu byte to read file “%sâ€" +msgid_plural "Could not allocate %lu bytes to read file “%sâ€" +msgstr[0] "無法é…ç½® %lu ä½å…ƒçµ„ä¾†è®€å–æª”案「%sã€" + +#: glib/gfileutils.c:754 +#, c-format +msgid "Error reading file “%sâ€: %s" +msgstr "è®€å–æª”案「%sã€æ™‚發生錯誤:%s" + +#: glib/gfileutils.c:790 +#, c-format +msgid "File “%s†is too large" +msgstr "檔案「%sã€å¤ªéŽå·¨å¤§" + +#: glib/gfileutils.c:854 +#, c-format +msgid "Failed to read from file “%sâ€: %s" +msgstr "è®€å–æª”案「%sã€å¤±æ•—:%s" + +#: glib/gfileutils.c:902 glib/gfileutils.c:974 glib/gfileutils.c:1466 +#, c-format +msgid "Failed to open file “%sâ€: %s" +msgstr "開啟檔案「%sã€å¤±æ•—:%s" + +#: glib/gfileutils.c:914 +#, c-format +msgid "Failed to get attributes of file “%sâ€: fstat() failed: %s" +msgstr "ç²å–檔案「%sã€çš„特性失敗:fstat() 失敗:%s" + +#: glib/gfileutils.c:944 +#, c-format +msgid "Failed to open file “%sâ€: fdopen() failed: %s" +msgstr "開啟檔案「%sã€å¤±æ•—:fdopen() 失敗:%s" + +#: glib/gfileutils.c:1044 +#, c-format +msgid "Failed to rename file “%s†to “%sâ€: g_rename() failed: %s" +msgstr "檔案å稱由「%sã€æ”¹ç‚ºã€Œ%sã€å¤±æ•—:g_rename() 失敗:%s" + +#: glib/gfileutils.c:1169 +#, c-format +msgid "Failed to write file “%sâ€: write() failed: %s" +msgstr "無法寫入檔案「%sã€ï¼šwrite() 失敗:%s" + +#: glib/gfileutils.c:1189 +#, c-format +msgid "Failed to write file “%sâ€: fsync() failed: %s" +msgstr "無法寫入檔案「%sã€ï¼šfsync() 失敗:%s" + +#: glib/gfileutils.c:1357 glib/gfileutils.c:1769 +#, c-format +msgid "Failed to create file “%sâ€: %s" +msgstr "建立檔案「%sã€å¤±æ•—:%s" + +#: glib/gfileutils.c:1401 +#, c-format +msgid "Existing file “%s†could not be removed: g_unlink() failed: %s" +msgstr "ç¾å­˜æª”案「%sã€ç„¡æ³•移除:g_unlink() 失敗:%s" + +#: glib/gfileutils.c:1735 +#, c-format +msgid "Template “%s†invalid, should not contain a “%sâ€" +msgstr "範本「%sã€ç„¡æ•ˆï¼Œä¸æ‡‰å«æœ‰ã€Œ%sã€" + +# (Abel) this is file template for mktemp/mkstemp +#: glib/gfileutils.c:1748 +#, c-format +msgid "Template “%s†doesn’t contain XXXXXX" +msgstr "範本「%sã€æ²’æœ‰åŒ…å« XXXXXX" + +#: glib/gfileutils.c:2306 glib/gfileutils.c:2334 +#, c-format +msgid "Failed to read the symbolic link “%sâ€: %s" +msgstr "讀å–符號連çµã€Œ%sã€å¤±æ•—:%s" + +#: glib/giochannel.c:1396 +#, c-format +msgid "Could not open converter from “%s†to “%sâ€: %s" +msgstr "無法開啟將「%sã€è½‰æ›è‡³ã€Œ%sã€çš„轉æ›å™¨ï¼š%s" + +#: glib/giochannel.c:1749 +msgid "Can’t do a raw read in g_io_channel_read_line_string" +msgstr "在 g_io_channel_read_line_string 中無法讀å–原始資料" + +#: glib/giochannel.c:1796 glib/giochannel.c:2054 glib/giochannel.c:2141 +msgid "Leftover unconverted data in read buffer" +msgstr "用來讀å–資料的緩è¡å€ä¸­ä»æœ‰æœªè½‰æ›çš„資料" + +#: glib/giochannel.c:1877 glib/giochannel.c:1954 +msgid "Channel terminates in a partial character" +msgstr "在字元未完整之å‰ï¼Œè¼¸å…¥ç®¡é“å·²ç¶“çµæŸ" + +#: glib/giochannel.c:1940 +msgid "Can’t do a raw read in g_io_channel_read_to_end" +msgstr "在 g_io_channel_read_to_end 中無法讀å–原始資料" + +#: glib/gkeyfile.c:789 +msgid "Valid key file could not be found in search dirs" +msgstr "在資料目錄中找ä¸åˆ°æœ‰æ•ˆçš„鵿ª”案" + +#: glib/gkeyfile.c:826 +msgid "Not a regular file" +msgstr "䏿˜¯æ­£è¦çš„æª”案" + +#: glib/gkeyfile.c:1275 +#, c-format +msgid "" +"Key file contains line “%s†which is not a key-value pair, group, or comment" +msgstr "鵿ª”案中「%sã€è¡Œä¸¦éžéµå€¼é…å°ã€ç¾¤çµ„或註解" + +#: glib/gkeyfile.c:1332 +#, c-format +msgid "Invalid group name: %s" +msgstr "無效的群組å稱:%s" + +#: glib/gkeyfile.c:1354 +msgid "Key file does not start with a group" +msgstr "鵿ª”案並éžä»¥ç¾¤çµ„é–‹é ­" + +#: glib/gkeyfile.c:1380 +#, c-format +msgid "Invalid key name: %s" +msgstr "無效的éµå稱:%s" + +#: glib/gkeyfile.c:1407 +#, c-format +msgid "Key file contains unsupported encoding “%sâ€" +msgstr "鵿ª”案包å«ä¸æ”¯æ´çš„編碼「%sã€" + +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3340 glib/gkeyfile.c:3470 glib/gkeyfile.c:3602 +#: glib/gkeyfile.c:3748 glib/gkeyfile.c:3977 glib/gkeyfile.c:4044 +#, c-format +msgid "Key file does not have group “%sâ€" +msgstr "鵿ª”案沒有群組「%sã€" + +#: glib/gkeyfile.c:1778 +#, c-format +msgid "Key file does not have key “%s†in group “%sâ€" +msgstr "鵿ª”案的「%2$sã€ç¾¤çµ„中沒有「%1$sã€éµ" + +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 +#, c-format +msgid "Key file contains key “%s†with value “%s†which is not UTF-8" +msgstr "鵿ª”案包å«çš„「%sã€éµï¼ˆå€¼ç‚ºã€Œ%sã€ï¼‰ä¸¦éž UTF-8" + +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 +#, c-format +msgid "" +"Key file contains key “%s†which has a value that cannot be interpreted." +msgstr "鵿ª”案包å«çš„「%sã€éµçš„值無法解譯。" + +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 +#, c-format +msgid "" +"Key file contains key “%s†in group “%s†which has a value that cannot be " +"interpreted." +msgstr "鵿ª”案包å«çš„「%2$sã€ç¾¤çµ„中「%1$sã€éµçš„值無法解譯。" + +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 +#, c-format +msgid "Key “%s†in group “%s†has value “%s†where %s was expected" +msgstr "「%2$sã€ç¾¤çµ„中的「%1$sã€éµåŒ…å«ã€Œ%3$sã€å€¼ï¼Œä½†é æœŸç‚ºã€Œ%4$sã€" + +#: glib/gkeyfile.c:4284 +msgid "Key file contains escape character at end of line" +msgstr "鵿ª”案在行尾包å«è·³å‡ºå­—å…ƒ" + +#: glib/gkeyfile.c:4306 +#, c-format +msgid "Key file contains invalid escape sequence “%sâ€" +msgstr "鵿ª”æ¡ˆå«æœ‰ä¸æ­£ç¢ºçš„「跳出字元ã€ã€Œ%sã€" + +#: glib/gkeyfile.c:4450 +#, c-format +msgid "Value “%s†cannot be interpreted as a number." +msgstr "「%sã€å€¼ä¸èƒ½è¢«è§£è­¯ç‚ºæ•¸å­—。" + +#: glib/gkeyfile.c:4464 +#, c-format +msgid "Integer value “%s†out of range" +msgstr "整數值「%sã€è¶…出範åœ" + +#: glib/gkeyfile.c:4497 +#, c-format +msgid "Value “%s†cannot be interpreted as a float number." +msgstr "「%sã€å€¼ä¸èƒ½è¢«è§£è­¯ç‚ºæµ®é»žæ•¸ã€‚" + +#: glib/gkeyfile.c:4536 +#, c-format +msgid "Value “%s†cannot be interpreted as a boolean." +msgstr "「%sã€å€¼ä¸èƒ½è¢«è§£è­¯ç‚ºå¸ƒæž—值。" + +#: glib/gmappedfile.c:129 +#, c-format +msgid "Failed to get attributes of file “%s%s%s%sâ€: fstat() failed: %s" +msgstr "檔案 「%s%s%s%sã€çš„特性å–得失敗:fstat() 失敗:%s" + +#: glib/gmappedfile.c:195 +#, c-format +msgid "Failed to map %s%s%s%s: mmap() failed: %s" +msgstr "å°æ‡‰æª”案 %s%s%s%s 失敗:mmap() 失敗:%s" + +#: glib/gmappedfile.c:262 +#, c-format +msgid "Failed to open file “%sâ€: open() failed: %s" +msgstr "開啟檔案「%sã€å¤±æ•—:open() 失敗:%s" + +#: glib/gmarkup.c:398 glib/gmarkup.c:440 +#, c-format +msgid "Error on line %d char %d: " +msgstr "第 %d 列第 %d 個字發生錯誤:" + +#: glib/gmarkup.c:462 glib/gmarkup.c:545 +#, c-format +msgid "Invalid UTF-8 encoded text in name — not valid “%sâ€" +msgstr "å稱中無效的 UTF-8 編碼文字 — 「%sã€ç„¡æ•ˆ" + +#: glib/gmarkup.c:473 +#, c-format +msgid "“%s†is not a valid name" +msgstr "「%sã€éžæœ‰æ•ˆå稱" + +#: glib/gmarkup.c:489 +#, c-format +msgid "“%s†is not a valid name: “%câ€" +msgstr "「%sã€éžæœ‰æ•ˆå稱:「%cã€" + +#: glib/gmarkup.c:613 +#, c-format +msgid "Error on line %d: %s" +msgstr "第 %d 列發生錯誤:%s" + +#: glib/gmarkup.c:690 +#, c-format +msgid "" +"Failed to parse “%-.*sâ€, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"無法解æžã€Œ%-.*sã€ï¼Œå­—å…ƒåƒç…§å…§æ‡‰è©²å«æœ‰æ•¸å­—(例如 ê)─ å¯èƒ½æ˜¯æ•¸å­—太大" + +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"å­—å…ƒåƒç…§çš„çµæŸéƒ¨åˆ†ä¸æ˜¯åˆ†è™Ÿï¼›å¾ˆå¯èƒ½æ‚¨æƒ³ä½¿ç”¨ & 字元但未將它變為實體 ─ è«‹å°‡ & 轉" +"æ›ç‚º &" + +#: glib/gmarkup.c:728 +#, c-format +msgid "Character reference “%-.*s†does not encode a permitted character" +msgstr "å­—å…ƒåƒç…§ã€Œ%-.*sã€ç„¡æ³•表示任何能接å—的字元" + +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;†seen; valid entities are: & " < > '" +msgstr "出ç¾ç©ºç™½çš„實體「&;ã€ï¼›å¯ç”¨çš„實體為:& " < > '" + +#: glib/gmarkup.c:774 +#, c-format +msgid "Entity name “%-.*s†is not known" +msgstr "實體å稱「%-.*sã€æ„ç¾©ä¸æ˜Ž" + +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"å¯¦é«”çš„çµæŸéƒ¨åˆ†ä¸æ˜¯åˆ†è™Ÿï¼›å¾ˆå¯èƒ½æ‚¨æƒ³ä½¿ç”¨ & 字元但未將它變為實體 ─ è«‹å°‡ & 轉æ›" +"為 &" + +#: glib/gmarkup.c:1193 +msgid "Document must begin with an element (e.g. )" +msgstr "文件開始必須為一元素(例如 )" + +#: glib/gmarkup.c:1233 +#, c-format +msgid "" +"“%s†is not a valid character following a “<†character; it may not begin an " +"element name" +msgstr "「<ã€å­—元後的「%sã€ä¸æ˜¯æœ‰æ•ˆçš„字元;這樣ä¸å¯èƒ½æ˜¯å…ƒç´ å稱的開始部份" + +#: glib/gmarkup.c:1276 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†character to end the empty-element tag " +"“%sâ€" +msgstr "ä¸å°‹å¸¸çš„「%sã€å­—元,空元素標籤「%sã€çš„çµå°¾æ‡‰è©²ä»¥ã€Œ>ã€å­—å…ƒçµæŸ" + +#: glib/gmarkup.c:1346 +#, c-format +msgid "Too many attributes in element “%sâ€" +msgstr "「%sã€å…ƒç´ ä¸­çš„特性éŽå¤š" + +#: glib/gmarkup.c:1366 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “=†after attribute name “%s†of element “%sâ€" +msgstr "ä¸å°‹å¸¸çš„「%sã€å­—元,特性å稱「%sã€ï¼ˆå±¬æ–¼ã€Œ%sã€å…ƒç´ ï¼‰å¾Œæ‡‰è©²æ˜¯ã€Œ=ã€å­—å…ƒ" + +#: glib/gmarkup.c:1408 +#, c-format +msgid "" +"Odd character “%sâ€, expected a “>†or “/†character to end the start tag of " +"element “%sâ€, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"ä¸å°‹å¸¸çš„「%sã€å­—元,「%sã€å…ƒç´ çš„開始標籤應該以「>ã€æˆ–「/ã€å­—å…ƒçµæŸï¼Œä¹Ÿå¯ä»¥æ˜¯" +"特性;或許您在特性å稱中使用的字元無效" + +#: glib/gmarkup.c:1453 +#, c-format +msgid "" +"Odd character “%sâ€, expected an open quote mark after the equals sign when " +"giving value for attribute “%s†of element “%sâ€" +msgstr "" +"ä¸å°‹å¸¸çš„「%sã€å­—元,當指定「%sã€ç‰¹æ€§çš„值(屬於「%sã€å…ƒç´ ï¼‰æ™‚,等號後應該出ç¾" +"開引號" + +#: glib/gmarkup.c:1587 +#, c-format +msgid "" +"“%s†is not a valid character following the characters “â€" +msgstr "「%sã€å­—元無效(ä½ç½®åœ¨é—œé–‰ã€Œ%sã€å…ƒç´ æœ«ç«¯ï¼‰ï¼›å…許的字元為「>ã€" + +#: glib/gmarkup.c:1637 +#, c-format +msgid "Element “%s†was closed, no element is currently open" +msgstr "「%sã€å…ƒç´ å·²é—œé–‰ï¼Œæ²’有開啟中的元素" + +#: glib/gmarkup.c:1646 +#, c-format +msgid "Element “%s†was closed, but the currently open element is “%sâ€" +msgstr "「%sã€å…ƒç´ å·²é—œé–‰ï¼Œä½†é–‹å•Ÿä¸­çš„元素是「%sã€" + +#: glib/gmarkup.c:1799 +msgid "Document was empty or contained only whitespace" +msgstr "文件完全空白或åªå«æœ‰ç©ºç™½å­—å…ƒ" + +#: glib/gmarkup.c:1813 +msgid "Document ended unexpectedly just after an open angle bracket “<â€" +msgstr "文件在尖角括號「<ã€å¾Œçªç„¶çµ‚æ­¢" + +#: glib/gmarkup.c:1821 glib/gmarkup.c:1866 +#, c-format +msgid "" +"Document ended unexpectedly with elements still open — “%s†was the last " +"element opened" +msgstr "在ä»ç„¶æœ‰é–‹å•Ÿä¸­çš„元素時,文件çªç„¶çµæŸ ─「%sã€æ˜¯æœ€å¾Œä¸€å€‹é–‹å•Ÿçš„元素" + +#: glib/gmarkup.c:1829 +#, c-format +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "文件çªç„¶çµæŸï¼Œæœ¬ä¾†æ‡‰è©²å‡ºç¾ç”¨ä¾†é—œé–‰æ¨™ç±¤ <%s/> 的尖角括號" + +#: glib/gmarkup.c:1835 +msgid "Document ended unexpectedly inside an element name" +msgstr "在元素的å稱內,文件çªç„¶çµæŸ" + +#: glib/gmarkup.c:1841 +msgid "Document ended unexpectedly inside an attribute name" +msgstr "在特性å稱內,文件çªç„¶çµæŸ" + +#: glib/gmarkup.c:1846 +msgid "Document ended unexpectedly inside an element-opening tag." +msgstr "在元素的開啟標籤內,文件çªç„¶çµæŸ" + +#: glib/gmarkup.c:1852 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "在特性å稱的等號後,文件çªç„¶çµæŸï¼›æ²’有特性值" + +#: glib/gmarkup.c:1859 +msgid "Document ended unexpectedly while inside an attribute value" +msgstr "在特性值內,文件çªç„¶çµæŸ" + +#: glib/gmarkup.c:1876 +#, c-format +msgid "Document ended unexpectedly inside the close tag for element “%sâ€" +msgstr "在「%sã€å…ƒç´ çš„關閉標籤內,文件çªç„¶çµæŸ" + +#: glib/gmarkup.c:1880 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "在未開啟「%sã€å…ƒç´ çš„關閉標籤內,文件çªç„¶çµæŸ" + +#: glib/gmarkup.c:1886 +msgid "Document ended unexpectedly inside a comment or processing instruction" +msgstr "åœ¨è¨»è§£æˆ–è™•ç†æŒ‡ç¤ºå…§ï¼Œæ–‡ä»¶çªç„¶çµæŸ" + +#: glib/goption.c:873 +msgid "[OPTION…]" +msgstr "[é¸é ……]" + +#: glib/goption.c:989 +msgid "Help Options:" +msgstr "說明é¸é …:" + +#: glib/goption.c:990 +msgid "Show help options" +msgstr "顯示說明的é¸é …" + +#: glib/goption.c:996 +msgid "Show all help options" +msgstr "顯示所有的說明é¸é …" + +#: glib/goption.c:1059 +msgid "Application Options:" +msgstr "應用程å¼é¸é …:" + +#: glib/goption.c:1061 +msgid "Options:" +msgstr "é¸é …:" + +#: glib/goption.c:1125 glib/goption.c:1195 +#, c-format +msgid "Cannot parse integer value “%s†for %s" +msgstr "無法給 %2$s è§£æžæ•´æ•¸å€¼ã€Œ%1$sã€" + +#: glib/goption.c:1135 glib/goption.c:1203 +#, c-format +msgid "Integer value “%s†for %s out of range" +msgstr "%2$s 的整數值「%1$sã€è¶…出範åœ" + +#: glib/goption.c:1160 +#, c-format +msgid "Cannot parse double value “%s†for %s" +msgstr "無法給 %2$s è§£æžé›™ç²¾åº¦æµ®é»žæ•¸ã€Œ%1$sã€" + +#: glib/goption.c:1168 +#, c-format +msgid "Double value “%s†for %s out of range" +msgstr "%2$s 的雙精度浮點數「%1$sã€è¶…出範åœ" + +#: glib/goption.c:1460 glib/goption.c:1539 +#, c-format +msgid "Error parsing option %s" +msgstr "è§£æž %s é¸é …時發生錯誤" + +#: glib/goption.c:1570 glib/goption.c:1683 +#, c-format +msgid "Missing argument for %s" +msgstr "缺少 %s çš„åƒæ•¸" + +#: glib/goption.c:2194 +#, c-format +msgid "Unknown option %s" +msgstr "䏿˜Žçš„é¸é … %s" + +#: glib/gregex.c:257 +msgid "corrupted object" +msgstr "ææ¯€çš„物件" + +#: glib/gregex.c:259 +msgid "internal error or corrupted object" +msgstr "å…§éƒ¨éŒ¯èª¤æˆ–ææ¯€çš„物件" + +#: glib/gregex.c:261 +msgid "out of memory" +msgstr "記憶體耗盡" + +#: glib/gregex.c:266 +msgid "backtracking limit reached" +msgstr "å·²é”回溯上é™" + +#: glib/gregex.c:278 glib/gregex.c:286 +msgid "the pattern contains items not supported for partial matching" +msgstr "此模å¼åŒ…å«äº†ä¸æ”¯æ´éƒ¨åˆ†æ¯”å°çš„é …ç›®" + +#: glib/gregex.c:280 +msgid "internal error" +msgstr "內部的錯誤" + +#: glib/gregex.c:288 +msgid "back references as conditions are not supported for partial matching" +msgstr "部分比å°ä¸æ”¯æ´ä»¥åå‘åƒç…§ç‚ºæ¢ä»¶" + +#: glib/gregex.c:297 +msgid "recursion limit reached" +msgstr "å·²é”éžå»»ä¸Šé™" + +#: glib/gregex.c:299 +msgid "invalid combination of newline flags" +msgstr "無效的æ›åˆ—旗標組åˆ" + +#: glib/gregex.c:301 +msgid "bad offset" +msgstr "錯誤的åç§»" + +#: glib/gregex.c:303 +msgid "short utf8" +msgstr "çŸ­å¼ utf8" + +#: glib/gregex.c:305 +msgid "recursion loop" +msgstr "循環廻圈" + +#: glib/gregex.c:309 +msgid "unknown error" +msgstr "䏿˜Žçš„錯誤" + +#: glib/gregex.c:329 +msgid "\\ at end of pattern" +msgstr "\\ 於模å¼çµå°¾" + +#: glib/gregex.c:332 +msgid "\\c at end of pattern" +msgstr "\\c 於模å¼çµå°¾" + +#: glib/gregex.c:335 +msgid "unrecognized character following \\" +msgstr "無法辨識的字元接著 \\" + +#: glib/gregex.c:338 +msgid "numbers out of order in {} quantifier" +msgstr "{} 裡的數字次åºé¡›å€’了" + +#: glib/gregex.c:341 +msgid "number too big in {} quantifier" +msgstr "{} 裡的數字太大了" + +#: glib/gregex.c:344 +msgid "missing terminating ] for character class" +msgstr "å­—å…ƒé¡žåˆ¥ç¼ºå°‘çµæŸçš„ ]" + +#: glib/gregex.c:347 +msgid "invalid escape sequence in character class" +msgstr "字元類別中無效的跳脫åºåˆ—" + +#: glib/gregex.c:350 +msgid "range out of order in character class" +msgstr "å­—å…ƒé¡žåˆ¥çš„ç¯„åœæ¬¡åºé¡›å€’" + +#: glib/gregex.c:353 +msgid "nothing to repeat" +msgstr "沒有æ±è¥¿å¯é‡è¤‡" + +#: glib/gregex.c:357 +msgid "unexpected repeat" +msgstr "æœªé æœŸçš„é‡è¤‡" + +#: glib/gregex.c:360 +msgid "unrecognized character after (? or (?-" +msgstr "在 (? 或 (?- 後無法辨識的字元" + +#: glib/gregex.c:363 +msgid "POSIX named classes are supported only within a class" +msgstr "POSIX 命å類別åªåœ¨å–®ä¸€é¡žåˆ¥ä¸­æ”¯æ´" + +#: glib/gregex.c:366 +msgid "missing terminating )" +msgstr "ç¼ºå°‘çµæŸçš„ )" + +#: glib/gregex.c:369 +msgid "reference to non-existent subpattern" +msgstr "åƒç…§ä¸å­˜åœ¨çš„å­æ¨¡å¼" + +#: glib/gregex.c:372 +msgid "missing ) after comment" +msgstr "註解後缺少 )" + +#: glib/gregex.c:375 +msgid "regular expression is too large" +msgstr "æ­£è¦è¡¨ç¤ºå¼å¤ªå¤§" + +#: glib/gregex.c:378 +msgid "failed to get memory" +msgstr "å–得記憶體失敗" + +#: glib/gregex.c:382 +msgid ") without opening (" +msgstr ") 沒有開頭的 (" + +#: glib/gregex.c:386 +msgid "code overflow" +msgstr "程å¼ç¢¼æº¢æµ" + +#: glib/gregex.c:390 +msgid "unrecognized character after (?<" +msgstr "在 (?< 後有無法辨識的字元" + +#: glib/gregex.c:393 +msgid "lookbehind assertion is not fixed length" +msgstr "lookbehind 判斷æç¤º(assertion) 䏿˜¯å›ºå®šçš„長度" + +#: glib/gregex.c:396 +msgid "malformed number or name after (?(" +msgstr "(?( 之後有格å¼ä¸æ­£ç¢ºçš„æ•¸å­—或å稱" + +#: glib/gregex.c:399 +msgid "conditional group contains more than two branches" +msgstr "æ¢ä»¶å¼ç¾¤çµ„包å«äº†å…©å€‹ä»¥ä¸Šçš„分支" + +#: glib/gregex.c:402 +msgid "assertion expected after (?(" +msgstr "(?( 後應該有判斷æç¤º(assertion)" + +#. translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +#. * sequences here, '(?-54' would be an example for the second group. +#. +#: glib/gregex.c:409 +msgid "(?R or (?[+-]digits must be followed by )" +msgstr "(?R 或 (?[+-]數字必須接著 )" + +#: glib/gregex.c:412 +msgid "unknown POSIX class name" +msgstr "䏿˜Žçš„ POSIX 類別å稱" + +#: glib/gregex.c:415 +msgid "POSIX collating elements are not supported" +msgstr "䏿”¯æ´ POSIX æ•´ç†å…ƒç´ " + +#: glib/gregex.c:418 +msgid "character value in \\x{...} sequence is too large" +msgstr "\\x{…} åºåˆ—中的字元值太大" + +#: glib/gregex.c:421 +msgid "invalid condition (?(0)" +msgstr "無效的æ¢ä»¶ (?(0)" + +#: glib/gregex.c:424 +msgid "\\C not allowed in lookbehind assertion" +msgstr "在 lookbehind 判斷æç¤º(assertion) 䏭䏿”¯æ´\\C" + +#: glib/gregex.c:431 +msgid "escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported" +msgstr "escapes \\L, \\l, \\N{name}, \\U, å’Œ \\u 䏿”¯æ´" + +#: glib/gregex.c:434 +msgid "recursive call could loop indefinitely" +msgstr "éžå»»å‘¼å«å¯èƒ½è®Šæˆç„¡é™å»»åœˆ" + +#: glib/gregex.c:438 +msgid "unrecognized character after (?P" +msgstr "在 (?P 後有無法辨識的字元" + +#: glib/gregex.c:441 +msgid "missing terminator in subpattern name" +msgstr "å­æ¨¡å¼åç¨±ä¸­ç¼ºå°‘çµæŸå­—å…ƒ" + +#: glib/gregex.c:444 +msgid "two named subpatterns have the same name" +msgstr "兩個命åçš„å­æ¨¡å¼å…·æœ‰ç›¸åŒçš„å稱" + +#: glib/gregex.c:447 +msgid "malformed \\P or \\p sequence" +msgstr "æ ¼å¼ä¸æ­£ç¢ºçš„ \\P 或 \\p åºåˆ—" + +#: glib/gregex.c:450 +msgid "unknown property name after \\P or \\p" +msgstr "在 \\P 或 \\p å¾Œæœ‰ä¸æ˜Žçš„屬性å稱" + +#: glib/gregex.c:453 +msgid "subpattern name is too long (maximum 32 characters)" +msgstr "å­æ¨¡å¼å稱太長(最多 32 字元)" + +#: glib/gregex.c:456 +msgid "too many named subpatterns (maximum 10,000)" +msgstr "太多命åçš„å­æ¨¡å¼ï¼ˆæœ€å¤§å€¼ 10,000)" + +#: glib/gregex.c:459 +msgid "octal value is greater than \\377" +msgstr "8 進ä½å€¼å¤§æ–¼ \\377" + +#: glib/gregex.c:463 +msgid "overran compiling workspace" +msgstr "編譯工作å€è¶…出範åœ" + +#: glib/gregex.c:467 +msgid "previously-checked referenced subpattern not found" +msgstr "找ä¸åˆ°é å…ˆå‹¾é¸çš„åƒç…§å­å­—串" + +#: glib/gregex.c:470 +msgid "DEFINE group contains more than one branch" +msgstr "DEFINE 群組包å«ä¸€å€‹ä»¥ä¸Šçš„分支" + +#: glib/gregex.c:473 +msgid "inconsistent NEWLINE options" +msgstr "ä¸ä¸€è‡´çš„ NEWLINE é¸é …" + +#: glib/gregex.c:476 +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "\\g 並未隨著具有大括弧ã€è§’括弧或引號的å稱或數字或純文字數字" + +#: glib/gregex.c:480 +msgid "a numbered reference must not be zero" +msgstr "編號å¼åƒç…§å¿…é ˆä¸ç‚ºé›¶" + +#: glib/gregex.c:483 +msgid "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)" +msgstr "引數ä¸å…許用於 (*ACCEPT)ã€(*FAIL) 或 (*COMMIT)" + +#: glib/gregex.c:486 +msgid "(*VERB) not recognized" +msgstr "(*VERB) 無法辨識" + +#: glib/gregex.c:489 +msgid "number is too big" +msgstr "數字太大" + +#: glib/gregex.c:492 +msgid "missing subpattern name after (?&" +msgstr "(?& å¾Œç¼ºå°‘å­æ¨£å¼" + +#: glib/gregex.c:495 +msgid "digit expected after (?+" +msgstr "(?+ 後應該有數字" + +#: glib/gregex.c:498 +msgid "] is an invalid data character in JavaScript compatibility mode" +msgstr "] 在 JavaScript 相容性模å¼ä¸­æ˜¯ç„¡æ•ˆçš„資料字元" + +#: glib/gregex.c:501 +msgid "different names for subpatterns of the same number are not allowed" +msgstr "ä¸å…è¨±åŒæ¨£ç·¨è™Ÿçš„å­æ¨£å¼æœ‰ä¸åŒçš„å稱" + +#: glib/gregex.c:504 +msgid "(*MARK) must have an argument" +msgstr "(*MARK) 需è¦ä¸€å€‹å¼•數" + +#: glib/gregex.c:507 +msgid "\\c must be followed by an ASCII character" +msgstr "\\c 必須接著 ASCII å­—å…ƒ" + +#: glib/gregex.c:510 +msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" +msgstr "\\k 並未隨著具有大括弧ã€è§’括弧或引號的å稱" + +#: glib/gregex.c:513 +msgid "\\N is not supported in a class" +msgstr "\\N åœ¨é¡žåˆ¥ä¸­ä¸æ”¯æ´" + +#: glib/gregex.c:516 +msgid "too many forward references" +msgstr "有太多的å‘å‰åƒç…§" + +#: glib/gregex.c:519 +msgid "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)" +msgstr "å稱在 (*MARK)ã€(*PRUNE)ã€(*SKIP) 或 (*THEN)" + +#: glib/gregex.c:522 +msgid "character value in \\u.... sequence is too large" +msgstr "\\u.... åºåˆ—中的字元值太大" + +#: glib/gregex.c:745 glib/gregex.c:1983 +#, c-format +msgid "Error while matching regular expression %s: %s" +msgstr "æ¯”å°æ­£è¦è¡¨ç¤ºå¼ %s 發生錯誤:%s" + +#: glib/gregex.c:1316 +msgid "PCRE library is compiled without UTF8 support" +msgstr "PCRE 程å¼åº«ä¸¦æœªç·¨è­¯å° UTF8 的支æ´" + +#: glib/gregex.c:1320 +msgid "PCRE library is compiled without UTF8 properties support" +msgstr "PCRE 程å¼åº«ä¸¦æœªç·¨è­¯å° UTF8 屬性的支æ´" + +#: glib/gregex.c:1328 +msgid "PCRE library is compiled with incompatible options" +msgstr "PCRE 程å¼åº«ä¸¦æœªç·¨è­¯ä¸ç›¸å®¹çš„é¸é …" + +#: glib/gregex.c:1357 +#, c-format +msgid "Error while optimizing regular expression %s: %s" +msgstr "最佳化正è¦è¡¨ç¤ºå¼ %s 時發生錯誤:%s" + +#: glib/gregex.c:1437 +#, c-format +msgid "Error while compiling regular expression %s at char %d: %s" +msgstr "編譯正è¦è¡¨ç¤ºå¼ %s 時於第 %d 個字發生錯誤:%s" + +#: glib/gregex.c:2419 +msgid "hexadecimal digit or “}†expected" +msgstr "應為 16 進使•¸å­—或「}ã€" + +#: glib/gregex.c:2435 +msgid "hexadecimal digit expected" +msgstr "應為 16 進使•¸å­—" + +#: glib/gregex.c:2475 +msgid "missing “<†in symbolic reference" +msgstr "在符號åƒç…§ä¸­ç¼ºå°‘「<ã€" + +#: glib/gregex.c:2484 +msgid "unfinished symbolic reference" +msgstr "未完æˆçš„符號åƒç…§" + +#: glib/gregex.c:2491 +msgid "zero-length symbolic reference" +msgstr "é›¶-長度的符號åƒç…§" + +#: glib/gregex.c:2502 +msgid "digit expected" +msgstr "é æœŸæ•¸å­—" + +#: glib/gregex.c:2520 +msgid "illegal symbolic reference" +msgstr "ä¸åˆæ³•的符號åƒç…§" + +#: glib/gregex.c:2583 +msgid "stray final “\\â€" +msgstr "缺少最後的「\\ã€" + +#: glib/gregex.c:2587 +msgid "unknown escape sequence" +msgstr "䏿˜Žçš„跳脫åºåˆ—" + +#: glib/gregex.c:2597 +#, c-format +msgid "Error while parsing replacement text “%s†at char %lu: %s" +msgstr "ç•¶è§£æžæ–¼å­—å…ƒ %2$lu çš„å–代文字「%1$sã€æ™‚發生錯誤:%3$s" + +#: glib/gshell.c:94 +msgid "Quoted text doesn’t begin with a quotation mark" +msgstr "æ‡‰è©²ç”¨å¼•è™Ÿæ‹¬èµ·ä¾†çš„æ–‡å­—ä¸æ˜¯ä»¥æ‹¬è™Ÿç‚ºé–‹å§‹" + +#: glib/gshell.c:184 +msgid "Unmatched quotation mark in command line or other shell-quoted text" +msgstr "指令列或其它標為指令的字串內有ä¸å°ç¨±çš„引號" + +#: glib/gshell.c:580 +#, c-format +msgid "Text ended just after a “\\†character. (The text was “%sâ€)" +msgstr "文字在「\\ã€å­—元後就終止了。(文字為「%sã€)" + +#: glib/gshell.c:587 +#, c-format +msgid "Text ended before matching quote was found for %c. (The text was “%sâ€)" +msgstr "字串完çµå‰ä»æ²’æœ‰å°æ‡‰æ–¼ %c 的引號 (字串為「%sã€)" + +#: glib/gshell.c:599 +msgid "Text was empty (or contained only whitespace)" +msgstr "文字是空白的(或åªå«æœ‰ç©ºç™½å­—元)" + +#: glib/gspawn.c:323 +#, c-format +msgid "Failed to read data from child process (%s)" +msgstr "無法從副進程讀å–資料 (%s)" + +#: glib/gspawn.c:468 +#, c-format +msgid "Unexpected error in reading data from a child process (%s)" +msgstr "從å­ç¨‹åº (%s) 讀å–è³‡æ–™æ™‚ç™¼ç”Ÿæœªé æœŸçš„錯誤" + +#: glib/gspawn.c:553 +#, c-format +msgid "Unexpected error in waitpid() (%s)" +msgstr "waitpid() ç™¼ç”Ÿæœªé æœŸçš„錯誤 (%s)" + +#: glib/gspawn.c:1061 glib/gspawn-win32.c:1329 +#, c-format +msgid "Child process exited with code %ld" +msgstr "å­ç¨‹åºä»¥ä»£ç¢¼ %ld çµæŸ" + +#: glib/gspawn.c:1069 +#, c-format +msgid "Child process killed by signal %ld" +msgstr "å­ç¨‹åºè¢«ä¿¡è™Ÿ %ld 中止" + +#: glib/gspawn.c:1076 +#, c-format +msgid "Child process stopped by signal %ld" +msgstr "å­ç¨‹åºè¢«ä¿¡è™Ÿ %ld åœæ­¢" + +#: glib/gspawn.c:1083 +#, c-format +msgid "Child process exited abnormally" +msgstr "å­ç¨‹åºç•°å¸¸çµæŸ" + +#: glib/gspawn.c:1532 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 +#, c-format +msgid "Failed to read from child pipe (%s)" +msgstr "無法從管é“讀å–資料 (%s)" + +#: glib/gspawn.c:1788 +#, c-format +msgid "Failed to spawn child process “%s†(%s)" +msgstr "無法產生副程åºã€Œ%sã€(%s)" + +#: glib/gspawn.c:1871 +#, c-format +msgid "Failed to fork (%s)" +msgstr "無法è¡ç”Ÿé€²ç¨‹ (%s)" + +#: glib/gspawn.c:2026 glib/gspawn-win32.c:381 +#, c-format +msgid "Failed to change to directory “%s†(%s)" +msgstr "無法進入目錄「%sã€(%s)" + +#: glib/gspawn.c:2036 +#, c-format +msgid "Failed to execute child process “%s†(%s)" +msgstr "無法執行副程åºã€Œ%sã€(%s)" + +#: glib/gspawn.c:2046 +#, c-format +msgid "Failed to redirect output or input of child process (%s)" +msgstr "ç„¡æ³•å°‡å‰¯é€²ç¨‹çš„è¼¸å‡ºæˆ–è¼¸å…¥é‡æ–°å°Žå‘ (%s)" + +#: glib/gspawn.c:2055 +#, c-format +msgid "Failed to fork child process (%s)" +msgstr "無法è¡ç”Ÿå‰¯é€²ç¨‹ (%s)" + +#: glib/gspawn.c:2063 +#, c-format +msgid "Unknown error executing child process “%sâ€" +msgstr "執行副程åºã€Œ%sã€æ™‚ç™¼ç”Ÿä¸æ˜Žçš„錯誤" + +#: glib/gspawn.c:2087 +#, c-format +msgid "Failed to read enough data from child pid pipe (%s)" +msgstr "無法從 child pid pipe 讀å–足夠的資料 (%s)" + +#: glib/gspawn-win32.c:294 +msgid "Failed to read data from child process" +msgstr "無法從副進程讀å–資料" + +#: glib/gspawn-win32.c:311 +#, c-format +msgid "Failed to create pipe for communicating with child process (%s)" +msgstr "無法建立管é“來和副進程æºé€š (%s)" + +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 +#, c-format +msgid "Failed to execute child process (%s)" +msgstr "無法執行副進程 (%s)" + +#: glib/gspawn-win32.c:461 +#, c-format +msgid "Invalid program name: %s" +msgstr "程å¼å稱無效:%s" + +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 +#, c-format +msgid "Invalid string in argument vector at %d: %s" +msgstr "第 %d 個引數å‘é‡ä¸­å«ç„¡æ•ˆçš„字串:%s" + +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 +#, c-format +msgid "Invalid string in environment: %s" +msgstr "環境變數中的字串無效:%s" + +#: glib/gspawn-win32.c:721 +#, c-format +msgid "Invalid working directory: %s" +msgstr "無效的工作目錄:%s" + +#: glib/gspawn-win32.c:783 +#, c-format +msgid "Failed to execute helper program (%s)" +msgstr "無法執行å”åŠ©ç¨‹å¼ (%s)" + +#: glib/gspawn-win32.c:1056 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "ç•¶ g_io_channel_win32_poll() 從副進程讀å–資料時發生無法é è¨ˆçš„錯誤" + +#: glib/gstrfuncs.c:3303 glib/gstrfuncs.c:3405 +msgid "Empty string is not a number" +msgstr "ç©ºå­—ä¸²ä¸æ˜¯æ•¸å­—" + +#: glib/gstrfuncs.c:3327 +#, c-format +msgid "“%s†is not a signed number" +msgstr "「%sã€ä¸æ˜¯æœ‰è™Ÿæ•¸å­—" + +#: glib/gstrfuncs.c:3337 glib/gstrfuncs.c:3441 +#, c-format +msgid "Number “%s†is out of bounds [%s, %s]" +msgstr "「%sã€æ•¸å­—è¶…å‡ºç¯„åœ [%s, %s]" + +#: glib/gstrfuncs.c:3431 +#, c-format +msgid "“%s†is not an unsigned number" +msgstr "「%sã€ä¸æ˜¯ç„¡è™Ÿæ•¸å­—" + +#: glib/guri.c:313 +#, no-c-format +msgid "Invalid %-encoding in URI" +msgstr "URI 中有無效的 %-編碼" + +#: glib/guri.c:330 +msgid "Illegal character in URI" +msgstr "URI 中有ä¸åˆè¦çš„å­—å…ƒ" + +#: glib/guri.c:359 +msgid "Non-UTF-8 characters in URI" +msgstr "URI ä¸­æœ‰éž UTF-8 å­—å…ƒ" + +#: glib/guri.c:533 +#, c-format +msgid "Invalid IPv6 address ‘%.*s’ in URI" +msgstr "URI 中有無效的 IPv6 ä½å€ã€Œ%.*sã€" + +#: glib/guri.c:588 +#, c-format +msgid "Illegal encoded IP address ‘%.*s’ in URI" +msgstr "URI 中有ä¸åˆè¦çš„編碼 IP ä½å€ã€Œ%.*sã€" + +#: glib/guri.c:620 glib/guri.c:632 +#, c-format +msgid "Could not parse port ‘%.*s’ in URI" +msgstr "ç„¡æ³•è§£æž URI 中的「%.*sã€é€£æŽ¥åŸ " + +#: glib/guri.c:639 +#, c-format +msgid "Port ‘%.*s’ in URI is out of range" +msgstr "URI 中的「%.*sã€é€£æŽ¥åŸ è¶…出範åœ" + +#: glib/guri.c:1119 glib/guri.c:1183 +#, c-format +msgid "URI ‘%s’ is not an absolute URI" +msgstr "「%sã€URI 䏿˜¯çµ•å°è·¯å¾‘ URI" + +#: glib/guri.c:1125 +#, c-format +msgid "URI ‘%s’ has no host component" +msgstr "「%sã€URI 沒有主機部分" + +#: glib/guri.c:1330 +msgid "URI is not absolute, and no base URI was provided" +msgstr "URI 䏿˜¯çµ•å°è·¯å¾‘,且沒有æä¾›åŸºç¤Ž URI" + +#: glib/guri.c:2082 +msgid "Missing ‘=’ and parameter value" +msgstr "缺失「=ã€èˆ‡åƒæ•¸å€¼" + +#: glib/gutf8.c:817 +msgid "Failed to allocate memory" +msgstr "é…置記憶體失敗" + +#: glib/gutf8.c:950 +msgid "Character out of range for UTF-8" +msgstr "å­—å…ƒä¸åœ¨ UTF-8 範åœä¹‹å…§" + +#: glib/gutf8.c:1051 glib/gutf8.c:1060 glib/gutf8.c:1190 glib/gutf8.c:1199 +#: glib/gutf8.c:1338 glib/gutf8.c:1435 +msgid "Invalid sequence in conversion input" +msgstr "轉æ›è¼¸å…¥è³‡æ–™æ™‚出ç¾ç„¡æ•ˆçš„字元次åº" + +#: glib/gutf8.c:1349 glib/gutf8.c:1446 +msgid "Character out of range for UTF-16" +msgstr "å­—å…ƒä¸åœ¨ UTF-16 範åœä¹‹å…§" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2759 +#, c-format +msgid "%.1f kB" +msgstr "%.1f kB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2761 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2763 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2765 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2767 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2769 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2773 +#, c-format +msgid "%.1f KiB" +msgstr "%.1f KiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2775 +#, c-format +msgid "%.1f MiB" +msgstr "%.1f MiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2777 +#, c-format +msgid "%.1f GiB" +msgstr "%.1f GiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2779 +#, c-format +msgid "%.1f TiB" +msgstr "%.1f TiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2781 +#, c-format +msgid "%.1f PiB" +msgstr "%.1f PiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2783 +#, c-format +msgid "%.1f EiB" +msgstr "%.1f EiB" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2787 +#, c-format +msgid "%.1f kb" +msgstr "%.1f kb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2789 +#, c-format +msgid "%.1f Mb" +msgstr "%.1f Mb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2791 +#, c-format +msgid "%.1f Gb" +msgstr "%.1f Gb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2793 +#, c-format +msgid "%.1f Tb" +msgstr "%.1f Tb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2795 +#, c-format +msgid "%.1f Pb" +msgstr "%.1f Pb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2797 +#, c-format +msgid "%.1f Eb" +msgstr "%.1f Eb" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2801 +#, c-format +msgid "%.1f Kib" +msgstr "%.1f Kib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2803 +#, c-format +msgid "%.1f Mib" +msgstr "%.1f Mib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2805 +#, c-format +msgid "%.1f Gib" +msgstr "%.1f Gib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2807 +#, c-format +msgid "%.1f Tib" +msgstr "%.1f Tib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2809 +#, c-format +msgid "%.1f Pib" +msgstr "%.1f Pib" + +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2811 +#, c-format +msgid "%.1f Eib" +msgstr "%.1f Eib" + +#: glib/gutils.c:2845 glib/gutils.c:2962 +#, c-format +msgid "%u byte" +msgid_plural "%u bytes" +msgstr[0] "%u ä½å…ƒçµ„" + +#: glib/gutils.c:2849 +#, c-format +msgid "%u bit" +msgid_plural "%u bits" +msgstr[0] "%u ä½å…ƒ" + +#. Translators: the %s in "%s bytes" will always be replaced by a number. +#: glib/gutils.c:2916 +#, c-format +msgid "%s byte" +msgid_plural "%s bytes" +msgstr[0] "%s ä½å…ƒçµ„" + +#. Translators: the %s in "%s bits" will always be replaced by a number. +#: glib/gutils.c:2921 +#, c-format +msgid "%s bit" +msgid_plural "%s bits" +msgstr[0] "%s ä½å…ƒ" + +#. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to +#. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of +#. * compatibility. Users will not see this string unless a program is using this deprecated function. +#. * Please translate as literally as possible. +#. +#: glib/gutils.c:2975 +#, c-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: glib/gutils.c:2980 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2985 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2990 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2995 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:3000 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + +#~ msgid "Error in address “%s†— the family attribute is malformed" +#~ msgstr "ä½å€ã€Œ%sã€æœ‰éŒ¯èª¤ — family 屬性的格å¼ä¸è‰¯" + +#~ msgid "Mounted %s at %s\n" +#~ msgstr "%s 已掛載於 %s\n" + +#~ msgid "; ignoring override for this key.\n" +#~ msgstr ";忽略這個設定éµçš„覆蓋。\n" + +#~ msgid " and --strict was specified; exiting.\n" +#~ msgstr "並且指定了 --strictï¼›æ­£åœ¨çµæŸã€‚\n" + +#~ msgid "Ignoring override for this key.\n" +#~ msgstr "忽略這個設定éµçš„覆蓋。\n" + +#~ msgid "doing nothing.\n" +#~ msgstr "ä¸åšä»»ä½•事。\n" + +#~ msgid "No such method '%s'" +#~ msgstr "沒有這個方法「%sã€" + +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "ä¸èƒ½å¾ž DBUS_STARTER_BUS_TYPE ç’°å¢ƒè®Šæ•¸åˆ¤æ–·åŒ¯æµæŽ’ä½å€ - 䏿˜Žçš„æ•¸å€¼ã€Œ%sã€" + +#~ msgid "[ARGS...]" +#~ msgstr "[ARGS...]" + +#~ msgid "Failed to create temp file: %s" +#~ msgstr "無法建立暫存檔案:%s" + +#~ msgid "No such interface" +#~ msgstr "沒有這個介é¢" + +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "è¨Šæ¯æœ‰ %d 檔案æè¿°ç¬¦ä½†æ¨™é ­æ¬„ä½è¡¨ç¤ºæœ‰ %d 檔案æè¿°ç¬¦" + +#~ msgid "Error: signal not specified.\n" +#~ msgstr "錯誤:尚未指定信號。\n" + +#~ msgid "Error: signal must be the fully-qualified name.\n" +#~ msgstr "錯誤:信號必須為完全åˆè¦å®šçš„å稱。\n" + +#~ msgid "No files given" +#~ msgstr "尚未指定檔案" + +#~ msgid "Error getting writable attributes: %s\n" +#~ msgstr "å–å¾—å¯å¯«å…¥å±¬æ€§æ™‚發生錯誤:%s\n" + +#~ msgid "Error mounting location: %s\n" +#~ msgstr "掛載ä½ç½®æ™‚發生錯誤: %s\n" + +#~ msgid "Error unmounting mount: %s\n" +#~ msgstr "å¸è¼‰æ™‚發生錯誤: %s\n" + +#~ msgid "Error finding enclosing mount: %s\n" +#~ msgstr "尋找å°è£æŽ›è¼‰ç™¼ç”ŸéŒ¯èª¤ï¼š%s\n" + +#~ msgid "Error ejecting mount: %s\n" +#~ msgstr "退出掛載時發生錯誤:%s\n" + +#~ msgid "Error mounting %s: %s\n" +#~ msgstr "掛載 %s 時發生錯誤:%s\n" + +#~ msgid "No files to open" +#~ msgstr "沒有檔案å¯é–‹å•Ÿ" + +#~ msgid "No files to delete" +#~ msgstr "沒有è¦åˆªé™¤çš„æª”案" + +#~ msgid "Error setting attribute: %s\n" +#~ msgstr "設定屬性時發生錯誤:%s\n" + +#~ msgid "No locations gives" +#~ msgstr "未æä¾›ä½ç½®" + +#~ msgid "Error renaming file: %s" +#~ msgstr "釿–°å‘½å檔案時發生錯誤:%s" + +#~ msgid "Can't open directory" +#~ msgstr "ä¸èƒ½é–‹å•Ÿç›®éŒ„" + +#~ msgid "Error opening file: %s" +#~ msgstr "開啓檔案時發生錯誤:%s" + +#~ msgid "Error creating directory: %s" +#~ msgstr "建立目錄發生錯誤:%s" + +#~ msgid "Error reading file '%s': %s" +#~ msgstr "è®€å–æª”案‘%s’時發生錯誤:%s" + +#~ msgid "Unable to find default local directory monitor type" +#~ msgstr "無法找到é è¨­çš„æœ¬åœ°ç«¯ç›®éŒ„監視器類型" + +#~ msgid "association changes not supported on win32" +#~ msgstr "é—œè¯è®Šæ›´åœ¨ win32 ä¸Šä¸æ”¯æ´" + +#~ msgid "Association creation not supported on win32" +#~ msgstr "é—œè¯å»ºç«‹åœ¨ win32 ä¸Šä¸æ”¯æ´" + +#~ msgid "URIs not supported" +#~ msgstr "䏿”¯æ´ URIs" + +#~ msgid "Key file does not have key '%s'" +#~ msgstr "è¨­å®šéµæª”案沒有設定éµâ€˜%s’" diff --git a/subprojects/gtk-doc.wrap b/subprojects/gtk-doc.wrap new file mode 100644 index 0000000..0490a03 --- /dev/null +++ b/subprojects/gtk-doc.wrap @@ -0,0 +1,5 @@ +[wrap-git] +directory=gtk-doc +url=https://gitlab.gnome.org/GNOME/gtk-doc.git +revision=1.33.2 +depth=1 diff --git a/subprojects/libffi.wrap b/subprojects/libffi.wrap new file mode 100644 index 0000000..00b29d6 --- /dev/null +++ b/subprojects/libffi.wrap @@ -0,0 +1,5 @@ +[wrap-git] +directory=libffi +url=https://gitlab.freedesktop.org/gstreamer/meson-ports/libffi.git +revision=meson +depth=1 diff --git a/subprojects/pcre.wrap b/subprojects/pcre.wrap new file mode 100644 index 0000000..a6b07b9 --- /dev/null +++ b/subprojects/pcre.wrap @@ -0,0 +1,11 @@ +[wrap-file] +directory = pcre-8.37 +source_url = https://sourceforge.net/projects/pcre/files/pcre/8.37/pcre-8.37.tar.bz2 +source_filename = pcre-8.37.tar.bz2 +source_hash = 51679ea8006ce31379fb0860e46dd86665d864b5020fc9cd19e71260eef4789d +patch_filename = pcre_8.37-4_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/pcre_8.37-4/get_patch +patch_hash = c957f42da6f6378300eb8a18f4a5cccdb8e2aada51a703cac842982f9f785399 + +[provide] +libpcre = pcre_dep diff --git a/subprojects/proxy-libintl.wrap b/subprojects/proxy-libintl.wrap new file mode 100644 index 0000000..0e6c852 --- /dev/null +++ b/subprojects/proxy-libintl.wrap @@ -0,0 +1,5 @@ +[wrap-git] +directory=proxy-libintl +url=https://github.com/frida/proxy-libintl.git +revision=c03e1a74b17fa7ec467e110130775409e4828a4c +depth=1 diff --git a/subprojects/sysprof.wrap b/subprojects/sysprof.wrap new file mode 100644 index 0000000..7ae489c --- /dev/null +++ b/subprojects/sysprof.wrap @@ -0,0 +1,5 @@ +[wrap-git] +directory=sysprof +url=https://gitlab.gnome.org/GNOME/sysprof.git +revision=3.38.0 +depth=1 diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap new file mode 100644 index 0000000..c49c1d9 --- /dev/null +++ b/subprojects/zlib.wrap @@ -0,0 +1,11 @@ +[wrap-file] +directory = zlib-1.2.11 +source_url = https://zlib.net/fossils/zlib-1.2.11.tar.gz +source_filename = zlib-1.2.11.tar.gz +source_hash = c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 +patch_filename = zlib_1.2.11-6_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.2.11-6/get_patch +patch_hash = f7c24c5698ce787294910ad431f94088102d35ddaf88542d04add1e54afa9212 + +[provide] +zlib = zlib_dep diff --git a/template-tap.test.in b/template-tap.test.in new file mode 100644 index 0000000..c7d50dc --- /dev/null +++ b/template-tap.test.in @@ -0,0 +1,4 @@ +[Test] +Type=session +Exec=@env@@installed_tests_dir@/@program@ +Output=TAP diff --git a/template.test.in b/template.test.in new file mode 100644 index 0000000..f701627 --- /dev/null +++ b/template.test.in @@ -0,0 +1,3 @@ +[Test] +Type=session +Exec=@installed_tests_dir@/@program@ diff --git a/tests/assert-msg-test.c b/tests/assert-msg-test.c new file mode 100644 index 0000000..75591c8 --- /dev/null +++ b/tests/assert-msg-test.c @@ -0,0 +1,7 @@ +#include + +int main(int argc, char **argv) +{ + g_assert(42 < 0); + return 0; +} diff --git a/tests/assert-msg-test.gdb b/tests/assert-msg-test.gdb new file mode 100644 index 0000000..dbecaaf --- /dev/null +++ b/tests/assert-msg-test.gdb @@ -0,0 +1,5 @@ +run +set print elements 0 +# Work around https://sourceware.org/bugzilla/show_bug.cgi?id=22501 +print *((char**) &__glib_assert_msg) +quit diff --git a/tests/collate/collate-1.file b/tests/collate/collate-1.file new file mode 100644 index 0000000..c8e41e9 --- /dev/null +++ b/tests/collate/collate-1.file @@ -0,0 +1,9 @@ +223 +bar +baz +c +eer34 +er1 +foo +GTK+ +z diff --git a/tests/collate/collate-1.in b/tests/collate/collate-1.in new file mode 100644 index 0000000..1fc8977 --- /dev/null +++ b/tests/collate/collate-1.in @@ -0,0 +1,9 @@ +z +c +eer34 +223 +er1 +foo +bar +baz +GTK+ diff --git a/tests/collate/collate-1.unicode b/tests/collate/collate-1.unicode new file mode 100644 index 0000000..c8e41e9 --- /dev/null +++ b/tests/collate/collate-1.unicode @@ -0,0 +1,9 @@ +223 +bar +baz +c +eer34 +er1 +foo +GTK+ +z diff --git a/tests/collate/collate-2.file b/tests/collate/collate-2.file new file mode 100644 index 0000000..2a5a4da --- /dev/null +++ b/tests/collate/collate-2.file @@ -0,0 +1,13 @@ +bla001 +bla02 +bla03 +bla4 +bla10 +bla100 +event.c +event.h +eventgenerator.c +file.c +file.txt +file2.bla +file3.xx diff --git a/tests/collate/collate-2.in b/tests/collate/collate-2.in new file mode 100644 index 0000000..be294ca --- /dev/null +++ b/tests/collate/collate-2.in @@ -0,0 +1,13 @@ +file.txt +file2.bla +file.c +file3.xx +bla001 +bla02 +bla03 +bla4 +bla10 +bla100 +event.c +eventgenerator.c +event.h diff --git a/tests/collate/collate-2.unicode b/tests/collate/collate-2.unicode new file mode 100644 index 0000000..3546853 --- /dev/null +++ b/tests/collate/collate-2.unicode @@ -0,0 +1,13 @@ +bla001 +bla02 +bla03 +bla10 +bla100 +bla4 +event.c +eventgenerator.c +event.h +file2.bla +file3.xx +file.c +file.txt diff --git a/tests/gio-test.c b/tests/gio-test.c new file mode 100644 index 0000000..d203d0b --- /dev/null +++ b/tests/gio-test.c @@ -0,0 +1,421 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2000 Tor Lillqvist + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* A test program for the main loop and IO channel code. + * Just run it. Optional parameter is number of sub-processes. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include "config.h" + +#include + +#include +#include +#include +#include + +#ifdef G_OS_WIN32 + #include + #include + #include + #define STRICT + #include + #define pipe(fds) _pipe(fds, 4096, _O_BINARY) +#endif + +#ifdef G_OS_UNIX + #include +#endif + +static int nrunning; +static GMainLoop *main_loop; + +#define BUFSIZE 5000 /* Larger than the circular buffer in + * giowin32.c on purpose. + */ + +static int nkiddies; + +static struct { + int fd; + int seq; +} *seqtab; + +static GIOError +read_all (int fd, + GIOChannel *channel, + char *buffer, + guint nbytes, + guint *bytes_read) +{ + guint left = nbytes; + gsize nb; + GIOError error = G_IO_ERROR_NONE; + char *bufp = buffer; + + /* g_io_channel_read() doesn't necessarily return all the + * data we want at once. + */ + *bytes_read = 0; + while (left) + { + error = g_io_channel_read (channel, bufp, left, &nb); + + if (error != G_IO_ERROR_NONE) + { + g_print ("gio-test: ...from %d: %d\n", fd, error); + if (error == G_IO_ERROR_AGAIN) + continue; + break; + } + if (nb == 0) + return error; + left -= nb; + bufp += nb; + *bytes_read += nb; + } + return error; +} + +static void +shutdown_source (gpointer data) +{ + if (g_source_remove (*(guint *) data)) + { + nrunning--; + if (nrunning == 0) + g_main_loop_quit (main_loop); + } +} + +static gboolean +recv_message (GIOChannel *channel, + GIOCondition cond, + gpointer data) +{ + gint fd = g_io_channel_unix_get_fd (channel); + gboolean retval = TRUE; + + g_debug ("gio-test: ...from %d:%s%s%s%s", fd, + (cond & G_IO_ERR) ? " ERR" : "", + (cond & G_IO_HUP) ? " HUP" : "", + (cond & G_IO_IN) ? " IN" : "", + (cond & G_IO_PRI) ? " PRI" : ""); + + if (cond & (G_IO_ERR | G_IO_HUP)) + { + shutdown_source (data); + retval = FALSE; + } + + if (cond & G_IO_IN) + { + char buf[BUFSIZE]; + guint nbytes = 0; + guint nb; + guint j; + int i, seq; + GIOError error; + + error = read_all (fd, channel, (gchar *) &seq, sizeof (seq), &nb); + if (error == G_IO_ERROR_NONE) + { + if (nb == 0) + { + g_debug ("gio-test: ...from %d: EOF", fd); + shutdown_source (data); + return FALSE; + } + + g_assert (nb == sizeof (nbytes)); + + for (i = 0; i < nkiddies; i++) + if (seqtab[i].fd == fd) + { + g_assert_cmpint (seq, ==, seqtab[i].seq); + seqtab[i].seq++; + break; + } + + error = read_all (fd, channel, (gchar *) &nbytes, sizeof (nbytes), &nb); + } + + if (error != G_IO_ERROR_NONE) + return FALSE; + + if (nb == 0) + { + g_debug ("gio-test: ...from %d: EOF", fd); + shutdown_source (data); + return FALSE; + } + + g_assert (nb == sizeof (nbytes)); + + g_assert_cmpint (nbytes, <, BUFSIZE); + g_assert (nbytes < BUFSIZE); + g_debug ("gio-test: ...from %d: %d bytes", fd, nbytes); + if (nbytes > 0) + { + error = read_all (fd, channel, buf, nbytes, &nb); + + if (error != G_IO_ERROR_NONE) + return FALSE; + + if (nb == 0) + { + g_debug ("gio-test: ...from %d: EOF", fd); + shutdown_source (data); + return FALSE; + } + + for (j = 0; j < nbytes; j++) + g_assert (buf[j] == ' ' + (char) ((nbytes + j) % 95)); + g_debug ("gio-test: ...from %d: OK", fd); + } + } + return retval; +} + +#ifdef G_OS_WIN32 + +static gboolean +recv_windows_message (GIOChannel *channel, + GIOCondition cond, + gpointer data) +{ + GIOError error; + MSG msg; + gsize nb; + + while (1) + { + error = g_io_channel_read (channel, (gchar *) &msg, sizeof (MSG), &nb); + + if (error != G_IO_ERROR_NONE) + { + g_print ("gio-test: ...reading Windows message: G_IO_ERROR_%s\n", + (error == G_IO_ERROR_AGAIN ? "AGAIN" : + (error == G_IO_ERROR_INVAL ? "INVAL" : + (error == G_IO_ERROR_UNKNOWN ? "UNKNOWN" : "???")))); + if (error == G_IO_ERROR_AGAIN) + continue; + } + break; + } + + g_print ("gio-test: ...Windows message for 0x%p: %d,%" G_GUINTPTR_FORMAT ",%" G_GINTPTR_FORMAT "\n", + msg.hwnd, msg.message, msg.wParam, (gintptr)msg.lParam); + + return TRUE; +} + +LRESULT CALLBACK window_procedure (HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam); + +LRESULT CALLBACK +window_procedure (HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + g_print ("gio-test: window_procedure for 0x%p: %d,%" G_GUINTPTR_FORMAT ",%" G_GINTPTR_FORMAT "\n", + hwnd, message, wparam, (gintptr)lparam); + return DefWindowProc (hwnd, message, wparam, lparam); +} + +#endif + +int +main (int argc, + char **argv) +{ + if (argc < 3) + { + /* Parent */ + + GIOChannel *my_read_channel; + gchar *cmdline; + int i; +#ifdef G_OS_WIN32 + GTimeVal start, end; + GPollFD pollfd; + int pollresult; + ATOM klass; + static WNDCLASS wcl; + HWND hwnd; + GIOChannel *windows_messages_channel; +#endif + + nkiddies = (argc == 1 ? 1 : atoi(argv[1])); + seqtab = g_malloc (nkiddies * 2 * sizeof (int)); + +#ifdef G_OS_WIN32 + wcl.style = 0; + wcl.lpfnWndProc = window_procedure; + wcl.cbClsExtra = 0; + wcl.cbWndExtra = 0; + wcl.hInstance = GetModuleHandle (NULL); + wcl.hIcon = NULL; + wcl.hCursor = NULL; + wcl.hbrBackground = NULL; + wcl.lpszMenuName = NULL; + wcl.lpszClassName = "gio-test"; + + klass = RegisterClass (&wcl); + + if (!klass) + { + g_print ("gio-test: RegisterClass failed\n"); + exit (1); + } + + hwnd = CreateWindow (MAKEINTATOM(klass), "gio-test", 0, 0, 0, 10, 10, + NULL, NULL, wcl.hInstance, NULL); + if (!hwnd) + { + g_print ("gio-test: CreateWindow failed\n"); + exit (1); + } + + windows_messages_channel = g_io_channel_win32_new_messages ((guint) (guintptr) hwnd); + g_io_add_watch (windows_messages_channel, G_IO_IN, recv_windows_message, 0); +#endif + + for (i = 0; i < nkiddies; i++) + { + int pipe_to_sub[2], pipe_from_sub[2]; + guint *id; + + if (pipe (pipe_to_sub) == -1 || + pipe (pipe_from_sub) == -1) + perror ("pipe"), exit (1); + + seqtab[i].fd = pipe_from_sub[0]; + seqtab[i].seq = 0; + + my_read_channel = g_io_channel_unix_new (pipe_from_sub[0]); + + id = g_new (guint, 1); + *id = + g_io_add_watch_full (my_read_channel, + G_PRIORITY_DEFAULT, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + recv_message, + id, g_free); + + nrunning++; + +#ifdef G_OS_WIN32 + cmdline = g_strdup_printf ("%d:%d:0x%p", + pipe_to_sub[0], + pipe_from_sub[1], + hwnd); + _spawnl (_P_NOWAIT, argv[0], argv[0], "--child", cmdline, NULL); +#else + cmdline = g_strdup_printf ("%s --child %d:%d &", argv[0], + pipe_to_sub[0], pipe_from_sub[1]); + + system (cmdline); + g_free (cmdline); +#endif + close (pipe_to_sub[0]); + close (pipe_from_sub [1]); + +#ifdef G_OS_WIN32 + g_get_current_time (&start); + g_io_channel_win32_make_pollfd (my_read_channel, G_IO_IN, &pollfd); + pollresult = g_io_channel_win32_poll (&pollfd, 1, 100); + g_get_current_time (&end); + if (end.tv_usec < start.tv_usec) + end.tv_sec--, end.tv_usec += 1000000; + g_print ("gio-test: had to wait %ld.%03ld s, result:%d\n", + end.tv_sec - start.tv_sec, + (end.tv_usec - start.tv_usec) / 1000, + pollresult); +#endif + g_io_channel_unref (my_read_channel); + } + + main_loop = g_main_loop_new (NULL, FALSE); + + g_main_loop_run (main_loop); + + g_main_loop_unref (main_loop); + g_free (seqtab); + } + else if (argc == 3) + { + /* Child */ + + int readfd, writefd; +#ifdef G_OS_WIN32 + HWND hwnd; +#endif + int i, j; + char buf[BUFSIZE]; + int buflen; + GTimeVal tv; + int n; + + g_get_current_time (&tv); + + sscanf (argv[2], "%d:%d%n", &readfd, &writefd, &n); + +#ifdef G_OS_WIN32 + sscanf (argv[2] + n, ":0x%p", &hwnd); +#endif + + srand (tv.tv_sec ^ (tv.tv_usec / 1000) ^ readfd ^ (writefd << 4)); + + for (i = 0; i < 20 + rand() % 20; i++) + { + g_usleep (100 + (rand() % 10) * 5000); + buflen = rand() % BUFSIZE; + for (j = 0; j < buflen; j++) + buf[j] = ' ' + ((buflen + j) % 95); + g_debug ("gio-test: child writing %d+%d bytes to %d", + (int)(sizeof(i) + sizeof(buflen)), buflen, writefd); + write (writefd, &i, sizeof (i)); + write (writefd, &buflen, sizeof (buflen)); + write (writefd, buf, buflen); + +#ifdef G_OS_WIN32 + if (rand() % 100 < 5) + { + int msg = WM_USER + (rand() % 100); + WPARAM wparam = rand (); + LPARAM lparam = rand (); + g_print ("gio-test: child posting message %d,%" G_GUINTPTR_FORMAT ",%" G_GINTPTR_FORMAT " to 0x%p\n", + msg, wparam, (gintptr)lparam, hwnd); + PostMessage (hwnd, msg, wparam, lparam); + } +#endif + } + g_debug ("gio-test: child exiting, closing %d", writefd); + close (writefd); + } + else + g_print ("Huh?\n"); + + return 0; +} diff --git a/tests/gobject/.gitignore b/tests/gobject/.gitignore new file mode 100644 index 0000000..120092d --- /dev/null +++ b/tests/gobject/.gitignore @@ -0,0 +1,15 @@ +accumulator +defaultiface +dynamictype +gvalue-test +ifacecheck +ifaceinherit +ifaceinit +ifaceproperties +override +paramspec-test +performance +performance-threaded +references +signals +singleton diff --git a/tests/gobject/accumulator.c b/tests/gobject/accumulator.c new file mode 100644 index 0000000..a418151 --- /dev/null +++ b/tests/gobject/accumulator.c @@ -0,0 +1,307 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001, 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestAccumulator" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#include + +#include + +#include "testmarshal.h" +#include "testcommon.h" + +/* What this test tests is the behavior of signal accumulators + * Two accumulators are tested: + * + * 1: A custom accumulator that appends the returned strings + * 2: The standard g_signal_accumulator_true_handled that stops + * emission on TRUE returns. + */ + +/* + * TestObject, a parent class for TestObject + */ +#define TEST_TYPE_OBJECT (test_object_get_type ()) +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; + +struct _TestObject +{ + GObject parent_instance; +}; +struct _TestObjectClass +{ + GObjectClass parent_class; + + gchar* (*test_signal1) (TestObject *tobject, + gint param); + gboolean (*test_signal2) (TestObject *tobject, + gint param); + GVariant* (*test_signal3) (TestObject *tobject, + gboolean *weak_ptr); +}; + +static GType test_object_get_type (void); + +static gboolean +test_signal1_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + const gchar *accu_string = g_value_get_string (return_accu); + const gchar *new_string = g_value_get_string (handler_return); + gchar *result_string; + + if (accu_string) + result_string = g_strconcat (accu_string, new_string, NULL); + else if (new_string) + result_string = g_strdup (new_string); + else + result_string = NULL; + + g_value_set_string_take_ownership (return_accu, result_string); + + return TRUE; +} + +static gchar * +test_object_signal1_callback_before (TestObject *tobject, + gint param, + gpointer data) +{ + return g_strdup (""); +} + +static gchar * +test_object_real_signal1 (TestObject *tobject, + gint param) +{ + return g_strdup (""); +} + +static gchar * +test_object_signal1_callback_after (TestObject *tobject, + gint param, + gpointer data) +{ + return g_strdup (""); +} + +static gboolean +test_object_signal2_callback_before (TestObject *tobject, + gint param) +{ + switch (param) + { + case 1: return TRUE; + case 2: return FALSE; + case 3: return FALSE; + case 4: return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +static gboolean +test_object_real_signal2 (TestObject *tobject, + gint param) +{ + switch (param) + { + case 1: g_assert_not_reached (); return FALSE; + case 2: return TRUE; + case 3: return FALSE; + case 4: return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +static gboolean +test_object_signal2_callback_after (TestObject *tobject, + gint param) +{ + switch (param) + { + case 1: g_assert_not_reached (); return FALSE; + case 2: g_assert_not_reached (); return FALSE; + case 3: return TRUE; + case 4: return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +static gboolean +test_signal3_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + GVariant *variant; + + variant = g_value_get_variant (handler_return); + g_assert (!g_variant_is_floating (variant)); + + g_value_set_variant (return_accu, variant); + + return variant == NULL; +} + +/* To be notified when the variant is finalised, we construct + * it from data with a custom GDestroyNotify. + */ + +typedef struct { + char *mem; + gsize n; + gboolean *weak_ptr; +} VariantData; + +static void +free_data (VariantData *data) +{ + *(data->weak_ptr) = TRUE; + g_free (data->mem); + g_slice_free (VariantData, data); +} + +static GVariant * +test_object_real_signal3 (TestObject *tobject, + gboolean *weak_ptr) +{ + GVariant *variant; + VariantData *data; + + variant = g_variant_ref_sink (g_variant_new_uint32 (42)); + data = g_slice_new (VariantData); + data->weak_ptr = weak_ptr; + data->n = g_variant_get_size (variant); + data->mem = g_malloc (data->n); + g_variant_store (variant, data->mem); + g_variant_unref (variant); + + variant = g_variant_new_from_data (G_VARIANT_TYPE ("u"), + data->mem, + data->n, + TRUE, + (GDestroyNotify) free_data, + data); + return g_variant_ref_sink (variant); +} + +static void +test_object_class_init (TestObjectClass *class) +{ + class->test_signal1 = test_object_real_signal1; + class->test_signal2 = test_object_real_signal2; + class->test_signal3 = test_object_real_signal3; + + g_signal_new ("test-signal1", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestObjectClass, test_signal1), + test_signal1_accumulator, NULL, + test_marshal_STRING__INT, + G_TYPE_STRING, 1, G_TYPE_INT); + g_signal_new ("test-signal2", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestObjectClass, test_signal2), + g_signal_accumulator_true_handled, NULL, + test_marshal_BOOLEAN__INT, + G_TYPE_BOOLEAN, 1, G_TYPE_INT); + g_signal_new ("test-signal3", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestObjectClass, test_signal3), + test_signal3_accumulator, NULL, + test_marshal_VARIANT__POINTER, + G_TYPE_VARIANT, 1, G_TYPE_POINTER); +} + +static DEFINE_TYPE(TestObject, test_object, + test_object_class_init, NULL, NULL, + G_TYPE_OBJECT) + +int +main (int argc, + char *argv[]) +{ + TestObject *object; + gchar *string_result; + gboolean bool_result; + gboolean variant_finalised; + GVariant *variant_result; + + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + + object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_signal_connect (object, "test-signal1", + G_CALLBACK (test_object_signal1_callback_before), NULL); + g_signal_connect_after (object, "test-signal1", + G_CALLBACK (test_object_signal1_callback_after), NULL); + + g_signal_emit_by_name (object, "test-signal1", 0, &string_result); + g_assert (strcmp (string_result, "") == 0); + g_free (string_result); + + g_signal_connect (object, "test-signal2", + G_CALLBACK (test_object_signal2_callback_before), NULL); + g_signal_connect_after (object, "test-signal2", + G_CALLBACK (test_object_signal2_callback_after), NULL); + + bool_result = FALSE; + g_signal_emit_by_name (object, "test-signal2", 1, &bool_result); + g_assert (bool_result == TRUE); + bool_result = FALSE; + g_signal_emit_by_name (object, "test-signal2", 2, &bool_result); + g_assert (bool_result == TRUE); + bool_result = FALSE; + g_signal_emit_by_name (object, "test-signal2", 3, &bool_result); + g_assert (bool_result == TRUE); + bool_result = TRUE; + g_signal_emit_by_name (object, "test-signal2", 4, &bool_result); + g_assert (bool_result == FALSE); + + variant_finalised = FALSE; + variant_result = NULL; + g_signal_emit_by_name (object, "test-signal3", &variant_finalised, &variant_result); + g_assert (variant_result != NULL); + g_assert (!g_variant_is_floating (variant_result)); + + /* Test that variant_result had refcount 1 */ + g_assert (!variant_finalised); + g_variant_unref (variant_result); + g_assert (variant_finalised); + + g_object_unref (object); + + return 0; +} diff --git a/tests/gobject/defaultiface.c b/tests/gobject/defaultiface.c new file mode 100644 index 0000000..92e45ce --- /dev/null +++ b/tests/gobject/defaultiface.c @@ -0,0 +1,199 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001, 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestDefaultIface" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#include + +#include "testcommon.h" +#include "testmodule.h" + +/* This test tests getting the default vtable for an interface + * and the initialization and finalization of such default + * interfaces. + * + * We test this both for static and for dynamic interfaces. + */ + +/********************************************************************** + * Static interface tests + **********************************************************************/ + +typedef struct _TestStaticIfaceClass TestStaticIfaceClass; + +struct _TestStaticIfaceClass +{ + GTypeInterface base_iface; + guint val; +}; + +GType test_static_iface_get_type (void); +#define TEST_TYPE_STATIC_IFACE (test_static_iface_get_type ()) + +static void +test_static_iface_default_init (TestStaticIfaceClass *iface) +{ + iface->val = 42; +} + +DEFINE_IFACE (TestStaticIface, test_static_iface, + NULL, test_static_iface_default_init) + +static void +test_static_iface (void) +{ + TestStaticIfaceClass *static_iface; + + /* Not loaded until we call ref for the first time */ + static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE); + g_assert (static_iface == NULL); + + /* Ref loads */ + static_iface = g_type_default_interface_ref (TEST_TYPE_STATIC_IFACE); + g_assert (static_iface && static_iface->val == 42); + + /* Peek then works */ + static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE); + g_assert (static_iface && static_iface->val == 42); + + /* Unref does nothing */ + g_type_default_interface_unref (static_iface); + + /* And peek still works */ + static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE); + g_assert (static_iface && static_iface->val == 42); +} + +/********************************************************************** + * Dynamic interface tests + **********************************************************************/ + +typedef struct _TestDynamicIfaceClass TestDynamicIfaceClass; + +struct _TestDynamicIfaceClass +{ + GTypeInterface base_iface; + guint val; +}; + +static GType test_dynamic_iface_type; +static gboolean dynamic_iface_init = FALSE; + +#define TEST_TYPE_DYNAMIC_IFACE (test_dynamic_iface_type) + +static void +test_dynamic_iface_default_init (TestStaticIfaceClass *iface) +{ + dynamic_iface_init = TRUE; + iface->val = 42; +} + +static void +test_dynamic_iface_default_finalize (TestStaticIfaceClass *iface) +{ + dynamic_iface_init = FALSE; +} + +static void +test_dynamic_iface_register (GTypeModule *module) +{ + const GTypeInfo iface_info = + { + sizeof (TestDynamicIfaceClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) test_dynamic_iface_default_init, + (GClassFinalizeFunc) test_dynamic_iface_default_finalize, + NULL, + 0, + 0, + NULL, + NULL + }; + + test_dynamic_iface_type = g_type_module_register_type (module, G_TYPE_INTERFACE, + "TestDynamicIface", &iface_info, 0); +} + +static void +module_register (GTypeModule *module) +{ + test_dynamic_iface_register (module); +} + +static void +test_dynamic_iface (void) +{ + TestDynamicIfaceClass *dynamic_iface; + + test_module_new (module_register); + + /* Not loaded until we call ref for the first time */ + dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE); + g_assert (dynamic_iface == NULL); + + /* Ref loads */ + dynamic_iface = g_type_default_interface_ref (TEST_TYPE_DYNAMIC_IFACE); + g_assert (dynamic_iface_init); + g_assert (dynamic_iface && dynamic_iface->val == 42); + + /* Peek then works */ + dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE); + g_assert (dynamic_iface && dynamic_iface->val == 42); + + /* Unref causes finalize */ + g_type_default_interface_unref (dynamic_iface); +#if 0 + g_assert (!dynamic_iface_init); +#endif + + /* Peek returns NULL */ + dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE); +#if 0 + g_assert (dynamic_iface == NULL); +#endif + + /* Ref reloads */ + dynamic_iface = g_type_default_interface_ref (TEST_TYPE_DYNAMIC_IFACE); + g_assert (dynamic_iface_init); + g_assert (dynamic_iface && dynamic_iface->val == 42); + + /* And Unref causes finalize once more*/ + g_type_default_interface_unref (dynamic_iface); +#if 0 + g_assert (!dynamic_iface_init); +#endif +} + +int +main (int argc, + char *argv[]) +{ + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + + test_static_iface (); + test_dynamic_iface (); + + return 0; +} diff --git a/tests/gobject/deftype.c b/tests/gobject/deftype.c new file mode 100644 index 0000000..773aaa1 --- /dev/null +++ b/tests/gobject/deftype.c @@ -0,0 +1,59 @@ +/* deftype.c + * Copyright (C) 2006 Behdad Esfahbod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#include + +/* see http://bugzilla.gnome.org/show_bug.cgi?id=337128 for the purpose of this test */ + +#define MY_G_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) { \ + const GInterfaceInfo g_implement_interface_info = { \ + (GInterfaceInitFunc) iface_init, \ + NULL, \ + NULL \ + }; \ + g_type_add_interface_static (g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \ +} + +#define MY_DEFINE_TYPE(TN, t_n, T_P) \ + G_DEFINE_TYPE_WITH_CODE (TN, t_n, T_P, \ + MY_G_IMPLEMENT_INTERFACE (G_TYPE_INTERFACE, NULL)) + +typedef struct _TypeName { + GObject parent_instance; + const char *name; +} TypeName; + +typedef struct _TypeNameClass { + GObjectClass parent_parent; +} TypeNameClass; + +GType type_name_get_type (void); + +MY_DEFINE_TYPE (TypeName, type_name, G_TYPE_OBJECT) + +static void type_name_init (TypeName *self) +{ +} + +static void type_name_class_init (TypeNameClass *klass) +{ +} + +int +main (void) +{ + return 0; +} diff --git a/tests/gobject/dynamictype.c b/tests/gobject/dynamictype.c new file mode 100644 index 0000000..c3db276 --- /dev/null +++ b/tests/gobject/dynamictype.c @@ -0,0 +1,175 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001, 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestDynamicType" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#include + +#include "testcommon.h" +#include "testmodule.h" + +/* This test tests the macros for defining dynamic types. + */ + +static gboolean loaded = FALSE; + +struct _TestIfaceClass +{ + GTypeInterface base_iface; + guint val; +}; + +static GType test_iface_get_type (void); +#define TEST_TYPE_IFACE (test_iface_get_type ()) +#define TEST_IFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE, TestIfaceClass)) +typedef struct _TestIface TestIface; +typedef struct _TestIfaceClass TestIfaceClass; + +static void test_iface_base_init (TestIfaceClass *iface); +static void test_iface_default_init (TestIfaceClass *iface, gpointer class_data); + +static DEFINE_IFACE(TestIface, test_iface, test_iface_base_init, test_iface_default_init) + +static void +test_iface_default_init (TestIfaceClass *iface, + gpointer class_data) +{ +} + +static void +test_iface_base_init (TestIfaceClass *iface) +{ +} + +GType dynamic_object_get_type (void); +#define DYNAMIC_OBJECT_TYPE (dynamic_object_get_type ()) + +typedef GObject DynamicObject; +typedef struct _DynamicObjectClass DynamicObjectClass; + +struct _DynamicObjectClass +{ + GObjectClass parent_class; + guint val; +}; + +static void dynamic_object_iface_init (TestIface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED(DynamicObject, dynamic_object, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (TEST_TYPE_IFACE, + dynamic_object_iface_init)); + +static void +dynamic_object_class_init (DynamicObjectClass *class) +{ + class->val = 42; + loaded = TRUE; +} + +static void +dynamic_object_class_finalize (DynamicObjectClass *class) +{ + loaded = FALSE; +} + +static void +dynamic_object_iface_init (TestIface *iface) +{ +} + +static void +dynamic_object_init (DynamicObject *dynamic_object) +{ +} + +static void +module_register (GTypeModule *module) +{ + dynamic_object_register_type (module); +} + +static void +test_dynamic_type (void) +{ + DynamicObjectClass *class; + + test_module_new (module_register); + + /* Not loaded until we call ref for the first time */ + class = g_type_class_peek (DYNAMIC_OBJECT_TYPE); + g_assert (class == NULL); + g_assert (!loaded); + + /* Make sure interfaces work */ + g_assert (g_type_is_a (DYNAMIC_OBJECT_TYPE, + TEST_TYPE_IFACE)); + + /* Ref loads */ + class = g_type_class_ref (DYNAMIC_OBJECT_TYPE); + g_assert (class && class->val == 42); + g_assert (loaded); + + /* Peek then works */ + class = g_type_class_peek (DYNAMIC_OBJECT_TYPE); + g_assert (class && class->val == 42); + g_assert (loaded); + + /* Make sure interfaces still work */ + g_assert (g_type_is_a (DYNAMIC_OBJECT_TYPE, + TEST_TYPE_IFACE)); + + /* Unref causes finalize */ + g_type_class_unref (class); + + /* Peek returns NULL */ + class = g_type_class_peek (DYNAMIC_OBJECT_TYPE); +#if 0 + g_assert (!class); + g_assert (!loaded); +#endif + + /* Ref reloads */ + class = g_type_class_ref (DYNAMIC_OBJECT_TYPE); + g_assert (class && class->val == 42); + g_assert (loaded); + + /* And Unref causes finalize once more*/ + g_type_class_unref (class); + class = g_type_class_peek (DYNAMIC_OBJECT_TYPE); +#if 0 + g_assert (!class); + g_assert (!loaded); +#endif +} + +int +main (int argc, + char *argv[]) +{ + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + + test_dynamic_type (); + + return 0; +} diff --git a/tests/gobject/meson.build b/tests/gobject/meson.build new file mode 100644 index 0000000..a02480e --- /dev/null +++ b/tests/gobject/meson.build @@ -0,0 +1,98 @@ +# We cannot use gnome.genmarshal() here +testmarshal_h = custom_target('testmarshal_h', + output : 'testmarshal.h', + input : 'testmarshal.list', + command : [ + python, glib_genmarshal, + '--prefix=test_marshal', + '--output=@OUTPUT@', + '--quiet', + '--header', + '@INPUT@', + ], +) + +testmarshal_c = custom_target('testmarshal_c', + output : 'testmarshal.c', + input : 'testmarshal.list', + command : [ + python, glib_genmarshal, + '--prefix=test_marshal', + '--include-header=testmarshal.h', + '--output=@OUTPUT@', + '--quiet', + '--body', + '@INPUT@', + ], +) + +gobject_tests = { + 'deftype' : {}, + 'defaultiface' : { + 'extra_sources' : ['testmodule.c'], + }, + 'dynamictype' : { + 'extra_sources' : ['testmodule.c'], + }, + 'override' : {}, + 'signals' : {}, + 'singleton' : {}, + 'references' : {}, + 'testgobject' : {}, + 'accumulator' : { + 'extra_sources' : [testmarshal_c, testmarshal_h], + }, +} + +if host_system != 'windows' + gobject_tests += { + 'timeloop-closure' : {}, + } +endif + +common_c_args = test_cargs + ['-DGLIB_DISABLE_DEPRECATION_WARNINGS'] +common_deps = [libm, thread_dep, libglib_dep, libgobject_dep] + +foreach test_name, extra_args : gobject_tests + source = extra_args.get('source', test_name + '.c') + extra_sources = extra_args.get('extra_sources', []) + install = installed_tests_enabled and extra_args.get('install', true) + template = extra_args.get('tap', false) ? installed_tests_template_tap : installed_tests_template + + if install + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_conf.set('env', '') + configure_file( + input: template, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf + ) + endif + + # FIXME? $(GLIB_DEBUG_FLAGS) + exe = executable(test_name, [source, extra_sources], + c_args : common_c_args + extra_args.get('c_args', []), + dependencies : common_deps + extra_args.get('dependencies', []), + install_dir: installed_tests_execdir, + install: install, + ) + + suite = ['gobject'] + extra_args.get('suite', []) + timeout = suite.contains('slow') ? test_timeout_slow : test_timeout + # FIXME? TESTS_ENVIRONMENT = LIBCHARSET_ALIAS_DIR=$(top_builddir)/glib/libcharset + test(test_name, exe, env : test_env, timeout : timeout, suite : suite) +endforeach + +# Don't install these ones, and keep them out of 'make check' because they take too long... +executable('performance', 'performance.c', + c_args : common_c_args, + dependencies : common_deps, + install : false) + +executable('performance-threaded', 'performance-threaded.c', + c_args : common_c_args, + dependencies : common_deps, + install : false) diff --git a/tests/gobject/override.c b/tests/gobject/override.c new file mode 100644 index 0000000..d048a46 --- /dev/null +++ b/tests/gobject/override.c @@ -0,0 +1,418 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * override.c: Closure override test program + * Copyright (C) 2001, James Henstridge + * Copyright (C) 2003, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestOverride" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#undef VERBOSE + +#include + +#include +#include + +#include "testcommon.h" + +static guint foo_signal_id = 0; +static guint bar_signal_id = 0; +static guint baz_signal_id = 0; + +static GType test_i_get_type (void); +static GType test_a_get_type (void); +static GType test_b_get_type (void); +static GType test_c_get_type (void); + +static void record (const gchar *str); + +#define TEST_TYPE_I (test_i_get_type ()) + +typedef struct _TestI TestI; +typedef struct _TestIClass TestIClass; + +struct _TestIClass +{ + GTypeInterface base_iface; +}; + +static void +test_i_foo (TestI *self) +{ + record ("TestI::foo"); +} + +static void +test_i_default_init (gpointer g_class) +{ + foo_signal_id = g_signal_newv ("foo", + TEST_TYPE_I, + G_SIGNAL_RUN_LAST, + g_cclosure_new(G_CALLBACK(test_i_foo), + NULL, NULL), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, NULL); +} + +static DEFINE_IFACE (TestI, test_i, NULL, test_i_default_init) + +#define TEST_TYPE_A (test_a_get_type()) + + typedef struct _TestA TestA; + typedef struct _TestAClass TestAClass; + +struct _TestA { + GObject parent; +}; +struct _TestAClass { + GObjectClass parent_class; + + void (* bar) (TestA *self); +}; + +static void +test_a_foo (TestI *self) +{ + GValue args[1] = { G_VALUE_INIT }; + + record ("TestA::foo"); + + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); + + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); + + g_value_unset (&args[0]); +} + +static void +test_a_bar (TestA *self) +{ + record ("TestA::bar"); +} + +static gchar * +test_a_baz (TestA *self, + GObject *object, + gpointer pointer) +{ + record ("TestA::baz"); + + g_assert (object == G_OBJECT (self)); + g_assert (GPOINTER_TO_INT (pointer) == 23); + + return g_strdup ("TestA::baz"); +} + +static void +test_a_class_init (TestAClass *class) +{ + class->bar = test_a_bar; + + bar_signal_id = g_signal_new ("bar", + TEST_TYPE_A, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestAClass, bar), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, NULL); + + baz_signal_id = g_signal_new_class_handler ("baz", + TEST_TYPE_A, + G_SIGNAL_RUN_LAST, + G_CALLBACK (test_a_baz), + NULL, NULL, + g_cclosure_marshal_STRING__OBJECT_POINTER, + G_TYPE_STRING, 2, + G_TYPE_OBJECT, + G_TYPE_POINTER); +} + +static void +test_a_interface_init (TestIClass *iface) +{ + g_signal_override_class_closure (foo_signal_id, + TEST_TYPE_A, + g_cclosure_new (G_CALLBACK (test_a_foo), + NULL, NULL)); +} + +static DEFINE_TYPE_FULL (TestA, test_a, + test_a_class_init, NULL, NULL, + G_TYPE_OBJECT, + INTERFACE (test_a_interface_init, TEST_TYPE_I)) + +#define TEST_TYPE_B (test_b_get_type()) + +typedef struct _TestB TestB; +typedef struct _TestBClass TestBClass; + +struct _TestB { + TestA parent; +}; +struct _TestBClass { + TestAClass parent_class; +}; + +static void +test_b_foo (TestI *self) +{ + GValue args[1] = { G_VALUE_INIT }; + + record ("TestB::foo"); + + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); + + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); + + g_value_unset (&args[0]); +} + +static void +test_b_bar (TestA *self) +{ + GValue args[1] = { G_VALUE_INIT }; + + record ("TestB::bar"); + + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); + + g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); + g_signal_chain_from_overridden (args, NULL); + + g_value_unset (&args[0]); +} + +static gchar * +test_b_baz (TestA *self, + GObject *object, + gpointer pointer) +{ + gchar *retval = NULL; + + record ("TestB::baz"); + + g_assert (object == G_OBJECT (self)); + g_assert (GPOINTER_TO_INT (pointer) == 23); + + g_signal_chain_from_overridden_handler (self, object, pointer, &retval); + + if (retval) + { + gchar *tmp = g_strconcat (retval , ",TestB::baz", NULL); + g_free (retval); + retval = tmp; + } + + return retval; +} + +static void +test_b_class_init (TestBClass *class) +{ + g_signal_override_class_closure (foo_signal_id, + TEST_TYPE_B, + g_cclosure_new (G_CALLBACK (test_b_foo), + NULL, NULL)); + g_signal_override_class_closure (bar_signal_id, + TEST_TYPE_B, + g_cclosure_new (G_CALLBACK (test_b_bar), + NULL, NULL)); + g_signal_override_class_handler ("baz", + TEST_TYPE_B, + G_CALLBACK (test_b_baz)); +} + +static DEFINE_TYPE (TestB, test_b, + test_b_class_init, NULL, NULL, + TEST_TYPE_A) + +#define TEST_TYPE_C (test_c_get_type()) + +typedef struct _TestC TestC; +typedef struct _TestCClass TestCClass; + +struct _TestC { + TestB parent; +}; +struct _TestCClass { + TestBClass parent_class; +}; + +static void +test_c_foo (TestI *self) +{ + GValue args[1] = { G_VALUE_INIT }; + + record ("TestC::foo"); + + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); + + g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); + g_signal_chain_from_overridden (args, NULL); + + g_value_unset (&args[0]); +} + +static void +test_c_bar (TestA *self) +{ + GValue args[1] = { G_VALUE_INIT }; + + record ("TestC::bar"); + + g_value_init (&args[0], TEST_TYPE_A); + g_value_set_object (&args[0], self); + + g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); + g_signal_chain_from_overridden (args, NULL); + + g_value_unset (&args[0]); +} + +static gchar * +test_c_baz (TestA *self, + GObject *object, + gpointer pointer) +{ + gchar *retval = NULL; + + record ("TestC::baz"); + + g_assert (object == G_OBJECT (self)); + g_assert (GPOINTER_TO_INT (pointer) == 23); + + g_signal_chain_from_overridden_handler (self, object, pointer, &retval); + + if (retval) + { + gchar *tmp = g_strconcat (retval , ",TestC::baz", NULL); + g_free (retval); + retval = tmp; + } + + return retval; +} + +static void +test_c_class_init (TestBClass *class) +{ + g_signal_override_class_closure (foo_signal_id, + TEST_TYPE_C, + g_cclosure_new (G_CALLBACK (test_c_foo), + NULL, NULL)); + g_signal_override_class_closure (bar_signal_id, + TEST_TYPE_C, + g_cclosure_new (G_CALLBACK (test_c_bar), + NULL, NULL)); + g_signal_override_class_handler ("baz", + TEST_TYPE_C, + G_CALLBACK (test_c_baz)); +} + + +static DEFINE_TYPE (TestC, test_c, + test_c_class_init, NULL, NULL, + TEST_TYPE_B) + +static GString *test_string = NULL; +gboolean failed = FALSE; + +static void +record (const gchar *str) +{ + if (test_string->len) + g_string_append_c (test_string, ','); + g_string_append (test_string, str); +} + +static void +test (GType type, + const gchar *signal, + const gchar *expected, + const gchar *expected_retval) +{ + GObject *self = g_object_new (type, NULL); + + test_string = g_string_new (NULL); + + if (strcmp (signal, "baz")) + { + g_signal_emit_by_name (self, signal); + } + else + { + gchar *ret; + + g_signal_emit_by_name (self, signal, self, GINT_TO_POINTER (23), &ret); + + if (strcmp (ret, expected_retval) != 0) + failed = TRUE; + + g_free (ret); + } + +#ifndef VERBOSE + if (strcmp (test_string->str, expected) != 0) +#endif + { + g_printerr ("*** emitting %s on a %s instance\n" + " Expecting: %s\n" + " Got: %s\n", + signal, g_type_name (type), + expected, + test_string->str); + + if (strcmp (test_string->str, expected) != 0) + failed = TRUE; + } + + g_string_free (test_string, TRUE); + g_object_unref (self); +} + +int +main (int argc, char **argv) +{ + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + + test (TEST_TYPE_A, "foo", "TestA::foo,TestI::foo", NULL); + test (TEST_TYPE_A, "bar", "TestA::bar", NULL); + test (TEST_TYPE_A, "baz", "TestA::baz", "TestA::baz"); + + test (TEST_TYPE_B, "foo", "TestB::foo,TestA::foo,TestI::foo", NULL); + test (TEST_TYPE_B, "bar", "TestB::bar,TestA::bar", NULL); + test (TEST_TYPE_B, "baz", "TestB::baz,TestA::baz", "TestA::baz,TestB::baz"); + + test (TEST_TYPE_C, "foo", "TestC::foo,TestB::foo,TestA::foo,TestI::foo", NULL); + test (TEST_TYPE_C, "bar", "TestC::bar,TestB::bar,TestA::bar", NULL); + test (TEST_TYPE_C, "baz", "TestC::baz,TestB::baz,TestA::baz", "TestA::baz,TestB::baz,TestC::baz"); + + return failed ? 1 : 0; +} diff --git a/tests/gobject/performance-threaded.c b/tests/gobject/performance-threaded.c new file mode 100644 index 0000000..af8cc79 --- /dev/null +++ b/tests/gobject/performance-threaded.c @@ -0,0 +1,375 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include +#include +#include +#include "testcommon.h" + +#define DEFAULT_TEST_TIME 2 /* seconds */ + +static GType +simple_register_class (const char *name, GType parent, ...) +{ + GInterfaceInfo interface_info = { NULL, NULL, NULL }; + va_list args; + GType type, interface; + + va_start (args, parent); + type = g_type_register_static_simple (parent, name, sizeof (GObjectClass), + NULL, parent == G_TYPE_INTERFACE ? 0 : sizeof (GObject), NULL, 0); + for (;;) + { + interface = va_arg (args, GType); + if (interface == 0) + break; + g_type_add_interface_static (type, interface, &interface_info); + } + va_end (args); + + return type; +} + +/* test emulating liststore behavior for interface lookups */ + +static GType liststore; +static GType liststore_interfaces[6]; + +static gpointer +register_types (void) +{ + static gsize inited = 0; + if (g_once_init_enter (&inited)) + { + liststore_interfaces[0] = simple_register_class ("GtkBuildable", G_TYPE_INTERFACE, 0); + liststore_interfaces[1] = simple_register_class ("GtkTreeDragDest", G_TYPE_INTERFACE, 0); + liststore_interfaces[2] = simple_register_class ("GtkTreeModel", G_TYPE_INTERFACE, 0); + liststore_interfaces[3] = simple_register_class ("GtkTreeDragSource", G_TYPE_INTERFACE, 0); + liststore_interfaces[4] = simple_register_class ("GtkTreeSortable", G_TYPE_INTERFACE, 0); + liststore_interfaces[5] = simple_register_class ("UnrelatedInterface", G_TYPE_INTERFACE, 0); + + liststore = simple_register_class ("GtkListStore", G_TYPE_OBJECT, + liststore_interfaces[0], liststore_interfaces[1], liststore_interfaces[2], + liststore_interfaces[3], liststore_interfaces[4], (GType) 0); + + g_once_init_leave (&inited, 1); + } + return NULL; +} + +static void +liststore_is_a_run (gpointer data) +{ + guint i; + + for (i = 0; i < 1000; i++) + { + g_assert (g_type_is_a (liststore, liststore_interfaces[0])); + g_assert (g_type_is_a (liststore, liststore_interfaces[1])); + g_assert (g_type_is_a (liststore, liststore_interfaces[2])); + g_assert (g_type_is_a (liststore, liststore_interfaces[3])); + g_assert (g_type_is_a (liststore, liststore_interfaces[4])); + g_assert (!g_type_is_a (liststore, liststore_interfaces[5])); + } +} + +static gpointer +liststore_get_class (void) +{ + register_types (); + return g_type_class_ref (liststore); +} + +static void +liststore_interface_peek_run (gpointer klass) +{ + guint i; + gpointer iface; + + for (i = 0; i < 1000; i++) + { + iface = g_type_interface_peek (klass, liststore_interfaces[0]); + g_assert (iface); + iface = g_type_interface_peek (klass, liststore_interfaces[1]); + g_assert (iface); + iface = g_type_interface_peek (klass, liststore_interfaces[2]); + g_assert (iface); + iface = g_type_interface_peek (klass, liststore_interfaces[3]); + g_assert (iface); + iface = g_type_interface_peek (klass, liststore_interfaces[4]); + g_assert (iface); + } +} + +static void +liststore_interface_peek_same_run (gpointer klass) +{ + guint i; + gpointer iface; + + for (i = 0; i < 1000; i++) + { + iface = g_type_interface_peek (klass, liststore_interfaces[0]); + g_assert (iface); + iface = g_type_interface_peek (klass, liststore_interfaces[0]); + g_assert (iface); + iface = g_type_interface_peek (klass, liststore_interfaces[0]); + g_assert (iface); + iface = g_type_interface_peek (klass, liststore_interfaces[0]); + g_assert (iface); + iface = g_type_interface_peek (klass, liststore_interfaces[0]); + g_assert (iface); + } +} + +#if 0 +/* DUMB test doing nothing */ + +static gpointer +no_setup (void) +{ + return NULL; +} + +static void +no_run (gpointer data) +{ +} +#endif + +static void +no_reset (gpointer data) +{ +} + +static void +no_teardown (gpointer data) +{ +} + +typedef struct _PerformanceTest PerformanceTest; +struct _PerformanceTest { + const char *name; + + gpointer (*setup) (void); + void (*run) (gpointer data); + void (*reset) (gpointer data); + void (*teardown) (gpointer data); +}; + +static const PerformanceTest tests[] = { + { "liststore-is-a", + register_types, + liststore_is_a_run, + no_reset, + no_teardown }, + { "liststore-interface-peek", + liststore_get_class, + liststore_interface_peek_run, + no_reset, + g_type_class_unref }, + { "liststore-interface-peek-same", + liststore_get_class, + liststore_interface_peek_same_run, + no_reset, + g_type_class_unref }, +#if 0 + { "nothing", + no_setup, + no_run, + no_reset, + no_teardown } +#endif +}; + +static gboolean verbose = FALSE; +static guint n_threads = 0; +static gboolean list = FALSE; +static int test_length = DEFAULT_TEST_TIME; + +static GOptionEntry cmd_entries[] = { + {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, + "Print extra information", NULL}, + {"threads", 't', 0, G_OPTION_ARG_INT, &n_threads, + "number of threads to run in parallel", NULL}, + {"seconds", 's', 0, G_OPTION_ARG_INT, &test_length, + "Time to run each test in seconds", NULL}, + {"list", 'l', 0, G_OPTION_ARG_NONE, &list, + "List all available tests and exit", NULL}, + G_OPTION_ENTRY_NULL +}; + +static gpointer +run_test_thread (gpointer user_data) +{ + const PerformanceTest *test = user_data; + gpointer data; + double elapsed; + GTimer *timer, *total; + GArray *results; + + total = g_timer_new (); + g_timer_start (total); + + /* Set up test */ + timer = g_timer_new (); + data = test->setup (); + results = g_array_new (FALSE, FALSE, sizeof (double)); + + /* Run the test */ + while (g_timer_elapsed (total, NULL) < test_length) + { + g_timer_reset (timer); + g_timer_start (timer); + test->run (data); + g_timer_stop (timer); + elapsed = g_timer_elapsed (timer, NULL); + g_array_append_val (results, elapsed); + test->reset (data); + } + + /* Tear down */ + test->teardown (data); + g_timer_destroy (timer); + g_timer_destroy (total); + + return results; +} + +static int +compare_doubles (gconstpointer a, gconstpointer b) +{ + double d = *(double *) a - *(double *) b; + + if (d < 0) + return -1; + if (d > 0) + return 1; + return 0; +} + +static void +print_results (GArray *array) +{ + double min, max, avg; + guint i; + + g_array_sort (array, compare_doubles); + + /* FIXME: discard outliers */ + + min = g_array_index (array, double, 0) * 1000; + max = g_array_index (array, double, array->len - 1) * 1000; + avg = 0; + for (i = 0; i < array->len; i++) + { + avg += g_array_index (array, double, i); + } + avg = avg / array->len * 1000; + + g_print (" %u runs, min/avg/max = %.3f/%.3f/%.3f ms\n", array->len, min, avg, max); +} + +static void +run_test (const PerformanceTest *test) +{ + GArray *results; + + g_print ("Running test \"%s\"\n", test->name); + + if (n_threads == 0) { + results = run_test_thread ((gpointer) test); + } else { + guint i; + GThread **threads; + GArray *thread_results; + + threads = g_new (GThread *, n_threads); + for (i = 0; i < n_threads; i++) { + threads[i] = g_thread_create (run_test_thread, (gpointer) test, TRUE, NULL); + g_assert (threads[i] != NULL); + } + + results = g_array_new (FALSE, FALSE, sizeof (double)); + for (i = 0; i < n_threads; i++) { + thread_results = g_thread_join (threads[i]); + g_array_append_vals (results, thread_results->data, thread_results->len); + g_array_free (thread_results, TRUE); + } + g_free (threads); + } + + print_results (results); + g_array_free (results, TRUE); +} + +static const PerformanceTest * +find_test (const char *name) +{ + gsize i; + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + if (strcmp (tests[i].name, name) == 0) + return &tests[i]; + } + return NULL; +} + +int +main (int argc, + char *argv[]) +{ + const PerformanceTest *test; + GOptionContext *context; + GError *error = NULL; + gsize i; + + context = g_option_context_new ("GObject performance tests"); + g_option_context_add_main_entries (context, cmd_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + if (list) + { + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + g_print ("%s\n", tests[i].name); + } + return 0; + } + + if (argc > 1) + { + int k; + for (k = 1; k < argc; k++) + { + test = find_test (argv[k]); + if (test) + run_test (test); + } + } + else + { + for (i = 0; i < G_N_ELEMENTS (tests); i++) + run_test (&tests[i]); + } + + return 0; +} diff --git a/tests/gobject/performance.c b/tests/gobject/performance.c new file mode 100644 index 0000000..5208172 --- /dev/null +++ b/tests/gobject/performance.c @@ -0,0 +1,1060 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include +#include +#include +#include "testcommon.h" + +#define WARM_UP_N_RUNS 50 +#define ESTIMATE_ROUND_TIME_N_RUNS 5 +#define DEFAULT_TEST_TIME 15 /* seconds */ + /* The time we want each round to take, in seconds, this should + * be large enough compared to the timer resolution, but small + * enough that the risk of any random slowness will miss the + * running window */ +#define TARGET_ROUND_TIME 0.008 + +static gboolean verbose = FALSE; +static int test_length = DEFAULT_TEST_TIME; + +static GOptionEntry cmd_entries[] = { + {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, + "Print extra information", NULL}, + {"seconds", 's', 0, G_OPTION_ARG_INT, &test_length, + "Time to run each test in seconds", NULL}, + G_OPTION_ENTRY_NULL +}; + +typedef struct _PerformanceTest PerformanceTest; +struct _PerformanceTest { + const char *name; + gpointer extra_data; + + gpointer (*setup) (PerformanceTest *test); + void (*init) (PerformanceTest *test, + gpointer data, + double factor); + void (*run) (PerformanceTest *test, + gpointer data); + void (*finish) (PerformanceTest *test, + gpointer data); + void (*teardown) (PerformanceTest *test, + gpointer data); + void (*print_result) (PerformanceTest *test, + gpointer data, + double time); +}; + +static void +run_test (PerformanceTest *test) +{ + gpointer data = NULL; + guint64 i, num_rounds; + double elapsed, min_elapsed, max_elapsed, avg_elapsed, factor; + GTimer *timer; + + g_print ("Running test %s\n", test->name); + + /* Set up test */ + timer = g_timer_new (); + data = test->setup (test); + + if (verbose) + g_print ("Warming up\n"); + + g_timer_start (timer); + + /* Warm up the test by doing a few runs */ + for (i = 0; i < WARM_UP_N_RUNS; i++) + { + test->init (test, data, 1.0); + test->run (test, data); + test->finish (test, data); + } + + g_timer_stop (timer); + elapsed = g_timer_elapsed (timer, NULL); + + if (verbose) + { + g_print ("Warm up time: %.2f secs\n", elapsed); + g_print ("Estimating round time\n"); + } + + /* Estimate time for one run by doing a few test rounds */ + min_elapsed = 0; + for (i = 0; i < ESTIMATE_ROUND_TIME_N_RUNS; i++) + { + test->init (test, data, 1.0); + g_timer_start (timer); + test->run (test, data); + g_timer_stop (timer); + test->finish (test, data); + + elapsed = g_timer_elapsed (timer, NULL); + if (i == 0) + min_elapsed = elapsed; + else + min_elapsed = MIN (min_elapsed, elapsed); + } + + factor = TARGET_ROUND_TIME / min_elapsed; + + if (verbose) + g_print ("Uncorrected round time: %.4f msecs, correction factor %.2f\n", 1000*min_elapsed, factor); + + /* Calculate number of rounds needed */ + num_rounds = (test_length / TARGET_ROUND_TIME) + 1; + + if (verbose) + g_print ("Running %"G_GINT64_MODIFIER"d rounds\n", num_rounds); + + /* Run the test */ + avg_elapsed = 0.0; + min_elapsed = 0.0; + max_elapsed = 0.0; + for (i = 0; i < num_rounds; i++) + { + test->init (test, data, factor); + g_timer_start (timer); + test->run (test, data); + g_timer_stop (timer); + test->finish (test, data); + elapsed = g_timer_elapsed (timer, NULL); + + if (i == 0) + max_elapsed = min_elapsed = avg_elapsed = elapsed; + else + { + min_elapsed = MIN (min_elapsed, elapsed); + max_elapsed = MAX (max_elapsed, elapsed); + avg_elapsed += elapsed; + } + } + + if (num_rounds > 1) + avg_elapsed = avg_elapsed / num_rounds; + + if (verbose) + { + g_print ("Minimum corrected round time: %.2f msecs\n", min_elapsed * 1000); + g_print ("Maximum corrected round time: %.2f msecs\n", max_elapsed * 1000); + g_print ("Average corrected round time: %.2f msecs\n", avg_elapsed * 1000); + } + + /* Print the results */ + test->print_result (test, data, min_elapsed); + + /* Tear down */ + test->teardown (test, data); + g_timer_destroy (timer); +} + +/************************************************************* + * Simple object is a very simple small GObject subclass + * with no properties, no signals, implementing no interfaces + *************************************************************/ + +static GType simple_object_get_type (void); +#define SIMPLE_TYPE_OBJECT (simple_object_get_type ()) +typedef struct _SimpleObject SimpleObject; +typedef struct _SimpleObjectClass SimpleObjectClass; + +struct _SimpleObject +{ + GObject parent_instance; + int val; +}; + +struct _SimpleObjectClass +{ + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (SimpleObject, simple_object, G_TYPE_OBJECT) + +static void +simple_object_finalize (GObject *object) +{ + G_OBJECT_CLASS (simple_object_parent_class)->finalize (object); +} + +static void +simple_object_class_init (SimpleObjectClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = simple_object_finalize; +} + +static void +simple_object_init (SimpleObject *simple_object) +{ + simple_object->val = 42; +} + +typedef struct _TestIfaceClass TestIfaceClass; +typedef struct _TestIfaceClass TestIface1Class; +typedef struct _TestIfaceClass TestIface2Class; +typedef struct _TestIfaceClass TestIface3Class; +typedef struct _TestIfaceClass TestIface4Class; +typedef struct _TestIfaceClass TestIface5Class; +typedef struct _TestIface TestIface; + +struct _TestIfaceClass +{ + GTypeInterface base_iface; + void (*method) (TestIface *obj); +}; + +static GType test_iface1_get_type (void); +static GType test_iface2_get_type (void); +static GType test_iface3_get_type (void); +static GType test_iface4_get_type (void); +static GType test_iface5_get_type (void); + +#define TEST_TYPE_IFACE1 (test_iface1_get_type ()) +#define TEST_TYPE_IFACE2 (test_iface2_get_type ()) +#define TEST_TYPE_IFACE3 (test_iface3_get_type ()) +#define TEST_TYPE_IFACE4 (test_iface4_get_type ()) +#define TEST_TYPE_IFACE5 (test_iface5_get_type ()) + +static DEFINE_IFACE (TestIface1, test_iface1, NULL, NULL) +static DEFINE_IFACE (TestIface2, test_iface2, NULL, NULL) +static DEFINE_IFACE (TestIface3, test_iface3, NULL, NULL) +static DEFINE_IFACE (TestIface4, test_iface4, NULL, NULL) +static DEFINE_IFACE (TestIface5, test_iface5, NULL, NULL) + +/************************************************************* + * Complex object is a GObject subclass with a properties, + * construct properties, signals and implementing an interface. + *************************************************************/ + +static GType complex_object_get_type (void); +#define COMPLEX_TYPE_OBJECT (complex_object_get_type ()) +typedef struct _ComplexObject ComplexObject; +typedef struct _ComplexObjectClass ComplexObjectClass; + +struct _ComplexObject +{ + GObject parent_instance; + int val1; + int val2; +}; + +struct _ComplexObjectClass +{ + GObjectClass parent_class; + + void (*signal) (ComplexObject *obj); + void (*signal_empty) (ComplexObject *obj); +}; + +static void complex_test_iface_init (gpointer g_iface, + gpointer iface_data); + +G_DEFINE_TYPE_EXTENDED (ComplexObject, complex_object, + G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE1, complex_test_iface_init) + G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE2, complex_test_iface_init) + G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE3, complex_test_iface_init) + G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE4, complex_test_iface_init) + G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE5, complex_test_iface_init)) + +#define COMPLEX_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), COMPLEX_TYPE_OBJECT, ComplexObject)) + +enum { + PROP_0, + PROP_VAL1, + PROP_VAL2 +}; + +enum { + COMPLEX_SIGNAL, + COMPLEX_SIGNAL_EMPTY, + COMPLEX_SIGNAL_GENERIC, + COMPLEX_SIGNAL_GENERIC_EMPTY, + COMPLEX_SIGNAL_ARGS, + COMPLEX_LAST_SIGNAL +}; + +static guint complex_signals[COMPLEX_LAST_SIGNAL] = { 0 }; + +static void +complex_object_finalize (GObject *object) +{ + G_OBJECT_CLASS (complex_object_parent_class)->finalize (object); +} + +static void +complex_object_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ComplexObject *complex = COMPLEX_OBJECT (object); + + switch (prop_id) + { + case PROP_VAL1: + complex->val1 = g_value_get_int (value); + break; + case PROP_VAL2: + complex->val2 = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +complex_object_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ComplexObject *complex = COMPLEX_OBJECT (object); + + switch (prop_id) + { + case PROP_VAL1: + g_value_set_int (value, complex->val1); + break; + case PROP_VAL2: + g_value_set_int (value, complex->val2); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +complex_object_real_signal (ComplexObject *obj) +{ +} + +static void +complex_object_class_init (ComplexObjectClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = complex_object_finalize; + object_class->set_property = complex_object_set_property; + object_class->get_property = complex_object_get_property; + + class->signal = complex_object_real_signal; + + complex_signals[COMPLEX_SIGNAL] = + g_signal_new ("signal", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ComplexObjectClass, signal), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + complex_signals[COMPLEX_SIGNAL_EMPTY] = + g_signal_new ("signal-empty", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ComplexObjectClass, signal_empty), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + complex_signals[COMPLEX_SIGNAL_GENERIC] = + g_signal_new ("signal-generic", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ComplexObjectClass, signal), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + complex_signals[COMPLEX_SIGNAL_GENERIC_EMPTY] = + g_signal_new ("signal-generic-empty", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ComplexObjectClass, signal_empty), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + + complex_signals[COMPLEX_SIGNAL_ARGS] = + g_signal_new ("signal-args", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ComplexObjectClass, signal), + NULL, NULL, + g_cclosure_marshal_VOID__UINT_POINTER, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER); + + g_object_class_install_property (object_class, + PROP_VAL1, + g_param_spec_int ("val1", + "val1", + "val1", + 0, + G_MAXINT, + 42, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_VAL2, + g_param_spec_int ("val2", + "val2", + "val2", + 0, + G_MAXINT, + 43, + G_PARAM_READWRITE)); + + +} + +static void +complex_object_iface_method (TestIface *obj) +{ + ComplexObject *complex = COMPLEX_OBJECT (obj); + complex->val1++; +} + +static void +complex_test_iface_init (gpointer g_iface, + gpointer iface_data) +{ + TestIfaceClass *iface = g_iface; + iface->method = complex_object_iface_method; +} + +static void +complex_object_init (ComplexObject *complex_object) +{ + complex_object->val2 = 43; +} + +/************************************************************* + * Test object construction performance + *************************************************************/ + +#define NUM_OBJECT_TO_CONSTRUCT 10000 + +struct ConstructionTest { + GObject **objects; + int n_objects; + GType type; +}; + +static gpointer +test_construction_setup (PerformanceTest *test) +{ + struct ConstructionTest *data; + + data = g_new0 (struct ConstructionTest, 1); + data->type = ((GType (*)(void))test->extra_data)(); + + return data; +} + +static void +test_construction_init (PerformanceTest *test, + gpointer _data, + double count_factor) +{ + struct ConstructionTest *data = _data; + int n; + + n = NUM_OBJECT_TO_CONSTRUCT * count_factor; + if (data->n_objects != n) + { + data->n_objects = n; + data->objects = g_new (GObject *, n); + } +} + +static void +test_construction_run (PerformanceTest *test, + gpointer _data) +{ + struct ConstructionTest *data = _data; + GObject **objects = data->objects; + GType type = data->type; + int i, n_objects; + + n_objects = data->n_objects; + for (i = 0; i < n_objects; i++) + objects[i] = g_object_new (type, NULL); +} + +static void +test_construction_finish (PerformanceTest *test, + gpointer _data) +{ + struct ConstructionTest *data = _data; + int i; + + for (i = 0; i < data->n_objects; i++) + g_object_unref (data->objects[i]); +} + +static void +test_construction_teardown (PerformanceTest *test, + gpointer _data) +{ + struct ConstructionTest *data = _data; + g_free (data->objects); + g_free (data); +} + +static void +test_construction_print_result (PerformanceTest *test, + gpointer _data, + double time) +{ + struct ConstructionTest *data = _data; + + g_print ("Millions of constructed objects per second: %.3f\n", + data->n_objects / (time * 1000000)); +} + +/************************************************************* + * Test runtime type check performance + *************************************************************/ + +#define NUM_KILO_CHECKS_PER_ROUND 50 + +struct TypeCheckTest { + GObject *object; + int n_checks; +}; + +static gpointer +test_type_check_setup (PerformanceTest *test) +{ + struct TypeCheckTest *data; + + data = g_new0 (struct TypeCheckTest, 1); + data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL); + + return data; +} + +static void +test_type_check_init (PerformanceTest *test, + gpointer _data, + double factor) +{ + struct TypeCheckTest *data = _data; + + data->n_checks = factor * NUM_KILO_CHECKS_PER_ROUND; +} + + +/* Work around g_type_check_instance_is_a being marked "pure", + and thus only called once for the loop. */ +gboolean (*my_type_check_instance_is_a) (GTypeInstance *type_instance, + GType iface_type) = &g_type_check_instance_is_a; + +static void +test_type_check_run (PerformanceTest *test, + gpointer _data) +{ + struct TypeCheckTest *data = _data; + GObject *object = data->object; + GType type, types[5]; + int i, j; + + types[0] = test_iface1_get_type (); + types[1] = test_iface2_get_type (); + types[2] = test_iface3_get_type (); + types[3] = test_iface4_get_type (); + types[4] = test_iface5_get_type (); + + for (i = 0; i < data->n_checks; i++) + { + type = types[i%5]; + for (j = 0; j < 1000; j++) + { + my_type_check_instance_is_a ((GTypeInstance *)object, + type); + } + } +} + +static void +test_type_check_finish (PerformanceTest *test, + gpointer data) +{ +} + +static void +test_type_check_print_result (PerformanceTest *test, + gpointer _data, + double time) +{ + struct TypeCheckTest *data = _data; + g_print ("Million type checks per second: %.2f\n", + data->n_checks / (1000*time)); +} + +static void +test_type_check_teardown (PerformanceTest *test, + gpointer _data) +{ + struct TypeCheckTest *data = _data; + + g_object_unref (data->object); + g_free (data); +} + +/************************************************************* + * Test signal emissions performance (common code) + *************************************************************/ + +#define NUM_EMISSIONS_PER_ROUND 10000 + +struct EmissionTest { + GObject *object; + int n_checks; + int signal_id; +}; + +static void +test_emission_run (PerformanceTest *test, + gpointer _data) +{ + struct EmissionTest *data = _data; + GObject *object = data->object; + int i; + + for (i = 0; i < data->n_checks; i++) + g_signal_emit (object, data->signal_id, 0); +} + +static void +test_emission_run_args (PerformanceTest *test, + gpointer _data) +{ + struct EmissionTest *data = _data; + GObject *object = data->object; + int i; + + for (i = 0; i < data->n_checks; i++) + g_signal_emit (object, data->signal_id, 0, 0, NULL); +} + +/************************************************************* + * Test signal unhandled emissions performance + *************************************************************/ + +static gpointer +test_emission_unhandled_setup (PerformanceTest *test) +{ + struct EmissionTest *data; + + data = g_new0 (struct EmissionTest, 1); + data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL); + data->signal_id = complex_signals[GPOINTER_TO_INT (test->extra_data)]; + return data; +} + +static void +test_emission_unhandled_init (PerformanceTest *test, + gpointer _data, + double factor) +{ + struct EmissionTest *data = _data; + + data->n_checks = factor * NUM_EMISSIONS_PER_ROUND; +} + +static void +test_emission_unhandled_finish (PerformanceTest *test, + gpointer data) +{ +} + +static void +test_emission_unhandled_print_result (PerformanceTest *test, + gpointer _data, + double time) +{ + struct EmissionTest *data = _data; + + g_print ("Emissions per second: %.0f\n", + data->n_checks / time); +} + +static void +test_emission_unhandled_teardown (PerformanceTest *test, + gpointer _data) +{ + struct EmissionTest *data = _data; + + g_object_unref (data->object); + g_free (data); +} + +/************************************************************* + * Test signal handled emissions performance + *************************************************************/ + +static void +test_emission_handled_handler (ComplexObject *obj, gpointer data) +{ +} + +static gpointer +test_emission_handled_setup (PerformanceTest *test) +{ + struct EmissionTest *data; + + data = g_new0 (struct EmissionTest, 1); + data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL); + data->signal_id = complex_signals[GPOINTER_TO_INT (test->extra_data)]; + g_signal_connect (data->object, "signal", + G_CALLBACK (test_emission_handled_handler), + NULL); + g_signal_connect (data->object, "signal-empty", + G_CALLBACK (test_emission_handled_handler), + NULL); + g_signal_connect (data->object, "signal-generic", + G_CALLBACK (test_emission_handled_handler), + NULL); + g_signal_connect (data->object, "signal-generic-empty", + G_CALLBACK (test_emission_handled_handler), + NULL); + g_signal_connect (data->object, "signal-args", + G_CALLBACK (test_emission_handled_handler), + NULL); + + return data; +} + +static void +test_emission_handled_init (PerformanceTest *test, + gpointer _data, + double factor) +{ + struct EmissionTest *data = _data; + + data->n_checks = factor * NUM_EMISSIONS_PER_ROUND; +} + +static void +test_emission_handled_finish (PerformanceTest *test, + gpointer data) +{ +} + +static void +test_emission_handled_print_result (PerformanceTest *test, + gpointer _data, + double time) +{ + struct EmissionTest *data = _data; + + g_print ("Emissions per second: %.0f\n", + data->n_checks / time); +} + +static void +test_emission_handled_teardown (PerformanceTest *test, + gpointer _data) +{ + struct EmissionTest *data = _data; + + g_object_unref (data->object); + g_free (data); +} + +/************************************************************* + * Test object refcount performance + *************************************************************/ + +#define NUM_KILO_REFS_PER_ROUND 100000 + +struct RefcountTest { + GObject *object; + int n_checks; +}; + +static gpointer +test_refcount_setup (PerformanceTest *test) +{ + struct RefcountTest *data; + + data = g_new0 (struct RefcountTest, 1); + data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL); + + return data; +} + +static void +test_refcount_init (PerformanceTest *test, + gpointer _data, + double factor) +{ + struct RefcountTest *data = _data; + + data->n_checks = factor * NUM_KILO_REFS_PER_ROUND; +} + +static void +test_refcount_run (PerformanceTest *test, + gpointer _data) +{ + struct RefcountTest *data = _data; + GObject *object = data->object; + int i; + + for (i = 0; i < data->n_checks; i++) + { + g_object_ref (object); + g_object_ref (object); + g_object_ref (object); + g_object_unref (object); + g_object_unref (object); + + g_object_ref (object); + g_object_ref (object); + g_object_unref (object); + g_object_unref (object); + g_object_unref (object); + } +} + +static void +test_refcount_finish (PerformanceTest *test, + gpointer _data) +{ +} + +static void +test_refcount_print_result (PerformanceTest *test, + gpointer _data, + double time) +{ + struct RefcountTest *data = _data; + g_print ("Million refs+unref per second: %.2f\n", + data->n_checks * 5 / (time * 1000000 )); +} + +static void +test_refcount_teardown (PerformanceTest *test, + gpointer _data) +{ + struct RefcountTest *data = _data; + + g_object_unref (data->object); + g_free (data); +} + +/************************************************************* + * Main test code + *************************************************************/ + +static PerformanceTest tests[] = { + { + "simple-construction", + simple_object_get_type, + test_construction_setup, + test_construction_init, + test_construction_run, + test_construction_finish, + test_construction_teardown, + test_construction_print_result + }, + { + "complex-construction", + complex_object_get_type, + test_construction_setup, + test_construction_init, + test_construction_run, + test_construction_finish, + test_construction_teardown, + test_construction_print_result + }, + { + "type-check", + NULL, + test_type_check_setup, + test_type_check_init, + test_type_check_run, + test_type_check_finish, + test_type_check_teardown, + test_type_check_print_result + }, + { + "emit-unhandled", + GINT_TO_POINTER (COMPLEX_SIGNAL), + test_emission_unhandled_setup, + test_emission_unhandled_init, + test_emission_run, + test_emission_unhandled_finish, + test_emission_unhandled_teardown, + test_emission_unhandled_print_result + }, + { + "emit-unhandled-empty", + GINT_TO_POINTER (COMPLEX_SIGNAL_EMPTY), + test_emission_unhandled_setup, + test_emission_unhandled_init, + test_emission_run, + test_emission_unhandled_finish, + test_emission_unhandled_teardown, + test_emission_unhandled_print_result + }, + { + "emit-unhandled-generic", + GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC), + test_emission_unhandled_setup, + test_emission_unhandled_init, + test_emission_run, + test_emission_unhandled_finish, + test_emission_unhandled_teardown, + test_emission_unhandled_print_result + }, + { + "emit-unhandled-generic-empty", + GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC_EMPTY), + test_emission_unhandled_setup, + test_emission_unhandled_init, + test_emission_run, + test_emission_unhandled_finish, + test_emission_unhandled_teardown, + test_emission_unhandled_print_result + }, + { + "emit-unhandled-args", + GINT_TO_POINTER (COMPLEX_SIGNAL_ARGS), + test_emission_unhandled_setup, + test_emission_unhandled_init, + test_emission_run_args, + test_emission_unhandled_finish, + test_emission_unhandled_teardown, + test_emission_unhandled_print_result + }, + { + "emit-handled", + GINT_TO_POINTER (COMPLEX_SIGNAL), + test_emission_handled_setup, + test_emission_handled_init, + test_emission_run, + test_emission_handled_finish, + test_emission_handled_teardown, + test_emission_handled_print_result + }, + { + "emit-handled-empty", + GINT_TO_POINTER (COMPLEX_SIGNAL_EMPTY), + test_emission_handled_setup, + test_emission_handled_init, + test_emission_run, + test_emission_handled_finish, + test_emission_handled_teardown, + test_emission_handled_print_result + }, + { + "emit-handled-generic", + GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC), + test_emission_handled_setup, + test_emission_handled_init, + test_emission_run, + test_emission_handled_finish, + test_emission_handled_teardown, + test_emission_handled_print_result + }, + { + "emit-handled-generic-empty", + GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC_EMPTY), + test_emission_handled_setup, + test_emission_handled_init, + test_emission_run, + test_emission_handled_finish, + test_emission_handled_teardown, + test_emission_handled_print_result + }, + { + "emit-handled-args", + GINT_TO_POINTER (COMPLEX_SIGNAL_ARGS), + test_emission_handled_setup, + test_emission_handled_init, + test_emission_run_args, + test_emission_handled_finish, + test_emission_handled_teardown, + test_emission_handled_print_result + }, + { + "refcount", + NULL, + test_refcount_setup, + test_refcount_init, + test_refcount_run, + test_refcount_finish, + test_refcount_teardown, + test_refcount_print_result + } +}; + +static PerformanceTest * +find_test (const char *name) +{ + gsize i; + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + if (strcmp (tests[i].name, name) == 0) + return &tests[i]; + } + return NULL; +} +int +main (int argc, + char *argv[]) +{ + PerformanceTest *test; + GOptionContext *context; + GError *error = NULL; + int i; + + context = g_option_context_new ("GObject performance tests"); + g_option_context_add_main_entries (context, cmd_entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + return 1; + } + + if (argc > 1) + { + for (i = 1; i < argc; i++) + { + test = find_test (argv[i]); + if (test) + run_test (test); + } + } + else + { + gsize k; + for (k = 0; k < G_N_ELEMENTS (tests); k++) + run_test (&tests[k]); + } + + return 0; +} diff --git a/tests/gobject/references.c b/tests/gobject/references.c new file mode 100644 index 0000000..36ff35c --- /dev/null +++ b/tests/gobject/references.c @@ -0,0 +1,280 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestReferences" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#include + +/* This test tests weak and toggle references + */ + +static GObject *global_object; + +static gboolean object_destroyed; +static gboolean weak_ref1_notified; +static gboolean weak_ref2_notified; +static gboolean toggle_ref1_weakened; +static gboolean toggle_ref1_strengthened; +static gboolean toggle_ref2_weakened; +static gboolean toggle_ref2_strengthened; +static gboolean toggle_ref3_weakened; +static gboolean toggle_ref3_strengthened; + +/* + * TestObject, a parent class for TestObject + */ +static GType test_object_get_type (void); +#define TEST_TYPE_OBJECT (test_object_get_type ()) +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; + +struct _TestObject +{ + GObject parent_instance; +}; +struct _TestObjectClass +{ + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT) + +static void +test_object_finalize (GObject *object) +{ + object_destroyed = TRUE; + + G_OBJECT_CLASS (test_object_parent_class)->finalize (object); +} + +static void +test_object_class_init (TestObjectClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = test_object_finalize; +} + +static void +test_object_init (TestObject *test_object) +{ +} + +static void +clear_flags (void) +{ + object_destroyed = FALSE; + weak_ref1_notified = FALSE; + weak_ref2_notified = FALSE; + toggle_ref1_weakened = FALSE; + toggle_ref1_strengthened = FALSE; + toggle_ref2_weakened = FALSE; + toggle_ref2_strengthened = FALSE; + toggle_ref3_weakened = FALSE; + toggle_ref3_strengthened = FALSE; +} + +static void +weak_ref1 (gpointer data, + GObject *object) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (42)); + + weak_ref1_notified = TRUE; +} + +static void +weak_ref2 (gpointer data, + GObject *object) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (24)); + + weak_ref2_notified = TRUE; +} + +static void +toggle_ref1 (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (42)); + + if (is_last_ref) + toggle_ref1_weakened = TRUE; + else + toggle_ref1_strengthened = TRUE; +} + +static void +toggle_ref2 (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (24)); + + if (is_last_ref) + toggle_ref2_weakened = TRUE; + else + toggle_ref2_strengthened = TRUE; +} + +static void +toggle_ref3 (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (34)); + + if (is_last_ref) + { + toggle_ref3_weakened = TRUE; + g_object_remove_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34)); + } + else + toggle_ref3_strengthened = TRUE; +} + +int +main (int argc, + char *argv[]) +{ + GObject *object; + + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + + /* Test basic weak reference operation + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42)); + + clear_flags (); + g_object_unref (object); + g_assert (weak_ref1_notified == TRUE); + g_assert (object_destroyed == TRUE); + + /* Test two weak references at once + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42)); + g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24)); + + clear_flags (); + g_object_unref (object); + g_assert (weak_ref1_notified == TRUE); + g_assert (weak_ref2_notified == TRUE); + g_assert (object_destroyed == TRUE); + + /* Test remove weak references + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42)); + g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24)); + g_object_weak_unref (object, weak_ref1, GUINT_TO_POINTER (42)); + + clear_flags (); + g_object_unref (object); + g_assert (weak_ref1_notified == FALSE); + g_assert (weak_ref2_notified == TRUE); + g_assert (object_destroyed == TRUE); + + /* Test basic toggle reference operation + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42)); + + clear_flags (); + g_object_unref (object); + g_assert (toggle_ref1_weakened == TRUE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (object_destroyed == FALSE); + + clear_flags (); + g_object_ref (object); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == TRUE); + g_assert (object_destroyed == FALSE); + + g_object_unref (object); + + clear_flags (); + g_object_remove_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42)); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (object_destroyed == TRUE); + + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + /* Test two toggle references at once + */ + g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42)); + g_object_add_toggle_ref (object, toggle_ref2, GUINT_TO_POINTER (24)); + + clear_flags (); + g_object_unref (object); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (toggle_ref2_weakened == FALSE); + g_assert (toggle_ref2_strengthened == FALSE); + g_assert (object_destroyed == FALSE); + + clear_flags (); + g_object_remove_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42)); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (toggle_ref2_weakened == TRUE); + g_assert (toggle_ref2_strengthened == FALSE); + g_assert (object_destroyed == FALSE); + + clear_flags (); + /* Check that removing a toggle ref with %NULL data works fine. */ + g_object_remove_toggle_ref (object, toggle_ref2, NULL); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (toggle_ref2_weakened == FALSE); + g_assert (toggle_ref2_strengthened == FALSE); + g_assert (object_destroyed == TRUE); + + /* Test a toggle reference that removes itself + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_add_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34)); + + clear_flags (); + g_object_unref (object); + g_assert (toggle_ref3_weakened == TRUE); + g_assert (toggle_ref3_strengthened == FALSE); + g_assert (object_destroyed == TRUE); + + return 0; +} diff --git a/tests/gobject/signals.c b/tests/gobject/signals.c new file mode 100644 index 0000000..3b1f3b6 --- /dev/null +++ b/tests/gobject/signals.c @@ -0,0 +1,134 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2013 Red Hat, Inc. + * Copy and pasted from accumulator.c and modified. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestSignals" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#include + +#include "testcommon.h" + +/* What this test tests is the behavior of signal disconnection + * from within a signal handler for the signal being disconnected. + * + * The test demonstrates that signal handlers disconnected from a signal + * from an earlier handler in the same emission will not be run. + * + * It also demonstrates that signal handlers connected from a signal + * from an earlier handler in the same emission will not be run. + */ + +/* + * TestObject, a parent class for TestObject + */ +#define TEST_TYPE_OBJECT (test_object_get_type ()) +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; +static gboolean callback1_ran = FALSE, callback2_ran = FALSE, callback3_ran = FALSE, default_handler_ran = FALSE; + +struct _TestObject +{ + GObject parent_instance; +}; +struct _TestObjectClass +{ + GObjectClass parent_class; + + void (*test_signal) (TestObject *object); +}; + +static GType test_object_get_type (void); + +static void +test_object_real_signal (TestObject *object) +{ + default_handler_ran = TRUE; +} + +static void +test_object_signal_callback3 (TestObject *object, + gpointer data) +{ + callback3_ran = TRUE; +} + +static void +test_object_signal_callback2 (TestObject *object, + gpointer data) +{ + callback2_ran = TRUE; +} + +static void +test_object_signal_callback1 (TestObject *object, + gpointer data) +{ + callback1_ran = TRUE; + g_signal_handlers_disconnect_by_func (G_OBJECT (object), + test_object_signal_callback2, + data); + g_signal_connect (object, "test-signal", + G_CALLBACK (test_object_signal_callback3), NULL); +} + +static void +test_object_class_init (TestObjectClass *class) +{ + class->test_signal = test_object_real_signal; + + g_signal_new ("test-signal", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestObjectClass, test_signal), + NULL, NULL, NULL, G_TYPE_NONE, 0); +} + +static DEFINE_TYPE(TestObject, test_object, + test_object_class_init, NULL, NULL, + G_TYPE_OBJECT) + +int +main (int argc, + char *argv[]) +{ + TestObject *object; + + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + + object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_signal_connect (object, "test-signal", + G_CALLBACK (test_object_signal_callback1), NULL); + g_signal_connect (object, "test-signal", + G_CALLBACK (test_object_signal_callback2), NULL); + g_signal_emit_by_name (object, "test-signal"); + + g_assert (callback1_ran); + g_assert (!callback2_ran); + g_assert (!callback3_ran); + g_assert (default_handler_ran); + + g_object_unref (object); + return 0; +} diff --git a/tests/gobject/singleton.c b/tests/gobject/singleton.c new file mode 100644 index 0000000..79a41b2 --- /dev/null +++ b/tests/gobject/singleton.c @@ -0,0 +1,84 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2006 Imendio AB + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestSingleton" +#include +#include + +/* --- MySingleton class --- */ +typedef struct { + GObject parent_instance; +} MySingleton; +typedef struct { + GObjectClass parent_class; +} MySingletonClass; + +static GType my_singleton_get_type (void); +#define MY_TYPE_SINGLETON (my_singleton_get_type ()) +#define MY_SINGLETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MY_TYPE_SINGLETON, MySingleton)) +#define MY_IS_SINGLETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MY_TYPE_SINGLETON)) +#define MY_SINGLETON_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), MY_TYPE_SINGLETON, MySingletonClass)) +#define MY_IS_SINGLETON_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), MY_TYPE_SINGLETON)) +#define MY_SINGLETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MY_TYPE_SINGLETON, MySingletonClass)) + +G_DEFINE_TYPE (MySingleton, my_singleton, G_TYPE_OBJECT) + +static MySingleton *the_one_and_only = NULL; + +/* --- methods --- */ +static GObject* +my_singleton_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + if (the_one_and_only) + return g_object_ref (G_OBJECT (the_one_and_only)); + else + return G_OBJECT_CLASS (my_singleton_parent_class)->constructor (type, n_construct_properties, construct_properties); +} + +static void +my_singleton_init (MySingleton *self) +{ + g_assert (the_one_and_only == NULL); + the_one_and_only = self; +} + +static void +my_singleton_class_init (MySingletonClass *klass) +{ + G_OBJECT_CLASS (klass)->constructor = my_singleton_constructor; +} + +/* --- test program --- */ +int +main (int argc, + char *argv[]) +{ + MySingleton *singleton, *obj; + + /* create the singleton */ + singleton = g_object_new (MY_TYPE_SINGLETON, NULL); + g_assert (singleton != NULL); + /* assert _singleton_ creation */ + obj = g_object_new (MY_TYPE_SINGLETON, NULL); + g_assert (singleton == obj); + g_object_unref (obj); + /* shutdown */ + g_object_unref (singleton); + return 0; +} diff --git a/tests/gobject/testcommon.h b/tests/gobject/testcommon.h new file mode 100644 index 0000000..3e40cca --- /dev/null +++ b/tests/gobject/testcommon.h @@ -0,0 +1,105 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#ifndef __TEST_COMMON_H__ +#define __TEST_COMMON_H__ + +G_BEGIN_DECLS + +#define DEFINE_TYPE_FULL(name, prefix, \ + class_init, base_init, instance_init, \ + parent_type, interface_decl) \ +GType \ +prefix ## _get_type (void) \ +{ \ + static GType object_type = 0; \ + \ + if (!object_type) \ + { \ + const GTypeInfo object_info = \ + { \ + sizeof (name ## Class), \ + (GBaseInitFunc) base_init, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) class_init, \ + (GClassFinalizeFunc) NULL, \ + NULL, /* class_data */ \ + sizeof (name), \ + 0, /* n_prelocs */ \ + (GInstanceInitFunc) instance_init, \ + (const GTypeValueTable *) NULL, \ + }; \ + \ + object_type = g_type_register_static (parent_type, \ + # name, \ + &object_info, 0); \ + interface_decl \ + } \ + \ + return object_type; \ +} + +#define DEFINE_TYPE(name, prefix, \ + class_init, base_init, instance_init, \ + parent_type) \ + DEFINE_TYPE_FULL(name, prefix, class_init, base_init, \ + instance_init, parent_type, {}) + +#define DEFINE_IFACE(name, prefix, base_init, dflt_init) \ +GType \ +prefix ## _get_type (void) \ +{ \ + static GType iface_type = 0; \ + \ + if (!iface_type) \ + { \ + const GTypeInfo iface_info = \ + { \ + sizeof (name ## Class), \ + (GBaseInitFunc) base_init, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) dflt_init, \ + (GClassFinalizeFunc) NULL, \ + (gconstpointer) NULL, \ + (guint16) 0, \ + (guint16) 0, \ + (GInstanceInitFunc) NULL, \ + (const GTypeValueTable*) NULL, \ + }; \ + \ + iface_type = g_type_register_static (G_TYPE_INTERFACE, \ + # name, \ + &iface_info, 0); \ + } \ + return iface_type; \ +} + +#define INTERFACE_FULL(type, init_func, iface_type) \ +{ \ + GInterfaceInfo const iface = \ + { \ + (GInterfaceInitFunc) init_func, NULL, NULL \ + }; \ + \ + g_type_add_interface_static (type, iface_type, &iface); \ +} +#define INTERFACE(init_func, iface_type) \ + INTERFACE_FULL(object_type, init_func, iface_type) + +G_END_DECLS + +#endif /* __TEST_COMMON_H__ */ diff --git a/tests/gobject/testgobject.c b/tests/gobject/testgobject.c new file mode 100644 index 0000000..e467abc --- /dev/null +++ b/tests/gobject/testgobject.c @@ -0,0 +1,445 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + */ + +#include + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestObject" +#include + +/* --- TestIface --- */ +#define TEST_TYPE_IFACE (test_iface_get_type ()) +#define TEST_IFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_IFACE, TestIface)) +#define TEST_IS_IFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_IFACE)) +#define TEST_IFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE, TestIfaceClass)) +typedef struct _TestIface TestIface; +typedef struct _TestIfaceClass TestIfaceClass; +struct _TestIfaceClass +{ + GTypeInterface base_iface; + void (*print_string) (TestIface *tiobj, + const gchar *string); +}; +static void iface_base_init (TestIfaceClass *iface); +static void iface_base_finalize (TestIfaceClass *iface); +static void print_foo (TestIface *tiobj, + const gchar *string); +static GType +test_iface_get_type (void) +{ + static GType test_iface_type = 0; + + if (!test_iface_type) + { + const GTypeInfo test_iface_info = + { + sizeof (TestIfaceClass), + (GBaseInitFunc) iface_base_init, /* base_init */ + (GBaseFinalizeFunc) iface_base_finalize, /* base_finalize */ + NULL, + NULL, + NULL, + 0, + 0, + NULL, + NULL + }; + + test_iface_type = g_type_register_static (G_TYPE_INTERFACE, "TestIface", &test_iface_info, 0); + g_type_interface_add_prerequisite (test_iface_type, G_TYPE_OBJECT); + } + + return test_iface_type; +} +static guint iface_base_init_count = 0; +static void +iface_base_init (TestIfaceClass *iface) +{ + iface_base_init_count++; + if (iface_base_init_count == 1) + { + /* add signals here */ + } +} +static void +iface_base_finalize (TestIfaceClass *iface) +{ + iface_base_init_count--; + if (iface_base_init_count == 0) + { + /* destroy signals here */ + } +} +static void +print_foo (TestIface *tiobj, + const gchar *string) +{ + if (!string) + string = ""; + g_print ("Iface-FOO: \"%s\" from %p\n", string, tiobj); +} +static void +test_object_test_iface_init (gpointer giface, + gpointer iface_data) +{ + TestIfaceClass *iface = giface; + + g_assert (iface_data == GUINT_TO_POINTER (42)); + + g_assert (G_TYPE_FROM_INTERFACE (iface) == TEST_TYPE_IFACE); + + /* assert iface_base_init() was already called */ + g_assert (iface_base_init_count > 0); + + /* initialize stuff */ + iface->print_string = print_foo; +} +static void +iface_print_string (TestIface *tiobj, + const gchar *string) +{ + TestIfaceClass *iface; + + g_return_if_fail (TEST_IS_IFACE (tiobj)); + g_return_if_fail (G_IS_OBJECT (tiobj)); /* ensured through prerequisite */ + + iface = TEST_IFACE_GET_CLASS (tiobj); + g_object_ref (tiobj); + iface->print_string (tiobj, string); + g_object_unref (tiobj); +} + + +/* --- TestObject --- */ +#define TEST_TYPE_OBJECT (test_object_get_type ()) +#define TEST_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject)) +#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass)) +#define TEST_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT)) +#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass)) +#define TEST_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TEST_TYPE_OBJECT, TestObjectPrivate)) +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; +typedef struct _TestObjectPrivate TestObjectPrivate; +struct _TestObject +{ + GObject parent_instance; +}; +struct _TestObjectClass +{ + GObjectClass parent_class; + + gchar* (*test_signal) (TestObject *tobject, + TestIface *iface_object, + gpointer tdata); +}; +struct _TestObjectPrivate +{ + int dummy1; + gdouble dummy2; +}; +static void test_object_class_init (TestObjectClass *class); +static void test_object_init (TestObject *tobject); +static gboolean test_signal_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data); +static gchar* test_object_test_signal (TestObject *tobject, + TestIface *iface_object, + gpointer tdata); +static gint TestObject_private_offset; +static inline gpointer +test_object_get_instance_private (TestObject *self) +{ + return (G_STRUCT_MEMBER_P (self, TestObject_private_offset)); +} + +static GType +test_object_get_type (void) +{ + static GType test_object_type = 0; + + if (!test_object_type) + { + const GTypeInfo test_object_info = + { + sizeof (TestObjectClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) test_object_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (TestObject), + 5, /* n_preallocs */ + (GInstanceInitFunc) test_object_init, + NULL + }; + GInterfaceInfo iface_info = { test_object_test_iface_init, NULL, GUINT_TO_POINTER (42) }; + + test_object_type = g_type_register_static (G_TYPE_OBJECT, "TestObject", &test_object_info, 0); + g_type_add_interface_static (test_object_type, TEST_TYPE_IFACE, &iface_info); + + TestObject_private_offset = + g_type_add_instance_private (test_object_type, sizeof (TestObjectPrivate)); + } + + return test_object_type; +} +static void +test_object_class_init (TestObjectClass *class) +{ + /* GObjectClass *gobject_class = G_OBJECT_CLASS (class); */ + g_type_class_adjust_private_offset (class, &TestObject_private_offset); + + class->test_signal = test_object_test_signal; + + g_signal_new ("test-signal", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP, + G_STRUCT_OFFSET (TestObjectClass, test_signal), + test_signal_accumulator, NULL, + g_cclosure_marshal_STRING__OBJECT_POINTER, + G_TYPE_STRING, 2, TEST_TYPE_IFACE, G_TYPE_POINTER); +} +static void +test_object_init (TestObject *tobject) +{ + TestObjectPrivate *priv = test_object_get_instance_private (tobject); + + g_assert (priv); + + priv->dummy1 = 54321; +} +/* Check to see if private data initialization in the + * instance init function works. + */ +static void +test_object_check_private_init (TestObject *tobject) +{ + TestObjectPrivate *priv = test_object_get_instance_private (tobject); + + g_print ("private data during initialization: %u == %u\n", priv->dummy1, 54321); + g_assert (priv->dummy1 == 54321); +} +static gboolean +test_signal_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + const gchar *accu_string = g_value_get_string (return_accu); + const gchar *new_string = g_value_get_string (handler_return); + gchar *result_string; + + if (accu_string) + result_string = g_strconcat (accu_string, new_string, NULL); + else if (new_string) + result_string = g_strdup (new_string); + else + result_string = NULL; + + g_value_take_string (return_accu, result_string); + + return TRUE; +} +static gchar* +test_object_test_signal (TestObject *tobject, + TestIface *iface_object, + gpointer tdata) +{ + g_message ("::test_signal default_handler called"); + + g_return_val_if_fail (TEST_IS_IFACE (iface_object), NULL); + + return g_strdup (""); +} + + +/* --- TestIface for DerivedObject --- */ +static void +print_bar (TestIface *tiobj, + const gchar *string) +{ + TestIfaceClass *parent_iface; + + g_return_if_fail (TEST_IS_IFACE (tiobj)); + + if (!string) + string = ""; + g_print ("Iface-BAR: \"%s\" from %p\n", string, tiobj); + + g_print ("chaining: "); + parent_iface = g_type_interface_peek_parent (TEST_IFACE_GET_CLASS (tiobj)); + parent_iface->print_string (tiobj, string); + + g_assert (g_type_interface_peek_parent (parent_iface) == NULL); +} + +static void +derived_object_test_iface_init (gpointer giface, + gpointer iface_data) +{ + TestIfaceClass *iface = giface; + + g_assert (iface_data == GUINT_TO_POINTER (87)); + + g_assert (G_TYPE_FROM_INTERFACE (iface) == TEST_TYPE_IFACE); + + /* assert test_object_test_iface_init() was already called */ + g_assert (iface->print_string == print_foo); + + /* override stuff */ + iface->print_string = print_bar; +} + + +/* --- DerivedObject --- */ +#define DERIVED_TYPE_OBJECT (derived_object_get_type ()) +#define DERIVED_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), DERIVED_TYPE_OBJECT, DerivedObject)) +#define DERIVED_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DERIVED_TYPE_OBJECT, DerivedObjectClass)) +#define DERIVED_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), DERIVED_TYPE_OBJECT)) +#define DERIVED_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DERIVED_TYPE_OBJECT)) +#define DERIVED_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DERIVED_TYPE_OBJECT, DerivedObjectClass)) +#define DERIVED_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DERIVED_TYPE_OBJECT, DerivedObjectPrivate)) +typedef struct _DerivedObject DerivedObject; +typedef struct _TestObjectClass DerivedObjectClass; +typedef struct _DerivedObjectPrivate DerivedObjectPrivate; +struct _DerivedObject +{ + TestObject parent_instance; + int dummy1; + int dummy2; +}; +struct _DerivedObjectPrivate +{ + char dummy; +}; +static void derived_object_class_init (DerivedObjectClass *class); +static void derived_object_init (DerivedObject *dobject); +static gint DerivedObject_private_offset; +static inline gpointer +derived_object_get_instance_private (DerivedObject *self) +{ + return (G_STRUCT_MEMBER_P (self, DerivedObject_private_offset)); +} +static GType +derived_object_get_type (void) +{ + static GType derived_object_type = 0; + + if (!derived_object_type) + { + const GTypeInfo derived_object_info = + { + sizeof (DerivedObjectClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) derived_object_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (DerivedObject), + 5, /* n_preallocs */ + (GInstanceInitFunc) derived_object_init, + NULL + }; + GInterfaceInfo iface_info = { derived_object_test_iface_init, NULL, GUINT_TO_POINTER (87) }; + + derived_object_type = g_type_register_static (TEST_TYPE_OBJECT, "DerivedObject", &derived_object_info, 0); + g_type_add_interface_static (derived_object_type, TEST_TYPE_IFACE, &iface_info); + DerivedObject_private_offset = + g_type_add_instance_private (derived_object_type, sizeof (DerivedObjectPrivate)); + } + + return derived_object_type; +} +static void +derived_object_class_init (DerivedObjectClass *class) +{ + g_type_class_adjust_private_offset (class, &DerivedObject_private_offset); +} +static void +derived_object_init (DerivedObject *dobject) +{ + TestObjectPrivate *test_priv; + DerivedObjectPrivate *derived_priv; + + derived_priv = derived_object_get_instance_private (dobject); + + g_assert (derived_priv); + + test_priv = test_object_get_instance_private (TEST_OBJECT (dobject)); + + g_assert (test_priv); +} + +/* --- main --- */ +int +main (int argc, + char *argv[]) +{ + GTypeInfo info = { 0, }; + GTypeFundamentalInfo finfo = { 0, }; + GType type; + TestObject *sigarg; + DerivedObject *dobject; + TestObjectPrivate *priv; + gchar *string = NULL; + + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + + /* test new fundamentals */ + g_assert (G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST) == g_type_fundamental_next ()); + type = g_type_register_fundamental (g_type_fundamental_next (), "FooShadow1", &info, &finfo, 0); + g_assert (type == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST)); + g_assert (G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST + 1) == g_type_fundamental_next ()); + type = g_type_register_fundamental (g_type_fundamental_next (), "FooShadow2", &info, &finfo, 0); + g_assert (type == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST + 1)); + g_assert (G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST + 2) == g_type_fundamental_next ()); + g_assert (g_type_from_name ("FooShadow1") == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST)); + g_assert (g_type_from_name ("FooShadow2") == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST + 1)); + + /* to test past class initialization interface setups, create the class here */ + g_type_class_ref (TEST_TYPE_OBJECT); + + dobject = g_object_new (DERIVED_TYPE_OBJECT, NULL); + test_object_check_private_init (TEST_OBJECT (dobject)); + + sigarg = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_print ("MAIN: emit test-signal:\n"); + g_signal_emit_by_name (dobject, "test-signal", sigarg, NULL, &string); + g_message ("signal return: \"%s\"", string); + g_assert_cmpstr (string, ==, ""); + g_free (string); + + g_print ("MAIN: call iface print-string on test and derived object:\n"); + iface_print_string (TEST_IFACE (sigarg), "iface-string-from-test-type"); + iface_print_string (TEST_IFACE (dobject), "iface-string-from-derived-type"); + + priv = test_object_get_instance_private (TEST_OBJECT (dobject)); + g_print ("private data after initialization: %u == %u\n", priv->dummy1, 54321); + g_assert (priv->dummy1 == 54321); + + g_object_unref (sigarg); + g_object_unref (dobject); + + g_message ("%s done", argv[0]); + + return 0; +} diff --git a/tests/gobject/testmarshal.list b/tests/gobject/testmarshal.list new file mode 100644 index 0000000..198c4f9 --- /dev/null +++ b/tests/gobject/testmarshal.list @@ -0,0 +1,4 @@ +# Marshallers used in tests +BOOLEAN:INT +STRING:INT +VARIANT:POINTER diff --git a/tests/gobject/testmodule.c b/tests/gobject/testmodule.c new file mode 100644 index 0000000..3133be1 --- /dev/null +++ b/tests/gobject/testmodule.c @@ -0,0 +1,66 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * testmodule.c: Dummy dynamic type module + * Copyright (C) 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "testmodule.h" +#include "testcommon.h" + +static gboolean test_module_load (GTypeModule *module); +static void test_module_unload (GTypeModule *module); + +static void +test_module_class_init (TestModuleClass *class) +{ + GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class); + + module_class->load = test_module_load; + module_class->unload = test_module_unload; +} + +DEFINE_TYPE (TestModule, test_module, + test_module_class_init, NULL, NULL, + G_TYPE_TYPE_MODULE) + +static gboolean +test_module_load (GTypeModule *module) +{ + TestModule *test_module = TEST_MODULE (module); + + test_module->register_func (module); + + return TRUE; +} + +static void +test_module_unload (GTypeModule *module) +{ +} + +GTypeModule * +test_module_new (TestModuleRegisterFunc register_func) +{ + TestModule *test_module = g_object_new (TEST_TYPE_MODULE, NULL); + GTypeModule *module = G_TYPE_MODULE (test_module); + + test_module->register_func = register_func; + + /* Register the types initially */ + g_type_module_use (module); + g_type_module_unuse (module); + + return G_TYPE_MODULE (module); +} diff --git a/tests/gobject/testmodule.h b/tests/gobject/testmodule.h new file mode 100644 index 0000000..e849b4d --- /dev/null +++ b/tests/gobject/testmodule.h @@ -0,0 +1,55 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * testmodule.h: Dummy dynamic type module + * Copyright (C) 2003 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __TEST_MODULE_H__ +#define __TEST_MODULE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _TestModule TestModule; +typedef struct _TestModuleClass TestModuleClass; + +#define TEST_TYPE_MODULE (test_module_get_type ()) +#define TEST_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), TEST_TYPE_MODULE, TestModule)) +#define TEST_MODULE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), TEST_TYPE_MODULE, TestModuleClass)) +#define TEST_IS_MODULE(module) (G_TYPE_CHECK_INSTANCE_TYPE ((module), TEST_TYPE_MODULE)) +#define TEST_IS_MODULE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), TEST_TYPE_MODULE)) +#define TEST_MODULE_GET_CLASS(module) (G_TYPE_INSTANCE_GET_CLASS ((module), TEST_TYPE_MODULE, TestModuleClass)) + +typedef void (*TestModuleRegisterFunc) (GTypeModule *module); + +struct _TestModule +{ + GTypeModule parent_instance; + + TestModuleRegisterFunc register_func; +}; + +struct _TestModuleClass +{ + GTypeModuleClass parent_class; +}; + +GType test_module_get_type (void); +GTypeModule *test_module_new (TestModuleRegisterFunc register_func); + +G_END_DECLS + +#endif /* __TEST_MODULE_H__ */ diff --git a/tests/gobject/timeloop-closure.c b/tests/gobject/timeloop-closure.c new file mode 100644 index 0000000..51dd6f1 --- /dev/null +++ b/tests/gobject/timeloop-closure.c @@ -0,0 +1,228 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include +#include +#include +#include + +#include +#include + +static int n_children = 3; +static int n_active_children; +static int n_iters = 10000; +static GMainLoop *loop; + +static void +io_pipe (GIOChannel **channels) +{ + int fds[2]; + + if (pipe(fds) < 0) + { + int errsv = errno; + fprintf (stderr, "Cannot create pipe %s\n", g_strerror (errsv)); + exit (1); + } + + channels[0] = g_io_channel_unix_new (fds[0]); + channels[1] = g_io_channel_unix_new (fds[1]); +} + +static gboolean +read_all (GIOChannel *channel, char *buf, gsize len) +{ + gsize bytes_read = 0; + gsize count; + GIOError err; + + while (bytes_read < len) + { + err = g_io_channel_read (channel, buf + bytes_read, len - bytes_read, &count); + if (err) + { + if (err != G_IO_ERROR_AGAIN) + return FALSE; + } + else if (count == 0) + return FALSE; + + bytes_read += count; + } + + return TRUE; +} + +static gboolean +write_all (GIOChannel *channel, char *buf, gsize len) +{ + gsize bytes_written = 0; + gsize count; + GIOError err; + + while (bytes_written < len) + { + err = g_io_channel_write (channel, buf + bytes_written, len - bytes_written, &count); + if (err && err != G_IO_ERROR_AGAIN) + return FALSE; + + bytes_written += count; + } + + return TRUE; +} + +static void +run_child (GIOChannel *in_channel, GIOChannel *out_channel) +{ + int i; + int val = 1; + GTimer *timer = g_timer_new(); + + for (i = 0; i < n_iters; i++) + { + write_all (out_channel, (char *)&val, sizeof (val)); + read_all (in_channel, (char *)&val, sizeof (val)); + } + + val = 0; + write_all (out_channel, (char *)&val, sizeof (val)); + + val = g_timer_elapsed (timer, NULL) * 1000; + + write_all (out_channel, (char *)&val, sizeof (val)); + g_timer_destroy (timer); + + exit (0); +} + +static gboolean +input_callback (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + int val; + GIOChannel *dest = (GIOChannel *)data; + + if (!read_all (source, (char *)&val, sizeof(val))) + { + fprintf (stderr, "Unexpected EOF\n"); + exit (1); + } + + if (val) + { + write_all (dest, (char *)&val, sizeof(val)); + + return TRUE; + } + else + { + g_io_channel_close (source); + g_io_channel_close (dest); + + n_active_children--; + if (n_active_children == 0) + g_main_loop_quit (loop); + + return FALSE; + } +} + +static void +create_child (void) +{ + int pid, errsv; + GIOChannel *in_channels[2]; + GIOChannel *out_channels[2]; + GSource *source; + + io_pipe (in_channels); + io_pipe (out_channels); + + pid = fork (); + errsv = errno; + + if (pid > 0) /* Parent */ + { + g_io_channel_close (in_channels[0]); + g_io_channel_close (out_channels[1]); + + source = g_io_create_watch (out_channels[0], G_IO_IN | G_IO_HUP); + g_source_set_closure (source, + g_cclosure_new (G_CALLBACK (input_callback), in_channels[1], + (GClosureNotify)g_io_channel_unref)); + g_source_attach (source, NULL); + g_source_unref (source); + + g_io_channel_unref (in_channels[0]); + g_io_channel_unref (out_channels[0]); + g_io_channel_unref (out_channels[1]); + + } + else if (pid == 0) /* Child */ + { + g_io_channel_close (in_channels[1]); + g_io_channel_close (out_channels[0]); + + setsid (); + + run_child (in_channels[0], out_channels[1]); + } + else /* Error */ + { + fprintf (stderr, "Cannot fork: %s\n", g_strerror (errsv)); + exit (1); + } +} + +static double +difftimeval (struct timeval *old, struct timeval *new) +{ + return + (new->tv_sec - old->tv_sec) * 1000. + (new->tv_usec - old->tv_usec) / 1000; +} + +int +main (int argc, char **argv) +{ + int i; + struct rusage old_usage; + struct rusage new_usage; + + if (argc > 1) + n_children = atoi(argv[1]); + + if (argc > 2) + n_iters = atoi(argv[2]); + + printf ("Children: %d Iters: %d\n", n_children, n_iters); + + n_active_children = n_children; + for (i = 0; i < n_children; i++) + create_child (); + + getrusage (RUSAGE_SELF, &old_usage); + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + getrusage (RUSAGE_SELF, &new_usage); + + printf ("Elapsed user: %g\n", + difftimeval (&old_usage.ru_utime, &new_usage.ru_utime)); + printf ("Elapsed system: %g\n", + difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)); + printf ("Elapsed total: %g\n", + difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) + + difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)); + printf ("total / iteration: %g\n", + (difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) + + difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)) / + (n_iters * n_children)); + + g_main_loop_unref (loop); + + return 0; +} diff --git a/tests/libmoduletestplugin_a.c b/tests/libmoduletestplugin_a.c new file mode 100644 index 0000000..56bd529 --- /dev/null +++ b/tests/libmoduletestplugin_a.c @@ -0,0 +1,75 @@ +/* libgplugin_a.c - test plugin for testgmodule + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include + +G_MODULE_EXPORT void gplugin_a_func (void); +G_MODULE_EXPORT void gplugin_clash_func (void); +G_MODULE_EXPORT void g_clash_func (void); +G_MODULE_EXPORT void gplugin_say_boo_func (void); +G_MODULE_EXPORT void gplugin_a_module_func (GModule *module); + +G_MODULE_EXPORT gchar* gplugin_a_state; + +G_MODULE_EXPORT void +gplugin_a_func (void) +{ + gplugin_a_state = "Hello world"; +} + +G_MODULE_EXPORT void +gplugin_clash_func (void) +{ + gplugin_a_state = "plugin clash"; +} + +G_MODULE_EXPORT void +g_clash_func (void) +{ + gplugin_a_state = "global clash"; +} + +G_MODULE_EXPORT void +gplugin_say_boo_func (void) +{ + gplugin_a_state = "BOOH"; +} + +G_MODULE_EXPORT void +gplugin_a_module_func (GModule *module) +{ + void *f = NULL; + + if (!g_module_symbol (module, "gplugin_say_boo_func", &f )) + { + g_print ("error: %s\n", g_module_error ()); + exit (1); + } + + ((void(*)(void)) f) (); +} diff --git a/tests/libmoduletestplugin_b.c b/tests/libmoduletestplugin_b.c new file mode 100644 index 0000000..e147dd2 --- /dev/null +++ b/tests/libmoduletestplugin_b.c @@ -0,0 +1,76 @@ +/* libgplugin_b.c - test plugin for testgmodule + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include + +G_MODULE_EXPORT gchar* gplugin_b_state; + +G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module); +G_MODULE_EXPORT void g_module_unload (GModule *module); + +G_MODULE_EXPORT void gplugin_b_func (void); +G_MODULE_EXPORT void gplugin_clash_func (void); +G_MODULE_EXPORT void g_clash_func (void); +G_MODULE_EXPORT void gplugin_say_boo_func (void); + +G_MODULE_EXPORT const gchar* +g_module_check_init (GModule *module) +{ + gplugin_b_state = "check-init"; + + return NULL; +} + +G_MODULE_EXPORT void +g_module_unload (GModule *module) +{ + gplugin_b_state = "unloaded"; +} + +G_MODULE_EXPORT void +gplugin_b_func (void) +{ + gplugin_b_state = "Hello world"; +} + +G_MODULE_EXPORT void +gplugin_clash_func (void) +{ + gplugin_b_state = "plugin clash"; +} + +G_MODULE_EXPORT void +g_clash_func (void) +{ + gplugin_b_state = "global clash"; +} + +G_MODULE_EXPORT void +gplugin_say_boo_func (void) +{ + gplugin_b_state = "BOOH"; +} diff --git a/tests/mainloop-test.c b/tests/mainloop-test.c new file mode 100644 index 0000000..365864d --- /dev/null +++ b/tests/mainloop-test.c @@ -0,0 +1,442 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#ifdef G_OS_UNIX +#include +#endif +#include +#include + +#ifdef G_OS_WIN32 +#include /* For _O_BINARY used by pipe() macro */ +#include /* for _pipe() */ +#define pipe(fds) _pipe(fds, 4096, _O_BINARY) +#endif + +#define ITERS 10000 +#define INCREMENT 10 +#define NTHREADS 4 +#define NCRAWLERS 4 +#define CRAWLER_TIMEOUT_RANGE 40 +#define RECURSER_TIMEOUT 50 + +/* The partial ordering between the context array mutex and + * crawler array mutex is that the crawler array mutex cannot + * be locked while the context array mutex is locked + */ +GPtrArray *context_array; +GMutex context_array_mutex; +GCond context_array_cond; + +GMainLoop *main_loop; + +G_LOCK_DEFINE_STATIC (crawler_array_lock); +GPtrArray *crawler_array; + +typedef struct _AddrData AddrData; +typedef struct _TestData TestData; + +struct _AddrData +{ + GMainLoop *loop; + GIOChannel *dest; + gint count; +}; + +struct _TestData +{ + gint current_val; + gint iters; + GIOChannel *in; +}; + +static void cleanup_crawlers (GMainContext *context); + +static gboolean +read_all (GIOChannel *channel, char *buf, gsize len) +{ + gsize bytes_read = 0; + gsize count; + GIOError err; + + while (bytes_read < len) + { + err = g_io_channel_read (channel, buf + bytes_read, len - bytes_read, &count); + if (err) + { + if (err != G_IO_ERROR_AGAIN) + return FALSE; + } + else if (count == 0) + return FALSE; + + bytes_read += count; + } + + return TRUE; +} + +static gboolean +write_all (GIOChannel *channel, char *buf, gsize len) +{ + gsize bytes_written = 0; + gsize count; + GIOError err; + + while (bytes_written < len) + { + err = g_io_channel_write (channel, buf + bytes_written, len - bytes_written, &count); + if (err && err != G_IO_ERROR_AGAIN) + return FALSE; + + bytes_written += count; + } + + return TRUE; +} + +static gboolean +adder_callback (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + char buf1[32]; + char buf2[32]; + + char result[32] = { 0, }; + + AddrData *addr_data = data; + + if (!read_all (source, buf1, 32) || + !read_all (source, buf2, 32)) + { + g_main_loop_quit (addr_data->loop); + return FALSE; + } + + sprintf (result, "%d", atoi(buf1) + atoi(buf2)); + write_all (addr_data->dest, result, 32); + + return TRUE; +} + +static gboolean +timeout_callback (gpointer data) +{ + AddrData *addr_data = data; + + addr_data->count++; + + return TRUE; +} + +static gpointer +adder_thread (gpointer data) +{ + GMainContext *context; + GSource *adder_source; + GSource *timeout_source; + + GIOChannel **channels = data; + AddrData addr_data; + + context = g_main_context_new (); + + g_mutex_lock (&context_array_mutex); + + g_ptr_array_add (context_array, context); + + if (context_array->len == NTHREADS) + g_cond_broadcast (&context_array_cond); + + g_mutex_unlock (&context_array_mutex); + + addr_data.dest = channels[1]; + addr_data.loop = g_main_loop_new (context, FALSE); + addr_data.count = 0; + + adder_source = g_io_create_watch (channels[0], G_IO_IN | G_IO_HUP); + g_source_set_static_name (adder_source, "Adder I/O"); + g_source_set_callback (adder_source, (GSourceFunc)adder_callback, &addr_data, NULL); + g_source_attach (adder_source, context); + g_source_unref (adder_source); + + timeout_source = g_timeout_source_new (10); + g_source_set_static_name (timeout_source, "Adder timeout"); + g_source_set_callback (timeout_source, (GSourceFunc)timeout_callback, &addr_data, NULL); + g_source_set_priority (timeout_source, G_PRIORITY_HIGH); + g_source_attach (timeout_source, context); + g_source_unref (timeout_source); + + g_main_loop_run (addr_data.loop); + + g_io_channel_unref (channels[0]); + g_io_channel_unref (channels[1]); + + g_free (channels); + + g_main_loop_unref (addr_data.loop); + +#ifdef VERBOSE + g_print ("Timeout run %d times\n", addr_data.count); +#endif + + g_mutex_lock (&context_array_mutex); + g_ptr_array_remove (context_array, context); + if (context_array->len == 0) + g_main_loop_quit (main_loop); + g_mutex_unlock (&context_array_mutex); + + cleanup_crawlers (context); + g_main_context_unref (context); + + return NULL; +} + +static void +io_pipe (GIOChannel **channels) +{ + gint fds[2]; + + if (pipe(fds) < 0) + { + int errsv = errno; + g_warning ("Cannot create pipe %s", g_strerror (errsv)); + exit (1); + } + + channels[0] = g_io_channel_unix_new (fds[0]); + channels[1] = g_io_channel_unix_new (fds[1]); + + g_io_channel_set_close_on_unref (channels[0], TRUE); + g_io_channel_set_close_on_unref (channels[1], TRUE); +} + +static void +do_add (GIOChannel *in, gint a, gint b) +{ + char buf1[32] = { 0, }; + char buf2[32] = { 0, }; + + sprintf (buf1, "%d", a); + sprintf (buf2, "%d", b); + + write_all (in, buf1, 32); + write_all (in, buf2, 32); +} + +static gboolean +adder_response (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + char result[32]; + TestData *test_data = data; + + if (!read_all (source, result, 32)) + return FALSE; + + test_data->current_val = atoi (result); + test_data->iters--; + + if (test_data->iters == 0) + { + if (test_data->current_val != ITERS * INCREMENT) + { + g_print ("Addition failed: %d != %d\n", + test_data->current_val, ITERS * INCREMENT); + exit (1); + } + + g_io_channel_unref (source); + g_io_channel_unref (test_data->in); + + g_free (test_data); + + return FALSE; + } + + do_add (test_data->in, test_data->current_val, INCREMENT); + + return TRUE; +} + +static GThread * +create_adder_thread (void) +{ + GThread *thread; + TestData *test_data; + + GIOChannel *in_channels[2]; + GIOChannel *out_channels[2]; + + GIOChannel **sub_channels; + + sub_channels = g_new (GIOChannel *, 2); + + io_pipe (in_channels); + io_pipe (out_channels); + + sub_channels[0] = in_channels[0]; + sub_channels[1] = out_channels[1]; + + thread = g_thread_new ("adder", adder_thread, sub_channels); + + test_data = g_new (TestData, 1); + test_data->in = in_channels[1]; + test_data->current_val = 0; + test_data->iters = ITERS; + + g_io_add_watch (out_channels[0], G_IO_IN | G_IO_HUP, + adder_response, test_data); + + do_add (test_data->in, test_data->current_val, INCREMENT); + + return thread; +} + +static void create_crawler (void); + +static void +remove_crawler (void) +{ + GSource *other_source; + + if (crawler_array->len > 0) + { + other_source = crawler_array->pdata[g_random_int_range (0, crawler_array->len)]; + g_source_destroy (other_source); + g_assert (g_ptr_array_remove_fast (crawler_array, other_source)); + } +} + +static gint +crawler_callback (gpointer data) +{ + GSource *source = data; + + G_LOCK (crawler_array_lock); + + if (!g_ptr_array_remove_fast (crawler_array, source)) + remove_crawler(); + + remove_crawler(); + G_UNLOCK (crawler_array_lock); + + create_crawler(); + create_crawler(); + + return FALSE; +} + +static void +create_crawler (void) +{ + GSource *source = g_timeout_source_new (g_random_int_range (0, CRAWLER_TIMEOUT_RANGE)); + g_source_set_static_name (source, "Crawler timeout"); + g_source_set_callback (source, (GSourceFunc)crawler_callback, source, NULL); + + G_LOCK (crawler_array_lock); + g_ptr_array_add (crawler_array, source); + + g_mutex_lock (&context_array_mutex); + g_source_attach (source, context_array->pdata[g_random_int_range (0, context_array->len)]); + g_source_unref (source); + g_mutex_unlock (&context_array_mutex); + + G_UNLOCK (crawler_array_lock); +} + +static void +cleanup_crawlers (GMainContext *context) +{ + guint i; + + G_LOCK (crawler_array_lock); + for (i = 0; i < crawler_array->len; i++) + { + if (g_source_get_context (crawler_array->pdata[i]) == context) + { + g_source_destroy (g_ptr_array_remove_index (crawler_array, i)); + i--; + } + } + G_UNLOCK (crawler_array_lock); +} + +static gboolean +recurser_idle (gpointer data) +{ + GMainContext *context = data; + gint i; + + for (i = 0; i < 10; i++) + g_main_context_iteration (context, FALSE); + + return FALSE; +} + +static gboolean +recurser_start (gpointer data) +{ + GMainContext *context; + GSource *source; + + g_mutex_lock (&context_array_mutex); + if (context_array->len > 0) + { + context = context_array->pdata[g_random_int_range (0, context_array->len)]; + source = g_idle_source_new (); + g_source_set_static_name (source, "Recursing idle source"); + g_source_set_callback (source, recurser_idle, context, NULL); + g_source_attach (source, context); + g_source_unref (source); + } + g_mutex_unlock (&context_array_mutex); + + return TRUE; +} + +int +main (int argc, + char *argv[]) +{ + gint i; + GThread *threads[NTHREADS]; + + context_array = g_ptr_array_new (); + + crawler_array = g_ptr_array_new (); + + main_loop = g_main_loop_new (NULL, FALSE); + + for (i = 0; i < NTHREADS; i++) + threads[i] = create_adder_thread (); + + /* Wait for all threads to start + */ + g_mutex_lock (&context_array_mutex); + + while (context_array->len < NTHREADS) + g_cond_wait (&context_array_cond, &context_array_mutex); + + g_mutex_unlock (&context_array_mutex); + + for (i = 0; i < NCRAWLERS; i++) + create_crawler (); + + g_timeout_add (RECURSER_TIMEOUT, recurser_start, NULL); + + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + for (i = 0; i < NTHREADS; i++) + g_thread_join (threads[i]); + + g_ptr_array_unref (crawler_array); + g_ptr_array_unref (context_array); + + return 0; +} diff --git a/tests/mapping-test.c b/tests/mapping-test.c new file mode 100644 index 0000000..d4547de --- /dev/null +++ b/tests/mapping-test.c @@ -0,0 +1,321 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2005 Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#include +#include +#include +#include + +#include "glib.h" +#include "gstdio.h" + +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include +#endif + +static gchar *dir, *global_filename, *global_displayname, *childname; + +static gboolean stop = FALSE; + +static gint parent_pid; + +#ifndef G_OS_WIN32 + +static void +handle_usr1 (int signum) +{ + stop = TRUE; +} + +#endif + +static gboolean +check_stop (gpointer data) +{ + GMainLoop *loop = data; + +#ifdef G_OS_WIN32 + stop = g_file_test ("STOP", G_FILE_TEST_EXISTS); +#endif + + if (stop) + g_main_loop_quit (loop); + + return TRUE; +} + +static void +write_or_die (const gchar *filename, + const gchar *contents, + gssize length) +{ + GError *error = NULL; + gchar *displayname; + + if (!g_file_set_contents (filename, contents, length, &error)) + { + displayname = g_filename_display_name (childname); + g_print ("failed to write '%s': %s\n", + displayname, error->message); + exit (1); + } +} + +static GMappedFile * +map_or_die (const gchar *filename, + gboolean writable) +{ + GError *error = NULL; + GMappedFile *map; + gchar *displayname; + + map = g_mapped_file_new (filename, writable, &error); + if (!map) + { + displayname = g_filename_display_name (childname); + g_print ("failed to map '%s' non-writable, shared: %s\n", + displayname, error->message); + exit (1); + } + + return map; +} + +static gboolean +signal_parent (gpointer data) +{ +#ifndef G_OS_WIN32 + kill (parent_pid, SIGUSR1); +#endif + return G_SOURCE_REMOVE; +} + +static int +child_main (int argc, char *argv[]) +{ + GMappedFile *map; + GMainLoop *loop; + + parent_pid = atoi (argv[2]); + map = map_or_die (global_filename, FALSE); + +#ifndef G_OS_WIN32 + signal (SIGUSR1, handle_usr1); +#endif + loop = g_main_loop_new (NULL, FALSE); + g_idle_add (check_stop, loop); + g_idle_add (signal_parent, NULL); + g_main_loop_run (loop); + + g_message ("test_child_private: received parent signal"); + + write_or_die (childname, + g_mapped_file_get_contents (map), + g_mapped_file_get_length (map)); + + signal_parent (NULL); + + return 0; +} + +static void +test_mapping (void) +{ + GMappedFile *map; + + write_or_die (global_filename, "ABC", -1); + + map = map_or_die (global_filename, FALSE); + g_assert (g_mapped_file_get_length (map) == 3); + g_mapped_file_free (map); + + map = map_or_die (global_filename, TRUE); + g_assert (g_mapped_file_get_length (map) == 3); + g_mapped_file_free (map); + g_message ("test_mapping: ok"); +} + +static void +test_private (void) +{ + GError *error = NULL; + GMappedFile *map; + gchar *buffer; + gsize len; + + write_or_die (global_filename, "ABC", -1); + map = map_or_die (global_filename, TRUE); + + buffer = (gchar *)g_mapped_file_get_contents (map); + buffer[0] = '1'; + buffer[1] = '2'; + buffer[2] = '3'; + g_mapped_file_free (map); + + if (!g_file_get_contents (global_filename, &buffer, &len, &error)) + { + g_print ("failed to read '%s': %s\n", + global_displayname, error->message); + exit (1); + + } + g_assert (len == 3); + g_assert (strcmp (buffer, "ABC") == 0); + g_free (buffer); + + g_message ("test_private: ok"); +} + +static void +test_child_private (gchar *argv0) +{ + GError *error = NULL; + GMappedFile *map; + gchar *buffer; + gsize len; + gchar *child_argv[4]; + GPid child_pid; +#ifndef G_OS_WIN32 + GMainLoop *loop; +#endif + gchar pid[100]; + +#ifdef G_OS_WIN32 + g_remove ("STOP"); + g_assert (!g_file_test ("STOP", G_FILE_TEST_EXISTS)); +#endif + + write_or_die (global_filename, "ABC", -1); + map = map_or_die (global_filename, TRUE); + +#ifndef G_OS_WIN32 + signal (SIGUSR1, handle_usr1); +#endif + + g_snprintf (pid, sizeof(pid), "%d", getpid ()); + child_argv[0] = argv0; + child_argv[1] = "mapchild"; + child_argv[2] = pid; + child_argv[3] = NULL; + if (!g_spawn_async (dir, child_argv, NULL, + 0, NULL, NULL, &child_pid, &error)) + { + g_print ("failed to spawn child: %s\n", + error->message); + exit (1); + } + g_message ("test_child_private: child spawned"); + +#ifndef G_OS_WIN32 + loop = g_main_loop_new (NULL, FALSE); + g_idle_add (check_stop, loop); + g_main_loop_run (loop); + stop = FALSE; +#else + g_usleep (2000000); +#endif + + g_message ("test_child_private: received first child signal"); + + buffer = (gchar *)g_mapped_file_get_contents (map); + buffer[0] = '1'; + buffer[1] = '2'; + buffer[2] = '3'; + g_mapped_file_free (map); + +#ifndef G_OS_WIN32 + kill (child_pid, SIGUSR1); +#else + g_file_set_contents ("STOP", "Hey there\n", -1, NULL); +#endif + +#ifndef G_OS_WIN32 + g_idle_add (check_stop, loop); + g_main_loop_run (loop); +#else + g_usleep (2000000); +#endif + + g_message ("test_child_private: received second child signal"); + + if (!g_file_get_contents (childname, &buffer, &len, &error)) + { + gchar *name; + + name = g_filename_display_name (childname); + g_print ("failed to read '%s': %s\n", name, error->message); + exit (1); + } + g_assert (len == 3); + g_assert (strcmp (buffer, "ABC") == 0); + g_free (buffer); + + g_message ("test_child_private: ok"); +} + +static int +parent_main (int argc, + char *argv[]) +{ + /* test mapping with various flag combinations */ + test_mapping (); + + /* test private modification */ + test_private (); + + /* test multiple clients, non-shared */ + test_child_private (argv[0]); + + return 0; +} + +int +main (int argc, + char *argv[]) +{ + int ret; +#ifndef G_OS_WIN32 + sigset_t sig_mask, old_mask; + + sigemptyset (&sig_mask); + sigaddset (&sig_mask, SIGUSR1); + if (sigprocmask (SIG_UNBLOCK, &sig_mask, &old_mask) == 0) + { + if (sigismember (&old_mask, SIGUSR1)) + g_message ("SIGUSR1 was blocked, unblocking it"); + } +#endif + + dir = g_get_current_dir (); + global_filename = g_build_filename (dir, "maptest", NULL); + global_displayname = g_filename_display_name (global_filename); + childname = g_build_filename (dir, "mapchild", NULL); + + if (argc > 1) + ret = child_main (argc, argv); + else + ret = parent_main (argc, argv); + + g_free (childname); + g_free (global_filename); + g_free (global_displayname); + g_free (dir); + + return ret; +} diff --git a/tests/memchunks.c b/tests/memchunks.c new file mode 100644 index 0000000..f574ed8 --- /dev/null +++ b/tests/memchunks.c @@ -0,0 +1,603 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include +#include + +#include "glib.h" + +/* notes on macros: + * if ENABLE_GC_FRIENDLY is defined, freed memory should be 0-wiped. + */ + +#define MEM_PROFILE_TABLE_SIZE 4096 + +#define MEM_AREA_SIZE 4L + +static guint mem_chunk_recursion = 0; +# define MEM_CHUNK_ROUTINE_COUNT() (mem_chunk_recursion) +# define ENTER_MEM_CHUNK_ROUTINE() (mem_chunk_recursion = MEM_CHUNK_ROUTINE_COUNT () + 1) +# define LEAVE_MEM_CHUNK_ROUTINE() (mem_chunk_recursion = MEM_CHUNK_ROUTINE_COUNT () - 1) + +/* --- old memchunk prototypes --- */ +GMemChunk* old_mem_chunk_new (const gchar *name, + gulong atom_size, + gulong area_size, + gint type); +void old_mem_chunk_destroy (GMemChunk *mem_chunk); +gpointer old_mem_chunk_alloc (GMemChunk *mem_chunk); +gpointer old_mem_chunk_alloc0 (GMemChunk *mem_chunk); +void old_mem_chunk_free (GMemChunk *mem_chunk, + gpointer mem); +void old_mem_chunk_clean (GMemChunk *mem_chunk); +void old_mem_chunk_reset (GMemChunk *mem_chunk); +void old_mem_chunk_print (GMemChunk *mem_chunk); +void old_mem_chunk_info (void); + + +/* --- MemChunks --- */ +#ifndef G_ALLOC_AND_FREE +typedef struct _GAllocator GAllocator; +typedef struct _GMemChunk GMemChunk; +#define G_ALLOC_ONLY 1 +#define G_ALLOC_AND_FREE 2 +#endif + +typedef struct _GFreeAtom GFreeAtom; +typedef struct _GMemArea GMemArea; + +struct _GFreeAtom +{ + GFreeAtom *next; +}; + +struct _GMemArea +{ + GMemArea *next; /* the next mem area */ + GMemArea *prev; /* the previous mem area */ + gulong index; /* the current index into the "mem" array */ + gulong free; /* the number of free bytes in this mem area */ + gulong allocated; /* the number of atoms allocated from this area */ + gulong mark; /* is this mem area marked for deletion */ + gchar mem[MEM_AREA_SIZE]; /* the mem array from which atoms get allocated + * the actual size of this array is determined by + * the mem chunk "area_size". ANSI says that it + * must be declared to be the maximum size it + * can possibly be (even though the actual size + * may be less). + */ +}; + +struct _GMemChunk +{ + const gchar *name; /* name of this MemChunk...used for debugging output */ + gint type; /* the type of MemChunk: ALLOC_ONLY or ALLOC_AND_FREE */ + gint num_mem_areas; /* the number of memory areas */ + gint num_marked_areas; /* the number of areas marked for deletion */ + guint atom_size; /* the size of an atom */ + gulong area_size; /* the size of a memory area */ + GMemArea *mem_area; /* the current memory area */ + GMemArea *mem_areas; /* a list of all the mem areas owned by this chunk */ + GMemArea *free_mem_area; /* the free area...which is about to be destroyed */ + GFreeAtom *free_atoms; /* the free atoms list */ + GTree *mem_tree; /* tree of mem areas sorted by memory address */ + GMemChunk *next; /* pointer to the next chunk */ + GMemChunk *prev; /* pointer to the previous chunk */ +}; + + +static gulong old_mem_chunk_compute_size (gulong size, + gulong min_size) G_GNUC_CONST; +static gint old_mem_chunk_area_compare (GMemArea *a, + GMemArea *b); +static gint old_mem_chunk_area_search (GMemArea *a, + gchar *addr); + +/* here we can't use StaticMutexes, as they depend upon a working + * g_malloc, the same holds true for StaticPrivate + */ +static GMutex mem_chunks_lock; +static GMemChunk *mem_chunks = NULL; + +GMemChunk* +old_mem_chunk_new (const gchar *name, + gulong atom_size, + gulong area_size, + gint type) +{ + GMemChunk *mem_chunk; + gulong rarea_size; + + g_return_val_if_fail (atom_size > 0, NULL); + g_return_val_if_fail (area_size >= atom_size, NULL); + + ENTER_MEM_CHUNK_ROUTINE (); + + area_size = (area_size + atom_size - 1) / atom_size; + area_size *= atom_size; + + mem_chunk = g_new (GMemChunk, 1); + mem_chunk->name = name; + mem_chunk->type = type; + mem_chunk->num_mem_areas = 0; + mem_chunk->num_marked_areas = 0; + mem_chunk->mem_area = NULL; + mem_chunk->free_mem_area = NULL; + mem_chunk->free_atoms = NULL; + mem_chunk->mem_tree = NULL; + mem_chunk->mem_areas = NULL; + mem_chunk->atom_size = atom_size; + + if (mem_chunk->type == G_ALLOC_AND_FREE) + mem_chunk->mem_tree = g_tree_new ((GCompareFunc) old_mem_chunk_area_compare); + + if (mem_chunk->atom_size % G_MEM_ALIGN) + mem_chunk->atom_size += G_MEM_ALIGN - (mem_chunk->atom_size % G_MEM_ALIGN); + + rarea_size = area_size + sizeof (GMemArea) - MEM_AREA_SIZE; + rarea_size = old_mem_chunk_compute_size (rarea_size, atom_size + sizeof (GMemArea) - MEM_AREA_SIZE); + mem_chunk->area_size = rarea_size - (sizeof (GMemArea) - MEM_AREA_SIZE); + + g_mutex_lock (&mem_chunks_lock); + mem_chunk->next = mem_chunks; + mem_chunk->prev = NULL; + if (mem_chunks) + mem_chunks->prev = mem_chunk; + mem_chunks = mem_chunk; + g_mutex_unlock (&mem_chunks_lock); + + LEAVE_MEM_CHUNK_ROUTINE (); + + return mem_chunk; +} + +void +old_mem_chunk_destroy (GMemChunk *mem_chunk) +{ + GMemArea *mem_areas; + GMemArea *temp_area; + + g_return_if_fail (mem_chunk != NULL); + + ENTER_MEM_CHUNK_ROUTINE (); + + mem_areas = mem_chunk->mem_areas; + while (mem_areas) + { + temp_area = mem_areas; + mem_areas = mem_areas->next; + g_free (temp_area); + } + + g_mutex_lock (&mem_chunks_lock); + if (mem_chunk->next) + mem_chunk->next->prev = mem_chunk->prev; + if (mem_chunk->prev) + mem_chunk->prev->next = mem_chunk->next; + + if (mem_chunk == mem_chunks) + mem_chunks = mem_chunks->next; + g_mutex_unlock (&mem_chunks_lock); + + if (mem_chunk->type == G_ALLOC_AND_FREE) + g_tree_destroy (mem_chunk->mem_tree); + + g_free (mem_chunk); + + LEAVE_MEM_CHUNK_ROUTINE (); +} + +gpointer +old_mem_chunk_alloc (GMemChunk *mem_chunk) +{ + GMemArea *temp_area; + gpointer mem; + + ENTER_MEM_CHUNK_ROUTINE (); + + g_return_val_if_fail (mem_chunk != NULL, NULL); + + while (mem_chunk->free_atoms) + { + /* Get the first piece of memory on the "free_atoms" list. + * We can go ahead and destroy the list node we used to keep + * track of it with and to update the "free_atoms" list to + * point to its next element. + */ + mem = mem_chunk->free_atoms; + mem_chunk->free_atoms = mem_chunk->free_atoms->next; + + /* Determine which area this piece of memory is allocated from */ + temp_area = g_tree_search (mem_chunk->mem_tree, + (GCompareFunc) old_mem_chunk_area_search, + mem); + + /* If the area has been marked, then it is being destroyed. + * (ie marked to be destroyed). + * We check to see if all of the segments on the free list that + * reference this area have been removed. This occurs when + * the amount of free memory is less than the allocatable size. + * If the chunk should be freed, then we place it in the "free_mem_area". + * This is so we make sure not to free the mem area here and then + * allocate it again a few lines down. + * If we don't allocate a chunk a few lines down then the "free_mem_area" + * will be freed. + * If there is already a "free_mem_area" then we'll just free this mem area. + */ + if (temp_area->mark) + { + /* Update the "free" memory available in that area */ + temp_area->free += mem_chunk->atom_size; + + if (temp_area->free == mem_chunk->area_size) + { + if (temp_area == mem_chunk->mem_area) + mem_chunk->mem_area = NULL; + + if (mem_chunk->free_mem_area) + { + mem_chunk->num_mem_areas -= 1; + + if (temp_area->next) + temp_area->next->prev = temp_area->prev; + if (temp_area->prev) + temp_area->prev->next = temp_area->next; + if (temp_area == mem_chunk->mem_areas) + mem_chunk->mem_areas = mem_chunk->mem_areas->next; + + if (mem_chunk->type == G_ALLOC_AND_FREE) + g_tree_remove (mem_chunk->mem_tree, temp_area); + g_free (temp_area); + } + else + mem_chunk->free_mem_area = temp_area; + + mem_chunk->num_marked_areas -= 1; + } + } + else + { + /* Update the number of allocated atoms count. + */ + temp_area->allocated += 1; + + /* The area wasn't marked...return the memory + */ + goto outa_here; + } + } + + /* If there isn't a current mem area or the current mem area is out of space + * then allocate a new mem area. We'll first check and see if we can use + * the "free_mem_area". Otherwise we'll just malloc the mem area. + */ + if ((!mem_chunk->mem_area) || + ((mem_chunk->mem_area->index + mem_chunk->atom_size) > mem_chunk->area_size)) + { + if (mem_chunk->free_mem_area) + { + mem_chunk->mem_area = mem_chunk->free_mem_area; + mem_chunk->free_mem_area = NULL; + } + else + { +#ifdef ENABLE_GC_FRIENDLY + mem_chunk->mem_area = (GMemArea*) g_malloc0 (sizeof (GMemArea) - + MEM_AREA_SIZE + + mem_chunk->area_size); +#else /* !ENABLE_GC_FRIENDLY */ + mem_chunk->mem_area = (GMemArea*) g_malloc (sizeof (GMemArea) - + MEM_AREA_SIZE + + mem_chunk->area_size); +#endif /* ENABLE_GC_FRIENDLY */ + + mem_chunk->num_mem_areas += 1; + mem_chunk->mem_area->next = mem_chunk->mem_areas; + mem_chunk->mem_area->prev = NULL; + + if (mem_chunk->mem_areas) + mem_chunk->mem_areas->prev = mem_chunk->mem_area; + mem_chunk->mem_areas = mem_chunk->mem_area; + + if (mem_chunk->type == G_ALLOC_AND_FREE) + g_tree_insert (mem_chunk->mem_tree, mem_chunk->mem_area, mem_chunk->mem_area); + } + + mem_chunk->mem_area->index = 0; + mem_chunk->mem_area->free = mem_chunk->area_size; + mem_chunk->mem_area->allocated = 0; + mem_chunk->mem_area->mark = 0; + } + + /* Get the memory and modify the state variables appropriately. + */ + mem = (gpointer) &mem_chunk->mem_area->mem[mem_chunk->mem_area->index]; + mem_chunk->mem_area->index += mem_chunk->atom_size; + mem_chunk->mem_area->free -= mem_chunk->atom_size; + mem_chunk->mem_area->allocated += 1; + + outa_here: + + LEAVE_MEM_CHUNK_ROUTINE (); + + return mem; +} + +gpointer +old_mem_chunk_alloc0 (GMemChunk *mem_chunk) +{ + gpointer mem; + + mem = old_mem_chunk_alloc (mem_chunk); + if (mem) + { + memset (mem, 0, mem_chunk->atom_size); + } + + return mem; +} + +void +old_mem_chunk_free (GMemChunk *mem_chunk, + gpointer mem) +{ + GMemArea *temp_area; + GFreeAtom *free_atom; + + g_return_if_fail (mem_chunk != NULL); + g_return_if_fail (mem != NULL); + + ENTER_MEM_CHUNK_ROUTINE (); + +#ifdef ENABLE_GC_FRIENDLY + memset (mem, 0, mem_chunk->atom_size); +#endif /* ENABLE_GC_FRIENDLY */ + + /* Don't do anything if this is an ALLOC_ONLY chunk + */ + if (mem_chunk->type == G_ALLOC_AND_FREE) + { + /* Place the memory on the "free_atoms" list + */ + free_atom = (GFreeAtom*) mem; + free_atom->next = mem_chunk->free_atoms; + mem_chunk->free_atoms = free_atom; + + temp_area = g_tree_search (mem_chunk->mem_tree, + (GCompareFunc) old_mem_chunk_area_search, + mem); + + temp_area->allocated -= 1; + + if (temp_area->allocated == 0) + { + temp_area->mark = 1; + mem_chunk->num_marked_areas += 1; + } + } + + LEAVE_MEM_CHUNK_ROUTINE (); +} + +/* This doesn't free the free_area if there is one */ +void +old_mem_chunk_clean (GMemChunk *mem_chunk) +{ + GMemArea *mem_area; + GFreeAtom *prev_free_atom; + GFreeAtom *temp_free_atom; + gpointer mem; + + g_return_if_fail (mem_chunk != NULL); + + ENTER_MEM_CHUNK_ROUTINE (); + + if (mem_chunk->type == G_ALLOC_AND_FREE) + { + prev_free_atom = NULL; + temp_free_atom = mem_chunk->free_atoms; + + while (temp_free_atom) + { + mem = (gpointer) temp_free_atom; + + mem_area = g_tree_search (mem_chunk->mem_tree, + (GCompareFunc) old_mem_chunk_area_search, + mem); + + /* If this mem area is marked for destruction then delete the + * area and list node and decrement the free mem. + */ + if (mem_area->mark) + { + if (prev_free_atom) + prev_free_atom->next = temp_free_atom->next; + else + mem_chunk->free_atoms = temp_free_atom->next; + temp_free_atom = temp_free_atom->next; + + mem_area->free += mem_chunk->atom_size; + if (mem_area->free == mem_chunk->area_size) + { + mem_chunk->num_mem_areas -= 1; + mem_chunk->num_marked_areas -= 1; + + if (mem_area->next) + mem_area->next->prev = mem_area->prev; + if (mem_area->prev) + mem_area->prev->next = mem_area->next; + if (mem_area == mem_chunk->mem_areas) + mem_chunk->mem_areas = mem_chunk->mem_areas->next; + if (mem_area == mem_chunk->mem_area) + mem_chunk->mem_area = NULL; + + if (mem_chunk->type == G_ALLOC_AND_FREE) + g_tree_remove (mem_chunk->mem_tree, mem_area); + g_free (mem_area); + } + } + else + { + prev_free_atom = temp_free_atom; + temp_free_atom = temp_free_atom->next; + } + } + } + LEAVE_MEM_CHUNK_ROUTINE (); +} + +void +old_mem_chunk_reset (GMemChunk *mem_chunk) +{ + GMemArea *mem_areas; + GMemArea *temp_area; + + g_return_if_fail (mem_chunk != NULL); + + ENTER_MEM_CHUNK_ROUTINE (); + + mem_areas = mem_chunk->mem_areas; + mem_chunk->num_mem_areas = 0; + mem_chunk->mem_areas = NULL; + mem_chunk->mem_area = NULL; + + while (mem_areas) + { + temp_area = mem_areas; + mem_areas = mem_areas->next; + g_free (temp_area); + } + + mem_chunk->free_atoms = NULL; + + if (mem_chunk->mem_tree) + { + g_tree_destroy (mem_chunk->mem_tree); + mem_chunk->mem_tree = g_tree_new ((GCompareFunc) old_mem_chunk_area_compare); + } + + LEAVE_MEM_CHUNK_ROUTINE (); +} + +void +old_mem_chunk_print (GMemChunk *mem_chunk) +{ + GMemArea *mem_areas; + gulong mem; + + g_return_if_fail (mem_chunk != NULL); + + mem_areas = mem_chunk->mem_areas; + mem = 0; + + while (mem_areas) + { + mem += mem_chunk->area_size - mem_areas->free; + mem_areas = mem_areas->next; + } + + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, + "%s: %ld bytes using %d mem areas", + mem_chunk->name, mem, mem_chunk->num_mem_areas); +} + +void +old_mem_chunk_info (void) +{ + GMemChunk *mem_chunk; + gint count; + + count = 0; + g_mutex_lock (&mem_chunks_lock); + mem_chunk = mem_chunks; + while (mem_chunk) + { + count += 1; + mem_chunk = mem_chunk->next; + } + g_mutex_unlock (&mem_chunks_lock); + + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "%d mem chunks", count); + + g_mutex_lock (&mem_chunks_lock); + mem_chunk = mem_chunks; + g_mutex_unlock (&mem_chunks_lock); + + while (mem_chunk) + { + old_mem_chunk_print ((GMemChunk*) mem_chunk); + mem_chunk = mem_chunk->next; + } +} + +static gulong +old_mem_chunk_compute_size (gulong size, + gulong min_size) +{ + gulong power_of_2; + gulong lower, upper; + + power_of_2 = 16; + while (power_of_2 < size) + power_of_2 <<= 1; + + lower = power_of_2 >> 1; + upper = power_of_2; + + if (size - lower < upper - size && lower >= min_size) + return lower; + else + return upper; +} + +static gint +old_mem_chunk_area_compare (GMemArea *a, + GMemArea *b) +{ + if (a->mem > b->mem) + return 1; + else if (a->mem < b->mem) + return -1; + return 0; +} + +static gint +old_mem_chunk_area_search (GMemArea *a, + gchar *addr) +{ + if (a->mem <= addr) + { + if (addr < &a->mem[a->index]) + return 0; + return 1; + } + return -1; +} diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000..c95fa1d --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,139 @@ +# tests + +# Not entirely random of course, but at least it changes over time +random_number = minor_version + meson.version().split('.').get(1).to_int() + +test_env = environment() +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +test_env.set('G_DEBUG', 'gc-friendly') +test_env.set('MALLOC_CHECK_', '2') +test_env.set('MALLOC_PERTURB_', '@0@'.format(random_number % 256)) + +test_cargs = ['-DG_LOG_DOMAIN="GLib"', '-UG_DISABLE_ASSERT'] + +subdir('gobject') +subdir('refcount') + +tests = { + 'gio-test' : {}, + 'mainloop-test' : {}, + 'mapping-test' : {}, + 'onceinit' : {}, + 'slice-threadinit' : { + 'dependencies' : [libgthread_dep], + }, + 'spawn-test' : {}, + 'thread-test' : {}, + 'threadpool-test' : {'suite' : ['slow']}, + 'unicode-encoding' : {}, + 'module-test-library' : { + 'dependencies' : [libgmodule_dep], + 'export_dynamic' : true, + 'source': 'module-test.c', + 'c_args': ['-DMODULE_TYPE="library"'], + }, + 'module-test-plugin' : { + 'dependencies' : [libgmodule_dep], + 'export_dynamic' : true, + 'source': 'module-test.c', + 'c_args': ['-DMODULE_TYPE="plugin"'], + }, +} + +test_extra_programs = { + 'slice-test' : { + 'extra_sources' : ['memchunks.c'], + }, + 'assert-msg-test' : {}, +} + +if host_machine.system() != 'windows' + tests += { + 'timeloop' : {}, + } +else + test_extra_programs += { + 'spawn-test-win32-gui' : {'gui_app' : true} + } +endif + +if installed_tests_enabled + install_data( + 'utf8.txt', + install_dir : installed_tests_execdir, + ) +endif + +module_suffix = [] +# Keep the autotools convention for shared module suffix because GModule +# depends on it: https://gitlab.gnome.org/GNOME/glib/issues/520 +if ['darwin', 'ios'].contains(host_machine.system()) + module_suffix = 'so' +endif + +foreach module : ['moduletestplugin_a', 'moduletestplugin_b'] + shared_module(module + '_plugin', 'lib@0@.c'.format(module), + dependencies : [libglib_dep, libgmodule_dep], + install_dir : installed_tests_execdir, + install : installed_tests_enabled, + name_suffix : module_suffix + ) + shared_library(module + '_library', 'lib@0@.c'.format(module), + dependencies : [libglib_dep, libgmodule_dep], + install_dir : installed_tests_execdir, + install : installed_tests_enabled, + name_suffix : module_suffix + ) +endforeach + +common_c_args = test_cargs + ['-DGLIB_DISABLE_DEPRECATION_WARNINGS'] +common_deps = [libm, thread_dep, libglib_dep] + +foreach test_name, extra_args : tests + source = extra_args.get('source', test_name + '.c') + extra_sources = extra_args.get('extra_sources', []) + install = installed_tests_enabled and extra_args.get('install', true) + template = extra_args.get('tap', false) ? installed_tests_template_tap : installed_tests_template + + if install + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_conf.set('env', '') + configure_file( + input: template, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf + ) + endif + + # FIXME? $(GLIB_DEBUG_FLAGS) + exe = executable(test_name, [source, extra_sources], + c_args : common_c_args + extra_args.get('c_args', []), + dependencies : common_deps + extra_args.get('dependencies', []), + export_dynamic : extra_args.get('export_dynamic', false), + include_directories : extra_args.get('include_directories', []), + install_dir: installed_tests_execdir, + install: install, + ) + + suite = ['glib'] + extra_args.get('suite', []) + timeout = suite.contains('slow') ? test_timeout_slow : test_timeout + # FIXME? TESTS_ENVIRONMENT = LIBCHARSET_ALIAS_DIR=$(top_builddir)/glib/libcharset + test(test_name, exe, env : test_env, timeout : timeout, suite : suite) +endforeach + +foreach program_name, extra_args : test_extra_programs + source = extra_args.get('source', program_name + '.c') + extra_sources = extra_args.get('extra_sources', []) + install = installed_tests_enabled and extra_args.get('install', true) + executable(program_name, [source, extra_sources], + c_args : common_c_args, + dependencies : common_deps + extra_args.get('dependencies', []), + install_dir : installed_tests_execdir, + install : install, + gui_app : extra_args.get('gui_app', false), + ) +endforeach diff --git a/tests/module-test.c b/tests/module-test.c new file mode 100644 index 0000000..a74bc74 --- /dev/null +++ b/tests/module-test.c @@ -0,0 +1,214 @@ +/* module-test.c - test program for GMODULE + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include + +#ifdef _MSC_VER +# define MODULE_FILENAME_PREFIX "" +#else +# define MODULE_FILENAME_PREFIX "lib" +#endif + +gchar* global_state; + +G_MODULE_EXPORT void g_clash_func (void); + +G_MODULE_EXPORT void +g_clash_func (void) +{ + global_state = "global clash"; +} + +typedef void (*SimpleFunc) (void); +typedef void (*GModuleFunc) (GModule *); + +static gchar **gplugin_a_state; +static gchar **gplugin_b_state; + +static void +compare (const gchar *desc, const gchar *expected, const gchar *found) +{ + if (!expected && !found) + return; + + if (expected && found && strcmp (expected, found) == 0) + return; + + g_error ("error: %s state should have been \"%s\", but is \"%s\"", + desc, expected ? expected : "NULL", found ? found : "NULL"); +} + +static void +test_states (const gchar *global, const gchar *gplugin_a, + const gchar *gplugin_b) +{ + compare ("global", global, global_state); + compare ("Plugin A", gplugin_a, *gplugin_a_state); + compare ("Plugin B", gplugin_b, *gplugin_b_state); + + global_state = *gplugin_a_state = *gplugin_b_state = NULL; +} + +static SimpleFunc plugin_clash_func = NULL; + +int +main (int argc, + char **argv) +{ + GModule *module_self, *module_a, *module_b; + gchar *plugin_a, *plugin_b; + SimpleFunc f_a, f_b, f_self; + GModuleFunc gmod_f; + GError *error = NULL; + + g_test_init (&argc, &argv, NULL); + + if (!g_module_supported ()) + g_error ("dynamic modules not supported"); + + plugin_a = g_test_build_filename (G_TEST_BUILT, MODULE_FILENAME_PREFIX "moduletestplugin_a_" MODULE_TYPE, NULL); + plugin_b = g_test_build_filename (G_TEST_BUILT, MODULE_FILENAME_PREFIX "moduletestplugin_b_" MODULE_TYPE, NULL); + + /* module handles */ + + module_self = g_module_open_full (NULL, G_MODULE_BIND_LAZY, &error); + g_assert_no_error (error); + if (!module_self) + g_error ("error: %s", g_module_error ()); + + /* On Windows static compilation mode, glib API symbols are not + * exported dynamically by definition. */ +#if !defined(G_PLATFORM_WIN32) || !defined(GLIB_STATIC_COMPILATION) + if (!g_module_symbol (module_self, "g_module_close", (gpointer *) &f_self)) + g_error ("error: %s", g_module_error ()); +#endif + + module_a = g_module_open_full (plugin_a, G_MODULE_BIND_LAZY, &error); + g_assert_no_error (error); + if (!module_a) + g_error ("error: %s", g_module_error ()); + + module_b = g_module_open_full (plugin_b, G_MODULE_BIND_LAZY, &error); + g_assert_no_error (error); + if (!module_b) + g_error ("error: %s", g_module_error ()); + + /* get plugin state vars */ + + if (!g_module_symbol (module_a, "gplugin_a_state", + (gpointer *) &gplugin_a_state)) + g_error ("error: %s", g_module_error ()); + + if (!g_module_symbol (module_b, "gplugin_b_state", + (gpointer *) &gplugin_b_state)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, "check-init"); + + /* get plugin specific symbols and call them + */ + if (!g_module_symbol (module_a, "gplugin_a_func", (gpointer *) &f_a)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, NULL); + + if (!g_module_symbol (module_b, "gplugin_b_func", (gpointer *) &f_b)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, NULL); + + f_a (); + test_states (NULL, "Hello world", NULL); + + f_b (); + test_states (NULL, NULL, "Hello world"); + + /* get and call globally clashing functions + */ + + if (!g_module_symbol (module_self, "g_clash_func", (gpointer *) &f_self)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, NULL); + + if (!g_module_symbol (module_a, "g_clash_func", (gpointer *) &f_a)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, NULL); + + if (!g_module_symbol (module_b, "g_clash_func", (gpointer *) &f_b)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, NULL); + + f_self (); + test_states ("global clash", NULL, NULL); + + f_a (); + test_states (NULL, "global clash", NULL); + + f_b (); + test_states (NULL, NULL, "global clash"); + + /* get and call clashing plugin functions */ + + if (!g_module_symbol (module_a, "gplugin_clash_func", (gpointer *) &f_a)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, NULL); + + if (!g_module_symbol (module_b, "gplugin_clash_func", (gpointer *) &f_b)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, NULL); + + plugin_clash_func = f_a; + plugin_clash_func (); + test_states (NULL, "plugin clash", NULL); + + plugin_clash_func = f_b; + plugin_clash_func (); + test_states (NULL, NULL, "plugin clash"); + + /* call gmodule function from A */ + + if (!g_module_symbol (module_a, "gplugin_a_module_func", (gpointer *) &gmod_f)) + g_error ("error: %s", g_module_error ()); + test_states (NULL, NULL, NULL); + + gmod_f (module_b); + test_states (NULL, NULL, "BOOH"); + + gmod_f (module_a); + test_states (NULL, "BOOH", NULL); + + /* unload plugins */ + + if (!g_module_close (module_a)) + g_error ("error: %s", g_module_error ()); + + if (!g_module_close (module_b)) + g_error ("error: %s", g_module_error ()); + + g_free (plugin_a); + g_free (plugin_b); + g_module_close (module_self); + return 0; +} diff --git a/tests/onceinit.c b/tests/onceinit.c new file mode 100644 index 0000000..4f30739 --- /dev/null +++ b/tests/onceinit.c @@ -0,0 +1,273 @@ +/* g_once_init_*() test + * Copyright (C) 2007 Tim Janik + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#include +#include + +#define N_THREADS (13) + +static GMutex tmutex; +static GCond tcond; +static int thread_call_count = 0; /* (atomic) */ +static char dummy_value = 'x'; + +static void +assert_singleton_execution1 (void) +{ + static int seen_execution = 0; /* (atomic) */ + int old_seen_execution = g_atomic_int_add (&seen_execution, 1); + if (old_seen_execution != 0) + g_error ("%s: function executed more than once", G_STRFUNC); +} + +static void +assert_singleton_execution2 (void) +{ + static int seen_execution = 0; /* (atomic) */ + int old_seen_execution = g_atomic_int_add (&seen_execution, 1); + if (old_seen_execution != 0) + g_error ("%s: function executed more than once", G_STRFUNC); +} + +static void +assert_singleton_execution3 (void) +{ + static int seen_execution = 0; /* (atomic) */ + int old_seen_execution = g_atomic_int_add (&seen_execution, 1); + if (old_seen_execution != 0) + g_error ("%s: function executed more than once", G_STRFUNC); +} + +static void +initializer1 (void) +{ + static gsize initialized = 0; + if (g_once_init_enter (&initialized)) + { + gsize initval = 42; + assert_singleton_execution1(); + g_once_init_leave (&initialized, initval); + } +} + +static gpointer +initializer2 (void) +{ + static gsize initialized = 0; + if (g_once_init_enter (&initialized)) + { + void *pointer_value = &dummy_value; + assert_singleton_execution2(); + g_once_init_leave (&initialized, (gsize) pointer_value); + } + return (void*) initialized; +} + +static void +initializer3 (void) +{ + static gsize initialized = 0; + if (g_once_init_enter (&initialized)) + { + gsize initval = 42; + assert_singleton_execution3(); + g_usleep (25 * 1000); /* waste time for multiple threads to wait */ + g_once_init_leave (&initialized, initval); + } +} + +static gpointer +tmain_call_initializer3 (gpointer user_data) +{ + g_mutex_lock (&tmutex); + g_cond_wait (&tcond, &tmutex); + g_mutex_unlock (&tmutex); + //g_printf ("["); + initializer3(); + //g_printf ("]\n"); + g_atomic_int_add (&thread_call_count, 1); + return NULL; +} + +static void* stress_concurrent_initializers (void*); + +int +main (int argc, + char *argv[]) +{ + G_GNUC_UNUSED GThread *threads[N_THREADS]; + int i; + void *p; + + /* test simple initializer */ + initializer1(); + initializer1(); + /* test pointer initializer */ + p = initializer2(); + g_assert (p == &dummy_value); + p = initializer2(); + g_assert (p == &dummy_value); + /* start multiple threads for initializer3() */ + g_mutex_lock (&tmutex); + for (i = 0; i < N_THREADS; i++) + threads[i] = g_thread_create (tmain_call_initializer3, 0, FALSE, NULL); + g_mutex_unlock (&tmutex); + /* concurrently call initializer3() */ + g_cond_broadcast (&tcond); + /* loop until all threads passed the call to initializer3() */ + while (g_atomic_int_get (&thread_call_count) < i) + { + if (rand() % 2) + g_thread_yield(); /* concurrent shuffling for single core */ + else + g_usleep (1000); /* concurrent shuffling for multi core */ + g_cond_broadcast (&tcond); + } + /* call multiple (unoptimized) initializers from multiple threads */ + g_mutex_lock (&tmutex); + g_atomic_int_set (&thread_call_count, 0); + for (i = 0; i < N_THREADS; i++) + g_thread_create (stress_concurrent_initializers, 0, FALSE, NULL); + g_mutex_unlock (&tmutex); + while (g_atomic_int_get (&thread_call_count) < 256 * 4 * N_THREADS) + g_usleep (50 * 1000); /* wait for all 5 threads to complete */ + return 0; +} + +/* get rid of g_once_init_enter-optimizations in the below definitions + * to uncover possible races in the g_once_init_enter_impl()/ + * g_once_init_leave() implementations + */ +#undef g_once_init_enter +#undef g_once_init_leave + +/* define 16 * 16 simple initializers */ +#define DEFINE_TEST_INITIALIZER(N) \ + static void \ + test_initializer_##N (void) \ + { \ + static gsize initialized = 0; \ + if (g_once_init_enter (&initialized)) \ + { \ + g_free (g_strdup_printf ("cpuhog%5d", 1)); \ + g_free (g_strdup_printf ("cpuhog%6d", 2)); \ + g_free (g_strdup_printf ("cpuhog%7d", 3)); \ + g_once_init_leave (&initialized, 1); \ + } \ + } +#define DEFINE_16_TEST_INITIALIZERS(P) \ + DEFINE_TEST_INITIALIZER (P##0) \ + DEFINE_TEST_INITIALIZER (P##1) \ + DEFINE_TEST_INITIALIZER (P##2) \ + DEFINE_TEST_INITIALIZER (P##3) \ + DEFINE_TEST_INITIALIZER (P##4) \ + DEFINE_TEST_INITIALIZER (P##5) \ + DEFINE_TEST_INITIALIZER (P##6) \ + DEFINE_TEST_INITIALIZER (P##7) \ + DEFINE_TEST_INITIALIZER (P##8) \ + DEFINE_TEST_INITIALIZER (P##9) \ + DEFINE_TEST_INITIALIZER (P##a) \ + DEFINE_TEST_INITIALIZER (P##b) \ + DEFINE_TEST_INITIALIZER (P##c) \ + DEFINE_TEST_INITIALIZER (P##d) \ + DEFINE_TEST_INITIALIZER (P##e) \ + DEFINE_TEST_INITIALIZER (P##f) +#define DEFINE_256_TEST_INITIALIZERS(P) \ + DEFINE_16_TEST_INITIALIZERS (P##_0) \ + DEFINE_16_TEST_INITIALIZERS (P##_1) \ + DEFINE_16_TEST_INITIALIZERS (P##_2) \ + DEFINE_16_TEST_INITIALIZERS (P##_3) \ + DEFINE_16_TEST_INITIALIZERS (P##_4) \ + DEFINE_16_TEST_INITIALIZERS (P##_5) \ + DEFINE_16_TEST_INITIALIZERS (P##_6) \ + DEFINE_16_TEST_INITIALIZERS (P##_7) \ + DEFINE_16_TEST_INITIALIZERS (P##_8) \ + DEFINE_16_TEST_INITIALIZERS (P##_9) \ + DEFINE_16_TEST_INITIALIZERS (P##_a) \ + DEFINE_16_TEST_INITIALIZERS (P##_b) \ + DEFINE_16_TEST_INITIALIZERS (P##_c) \ + DEFINE_16_TEST_INITIALIZERS (P##_d) \ + DEFINE_16_TEST_INITIALIZERS (P##_e) \ + DEFINE_16_TEST_INITIALIZERS (P##_f) + +/* list 16 * 16 simple initializers */ +#define LIST_16_TEST_INITIALIZERS(P) \ + test_initializer_##P##0, \ + test_initializer_##P##1, \ + test_initializer_##P##2, \ + test_initializer_##P##3, \ + test_initializer_##P##4, \ + test_initializer_##P##5, \ + test_initializer_##P##6, \ + test_initializer_##P##7, \ + test_initializer_##P##8, \ + test_initializer_##P##9, \ + test_initializer_##P##a, \ + test_initializer_##P##b, \ + test_initializer_##P##c, \ + test_initializer_##P##d, \ + test_initializer_##P##e, \ + test_initializer_##P##f +#define LIST_256_TEST_INITIALIZERS(P) \ + LIST_16_TEST_INITIALIZERS (P##_0), \ + LIST_16_TEST_INITIALIZERS (P##_1), \ + LIST_16_TEST_INITIALIZERS (P##_2), \ + LIST_16_TEST_INITIALIZERS (P##_3), \ + LIST_16_TEST_INITIALIZERS (P##_4), \ + LIST_16_TEST_INITIALIZERS (P##_5), \ + LIST_16_TEST_INITIALIZERS (P##_6), \ + LIST_16_TEST_INITIALIZERS (P##_7), \ + LIST_16_TEST_INITIALIZERS (P##_8), \ + LIST_16_TEST_INITIALIZERS (P##_9), \ + LIST_16_TEST_INITIALIZERS (P##_a), \ + LIST_16_TEST_INITIALIZERS (P##_b), \ + LIST_16_TEST_INITIALIZERS (P##_c), \ + LIST_16_TEST_INITIALIZERS (P##_d), \ + LIST_16_TEST_INITIALIZERS (P##_e), \ + LIST_16_TEST_INITIALIZERS (P##_f) + +/* define 4 * 256 initializers */ +DEFINE_256_TEST_INITIALIZERS (stress1); +DEFINE_256_TEST_INITIALIZERS (stress2); +DEFINE_256_TEST_INITIALIZERS (stress3); +DEFINE_256_TEST_INITIALIZERS (stress4); + +/* call the above 1024 initializers */ +static void* +stress_concurrent_initializers (void *user_data) +{ + static void (*initializers[]) (void) = { + LIST_256_TEST_INITIALIZERS (stress1), + LIST_256_TEST_INITIALIZERS (stress2), + LIST_256_TEST_INITIALIZERS (stress3), + LIST_256_TEST_INITIALIZERS (stress4), + }; + gsize i; + /* sync to main thread */ + g_mutex_lock (&tmutex); + g_mutex_unlock (&tmutex); + /* initialize concurrently */ + for (i = 0; i < G_N_ELEMENTS (initializers); i++) + { + initializers[i](); + g_atomic_int_add (&thread_call_count, 1); + } + return NULL; +} diff --git a/tests/refcount/meson.build b/tests/refcount/meson.build new file mode 100644 index 0000000..02571fe --- /dev/null +++ b/tests/refcount/meson.build @@ -0,0 +1,60 @@ +refcount_tests = { + 'objects' : {}, + 'objects2' : {'suite' : ['slow']}, + 'properties' : {}, + 'properties2' : {'suite' : ['slow']}, + 'properties3' : {'suite' : ['slow']}, + 'properties4' : {}, + 'signal1' : { + 'source' : 'signals.c', + 'c_args' : ['-DTESTNUM=1'], + }, + 'signal2' : { + 'source' : 'signals.c', + 'c_args' : ['-DTESTNUM=2'], + }, + 'signal3' : { + 'source' : 'signals.c', + 'c_args' : ['-DTESTNUM=3'], + }, + 'signal4' : { + 'source' : 'signals.c', + 'c_args' : ['-DTESTNUM=4'], + }, +} + +common_c_args = test_cargs + ['-DGLIB_DISABLE_DEPRECATION_WARNINGS'] +common_deps = [libm, thread_dep, libglib_dep, libgobject_dep] + +foreach test_name, extra_args : refcount_tests + source = extra_args.get('source', test_name + '.c') + extra_sources = extra_args.get('extra_sources', []) + install = installed_tests_enabled and extra_args.get('install', true) + + if install + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_conf.set('env', '') + configure_file( + input: installed_tests_template, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf + ) + endif + + # FIXME? $(GLIB_DEBUG_FLAGS) + exe = executable(test_name, [source, extra_sources], + c_args : common_c_args + extra_args.get('c_args', []), + dependencies : common_deps + extra_args.get('dependencies', []), + install_dir: installed_tests_execdir, + install: install, + ) + + suite = ['refcount'] + extra_args.get('suite', []) + timeout = suite.contains('slow') ? test_timeout_slow : test_timeout + + # FIXME? TESTS_ENVIRONMENT = LIBCHARSET_ALIAS_DIR=$(top_builddir)/glib/libcharset + test(test_name, exe, env : test_env, timeout : timeout, suite : suite) +endforeach diff --git a/tests/refcount/objects.c b/tests/refcount/objects.c new file mode 100644 index 0000000..06b8719 --- /dev/null +++ b/tests/refcount/objects.c @@ -0,0 +1,163 @@ +#include +#include + +#ifdef G_OS_UNIX +#include +#endif + +#define G_TYPE_TEST (my_test_get_type ()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +#define MY_IS_TEST(test) (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST)) +#define MY_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass)) +#define MY_IS_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST)) +#define MY_TEST_GET_CLASS(test) (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass)) + +typedef struct _GTest GTest; +typedef struct _GTestClass GTestClass; + +struct _GTest +{ + GObject object; +}; + +struct _GTestClass +{ + GObjectClass parent_class; +}; + +static GType my_test_get_type (void); +static gint stopping; /* (atomic) */ + +static void my_test_class_init (GTestClass * klass); +static void my_test_init (GTest * test); +static void my_test_dispose (GObject * object); + +static GObjectClass *parent_class = NULL; + +static GType +my_test_get_type (void) +{ + static GType test_type = 0; + + if (!test_type) { + const GTypeInfo test_info = { + sizeof (GTestClass), + NULL, + NULL, + (GClassInitFunc) my_test_class_init, + NULL, + NULL, + sizeof (GTest), + 0, + (GInstanceInitFunc) my_test_init, + NULL + }; + + test_type = g_type_register_static (G_TYPE_OBJECT, "GTest", + &test_info, 0); + } + return test_type; +} + +static void +my_test_class_init (GTestClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + gobject_class->dispose = my_test_dispose; +} + +static void +my_test_init (GTest * test) +{ + g_print ("init %p\n", test); +} + +static void +my_test_dispose (GObject * object) +{ + GTest *test; + + test = MY_TEST (object); + + g_print ("dispose %p!\n", test); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +my_test_do_refcount (GTest * test) +{ + g_object_ref (test); + g_object_unref (test); +} + +static gpointer +run_thread (GTest * test) +{ + gint i = 1; + + while (!g_atomic_int_get (&stopping)) { + my_test_do_refcount (test); + if ((i++ % 10000) == 0) { + g_print ("."); + g_thread_yield(); /* force context switch */ + } + } + + return NULL; +} + +int +main (int argc, char **argv) +{ + guint i; + GTest *test1, *test2; + GArray *test_threads; + const guint n_threads = 5; + + g_print ("START: %s\n", argv[0]); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); + + test1 = g_object_new (G_TYPE_TEST, NULL); + test2 = g_object_new (G_TYPE_TEST, NULL); + + test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *)); + + g_atomic_int_set (&stopping, 0); + + for (i = 0; i < n_threads; i++) { + GThread *thread; + + thread = g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL); + g_array_append_val (test_threads, thread); + + thread = g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL); + g_array_append_val (test_threads, thread); + } + g_usleep (5000000); + + g_atomic_int_set (&stopping, 1); + + g_print ("\nstopping\n"); + + /* join all threads */ + for (i = 0; i < 2 * n_threads; i++) { + GThread *thread; + + thread = g_array_index (test_threads, GThread *, i); + g_thread_join (thread); + } + + g_object_unref (test1); + g_object_unref (test2); + g_array_unref (test_threads); + + g_print ("stopped\n"); + + return 0; +} diff --git a/tests/refcount/objects2.c b/tests/refcount/objects2.c new file mode 100644 index 0000000..e19bc67 --- /dev/null +++ b/tests/refcount/objects2.c @@ -0,0 +1,121 @@ +#include +#include + +#ifdef G_OS_UNIX +#include +#endif + +#define G_TYPE_TEST (my_test_get_type ()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +#define MY_IS_TEST(test) (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST)) +#define MY_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass)) +#define MY_IS_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST)) +#define MY_TEST_GET_CLASS(test) (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass)) + +typedef struct _GTest GTest; +typedef struct _GTestClass GTestClass; + +struct _GTest +{ + GObject object; +}; + +struct _GTestClass +{ + GObjectClass parent_class; +}; + +static GType my_test_get_type (void); + +static void my_test_class_init (GTestClass * klass); +static void my_test_init (GTest * test); +static void my_test_dispose (GObject * object); + +static GObjectClass *parent_class = NULL; + +static GType +my_test_get_type (void) +{ + static GType test_type = 0; + + if (!test_type) { + const GTypeInfo test_info = { + sizeof (GTestClass), + NULL, + NULL, + (GClassInitFunc) my_test_class_init, + NULL, + NULL, + sizeof (GTest), + 0, + (GInstanceInitFunc) my_test_init, + NULL + }; + + test_type = g_type_register_static (G_TYPE_OBJECT, "GTest", + &test_info, 0); + } + return test_type; +} + +static void +my_test_class_init (GTestClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + gobject_class->dispose = my_test_dispose; +} + +static void +my_test_init (GTest * test) +{ + g_print ("init %p\n", test); +} + +static void +my_test_dispose (GObject * object) +{ + GTest *test; + + test = MY_TEST (object); + + g_print ("dispose %p!\n", test); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +my_test_do_refcount (GTest * test) +{ + static guint i = 1; + if (i++ % 100000 == 0) + g_print ("."); + g_object_ref (test); + g_object_unref (test); +} + +int +main (int argc, char **argv) +{ + gint i; + GTest *test; + + g_print ("START: %s\n", argv[0]); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); + + test = g_object_new (G_TYPE_TEST, NULL); + + for (i=0; i<100000000; i++) { + my_test_do_refcount (test); + } + + g_object_unref (test); + + g_print ("\n"); + + return 0; +} diff --git a/tests/refcount/properties.c b/tests/refcount/properties.c new file mode 100644 index 0000000..376d931 --- /dev/null +++ b/tests/refcount/properties.c @@ -0,0 +1,237 @@ +#include +#include + +#ifdef G_OS_UNIX +#include +#endif + +#define G_TYPE_TEST (my_test_get_type ()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +#define MY_IS_TEST(test) (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST)) +#define MY_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass)) +#define MY_IS_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST)) +#define MY_TEST_GET_CLASS(test) (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass)) + +enum { + PROP_0, + PROP_DUMMY +}; + +typedef struct _GTest GTest; +typedef struct _GTestClass GTestClass; + +struct _GTest +{ + GObject object; + gint id; + gint dummy; + + gint count; +}; + +struct _GTestClass +{ + GObjectClass parent_class; +}; + +static GType my_test_get_type (void); +static gboolean stopping; + +static void my_test_class_init (GTestClass * klass); +static void my_test_init (GTest * test); +static void my_test_dispose (GObject * object); +static void my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static GObjectClass *parent_class = NULL; + +static GType +my_test_get_type (void) +{ + static GType test_type = 0; + + if (!test_type) { + const GTypeInfo test_info = { + sizeof (GTestClass), + NULL, + NULL, + (GClassInitFunc) my_test_class_init, + NULL, + NULL, + sizeof (GTest), + 0, + (GInstanceInitFunc) my_test_init, + NULL + }; + + test_type = g_type_register_static (G_TYPE_OBJECT, "GTest", &test_info, 0); + } + return test_type; +} + +static void +my_test_class_init (GTestClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + gobject_class->dispose = my_test_dispose; + gobject_class->get_property = my_test_get_property; + gobject_class->set_property = my_test_set_property; + + g_object_class_install_property (gobject_class, + PROP_DUMMY, + g_param_spec_int ("dummy", + NULL, + NULL, + 0, G_MAXINT, 0, + G_PARAM_READWRITE)); +} + +static void +my_test_init (GTest * test) +{ + static guint static_id = 1; + test->id = static_id++; +} + +static void +my_test_dispose (GObject * object) +{ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTest *test; + + test = MY_TEST (object); + + switch (prop_id) + { + case PROP_DUMMY: + g_value_set_int (value, test->dummy); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTest *test; + + test = MY_TEST (object); + + switch (prop_id) + { + case PROP_DUMMY: + test->dummy = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dummy_notify (GObject *object, + GParamSpec *pspec) +{ + GTest *test; + + test = MY_TEST (object); + + test->count++; +} + +static void +my_test_do_property (GTest * test) +{ + gint dummy; + + g_object_get (test, "dummy", &dummy, NULL); + g_object_set (test, "dummy", dummy + 1, NULL); +} + +static gpointer +run_thread (GTest * test) +{ + gint i = 1; + + while (!g_atomic_int_get (&stopping)) { + my_test_do_property (test); + if ((i++ % 10000) == 0) + { + g_print (".%c", 'a' + test->id); + g_thread_yield(); /* force context switch */ + } + } + + return NULL; +} + +int +main (int argc, char **argv) +{ +#define N_THREADS 5 + GThread *test_threads[N_THREADS]; + GTest *test_objects[N_THREADS]; + gint i; + + g_print ("START: %s\n", argv[0]); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); + + for (i = 0; i < N_THREADS; i++) { + GTest *test; + + test = g_object_new (G_TYPE_TEST, NULL); + test_objects[i] = test; + + g_assert (test->count == test->dummy); + g_signal_connect (test, "notify::dummy", G_CALLBACK (dummy_notify), NULL); + } + + g_atomic_int_set (&stopping, FALSE); + + for (i = 0; i < N_THREADS; i++) + test_threads[i] = g_thread_create ((GThreadFunc) run_thread, test_objects[i], TRUE, NULL); + + g_usleep (3000000); + + g_atomic_int_set (&stopping, TRUE); + g_print ("\nstopping\n"); + + /* join all threads */ + for (i = 0; i < N_THREADS; i++) + g_thread_join (test_threads[i]); + + g_print ("stopped\n"); + + for (i = 0; i < N_THREADS; i++) { + GTest *test = test_objects[i]; + + g_assert (test->count == test->dummy); + g_object_unref (test); + } + + return 0; +} diff --git a/tests/refcount/properties2.c b/tests/refcount/properties2.c new file mode 100644 index 0000000..1684bd4 --- /dev/null +++ b/tests/refcount/properties2.c @@ -0,0 +1,202 @@ +#include +#include + +#ifdef G_OS_UNIX +#include +#endif + +#define G_TYPE_TEST (my_test_get_type ()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +#define MY_IS_TEST(test) (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST)) +#define MY_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass)) +#define MY_IS_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST)) +#define MY_TEST_GET_CLASS(test) (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass)) + +enum { + PROP_0, + PROP_DUMMY +}; + +typedef struct _GTest GTest; +typedef struct _GTestClass GTestClass; + +struct _GTest +{ + GObject object; + + gint dummy; +}; + +struct _GTestClass +{ + GObjectClass parent_class; +}; + +static GType my_test_get_type (void); + +static void my_test_class_init (GTestClass * klass); +static void my_test_init (GTest * test); +static void my_test_dispose (GObject * object); +static void my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static GObjectClass *parent_class = NULL; + +static GType +my_test_get_type (void) +{ + static GType test_type = 0; + + if (!test_type) { + const GTypeInfo test_info = { + sizeof (GTestClass), + NULL, + NULL, + (GClassInitFunc) my_test_class_init, + NULL, + NULL, + sizeof (GTest), + 0, + (GInstanceInitFunc) my_test_init, + NULL + }; + + test_type = g_type_register_static (G_TYPE_OBJECT, "GTest", + &test_info, 0); + } + return test_type; +} + +static void +my_test_class_init (GTestClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + gobject_class->dispose = my_test_dispose; + gobject_class->get_property = my_test_get_property; + gobject_class->set_property = my_test_set_property; + + g_object_class_install_property (gobject_class, + PROP_DUMMY, + g_param_spec_int ("dummy", + NULL, + NULL, + 0, G_MAXINT, 0, + G_PARAM_READWRITE)); +} + +static void +my_test_init (GTest * test) +{ + g_print ("init %p\n", test); +} + +static void +my_test_dispose (GObject * object) +{ + GTest *test; + + test = MY_TEST (object); + + g_print ("dispose %p!\n", test); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTest *test; + + test = MY_TEST (object); + + switch (prop_id) + { + case PROP_DUMMY: + g_value_set_int (value, test->dummy); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTest *test; + + test = MY_TEST (object); + + switch (prop_id) + { + case PROP_DUMMY: + test->dummy = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gint count = 0; + +static void +dummy_notify (GObject *object, + GParamSpec *pspec) +{ + count++; + if (count % 10000 == 0) + g_print ("."); +} + +static void +my_test_do_property (GTest * test) +{ + gint dummy; + + g_object_get (test, "dummy", &dummy, NULL); + g_object_set (test, "dummy", dummy + 1, NULL); +} + +int +main (int argc, char **argv) +{ + gint i; + GTest *test; + + g_print ("START: %s\n", argv[0]); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); + + test = g_object_new (G_TYPE_TEST, NULL); + + g_signal_connect (test, "notify::dummy", G_CALLBACK (dummy_notify), NULL); + + g_assert (count == test->dummy); + + for (i=0; i<1000000; i++) { + my_test_do_property (test); + } + + g_assert (count == test->dummy); + + g_object_unref (test); + + return 0; +} diff --git a/tests/refcount/properties3.c b/tests/refcount/properties3.c new file mode 100644 index 0000000..31f26a4 --- /dev/null +++ b/tests/refcount/properties3.c @@ -0,0 +1,202 @@ +#include +#include + +#define G_TYPE_TEST (my_test_get_type ()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +#define MY_IS_TEST(test) (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST)) +#define MY_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass)) +#define MY_IS_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST)) +#define MY_TEST_GET_CLASS(test) (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass)) + +enum { + PROP_0, + PROP_DUMMY +}; + +typedef struct _GTest GTest; +typedef struct _GTestClass GTestClass; + +struct _GTest +{ + GObject object; + gint id; + gint dummy; + + gint count; + gint setcount; +}; + +struct _GTestClass +{ + GObjectClass parent_class; +}; + +static GType my_test_get_type (void); +G_DEFINE_TYPE (GTest, my_test, G_TYPE_OBJECT) + +static gint stopping; /* (atomic) */ + +static void my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static void +my_test_class_init (GTestClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + gobject_class->get_property = my_test_get_property; + gobject_class->set_property = my_test_set_property; + + g_object_class_install_property (gobject_class, + PROP_DUMMY, + g_param_spec_int ("dummy", + NULL, + NULL, + 0, G_MAXINT, 0, + G_PARAM_READWRITE)); +} + +static void +my_test_init (GTest * test) +{ + static guint static_id = 1; + test->id = static_id++; +} + +static void +my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTest *test; + + test = MY_TEST (object); + + switch (prop_id) + { + case PROP_DUMMY: + g_value_set_int (value, g_atomic_int_get (&test->dummy)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTest *test; + + test = MY_TEST (object); + + switch (prop_id) + { + case PROP_DUMMY: + g_atomic_int_set (&test->dummy, g_value_get_int (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dummy_notify (GObject *object, + GParamSpec *pspec) +{ + GTest *test; + + test = MY_TEST (object); + + g_atomic_int_inc (&test->count); +} + +static void +my_test_do_property (GTest * test) +{ + gint dummy; + + g_atomic_int_inc (&test->setcount); + + g_object_get (test, "dummy", &dummy, NULL); + g_object_set (test, "dummy", dummy + 1, NULL); +} + +static gpointer +run_thread (GTest * test) +{ + gint i = 1; + + while (!g_atomic_int_get (&stopping)) { + my_test_do_property (test); + if ((i++ % 10000) == 0) + { + g_print (".%c", 'a' + test->id); + g_thread_yield(); /* force context switch */ + } + } + + return NULL; +} + +int +main (int argc, char **argv) +{ + gint i; + GTest *test; + GArray *test_threads; + const gint n_threads = 5; + + g_print ("START: %s\n", argv[0]); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); + + test = g_object_new (G_TYPE_TEST, NULL); + + g_assert (test->count == test->dummy); + g_signal_connect (test, "notify::dummy", G_CALLBACK (dummy_notify), NULL); + + test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *)); + + g_atomic_int_set (&stopping, 0); + + for (i = 0; i < n_threads; i++) { + GThread *thread; + + thread = g_thread_create ((GThreadFunc) run_thread, test, TRUE, NULL); + g_array_append_val (test_threads, thread); + } + g_usleep (30000000); + + g_atomic_int_set (&stopping, 1); + g_print ("\nstopping\n"); + + /* join all threads */ + for (i = 0; i < n_threads; i++) { + GThread *thread; + + thread = g_array_index (test_threads, GThread *, i); + g_thread_join (thread); + } + + g_print ("stopped\n"); + + g_print ("%d %d\n", test->setcount, test->count); + + g_array_free (test_threads, TRUE); + g_object_unref (test); + + return 0; +} diff --git a/tests/refcount/properties4.c b/tests/refcount/properties4.c new file mode 100644 index 0000000..d4bca94 --- /dev/null +++ b/tests/refcount/properties4.c @@ -0,0 +1,173 @@ +#include +#include + +#define MY_TYPE_BADGER (my_badger_get_type ()) +#define MY_BADGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_BADGER, MyBadger)) +#define MY_IS_BADGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_BADGER)) +#define MY_BADGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_BADGER, MyBadgerClass)) +#define MY_IS_BADGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_BADGER)) +#define MY_BADGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_BADGER, MyBadgerClass)) + +enum { + PROP_0, + PROP_MAMA +}; + +typedef struct _MyBadger MyBadger; +typedef struct _MyBadgerClass MyBadgerClass; + +struct _MyBadger +{ + GObject parent_instance; + + MyBadger * mama; + guint mama_notify_count; +}; + +struct _MyBadgerClass +{ + GObjectClass parent_class; +}; + +static GType my_badger_get_type (void); +G_DEFINE_TYPE (MyBadger, my_badger, G_TYPE_OBJECT) + +static void my_badger_dispose (GObject * object); + +static void my_badger_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void my_badger_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static void my_badger_mama_notify (GObject *object, + GParamSpec *pspec); + +static void +my_badger_class_init (MyBadgerClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + gobject_class->dispose = my_badger_dispose; + + gobject_class->get_property = my_badger_get_property; + gobject_class->set_property = my_badger_set_property; + + g_object_class_install_property (gobject_class, + PROP_MAMA, + g_param_spec_object ("mama", + NULL, + NULL, + MY_TYPE_BADGER, + G_PARAM_READWRITE)); +} + +static void +my_badger_init (MyBadger * self) +{ + g_signal_connect (self, "notify::mama", G_CALLBACK (my_badger_mama_notify), + NULL); +} + +static void +my_badger_dispose (GObject * object) +{ + MyBadger * self; + + self = MY_BADGER (object); + + if (self->mama != NULL) + { + g_object_unref (self->mama); + self->mama = NULL; + } + + G_OBJECT_CLASS (my_badger_parent_class)->dispose (object); +} + +static void +my_badger_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MyBadger *self; + + self = MY_BADGER (object); + + switch (prop_id) + { + case PROP_MAMA: + g_value_set_object (value, self->mama); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_badger_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MyBadger *self; + + self = MY_BADGER (object); + + switch (prop_id) + { + case PROP_MAMA: + if (self->mama) + g_object_unref (self->mama); + self->mama = g_value_dup_object (value); + if (self->mama) + g_object_set (self->mama, "mama", NULL, NULL); /* another notify */ + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_badger_mama_notify (GObject *object, + GParamSpec *pspec) +{ + MyBadger *self; + + self = MY_BADGER (object); + + self->mama_notify_count++; +} + +int +main (int argc, char **argv) +{ + MyBadger * badger1, * badger2; + gpointer test; + + g_print ("START: %s\n", argv[0]); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); + + badger1 = g_object_new (MY_TYPE_BADGER, NULL); + badger2 = g_object_new (MY_TYPE_BADGER, NULL); + + g_object_set (badger1, "mama", badger2, NULL); + g_assert_cmpuint (badger1->mama_notify_count, ==, 1); + g_assert_cmpuint (badger2->mama_notify_count, ==, 1); + g_object_get (badger1, "mama", &test, NULL); + g_assert (test == badger2); + g_object_unref (test); + + g_object_unref (badger1); + g_object_unref (badger2); + + return 0; +} diff --git a/tests/refcount/signals.c b/tests/refcount/signals.c new file mode 100644 index 0000000..f714ac0 --- /dev/null +++ b/tests/refcount/signals.c @@ -0,0 +1,308 @@ +#include +#include + +#ifdef G_OS_UNIX +#include +#endif + +#define G_TYPE_TEST (my_test_get_type ()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +#define MY_IS_TEST(test) (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST)) +#define MY_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass)) +#define MY_IS_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST)) +#define MY_TEST_GET_CLASS(test) (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass)) + +typedef struct _GTest GTest; +typedef struct _GTestClass GTestClass; + +struct _GTest +{ + GObject object; + + gint value; +}; + +struct _GTestClass +{ + GObjectClass parent_class; + + void (*test_signal1) (GTest * test, gint an_int); + void (*test_signal2) (GTest * test, gint an_int); + gchar * (*test_signal3) (GTest * test, gint an_int); +}; + +static GType my_test_get_type (void); +static gboolean stopping; + +/* Element signals and args */ +enum +{ + TEST_SIGNAL1, + TEST_SIGNAL2, + TEST_SIGNAL3, + /* add more above */ + LAST_SIGNAL +}; + +enum +{ + ARG_0, + ARG_TEST_PROP +}; + +static void my_test_class_init (GTestClass * klass); +static void my_test_init (GTest * test); +static void my_test_dispose (GObject * object); + +static void signal2_handler (GTest * test, gint anint); +static gchar * signal3_handler (GTest * test, gint anint); + +static void my_test_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void my_test_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static GObjectClass *parent_class = NULL; + +static guint my_test_signals[LAST_SIGNAL] = { 0 }; + +static GType +my_test_get_type (void) +{ + static GType test_type = 0; + + if (!test_type) { + const GTypeInfo test_info = { + sizeof (GTestClass), + NULL, + NULL, + (GClassInitFunc) my_test_class_init, + NULL, + NULL, + sizeof (GTest), + 0, + (GInstanceInitFunc) my_test_init, + NULL + }; + + test_type = g_type_register_static (G_TYPE_OBJECT, "GTest", + &test_info, 0); + } + return test_type; +} + +static void +my_test_class_init (GTestClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + gobject_class->dispose = my_test_dispose; + gobject_class->set_property = my_test_set_property; + gobject_class->get_property = my_test_get_property; + + my_test_signals[TEST_SIGNAL1] = + g_signal_new ("test-signal1", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GTestClass, test_signal1), NULL, + NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + my_test_signals[TEST_SIGNAL2] = + g_signal_new ("test-signal2", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GTestClass, test_signal2), NULL, + NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + my_test_signals[TEST_SIGNAL3] = + g_signal_new ("test-signal3", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GTestClass, test_signal3), NULL, + NULL, g_cclosure_marshal_generic, G_TYPE_STRING, 1, G_TYPE_INT); + + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TEST_PROP, + g_param_spec_int ("test-prop", "Test Prop", "Test property", + 0, 1, 0, G_PARAM_READWRITE)); + + klass->test_signal2 = signal2_handler; + klass->test_signal3 = signal3_handler; +} + +static void +my_test_init (GTest * test) +{ + g_print ("init %p\n", test); + + test->value = 0; +} + +static void +my_test_dispose (GObject * object) +{ + GTest *test; + + test = MY_TEST (object); + + g_print ("dispose %p!\n", test); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +my_test_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GTest *test; + + test = MY_TEST (object); + + switch (prop_id) { + case ARG_TEST_PROP: + test->value = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GTest *test; + + test = MY_TEST (object); + + switch (prop_id) { + case ARG_TEST_PROP: + g_value_set_int (value, test->value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_do_signal1 (GTest * test) +{ + g_signal_emit (G_OBJECT (test), my_test_signals[TEST_SIGNAL1], 0, 0); +} + +static void +signal2_handler (GTest * test, gint anint) +{ +} + +static void +my_test_do_signal2 (GTest * test) +{ + g_signal_emit (G_OBJECT (test), my_test_signals[TEST_SIGNAL2], 0, 0); +} + +static gchar * +signal3_handler (GTest * test, gint anint) +{ + return g_strdup ("test"); +} + +static void +my_test_do_signal3 (GTest * test) +{ + gchar *res; + + g_signal_emit (G_OBJECT (test), my_test_signals[TEST_SIGNAL3], 0, 0, &res); + g_assert (res); + g_free (res); +} + +static void +my_test_do_prop (GTest * test) +{ + test->value = g_random_int (); + g_object_notify (G_OBJECT (test), "test-prop"); +} + +static gpointer +run_thread (GTest * test) +{ + gint i = 1; + + while (!g_atomic_int_get (&stopping)) { + if (TESTNUM == 1) + my_test_do_signal1 (test); + if (TESTNUM == 2) + my_test_do_signal2 (test); + if (TESTNUM == 3) + my_test_do_prop (test); + if (TESTNUM == 4) + my_test_do_signal3 (test); + if ((i++ % 10000) == 0) { + g_print ("."); + g_thread_yield(); /* force context switch */ + } + } + + return NULL; +} + +static void +notify (GObject *object, GParamSpec *spec, gpointer user_data) +{ + gint value; + + g_object_get (object, "test-prop", &value, NULL); + /*g_print ("+ %d", value);*/ +} + +int +main (int argc, char **argv) +{ + gint i; + GTest *test1, *test2; + GArray *test_threads; + const gint n_threads = 1; + + g_print ("START: %s\n", argv[0]); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); + + test1 = g_object_new (G_TYPE_TEST, NULL); + test2 = g_object_new (G_TYPE_TEST, NULL); + + g_signal_connect (test1, "notify::test-prop", G_CALLBACK (notify), NULL); + g_signal_connect (test1, "test-signal1", G_CALLBACK (notify), NULL); + g_signal_connect (test1, "test-signal2", G_CALLBACK (notify), NULL); + + test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *)); + + stopping = FALSE; + + for (i = 0; i < n_threads; i++) { + GThread *thread; + + thread = g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL); + g_array_append_val (test_threads, thread); + + thread = g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL); + g_array_append_val (test_threads, thread); + } + g_usleep (5000000); + + g_atomic_int_set (&stopping, TRUE); + + g_print ("\nstopping\n"); + + /* join all threads */ + for (i = 0; i < 2 * n_threads; i++) { + GThread *thread; + + thread = g_array_index (test_threads, GThread *, i); + g_thread_join (thread); + } + + g_print ("stopped\n"); + + g_array_free (test_threads, TRUE); + g_object_unref (test1); + g_object_unref (test2); + + return 0; +} diff --git a/tests/run-assert-msg-test.sh b/tests/run-assert-msg-test.sh new file mode 100755 index 0000000..88f86f1 --- /dev/null +++ b/tests/run-assert-msg-test.sh @@ -0,0 +1,49 @@ +#! /bin/sh + +fail () +{ + echo "Test failed: $*" + exit 1 +} + +echo_v () +{ + if [ "$verbose" = "1" ]; then + echo "$*" + fi +} + +error_out=/dev/null +if [ "$1" = "-v" ]; then + verbose=1 + error_out=/dev/stderr +fi + +if [ -z "$LIBTOOL" ]; then + if [ -f ../libtool ]; then + LIBTOOL=../libtool + else + LIBTOOL=libtool + fi +fi + +echo_v "Running assert-msg-test" +OUT=$(./assert-msg-test 2>&1) && fail "assert-msg-test should abort" +echo "$OUT" | grep -q '^GLib:ERROR:.*assert-msg-test.c:.*:.*main.*: assertion failed: (42 < 0)' || \ + fail "does not print assertion message" + +if ! type gdb >/dev/null 2>&1; then + echo_v "Skipped (no gdb installed)" + exit 0 +fi + +echo_v "Running gdb on assert-msg-test" +OUT=$($LIBTOOL --mode=execute gdb --batch -x "${srcdir:-.}/assert-msg-test.gdb" ./assert-msg-test 2> $error_out) || fail "failed to run gdb" + +echo_v "Checking if assert message is in __glib_assert_msg" +# shellcheck disable=SC2016 +if ! echo "$OUT" | grep -q '^$1.*"GLib:ERROR:.*assert-msg-test.c:.*:.*main.*: assertion failed: (42 < 0)"'; then + fail "__glib_assert_msg does not have assertion message" +fi + +echo_v "All tests passed." diff --git a/tests/slice-test.c b/tests/slice-test.c new file mode 100644 index 0000000..b2cd77f --- /dev/null +++ b/tests/slice-test.c @@ -0,0 +1,303 @@ +/* GLIB sliced memory - fast threaded memory chunk allocator + * Copyright (C) 2005 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#include + +#include +#include + +#define quick_rand32() (rand_accu = 1664525 * rand_accu + 1013904223, rand_accu) +static guint prime_size = 1021; /* 769; 509 */ +static gboolean clean_memchunks = FALSE; +static guint number_of_blocks = 10000; /* total number of blocks allocated */ +static guint number_of_repetitions = 10000; /* number of alloc+free repetitions */ +static gboolean want_corruption = FALSE; + +/* --- old memchunk prototypes (memchunks.c) --- */ +GMemChunk* old_mem_chunk_new (const gchar *name, + gulong atom_size, + gulong area_size, + gint type); +void old_mem_chunk_destroy (GMemChunk *mem_chunk); +gpointer old_mem_chunk_alloc (GMemChunk *mem_chunk); +gpointer old_mem_chunk_alloc0 (GMemChunk *mem_chunk); +void old_mem_chunk_free (GMemChunk *mem_chunk, + gpointer mem); +void old_mem_chunk_clean (GMemChunk *mem_chunk); +void old_mem_chunk_reset (GMemChunk *mem_chunk); +void old_mem_chunk_print (GMemChunk *mem_chunk); +void old_mem_chunk_info (void); +#ifndef G_ALLOC_AND_FREE +#define G_ALLOC_AND_FREE 2 +#endif + +/* --- functions --- */ +static inline int +corruption (void) +{ + if (G_UNLIKELY (want_corruption)) + { + /* corruption per call likelyness is about 1:4000000 */ + guint32 r = g_random_int() % 8000009; + return r == 277 ? +1 : r == 281 ? -1 : 0; + } + return 0; +} + +static inline gpointer +memchunk_alloc (GMemChunk **memchunkp, + guint size) +{ + size = MAX (size, 1); + if (G_UNLIKELY (!*memchunkp)) + *memchunkp = old_mem_chunk_new ("", size, 4096, G_ALLOC_AND_FREE); + return old_mem_chunk_alloc (*memchunkp); +} + +static inline void +memchunk_free (GMemChunk *memchunk, + gpointer chunk) +{ + old_mem_chunk_free (memchunk, chunk); + if (clean_memchunks) + old_mem_chunk_clean (memchunk); +} + +static gpointer +test_memchunk_thread (gpointer data) +{ + GMemChunk **memchunks; + guint i, j; + guint8 **ps; + guint *ss; + guint32 rand_accu = 2147483563; + /* initialize random numbers */ + if (data) + rand_accu = *(guint32*) data; + else + { + GTimeVal rand_tv; + g_get_current_time (&rand_tv); + rand_accu = rand_tv.tv_usec + (rand_tv.tv_sec << 16); + } + + /* prepare for memchunk creation */ + memchunks = g_newa0 (GMemChunk*, prime_size); + + ps = g_new (guint8*, number_of_blocks); + ss = g_new (guint, number_of_blocks); + /* create number_of_blocks random sizes */ + for (i = 0; i < number_of_blocks; i++) + ss[i] = quick_rand32() % prime_size; + /* allocate number_of_blocks blocks */ + for (i = 0; i < number_of_blocks; i++) + ps[i] = memchunk_alloc (&memchunks[ss[i]], ss[i]); + for (j = 0; j < number_of_repetitions; j++) + { + /* free number_of_blocks/2 blocks */ + for (i = 0; i < number_of_blocks; i += 2) + memchunk_free (memchunks[ss[i]], ps[i]); + /* allocate number_of_blocks/2 blocks with new sizes */ + for (i = 0; i < number_of_blocks; i += 2) + { + ss[i] = quick_rand32() % prime_size; + ps[i] = memchunk_alloc (&memchunks[ss[i]], ss[i]); + } + } + /* free number_of_blocks blocks */ + for (i = 0; i < number_of_blocks; i++) + memchunk_free (memchunks[ss[i]], ps[i]); + /* alloc and free many equally sized chunks in a row */ + for (i = 0; i < number_of_repetitions; i++) + { + guint sz = quick_rand32() % prime_size; + guint k = number_of_blocks / 100; + for (j = 0; j < k; j++) + ps[j] = memchunk_alloc (&memchunks[sz], sz); + for (j = 0; j < k; j++) + memchunk_free (memchunks[sz], ps[j]); + } + /* cleanout memchunks */ + for (i = 0; i < prime_size; i++) + if (memchunks[i]) + old_mem_chunk_destroy (memchunks[i]); + g_free (ps); + g_free (ss); + + return NULL; +} + +static gpointer +test_sliced_mem_thread (gpointer data) +{ + guint32 rand_accu = 2147483563; + guint i, j; + guint8 **ps; + guint *ss; + + /* initialize random numbers */ + if (data) + rand_accu = *(guint32*) data; + else + { + GTimeVal rand_tv; + g_get_current_time (&rand_tv); + rand_accu = rand_tv.tv_usec + (rand_tv.tv_sec << 16); + } + + ps = g_new (guint8*, number_of_blocks); + ss = g_new (guint, number_of_blocks); + /* create number_of_blocks random sizes */ + for (i = 0; i < number_of_blocks; i++) + ss[i] = quick_rand32() % prime_size; + /* allocate number_of_blocks blocks */ + for (i = 0; i < number_of_blocks; i++) + ps[i] = g_slice_alloc (ss[i] + corruption()); + for (j = 0; j < number_of_repetitions; j++) + { + /* free number_of_blocks/2 blocks */ + for (i = 0; i < number_of_blocks; i += 2) + g_slice_free1 (ss[i] + corruption(), ps[i] + corruption()); + /* allocate number_of_blocks/2 blocks with new sizes */ + for (i = 0; i < number_of_blocks; i += 2) + { + ss[i] = quick_rand32() % prime_size; + ps[i] = g_slice_alloc (ss[i] + corruption()); + } + } + /* free number_of_blocks blocks */ + for (i = 0; i < number_of_blocks; i++) + g_slice_free1 (ss[i] + corruption(), ps[i] + corruption()); + /* alloc and free many equally sized chunks in a row */ + for (i = 0; i < number_of_repetitions; i++) + { + guint sz = quick_rand32() % prime_size; + guint k = number_of_blocks / 100; + for (j = 0; j < k; j++) + ps[j] = g_slice_alloc (sz + corruption()); + for (j = 0; j < k; j++) + g_slice_free1 (sz + corruption(), ps[j] + corruption()); + } + g_free (ps); + g_free (ss); + + return NULL; +} + +static void +usage (void) +{ + g_print ("Usage: slice-test [n_threads] [G|S|M|O][f][c][~] [maxblocksize] [seed]\n"); +} + +int +main (int argc, + char *argv[]) +{ + guint seed32, *seedp = NULL; + gboolean ccounters = FALSE, use_memchunks = FALSE; + guint n_threads = 1; + const gchar *mode = "slab allocator + magazine cache", *emode = " "; + if (argc > 1) + n_threads = g_ascii_strtoull (argv[1], NULL, 10); + if (argc > 2) + { + guint i, l = strlen (argv[2]); + for (i = 0; i < l; i++) + switch (argv[2][i]) + { + case 'G': /* GLib mode */ + g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, FALSE); + g_slice_set_config (G_SLICE_CONFIG_BYPASS_MAGAZINES, FALSE); + mode = "slab allocator + magazine cache"; + break; + case 'S': /* slab mode */ + g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, FALSE); + g_slice_set_config (G_SLICE_CONFIG_BYPASS_MAGAZINES, TRUE); + mode = "slab allocator"; + break; + case 'M': /* malloc mode */ + g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, TRUE); + mode = "system malloc"; + break; + case 'O': /* old memchunks */ + use_memchunks = TRUE; + mode = "old memchunks"; + break; + case 'f': /* eager freeing */ + g_slice_set_config (G_SLICE_CONFIG_WORKING_SET_MSECS, 0); + clean_memchunks = TRUE; + emode = " with eager freeing"; + break; + case 'c': /* print contention counters */ + ccounters = TRUE; + break; + case '~': + want_corruption = TRUE; /* force occasional corruption */ + break; + default: + usage(); + return 1; + } + } + if (argc > 3) + prime_size = g_ascii_strtoull (argv[3], NULL, 10); + if (argc > 4) + { + seed32 = g_ascii_strtoull (argv[4], NULL, 10); + seedp = &seed32; + } + + if (argc <= 1) + usage(); + + { + gchar strseed[64] = ""; + GThread **threads; + guint i; + + if (seedp) + g_snprintf (strseed, 64, "%u", *seedp); + g_print ("Starting %d threads allocating random blocks <= %u bytes with seed=%s using %s%s\n", n_threads, prime_size, strseed, mode, emode); + + threads = g_alloca (sizeof(GThread*) * n_threads); + if (!use_memchunks) + for (i = 0; i < n_threads; i++) + threads[i] = g_thread_create (test_sliced_mem_thread, seedp, TRUE, NULL); + else + { + for (i = 0; i < n_threads; i++) + threads[i] = g_thread_create (test_memchunk_thread, seedp, TRUE, NULL); + } + for (i = 0; i < n_threads; i++) + g_thread_join (threads[i]); + + if (ccounters) + { + guint n, n_chunks = g_slice_get_config (G_SLICE_CONFIG_CHUNK_SIZES); + g_print (" ChunkSize | MagazineSize | Contention\n"); + for (i = 0; i < n_chunks; i++) + { + gint64 *vals = g_slice_get_config_state (G_SLICE_CONFIG_CONTENTION_COUNTER, i, &n); + g_print (" %9" G_GINT64_FORMAT " | %9" G_GINT64_FORMAT " | %9" G_GINT64_FORMAT "\n", vals[0], vals[2], vals[1]); + g_free (vals); + } + } + else + g_print ("Done.\n"); + return 0; + } +} diff --git a/tests/slice-threadinit.c b/tests/slice-threadinit.c new file mode 100644 index 0000000..e303aa0 --- /dev/null +++ b/tests/slice-threadinit.c @@ -0,0 +1,166 @@ +/* slice-threadinit.c - test GSlice across g_thread_init + * Copyright (C) 2007 Tim Janik + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#include + +#define N_PAGES (101) /* number of pages to sample */ +#define SAMPLE_SIZE (7) +#define PAGE_SIZE (128) /* must be <= minimum GSlice alignment block */ +#define MAGAZINE_PROBES { 97, 265, 347 } /* block sizes hopefully unused by g_thread_init */ +#define MAX_PROBE_TRIALS (1031) /* must be >= maximum magazine size */ + +#define ALIGN(size, base) ((base) * (gsize) (((size) + (base) - 1) / (base))) + +static struct { + void *page; + void *sample; +} pages[N_PAGES] = { { NULL, NULL }, }; + +static const guint magazine_probes[] = MAGAZINE_PROBES; +#define N_MAGAZINE_PROBES G_N_ELEMENTS (magazine_probes) + +static void +release_trash_list (GSList **trash_list, + gsize block_size) +{ + while (*trash_list) + { + g_slice_free1 (block_size, (*trash_list)->data); + *trash_list = g_slist_delete_link (*trash_list, *trash_list); + } +} + +static GSList *free_list = NULL; + +static gboolean +allocate_from_known_page (void) +{ + guint i, j, n_trials = N_PAGES * PAGE_SIZE / SAMPLE_SIZE; /* upper bound */ + for (i = 0; i < n_trials; i++) + { + void *b = g_slice_alloc (SAMPLE_SIZE); + void *p = (void*) (PAGE_SIZE * ((gsize) b / PAGE_SIZE)); + free_list = g_slist_prepend (free_list, b); + /* find page */ + for (j = 0; j < N_PAGES; j++) + if (pages[j].page == p) + return TRUE; + } + return FALSE; +} + +int +main (int argc, + char *argv[]) +{ + gsize j, n_pages = 0; + void *mps[N_MAGAZINE_PROBES]; + + /* probe some magazine sizes */ + for (j = 0; j < N_MAGAZINE_PROBES; j++) + mps[j] = g_slice_alloc (magazine_probes[j]); + /* mps[*] now contains pointers to allocated slices */ + + /* allocate blocks from N_PAGES different pages */ + while (n_pages < N_PAGES) + { + void *b = g_slice_alloc (SAMPLE_SIZE); + void *p = (void*) (PAGE_SIZE * ((gsize) b / PAGE_SIZE)); + for (j = 0; j < N_PAGES; j++) + if (pages[j].page == p) + break; + if (j < N_PAGES) /* known page */ + free_list = g_slist_prepend (free_list, b); + else /* new page */ + { + j = n_pages++; + pages[j].page = p; + pages[j].sample = b; + } + } + /* release intermediate allocations */ + release_trash_list (&free_list, SAMPLE_SIZE); + + /* ensure that we can allocate from known pages */ + if (!allocate_from_known_page()) + g_error ("failed to allocate from magazine/page cache (before g_thread_init)"); + /* release intermediate allocations */ + release_trash_list (&free_list, SAMPLE_SIZE); + + /* release magazine probes to be retained */ + for (j = 0; j < N_MAGAZINE_PROBES; j++) + g_slice_free1 (magazine_probes[j], mps[j]); + /* mps[*] now contains pointers to releaed slices */ + + /* ensure probes were retained */ + for (j = 0; j < N_MAGAZINE_PROBES; j++) + { + GSList *trash = NULL; + guint k; + for (k = 0; k < MAX_PROBE_TRIALS; k++) + { + void *mem = g_slice_alloc (magazine_probes[j]); + if (mem == mps[j]) + break; /* reallocated previously freed slice */ + trash = g_slist_prepend (trash, mem); + } + release_trash_list (&trash, magazine_probes[j]); + if (k >= MAX_PROBE_TRIALS) /* failed to reallocate slice */ + g_error ("failed to reallocate slice from magazine (before g_thread_init): size=%d", magazine_probes[j]); + } + /* mps[*] now contains pointers to reallocated slices */ + + /* release magazine probes to be retained across g_thread_init */ + for (j = 0; j < N_MAGAZINE_PROBES; j++) + g_slice_free1 (magazine_probes[j], mps[j]); + /* mps[*] now contains pointers to released slices */ + + /* initialize threading (should retain allocator state) */ + g_thread_init (NULL); + + /* ensure probes were retained */ + for (j = 0; j < N_MAGAZINE_PROBES; j++) + { + GSList *trash = NULL; + guint k; + for (k = 0; k < MAX_PROBE_TRIALS; k++) + { + void *mem = g_slice_alloc (magazine_probes[j]); + if (mem == mps[j]) + break; /* reallocated previously freed slice */ + trash = g_slist_prepend (trash, mem); + } + release_trash_list (&trash, magazine_probes[j]); + if (k >= MAX_PROBE_TRIALS) /* failed to reallocate slice */ + g_error ("failed to reallocate slice from magazine (after g_thread_init): size=%d", magazine_probes[j]); + } + /* mps[*] now contains pointers to reallocated slices */ + + /* ensure that we can allocate from known pages */ + if (!allocate_from_known_page()) + g_error ("failed to allocate from magazine/page cache (after g_thread_init)"); + + /* some cleanups */ + for (j = 0; j < N_MAGAZINE_PROBES; j++) + g_slice_free1 (magazine_probes[j], mps[j]); + release_trash_list (&free_list, SAMPLE_SIZE); + + return 0; +} diff --git a/tests/spawn-test-win32-gui.c b/tests/spawn-test-win32-gui.c new file mode 100644 index 0000000..34945f5 --- /dev/null +++ b/tests/spawn-test-win32-gui.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include + +#ifdef __CYGWIN__ +/* For read() and write() */ +#include +/* Cygwin does not prototype __argc and __argv in stdlib.h */ +extern int __argc; +extern char** __argv; +#endif + +int _stdcall +WinMain (struct HINSTANCE__ *hInstance, + struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, + int nCmdShow) +{ + if (__argc >= 2 && strcmp (__argv[1], "print_argv0") == 0) + { + printf ("%s", __argv[0]); + } + else if (__argc <= 2) + { + printf ("This is stdout\n"); + fflush (stdout); + + fprintf (stderr, "This is stderr\n"); + fflush (stderr); + } + else if (__argc == 4 && strcmp (__argv[1], "pipes") == 0) + { + int infd = atoi (__argv[2]); + int outfd = atoi (__argv[3]); + int k, n; + char buf[100] = {0}; + + if (infd < 0 || outfd < 0) + { + printf ("spawn-test-win32-gui: illegal fds on command line %s", + lpszCmdLine); + exit (1); + } + + n = strlen ("Hello there"); + if (write (outfd, &n, sizeof (n)) == -1 || + write (outfd, "Hello there", n) == -1) + { + int errsv = errno; + printf ("spawn-test-win32-gui: Write error: %s", strerror (errsv)); + exit (1); + } + + if ((k = read (infd, &n, sizeof (n))) != sizeof (n)) + { + printf ("spawn-test-win32-gui: Got only %d bytes, wanted %d", + k, (int)sizeof (n)); + exit (1); + } + + printf ("spawn-test-win32-gui: Parent says %d bytes to read", n); + + if ((k = read (infd, buf, n)) != n) + { + int errsv = errno; + if (k == -1) + printf ("spawn-test-win32-gui: Read error: %s", strerror (errsv)); + else + printf ("spawn-test-win32-gui: Got only %d bytes", k); + exit (1); + } + + n = strlen ("See ya"); + if (write (outfd, &n, sizeof (n)) == -1 || + write (outfd, "See ya", n) == -1) + { + int errsv = errno; + printf ("spawn-test-win32-gui: Write error: %s", strerror (errsv)); + exit (1); + } + } + + return 0; +} diff --git a/tests/spawn-test.c b/tests/spawn-test.c new file mode 100644 index 0000000..78a7e7c --- /dev/null +++ b/tests/spawn-test.c @@ -0,0 +1,352 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include +#include +#include + +#ifdef G_OS_WIN32 +#include +#include +#define pipe(fds) _pipe(fds, 4096, _O_BINARY) +#endif + + +static void +run_tests (const gchar* argv0) +{ + GError *err = NULL; + gchar *output = NULL; + gchar *erroutput = NULL; + gchar *dirname = g_path_get_dirname (argv0); +#ifdef G_OS_WIN32 + int pipedown[2], pipeup[2]; + gchar **argv = 0; + gchar spawn_binary[1000] = {0}; + gchar full_cmdline[1000] = {0}; + g_snprintf (spawn_binary, sizeof (spawn_binary), "%s\\spawn-test-win32-gui.exe", dirname); +#endif + g_free (dirname); + + err = NULL; + if (!g_spawn_command_line_sync ("nonexistent_application foo 'bar baz' blah blah", + NULL, NULL, NULL, + &err)) + { + g_error_free (err); + } + else + { + g_warning ("no error for sync spawn of nonexistent application"); + exit (1); + } + + err = NULL; + if (!g_spawn_command_line_async ("nonexistent_application foo bar baz \"blah blah\"", + &err)) + { + g_error_free (err); + } + else + { + g_warning ("no error for async spawn of nonexistent application"); + exit (1); + } + + err = NULL; +#ifdef G_OS_UNIX + if (!g_spawn_command_line_sync ("/bin/sh -c 'echo hello'", + &output, NULL, NULL, + &err)) + { + fprintf (stderr, "Error: %s\n", err->message); + g_error_free (err); + exit (1); + } + else + { + g_assert (output != NULL); + + if (strcmp (output, "hello\n") != 0) + { + printf ("output was '%s', should have been 'hello'\n", + output); + + exit (1); + } + + g_free (output); + output = NULL; + } +#endif + /* Running sort synchronously, collecting its output. 'sort' command is selected + * because it is non-builtin command on both unix and win32 with well-defined stdout behaviour. + */ + g_file_set_contents ("spawn-test-created-file.txt", "line first\nline 2\nline last\n", -1, &err); + g_assert_no_error(err); + if (!g_spawn_command_line_sync ("sort spawn-test-created-file.txt", + &output, &erroutput, NULL, + &err)) + { + fprintf (stderr, "Error: %s\n", err->message); + g_error_free (err); + exit (1); + } + else + { + g_assert (output != NULL); + g_assert (erroutput != NULL); + + if (strstr (output, "\nline first") == 0) + { + printf ("output was '%s', should have contained 'line first' in second line\n", + output); + + exit (1); + } + if (erroutput[0] != '\0') + { + printf ("error output was '%s', should have been empty\n", + erroutput); + exit (1); + } + + g_free (output); + output = NULL; + g_free (erroutput); + erroutput = NULL; + g_unlink ("spawn-test-created-file.txt"); + } + + if (!g_spawn_command_line_sync ("sort non-existing-file.txt", + NULL, &erroutput, NULL, + &err)) + { + fprintf (stderr, "Error: %s\n", err->message); + g_error_free (err); + exit (1); + } + else + { + g_assert (erroutput != NULL); + + if (erroutput[0] == '\0') + { + printf ("erroutput was empty, expected contain error message about non-existing-file.txt\n"); + exit (1); + } + g_free (erroutput); + erroutput = NULL; + } + +#ifdef G_OS_WIN32 + printf ("Running spawn-test-win32-gui in various ways.\n"); + + printf ("First asynchronously (without wait).\n"); + g_snprintf (full_cmdline, sizeof (full_cmdline), "'%s' 1", spawn_binary); + if (!g_spawn_command_line_async (full_cmdline, &err)) + { + fprintf (stderr, "Error: %s\n", err->message); + g_error_free (err); + exit (1); + } + + printf ("Now synchronously, collecting its output.\n"); + g_snprintf (full_cmdline, sizeof (full_cmdline), "'%s' 2", spawn_binary); + if (!g_spawn_command_line_sync (full_cmdline, + &output, &erroutput, NULL, + &err)) + { + fprintf (stderr, "Error: %s\n", err->message); + g_error_free (err); + exit (1); + } + else + { + g_assert (output != NULL); + g_assert (erroutput != NULL); + + if (strcmp (output, "This is stdout\r\n") != 0) + { + printf ("output was '%s', should have been 'This is stdout'\n", + g_strescape (output, NULL)); + + exit (1); + } + if (strcmp (erroutput, "This is stderr\r\n") != 0) + { + printf ("error output was '%s', should have been 'This is stderr'\n", + g_strescape (erroutput, NULL)); + exit (1); + } + + g_free (output); + output = NULL; + g_free (erroutput); + erroutput = NULL; + } + + printf ("Now with G_SPAWN_FILE_AND_ARGV_ZERO.\n"); + g_snprintf (full_cmdline, sizeof (full_cmdline), "'%s' this-should-be-argv-zero print_argv0", spawn_binary); + if (!g_shell_parse_argv (full_cmdline, NULL, &argv, &err)) + { + fprintf (stderr, "Error parsing command line? %s\n", err->message); + g_error_free (err); + exit (1); + } + + if (!g_spawn_sync (NULL, argv, NULL, + G_SPAWN_FILE_AND_ARGV_ZERO, + NULL, NULL, &output, NULL, NULL, + &err)) + { + fprintf (stderr, "Error: %s\n", err->message); + g_error_free (err); + exit (1); + } + else + { + if (strcmp (output, "this-should-be-argv-zero") != 0) + { + printf ("output was '%s', should have been 'this-should-be-argv-zero'\n", output); + exit (1); + } + g_free (output); + output = NULL; + } + + printf ("Now talking to it through pipes.\n"); + + if (pipe (pipedown) < 0 || + pipe (pipeup) < 0) + { + fprintf (stderr, "Could not create pipes\n"); + exit (1); + } + + g_snprintf (full_cmdline, sizeof (full_cmdline), "'%s' pipes %d %d", spawn_binary, pipedown[0], pipeup[1]); + if (!g_shell_parse_argv (full_cmdline, + NULL, &argv, + &err)) + { + fprintf (stderr, "Error parsing command line? %s\n", err->message); + g_error_free (err); + exit (1); + } + + if (!g_spawn_async (NULL, argv, NULL, + G_SPAWN_LEAVE_DESCRIPTORS_OPEN | + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, NULL, + &err)) + { + fprintf (stderr, "Error: %s\n", err->message); + g_error_free (err); + exit (1); + } + else + { + int k, n; + char buf[100]; + + if ((k = read (pipeup[0], &n, sizeof (n))) != sizeof (n)) + { + int errsv = errno; + if (k == -1) + fprintf (stderr, "Read error: %s\n", g_strerror (errsv)); + else + fprintf (stderr, "Wanted to read %d bytes, got %d\n", + (int)sizeof (n), k); + exit (1); + } + + if ((k = read (pipeup[0], buf, n)) != n) + { + int errsv = errno; + if (k == -1) + fprintf (stderr, "Read error: %s\n", g_strerror (errsv)); + else + fprintf (stderr, "Wanted to read %d bytes, got %d\n", + n, k); + exit (1); + } + + n = strlen ("Bye then"); + if (write (pipedown[1], &n, sizeof (n)) == -1 || + write (pipedown[1], "Bye then", n) == -1) + { + int errsv = errno; + fprintf (stderr, "Write error: %s\n", g_strerror (errsv)); + exit (1); + } + + if ((k = read (pipeup[0], &n, sizeof (n))) != sizeof (n)) + { + int errsv = errno; + if (k == -1) + fprintf (stderr, "Read error: %s\n", g_strerror (errsv)); + else + fprintf (stderr, "Wanted to read %d bytes, got %d\n", + (int)sizeof (n), k); + exit (1); + } + if (n != strlen ("See ya")) + { + printf ("child wrote %d bytes, expected %d", n, (int) strlen ("See ya")); + exit (1); + } + + if ((k = read (pipeup[0], buf, n)) != n) + { + int errsv = errno; + if (k == -1) + fprintf (stderr, "Read error: %s\n", g_strerror (errsv)); + else + fprintf (stderr, "Wanted to read %d bytes, got %d\n", + n, k); + exit (1); + } + buf[n] = '\0'; + if (strcmp (buf, "See ya") != 0) + { + printf ("output was '%s', should have been 'See ya'\n", buf); + exit (1); + } + } +#endif +} + +int +main (int argc, + char *argv[]) +{ + run_tests (argv[0]); + + return 0; +} diff --git a/tests/thread-test.c b/tests/thread-test.c new file mode 100644 index 0000000..883aa54 --- /dev/null +++ b/tests/thread-test.c @@ -0,0 +1,400 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include + +/* GMutex */ + +static GMutex test_g_mutex_mutex; +static guint test_g_mutex_int = 0; +static gboolean test_g_mutex_thread_ready; +G_LOCK_DEFINE_STATIC (test_g_mutex); + +static gpointer +test_g_mutex_thread (gpointer data) +{ + g_assert (GPOINTER_TO_INT (data) == 42); + g_assert (g_mutex_trylock (&test_g_mutex_mutex) == FALSE); + g_assert (G_TRYLOCK (test_g_mutex) == FALSE); + test_g_mutex_thread_ready = TRUE; + g_mutex_lock (&test_g_mutex_mutex); + g_assert (test_g_mutex_int == 42); + g_mutex_unlock (&test_g_mutex_mutex); + + return GINT_TO_POINTER (41); +} + +static void +test_g_mutex (void) +{ + GThread *thread; + + g_assert (g_mutex_trylock (&test_g_mutex_mutex)); + g_assert (G_TRYLOCK (test_g_mutex)); + test_g_mutex_thread_ready = FALSE; + thread = g_thread_create (test_g_mutex_thread, GINT_TO_POINTER (42), + TRUE, NULL); + /* This busy wait is only for testing purposes and not an example of + * good code!*/ + while (!test_g_mutex_thread_ready) + g_usleep (G_USEC_PER_SEC / 5); + test_g_mutex_int = 42; + G_UNLOCK (test_g_mutex); + g_mutex_unlock (&test_g_mutex_mutex); + g_assert (GPOINTER_TO_INT (g_thread_join (thread)) == 41); +} + +/* GStaticRecMutex */ + +static GStaticRecMutex test_g_static_rec_mutex_mutex = G_STATIC_REC_MUTEX_INIT; +static guint test_g_static_rec_mutex_int = 0; +static gboolean test_g_static_rec_mutex_thread_ready; + +static gpointer +test_g_static_rec_mutex_thread (gpointer data) +{ + g_assert (GPOINTER_TO_INT (data) == 42); + g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex) + == FALSE); + test_g_static_rec_mutex_thread_ready = TRUE; + g_static_rec_mutex_lock (&test_g_static_rec_mutex_mutex); + g_static_rec_mutex_lock (&test_g_static_rec_mutex_mutex); + g_assert (test_g_static_rec_mutex_int == 42); + test_g_static_rec_mutex_thread_ready = FALSE; + g_static_rec_mutex_unlock (&test_g_static_rec_mutex_mutex); + g_static_rec_mutex_unlock (&test_g_static_rec_mutex_mutex); + + g_thread_exit (GINT_TO_POINTER (43)); + + g_assert_not_reached (); + return NULL; +} + +static void +test_g_static_rec_mutex (void) +{ + GThread *thread; + + g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex)); + test_g_static_rec_mutex_thread_ready = FALSE; + thread = g_thread_create (test_g_static_rec_mutex_thread, + GINT_TO_POINTER (42), TRUE, NULL); + /* This busy wait is only for testing purposes and not an example of + * good code!*/ + while (!test_g_static_rec_mutex_thread_ready) + g_usleep (G_USEC_PER_SEC / 5); + + g_assert (g_static_rec_mutex_trylock (&test_g_static_rec_mutex_mutex)); + test_g_static_rec_mutex_int = 41; + g_static_rec_mutex_unlock (&test_g_static_rec_mutex_mutex); + test_g_static_rec_mutex_int = 42; + g_static_rec_mutex_unlock (&test_g_static_rec_mutex_mutex); + + /* This busy wait is only for testing purposes and not an example of + * good code!*/ + while (test_g_static_rec_mutex_thread_ready) + g_usleep (G_USEC_PER_SEC / 5); + + g_static_rec_mutex_lock (&test_g_static_rec_mutex_mutex); + test_g_static_rec_mutex_int = 0; + g_static_rec_mutex_unlock (&test_g_static_rec_mutex_mutex); + + g_assert (GPOINTER_TO_INT (g_thread_join (thread)) == 43); +} + +/* GStaticPrivate */ + +#define THREADS 10 + +static GStaticPrivate test_g_static_private_private1 = G_STATIC_PRIVATE_INIT; +static GStaticPrivate test_g_static_private_private2 = G_STATIC_PRIVATE_INIT; +static GMutex test_g_static_private_mutex; +static guint test_g_static_private_counter = 0; +static guint test_g_static_private_ready = 0; + +static gpointer +test_g_static_private_constructor (void) +{ + g_mutex_lock (&test_g_static_private_mutex); + test_g_static_private_counter++; + g_mutex_unlock (&test_g_static_private_mutex); + return g_new (guint,1); +} + +static void +test_g_static_private_destructor (gpointer data) +{ + g_mutex_lock (&test_g_static_private_mutex); + test_g_static_private_counter--; + g_mutex_unlock (&test_g_static_private_mutex); + g_free (data); +} + + +static gpointer +test_g_static_private_thread (gpointer data) +{ + guint number = GPOINTER_TO_INT (data); + guint i; + guint *private1, *private2; + for (i = 0; i < 10; i++) + { + number = number * 11 + 1; /* A very simple and bad RNG ;-) */ + private1 = g_static_private_get (&test_g_static_private_private1); + if (!private1 || number % 7 > 3) + { + private1 = test_g_static_private_constructor (); + g_static_private_set (&test_g_static_private_private1, private1, + test_g_static_private_destructor); + } + *private1 = number; + private2 = g_static_private_get (&test_g_static_private_private2); + if (!private2 || number % 13 > 5) + { + private2 = test_g_static_private_constructor (); + g_static_private_set (&test_g_static_private_private2, private2, + test_g_static_private_destructor); + } + *private2 = number * 2; + g_usleep (G_USEC_PER_SEC / 5); + g_assert (number == *private1); + g_assert (number * 2 == *private2); + } + g_mutex_lock (&test_g_static_private_mutex); + test_g_static_private_ready++; + g_mutex_unlock (&test_g_static_private_mutex); + + /* Busy wait is not nice but that's just a test */ + while (test_g_static_private_ready != 0) + g_usleep (G_USEC_PER_SEC / 5); + + for (i = 0; i < 10; i++) + { + private2 = g_static_private_get (&test_g_static_private_private2); + number = number * 11 + 1; /* A very simple and bad RNG ;-) */ + if (!private2 || number % 13 > 5) + { + private2 = test_g_static_private_constructor (); + g_static_private_set (&test_g_static_private_private2, private2, + test_g_static_private_destructor); + } + *private2 = number * 2; + g_usleep (G_USEC_PER_SEC / 5); + g_assert (number * 2 == *private2); + } + + return GINT_TO_POINTER (GPOINTER_TO_INT (data) * 3); +} + +static void +test_g_static_private (void) +{ + GThread *threads[THREADS]; + guint i; + + test_g_static_private_ready = 0; + + for (i = 0; i < THREADS; i++) + { + threads[i] = g_thread_create (test_g_static_private_thread, + GINT_TO_POINTER (i), TRUE, NULL); + } + + /* Busy wait is not nice but that's just a test */ + while (test_g_static_private_ready != THREADS) + g_usleep (G_USEC_PER_SEC / 5); + + /* Reuse the static private */ + g_static_private_free (&test_g_static_private_private2); + g_static_private_init (&test_g_static_private_private2); + + test_g_static_private_ready = 0; + + for (i = 0; i < THREADS; i++) + g_assert (GPOINTER_TO_UINT (g_thread_join (threads[i])) == i * 3); + + g_assert (test_g_static_private_counter == 0); +} + +/* GStaticRWLock */ + +/* -1 = writing; >0 = # of readers */ +static gint test_g_static_rw_lock_state = 0; +G_LOCK_DEFINE (test_g_static_rw_lock_state); + +static gboolean test_g_static_rw_lock_run = TRUE; +static GStaticRWLock test_g_static_rw_lock_lock = G_STATIC_RW_LOCK_INIT; + +static gpointer +test_g_static_rw_lock_thread (gpointer data) +{ + while (test_g_static_rw_lock_run) + { + if (g_random_double() > .2) /* I'm a reader */ + { + + if (g_random_double() > .2) /* I'll block */ + g_static_rw_lock_reader_lock (&test_g_static_rw_lock_lock); + else /* I'll only try */ + if (!g_static_rw_lock_reader_trylock (&test_g_static_rw_lock_lock)) + continue; + G_LOCK (test_g_static_rw_lock_state); + g_assert (test_g_static_rw_lock_state >= 0); + test_g_static_rw_lock_state++; + G_UNLOCK (test_g_static_rw_lock_state); + + g_usleep (g_random_int_range (20,1000)); + + G_LOCK (test_g_static_rw_lock_state); + test_g_static_rw_lock_state--; + G_UNLOCK (test_g_static_rw_lock_state); + + g_static_rw_lock_reader_unlock (&test_g_static_rw_lock_lock); + } + else /* I'm a writer */ + { + + if (g_random_double() > .2) /* I'll block */ + g_static_rw_lock_writer_lock (&test_g_static_rw_lock_lock); + else /* I'll only try */ + if (!g_static_rw_lock_writer_trylock (&test_g_static_rw_lock_lock)) + continue; + G_LOCK (test_g_static_rw_lock_state); + g_assert (test_g_static_rw_lock_state == 0); + test_g_static_rw_lock_state = -1; + G_UNLOCK (test_g_static_rw_lock_state); + + g_usleep (g_random_int_range (20,1000)); + + G_LOCK (test_g_static_rw_lock_state); + test_g_static_rw_lock_state = 0; + G_UNLOCK (test_g_static_rw_lock_state); + + g_static_rw_lock_writer_unlock (&test_g_static_rw_lock_lock); + } + } + return NULL; +} + +static void +test_g_static_rw_lock (void) +{ + GThread *threads[THREADS]; + guint i; + for (i = 0; i < THREADS; i++) + { + threads[i] = g_thread_create (test_g_static_rw_lock_thread, + NULL, TRUE, NULL); + } + g_usleep (G_USEC_PER_SEC * 5); + test_g_static_rw_lock_run = FALSE; + for (i = 0; i < THREADS; i++) + { + g_thread_join (threads[i]); + } + g_assert (test_g_static_rw_lock_state == 0); +} + +#define G_ONCE_SIZE 100 +#define G_ONCE_THREADS 10 + +G_LOCK_DEFINE (test_g_once); +static guint test_g_once_guint_array[G_ONCE_SIZE]; +static GOnce test_g_once_array[G_ONCE_SIZE]; + +static gpointer +test_g_once_init_func(gpointer arg) +{ + guint *count = arg; + g_usleep (g_random_int_range (20,1000)); + (*count)++; + g_usleep (g_random_int_range (20,1000)); + return arg; +} + +static gpointer +test_g_once_thread (gpointer ignore) +{ + guint i; + G_LOCK (test_g_once); + /* Don't start before all threads are created */ + G_UNLOCK (test_g_once); + for (i = 0; i < 1000; i++) + { + guint pos = g_random_int_range (0, G_ONCE_SIZE); + gpointer ret = g_once (test_g_once_array + pos, test_g_once_init_func, + test_g_once_guint_array + pos); + g_assert (ret == test_g_once_guint_array + pos); + } + + /* Make sure, that all counters are touched at least once */ + for (i = 0; i < G_ONCE_SIZE; i++) + { + gpointer ret = g_once (test_g_once_array + i, test_g_once_init_func, + test_g_once_guint_array + i); + g_assert (ret == test_g_once_guint_array + i); + } + + return NULL; +} + +static void +test_g_thread_once (void) +{ + static GOnce once_init = G_ONCE_INIT; + GThread *threads[G_ONCE_THREADS]; + guint i; + for (i = 0; i < G_ONCE_SIZE; i++) + { + test_g_once_array[i] = once_init; + test_g_once_guint_array[i] = i; + } + G_LOCK (test_g_once); + for (i = 0; i < G_ONCE_THREADS; i++) + { + threads[i] = g_thread_create (test_g_once_thread, GUINT_TO_POINTER(i%2), + TRUE, NULL); + } + G_UNLOCK (test_g_once); + for (i = 0; i < G_ONCE_THREADS; i++) + { + g_thread_join (threads[i]); + } + + for (i = 0; i < G_ONCE_SIZE; i++) + { + g_assert (test_g_once_guint_array[i] == i + 1); + } +} + +/* run all the tests */ +static void +run_all_tests (void) +{ + test_g_mutex (); + test_g_static_rec_mutex (); + test_g_static_private (); + test_g_static_rw_lock (); + test_g_thread_once (); +} + +int +main (int argc, + char *argv[]) +{ + run_all_tests (); + + /* Now we rerun all tests, but this time we fool the system into + * thinking, that the available thread system is not native, but + * userprovided. */ + + g_thread_use_default_impl = FALSE; + run_all_tests (); + + /* XXX: And this shows how silly the above non-native tests are */ + g_static_rw_lock_free (&test_g_static_rw_lock_lock); + g_static_rec_mutex_free (&test_g_static_rec_mutex_mutex); + g_static_private_free (&test_g_static_private_private2); + + return 0; +} diff --git a/tests/threadpool-test.c b/tests/threadpool-test.c new file mode 100644 index 0000000..1612e27 --- /dev/null +++ b/tests/threadpool-test.c @@ -0,0 +1,465 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include "config.h" + +#include + +/* #define DEBUG 1 */ + +#ifdef DEBUG +# define DEBUG_MSG(args) g_printerr args ; g_printerr ("\n"); +#else +# define DEBUG_MSG(x) +#endif + +#define WAIT 5 /* seconds */ +#define MAX_THREADS 10 + +/* if > 0 the test will run continuously (since the test ends when + * thread count is 0), if -1 it means no limit to unused threads + * if 0 then no unused threads are possible */ +#define MAX_UNUSED_THREADS -1 + +G_LOCK_DEFINE_STATIC (thread_counter_pools); + +static gulong abs_thread_counter = 0; +static gulong running_thread_counter = 0; +static gulong leftover_task_counter = 0; + +G_LOCK_DEFINE_STATIC (last_thread); + +static guint last_thread_id = 0; + +G_LOCK_DEFINE_STATIC (thread_counter_sort); + +static gulong sort_thread_counter = 0; + +static GThreadPool *idle_pool = NULL; + +static GMainLoop *main_loop = NULL; + +static void +test_thread_functions (void) +{ + gint max_unused_threads; + guint max_idle_time; + + /* This function attempts to call functions which don't need a + * threadpool to operate to make sure no uninitialised pointers + * accessed and no errors occur. + */ + + max_unused_threads = 3; + + DEBUG_MSG (("[funcs] Setting max unused threads to %d", + max_unused_threads)); + g_thread_pool_set_max_unused_threads (max_unused_threads); + + DEBUG_MSG (("[funcs] Getting max unused threads = %d", + g_thread_pool_get_max_unused_threads ())); + g_assert (g_thread_pool_get_max_unused_threads() == max_unused_threads); + + DEBUG_MSG (("[funcs] Getting num unused threads = %d", + g_thread_pool_get_num_unused_threads ())); + g_assert (g_thread_pool_get_num_unused_threads () == 0); + + DEBUG_MSG (("[funcs] Stopping unused threads")); + g_thread_pool_stop_unused_threads (); + + max_idle_time = 10 * G_USEC_PER_SEC; + + DEBUG_MSG (("[funcs] Setting max idle time to %d", + max_idle_time)); + g_thread_pool_set_max_idle_time (max_idle_time); + + DEBUG_MSG (("[funcs] Getting max idle time = %d", + g_thread_pool_get_max_idle_time ())); + g_assert (g_thread_pool_get_max_idle_time () == max_idle_time); + + DEBUG_MSG (("[funcs] Setting max idle time to 0")); + g_thread_pool_set_max_idle_time (0); + + DEBUG_MSG (("[funcs] Getting max idle time = %d", + g_thread_pool_get_max_idle_time ())); + g_assert (g_thread_pool_get_max_idle_time () == 0); +} + +static void +test_thread_stop_unused (void) +{ + GThreadPool *pool; + guint i; + guint limit = 100; + + /* Spawn a few threads. */ + g_thread_pool_set_max_unused_threads (-1); + pool = g_thread_pool_new ((GFunc) g_usleep, NULL, -1, FALSE, NULL); + + for (i = 0; i < limit; i++) + g_thread_pool_push (pool, GUINT_TO_POINTER (1000), NULL); + + DEBUG_MSG (("[unused] ===> pushed %d threads onto the idle pool", + limit)); + + /* Wait for the threads to migrate. */ + g_usleep (G_USEC_PER_SEC); + + DEBUG_MSG (("[unused] stopping unused threads")); + g_thread_pool_stop_unused_threads (); + + for (i = 0; i < 5; i++) + { + if (g_thread_pool_get_num_unused_threads () == 0) + break; + + DEBUG_MSG (("[unused] waiting ONE second for threads to die")); + + /* Some time for threads to die. */ + g_usleep (G_USEC_PER_SEC); + } + + DEBUG_MSG (("[unused] stopped idle threads, %d remain", + g_thread_pool_get_num_unused_threads ())); + + g_assert (g_thread_pool_get_num_unused_threads () == 0); + + g_thread_pool_set_max_unused_threads (MAX_THREADS); + + DEBUG_MSG (("[unused] cleaning up thread pool")); + g_thread_pool_free (pool, FALSE, TRUE); +} + +static void +test_thread_pools_entry_func (gpointer data, gpointer user_data) +{ +#ifdef DEBUG + guint id = 0; + + id = GPOINTER_TO_UINT (data); +#endif + + DEBUG_MSG (("[pool] ---> [%3.3d] entered thread.", id)); + + G_LOCK (thread_counter_pools); + abs_thread_counter++; + running_thread_counter++; + G_UNLOCK (thread_counter_pools); + + g_usleep (g_random_int_range (0, 4000)); + + G_LOCK (thread_counter_pools); + running_thread_counter--; + leftover_task_counter--; + + DEBUG_MSG (("[pool] ---> [%3.3d] exiting thread (abs count:%ld, " + "running count:%ld, left over:%ld)", + id, abs_thread_counter, + running_thread_counter, leftover_task_counter)); + G_UNLOCK (thread_counter_pools); +} + +static void +test_thread_pools (void) +{ + GThreadPool *pool1, *pool2, *pool3; + guint runs; + guint i; + + pool1 = g_thread_pool_new ((GFunc)test_thread_pools_entry_func, NULL, 3, FALSE, NULL); + pool2 = g_thread_pool_new ((GFunc)test_thread_pools_entry_func, NULL, 5, TRUE, NULL); + pool3 = g_thread_pool_new ((GFunc)test_thread_pools_entry_func, NULL, 7, TRUE, NULL); + + runs = 300; + for (i = 0; i < runs; i++) + { + g_thread_pool_push (pool1, GUINT_TO_POINTER (i + 1), NULL); + g_thread_pool_push (pool2, GUINT_TO_POINTER (i + 1), NULL); + g_thread_pool_push (pool3, GUINT_TO_POINTER (i + 1), NULL); + + G_LOCK (thread_counter_pools); + leftover_task_counter += 3; + G_UNLOCK (thread_counter_pools); + } + + g_thread_pool_free (pool1, TRUE, TRUE); + g_thread_pool_free (pool2, FALSE, TRUE); + g_thread_pool_free (pool3, FALSE, TRUE); + + g_assert (runs * 3 == abs_thread_counter + leftover_task_counter); + g_assert (running_thread_counter == 0); +} + +static gint +test_thread_sort_compare_func (gconstpointer a, gconstpointer b, gpointer user_data) +{ + guint32 id1, id2; + + id1 = GPOINTER_TO_UINT (a); + id2 = GPOINTER_TO_UINT (b); + + return (id1 > id2 ? +1 : id1 == id2 ? 0 : -1); +} + +static void +test_thread_sort_entry_func (gpointer data, gpointer user_data) +{ + guint thread_id; + gboolean is_sorted; + + G_LOCK (last_thread); + + thread_id = GPOINTER_TO_UINT (data); + is_sorted = GPOINTER_TO_INT (user_data); + + DEBUG_MSG (("%s ---> entered thread:%2.2d, last thread:%2.2d", + is_sorted ? "[ sorted]" : "[unsorted]", + thread_id, last_thread_id)); + + if (is_sorted) { + static gboolean last_failed = FALSE; + + if (last_thread_id > thread_id) { + if (last_failed) { + g_assert (last_thread_id <= thread_id); + } + + /* Here we remember one fail and if it concurrently fails, it + * can not be sorted. the last thread id might be < this thread + * id if something is added to the queue since threads were + * created + */ + last_failed = TRUE; + } else { + last_failed = FALSE; + } + + last_thread_id = thread_id; + } + + G_UNLOCK (last_thread); + + g_usleep (WAIT * 1000); +} + +static void +test_thread_sort (gboolean sort) +{ + GThreadPool *pool; + guint limit; + guint max_threads; + guint i; + + limit = MAX_THREADS * 10; + + if (sort) { + max_threads = 1; + } else { + max_threads = MAX_THREADS; + } + + /* It is important that we only have a maximum of 1 thread for this + * test since the results can not be guaranteed to be sorted if > 1. + * + * Threads are scheduled by the operating system and are executed at + * random. It cannot be assumed that threads are executed in the + * order they are created. This was discussed in bug #334943. + */ + + pool = g_thread_pool_new (test_thread_sort_entry_func, + GINT_TO_POINTER (sort), + max_threads, + FALSE, + NULL); + + g_thread_pool_set_max_unused_threads (MAX_UNUSED_THREADS); + + if (sort) { + g_thread_pool_set_sort_function (pool, + test_thread_sort_compare_func, + GUINT_TO_POINTER (69)); + } + + for (i = 0; i < limit; i++) { + guint id; + + id = g_random_int_range (1, limit) + 1; + g_thread_pool_push (pool, GUINT_TO_POINTER (id), NULL); + DEBUG_MSG (("%s ===> pushed new thread with id:%d, number " + "of threads:%d, unprocessed:%d", + sort ? "[ sorted]" : "[unsorted]", + id, + g_thread_pool_get_num_threads (pool), + g_thread_pool_unprocessed (pool))); + } + + g_assert (g_thread_pool_get_max_threads (pool) == (gint) max_threads); + g_assert (g_thread_pool_get_num_threads (pool) == (guint) g_thread_pool_get_max_threads (pool)); + g_thread_pool_free (pool, TRUE, TRUE); +} + +static void +test_thread_idle_time_entry_func (gpointer data, gpointer user_data) +{ +#ifdef DEBUG + guint thread_id; + + thread_id = GPOINTER_TO_UINT (data); +#endif + + DEBUG_MSG (("[idle] ---> entered thread:%2.2d", thread_id)); + + g_usleep (WAIT * 1000); + + DEBUG_MSG (("[idle] <--- exiting thread:%2.2d", thread_id)); +} + +static gboolean +test_thread_idle_timeout (gpointer data) +{ + gint i; + + for (i = 0; i < 2; i++) { + g_thread_pool_push (idle_pool, GUINT_TO_POINTER (100 + i), NULL); + DEBUG_MSG (("[idle] ===> pushed new thread with id:%d, number " + "of threads:%d, unprocessed:%d", + 100 + i, + g_thread_pool_get_num_threads (idle_pool), + g_thread_pool_unprocessed (idle_pool))); + } + + + return FALSE; +} + +static void +test_thread_idle_time (void) +{ + guint limit = 50; + guint interval = 10000; + guint i; + + idle_pool = g_thread_pool_new (test_thread_idle_time_entry_func, + NULL, + 0, + FALSE, + NULL); + + g_thread_pool_set_max_threads (idle_pool, MAX_THREADS, NULL); + g_thread_pool_set_max_unused_threads (MAX_UNUSED_THREADS); + g_thread_pool_set_max_idle_time (interval); + + g_assert (g_thread_pool_get_max_threads (idle_pool) == MAX_THREADS); + g_assert (g_thread_pool_get_max_unused_threads () == MAX_UNUSED_THREADS); + g_assert (g_thread_pool_get_max_idle_time () == interval); + + for (i = 0; i < limit; i++) { + g_thread_pool_push (idle_pool, GUINT_TO_POINTER (i + 1), NULL); + DEBUG_MSG (("[idle] ===> pushed new thread with id:%d, " + "number of threads:%d, unprocessed:%d", + i, + g_thread_pool_get_num_threads (idle_pool), + g_thread_pool_unprocessed (idle_pool))); + } + + g_assert_cmpint (g_thread_pool_unprocessed (idle_pool), <=, limit); + + g_timeout_add ((interval - 1000), + test_thread_idle_timeout, + GUINT_TO_POINTER (interval)); +} + +static gboolean +test_check_start_and_stop (gpointer user_data) +{ + static guint test_number = 0; + static gboolean run_next = FALSE; + gboolean continue_timeout = TRUE; + gboolean quit = TRUE; + + if (test_number == 0) { + run_next = TRUE; + DEBUG_MSG (("***** RUNNING TEST %2.2d *****", test_number)); + } + + if (run_next) { + test_number++; + + switch (test_number) { + case 1: + test_thread_functions (); + break; + case 2: + test_thread_stop_unused (); + break; + case 3: + test_thread_pools (); + break; + case 4: + test_thread_sort (FALSE); + break; + case 5: + test_thread_sort (TRUE); + break; + case 6: + test_thread_stop_unused (); + break; + case 7: + test_thread_idle_time (); + break; + default: + DEBUG_MSG (("***** END OF TESTS *****")); + g_main_loop_quit (main_loop); + continue_timeout = FALSE; + break; + } + + run_next = FALSE; + return continue_timeout; + } + + if (test_number == 3) { + G_LOCK (thread_counter_pools); + quit &= running_thread_counter <= 0; + DEBUG_MSG (("***** POOL RUNNING THREAD COUNT:%ld", + running_thread_counter)); + G_UNLOCK (thread_counter_pools); + } + + if (test_number == 4 || test_number == 5) { + G_LOCK (thread_counter_sort); + quit &= sort_thread_counter <= 0; + DEBUG_MSG (("***** POOL SORT THREAD COUNT:%ld", + sort_thread_counter)); + G_UNLOCK (thread_counter_sort); + } + + if (test_number == 7) { + guint idle; + + idle = g_thread_pool_get_num_unused_threads (); + quit &= idle < 1; + DEBUG_MSG (("***** POOL IDLE THREAD COUNT:%d, UNPROCESSED JOBS:%d", + idle, g_thread_pool_unprocessed (idle_pool))); + } + + if (quit) { + run_next = TRUE; + } + + return continue_timeout; +} + +int +main (int argc, char *argv[]) +{ + DEBUG_MSG (("Starting... (in one second)")); + g_timeout_add (1000, test_check_start_and_stop, NULL); + + main_loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + g_thread_pool_free (idle_pool, FALSE, TRUE); + return 0; +} diff --git a/tests/timeloop-basic.c b/tests/timeloop-basic.c new file mode 100644 index 0000000..57d7e1f --- /dev/null +++ b/tests/timeloop-basic.c @@ -0,0 +1,236 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +static int n_children = 3; +static int n_active_children; +static int n_iters = 10000; + +static int write_fds[1024]; +static struct pollfd poll_fds[1024]; + +void +my_pipe (int *fds) +{ + if (pipe(fds) < 0) + { + int errsv = errno; + fprintf (stderr, "Cannot create pipe %s\n", strerror (errsv)); + exit (1); + } +} + +int +read_all (int fd, char *buf, int len) +{ + size_t bytes_read = 0; + gssize count; + + while (bytes_read < len) + { + count = read (fd, buf + bytes_read, len - bytes_read); + if (count < 0) + { + if (errno != EAGAIN) + return FALSE; + } + else if (count == 0) + return FALSE; + + bytes_read += count; + } + + return TRUE; +} + +int +write_all (int fd, char *buf, int len) +{ + size_t bytes_written = 0; + gssize count; + + while (bytes_written < len) + { + count = write (fd, buf + bytes_written, len - bytes_written); + if (count < 0) + { + if (errno != EAGAIN) + return FALSE; + } + + bytes_written += count; + } + + return TRUE; +} + +void +run_child (int in_fd, int out_fd) +{ + int i; + int val = 1; + + for (i = 0; i < n_iters; i++) + { + write_all (out_fd, (char *)&val, sizeof (val)); + read_all (in_fd, (char *)&val, sizeof (val)); + } + + val = 0; + write_all (out_fd, (char *)&val, sizeof (val)); + + exit (0); +} + +int +input_callback (int source, int dest) +{ + int val; + + if (!read_all (source, (char *)&val, sizeof(val))) + { + fprintf (stderr,"Unexpected EOF\n"); + exit (1); + } + + if (val) + { + write_all (dest, (char *)&val, sizeof(val)); + return TRUE; + } + else + { + close (source); + close (dest); + + n_active_children--; + return FALSE; + } +} + +void +create_child (int pos) +{ + int pid, errsv; + int in_fds[2]; + int out_fds[2]; + + my_pipe (in_fds); + my_pipe (out_fds); + + pid = fork (); + errsv = errno; + + if (pid > 0) /* Parent */ + { + close (in_fds[0]); + close (out_fds[1]); + + write_fds[pos] = in_fds[1]; + poll_fds[pos].fd = out_fds[0]; + poll_fds[pos].events = POLLIN; + } + else if (pid == 0) /* Child */ + { + close (in_fds[1]); + close (out_fds[0]); + + setsid (); + + run_child (in_fds[0], out_fds[1]); + } + else /* Error */ + { + fprintf (stderr,"Cannot fork: %s\n", strerror (errsv)); + exit (1); + } +} + +static double +difftimeval (struct timeval *old, struct timeval *new) +{ + return + (new->tv_sec - old->tv_sec) * 1000. + (new->tv_usec - old->tv_usec) / 1000; +} + +int +main (int argc, char **argv) +{ + int i, j; + struct rusage old_usage; + struct rusage new_usage; + + if (argc > 1) + n_children = atoi(argv[1]); + + if (argc > 2) + n_iters = atoi(argv[2]); + + printf ("Children: %d Iters: %d\n", n_children, n_iters); + + n_active_children = n_children; + for (i = 0; i < n_children; i++) + create_child (i); + + getrusage (RUSAGE_SELF, &old_usage); + + while (n_active_children > 0) + { + int old_n_active_children = n_active_children; + + poll (poll_fds, n_active_children, -1); + + for (i=0; i n_active_children) + { + j = 0; + for (i=0; i +#include +#include +#include +#include +#include + +#include + +static int n_children = 3; +static int n_active_children; +static int n_iters = 10000; +static GMainLoop *loop; + +static void +io_pipe (GIOChannel **channels) +{ + int fds[2]; + + if (pipe(fds) < 0) + { + int errsv = errno; + fprintf (stderr, "Cannot create pipe %s\n", g_strerror (errsv)); + exit (1); + } + + channels[0] = g_io_channel_unix_new (fds[0]); + channels[1] = g_io_channel_unix_new (fds[1]); +} + +static gboolean +read_all (GIOChannel *channel, char *buf, gsize len) +{ + gsize bytes_read = 0; + gsize count; + GIOError err; + + while (bytes_read < len) + { + err = g_io_channel_read (channel, buf + bytes_read, len - bytes_read, &count); + if (err) + { + if (err != G_IO_ERROR_AGAIN) + return FALSE; + } + else if (count == 0) + return FALSE; + + bytes_read += count; + } + + return TRUE; +} + +static gboolean +write_all (GIOChannel *channel, char *buf, gsize len) +{ + gsize bytes_written = 0; + gsize count; + GIOError err; + + while (bytes_written < len) + { + err = g_io_channel_write (channel, buf + bytes_written, len - bytes_written, &count); + if (err && err != G_IO_ERROR_AGAIN) + return FALSE; + + bytes_written += count; + } + + return TRUE; +} + +static void +run_child (GIOChannel *in_channel, GIOChannel *out_channel) +{ + int i; + int val = 1; + GTimer *timer = g_timer_new(); + + for (i = 0; i < n_iters; i++) + { + write_all (out_channel, (char *)&val, sizeof (val)); + read_all (in_channel, (char *)&val, sizeof (val)); + } + + val = 0; + write_all (out_channel, (char *)&val, sizeof (val)); + + val = g_timer_elapsed (timer, NULL) * 1000; + + write_all (out_channel, (char *)&val, sizeof (val)); + g_timer_destroy (timer); + + exit (0); +} + +static gboolean +input_callback (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + int val; + GIOChannel *dest = (GIOChannel *)data; + + if (!read_all (source, (char *)&val, sizeof(val))) + { + fprintf (stderr, "Unexpected EOF\n"); + exit (1); + } + + if (val) + { + write_all (dest, (char *)&val, sizeof(val)); + + return TRUE; + } + else + { + g_io_channel_close (source); + g_io_channel_close (dest); + + g_io_channel_unref (source); + g_io_channel_unref (dest); + + n_active_children--; + if (n_active_children == 0) + g_main_loop_quit (loop); + + return FALSE; + } +} + +static void +create_child (void) +{ + int pid, errsv; + GIOChannel *in_channels[2]; + GIOChannel *out_channels[2]; + + io_pipe (in_channels); + io_pipe (out_channels); + + pid = fork (); + errsv = errno; + + if (pid > 0) /* Parent */ + { + g_io_channel_close (in_channels[0]); + g_io_channel_unref (in_channels[0]); + g_io_channel_close (out_channels[1]); + g_io_channel_unref (out_channels[1]); + + g_io_add_watch (out_channels[0], G_IO_IN | G_IO_HUP, + input_callback, in_channels[1]); + } + else if (pid == 0) /* Child */ + { + g_io_channel_close (in_channels[1]); + g_io_channel_close (out_channels[0]); + + setsid (); + + run_child (in_channels[0], out_channels[1]); + } + else /* Error */ + { + fprintf (stderr, "Cannot fork: %s\n", g_strerror (errsv)); + exit (1); + } +} + +static double +difftimeval (struct timeval *old, struct timeval *new) +{ + return + (new->tv_sec - old->tv_sec) * 1000. + (new->tv_usec - old->tv_usec) / 1000; +} + +int +main (int argc, char **argv) +{ + int i; + struct rusage old_usage; + struct rusage new_usage; + + if (argc > 1) + n_children = atoi(argv[1]); + + if (argc > 2) + n_iters = atoi(argv[2]); + + printf ("Children: %d Iters: %d\n", n_children, n_iters); + + n_active_children = n_children; + for (i = 0; i < n_children; i++) + create_child (); + + getrusage (RUSAGE_SELF, &old_usage); + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + getrusage (RUSAGE_SELF, &new_usage); + + printf ("Elapsed user: %g\n", + difftimeval (&old_usage.ru_utime, &new_usage.ru_utime)); + printf ("Elapsed system: %g\n", + difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)); + printf ("Elapsed total: %g\n", + difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) + + difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)); + printf ("total / iteration: %g\n", + (difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) + + difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)) / + (n_iters * n_children)); + + g_main_loop_unref (loop); + return 0; +} diff --git a/tests/unicode-encoding.c b/tests/unicode-encoding.c new file mode 100644 index 0000000..b0603d1 --- /dev/null +++ b/tests/unicode-encoding.c @@ -0,0 +1,444 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include +#include +#include + +static gint exit_status = 0; + +G_GNUC_PRINTF (1, 2) +static void +croak (char *format, ...) +{ + va_list va; + + va_start (va, format); + vfprintf (stderr, format, va); + va_end (va); + + exit (1); +} + +G_GNUC_PRINTF (1, 2) +static void +fail (char *format, ...) +{ + va_list va; + + va_start (va, format); + vfprintf (stderr, format, va); + va_end (va); + + exit_status |= 1; +} + +typedef enum +{ + VALID, + INCOMPLETE, + NOTUNICODE, + OVERLONG, + MALFORMED +} Status; + +static gboolean +ucs4_equal (gunichar *a, gunichar *b) +{ + while (*a && *b && (*a == *b)) + { + a++; + b++; + } + + return (*a == *b); +} + +static gboolean +utf16_equal (gunichar2 *a, gunichar2 *b) +{ + while (*a && *b && (*a == *b)) + { + a++; + b++; + } + + return (*a == *b); +} + +static gint +utf16_count (gunichar2 *a) +{ + gint result = 0; + + while (a[result]) + result++; + + return result; +} + +static void +print_ucs4 (const gchar *prefix, gunichar *ucs4, gint ucs4_len) +{ + gint i; + g_print ("%s ", prefix); + for (i = 0; i < ucs4_len; i++) + g_print ("%x ", ucs4[i]); + g_print ("\n"); +} + +static void +process (gint line, + gchar *utf8, + Status status, + gunichar *ucs4, + gint ucs4_len) +{ + const gchar *end; + gboolean is_valid = g_utf8_validate (utf8, -1, &end); + GError *error = NULL; + glong items_read, items_written; + + switch (status) + { + case VALID: + if (!is_valid) + { + fail ("line %d: valid but g_utf8_validate returned FALSE\n", line); + return; + } + break; + case NOTUNICODE: + case INCOMPLETE: + case OVERLONG: + case MALFORMED: + if (is_valid) + { + fail ("line %d: invalid but g_utf8_validate returned TRUE\n", line); + return; + } + break; + } + + if (status == INCOMPLETE) + { + gunichar *ucs4_result; + + ucs4_result = g_utf8_to_ucs4 (utf8, -1, NULL, NULL, &error); + + if (!error || !g_error_matches (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT)) + { + fail ("line %d: incomplete input not properly detected\n", line); + return; + } + g_clear_error (&error); + + ucs4_result = g_utf8_to_ucs4 (utf8, -1, &items_read, NULL, &error); + + if (!ucs4_result || items_read == (glong) strlen (utf8)) + { + fail ("line %d: incomplete input not properly detected\n", line); + return; + } + + g_free (ucs4_result); + } + + if (status == VALID || status == NOTUNICODE) + { + gunichar *ucs4_result; + + ucs4_result = g_utf8_to_ucs4 (utf8, -1, &items_read, &items_written, &error); + if (!ucs4_result) + { + fail ("line %d: conversion with status %d to ucs4 failed: %s\n", line, status, error->message); + return; + } + + if (!ucs4_equal (ucs4_result, ucs4) || + items_read != (glong) strlen (utf8) || + items_written != ucs4_len) + { + fail ("line %d: results of conversion with status %d to ucs4 do not match expected.\n", line, status); + print_ucs4 ("expected: ", ucs4, ucs4_len); + print_ucs4 ("received: ", ucs4_result, items_written); + return; + } + + g_free (ucs4_result); + } + + if (status == VALID) + { + gunichar *ucs4_result; + gchar *utf8_result; + + ucs4_result = g_utf8_to_ucs4_fast (utf8, -1, &items_written); + + if (!ucs4_equal (ucs4_result, ucs4) || + items_written != ucs4_len) + { + fail ("line %d: results of fast conversion with status %d to ucs4 do not match expected.\n", line, status); + print_ucs4 ("expected: ", ucs4, ucs4_len); + print_ucs4 ("received: ", ucs4_result, items_written); + return; + } + + utf8_result = g_ucs4_to_utf8 (ucs4_result, -1, &items_read, &items_written, &error); + if (!utf8_result) + { + fail ("line %d: conversion back to utf8 failed: %s", line, error->message); + return; + } + + if (strcmp (utf8_result, utf8) != 0 || + items_read != ucs4_len || + items_written != (glong) strlen (utf8)) + { + fail ("line %d: conversion back to utf8 did not match original\n", line); + return; + } + + g_free (utf8_result); + g_free (ucs4_result); + } + + if (status == VALID) + { + gunichar2 *utf16_expected_tmp; + gunichar2 *utf16_expected; + gunichar2 *utf16_from_utf8; + gunichar2 *utf16_from_ucs4; + gunichar *ucs4_result; + gsize bytes_written; + gint n_chars; + gchar *utf8_result; + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define TARGET "UTF-16LE" +#else +#define TARGET "UTF-16" +#endif + + if (!(utf16_expected_tmp = (gunichar2 *)g_convert (utf8, -1, TARGET, "UTF-8", + NULL, &bytes_written, NULL))) + { + fail ("line %d: could not convert to UTF-16 via g_convert\n", line); + return; + } + + /* zero-terminate and remove BOM + */ + n_chars = bytes_written / 2; + if (utf16_expected_tmp[0] == 0xfeff) /* BOM */ + { + n_chars--; + utf16_expected = g_new (gunichar2, n_chars + 1); + memcpy (utf16_expected, utf16_expected_tmp + 1, sizeof(gunichar2) * n_chars); + } + else if (utf16_expected_tmp[0] == 0xfffe) /* ANTI-BOM */ + { + fail ("line %d: conversion via iconv to \"UTF-16\" is not native-endian\n", line); + return; + } + else + { + utf16_expected = g_new (gunichar2, n_chars + 1); + memcpy (utf16_expected, utf16_expected_tmp, sizeof(gunichar2) * n_chars); + } + + utf16_expected[n_chars] = '\0'; + + if (!(utf16_from_utf8 = g_utf8_to_utf16 (utf8, -1, &items_read, &items_written, &error))) + { + fail ("line %d: conversion to ucs16 failed: %s\n", line, error->message); + return; + } + + if (items_read != (glong) strlen (utf8) || + utf16_count (utf16_from_utf8) != items_written) + { + fail ("line %d: length error in conversion to ucs16\n", line); + return; + } + + if (!(utf16_from_ucs4 = g_ucs4_to_utf16 (ucs4, -1, &items_read, &items_written, &error))) + { + fail ("line %d: conversion to ucs16 failed: %s\n", line, error->message); + return; + } + + if (items_read != ucs4_len || + utf16_count (utf16_from_ucs4) != items_written) + { + fail ("line %d: length error in conversion to ucs16\n", line); + return; + } + + if (!utf16_equal (utf16_from_utf8, utf16_expected) || + !utf16_equal (utf16_from_ucs4, utf16_expected)) + { + fail ("line %d: results of conversion to ucs16 do not match\n", line); + return; + } + + if (!(utf8_result = g_utf16_to_utf8 (utf16_from_utf8, -1, &items_read, &items_written, &error))) + { + fail ("line %d: conversion back to utf8 failed: %s\n", line, error->message); + return; + } + + if (items_read != utf16_count (utf16_from_utf8) || + items_written != (glong) strlen (utf8)) + { + fail ("line %d: length error in conversion from ucs16 to utf8\n", line); + return; + } + + if (!(ucs4_result = g_utf16_to_ucs4 (utf16_from_ucs4, -1, &items_read, &items_written, &error))) + { + fail ("line %d: conversion back to utf8/ucs4 failed\n", line); + return; + } + + if (items_read != utf16_count (utf16_from_utf8) || + items_written != ucs4_len) + { + fail ("line %d: length error in conversion from ucs16 to ucs4\n", line); + return; + } + + if (strcmp (utf8, utf8_result) != 0 || + !ucs4_equal (ucs4, ucs4_result)) + { + fail ("line %d: conversion back to utf8/ucs4 did not match original\n", line); + return; + } + + g_free (utf16_expected_tmp); + g_free (utf16_expected); + g_free (utf16_from_utf8); + g_free (utf16_from_ucs4); + g_free (utf8_result); + g_free (ucs4_result); + } +} + +int +main (int argc, char **argv) +{ + gchar *testfile; + gchar *contents; + GError *error = NULL; + gchar *p, *end; + char *tmp; + gint state = 0; + gint line = 1; + gint start_line = 0; /* Quiet GCC */ + gchar *utf8 = NULL; /* Quiet GCC */ + GArray *ucs4; + Status status = VALID; /* Quiet GCC */ + + g_test_init (&argc, &argv, NULL); + + testfile = g_test_build_filename (G_TEST_DIST, "utf8.txt", NULL); + + g_file_get_contents (testfile, &contents, NULL, &error); + if (error) + croak ("Cannot open utf8.txt: %s", error->message); + + ucs4 = g_array_new (TRUE, FALSE, sizeof(gunichar)); + + p = contents; + + /* Loop over lines */ + while (*p) + { + while (*p && (*p == ' ' || *p == '\t')) + p++; + + end = p; + while (*end && (*end != '\r' && *end != '\n')) + end++; + + if (!*p || *p == '#' || *p == '\r' || *p == '\n') + goto next_line; + + tmp = g_strstrip (g_strndup (p, end - p)); + + switch (state) + { + case 0: + /* UTF-8 string */ + start_line = line; + utf8 = tmp; + tmp = NULL; + break; + + case 1: + /* Status */ + if (!strcmp (tmp, "VALID")) + status = VALID; + else if (!strcmp (tmp, "INCOMPLETE")) + status = INCOMPLETE; + else if (!strcmp (tmp, "NOTUNICODE")) + status = NOTUNICODE; + else if (!strcmp (tmp, "OVERLONG")) + status = OVERLONG; + else if (!strcmp (tmp, "MALFORMED")) + status = MALFORMED; + else + croak ("Invalid status on line %d\n", line); + + if (status != VALID && status != NOTUNICODE) + state++; /* No UCS-4 data */ + + break; + + case 2: + /* UCS-4 version */ + + p = strtok (tmp, " \t"); + while (p) + { + gchar *endptr; + + gunichar ch = strtoul (p, &endptr, 16); + if (*endptr != '\0') + croak ("Invalid UCS-4 character on line %d\n", line); + + g_array_append_val (ucs4, ch); + + p = strtok (NULL, " \t"); + } + + break; + } + + g_free (tmp); + state = (state + 1) % 3; + + if (state == 0) + { + process (start_line, utf8, status, (gunichar *)ucs4->data, ucs4->len); + g_array_set_size (ucs4, 0); + g_free (utf8); + } + + next_line: + p = end; + if (*p && *p == '\r') + p++; + if (*p && *p == '\n') + p++; + + line++; + } + + g_free (testfile); + g_array_free (ucs4, TRUE); + g_free (contents); + return exit_status; +} diff --git a/tests/unicode-normalize.c b/tests/unicode-normalize.c new file mode 100644 index 0000000..9679e25 --- /dev/null +++ b/tests/unicode-normalize.c @@ -0,0 +1,210 @@ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include +#include +#include + +gboolean success = TRUE; + +static char * +decode (const gchar *input) +{ + unsigned ch; + int offset = 0; + GString *result = g_string_new (NULL); + + do + { + if (sscanf (input + offset, "%x", &ch) != 1) + { + fprintf (stderr, "Error parsing character string %s\n", input); + exit (1); + } + + g_string_append_unichar (result, ch); + + while (input[offset] && input[offset] != ' ') + offset++; + while (input[offset] && input[offset] == ' ') + offset++; + } + while (input[offset]); + + return g_string_free (result, FALSE); +} + +const char *names[4] = { + "NFD", + "NFC", + "NFKD", + "NFKC" +}; + +static char * +encode (const gchar *input) +{ + GString *result = g_string_new(NULL); + + const gchar *p = input; + while (*p) + { + gunichar c = g_utf8_get_char (p); + g_string_append_printf (result, "%04X ", c); + p = g_utf8_next_char(p); + } + + return g_string_free (result, FALSE); +} + +static void +test_form (int line, + GNormalizeMode mode, + gboolean do_compat, + int expected, + char **c, + char **raw) +{ + int i; + + gboolean mode_is_compat = (mode == G_NORMALIZE_NFKC || + mode == G_NORMALIZE_NFKD); + + if (mode_is_compat || !do_compat) + { + for (i = 0; i < 3; i++) + { + char *result = g_utf8_normalize (c[i], -1, mode); + if (strcmp (result, c[expected]) != 0) + { + char *result_raw = encode(result); + fprintf (stderr, "\nFailure: %d/%d: %s\n", line, i + 1, raw[5]); + fprintf (stderr, " g_utf8_normalize (%s, %s) != %s but %s\n", + raw[i], names[mode], raw[expected], result_raw); + g_free (result_raw); + success = FALSE; + } + + g_free (result); + } + } + if (mode_is_compat || do_compat) + { + for (i = 3; i < 5; i++) + { + char *result = g_utf8_normalize (c[i], -1, mode); + if (strcmp (result, c[expected]) != 0) + { + char *result_raw = encode(result); + fprintf (stderr, "\nFailure: %d/%d: %s\n", line, i, raw[5]); + fprintf (stderr, " g_utf8_normalize (%s, %s) != %s but %s\n", + raw[i], names[mode], raw[expected], result_raw); + g_free (result_raw); + success = FALSE; + } + + g_free (result); + } + } +} + +static gboolean +process_one (int line, gchar **columns) +{ + char *c[5]; + int i; + gboolean skip = FALSE; + + for (i=0; i < 5; i++) + { + c[i] = decode(columns[i]); + if (!c[i]) + skip = TRUE; + } + + if (!skip) + { + test_form (line, G_NORMALIZE_NFD, FALSE, 2, c, columns); + test_form (line, G_NORMALIZE_NFD, TRUE, 4, c, columns); + test_form (line, G_NORMALIZE_NFC, FALSE, 1, c, columns); + test_form (line, G_NORMALIZE_NFC, TRUE, 3, c, columns); + test_form (line, G_NORMALIZE_NFKD, TRUE, 4, c, columns); + test_form (line, G_NORMALIZE_NFKC, TRUE, 3, c, columns); + } + + for (i=0; i < 5; i++) + g_free (c[i]); + + return TRUE; +} + +int main (int argc, char **argv) +{ + GIOChannel *in; + GError *error = NULL; + GString *buffer = g_string_new (NULL); + int line_to_do = 0; + int line = 1; + + if (argc != 2 && argc != 3) + { + fprintf (stderr, "Usage: unicode-normalize NormalizationTest.txt LINE\n"); + return 1; + } + + if (argc == 3) + line_to_do = atoi(argv[2]); + + in = g_io_channel_new_file (argv[1], "r", &error); + if (!in) + { + fprintf (stderr, "Cannot open %s: %s\n", argv[1], error->message); + return 1; + } + + while (TRUE) + { + gsize term_pos; + gchar **columns; + + if (g_io_channel_read_line_string (in, buffer, &term_pos, &error) != G_IO_STATUS_NORMAL) + break; + + if (line_to_do && line != line_to_do) + goto next; + + buffer->str[term_pos] = '\0'; + + if (buffer->str[0] == '#') /* Comment */ + goto next; + if (buffer->str[0] == '@') /* Part */ + { + fprintf (stderr, "\nProcessing %s\n", buffer->str + 1); + goto next; + } + + columns = g_strsplit (buffer->str, ";", -1); + if (!columns[0]) + goto next; + + if (!process_one (line, columns)) + return 1; + g_strfreev (columns); + + next: + g_string_truncate (buffer, 0); + line++; + } + + if (error) + { + fprintf (stderr, "Error reading test file, %s\n", error->message); + return 1; + } + + g_io_channel_unref (in); + g_string_free (buffer, TRUE); + + return !success; +} diff --git a/tests/utf8.txt b/tests/utf8.txt new file mode 100644 index 0000000..194d1b5 --- /dev/null +++ b/tests/utf8.txt @@ -0,0 +1,291 @@ +# This file is derived from +# +# http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt +# +# Which was created by Markus Kuhn - 2000-09-02 +# +# lines begining with # and blank lines are ignored +# +# Beyond that, this file consists of a series of test cases. Each test case consists of +# 2 or 3 lines: +# +# 1. A UTF-8 string +# 2. A status +# VALID : The string is a valid UTF-8 representation of valid Unicode +# INCOMPLETE : The string has a partial character at the end +# NOTUNICODE : The string is valid UTF-8, but the characters represented +# are not valid unicode ( +# OVERLONG : The string includes overlong sequences +# MALFORMED : The string is not valid UTF-8 +# 3. If the status is VALID or NOTUNICODE, the UCS-4 representation of the string, +# as a series of hex numbers. + +# 1 Some correct UTF-8 text +κόσμε +VALID +03ba 1f79 03c3 03bc 03b5 + +# 2.1 First possible sequence of a certain length +# +# FIXME - handle NULLS? +# +# [ NULL BYTE ] +#VALID +#0000 + +€ +VALID +0080 + +à € +VALID +0800 + +ð€€ +VALID +00010000 + +øˆ€€€ +NOTUNICODE +00200000 + +ü„€€€€ +NOTUNICODE +04000000 + + +VALID +0000007f + +ß¿ +VALID +000007ff + +ï¿¿ +VALID +0000ffff + +÷¿¿¿ +NOTUNICODE +001fffff + +û¿¿¿¿ +NOTUNICODE +03ffffff + +ý¿¿¿¿¿ +NOTUNICODE +7fffffff + +# 2.3 Other boundary conditions + +퟿ +VALID +d7ff + + +VALID +e000 + +� +VALID +fffd + +ô¿½ +VALID +0010fffd + +ô¿¿ +VALID +0010ffff + +ô€€ +NOTUNICODE +00110000 + +# 3.1 Unexpected continuation bytes + +€ +MALFORMED +¿ +MALFORMED +€¿ +MALFORMED +€¿€ +MALFORMED +€¿€¿ +MALFORMED +€¿€¿€ +MALFORMED +€¿€¿€¿ +MALFORMED +€¿€¿€¿€ +MALFORMED +€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ +MALFORMED + +# 3.2 Lonely start characters + +À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß +MALFORMED +à á â ã ä å æ ç è é ê ë ì í î ï +MALFORMED +ð ñ ò ó ô õ ö ÷ +MALFORMED +ø ù ú û +MALFORMED +ü ý +MALFORMED + +# 3.3 Sequences with last continuation byte missing + +À +INCOMPLETE +à€ +INCOMPLETE +ð€€ +INCOMPLETE +ø€€€ +INCOMPLETE +ü€€€€ +INCOMPLETE +ß +INCOMPLETE +ï¿ +INCOMPLETE +÷¿¿ +INCOMPLETE +û¿¿¿ +INCOMPLETE +ý¿¿¿¿ +INCOMPLETE + +# 3.4 Concatenation of incomplete sequences + +Àà€ð€€ø€€€ü€€€€ßï¿÷¿¿û¿¿¿ý¿¿¿¿ +MALFORMED + +# 3.5 Impossible bytes + +þ +MALFORMED +ÿ +MALFORMED +þþÿÿ +MALFORMED + +# Examples of an overlong ASCII character + +À¯ +OVERLONG +à€¯ +OVERLONG +ð€€¯ +OVERLONG +ø€€€¯ +OVERLONG +ü€€€€¯ +OVERLONG + +# Maximum overlong sequences + +Á¿ +OVERLONG +àŸ¿ +OVERLONG +ð¿¿ +OVERLONG +ø‡¿¿¿ +OVERLONG +üƒ¿¿¿¿ +OVERLONG + +# Overlong representation of the NUL character + +À€ +OVERLONG +à€€ +OVERLONG +ð€€€ +OVERLONG +ø€€€€ +OVERLONG +ü€€€€€ +OVERLONG + +# Illegal code positions + +# Single UTF-16 surrogates + +í € +NOTUNICODE +d800 + +í­¿ +NOTUNICODE +db7f + +í®€ +NOTUNICODE +db80 + +í¯¿ +NOTUNICODE +dbff + +í°€ +NOTUNICODE +dc00 + +í¾€ +NOTUNICODE +df80 + +í¿¿ +NOTUNICODE +dfff + +# Paired UTF-16 surrogates + +𐀀 +NOTUNICODE +d800 dc00 + +𐏿 +NOTUNICODE +d800 dfff + +í­¿í°€ +NOTUNICODE +db7f dc00 + +í­¿í¿¿ +NOTUNICODE +db7f dfff + +󰀀 +NOTUNICODE +db80 dc00 + +󰏿 +NOTUNICODE +db80 dfff + +􏰀 +NOTUNICODE +dbff dc00 + +􏿿 +NOTUNICODE +dbff dfff + +################ +# +# Some more tests, not from Markus Kuhn's file +# + +# Mixed plane 0 and higher planes + +Að€€Bô¿½C +VALID +41 00010000 42 10fffd 43 From 0140d3c4f1b08a63cb7971dc222e90e79e5d1af9 Mon Sep 17 00:00:00 2001 From: Marc Deslauriers Date: Thu, 8 Jun 2023 10:15:59 -0400 Subject: [PATCH 2/5] Import Debian changes 2.72.4-0ubuntu2.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit glib2.0 (2.72.4-0ubuntu2.2) jammy-security; urgency=medium . * SECURITY UPDATE: multiple GVariant security issues - debian/patches/gvariant-security-*.patch: backported upstream fixes for GVariant normalization issues. - CVE-2023-24593, CVE-2023-29499, CVE-2023-25180, CVE-2023-32611, CVE-2023-32636, CVE-2023-32643, CVE-2023-32665 . glib2.0 (2.72.4-0ubuntu2) jammy; urgency=medium . * d/p/0001-gio-Make-portal-support-aware-of-snaps.patch: - Make portal support aware of snaps (LP: #1998267) . glib2.0 (2.72.4-0ubuntu1) jammy; urgency=medium . * New upstream release (LP: #1980408) * Update testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch for new testfilemonitor test. . glib2.0 (2.72.1-1) unstable; urgency=medium . [ Jeremy Bicha ] * New upstream release (LP: #1969115) - Includes workaround for meson #1008382 * Add patch to recognize GNOME Console as a terminal app * Refresh patch * debian/libglib2.0-0.symbols: Add new symbol . [ Johannes Schauer Marin Rodrigues ] * debian/libglib2.0-0.postinst.in: only run clean-up-unmanaged-libraries on upgrades and not on new installations (Closes: #1008096) . glib2.0 (2.72.0-1) unstable; urgency=medium . * New upstream release - Fix assertion failure with time zone offsets >= 25 hours (Closes: #1007226) - Various unit test fixes - Fix a memory leak with an invalid format in g_vasprintf() - Translation updates * Merge 2.71.x release history from experimental - d/gbp.conf, d/control.in: Update branch for upload to unstable * Upload to unstable . glib2.0 (2.70.5-1) unstable; urgency=medium . * New upstream release - Fix assertion failure with time zone offsets >= 25 hours (Closes: #1007226) - Fix possible buffer overflow in g_canonicalize_filename() . glib2.0 (2.70.4-1) unstable; urgency=medium . * New upstream release * Adjust Lintian overrides for newer Lintian . glib2.0 (2.71.3-1) experimental; urgency=medium . * New upstream development release . glib2.0 (2.71.2-1) experimental; urgency=medium . * New upstream development release * Update symbols file. Ignore removal of g_debug_controller_dup_default, which was only added during this development cycle. GLib doesn't guarantee ABI stability within x.odd.z branches. * d/p/debian/tests-Skip-debugcontroller-test.patch: Add patch to skip another unreliable unit test while it's investigated upstream . glib2.0 (2.71.1-1) experimental; urgency=medium . * New upstream development release * Merge packaging changes from unstable - Use debhelper 13 features instead of dh-exec * Update symbols file . glib2.0 (2.70.3-1) unstable; urgency=medium . * New upstream release - Do not allow empty structs (tuples) in D-Bus messages, resolving a denial-of-service vulnerability for private GDBus servers that accept messages from untrusted clients (glib#2557) - Do not allow deep recursion in serialized GVariant binary data, resolving a denial of service for anything that loads untrusted GVariant binary data (glib#2572) - Fix file descriptor handling when launching subprocesses - Don't skip fsync when writing out files on btrfs. This was based on a kernel behaviour that was guaranteed prior to 2014, but is no longer considered to be a guarantee. - Translation updates * Use debhelper 13 features instead of dh-exec debhelper now has ${DEB_HOST_MULTIARCH} substitutions, so we don't need to use dh-exec for those. After that, the one remaining dh-exec feature in use was a conditional installation for the FAM GIO module for Hurd. Open-code this in d/rules instead. * d/gbp.conf: Use upstream/2.70.x branch for packaging. We have already had a 2.71.x release. . glib2.0 (2.71.0-2) experimental; urgency=medium . * Merge packaging updates from unstable . glib2.0 (2.70.2-1) unstable; urgency=medium . * New upstream release * Build-Depend on dh-sequence-gnome and dh-sequence-python3 * debian/rules: Drop environment variable clearing now done for us by dh13 . glib2.0 (2.71.0-1) experimental; urgency=medium . * New upstream development release * Unfuzz patch series * Update symbols file . glib2.0 (2.70.1-1) unstable; urgency=medium . * New upstream release - Functionally equivalent to previous releases to Debian, except for Windows-specific changes * Drop patches that came from upstream * d/upstream/metadata: Add * Use debhelper compat level 13 - Drop override for dh_missing --fail-missing, which is now the default . glib2.0 (2.70.0-3) unstable; urgency=medium . * d/rules: Remove internal_pcre build option, which no longer exists. Meson 0.60.0 no longer tolerates this. . glib2.0 (2.70.0-2) unstable; urgency=medium . * d/patches: Update to upstream glib-2-70 branch commit 2.70.0-41-g359a837ee. Among other fixes, this makes sure we receive change-notification from NetworkManager (>= 1.31.5), which dropped its legacy PropertiesChanged signal in favour of using standard D-Bus Properties. (LP: #1946196) * Add Breaks on older versions of glib-networking-tests. With this GLib, the old way glib-networking's tests used to mock up a particular negotiated protocol no longer works. * Add Breaks on versions of gnome-keyring that had elevated capabilities. Security hardening in GLib 2.70.0 interferes with their ability to connect to D-Bus in some system configurations. (See #994961) * Remove vestigial triggers for /usr/lib/gio/modules. We no longer load files from that directory (since Debian 11 and Ubuntu 20.04), but we still had a trigger for it, and the postinst still created a module cache if it existed. * d/libglib2.0-0.postinst.in: Clean up /usr/lib/gio/modules on upgrade. This directory would still exist if older versions of GLib created a cache there. * d/libglib2.0-0.postinst.in: Add comments indicating when other workarounds can be removed * Add Lintian override for a unit test depending on a private library * Skip memory-monitor-dbus test by default, and add extra debug info. Helps: #995178 . glib2.0 (2.70.0-1) unstable; urgency=medium . * New upstream release * d/rules: Make shared objects in installed-tests non-executable * Remove shebang from taptestrunner.py differently - Remove shebang from installed file using sed. This avoids missing the fact that there are two copies in the source, of which we only patched one. - d/p/debian/taptestrunner-Stop-looking-like-an-executable-script.patch: Drop, no longer necessary * Add Lintian override for #970275 * d/copyright, d/libglib2.0-0.symbols: Update * d/gbp.conf: Switch upstream branch * Unfuzz patch series * Standards-Version: 4.6.0 (no changes required) . glib2.0 (2.68.4-1) unstable; urgency=medium . * New upstream release - Avoid a deadlock while finalizing a GLocalFileMonitor - Correctly use 3 parameters for close_range(), fixing build with glibc 2.34 - Fix global trash directory detection - Make g_string_replace() with empty search string behave sensibly (matching Python str.replace()) - Translation updates: oc, zh_CN, zh_TW * tests: Specify charset for generated locales to fix FTBFS with new glibc. glibc 2.31-14 dropped support for all non-UTF-8 locales, so we can't use /usr/share/i18n/SUPPORTED to choose a suitable charset any more. * d/rules: Override dh_fixperms to set correct permissions on /usr/libexec. Making everything executable is not quite right for installed-tests. . glib2.0 (2.68.3-2) unstable; urgency=medium . * Merge from experimental branch * Changes relative to 2.68.3-1 in experimental: - d/watch: Only watch for stable (2.even.z) releases - d/p/debian/61_glib-compile-binaries-path.patch: Remove. This patch turns out to be unnecessary, and is harmful for cross-compiling. Thanks to Helmut Grohne (Closes: #982213) * Changes relative to previous version in unstable: - New upstream stable release branch 2.68.x - Fix maintainer scripts' handling of /usr/lib/MULTIARCH/gio/modules (Closes: #987913, see 2.68.1-2 changelog) - Mark dbus as . Several of the installed-tests won't be built unless dbus-daemon is available, so is insufficient. - Move test-dependencies to Build-Depends-Arch. We don't run the majority of the tests when we're only building the documentation. - Remove an unused Lintian override - Add more Lintian overrides for test data - Use d/tests/run-with-locales for better locale-sensitive test coverage * d/rules: Fix dead link when documenting why we use -Wl,--no-as-needed * Bump minimum GLib version for callers of g_dbus_server_new_sync() Programs that call this function might be passing in the new flag G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER, which is security-significant. Don't allow such programs to be built against GLib 2.68 and run with GLib 2.66 or older. * Add Breaks on libsoup2.4-tests before 2.72.0-3. Older versions of the libsoup test suite had an assertion that would only succeed because of a GLib bug, which is fixed in 2.68.x. Newer versions tolerate the bug, but do not require it. . glib2.0 (2.68.3-1) experimental; urgency=medium . * New upstream release 2.68.3, fixing bugs: - GFile: `g_file_replace_contents()` reports `G_IO_ERROR_WRONG_ETAG` when saving from a symlink - glocalfileoutputstream: Fix ETag check when replacing through a symlink - gmacros: check that __cplusplus or _MSC_VER is defined - gmacros: missing check if __STDC_VERSION__ is defined - gthreadedresolver: don't ignore flags in lookup_by_name_with_flags - inotify: Fix a memory leak - json-glib does not build with glib 2.68.1 - testfilemonitor test leaks ip_watched_file_t struct - tlscertificate: Avoid possible invalid read . glib2.0 (2.68.1-2) experimental; urgency=medium . * Fix maintainer scripts' handling of /usr/lib/MULTIARCH/gio/modules: - postrm: Only delete GIO module cache on remove or purge. Despite its name, the postrm can be invoked for reasons other than package removal: in particular, the old version's postrm is run during upgrades. - postinst: Recreate GIO module directory if deleted by an older postrm, to recover from the bug fixed here. - postinst: Don't guard glib-compile-schemas or gio-querymodules with a check for existence of a directory that is shipped in the .deb. If such a directory has somehow gone missing, we want to see a warning. This won't make the postinst fail, because we're ignoring exit status anyway. (Closes: #987913) . glib2.0 (2.68.1-1) experimental; urgency=medium . * New upstream stable release * d/tests/run-with-locales: Avoid FTBFS with locales-all installed . glib2.0 (2.68.0-1) experimental; urgency=medium . * New upstream stable release - Drop dead code from glib-compile-schemas - Improve valgrind suppressions - Fix error in g_bytes_icon_new() documentation - Avoid close(-1) during error handling - Fix copy/paste error in queue test - Translation updates * Add CVE ID references to previous changelog entries. CVE IDs were not yet available at the time these vulnerabilities were initially fixed. . glib2.0 (2.67.6-1) experimental; urgency=medium . * New upstream release - This fixes a symlink attack affecting file-roller. When g_file_replace() is used with G_FILE_CREATE_REPLACE_DESTINATION to replace a path that is a dangling symlink, previously it would have also created the target of the symlink as an empty file, which could conceivably be security-sensitive if the symlink is attacker-controlled. (Closes: #984969; CVE-2021-28153) * Revert test-dependency on libc6-dev, which should no longer be necessary with the new upstream release. . glib2.0 (2.67.5-2) experimental; urgency=medium . * debian/tests/control: Test-Depend on libc6-dev; the `pollable` test requires it. See [upstream MR !1977][0]. The upstream tests now rely on finding "libutil.so", which is in libc6-dev. Once that MR, or something like it, is merged, we can remove this test-dep as the runtime library will be being used. [0]: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1977 . glib2.0 (2.67.5-1) experimental; urgency=medium . * New upstream release + Fix more issues with `glib_typeof` macro from 2.67.3–2.67.4 (LP: #1916705) + Fix regression with some FD mappings passed to `g_subprocess_launcher_spawnv()` (Closes: #983026) (LP: #1916701) * debian/watch: Fix to not match `..`. The watch file was matching the "Parent directory/" link and considering that the highest, since its target is `..`. Expect 1+ digits to begin the version number. . glib2.0 (2.67.4-1) experimental; urgency=medium . * New upstream release - Among other changes, this should fix FTBFS on armel * d/libglib2.0-0.symbols: Add g_spawn_async_with_pipes_and_fds . glib2.0 (2.67.3+git20210214-1) experimental; urgency=medium . * d/changelog: Add bug reference for GHSL-2021-045 to previous entry * New upstream git snapshot; among other changes: - Fix regressions caused by the GHSL-2021-045 fixes in 2.67.3 - Warn and fail on integer overflow in g_byte_array_new_take() for arrays larger than G_MAXUINT (Closes: #982779; CVE-2021-27218) * d/libglib2.0-0.symbols: Add g_string_replace() * Refresh patch series * d/rules, d/tests: Generate various locales mentioned in the tests * Mark dbus as . Several of the installed-tests won't be built unless dbus-daemon is available, so is insufficient. * Move test-dependencies to Build-Depends-Arch. We don't run the majority of the tests when we're only building the documentation. * Remove an unused Lintian override * Add more Lintian overrides for test data . glib2.0 (2.67.3-1) experimental; urgency=medium . * New upstream release - Fix various integer overflows, some of them potentially exploitable (Closes: #982778; CVE-2021-27219, GHSL-2021-045) * Drop patches that came from upstream or were applied upstream . glib2.0 (2.67.2-1) experimental; urgency=medium . * New upstream release * Refresh patch series * d/patches: Cherry-pick some fixes from upstream git master. This is mostly for parity with the update to 2.66.x that I'm preparing for unstable, which also includes the XDG_CURRENT_DESKTOP fixes. * d/p/spawn-Don-t-set-a-search-path-if-we-don-t-want-to-search-.patch: Make the g_spawn family only search PATH if G_SPAWN_SEARCH_PATH is used. Previously, they would sometimes search /usr/bin:/bin:. for an executable they should have only loaded from the current working directory. In particular, this made gtk+3.0 fail its build-time tests if ImageMagick display(1) happened to be installed. (Closes: #977961) . glib2.0 (2.67.1-1) experimental; urgency=medium . * Branch for experimental and 2.67.x * New upstream development release * Temporarily use git to fetch upstream release. The official tarball release doesn't seem to have made it onto mirrors. * d/rules: Explicitly enable libelf dependency for gresource tool * d/p/Handle-the-case-of-g_object_run_dispose-in-GBinding.patch: Add patch from upstream to fix a regression in GBinding that caused gnome-terminal-server to crash on startup . glib2.0 (2.66.8-1) unstable; urgency=medium . * d/watch: Only watch for 2.66.x versions. 2.68.0 has been released but will not be in bullseye. * New upstream release - Functionally equivalent to 2.66.7-2, except for the version number and a change to Windows-specific code that is not used in Debian * Drop patches that were included in the new upstream release * d/p/glocalfileoutputstream-Tidy-up-error-handling.patch: Add patch from upstream to clean up error handling. After the fix for #984969, this function could end up calling close(-1), which is harmless but gets flagged as an error by static analysis and by error-checking instrumentation. Fixing this will prevent it from obscuring real errors. * Add CVE references in recent changelog entries. CVE IDs for the vulnerabilities were not available at the time they were fixed, but now they are. . glib2.0 (2.66.7-2) unstable; urgency=medium . * d/changelog: Add bug numbers for integer overflows in previous versions * Add patches to fix a symlink attack affecting file-roller. When g_file_replace() is used with G_FILE_CREATE_REPLACE_DESTINATION to replace a path that is a dangling symlink, previously it would have also created the target of the symlink as an empty file, which could conceivably be security-sensitive if the symlink is attacker-controlled. (Closes: #984969; CVE-2021-28153) . glib2.0 (2.66.7-1) unstable; urgency=high . * New upstream release - Fix another regression caused by the GHSL-2021-045 fixes in 2.66.6 - Warn and fail on integer overflow in g_byte_array_new_take() for arrays larger than G_MAXUINT (Closes: #982779; CVE-2021-27218) - Disallow using currently-undefined D-Bus connection or server flags, to prevent forward-compatibility problems with new security-sensitive flags that are likely to be introduced in GLib 2.68 * Drop previous patches for GHSL-2021-045 regressions, applied upstream . glib2.0 (2.66.6-2) unstable; urgency=high . * d/patches: Add proposed fixes for regressions in 2.66.6. Two functions that took either a positive length, or -1 to indicate strlen(), had assertions with the wrong sense in 2.66.6, causing some valid uses of those functions to regress. * d/p/debian/61_glib-compile-binaries-path.patch: Remove. This patch turns out to be unnecessary, and is harmful for cross-compiling. Thanks to Helmut Grohne (Closes: #982213) * Set high urgency to get the regression fixes into bullseye . glib2.0 (2.66.6-1) unstable; urgency=high . * New upstream release - Fix various integer overflows, some of them potentially exploitable (Closes: #982778; CVE-2021-27219, GHSL-2021-045) . glib2.0 (2.66.5-1) unstable; urgency=medium . * New upstream release, equivalent to 2.66.4-27-g0051c0635 * Drop patches that were applied upstream . glib2.0 (2.66.4-4) unstable; urgency=medium . * d/patches: Update patch series to upstream commit 2.66.4-27-g0051c0635 - Improve test coverage for #977961 - Stop valgrind reporting memory leaks in GSpawn in most cases - Partially revert security hardening from 2.66.4-2: allow DBUS_SESSION_BUS_ADDRESS to be taken from the environment by setcap executables (to avoid regressing gnome-keyring) and by setgid executables (to avoid regressing msmtp). (Closes: #981420, #981555) Note that this is likely to be reverted in GLib 2.70.x to provide better hardening. The D-Bus session bus is not designed to be used by processes that have elevated privileges. . glib2.0 (2.66.4-3) unstable; urgency=medium . * Improve patch for #977961, and add basic test coverage . glib2.0 (2.66.4-2) unstable; urgency=medium . * d/patches: Update patch series to upstream commit 2.66.4-18-g872181c4f (excluding Windows-specific changes) - Security hardening: in GIO, ignore various environment variables if GIO is (inadvisably) used in a setuid process without sanitizing the environment first, similar to CVE-2012-3524 - Reject very long date strings early, instead of spending time normalizing and parsing them - Fix recursion in GPrivate * d/p/spawn-Don-t-set-a-search-path-if-we-don-t-want-to-search-.patch: Make the g_spawn family only search PATH if G_SPAWN_SEARCH_PATH is used. Previously, they would sometimes search /usr/bin:/bin:. for an executable they should have only loaded from the current working directory. In particular, this made gtk+3.0 fail its build-time tests if ImageMagick display(1) happened to be installed. (Closes: #977961) . glib2.0 (2.66.4-1) unstable; urgency=medium . * New upstream release . glib2.0 (2.66.3-2) unstable; urgency=medium . * Apply packaging changes from experimental to unstable: - postinst: Clean up outdated copies of GLib if present, to avoid infrequent upgrade issues on non-merged-/usr systems. See #911225 and #949395 for more information. (Closes: #896019, #954960, #955331) * Add myself to Uploaders * Standards-Version: 4.5.1 (no changes required) * Swap Homepage field to something more GLib-specific * d/gbp.conf: Change upstream branch to upstream/2.66.x. 2.67.0 was already released, so it's inaccurate to say that 2.66.x is the latest. . glib2.0 (2.66.3-1+exp1) experimental; urgency=medium . * Merge from unstable . glib2.0 (2.66.3-1) unstable; urgency=medium . * Team upload * New upstream release - Improve performance of processing files hidden via ./.hidden - All other changes were already included in 2.66.2-1 * Drop patches that were cherry-picked from upstream * Stop reverting gtk-doc dependency version. We now have a suitable gtk-doc in Debian. * Drop a patch that was not applied upstream. This was hoped to be a workaround for intermittent test failures, but doesn't seem to have had the desired effect in practice. * Mark the DBUS_COOKIE_SHA1 parts of gdbus-server-auth test as flaky. This is not reliable enough to always pass on buildds, but is too intermittent to be able to reproduce the failure in a development environment, and DBUS_COOKIE_SHA1 is not an important enough feature to justify failing the build for this. As with other flaky tests, we still run this as an autopkgtest in an attempt to get more useful information, but we ignore failure. . glib2.0 (2.66.2-1+exp1) experimental; urgency=medium . * Branch for experimental * postinst: Clean up outdated copies of GLib to avoid infrequent upgrade issues on non-merged-/usr systems (Closes: #896019, #954960, #955331) . glib2.0 (2.66.2-1) unstable; urgency=medium . * Team upload * New upstream release - Add some missing (nullable) and (not nullable) annotations * Drop patches that were cherry-picked from upstream * Update patch series to upstream 2.66.2-9-g4daaf303a - Fix race in socketclient-slow test - Cope with sending fds in a D-Bus message that takes multiple writes - Don't skip updating polled fd sources - Add G_GNUC_PRINTF annotation to g_trace_mark() * d/p/glib-tests-fileutils-Make-more-use-of-g_assert_no_errno.patch, d/p/glib-tests-fileutils-Fix-expectations-when-running-as-roo.patch: Add proposed patch to fix a test failure when running as root (Closes: #973271) * d/rules: Remove migration path from legacy -dbg package. This was most recently shipped in Debian 9, and we don't support upgrades from anything older than Debian 10. * Drop obsolete workaround for #887629. We don't support upgrades from versions older than Debian 10, so we can drop workarounds that were only relevant for the upgrade from 9 to 10. . glib2.0 (2.66.1-2) unstable; urgency=medium . * Cherry-pick patches from the glib-2-66 branch upstream - Fixes the regression called out in 2.66.1-1's changelog. * Add-a-test-for-the-6-days-until-EOM-bug.patch, Fix-the-6-days-until-the-end-of-the-month-bug.patch: Cherry-pick upstream mr!1705 to not break on timezones built with `zic -b slim` . glib2.0 (2.66.1-1) unstable; urgency=medium . * Team upload * New upstream release - A performance problem where timezones were reloaded from disk every time a GTimeZone was created has been fixed (upstream issue #2204), but this means that changes to /etc/localtime will not take effect until a process restarts. Future changes in a subsequent 2.66.x release will improve this. - Security fix for incorrect scope/zone ID parsing in URIs - Fix invalid Pointer Arithmetic in g_path_get_basename - Fix cookie lifetimes in GDBus DBUS_COOKIE_SHA1 mechanism - Fix faulty logic in DNS TXT record parsing - trash portal: Handle portal failures - gio-tool-trash: Prevent recursion to speed up emptying trash - glist: Clarify that g_list_free() and friends only free an entire list - gdatetime: Avoid integer overflow creating dates too far in the past - Translation updates * d/p/glocalfile-Never-require-G_LOCAL_FILE_STAT_FIELD_ATIME.patch, d/p/gdbusauthmechanismsha1-Use-the-same-timeouts-as-libdbus.patch: Drop patches that were applied upstream . glib2.0 (2.66.0-2) unstable; urgency=medium . * Team upload * d/p/glocalfile-Never-require-G_LOCAL_FILE_STAT_FIELD_ATIME.patch: Add proposed patch to fix file copying on ZFS and CIFS (Closes: #970228) * d/p/gdbus-server-auth-Don-t-usually-test-non-EXTERNAL-repeate.patch: Add proposed patch to work around DBUS_COOKIE_SHA1 test failures * d/p/Revert-gtk-doc-dependency-to-1.32.patch: Move to debian subdirectory. This patch is not intended to go upstream. . glib2.0 (2.66.0-1) unstable; urgency=medium . * Team upload * New upstream stable release - Fix missing tab in makefile rule - guri: Fix user passed to g_uri_split_with_user() not being NULL'd - Translation updates: * d/watch: Only watch for stable releases * d/p/gdbusauthmechanismsha1-Use-the-same-timeouts-as-libdbus.patch: Add patch to fix intermittent test failures on slower architectures. This narrowly missed the upstream code freeze, and should be in 2.66.1. . glib2.0 (2.65.3-1) experimental; urgency=medium . * New upstream release + Fixes to the new `statx()` calls — note that since GLib 2.65.2 uses `statx()` (if available) instead of `stat()`/`fstat()`/`lstat()`/`fstatat()`, syscall sandboxing for third party applications might need to be updated + Also includes "Fix splice behavior on cancellation", a fix for a bug which was affecting tracker - particularly its autopkgtests. . glib2.0 (2.65.2-1) experimental; urgency=medium . * Team upload * New upstream development release * d/rules: Run gtk-doc checks, even if building indep-only. Previously we would only run the gtk-doc checks if building architecture-dependent and -independent packages in the same build, which is done on Ubuntu amd64 buildds, but not on any Debian buildds. * Reduce dependency to the version of gtk-doc-tools from unstable. Instead of being some random snapshot from upstream git, this is the last release plus some selected patches. In particular, it has enough fixes to make the gtk-doc tests pass (Closes: #968975). * d/libglib2.0-tests.lintian-overrides: Update . glib2.0 (2.65.1-1) experimental; urgency=medium . [ Sebastien Bacher ] * debian/control.in: - let libglib2.0-tests Depends on libglib2.0-0 (= ${binary:Version}), otherwise we can end up with failures due to out of sync versions . [ Simon McVittie ] * d/shlibs.local: Upgrade all binary packages in lockstep. Like many projects where one source package builds multiple binary packages, GLib has private headers that share non-public interfaces between its binary packages. Instead of setting this up for individual binary packages, we can tell dpkg-shlibdeps to generate lockstep dependencies whenever one of our binary packages depends on our shared libraries. * d/watch, d/control.in, d/gbp.conf: Branch for experimental * New upstream development release - Require the experimental version of gtk-doc-tools. GLib 2.65.x requires a version that hasn't been released yet. - Update symbols file - Drop patches that were applied upstream . glib2.0 (2.64.4-1) unstable; urgency=medium . * Team upload * New upstream release - Improve async-signal-safety * d/tests/build: Don't exercise static linking for GIO. libmount will no longer support being linked statically from 2.35.2-8 onwards. For now I'm continuing to test that the other libraries can still be statically linked, but please consider them to be "at risk". (Closes: #963933) * Re-enable libmount support. libmount no longer depends on libcryptsetup, avoiding the various crashes that we are working around. Future versions will dlopen it on-demand, which should also avoid those crashes. Bump the build-dependency to a suitable version. * d/p/tests-Use-g_assert_-in-cancellable-test-rather-than-g_ass.patch, d/p/gcancellable-Fix-minor-race-between-GCancellable-and-GCan.patch: Split combined d/p/git_gsource_segfault.patch into its two component upstream commits, and add metadata * d/p/glib-compile-resources-Fix-exporting-on-Visual-Studio.patch, d/p/gdesktopappinfo-Fix-unnecessarily-copied-and-leaked-URI-l.patch: Add post-release bugfixes from upstream . glib2.0 (2.64.3-2) unstable; urgency=medium . * Team upload * Temporarily disable libmount support. Recent Debian revisions of libmount pull in libcryptsetup as a dependency, for dm-verity support. libcryptsetup depends on json-c and OpenSSL, causing crashes due to symbol conflicts with other JSON libraries (jansson and json-glib, for example in firewalld and virt-manager) and with statically-linked copies of OpenSSL (for example in Steam and Minecraft). Until this is resolved in some other way, disable libmount and parse /etc/fstab and /proc/mounts ourselves, as we do in libglib2.0-udeb. Mitigates: #963933, #963932, #963525, #963721 . glib2.0 (2.64.3-1) unstable; urgency=medium . * Team upload . [ Laurent Bigonville ] * Drop the libgio-fam package, and install the fam GIO plugin in libglib2.0-0 on Hurd ports. See: #885011 (Closes: #875915) * Stop building the libgio-fam package on kFreeBSD ports. It is no longer necessary now that gkqueuefilemonitor is available. . [ Simon McVittie ] * Clarify changelog entry regarding Hurd and kFreeBSD * New upstream stable release . glib2.0 (2.64.2-1) unstable; urgency=medium . [ Simon McVittie ] * Add Breaks on older versions of gimp, which used a syntactically invalid property name in a plugin, and would crash when GObject rejects syntactically invalid property names . [ Sebastien Bacher ] * New upstream release * debian/patches/git_gsource_segfault.patch: - backport an upstream git change to fix a signal handler disconnect segfault situation (lp: #1872153) . glib2.0 (2.64.1-1) unstable; urgency=medium . * Team upload * New upstream stable release * d/p/tests-Skip-MemoryMonitor-test-if-GObject-Introspection-is.patch: Drop patch, applied upstream * Add Breaks on glib-networking-tests older than 2.63.2. Those versions had a test that relied on TLS version fallback behaviour that has now been removed. (Closes: #953766) . glib2.0 (2.64.0-2) unstable; urgency=medium . * Team upload * Merge packaging changes from unstable with new upstream release from experimental * d/control.in: Add Breaks on libgladeui-2-6 before 3.22.2. Older versions used a syntactically invalid property name "support warning", which GObject used to canonicalize to "support-warning". GLib 2.64 made this check more strict (see #953010). . glib2.0 (2.64.0-1) experimental; urgency=medium . * Team upload * New upstream release - Fixes a vulnerability where GSocketClient sometimes forgot to use a configured proxy (CVE-2020-6750, Closes: #948554) - Stop installing gio-launch-desktop, which no longer exists - d/p/docs-Don-t-install-object-manager-example-separately.patch: Drop, applied upstream * d/p/debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch: Treat testfilemonitor as a flaky test * Standards-Version: 4.5.0 (no changes required) * New upstream release * d/p/tests-Skip-MemoryMonitor-test-if-GObject-Introspection-is.patch: Skip MemoryMonitor test if GObject-Introspection is too old to know it * Install a shell script implementation of the old gio-launch-desktop executable. While not required for *this* GLib, it is required by old processes that already had the old GLib (2.57.2 to 2.63.5) in memory before the upgrade. This can be removed after Ubuntu 20.04 and Debian 11 are both released. . glib2.0 (2.63.5-2) experimental; urgency=medium . * Skip-unreliable-gdbus-threading-tests--by-default.patch: Skip all of gdbus-threading test_method_calls_in_thread() has become (more?) unreliable too. When skipped, the test bus doesn't get torn down properly - it times out. Let's stop running these tests for now, until they are made reliable. . glib2.0 (2.63.5-1) experimental; urgency=medium . [ Iain Lane ] * New upstream release . [ Philip Withnall ] * Rework 01_gettext-desktopfiles.patch to not add new public API. Downstreams should not be adding new public API to GLib. From some code searching, this doesn’t appear to be used in more than one or two places, so won’t be too inconvenient to drop. The original patch should either be upstreamed (I’d be open to some form of it, if there’s still evidence it’s useful) or dropped. If it’s upstreamed, the new keys should be standardised. The alternative to this was to document the added public API; its addition was causing the new gtk-doc tests in GLib to fail. * Bump gtk-doc-tools dependency to >= 1.32-4 as GLib requires some fixes pushed to gtk-doc after its 1.32 release. * control: Bump Meson dependency to >= 0.52.0 for building the documentation * Drop PKCS#11 APIs added in 2.63.1 (not stable yet) - g_tls_certificate_new_from_pkcs11_uris() * Remove patches applied upstream: - tests-Skip-GMemoryMonitor-tests-if-the-dbusmock-template-.patch - tests-optional-portal.patch * d/p/docs-Don-t-install-object-manager-example-separately.patch: Add patch from upstream to disable incorrect installation of some example documentation * Rework libmount Meson argument as it’s now a feature; see !1344 upstream . glib2.0 (2.63.3-3) experimental; urgency=medium . * debian/control.in: - lower the libglib2.0-tests Depends on xdg-desktop-portal to a Recommends since the portal is not available on some architectures * debian/patches/tests-optional-portal.patch: - skip the new memory monitor tests if the portal is not available, that allows the tests to be still successful on architectures were the portal is not available (e.g Ubuntu/i386) . glib2.0 (2.63.3-2) experimental; urgency=medium . * debian/control.in: - libglib2.0-tests Depends on xdg-desktop-portal, it's required by the new low memory tests (and got enabled by the new python-dbusmock) . glib2.0 (2.63.3-1) experimental; urgency=medium . [ Iain Lane ] * New upstream release + Add a `--glib-min-version` argument to `gdbus-codegen` which controls breaks in the API of generated code + Add `g_clear_list()` API to clear `GList`s to `NULL` + Add a `GMemoryMonitor` API to be notified of memory pressure situations using the low-memory-monitor project + Add support for dispose functions for `GSource` implementations + Tighten up validation of GObject signal and property names, allowing performance improvements * debian/tests/build: Style fixes, thanks to shellcheck. * d/p/d/Disable-some-tests-on-slow-architectures-which-keep-faili.patch: Rebase. Upstream have disabled these tests by default too (unless slow mode is enabled), so we don't need to add a patch to do a similar thing. * debian/libglib2.0-0.symbols: New symbols for 2.63.3 * d/p/tests-Skip-GMemoryMonitor-tests-if-the-dbusmock-template-.patch: Add. We don't have a new enough dbusmock in Debian at the minute (one is not released yet). Skip the test if the required template isn't available. * control: Add Depends for the new memory-monitor tests. There are new tests, written in python, for GMemoryMonitor. They require dbus-python, pygobject, and the GI bindings for GLib and GIO. . [ Steve Langasek ] * debian/tests/build: Make cross-test friendly autopkgtest is soon to get a `-a ARCHITECTURE` switch, which will cross-test autopkgtests. This is to be detected by the presence of the `dpkg-architecture`-style family of variables being set in the environment. For build tests like `glib2.0`'s `build` test, this means that we should test "${DEB_HOST_ARCH}" and invoke the cross toolchain as necessary. (Closes: #946355) . glib2.0 (2.63.2-1) experimental; urgency=medium . * Team upload * Merge packaging changes from unstable - Support for pkg.glib2.0.noinsttest build profile * d/control.in: Refer to debian/experimental branch. This avoids false-positive warnings from vcswatch. * New upstream release - Drop patches that were applied upstream * Rename pkg.glib2.0.noinsttest build profile to noinsttest. This is now registered on . * Update symbols file . glib2.0 (2.63.1-2) experimental; urgency=medium . * d/p/Revert-glocalfileinfo-Only-return-file-mode-not-type-as-U.patch: Revert "glocalfileinfo: Only return file mode, not type, as UNIX_MODE attribute" This reverts commit bfdc5fc4fc84ef8518d2d1a328c8482cf5a38e98. This commit changes the semantics of the `unix::mode` attribute, which some things (the one we've noticed is ostree) rely on. * d/p/test_copy_preserve_mode-Adjust-for-revert-semantics.patch: test_copy_preserve_mode: Adjust for revert semantics. Now we're returning the file type again, we need to mask it out to compare with the mode. . glib2.0 (2.63.1-1) experimental; urgency=medium . * New upstream release - Add `g_array_steal()`, `g_ptr_array_steal()` and `g_byte_array_steal()` APIs - Add `g_get_os_info()` API - Add `GMainContextPusher` API - Add `g_warning_once()` API - Allow passing empty `GValue`s to `g_param_value_set_default()` - Always resolve `localhost` to loopback address in `GResolver` - Escape header guards generated by `gdbus-codegen` better - Fix crash in `g_spawn()` with high FD numbers due to use of `select()` rather than `poll()` - Limit recursion in `g_variant_parse()` - Several usability improvements to command line `gio` tool * debian/libglib2.0-0.symbols: Add new symbols for this release * debian/patches/*: - Drop backports we had which are in this release. - Update to upstream master at cc1b53f74. There are several test fixes that we might as well grab now. . glib2.0 (2.62.5-1) unstable; urgency=medium . * Team upload * New upstream release - Fixes a vulnerability where GSocketClient sometimes forgot to use a configured proxy (CVE-2020-6750, Closes: #948554) * Build-depend on libnss-myhostname | netbase if running tests. This is an attempt to work around localhost not being a resolvable name in some build environments, notably reproducible-builds. (See #948834) * Put the result of `getent ahosts localhost` and `getent ahosts $(hostname)` in the build log, to check whether those names are resolvable in the build environment. * d/p/debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch: Treat testfilemonitor as a flaky test * Standards-Version: 4.5.0 (no changes required) . glib2.0 (2.62.4-2) unstable; urgency=medium . * Team upload * Adjust dependencies to avoid broken partial upgrades on arm64 during libffi7 transition: - Bump versioned Depends on libffi-dev to get a guarantee that we'll depend on libffi7 - Add Breaks on libgirepository-1.0-1 (<< 1.62.0-4~) so we cannot get a GObject built with libffi7 but a libgirepository built with libffi6 . glib2.0 (2.62.4-1) unstable; urgency=medium . * Team upload . [ Steve Langasek ] * debian/tests/build: Make cross-test friendly (Closes: #946355) . [ Iain Lane ] * debian/tests/build: Style fixes . [ Simon McVittie ] * New upstream release . glib2.0 (2.62.3-2) unstable; urgency=medium . * Team upload * Rename pkg.glib2.0.noinsttest build profile to noinsttest. This is now registered on . . glib2.0 (2.62.3-1) unstable; urgency=medium . * Team upload * New upstream release - Drop patches that were applied upstream * Don't build libglib2.0-tests under pkg.glib2.0.noinsttest build profile. This is a prototype of the proposed standard build profile noinsttest. If the build profiles include both nocheck and pkg.glib2.0.noinsttest, we can drop the libdbus-1-dev build-dependency without harming test coverage or altering the contents of binary packages. * d/gbp.conf: Use upstream/2.62.x branch . glib2.0 (2.62.2-3) unstable; urgency=medium . * Team upload . [ Iain Lane ] * control: Drop `debian/experimental` from Vcs-* . [ Simon McVittie ] * Build-depend on libdbus-1-dev for better test coverage * Update to upstream commit 2.62.2-28-g3cf25070e: - d/p/goption-Relax-assertion-to-avoid-being-broken-by-kdeinit5.patch: Fix assertion failure when called from a process that overwrites its argv, such as kdeinit5 - d/p/gdbus-peer-Specifically-listen-on-127.0.0.1.patch: Improve reliability of gdbus-peer test in some container environments - d/p/gdbusserver-Delete-socket-and-nonce-file-when-stopping-se.patch, d/p/gdbusserver-Keep-a-strong-reference-to-the-server-in-call.patch, d/p/gdbusauthmechanismsha1-Remove-unnecessary-g_warning-calls.patch, d/p/gdbusauthmechanismsha1-Create-.dbus-keyrings-directory-re.patch, d/p/tests-Move-main-loop-and-test-GUID-into-test-functions-in.patch, d/p/tests-Isolate-directories-in-gdbus-peer-test.patch, d/p/gdbus-peer-test-Improve-diagnostics-if-g_rmdir-fails.patch, d/p/gdbus-peer-test-Stop-GDBusServer-before-tearing-down-temp.patch, d/p/gdbus-peer-test-Use-unix-dir-address-if-exact-format-does.patch, d/p/gdbus-server-auth-test-Create-temporary-directory-for-Uni.patch: Mark as applied upstream in 2.62.x branch * d/p/gdbus-server-auth-test-Include-gcredentialsprivate.h.patch: Apply patch from 2.63.x to fix missing coverage in test for #941018 * d/p/Make-ld-executable-configurable.patch: Apply patch from 2.63.x to use cross ld where necessary * d/p/gdbus-server-auth-test-Create-temporary-directory-for-Uni.patch: Mark as applied upstream in 2.63.x branch * Improve patch metadata: use more URLs for bug references . glib2.0 (2.62.2-2) unstable; urgency=medium . * Team upload * Update to upstream commit 2.62.2-14-gfcbb88823: - d/p/gdesktopappinfo-Allocate-DesktopFileDir-structs-dynamical.patch, d/p/gdesktopappinfo-Cancel-file-monitor-when-resetting-a-Desk.patch, d/p/glocalfilemonitor-Keep-a-weak-ref-to-the-monitor-in-GFile.patch: Fix intermittent test failures for GDesktopAppInfo (Closes: #941550) - d/p/gvariant-Limit-recursion-in-g_variant_parse.patch: Ensure that parsing a text-format GVariant does not run out of stack space - d/p/tests-Use-objcopy-from-the-cross-compilation-file-if-conf.patch, d/p/docs-Add-objcopy-to-example-cross-compilation-file.patch: Use the appropriate architecture's objcopy when cross-compiling - d/p/gtestutils-Add-additional-non-NULL-check-in-g_assert_cmpm.patch: Avoid false positive NULL dereference warnings in g_assert_cmpmem() - d/p/gspawn-Port-to-g_poll-from-select.patch: Fix launching subprocesses when a very large number of fds are open - d/p/gcredentialsprivate-Document-the-various-private-macros.patch, d/p/credentials-Invalid-Linux-struct-ucred-means-no-informati.patch, d/p/GDBus-prefer-getsockopt-style-credentials-passing-APIs.patch: Ensure libdbus clients can authenticate with a GDBusServer like the one in ibus (Closes: #941018) * d/p/gdbusserver-Delete-socket-and-nonce-file-when-stopping-se.patch, d/p/gdbusserver-Keep-a-strong-reference-to-the-server-in-call.patch, d/p/Add-a-test-for-GDBusServer-authentication.patch: Backport regression test for #941018 from upstream git master * d/p/gdbusauthmechanismsha1-Remove-unnecessary-g_warning-calls.patch, d/p/gdbusauthmechanismsha1-Create-.dbus-keyrings-directory-re.patch, d/p/tests-Move-main-loop-and-test-GUID-into-test-functions-in.patch, d/p/tests-Isolate-directories-in-gdbus-peer-test.patch: Backport reliability fixes for gdbus-peer test from upstream git master * d/p/gdbus-peer-test-Improve-diagnostics-if-g_rmdir-fails.patch, d/p/gdbus-peer-test-Stop-GDBusServer-before-tearing-down-temp.patch, d/p/gdbus-peer-test-Use-unix-dir-address-if-exact-format-does.patch, d/p/gdbus-server-auth-test-Create-temporary-directory-for-Uni.patch: Add some proposed patches to improve GDBus unit tests * d/p/debian/mimeapps-test-Mark-as-flaky.patch: Drop patch, hopefully no longer needed with #941550 fixed * d/p/debian/taptestrunner-Stop-looking-like-an-executable-script.patch: Make taptestrunner non-executable to avoid a Lintian warning . glib2.0 (2.62.2-1) unstable; urgency=medium . * New upstream release + Fixes use after free when calling g_dbus_connection_flush_sync() in a dedicated thread (LP: #1848202) . glib2.0 (2.62.1-1) unstable; urgency=medium . * Team upload * d/watch: Only watch for even-numbered (stable) releases * New upstream release - Fix regression that made G_FILE_COPY_TARGET_DEFAULT_PERMS result in private permissions rather than respecting umask (Closes: #505398) - d/p/g_file_info_get_modification_date_time-Calculate-in-integ.patch, d/p/Always-build-tests-if-we-enabled-installed-tests.patch: Drop patches that were applied upstream * d/p/debian/mimeapps-test-Mark-as-flaky.patch: Mark mimeapps test as flaky (see #941550) . glib2.0 (2.62.0-3) unstable; urgency=medium . * Team upload * Merge packaging from 2.60.x branch previously in unstable - No changes since 2.62.0-2, except in d/changelog - d/p/debian/Disable-an-optimization-when-building-with-gcc-9.patch: Remove workaround for #931921, which turned out to be a clutter bug * d/p/Always-build-tests-if-we-enabled-installed-tests.patch: Add patch to fix installation of installed-tests in cross-builds (Closes: #941509) * d/p/g_file_info_get_modification_date_time-Calculate-in-integ.patch: Add patch to fix intermittent g-file-info test failures on i386 (Closes: #941547) * libglib2.0-dev: Suggest libgirepository1.0-dev, for the GIR files (Closes: #914152) * d/gbp.conf: Use debian/master branch * Standards-Version: 4.4.1 (no changes required) . glib2.0 (2.60.6-2) unstable; urgency=medium . * Team upload * d/rules: Edit debcrossgen output instead of using a modified version. This fixes use of CFLAGS, etc. during cross-compilation. (Closes: #933560) * Remove obsolete permissions fixing. Issue 1539 was fixed upstream. * d/p/debian/Disable-an-optimization-when-building-with-gcc-9.patch: Disable an optimization when building with gcc-9, instead of forcing gcc-8. This avoids depending on an old gcc, and should be easier to deal with for cross-compilation. (Workaround for #931921) * d/p/gmessages-Only-use-structured-logs-if-GLIB_VERSION_MAX_AL.patch: Update to upstream glib-2-60 branch at commit 2.60.6-2-ga365528f6 - Don't use structured logging if GLIB_VERSION_MAX_ALLOWED < 2.56 . glib2.0 (2.62.0-2) unstable; urgency=medium . * Team upload. * Upload to unstable. (Closes: #940161) . glib2.0 (2.62.0-1) experimental; urgency=medium . * New upstream release + Fix new `GFileInfo` APIs to work when `G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC` was not queried . glib2.0 (2.61.3-1) experimental; urgency=medium . * New upstream release * d/p: Drop cherry-picks from upstream branch which we now have * d/p/d/Disable-an-optimization-when-building-with-gcc-9.patch: Drop, clutter has been fixed now (thanks Simon) * d/p/*: Refresh via gbp-pq as necessary . glib2.0 (2.61.2-2) experimental; urgency=medium . * Team upload * d/p/cond-test-Don-t-make-assumptions-about-struct-sigaction-m.patch: Add proposed patch to fix FTBFS due to a test failure on mips* . glib2.0 (2.61.2-1) experimental; urgency=medium . * Team upload * New upstream release * d/patches: Update to upstream git master, commit 2.61.2-23-g870b30bd7 - Fix regression in g_mkdir_with_permissions() - Fix a memory leak - Update translations: es, id, ro * Merge changes from unstable * Refresh patch series * d/p/debian/06_thread_test_ignore_prctl_fail.patch: Use g_test_skip() when skipping test * d/p/GIO-tests-Don-t-do-clever-tricks-with-objcopy.patch: Drop workaround for #932287, and build-depend on fixed binutils on mips64el instead * d/rules: Edit debcrossgen output instead of using a modified version. This fixes use of CFLAGS, etc. during cross-compilation. (Closes: #933560) * d/libglib2.0-0.symbols: Update * Remove obsolete permissions fixing. Issue 1539 was fixed upstream. * libglib2.0-tests: Depend on libglib2.0-dev-bin. This is required for the new mkenums and genmarshal tests. * d/p/debian/Disable-an-optimization-when-building-with-gcc-9.patch: Disable an optimization when building with gcc-9, instead of forcing gcc-8. This avoids depending on an old gcc, and should be easier to deal with for cross-compilation. (Workaround for #931921) . glib2.0 (2.60.6-1) unstable; urgency=medium . * Team upload * New upstream release, functionally equivalent to 2.60.5 with the patches we were already applying - d/p/portal-Add-a-getter-for-dconf-access.patch, d/p/settings-Tweak-priorities-for-keyfile-backend.patch, d/p/key-file-Handle-filename-being-NULL.patch: Drop, applied upstream * d/p/tests-Fix-data-race-in-gmenumodel-test.patch, d/p/tests-Fix-data-race-in-task-test.patch: Add patches from upstream git master to fix data races in tests. In particular, the one for gmenumodel might solve an unreproducible test failure on i386 (see #932678). * d/p/debian/gmenumodel-test-Mark-as-flaky.patch, d/p/debian/gvariant-test-Don-t-run-at-build-time-on-mips.patch: Skip more tests at build-time and during the non-flaky autopkgtest. The unreproducible gmenumodel test failure on i386 might in fact be fixed by d/p/tests-Fix-data-race-in-gmenumodel-test.patch, but it's hard to be sure about that. The gvariant fuzz test is catastrophically slow on certain mips CPUs and so is impractical to run there. (Closes: #932678) * Standards-Version: 4.4.0 (no changes required) * Use debhelper compat level 12 - Stop explicitly passing -V to dh_makeshlibs, it is now the default - Disable dh_dwz for libglib2.0-udeb. This avoids an apparent debhelper bug in which dh_dwz generates multifiles for udebs, but dh_strip does not remove them from the udeb's staging directory. (Workaround for #933212) * Stop overriding libexecdir. Since FHS 3.0 (Policy 4.1.5), /usr/libexec is considered valid, and since debhelper compat level 12 it is the default. In this particular package this only affects the installed-tests. * Remove an obsolete Lintian override . glib2.0 (2.60.5-1) unstable; urgency=medium . * Team upload * Prepare GLib 2.60.x stable branch for unstable * New upstream release * d/p/portal-Add-a-getter-for-dconf-access.patch, d/p/settings-Tweak-priorities-for-keyfile-backend.patch, d/p/key-file-Handle-filename-being-NULL.patch: Add post-release fixes from upstream glib-2-60 branch * d/p/GIO-tests-Don-t-do-clever-tricks-with-objcopy.patch: Don't do strange things with objcopy while testing GResource, while we work out what is going on in mips64el builds. Mitigates: #932287 . glib2.0 (2.61.1-2) experimental; urgency=medium . * control, rules: Build with gcc-8. See #931921 - when we're built with gcc-9, some applications that use GLib might start hanging. . glib2.0 (2.61.1-1) experimental; urgency=medium . * New upstream release + `g_unichar_isxdigit()` and `g_unichar_xdigit_value()` now handle full-width characters (U+FF21–U+FF26 and U+FF41–U+FF46) + Deprecate `gtester` utility and its test reporting format and enable TAP output by default instead — the `--tap` option to tests is now a no-op + Add `g_test_summary()` to allow test authors to programmatically summarise what each unit test in a test suite does * Upgrade to Unicode Character Database v12.1 + More IPv6 Happy Eyeballs fixes to `GNetworkAddress` and `GSocketClient` + Fix valgrind and gdb support for the new `GHashTable` changes + Fix GTask wait times growing faster than the number of task threads + Add `g_autoqueue()` helper macros, similar to `g_autolist()` + Add pre-allocated link helpers for `GList` and `GQueue`: - `g_list_insert_before_link()` - `g_queue_insert_before_link()` - `g_queue_insert_after_link()` + Improve network availability detection with NetworkManager to treat lower levels of connectivity as having reduced availability + Add `g_clear_signal_handler()` to allow disconnecting from a `GObject` signal and clearing the signal handler ID to zero in a single call + Add `g_autoptr()` support for `GRWLock` * 81-skip-monitor-test-on-non-linux.patch: Drop. This test was removed upstream. * debian/libglib2.0-0.symbols: Update . glib2.0 (2.60.4-1) experimental; urgency=medium . * New upstream release (LP: #1832457) + Fixes to improved network status detection with NetworkManager (#1788) + Leak fixes to some `glib-genmarshal` generated code + Further fixes to the Happy Eyeballs (RFC 8305) implementation + File system permissions fix to clamp down permissions in a small time window when copying files (CVE-2019-12450) + Bugs fixed: - Please revert #535 gmacros: Try to use the standard __func__ first in G_STRFUNC * gfile-Limit-access-to-files-when-copying.patch: Drop. It's in this version upstream. * d/p/*: Refresh through gbp pq . glib2.0 (2.60.3-2) experimental; urgency=medium . * Team upload * d/p/gfile-Limit-access-to-files-when-copying.patch: Backport patch from upstream to ensure files don't temporarily have less restrictive permissions during copying (Closes: #929753, CVE-2019-12450) * Drop d/p/debian/04_homedir_env.patch: Remove legacy support for Debian-specific G_HOME environment variable. GLib has respected the HOME environment variable in the conventional way since wheezy. Only two packages (pygtk and ruby-graphviz) still set G_HOME without also setting HOME. * Drop d/p/debian/90_gio-modules-multiarch-compat.patch: Remove legacy support for loading modules from /usr/lib/gio/modules. All the known packages containing GIO modules (dconf, glib-networking and gvfs) migrated to /usr/lib/${DEB_HOST_MULTIARCH}/gio/modules before wheezy. * Register documentation in doc-base via symlinks in /usr/share/doc. The doc-base specification requires this, presumably for the benefit of tools that export /usr/share/doc via HTTP (see #925200), and Lintian 2.12 added a warning for not doing so. . glib2.0 (2.60.3-1) experimental; urgency=medium . * New upstream releases 2.60.1 2.60.2 2.60.3, fixing many bugs: + build: Fix a typo in the test whether _NL_ABALTMON_n is supported + Critical in g_socket_client_async_connect_complete + Fix crash when displaying notifications on macOS (!786) + Fix documentation for `gdbus-tool wait` to use correct units + Fix typo in German translation + glib/date test fails + glib/gconstructor.h: Include stdlib.h for MSVC builds + GNetworkAddressAddressEnumerator unsafely modifies cache in GNetworkAddress + gnetworkaddress: Fix parallel enumerations interfering with eachother + gnetworkmonitornm: Fix network available detection + GResource generation test incompatible with stable LLVM on Linux + gschema.dtd: Add target attribute to alias + gsocketclient: Fix a leak in the connection code + Improve network status detection with NetworkManager + Leaks in gsocketclient.c connection code + test_month_names: assertion failed + tests: Update month name check for Greek locale + Update gdb pretty-printer for GHashTable + Various fixes to small key/value support in `GHashTable` + New GHashTable implementation confuses valgrind + more GHashTable fixes + GDB pretty-printer for GHashTable no longer works + ghash: Disable small-arrays under valgrind . glib2.0 (2.60.0-1) experimental; urgency=medium . * New upstream release + Further fixes to the Happy Eyeballs (RFC 8305) implementation + Add support for the XDG trash portal * Call dh_python3 for all packages and add Depends to libglib2.0-tests. The tests now ship a "static-link.py" test. While it early-exits currently, we still need the right dependencies to be able to do that. Call dh_python3 for libglib2.0-test's private directory, and while we're here make sure that it is called for all packages too. * flaky autopkgtest: `closures` has been renamed to `closure-refcount` * Refresh and drop patches. - d/p/flaky-socket-service-test/*: Drop, applied upstream. - d/p/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch: Refresh. . glib2.0 (2.59.3-2) experimental; urgency=medium . [ Philip Withnall ] * debian: Drop GVariant alignment patches which are no longer needed. The upstream 2.59.0 release contained commit 0f2a6c61c9c5e34d57293fb6987b21f3d1feb1cb, which automatically aligns GVariants at construction time. The realignment in the tests was a workaround for this. See upstream issue https://gitlab.gnome.org/GNOME/glib/issues/1342. . [ Iain Lane ] * Cherry-pick fixes for upstream bug #1679 to fix a flaky test. This is apparently more flaky on the autopkgtest machines than elsewhere - it's quite consistently failing there. . glib2.0 (2.59.3-1) experimental; urgency=medium . * New upstream release + Fix support for g_get_user_special_dir() on macOS, including support for the Downloads directory + Ensure that cancelling a GTask cannot cause its callback to be called synchronously (in the same call chain as the original *_async() call) + Further fixes to the Happy Eyeballs (RFC 8305) implementation + Various fixes for installation of installed tests * Refresh and drop patches. Drop gio-tests-Install-test1.overlay-file-when-building-instal.patch, tests-Install-the-slow-connect-preload.so-library-and-use.patch, fixed upstream. . glib2.0 (2.59.2-2) experimental; urgency=medium . * Install `test1.overlay' file, which is needed for the installed tests. * tests: Install the slow-connect-preload.so library and use it . glib2.0 (2.59.2-1) experimental; urgency=medium . * New upstream release + Fix check on GDBusMessage size when reading it. + Add async GIO API: g_file_query_default_handler_async(), g_app_info_launch_uris_async() + Fix some bugs in the Happy Eyeballs implementation. + Install a new generated header with enum types for Unicode enums. + Support the XDG trash portal. + Autotools support is gone. + g_format_size() now uses a no-break space to separate digits and units; translations will need to be updated accordingly. + New g_queue_clear_full() API. + Fix argument quoting on win32 when spawning subprocesses. + Allow polling more than 64 handles on win32 using g_poll(). + Tag various tests as ‘flaky’. These are no longer run routinely on our upstream CI machines, and downstream packagers may want to not run them (or not treat those test failures as package build failures) on their test machines either. They are in the `flaky` test suite. + Add overlay support to g_resources_get_info(). + Support defaults and locks in the keyfile GSettings backend. This will be used for flatpaks. + Accept unquoted strings in the keyfile GSettings backend to simplify things for sysadmins. + Update our contribution guidelines (`CONTRIBUTING.md`). + Add writev() and writev_all() APIs to GOutputStream and GPollableOutputStream, and provide implementations of them for many subclasses. * Refresh patches, drop trash test patches which are upstream now * build-time tests: Run "flaky" suite separately and non fatally * debian/libglib2.0-0.symbols: Add new symbols from 2.59.{1,2} . glib2.0 (2.59.0-1) experimental; urgency=medium . * New upstream release * Update patches and drop upstreamed ones * debian/control: Update meson BD to ≥ 0.48.0 per upstream * debian/rules: enable-selinux takes "enabled" or "disabled" now. Not true/false. * debian/*: Update for experimental * debian/libglib2.0-0.symbols: Update with new symbols for this release . glib2.0 (2.58.3-3) unstable; urgency=medium . * control, rules: Build with gcc-8. See #931921 - when we're built with gcc-9, some applications that use GLib might start hanging. . glib2.0 (2.58.3-2) unstable; urgency=medium . * Team upload * d/p/gfile-Limit-access-to-files-when-copying.patch: Backport patch from upstream to ensure files don't temporarily have less restrictive permissions during copying (Closes: #929753, CVE-2019-12450) * d/watch: Only watch for 2.58.x releases now that 2.60.x is out * Add cross-reference to #919777 in previous changelog entry . glib2.0 (2.58.3-1) unstable; urgency=medium . * Team upload . [ Iain Lane ] * debian/gbp.conf: Use upstream/2.58.x . [ Simon McVittie ] * New upstream release - Fix crashes related to the GUnixMount API (Closes: #919777) - Make G_DEFINE_INTERFACE compatible with g++ -Wint-in-bool-context - Drop patches that were applied upstream * d/p/gdbusmessage-Fix-check-on-upper-limit-of-message-size.patch: Add patch from upstream glib-2-58 branch to limit the maximum size of D-Bus messages according to the protocol specification (the limit was 256M, and is now the correct 128M) . glib2.0 (2.58.2-4) unstable; urgency=medium . [ Simon McVittie ] * Update patch metadata . [ Iain Lane ] * trash-test-Don-t-assume-that-.local-exists.patch, trash-test-Don-t-rely-on-being-able-to-determine-mount-po.patch: Cherry pick two patches by Simon McVittie (slightly modified by Iain Lane) to fix the trash test on Launchpad autobuilders. . glib2.0 (2.58.2-3) unstable; urgency=medium . * Team upload * Release to unstable * Standards-Version: 4.3.0 (no changes required) * d/p/gvariant-test-Also-force-alignment-for-tuple-test-data.patch: Mark as forwarded * debian/Skip-unreliable-test_threaded_singleton-by-default.patch: Don't run test_threaded_singleton() at build-time or in the part of the autopkgtest run that must succeed. Run it from d/tests/flaky instead. . glib2.0 (2.58.2-2) experimental; urgency=medium . * Team upload * d/p/gvariant-test-Also-force-alignment-for-tuple-test-data.patch: Fix gvariant test failure on s390x by forcing more test data to be aligned (Closes: #917980) * d/p/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch, d/tests/flaky: Only run closures test on arm* as part of a separate, flaky autopkgtest. This test does not seem to be reliable enough for its failures to be treated as release-critical, at least on arm*. If we run too many iterations, it fails on CPUs where 16-bit accesses are slow; if we run too few, it occasionally fails when one thread starves another. (Closes: #917983) * d/p/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch, d/p/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch: d/tests/flaky: Use g_test_skip() for flaky tests, and run them from d/tests/flaky . glib2.0 (2.58.2-1) experimental; urgency=medium . * Team upload * New upstream release * Drop many patches that were applied upstream * d/p/tests-Allocate-gvariant-data-from-the-heap-to-guarantee-a.patch: Add patch from upstream to fix alignment of GVariant test data * d/libglib2.0-0.symbols: Update for new ABI * d/tests/installed-tests: Log execution environment * postinst: Convert triggers into a function * postinst: Quote strings with #TOKENS# to fix syntax highlighting * postinst: Add a vim modeline . glib2.0 (2.58.1-6) experimental; urgency=medium . * Team upload * d/p/closures-test-Avoid-timeout-on-ARM64-CPUs.patch: Rename from d/p/debian/closures-test-Run-fewer-iterations-on-ARM64-and-armhf.patch, increase the test timeout to prevent this test from timing out on Cortex-A57 CPUs when building with Meson, and mark as forwarded upstream * Disable xattr support on kFreeBSD. kFreeBSD has stub implementations of getxattr() etc. which will always fail. Autoconf considers these to be present, but Meson detects them and treats them as absent, resulting in configuration failure. . glib2.0 (2.58.1-5) experimental; urgency=medium . * Team upload * d/p/*: Update to upstream glib-2-58 branch as of 2.58.1-89-g7aa52a7d5, except for translations * d/p/mainloop-test-Fix-race-conditions.patch: Add patch from upstream git master to fix race conditions in mainloop test * d/p/meson-Define-__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4-on-GNU-Li.patch: Add proposed patch to fix detection of atomic operations on armel * Respect nocheck in DEB_BUILD_OPTIONS * Adjust test timeouts: - Increase armel, armhf, hppa timeout multiplier from x3 to x5 - Reduce mips*, sparc* timeout multiplier from x10 to x5 - Reduce timeout multiplier for architectures known to have qemu buildds from x50 to x20 * d/rules: Set Meson cross properties using a modified debcrossgen. This avoids embedding a local copy of GNUlib (v)(sn)printf when cross-compiling. (Workaround for #912559) . glib2.0 (2.58.1-4) experimental; urgency=medium . * Team upload * d/rules: Deduplicate test invocation * Use `meson test` directly, instead of going via `ninja test` * Multiply Meson test timeouts. Use x3 timeouts for most architectures (in general the timeouts in the upstream Meson build system are somewhat optimistic), x10 for the mips and sparc families, and x50 for architectures known to use qemu for buildds. * Enable FAM support on Hurd and kFreeBSD. In the Autotools build system this was auto-detected, but in Meson it is off by default and must be explicitly enabled if wanted. * d/p/meson-Mark-1bit-emufutex-test-as-slow.patch: Increase timeout for the 1bit-emufutex test . glib2.0 (2.58.1-3) experimental; urgency=medium . * Team upload * Upload to experimental to check that everything is OK with the switch to Meson * Switch build system to Meson as recommended by upstream - Stop removing .la files: Meson doesn't build those - d/p/debian/61_glib-compile-binaries-path.patch: Change the same path if we build with Meson - d/patches: Apply patches proposed for backport from master to glib-2-58 in upstream MR 392. These fix various build issues, mostly around Meson. Some of these patch Windows-specific code, but they are likely to be in 2.58.2 and upstream asked for wider testing, so I'm applying them anyway, to test the complete set. - d/p/Spelling-*.patch: MR 392 also applies patches from upstream git master to fix various spelling mistakes detected by Lintian * Always generate testmarshal.h, even when cross-compiling (Closes: #908334) * Fix static linking and make sure it won't regress, prompted by comparing the Autotools and Meson builds: - Add missing -dev dependencies on libffi-dev, libmount-dev, libselinux1-dev - d/p/Autotools-Move-libmount-from-Libs.private-to-Requires.pri.patch: Add patch from upstream git master to fix static linking with libgio - d/tests/build: Exercise all libraries - d/tests/build-static: Exercise static linking * d/rules: Fix some permissions (equivalent of #1539 upstream) * Add Lintian override for a spelling-error-in-binary false positive * Add some Lintian overrides for hardening-no-fortify-functions. These objects mostly don't use libc directly. * Remove /usr/bin/gio-launch-desktop symlink. It's an implementation detail of libgio, and isn't intended to be run directly. Removing it from PATH silences a Lintian warning about it not having a man page. * Don't delete compiled GSettings schemas during purge if the dpkg reference count is greater than 1. This avoids deleting and regenerating it unnecessarily if another architecture's libglib2.0-0 is still installed. (Closes: #775854) * d/tests/installed-tests: Replace deprecated $ADTTMP with $AUTOPKGTEST_TMP * d/tests/control: Mark build tests as superficial (see #904979) . glib2.0 (2.58.1-2) unstable; urgency=medium . * Fix dh_missing rule for arch:all build with compat 11 . glib2.0 (2.58.1-1) unstable; urgency=medium . * New upstream release * Drop patches applied in new release: - Fix-g_icon_to_string-regression-doc-inconsistency.patch - tests-timer-Skip-test_timeval_to_iso8601_overflow-if-we-c.patch * Refresh 61_glib-compile-binaries-path.patch * Bump Standards-Version to 4.2.1 * Bump debhelper compat to 11 . glib2.0 (2.58.0-4) unstable; urgency=medium . [ Simon McVittie ] * Adjust installation path of gdb scripts to match GLib itself. We used to put libglib-2.0.so.0 in /lib/MULTIARCH, but this is no longer the case since 2.56.0-5. * Wrap and sort (build-)dependency lists (wrap-and-sort -a) * Wrap and sort file lists (wrap-and-sort -a) * Install HTML in /usr/share/gtk-doc/html with symlinks in /usr/share/doc. The gtk-doc documentation is technically a functionally significant part of the package (it affects cross-reference generation during build of other packages) so according to Policy §12.3 it is not appropriate for /usr/share/doc. Using the upstream default installation path for the HTML also makes it more straightforward to switch to the Meson build system, because the Meson build does not have an equivalent of --with-html-dir. - d/debian/libglib2.0-doc.maintscript: Add migration steps * d/p/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch: Also patch meson build system . [ Jeremy Bicha ] * Cherry-pick Fix-g_icon_to_string-regression-doc-inconsistency.patch - Have g_icon_new_for_string() go back to only returning a single name when created with a single name since some apps assume that behavior. (Closes: #908705) . glib2.0 (2.58.0-3) unstable; urgency=medium . [ Iain Lane ] * Run fewer iterations of clousures test on armhf too . glib2.0 (2.58.0-2) unstable; urgency=medium . * Cherry-pick upstream patch to fix test_timeval_to_iso8601_overflow on 32-bit, fixing FTBFS there. . glib2.0 (2.58.0-1) unstable; urgency=medium . [ Jeremy Bicha ] * New upstream release * Drop patches applied in new release: - date-test-Use-g_test_skip-not-g_test_incomplete.patch - g_binding_unbind-make-it-more-introspection-friendly-allo.patch: * Release to unstable . [ Simon McVittie ] * d/p/debian/closures-test-Run-fewer-iterations-on-ARM64.patch: Update metadata * libglib2.0-dev-bin: Add Suggests for the packages containing xmllint and gdk-pixbuf-pixdata, which are sometimes invoked by glib-compile-resources (Closes: #834998) * Invoke dh_python3 twice so that we correctly rewrite the shebang line for /usr/bin scripts (Closes: #876009) * Don't install very old changelogs and NEWS files * Install README.md instead of stub README . glib2.0 (2.57.2-2) experimental; urgency=medium . * Cherry-pick g_binding_unbind-make-it-more-introspection-friendly-allo.patch to fix pygobject build (LP: #1787474) . glib2.0 (2.57.2-1) experimental; urgency=medium . * Team upload * New upstream development release * d/watch: Look for odd-numbered releases * Rebase patch series * Install gio-launch-desktop in libglib2.0-0's private libdir to avoid a circular dependency between libglib2.0-0 and libglib2.0-bin - d/p/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch: Look for it there * d/copyright: Update * d/libglib2.0-0.symbols: Update * Use upstream autogen.sh for autoreconf * Don't clean org.gtk.test.gschema.override.orig * d/gbp.conf: Use upstream/latest branch * d/p/Drop-a-questionable-test-from-the-refstring-suite.patch: Add patch to fix FTBFS on i386 * d/p/date-test-Use-g_test_skip-not-g_test_incomplete.patch: Add patch to fix autopkgtest failures without locales-all * d/gbp.conf: Don't number patches . glib2.0 (2.56.1-2) unstable; urgency=medium . [ Tim Lunn ] * libglib2.0-0.triggers:use interest-await trigger for schemas . [ Iain Lane ] * debian/patches/tests-network-monitor-Always-use-the-dummy-proxy-res.patch: Take patch from upstream to ignore the system's proxy settings for the network-monitor test - it's testing an "abstract" network unrelated to the system's network, and these settings interfere with that. This fixes a failure in the Ubuntu autopkgtest machines, which have a proxy set. . glib2.0 (2.56.1-1) unstable; urgency=medium . [ Tim Lunn ] * New upstream release * Drop patches included in new release * libglib2.0-0.triggers: Use interest-noawait triggers, generating caches doesn't need to block configuration. flagged by lintian uses-implicit-await-trigger warning. . [ Simon McVittie ] * Explicitly use autoconf build system, even with debhelper 11.2 (see #895174) . glib2.0 (2.56.0-6) unstable; urgency=medium . * Team upload * d/p/0002-gapplication-Tighten-up-application-ID-validation.patch: Transliterate commit message into ASCII so git-buildpackage doesn't export it as a blob of base64 * d/p/g_test_dbus_down-Ensure-next-test-does-not-use-old-c.patch: Add patch to address a race condition that sometimes makes D-Bus-based tests fail (Closes: #894677) * d/patches: Improve metadata on various patches . glib2.0 (2.56.0-5) unstable; urgency=medium . [ Simon McVittie ] * Use `set -e` in the (empty) prerm to avoid a Lintian warning * Add Lintian override for the empty prerm used to work around #887629 . [ Michael Biebl ] * Stop installing libglib to /lib. Late mounting of /usr is no longer supported, so this is not necessary anymore. * Drop maintscript migration code from pre-jessie. * Drop obsolete Breaks. . glib2.0 (2.56.0-4) unstable; urgency=medium . * Fix typo: libglib2.0-dev-bin Depends on python3-distutils, not distuils (Closes: #893773) * Restore `set -x` in debian/tests/build . glib2.0 (2.56.0-3) unstable; urgency=medium . [ Iain Lane ] * debian/tests/build: Add Restrictions: allow-stderr. We run this test with `set -x', which outputs to stderr, and would like to continue doing so. . [ Jeremy Bicha ] * Depend and Build-Depend on python3-distutils to fix build failures since python3 no longer depends on python3-distutils (Closes: #893736) . glib2.0 (2.56.0-2) unstable; urgency=medium . [ Simon McVittie ] * Merge from experimental to unstable * d/tests/build: Don't rely on having unmerged /usr * d/watch: Only watch for stable releases * d/gbp.conf: Use debian/master, upstream/2.56.x branches * d/control: Update Vcs-* for default branch . glib2.0 (2.56.0-1) experimental; urgency=medium . * Team upload * New upstream stable release 2.56.0 * d/p/000?-gdbus-tool-*.patch: Drop patches that came from upstream * Refresh remaining patches * d/p/0001-tests-Use-modern-test-assertions-in-GApplication-tes.patch, d/p/0002-gapplication-Tighten-up-application-ID-validation.patch: Cherry-pick GApplication ID fixes from upstream 2.56 branch (GNOME #793400) . glib2.0 (2.55.2-2) experimental; urgency=medium . * Merge changes from unstable, in particular: + d/libglib2.0-dev.prerm: Add an empty prerm to make sure that we have a way to recover from #887629 in stretch (Closes: #887863) * d/p/0001-gdbus-tool-Ignore-unknown-options-for-the-emit-subco.patch, d/p/0002-gdbus-tool-Make-dest-optional-for-emit-again.patch, d/p/0003-gdbus-tool-Don-t-repeatedly-complete-signal.patch, d/p/0004-gdbus-tool-Factor-out-common-GOptionContext-construc.patch: Cherry-pick from upstream. Fix `gdbus emit' to not require `--dest', and improve its bash completion. Should fix the dbus-test-runner autopkgtest, which relied on this behaviour. . glib2.0 (2.55.2-1) experimental; urgency=medium . * debian/control{,.in}: Update Vcs-* to specify debian/experimental branch. * New upstream release 2.55.2: + GFile now has API to get the path without copying * debian/patches/gdbus-threading-test-Allow-even-longer-for-test_method_ca.patch, debian/patches/gdatetime-Avoid-repeated-floating-point-multiplies-w.patch, debian/patches/gdatetime-Mark-the-usecs-as-volatile.patch: Drop, applied upstream in this release. * debian/libglib2.0-0.symbols: New symbols for 2.55.2 . glib2.0 (2.55.1-1) experimental; urgency=medium . * debian/gbp.conf, debian/watch: Update for experimental * New upstream development release 2.55.1 * debian/libglib2.0-0.symbols: Update with new symbols in this release. * debian/patches/gdatetime-Avoid-repeated-floating-point-multiplies-w.patch, debian/patches/gdatetime-Mark-the-usecs-as-volatile.patch: Cherry-pick two patches from upstream. Fix some precision problems within GDateTime, that in some cases resulted in incorrect answers on i386. . glib2.0 (2.54.3-2) unstable; urgency=medium . * Team upload * d/libglib2.0-dev.prerm: Add an empty prerm to make sure that we have a way to recover from #887629 in stretch (Closes: #887863) * d/p/gdbus-threading-test-Allow-even-longer-for-test_method_ca.patch: Mark as applied upstream * d/p/gmain-Partial-revert-of-recent-wakeup-changes-to-gmain.c.patch: Apply patch from upstream glib-2-54 branch to revert GWakeup changes that appear to have broken WebKit and/or LibreOffice (Closes: #887492) . glib2.0 (2.54.3-1) unstable; urgency=medium . [ Simon McVittie ] * Move Vcs-* to salsa.debian.org * New upstream stable release - Fix a race condition when a GCancellable is cancelled in another thread (Closes: #884654) - Drop patches for #884661, fixed upstream * d/p/gdbus-peer-Skip-test-during-Debian-package-build.patch: Drop. We should no longer need to skip this test now that #884654 is fixed. * d/p/Do-not-attempt-to-autolaunch-a-session-dbus-daemon-w.patch: Drop patch. It has not been necessary since 2.50. * d/p/0001-Fix-trashing-on-overlayfs.patch, d/p/0001-timer-test-use-volatile-for-locals.patch, d/p/gdbus-threading-test-Allow-even-longer-for-test_method_ca.patch: Mark as forwarded upstream * d/patches: Move non-upstreamable patches (Debian-specific changes and workarounds) to d/p/debian, and to the bottom of d/p/series * d/watch: Only watch for the upstream stable branch . [ Iain Lane ] * debian/gbp.conf: Update upstream branch to upstream/2.54.x following DEP-14. . glib2.0 (2.54.2-5) unstable; urgency=medium . * Set Rules-Requires-Root to no. This package builds successfully with the same content in that mode. * d/p/61_glib-compile-binaries-path.patch: Only use the multiarch path for glib-compile-schemas, not for glib-compile-resources * Install glib-compile-resources into PATH in libglib2.0-dev-bin, not libglib2.0-bin: it is a development tool used at compile-time - libglib2.0-dev-bin Breaks/Replaces older libglib2.0-bin * Install the glib-compile-resources binary in libglib2.0-dev-bin, not libglib2.0-0. This means we get an executable version of that binary when cross-compiling (Closes: #885019) * Bump Standards-Version to 4.1.3 . glib2.0 (2.54.2-4) unstable; urgency=medium . * Team upload * d/p/closures-test-Run-fewer-iterations-on-ARM64.patch: Run more iterations on ARM64 than in 2.54.2-3, but fewer than in 2.54.2-2. If we don't run enough iterations, we get an assertion failure when the main thread starves the other threads. * d/p/gmenumodel*.patch: Mark as upstreamed in 2.54.3 and 2.55.1 * d/rules: Set DEB_BUILD_TIME_TESTS when running dh_auto_test, so that tests can distinguish between autopkgtest and `make check` * d/p/gdbus-peer-Skip-test-during-Debian-package-build.patch: Skip the gdbus-peer test during package build, so that its known race condition does not cause intermittent FTBFS (mitigates: #884654) . glib2.0 (2.54.2-3) unstable; urgency=medium . * Team upload * d/patches: Re-export with gbp pq * d/patches: Use `gbp pq export`-style metadata, retrieving authors and dates from d/changelog where needed * d/p/closures-test-Run-fewer-iterations-on-ARM64.patch: New patch. tests/refcount/closures: Run fewer iterations on ARM64 (mitigates: #880883) * d/p/gdbus-threading-test-Allow-even-longer-for-test_method_ca.patch: New patch. Allow even longer for the gdbus-threading test, and re-enable it on 32-bit ARM now that the timeout is longer (Closes: #884660) * d/p/gmenumodel-test-If-something-goes-wrong-don-t-wait-foreve.patch, d/p/gmenumodel-test-Wait-for-the-expected-events-to-happen.patch: Add patches to make the GMenuModel test more patient (Closes: #884661) * d/p/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch: Reduce number of threads and number of operations in response to timeout on reproducible-builds infrastructure (mitigates: #884659) . glib2.0 (2.54.2-2) unstable; urgency=medium . * Update Vcs fields for conversion to git * Add debian/gbp.conf * Bump Standards-Version to 4.1.2 . glib2.0 (2.54.2-1) unstable; urgency=medium . [ Jeremy Bicha ] * New upstream release . [ Didier Roche ] * debian/patches/01_gettext-desktopfiles.patch: - fix untranslated desktop action names when using gettext (Closes: #877761) . [ Simon McVittie ] * Skip gtk-doc documentation unless we are building libglib2.0-doc, fixing cross-builds (Closes: #870346) - Note that gtk-doc-tools is still in Build-Depends, not Build-Depends-Indep, because we need it for autoreconf * Explicitly disable documentation for the udeb build * Skip build-time tests for Arch:all builds - testing once per architecture is sufficient * Remove unused lintian override for an example file that is no longer installed . glib2.0 (2.54.1-1) unstable; urgency=medium . [ Jeremy Bicha ] * New upstream release * Bump Standards-Version to 4.1.1 . [ Michael Biebl ] * Drop uploaders.mk include as it breaks the clean target. Updating the Uploaders list is already handled by the gnome dh addon. . glib2.0 (2.54.0-1) unstable; urgency=medium . * New upstream stable release. . glib2.0 (2.53.7-1) unstable; urgency=medium . * New upstream release. * debian/patches/81-skip-monitor-test-on-non-linux.patch: + Refreshed. * debian/control.in: drop automake and autotools-dev build dependencies, dh-autoreconf does that for us. * Bump Standards-Version to 4.1.0; no changes needed. . glib2.0 (2.53.6-1) unstable; urgency=medium . * New upstream release. * git_glib-mkenums-utf8.patch, git_glib-mkenums-flags.patch: Drop, now applied upstream. * debian/rules: Don't pass -X.la to dh_auto_install - it can easily lead to unwanted removals (not claiming this is happening here) * debian/rules: Fix arguments to dh_auto_test so tests are run again * debian/rules, debian/control{,.in}: Use dh_missing and not dh_install --list-missing. Also upgrade this check to --fail-missing. * debian/rules: Don't run the tests under fakeroot; it makes them fail with dbus-related authentication problems. . glib2.0 (2.53.4-3) unstable; urgency=medium . [ Matthias Klumpp ] * Update Vcs-* URLs . [ Jeremy Bicha ] * Bump Breaks/Replaces: libglib2.0-dev to 2.53 (Closes: #867679) * Add git_glib-mkenums-utf8.patch: - Backport commit to fix "glib-mkenums: UnicodeDecodeError" (Closes: #870310) * Add git_glib-mkenums-flags.patch: - Backport commit to fix mate-panel FTBFS (Closes: #870212) . glib2.0 (2.53.4-2) unstable; urgency=medium . * Upload to unstable . glib2.0 (2.53.4-1) experimental; urgency=medium . * New upstream release 2.53.4 + Unicode support has been updated to Unicode 10.0.0 + glib-genmarshal and glib-mkenums have been rewritten in python + GLib can now be built with meson. autotools are still supported . glib2.0 (2.53.3-1) experimental; urgency=medium . * New upstream release 2.53.3. * d/p/0001-gdatetime-Fix-a-potential-overflow-in-overflow-calcu.patch, d/p/0002-tests-Fix-GDateTime-overflow-tests-on-32-bit-archite.patch, d/p/0003-tests-Fix-overflows-in-find_maximum_supported_tv_sec.patch: Cherry-picks to fix some overflow problems in GDateTime on 32 bit arches. . glib2.0 (2.53.2-1) experimental; urgency=medium . * New upstream release 2.53.2 + A few new number parsing functions have been added: - g_ascii_string_to_signed - g_ascii_string_to_unsigned These have better error handling than the existing ones. + glib-mkenums now supports /*< private >*/ and /*< public >*/ + GSettings now consider XDG_DATA_HOME in addition to XDG_DATA_DIRS. * debian/libglib2.0-0.symbols: Add new symbols for 2.53.1. * debian/patches/skip-broken-dbus-appinfo-test.patch: Drop - this test works now. . glib2.0 (2.53.1-1) experimental; urgency=medium . * New upstream release 2.53.1 + The gdbus tool gained a wait command + g_unix_signal_source_new support SIGWINCH now + There are now g_enum_to_string and g_flags_to_string functions + A new function to instantiate objects: g_objet_new_with_properties + GParameter and related APIs have been deprecated * debian/libglib2.0-0.symbols: Add new symbols for 2.53.1. . glib2.0 (2.52.0-1) experimental; urgency=medium . * New upstream release 2.52.0 * d/p/tests-gdatetime-Use-a-real-rather-than-invented-time.patch: Drop, applied in this release. . glib2.0 (2.51.5-1) experimental; urgency=medium . * New upstream release 2.51.5 * Drop patches applied upstream in this release: - Install-gdb-Python-helpers-as-data-not-as-executable.patch - glib-mkenums-Sort-input-files-for-more-deterministic.patch * debian/patches/tests-gdatetime-Use-a-real-rather-than-invented-time.patch: Cherry-pick a patch from upstream to fix GDateTime tests when tzdata ≥ 2017a is in use. * debian/libglib2.0-dev.install: Install the gdb script for libglib-2.0.so.* into .../lib instead of .../usr/lib - it needs to match the installed path of the library and we put libglib-2.0.so.* into /lib. * debian/libglib2.0-0.symbols: Add g_content_type_is_mime_type . glib2.0 (2.51.4-1) experimental; urgency=medium . * Team upload * New upstream release 2.51.4 (and 2.51.3) * Build with dh instead of cdbs - Move to debhelper compat level 10 - Use dpkg-buildflags variables to extend LDFLAGS - Enable bindnow hardening - Remove indirection via $(SHARED_PKG), etc. variables - Let dh_gnome_clean update the Uploaders instead of reinventing it - Install some missing files detected by dh_install --list-missing - Fix lintian warnings about useless use of dh-exec - debian/dh_listmissing.pl: Remove * Improve packaging for cross-compiling (Closes: #648621, #842442) - Move glib-genmarshal and related files to a new M-A:foreign package libglib2.0-dev-bin. Thanks to Helmut Grohne for the patch. - Additionally move gdbus-codegen and gtester-report to libglib2.0-dev-bin. They are architecture-independent, so in particular clearly Multi-Arch: foreign; they aren't large enough to justify a separate Architecture: all package. This works around dh_python3's postinst snippet failing when used in a Multi-Arch: same package with more than one instance installed. - Move gtester to libglib2.0-dev-bin. It is a test-runner that can operate on any executable, and does not rely on a matching architecture. - Move gobject-query to libglib2.0-dev-bin. It prints the same things on all architectures, and it isn't clear what use it is; glib-2.0.m4 checks for it and AC_SUBSTs it, but according to codesearch.debian.net no package actually seems to run it. - Make libglib2.0-dev Multi-Arch: same * Move gdb helpers from libglib2.0-0-dbg to libglib2.0-dev, move detached debug symbols from libglib2.0-0-dbg to autogenerated -dbgsym packages, and remove the libglib2.0-0-dbg binary package * Add support for noudeb build profile - Do not do the udeb build if the noudeb profile is selected, for faster test-builds * Fix assorted Lintian warnings - Add missing build-dependency on dh-python + remove obsolete Lintian override for mmissing B-D on python - Add Lintian overrides for some intentionally weird scripts used in tests - Do not install glib_gdb.py, gobject_gdb.py executable. They are libraries to be imported by the gdb hooks, not scripts. - Don't generate a ldconfig trigger for libglib2.0-tests, which does not contain any public shared libraries * Add patch to make glib-mkenums output more reproducible (Closes: #809152) * Explicitly build-depend on automake so that the aspcud resolver used for experimental does not decide automake1.11 is the best solution to a dependency on automake | automaken . glib2.0 (2.51.2-1) experimental; urgency=medium . * New upstream release 2.51.2 (& 2.51.1). + Minimal support for UUIDs has been added + A new file attribute, G_FILE_ATTRIBUTE_RECENT_MODIFIED has been added to improve sorting of recent files + glib-compile-resources grew a --generate-phony-targets flag + GLib now installs a valgrind suppressions file for GLib and GIO * debian/patches/skip-brokwn-dbus-appinfo-test.patch: Refresh (and fix the typo in the filename) * debian/libglib2.0-0.symbols: Add g_uuid* symbols which are new in this release . glib2.0 (2.51.0-2) experimental; urgency=medium . * Merge changes from 2.50.2-2: + debian/rules: disable libmount on !linux (Closes: #844052) + debian/patches/0001-Fix-trashing-on-overlayfs.patch: Update with new version from the upstream report to hopefully fix trashing of files in directories which are symlinks to different devices. (Closes: #800047) (LP: #1638245) . glib2.0 (2.51.0-1) experimental; urgency=medium . * debian/control{,.in}: Branch to experimental * debian/watch: Track unstable releases again. * New upstream release 2.51.0 + glib-genmarshal and glib-mkenums have gained --output options for better build system integration + New API: g_utf8_make_valid * Update debian/libglib2.0-0.symbols. . glib2.0 (2.52.3-1) unstable; urgency=medium . * New upstream release. * skip-brokwn-dbus-appinfo-test.patch, tests-gdatetime-Use-a-real-rather-than-invented-time.patch: + Dropped, applied upstream. * debian/libglib2.0-0.symbols: + Add new symbols. . glib2.0 (2.50.3-2) unstable; urgency=medium . * debian/patches/tests-gdatetime-Use-a-real-rather-than-invented-time.patch: Cherry-pick a patch from upstream to fix GDateTime tests when tzdata ≥ 2017a is in use. (Closes: #858214) . glib2.0 (2.50.3-1) unstable; urgency=medium . * New upstream release. . glib2.0 (2.50.2-2) unstable; urgency=medium . * debian/rules: disable libmount on !linux (Closes: #844052) * debian/patches/0001-Fix-trashing-on-overlayfs.patch: Update with new version from the upstream report to hopefully fix trashing of files in directories which are symlinks to different devices. (Closes: #800047) . glib2.0 (2.50.2-1) unstable; urgency=medium . * New upstream release. * Track stable releases in debian/watch. . glib2.0 (2.50.1-1) unstable; urgency=medium . [ Jason Crain ] * libglib2.0-bin: includes a new 'gio' commandline tool (Closes: #840164) . [ Andreas Henriksson ] * New upstream release. . glib2.0 (2.50.0-2) unstable; urgency=medium . [ Simon McVittie ] * Build-depend on tzdata, which is no longer transitively Essential. One test needs it. (Closes: #839487) . [ Michael Biebl ] * Fix Vcs-* to point to unstable. * Mark dependencies which are required to run the test-suite with . * Add explicit Build-Depends on xsltproc, docbook-xml and docbook-xsl. Besides libxml2-utils, those are needed for building the man pages. * Drop Build-Depends on dbus-x11. The test-suite uses a mock version of dbus-launch nowadays, so this dependency is no longer needed. (Closes: #835884) * Use dh-exec to substitute ${DEB_HOST_MULTIARCH} in .install, .links and .dirs files. . glib2.0 (2.50.0-1) unstable; urgency=medium . * New upstream release. * Refresh patches. . glib2.0 (2.49.7-1) unstable; urgency=medium . * New upstream release. * Update debian/libglib2.0-0.symbols with one addition. . glib2.0 (2.49.6-1) unstable; urgency=low . * New upstream release. * Limit the libmount-dev build-depedency to [linux-any]. . glib2.0 (2.49.5-2) experimental; urgency=medium . * debian/rules: Disable libmount for the udeb build; there's no libmount-udeb, no immediate plans to provide one, and the functionality in glib isn't that interesting in the d-i context at the present time. . glib2.0 (2.49.5-1) experimental; urgency=medium . [ Simon McVittie ] * Merge packaging from unstable. . [ Iain Lane ] * New upstream release 2.49.5 * debian/patches/gregex-loosen-behaviour-testing.patch: Drop this patch - it's in 2.49.5. * debian/libglib2.0-0.symbols: Add symbols for async g_app_info_launch_default_for_uri. * debian/control{,.in}, debian/rules: Enable libmount support . glib2.0 (2.48.1-3) unstable; urgency=medium . * debian/tests/control: do not fail on stderr output from installed-tests. If gvfs happens to be installed, it gets D-Bus-activated (even if it's disabled via GIO_USE_VFS and GIO_USE_VOLUME_MONITOR), resulting in logging from dbus-daemon. (Closes: #821031) * debian/tests/installed-tests: explicitly select built-in VFS and volume monitor * d/p/gregex-loosen-behaviour-testing.patch: add patch from upstream bug 767240 (not applied yet) to relax assertions about PCRE's behaviour, which changed in 8.38 (Closes: #834272) * d/rules: unset XDG_CONFIG_HOME, XDG_CACHE_HOME, XDG_DATA_HOME, XDG_CONFIG_DIRS, XDG_DATA_DIRS so that they are based on the temporary HOME. This avoids FTBFS if the user doing the build has these variables already set in their build environment (Closes: #834334) . glib2.0 (2.48.1-2) unstable; urgency=medium . * Remove refdbg variant. Thanks to Jonny Lamb for the patch. Closes: #827269. * Switch to python3. . glib2.0 (2.49.4-1) experimental; urgency=medium . * New upstream release. * debian/patches/add-missing-gio-xml.patch: + Dropped, gio.xml is now shipped in the tarballs. * debian/patches/0001-Fix-gio-tests-socket-listener.patch: + Dropped, included upstream. . glib2.0 (2.49.3-1) experimental; urgency=medium . * Switch to python3. * New upstream release. * d/p/0001-gsettings-test-Wrap-guint64-literals-in-G_GUINT64_CO.patch: + Dropped, applied upstream. * debian/patches/add-missing-gio-xml.patch: + Add gio.xml file, which is missing from the tarball. Needed for the documentation build. * debian/patches/0001-Fix-gio-tests-socket-listener.patch: + Fix a test hang. * debian/libglib2.0-0.symbols: + Update with new symbols. * Standards-Version is 3.9.8. No changes needed. . glib2.0 (2.49.2-2) experimental; urgency=medium . * d/p/0001-gsettings-test-Wrap-guint64-literals-in-G_GUINT64_CO.patch: Cherry-pick from upstream to fix test failure on non-64 bit arches. . glib2.0 (2.49.2-1) experimental; urgency=medium . [ Emilio Pozuelo Monfort ] * Remove refdbg variant. Thanks to Jonny Lamb for the patch. Closes: #827269. . [ Iain Lane ] * Update Vcs-* for experimental * New upstream release 2.49.2 + GDesktopAppInfo now allows bus activation with dashes. This is not technically allowed per the Desktop Entry specification, but it happens in the wild. Rather than forcing people to go through another traumatic desktop file rename, accept it and translate - to _. + The support for giving names to threads has been improved. Thread names are now supported on Solaris as well, and the Linux support no longer uses prctl() but the pthread api. + GIO resources can now be overridden at runtime, using the G_RESOURCE_OVERLAYS environment variable. + gdbus-codegen can now generate autocleanup definitions for the types it generates. Use the --c-generate-autocleanup option to control this + GMainContext and GTask have gained more systemtap probes * debian/watch: Update to find unstable versions * debian/patches/04_homedir_env.patch: Refresh to apply correctly * debian/libglib2.0-0.symbols: Update for this release . glib2.0 (2.48.1-1) unstable; urgency=medium . * New upstream release. * Refresh patches. * Drop obsolete Conflicts, Breaks and Replaces from pre-wheezy. * Drop obsolete preinst maintainer scripts which cleaned up the /usr/share/doc symlinks. * Drop version requirement for pkg-config dependency. (Closes: #734479) . glib2.0 (2.48.0-1) unstable; urgency=medium . * New upstream stable release 2.48.0 + a minor build fix in the name of determinism (Closes: #812876) + a few coverity fixes . glib2.0 (2.47.92-1) experimental; urgency=medium . * New upstream release. . glib2.0 (2.47.6-1) experimental; urgency=medium . * New upstream release. - GString is missing (transfer none) annotations on many of its methods - systemtap and gdb scripts install in wrong place - Documentation: various small improvements - gdbusobjectmanagerserver: Clarify recommended ObjectManager paths - Fix some annotations - Cannot build with default flags under Fedora rawhide (-Werror=format-nonliteral) - gmacros.h is testing attributes with __has_feature (when compiling with clang) * debian/libglib2.0-0-dbg.install.in: Upstream now installs the gdb auto-loaded scripts in the right place by themselves - no need for us to move them about. . glib2.0 (2.47.5-1) experimental; urgency=medium . * debian/watch: Use download.gnome.org, seems ftp.gnome.org is not updating properly currently. * New upstream release 2.47.5 + the system copy of PCRE is now used by default to implement GRegex. Configure with --with-pcre=internal if a system PCRE version is unavailable or undesired. + interfaces for DTLS support have been added. A new version of glib-networking will also be required. + GDBusMethodInvocation now drops replies if the sender set the NO_REPLY_EXPECTED flag + several GApplication fixes, including fixes for commandline arguments in interpreted languages on Windows * debian/libglib2.0-0.symbols: Update with new symbols for this release. * 0001-regex-test-expect-ASSERTION_EXPECTED-for-ab-with-PCR.patch: Drop, it's included in this release. . glib2.0 (2.47.4-1) experimental; urgency=medium . * New upstream release + The GApplication documentation has been improved in several areas. * 0001-tests-fix-a-test-on-32-bit-builds.patch, 0001-gtypes.h-move-G_STATIC_ASSERT-to-function-scope.patch: Drop, applied upstream in this release. * 0001-regex-test-expect-ASSERTION_EXPECTED-for-ab-with-PCR.patch: Fix regex tests to assert the right errors as of pcre 8.38. Cherry-pick from upstream. (Closes: #808842) * Don't build automatic dbgsym package for -refdbg . glib2.0 (2.47.3-3) experimental; urgency=medium . * debian/patches/0001-gtypes.h-move-G_STATIC_ASSERT-to-function-scope.patch: Another cherry-pick. Should fix g-ir-scanner. . glib2.0 (2.47.3-2) experimental; urgency=medium . * debian/patches/0001-tests-fix-a-test-on-32-bit-builds.patch: Cherry-pick from upstream. Fix tests (and therefore the build) on 32 bit arches. . glib2.0 (2.47.3-1) experimental; urgency=medium . * New upstream release + New API: hardware-assisted helpers for overflow-checked integer math. + Fixes: Invalid free in g_local_file_trash() (LP: #1512826) * d/p/{Doc-copy-included-example-files.patch, Doc-Fix-missing-glibconfig.h-when-builddir-srcdir.patch, Build-gdbus-example-objectmanager-server-again.patch}: Remove - in this upstream release. . glib2.0 (2.47.1-1) experimental; urgency=medium . * New upstream release. + The Unicode support has been updated to version 8.0 of the Unicode standard + GDesktopAppInfo no longer sets the DISPLAY environment variable when launching apps. This is now done in the GAppLaunchContext implementations when appropriate. * debian/watch: Look for development versions too. * debian/patches/90_gio-modules-multiarch-compat.patch: Refresh to apply on this version. * debian/patches/0001-GDateTime-test-fix-occasional-failures.patch: Drop, upstream in this release. * debian/libglib2.0-0.symbols: Update with new symbols for this release. . glib2.0 (2.46.2-3) unstable; urgency=medium . * Add debian/patches/disable-failing-test-for-pcre838.patch - disable regexp test that fails with new system pcre 8.38 which just hit Debian unstable. Needs further investigation but lets not leave the build broken during the holidays. . glib2.0 (2.46.2-2) unstable; urgency=medium . [ Iain Lane ] * Fix typo in previous changelog entry. . [ Andreas Henriksson ] * Add debian/patches/bug712848-volume-monitor-deadlock-kfreebsd.patch - patch by and big thanks to Steven Chamberlain for debugging this! - given lack of feedback from upstream, which would be very welcome for deep changes like this, use an ifdef to only change on *FreeBSD for now... (Closes: #712848) * Add --no-ddebs arg to dh_strip for refdbg package build which otherwise fails and I doubt we need ddeb/dbgsym for our debug package. . glib2.0 (2.46.2-1) unstable; urgency=medium . * Fix Vcs-* to point to unstable. * New upstream stable release 2.46.2. + Fixes cross compilation (Closes: #800610) * Drop changes from 2.46.1-2, which are all in this upstream release. * Drop debian/patches/0001-GDateTime-test-fix-occasional-failures.patch, applied upstream. . glib2.0 (2.46.1-2) unstable; urgency=medium . * Team upload. * Cherry-pick patches from upstream glib-2-46 branch to fix incomplete documentation (Closes: #659977) * debian/gdbus-example-objectmanager-server.c: add missing example file from upstream git; it was accidentally omitted from upstream tarballs . glib2.0 (2.46.1-1) unstable; urgency=medium . [ Michael Biebl ] * Drop clean-la.mk from debian/rules, no longer required. . [ Iain Lane ] * New upstream release 2.46.1 + Remove system_header pragma (should fix lack of warnings with things like g_return_if_fail) + move GStrv typedef (and auto-cleanup) from libgobject to libglib + fix order of trashing files to be closer to what is required in the specification. Namely, trashinfo files are written first. This should fix issues with the gvfs trash backend failing to correctly read the info for recently trashed files (preventing 'restore'). (Closes: #800491) (LP: #1495943) + tweak mime logic to return text/plain on all empty files instead of returning application/octet-stream. This includes files that have extensions that imply that they may be other types of files, which is a slight change of behaviour with respect to old GLib versions. (LP: #1497170) * debian/patches/0001-Revert-list-store-Fix-a-parameter-check.patch: Drop - this is applied upstream in this release. * debian/patches/0001-GDateTime-test-fix-occasional-failures.patch: Take patch from bgo#754994 to resolve intermittent test failures in the GDateTime tests. . glib2.0 (2.46.0-2) unstable; urgency=medium . * debian/patches/0001-Revert-list-store-Fix-a-parameter-check.patch: Cherry-pick from upstream to fix GSequence (this at least makes GStreamer's testsuite fail). . glib2.0 (2.46.0-1) unstable; urgency=medium . [ Iain Lane ] * New upstream stable release 2.46.0 + Disable runtime-deprecation warnings + Fix marshalling of flags on bigendian 64bit architectures . [ Simon McVittie ] * Change section of libglib2.0-refdbg from debug to devel, so that it isn't kicked out into a separate mirror network when we get automatic -dbgsym packages (Closes: #796836) . glib2.0 (2.45.8-1) experimental; urgency=medium . * New upstream development release. * Update debian/libglib2.0-0.symbols with one addition: g_param_spec_get_name_quark . glib2.0 (2.45.7-1) experimental; urgency=medium . * New upstream release 2.45.7 + Add G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE for use by non-POSIX-like backends (e.g. cloud storage). + GFileMonitor: Make the inotify backend work with atomic renames again + GSettings: change notification is again working unconditionally + GListStore has a sort function now + Test infrastructure: - Tests are now required to have unique names - TAP support has been improved - A macro for asserting that two memory regions have identical content has been added * debian/libglib2.0-0.symbols: Add new symbol for this release. . glib2.0 (2.45.6-1) experimental; urgency=medium . * New upstream releases 2.45.5 and 2.45.6 + GNetworkMonitor now provides information about metered networks + g_mem_set_vtable has been deprecated; it has not been working for quite a while. The recommendation is to use valgrind, or replace malloc itself. * debian/patches/0001-GOptionContext-Don-t-crash-without-main-group.patch: Drop, applied upstream. * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.45.4-2) experimental; urgency=medium . * debian/patches/0001-GOptionContext-Don-t-crash-without-main-group.patch: Cherry-pick. Don't crash in GOptionContext if there's no main group. Fixes crash when running (for example) gdbus. . glib2.0 (2.45.4-1) experimental; urgency=medium . * New upstream release 2.45.4 * d/p/0001-gio-tests-appmonitor-Delete-file-before-checking-for.patch, d/p/0001-glocalfilemonitor-Send-DELETED-event-when-there-is-n.patch: Drop, applied upstream. * d/p/07_disable_tests_on_slow_archs.patch: Refresh to apply cleanly. * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.45.3-1) experimental; urgency=medium . [ Simon McVittie ] * d/p/regex-if-PCRE-is-8.34-or-later-disable-auto-possessi.patch: mark as applied upstream in 2.45.3 . [ Iain Lane ] * New upstream release 2.45.3. + Improve performance of g_signal_handler_disconnect for signals with many handlers + GDBus has gained a new call flag to allow interactive authorization + GSettings: - New API: g_settings_schema_list_keys - Deprecated: g_settings_list_keys * debian/libglib2.0-0.symbols: Update with new symbols from this release. * debian/patches/regex-if-PCRE-is-8.34-or-later-disable-auto-possessi.patch: Delete, applied upstream. * d/p/0001-gio-tests-appmonitor-Delete-file-before-checking-for.patch: Cherry-pick upstream patch to fix testsuite failure causing FTBFS. . glib2.0 (2.45.2-1) experimental; urgency=medium . [ Simon McVittie ] * Correctly attribute previous upload to Iain * d/p/0001-Fix-trashing-on-overlayfs.patch: add upstream bug reference * d/p/0001-glocalfilemonitor-Send-DELETED-event-when-there-is-n.patch: add upstream bug reference * d/p/10_kfreebsd_issetugid_prototype.patch, d/p/11_kfreebsd_pthread_condattr_setclock_prototype.patch, d/p/13_sparc_prlimit_prototype.patch: drop workarounds for #635205, #703545, #703559 which were all fixed in jessie * d/p/81-skip-monitor-test-on-non-linux.patch: add DEP-3 information * d/p/90_gio-modules-multiarch-compat.patch: add DEP-3 information . [ Iain Lane ] * New upstream release 2.45.2 + Improve error reporting in glib-compile-schemas. + Add introspection annotations to GListStore. * GDBus-tests-change-progress-noise-from-if-not-quiet-.patch, gdbus-tests-wait-up-to-60s-for-gdbus-testserver-to-t.patch, gdbus-connection-wait-up-to-10s-to-actually-send-a-m.patch, regex-test-do-not-assert-that-system-PCRE-still-has-.patch, gdbus-serialization-use-check_serialization-instead-.patch, gdbus-peer-test-let-GDBusServer-start-before-notifyi.patch, gdatetime-test-don-t-assume-that-time-stands-still.patch: Delete, applied upstream. * 07_disable_tests_on_slow_archs.patch: Refresh to defuzz . glib2.0 (2.45.1-2) experimental; urgency=medium . [ Simon McVittie ] * d/p/regex-if-PCRE-is-8.34-or-later-disable-auto-possessi.patch: update to my latest version submitted upstream, which fixes undefined behaviour in the unlikely event that G_REGEX_OPTIMIZE is combined with g_regex_match_all(). * d/p/regex-test-do-not-assert-that-system-PCRE-still-has-.patch: update to my latest version submitted upstream, which asserts that a newer-than-8.32 system PCRE does not have the bug in question. * d/p/gdbus-serialization-use-check_serialization-instead-.patch: add patch to fix FTBFS in non-minimal environments (libdbus-1-dev installed). Applied upstream for 2.45.2. . [ Iain Lane ] * d/p/0001-Fix-trashing-on-overlayfs.patch: Take patch from upstream bug to fix trashing on overlayfs. * d/p/0001-glocalfilemonitor-Send-DELETED-event-when-there-is-n.patch: Take patch from upstream bug to send the right event when moving files outside a monitored directory. . glib2.0 (2.45.1-1) experimental; urgency=medium . * New upstream release 2.45.1 + The GSettings schema compiler, glib-compile-schemas has been changed to reject schema xml that has duplicate or elements. Such elements typically occur when translations are merged into the schema, with xml:lang attributes. This is not the correct way to translate schemas. Instead keep the translations in the .mo file and set the gettext-domain attribute on the element. To avoid breaking already-installed schemas, this change is only taking effect when you use the --strict option. + The file monitoring infrastructure has been rewritten, and all backends have seen major improvements. + The inotify backend is reporting events with less delay (no event will be delayed more than 10ms) and wakeups due to file monitoring have been significantly reduced. A CHANGES_DONE event will also be sent when new files appear. + The poll implementation is now using the thread default main context. + The fam implmentation is now running in the worker thread. + The fen implementation has been removed, since it was unmaintained. + The hardcoded 10-thread limit of GTask's thread pool has been removed, since it was prone to causing deadlocks. The thread pool is now allowed to grow dynamically and will shrink back over time. + GSimpleAsyncResult has been deprecated in favor of GTask. + The algorithm used by GAppInfo to find default handlers for mime types has been tweaked to prefer apps that handle the specific subtype over default handlers for a generic supertype. * d/p/regex-test-do-not-assert-that-system-PCRE-allows-P-1.patch: Drop, applied upstream. * debian/control{,.in}: Update Vcs-* for experimental. * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.44.1-1) unstable; urgency=medium . * New upstream release 2.44.1 + Improve the default application algorithm + Bump the number of children a GType can have + Various testsuite improvements . glib2.0 (2.44.0-3) unstable; urgency=medium . * Team upload. . [ Simon McVittie ] * d/p/regex-test-do-not-assert-that-system-PCRE-allows-P-1.patch: update to the version that went upstream in 2.45.1. No functional change. * d/p/regex-if-PCRE-is-8.34-or-later-disable-auto-possessi.patch: update to my latest version submitted upstream, which fixes undefined behaviour in the unlikely event that G_REGEX_OPTIMIZE is combined with g_regex_match_all(). * d/p/regex-test-do-not-assert-that-system-PCRE-still-has-.patch: update to my latest version submitted upstream, which asserts that a newer-than-8.32 system PCRE does not have the bug in question. * d/p/gdbus-serialization-use-check_serialization-instead-.patch: add patch to fix FTBFS in non-minimal environments (libdbus-1-dev installed). Applied upstream for 2.45.2. * d/p/gdbus-peer-test-let-GDBusServer-start-before-notifyi.patch: add patch fixing a race condition in the gdbus-peer test. Applied upstream for 2.45.2. * d/p/GDBus-tests-change-progress-noise-from-if-not-quiet-.patch: add patch fixing potential test failures caused by corrupt TAP output. Applied upstream for 2.45.2. * d/p/gdatetime-test-don-t-assume-that-time-stands-still.patch: add patch fixing potential test failures at the boundary between one second and the next. Applied upstream for 2.45.2. * d/p/10_kfreebsd_issetugid_prototype.patch, d/p/11_kfreebsd_pthread_condattr_setclock_prototype.patch, d/p/13_sparc_prlimit_prototype.patch: drop workarounds for #635205, #703545, #703559 which were all fixed in jessie * d/p/81-skip-monitor-test-on-non-linux.patch: add DEP-3 information * d/p/90_gio-modules-multiarch-compat.patch: add DEP-3 information . [ Iain Lane ] * d/p/0001-Fix-trashing-on-overlayfs.patch: Take patch from upstream bug to fix trashing on overlayfs. . glib2.0 (2.44.0-2) unstable; urgency=medium . * Upload to unstable. * debian/watch: Consider stable versions only. . glib2.0 (2.44.0-1) experimental; urgency=medium . * New upstream release 2.44.0 + gsocket: Document FD ownership with g_socket_new_from_fd() . glib2.0 (2.43.92-1) experimental; urgency=medium . * New upstream release 2.43.92 + GUnixMountMonitor now properly supports multiple main contexts + many documentation improvements and cleanups. + new support for HTTP proxies in GIO + new GTask:completed property + use "private" futexes in order to further improve the performance of the contended case of GMutex and g_bit_lock() * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.43.91-1) experimental; urgency=medium . * New upstream release 2.43.91 - We have now added 'g_autofree' as a libgsystem-style autocleanup macro that calls g_free() on the content of a local variable when it leaves scope (working only on GCC and clang). - GApplication now has an "is-busy" property, allowing one to query the effective busy state. * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.43.90-1) experimental; urgency=medium . * New upstream release 2.43.90 + new GSimpleIOStream class to construct a GIOStream from an arbitrary GInputStream and GOutputStream + GApplication: new API for marking 'busy' state according to the value of a boolean property on another object + GOptionGroup: add binding support (boxed type, annotation fixes, etc.) * debian/patches/gdbus-Let-the-pending-read-finish-before-closing-the.patch: Drop this cherry-pick from an upstream bug - should be fixed differently in this release (bgo #743990). * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.43.4-1) experimental; urgency=medium . * New upstream release 2.43.4 + GType now has type declaration macros G_DECLARE_DERIVABLE_TYPE, G_DECLARE_FINAL_TYPE and G_DECLARE_INTERFACE, which significantly reduce the boilerplate needed for GObject types and interfaces. + g_autoptr and g_auto are macros for declaring variables with automatic cleanup. They only work with gcc and clang. + GListModel is a new interface that represents a dynamic list of GObjects. + GListStore is a GSequence-based implementation of GListModel. + g_simple_action_set_state_hint: New function to set the state hint of GSimpleActions + g_settings_schema_list_children and g_settings_schema_key_get_name are new functions to complete the GSettingsSchema API. * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.43.3-1) experimental; urgency=medium . [ Laurent Bigonville ] * debian/control.in, debian/libglib2.0-dev.install.in, debian/libglib2.0-0-dbg.install.in: Install the gdb python scripts in the proper locations, move them to the -dbg package and add the needed Breaks/Replaces (Closes: #774024) . [ Iain Lane ] * New upstream release 2.43.3 + add g_set_object() convenience function + GNetworkMonitor: check if NM is not running and don't crash + fix some races with g_mkdir_with_parents + avoid use of G_STRLOC in G_OBJECT_WARN_INVALID_PSPEC in order to save on static strings + fix some content type vs. mime issues * 07_disable_tests_on_slow_archs.patch: Refresh . glib2.0 (2.43.2-1) experimental; urgency=medium . [ Laurent Bigonville ] * debian/control.in: Switch build-dependency from libelfg0-dev to libelf-dev (Closes: #769408) . [ Iain Lane ] * New upstream release 2.43.2 + New function: g_strv_contains + New function: g_network_address_new_loopback + New function: g_socket_send_messages + A new GNetworkMonitor implementation using NetworkManager provides more detailed connectivity information * 0001-GSettings-fix-check-for-delaying-backend-subscriptio.patch, 0001-gmain-fix-poll-record-comparison.patch: gmain: fix the sorting of: Drop, applied in this release. * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.43.1-2) experimental; urgency=medium . * 0001-GSettings-fix-check-for-delaying-backend-subscriptio.patch: Cherry-pick patch from upstream. Check signal detail too when looking for pending signal handlers, so that subscribing to changed signals with a detail works again. * 0001-gmain-fix-poll-record-comparison.patch: gmain: fix the sorting of poll records. Resolves FTBFS on ppc64el. . glib2.0 (2.43.1-1) experimental; urgency=medium . * New upstream release 2.43.1, changes since 2.42.1: + GQueue now accepts NULL as a sibling in g_queue_insert_before() and g_queue_insert_after() + GObject gained a debug option to provide instance counts. To use it, set GOBJECT_DEBUG=instance-count and call g_type_get_instance_count(). + GOption now has a strict POSIX mode in which it stops parsing arguments as soon as a non-option argument is encountered. * debian/control{,.in}: Bump Standards-Version to 3.9.6, no changes required. * debian/libglib2.0-0.symbols: Add new symbols for this release. . glib2.0 (2.42.1-1) unstable; urgency=medium . [ Iain Lane ] * Pass --enable-debug=minimum not minimal - this is what configure.ac expects. . [ Emilio Pozuelo Monfort ] * New upstream bugfix release. * d/p/0001-properties-disable-default-deprecation-warnings.patch: + Removed, merged upstream. . glib2.0 (2.42.0-2) unstable; urgency=medium . [ Andreas Henriksson ] * Update Vcs-* to use unstable instead of experimental branch . [ Iain Lane ] * 0001-properties-disable-default-deprecation-warnings.patch: Backport from upstream stable branch - silences warnings that are shown to users on stderr, and which also cause some testsuite failures and consequent FTBFS. . glib2.0 (2.42.0-1) unstable; urgency=medium . * New upstream release . glib2.0 (2.41.5-2) unstable; urgency=medium . * Upload to unstable. . glib2.0 (2.41.5-1) experimental; urgency=medium . [ Andreas Henriksson ] * Make libglib2.0-0 recommend xdg-user-dirs - needed to set up ~/.config/user-dirs.dirs to get default XDG_*_DIR set. . [ Iain Lane ] * New upstream release 2.41.5 - GDesktopAppInfo: avoid polling on missing desktop dirs . glib2.0 (2.41.4-1) experimental; urgency=medium . * New upstream release * debian/libglib2.0-0.symbols: + Add g_application_add_main_option symbol . glib2.0 (2.41.3-1) experimental; urgency=medium . * New upstream release 2.41.3 * debian/tests/installed-tests: Revert the previous change - require dbus >= 1.8 and always use dbus-run-session. . glib2.0 (2.41.2-1) experimental; urgency=medium . * New upstream release - The Unicode support has been updated to version 7.0 of the Unicode standard - GNotification now supports priorities for notifications - GMutex now uses a faster, native implementation on Linux * 0001-gvariant-tests-workaround-libc-compiler-issue.patch: Drop, applied upstream in this release. * Add new symbols for this release. * Merge in changes from 2.40.0-4 + Adapt for system pcre3/1:8.35 (Closes: #755439): - a PCRE 8.31 bug in case-insensitivity has been fixed, so do not assert bug-for-bug compatibility with 8.31 - named match groups' names cannot start with a digit any more, so (?P<1>.) is no longer allowed; do not assert that it is - turn off a new optimization that would reduce the result set when called from g_match_all(_full), to preserve existing functionality + Build-depend on pcre3/1:8.35 so that the new optimization is known to be turned off in the built binaries + Add patch from upstream to fix mis-optimization in gvariant test with gcc 4.9 (Closes: #756272) + Avoid using dbus-launch for regression tests (Closes: #737488): - run installed-tests under dbus-run-session from dbus (>= 1.8) - do not run build-time tests under dbus-launch: those that use D-Bus all create their own session bus instances now (i.e. remove 05_run-gio-tests-with-a-dbus-session.patch) - set a deliberately invalid DBUS_SESSION_BUS_ADDRESS to make sure nothing in the build is still inheriting it from the environment + Override Lintian false positive #733733: we build-depend on python:any but Lintian doesn't yet understand :any syntax * Make the installed tests still run dbus-launch if we don't have dbus-run-session (i.e. if the installed dbus is << 1.8). . glib2.0 (2.41.1-2) experimental; urgency=medium . * 0001-gvariant-tests-workaround-libc-compiler-issue.patch: Cherry-pick patch from upstream to fix/workaround a new compiler optimisation in gcc-4.9 which occurs when passing a null pointer / zero size to memcmp. Should fix FTBFS on many arches in unstable. . glib2.0 (2.41.1-1) experimental; urgency=medium . * New upstream release * 0001-Prevent-an-invalid-CARBON_LIBS-from-appearing-in-the.patch: Drop, included in this release. * Update symbols file with the new symbol in this release. . glib2.0 (2.41.0-2) experimental; urgency=medium . [ Andreas Henriksson ] * Bump python:any build-dependency to >= 2.7.5-5~ (Closes: #747928) . [ Emilio Pozuelo Monfort ] * Use the default compiler on sparc, since it's already >> 4.7. Closes: #751313. . [ Iain Lane ] * 0001-Prevent-an-invalid-CARBON_LIBS-from-appearing-in-the.patch: Cherry-pick patch from upstream to fix an invalid "@CARBON_LIBS@" token appearing in Libs.private in the pcfile. (LP: #1330033) . glib2.0 (2.41.0-1) experimental; urgency=medium . [ Emilio Pozuelo Monfort ] * debian/libglib2.0-doc.links: + The symlink for the gtk docs is broken at the moment, and even if fixed, it will still be broken if libgtk2.0-doc isn't installed on a system, so just drop it. Closes: #746782. . [ Iain Lane ] * New upstream release 2.41.0 - Many bugfixes found by static analysis, including potential fd leaks and NULL pointer dereferences. - Increased use of (nullable) attribute on out values and return types now that it is supported (mostly from porting Vala metadata). - use XDG_CURRENT_DESKTOP for OnlyShowIn/NotShowIn handling of desktop files, deprecating g_desktop_app_info_set_desktop_env() - add support for g_desktop_app_info_get_implementations() to find desktop files that have an Implements= line for a given interface - GHmac has gained SHA-512 support - support the new mimeapps specification (most notably, moving the assoications/defaults configuration to ~/.config/mimeapps.list). - libgobject is now linked -Wl,-z,nodelete when possible to avoid errors when gobject is used from a module for a program that does not itself use gobject and that module is unloaded/reloaded * debian/watch: Use http://ftp.gnome.org; it's more up-to-date. * Update symbols file with new symbols for this release. . glib2.0 (2.40.0-4) unstable; urgency=medium . * Team upload . [ Emilio Pozuelo Monfort ] * Use the default compiler on sparc, since it's already >> 4.7. Closes: #751313. . [ Iain Lane ] * Fix Vcs-* for the unstable branches . [ Simon McVittie ] * Adapt for system pcre3/1:8.35 (Closes: #755439): - a PCRE 8.31 bug in case-insensitivity has been fixed, so do not assert bug-for-bug compatibility with 8.31 - named match groups' names cannot start with a digit any more, so (?P<1>.) is no longer allowed; do not assert that it is - turn off a new optimization that would reduce the result set when called from g_match_all(_full), to preserve existing functionality * Build-depend on pcre3/1:8.35 so that the new optimization is known to be turned off in the built binaries * Add patch from upstream to fix mis-optimization in gvariant test with gcc 4.9 (Closes: #756272) * Avoid using dbus-launch for regression tests (Closes: #737488): - run installed-tests under dbus-run-session from dbus (>= 1.8) - do not run build-time tests under dbus-launch: those that use D-Bus all create their own session bus instances now (i.e. remove 05_run-gio-tests-with-a-dbus-session.patch) - set a deliberately invalid DBUS_SESSION_BUS_ADDRESS to make sure nothing in the build is still inheriting it from the environment * Override Lintian false positive #733733: we build-depend on python:any but Lintian doesn't yet understand :any syntax . glib2.0 (2.40.0-3) unstable; urgency=medium . [ Rico Tzschichholz ] * debian/libglib2.0-bin.install: - Install /usr/bin/gapplication . glib2.0 (2.40.0-2) unstable; urgency=medium . [ Iain Lane ] * gdbus-tests-wait-up-to-60s-for-gdbus-testserver-to-t.patch: Take latest version from upstream bug to resolve some test failures. * Add xauth test-dep, needed for xvfb-run . [ Emilio Pozuelo Monfort ] * Upload to unstable. . glib2.0 (2.40.0-1) experimental; urgency=medium . * New upstream release. . glib2.0 (2.39.92-2) experimental; urgency=medium . * test_timer_basic is still broken. Skip it. . glib2.0 (2.39.92-1) experimental; urgency=medium . * New upstream release. * 0001-timer-test-use-volatile-for-locals.patch: Take patch from bgo #722604 to workaround gcc's intentional spec violation in the timer tests. + Remove debian/patches/80-skip-timer-test.patch accordingly; it should now work. . glib2.0 (2.39.91-1) experimental; urgency=medium . * New upstream release. * d/p/0001-asyncqueue-fix-timeout-math-on-32bit-systems.patch: + Dropped, merged upstream. * debian/patches/81-skip-monitor-test-on-non-linux.patch: + New patch, skip the monitor test on non-linux as it currently hangs. * debian/libglib2.0-0.symbols: + Add a new symbol. . glib2.0 (2.39.90-2) experimental; urgency=medium . * debian/control.in: + Bump gtk-doc-tools build-dependency per configure.ac. * debian/patches/Don-t-use-a-parallel-build-for-the-documentation.patch: + Removed, no longer needed with gtk-doc 1.20. * d/p/0001-asyncqueue-fix-timeout-math-on-32bit-systems.patch: + Patch from git, fix an overflow in g_async_queue_timed_pop_unlocked on 32 bits systems. * debian/patches/80-skip-timer-test.patch: + Skip the timer test which currently fails on x86 because of float precission errors. * debian/rules: + Make the test suite fatal on linux. + Run the test suite on !linux, but ignore test suite errors for now. . glib2.0 (2.39.90-1) experimental; urgency=medium . * New upstream release. * Drop patches now included in upstream release: - 0001-glib-tests-collate.c-run-to-completion-when-skipping.patch - 0002-g_test_run-return-0-if-all-tests-are-skipped-in-TAP-.patch * Fix fuzz to make debian/patches/04_homedir_env.patch apply again. * Use quilt to refresh remaining patches. * debian/libglib2.0-0.symbols: Add new symbols. . glib2.0 (2.39.4-1) experimental; urgency=medium . * New upstream development release. * debian/rules: + Tell dh_clean not to remove org.gtk.test.gschema.xml.orig, otherwise the build fails as that fail is missing. Apparently dh_clean removes everything that ends with .orig. * debian/libglib2.0-0.symbols: + Add new symbols. * d/p/valgrind_h_add_r0_to_the_clobber_list_on_PPC.patch, d/p/tests-move-param-implement-to-m-slow.patch, d/p/Fix-races-in-unix-signal-dispatch.patch: + Dropped, applied upstream. * d/p/0001-glib-tests-collate.c-run-to-completion-when-skipping.patch, d/p/0002-g_test_run-return-0-if-all-tests-are-skipped-in-TAP-.patch: + Add patches from upstream to fix test suite errors. * debian/patches/*: + Refreshed. * debian/rules: + Don't run the test suite in parallel as some tests fail otherwise. + Ignore test suite errors for now. There are a few known racy tests that fail randomly, and I'm more interested in whether glib builds fine everywhere. We should make the tests fatal again before 2.40. . glib2.0 (2.38.2-5) unstable; urgency=medium . * Upload to unstable. . glib2.0 (2.38.2-4) experimental; urgency=medium . * Team upload * DEP-3: tag patch for Debian#737501 as sent upstream to GNOME#723653 * d/p/gdbus-Let-the-pending-read-finish-before-closing-the.patch: add patch from Mikhail Zabaluev fixing a test failure on mips, also reproduced on mipsel (Closes: #738290) * d/p/Fix-races-in-unix-signal-dispatch.patch: add patch from upstream to fix what appears to be the root cause of #737380 * d/p/gdbus-tests-wait-up-to-60s-for-gdbus-testserver-to-t.patch, d/p/gdbus-connection-wait-up-to-10s-to-actually-send-a-m.patch: improve arbitrary timeouts in regression tests, fixing an unreported FTBFS on armhf . glib2.0 (2.38.2-3) experimental; urgency=medium . * Team upload * d/p/Don-t-use-a-parallel-build-for-the-documentation.patch: Disable parallel build for the documentation, hopefully fixing an intermittent FTBFS in which gtk-doc tries to scan Windows-specific objects (Closes: #737501) * d/p/Do-not-attempt-to-autolaunch-a-session-dbus-daemon-w.patch: Refuse to perform D-Bus "autolaunch" if $DISPLAY is unset, in which case it isn't going to work anyway. This works around a process-launching issue in the GApplication test on mipsel (Closes: #737380) * Bump debhelper compat level to 9, resulting in co-installable multiarch debug symbols and ~ 50% smaller installed size for libglib2.0-0-dbg (at the cost of ~ 30% larger .deb size) - mark libglib2.0-0-dbg Multi-Arch: same . glib2.0 (2.38.2-2) experimental; urgency=medium . * Team upload. . [ Emilio Pozuelo Monfort ] * debian/rules: + Enable parallel builds. . [ Laurent Bigonville ] * Add d/p/valgrind_h_add_r0_to_the_clobber_list_on_PPC.patch: Fix FTBFS on PPC (taken from upstream, Closes: #737379) . [ Simon McVittie ] * Add DEP-3 tagging to PPC patch * Add d/p/tests-move-param-implement-to-m-slow.patch to knock out test /param/implement, which upstream describe as "essentially a forkbomb", leading to failures on armel and at least sporadically on mipsel (Closes: #737381) . glib2.0 (2.38.2-1) experimental; urgency=low . * New upstream release - Drop d/p/0001-g_file_copy-Fall-back-to-pathname-queryinfo-to-help-.patch merged upstream * debian/control.in: - Bump Standards-Version to 3.9.5 (no further changes) - Use canonical URL for Vcs-Svn field . glib2.0 (2.38.1-2) experimental; urgency=low . * debian/rules: + Set VERBOSE so we get failing tests' stdout and stderr. This will help us debug the various build failures in different arches. . glib2.0 (2.38.1-1) experimental; urgency=low . * Build-Depend on python:any. python is Multi-Arch: allowed; this BD allows the python from any architecture that can be executed on the builder to satisfy the BD, simplifying cross building of glib2.0. * New upstream bugfix release 2.38.1 + Fix error code checks when SOCK_CLOEXEC is defined but not supported (fix support for GNU/Hurd) + g_settings_list_children: only list viable schemas (fix gsettings list-recursively crashes with invalid schemas installed) + GDBusObjectManagerClient: Fix typo in the /org/freedesktop/DBus path when adding match rules - Remove 0001-gio-Fix-typo-in-the-org-freedesktop-DBus-path.patch * 0001-g_file_copy-Fall-back-to-pathname-queryinfo-to-help-.patch: Cherry-pick gio patch to fall back to g_file_query_info if query_info_on_read is not supported. Fixes copying from backends that don't implement the latter. (Closes: #715436, LP: #1217230) . glib2.0 (2.38.0-1) experimental; urgency=low . * New upstream release * debian/patches/0001-gio-Fix-typo-in-the-org-freedesktop-DBus-path.patch: Cherry-pick patch from upstream to fix object path typo in gio (LP: #1227295) * Add --enable-debug=minimal explicitly to the deb build so the debugging level doesn't change between pre-release and stable versions. . glib2.0 (2.37.93-1) experimental; urgency=low . * New upstream release 2.37.93 (& .92) + new API g_file_measure_disk_usage() similar to du(1) * Add new symbols for g_file_measure_disk_usage API added in this release. . glib2.0 (2.37.7-1) experimental; urgency=low . * New upstream 2.37.7 + GDateTime now supports %:z formatting variations for timezones. This is a GNU date extension. . glib2.0 (2.37.6-1) experimental; urgency=low . * New upstream release 2.37.6 * Update symbols file * Merge changes from unstable, mainly for build / testsuite fixes. . glib2.0 (2.37.5-1) experimental; urgency=low . * New upstream release 2.37.5 (including interesting changes from .3 and .4) + Implement the Desktop Action specification + The gsettings tool now reports failure to write a key (e.g. because the key was locked down) + add a new API for instance private data: G_DEFINE_TYPE_WITH_PRIVATE + add new D-Bus API for async property handling * libglib2.0-tests: Depend on shared-mime-info required by contenttype test. * New upstream release * 0001-Revert-g_file_set_contents-don-t-fsync-on-ext3-4.patch: Drop, now upstream. * debian/tests/installed-tests: Add a new DEP-8 test to run the installed-tests. * Refresh patches. * Update symbols file. * debian/patches/skip-brokwn-dbus-appinfo-test.patch: Skip a broken new dbus-appinfo test which is hanging. . glib2.0 (2.37.2-1) experimental; urgency=low . * New upstream version + add support for installed tests: https://live.gnome.org/GnomeGoals/InstalledTests + add a new g_test_trap_subprocess() that works on Windows as a replacement for the (now deprecated) g_test_trap_fork() + support for explicitly cancelling a gobject property binding + performance improvements for signal argument handling + stop using `quotes' in very many log messages generated by GLib, for favour of 'this style'. This may cause testcases in other packages to fail if they were matching on the previous text. + improve manpages: add missing arguments and flags + Installing properties after class initialization is deprecated, and will trigger a warning. + GApplication Support org.freedesktop.Application, including D-Bus activation from desktop files * Refresh patches. * Update symbols file with new symbols in this release. * Enable installed tests and install into a libglib2.0-tests package. * clean debian/{install,build,stamp-makefile-check} and gio/gdbus-2.0/codegen/*.pyc * Set $XDG_RUNTIME_DIR to a writable directory we control; now required by the testsuite. . glib2.0 (2.36.4-1) unstable; urgency=low . * New upstream release. * Remove 0001-Revert-g_file_set_contents-don-t-fsync-on-ext3-4.patch, merged upstream. * Make test suite linux only again. On kfreebsd the test suite keeps getting stuck and the build is killed after a timeout. . glib2.0 (2.36.3-4) unstable; urgency=low . [ Josselin Mouette ] * Still run the testsuite on !linux, even though non-fatal. . [ Michael Biebl ] * Track stable releases. * Use dh_python2 to properly generate the dependencies for gdbus-codegen, which is shipped in libglib2.0-dev. . glib2.0 (2.36.3-3) unstable; urgency=low . [ Julien Cristau ] * Use gcc-4.8 on sparc to fix misbuild causing test failure (closes: #709781). . [ Josselin Mouette ] * Only make the testsuite fatal on linux. Although the other architectures don’t pass, we have to keep a pair of reverse dependencies working. . glib2.0 (2.36.3-2) unstable; urgency=low . * 0001-Revert-g_file_set_contents-don-t-fsync-on-ext3-4.patch: + Patch from the upstream 2.36 stable branch. Revert a previous commit that dropped calls to fsync() on ext[234] fileystems as that caused data corruption in some cases (e.g. corrupted dconf db on power loss). . glib2.0 (2.36.3-1) unstable; urgency=low . [ Josselin Mouette ] * Make the testsuite fatal on all architectures. If it fails, we need to fix it or drop the architecture, not to ignore it. * Break libgnome-desktop-3-2 < 3.4.2-2 for the thumbnails location change. . [ Emilio Pozuelo Monfort ] * New upstream bugfix release. Closes: #708568. * debian/patches/13_sparc_prlimit_prototype.patch: + Refreshed. . glib2.0 (2.36.1-2) unstable; urgency=low . * Merge experimental branch, upload to unstable. . glib2.0 (2.36.1-1) experimental; urgency=low . * New upstream release * Refresh debian/patches/06_thread_test_ignore_prctl_fail.patch . glib2.0 (2.36.0-2) experimental; urgency=low . * debian/rules: + Don't abort the build if the test suite fails on mipsel. * debian/patches/17_check_abis_mips_symbols.patch: + Also allow _ftext in libgthread. . glib2.0 (2.36.0-1) experimental; urgency=low . * New upstream release. + debian/libglib2.0-0.symbols: - Updated. * debian/rules: + Make the test suite fatal in armel and armhf. * debian/patches/17_check_abis_mips_symbols.patch: + Add _ftext to the list of allowed symbols, since that is leaked on mips. . glib2.0 (2.35.9-2) experimental; urgency=low . * d/p/11_kfreebsd_pthread_condattr_setclock_prototype.patch: + Another patch to fix the build on kfreebsd. Add a prototype for pthread_condattr_setclock() when building on kfreebsd since the prototype there is missing. The glibc bug to add the missing prototype is #703545, we can remove this hack when that is fixed. * debian/patches/13_sparc_prlimit_prototype.patch: + New patch, only use prlimit if the prototype is available. Should fix the build on sparc where prlimit is available but the prototype is missing. Thanks to Julien Cristau for the patch. This works-around #703559 and can be removed when that bug is fixed. * debian/patches/15_gio_desktop_app_info_test_bin_true_path.patch: + Change path for 'true' to /bin/true as that's where it is in Debian. This fixes a testcase that was failing on every arch and was causing the build to fail on ia64 and powerpc as test failures are fatal on those arches. * debian/rules: + Use filter instead of findstring to match the current arch against the list of architectures where the test suite should not be fatal, as the latter matches substrings and so it was making the testsuite non-fatal on amd64 and i386 because they match kfreebsd-amd64 and kfreebsd-i386. . glib2.0 (2.35.9-1) experimental; urgency=low . * debian/control.in: + Break python-gi (<< 3.7.2). Closes: #702603. * New upstream release. + debian/patches/04_homedir_env.patch: - Updated to apply again. * debian/rules: + Set HOME instead G_HOME, as GLib now honors the former. We will eventually remove our local patch to support G_HOME, so packages that need to override the home directory for the test suite should switch to overriding HOME. * debian/libglib2.0-0.symbols: + Bump minimum version for g_get_home_dir() so that users that need HOME to be honored get a proper runtime dependency. * debian/patches/10_kfreebsd_issetugid_prototype.patch: + Untested patch to fix the build on kfreebsd. . glib2.0 (2.35.8-1) experimental; urgency=low . [ Matthias Klose ] * Configure cross builds with --disable-modular-tests --disable-gtk-doc. . [ Iain Lane ] * Merges from unstable branch (Michael Biebl) - Take into account multiarch when removing the cache files in postrm: Remove /usr/lib/gio/modules/giomodule.cache only for the native architecture for which this cache file was created. After removing /usr/share/glib-2.0/schemas/gschemas.compiled on purge, run dpkg-trigger explicitly, so in case libglib2.0-0 is installed for other architectures, the cache file is re-created. (Closes: #696389) - Drop the various Breaks from libglib2.0-0. Those are causing APT to fail on a dist-upgrade from squeeze to wheezy. (Closes: #676485) * Refresh patches and slightly rework debian/patches/04_homedir_env.patch: g_get_home_dir() now respects the HOME environment variable but we'll keep G_HOME for now as packages in Debian rely on it. * gdbus-codegen .py files have moved to /usr/share/glib-2.0 * Update symbols file . [ Martin Pitt ] * New upstream release 2.35.4 * debian/libglib2.0-0.symbols: Update for new upstream release. * Drop 08_disable_gapplication_basic_test.patch, test is now more robust. * Drop 92_revert_appinfo_command_line.patch and add xterm build dependency; xterm is rather lightweight in terms of dependencies and is sufficient to run all the "Terminal=true" tests. * Add 08_fix_closure_invalidation.patch: gsignal: fix closure invalidation code. (GNOME #690118) . [ Emilio Pozuelo Monfort ] * New upstream release 2.35.8. + debian/patches/08_fix_closure_invalidation.patch: - Removed, applied upstream. + debian/patches/*: - Refreshed. + debian/libglib2.0-0.symbols: - Updated for the new symbols. . glib2.0 (2.34.3-1) experimental; urgency=low . * New upstream release. . glib2.0 (2.34.2-1) experimental; urgency=low . * Team upload . [ Martin Pitt ] * debian/rules: Re-enable failing the build on failed tests on armel/armhf on Ubuntu, now that the buildds behave themselves again. . [ Simon McVittie ] * New upstream release - 50_git_gmenuexporter_allow_null_bus_on_name_vanished.patch: remove, applied upstream - 91_kfreebsd_credentials.patch: remove, applied upstream * Override a couple of package-contains-empty-directory lintian tags for deliberate empty directories * Override package-contains-devhelp-file-without-symlink lintian tag for gdbus-object-manager-example, which is deliberately not in devhelp . glib2.0 (2.34.1-2) experimental; urgency=low . * Team upload * Apply patch from unstable to use the FreeBSD credentials-passing code path on kFreeBSD too, fixing (at least) gnome-terminal and lightdm on kFreeBSD (Closes: #581750, #631968) . glib2.0 (2.34.1-1) experimental; urgency=low . [ Josselin Mouette ] * Require libelfg0-dev, not libelf-dev which has nothing to do with it. . [ Iain Lane ] * New upstream release + GTimeZone support for zoneinfo version 1 + Leak in glib-compile-resources + g_settings_bind: use canonical property name + Port gio tests from pygobject to pygi * Switch python-gobject-2 BD to python-gi, folowing porting of tests. * debian/patches/50_git_gmenuexporter_allow_null_bus_on_name_vanished.patch: Cherry-pick upstream patch to fix crash when GBusNameVanishedCallback is called with a NULL GDBusConnection. (LP: #1044322) . glib2.0 (2.34.0-1) experimental; urgency=low . [ Martin Pitt ] * debian/rules: Only run tests for the main flavour; it takes too long for all three and does not give us a lot of extra confidence. * debian/rules: Manually create debian/stamp-makefile-check, as with above change it's not created automatically any more. * Add 07_disable_tests_on_slow_archs.patch: Disable tests on slow architectures which keep failing the tests. These are currently /socket/timed_wait, /mainloop/timeouts, /mainloop/child_sources, /timeout/rounding, and the upper bound on /gdbus/method-calls-in-thread on ARM platforms. * debian/control.in: Bump pcre dependency to >= 1:8.31. * debian/rules: Seems there is no way of making the test suite work reliably with the upgraded Ubuntu ARM builders, so make tests non-fatal on arm{el,hf} until they get less swap happy. . [ Michael Biebl ] * New upstream release. * Drop debian/patches/91_revert_pcre_8.31_test.patch now that we have a recent enough version. . glib2.0 (2.33.14-1) experimental; urgency=low . [ Iain Lane ] * New upstream release + CVE-2012-3524: don't run dbus-launch from setuid binaries + g_content_type_get_generic_icon_name(): new API for getting the icon name for a mime type + Introspection fixes: - GDBusConnection nullability fixes - give a box type to GTimeZone + Drop GVFS_INOTIFY_DIAG + Add a new "Writing GLib Applications" section to the reference documentation with general info on security, threads, etc. + gwin32mount.c: Fix syntax error + gresource tests: srcdir != builddir fixes + tests/gvariant: Fix test on big endian architectures + Fix regression in g_shell_parse_argv() * Dropped 07_tests_gvariant_big_endian.patch: applied upstream. . [ Michael Biebl ] * Bump all 2.33.x symbol versions to 2.33.14 to ensure a tight enough dependency for packages using features from glib 2.33. . glib2.0 (2.33.12-4) experimental; urgency=low . * debian/patches/03_disble_glib_compile_schemas_warning.patch: Add a new patch to disable a warning when compiling schemas which are installed into 'deprecated' locations. Users see this very often due to glib-compile-schemas being called from libglib2.0-0's trigger and it is not very useful for them. . glib2.0 (2.33.12-3) experimental; urgency=low . * debian/control.in: Add Breaks: too glib-networking versions prior to 2.33.12. (LP: #1046319) * debian/rules: Ignore test case failures on hurd-i386 (not a release architecture) and mips (this keeps tripping over a gdbus test race condition). * Replace 07_disable_gvariant_checksum_tests.patch with 07_tests_gvariant_big_endian.patch which fixes the test properly instead of disabling it. Taken from https://bugzilla.gnome.org/show_bug.cgi?id=683384 . glib2.0 (2.33.12-2) experimental; urgency=low . * Drop 10_increase_gapplication_test_delay.patch. We disable the whole test now anyway (08_disable_gapplication_basic_test.patch). * Add 07_disable_gvariant_checksum_tests.patch: 2.33.12 introduced two new checks for GVariant checksum stability. This does not currently work on big-endian machines (https://bugzilla.gnome.org/show_bug.cgi?id=683384), so disable these tests for now. . glib2.0 (2.33.12-1) experimental; urgency=low . [ Sebastien Bacher ] * New upstream version * debian/libglib2.0-0.symbols: - updated * revert_g_file_make_directory_with_parents_error_propagation.patch: - dropped, the issue is fixed in the new version * debian/patches/92_revert_appinfo_command_line.patch: - don't require a vte for test, we don't want an xorg stack there . [ Iain Lane ] * Add revert_g_file_make_directory_with_parents_error_propagation.patch: This reverts upstream commit b0bce4ad41937dabf7e5c94dcce3caf4e88f3f97 which caused applications to segfault. The proper fix will be in the next glib release, so this patch should be dropped then. (LP: #1035688) . [ Martin Pitt ] * Add 07_test_method_calls_on_proxy_bump_max_time.patch: On slower platforms, the overhead of the 240 D-BUS Sleep calls is larger than the current maximum of 6 seconds. Bump maximum time to 8 seconds to be more resilient to this. * Add 08_disable_gapplication_basic_test.patch: Disable /gapplication/basic test. It's full of race conditions and keeps breaking builds. . [ Robert Ancell ] * New upstream bugfix release (LP: #1045608) * Drop 07_test_method_calls_on_proxy_bump_max_time.patch: - Applied upstream . glib2.0 (2.33.8-1) experimental; urgency=low . * New upstream release 2.33.8. - GIO now has a g_file_delete_async function - The defaults for GThreadPools max_unused_threads and max_idle_time values have been changed to 2 and 15*1000, respectively. * debian/control{,.in}: XC-Package-Type → Package-Type, thanks to Lintian. * debian/libglib2.0-0.symbols: Update for new symbols in this release and remove Debian revisions which aren't necessary. . glib2.0 (2.33.6-1) experimental; urgency=low . * New upstream release. * Drop 91_revert_schema_path_warning.patch now, we are not in final freeze in Ubuntu, and this is not aimed at Debian Wheezy. * Add 91_revert_pcre_8.31_test.patch: Revert new regex test from 2.33.4 which depends on pcre 8.31. We still have 8.30, and we are building against the system library instead of the bundled one. . glib2.0 (2.33.4-1) experimental; urgency=low . [ Martin Pitt ] * debian/rules: Make tests always fatal on Ubuntu. . [ Iain Lane ] * New upstream release 2.33.4. * Refresh patches to apply cleanly and remove those applied upstream. * Bump version on libpcre-dev BD in line with upstream. * debian/libglib2.0-0.symbols: Add new symbols in this release. . glib2.0 (2.33.3-2) experimental; urgency=low . * Rename 07_socket_test_timespan_jitter.patch to 00git_* and update changelog with what got committed upstream. * Add 07_contenttype_test_fix_overflow.patch: Call g_content_type_guess() with valid data len. Fixes a segfault when running the test. Forwarded to GNOME #674452. * Add 08_contenttype_known_test_failure.patch: Disable known test failure due to a bug in g_content_type_from_mime_type(). For details, see https://bugzilla.gnome.org/show_bug.cgi?id=678941 * Add 09_valuetransform_ulong_bool.patch: valuetransform: Fix definition of ulong_bool. Thanks Philipp Kern! (Closes: #662057) * Add 10_increase_gapplication_test_delay.patch: /gapplication/basic sometimes fails due to a different order of expected and actual actions; increase delay between them to reduce the race condition. Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=664627 * Add 11_timeout_test_reduce_race.patch: Due to load, particular traits of the architecture, or other circumstances, the /mainloop/timeouts sometimes manages to call the "every 100 ms" timer loop only 9 times in 1050 ms. This is an inherent race-condition in the test; allow it some slack and accept 9 times as well. Forwarded to GNOME #678959. . glib2.0 (2.33.3-1) experimental; urgency=low . * New upstream release. * debian/libglib2.0-0.symbols: Add new symbols from this release. * debian/libglib2.0-bin.install: bash completion is now installed into /usr/share/bash-completion/completions/ by upstream. * Add debian/libglib2.0-bin.maintscript: Clean up old bash completion conffiles on upgrade. Add ${misc:Pre-Depends} to libglib2.0-bin. * Add debian/tests/control: DEP-8 autopkgtest control file. Add XS-Testsuite header to debian/control.in. * Add debian/tests/build: autopkgtest check: Build and run a program against glib, to verify that the headers and pkg-config file are installed correctly. * Add 06_thread_test_ignore_prctl_fail.patch: Do not fail the /thread/thread4 test if prctrl() fails. This happens on the Debian buildds. * debian/rules: Set G_HOME to not clutter $HOME with ~/.dbus-keyrings and avoid failure on the buildds where creating /home/buildd/.dbus-keyrings fails. * debian/rules: Fail the build on failed tests, except on architectures with known current failures (arm*, kfreebsd*, s390x, sparc). * Add 07_socket_test_timespan_jitter.patch: On some buildds the poll duration in the /socket/timed_wait test is slightly lower than the requested 100000. Adjust test to not fail in these cases. Forwarded to GNOME #678881. . glib2.0 (2.33.2-1) experimental; urgency=low . * Track unstable versions in the experimental branch. * New upstream release 2.33.2 - GLIB_VERSION_MIN_REQUIRED now defaults to the current stable version - GIO input and output stream classes have grown GBytes-based methods - GApplication now has hooks to register D-Bus objects before the bus name is taken * Refresh 04_homedir_env.patch to cleanly apply * Add the new symbols from this release (g_app_info_get_supported_types, g_*_bytes, g_type_ensure) . glib2.0 (2.33.1-1) experimental; urgency=low . * debian/control.in: Update Vcs-* for experimental branch. * Drop 03_revert_git_single_include_error.patch. For GNOME 3.5.x we want to properly fix the reverse dependencies. NB this is NOT for Debian wheezy. * New upstream release. * 04_homedir_env.patch: Adjust for new release. * Drop 95_configure-Fix-typo-in-ELF-check.patch and 96_configure-Reset-LIBS-after-ELF-check.patch: upstream now. * debian/libglib2.0-0.symbols: Add new symbols from this release. . glib2.0 (2.33.12+really2.32.4-5) unstable; urgency=low . * Fix the closing fi in the if statement in postrm. . glib2.0 (2.33.12+really2.32.4-4) unstable; urgency=low . * Take into account multiarch when removing the cache files in postrm: Remove /usr/lib/gio/modules/giomodule.cache only for the native architecture for which this cache file was created. After removing /usr/share/glib-2.0/schemas/gschemas.compiled on purge, run dpkg-trigger explicitly, so in case libglib2.0-0 is installed for other architectures, the cache file is re-created. (Closes: #696389) * Drop the various Breaks from libglib2.0-0. Those are causing APT to fail on a dist-upgrade from squeeze to wheezy. (Closes: #676485) . glib2.0 (2.33.12+really2.32.4-3) unstable; urgency=low . * Team upload * 92_kfreebsd_credentials.patch: use the FreeBSD credentials-passing implementation on kFreeBSD too, making gnome-terminal and lightdm work on kFreeBSD (Closes: #631968) . glib2.0 (2.33.12+really2.32.4-2) unstable; urgency=medium . * Revert link adding for gdbus-object-manager-example. While it is useful to have in /usr/share/doc as an example, it must not be shipped with the system documentation. * 20_glib-compile-resources_leak.patch: new patch. Fix a leak introduced in version 2.32.4. Thanks Niels Thykier! * SECURITY: add 11_CVE-2012-3524_setuid.patch from upstream. Prevents using DBus in a setuid binary. Fixes CVE-2012-3524. . glib2.0 (2.33.12+really2.32.4-1) unstable; urgency=low . * New upstream bugfix release. * 10_gdbus_race.patch: stolen from upstream git. Fix a race condition that would make gnome-shell crash on startup under some conditions. * libglib2.0-bin.install: bash completions have moved to /usr/share. * libglib2.0-bin.maintscript: remove old conffiles. * Add appropriate pre-dependency. * libglib2.0-doc.links: add link for gdbus-object-manager-example. . glib2.0 (2.33.12+really2.32.3-2) unstable; urgency=low . * Explicitly set the shlibs version to 2.32.3 to not generate overly strict dependencies for udeb packages. . glib2.0 (2.33.12+really2.32.3-1) unstable; urgency=low . * Brown paper bag upload * Re-upload version previously in unstable to superseded experimental-targetted version previously mistakenly uploaded there. . glib2.0 (2.32.3-1) unstable; urgency=low . * New upstream release. * Remove debian/patches/95_configure-Fix-typo-in-ELF-check.patch and debian/patches/96_configure-Reset-LIBS-after-ELF-check.patch, merged upstream. . glib2.0 (2.32.2-1) unstable; urgency=low . * New upstream release. * Refresh patches. * Remove debian/patches/git_powerpc_gresources.patch, merged upstream. * debian/patches/95_configure-Fix-typo-in-ELF-check.patch: Fix typo in ELF configure check. Patch cherry-picked from upstream Git. * debian/patches/96_configure-Reset-LIBS-after-ELF-check.patch: Reset LIBS after running the ELF checks otherwise we end up linking everything against libelf. Patch cherry-picked from upstream Git. . glib2.0 (2.32.1-1) unstable; urgency=low . * New upstream release. * Refresh patches. * debian/patches/git_powerpc_gresources.patch: Upstream fix for gresource on big endian architectures, i.e powerpc. Closes: #669130 * debian/patches/revert_schema_path_warning.patch: Revert upstream commit which generates a warning for applications using a non-recommended gsettings path. Final freeze is not the time to start fixing the gsettings paths of all packages. This avoids tons of spewage from the gsettings trigger during package installation. . glib2.0 (2.32.0-4) unstable; urgency=low . * Set --sourcedir for the different flavors when running dh_install. This way the .install files can be simplified a lot which makes them much more readable. * Bump Standards-Version to 3.9.3. * Add Breaks against emacs23, eog and gwaei. Those applications were broken due to changes in GApplication and the way they interacted with GdkThreads so they needed to be fixed to correctly work with glib 2.32. Closes: #668019 . glib2.0 (2.32.0-3) unstable; urgency=low . [ Martin Pitt ] * 01_gettext-desktopfiles.patch: Use official "Keywords" key now, X-GNOME-Keywords has been deprecated for a while now. (LP: #949864) * debian/libglib2.0-0.postrm.in: Only remove the compiled schemas on purge, not during upgrades. Otherwise we have no schemas available until the new postinst is run, which leads to applications aborting on missing schemas. . [ Michael Biebl ] * Don't enforce single include for glib/gversionmacros.h since this header is included from glib/gtypes.h which is widely used. . glib2.0 (2.32.0-2) unstable; urgency=low . * Upload to unstable. * Revert upstream commit for now which makes single includes mandatory as the list of affected packages is still a bit too long. . glib2.0 (2.32.0-1) experimental; urgency=low . * New upstream release. * Add single-include guard for gbytes.h. Patch cherry-picked from upstream Git. . glib2.0 (2.31.22-1) experimental; urgency=low . * New upstream development release. * debian/libglib2.0-0.symbols: Add new symbol. . glib2.0 (2.31.20-1) experimental; urgency=low . * New upstream development release. * debian/patches/61_glib-compile-binaries-path.patch: Refreshed. * debian/libglib2.0-0.symbols: Add new symbols. * Override list-missing target with an implementation that better handles multiple flavors (copied from the gtk+3.0 package). . glib2.0 (2.31.18-3) experimental; urgency=low . * debian/control.in: Add Build-Depends on python-dbus, python-gobject-2, and libxml2-utils (xmllint). Required to run the test-suite. . glib2.0 (2.31.18-2) experimental; urgency=low . * debian/control.in: - add libpcre3-dev to the list of dependencies of libglib2.0-dev - add libelf-dev as a build dependency to make gresource able to deal with ELF files . glib2.0 (2.31.18-1) experimental; urgency=low . [ Gustavo Noronha Silva ] * New development release - Yeah, 2.31.8 was a mistake =/ * debian/libglib2.0-0.symbols: - fix version declared for 2.31.8 symbols to not have -1 - updated for 2.31.8 symbols * debian/patches/61_glib-compile-schemas-path.patch, debian/patches/61_glib-compile-binaries-path.patch: - renamed, and updated to also cover glib-compile-resources * debian/libglib2.0-0.install.in: - add glib-compile-resources . [ Michael Biebl ] * debian/libglib2.0-bin.install: Install new gresource binary and the man pages for gresource and glib-compile-resources. * debian/libglib2.0-bin.links.in: Add symlink in /usr/bin for glib-compile-resources since we install the binary in a multiarch path. * debian/rules: Re-enable test-suite on kfreebsd but keep it non-fatal for now. . glib2.0 (2.31.8-1) experimental; urgency=low . * New development release * debian/patches/*: - refreshed; * debian/patches/95-gmain-get-rid-of-poll_waiting.patch, debian/patches/96-fix-one-bit-mutex-test-on-some-platforms.patch, debian/patches/97-silence-compiler-warnings.patch, debian/patches/98-disable-two-more-GDBus-tests-using-fork.patch: - removed; applied upstream * debian/libglib2.0-0.symbols: - updated with new symbols NOTES: + g_simple_action_get_parameter_type (from 2.28.0) was made static in 09429e2c820118918e6132d32884eb02203136d4 + g_unix_resolver_get_type (from 2.22.0) was removed by 5a30712dc7e4adc36b0e8fd82cf5ccec19bbbdc5, with the removal of !g_thread_supported code paths . glib2.0 (2.30.2-7) UNRELEASED; urgency=low . * libglib2.0-0.postinst.in: + Encapsulate gio-querymodules calls in || true statements. Closes: #659588. + Only run gio-querymodules on the non-multiarch path for the host architecture. * rules: add substitution for #ARCH# for the above change. . glib2.0 (2.30.2-6) unstable; urgency=low . * Revert the patches added in 2.30.2-5 which changed the handling of return types from libffi. They didn't actually fix the build failures on s390x and had some unpleasant side effects, like making other packages FTBFS. . glib2.0 (2.30.2-5) unstable; urgency=low . [ Josselin Mouette ] * Drop deprecated build-dependencies on pygobject & python-dbus. * Retain one on python for the script that uses it. . [ Loïc Minier ] * Avoid harmless warnings when processing triggers of libglib2.0-0 ("Unable to open directory /usr/lib/gio/modules: Error opening directory '/usr/lib/gio/modules': No such file or directory"). . [ Michael Biebl ] * Cherry-pick patches from upstream Git which fix handling of ENUMs and integral return types on 64-bit BE platforms. Closes: #653308 - Add d/p/94-closure-fix-handling-of-ENUMs-and-integral-return-ty.patch. - Add d/p/93-gvalue-Add-explicitly-signed-g_value_get_schar-and-g.patch. - Update symbols file accordingly. . glib2.0 (2.30.2-4) unstable; urgency=low . * Upload to unstable. * Disable test suite on kfreebsd-* for now. . glib2.0 (2.30.2-3) experimental; urgency=low . * debian/patches/98-disable-two-more-GDBus-tests-using-fork.patch: - Added. Disable gdbus test which use GMainContext over a fork, see https://bugzilla.gnome.org/show_bug.cgi?id=658999 for more details . glib2.0 (2.30.2-2) experimental; urgency=low . * debian/patches/95-gmain-get-rid-of-poll_waiting.patch: - Added, Fix race conditions with g_main_quit being called from other threads by getting rid of the poll_waiting flag. (Backported from git master) * debian/patches/96-fix-one-bit-mutex-test-on-some-platforms.patch: - Added, Fix the 1 bit mutex failing on platforms that have pointers aligned to 32 bits instead of 64 bits (bgo#201322). * debian/patches/97-silence-compiler-warnings.patch: - Added, Fix various compiler warnings . glib2.0 (2.30.2-1) experimental; urgency=low . * New upstream release. * debian/patches/70-fix-race-in-gdbus-connection-test.patch: - Removed, merged upstream. * debian/patches/80_gtk_doc_out_of_tree.patch: - Removed, merged upstream. . glib2.0 (2.30.1-2) experimental; urgency=low . [ Martin Pitt ] * debian/patches/01_gettext-desktopfiles.patch: - Translate X-GNOME-FullName and X-GNOME-Keywords, too. . [ Sjoerd Simons ] * debian/patches/80_gtk_doc_out_of_tree.patch: - Added. Fix documentation generation when build out of tree . [ Michael Biebl ] * Transition to multiarch, thanks Steve. Closes: #634099 The following modifications were made to the original patch: - Drop the libtool .la files, since we break existing references anyway. - Don't mark libglib2.0-0-dbg as Multi-Arch: same and install into /usr/lib/debug, not /usr/lib//debug. - Guard the for loops in debian/rules with "set -e". * debian/libglib2.0-dev.install.in: - Install gdb auto-load files. . glib2.0 (2.30.1-1) experimental; urgency=low . [ Michael Biebl ] * New upstream release. - Avoid assertion in GDBus if we fail to authenticate twice. Closes: #634312 * Bump debhelper compatibility level to 8. - Bump Build-Depends on debhelper. - Don't pass --dbg-package= without an argument to dh_strip as commands will fail rather than warn when they are passed unknown options. * Don't use brace expansion in debian/libglib2.0-0.install and debian/libglib2.0-dev.install. * debian/control.in - Use architecture wildcard for kfreebsd and hurd. - Bump Standards-Version to 3.9.2. No further changes. - Set pkg-gnome-maintainers@lists.alioth.debian.org as Maintainer. - Add Build-Depends on libffi-dev (>= 3.0.0). * debian/libglib2.0-dev.install - Install gdbus-codegen binary and manpage. - Install gtester and gtester-report manpage. * debian/libglib2.0-bin.install - Install bash completion files for gdbus and gsettings. * debian/libglib2.0-0.symbols - Update symbols file. The GAction API had an incompatible change. As a result g_action_set_state has been renamed to g_action_change_state. See upstream commit 5ff65d869543587d10d78c123698e47effc5fb8c for further details and on the impact of this change. * debian/watch: - Track .xz tarballs. * Update patches - Remove 03_blacklist-directories.patch, merged upstream. - Remove 10_gdesktopappinfo_set_last_used.patch, fixed upstream. - Remove 60_wait-longer-for-threads-to-die.patch, fixed upstream using a counter. - Refresh remaining patches. . [ Josselin Mouette ] * Break gtk3 < 3.0.12 because it uses an internal symbol that ceases to work with glib 2.30. . [ Sjoerd Simons ] * debian/rules: Explicitely build gtk-doc * debian/patches/70-fix-race-in-gdbus-connection-test.patch: - Added, fix race condition in the GDBusConnection life-cycle test . glib2.0 (2.28.8-1) unstable; urgency=low . * New upstream release. * debian/watch: - Update to version 3. - Track .xz tarballs. * Bump debhelper compatibility level to 8. - Bump Build-Depends on debhelper. - Don't pass --dbg-package= without an argument to dh_strip as commands will fail rather than warn when they are passed unknown options. * Don't use brace expansion in debian/libglib2.0-0.install and debian/libglib2.0-dev.install. * debian/control.in - Use architecture wildcard for kfreebsd and hurd. - Bump Standards-Version to 3.9.2. No further changes. - Set pkg-gnome-maintainers@lists.alioth.debian.org as Maintainer. * Refresh patches. . glib2.0 (2.28.6-4) unstable; urgency=low . * Upload to unstable. . glib2.0 (2.28.6-3) experimental; urgency=low . * Break gnome-session < 3.0.0-3 for the updated defaults.list taking x-scheme-* into account. * Break gdm < 3.0.3 to avoid adding a security hole to it. * 10_gdesktopappinfo_set_last_used.patch: new patch. When calling g_app_info_set_as_last_used_for_type, correctly inherit the default filled in the file from the system default. This avoids gnome-control-center breaking file associations just by opening the info dialog. . glib2.0 (2.28.6-2) experimental; urgency=low . * Team upload. * Drop 20_mime_extension_point.patch and add Breaks against gvfs and gnome-control-center to ensure they have been updated at the same time. * Drop Conflicts against pango, it's no longer relevant (even for oldstable). * Fix watch file. * Drop leading article in descriptions as recommended by lintian. * Add lintian overrides for package-name-doesnt-match-sonames, it's a deliberate choice. * Add some copyright holders to debian/copyright to appease lintian. * Drop unneeded section/priority fields as they duplicate the default values. * Add some DEP-3 descriptions to patches that had no description at all. . glib2.0 (2.28.6-1) unstable; urgency=low . * New upstream bugfix release. . glib2.0 (2.28.4-1) unstable; urgency=low . * debian/control.in: + Build depend on dbus, dbus-x11, shared-mime-info, python-gobject and python-dbus, needed by the test suite. + libglib2.0-data doesn't need to depend on libglib2.0-0, since it only ships translations. This will avoid making glib uninstallable on the buildds when it is uploaded until the new version has been built. * d/p/0001-Run-gio-tests-with-a-dbus-session.patch: + New patch. Run gio tests through dbus-launch, since some of them need a running dbus session. * debian/control.in, debian/rules: + Add autoreconf magic, needed by the above patch. * New upstream release. . glib2.0 (2.28.2-1) unstable; urgency=low . * New upstream release. . glib2.0 (2.28.1-1) unstable; urgency=low . * New upstream release. + Fixes g_timeout_add overflowing with large timeouts. Closes: #606618. . glib2.0 (2.28.0-2) unstable; urgency=low . * 20_mime_extension_point.patch: temporary revert the upstream change in URI schemes handling. Closes: #612876. Note for later: it must absolutely be reverted in a synchronized upload with gvfs 1.8 and control-center 3.0. . glib2.0 (2.28.0-1) unstable; urgency=low . * debian/control.in: + Drop obsolete conflicts/replaces with libglib1.3. + Don't suggest libgtk2.0-doc in the doc package. * New upstream stable release. + debian/control.in: - Bump the libpcre3-dev build dependency. + debian/patches/01_gettext-desktopfiles.patch, debian/patches/02_gettext-desktopfiles-ubuntu.patch, debian/patches/04_homedir_env.patch, debian/patches/61_glib-compile-schemas-path.patch: - Refreshed. + debian/libglib2.0-0.symbols: - Updated. . glib2.0 (2.27.91-1) experimental; urgency=low . * debian/rules: - Don't exclude .sgml and .devhelp files from being compressed. The former are already excluded by dh_compress and the later can be compressed now that devhelp can handle them. - Fix variable substitution. * New upstream release. - debian/patches/62_dont_crash_without_desktop_filename.patch: + Removed, included upstream. * debian/control.in: - Standards-Version is 3.9.1, no changes needed. . glib2.0 (2.27.90-2) experimental; urgency=low . * debian/patches/62_dont_crash_without_desktop_filename.patch * Added. Fix crash when launching application without a desktop file (From upstream git) . glib2.0 (2.27.90-1) experimental; urgency=low . * Switch to CDBS' flavors system. * Switch to source format 3.0 (quilt). * Stop symlinking /usr/share/doc/$pkg directories. * debian/rules: - Explicitly link with --no-as-needed, as --as-needed might be the default and is harmful for us. - Run the test suite but don't make it fatal yet. * New upstream release. - debian/libglib2.0-0.symbols: + Updated. . glib2.0 (2.27.5-1) experimental; urgency=low . * New upstream release. + debian/libglib2.0-0.symbols: - Updated. * debian/rules: + Make the shlibs always depend on the latest upstream version. We have symbols file anyway, and manually bumping the shver is error prone. . glib2.0 (2.27.4-2) experimental; urgency=low . * debian/rules: Change --disable-visibility to --disable-Bsymbolic for the refdbg package. . glib2.0 (2.27.4-1) experimental; urgency=low . * New upstream release. + debian/libglib2.0-0.symbols: - Updated. + debian/rules: - Bump the SHVER. . glib2.0 (2.27.3-1) experimental; urgency=low . * New upstream release. + debian/libglib2.0-0.symbols: - Updated. . glib2.0 (2.27.2-1) experimental; urgency=low . * New upstream development release: + debian/patches/*: - Refreshed. + debian/libglib2.0-0.symbols: - Updated + debian/patches/70_dtrace.patch: - Dropped, merged upstream. . glib2.0 (2.27.1-1) experimental; urgency=low . [ Josselin Mouette ] * Drop lynx dependency in the -doc package. Suggest devhelp instead. Closes: #599743. . [ Sebastian Dröge ] * New upstream development release: + debian/patches/70_fix-header-cleaup-fallout.patch: - Dropped, merged upstream. + debian/patches/*: - Refreshed. + debian/libglib2.0-0.symbols: - Updated + debian/patches/70_dtrace.patch: - Patch from upstream GIT to not enable DTrace if it's not available. Fixes the build on kFreeBSD (Closes: #592024). . glib2.0 (2.27.0-1) experimental; urgency=low . [ Sjoerd Simons ] * New upstream experimental release * debian/libglib2.0-0.symbols + Updated * debian/patches/70_fix-header-cleaup-fallout.patch + Added. Fix complilation error (from upstream git) . [ Sebastian Dröge ] * Upload to experimental. * debian/rules: + Update SHVER to 2.27.0. . glib2.0 (2.26.0-1) experimental; urgency=low . * New upstream stable release: + debian/rules, debian/libglib2.0-0.symbols: - Update for the new version. + debian/patches/90_gregex-system-pcre.patch: - Dropped, merged upstream. . glib2.0 (2.25.16-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for the new version. + debian/patches/90_gregex-system-pcre.patch: - Fix GRegex compilation with the system pcre. . glib2.0 (2.25.15-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for the new version. . glib2.0 (2.25.14-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for the new version. . glib2.0 (2.25.13-1) experimental; urgency=low . * New upstream development release: + debian/patches/90_git_glibconfig_build.patch, + debian/patches/99_autoreconf.patch: - Dropped, merged upstream. + debian/rules, debian/libglib2.0-0.symbols: - Update for the new version. + debian/control.in: - (Build-) depend on pkg-config >= 0.16.0. . glib2.0 (2.25.12-2) experimental; urgency=low . [ Sebastien Bacher ] * debian/rules: + clean the distributed glibconfig.h it has 64 bits values which leaded to the issues on 32 bits architectures (Closes: #591075, #591492). * debian/patches/90_git_glibconfig_build.patch: + git change to use the builddir glibconfig.h and not the srcdir one . [ Sebastian Dröge ] * debian/patches/99_autoreconf.patch: + Regenerated autotools files for the above patch. * debian/rules: + Call dh_installdirs to actually use the .dirs files. . glib2.0 (2.25.12-1) experimental; urgency=low . [ Josselin Mouette ] * Don’t run the triggers when executed from a nonexistent directory. Closes: #589693. . [ Sebastian Dröge ] * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API changes. + debian/patches/99_gsocket-create-socket-cloexec.patch: - Dropped, merged upstream. . glib2.0 (2.25.11-3) experimental; urgency=low . * debian/patches/99_gsocket-create-socket-cloexec.patch: Patch by Julien Cristau: Just because SOCK_CLOEXEC was defined at build time doesn't mean the kernel we're running on supports it. So if socket() fails with EINVAL, try again without the flag. . glib2.0 (2.25.11-2) experimental; urgency=low . * debian/control.in, debian/libglib2.0-bin.links, debian/libglib2.0-0.links: + Move links to the -bin package again but let the -dev package depend on the -bin package. Having the links in the shared library package will cause conflicts when the soname changes but the links in /usr/bin must be there at least if the -dev package is installed because build systems might assume that the applications are in $PATH. * debian/patches/61_glib-compile-schemas-path.patch: + Adjust path to glib-compile-schemas in the pkg-config file. . glib2.0 (2.25.11-1) experimental; urgency=low . [ Josselin Mouette ] * Drop type-handling usage. Closes: #587863. * Bump standards version accordingly. * Patch from Ubuntu, thanks Sébastien Bacher. Closes: #587661. * debian/libglib2.0-bin.install: - Install glib-compile-schemas * debian/libglib2.0-bin.postinst: - Run glib-compile-schemas when schemas modified * debian/libglib2.0-bin.triggers: - Watch for schema changes * debian/libglib2.0-dev.install: - glib-compile-schemas moved to libglib2.0-bin * debian/libglib2.0-dev.install: - install the new gdb python macros since the gdb version is recent enough now to use those * Put gio-querymodules and glib-compile-schemas in a private, versioned directory in libglib2.0-0 to avoid a dependency loop. * Move back the triggers to libglib2.0-0. * Add a purge of the necessary files in the postinst. * Stop recommending libglib2.0-bin since the necessary stuff is in libglib2.0-0 now. * Add symlinks to keep the binaries at their place in libglib2.0-bin. * Tighten the dependency between libglib2.0-bin and libglib2.0-0. . [ Sebastian Dröge ] * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API changes. * debian/libglib2.0-0.dirs: + Create empty directories for the triggers to actually work. * debian/libglib2.0-0.links, debian/control.in: + Add links for gio-querymodules and glib-compile-schemas in /usr/bin. . glib2.0 (2.25.10-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API changes. + debian/libglib2.0-dev.install: - Drop gsettings-schema-convert. + debian/patches/*: - Refreshed all patches. . glib2.0 (2.25.9-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API additions. . glib2.0 (2.25.8-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API additions. . glib2.0 (2.25.7-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API additions. . glib2.0 (2.25.6-1) experimental; urgency=low . * New upstream development release. . glib2.0 (2.25.5-1) experimental; urgency=low . * New upstream development release. . glib2.0 (2.25.4-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API additions. + debian/libglib2.0-bin.install: - Add gdbus utility and manpage. . glib2.0 (2.25.3-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API additions. + debian/libglib2.0-dev.install: - gschema-compile was renamed to glib-compile-schemas. + debian/control.in, debian/rules: - Manpages are now properly shipped with the tarballs, drop xsltproc, etc. build dependencies. . glib2.0 (2.25.2-1) experimental; urgency=low . * New upstream development release: + debian/libglib2.0-0.install, debian/libglib2.0-0.triggers, debian/control.in, debian/rules, debian/libglib2.0-bin.install, debian/libglib2.0-bin.triggers: - Move binaries to an unversioned, separate package. - Add new gsettings tool. + debian/rules, debian/libglib2.0-0.symbols: - Update for API additions. . glib2.0 (2.25.1-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Update for API additions. + debian/libglib2.0-dev.install, debian/libglib2.0-0.install: - Install new GSettings utitilies and manpages. * debian/control.in, debian/rules: + Enable manpage generation via xsltproc for now until https://bugzilla.gnome.org/show_bug.cgi?id=616264 is fixed. . glib2.0 (2.24.0-1) unstable; urgency=low . * New upstream stable release: + debian/rules, debian/libglib2.0-0.symbols: - Updated 2.23 symbols to 2.24 to force dependencies on a stable release. + debian/rules: - Remove check-dist.mk include to allow uploads to unstable again. . glib2.0 (2.23.6-1) experimental; urgency=low . [ Emilio Pozuelo Monfort ] * debian/patches/05_gvariant_test_failure.patch: - Backport patch from upstream git to fix a gvariant test that fails randomly on x86. . [ Sebastian Dröge ] * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new API. + debian/patches/05_gvariant_test_failure.patch: - Dropped, merged upstream. * debian/rules: + Make unit test failures non-fatal again because of race conditions in some tests. . glib2.0 (2.23.5-1) experimental; urgency=low . [ Emilio Pozuelo Monfort ] * debian/patches/05-dont-fail-a-couple-of-tests-when-running-as-root.patch: - Updated. * 06-test-for-unexisting-files-in-TMP-and-not-in-HOME.patch: - Added, don't look for an unexisting file in $HOME since it will fail with an unexpected result if it's not writable (which happens on some buildds). Look at $TMP instead. * debian/rules: - Make test suite failures fatal on amd64, i386 and s390. . [ Sebastian Dröge ] * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new API. + debian/patches/05-dont-fail-a-couple-of-tests-when-running-as-root.patch, debian/patches/06-test-for-unexisting-files-in-TMP-and-not-in-HOME.patch: - Dropped, merged upstream. . glib2.0 (2.23.4-1) experimental; urgency=low . [ Emilio Pozuelo Monfort ] * debian/patches/05-dont-fail-a-couple-of-tests-when-running-as-root.patch: - Added, expect a couple of tests that play with file permissions to succeed when running as root. * debian/control.in: - Add desktop-file-utils to build depends to fix another test. - Standards-Version is 3.8.4, no changes needed. - Let libgio-fam depend on ${misc:Depends}. . [ Sebastian Dröge ] * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new API. . glib2.0 (2.23.3-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new API. . glib2.0 (2.23.2-2) experimental; urgency=low . * debian/control.in, debian/libglib2.0-0.triggers, debian/libglib2.0-0.install, debian/libglib2.0-dev.install: + Ship gio-querymodules in the shared library package and triggers calls to every time /usr/lib/gio/modules is touched by a package. . glib2.0 (2.23.2-1) experimental; urgency=low . * New upstream development release: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new API. . glib2.0 (2.23.1-1) experimental; urgency=low . [ Sebastian Dröge ] * debian/control.in: + Let the -dev package depend on zlib1g-dev as it's required by the pkg-config file now. . [ Emilio Pozuelo Monfort ] * New upstream release. + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new API. . glib2.0 (2.23.0-1) experimental; urgency=low . [ Loïc Minier ] * -refdbg package is section/prio debug/extra. * Add note to NOT use -Wl,--as-needed as it might drop a critical -lpthread link in gio (which dlopen()s gvfs); see mid:<1257999019.21780.15.camel@marzipan>. . [ Sebastian Dröge ] * New upstream development release: + debian/patches/90_mimetype-sorting.patch: - Dropped, merged upstream. + debian/rules, debian/libglib2.0-0.symbols: - Update for new API. + debian/control.in: - Build depend on zlib. + debian/rules: - Include check-dist.mk to prevent accidental uploads to unstable. . glib2.0 (2.22.2-2) unstable; urgency=low . * debian/patches/90_mimetype-sorting.patch: + Fix sorting of mimetypes by weight. Highest weight means most important, not the other way around. Patch from upstream GIT. . glib2.0 (2.22.2-1) unstable; urgency=low . [ Emilio Pozuelo Monfort ] * Move libglib2.0-data to section libs. Closes: #549079. . [ Sebastian Dröge ] * New upstream bugfix release. . glib2.0 (2.22.1-1) unstable; urgency=low . * New upstream bugfix release: + debian/patches/10_inotify_init1.patch, debian/patches/30_metadata_symlinks.patch: - Dropped, merged upstream. . glib2.0 (2.22.0-2) unstable; urgency=low . * Don’t install Python GDB macros for now, they only work with an experimental GDB branch. * 30_metadata_symlinks.patch: stolen upstream. Get metadata to work with symbolic links. Closes: #548142. . glib2.0 (2.22.0-1) unstable; urgency=low . [ Josselin Mouette ] * Move libglib-2.0.so.0 to /lib so that DeviceKit (and other potential sources) can work without having /usr mounted. * 11_chmod_symlinks.patch: new patch. Fix potential security issue when manipulating symlink permissions. Thanks Arand Nash for the heads up. . [ Sebastian Dröge ] * New upstream stable release: + debian/patches/11_chmod_symlinks.patch: - Dropped, merged upstream. + debian/libglib2.0-0.symbols, debian/rules: - Update for the new version. . glib2.0 (2.21.6-1) experimental; urgency=low . [ Josselin Mouette ] * 10_inotify_init1.patch: fall back on inotify_init when inotify_init1 does not work, as happens with kernel versions < 2.6.27. Closes: #544354. . [ Sebastian Dröge ] * New upstream development release: + debian/libglib2.0-0.symbols: - Update for the new version. + debian/rules: - Update SHVER to 2.21.6. * debian/control.in: + Updated Standards-Version to 3.8.3, no additional changes needed. . glib2.0 (2.21.5-1) experimental; urgency=low . * New upstream development release: + debian/libglib2.0-0.symbols: - Update for the new version. + debian/rules: - Update SHVER to 2.21.5. * debian/control.in: + Updated Standards-Version to 3.8.2, no additional changes needed. . glib2.0 (2.21.4-1) experimental; urgency=low . * New upstream development release: + debian/rules: - Include check-dist.mk to prevent accidental uploads to unstable. - Update shlib version to 2.21.4. + debian/libglib2.0-0.symbols: - Update for the API additions. * debian/control.in: + Updated Standards-Version to 3.8.1, no additional changes needed. . glib2.0 (2.20.4-1) unstable; urgency=low . * New upstream bugfix release. . glib2.0 (2.20.3-1) unstable; urgency=low . [ Josselin Mouette ] * Only build the libgio-fam package for hurd and kfreebsd, it is totally useless under Linux. * Make it recommend gamin for kqueue support. * Make libgamin-dev the primary build-dependency. Closes: #526219. . [ Sebastian Dröge ] * New upstream bugfix release. . glib2.0 (2.20.1-2) unstable; urgency=low . * Add refdbg package: libglib2.0-0-refdbg. (Closes: #525915) . glib2.0 (2.20.1-1) unstable; urgency=low . * New upstream bugfix release: + 10_log_valist.patch, dropped. . glib2.0 (2.20.0-3) unstable; urgency=low . * Fix debug package section. * 10_log_valist.patch: new patch, stolen upstream. Copy a va_list before using it twice. Closes: #520484. . glib2.0 (2.20.0-2) unstable; urgency=low . * Remove 02_usr_share_gnome_applications.patch, now gnome-session sets XDG_DATA_DIRS accordingly. . glib2.0 (2.20.0-1) unstable; urgency=low . * New upstream stable release. * Upload to unstable, remove check-dist include. This won't block any transitions because of symbol files. * debian/libglib2.0-0.symbols, debian/rules: + Update for the API changes. . glib2.0 (2.19.10-1) experimental; urgency=low . * New upstream development release. . glib2.0 (2.19.8-2) experimental; urgency=low . * debian/patches/01_gettext-desktopfiles.patch, debian/patches/02_gettext-desktopfiles-ubuntu.patch: + Updated from the Ubuntu package, thanks to Martin Pitt for the changes: - 01_gettext-desktopfiles.patch: Merge OpenSUSE's and our patch: - Now prefers inline translations over gettext translations, which fixes a few corner cases (like renaming .desktop files on the user's desktop), is more in line with the recent gconf patch, and more palatable for upstream inclusion. - Use X-GNOME-Gettext-Domain, for preparing upstream inclusion. - Forwarded upstream now. - Add 02_gettext-desktopfiles-ubuntu.patch: Provide backwards compatibility for 01_gettext-desktopfiles.patch for X-{Debian,Ubuntu}-Gettext-Domain. The latter was changed to use X-GNOME-, so this is necessary until all our .desktop files are converted. . glib2.0 (2.19.8-1) experimental; urgency=low . * New upstream development release. . glib2.0 (2.19.7-1) experimental; urgency=low . * New development release . glib2.0 (2.19.6-1) experimental; urgency=low . * New development release * debian/libglib2.0-0.symbols: - updated with new symbols . glib2.0 (2.18.4-2) unstable; urgency=low . * Release to unstable * debian/rules: - bump SHVER, since we are already forcing a 2.18.0 dependecy on the symbols introduced in the development versions * debian/control.in: - added Homepage and Vcs-* control fields . glib2.0 (2.18.4-1) experimental; urgency=low . [ Josselin Mouette ] * 04_homedir_env.patch: new patch. Handle the G_HOME environment variable, to override the passwd entry. This will allow to fix various kinds of build failures due to restricted build environments. . [ Sebastian Dröge ] * New upstream bugfix release. . glib2.0 (2.18.3-1) experimental; urgency=low . * New upstream bugfix release. . glib2.0 (2.18.2-1) experimental; urgency=low . [ Loic Minier ] * Suffix the Debian specific pcre bdep with "~" to allow backports and make lintian happy. * Update doc-base entries for new doc-base secttions: use Programming/C instead of Apps/Programming. * Use uppercase GNOME in doc-base description of glib. * Recommend shared-mime-info for content-type guessing API; see GNOME #554563. * Pass -k to make check. . [ Sebastian Dröge ] * New upstream bugfix release. . glib2.0 (2.18.1-1) experimental; urgency=low . * New upstream bugfix release. * debian/libglib2.0-0.symbols: + Updated all 2.17 symbols to 2.18.0 to get dependencies on the stable versions. . glib2.0 (2.18.0-1) experimental; urgency=low . * New upstream stable release, with API addition. - Update symbols file for new g_object_get_type() symbol and drop g_slice_debug_tree_statistics() which shouldn't have been exported in the first place. - Refresh patches 01_gettext-desktopfiles, 02_usr_share_gnome_applications, and 03_blacklist-directories to apply cleanly. . glib2.0 (2.17.7-1) experimental; urgency=low . * New upstream development release, the new API might still change: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new symbols. . glib2.0 (2.17.6-1) experimental; urgency=low . * New upstream development release, the new API might still change: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new symbols. . glib2.0 (2.17.4-1) experimental; urgency=low . [ Loic Minier ] * List back m68k in arches where we could make the testsuite fatal, following the update on GNOME #481575. * Document why testsuite is currently completely disabled (fails when there's no writable $HOME). . [ Sebastian Dröge ] * New upstream development release, the new API might still change: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new symbols. + debian/patches/90_gio-nautilus-crash.patch: - Dropped, merged upstream. . glib2.0 (2.17.3-2) experimental; urgency=low . * debian/patches/90_gio-nautilus-crash.patch: + Patch from upstream SVN to fix a crash in nautilus 2.22. . glib2.0 (2.17.3-1) experimental; urgency=low . * New upstream development release, the new API might still change: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new symbols. * debian/control.in: + Updated Standards-Version to 3.8.0, no additional changes needed. . glib2.0 (2.17.2-1) experimental; urgency=low . * New upstream development release, the new API might still change: + debian/rules, debian/libglib2.0-0.symbols: - Updated for the new symbols. . glib2.0 (2.17.0-1) experimental; urgency=low . [ Josselin Mouette ] * debian/rules: don't compress .sgml and .devhelp files. . [ Loic Minier ] * Fix broken second dh_strip invocation which was not only acting on the udeb but also on binary packages (-s -pUDEB should have been -pUDEB). . [ Sebastian Dröge ] * New upstream development release, the new API might still change. * debian/rules: + Include check-dist.mk to prevent accidental uploads to unstable. + Bump SHVER to 2.17.0. + Pass -c4 to dh_makeshlibs. * debian/libglib2.0-0.symbols: + Update symbols. . glib2.0 (2.16.3-2) unstable; urgency=low . * debian/rules: Don't add the debug symbols of the udeb in the -dbg package. Makes the debugging info actually usefull again (Closes: #468093) . glib2.0 (2.16.3-1) unstable; urgency=low . [ Sjoerd Simons ] * debian/patches/70_g_timeout_seconds_fix.patch + Added. Fix a rare case where a timeout from g_timeout_add_seconds() is never triggered. See http://bugzilla.gnome.org/show_bug.cgi?id=448943 . [ Sebastian Dröge ] * New upstream bugfix release: + debian/patches/70_g_timeout_seconds_fix.patch: - Dropped, merged upstream. . glib2.0 (2.16.2-1) unstable; urgency=low . [ Loic Minier ] * Drop nautilus conflicts as it triggers a bug in the APT resolver on dist-upgrade. * Update patch 01_gettext-desktopfiles with a newer version taken from the Ubuntu package. * Update and enable patch 01_gettext-desktopfiles to also look for X-Debian-Gettext-Domain if X-Ubuntu-Gettext-Domain isn't present. . [ Sebastian Dröge ] * New upstream bugfix release: + Fixes FTBFS on hurd/i386 (Closes: #472129). + debian/patches/04_nfs4.patch, debian/patches/80_static-mutex-aliasing-warnings.patch, debian/patches/81_c99-inline-warnings.patch: - Dropped, merged upstream. . glib2.0 (2.16.1-2) unstable; urgency=low . [ Josselin Mouette ] * 02_usr_share_gnome_applications.patch: ported from GnomeVFS. Use /usr/share/gnome/applications/defaults.list to obtain the defaults for MIME mapping. Currently this file is still shipped by GnomeVFS. Closes: #469504. * 03_blacklist-directories.patch: ported from GnomeVFS. Blacklist more FHS directories that are commonly found as Unix mount points, including those necessary for live-initramfs. * 04_nfs4.patch: ported from GnomeVFS. Support for nfs4 filesystems. . [ Sebastian Dröge ] * 80_static-mutex-aliasing-warnings.patch: Prevent warnings about breaking strict-aliasing rules when using G_LOCK(). See http://bugzilla.gnome.org/show_bug.cgi?id=316221 * 81_c99-inline-warnings.patch: Fix warnings when using G_INLINE_FUNC in C99 mode (Closes: #470796). See http://bugzilla.gnome.org/show_bug.cgi?id=522292 * Don't ship the old changelogs and news to save some space. . glib2.0 (2.16.1-1) unstable; urgency=low . * New upstream bugfix release. . glib2.0 (2.16.0-1) unstable; urgency=low . * New upstream stable release: + debian/rules: - Update shlibs version to 2.16.0. - Drop check-dist include, upload to unstable. + debian/libglib2.0-0.symbols: - Updated symbols for the new version. . glib2.0 (2.15.6-1) experimental; urgency=low . * New upstream release: + debian/rules: - Update shlibs version to 2.15.6. + debian/libglib2.0-0.symbols: - Updated symbols for the new version. . glib2.0 (2.15.5-1) experimental; urgency=low . * New upstream release: + debian/patches/02_fam-helper.patch: - Dropped, merged upstream. + debian/patches/60_wait-longer-for-threads-to-die.patch: - Updated to apply cleanly again. + debian/libglib2.0-0.symbols: - Update symbols for 2.15.5. . glib2.0 (2.15.4-1) experimental; urgency=low . [ Loic Minier ] * Add a gio gtk-doc symlink. * Add a doc-base file for gio. . [ Sebastian Dröge ] * New upstream release: + debian/libglib2.0-0.symbols: - Update symbols for 2.15.4. + debian/rules: - Update API version to 2.15.4. * debian/patches/02_fam-helper.patch: + Fix build failure when building with FAM and not gamin. See BGO #509419 and BGO #512384 for more details. . glib2.0 (2.15.3-1) experimental; urgency=low . * New upstream release. * debian/rules, debian/libglib2.0-0.symbols: + Update shlibs and all unstable symbols to 2.15.3. . glib2.0 (2.15.2-3) experimental; urgency=low . [ Loic Minier ] * Bump up dpkg-dev build-dep to >= 1.14.13 for Build-Depends-Package; thanks Raphaël Hertzog. * Drop duplicate dpkg-dev bdep. * Let libglib2.0-dev depends on ${shlibs:Depends}; thanks Niko Tyni. . [ Sebastian Dröge ] * debian/libgio-fam.install: + Fix path where we install the GIO FAM plugin. It shouldn't be /usr/lib/gio/gio but /usr/lib/gio. Thanks to Sedat Dilek for reporting. . glib2.0 (2.15.2-2) experimental; urgency=low . * debian/rules: + Disable selinux for the udeb until we have a libselinux1 udeb. . glib2.0 (2.15.2-1) experimental; urgency=low . [ Sebastian Dröge ] * New upstream development release, the new API may still change incompatibly; API additions: + Drop patch 67_gcc43-inline.patch, merged upstream. * Include check-dist again to prevent accidental uploads to unstable. * Disable testsuite for now. * Bump shlibs to 2.15.2. * Add build dependencies for GIO and add libgio-fam package that contains a GIO file/directory monitoring module that uses fam. * debian/rules, debian/libglib2.0-0.symbols, debian/control.in: + Add a symbol file for GLib, generated from 2.12.4, 2.14.3, 2.15.2. This is handled by dh_makeshlibs. Require dpkg-dev (>= 1.14.8) for this. * debian/control.in: + Recommend python on the -dev package for the gtester-report utility. * debian/shlibs.local: + Dropped as pcre is fixed now since 7.4-1 (Closes: #450796). . [ Loic Minier ] * Build-dep on gtk-doc-tools to prevent a spurious warning from gtk-doc.make: "/bin/sh: line 11: test: !=: unary operator expected". * Build udeb against system pcre again (now that it provides an udeb); bump up libpcre build-dep to >= 7.4-1 (Closes: #443067). . glib2.0 (2.14.4-2) unstable; urgency=low . * debian/rules: + Make testsuite failures on sparc non-fatal too as the threadpool-test fails there too, most probably of some timing related bug. See BGO #481573. . glib2.0 (2.14.4-1) unstable; urgency=low . [ Loic Minier ] * Fix disabled patch name 01_gettext-desktopfiles in series. . [ Josselin Mouette ] * Conflict against nautilus < 2.20 according to http://bugzilla.gnome.org/show_bug.cgi?id=440988#c182 . [ Sebastian Dröge ] * New upstream bugfix release. . glib2.0 (2.14.3-1) unstable; urgency=high . [ Sebastian Dröge ] * debian/shlibs.local: + Override libpcre3's shlibs to require at least pcre 7.2 (See: #449289). . [ Loic Minier ] * New upstream stable release; bug fixes and security update. - SECURITY: Update the internal copy of PCRE to 7.4, fixes CVE-2007-4767; the internal copy is used for the udeb. - Drop relibtoolizing patch, 70_relibtoolize, as upstream prepared this tarball with libtool 1.5.24. . glib2.0 (2.14.2-1) unstable; urgency=low . * Add GNOME bug id to 70_relibtoolize. * New upstream stable release; no API change. * Add lpia to the list of arches on which testsuite failures are fatal. . glib2.0 (2.14.1-5) unstable; urgency=low . * Add a relibtoolizing patch, 70_relibtoolize, to get some hurd-i386 fixes in libtool; see Debian #445001. . glib2.0 (2.14.1-4) unstable; urgency=low . * Document that testsuite failure aren't fatal on m68k due to GNOME #481575. * Disable testsuite on arm, mips, powerpc; see GNOME #481573; mipsel was already disabled because its testsuite results were unknown in experimental. * Document that testsuite failure is disabled on hppa, hurd, kfreebsd-amd64, kfreebsd-i386 due to Debian #428674. . glib2.0 (2.14.1-3) unstable; urgency=medium . * Only build the standards debs against the system PCRE, i.e. build the udeb against the builtin PCRE until pcre3 provides an udeb. . glib2.0 (2.14.1-2) unstable; urgency=low . * debian/control.in, debian/rules: + Build against the system PCRE instead of the supplied one. . glib2.0 (2.14.1-1) unstable; urgency=low . [ Loic Minier ] * Mention I added 90_fix-abi-check-with-debug in 2.14.0-1 . [ Sebastian Dröge ] * New upstream major stable release, without API changes. * debian/patches/90_fix-abi-check-with-debug.patch: + Dropped, merged upstream. . glib2.0 (2.14.0-2) unstable; urgency=low . * Upload to unstable; drop check-dist include. . glib2.0 (2.14.0-1) experimental; urgency=low . * Fix double --host/--build flags to configure. * Update patch 67_gcc43-inline to also fix the headers for GCC 4.2. * New upstream major stable release; API additions. - Bump up shlibs to >= 2.14.0. - Drop patch 90_from_svn_fix_missing_pointer_casting, merged upstream. - New patch, 90_fix-abi-check-with-debug, fixes build of testsuite in debug mode; from SVN. . glib2.0 (2.13.7-3) experimental; urgency=low . * debian/patches/90_from_svn_fix_missing_pointer_casting.patch: - patch from SVN, "fixed missing pointer casts when using atomic ops." (Closes: #434853) . glib2.0 (2.13.7-2) experimental; urgency=low . * Bump shlibs to 2.13.7. . glib2.0 (2.13.7-1) experimental; urgency=low . * Drop "libtool_is_fool" snippet patching hardcode_libdir_flag_spec and archive_cmds which is probably dangerous with newer libtools. * Fix flavor name in a comment of debian/rules. * Use -s instead of -a in arch-specific dh_* calls. * New upstream development release; some API additions. - Drop patch 60_output-lines-during-tests, merged upstream. * New patch, 60_wait-longer-for-threads-to-die, to wait 5 seconds instead of one for threads to die in the threadpool test; hopefully fixes hppa and kfreebsd testsuite failures; see #428674 and #431720. * Don't make testsuite failures fatal on hppa; closes: #431720. . glib2.0 (2.13.6-1) experimental; urgency=low . * Don't pass -L to dh_shlibdeps as the shlibs.local trick is enough and this can result in duplicate deps; closes: #317461. * Set myself as maintainer. * Cleanups. * Make the testsuite failures fatal on arches which passed the testsuite with 2.13.5 in experimental (currently: alpha amd64 arm hppa i386 ia64 mips powerpc s390); closes: #291486. * Don't run the testsuite when cross-compiling. * New upstream development release; only API change is to change back the definition of GType for C++ to be gulong. . glib2.0 (2.13.5-1) experimental; urgency=low . * New upstream release - Bump shlibs to >= 2.13.5, as the API was changed . glib2.0 (2.13.4-2) experimental; urgency=low . * New patch, 67_gcc43-inline, fixes FTBFS of apps using glib with GCC 4.3 which uses C99 where the meaning of "inline" changed; patch was adapted from patches in GNOME #315437 and Gentoo #156475; closes: #416863. . glib2.0 (2.13.4-1) experimental; urgency=low . * Also honor parallel=n in DEB_BUILD_OPTIONS. * New upstream release series; these are development releases, the new API may still change incompatibly. - Target at experimental; include check-dist. - Bump up shlibs to >= 2.13.4. * New patch but disabled, 01_gettext-desktopfiles, permits overriding the gettext domain when desktop files have such a field; found in the Ubuntu package. . glib2.0 (2.12.12-1) unstable; urgency=low . * Fix description of the -dbg package. * New upstream release. . glib2.0 (2.12.11-3) unstable; urgency=medium . * Initialize CFLAGS to -Wall -g; pass debian/rules' CFLAGS and LDFLAGS to configure, doh! * Track all stable versions in watch file. * Wrap build-deps and deps. * Add ${misc:Depends}. * New patch 60_output-lines-during-tests, outputs newlines after thousand iterations of the inner-loop of the closures test to avoid the timeout on mips and mipsel buildds. . glib2.0 (2.12.11-2) unstable; urgency=low . * Run "make check" test suite for the deb flavor except if DEB_BUILD_OPTIONS contains the "nocheck" keyword; ignore failures. * Include the new uploaders.mk from gnome-pkg-tools instead of duplicating its logic; build-dep on gnome-pkg-tools >= 0.11. * Drop useless version computations. * Add support for DEB_BUILD_OPTIONS_PARALLEL. * Upload to unstable; drop check-dist include. . glib2.0 (2.12.11-1) experimental; urgency=medium . * New upstream release; no API change. . glib2.0 (2.12.10-1) experimental; urgency=low . * Include the new check-dist Makefile to prevent accidental uploads to unstable; bump build-dep on gnome-pkg-tools to >= 0.10. * New upstream release; no API change. - Rewrite and cleanup the build-system completely to build a set of flavors; drop obsolete targets; drop obsolete files; switch from tar-in-tar and sys-build to regular source and quilt patching; build-depend on quilt; drop DEB_USE_DBS_TARBALL_LAYOUT; create stampdir when necessary; switch from dh_movefiles and dh_installdirs to dh_install. - Drop patch 000_glib-link; merged upstream. * Bump up Debhelper compatibility level to 5. * Only ship README.Debian in libglib2.0-dev. * Empty dependency_libs in the *.la files of libglib2.0-dev. * Override shlibs for the inter-shlibdeps before computing them. * Use >= ${source:Version} and ${binary:Version} for inder-deps; build-dep on dpkg-dev >= 1.13.19. * Fix --dbg-package name. * Use make vars for package names. * Tune udeb description. * Clean /usr/share/doc symlinks generation and move to dh_link generated links. * Cleanup list of invoked dh_* commands. . glib2.0 (2.12.9-2) experimental; urgency=low . * Bump shlibs to >= 2.12.9. * Avoir overwriting the *.la files of the main build with the *.la files of the udeb build; fixes "old_library" in *.la files; thanks Tim Dijkstra; closes: #297741. . glib2.0 (2.12.9-1) experimental; urgency=low . * Add a get-orig-source target to retrieve the upstream tarball. * New upstream releases; no API change. - Fixes documentation of g_key_file_set_string_list(); closes: #405028. - Avoids spewing warnings with gcc 2.95; closes: #303124. - Drop patch 009_accept-space-in-key-names; merged and adapted upstream. . glib2.0 (2.12.7-1) experimental; urgency=low . * New upstream release; no API change; translation updates, bug fixes, build fixes. - Target at experimental for now. - Drop patch 010_restore-old-key-file-syntax-support, merged and adapted upstream. . glib2.0 (2.12.6-2) unstable; urgency=medium . * New patch, 010_restore-old-key-file-syntax-support, reverts strict group names and key names checks introduced between glib 2.12.4 and 2.12.6; instead of failing, critical warnings are output; updates the relevant tests as well; closes: #404888. * New patch, 009_accept-space-in-key-names, adds support for space in key names (independently of 010_restore-old-key-file-syntax-support); updates and add relevant tests as well; closes: #404888 as well. . glib2.0 (2.12.6-1) unstable; urgency=low . * New upstream release; no API or ABI change. - Fixes file-type detection in nautilus; closes: #404015. . glib2.0 (2.12.5-3) unstable; urgency=low . * Upload to unstable. . glib2.0 (2.12.5-2) experimental; urgency=low . * Upload to unstable. . glib2.0 (2.12.5-1) experimental; urgency=low . * Add cross-reference in 2.12.4-2. * New upstream release; no API or ABI change. - Target at experimental for now. - Drop patch 011_glib-gettext-datarootdir, merged upstream. * Drop patch 010_glib2.0.kfreebsd-amd64, is not needed anymore and seems to have been at the wrong level anyway. * Review and comment on the usefulness of patch 000_glib-link. . glib2.0 (2.12.4-2) unstable; urgency=low . * New patch, 011_glib-gettext-datarootdir, to compute datarootdir appropriately for AM_GLIB_DEFINE_LOCALEDIR; GNOME #343825; closes: #370282. . glib2.0 (2.12.4-1) unstable; urgency=low . * New upstream release; no API changes. . glib2.0 (2.12.3-2) unstable; urgency=low . * Upload to unstable . [ Loic Minier] * Merge 2.10.3-3. . glib2.0 (2.12.3-1) experimental; urgency=low . * New upstream release; no public API changes. * Broaden the -data dep on the lib to permit bin NMUs. . glib2.0 (2.12.2-1) experimental; urgency=low . * New upstream release; no API changes. . glib2.0 (2.12.1-1) experimental; urgency=low . * New upstream release. * Sync with overrides and set udeb's Priority to optional instead of extra. * Bump up Standards-Version to 3.7.2. . glib2.0 (2.12.0-1) experimental; urgency=low . * New upstream version: Major new features include: * The Unicode support has been updated to Unicode 5. * GBookmarkFile: a parser for files containing bookmarks stored using the Desktop Bookmark specification * Base64 encoding support * debian/rules: - updated shver number * debian/watch: - updated . glib2.0 (2.10.3-3) unstable; urgency=low . * debian/patches/999_ia64_atomic_ops_broken.patch: - dropped, it's not required with the new gcc and it was breaking the build (Closes: #376260) . [ Loic Minier ] * Sync with overrides and set udeb's Priority to optional instead of extra. . glib2.0 (2.10.3-2) unstable; urgency=medium . * Re-add changes from 2.10.2-2 that were lost in the wild (closes: #361697). . glib2.0 (2.10.3-1) unstable; urgency=low . * New upstream version: Bugs fixed: - g_completion_complete_utf8 crashes when NULL is passed to it - update-desktop-database doesn't handle duplicate entries (Closes: #298668) - Dereferencing NULL value in g_key_file_get_group_comment - GKeyFile set_string_list invalid memory reads - The GObject tutorial say g_object_(un)ref is _not_ thread-safe - Fix a memory leak in GOption . glib2.0 (2.10.2-2) unstable; urgency=low . * debian/control.in, debian/rules: - patch by Frans Pop - Add support for udeb dependency resolution in shlibs file (Closes: #361697). - Simplify debian/rules by making use of udeb support in debhelper. * debian/control.in: - clarify the description for the -data package (Closes: #362316), change suggested Robert Bihlmeyer . glib2.0 (2.10.2-1) unstable; urgency=low . * New upstream version: - Missing check for .dylib - Segmentation Fault when %llu is passed to vasnprintf and HAVE_SNPRINTF is not defined - Add support for write FDs to GIOChannel - Memleak in goption.c::parse_short_option - g_parse_debug_string reads beyond buffer - g_option_context_parse() should not set program name to '' if it is already set - g_main_context_unref calls g_source_destroy_internal with incorrect arguments - Slight performance gains (GList, GAsyncQueue) - Use of unitialised memory in g_mem_profile - make check FAIL: threadpool-test - g_option_context_new parameter lacks better explanation - Some breakages with GThreadPool - gthread/gthread-win32.c: IsDebuggerPresent needs '#define _WIN32_WINDOWS 0x0401' - dlerror() portability issue causes crash on (old) a.out NetBSD platform - g_timer_elapsed docs should mention that microseconds may be NULL - goption + error out params - Documentation should not reference G_HAVE_GINT64, as it's deprecated. * debian/patches/010_glib2.0.kfreebsd-amd64.patch: - patch by Aurelien Jarno , fix build on kfreebsd-amd64 (Closes: #355953) * debian/rules: - use "-g" for CFLAGS, makes -dbg package useful again change by Fabio M. Di Nitto on the Ubuntu package: * Make sure to pass CFLAGS to configure. * Generalize DEB_BUILD_ARCH. . glib2.0 (2.10.1-2) unstable; urgency=low . [ Sjoerd Simons ] * Upload to unstable * Document udeb changes that Josselin did in an earlier experimental package. * debian/patches/999_ia64_atomic_ops_broken.patch + Added. Uses atomic builtins that gcc-4.0 know on ia64, instead of those for gcc-4.1. (Patch by LaMont Jones from the ubuntu package) * Updated debian/watch to use download.gnome.org . [ Josselin Mouette ] * Set the conflict with pango < 1.11, that's where the breakage lies. * Add a XC-Package-Type header to the udeb and set the priority to extra. [debian/control.in] . glib2.0 (2.10.1-1) experimental; urgency=low . * New upstream release (bugfixes, translation updates). * [debian/rules] Bring priority parameter for dpkg-distaddfile for the udeb in line with control.in . . Josselin Mouette : * Conflict with pango < 1.10 to avoid breakage caused by the unicode changes. . glib2.0 (2.10.0-1) experimental; urgency=low . * New upstream release. . glib2.0 (2.8.6-1) unstable; urgency=medium . * New upstream release (bugfixes, translation updates). . glib2.0 (2.8.5-1) unstable; urgency=low . * New upstream release (bugfixes, translation updates, g_object_compat_control() added). * [debian/rules] Bumped shver to 2.8.5 to reflect the API change. . glib2.0 (2.8.4-2) unstable; urgency=high . * Fix shlibs deps that crept in the amd64 package, thanks Kurt Roeckx for all the fish. (Closes: #339685) - Cleanup and clarify upstream version calculations. - Drop dh_makeshlibs -a call as only one package ships shlibs and already has a separate call. - Drop useless shlibs.local generation. - Call dh_shlibdeps with cleaner arguments. [debian/rules] * Fix "fakeroot debian/rules clean" by following find calls with a .svn filter. [debian/scripts/lib] * Fix quoting of unfix.source.patch:START and FAILED messages. [debian/scripts/messages] * Clarify Copyright versus License and update upstream URL. [debian/copyright] . glib2.0 (2.8.4-1) unstable; urgency=low . * New upstream version. . glib2.0 (2.8.3-1) unstable; urgency=medium . * New upstream release (fix an error that crept in with a change to glib-mkenums in 2.8.2, documentation improvements, translation updates). . glib2.0 (2.8.2-1) unstable; urgency=medium . * New upstream release (bug fixes, documentation improvements, translation updates). . glib2.0 (2.8.1-1) unstable; urgency=medium . * New (for Debian) upstream version (bug fixes, documentation improvements, translation updates). * [debian/control.in] Bumped Standards-Version. * [debian/copyright] Updated FSF's address. . glib2.0 (2.8.1-0ubuntu1) breezy; urgency=low . * New upstream version. * debian/watch: - updated. . glib2.0 (2.8.0-1) unstable; urgency=low . * New upstream version. * debian/rules: - updated the shlibs. . glib2.0 (2.7.3-1) experimental; urgency=low . * New upstream version. . glib2.0 (2.7.2-1) experimental; urgency=low . * New upstream version. . glib2.0 (2.7.1-1) experimental; urgency=low . * New upstream version. * debian/rules: - updated the shlib. . glib2.0 (2.7.0-1) experimental; urgency=low . * New upstream version: * GKeyFile: - add unit tests. - accept \r\n as line end. - don't interpret leading zeros as octal numbers. - make key and group removal work. * GOption: - improve formatting of --help output. - accept -?. - warn about duplicate main groups. - treat '-' as non-option argument. - report missing arguments as errors. - add a boxed type for GDate. * GTree: - g_tree_remove() and g_tree_steal() return status information. * Stdio wrappers: - work regardless of large file support. - add g_access(), g_chmod(), g_creat(), g_chdir. * GObject: - implement "toggle references" to help language bindings. - allow to mark names, nicks and blurbs of pspecs as static. - make pspec lookup a bit faster. * add g_listenv() to list all set environment variables. * add g_file_set_contents() to atomically write a file. * add g_try_malloc(), g_try_new(), g_try_new0() and g_try_renew(). * add g_utf8_collate_key_for_filename() to sort filenames taking extensions and numeric suffixes into account. * add G_GNUC_NULL_TERMINATED to mark varargs function with NULL-terminated argument lists. * documentation improvements. * new and updated translations. * debian/rules: - updated the shlibs. * debian/watch: - updated. . glib2.0 (2.6.5-1) unstable; urgency=low . * New upstream release again bringing a number of bugfixes, improved documentation and updated translations, including gthread-posix.c (g_thread_create_posix_impl): Allow setstacksize to fail. (GNOME #304790, Michael Banck) (Closes: #312382) * [debian/patches/000_glib-link.patch] Updated. . glib2.0 (2.6.4-1) unstable; urgency=low . * New upstream release bringing a number of bugfixes, improved documentation and updated translations. . glib2.0 (2.6.3-1) unstable; urgency=low . * New upstream release. . glib2.0 (2.6.2-1) unstable; urgency=low . * New upstream release. . glib2.0 (2.6.1-3) unstable; urgency=low . * debian/rules: - use "-plibglib$(apiver)-udeb", fix the libglib2.0-0-dbg package. . glib2.0 (2.6.1-2) unstable; urgency=low . * Upload to unstable. * debian/control.in: - rename libglib2.0-dbg to libglib2.0-0-dbg. - set myself as maintainer. * debian/rules: - use dh_strip to make the debug package. . glib2.0 (2.6.1-1) experimental; urgency=low . * New upstream release. . glib2.0 (2.6.0-1) experimental; urgency=low . * New upstream release. * debian/rules: - updated the shlibs. * debian/watch: - updated. . glib2.0 (2.4.8-1) unstable; urgency=medium . * New upstream bugfix release. . glib2.0 (2.4.7-1) unstable; urgency=medium . * New upstream bugfix release. * [debian/patches/000_glib-link.patch] Updated. * [debian/patches/001_translations.patch] Dropped. . glib2.0 (2.4.6-4) unstable; urgency=medium . * [debian/patches/001_translations.patch] Updated translations from CVS and relibtoolise to use new translations. * [debian/rules] Fixed udeb naming on Hurd. . glib2.0 (2.4.6-3) unstable; urgency=medium . Colin Watson : (Closes: #274053) * [debian/rules] binary-arch depends on binary-arch-udeb. * [debian/rules] Strip udeb! . glib2.0 (2.4.6-2) unstable; urgency=medium . * [debian/patches/001_translations.patch] Updated translations from CVS. * [debian/rules] Tightened "shver" to tighten shlibs, as some incompatibilities with older versions turned up with gconf. (Closes: #265659) . glib2.0 (2.4.6-1) unstable; urgency=medium . * New upstream bugfix release. . glib2.0 (2.4.5-2) unstable; urgency=low . * debian/patches/000_glib-link.patch: - patch from Jurij Smakov to link with all the libs (Closes: #263130). . glib2.0 (2.4.5-1) unstable; urgency=low . * New upstream release. . glib2.0 (2.4.4-1) unstable; urgency=low . * New upstream release. - remove spaces before "#pragma alloca" (Closes: #250667). . glib2.0 (2.4.2-1) unstable; urgency=low . * New upstream release. . glib2.0 (2.4.1-2) unstable; urgency=low . * Upload in unstable. * GNOME Team Upload. * J.H.M. Dassen (Ray) : + [debian/rules] Make the linker work a bit harder so dynamic loading can be done faster; safety measure: ensure the build aborts when the library still has references to undefined symbols. . glib2.0 (2.4.1-1) experimental; urgency=low . * New upstream release. * GNOME Team Upload. * debian/rules: - updated shlib version to 2.4.1. . glib2.0 (2.4.0-2) experimental; urgency=low . * Akira TAGOH - debian/rules: - bumped shlib version to 2.4.0. . glib2.0 (2.4.0-1) experimental; urgency=low . * New upstream release. * debian/rules: - doh. don't claim the newer shlibs. * debian/control: - added Uploaders to maintain as team. - added gnome-pkg-tools to Build-Depends. * debian/docs: - added old ChangeLog and NEWS files. . glib2.0 (2.2.3-1) unstable; urgency=low . * "Welcome back my laptop PC!" release. * New upstream release. * debian/control: - bumped Standards-Version to 3.6.1.0. . glib2.0 (2.2.2-1) unstable; urgency=low . * New upstream release. - Fix portability problems with G_MIN/MAX_INT64 (closes: Bug#195302) * debian/control: - bumped Standards-Version to 3.5.10.0. - changed the sections for libglib2.0-dev and libglib2.0-dbg to libdevel. * debian/compat: - use it instead of DH_COMPAT. . glib2.0 (2.2.1-3) unstable; urgency=low . * debian/control: - rename libglib2.0-0-udeb to libglib2.0-udeb. - delete Recommends line from libglib2.0-udeb. (closes: Bug#183749) - add Provides: libglib2.0-0 for libglib2.0-udeb. * debian/libglib2.0-udeb.files: - contain the libraries and locale data. . glib2.0 (2.2.1-2) unstable; urgency=low . * debian/rules: - create the symlinks on /usr/share/gtk-doc/html. (closes: Bug#183504) - changed DH_COMPAT to 4. * debian/control: - add libglib2.0-0-udeb package for debian-installer. . glib2.0 (2.2.1-1) unstable; urgency=low . * New upstream release. * debian/control: - needed pkg-config (>= 0.14.0). - add autotools-dev to Build-Depends. . glib2.0 (2.2.0-2) unstable; urgency=low . * close to be fixed in the upstream release. (closes: Bug#173508) . glib2.0 (2.2.0-1) unstable; urgency=low . * New upstream release. * debian/control: bumped Standards-Version to 3.5.8. . glib2.0 (2.0.7-1) unstable; urgency=low . * New upstream release. * debian/control: - changed libc6-dev to libc6-dev | libc-dev in -dev's Depends. - bumped Standards-Version and depends debhelper (>> 4). - add libgtk2.0-doc to Suggests for -doc. * debian/rules: - add symlink to fix the missing symlink for gtk. but this release doesn't include the hyperlink for gtk+ (closes: Bug#162845) - support noopt option for DEB_BUILD_OPTIONS. . glib2.0 (2.0.6-1) unstable; urgency=low . * New upstream release. * debian/rules: removed --enable-debug option. conform to the default value now. (closes: Bug#151815) * debian/patches/000_glib2.0-garray.patch: removed because it's merged by the upstream. . glib2.0 (2.0.4-3) unstable; urgency=low . * debian/patches/000_glib2.0-garray.patch: applied to fix g_ptr_array_index() macro. (closes: Bug#150521) . glib2.0 (2.0.4-2) unstable; urgency=low . * debian/libglib2.0-doc.doc-base.gobject: fix the dupplicated title. (closes: Bug#150040) . glib2.0 (2.0.4-1) unstable; urgency=low . * New upstream release. . glib2.0 (2.0.3-1) unstable; urgency=low . * New upstream release. . glib2.0 (2.0.1-2) unstable; urgency=low . * debian/scripts/vars.build: fix bashism. * debian/README.Debian: add static link issue. * debian/rules: add --enable-static. (closes: Bug#142198) . glib2.0 (2.0.1-1) unstable; urgency=low . * New upstream release. . glib2.0 (2.0.0-1) unstable; urgency=low . * Initial Release. --- debian/changelog | 6580 +++++++++++++++++ debian/clean | 6 + debian/clean-up-unmanaged-libraries | 216 + debian/control | 208 + debian/control.in | 204 + debian/copyright | 107 + debian/docs | 2 + debian/gbp.conf | 18 + debian/gio-launch-desktop | 12 + debian/libglib2.0-0.dirs | 2 + debian/libglib2.0-0.install | 7 + debian/libglib2.0-0.lintian-overrides | 7 + debian/libglib2.0-0.postinst.in | 68 + debian/libglib2.0-0.postrm.in | 21 + debian/libglib2.0-0.symbols | 4381 +++++++++++ debian/libglib2.0-0.triggers.in | 2 + debian/libglib2.0-bin.install | 13 + debian/libglib2.0-bin.links | 2 + debian/libglib2.0-bin.lintian-overrides | 2 + debian/libglib2.0-data.install | 1 + debian/libglib2.0-dev-bin.install | 19 + debian/libglib2.0-dev.README.Debian | 15 + debian/libglib2.0-dev.install | 14 + debian/libglib2.0-doc.doc-base.gio | 14 + debian/libglib2.0-doc.doc-base.glib | 12 + debian/libglib2.0-doc.doc-base.gobject | 15 + debian/libglib2.0-doc.install | 3 + debian/libglib2.0-doc.links | 3 + debian/libglib2.0-doc.lintian-overrides | 2 + debian/libglib2.0-doc.maintscript | 6 + debian/libglib2.0-tests.install | 2 + debian/libglib2.0-tests.lintian-overrides | 12 + debian/libglib2.0-udeb.install | 2 + debian/libglib2.0-udeb.lintian-overrides | 2 + ...o-Make-portal-support-aware-of-snaps.patch | 1136 +++ ...1-timer-test-use-volatile-for-locals.patch | 38 + debian/patches/01_gettext-desktopfiles.patch | 167 + .../02_gettext-desktopfiles-ubuntu.patch | 51 + ..._disble_glib_compile_schemas_warning.patch | 36 + .../06_thread_test_ignore_prctl_fail.patch | 33 + ...ra-debug-to-memory-monitor-dbus-test.patch | 70 + ...-slow-architectures-which-keep-faili.patch | 70 + ...bus-test-if-not-specifically-request.patch | 25 + ...rms-some-unreliable-floating-point-c.patch | 32 + ...le-gdbus-threading-tests--by-default.patch | 48 + ...n-arm-unless-flaky-tests-are-allowed.patch | 37 + ...mally-skip-flaky-DBUS_COOKIE_SHA1-te.patch | 35 + ...nize-gnome-console-as-a-terminal-app.patch | 29 + .../gmenumodel-test-Mark-as-flaky.patch | 30 + ...test-Don-t-run-at-build-time-on-mips.patch | 36 + ...-Skip-if-we-are-avoiding-flaky-tests.patch | 117 + .../tests-Skip-debugcontroller-test.patch | 28 + debian/patches/gvariant-security-1-01.patch | 94 + debian/patches/gvariant-security-1-02.patch | 201 + debian/patches/gvariant-security-1-03.patch | 87 + debian/patches/gvariant-security-1-04.patch | 406 + debian/patches/gvariant-security-1-05.patch | 104 + debian/patches/gvariant-security-1-06.patch | 74 + debian/patches/gvariant-security-1-07.patch | 382 + debian/patches/gvariant-security-1-08.patch | 378 + debian/patches/gvariant-security-1-09.patch | 63 + debian/patches/gvariant-security-1-10.patch | 71 + debian/patches/gvariant-security-1-11.patch | 26 + debian/patches/gvariant-security-1-12.patch | 40 + debian/patches/gvariant-security-1-13.patch | 105 + debian/patches/gvariant-security-1-14.patch | 125 + debian/patches/gvariant-security-1-15.patch | 21 + debian/patches/gvariant-security-1-16.patch | 280 + debian/patches/gvariant-security-1-17.patch | 89 + debian/patches/gvariant-security-1-18.patch | 290 + debian/patches/gvariant-security-2-1.patch | 146 + debian/patches/gvariant-security-2-2.patch | 40 + debian/patches/gvariant-security-3-1.patch | 60 + ...-parallel-unless-invoked-with-m-slow.patch | 80 + debian/patches/series | 40 + debian/rules | 296 + debian/set-cross-properties | 22 + debian/shlibs.local | 10 + debian/source/format | 1 + debian/tests/bug896019 | 170 + debian/tests/bug896019-biarch | 2 + debian/tests/build | 143 + debian/tests/build-static | 2 + debian/tests/control | 15 + debian/tests/flaky | 72 + debian/tests/installed-tests | 55 + debian/tests/lib.sh | 124 + debian/tests/run-with-locales | 165 + debian/upstream/metadata | 6 + debian/watch | 7 + 90 files changed, 18290 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/clean create mode 100755 debian/clean-up-unmanaged-libraries create mode 100644 debian/control create mode 100644 debian/control.in create mode 100644 debian/copyright create mode 100644 debian/docs create mode 100644 debian/gbp.conf create mode 100755 debian/gio-launch-desktop create mode 100644 debian/libglib2.0-0.dirs create mode 100644 debian/libglib2.0-0.install create mode 100644 debian/libglib2.0-0.lintian-overrides create mode 100644 debian/libglib2.0-0.postinst.in create mode 100644 debian/libglib2.0-0.postrm.in create mode 100644 debian/libglib2.0-0.symbols create mode 100644 debian/libglib2.0-0.triggers.in create mode 100644 debian/libglib2.0-bin.install create mode 100644 debian/libglib2.0-bin.links create mode 100644 debian/libglib2.0-bin.lintian-overrides create mode 100644 debian/libglib2.0-data.install create mode 100644 debian/libglib2.0-dev-bin.install create mode 100644 debian/libglib2.0-dev.README.Debian create mode 100644 debian/libglib2.0-dev.install create mode 100644 debian/libglib2.0-doc.doc-base.gio create mode 100644 debian/libglib2.0-doc.doc-base.glib create mode 100644 debian/libglib2.0-doc.doc-base.gobject create mode 100644 debian/libglib2.0-doc.install create mode 100644 debian/libglib2.0-doc.links create mode 100644 debian/libglib2.0-doc.lintian-overrides create mode 100644 debian/libglib2.0-doc.maintscript create mode 100644 debian/libglib2.0-tests.install create mode 100644 debian/libglib2.0-tests.lintian-overrides create mode 100644 debian/libglib2.0-udeb.install create mode 100644 debian/libglib2.0-udeb.lintian-overrides create mode 100644 debian/patches/0001-gio-Make-portal-support-aware-of-snaps.patch create mode 100644 debian/patches/0001-timer-test-use-volatile-for-locals.patch create mode 100644 debian/patches/01_gettext-desktopfiles.patch create mode 100644 debian/patches/debian/02_gettext-desktopfiles-ubuntu.patch create mode 100644 debian/patches/debian/03_disble_glib_compile_schemas_warning.patch create mode 100644 debian/patches/debian/06_thread_test_ignore_prctl_fail.patch create mode 100644 debian/patches/debian/Add-extra-debug-to-memory-monitor-dbus-test.patch create mode 100644 debian/patches/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch create mode 100644 debian/patches/debian/Skip-memory-monitor-dbus-test-if-not-specifically-request.patch create mode 100644 debian/patches/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch create mode 100644 debian/patches/debian/Skip-unreliable-gdbus-threading-tests--by-default.patch create mode 100644 debian/patches/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch create mode 100644 debian/patches/debian/gdbus-server-auth-Normally-skip-flaky-DBUS_COOKIE_SHA1-te.patch create mode 100644 debian/patches/debian/gdesktopappinfo-Recognize-gnome-console-as-a-terminal-app.patch create mode 100644 debian/patches/debian/gmenumodel-test-Mark-as-flaky.patch create mode 100644 debian/patches/debian/gvariant-test-Don-t-run-at-build-time-on-mips.patch create mode 100644 debian/patches/debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch create mode 100644 debian/patches/debian/tests-Skip-debugcontroller-test.patch create mode 100644 debian/patches/gvariant-security-1-01.patch create mode 100644 debian/patches/gvariant-security-1-02.patch create mode 100644 debian/patches/gvariant-security-1-03.patch create mode 100644 debian/patches/gvariant-security-1-04.patch create mode 100644 debian/patches/gvariant-security-1-05.patch create mode 100644 debian/patches/gvariant-security-1-06.patch create mode 100644 debian/patches/gvariant-security-1-07.patch create mode 100644 debian/patches/gvariant-security-1-08.patch create mode 100644 debian/patches/gvariant-security-1-09.patch create mode 100644 debian/patches/gvariant-security-1-10.patch create mode 100644 debian/patches/gvariant-security-1-11.patch create mode 100644 debian/patches/gvariant-security-1-12.patch create mode 100644 debian/patches/gvariant-security-1-13.patch create mode 100644 debian/patches/gvariant-security-1-14.patch create mode 100644 debian/patches/gvariant-security-1-15.patch create mode 100644 debian/patches/gvariant-security-1-16.patch create mode 100644 debian/patches/gvariant-security-1-17.patch create mode 100644 debian/patches/gvariant-security-1-18.patch create mode 100644 debian/patches/gvariant-security-2-1.patch create mode 100644 debian/patches/gvariant-security-2-2.patch create mode 100644 debian/patches/gvariant-security-3-1.patch create mode 100644 debian/patches/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch create mode 100644 debian/patches/series create mode 100755 debian/rules create mode 100755 debian/set-cross-properties create mode 100644 debian/shlibs.local create mode 100644 debian/source/format create mode 100755 debian/tests/bug896019 create mode 100755 debian/tests/bug896019-biarch create mode 100755 debian/tests/build create mode 100755 debian/tests/build-static create mode 100644 debian/tests/control create mode 100755 debian/tests/flaky create mode 100755 debian/tests/installed-tests create mode 100644 debian/tests/lib.sh create mode 100755 debian/tests/run-with-locales create mode 100644 debian/upstream/metadata create mode 100644 debian/watch diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..f3b1f43 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6580 @@ +glib2.0 (2.72.4-0ubuntu2.2) jammy-security; urgency=medium + + * SECURITY UPDATE: multiple GVariant security issues + - debian/patches/gvariant-security-*.patch: backported upstream fixes + for GVariant normalization issues. + - CVE-2023-24593, CVE-2023-29499, CVE-2023-25180, CVE-2023-32611, + CVE-2023-32636, CVE-2023-32643, CVE-2023-32665 + + -- Marc Deslauriers Thu, 08 Jun 2023 10:15:59 -0400 + +glib2.0 (2.72.4-0ubuntu2) jammy; urgency=medium + + * d/p/0001-gio-Make-portal-support-aware-of-snaps.patch: + - Make portal support aware of snaps (LP: #1998267) + + -- Robert Ancell Wed, 22 Mar 2023 15:52:13 +1300 + +glib2.0 (2.72.4-0ubuntu1) jammy; urgency=medium + + * New upstream release (LP: #1980408) + * Update testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch + for new testfilemonitor test. + + -- Jeremy Bicha Wed, 12 Oct 2022 14:59:04 -0400 + +glib2.0 (2.72.1-1) unstable; urgency=medium + + [ Jeremy Bicha ] + * New upstream release (LP: #1969115) + - Includes workaround for meson #1008382 + * Add patch to recognize GNOME Console as a terminal app + * Refresh patch + * debian/libglib2.0-0.symbols: Add new symbol + + [ Johannes Schauer Marin Rodrigues ] + * debian/libglib2.0-0.postinst.in: only run clean-up-unmanaged-libraries + on upgrades and not on new installations + (Closes: #1008096) + + -- Jeremy Bicha Thu, 14 Apr 2022 09:35:23 -0400 + +glib2.0 (2.72.0-1) unstable; urgency=medium + + * New upstream release + - Fix assertion failure with time zone offsets >= 25 hours + (Closes: #1007226) + - Various unit test fixes + - Fix a memory leak with an invalid format in g_vasprintf() + - Translation updates + * Merge 2.71.x release history from experimental + - d/gbp.conf, d/control.in: Update branch for upload to unstable + * Upload to unstable + + -- Simon McVittie Fri, 18 Mar 2022 09:05:21 +0000 + +glib2.0 (2.70.5-1) unstable; urgency=medium + + * New upstream release + - Fix assertion failure with time zone offsets >= 25 hours + (Closes: #1007226) + - Fix possible buffer overflow in g_canonicalize_filename() + + -- Simon McVittie Thu, 17 Mar 2022 23:28:00 +0000 + +glib2.0 (2.70.4-1) unstable; urgency=medium + + * New upstream release + * Adjust Lintian overrides for newer Lintian + + -- Simon McVittie Tue, 15 Feb 2022 10:08:01 +0000 + +glib2.0 (2.71.3-1) experimental; urgency=medium + + * New upstream development release + + -- Simon McVittie Tue, 08 Mar 2022 19:53:44 +0000 + +glib2.0 (2.71.2-1) experimental; urgency=medium + + * New upstream development release + * Update symbols file. + Ignore removal of g_debug_controller_dup_default, which was only added + during this development cycle. GLib doesn't guarantee ABI stability + within x.odd.z branches. + * d/p/debian/tests-Skip-debugcontroller-test.patch: + Add patch to skip another unreliable unit test while it's investigated + upstream + + -- Simon McVittie Tue, 15 Feb 2022 20:52:33 +0000 + +glib2.0 (2.71.1-1) experimental; urgency=medium + + * New upstream development release + * Merge packaging changes from unstable + - Use debhelper 13 features instead of dh-exec + * Update symbols file + + -- Simon McVittie Thu, 27 Jan 2022 16:43:04 +0000 + +glib2.0 (2.70.3-1) unstable; urgency=medium + + * New upstream release + - Do not allow empty structs (tuples) in D-Bus messages, resolving a + denial-of-service vulnerability for private GDBus servers that accept + messages from untrusted clients (glib#2557) + - Do not allow deep recursion in serialized GVariant binary data, + resolving a denial of service for anything that loads untrusted + GVariant binary data (glib#2572) + - Fix file descriptor handling when launching subprocesses + - Don't skip fsync when writing out files on btrfs. + This was based on a kernel behaviour that was guaranteed prior to + 2014, but is no longer considered to be a guarantee. + - Translation updates + * Use debhelper 13 features instead of dh-exec + debhelper now has ${DEB_HOST_MULTIARCH} substitutions, so we don't need + to use dh-exec for those. + After that, the one remaining dh-exec feature in use was a conditional + installation for the FAM GIO module for Hurd. Open-code this in d/rules + instead. + * d/gbp.conf: Use upstream/2.70.x branch for packaging. + We have already had a 2.71.x release. + + -- Simon McVittie Wed, 26 Jan 2022 20:18:19 +0000 + +glib2.0 (2.71.0-2) experimental; urgency=medium + + * Merge packaging updates from unstable + + -- Simon McVittie Mon, 27 Dec 2021 17:05:59 +0000 + +glib2.0 (2.70.2-1) unstable; urgency=medium + + * New upstream release + * Build-Depend on dh-sequence-gnome and dh-sequence-python3 + * debian/rules: Drop environment variable clearing now done for us by dh13 + + -- Jeremy Bicha Sat, 04 Dec 2021 20:58:45 -0500 + +glib2.0 (2.71.0-1) experimental; urgency=medium + + * New upstream development release + * Unfuzz patch series + * Update symbols file + + -- Simon McVittie Mon, 27 Dec 2021 15:04:01 +0000 + +glib2.0 (2.70.1-1) unstable; urgency=medium + + * New upstream release + - Functionally equivalent to previous releases to Debian, except for + Windows-specific changes + * Drop patches that came from upstream + * d/upstream/metadata: Add + * Use debhelper compat level 13 + - Drop override for dh_missing --fail-missing, which is now the default + + -- Simon McVittie Fri, 05 Nov 2021 15:58:04 +0000 + +glib2.0 (2.70.0-3) unstable; urgency=medium + + * d/rules: Remove internal_pcre build option, which no longer exists. + Meson 0.60.0 no longer tolerates this. + + -- Simon McVittie Mon, 25 Oct 2021 11:25:31 +0100 + +glib2.0 (2.70.0-2) unstable; urgency=medium + + * d/patches: Update to upstream glib-2-70 branch commit + 2.70.0-41-g359a837ee. + Among other fixes, this makes sure we receive change-notification from + NetworkManager (>= 1.31.5), which dropped its legacy PropertiesChanged + signal in favour of using standard D-Bus Properties. (LP: #1946196) + * Add Breaks on older versions of glib-networking-tests. + With this GLib, the old way glib-networking's tests used to mock up + a particular negotiated protocol no longer works. + * Add Breaks on versions of gnome-keyring that had elevated capabilities. + Security hardening in GLib 2.70.0 interferes with their ability to + connect to D-Bus in some system configurations. (See #994961) + * Remove vestigial triggers for /usr/lib/gio/modules. + We no longer load files from that directory (since Debian 11 and Ubuntu + 20.04), but we still had a trigger for it, and the postinst still created + a module cache if it existed. + * d/libglib2.0-0.postinst.in: Clean up /usr/lib/gio/modules on upgrade. + This directory would still exist if older versions of GLib created a + cache there. + * d/libglib2.0-0.postinst.in: Add comments indicating when other + workarounds can be removed + * Add Lintian override for a unit test depending on a private library + * Skip memory-monitor-dbus test by default, and add extra debug info. + Helps: #995178 + + -- Simon McVittie Sun, 24 Oct 2021 22:41:35 +0100 + +glib2.0 (2.70.0-1) unstable; urgency=medium + + * New upstream release + * d/rules: Make shared objects in installed-tests non-executable + * Remove shebang from taptestrunner.py differently + - Remove shebang from installed file using sed. + This avoids missing the fact that there are two copies in the source, + of which we only patched one. + - d/p/debian/taptestrunner-Stop-looking-like-an-executable-script.patch: + Drop, no longer necessary + * Add Lintian override for #970275 + * d/copyright, d/libglib2.0-0.symbols: Update + * d/gbp.conf: Switch upstream branch + * Unfuzz patch series + * Standards-Version: 4.6.0 (no changes required) + + -- Simon McVittie Sun, 19 Sep 2021 17:11:43 +0100 + +glib2.0 (2.68.4-1) unstable; urgency=medium + + * New upstream release + - Avoid a deadlock while finalizing a GLocalFileMonitor + - Correctly use 3 parameters for close_range(), fixing build with + glibc 2.34 + - Fix global trash directory detection + - Make g_string_replace() with empty search string behave sensibly + (matching Python str.replace()) + - Translation updates: oc, zh_CN, zh_TW + * tests: Specify charset for generated locales to fix FTBFS with new glibc. + glibc 2.31-14 dropped support for all non-UTF-8 locales, so we can't + use /usr/share/i18n/SUPPORTED to choose a suitable charset any more. + * d/rules: Override dh_fixperms to set correct permissions on /usr/libexec. + Making everything executable is not quite right for installed-tests. + + -- Simon McVittie Fri, 20 Aug 2021 10:31:42 +0100 + +glib2.0 (2.68.3-2) unstable; urgency=medium + + * Merge from experimental branch + * Changes relative to 2.68.3-1 in experimental: + - d/watch: Only watch for stable (2.even.z) releases + - d/p/debian/61_glib-compile-binaries-path.patch: Remove. + This patch turns out to be unnecessary, and is harmful for + cross-compiling. Thanks to Helmut Grohne (Closes: #982213) + * Changes relative to previous version in unstable: + - New upstream stable release branch 2.68.x + - Fix maintainer scripts' handling of /usr/lib/MULTIARCH/gio/modules + (Closes: #987913, see 2.68.1-2 changelog) + - Mark dbus as . + Several of the installed-tests won't be built unless dbus-daemon is + available, so is insufficient. + - Move test-dependencies to Build-Depends-Arch. + We don't run the majority of the tests when we're only building the + documentation. + - Remove an unused Lintian override + - Add more Lintian overrides for test data + - Use d/tests/run-with-locales for better locale-sensitive test coverage + * d/rules: Fix dead link when documenting why we use -Wl,--no-as-needed + * Bump minimum GLib version for callers of g_dbus_server_new_sync() + Programs that call this function might be passing in the new flag + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER, which is + security-significant. Don't allow such programs to be built against + GLib 2.68 and run with GLib 2.66 or older. + * Add Breaks on libsoup2.4-tests before 2.72.0-3. + Older versions of the libsoup test suite had an assertion that would + only succeed because of a GLib bug, which is fixed in 2.68.x. Newer + versions tolerate the bug, but do not require it. + + -- Simon McVittie Sun, 15 Aug 2021 14:57:30 +0100 + +glib2.0 (2.68.3-1) experimental; urgency=medium + + * New upstream release 2.68.3, fixing bugs: + - GFile: `g_file_replace_contents()` reports `G_IO_ERROR_WRONG_ETAG` when + saving from a symlink + - glocalfileoutputstream: Fix ETag check when replacing through a symlink + - gmacros: check that __cplusplus or _MSC_VER is defined + - gmacros: missing check if __STDC_VERSION__ is defined + - gthreadedresolver: don't ignore flags in lookup_by_name_with_flags + - inotify: Fix a memory leak + - json-glib does not build with glib 2.68.1 + - testfilemonitor test leaks ip_watched_file_t struct + - tlscertificate: Avoid possible invalid read + + -- Iain Lane Tue, 29 Jun 2021 15:24:06 +0100 + +glib2.0 (2.68.1-2) experimental; urgency=medium + + * Fix maintainer scripts' handling of /usr/lib/MULTIARCH/gio/modules: + - postrm: Only delete GIO module cache on remove or purge. + Despite its name, the postrm can be invoked for reasons other than + package removal: in particular, the old version's postrm is run + during upgrades. + - postinst: Recreate GIO module directory if deleted by an older + postrm, to recover from the bug fixed here. + - postinst: Don't guard glib-compile-schemas or gio-querymodules with + a check for existence of a directory that is shipped in the .deb. + If such a directory has somehow gone missing, we want to see + a warning. This won't make the postinst fail, because we're ignoring + exit status anyway. + (Closes: #987913) + + -- Simon McVittie Sun, 02 May 2021 14:45:36 +0100 + +glib2.0 (2.68.1-1) experimental; urgency=medium + + * New upstream stable release + * d/tests/run-with-locales: Avoid FTBFS with locales-all installed + + -- Simon McVittie Thu, 15 Apr 2021 09:42:05 +0100 + +glib2.0 (2.68.0-1) experimental; urgency=medium + + * New upstream stable release + - Drop dead code from glib-compile-schemas + - Improve valgrind suppressions + - Fix error in g_bytes_icon_new() documentation + - Avoid close(-1) during error handling + - Fix copy/paste error in queue test + - Translation updates + * Add CVE ID references to previous changelog entries. + CVE IDs were not yet available at the time these vulnerabilities were + initially fixed. + + -- Simon McVittie Sat, 20 Mar 2021 15:42:00 +0000 + +glib2.0 (2.67.6-1) experimental; urgency=medium + + * New upstream release + - This fixes a symlink attack affecting file-roller. + When g_file_replace() is used with G_FILE_CREATE_REPLACE_DESTINATION + to replace a path that is a dangling symlink, previously it would + have also created the target of the symlink as an empty file, which + could conceivably be security-sensitive if the symlink is + attacker-controlled. (Closes: #984969; CVE-2021-28153) + * Revert test-dependency on libc6-dev, which should no longer be + necessary with the new upstream release. + + -- Simon McVittie Mon, 15 Mar 2021 18:18:48 +0000 + +glib2.0 (2.67.5-2) experimental; urgency=medium + + * debian/tests/control: Test-Depend on libc6-dev; the `pollable` test + requires it. See [upstream MR !1977][0]. The upstream tests now rely on + finding "libutil.so", which is in libc6-dev. Once that MR, or something + like it, is merged, we can remove this test-dep as the runtime library + will be being used. + [0]: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1977 + + -- Iain Lane Tue, 02 Mar 2021 18:29:23 +0000 + +glib2.0 (2.67.5-1) experimental; urgency=medium + + * New upstream release + + Fix more issues with `glib_typeof` macro from 2.67.3–2.67.4 (LP: + #1916705) + + Fix regression with some FD mappings passed to + `g_subprocess_launcher_spawnv()` (Closes: #983026) (LP: #1916701) + * debian/watch: Fix to not match `..`. The watch file was matching the + "Parent directory/" link and considering that the highest, since its + target is `..`. Expect 1+ digits to begin the version number. + + + -- Iain Lane Mon, 01 Mar 2021 17:18:36 +0000 + +glib2.0 (2.67.4-1) experimental; urgency=medium + + * New upstream release + - Among other changes, this should fix FTBFS on armel + * d/libglib2.0-0.symbols: Add g_spawn_async_with_pipes_and_fds + + -- Simon McVittie Wed, 17 Feb 2021 09:58:25 +0000 + +glib2.0 (2.67.3+git20210214-1) experimental; urgency=medium + + * d/changelog: Add bug reference for GHSL-2021-045 to previous entry + * New upstream git snapshot; among other changes: + - Fix regressions caused by the GHSL-2021-045 fixes in 2.67.3 + - Warn and fail on integer overflow in g_byte_array_new_take() + for arrays larger than G_MAXUINT + (Closes: #982779; CVE-2021-27218) + * d/libglib2.0-0.symbols: Add g_string_replace() + * Refresh patch series + * d/rules, d/tests: Generate various locales mentioned in the tests + * Mark dbus as . + Several of the installed-tests won't be built unless dbus-daemon is + available, so is insufficient. + * Move test-dependencies to Build-Depends-Arch. + We don't run the majority of the tests when we're only building the + documentation. + * Remove an unused Lintian override + * Add more Lintian overrides for test data + + -- Simon McVittie Sun, 14 Feb 2021 17:27:54 +0000 + +glib2.0 (2.67.3-1) experimental; urgency=medium + + * New upstream release + - Fix various integer overflows, some of them potentially exploitable + (Closes: #982778; CVE-2021-27219, GHSL-2021-045) + * Drop patches that came from upstream or were applied upstream + + -- Simon McVittie Thu, 04 Feb 2021 22:38:42 +0000 + +glib2.0 (2.67.2-1) experimental; urgency=medium + + * New upstream release + * Refresh patch series + * d/patches: Cherry-pick some fixes from upstream git master. + This is mostly for parity with the update to 2.66.x that I'm preparing + for unstable, which also includes the XDG_CURRENT_DESKTOP fixes. + * d/p/spawn-Don-t-set-a-search-path-if-we-don-t-want-to-search-.patch: + Make the g_spawn family only search PATH if G_SPAWN_SEARCH_PATH is used. + Previously, they would sometimes search /usr/bin:/bin:. for an + executable they should have only loaded from the current working + directory. In particular, this made gtk+3.0 fail its build-time tests + if ImageMagick display(1) happened to be installed. (Closes: #977961) + + -- Simon McVittie Wed, 27 Jan 2021 12:57:48 +0000 + +glib2.0 (2.67.1-1) experimental; urgency=medium + + * Branch for experimental and 2.67.x + * New upstream development release + * Temporarily use git to fetch upstream release. + The official tarball release doesn't seem to have made it onto mirrors. + * d/rules: Explicitly enable libelf dependency for gresource tool + * d/p/Handle-the-case-of-g_object_run_dispose-in-GBinding.patch: + Add patch from upstream to fix a regression in GBinding that caused + gnome-terminal-server to crash on startup + + -- Simon McVittie Fri, 11 Dec 2020 11:16:25 +0000 + +glib2.0 (2.66.8-1) unstable; urgency=medium + + * d/watch: Only watch for 2.66.x versions. + 2.68.0 has been released but will not be in bullseye. + * New upstream release + - Functionally equivalent to 2.66.7-2, except for the version number + and a change to Windows-specific code that is not used in Debian + * Drop patches that were included in the new upstream release + * d/p/glocalfileoutputstream-Tidy-up-error-handling.patch: + Add patch from upstream to clean up error handling. + After the fix for #984969, this function could end up calling close(-1), + which is harmless but gets flagged as an error by static analysis and + by error-checking instrumentation. Fixing this will prevent it from + obscuring real errors. + * Add CVE references in recent changelog entries. + CVE IDs for the vulnerabilities were not available at the time they were + fixed, but now they are. + + -- Simon McVittie Sat, 20 Mar 2021 15:35:19 +0000 + +glib2.0 (2.66.7-2) unstable; urgency=medium + + * d/changelog: Add bug numbers for integer overflows in previous versions + * Add patches to fix a symlink attack affecting file-roller. + When g_file_replace() is used with G_FILE_CREATE_REPLACE_DESTINATION to + replace a path that is a dangling symlink, previously it would have also + created the target of the symlink as an empty file, which could + conceivably be security-sensitive if the symlink is attacker-controlled. + (Closes: #984969; CVE-2021-28153) + + -- Simon McVittie Thu, 11 Mar 2021 10:23:38 +0000 + +glib2.0 (2.66.7-1) unstable; urgency=high + + * New upstream release + - Fix another regression caused by the GHSL-2021-045 fixes in 2.66.6 + - Warn and fail on integer overflow in g_byte_array_new_take() + for arrays larger than G_MAXUINT + (Closes: #982779; CVE-2021-27218) + - Disallow using currently-undefined D-Bus connection or server flags, + to prevent forward-compatibility problems with new security-sensitive + flags that are likely to be introduced in GLib 2.68 + * Drop previous patches for GHSL-2021-045 regressions, applied upstream + + -- Simon McVittie Thu, 11 Feb 2021 17:08:14 +0000 + +glib2.0 (2.66.6-2) unstable; urgency=high + + * d/patches: Add proposed fixes for regressions in 2.66.6. + Two functions that took either a positive length, or -1 to indicate + strlen(), had assertions with the wrong sense in 2.66.6, causing some + valid uses of those functions to regress. + * d/p/debian/61_glib-compile-binaries-path.patch: Remove. + This patch turns out to be unnecessary, and is harmful for + cross-compiling. Thanks to Helmut Grohne (Closes: #982213) + * Set high urgency to get the regression fixes into bullseye + + -- Simon McVittie Mon, 08 Feb 2021 19:43:08 +0000 + +glib2.0 (2.66.6-1) unstable; urgency=high + + * New upstream release + - Fix various integer overflows, some of them potentially exploitable + (Closes: #982778; CVE-2021-27219, GHSL-2021-045) + + -- Simon McVittie Thu, 04 Feb 2021 20:24:20 +0000 + +glib2.0 (2.66.5-1) unstable; urgency=medium + + * New upstream release, equivalent to 2.66.4-27-g0051c0635 + * Drop patches that were applied upstream + + -- Simon McVittie Wed, 03 Feb 2021 19:16:01 +0000 + +glib2.0 (2.66.4-4) unstable; urgency=medium + + * d/patches: Update patch series to upstream commit 2.66.4-27-g0051c0635 + - Improve test coverage for #977961 + - Stop valgrind reporting memory leaks in GSpawn in most cases + - Partially revert security hardening from 2.66.4-2: allow + DBUS_SESSION_BUS_ADDRESS to be taken from the environment by + setcap executables (to avoid regressing gnome-keyring) and by + setgid executables (to avoid regressing msmtp). + (Closes: #981420, #981555) + Note that this is likely to be reverted in GLib 2.70.x to provide + better hardening. The D-Bus session bus is not designed to be used + by processes that have elevated privileges. + + -- Simon McVittie Wed, 03 Feb 2021 13:55:41 +0000 + +glib2.0 (2.66.4-3) unstable; urgency=medium + + * Improve patch for #977961, and add basic test coverage + + -- Simon McVittie Thu, 28 Jan 2021 19:05:50 +0000 + +glib2.0 (2.66.4-2) unstable; urgency=medium + + * d/patches: Update patch series to upstream commit 2.66.4-18-g872181c4f + (excluding Windows-specific changes) + - Security hardening: in GIO, ignore various environment variables + if GIO is (inadvisably) used in a setuid process without sanitizing + the environment first, similar to CVE-2012-3524 + - Reject very long date strings early, instead of spending time + normalizing and parsing them + - Fix recursion in GPrivate + * d/p/spawn-Don-t-set-a-search-path-if-we-don-t-want-to-search-.patch: + Make the g_spawn family only search PATH if G_SPAWN_SEARCH_PATH is used. + Previously, they would sometimes search /usr/bin:/bin:. for an + executable they should have only loaded from the current working + directory. In particular, this made gtk+3.0 fail its build-time tests + if ImageMagick display(1) happened to be installed. (Closes: #977961) + + -- Simon McVittie Wed, 27 Jan 2021 11:33:06 +0000 + +glib2.0 (2.66.4-1) unstable; urgency=medium + + * New upstream release + + -- Simon McVittie Fri, 18 Dec 2020 17:26:51 +0000 + +glib2.0 (2.66.3-2) unstable; urgency=medium + + * Apply packaging changes from experimental to unstable: + - postinst: Clean up outdated copies of GLib if present, to avoid + infrequent upgrade issues on non-merged-/usr systems. + See #911225 and #949395 for more information. + (Closes: #896019, #954960, #955331) + * Add myself to Uploaders + * Standards-Version: 4.5.1 (no changes required) + * Swap Homepage field to something more GLib-specific + * d/gbp.conf: Change upstream branch to upstream/2.66.x. + 2.67.0 was already released, so it's inaccurate to say that 2.66.x + is the latest. + + -- Simon McVittie Wed, 02 Dec 2020 12:28:42 +0000 + +glib2.0 (2.66.3-1+exp1) experimental; urgency=medium + + * Merge from unstable + + -- Simon McVittie Thu, 19 Nov 2020 20:47:54 +0000 + +glib2.0 (2.66.3-1) unstable; urgency=medium + + * Team upload + * New upstream release + - Improve performance of processing files hidden via ./.hidden + - All other changes were already included in 2.66.2-1 + * Drop patches that were cherry-picked from upstream + * Stop reverting gtk-doc dependency version. + We now have a suitable gtk-doc in Debian. + * Drop a patch that was not applied upstream. + This was hoped to be a workaround for intermittent test failures, but + doesn't seem to have had the desired effect in practice. + * Mark the DBUS_COOKIE_SHA1 parts of gdbus-server-auth test as flaky. + This is not reliable enough to always pass on buildds, but is too + intermittent to be able to reproduce the failure in a development + environment, and DBUS_COOKIE_SHA1 is not an important enough feature + to justify failing the build for this. + As with other flaky tests, we still run this as an autopkgtest in an + attempt to get more useful information, but we ignore failure. + + -- Simon McVittie Thu, 19 Nov 2020 11:11:06 +0000 + +glib2.0 (2.66.2-1+exp1) experimental; urgency=medium + + * Branch for experimental + * postinst: Clean up outdated copies of GLib to avoid infrequent + upgrade issues on non-merged-/usr systems + (Closes: #896019, #954960, #955331) + + -- Simon McVittie Sun, 01 Nov 2020 13:11:00 +0000 + +glib2.0 (2.66.2-1) unstable; urgency=medium + + * Team upload + * New upstream release + - Add some missing (nullable) and (not nullable) annotations + * Drop patches that were cherry-picked from upstream + * Update patch series to upstream 2.66.2-9-g4daaf303a + - Fix race in socketclient-slow test + - Cope with sending fds in a D-Bus message that takes multiple writes + - Don't skip updating polled fd sources + - Add G_GNUC_PRINTF annotation to g_trace_mark() + * d/p/glib-tests-fileutils-Make-more-use-of-g_assert_no_errno.patch, + d/p/glib-tests-fileutils-Fix-expectations-when-running-as-roo.patch: + Add proposed patch to fix a test failure when running as root + (Closes: #973271) + * d/rules: Remove migration path from legacy -dbg package. + This was most recently shipped in Debian 9, and we don't support + upgrades from anything older than Debian 10. + * Drop obsolete workaround for #887629. + We don't support upgrades from versions older than Debian 10, so we can + drop workarounds that were only relevant for the upgrade from 9 to 10. + + -- Simon McVittie Sat, 31 Oct 2020 13:54:56 +0000 + +glib2.0 (2.66.1-2) unstable; urgency=medium + + * Cherry-pick patches from the glib-2-66 branch upstream + - Fixes the regression called out in 2.66.1-1's changelog. + * Add-a-test-for-the-6-days-until-EOM-bug.patch, + Fix-the-6-days-until-the-end-of-the-month-bug.patch: Cherry-pick upstream + mr!1705 to not break on timezones built with `zic -b slim` + + -- Iain Lane Fri, 16 Oct 2020 17:38:50 +0100 + +glib2.0 (2.66.1-1) unstable; urgency=medium + + * Team upload + * New upstream release + - A performance problem where timezones were reloaded from disk + every time a GTimeZone was created has been fixed (upstream issue + #2204), but this means that changes to /etc/localtime will not take + effect until a process restarts. Future changes in a subsequent + 2.66.x release will improve this. + - Security fix for incorrect scope/zone ID parsing in URIs + - Fix invalid Pointer Arithmetic in g_path_get_basename + - Fix cookie lifetimes in GDBus DBUS_COOKIE_SHA1 mechanism + - Fix faulty logic in DNS TXT record parsing + - trash portal: Handle portal failures + - gio-tool-trash: Prevent recursion to speed up emptying trash + - glist: Clarify that g_list_free() and friends only free an entire list + - gdatetime: Avoid integer overflow creating dates too far in the past + - Translation updates + * d/p/glocalfile-Never-require-G_LOCAL_FILE_STAT_FIELD_ATIME.patch, + d/p/gdbusauthmechanismsha1-Use-the-same-timeouts-as-libdbus.patch: + Drop patches that were applied upstream + + -- Simon McVittie Mon, 12 Oct 2020 09:31:27 +0100 + +glib2.0 (2.66.0-2) unstable; urgency=medium + + * Team upload + * d/p/glocalfile-Never-require-G_LOCAL_FILE_STAT_FIELD_ATIME.patch: + Add proposed patch to fix file copying on ZFS and CIFS (Closes: #970228) + * d/p/gdbus-server-auth-Don-t-usually-test-non-EXTERNAL-repeate.patch: + Add proposed patch to work around DBUS_COOKIE_SHA1 test failures + * d/p/Revert-gtk-doc-dependency-to-1.32.patch: Move to debian subdirectory. + This patch is not intended to go upstream. + + -- Simon McVittie Tue, 15 Sep 2020 22:12:49 +0100 + +glib2.0 (2.66.0-1) unstable; urgency=medium + + * Team upload + * New upstream stable release + - Fix missing tab in makefile rule + - guri: Fix user passed to g_uri_split_with_user() not being NULL'd + - Translation updates: + * d/watch: Only watch for stable releases + * d/p/gdbusauthmechanismsha1-Use-the-same-timeouts-as-libdbus.patch: + Add patch to fix intermittent test failures on slower architectures. + This narrowly missed the upstream code freeze, and should be in 2.66.1. + + -- Simon McVittie Fri, 11 Sep 2020 09:18:58 +0100 + +glib2.0 (2.65.3-1) experimental; urgency=medium + + * New upstream release + + Fixes to the new `statx()` calls — note that since GLib 2.65.2 uses + `statx()` (if available) instead of + `stat()`/`fstat()`/`lstat()`/`fstatat()`, syscall sandboxing for third + party applications might need to be updated + + Also includes "Fix splice behavior on cancellation", a fix for a bug + which was affecting tracker - particularly its autopkgtests. + + -- Iain Lane Thu, 03 Sep 2020 18:55:20 +0100 + +glib2.0 (2.65.2-1) experimental; urgency=medium + + * Team upload + * New upstream development release + * d/rules: Run gtk-doc checks, even if building indep-only. + Previously we would only run the gtk-doc checks if building + architecture-dependent and -independent packages in the same build, + which is done on Ubuntu amd64 buildds, but not on any Debian buildds. + * Reduce dependency to the version of gtk-doc-tools from unstable. + Instead of being some random snapshot from upstream git, this is the + last release plus some selected patches. In particular, it has enough + fixes to make the gtk-doc tests pass (Closes: #968975). + * d/libglib2.0-tests.lintian-overrides: Update + + -- Simon McVittie Tue, 25 Aug 2020 12:44:02 +0100 + +glib2.0 (2.65.1-1) experimental; urgency=medium + + [ Sebastien Bacher ] + * debian/control.in: + - let libglib2.0-tests Depends on libglib2.0-0 (= ${binary:Version}), + otherwise we can end up with failures due to out of sync versions + + [ Simon McVittie ] + * d/shlibs.local: Upgrade all binary packages in lockstep. + Like many projects where one source package builds multiple binary + packages, GLib has private headers that share non-public interfaces + between its binary packages. Instead of setting this up for individual + binary packages, we can tell dpkg-shlibdeps to generate lockstep + dependencies whenever one of our binary packages depends on our shared + libraries. + * d/watch, d/control.in, d/gbp.conf: Branch for experimental + * New upstream development release + - Require the experimental version of gtk-doc-tools. + GLib 2.65.x requires a version that hasn't been released yet. + - Update symbols file + - Drop patches that were applied upstream + + -- Simon McVittie Fri, 07 Aug 2020 15:44:34 +0100 + +glib2.0 (2.64.4-1) unstable; urgency=medium + + * Team upload + * New upstream release + - Improve async-signal-safety + * d/tests/build: Don't exercise static linking for GIO. + libmount will no longer support being linked statically from 2.35.2-8 + onwards. For now I'm continuing to test that the other libraries can + still be statically linked, but please consider them to be "at risk". + (Closes: #963933) + * Re-enable libmount support. + libmount no longer depends on libcryptsetup, avoiding the various + crashes that we are working around. Future versions will dlopen it + on-demand, which should also avoid those crashes. Bump the + build-dependency to a suitable version. + * d/p/tests-Use-g_assert_-in-cancellable-test-rather-than-g_ass.patch, + d/p/gcancellable-Fix-minor-race-between-GCancellable-and-GCan.patch: + Split combined d/p/git_gsource_segfault.patch into its two component + upstream commits, and add metadata + * d/p/glib-compile-resources-Fix-exporting-on-Visual-Studio.patch, + d/p/gdesktopappinfo-Fix-unnecessarily-copied-and-leaked-URI-l.patch: + Add post-release bugfixes from upstream + + -- Simon McVittie Tue, 07 Jul 2020 13:33:01 +0100 + +glib2.0 (2.64.3-2) unstable; urgency=medium + + * Team upload + * Temporarily disable libmount support. + Recent Debian revisions of libmount pull in libcryptsetup as a + dependency, for dm-verity support. libcryptsetup depends on json-c + and OpenSSL, causing crashes due to symbol conflicts with other + JSON libraries (jansson and json-glib, for example in firewalld and + virt-manager) and with statically-linked copies of OpenSSL (for + example in Steam and Minecraft). Until this is resolved in some + other way, disable libmount and parse /etc/fstab and /proc/mounts + ourselves, as we do in libglib2.0-udeb. + Mitigates: #963933, #963932, #963525, #963721 + + -- Simon McVittie Thu, 02 Jul 2020 10:05:03 +0100 + +glib2.0 (2.64.3-1) unstable; urgency=medium + + * Team upload + + [ Laurent Bigonville ] + * Drop the libgio-fam package, and install the fam GIO plugin in + libglib2.0-0 on Hurd ports. See: #885011 (Closes: #875915) + * Stop building the libgio-fam package on kFreeBSD ports. + It is no longer necessary now that gkqueuefilemonitor is available. + + [ Simon McVittie ] + * Clarify changelog entry regarding Hurd and kFreeBSD + * New upstream stable release + + -- Simon McVittie Fri, 29 May 2020 20:24:33 +0100 + +glib2.0 (2.64.2-1) unstable; urgency=medium + + [ Simon McVittie ] + * Add Breaks on older versions of gimp, which used a syntactically + invalid property name in a plugin, and would crash when GObject + rejects syntactically invalid property names + + [ Sebastien Bacher ] + * New upstream release + * debian/patches/git_gsource_segfault.patch: + - backport an upstream git change to fix a signal handler disconnect + segfault situation (lp: #1872153) + + -- Sebastien Bacher Wed, 15 Apr 2020 23:01:50 +0200 + +glib2.0 (2.64.1-1) unstable; urgency=medium + + * Team upload + * New upstream stable release + * d/p/tests-Skip-MemoryMonitor-test-if-GObject-Introspection-is.patch: + Drop patch, applied upstream + * Add Breaks on glib-networking-tests older than 2.63.2. + Those versions had a test that relied on TLS version fallback + behaviour that has now been removed. (Closes: #953766) + + -- Simon McVittie Sun, 15 Mar 2020 18:39:17 +0000 + +glib2.0 (2.64.0-2) unstable; urgency=medium + + * Team upload + * Merge packaging changes from unstable with new upstream release from + experimental + * d/control.in: Add Breaks on libgladeui-2-6 before 3.22.2. + Older versions used a syntactically invalid property name + "support warning", which GObject used to canonicalize to + "support-warning". GLib 2.64 made this check more strict (see #953010). + + -- Simon McVittie Tue, 10 Mar 2020 21:22:18 +0000 + +glib2.0 (2.64.0-1) experimental; urgency=medium + + * Team upload + * New upstream release + - Fixes a vulnerability where GSocketClient sometimes forgot to use + a configured proxy (CVE-2020-6750, Closes: #948554) + - Stop installing gio-launch-desktop, which no longer exists + - d/p/docs-Don-t-install-object-manager-example-separately.patch: + Drop, applied upstream + * d/p/debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch: + Treat testfilemonitor as a flaky test + * Standards-Version: 4.5.0 (no changes required) + * New upstream release + * d/p/tests-Skip-MemoryMonitor-test-if-GObject-Introspection-is.patch: + Skip MemoryMonitor test if GObject-Introspection is too old to know it + * Install a shell script implementation of the old gio-launch-desktop + executable. While not required for *this* GLib, it is required by + old processes that already had the old GLib (2.57.2 to 2.63.5) in + memory before the upgrade. This can be removed after Ubuntu 20.04 + and Debian 11 are both released. + + -- Simon McVittie Fri, 28 Feb 2020 17:16:04 +0000 + +glib2.0 (2.63.5-2) experimental; urgency=medium + + * Skip-unreliable-gdbus-threading-tests--by-default.patch: Skip all of + gdbus-threading test_method_calls_in_thread() has become (more?) + unreliable too. When skipped, the test bus doesn't get torn down properly + - it times out. Let's stop running these tests for now, until they are + made reliable. + + -- Iain Lane Wed, 19 Feb 2020 17:16:16 +0000 + +glib2.0 (2.63.5-1) experimental; urgency=medium + + [ Iain Lane ] + * New upstream release + + [ Philip Withnall ] + * Rework 01_gettext-desktopfiles.patch to not add new public API. + Downstreams should not be adding new public API to GLib. From some code + searching, this doesn’t appear to be used in more than one or two places, + so won’t be too inconvenient to drop. The original patch should either be + upstreamed (I’d be open to some form of it, if there’s still evidence it’s + useful) or dropped. If it’s upstreamed, the new keys should be + standardised. The alternative to this was to document the added public + API; its addition was causing the new gtk-doc tests in GLib to fail. + * Bump gtk-doc-tools dependency to >= 1.32-4 as GLib requires some fixes + pushed to gtk-doc after its 1.32 release. + * control: Bump Meson dependency to >= 0.52.0 for building the documentation + * Drop PKCS#11 APIs added in 2.63.1 (not stable yet) + - g_tls_certificate_new_from_pkcs11_uris() + * Remove patches applied upstream: + - tests-Skip-GMemoryMonitor-tests-if-the-dbusmock-template-.patch + - tests-optional-portal.patch + * d/p/docs-Don-t-install-object-manager-example-separately.patch: Add patch + from upstream to disable incorrect installation of some example + documentation + * Rework libmount Meson argument as it’s now a feature; see !1344 upstream + + -- Iain Lane Mon, 17 Feb 2020 17:47:17 +0000 + +glib2.0 (2.63.3-3) experimental; urgency=medium + + * debian/control.in: + - lower the libglib2.0-tests Depends on xdg-desktop-portal to a + Recommends since the portal is not available on some architectures + * debian/patches/tests-optional-portal.patch: + - skip the new memory monitor tests if the portal is not available, + that allows the tests to be still successful on architectures were + the portal is not available (e.g Ubuntu/i386) + + -- Sebastien Bacher Wed, 22 Jan 2020 09:36:27 +0200 + +glib2.0 (2.63.3-2) experimental; urgency=medium + + * debian/control.in: + - libglib2.0-tests Depends on xdg-desktop-portal, it's required by the + new low memory tests (and got enabled by the new python-dbusmock) + + -- Sebastien Bacher Thu, 16 Jan 2020 10:28:46 +0100 + +glib2.0 (2.63.3-1) experimental; urgency=medium + + [ Iain Lane ] + * New upstream release + + Add a `--glib-min-version` argument to `gdbus-codegen` which controls + breaks in the API of generated code + + Add `g_clear_list()` API to clear `GList`s to `NULL` + + Add a `GMemoryMonitor` API to be notified of memory pressure situations + using the low-memory-monitor project + + Add support for dispose functions for `GSource` implementations + + Tighten up validation of GObject signal and property names, allowing + performance improvements + * debian/tests/build: Style fixes, thanks to shellcheck. + * d/p/d/Disable-some-tests-on-slow-architectures-which-keep-faili.patch: + Rebase. Upstream have disabled these tests by default too (unless slow + mode is enabled), so we don't need to add a patch to do a similar thing. + * debian/libglib2.0-0.symbols: New symbols for 2.63.3 + * d/p/tests-Skip-GMemoryMonitor-tests-if-the-dbusmock-template-.patch: Add. + We don't have a new enough dbusmock in Debian at the minute (one is not + released yet). Skip the test if the required template isn't available. + * control: Add Depends for the new memory-monitor tests. + There are new tests, written in python, for GMemoryMonitor. They require + dbus-python, pygobject, and the GI bindings for GLib and GIO. + + [ Steve Langasek ] + * debian/tests/build: Make cross-test friendly + autopkgtest is soon to get a `-a ARCHITECTURE` switch, which will + cross-test autopkgtests. This is to be detected by the presence of the + `dpkg-architecture`-style family of variables being set in the + environment. + For build tests like `glib2.0`'s `build` test, this means that we should + test "${DEB_HOST_ARCH}" and invoke the cross toolchain as necessary. + (Closes: #946355) + + -- Iain Lane Wed, 18 Dec 2019 14:02:00 +0000 + +glib2.0 (2.63.2-1) experimental; urgency=medium + + * Team upload + * Merge packaging changes from unstable + - Support for pkg.glib2.0.noinsttest build profile + * d/control.in: Refer to debian/experimental branch. + This avoids false-positive warnings from vcswatch. + * New upstream release + - Drop patches that were applied upstream + * Rename pkg.glib2.0.noinsttest build profile to noinsttest. + This is now registered on . + * Update symbols file + + -- Simon McVittie Sat, 30 Nov 2019 10:55:48 +0000 + +glib2.0 (2.63.1-2) experimental; urgency=medium + + * d/p/Revert-glocalfileinfo-Only-return-file-mode-not-type-as-U.patch: + Revert "glocalfileinfo: Only return file mode, not type, as UNIX_MODE + attribute" This reverts commit bfdc5fc4fc84ef8518d2d1a328c8482cf5a38e98. + This commit changes the semantics of the `unix::mode` attribute, which + some things (the one we've noticed is ostree) rely on. + * d/p/test_copy_preserve_mode-Adjust-for-revert-semantics.patch: + test_copy_preserve_mode: Adjust for revert semantics. Now we're returning + the file type again, we need to mask it out to compare with the mode. + + -- Iain Lane Mon, 18 Nov 2019 13:59:35 +0000 + +glib2.0 (2.63.1-1) experimental; urgency=medium + + * New upstream release + - Add `g_array_steal()`, `g_ptr_array_steal()` and `g_byte_array_steal()` + APIs + - Add `g_get_os_info()` API + - Add `GMainContextPusher` API + - Add `g_warning_once()` API + - Allow passing empty `GValue`s to `g_param_value_set_default()` + - Always resolve `localhost` to loopback address in `GResolver` + - Escape header guards generated by `gdbus-codegen` better + - Fix crash in `g_spawn()` with high FD numbers due to use of `select()` + rather than `poll()` + - Limit recursion in `g_variant_parse()` + - Several usability improvements to command line `gio` tool + * debian/libglib2.0-0.symbols: Add new symbols for this release + * debian/patches/*: + - Drop backports we had which are in this release. + - Update to upstream master at cc1b53f74. There are several test fixes + that we might as well grab now. + + -- Iain Lane Wed, 06 Nov 2019 16:37:24 +0000 + +glib2.0 (2.62.5-1) unstable; urgency=medium + + * Team upload + * New upstream release + - Fixes a vulnerability where GSocketClient sometimes forgot to use + a configured proxy (CVE-2020-6750, Closes: #948554) + * Build-depend on libnss-myhostname | netbase if running tests. + This is an attempt to work around localhost not being a resolvable + name in some build environments, notably reproducible-builds. + (See #948834) + * Put the result of `getent ahosts localhost` and + `getent ahosts $(hostname)` in the build log, to check whether those + names are resolvable in the build environment. + * d/p/debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch: + Treat testfilemonitor as a flaky test + * Standards-Version: 4.5.0 (no changes required) + + -- Simon McVittie Tue, 25 Feb 2020 12:19:00 +0000 + +glib2.0 (2.62.4-2) unstable; urgency=medium + + * Team upload + * Adjust dependencies to avoid broken partial upgrades on arm64 during + libffi7 transition: + - Bump versioned Depends on libffi-dev to get a guarantee that we'll + depend on libffi7 + - Add Breaks on libgirepository-1.0-1 (<< 1.62.0-4~) so we cannot + get a GObject built with libffi7 but a libgirepository built with + libffi6 + + -- Simon McVittie Mon, 03 Feb 2020 15:12:40 +0100 + +glib2.0 (2.62.4-1) unstable; urgency=medium + + * Team upload + + [ Steve Langasek ] + * debian/tests/build: Make cross-test friendly (Closes: #946355) + + [ Iain Lane ] + * debian/tests/build: Style fixes + + [ Simon McVittie ] + * New upstream release + + -- Simon McVittie Mon, 30 Dec 2019 13:01:04 +0000 + +glib2.0 (2.62.3-2) unstable; urgency=medium + + * Team upload + * Rename pkg.glib2.0.noinsttest build profile to noinsttest. + This is now registered on . + + -- Simon McVittie Sun, 01 Dec 2019 16:05:01 +0000 + +glib2.0 (2.62.3-1) unstable; urgency=medium + + * Team upload + * New upstream release + - Drop patches that were applied upstream + * Don't build libglib2.0-tests under pkg.glib2.0.noinsttest build profile. + This is a prototype of the proposed standard build profile noinsttest. + If the build profiles include both nocheck and pkg.glib2.0.noinsttest, + we can drop the libdbus-1-dev build-dependency without harming test + coverage or altering the contents of binary packages. + * d/gbp.conf: Use upstream/2.62.x branch + + -- Simon McVittie Mon, 25 Nov 2019 08:47:58 +0000 + +glib2.0 (2.62.2-3) unstable; urgency=medium + + * Team upload + + [ Iain Lane ] + * control: Drop `debian/experimental` from Vcs-* + + [ Simon McVittie ] + * Build-depend on libdbus-1-dev for better test coverage + * Update to upstream commit 2.62.2-28-g3cf25070e: + - d/p/goption-Relax-assertion-to-avoid-being-broken-by-kdeinit5.patch: + Fix assertion failure when called from a process that overwrites its + argv, such as kdeinit5 + - d/p/gdbus-peer-Specifically-listen-on-127.0.0.1.patch: + Improve reliability of gdbus-peer test in some container environments + - d/p/gdbusserver-Delete-socket-and-nonce-file-when-stopping-se.patch, + d/p/gdbusserver-Keep-a-strong-reference-to-the-server-in-call.patch, + d/p/gdbusauthmechanismsha1-Remove-unnecessary-g_warning-calls.patch, + d/p/gdbusauthmechanismsha1-Create-.dbus-keyrings-directory-re.patch, + d/p/tests-Move-main-loop-and-test-GUID-into-test-functions-in.patch, + d/p/tests-Isolate-directories-in-gdbus-peer-test.patch, + d/p/gdbus-peer-test-Improve-diagnostics-if-g_rmdir-fails.patch, + d/p/gdbus-peer-test-Stop-GDBusServer-before-tearing-down-temp.patch, + d/p/gdbus-peer-test-Use-unix-dir-address-if-exact-format-does.patch, + d/p/gdbus-server-auth-test-Create-temporary-directory-for-Uni.patch: + Mark as applied upstream in 2.62.x branch + * d/p/gdbus-server-auth-test-Include-gcredentialsprivate.h.patch: + Apply patch from 2.63.x to fix missing coverage in test for #941018 + * d/p/Make-ld-executable-configurable.patch: + Apply patch from 2.63.x to use cross ld where necessary + * d/p/gdbus-server-auth-test-Create-temporary-directory-for-Uni.patch: + Mark as applied upstream in 2.63.x branch + * Improve patch metadata: use more URLs for bug references + + -- Simon McVittie Wed, 06 Nov 2019 09:02:14 +0000 + +glib2.0 (2.62.2-2) unstable; urgency=medium + + * Team upload + * Update to upstream commit 2.62.2-14-gfcbb88823: + - d/p/gdesktopappinfo-Allocate-DesktopFileDir-structs-dynamical.patch, + d/p/gdesktopappinfo-Cancel-file-monitor-when-resetting-a-Desk.patch, + d/p/glocalfilemonitor-Keep-a-weak-ref-to-the-monitor-in-GFile.patch: + Fix intermittent test failures for GDesktopAppInfo (Closes: #941550) + - d/p/gvariant-Limit-recursion-in-g_variant_parse.patch: + Ensure that parsing a text-format GVariant does not run out of stack + space + - d/p/tests-Use-objcopy-from-the-cross-compilation-file-if-conf.patch, + d/p/docs-Add-objcopy-to-example-cross-compilation-file.patch: + Use the appropriate architecture's objcopy when cross-compiling + - d/p/gtestutils-Add-additional-non-NULL-check-in-g_assert_cmpm.patch: + Avoid false positive NULL dereference warnings in g_assert_cmpmem() + - d/p/gspawn-Port-to-g_poll-from-select.patch: + Fix launching subprocesses when a very large number of fds are open + - d/p/gcredentialsprivate-Document-the-various-private-macros.patch, + d/p/credentials-Invalid-Linux-struct-ucred-means-no-informati.patch, + d/p/GDBus-prefer-getsockopt-style-credentials-passing-APIs.patch: + Ensure libdbus clients can authenticate with a GDBusServer like the + one in ibus (Closes: #941018) + * d/p/gdbusserver-Delete-socket-and-nonce-file-when-stopping-se.patch, + d/p/gdbusserver-Keep-a-strong-reference-to-the-server-in-call.patch, + d/p/Add-a-test-for-GDBusServer-authentication.patch: + Backport regression test for #941018 from upstream git master + * d/p/gdbusauthmechanismsha1-Remove-unnecessary-g_warning-calls.patch, + d/p/gdbusauthmechanismsha1-Create-.dbus-keyrings-directory-re.patch, + d/p/tests-Move-main-loop-and-test-GUID-into-test-functions-in.patch, + d/p/tests-Isolate-directories-in-gdbus-peer-test.patch: + Backport reliability fixes for gdbus-peer test from upstream git master + * d/p/gdbus-peer-test-Improve-diagnostics-if-g_rmdir-fails.patch, + d/p/gdbus-peer-test-Stop-GDBusServer-before-tearing-down-temp.patch, + d/p/gdbus-peer-test-Use-unix-dir-address-if-exact-format-does.patch, + d/p/gdbus-server-auth-test-Create-temporary-directory-for-Uni.patch: + Add some proposed patches to improve GDBus unit tests + * d/p/debian/mimeapps-test-Mark-as-flaky.patch: + Drop patch, hopefully no longer needed with #941550 fixed + * d/p/debian/taptestrunner-Stop-looking-like-an-executable-script.patch: + Make taptestrunner non-executable to avoid a Lintian warning + + -- Simon McVittie Wed, 30 Oct 2019 08:45:56 +0000 + +glib2.0 (2.62.2-1) unstable; urgency=medium + + * New upstream release + + Fixes use after free when calling g_dbus_connection_flush_sync() in a + dedicated thread (LP: #1848202) + + -- Iain Lane Fri, 25 Oct 2019 10:54:42 +0100 + +glib2.0 (2.62.1-1) unstable; urgency=medium + + * Team upload + * d/watch: Only watch for even-numbered (stable) releases + * New upstream release + - Fix regression that made G_FILE_COPY_TARGET_DEFAULT_PERMS result in + private permissions rather than respecting umask (Closes: #505398) + - d/p/g_file_info_get_modification_date_time-Calculate-in-integ.patch, + d/p/Always-build-tests-if-we-enabled-installed-tests.patch: + Drop patches that were applied upstream + * d/p/debian/mimeapps-test-Mark-as-flaky.patch: + Mark mimeapps test as flaky (see #941550) + + -- Simon McVittie Mon, 07 Oct 2019 09:46:24 +0100 + +glib2.0 (2.62.0-3) unstable; urgency=medium + + * Team upload + * Merge packaging from 2.60.x branch previously in unstable + - No changes since 2.62.0-2, except in d/changelog + - d/p/debian/Disable-an-optimization-when-building-with-gcc-9.patch: + Remove workaround for #931921, which turned out to be a clutter bug + * d/p/Always-build-tests-if-we-enabled-installed-tests.patch: + Add patch to fix installation of installed-tests in cross-builds + (Closes: #941509) + * d/p/g_file_info_get_modification_date_time-Calculate-in-integ.patch: + Add patch to fix intermittent g-file-info test failures on i386 + (Closes: #941547) + * libglib2.0-dev: Suggest libgirepository1.0-dev, for the GIR files + (Closes: #914152) + * d/gbp.conf: Use debian/master branch + * Standards-Version: 4.4.1 (no changes required) + + -- Simon McVittie Wed, 02 Oct 2019 09:13:12 +0100 + +glib2.0 (2.60.6-2) unstable; urgency=medium + + * Team upload + * d/rules: Edit debcrossgen output instead of using a modified version. + This fixes use of CFLAGS, etc. during cross-compilation. + (Closes: #933560) + * Remove obsolete permissions fixing. + Issue 1539 was fixed upstream. + * d/p/debian/Disable-an-optimization-when-building-with-gcc-9.patch: + Disable an optimization when building with gcc-9, instead of forcing + gcc-8. This avoids depending on an old gcc, and should be easier to + deal with for cross-compilation. (Workaround for #931921) + * d/p/gmessages-Only-use-structured-logs-if-GLIB_VERSION_MAX_AL.patch: + Update to upstream glib-2-60 branch at commit 2.60.6-2-ga365528f6 + - Don't use structured logging if GLIB_VERSION_MAX_ALLOWED < 2.56 + + -- Simon McVittie Tue, 13 Aug 2019 10:32:40 +0100 + +glib2.0 (2.62.0-2) unstable; urgency=medium + + * Team upload. + * Upload to unstable. (Closes: #940161) + + -- Andreas Henriksson Mon, 30 Sep 2019 12:33:16 +0200 + +glib2.0 (2.62.0-1) experimental; urgency=medium + + * New upstream release + + Fix new `GFileInfo` APIs to work when + `G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC` was not queried + + -- Iain Lane Mon, 09 Sep 2019 15:41:48 +0100 + +glib2.0 (2.61.3-1) experimental; urgency=medium + + * New upstream release + * d/p: Drop cherry-picks from upstream branch which we now have + * d/p/d/Disable-an-optimization-when-building-with-gcc-9.patch: Drop, + clutter has been fixed now (thanks Simon) + * d/p/*: Refresh via gbp-pq as necessary + + -- Iain Lane Wed, 04 Sep 2019 17:29:23 +0100 + +glib2.0 (2.61.2-2) experimental; urgency=medium + + * Team upload + * d/p/cond-test-Don-t-make-assumptions-about-struct-sigaction-m.patch: + Add proposed patch to fix FTBFS due to a test failure on mips* + + -- Simon McVittie Tue, 13 Aug 2019 10:29:29 +0100 + +glib2.0 (2.61.2-1) experimental; urgency=medium + + * Team upload + * New upstream release + * d/patches: Update to upstream git master, commit 2.61.2-23-g870b30bd7 + - Fix regression in g_mkdir_with_permissions() + - Fix a memory leak + - Update translations: es, id, ro + * Merge changes from unstable + * Refresh patch series + * d/p/debian/06_thread_test_ignore_prctl_fail.patch: + Use g_test_skip() when skipping test + * d/p/GIO-tests-Don-t-do-clever-tricks-with-objcopy.patch: + Drop workaround for #932287, and build-depend on fixed binutils on + mips64el instead + * d/rules: Edit debcrossgen output instead of using a modified version. + This fixes use of CFLAGS, etc. during cross-compilation. + (Closes: #933560) + * d/libglib2.0-0.symbols: Update + * Remove obsolete permissions fixing. + Issue 1539 was fixed upstream. + * libglib2.0-tests: Depend on libglib2.0-dev-bin. + This is required for the new mkenums and genmarshal tests. + * d/p/debian/Disable-an-optimization-when-building-with-gcc-9.patch: + Disable an optimization when building with gcc-9, instead of forcing + gcc-8. This avoids depending on an old gcc, and should be easier to + deal with for cross-compilation. (Workaround for #931921) + + -- Simon McVittie Mon, 12 Aug 2019 09:32:26 +0100 + +glib2.0 (2.60.6-1) unstable; urgency=medium + + * Team upload + * New upstream release, functionally equivalent to 2.60.5 with the + patches we were already applying + - d/p/portal-Add-a-getter-for-dconf-access.patch, + d/p/settings-Tweak-priorities-for-keyfile-backend.patch, + d/p/key-file-Handle-filename-being-NULL.patch: + Drop, applied upstream + * d/p/tests-Fix-data-race-in-gmenumodel-test.patch, + d/p/tests-Fix-data-race-in-task-test.patch: + Add patches from upstream git master to fix data races in tests. + In particular, the one for gmenumodel might solve an unreproducible + test failure on i386 (see #932678). + * d/p/debian/gmenumodel-test-Mark-as-flaky.patch, + d/p/debian/gvariant-test-Don-t-run-at-build-time-on-mips.patch: + Skip more tests at build-time and during the non-flaky autopkgtest. + The unreproducible gmenumodel test failure on i386 might in fact be + fixed by d/p/tests-Fix-data-race-in-gmenumodel-test.patch, but it's + hard to be sure about that. The gvariant fuzz test is catastrophically + slow on certain mips CPUs and so is impractical to run there. + (Closes: #932678) + * Standards-Version: 4.4.0 (no changes required) + * Use debhelper compat level 12 + - Stop explicitly passing -V to dh_makeshlibs, it is now the default + - Disable dh_dwz for libglib2.0-udeb. + This avoids an apparent debhelper bug in which dh_dwz generates + multifiles for udebs, but dh_strip does not remove them from the + udeb's staging directory. (Workaround for #933212) + * Stop overriding libexecdir. + Since FHS 3.0 (Policy 4.1.5), /usr/libexec is considered valid, + and since debhelper compat level 12 it is the default. + In this particular package this only affects the installed-tests. + * Remove an obsolete Lintian override + + -- Simon McVittie Sat, 27 Jul 2019 16:57:55 +0100 + +glib2.0 (2.60.5-1) unstable; urgency=medium + + * Team upload + * Prepare GLib 2.60.x stable branch for unstable + * New upstream release + * d/p/portal-Add-a-getter-for-dconf-access.patch, + d/p/settings-Tweak-priorities-for-keyfile-backend.patch, + d/p/key-file-Handle-filename-being-NULL.patch: + Add post-release fixes from upstream glib-2-60 branch + * d/p/GIO-tests-Don-t-do-clever-tricks-with-objcopy.patch: + Don't do strange things with objcopy while testing GResource, + while we work out what is going on in mips64el builds. + Mitigates: #932287 + + -- Simon McVittie Wed, 17 Jul 2019 21:36:30 +0100 + +glib2.0 (2.61.1-2) experimental; urgency=medium + + * control, rules: Build with gcc-8. See #931921 - when we're built with + gcc-9, some applications that use GLib might start hanging. + + -- Iain Lane Fri, 12 Jul 2019 11:37:01 +0100 + +glib2.0 (2.61.1-1) experimental; urgency=medium + + * New upstream release + + `g_unichar_isxdigit()` and `g_unichar_xdigit_value()` now handle + full-width characters (U+FF21–U+FF26 and U+FF41–U+FF46) + + Deprecate `gtester` utility and its test reporting format and enable TAP + output by default instead — the `--tap` option to tests is now a no-op + + Add `g_test_summary()` to allow test authors to programmatically summarise + what each unit test in a test suite does + * Upgrade to Unicode Character Database v12.1 + + More IPv6 Happy Eyeballs fixes to `GNetworkAddress` and `GSocketClient` + + Fix valgrind and gdb support for the new `GHashTable` changes + + Fix GTask wait times growing faster than the number of task threads + + Add `g_autoqueue()` helper macros, similar to `g_autolist()` + + Add pre-allocated link helpers for `GList` and `GQueue`: + - `g_list_insert_before_link()` + - `g_queue_insert_before_link()` + - `g_queue_insert_after_link()` + + Improve network availability detection with NetworkManager to treat lower + levels of connectivity as having reduced availability + + Add `g_clear_signal_handler()` to allow disconnecting from a `GObject` + signal and clearing the signal handler ID to zero in a single call + + Add `g_autoptr()` support for `GRWLock` + * 81-skip-monitor-test-on-non-linux.patch: Drop. This test was removed + upstream. + * debian/libglib2.0-0.symbols: Update + + -- Iain Lane Fri, 05 Jul 2019 17:45:06 +0100 + +glib2.0 (2.60.4-1) experimental; urgency=medium + + * New upstream release (LP: #1832457) + + Fixes to improved network status detection with NetworkManager (#1788) + + Leak fixes to some `glib-genmarshal` generated code + + Further fixes to the Happy Eyeballs (RFC 8305) implementation + + File system permissions fix to clamp down permissions in a small time window + when copying files (CVE-2019-12450) + + Bugs fixed: + - Please revert #535 gmacros: Try to use the standard __func__ first in + G_STRFUNC + * gfile-Limit-access-to-files-when-copying.patch: Drop. It's in this version + upstream. + * d/p/*: Refresh through gbp pq + + -- Iain Lane Wed, 12 Jun 2019 09:15:11 +0100 + +glib2.0 (2.60.3-2) experimental; urgency=medium + + * Team upload + * d/p/gfile-Limit-access-to-files-when-copying.patch: + Backport patch from upstream to ensure files don't temporarily have + less restrictive permissions during copying + (Closes: #929753, CVE-2019-12450) + * Drop d/p/debian/04_homedir_env.patch: + Remove legacy support for Debian-specific G_HOME environment variable. + GLib has respected the HOME environment variable in the conventional + way since wheezy. Only two packages (pygtk and ruby-graphviz) still + set G_HOME without also setting HOME. + * Drop d/p/debian/90_gio-modules-multiarch-compat.patch: + Remove legacy support for loading modules from /usr/lib/gio/modules. + All the known packages containing GIO modules (dconf, glib-networking + and gvfs) migrated to /usr/lib/${DEB_HOST_MULTIARCH}/gio/modules + before wheezy. + * Register documentation in doc-base via symlinks in /usr/share/doc. + The doc-base specification requires this, presumably for the benefit + of tools that export /usr/share/doc via HTTP (see #925200), and + Lintian 2.12 added a warning for not doing so. + + -- Simon McVittie Tue, 04 Jun 2019 11:03:28 +0100 + +glib2.0 (2.60.3-1) experimental; urgency=medium + + * New upstream releases 2.60.1 2.60.2 2.60.3, fixing many bugs: + + build: Fix a typo in the test whether _NL_ABALTMON_n is supported + + Critical in g_socket_client_async_connect_complete + + Fix crash when displaying notifications on macOS (!786) + + Fix documentation for `gdbus-tool wait` to use correct units + + Fix typo in German translation + + glib/date test fails + + glib/gconstructor.h: Include stdlib.h for MSVC builds + + GNetworkAddressAddressEnumerator unsafely modifies cache in + GNetworkAddress + + gnetworkaddress: Fix parallel enumerations interfering with eachother + + gnetworkmonitornm: Fix network available detection + + GResource generation test incompatible with stable LLVM on Linux + + gschema.dtd: Add target attribute to alias + + gsocketclient: Fix a leak in the connection code + + Improve network status detection with NetworkManager + + Leaks in gsocketclient.c connection code + + test_month_names: assertion failed + + tests: Update month name check for Greek locale + + Update gdb pretty-printer for GHashTable + + Various fixes to small key/value support in `GHashTable` + + New GHashTable implementation confuses valgrind + + more GHashTable fixes + + GDB pretty-printer for GHashTable no longer works + + ghash: Disable small-arrays under valgrind + + -- Iain Lane Thu, 23 May 2019 16:59:32 +0100 + +glib2.0 (2.60.0-1) experimental; urgency=medium + + * New upstream release + + Further fixes to the Happy Eyeballs (RFC 8305) implementation + + Add support for the XDG trash portal + * Call dh_python3 for all packages and add Depends to libglib2.0-tests. + The tests now ship a "static-link.py" test. While it early-exits + currently, we still need the right dependencies to be able to do that. + Call dh_python3 for libglib2.0-test's private directory, and while we're + here make sure that it is called for all packages too. + * flaky autopkgtest: `closures` has been renamed to `closure-refcount` + * Refresh and drop patches. + - d/p/flaky-socket-service-test/*: Drop, applied upstream. + - d/p/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch: + Refresh. + + -- Iain Lane Tue, 05 Mar 2019 15:32:41 +0000 + +glib2.0 (2.59.3-2) experimental; urgency=medium + + [ Philip Withnall ] + * debian: Drop GVariant alignment patches which are no longer needed. + The upstream 2.59.0 release contained commit + 0f2a6c61c9c5e34d57293fb6987b21f3d1feb1cb, which automatically aligns + GVariants at construction time. The realignment in the tests was a + workaround for this. + See upstream issue https://gitlab.gnome.org/GNOME/glib/issues/1342. + + [ Iain Lane ] + * Cherry-pick fixes for upstream bug #1679 to fix a flaky test. + This is apparently more flaky on the autopkgtest machines than elsewhere + - it's quite consistently failing there. + + -- Iain Lane Wed, 27 Feb 2019 10:21:40 +0000 + +glib2.0 (2.59.3-1) experimental; urgency=medium + + * New upstream release + + Fix support for g_get_user_special_dir() on macOS, including support for + the Downloads directory + + Ensure that cancelling a GTask cannot cause its callback to be called + synchronously (in the same call chain as the original *_async() call) + + Further fixes to the Happy Eyeballs (RFC 8305) implementation + + Various fixes for installation of installed tests + * Refresh and drop patches. + Drop gio-tests-Install-test1.overlay-file-when-building-instal.patch, + tests-Install-the-slow-connect-preload.so-library-and-use.patch, + fixed upstream. + + -- Iain Lane Wed, 20 Feb 2019 14:25:13 +0000 + +glib2.0 (2.59.2-2) experimental; urgency=medium + + * Install `test1.overlay' file, which is needed for the installed tests. + * tests: Install the slow-connect-preload.so library and use it + + -- Iain Lane Mon, 11 Feb 2019 10:25:27 +0000 + +glib2.0 (2.59.2-1) experimental; urgency=medium + + * New upstream release + + Fix check on GDBusMessage size when reading it. + + Add async GIO API: g_file_query_default_handler_async(), + g_app_info_launch_uris_async() + + Fix some bugs in the Happy Eyeballs implementation. + + Install a new generated header with enum types for Unicode enums. + + Support the XDG trash portal. + + Autotools support is gone. + + g_format_size() now uses a no-break space to separate digits and units; + translations will need to be updated accordingly. + + New g_queue_clear_full() API. + + Fix argument quoting on win32 when spawning subprocesses. + + Allow polling more than 64 handles on win32 using g_poll(). + + Tag various tests as ‘flaky’. These are no longer run routinely on our + upstream CI machines, and downstream packagers may want to not run them + (or not treat those test failures as package build failures) on their + test machines either. They are in the `flaky` test suite. + + Add overlay support to g_resources_get_info(). + + Support defaults and locks in the keyfile GSettings backend. This will + be used for flatpaks. + + Accept unquoted strings in the keyfile GSettings backend to simplify + things for sysadmins. + + Update our contribution guidelines (`CONTRIBUTING.md`). + + Add writev() and writev_all() APIs to GOutputStream and + GPollableOutputStream, and provide implementations of them for many + subclasses. + * Refresh patches, drop trash test patches which are upstream now + * build-time tests: Run "flaky" suite separately and non fatally + * debian/libglib2.0-0.symbols: Add new symbols from 2.59.{1,2} + + -- Iain Lane Wed, 06 Feb 2019 17:09:28 +0000 + +glib2.0 (2.59.0-1) experimental; urgency=medium + + * New upstream release + * Update patches and drop upstreamed ones + * debian/control: Update meson BD to ≥ 0.48.0 per upstream + * debian/rules: enable-selinux takes "enabled" or "disabled" now. + Not true/false. + * debian/*: Update for experimental + * debian/libglib2.0-0.symbols: Update with new symbols for this release + + -- Iain Lane Thu, 17 Jan 2019 18:43:00 +0000 + +glib2.0 (2.58.3-3) unstable; urgency=medium + + * control, rules: Build with gcc-8. See #931921 - when we're built with + gcc-9, some applications that use GLib might start hanging. + + -- Iain Lane Fri, 12 Jul 2019 11:38:21 +0100 + +glib2.0 (2.58.3-2) unstable; urgency=medium + + * Team upload + * d/p/gfile-Limit-access-to-files-when-copying.patch: + Backport patch from upstream to ensure files don't temporarily have + less restrictive permissions during copying + (Closes: #929753, CVE-2019-12450) + * d/watch: Only watch for 2.58.x releases now that 2.60.x is out + * Add cross-reference to #919777 in previous changelog entry + + -- Simon McVittie Mon, 03 Jun 2019 22:37:45 +0100 + +glib2.0 (2.58.3-1) unstable; urgency=medium + + * Team upload + + [ Iain Lane ] + * debian/gbp.conf: Use upstream/2.58.x + + [ Simon McVittie ] + * New upstream release + - Fix crashes related to the GUnixMount API (Closes: #919777) + - Make G_DEFINE_INTERFACE compatible with g++ -Wint-in-bool-context + - Drop patches that were applied upstream + * d/p/gdbusmessage-Fix-check-on-upper-limit-of-message-size.patch: + Add patch from upstream glib-2-58 branch to limit the maximum size of + D-Bus messages according to the protocol specification + (the limit was 256M, and is now the correct 128M) + + -- Simon McVittie Thu, 07 Feb 2019 08:28:56 +0000 + +glib2.0 (2.58.2-4) unstable; urgency=medium + + [ Simon McVittie ] + * Update patch metadata + + [ Iain Lane ] + * trash-test-Don-t-assume-that-.local-exists.patch, + trash-test-Don-t-rely-on-being-able-to-determine-mount-po.patch: + Cherry pick two patches by Simon McVittie (slightly modified by Iain Lane) + to fix the trash test on Launchpad autobuilders. + + -- Iain Lane Thu, 17 Jan 2019 11:27:34 +0000 + +glib2.0 (2.58.2-3) unstable; urgency=medium + + * Team upload + * Release to unstable + * Standards-Version: 4.3.0 (no changes required) + * d/p/gvariant-test-Also-force-alignment-for-tuple-test-data.patch: + Mark as forwarded + * debian/Skip-unreliable-test_threaded_singleton-by-default.patch: + Don't run test_threaded_singleton() at build-time or in the part of + the autopkgtest run that must succeed. Run it from d/tests/flaky + instead. + + -- Simon McVittie Fri, 04 Jan 2019 08:43:36 +0000 + +glib2.0 (2.58.2-2) experimental; urgency=medium + + * Team upload + * d/p/gvariant-test-Also-force-alignment-for-tuple-test-data.patch: + Fix gvariant test failure on s390x by forcing more test data to be aligned + (Closes: #917980) + * d/p/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch, + d/tests/flaky: + Only run closures test on arm* as part of a separate, flaky autopkgtest. + This test does not seem to be reliable enough for its failures to be + treated as release-critical, at least on arm*. If we run too many + iterations, it fails on CPUs where 16-bit accesses are slow; if we run + too few, it occasionally fails when one thread starves another. + (Closes: #917983) + * d/p/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch, + d/p/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch: + d/tests/flaky: + Use g_test_skip() for flaky tests, and run them from d/tests/flaky + + -- Simon McVittie Thu, 03 Jan 2019 09:35:04 +0000 + +glib2.0 (2.58.2-1) experimental; urgency=medium + + * Team upload + * New upstream release + * Drop many patches that were applied upstream + * d/p/tests-Allocate-gvariant-data-from-the-heap-to-guarantee-a.patch: + Add patch from upstream to fix alignment of GVariant test data + * d/libglib2.0-0.symbols: Update for new ABI + * d/tests/installed-tests: Log execution environment + * postinst: Convert triggers into a function + * postinst: Quote strings with #TOKENS# to fix syntax highlighting + * postinst: Add a vim modeline + + -- Simon McVittie Tue, 01 Jan 2019 10:59:39 +0000 + +glib2.0 (2.58.1-6) experimental; urgency=medium + + * Team upload + * d/p/closures-test-Avoid-timeout-on-ARM64-CPUs.patch: + Rename from + d/p/debian/closures-test-Run-fewer-iterations-on-ARM64-and-armhf.patch, + increase the test timeout to prevent this test from timing out on + Cortex-A57 CPUs when building with Meson, and mark as forwarded + upstream + * Disable xattr support on kFreeBSD. + kFreeBSD has stub implementations of getxattr() etc. which will + always fail. Autoconf considers these to be present, but Meson + detects them and treats them as absent, resulting in configuration + failure. + + -- Simon McVittie Tue, 06 Nov 2018 14:19:18 +0000 + +glib2.0 (2.58.1-5) experimental; urgency=medium + + * Team upload + * d/p/*: + Update to upstream glib-2-58 branch as of 2.58.1-89-g7aa52a7d5, + except for translations + * d/p/mainloop-test-Fix-race-conditions.patch: + Add patch from upstream git master to fix race conditions in + mainloop test + * d/p/meson-Define-__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4-on-GNU-Li.patch: + Add proposed patch to fix detection of atomic operations on armel + * Respect nocheck in DEB_BUILD_OPTIONS + * Adjust test timeouts: + - Increase armel, armhf, hppa timeout multiplier from x3 to x5 + - Reduce mips*, sparc* timeout multiplier from x10 to x5 + - Reduce timeout multiplier for architectures known to have qemu + buildds from x50 to x20 + * d/rules: Set Meson cross properties using a modified debcrossgen. + This avoids embedding a local copy of GNUlib (v)(sn)printf when + cross-compiling. (Workaround for #912559) + + -- Simon McVittie Fri, 02 Nov 2018 19:05:22 +0000 + +glib2.0 (2.58.1-4) experimental; urgency=medium + + * Team upload + * d/rules: Deduplicate test invocation + * Use `meson test` directly, instead of going via `ninja test` + * Multiply Meson test timeouts. + Use x3 timeouts for most architectures (in general the timeouts in + the upstream Meson build system are somewhat optimistic), x10 for + the mips and sparc families, and x50 for architectures known to + use qemu for buildds. + * Enable FAM support on Hurd and kFreeBSD. + In the Autotools build system this was auto-detected, but in Meson it + is off by default and must be explicitly enabled if wanted. + * d/p/meson-Mark-1bit-emufutex-test-as-slow.patch: + Increase timeout for the 1bit-emufutex test + + -- Simon McVittie Fri, 19 Oct 2018 09:55:19 +0100 + +glib2.0 (2.58.1-3) experimental; urgency=medium + + * Team upload + * Upload to experimental to check that everything is OK with the + switch to Meson + * Switch build system to Meson as recommended by upstream + - Stop removing .la files: Meson doesn't build those + - d/p/debian/61_glib-compile-binaries-path.patch: Change the same + path if we build with Meson + - d/patches: Apply patches proposed for backport from master to + glib-2-58 in upstream MR 392. These fix various build issues, + mostly around Meson. Some of these patch Windows-specific code, + but they are likely to be in 2.58.2 and upstream asked for wider + testing, so I'm applying them anyway, to test the complete set. + - d/p/Spelling-*.patch: + MR 392 also applies patches from upstream git master to fix various + spelling mistakes detected by Lintian + * Always generate testmarshal.h, even when cross-compiling + (Closes: #908334) + * Fix static linking and make sure it won't regress, prompted by + comparing the Autotools and Meson builds: + - Add missing -dev dependencies on libffi-dev, libmount-dev, + libselinux1-dev + - d/p/Autotools-Move-libmount-from-Libs.private-to-Requires.pri.patch: + Add patch from upstream git master to fix static linking with libgio + - d/tests/build: Exercise all libraries + - d/tests/build-static: Exercise static linking + * d/rules: Fix some permissions (equivalent of #1539 upstream) + * Add Lintian override for a spelling-error-in-binary false positive + * Add some Lintian overrides for hardening-no-fortify-functions. + These objects mostly don't use libc directly. + * Remove /usr/bin/gio-launch-desktop symlink. + It's an implementation detail of libgio, and isn't intended to be + run directly. Removing it from PATH silences a Lintian warning about + it not having a man page. + * Don't delete compiled GSettings schemas during purge if the dpkg + reference count is greater than 1. This avoids deleting and regenerating + it unnecessarily if another architecture's libglib2.0-0 is still + installed. (Closes: #775854) + * d/tests/installed-tests: Replace deprecated $ADTTMP with $AUTOPKGTEST_TMP + * d/tests/control: Mark build tests as superficial (see #904979) + + -- Simon McVittie Thu, 18 Oct 2018 18:32:21 +0100 + +glib2.0 (2.58.1-2) unstable; urgency=medium + + * Fix dh_missing rule for arch:all build with compat 11 + + -- Jeremy Bicha Fri, 21 Sep 2018 23:53:00 -0400 + +glib2.0 (2.58.1-1) unstable; urgency=medium + + * New upstream release + * Drop patches applied in new release: + - Fix-g_icon_to_string-regression-doc-inconsistency.patch + - tests-timer-Skip-test_timeval_to_iso8601_overflow-if-we-c.patch + * Refresh 61_glib-compile-binaries-path.patch + * Bump Standards-Version to 4.2.1 + * Bump debhelper compat to 11 + + -- Jeremy Bicha Fri, 21 Sep 2018 20:11:06 -0400 + +glib2.0 (2.58.0-4) unstable; urgency=medium + + [ Simon McVittie ] + * Adjust installation path of gdb scripts to match GLib itself. + We used to put libglib-2.0.so.0 in /lib/MULTIARCH, but this is no + longer the case since 2.56.0-5. + * Wrap and sort (build-)dependency lists (wrap-and-sort -a) + * Wrap and sort file lists (wrap-and-sort -a) + * Install HTML in /usr/share/gtk-doc/html with symlinks in /usr/share/doc. + The gtk-doc documentation is technically a functionally significant + part of the package (it affects cross-reference generation during build + of other packages) so according to Policy §12.3 it is not appropriate + for /usr/share/doc. + Using the upstream default installation path for the HTML also makes + it more straightforward to switch to the Meson build system, because + the Meson build does not have an equivalent of --with-html-dir. + - d/debian/libglib2.0-doc.maintscript: Add migration steps + * d/p/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch: + Also patch meson build system + + [ Jeremy Bicha ] + * Cherry-pick Fix-g_icon_to_string-regression-doc-inconsistency.patch + - Have g_icon_new_for_string() go back to only returning a single name + when created with a single name since some apps assume that behavior. + (Closes: #908705) + + -- Jeremy Bicha Mon, 17 Sep 2018 17:47:57 -0400 + +glib2.0 (2.58.0-3) unstable; urgency=medium + + [ Iain Lane ] + * Run fewer iterations of clousures test on armhf too + + -- Jeremy Bicha Fri, 07 Sep 2018 13:51:53 -0400 + +glib2.0 (2.58.0-2) unstable; urgency=medium + + * Cherry-pick upstream patch to fix test_timeval_to_iso8601_overflow on + 32-bit, fixing FTBFS there. + + -- Iain Lane Tue, 04 Sep 2018 15:29:53 +0100 + +glib2.0 (2.58.0-1) unstable; urgency=medium + + [ Jeremy Bicha ] + * New upstream release + * Drop patches applied in new release: + - date-test-Use-g_test_skip-not-g_test_incomplete.patch + - g_binding_unbind-make-it-more-introspection-friendly-allo.patch: + * Release to unstable + + [ Simon McVittie ] + * d/p/debian/closures-test-Run-fewer-iterations-on-ARM64.patch: + Update metadata + * libglib2.0-dev-bin: Add Suggests for the packages containing + xmllint and gdk-pixbuf-pixdata, which are sometimes invoked by + glib-compile-resources (Closes: #834998) + * Invoke dh_python3 twice so that we correctly rewrite the shebang + line for /usr/bin scripts (Closes: #876009) + * Don't install very old changelogs and NEWS files + * Install README.md instead of stub README + + -- Jeremy Bicha Sun, 02 Sep 2018 08:57:46 -0400 + +glib2.0 (2.57.2-2) experimental; urgency=medium + + * Cherry-pick g_binding_unbind-make-it-more-introspection-friendly-allo.patch + to fix pygobject build (LP: #1787474) + + -- Jeremy Bicha Mon, 20 Aug 2018 12:54:49 -0400 + +glib2.0 (2.57.2-1) experimental; urgency=medium + + * Team upload + * New upstream development release + * d/watch: Look for odd-numbered releases + * Rebase patch series + * Install gio-launch-desktop in libglib2.0-0's private libdir to avoid + a circular dependency between libglib2.0-0 and libglib2.0-bin + - d/p/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch: + Look for it there + * d/copyright: Update + * d/libglib2.0-0.symbols: Update + * Use upstream autogen.sh for autoreconf + * Don't clean org.gtk.test.gschema.override.orig + * d/gbp.conf: Use upstream/latest branch + * d/p/Drop-a-questionable-test-from-the-refstring-suite.patch: + Add patch to fix FTBFS on i386 + * d/p/date-test-Use-g_test_skip-not-g_test_incomplete.patch: + Add patch to fix autopkgtest failures without locales-all + * d/gbp.conf: Don't number patches + + -- Simon McVittie Thu, 02 Aug 2018 17:44:16 +0100 + +glib2.0 (2.56.1-2) unstable; urgency=medium + + [ Tim Lunn ] + * libglib2.0-0.triggers:use interest-await trigger for schemas + + [ Iain Lane ] + * debian/patches/tests-network-monitor-Always-use-the-dummy-proxy-res.patch: + Take patch from upstream to ignore the system's proxy settings for the + network-monitor test - it's testing an "abstract" network unrelated to the + system's network, and these settings interfere with that. This fixes a + failure in the Ubuntu autopkgtest machines, which have a proxy set. + + -- Iain Lane Tue, 10 Apr 2018 18:12:27 +0100 + +glib2.0 (2.56.1-1) unstable; urgency=medium + + [ Tim Lunn ] + * New upstream release + * Drop patches included in new release + * libglib2.0-0.triggers: Use interest-noawait triggers, generating caches + doesn't need to block configuration. flagged by lintian + uses-implicit-await-trigger warning. + + [ Simon McVittie ] + * Explicitly use autoconf build system, even with debhelper 11.2 + (see #895174) + + -- Tim Lunn Mon, 09 Apr 2018 19:03:24 +1000 + +glib2.0 (2.56.0-6) unstable; urgency=medium + + * Team upload + * d/p/0002-gapplication-Tighten-up-application-ID-validation.patch: + Transliterate commit message into ASCII so git-buildpackage doesn't + export it as a blob of base64 + * d/p/g_test_dbus_down-Ensure-next-test-does-not-use-old-c.patch: + Add patch to address a race condition that sometimes makes D-Bus-based + tests fail (Closes: #894677) + * d/patches: Improve metadata on various patches + + -- Simon McVittie Thu, 05 Apr 2018 09:24:45 +0100 + +glib2.0 (2.56.0-5) unstable; urgency=medium + + [ Simon McVittie ] + * Use `set -e` in the (empty) prerm to avoid a Lintian warning + * Add Lintian override for the empty prerm used to work around + #887629 + + [ Michael Biebl ] + * Stop installing libglib to /lib. + Late mounting of /usr is no longer supported, so this is not necessary + anymore. + * Drop maintscript migration code from pre-jessie. + * Drop obsolete Breaks. + + -- Michael Biebl Sun, 01 Apr 2018 17:59:50 +0200 + +glib2.0 (2.56.0-4) unstable; urgency=medium + + * Fix typo: libglib2.0-dev-bin Depends on python3-distutils, not + distuils (Closes: #893773) + * Restore `set -x` in debian/tests/build + + -- Simon McVittie Thu, 22 Mar 2018 09:08:05 +0000 + +glib2.0 (2.56.0-3) unstable; urgency=medium + + [ Iain Lane ] + * debian/tests/build: Add Restrictions: allow-stderr. We run this test with + `set -x', which outputs to stderr, and would like to continue doing so. + + [ Jeremy Bicha ] + * Depend and Build-Depend on python3-distutils to fix build failures + since python3 no longer depends on python3-distutils (Closes: #893736) + + -- Jeremy Bicha Thu, 22 Mar 2018 00:27:02 -0400 + +glib2.0 (2.56.0-2) unstable; urgency=medium + + [ Simon McVittie ] + * Merge from experimental to unstable + * d/tests/build: Don't rely on having unmerged /usr + * d/watch: Only watch for stable releases + * d/gbp.conf: Use debian/master, upstream/2.56.x branches + * d/control: Update Vcs-* for default branch + + -- Jeremy Bicha Sat, 17 Mar 2018 08:49:26 -0400 + +glib2.0 (2.56.0-1) experimental; urgency=medium + + * Team upload + * New upstream stable release 2.56.0 + * d/p/000?-gdbus-tool-*.patch: + Drop patches that came from upstream + * Refresh remaining patches + * d/p/0001-tests-Use-modern-test-assertions-in-GApplication-tes.patch, + d/p/0002-gapplication-Tighten-up-application-ID-validation.patch: + Cherry-pick GApplication ID fixes from upstream 2.56 branch + (GNOME #793400) + + -- Simon McVittie Tue, 13 Mar 2018 18:53:02 +0000 + +glib2.0 (2.55.2-2) experimental; urgency=medium + + * Merge changes from unstable, in particular: + + d/libglib2.0-dev.prerm: Add an empty prerm to make sure that we have a + way to recover from #887629 in stretch (Closes: #887863) + * d/p/0001-gdbus-tool-Ignore-unknown-options-for-the-emit-subco.patch, + d/p/0002-gdbus-tool-Make-dest-optional-for-emit-again.patch, + d/p/0003-gdbus-tool-Don-t-repeatedly-complete-signal.patch, + d/p/0004-gdbus-tool-Factor-out-common-GOptionContext-construc.patch: + Cherry-pick from upstream. Fix `gdbus emit' to not require `--dest', and + improve its bash completion. Should fix the dbus-test-runner autopkgtest, + which relied on this behaviour. + + -- Iain Lane Thu, 22 Feb 2018 10:02:17 +0000 + +glib2.0 (2.55.2-1) experimental; urgency=medium + + * debian/control{,.in}: Update Vcs-* to specify debian/experimental branch. + * New upstream release 2.55.2: + + GFile now has API to get the path without copying + * debian/patches/gdbus-threading-test-Allow-even-longer-for-test_method_ca.patch, + debian/patches/gdatetime-Avoid-repeated-floating-point-multiplies-w.patch, + debian/patches/gdatetime-Mark-the-usecs-as-volatile.patch: + Drop, applied upstream in this release. + * debian/libglib2.0-0.symbols: New symbols for 2.55.2 + + -- Iain Lane Thu, 15 Feb 2018 10:23:05 +0000 + +glib2.0 (2.55.1-1) experimental; urgency=medium + + * debian/gbp.conf, debian/watch: Update for experimental + * New upstream development release 2.55.1 + * debian/libglib2.0-0.symbols: Update with new symbols in this release. + * debian/patches/gdatetime-Avoid-repeated-floating-point-multiplies-w.patch, + debian/patches/gdatetime-Mark-the-usecs-as-volatile.patch: Cherry-pick two + patches from upstream. Fix some precision problems within GDateTime, that + in some cases resulted in incorrect answers on i386. + + -- Iain Lane Mon, 15 Jan 2018 12:26:35 +0000 + +glib2.0 (2.54.3-2) unstable; urgency=medium + + * Team upload + * d/libglib2.0-dev.prerm: Add an empty prerm to make sure that we have + a way to recover from #887629 in stretch (Closes: #887863) + * d/p/gdbus-threading-test-Allow-even-longer-for-test_method_ca.patch: + Mark as applied upstream + * d/p/gmain-Partial-revert-of-recent-wakeup-changes-to-gmain.c.patch: + Apply patch from upstream glib-2-54 branch to revert GWakeup changes + that appear to have broken WebKit and/or LibreOffice + (Closes: #887492) + + -- Simon McVittie Mon, 22 Jan 2018 12:39:58 +0000 + +glib2.0 (2.54.3-1) unstable; urgency=medium + + [ Simon McVittie ] + * Move Vcs-* to salsa.debian.org + * New upstream stable release + - Fix a race condition when a GCancellable is cancelled in another + thread (Closes: #884654) + - Drop patches for #884661, fixed upstream + * d/p/gdbus-peer-Skip-test-during-Debian-package-build.patch: + Drop. We should no longer need to skip this test now that #884654 + is fixed. + * d/p/Do-not-attempt-to-autolaunch-a-session-dbus-daemon-w.patch: + Drop patch. It has not been necessary since 2.50. + * d/p/0001-Fix-trashing-on-overlayfs.patch, + d/p/0001-timer-test-use-volatile-for-locals.patch, + d/p/gdbus-threading-test-Allow-even-longer-for-test_method_ca.patch: + Mark as forwarded upstream + * d/patches: Move non-upstreamable patches (Debian-specific changes + and workarounds) to d/p/debian, and to the bottom of d/p/series + * d/watch: Only watch for the upstream stable branch + + [ Iain Lane ] + * debian/gbp.conf: Update upstream branch to upstream/2.54.x following + DEP-14. + + -- Iain Lane Tue, 09 Jan 2018 18:02:53 +0000 + +glib2.0 (2.54.2-5) unstable; urgency=medium + + * Set Rules-Requires-Root to no. This package builds successfully + with the same content in that mode. + * d/p/61_glib-compile-binaries-path.patch: Only use the multiarch + path for glib-compile-schemas, not for glib-compile-resources + * Install glib-compile-resources into PATH in libglib2.0-dev-bin, + not libglib2.0-bin: it is a development tool used at compile-time + - libglib2.0-dev-bin Breaks/Replaces older libglib2.0-bin + * Install the glib-compile-resources binary in libglib2.0-dev-bin, + not libglib2.0-0. This means we get an executable version of that + binary when cross-compiling (Closes: #885019) + * Bump Standards-Version to 4.1.3 + + -- Simon McVittie Fri, 29 Dec 2017 22:07:56 +0000 + +glib2.0 (2.54.2-4) unstable; urgency=medium + + * Team upload + * d/p/closures-test-Run-fewer-iterations-on-ARM64.patch: + Run more iterations on ARM64 than in 2.54.2-3, but fewer than in + 2.54.2-2. If we don't run enough iterations, we get an assertion + failure when the main thread starves the other threads. + * d/p/gmenumodel*.patch: Mark as upstreamed in 2.54.3 and 2.55.1 + * d/rules: Set DEB_BUILD_TIME_TESTS when running dh_auto_test, so that + tests can distinguish between autopkgtest and `make check` + * d/p/gdbus-peer-Skip-test-during-Debian-package-build.patch: + Skip the gdbus-peer test during package build, so that its known + race condition does not cause intermittent FTBFS (mitigates: #884654) + + -- Simon McVittie Thu, 21 Dec 2017 14:41:40 +0000 + +glib2.0 (2.54.2-3) unstable; urgency=medium + + * Team upload + * d/patches: Re-export with gbp pq + * d/patches: Use `gbp pq export`-style metadata, retrieving authors + and dates from d/changelog where needed + * d/p/closures-test-Run-fewer-iterations-on-ARM64.patch: New patch. + tests/refcount/closures: Run fewer iterations on ARM64 + (mitigates: #880883) + * d/p/gdbus-threading-test-Allow-even-longer-for-test_method_ca.patch: + New patch. Allow even longer for the gdbus-threading test, and + re-enable it on 32-bit ARM now that the timeout is longer + (Closes: #884660) + * d/p/gmenumodel-test-If-something-goes-wrong-don-t-wait-foreve.patch, + d/p/gmenumodel-test-Wait-for-the-expected-events-to-happen.patch: + Add patches to make the GMenuModel test more patient (Closes: #884661) + * d/p/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch: + Reduce number of threads and number of operations in response to + timeout on reproducible-builds infrastructure (mitigates: #884659) + + -- Simon McVittie Mon, 18 Dec 2017 21:30:18 +0000 + +glib2.0 (2.54.2-2) unstable; urgency=medium + + * Update Vcs fields for conversion to git + * Add debian/gbp.conf + * Bump Standards-Version to 4.1.2 + + -- Jeremy Bicha Wed, 13 Dec 2017 21:15:13 -0500 + +glib2.0 (2.54.2-1) unstable; urgency=medium + + [ Jeremy Bicha ] + * New upstream release + + [ Didier Roche ] + * debian/patches/01_gettext-desktopfiles.patch: + - fix untranslated desktop action names when using gettext + (Closes: #877761) + + [ Simon McVittie ] + * Skip gtk-doc documentation unless we are building libglib2.0-doc, + fixing cross-builds (Closes: #870346) + - Note that gtk-doc-tools is still in Build-Depends, not + Build-Depends-Indep, because we need it for autoreconf + * Explicitly disable documentation for the udeb build + * Skip build-time tests for Arch:all builds - testing once per + architecture is sufficient + * Remove unused lintian override for an example file that is no + longer installed + + -- Jeremy Bicha Fri, 27 Oct 2017 21:16:41 -0400 + +glib2.0 (2.54.1-1) unstable; urgency=medium + + [ Jeremy Bicha ] + * New upstream release + * Bump Standards-Version to 4.1.1 + + [ Michael Biebl ] + * Drop uploaders.mk include as it breaks the clean target. + Updating the Uploaders list is already handled by the gnome dh addon. + + -- Jeremy Bicha Mon, 02 Oct 2017 12:13:25 -0400 + +glib2.0 (2.54.0-1) unstable; urgency=medium + + * New upstream stable release. + + -- Emilio Pozuelo Monfort Mon, 11 Sep 2017 19:11:00 +0200 + +glib2.0 (2.53.7-1) unstable; urgency=medium + + * New upstream release. + * debian/patches/81-skip-monitor-test-on-non-linux.patch: + + Refreshed. + * debian/control.in: drop automake and autotools-dev build dependencies, + dh-autoreconf does that for us. + * Bump Standards-Version to 4.1.0; no changes needed. + + -- Emilio Pozuelo Monfort Sat, 09 Sep 2017 15:11:02 +0200 + +glib2.0 (2.53.6-1) unstable; urgency=medium + + * New upstream release. + * git_glib-mkenums-utf8.patch, git_glib-mkenums-flags.patch: Drop, now + applied upstream. + * debian/rules: Don't pass -X.la to dh_auto_install - it can easily lead to + unwanted removals (not claiming this is happening here) + * debian/rules: Fix arguments to dh_auto_test so tests are run again + * debian/rules, debian/control{,.in}: Use dh_missing and not dh_install + --list-missing. Also upgrade this check to --fail-missing. + * debian/rules: Don't run the tests under fakeroot; it makes them fail with + dbus-related authentication problems. + + -- Iain Lane Mon, 21 Aug 2017 17:01:22 +0100 + +glib2.0 (2.53.4-3) unstable; urgency=medium + + [ Matthias Klumpp ] + * Update Vcs-* URLs + + [ Jeremy Bicha ] + * Bump Breaks/Replaces: libglib2.0-dev to 2.53 (Closes: #867679) + * Add git_glib-mkenums-utf8.patch: + - Backport commit to fix "glib-mkenums: UnicodeDecodeError" + (Closes: #870310) + * Add git_glib-mkenums-flags.patch: + - Backport commit to fix mate-panel FTBFS (Closes: #870212) + + -- Jeremy Bicha Thu, 03 Aug 2017 12:21:04 -0400 + +glib2.0 (2.53.4-2) unstable; urgency=medium + + * Upload to unstable + + -- Matthias Klumpp Sun, 30 Jul 2017 12:54:22 +0200 + +glib2.0 (2.53.4-1) experimental; urgency=medium + + * New upstream release 2.53.4 + + Unicode support has been updated to Unicode 10.0.0 + + glib-genmarshal and glib-mkenums have been rewritten in python + + GLib can now be built with meson. autotools are still supported + + -- Iain Lane Wed, 19 Jul 2017 17:32:31 +0100 + +glib2.0 (2.53.3-1) experimental; urgency=medium + + * New upstream release 2.53.3. + * d/p/0001-gdatetime-Fix-a-potential-overflow-in-overflow-calcu.patch, + d/p/0002-tests-Fix-GDateTime-overflow-tests-on-32-bit-archite.patch, + d/p/0003-tests-Fix-overflows-in-find_maximum_supported_tv_sec.patch: + Cherry-picks to fix some overflow problems in GDateTime on 32 bit arches. + + -- Iain Lane Fri, 23 Jun 2017 11:09:22 +0100 + +glib2.0 (2.53.2-1) experimental; urgency=medium + + * New upstream release 2.53.2 + + A few new number parsing functions have been added: + - g_ascii_string_to_signed + - g_ascii_string_to_unsigned + These have better error handling than the existing ones. + + glib-mkenums now supports /*< private >*/ and /*< public >*/ + + GSettings now consider XDG_DATA_HOME in addition to XDG_DATA_DIRS. + * debian/libglib2.0-0.symbols: Add new symbols for 2.53.1. + * debian/patches/skip-broken-dbus-appinfo-test.patch: Drop - this test works + now. + + -- Iain Lane Mon, 12 Jun 2017 16:25:21 +0100 + +glib2.0 (2.53.1-1) experimental; urgency=medium + + * New upstream release 2.53.1 + + The gdbus tool gained a wait command + + g_unix_signal_source_new support SIGWINCH now + + There are now g_enum_to_string and g_flags_to_string functions + + A new function to instantiate objects: g_objet_new_with_properties + + GParameter and related APIs have been deprecated + * debian/libglib2.0-0.symbols: Add new symbols for 2.53.1. + + -- Iain Lane Fri, 05 May 2017 18:04:15 +0100 + +glib2.0 (2.52.0-1) experimental; urgency=medium + + * New upstream release 2.52.0 + * d/p/tests-gdatetime-Use-a-real-rather-than-invented-time.patch: Drop, + applied in this release. + + -- Iain Lane Mon, 20 Mar 2017 17:14:29 +0000 + +glib2.0 (2.51.5-1) experimental; urgency=medium + + * New upstream release 2.51.5 + * Drop patches applied upstream in this release: + - Install-gdb-Python-helpers-as-data-not-as-executable.patch + - glib-mkenums-Sort-input-files-for-more-deterministic.patch + * debian/patches/tests-gdatetime-Use-a-real-rather-than-invented-time.patch: + Cherry-pick a patch from upstream to fix GDateTime tests when tzdata ≥ + 2017a is in use. + * debian/libglib2.0-dev.install: Install the gdb script for libglib-2.0.so.* + into .../lib instead of .../usr/lib - it needs to match the installed path + of the library and we put libglib-2.0.so.* into /lib. + * debian/libglib2.0-0.symbols: Add g_content_type_is_mime_type + + -- Iain Lane Wed, 15 Mar 2017 13:55:41 +0000 + +glib2.0 (2.51.4-1) experimental; urgency=medium + + * Team upload + * New upstream release 2.51.4 (and 2.51.3) + * Build with dh instead of cdbs + - Move to debhelper compat level 10 + - Use dpkg-buildflags variables to extend LDFLAGS + - Enable bindnow hardening + - Remove indirection via $(SHARED_PKG), etc. variables + - Let dh_gnome_clean update the Uploaders instead of reinventing it + - Install some missing files detected by dh_install --list-missing + - Fix lintian warnings about useless use of dh-exec + - debian/dh_listmissing.pl: Remove + * Improve packaging for cross-compiling (Closes: #648621, #842442) + - Move glib-genmarshal and related files to a new M-A:foreign package + libglib2.0-dev-bin. Thanks to Helmut Grohne for the patch. + - Additionally move gdbus-codegen and gtester-report to + libglib2.0-dev-bin. They are architecture-independent, so in + particular clearly Multi-Arch: foreign; they aren't large enough to + justify a separate Architecture: all package. This works around + dh_python3's postinst snippet failing when used in a Multi-Arch: same + package with more than one instance installed. + - Move gtester to libglib2.0-dev-bin. It is a test-runner that can + operate on any executable, and does not rely on a matching architecture. + - Move gobject-query to libglib2.0-dev-bin. It prints the same things on + all architectures, and it isn't clear what use it is; glib-2.0.m4 + checks for it and AC_SUBSTs it, but according to codesearch.debian.net + no package actually seems to run it. + - Make libglib2.0-dev Multi-Arch: same + * Move gdb helpers from libglib2.0-0-dbg to libglib2.0-dev, move + detached debug symbols from libglib2.0-0-dbg to autogenerated -dbgsym + packages, and remove the libglib2.0-0-dbg binary package + * Add support for noudeb build profile + - Do not do the udeb build if the noudeb profile is selected, + for faster test-builds + * Fix assorted Lintian warnings + - Add missing build-dependency on dh-python + + remove obsolete Lintian override for mmissing B-D on python + - Add Lintian overrides for some intentionally weird scripts used in tests + - Do not install glib_gdb.py, gobject_gdb.py executable. They are + libraries to be imported by the gdb hooks, not scripts. + - Don't generate a ldconfig trigger for libglib2.0-tests, which does + not contain any public shared libraries + * Add patch to make glib-mkenums output more reproducible (Closes: #809152) + * Explicitly build-depend on automake so that the aspcud resolver used for + experimental does not decide automake1.11 is the best solution to + a dependency on automake | automaken + + -- Simon McVittie Sat, 04 Mar 2017 17:00:47 +0000 + +glib2.0 (2.51.2-1) experimental; urgency=medium + + * New upstream release 2.51.2 (& 2.51.1). + + Minimal support for UUIDs has been added + + A new file attribute, G_FILE_ATTRIBUTE_RECENT_MODIFIED has been added to + improve sorting of recent files + + glib-compile-resources grew a --generate-phony-targets flag + + GLib now installs a valgrind suppressions file for GLib and GIO + * debian/patches/skip-brokwn-dbus-appinfo-test.patch: Refresh (and fix the + typo in the filename) + * debian/libglib2.0-0.symbols: Add g_uuid* symbols which are new in this + release + + -- Iain Lane Tue, 14 Feb 2017 14:16:05 +0000 + +glib2.0 (2.51.0-2) experimental; urgency=medium + + * Merge changes from 2.50.2-2: + + debian/rules: disable libmount on !linux (Closes: #844052) + + debian/patches/0001-Fix-trashing-on-overlayfs.patch: Update with new + version from the upstream report to hopefully fix trashing of files in + directories which are symlinks to different devices. (Closes: #800047) + (LP: #1638245) + + -- Iain Lane Wed, 23 Nov 2016 17:36:07 +0000 + +glib2.0 (2.51.0-1) experimental; urgency=medium + + * debian/control{,.in}: Branch to experimental + * debian/watch: Track unstable releases again. + * New upstream release 2.51.0 + + glib-genmarshal and glib-mkenums have gained --output options for better + build system integration + + New API: g_utf8_make_valid + * Update debian/libglib2.0-0.symbols. + + -- Iain Lane Wed, 16 Nov 2016 18:23:38 +0000 + +glib2.0 (2.52.3-1) unstable; urgency=medium + + * New upstream release. + * skip-brokwn-dbus-appinfo-test.patch, + tests-gdatetime-Use-a-real-rather-than-invented-time.patch: + + Dropped, applied upstream. + * debian/libglib2.0-0.symbols: + + Add new symbols. + + -- Emilio Pozuelo Monfort Fri, 23 Jun 2017 21:06:46 +0200 + +glib2.0 (2.50.3-2) unstable; urgency=medium + + * debian/patches/tests-gdatetime-Use-a-real-rather-than-invented-time.patch: + Cherry-pick a patch from upstream to fix GDateTime tests when tzdata ≥ + 2017a is in use. (Closes: #858214) + + -- Michael Biebl Mon, 20 Mar 2017 00:21:57 +0100 + +glib2.0 (2.50.3-1) unstable; urgency=medium + + * New upstream release. + + -- Michael Biebl Wed, 15 Feb 2017 19:00:01 +0100 + +glib2.0 (2.50.2-2) unstable; urgency=medium + + * debian/rules: disable libmount on !linux (Closes: #844052) + * debian/patches/0001-Fix-trashing-on-overlayfs.patch: Update with new + version from the upstream report to hopefully fix trashing of files in + directories which are symlinks to different devices. (Closes: #800047) + + -- Iain Lane Wed, 23 Nov 2016 16:33:21 +0000 + +glib2.0 (2.50.2-1) unstable; urgency=medium + + * New upstream release. + * Track stable releases in debian/watch. + + -- Michael Biebl Tue, 08 Nov 2016 00:37:05 +0100 + +glib2.0 (2.50.1-1) unstable; urgency=medium + + [ Jason Crain ] + * libglib2.0-bin: includes a new 'gio' commandline tool (Closes: #840164) + + [ Andreas Henriksson ] + * New upstream release. + + -- Andreas Henriksson Tue, 11 Oct 2016 14:51:05 +0200 + +glib2.0 (2.50.0-2) unstable; urgency=medium + + [ Simon McVittie ] + * Build-depend on tzdata, which is no longer transitively Essential. + One test needs it. (Closes: #839487) + + [ Michael Biebl ] + * Fix Vcs-* to point to unstable. + * Mark dependencies which are required to run the test-suite with + . + * Add explicit Build-Depends on xsltproc, docbook-xml and docbook-xsl. + Besides libxml2-utils, those are needed for building the man pages. + * Drop Build-Depends on dbus-x11. The test-suite uses a mock version of + dbus-launch nowadays, so this dependency is no longer needed. + (Closes: #835884) + * Use dh-exec to substitute ${DEB_HOST_MULTIARCH} in .install, .links and + .dirs files. + + -- Michael Biebl Sat, 01 Oct 2016 22:15:22 +0200 + +glib2.0 (2.50.0-1) unstable; urgency=medium + + * New upstream release. + * Refresh patches. + + -- Michael Biebl Tue, 20 Sep 2016 18:37:10 +0200 + +glib2.0 (2.49.7-1) unstable; urgency=medium + + * New upstream release. + * Update debian/libglib2.0-0.symbols with one addition. + + -- Andreas Henriksson Tue, 13 Sep 2016 14:40:14 +0200 + +glib2.0 (2.49.6-1) unstable; urgency=low + + * New upstream release. + * Limit the libmount-dev build-depedency to [linux-any]. + + -- Andreas Henriksson Tue, 30 Aug 2016 17:57:52 +0200 + +glib2.0 (2.49.5-2) experimental; urgency=medium + + * debian/rules: Disable libmount for the udeb build; there's no + libmount-udeb, no immediate plans to provide one, and the functionality in + glib isn't that interesting in the d-i context at the present time. + + -- Iain Lane Mon, 22 Aug 2016 11:12:26 +0100 + +glib2.0 (2.49.5-1) experimental; urgency=medium + + [ Simon McVittie ] + * Merge packaging from unstable. + + [ Iain Lane ] + * New upstream release 2.49.5 + * debian/patches/gregex-loosen-behaviour-testing.patch: Drop this patch - + it's in 2.49.5. + * debian/libglib2.0-0.symbols: Add symbols for async + g_app_info_launch_default_for_uri. + * debian/control{,.in}, debian/rules: Enable libmount support + + -- Iain Lane Thu, 18 Aug 2016 12:10:08 +0100 + +glib2.0 (2.48.1-3) unstable; urgency=medium + + * debian/tests/control: do not fail on stderr output from + installed-tests. If gvfs happens to be installed, it gets + D-Bus-activated (even if it's disabled via GIO_USE_VFS and + GIO_USE_VOLUME_MONITOR), resulting in logging from dbus-daemon. + (Closes: #821031) + * debian/tests/installed-tests: explicitly select built-in VFS and + volume monitor + * d/p/gregex-loosen-behaviour-testing.patch: add patch from upstream + bug 767240 (not applied yet) to relax assertions about PCRE's behaviour, + which changed in 8.38 (Closes: #834272) + * d/rules: unset XDG_CONFIG_HOME, XDG_CACHE_HOME, XDG_DATA_HOME, + XDG_CONFIG_DIRS, XDG_DATA_DIRS so that they are based on the temporary + HOME. This avoids FTBFS if the user doing the build has these variables + already set in their build environment (Closes: #834334) + + -- Simon McVittie Mon, 15 Aug 2016 18:01:03 +0100 + +glib2.0 (2.48.1-2) unstable; urgency=medium + + * Remove refdbg variant. Thanks to Jonny Lamb for the patch. + Closes: #827269. + * Switch to python3. + + -- Emilio Pozuelo Monfort Wed, 13 Jul 2016 17:46:31 +0200 + +glib2.0 (2.49.4-1) experimental; urgency=medium + + * New upstream release. + * debian/patches/add-missing-gio-xml.patch: + + Dropped, gio.xml is now shipped in the tarballs. + * debian/patches/0001-Fix-gio-tests-socket-listener.patch: + + Dropped, included upstream. + + -- Emilio Pozuelo Monfort Thu, 21 Jul 2016 18:12:05 +0200 + +glib2.0 (2.49.3-1) experimental; urgency=medium + + * Switch to python3. + * New upstream release. + * d/p/0001-gsettings-test-Wrap-guint64-literals-in-G_GUINT64_CO.patch: + + Dropped, applied upstream. + * debian/patches/add-missing-gio-xml.patch: + + Add gio.xml file, which is missing from the tarball. Needed for the + documentation build. + * debian/patches/0001-Fix-gio-tests-socket-listener.patch: + + Fix a test hang. + * debian/libglib2.0-0.symbols: + + Update with new symbols. + * Standards-Version is 3.9.8. No changes needed. + + -- Emilio Pozuelo Monfort Wed, 20 Jul 2016 23:23:12 +0200 + +glib2.0 (2.49.2-2) experimental; urgency=medium + + * d/p/0001-gsettings-test-Wrap-guint64-literals-in-G_GUINT64_CO.patch: + Cherry-pick from upstream to fix test failure on non-64 bit arches. + + -- Iain Lane Thu, 23 Jun 2016 16:56:04 +0100 + +glib2.0 (2.49.2-1) experimental; urgency=medium + + [ Emilio Pozuelo Monfort ] + * Remove refdbg variant. Thanks to Jonny Lamb for the patch. + Closes: #827269. + + [ Iain Lane ] + * Update Vcs-* for experimental + * New upstream release 2.49.2 + + GDesktopAppInfo now allows bus activation with dashes. This is not + technically allowed per the Desktop Entry specification, but it happens + in the wild. Rather than forcing people to go through another traumatic + desktop file rename, accept it and translate - to _. + + The support for giving names to threads has been improved. Thread names + are now supported on Solaris as well, and the Linux support no longer + uses prctl() but the pthread api. + + GIO resources can now be overridden at runtime, using the + G_RESOURCE_OVERLAYS environment variable. + + gdbus-codegen can now generate autocleanup definitions for the types it + generates. Use the --c-generate-autocleanup option to control this + + GMainContext and GTask have gained more systemtap probes + * debian/watch: Update to find unstable versions + * debian/patches/04_homedir_env.patch: Refresh to apply correctly + * debian/libglib2.0-0.symbols: Update for this release + + -- Iain Lane Tue, 21 Jun 2016 14:20:19 +0100 + +glib2.0 (2.48.1-1) unstable; urgency=medium + + * New upstream release. + * Refresh patches. + * Drop obsolete Conflicts, Breaks and Replaces from pre-wheezy. + * Drop obsolete preinst maintainer scripts which cleaned up the + /usr/share/doc symlinks. + * Drop version requirement for pkg-config dependency. (Closes: #734479) + + -- Michael Biebl Wed, 11 May 2016 01:11:42 +0200 + +glib2.0 (2.48.0-1) unstable; urgency=medium + + * New upstream stable release 2.48.0 + + a minor build fix in the name of determinism (Closes: #812876) + + a few coverity fixes + + -- Iain Lane Wed, 23 Mar 2016 17:59:23 +0000 + +glib2.0 (2.47.92-1) experimental; urgency=medium + + * New upstream release. + + -- Andreas Henriksson Wed, 16 Mar 2016 11:18:53 +0100 + +glib2.0 (2.47.6-1) experimental; urgency=medium + + * New upstream release. + - GString is missing (transfer none) annotations on many of its methods + - systemtap and gdb scripts install in wrong place + - Documentation: various small improvements + - gdbusobjectmanagerserver: Clarify recommended ObjectManager paths + - Fix some annotations + - Cannot build with default flags under Fedora rawhide + (-Werror=format-nonliteral) + - gmacros.h is testing attributes with __has_feature (when compiling with + clang) + * debian/libglib2.0-0-dbg.install.in: Upstream now installs the gdb + auto-loaded scripts in the right place by themselves - no need for us to + move them about. + + -- Iain Lane Thu, 18 Feb 2016 14:07:22 +0000 + +glib2.0 (2.47.5-1) experimental; urgency=medium + + * debian/watch: Use download.gnome.org, seems ftp.gnome.org is not updating + properly currently. + * New upstream release 2.47.5 + + the system copy of PCRE is now used by default to implement GRegex. + Configure with --with-pcre=internal if a system PCRE version + is unavailable or undesired. + + interfaces for DTLS support have been added. A new version of + glib-networking will also be required. + + GDBusMethodInvocation now drops replies if the sender set the + NO_REPLY_EXPECTED flag + + several GApplication fixes, including fixes for commandline arguments in + interpreted languages on Windows + * debian/libglib2.0-0.symbols: Update with new symbols for this release. + * 0001-regex-test-expect-ASSERTION_EXPECTED-for-ab-with-PCR.patch: Drop, + it's included in this release. + + -- Iain Lane Wed, 20 Jan 2016 17:55:16 +0000 + +glib2.0 (2.47.4-1) experimental; urgency=medium + + * New upstream release + + The GApplication documentation has been improved in several areas. + * 0001-tests-fix-a-test-on-32-bit-builds.patch, + 0001-gtypes.h-move-G_STATIC_ASSERT-to-function-scope.patch: Drop, applied + upstream in this release. + * 0001-regex-test-expect-ASSERTION_EXPECTED-for-ab-with-PCR.patch: Fix regex + tests to assert the right errors as of pcre 8.38. Cherry-pick from + upstream. (Closes: #808842) + * Don't build automatic dbgsym package for -refdbg + + -- Iain Lane Thu, 14 Jan 2016 18:27:02 +0000 + +glib2.0 (2.47.3-3) experimental; urgency=medium + + * debian/patches/0001-gtypes.h-move-G_STATIC_ASSERT-to-function-scope.patch: + Another cherry-pick. Should fix g-ir-scanner. + + -- Iain Lane Sun, 29 Nov 2015 18:45:29 +0000 + +glib2.0 (2.47.3-2) experimental; urgency=medium + + * debian/patches/0001-tests-fix-a-test-on-32-bit-builds.patch: Cherry-pick + from upstream. Fix tests (and therefore the build) on 32 bit arches. + + -- Iain Lane Thu, 26 Nov 2015 16:12:12 +0000 + +glib2.0 (2.47.3-1) experimental; urgency=medium + + * New upstream release + + New API: hardware-assisted helpers for overflow-checked integer math. + + Fixes: Invalid free in g_local_file_trash() (LP: #1512826) + * d/p/{Doc-copy-included-example-files.patch, + Doc-Fix-missing-glibconfig.h-when-builddir-srcdir.patch, + Build-gdbus-example-objectmanager-server-again.patch}: Remove - in this + upstream release. + + -- Iain Lane Wed, 25 Nov 2015 17:59:33 +0000 + +glib2.0 (2.47.1-1) experimental; urgency=medium + + * New upstream release. + + The Unicode support has been updated to version 8.0 of the Unicode standard + + GDesktopAppInfo no longer sets the DISPLAY environment variable when + launching apps. This is now done in the GAppLaunchContext + implementations when appropriate. + * debian/watch: Look for development versions too. + * debian/patches/90_gio-modules-multiarch-compat.patch: Refresh to apply on + this version. + * debian/patches/0001-GDateTime-test-fix-occasional-failures.patch: Drop, + upstream in this release. + * debian/libglib2.0-0.symbols: Update with new symbols for this release. + + -- Iain Lane Wed, 04 Nov 2015 17:28:23 +0000 + +glib2.0 (2.46.2-3) unstable; urgency=medium + + * Add debian/patches/disable-failing-test-for-pcre838.patch + - disable regexp test that fails with new system pcre 8.38 + which just hit Debian unstable. Needs further investigation + but lets not leave the build broken during the holidays. + + -- Andreas Henriksson Wed, 23 Dec 2015 17:11:16 +0100 + +glib2.0 (2.46.2-2) unstable; urgency=medium + + [ Iain Lane ] + * Fix typo in previous changelog entry. + + [ Andreas Henriksson ] + * Add debian/patches/bug712848-volume-monitor-deadlock-kfreebsd.patch + - patch by and big thanks to Steven Chamberlain for debugging this! + - given lack of feedback from upstream, which would be very welcome + for deep changes like this, use an ifdef to only change on + *FreeBSD for now... (Closes: #712848) + * Add --no-ddebs arg to dh_strip for refdbg package build which + otherwise fails and I doubt we need ddeb/dbgsym for our debug + package. + + -- Andreas Henriksson Wed, 23 Dec 2015 11:54:51 +0100 + +glib2.0 (2.46.2-1) unstable; urgency=medium + + * Fix Vcs-* to point to unstable. + * New upstream stable release 2.46.2. + + Fixes cross compilation (Closes: #800610) + * Drop changes from 2.46.1-2, which are all in this upstream release. + * Drop debian/patches/0001-GDateTime-test-fix-occasional-failures.patch, + applied upstream. + + -- Iain Lane Mon, 09 Nov 2015 12:59:12 +0000 + +glib2.0 (2.46.1-2) unstable; urgency=medium + + * Team upload. + * Cherry-pick patches from upstream glib-2-46 branch to fix incomplete + documentation (Closes: #659977) + * debian/gdbus-example-objectmanager-server.c: add missing example file + from upstream git; it was accidentally omitted from upstream tarballs + + -- Simon McVittie Mon, 02 Nov 2015 17:31:00 +0000 + +glib2.0 (2.46.1-1) unstable; urgency=medium + + [ Michael Biebl ] + * Drop clean-la.mk from debian/rules, no longer required. + + [ Iain Lane ] + * New upstream release 2.46.1 + + Remove system_header pragma (should fix lack of warnings with things + like g_return_if_fail) + + move GStrv typedef (and auto-cleanup) from libgobject to libglib + + fix order of trashing files to be closer to what is required in the + specification. Namely, trashinfo files are written first. This should + fix issues with the gvfs trash backend failing to correctly read the + info for recently trashed files (preventing 'restore'). (Closes: + #800491) (LP: #1495943) + + tweak mime logic to return text/plain on all empty files instead of + returning application/octet-stream. This includes files that have + extensions that imply that they may be other types of files, which is a + slight change of behaviour with respect to old GLib versions. (LP: + #1497170) + * debian/patches/0001-Revert-list-store-Fix-a-parameter-check.patch: Drop - + this is applied upstream in this release. + * debian/patches/0001-GDateTime-test-fix-occasional-failures.patch: Take + patch from bgo#754994 to resolve intermittent test failures in the + GDateTime tests. + + -- Iain Lane Thu, 15 Oct 2015 16:08:30 +0100 + +glib2.0 (2.46.0-2) unstable; urgency=medium + + * debian/patches/0001-Revert-list-store-Fix-a-parameter-check.patch: + Cherry-pick from upstream to fix GSequence (this at least makes + GStreamer's testsuite fail). + + -- Iain Lane Mon, 28 Sep 2015 13:07:06 +0100 + +glib2.0 (2.46.0-1) unstable; urgency=medium + + [ Iain Lane ] + * New upstream stable release 2.46.0 + + Disable runtime-deprecation warnings + + Fix marshalling of flags on bigendian 64bit architectures + + [ Simon McVittie ] + * Change section of libglib2.0-refdbg from debug to devel, so that it + isn't kicked out into a separate mirror network when we get + automatic -dbgsym packages (Closes: #796836) + + -- Iain Lane Wed, 23 Sep 2015 11:33:01 +0100 + +glib2.0 (2.45.8-1) experimental; urgency=medium + + * New upstream development release. + * Update debian/libglib2.0-0.symbols with one addition: + g_param_spec_get_name_quark + + -- Andreas Henriksson Thu, 17 Sep 2015 10:05:17 +0200 + +glib2.0 (2.45.7-1) experimental; urgency=medium + + * New upstream release 2.45.7 + + Add G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE for use by non-POSIX-like + backends (e.g. cloud storage). + + GFileMonitor: Make the inotify backend work with atomic renames again + + GSettings: change notification is again working unconditionally + + GListStore has a sort function now + + Test infrastructure: + - Tests are now required to have unique names + - TAP support has been improved + - A macro for asserting that two memory regions have identical content + has been added + * debian/libglib2.0-0.symbols: Add new symbol for this release. + + -- Iain Lane Thu, 03 Sep 2015 14:09:02 +0100 + +glib2.0 (2.45.6-1) experimental; urgency=medium + + * New upstream releases 2.45.5 and 2.45.6 + + GNetworkMonitor now provides information about metered networks + + g_mem_set_vtable has been deprecated; it has not been working for quite + a while. The recommendation is to use valgrind, or replace malloc + itself. + * debian/patches/0001-GOptionContext-Don-t-crash-without-main-group.patch: + Drop, applied upstream. + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Wed, 26 Aug 2015 17:25:52 +0100 + +glib2.0 (2.45.4-2) experimental; urgency=medium + + * debian/patches/0001-GOptionContext-Don-t-crash-without-main-group.patch: + Cherry-pick. Don't crash in GOptionContext if there's no main group. Fixes + crash when running (for example) gdbus. + + -- Iain Lane Wed, 29 Jul 2015 16:30:21 +0100 + +glib2.0 (2.45.4-1) experimental; urgency=medium + + * New upstream release 2.45.4 + * d/p/0001-gio-tests-appmonitor-Delete-file-before-checking-for.patch, + d/p/0001-glocalfilemonitor-Send-DELETED-event-when-there-is-n.patch: Drop, + applied upstream. + * d/p/07_disable_tests_on_slow_archs.patch: Refresh to apply cleanly. + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Tue, 21 Jul 2015 18:07:32 +0100 + +glib2.0 (2.45.3-1) experimental; urgency=medium + + [ Simon McVittie ] + * d/p/regex-if-PCRE-is-8.34-or-later-disable-auto-possessi.patch: + mark as applied upstream in 2.45.3 + + [ Iain Lane ] + * New upstream release 2.45.3. + + Improve performance of g_signal_handler_disconnect for signals + with many handlers + + GDBus has gained a new call flag to allow interactive authorization + + GSettings: + - New API: g_settings_schema_list_keys + - Deprecated: g_settings_list_keys + * debian/libglib2.0-0.symbols: Update with new symbols from this release. + * debian/patches/regex-if-PCRE-is-8.34-or-later-disable-auto-possessi.patch: + Delete, applied upstream. + * d/p/0001-gio-tests-appmonitor-Delete-file-before-checking-for.patch: + Cherry-pick upstream patch to fix testsuite failure causing FTBFS. + + -- Iain Lane Wed, 01 Jul 2015 18:15:07 +0100 + +glib2.0 (2.45.2-1) experimental; urgency=medium + + [ Simon McVittie ] + * Correctly attribute previous upload to Iain + * d/p/0001-Fix-trashing-on-overlayfs.patch: add upstream bug reference + * d/p/0001-glocalfilemonitor-Send-DELETED-event-when-there-is-n.patch: + add upstream bug reference + * d/p/10_kfreebsd_issetugid_prototype.patch, + d/p/11_kfreebsd_pthread_condattr_setclock_prototype.patch, + d/p/13_sparc_prlimit_prototype.patch: + drop workarounds for #635205, #703545, #703559 which were all fixed + in jessie + * d/p/81-skip-monitor-test-on-non-linux.patch: add DEP-3 information + * d/p/90_gio-modules-multiarch-compat.patch: add DEP-3 information + + [ Iain Lane ] + * New upstream release 2.45.2 + + Improve error reporting in glib-compile-schemas. + + Add introspection annotations to GListStore. + * GDBus-tests-change-progress-noise-from-if-not-quiet-.patch, + gdbus-tests-wait-up-to-60s-for-gdbus-testserver-to-t.patch, + gdbus-connection-wait-up-to-10s-to-actually-send-a-m.patch, + regex-test-do-not-assert-that-system-PCRE-still-has-.patch, + gdbus-serialization-use-check_serialization-instead-.patch, + gdbus-peer-test-let-GDBusServer-start-before-notifyi.patch, + gdatetime-test-don-t-assume-that-time-stands-still.patch: Delete, applied + upstream. + * 07_disable_tests_on_slow_archs.patch: Refresh to defuzz + + -- Iain Lane Tue, 09 Jun 2015 16:19:20 +0100 + +glib2.0 (2.45.1-2) experimental; urgency=medium + + [ Simon McVittie ] + * d/p/regex-if-PCRE-is-8.34-or-later-disable-auto-possessi.patch: + update to my latest version submitted upstream, which fixes undefined + behaviour in the unlikely event that G_REGEX_OPTIMIZE is combined + with g_regex_match_all(). + * d/p/regex-test-do-not-assert-that-system-PCRE-still-has-.patch: + update to my latest version submitted upstream, which asserts that + a newer-than-8.32 system PCRE does not have the bug in question. + * d/p/gdbus-serialization-use-check_serialization-instead-.patch: + add patch to fix FTBFS in non-minimal environments (libdbus-1-dev + installed). Applied upstream for 2.45.2. + + [ Iain Lane ] + * d/p/0001-Fix-trashing-on-overlayfs.patch: Take patch from + upstream bug to fix trashing on overlayfs. + * d/p/0001-glocalfilemonitor-Send-DELETED-event-when-there-is-n.patch: Take + patch from upstream bug to send the right event when moving files outside + a monitored directory. + + -- Iain Lane Mon, 11 May 2015 16:30:47 +0100 + +glib2.0 (2.45.1-1) experimental; urgency=medium + + * New upstream release 2.45.1 + + The GSettings schema compiler, glib-compile-schemas has been changed + to reject schema xml that has duplicate or + elements. Such elements typically occur when translations are merged + into the schema, with xml:lang attributes. This is not the correct way + to translate schemas. Instead keep the translations in the .mo file and + set the gettext-domain attribute on the element. To avoid + breaking already-installed schemas, this change is only taking effect + when you use the --strict option. + + The file monitoring infrastructure has been rewritten, and all backends + have seen major improvements. + + The inotify backend is reporting events with less delay (no event will + be delayed more than 10ms) and wakeups due to file monitoring have + been significantly reduced. A CHANGES_DONE event will also be sent + when new files appear. + + The poll implementation is now using the thread default main context. + + The fam implmentation is now running in the worker thread. + + The fen implementation has been removed, since it was unmaintained. + + The hardcoded 10-thread limit of GTask's thread pool has been removed, + since it was prone to causing deadlocks. The thread pool is now allowed + to grow dynamically and will shrink back over time. + + GSimpleAsyncResult has been deprecated in favor of GTask. + + The algorithm used by GAppInfo to find default handlers for mime types + has been tweaked to prefer apps that handle the specific subtype over + default handlers for a generic supertype. + * d/p/regex-test-do-not-assert-that-system-PCRE-allows-P-1.patch: Drop, + applied upstream. + * debian/control{,.in}: Update Vcs-* for experimental. + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Fri, 01 May 2015 13:37:01 +0100 + +glib2.0 (2.44.1-1) unstable; urgency=medium + + * New upstream release 2.44.1 + + Improve the default application algorithm + + Bump the number of children a GType can have + + Various testsuite improvements + + -- Iain Lane Wed, 13 May 2015 17:46:59 +0100 + +glib2.0 (2.44.0-3) unstable; urgency=medium + + * Team upload. + + [ Simon McVittie ] + * d/p/regex-test-do-not-assert-that-system-PCRE-allows-P-1.patch: + update to the version that went upstream in 2.45.1. No functional change. + * d/p/regex-if-PCRE-is-8.34-or-later-disable-auto-possessi.patch: + update to my latest version submitted upstream, which fixes undefined + behaviour in the unlikely event that G_REGEX_OPTIMIZE is combined + with g_regex_match_all(). + * d/p/regex-test-do-not-assert-that-system-PCRE-still-has-.patch: + update to my latest version submitted upstream, which asserts that + a newer-than-8.32 system PCRE does not have the bug in question. + * d/p/gdbus-serialization-use-check_serialization-instead-.patch: + add patch to fix FTBFS in non-minimal environments (libdbus-1-dev + installed). Applied upstream for 2.45.2. + * d/p/gdbus-peer-test-let-GDBusServer-start-before-notifyi.patch: + add patch fixing a race condition in the gdbus-peer test. + Applied upstream for 2.45.2. + * d/p/GDBus-tests-change-progress-noise-from-if-not-quiet-.patch: + add patch fixing potential test failures caused by corrupt TAP + output. Applied upstream for 2.45.2. + * d/p/gdatetime-test-don-t-assume-that-time-stands-still.patch: + add patch fixing potential test failures at the boundary between + one second and the next. Applied upstream for 2.45.2. + * d/p/10_kfreebsd_issetugid_prototype.patch, + d/p/11_kfreebsd_pthread_condattr_setclock_prototype.patch, + d/p/13_sparc_prlimit_prototype.patch: + drop workarounds for #635205, #703545, #703559 which were all fixed + in jessie + * d/p/81-skip-monitor-test-on-non-linux.patch: add DEP-3 information + * d/p/90_gio-modules-multiarch-compat.patch: add DEP-3 information + + [ Iain Lane ] + * d/p/0001-Fix-trashing-on-overlayfs.patch: Take patch from + upstream bug to fix trashing on overlayfs. + + -- Simon McVittie Tue, 12 May 2015 13:15:38 +0100 + +glib2.0 (2.44.0-2) unstable; urgency=medium + + * Upload to unstable. + * debian/watch: Consider stable versions only. + + -- Iain Lane Fri, 01 May 2015 11:27:39 +0100 + +glib2.0 (2.44.0-1) experimental; urgency=medium + + * New upstream release 2.44.0 + + gsocket: Document FD ownership with g_socket_new_from_fd() + + -- Iain Lane Mon, 30 Mar 2015 16:35:53 +0100 + +glib2.0 (2.43.92-1) experimental; urgency=medium + + * New upstream release 2.43.92 + + GUnixMountMonitor now properly supports multiple main contexts + + many documentation improvements and cleanups. + + new support for HTTP proxies in GIO + + new GTask:completed property + + use "private" futexes in order to further improve the performance of the + contended case of GMutex and g_bit_lock() + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Wed, 18 Mar 2015 11:03:04 +0000 + +glib2.0 (2.43.91-1) experimental; urgency=medium + + * New upstream release 2.43.91 + - We have now added 'g_autofree' as a libgsystem-style autocleanup macro + that calls g_free() on the content of a local variable when it leaves + scope (working only on GCC and clang). + - GApplication now has an "is-busy" property, allowing one to query the + effective busy state. + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Tue, 03 Mar 2015 17:36:38 +0000 + +glib2.0 (2.43.90-1) experimental; urgency=medium + + * New upstream release 2.43.90 + + new GSimpleIOStream class to construct a GIOStream from an arbitrary + GInputStream and GOutputStream + + GApplication: new API for marking 'busy' state according to the value of + a boolean property on another object + + GOptionGroup: add binding support (boxed type, annotation fixes, etc.) + * debian/patches/gdbus-Let-the-pending-read-finish-before-closing-the.patch: + Drop this cherry-pick from an upstream bug - should be fixed differently + in this release (bgo #743990). + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Thu, 19 Feb 2015 11:37:11 +0000 + +glib2.0 (2.43.4-1) experimental; urgency=medium + + * New upstream release 2.43.4 + + GType now has type declaration macros G_DECLARE_DERIVABLE_TYPE, + G_DECLARE_FINAL_TYPE and G_DECLARE_INTERFACE, which significantly reduce + the boilerplate needed for GObject types and interfaces. + + g_autoptr and g_auto are macros for declaring variables with automatic + cleanup. They only work with gcc and clang. + + GListModel is a new interface that represents a dynamic list of GObjects. + + GListStore is a GSequence-based implementation of GListModel. + + g_simple_action_set_state_hint: New function to set the state hint of + GSimpleActions + + g_settings_schema_list_children and g_settings_schema_key_get_name are + new functions to complete the GSettingsSchema API. + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Mon, 16 Feb 2015 16:37:30 +0000 + +glib2.0 (2.43.3-1) experimental; urgency=medium + + [ Laurent Bigonville ] + * debian/control.in, debian/libglib2.0-dev.install.in, + debian/libglib2.0-0-dbg.install.in: Install the gdb python scripts in the + proper locations, move them to the -dbg package and add the needed + Breaks/Replaces (Closes: #774024) + + [ Iain Lane ] + * New upstream release 2.43.3 + + add g_set_object() convenience function + + GNetworkMonitor: check if NM is not running and don't crash + + fix some races with g_mkdir_with_parents + + avoid use of G_STRLOC in G_OBJECT_WARN_INVALID_PSPEC in order to save on + static strings + + fix some content type vs. mime issues + * 07_disable_tests_on_slow_archs.patch: Refresh + + -- Iain Lane Tue, 20 Jan 2015 13:46:28 +0000 + +glib2.0 (2.43.2-1) experimental; urgency=medium + + [ Laurent Bigonville ] + * debian/control.in: Switch build-dependency from libelfg0-dev to libelf-dev + (Closes: #769408) + + [ Iain Lane ] + * New upstream release 2.43.2 + + New function: g_strv_contains + + New function: g_network_address_new_loopback + + New function: g_socket_send_messages + + A new GNetworkMonitor implementation using NetworkManager provides more + detailed connectivity information + * 0001-GSettings-fix-check-for-delaying-backend-subscriptio.patch, + 0001-gmain-fix-poll-record-comparison.patch: gmain: fix the sorting of: + Drop, applied in this release. + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Tue, 16 Dec 2014 17:29:02 +0000 + +glib2.0 (2.43.1-2) experimental; urgency=medium + + * 0001-GSettings-fix-check-for-delaying-backend-subscriptio.patch: + Cherry-pick patch from upstream. Check signal detail too when looking for + pending signal handlers, so that subscribing to changed signals with a + detail works again. + * 0001-gmain-fix-poll-record-comparison.patch: gmain: fix the sorting of + poll records. Resolves FTBFS on ppc64el. + + -- Iain Lane Fri, 28 Nov 2014 18:08:16 +0000 + +glib2.0 (2.43.1-1) experimental; urgency=medium + + * New upstream release 2.43.1, changes since 2.42.1: + + GQueue now accepts NULL as a sibling in g_queue_insert_before() and + g_queue_insert_after() + + GObject gained a debug option to provide instance counts. To use it, set + GOBJECT_DEBUG=instance-count and call g_type_get_instance_count(). + + GOption now has a strict POSIX mode in which it stops parsing arguments + as soon as a non-option argument is encountered. + * debian/control{,.in}: Bump Standards-Version to 3.9.6, no changes + required. + * debian/libglib2.0-0.symbols: Add new symbols for this release. + + -- Iain Lane Tue, 25 Nov 2014 12:46:31 +0000 + +glib2.0 (2.42.1-1) unstable; urgency=medium + + [ Iain Lane ] + * Pass --enable-debug=minimum not minimal - this is what configure.ac + expects. + + [ Emilio Pozuelo Monfort ] + * New upstream bugfix release. + * d/p/0001-properties-disable-default-deprecation-warnings.patch: + + Removed, merged upstream. + + -- Emilio Pozuelo Monfort Tue, 11 Nov 2014 18:53:49 +0100 + +glib2.0 (2.42.0-2) unstable; urgency=medium + + [ Andreas Henriksson ] + * Update Vcs-* to use unstable instead of experimental branch + + [ Iain Lane ] + * 0001-properties-disable-default-deprecation-warnings.patch: Backport from + upstream stable branch - silences warnings that are shown to users on + stderr, and which also cause some testsuite failures and consequent FTBFS. + + -- Iain Lane Thu, 02 Oct 2014 13:08:24 +0100 + +glib2.0 (2.42.0-1) unstable; urgency=medium + + * New upstream release + + -- Iain Lane Tue, 23 Sep 2014 10:12:15 +0100 + +glib2.0 (2.41.5-2) unstable; urgency=medium + + * Upload to unstable. + + -- Andreas Henriksson Fri, 19 Sep 2014 22:00:33 +0200 + +glib2.0 (2.41.5-1) experimental; urgency=medium + + [ Andreas Henriksson ] + * Make libglib2.0-0 recommend xdg-user-dirs + - needed to set up ~/.config/user-dirs.dirs to get default XDG_*_DIR set. + + [ Iain Lane ] + * New upstream release 2.41.5 + - GDesktopAppInfo: avoid polling on missing desktop dirs + + -- Iain Lane Wed, 17 Sep 2014 10:19:27 +0100 + +glib2.0 (2.41.4-1) experimental; urgency=medium + + * New upstream release + * debian/libglib2.0-0.symbols: + + Add g_application_add_main_option symbol + + -- Sjoerd Simons Sat, 06 Sep 2014 15:16:14 +0200 + +glib2.0 (2.41.3-1) experimental; urgency=medium + + * New upstream release 2.41.3 + * debian/tests/installed-tests: Revert the previous change - require dbus >= + 1.8 and always use dbus-run-session. + + -- Iain Lane Wed, 20 Aug 2014 16:16:23 +0100 + +glib2.0 (2.41.2-1) experimental; urgency=medium + + * New upstream release + - The Unicode support has been updated to version 7.0 of the Unicode + standard + - GNotification now supports priorities for notifications + - GMutex now uses a faster, native implementation on Linux + * 0001-gvariant-tests-workaround-libc-compiler-issue.patch: Drop, applied + upstream in this release. + * Add new symbols for this release. + * Merge in changes from 2.40.0-4 + + Adapt for system pcre3/1:8.35 (Closes: #755439): + - a PCRE 8.31 bug in case-insensitivity has been fixed, so do not assert + bug-for-bug compatibility with 8.31 + - named match groups' names cannot start with a digit any more, so + (?P<1>.) is no longer allowed; do not assert that it is + - turn off a new optimization that would reduce the result set when + called from g_match_all(_full), to preserve existing functionality + + Build-depend on pcre3/1:8.35 so that the new optimization is + known to be turned off in the built binaries + + Add patch from upstream to fix mis-optimization in gvariant test + with gcc 4.9 (Closes: #756272) + + Avoid using dbus-launch for regression tests (Closes: #737488): + - run installed-tests under dbus-run-session from dbus (>= 1.8) + - do not run build-time tests under dbus-launch: those that use D-Bus + all create their own session bus instances now + (i.e. remove 05_run-gio-tests-with-a-dbus-session.patch) + - set a deliberately invalid DBUS_SESSION_BUS_ADDRESS to make sure + nothing in the build is still inheriting it from the environment + + Override Lintian false positive #733733: we build-depend on python:any + but Lintian doesn't yet understand :any syntax + * Make the installed tests still run dbus-launch if we don't have + dbus-run-session (i.e. if the installed dbus is << 1.8). + + -- Iain Lane Thu, 14 Aug 2014 11:14:40 +0100 + +glib2.0 (2.41.1-2) experimental; urgency=medium + + * 0001-gvariant-tests-workaround-libc-compiler-issue.patch: Cherry-pick + patch from upstream to fix/workaround a new compiler optimisation in + gcc-4.9 which occurs when passing a null pointer / zero size to memcmp. + Should fix FTBFS on many arches in unstable. + + -- Iain Lane Wed, 25 Jun 2014 10:21:27 +0100 + +glib2.0 (2.41.1-1) experimental; urgency=medium + + * New upstream release + * 0001-Prevent-an-invalid-CARBON_LIBS-from-appearing-in-the.patch: Drop, + included in this release. + * Update symbols file with the new symbol in this release. + + -- Iain Lane Tue, 24 Jun 2014 12:40:29 +0100 + +glib2.0 (2.41.0-2) experimental; urgency=medium + + [ Andreas Henriksson ] + * Bump python:any build-dependency to >= 2.7.5-5~ (Closes: #747928) + + [ Emilio Pozuelo Monfort ] + * Use the default compiler on sparc, since it's already >> 4.7. + Closes: #751313. + + [ Iain Lane ] + * 0001-Prevent-an-invalid-CARBON_LIBS-from-appearing-in-the.patch: + Cherry-pick patch from upstream to fix an invalid "@CARBON_LIBS@" token + appearing in Libs.private in the pcfile. (LP: #1330033) + + -- Iain Lane Mon, 16 Jun 2014 10:17:36 +0100 + +glib2.0 (2.41.0-1) experimental; urgency=medium + + [ Emilio Pozuelo Monfort ] + * debian/libglib2.0-doc.links: + + The symlink for the gtk docs is broken at the moment, and even if + fixed, it will still be broken if libgtk2.0-doc isn't installed on + a system, so just drop it. Closes: #746782. + + [ Iain Lane ] + * New upstream release 2.41.0 + - Many bugfixes found by static analysis, including potential fd leaks and + NULL pointer dereferences. + - Increased use of (nullable) attribute on out values and return types now + that it is supported (mostly from porting Vala metadata). + - use XDG_CURRENT_DESKTOP for OnlyShowIn/NotShowIn handling of desktop + files, deprecating g_desktop_app_info_set_desktop_env() + - add support for g_desktop_app_info_get_implementations() to find desktop + files that have an Implements= line for a given interface + - GHmac has gained SHA-512 support + - support the new mimeapps specification (most notably, moving the + assoications/defaults configuration to ~/.config/mimeapps.list). + - libgobject is now linked -Wl,-z,nodelete when possible to avoid errors + when gobject is used from a module for a program that does not itself use + gobject and that module is unloaded/reloaded + * debian/watch: Use http://ftp.gnome.org; it's more up-to-date. + * Update symbols file with new symbols for this release. + + -- Iain Lane Tue, 27 May 2014 15:41:46 +0100 + +glib2.0 (2.40.0-4) unstable; urgency=medium + + * Team upload + + [ Emilio Pozuelo Monfort ] + * Use the default compiler on sparc, since it's already >> 4.7. + Closes: #751313. + + [ Iain Lane ] + * Fix Vcs-* for the unstable branches + + [ Simon McVittie ] + * Adapt for system pcre3/1:8.35 (Closes: #755439): + - a PCRE 8.31 bug in case-insensitivity has been fixed, so do not assert + bug-for-bug compatibility with 8.31 + - named match groups' names cannot start with a digit any more, so + (?P<1>.) is no longer allowed; do not assert that it is + - turn off a new optimization that would reduce the result set when called + from g_match_all(_full), to preserve existing functionality + * Build-depend on pcre3/1:8.35 so that the new optimization is + known to be turned off in the built binaries + * Add patch from upstream to fix mis-optimization in gvariant test + with gcc 4.9 (Closes: #756272) + * Avoid using dbus-launch for regression tests (Closes: #737488): + - run installed-tests under dbus-run-session from dbus (>= 1.8) + - do not run build-time tests under dbus-launch: those that use D-Bus + all create their own session bus instances now + (i.e. remove 05_run-gio-tests-with-a-dbus-session.patch) + - set a deliberately invalid DBUS_SESSION_BUS_ADDRESS to make sure + nothing in the build is still inheriting it from the environment + * Override Lintian false positive #733733: we build-depend on python:any + but Lintian doesn't yet understand :any syntax + + -- Simon McVittie Sun, 10 Aug 2014 22:58:33 +0100 + +glib2.0 (2.40.0-3) unstable; urgency=medium + + [ Rico Tzschichholz ] + * debian/libglib2.0-bin.install: + - Install /usr/bin/gapplication + + -- Sjoerd Simons Sun, 27 Apr 2014 10:36:34 +0200 + +glib2.0 (2.40.0-2) unstable; urgency=medium + + [ Iain Lane ] + * gdbus-tests-wait-up-to-60s-for-gdbus-testserver-to-t.patch: Take latest + version from upstream bug to resolve some test failures. + * Add xauth test-dep, needed for xvfb-run + + [ Emilio Pozuelo Monfort ] + * Upload to unstable. + + -- Emilio Pozuelo Monfort Wed, 02 Apr 2014 14:37:13 +0200 + +glib2.0 (2.40.0-1) experimental; urgency=medium + + * New upstream release. + + -- Andreas Henriksson Mon, 24 Mar 2014 20:58:34 +0100 + +glib2.0 (2.39.92-2) experimental; urgency=medium + + * test_timer_basic is still broken. Skip it. + + -- Iain Lane Tue, 18 Mar 2014 15:43:35 +0000 + +glib2.0 (2.39.92-1) experimental; urgency=medium + + * New upstream release. + * 0001-timer-test-use-volatile-for-locals.patch: Take patch from bgo #722604 + to workaround gcc's intentional spec violation in the timer tests. + + Remove debian/patches/80-skip-timer-test.patch accordingly; it should + now work. + + -- Iain Lane Tue, 18 Mar 2014 10:14:36 +0000 + +glib2.0 (2.39.91-1) experimental; urgency=medium + + * New upstream release. + * d/p/0001-asyncqueue-fix-timeout-math-on-32bit-systems.patch: + + Dropped, merged upstream. + * debian/patches/81-skip-monitor-test-on-non-linux.patch: + + New patch, skip the monitor test on non-linux as it currently hangs. + * debian/libglib2.0-0.symbols: + + Add a new symbol. + + -- Emilio Pozuelo Monfort Sun, 09 Mar 2014 15:06:31 +0100 + +glib2.0 (2.39.90-2) experimental; urgency=medium + + * debian/control.in: + + Bump gtk-doc-tools build-dependency per configure.ac. + * debian/patches/Don-t-use-a-parallel-build-for-the-documentation.patch: + + Removed, no longer needed with gtk-doc 1.20. + * d/p/0001-asyncqueue-fix-timeout-math-on-32bit-systems.patch: + + Patch from git, fix an overflow in g_async_queue_timed_pop_unlocked + on 32 bits systems. + * debian/patches/80-skip-timer-test.patch: + + Skip the timer test which currently fails on x86 because of float + precission errors. + * debian/rules: + + Make the test suite fatal on linux. + + Run the test suite on !linux, but ignore test suite errors for now. + + -- Emilio Pozuelo Monfort Sun, 23 Feb 2014 16:36:18 +0100 + +glib2.0 (2.39.90-1) experimental; urgency=medium + + * New upstream release. + * Drop patches now included in upstream release: + - 0001-glib-tests-collate.c-run-to-completion-when-skipping.patch + - 0002-g_test_run-return-0-if-all-tests-are-skipped-in-TAP-.patch + * Fix fuzz to make debian/patches/04_homedir_env.patch apply again. + * Use quilt to refresh remaining patches. + * debian/libglib2.0-0.symbols: Add new symbols. + + -- Andreas Henriksson Tue, 18 Feb 2014 19:53:16 +0100 + +glib2.0 (2.39.4-1) experimental; urgency=medium + + * New upstream development release. + * debian/rules: + + Tell dh_clean not to remove org.gtk.test.gschema.xml.orig, otherwise + the build fails as that fail is missing. Apparently dh_clean removes + everything that ends with .orig. + * debian/libglib2.0-0.symbols: + + Add new symbols. + * d/p/valgrind_h_add_r0_to_the_clobber_list_on_PPC.patch, + d/p/tests-move-param-implement-to-m-slow.patch, + d/p/Fix-races-in-unix-signal-dispatch.patch: + + Dropped, applied upstream. + * d/p/0001-glib-tests-collate.c-run-to-completion-when-skipping.patch, + d/p/0002-g_test_run-return-0-if-all-tests-are-skipped-in-TAP-.patch: + + Add patches from upstream to fix test suite errors. + * debian/patches/*: + + Refreshed. + * debian/rules: + + Don't run the test suite in parallel as some tests fail otherwise. + + Ignore test suite errors for now. There are a few known racy tests + that fail randomly, and I'm more interested in whether glib builds + fine everywhere. We should make the tests fatal again before 2.40. + + -- Emilio Pozuelo Monfort Sun, 16 Feb 2014 11:38:59 +0100 + +glib2.0 (2.38.2-5) unstable; urgency=medium + + * Upload to unstable. + + -- Emilio Pozuelo Monfort Sat, 15 Feb 2014 12:34:05 +0100 + +glib2.0 (2.38.2-4) experimental; urgency=medium + + * Team upload + * DEP-3: tag patch for Debian#737501 as sent upstream to GNOME#723653 + * d/p/gdbus-Let-the-pending-read-finish-before-closing-the.patch: + add patch from Mikhail Zabaluev fixing a test failure on mips, + also reproduced on mipsel (Closes: #738290) + * d/p/Fix-races-in-unix-signal-dispatch.patch: add patch from upstream + to fix what appears to be the root cause of #737380 + * d/p/gdbus-tests-wait-up-to-60s-for-gdbus-testserver-to-t.patch, + d/p/gdbus-connection-wait-up-to-10s-to-actually-send-a-m.patch: + improve arbitrary timeouts in regression tests, fixing an unreported + FTBFS on armhf + + -- Simon McVittie Tue, 11 Feb 2014 17:43:08 +0000 + +glib2.0 (2.38.2-3) experimental; urgency=medium + + * Team upload + * d/p/Don-t-use-a-parallel-build-for-the-documentation.patch: + Disable parallel build for the documentation, hopefully fixing an + intermittent FTBFS in which gtk-doc tries to scan Windows-specific + objects (Closes: #737501) + * d/p/Do-not-attempt-to-autolaunch-a-session-dbus-daemon-w.patch: + Refuse to perform D-Bus "autolaunch" if $DISPLAY is unset, in which + case it isn't going to work anyway. This works around a process-launching + issue in the GApplication test on mipsel (Closes: #737380) + * Bump debhelper compat level to 9, resulting in co-installable + multiarch debug symbols and ~ 50% smaller installed size + for libglib2.0-0-dbg (at the cost of ~ 30% larger .deb size) + - mark libglib2.0-0-dbg Multi-Arch: same + + -- Simon McVittie Thu, 06 Feb 2014 09:53:27 +0000 + +glib2.0 (2.38.2-2) experimental; urgency=medium + + * Team upload. + + [ Emilio Pozuelo Monfort ] + * debian/rules: + + Enable parallel builds. + + [ Laurent Bigonville ] + * Add d/p/valgrind_h_add_r0_to_the_clobber_list_on_PPC.patch: Fix FTBFS on + PPC (taken from upstream, Closes: #737379) + + [ Simon McVittie ] + * Add DEP-3 tagging to PPC patch + * Add d/p/tests-move-param-implement-to-m-slow.patch to knock out + test /param/implement, which upstream describe as "essentially a + forkbomb", leading to failures on armel and at least sporadically + on mipsel (Closes: #737381) + + -- Simon McVittie Sun, 02 Feb 2014 20:35:34 +0000 + +glib2.0 (2.38.2-1) experimental; urgency=low + + * New upstream release + - Drop d/p/0001-g_file_copy-Fall-back-to-pathname-queryinfo-to-help-.patch + merged upstream + * debian/control.in: + - Bump Standards-Version to 3.9.5 (no further changes) + - Use canonical URL for Vcs-Svn field + + -- Laurent Bigonville Sat, 14 Dec 2013 16:38:02 +0100 + +glib2.0 (2.38.1-2) experimental; urgency=low + + * debian/rules: + + Set VERBOSE so we get failing tests' stdout and stderr. This will + help us debug the various build failures in different arches. + + -- Emilio Pozuelo Monfort Sun, 27 Oct 2013 21:58:46 +0100 + +glib2.0 (2.38.1-1) experimental; urgency=low + + * Build-Depend on python:any. python is Multi-Arch: allowed; this BD allows + the python from any architecture that can be executed on the builder to + satisfy the BD, simplifying cross building of glib2.0. + * New upstream bugfix release 2.38.1 + + Fix error code checks when SOCK_CLOEXEC is defined but not supported + (fix support for GNU/Hurd) + + g_settings_list_children: only list viable schemas (fix gsettings + list-recursively crashes with invalid schemas installed) + + GDBusObjectManagerClient: Fix typo in the /org/freedesktop/DBus path + when adding match rules + - Remove 0001-gio-Fix-typo-in-the-org-freedesktop-DBus-path.patch + * 0001-g_file_copy-Fall-back-to-pathname-queryinfo-to-help-.patch: + Cherry-pick gio patch to fall back to g_file_query_info if + query_info_on_read is not supported. Fixes copying from backends that + don't implement the latter. (Closes: #715436, LP: #1217230) + + -- Iain Lane Thu, 17 Oct 2013 15:53:12 +0100 + +glib2.0 (2.38.0-1) experimental; urgency=low + + * New upstream release + * debian/patches/0001-gio-Fix-typo-in-the-org-freedesktop-DBus-path.patch: + Cherry-pick patch from upstream to fix object path typo in gio (LP: + #1227295) + * Add --enable-debug=minimal explicitly to the deb build so the debugging + level doesn't change between pre-release and stable versions. + + -- Iain Lane Wed, 25 Sep 2013 10:37:50 +0000 + +glib2.0 (2.37.93-1) experimental; urgency=low + + * New upstream release 2.37.93 (& .92) + + new API g_file_measure_disk_usage() similar to du(1) + * Add new symbols for g_file_measure_disk_usage API added in this release. + + -- Iain Lane Wed, 18 Sep 2013 10:07:15 +0000 + +glib2.0 (2.37.7-1) experimental; urgency=low + + * New upstream 2.37.7 + + GDateTime now supports %:z formatting variations for timezones. This is + a GNU date extension. + + -- Iain Lane Tue, 10 Sep 2013 11:26:28 +0000 + +glib2.0 (2.37.6-1) experimental; urgency=low + + * New upstream release 2.37.6 + * Update symbols file + * Merge changes from unstable, mainly for build / testsuite fixes. + + -- Iain Lane Wed, 21 Aug 2013 09:48:19 +0000 + +glib2.0 (2.37.5-1) experimental; urgency=low + + * New upstream release 2.37.5 (including interesting changes from .3 and .4) + + Implement the Desktop Action specification + + The gsettings tool now reports failure to write a key (e.g. because the + key was locked down) + + add a new API for instance private data: G_DEFINE_TYPE_WITH_PRIVATE + + add new D-Bus API for async property handling + * libglib2.0-tests: Depend on shared-mime-info required by contenttype test. + * New upstream release + * 0001-Revert-g_file_set_contents-don-t-fsync-on-ext3-4.patch: Drop, now + upstream. + * debian/tests/installed-tests: Add a new DEP-8 test to run the + installed-tests. + * Refresh patches. + * Update symbols file. + * debian/patches/skip-brokwn-dbus-appinfo-test.patch: Skip a broken new + dbus-appinfo test which is hanging. + + -- Iain Lane Fri, 02 Aug 2013 16:54:51 +0000 + +glib2.0 (2.37.2-1) experimental; urgency=low + + * New upstream version + + add support for installed tests: + https://live.gnome.org/GnomeGoals/InstalledTests + + add a new g_test_trap_subprocess() that works on Windows as a + replacement for the (now deprecated) g_test_trap_fork() + + support for explicitly cancelling a gobject property binding + + performance improvements for signal argument handling + + stop using `quotes' in very many log messages generated by GLib, for + favour of 'this style'. This may cause testcases in other packages to + fail if they were matching on the previous text. + + improve manpages: add missing arguments and flags + + Installing properties after class initialization is deprecated, and will + trigger a warning. + + GApplication Support org.freedesktop.Application, including D-Bus + activation from desktop files + * Refresh patches. + * Update symbols file with new symbols in this release. + * Enable installed tests and install into a libglib2.0-tests package. + * clean debian/{install,build,stamp-makefile-check} and + gio/gdbus-2.0/codegen/*.pyc + * Set $XDG_RUNTIME_DIR to a writable directory we control; now required by + the testsuite. + + -- Iain Lane Fri, 21 Jun 2013 15:28:46 +0100 + +glib2.0 (2.36.4-1) unstable; urgency=low + + * New upstream release. + * Remove 0001-Revert-g_file_set_contents-don-t-fsync-on-ext3-4.patch, merged + upstream. + * Make test suite linux only again. On kfreebsd the test suite keeps getting + stuck and the build is killed after a timeout. + + -- Michael Biebl Sat, 10 Aug 2013 09:57:58 +0200 + +glib2.0 (2.36.3-4) unstable; urgency=low + + [ Josselin Mouette ] + * Still run the testsuite on !linux, even though non-fatal. + + [ Michael Biebl ] + * Track stable releases. + * Use dh_python2 to properly generate the dependencies for gdbus-codegen, + which is shipped in libglib2.0-dev. + + -- Michael Biebl Sun, 04 Aug 2013 16:39:05 +0200 + +glib2.0 (2.36.3-3) unstable; urgency=low + + [ Julien Cristau ] + * Use gcc-4.8 on sparc to fix misbuild causing test failure (closes: #709781). + + [ Josselin Mouette ] + * Only make the testsuite fatal on linux. Although the other + architectures don’t pass, we have to keep a pair of reverse + dependencies working. + + -- Josselin Mouette Sat, 06 Jul 2013 15:51:11 +0200 + +glib2.0 (2.36.3-2) unstable; urgency=low + + * 0001-Revert-g_file_set_contents-don-t-fsync-on-ext3-4.patch: + + Patch from the upstream 2.36 stable branch. Revert a previous + commit that dropped calls to fsync() on ext[234] fileystems as + that caused data corruption in some cases (e.g. corrupted dconf + db on power loss). + + -- Emilio Pozuelo Monfort Thu, 20 Jun 2013 23:17:54 +0200 + +glib2.0 (2.36.3-1) unstable; urgency=low + + [ Josselin Mouette ] + * Make the testsuite fatal on all architectures. If it fails, we need + to fix it or drop the architecture, not to ignore it. + * Break libgnome-desktop-3-2 < 3.4.2-2 for the thumbnails location + change. + + [ Emilio Pozuelo Monfort ] + * New upstream bugfix release. Closes: #708568. + * debian/patches/13_sparc_prlimit_prototype.patch: + + Refreshed. + + -- Emilio Pozuelo Monfort Mon, 10 Jun 2013 21:34:19 +0200 + +glib2.0 (2.36.1-2) unstable; urgency=low + + * Merge experimental branch, upload to unstable. + + -- Martin Pitt Wed, 08 May 2013 06:25:57 +0200 + +glib2.0 (2.36.1-1) experimental; urgency=low + + * New upstream release + * Refresh debian/patches/06_thread_test_ignore_prctl_fail.patch + + -- Iain Lane Tue, 23 Apr 2013 10:20:47 +0100 + +glib2.0 (2.36.0-2) experimental; urgency=low + + * debian/rules: + + Don't abort the build if the test suite fails on mipsel. + * debian/patches/17_check_abis_mips_symbols.patch: + + Also allow _ftext in libgthread. + + -- Emilio Pozuelo Monfort Thu, 28 Mar 2013 12:44:06 +0100 + +glib2.0 (2.36.0-1) experimental; urgency=low + + * New upstream release. + + debian/libglib2.0-0.symbols: + - Updated. + * debian/rules: + + Make the test suite fatal in armel and armhf. + * debian/patches/17_check_abis_mips_symbols.patch: + + Add _ftext to the list of allowed symbols, since that + is leaked on mips. + + -- Emilio Pozuelo Monfort Tue, 26 Mar 2013 11:14:37 +0100 + +glib2.0 (2.35.9-2) experimental; urgency=low + + * d/p/11_kfreebsd_pthread_condattr_setclock_prototype.patch: + + Another patch to fix the build on kfreebsd. Add a prototype + for pthread_condattr_setclock() when building on kfreebsd + since the prototype there is missing. The glibc bug to add + the missing prototype is #703545, we can remove this hack + when that is fixed. + * debian/patches/13_sparc_prlimit_prototype.patch: + + New patch, only use prlimit if the prototype is available. + Should fix the build on sparc where prlimit is available but + the prototype is missing. Thanks to Julien Cristau for the + patch. This works-around #703559 and can be removed when that + bug is fixed. + * debian/patches/15_gio_desktop_app_info_test_bin_true_path.patch: + + Change path for 'true' to /bin/true as that's where it is in + Debian. This fixes a testcase that was failing on every arch + and was causing the build to fail on ia64 and powerpc as test + failures are fatal on those arches. + * debian/rules: + + Use filter instead of findstring to match the current arch + against the list of architectures where the test suite should + not be fatal, as the latter matches substrings and so it was + making the testsuite non-fatal on amd64 and i386 because they + match kfreebsd-amd64 and kfreebsd-i386. + + -- Emilio Pozuelo Monfort Thu, 21 Mar 2013 16:24:45 +0100 + +glib2.0 (2.35.9-1) experimental; urgency=low + + * debian/control.in: + + Break python-gi (<< 3.7.2). Closes: #702603. + * New upstream release. + + debian/patches/04_homedir_env.patch: + - Updated to apply again. + * debian/rules: + + Set HOME instead G_HOME, as GLib now honors the former. We will + eventually remove our local patch to support G_HOME, so packages + that need to override the home directory for the test suite should + switch to overriding HOME. + * debian/libglib2.0-0.symbols: + + Bump minimum version for g_get_home_dir() so that users that need + HOME to be honored get a proper runtime dependency. + * debian/patches/10_kfreebsd_issetugid_prototype.patch: + + Untested patch to fix the build on kfreebsd. + + -- Emilio Pozuelo Monfort Tue, 19 Mar 2013 13:58:27 +0100 + +glib2.0 (2.35.8-1) experimental; urgency=low + + [ Matthias Klose ] + * Configure cross builds with --disable-modular-tests --disable-gtk-doc. + + [ Iain Lane ] + * Merges from unstable branch (Michael Biebl) + - Take into account multiarch when removing the cache files in postrm: + Remove /usr/lib/gio/modules/giomodule.cache only for the native + architecture for which this cache file was created. + After removing /usr/share/glib-2.0/schemas/gschemas.compiled on purge, + run dpkg-trigger explicitly, so in case libglib2.0-0 is installed for + other architectures, the cache file is re-created. (Closes: #696389) + - Drop the various Breaks from libglib2.0-0. Those are causing APT to + fail on a dist-upgrade from squeeze to wheezy. (Closes: #676485) + * Refresh patches and slightly rework debian/patches/04_homedir_env.patch: + g_get_home_dir() now respects the HOME environment variable but we'll keep + G_HOME for now as packages in Debian rely on it. + * gdbus-codegen .py files have moved to /usr/share/glib-2.0 + * Update symbols file + + [ Martin Pitt ] + * New upstream release 2.35.4 + * debian/libglib2.0-0.symbols: Update for new upstream release. + * Drop 08_disable_gapplication_basic_test.patch, test is now more robust. + * Drop 92_revert_appinfo_command_line.patch and add xterm build dependency; + xterm is rather lightweight in terms of dependencies and is sufficient to + run all the "Terminal=true" tests. + * Add 08_fix_closure_invalidation.patch: gsignal: fix closure invalidation + code. (GNOME #690118) + + [ Emilio Pozuelo Monfort ] + * New upstream release 2.35.8. + + debian/patches/08_fix_closure_invalidation.patch: + - Removed, applied upstream. + + debian/patches/*: + - Refreshed. + + debian/libglib2.0-0.symbols: + - Updated for the new symbols. + + -- Emilio Pozuelo Monfort Sat, 23 Feb 2013 19:27:38 +0100 + +glib2.0 (2.34.3-1) experimental; urgency=low + + * New upstream release. + + -- Emilio Pozuelo Monfort Wed, 28 Nov 2012 14:38:35 +0100 + +glib2.0 (2.34.2-1) experimental; urgency=low + + * Team upload + + [ Martin Pitt ] + * debian/rules: Re-enable failing the build on failed tests on armel/armhf + on Ubuntu, now that the buildds behave themselves again. + + [ Simon McVittie ] + * New upstream release + - 50_git_gmenuexporter_allow_null_bus_on_name_vanished.patch: remove, + applied upstream + - 91_kfreebsd_credentials.patch: remove, applied upstream + * Override a couple of package-contains-empty-directory lintian tags + for deliberate empty directories + * Override package-contains-devhelp-file-without-symlink lintian tag + for gdbus-object-manager-example, which is deliberately not in devhelp + + -- Simon McVittie Mon, 12 Nov 2012 16:08:29 +0000 + +glib2.0 (2.34.1-2) experimental; urgency=low + + * Team upload + * Apply patch from unstable to use the FreeBSD credentials-passing code + path on kFreeBSD too, fixing (at least) gnome-terminal and lightdm on + kFreeBSD (Closes: #581750, #631968) + + -- Simon McVittie Wed, 31 Oct 2012 12:56:54 +0000 + +glib2.0 (2.34.1-1) experimental; urgency=low + + [ Josselin Mouette ] + * Require libelfg0-dev, not libelf-dev which has nothing to do with + it. + + [ Iain Lane ] + * New upstream release + + GTimeZone support for zoneinfo version 1 + + Leak in glib-compile-resources + + g_settings_bind: use canonical property name + + Port gio tests from pygobject to pygi + * Switch python-gobject-2 BD to python-gi, folowing porting of tests. + * debian/patches/50_git_gmenuexporter_allow_null_bus_on_name_vanished.patch: + Cherry-pick upstream patch to fix crash when GBusNameVanishedCallback is + called with a NULL GDBusConnection. (LP: #1044322) + + -- Iain Lane Wed, 17 Oct 2012 11:51:14 +0100 + +glib2.0 (2.34.0-1) experimental; urgency=low + + [ Martin Pitt ] + * debian/rules: Only run tests for the main flavour; it takes too + long for all three and does not give us a lot of extra confidence. + * debian/rules: Manually create debian/stamp-makefile-check, as with above + change it's not created automatically any more. + * Add 07_disable_tests_on_slow_archs.patch: Disable tests on slow + architectures which keep failing the tests. These are currently + /socket/timed_wait, /mainloop/timeouts, /mainloop/child_sources, + /timeout/rounding, and the upper bound on /gdbus/method-calls-in-thread on + ARM platforms. + * debian/control.in: Bump pcre dependency to >= 1:8.31. + * debian/rules: Seems there is no way of making the test suite work reliably + with the upgraded Ubuntu ARM builders, so make tests non-fatal on + arm{el,hf} until they get less swap happy. + + [ Michael Biebl ] + * New upstream release. + * Drop debian/patches/91_revert_pcre_8.31_test.patch now that we have a + recent enough version. + + -- Martin Pitt Thu, 27 Sep 2012 11:22:56 +0200 + +glib2.0 (2.33.14-1) experimental; urgency=low + + [ Iain Lane ] + * New upstream release + + CVE-2012-3524: don't run dbus-launch from setuid binaries + + g_content_type_get_generic_icon_name(): new API for getting the icon + name for a mime type + + Introspection fixes: + - GDBusConnection nullability fixes + - give a box type to GTimeZone + + Drop GVFS_INOTIFY_DIAG + + Add a new "Writing GLib Applications" section to the reference + documentation with general info on security, threads, etc. + + gwin32mount.c: Fix syntax error + + gresource tests: srcdir != builddir fixes + + tests/gvariant: Fix test on big endian architectures + + Fix regression in g_shell_parse_argv() + * Dropped 07_tests_gvariant_big_endian.patch: applied upstream. + + [ Michael Biebl ] + * Bump all 2.33.x symbol versions to 2.33.14 to ensure a tight enough + dependency for packages using features from glib 2.33. + + -- Michael Biebl Wed, 19 Sep 2012 18:38:24 +0200 + +glib2.0 (2.33.12-4) experimental; urgency=low + + * debian/patches/03_disble_glib_compile_schemas_warning.patch: Add a new + patch to disable a warning when compiling schemas which are installed into + 'deprecated' locations. Users see this very often due to + glib-compile-schemas being called from libglib2.0-0's trigger and it is + not very useful for them. + + -- Iain Lane Mon, 10 Sep 2012 16:25:18 +0100 + +glib2.0 (2.33.12-3) experimental; urgency=low + + * debian/control.in: Add Breaks: too glib-networking versions prior to + 2.33.12. (LP: #1046319) + * debian/rules: Ignore test case failures on hurd-i386 (not a release + architecture) and mips (this keeps tripping over a gdbus test race + condition). + * Replace 07_disable_gvariant_checksum_tests.patch with + 07_tests_gvariant_big_endian.patch which fixes the test properly instead + of disabling it. Taken from + https://bugzilla.gnome.org/show_bug.cgi?id=683384 + + -- Martin Pitt Thu, 06 Sep 2012 06:14:41 +0200 + +glib2.0 (2.33.12-2) experimental; urgency=low + + * Drop 10_increase_gapplication_test_delay.patch. We disable the whole test + now anyway (08_disable_gapplication_basic_test.patch). + * Add 07_disable_gvariant_checksum_tests.patch: 2.33.12 introduced two new + checks for GVariant checksum stability. This does not currently work on + big-endian machines (https://bugzilla.gnome.org/show_bug.cgi?id=683384), + so disable these tests for now. + + -- Martin Pitt Wed, 05 Sep 2012 11:19:29 +0200 + +glib2.0 (2.33.12-1) experimental; urgency=low + + [ Sebastien Bacher ] + * New upstream version + * debian/libglib2.0-0.symbols: + - updated + * revert_g_file_make_directory_with_parents_error_propagation.patch: + - dropped, the issue is fixed in the new version + * debian/patches/92_revert_appinfo_command_line.patch: + - don't require a vte for test, we don't want an xorg stack there + + [ Iain Lane ] + * Add revert_g_file_make_directory_with_parents_error_propagation.patch: + This reverts upstream commit b0bce4ad41937dabf7e5c94dcce3caf4e88f3f97 + which caused applications to segfault. The proper fix will be in the next + glib release, so this patch should be dropped then. (LP: #1035688) + + [ Martin Pitt ] + * Add 07_test_method_calls_on_proxy_bump_max_time.patch: On slower + platforms, the overhead of the 240 D-BUS Sleep calls is larger than + the current maximum of 6 seconds. Bump maximum time to 8 seconds to be + more resilient to this. + * Add 08_disable_gapplication_basic_test.patch: Disable /gapplication/basic + test. It's full of race conditions and keeps breaking builds. + + [ Robert Ancell ] + * New upstream bugfix release (LP: #1045608) + * Drop 07_test_method_calls_on_proxy_bump_max_time.patch: + - Applied upstream + + -- Martin Pitt Tue, 04 Sep 2012 15:50:40 +0200 + +glib2.0 (2.33.8-1) experimental; urgency=low + + * New upstream release 2.33.8. + - GIO now has a g_file_delete_async function + - The defaults for GThreadPools max_unused_threads and max_idle_time + values have been changed to 2 and 15*1000, respectively. + * debian/control{,.in}: XC-Package-Type → Package-Type, thanks to Lintian. + * debian/libglib2.0-0.symbols: Update for new symbols in this release and + remove Debian revisions which aren't necessary. + + -- Iain Lane Tue, 07 Aug 2012 14:38:25 +0100 + +glib2.0 (2.33.6-1) experimental; urgency=low + + * New upstream release. + * Drop 91_revert_schema_path_warning.patch now, we are not in final freeze + in Ubuntu, and this is not aimed at Debian Wheezy. + * Add 91_revert_pcre_8.31_test.patch: Revert new regex test from 2.33.4 + which depends on pcre 8.31. We still have 8.30, and we are building + against the system library instead of the bundled one. + + -- Martin Pitt Wed, 18 Jul 2012 14:41:39 +0200 + +glib2.0 (2.33.4-1) experimental; urgency=low + + [ Martin Pitt ] + * debian/rules: Make tests always fatal on Ubuntu. + + [ Iain Lane ] + * New upstream release 2.33.4. + * Refresh patches to apply cleanly and remove those applied upstream. + * Bump version on libpcre-dev BD in line with upstream. + * debian/libglib2.0-0.symbols: Add new symbols in this release. + + -- Iain Lane Mon, 16 Jul 2012 11:55:30 +0100 + +glib2.0 (2.33.3-2) experimental; urgency=low + + * Rename 07_socket_test_timespan_jitter.patch to 00git_* and update + changelog with what got committed upstream. + * Add 07_contenttype_test_fix_overflow.patch: Call g_content_type_guess() + with valid data len. Fixes a segfault when running the test. + Forwarded to GNOME #674452. + * Add 08_contenttype_known_test_failure.patch: Disable known test failure + due to a bug in g_content_type_from_mime_type(). For details, see + https://bugzilla.gnome.org/show_bug.cgi?id=678941 + * Add 09_valuetransform_ulong_bool.patch: valuetransform: Fix definition of + ulong_bool. Thanks Philipp Kern! (Closes: #662057) + * Add 10_increase_gapplication_test_delay.patch: /gapplication/basic + sometimes fails due to a different order of expected and actual actions; + increase delay between them to reduce the race condition. Workaround for + https://bugzilla.gnome.org/show_bug.cgi?id=664627 + * Add 11_timeout_test_reduce_race.patch: Due to load, particular traits of + the architecture, or other circumstances, the /mainloop/timeouts sometimes + manages to call the "every 100 ms" timer loop only 9 times in 1050 ms. + This is an inherent race-condition in the test; allow it some slack and + accept 9 times as well. Forwarded to GNOME #678959. + + -- Martin Pitt Wed, 27 Jun 2012 11:50:54 +0200 + +glib2.0 (2.33.3-1) experimental; urgency=low + + * New upstream release. + * debian/libglib2.0-0.symbols: Add new symbols from this release. + * debian/libglib2.0-bin.install: bash completion is now installed into + /usr/share/bash-completion/completions/ by upstream. + * Add debian/libglib2.0-bin.maintscript: Clean up old bash completion + conffiles on upgrade. Add ${misc:Pre-Depends} to libglib2.0-bin. + * Add debian/tests/control: DEP-8 autopkgtest control file. Add XS-Testsuite + header to debian/control.in. + * Add debian/tests/build: autopkgtest check: Build and run a program against + glib, to verify that the headers and pkg-config file are installed + correctly. + * Add 06_thread_test_ignore_prctl_fail.patch: Do not fail the + /thread/thread4 test if prctrl() fails. This happens on the Debian + buildds. + * debian/rules: Set G_HOME to not clutter $HOME with ~/.dbus-keyrings and + avoid failure on the buildds where creating /home/buildd/.dbus-keyrings + fails. + * debian/rules: Fail the build on failed tests, except on architectures with + known current failures (arm*, kfreebsd*, s390x, sparc). + * Add 07_socket_test_timespan_jitter.patch: On some buildds the poll + duration in the /socket/timed_wait test is slightly lower than the + requested 100000. Adjust test to not fail in these cases. Forwarded to + GNOME #678881. + + -- Martin Pitt Tue, 26 Jun 2012 19:28:14 +0200 + +glib2.0 (2.33.2-1) experimental; urgency=low + + * Track unstable versions in the experimental branch. + * New upstream release 2.33.2 + - GLIB_VERSION_MIN_REQUIRED now defaults to the current stable version + - GIO input and output stream classes have grown GBytes-based methods + - GApplication now has hooks to register D-Bus objects before the bus name + is taken + * Refresh 04_homedir_env.patch to cleanly apply + * Add the new symbols from this release (g_app_info_get_supported_types, + g_*_bytes, g_type_ensure) + + -- Iain Lane Mon, 18 Jun 2012 11:56:08 +0100 + +glib2.0 (2.33.1-1) experimental; urgency=low + + * debian/control.in: Update Vcs-* for experimental branch. + * Drop 03_revert_git_single_include_error.patch. For GNOME 3.5.x we want to + properly fix the reverse dependencies. NB this is NOT for Debian wheezy. + * New upstream release. + * 04_homedir_env.patch: Adjust for new release. + * Drop 95_configure-Fix-typo-in-ELF-check.patch and + 96_configure-Reset-LIBS-after-ELF-check.patch: upstream now. + * debian/libglib2.0-0.symbols: Add new symbols from this release. + + -- Martin Pitt Tue, 15 May 2012 16:59:15 +0200 + +glib2.0 (2.33.12+really2.32.4-5) unstable; urgency=low + + * Fix the closing fi in the if statement in postrm. + + -- Michael Biebl Wed, 09 Jan 2013 16:14:49 +0100 + +glib2.0 (2.33.12+really2.32.4-4) unstable; urgency=low + + * Take into account multiarch when removing the cache files in postrm: + Remove /usr/lib/gio/modules/giomodule.cache only for the native + architecture for which this cache file was created. + After removing /usr/share/glib-2.0/schemas/gschemas.compiled on purge, + run dpkg-trigger explicitly, so in case libglib2.0-0 is installed for + other architectures, the cache file is re-created. (Closes: #696389) + * Drop the various Breaks from libglib2.0-0. Those are causing APT to fail + on a dist-upgrade from squeeze to wheezy. (Closes: #676485) + + -- Michael Biebl Tue, 08 Jan 2013 23:30:04 +0100 + +glib2.0 (2.33.12+really2.32.4-3) unstable; urgency=low + + * Team upload + * 92_kfreebsd_credentials.patch: use the FreeBSD credentials-passing + implementation on kFreeBSD too, making gnome-terminal and lightdm + work on kFreeBSD (Closes: #631968) + + -- Simon McVittie Wed, 24 Oct 2012 10:51:08 +0100 + +glib2.0 (2.33.12+really2.32.4-2) unstable; urgency=medium + + * Revert link adding for gdbus-object-manager-example. While it is + useful to have in /usr/share/doc as an example, it must not be + shipped with the system documentation. + * 20_glib-compile-resources_leak.patch: new patch. Fix a leak + introduced in version 2.32.4. Thanks Niels Thykier! + * SECURITY: add 11_CVE-2012-3524_setuid.patch from upstream. Prevents + using DBus in a setuid binary. Fixes CVE-2012-3524. + + -- Josselin Mouette Sat, 06 Oct 2012 01:15:16 +0200 + +glib2.0 (2.33.12+really2.32.4-1) unstable; urgency=low + + * New upstream bugfix release. + * 10_gdbus_race.patch: stolen from upstream git. Fix a race condition + that would make gnome-shell crash on startup under some conditions. + * libglib2.0-bin.install: bash completions have moved to /usr/share. + * libglib2.0-bin.maintscript: remove old conffiles. + * Add appropriate pre-dependency. + * libglib2.0-doc.links: add link for gdbus-object-manager-example. + + -- Josselin Mouette Sat, 22 Sep 2012 17:59:34 +0200 + +glib2.0 (2.33.12+really2.32.3-2) unstable; urgency=low + + * Explicitly set the shlibs version to 2.32.3 to not generate overly strict + dependencies for udeb packages. + + -- Michael Biebl Wed, 19 Sep 2012 21:25:56 +0200 + +glib2.0 (2.33.12+really2.32.3-1) unstable; urgency=low + + * Brown paper bag upload + * Re-upload version previously in unstable to superseded + experimental-targetted version previously mistakenly uploaded there. + + -- Iain Lane Mon, 10 Sep 2012 22:52:32 +0100 + +glib2.0 (2.32.3-1) unstable; urgency=low + + * New upstream release. + * Remove debian/patches/95_configure-Fix-typo-in-ELF-check.patch and + debian/patches/96_configure-Reset-LIBS-after-ELF-check.patch, merged + upstream. + + -- Michael Biebl Tue, 15 May 2012 16:12:21 +0200 + +glib2.0 (2.32.2-1) unstable; urgency=low + + * New upstream release. + * Refresh patches. + * Remove debian/patches/git_powerpc_gresources.patch, merged upstream. + * debian/patches/95_configure-Fix-typo-in-ELF-check.patch: Fix typo in ELF + configure check. Patch cherry-picked from upstream Git. + * debian/patches/96_configure-Reset-LIBS-after-ELF-check.patch: Reset LIBS + after running the ELF checks otherwise we end up linking everything + against libelf. Patch cherry-picked from upstream Git. + + -- Michael Biebl Tue, 01 May 2012 20:02:21 +0200 + +glib2.0 (2.32.1-1) unstable; urgency=low + + * New upstream release. + * Refresh patches. + * debian/patches/git_powerpc_gresources.patch: Upstream fix for gresource on + big endian architectures, i.e powerpc. Closes: #669130 + * debian/patches/revert_schema_path_warning.patch: Revert upstream commit + which generates a warning for applications using a non-recommended + gsettings path. Final freeze is not the time to start fixing the gsettings + paths of all packages. This avoids tons of spewage from the gsettings + trigger during package installation. + + -- Michael Biebl Thu, 26 Apr 2012 23:13:28 +0200 + +glib2.0 (2.32.0-4) unstable; urgency=low + + * Set --sourcedir for the different flavors when running dh_install. This + way the .install files can be simplified a lot which makes them much more + readable. + * Bump Standards-Version to 3.9.3. + * Add Breaks against emacs23, eog and gwaei. Those applications were broken + due to changes in GApplication and the way they interacted with + GdkThreads so they needed to be fixed to correctly work with glib 2.32. + Closes: #668019 + + -- Michael Biebl Mon, 09 Apr 2012 14:16:26 +0200 + +glib2.0 (2.32.0-3) unstable; urgency=low + + [ Martin Pitt ] + * 01_gettext-desktopfiles.patch: Use official "Keywords" key now, + X-GNOME-Keywords has been deprecated for a while now. (LP: #949864) + * debian/libglib2.0-0.postrm.in: Only remove the compiled schemas on purge, + not during upgrades. Otherwise we have no schemas available until the new + postinst is run, which leads to applications aborting on missing schemas. + + [ Michael Biebl ] + * Don't enforce single include for glib/gversionmacros.h since this header + is included from glib/gtypes.h which is widely used. + + -- Michael Biebl Fri, 30 Mar 2012 23:55:41 +0200 + +glib2.0 (2.32.0-2) unstable; urgency=low + + * Upload to unstable. + * Revert upstream commit for now which makes single includes mandatory as + the list of affected packages is still a bit too long. + + -- Michael Biebl Fri, 30 Mar 2012 08:25:15 +0200 + +glib2.0 (2.32.0-1) experimental; urgency=low + + * New upstream release. + * Add single-include guard for gbytes.h. Patch cherry-picked from + upstream Git. + + -- Michael Biebl Mon, 26 Mar 2012 18:41:49 +0200 + +glib2.0 (2.31.22-1) experimental; urgency=low + + * New upstream development release. + * debian/libglib2.0-0.symbols: Add new symbol. + + -- Michael Biebl Tue, 20 Mar 2012 02:00:06 +0100 + +glib2.0 (2.31.20-1) experimental; urgency=low + + * New upstream development release. + * debian/patches/61_glib-compile-binaries-path.patch: Refreshed. + * debian/libglib2.0-0.symbols: Add new symbols. + * Override list-missing target with an implementation that better handles + multiple flavors (copied from the gtk+3.0 package). + + -- Michael Biebl Tue, 06 Mar 2012 02:28:12 +0100 + +glib2.0 (2.31.18-3) experimental; urgency=low + + * debian/control.in: Add Build-Depends on python-dbus, python-gobject-2, and + libxml2-utils (xmllint). Required to run the test-suite. + + -- Michael Biebl Sun, 04 Mar 2012 20:27:09 +0100 + +glib2.0 (2.31.18-2) experimental; urgency=low + + * debian/control.in: + - add libpcre3-dev to the list of dependencies of libglib2.0-dev + - add libelf-dev as a build dependency to make gresource able to deal + with ELF files + + -- Gustavo Noronha Silva Sat, 03 Mar 2012 17:29:51 -0300 + +glib2.0 (2.31.18-1) experimental; urgency=low + + [ Gustavo Noronha Silva ] + * New development release + - Yeah, 2.31.8 was a mistake =/ + * debian/libglib2.0-0.symbols: + - fix version declared for 2.31.8 symbols to not have -1 + - updated for 2.31.8 symbols + * debian/patches/61_glib-compile-schemas-path.patch, + debian/patches/61_glib-compile-binaries-path.patch: + - renamed, and updated to also cover glib-compile-resources + * debian/libglib2.0-0.install.in: + - add glib-compile-resources + + [ Michael Biebl ] + * debian/libglib2.0-bin.install: Install new gresource binary and the man + pages for gresource and glib-compile-resources. + * debian/libglib2.0-bin.links.in: Add symlink in /usr/bin for + glib-compile-resources since we install the binary in a multiarch path. + * debian/rules: Re-enable test-suite on kfreebsd but keep it non-fatal for + now. + + -- Michael Biebl Sat, 03 Mar 2012 02:36:26 +0100 + +glib2.0 (2.31.8-1) experimental; urgency=low + + * New development release + * debian/patches/*: + - refreshed; + * debian/patches/95-gmain-get-rid-of-poll_waiting.patch, + debian/patches/96-fix-one-bit-mutex-test-on-some-platforms.patch, + debian/patches/97-silence-compiler-warnings.patch, + debian/patches/98-disable-two-more-GDBus-tests-using-fork.patch: + - removed; applied upstream + * debian/libglib2.0-0.symbols: + - updated with new symbols + NOTES: + + g_simple_action_get_parameter_type (from 2.28.0) + was made static in 09429e2c820118918e6132d32884eb02203136d4 + + g_unix_resolver_get_type (from 2.22.0) was removed + by 5a30712dc7e4adc36b0e8fd82cf5ccec19bbbdc5, with the + removal of !g_thread_supported code paths + + -- Gustavo Noronha Silva Fri, 02 Mar 2012 00:34:30 -0300 + +glib2.0 (2.30.2-7) UNRELEASED; urgency=low + + * libglib2.0-0.postinst.in: + + Encapsulate gio-querymodules calls in || true statements. + Closes: #659588. + + Only run gio-querymodules on the non-multiarch path for the host + architecture. + * rules: add substitution for #ARCH# for the above change. + + -- Josselin Mouette Thu, 16 Feb 2012 12:21:51 +0100 + +glib2.0 (2.30.2-6) unstable; urgency=low + + * Revert the patches added in 2.30.2-5 which changed the handling of return + types from libffi. They didn't actually fix the build failures on s390x + and had some unpleasant side effects, like making other packages FTBFS. + + -- Michael Biebl Wed, 25 Jan 2012 12:17:29 +0100 + +glib2.0 (2.30.2-5) unstable; urgency=low + + [ Josselin Mouette ] + * Drop deprecated build-dependencies on pygobject & python-dbus. + * Retain one on python for the script that uses it. + + [ Loïc Minier ] + * Avoid harmless warnings when processing triggers of libglib2.0-0 + ("Unable to open directory /usr/lib/gio/modules: Error opening + directory '/usr/lib/gio/modules': No such file or directory"). + + [ Michael Biebl ] + * Cherry-pick patches from upstream Git which fix handling of ENUMs and + integral return types on 64-bit BE platforms. Closes: #653308 + - Add d/p/94-closure-fix-handling-of-ENUMs-and-integral-return-ty.patch. + - Add d/p/93-gvalue-Add-explicitly-signed-g_value_get_schar-and-g.patch. + - Update symbols file accordingly. + + -- Michael Biebl Wed, 18 Jan 2012 13:50:56 +0100 + +glib2.0 (2.30.2-4) unstable; urgency=low + + * Upload to unstable. + * Disable test suite on kfreebsd-* for now. + + -- Michael Biebl Fri, 18 Nov 2011 19:38:40 +0100 + +glib2.0 (2.30.2-3) experimental; urgency=low + + * debian/patches/98-disable-two-more-GDBus-tests-using-fork.patch: + - Added. Disable gdbus test which use GMainContext over a fork, see + https://bugzilla.gnome.org/show_bug.cgi?id=658999 for more details + + -- Sjoerd Simons Thu, 17 Nov 2011 22:20:48 +0000 + +glib2.0 (2.30.2-2) experimental; urgency=low + + * debian/patches/95-gmain-get-rid-of-poll_waiting.patch: + - Added, Fix race conditions with g_main_quit being called from other + threads by getting rid of the poll_waiting flag. (Backported from git + master) + * debian/patches/96-fix-one-bit-mutex-test-on-some-platforms.patch: + - Added, Fix the 1 bit mutex failing on platforms that have pointers + aligned to 32 bits instead of 64 bits (bgo#201322). + * debian/patches/97-silence-compiler-warnings.patch: + - Added, Fix various compiler warnings + + -- Sjoerd Simons Wed, 16 Nov 2011 22:21:52 +0000 + +glib2.0 (2.30.2-1) experimental; urgency=low + + * New upstream release. + * debian/patches/70-fix-race-in-gdbus-connection-test.patch: + - Removed, merged upstream. + * debian/patches/80_gtk_doc_out_of_tree.patch: + - Removed, merged upstream. + + -- Michael Biebl Sun, 13 Nov 2011 01:24:28 +0100 + +glib2.0 (2.30.1-2) experimental; urgency=low + + [ Martin Pitt ] + * debian/patches/01_gettext-desktopfiles.patch: + - Translate X-GNOME-FullName and X-GNOME-Keywords, too. + + [ Sjoerd Simons ] + * debian/patches/80_gtk_doc_out_of_tree.patch: + - Added. Fix documentation generation when build out of tree + + [ Michael Biebl ] + * Transition to multiarch, thanks Steve. Closes: #634099 + The following modifications were made to the original patch: + - Drop the libtool .la files, since we break existing references anyway. + - Don't mark libglib2.0-0-dbg as Multi-Arch: same and install into + /usr/lib/debug, not /usr/lib//debug. + - Guard the for loops in debian/rules with "set -e". + * debian/libglib2.0-dev.install.in: + - Install gdb auto-load files. + + -- Michael Biebl Fri, 21 Oct 2011 21:26:48 +0200 + +glib2.0 (2.30.1-1) experimental; urgency=low + + [ Michael Biebl ] + * New upstream release. + - Avoid assertion in GDBus if we fail to authenticate twice. + Closes: #634312 + * Bump debhelper compatibility level to 8. + - Bump Build-Depends on debhelper. + - Don't pass --dbg-package= without an argument to dh_strip as commands + will fail rather than warn when they are passed unknown options. + * Don't use brace expansion in debian/libglib2.0-0.install and + debian/libglib2.0-dev.install. + * debian/control.in + - Use architecture wildcard for kfreebsd and hurd. + - Bump Standards-Version to 3.9.2. No further changes. + - Set pkg-gnome-maintainers@lists.alioth.debian.org as Maintainer. + - Add Build-Depends on libffi-dev (>= 3.0.0). + * debian/libglib2.0-dev.install + - Install gdbus-codegen binary and manpage. + - Install gtester and gtester-report manpage. + * debian/libglib2.0-bin.install + - Install bash completion files for gdbus and gsettings. + * debian/libglib2.0-0.symbols + - Update symbols file. The GAction API had an incompatible change. As a + result g_action_set_state has been renamed to g_action_change_state. + See upstream commit 5ff65d869543587d10d78c123698e47effc5fb8c for further + details and on the impact of this change. + * debian/watch: + - Track .xz tarballs. + * Update patches + - Remove 03_blacklist-directories.patch, merged upstream. + - Remove 10_gdesktopappinfo_set_last_used.patch, fixed upstream. + - Remove 60_wait-longer-for-threads-to-die.patch, fixed upstream using a + counter. + - Refresh remaining patches. + + [ Josselin Mouette ] + * Break gtk3 < 3.0.12 because it uses an internal symbol that ceases + to work with glib 2.30. + + [ Sjoerd Simons ] + * debian/rules: Explicitely build gtk-doc + * debian/patches/70-fix-race-in-gdbus-connection-test.patch: + - Added, fix race condition in the GDBusConnection life-cycle test + + -- Sjoerd Simons Sun, 16 Oct 2011 11:50:31 +0100 + +glib2.0 (2.28.8-1) unstable; urgency=low + + * New upstream release. + * debian/watch: + - Update to version 3. + - Track .xz tarballs. + * Bump debhelper compatibility level to 8. + - Bump Build-Depends on debhelper. + - Don't pass --dbg-package= without an argument to dh_strip as commands + will fail rather than warn when they are passed unknown options. + * Don't use brace expansion in debian/libglib2.0-0.install and + debian/libglib2.0-dev.install. + * debian/control.in + - Use architecture wildcard for kfreebsd and hurd. + - Bump Standards-Version to 3.9.2. No further changes. + - Set pkg-gnome-maintainers@lists.alioth.debian.org as Maintainer. + * Refresh patches. + + -- Michael Biebl Sat, 15 Oct 2011 18:09:05 +0200 + +glib2.0 (2.28.6-4) unstable; urgency=low + + * Upload to unstable. + + -- Michael Biebl Fri, 14 Oct 2011 10:42:58 +0200 + +glib2.0 (2.28.6-3) experimental; urgency=low + + * Break gnome-session < 3.0.0-3 for the updated defaults.list taking + x-scheme-* into account. + * Break gdm < 3.0.3 to avoid adding a security hole to it. + * 10_gdesktopappinfo_set_last_used.patch: new patch. When calling + g_app_info_set_as_last_used_for_type, correctly inherit the default + filled in the file from the system default. This avoids + gnome-control-center breaking file associations just by opening the + info dialog. + + -- Josselin Mouette Sun, 04 Sep 2011 23:07:46 +0200 + +glib2.0 (2.28.6-2) experimental; urgency=low + + * Team upload. + * Drop 20_mime_extension_point.patch and add Breaks against gvfs + and gnome-control-center to ensure they have been updated at the + same time. + * Drop Conflicts against pango, it's no longer relevant (even for + oldstable). + * Fix watch file. + * Drop leading article in descriptions as recommended by lintian. + * Add lintian overrides for package-name-doesnt-match-sonames, it's a + deliberate choice. + * Add some copyright holders to debian/copyright to appease lintian. + * Drop unneeded section/priority fields as they duplicate the default + values. + * Add some DEP-3 descriptions to patches that had no description at + all. + + -- Raphaël Hertzog Thu, 14 Apr 2011 10:51:16 +0200 + +glib2.0 (2.28.6-1) unstable; urgency=low + + * New upstream bugfix release. + + -- Sebastian Dröge Thu, 14 Apr 2011 09:18:31 +0200 + +glib2.0 (2.28.4-1) unstable; urgency=low + + * debian/control.in: + + Build depend on dbus, dbus-x11, shared-mime-info, python-gobject + and python-dbus, needed by the test suite. + + libglib2.0-data doesn't need to depend on libglib2.0-0, since + it only ships translations. This will avoid making glib + uninstallable on the buildds when it is uploaded until the new + version has been built. + * d/p/0001-Run-gio-tests-with-a-dbus-session.patch: + + New patch. Run gio tests through dbus-launch, since some of them + need a running dbus session. + * debian/control.in, + debian/rules: + + Add autoreconf magic, needed by the above patch. + * New upstream release. + + -- Emilio Pozuelo Monfort Mon, 28 Mar 2011 19:53:02 +0100 + +glib2.0 (2.28.2-1) unstable; urgency=low + + * New upstream release. + + -- Emilio Pozuelo Monfort Fri, 11 Mar 2011 21:05:36 +0000 + +glib2.0 (2.28.1-1) unstable; urgency=low + + * New upstream release. + + Fixes g_timeout_add overflowing with large timeouts. Closes: #606618. + + -- Emilio Pozuelo Monfort Sat, 19 Feb 2011 21:24:21 +0000 + +glib2.0 (2.28.0-2) unstable; urgency=low + + * 20_mime_extension_point.patch: temporary revert the upstream change + in URI schemes handling. Closes: #612876. + Note for later: it must absolutely be reverted in a synchronized + upload with gvfs 1.8 and control-center 3.0. + + -- Josselin Mouette Fri, 18 Feb 2011 19:36:42 +0100 + +glib2.0 (2.28.0-1) unstable; urgency=low + + * debian/control.in: + + Drop obsolete conflicts/replaces with libglib1.3. + + Don't suggest libgtk2.0-doc in the doc package. + * New upstream stable release. + + debian/control.in: + - Bump the libpcre3-dev build dependency. + + debian/patches/01_gettext-desktopfiles.patch, + debian/patches/02_gettext-desktopfiles-ubuntu.patch, + debian/patches/04_homedir_env.patch, + debian/patches/61_glib-compile-schemas-path.patch: + - Refreshed. + + debian/libglib2.0-0.symbols: + - Updated. + + -- Emilio Pozuelo Monfort Wed, 09 Feb 2011 21:52:02 +0000 + +glib2.0 (2.27.91-1) experimental; urgency=low + + * debian/rules: + - Don't exclude .sgml and .devhelp files from being compressed. + The former are already excluded by dh_compress and the later + can be compressed now that devhelp can handle them. + - Fix variable substitution. + * New upstream release. + - debian/patches/62_dont_crash_without_desktop_filename.patch: + + Removed, included upstream. + * debian/control.in: + - Standards-Version is 3.9.1, no changes needed. + + -- Emilio Pozuelo Monfort Tue, 11 Jan 2011 22:59:07 +0000 + +glib2.0 (2.27.90-2) experimental; urgency=low + + * debian/patches/62_dont_crash_without_desktop_filename.patch + * Added. Fix crash when launching application without a desktop file (From + upstream git) + + -- Sjoerd Simons Fri, 07 Jan 2011 11:28:34 +0000 + +glib2.0 (2.27.90-1) experimental; urgency=low + + * Switch to CDBS' flavors system. + * Switch to source format 3.0 (quilt). + * Stop symlinking /usr/share/doc/$pkg directories. + * debian/rules: + - Explicitly link with --no-as-needed, as --as-needed might be the + default and is harmful for us. + - Run the test suite but don't make it fatal yet. + * New upstream release. + - debian/libglib2.0-0.symbols: + + Updated. + + -- Emilio Pozuelo Monfort Thu, 06 Jan 2011 12:46:00 +0000 + +glib2.0 (2.27.5-1) experimental; urgency=low + + * New upstream release. + + debian/libglib2.0-0.symbols: + - Updated. + * debian/rules: + + Make the shlibs always depend on the latest upstream version. + We have symbols file anyway, and manually bumping the shver is + error prone. + + -- Emilio Pozuelo Monfort Thu, 23 Dec 2010 01:44:45 +0000 + +glib2.0 (2.27.4-2) experimental; urgency=low + + * debian/rules: Change --disable-visibility to --disable-Bsymbolic for + the refdbg package. + + -- Jonny Lamb Wed, 15 Dec 2010 21:52:29 +0000 + +glib2.0 (2.27.4-1) experimental; urgency=low + + * New upstream release. + + debian/libglib2.0-0.symbols: + - Updated. + + debian/rules: + - Bump the SHVER. + + -- Emilio Pozuelo Monfort Tue, 30 Nov 2010 00:48:49 +0100 + +glib2.0 (2.27.3-1) experimental; urgency=low + + * New upstream release. + + debian/libglib2.0-0.symbols: + - Updated. + + -- Emilio Pozuelo Monfort Mon, 15 Nov 2010 23:05:29 +0100 + +glib2.0 (2.27.2-1) experimental; urgency=low + + * New upstream development release: + + debian/patches/*: + - Refreshed. + + debian/libglib2.0-0.symbols: + - Updated + + debian/patches/70_dtrace.patch: + - Dropped, merged upstream. + + -- Sebastian Dröge Mon, 01 Nov 2010 10:53:15 +0100 + +glib2.0 (2.27.1-1) experimental; urgency=low + + [ Josselin Mouette ] + * Drop lynx dependency in the -doc package. Suggest devhelp instead. + Closes: #599743. + + [ Sebastian Dröge ] + * New upstream development release: + + debian/patches/70_fix-header-cleaup-fallout.patch: + - Dropped, merged upstream. + + debian/patches/*: + - Refreshed. + + debian/libglib2.0-0.symbols: + - Updated + + debian/patches/70_dtrace.patch: + - Patch from upstream GIT to not enable DTrace if it's not + available. Fixes the build on kFreeBSD (Closes: #592024). + + -- Sebastian Dröge Fri, 29 Oct 2010 11:32:02 +0200 + +glib2.0 (2.27.0-1) experimental; urgency=low + + [ Sjoerd Simons ] + * New upstream experimental release + * debian/libglib2.0-0.symbols + + Updated + * debian/patches/70_fix-header-cleaup-fallout.patch + + Added. Fix complilation error (from upstream git) + + [ Sebastian Dröge ] + * Upload to experimental. + * debian/rules: + + Update SHVER to 2.27.0. + + -- Sebastian Dröge Tue, 12 Oct 2010 10:56:13 +0200 + +glib2.0 (2.26.0-1) experimental; urgency=low + + * New upstream stable release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for the new version. + + debian/patches/90_gregex-system-pcre.patch: + - Dropped, merged upstream. + + -- Sebastian Dröge Mon, 27 Sep 2010 22:43:13 +0200 + +glib2.0 (2.25.16-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for the new version. + + debian/patches/90_gregex-system-pcre.patch: + - Fix GRegex compilation with the system pcre. + + -- Sebastian Dröge Sat, 18 Sep 2010 07:15:26 +0200 + +glib2.0 (2.25.15-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for the new version. + + -- Sebastian Dröge Tue, 31 Aug 2010 11:26:25 +0200 + +glib2.0 (2.25.14-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for the new version. + + -- Sebastian Dröge Tue, 17 Aug 2010 11:37:23 +0200 + +glib2.0 (2.25.13-1) experimental; urgency=low + + * New upstream development release: + + debian/patches/90_git_glibconfig_build.patch, + + debian/patches/99_autoreconf.patch: + - Dropped, merged upstream. + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for the new version. + + debian/control.in: + - (Build-) depend on pkg-config >= 0.16.0. + + -- Sebastian Dröge Sat, 07 Aug 2010 09:34:16 +0200 + +glib2.0 (2.25.12-2) experimental; urgency=low + + [ Sebastien Bacher ] + * debian/rules: + + clean the distributed glibconfig.h it has 64 bits values + which leaded to the issues on 32 bits architectures + (Closes: #591075, #591492). + * debian/patches/90_git_glibconfig_build.patch: + + git change to use the builddir glibconfig.h and not the srcdir one + + [ Sebastian Dröge ] + * debian/patches/99_autoreconf.patch: + + Regenerated autotools files for the above patch. + * debian/rules: + + Call dh_installdirs to actually use the .dirs files. + + -- Sebastian Dröge Fri, 06 Aug 2010 18:50:27 +0200 + +glib2.0 (2.25.12-1) experimental; urgency=low + + [ Josselin Mouette ] + * Don’t run the triggers when executed from a nonexistent directory. + Closes: #589693. + + [ Sebastian Dröge ] + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API changes. + + debian/patches/99_gsocket-create-socket-cloexec.patch: + - Dropped, merged upstream. + + -- Sebastian Dröge Fri, 30 Jul 2010 12:29:10 +0200 + +glib2.0 (2.25.11-3) experimental; urgency=low + + * debian/patches/99_gsocket-create-socket-cloexec.patch: + Patch by Julien Cristau: + Just because SOCK_CLOEXEC was defined at build time doesn't mean the + kernel we're running on supports it. So if socket() fails with EINVAL, + try again without the flag. + + -- Sebastian Dröge Thu, 15 Jul 2010 20:23:30 +0200 + +glib2.0 (2.25.11-2) experimental; urgency=low + + * debian/control.in, + debian/libglib2.0-bin.links, + debian/libglib2.0-0.links: + + Move links to the -bin package again but let the -dev package + depend on the -bin package. Having the links in the shared library + package will cause conflicts when the soname changes but the + links in /usr/bin must be there at least if the -dev package is + installed because build systems might assume that the applications + are in $PATH. + * debian/patches/61_glib-compile-schemas-path.patch: + + Adjust path to glib-compile-schemas in the pkg-config file. + + -- Sebastian Dröge Tue, 13 Jul 2010 14:06:28 +0200 + +glib2.0 (2.25.11-1) experimental; urgency=low + + [ Josselin Mouette ] + * Drop type-handling usage. Closes: #587863. + * Bump standards version accordingly. + * Patch from Ubuntu, thanks Sébastien Bacher. Closes: #587661. + * debian/libglib2.0-bin.install: + - Install glib-compile-schemas + * debian/libglib2.0-bin.postinst: + - Run glib-compile-schemas when schemas modified + * debian/libglib2.0-bin.triggers: + - Watch for schema changes + * debian/libglib2.0-dev.install: + - glib-compile-schemas moved to libglib2.0-bin + * debian/libglib2.0-dev.install: + - install the new gdb python macros since the gdb version is recent + enough now to use those + * Put gio-querymodules and glib-compile-schemas in a private, + versioned directory in libglib2.0-0 to avoid a dependency loop. + * Move back the triggers to libglib2.0-0. + * Add a purge of the necessary files in the postinst. + * Stop recommending libglib2.0-bin since the necessary stuff is in + libglib2.0-0 now. + * Add symlinks to keep the binaries at their place in libglib2.0-bin. + * Tighten the dependency between libglib2.0-bin and libglib2.0-0. + + [ Sebastian Dröge ] + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API changes. + * debian/libglib2.0-0.dirs: + + Create empty directories for the triggers to actually work. + * debian/libglib2.0-0.links, + debian/control.in: + + Add links for gio-querymodules and glib-compile-schemas in + /usr/bin. + + -- Sebastian Dröge Sun, 11 Jul 2010 20:13:58 +0200 + +glib2.0 (2.25.10-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API changes. + + debian/libglib2.0-dev.install: + - Drop gsettings-schema-convert. + + debian/patches/*: + - Refreshed all patches. + + -- Sebastian Dröge Thu, 24 Jun 2010 19:59:54 +0200 + +glib2.0 (2.25.9-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API additions. + + -- Sebastian Dröge Fri, 18 Jun 2010 06:24:03 +0200 + +glib2.0 (2.25.8-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API additions. + + -- Sebastian Dröge Tue, 08 Jun 2010 11:07:18 +0200 + +glib2.0 (2.25.7-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API additions. + + -- Sebastian Dröge Tue, 25 May 2010 11:29:07 +0200 + +glib2.0 (2.25.6-1) experimental; urgency=low + + * New upstream development release. + + -- Sebastian Dröge Thu, 20 May 2010 10:27:41 +0200 + +glib2.0 (2.25.5-1) experimental; urgency=low + + * New upstream development release. + + -- Sebastian Dröge Sat, 15 May 2010 09:44:10 +0200 + +glib2.0 (2.25.4-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API additions. + + debian/libglib2.0-bin.install: + - Add gdbus utility and manpage. + + -- Sebastian Dröge Fri, 14 May 2010 18:25:58 +0200 + +glib2.0 (2.25.3-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API additions. + + debian/libglib2.0-dev.install: + - gschema-compile was renamed to glib-compile-schemas. + + debian/control.in, + debian/rules: + - Manpages are now properly shipped with the tarballs, + drop xsltproc, etc. build dependencies. + + -- Sebastian Dröge Sat, 24 Apr 2010 06:16:59 +0200 + +glib2.0 (2.25.2-1) experimental; urgency=low + + * New upstream development release: + + debian/libglib2.0-0.install, + debian/libglib2.0-0.triggers, + debian/control.in, + debian/rules, + debian/libglib2.0-bin.install, + debian/libglib2.0-bin.triggers: + - Move binaries to an unversioned, separate package. + - Add new gsettings tool. + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API additions. + + -- Sebastian Dröge Fri, 23 Apr 2010 06:14:47 +0200 + +glib2.0 (2.25.1-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for API additions. + + debian/libglib2.0-dev.install, + debian/libglib2.0-0.install: + - Install new GSettings utitilies and manpages. + * debian/control.in, + debian/rules: + + Enable manpage generation via xsltproc for now until + https://bugzilla.gnome.org/show_bug.cgi?id=616264 + is fixed. + + -- Sebastian Dröge Tue, 20 Apr 2010 09:24:20 +0200 + +glib2.0 (2.24.0-1) unstable; urgency=low + + * New upstream stable release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated 2.23 symbols to 2.24 to force dependencies on a stable release. + + debian/rules: + - Remove check-dist.mk include to allow uploads to unstable again. + + -- Sebastian Dröge Fri, 26 Mar 2010 16:59:18 +0100 + +glib2.0 (2.23.6-1) experimental; urgency=low + + [ Emilio Pozuelo Monfort ] + * debian/patches/05_gvariant_test_failure.patch: + - Backport patch from upstream git to fix a gvariant test that fails + randomly on x86. + + [ Sebastian Dröge ] + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new API. + + debian/patches/05_gvariant_test_failure.patch: + - Dropped, merged upstream. + * debian/rules: + + Make unit test failures non-fatal again because of race conditions + in some tests. + + -- Sebastian Dröge Mon, 22 Mar 2010 06:10:18 +0100 + +glib2.0 (2.23.5-1) experimental; urgency=low + + [ Emilio Pozuelo Monfort ] + * debian/patches/05-dont-fail-a-couple-of-tests-when-running-as-root.patch: + - Updated. + * 06-test-for-unexisting-files-in-TMP-and-not-in-HOME.patch: + - Added, don't look for an unexisting file in $HOME since it will + fail with an unexpected result if it's not writable (which happens + on some buildds). Look at $TMP instead. + * debian/rules: + - Make test suite failures fatal on amd64, i386 and s390. + + [ Sebastian Dröge ] + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new API. + + debian/patches/05-dont-fail-a-couple-of-tests-when-running-as-root.patch, + debian/patches/06-test-for-unexisting-files-in-TMP-and-not-in-HOME.patch: + - Dropped, merged upstream. + + -- Sebastian Dröge Mon, 08 Mar 2010 18:49:00 +0000 + +glib2.0 (2.23.4-1) experimental; urgency=low + + [ Emilio Pozuelo Monfort ] + * debian/patches/05-dont-fail-a-couple-of-tests-when-running-as-root.patch: + - Added, expect a couple of tests that play with file permissions + to succeed when running as root. + * debian/control.in: + - Add desktop-file-utils to build depends to fix another test. + - Standards-Version is 3.8.4, no changes needed. + - Let libgio-fam depend on ${misc:Depends}. + + [ Sebastian Dröge ] + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new API. + + -- Sebastian Dröge Mon, 22 Feb 2010 09:04:48 +0100 + +glib2.0 (2.23.3-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new API. + + -- Sebastian Dröge Tue, 09 Feb 2010 16:48:07 +0100 + +glib2.0 (2.23.2-2) experimental; urgency=low + + * debian/control.in, + debian/libglib2.0-0.triggers, + debian/libglib2.0-0.install, + debian/libglib2.0-dev.install: + + Ship gio-querymodules in the shared library package + and triggers calls to every time /usr/lib/gio/modules + is touched by a package. + + -- Sebastian Dröge Tue, 26 Jan 2010 09:40:47 +0100 + +glib2.0 (2.23.2-1) experimental; urgency=low + + * New upstream development release: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new API. + + -- Sebastian Dröge Tue, 26 Jan 2010 08:14:26 +0100 + +glib2.0 (2.23.1-1) experimental; urgency=low + + [ Sebastian Dröge ] + * debian/control.in: + + Let the -dev package depend on zlib1g-dev as it's required by + the pkg-config file now. + + [ Emilio Pozuelo Monfort ] + * New upstream release. + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new API. + + -- Emilio Pozuelo Monfort Tue, 22 Dec 2009 23:25:41 +0100 + +glib2.0 (2.23.0-1) experimental; urgency=low + + [ Loïc Minier ] + * -refdbg package is section/prio debug/extra. + * Add note to NOT use -Wl,--as-needed as it might drop a critical -lpthread + link in gio (which dlopen()s gvfs); see + mid:<1257999019.21780.15.camel@marzipan>. + + [ Sebastian Dröge ] + * New upstream development release: + + debian/patches/90_mimetype-sorting.patch: + - Dropped, merged upstream. + + debian/rules, + debian/libglib2.0-0.symbols: + - Update for new API. + + debian/control.in: + - Build depend on zlib. + + debian/rules: + - Include check-dist.mk to prevent accidental uploads to unstable. + + -- Sebastian Dröge Mon, 30 Nov 2009 10:04:07 +0100 + +glib2.0 (2.22.2-2) unstable; urgency=low + + * debian/patches/90_mimetype-sorting.patch: + + Fix sorting of mimetypes by weight. Highest weight means most + important, not the other way around. Patch from upstream GIT. + + -- Sebastian Dröge Thu, 08 Oct 2009 18:34:23 +0200 + +glib2.0 (2.22.2-1) unstable; urgency=low + + [ Emilio Pozuelo Monfort ] + * Move libglib2.0-data to section libs. Closes: #549079. + + [ Sebastian Dröge ] + * New upstream bugfix release. + + -- Sebastian Dröge Thu, 08 Oct 2009 12:48:51 +0200 + +glib2.0 (2.22.1-1) unstable; urgency=low + + * New upstream bugfix release: + + debian/patches/10_inotify_init1.patch, + debian/patches/30_metadata_symlinks.patch: + - Dropped, merged upstream. + + -- Sebastian Dröge Wed, 30 Sep 2009 08:17:57 +0200 + +glib2.0 (2.22.0-2) unstable; urgency=low + + * Don’t install Python GDB macros for now, they only work with an + experimental GDB branch. + * 30_metadata_symlinks.patch: stolen upstream. Get metadata to work + with symbolic links. Closes: #548142. + + -- Josselin Mouette Wed, 30 Sep 2009 01:02:11 +0200 + +glib2.0 (2.22.0-1) unstable; urgency=low + + [ Josselin Mouette ] + * Move libglib-2.0.so.0 to /lib so that DeviceKit (and other potential + sources) can work without having /usr mounted. + * 11_chmod_symlinks.patch: new patch. Fix potential security issue + when manipulating symlink permissions. Thanks Arand Nash for the + heads up. + + [ Sebastian Dröge ] + * New upstream stable release: + + debian/patches/11_chmod_symlinks.patch: + - Dropped, merged upstream. + + debian/libglib2.0-0.symbols, + debian/rules: + - Update for the new version. + + -- Sebastian Dröge Wed, 23 Sep 2009 05:04:37 +0200 + +glib2.0 (2.21.6-1) experimental; urgency=low + + [ Josselin Mouette ] + * 10_inotify_init1.patch: fall back on inotify_init when inotify_init1 + does not work, as happens with kernel versions < 2.6.27. + Closes: #544354. + + [ Sebastian Dröge ] + * New upstream development release: + + debian/libglib2.0-0.symbols: + - Update for the new version. + + debian/rules: + - Update SHVER to 2.21.6. + * debian/control.in: + + Updated Standards-Version to 3.8.3, no additional changes needed. + + -- Sebastian Dröge Sat, 05 Sep 2009 07:15:58 +0200 + +glib2.0 (2.21.5-1) experimental; urgency=low + + * New upstream development release: + + debian/libglib2.0-0.symbols: + - Update for the new version. + + debian/rules: + - Update SHVER to 2.21.5. + * debian/control.in: + + Updated Standards-Version to 3.8.2, no additional changes needed. + + -- Sebastian Dröge Tue, 25 Aug 2009 18:38:51 +0200 + +glib2.0 (2.21.4-1) experimental; urgency=low + + * New upstream development release: + + debian/rules: + - Include check-dist.mk to prevent accidental uploads to unstable. + - Update shlib version to 2.21.4. + + debian/libglib2.0-0.symbols: + - Update for the API additions. + * debian/control.in: + + Updated Standards-Version to 3.8.1, no additional changes needed. + + -- Sebastian Dröge Tue, 21 Jul 2009 09:35:33 +0200 + +glib2.0 (2.20.4-1) unstable; urgency=low + + * New upstream bugfix release. + + -- Sebastian Dröge Sat, 27 Jun 2009 09:56:08 +0200 + +glib2.0 (2.20.3-1) unstable; urgency=low + + [ Josselin Mouette ] + * Only build the libgio-fam package for hurd and kfreebsd, it is + totally useless under Linux. + * Make it recommend gamin for kqueue support. + * Make libgamin-dev the primary build-dependency. Closes: #526219. + + [ Sebastian Dröge ] + * New upstream bugfix release. + + -- Sebastian Dröge Mon, 01 Jun 2009 15:35:40 +0200 + +glib2.0 (2.20.1-2) unstable; urgency=low + + * Add refdbg package: libglib2.0-0-refdbg. (Closes: #525915) + + -- Jonny Lamb Tue, 28 Apr 2009 15:11:27 +0100 + +glib2.0 (2.20.1-1) unstable; urgency=low + + * New upstream bugfix release: + + 10_log_valist.patch, dropped. + + -- Sebastian Dröge Sat, 11 Apr 2009 17:00:43 +0200 + +glib2.0 (2.20.0-3) unstable; urgency=low + + * Fix debug package section. + * 10_log_valist.patch: new patch, stolen upstream. Copy a va_list + before using it twice. Closes: #520484. + + -- Josselin Mouette Thu, 09 Apr 2009 20:11:52 +0200 + +glib2.0 (2.20.0-2) unstable; urgency=low + + * Remove 02_usr_share_gnome_applications.patch, now gnome-session sets + XDG_DATA_DIRS accordingly. + + -- Josselin Mouette Thu, 19 Mar 2009 22:59:34 +0100 + +glib2.0 (2.20.0-1) unstable; urgency=low + + * New upstream stable release. + * Upload to unstable, remove check-dist include. + This won't block any transitions because of symbol files. + * debian/libglib2.0-0.symbols, + debian/rules: + + Update for the API changes. + + -- Sebastian Dröge Sat, 14 Mar 2009 10:53:26 +0100 + +glib2.0 (2.19.10-1) experimental; urgency=low + + * New upstream development release. + + -- Sebastian Dröge Mon, 02 Mar 2009 16:04:08 +0100 + +glib2.0 (2.19.8-2) experimental; urgency=low + + * debian/patches/01_gettext-desktopfiles.patch, + debian/patches/02_gettext-desktopfiles-ubuntu.patch: + + Updated from the Ubuntu package, thanks to Martin Pitt for the changes: + - 01_gettext-desktopfiles.patch: Merge OpenSUSE's and our patch: + - Now prefers inline translations over gettext translations, which + fixes a few corner cases (like renaming .desktop files on the + user's desktop), is more in line with the recent gconf patch, + and more palatable for upstream inclusion. + - Use X-GNOME-Gettext-Domain, for preparing upstream inclusion. + - Forwarded upstream now. + - Add 02_gettext-desktopfiles-ubuntu.patch: Provide backwards + compatibility for 01_gettext-desktopfiles.patch for + X-{Debian,Ubuntu}-Gettext-Domain. The latter was changed to use + X-GNOME-, so this is necessary until all our .desktop files are + converted. + + -- Sebastian Dröge Tue, 24 Feb 2009 16:08:05 +0100 + +glib2.0 (2.19.8-1) experimental; urgency=low + + * New upstream development release. + + -- Sebastian Dröge Fri, 20 Feb 2009 10:38:44 +0100 + +glib2.0 (2.19.7-1) experimental; urgency=low + + * New development release + + -- Gustavo Noronha Silva Tue, 17 Feb 2009 01:43:04 -0300 + +glib2.0 (2.19.6-1) experimental; urgency=low + + * New development release + * debian/libglib2.0-0.symbols: + - updated with new symbols + + -- Gustavo Noronha Silva Sun, 15 Feb 2009 23:58:22 -0300 + +glib2.0 (2.18.4-2) unstable; urgency=low + + * Release to unstable + * debian/rules: + - bump SHVER, since we are already forcing a 2.18.0 dependecy on the + symbols introduced in the development versions + * debian/control.in: + - added Homepage and Vcs-* control fields + + -- Gustavo Noronha Silva Sun, 15 Feb 2009 13:00:43 -0300 + +glib2.0 (2.18.4-1) experimental; urgency=low + + [ Josselin Mouette ] + * 04_homedir_env.patch: new patch. Handle the G_HOME environment + variable, to override the passwd entry. This will allow to fix + various kinds of build failures due to restricted build + environments. + + [ Sebastian Dröge ] + * New upstream bugfix release. + + -- Sebastian Dröge Sat, 10 Jan 2009 14:21:55 +0100 + +glib2.0 (2.18.3-1) experimental; urgency=low + + * New upstream bugfix release. + + -- Sebastian Dröge Mon, 24 Nov 2008 10:07:47 +0100 + +glib2.0 (2.18.2-1) experimental; urgency=low + + [ Loic Minier ] + * Suffix the Debian specific pcre bdep with "~" to allow backports and make + lintian happy. + * Update doc-base entries for new doc-base secttions: use Programming/C + instead of Apps/Programming. + * Use uppercase GNOME in doc-base description of glib. + * Recommend shared-mime-info for content-type guessing API; see + GNOME #554563. + * Pass -k to make check. + + [ Sebastian Dröge ] + * New upstream bugfix release. + + -- Sebastian Dröge Sun, 19 Oct 2008 13:26:48 +0200 + +glib2.0 (2.18.1-1) experimental; urgency=low + + * New upstream bugfix release. + * debian/libglib2.0-0.symbols: + + Updated all 2.17 symbols to 2.18.0 to get dependencies on the stable + versions. + + -- Sebastian Dröge Sun, 21 Sep 2008 15:31:15 +0200 + +glib2.0 (2.18.0-1) experimental; urgency=low + + * New upstream stable release, with API addition. + - Update symbols file for new g_object_get_type() symbol and drop + g_slice_debug_tree_statistics() which shouldn't have been exported in + the first place. + - Refresh patches 01_gettext-desktopfiles, + 02_usr_share_gnome_applications, and 03_blacklist-directories to apply + cleanly. + + -- Loic Minier Wed, 03 Sep 2008 00:51:29 +0200 + +glib2.0 (2.17.7-1) experimental; urgency=low + + * New upstream development release, the new API might still change: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new symbols. + + -- Sebastian Dröge Mon, 18 Aug 2008 16:04:30 +0200 + +glib2.0 (2.17.6-1) experimental; urgency=low + + * New upstream development release, the new API might still change: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new symbols. + + -- Sebastian Dröge Mon, 04 Aug 2008 19:54:44 +0200 + +glib2.0 (2.17.4-1) experimental; urgency=low + + [ Loic Minier ] + * List back m68k in arches where we could make the testsuite fatal, + following the update on GNOME #481575. + * Document why testsuite is currently completely disabled (fails when + there's no writable $HOME). + + [ Sebastian Dröge ] + * New upstream development release, the new API might still change: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new symbols. + + debian/patches/90_gio-nautilus-crash.patch: + - Dropped, merged upstream. + + -- Sebastian Dröge Tue, 22 Jul 2008 11:17:05 +0200 + +glib2.0 (2.17.3-2) experimental; urgency=low + + * debian/patches/90_gio-nautilus-crash.patch: + + Patch from upstream SVN to fix a crash in nautilus 2.22. + + -- Sebastian Dröge Sat, 05 Jul 2008 16:57:05 +0200 + +glib2.0 (2.17.3-1) experimental; urgency=low + + * New upstream development release, the new API might still change: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new symbols. + * debian/control.in: + + Updated Standards-Version to 3.8.0, no additional changes needed. + + -- Sebastian Dröge Thu, 03 Jul 2008 11:21:17 +0200 + +glib2.0 (2.17.2-1) experimental; urgency=low + + * New upstream development release, the new API might still change: + + debian/rules, + debian/libglib2.0-0.symbols: + - Updated for the new symbols. + + -- Sebastian Dröge Tue, 17 Jun 2008 09:18:10 +0200 + +glib2.0 (2.17.0-1) experimental; urgency=low + + [ Josselin Mouette ] + * debian/rules: don't compress .sgml and .devhelp files. + + [ Loic Minier ] + * Fix broken second dh_strip invocation which was not only acting on the + udeb but also on binary packages (-s -pUDEB should have been -pUDEB). + + [ Sebastian Dröge ] + * New upstream development release, the new API might still change. + * debian/rules: + + Include check-dist.mk to prevent accidental uploads to unstable. + + Bump SHVER to 2.17.0. + + Pass -c4 to dh_makeshlibs. + * debian/libglib2.0-0.symbols: + + Update symbols. + + -- Sebastian Dröge Wed, 28 May 2008 10:40:30 +0200 + +glib2.0 (2.16.3-2) unstable; urgency=low + + * debian/rules: Don't add the debug symbols of the udeb in the -dbg package. + Makes the debugging info actually usefull again (Closes: #468093) + + -- Sjoerd Simons Fri, 11 Apr 2008 22:58:03 +0200 + +glib2.0 (2.16.3-1) unstable; urgency=low + + [ Sjoerd Simons ] + * debian/patches/70_g_timeout_seconds_fix.patch + + Added. Fix a rare case where a timeout from g_timeout_add_seconds() is + never triggered. See http://bugzilla.gnome.org/show_bug.cgi?id=448943 + + [ Sebastian Dröge ] + * New upstream bugfix release: + + debian/patches/70_g_timeout_seconds_fix.patch: + - Dropped, merged upstream. + + -- Sebastian Dröge Tue, 08 Apr 2008 12:02:07 +0200 + +glib2.0 (2.16.2-1) unstable; urgency=low + + [ Loic Minier ] + * Drop nautilus conflicts as it triggers a bug in the APT resolver on + dist-upgrade. + * Update patch 01_gettext-desktopfiles with a newer version taken from the + Ubuntu package. + * Update and enable patch 01_gettext-desktopfiles to also look for + X-Debian-Gettext-Domain if X-Ubuntu-Gettext-Domain isn't present. + + [ Sebastian Dröge ] + * New upstream bugfix release: + + Fixes FTBFS on hurd/i386 (Closes: #472129). + + debian/patches/04_nfs4.patch, + debian/patches/80_static-mutex-aliasing-warnings.patch, + debian/patches/81_c99-inline-warnings.patch: + - Dropped, merged upstream. + + -- Sebastian Dröge Tue, 01 Apr 2008 07:40:48 +0200 + +glib2.0 (2.16.1-2) unstable; urgency=low + + [ Josselin Mouette ] + * 02_usr_share_gnome_applications.patch: ported from GnomeVFS. Use + /usr/share/gnome/applications/defaults.list to obtain the defaults + for MIME mapping. Currently this file is still shipped by GnomeVFS. + Closes: #469504. + * 03_blacklist-directories.patch: ported from GnomeVFS. Blacklist more + FHS directories that are commonly found as Unix mount points, + including those necessary for live-initramfs. + * 04_nfs4.patch: ported from GnomeVFS. Support for nfs4 filesystems. + + [ Sebastian Dröge ] + * 80_static-mutex-aliasing-warnings.patch: Prevent warnings about + breaking strict-aliasing rules when using G_LOCK(). + See http://bugzilla.gnome.org/show_bug.cgi?id=316221 + * 81_c99-inline-warnings.patch: Fix warnings when using G_INLINE_FUNC + in C99 mode (Closes: #470796). + See http://bugzilla.gnome.org/show_bug.cgi?id=522292 + * Don't ship the old changelogs and news to save some space. + + -- Sebastian Dröge Fri, 14 Mar 2008 10:13:09 +0100 + +glib2.0 (2.16.1-1) unstable; urgency=low + + * New upstream bugfix release. + + -- Sebastian Dröge Tue, 11 Mar 2008 04:41:30 +0100 + +glib2.0 (2.16.0-1) unstable; urgency=low + + * New upstream stable release: + + debian/rules: + - Update shlibs version to 2.16.0. + - Drop check-dist include, upload to unstable. + + debian/libglib2.0-0.symbols: + - Updated symbols for the new version. + + -- Sebastian Dröge Mon, 10 Mar 2008 19:23:55 +0100 + +glib2.0 (2.15.6-1) experimental; urgency=low + + * New upstream release: + + debian/rules: + - Update shlibs version to 2.15.6. + + debian/libglib2.0-0.symbols: + - Updated symbols for the new version. + + -- Sebastian Dröge Tue, 26 Feb 2008 06:22:28 +0100 + +glib2.0 (2.15.5-1) experimental; urgency=low + + * New upstream release: + + debian/patches/02_fam-helper.patch: + - Dropped, merged upstream. + + debian/patches/60_wait-longer-for-threads-to-die.patch: + - Updated to apply cleanly again. + + debian/libglib2.0-0.symbols: + - Update symbols for 2.15.5. + + -- Sebastian Dröge Tue, 12 Feb 2008 06:08:39 +0100 + +glib2.0 (2.15.4-1) experimental; urgency=low + + [ Loic Minier ] + * Add a gio gtk-doc symlink. + * Add a doc-base file for gio. + + [ Sebastian Dröge ] + * New upstream release: + + debian/libglib2.0-0.symbols: + - Update symbols for 2.15.4. + + debian/rules: + - Update API version to 2.15.4. + * debian/patches/02_fam-helper.patch: + + Fix build failure when building with FAM and not gamin. See BGO #509419 + and BGO #512384 for more details. + + -- Sebastian Dröge Tue, 29 Jan 2008 12:14:08 +0100 + +glib2.0 (2.15.3-1) experimental; urgency=low + + * New upstream release. + * debian/rules, + debian/libglib2.0-0.symbols: + + Update shlibs and all unstable symbols to 2.15.3. + + -- Sebastian Dröge Tue, 22 Jan 2008 11:54:42 +0100 + +glib2.0 (2.15.2-3) experimental; urgency=low + + [ Loic Minier ] + * Bump up dpkg-dev build-dep to >= 1.14.13 for Build-Depends-Package; thanks + Raphaël Hertzog. + * Drop duplicate dpkg-dev bdep. + * Let libglib2.0-dev depends on ${shlibs:Depends}; thanks Niko Tyni. + + [ Sebastian Dröge ] + * debian/libgio-fam.install: + + Fix path where we install the GIO FAM plugin. It shouldn't be + /usr/lib/gio/gio but /usr/lib/gio. Thanks to Sedat Dilek for reporting. + + -- Sebastian Dröge Mon, 21 Jan 2008 08:58:33 +0100 + +glib2.0 (2.15.2-2) experimental; urgency=low + + * debian/rules: + + Disable selinux for the udeb until we have a libselinux1 udeb. + + -- Sebastian Dröge Thu, 17 Jan 2008 11:50:11 +0100 + +glib2.0 (2.15.2-1) experimental; urgency=low + + [ Sebastian Dröge ] + * New upstream development release, the new API may still change + incompatibly; API additions: + + Drop patch 67_gcc43-inline.patch, merged upstream. + * Include check-dist again to prevent accidental uploads to unstable. + * Disable testsuite for now. + * Bump shlibs to 2.15.2. + * Add build dependencies for GIO and add libgio-fam package that contains + a GIO file/directory monitoring module that uses fam. + * debian/rules, + debian/libglib2.0-0.symbols, + debian/control.in: + + Add a symbol file for GLib, generated from 2.12.4, 2.14.3, 2.15.2. + This is handled by dh_makeshlibs. Require dpkg-dev (>= 1.14.8) for this. + * debian/control.in: + + Recommend python on the -dev package for the gtester-report utility. + * debian/shlibs.local: + + Dropped as pcre is fixed now since 7.4-1 (Closes: #450796). + + [ Loic Minier ] + * Build-dep on gtk-doc-tools to prevent a spurious warning from + gtk-doc.make: "/bin/sh: line 11: test: !=: unary operator expected". + * Build udeb against system pcre again (now that it provides an udeb); bump + up libpcre build-dep to >= 7.4-1 (Closes: #443067). + + -- Sebastian Dröge Tue, 15 Jan 2008 15:30:20 +0100 + +glib2.0 (2.14.4-2) unstable; urgency=low + + * debian/rules: + + Make testsuite failures on sparc non-fatal too as the + threadpool-test fails there too, most probably of some + timing related bug. See BGO #481573. + + -- Sebastian Dröge Thu, 29 Nov 2007 11:45:57 +0100 + +glib2.0 (2.14.4-1) unstable; urgency=low + + [ Loic Minier ] + * Fix disabled patch name 01_gettext-desktopfiles in series. + + [ Josselin Mouette ] + * Conflict against nautilus < 2.20 according to + http://bugzilla.gnome.org/show_bug.cgi?id=440988#c182 + + [ Sebastian Dröge ] + * New upstream bugfix release. + + -- Sebastian Dröge Sun, 25 Nov 2007 14:37:34 +0100 + +glib2.0 (2.14.3-1) unstable; urgency=high + + [ Sebastian Dröge ] + * debian/shlibs.local: + + Override libpcre3's shlibs to require at least pcre 7.2 (See: #449289). + + [ Loic Minier ] + * New upstream stable release; bug fixes and security update. + - SECURITY: Update the internal copy of PCRE to 7.4, fixes CVE-2007-4767; + the internal copy is used for the udeb. + - Drop relibtoolizing patch, 70_relibtoolize, as upstream prepared this + tarball with libtool 1.5.24. + + -- Loic Minier Sat, 10 Nov 2007 19:59:04 +0100 + +glib2.0 (2.14.2-1) unstable; urgency=low + + * Add GNOME bug id to 70_relibtoolize. + * New upstream stable release; no API change. + * Add lpia to the list of arches on which testsuite failures are fatal. + + -- Loic Minier Wed, 17 Oct 2007 17:19:16 +0200 + +glib2.0 (2.14.1-5) unstable; urgency=low + + * Add a relibtoolizing patch, 70_relibtoolize, to get some hurd-i386 fixes + in libtool; see Debian #445001. + + -- Loic Minier Sun, 07 Oct 2007 16:52:44 +0200 + +glib2.0 (2.14.1-4) unstable; urgency=low + + * Document that testsuite failure aren't fatal on m68k due to GNOME #481575. + * Disable testsuite on arm, mips, powerpc; see GNOME #481573; mipsel was + already disabled because its testsuite results were unknown in + experimental. + * Document that testsuite failure is disabled on hppa, hurd, kfreebsd-amd64, + kfreebsd-i386 due to Debian #428674. + + -- Loic Minier Sat, 29 Sep 2007 13:56:18 +0200 + +glib2.0 (2.14.1-3) unstable; urgency=medium + + * Only build the standards debs against the system PCRE, i.e. build the udeb + against the builtin PCRE until pcre3 provides an udeb. + + -- Loic Minier Tue, 18 Sep 2007 21:35:30 +0200 + +glib2.0 (2.14.1-2) unstable; urgency=low + + * debian/control.in, + debian/rules: + + Build against the system PCRE instead of the supplied one. + + -- Sebastian Dröge Mon, 17 Sep 2007 09:41:48 +0200 + +glib2.0 (2.14.1-1) unstable; urgency=low + + [ Loic Minier ] + * Mention I added 90_fix-abi-check-with-debug in 2.14.0-1 + + [ Sebastian Dröge ] + * New upstream major stable release, without API changes. + * debian/patches/90_fix-abi-check-with-debug.patch: + + Dropped, merged upstream. + + -- Sebastian Dröge Mon, 17 Sep 2007 06:35:29 +0200 + +glib2.0 (2.14.0-2) unstable; urgency=low + + * Upload to unstable; drop check-dist include. + + -- Loic Minier Tue, 21 Aug 2007 09:05:30 +0200 + +glib2.0 (2.14.0-1) experimental; urgency=low + + * Fix double --host/--build flags to configure. + * Update patch 67_gcc43-inline to also fix the headers for GCC 4.2. + * New upstream major stable release; API additions. + - Bump up shlibs to >= 2.14.0. + - Drop patch 90_from_svn_fix_missing_pointer_casting, merged upstream. + - New patch, 90_fix-abi-check-with-debug, fixes build of testsuite in + debug mode; from SVN. + + -- Loic Minier Mon, 20 Aug 2007 21:54:07 +0200 + +glib2.0 (2.13.7-3) experimental; urgency=low + + * debian/patches/90_from_svn_fix_missing_pointer_casting.patch: + - patch from SVN, "fixed missing pointer casts when using atomic ops." + (Closes: #434853) + + -- Sebastien Bacher Fri, 27 Jul 2007 16:14:13 +0200 + +glib2.0 (2.13.7-2) experimental; urgency=low + + * Bump shlibs to 2.13.7. + + -- Loic Minier Wed, 25 Jul 2007 16:09:27 +0200 + +glib2.0 (2.13.7-1) experimental; urgency=low + + * Drop "libtool_is_fool" snippet patching hardcode_libdir_flag_spec and + archive_cmds which is probably dangerous with newer libtools. + * Fix flavor name in a comment of debian/rules. + * Use -s instead of -a in arch-specific dh_* calls. + * New upstream development release; some API additions. + - Drop patch 60_output-lines-during-tests, merged upstream. + * New patch, 60_wait-longer-for-threads-to-die, to wait 5 seconds instead of + one for threads to die in the threadpool test; hopefully fixes hppa and + kfreebsd testsuite failures; see #428674 and #431720. + * Don't make testsuite failures fatal on hppa; closes: #431720. + + -- Loic Minier Thu, 12 Jul 2007 21:37:47 +0200 + +glib2.0 (2.13.6-1) experimental; urgency=low + + * Don't pass -L to dh_shlibdeps as the shlibs.local trick is enough and this + can result in duplicate deps; closes: #317461. + * Set myself as maintainer. + * Cleanups. + * Make the testsuite failures fatal on arches which passed the testsuite + with 2.13.5 in experimental (currently: alpha amd64 arm hppa i386 ia64 + mips powerpc s390); closes: #291486. + * Don't run the testsuite when cross-compiling. + * New upstream development release; only API change is to change back the + definition of GType for C++ to be gulong. + + -- Loic Minier Mon, 02 Jul 2007 10:21:34 +0200 + +glib2.0 (2.13.5-1) experimental; urgency=low + + * New upstream release + - Bump shlibs to >= 2.13.5, as the API was changed + + -- Marc 'HE' Brockschmidt Tue, 19 Jun 2007 16:14:16 +0200 + +glib2.0 (2.13.4-2) experimental; urgency=low + + * New patch, 67_gcc43-inline, fixes FTBFS of apps using glib with GCC 4.3 + which uses C99 where the meaning of "inline" changed; patch was adapted + from patches in GNOME #315437 and Gentoo #156475; closes: #416863. + + -- Loic Minier Sat, 16 Jun 2007 18:49:57 +0200 + +glib2.0 (2.13.4-1) experimental; urgency=low + + * Also honor parallel=n in DEB_BUILD_OPTIONS. + * New upstream release series; these are development releases, the new API + may still change incompatibly. + - Target at experimental; include check-dist. + - Bump up shlibs to >= 2.13.4. + * New patch but disabled, 01_gettext-desktopfiles, permits overriding the + gettext domain when desktop files have such a field; found in the Ubuntu + package. + + -- Loic Minier Wed, 13 Jun 2007 10:52:27 +0200 + +glib2.0 (2.12.12-1) unstable; urgency=low + + * Fix description of the -dbg package. + * New upstream release. + + -- Loic Minier Thu, 03 May 2007 19:14:33 +0200 + +glib2.0 (2.12.11-3) unstable; urgency=medium + + * Initialize CFLAGS to -Wall -g; pass debian/rules' CFLAGS and LDFLAGS to + configure, doh! + * Track all stable versions in watch file. + * Wrap build-deps and deps. + * Add ${misc:Depends}. + * New patch 60_output-lines-during-tests, outputs newlines after thousand + iterations of the inner-loop of the closures test to avoid the timeout on + mips and mipsel buildds. + + -- Loic Minier Thu, 12 Apr 2007 16:13:46 +0200 + +glib2.0 (2.12.11-2) unstable; urgency=low + + * Run "make check" test suite for the deb flavor except if DEB_BUILD_OPTIONS + contains the "nocheck" keyword; ignore failures. + * Include the new uploaders.mk from gnome-pkg-tools instead of duplicating + its logic; build-dep on gnome-pkg-tools >= 0.11. + * Drop useless version computations. + * Add support for DEB_BUILD_OPTIONS_PARALLEL. + * Upload to unstable; drop check-dist include. + + -- Loic Minier Wed, 11 Apr 2007 10:35:43 +0200 + +glib2.0 (2.12.11-1) experimental; urgency=medium + + * New upstream release; no API change. + + -- Loic Minier Fri, 9 Mar 2007 22:02:25 +0100 + +glib2.0 (2.12.10-1) experimental; urgency=low + + * Include the new check-dist Makefile to prevent accidental uploads to + unstable; bump build-dep on gnome-pkg-tools to >= 0.10. + * New upstream release; no API change. + - Rewrite and cleanup the build-system completely to build a set of + flavors; drop obsolete targets; drop obsolete files; switch from + tar-in-tar and sys-build to regular source and quilt patching; + build-depend on quilt; drop DEB_USE_DBS_TARBALL_LAYOUT; create stampdir + when necessary; switch from dh_movefiles and dh_installdirs to + dh_install. + - Drop patch 000_glib-link; merged upstream. + * Bump up Debhelper compatibility level to 5. + * Only ship README.Debian in libglib2.0-dev. + * Empty dependency_libs in the *.la files of libglib2.0-dev. + * Override shlibs for the inter-shlibdeps before computing them. + * Use >= ${source:Version} and ${binary:Version} for inder-deps; build-dep + on dpkg-dev >= 1.13.19. + * Fix --dbg-package name. + * Use make vars for package names. + * Tune udeb description. + * Clean /usr/share/doc symlinks generation and move to dh_link generated + links. + * Cleanup list of invoked dh_* commands. + + -- Loic Minier Thu, 8 Mar 2007 18:51:27 +0100 + +glib2.0 (2.12.9-2) experimental; urgency=low + + * Bump shlibs to >= 2.12.9. + * Avoir overwriting the *.la files of the main build with the *.la files of + the udeb build; fixes "old_library" in *.la files; thanks Tim Dijkstra; + closes: #297741. + + -- Loic Minier Sat, 20 Jan 2007 09:13:40 +0100 + +glib2.0 (2.12.9-1) experimental; urgency=low + + * Add a get-orig-source target to retrieve the upstream tarball. + * New upstream releases; no API change. + - Fixes documentation of g_key_file_set_string_list(); closes: #405028. + - Avoids spewing warnings with gcc 2.95; closes: #303124. + - Drop patch 009_accept-space-in-key-names; merged and adapted upstream. + + -- Loic Minier Wed, 17 Jan 2007 08:55:27 +0100 + +glib2.0 (2.12.7-1) experimental; urgency=low + + * New upstream release; no API change; translation updates, bug fixes, + build fixes. + - Target at experimental for now. + - Drop patch 010_restore-old-key-file-syntax-support, merged and adapted + upstream. + + -- Loic Minier Fri, 5 Jan 2007 12:24:38 +0100 + +glib2.0 (2.12.6-2) unstable; urgency=medium + + * New patch, 010_restore-old-key-file-syntax-support, reverts strict group + names and key names checks introduced between glib 2.12.4 and 2.12.6; + instead of failing, critical warnings are output; updates the relevant + tests as well; closes: #404888. + * New patch, 009_accept-space-in-key-names, adds support for space in key + names (independently of 010_restore-old-key-file-syntax-support); updates + and add relevant tests as well; closes: #404888 as well. + + -- Loic Minier Sun, 31 Dec 2006 20:43:23 +0100 + +glib2.0 (2.12.6-1) unstable; urgency=low + + * New upstream release; no API or ABI change. + - Fixes file-type detection in nautilus; closes: #404015. + + -- Loic Minier Thu, 21 Dec 2006 09:46:30 +0100 + +glib2.0 (2.12.5-3) unstable; urgency=low + + * Upload to unstable. + + -- Loic Minier Wed, 20 Dec 2006 17:27:25 +0100 + +glib2.0 (2.12.5-2) experimental; urgency=low + + * Upload to unstable. + + -- Loic Minier Wed, 20 Dec 2006 08:50:56 +0100 + +glib2.0 (2.12.5-1) experimental; urgency=low + + * Add cross-reference in 2.12.4-2. + * New upstream release; no API or ABI change. + - Target at experimental for now. + - Drop patch 011_glib-gettext-datarootdir, merged upstream. + * Drop patch 010_glib2.0.kfreebsd-amd64, is not needed anymore and seems to + have been at the wrong level anyway. + * Review and comment on the usefulness of patch 000_glib-link. + + -- Loic Minier Tue, 19 Dec 2006 08:52:26 +0100 + +glib2.0 (2.12.4-2) unstable; urgency=low + + * New patch, 011_glib-gettext-datarootdir, to compute datarootdir + appropriately for AM_GLIB_DEFINE_LOCALEDIR; GNOME #343825; + closes: #370282. + + -- Loic Minier Thu, 16 Nov 2006 10:14:52 +0100 + +glib2.0 (2.12.4-1) unstable; urgency=low + + * New upstream release; no API changes. + + -- Loic Minier Mon, 2 Oct 2006 10:39:57 +0200 + +glib2.0 (2.12.3-2) unstable; urgency=low + + * Upload to unstable + + [ Loic Minier] + * Merge 2.10.3-3. + + -- Sebastien Bacher Wed, 13 Sep 2006 13:16:29 +0200 + +glib2.0 (2.12.3-1) experimental; urgency=low + + * New upstream release; no public API changes. + * Broaden the -data dep on the lib to permit bin NMUs. + + -- Loic Minier Wed, 30 Aug 2006 22:12:02 +0200 + +glib2.0 (2.12.2-1) experimental; urgency=low + + * New upstream release; no API changes. + + -- Loic Minier Mon, 21 Aug 2006 12:30:24 +0200 + +glib2.0 (2.12.1-1) experimental; urgency=low + + * New upstream release. + * Sync with overrides and set udeb's Priority to optional instead of extra. + * Bump up Standards-Version to 3.7.2. + + -- Loic Minier Mon, 7 Aug 2006 22:08:21 +0200 + +glib2.0 (2.12.0-1) experimental; urgency=low + + * New upstream version: + Major new features include: + * The Unicode support has been updated to Unicode 5. + * GBookmarkFile: a parser for files containing bookmarks + stored using the Desktop Bookmark specification + * Base64 encoding support + * debian/rules: + - updated shver number + * debian/watch: + - updated + + -- Sebastien Bacher Mon, 3 Jul 2006 10:46:21 +0200 + +glib2.0 (2.10.3-3) unstable; urgency=low + + * debian/patches/999_ia64_atomic_ops_broken.patch: + - dropped, it's not required with the new gcc and it was breaking the build + (Closes: #376260) + + [ Loic Minier ] + * Sync with overrides and set udeb's Priority to optional instead of extra. + + -- Sebastien Bacher Wed, 12 Jul 2006 19:09:21 +0200 + +glib2.0 (2.10.3-2) unstable; urgency=medium + + * Re-add changes from 2.10.2-2 that were lost in the wild + (closes: #361697). + + -- Josselin Mouette Mon, 26 Jun 2006 19:54:17 +0200 + +glib2.0 (2.10.3-1) unstable; urgency=low + + * New upstream version: + Bugs fixed: + - g_completion_complete_utf8 crashes when NULL is passed to it + - update-desktop-database doesn't handle duplicate entries + (Closes: #298668) + - Dereferencing NULL value in g_key_file_get_group_comment + - GKeyFile set_string_list invalid memory reads + - The GObject tutorial say g_object_(un)ref is _not_ thread-safe + - Fix a memory leak in GOption + + -- Sebastien Bacher Sat, 27 May 2006 12:54:17 +0200 + +glib2.0 (2.10.2-2) unstable; urgency=low + + * debian/control.in, debian/rules: + - patch by Frans Pop + - Add support for udeb dependency resolution in shlibs file + (Closes: #361697). + - Simplify debian/rules by making use of udeb support in debhelper. + * debian/control.in: + - clarify the description for the -data package (Closes: #362316), + change suggested Robert Bihlmeyer + + -- Sebastien Bacher Fri, 28 Apr 2006 00:03:41 +0200 + +glib2.0 (2.10.2-1) unstable; urgency=low + + * New upstream version: + - Missing check for .dylib + - Segmentation Fault when %llu is passed to vasnprintf and HAVE_SNPRINTF + is not defined + - Add support for write FDs to GIOChannel + - Memleak in goption.c::parse_short_option + - g_parse_debug_string reads beyond buffer + - g_option_context_parse() should not set program name to '' if + it is already set + - g_main_context_unref calls g_source_destroy_internal with incorrect + arguments + - Slight performance gains (GList, GAsyncQueue) + - Use of unitialised memory in g_mem_profile + - make check FAIL: threadpool-test + - g_option_context_new parameter lacks better explanation + - Some breakages with GThreadPool + - gthread/gthread-win32.c: IsDebuggerPresent needs + '#define _WIN32_WINDOWS 0x0401' + - dlerror() portability issue causes crash on (old) a.out NetBSD platform + - g_timer_elapsed docs should mention that microseconds may be NULL + - goption + error out params + - Documentation should not reference G_HAVE_GINT64, as it's deprecated. + * debian/patches/010_glib2.0.kfreebsd-amd64.patch: + - patch by Aurelien Jarno , fix build on kfreebsd-amd64 + (Closes: #355953) + * debian/rules: + - use "-g" for CFLAGS, makes -dbg package useful again + change by Fabio M. Di Nitto on the Ubuntu package: + * Make sure to pass CFLAGS to configure. + * Generalize DEB_BUILD_ARCH. + + -- Sebastien Bacher Fri, 7 Apr 2006 23:23:14 +0200 + +glib2.0 (2.10.1-2) unstable; urgency=low + + [ Sjoerd Simons ] + * Upload to unstable + * Document udeb changes that Josselin did in an earlier experimental + package. + * debian/patches/999_ia64_atomic_ops_broken.patch + + Added. Uses atomic builtins that gcc-4.0 know on ia64, instead of those + for gcc-4.1. (Patch by LaMont Jones from the ubuntu package) + * Updated debian/watch to use download.gnome.org + + [ Josselin Mouette ] + * Set the conflict with pango < 1.11, that's where the breakage lies. + * Add a XC-Package-Type header to the udeb and set the priority to extra. + [debian/control.in] + + -- Sjoerd Simons Sun, 19 Mar 2006 12:41:21 +0100 + +glib2.0 (2.10.1-1) experimental; urgency=low + + * New upstream release (bugfixes, translation updates). + * [debian/rules] Bring priority parameter for dpkg-distaddfile for the udeb + in line with control.in . + + Josselin Mouette : + * Conflict with pango < 1.10 to avoid breakage caused by the unicode + changes. + + -- J.H.M. Dassen (Ray) Sat, 11 Mar 2006 13:53:16 +0100 + +glib2.0 (2.10.0-1) experimental; urgency=low + + * New upstream release. + + -- Josselin Mouette Mon, 6 Mar 2006 00:32:27 +0100 + +glib2.0 (2.8.6-1) unstable; urgency=medium + + * New upstream release (bugfixes, translation updates). + + -- J.H.M. Dassen (Ray) Wed, 18 Jan 2006 20:30:26 +0100 + +glib2.0 (2.8.5-1) unstable; urgency=low + + * New upstream release (bugfixes, translation updates, + g_object_compat_control() added). + * [debian/rules] Bumped shver to 2.8.5 to reflect the API change. + + -- J.H.M. Dassen (Ray) Thu, 5 Jan 2006 21:22:36 +0100 + +glib2.0 (2.8.4-2) unstable; urgency=high + + * Fix shlibs deps that crept in the amd64 package, thanks Kurt Roeckx for + all the fish. (Closes: #339685) + - Cleanup and clarify upstream version calculations. + - Drop dh_makeshlibs -a call as only one package ships shlibs and already + has a separate call. + - Drop useless shlibs.local generation. + - Call dh_shlibdeps with cleaner arguments. + [debian/rules] + * Fix "fakeroot debian/rules clean" by following find calls with a .svn + filter. + [debian/scripts/lib] + * Fix quoting of unfix.source.patch:START and FAILED messages. + [debian/scripts/messages] + * Clarify Copyright versus License and update upstream URL. + [debian/copyright] + + -- Loic Minier Sun, 20 Nov 2005 10:36:26 +0100 + +glib2.0 (2.8.4-1) unstable; urgency=low + + * New upstream version. + + -- Sebastien Bacher Tue, 15 Nov 2005 16:22:08 +0100 + +glib2.0 (2.8.3-1) unstable; urgency=medium + + * New upstream release (fix an error that crept in with a change to + glib-mkenums in 2.8.2, documentation improvements, translation updates). + + -- J.H.M. Dassen (Ray) Mon, 3 Oct 2005 20:52:26 +0200 + +glib2.0 (2.8.2-1) unstable; urgency=medium + + * New upstream release (bug fixes, documentation improvements, translation + updates). + + -- J.H.M. Dassen (Ray) Sun, 2 Oct 2005 09:31:27 +0200 + +glib2.0 (2.8.1-1) unstable; urgency=medium + + * New (for Debian) upstream version (bug fixes, documentation improvements, + translation updates). + * [debian/control.in] Bumped Standards-Version. + * [debian/copyright] Updated FSF's address. + + -- J.H.M. Dassen (Ray) Sat, 24 Sep 2005 13:45:47 +0200 + +glib2.0 (2.8.1-0ubuntu1) breezy; urgency=low + + * New upstream version. + * debian/watch: + - updated. + + -- Sebastien Bacher Tue, 23 Aug 2005 12:05:20 +0200 + +glib2.0 (2.8.0-1) unstable; urgency=low + + * New upstream version. + * debian/rules: + - updated the shlibs. + + -- Sebastien Bacher Sat, 13 Aug 2005 14:14:00 +0200 + +glib2.0 (2.7.3-1) experimental; urgency=low + + * New upstream version. + + -- Sebastien Bacher Fri, 15 Jul 2005 23:42:37 +0200 + +glib2.0 (2.7.2-1) experimental; urgency=low + + * New upstream version. + + -- Sebastien Bacher Fri, 8 Jul 2005 22:07:59 +0200 + +glib2.0 (2.7.1-1) experimental; urgency=low + + * New upstream version. + * debian/rules: + - updated the shlib. + + -- Sebastien Bacher Fri, 1 Jul 2005 19:43:05 +0200 + +glib2.0 (2.7.0-1) experimental; urgency=low + + * New upstream version: + * GKeyFile: + - add unit tests. + - accept \r\n as line end. + - don't interpret leading zeros as octal numbers. + - make key and group removal work. + * GOption: + - improve formatting of --help output. + - accept -?. + - warn about duplicate main groups. + - treat '-' as non-option argument. + - report missing arguments as errors. + - add a boxed type for GDate. + * GTree: + - g_tree_remove() and g_tree_steal() return status information. + * Stdio wrappers: + - work regardless of large file support. + - add g_access(), g_chmod(), g_creat(), g_chdir. + * GObject: + - implement "toggle references" to help language bindings. + - allow to mark names, nicks and blurbs of pspecs as static. + - make pspec lookup a bit faster. + * add g_listenv() to list all set environment variables. + * add g_file_set_contents() to atomically write a file. + * add g_try_malloc(), g_try_new(), g_try_new0() and g_try_renew(). + * add g_utf8_collate_key_for_filename() to sort filenames taking + extensions and numeric suffixes into account. + * add G_GNUC_NULL_TERMINATED to mark varargs function with + NULL-terminated argument lists. + * documentation improvements. + * new and updated translations. + * debian/rules: + - updated the shlibs. + * debian/watch: + - updated. + + -- Sebastien Bacher Tue, 21 Jun 2005 12:15:47 +0200 + +glib2.0 (2.6.5-1) unstable; urgency=low + + * New upstream release again bringing a number of bugfixes, improved + documentation and updated translations, including + gthread-posix.c (g_thread_create_posix_impl): Allow setstacksize to + fail. (GNOME #304790, Michael Banck) (Closes: #312382) + * [debian/patches/000_glib-link.patch] Updated. + + -- J.H.M. Dassen (Ray) Fri, 10 Jun 2005 21:14:42 +0200 + +glib2.0 (2.6.4-1) unstable; urgency=low + + * New upstream release bringing a number of bugfixes, improved + documentation and updated translations. + + -- J.H.M. Dassen (Ray) Wed, 6 Apr 2005 22:16:44 +0200 + +glib2.0 (2.6.3-1) unstable; urgency=low + + * New upstream release. + + -- Sebastien Bacher Mon, 28 Feb 2005 09:38:38 +0100 + +glib2.0 (2.6.2-1) unstable; urgency=low + + * New upstream release. + + -- Sebastien Bacher Sat, 5 Feb 2005 19:23:59 +0100 + +glib2.0 (2.6.1-3) unstable; urgency=low + + * debian/rules: + - use "-plibglib$(apiver)-udeb", fix the libglib2.0-0-dbg package. + + -- Sebastien Bacher Sun, 23 Jan 2005 22:24:21 +0100 + +glib2.0 (2.6.1-2) unstable; urgency=low + + * Upload to unstable. + * debian/control.in: + - rename libglib2.0-dbg to libglib2.0-0-dbg. + - set myself as maintainer. + * debian/rules: + - use dh_strip to make the debug package. + + -- Sebastien Bacher Sun, 16 Jan 2005 12:59:21 +0100 + +glib2.0 (2.6.1-1) experimental; urgency=low + + * New upstream release. + + -- Sebastien Bacher Sat, 8 Jan 2005 14:44:05 +0100 + +glib2.0 (2.6.0-1) experimental; urgency=low + + * New upstream release. + * debian/rules: + - updated the shlibs. + * debian/watch: + - updated. + + -- Sebastien Bacher Mon, 27 Dec 2004 16:15:36 +0100 + +glib2.0 (2.4.8-1) unstable; urgency=medium + + * New upstream bugfix release. + + -- J.H.M. Dassen (Ray) Sat, 4 Dec 2004 18:52:44 +0100 + +glib2.0 (2.4.7-1) unstable; urgency=medium + + * New upstream bugfix release. + * [debian/patches/000_glib-link.patch] Updated. + * [debian/patches/001_translations.patch] Dropped. + + -- J.H.M. Dassen (Ray) Fri, 8 Oct 2004 22:27:49 +0200 + +glib2.0 (2.4.6-4) unstable; urgency=medium + + * [debian/patches/001_translations.patch] Updated translations from CVS and + relibtoolise to use new translations. + * [debian/rules] Fixed udeb naming on Hurd. + + -- J.H.M. Dassen (Ray) Fri, 8 Oct 2004 12:43:09 +0200 + +glib2.0 (2.4.6-3) unstable; urgency=medium + + Colin Watson : (Closes: #274053) + * [debian/rules] binary-arch depends on binary-arch-udeb. + * [debian/rules] Strip udeb! + + -- J.H.M. Dassen (Ray) Wed, 29 Sep 2004 19:39:22 +0200 + +glib2.0 (2.4.6-2) unstable; urgency=medium + + * [debian/patches/001_translations.patch] Updated translations from CVS. + * [debian/rules] Tightened "shver" to tighten shlibs, as some + incompatibilities with older versions turned up with gconf. + (Closes: #265659) + + -- J.H.M. Dassen (Ray) Tue, 24 Aug 2004 18:50:04 +0200 + +glib2.0 (2.4.6-1) unstable; urgency=medium + + * New upstream bugfix release. + + -- J.H.M. Dassen (Ray) Sun, 15 Aug 2004 18:34:27 +0200 + +glib2.0 (2.4.5-2) unstable; urgency=low + + * debian/patches/000_glib-link.patch: + - patch from Jurij Smakov to link with all the libs + (Closes: #263130). + + -- Sebastien Bacher Tue, 3 Aug 2004 18:03:53 +0200 + +glib2.0 (2.4.5-1) unstable; urgency=low + + * New upstream release. + + -- Sebastien Bacher Sun, 1 Aug 2004 17:31:43 +0200 + +glib2.0 (2.4.4-1) unstable; urgency=low + + * New upstream release. + - remove spaces before "#pragma alloca" (Closes: #250667). + + -- Sebastien Bacher Fri, 16 Jul 2004 18:44:31 +0200 + +glib2.0 (2.4.2-1) unstable; urgency=low + + * New upstream release. + + -- Sebastien Bacher Sat, 5 Jun 2004 00:51:01 +0200 + +glib2.0 (2.4.1-2) unstable; urgency=low + + * Upload in unstable. + * GNOME Team Upload. + * J.H.M. Dassen (Ray) : + + [debian/rules] Make the linker work a bit harder so dynamic loading can + be done faster; safety measure: ensure the build aborts when the library + still has references to undefined symbols. + + -- Sebastien Bacher Sat, 22 May 2004 14:18:23 +0200 + +glib2.0 (2.4.1-1) experimental; urgency=low + + * New upstream release. + * GNOME Team Upload. + * debian/rules: + - updated shlib version to 2.4.1. + + -- Sebastien Bacher Sun, 2 May 2004 12:47:25 +0200 + +glib2.0 (2.4.0-2) experimental; urgency=low + + * Akira TAGOH + - debian/rules: + - bumped shlib version to 2.4.0. + + -- Akira TAGOH Wed, 24 Mar 2004 09:12:31 +0900 + +glib2.0 (2.4.0-1) experimental; urgency=low + + * New upstream release. + * debian/rules: + - doh. don't claim the newer shlibs. + * debian/control: + - added Uploaders to maintain as team. + - added gnome-pkg-tools to Build-Depends. + * debian/docs: + - added old ChangeLog and NEWS files. + + -- Akira TAGOH Wed, 17 Mar 2004 21:18:00 +0900 + +glib2.0 (2.2.3-1) unstable; urgency=low + + * "Welcome back my laptop PC!" release. + * New upstream release. + * debian/control: + - bumped Standards-Version to 3.6.1.0. + + -- Akira TAGOH Mon, 1 Sep 2003 02:29:14 +0900 + +glib2.0 (2.2.2-1) unstable; urgency=low + + * New upstream release. + - Fix portability problems with G_MIN/MAX_INT64 (closes: Bug#195302) + * debian/control: + - bumped Standards-Version to 3.5.10.0. + - changed the sections for libglib2.0-dev and libglib2.0-dbg to libdevel. + * debian/compat: + - use it instead of DH_COMPAT. + + -- Akira TAGOH Tue, 10 Jun 2003 18:44:01 +0900 + +glib2.0 (2.2.1-3) unstable; urgency=low + + * debian/control: + - rename libglib2.0-0-udeb to libglib2.0-udeb. + - delete Recommends line from libglib2.0-udeb. (closes: Bug#183749) + - add Provides: libglib2.0-0 for libglib2.0-udeb. + * debian/libglib2.0-udeb.files: + - contain the libraries and locale data. + + -- Akira TAGOH Sat, 8 Mar 2003 02:46:19 +0900 + +glib2.0 (2.2.1-2) unstable; urgency=low + + * debian/rules: + - create the symlinks on /usr/share/gtk-doc/html. (closes: Bug#183504) + - changed DH_COMPAT to 4. + * debian/control: + - add libglib2.0-0-udeb package for debian-installer. + + -- Akira TAGOH Thu, 6 Mar 2003 01:14:44 +0900 + +glib2.0 (2.2.1-1) unstable; urgency=low + + * New upstream release. + * debian/control: + - needed pkg-config (>= 0.14.0). + - add autotools-dev to Build-Depends. + + -- Akira TAGOH Tue, 4 Feb 2003 01:02:20 +0900 + +glib2.0 (2.2.0-2) unstable; urgency=low + + * close to be fixed in the upstream release. (closes: Bug#173508) + + -- Akira TAGOH Tue, 7 Jan 2003 17:22:20 +0900 + +glib2.0 (2.2.0-1) unstable; urgency=low + + * New upstream release. + * debian/control: + bumped Standards-Version to 3.5.8. + + -- Akira TAGOH Wed, 25 Dec 2002 13:46:08 +0900 + +glib2.0 (2.0.7-1) unstable; urgency=low + + * New upstream release. + * debian/control: + - changed libc6-dev to libc6-dev | libc-dev in -dev's Depends. + - bumped Standards-Version and depends debhelper (>> 4). + - add libgtk2.0-doc to Suggests for -doc. + * debian/rules: + - add symlink to fix the missing symlink for gtk. but this release doesn't + include the hyperlink for gtk+ (closes: Bug#162845) + - support noopt option for DEB_BUILD_OPTIONS. + + -- Akira TAGOH Tue, 5 Nov 2002 17:06:50 +0900 + +glib2.0 (2.0.6-1) unstable; urgency=low + + * New upstream release. + * debian/rules: removed --enable-debug option. conform to the default value + now. (closes: Bug#151815) + * debian/patches/000_glib2.0-garray.patch: removed because it's merged by + the upstream. + + -- Akira TAGOH Sun, 4 Aug 2002 16:05:03 +0900 + +glib2.0 (2.0.4-3) unstable; urgency=low + + * debian/patches/000_glib2.0-garray.patch: + applied to fix g_ptr_array_index() macro. (closes: Bug#150521) + + -- Akira TAGOH Sat, 29 Jun 2002 19:46:51 +0900 + +glib2.0 (2.0.4-2) unstable; urgency=low + + * debian/libglib2.0-doc.doc-base.gobject: fix the dupplicated title. + (closes: Bug#150040) + + -- Akira TAGOH Sun, 16 Jun 2002 23:27:38 +0900 + +glib2.0 (2.0.4-1) unstable; urgency=low + + * New upstream release. + + -- Akira TAGOH Sun, 16 Jun 2002 03:33:22 +0900 + +glib2.0 (2.0.3-1) unstable; urgency=low + + * New upstream release. + + -- Akira TAGOH Wed, 29 May 2002 00:49:56 +0900 + +glib2.0 (2.0.1-2) unstable; urgency=low + + * debian/scripts/vars.build: fix bashism. + * debian/README.Debian: add static link issue. + * debian/rules: add --enable-static. (closes: Bug#142198) + + -- Akira TAGOH Thu, 11 Apr 2002 19:25:17 +0900 + +glib2.0 (2.0.1-1) unstable; urgency=low + + * New upstream release. + + -- Akira TAGOH Sat, 30 Mar 2002 16:23:54 +0900 + +glib2.0 (2.0.0-1) unstable; urgency=low + + * Initial Release. + + -- Akira TAGOH Tue, 12 Mar 2002 02:32:11 +0900 diff --git a/debian/clean b/debian/clean new file mode 100644 index 0000000..2cecdbc --- /dev/null +++ b/debian/clean @@ -0,0 +1,6 @@ +debian/cross.txt +debian/cross.txt.in +debian/libglib2.0-0.triggers +debian/libglib2.0-0.postinst +debian/libglib2.0-0.postrm +gio/gdbus-2.0/codegen/*.pyc diff --git a/debian/clean-up-unmanaged-libraries b/debian/clean-up-unmanaged-libraries new file mode 100755 index 0000000..9dec236 --- /dev/null +++ b/debian/clean-up-unmanaged-libraries @@ -0,0 +1,216 @@ +#!/bin/dash +# (This script requires either dash or bash due to its use of test -ef.) + +# Copyright 2020 Collabora Ltd. +# SPDX-License-Identifier: MIT +# (see "Expat" paragraph in debian/copyright) + +set -eu + +# global +bug_ref=911225 +force= +me="$0" +need_ldconfig= +really=yes +verbose= + +debug () { + [ -z "$verbose" ] || echo "DEBUG: $me: $*" >&2 +} + +warning () { + echo "WARNING: $me: $*" >&2 +} + +usage () { + local status="${1:-2}" + + if [ "$status" -gt 0 ]; then + exec >&2 + fi + + cat <&2 || : + + if [ -n "$really" ]; then + warning "Moving $impl into $removal" + install -d "$removal" + rm -f "$removal/${impl##*/}" + mv "$impl" "$removal/." + else + warning "Not moving $impl into $removal (--dry-run)" + fi + + echo >&2 + need_ldconfig=yes + done + + if [ -z "$found_one" ]; then + debug "No stray files found at /lib/$multiarch/$soname.*" + fi +} + +main () { + local getopt_temp + local multiarch + local soname + + getopt_temp="help" + getopt_temp="$getopt_temp,bug-ref:" + getopt_temp="$getopt_temp,dry-run" + getopt_temp="$getopt_temp,force" + getopt_temp="$getopt_temp,verbose" + + getopt_temp="$(getopt -o '' --long "$getopt_temp" -n "$me" -- "$@")" + eval "set -- $getopt_temp" + + while [ "$#" -gt 0 ] + do + case "$1" in + (--dry-run) + really= + verbose=yes + shift + ;; + + (--bug-ref) + bug_ref="$2" + shift 2 + ;; + + (--force) + force=yes + shift + ;; + + (--help) + usage 0 + ;; + + (--verbose) + verbose=yes + shift + ;; + + (--) + shift + break + ;; + + (-*) + warning "Unknown option: $1" + usage 2 + ;; + + (*) + break + ;; + esac + done + + if [ "$#" -lt 2 ]; then + warning "A multiarch tuple and at least one SONAME are required" + usage 2 + fi + + multiarch="$1" + shift + + if [ -n "$force" ]; then + debug "Using force" + elif [ "/usr/lib/$multiarch" -ef "/lib/$multiarch" ]; then + # On a merged-/usr system, a new library like libglib-2.0.so.0.5000.0 + # will take precedence over a stale library like + # libglib-2.0.so.0.4200.0 in the same directory without us needing + # to do anything, so the safe route is to avoid doing anything. + debug "Merged-/usr system, no need to do anything without --force" + return 0 + fi + + for soname in "$@"; do + do_soname "$multiarch" "$soname" + done + + if [ -n "$need_ldconfig" ] && [ -n "$really" ]; then + warning "Changes were made, running ldconfig..." + ldconfig || ldconfig --verbose + elif [ -n "$need_ldconfig" ]; then + debug "Would run ldconfig, but skipped due to --dry-run" + fi +} + +main "$@" + +# vim:set sw=4 sts=4 et: diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..b38d912 --- /dev/null +++ b/debian/control @@ -0,0 +1,208 @@ +# This file is autogenerated. DO NOT EDIT! +# +# Modifications should be made to debian/control.in instead. +# This file is regenerated automatically in the clean target. +Source: glib2.0 +Section: libs +Priority: optional +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian GNOME Maintainers +Uploaders: Iain Lane , Jeremy Bicha , Simon McVittie +Build-Depends: dbus , + debhelper-compat (= 13), + dh-sequence-python3, + dh-sequence-gnome, + docbook-xml, + docbook-xsl, + dpkg-dev (>= 1.17.14), + gettext, + libdbus-1-dev (>= 1.2.14) , + libelf-dev (>= 0.142), + libffi-dev (>= 3.3), + libgamin-dev [hurd-any] | libfam-dev [hurd-any], + libmount-dev (>= 2.35.2-7~) [linux-any], + libpcre3-dev (>= 1:8.35), + libselinux1-dev [linux-any], + libxml2-utils, + linux-libc-dev [linux-any], + meson (>= 0.52.0), + pkg-config (>= 0.16.0), + python3-distutils, + python3:any (>= 2.7.5-5~), + xsltproc, + zlib1g-dev +Build-Depends-Arch: desktop-file-utils , + locales | locales-all , + python3-dbus , + python3-gi , + shared-mime-info , + tzdata , + xterm +Build-Depends-Indep: gtk-doc-tools (>= 1.32.1), +Rules-Requires-Root: no +Standards-Version: 4.6.0 +Homepage: https://wiki.gnome.org/Projects/GLib +XS-Debian-Vcs-Browser: https://salsa.debian.org/gnome-team/glib +XS-Debian-Vcs-Git: https://salsa.debian.org/gnome-team/glib.git +Vcs-Browser: https://salsa.debian.org/gnome-team/glib/tree/ubuntu/jammy +Vcs-Git: https://salsa.debian.org/gnome-team/glib.git -b ubuntu/jammy + +Package: libglib2.0-0 +Architecture: any +Depends: ${misc:Depends}, + ${shlibs:Depends} +Recommends: libglib2.0-data, + shared-mime-info, + xdg-user-dirs +Breaks: gimp (<< 2.10.14-3~), + glib-networking-tests (<< 2.70.0~), + gnome-keyring (<< 40.0-3~), + libgio-fam (<< 2.64.1-2~) [kfreebsd-any hurd-any], + libgirepository-1.0-1 (<< 1.62.0-4~), + libgladeui-2-6 (<< 3.22.2), + libsoup2.4-tests (<< 2.72.0-3~), +Replaces: libgio-fam (<< 2.64.1-2~) [kfreebsd-any hurd-any] +Multi-Arch: same +Pre-Depends: ${misc:Pre-Depends} +Description: GLib library of C routines + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains the shared libraries. + +Package: libglib2.0-tests +Build-profiles: +Architecture: any +Depends: gir1.2-glib-2.0, + libglib2.0-dev-bin, + python3-dbus, + python3-dbusmock, + python3-gi, + shared-mime-info, + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends} +Recommends: xdg-desktop-portal, +Pre-Depends: ${misc:Pre-Depends} +Description: GLib library of C routines - installed tests + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains test programs, designed to be run as part of a + regression testsuite. + +Package: libglib2.0-udeb +Build-Profiles: +Section: debian-installer +Package-Type: udeb +Architecture: any +Depends: ${misc:Depends}, + ${shlibs:Depends} +Description: GLib library of C routines - minimal runtime + This is a udeb, or a microdeb, for the debian-installer. + . + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains the minimal runtime library needed by the Debian + installer. + +Package: libglib2.0-bin +Section: misc +Architecture: any +Pre-Depends: ${misc:Pre-Depends} +Depends: libglib2.0-data, + ${misc:Depends}, + ${shlibs:Depends} +Multi-Arch: foreign +Description: Programs for the GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains the program files which is used for the libraries + and others. + +Package: libglib2.0-dev +Section: libdevel +Architecture: any +Multi-Arch: same +Depends: libffi-dev (>= 3.3), + libglib2.0-0 (= ${binary:Version}), + libglib2.0-bin (= ${binary:Version}), + libglib2.0-dev-bin (= ${binary:Version}), + libmount-dev (>= 2.35.2-7~) [linux-any], + libpcre3-dev (>= 1:8.31), + libselinux1-dev [linux-any], + pkg-config, + zlib1g-dev, + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends} +Breaks: libglib2.0-0-dbg (<< 2.51.4-1~) +Replaces: libglib2.0-0-dbg (<< 2.51.4-1~) +Suggests: libgirepository1.0-dev (>= 1.62), + libglib2.0-doc +Description: Development files for the GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package is needed to compile programs against libglib2.0-0, + as only it includes the header files and static libraries (optionally) + needed for compiling. + . + GObject-Introspection metadata for this library can be found in the + libgirepository1.0-dev package. + +Package: libglib2.0-dev-bin +Section: libdevel +Architecture: any +Depends: python3-distutils, + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends} +Suggests: libgdk-pixbuf2.0-bin (>= 2.36.12-2~) | libgdk-pixbuf2.0-dev, + libxml2-utils +Breaks: libglib2.0-bin (<< 2.54.2-5~), + libglib2.0-dev (<< 2.53) +Replaces: libglib2.0-bin (<< 2.54.2-5~), + libglib2.0-dev (<< 2.53) +Multi-Arch: foreign +Description: Development utilities for the GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package is needed to compile programs against libglib2.0-0. It contains + development utilities typically run during compilation and should not be + installed directly. Use libglib2.0-dev instead. + +Package: libglib2.0-data +Architecture: all +Depends: ${misc:Depends} +Multi-Arch: foreign +Description: Common files for GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package is needed for the runtime libraries to display messages in + languages other than English. + +Package: libglib2.0-doc +Section: doc +Architecture: all +Depends: ${misc:Depends} +Suggests: devhelp +Multi-Arch: foreign +Description: Documentation files for the GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains the HTML documentation for the GLib library + in /usr/share/doc/libglib2.0-doc/ . diff --git a/debian/control.in b/debian/control.in new file mode 100644 index 0000000..758cf99 --- /dev/null +++ b/debian/control.in @@ -0,0 +1,204 @@ +Source: glib2.0 +Section: libs +Priority: optional +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian GNOME Maintainers +Uploaders: @GNOME_TEAM@, Simon McVittie +Build-Depends: dbus , + debhelper-compat (= 13), + dh-sequence-python3, + dh-sequence-gnome, + docbook-xml, + docbook-xsl, + dpkg-dev (>= 1.17.14), + gettext, + libdbus-1-dev (>= 1.2.14) , + libelf-dev (>= 0.142), + libffi-dev (>= 3.3), + libgamin-dev [hurd-any] | libfam-dev [hurd-any], + libmount-dev (>= 2.35.2-7~) [linux-any], + libpcre3-dev (>= 1:8.35), + libselinux1-dev [linux-any], + libxml2-utils, + linux-libc-dev [linux-any], + meson (>= 0.52.0), + pkg-config (>= 0.16.0), + python3-distutils, + python3:any (>= 2.7.5-5~), + xsltproc, + zlib1g-dev +Build-Depends-Arch: desktop-file-utils , + locales | locales-all , + python3-dbus , + python3-gi , + shared-mime-info , + tzdata , + xterm +Build-Depends-Indep: gtk-doc-tools (>= 1.32.1), +Rules-Requires-Root: no +Standards-Version: 4.6.0 +Homepage: https://wiki.gnome.org/Projects/GLib +XS-Debian-Vcs-Browser: https://salsa.debian.org/gnome-team/glib +XS-Debian-Vcs-Git: https://salsa.debian.org/gnome-team/glib.git +Vcs-Browser: https://salsa.debian.org/gnome-team/glib/tree/ubuntu/jammy +Vcs-Git: https://salsa.debian.org/gnome-team/glib.git -b ubuntu/jammy + +Package: libglib2.0-0 +Architecture: any +Depends: ${misc:Depends}, + ${shlibs:Depends} +Recommends: libglib2.0-data, + shared-mime-info, + xdg-user-dirs +Breaks: gimp (<< 2.10.14-3~), + glib-networking-tests (<< 2.70.0~), + gnome-keyring (<< 40.0-3~), + libgio-fam (<< 2.64.1-2~) [kfreebsd-any hurd-any], + libgirepository-1.0-1 (<< 1.62.0-4~), + libgladeui-2-6 (<< 3.22.2), + libsoup2.4-tests (<< 2.72.0-3~), +Replaces: libgio-fam (<< 2.64.1-2~) [kfreebsd-any hurd-any] +Multi-Arch: same +Pre-Depends: ${misc:Pre-Depends} +Description: GLib library of C routines + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains the shared libraries. + +Package: libglib2.0-tests +Build-profiles: +Architecture: any +Depends: gir1.2-glib-2.0, + libglib2.0-dev-bin, + python3-dbus, + python3-dbusmock, + python3-gi, + shared-mime-info, + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends} +Recommends: xdg-desktop-portal, +Pre-Depends: ${misc:Pre-Depends} +Description: GLib library of C routines - installed tests + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains test programs, designed to be run as part of a + regression testsuite. + +Package: libglib2.0-udeb +Build-Profiles: +Section: debian-installer +Package-Type: udeb +Architecture: any +Depends: ${misc:Depends}, + ${shlibs:Depends} +Description: GLib library of C routines - minimal runtime + This is a udeb, or a microdeb, for the debian-installer. + . + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains the minimal runtime library needed by the Debian + installer. + +Package: libglib2.0-bin +Section: misc +Architecture: any +Pre-Depends: ${misc:Pre-Depends} +Depends: libglib2.0-data, + ${misc:Depends}, + ${shlibs:Depends} +Multi-Arch: foreign +Description: Programs for the GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains the program files which is used for the libraries + and others. + +Package: libglib2.0-dev +Section: libdevel +Architecture: any +Multi-Arch: same +Depends: libffi-dev (>= 3.3), + libglib2.0-0 (= ${binary:Version}), + libglib2.0-bin (= ${binary:Version}), + libglib2.0-dev-bin (= ${binary:Version}), + libmount-dev (>= 2.35.2-7~) [linux-any], + libpcre3-dev (>= 1:8.31), + libselinux1-dev [linux-any], + pkg-config, + zlib1g-dev, + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends} +Breaks: libglib2.0-0-dbg (<< 2.51.4-1~) +Replaces: libglib2.0-0-dbg (<< 2.51.4-1~) +Suggests: libgirepository1.0-dev (>= 1.62), + libglib2.0-doc +Description: Development files for the GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package is needed to compile programs against libglib2.0-0, + as only it includes the header files and static libraries (optionally) + needed for compiling. + . + GObject-Introspection metadata for this library can be found in the + libgirepository1.0-dev package. + +Package: libglib2.0-dev-bin +Section: libdevel +Architecture: any +Depends: python3-distutils, + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends} +Suggests: libgdk-pixbuf2.0-bin (>= 2.36.12-2~) | libgdk-pixbuf2.0-dev, + libxml2-utils +Breaks: libglib2.0-bin (<< 2.54.2-5~), + libglib2.0-dev (<< 2.53) +Replaces: libglib2.0-bin (<< 2.54.2-5~), + libglib2.0-dev (<< 2.53) +Multi-Arch: foreign +Description: Development utilities for the GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package is needed to compile programs against libglib2.0-0. It contains + development utilities typically run during compilation and should not be + installed directly. Use libglib2.0-dev instead. + +Package: libglib2.0-data +Architecture: all +Depends: ${misc:Depends} +Multi-Arch: foreign +Description: Common files for GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package is needed for the runtime libraries to display messages in + languages other than English. + +Package: libglib2.0-doc +Section: doc +Architecture: all +Depends: ${misc:Depends} +Suggests: devhelp +Multi-Arch: foreign +Description: Documentation files for the GLib library + GLib is a library containing many useful C routines for things such + as trees, hashes, lists, and strings. It is a useful general-purpose + C library used by projects such as GTK+, GIMP, and GNOME. + . + This package contains the HTML documentation for the GLib library + in /usr/share/doc/libglib2.0-doc/ . diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..e9dffa1 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,107 @@ +This package was debianized by Akira TAGOH on +Thu, 7 Mar 2002 01:05:25 +0900. + +It was downloaded from . + +Original Authors +---------------- +Peter Mattis +Spencer Kimball +Josh MacDonald + +Please do not mail the original authors asking questions about this +version of GLib. + +GLib Team +--------- +Shawn T. Amundson +Jeff Garzik +Raja R Harinath +Tim Janik +Elliot Lee +Tor Lillqvist +Paolo Molaro +Havoc Pennington +Manish Singh +Owen Taylor +Sebastian Wilhelmi + +The random number generator "Mersenne Twister", which is used by GLib, +was developed and originally coded by: +Makoto Matsumoto +Takuji Nishimura + +Major copyright holders: + + Copyright © 1995-2021 Red Hat, Inc. + Copyright © 2008-2010 Novell, Inc. + Copyright © 2008-2010 Codethink Limited. + Copyright © 2008-2018 Collabora, Ltd. + Copyright © 2018 Endless Mobile, Inc. + Copyright © 2018 Emmanuele Bassi + +License: + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Debian systems, the complete text of the GNU Lesser General +Public License can be found in `/usr/share/common-licenses/LGPL'. + +Files: + gobject/tests/taptestrunner.py +Copyright: + 2015 Remko Tronçon +License: Expat + +Files: + tests/gen-casefold-txt.py + tests/gen-casemap-txt.py +Copyright: + 1998-1999 Tom Tromey + 2001 Red Hat Software +License: GPL-2+ + +License: Expat + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +License: GPL-2+ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program; if not, see . diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..8913f46 --- /dev/null +++ b/debian/docs @@ -0,0 +1,2 @@ +NEWS +README.md diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 0000000..38ea28e --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,18 @@ +[DEFAULT] +pristine-tar = True +debian-branch = ubuntu/jammy +debian-tag = ubuntu/%(version)s +upstream-branch = upstream/2.72.x + +[buildpackage] +sign-tags = True + +[dch] +multimaint-merge = True + +[import-orig] +postimport = dch -v%(version)s New upstream release; git add debian/changelog; debcommit +upstream-vcs-tag = %(version%~%.)s + +[pq] +patch-numbers = False diff --git a/debian/gio-launch-desktop b/debian/gio-launch-desktop new file mode 100755 index 0000000..9b949c3 --- /dev/null +++ b/debian/gio-launch-desktop @@ -0,0 +1,12 @@ +#!/bin/sh +# Fallback implementation of gio-launch-desktop. If we upgrade from a +# GLib version between 2.57.2 and 2.63.5, as long as that version is +# still loaded into some process, it requires this executable to launch +# .desktop files. +# +# This script will be removed after Ubuntu 20.04 and Debian 11 are released. +# Do not rely on it. + +set -eu +export GIO_LAUNCHED_DESKTOP_FILE_PID="$$" +exec "$@" diff --git a/debian/libglib2.0-0.dirs b/debian/libglib2.0-0.dirs new file mode 100644 index 0000000..0541661 --- /dev/null +++ b/debian/libglib2.0-0.dirs @@ -0,0 +1,2 @@ +/usr/lib/${DEB_HOST_MULTIARCH}/gio/modules +/usr/share/glib-2.0/schemas diff --git a/debian/libglib2.0-0.install b/debian/libglib2.0-0.install new file mode 100644 index 0000000..eb06f41 --- /dev/null +++ b/debian/libglib2.0-0.install @@ -0,0 +1,7 @@ +usr/lib/*/libglib*.so.* +usr/lib/*/libgobject*.so.* +usr/lib/*/libgmodule*.so.* +usr/lib/*/libgthread*.so.* +usr/lib/*/libgio*.so.* +usr/bin/gio-querymodules usr/lib/${DEB_HOST_MULTIARCH}/glib-2.0 +usr/bin/glib-compile-schemas usr/lib/${DEB_HOST_MULTIARCH}/glib-2.0 diff --git a/debian/libglib2.0-0.lintian-overrides b/debian/libglib2.0-0.lintian-overrides new file mode 100644 index 0000000..71438d8 --- /dev/null +++ b/debian/libglib2.0-0.lintian-overrides @@ -0,0 +1,7 @@ +# GObject uses GLib functions instead of using libc directly +libglib2.0-0: hardening-no-fortify-functions [usr/lib/*/libgobject-2.0.so.*] +# It's a deliberate choice of bundling them together +libglib2.0-0: package-name-doesnt-match-sonames libgio-2.0-0 libglib-2.0-0 libgmodule-2.0-0 libgobject-2.0-0 libgthread-2.0-0 +# These empty directories are deliberate. +libglib2.0-0: package-contains-empty-directory usr/lib/*/gio/modules/ +libglib2.0-0: package-contains-empty-directory usr/share/glib-2.0/schemas/ diff --git a/debian/libglib2.0-0.postinst.in b/debian/libglib2.0-0.postinst.in new file mode 100644 index 0000000..231ca3e --- /dev/null +++ b/debian/libglib2.0-0.postinst.in @@ -0,0 +1,68 @@ +#!/bin/sh +set -e + + +handle_triggers () { + local trigger + local dirs + + for trigger in "$@"; do + if ! [ -d $trigger ]; then + continue + fi + case $trigger in + /usr/share/glib-2.0/schemas) + # This is triggered everytime an application installs a + # GSettings schema + "/usr/lib/#MULTIARCH#/glib-2.0/glib-compile-schemas" /usr/share/glib-2.0/schemas || true + ;; + + "/usr/lib/#MULTIARCH#/gio/modules") + # This is triggered everytime an application installs a GIO + # module into /usr/lib/#MULTIARCH#/gio/modules + + "/usr/lib/#MULTIARCH#/glib-2.0/gio-querymodules" "/usr/lib/#MULTIARCH#/gio/modules" || true + ;; + esac + done +} + +cleanup () { + /usr/share/glib-2.0/clean-up-unmanaged-libraries \ + --bug-ref=896019 \ + "$@" \ + "#MULTIARCH#" \ + libglib-2.0.so.0 +} + +if [ "$1" = triggered ]; then + handle_triggers $2 + exit 0 +fi + +# Clean up stale shared libraries on upgrades if necessary. Do this before running +# glib-compile-schemas, gio-querymodules. +# This workaround can be removed after Ubuntu 22.04 is released. +if [ -n "$2" ] && ! cleanup; then + echo "$0: Trying cleanup again with more logging..." + cleanup --verbose +fi + +#DEBHELPER# + +# This is shipped in the .deb (see debian/libglib2.0-0.dirs) but would +# be removed if empty during upgrade by old versions of the postrm (#987913). +# This workaround can be removed after Ubuntu 22.04 is released. +install -d "/usr/lib/#MULTIARCH#/gio/modules" + +"/usr/lib/#MULTIARCH#/glib-2.0/glib-compile-schemas" /usr/share/glib-2.0/schemas || true +"/usr/lib/#MULTIARCH#/glib-2.0/gio-querymodules" "/usr/lib/#MULTIARCH#/gio/modules" || true + +# Clean up pre-multiarch giomodule.cache. +# This workaround can be removed after Debian 12 and Ubuntu 22.04 are released. +if [ -d /usr/lib/gio/modules ]; then + rm -f /usr/lib/gio/modules/giomodule.cache + rmdir -p --ignore-fail-on-non-empty /usr/lib/gio/modules +fi + +# vim:set sw=4 sts=4 et: diff --git a/debian/libglib2.0-0.postrm.in b/debian/libglib2.0-0.postrm.in new file mode 100644 index 0000000..c9d5cc0 --- /dev/null +++ b/debian/libglib2.0-0.postrm.in @@ -0,0 +1,21 @@ +#! /bin/sh +set -e + +#DEBHELPER# + +case "$1" in + (remove|purge) + if [ -d /usr/lib/#MULTIARCH#/gio/modules ]; then + # Purge the cache + rm -f /usr/lib/#MULTIARCH#/gio/modules/giomodule.cache + rmdir -p --ignore-fail-on-non-empty /usr/lib/#MULTIARCH#/gio/modules + fi + ;; +esac + +if [ "$1" = purge ] && [ -d /usr/share/glib-2.0/schemas ] && [ "$DPKG_MAINTSCRIPT_PACKAGE_REFCOUNT" = 1 ]; then + # This is the last multiarch variant to be removed, so drop the + # architecture-independent compiled schemas + rm -f /usr/share/glib-2.0/schemas/gschemas.compiled + rmdir -p --ignore-fail-on-non-empty /usr/share/glib-2.0/schemas +fi diff --git a/debian/libglib2.0-0.symbols b/debian/libglib2.0-0.symbols new file mode 100644 index 0000000..268f89c --- /dev/null +++ b/debian/libglib2.0-0.symbols @@ -0,0 +1,4381 @@ +libgio-2.0.so.0 libglib2.0-0 #MINVER# +* Build-Depends-Package: libglib2.0-dev + g_action_activate@Base 2.28.0 + g_action_change_state@Base 2.30.0 + g_action_get_enabled@Base 2.28.0 + g_action_get_name@Base 2.28.0 + g_action_get_parameter_type@Base 2.28.0 + g_action_get_state@Base 2.28.0 + g_action_get_state_hint@Base 2.28.0 + g_action_get_state_type@Base 2.28.0 + g_action_get_type@Base 2.28.0 + g_action_group_action_added@Base 2.28.0 + g_action_group_action_enabled_changed@Base 2.28.0 + g_action_group_action_removed@Base 2.28.0 + g_action_group_action_state_changed@Base 2.28.0 + g_action_group_activate_action@Base 2.28.0 + g_action_group_change_action_state@Base 2.28.0 + g_action_group_get_action_enabled@Base 2.28.0 + g_action_group_get_action_parameter_type@Base 2.28.0 + g_action_group_get_action_state@Base 2.28.0 + g_action_group_get_action_state_hint@Base 2.28.0 + g_action_group_get_action_state_type@Base 2.28.0 + g_action_group_get_type@Base 2.28.0 + g_action_group_has_action@Base 2.28.0 + g_action_group_list_actions@Base 2.28.0 + g_action_group_query_action@Base 2.31.8 + g_action_map_add_action@Base 2.31.8 + g_action_map_add_action_entries@Base 2.31.8 + g_action_map_get_type@Base 2.31.8 + g_action_map_lookup_action@Base 2.31.8 + g_action_map_remove_action@Base 2.31.8 + g_action_name_is_valid@Base 2.37.5 + g_action_parse_detailed_name@Base 2.37.0 + g_action_print_detailed_name@Base 2.37.5 + g_app_info_add_supports_type@Base 2.16.0 + g_app_info_can_delete@Base 2.20.0 + g_app_info_can_remove_supports_type@Base 2.16.0 + g_app_info_create_flags_get_type@Base 2.16.0 + g_app_info_create_from_commandline@Base 2.16.0 + g_app_info_delete@Base 2.20.0 + g_app_info_dup@Base 2.16.0 + g_app_info_equal@Base 2.16.0 + g_app_info_get_all@Base 2.16.0 + g_app_info_get_all_for_type@Base 2.16.0 + g_app_info_get_commandline@Base 2.20.0 + g_app_info_get_default_for_type@Base 2.16.0 + g_app_info_get_default_for_uri_scheme@Base 2.16.0 + g_app_info_get_description@Base 2.16.0 + g_app_info_get_display_name@Base 2.24.0 + g_app_info_get_executable@Base 2.16.0 + g_app_info_get_fallback_for_type@Base 2.28.0 + g_app_info_get_icon@Base 2.16.0 + g_app_info_get_id@Base 2.16.0 + g_app_info_get_name@Base 2.16.0 + g_app_info_get_recommended_for_type@Base 2.28.0 + g_app_info_get_supported_types@Base 2.33.14 + g_app_info_get_type@Base 2.16.0 + g_app_info_launch@Base 2.16.0 + g_app_info_launch_default_for_uri@Base 2.16.0 + g_app_info_launch_default_for_uri_async@Base 2.49.5 + g_app_info_launch_default_for_uri_finish@Base 2.49.5 + g_app_info_launch_uris@Base 2.16.0 + g_app_info_launch_uris_async@Base 2.59.2 + g_app_info_launch_uris_finish@Base 2.59.2 + g_app_info_monitor_get@Base 2.39.4 + g_app_info_monitor_get_type@Base 2.39.4 + g_app_info_remove_supports_type@Base 2.16.0 + g_app_info_reset_type_associations@Base 2.20.0 + g_app_info_set_as_default_for_extension@Base 2.16.0 + g_app_info_set_as_default_for_type@Base 2.16.0 + g_app_info_set_as_last_used_for_type@Base 2.28.0 + g_app_info_should_show@Base 2.16.0 + g_app_info_supports_files@Base 2.16.0 + g_app_info_supports_uris@Base 2.16.0 + g_app_launch_context_get_display@Base 2.16.0 + g_app_launch_context_get_environment@Base 2.31.8 + g_app_launch_context_get_startup_notify_id@Base 2.16.0 + g_app_launch_context_get_type@Base 2.16.0 + g_app_launch_context_launch_failed@Base 2.16.0 + g_app_launch_context_new@Base 2.16.0 + g_app_launch_context_setenv@Base 2.31.8 + g_app_launch_context_unsetenv@Base 2.31.8 + g_application_activate@Base 2.28.0 + g_application_add_main_option@Base 2.41.4 + g_application_add_main_option_entries@Base 2.39.90 + g_application_add_option_group@Base 2.39.90 + g_application_bind_busy_property@Base 2.43.90 + g_application_command_line_create_file_for_arg@Base 2.35.8 + g_application_command_line_get_arguments@Base 2.28.0 + g_application_command_line_get_cwd@Base 2.28.0 + g_application_command_line_get_environ@Base 2.28.0 + g_application_command_line_get_exit_status@Base 2.28.0 + g_application_command_line_get_is_remote@Base 2.28.0 + g_application_command_line_get_options_dict@Base 2.39.90 + g_application_command_line_get_platform_data@Base 2.28.0 + g_application_command_line_get_stdin@Base 2.35.8 + g_application_command_line_get_type@Base 2.28.0 + g_application_command_line_getenv@Base 2.28.0 + g_application_command_line_print@Base 2.28.0 + g_application_command_line_printerr@Base 2.28.0 + g_application_command_line_set_exit_status@Base 2.28.0 + g_application_flags_get_type@Base 2.28.0 + g_application_get_application_id@Base 2.28.0 + g_application_get_dbus_connection@Base 2.33.14 + g_application_get_dbus_object_path@Base 2.33.14 + g_application_get_default@Base 2.31.8 + g_application_get_flags@Base 2.28.0 + g_application_get_inactivity_timeout@Base 2.28.0 + g_application_get_is_busy@Base 2.43.91 + g_application_get_is_registered@Base 2.28.0 + g_application_get_is_remote@Base 2.28.0 + g_application_get_resource_base_path@Base 2.41.2 + g_application_get_type@Base 2.28.0 + g_application_hold@Base 2.28.0 + g_application_id_is_valid@Base 2.28.0 + g_application_mark_busy@Base 2.37.0 + g_application_new@Base 2.28.0 + g_application_open@Base 2.28.0 + g_application_quit@Base 2.31.18 + g_application_register@Base 2.28.0 + g_application_release@Base 2.28.0 + g_application_run@Base 2.28.0 + g_application_send_notification@Base 2.39.4 + g_application_set_action_group@Base 2.28.0 + g_application_set_application_id@Base 2.28.0 + g_application_set_default@Base 2.31.8 + g_application_set_flags@Base 2.28.0 + g_application_set_inactivity_timeout@Base 2.28.0 + g_application_set_option_context_description@Base 2.55.1 + g_application_set_option_context_parameter_string@Base 2.55.1 + g_application_set_option_context_summary@Base 2.55.1 + g_application_set_resource_base_path@Base 2.41.2 + g_application_unbind_busy_property@Base 2.43.91 + g_application_unmark_busy@Base 2.37.0 + g_application_withdraw_notification@Base 2.39.4 + g_ask_password_flags_get_type@Base 2.16.0 + g_async_initable_get_type@Base 2.22.0 + g_async_initable_init_async@Base 2.22.0 + g_async_initable_init_finish@Base 2.22.0 + g_async_initable_new_async@Base 2.22.0 + g_async_initable_new_finish@Base 2.22.0 + g_async_initable_new_valist_async@Base 2.22.0 + g_async_initable_newv_async@Base 2.22.0 + g_async_result_get_source_object@Base 2.16.0 + g_async_result_get_type@Base 2.16.0 + g_async_result_get_user_data@Base 2.16.0 + g_async_result_is_tagged@Base 2.33.14 + g_async_result_legacy_propagate_error@Base 2.33.14 + g_buffered_input_stream_fill@Base 2.16.0 + g_buffered_input_stream_fill_async@Base 2.16.0 + g_buffered_input_stream_fill_finish@Base 2.16.0 + g_buffered_input_stream_get_available@Base 2.16.0 + g_buffered_input_stream_get_buffer_size@Base 2.16.0 + g_buffered_input_stream_get_type@Base 2.16.0 + g_buffered_input_stream_new@Base 2.16.0 + g_buffered_input_stream_new_sized@Base 2.16.0 + g_buffered_input_stream_peek@Base 2.16.0 + g_buffered_input_stream_peek_buffer@Base 2.16.0 + g_buffered_input_stream_read_byte@Base 2.16.0 + g_buffered_input_stream_set_buffer_size@Base 2.16.0 + g_buffered_output_stream_get_auto_grow@Base 2.16.0 + g_buffered_output_stream_get_buffer_size@Base 2.16.0 + g_buffered_output_stream_get_type@Base 2.16.0 + g_buffered_output_stream_new@Base 2.16.0 + g_buffered_output_stream_new_sized@Base 2.16.0 + g_buffered_output_stream_set_auto_grow@Base 2.16.0 + g_buffered_output_stream_set_buffer_size@Base 2.16.0 + g_bus_get@Base 2.26.0 + g_bus_get_finish@Base 2.26.0 + g_bus_get_sync@Base 2.26.0 + g_bus_name_owner_flags_get_type@Base 2.26.0 + g_bus_name_watcher_flags_get_type@Base 2.26.0 + g_bus_own_name@Base 2.26.0 + g_bus_own_name_on_connection@Base 2.26.0 + g_bus_own_name_on_connection_with_closures@Base 2.26.0 + g_bus_own_name_with_closures@Base 2.26.0 + g_bus_type_get_type@Base 2.26.0 + g_bus_unown_name@Base 2.26.0 + g_bus_unwatch_name@Base 2.26.0 + g_bus_watch_name@Base 2.26.0 + g_bus_watch_name_on_connection@Base 2.26.0 + g_bus_watch_name_on_connection_with_closures@Base 2.26.0 + g_bus_watch_name_with_closures@Base 2.26.0 + g_bytes_icon_get_bytes@Base 2.37.0 + g_bytes_icon_get_type@Base 2.37.0 + g_bytes_icon_new@Base 2.37.0 + g_cancellable_cancel@Base 2.16.0 + g_cancellable_connect@Base 2.22.0 + g_cancellable_disconnect@Base 2.22.0 + g_cancellable_get_current@Base 2.16.0 + g_cancellable_get_fd@Base 2.16.0 + g_cancellable_get_type@Base 2.16.0 + g_cancellable_is_cancelled@Base 2.16.0 + g_cancellable_make_pollfd@Base 2.22.0 + g_cancellable_new@Base 2.16.0 + g_cancellable_pop_current@Base 2.16.0 + g_cancellable_push_current@Base 2.16.0 + g_cancellable_release_fd@Base 2.22.0 + g_cancellable_reset@Base 2.16.0 + g_cancellable_set_error_if_cancelled@Base 2.16.0 + g_cancellable_source_new@Base 2.28.0 + g_charset_converter_get_num_fallbacks@Base 2.24.0 + g_charset_converter_get_type@Base 2.24.0 + g_charset_converter_get_use_fallback@Base 2.24.0 + g_charset_converter_new@Base 2.24.0 + g_charset_converter_set_use_fallback@Base 2.24.0 + g_content_type_can_be_executable@Base 2.16.0 + g_content_type_equals@Base 2.16.0 + g_content_type_from_mime_type@Base 2.18.0 + g_content_type_get_description@Base 2.16.0 + g_content_type_get_generic_icon_name@Base 2.33.14 + g_content_type_get_icon@Base 2.16.0 + g_content_type_get_mime_dirs@Base 2.59.0 + g_content_type_get_mime_type@Base 2.16.0 + g_content_type_get_symbolic_icon@Base 2.33.14 + g_content_type_guess@Base 2.16.0 + g_content_type_guess_for_tree@Base 2.18.0 + g_content_type_is_a@Base 2.16.0 + g_content_type_is_mime_type@Base 2.51.5 + g_content_type_is_unknown@Base 2.16.0 + g_content_type_set_mime_dirs@Base 2.59.0 + g_content_types_get_registered@Base 2.16.0 + g_converter_convert@Base 2.24.0 + g_converter_flags_get_type@Base 2.24.0 + g_converter_get_type@Base 2.24.0 + g_converter_input_stream_get_converter@Base 2.24.0 + g_converter_input_stream_get_type@Base 2.24.0 + g_converter_input_stream_new@Base 2.24.0 + g_converter_output_stream_get_converter@Base 2.24.0 + g_converter_output_stream_get_type@Base 2.24.0 + g_converter_output_stream_new@Base 2.24.0 + g_converter_reset@Base 2.24.0 + g_converter_result_get_type@Base 2.24.0 + g_credentials_get_native@Base 2.26.0 + g_credentials_get_type@Base 2.26.0 + g_credentials_get_unix_pid@Base 2.35.8 + g_credentials_get_unix_user@Base 2.26.0 + g_credentials_is_same_user@Base 2.26.0 + g_credentials_new@Base 2.26.0 + g_credentials_set_native@Base 2.26.0 + g_credentials_set_unix_user@Base 2.26.0 + g_credentials_to_string@Base 2.26.0 + g_credentials_type_get_type@Base 2.26.0 + g_data_input_stream_get_byte_order@Base 2.16.0 + g_data_input_stream_get_newline_type@Base 2.16.0 + g_data_input_stream_get_type@Base 2.16.0 + g_data_input_stream_new@Base 2.16.0 + g_data_input_stream_read_byte@Base 2.16.0 + g_data_input_stream_read_int16@Base 2.16.0 + g_data_input_stream_read_int32@Base 2.16.0 + g_data_input_stream_read_int64@Base 2.16.0 + g_data_input_stream_read_line@Base 2.16.0 + g_data_input_stream_read_line_async@Base 2.20.0 + g_data_input_stream_read_line_finish@Base 2.20.0 + g_data_input_stream_read_line_finish_utf8@Base 2.30.0 + g_data_input_stream_read_line_utf8@Base 2.30.0 + g_data_input_stream_read_uint16@Base 2.16.0 + g_data_input_stream_read_uint32@Base 2.16.0 + g_data_input_stream_read_uint64@Base 2.16.0 + g_data_input_stream_read_until@Base 2.16.0 + g_data_input_stream_read_until_async@Base 2.20.0 + g_data_input_stream_read_until_finish@Base 2.20.0 + g_data_input_stream_read_upto@Base 2.26.0 + g_data_input_stream_read_upto_async@Base 2.26.0 + g_data_input_stream_read_upto_finish@Base 2.26.0 + g_data_input_stream_set_byte_order@Base 2.16.0 + g_data_input_stream_set_newline_type@Base 2.16.0 + g_data_output_stream_get_byte_order@Base 2.16.0 + g_data_output_stream_get_type@Base 2.16.0 + g_data_output_stream_new@Base 2.16.0 + g_data_output_stream_put_byte@Base 2.16.0 + g_data_output_stream_put_int16@Base 2.16.0 + g_data_output_stream_put_int32@Base 2.16.0 + g_data_output_stream_put_int64@Base 2.16.0 + g_data_output_stream_put_string@Base 2.16.0 + g_data_output_stream_put_uint16@Base 2.16.0 + g_data_output_stream_put_uint32@Base 2.16.0 + g_data_output_stream_put_uint64@Base 2.16.0 + g_data_output_stream_set_byte_order@Base 2.16.0 + g_data_stream_byte_order_get_type@Base 2.16.0 + g_data_stream_newline_type_get_type@Base 2.16.0 + g_datagram_based_condition_check@Base 2.47.1 + g_datagram_based_condition_wait@Base 2.47.1 + g_datagram_based_create_source@Base 2.47.1 + g_datagram_based_get_type@Base 2.47.1 + g_datagram_based_receive_messages@Base 2.47.1 + g_datagram_based_send_messages@Base 2.47.1 + g_dbus_action_group_get@Base 2.31.8 + g_dbus_action_group_get_type@Base 2.31.8 + g_dbus_address_escape_value@Base 2.35.8 + g_dbus_address_get_for_bus_sync@Base 2.26.0 + g_dbus_address_get_stream@Base 2.26.0 + g_dbus_address_get_stream_finish@Base 2.26.0 + g_dbus_address_get_stream_sync@Base 2.26.0 + g_dbus_annotation_info_get_type@Base 2.26.0 + g_dbus_annotation_info_lookup@Base 2.26.0 + g_dbus_annotation_info_ref@Base 2.26.0 + g_dbus_annotation_info_unref@Base 2.26.0 + g_dbus_arg_info_get_type@Base 2.26.0 + g_dbus_arg_info_ref@Base 2.26.0 + g_dbus_arg_info_unref@Base 2.26.0 + g_dbus_auth_observer_allow_mechanism@Base 2.33.14 + g_dbus_auth_observer_authorize_authenticated_peer@Base 2.26.0 + g_dbus_auth_observer_get_type@Base 2.26.0 + g_dbus_auth_observer_new@Base 2.26.0 + g_dbus_call_flags_get_type@Base 2.26.0 + g_dbus_capability_flags_get_type@Base 2.26.0 + g_dbus_connection_add_filter@Base 2.26.0 + g_dbus_connection_call@Base 2.26.0 + g_dbus_connection_call_finish@Base 2.26.0 + g_dbus_connection_call_sync@Base 2.26.0 + g_dbus_connection_call_with_unix_fd_list@Base 2.30.0 + g_dbus_connection_call_with_unix_fd_list_finish@Base 2.30.0 + g_dbus_connection_call_with_unix_fd_list_sync@Base 2.30.0 + g_dbus_connection_close@Base 2.26.0 + g_dbus_connection_close_finish@Base 2.26.0 + g_dbus_connection_close_sync@Base 2.26.0 + g_dbus_connection_emit_signal@Base 2.26.0 + g_dbus_connection_export_action_group@Base 2.31.8 + g_dbus_connection_export_menu_model@Base 2.31.8 + g_dbus_connection_flags_get_type@Base 2.26.0 + g_dbus_connection_flush@Base 2.26.0 + g_dbus_connection_flush_finish@Base 2.26.0 + g_dbus_connection_flush_sync@Base 2.26.0 + g_dbus_connection_get_capabilities@Base 2.26.0 + g_dbus_connection_get_exit_on_close@Base 2.26.0 + g_dbus_connection_get_flags@Base 2.59.0 + g_dbus_connection_get_guid@Base 2.26.0 + g_dbus_connection_get_last_serial@Base 2.33.14 + g_dbus_connection_get_peer_credentials@Base 2.26.0 + g_dbus_connection_get_stream@Base 2.26.0 + g_dbus_connection_get_type@Base 2.26.0 + g_dbus_connection_get_unique_name@Base 2.26.0 + g_dbus_connection_is_closed@Base 2.26.0 + g_dbus_connection_new@Base 2.26.0 + g_dbus_connection_new_finish@Base 2.26.0 + g_dbus_connection_new_for_address@Base 2.26.0 + g_dbus_connection_new_for_address_finish@Base 2.26.0 + g_dbus_connection_new_for_address_sync@Base 2.26.0 + g_dbus_connection_new_sync@Base 2.26.0 + g_dbus_connection_register_object@Base 2.26.0 + g_dbus_connection_register_object_with_closures@Base 2.45.6 + g_dbus_connection_register_subtree@Base 2.26.0 + g_dbus_connection_remove_filter@Base 2.26.0 + g_dbus_connection_send_message@Base 2.26.0 + g_dbus_connection_send_message_with_reply@Base 2.26.0 + g_dbus_connection_send_message_with_reply_finish@Base 2.26.0 + g_dbus_connection_send_message_with_reply_sync@Base 2.26.0 + g_dbus_connection_set_exit_on_close@Base 2.26.0 + g_dbus_connection_signal_subscribe@Base 2.26.0 + g_dbus_connection_signal_unsubscribe@Base 2.26.0 + g_dbus_connection_start_message_processing@Base 2.26.0 + g_dbus_connection_unexport_action_group@Base 2.31.8 + g_dbus_connection_unexport_menu_model@Base 2.31.8 + g_dbus_connection_unregister_object@Base 2.26.0 + g_dbus_connection_unregister_subtree@Base 2.26.0 + g_dbus_error_encode_gerror@Base 2.26.0 + g_dbus_error_get_remote_error@Base 2.26.0 + g_dbus_error_get_type@Base 2.26.0 + g_dbus_error_is_remote_error@Base 2.26.0 + g_dbus_error_new_for_dbus_error@Base 2.26.0 + g_dbus_error_quark@Base 2.26.0 + g_dbus_error_register_error@Base 2.26.0 + g_dbus_error_register_error_domain@Base 2.26.0 + g_dbus_error_set_dbus_error@Base 2.26.0 + g_dbus_error_set_dbus_error_valist@Base 2.26.0 + g_dbus_error_strip_remote_error@Base 2.26.0 + g_dbus_error_unregister_error@Base 2.26.0 + g_dbus_escape_object_path@Base 2.67.3 + g_dbus_escape_object_path_bytestring@Base 2.67.3 + g_dbus_generate_guid@Base 2.26.0 + g_dbus_gvalue_to_gvariant@Base 2.30.0 + g_dbus_gvariant_to_gvalue@Base 2.30.0 + g_dbus_interface_dup_object@Base 2.31.18 + g_dbus_interface_get_info@Base 2.30.0 + g_dbus_interface_get_object@Base 2.30.0 + g_dbus_interface_get_type@Base 2.30.0 + g_dbus_interface_info_cache_build@Base 2.30.0 + g_dbus_interface_info_cache_release@Base 2.30.0 + g_dbus_interface_info_generate_xml@Base 2.26.0 + g_dbus_interface_info_get_type@Base 2.26.0 + g_dbus_interface_info_lookup_method@Base 2.26.0 + g_dbus_interface_info_lookup_property@Base 2.26.0 + g_dbus_interface_info_lookup_signal@Base 2.26.0 + g_dbus_interface_info_ref@Base 2.26.0 + g_dbus_interface_info_unref@Base 2.26.0 + g_dbus_interface_set_object@Base 2.30.0 + g_dbus_interface_skeleton_export@Base 2.30.0 + g_dbus_interface_skeleton_flags_get_type@Base 2.30.0 + g_dbus_interface_skeleton_flush@Base 2.30.0 + g_dbus_interface_skeleton_get_connection@Base 2.30.0 + g_dbus_interface_skeleton_get_connections@Base 2.31.8 + g_dbus_interface_skeleton_get_flags@Base 2.30.0 + g_dbus_interface_skeleton_get_info@Base 2.30.0 + g_dbus_interface_skeleton_get_object_path@Base 2.30.0 + g_dbus_interface_skeleton_get_properties@Base 2.30.0 + g_dbus_interface_skeleton_get_type@Base 2.30.0 + g_dbus_interface_skeleton_get_vtable@Base 2.30.0 + g_dbus_interface_skeleton_has_connection@Base 2.31.8 + g_dbus_interface_skeleton_set_flags@Base 2.30.0 + g_dbus_interface_skeleton_unexport@Base 2.30.0 + g_dbus_interface_skeleton_unexport_from_connection@Base 2.31.8 + g_dbus_is_address@Base 2.26.0 + g_dbus_is_error_name@Base 2.70.0 + g_dbus_is_guid@Base 2.26.0 + g_dbus_is_interface_name@Base 2.26.0 + g_dbus_is_member_name@Base 2.26.0 + g_dbus_is_name@Base 2.26.0 + g_dbus_is_supported_address@Base 2.26.0 + g_dbus_is_unique_name@Base 2.26.0 + g_dbus_menu_model_get@Base 2.31.8 + g_dbus_menu_model_get_type@Base 2.31.8 + g_dbus_message_byte_order_get_type@Base 2.26.0 + g_dbus_message_bytes_needed@Base 2.26.0 + g_dbus_message_copy@Base 2.26.0 + g_dbus_message_flags_get_type@Base 2.26.0 + g_dbus_message_get_arg0@Base 2.26.0 + g_dbus_message_get_body@Base 2.26.0 + g_dbus_message_get_byte_order@Base 2.26.0 + g_dbus_message_get_destination@Base 2.26.0 + g_dbus_message_get_error_name@Base 2.26.0 + g_dbus_message_get_flags@Base 2.26.0 + g_dbus_message_get_header@Base 2.26.0 + g_dbus_message_get_header_fields@Base 2.26.0 + g_dbus_message_get_interface@Base 2.26.0 + g_dbus_message_get_locked@Base 2.26.0 + g_dbus_message_get_member@Base 2.26.0 + g_dbus_message_get_message_type@Base 2.26.0 + g_dbus_message_get_num_unix_fds@Base 2.26.0 + g_dbus_message_get_path@Base 2.26.0 + g_dbus_message_get_reply_serial@Base 2.26.0 + g_dbus_message_get_sender@Base 2.26.0 + g_dbus_message_get_serial@Base 2.26.0 + g_dbus_message_get_signature@Base 2.26.0 + g_dbus_message_get_type@Base 2.26.0 + g_dbus_message_get_unix_fd_list@Base 2.26.0 + g_dbus_message_header_field_get_type@Base 2.26.0 + g_dbus_message_lock@Base 2.26.0 + g_dbus_message_new@Base 2.26.0 + g_dbus_message_new_from_blob@Base 2.26.0 + g_dbus_message_new_method_call@Base 2.26.0 + g_dbus_message_new_method_error@Base 2.26.0 + g_dbus_message_new_method_error_literal@Base 2.26.0 + g_dbus_message_new_method_error_valist@Base 2.26.0 + g_dbus_message_new_method_reply@Base 2.26.0 + g_dbus_message_new_signal@Base 2.26.0 + g_dbus_message_print@Base 2.26.0 + g_dbus_message_set_body@Base 2.26.0 + g_dbus_message_set_byte_order@Base 2.26.0 + g_dbus_message_set_destination@Base 2.26.0 + g_dbus_message_set_error_name@Base 2.26.0 + g_dbus_message_set_flags@Base 2.26.0 + g_dbus_message_set_header@Base 2.26.0 + g_dbus_message_set_interface@Base 2.26.0 + g_dbus_message_set_member@Base 2.26.0 + g_dbus_message_set_message_type@Base 2.26.0 + g_dbus_message_set_num_unix_fds@Base 2.26.0 + g_dbus_message_set_path@Base 2.26.0 + g_dbus_message_set_reply_serial@Base 2.26.0 + g_dbus_message_set_sender@Base 2.26.0 + g_dbus_message_set_serial@Base 2.26.0 + g_dbus_message_set_signature@Base 2.26.0 + g_dbus_message_set_unix_fd_list@Base 2.26.0 + g_dbus_message_to_blob@Base 2.26.0 + g_dbus_message_to_gerror@Base 2.26.0 + g_dbus_message_type_get_type@Base 2.26.0 + g_dbus_method_info_get_type@Base 2.26.0 + g_dbus_method_info_ref@Base 2.26.0 + g_dbus_method_info_unref@Base 2.26.0 + g_dbus_method_invocation_get_connection@Base 2.26.0 + g_dbus_method_invocation_get_interface_name@Base 2.26.0 + g_dbus_method_invocation_get_message@Base 2.26.0 + g_dbus_method_invocation_get_method_info@Base 2.26.0 + g_dbus_method_invocation_get_method_name@Base 2.26.0 + g_dbus_method_invocation_get_object_path@Base 2.26.0 + g_dbus_method_invocation_get_parameters@Base 2.26.0 + g_dbus_method_invocation_get_property_info@Base 2.37.3 + g_dbus_method_invocation_get_sender@Base 2.26.0 + g_dbus_method_invocation_get_type@Base 2.26.0 + g_dbus_method_invocation_get_user_data@Base 2.26.0 + g_dbus_method_invocation_return_dbus_error@Base 2.26.0 + g_dbus_method_invocation_return_error@Base 2.26.0 + g_dbus_method_invocation_return_error_literal@Base 2.26.0 + g_dbus_method_invocation_return_error_valist@Base 2.26.0 + g_dbus_method_invocation_return_gerror@Base 2.26.0 + g_dbus_method_invocation_return_value@Base 2.26.0 + g_dbus_method_invocation_return_value_with_unix_fd_list@Base 2.30.0 + g_dbus_method_invocation_take_error@Base 2.30.0 + g_dbus_node_info_generate_xml@Base 2.26.0 + g_dbus_node_info_get_type@Base 2.26.0 + g_dbus_node_info_lookup_interface@Base 2.26.0 + g_dbus_node_info_new_for_xml@Base 2.26.0 + g_dbus_node_info_ref@Base 2.26.0 + g_dbus_node_info_unref@Base 2.26.0 + g_dbus_object_get_interface@Base 2.30.0 + g_dbus_object_get_interfaces@Base 2.30.0 + g_dbus_object_get_object_path@Base 2.30.0 + g_dbus_object_get_type@Base 2.30.0 + g_dbus_object_manager_client_flags_get_type@Base 2.30.0 + g_dbus_object_manager_client_get_connection@Base 2.30.0 + g_dbus_object_manager_client_get_flags@Base 2.30.0 + g_dbus_object_manager_client_get_name@Base 2.30.0 + g_dbus_object_manager_client_get_name_owner@Base 2.30.0 + g_dbus_object_manager_client_get_type@Base 2.30.0 + g_dbus_object_manager_client_new@Base 2.30.0 + g_dbus_object_manager_client_new_finish@Base 2.30.0 + g_dbus_object_manager_client_new_for_bus@Base 2.30.0 + g_dbus_object_manager_client_new_for_bus_finish@Base 2.30.0 + g_dbus_object_manager_client_new_for_bus_sync@Base 2.30.0 + g_dbus_object_manager_client_new_sync@Base 2.30.0 + g_dbus_object_manager_get_interface@Base 2.30.0 + g_dbus_object_manager_get_object@Base 2.30.0 + g_dbus_object_manager_get_object_path@Base 2.30.0 + g_dbus_object_manager_get_objects@Base 2.30.0 + g_dbus_object_manager_get_type@Base 2.30.0 + g_dbus_object_manager_server_export@Base 2.30.0 + g_dbus_object_manager_server_export_uniquely@Base 2.30.0 + g_dbus_object_manager_server_get_connection@Base 2.30.0 + g_dbus_object_manager_server_get_type@Base 2.30.0 + g_dbus_object_manager_server_is_exported@Base 2.33.14 + g_dbus_object_manager_server_new@Base 2.30.0 + g_dbus_object_manager_server_set_connection@Base 2.30.0 + g_dbus_object_manager_server_unexport@Base 2.30.0 + g_dbus_object_proxy_get_connection@Base 2.30.0 + g_dbus_object_proxy_get_type@Base 2.30.0 + g_dbus_object_proxy_new@Base 2.30.0 + g_dbus_object_skeleton_add_interface@Base 2.30.0 + g_dbus_object_skeleton_flush@Base 2.30.0 + g_dbus_object_skeleton_get_type@Base 2.30.0 + g_dbus_object_skeleton_new@Base 2.30.0 + g_dbus_object_skeleton_remove_interface@Base 2.30.0 + g_dbus_object_skeleton_remove_interface_by_name@Base 2.30.0 + g_dbus_object_skeleton_set_object_path@Base 2.30.0 + g_dbus_property_info_flags_get_type@Base 2.26.0 + g_dbus_property_info_get_type@Base 2.26.0 + g_dbus_property_info_ref@Base 2.26.0 + g_dbus_property_info_unref@Base 2.26.0 + g_dbus_proxy_call@Base 2.26.0 + g_dbus_proxy_call_finish@Base 2.26.0 + g_dbus_proxy_call_sync@Base 2.26.0 + g_dbus_proxy_call_with_unix_fd_list@Base 2.30.0 + g_dbus_proxy_call_with_unix_fd_list_finish@Base 2.30.0 + g_dbus_proxy_call_with_unix_fd_list_sync@Base 2.30.0 + g_dbus_proxy_flags_get_type@Base 2.26.0 + g_dbus_proxy_get_cached_property@Base 2.26.0 + g_dbus_proxy_get_cached_property_names@Base 2.26.0 + g_dbus_proxy_get_connection@Base 2.26.0 + g_dbus_proxy_get_default_timeout@Base 2.26.0 + g_dbus_proxy_get_flags@Base 2.26.0 + g_dbus_proxy_get_interface_info@Base 2.26.0 + g_dbus_proxy_get_interface_name@Base 2.26.0 + g_dbus_proxy_get_name@Base 2.26.0 + g_dbus_proxy_get_name_owner@Base 2.26.0 + g_dbus_proxy_get_object_path@Base 2.26.0 + g_dbus_proxy_get_type@Base 2.26.0 + g_dbus_proxy_new@Base 2.26.0 + g_dbus_proxy_new_finish@Base 2.26.0 + g_dbus_proxy_new_for_bus@Base 2.26.0 + g_dbus_proxy_new_for_bus_finish@Base 2.26.0 + g_dbus_proxy_new_for_bus_sync@Base 2.26.0 + g_dbus_proxy_new_sync@Base 2.26.0 + g_dbus_proxy_set_cached_property@Base 2.26.0 + g_dbus_proxy_set_default_timeout@Base 2.26.0 + g_dbus_proxy_set_interface_info@Base 2.26.0 + g_dbus_send_message_flags_get_type@Base 2.26.0 + g_dbus_server_flags_get_type@Base 2.26.0 + g_dbus_server_get_client_address@Base 2.26.0 + g_dbus_server_get_flags@Base 2.26.0 + g_dbus_server_get_guid@Base 2.26.0 + g_dbus_server_get_type@Base 2.26.0 + g_dbus_server_is_active@Base 2.26.0 + g_dbus_server_new_sync@Base 2.68.0 + g_dbus_server_start@Base 2.26.0 + g_dbus_server_stop@Base 2.26.0 + g_dbus_signal_flags_get_type@Base 2.26.0 + g_dbus_signal_info_get_type@Base 2.26.0 + g_dbus_signal_info_ref@Base 2.26.0 + g_dbus_signal_info_unref@Base 2.26.0 + g_dbus_subtree_flags_get_type@Base 2.26.0 + g_dbus_unescape_object_path@Base 2.67.3 + g_debug_controller_dbus_get_type@Base 2.71.1 + g_debug_controller_dbus_new@Base 2.71.1 + g_debug_controller_dbus_stop@Base 2.71.2 + g_debug_controller_get_debug_enabled@Base 2.71.1 + g_debug_controller_get_type@Base 2.71.1 + g_debug_controller_set_debug_enabled@Base 2.71.1 + g_desktop_app_info_get_action_name@Base 2.37.5 + g_desktop_app_info_get_boolean@Base 2.35.8 + g_desktop_app_info_get_categories@Base 2.30.0 + g_desktop_app_info_get_filename@Base 2.24.0 + g_desktop_app_info_get_generic_name@Base 2.30.0 + g_desktop_app_info_get_implementations@Base 2.41.0 + g_desktop_app_info_get_is_hidden@Base 2.16.0 + g_desktop_app_info_get_keywords@Base 2.31.8 + g_desktop_app_info_get_locale_string@Base 2.55.1 + g_desktop_app_info_get_nodisplay@Base 2.30.0 + g_desktop_app_info_get_show_in@Base 2.30.0 + g_desktop_app_info_get_startup_wm_class@Base 2.33.14 + g_desktop_app_info_get_string@Base 2.35.8 + g_desktop_app_info_get_string_list@Base 2.59.0 + g_desktop_app_info_get_type@Base 2.16.0 + g_desktop_app_info_has_key@Base 2.35.8 + g_desktop_app_info_launch_action@Base 2.37.5 + g_desktop_app_info_launch_uris_as_manager@Base 2.28.0 + g_desktop_app_info_launch_uris_as_manager_with_fds@Base 2.57.2 + g_desktop_app_info_list_actions@Base 2.37.5 + g_desktop_app_info_lookup_get_default_for_uri_scheme@Base 2.28.0 + g_desktop_app_info_lookup_get_type@Base 2.28.0 + g_desktop_app_info_new@Base 2.16.0 + g_desktop_app_info_new_from_filename@Base 2.16.0 + g_desktop_app_info_new_from_keyfile@Base 2.18.0 + g_desktop_app_info_search@Base 2.39.4 + g_desktop_app_info_set_desktop_env@Base 2.16.0 + g_drive_can_eject@Base 2.16.0 + g_drive_can_poll_for_media@Base 2.16.0 + g_drive_can_start@Base 2.22.0 + g_drive_can_start_degraded@Base 2.22.0 + g_drive_can_stop@Base 2.22.0 + g_drive_eject@Base 2.16.0 + g_drive_eject_finish@Base 2.16.0 + g_drive_eject_with_operation@Base 2.22.0 + g_drive_eject_with_operation_finish@Base 2.22.0 + g_drive_enumerate_identifiers@Base 2.16.0 + g_drive_get_icon@Base 2.16.0 + g_drive_get_identifier@Base 2.16.0 + g_drive_get_name@Base 2.16.0 + g_drive_get_sort_key@Base 2.31.8 + g_drive_get_start_stop_type@Base 2.22.0 + g_drive_get_symbolic_icon@Base 2.33.14 + g_drive_get_type@Base 2.16.0 + g_drive_get_volumes@Base 2.16.0 + g_drive_has_media@Base 2.16.0 + g_drive_has_volumes@Base 2.16.0 + g_drive_is_media_check_automatic@Base 2.16.0 + g_drive_is_media_removable@Base 2.16.0 + g_drive_is_removable@Base 2.49.2 + g_drive_poll_for_media@Base 2.16.0 + g_drive_poll_for_media_finish@Base 2.16.0 + g_drive_start@Base 2.22.0 + g_drive_start_finish@Base 2.22.0 + g_drive_start_flags_get_type@Base 2.22.0 + g_drive_start_stop_type_get_type@Base 2.22.0 + g_drive_stop@Base 2.22.0 + g_drive_stop_finish@Base 2.22.0 + g_dtls_client_connection_get_accepted_cas@Base 2.47.5 + g_dtls_client_connection_get_server_identity@Base 2.47.5 + g_dtls_client_connection_get_type@Base 2.47.5 + g_dtls_client_connection_get_validation_flags@Base 2.47.5 + g_dtls_client_connection_new@Base 2.47.5 + g_dtls_client_connection_set_server_identity@Base 2.47.5 + g_dtls_client_connection_set_validation_flags@Base 2.47.5 + g_dtls_connection_close@Base 2.47.5 + g_dtls_connection_close_async@Base 2.47.5 + g_dtls_connection_close_finish@Base 2.47.5 + g_dtls_connection_emit_accept_certificate@Base 2.47.5 + g_dtls_connection_get_certificate@Base 2.47.5 + g_dtls_connection_get_channel_binding_data@Base 2.65.1 + g_dtls_connection_get_ciphersuite_name@Base 2.70.0 + g_dtls_connection_get_database@Base 2.47.5 + g_dtls_connection_get_interaction@Base 2.47.5 + g_dtls_connection_get_negotiated_protocol@Base 2.59.0 + g_dtls_connection_get_peer_certificate@Base 2.47.5 + g_dtls_connection_get_peer_certificate_errors@Base 2.47.5 + g_dtls_connection_get_protocol_version@Base 2.70.0 + g_dtls_connection_get_rehandshake_mode@Base 2.47.5 + g_dtls_connection_get_require_close_notify@Base 2.47.5 + g_dtls_connection_get_type@Base 2.47.5 + g_dtls_connection_handshake@Base 2.47.5 + g_dtls_connection_handshake_async@Base 2.47.5 + g_dtls_connection_handshake_finish@Base 2.47.5 + g_dtls_connection_set_advertised_protocols@Base 2.59.0 + g_dtls_connection_set_certificate@Base 2.47.5 + g_dtls_connection_set_database@Base 2.47.5 + g_dtls_connection_set_interaction@Base 2.47.5 + g_dtls_connection_set_rehandshake_mode@Base 2.47.5 + g_dtls_connection_set_require_close_notify@Base 2.47.5 + g_dtls_connection_shutdown@Base 2.47.5 + g_dtls_connection_shutdown_async@Base 2.47.5 + g_dtls_connection_shutdown_finish@Base 2.47.5 + g_dtls_server_connection_get_type@Base 2.47.5 + g_dtls_server_connection_new@Base 2.47.5 + g_emblem_get_icon@Base 2.18.0 + g_emblem_get_origin@Base 2.18.0 + g_emblem_get_type@Base 2.18.0 + g_emblem_new@Base 2.18.0 + g_emblem_new_with_origin@Base 2.18.0 + g_emblem_origin_get_type@Base 2.18.0 + g_emblemed_icon_add_emblem@Base 2.18.0 + g_emblemed_icon_clear_emblems@Base 2.28.0 + g_emblemed_icon_get_emblems@Base 2.18.0 + g_emblemed_icon_get_icon@Base 2.18.0 + g_emblemed_icon_get_type@Base 2.18.0 + g_emblemed_icon_new@Base 2.18.0 + g_file_append_to@Base 2.16.0 + g_file_append_to_async@Base 2.16.0 + g_file_append_to_finish@Base 2.16.0 + g_file_attribute_info_flags_get_type@Base 2.16.0 + g_file_attribute_info_list_add@Base 2.16.0 + g_file_attribute_info_list_dup@Base 2.16.0 + g_file_attribute_info_list_get_type@Base 2.20.0 + g_file_attribute_info_list_lookup@Base 2.16.0 + g_file_attribute_info_list_new@Base 2.16.0 + g_file_attribute_info_list_ref@Base 2.16.0 + g_file_attribute_info_list_unref@Base 2.16.0 + g_file_attribute_matcher_enumerate_namespace@Base 2.16.0 + g_file_attribute_matcher_enumerate_next@Base 2.16.0 + g_file_attribute_matcher_get_type@Base 2.26.0 + g_file_attribute_matcher_matches@Base 2.16.0 + g_file_attribute_matcher_matches_only@Base 2.16.0 + g_file_attribute_matcher_new@Base 2.16.0 + g_file_attribute_matcher_ref@Base 2.16.0 + g_file_attribute_matcher_subtract@Base 2.31.8 + g_file_attribute_matcher_to_string@Base 2.31.8 + g_file_attribute_matcher_unref@Base 2.16.0 + g_file_attribute_status_get_type@Base 2.16.0 + g_file_attribute_type_get_type@Base 2.16.0 + g_file_build_attribute_list_for_copy@Base 2.67.1 + g_file_copy@Base 2.16.0 + g_file_copy_async@Base 2.16.0 + g_file_copy_attributes@Base 2.16.0 + g_file_copy_finish@Base 2.16.0 + g_file_copy_flags_get_type@Base 2.16.0 + g_file_create@Base 2.16.0 + g_file_create_async@Base 2.16.0 + g_file_create_finish@Base 2.16.0 + g_file_create_flags_get_type@Base 2.16.0 + g_file_create_readwrite@Base 2.22.0 + g_file_create_readwrite_async@Base 2.22.0 + g_file_create_readwrite_finish@Base 2.22.0 + g_file_delete@Base 2.16.0 + g_file_delete_async@Base 2.33.14 + g_file_delete_finish@Base 2.33.14 + g_file_descriptor_based_get_fd@Base 2.24.0 + g_file_descriptor_based_get_type@Base 2.24.0 + g_file_dup@Base 2.16.0 + g_file_eject_mountable@Base 2.16.0 + g_file_eject_mountable_finish@Base 2.16.0 + g_file_eject_mountable_with_operation@Base 2.22.0 + g_file_eject_mountable_with_operation_finish@Base 2.22.0 + g_file_enumerate_children@Base 2.16.0 + g_file_enumerate_children_async@Base 2.16.0 + g_file_enumerate_children_finish@Base 2.16.0 + g_file_enumerator_close@Base 2.16.0 + g_file_enumerator_close_async@Base 2.16.0 + g_file_enumerator_close_finish@Base 2.16.0 + g_file_enumerator_get_child@Base 2.35.8 + g_file_enumerator_get_container@Base 2.18.0 + g_file_enumerator_get_type@Base 2.16.0 + g_file_enumerator_has_pending@Base 2.16.0 + g_file_enumerator_is_closed@Base 2.16.0 + g_file_enumerator_iterate@Base 2.43.91 + g_file_enumerator_next_file@Base 2.16.0 + g_file_enumerator_next_files_async@Base 2.16.0 + g_file_enumerator_next_files_finish@Base 2.16.0 + g_file_enumerator_set_pending@Base 2.16.0 + g_file_equal@Base 2.16.0 + g_file_find_enclosing_mount@Base 2.16.0 + g_file_find_enclosing_mount_async@Base 2.16.0 + g_file_find_enclosing_mount_finish@Base 2.16.0 + g_file_get_basename@Base 2.16.0 + g_file_get_child@Base 2.16.0 + g_file_get_child_for_display_name@Base 2.16.0 + g_file_get_parent@Base 2.16.0 + g_file_get_parse_name@Base 2.16.0 + g_file_get_path@Base 2.16.0 + g_file_get_relative_path@Base 2.16.0 + g_file_get_type@Base 2.16.0 + g_file_get_uri@Base 2.16.0 + g_file_get_uri_scheme@Base 2.16.0 + g_file_has_parent@Base 2.24.0 + g_file_has_prefix@Base 2.16.0 + g_file_has_uri_scheme@Base 2.16.0 + g_file_hash@Base 2.16.0 + g_file_icon_get_file@Base 2.16.0 + g_file_icon_get_type@Base 2.16.0 + g_file_icon_new@Base 2.16.0 + g_file_info_clear_status@Base 2.16.0 + g_file_info_copy_into@Base 2.16.0 + g_file_info_dup@Base 2.16.0 + g_file_info_get_access_date_time@Base 2.70.0 + g_file_info_get_attribute_as_string@Base 2.16.0 + g_file_info_get_attribute_boolean@Base 2.16.0 + g_file_info_get_attribute_byte_string@Base 2.16.0 + g_file_info_get_attribute_data@Base 2.16.0 + g_file_info_get_attribute_int32@Base 2.16.0 + g_file_info_get_attribute_int64@Base 2.16.0 + g_file_info_get_attribute_object@Base 2.16.0 + g_file_info_get_attribute_status@Base 2.16.0 + g_file_info_get_attribute_string@Base 2.16.0 + g_file_info_get_attribute_stringv@Base 2.22.0 + g_file_info_get_attribute_type@Base 2.16.0 + g_file_info_get_attribute_uint32@Base 2.16.0 + g_file_info_get_attribute_uint64@Base 2.16.0 + g_file_info_get_content_type@Base 2.16.0 + g_file_info_get_creation_date_time@Base 2.70.0 + g_file_info_get_deletion_date@Base 2.35.8 + g_file_info_get_display_name@Base 2.16.0 + g_file_info_get_edit_name@Base 2.16.0 + g_file_info_get_etag@Base 2.16.0 + g_file_info_get_file_type@Base 2.16.0 + g_file_info_get_icon@Base 2.16.0 + g_file_info_get_is_backup@Base 2.16.0 + g_file_info_get_is_hidden@Base 2.16.0 + g_file_info_get_is_symlink@Base 2.16.0 + g_file_info_get_modification_date_time@Base 2.61.2 + g_file_info_get_modification_time@Base 2.16.0 + g_file_info_get_name@Base 2.16.0 + g_file_info_get_size@Base 2.16.0 + g_file_info_get_sort_order@Base 2.16.0 + g_file_info_get_symbolic_icon@Base 2.33.14 + g_file_info_get_symlink_target@Base 2.16.0 + g_file_info_get_type@Base 2.16.0 + g_file_info_has_attribute@Base 2.16.0 + g_file_info_has_namespace@Base 2.22.0 + g_file_info_list_attributes@Base 2.16.0 + g_file_info_new@Base 2.16.0 + g_file_info_remove_attribute@Base 2.16.0 + g_file_info_set_access_date_time@Base 2.70.0 + g_file_info_set_attribute@Base 2.16.0 + g_file_info_set_attribute_boolean@Base 2.16.0 + g_file_info_set_attribute_byte_string@Base 2.16.0 + g_file_info_set_attribute_int32@Base 2.16.0 + g_file_info_set_attribute_int64@Base 2.16.0 + g_file_info_set_attribute_mask@Base 2.16.0 + g_file_info_set_attribute_object@Base 2.16.0 + g_file_info_set_attribute_status@Base 2.22.0 + g_file_info_set_attribute_string@Base 2.16.0 + g_file_info_set_attribute_stringv@Base 2.22.0 + g_file_info_set_attribute_uint32@Base 2.16.0 + g_file_info_set_attribute_uint64@Base 2.16.0 + g_file_info_set_content_type@Base 2.16.0 + g_file_info_set_creation_date_time@Base 2.70.0 + g_file_info_set_display_name@Base 2.16.0 + g_file_info_set_edit_name@Base 2.16.0 + g_file_info_set_file_type@Base 2.16.0 + g_file_info_set_icon@Base 2.16.0 + g_file_info_set_is_hidden@Base 2.16.0 + g_file_info_set_is_symlink@Base 2.16.0 + g_file_info_set_modification_date_time@Base 2.61.2 + g_file_info_set_modification_time@Base 2.16.0 + g_file_info_set_name@Base 2.16.0 + g_file_info_set_size@Base 2.16.0 + g_file_info_set_sort_order@Base 2.16.0 + g_file_info_set_symbolic_icon@Base 2.33.14 + g_file_info_set_symlink_target@Base 2.16.0 + g_file_info_unset_attribute_mask@Base 2.16.0 + g_file_input_stream_get_type@Base 2.16.0 + g_file_input_stream_query_info@Base 2.16.0 + g_file_input_stream_query_info_async@Base 2.16.0 + g_file_input_stream_query_info_finish@Base 2.16.0 + g_file_io_stream_get_etag@Base 2.22.0 + g_file_io_stream_get_type@Base 2.22.0 + g_file_io_stream_query_info@Base 2.22.0 + g_file_io_stream_query_info_async@Base 2.22.0 + g_file_io_stream_query_info_finish@Base 2.22.0 + g_file_is_native@Base 2.16.0 + g_file_load_bytes@Base 2.55.1 + g_file_load_bytes_async@Base 2.55.1 + g_file_load_bytes_finish@Base 2.55.1 + g_file_load_contents@Base 2.16.0 + g_file_load_contents_async@Base 2.16.0 + g_file_load_contents_finish@Base 2.16.0 + g_file_load_partial_contents_async@Base 2.16.0 + g_file_load_partial_contents_finish@Base 2.16.0 + g_file_make_directory@Base 2.16.0 + g_file_make_directory_async@Base 2.37.0 + g_file_make_directory_finish@Base 2.37.0 + g_file_make_directory_with_parents@Base 2.18.0 + g_file_make_symbolic_link@Base 2.16.0 + g_file_measure_disk_usage@Base 2.37.93 + g_file_measure_disk_usage_async@Base 2.37.93 + g_file_measure_disk_usage_finish@Base 2.37.93 + g_file_measure_flags_get_type@Base 2.37.93 + g_file_monitor@Base 2.18.0 + g_file_monitor_cancel@Base 2.16.0 + g_file_monitor_directory@Base 2.16.0 + g_file_monitor_emit_event@Base 2.16.0 + g_file_monitor_event_get_type@Base 2.16.0 + g_file_monitor_file@Base 2.16.0 + g_file_monitor_flags_get_type@Base 2.16.0 + g_file_monitor_get_type@Base 2.16.0 + g_file_monitor_is_cancelled@Base 2.16.0 + g_file_monitor_set_rate_limit@Base 2.16.0 + g_file_monitor_source_handle_event@Base 2.45.1 + g_file_mount_enclosing_volume@Base 2.16.0 + g_file_mount_enclosing_volume_finish@Base 2.16.0 + g_file_mount_mountable@Base 2.16.0 + g_file_mount_mountable_finish@Base 2.16.0 + g_file_move@Base 2.16.0 + g_file_move_async@Base 2.71.2 + g_file_move_finish@Base 2.71.2 + g_file_new_build_filename@Base 2.55.1 + g_file_new_for_commandline_arg@Base 2.16.0 + g_file_new_for_commandline_arg_and_cwd@Base 2.35.8 + g_file_new_for_path@Base 2.16.0 + g_file_new_for_uri@Base 2.16.0 + g_file_new_tmp@Base 2.31.8 + g_file_open_readwrite@Base 2.22.0 + g_file_open_readwrite_async@Base 2.22.0 + g_file_open_readwrite_finish@Base 2.22.0 + g_file_output_stream_get_etag@Base 2.16.0 + g_file_output_stream_get_type@Base 2.16.0 + g_file_output_stream_query_info@Base 2.16.0 + g_file_output_stream_query_info_async@Base 2.16.0 + g_file_output_stream_query_info_finish@Base 2.16.0 + g_file_parse_name@Base 2.16.0 + g_file_peek_path@Base 2.55.2 + g_file_poll_mountable@Base 2.22.0 + g_file_poll_mountable_finish@Base 2.22.0 + g_file_query_default_handler@Base 2.16.0 + g_file_query_default_handler_async@Base 2.59.2 + g_file_query_default_handler_finish@Base 2.59.2 + g_file_query_exists@Base 2.16.0 + g_file_query_file_type@Base 2.18.0 + g_file_query_filesystem_info@Base 2.16.0 + g_file_query_filesystem_info_async@Base 2.16.0 + g_file_query_filesystem_info_finish@Base 2.16.0 + g_file_query_info@Base 2.16.0 + g_file_query_info_async@Base 2.16.0 + g_file_query_info_finish@Base 2.16.0 + g_file_query_info_flags_get_type@Base 2.16.0 + g_file_query_settable_attributes@Base 2.16.0 + g_file_query_writable_namespaces@Base 2.16.0 + g_file_read@Base 2.16.0 + g_file_read_async@Base 2.16.0 + g_file_read_finish@Base 2.16.0 + g_file_replace@Base 2.16.0 + g_file_replace_async@Base 2.16.0 + g_file_replace_contents@Base 2.16.0 + g_file_replace_contents_async@Base 2.16.0 + g_file_replace_contents_bytes_async@Base 2.39.4 + g_file_replace_contents_finish@Base 2.16.0 + g_file_replace_finish@Base 2.16.0 + g_file_replace_readwrite@Base 2.22.0 + g_file_replace_readwrite_async@Base 2.22.0 + g_file_replace_readwrite_finish@Base 2.22.0 + g_file_resolve_relative_path@Base 2.16.0 + g_file_set_attribute@Base 2.16.0 + g_file_set_attribute_byte_string@Base 2.16.0 + g_file_set_attribute_int32@Base 2.16.0 + g_file_set_attribute_int64@Base 2.16.0 + g_file_set_attribute_string@Base 2.16.0 + g_file_set_attribute_uint32@Base 2.16.0 + g_file_set_attribute_uint64@Base 2.16.0 + g_file_set_attributes_async@Base 2.16.0 + g_file_set_attributes_finish@Base 2.16.0 + g_file_set_attributes_from_info@Base 2.16.0 + g_file_set_display_name@Base 2.16.0 + g_file_set_display_name_async@Base 2.16.0 + g_file_set_display_name_finish@Base 2.16.0 + g_file_start_mountable@Base 2.22.0 + g_file_start_mountable_finish@Base 2.22.0 + g_file_stop_mountable@Base 2.22.0 + g_file_stop_mountable_finish@Base 2.22.0 + g_file_supports_thread_contexts@Base 2.22.0 + g_file_trash@Base 2.16.0 + g_file_trash_async@Base 2.37.0 + g_file_trash_finish@Base 2.37.0 + g_file_type_get_type@Base 2.16.0 + g_file_unmount_mountable@Base 2.16.0 + g_file_unmount_mountable_finish@Base 2.16.0 + g_file_unmount_mountable_with_operation@Base 2.22.0 + g_file_unmount_mountable_with_operation_finish@Base 2.22.0 + g_filename_completer_get_completion_suffix@Base 2.16.0 + g_filename_completer_get_completions@Base 2.16.0 + g_filename_completer_get_type@Base 2.16.0 + g_filename_completer_new@Base 2.16.0 + g_filename_completer_set_dirs_only@Base 2.16.0 + g_filesystem_preview_type_get_type@Base 2.16.0 + g_filter_input_stream_get_base_stream@Base 2.16.0 + g_filter_input_stream_get_close_base_stream@Base 2.20.0 + g_filter_input_stream_get_type@Base 2.16.0 + g_filter_input_stream_set_close_base_stream@Base 2.20.0 + g_filter_output_stream_get_base_stream@Base 2.16.0 + g_filter_output_stream_get_close_base_stream@Base 2.20.0 + g_filter_output_stream_get_type@Base 2.16.0 + g_filter_output_stream_set_close_base_stream@Base 2.20.0 + g_icon_deserialize@Base 2.37.0 + g_icon_equal@Base 2.16.0 + g_icon_get_type@Base 2.16.0 + g_icon_hash@Base 2.16.0 + g_icon_new_for_string@Base 2.20.0 + g_icon_serialize@Base 2.37.0 + g_icon_to_string@Base 2.20.0 + g_inet_address_equal@Base 2.30.0 + g_inet_address_get_family@Base 2.22.0 + g_inet_address_get_is_any@Base 2.22.0 + g_inet_address_get_is_link_local@Base 2.22.0 + g_inet_address_get_is_loopback@Base 2.22.0 + g_inet_address_get_is_mc_global@Base 2.22.0 + g_inet_address_get_is_mc_link_local@Base 2.22.0 + g_inet_address_get_is_mc_node_local@Base 2.22.0 + g_inet_address_get_is_mc_org_local@Base 2.22.0 + g_inet_address_get_is_mc_site_local@Base 2.22.0 + g_inet_address_get_is_multicast@Base 2.22.0 + g_inet_address_get_is_site_local@Base 2.22.0 + g_inet_address_get_native_size@Base 2.22.0 + g_inet_address_get_type@Base 2.22.0 + g_inet_address_mask_equal@Base 2.31.8 + g_inet_address_mask_get_address@Base 2.31.8 + g_inet_address_mask_get_family@Base 2.31.8 + g_inet_address_mask_get_length@Base 2.31.8 + g_inet_address_mask_get_type@Base 2.31.8 + g_inet_address_mask_matches@Base 2.31.8 + g_inet_address_mask_new@Base 2.31.8 + g_inet_address_mask_new_from_string@Base 2.31.8 + g_inet_address_mask_to_string@Base 2.31.8 + g_inet_address_new_any@Base 2.22.0 + g_inet_address_new_from_bytes@Base 2.22.0 + g_inet_address_new_from_string@Base 2.22.0 + g_inet_address_new_loopback@Base 2.22.0 + g_inet_address_to_bytes@Base 2.22.0 + g_inet_address_to_string@Base 2.22.0 + g_inet_socket_address_get_address@Base 2.22.0 + g_inet_socket_address_get_flowinfo@Base 2.31.18 + g_inet_socket_address_get_port@Base 2.22.0 + g_inet_socket_address_get_scope_id@Base 2.31.18 + g_inet_socket_address_get_type@Base 2.22.0 + g_inet_socket_address_new@Base 2.22.0 + g_inet_socket_address_new_from_string@Base 2.39.90 + g_initable_get_type@Base 2.22.0 + g_initable_init@Base 2.22.0 + g_initable_new@Base 2.22.0 + g_initable_new_valist@Base 2.22.0 + g_initable_newv@Base 2.22.0 + g_input_stream_clear_pending@Base 2.16.0 + g_input_stream_close@Base 2.16.0 + g_input_stream_close_async@Base 2.16.0 + g_input_stream_close_finish@Base 2.16.0 + g_input_stream_get_type@Base 2.16.0 + g_input_stream_has_pending@Base 2.16.0 + g_input_stream_is_closed@Base 2.16.0 + g_input_stream_read@Base 2.16.0 + g_input_stream_read_all@Base 2.16.0 + g_input_stream_read_all_async@Base 2.43.1 + g_input_stream_read_all_finish@Base 2.43.1 + g_input_stream_read_async@Base 2.16.0 + g_input_stream_read_bytes@Base 2.33.14 + g_input_stream_read_bytes_async@Base 2.33.14 + g_input_stream_read_bytes_finish@Base 2.33.14 + g_input_stream_read_finish@Base 2.16.0 + g_input_stream_set_pending@Base 2.16.0 + g_input_stream_skip@Base 2.16.0 + g_input_stream_skip_async@Base 2.16.0 + g_input_stream_skip_finish@Base 2.16.0 + g_io_error_enum_get_type@Base 2.16.0 + g_io_error_from_errno@Base 2.16.0 + g_io_error_quark@Base 2.16.0 + g_io_extension_get_name@Base 2.16.0 + g_io_extension_get_priority@Base 2.16.0 + g_io_extension_get_type@Base 2.16.0 + g_io_extension_point_get_extension_by_name@Base 2.16.0 + g_io_extension_point_get_extensions@Base 2.16.0 + g_io_extension_point_get_required_type@Base 2.16.0 + g_io_extension_point_implement@Base 2.16.0 + g_io_extension_point_lookup@Base 2.16.0 + g_io_extension_point_register@Base 2.16.0 + g_io_extension_point_set_required_type@Base 2.16.0 + g_io_extension_ref_class@Base 2.16.0 + g_io_module_get_type@Base 2.16.0 + g_io_module_new@Base 2.16.0 + g_io_module_scope_block@Base 2.30.0 + g_io_module_scope_flags_get_type@Base 2.30.0 + g_io_module_scope_free@Base 2.30.0 + g_io_module_scope_new@Base 2.30.0 + g_io_modules_load_all_in_directory@Base 2.16.0 + g_io_modules_load_all_in_directory_with_scope@Base 2.30.0 + g_io_modules_scan_all_in_directory@Base 2.24.0 + g_io_modules_scan_all_in_directory_with_scope@Base 2.30.0 + g_io_scheduler_cancel_all_jobs@Base 2.16.0 + g_io_scheduler_job_send_to_mainloop@Base 2.16.0 + g_io_scheduler_job_send_to_mainloop_async@Base 2.16.0 + g_io_scheduler_push_job@Base 2.16.0 + g_io_stream_clear_pending@Base 2.22.0 + g_io_stream_close@Base 2.22.0 + g_io_stream_close_async@Base 2.22.0 + g_io_stream_close_finish@Base 2.22.0 + g_io_stream_get_input_stream@Base 2.22.0 + g_io_stream_get_output_stream@Base 2.22.0 + g_io_stream_get_type@Base 2.22.0 + g_io_stream_has_pending@Base 2.22.0 + g_io_stream_is_closed@Base 2.22.0 + g_io_stream_set_pending@Base 2.22.0 + g_io_stream_splice_async@Base 2.28.0 + g_io_stream_splice_finish@Base 2.28.0 + g_io_stream_splice_flags_get_type@Base 2.28.0 + g_keyfile_settings_backend_new@Base 2.26.0 + g_list_model_get_item@Base 2.43.4 + g_list_model_get_item_type@Base 2.43.4 + g_list_model_get_n_items@Base 2.43.4 + g_list_model_get_object@Base 2.43.4 + g_list_model_get_type@Base 2.43.4 + g_list_model_items_changed@Base 2.43.4 + g_list_store_append@Base 2.43.4 + g_list_store_find@Base 2.63.3 + g_list_store_find_with_equal_func@Base 2.63.3 + g_list_store_get_type@Base 2.43.4 + g_list_store_insert@Base 2.43.4 + g_list_store_insert_sorted@Base 2.43.4 + g_list_store_new@Base 2.43.4 + g_list_store_remove@Base 2.43.4 + g_list_store_remove_all@Base 2.43.4 + g_list_store_sort@Base 2.45.7 + g_list_store_splice@Base 2.43.4 + g_loadable_icon_get_type@Base 2.16.0 + g_loadable_icon_load@Base 2.16.0 + g_loadable_icon_load_async@Base 2.16.0 + g_loadable_icon_load_finish@Base 2.16.0 + g_local_file_monitor_get_type@Base 2.16.0 + g_memory_input_stream_add_bytes@Base 2.33.14 + g_memory_input_stream_add_data@Base 2.16.0 + g_memory_input_stream_get_type@Base 2.16.0 + g_memory_input_stream_new@Base 2.16.0 + g_memory_input_stream_new_from_bytes@Base 2.33.14 + g_memory_input_stream_new_from_data@Base 2.16.0 + g_memory_monitor_dup_default@Base 2.63.3 + g_memory_monitor_get_type@Base 2.63.3 + g_memory_monitor_warning_level_get_type@Base 2.63.3 + g_memory_output_stream_get_data@Base 2.16.0 + g_memory_output_stream_get_data_size@Base 2.18.0 + g_memory_output_stream_get_size@Base 2.16.0 + g_memory_output_stream_get_type@Base 2.16.0 + g_memory_output_stream_new@Base 2.16.0 + g_memory_output_stream_new_resizable@Base 2.35.8 + g_memory_output_stream_steal_as_bytes@Base 2.33.14 + g_memory_output_stream_steal_data@Base 2.26.0 + g_memory_settings_backend_new@Base 2.28.0 + g_menu_append@Base 2.31.8 + g_menu_append_item@Base 2.31.8 + g_menu_append_section@Base 2.31.8 + g_menu_append_submenu@Base 2.31.8 + g_menu_attribute_iter_get_name@Base 2.31.8 + g_menu_attribute_iter_get_next@Base 2.31.8 + g_menu_attribute_iter_get_type@Base 2.31.8 + g_menu_attribute_iter_get_value@Base 2.31.8 + g_menu_attribute_iter_next@Base 2.31.8 + g_menu_freeze@Base 2.31.8 + g_menu_get_type@Base 2.31.8 + g_menu_insert@Base 2.31.8 + g_menu_insert_item@Base 2.31.8 + g_menu_insert_section@Base 2.31.8 + g_menu_insert_submenu@Base 2.31.8 + g_menu_item_get_attribute@Base 2.33.14 + g_menu_item_get_attribute_value@Base 2.33.14 + g_menu_item_get_link@Base 2.33.14 + g_menu_item_get_type@Base 2.31.8 + g_menu_item_new@Base 2.31.8 + g_menu_item_new_from_model@Base 2.33.14 + g_menu_item_new_section@Base 2.31.8 + g_menu_item_new_submenu@Base 2.31.8 + g_menu_item_set_action_and_target@Base 2.31.8 + g_menu_item_set_action_and_target_value@Base 2.31.8 + g_menu_item_set_attribute@Base 2.31.8 + g_menu_item_set_attribute_value@Base 2.31.8 + g_menu_item_set_detailed_action@Base 2.31.8 + g_menu_item_set_icon@Base 2.37.0 + g_menu_item_set_label@Base 2.31.8 + g_menu_item_set_link@Base 2.31.8 + g_menu_item_set_section@Base 2.31.8 + g_menu_item_set_submenu@Base 2.31.8 + g_menu_link_iter_get_name@Base 2.31.8 + g_menu_link_iter_get_next@Base 2.31.8 + g_menu_link_iter_get_type@Base 2.31.8 + g_menu_link_iter_get_value@Base 2.31.8 + g_menu_link_iter_next@Base 2.31.8 + g_menu_model_get_item_attribute@Base 2.31.8 + g_menu_model_get_item_attribute_value@Base 2.31.8 + g_menu_model_get_item_link@Base 2.31.8 + g_menu_model_get_n_items@Base 2.31.8 + g_menu_model_get_type@Base 2.31.8 + g_menu_model_is_mutable@Base 2.31.8 + g_menu_model_items_changed@Base 2.31.8 + g_menu_model_iterate_item_attributes@Base 2.31.8 + g_menu_model_iterate_item_links@Base 2.31.8 + g_menu_new@Base 2.31.8 + g_menu_prepend@Base 2.31.8 + g_menu_prepend_item@Base 2.31.8 + g_menu_prepend_section@Base 2.31.8 + g_menu_prepend_submenu@Base 2.31.8 + g_menu_remove@Base 2.31.8 + g_menu_remove_all@Base 2.37.0 + g_mount_can_eject@Base 2.16.0 + g_mount_can_unmount@Base 2.16.0 + g_mount_eject@Base 2.16.0 + g_mount_eject_finish@Base 2.16.0 + g_mount_eject_with_operation@Base 2.22.0 + g_mount_eject_with_operation_finish@Base 2.22.0 + g_mount_get_default_location@Base 2.24.0 + g_mount_get_drive@Base 2.16.0 + g_mount_get_icon@Base 2.16.0 + g_mount_get_name@Base 2.16.0 + g_mount_get_root@Base 2.16.0 + g_mount_get_sort_key@Base 2.31.8 + g_mount_get_symbolic_icon@Base 2.33.14 + g_mount_get_type@Base 2.16.0 + g_mount_get_uuid@Base 2.16.0 + g_mount_get_volume@Base 2.16.0 + g_mount_guess_content_type@Base 2.18.0 + g_mount_guess_content_type_finish@Base 2.18.0 + g_mount_guess_content_type_sync@Base 2.18.0 + g_mount_is_shadowed@Base 2.20.0 + g_mount_mount_flags_get_type@Base 2.16.0 + g_mount_operation_get_anonymous@Base 2.16.0 + g_mount_operation_get_choice@Base 2.16.0 + g_mount_operation_get_domain@Base 2.16.0 + g_mount_operation_get_is_tcrypt_hidden_volume@Base 2.57.2 + g_mount_operation_get_is_tcrypt_system_volume@Base 2.57.2 + g_mount_operation_get_password@Base 2.16.0 + g_mount_operation_get_password_save@Base 2.16.0 + g_mount_operation_get_pim@Base 2.57.2 + g_mount_operation_get_type@Base 2.16.0 + g_mount_operation_get_username@Base 2.16.0 + g_mount_operation_new@Base 2.16.0 + g_mount_operation_reply@Base 2.16.0 + g_mount_operation_result_get_type@Base 2.16.0 + g_mount_operation_set_anonymous@Base 2.16.0 + g_mount_operation_set_choice@Base 2.16.0 + g_mount_operation_set_domain@Base 2.16.0 + g_mount_operation_set_is_tcrypt_hidden_volume@Base 2.57.2 + g_mount_operation_set_is_tcrypt_system_volume@Base 2.57.2 + g_mount_operation_set_password@Base 2.16.0 + g_mount_operation_set_password_save@Base 2.16.0 + g_mount_operation_set_pim@Base 2.57.2 + g_mount_operation_set_username@Base 2.16.0 + g_mount_remount@Base 2.16.0 + g_mount_remount_finish@Base 2.16.0 + g_mount_shadow@Base 2.20.0 + g_mount_unmount@Base 2.16.0 + g_mount_unmount_finish@Base 2.16.0 + g_mount_unmount_flags_get_type@Base 2.16.0 + g_mount_unmount_with_operation@Base 2.22.0 + g_mount_unmount_with_operation_finish@Base 2.22.0 + g_mount_unshadow@Base 2.20.0 + g_native_socket_address_get_type@Base 2.45.3 + g_native_socket_address_new@Base 2.45.3 + g_native_volume_monitor_get_type@Base 2.16.0 + g_network_address_get_hostname@Base 2.22.0 + g_network_address_get_port@Base 2.22.0 + g_network_address_get_scheme@Base 2.26.0 + g_network_address_get_type@Base 2.22.0 + g_network_address_new@Base 2.22.0 + g_network_address_new_loopback@Base 2.43.2 + g_network_address_parse@Base 2.22.0 + g_network_address_parse_uri@Base 2.26.0 + g_network_connectivity_get_type@Base 2.43.2 + g_network_monitor_base_add_network@Base 2.31.8 + g_network_monitor_base_get_type@Base 2.31.8 + g_network_monitor_base_remove_network@Base 2.31.8 + g_network_monitor_base_set_networks@Base 2.31.8 + g_network_monitor_can_reach@Base 2.31.8 + g_network_monitor_can_reach_async@Base 2.31.8 + g_network_monitor_can_reach_finish@Base 2.31.8 + g_network_monitor_get_connectivity@Base 2.43.2 + g_network_monitor_get_default@Base 2.31.8 + g_network_monitor_get_network_available@Base 2.31.8 + g_network_monitor_get_network_metered@Base 2.45.6 + g_network_monitor_get_type@Base 2.31.8 + g_network_service_get_domain@Base 2.22.0 + g_network_service_get_protocol@Base 2.22.0 + g_network_service_get_scheme@Base 2.26.0 + g_network_service_get_service@Base 2.22.0 + g_network_service_get_type@Base 2.22.0 + g_network_service_new@Base 2.22.0 + g_network_service_set_scheme@Base 2.26.0 + g_networking_init@Base 2.35.8 + g_notification_add_button@Base 2.39.4 + g_notification_add_button_with_target@Base 2.39.4 + g_notification_add_button_with_target_value@Base 2.39.4 + g_notification_get_type@Base 2.39.4 + g_notification_new@Base 2.39.4 + g_notification_priority_get_type@Base 2.41.2 + g_notification_set_body@Base 2.39.4 + g_notification_set_category@Base 2.70.0 + g_notification_set_default_action@Base 2.39.4 + g_notification_set_default_action_and_target@Base 2.39.4 + g_notification_set_default_action_and_target_value@Base 2.39.4 + g_notification_set_icon@Base 2.39.4 + g_notification_set_priority@Base 2.41.2 + g_notification_set_title@Base 2.39.4 + g_notification_set_urgent@Base 2.39.4 + g_null_settings_backend_new@Base 2.28.0 + g_output_stream_clear_pending@Base 2.16.0 + g_output_stream_close@Base 2.16.0 + g_output_stream_close_async@Base 2.16.0 + g_output_stream_close_finish@Base 2.16.0 + g_output_stream_flush@Base 2.16.0 + g_output_stream_flush_async@Base 2.16.0 + g_output_stream_flush_finish@Base 2.16.0 + g_output_stream_get_type@Base 2.16.0 + g_output_stream_has_pending@Base 2.16.0 + g_output_stream_is_closed@Base 2.16.0 + g_output_stream_is_closing@Base 2.24.0 + g_output_stream_printf@Base 2.39.4 + g_output_stream_set_pending@Base 2.16.0 + g_output_stream_splice@Base 2.16.0 + g_output_stream_splice_async@Base 2.16.0 + g_output_stream_splice_finish@Base 2.16.0 + g_output_stream_splice_flags_get_type@Base 2.16.0 + g_output_stream_vprintf@Base 2.39.4 + g_output_stream_write@Base 2.16.0 + g_output_stream_write_all@Base 2.16.0 + g_output_stream_write_all_async@Base 2.43.1 + g_output_stream_write_all_finish@Base 2.43.1 + g_output_stream_write_async@Base 2.16.0 + g_output_stream_write_bytes@Base 2.33.14 + g_output_stream_write_bytes_async@Base 2.33.14 + g_output_stream_write_bytes_finish@Base 2.33.14 + g_output_stream_write_finish@Base 2.16.0 + g_output_stream_writev@Base 2.59.2 + g_output_stream_writev_all@Base 2.59.2 + g_output_stream_writev_all_async@Base 2.59.2 + g_output_stream_writev_all_finish@Base 2.59.2 + g_output_stream_writev_async@Base 2.59.2 + g_output_stream_writev_finish@Base 2.59.2 + g_password_save_get_type@Base 2.16.0 + g_permission_acquire@Base 2.26.0 + g_permission_acquire_async@Base 2.26.0 + g_permission_acquire_finish@Base 2.26.0 + g_permission_get_allowed@Base 2.26.0 + g_permission_get_can_acquire@Base 2.26.0 + g_permission_get_can_release@Base 2.26.0 + g_permission_get_type@Base 2.26.0 + g_permission_impl_update@Base 2.26.0 + g_permission_release@Base 2.26.0 + g_permission_release_async@Base 2.26.0 + g_permission_release_finish@Base 2.26.0 + g_pollable_input_stream_can_poll@Base 2.28.0 + g_pollable_input_stream_create_source@Base 2.28.0 + g_pollable_input_stream_get_type@Base 2.28.0 + g_pollable_input_stream_is_readable@Base 2.28.0 + g_pollable_input_stream_read_nonblocking@Base 2.28.0 + g_pollable_output_stream_can_poll@Base 2.28.0 + g_pollable_output_stream_create_source@Base 2.28.0 + g_pollable_output_stream_get_type@Base 2.28.0 + g_pollable_output_stream_is_writable@Base 2.28.0 + g_pollable_output_stream_write_nonblocking@Base 2.28.0 + g_pollable_output_stream_writev_nonblocking@Base 2.59.2 + g_pollable_return_get_type@Base 2.59.2 + g_pollable_source_new@Base 2.28.0 + g_pollable_source_new_full@Base 2.33.14 + g_pollable_stream_read@Base 2.33.14 + g_pollable_stream_write@Base 2.33.14 + g_pollable_stream_write_all@Base 2.33.14 + g_power_profile_monitor_dup_default@Base 2.70.0 + g_power_profile_monitor_get_power_saver_enabled@Base 2.70.0 + g_power_profile_monitor_get_type@Base 2.70.0 + g_property_action_get_type@Base 2.37.5 + g_property_action_new@Base 2.37.5 + g_proxy_address_enumerator_get_type@Base 2.26.0 + g_proxy_address_get_destination_hostname@Base 2.26.0 + g_proxy_address_get_destination_port@Base 2.26.0 + g_proxy_address_get_destination_protocol@Base 2.33.14 + g_proxy_address_get_password@Base 2.26.0 + g_proxy_address_get_protocol@Base 2.26.0 + g_proxy_address_get_type@Base 2.26.0 + g_proxy_address_get_uri@Base 2.33.14 + g_proxy_address_get_username@Base 2.26.0 + g_proxy_address_new@Base 2.26.0 + g_proxy_connect@Base 2.26.0 + g_proxy_connect_async@Base 2.26.0 + g_proxy_connect_finish@Base 2.26.0 + g_proxy_get_default_for_protocol@Base 2.26.0 + g_proxy_get_type@Base 2.26.0 + g_proxy_resolver_get_default@Base 2.26.0 + g_proxy_resolver_get_type@Base 2.26.0 + g_proxy_resolver_is_supported@Base 2.26.0 + g_proxy_resolver_lookup@Base 2.26.0 + g_proxy_resolver_lookup_async@Base 2.26.0 + g_proxy_resolver_lookup_finish@Base 2.26.0 + g_proxy_supports_hostname@Base 2.26.0 + g_remote_action_group_activate_action_full@Base 2.31.8 + g_remote_action_group_change_action_state_full@Base 2.31.8 + g_remote_action_group_get_type@Base 2.31.8 + g_resolver_error_get_type@Base 2.22.0 + g_resolver_error_quark@Base 2.22.0 + g_resolver_free_addresses@Base 2.22.0 + g_resolver_free_targets@Base 2.22.0 + g_resolver_get_default@Base 2.22.0 + g_resolver_get_type@Base 2.22.0 + g_resolver_lookup_by_address@Base 2.22.0 + g_resolver_lookup_by_address_async@Base 2.22.0 + g_resolver_lookup_by_address_finish@Base 2.22.0 + g_resolver_lookup_by_name@Base 2.22.0 + g_resolver_lookup_by_name_async@Base 2.22.0 + g_resolver_lookup_by_name_finish@Base 2.22.0 + g_resolver_lookup_by_name_with_flags@Base 2.59.0 + g_resolver_lookup_by_name_with_flags_async@Base 2.59.0 + g_resolver_lookup_by_name_with_flags_finish@Base 2.59.0 + g_resolver_lookup_records@Base 2.33.14 + g_resolver_lookup_records_async@Base 2.33.14 + g_resolver_lookup_records_finish@Base 2.33.14 + g_resolver_lookup_service@Base 2.22.0 + g_resolver_lookup_service_async@Base 2.22.0 + g_resolver_lookup_service_finish@Base 2.22.0 + g_resolver_name_lookup_flags_get_type@Base 2.59.0 + g_resolver_record_type_get_type@Base 2.33.14 + g_resolver_record_type_to_rrtype@Base 2.72.1 + g_resolver_records_from_res_query@Base 2.71.0 + g_resolver_set_default@Base 2.22.0 + g_resource_enumerate_children@Base 2.31.18 + g_resource_error_get_type@Base 2.31.18 + g_resource_error_quark@Base 2.31.18 + g_resource_flags_get_type@Base 2.31.18 + g_resource_get_info@Base 2.31.18 + g_resource_get_type@Base 2.31.18 + g_resource_load@Base 2.31.18 + g_resource_lookup_data@Base 2.31.18 + g_resource_lookup_flags_get_type@Base 2.31.18 + g_resource_new_from_data@Base 2.31.18 + g_resource_open_stream@Base 2.31.18 + g_resource_ref@Base 2.31.18 + g_resource_unref@Base 2.31.18 + g_resources_enumerate_children@Base 2.31.18 + g_resources_get_info@Base 2.31.18 + g_resources_lookup_data@Base 2.31.18 + g_resources_open_stream@Base 2.31.18 + g_resources_register@Base 2.31.18 + g_resources_unregister@Base 2.31.18 + g_seekable_can_seek@Base 2.16.0 + g_seekable_can_truncate@Base 2.16.0 + g_seekable_get_type@Base 2.16.0 + g_seekable_seek@Base 2.16.0 + g_seekable_tell@Base 2.16.0 + g_seekable_truncate@Base 2.16.0 + g_settings_apply@Base 2.26.0 + g_settings_backend_changed@Base 2.26.0 + g_settings_backend_changed_tree@Base 2.26.0 + g_settings_backend_flatten_tree@Base 2.26.0 + g_settings_backend_get_default@Base 2.28.0 + g_settings_backend_get_type@Base 2.26.0 + g_settings_backend_keys_changed@Base 2.26.0 + g_settings_backend_path_changed@Base 2.26.0 + g_settings_backend_path_writable_changed@Base 2.26.0 + g_settings_backend_writable_changed@Base 2.26.0 + g_settings_bind@Base 2.26.0 + g_settings_bind_flags_get_type@Base 2.26.0 + g_settings_bind_with_mapping@Base 2.26.0 + g_settings_bind_writable@Base 2.26.0 + g_settings_create_action@Base 2.31.18 + g_settings_delay@Base 2.26.0 + g_settings_get@Base 2.26.0 + g_settings_get_boolean@Base 2.26.0 + g_settings_get_child@Base 2.26.0 + g_settings_get_default_value@Base 2.39.4 + g_settings_get_double@Base 2.26.0 + g_settings_get_enum@Base 2.26.0 + g_settings_get_flags@Base 2.26.0 + g_settings_get_has_unapplied@Base 2.26.0 + g_settings_get_int64@Base 2.49.2 + g_settings_get_int@Base 2.26.0 + g_settings_get_mapped@Base 2.26.0 + g_settings_get_range@Base 2.28.0 + g_settings_get_string@Base 2.26.0 + g_settings_get_strv@Base 2.26.0 + g_settings_get_type@Base 2.26.0 + g_settings_get_uint64@Base 2.49.2 + g_settings_get_uint@Base 2.30.0 + g_settings_get_user_value@Base 2.39.4 + g_settings_get_value@Base 2.26.0 + g_settings_is_writable@Base 2.26.0 + g_settings_list_children@Base 2.26.0 + g_settings_list_keys@Base 2.26.0 + g_settings_list_relocatable_schemas@Base 2.28.0 + g_settings_list_schemas@Base 2.26.0 + g_settings_new@Base 2.26.0 + g_settings_new_full@Base 2.31.8 + g_settings_new_with_backend@Base 2.26.0 + g_settings_new_with_backend_and_path@Base 2.26.0 + g_settings_new_with_path@Base 2.26.0 + g_settings_range_check@Base 2.28.0 + g_settings_reset@Base 2.26.0 + g_settings_revert@Base 2.26.0 + g_settings_schema_get_id@Base 2.31.8 + g_settings_schema_get_key@Base 2.39.4 + g_settings_schema_get_path@Base 2.31.8 + g_settings_schema_get_type@Base 2.31.8 + g_settings_schema_has_key@Base 2.39.4 + g_settings_schema_key_get_default_value@Base 2.39.4 + g_settings_schema_key_get_description@Base 2.39.4 + g_settings_schema_key_get_name@Base 2.43.4 + g_settings_schema_key_get_range@Base 2.39.4 + g_settings_schema_key_get_summary@Base 2.39.4 + g_settings_schema_key_get_type@Base 2.39.4 + g_settings_schema_key_get_value_type@Base 2.39.4 + g_settings_schema_key_range_check@Base 2.39.4 + g_settings_schema_key_ref@Base 2.39.4 + g_settings_schema_key_unref@Base 2.39.4 + g_settings_schema_list_children@Base 2.43.4 + g_settings_schema_list_keys@Base 2.45.3 + g_settings_schema_ref@Base 2.31.8 + g_settings_schema_source_get_default@Base 2.31.8 + g_settings_schema_source_get_type@Base 2.31.8 + g_settings_schema_source_list_schemas@Base 2.39.4 + g_settings_schema_source_lookup@Base 2.31.8 + g_settings_schema_source_new_from_directory@Base 2.31.8 + g_settings_schema_source_ref@Base 2.31.8 + g_settings_schema_source_unref@Base 2.31.8 + g_settings_schema_unref@Base 2.31.8 + g_settings_set@Base 2.26.0 + g_settings_set_boolean@Base 2.26.0 + g_settings_set_double@Base 2.26.0 + g_settings_set_enum@Base 2.26.0 + g_settings_set_flags@Base 2.26.0 + g_settings_set_int64@Base 2.49.2 + g_settings_set_int@Base 2.26.0 + g_settings_set_string@Base 2.26.0 + g_settings_set_strv@Base 2.26.0 + g_settings_set_uint64@Base 2.49.2 + g_settings_set_uint@Base 2.30.0 + g_settings_set_value@Base 2.26.0 + g_settings_sync@Base 2.26.0 + g_settings_unbind@Base 2.26.0 + g_simple_action_get_type@Base 2.28.0 + g_simple_action_group_add_entries@Base 2.30.0 + g_simple_action_group_get_type@Base 2.28.0 + g_simple_action_group_insert@Base 2.28.0 + g_simple_action_group_lookup@Base 2.28.0 + g_simple_action_group_new@Base 2.28.0 + g_simple_action_group_remove@Base 2.28.0 + g_simple_action_new@Base 2.28.0 + g_simple_action_new_stateful@Base 2.28.0 + g_simple_action_set_enabled@Base 2.28.0 + g_simple_action_set_state@Base 2.30.0 + g_simple_action_set_state_hint@Base 2.43.4 + g_simple_async_report_error_in_idle@Base 2.16.0 + g_simple_async_report_gerror_in_idle@Base 2.16.0 + g_simple_async_report_take_gerror_in_idle@Base 2.28.0 + g_simple_async_result_complete@Base 2.16.0 + g_simple_async_result_complete_in_idle@Base 2.16.0 + g_simple_async_result_get_op_res_gboolean@Base 2.16.0 + g_simple_async_result_get_op_res_gpointer@Base 2.16.0 + g_simple_async_result_get_op_res_gssize@Base 2.16.0 + g_simple_async_result_get_source_tag@Base 2.16.0 + g_simple_async_result_get_type@Base 2.16.0 + g_simple_async_result_is_valid@Base 2.20.0 + g_simple_async_result_new@Base 2.16.0 + g_simple_async_result_new_error@Base 2.16.0 + g_simple_async_result_new_from_error@Base 2.16.0 + g_simple_async_result_new_take_error@Base 2.28.0 + g_simple_async_result_propagate_error@Base 2.16.0 + g_simple_async_result_run_in_thread@Base 2.16.0 + g_simple_async_result_set_check_cancellable@Base 2.31.22 + g_simple_async_result_set_error@Base 2.16.0 + g_simple_async_result_set_error_va@Base 2.16.0 + g_simple_async_result_set_from_error@Base 2.16.0 + g_simple_async_result_set_handle_cancellation@Base 2.16.0 + g_simple_async_result_set_op_res_gboolean@Base 2.16.0 + g_simple_async_result_set_op_res_gpointer@Base 2.16.0 + g_simple_async_result_set_op_res_gssize@Base 2.16.0 + g_simple_async_result_take_error@Base 2.28.0 + g_simple_io_stream_get_type@Base 2.43.90 + g_simple_io_stream_new@Base 2.43.90 + g_simple_permission_get_type@Base 2.26.0 + g_simple_permission_new@Base 2.26.0 + g_simple_proxy_resolver_get_type@Base 2.35.8 + g_simple_proxy_resolver_new@Base 2.35.8 + g_simple_proxy_resolver_set_default_proxy@Base 2.35.8 + g_simple_proxy_resolver_set_ignore_hosts@Base 2.35.8 + g_simple_proxy_resolver_set_uri_proxy@Base 2.35.8 + g_socket_accept@Base 2.22.0 + g_socket_address_enumerator_get_type@Base 2.22.0 + g_socket_address_enumerator_next@Base 2.22.0 + g_socket_address_enumerator_next_async@Base 2.22.0 + g_socket_address_enumerator_next_finish@Base 2.22.0 + g_socket_address_get_family@Base 2.22.0 + g_socket_address_get_native_size@Base 2.22.0 + g_socket_address_get_type@Base 2.22.0 + g_socket_address_new_from_native@Base 2.22.0 + g_socket_address_to_native@Base 2.22.0 + g_socket_bind@Base 2.22.0 + g_socket_check_connect_result@Base 2.22.0 + g_socket_client_add_application_proxy@Base 2.26.0 + g_socket_client_connect@Base 2.22.0 + g_socket_client_connect_async@Base 2.22.0 + g_socket_client_connect_finish@Base 2.22.0 + g_socket_client_connect_to_host@Base 2.22.0 + g_socket_client_connect_to_host_async@Base 2.22.0 + g_socket_client_connect_to_host_finish@Base 2.22.0 + g_socket_client_connect_to_service@Base 2.22.0 + g_socket_client_connect_to_service_async@Base 2.22.0 + g_socket_client_connect_to_service_finish@Base 2.22.0 + g_socket_client_connect_to_uri@Base 2.26.0 + g_socket_client_connect_to_uri_async@Base 2.26.0 + g_socket_client_connect_to_uri_finish@Base 2.26.0 + g_socket_client_event_get_type@Base 2.31.8 + g_socket_client_get_enable_proxy@Base 2.26.0 + g_socket_client_get_family@Base 2.22.0 + g_socket_client_get_local_address@Base 2.22.0 + g_socket_client_get_protocol@Base 2.22.0 + g_socket_client_get_proxy_resolver@Base 2.35.8 + g_socket_client_get_socket_type@Base 2.22.0 + g_socket_client_get_timeout@Base 2.26.0 + g_socket_client_get_tls@Base 2.28.0 + g_socket_client_get_tls_validation_flags@Base 2.28.0 + g_socket_client_get_type@Base 2.22.0 + g_socket_client_new@Base 2.22.0 + g_socket_client_set_enable_proxy@Base 2.26.0 + g_socket_client_set_family@Base 2.22.0 + g_socket_client_set_local_address@Base 2.22.0 + g_socket_client_set_protocol@Base 2.22.0 + g_socket_client_set_proxy_resolver@Base 2.35.8 + g_socket_client_set_socket_type@Base 2.22.0 + g_socket_client_set_timeout@Base 2.26.0 + g_socket_client_set_tls@Base 2.28.0 + g_socket_client_set_tls_validation_flags@Base 2.28.0 + g_socket_close@Base 2.22.0 + g_socket_condition_check@Base 2.22.0 + g_socket_condition_timed_wait@Base 2.31.18 + g_socket_condition_wait@Base 2.22.0 + g_socket_connect@Base 2.22.0 + g_socket_connectable_enumerate@Base 2.22.0 + g_socket_connectable_get_type@Base 2.22.0 + g_socket_connectable_proxy_enumerate@Base 2.26.0 + g_socket_connectable_to_string@Base 2.47.1 + g_socket_connection_connect@Base 2.31.8 + g_socket_connection_connect_async@Base 2.31.8 + g_socket_connection_connect_finish@Base 2.31.8 + g_socket_connection_factory_create_connection@Base 2.22.0 + g_socket_connection_factory_lookup_type@Base 2.22.0 + g_socket_connection_factory_register_type@Base 2.22.0 + g_socket_connection_get_local_address@Base 2.22.0 + g_socket_connection_get_remote_address@Base 2.22.0 + g_socket_connection_get_socket@Base 2.22.0 + g_socket_connection_get_type@Base 2.22.0 + g_socket_connection_is_connected@Base 2.31.8 + g_socket_control_message_deserialize@Base 2.22.0 + g_socket_control_message_get_level@Base 2.22.0 + g_socket_control_message_get_msg_type@Base 2.22.0 + g_socket_control_message_get_size@Base 2.22.0 + g_socket_control_message_get_type@Base 2.22.0 + g_socket_control_message_serialize@Base 2.22.0 + g_socket_create_source@Base 2.22.0 + g_socket_family_get_type@Base 2.22.0 + g_socket_get_available_bytes@Base 2.31.18 + g_socket_get_blocking@Base 2.22.0 + g_socket_get_broadcast@Base 2.31.18 + g_socket_get_credentials@Base 2.26.0 + g_socket_get_family@Base 2.22.0 + g_socket_get_fd@Base 2.22.0 + g_socket_get_keepalive@Base 2.22.0 + g_socket_get_listen_backlog@Base 2.22.0 + g_socket_get_local_address@Base 2.22.0 + g_socket_get_multicast_loopback@Base 2.31.18 + g_socket_get_multicast_ttl@Base 2.31.18 + g_socket_get_option@Base 2.35.8 + g_socket_get_protocol@Base 2.22.0 + g_socket_get_remote_address@Base 2.22.0 + g_socket_get_socket_type@Base 2.22.0 + g_socket_get_timeout@Base 2.26.0 + g_socket_get_ttl@Base 2.31.18 + g_socket_get_type@Base 2.22.0 + g_socket_is_closed@Base 2.22.0 + g_socket_is_connected@Base 2.22.0 + g_socket_join_multicast_group@Base 2.31.18 + g_socket_join_multicast_group_ssm@Base 2.55.1 + g_socket_leave_multicast_group@Base 2.31.18 + g_socket_leave_multicast_group_ssm@Base 2.55.1 + g_socket_listen@Base 2.22.0 + g_socket_listener_accept@Base 2.22.0 + g_socket_listener_accept_async@Base 2.22.0 + g_socket_listener_accept_finish@Base 2.22.0 + g_socket_listener_accept_socket@Base 2.22.0 + g_socket_listener_accept_socket_async@Base 2.22.0 + g_socket_listener_accept_socket_finish@Base 2.22.0 + g_socket_listener_add_address@Base 2.22.0 + g_socket_listener_add_any_inet_port@Base 2.24.0 + g_socket_listener_add_inet_port@Base 2.22.0 + g_socket_listener_add_socket@Base 2.22.0 + g_socket_listener_close@Base 2.22.0 + g_socket_listener_event_get_type@Base 2.45.1 + g_socket_listener_get_type@Base 2.22.0 + g_socket_listener_new@Base 2.22.0 + g_socket_listener_set_backlog@Base 2.22.0 + g_socket_msg_flags_get_type@Base 2.22.0 + g_socket_new@Base 2.22.0 + g_socket_new_from_fd@Base 2.22.0 + g_socket_protocol_get_type@Base 2.22.0 + g_socket_receive@Base 2.22.0 + g_socket_receive_from@Base 2.22.0 + g_socket_receive_message@Base 2.22.0 + g_socket_receive_messages@Base 2.47.1 + g_socket_receive_with_blocking@Base 2.26.0 + g_socket_send@Base 2.22.0 + g_socket_send_message@Base 2.22.0 + g_socket_send_message_with_timeout@Base 2.59.2 + g_socket_send_messages@Base 2.43.2 + g_socket_send_to@Base 2.22.0 + g_socket_send_with_blocking@Base 2.26.0 + g_socket_service_get_type@Base 2.22.0 + g_socket_service_is_active@Base 2.22.0 + g_socket_service_new@Base 2.22.0 + g_socket_service_start@Base 2.22.0 + g_socket_service_stop@Base 2.22.0 + g_socket_set_blocking@Base 2.22.0 + g_socket_set_broadcast@Base 2.31.18 + g_socket_set_keepalive@Base 2.22.0 + g_socket_set_listen_backlog@Base 2.22.0 + g_socket_set_multicast_loopback@Base 2.31.18 + g_socket_set_multicast_ttl@Base 2.31.18 + g_socket_set_option@Base 2.35.8 + g_socket_set_timeout@Base 2.26.0 + g_socket_set_ttl@Base 2.31.18 + g_socket_shutdown@Base 2.22.0 + g_socket_speaks_ipv4@Base 2.22.0 + g_socket_type_get_type@Base 2.22.0 + g_srv_target_copy@Base 2.22.0 + g_srv_target_free@Base 2.22.0 + g_srv_target_get_hostname@Base 2.22.0 + g_srv_target_get_port@Base 2.22.0 + g_srv_target_get_priority@Base 2.22.0 + g_srv_target_get_type@Base 2.22.0 + g_srv_target_get_weight@Base 2.22.0 + g_srv_target_list_sort@Base 2.22.0 + g_srv_target_new@Base 2.22.0 + g_static_resource_fini@Base 2.31.18 + g_static_resource_get_resource@Base 2.31.18 + g_static_resource_init@Base 2.31.18 + g_subprocess_communicate@Base 2.39.4 + g_subprocess_communicate_async@Base 2.39.4 + g_subprocess_communicate_finish@Base 2.39.4 + g_subprocess_communicate_utf8@Base 2.39.4 + g_subprocess_communicate_utf8_async@Base 2.39.4 + g_subprocess_communicate_utf8_finish@Base 2.39.4 + g_subprocess_flags_get_type@Base 2.39.4 + g_subprocess_force_exit@Base 2.39.4 + g_subprocess_get_exit_status@Base 2.39.4 + g_subprocess_get_identifier@Base 2.39.4 + g_subprocess_get_if_exited@Base 2.39.4 + g_subprocess_get_if_signaled@Base 2.39.4 + g_subprocess_get_status@Base 2.39.4 + g_subprocess_get_stderr_pipe@Base 2.39.4 + g_subprocess_get_stdin_pipe@Base 2.39.4 + g_subprocess_get_stdout_pipe@Base 2.39.4 + g_subprocess_get_successful@Base 2.39.4 + g_subprocess_get_term_sig@Base 2.39.4 + g_subprocess_get_type@Base 2.39.4 + g_subprocess_launcher_close@Base 2.67.1 + g_subprocess_launcher_get_type@Base 2.39.4 + g_subprocess_launcher_getenv@Base 2.39.4 + g_subprocess_launcher_new@Base 2.39.4 + g_subprocess_launcher_set_child_setup@Base 2.39.4 + g_subprocess_launcher_set_cwd@Base 2.39.4 + g_subprocess_launcher_set_environ@Base 2.39.4 + g_subprocess_launcher_set_flags@Base 2.39.4 + g_subprocess_launcher_set_stderr_file_path@Base 2.39.4 + g_subprocess_launcher_set_stdin_file_path@Base 2.39.4 + g_subprocess_launcher_set_stdout_file_path@Base 2.39.4 + g_subprocess_launcher_setenv@Base 2.39.4 + g_subprocess_launcher_spawn@Base 2.39.4 + g_subprocess_launcher_spawnv@Base 2.39.4 + g_subprocess_launcher_take_fd@Base 2.39.4 + g_subprocess_launcher_take_stderr_fd@Base 2.39.4 + g_subprocess_launcher_take_stdin_fd@Base 2.39.4 + g_subprocess_launcher_take_stdout_fd@Base 2.39.4 + g_subprocess_launcher_unsetenv@Base 2.39.4 + g_subprocess_new@Base 2.39.4 + g_subprocess_newv@Base 2.39.4 + g_subprocess_send_signal@Base 2.39.4 + g_subprocess_wait@Base 2.39.4 + g_subprocess_wait_async@Base 2.39.4 + g_subprocess_wait_check@Base 2.39.4 + g_subprocess_wait_check_async@Base 2.39.4 + g_subprocess_wait_check_finish@Base 2.39.4 + g_subprocess_wait_finish@Base 2.39.4 + g_task_attach_source@Base 2.35.8 + g_task_get_cancellable@Base 2.35.8 + g_task_get_check_cancellable@Base 2.35.8 + g_task_get_completed@Base 2.43.92 + g_task_get_context@Base 2.35.8 + g_task_get_name@Base 2.59.0 + g_task_get_priority@Base 2.35.8 + g_task_get_return_on_cancel@Base 2.35.8 + g_task_get_source_object@Base 2.35.8 + g_task_get_source_tag@Base 2.35.8 + g_task_get_task_data@Base 2.35.8 + g_task_get_type@Base 2.35.8 + g_task_had_error@Base 2.35.8 + g_task_is_valid@Base 2.35.8 + g_task_new@Base 2.35.8 + g_task_propagate_boolean@Base 2.35.8 + g_task_propagate_int@Base 2.35.8 + g_task_propagate_pointer@Base 2.35.8 + g_task_propagate_value@Base 2.63.2 + g_task_report_error@Base 2.35.8 + g_task_report_new_error@Base 2.35.8 + g_task_return_boolean@Base 2.35.8 + g_task_return_error@Base 2.35.8 + g_task_return_error_if_cancelled@Base 2.35.8 + g_task_return_int@Base 2.35.8 + g_task_return_new_error@Base 2.35.8 + g_task_return_pointer@Base 2.35.8 + g_task_return_value@Base 2.63.2 + g_task_run_in_thread@Base 2.35.8 + g_task_run_in_thread_sync@Base 2.35.8 + g_task_set_check_cancellable@Base 2.35.8 + g_task_set_name@Base 2.59.0 + g_task_set_priority@Base 2.35.8 + g_task_set_return_on_cancel@Base 2.35.8 + g_task_set_source_tag@Base 2.35.8 + g_task_set_task_data@Base 2.35.8 + g_tcp_connection_get_graceful_disconnect@Base 2.22.0 + g_tcp_connection_get_type@Base 2.22.0 + g_tcp_connection_set_graceful_disconnect@Base 2.22.0 + g_tcp_wrapper_connection_get_base_io_stream@Base 2.28.0 + g_tcp_wrapper_connection_get_type@Base 2.28.0 + g_tcp_wrapper_connection_new@Base 2.28.0 + g_test_dbus_add_service_dir@Base 2.33.14 + g_test_dbus_down@Base 2.33.14 + g_test_dbus_flags_get_type@Base 2.33.14 + g_test_dbus_get_bus_address@Base 2.33.14 + g_test_dbus_get_flags@Base 2.33.14 + g_test_dbus_get_type@Base 2.33.14 + g_test_dbus_new@Base 2.33.14 + g_test_dbus_stop@Base 2.33.14 + g_test_dbus_unset@Base 2.33.14 + g_test_dbus_up@Base 2.33.14 + g_themed_icon_append_name@Base 2.16.0 + g_themed_icon_get_names@Base 2.16.0 + g_themed_icon_get_type@Base 2.16.0 + g_themed_icon_new@Base 2.16.0 + g_themed_icon_new_from_names@Base 2.16.0 + g_themed_icon_new_with_default_fallbacks@Base 2.16.0 + g_themed_icon_prepend_name@Base 2.18.0 + g_threaded_resolver_get_type@Base 2.22.0 + g_threaded_socket_service_get_type@Base 2.22.0 + g_threaded_socket_service_new@Base 2.22.0 + g_tls_authentication_mode_get_type@Base 2.28.0 + g_tls_backend_get_certificate_type@Base 2.28.0 + g_tls_backend_get_client_connection_type@Base 2.28.0 + g_tls_backend_get_default@Base 2.28.0 + g_tls_backend_get_default_database@Base 2.30.0 + g_tls_backend_get_dtls_client_connection_type@Base 2.47.5 + g_tls_backend_get_dtls_server_connection_type@Base 2.47.5 + g_tls_backend_get_file_database_type@Base 2.30.0 + g_tls_backend_get_server_connection_type@Base 2.28.0 + g_tls_backend_get_type@Base 2.28.0 + g_tls_backend_set_default_database@Base 2.59.0 + g_tls_backend_supports_dtls@Base 2.47.5 + g_tls_backend_supports_tls@Base 2.28.0 + g_tls_certificate_flags_get_type@Base 2.28.0 + g_tls_certificate_get_dns_names@Base 2.70.0 + g_tls_certificate_get_ip_addresses@Base 2.70.0 + g_tls_certificate_get_issuer@Base 2.28.0 + g_tls_certificate_get_issuer_name@Base 2.70.0 + g_tls_certificate_get_not_valid_after@Base 2.70.0 + g_tls_certificate_get_not_valid_before@Base 2.70.0 + g_tls_certificate_get_subject_name@Base 2.70.0 + g_tls_certificate_get_type@Base 2.28.0 + g_tls_certificate_is_same@Base 2.33.14 + g_tls_certificate_list_new_from_file@Base 2.28.0 + g_tls_certificate_new_from_file@Base 2.28.0 + g_tls_certificate_new_from_file_with_password@Base 2.71.1 + g_tls_certificate_new_from_files@Base 2.28.0 + g_tls_certificate_new_from_pem@Base 2.28.0 + g_tls_certificate_new_from_pkcs11_uris@Base 2.67.1 + g_tls_certificate_new_from_pkcs12@Base 2.71.1 + g_tls_certificate_request_flags_get_type@Base 2.39.4 + g_tls_certificate_verify@Base 2.28.0 + g_tls_channel_binding_error_get_type@Base 2.65.1 + g_tls_channel_binding_error_quark@Base 2.65.1 + g_tls_channel_binding_type_get_type@Base 2.65.1 + g_tls_client_connection_copy_session_state@Base 2.45.1 + g_tls_client_connection_get_accepted_cas@Base 2.28.0 + g_tls_client_connection_get_server_identity@Base 2.28.0 + g_tls_client_connection_get_type@Base 2.28.0 + g_tls_client_connection_get_use_ssl3@Base 2.28.0 + g_tls_client_connection_get_validation_flags@Base 2.28.0 + g_tls_client_connection_new@Base 2.28.0 + g_tls_client_connection_set_server_identity@Base 2.28.0 + g_tls_client_connection_set_use_ssl3@Base 2.28.0 + g_tls_client_connection_set_validation_flags@Base 2.28.0 + g_tls_connection_emit_accept_certificate@Base 2.28.0 + g_tls_connection_get_certificate@Base 2.28.0 + g_tls_connection_get_channel_binding_data@Base 2.65.1 + g_tls_connection_get_ciphersuite_name@Base 2.70.0 + g_tls_connection_get_database@Base 2.30.0 + g_tls_connection_get_interaction@Base 2.30.0 + g_tls_connection_get_negotiated_protocol@Base 2.59.0 + g_tls_connection_get_peer_certificate@Base 2.28.0 + g_tls_connection_get_peer_certificate_errors@Base 2.28.0 + g_tls_connection_get_protocol_version@Base 2.70.0 + g_tls_connection_get_rehandshake_mode@Base 2.28.0 + g_tls_connection_get_require_close_notify@Base 2.28.0 + g_tls_connection_get_type@Base 2.28.0 + g_tls_connection_get_use_system_certdb@Base 2.28.0 + g_tls_connection_handshake@Base 2.28.0 + g_tls_connection_handshake_async@Base 2.28.0 + g_tls_connection_handshake_finish@Base 2.28.0 + g_tls_connection_set_advertised_protocols@Base 2.59.0 + g_tls_connection_set_certificate@Base 2.28.0 + g_tls_connection_set_database@Base 2.30.0 + g_tls_connection_set_interaction@Base 2.30.0 + g_tls_connection_set_rehandshake_mode@Base 2.28.0 + g_tls_connection_set_require_close_notify@Base 2.28.0 + g_tls_connection_set_use_system_certdb@Base 2.28.0 + g_tls_database_create_certificate_handle@Base 2.30.0 + g_tls_database_get_type@Base 2.30.0 + g_tls_database_lookup_certificate_for_handle@Base 2.30.0 + g_tls_database_lookup_certificate_for_handle_async@Base 2.30.0 + g_tls_database_lookup_certificate_for_handle_finish@Base 2.30.0 + g_tls_database_lookup_certificate_issuer@Base 2.30.0 + g_tls_database_lookup_certificate_issuer_async@Base 2.30.0 + g_tls_database_lookup_certificate_issuer_finish@Base 2.30.0 + g_tls_database_lookup_certificates_issued_by@Base 2.30.0 + g_tls_database_lookup_certificates_issued_by_async@Base 2.30.0 + g_tls_database_lookup_certificates_issued_by_finish@Base 2.30.0 + g_tls_database_lookup_flags_get_type@Base 2.30.0 + g_tls_database_verify_chain@Base 2.30.0 + g_tls_database_verify_chain_async@Base 2.30.0 + g_tls_database_verify_chain_finish@Base 2.30.0 + g_tls_database_verify_flags_get_type@Base 2.30.0 + g_tls_error_get_type@Base 2.28.0 + g_tls_error_quark@Base 2.28.0 + g_tls_file_database_get_type@Base 2.30.0 + g_tls_file_database_new@Base 2.30.0 + g_tls_interaction_ask_password@Base 2.30.0 + g_tls_interaction_ask_password_async@Base 2.30.0 + g_tls_interaction_ask_password_finish@Base 2.30.0 + g_tls_interaction_get_type@Base 2.30.0 + g_tls_interaction_invoke_ask_password@Base 2.30.0 + g_tls_interaction_invoke_request_certificate@Base 2.39.4 + g_tls_interaction_request_certificate@Base 2.39.4 + g_tls_interaction_request_certificate_async@Base 2.39.4 + g_tls_interaction_request_certificate_finish@Base 2.39.4 + g_tls_interaction_result_get_type@Base 2.30.0 + g_tls_password_flags_get_type@Base 2.30.0 + g_tls_password_get_description@Base 2.30.0 + g_tls_password_get_flags@Base 2.30.0 + g_tls_password_get_type@Base 2.30.0 + g_tls_password_get_value@Base 2.30.0 + g_tls_password_get_warning@Base 2.30.0 + g_tls_password_new@Base 2.30.0 + g_tls_password_set_description@Base 2.30.0 + g_tls_password_set_flags@Base 2.30.0 + g_tls_password_set_value@Base 2.30.0 + g_tls_password_set_value_full@Base 2.30.0 + g_tls_password_set_warning@Base 2.30.0 + g_tls_protocol_version_get_type@Base 2.70.0 + g_tls_rehandshake_mode_get_type@Base 2.28.0 + g_tls_server_connection_get_type@Base 2.28.0 + g_tls_server_connection_new@Base 2.28.0 + g_unix_connection_get_type@Base 2.22.0 + g_unix_connection_receive_credentials@Base 2.26.0 + g_unix_connection_receive_credentials_async@Base 2.31.18 + g_unix_connection_receive_credentials_finish@Base 2.31.18 + g_unix_connection_receive_fd@Base 2.22.0 + g_unix_connection_send_credentials@Base 2.26.0 + g_unix_connection_send_credentials_async@Base 2.31.18 + g_unix_connection_send_credentials_finish@Base 2.31.18 + g_unix_connection_send_fd@Base 2.22.0 + g_unix_credentials_message_get_credentials@Base 2.26.0 + g_unix_credentials_message_get_type@Base 2.26.0 + g_unix_credentials_message_is_supported@Base 2.26.0 + g_unix_credentials_message_new@Base 2.26.0 + g_unix_credentials_message_new_with_credentials@Base 2.26.0 + g_unix_fd_list_append@Base 2.24.0 + g_unix_fd_list_get@Base 2.24.0 + g_unix_fd_list_get_length@Base 2.24.0 + g_unix_fd_list_get_type@Base 2.24.0 + g_unix_fd_list_new@Base 2.24.0 + g_unix_fd_list_new_from_array@Base 2.24.0 + g_unix_fd_list_peek_fds@Base 2.24.0 + g_unix_fd_list_steal_fds@Base 2.24.0 + g_unix_fd_message_append_fd@Base 2.22.0 + g_unix_fd_message_get_fd_list@Base 2.24.0 + g_unix_fd_message_get_type@Base 2.22.0 + g_unix_fd_message_new@Base 2.22.0 + g_unix_fd_message_new_with_fd_list@Base 2.24.0 + g_unix_fd_message_steal_fds@Base 2.22.0 + g_unix_input_stream_get_close_fd@Base 2.20.0 + g_unix_input_stream_get_fd@Base 2.20.0 + g_unix_input_stream_get_type@Base 2.16.0 + g_unix_input_stream_new@Base 2.16.0 + g_unix_input_stream_set_close_fd@Base 2.20.0 + g_unix_is_mount_path_system_internal@Base 2.16.0 + g_unix_is_system_device_path@Base 2.55.1 + g_unix_is_system_fs_type@Base 2.55.1 + g_unix_mount_at@Base 2.16.0 + g_unix_mount_compare@Base 2.16.0 + g_unix_mount_copy@Base 2.53.1 + g_unix_mount_entry_get_type@Base 2.53.1 + g_unix_mount_for@Base 2.51.0 + g_unix_mount_free@Base 2.16.0 + g_unix_mount_get_device_path@Base 2.16.0 + g_unix_mount_get_fs_type@Base 2.16.0 + g_unix_mount_get_mount_path@Base 2.16.0 + g_unix_mount_get_options@Base 2.57.2 + g_unix_mount_get_root_path@Base 2.59.0 + g_unix_mount_guess_can_eject@Base 2.16.0 + g_unix_mount_guess_icon@Base 2.16.0 + g_unix_mount_guess_name@Base 2.16.0 + g_unix_mount_guess_should_display@Base 2.16.0 + g_unix_mount_guess_symbolic_icon@Base 2.33.14 + g_unix_mount_is_readonly@Base 2.16.0 + g_unix_mount_is_system_internal@Base 2.16.0 + g_unix_mount_monitor_get@Base 2.43.92 + g_unix_mount_monitor_get_type@Base 2.16.0 + g_unix_mount_monitor_new@Base 2.16.0 + g_unix_mount_monitor_set_rate_limit@Base 2.18.0 + g_unix_mount_point_at@Base 2.65.1 + g_unix_mount_point_compare@Base 2.16.0 + g_unix_mount_point_copy@Base 2.53.1 + g_unix_mount_point_free@Base 2.16.0 + g_unix_mount_point_get_device_path@Base 2.16.0 + g_unix_mount_point_get_fs_type@Base 2.16.0 + g_unix_mount_point_get_mount_path@Base 2.16.0 + g_unix_mount_point_get_options@Base 2.31.8 + g_unix_mount_point_get_type@Base 2.53.1 + g_unix_mount_point_guess_can_eject@Base 2.16.0 + g_unix_mount_point_guess_icon@Base 2.16.0 + g_unix_mount_point_guess_name@Base 2.16.0 + g_unix_mount_point_guess_symbolic_icon@Base 2.33.14 + g_unix_mount_point_is_loopback@Base 2.16.0 + g_unix_mount_point_is_readonly@Base 2.16.0 + g_unix_mount_point_is_user_mountable@Base 2.16.0 + g_unix_mount_points_changed_since@Base 2.16.0 + g_unix_mount_points_get@Base 2.16.0 + g_unix_mounts_changed_since@Base 2.16.0 + g_unix_mounts_get@Base 2.16.0 + g_unix_output_stream_get_close_fd@Base 2.20.0 + g_unix_output_stream_get_fd@Base 2.20.0 + g_unix_output_stream_get_type@Base 2.16.0 + g_unix_output_stream_new@Base 2.16.0 + g_unix_output_stream_set_close_fd@Base 2.20.0 + g_unix_socket_address_abstract_names_supported@Base 2.22.0 + g_unix_socket_address_get_address_type@Base 2.26.0 + g_unix_socket_address_get_is_abstract@Base 2.22.0 + g_unix_socket_address_get_path@Base 2.22.0 + g_unix_socket_address_get_path_len@Base 2.22.0 + g_unix_socket_address_get_type@Base 2.22.0 + g_unix_socket_address_new@Base 2.22.0 + g_unix_socket_address_new_abstract@Base 2.22.0 + g_unix_socket_address_new_with_type@Base 2.26.0 + g_unix_socket_address_type_get_type@Base 2.26.0 + g_vfs_get_default@Base 2.16.0 + g_vfs_get_file_for_path@Base 2.16.0 + g_vfs_get_file_for_uri@Base 2.16.0 + g_vfs_get_local@Base 2.16.0 + g_vfs_get_supported_uri_schemes@Base 2.16.0 + g_vfs_get_type@Base 2.16.0 + g_vfs_is_active@Base 2.16.0 + g_vfs_parse_name@Base 2.16.0 + g_vfs_register_uri_scheme@Base 2.49.3 + g_vfs_unregister_uri_scheme@Base 2.49.3 + g_volume_can_eject@Base 2.16.0 + g_volume_can_mount@Base 2.16.0 + g_volume_eject@Base 2.16.0 + g_volume_eject_finish@Base 2.16.0 + g_volume_eject_with_operation@Base 2.22.0 + g_volume_eject_with_operation_finish@Base 2.22.0 + g_volume_enumerate_identifiers@Base 2.16.0 + g_volume_get_activation_root@Base 2.18.0 + g_volume_get_drive@Base 2.16.0 + g_volume_get_icon@Base 2.16.0 + g_volume_get_identifier@Base 2.16.0 + g_volume_get_mount@Base 2.16.0 + g_volume_get_name@Base 2.16.0 + g_volume_get_sort_key@Base 2.31.8 + g_volume_get_symbolic_icon@Base 2.33.14 + g_volume_get_type@Base 2.16.0 + g_volume_get_uuid@Base 2.16.0 + g_volume_monitor_adopt_orphan_mount@Base 2.16.0 + g_volume_monitor_get@Base 2.16.0 + g_volume_monitor_get_connected_drives@Base 2.16.0 + g_volume_monitor_get_mount_for_uuid@Base 2.16.0 + g_volume_monitor_get_mounts@Base 2.16.0 + g_volume_monitor_get_type@Base 2.16.0 + g_volume_monitor_get_volume_for_uuid@Base 2.16.0 + g_volume_monitor_get_volumes@Base 2.16.0 + g_volume_mount@Base 2.16.0 + g_volume_mount_finish@Base 2.16.0 + g_volume_should_automount@Base 2.16.0 + g_zlib_compressor_format_get_type@Base 2.24.0 + g_zlib_compressor_get_file_info@Base 2.26.0 + g_zlib_compressor_get_type@Base 2.24.0 + g_zlib_compressor_new@Base 2.24.0 + g_zlib_compressor_set_file_info@Base 2.26.0 + g_zlib_decompressor_get_file_info@Base 2.26.0 + g_zlib_decompressor_get_type@Base 2.24.0 + g_zlib_decompressor_new@Base 2.24.0 +libglib-2.0.so.0 libglib2.0-0 #MINVER# +* Build-Depends-Package: libglib2.0-dev + __glib_assert_msg@Base 2.37.6 + g_access@Base 2.12.0 + g_aligned_alloc@Base 2.71.2 + g_aligned_alloc0@Base 2.71.2 + g_aligned_free@Base 2.71.2 + g_allocator_free@Base 2.12.0 + g_allocator_new@Base 2.12.0 + g_array_append_vals@Base 2.12.0 + g_array_binary_search@Base 2.61.2 + g_array_copy@Base 2.61.2 + g_array_free@Base 2.12.0 + g_array_get_element_size@Base 2.22.0 + g_array_insert_vals@Base 2.12.0 + g_array_new@Base 2.12.0 + g_array_prepend_vals@Base 2.12.0 + g_array_ref@Base 2.22.0 + g_array_remove_index@Base 2.12.0 + g_array_remove_index_fast@Base 2.12.0 + g_array_remove_range@Base 2.12.0 + g_array_set_clear_func@Base 2.31.18 + g_array_set_size@Base 2.12.0 + g_array_sized_new@Base 2.12.0 + g_array_sort@Base 2.12.0 + g_array_sort_with_data@Base 2.12.0 + g_array_steal@Base 2.63.1 + g_array_unref@Base 2.22.0 + g_ascii_digit_value@Base 2.12.0 + g_ascii_dtostr@Base 2.12.0 + g_ascii_formatd@Base 2.12.0 + g_ascii_strcasecmp@Base 2.12.0 + g_ascii_strdown@Base 2.12.0 + g_ascii_string_to_signed@Base 2.53.2 + g_ascii_string_to_unsigned@Base 2.53.2 + g_ascii_strncasecmp@Base 2.12.0 + g_ascii_strtod@Base 2.12.0 + g_ascii_strtoll@Base 2.12.0 + g_ascii_strtoull@Base 2.12.0 + g_ascii_strup@Base 2.12.0 + g_ascii_table@Base 2.12.0 + g_ascii_tolower@Base 2.12.0 + g_ascii_toupper@Base 2.12.0 + g_ascii_xdigit_value@Base 2.12.0 + g_assert_warning@Base 2.12.0 + g_assertion_message@Base 2.16.0 + g_assertion_message_cmpnum@Base 2.16.0 + g_assertion_message_cmpstr@Base 2.16.0 + g_assertion_message_cmpstrv@Base 2.67.1 + g_assertion_message_error@Base 2.20.0 + g_assertion_message_expr@Base 2.16.0 + g_async_queue_length@Base 2.12.0 + g_async_queue_length_unlocked@Base 2.12.0 + g_async_queue_lock@Base 2.12.0 + g_async_queue_new@Base 2.12.0 + g_async_queue_new_full@Base 2.16.0 + g_async_queue_pop@Base 2.12.0 + g_async_queue_pop_unlocked@Base 2.12.0 + g_async_queue_push@Base 2.12.0 + g_async_queue_push_front@Base 2.45.4 + g_async_queue_push_front_unlocked@Base 2.45.4 + g_async_queue_push_sorted@Base 2.12.0 + g_async_queue_push_sorted_unlocked@Base 2.12.0 + g_async_queue_push_unlocked@Base 2.12.0 + g_async_queue_ref@Base 2.12.0 + g_async_queue_ref_unlocked@Base 2.12.0 + g_async_queue_remove@Base 2.45.4 + g_async_queue_remove_unlocked@Base 2.45.4 + g_async_queue_sort@Base 2.12.0 + g_async_queue_sort_unlocked@Base 2.12.0 + g_async_queue_timed_pop@Base 2.12.0 + g_async_queue_timed_pop_unlocked@Base 2.12.0 + g_async_queue_timeout_pop@Base 2.31.18 + g_async_queue_timeout_pop_unlocked@Base 2.31.18 + g_async_queue_try_pop@Base 2.12.0 + g_async_queue_try_pop_unlocked@Base 2.12.0 + g_async_queue_unlock@Base 2.12.0 + g_async_queue_unref@Base 2.12.0 + g_async_queue_unref_and_unlock@Base 2.12.0 + g_atexit@Base 2.12.0 + g_atomic_int_add@Base 2.12.0 + g_atomic_int_and@Base 2.30.0 + g_atomic_int_compare_and_exchange@Base 2.12.0 + g_atomic_int_dec_and_test@Base 2.30.0 + g_atomic_int_exchange_and_add@Base 2.12.0 + g_atomic_int_get@Base 2.12.0 + g_atomic_int_inc@Base 2.30.0 + g_atomic_int_or@Base 2.30.0 + g_atomic_int_set@Base 2.12.0 + g_atomic_int_xor@Base 2.30.0 + g_atomic_pointer_add@Base 2.30.0 + g_atomic_pointer_and@Base 2.30.0 + g_atomic_pointer_compare_and_exchange@Base 2.12.0 + g_atomic_pointer_get@Base 2.12.0 + g_atomic_pointer_or@Base 2.30.0 + g_atomic_pointer_set@Base 2.12.0 + g_atomic_pointer_xor@Base 2.30.0 + g_atomic_rc_box_acquire@Base 2.57.2 + g_atomic_rc_box_alloc@Base 2.57.2 + g_atomic_rc_box_alloc0@Base 2.57.2 + g_atomic_rc_box_dup@Base 2.57.2 + g_atomic_rc_box_get_size@Base 2.57.2 + g_atomic_rc_box_release@Base 2.57.2 + g_atomic_rc_box_release_full@Base 2.57.2 + g_atomic_ref_count_compare@Base 2.57.2 + g_atomic_ref_count_dec@Base 2.57.2 + g_atomic_ref_count_inc@Base 2.57.2 + g_atomic_ref_count_init@Base 2.57.2 + g_base64_decode@Base 2.12.0 + g_base64_decode_inplace@Base 2.20.0 + g_base64_decode_step@Base 2.12.0 + g_base64_encode@Base 2.12.0 + g_base64_encode_close@Base 2.12.0 + g_base64_encode_step@Base 2.12.0 + g_basename@Base 2.12.0 + g_bit_lock@Base 2.24.0 + g_bit_nth_lsf@Base 2.12.0 + g_bit_nth_msf@Base 2.12.0 + g_bit_storage@Base 2.12.0 + g_bit_trylock@Base 2.24.0 + g_bit_unlock@Base 2.24.0 + g_blow_chunks@Base 2.12.0 + g_bookmark_file_add_application@Base 2.12.0 + g_bookmark_file_add_group@Base 2.12.0 + g_bookmark_file_error_quark@Base 2.12.0 + g_bookmark_file_free@Base 2.12.0 + g_bookmark_file_get_added@Base 2.12.0 + g_bookmark_file_get_added_date_time@Base 2.65.1 + g_bookmark_file_get_app_info@Base 2.12.0 + g_bookmark_file_get_application_info@Base 2.65.1 + g_bookmark_file_get_applications@Base 2.12.0 + g_bookmark_file_get_description@Base 2.12.0 + g_bookmark_file_get_groups@Base 2.12.0 + g_bookmark_file_get_icon@Base 2.12.0 + g_bookmark_file_get_is_private@Base 2.12.0 + g_bookmark_file_get_mime_type@Base 2.12.0 + g_bookmark_file_get_modified@Base 2.12.0 + g_bookmark_file_get_modified_date_time@Base 2.65.1 + g_bookmark_file_get_size@Base 2.12.0 + g_bookmark_file_get_title@Base 2.12.0 + g_bookmark_file_get_uris@Base 2.12.0 + g_bookmark_file_get_visited@Base 2.12.0 + g_bookmark_file_get_visited_date_time@Base 2.65.1 + g_bookmark_file_has_application@Base 2.12.0 + g_bookmark_file_has_group@Base 2.12.0 + g_bookmark_file_has_item@Base 2.12.0 + g_bookmark_file_load_from_data@Base 2.12.0 + g_bookmark_file_load_from_data_dirs@Base 2.12.0 + g_bookmark_file_load_from_file@Base 2.12.0 + g_bookmark_file_move_item@Base 2.12.0 + g_bookmark_file_new@Base 2.12.0 + g_bookmark_file_remove_application@Base 2.12.0 + g_bookmark_file_remove_group@Base 2.12.0 + g_bookmark_file_remove_item@Base 2.12.0 + g_bookmark_file_set_added@Base 2.12.0 + g_bookmark_file_set_added_date_time@Base 2.65.1 + g_bookmark_file_set_app_info@Base 2.12.0 + g_bookmark_file_set_application_info@Base 2.65.1 + g_bookmark_file_set_description@Base 2.12.0 + g_bookmark_file_set_groups@Base 2.12.0 + g_bookmark_file_set_icon@Base 2.12.0 + g_bookmark_file_set_is_private@Base 2.12.0 + g_bookmark_file_set_mime_type@Base 2.12.0 + g_bookmark_file_set_modified@Base 2.12.0 + g_bookmark_file_set_modified_date_time@Base 2.65.1 + g_bookmark_file_set_title@Base 2.12.0 + g_bookmark_file_set_visited@Base 2.12.0 + g_bookmark_file_set_visited_date_time@Base 2.65.1 + g_bookmark_file_to_data@Base 2.12.0 + g_bookmark_file_to_file@Base 2.12.0 + g_build_filename@Base 2.12.0 + g_build_filename_valist@Base 2.55.1 + g_build_filenamev@Base 2.12.0 + g_build_path@Base 2.12.0 + g_build_pathv@Base 2.12.0 + g_byte_array_append@Base 2.12.0 + g_byte_array_free@Base 2.12.0 + g_byte_array_free_to_bytes@Base 2.31.8 + g_byte_array_new@Base 2.12.0 + g_byte_array_new_take@Base 2.31.8 + g_byte_array_prepend@Base 2.12.0 + g_byte_array_ref@Base 2.22.0 + g_byte_array_remove_index@Base 2.12.0 + g_byte_array_remove_index_fast@Base 2.12.0 + g_byte_array_remove_range@Base 2.12.0 + g_byte_array_set_size@Base 2.12.0 + g_byte_array_sized_new@Base 2.12.0 + g_byte_array_sort@Base 2.12.0 + g_byte_array_sort_with_data@Base 2.12.0 + g_byte_array_steal@Base 2.63.1 + g_byte_array_unref@Base 2.22.0 + g_bytes_compare@Base 2.31.8 + g_bytes_equal@Base 2.31.8 + g_bytes_get_data@Base 2.31.8 + g_bytes_get_region@Base 2.70.0 + g_bytes_get_size@Base 2.31.8 + g_bytes_hash@Base 2.31.8 + g_bytes_new@Base 2.31.8 + g_bytes_new_from_bytes@Base 2.31.8 + g_bytes_new_static@Base 2.31.8 + g_bytes_new_take@Base 2.31.8 + g_bytes_new_with_free_func@Base 2.31.8 + g_bytes_ref@Base 2.31.8 + g_bytes_unref@Base 2.31.8 + g_bytes_unref_to_array@Base 2.31.8 + g_bytes_unref_to_data@Base 2.31.8 + g_cache_destroy@Base 2.12.0 + g_cache_insert@Base 2.12.0 + g_cache_key_foreach@Base 2.12.0 + g_cache_new@Base 2.12.0 + g_cache_remove@Base 2.12.0 + g_cache_value_foreach@Base 2.12.0 + g_canonicalize_filename@Base 2.57.2 + g_chdir@Base 2.12.0 + g_checksum_copy@Base 2.16.0 + g_checksum_free@Base 2.16.0 + g_checksum_get_digest@Base 2.16.0 + g_checksum_get_string@Base 2.16.0 + g_checksum_new@Base 2.16.0 + g_checksum_reset@Base 2.18.0 + g_checksum_type_get_length@Base 2.16.0 + g_checksum_update@Base 2.16.0 + g_child_watch_add@Base 2.12.0 + g_child_watch_add_full@Base 2.12.0 + g_child_watch_funcs@Base 2.12.0 + g_child_watch_source_new@Base 2.12.0 + g_chmod@Base 2.12.0 + g_clear_error@Base 2.12.0 + g_clear_handle_id@Base 2.55.1 + g_clear_list@Base 2.63.3 + g_clear_pointer@Base 2.33.14 + g_clear_slist@Base 2.63.3 + g_close@Base 2.35.8 + g_completion_add_items@Base 2.12.0 + g_completion_clear_items@Base 2.12.0 + g_completion_complete@Base 2.12.0 + g_completion_complete_utf8@Base 2.12.0 + g_completion_free@Base 2.12.0 + g_completion_new@Base 2.12.0 + g_completion_remove_items@Base 2.12.0 + g_completion_set_compare@Base 2.12.0 + g_compute_checksum_for_bytes@Base 2.33.14 + g_compute_checksum_for_data@Base 2.16.0 + g_compute_checksum_for_string@Base 2.16.0 + g_compute_hmac_for_bytes@Base 2.49.3 + g_compute_hmac_for_data@Base 2.30.0 + g_compute_hmac_for_string@Base 2.30.0 + g_cond_broadcast@Base 2.31.8 + g_cond_clear@Base 2.31.8 + g_cond_free@Base 2.31.8 + g_cond_init@Base 2.31.8 + g_cond_new@Base 2.31.8 + g_cond_signal@Base 2.31.8 + g_cond_timed_wait@Base 2.31.8 + g_cond_wait@Base 2.31.8 + g_cond_wait_until@Base 2.31.8 + g_convert@Base 2.12.0 + g_convert_error_quark@Base 2.12.0 + g_convert_with_fallback@Base 2.12.0 + g_convert_with_iconv@Base 2.12.0 + g_creat@Base 2.12.0 + g_datalist_clear@Base 2.12.0 + g_datalist_foreach@Base 2.12.0 + g_datalist_get_data@Base 2.30.0 + g_datalist_get_flags@Base 2.12.0 + g_datalist_id_dup_data@Base 2.33.14 + g_datalist_id_get_data@Base 2.12.0 + g_datalist_id_remove_no_notify@Base 2.12.0 + g_datalist_id_replace_data@Base 2.33.14 + g_datalist_id_set_data_full@Base 2.12.0 + g_datalist_init@Base 2.12.0 + g_datalist_set_flags@Base 2.12.0 + g_datalist_unset_flags@Base 2.12.0 + g_dataset_destroy@Base 2.12.0 + g_dataset_foreach@Base 2.12.0 + g_dataset_id_get_data@Base 2.12.0 + g_dataset_id_remove_no_notify@Base 2.12.0 + g_dataset_id_set_data_full@Base 2.12.0 + g_date_add_days@Base 2.12.0 + g_date_add_months@Base 2.12.0 + g_date_add_years@Base 2.12.0 + g_date_clamp@Base 2.12.0 + g_date_clear@Base 2.12.0 + g_date_compare@Base 2.12.0 + g_date_copy@Base 2.55.1 + g_date_days_between@Base 2.12.0 + g_date_free@Base 2.12.0 + g_date_get_day@Base 2.12.0 + g_date_get_day_of_year@Base 2.12.0 + g_date_get_days_in_month@Base 2.12.0 + g_date_get_iso8601_week_of_year@Base 2.12.0 + g_date_get_julian@Base 2.12.0 + g_date_get_monday_week_of_year@Base 2.12.0 + g_date_get_monday_weeks_in_year@Base 2.12.0 + g_date_get_month@Base 2.12.0 + g_date_get_sunday_week_of_year@Base 2.12.0 + g_date_get_sunday_weeks_in_year@Base 2.12.0 + g_date_get_weekday@Base 2.12.0 + g_date_get_year@Base 2.12.0 + g_date_is_first_of_month@Base 2.12.0 + g_date_is_last_of_month@Base 2.12.0 + g_date_is_leap_year@Base 2.12.0 + g_date_new@Base 2.12.0 + g_date_new_dmy@Base 2.12.0 + g_date_new_julian@Base 2.12.0 + g_date_order@Base 2.12.0 + g_date_set_day@Base 2.12.0 + g_date_set_dmy@Base 2.12.0 + g_date_set_julian@Base 2.12.0 + g_date_set_month@Base 2.12.0 + g_date_set_parse@Base 2.12.0 + g_date_set_time@Base 2.12.0 + g_date_set_time_t@Base 2.12.0 + g_date_set_time_val@Base 2.12.0 + g_date_set_year@Base 2.12.0 + g_date_strftime@Base 2.12.0 + g_date_subtract_days@Base 2.12.0 + g_date_subtract_months@Base 2.12.0 + g_date_subtract_years@Base 2.12.0 + g_date_time_add@Base 2.26.0 + g_date_time_add_days@Base 2.26.0 + g_date_time_add_full@Base 2.26.0 + g_date_time_add_hours@Base 2.26.0 + g_date_time_add_minutes@Base 2.26.0 + g_date_time_add_months@Base 2.26.0 + g_date_time_add_seconds@Base 2.26.0 + g_date_time_add_weeks@Base 2.26.0 + g_date_time_add_years@Base 2.26.0 + g_date_time_compare@Base 2.26.0 + g_date_time_difference@Base 2.26.0 + g_date_time_equal@Base 2.26.0 + g_date_time_format@Base 2.26.0 + g_date_time_format_iso8601@Base 2.61.2 + g_date_time_get_day_of_month@Base 2.26.0 + g_date_time_get_day_of_week@Base 2.26.0 + g_date_time_get_day_of_year@Base 2.26.0 + g_date_time_get_hour@Base 2.26.0 + g_date_time_get_microsecond@Base 2.26.0 + g_date_time_get_minute@Base 2.26.0 + g_date_time_get_month@Base 2.26.0 + g_date_time_get_second@Base 2.26.0 + g_date_time_get_seconds@Base 2.26.0 + g_date_time_get_timezone@Base 2.57.2 + g_date_time_get_timezone_abbreviation@Base 2.26.0 + g_date_time_get_utc_offset@Base 2.26.0 + g_date_time_get_week_numbering_year@Base 2.28.0 + g_date_time_get_week_of_year@Base 2.26.0 + g_date_time_get_year@Base 2.26.0 + g_date_time_get_ymd@Base 2.26.0 + g_date_time_hash@Base 2.26.0 + g_date_time_is_daylight_savings@Base 2.26.0 + g_date_time_new@Base 2.26.0 + g_date_time_new_from_iso8601@Base 2.55.1 + g_date_time_new_from_timeval_local@Base 2.26.0 + g_date_time_new_from_timeval_utc@Base 2.26.0 + g_date_time_new_from_unix_local@Base 2.26.0 + g_date_time_new_from_unix_utc@Base 2.26.0 + g_date_time_new_local@Base 2.26.0 + g_date_time_new_now@Base 2.26.0 + g_date_time_new_now_local@Base 2.26.0 + g_date_time_new_now_utc@Base 2.26.0 + g_date_time_new_utc@Base 2.26.0 + g_date_time_ref@Base 2.26.0 + g_date_time_to_local@Base 2.26.0 + g_date_time_to_timeval@Base 2.26.0 + g_date_time_to_timezone@Base 2.26.0 + g_date_time_to_unix@Base 2.26.0 + g_date_time_to_utc@Base 2.26.0 + g_date_time_unref@Base 2.26.0 + g_date_to_struct_tm@Base 2.12.0 + g_date_valid@Base 2.12.0 + g_date_valid_day@Base 2.12.0 + g_date_valid_dmy@Base 2.12.0 + g_date_valid_julian@Base 2.12.0 + g_date_valid_month@Base 2.12.0 + g_date_valid_weekday@Base 2.12.0 + g_date_valid_year@Base 2.12.0 + g_dcgettext@Base 2.26.0 + g_dgettext@Base 2.18.0 + g_dir_close@Base 2.12.0 + g_dir_make_tmp@Base 2.30.0 + g_dir_open@Base 2.12.0 + g_dir_read_name@Base 2.12.0 + g_dir_rewind@Base 2.12.0 + g_direct_equal@Base 2.12.0 + g_direct_hash@Base 2.12.0 + g_dngettext@Base 2.18.0 + g_double_equal@Base 2.22.0 + g_double_hash@Base 2.22.0 + g_dpgettext2@Base 2.18.0 + g_dpgettext@Base 2.16.0 + g_environ_getenv@Base 2.31.8 + g_environ_setenv@Base 2.31.8 + g_environ_unsetenv@Base 2.31.8 + g_error_copy@Base 2.12.0 + g_error_domain_register@Base 2.67.2 + g_error_domain_register_static@Base 2.67.2 + g_error_free@Base 2.12.0 + g_error_matches@Base 2.12.0 + g_error_new@Base 2.12.0 + g_error_new_literal@Base 2.12.0 + g_error_new_valist@Base 2.22.0 + g_file_error_from_errno@Base 2.12.0 + g_file_error_quark@Base 2.12.0 + g_file_get_contents@Base 2.12.0 + g_file_open_tmp@Base 2.12.0 + g_file_read_link@Base 2.12.0 + g_file_set_contents@Base 2.12.0 + g_file_set_contents_full@Base 2.65.1 + g_file_test@Base 2.12.0 + g_filename_display_basename@Base 2.12.0 + g_filename_display_name@Base 2.12.0 + g_filename_from_uri@Base 2.12.0 + g_filename_from_utf8@Base 2.12.0 + g_filename_to_uri@Base 2.12.0 + g_filename_to_utf8@Base 2.12.0 + g_find_program_in_path@Base 2.12.0 + g_fopen@Base 2.12.0 + g_format_size@Base 2.30.0 + g_format_size_for_display@Base 2.16.0 + g_format_size_full@Base 2.30.0 + g_fprintf@Base 2.12.0 + g_free@Base 2.12.0 + g_freopen@Base 2.12.0 + g_fsync@Base 2.63.1 + g_get_application_name@Base 2.12.0 + g_get_charset@Base 2.12.0 + g_get_codeset@Base 2.12.0 + g_get_console_charset@Base 2.61.2 + g_get_current_dir@Base 2.12.0 + g_get_current_time@Base 2.12.0 + g_get_environ@Base 2.28.0 + g_get_filename_charsets@Base 2.12.0 + g_get_home_dir@Base 2.35.9 + g_get_host_name@Base 2.12.0 + g_get_language_names@Base 2.12.0 + g_get_language_names_with_category@Base 2.57.2 + g_get_locale_variants@Base 2.28.0 + g_get_monotonic_time@Base 2.28.0 + g_get_num_processors@Base 2.35.8 + g_get_os_info@Base 2.63.1 + g_get_prgname@Base 2.12.0 + g_get_real_name@Base 2.12.0 + g_get_real_time@Base 2.28.0 + g_get_system_config_dirs@Base 2.12.0 + g_get_system_data_dirs@Base 2.12.0 + g_get_tmp_dir@Base 2.12.0 + g_get_user_cache_dir@Base 2.12.0 + g_get_user_config_dir@Base 2.12.0 + g_get_user_data_dir@Base 2.12.0 + g_get_user_name@Base 2.12.0 + g_get_user_runtime_dir@Base 2.28.0 + g_get_user_special_dir@Base 2.14.0 + g_get_user_state_dir@Base 2.71.1 + g_getenv@Base 2.12.0 + g_hash_table_add@Base 2.31.8 + g_hash_table_contains@Base 2.31.8 + g_hash_table_destroy@Base 2.12.0 + g_hash_table_find@Base 2.12.0 + g_hash_table_foreach@Base 2.12.0 + g_hash_table_foreach_remove@Base 2.12.0 + g_hash_table_foreach_steal@Base 2.12.0 + g_hash_table_get_keys@Base 2.14.0 + g_hash_table_get_keys_as_array@Base 2.39.4 + g_hash_table_get_values@Base 2.14.0 + g_hash_table_insert@Base 2.12.0 + g_hash_table_iter_get_hash_table@Base 2.16.0 + g_hash_table_iter_init@Base 2.16.0 + g_hash_table_iter_next@Base 2.16.0 + g_hash_table_iter_remove@Base 2.16.0 + g_hash_table_iter_replace@Base 2.30.0 + g_hash_table_iter_steal@Base 2.16.0 + g_hash_table_lookup@Base 2.12.0 + g_hash_table_lookup_extended@Base 2.12.0 + g_hash_table_new@Base 2.12.0 + g_hash_table_new_full@Base 2.12.0 + g_hash_table_new_similar@Base 2.71.1 + g_hash_table_ref@Base 2.12.0 + g_hash_table_remove@Base 2.12.0 + g_hash_table_remove_all@Base 2.12.0 + g_hash_table_replace@Base 2.12.0 + g_hash_table_size@Base 2.12.0 + g_hash_table_steal@Base 2.12.0 + g_hash_table_steal_all@Base 2.12.0 + g_hash_table_steal_extended@Base 2.57.2 + g_hash_table_unref@Base 2.12.0 + g_hmac_copy@Base 2.30.0 + g_hmac_get_digest@Base 2.30.0 + g_hmac_get_string@Base 2.30.0 + g_hmac_new@Base 2.30.0 + g_hmac_ref@Base 2.30.0 + g_hmac_unref@Base 2.30.0 + g_hmac_update@Base 2.30.0 + g_hook_alloc@Base 2.12.0 + g_hook_compare_ids@Base 2.12.0 + g_hook_destroy@Base 2.12.0 + g_hook_destroy_link@Base 2.12.0 + g_hook_find@Base 2.12.0 + g_hook_find_data@Base 2.12.0 + g_hook_find_func@Base 2.12.0 + g_hook_find_func_data@Base 2.12.0 + g_hook_first_valid@Base 2.12.0 + g_hook_free@Base 2.12.0 + g_hook_get@Base 2.12.0 + g_hook_insert_before@Base 2.12.0 + g_hook_insert_sorted@Base 2.12.0 + g_hook_list_clear@Base 2.12.0 + g_hook_list_init@Base 2.12.0 + g_hook_list_invoke@Base 2.12.0 + g_hook_list_invoke_check@Base 2.12.0 + g_hook_list_marshal@Base 2.12.0 + g_hook_list_marshal_check@Base 2.12.0 + g_hook_next_valid@Base 2.12.0 + g_hook_prepend@Base 2.12.0 + g_hook_ref@Base 2.12.0 + g_hook_unref@Base 2.12.0 + g_hostname_is_ascii_encoded@Base 2.22.0 + g_hostname_is_ip_address@Base 2.22.0 + g_hostname_is_non_ascii@Base 2.22.0 + g_hostname_to_ascii@Base 2.22.0 + g_hostname_to_unicode@Base 2.22.0 + g_iconv@Base 2.12.0 + g_iconv_close@Base 2.12.0 + g_iconv_open@Base 2.12.0 + g_idle_add@Base 2.12.0 + g_idle_add_full@Base 2.12.0 + g_idle_funcs@Base 2.12.0 + g_idle_remove_by_data@Base 2.12.0 + g_idle_source_new@Base 2.12.0 + g_int64_equal@Base 2.22.0 + g_int64_hash@Base 2.22.0 + g_int_equal@Base 2.12.0 + g_int_hash@Base 2.12.0 + g_intern_static_string@Base 2.12.0 + g_intern_string@Base 2.12.0 + g_io_add_watch@Base 2.12.0 + g_io_add_watch_full@Base 2.12.0 + g_io_channel_close@Base 2.12.0 + g_io_channel_error_from_errno@Base 2.12.0 + g_io_channel_error_quark@Base 2.12.0 + g_io_channel_flush@Base 2.12.0 + g_io_channel_get_buffer_condition@Base 2.12.0 + g_io_channel_get_buffer_size@Base 2.12.0 + g_io_channel_get_buffered@Base 2.12.0 + g_io_channel_get_close_on_unref@Base 2.12.0 + g_io_channel_get_encoding@Base 2.12.0 + g_io_channel_get_flags@Base 2.12.0 + g_io_channel_get_line_term@Base 2.12.0 + g_io_channel_init@Base 2.12.0 + g_io_channel_new_file@Base 2.12.0 + g_io_channel_read@Base 2.12.0 + g_io_channel_read_chars@Base 2.12.0 + g_io_channel_read_line@Base 2.12.0 + g_io_channel_read_line_string@Base 2.12.0 + g_io_channel_read_to_end@Base 2.12.0 + g_io_channel_read_unichar@Base 2.12.0 + g_io_channel_ref@Base 2.12.0 + g_io_channel_seek@Base 2.12.0 + g_io_channel_seek_position@Base 2.12.0 + g_io_channel_set_buffer_size@Base 2.12.0 + g_io_channel_set_buffered@Base 2.12.0 + g_io_channel_set_close_on_unref@Base 2.12.0 + g_io_channel_set_encoding@Base 2.12.0 + g_io_channel_set_flags@Base 2.12.0 + g_io_channel_set_line_term@Base 2.12.0 + g_io_channel_shutdown@Base 2.12.0 + g_io_channel_unix_get_fd@Base 2.12.0 + g_io_channel_unix_new@Base 2.12.0 + g_io_channel_unref@Base 2.12.0 + g_io_channel_write@Base 2.12.0 + g_io_channel_write_chars@Base 2.12.0 + g_io_channel_write_unichar@Base 2.12.0 + g_io_create_watch@Base 2.12.0 + g_io_watch_funcs@Base 2.12.0 + g_key_file_error_quark@Base 2.12.0 + g_key_file_free@Base 2.12.0 + g_key_file_get_boolean@Base 2.12.0 + g_key_file_get_boolean_list@Base 2.12.0 + g_key_file_get_comment@Base 2.12.0 + g_key_file_get_double@Base 2.12.0 + g_key_file_get_double_list@Base 2.12.0 + g_key_file_get_groups@Base 2.12.0 + g_key_file_get_int64@Base 2.26.0 + g_key_file_get_integer@Base 2.12.0 + g_key_file_get_integer_list@Base 2.12.0 + g_key_file_get_keys@Base 2.12.0 + g_key_file_get_locale_for_key@Base 2.55.2 + g_key_file_get_locale_string@Base 2.12.0 + g_key_file_get_locale_string_list@Base 2.12.0 + g_key_file_get_start_group@Base 2.12.0 + g_key_file_get_string@Base 2.12.0 + g_key_file_get_string_list@Base 2.12.0 + g_key_file_get_uint64@Base 2.26.0 + g_key_file_get_value@Base 2.12.0 + g_key_file_has_group@Base 2.12.0 + g_key_file_has_key@Base 2.12.0 + g_key_file_load_from_bytes@Base 2.49.3 + g_key_file_load_from_data@Base 2.12.0 + g_key_file_load_from_data_dirs@Base 2.12.0 + g_key_file_load_from_dirs@Base 2.14.0 + g_key_file_load_from_file@Base 2.12.0 + g_key_file_new@Base 2.12.0 + g_key_file_ref@Base 2.31.8 + g_key_file_remove_comment@Base 2.12.0 + g_key_file_remove_group@Base 2.12.0 + g_key_file_remove_key@Base 2.12.0 + g_key_file_save_to_file@Base 2.39.4 + g_key_file_set_boolean@Base 2.12.0 + g_key_file_set_boolean_list@Base 2.12.0 + g_key_file_set_comment@Base 2.12.0 + g_key_file_set_double@Base 2.12.0 + g_key_file_set_double_list@Base 2.12.0 + g_key_file_set_int64@Base 2.26.0 + g_key_file_set_integer@Base 2.12.0 + g_key_file_set_integer_list@Base 2.12.0 + g_key_file_set_list_separator@Base 2.12.0 + g_key_file_set_locale_string@Base 2.12.0 + g_key_file_set_locale_string_list@Base 2.12.0 + g_key_file_set_string@Base 2.12.0 + g_key_file_set_string_list@Base 2.12.0 + g_key_file_set_uint64@Base 2.26.0 + g_key_file_set_value@Base 2.12.0 + g_key_file_to_data@Base 2.12.0 + g_key_file_unref@Base 2.31.8 + g_list_alloc@Base 2.12.0 + g_list_append@Base 2.12.0 + g_list_concat@Base 2.12.0 + g_list_copy@Base 2.12.0 + g_list_copy_deep@Base 2.33.14 + g_list_delete_link@Base 2.12.0 + g_list_find@Base 2.12.0 + g_list_find_custom@Base 2.12.0 + g_list_first@Base 2.12.0 + g_list_foreach@Base 2.12.0 + g_list_free@Base 2.12.0 + g_list_free_1@Base 2.12.0 + g_list_free_full@Base 2.28.0 + g_list_index@Base 2.12.0 + g_list_insert@Base 2.12.0 + g_list_insert_before@Base 2.12.0 + g_list_insert_before_link@Base 2.61.1 + g_list_insert_sorted@Base 2.12.0 + g_list_insert_sorted_with_data@Base 2.12.0 + g_list_last@Base 2.12.0 + g_list_length@Base 2.12.0 + g_list_nth@Base 2.12.0 + g_list_nth_data@Base 2.12.0 + g_list_nth_prev@Base 2.12.0 + g_list_pop_allocator@Base 2.12.0 + g_list_position@Base 2.12.0 + g_list_prepend@Base 2.12.0 + g_list_push_allocator@Base 2.12.0 + g_list_remove@Base 2.12.0 + g_list_remove_all@Base 2.12.0 + g_list_remove_link@Base 2.12.0 + g_list_reverse@Base 2.12.0 + g_list_sort@Base 2.12.0 + g_list_sort_with_data@Base 2.12.0 + g_listenv@Base 2.12.0 + g_locale_from_utf8@Base 2.12.0 + g_locale_to_utf8@Base 2.12.0 + g_log@Base 2.12.0 + g_log_default_handler@Base 2.12.0 + g_log_get_debug_enabled@Base 2.71.1 + g_log_remove_handler@Base 2.12.0 + g_log_set_always_fatal@Base 2.12.0 + g_log_set_debug_enabled@Base 2.71.1 + g_log_set_default_handler@Base 2.12.0 + g_log_set_fatal_mask@Base 2.12.0 + g_log_set_handler@Base 2.12.0 + g_log_set_handler_full@Base 2.45.3 + g_log_set_writer_func@Base 2.49.3 + g_log_structured@Base 2.49.3 + g_log_structured_array@Base 2.49.3 + g_log_structured_standard@Base 2.55.2 + g_log_variant@Base 2.49.7 + g_log_writer_default@Base 2.49.3 + g_log_writer_default_set_use_stderr@Base 2.67.1 + g_log_writer_default_would_drop@Base 2.67.1 + g_log_writer_format_fields@Base 2.49.3 + g_log_writer_is_journald@Base 2.49.3 + g_log_writer_journald@Base 2.49.3 + g_log_writer_standard_streams@Base 2.49.3 + g_log_writer_supports_color@Base 2.49.3 + g_logv@Base 2.12.0 + g_lstat@Base 2.12.0 + g_main_context_acquire@Base 2.12.0 + g_main_context_add_poll@Base 2.12.0 + g_main_context_check@Base 2.12.0 + g_main_context_default@Base 2.12.0 + g_main_context_dispatch@Base 2.12.0 + g_main_context_find_source_by_funcs_user_data@Base 2.12.0 + g_main_context_find_source_by_id@Base 2.12.0 + g_main_context_find_source_by_user_data@Base 2.12.0 + g_main_context_get_poll_func@Base 2.12.0 + g_main_context_get_thread_default@Base 2.22.0 + g_main_context_invoke@Base 2.28.0 + g_main_context_invoke_full@Base 2.28.0 + g_main_context_is_owner@Base 2.12.0 + g_main_context_iteration@Base 2.12.0 + g_main_context_new@Base 2.12.0 + g_main_context_new_with_flags@Base 2.71.0 + g_main_context_pending@Base 2.12.0 + g_main_context_pop_thread_default@Base 2.22.0 + g_main_context_prepare@Base 2.12.0 + g_main_context_push_thread_default@Base 2.22.0 + g_main_context_query@Base 2.12.0 + g_main_context_ref@Base 2.12.0 + g_main_context_ref_thread_default@Base 2.31.8 + g_main_context_release@Base 2.12.0 + g_main_context_remove_poll@Base 2.12.0 + g_main_context_set_poll_func@Base 2.12.0 + g_main_context_unref@Base 2.12.0 + g_main_context_wait@Base 2.12.0 + g_main_context_wakeup@Base 2.12.0 + g_main_current_source@Base 2.12.0 + g_main_depth@Base 2.12.0 + g_main_loop_get_context@Base 2.12.0 + g_main_loop_is_running@Base 2.12.0 + g_main_loop_new@Base 2.12.0 + g_main_loop_quit@Base 2.12.0 + g_main_loop_ref@Base 2.12.0 + g_main_loop_run@Base 2.12.0 + g_main_loop_unref@Base 2.12.0 + g_malloc0@Base 2.12.0 + g_malloc0_n@Base 2.24.0 + g_malloc@Base 2.12.0 + g_malloc_n@Base 2.24.0 + g_mapped_file_free@Base 2.12.0 + g_mapped_file_get_bytes@Base 2.33.14 + g_mapped_file_get_contents@Base 2.12.0 + g_mapped_file_get_length@Base 2.12.0 + g_mapped_file_new@Base 2.12.0 + g_mapped_file_new_from_fd@Base 2.31.8 + g_mapped_file_ref@Base 2.22.0 + g_mapped_file_unref@Base 2.22.0 + g_markup_collect_attributes@Base 2.16.0 + g_markup_error_quark@Base 2.12.0 + g_markup_escape_text@Base 2.12.0 + g_markup_parse_context_end_parse@Base 2.12.0 + g_markup_parse_context_free@Base 2.12.0 + g_markup_parse_context_get_element@Base 2.12.0 + g_markup_parse_context_get_element_stack@Base 2.16.0 + g_markup_parse_context_get_position@Base 2.12.0 + g_markup_parse_context_get_user_data@Base 2.18.0 + g_markup_parse_context_new@Base 2.12.0 + g_markup_parse_context_parse@Base 2.12.0 + g_markup_parse_context_pop@Base 2.18.0 + g_markup_parse_context_push@Base 2.18.0 + g_markup_parse_context_ref@Base 2.35.8 + g_markup_parse_context_unref@Base 2.35.8 + g_markup_printf_escaped@Base 2.12.0 + g_markup_vprintf_escaped@Base 2.12.0 + g_match_info_expand_references@Base 2.14.0 + g_match_info_fetch@Base 2.14.0 + g_match_info_fetch_all@Base 2.14.0 + g_match_info_fetch_named@Base 2.14.0 + g_match_info_fetch_named_pos@Base 2.14.0 + g_match_info_fetch_pos@Base 2.14.0 + g_match_info_free@Base 2.14.0 + g_match_info_get_match_count@Base 2.14.0 + g_match_info_get_regex@Base 2.14.0 + g_match_info_get_string@Base 2.14.0 + g_match_info_is_partial_match@Base 2.14.0 + g_match_info_matches@Base 2.14.0 + g_match_info_next@Base 2.14.0 + g_match_info_ref@Base 2.30.0 + g_match_info_unref@Base 2.30.0 + g_mem_chunk_alloc0@Base 2.12.0 + g_mem_chunk_alloc@Base 2.12.0 + g_mem_chunk_clean@Base 2.12.0 + g_mem_chunk_destroy@Base 2.12.0 + g_mem_chunk_free@Base 2.12.0 + g_mem_chunk_info@Base 2.12.0 + g_mem_chunk_new@Base 2.12.0 + g_mem_chunk_print@Base 2.12.0 + g_mem_chunk_reset@Base 2.12.0 + g_mem_gc_friendly@Base 2.12.0 + g_mem_is_system_malloc@Base 2.12.0 + g_mem_profile@Base 2.12.0 + g_mem_set_vtable@Base 2.12.0 + g_memdup2@Base 2.67.3 + g_memdup@Base 2.12.0 + g_mkdir@Base 2.12.0 + g_mkdir_with_parents@Base 2.12.0 + g_mkdtemp@Base 2.30.0 + g_mkdtemp_full@Base 2.30.0 + g_mkstemp@Base 2.12.0 + g_mkstemp_full@Base 2.22.0 + g_mutex_clear@Base 2.31.8 + g_mutex_free@Base 2.31.8 + g_mutex_init@Base 2.31.8 + g_mutex_lock@Base 2.31.8 + g_mutex_new@Base 2.31.8 + g_mutex_trylock@Base 2.31.8 + g_mutex_unlock@Base 2.31.8 + g_node_child_index@Base 2.12.0 + g_node_child_position@Base 2.12.0 + g_node_children_foreach@Base 2.12.0 + g_node_copy@Base 2.12.0 + g_node_copy_deep@Base 2.12.0 + g_node_depth@Base 2.12.0 + g_node_destroy@Base 2.12.0 + g_node_find@Base 2.12.0 + g_node_find_child@Base 2.12.0 + g_node_first_sibling@Base 2.12.0 + g_node_get_root@Base 2.12.0 + g_node_insert@Base 2.12.0 + g_node_insert_after@Base 2.12.0 + g_node_insert_before@Base 2.12.0 + g_node_is_ancestor@Base 2.12.0 + g_node_last_child@Base 2.12.0 + g_node_last_sibling@Base 2.12.0 + g_node_max_height@Base 2.12.0 + g_node_n_children@Base 2.12.0 + g_node_n_nodes@Base 2.12.0 + g_node_new@Base 2.12.0 + g_node_nth_child@Base 2.12.0 + g_node_pop_allocator@Base 2.12.0 + g_node_prepend@Base 2.12.0 + g_node_push_allocator@Base 2.12.0 + g_node_reverse_children@Base 2.12.0 + g_node_traverse@Base 2.12.0 + g_node_unlink@Base 2.12.0 + g_nullify_pointer@Base 2.12.0 + g_number_parser_error_quark@Base 2.53.2 + g_on_error_query@Base 2.12.0 + g_on_error_stack_trace@Base 2.12.0 + g_once_impl@Base 2.12.0 + g_once_init_enter@Base 2.14.0 + g_once_init_enter_impl@Base 2.14.0 + g_once_init_leave@Base 2.14.0 + g_open@Base 2.12.0 + g_option_context_add_group@Base 2.12.0 + g_option_context_add_main_entries@Base 2.12.0 + g_option_context_free@Base 2.12.0 + g_option_context_get_description@Base 2.12.0 + g_option_context_get_help@Base 2.14.0 + g_option_context_get_help_enabled@Base 2.12.0 + g_option_context_get_ignore_unknown_options@Base 2.12.0 + g_option_context_get_main_group@Base 2.12.0 + g_option_context_get_strict_posix@Base 2.43.1 + g_option_context_get_summary@Base 2.12.0 + g_option_context_new@Base 2.12.0 + g_option_context_parse@Base 2.12.0 + g_option_context_parse_strv@Base 2.39.4 + g_option_context_set_description@Base 2.12.0 + g_option_context_set_help_enabled@Base 2.12.0 + g_option_context_set_ignore_unknown_options@Base 2.12.0 + g_option_context_set_main_group@Base 2.12.0 + g_option_context_set_strict_posix@Base 2.43.1 + g_option_context_set_summary@Base 2.12.0 + g_option_context_set_translate_func@Base 2.12.0 + g_option_context_set_translation_domain@Base 2.12.0 + g_option_error_quark@Base 2.12.0 + g_option_group_add_entries@Base 2.12.0 + g_option_group_free@Base 2.12.0 + g_option_group_new@Base 2.12.0 + g_option_group_ref@Base 2.43.90 + g_option_group_set_error_hook@Base 2.12.0 + g_option_group_set_parse_hooks@Base 2.12.0 + g_option_group_set_translate_func@Base 2.12.0 + g_option_group_set_translation_domain@Base 2.12.0 + g_option_group_unref@Base 2.43.90 + g_parse_debug_string@Base 2.12.0 + g_path_get_basename@Base 2.12.0 + g_path_get_dirname@Base 2.12.0 + g_path_is_absolute@Base 2.12.0 + g_path_skip_root@Base 2.12.0 + g_pattern_match@Base 2.12.0 + g_pattern_match_simple@Base 2.12.0 + g_pattern_match_string@Base 2.12.0 + g_pattern_spec_copy@Base 2.70.0 + g_pattern_spec_equal@Base 2.12.0 + g_pattern_spec_free@Base 2.12.0 + g_pattern_spec_match@Base 2.70.0 + g_pattern_spec_match_string@Base 2.70.0 + g_pattern_spec_new@Base 2.12.0 + g_pointer_bit_lock@Base 2.30.0 + g_pointer_bit_trylock@Base 2.30.0 + g_pointer_bit_unlock@Base 2.30.0 + g_poll@Base 2.20.0 + g_prefix_error@Base 2.16.0 + g_prefix_error_literal@Base 2.70.0 + g_print@Base 2.12.0 + g_printerr@Base 2.12.0 + g_printf@Base 2.12.0 + g_printf_string_upper_bound@Base 2.12.0 + g_private_get@Base 2.31.8 + g_private_new@Base 2.31.8 + g_private_replace@Base 2.31.8 + g_private_set@Base 2.31.8 + g_propagate_error@Base 2.12.0 + g_propagate_prefixed_error@Base 2.16.0 + g_ptr_array_add@Base 2.12.0 + g_ptr_array_copy@Base 2.61.2 + g_ptr_array_extend@Base 2.61.2 + g_ptr_array_extend_and_steal@Base 2.61.2 + g_ptr_array_find@Base 2.53.2 + g_ptr_array_find_with_equal_func@Base 2.53.2 + g_ptr_array_foreach@Base 2.12.0 + g_ptr_array_free@Base 2.12.0 + g_ptr_array_insert@Base 2.39.4 + g_ptr_array_new@Base 2.12.0 + g_ptr_array_new_full@Base 2.30.0 + g_ptr_array_new_with_free_func@Base 2.22.0 + g_ptr_array_ref@Base 2.22.0 + g_ptr_array_remove@Base 2.12.0 + g_ptr_array_remove_fast@Base 2.12.0 + g_ptr_array_remove_index@Base 2.12.0 + g_ptr_array_remove_index_fast@Base 2.12.0 + g_ptr_array_remove_range@Base 2.12.0 + g_ptr_array_set_free_func@Base 2.22.0 + g_ptr_array_set_size@Base 2.12.0 + g_ptr_array_sized_new@Base 2.12.0 + g_ptr_array_sort@Base 2.12.0 + g_ptr_array_sort_with_data@Base 2.12.0 + g_ptr_array_steal@Base 2.63.1 + g_ptr_array_steal_index@Base 2.57.2 + g_ptr_array_steal_index_fast@Base 2.57.2 + g_ptr_array_unref@Base 2.22.0 + g_qsort_with_data@Base 2.12.0 + g_quark_from_static_string@Base 2.12.0 + g_quark_from_string@Base 2.12.0 + g_quark_to_string@Base 2.12.0 + g_quark_try_string@Base 2.12.0 + g_queue_clear@Base 2.14.0 + g_queue_clear_full@Base 2.59.2 + g_queue_copy@Base 2.12.0 + g_queue_delete_link@Base 2.12.0 + g_queue_find@Base 2.12.0 + g_queue_find_custom@Base 2.12.0 + g_queue_foreach@Base 2.12.0 + g_queue_free@Base 2.12.0 + g_queue_free_full@Base 2.31.8 + g_queue_get_length@Base 2.12.0 + g_queue_index@Base 2.12.0 + g_queue_init@Base 2.14.0 + g_queue_insert_after@Base 2.12.0 + g_queue_insert_after_link@Base 2.61.1 + g_queue_insert_before@Base 2.12.0 + g_queue_insert_before_link@Base 2.61.1 + g_queue_insert_sorted@Base 2.12.0 + g_queue_is_empty@Base 2.12.0 + g_queue_link_index@Base 2.12.0 + g_queue_new@Base 2.12.0 + g_queue_peek_head@Base 2.12.0 + g_queue_peek_head_link@Base 2.12.0 + g_queue_peek_nth@Base 2.12.0 + g_queue_peek_nth_link@Base 2.12.0 + g_queue_peek_tail@Base 2.12.0 + g_queue_peek_tail_link@Base 2.12.0 + g_queue_pop_head@Base 2.12.0 + g_queue_pop_head_link@Base 2.12.0 + g_queue_pop_nth@Base 2.12.0 + g_queue_pop_nth_link@Base 2.12.0 + g_queue_pop_tail@Base 2.12.0 + g_queue_pop_tail_link@Base 2.12.0 + g_queue_push_head@Base 2.12.0 + g_queue_push_head_link@Base 2.12.0 + g_queue_push_nth@Base 2.12.0 + g_queue_push_nth_link@Base 2.12.0 + g_queue_push_tail@Base 2.12.0 + g_queue_push_tail_link@Base 2.12.0 + g_queue_remove@Base 2.12.0 + g_queue_remove_all@Base 2.12.0 + g_queue_reverse@Base 2.12.0 + g_queue_sort@Base 2.12.0 + g_queue_unlink@Base 2.12.0 + g_rand_copy@Base 2.12.0 + g_rand_double@Base 2.12.0 + g_rand_double_range@Base 2.12.0 + g_rand_free@Base 2.12.0 + g_rand_int@Base 2.12.0 + g_rand_int_range@Base 2.12.0 + g_rand_new@Base 2.12.0 + g_rand_new_with_seed@Base 2.12.0 + g_rand_new_with_seed_array@Base 2.12.0 + g_rand_set_seed@Base 2.12.0 + g_rand_set_seed_array@Base 2.12.0 + g_random_double@Base 2.12.0 + g_random_double_range@Base 2.12.0 + g_random_int@Base 2.12.0 + g_random_int_range@Base 2.12.0 + g_random_set_seed@Base 2.12.0 + g_rc_box_acquire@Base 2.57.2 + g_rc_box_alloc@Base 2.57.2 + g_rc_box_alloc0@Base 2.57.2 + g_rc_box_dup@Base 2.57.2 + g_rc_box_get_size@Base 2.57.2 + g_rc_box_release@Base 2.57.2 + g_rc_box_release_full@Base 2.57.2 + g_realloc@Base 2.12.0 + g_realloc_n@Base 2.24.0 + g_rec_mutex_clear@Base 2.31.8 + g_rec_mutex_init@Base 2.31.8 + g_rec_mutex_lock@Base 2.31.8 + g_rec_mutex_trylock@Base 2.31.8 + g_rec_mutex_unlock@Base 2.31.8 + g_ref_count_compare@Base 2.57.2 + g_ref_count_dec@Base 2.57.2 + g_ref_count_inc@Base 2.57.2 + g_ref_count_init@Base 2.57.2 + g_ref_string_acquire@Base 2.57.2 + g_ref_string_length@Base 2.57.2 + g_ref_string_new@Base 2.57.2 + g_ref_string_new_intern@Base 2.57.2 + g_ref_string_new_len@Base 2.57.2 + g_ref_string_release@Base 2.57.2 + g_regex_check_replacement@Base 2.14.0 + g_regex_error_quark@Base 2.14.0 + g_regex_escape_nul@Base 2.30.0 + g_regex_escape_string@Base 2.14.0 + g_regex_get_capture_count@Base 2.14.0 + g_regex_get_compile_flags@Base 2.26.0 + g_regex_get_has_cr_or_lf@Base 2.33.14 + g_regex_get_match_flags@Base 2.26.0 + g_regex_get_max_backref@Base 2.14.0 + g_regex_get_max_lookbehind@Base 2.37.5 + g_regex_get_pattern@Base 2.14.0 + g_regex_get_string_number@Base 2.14.0 + g_regex_match@Base 2.14.0 + g_regex_match_all@Base 2.14.0 + g_regex_match_all_full@Base 2.14.0 + g_regex_match_full@Base 2.14.0 + g_regex_match_simple@Base 2.14.0 + g_regex_new@Base 2.14.0 + g_regex_ref@Base 2.14.0 + g_regex_replace@Base 2.14.0 + g_regex_replace_eval@Base 2.14.0 + g_regex_replace_literal@Base 2.14.0 + g_regex_split@Base 2.14.0 + g_regex_split_full@Base 2.14.0 + g_regex_split_simple@Base 2.14.0 + g_regex_unref@Base 2.14.0 + g_relation_count@Base 2.12.0 + g_relation_delete@Base 2.12.0 + g_relation_destroy@Base 2.12.0 + g_relation_exists@Base 2.12.0 + g_relation_index@Base 2.12.0 + g_relation_insert@Base 2.12.0 + g_relation_new@Base 2.12.0 + g_relation_print@Base 2.12.0 + g_relation_select@Base 2.12.0 + g_reload_user_special_dirs_cache@Base 2.22.0 + g_remove@Base 2.12.0 + g_rename@Base 2.12.0 + g_return_if_fail_warning@Base 2.12.0 + g_rmdir@Base 2.12.0 + g_rw_lock_clear@Base 2.31.8 + g_rw_lock_init@Base 2.31.8 + g_rw_lock_reader_lock@Base 2.31.8 + g_rw_lock_reader_trylock@Base 2.31.8 + g_rw_lock_reader_unlock@Base 2.31.8 + g_rw_lock_writer_lock@Base 2.31.8 + g_rw_lock_writer_trylock@Base 2.31.8 + g_rw_lock_writer_unlock@Base 2.31.8 + g_scanner_cur_line@Base 2.12.0 + g_scanner_cur_position@Base 2.12.0 + g_scanner_cur_token@Base 2.12.0 + g_scanner_cur_value@Base 2.12.0 + g_scanner_destroy@Base 2.12.0 + g_scanner_eof@Base 2.12.0 + g_scanner_error@Base 2.12.0 + g_scanner_get_next_token@Base 2.12.0 + g_scanner_input_file@Base 2.12.0 + g_scanner_input_text@Base 2.12.0 + g_scanner_lookup_symbol@Base 2.12.0 + g_scanner_new@Base 2.12.0 + g_scanner_peek_next_token@Base 2.12.0 + g_scanner_scope_add_symbol@Base 2.12.0 + g_scanner_scope_foreach_symbol@Base 2.12.0 + g_scanner_scope_lookup_symbol@Base 2.12.0 + g_scanner_scope_remove_symbol@Base 2.12.0 + g_scanner_set_scope@Base 2.12.0 + g_scanner_sync_file_offset@Base 2.12.0 + g_scanner_unexp_token@Base 2.12.0 + g_scanner_warn@Base 2.12.0 + g_sequence_append@Base 2.14.0 + g_sequence_foreach@Base 2.14.0 + g_sequence_foreach_range@Base 2.14.0 + g_sequence_free@Base 2.14.0 + g_sequence_get@Base 2.14.0 + g_sequence_get_begin_iter@Base 2.14.0 + g_sequence_get_end_iter@Base 2.14.0 + g_sequence_get_iter_at_pos@Base 2.14.0 + g_sequence_get_length@Base 2.14.0 + g_sequence_insert_before@Base 2.14.0 + g_sequence_insert_sorted@Base 2.14.0 + g_sequence_insert_sorted_iter@Base 2.14.0 + g_sequence_is_empty@Base 2.47.1 + g_sequence_iter_compare@Base 2.14.0 + g_sequence_iter_get_position@Base 2.14.0 + g_sequence_iter_get_sequence@Base 2.14.0 + g_sequence_iter_is_begin@Base 2.14.0 + g_sequence_iter_is_end@Base 2.14.0 + g_sequence_iter_move@Base 2.14.0 + g_sequence_iter_next@Base 2.14.0 + g_sequence_iter_prev@Base 2.14.0 + g_sequence_lookup@Base 2.28.0 + g_sequence_lookup_iter@Base 2.28.0 + g_sequence_move@Base 2.14.0 + g_sequence_move_range@Base 2.14.0 + g_sequence_new@Base 2.14.0 + g_sequence_prepend@Base 2.14.0 + g_sequence_range_get_midpoint@Base 2.14.0 + g_sequence_remove@Base 2.14.0 + g_sequence_remove_range@Base 2.14.0 + g_sequence_search@Base 2.14.0 + g_sequence_search_iter@Base 2.14.0 + g_sequence_set@Base 2.14.0 + g_sequence_sort@Base 2.14.0 + g_sequence_sort_changed@Base 2.14.0 + g_sequence_sort_changed_iter@Base 2.14.0 + g_sequence_sort_iter@Base 2.14.0 + g_sequence_swap@Base 2.14.0 + g_set_application_name@Base 2.12.0 + g_set_error@Base 2.12.0 + g_set_error_literal@Base 2.18.0 + g_set_prgname@Base 2.12.0 + g_set_print_handler@Base 2.12.0 + g_set_printerr_handler@Base 2.12.0 + g_set_user_dirs@Base 2.59.0 + g_setenv@Base 2.12.0 + g_shell_error_quark@Base 2.12.0 + g_shell_parse_argv@Base 2.12.0 + g_shell_quote@Base 2.12.0 + g_shell_unquote@Base 2.12.0 + g_slice_alloc0@Base 2.12.0 + g_slice_alloc@Base 2.12.0 + g_slice_copy@Base 2.14.0 + g_slice_free1@Base 2.12.0 + g_slice_free_chain_with_offset@Base 2.12.0 + g_slice_get_config@Base 2.12.0 + g_slice_get_config_state@Base 2.12.0 + g_slice_set_config@Base 2.12.0 + g_slist_alloc@Base 2.12.0 + g_slist_append@Base 2.12.0 + g_slist_concat@Base 2.12.0 + g_slist_copy@Base 2.12.0 + g_slist_copy_deep@Base 2.33.14 + g_slist_delete_link@Base 2.12.0 + g_slist_find@Base 2.12.0 + g_slist_find_custom@Base 2.12.0 + g_slist_foreach@Base 2.12.0 + g_slist_free@Base 2.12.0 + g_slist_free_1@Base 2.12.0 + g_slist_free_full@Base 2.28.0 + g_slist_index@Base 2.12.0 + g_slist_insert@Base 2.12.0 + g_slist_insert_before@Base 2.12.0 + g_slist_insert_sorted@Base 2.12.0 + g_slist_insert_sorted_with_data@Base 2.12.0 + g_slist_last@Base 2.12.0 + g_slist_length@Base 2.12.0 + g_slist_nth@Base 2.12.0 + g_slist_nth_data@Base 2.12.0 + g_slist_pop_allocator@Base 2.12.0 + g_slist_position@Base 2.12.0 + g_slist_prepend@Base 2.12.0 + g_slist_push_allocator@Base 2.12.0 + g_slist_remove@Base 2.12.0 + g_slist_remove_all@Base 2.12.0 + g_slist_remove_link@Base 2.12.0 + g_slist_reverse@Base 2.12.0 + g_slist_sort@Base 2.12.0 + g_slist_sort_with_data@Base 2.12.0 + g_snprintf@Base 2.12.0 + g_source_add_child_source@Base 2.28.0 + g_source_add_poll@Base 2.12.0 + g_source_add_unix_fd@Base 2.35.8 + g_source_attach@Base 2.12.0 + g_source_destroy@Base 2.12.0 + g_source_get_can_recurse@Base 2.12.0 + g_source_get_context@Base 2.12.0 + g_source_get_current_time@Base 2.12.0 + g_source_get_id@Base 2.12.0 + g_source_get_name@Base 2.26.0 + g_source_get_priority@Base 2.12.0 + g_source_get_ready_time@Base 2.35.8 + g_source_get_time@Base 2.28.0 + g_source_is_destroyed@Base 2.12.0 + g_source_modify_unix_fd@Base 2.35.8 + g_source_new@Base 2.12.0 + g_source_query_unix_fd@Base 2.35.8 + g_source_ref@Base 2.12.0 + g_source_remove@Base 2.12.0 + g_source_remove_by_funcs_user_data@Base 2.12.0 + g_source_remove_by_user_data@Base 2.12.0 + g_source_remove_child_source@Base 2.28.0 + g_source_remove_poll@Base 2.12.0 + g_source_remove_unix_fd@Base 2.35.8 + g_source_set_callback@Base 2.12.0 + g_source_set_callback_indirect@Base 2.12.0 + g_source_set_can_recurse@Base 2.12.0 + g_source_set_dispose_function@Base 2.63.3 + g_source_set_funcs@Base 2.12.0 + g_source_set_name@Base 2.26.0 + g_source_set_name_by_id@Base 2.26.0 + g_source_set_priority@Base 2.12.0 + g_source_set_ready_time@Base 2.35.8 + g_source_set_static_name@Base 2.70.0 + g_source_unref@Base 2.12.0 + g_spaced_primes_closest@Base 2.12.0 + g_spawn_async@Base 2.12.0 + g_spawn_async_with_fds@Base 2.57.2 + g_spawn_async_with_pipes@Base 2.12.0 + g_spawn_async_with_pipes_and_fds@Base 2.67.4 + g_spawn_check_exit_status@Base 2.33.14 + g_spawn_check_wait_status@Base 2.70.0 + g_spawn_close_pid@Base 2.12.0 + g_spawn_command_line_async@Base 2.12.0 + g_spawn_command_line_sync@Base 2.12.0 + g_spawn_error_quark@Base 2.12.0 + g_spawn_exit_error_quark@Base 2.33.14 + g_spawn_sync@Base 2.12.0 + g_sprintf@Base 2.12.0 + g_stat@Base 2.12.0 + g_static_mutex_free@Base 2.12.0 + g_static_mutex_get_mutex_impl@Base 2.12.0 + g_static_mutex_init@Base 2.12.0 + g_static_private_free@Base 2.12.0 + g_static_private_get@Base 2.12.0 + g_static_private_init@Base 2.12.0 + g_static_private_set@Base 2.12.0 + g_static_rec_mutex_free@Base 2.12.0 + g_static_rec_mutex_init@Base 2.12.0 + g_static_rec_mutex_lock@Base 2.12.0 + g_static_rec_mutex_lock_full@Base 2.12.0 + g_static_rec_mutex_trylock@Base 2.12.0 + g_static_rec_mutex_unlock@Base 2.12.0 + g_static_rec_mutex_unlock_full@Base 2.12.0 + g_static_rw_lock_free@Base 2.12.0 + g_static_rw_lock_init@Base 2.12.0 + g_static_rw_lock_reader_lock@Base 2.12.0 + g_static_rw_lock_reader_trylock@Base 2.12.0 + g_static_rw_lock_reader_unlock@Base 2.12.0 + g_static_rw_lock_writer_lock@Base 2.12.0 + g_static_rw_lock_writer_trylock@Base 2.12.0 + g_static_rw_lock_writer_unlock@Base 2.12.0 + g_stpcpy@Base 2.12.0 + g_str_equal@Base 2.12.0 + g_str_has_prefix@Base 2.12.0 + g_str_has_suffix@Base 2.12.0 + g_str_hash@Base 2.12.0 + g_str_is_ascii@Base 2.39.4 + g_str_match_string@Base 2.39.4 + g_str_to_ascii@Base 2.39.91 + g_str_tokenize_and_fold@Base 2.39.4 + g_strcanon@Base 2.12.0 + g_strcasecmp@Base 2.12.0 + g_strchomp@Base 2.12.0 + g_strchug@Base 2.12.0 + g_strcmp0@Base 2.16.0 + g_strcompress@Base 2.12.0 + g_strconcat@Base 2.12.0 + g_strdelimit@Base 2.12.0 + g_strdown@Base 2.12.0 + g_strdup@Base 2.12.0 + g_strdup_printf@Base 2.12.0 + g_strdup_vprintf@Base 2.12.0 + g_strdupv@Base 2.12.0 + g_strerror@Base 2.12.0 + g_strescape@Base 2.12.0 + g_strfreev@Base 2.12.0 + g_string_append@Base 2.12.0 + g_string_append_c@Base 2.12.0 + g_string_append_len@Base 2.12.0 + g_string_append_printf@Base 2.12.0 + g_string_append_unichar@Base 2.12.0 + g_string_append_uri_escaped@Base 2.16.0 + g_string_append_vprintf@Base 2.14.0 + g_string_ascii_down@Base 2.12.0 + g_string_ascii_up@Base 2.12.0 + g_string_assign@Base 2.12.0 + g_string_chunk_clear@Base 2.14.0 + g_string_chunk_free@Base 2.12.0 + g_string_chunk_insert@Base 2.12.0 + g_string_chunk_insert_const@Base 2.12.0 + g_string_chunk_insert_len@Base 2.12.0 + g_string_chunk_new@Base 2.12.0 + g_string_down@Base 2.12.0 + g_string_equal@Base 2.12.0 + g_string_erase@Base 2.12.0 + g_string_free@Base 2.12.0 + g_string_free_to_bytes@Base 2.33.14 + g_string_hash@Base 2.12.0 + g_string_insert@Base 2.12.0 + g_string_insert_c@Base 2.12.0 + g_string_insert_len@Base 2.12.0 + g_string_insert_unichar@Base 2.12.0 + g_string_new@Base 2.12.0 + g_string_new_len@Base 2.12.0 + g_string_overwrite@Base 2.14.0 + g_string_overwrite_len@Base 2.14.0 + g_string_prepend@Base 2.12.0 + g_string_prepend_c@Base 2.12.0 + g_string_prepend_len@Base 2.12.0 + g_string_prepend_unichar@Base 2.12.0 + g_string_printf@Base 2.12.0 + g_string_replace@Base 2.67.3+git20210214 + g_string_set_size@Base 2.12.0 + g_string_sized_new@Base 2.12.0 + g_string_truncate@Base 2.12.0 + g_string_up@Base 2.12.0 + g_string_vprintf@Base 2.14.0 + g_strip_context@Base 2.12.0 + g_strjoin@Base 2.12.0 + g_strjoinv@Base 2.12.0 + g_strlcat@Base 2.12.0 + g_strlcpy@Base 2.12.0 + g_strncasecmp@Base 2.12.0 + g_strndup@Base 2.12.0 + g_strnfill@Base 2.12.0 + g_strreverse@Base 2.12.0 + g_strrstr@Base 2.12.0 + g_strrstr_len@Base 2.12.0 + g_strsignal@Base 2.12.0 + g_strsplit@Base 2.12.0 + g_strsplit_set@Base 2.12.0 + g_strstr_len@Base 2.12.0 + g_strtod@Base 2.12.0 + g_strup@Base 2.12.0 + g_strv_builder_add@Base 2.67.1 + g_strv_builder_add_many@Base 2.70.0 + g_strv_builder_addv@Base 2.70.0 + g_strv_builder_end@Base 2.67.1 + g_strv_builder_new@Base 2.67.1 + g_strv_builder_ref@Base 2.67.1 + g_strv_builder_unref@Base 2.67.1 + g_strv_contains@Base 2.43.2 + g_strv_equal@Base 2.59.0 + g_strv_length@Base 2.12.0 + g_test_add_data_func@Base 2.16.0 + g_test_add_data_func_full@Base 2.33.14 + g_test_add_func@Base 2.16.0 + g_test_add_vtable@Base 2.16.0 + g_test_assert_expected_messages_internal@Base 2.33.14 + g_test_bug@Base 2.16.0 + g_test_bug_base@Base 2.16.0 + g_test_build_filename@Base 2.37.2 + g_test_case_free@Base 2.70.0 + g_test_config_vars@Base 2.16.0 + g_test_create_case@Base 2.16.0 + g_test_create_suite@Base 2.16.0 + g_test_expect_message@Base 2.33.14 + g_test_fail@Base 2.30.0 + g_test_fail_printf@Base 2.70.0 + g_test_failed@Base 2.37.6 + g_test_get_dir@Base 2.37.2 + g_test_get_filename@Base 2.37.2 + g_test_get_path@Base 2.67.3 + g_test_get_root@Base 2.16.0 + g_test_incomplete@Base 2.37.6 + g_test_incomplete_printf@Base 2.70.0 + g_test_init@Base 2.16.0 + g_test_log_buffer_free@Base 2.16.0 + g_test_log_buffer_new@Base 2.16.0 + g_test_log_buffer_pop@Base 2.16.0 + g_test_log_buffer_push@Base 2.16.0 + g_test_log_msg_free@Base 2.16.0 + g_test_log_set_fatal_handler@Base 2.22.0 + g_test_log_type_name@Base 2.16.0 + g_test_maximized_result@Base 2.16.0 + g_test_message@Base 2.16.0 + g_test_minimized_result@Base 2.16.0 + g_test_queue_destroy@Base 2.16.0 + g_test_queue_free@Base 2.16.0 + g_test_rand_double@Base 2.16.0 + g_test_rand_double_range@Base 2.16.0 + g_test_rand_int@Base 2.16.0 + g_test_rand_int_range@Base 2.16.0 + g_test_run@Base 2.16.0 + g_test_run_suite@Base 2.16.0 + g_test_set_nonfatal_assertions@Base 2.37.6 + g_test_skip@Base 2.37.6 + g_test_skip_printf@Base 2.70.0 + g_test_subprocess@Base 2.37.1 + g_test_suite_add@Base 2.16.0 + g_test_suite_add_suite@Base 2.16.0 + g_test_suite_free@Base 2.70.0 + g_test_summary@Base 2.61.1 + g_test_timer_elapsed@Base 2.16.0 + g_test_timer_last@Base 2.16.0 + g_test_timer_start@Base 2.16.0 + g_test_trap_assertions@Base 2.16.0 + g_test_trap_fork@Base 2.16.0 + g_test_trap_has_passed@Base 2.16.0 + g_test_trap_reached_timeout@Base 2.16.0 + g_test_trap_subprocess@Base 2.37.1 + g_thread_create@Base 2.31.8 + g_thread_create_full@Base 2.12.0 + g_thread_error_quark@Base 2.12.0 + g_thread_exit@Base 2.12.0 + g_thread_foreach@Base 2.12.0 + g_thread_functions_for_glib_use@Base 2.12.0 + g_thread_get_initialized@Base 2.20.0 + g_thread_gettime@Base 2.14.0 + g_thread_init_glib@Base 2.12.0 + g_thread_join@Base 2.12.0 + g_thread_new@Base 2.31.8 + g_thread_pool_free@Base 2.12.0 + g_thread_pool_get_max_idle_time@Base 2.12.0 + g_thread_pool_get_max_threads@Base 2.12.0 + g_thread_pool_get_max_unused_threads@Base 2.12.0 + g_thread_pool_get_num_threads@Base 2.12.0 + g_thread_pool_get_num_unused_threads@Base 2.12.0 + g_thread_pool_move_to_front@Base 2.45.4 + g_thread_pool_new@Base 2.12.0 + g_thread_pool_new_full@Base 2.70.0 + g_thread_pool_push@Base 2.12.0 + g_thread_pool_set_max_idle_time@Base 2.12.0 + g_thread_pool_set_max_threads@Base 2.12.0 + g_thread_pool_set_max_unused_threads@Base 2.12.0 + g_thread_pool_set_sort_function@Base 2.12.0 + g_thread_pool_stop_unused_threads@Base 2.12.0 + g_thread_pool_unprocessed@Base 2.12.0 + g_thread_ref@Base 2.31.8 + g_thread_self@Base 2.12.0 + g_thread_set_priority@Base 2.12.0 + g_thread_try_new@Base 2.31.8 + g_thread_unref@Base 2.31.8 + g_thread_use_default_impl@Base 2.12.0 + g_thread_yield@Base 2.31.8 + g_threads_got_initialized@Base 2.12.0 + g_time_val_add@Base 2.12.0 + g_time_val_from_iso8601@Base 2.12.0 + g_time_val_to_iso8601@Base 2.12.0 + g_time_zone_adjust_time@Base 2.28.0 + g_time_zone_find_interval@Base 2.28.0 + g_time_zone_get_abbreviation@Base 2.28.0 + g_time_zone_get_identifier@Base 2.57.2 + g_time_zone_get_offset@Base 2.28.0 + g_time_zone_is_dst@Base 2.28.0 + g_time_zone_new@Base 2.26.0 + g_time_zone_new_identifier@Base 2.67.1 + g_time_zone_new_local@Base 2.26.0 + g_time_zone_new_offset@Base 2.57.2 + g_time_zone_new_utc@Base 2.26.0 + g_time_zone_ref@Base 2.26.0 + g_time_zone_unref@Base 2.26.0 + g_timeout_add@Base 2.12.0 + g_timeout_add_full@Base 2.12.0 + g_timeout_add_seconds@Base 2.14.0 + g_timeout_add_seconds_full@Base 2.14.0 + g_timeout_funcs@Base 2.12.0 + g_timeout_source_new@Base 2.12.0 + g_timeout_source_new_seconds@Base 2.14.0 + g_timer_continue@Base 2.12.0 + g_timer_destroy@Base 2.12.0 + g_timer_elapsed@Base 2.12.0 + g_timer_is_active@Base 2.61.2 + g_timer_new@Base 2.12.0 + g_timer_reset@Base 2.12.0 + g_timer_start@Base 2.12.0 + g_timer_stop@Base 2.12.0 + g_trash_stack_height@Base 2.12.0 + g_trash_stack_peek@Base 2.12.0 + g_trash_stack_pop@Base 2.12.0 + g_trash_stack_push@Base 2.12.0 + g_tree_destroy@Base 2.12.0 + g_tree_foreach@Base 2.12.0 + g_tree_foreach_node@Base 2.67.1 + g_tree_height@Base 2.12.0 + g_tree_insert@Base 2.12.0 + g_tree_insert_node@Base 2.67.1 + g_tree_lookup@Base 2.12.0 + g_tree_lookup_extended@Base 2.12.0 + g_tree_lookup_node@Base 2.67.1 + g_tree_lower_bound@Base 2.67.1 + g_tree_new@Base 2.12.0 + g_tree_new_full@Base 2.12.0 + g_tree_new_with_data@Base 2.12.0 + g_tree_nnodes@Base 2.12.0 + g_tree_node_first@Base 2.67.1 + g_tree_node_key@Base 2.67.1 + g_tree_node_last@Base 2.67.1 + g_tree_node_next@Base 2.67.1 + g_tree_node_previous@Base 2.67.1 + g_tree_node_value@Base 2.67.1 + g_tree_ref@Base 2.22.0 + g_tree_remove@Base 2.12.0 + g_tree_remove_all@Base 2.70.0 + g_tree_replace@Base 2.12.0 + g_tree_replace_node@Base 2.67.1 + g_tree_search@Base 2.12.0 + g_tree_search_node@Base 2.67.1 + g_tree_steal@Base 2.12.0 + g_tree_traverse@Base 2.12.0 + g_tree_unref@Base 2.22.0 + g_tree_upper_bound@Base 2.67.1 + g_try_malloc0@Base 2.12.0 + g_try_malloc0_n@Base 2.24.0 + g_try_malloc@Base 2.12.0 + g_try_malloc_n@Base 2.24.0 + g_try_realloc@Base 2.12.0 + g_try_realloc_n@Base 2.24.0 + g_tuples_destroy@Base 2.12.0 + g_tuples_index@Base 2.12.0 + g_ucs4_to_utf16@Base 2.12.0 + g_ucs4_to_utf8@Base 2.12.0 + g_unichar_break_type@Base 2.12.0 + g_unichar_combining_class@Base 2.14.0 + g_unichar_compose@Base 2.30.0 + g_unichar_decompose@Base 2.30.0 + g_unichar_digit_value@Base 2.12.0 + g_unichar_fully_decompose@Base 2.30.0 + g_unichar_get_mirror_char@Base 2.12.0 + g_unichar_get_script@Base 2.14.0 + g_unichar_isalnum@Base 2.12.0 + g_unichar_isalpha@Base 2.12.0 + g_unichar_iscntrl@Base 2.12.0 + g_unichar_isdefined@Base 2.12.0 + g_unichar_isdigit@Base 2.12.0 + g_unichar_isgraph@Base 2.12.0 + g_unichar_islower@Base 2.12.0 + g_unichar_ismark@Base 2.14.0 + g_unichar_isprint@Base 2.12.0 + g_unichar_ispunct@Base 2.12.0 + g_unichar_isspace@Base 2.12.0 + g_unichar_istitle@Base 2.12.0 + g_unichar_isupper@Base 2.12.0 + g_unichar_iswide@Base 2.12.0 + g_unichar_iswide_cjk@Base 2.12.0 + g_unichar_isxdigit@Base 2.12.0 + g_unichar_iszerowidth@Base 2.14.0 + g_unichar_to_utf8@Base 2.12.0 + g_unichar_tolower@Base 2.12.0 + g_unichar_totitle@Base 2.12.0 + g_unichar_toupper@Base 2.12.0 + g_unichar_type@Base 2.12.0 + g_unichar_validate@Base 2.12.0 + g_unichar_xdigit_value@Base 2.12.0 + g_unicode_canonical_decomposition@Base 2.12.0 + g_unicode_canonical_ordering@Base 2.12.0 + g_unicode_script_from_iso15924@Base 2.30.0 + g_unicode_script_to_iso15924@Base 2.30.0 + g_unix_error_quark@Base 2.30.0 + g_unix_fd_add@Base 2.35.8 + g_unix_fd_add_full@Base 2.35.8 + g_unix_fd_source_funcs@Base 2.37.5 + g_unix_fd_source_new@Base 2.35.8 + g_unix_get_passwd_entry@Base 2.63.3 + g_unix_open_pipe@Base 2.30.0 + g_unix_set_fd_nonblocking@Base 2.30.0 + g_unix_signal_add@Base 2.30.0 + g_unix_signal_add_full@Base 2.30.0 + g_unix_signal_funcs@Base 2.37.5 + g_unix_signal_source_new@Base 2.30.0 + g_unlink@Base 2.12.0 + g_unsetenv@Base 2.12.0 + g_uri_build@Base 2.65.1 + g_uri_build_with_user@Base 2.65.1 + g_uri_error_quark@Base 2.65.1 + g_uri_escape_bytes@Base 2.65.1 + g_uri_escape_string@Base 2.16.0 + g_uri_get_auth_params@Base 2.65.1 + g_uri_get_flags@Base 2.65.1 + g_uri_get_fragment@Base 2.65.1 + g_uri_get_host@Base 2.65.1 + g_uri_get_password@Base 2.65.1 + g_uri_get_path@Base 2.65.1 + g_uri_get_port@Base 2.65.1 + g_uri_get_query@Base 2.65.1 + g_uri_get_scheme@Base 2.65.1 + g_uri_get_user@Base 2.65.1 + g_uri_get_userinfo@Base 2.65.1 + g_uri_is_valid@Base 2.65.1 + g_uri_join@Base 2.65.1 + g_uri_join_with_user@Base 2.65.1 + g_uri_list_extract_uris@Base 2.12.0 + g_uri_params_iter_init@Base 2.65.1 + g_uri_params_iter_next@Base 2.65.1 + g_uri_parse@Base 2.65.1 + g_uri_parse_params@Base 2.65.1 + g_uri_parse_relative@Base 2.65.1 + g_uri_parse_scheme@Base 2.16.0 + g_uri_peek_scheme@Base 2.65.1 + g_uri_ref@Base 2.65.1 + g_uri_resolve_relative@Base 2.65.1 + g_uri_split@Base 2.65.1 + g_uri_split_network@Base 2.65.1 + g_uri_split_with_user@Base 2.65.1 + g_uri_to_string@Base 2.65.1 + g_uri_to_string_partial@Base 2.65.1 + g_uri_unescape_bytes@Base 2.65.1 + g_uri_unescape_segment@Base 2.16.0 + g_uri_unescape_string@Base 2.16.0 + g_uri_unref@Base 2.65.1 + g_usleep@Base 2.12.0 + g_utf16_to_ucs4@Base 2.12.0 + g_utf16_to_utf8@Base 2.12.0 + g_utf8_casefold@Base 2.12.0 + g_utf8_collate@Base 2.12.0 + g_utf8_collate_key@Base 2.12.0 + g_utf8_collate_key_for_filename@Base 2.12.0 + g_utf8_find_next_char@Base 2.12.0 + g_utf8_find_prev_char@Base 2.12.0 + g_utf8_get_char@Base 2.12.0 + g_utf8_get_char_validated@Base 2.12.0 + g_utf8_make_valid@Base 2.51.0 + g_utf8_normalize@Base 2.12.0 + g_utf8_offset_to_pointer@Base 2.12.0 + g_utf8_pointer_to_offset@Base 2.12.0 + g_utf8_prev_char@Base 2.12.0 + g_utf8_skip@Base 2.12.0 + g_utf8_strchr@Base 2.12.0 + g_utf8_strdown@Base 2.12.0 + g_utf8_strlen@Base 2.12.0 + g_utf8_strncpy@Base 2.12.0 + g_utf8_strrchr@Base 2.12.0 + g_utf8_strreverse@Base 2.12.0 + g_utf8_strup@Base 2.12.0 + g_utf8_substring@Base 2.30.0 + g_utf8_to_ucs4@Base 2.12.0 + g_utf8_to_ucs4_fast@Base 2.12.0 + g_utf8_to_utf16@Base 2.12.0 + g_utf8_validate@Base 2.12.0 + g_utf8_validate_len@Base 2.59.0 + g_utime@Base 2.18.0 + g_uuid_string_is_valid@Base 2.51.2 + g_uuid_string_random@Base 2.51.2 + g_variant_builder_add@Base 2.24.0 + g_variant_builder_add_parsed@Base 2.26.0 + g_variant_builder_add_value@Base 2.24.0 + g_variant_builder_clear@Base 2.24.0 + g_variant_builder_close@Base 2.24.0 + g_variant_builder_end@Base 2.24.0 + g_variant_builder_init@Base 2.24.0 + g_variant_builder_new@Base 2.24.0 + g_variant_builder_open@Base 2.24.0 + g_variant_builder_ref@Base 2.24.0 + g_variant_builder_unref@Base 2.24.0 + g_variant_byteswap@Base 2.24.0 + g_variant_check_format_string@Base 2.33.14 + g_variant_classify@Base 2.24.0 + g_variant_compare@Base 2.26.0 + g_variant_dict_clear@Base 2.39.90 + g_variant_dict_contains@Base 2.39.90 + g_variant_dict_end@Base 2.39.90 + g_variant_dict_init@Base 2.39.90 + g_variant_dict_insert@Base 2.39.90 + g_variant_dict_insert_value@Base 2.39.90 + g_variant_dict_lookup@Base 2.39.90 + g_variant_dict_lookup_value@Base 2.39.90 + g_variant_dict_new@Base 2.39.90 + g_variant_dict_ref@Base 2.39.90 + g_variant_dict_remove@Base 2.39.90 + g_variant_dict_unref@Base 2.39.90 + g_variant_dup_bytestring@Base 2.26.0 + g_variant_dup_bytestring_array@Base 2.26.0 + g_variant_dup_objv@Base 2.30.0 + g_variant_dup_string@Base 2.24.0 + g_variant_dup_strv@Base 2.24.0 + g_variant_equal@Base 2.24.0 + g_variant_format_string_scan@Base 2.24.0 + g_variant_format_string_scan_type@Base 2.24.0 + g_variant_get@Base 2.24.0 + g_variant_get_boolean@Base 2.24.0 + g_variant_get_byte@Base 2.24.0 + g_variant_get_bytestring@Base 2.26.0 + g_variant_get_bytestring_array@Base 2.26.0 + g_variant_get_child@Base 2.24.0 + g_variant_get_child_value@Base 2.24.0 + g_variant_get_data@Base 2.24.0 + g_variant_get_data_as_bytes@Base 2.35.8 + g_variant_get_double@Base 2.24.0 + g_variant_get_fixed_array@Base 2.24.0 + g_variant_get_handle@Base 2.24.0 + g_variant_get_int16@Base 2.24.0 + g_variant_get_int32@Base 2.24.0 + g_variant_get_int64@Base 2.24.0 + g_variant_get_maybe@Base 2.24.0 + g_variant_get_normal_form@Base 2.24.0 + g_variant_get_objv@Base 2.30.0 + g_variant_get_size@Base 2.24.0 + g_variant_get_string@Base 2.24.0 + g_variant_get_strv@Base 2.24.0 + g_variant_get_type@Base 2.24.0 + g_variant_get_type_string@Base 2.24.0 + g_variant_get_uint16@Base 2.24.0 + g_variant_get_uint32@Base 2.24.0 + g_variant_get_uint64@Base 2.24.0 + g_variant_get_va@Base 2.24.0 + g_variant_get_variant@Base 2.24.0 + g_variant_hash@Base 2.24.0 + g_variant_is_container@Base 2.24.0 + g_variant_is_floating@Base 2.26.0 + g_variant_is_normal_form@Base 2.24.0 + g_variant_is_object_path@Base 2.24.0 + g_variant_is_of_type@Base 2.24.0 + g_variant_is_signature@Base 2.24.0 + g_variant_iter_copy@Base 2.24.0 + g_variant_iter_free@Base 2.24.0 + g_variant_iter_init@Base 2.24.0 + g_variant_iter_loop@Base 2.24.0 + g_variant_iter_n_children@Base 2.24.0 + g_variant_iter_new@Base 2.24.0 + g_variant_iter_next@Base 2.24.0 + g_variant_iter_next_value@Base 2.24.0 + g_variant_lookup@Base 2.28.0 + g_variant_lookup_value@Base 2.28.0 + g_variant_n_children@Base 2.24.0 + g_variant_new@Base 2.24.0 + g_variant_new_array@Base 2.24.0 + g_variant_new_boolean@Base 2.24.0 + g_variant_new_byte@Base 2.24.0 + g_variant_new_bytestring@Base 2.26.0 + g_variant_new_bytestring_array@Base 2.26.0 + g_variant_new_dict_entry@Base 2.24.0 + g_variant_new_double@Base 2.24.0 + g_variant_new_fixed_array@Base 2.31.8 + g_variant_new_from_bytes@Base 2.35.8 + g_variant_new_from_data@Base 2.24.0 + g_variant_new_handle@Base 2.24.0 + g_variant_new_int16@Base 2.24.0 + g_variant_new_int32@Base 2.24.0 + g_variant_new_int64@Base 2.24.0 + g_variant_new_maybe@Base 2.24.0 + g_variant_new_object_path@Base 2.24.0 + g_variant_new_objv@Base 2.30.0 + g_variant_new_parsed@Base 2.24.0 + g_variant_new_parsed_va@Base 2.24.0 + g_variant_new_printf@Base 2.37.5 + g_variant_new_signature@Base 2.24.0 + g_variant_new_string@Base 2.24.0 + g_variant_new_strv@Base 2.24.0 + g_variant_new_take_string@Base 2.37.0 + g_variant_new_tuple@Base 2.24.0 + g_variant_new_uint16@Base 2.24.0 + g_variant_new_uint32@Base 2.24.0 + g_variant_new_uint64@Base 2.24.0 + g_variant_new_va@Base 2.24.0 + g_variant_new_variant@Base 2.24.0 + g_variant_parse@Base 2.24.0 + g_variant_parse_error_print_context@Base 2.39.4 + g_variant_parse_error_quark@Base 2.39.4 + g_variant_parser_get_error_quark@Base 2.24.0 + g_variant_print@Base 2.24.0 + g_variant_print_string@Base 2.24.0 + g_variant_ref@Base 2.24.0 + g_variant_ref_sink@Base 2.24.0 + g_variant_serialised_byteswap@Base 2.24.0 + g_variant_serialised_check@Base 2.59.0 + g_variant_serialised_get_child@Base 2.24.0 + g_variant_serialised_is_normal@Base 2.24.0 + g_variant_serialised_n_children@Base 2.24.0 + g_variant_serialiser_is_object_path@Base 2.24.0 + g_variant_serialiser_is_signature@Base 2.24.0 + g_variant_serialiser_is_string@Base 2.24.0 + g_variant_serialiser_needed_size@Base 2.24.0 + g_variant_serialiser_serialise@Base 2.24.0 + g_variant_store@Base 2.24.0 + g_variant_take_ref@Base 2.30.0 + g_variant_type_checked_@Base 2.24.0 + g_variant_type_copy@Base 2.24.0 + g_variant_type_dup_string@Base 2.24.0 + g_variant_type_element@Base 2.24.0 + g_variant_type_equal@Base 2.24.0 + g_variant_type_first@Base 2.24.0 + g_variant_type_free@Base 2.24.0 + g_variant_type_get_string_length@Base 2.24.0 + g_variant_type_hash@Base 2.24.0 + g_variant_type_info_assert_no_infos@Base 2.24.0 + g_variant_type_info_element@Base 2.24.0 + g_variant_type_info_get@Base 2.24.0 + g_variant_type_info_get_type_string@Base 2.24.0 + g_variant_type_info_member_info@Base 2.24.0 + g_variant_type_info_n_members@Base 2.24.0 + g_variant_type_info_query@Base 2.24.0 + g_variant_type_info_query_depth@Base 2.58.2 + g_variant_type_info_query_element@Base 2.24.0 + g_variant_type_info_ref@Base 2.24.0 + g_variant_type_info_unref@Base 2.24.0 + g_variant_type_is_array@Base 2.24.0 + g_variant_type_is_basic@Base 2.24.0 + g_variant_type_is_container@Base 2.24.0 + g_variant_type_is_definite@Base 2.24.0 + g_variant_type_is_dict_entry@Base 2.24.0 + g_variant_type_is_maybe@Base 2.24.0 + g_variant_type_is_subtype_of@Base 2.24.0 + g_variant_type_is_tuple@Base 2.24.0 + g_variant_type_is_variant@Base 2.24.0 + g_variant_type_key@Base 2.24.0 + g_variant_type_n_items@Base 2.24.0 + g_variant_type_new@Base 2.24.0 + g_variant_type_new_array@Base 2.24.0 + g_variant_type_new_dict_entry@Base 2.24.0 + g_variant_type_new_maybe@Base 2.24.0 + g_variant_type_new_tuple@Base 2.24.0 + g_variant_type_next@Base 2.24.0 + g_variant_type_peek_string@Base 2.24.0 + g_variant_type_string_get_depth_@Base 2.58.2 + g_variant_type_string_is_valid@Base 2.24.0 + g_variant_type_string_scan@Base 2.24.0 + g_variant_type_value@Base 2.24.0 + g_variant_unref@Base 2.24.0 + g_vasprintf@Base 2.12.0 + g_vfprintf@Base 2.12.0 + g_vprintf@Base 2.12.0 + g_vsnprintf@Base 2.12.0 + g_vsprintf@Base 2.12.0 + g_warn_message@Base 2.16.0 + glib__private__@Base 2.31.8 + glib_binary_age@Base 2.12.0 + glib_check_version@Base 2.12.0 + glib_gettext@Base 2.16.0 + glib_interface_age@Base 2.12.0 + glib_major_version@Base 2.12.0 + glib_mem_profiler_table@Base 2.12.0 + glib_micro_version@Base 2.12.0 + glib_minor_version@Base 2.12.0 + glib_on_error_halt@Base 2.12.0 + glib_pgettext@Base 2.28.3 +libgmodule-2.0.so.0 libglib2.0-0 #MINVER# +* Build-Depends-Package: libglib2.0-dev + g_module_build_path@Base 2.12.0 + g_module_close@Base 2.12.0 + g_module_error@Base 2.12.0 + g_module_error_quark@Base 2.70.0 + g_module_make_resident@Base 2.12.0 + g_module_name@Base 2.12.0 + g_module_open@Base 2.12.0 + g_module_open_full@Base 2.70.0 + g_module_supported@Base 2.12.0 + g_module_symbol@Base 2.12.0 +libgobject-2.0.so.0 libglib2.0-0 #MINVER# +* Build-Depends-Package: libglib2.0-dev + g_array_get_type@Base 2.22.0 + g_binding_dup_source@Base 2.67.1 + g_binding_dup_target@Base 2.67.1 + g_binding_flags_get_type@Base 2.26.0 + g_binding_get_flags@Base 2.26.0 + g_binding_get_source@Base 2.26.0 + g_binding_get_source_property@Base 2.26.0 + g_binding_get_target@Base 2.26.0 + g_binding_get_target_property@Base 2.26.0 + g_binding_get_type@Base 2.26.0 + g_binding_group_bind@Base 2.71.2 + g_binding_group_bind_full@Base 2.71.2 + g_binding_group_bind_with_closures@Base 2.71.2 + g_binding_group_dup_source@Base 2.71.2 + g_binding_group_get_type@Base 2.71.2 + g_binding_group_new@Base 2.71.2 + g_binding_group_set_source@Base 2.71.2 + g_binding_unbind@Base 2.37.1 + g_boxed_copy@Base 2.12.0 + g_boxed_free@Base 2.12.0 + g_boxed_type_register_static@Base 2.12.0 + g_byte_array_get_type@Base 2.22.0 + g_bytes_get_type@Base 2.31.8 + g_cclosure_marshal_BOOLEAN__BOXED_BOXED@Base 2.26.0 + g_cclosure_marshal_BOOLEAN__BOXED_BOXEDv@Base 2.31.20 + g_cclosure_marshal_BOOLEAN__FLAGS@Base 2.12.0 + g_cclosure_marshal_BOOLEAN__FLAGSv@Base 2.31.20 + g_cclosure_marshal_STRING__OBJECT_POINTER@Base 2.12.0 + g_cclosure_marshal_STRING__OBJECT_POINTERv@Base 2.31.20 + g_cclosure_marshal_VOID__BOOLEAN@Base 2.12.0 + g_cclosure_marshal_VOID__BOOLEANv@Base 2.31.20 + g_cclosure_marshal_VOID__BOXED@Base 2.12.0 + g_cclosure_marshal_VOID__BOXEDv@Base 2.31.20 + g_cclosure_marshal_VOID__CHAR@Base 2.12.0 + g_cclosure_marshal_VOID__CHARv@Base 2.31.20 + g_cclosure_marshal_VOID__DOUBLE@Base 2.12.0 + g_cclosure_marshal_VOID__DOUBLEv@Base 2.31.20 + g_cclosure_marshal_VOID__ENUM@Base 2.12.0 + g_cclosure_marshal_VOID__ENUMv@Base 2.31.20 + g_cclosure_marshal_VOID__FLAGS@Base 2.12.0 + g_cclosure_marshal_VOID__FLAGSv@Base 2.31.20 + g_cclosure_marshal_VOID__FLOAT@Base 2.12.0 + g_cclosure_marshal_VOID__FLOATv@Base 2.31.20 + g_cclosure_marshal_VOID__INT@Base 2.12.0 + g_cclosure_marshal_VOID__INTv@Base 2.31.20 + g_cclosure_marshal_VOID__LONG@Base 2.12.0 + g_cclosure_marshal_VOID__LONGv@Base 2.31.20 + g_cclosure_marshal_VOID__OBJECT@Base 2.12.0 + g_cclosure_marshal_VOID__OBJECTv@Base 2.31.20 + g_cclosure_marshal_VOID__PARAM@Base 2.12.0 + g_cclosure_marshal_VOID__PARAMv@Base 2.31.20 + g_cclosure_marshal_VOID__POINTER@Base 2.12.0 + g_cclosure_marshal_VOID__POINTERv@Base 2.31.20 + g_cclosure_marshal_VOID__STRING@Base 2.12.0 + g_cclosure_marshal_VOID__STRINGv@Base 2.31.20 + g_cclosure_marshal_VOID__UCHAR@Base 2.12.0 + g_cclosure_marshal_VOID__UCHARv@Base 2.31.20 + g_cclosure_marshal_VOID__UINT@Base 2.12.0 + g_cclosure_marshal_VOID__UINT_POINTER@Base 2.12.0 + g_cclosure_marshal_VOID__UINT_POINTERv@Base 2.31.20 + g_cclosure_marshal_VOID__UINTv@Base 2.31.20 + g_cclosure_marshal_VOID__ULONG@Base 2.12.0 + g_cclosure_marshal_VOID__ULONGv@Base 2.31.20 + g_cclosure_marshal_VOID__VARIANT@Base 2.26.0 + g_cclosure_marshal_VOID__VARIANTv@Base 2.31.20 + g_cclosure_marshal_VOID__VOID@Base 2.12.0 + g_cclosure_marshal_VOID__VOIDv@Base 2.31.20 + g_cclosure_marshal_generic@Base 2.30.0 + g_cclosure_marshal_generic_va@Base 2.31.20 + g_cclosure_new@Base 2.12.0 + g_cclosure_new_object@Base 2.12.0 + g_cclosure_new_object_swap@Base 2.12.0 + g_cclosure_new_swap@Base 2.12.0 + g_checksum_get_type@Base 2.35.8 + g_clear_object@Base 2.28.0 + g_clear_signal_handler@Base 2.61.1 + g_closure_add_finalize_notifier@Base 2.12.0 + g_closure_add_invalidate_notifier@Base 2.12.0 + g_closure_add_marshal_guards@Base 2.12.0 + g_closure_get_type@Base 2.12.0 + g_closure_invalidate@Base 2.12.0 + g_closure_invoke@Base 2.12.0 + g_closure_new_object@Base 2.12.0 + g_closure_new_simple@Base 2.12.0 + g_closure_ref@Base 2.12.0 + g_closure_remove_finalize_notifier@Base 2.12.0 + g_closure_remove_invalidate_notifier@Base 2.12.0 + g_closure_set_marshal@Base 2.12.0 + g_closure_set_meta_marshal@Base 2.12.0 + g_closure_sink@Base 2.12.0 + g_closure_unref@Base 2.12.0 + g_date_get_type@Base 2.12.0 + g_date_time_get_type@Base 2.26.0 + g_enum_complete_type_info@Base 2.12.0 + g_enum_get_value@Base 2.12.0 + g_enum_get_value_by_name@Base 2.12.0 + g_enum_get_value_by_nick@Base 2.12.0 + g_enum_register_static@Base 2.12.0 + g_enum_to_string@Base 2.53.1 + g_error_get_type@Base 2.26.0 + g_flags_complete_type_info@Base 2.12.0 + g_flags_get_first_value@Base 2.12.0 + g_flags_get_value_by_name@Base 2.12.0 + g_flags_get_value_by_nick@Base 2.12.0 + g_flags_register_static@Base 2.12.0 + g_flags_to_string@Base 2.53.1 + g_gstring_get_type@Base 2.12.0 + g_gtype_get_type@Base 2.12.0 + g_hash_table_get_type@Base 2.12.0 + g_initially_unowned_get_type@Base 2.12.0 + g_io_channel_get_type@Base 2.12.0 + g_io_condition_get_type@Base 2.12.0 + g_key_file_get_type@Base 2.31.8 + g_main_context_get_type@Base 2.30.0 + g_main_loop_get_type@Base 2.30.0 + g_mapped_file_get_type@Base 2.39.4 + g_markup_parse_context_get_type@Base 2.35.8 + g_match_info_get_type@Base 2.30.0 + g_normalize_mode_get_type@Base 2.59.2 + g_object_add_toggle_ref@Base 2.12.0 + g_object_add_weak_pointer@Base 2.12.0 + g_object_bind_property@Base 2.26.0 + g_object_bind_property_full@Base 2.26.0 + g_object_bind_property_with_closures@Base 2.26.0 + g_object_class_find_property@Base 2.12.0 + g_object_class_install_properties@Base 2.26.0 + g_object_class_install_property@Base 2.12.0 + g_object_class_list_properties@Base 2.12.0 + g_object_class_override_property@Base 2.12.0 + g_object_compat_control@Base 2.12.0 + g_object_connect@Base 2.12.0 + g_object_disconnect@Base 2.12.0 + g_object_dup_data@Base 2.33.14 + g_object_dup_qdata@Base 2.33.14 + g_object_force_floating@Base 2.12.0 + g_object_freeze_notify@Base 2.12.0 + g_object_get@Base 2.12.0 + g_object_get_data@Base 2.12.0 + g_object_get_property@Base 2.12.0 + g_object_get_qdata@Base 2.12.0 + g_object_get_type@Base 2.18.0 + g_object_get_valist@Base 2.12.0 + g_object_getv@Base 2.53.1 + g_object_interface_find_property@Base 2.12.0 + g_object_interface_install_property@Base 2.12.0 + g_object_interface_list_properties@Base 2.12.0 + g_object_is_floating@Base 2.12.0 + g_object_new@Base 2.12.0 + g_object_new_valist@Base 2.12.0 + g_object_newv@Base 2.12.0 + g_object_new_with_properties@Base 2.53.1 + g_object_notify@Base 2.12.0 + g_object_notify_by_pspec@Base 2.26.0 + g_object_ref@Base 2.12.0 + g_object_ref_sink@Base 2.12.0 + g_object_take_ref@Base 2.70.0 + g_object_remove_toggle_ref@Base 2.12.0 + g_object_remove_weak_pointer@Base 2.12.0 + g_object_replace_data@Base 2.33.14 + g_object_replace_qdata@Base 2.33.14 + g_object_run_dispose@Base 2.12.0 + g_object_set@Base 2.12.0 + g_object_set_data@Base 2.12.0 + g_object_set_data_full@Base 2.12.0 + g_object_set_property@Base 2.12.0 + g_object_set_qdata@Base 2.12.0 + g_object_set_qdata_full@Base 2.12.0 + g_object_set_valist@Base 2.12.0 + g_object_setv@Base 2.53.1 + g_object_steal_data@Base 2.12.0 + g_object_steal_qdata@Base 2.12.0 + g_object_thaw_notify@Base 2.12.0 + g_object_unref@Base 2.12.0 + g_object_watch_closure@Base 2.12.0 + g_object_weak_ref@Base 2.12.0 + g_object_weak_unref@Base 2.12.0 + g_option_group_get_type@Base 2.43.90 + g_param_spec_boolean@Base 2.12.0 + g_param_spec_boxed@Base 2.12.0 + g_param_spec_char@Base 2.12.0 + g_param_spec_double@Base 2.12.0 + g_param_spec_enum@Base 2.12.0 + g_param_spec_flags@Base 2.12.0 + g_param_spec_float@Base 2.12.0 + g_param_spec_get_blurb@Base 2.12.0 + g_param_spec_get_default_value@Base 2.37.0 + g_param_spec_get_name@Base 2.12.0 + g_param_spec_get_name_quark@Base 2.45.8 + g_param_spec_get_nick@Base 2.12.0 + g_param_spec_get_qdata@Base 2.12.0 + g_param_spec_get_redirect_target@Base 2.12.0 + g_param_spec_gtype@Base 2.12.0 + g_param_spec_int64@Base 2.12.0 + g_param_spec_int@Base 2.12.0 + g_param_spec_internal@Base 2.12.0 + g_param_spec_is_valid_name@Base 2.65.1 + g_param_spec_long@Base 2.12.0 + g_param_spec_object@Base 2.12.0 + g_param_spec_override@Base 2.12.0 + g_param_spec_param@Base 2.12.0 + g_param_spec_pointer@Base 2.12.0 + g_param_spec_pool_insert@Base 2.12.0 + g_param_spec_pool_list@Base 2.12.0 + g_param_spec_pool_list_owned@Base 2.12.0 + g_param_spec_pool_lookup@Base 2.12.0 + g_param_spec_pool_new@Base 2.12.0 + g_param_spec_pool_remove@Base 2.12.0 + g_param_spec_ref@Base 2.12.0 + g_param_spec_ref_sink@Base 2.12.0 + g_param_spec_set_qdata@Base 2.12.0 + g_param_spec_set_qdata_full@Base 2.12.0 + g_param_spec_sink@Base 2.12.0 + g_param_spec_steal_qdata@Base 2.12.0 + g_param_spec_string@Base 2.12.0 + g_param_spec_types@Base 2.12.0 + g_param_spec_uchar@Base 2.12.0 + g_param_spec_uint64@Base 2.12.0 + g_param_spec_uint@Base 2.12.0 + g_param_spec_ulong@Base 2.12.0 + g_param_spec_unichar@Base 2.12.0 + g_param_spec_unref@Base 2.12.0 + g_param_spec_value_array@Base 2.12.0 + g_param_spec_variant@Base 2.26.0 + g_param_type_register_static@Base 2.12.0 + g_param_value_convert@Base 2.12.0 + g_param_value_defaults@Base 2.12.0 + g_param_value_set_default@Base 2.12.0 + g_param_value_validate@Base 2.12.0 + g_param_values_cmp@Base 2.12.0 + g_pattern_spec_get_type@Base 2.70.0 + g_pointer_type_register_static@Base 2.12.0 + g_pollfd_get_type@Base 2.35.8 + g_ptr_array_get_type@Base 2.22.0 + g_regex_get_type@Base 2.14.0 + g_signal_accumulator_first_wins@Base 2.28.0 + g_signal_accumulator_true_handled@Base 2.12.0 + g_signal_add_emission_hook@Base 2.12.0 + g_signal_chain_from_overridden@Base 2.12.0 + g_signal_chain_from_overridden_handler@Base 2.18.0 + g_signal_connect_closure@Base 2.12.0 + g_signal_connect_closure_by_id@Base 2.12.0 + g_signal_connect_data@Base 2.12.0 + g_signal_connect_object@Base 2.12.0 + g_signal_emit@Base 2.12.0 + g_signal_emit_by_name@Base 2.12.0 + g_signal_emit_valist@Base 2.12.0 + g_signal_emitv@Base 2.12.0 + g_signal_get_invocation_hint@Base 2.12.0 + g_signal_group_block@Base 2.71.2 + g_signal_group_connect@Base 2.71.2 + g_signal_group_connect_after@Base 2.71.2 + g_signal_group_connect_data@Base 2.71.2 + g_signal_group_connect_object@Base 2.71.2 + g_signal_group_connect_swapped@Base 2.71.2 + g_signal_group_dup_target@Base 2.71.2 + g_signal_group_get_type@Base 2.71.2 + g_signal_group_new@Base 2.71.2 + g_signal_group_set_target@Base 2.71.2 + g_signal_group_unblock@Base 2.71.2 + g_signal_handler_block@Base 2.12.0 + g_signal_handler_disconnect@Base 2.12.0 + g_signal_handler_find@Base 2.12.0 + g_signal_handler_is_connected@Base 2.12.0 + g_signal_handler_unblock@Base 2.12.0 + g_signal_handlers_block_matched@Base 2.12.0 + g_signal_handlers_destroy@Base 2.12.0 + g_signal_handlers_disconnect_matched@Base 2.12.0 + g_signal_handlers_unblock_matched@Base 2.12.0 + g_signal_has_handler_pending@Base 2.12.0 + g_signal_is_valid_name@Base 2.65.1 + g_signal_list_ids@Base 2.12.0 + g_signal_lookup@Base 2.12.0 + g_signal_name@Base 2.12.0 + g_signal_new@Base 2.12.0 + g_signal_new_class_handler@Base 2.18.0 + g_signal_new_valist@Base 2.12.0 + g_signal_newv@Base 2.12.0 + g_signal_override_class_closure@Base 2.12.0 + g_signal_override_class_handler@Base 2.18.0 + g_signal_parse_name@Base 2.12.0 + g_signal_query@Base 2.12.0 + g_signal_remove_emission_hook@Base 2.12.0 + g_signal_set_va_marshaller@Base 2.31.20 + g_signal_stop_emission@Base 2.12.0 + g_signal_stop_emission_by_name@Base 2.12.0 + g_signal_type_cclosure_new@Base 2.12.0 + g_source_get_type@Base 2.30.0 + g_source_set_closure@Base 2.12.0 + g_source_set_dummy_callback@Base 2.28.0 + g_strdup_value_contents@Base 2.12.0 + g_strv_get_type@Base 2.12.0 + g_thread_get_type@Base 2.35.8 + g_time_zone_get_type@Base 2.33.14 + g_tree_get_type@Base 2.67.1 + g_type_add_class_cache_func@Base 2.12.0 + g_type_add_class_private@Base 2.24.0 + g_type_add_instance_private@Base 2.37.3 + g_type_add_interface_check@Base 2.12.0 + g_type_add_interface_dynamic@Base 2.12.0 + g_type_add_interface_static@Base 2.12.0 + g_type_check_class_cast@Base 2.12.0 + g_type_check_class_is_a@Base 2.12.0 + g_type_check_instance@Base 2.12.0 + g_type_check_instance_cast@Base 2.12.0 + g_type_check_instance_is_a@Base 2.12.0 + g_type_check_instance_is_fundamentally_a@Base 2.41.1 + g_type_check_is_value_type@Base 2.12.0 + g_type_check_value@Base 2.12.0 + g_type_check_value_holds@Base 2.12.0 + g_type_children@Base 2.12.0 + g_type_class_add_private@Base 2.12.0 + g_type_class_adjust_private_offset@Base 2.37.3 + g_type_class_get_instance_private_offset@Base 2.37.0 + g_type_class_get_private@Base 2.24.0 + g_type_class_peek@Base 2.12.0 + g_type_class_peek_parent@Base 2.12.0 + g_type_class_peek_static@Base 2.12.0 + g_type_class_ref@Base 2.12.0 + g_type_class_unref@Base 2.12.0 + g_type_class_unref_uncached@Base 2.12.0 + g_type_create_instance@Base 2.12.0 + g_type_default_interface_peek@Base 2.12.0 + g_type_default_interface_ref@Base 2.12.0 + g_type_default_interface_unref@Base 2.12.0 + g_type_depth@Base 2.12.0 + g_type_ensure@Base 2.33.14 + g_type_free_instance@Base 2.12.0 + g_type_from_name@Base 2.12.0 + g_type_fundamental@Base 2.12.0 + g_type_fundamental_next@Base 2.12.0 + g_type_get_instance_count@Base 2.43.1 + g_type_get_plugin@Base 2.12.0 + g_type_get_qdata@Base 2.12.0 + g_type_get_type_registration_serial@Base 2.35.8 + g_type_init@Base 2.12.0 + g_type_init_with_debug_flags@Base 2.12.0 + g_type_instance_get_private@Base 2.12.0 + g_type_interface_add_prerequisite@Base 2.12.0 + g_type_interface_get_plugin@Base 2.12.0 + g_type_interface_instantiatable_prerequisite@Base 2.67.1 + g_type_interface_peek@Base 2.12.0 + g_type_interface_peek_parent@Base 2.12.0 + g_type_interface_prerequisites@Base 2.12.0 + g_type_interfaces@Base 2.12.0 + g_type_is_a@Base 2.12.0 + g_type_module_add_interface@Base 2.12.0 + g_type_module_get_type@Base 2.12.0 + g_type_module_register_enum@Base 2.12.0 + g_type_module_register_flags@Base 2.12.0 + g_type_module_register_type@Base 2.12.0 + g_type_module_set_name@Base 2.12.0 + g_type_module_unuse@Base 2.12.0 + g_type_module_use@Base 2.12.0 + g_type_name@Base 2.12.0 + g_type_name_from_class@Base 2.12.0 + g_type_name_from_instance@Base 2.12.0 + g_type_next_base@Base 2.12.0 + g_type_parent@Base 2.12.0 + g_type_plugin_complete_interface_info@Base 2.12.0 + g_type_plugin_complete_type_info@Base 2.12.0 + g_type_plugin_get_type@Base 2.12.0 + g_type_plugin_unuse@Base 2.12.0 + g_type_plugin_use@Base 2.12.0 + g_type_qname@Base 2.12.0 + g_type_query@Base 2.12.0 + g_type_register_dynamic@Base 2.12.0 + g_type_register_fundamental@Base 2.12.0 + g_type_register_static@Base 2.12.0 + g_type_register_static_simple@Base 2.12.0 + g_type_remove_class_cache_func@Base 2.12.0 + g_type_remove_interface_check@Base 2.12.0 + g_type_set_qdata@Base 2.12.0 + g_type_test_flags@Base 2.12.0 + g_type_value_table_peek@Base 2.12.0 + g_unicode_break_type_get_type@Base 2.59.2 + g_unicode_script_get_type@Base 2.59.2 + g_unicode_type_get_type@Base 2.59.2 + g_uri_get_type@Base 2.65.1 + g_value_array_append@Base 2.12.0 + g_value_array_copy@Base 2.12.0 + g_value_array_free@Base 2.12.0 + g_value_array_get_nth@Base 2.12.0 + g_value_array_get_type@Base 2.12.0 + g_value_array_insert@Base 2.12.0 + g_value_array_new@Base 2.12.0 + g_value_array_prepend@Base 2.12.0 + g_value_array_remove@Base 2.12.0 + g_value_array_sort@Base 2.12.0 + g_value_array_sort_with_data@Base 2.12.0 + g_value_copy@Base 2.12.0 + g_value_dup_boxed@Base 2.12.0 + g_value_dup_object@Base 2.12.0 + g_value_dup_param@Base 2.12.0 + g_value_dup_string@Base 2.12.0 + g_value_dup_variant@Base 2.26.0 + g_value_fits_pointer@Base 2.12.0 + g_value_get_boolean@Base 2.12.0 + g_value_get_boxed@Base 2.12.0 + g_value_get_char@Base 2.12.0 + g_value_get_double@Base 2.12.0 + g_value_get_enum@Base 2.12.0 + g_value_get_flags@Base 2.12.0 + g_value_get_float@Base 2.12.0 + g_value_get_gtype@Base 2.12.0 + g_value_get_int64@Base 2.12.0 + g_value_get_int@Base 2.12.0 + g_value_get_long@Base 2.12.0 + g_value_get_object@Base 2.12.0 + g_value_get_param@Base 2.12.0 + g_value_get_pointer@Base 2.12.0 + g_value_get_schar@Base 2.31.8 + g_value_get_string@Base 2.12.0 + g_value_get_type@Base 2.12.0 + g_value_get_uchar@Base 2.12.0 + g_value_get_uint64@Base 2.12.0 + g_value_get_uint@Base 2.12.0 + g_value_get_ulong@Base 2.12.0 + g_value_get_variant@Base 2.26.0 + g_value_init@Base 2.12.0 + g_value_init_from_instance@Base 2.41.2 + g_value_peek_pointer@Base 2.12.0 + g_value_register_transform_func@Base 2.12.0 + g_value_reset@Base 2.12.0 + g_value_set_boolean@Base 2.12.0 + g_value_set_boxed@Base 2.12.0 + g_value_set_boxed_take_ownership@Base 2.12.0 + g_value_set_char@Base 2.12.0 + g_value_set_double@Base 2.12.0 + g_value_set_enum@Base 2.12.0 + g_value_set_flags@Base 2.12.0 + g_value_set_float@Base 2.12.0 + g_value_set_gtype@Base 2.12.0 + g_value_set_instance@Base 2.12.0 + g_value_set_int64@Base 2.12.0 + g_value_set_int@Base 2.12.0 + g_value_set_interned_string@Base 2.65.1 + g_value_set_long@Base 2.12.0 + g_value_set_object@Base 2.12.0 + g_value_set_object_take_ownership@Base 2.12.0 + g_value_set_param@Base 2.12.0 + g_value_set_param_take_ownership@Base 2.12.0 + g_value_set_pointer@Base 2.12.0 + g_value_set_schar@Base 2.31.8 + g_value_set_static_boxed@Base 2.12.0 + g_value_set_static_string@Base 2.12.0 + g_value_set_string@Base 2.12.0 + g_value_set_string_take_ownership@Base 2.12.0 + g_value_set_uchar@Base 2.12.0 + g_value_set_uint64@Base 2.12.0 + g_value_set_uint@Base 2.12.0 + g_value_set_ulong@Base 2.12.0 + g_value_set_variant@Base 2.26.0 + g_value_take_boxed@Base 2.12.0 + g_value_take_object@Base 2.12.0 + g_value_take_param@Base 2.12.0 + g_value_take_string@Base 2.12.0 + g_value_take_variant@Base 2.26.0 + g_value_transform@Base 2.12.0 + g_value_type_compatible@Base 2.12.0 + g_value_type_transformable@Base 2.12.0 + g_value_unset@Base 2.12.0 + g_variant_builder_get_type@Base 2.30.0 + g_variant_dict_get_type@Base 2.39.90 + g_variant_get_gtype@Base 2.24.0 + g_variant_type_get_gtype@Base 2.24.0 + g_weak_ref_clear@Base 2.31.8 + g_weak_ref_get@Base 2.31.8 + g_weak_ref_init@Base 2.31.8 + g_weak_ref_set@Base 2.31.8 +libgthread-2.0.so.0 libglib2.0-0 #MINVER# +* Build-Depends-Package: libglib2.0-dev + g_thread_init@Base 2.12.0 + g_thread_init_with_errorcheck_mutexes@Base 2.12.0 diff --git a/debian/libglib2.0-0.triggers.in b/debian/libglib2.0-0.triggers.in new file mode 100644 index 0000000..b365a66 --- /dev/null +++ b/debian/libglib2.0-0.triggers.in @@ -0,0 +1,2 @@ +interest-noawait /usr/lib/#MULTIARCH#/gio/modules +interest-await /usr/share/glib-2.0/schemas diff --git a/debian/libglib2.0-bin.install b/debian/libglib2.0-bin.install new file mode 100644 index 0000000..1c406ca --- /dev/null +++ b/debian/libglib2.0-bin.install @@ -0,0 +1,13 @@ +usr/bin/gapplication +usr/bin/gdbus +usr/bin/gio +usr/bin/gresource +usr/bin/gsettings +usr/share/bash-completion +usr/share/man/man1/gapplication.1* +usr/share/man/man1/gdbus.1* +usr/share/man/man1/gio-querymodules.1* +usr/share/man/man1/gio.1* +usr/share/man/man1/glib-compile-schemas.1* +usr/share/man/man1/gresource.1* +usr/share/man/man1/gsettings.1* diff --git a/debian/libglib2.0-bin.links b/debian/libglib2.0-bin.links new file mode 100644 index 0000000..3ccceac --- /dev/null +++ b/debian/libglib2.0-bin.links @@ -0,0 +1,2 @@ +/usr/lib/${DEB_HOST_MULTIARCH}/glib-2.0/gio-querymodules /usr/bin/gio-querymodules +/usr/lib/${DEB_HOST_MULTIARCH}/glib-2.0/glib-compile-schemas /usr/bin/glib-compile-schemas diff --git a/debian/libglib2.0-bin.lintian-overrides b/debian/libglib2.0-bin.lintian-overrides new file mode 100644 index 0000000..3b4f46b --- /dev/null +++ b/debian/libglib2.0-bin.lintian-overrides @@ -0,0 +1,2 @@ +# GLib programs normally use GLib functions instead of using libc directly +libglib2.0-bin: hardening-no-fortify-functions [usr/bin/gio] diff --git a/debian/libglib2.0-data.install b/debian/libglib2.0-data.install new file mode 100644 index 0000000..3635480 --- /dev/null +++ b/debian/libglib2.0-data.install @@ -0,0 +1 @@ +usr/share/locale diff --git a/debian/libglib2.0-dev-bin.install b/debian/libglib2.0-dev-bin.install new file mode 100644 index 0000000..84156be --- /dev/null +++ b/debian/libglib2.0-dev-bin.install @@ -0,0 +1,19 @@ +usr/bin/gdbus-codegen +usr/bin/glib-compile-resources +usr/bin/glib-genmarshal +usr/bin/glib-gettextize +usr/bin/glib-mkenums +usr/bin/gobject-query +usr/bin/gtester +usr/bin/gtester-report +usr/share/aclocal +usr/share/glib-2.0/codegen/*.py +usr/share/glib-2.0/gettext +usr/share/man/man1/gdbus-codegen.1* +usr/share/man/man1/glib-compile-resources.1* +usr/share/man/man1/glib-genmarshal.1* +usr/share/man/man1/glib-gettextize.1* +usr/share/man/man1/glib-mkenums.1* +usr/share/man/man1/gobject-query.1* +usr/share/man/man1/gtester-report.1* +usr/share/man/man1/gtester.1* diff --git a/debian/libglib2.0-dev.README.Debian b/debian/libglib2.0-dev.README.Debian new file mode 100644 index 0000000..b36c218 --- /dev/null +++ b/debian/libglib2.0-dev.README.Debian @@ -0,0 +1,15 @@ +GLib2.0 for Debian +------------------- + +Static libraries issue: +Right now glib2.0 provides some static libraries. If your application +uses g_module* functions or other libraries uses g_module* functions and +your application link it, Please don't statically link this libraries. +You may get some strange proglem between static-linked application and +dynamic-loaded modules, g_module* provides the feature for dynamically +loading some modules. +This is well-known bug, so please don't file a bug report. + + + -- Akira TAGOH , Thu, 11 Apr 2002 19:28:50 +0900 + diff --git a/debian/libglib2.0-dev.install b/debian/libglib2.0-dev.install new file mode 100644 index 0000000..0bb46ef --- /dev/null +++ b/debian/libglib2.0-dev.install @@ -0,0 +1,14 @@ +usr/include/* +usr/lib/*/glib-2.0 +usr/lib/*/lib*.a +usr/lib/*/libgio*.so +usr/lib/*/libglib*.so +usr/lib/*/libgmodule*.so +usr/lib/*/libgobject*.so +usr/lib/*/libgthread*.so +usr/lib/*/pkgconfig +usr/share/gdb +usr/share/gettext/its +usr/share/glib-2.0/gdb +usr/share/glib-2.0/schemas +usr/share/glib-2.0/valgrind diff --git a/debian/libglib2.0-doc.doc-base.gio b/debian/libglib2.0-doc.doc-base.gio new file mode 100644 index 0000000..72ffc95 --- /dev/null +++ b/debian/libglib2.0-doc.doc-base.gio @@ -0,0 +1,14 @@ +Document: gio +Title: GIO (GLib) Reference Manual +Author: Damon Chaplin et al. +Abstract: GIO is striving to provide a modern, easy-to-use VFS API that sits at + the right level in the library stack. The goal is to overcome the shortcomings + of GnomeVFS and provide an API that is so good that developers prefer it over + raw POSIX calls. Among other things that means using GObject. It also means + not cloning the POSIX API, but providing higher-level, document-centric + interfaces. +Section: Programming/C + +Format: HTML +Index: /usr/share/doc/libglib2.0-doc/gio/index.html +Files: /usr/share/doc/libglib2.0-doc/gio/*.html diff --git a/debian/libglib2.0-doc.doc-base.glib b/debian/libglib2.0-doc.doc-base.glib new file mode 100644 index 0000000..d611198 --- /dev/null +++ b/debian/libglib2.0-doc.doc-base.glib @@ -0,0 +1,12 @@ +Document: glib +Title: GLib Reference Manual +Author: Damon Chaplin et al. +Abstract: The GLib C library is used in GTK+ and GNOME + programs as a general-purpose set of functions for hash, tree, list, + and string operations, which C is oddly lacking whatsoever in any + of its standard libraries. +Section: Programming/C + +Format: HTML +Index: /usr/share/doc/libglib2.0-doc/glib/index.html +Files: /usr/share/doc/libglib2.0-doc/glib/*.html diff --git a/debian/libglib2.0-doc.doc-base.gobject b/debian/libglib2.0-doc.doc-base.gobject new file mode 100644 index 0000000..adcc6f0 --- /dev/null +++ b/debian/libglib2.0-doc.doc-base.gobject @@ -0,0 +1,15 @@ +Document: gobject +Title: GObject (GLib) Reference Manual +Author: Damon Chaplin et al. +Abstract: Most modern programming languages come with their own native object + systems and additional fundamental algorithmic language constructs. + Just as GLib serves as an implementation of such fundamental + types and algorithms (linked lists, hash tables and so forth), the + GLib Object System provides the required implementations of a + flexible extensible and intentionally easy to map (into other + languages) object oriented framework for C. +Section: Programming/C + +Format: HTML +Index: /usr/share/doc/libglib2.0-doc/gobject/index.html +Files: /usr/share/doc/libglib2.0-doc/gobject/*.html diff --git a/debian/libglib2.0-doc.install b/debian/libglib2.0-doc.install new file mode 100644 index 0000000..a5f4974 --- /dev/null +++ b/debian/libglib2.0-doc.install @@ -0,0 +1,3 @@ +usr/share/gtk-doc/html/gio +usr/share/gtk-doc/html/glib +usr/share/gtk-doc/html/gobject diff --git a/debian/libglib2.0-doc.links b/debian/libglib2.0-doc.links new file mode 100644 index 0000000..a979f87 --- /dev/null +++ b/debian/libglib2.0-doc.links @@ -0,0 +1,3 @@ +usr/share/gtk-doc/html/gio usr/share/doc/libglib2.0-doc/gio +usr/share/gtk-doc/html/glib usr/share/doc/libglib2.0-doc/glib +usr/share/gtk-doc/html/gobject usr/share/doc/libglib2.0-doc/gobject diff --git a/debian/libglib2.0-doc.lintian-overrides b/debian/libglib2.0-doc.lintian-overrides new file mode 100644 index 0000000..48af548 --- /dev/null +++ b/debian/libglib2.0-doc.lintian-overrides @@ -0,0 +1,2 @@ +# https://bugs.debian.org/970275 +package-contains-documentation-outside-usr-share-doc usr/share/gtk-doc/html/* diff --git a/debian/libglib2.0-doc.maintscript b/debian/libglib2.0-doc.maintscript new file mode 100644 index 0000000..807786b --- /dev/null +++ b/debian/libglib2.0-doc.maintscript @@ -0,0 +1,6 @@ +dir_to_symlink /usr/share/doc/libglib2.0-doc/gio ../../gtk-doc/html/gio 2.58.0-4~ +dir_to_symlink /usr/share/doc/libglib2.0-doc/glib ../../gtk-doc/html/glib 2.58.0-4~ +dir_to_symlink /usr/share/doc/libglib2.0-doc/gobject ../../gtk-doc/html/gobject 2.58.0-4~ +symlink_to_dir /usr/share/gtk-doc/html/gio ../../doc/libglib2.0-doc/gio 2.58.0-4~ +symlink_to_dir /usr/share/gtk-doc/html/glib ../../doc/libglib2.0-doc/glib 2.58.0-4~ +symlink_to_dir /usr/share/gtk-doc/html/gobject ../../doc/libglib2.0-doc/gobject 2.58.0-4~ diff --git a/debian/libglib2.0-tests.install b/debian/libglib2.0-tests.install new file mode 100644 index 0000000..e2a2951 --- /dev/null +++ b/debian/libglib2.0-tests.install @@ -0,0 +1,2 @@ +usr/libexec/installed-tests +usr/share/installed-tests diff --git a/debian/libglib2.0-tests.lintian-overrides b/debian/libglib2.0-tests.lintian-overrides new file mode 100644 index 0000000..e5e79f4 --- /dev/null +++ b/debian/libglib2.0-tests.lintian-overrides @@ -0,0 +1,12 @@ +# Lots of tests don't use libc functions +libglib2.0-tests: hardening-no-fortify-functions [usr/libexec/installed-tests/glib/*] +# Some are deliberately not well-formed UTF-8 +libglib2.0-tests: national-encoding usr/libexec/installed-tests/glib/markups/fail* +# Not every .txt file is documentation +libglib2.0-tests: package-contains-documentation-outside-usr-share-doc usr/libexec/installed-tests/glib/*.txt +# Test data for content-type sniffing, never actually executed +libglib2.0-tests: script-not-executable [usr/libexec/installed-tests/glib/x-content/unix-software/autorun.sh] +# This is lorem ipsum in a test-case, nothing to do with the Debian Free Software Guidelines +libglib2.0-tests: spelling-error-in-binary usr/libexec/installed-tests/glib/utf8-pointer dsfg dfsg +# Depends on a private test-only library +libglib2.0-tests: custom-library-search-path RUNPATH /usr/libexec/installed-tests/glib [usr/libexec/installed-tests/glib/gdbus-peer] diff --git a/debian/libglib2.0-udeb.install b/debian/libglib2.0-udeb.install new file mode 100644 index 0000000..d484cc1 --- /dev/null +++ b/debian/libglib2.0-udeb.install @@ -0,0 +1,2 @@ +usr/lib/*/lib*.so.* +usr/share/locale diff --git a/debian/libglib2.0-udeb.lintian-overrides b/debian/libglib2.0-udeb.lintian-overrides new file mode 100644 index 0000000..e60fe9e --- /dev/null +++ b/debian/libglib2.0-udeb.lintian-overrides @@ -0,0 +1,2 @@ +# It's a deliberate choice of bundling them together +libglib2.0-udeb udeb: package-name-doesnt-match-sonames libgio-2.0-0 libglib-2.0-0 libgmodule-2.0-0 libgobject-2.0-0 libgthread-2.0-0 diff --git a/debian/patches/0001-gio-Make-portal-support-aware-of-snaps.patch b/debian/patches/0001-gio-Make-portal-support-aware-of-snaps.patch new file mode 100644 index 0000000..80f2b7a --- /dev/null +++ b/debian/patches/0001-gio-Make-portal-support-aware-of-snaps.patch @@ -0,0 +1,1136 @@ +From 3cfd08a16c3d9424d37ef71756e4471930c32598 Mon Sep 17 00:00:00 2001 +From: Robert Ancell +Date: Mon, 31 Oct 2022 12:07:52 +0100 +Subject: [PATCH] gio: Make portal support aware of snaps + +--- + docs/reference/gio/meson.build | 1 + + gio/gportalsupport.c | 155 ++++++++++++------ + gio/gsandbox.c | 126 ++++++++++++++ + gio/gsandbox.h | 47 ++++++ + gio/meson.build | 3 +- + gio/tests/meson.build | 22 +++ + gio/tests/portal-support-env-var.c | 45 +++++ + gio/tests/portal-support-none.c | 43 +++++ + gio/tests/portal-support-snap-classic.c | 119 ++++++++++++++ + gio/tests/portal-support-snap.c | 208 ++++++++++++++++++++++++ + gio/tests/portal-support-utils.c | 87 ++++++++++ + gio/tests/portal-support-utils.h | 30 ++++ + gio/tests/sandbox.c | 80 +++++++++ + 13 files changed, 919 insertions(+), 47 deletions(-) + create mode 100644 gio/gsandbox.c + create mode 100644 gio/gsandbox.h + create mode 100644 gio/tests/portal-support-env-var.c + create mode 100644 gio/tests/portal-support-none.c + create mode 100644 gio/tests/portal-support-snap-classic.c + create mode 100644 gio/tests/portal-support-snap.c + create mode 100644 gio/tests/portal-support-utils.c + create mode 100644 gio/tests/portal-support-utils.h + create mode 100644 gio/tests/sandbox.c + +diff --git a/docs/reference/gio/meson.build b/docs/reference/gio/meson.build +index bb14e6923..fe32a2ad3 100644 +--- a/docs/reference/gio/meson.build ++++ b/docs/reference/gio/meson.build +@@ -71,6 +71,7 @@ if get_option('gtk_doc') + 'gproxyresolverportal.h', + 'gregistrysettingsbackend.h', + 'gresourcefile.h', ++ 'gsandbox.h', + 'gsettingsbackendinternal.h', + 'gsettings-mapping.h', + 'gsettingsschema-internal.h', +diff --git a/gio/gportalsupport.c b/gio/gportalsupport.c +index 233f6af45..0742b9beb 100644 +--- a/gio/gportalsupport.c ++++ b/gio/gportalsupport.c +@@ -18,84 +18,147 @@ + + #include "config.h" + ++#include "glib-private.h" + #include "gportalsupport.h" ++#include "gsandbox.h" + ++static GSandboxType sandbox_type = G_SANDBOX_TYPE_UNKNOWN; + static gboolean use_portal; + static gboolean network_available; + static gboolean dconf_access; + ++#ifdef G_PORTAL_SUPPORT_TEST ++static const char *snapctl = "snapctl"; ++#else ++static const char *snapctl = "/usr/bin/snapctl"; ++#endif ++ ++static gboolean ++snap_plug_is_connected (const gchar *plug_name) ++{ ++ gint wait_status; ++ const gchar *argv[] = { snapctl, "is-connected", plug_name, NULL }; ++ ++ /* Bail out if our process is privileged - we don't want to pass those ++ * privileges to snapctl. It could be overridden and this would ++ * allow arbitrary code execution. ++ */ ++ if (GLIB_PRIVATE_CALL (g_check_setuid) ()) ++ return FALSE; ++ ++ if (!g_spawn_sync (NULL, (gchar **) argv, NULL, ++#ifdef G_PORTAL_SUPPORT_TEST ++ G_SPAWN_SEARCH_PATH | ++#endif ++ G_SPAWN_STDOUT_TO_DEV_NULL | ++ G_SPAWN_STDERR_TO_DEV_NULL, ++ NULL, NULL, NULL, NULL, &wait_status, ++ NULL)) ++ return FALSE; ++ ++ return g_spawn_check_wait_status (wait_status, NULL); ++} ++ + static void +-read_flatpak_info (void) ++sandbox_info_read (void) + { +- static gsize flatpak_info_read = 0; +- const gchar *path = "/.flatpak-info"; ++ static gsize sandbox_info_is_read = 0; + +- if (!g_once_init_enter (&flatpak_info_read)) ++ /* Sandbox type and Flatpak info is static, so only read once */ ++ if (!g_once_init_enter (&sandbox_info_is_read)) + return; + +- if (g_file_test (path, G_FILE_TEST_EXISTS)) +- { +- GKeyFile *keyfile; +- +- use_portal = TRUE; +- network_available = FALSE; +- dconf_access = FALSE; +- +- keyfile = g_key_file_new (); +- if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL)) +- { +- char **shared = NULL; +- char *dconf_policy = NULL; +- +- shared = g_key_file_get_string_list (keyfile, "Context", "shared", NULL, NULL); +- if (shared) +- { +- network_available = g_strv_contains ((const char * const *)shared, "network"); +- g_strfreev (shared); +- } +- +- dconf_policy = g_key_file_get_string (keyfile, "Session Bus Policy", "ca.desrt.dconf", NULL); +- if (dconf_policy) +- { +- if (strcmp (dconf_policy, "talk") == 0) +- dconf_access = TRUE; +- g_free (dconf_policy); +- } +- } +- +- g_key_file_unref (keyfile); +- } +- else ++ sandbox_type = glib_get_sandbox_type (); ++ ++ switch (sandbox_type) + { +- const char *var; ++ case G_SANDBOX_TYPE_FLATPAK: ++ { ++ GKeyFile *keyfile; + +- var = g_getenv ("GTK_USE_PORTAL"); +- if (var && var[0] == '1') + use_portal = TRUE; +- network_available = TRUE; +- dconf_access = TRUE; ++ network_available = FALSE; ++ dconf_access = FALSE; ++ ++ keyfile = g_key_file_new (); ++ if (g_key_file_load_from_file (keyfile, "/.flatpak-info", G_KEY_FILE_NONE, NULL)) ++ { ++ char **shared = NULL; ++ char *dconf_policy = NULL; ++ ++ shared = g_key_file_get_string_list (keyfile, "Context", "shared", NULL, NULL); ++ if (shared) ++ { ++ network_available = g_strv_contains ((const char * const *)shared, "network"); ++ g_strfreev (shared); ++ } ++ ++ dconf_policy = g_key_file_get_string (keyfile, "Session Bus Policy", "ca.desrt.dconf", NULL); ++ if (dconf_policy) ++ { ++ if (strcmp (dconf_policy, "talk") == 0) ++ dconf_access = TRUE; ++ g_free (dconf_policy); ++ } ++ } ++ ++ g_key_file_unref (keyfile); ++ } ++ break; ++ case G_SANDBOX_TYPE_SNAP: ++ break; ++ case G_SANDBOX_TYPE_UNKNOWN: ++ { ++ const char *var; ++ ++ var = g_getenv ("GTK_USE_PORTAL"); ++ if (var && var[0] == '1') ++ use_portal = TRUE; ++ network_available = TRUE; ++ dconf_access = TRUE; ++ } ++ break; + } + +- g_once_init_leave (&flatpak_info_read, 1); ++ g_once_init_leave (&sandbox_info_is_read, 1); + } + + gboolean + glib_should_use_portal (void) + { +- read_flatpak_info (); ++ sandbox_info_read (); ++ ++ if (sandbox_type == G_SANDBOX_TYPE_SNAP) ++ return snap_plug_is_connected ("desktop"); ++ + return use_portal; + } + + gboolean + glib_network_available_in_sandbox (void) + { +- read_flatpak_info (); ++ sandbox_info_read (); ++ ++ if (sandbox_type == G_SANDBOX_TYPE_SNAP) ++ { ++ /* FIXME: This is inefficient doing multiple calls to check connections. ++ * See https://github.com/snapcore/snapd/pull/12301 for a proposed ++ * improvement to snapd for this. ++ */ ++ return snap_plug_is_connected ("desktop") || ++ snap_plug_is_connected ("network-status"); ++ } ++ + return network_available; + } + + gboolean + glib_has_dconf_access_in_sandbox (void) + { +- read_flatpak_info (); ++ sandbox_info_read (); ++ ++ if (sandbox_type == G_SANDBOX_TYPE_SNAP) ++ return snap_plug_is_connected ("gsettings"); ++ + return dconf_access; + } +diff --git a/gio/gsandbox.c b/gio/gsandbox.c +new file mode 100644 +index 000000000..34f680b5a +--- /dev/null ++++ b/gio/gsandbox.c +@@ -0,0 +1,126 @@ ++/* GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright 2022 Canonical Ltd ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ */ ++ ++#include "config.h" ++ ++#include "gsandbox.h" ++ ++#include ++ ++#define SNAP_CONFINEMENT_PREFIX "confinement:" ++ ++static gboolean ++is_flatpak (void) ++{ ++ return g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS); ++} ++ ++static gchar * ++get_snap_confinement (const char *snap_yaml, ++ GError **error) ++{ ++ char *confinement = NULL; ++ char *yaml_contents; ++ ++ if (g_file_get_contents (snap_yaml, &yaml_contents, NULL, error)) ++ { ++ const char *line = yaml_contents; ++ ++ do ++ { ++ if (g_str_has_prefix (line, SNAP_CONFINEMENT_PREFIX)) ++ break; ++ ++ line = strchr (line, '\n'); ++ if (line) ++ line += 1; ++ } ++ while (line != NULL); ++ ++ if (line) ++ { ++ const char *start = line + strlen (SNAP_CONFINEMENT_PREFIX); ++ const char *end = strchr (start, '\n'); ++ ++ confinement = ++ g_strstrip (end ? g_strndup (start, end-start) : g_strdup (start)); ++ } ++ ++ g_free (yaml_contents); ++ } ++ ++ return g_steal_pointer (&confinement); ++} ++ ++static gboolean ++is_snap (void) ++{ ++ GError *error = NULL; ++ const gchar *snap_path; ++ gchar *yaml_path; ++ char *confinement; ++ gboolean result; ++ ++ snap_path = g_getenv ("SNAP"); ++ if (snap_path == NULL) ++ return FALSE; ++ ++ result = FALSE; ++ yaml_path = g_build_filename (snap_path, "meta", "snap.yaml", NULL); ++ confinement = get_snap_confinement (yaml_path, &error); ++ g_free (yaml_path); ++ ++ /* Classic snaps are de-facto no sandboxed apps, so we can ignore them */ ++ if (!error && g_strcmp0 (confinement, "classic") != 0) ++ result = TRUE; ++ ++ g_clear_error (&error); ++ g_free (confinement); ++ ++ return result; ++} ++ ++/* ++ * glib_get_sandbox_type: ++ * ++ * Gets the type of sandbox this process is running inside. ++ * ++ * Checking for sandboxes may involve doing blocking I/O calls, but should not take ++ * any significant time. ++ * ++ * The sandbox will not change over the lifetime of the process, so calling this ++ * function once and reusing the result is valid. ++ * ++ * If this process is not sandboxed then @G_SANDBOX_TYPE_UNKNOWN will be returned. ++ * This is because this function only detects known sandbox types in #GSandboxType. ++ * It may be updated in the future if new sandboxes come into use. ++ * ++ * Returns: a #GSandboxType. ++ */ ++GSandboxType ++glib_get_sandbox_type (void) ++{ ++ if (is_flatpak ()) ++ return G_SANDBOX_TYPE_FLATPAK; ++ else if (is_snap ()) ++ return G_SANDBOX_TYPE_SNAP; ++ else ++ return G_SANDBOX_TYPE_UNKNOWN; ++} +diff --git a/gio/gsandbox.h b/gio/gsandbox.h +new file mode 100644 +index 000000000..7861b2756 +--- /dev/null ++++ b/gio/gsandbox.h +@@ -0,0 +1,47 @@ ++/* GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright 2022 Canonical Ltd ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ */ ++ ++#ifndef __G_SANDBOX_H__ ++#define __G_SANDBOX_H__ ++ ++#include ++ ++G_BEGIN_DECLS ++ ++/* ++ * GSandboxType: ++ * @G_SANDBOX_TYPE_UNKNOWN: process is running inside an unknown or no sandbox. ++ * @G_SANDBOX_TYPE_FLATPAK: process is running inside a flatpak sandbox. ++ * @G_SANDBOX_TYPE_SNAP: process is running inside a snap sandbox. ++ * ++ * The type of sandbox that processes can be running inside. ++ */ ++typedef enum ++{ ++ G_SANDBOX_TYPE_UNKNOWN, ++ G_SANDBOX_TYPE_FLATPAK, ++ G_SANDBOX_TYPE_SNAP ++} GSandboxType; ++ ++GSandboxType glib_get_sandbox_type (void); ++ ++G_END_DECLS ++ ++#endif +diff --git a/gio/meson.build b/gio/meson.build +index 9019104a4..ad4bc47ee 100644 +--- a/gio/meson.build ++++ b/gio/meson.build +@@ -375,7 +375,8 @@ if host_system != 'windows' + 'gproxyresolverportal.c', + 'gtrashportal.c', + 'gportalsupport.c', +- 'gportalnotificationbackend.c'), ++ 'gportalnotificationbackend.c', ++ 'gsandbox.c'), + xdp_dbus_generated + ] + +diff --git a/gio/tests/meson.build b/gio/tests/meson.build +index 383d84319..f1345189a 100644 +--- a/gio/tests/meson.build ++++ b/gio/tests/meson.build +@@ -94,6 +94,9 @@ gio_tests = { + 'power-profile-monitor' : {}, + 'proxy-test' : {}, + 'readwrite' : {}, ++ 'sandbox' : { ++ 'extra_sources': ['../gsandbox.c', 'portal-support-utils.c'], ++ }, + 'simple-async-result' : {}, + 'simple-proxy' : {}, + 'sleepy-stream' : {}, +@@ -198,6 +201,25 @@ if host_machine.system() != 'windows' + }, + 'gdbus-peer-object-manager' : {}, + 'live-g-file' : {}, ++ 'portal-support-none' : { ++ 'extra_sources': ['../gportalsupport.c', '../gsandbox.c'], ++ 'c_args': ['-DG_PORTAL_SUPPORT_TEST'], ++ 'suite': ['portal-support'], ++ }, ++ 'portal-support-env-var' : { ++ 'extra_sources': ['../gportalsupport.c', '../gsandbox.c'], ++ 'suite': ['portal-support'], ++ }, ++ 'portal-support-snap' : { ++ 'extra_sources': ['../gportalsupport.c', '../gsandbox.c', 'portal-support-utils.c'], ++ 'c_args': ['-DG_PORTAL_SUPPORT_TEST'], ++ 'suite': ['portal-support'], ++ }, ++ 'portal-support-snap-classic' : { ++ 'extra_sources': ['../gportalsupport.c', '../gsandbox.c', 'portal-support-utils.c'], ++ 'c_args': ['-DG_PORTAL_SUPPORT_TEST'], ++ 'suite': ['portal-support'], ++ }, + 'resolver-parsing' : {'dependencies' : [network_libs]}, + 'socket-address' : {}, + 'stream-rw_all' : {}, +diff --git a/gio/tests/portal-support-env-var.c b/gio/tests/portal-support-env-var.c +new file mode 100644 +index 000000000..b1d3fd3c3 +--- /dev/null ++++ b/gio/tests/portal-support-env-var.c +@@ -0,0 +1,45 @@ ++/* ++ * GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2022 Canonical Ltd. ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ * ++ * Author: Marco Trevisan ++ */ ++ ++#include "../gportalsupport.h" ++#include ++ ++static void ++test_portal_support_env_var (void) ++{ ++ g_assert_true (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ g_test_init (&argc, &argv, NULL); ++ ++ g_setenv ("GTK_USE_PORTAL", "1", TRUE); ++ ++ g_test_add_func ("/portal-support/env-var", test_portal_support_env_var); ++ ++ return g_test_run (); ++} +diff --git a/gio/tests/portal-support-none.c b/gio/tests/portal-support-none.c +new file mode 100644 +index 000000000..1bc0a9391 +--- /dev/null ++++ b/gio/tests/portal-support-none.c +@@ -0,0 +1,43 @@ ++/* ++ * GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2022 Canonical Ltd. ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ * ++ * Author: Marco Trevisan ++ */ ++ ++#include "../gportalsupport.h" ++#include ++ ++static void ++test_portal_support_none (void) ++{ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ g_test_init (&argc, &argv, NULL); ++ ++ g_test_add_func ("/portal-support/none", test_portal_support_none); ++ ++ return g_test_run (); ++} +diff --git a/gio/tests/portal-support-snap-classic.c b/gio/tests/portal-support-snap-classic.c +new file mode 100644 +index 000000000..8c0ed90c2 +--- /dev/null ++++ b/gio/tests/portal-support-snap-classic.c +@@ -0,0 +1,119 @@ ++/* ++ * GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2022 Canonical Ltd. ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ * ++ * Author: Marco Trevisan ++ */ ++ ++#include "portal-support-utils.h" ++ ++#include "../gportalsupport.h" ++#include ++ ++typedef struct ++{ ++ char *old_path; ++ char *old_snap; ++ ++ const char *bin_path; ++ const char *snap_path; ++} SetupData; ++ ++static void ++tests_setup (SetupData *setup_data, ++ gconstpointer data) ++{ ++ setup_data->old_path = g_strdup (g_getenv ("PATH")); ++ setup_data->old_snap = g_strdup (g_getenv ("SNAP")); ++ ++ setup_data->bin_path = g_get_user_runtime_dir (); ++ setup_data->snap_path = g_getenv ("G_TEST_TMPDIR"); ++ ++ g_assert_nonnull (setup_data->bin_path); ++ g_assert_nonnull (setup_data->snap_path); ++ ++ g_setenv ("PATH", setup_data->bin_path, TRUE); ++ g_setenv ("SNAP", setup_data->snap_path, TRUE); ++} ++ ++static void ++tests_teardown (SetupData *setup_data, ++ gconstpointer data) ++{ ++ if (setup_data->old_path) ++ g_setenv ("PATH", setup_data->old_path, TRUE); ++ else ++ g_unsetenv ("PATH"); ++ ++ if (setup_data->old_snap) ++ g_setenv ("SNAP", setup_data->old_snap, TRUE); ++ else ++ g_unsetenv ("SNAP"); ++ ++ g_clear_pointer (&setup_data->old_path, g_free); ++ g_clear_pointer (&setup_data->old_snap, g_free); ++} ++ ++static void ++test_portal_support_snap_no_snapctl (SetupData *setup, ++ gconstpointer data) ++{ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++} ++ ++static void ++test_portal_support_snap_none (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, TRUE); ++ create_fake_snapctl (setup->bin_path, NULL); ++ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++} ++ ++static void ++test_portal_support_snap_all (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, TRUE); ++ create_fake_snapctl (setup->bin_path, "desktop|network-status|gsettings"); ++ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); ++ ++ g_test_add ("/portal-support/snap-classic/no-snapctl", SetupData, NULL, ++ tests_setup, test_portal_support_snap_no_snapctl, tests_teardown); ++ g_test_add ("/portal-support/snap-classic/none", SetupData, NULL, ++ tests_setup, test_portal_support_snap_none, tests_teardown); ++ g_test_add ("/portal-support/snap-classic/all", SetupData, NULL, ++ tests_setup, test_portal_support_snap_all, tests_teardown); ++ ++ return g_test_run (); ++} +diff --git a/gio/tests/portal-support-snap.c b/gio/tests/portal-support-snap.c +new file mode 100644 +index 000000000..7dd14d82f +--- /dev/null ++++ b/gio/tests/portal-support-snap.c +@@ -0,0 +1,208 @@ ++/* ++ * GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2022 Canonical Ltd. ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ * ++ * Author: Marco Trevisan ++ */ ++ ++#include "portal-support-utils.h" ++ ++#include "../gportalsupport.h" ++#include ++#include ++ ++typedef struct ++{ ++ char *old_path; ++ char *old_snap; ++ ++ const char *bin_path; ++ const char *snap_path; ++} SetupData; ++ ++static void ++tests_setup (SetupData *setup_data, ++ gconstpointer data) ++{ ++ setup_data->old_path = g_strdup (g_getenv ("PATH")); ++ setup_data->old_snap = g_strdup (g_getenv ("SNAP")); ++ ++ setup_data->bin_path = g_get_user_runtime_dir (); ++ setup_data->snap_path = g_getenv ("G_TEST_TMPDIR"); ++ ++ g_assert_nonnull (setup_data->bin_path); ++ g_assert_nonnull (setup_data->snap_path); ++ ++ g_setenv ("PATH", setup_data->bin_path, TRUE); ++ g_setenv ("SNAP", setup_data->snap_path, TRUE); ++} ++ ++static void ++tests_teardown (SetupData *setup_data, ++ gconstpointer data) ++{ ++ if (setup_data->old_path) ++ g_setenv ("PATH", setup_data->old_path, TRUE); ++ else ++ g_unsetenv ("PATH"); ++ ++ if (setup_data->old_snap) ++ g_setenv ("SNAP", setup_data->old_snap, TRUE); ++ else ++ g_unsetenv ("SNAP"); ++ ++ g_clear_pointer (&setup_data->old_path, g_free); ++ g_clear_pointer (&setup_data->old_snap, g_free); ++} ++ ++static void ++test_portal_support_snap_no_snapctl (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, FALSE); ++ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_false (glib_network_available_in_sandbox ()); ++ g_assert_false (glib_has_dconf_access_in_sandbox ()); ++} ++ ++static void ++test_portal_support_snap_none (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, FALSE); ++ create_fake_snapctl (setup->bin_path, NULL); ++ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_false (glib_network_available_in_sandbox ()); ++ g_assert_false (glib_has_dconf_access_in_sandbox ()); ++} ++ ++static void ++test_portal_support_snap_all (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, FALSE); ++ create_fake_snapctl (setup->bin_path, "desktop|network-status|gsettings"); ++ ++ g_assert_true (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++} ++ ++static void ++test_portal_support_snap_desktop_only (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, FALSE); ++ create_fake_snapctl (setup->bin_path, "desktop"); ++ ++ g_assert_true (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_false (glib_has_dconf_access_in_sandbox ()); ++} ++ ++static void ++test_portal_support_snap_network_only (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, FALSE); ++ create_fake_snapctl (setup->bin_path, "network-status"); ++ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_false (glib_has_dconf_access_in_sandbox ()); ++} ++ ++static void ++test_portal_support_snap_gsettings_only (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, FALSE); ++ create_fake_snapctl (setup->bin_path, "gsettings"); ++ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_false (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++} ++ ++static void ++test_portal_support_snap_updates_dynamically (SetupData *setup, ++ gconstpointer data) ++{ ++ create_fake_snap_yaml (setup->snap_path, FALSE); ++ create_fake_snapctl (setup->bin_path, NULL); ++ ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_false (glib_network_available_in_sandbox ()); ++ g_assert_false (glib_has_dconf_access_in_sandbox ()); ++ ++ create_fake_snapctl (setup->bin_path, "desktop"); ++ g_assert_true (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_false (glib_has_dconf_access_in_sandbox ()); ++ ++ create_fake_snapctl (setup->bin_path, "network-status|gsettings"); ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++ ++ create_fake_snapctl (setup->bin_path, "desktop|network-status|gsettings"); ++ g_assert_true (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++ ++ create_fake_snapctl (setup->bin_path, "desktop|gsettings"); ++ g_assert_true (glib_should_use_portal ()); ++ g_assert_true (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++ ++ create_fake_snapctl (setup->bin_path, "gsettings"); ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_false (glib_network_available_in_sandbox ()); ++ g_assert_true (glib_has_dconf_access_in_sandbox ()); ++ ++ create_fake_snapctl (setup->bin_path, NULL); ++ g_assert_false (glib_should_use_portal ()); ++ g_assert_false (glib_network_available_in_sandbox ()); ++ g_assert_false (glib_has_dconf_access_in_sandbox ()); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); ++ ++ g_test_add ("/portal-support/snap/no-snapctl", SetupData, NULL, ++ tests_setup, test_portal_support_snap_no_snapctl, tests_teardown); ++ g_test_add ("/portal-support/snap/none", SetupData, NULL, ++ tests_setup, test_portal_support_snap_none, tests_teardown); ++ g_test_add ("/portal-support/snap/all", SetupData, NULL, ++ tests_setup, test_portal_support_snap_all, tests_teardown); ++ g_test_add ("/portal-support/snap/desktop-only", SetupData, NULL, ++ tests_setup, test_portal_support_snap_desktop_only, tests_teardown); ++ g_test_add ("/portal-support/snap/network-only", SetupData, NULL, ++ tests_setup, test_portal_support_snap_network_only, tests_teardown); ++ g_test_add ("/portal-support/snap/gsettings-only", SetupData, NULL, ++ tests_setup, test_portal_support_snap_gsettings_only, tests_teardown); ++ g_test_add ("/portal-support/snap/updates-dynamically", SetupData, NULL, ++ tests_setup, test_portal_support_snap_updates_dynamically, tests_teardown); ++ ++ return g_test_run (); ++} +diff --git a/gio/tests/portal-support-utils.c b/gio/tests/portal-support-utils.c +new file mode 100644 +index 000000000..9fb69287a +--- /dev/null ++++ b/gio/tests/portal-support-utils.c +@@ -0,0 +1,87 @@ ++/* ++ * GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2022 Canonical Ltd. ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ * ++ * Author: Marco Trevisan ++ */ ++ ++#include "portal-support-utils.h" ++ ++#include ++#include ++ ++void ++create_fake_snapctl (const char *path, ++ const char *supported_op) ++{ ++ GError *error = NULL; ++ char *snapctl_content; ++ char *snapctl; ++ ++ snapctl = g_build_filename (path, "snapctl", NULL); ++ snapctl_content = g_strdup_printf ("#!/bin/sh\n" \ ++ "[ \"$1\" != 'is-connected' ] && exit 2\n" ++ "[ -z \"$2\" ] && exit 3\n" ++ "[ -n \"$3\" ] && exit 4\n" ++ "case \"$2\" in\n" ++ " %s) exit 0;;\n" ++ " *) exit 1;;\n" ++ "esac\n", ++ supported_op ? supported_op : ""); ++ ++ g_file_set_contents (snapctl, snapctl_content, -1, &error); ++ g_assert_no_error (error); ++ g_assert_cmpint (g_chmod (snapctl, 0500), ==, 0); ++ ++ g_test_message ("Created snapctl in %s", snapctl); ++ ++ g_clear_error (&error); ++ g_free (snapctl_content); ++ g_free (snapctl); ++} ++ ++void ++create_fake_snap_yaml (const char *snap_path, ++ gboolean is_classic) ++{ ++ char *meta_path; ++ char *yaml_path; ++ char *yaml_contents; ++ ++ g_assert_nonnull (snap_path); ++ ++ yaml_contents = g_strconcat ("name: glib-test-portal-support\n" ++ "title: GLib Portal Support Test\n" ++ "version: 2.76\n" ++ "summary: Test it works\n", ++ is_classic ? ++ "confinement: classic\n" : NULL, NULL); ++ ++ meta_path = g_build_filename (snap_path, "meta", NULL); ++ g_assert_cmpint (g_mkdir_with_parents (meta_path, 0700), ==, 0); ++ ++ yaml_path = g_build_filename (meta_path, "snap.yaml", NULL); ++ g_file_set_contents (yaml_path, yaml_contents, -1, NULL); ++ ++ g_test_message ("Created snap.yaml in %s", yaml_path); ++ ++ g_free (meta_path); ++ g_free (yaml_path); ++ g_free (yaml_contents); ++} +diff --git a/gio/tests/portal-support-utils.h b/gio/tests/portal-support-utils.h +new file mode 100644 +index 000000000..bb5a31c6e +--- /dev/null ++++ b/gio/tests/portal-support-utils.h +@@ -0,0 +1,30 @@ ++/* ++ * GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright (C) 2022 Canonical Ltd. ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ * ++ * Author: Marco Trevisan ++ */ ++ ++#include ++ ++void create_fake_snap_yaml (const char *snap_path, ++ gboolean is_classic); ++ ++void create_fake_snapctl (const char *path, ++ const char *supported_op); +diff --git a/gio/tests/sandbox.c b/gio/tests/sandbox.c +new file mode 100644 +index 000000000..a432556dd +--- /dev/null ++++ b/gio/tests/sandbox.c +@@ -0,0 +1,80 @@ ++/* ++ * Copyright 2022 Canonical Ltd ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ */ ++ ++#include "portal-support-utils.h" ++ ++#include "../gsandbox.h" ++#include ++#include ++ ++static void ++test_sandbox_none (void) ++{ ++ g_assert_cmpint (glib_get_sandbox_type (), ==, G_SANDBOX_TYPE_UNKNOWN); ++} ++ ++static void ++test_sandbox_snap (void) ++{ ++ const char *temp_dir; ++ gchar *snap_path; ++ ++ temp_dir = g_getenv ("G_TEST_TMPDIR"); ++ g_assert_nonnull (temp_dir); ++ ++ snap_path = g_build_filename (temp_dir, "snap", "current", NULL); ++ create_fake_snap_yaml (snap_path, FALSE); ++ g_setenv ("SNAP", snap_path, TRUE); ++ ++ g_assert_cmpint (glib_get_sandbox_type (), ==, G_SANDBOX_TYPE_SNAP); ++ ++ g_unsetenv ("SNAP"); ++ g_free (snap_path); ++} ++ ++static void ++test_sandbox_snap_classic (void) ++{ ++ const char *temp_dir; ++ char *snap_path; ++ ++ temp_dir = g_getenv ("G_TEST_TMPDIR"); ++ g_assert_nonnull (temp_dir); ++ ++ snap_path = g_build_filename (temp_dir, "snap", "current", NULL); ++ create_fake_snap_yaml (snap_path, TRUE); ++ g_setenv ("SNAP", snap_path, TRUE); ++ ++ g_assert_cmpint (glib_get_sandbox_type (), ==, G_SANDBOX_TYPE_UNKNOWN); ++ ++ g_unsetenv ("SNAP"); ++ g_free (snap_path); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); ++ ++ g_test_add_func ("/sandbox/none", test_sandbox_none); ++ g_test_add_func ("/sandbox/snap", test_sandbox_snap); ++ g_test_add_func ("/sandbox/classic-snap", test_sandbox_snap_classic); ++ ++ return g_test_run (); ++} +-- +2.39.2 + diff --git a/debian/patches/0001-timer-test-use-volatile-for-locals.patch b/debian/patches/0001-timer-test-use-volatile-for-locals.patch new file mode 100644 index 0000000..1bf63f8 --- /dev/null +++ b/debian/patches/0001-timer-test-use-volatile-for-locals.patch @@ -0,0 +1,38 @@ +From: Ryan Lortie +Date: Tue, 4 Mar 2014 09:20:38 -0500 +Subject: timer test: use 'volatile' for locals + +GCC seems to be failing to follow the letter of the C spec by allowing extra +precision in floating point values to persist across assignments which are +optimised away. + +Force its hand by using 'volatile' on the locals in question. + +Bug: https://gitlab.gnome.org/GNOME/glib/issues/820 +Forwarded: yes +--- + glib/tests/timer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/glib/tests/timer.c b/glib/tests/timer.c +index 102406e..8ea5c1f 100644 +--- a/glib/tests/timer.c ++++ b/glib/tests/timer.c +@@ -30,7 +30,7 @@ static void + test_timer_basic (void) + { + GTimer *timer; +- gdouble elapsed; ++ volatile gdouble elapsed; + gulong micros; + + timer = g_timer_new (); +@@ -65,7 +65,7 @@ static void + test_timer_stop (void) + { + GTimer *timer; +- gdouble elapsed, elapsed2; ++ volatile gdouble elapsed, elapsed2; + + timer = g_timer_new (); + diff --git a/debian/patches/01_gettext-desktopfiles.patch b/debian/patches/01_gettext-desktopfiles.patch new file mode 100644 index 0000000..95163b6 --- /dev/null +++ b/debian/patches/01_gettext-desktopfiles.patch @@ -0,0 +1,167 @@ +From: Philip Withnall +Date: Thu, 23 Nov 2017 18:48:58 +0000 +Subject: Call gettext if .desktop file does not have inline translations + +Patch from OpenSUSE via Ubuntu, original author unknown. Martin Pitt and +Vincent Untz appear to be the main authors. + +Reworked slightly by Philip Withnall to avoid exposing new public API +for the non-standard keys. + +Bug: https://bugzilla.gnome.org/show_bug.cgi?id=569829 +Bug-Ubuntu: https://launchpad.net/bugs/3935 +Applied-upstream: no, rejected because "this will be solved soon" (in 2013) +--- + glib/gkeyfile.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 83 insertions(+) + +diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c +index 6460970..762dfef 100644 +--- a/glib/gkeyfile.c ++++ b/glib/gkeyfile.c +@@ -489,6 +489,17 @@ + * Since: 2.14 + */ + ++/* Downstream Debian defines for calling gettext() if a .desktop file doesn’t ++ * contain translations. These are not standardised. ++ * ++ * See: https://launchpad.net/bugs/3935 ++ * See:http://bugzilla.gnome.org/show_bug.cgi?id=569829 ++ */ ++#define G_KEY_FILE_DESKTOP_ACTION_GROUP_PREFIX "Desktop Action" ++#define G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN "X-GNOME-Gettext-Domain" ++#define G_KEY_FILE_DESKTOP_KEY_FULLNAME "X-GNOME-FullName" ++#define G_KEY_FILE_DESKTOP_KEY_KEYWORDS "Keywords" ++ + typedef struct _GKeyFileGroup GKeyFileGroup; + + /** +@@ -513,6 +524,7 @@ struct _GKeyFile + + gboolean checked_locales; /* TRUE if @locales has been initialised */ + gchar **locales; /* (nullable) */ ++ gchar *gettext_domain; + + gint ref_count; /* (atomic) */ + }; +@@ -639,6 +651,7 @@ g_key_file_init (GKeyFile *key_file) + key_file->parse_buffer = NULL; + key_file->list_separator = ';'; + key_file->flags = 0; ++ key_file->gettext_domain = NULL; + } + + static void +@@ -659,6 +672,12 @@ g_key_file_clear (GKeyFile *key_file) + key_file->parse_buffer = NULL; + } + ++ if (key_file->gettext_domain) ++ { ++ g_free (key_file->gettext_domain); ++ key_file->gettext_domain = NULL; ++ } ++ + tmp = key_file->groups; + while (tmp != NULL) + { +@@ -879,6 +898,11 @@ g_key_file_load_from_fd (GKeyFile *key_file, + return FALSE; + } + ++ key_file->gettext_domain = g_key_file_get_string (key_file, ++ G_KEY_FILE_DESKTOP_GROUP, ++ G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, ++ NULL); ++ + return TRUE; + } + +@@ -991,6 +1015,11 @@ g_key_file_load_from_data (GKeyFile *key_file, + return FALSE; + } + ++ key_file->gettext_domain = g_key_file_get_string (key_file, ++ G_KEY_FILE_DESKTOP_GROUP, ++ G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, ++ NULL); ++ + return TRUE; + } + +@@ -2240,6 +2269,8 @@ g_key_file_get_locale_string (GKeyFile *key_file, + GError *key_file_error; + gchar **languages; + gboolean free_languages = FALSE; ++ gboolean try_gettext = FALSE; ++ const gchar *msg_locale; + gint i; + + g_return_val_if_fail (key_file != NULL, NULL); +@@ -2261,6 +2292,25 @@ g_key_file_get_locale_string (GKeyFile *key_file, + free_languages = FALSE; + } + ++ /* we're only interested in gettext translation if we don't have a ++ * translation in the .desktop file itself and if the key is one of the keys ++ * we know we want to translate: Name, GenericName, Comment, Keywords. ++ * Blindly doing this for all keys can give strange result for the icons, ++ * since the Icon is a locale string in the spec, eg. We also only get ++ * translation in the mo file if the requested locale is the LC_MESSAGES one. ++ * Ideally, we should do more and change LC_MESSAGES to use the requested ++ * locale, but there's no guarantee it's installed on the system and it might ++ * have some side-effects. Since this is a corner case, let's ignore it. */ ++ msg_locale = setlocale (LC_MESSAGES, NULL); ++ try_gettext = msg_locale && key_file->gettext_domain && ++ (strcmp (group_name, G_KEY_FILE_DESKTOP_GROUP) == 0 || ++ g_str_has_prefix (group_name, G_KEY_FILE_DESKTOP_ACTION_GROUP_PREFIX)) && ++ (strcmp (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0 || ++ strcmp (key, G_KEY_FILE_DESKTOP_KEY_FULLNAME) == 0 || ++ strcmp (key, G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME) == 0 || ++ strcmp (key, G_KEY_FILE_DESKTOP_KEY_KEYWORDS) == 0 || ++ strcmp (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0); ++ + for (i = 0; languages[i]; i++) + { + candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); +@@ -2274,6 +2324,39 @@ g_key_file_get_locale_string (GKeyFile *key_file, + break; + } + ++ /* Fallback to gettext */ ++ if (try_gettext && !translated_value) ++ { ++ gchar *orig_value = g_key_file_get_string (key_file, group_name, key, NULL); ++ ++ if (orig_value) ++ { ++ gboolean codeset_set; ++ const gchar *translated; ++ gboolean has_gettext; ++ ++ codeset_set = bind_textdomain_codeset (key_file->gettext_domain, "UTF-8") != NULL; ++ translated = NULL; ++ ++ translated = g_dgettext (key_file->gettext_domain, ++ orig_value); ++ has_gettext = translated != orig_value; ++ ++ g_free (orig_value); ++ ++ if (has_gettext) ++ { ++ if (codeset_set) ++ translated_value = g_strdup (translated); ++ else ++ translated_value = g_locale_to_utf8 (translated, ++ -1, NULL, NULL, NULL); ++ } ++ else ++ translated_value = NULL; ++ } ++ } ++ + /* Fallback to untranslated key + */ + if (!translated_value) diff --git a/debian/patches/debian/02_gettext-desktopfiles-ubuntu.patch b/debian/patches/debian/02_gettext-desktopfiles-ubuntu.patch new file mode 100644 index 0000000..fa5ae60 --- /dev/null +++ b/debian/patches/debian/02_gettext-desktopfiles-ubuntu.patch @@ -0,0 +1,51 @@ +From: Martin Pitt +Date: Tue, 24 Feb 2009 16:08:05 +0100 +Subject: Provide backwards compatibility for 01_gettext-desktopfiles.patch + for X-{Debian,Ubuntu}-Gettext-Domain + +Ubuntu-specific. 01_gettext-desktopfiles.patch was changed to use +X-GNOME-, so this is necessary until all our .desktop files are converted. + +Forwarded: no +--- + glib/gkeyfile.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c +index 762dfef..6b9f45b 100644 +--- a/glib/gkeyfile.c ++++ b/glib/gkeyfile.c +@@ -902,6 +902,16 @@ g_key_file_load_from_fd (GKeyFile *key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, + NULL); ++ if (!key_file->gettext_domain) ++ key_file->gettext_domain = g_key_file_get_string (key_file, ++ G_KEY_FILE_DESKTOP_GROUP, ++ "X-Ubuntu-Gettext-Domain", ++ NULL); ++ if (!key_file->gettext_domain) ++ key_file->gettext_domain = g_key_file_get_string (key_file, ++ G_KEY_FILE_DESKTOP_GROUP, ++ "X-Debian-Gettext-Domain", ++ NULL); + + return TRUE; + } +@@ -1019,6 +1029,16 @@ g_key_file_load_from_data (GKeyFile *key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, + NULL); ++ if (!key_file->gettext_domain) ++ key_file->gettext_domain = g_key_file_get_string (key_file, ++ G_KEY_FILE_DESKTOP_GROUP, ++ "X-Ubuntu-Gettext-Domain", ++ NULL); ++ if (!key_file->gettext_domain) ++ key_file->gettext_domain = g_key_file_get_string (key_file, ++ G_KEY_FILE_DESKTOP_GROUP, ++ "X-Debian-Gettext-Domain", ++ NULL); + + return TRUE; + } diff --git a/debian/patches/debian/03_disble_glib_compile_schemas_warning.patch b/debian/patches/debian/03_disble_glib_compile_schemas_warning.patch new file mode 100644 index 0000000..bf2a4de --- /dev/null +++ b/debian/patches/debian/03_disble_glib_compile_schemas_warning.patch @@ -0,0 +1,36 @@ +From: Iain Lane +Date: Mon, 10 Sep 2012 16:25:18 +0100 +Subject: Disable confusing (to users) warning about deprecated schema paths + +Disable a warning when compiling schemas which are installed +into 'deprecated' locations. Users see this very often due to +glib-compile-schemas being called from libglib2.0-0's trigger and it is +not very useful for them. + +Forwarded: not-needed +--- + gio/glib-compile-schemas.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c +index 7e1152f..57f6b96 100644 +--- a/gio/glib-compile-schemas.c ++++ b/gio/glib-compile-schemas.c +@@ -1232,6 +1232,9 @@ parse_state_start_schema (ParseState *state, + return; + } + ++ // Disable this warning: it confuses users and there is unlikely to be much ++ // progress towards fixing ++ /* + if (path && (g_str_has_prefix (path, "/apps/") || + g_str_has_prefix (path, "/desktop/") || + g_str_has_prefix (path, "/system/"))) +@@ -1244,6 +1247,7 @@ parse_state_start_schema (ParseState *state, + g_printerr ("%s\n", message); + g_free (message); + } ++ */ + + state->schema_state = schema_state_new (path, gettext_domain, + extends, extends_name, list_of); diff --git a/debian/patches/debian/06_thread_test_ignore_prctl_fail.patch b/debian/patches/debian/06_thread_test_ignore_prctl_fail.patch new file mode 100644 index 0000000..f416084 --- /dev/null +++ b/debian/patches/debian/06_thread_test_ignore_prctl_fail.patch @@ -0,0 +1,33 @@ +From: Martin Pitt +Date: Tue, 26 Jun 2012 19:28:14 +0200 +Subject: Do not fail the /thread/thread4 test if prlimit() fails + +This happens on the Debian buildds. + +[smcv: Use g_test_skip()] + +Forwarded: no, Debian buildd specific +--- + glib/tests/thread.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/glib/tests/thread.c b/glib/tests/thread.c +index 2bae96c..d2a91bf 100644 +--- a/glib/tests/thread.c ++++ b/glib/tests/thread.c +@@ -146,7 +146,14 @@ test_thread4 (void) + nl.rlim_cur = 1; + + if ((ret = prlimit (getpid (), RLIMIT_NPROC, &nl, &ol)) != 0) +- g_error ("prlimit failed: %s", g_strerror (errno)); ++ { ++ gchar *message = g_strdup_printf ("setting PRLIMIT_NPROC to {cur=%d,max=%d} failed: %s", ++ (int) nl.rlim_cur, (int) nl.rlim_max, ++ g_strerror (errno)); ++ g_test_skip (message); ++ g_free (message); ++ return; ++ } + + error = NULL; + thread = g_thread_try_new ("a", thread1_func, NULL, &error); diff --git a/debian/patches/debian/Add-extra-debug-to-memory-monitor-dbus-test.patch b/debian/patches/debian/Add-extra-debug-to-memory-monitor-dbus-test.patch new file mode 100644 index 0000000..3dc4a85 --- /dev/null +++ b/debian/patches/debian/Add-extra-debug-to-memory-monitor-dbus-test.patch @@ -0,0 +1,70 @@ +From: Simon McVittie +Date: Sun, 24 Oct 2021 22:40:11 +0100 +Subject: Add extra debug to memory-monitor-dbus test + +Hopefully this will give us the necessary information to find out why +this test isn't reliable. + +Bug-Debian: https://bugs.debian.org/995178 +Forwarded: no +--- + gio/tests/memory-monitor-dbus.py.in | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/gio/tests/memory-monitor-dbus.py.in b/gio/tests/memory-monitor-dbus.py.in +index 17862e3..61e6f94 100755 +--- a/gio/tests/memory-monitor-dbus.py.in ++++ b/gio/tests/memory-monitor-dbus.py.in +@@ -74,18 +74,29 @@ try: + Timeout is in deciseconds, defaulting to 50 (5 seconds). message is + printed on failure. + ''' ++ print('Waiting up to {}/10 seconds for {!r} to be true'.format(timeout, condition)) ++ orig_timeout = timeout ++ + while timeout >= 0: ++ print('Loop iteration') + context = GLib.MainContext.default() + while context.iteration(False): ++ print('Iterating main loop') + pass + if condition(): ++ print('Condition reached') + break + timeout -= 1 + time.sleep(0.1) + else: ++ print('Condition not reached in {}/10 seconds'.format(orig_timeout)) + self.fail(message or 'timed out waiting for ' + str(condition)) + + def memory_warning_cb(self, monitor, level): ++ print('low-memory-warning: monitor {!r} reports level {}'.format( ++ monitor, ++ level, ++ )) + self.last_warning = level + self.main_context.wakeup() + +@@ -95,17 +106,20 @@ try: + # Wait 2 seconds + timeout = 2 + while timeout > 0: ++ print('Waiting 0.5s for stray events...') + time.sleep(0.5) + timeout -= 0.5 + self.main_context.iteration(False) + ++ print('Emitting mock low-memory warning, level 100: try to free memory') + self.dbusmock.EmitWarning(100) + # Wait 2 seconds or until warning +- self.assertEventually(lambda: self.last_warning == 100, "'100' low-memory warning not received", 20) ++ self.assertEventually(lambda: self.last_warning == 100, "'100' low-memory warning not received", 100) + ++ print('Emitting mock low-memory warning, level 255: OOM imminent') + self.dbusmock.EmitWarning(255) + # Wait 2 seconds or until warning +- self.assertEventually(lambda: self.last_warning == 255, "'255' low-memory warning not received", 20) ++ self.assertEventually(lambda: self.last_warning == 255, "'255' low-memory warning not received", 100) + + except ImportError as e: + @unittest.skip("Cannot import %s" % e.name) diff --git a/debian/patches/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch b/debian/patches/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch new file mode 100644 index 0000000..8df9442 --- /dev/null +++ b/debian/patches/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch @@ -0,0 +1,70 @@ +From: Martin Pitt +Date: Thu, 27 Sep 2012 11:22:56 +0200 +Subject: Disable some tests on slow architectures which keep failing the + tests + +[smcv: Modified to use g_test_skip() instead of omitting those test cases +completely, and allow them to be re-enabled with a Debian-specific +environment variable] + +Co-authored-by: Simon McVittie +Forwarded: no +--- + glib/tests/mainloop.c | 16 ++++++++++++++++ + glib/tests/timeout.c | 9 +++++++++ + 2 files changed, 25 insertions(+) + +diff --git a/glib/tests/mainloop.c b/glib/tests/mainloop.c +index 2bbb3d8..d6220a6 100644 +--- a/glib/tests/mainloop.c ++++ b/glib/tests/mainloop.c +@@ -520,6 +520,14 @@ test_child_sources (void) + GMainLoop *loop; + GSource *parent, *child_b, *child_c, *end; + ++#if defined(__arm__) ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("Not reliable on older ARM hardware"); ++ return; ++ } ++#endif ++ + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + +@@ -598,6 +606,14 @@ test_recursive_child_sources (void) + GMainLoop *loop; + GSource *parent, *child_b, *child_c, *end; + ++#if defined(__arm__) ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("Not reliable on older ARM hardware"); ++ return; ++ } ++#endif ++ + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + +diff --git a/glib/tests/timeout.c b/glib/tests/timeout.c +index 9e4d047..1ab8845 100644 +--- a/glib/tests/timeout.c ++++ b/glib/tests/timeout.c +@@ -179,6 +179,15 @@ test_func (gpointer data) + static void + test_rounding (void) + { ++ ++#if defined(__arm__) ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("Not reliable on older ARM hardware"); ++ return; ++ } ++#endif ++ + loop = g_main_loop_new (NULL, FALSE); + + last_time = g_get_monotonic_time (); diff --git a/debian/patches/debian/Skip-memory-monitor-dbus-test-if-not-specifically-request.patch b/debian/patches/debian/Skip-memory-monitor-dbus-test-if-not-specifically-request.patch new file mode 100644 index 0000000..b692f9f --- /dev/null +++ b/debian/patches/debian/Skip-memory-monitor-dbus-test-if-not-specifically-request.patch @@ -0,0 +1,25 @@ +From: Simon McVittie +Date: Sun, 24 Oct 2021 22:38:20 +0100 +Subject: Skip memory-monitor-dbus test if not specifically requested + +This seems to be unreliable, particularly on non-x86. + +Bug-Debian: https://bugs.debian.org/995178 +Forwarded: no +--- + gio/tests/memory-monitor-dbus.py.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gio/tests/memory-monitor-dbus.py.in b/gio/tests/memory-monitor-dbus.py.in +index bf32918..17862e3 100755 +--- a/gio/tests/memory-monitor-dbus.py.in ++++ b/gio/tests/memory-monitor-dbus.py.in +@@ -39,6 +39,8 @@ try: + klass.start_system_bus() + klass.dbus_con = klass.get_dbus(True) + ++ @unittest.skipIf('DEB_ALLOW_FLAKY_TESTS' not in os.environ, ++ 'https://bugs.debian.org/995178') + def setUp(self): + try: + Gio.MemoryMonitor diff --git a/debian/patches/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch b/debian/patches/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch new file mode 100644 index 0000000..d2ff7b7 --- /dev/null +++ b/debian/patches/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch @@ -0,0 +1,32 @@ +From: Iain Lane +Date: Tue, 18 Mar 2014 15:43:35 +0000 +Subject: Skip test which performs some unreliable floating point comparisons + +[smcv: Modified to use g_test_skip() instead of omitting those test cases +completely, and allow them to be re-enabled with a Debian-specific +environment variable] + +Co-authored-by: Simon McVittie +Bug: https://gitlab.gnome.org/GNOME/glib/issues/820 +Forwarded: no +--- + glib/tests/timer.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/glib/tests/timer.c b/glib/tests/timer.c +index 8ea5c1f..a4c1095 100644 +--- a/glib/tests/timer.c ++++ b/glib/tests/timer.c +@@ -33,6 +33,12 @@ test_timer_basic (void) + volatile gdouble elapsed; + gulong micros; + ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("Not reliable due to floating-point rounding (glib#820)"); ++ return; ++ } ++ + timer = g_timer_new (); + + g_timer_start (timer); diff --git a/debian/patches/debian/Skip-unreliable-gdbus-threading-tests--by-default.patch b/debian/patches/debian/Skip-unreliable-gdbus-threading-tests--by-default.patch new file mode 100644 index 0000000..1130f93 --- /dev/null +++ b/debian/patches/debian/Skip-unreliable-gdbus-threading-tests--by-default.patch @@ -0,0 +1,48 @@ +From: Simon McVittie +Date: Fri, 4 Jan 2019 08:37:20 +0000 +Subject: Skip unreliable gdbus-threading tests by default + +test_threaded_singleton() test to reproduce a race condition between +last-unref of the global singleton GDBusConnection and g_bus_get_sync(). + +test_method_calls_in_thread() checks that multiple threads can all make +method calls to the same proxy. + +However, test setup intermittently times out with: + + # GLib-GIO-DEBUG: run 0: refcount is 2, sleeping + Bail out! GLib-GIO-FATAL-ERROR: connection had too many refs + +The current theory upstream is that this might be a reference leak in +test_delivery_in_thread(). + +Furthermore, test teardown is now often failing when destroying the test +bus. + +Demote these tests to be run as part of the "flaky" autopkgtests, but +not at build time or in the part of the autopkgtest run that gates +progress into testing. + +Bug: https://gitlab.gnome.org/GNOME/glib/issues/1515 +Forwarded: no +--- + gio/tests/gdbus-threading.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/gio/tests/gdbus-threading.c b/gio/tests/gdbus-threading.c +index 9f3abc4..ec8867e 100644 +--- a/gio/tests/gdbus-threading.c ++++ b/gio/tests/gdbus-threading.c +@@ -649,6 +649,12 @@ main (int argc, + + g_test_init (&argc, &argv, NULL); + ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_print("ok 1 # SKIP all gdbus-threading tests skipped because they are too unreliable (glib#1515)\n"); ++ return 77; ++ } ++ + session_bus_up (); + + /* this is safe; testserver will exit once the bus goes away */ diff --git a/debian/patches/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch b/debian/patches/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch new file mode 100644 index 0000000..54b67f8 --- /dev/null +++ b/debian/patches/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch @@ -0,0 +1,37 @@ +From: Simon McVittie +Date: Thu, 3 Jan 2019 09:01:03 +0000 +Subject: closures test: Skip on arm* unless flaky tests are allowed + +Choosing the right number of iterations to avoid either taking literally +hours on some hardware, or getting spurious failures when one thread +starves another, seems to be too hard to get right in practice. +Make this test opt-in so that its failures aren't release-critical. +We can run it as a separate autopkgtest that is marked flaky. + +Signed-off-by: Simon McVittie +Bug-Debian: https://bugs.debian.org/880883 +Bug-Debian: https://bugs.debian.org/917983 +Forwarded: not-needed +--- + gobject/tests/closure-refcount.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/gobject/tests/closure-refcount.c b/gobject/tests/closure-refcount.c +index 5a92005..73185f0 100644 +--- a/gobject/tests/closure-refcount.c ++++ b/gobject/tests/closure-refcount.c +@@ -260,6 +260,14 @@ test_closure_refcount (void) + GTest *object; + guint i, n_iterations; + ++#if defined(__aarch64__) || defined(__arm__) ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") != NULL) ++ { ++ g_print ("SKIP: Test is known to be flaky on arm* (#880883, #917983)\n"); ++ return 0; ++ } ++#endif ++ + object = g_object_new (G_TYPE_TEST, NULL); + closure = g_cclosure_new (G_CALLBACK (test_signal_handler), &test_data, destroy_data); + diff --git a/debian/patches/debian/gdbus-server-auth-Normally-skip-flaky-DBUS_COOKIE_SHA1-te.patch b/debian/patches/debian/gdbus-server-auth-Normally-skip-flaky-DBUS_COOKIE_SHA1-te.patch new file mode 100644 index 0000000..43d2196 --- /dev/null +++ b/debian/patches/debian/gdbus-server-auth-Normally-skip-flaky-DBUS_COOKIE_SHA1-te.patch @@ -0,0 +1,35 @@ +From: Simon McVittie +Date: Thu, 19 Nov 2020 10:44:39 +0000 +Subject: gdbus-server-auth: Normally skip flaky DBUS_COOKIE_SHA1 tests + +These intermittently fail on the buildds, but the failure cannot be +reproduced in a debugging environment. + +We do not expect to use D-Bus over TCP on non-Windows platforms: we use +an AF_UNIX socket, which is much more robust and secure. However, when +using AF_UNIX, DBUS_COOKIE_SHA1 is unnecessary, because we can use the +more reliable EXTERNAL authentication. + +Forwarded: not-needed +--- + gio/tests/gdbus-server-auth.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/gio/tests/gdbus-server-auth.c b/gio/tests/gdbus-server-auth.c +index bd1443e..a231b0c 100644 +--- a/gio/tests/gdbus-server-auth.c ++++ b/gio/tests/gdbus-server-auth.c +@@ -324,6 +324,13 @@ do_test_server_auth (InteropFlags flags) + } + #endif + ++ if ((flags & (INTEROP_FLAGS_TCP | INTEROP_FLAGS_SHA1)) && ++ g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("https://gitlab.gnome.org/GNOME/glib/-/issues/2206"); ++ goto out; ++ } ++ + if (flags & INTEROP_FLAGS_ANONYMOUS) + server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; + if (flags & INTEROP_FLAGS_REQUIRE_SAME_USER) diff --git a/debian/patches/debian/gdesktopappinfo-Recognize-gnome-console-as-a-terminal-app.patch b/debian/patches/debian/gdesktopappinfo-Recognize-gnome-console-as-a-terminal-app.patch new file mode 100644 index 0000000..206643a --- /dev/null +++ b/debian/patches/debian/gdesktopappinfo-Recognize-gnome-console-as-a-terminal-app.patch @@ -0,0 +1,29 @@ +From: Jeremy Bicha +Date: Wed, 23 Mar 2022 14:40:16 -0400 +Subject: gdesktopappinfo: Recognize gnome-console as a terminal app + +GNOME Console (installed as /usr/bin/kgx ) is the default +GNOME terminal app as of GNOME 42 + +Related to: https://gitlab.gnome.org/GNOME/glib/-/issues/338 + +But see https://gitlab.freedesktop.org/xdg/xdg-specs/-/merge_requests/46 +for a more comprehensive way of handling issues around the default +terminal app +--- + gio/gdesktopappinfo.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c +index 60d6deb..4a0b019 100644 +--- a/gio/gdesktopappinfo.c ++++ b/gio/gdesktopappinfo.c +@@ -2672,6 +2672,8 @@ prepend_terminal_to_vector (int *argc, + } + else + { ++ if (check == NULL) ++ check = g_find_program_in_path ("kgx"); + if (check == NULL) + check = g_find_program_in_path ("tilix"); + if (check == NULL) diff --git a/debian/patches/debian/gmenumodel-test-Mark-as-flaky.patch b/debian/patches/debian/gmenumodel-test-Mark-as-flaky.patch new file mode 100644 index 0000000..13c3fba --- /dev/null +++ b/debian/patches/debian/gmenumodel-test-Mark-as-flaky.patch @@ -0,0 +1,30 @@ +From: Simon McVittie +Date: Fri, 26 Jul 2019 23:49:03 +0100 +Subject: gmenumodel test: Mark as flaky + +This test has not had a great history of reliability. + +Signed-off-by: Simon McVittie +Bug-Debian: https://bugs.debian.org/932678 +Forwarded: no +--- + gio/tests/gmenumodel.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/gio/tests/gmenumodel.c b/gio/tests/gmenumodel.c +index 492daf8..ed8828d 100644 +--- a/gio/tests/gmenumodel.c ++++ b/gio/tests/gmenumodel.c +@@ -1160,6 +1160,12 @@ test_dbus_peer_subscriptions (void) + #else + PeerConnection peer; + ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("Not reliable? #932678"); ++ return; ++ } ++ + peer_connection_up (&peer); + do_subscriptions (peer.server_connection, peer.client_connection); + peer_connection_down (&peer); diff --git a/debian/patches/debian/gvariant-test-Don-t-run-at-build-time-on-mips.patch b/debian/patches/debian/gvariant-test-Don-t-run-at-build-time-on-mips.patch new file mode 100644 index 0000000..e94e5d2 --- /dev/null +++ b/debian/patches/debian/gvariant-test-Don-t-run-at-build-time-on-mips.patch @@ -0,0 +1,36 @@ +From: Simon McVittie +Date: Fri, 26 Jul 2019 23:51:39 +0100 +Subject: gvariant test: Don't run at build-time on mips + +DEB_ALLOW_FLAKY_TESTS is not quite right here, because we don't know +that the test would fail if left for long enough - the problem is that +it doesn't get there, because generating random floating-point numbers +is very slow on some of our mips hardware. However, it has the right +practical effect. + +Signed-off-by: Simon McVittie +Bug: https://bugs.debian.org/932678 +Forwarded: no +--- + glib/tests/gvariant.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c +index 0110f26..1f30d23 100644 +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -2401,6 +2401,14 @@ test_fuzzes (gpointer data) + gdouble fuzziness; + int i; + ++#ifdef __mips__ ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("Extremely slow on some mips CPUs: #932678"); ++ return; ++ } ++#endif ++ + fuzziness = GPOINTER_TO_INT (data) / 100.; + + for (i = 0; i < 200; i++) diff --git a/debian/patches/debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch b/debian/patches/debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch new file mode 100644 index 0000000..a89306f --- /dev/null +++ b/debian/patches/debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch @@ -0,0 +1,117 @@ +From: Simon McVittie +Date: Tue, 25 Feb 2020 10:45:07 +0000 +Subject: testfilemonitor: Skip if we are avoiding flaky tests + +See https://gitlab.gnome.org/GNOME/glib/issues/1634 + +Signed-off-by: Simon McVittie +Forwarded: no +--- + gio/tests/testfilemonitor.c | 38 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 37 insertions(+), 1 deletion(-) + +diff --git a/gio/tests/testfilemonitor.c b/gio/tests/testfilemonitor.c +index 082f0db..7e7db90 100644 +--- a/gio/tests/testfilemonitor.c ++++ b/gio/tests/testfilemonitor.c +@@ -32,6 +32,12 @@ setup (Fixture *fixture, + gchar *path = NULL; + GError *local_error = NULL; + ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("https://gitlab.gnome.org/GNOME/glib/issues/1634"); ++ return; ++ } ++ + path = g_dir_make_tmp ("gio-test-testfilemonitor_XXXXXX", &local_error); + g_assert_no_error (local_error); + +@@ -48,7 +54,9 @@ teardown (Fixture *fixture, + { + GError *local_error = NULL; + +- g_file_delete (fixture->tmp_dir, NULL, &local_error); ++ if (fixture->tmp_dir != NULL) ++ g_file_delete (fixture->tmp_dir, NULL, &local_error); ++ + g_assert_no_error (local_error); + g_clear_object (&fixture->tmp_dir); + } +@@ -375,6 +383,10 @@ test_atomic_replace (Fixture *fixture, + if (skip_win32 ()) + return; + ++ /* respect g_test_skip() during setup() */ ++ if (g_test_failed ()) ++ return; ++ + data.step = 0; + data.events = NULL; + +@@ -483,6 +495,10 @@ test_file_changes (Fixture *fixture, + if (skip_win32 ()) + return; + ++ /* respect g_test_skip() during setup() */ ++ if (g_test_failed ()) ++ return; ++ + data.step = 0; + data.events = NULL; + +@@ -603,6 +619,10 @@ test_dir_monitor (Fixture *fixture, + if (skip_win32 ()) + return; + ++ /* respect g_test_skip() during setup() */ ++ if (g_test_failed ()) ++ return; ++ + data.step = 0; + data.events = NULL; + +@@ -703,6 +723,10 @@ test_dir_non_existent (Fixture *fixture, + if (skip_win32 ()) + return; + ++ /* respect g_test_skip() during setup() */ ++ if (g_test_failed ()) ++ return; ++ + data.step = 0; + data.events = NULL; + +@@ -815,6 +839,10 @@ test_cross_dir_moves (Fixture *fixture, + if (skip_win32 ()) + return; + ++ /* respect g_test_skip() during setup() */ ++ if (g_test_failed ()) ++ return; ++ + data[0].step = 0; + data[0].events = NULL; + +@@ -984,6 +1012,10 @@ test_file_hard_links (Fixture *fixture, + GError *error = NULL; + TestData data; + ++ /* respect g_test_skip() during setup() */ ++ if (g_test_failed ()) ++ return; ++ + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=755721"); + + if (skip_win32 ()) +@@ -1043,6 +1075,10 @@ test_finalize_in_callback (Fixture *fixture, + GFile *file = NULL; + guint i; + ++ /* respect g_test_skip() during setup() */ ++ if (g_test_failed ()) ++ return; ++ + g_test_summary ("Test that finalization of a GFileMonitor in one of its " + "callbacks doesn’t cause a deadlock."); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1941"); diff --git a/debian/patches/debian/tests-Skip-debugcontroller-test.patch b/debian/patches/debian/tests-Skip-debugcontroller-test.patch new file mode 100644 index 0000000..0b7eb8a --- /dev/null +++ b/debian/patches/debian/tests-Skip-debugcontroller-test.patch @@ -0,0 +1,28 @@ +From: Simon McVittie +Date: Tue, 15 Feb 2022 20:42:53 +0000 +Subject: tests: Skip debugcontroller test + +This is known to be flaky upstream. + +Forwarded: not-needed +--- + gio/tests/debugcontroller.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/gio/tests/debugcontroller.c b/gio/tests/debugcontroller.c +index c20acd6..9c7216e 100644 +--- a/gio/tests/debugcontroller.c ++++ b/gio/tests/debugcontroller.c +@@ -189,6 +189,12 @@ test_dbus_properties (void) + + g_test_summary ("Test getting and setting properties on a #GDebugControllerDBus."); + ++ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) ++ { ++ g_test_skip ("https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2486#note_1384102"); ++ return; ++ } ++ + /* Set up a test session bus and connection. Set up a separate second + * connection to simulate a remote peer. */ + bus = g_test_dbus_new (G_TEST_DBUS_NONE); diff --git a/debian/patches/gvariant-security-1-01.patch b/debian/patches/gvariant-security-1-01.patch new file mode 100644 index 0000000..7fa3682 --- /dev/null +++ b/debian/patches/gvariant-security-1-01.patch @@ -0,0 +1,94 @@ +From 590f7a6b76b5a3695aa562c9c3ab244433b6624b Mon Sep 17 00:00:00 2001 +From: William Manley +Date: Tue, 23 Jun 2020 22:59:58 +0100 +Subject: [PATCH 01/18] gvariant-core: Consolidate construction of + `GVariantSerialised` + +So I only need to change it in one place. + +This introduces no functional changes. + +Helps: #2121 +--- + glib/gvariant-core.c | 49 ++++++++++++++++++++++---------------------- + 1 file changed, 25 insertions(+), 24 deletions(-) + +--- a/glib/gvariant-core.c ++++ b/glib/gvariant-core.c +@@ -350,6 +350,27 @@ g_variant_ensure_size (GVariant *value) + } + + /* < private > ++ * g_variant_to_serialised: ++ * @value: a #GVariant ++ * ++ * Gets a GVariantSerialised for a GVariant in state STATE_SERIALISED. ++ */ ++inline static GVariantSerialised ++g_variant_to_serialised (GVariant *value) ++{ ++ g_assert (value->state & STATE_SERIALISED); ++ { ++ GVariantSerialised serialised = { ++ value->type_info, ++ (gpointer) value->contents.serialised.data, ++ value->size, ++ value->depth, ++ }; ++ return serialised; ++ } ++} ++ ++/* < private > + * g_variant_serialise: + * @value: a #GVariant + * @data: an appropriately-sized buffer +@@ -1007,16 +1028,8 @@ g_variant_n_children (GVariant *value) + g_variant_lock (value); + + if (value->state & STATE_SERIALISED) +- { +- GVariantSerialised serialised = { +- value->type_info, +- (gpointer) value->contents.serialised.data, +- value->size, +- value->depth, +- }; +- +- n_children = g_variant_serialised_n_children (serialised); +- } ++ n_children = g_variant_serialised_n_children ( ++ g_variant_to_serialised (value)); + else + n_children = value->contents.tree.n_children; + +@@ -1083,12 +1096,7 @@ g_variant_get_child_value (GVariant *val + } + + { +- GVariantSerialised serialised = { +- value->type_info, +- (gpointer) value->contents.serialised.data, +- value->size, +- value->depth, +- }; ++ GVariantSerialised serialised = g_variant_to_serialised (value); + GVariantSerialised s_child; + GVariant *child; + +@@ -1201,14 +1209,7 @@ g_variant_is_normal_form (GVariant *valu + + if (value->state & STATE_SERIALISED) + { +- GVariantSerialised serialised = { +- value->type_info, +- (gpointer) value->contents.serialised.data, +- value->size, +- value->depth +- }; +- +- if (g_variant_serialised_is_normal (serialised)) ++ if (g_variant_serialised_is_normal (g_variant_to_serialised (value))) + value->state |= STATE_TRUSTED; + } + else diff --git a/debian/patches/gvariant-security-1-02.patch b/debian/patches/gvariant-security-1-02.patch new file mode 100644 index 0000000..86547dd --- /dev/null +++ b/debian/patches/gvariant-security-1-02.patch @@ -0,0 +1,201 @@ +From f8f5d8eefa06008aa8fe684069193dc3b1ae1b58 Mon Sep 17 00:00:00 2001 +From: William Manley +Date: Thu, 25 Jun 2020 17:08:21 +0100 +Subject: [PATCH 02/18] gvariant-serialiser: Factor out functions for dealing + with framing offsets + +This introduces no functional changes. + +Helps: #2121 +--- + glib/gvariant-serialiser.c | 108 +++++++++++++++++++------------------ + 1 file changed, 57 insertions(+), 51 deletions(-) + +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -633,30 +633,62 @@ gvs_calculate_total_size (gsize body_siz + return body_size + 8 * offsets; + } + ++struct Offsets ++{ ++ gsize data_size; ++ ++ guchar *array; ++ gsize length; ++ guint offset_size; ++ ++ gboolean is_normal; ++}; ++ + static gsize +-gvs_variable_sized_array_n_children (GVariantSerialised value) ++gvs_offsets_get_offset_n (struct Offsets *offsets, ++ gsize n) + { ++ return gvs_read_unaligned_le ( ++ offsets->array + (offsets->offset_size * n), offsets->offset_size); ++} ++ ++static struct Offsets ++gvs_variable_sized_array_get_frame_offsets (GVariantSerialised value) ++{ ++ struct Offsets out = { 0, }; + gsize offsets_array_size; +- gsize offset_size; + gsize last_end; + + if (value.size == 0) +- return 0; +- +- offset_size = gvs_get_offset_size (value.size); ++ { ++ out.is_normal = TRUE; ++ return out; ++ } + +- last_end = gvs_read_unaligned_le (value.data + value.size - +- offset_size, offset_size); ++ out.offset_size = gvs_get_offset_size (value.size); ++ last_end = gvs_read_unaligned_le (value.data + value.size - out.offset_size, ++ out.offset_size); + + if (last_end > value.size) +- return 0; ++ return out; /* offsets not normal */ + + offsets_array_size = value.size - last_end; + +- if (offsets_array_size % offset_size) +- return 0; ++ if (offsets_array_size % out.offset_size) ++ return out; /* offsets not normal */ + +- return offsets_array_size / offset_size; ++ out.data_size = last_end; ++ out.array = value.data + last_end; ++ out.length = offsets_array_size / out.offset_size; ++ out.is_normal = TRUE; ++ ++ return out; ++} ++ ++static gsize ++gvs_variable_sized_array_n_children (GVariantSerialised value) ++{ ++ return gvs_variable_sized_array_get_frame_offsets (value).length; + } + + static GVariantSerialised +@@ -664,8 +696,9 @@ gvs_variable_sized_array_get_child (GVar + gsize index_) + { + GVariantSerialised child = { 0, }; +- gsize offset_size; +- gsize last_end; ++ ++ struct Offsets offsets = gvs_variable_sized_array_get_frame_offsets (value); ++ + gsize start; + gsize end; + +@@ -673,18 +706,11 @@ gvs_variable_sized_array_get_child (GVar + g_variant_type_info_ref (child.type_info); + child.depth = value.depth + 1; + +- offset_size = gvs_get_offset_size (value.size); +- +- last_end = gvs_read_unaligned_le (value.data + value.size - +- offset_size, offset_size); +- + if (index_ > 0) + { + guint alignment; + +- start = gvs_read_unaligned_le (value.data + last_end + +- (offset_size * (index_ - 1)), +- offset_size); ++ start = gvs_offsets_get_offset_n (&offsets, index_ - 1); + + g_variant_type_info_query (child.type_info, &alignment, NULL); + start += (-start) & alignment; +@@ -692,11 +718,9 @@ gvs_variable_sized_array_get_child (GVar + else + start = 0; + +- end = gvs_read_unaligned_le (value.data + last_end + +- (offset_size * index_), +- offset_size); ++ end = gvs_offsets_get_offset_n (&offsets, index_); + +- if (start < end && end <= value.size && end <= last_end) ++ if (start < end && end <= value.size && end <= offsets.data_size) + { + child.data = value.data + start; + child.size = end - start; +@@ -768,34 +792,16 @@ static gboolean + gvs_variable_sized_array_is_normal (GVariantSerialised value) + { + GVariantSerialised child = { 0, }; +- gsize offsets_array_size; +- guchar *offsets_array; +- guint offset_size; + guint alignment; +- gsize last_end; +- gsize length; + gsize offset; + gsize i; + +- if (value.size == 0) +- return TRUE; +- +- offset_size = gvs_get_offset_size (value.size); +- last_end = gvs_read_unaligned_le (value.data + value.size - +- offset_size, offset_size); ++ struct Offsets offsets = gvs_variable_sized_array_get_frame_offsets (value); + +- if (last_end > value.size) ++ if (!offsets.is_normal) + return FALSE; + +- offsets_array_size = value.size - last_end; +- +- if (offsets_array_size % offset_size) +- return FALSE; +- +- offsets_array = value.data + value.size - offsets_array_size; +- length = offsets_array_size / offset_size; +- +- if (length == 0) ++ if (value.size != 0 && offsets.length == 0) + return FALSE; + + child.type_info = g_variant_type_info_element (value.type_info); +@@ -803,14 +809,14 @@ gvs_variable_sized_array_is_normal (GVar + child.depth = value.depth + 1; + offset = 0; + +- for (i = 0; i < length; i++) ++ for (i = 0; i < offsets.length; i++) + { + gsize this_end; + +- this_end = gvs_read_unaligned_le (offsets_array + offset_size * i, +- offset_size); ++ this_end = gvs_read_unaligned_le (offsets.array + offsets.offset_size * i, ++ offsets.offset_size); + +- if (this_end < offset || this_end > last_end) ++ if (this_end < offset || this_end > offsets.data_size) + return FALSE; + + while (offset & alignment) +@@ -832,7 +838,7 @@ gvs_variable_sized_array_is_normal (GVar + offset = this_end; + } + +- g_assert (offset == last_end); ++ g_assert (offset == offsets.data_size); + + return TRUE; + } diff --git a/debian/patches/gvariant-security-1-03.patch b/debian/patches/gvariant-security-1-03.patch new file mode 100644 index 0000000..55a459d --- /dev/null +++ b/debian/patches/gvariant-security-1-03.patch @@ -0,0 +1,87 @@ +From 5c27f22aff636766fbc5e49927fd28213629e840 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 25 Oct 2022 18:05:52 +0100 +Subject: [PATCH 03/18] gvariant: Zero-initialise various GVariantSerialised + objects + +The following few commits will add a couple of new fields to +`GVariantSerialised`, and they should be zero-filled by default. + +Try and pre-empt that a bit by zero-filling `GVariantSerialised` by +default in a few places. + +Signed-off-by: Philip Withnall + +Helps: #2121 +--- + glib/gvariant.c | 2 +- + glib/tests/gvariant.c | 12 ++++++------ + 2 files changed, 7 insertions(+), 7 deletions(-) + +--- a/glib/gvariant.c ++++ b/glib/gvariant.c +@@ -5988,7 +5988,7 @@ g_variant_byteswap (GVariant *value) + if (alignment) + /* (potentially) contains multi-byte numeric data */ + { +- GVariantSerialised serialised; ++ GVariantSerialised serialised = { 0, }; + GVariant *trusted; + GBytes *bytes; + +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -1438,7 +1438,7 @@ test_maybe (void) + + for (flavour = 0; flavour < 8; flavour += alignment) + { +- GVariantSerialised serialised; ++ GVariantSerialised serialised = { 0, }; + GVariantSerialised child; + + serialised.type_info = type_info; +@@ -1562,7 +1562,7 @@ test_array (void) + + for (flavour = 0; flavour < 8; flavour += alignment) + { +- GVariantSerialised serialised; ++ GVariantSerialised serialised = { 0, }; + + serialised.type_info = array_info; + serialised.data = flavoured_malloc (needed_size, flavour); +@@ -1726,7 +1726,7 @@ test_tuple (void) + + for (flavour = 0; flavour < 8; flavour += alignment) + { +- GVariantSerialised serialised; ++ GVariantSerialised serialised = { 0, }; + + serialised.type_info = type_info; + serialised.data = flavoured_malloc (needed_size, flavour); +@@ -1821,7 +1821,7 @@ test_variant (void) + + for (flavour = 0; flavour < 8; flavour += alignment) + { +- GVariantSerialised serialised; ++ GVariantSerialised serialised = { 0, }; + GVariantSerialised child; + + serialised.type_info = type_info; +@@ -2268,7 +2268,7 @@ serialise_tree (TreeInstance *tree + static void + test_byteswap (void) + { +- GVariantSerialised one, two; ++ GVariantSerialised one = { 0, }, two = { 0, }; + TreeInstance *tree; + + tree = tree_instance_new (NULL, 3); +@@ -2342,7 +2342,7 @@ test_serialiser_children (void) + static void + test_fuzz (gdouble *fuzziness) + { +- GVariantSerialised serialised; ++ GVariantSerialised serialised = { 0, }; + TreeInstance *tree; + + /* make an instance */ diff --git a/debian/patches/gvariant-security-1-04.patch b/debian/patches/gvariant-security-1-04.patch new file mode 100644 index 0000000..3c1b85b --- /dev/null +++ b/debian/patches/gvariant-security-1-04.patch @@ -0,0 +1,406 @@ +From c8067857f7c8fb369ecb30bb534b018b2e2b8f87 Mon Sep 17 00:00:00 2001 +From: William Manley +Date: Mon, 29 Jun 2020 16:59:44 +0100 +Subject: [PATCH 04/18] =?UTF-8?q?gvariant:=20Don=E2=80=99t=20allow=20child?= + =?UTF-8?q?=20elements=20to=20overlap=20with=20each=20other?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If different elements of a variable sized array can overlap with each +other then we can cause a `GVariant` to normalise to a much larger type. + +This commit changes the behaviour of `GVariant` with non-normal form data. If +an invalid frame offset is found all subsequent elements are given their +default value. + +When retrieving an element at index `n` we scan the frame offsets up to index +`n` and if they are not in order we return an element with the default value +for that type. This guarantees that elements don't overlap with each +other. We remember the offset we've scanned up to so we don't need to +repeat this work on subsequent accesses. We skip these checks for trusted +data. + +Unfortunately this makes random access of untrusted data O(n) — at least +on first access. It doesn't affect the algorithmic complexity of accessing +elements in order, such as when using the `GVariantIter` interface. Also: +the cost of validation will be amortised as the `GVariant` instance is +continued to be used. + +I've implemented this with 4 different functions, 1 for each element size, +rather than looping calling `gvs_read_unaligned_le` in the hope that the +compiler will find it easy to optimise and should produce fairly tight +code. + +Fixes: #2121 +--- + glib/gvariant-core.c | 35 ++++++++++++++++ + glib/gvariant-serialiser.c | 86 ++++++++++++++++++++++++++++++++++++-- + glib/gvariant-serialiser.h | 9 ++++ + glib/tests/gvariant.c | 45 ++++++++++++++++++++ + 4 files changed, 172 insertions(+), 3 deletions(-) + +--- a/glib/gvariant-core.c ++++ b/glib/gvariant-core.c +@@ -65,6 +65,7 @@ struct _GVariant + { + GBytes *bytes; + gconstpointer data; ++ gsize ordered_offsets_up_to; + } serialised; + + struct +@@ -162,6 +163,24 @@ struct _GVariant + * if .data pointed to the appropriate number of nul + * bytes. + * ++ * .ordered_offsets_up_to: If ordered_offsets_up_to == n this means that all ++ * the frame offsets up to and including the frame ++ * offset determining the end of element n are in ++ * order. This guarantees that the bytes of element ++ * n don't overlap with any previous element. ++ * ++ * For trusted data this is set to G_MAXSIZE and we ++ * don't check that the frame offsets are in order. ++ * ++ * Note: This doesn't imply the offsets are good in ++ * any way apart from their ordering. In particular ++ * offsets may be out of bounds for this value or ++ * may imply that the data overlaps the frame ++ * offsets themselves. ++ * ++ * This field is only relevant for arrays of non ++ * fixed width types. ++ * + * .tree: Only valid when the instance is in tree form. + * + * Note that accesses from other threads could result in +@@ -365,6 +384,7 @@ g_variant_to_serialised (GVariant *value + (gpointer) value->contents.serialised.data, + value->size, + value->depth, ++ value->contents.serialised.ordered_offsets_up_to, + }; + return serialised; + } +@@ -396,6 +416,7 @@ g_variant_serialise (GVariant *value, + serialised.size = value->size; + serialised.data = data; + serialised.depth = value->depth; ++ serialised.ordered_offsets_up_to = 0; + + children = (gpointer *) value->contents.tree.children; + n_children = value->contents.tree.n_children; +@@ -439,6 +460,15 @@ g_variant_fill_gvs (GVariantSerialised * + g_assert (serialised->size == value->size); + serialised->depth = value->depth; + ++ if (value->state & STATE_SERIALISED) ++ { ++ serialised->ordered_offsets_up_to = value->contents.serialised.ordered_offsets_up_to; ++ } ++ else ++ { ++ serialised->ordered_offsets_up_to = 0; ++ } ++ + if (serialised->data) + /* g_variant_store() is a public API, so it + * it will reacquire the lock if it needs to. +@@ -481,6 +511,7 @@ g_variant_ensure_serialised (GVariant *v + bytes = g_bytes_new_take (data, value->size); + value->contents.serialised.data = g_bytes_get_data (bytes, NULL); + value->contents.serialised.bytes = bytes; ++ value->contents.serialised.ordered_offsets_up_to = G_MAXSIZE; + value->state |= STATE_SERIALISED; + } + } +@@ -561,6 +592,7 @@ g_variant_new_from_bytes (const GVariant + serialised.type_info = value->type_info; + serialised.data = (guchar *) g_bytes_get_data (bytes, &serialised.size); + serialised.depth = 0; ++ serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0; + + if (!g_variant_serialised_check (serialised)) + { +@@ -611,6 +643,8 @@ g_variant_new_from_bytes (const GVariant + value->contents.serialised.data = g_bytes_get_data (bytes, &value->size); + } + ++ value->contents.serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0; ++ + g_clear_pointer (&owned_bytes, g_bytes_unref); + + return value; +@@ -1130,6 +1164,7 @@ g_variant_get_child_value (GVariant *val + child->contents.serialised.bytes = + g_bytes_ref (value->contents.serialised.bytes); + child->contents.serialised.data = s_child.data; ++ child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to; + + return child; + } +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -1,6 +1,7 @@ + /* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited ++ * Copyright © 2020 William Manley + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -264,6 +265,7 @@ gvs_fixed_sized_maybe_get_child (GVarian + value.type_info = g_variant_type_info_element (value.type_info); + g_variant_type_info_ref (value.type_info); + value.depth++; ++ value.ordered_offsets_up_to = 0; + + return value; + } +@@ -295,7 +297,7 @@ gvs_fixed_sized_maybe_serialise (GVarian + { + if (n_children) + { +- GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1 }; ++ GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0 }; + + gvs_filler (&child, children[0]); + } +@@ -317,6 +319,7 @@ gvs_fixed_sized_maybe_is_normal (GVarian + /* proper element size: "Just". recurse to the child. */ + value.type_info = g_variant_type_info_element (value.type_info); + value.depth++; ++ value.ordered_offsets_up_to = 0; + + return g_variant_serialised_is_normal (value); + } +@@ -358,6 +361,7 @@ gvs_variable_sized_maybe_get_child (GVar + value.data = NULL; + + value.depth++; ++ value.ordered_offsets_up_to = 0; + + return value; + } +@@ -388,7 +392,7 @@ gvs_variable_sized_maybe_serialise (GVar + { + if (n_children) + { +- GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1 }; ++ GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0 }; + + /* write the data for the child. */ + gvs_filler (&child, children[0]); +@@ -408,6 +412,7 @@ gvs_variable_sized_maybe_is_normal (GVar + value.type_info = g_variant_type_info_element (value.type_info); + value.size--; + value.depth++; ++ value.ordered_offsets_up_to = 0; + + return g_variant_serialised_is_normal (value); + } +@@ -691,6 +696,32 @@ gvs_variable_sized_array_n_children (GVa + return gvs_variable_sized_array_get_frame_offsets (value).length; + } + ++/* Find the index of the first out-of-order element in @data, assuming that ++ * @data is an array of elements of given @type, starting at index @start and ++ * containing a further @len-@start elements. */ ++#define DEFINE_FIND_UNORDERED(type) \ ++ static gsize \ ++ find_unordered_##type (const guint8 *data, gsize start, gsize len) \ ++ { \ ++ gsize off; \ ++ type current, previous; \ ++ \ ++ memcpy (&previous, data + start * sizeof (current), sizeof (current)); \ ++ for (off = (start + 1) * sizeof (current); off < len * sizeof (current); off += sizeof (current)) \ ++ { \ ++ memcpy (¤t, data + off, sizeof (current)); \ ++ if (current < previous) \ ++ break; \ ++ previous = current; \ ++ } \ ++ return off / sizeof (current) - 1; \ ++ } ++ ++DEFINE_FIND_UNORDERED (guint8); ++DEFINE_FIND_UNORDERED (guint16); ++DEFINE_FIND_UNORDERED (guint32); ++DEFINE_FIND_UNORDERED (guint64); ++ + static GVariantSerialised + gvs_variable_sized_array_get_child (GVariantSerialised value, + gsize index_) +@@ -706,6 +737,49 @@ gvs_variable_sized_array_get_child (GVar + g_variant_type_info_ref (child.type_info); + child.depth = value.depth + 1; + ++ /* If the requested @index_ is beyond the set of indices whose framing offsets ++ * have been checked, check the remaining offsets to see whether they’re ++ * normal (in order, no overlapping array elements). */ ++ if (index_ > value.ordered_offsets_up_to) ++ { ++ switch (offsets.offset_size) ++ { ++ case 1: ++ { ++ value.ordered_offsets_up_to = find_unordered_guint8 ( ++ offsets.array, value.ordered_offsets_up_to, index_ + 1); ++ break; ++ } ++ case 2: ++ { ++ value.ordered_offsets_up_to = find_unordered_guint16 ( ++ offsets.array, value.ordered_offsets_up_to, index_ + 1); ++ break; ++ } ++ case 4: ++ { ++ value.ordered_offsets_up_to = find_unordered_guint32 ( ++ offsets.array, value.ordered_offsets_up_to, index_ + 1); ++ break; ++ } ++ case 8: ++ { ++ value.ordered_offsets_up_to = find_unordered_guint64 ( ++ offsets.array, value.ordered_offsets_up_to, index_ + 1); ++ break; ++ } ++ default: ++ /* gvs_get_offset_size() only returns maximum 8 */ ++ g_assert_not_reached (); ++ } ++ } ++ ++ if (index_ > value.ordered_offsets_up_to) ++ { ++ /* Offsets are invalid somewhere, so return an empty child. */ ++ return child; ++ } ++ + if (index_ > 0) + { + guint alignment; +@@ -840,6 +914,9 @@ gvs_variable_sized_array_is_normal (GVar + + g_assert (offset == offsets.data_size); + ++ /* All offsets have now been checked. */ ++ value.ordered_offsets_up_to = G_MAXSIZE; ++ + return TRUE; + } + +@@ -1072,7 +1149,7 @@ gvs_tuple_is_normal (GVariantSerialised + for (i = 0; i < length; i++) + { + const GVariantMemberInfo *member_info; +- GVariantSerialised child; ++ GVariantSerialised child = { 0, }; + gsize fixed_size; + guint alignment; + gsize end; +@@ -1132,6 +1209,9 @@ gvs_tuple_is_normal (GVariantSerialised + offset = end; + } + ++ /* All element bounds have been checked above. */ ++ value.ordered_offsets_up_to = G_MAXSIZE; ++ + { + gsize fixed_size; + guint alignment; +--- a/glib/gvariant-serialiser.h ++++ b/glib/gvariant-serialiser.h +@@ -29,6 +29,15 @@ typedef struct + guchar *data; + gsize size; + gsize depth; /* same semantics as GVariant.depth */ ++ ++ /* If ordered_offsets_up_to == n this means that all the frame offsets up to and ++ * including the frame offset determining the end of element n are in order. ++ * This guarantees that the bytes of element n don't overlap with any previous ++ * element. ++ * ++ * This is both read and set by g_variant_serialised_get_child for arrays of ++ * non-fixed-width types */ ++ gsize ordered_offsets_up_to; + } GVariantSerialised; + + /* deserialization */ +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -1,5 +1,6 @@ + /* + * Copyright © 2010 Codethink Limited ++ * Copyright © 2020 William Manley + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -1279,6 +1280,7 @@ random_instance_filler (GVariantSerialis + serialised->size = instance->size; + + serialised->depth = 0; ++ serialised->ordered_offsets_up_to = 0; + + g_assert_true (serialised->type_info == instance->type_info); + g_assert_cmpuint (serialised->size, ==, instance->size); +@@ -5031,6 +5033,47 @@ test_normal_checking_array_offsets (void + g_variant_unref (variant); + } + ++/* This is a regression test that we can't have non-normal values that take up ++ * significantly more space than the normal equivalent, by specifying the ++ * offset table entries so that array elements overlap. ++ * ++ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_832242 */ ++static void ++test_normal_checking_array_offsets2 (void) ++{ ++ const guint8 data[] = { ++ 'h', 'i', '\0', ++ 0x03, 0x00, 0x03, ++ 0x06, 0x00, 0x06, ++ 0x09, 0x00, 0x09, ++ 0x0c, 0x00, 0x0c, ++ 0x0f, 0x00, 0x0f, ++ 0x12, 0x00, 0x12, ++ 0x15, 0x00, 0x15, ++ }; ++ gsize size = sizeof (data); ++ const GVariantType *aaaaaaas = G_VARIANT_TYPE ("aaaaaaas"); ++ GVariant *variant = NULL; ++ GVariant *normal_variant = NULL; ++ GVariant *expected = NULL; ++ ++ variant = g_variant_new_from_data (aaaaaaas, data, size, FALSE, NULL, NULL); ++ g_assert_nonnull (variant); ++ ++ normal_variant = g_variant_get_normal_form (variant); ++ g_assert_nonnull (normal_variant); ++ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 2); ++ ++ expected = g_variant_new_parsed ( ++ "[[[[[[['hi', '', ''], [], []], [], []], [], []], [], []], [], []], [], []]"); ++ g_assert_cmpvariant (expected, variant); ++ g_assert_cmpvariant (expected, normal_variant); ++ ++ g_variant_unref (expected); ++ g_variant_unref (normal_variant); ++ g_variant_unref (variant); ++} ++ + /* Test that a tuple with invalidly large values in its offset table is + * normalised successfully without looping infinitely. */ + static void +@@ -5197,6 +5240,8 @@ main (int argc, char **argv) + test_normal_checking_tuples); + g_test_add_func ("/gvariant/normal-checking/array-offsets", + test_normal_checking_array_offsets); ++ g_test_add_func ("/gvariant/normal-checking/array-offsets2", ++ test_normal_checking_array_offsets2); + g_test_add_func ("/gvariant/normal-checking/tuple-offsets", + test_normal_checking_tuple_offsets); + g_test_add_func ("/gvariant/normal-checking/empty-object-path", diff --git a/debian/patches/gvariant-security-1-05.patch b/debian/patches/gvariant-security-1-05.patch new file mode 100644 index 0000000..c4666ca --- /dev/null +++ b/debian/patches/gvariant-security-1-05.patch @@ -0,0 +1,104 @@ +From 66e7c10aa1ec3102c49186f83671a5f0461ffbc0 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Fri, 7 Jan 2022 15:03:52 +0000 +Subject: [PATCH 05/18] gvariant-serialiser: Factor out code to get bounds of a + tuple member + +This introduces no functional changes. + +Signed-off-by: Philip Withnall + +Helps: #2121 +--- + glib/gvariant-serialiser.c | 73 ++++++++++++++++++++++++-------------- + 1 file changed, 46 insertions(+), 27 deletions(-) + +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -942,6 +942,51 @@ gvs_variable_sized_array_is_normal (GVar + * for the tuple. See the notes in gvarianttypeinfo.h. + */ + ++static void ++gvs_tuple_get_member_bounds (GVariantSerialised value, ++ gsize index_, ++ gsize offset_size, ++ gsize *out_member_start, ++ gsize *out_member_end) ++{ ++ const GVariantMemberInfo *member_info; ++ gsize member_start, member_end; ++ ++ member_info = g_variant_type_info_member_info (value.type_info, index_); ++ ++ if (member_info->i + 1) ++ member_start = gvs_read_unaligned_le (value.data + value.size - ++ offset_size * (member_info->i + 1), ++ offset_size); ++ else ++ member_start = 0; ++ ++ member_start += member_info->a; ++ member_start &= member_info->b; ++ member_start |= member_info->c; ++ ++ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST) ++ member_end = value.size - offset_size * (member_info->i + 1); ++ ++ else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) ++ { ++ gsize fixed_size; ++ ++ g_variant_type_info_query (member_info->type_info, NULL, &fixed_size); ++ member_end = member_start + fixed_size; ++ } ++ ++ else /* G_VARIANT_MEMBER_ENDING_OFFSET */ ++ member_end = gvs_read_unaligned_le (value.data + value.size - ++ offset_size * (member_info->i + 2), ++ offset_size); ++ ++ if (out_member_start != NULL) ++ *out_member_start = member_start; ++ if (out_member_end != NULL) ++ *out_member_end = member_end; ++} ++ + static gsize + gvs_tuple_n_children (GVariantSerialised value) + { +@@ -997,33 +1042,7 @@ gvs_tuple_get_child (GVariantSerialised + } + } + +- if (member_info->i + 1) +- start = gvs_read_unaligned_le (value.data + value.size - +- offset_size * (member_info->i + 1), +- offset_size); +- else +- start = 0; +- +- start += member_info->a; +- start &= member_info->b; +- start |= member_info->c; +- +- if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST) +- end = value.size - offset_size * (member_info->i + 1); +- +- else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) +- { +- gsize fixed_size; +- +- g_variant_type_info_query (child.type_info, NULL, &fixed_size); +- end = start + fixed_size; +- child.size = fixed_size; +- } +- +- else /* G_VARIANT_MEMBER_ENDING_OFFSET */ +- end = gvs_read_unaligned_le (value.data + value.size - +- offset_size * (member_info->i + 2), +- offset_size); ++ gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end); + + /* The child should not extend into the offset table. */ + if (index_ != g_variant_type_info_n_members (value.type_info) - 1) diff --git a/debian/patches/gvariant-security-1-06.patch b/debian/patches/gvariant-security-1-06.patch new file mode 100644 index 0000000..0c18fa7 --- /dev/null +++ b/debian/patches/gvariant-security-1-06.patch @@ -0,0 +1,74 @@ +From a62a6b5d3e53b30a4628db2a077ab9ed03605748 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Fri, 7 Jan 2022 16:37:29 +0000 +Subject: [PATCH 06/18] gvariant-serialiser: Rework child size calculation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reduces a few duplicate calls to `g_variant_type_info_query()` and +explains why they’re needed. + +Signed-off-by: Philip Withnall + +Helps: #2121 +--- + glib/gvariant-serialiser.c | 31 +++++++++---------------------- + 1 file changed, 9 insertions(+), 22 deletions(-) + +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -1007,14 +1007,18 @@ gvs_tuple_get_child (GVariantSerialised + child.depth = value.depth + 1; + offset_size = gvs_get_offset_size (value.size); + ++ /* Ensure the size is set for fixed-sized children, or ++ * g_variant_serialised_check() will fail, even if we return ++ * (child.data == NULL) to indicate an error. */ ++ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) ++ g_variant_type_info_query (child.type_info, NULL, &child.size); ++ + /* tuples are the only (potentially) fixed-sized containers, so the + * only ones that have to deal with the possibility of having %NULL + * data with a non-zero %size if errors occurred elsewhere. + */ + if G_UNLIKELY (value.data == NULL && value.size != 0) + { +- g_variant_type_info_query (child.type_info, NULL, &child.size); +- + /* this can only happen in fixed-sized tuples, + * so the child must also be fixed sized. + */ +@@ -1032,29 +1036,12 @@ gvs_tuple_get_child (GVariantSerialised + else + { + if (offset_size * (member_info->i + 1) > value.size) +- { +- /* if the child is fixed size, return its size. +- * if child is not fixed-sized, return size = 0. +- */ +- g_variant_type_info_query (child.type_info, NULL, &child.size); +- +- return child; +- } ++ return child; + } + +- gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end); +- + /* The child should not extend into the offset table. */ +- if (index_ != g_variant_type_info_n_members (value.type_info) - 1) +- { +- GVariantSerialised last_child; +- last_child = gvs_tuple_get_child (value, +- g_variant_type_info_n_members (value.type_info) - 1); +- last_end = last_child.data + last_child.size - value.data; +- g_variant_type_info_unref (last_child.type_info); +- } +- else +- last_end = end; ++ gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end); ++ gvs_tuple_get_member_bounds (value, g_variant_type_info_n_members (value.type_info) - 1, offset_size, NULL, &last_end); + + if (start < end && end <= value.size && end <= last_end) + { diff --git a/debian/patches/gvariant-security-1-07.patch b/debian/patches/gvariant-security-1-07.patch new file mode 100644 index 0000000..cd23fbf --- /dev/null +++ b/debian/patches/gvariant-security-1-07.patch @@ -0,0 +1,382 @@ +From 2d55b3b74b1bc256e91a9d0d59120570376e6acc Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Fri, 7 Jan 2022 16:42:14 +0000 +Subject: [PATCH 07/18] =?UTF-8?q?gvariant:=20Don=E2=80=99t=20allow=20child?= + =?UTF-8?q?=20elements=20of=20a=20tuple=20to=20overlap=20each=20other?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is similar to the earlier commit which prevents child elements of a +variable-sized array from overlapping each other, but this time for +tuples. It is based heavily on ideas by William Manley. + +Tuples are slightly different from variable-sized arrays in that they +contain a mixture of fixed and variable sized elements. All but one of +the variable sized elements have an entry in the frame offsets table. +This means that if we were to just check the ordering of the frame +offsets table, the variable sized elements could still overlap +interleaving fixed sized elements, which would be bad. + +Therefore we have to check the elements rather than the frame offsets. + +The logic of checking the elements up to the index currently being +requested, and caching the result in `ordered_offsets_up_to`, means that +the algorithmic cost implications are the same for this commit as for +variable-sized arrays: an O(N) cost for these checks is amortised out +over N accesses to O(1) per access. + +Signed-off-by: Philip Withnall + +Fixes: #2121 +--- + glib/gvariant-core.c | 6 +- + glib/gvariant-serialiser.c | 40 ++++++++ + glib/gvariant-serialiser.h | 7 +- + glib/gvariant.c | 1 + + glib/tests/gvariant.c | 181 +++++++++++++++++++++++++++++++++++++ + 5 files changed, 232 insertions(+), 3 deletions(-) + +--- a/glib/gvariant-core.c ++++ b/glib/gvariant-core.c +@@ -1,6 +1,7 @@ + /* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited ++ * Copyright © 2022 Endless OS Foundation, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -179,7 +180,7 @@ struct _GVariant + * offsets themselves. + * + * This field is only relevant for arrays of non +- * fixed width types. ++ * fixed width types and for tuples. + * + * .tree: Only valid when the instance is in tree form. + * +@@ -1139,6 +1140,9 @@ g_variant_get_child_value (GVariant *val + */ + s_child = g_variant_serialised_get_child (serialised, index_); + ++ /* Update the cached ordered_offsets_up_to, since @serialised will be thrown away when this function exits */ ++ value->contents.serialised.ordered_offsets_up_to = MAX (value->contents.serialised.ordered_offsets_up_to, serialised.ordered_offsets_up_to); ++ + /* Check whether this would cause nesting too deep. If so, return a fake + * child. The only situation we expect this to happen in is with a variant, + * as all other deeply-nested types have a static type, and hence should +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -942,6 +942,10 @@ gvs_variable_sized_array_is_normal (GVar + * for the tuple. See the notes in gvarianttypeinfo.h. + */ + ++/* Note: This doesn’t guarantee that @out_member_end >= @out_member_start; that ++ * condition may not hold true for invalid serialised variants. The caller is ++ * responsible for checking the returned values and handling invalid ones ++ * appropriately. */ + static void + gvs_tuple_get_member_bounds (GVariantSerialised value, + gsize index_, +@@ -1028,6 +1032,42 @@ gvs_tuple_get_child (GVariantSerialised + return child; + } + ++ /* If the requested @index_ is beyond the set of indices whose framing offsets ++ * have been checked, check the remaining offsets to see whether they’re ++ * normal (in order, no overlapping tuple elements). ++ * ++ * Unlike the checks in gvs_variable_sized_array_get_child(), we have to check ++ * all the tuple *elements* here, not just all the framing offsets, since ++ * tuples contain a mix of elements which use framing offsets and ones which ++ * don’t. None of them are allowed to overlap. */ ++ if (index_ > value.ordered_offsets_up_to) ++ { ++ gsize i, prev_i_end = 0; ++ ++ if (value.ordered_offsets_up_to > 0) ++ gvs_tuple_get_member_bounds (value, value.ordered_offsets_up_to - 1, offset_size, NULL, &prev_i_end); ++ ++ for (i = value.ordered_offsets_up_to; i <= index_; i++) ++ { ++ gsize i_start, i_end; ++ ++ gvs_tuple_get_member_bounds (value, i, offset_size, &i_start, &i_end); ++ ++ if (i_start > i_end || i_start < prev_i_end || i_end > value.size) ++ break; ++ ++ prev_i_end = i_end; ++ } ++ ++ value.ordered_offsets_up_to = i - 1; ++ } ++ ++ if (index_ > value.ordered_offsets_up_to) ++ { ++ /* Offsets are invalid somewhere, so return an empty child. */ ++ return child; ++ } ++ + if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET) + { + if (offset_size * (member_info->i + 2) > value.size) +--- a/glib/gvariant-serialiser.h ++++ b/glib/gvariant-serialiser.h +@@ -35,8 +35,11 @@ typedef struct + * This guarantees that the bytes of element n don't overlap with any previous + * element. + * +- * This is both read and set by g_variant_serialised_get_child for arrays of +- * non-fixed-width types */ ++ * This is both read and set by g_variant_serialised_get_child() for arrays of ++ * non-fixed-width types, and for tuples. ++ * ++ * Even when dealing with tuples, @ordered_offsets_up_to is an element index, ++ * rather than an index into the frame offsets. */ + gsize ordered_offsets_up_to; + } GVariantSerialised; + +--- a/glib/gvariant.c ++++ b/glib/gvariant.c +@@ -5997,6 +5997,7 @@ g_variant_byteswap (GVariant *value) + serialised.size = g_variant_get_size (trusted); + serialised.data = g_malloc (serialised.size); + serialised.depth = g_variant_get_depth (trusted); ++ serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */ + g_variant_store (trusted, serialised.data); + g_variant_unref (trusted); + +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -1,6 +1,7 @@ + /* + * Copyright © 2010 Codethink Limited + * Copyright © 2020 William Manley ++ * Copyright © 2022 Endless OS Foundation, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -1447,6 +1448,7 @@ test_maybe (void) + serialised.data = flavoured_malloc (needed_size, flavour); + serialised.size = needed_size; + serialised.depth = 0; ++ serialised.ordered_offsets_up_to = 0; + + g_variant_serialiser_serialise (serialised, + random_instance_filler, +@@ -1570,6 +1572,7 @@ test_array (void) + serialised.data = flavoured_malloc (needed_size, flavour); + serialised.size = needed_size; + serialised.depth = 0; ++ serialised.ordered_offsets_up_to = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) instances, n_children); +@@ -1734,6 +1737,7 @@ test_tuple (void) + serialised.data = flavoured_malloc (needed_size, flavour); + serialised.size = needed_size; + serialised.depth = 0; ++ serialised.ordered_offsets_up_to = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) instances, n_children); +@@ -1830,6 +1834,7 @@ test_variant (void) + serialised.data = flavoured_malloc (needed_size, flavour); + serialised.size = needed_size; + serialised.depth = 0; ++ serialised.ordered_offsets_up_to = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) &instance, 1); +@@ -5098,6 +5103,176 @@ test_normal_checking_tuple_offsets (void + g_variant_unref (variant); + } + ++/* This is a regression test that we can't have non-normal values that take up ++ * significantly more space than the normal equivalent, by specifying the ++ * offset table entries so that tuple elements overlap. ++ * ++ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_838503 and ++ * https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_838513 */ ++static void ++test_normal_checking_tuple_offsets2 (void) ++{ ++ const GVariantType *data_type = G_VARIANT_TYPE ("(yyaiyyaiyy)"); ++ const guint8 data[] = { ++ 0x12, 0x34, 0x56, 0x78, 0x01, ++ /* ++ ^───────────────────┘ ++ ++ ^^^^^^^^^^ 1st yy ++ ^^^^^^^^^^ 2nd yy ++ ^^^^^^^^^^ 3rd yy ++ ^^^^ Framing offsets ++ */ ++ ++ /* If this variant was encoded normally, it would be something like this: ++ * 0x12, 0x34, pad, pad, [array bytes], 0x56, 0x78, pad, pad, [array bytes], 0x9A, 0xBC, 0xXX ++ * ^─────────────────────────────────────────────────────┘ ++ * ++ * ^^^^^^^^^^ 1st yy ++ * ^^^^^^^^^^ 2nd yy ++ * ^^^^^^^^^^ 3rd yy ++ * ^^^^ Framing offsets ++ */ ++ }; ++ gsize size = sizeof (data); ++ GVariant *variant = NULL; ++ GVariant *normal_variant = NULL; ++ GVariant *expected = NULL; ++ ++ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); ++ g_assert_nonnull (variant); ++ ++ normal_variant = g_variant_get_normal_form (variant); ++ g_assert_nonnull (normal_variant); ++ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3); ++ ++ expected = g_variant_new_parsed ( ++ "@(yyaiyyaiyy) (0x12, 0x34, [], 0x00, 0x00, [], 0x00, 0x00)"); ++ g_assert_cmpvariant (expected, variant); ++ g_assert_cmpvariant (expected, normal_variant); ++ ++ g_variant_unref (expected); ++ g_variant_unref (normal_variant); ++ g_variant_unref (variant); ++} ++ ++/* This is a regression test that overlapping entries in the offset table are ++ * decoded consistently, even though they’re non-normal. ++ * ++ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_910935 */ ++static void ++test_normal_checking_tuple_offsets3 (void) ++{ ++ /* The expected decoding of this non-normal byte stream is complex. See ++ * section 2.7.3 (Handling Non-Normal Serialised Data) of the GVariant ++ * specification. ++ * ++ * The rule “Child Values Overlapping Framing Offsets†from the specification ++ * says that the first `ay` must be decoded as `[0x01]` even though it ++ * overlaps the first byte of the offset table. However, since commit ++ * 7eedcd76f7d5b8c98fa60013e1fe6e960bf19df3, GLib explicitly doesn’t allow ++ * this as it’s exploitable. So the first `ay` must be given a default value. ++ * ++ * The second and third `ay`s must be given default values because of rule ++ * “End Boundary Precedes Start Boundaryâ€. ++ * ++ * The `i` must be given a default value because of rule “Start or End ++ * Boundary of a Child Falls Outside the Containerâ€. ++ */ ++ const GVariantType *data_type = G_VARIANT_TYPE ("(ayayiay)"); ++ const guint8 data[] = { ++ 0x01, 0x00, 0x02, ++ /* ++ ^──┘ ++ ++ ^^^^^^^^^^ 1st ay, bytes 0-2 (but given a default value anyway, see above) ++ 2nd ay, bytes 2-0 ++ i, bytes 0-4 ++ 3rd ay, bytes 4-1 ++ ^^^^^^^^^^ Framing offsets ++ */ ++ }; ++ gsize size = sizeof (data); ++ GVariant *variant = NULL; ++ GVariant *normal_variant = NULL; ++ GVariant *expected = NULL; ++ ++ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); ++ g_assert_nonnull (variant); ++ ++ g_assert_false (g_variant_is_normal_form (variant)); ++ ++ normal_variant = g_variant_get_normal_form (variant); ++ g_assert_nonnull (normal_variant); ++ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3); ++ ++ expected = g_variant_new_parsed ("@(ayayiay) ([], [], 0, [])"); ++ g_assert_cmpvariant (expected, variant); ++ g_assert_cmpvariant (expected, normal_variant); ++ ++ g_variant_unref (expected); ++ g_variant_unref (normal_variant); ++ g_variant_unref (variant); ++} ++ ++/* This is a regression test that overlapping entries in the offset table are ++ * decoded consistently, even though they’re non-normal. ++ * ++ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_910935 */ ++static void ++test_normal_checking_tuple_offsets4 (void) ++{ ++ /* The expected decoding of this non-normal byte stream is complex. See ++ * section 2.7.3 (Handling Non-Normal Serialised Data) of the GVariant ++ * specification. ++ * ++ * The rule “Child Values Overlapping Framing Offsets†from the specification ++ * says that the first `ay` must be decoded as `[0x01]` even though it ++ * overlaps the first byte of the offset table. However, since commit ++ * 7eedcd76f7d5b8c98fa60013e1fe6e960bf19df3, GLib explicitly doesn’t allow ++ * this as it’s exploitable. So the first `ay` must be given a default value. ++ * ++ * The second `ay` must be given a default value because of rule “End Boundary ++ * Precedes Start Boundaryâ€. ++ * ++ * The third `ay` must be given a default value because its framing offsets ++ * overlap that of the first `ay`. ++ */ ++ const GVariantType *data_type = G_VARIANT_TYPE ("(ayayay)"); ++ const guint8 data[] = { ++ 0x01, 0x00, 0x02, ++ /* ++ ^──┘ ++ ++ ^^^^^^^^^^ 1st ay, bytes 0-2 (but given a default value anyway, see above) ++ 2nd ay, bytes 2-0 ++ 3rd ay, bytes 0-1 ++ ^^^^^^^^^^ Framing offsets ++ */ ++ }; ++ gsize size = sizeof (data); ++ GVariant *variant = NULL; ++ GVariant *normal_variant = NULL; ++ GVariant *expected = NULL; ++ ++ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); ++ g_assert_nonnull (variant); ++ ++ g_assert_false (g_variant_is_normal_form (variant)); ++ ++ normal_variant = g_variant_get_normal_form (variant); ++ g_assert_nonnull (normal_variant); ++ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3); ++ ++ expected = g_variant_new_parsed ("@(ayayay) ([], [], [])"); ++ g_assert_cmpvariant (expected, variant); ++ g_assert_cmpvariant (expected, normal_variant); ++ ++ g_variant_unref (expected); ++ g_variant_unref (normal_variant); ++ g_variant_unref (variant); ++} ++ + /* Test that an empty object path is normalised successfully to the base object + * path, ‘/’. */ + static void +@@ -5244,6 +5419,12 @@ main (int argc, char **argv) + test_normal_checking_array_offsets2); + g_test_add_func ("/gvariant/normal-checking/tuple-offsets", + test_normal_checking_tuple_offsets); ++ g_test_add_func ("/gvariant/normal-checking/tuple-offsets2", ++ test_normal_checking_tuple_offsets2); ++ g_test_add_func ("/gvariant/normal-checking/tuple-offsets3", ++ test_normal_checking_tuple_offsets3); ++ g_test_add_func ("/gvariant/normal-checking/tuple-offsets4", ++ test_normal_checking_tuple_offsets4); + g_test_add_func ("/gvariant/normal-checking/empty-object-path", + test_normal_checking_empty_object_path); + diff --git a/debian/patches/gvariant-security-1-08.patch b/debian/patches/gvariant-security-1-08.patch new file mode 100644 index 0000000..21485f3 --- /dev/null +++ b/debian/patches/gvariant-security-1-08.patch @@ -0,0 +1,378 @@ +From a6cb880af0a0932493ba096f01990e694e2c5b72 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 25 Oct 2022 15:14:14 +0100 +Subject: [PATCH 08/18] gvariant: Track checked and ordered offsets + independently + +The past few commits introduced the concept of known-good offsets in the +offset table (which is used for variable-width arrays and tuples). +Good offsets are ones which are non-overlapping with all the previous +offsets in the table. + +If a bad offset is encountered when indexing into the array or tuple, +the cached known-good offset index will not be increased. In this way, +all child variants at and beyond the first bad offset can be returned as +default values rather than dereferencing potentially invalid data. + +In this case, there was no information about the fact that the indexes +between the highest known-good index and the requested one had been +checked already. That could lead to a pathological case where an offset +table with an invalid first offset is repeatedly checked in full when +trying to access higher-indexed children. + +Avoid that by storing the index of the highest checked offset in the +table, as well as the index of the highest good/ordered offset. + +Signed-off-by: Philip Withnall + +Helps: #2121 +--- + glib/gvariant-core.c | 28 ++++++++++++++++++++++++ + glib/gvariant-serialiser.c | 44 +++++++++++++++++++++++++++----------- + glib/gvariant-serialiser.h | 9 ++++++++ + glib/gvariant.c | 1 + + glib/tests/gvariant.c | 5 +++++ + 5 files changed, 75 insertions(+), 12 deletions(-) + +--- a/glib/gvariant-core.c ++++ b/glib/gvariant-core.c +@@ -67,6 +67,7 @@ struct _GVariant + GBytes *bytes; + gconstpointer data; + gsize ordered_offsets_up_to; ++ gsize checked_offsets_up_to; + } serialised; + + struct +@@ -182,6 +183,24 @@ struct _GVariant + * This field is only relevant for arrays of non + * fixed width types and for tuples. + * ++ * .checked_offsets_up_to: Similarly to .ordered_offsets_up_to, this stores ++ * the index of the highest element, n, whose frame ++ * offsets (and all the preceding frame offsets) ++ * have been checked for validity. ++ * ++ * It is always the case that ++ * .checked_offsets_up_to ≥ .ordered_offsets_up_to. ++ * ++ * If .checked_offsets_up_to == .ordered_offsets_up_to, ++ * then a bad offset has not been found so far. ++ * ++ * If .checked_offsets_up_to > .ordered_offsets_up_to, ++ * then a bad offset has been found at ++ * (.ordered_offsets_up_to + 1). ++ * ++ * This field is only relevant for arrays of non ++ * fixed width types and for tuples. ++ * + * .tree: Only valid when the instance is in tree form. + * + * Note that accesses from other threads could result in +@@ -386,6 +405,7 @@ g_variant_to_serialised (GVariant *value + value->size, + value->depth, + value->contents.serialised.ordered_offsets_up_to, ++ value->contents.serialised.checked_offsets_up_to, + }; + return serialised; + } +@@ -418,6 +438,7 @@ g_variant_serialise (GVariant *value, + serialised.data = data; + serialised.depth = value->depth; + serialised.ordered_offsets_up_to = 0; ++ serialised.checked_offsets_up_to = 0; + + children = (gpointer *) value->contents.tree.children; + n_children = value->contents.tree.n_children; +@@ -464,10 +485,12 @@ g_variant_fill_gvs (GVariantSerialised * + if (value->state & STATE_SERIALISED) + { + serialised->ordered_offsets_up_to = value->contents.serialised.ordered_offsets_up_to; ++ serialised->checked_offsets_up_to = value->contents.serialised.checked_offsets_up_to; + } + else + { + serialised->ordered_offsets_up_to = 0; ++ serialised->checked_offsets_up_to = 0; + } + + if (serialised->data) +@@ -513,6 +536,7 @@ g_variant_ensure_serialised (GVariant *v + value->contents.serialised.data = g_bytes_get_data (bytes, NULL); + value->contents.serialised.bytes = bytes; + value->contents.serialised.ordered_offsets_up_to = G_MAXSIZE; ++ value->contents.serialised.checked_offsets_up_to = G_MAXSIZE; + value->state |= STATE_SERIALISED; + } + } +@@ -594,6 +618,7 @@ g_variant_new_from_bytes (const GVariant + serialised.data = (guchar *) g_bytes_get_data (bytes, &serialised.size); + serialised.depth = 0; + serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0; ++ serialised.checked_offsets_up_to = trusted ? G_MAXSIZE : 0; + + if (!g_variant_serialised_check (serialised)) + { +@@ -645,6 +670,7 @@ g_variant_new_from_bytes (const GVariant + } + + value->contents.serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0; ++ value->contents.serialised.checked_offsets_up_to = trusted ? G_MAXSIZE : 0; + + g_clear_pointer (&owned_bytes, g_bytes_unref); + +@@ -1142,6 +1168,7 @@ g_variant_get_child_value (GVariant *val + + /* Update the cached ordered_offsets_up_to, since @serialised will be thrown away when this function exits */ + value->contents.serialised.ordered_offsets_up_to = MAX (value->contents.serialised.ordered_offsets_up_to, serialised.ordered_offsets_up_to); ++ value->contents.serialised.checked_offsets_up_to = MAX (value->contents.serialised.checked_offsets_up_to, serialised.checked_offsets_up_to); + + /* Check whether this would cause nesting too deep. If so, return a fake + * child. The only situation we expect this to happen in is with a variant, +@@ -1169,6 +1196,7 @@ g_variant_get_child_value (GVariant *val + g_bytes_ref (value->contents.serialised.bytes); + child->contents.serialised.data = s_child.data; + child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to; ++ child->contents.serialised.checked_offsets_up_to = s_child.checked_offsets_up_to; + + return child; + } +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -120,6 +120,8 @@ + * + * @depth has no restrictions; the depth of a top-level serialized #GVariant is + * zero, and it increases for each level of nested child. ++ * ++ * @checked_offsets_up_to is always ≥ @ordered_offsets_up_to + */ + + /* < private > +@@ -147,6 +149,9 @@ g_variant_serialised_check (GVariantSeri + !(serialised.size == 0 || serialised.data != NULL)) + return FALSE; + ++ if (serialised.ordered_offsets_up_to > serialised.checked_offsets_up_to) ++ return FALSE; ++ + /* Depending on the native alignment requirements of the machine, the + * compiler will insert either 3 or 7 padding bytes after the char. + * This will result in the sizeof() the struct being 12 or 16. +@@ -266,6 +271,7 @@ gvs_fixed_sized_maybe_get_child (GVarian + g_variant_type_info_ref (value.type_info); + value.depth++; + value.ordered_offsets_up_to = 0; ++ value.checked_offsets_up_to = 0; + + return value; + } +@@ -297,7 +303,7 @@ gvs_fixed_sized_maybe_serialise (GVarian + { + if (n_children) + { +- GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0 }; ++ GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0, 0 }; + + gvs_filler (&child, children[0]); + } +@@ -320,6 +326,7 @@ gvs_fixed_sized_maybe_is_normal (GVarian + value.type_info = g_variant_type_info_element (value.type_info); + value.depth++; + value.ordered_offsets_up_to = 0; ++ value.checked_offsets_up_to = 0; + + return g_variant_serialised_is_normal (value); + } +@@ -362,6 +369,7 @@ gvs_variable_sized_maybe_get_child (GVar + + value.depth++; + value.ordered_offsets_up_to = 0; ++ value.checked_offsets_up_to = 0; + + return value; + } +@@ -392,7 +400,7 @@ gvs_variable_sized_maybe_serialise (GVar + { + if (n_children) + { +- GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0 }; ++ GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0, 0 }; + + /* write the data for the child. */ + gvs_filler (&child, children[0]); +@@ -413,6 +421,7 @@ gvs_variable_sized_maybe_is_normal (GVar + value.size--; + value.depth++; + value.ordered_offsets_up_to = 0; ++ value.checked_offsets_up_to = 0; + + return g_variant_serialised_is_normal (value); + } +@@ -739,39 +748,46 @@ gvs_variable_sized_array_get_child (GVar + + /* If the requested @index_ is beyond the set of indices whose framing offsets + * have been checked, check the remaining offsets to see whether they’re +- * normal (in order, no overlapping array elements). */ +- if (index_ > value.ordered_offsets_up_to) ++ * normal (in order, no overlapping array elements). ++ * ++ * Don’t bother checking if the highest known-good offset is lower than the ++ * highest checked offset, as that means there’s an invalid element at that ++ * index, so there’s no need to check further. */ ++ if (index_ > value.checked_offsets_up_to && ++ value.ordered_offsets_up_to == value.checked_offsets_up_to) + { + switch (offsets.offset_size) + { + case 1: + { + value.ordered_offsets_up_to = find_unordered_guint8 ( +- offsets.array, value.ordered_offsets_up_to, index_ + 1); ++ offsets.array, value.checked_offsets_up_to, index_ + 1); + break; + } + case 2: + { + value.ordered_offsets_up_to = find_unordered_guint16 ( +- offsets.array, value.ordered_offsets_up_to, index_ + 1); ++ offsets.array, value.checked_offsets_up_to, index_ + 1); + break; + } + case 4: + { + value.ordered_offsets_up_to = find_unordered_guint32 ( +- offsets.array, value.ordered_offsets_up_to, index_ + 1); ++ offsets.array, value.checked_offsets_up_to, index_ + 1); + break; + } + case 8: + { + value.ordered_offsets_up_to = find_unordered_guint64 ( +- offsets.array, value.ordered_offsets_up_to, index_ + 1); ++ offsets.array, value.checked_offsets_up_to, index_ + 1); + break; + } + default: + /* gvs_get_offset_size() only returns maximum 8 */ + g_assert_not_reached (); + } ++ ++ value.checked_offsets_up_to = index_; + } + + if (index_ > value.ordered_offsets_up_to) +@@ -916,6 +932,7 @@ gvs_variable_sized_array_is_normal (GVar + + /* All offsets have now been checked. */ + value.ordered_offsets_up_to = G_MAXSIZE; ++ value.checked_offsets_up_to = G_MAXSIZE; + + return TRUE; + } +@@ -1040,14 +1057,15 @@ gvs_tuple_get_child (GVariantSerialised + * all the tuple *elements* here, not just all the framing offsets, since + * tuples contain a mix of elements which use framing offsets and ones which + * don’t. None of them are allowed to overlap. */ +- if (index_ > value.ordered_offsets_up_to) ++ if (index_ > value.checked_offsets_up_to && ++ value.ordered_offsets_up_to == value.checked_offsets_up_to) + { + gsize i, prev_i_end = 0; + +- if (value.ordered_offsets_up_to > 0) +- gvs_tuple_get_member_bounds (value, value.ordered_offsets_up_to - 1, offset_size, NULL, &prev_i_end); ++ if (value.checked_offsets_up_to > 0) ++ gvs_tuple_get_member_bounds (value, value.checked_offsets_up_to - 1, offset_size, NULL, &prev_i_end); + +- for (i = value.ordered_offsets_up_to; i <= index_; i++) ++ for (i = value.checked_offsets_up_to; i <= index_; i++) + { + gsize i_start, i_end; + +@@ -1060,6 +1078,7 @@ gvs_tuple_get_child (GVariantSerialised + } + + value.ordered_offsets_up_to = i - 1; ++ value.checked_offsets_up_to = index_; + } + + if (index_ > value.ordered_offsets_up_to) +@@ -1257,6 +1276,7 @@ gvs_tuple_is_normal (GVariantSerialised + + /* All element bounds have been checked above. */ + value.ordered_offsets_up_to = G_MAXSIZE; ++ value.checked_offsets_up_to = G_MAXSIZE; + + { + gsize fixed_size; +--- a/glib/gvariant-serialiser.h ++++ b/glib/gvariant-serialiser.h +@@ -41,6 +41,15 @@ typedef struct + * Even when dealing with tuples, @ordered_offsets_up_to is an element index, + * rather than an index into the frame offsets. */ + gsize ordered_offsets_up_to; ++ ++ /* Similar to @ordered_offsets_up_to. This gives the index of the child element ++ * whose frame offset is the highest in the offset table which has been ++ * checked so far. ++ * ++ * This is always ≥ @ordered_offsets_up_to. It is always an element index. ++ * ++ * See documentation in gvariant-core.c for `struct GVariant` for details. */ ++ gsize checked_offsets_up_to; + } GVariantSerialised; + + /* deserialization */ +--- a/glib/gvariant.c ++++ b/glib/gvariant.c +@@ -5998,6 +5998,7 @@ g_variant_byteswap (GVariant *value) + serialised.data = g_malloc (serialised.size); + serialised.depth = g_variant_get_depth (trusted); + serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */ ++ serialised.checked_offsets_up_to = G_MAXSIZE; + g_variant_store (trusted, serialised.data); + g_variant_unref (trusted); + +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -1282,6 +1282,7 @@ random_instance_filler (GVariantSerialis + + serialised->depth = 0; + serialised->ordered_offsets_up_to = 0; ++ serialised->checked_offsets_up_to = 0; + + g_assert_true (serialised->type_info == instance->type_info); + g_assert_cmpuint (serialised->size, ==, instance->size); +@@ -1449,6 +1450,7 @@ test_maybe (void) + serialised.size = needed_size; + serialised.depth = 0; + serialised.ordered_offsets_up_to = 0; ++ serialised.checked_offsets_up_to = 0; + + g_variant_serialiser_serialise (serialised, + random_instance_filler, +@@ -1573,6 +1575,7 @@ test_array (void) + serialised.size = needed_size; + serialised.depth = 0; + serialised.ordered_offsets_up_to = 0; ++ serialised.checked_offsets_up_to = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) instances, n_children); +@@ -1738,6 +1741,7 @@ test_tuple (void) + serialised.size = needed_size; + serialised.depth = 0; + serialised.ordered_offsets_up_to = 0; ++ serialised.checked_offsets_up_to = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) instances, n_children); +@@ -1835,6 +1839,7 @@ test_variant (void) + serialised.size = needed_size; + serialised.depth = 0; + serialised.ordered_offsets_up_to = 0; ++ serialised.checked_offsets_up_to = 0; + + g_variant_serialiser_serialise (serialised, random_instance_filler, + (gpointer *) &instance, 1); diff --git a/debian/patches/gvariant-security-1-09.patch b/debian/patches/gvariant-security-1-09.patch new file mode 100644 index 0000000..37db717 --- /dev/null +++ b/debian/patches/gvariant-security-1-09.patch @@ -0,0 +1,63 @@ +From 8c1a7815e7e6695c120cdedff48395c1222af6d1 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Fri, 12 Jun 2020 18:01:13 +0100 +Subject: [PATCH 09/18] tests: Add another test for overlapping offsets in + GVariant + +Signed-off-by: Philip Withnall + +Helps: #2121 +--- + glib/tests/gvariant.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -5019,6 +5019,38 @@ test_recursion_limits_array_in_variant ( + g_variant_unref (wrapper_variant); + } + ++/* Test that a nested array with invalid values in its offset table (which point ++ * from the inner to the outer array) is normalised successfully without ++ * looping infinitely. */ ++static void ++test_normal_checking_array_offsets_overlapped (void) ++{ ++ const guint8 data[] = { ++ 0x01, 0x00, ++ }; ++ gsize size = sizeof (data); ++ GVariant *variant = NULL; ++ GVariant *normal_variant = NULL; ++ GVariant *expected_variant = NULL; ++ ++ variant = g_variant_new_from_data (G_VARIANT_TYPE ("aay"), data, size, ++ FALSE, NULL, NULL); ++ g_assert_nonnull (variant); ++ ++ normal_variant = g_variant_get_normal_form (variant); ++ g_assert_nonnull (normal_variant); ++ ++ expected_variant = g_variant_new_parsed ("[@ay [], []]"); ++ g_assert_cmpvariant (normal_variant, expected_variant); ++ ++ g_assert_cmpmem (g_variant_get_data (normal_variant), g_variant_get_size (normal_variant), ++ g_variant_get_data (expected_variant), g_variant_get_size (expected_variant)); ++ ++ g_variant_unref (expected_variant); ++ g_variant_unref (normal_variant); ++ g_variant_unref (variant); ++} ++ + /* Test that an array with invalidly large values in its offset table is + * normalised successfully without looping infinitely. */ + static void +@@ -5418,6 +5450,8 @@ main (int argc, char **argv) + + g_test_add_func ("/gvariant/normal-checking/tuples", + test_normal_checking_tuples); ++ g_test_add_func ("/gvariant/normal-checking/array-offsets/overlapped", ++ test_normal_checking_array_offsets_overlapped); + g_test_add_func ("/gvariant/normal-checking/array-offsets", + test_normal_checking_array_offsets); + g_test_add_func ("/gvariant/normal-checking/array-offsets2", diff --git a/debian/patches/gvariant-security-1-10.patch b/debian/patches/gvariant-security-1-10.patch new file mode 100644 index 0000000..529d46e --- /dev/null +++ b/debian/patches/gvariant-security-1-10.patch @@ -0,0 +1,71 @@ +From 019505a7ccc32d0afa06e104dc0ac2e63e6f7189 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 24 Oct 2022 16:43:23 +0100 +Subject: [PATCH 10/18] tests: Disable some random instance tests of GVariants +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Building a `GVariant` using entirely random data may result in a +non-normally-formed `GVariant`. It’s always possible to read these +`GVariant`s, but the API might return default values for some or all of +their components. + +In particular, this can easily happen when randomly generating the +offset tables for non-fixed-width container types. + +If it does happen, bytewise comparison of the parsed `GVariant` with the +original bytes will not always match. So skip those checks. + +Signed-off-by: Philip Withnall + +Helps: #2121 +--- + glib/tests/gvariant.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -1229,6 +1229,7 @@ random_instance_assert (RandomInstance * + GRand *rand; + gsize i; + ++ g_assert_true (size == 0 || buffer != NULL); + g_assert_cmpint ((gsize) buffer & ALIGN_BITS & instance->alignment, ==, 0); + g_assert_cmpint (size, ==, instance->size); + +@@ -1455,10 +1456,13 @@ test_maybe (void) + g_variant_serialiser_serialise (serialised, + random_instance_filler, + (gpointer *) &instance, 1); ++ + child = g_variant_serialised_get_child (serialised, 0); + g_assert_true (child.type_info == instance->type_info); +- random_instance_assert (instance, child.data, child.size); ++ if (child.data != NULL) /* could be NULL if element is non-normal */ ++ random_instance_assert (instance, child.data, child.size); + g_variant_type_info_unref (child.type_info); ++ + flavoured_free (serialised.data, flavour); + } + } +@@ -1591,7 +1595,8 @@ test_array (void) + + child = g_variant_serialised_get_child (serialised, i); + g_assert_true (child.type_info == instances[i]->type_info); +- random_instance_assert (instances[i], child.data, child.size); ++ if (child.data != NULL) /* could be NULL if element is non-normal */ ++ random_instance_assert (instances[i], child.data, child.size); + g_variant_type_info_unref (child.type_info); + } + +@@ -1757,7 +1762,8 @@ test_tuple (void) + + child = g_variant_serialised_get_child (serialised, i); + g_assert_true (child.type_info == instances[i]->type_info); +- random_instance_assert (instances[i], child.data, child.size); ++ if (child.data != NULL) /* could be NULL if element is non-normal */ ++ random_instance_assert (instances[i], child.data, child.size); + g_variant_type_info_unref (child.type_info); + } + diff --git a/debian/patches/gvariant-security-1-11.patch b/debian/patches/gvariant-security-1-11.patch new file mode 100644 index 0000000..ac087b0 --- /dev/null +++ b/debian/patches/gvariant-security-1-11.patch @@ -0,0 +1,26 @@ +From 9d2a142807806212a23436d0332b0209733810f2 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 24 Oct 2022 18:14:57 +0100 +Subject: [PATCH 11/18] gvariant: Clarify the docs for + g_variant_get_normal_form() + +Document how non-normal parts of the `GVariant` are handled. + +Signed-off-by: Philip Withnall +--- + glib/gvariant.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/glib/gvariant.c ++++ b/glib/gvariant.c +@@ -5923,7 +5923,9 @@ g_variant_deep_copy (GVariant *value) + * marked as trusted and a new reference to it is returned. + * + * If @value is found not to be in normal form then a new trusted +- * #GVariant is created with the same value as @value. ++ * #GVariant is created with the same value as @value. The non-normal parts of ++ * @value will be replaced with default values which are guaranteed to be in ++ * normal form. + * + * It makes sense to call this function if you've received #GVariant + * data from untrusted sources and you want to ensure your serialized diff --git a/debian/patches/gvariant-security-1-12.patch b/debian/patches/gvariant-security-1-12.patch new file mode 100644 index 0000000..d325ea9 --- /dev/null +++ b/debian/patches/gvariant-security-1-12.patch @@ -0,0 +1,40 @@ +From b0ccb1616688290088e49dea2dc0d7fe723136e4 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 24 Oct 2022 18:43:55 +0100 +Subject: [PATCH 12/18] gvariant: Port g_variant_deep_copy() to count its + iterations directly + +This is equivalent to what `GVariantIter` does, but it means that +`g_variant_deep_copy()` is making its own `g_variant_get_child_value()` +calls. + +This will be useful in an upcoming commit, where those child values will +be inspected a little more deeply. + +Signed-off-by: Philip Withnall + +Helps: #2121 +--- + glib/gvariant.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/glib/gvariant.c ++++ b/glib/gvariant.c +@@ -5850,14 +5850,13 @@ g_variant_deep_copy (GVariant *value) + case G_VARIANT_CLASS_VARIANT: + { + GVariantBuilder builder; +- GVariantIter iter; +- GVariant *child; ++ gsize i, n_children; + + g_variant_builder_init (&builder, g_variant_get_type (value)); +- g_variant_iter_init (&iter, value); + +- while ((child = g_variant_iter_next_value (&iter))) ++ for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++) + { ++ GVariant *child = g_variant_get_child_value (value, i); + g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); + g_variant_unref (child); + } diff --git a/debian/patches/gvariant-security-1-13.patch b/debian/patches/gvariant-security-1-13.patch new file mode 100644 index 0000000..23f4eb8 --- /dev/null +++ b/debian/patches/gvariant-security-1-13.patch @@ -0,0 +1,105 @@ +Backport of: + +From 1770e255ae6cc3f0bf5312322432bbc6524a3632 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 25 Oct 2022 13:03:22 +0100 +Subject: [PATCH 13/18] gvariant: Add internal + g_variant_maybe_get_child_value() + +This will be used in a following commit. + +Signed-off-by: Philip Withnall + +Helps: #2540 +--- + glib/gvariant-core.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ + glib/gvariant-core.h | 3 ++ + 2 files changed, 71 insertions(+) + +--- a/glib/gvariant-core.c ++++ b/glib/gvariant-core.c +@@ -1203,6 +1203,74 @@ g_variant_get_child_value (GVariant *val + } + + /** ++ * g_variant_maybe_get_child_value: ++ * @value: a container #GVariant ++ * @index_: the index of the child to fetch ++ * ++ * Reads a child item out of a container #GVariant instance, if it is in normal ++ * form. If it is not in normal form, return %NULL. ++ * ++ * This function behaves the same as g_variant_get_child_value(), except that it ++ * returns %NULL if the child is not in normal form. g_variant_get_child_value() ++ * would instead return a new default value of the correct type. ++ * ++ * This is intended to be used internally to avoid unnecessary #GVariant ++ * allocations. ++ * ++ * The returned value is never floating. You should free it with ++ * g_variant_unref() when you're done with it. ++ * ++ * This function is O(1). ++ * ++ * Returns: (transfer full): the child at the specified index ++ * ++ * Since: 2.72 ++ */ ++GVariant * ++g_variant_maybe_get_child_value (GVariant *value, ++ gsize index_) ++{ ++ g_return_val_if_fail (index_ < g_variant_n_children (value), NULL); ++ g_return_val_if_fail (value->depth < G_MAXSIZE, NULL); ++ ++ if (~g_atomic_int_get (&value->state) & STATE_SERIALISED) ++ { ++ g_variant_lock (value); ++ ++ if (~value->state & STATE_SERIALISED) ++ { ++ GVariant *child; ++ ++ child = g_variant_ref (value->contents.tree.children[index_]); ++ g_variant_unlock (value); ++ ++ return child; ++ } ++ ++ g_variant_unlock (value); ++ } ++ ++ { ++ GVariantSerialised serialised = g_variant_to_serialised (value); ++ GVariantSerialised s_child; ++ ++ /* get the serializer to extract the serialized data for the child ++ * from the serialized data for the container ++ */ ++ s_child = g_variant_serialised_get_child (serialised, index_); ++ ++ if (!(value->state & STATE_TRUSTED) && s_child.data == NULL) ++ { ++ g_variant_type_info_unref (s_child.type_info); ++ return NULL; ++ } ++ ++ g_variant_type_info_unref (s_child.type_info); ++ return g_variant_get_child_value (value, index_); ++ } ++} ++ ++/** + * g_variant_store: + * @value: the #GVariant to store + * @data: (not nullable): the location to store the serialized data at +--- a/glib/gvariant-core.h ++++ b/glib/gvariant-core.h +@@ -36,4 +36,7 @@ GVariantTypeInfo * g_variant_get_ty + + gsize g_variant_get_depth (GVariant *value); + ++GVariant * g_variant_maybe_get_child_value (GVariant *value, ++ gsize index_); ++ + #endif /* __G_VARIANT_CORE_H__ */ diff --git a/debian/patches/gvariant-security-1-14.patch b/debian/patches/gvariant-security-1-14.patch new file mode 100644 index 0000000..28246a4 --- /dev/null +++ b/debian/patches/gvariant-security-1-14.patch @@ -0,0 +1,125 @@ +From 82fc15af4c84a2645343c51b18ab3528c51790ab Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 25 Oct 2022 13:03:45 +0100 +Subject: [PATCH 14/18] gvariant: Cut allocs of default values for children of + non-normal arrays +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This improves a slow case in `g_variant_get_normal_form()` where +allocating many identical default values for the children of a +variable-sized array which has a malformed offset table would take a lot +of time. + +The fix is to make all child values after the first invalid one be +references to the default value emitted for the first invalid one, +rather than identical new `GVariant`s. + +In particular, this fixes a case where an attacker could create an array +of length L of very large tuples of size T each, corrupt the offset table +so they don’t have to specify the array content, and then induce +`g_variant_get_normal_form()` into allocating L×T default values from an +input which is significantly smaller than L×T in length. + +A pre-existing workaround for this issue is for code to call +`g_variant_is_normal_form()` before calling +`g_variant_get_normal_form()`, and to skip the latter call if the former +returns false. This commit improves the behaviour in the case that +`g_variant_get_normal_form()` is called anyway. + +This fix changes the time to run the `fuzz_variant_binary` test on the +testcase from oss-fuzz#19777 from >60s (before being terminated) with +2.3GB of memory usage and 580k page faults; to 32s, 8.3MB of memory +usage and 1500 page faults (as measured by `time -v`). + +Signed-off-by: Philip Withnall + +Fixes: #2540 +oss-fuzz#19777 +--- + glib/gvariant.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 65 insertions(+), 1 deletion(-) + +--- a/glib/gvariant.c ++++ b/glib/gvariant.c +@@ -5844,7 +5844,6 @@ g_variant_deep_copy (GVariant *value) + switch (g_variant_classify (value)) + { + case G_VARIANT_CLASS_MAYBE: +- case G_VARIANT_CLASS_ARRAY: + case G_VARIANT_CLASS_TUPLE: + case G_VARIANT_CLASS_DICT_ENTRY: + case G_VARIANT_CLASS_VARIANT: +@@ -5863,6 +5862,71 @@ g_variant_deep_copy (GVariant *value) + + return g_variant_builder_end (&builder); + } ++ ++ case G_VARIANT_CLASS_ARRAY: ++ { ++ GVariantBuilder builder; ++ gsize i, n_children; ++ GVariant *first_invalid_child_deep_copy = NULL; ++ ++ /* Arrays are in theory treated the same as maybes, tuples, dict entries ++ * and variants, and could be another case in the above block of code. ++ * ++ * However, they have the property that when dealing with non-normal ++ * data (which is the only time g_variant_deep_copy() is currently ++ * called) in a variable-sized array, the code above can easily end up ++ * creating many default child values in order to return an array which ++ * is of the right length and type, but without containing non-normal ++ * data. This can happen if the offset table for the array is malformed. ++ * ++ * In this case, the code above would end up allocating the same default ++ * value for each one of the child indexes beyond the first malformed ++ * entry in the offset table. This can end up being a lot of identical ++ * allocations of default values, particularly if the non-normal array ++ * is crafted maliciously. ++ * ++ * Avoid that problem by returning a new reference to the same default ++ * value for every child after the first invalid one. This results in ++ * returning an equivalent array, in normal form and trusted — but with ++ * significantly fewer memory allocations. ++ * ++ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2540 */ ++ ++ g_variant_builder_init (&builder, g_variant_get_type (value)); ++ ++ for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++) ++ { ++ /* Try maybe_get_child_value() first; if it returns NULL, this child ++ * is non-normal. get_child_value() would have constructed and ++ * returned a default value in that case. */ ++ GVariant *child = g_variant_maybe_get_child_value (value, i); ++ ++ if (child != NULL) ++ { ++ /* Non-normal children may not always be contiguous, as they may ++ * be non-normal for reasons other than invalid offset table ++ * entries. As they are all the same type, they will all have ++ * the same default value though, so keep that around. */ ++ g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); ++ } ++ else if (child == NULL && first_invalid_child_deep_copy != NULL) ++ { ++ g_variant_builder_add_value (&builder, first_invalid_child_deep_copy); ++ } ++ else if (child == NULL) ++ { ++ child = g_variant_get_child_value (value, i); ++ first_invalid_child_deep_copy = g_variant_ref_sink (g_variant_deep_copy (child)); ++ g_variant_builder_add_value (&builder, first_invalid_child_deep_copy); ++ } ++ ++ g_clear_pointer (&child, g_variant_unref); ++ } ++ ++ g_clear_pointer (&first_invalid_child_deep_copy, g_variant_unref); ++ ++ return g_variant_builder_end (&builder); ++ } + + case G_VARIANT_CLASS_BOOLEAN: + return g_variant_new_boolean (g_variant_get_boolean (value)); diff --git a/debian/patches/gvariant-security-1-15.patch b/debian/patches/gvariant-security-1-15.patch new file mode 100644 index 0000000..a7990e9 --- /dev/null +++ b/debian/patches/gvariant-security-1-15.patch @@ -0,0 +1,21 @@ +From 935f1c200789c76ad5b51b1f403f611e3cc75318 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 25 Oct 2022 18:03:56 +0100 +Subject: [PATCH 15/18] gvariant: Fix a leak of a GVariantTypeInfo on an error + handling path + +Signed-off-by: Philip Withnall +--- + glib/gvariant-core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/glib/gvariant-core.c ++++ b/glib/gvariant-core.c +@@ -1181,6 +1181,7 @@ g_variant_get_child_value (GVariant *val + G_VARIANT_MAX_RECURSION_DEPTH - value->depth) + { + g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_VARIANT)); ++ g_variant_type_info_unref (s_child.type_info); + return g_variant_new_tuple (NULL, 0); + } + diff --git a/debian/patches/gvariant-security-1-16.patch b/debian/patches/gvariant-security-1-16.patch new file mode 100644 index 0000000..a1ca393 --- /dev/null +++ b/debian/patches/gvariant-security-1-16.patch @@ -0,0 +1,280 @@ +From f1dfc5d0c5c0486b5fccb2ceddf1db1162c7033c Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 27 Oct 2022 12:00:04 +0100 +Subject: [PATCH 16/18] gvariant-serialiser: Check offset table entry size is + minimal + +The entries in an offset table (which is used for variable sized arrays +and tuples containing variable sized members) are sized so that they can +address every byte in the overall variant. + +The specification requires that for a variant to be in normal form, its +offset table entries must be the minimum width such that they can +address every byte in the variant. + +That minimality requirement was not checked in +`g_variant_is_normal_form()`, leading to two different byte arrays being +interpreted as the normal form of a given variant tree. That kind of +confusion could potentially be exploited, and is certainly a bug. + +Fix it by adding the necessary checks on offset table entry width, and +unit tests. + +Spotted by William Manley. + +Signed-off-by: Philip Withnall + +Fixes: #2794 +--- + glib/gvariant-serialiser.c | 19 +++- + glib/tests/gvariant.c | 176 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 194 insertions(+), 1 deletion(-) + +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -694,6 +694,10 @@ gvs_variable_sized_array_get_frame_offse + out.data_size = last_end; + out.array = value.data + last_end; + out.length = offsets_array_size / out.offset_size; ++ ++ if (out.length > 0 && gvs_calculate_total_size (last_end, out.length) != value.size) ++ return out; /* offset size not minimal */ ++ + out.is_normal = TRUE; + + return out; +@@ -1201,6 +1205,7 @@ gvs_tuple_is_normal (GVariantSerialised + gsize length; + gsize offset; + gsize i; ++ gsize offset_table_size; + + /* as per the comment in gvs_tuple_get_child() */ + if G_UNLIKELY (value.data == NULL && value.size != 0) +@@ -1305,7 +1310,19 @@ gvs_tuple_is_normal (GVariantSerialised + } + } + +- return offset_ptr == offset; ++ /* @offset_ptr has been counting backwards from the end of the variant, to ++ * find the beginning of the offset table. @offset has been counting forwards ++ * from the beginning of the variant to find the end of the data. They should ++ * have met in the middle. */ ++ if (offset_ptr != offset) ++ return FALSE; ++ ++ offset_table_size = value.size - offset_ptr; ++ if (value.size > 0 && ++ gvs_calculate_total_size (offset, offset_table_size / offset_size) != value.size) ++ return FALSE; /* offset size not minimal */ ++ ++ return TRUE; + } + + /* Variants {{{2 +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -5122,6 +5122,86 @@ test_normal_checking_array_offsets2 (voi + g_variant_unref (variant); + } + ++/* Test that an otherwise-valid serialised GVariant is considered non-normal if ++ * its offset table entries are too wide. ++ * ++ * See §2.3.6 (Framing Offsets) of the GVariant specification. */ ++static void ++test_normal_checking_array_offsets_minimal_sized (void) ++{ ++ GVariantBuilder builder; ++ gsize i; ++ GVariant *aay_constructed = NULL; ++ const guint8 *data = NULL; ++ guint8 *data_owned = NULL; ++ GVariant *aay_deserialised = NULL; ++ GVariant *aay_normalised = NULL; ++ ++ /* Construct an array of type aay, consisting of 128 elements which are each ++ * an empty array, i.e. `[[] * 128]`. This is chosen because the inner ++ * elements are variable sized (making the outer array variable sized, so it ++ * must have an offset table), but they are also zero-sized when serialised. ++ * So the serialised representation of @aay_constructed consists entirely of ++ * its offset table, which is entirely zeroes. ++ * ++ * The array is chosen to be 128 elements long because that means offset ++ * table entries which are 1 byte long. If the elements in the array were ++ * non-zero-sized (to the extent that the overall array is ≥256 bytes long), ++ * the offset table entries would end up being 2 bytes long. */ ++ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay")); ++ ++ for (i = 0; i < 128; i++) ++ g_variant_builder_add_value (&builder, g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0)); ++ ++ aay_constructed = g_variant_builder_end (&builder); ++ ++ /* Verify that the constructed array is in normal form, and its serialised ++ * form is `b'\0' * 128`. */ ++ g_assert_true (g_variant_is_normal_form (aay_constructed)); ++ g_assert_cmpuint (g_variant_n_children (aay_constructed), ==, 128); ++ g_assert_cmpuint (g_variant_get_size (aay_constructed), ==, 128); ++ ++ data = g_variant_get_data (aay_constructed); ++ for (i = 0; i < g_variant_get_size (aay_constructed); i++) ++ g_assert_cmpuint (data[i], ==, 0); ++ ++ /* Construct a serialised `aay` GVariant which is `b'\0' * 256`. This has to ++ * be a non-normal form of `[[] * 128]`, with 2-byte-long offset table ++ * entries, because each offset table entry has to be able to reference all of ++ * the byte boundaries in the container. All the entries in the offset table ++ * are zero, so all the elements of the array are zero-sized. */ ++ data = data_owned = g_malloc0 (256); ++ aay_deserialised = g_variant_new_from_data (G_VARIANT_TYPE ("aay"), ++ data, ++ 256, ++ FALSE, ++ g_free, ++ g_steal_pointer (&data_owned)); ++ ++ g_assert_false (g_variant_is_normal_form (aay_deserialised)); ++ g_assert_cmpuint (g_variant_n_children (aay_deserialised), ==, 128); ++ g_assert_cmpuint (g_variant_get_size (aay_deserialised), ==, 256); ++ ++ data = g_variant_get_data (aay_deserialised); ++ for (i = 0; i < g_variant_get_size (aay_deserialised); i++) ++ g_assert_cmpuint (data[i], ==, 0); ++ ++ /* Get its normal form. That should change the serialised size. */ ++ aay_normalised = g_variant_get_normal_form (aay_deserialised); ++ ++ g_assert_true (g_variant_is_normal_form (aay_normalised)); ++ g_assert_cmpuint (g_variant_n_children (aay_normalised), ==, 128); ++ g_assert_cmpuint (g_variant_get_size (aay_normalised), ==, 128); ++ ++ data = g_variant_get_data (aay_normalised); ++ for (i = 0; i < g_variant_get_size (aay_normalised); i++) ++ g_assert_cmpuint (data[i], ==, 0); ++ ++ g_variant_unref (aay_normalised); ++ g_variant_unref (aay_deserialised); ++ g_variant_unref (aay_constructed); ++} ++ + /* Test that a tuple with invalidly large values in its offset table is + * normalised successfully without looping infinitely. */ + static void +@@ -5316,6 +5396,98 @@ test_normal_checking_tuple_offsets4 (voi + g_variant_unref (variant); + } + ++/* Test that an otherwise-valid serialised GVariant is considered non-normal if ++ * its offset table entries are too wide. ++ * ++ * See §2.3.6 (Framing Offsets) of the GVariant specification. */ ++static void ++test_normal_checking_tuple_offsets_minimal_sized (void) ++{ ++ GString *type_string = NULL; ++ GVariantBuilder builder; ++ gsize i; ++ GVariant *ray_constructed = NULL; ++ const guint8 *data = NULL; ++ guint8 *data_owned = NULL; ++ GVariant *ray_deserialised = NULL; ++ GVariant *ray_normalised = NULL; ++ ++ /* Construct a tuple of type (ay…ay), consisting of 129 members which are each ++ * an empty array, i.e. `([] * 129)`. This is chosen because the inner ++ * members are variable sized, so the outer tuple must have an offset table, ++ * but they are also zero-sized when serialised. So the serialised ++ * representation of @ray_constructed consists entirely of its offset table, ++ * which is entirely zeroes. ++ * ++ * The tuple is chosen to be 129 members long because that means it has 128 ++ * offset table entries which are 1 byte long each. If the members in the ++ * tuple were non-zero-sized (to the extent that the overall tuple is ≥256 ++ * bytes long), the offset table entries would end up being 2 bytes long. ++ * ++ * 129 members are used unlike 128 array elements in ++ * test_normal_checking_array_offsets_minimal_sized(), because the last member ++ * in a tuple never needs an offset table entry. */ ++ type_string = g_string_new (""); ++ g_string_append_c (type_string, '('); ++ for (i = 0; i < 129; i++) ++ g_string_append (type_string, "ay"); ++ g_string_append_c (type_string, ')'); ++ ++ g_variant_builder_init (&builder, G_VARIANT_TYPE (type_string->str)); ++ ++ for (i = 0; i < 129; i++) ++ g_variant_builder_add_value (&builder, g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0)); ++ ++ ray_constructed = g_variant_builder_end (&builder); ++ ++ /* Verify that the constructed tuple is in normal form, and its serialised ++ * form is `b'\0' * 128`. */ ++ g_assert_true (g_variant_is_normal_form (ray_constructed)); ++ g_assert_cmpuint (g_variant_n_children (ray_constructed), ==, 129); ++ g_assert_cmpuint (g_variant_get_size (ray_constructed), ==, 128); ++ ++ data = g_variant_get_data (ray_constructed); ++ for (i = 0; i < g_variant_get_size (ray_constructed); i++) ++ g_assert_cmpuint (data[i], ==, 0); ++ ++ /* Construct a serialised `(ay…ay)` GVariant which is `b'\0' * 256`. This has ++ * to be a non-normal form of `([] * 129)`, with 2-byte-long offset table ++ * entries, because each offset table entry has to be able to reference all of ++ * the byte boundaries in the container. All the entries in the offset table ++ * are zero, so all the members of the tuple are zero-sized. */ ++ data = data_owned = g_malloc0 (256); ++ ray_deserialised = g_variant_new_from_data (G_VARIANT_TYPE (type_string->str), ++ data, ++ 256, ++ FALSE, ++ g_free, ++ g_steal_pointer (&data_owned)); ++ ++ g_assert_false (g_variant_is_normal_form (ray_deserialised)); ++ g_assert_cmpuint (g_variant_n_children (ray_deserialised), ==, 129); ++ g_assert_cmpuint (g_variant_get_size (ray_deserialised), ==, 256); ++ ++ data = g_variant_get_data (ray_deserialised); ++ for (i = 0; i < g_variant_get_size (ray_deserialised); i++) ++ g_assert_cmpuint (data[i], ==, 0); ++ ++ /* Get its normal form. That should change the serialised size. */ ++ ray_normalised = g_variant_get_normal_form (ray_deserialised); ++ ++ g_assert_true (g_variant_is_normal_form (ray_normalised)); ++ g_assert_cmpuint (g_variant_n_children (ray_normalised), ==, 129); ++ g_assert_cmpuint (g_variant_get_size (ray_normalised), ==, 128); ++ ++ data = g_variant_get_data (ray_normalised); ++ for (i = 0; i < g_variant_get_size (ray_normalised); i++) ++ g_assert_cmpuint (data[i], ==, 0); ++ ++ g_variant_unref (ray_normalised); ++ g_variant_unref (ray_deserialised); ++ g_variant_unref (ray_constructed); ++ g_string_free (type_string, TRUE); ++} ++ + /* Test that an empty object path is normalised successfully to the base object + * path, ‘/’. */ + static void +@@ -5462,6 +5634,8 @@ main (int argc, char **argv) + test_normal_checking_array_offsets); + g_test_add_func ("/gvariant/normal-checking/array-offsets2", + test_normal_checking_array_offsets2); ++ g_test_add_func ("/gvariant/normal-checking/array-offsets/minimal-sized", ++ test_normal_checking_array_offsets_minimal_sized); + g_test_add_func ("/gvariant/normal-checking/tuple-offsets", + test_normal_checking_tuple_offsets); + g_test_add_func ("/gvariant/normal-checking/tuple-offsets2", +@@ -5470,6 +5644,8 @@ main (int argc, char **argv) + test_normal_checking_tuple_offsets3); + g_test_add_func ("/gvariant/normal-checking/tuple-offsets4", + test_normal_checking_tuple_offsets4); ++ g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized", ++ test_normal_checking_tuple_offsets_minimal_sized); + g_test_add_func ("/gvariant/normal-checking/empty-object-path", + test_normal_checking_empty_object_path); + diff --git a/debian/patches/gvariant-security-1-17.patch b/debian/patches/gvariant-security-1-17.patch new file mode 100644 index 0000000..9f16500 --- /dev/null +++ b/debian/patches/gvariant-security-1-17.patch @@ -0,0 +1,89 @@ +From 781f05a22ef11d8a2177b4e9078978decec36dd0 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 27 Oct 2022 16:13:54 +0100 +Subject: [PATCH 17/18] gvariant: Fix g_variant_byteswap() returning non-normal + data sometimes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If `g_variant_byteswap()` was called on a non-normal variant of a type +which doesn’t need byteswapping, it would return a non-normal output. + +That contradicts the documentation, which says that the return value is +always in normal form. + +Fix the code so it matches the documentation. + +Includes a unit test. + +Signed-off-by: Philip Withnall + +Helps: #2797 +--- + glib/gvariant.c | 8 +++++--- + glib/tests/gvariant.c | 24 ++++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 3 deletions(-) + +--- a/glib/gvariant.c ++++ b/glib/gvariant.c +@@ -6070,14 +6070,16 @@ g_variant_byteswap (GVariant *value) + g_variant_serialised_byteswap (serialised); + + bytes = g_bytes_new_take (serialised.data, serialised.size); +- new = g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE); ++ new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE)); + g_bytes_unref (bytes); + } + else + /* contains no multi-byte data */ +- new = value; ++ new = g_variant_get_normal_form (value); + +- return g_variant_ref_sink (new); ++ g_assert (g_variant_is_trusted (new)); ++ ++ return g_steal_pointer (&new); + } + + /** +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -3833,6 +3833,29 @@ test_gv_byteswap (void) + } + + static void ++test_gv_byteswap_non_normal_non_aligned (void) ++{ ++ const guint8 data[] = { 0x02 }; ++ GVariant *v = NULL; ++ GVariant *v_byteswapped = NULL; ++ ++ g_test_summary ("Test that calling g_variant_byteswap() on a variant which " ++ "is in non-normal form and doesn’t need byteswapping returns " ++ "the same variant in normal form."); ++ ++ v = g_variant_new_from_data (G_VARIANT_TYPE_BOOLEAN, data, sizeof (data), FALSE, NULL, NULL); ++ g_assert_false (g_variant_is_normal_form (v)); ++ ++ v_byteswapped = g_variant_byteswap (v); ++ g_assert_true (g_variant_is_normal_form (v_byteswapped)); ++ ++ g_assert_cmpvariant (v, v_byteswapped); ++ ++ g_variant_unref (v); ++ g_variant_unref (v_byteswapped); ++} ++ ++static void + test_parser (void) + { + TreeInstance *tree; +@@ -5599,6 +5622,7 @@ main (int argc, char **argv) + g_test_add_func ("/gvariant/builder-memory", test_builder_memory); + g_test_add_func ("/gvariant/hashing", test_hashing); + g_test_add_func ("/gvariant/byteswap", test_gv_byteswap); ++ g_test_add_func ("/gvariant/byteswap/non-normal-non-aligned", test_gv_byteswap_non_normal_non_aligned); + g_test_add_func ("/gvariant/parser", test_parses); + g_test_add_func ("/gvariant/parser/integer-bounds", test_parser_integer_bounds); + g_test_add_func ("/gvariant/parser/recursion", test_parser_recursion); diff --git a/debian/patches/gvariant-security-1-18.patch b/debian/patches/gvariant-security-1-18.patch new file mode 100644 index 0000000..f633cb2 --- /dev/null +++ b/debian/patches/gvariant-security-1-18.patch @@ -0,0 +1,290 @@ +From 7d7efce1d9c379fdd7d2ff58caea88f8806fdd2e Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 27 Oct 2022 22:53:13 +0100 +Subject: [PATCH 18/18] gvariant: Allow g_variant_byteswap() to operate on + tree-form variants +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This avoids needing to always serialise a variant before byteswapping it. +With variants in non-normal forms, serialisation can result in a large +increase in size of the variant, and a lot of allocations for leaf +`GVariant`s. This can lead to a denial of service attack. + +Avoid that by changing byteswapping so that it happens on the tree form +of the variant if the input is in non-normal form. If the input is in +normal form (either serialised or in tree form), continue using the +existing code as byteswapping an already-serialised normal variant is +about 3× faster than byteswapping on the equivalent tree form. + +The existing unit tests cover byteswapping well, but need some +adaptation so that they operate on tree form variants too. + +I considered dropping the serialised byteswapping code and doing all +byteswapping on tree-form variants, as that would make maintenance +simpler (avoiding having two parallel implementations of byteswapping). +However, most inputs to `g_variant_byteswap()` are likely to be +serialised variants (coming from a byte array of input from some foreign +source) and most of them are going to be in normal form (as corruption +and malicious action are rare). So getting rid of the serialised +byteswapping code would impose quite a performance penalty on the common +case. + +Signed-off-by: Philip Withnall + +Fixes: #2797 +--- + glib/gvariant.c | 87 ++++++++++++++++++++++++++++++++----------- + glib/tests/gvariant.c | 57 ++++++++++++++++++++++++---- + 2 files changed, 115 insertions(+), 29 deletions(-) + +--- a/glib/gvariant.c ++++ b/glib/gvariant.c +@@ -5839,7 +5839,8 @@ g_variant_iter_loop (GVariantIter *iter, + + /* Serialized data {{{1 */ + static GVariant * +-g_variant_deep_copy (GVariant *value) ++g_variant_deep_copy (GVariant *value, ++ gboolean byteswap) + { + switch (g_variant_classify (value)) + { +@@ -5856,7 +5857,7 @@ g_variant_deep_copy (GVariant *value) + for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++) + { + GVariant *child = g_variant_get_child_value (value, i); +- g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); ++ g_variant_builder_add_value (&builder, g_variant_deep_copy (child, byteswap)); + g_variant_unref (child); + } + +@@ -5907,7 +5908,7 @@ g_variant_deep_copy (GVariant *value) + * be non-normal for reasons other than invalid offset table + * entries. As they are all the same type, they will all have + * the same default value though, so keep that around. */ +- g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); ++ g_variant_builder_add_value (&builder, g_variant_deep_copy (child, byteswap)); + } + else if (child == NULL && first_invalid_child_deep_copy != NULL) + { +@@ -5916,7 +5917,7 @@ g_variant_deep_copy (GVariant *value) + else if (child == NULL) + { + child = g_variant_get_child_value (value, i); +- first_invalid_child_deep_copy = g_variant_ref_sink (g_variant_deep_copy (child)); ++ first_invalid_child_deep_copy = g_variant_ref_sink (g_variant_deep_copy (child, byteswap)); + g_variant_builder_add_value (&builder, first_invalid_child_deep_copy); + } + +@@ -5935,28 +5936,63 @@ g_variant_deep_copy (GVariant *value) + return g_variant_new_byte (g_variant_get_byte (value)); + + case G_VARIANT_CLASS_INT16: +- return g_variant_new_int16 (g_variant_get_int16 (value)); ++ if (byteswap) ++ return g_variant_new_int16 (GUINT16_SWAP_LE_BE (g_variant_get_int16 (value))); ++ else ++ return g_variant_new_int16 (g_variant_get_int16 (value)); + + case G_VARIANT_CLASS_UINT16: +- return g_variant_new_uint16 (g_variant_get_uint16 (value)); ++ if (byteswap) ++ return g_variant_new_uint16 (GUINT16_SWAP_LE_BE (g_variant_get_uint16 (value))); ++ else ++ return g_variant_new_uint16 (g_variant_get_uint16 (value)); + + case G_VARIANT_CLASS_INT32: +- return g_variant_new_int32 (g_variant_get_int32 (value)); ++ if (byteswap) ++ return g_variant_new_int32 (GUINT32_SWAP_LE_BE (g_variant_get_int32 (value))); ++ else ++ return g_variant_new_int32 (g_variant_get_int32 (value)); + + case G_VARIANT_CLASS_UINT32: +- return g_variant_new_uint32 (g_variant_get_uint32 (value)); ++ if (byteswap) ++ return g_variant_new_uint32 (GUINT32_SWAP_LE_BE (g_variant_get_uint32 (value))); ++ else ++ return g_variant_new_uint32 (g_variant_get_uint32 (value)); + + case G_VARIANT_CLASS_INT64: +- return g_variant_new_int64 (g_variant_get_int64 (value)); ++ if (byteswap) ++ return g_variant_new_int64 (GUINT64_SWAP_LE_BE (g_variant_get_int64 (value))); ++ else ++ return g_variant_new_int64 (g_variant_get_int64 (value)); + + case G_VARIANT_CLASS_UINT64: +- return g_variant_new_uint64 (g_variant_get_uint64 (value)); ++ if (byteswap) ++ return g_variant_new_uint64 (GUINT64_SWAP_LE_BE (g_variant_get_uint64 (value))); ++ else ++ return g_variant_new_uint64 (g_variant_get_uint64 (value)); + + case G_VARIANT_CLASS_HANDLE: +- return g_variant_new_handle (g_variant_get_handle (value)); ++ if (byteswap) ++ return g_variant_new_handle (GUINT32_SWAP_LE_BE (g_variant_get_handle (value))); ++ else ++ return g_variant_new_handle (g_variant_get_handle (value)); + + case G_VARIANT_CLASS_DOUBLE: +- return g_variant_new_double (g_variant_get_double (value)); ++ if (byteswap) ++ { ++ /* We have to convert the double to a uint64 here using a union, ++ * because a cast will round it numerically. */ ++ union ++ { ++ guint64 u64; ++ gdouble dbl; ++ } u1, u2; ++ u1.dbl = g_variant_get_double (value); ++ u2.u64 = GUINT64_SWAP_LE_BE (u1.u64); ++ return g_variant_new_double (u2.dbl); ++ } ++ else ++ return g_variant_new_double (g_variant_get_double (value)); + + case G_VARIANT_CLASS_STRING: + return g_variant_new_string (g_variant_get_string (value, NULL)); +@@ -6013,7 +6049,7 @@ g_variant_get_normal_form (GVariant *val + if (g_variant_is_normal_form (value)) + return g_variant_ref (value); + +- trusted = g_variant_deep_copy (value); ++ trusted = g_variant_deep_copy (value, FALSE); + g_assert (g_variant_is_trusted (trusted)); + + return g_variant_ref_sink (trusted); +@@ -6033,6 +6069,11 @@ g_variant_get_normal_form (GVariant *val + * contain multi-byte numeric data. That include strings, booleans, + * bytes and containers containing only these things (recursively). + * ++ * While this function can safely handle untrusted, non-normal data, it is ++ * recommended to check whether the input is in normal form beforehand, using ++ * g_variant_is_normal_form(), and to reject non-normal inputs if your ++ * application can be strict about what inputs it rejects. ++ * + * The returned value is always in normal form and is marked as trusted. + * + * Returns: (transfer full): the byteswapped form of @value +@@ -6050,22 +6091,21 @@ g_variant_byteswap (GVariant *value) + + g_variant_type_info_query (type_info, &alignment, NULL); + +- if (alignment) +- /* (potentially) contains multi-byte numeric data */ ++ if (alignment && g_variant_is_normal_form (value)) + { ++ /* (potentially) contains multi-byte numeric data, but is also already in ++ * normal form so we can use a faster byteswapping codepath on the ++ * serialised data */ + GVariantSerialised serialised = { 0, }; +- GVariant *trusted; + GBytes *bytes; + +- trusted = g_variant_get_normal_form (value); +- serialised.type_info = g_variant_get_type_info (trusted); +- serialised.size = g_variant_get_size (trusted); ++ serialised.type_info = g_variant_get_type_info (value); ++ serialised.size = g_variant_get_size (value); + serialised.data = g_malloc (serialised.size); +- serialised.depth = g_variant_get_depth (trusted); ++ serialised.depth = g_variant_get_depth (value); + serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */ + serialised.checked_offsets_up_to = G_MAXSIZE; +- g_variant_store (trusted, serialised.data); +- g_variant_unref (trusted); ++ g_variant_store (value, serialised.data); + + g_variant_serialised_byteswap (serialised); + +@@ -6073,6 +6113,9 @@ g_variant_byteswap (GVariant *value) + new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE)); + g_bytes_unref (bytes); + } ++ else if (alignment) ++ /* (potentially) contains multi-byte numeric data */ ++ new = g_variant_ref_sink (g_variant_deep_copy (value, TRUE)); + else + /* contains no multi-byte data */ + new = g_variant_get_normal_form (value); +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -2286,24 +2286,67 @@ serialise_tree (TreeInstance *tree + static void + test_byteswap (void) + { +- GVariantSerialised one = { 0, }, two = { 0, }; ++ GVariantSerialised one = { 0, }, two = { 0, }, three = { 0, }; + TreeInstance *tree; ++ GVariant *one_variant = NULL; ++ GVariant *two_variant = NULL; ++ GVariant *two_byteswapped = NULL; ++ GVariant *three_variant = NULL; ++ GVariant *three_byteswapped = NULL; ++ guint8 *three_data_copy = NULL; ++ gsize three_size_copy = 0; + ++ /* Write a tree out twice, once normally and once byteswapped. */ + tree = tree_instance_new (NULL, 3); + serialise_tree (tree, &one); + ++ one_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (one.type_info)), ++ one.data, one.size, FALSE, NULL, NULL); ++ + i_am_writing_byteswapped = TRUE; + serialise_tree (tree, &two); ++ serialise_tree (tree, &three); + i_am_writing_byteswapped = FALSE; + +- g_variant_serialised_byteswap (two); +- +- g_assert_cmpmem (one.data, one.size, two.data, two.size); +- g_assert_cmpuint (one.depth, ==, two.depth); +- ++ /* Swap the first byteswapped one back using the function we want to test. */ ++ two_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (two.type_info)), ++ two.data, two.size, FALSE, NULL, NULL); ++ two_byteswapped = g_variant_byteswap (two_variant); ++ ++ /* Make the second byteswapped one non-normal (hopefully), and then byteswap ++ * it back using the function we want to test in its non-normal mode. ++ * This might not work because it’s not necessarily possible to make an ++ * arbitrary random variant non-normal. Adding a single zero byte to the end ++ * often makes something non-normal but still readable. */ ++ three_size_copy = three.size + 1; ++ three_data_copy = g_malloc (three_size_copy); ++ memcpy (three_data_copy, three.data, three.size); ++ three_data_copy[three.size] = '\0'; ++ ++ three_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (three.type_info)), ++ three_data_copy, three_size_copy, FALSE, NULL, NULL); ++ three_byteswapped = g_variant_byteswap (three_variant); ++ ++ /* Check they’re the same. We can always compare @one_variant and ++ * @two_byteswapped. We can only compare @two_byteswapped and ++ * @three_byteswapped if @two_variant and @three_variant are equal: in that ++ * case, the corruption to @three_variant was enough to make it non-normal but ++ * not enough to change its value. */ ++ g_assert_cmpvariant (one_variant, two_byteswapped); ++ ++ if (g_variant_equal (two_variant, three_variant)) ++ g_assert_cmpvariant (two_byteswapped, three_byteswapped); ++ ++ g_variant_unref (three_byteswapped); ++ g_variant_unref (three_variant); ++ g_variant_unref (two_byteswapped); ++ g_variant_unref (two_variant); ++ g_variant_unref (one_variant); + tree_instance_free (tree); + g_free (one.data); + g_free (two.data); ++ g_free (three.data); ++ g_free (three_data_copy); + } + + static void diff --git a/debian/patches/gvariant-security-2-1.patch b/debian/patches/gvariant-security-2-1.patch new file mode 100644 index 0000000..9241a3a --- /dev/null +++ b/debian/patches/gvariant-security-2-1.patch @@ -0,0 +1,146 @@ +From bf008669f26f70426ca30ee8cdcbd48e41a74718 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 15 Dec 2022 13:00:39 +0000 +Subject: [PATCH 1/2] =?UTF-8?q?gvariant:=20Check=20offset=20table=20doesn?= + =?UTF-8?q?=E2=80=99t=20fall=20outside=20variant=20bounds?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When dereferencing the first entry in the offset table for a tuple, +check that it doesn’t fall outside the bounds of the variant first. + +This prevents an out-of-bounds read from some non-normal tuples. + +This bug was introduced in commit 73d0aa81c2575a5c9ae77d. + +Includes a unit test, although the test will likely only catch the +original bug if run with asan enabled. + +Signed-off-by: Philip Withnall + +Fixes: #2840 +oss-fuzz#54302 +--- + glib/gvariant-serialiser.c | 12 ++++++-- + glib/tests/gvariant.c | 63 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 72 insertions(+), 3 deletions(-) + +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -979,7 +979,8 @@ gvs_tuple_get_member_bounds (GVariantSer + + member_info = g_variant_type_info_member_info (value.type_info, index_); + +- if (member_info->i + 1) ++ if (member_info->i + 1 && ++ offset_size * (member_info->i + 1) <= value.size) + member_start = gvs_read_unaligned_le (value.data + value.size - + offset_size * (member_info->i + 1), + offset_size); +@@ -990,7 +991,8 @@ gvs_tuple_get_member_bounds (GVariantSer + member_start &= member_info->b; + member_start |= member_info->c; + +- if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST) ++ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST && ++ offset_size * (member_info->i + 1) <= value.size) + member_end = value.size - offset_size * (member_info->i + 1); + + else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) +@@ -1001,11 +1003,15 @@ gvs_tuple_get_member_bounds (GVariantSer + member_end = member_start + fixed_size; + } + +- else /* G_VARIANT_MEMBER_ENDING_OFFSET */ ++ else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET && ++ offset_size * (member_info->i + 2) <= value.size) + member_end = gvs_read_unaligned_le (value.data + value.size - + offset_size * (member_info->i + 2), + offset_size); + ++ else /* invalid */ ++ member_end = G_MAXSIZE; ++ + if (out_member_start != NULL) + *out_member_start = member_start; + if (out_member_end != NULL) +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -5462,6 +5462,67 @@ test_normal_checking_tuple_offsets4 (voi + g_variant_unref (variant); + } + ++/* This is a regression test that dereferencing the first element in the offset ++ * table doesn’t dereference memory before the start of the GVariant. The first ++ * element in the offset table gives the offset of the final member in the ++ * tuple (the offset table is stored in reverse), and the position of this final ++ * member is needed to check that none of the tuple members overlap with the ++ * offset table ++ * ++ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2840 */ ++static void ++test_normal_checking_tuple_offsets5 (void) ++{ ++ /* A tuple of type (sss) in normal form would have an offset table with two ++ * entries: ++ * - The first entry (lowest index in the table) gives the offset of the ++ * third `s` in the tuple, as the offset table is reversed compared to the ++ * tuple members. ++ * - The second entry (highest index in the table) gives the offset of the ++ * second `s` in the tuple. ++ * - The offset of the first `s` in the tuple is always 0. ++ * ++ * See §2.5.4 (Structures) of the GVariant specification for details, noting ++ * that the table is only layed out this way because all three members of the ++ * tuple have non-fixed sizes. ++ * ++ * It’s not clear whether the 0xaa data of this variant is part of the strings ++ * in the tuple, or part of the offset table. It doesn’t really matter. This ++ * is a regression test to check that the code to validate the offset table ++ * doesn’t unconditionally try to access the first entry in the offset table ++ * by subtracting the table size from the end of the GVariant data. ++ * ++ * In this non-normal case, that would result in an address off the start of ++ * the GVariant data, and an out-of-bounds read, because the GVariant is one ++ * byte long, but the offset table is calculated as two bytes long (with 1B ++ * sized entries) from the tuple’s type. ++ */ ++ const GVariantType *data_type = G_VARIANT_TYPE ("(sss)"); ++ const guint8 data[] = { 0xaa }; ++ gsize size = sizeof (data); ++ GVariant *variant = NULL; ++ GVariant *normal_variant = NULL; ++ GVariant *expected = NULL; ++ ++ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2840"); ++ ++ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL); ++ g_assert_nonnull (variant); ++ ++ g_assert_false (g_variant_is_normal_form (variant)); ++ ++ normal_variant = g_variant_get_normal_form (variant); ++ g_assert_nonnull (normal_variant); ++ ++ expected = g_variant_new_parsed ("('', '', '')"); ++ g_assert_cmpvariant (expected, variant); ++ g_assert_cmpvariant (expected, normal_variant); ++ ++ g_variant_unref (expected); ++ g_variant_unref (normal_variant); ++ g_variant_unref (variant); ++} ++ + /* Test that an otherwise-valid serialised GVariant is considered non-normal if + * its offset table entries are too wide. + * +@@ -5711,6 +5772,8 @@ main (int argc, char **argv) + test_normal_checking_tuple_offsets3); + g_test_add_func ("/gvariant/normal-checking/tuple-offsets4", + test_normal_checking_tuple_offsets4); ++ g_test_add_func ("/gvariant/normal-checking/tuple-offsets5", ++ test_normal_checking_tuple_offsets5); + g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized", + test_normal_checking_tuple_offsets_minimal_sized); + g_test_add_func ("/gvariant/normal-checking/empty-object-path", diff --git a/debian/patches/gvariant-security-2-2.patch b/debian/patches/gvariant-security-2-2.patch new file mode 100644 index 0000000..f15e29a --- /dev/null +++ b/debian/patches/gvariant-security-2-2.patch @@ -0,0 +1,40 @@ +From 4d0bed8c4690f7a2692474ef6a570bd99ef45ef1 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 15 Dec 2022 16:49:28 +0000 +Subject: [PATCH 2/2] gvariant: Propagate trust when getting a child of a + serialised variant + +If a variant is trusted, that means all its children are trusted, so +ensure that their checked offsets are set as such. + +This allows a lot of the offset table checks to be avoided when getting +children from trusted serialised tuples, which speeds things up. + +No unit test is included because this is just a performance fix. If +there are other slownesses, or regressions, in serialised `GVariant` +performance, the fuzzing setup will catch them like it did this one. + +This change does reduce the time to run the oss-fuzz reproducer from 80s +to about 0.7s on my machine. + +Signed-off-by: Philip Withnall + +Fixes: #2841 +oss-fuzz#54314 +--- + glib/gvariant-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/glib/gvariant-core.c ++++ b/glib/gvariant-core.c +@@ -1196,8 +1196,8 @@ g_variant_get_child_value (GVariant *val + child->contents.serialised.bytes = + g_bytes_ref (value->contents.serialised.bytes); + child->contents.serialised.data = s_child.data; +- child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to; +- child->contents.serialised.checked_offsets_up_to = s_child.checked_offsets_up_to; ++ child->contents.serialised.ordered_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.ordered_offsets_up_to; ++ child->contents.serialised.checked_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.checked_offsets_up_to; + + return child; + } diff --git a/debian/patches/gvariant-security-3-1.patch b/debian/patches/gvariant-security-3-1.patch new file mode 100644 index 0000000..3938bdf --- /dev/null +++ b/debian/patches/gvariant-security-3-1.patch @@ -0,0 +1,60 @@ +From dc16dffed0480d0c8cdd6a05ede68263fc8723a9 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 15 Dec 2022 12:51:37 +0000 +Subject: [PATCH] gvariant-serialiser: Convert endianness of offsets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The array of offsets is little-endian, even on big-endian architectures +like s390x. + +Fixes: ade71fb5 "gvariant: Don’t allow child elements to overlap with each other" +Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2839 +Signed-off-by: Simon McVittie +--- + glib/gvariant-serialiser.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/glib/gvariant-serialiser.c ++++ b/glib/gvariant-serialiser.c +@@ -712,17 +712,19 @@ gvs_variable_sized_array_n_children (GVa + /* Find the index of the first out-of-order element in @data, assuming that + * @data is an array of elements of given @type, starting at index @start and + * containing a further @len-@start elements. */ +-#define DEFINE_FIND_UNORDERED(type) \ ++#define DEFINE_FIND_UNORDERED(type, le_to_native) \ + static gsize \ + find_unordered_##type (const guint8 *data, gsize start, gsize len) \ + { \ + gsize off; \ +- type current, previous; \ ++ type current_le, previous_le, current, previous; \ + \ +- memcpy (&previous, data + start * sizeof (current), sizeof (current)); \ ++ memcpy (&previous_le, data + start * sizeof (current), sizeof (current)); \ ++ previous = le_to_native (previous_le); \ + for (off = (start + 1) * sizeof (current); off < len * sizeof (current); off += sizeof (current)) \ + { \ +- memcpy (¤t, data + off, sizeof (current)); \ ++ memcpy (¤t_le, data + off, sizeof (current)); \ ++ current = le_to_native (current_le); \ + if (current < previous) \ + break; \ + previous = current; \ +@@ -730,10 +732,11 @@ gvs_variable_sized_array_n_children (GVa + return off / sizeof (current) - 1; \ + } + +-DEFINE_FIND_UNORDERED (guint8); +-DEFINE_FIND_UNORDERED (guint16); +-DEFINE_FIND_UNORDERED (guint32); +-DEFINE_FIND_UNORDERED (guint64); ++#define NO_CONVERSION(x) (x) ++DEFINE_FIND_UNORDERED (guint8, NO_CONVERSION); ++DEFINE_FIND_UNORDERED (guint16, GUINT16_FROM_LE); ++DEFINE_FIND_UNORDERED (guint32, GUINT32_FROM_LE); ++DEFINE_FIND_UNORDERED (guint64, GUINT64_FROM_LE); + + static GVariantSerialised + gvs_variable_sized_array_get_child (GVariantSerialised value, diff --git a/debian/patches/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch b/debian/patches/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch new file mode 100644 index 0000000..a05951d --- /dev/null +++ b/debian/patches/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch @@ -0,0 +1,80 @@ +From: Simon McVittie +Date: Mon, 18 Dec 2017 18:06:05 +0000 +Subject: gwakeuptest: Be less parallel unless invoked with -m slow + +This is a workaround for test failures on the reproducible-builds +infrastructure, where a multi-threaded stress-test sometimes takes longer +to finish on x86_64 than it would have done on slow architectures like +arm and mips on the official Debian autobuilders. It is not clear why. + +This change will make this test more likely to pass, but less likely to +detect bugs. + +Signed-off-by: Simon McVittie +Bug-Debian: https://bugs.debian.org/884659 +Forwarded: no +--- + glib/tests/gwakeuptest.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/glib/tests/gwakeuptest.c b/glib/tests/gwakeuptest.c +index b37fb43..a9bef21 100644 +--- a/glib/tests/gwakeuptest.c ++++ b/glib/tests/gwakeuptest.c +@@ -89,6 +89,9 @@ struct context + #define NUM_TOKENS 5 + #define TOKEN_TTL 100000 + ++static gint num_threads = NUM_THREADS; ++static gint token_ttl = TOKEN_TTL; ++ + static struct context contexts[NUM_THREADS]; + static GThread *threads[NUM_THREADS]; + static GWakeup *last_token_wakeup; +@@ -158,7 +161,7 @@ dispatch_token (struct token *token) + struct context *ctx; + gint next_ctx; + +- next_ctx = g_test_rand_int_range (0, NUM_THREADS); ++ next_ctx = g_test_rand_int_range (0, num_threads); + ctx = &contexts[next_ctx]; + token->owner = ctx; + token->ttl--; +@@ -213,6 +216,12 @@ test_threaded (void) + { + gint i; + ++ if (!g_test_slow ()) ++ { ++ num_threads = NUM_THREADS / 10; ++ token_ttl = TOKEN_TTL / 10; ++ } ++ + /* make sure we don't block forever */ + alarm (60); + +@@ -230,7 +239,7 @@ test_threaded (void) + last_token_wakeup = g_wakeup_new (); + + /* create contexts, assign to threads */ +- for (i = 0; i < NUM_THREADS; i++) ++ for (i = 0; i < num_threads; i++) + { + context_init (&contexts[i]); + threads[i] = g_thread_new ("test", thread_func, &contexts[i]); +@@ -238,13 +247,13 @@ test_threaded (void) + + /* dispatch tokens */ + for (i = 0; i < NUM_TOKENS; i++) +- dispatch_token (token_new (TOKEN_TTL)); ++ dispatch_token (token_new (token_ttl)); + + /* wait until all tokens are gone */ + wait_for_signaled (last_token_wakeup); + + /* ask threads to quit, join them, cleanup */ +- for (i = 0; i < NUM_THREADS; i++) ++ for (i = 0; i < num_threads; i++) + { + context_quit (&contexts[i]); + g_thread_join (threads[i]); diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..3bd5e17 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,40 @@ +01_gettext-desktopfiles.patch +0001-timer-test-use-volatile-for-locals.patch +gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch +debian/02_gettext-desktopfiles-ubuntu.patch +debian/03_disble_glib_compile_schemas_warning.patch +debian/06_thread_test_ignore_prctl_fail.patch +debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch +debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch +debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch +debian/Skip-unreliable-gdbus-threading-tests--by-default.patch +debian/gmenumodel-test-Mark-as-flaky.patch +debian/gvariant-test-Don-t-run-at-build-time-on-mips.patch +debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch +debian/gdbus-server-auth-Normally-skip-flaky-DBUS_COOKIE_SHA1-te.patch +debian/Skip-memory-monitor-dbus-test-if-not-specifically-request.patch +debian/Add-extra-debug-to-memory-monitor-dbus-test.patch +debian/tests-Skip-debugcontroller-test.patch +debian/gdesktopappinfo-Recognize-gnome-console-as-a-terminal-app.patch +0001-gio-Make-portal-support-aware-of-snaps.patch +gvariant-security-1-01.patch +gvariant-security-1-02.patch +gvariant-security-1-03.patch +gvariant-security-1-04.patch +gvariant-security-1-05.patch +gvariant-security-1-06.patch +gvariant-security-1-07.patch +gvariant-security-1-08.patch +gvariant-security-1-09.patch +gvariant-security-1-10.patch +gvariant-security-1-11.patch +gvariant-security-1-12.patch +gvariant-security-1-13.patch +gvariant-security-1-14.patch +gvariant-security-1-15.patch +gvariant-security-1-16.patch +gvariant-security-1-17.patch +gvariant-security-1-18.patch +gvariant-security-2-1.patch +gvariant-security-2-2.patch +gvariant-security-3-1.patch diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..7d06368 --- /dev/null +++ b/debian/rules @@ -0,0 +1,296 @@ +#!/usr/bin/make -f + +binaries := $(shell dh_listpackages) + +export DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow + +# Ensure the build aborts when there are still references to undefined symbols +DEB_LDFLAGS_MAINT_APPEND += -Wl,-z,defs + +# NB: do NOT use -Wl,--as-needed to build glib; for instance the link to +# pthread is carefully crafted to allow dlopen()ing pthread-using libs; see +# https://marc.info/?i=1257999019.21780.15.camel@marzipan aka +# https://mail.gnome.org/archives/gtk-devel-list/2009-November/msg00096.html +DEB_LDFLAGS_MAINT_APPEND += -Wl,--no-as-needed + +# Make the linker work a bit harder so dynamic loading can be done faster +DEB_LDFLAGS_MAINT_APPEND += -Wl,-O1 + +include /usr/share/dpkg/default.mk + +%: + dh $@ + +ifneq ($(filter hppa,$(DEB_HOST_ARCH_CPU)),) +stack_grows_up = true +else +stack_grows_up = false +endif + +ifneq ($(filter kfreebsd,$(DEB_HOST_ARCH_OS)),) +have_non_stub_xattr = false +else +have_non_stub_xattr = true +endif + +export DH_MESON_CROSS_FILE = debian/cross.txt + +# We edit the debcrossgen output to work around unimplemented feature +# request https://bugs.debian.org/912559 +override_dh_auto_configure: +ifneq ($(DEB_HOST_ARCH),$(DEB_BUILD_ARCH)) + /usr/share/meson/debcrossgen \ + -o debian/cross.txt.in + debian/set-cross-properties \ + have_c99_snprintf=true \ + have_c99_vsnprintf=true \ + have_strlcpy=false \ + have_unix98_printf=true \ + growing_stack=$(stack_grows_up) \ + < debian/cross.txt.in > debian/cross.txt +endif + dh_auto_configure \ + --builddirectory=debian/build/deb \ + -- \ + $(DEB_CONFIGURE_EXTRA_FLAGS) \ + $(DEB_CONFIGURE_FLAGS_deb) \ + $(NULL) +ifneq ($(filter %-udeb,$(binaries)),) + dh_auto_configure \ + --builddirectory=debian/build/udeb \ + -- \ + $(DEB_CONFIGURE_EXTRA_FLAGS) \ + $(DEB_CONFIGURE_FLAGS_udeb) \ + $(NULL) +endif + +override_dh_clean: + rm -rf $(CURDIR)/debian/build \ + $(CURDIR)/debian/install + dh_clean -Xorg.gtk.test.gschema.xml.orig -Xorg.gtk.test.gschema.override.orig + + +override_dh_makeshlibs: + dh_makeshlibs -plibglib2.0-tests -n + dh_makeshlibs --remaining-packages --add-udeb=libglib2.0-udeb -Xlibgiofam.so -- -c4 + +# (Ubuntu-specific) +# Don't strip translations from the installed tests; makes them environment dependent. +override_dh_translations: + dh_translations -Xinstalled-tests + +# Do not clutter $HOME with ~/.dbus-keyrings and avoid failure on the buildds +# where creating /home/buildd/.dbus-keyrings fails +export HOME=$(CURDIR)/debian/build + +# Make sure that everything that uses D-Bus is creating its own temporary +# session rather than polluting the developer's (or failing, on buildds) +export DBUS_SESSION_BUS_ADDRESS=this-should-not-be-used-and-will-fail: + +ifeq ($(DEB_HOST_ARCH_OS), linux) +handle_test_failure := exit $$? +else +handle_test_failure := true +endif + +# Upstream test timeouts assume an otherwise unloaded system, but that +# isn't necessarily the case for a porterbox or multiple parallel builds +test_timeout_multiplier = 3 + +ifneq ($(filter arm hppa mips% sparc%,$(DEB_HOST_ARCH_CPU)),) +$(info Slow architecture detected, increasing test timeout) +test_timeout_multiplier = 5 +endif + +ifneq ($(filter m68k riscv64 sh4,$(DEB_HOST_ARCH_CPU)),) +$(info Architecture with qemu buildds detected, increasing test timeout a lot) +test_timeout_multiplier = 20 +endif + +override_dh_auto_test-arch: +ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) + # Remove LD_PRELOAD so we don't run with fakeroot, which makes dbus-related tests fail + # First run the non-flaky tests, and fail the build if they fail (on linux) + env -u LD_PRELOAD \ + DEB_BUILD_TIME_TESTS=1 \ + LC_ALL=C.UTF-8 \ + MESON_TESTTHREADS=1 \ + debian/tests/run-with-locales \ + --generate de_DE=ISO-8859-1 \ + --generate de_DE.utf8 \ + --generate de_DE@euro.utf8 \ + --generate el_GR.utf8 \ + --generate en_GB=ISO-8859-1 \ + --generate en_GB.utf8 \ + --generate en_US=ISO-8859-1 \ + --generate en_US.utf8 \ + --generate es_ES.utf8 \ + --generate fa_IR=UTF-8 \ + --generate fa_IR.utf8 \ + --generate fr_FR.utf8 \ + --generate hr_HR.utf8 \ + --generate ja_JP.utf8 \ + --generate ja_JP.EUC-JP \ + --generate lt_LT.utf8 \ + --generate pl_PL=ISO-8859-2 \ + --generate pl_PL.ISO-8859-2 \ + --generate pl_PL.utf8 \ + --generate ru_RU=ISO-8859-5 \ + --generate ru_RU.utf8 \ + --generate sr_RS=UTF-8 \ + --generate sr_RS@latin=UTF-8 \ + --generate sv_SE=ISO-8859-1 \ + --generate sv_SE.utf8 \ + --generate tr_TR=ISO-8859-9 \ + --generate tr_TR.utf8 \ + --generate tt_RU=UTF-8 \ + --generate tt_RU.utf8 \ + --generate tt_RU@iqtelif=UTF-8 \ + -- \ + meson test -C debian/build/deb \ + --no-rebuild \ + --num-processes 1 \ + --timeout-multiplier $(test_timeout_multiplier) \ + --no-suite flaky \ + --verbose \ + || $(handle_test_failure) + # and then run the flaky ones, but ignore them failing + env -u LD_PRELOAD \ + DEB_BUILD_TIME_TESTS=1 \ + LC_ALL=C.UTF-8 \ + MESON_TESTTHREADS=1 \ + meson test -C debian/build/deb \ + --no-rebuild \ + --num-processes 1 \ + --timeout-multiplier $(test_timeout_multiplier) \ + --suite flaky \ + --verbose \ + || true +endif + +# Skip most build-time tests if all we are building is documentation; +# running them once per architecture is plenty. As an exception, do run the +# documentation completeness checks, which won't normally be run on +# architecture-specific buildds (except in Ubuntu). +override_dh_auto_test-indep: + meson test -C debian/build/deb \ + --no-rebuild \ + --num-processes 1 \ + --timeout-multiplier $(test_timeout_multiplier) \ + --verbose \ + gio-doc-check glib-doc-check gobject-doc-check \ + || $(handle_test_failure) + +# Let's get failing tests' stdout and stderr so we have some information when +# a build fails +export VERBOSE=1 + +ifeq ($(DEB_HOST_ARCH_OS),linux) +enable_libmount := enabled +enable_selinux := enabled +else +enable_libmount := disabled +enable_selinux := disabled +endif + +ifneq ($(filter hurd,$(DEB_HOST_ARCH_OS)),) +use_fam := true +else +use_fam := false +endif + +DEB_CONFIGURE_FLAGS_deb := \ + --default-library both \ + -Dfam=$(use_fam) \ + -Dinstalled_tests=true \ + -Dlibelf=enabled \ + -Dlibmount=$(enable_libmount) \ + -Dman=true \ + -Dselinux=$(enable_selinux) \ + -Dsystemtap=true \ + -Dxattr=$(have_non_stub_xattr) \ + $(NULL) + +ifneq ($(filter libglib2.0-doc,$(binaries)),) +DEB_CONFIGURE_FLAGS_deb += -Dgtk_doc=true +else +DEB_CONFIGURE_FLAGS_deb += -Dgtk_doc=false +endif + +DEB_CONFIGURE_FLAGS_udeb := \ + --default-library shared \ + -Dgtk_doc=false \ + -Dinstalled_tests=false \ + -Dlibmount=disabled \ + -Dselinux=disabled \ + -Dxattr=$(have_non_stub_xattr) \ + $(NULL) + +override_dh_auto_build: + mkdir -p debian/tmp-xdg-runtime-dir + dh_auto_build --builddirectory=debian/build/deb +ifneq ($(filter %-udeb,$(binaries)),) + dh_auto_build --builddirectory=debian/build/udeb +endif + +override_dh_auto_install: + set -e; for script in postinst postrm triggers; do \ + sed -e"s/#MULTIARCH#/$(DEB_HOST_MULTIARCH)/g" \ + -e"s/#ARCH#/$(DEB_HOST_ARCH)/g" \ + debian/libglib2.0-0.$$script.in \ + > debian/libglib2.0-0.$$script ; \ + done +ifneq ($(filter %-udeb,$(binaries)),) + dh_auto_install -plibglib2.0-udeb --builddirectory=debian/build/udeb --destdir=debian/install/udeb +endif + dh_auto_install --remaining-packages --builddirectory=debian/build/deb --destdir=debian/install/deb + +override_dh_python3: + # dh_python3 can't process both a private directory and /usr/bin + # in the same invocation + dh_python3 -plibglib2.0-dev-bin /usr/share/glib-2.0/codegen + dh_python3 -plibglib2.0-tests --no-ext-rename /usr/libexec/installed-tests/glib + dh_python3 + +override_dh_install: + # Unwanted bits from the .deb build + rm -fr debian/install/deb/usr/share/glib-2.0/codegen/__pycache__ +ifneq ($(filter %-udeb,$(binaries)),) + # Unwanted bits from the .udeb build + rm -f debian/install/udeb/usr/lib/*/*.so + rm -fr debian/install/udeb/usr/share/gdb + rm -fr debian/install/udeb/usr/share/gettext/its + rm -fr debian/install/udeb/usr/share/glib-2.0/codegen + rm -fr debian/install/udeb/usr/share/glib-2.0/gdb + rm -fr debian/install/udeb/usr/share/glib-2.0/valgrind + rm -fr debian/install/udeb/usr/share/man + dh_install -plibglib2.0-udeb --sourcedir=debian/install/udeb +endif +ifneq ($(filter %-tests,$(binaries)),) + sed -i -e '/^#!.*/,1 d' debian/install/deb/usr/libexec/installed-tests/glib/taptestrunner.py +endif +ifneq ($(filter hurd,$(DEB_HOST_ARCH_OS)),) + dh_install -plibglib2.0-0 --sourcedir=debian/install/deb usr/lib/${DEB_HOST_MULTIARCH}/gio/modules/libgiofam.so usr/lib/${DEB_HOST_MULTIARCH}/gio/modules +endif + dh_install --remaining-packages --sourcedir=debian/install/deb + install -D -t debian/libglib2.0-0/usr/share/glib-2.0/ debian/clean-up-unmanaged-libraries + install -D -t debian/libglib2.0-0/usr/lib/${DEB_HOST_MULTIARCH}/glib-2.0/ debian/gio-launch-desktop + +override_dh_dwz: + dh_dwz -Nlibglib2.0-udeb + +# debhelper >= 13.4 makes all of /usr/libexec executable, which is not +# quite right for installed-tests +override_dh_fixperms: + dh_fixperms -Xusr/libexec/installed-tests +ifneq ($(filter %-tests,$(binaries)),) + chmod --changes u=rw,og=r debian/libglib2.0-tests/usr/libexec/installed-tests/*/*.so + chmod --changes u=rw,og=r debian/libglib2.0-tests/usr/libexec/installed-tests/*/*/*.so + chmod --recursive --changes a+rX,u+w,og-w debian/libglib2.0-tests/usr/libexec/installed-tests +endif + +override_dh_missing: + dh_missing --sourcedir=debian/install/deb +ifneq ($(filter %-udeb,$(binaries)),) + dh_missing --sourcedir=debian/install/udeb +endif diff --git a/debian/set-cross-properties b/debian/set-cross-properties new file mode 100755 index 0000000..728d8d8 --- /dev/null +++ b/debian/set-cross-properties @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys + + +def write_properties(properties): + for prop in properties: + k, v = prop.split('=', 1) + print('{} = {}'.format(k, v)) + + +if __name__ == '__main__': + for line in sys.stdin: + sys.stdout.write(line) + + if line.strip() == '[properties]': + write_properties(sys.argv[1:]) + done = True + + if not done: + print('[properties]') + write_properties(sys.argv[1:]) diff --git a/debian/shlibs.local b/debian/shlibs.local new file mode 100644 index 0000000..f21d4a5 --- /dev/null +++ b/debian/shlibs.local @@ -0,0 +1,10 @@ +libgio-2.0 0 libglib2.0-0 (= ${binary:Version}) +libglib-2.0 0 libglib2.0-0 (= ${binary:Version}) +libgmodule-2.0 0 libglib2.0-0 (= ${binary:Version}) +libgobject-2.0 0 libglib2.0-0 (= ${binary:Version}) +libgthread-2.0 0 libglib2.0-0 (= ${binary:Version}) +udeb: libgio-2.0 0 libglib2.0-udeb (= ${binary:Version}) +udeb: libglib-2.0 0 libglib2.0-udeb (= ${binary:Version}) +udeb: libgmodule-2.0 0 libglib2.0-udeb (= ${binary:Version}) +udeb: libgobject-2.0 0 libglib2.0-udeb (= ${binary:Version}) +udeb: libgthread-2.0 0 libglib2.0-udeb (= ${binary:Version}) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/tests/bug896019 b/debian/tests/bug896019 new file mode 100755 index 0000000..171afb0 --- /dev/null +++ b/debian/tests/bug896019 @@ -0,0 +1,170 @@ +#!/bin/bash + +set -e + +. debian/tests/lib.sh +cd "$AUTOPKGTEST_TMP" + +biarch= + +getopt_temp="help" +getopt_temp="$getopt_temp,biarch" + +getopt_temp="$(getopt -o '' --long "$getopt_temp" -n "$me" -- "$@")" +eval "set -- $getopt_temp" + +while [ "$#" -gt 0 ] +do + case "$1" in + (--biarch) + biarch=yes + shift + ;; + + (--) + shift + break + ;; + + (-*) + warning "Unknown option: $1" + usage 2 + ;; + + (*) + break + ;; + esac +done + +system_arch="${DEB_HOST_ARCH:-"$(dpkg --print-architecture)"}" +multiarch="${DEB_HOST_MULTIARCH:-"$(dpkg-architecture -a"$system_arch" -qDEB_HOST_MULTIARCH)"}" +foreign_arch= +foreign_multiarch= + +if [ -n "$biarch" ]; then + case "$system_arch" in + (amd64) + foreign_arch="i386" + foreign_multiarch="i386-linux-gnu" + ;; + (arm64) + foreign_arch="armhf" + foreign_multiarch="arm-linux-gnueabihf" + ;; + (*) + echo "1..0 # SKIP - no secondary architecture" >&7 + exit 77 + esac +fi + +if [ -n "$foreign_arch" ]; then + require dpkg --add-architecture "$foreign_arch" + require_apt "$foreign_arch" +fi + +if [ -n "$foreign_arch" ]; then + multiarchs=("$multiarch" "$foreign_multiarch") +else + multiarchs=("$multiarch") +fi + +require_apt_stretch + +package=libglib2.0-0 +old_version=2.50.3-2+deb9u2 +soname=libglib-2.0.so.0 +other_sonames=(libgio-2.0.so.0 libgmodule-2.0.so.0 libgobject-2.0.so.0 libgthread-2.0.so.0) +tail=5000.3 + +if ! new_version=$(dpkg-query -W -f '${Version}' "$package:$system_arch"); then + echo "1..0 # SKIP - unable to get version of $package:$system_arch" >&7 + exit 77 +fi + +if ! apt-get download "$package=$old_version"; then + echo "1..0 # SKIP - unable to download $package=$old_version" >&7 + exit 77 +fi + +if [ -n "$foreign_arch" ] && ! apt-get download "$package:$foreign_arch=$old_version"; then + echo "1..0 # SKIP - unable to download $package:$foreign_arch=$old_version" >&7 + exit 77 +fi + +if [ -n "$foreign_arch" ]; then + require apt-get -y install --reinstall "$package=$new_version" "$package:$foreign_arch=$new_version" + good_foreign_realpath="$(readlink -f "/usr/lib/$foreign_multiarch/$soname")" +else + require apt-get -y install --reinstall "$package=$new_version" + good_foreign_realpath= +fi + +good_realpath="$(readlink -f "/usr/lib/$multiarch/$soname")" + +# Pretend the version from stretch got stuck on the system somehow. +# (This is the wrong way to use dpkg-deb, never do this in production.) +require dpkg-deb --vextract "${package}_${old_version}_${system_arch}.deb" . + +if [ -n "$foreign_arch" ]; then + require dpkg-deb --vextract "${package}_${old_version}_${foreign_arch}.deb" . +fi + +for ma in "${multiarchs[@]}"; do + cp -a ./lib/"$ma"/"$soname" /lib/"$ma"/ + cp -a ./lib/"$ma"/"$soname".* /lib/"$ma"/ + + for other in "${other_sonames[@]}"; do + cp -a ./usr/lib/"$ma"/"$other" /usr/lib/"$ma"/ + cp -a ./usr/lib/"$ma"/"$other".* /usr/lib/"$ma"/ + done +done + +assert_succeeds ldconfig --verbose + +for ma in "${multiarchs[@]}"; do + echo "Status before reinstalling $package" + assert_succeeds ls -il "/lib/$ma/$soname" + assert_succeeds ls -il "/lib/$ma/$soname".* + assert_succeeds ls -il "/lib/$ma/$soname.$tail" + assert_succeeds ls -il "/usr/lib/$ma/$soname" + assert_succeeds ls -il "/usr/lib/$ma/$soname".* +done + +for other in "$soname" "${other_sonames[@]}"; do + echo "Running 'true' with $other preloaded to see what we get..." + env LD_DEBUG=libs LD_PRELOAD="$other" true || true +done + +if [ -n "$foreign_arch" ]; then + assert_succeeds apt-get -y install --reinstall "$package:$system_arch=$new_version" "$package:$foreign_arch=$new_version" +else + assert_succeeds apt-get -y install --reinstall "$package:$system_arch=$new_version" +fi + +for ma in "${multiarchs[@]}"; do + if [ "/usr/lib/$ma" -ef "/lib/$ma" ]; then + echo "Merged-/usr system" + assert_status 1 test "/usr/lib/$ma/$soname" -ef "/usr/lib/$ma/$soname.$tail" + else + echo "Non-merged-/usr system" + assert_succeeds ls -il "/lib/$ma/removed-by-upgrade-bug896019/" + assert_status 1 test -e "/lib/$ma/$soname.$tail" + assert_status 1 test -e "/lib/$ma/$soname" + assert_succeeds test -e "/usr/lib/$ma/$soname" + fi +done + +assert_succeeds test "/usr/lib/$multiarch/$soname" -ef "$good_realpath" + +if [ -n "$foreign_arch" ]; then + assert_succeeds test "/usr/lib/$foreign_multiarch/$soname" -ef "$good_foreign_realpath" +fi + +for other in "$soname" "${other_sonames[@]}"; do + env LD_DEBUG=libs LD_PRELOAD="$other" true +done + +finish + +# vim:set sw=4 sts=4 et: diff --git a/debian/tests/bug896019-biarch b/debian/tests/bug896019-biarch new file mode 100755 index 0000000..0cc01bf --- /dev/null +++ b/debian/tests/bug896019-biarch @@ -0,0 +1,2 @@ +#!/bin/sh +exec debian/tests/bug896019 --biarch diff --git a/debian/tests/build b/debian/tests/build new file mode 100755 index 0000000..d0a8ad2 --- /dev/null +++ b/debian/tests/build @@ -0,0 +1,143 @@ +#!/bin/sh +# autopkgtest check: Build and run a program against glib, to verify that the +# headers and pkg-config file are installed correctly +# (C) 2012,2019 Canonical Ltd. +# (C) 2018 Simon McVittie +# Authors: Martin Pitt , Simon McVittie + +set -eux + +mode=dynamic + +getopt_temp="$(getopt -o '' --long 'static' -n debian/tests/build -- "$@")" +eval set -- "$getopt_temp" + +while true; do + case "$1" in + (--static) + mode=static + shift + continue + ;; + + (--) + shift + break + ;; + + (*) + echo "getopt: Internal error" >&2 + exit 2 + esac +done + +WORKDIR=$(mktemp -d) +trap 'rm -rf "${WORKDIR}"' 0 INT QUIT ABRT PIPE TERM +cd "${WORKDIR}" + +if [ -n "${DEB_HOST_GNU_TYPE:-}" ]; then + CROSS_COMPILE="${DEB_HOST_GNU_TYPE}-" +else + CROSS_COMPILE= +fi + +cat < glib.c +#include + +int main(void) +{ + g_assert_cmpint (g_strcmp0 (NULL, "hello"), ==, -1); + g_assert_cmpstr (g_getenv ("foo"), ==, "bar"); + return 0; +} +EOF +cat < gobject.c +#include + +int main(void) +{ + g_assert_cmpuint (G_TYPE_OBJECT, !=, G_TYPE_INVALID); + return 0; +} +EOF +cat < gio.c +#include + +int main(void) +{ + g_assert_cmpuint (G_TYPE_FILE, !=, G_TYPE_INVALID); + return 0; +} +EOF +cat < gio-unix.c +#include + +int main(void) +{ + g_assert_cmpuint (G_TYPE_UNIX_FD_LIST, !=, G_TYPE_INVALID); + return 0; +} +EOF +cat < gmodule.c +#include + +int main(void) +{ + GModule *module; + + g_assert_true (g_module_supported ()); + module = g_module_open (NULL, 0); + g_assert_nonnull (module); + g_assert_true (g_module_close (module)); + return 0; +} +EOF +cat < gthread.c +#include + +static gpointer +other_cb (gpointer nil) +{ + return "hello"; +} + +int main(void) +{ + GThread *other; + gpointer ret; + + other = g_thread_new ("other", other_cb, NULL); + g_assert_nonnull (other); + ret = g_thread_join (other); + g_assert_cmpstr (ret, ==, "hello"); + return 0; +} +EOF + +for lib in glib gobject gio gio-unix gmodule gthread; do + cflags= + pcflags= + packages="${lib}-2.0" + + case "$mode" in + (static) + cflags=-static + pcflags=--static + + case "$lib" in + (gio|gio-unix) + # GIO depends on libmount which no longer supports + # being linked statically + continue + ;; + esac + ;; + esac + + # shellcheck disable=SC2046 + ${CROSS_COMPILE}gcc $cflags -o ${lib}-$mode ${lib}.c $(${CROSS_COMPILE}pkg-config $pcflags --cflags --libs ${packages}) + echo "build ($lib, $mode): OK" + [ -x ${lib}-$mode ] + foo=bar ./${lib}-$mode + echo "run ($lib, $mode): OK" +done diff --git a/debian/tests/build-static b/debian/tests/build-static new file mode 100755 index 0000000..7ba5c42 --- /dev/null +++ b/debian/tests/build-static @@ -0,0 +1,2 @@ +#!/bin/sh +exec debian/tests/build --static diff --git a/debian/tests/control b/debian/tests/control new file mode 100644 index 0000000..e36a37f --- /dev/null +++ b/debian/tests/control @@ -0,0 +1,15 @@ +Tests: build build-static +Depends: libglib2.0-dev, build-essential +Restrictions: allow-stderr superficial + +Tests: installed-tests +Depends: dbus (>= 1.8), dbus-x11, gnome-desktop-testing, libglib2.0-tests, locales | locales-all, xauth, xvfb +Restrictions: allow-stderr + +Tests: flaky +Depends: dbus (>= 1.8), dbus-x11, gnome-desktop-testing, libglib2.0-tests, locales | locales-all, xauth, xvfb +Restrictions: allow-stderr flaky + +Tests: bug896019 bug896019-biarch +Depends: dpkg-dev, libglib2.0-0 +Restrictions: allow-stderr, breaks-testbed, needs-root, skippable diff --git a/debian/tests/flaky b/debian/tests/flaky new file mode 100755 index 0000000..51a2e0b --- /dev/null +++ b/debian/tests/flaky @@ -0,0 +1,72 @@ +#!/bin/sh +# autopkgtest check: Run the installed-tests to verify glib works correctly +# This part runs tests that have been marked as opt-in due to being flaky +# on at least some architectures. +# (C) 2013 Canonical Ltd. +# (C) 2019 Collabora Ltd. + +set -eu +NULL= + +export DEB_ALLOW_FLAKY_TESTS=1 + +# Disable gvfs if it happens to be installed. We want to test the built-in +# stuff +export GIO_USE_VFS=local +export GIO_USE_VOLUME_MONITOR=unix + +export XDG_RUNTIME_DIR="$AUTOPKGTEST_TMP" + +printf "Running as: "; id -a +printf "passwd entry: "; getent passwd "$(id -u)" || echo "(exit status $?)" +printf "group entry: "; getent group "$(id -g)" || echo "(exit status $?)" +echo "Environment:" +env | LC_ALL=C sort -u + +exec dbus-run-session -- \ +xvfb-run -a \ +debian/tests/run-with-locales \ + --generate de_DE=ISO-8859-1 \ + --generate de_DE.utf8 \ + --generate de_DE@euro.utf8 \ + --generate el_GR.utf8 \ + --generate en_GB=ISO-8859-1 \ + --generate en_GB.utf8 \ + --generate en_US=ISO-8859-1 \ + --generate en_US.utf8 \ + --generate es_ES.utf8 \ + --generate fa_IR=UTF-8 \ + --generate fa_IR.utf8 \ + --generate fr_FR.utf8 \ + --generate hr_HR.utf8 \ + --generate ja_JP.utf8 \ + --generate ja_JP.EUC-JP \ + --generate lt_LT.utf8 \ + --generate pl_PL=ISO-8859-2 \ + --generate pl_PL.ISO-8859-2 \ + --generate pl_PL.utf8 \ + --generate ru_RU=ISO-8859-5 \ + --generate ru_RU.utf8 \ + --generate sr_RS=UTF-8 \ + --generate sr_RS@latin=UTF-8 \ + --generate sv_SE=ISO-8859-1 \ + --generate sv_SE.utf8 \ + --generate tr_TR=ISO-8859-9 \ + --generate tr_TR.utf8 \ + --generate tt_RU=UTF-8 \ + --generate tt_RU.utf8 \ + --generate tt_RU@iqtelif=UTF-8 \ + -- \ +gnome-desktop-testing-runner \ + glib/closure-refcount.test \ + glib/debugcontroller.test \ + glib/gdbus-server-auth.test \ + glib/gdbus-threading.test \ + glib/gmenumodel.test \ + glib/mainloop.test \ + glib/memory-monitor-dbus.test \ + glib/socket.test \ + glib/testfilemonitor.test \ + glib/timeout.test \ + glib/timer.test \ + ${NULL} diff --git a/debian/tests/installed-tests b/debian/tests/installed-tests new file mode 100755 index 0000000..c286625 --- /dev/null +++ b/debian/tests/installed-tests @@ -0,0 +1,55 @@ +#!/bin/sh +# autopkgtest check: Run the installed-tests to verify glib works correctly +# (C) 2013 Canonical Ltd. +# Author: Iain Lane + +set -eu + +# Disable gvfs if it happens to be installed. We want to test the built-in +# stuff +export GIO_USE_VFS=local +export GIO_USE_VOLUME_MONITOR=unix + +export XDG_RUNTIME_DIR="$AUTOPKGTEST_TMP" + +printf "Running as: "; id -a +printf "passwd entry: "; getent passwd "$(id -u)" || echo "(exit status $?)" +printf "group entry: "; getent group "$(id -g)" || echo "(exit status $?)" +echo "Environment:" +env | LC_ALL=C sort -u + +exec dbus-run-session -- \ +xvfb-run -a \ +debian/tests/run-with-locales \ + --generate de_DE=ISO-8859-1 \ + --generate de_DE.utf8 \ + --generate de_DE@euro.utf8 \ + --generate el_GR.utf8 \ + --generate en_GB=ISO-8859-1 \ + --generate en_GB.utf8 \ + --generate en_US=ISO-8859-1 \ + --generate en_US.utf8 \ + --generate es_ES.utf8 \ + --generate fa_IR=UTF-8 \ + --generate fa_IR.utf8 \ + --generate fr_FR.utf8 \ + --generate hr_HR.utf8 \ + --generate ja_JP.utf8 \ + --generate ja_JP.EUC-JP \ + --generate lt_LT.utf8 \ + --generate pl_PL=ISO-8859-2 \ + --generate pl_PL.ISO-8859-2 \ + --generate pl_PL.utf8 \ + --generate ru_RU=ISO-8859-5 \ + --generate ru_RU.utf8 \ + --generate sr_RS=UTF-8 \ + --generate sr_RS@latin=UTF-8 \ + --generate sv_SE=ISO-8859-1 \ + --generate sv_SE.utf8 \ + --generate tr_TR=ISO-8859-9 \ + --generate tr_TR.utf8 \ + --generate tt_RU=UTF-8 \ + --generate tt_RU.utf8 \ + --generate tt_RU@iqtelif=UTF-8 \ + -- \ +gnome-desktop-testing-runner glib diff --git a/debian/tests/lib.sh b/debian/tests/lib.sh new file mode 100644 index 0000000..376287f --- /dev/null +++ b/debian/tests/lib.sh @@ -0,0 +1,124 @@ +#!/bin/sh + +test_num=0 +fail=0 + +# TAP output goes to fd 7, which is our original stdout +exec 7>&1 +# Other stdout goes to our original stderr +exec >&2 + +require () { + if ! "$@"; then + echo "1..0 # SKIP - command failed: $*" >&7 + exit 77 + fi +} + +require_apt_stretch () { + mirror="$(perl -ne 'if (m{^deb\s+(https?://[-\w.:]+)/debian/?\s}) { print "$1\n"; exit; }' /etc/apt/sources.list /etc/apt/sources.list.d/*)" + if [ -n "$mirror" ]; then + echo >> /etc/apt/sources.list + echo "deb $mirror/debian stretch main" >> /etc/apt/sources.list + else + echo "1..0 # SKIP - unable to guess how to set up an apt source for stretch" >&7 + exit 77 + fi + + require_apt +} + +require_apt () { + local arch="${1-}" + + if [ -n "${DEB_HOST_ARCH-}" ]; then + host_suffix=":${DEB_HOST_ARCH}" + fi + + if ! apt-get -y update; then + echo "1..0 # SKIP - apt not configured?" >&7 + exit 77 + fi + + if [ -n "$arch" ]; then + if ! apt-get -y install libc6:$arch; then + echo "1..0 # SKIP - cannot install libc6:$arch" >&7 + exit 77 + fi + else + if ! apt-get -y install hello; then + echo "1..0 # SKIP - apt not configured?" >&7 + exit 77 + fi + fi +} + +assert_succeeds () { + assert_status 0 "$@" +} + +assert_status () { + local expected="$1" + local e + + shift + test_num=$(( $test_num + 1 )) + + echo "# $*" + if "$@"; then + if [ "x$expected" = x0 ]; then + echo "ok $test_num - “$*â€" >&7 + else + echo "not ok $test_num - “$*†succeeded but should have failed" >&7 + fail=1 + fi + else + e="$?" + if [ "x$expected" = "x$e" ] || [ "x$expected" = xfailure ]; then + echo "ok $test_num - “$*†failed with status $e as expected" >&7 + else + echo "not ok $test_num - “$*†expected status $expected, got $e" >&7 + fail=1 + fi + fi +} + +assert_output () { + local expected="$1" + shift + local really + + test_num=$(( $test_num + 1 )) + echo "# $*" + + if really="$("$@")"; then + if [ "x$expected" = "x$really" ]; then + echo "ok $test_num - “$*†returned “$really†as expected" >&7 + else + echo "not ok $test_num - expected “$*†to output “$*â€, got “$reallyâ€" >&7 + fail=1 + fi + else + e="$?" + echo "not ok $test_num - “$*†failed with exit status $e" >&7 + fail=1 + fi +} + +ok () { + test_num=$(( $test_num + 1 )) + echo "ok $test_num - $*" >&7 +} + +skip_to_the_end () { + test_num=$(( $test_num + 1 )) + echo "not ok $test_num # SKIP $*" >&7 + finish +} + +finish () { + echo "1..$test_num" >&7 + exit "$fail" +} + +# vim:set sw=4 sts=4 et: diff --git a/debian/tests/run-with-locales b/debian/tests/run-with-locales new file mode 100755 index 0000000..29264ef --- /dev/null +++ b/debian/tests/run-with-locales @@ -0,0 +1,165 @@ +#!/bin/sh +# +# Run a wrapped command with at least the requested locales available. +# Requires a dependency on locales | locales-all. +# The requested locales must be of the form foo_FOO.utf8, or special-cased +# in generate(), or listed in /usr/share/i18n/SUPPORTED, or specify the +# locale in the form locale=charset. +# +# Copyright 2016-2021 Simon McVittie +# Copyright 2017-2018 Collabora Ltd. +# +# SPDX-License-Identifier: MIT +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Assume a Debian Policy §10.4-compatible shell like dash or bash (with the +# 'local' builtin) +# shellcheck disable=SC2039 + +set -eu + +me="$(basename "$0")" +tempdir= + +usage () { + local status="${1-2}" + + if [ "$status" -ne 0 ]; then + exec >&2 + fi + + echo "Usage: $me [--generate LOCALE...] [--] COMMAND [ARGS...]" + exit "$status" +} + +getopt_temp=help +getopt_temp="$getopt_temp,generate:" + +getopt_temp="$(getopt -o '+' --long "$getopt_temp" -n "$0" -- "$@")" +eval set -- "$getopt_temp" +unset getopt_temp + +generate () { + local locale="$1" + local charset="" + local source + local output + + echo "$me: $locale..." >&2 + + case "$locale" in + (*=*) + source="${locale%=*}" + output="$source" + ;; + + (*.*) + source="${locale%.*}" + output="$source.$( + export LC_ALL=C + printf '%s' "${locale##*.}" | \ + tr '[:upper:]' '[:lower:]' | \ + tr -d -C '[:lower:][:digit:]' + )" + ;; + + (*) + source="${locale}" + output="${locale}" + esac + + if [ -e "/usr/lib/locale/$output/LC_MESSAGES/SYS_LC_MESSAGES" ]; then + printf '\t%s\n' "Found in locales-all" >&2 + return + fi + + if ! [ -d /usr/share/i18n/charmaps ]; then + echo "$me: $locale not in locales-all and /usr/share/i18n/charmaps not found" >&2 + return + fi + + case "$locale" in + (*=*) + charset="${locale##*=}" + ;; + + (*.utf8 | *.UTF-8) + charset="UTF-8" + ;; + + (*.*) + charset="${locale##*.}" + ;; + esac + + if [ -z "$charset" ]; then + echo "$me: $locale charset not known" >&2 + exit 1 + fi + + printf '\t%s\n' "Character set: $charset" >&2 + printf '\t%s\n' "Source file: $source" >&2 + + if [ -z "$tempdir" ]; then + tempdir="$(mktemp -d)" + trap 'rm -fr "$tempdir"' EXIT + fi + + printf '\t%s\n' "Output: $tempdir/$output" >&2 + + localedef -i "$source" -f "$charset" "$tempdir/$output" +} + +while [ "$#" -gt 0 ]; do + case "$1" in + (--help) + usage 2 + # not reached + ;; + + (--generate) + generate "$2" + shift 2 + ;; + + (--) + shift + break + ;; + + (-*) + echo "$me: Unknown option: $1" >&2 + usage 2 + # not reached + ;; + + (*) + break + ;; + esac +done + +if [ -n "$tempdir" ]; then + export LOCPATH="$tempdir" +fi + +"$@" + +# vim:set sw=4 sts=4 et: diff --git a/debian/upstream/metadata b/debian/upstream/metadata new file mode 100644 index 0000000..7dbae41 --- /dev/null +++ b/debian/upstream/metadata @@ -0,0 +1,6 @@ +--- +Name: GLib +Bug-Database: https://gitlab.gnome.org/GNOME/glib/issues/new +Repository: https://gitlab.gnome.org/GNOME/glib.git +Repository-Browse: https://gitlab.gnome.org/GNOME/glib/ +Security-Contact: https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/SECURITY.md diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..d971fae --- /dev/null +++ b/debian/watch @@ -0,0 +1,7 @@ +version=4 +opts="searchmode=plain, uversionmangle=s/\.(alpha|beta|rc)/~$1/, downloadurlmangle=s|cache.json||" \ +https://download.gnome.org/sources/glib/cache.json \ + [\d.]+/glib-([\d.]+)@ARCHIVE_EXT@ +#opts="mode=git,compression=xz" \ +#https://gitlab.gnome.org/GNOME/glib.git \ +#refs/tags/@ANY_VERSION@ From 9c17110c550c1f46a4e1006def26dbc0bb19179c Mon Sep 17 00:00:00 2001 From: evinadmin Date: Tue, 4 Jul 2023 11:23:48 +0200 Subject: [PATCH 3/5] pristine-tar data for glib2.0_2.72.4.orig.tar.xz --- glib2.0_2.72.4.orig.tar.xz.delta | Bin 0 -> 87305 bytes glib2.0_2.72.4.orig.tar.xz.id | 1 + 2 files changed, 1 insertion(+) create mode 100644 glib2.0_2.72.4.orig.tar.xz.delta create mode 100644 glib2.0_2.72.4.orig.tar.xz.id diff --git a/glib2.0_2.72.4.orig.tar.xz.delta b/glib2.0_2.72.4.orig.tar.xz.delta new file mode 100644 index 0000000000000000000000000000000000000000..c1fd3f56682b6e1417ef14caf87b722f19951874 GIT binary patch literal 87305 zcmb2|=3oE=<~OyRTU1=9mMJs+dlBfsI+rmwP>g-kudAQp%n#pkxNPEN{;kPA`)_1q zWa!D$Yl|zr`?;93c$yZRc(#v+i#Q zJ+Xql%Etb^OvT?%b>F*BMC9GMk=Mq&*U(b**ttc|-=#PG@$udI;{C5nCp+Kde+!xHqt%+OH}W#OL{B2o*fC=dvC6h)$bR!hi@#uI5TJFWVgL5rN7=YT6{Iv*H_2* z`^;CqGj9J|8~@{jE-~a1BUf#a8@7fC8 z+$&Mu+s^(AG|svEHrrOe;ERU-%c#b*>bAUg)63_&&#V)zY<#%WcJ=(pI`=pH`(T=V z{pmc}O=(|$ZC%ZGZ$sVHS5r-wM^BKg)v26QUH0RX^SzLoZCPJ;eLdZ8vng%o&f}}Y z_oT+YbUe%Nvv!?nann}qY4TN9xE=%=y8p>s;6Cm7t8JW|>AKr*I6g6fJ+%yJH2Q+fK8Xe(F3rgb+v zf7hOVdwtQ)6*^@l${(B}#AetU8^j)FnIv;Et5$o{uXW-xltivLa0#sN6;W7PrGMi0 zH1#vuQ^QZ|yG|<0o6z+la+_op^W|@68P-hL6Bhry_O?-k^{TU$+eGfaJ+d&ZB6f4W zmPW5?(BDN^f2h`9-?>$C3F%ffED z722LwyeyL;%h>wuZNxi`BGIE!{f}0h{U7^v?@TWbwN+Q88G<{X)&5MF7${M(d1B4C ziGdsLXaodx*qmQ?XNQQD#q|l_KJxhOot-{K`!Y*H1dX?|)NtruUwSDoVPerr z$psVst>X;{-2J%n@{vhC+*gbx^glcnV3*qUdgru-w~wf12D^9sa#VVzCwcIeoncB* zNQ!0JZPWDIdk+-f3VWeDd)5l>ttYOm@a?izxf|ZHImS5a^<6#5X&iC<%iUMD1Uj_O zTXkwx)xvb2{^fSL=e&g%+iZtqV#Hu3%C6=5Srf-?+>BqK`+o@$OwO8NAPj+`Bxt$n#=* z?I-)J%^ga2A8KAvZYwI0KhmkSalLUmtB2xL9s^JN4@vUjK1Y&ri~G)<@v`M>U6}La zY9XIii%ISMqH4Jn$6a?!^JlX%5>e>b@-XYlVh16KJTH$Uk3?QHt$$aRn{-6gC34A( z%SvzKl2=zIxpgtGJi&72fwYN$vs+JQ^b*(CveI?SWf+nb?pkf@7Tci0w#B-z-^wHQ z^w-B7JoU@oIp_%Z9C&s#P<59K-=o>;pL0$(%s%VEks;K6!XQ^#`|28rOL7+`YAM}G zX>h5^;bi_;(dKTm`NXS_ZdWdLK7Lr1&DT<@{OHG}N~Ze@8-!#VQ<4m8D|PK)~YRS3Eh+PCH&+Af`!78&&!*xn9_7% zs`kR0Zx)q!FdaKKF_rsMuccAQjE`4L0@t5)*50sC=j0at)CWmE)_rU%w5D=?k(vCC zJyP+`Rqq8_J|%M(2}v`DC8{`2ki2kpht?YB0?}s$3&gKmvN$jGM|!1ut2k<T616%(%V@7eiilO%`W zrW01tjI9MromHHaBpqAxm1@`vCw6%oe&iFl>cWwE>F~OeAd!k~y(+N{Cn7hra&oY3 zy7_C*O<(aZmtLxSa40#RE3o=hbFe9hk+HDC&4(x1C4AR}h1UHI7BAj$uQx`T-&!EkP0 zZqqsS=?kpV#G_45on-tQcfDCGhe2)4gpHq;p8u-BwZ>0oX3i@G*TgT%42K-576?Yv zJz;&Zijl?n#tQaiHmf~m@h%E75w$$2GvqcZ96EHU=R!c+E6#AEE`gq-lLIP}YHQ9b ztGjJkDSXsC@4>w&HbtLJt#gIgo=seTb*iIAaH~yd#G=>kmqo3=D0J0ac__izXtLp0 zuW8OMPTd*T(vK$P?#k9nOb}>My~#fPi3&f{%nxt5FP>{%vee^N$J5M|dv7FwAsxJL4F+8AfdkR!=86x9pnHSg~8FP~^qJ z4N5OEa~fk*m}YB#GBG&tHAsn5Szd5!=f+nP%6Qhy5mKx)uGo3>)1>0A6&jHrO|vF? zx``MS3qNK{lG(OwO4orH6!oDO$&91bW1wS8ro9BOnH4XhX$D(<)F*eZw}31Xq^7lqc0`-R*LZ?uHcYg) z@G=xS**T_bHM{sUC2nXD{CGkpQli7~l5~m$=Tye3KSy>QyLNoy-bq5sxcGBlGxSXH zGSFXn-H5|$LL>ap5d;Jrh)!+#S}c_Wq#U|a9l5O ziOr5!ra}w(*z9c&Y;Q9$J(;20cH&F-F*b{D(_&`}{#+C(Gh^kNm__;AWODUha+A4Hz{zOCi8hfWRatGGiCQN;6l3)*>op67 z6=pQ}esfdsJJ6oT`izmI`ADaZlY`hTBQ3LgEHcOJb~Ea*Hk>>=t5Lq406#GnhGE zu{SX0G~QGG_Il|2m45~ zm8HrFe7W` zfVHD4&pGAII|X=>l8wD4C`?>n)#T`5<$IR#$YB9C*T|2~<(8J~=FgeonCs7}l6>gZ zt`5PE7bZtHEuOEy_jIzw#Z-Y)F5zE%#4{TzSxzYyA7T_ar8=Yi86$`DjZ1;kb=2Lz zs=i8k>$&lp$~xIIE>#!Ytv&^CWFC_}l$9V`sUrGHZTE#Vg;|rQUwkCeuF;_Fv@90 z5e=I^>UQ7V`F$rvh8aC=-8|70HS)EV=(TxZf~$QG`2 z;9n6K%>P+LfW!Uzl+8~JQsuf$yMAu+^=Ga9$NzEK1dd+yQ}x*yKV(=m(&v~li`xV= zF+A_-NJM-{|sAm>|jGZZQ7uJ7ey8NVEIlCsVNMrxA2)-kl0a1@< zziZpNIwYiT*=wKd%c2adN58(|u~~AUNwrDYEcPwO>9;DCIvs~5F}(U(wL4odWcI(< z!~07Of-Y9_MCoYXsl4zaK8ov^ew1r#>pOqZ1P}FlT@aJ!Y6Dka?(Xy5oj=sm8mjf2REm5#U*VFQn9D^QWl~zrMQQR+_O{YRaA& z$Nu?TU%REMdBrv9tD&Mot72YEJw2OYdZ_!Xb%Bz1o;54Z?5Y0pV%?^D3N!1%FDXBp z)XF5-@KGXK(?LW=zj-FJcuQM@%9q(&!nvIH7oNEjbM}Lw_PIqX!;B<&BF{!__z`OK z`i#R1TjxGTo4pI4oN&J7zBXce-p^B_ueBDr>-}Kw_M|GMbv(Y1M1>@vyFD6UV%dfrfuxd8v|75;9_j;PI(PahS{m)sY zBzJjMR?iZ>wd?lPZ-&dhOtZY0QS!=r`7~cs^<`3P)571sI{oVFyC+Xvwi{-az1rIs z6!yqq#kXrBE8@ab*Y>?DE%~bR%%Z0;v+da-i(MvH=1r@)P?YGiYHGaNjEx=T3x76x z?w3u~GqLW;O_a%L?EC(?Rgg8Vo$Y9Rf#P@GUA*rs>$Y6b30#)Gc+T%FZ*?XdQfvOq zqb3uWiUg#?OcCrG#3Vl^=e7uKdto%2elON3MG&o!^>S;!iqGk`%Jj ze!bZ$ab10o^=C!TdAVZM>v(f@rhZY8Xq2#ge)Qkj<75BCzWh!h;J0)eIF*96!x$%qd@}8fMpQ~Y(N|@6n!^d}dPHTyo zujw?sTn;at&JAa;`P7y*Gu%3UBC(x)(iS6(*KE`9UXJzjZx`VF~B8J*O8wwTF%MYGioMoX-XK*PJ=yr+ay>%QLf(kf2l6 z58axy9W%sEEV~}69Vu2Dv9v*m^^HS$+~F>hOHGmSQ%HA_*Vbcd7Bsi)@Hfq zuhjQ7={ke`{DY0tmX|IRFmg7OYV1{ZS-8`}MZ~ntxoD$mN-A69#aRdn*^>R(6;`6?b#CzA>-cYqve(E}=V}@U*e=uY3aXziLQ%kVQWLfhIqb7mAjh7A9 zR>);q1oPUrpLLv<(|>kbnvbv1<Goo1^1^MUvD%Pr~dGM6Gv4)$trv~E?G;}a|P4JvGnDNeC?Ut$wId!y6p zzefHbmS?4~n^UgXu@HzJkQ@quXNl zKHMO>FJsp+X1h%rd;VOWv2Lj&XF<8a)ur`UZ-`g^VB1yE$QSzhX4R9|m$hDHs$E{c z{ra8*uU2bZGPP^$`!LO_y<(EHo6d}`V~baYn7eFEMT!+>ft7T zR-!`8*Y#d#QH<=~)1k*NE^(i8EI7Mo<#n0h^`?Dt*6mByhzls^NAD^MmH5&#VUy76 z-G;(GB`0V1t+(_OEPPucT%uU%e}1Lv@z!IHIoPYF&sf=-s`AY_>659`lfL5y^Tc{P z-cS54zg#Ma*{O%Uy14Z5$2T(;OlhrHJnOo0U;AzO$FY;nFSsyMK5!#vyB6#1cIo4b zE=H~~%XV!p>@IY1=;hPz`{>!z=$Gc1Z1!B|ti{=)CHoh=i(MwUy1hSx>9YCPjE75& zo)oV2s$1EU*0_G^jddU6y&}`~l;rlf^$UMmqPsnt^^0~LcdFE6g}v{L=WTnv^UZ?a z6}J{%0_d&*WA6qrmYy+aMYVarvFFuMTc_J^Qv;4 zrfR&eeb>Zae9XiBw4>y!5wA`Ayn6xfj!m0gCzZ9vEnz3~_{?{L#Er#9!%sY|{8^cnJczG}?t+3QjJqI_>*^#6j_SvHakmL&*6#D86&iPK^yY||)BG{Y-|0Y(OV?veopB&7r_Q7Ke6}w7^>C$-nK zU3C5Rwr!ceK5ydH*cEMMGvN)p+TTM$d}+VeTzbpLH(AEqD{!8&Rn@V;rX8~_=cGtm zH#aH&NKM=kAy6|(`G#p}Z`~cH+#ix1@0<^;m=x8+16=e&T;8}CURdACI@YPOGRXqn9ZSx!E4q^^d{IZ@=3 zJ6W>g>IXgEe#i8kSL9bLIcU{wekW z>Kc)G&rIb0FueY%-0<{8iCFrVkOl2>n_g+8{!z5*ePg#SDtXbpIT6>^Y?l^3TPrnr z>*U%sYgZZSu0Aql3uE1Jzkghn7W)^6a~nRk4|;Mn+HxV2o$tvx%G~M@L$y&tm1~no zf^pcf1RJGxTgL*ShQxKZm#6!ACK2fh8of@==MJ+Y? zd*jm_PM=fPw%fiqAm1{nNO8M};*>eubCj4BG=(?5o2K~OD#xlVlYSa0)A^&dG`PXyQDT{!_7| zMRn)51-)`7EreMoT;n>W7wWd5?C2-w{;0;T$?><;PEU6@AoGl&;#nH2NQu2b#kt!e zF1M~TFMd3An#c}~3*LS%ZcLXh9<>v*5Dt^+JbLSdyN6K76U)@i6GR=OzE~8p$Oh|q zB;LI+N9*q4vt16l+KU#lCz$Fnf3?ZKb+I|~M6M>YL)!(FuT}?EuQZmQ+CL*rWdh$* z?$g>WmNOmvLl(2yZj(KxTCT3oVrn~G?}cQ?-Z!6L(-RShRO?Fy@vv=s_0 z5^HygcrfwbTc(BExq~9aqs~23GMmYedij}6mQ=9h6q#Cw=jYpUU*)|yywpKHA|;P= z6MyTBWyu%ayv(~i?=$@2U~sVxdB-`cD2{(Fhhl|P{(h_Ku48c~JMZ;$1wU?6RWqvl z!gzQ2x2hEqxn|Cai#qN2doI~M3lMXAy5q#k4R_y{d0BfpFO;v4O;VW1mGzjf-PfM& z!M8PaxeaQ*X#oY>o02y5vrJ$!bZBJ%&i?B7;``FFN(Y{7&~%tzx9RGeMYR^nZCjgP zeiC=xtQ2s%WiR(HnPZz5aBWbO<#If`MY(bQv=o8qJ@XU{g&U+c@}9Hb$uN6H!A7|+ zFK>oc?e{ydu3hit^t>z0n~xbBi>od@`{`2v+r`bcwzs@lJ|riHsqmk%+)-s*RI$U8 zp;q^2yF%~2yJl&(+AhAUGF-XDEKx=7CrjLc8BI61(o0{8{xUmVJv**VC-3^nkB?PS zS1(KLpFZPmsE^L_1v4TpdE7pE(LeiGj`(&Nt<}0F4QQTJrQuUbN$#W~?BLX}~mSt^-}qzWw)@9*q6WPBvhsNaBn^)a=o z(>8vmj{B9JeknAg$M=+S0>|2Y-gANiCqEJhG?G!$S};?~xRrT$QnbvdW6H6c4O4AWoZPthI`&N$Rg8+5%aNrd z$oPAs&n`ojCebvN1%5uy9&X^9e8B3)Ji&djA_?Cnb2{*rY}TH*z-kfe>H}{iFR0sp zc5<0q8?sg;e2GG9>2I}9T0TrKTiV_+xt}XGis-*L?f7+Lr$^#5^fqlZ6KR^oEc{Zs zljX|B#>wv_ITtnSbhW-%74hQr=5+-tjT}|nw>Nw1p&MoM>W+8V}rBc%K8rD^vG8gAN+6Bf=a{l!uqTE6ML2xpARWBz?%5tR| z>ogVCV81@oA8{RPN{bopt@&Ze-pJv9{kzSM=(HnDxsKe6q$hf08gee%d{W!p{5-d# z@2(?yZw~*M$)Hr&S^D7ke!J{&EPlX*%6o^l$cfc)A_nG;}XNgw`-G}4HFYy>h1jy!dD*6)*;an?V-u>FQtO- zP%@YH0T#|K4VS75;_TigBL61 zXmVefAR=q~GoAZfUSfdZYG-?n!$pz1z67{*UF$KjFuJ|)dO^10lN8Yc6OJuB;=kW) z5Se8CP3Pur_Pth#>n2-E-6#$$_7V8XSEx0|qUm`)=Q7ic=S6sDUHmH3JNM+_hTyfw zT#~uey$;!LvYv0@R*^M1`9kpY7{2=GN|posfkl>eF_V~8o-2LU*wf_JA-9*)IB@;h zQlAGr(mi<^3uk-1m?l&e#A&;8>@}S5uu=>PdT*-V9iEx-BTyY|5)m3qz*!F5Q)*0hbC{b$VG)tl898 zn^uNQ_g%UxN9$^8@JhYeUZpo7Qro7y+O#xe`r1{cGw)=sw~;8`p;UcznUY&#xw?>H zm9DmEd)oQUyPtj#spR>av4*3``imyR{-A?`KX!R@3B+=H8-5Tw6VP>c--8CrM@+vD zl&*Bq*^y+(!V$-?^VS58$^E&TdV9GhM7bYNH1T57@_A=vabl`2-yuC)m86G%+gOzL zFdR}`wtDGWe`Q~8n{9L2C%I|3y8X-Xakf0vIL*i-M|?{6P42A147Q9H9Xe8x&mScn z{Ke<4(k=NYQ?TrKv-iZ`GBI6u?s_b3>TP66+Sw+1_;`!ufy*r6`awMHD)Va=u`kOh ziPG8;K9PBY)8-iN=EUgSm{(tapKuFcde9xrwDajLxjhxLm0X^m4(74dS{JD7p>K4e zAT8s?hgtD_ZSz=9E_~rW{^YK#lGnv0r7Idyl6?yPSq1Nd2r95$1Kh4O$y%ChF@Hd{)H-l?v^S+xP}m z2oF!gOlE7@7lPTcFBgV-LF*^zV+U!8G3(3K-LC^2 zbs3+E2h=vdiY;5QV4A~MKkJYH?*&!cWwlnQ2HbtbFM362#;T3^H?yivELt0WE$B>G z>f}QoulAk_aMWbHx@`H4Pa)Ftl6D8@mUXT5+j>!Ro8{GGi*J;L%|`a`Y3Wk>z?r5rCk<4y*~=tKo8eVtI3~@D}U(dOid`BR##+rlZWrI-*v7FvPXnAI5|!$nKZlq4QHKw(TeWab08v|SfV>adBf}dF+T4eEq$|1OUrNl)Gh`l?T$MSpB!4Ty{E3g zv!JTm(Zl*hW#eLQ-H4_yH@>=Yc3IjT67)&(zi3@@GFCmeL|)QrgZi!)o-=NLdCX_b zQ2lFdx>N@14z1AFRaG}TSGN{^j9C7-^l{J@&3^?y+rGB1kKD~SMRwD(7s=sk<2X zN4)x0skq2o+DQF0Hxk4GWiY3s@W|VPt8Wc`i9de^b@x z2VXQ;e^mwilM9XOP&wGLFn?ODJ40i^g%v3kzaIoGTzA1LMNxwLH`9tGi=R7k2>+gB zE_6h(`=C(cBJPyb4;icqEHe9Kzn@Or%gAzQV$DCHK>rpc--i{G96Kz2T+CZ9!l=}q zq$gbZxn*VJJ*|d@V5R<`!_6_4&mC?G@brGN6fFC0!|s%q_1xeQqh-5bsSck=&+0qY zo>e_Bfm9<4%Dko--M@a7}eq zWo|ILaCcqoyc3K8m8<;=9=++_?=i1^(*Mu;rw@m@?Xa78e8W}t%G2r0Q}+~dA6v!3 zz{lpPHm!mG@{P1#Z&emh=UUpWV&z=IV>jWt(mbOj|eI>S51CzKjbx$4hpnO|O`4Rk*i% z@vL|bZ@+(blg^ws*NG3WshMJzyD2*2h`&Y%(?q$wX@3(}_r+}VQ{h_9egBfO)86pU zdoMY&SG{oJXMT~$Vb`-@`Rs;vS>c)rf!OYLql+({`5l+sj@v3##rO2ag@f(v6Zt%J z7O;9b&Z~ToC?53QN&jAJ*NH6)+uu2+@XTgaed|2!@cD2#9^3B=+Ao}*8L)Pi;fD?E zdkfDu$vO3|5_k6hEs(jN+qT7P4S#A0!_`9!r(Q6ey2S9LH=DeEro6bj z{9ya#3(hN=eVj$@dG}7_O+7h}QO?RLq-;j$Ql%C4))%ZT0+w1`=(Y?9wG4>dE&C!- zyv0fPXzQmZPL-c{UMNlplwTDp?{(t4RN(P-ttnjra-20URBKi!{asP}A?iUT!`6O= zEP2M1cBd7pEdgiSE}U+aUf3Sc*m}_M+R1>o0*q!oEdh^v7fk9`c*c>n^&&$R$KGg` zy>2X5eR)(xoLeoJMZfEOaVrk6d#?D^xA~jm1p%*l^8eI+{QR|DWd3FA+l}sXZ#5;) z5dE?^bFKHU6FC7lgibb{cq}LB(jswR;d8X1(uZfyUOtz)nf{>VLV=yi|972^vrl|B zQi@f)rXlW#zEx)I=PuJQpbF#Q%wnycJJc*6Mw-2zN{cK@md->(e zjyTH`MVuUGl({ALr6?axWGgVqYEF}s$8M%6JbxG>9vOE~R9k&o0r=jQ2*!UmNS0xsH5p8Be+ za3+VlnEj+#>$a;Fx_>z5`nYcc|B6Knby0%r{0lcf{e4Bl+_s&gW=Gi$j$_wC7uMNN z>AWm|Xi`-}{6Y?`cPqpLUMR_Tt@gRGhD*myMVG-<)}SMHt%Xl(z-`~Y6$?X;A3d{Y zLFf$2Ra0G}-yJ_{tmmqr@yt70$kKM7%7G=d8y2@Oow1>kL&L{j!SBs{_8j9Uj(Voc z%YGU=ES_wdqnds3vwi(*`B!$6;=ayVX6RVAY+2No^4gbAT)vtA&NO?~{c7#CCr2)= zbX$Ej#w0NR+H^nND4UOSo^|~{lDLGuTU_5LT_^m#)wJ#hDWCRVo_~Gb-$hU4qyK$u zchCL(we#(^Ur*D&#|PeiH_895?A_J!A16JwD}Austmfk=Xn{fArfGWF+T z&$-^-^Kq{EzNEw9)936>^R@kVTK)Zwf>*x#Z#+7*`+P;x?sjSZdA| zqw&Mi{&_#oES=mx|NHcn_H(OW2h0Dt6#uQ_$;`ic9AS1_s_xIVONra~vTHBD#p9{` zJD%_PuD!qVlfJioNd1okxpI~UpM}il7X6);E!VLwYRmKcOL+dzt6!1)FJ`&o>;J;S zYkmH!@2Fb*wdVi-*MBBVudkE%_y5Q8>{}E6$t+iV^S{?E`Q@dhNB`Mhol~>#|9{iE zx-Y%6#dE(l#qK%qYI4zw7u)u>#C0ou?mXcmpHuqKS}*q3qw<-|n|geLcPY*|GKIzw-aD|NPzh&n0#H&9~j(*BpO%`%c!pO<$*K`~Q0IT>g_@ zrO}Pl*T?hXHoj&wzhC$JBLDre|H|R>_WyKDzkl~#Rc-$LY%|~5NB0hwTmR;IeB!s9 z<<|w_TjH-}-zhk-v;V#Q&fiz%D?ZqMJoD80eYM}~mw(sa|9ztV-q%~_ecxTVU31=l ze&n|!q5Cafw6*vDdGIbf|JO0=eS5!ZF2Dc%`S0^q4{Nux%)kF_()o8ge!kM5fBRqm z|LOy)>h~0!KdGO${qO8&|6cCPe^dE6+waEf8QXr}w*L3D<*dEs=W7ohH=n$fZ2so& zrt5b~Z)~%#IlpoDoZnA6ci-Fn@ZnqBZTH?^TL0&vx8Lul`=aeG z{CvN+?)!;J*JR6U9)I|;@&5ep`SLq5?q|>6_3)tmo{!tj_dE^Xo?H1x`rW=oWzWj* zef`n*|CY_8E5_%mKEBugKmDiqi}hw@zdk>^UjM3N`Teas_Z@b8*mwQTr(??Zzkhfd zE@%AzXZ8I(&%U02bGPoxmh*c)#;^O=->v`q-QMl><^F%yhR1#Qy!g!e_4Qw_Uyu3r zDPE@H^_AW4em}eZ{m&oMgPp74yv;Lx- zKL7K*-FbWT_I)-qTd-?i(A1C()FX#XH>6L!X z>)F*?>WdCZPM=e9UM&3l-I}we?{|G$^!0zi|Afc$%;kUlTmSFHJK^az8xx#YfH}ZZ=Wes^XtI%by1b8{~l6~`?vaNd+fFP7i$08Ud!L# za{2i3HJABsJvD#-=i2di_dc%9znT5{&K1k=b|Ux6?k=}4{UrY_{@3hpkDtdBKG)>8 zD>+tf_jk7J_Fd|Bne*%a-|Xv`t@Ho8;r`WsFX!I>eb8U;*Wo8~=zf{qr)OI4f3@MP_`d94)5_|9AB}$h@!jp-)6?hFUHQ)cVcYIsm)6?-ezy0U z-SbcL*T?+3bUnB5h~azrnh)C9+hTUUy{#9QK7YeyX+O*5_3u8aZ|(d4?d0wK?_YjC zXa4u?bGwq?i^cap^S;QfXK|?VOLTnop5o`J;jx9UgY9pXw#V<^^8G{W>H4}`Gv(up zZ;NlU`f_^W=CsGz>thW6e|ffjZ$kUAr_;BK>&AU=ZLhmq_d9O-ybq82-`e~*@mtR- z<8WTFdCi08-{;m`a=o5g{D?dY{VMCjZ$Eob{`;Z*o;O==hux_={e1oYUx)19e!p?Y_WS=Q z-q!Daw5eV{7yIF;xNha6{W^JyYA9Y#VQEykh^cs<_^&w}LA~c+cWXTX?v=lh-utNu9C9=IM;b zhweq&&n=i#mAsxi?fTN6Q7ie@iSRtMvgLDJd`Q0BTqI=GIXBaChF%L(Pp)^WSL9wl zXW1;Ce`Mu3pKm)B{Et2D;j*S}^EHiywr2&!Yf{hH)Hjy8s#M>0Ds${{|63Sm*ZTCm z#O{Rm`%ixhz7$scZeRS56>8jZ%=+muy>0xJ3s>*wIp3os|5LqcV(0ZuKeGGfnnFDe zuP?7Wc1*hU+?K<4rvCnV?TS#>s-*vF602HM-=t1=x^;j5;rF{6EZ0_--mQ&{xpAV7 zbG^saUDE9nQ?5;TZS~~LWV6Qmi*yQ08O~fi!_($@L}*rq`TApXQbV6MS^hn8R^NSM z+2YtG3;)`G`g$jO?=*+0@2cNRykYp6UXpsUxcx-WdHrxhf2r>Eo-2RE_Hn7CEnI!! z?pLi7?;mA~FIuc{)O+L9?J|$cp3i^4zob&6X?viP15=#Ldar4l8d!Jgy#KKD_DA2W z)5V7If`54u&RZTe&Xg9@d+=>ajA>)@osR+A;sg_ocI>~!JtJ+=9*y;^rx=6I8|*(a z`K{ZseaUAgM@Zf(p|O^U;8Ydgk}h>-s2q0*sQH0+m|7Aulr+vdGkJ_q~&vO zGc9QejL~RyJb&+U(Uz=v<$OhzPRoCKiYhj*lCfof9`x>dg0Bhq|+@+2P# zQZX)J+L9+*ld2ppdF+IpPsqi4nQwNAR>tks0m6B#8$8s?~f_Be9k^2@+k${(ILuh#y}cgNZ0p-gJL zbgJZc>62SbCgiTVVSau^N|xfbh!$7nulHMTw@qBzqa`N%Y*|u?LS0}%N*HWvJ@Ir zmu6r3cu>!-#-c%U%KLTBug{q$Jbcz~x6>zzWpD1nxtPU{@Y zV@~_@MZ%?y>#1ns+vV5Aw0MPNiC=qFb8zXM%sXj`TW-o^-qPldQIyoUWF0VDOCqx9EW7s1WQmWn zcUenD-mGM}ZS~_tenrOLt^Tt&DjO$!X!x)?|LvKn7g)vFVy9M};o8cmzNQk;=miBzeio)6t92b zDiXEE`2RsEnW}z;n5!Z-!L!9LgjK)VUUT5qU2ad0BBg8G2Z97t50zV;oYEF_#v%XP zjgxFT@Oj&3e{$Z&%$JJEX!_Zt7(Kn^?1sF} z|GP`7BwMXzq}N6Jt}nUx*!`a2izf*VH*S<}i{3V=fJtV8(vhTk{nctK|9+Ucib3l3 zX^pd77ux6Ew>$CR)1f97v0GQe*-Ua%wy*S1SuFH2hu@Iz)QbO`*Zj~GowY__XII0N z?P`*&w)Z$@oVqJEvHs2z%(%9Pa%H6&oipy&TWl6 z%za(1cv@X!w4~9FxMK&(CutpQUfL!0`|ljV?3ap*9aT8}QV(P|-u!WD-<+DHEirYX zx9=owHcx%bEl~Tt*Wl;@H7%PyfzVEktjp@__a8gcG%-yhbJv~wEBtd~&$aGrtI)aj z^uwyig=LKQWz#elGFpqTxOZ@4LE@p6Y%}I}&1iYK{lT%-{wp#tZh27cFsL$Yer?+FY zTUVGZ%a2VLx82f@sAH~N*K{uATFfaXk!N!IYs)JW)xT!trN~@wofw?5VxhK_TQXw? z!_Bj9>suEl%Vg#MNGWt!F?aesnWRMD{`pm1;#RM#zns{!vZ>=XgUM|>$z}>fq(H;8z0GrQ>IGi_bXm_@~e54VDbMj zmsNAq+O`OVo4ubcT-~g<)o=L}kL}NYf1GtwNGU$6$a9(TlY0%b-`SRImJo{6{qjEf z{Itw)mFcqu)>bIf8a=N?P(@<;wY6io6_5 zYMiFs^2@!}!04_ri#uG!`l_k$ir30k?1DKyOhSe~7o2*;$6(EHIeoiWM{n~cshAn+ zmrZ39`0b37EPhN|xo`GCAu*Mi%jQ%|p5~CsFS)<|rtQY5EY1&vCeC|R_j7AXK;XiV z;|mo&>V!D1zApV$_mHoV;>0a0%zvj^Jipmfb**9Foo0?ZpJa?>gQUK^d#!D(JA2c& z#kW;&-i?=w`?F_a#J3{}*Is&Udaqz%ch{lBcTci{$%_4(L+343Y%Mp=wK*KJz-K;# z;(C2wj-yY`_X*$RRbBb@;Zg-fhw|nA^WLADc#E+~K;;-a--XJRma$s=pO`&LF8Fk1 z2wL-aW|xL)irb{wUNAUyJNeva+g#Pmo^MiWuf#WsWc;!wK@CnWSe+n&Ci`=qdt(bjHP)*>#pEyqJQ^rSxd>UO_ym-S2E zcIJ0H3%|VKIolDu+^@XL;L7v3#J&}tS3K`bbnf`JHF>L>yw$_piLWKi!dL^tf@4$S zH}Bl|E4J!W;EW|NzC0^wu3OJl>Z{T8ujs*Ysk4^dF=D%=YgVcV?sARUzR`K>u_er` zH{Z)IasQz_tybpo#4j9|zemNLXyu4lvz-5V*%RxUrw@asx+kxEkQLTky1P!XjgiT7 z!LfR&E#{xD3hIB=`+aBnL2H+v2mh>H^{4o~>%B+EUP`68#Qe6fzLGh8y66Vp+6n(k zulQ7C<@0aQDrK_$*6QrjsIJEUeeRUP??F}PuQRz^x@@FLw|;(4se17Ck=FB*sfszD&-M0*{Vr9Tt(*VMq~5C4l2vW) zhldW8EBdt!_BDL3(VS^=gw6WY`j?k;QsxUWYvutUSc#Wvjf?=F#EZXQavweo5&06!}OjoO|NO zC45__p6)pPk6$pxV5uYX^WUOGW^`+S;KCx;OH!WGrc|F^@#F9R*_lraW%o+PmQE5}(|q>+bA0RPNElxM7FM z*|R;WQ%>Gyt~zS-eMg=52hTUkT=Vy~F8*SD_C8O0vYp8Md9vEPCze|W*qHuXKQ+u^ z@w}zhZ@m_?&Rh2Bo|)YeH}NvRN9%-{Jj&Kded6GI5mxA8sA5paoy7A#a;ANA?0LO{ z)$cyrcipOX+M4<)BU@MQL%Is*j>o%MGAuq?tToAG|1-JcsEm&VC+o_)@1HJ@3~mWL z{Px=<{mp(WL_eP8e(UF6`CpK)OY(3=O61RH-{&=M7ZJZyG-q1!HXpu~l^ex2Cwx@1 zt)97iL7UW--#oR(Dn45>n4=%NIoADLd-$@7@FxvF)%DYMIEY-l>i=1Ol4w1(5|Ok0=J*%%~y?xn6-QP^X@*VGnyO$c>#U>t3d{nvqqJykKym=z6{`97x0JAN_|8KLFMqE4j-gHg5J>OqF zA$1Y=<8j*C<`xKi{3PWP|6udJdJeXO4c9}NG)ni@{N^=1dHLuJ2eU8h{S|smzdd}h zP^ma0M{a#^nR;)-yM+vg*P5+ON?TQPgSmf8RMe9N>P+*WdTPbV`iil!hVE8X|(~*fmk&%aifuVnf%396)J1cInJ}GrBnPsx%e!VS3E(8d){3M`4gpY*lIqPZoluMdr|nD?)RT9 zlgcvAY*hP_`TV*%d!|Z^-X{T>J4fDqS^RLDv#ZiJ4nK?g5=!fqg(W!evv-wSBg_P3L~}ui5UB>v=Nk=Kp_s>*Tx? zHqNO}-u`1N^N-!^Up{Cb=L^W47Qfg3hwO%FixZFT(B0*+P|0kD&Xm|hww|RdOSq=w zuRY4YQedb5ooV%@8AAWx$9OYpJo%@|yW&pNyEMi3Cod<3yPN!s-oB9O3tKa<6ECCO zjAy<@oUc^cwI{sLu52&wT6mu65z}7Io3Zcs3Re|hDpy#$TFP?r2a9{}6K8Lm-nDGI z>yE9n*tvApxgNHeef+;dOZz(Soon|-=Vy2;)SbK4w{6+0%gKxy?=p?23dLL(xv_PQ z-l|2RHn~Uj{xIyj-RLMjRXk(a``b>zddX*1swXq=Zs@(1eBtZEG%LPcW_2y$VKtk6 zFETJ+d{xF}@y~^u%daPTOYd}Q+j3cB%CbwdE|^_d5jszCQ<#!L{hP{nv;3DI`5Rq& zG+H=IlKcFF8G&7m44oHcYKm?z`gY=MoU`Lh-=eK&CVV+OV|)3EQn4Ug`y}Q&bDuX# zUwfVw7^k^$$9LW}yWNfL?nNDr;)wB3_+Th4)EYlck#p&MuG9%H!lb5c7F`!EXs|QY z-+7s6a&~rV+|B*PN48A58g)~Bk6GcK!%`*xEUgxLx8CMI_RHL-DevBd?(Lfu7cb7@ z3#d!ZpRggc`W~<2lM@qu?DSd7QQc@W{UWcJq1B9_Rk>fPF9{m+ex9d(v8r+T7KTJM zP6^kZ%?|a(2X#&QU%id67zmC6a2BH*!0thNi6(vr@GDSvjBaPw*GX&h<+) z^{i3U6!pX1sGsXO?C4(9^&);gcv^}ZEB*W&6<9w&tk1vV7{2J=Ae4ZoM z!bd7A9h~R6>R9$Ez5CpCqHp%Io~vp5G(MIq&Ewy@yZeC}>*nmA`xc@^Rs2^Ek(Y4yW4W* z{5vJ3bHdBNDsX6dJPF^cBC$V1d}_gix!TW4-fMC%v)!ncW#`wHGg{IsmOgS3DQS|k1mk+n|RP|`BJ^vmtJx0 z*d!;h+uK z@Vaa0S3eImN)CE)SMuU(iGPoi^W6TrvOYO5cecwTg_d&#b7wB||2ir6tO(B>%jZAO zu9XdWC{(ES>ikvV^!VRXyUa9NyUY1~GV~6tTBv4em305fA0z&J_rko#8;l-D+db6V zEHm$Amf5|&v%0nIvtvbDvs4ea#*8$1trcls_Pn-XJAdRE zOQ)IYvgQq!;wM$;cjOOgdRMY|>$-;UIr zsmC(q1CQ{u;Na}@OZHEao#^j>l(S`Xdh|@Gx+s>iG=X@X+%MfLCrGtqR<&EQ1%7dt z)%SY8BY3KmuD-|m-su{v`?SNC+_}GZ+w70t@2~$hXkB|{dG&&mpP#H)Ve7D(MdoPm zzw7bu&gFR;e4N%F)DZBjqv2crq_j(suG`PfpL{;sm|f|OOlHi9`WH*?)Ex}Z>UOKj zc3h{eHR0lt3maz5Yb;Ea>Ubr;v47(BTjd-a(th#5|KD#8o4)^S*TIMz=O%@&JFtD7 zqDpn>l}W$qZx`HO`LA5$f`@cf*fvhKHNQ)4ZerT8d744buBTzW``>fEb=i@<{M-`H zNy-c6%Li9feUrHwmAr0l)rK6!+SK%ASN#m+m)d>H_4`_sQ^i%cs5k$iOuqWcea2y1 zGZ>Co+Hcr+P9f_O|9sO4`)iKG8gF+u5x=)UD9hF3Nw8(*ch&UYrEhXsLmp-9%xH7{ zSa0~FPUp2u=4*iiCl|i>@0}$vQSajMh^;LPjNXJ_e(`y&$hHKdx)60~UJ=R5`-)ta za)--%SsF%~xG=kyi*9I~cYtTz9?ih4KT5x-&j4VN7uzv)|oX>~X&>yE1c$-OK50dk@Y~ z`dH<4m|6WxxQ6uG{+)rl!e+3Q-Rsw$u4Hq%)BNVPW6~%0rH00S5ZmKh?r<|Md~tZG z3g7hXKW7X5Vk9TNmVDwJ<9Th{?k?AibyCg8rW}n+R{yuje}6z=&N-)b`H34gKKl0C zv2no!HI{TE4E1&e>K-zE5MR=?(LMfwvyqg zSNisCtGoSR`NW^E6L(!tig<4MX`boXg&M0iolMA1{JBcjwd-5ODw`^WKWD{?7Vq`f zD9pGY^+U16XY<8pY-U&AR|*SRzSisBtgRc!xMa(JkEHpznfW_*=I%b%F(>oXPPw@r zKi1X9_g4n*>HENJAFrDN9L4?=-nx7yS8N8$DN+X{V&GyE)2hsx9H@0 zrIoYZpFSzkw3ls5>G~b@-*w|W^wUCibR_@WD*t@zZfm97>t9*9HnVb?*9wmy7qWOt@KpCxNSEx8&`@A5IKAm?pfxSS}d2PJR1} z&7XgX^7y~&acFzh-uV3i+q7-!8hR}Iv_CbOzf*hOd&zn6vBj5PTz;P)$6VH2c_2AI zXc(kHrwM+B6V4X|Zmdkvexl*EepS6#zqS1`ZC-;vdtM&(ykI@$ zn7|P(k>`6SuIOBN=k%p*BB!q8s&+7U7uI|Gb$p3y+f`NL>ayUV#8>&BvdW4tdJ6JY z7roI?N#&c6$R2arNMy^VXjgIjpL-lpr+u}~%>ET88tb;)+Ggui=EcoyS1K3Y5eZhGX0g6?Q(?wA2DyEgFXsIDxXk>h z;JhivAO5e&T3yuZ$HsMt>CSFR?=0)sV6!Qq;_1K4r*Zw6(;jprW8(UvOTO&Zlbo*{ z*4W74VP;(O^w#z6s`nNTtEL^;+z=YnyF<2+^Xr!PM)UMJXC1z}`P{_a1+P`V#Jtep zdK;t@7cCg}&&<}+tC;=DpVnFb%kOh8e;RaT3)jMbc|YwH_wAdqdP;E4cmD5Nx7PAG z-w6JwcE?t8mfhjd&P5s@N3yPu%OZ;w z+h;7tr-hccKWtui`rP9ii}?1QS-h}L#BSCX*@u-|FRO)htbAb8kUgpUjP(Vpda)@V zbEP`w|Co^WzV=~^a~hwdl!V`>l(NYGcQYQpm$Vl6d||Tn;pU@vXXkEc{C2hON><&{ zmG2rR7;!&7?pbzVvHFXrCJSX7%SCbx%0H#=Nz-2=dn3SkpUuou+sqkUbgIr2UOV0J z*6fF2l>6?Ml|`~%^Nr^fc-0syA_A+;^2erZ1V$E9*YJz;3VXE;E~>ACzD0zU#e4*(dJhb3gBgzl}Q& z3AgR2ax~SI`k|++b>n~hq~rhmUapR>zoFe)c7I7^mUjW~*XgqIfI@(V3(b-@K|Bv(cpz#(=D}EhaGk}+nVYb z-}A@n`m=qvpLpsj_}9Gtb6hZ0XwjqjMuES!d{)ogs^ubl$<{7-W&6Y(8#ovb&aAXL z_GmPcFUb5QP@jhT#{Yk$y>+@eHvm_hwUbcKxzgA*y z%hdM9nQ6Dm*1Wk?V^y%fz9d<4cK!zK53iYLh8%llwtB{eugm9ea@orIfI}d!Hu>D# zr+Q(hmavHN>{v75$g^3nJ4!;#A?c#U`D3yldN<2 zl2jMJ`VzDF3HM@sCacIjA0DZmalDfB=;ZtxXAH&9NwS~1vD+-px1voePW|NUMIwSn zx0^FOvpW9sqw_P*Ep^QPTnx**c=mV{gha-RzS`2o99Hfhd*G~}>9Stl|EPSv=z%DY>|~za{}U#+uG=H?bMc>~e*(ekhifYy9Jcm;yu#|W@%C#{ zUXqeIb0-B|kL*!SZkeiS=JR=<=aS?VZTshN744XOKlBQJ?zO*PdbY2<*sm>d{>1z; zrO7?2KMW^j-SynkWPC%;>(`lhgVtWbr_&YVlw!n#uQac{78N`zr{Y-TQuDhV^E`j0 zmzhTRw|~@Dov`@Kv0JP+YJZ9ETjcfPH9C$m#U*)>?!m*_iKAaY}Mq> zjrZO@e0*@b!esgGOD1I^n%+J-MbEdX<)@qrR?+0T^|pQyd-*4A*^6&Fx31;$pY%xY zcJynGnSDwjb#wIp^=Um!P@J*z(ET^z?Qy?L1I#XMx*=fsr|ILdE+yFwA4@n+Tx(Ci zaaZR4i&ND~YyLZ2dTqSX&1!|}z1^M68$*hImfsSYKX2VG9Z%`Zn0tZ;V{ZKUd^VYx#Th?9B*%G7t?aJH4)&78Vs*ym0?1mH&@V z?p(6|?K7T0hIPlT3hWdNUb5dSnXlVQ@viV+lhl%c=DokG^ybZwTj|tjb}O1mEp`jD zsC@Qv$1fNAU&;RyuXg(LVqL(tAGdlWOO`f79p%yS>Tdd2Yw=vKmG7He=+TN#%D9Th{(QyYnziuh zgvPZuGJ>lPd{<`jD84++BG|_9;rX-KMpZLK7AH@Wcy_!w$MCW3ljeE%-nO z#yNGdOZNq?)jOO|stEo0-#tss;^YP={>w+!73%Dn%deia>AZBPg^Wh=jhWBPtY5pg zFFAAF{=?zYXIa~BPL=vM-FyAJxXmkVJ~76{h?QrapB1%1m+RaMH?^-%Dg)&54HKMkqiX{yy=wrNb+ zCjKp8rf0#yJ!J`>&3x}KJ@+fZB;m?xA8w%)c|zJp?nQPl@~aE#jwlK@F3gSo|L)zT zzTfRDrdJ!Si7+&o%J}>1saIC#cCR&ctQ4ryuexBHd^>KLd9t|klNa`B-*0JZcwagz zGs{cKFDd@E_{_Dw`AaNvI64*@md=iSnOgLV-Rg-^VYlk7mcD{_d~Z%EZeQ;fC$7Gyp4;C3` za$dPZFx}fg+^LCwQiUCBPGFYWmFt(^zuKZU;o`hVt~YzQ&gqFTebnvw(-YP5ZpyTc zuDfqHKfZgnvdZS#v8!Se;|k_HHaTGB7d&yomI$Rj!GzjW{g7XuUccFM?e&tmd(77u z-C@u#obzSjT1lD9ub-@}*s-ml zrh`>sDb^etUpP8$&ggnNvGWCIZGmt+@6T6DnP(ZO7d9Jw|D1l8+i&LcuGNt}2af$w zvRl08deD!;2~+z&?iF8k?#|SNodS2xy>y>mE_0%G7He?lTVJaQe{W5{=$CwRk&@?k z`y1VNdk;>#tMTybM1hc~c~9;ank-<6Z2sP~h;7Q|<{1;e<^7PKCAcsBYf@Z&oxZDV z$E;$;z5n-aeCCUk#dbSuF|N46QMc72!@w3+8QZ9}QLA_#FTbU;gS}R1(T(5z zDtjb1u?qy+%w&?<9aH4J{DZ^vZ-U)lx6PK>$+&n1duz&{|0%z$gO2O3mWyBFQ4n-! zBj18eT5EJaY%Au!ulPEv^3sAgJjzb-#<#+L{=Cz=`F}%EM3=rxAGdzm(eg*ji@h1| zuaomR(|o+z{7%e#h35uGPkFw~^xxKdBJ*I<>kSNBuD;niak@dZbd}d`uR9wSJ>R8! z-m5~z>`VG8>5Ap&w_UT2HCf-uG-GMsj3OuH@I_mCOm6P(4|Wfn`KDaMV)umOrhvn5u=t7=XslrK*gDVg{k6`tEQ_G(M*@~h zqdytc?D8!A#AzP0dj9(SipiB(%#T7uPKW1*TP64!uUP*{@1@x1tyYhFS)!jW`1@J- zT=^V^5|fWVudj#`tlTUxd0*7oYj?QalOBq8w%O_Ycn~fvasK|7>$A%F4=E_DTON|l z9XJ2bJI(h0c{K;#Is7wxdYC0*Yg2f5fW_-qHLU9rxL@&o>M6Ktk;iuBV$c6+HH|6f znZL3;`0CevgQ-fpO;`RPgE)d|<%Nb7U1xcrbk{=(eTtjYTp z3jCWlt2}kDd}lvz7{i`N4;IAal$7V}UbEot=big4YtxG|^7iF_y^_6@{rorfBip^$ zrze#CX`lE^ZAxDE{%~fwDvnpr^P1mWUu3$XMxr)%;pVsDG?{rXjW529DxT-@rd0K)Ut>0_-HfJ- z-!A(-{F0O^TdmA7>-EH>*Xw&S4z^EF)#<5v%3J5i`1#&+ri6L!{dbP8ynNx&jjVf1 zdH2U$Q=i=JJ~euZ%Le|s)huEqsXH4_ZWga;=Hsrt`NKbG`er-c?FV=AZV=#qpe0>Y zHtX@^i$8goo^4^%Y;$@$egFHHch(r>zF~c${`>f;@TG#&MURRz#NOS_y*(yhlzGO} zjqiTXQRG&i&2=X>Gw4R^_x(bgQ`E~}i_JLKxT&yBBl;5Gk3*$X%UTl_PA-^j(W%;A zQQ5yzYX79zfc#bKKL-g^yf0B?E88~b(l&ASjXRDVj5sv4qGr0UaN^e}jgae;v^HmJrO+Z6XFD=?ehohPJ^_zr9xVU0 z{xxS_$j`~r{B9@SPg;}avQwV5ulql%Q;KuIwb?gsGqtaOZT$4RbL{Rg?MNGi=?)jT z{^FXg)8Lf95zF8w!PB<2%Vy?Ob?#k>uYE5}JAUiE&iqOrc?d4NU7s?35*l#{ic)8uGMC$W9F|&NVW+kavA06t`GMm-}UFrF6P_O;nWAd^8 zA~nIRJP$vy$1d+zU+S#M{=d2QT1L;m%I-P8vrn~dS$fX7mT7Ub^pziH(zfcgFH!Le z6pWcGx_Yhkrq@eWJl)P7)%hf)S2{hqrd8ZC&^uUEs_Wp(mPL8n%`e`Xb7rzfruP@M z@ao&1tUuy&vNyiD`*UeRj_8b+tUY;^xi`3bCJ6q!^L2Zqu*c)8rt{WuhwGOo-raxw zX{Gy9#*8Qr52vUDw(IV#OYN+k{`iXao&~F}Y^`_tIO|i5qSVIciGPoMyrMrLGE4Ky z%N@4g>=)^YL~dn17^Azb`g>oN*TaoUzKKU|^wNF5h(5@8$eLkpB*U>uJB4%dLWYYa zs`Iru*!bT|&d+(b>){H$61&u88V>sNE5Ft~zdoIF^0~g(CtDQMRqb1@o6GI|V6rZ2 z!am0j9M5kYVXNG`@UM4=c3tDG%O<7#ZIXwgTLpq&)LyZE=6`#G&n|(ejWfOlmn~-A zaE4*Indf<Ux^?&QR^M?c;Eci3p5`9_=5O4;|>g?n?gS&U{b+c?8b z)SzU}Tn?Z9{VxK}{FU0|F?W(>SB<&nb))w3PD4}^Kwg>F*_ARXa*uBX=^0mrV z$J(^!FCE`!{M6lXASSzQk)s`p_80T=x9v0bs&$|GdiDRj^=GH;+Q;>}>>8Wa)lIKf zs3fnS%h<~2V`br;JX@+~TYkpcx&zu_HFn1TCco$jabo-07yP3}|JvdUj9Vw|`}oxK zRzRq~c3Idz=1zs}M_(%U#zfY?tQ8IJ&9MOWui)hEZF(OS@Q&WKMKALdtJq3XXqGHu}|jL z`@G*9k6qg%8Kk^E^CH`v#&-{ERV)MC>eD{Ha`*eF)O_kiow>^7RK&4O1R?DNRb#?2eGx48K zW@;6gG463okC)NgH~G>!|4nb3PFCDF8PoFf;gy~4`!3cU3HWsF-B0`a3jffj*w$(=AGuvF}kWayqf^78?XEo$a8z#Fma!++upQd#%P;^&O zll8#`>Qk-p+`0m$tXZ2S+0!}Z=}(@mXj1#__%A8fLe0DnbMn*XXY;8w)ae-oEn1!bZn@cm zz&%$sfBQaTUpDtMme(Koy1C|GP~IF~P%L0on3raJXzu-tFu!$qToZ zJTSetxuC{0V75(D)1TXgJXxIjuh@3$PUd|4=i=d>-ECj?i}W@Gym=WiTVrzY#7n={ z%HDKvEHnBv>b*J$j=D5SLd%lIst>Lbz*qZ-I^V8;6pAv3e zf`+%Wpe0{60={Oqwvypxi5Ok|%4(2eEru*B*%-`Zrl+CiC{qvwOGH zTsm{S|0MU0TZfkJYE}`{KX<|R!^xKY-;|8QP3>;YmQYqqtUI%8@!w4v-fZphK@W?| z>@WL$>bZT-E2ZVkgAYNh^Jc%4|9a|g1=mlng!Ws;OgEzHm)HA!-yHcu`?;v-45bFs zQ|F#-RC|>5?Y72Ly%d*XzL!g~H&m7c@rf5EpM7#H(TROXoG@Tzrve1d#Mwz_4a?1zPshXoX=YlK0KcD^LWYsSxF0T zf7vig$o$^@9qQ+}15aQ5^Gv+w=7}f!+A8C1->v;!#B%Ud@$0-#>;0IEUPKo zV6<@Kn&k!88;)4)`SUPvT2T_K+m#t2alDiEvn!Ppul%>XaNPmR1dcNKXOq6UrAR%V zJVia-_oPpA!5X)Y@O$~`QeJsaj85>~_tLo$oa`sFZnMRsTs!lW(DC6OGGMrk<1ZmzllcNqB+S%*so9F7TO!sLYzXYEH{9 zc855&-(E@YAI%m|WxU&LlDzAz*uu^UevX`nZ$65RU$l#lEj4@fpMU>;tM2dj(E7m0 zGV^K43*VM=mT!wMc(eZZSe|j_n&IOTT>v*R$RI7a6^*o|$9}E9fpEse7 zrI8QMY+#bl4!-&)a%zt7`~$9hoKIK(`ZsaEt(~(C-@}8IUioJi`QI&Re0Q!{u+4aT zZ_RTTVMoqGX+Cv!@2AEG)?R$WeYa!L*MxiR$tH&u-89b1x0&AXA=YJvaA&ua-Y#$R z+AYc_?>zm_nmGODy`Qg~ZWj6e&YAb+vdkr+saKXgIsAXxfd|r)*M+TSKGplat>xJ4 zoeNeTVN~T>a&#e!V{89~lm-7ZY^9$4J#Ak$;m{`EPL5M)+gsS`*-dV;SS$VdT)v&} z#7E^{-DjOvrtI3B-0K{>L-E>_U&q|PTynbZ^^`kHB3tSCdjABsFizRPojzOiw=Vs> zqwRc9@}mzLab}jb`j5Q!aSBY@vw)%X`w@Px#Op`PQlgh%-`&!_*i?DLR@vDWlf+MaeXwc9eEVN&Jf;$923>YH z($exyc)w_8dvos6t0&7%{s^veyP@~;Q&qv*po8|lWxpK#uPAQ{FO?4M-?;qLSEh)c zf=l-m@^#ENcw*vGoy?J^_-ex41BRi6dt~|2J@#$8^8QWJecAArb5j%?)t4Rg|J)KD zAGRj#z65>@7l-w z>mP_Z+XULQFMrafbZ}Y5;=k?rJ5-lVKE3JYx+4j9TjQf*H#)!EY&&(XS^lF>Q#2pj zyQ;g@Y)Wglcvs5#>-TC?oh~!46#*Hpb9b3{O+L-+!f@Z2^~bNm2v^R9v&zehV`C2e z`mwr?`_QM^pYm6qDcV?-eABGZ{*>_Co}NvS($_8rwS9c_gT--gr|R;955La;?H4B1 zc)6&#_o0pMhm;=yp2B(Mtmq_jy2C{4e-ynQ6f#kkOX^lQTM5&Gwy`U6&TN_=`Y~WMz2j zQ7!q5J0a;B+WIn27cltGm)mRQvE#})FSFqFMs?nkm48X+W%El-P)IR3@yL5dg~`vJ zp6a+WDqjz8^5@*UKh5cB+f%Z#S9q8)hHWi+oq8vzzmRu3Gt;rA?Td0J z&irAwd1LRUx;jG zp>cZew8itq?rVqL)=f-xc7An!PQEMC)GwEcGw1c$_C1^F;H(+>cFFRaY^r|1 z`X%mv#_My!=e{@e|Cpe%C}roF3B|upZ`m`f2tR$&q1nGQaMk}i4=1c@I}~x2b@4_0_xAP|UPeA^H!GT%$Sre{-NV_> z!~5ZOiy3*(Cw_2}3OHOc-7)AC@5045F24*|xLNC@fOnQ$NaOn_F1j~3R8Kor?|obQ zitAz(`}fud%y%>Y9_5;JD8}6V`pL{&^YJY$TIRu!9hltFQq`JR5)NlOm4 znZE8@x-~F@@Ai~TgR+YU!bDD6?%B7~cTZaFg|9Q0BzsiqT7*YMUJI~hVo-EWs;#-c zXVT;frH!9Xxn!RBWGtt##9({WovWvk%QHW{Fj=ahw8nHomJgq%x@_&9EdJ=@9MR&J zZ$IPKHcvLlc(-uHrsGyXW{e zp`Wtm73b2td9X&~W>#BV~NlGwzZ9`p6ZWQ$pmWJ}SagJX;`H5w+yXj<{K)Mm~4@NVCor8;-Rv;)tcWiESV;j-C3_ym`H zb9YSAmG*hN9kM>WZn8e|C&;M2VT0`?ckknQ(mT{oO=Vgr_|mpT^~+186D2d&nLjQH zShv^nV$T}E8(oLyFb6-op>J>}ukzrvZA<@fUt9Kl)>q@|Z;Dn6O?s9}9yoi#HRsu> zLv9I^$|t^w6OYr$cXvJPT)gj;%JTd~VZE(pdY4pXS}R=Ucz*n`-~u=E>e!NHGRu4T zFE81+@$J@<_Sbi&TRr_Ty)e-s zy0VF<OIi4*fKQ3UUGxh`d7M}Z>K0v5%Aupar^RpRzbf#T;7j)82YBooGRkc&3l$n zH)iGu+hz{AfbKh*S`2Gjd2LS2UzV9H!krefruwPNL5)Wz&I?}cx)-|lC4a--aCrwG zz8v4p%RhYaOt7@+{fF8DI7mB^w&X+?v$G+_^qeS?j##YTa)li{^yQ4Z9H* z(7fvZneds)>ECb9)2xt6Ik3mCXS=57ySGeJxt8s|y~IJRH}l@-F9{45+L@oPg>GD= zVHvycirIrZiMltmcds@&*0L!h!}s)$2TVWyUf}$5=kEpXI?+GRYrIO2KR&d^vN5;$ zJKKVz0s>9TtP=FDZ=S**wS4R3_un6fb${e!D7oYCwsr0P2diox#qGEebf-)3yUxvU zc?NeUyNBmBZJP`ESb8{pt_W{9z($menr<;v8r!$Gg_8u!+&Gzyp z{y(#3XBvI>Eq~6S^m9?55E=bX+J=!s@HF!!KtsUw4l>_yMX%Z~+V>~gIuoMfM-_Kk}(Lsv4^ zB2JB=CgYjPrtB*-en-lNPmtTGtgdo&8{21rUvF}1^}cQK4L7`W+~|OuXsP_8`u^6) zm$sKb-HHjgvt(v*WW<8CbBdkgKQEuWAnN@F_s^R|4MT$;X5O^syuEH!kh_Xf>BFA- zxQVBH&(3FieJZ7d{bwuhqFGPh$@1pR63sZjFPDea>WiJYx9K_6_F09W-c08?H@*1F zwEdMKb_}0R#GU?OOmWUic*>+wrQ*5^+M8kZCw7I+*#U+7M@%1I~YlYWUyb{gBt zur*wYR=-zy>3iSL6E}s;dhBKvhr6<^U9SJf(0av8^Rv7;osE{O7k-(&ec{Zf*Wb&Z zS<-U3{n`T+nYhU4xU>z*pG!A*vNR-Ss(0l7a5WeGvA%i2YWcjCQV*8)FA=oQYY#oN z-?Z9FfnR&hndE)fufNqiC6h7n^}RKf?mtW#;!CSEI0Mp8?2=Pn=4zI{sq{cwcIWpN z=O~jf^&93YJK4i5y5^ZD#dw^r5MSv!$)u~@pxAAV8@pTaiT3-qgQpjqaWrV)owD{t z$&(7(yb}WF>si&G{+)PH^V|L}b~U#fXL{)^4_SR&P~)z~7j{muJof{+6(_z)b2M%| zY|OGk@P1>z6zd<475+k%@m4cdoSA>MMXbT(w%G1X_nxP`DqDEKbJr7TS8lacHvX@Z zx9xb`yL9QH)DLQ=?-}l>IHfGTw)tPj*W*!wzWeyazOOXs@#<9-JIME1Z{wdw0{gA+ z*YWfzq})H@zWHy8F_OggYDa^jXYY1t&%1P!k8*}Z-JOMg5&y-Pq+DeU*sWSDbQW|^P&Hw7V8NYX0>>3pX0gf`_Zk>mp8^5FP|&wXA?GA zrsa)oRuhxYRjx11B0(>F<*o9c{$6)P*fZ!3i}1xQ9}SO~Og!;hCBen@u=Lw*5u3B? zSzq!fxJws2*?i~avr8`T?r(hgxJqU5za2k6Okc^y5nIDCFD=lGbR{>J2j-Nm=?On7Ai{d1o6B=*1Y=}e+U8r+dgq#NmQBsmeZR=O z%-?v?+TIoho5Rrx50xcrKbBiPS2>e8A^4OgYmm;lc@GwwI9E?p5zEbsVM{+LHoNw> z_OF_SyFwalidnM6+ux=9*NC}RKFQUE%T8XcFm=}n?SzviLAh`Kaqv&A&)Zx!$GXqz zi+8Hl4fU#T*?bOGriCvGt*)I2u(-NwMfTU`$})!y&v@U5N3`;On>hd6Px;Jq*6aJG z6#vLG&Q@J>lXGFhA(!26W?V9_yvtTEreDiqbl-Jj>-rC6Z&pX{IJb1w9W+~e>w9?)#K?#*SBl?7xvqlpUW->q+i%j_JU_51yfvnU*wUbMqfgwK7; z-~30*;|@*>ei>zxX7ebzz2#Z(yD4l5GCg-+q%VH<@|BC!&X+&-tO$-}%4XA%t@80c zA<}tu68rSbna?D{mmQoq<0XsScE{Z9r%o6BQVHtgRqGXz{_)RH)7`c}WL|hw>i@nC zeA`Ty$NQT6yeQEdeD3L#olBWw)H|auoPSm1A27F+r*`(WXwCPFcXK@8IsD;+>&_SH zi_h2@UNXs8vhTcQJnOW1V&N~7BbO#xhKRlMdmpT?>iTpQf8DH^8SGL!W*BKk>c_uq znqV~J{-!FQ=2tFPou72+@!mCX_^~0hTTb-Vw_E2`H!k>f-XbyK)b$q|6K?F9_toZF zg=NBaju|&sc}+92KcZe5wcK4NX2G2GkG8OK2`hJ7>}$O*Dxf!`IcY`N9?N%C`+DAn z$d)vzPhRToVD{o~^u}$;O3{LfM>pm_H<F+rM0|n{NFye0@nqUqq`tgXLb? z9?K2VZg<_DH|n~as?3jQ{plJTbac7B|91ITmfw#bjAzV$_H)DKk6S;yacvAT@>Y9n z{yKt@ebTA5R*z~=PW*h%K81yA-Q`X1i;qW(1guLboip#Q_6lK#yxlFIo-2Awy>>iN zv;AWC?pq8zD=$YInkXN8kYlKSwb8syy)w%_R<(jPy|`8@;>OH~2VKQFx6P{jrj{00 z)Z4RlT#i`fufIq~j4y0$huKBz(n*u*1S+;n%xa$Y%23jj;n$6vwU2*jdVSjQe@7}K zLrKTR16dP;r*LpxJQ%dq?Eb@&!;}A*NW}6hHq^H0W=C}v$<|&ywrIuOWe;j=B6ZXr z+ImvEax)6;%G(c|h@yzYwa$(|l_-lcWor0g|uJRR)s%mX+4 z)X4Ug3ekTu^H+|~4(WsKSEir2^k~JGJbtsV<-GxuVeQKLmR%Ej&VGTBkJ@jb+-Mf z-aX;sRzBu@JEv(&)Mquv*1PmhHxxLy)a#0v=y%hQ`W6vX&h>kDivU%rr~adyyT*rhnq>_MB#Ip)4o&b3R-=oK=_aEmGjHSmC|s zt4Cqz)2=rAOwFv*9(JqSwY)MTu5|Y-FF9+;^)YVepXi|2h@T;zh8j7|CKGC|C>tnD zHmK9Q+_Bd7e~tRjDJv9npWiqp=i1+TW~pS<`VhODJI*qnkiAg*x%qIIy5AP&FHIAA zZM4egs|WtDN-#ETxcf(Gw&XRRP@6r?wd=oLe=oCe!j4O4CW)wCv(=1L$X~p#_{_BR znr2!G9p=q<+*jY867#mSFG6>zujQM(!yjeu-Pkf~qQa|L{g&cx0@e*Xcb-&;`dYOz z@Y5vk%9YXgXSdHudojh@^Y&G)jlSB!cgx>c-@INJa`IDc#P(B-yWecS^C-KFIp5@H!aTU#5r7ZfEGI*-y=FeHT;b`cc)Bo+GZ{)J&f0@Rv#jspC zAmyhw&js!MY#xlVhxNlXXC6ou^K3`^mgF=(hfX zUB9K7mz_T-_u=8*aE1xBd4Zo?9eLVzzn#gNdt9|=|Emff1(``{e}$%-B>s9GWwK=V zJqba*kgmTj4R6VO3H0j){&1FQ3i$x~))T_c=YWb-tEotwi=bkus0o z@j^O6<9PR^7XAaaliqUwP^o_ZG=F)W)t8L_4|WU9pP(1BalwP! z>CLB0zs4jr|I@76WhJ*ond3{fQ%~=)euEV=J^rbvw6(L`I%uS_D=1{A|Av=~1ly+i zI4V3la77SPpZ;j@dvW}` z>0H+={pjVQ*3L{(*Gj+z?r`O(a9A(y;{%Pvl_S;=Azf@)`Cz-_ePygHC7rFW7%?(sw$+(cc^5WMUi^@CTH7K8uEwJdEe#C}?7KM*xSvd_Q8s03omJlG zTP9o2aAvU>gTs_S*_jsK)uI=(J->T))kmpIudY>HI;0sfA*Z!gps-~Lk8-i*quY)D zzj7OYJG^hBhL&x0jK-`V>qu zqGPLZyXf7HD~Ea0*ByIsQ*Pmo=_?IuzigXqmB*r#v2TWGZ((`CWXo%lrcU;Zkeevo zWmRI`Riu9Ih@r~u2l^|d=gfU~d6o2rZK990y_}`4IKTXOM^yM=?4qwbjdSH536bn}?;jIe`g zr&U-N-uQiGzuTE=raXlm2W6ut8h?*!@syB>3i^7L=Vju28HPn>5!3jJS86hrDeSA@ zFWFZ7cA}!aloadM^C=e(a{S%?WD$$XeUj zaut2IO8!WF)5*`cUG>Ruk>QF3gD45yg92~c5m)1&I|JK z1&lu*{HSJ`^J#;r@E)Q4Ti#62=i-yMksCX{zR>yYvd zUvyhraR0$MDz2xNe_ZzF*srPA(yY=NRNDG$zUjX#V_;Pm+G78^Y|&eOy{A2$Tg{&~ z*mj=xwn|@fB=WNP>tF3BdR0EX4DYk}%dGADEuts)W9I5pm$v$z6t?q;$^Ba=9jAT7 zsO+5W;W<5TqO4|ke!hS4!snCzucv)fnG@)rpCs|)Pm`_f^ELSnF_JGkW&pmN6&OtKDbVVrNUU z?`^XyW13wx&GVYIyHD}S`1?Km>$$hqML0c**8TYICChtLK;VL?zw1#=O)i3>-0XTyz0C1;J~$| zBK}ez7(Aj^@TZ;k3|sr_=d+^{DvW*aH_cz%tD&a;=)lf@4vRN^2%S4|tASI8pJ_#M z*oFp;rJuh&keHj3P@uBXobCAP7i=-FO&Rqh^BN}wMm}VWO?vW7C^vGmf?L(4>ob=b zhZdFDt7R11Z`4jT;hSpHm18b(P*(KYmB-BGIY|?*F3SEL)Ti;#I?Rsah~TtGQ_|YA zf8X=Hx6fjdQtbpu&+Rt?5B_#N-D34qB;kVomy9iQpZ#N(eYnq-b?=?LyYJ&oYGRvv zj?9TuJL8_Y^_)Thd**YI_Rfk~3}SJja-R1tukd=l?*Tv0?2y~LcItfLe9yp=HfiR$ z7rOpJv!1Uk=aWu&w!>KYQcQ6FbGL8lp6)Bd>?iNwvtnO$LqxSIdwS`?DZIvqbIosf zwB@9)dhKw)zUsnHr!RTByZ_nWwqcDnKl0=2U*>t0=Qb#xxyY7q_f(9^YF^gf%!JgylY?d7nT+*!Fi)NIp6nfXK&Ea%w!s4{%YI*%Be$OSttUs^H z{Qfp;&o+sU%^TKTE7Vw@+jZ9NZ@~(iOKOdJ!mhl(qZk7@RPSmT9eGgmyIf||ZSIqi z8IS!I><)gu@xTH;yS1^4^3EB2w|iRskNFqpIyM`Y&AZ9c2LMO?@Jm}wQuw-W;Scw>14Xtxb|5?@r`>P zA5E;BuJ2My`nm1op)i3(C!)jn=W|G%oVy_9`C*0x-ay+WwHwTKh%ZlH8u(10efiG@ z^Iuu*%ty{nyw|4j>ea5}MP;qlGSmNDeYeYL-R6#2f7WL5O!j6^;5^Ujap#Hz;}S3T z&o7@Cq_@0&FeAqCVnzR9iNo2c;bkg7W{p(-d>3BWWc;DQ&GCW76#8uNP*{6N>c%(0QC&}`^hFt8|Sw{># z_fNBlI(WwRe*O(x|I?whh7&yFIX_-^Y%jfRP_wh{jlj0zsyj!v&7Y`ri1otr=grId zTTUJ*T6CU$(ywIpU4JK^e*T}=)H&d3?ha!M=aMX6rkEEy`(3|nzcfGYM{xP|+O*{+Riz=mqyLK8`=7 zaN2Zoh+u+*x_h4Y`$89giK0CwU7NNld90VMdS5fYS#bI9pr1!LH=17*d=%lopn3j6 z!vnXPUh2tk{JT|UP?|4gax%^Au8{5*;qxZ9KM3SX$h@@5xEiYRd*8d0)8tOA{*-@8 zvUX3}g?^tnF3swq6E`|C9j~w1?#0>tlu5RzOXXqdZqH`{tb$i29(1nNNz^NOUeR!* z&4t4vnA76*1mgxr`>w!*hO8h5U3Z(@*IkXq$> z{k-JXg7sGOI2gTxcqiP86K#JYUq0#8fsBg>ZeP9>+jvS@>e%NgYr_5RWHv83ZrpTo zMbDB=idqZZpIqB9<-=T^gLDb`W9k-Ot2=l+-%ElI_zV&`t}`*_&Y)Ja*hMR0-z z&myD4woe>ptP^K!HxT-LiuZ4RW2q-}_J(i<}O>c%2ViISiNf5>u9vw zsq1b^Z&JJP&eNXW?*zU}2p8=9!?HCt=i9u0F_$^(OFr}1Bwj1pe@`{7;asr)-dPKR z!q$DNeXO+c!Q5pHr6$uB*6duk^v&5P28@@uKDO?YGuY+xbME`Cnpf7X^1AX<_vBH- zoF55Qd6B8{V!eTjeb*e=vhI99kxoVU8>tMYlegYE^`{;%s@&fAl;K6{G8MnSOB{|Z z%HI*N*YGl553hgDFShloCR^N8eILGloibeCbZjF~rm2KPswJcHBT+rMf>{15g{je6VVq425q1pAz21zyTu zQ_rzlwHiK@6mVLe8lcL0^F!YO;|Z4&#O79AHd^~Ul)3A@T+*Lt4n-St_j=w`)7n|Q zbzdVN^f(t7t#4?U%cLsI<-S?9YSo6l`#-FIx~NHfpJDbE|H+Tj6q{$ASurcm@!iM% z!z}Di(^VMfKb@=${mxZ0}3n`|)^t@;Z%IExWc)zMc8#;Tbud<4snd zJuPR-@TQ)gvZQgsPv!$QE=RlPlrpV!FSx!z>F)e1A@-?}yY^l%Wp0^N9`#HrsW{r- zqx4R~Mp;jfWz!bkeffAIzGxjahoaP~VPntRG zOH|m2Dkj;C8@e{WITzwSIOji-S$}-X{=~*op>0eodsfZijL&F(y5|Cy=RUV@i8t3c zaqhfQrh6oKo${@%4-SaEyOnw*%sjdHe5<%mW7@Z~N@}0WOBwG8?r1r&6 z=4bp?Kl^WX5dWG2}ja~I$ZT+4@C*L1Ql$LSc?Wy-{k(2*NlVe~1C|5@K zUaiXO+K{zTZslKxq!sGwiwaG9%2a*+&5SnaR!jPSp8Jrr`=0<$?(i#SC!a6d^ecYb z|DU;!^NjA?7iD}Bw*JghF4H`toJ%TZC5ye+`u3XJ>Ag=E+8>;>{PRqg{~tfwl%4Ld zoRj9MwdxYT;mq$#Gc;sVE4T#u);ILMiB=Mt$TR!iss|E{ju%4@nF+5Bmy$bWb?>J4 zmurt!+l01V&pGvEuWqcz8SyFG%_fDI6^RO6iaWSW&a5rRbNAwe-5)1B{#s)Nt|&!n~5I!3qb|LpCubUHcd zjiGMs=pJhbq z6oc6~%)dx97O0pWWHeWZHOpD~Mr_Zb)E^nA;<$}e*9ePm&V6_^Ln&pcn3}p{%MFWZ zoiaCtr{r$SuB$fqbH4YM<{GuL=k{nUniD7FBIwwkbeHL^vabA2&zy+YTNWLS^5j^x zO?;AkUvzEy#Neab6ofbvBv1V;?`ipR;hf6$%!Nf$zEmeh2FEd9`88?FwSDEa>TYHN zFKZK8ubsT^`1V20`Nv^)ZhH=h>}pZv*zcEL53tlD`bmrN$%g7^_~BdLeGptT8(GgFJ<;Jcy+%mQQy#`VR(Px znF;DEq$k{7w7Kj|K+xsv@>kb?9ZQOuu$0Fx>bmf)Dw}(qFVi0%@qCfgEw^y{%ryox zYZ~_W7~L=TKcTy|@6n&cDNlVx!dHyaqH4ui}LR6o*%5nGO2w2 z%H!v5y|Y@gaDK3!z%oJOt8#mpa?39-o40vG9=CJ-w^QlnZzl@eUH3Rlu4DEdc{z`l zO|@q>eOYobXD`!2iL(2<|9%qHa5GxPd4Jl@a}hn6 z3sN?&+?l+?ae~i<`6rliQ<*j%E5FPA)pG9ru2j=AHy5lpQp*!_@Ac&`KF8y;Znb>- z5!K(8;D3kZj-s{SpO^{1Ec(};e%GDEyYYwJgFUaTg@rRcA%tYT09#9JI|-hB7I zwvRVE=fZlc>W=t-!Nyni@4TMw@>=>0i-5@d=|A0*Hm^AH=1BIO+&y2X^c*_*tZU7= z-b%-Rj^-6&5}y)l|8ng;VreCyG36w0%-Z)!v2EYlnB`{w+j(xM=;Xc)jPZXTJ$u$@ zTk^_$+1?XXdRevpM@y7nM9un?9@2R-jL+{ul)+BLLqSfeDo5sVC~c4p^ocP@aQ~k) z*YuY6iV!{F;}bt!>=*A^KjTO$S3vviQwKk)O)Je;`{B;ZzQp0@nqpR_`*cRx4(UfHox=`YzAbxq=c;KSK>3vbyS+;Xh^E#nJz zM+Ou7O*Lm3a$W0$Cw`uylFwnmlY3X_zV^M_Ra;kBb8$VJR4d|eLDK!wPJ>%*VJ(k! zZfobfb=}%|Y>v)OyN4f*7xk^n(nzn)+cfoS^0U0^;^XW0CjEPmFR;?^%jxSZb~UTZ zdeyeu83xBD2F$pZ>Jh)q+*d!fK2AdM4dU_?^REWYRAu{Jm5vdu7>QOYxVUg+80UulwH%Qe&Ck=n`Q;l5WU9=z6l z%sSd+dxCV(byh?F=wBaI-g>POn5k!Yl>Is5z~nfd&&4+~ZK*FKo`S6EA;v!cn$RyM3UJ^Ph?-cj>cw^lq-cJ!^yE;43Uvvo7h zTUuK`&1<%X!Ni7iVMm|Pe`_Ac=8Bpw!ESlA@X)#-pVo=k4>wY)szPE1$P4PU(17wa9A8pH9BLuRez-c~4oFYF+$j60>yvCQa7Vuj$`)l|1FFv!oX|G~X2V zn`g0ZBV(9d;mL=uWnO>g``699M8I4|Wv6F{++?=zau0t8uQ{weIM?APxNc#8r!4F z7e&~w*Qc2Th+UrjrhSfjP$+V%F5ah!)!lQYTKlTb;O)Mr?V>+@sC)2+Lus|> z)Rd{yZA+MBC3nugzsusTYT=HZcHzvM%WV_CQE?TRR; z8BbTG2aC@9UgfIaN-iNCG+#HUg%fIXbpCK z|M+FZD%r*vk2inhSu#&1YS)DAn_lYIcnN<{{vxWf%2z<}#{66@hrd44uGWQ3H&7~_ zYdZPNlC?%1o?zXhae`5YA)BbaneYWSB!q*F=7Yo#JY9}jdKP`^0w~?Qw$$EtI z3g_duf=9F(b*07HXO|sZpxCb6a5+Vxtg|_3*_HJ6_KACjHDkaZoQy# z_ejoD#)H54k9+XkysN}E6&s6IwIdE!);-ySK-Pu{kxojr|9^1}zHYzq(H*m9%qQ|`DZ_>pl zpIN=j|MYc>WPPq5M*>e4FHnADe)fJR>va3`IcHCsl%4p0zBhPJ5Ut*_^& z<+&VWK6HFWwbz8TO8d^7>bn&;@xsl=eHzo3a^^o;Tp4a*^5M|qnd{DWzg}muB=rIF zWQ9Y9dtsS9esZn*lDM|O z-MlJ`t%?L%7G!D9$JAbYBrPA&1vnQXbs;sKidn-75JDd1c>n;0V_?!|pSv9kz@rQ

0SC)X%PSjGG-u$l3B@2YPtAKe}Xl&RdCa549_?W^7k zX$#L--2KYv-XD~CyGeqtq^K`_|LZevtuL@{ao1J7=5%$NlZ$F|=&3)8|LGPe|BLxF z`9qnL?*+r+I45?=EgP4G{=4_H<>5Q8t$oHzzD|}{C-V93C%?k}2TyLK-A$95CVQLj zP5P%jvujK@S;l^o&%3Omdh^NLDH&T%$Db~K>N&-<;!mAHD&vtvyTf~m!&-#uYo69< zNME`iw(Y0PYaXGf+cipZMTKIL<EU|uZa+f%3|2-6FYxfTq%p!oj`8g zv+hoRgI@+sII_s!yzQvL(!J-)R_0tgBkAsW$-(8kT(<+q;)=gJf(xHFm`%JceB;Y5 zQ~8R!Yt}k#d9#5_{6*)zzT);szNO!UKRige_m1g#Le1IjpI=nFvz<6AojJ|zdQ`|3 zb@x{0*9EN-mzEr4XuKiWkRzdB$Dpd^SDk$H|9MG6wbI;YGq^dkHgA5iEXvyZ2mj;c z{Op;br{i8+pJFEv_%f$e{ngnHtJW{u^`{raELv77o9_Plx|W8HrgG_;+3FV<_r5uJ z=uLfqwT<)acmDRKa>XsL{&7Bj`B~$2z0J*~*)t9t(b@ZLORzx1LT}IYD;@smb^Awp zas_?UKDp)X#Pf^FlO-8WEc6U8zu%kkI(F86uVqmdN>u^uf6an<85zDP*ULRlo~}@E zVAqA%cLk}TO1~~wWaTAU?kKf9=eEdk@6XOV7ayK{0@^t{2G6&G=-DQvD@BXd%xd(UDoMm21Y8iaVvt{ z)I9asE&aq7@pq?mh?}fBxb{lnkMCudjk(@jEaQ!McINR1cNLL)hF9x(IkoQ2yk|Fc z=e$jgwkeaQKjg5PX7gjW!_`NZ+V0zV2KJkl_kQ@tVBhiYf~;M{a6UF^i3HRbZ zm~^)FhJ3V{;Wk<9ZOO^P>h|`nOv$T$J8!ua^ytwU{#*Komd(|eFS>)Tt0q6wO?S%G z)yJ>inOI|Zf%V(DGrF&1mH*mT?D%fxb9vgbcCO4Pb=UQ)UME@3mvKM%^mS2K+tkHc zta(@Uxx6143QT^fBPK7iXYbS1;#;%7e7(Ce%Hi6jQwQ5l6!^0}XU%W$E11Wn&Z)v_ zAYnag``#Fbqt|6S*LfW-a`!l`(S3+1tn|n;b+hkzD$6Ie+2?Y1#T?wv^j=FgJ$3cbX(0|3PD`htSC*k58!_?e!6oNIN3wdG1{F zcJJ?34lYg&QNI_w;aQQ##qMQ|cK2UvTORUL3w}R6bRzr1i!b>j9_)PWWx@H+F(dfr zgS3;o7OXpYh&NBnUhki6R8!opm&ZAl^;x}#Q$xAfcNdF)ML z8~Plt95{FVdz{j}$?C@C?U_yyTa9al8ClvE?A~VVde~{f!mOaAsl3~2=Ps~2|4cOT zY}$D_Y2J9*5Ut#er;nUC7uun}ezMu>BMfOh*&+*Ad}c~mTj?FiV6p01ko=<4h%0&T zy24K#(-xlBxp{t0fY|H+xybqAHw_~4%a(i(su3vN=A;>UIAu*AAK#45i8r{jr`>%y zJ$?Q3cwOOcqnQtONzY?3V7bOvU@!XP+um*a`V_K`iZxrUa*8SCcoBOhq=yK=E=vwG2qM{(LO zmd&2Nc~$B~KR4S4>Cpxsr~tEPlfHZCN7vib<#cSO?5(r zQxo*LT|X@O-lw@!tMuB}W6GLg|GrMYZvAj-l=ts7ac`=(FQ3G^=<-c2hN(gaU&e;6 z;<}%hpk?>|!<^sYPFEIPetv@GrOow@eXruHR2C=)oxbdqW_|AP>-|g|70#_Y7Ju}) z{PeBvP5xt18zEY9?JMY)uFK6^G%v<(mSJBqSw|2_g&OS;E*Lc(SsXBg1t(igd!!LVp z8k~B=lQXei_1;q^kDCe4k9{bvX5;SsU3q!6{^n%H-MO#Y7yU4(ny9HG8)EolpFCHn zB)9gK%Q^qvKHP4xF6v9=oziokf1H-lFlXKC`=jY%bBch?m47yjJJg!D$Y$_$%>TV} z^*jA%njTV`lNKdOEOaZBKK=FlA08QlX134H8@QTzJXzvyYH1#__CL^BD5G%vfcw3W zYxcT|?gkuljh}ul&f1wGm1QwU;mr-RHEUbAkf_GmqsN-By1d{z5hljY zyDrT6tnp6Q_&90l-47n|J+7@SH8J{mjcvPZXSAM%IJ1m-x;uOL@t``7`!5X}pSx`6 z@u{`W%Kde~;>Mbk(i3bMThtd!Pk-FMbLq10_ET=#HQY?%k^O#cS)7^u@8+_A02hJO z%$Fi3!fR@or#<-HbbHJ1mp7daPboh6tZ**s*lF9=nfEt0$UT_7Q{dbe!-;C~r`!*< zDu_lxcCai0S)3 zOJD6QPuP-lbV}o&oe6uUKYGK~9J>DV{I56Oxrk3?cX;x4-3IT1W{(@M*W6w?amP=q z^6OuBfB574GCuaQM_2s>w-~M;41c@YSBc(MaEUIPw|S+T_|mIfTy^q>|G)ohoc&*J zQH@`y2!424?(sm04y_i9{wzOMdD*OV6A3sQDalXv@ z{qEqpiCnv1I40fP^FV7ky4p9&#H>@wbndWQ&eU0K8zLlp@oB}L+xqiwUN~@E<4vW` zhU7!rFTR@)_ig2o=~sl;eSFR~dGV`L_jdmJ!8~=FwB6%(bKJjvk-aIrm(AVxoGYg; zW9I~(Mbj?Ll%B0!#C1XnDx-T0|Yt=Y%S0rU#(V-6?SywEN`L>X^;*9zA{<z&%$hI2`uzBz6TnEHe90mDzPso4_y z>~DqOMc5n8*$y6lkS13f!Shh(`Q?bAZ#WEc5&&G^W1lez3~ z=^_6$QV%M9QzXuJho~qtSRTmDwjeL0 zCZPA}QIE3brC+}r9j)zJ6TEnXx52s0>me0Kznu5?z35@}y+81x%LO4PS@#`&H=bDe zmrn@ld_7O#!VJr2;@|!1QeRm=K5im+S(E#@p~gSPlZWn$6c%hewZ7;5CgC4PoY?(U zm_pd(AMmogy(-e6u2IqcMPbI1&Hr}Jy^*%*t=>G|Wk)WoO4;r`dzNK}q~zV1XI}}< zdSd%`?%{k(Df1F;h8JX(G3!kx?)w>B@VjJ@>y^!$Kx2OeJwdFAmnNKE>8{r(=iqOuzX)Bf<;U5PN~*yuI4?TTK+ z*|st@-XH#gO^0@N9RIjMoZU<{N1NljJ=QC=oI@sCA&*Ct@`4F;EHXpCY9NLoFAm{=V;X1 z*6Qwx=HjZQJ8s*|tJ$wIr}Pp)nK_HfbS8@F>x6&L=Ih<|ihQz^%H$q97^ zl?xsFmmip#CEps$^VxszW#NVitEcp^54(8YT*$(Ik`ZJbtNvWNTxn2J5z4sKOt2;j|+T>*`vuUQyRq>0# z>+4UZX3l^8%W~$N_lsW5TeaLmO@U|MtVTbp)h+9^{i*gYbE}NF$$ZJ=-m3(;Vt3P=`iuLa{%~@Woy4H}ba&^d`AMe@c_0J7C zJdyRH^Ye*Evb8>o8_C;sMNZ6k#w8bH_2|R5V@r>(eAb!zl+*sp_eSmw8b+FdCm%F8 z2g*1w@2T)O)Ee%>@R22zQRAh`;ccH9gB;(KOv$ZZmno;_w75L_=PH9~RgYHI)jpAU zG5bkrpA=gEG z{hP;`33a~g@{1hqmxs-_`M6#7lOmIsL!UNFXuzycug~+>8Al0v{GJ&nJv@dYb4tz}sGvasDh z_|F`1SMT3BkCYzd95+t5cC`_q%OZU73?GKSjyudFP%3nztQ#j&t3a(zxU8+j~!JpXNW~ zUYxtV@um6G%re`3D=tgl4T+RHUeKSzlOa3#==rlfr$zncR@% zJ-6t^+zdM2A?Lp;aZ+|mK^F7Mt5yjPe?M8w=y5y0+vvB_QOD|gY+5;c&-`28_Vk$H z{q^T~3pA$PO5A&Nd+cA~55CD3Sw5#dPYZiB?p2j3OZ)wqp^HD9?fCUuR<}cs%in)+ z^N6j+{X?f>kDc$RaJoA6d!bLPsQjXfd2i)pWOT>R0)T8)Cl+CWn9eyEW@~xPad$XC8qQ9~<`bL_4K$ zNndpnopg5pCg0uf{zx6u+qoq7xB9tP;s2PA%y?89CF;ACA?jNiN^YbAhjHjJ}4S)g|czF%#kfSr?{%KXL6* zm+a%5y&9Rp%Y+NQPxRZ^sU$x0yz$1DJjV`iI?BxAxZ?07_ZXGOSBjTZDQtBA&kQ9a~wSA94EP)q6Lygs=56Nq!9N3{jt~<}mmA zgV`Pa$`|`er$*$R@(`_Lu&$n9&zQ0|ye{RELD^x9vV%0s-9QsUppmrNoZHw zyV}-D$^AvqlUe3i?%G%#y-~pF$AOm%`Y%g)xWAt4d*J1((}!79JQnC#Z~F4ZN=J3+ z#`wdFQzDK|_ft7BZI$Ds-OnbR+FCo~U>Gai?*Gx(*yXu^8)EIp7+Ip^k`Df!E2FNhXOq*uEi}P^x zo;%B$jy~-dnVx(7o{~gf0oyP2D;Bv4eM|USB0qhe`gCF2nSaNnd|mBrSCy=O>8s_E zv7}jKO5Wd7s*6~0xFGqSWKLAWzR&(E;=XU^vfTfV%k>+7^n>rmbwbyhf9JG) zSn6~-_cGu0=*j;doDx_t>FJ4Sd;RAvPF?&@WmoW*GN8 z^&`i;4kWK#yT-&ic)RlE>N~=pT2=+`WfB#8t$ez_@tX3cS%zCwf36PwU7o-*<>juA zQ@`f@JrKGz@^sb?XEg!C3hAGE!sho~^mf|qZ+X7xz-xmyoe6(myjrxZbIXZ)k_Tp3 zp4YW@al5s1$KU4IJKUQ(=4pII#N_el6@^J3^%^^`|hSEurF(okuqQWgZ#a7j-)df{GTVQwI{Xs z@5A(8%|@9v$pTir?XPzn^;lrQe_UC3#s2dB^}QW??l3j)54?SAGJEM{tJ$-j7+>INXo;;N8sw~pf z+_;(dgh{;1zL@vci&);bp4eM{e6?T0*2E8CGC%c#t~~ovD78{WA?8THhKarIx2$i? z)B5yk>o&vp594Bemt?9|mIX00eAi>*xfMLIII3uK#H`7gE6h&wWC<30FmRr-Lhz1x zndRoi%sH#C+A!xFpU_hiZ?t)@=^T3nCcpogOZX0Cd#?&Jx_VW@TSEfi_o9gf(tnOIq)VB)*edB%> zb{I3}b8cTEVVZpFc#}}^@zoc#I7cZG+} zp}%5{``5Gh871@lJy@P_N$3{KOzFt*gG`Us)^4pkD|q>IjfrmngF?go`c-7?4Hf}Gm?jNsY;&nb+?vFe-$yP2-us;6cn}qsp4u-6g z#rdZDPE$WU_08oEJ8z5IM;w~*XIJcP>B0*?&s=uf_-Xc^9n7r#eJ3|Xe?Gm)=fAVi z+fQs659Zwdn4`Jn?c$=}A0jtBNjW4vBeLS=q)m4pOxeLA{3=bbswM4;O6L_Xo%Kti zLMMi;e8d%Ft*joTA+zD_&2!}eze=N-j*7pW8O!7Knx*yf`+M^*UeosVI#-_hQ;6B8 z{lN4ei-T|evx-X!ypn%Y^4QLlU*A9Nbba|JM=r_9`=`u;YdcroJ?`C{`2AA$(d56D zmNQJX7R3r%T9pf{CUIHP~oH(D|PEWNZ6Ri9s;Qr(?0cp$UA?ERbs_EluiNp>yPO_A=DjZK z%lolZ{LtgPn92R`JC>GzesLhdHh4ugk3u}Z2h)q!6=DD4w(c-j=_r5WJ$^ndN8i6pmTWhR^msYRtR;{!;A$zn88%nAeMc z7W&|GhBdx-gV&@vBJXwIF4L@e+7w`3cWlo}cB#F4lh$7;J{$ei{dAic>mTbqb&q^VvB431e=lr`S399I z#eQn*yHpbk;WY*e^2J@&b(~o1^M(Bo(=xG{Rz|u>jGR79@^U(^xvNF~MSfiTYjV>J zhwh4b>EBZ{O>)akK5L(qID2rTuUTk9-i(CZN-Q0J4vKsV+_*Vxv#qew^K~39ukA1X zJ#p}x{qzU-3V(5byruj=CXey+-0FFcbTc-lC!hQ)WVkch+_#2T^~ZjegKt)G-VJj) z>G6O6-?e;|dD9K*;zRW0RO_emTPi9w*Wdoh{pabkC-RoR7@J=0NqcX!upo9j>-zrV ze{av&#TEI%Yu--Vj~@EW&yRc))K0VQP|6RT`Af!gN5q0Dv%{0G&Dyt(?@TNE0%N8f zzWZ~pitEKqa9Q*8gMY=bNW}>)iUpEW?l|x3&&p{yTyyHK(ep`97MZ%WO*M(*e{rE; zSK*WCw{EcKy*-=x=~CK+8^-y|O0q4R|DHX+sU_m>hk2e$euTNqJ39SKvs?I^^*XjJ z$~}*n0+gqTWgkE1XSg?NyMX!JBz4x(mp{*&iEDq5yZd5-qqpaC8<{6k+%-zmXPa(T zk=L58e!^>a>uo)q`~1&VU2wXj>=L+nS%J?Ym+lk>CCAk##S$L2?Q*<*-9n|d!u)t# zBs0S;v4x@LJUdniCoC|Vd61)0=jLq}$CY}S=?Z@fPw;G#dwlKWpOr=r47{DRQVYdT zJlMCWMttV|zyBF3JdZrh6)UK%DB5+t>{mUr=9;g|Hwm4Z5!l73$ogwT(S8Y^po?z% z7H<3ynVoXy-leDtjUajuB_H(*n2=l8e{toz?)i6JapwJ#tsd>R zVAnt6arn}TfCYQ!*@(v~mwxBe?k}w_I{icWTgI9fTbL$a70=o6`>b$?`LdvI^Xs|h zEla9?A+ewRvOJ^j(u6;PKmDpS1(I(EF1q*Uz|-^pU&q>Xu3|D-J8w^pQ?+~g;UxJ} z*A$(?QtN`IU$-lX75!?dwv}-`LpaODnKOShN$M5tl)LTqZYPuF>gz0GYaW;isOx`7 z*B9h}+S%i=^Sa%Nk8HX+xwi!VA70vQx?kv;662jI!Op(zTi+ek(9EA8_~!IwpD&Ar zUtB&H!uR0*)_sK~`H%W)Z+_C4QGY&Uv(uqd8-KJ}RZRX-H@|z%_AC6o&h2xK>+SGl zJr=Fu8_FVP^rUurot^NJ331h8TcSJ|1()1avTV`ukWrn`w&G`EWkAD=Gsa4FTlzQt z{`f}oWBqjYJa(4ctO?FLx5vJi&*d8QcGukdZ*P}$>o+p~-JDpvHIQN1;lGiL-i@kn z?6%b2crTXm{Ai`=Q@{R<_PHY8Ba_U3FFWAN32 z2($tEH>>+g#H}Ms9N#?@CTCRrR{7)@D$( z``SMK=9kkqF7-OUSbic;&E|+3y+_zuImM@+3AwhcQlM+D*c6>sg@+13LV-_8|MdMc zePwZ#zu|ApPWDeRi;j2w%PgM|GM|5jr)bURLp8bal_z#x=eVFIF1NAH!sYbm2+_!G zHFcBPcmERK_K^SUOoxvjbZ_imdnn5HkF}*50s7D86jh6|YMRZoR5Ax+k#p`5NEIQ?t$`@T*F`zkA}7 zyzb?0E1lx)yM#(#GF(g9{J$pM^XhxmZxUxDp0@7dntE)V?}ry}mQD$YPS`s~Yv0_z z6QjlNRI;ai`E59#L*Ty3O$pW~(RFATR=$$Z*Zb9B4lxr!wEgq=>^*87SS!jGx5X~Hv2};j@6MUazp+0)b+#|`zSZl`A5Nv8$m(Lr zK5j1by)kQ=cfy<;|HC&n2p4gz&($av$}qcpQf{W+`eI zVjoz=rX7BzpOVg5Sk2WuJ=I<>-H6Rp##aA{Ue#mYX|b-8Rj-;zpV`oCeQ~j(>4aPJ z*uJo6-F3dU&8Dm4xpIT?B9&VV<@2(ihpr506x?&6&CTQL3huh>n+r6er&q5RU(GLc z=}6G_`K4Qx)^SbpWjwR#S@b_AsSVekA7qNvWu8(y!MkGJcAw)e;qH=$WmWE6*_Sox z#uo>3=6NSJoJhXn_TZzk#C6su$&4rVx0FOXi%#qfe|l=!laOk~u-YAgPMe=S+;!i5 z)l{b1b>Ej>EB(^EdE0GSpWWY!_HQs^m3i+YG0QybLG|$$pJr87^*g?Q)V9vG@Wu&e zmngd(cP-Og?wt^`5>K2s^ZT@aE3Z9gKCi>uEv6UL=T{TMBDV0{t6%9FKb@AWJ1LO8 z*z}EYtxt6R`J3Wbt4diqCjERBd~D9E#lNDKbjVp9x~F*Ee~H7dcBjfMkFN!6Ww~Jb z`$W`{oandxJjc)H?b#fC&O$$yC%^k9@3|cA9Wy>|6l=`sJGOp8-#Wi18x~9bX|7e{ z$z;38y#4sB+JCbQPt6n*eWUxm=g^s=_0>-|OxyC(fb;GFlWDw5K5t;Xm$#%TLoKN9 zXxMrig;%Z}5phN-4*#3#Y@_c7Z;k%yL}Cb zW1lU3!>XDlKQG&Ia{e@%f`|XMz3s8v=5J@WcLNvmdfCG(awlDT7H@gLsHbv9PJPdX z37&5caChx>(wJ{+DwxhK`@MRf`8*{%-^zfMOJt^dvrQ0a zaZ;M7DfIWcgz(bJsI+dQYMTw`-CyW_JU`zw7g) z%WFk*S?nK)P8ErpZ`StZzztS)?U$1CwrX73s$yBDsVIF;=DWE|OXFLyx7VyYx&JRp zZBv>0%p>UaJWciELjS!|j`XRo!CNKV<&$YwpD-Wqv?-w zRK$+OGrrxLvp{?5RX5X;^HU@D^ar~?4p01a)%LW+;?@f>$3MTF6*lMos@Lm!v^Vc> z-SbPdbw|qKAHB)5vwq#)`~FXG+1v8I?IK^RCPtWSn^&y<_^jo{wcIj?{=IekK2P{W z_NRZ=oBv!@IbGw?(;RIx%b-zb$ExeIdu;aoyvWw} zt^IaORM?4Gr4J8Bcw5fj#}rlc{bu0a-0ye5ul)!`Bt!q9mOU#CMk+J#_u% zO0FE0sMm+&B$ustlAG^e=X`#zo40Vnrh zD4k?k=(GCo(Q>Kig!8fsj-A{tyI>jTTBm!uU#6y%UaI91dwzr0%r4-??2Sj`I~ca@ zi@x!D!$PlIo-H}Ov~#V_#=RZKI%BT8x?a2c;P}mdkKFHk`}EcKnOxGxyDaBF z@7&jzr+#_&8s>Y}U$*H?u{T+DTj;W@X?Xn67cYwT-Ie(~Jt%R4_dOnu1~ygI|CCs%ehrNL79%$_+{wp_X4cW7%v!@}}uTOQSU z*=GGKxMf??maez_OE>F&yA}JUZ+Xd)CD2yaxBKbICx7hAt{mx@`fwzYv(StU))uR8@~TC&20HoedFb=izOen`3Fr;FYzqMY-n}xsw$CN!JyLq^h2<% zn0}zhr@8e;{fU}f#T%~vX1f0L1$VQDP~P_1#Y`SW+bi!&@6|i>DE!hSj*~8Dm{yCn z)W5!0B!5SFSqKy3&JPO(*2)Rxz1ZR;8>SPmecFW`ug~&sthL=ZRcqd{&5Z$qcS{${ zn~}^{$TDGTm1gVmz)20xH>H#Q$4QsZ_j~VAp0u*(K{AW-Q$5Kv`_Rag>xsNS>R$$L zy+8Z&-KV0j`(~`j-nn*<&>^PRn+t2rg;uP$^R~`^=wU6f=jqEv#-szg&wsb#IBs_| z<&fXi{Yl*ipFde_8kLc=YeGeT?BYATdE1v7&EiXDIBquW@T0!!N!Qj{zlrYj3VnIi zsDV2@@`%SK_P*(P7hRvVKf7{WBq+~4d-m7I%Qu>zKY3&uqr~(OzRQ0sgqB`kcCUri zbs4YUjN^-6-Oc-SVk1?5#hFKJuBi)@29^yG)2*-oN39w%SQXxlaKf_q`CV zsx)7?B$L5vsZQ9{(&a(>IA>}ViZ1NCU!1tRoa2A)+(RlZY!$I}p*w3=UkYJ!-q-te zLe#|fRky1(Skl7(WqXOQE2(sI{kti6>96Aw8#tMxE?bB2edJnVyT5-`*rOfWkDJfi z$KfG(e!`0hE1M@Q`h8a3LW$W;y>3^p?5967vhGZOtx-Sy zV(+9NQ-7AXxYH5DE!~cY+=vocN8$98T$L*f^_ne!{yXx-NGo~}R zwlVZfUBUO};k!KEg!6lJ=AE&>+PJx1W5H$a1$#?*Q$;o8wuG{rYpPxx{8arE{{fwk zjGebw1B)Z>B+R&0_ebt%23zI3x|Y3<-naRET(|f4iUOzS4ZdMETl(-My*uG>B9Q1-L)tFw{~!!NdOEeW=Zjy6mv z`VrF?tUcd<_g$;dcb6jO&i=P`%B<5l`{ za`))hDyVPx_s^*3+cnF^S?98&zj|INo_|35LBGEK+s_;u*WN8l2|WGQLH^U#*NQ!o z*Eg>#ZF?=57JdD}s;OUe*KAs>C42uaU-~W8)Y!kO2j`rw?~v?v{PF&txw+bTI^|{)`3ilrJZryb3|As)dNg3XorE@-c1pJ<;oY?qL zz0IeU(>Zj~iEYzvh;~2Q=68J8n*K&nmlZBwn)M%+i5hM!7XJL=UZEKGCcE>F{i10L zXUC*&Qhpz;vF=xh|BRHF7h9b94ey*>qO`fRz2#5hv?sN!@BZ{$>GNFUa6vja%zPfh zCjpJt{m&Nt5#=fR{QF|hJ2R9;tZ`t6**a^9qOt6yAB3+*YnQ*|Z! zb<~`fH`j$fU3jFCgX`_Zn0c9ze^0K^74`fZ7~-}->cQ1-#a|?&&vW?;9Pc~*KRz~> zRiZ=5S|l%4?5qRBn?RRS(Y(KIXN%nBns@P@>b1mwi$ik*znlIMJTU)iuJ^S3kc-Jh z_id+^crEBJbSO~$94~hD#J#Iu4~tgKULe}LGMp*bW8tFNFC>?6ulS*bDWq?vkK6pz{_zj^yhI(PrC>9x}ieb=vQdU9i{ zq|5E@pouG$){DO|iAp-)mC48#*Xvg|J<-u1^w;!bH33W((NiON4q35hSL}QkEV7F+ z@abyl$QuiMj%L4KdWp|>OWWDB6N<|>UQ~(Q_#{O&H!|^%%U-!l436&Riw-${JkJ;Z zYkq*^(igRYrd{keU(C^+QIs^v^pSL5=GH8etp!Y`UnK7rE`Am|NvGv|itCn)Pv6b` z0^GVSl9Q8+s+S*#G=eES|>F_wW&!BQoT6W$$Cx!>S!X5eNuFU`W z#<%;?w^`QDJA9TV%~0zwnECfwd1paRfc~#ZE?5FPjPZi>IMlrjt$jp*1 zte*R}L-pRVn#yOvm8X5Cuhy)*sQQPUA%v&rV2jZT8$+(Y0(;+Hcd&jjJyu?{sY82C z!8N0u+yxf}&b>c*^!^Or(>r)CMCNB@KTsMvof=b>kF_gLERz2|=b4Vh`W!Lg^JN{+W9$NF^Pc#3Y+|Xl(4(2j0`mhF z&(u}aT&`6+aW{XkQ+(5d|49$#y*Za##mn-cuBImJn*FIGDGA)-QRlNb|9|?t+Va+& zC#Dz6mM*!^kmeDiVihtueS7(i&6$hkw%!)o!nAXhm&Au(c4^&WpFhlb@r^U+VT0$b zb#7PL6OH~%@DH`qB#w*112 zzrIJ;oKw8>Xq(ZYu9BH$`iA*ElAXMoE_#b));5c_TFD%|{bo}0lDVHev)7(8QarK# z|4HS7Oot63XA++jr*C{5^P*clp8pZ;W!JqlPtCvM_jlXYm&~i8nfn>U z-QCXIHuJfvt8q=uY7%o-bmj8C#b3(TO?(;-^qNj5E zk%<0XyvH(MotPKQo?WN-B*(>fqS-S}o8L1QY&iLJPAb#kC>P}m^FNtRNe=&)&>7LT zB=Bj7O%HovAza%bGrOxv`-0%KIyJPxghq=;1Be>m{0h>)MYy z8mqd0FFCkmUE@XNDQ(w_|HSM6+}OXyaL@b5ioasIzBjkrDapGfs_nGrFweanxqq8} zJlT8eTJy8I2_1V5Fn`WY{Pkz@;p+Y8c3L*xx#cinvi0W=@fpRg{I6mhHkx{JiMZZ~ z2)DeQBy2Rn$a-P4@E^&b^FPezAATWXwfy7`h75~3p_l*`shLj&GLBwU(EhjZlxrSW z#Al5~)xwgFng4r}B`=?D*)yrxVg8q6Kc3mxnHMgNzrrLX;T3$SU3=#Ge#JU{ zy=xLzUCOy$Shv|G{<$_Ow6*G4Zm{>{PVKetGEc>-dxSJkSo1;c@v^SM;$wDKo2|N4 z`9n)hwC~^W65sdB={)ZbgXb>$uFF>_od58FukFUm|7NMBk5XM5wyu2O^Cp39dd1iO zE0pfCP3=1M!0X3H=dcJLeouKJ-eqTB=6d#c-gDf)dhK)1sx#Jk?+;&*TYdi8F2U<7 zTsIipia2p}#-%tP$Brd+Q)5Pk*W|Q50i)M2fPT zzuM*v(Ue`9H;sC-PLpc>1*_CfOXWOj^BL;F8wrcF8>k zH8)kaewI?&v2H@kl;2M4J{BlXh;si?_D%OD&#eEwXBSUJ9hac3+@;;f8oC^dvE>1>^qTxA5(OeZP=fDinn%_ zTTpMPT~_+iDVIb=w>kYiF=;~8m(R&ZBH0i0s%%>7Si>7rwM?MMtEIJnN3`LqX)~ry z)%{uQ{z%X<$#ll#>=mswvsP^0y6uoYgO%fWYM8AjYn`hvkE@n=z@-(Xr_2`$Ixx%5TzIC^ zFn;I9Qmf1fY2E9ODQk4iKPohRgW6UL-UlA?0>^J}+>=?Ad$mNb{{H3kyBDrGhlP}e zT=qPy5-#^hI`MG+Mai2fhR^NO*|vvO%Cx@R$RO@5d$|3{+fTJz)sBm<=ss_$s$$nM zn)hYzSdfx%A8%sKx_NcDVNed}uY$-n2rivP>b6E3{F zaoWBmNhh|fvT8Z5{`RDEQB;@@m*WIE9)HKZnU~c$4H%=|N_ndbr~lJG`1}5wqo$ud zwT`(&t-HJ>){>*`{^?EtM;DXIib&- zM$8{bdQkU99vm_>6adP>~7kKJm z>P`uWmrDX^tDb< zefHK1Zf}nBsUBUuR-wT-r{H;mLu~lYgl&Hw?-2R6WGa))(`o9;`+suY)RDQs8N_q? z=Eq-3+gE4q;R?AF8d&?Zr*z52XV(prIoIu+TCcfd#e_rqH=k69W|{wK`I_Qdsh+jQ z%~9-}rq6O;_lU~RUcOO%-XX8!EN(e(c)o7Q$at-IS$gZo!%n7R7CCYbXFmMOD*AeTl5MU~{`M`M$5oh&L*0yeeSZhVdnfK=|Fcnsfi>w2!^6EL|JHd%Iz~R) z%NTKS(l+U;A~p>Hlcv@pem{o8tb2D`@%c~qa-YF>qFgPXf_?s`s{obBT##`E{KFb2P zOztW_s2>-&$NT$xi!w1E=1EOz>(nFSUBo6ImP_80u{_HuEWZBEaW-bLT4w&&Huig` zKA-mcLz|F&YL3OP;%C_gGR=3kXh`b+JpbXy#)Sz98)7*;oK0OdU!9MfG;Pj<3zK=f zc3lhkyyfTrce@K>VlGYn-fsHCO3SzE8MBn|)RS#T7jIwBaY;Y;$qT)w6Vn-OPg>8; zbPs0Q7Sf}UYMgJj;G}H3rrm}caq-=|r=D@UBu+PnKd%4M3v$~_^Qf8~dGi{v18g2VGG5kIo=X0X5 zwEeS}$nRI5Ywy0~+thkWY*mWvf&`t^<_g~Rsc)Fqw7$60CMWfKiJj;K`D4e~7T>rr zUr_w&%1q^`N+0`jyN9`&53h&!{+%M&nxkW3U9xCipu+0;D}LO%x3PT!=iw?D34xP} zUe=cTa@X$A&D(lMuXxQ}`D9$WCgXzir!Q6;;@PW(yZTdQa_(WI;J`2F^EzR9O2 z8kRr4doRD@I)A={m|J@P>UpI{cs=XS)z8b8xMw5a-{$`|iz&XYV%j?cP+)@#(`ao?nx8O%qiJnY-cW(z~lmPV4^*w!E-kuX4+w zJJa{}eGN5AZTn-s@jRiEE{RP5`N_%G{I8g(8;yo+zYwU4>>TzGL! z$esER>=%yzTH)z(Y;AaRSk;|_FRso}`m&Ql?aH@DoU@%*#GS6!vRk9Jd1}b5CC2Zs zKmR5=BkqFFt?wUSF5A`3KEtG9p+*16*ZJF@rfu;~6kPK^_W$=IUft%Iv!!_d?_*Ev ztAAEwoK$eX^pVH|x$b~lg=>Q^M@;&~{_@55jK9XQuLH!p8s;ZtuF%!Iqw6#(eNSvKDfAZ6yrwVUROwT)&%yjHcadhjqDU0XWZ_ZL@pXF>O zt9NZxO8t%VS9Cn)9r_sWT^F-IL;C*-Gp?;uZo7F;UH0*|aIYuFHLG$R%`LB6Eju=} zPM>}My-3=(kZ>;kMxmJ&Y#PPv4@6DhK9yKl@afh9Ic3|7RdHRLIC_N-tyk4|7CbKe z{Wr%=GltVH=}ASkoK_ctd(%$c-yE^fk4NzEepyFX;c2#Rc3g6r%I{)!L@_K=%+uS( zFaMv9kHbxN+_+(|zb@2qN)Uh8@F*`>^TONv%3$+ape+5Nfxx@KO0#DYzWeueG-!kchj z`Gf0%J1;v{?OOKjTm6CbIVQn9Z?~xK3y|=;wBcIhA5pU#)x7j-HaqV%plEsS;of3C=b}eGp;mj)s_wrm+2z2{9 z#l$H5`J2G!<(A1Alk2Ciu{+pY@}eb7pQD5A_KWxV84DI^nHyQ99_c9+{g-p0H}PTd z>%KY}c5b0k&)GNkCM12kr8Bo7WM1Hg%y;=aOLseX7H@F;dUxlQP*brd?4oI(9^c=; zU3S?^gYMLil6^Bbp1OG>^o5?s*~o3%8qZj_o$anHR@r1wbBq7S67l%7EtaR&pD2*J zIH~OA3j364x!+?puLxaxQo5#P!RPG`7YfS%I=z4W{@<&fGsn+v-F@INArDgA&fiIW+O?5oli<@AitO?(+vd&8 z%bvBzMZL5=audVa?OWFKUfVAH;_=CkefR!yIXZD%JXbnFSux;J)!YX;XSmoEmwEO^ zRPaBzGh^o^6@5b&?-SpXeieLBa`yN-VUPczUHe|$50cO=HZ44(xcFGlYpce9Z9fJ6 zGyZt({QE=5?YGefKXn%^KBcexZJqPI`pnYFNA~fxrI}4Wy5a5JGatjv_vZF(G`cxk z(;`ew^3u_jY?7OfE3eS{vdn9P@;!Cel4D;!&#|v$(|GoDMcTypKTN9TXX07{xHEmM z_si+BhwxqGQv24mkAfB1&er0LtQ1v6eR zT=DJPzKybLi-VdLU0S)v`NcA6+lp5c*IX`Ic~4+x&;0Nhk9?6B`C})xDNNQ6lKES^ zAkFQFadWWwHm==@_Cf59zwboxCqy3nES0SG$81NO^tH-7=GOgle(mEtI6K|=soJ92 z?A`-0$F|-+eeHEXz z#K!D@{%na;MOL6saHxd&lUU*AJ>4O-rTG&C>n7XJ+pyFvda`VKdG}5hsS?}eFV*CZ z_2@Jg$-L?gj_=z1(R`b-L=2Pu^~zPY{nG3UrnxvoKTk3KTt2t@N!hg9;__WO|1)%S z&fnKGmy0QFsG8XAIO)@~e-C$E)|g-ULAv+uTei%n@7rbxh{XgtA2t0JII%YFnEJU& zcZ>B^bAFhsZTk0`QG=~i_m#trr&s>X@a2~I_DW>WF1IZ_m;GJ#e{I;FJ#pRgz$44H zvFb;=S?Ydk>H8mgS@-u*xxzD9iWb|&A4>N#UeTYmU9?qxUGsFsi|Q8Vgq z>a?HWcw^4Se0kmHR=;pT_JxeTx@9p3mrC_*zZ6{Dbz!f5z&ysj(22I3uWf_ZEKt+# z(TFX0`$#Gwo6WV5^W;Kc zwUkj#27kJJImZ^^eNKDkOwpO{9>SJ-@`oRrdZgqI_oe&PXJ6&~eztqo4ZZp;H$}>F zH>t+lYJMYH7^$bL_HEDP>^Ga-{&%oHO!<-*wt!zp_3Ft0!}l)#UU|2ixXt6ZaZc*O z8TZAHhj{1D$-2^K)gd)=ZpZZ88!keoZoyM$ZHw$*<;d|PO+-eyi*?CWQ-{|-ic%5{ z_?I|6+4*3fa8cIveFc7r1)FA7dNLM$X5C?SbX~@3`9zO@|7J7nT_kjU?#iTd9!b@y zJD#vP2qpZpbFmRlcjI$Tiwv_a&iudNXzIOxeY8v9?h+OmsG1 zJXq+RQ7#@@|0ZHu#H3eee7>x`z*FrhA)b8Pd!K33)1#82?hPTgueA7C`J1M!A9`I@oM90tD2ruiH~$xr?s7| z=02j)($K)bK2>CD#7y10?cWwPJ_>3m4CLx&xHO5gGk5yezAqCmYkaagzbO1{tV7J9 z$0r_ytXHLwKx#6wtstUe8^_&qw@(08Dr+%q(5xu1;Qo7PD?920N z(T(dT>S)%s{d$=#u|%n9)rU=c7J7=kyyuW|VkMto#m(Ng3~XoiHTF+su+n%@qcGF+ zl605bzdLWOPApKFIQ3Q83HFz1_1`xJGKW5y(eAOcBr~y>WyO}J?b7L+XGVWB-4@}W zy~kOvfAWIxQy-E)=qwFXPbW0x(E@eKR*{$ub9}r_JcK>_2O5xTW(*rjK6Vp+vmpHPgN8%_svv4 zTl^{|;b_9-`f9rFuCT%$BynG0ky3s}{K0 zuePdNn;5a=k95M@c`nai$t7(RIJsfh$B2IO8#)Vl$|P)UH!M}?<@zYU{+cdFsi}Cd z>)a068;*znwTAp^|G9qU=PViBx))PDSNL)}b8P-PKhLI;Bl)A&2k#{L^{Z4j26|8b zV!SD##kF6!W96oU;+(g>RDILC|IRi4>aE1Gtup3|SbUol<9c%bzBo|nDtB!~JHPSd z#rdC&b*hfvYK=^veXXGL=$EBSGi1+8v^sw+`6^^waOi{Tx%J0bPP5;d_sx%g;pw}M zpC7z%doHz)vFf=r_saciig}|M5hZw`GxJZU4k~ zRTj=w>z8ft6xvocW0K#ClA;x%YaUcHe0(t1P1woi&kOf$9e+~lC(HW?O1)w}91igPDy2rMz3%R-K#PZ@ZHmMR*kN10XgfYxv&g=Mfb_HK~LVuq9sbBA&t&vuW z>uSx~R^=|e!Z>Ni#n#X1tKZxIby++&h{o}T*U#jRjoOr%S2Mwf|Mj->wr-!prj^R6W*&Mae`^o7 z;c;sx_siSMz8w^66aZhqPPsHmB{`a;w zU%t*Wx2E_;``+$P>lH!+#q|nR&E1kcYcD^O4mkIhd7H6}r*rlBN8ul%q!xJa-#Ne4 z(xNSYWzN=XH$%1l?&9M=9kL;3vWm9N`af?b)Xi?0VHV}OgGHnHebe4mH*N_Y*x;7% z<==@(n~Dryr=4E5#~}Olr5H2b?oTr2Vg|oe&Sw?!s?W1pspUQ4lHl&`(O>2tcanM| zb1PXge(v&@B`qynr=s@+d*3;HZ|ifFgBPcq+U)&fR?8FnvyPr${yp>1uy=a6Z+2#n zMtV_2!NGayxHcm1Re7Y;~}-l~qzX{+grz@3xE|=RK|pHZ454_-HNUfF%whP+DO5UR!F1~n1)EpKrk+x0 z=VV{+bu1*XJ1lQ+$i9L({M>C$(l?D=?al4mRD8T#l$T8?E&15ZUueyFDjC+yk@v&mTi&A$TAZ!&F`#y5?$_ec-4|{nXmbK0@B_d z*-$SjA=DdtO^DA~clv~5+M9RtZBX2C_}C?l$b%DlPx1Y5-{W*BdQ-rbxK&w6drBmu z1izR`Y5iiek(zSmXY4AAK!t#%Y1!7VHaxgoS0C@V*{frEQ{VP^TlyCqllbaPJ+fxzu|0`1IbA+2vd-(i zlU&TBj3% zuA3}zwqnh`k84ld+Y|(FW)cVDUkX@ubMMs4pEoZ%@pwSK ziB*`&u2t`sm0SpVKZ#4V`(5(p7h9a9Z7yC{%CK1}p{3KovMk0v`jUt1fWiiU|D ze6G=<_OtSzh_B<34XJX7rYjS7I-8Znkcl z(fp6Ar6*>;_&n!D&8FOb6MlxLzI0IMKbgp>=CS;K$E}Jjp#n1M# z!rsCN>zSs!#k`C4_b_K`2N`))HvN$DerxvR+d0SY+Z3gje?Dg!mX^VKL_lTDqAzP6 zyG5nXogQ~a>g)3tFHZlk*x5Z@#&hk;b_Iz`{Yo*3fqtxa10>^TZP{evW^wM&txN0| z8qFDajQh%s7nxp2N+_Q3N;P%Kn)I&iYPpIr1bD|3$O*3EJ6zAfLS_3g^~#l?mv4}MBhs*x*08f2cCFp!mMNwA=uCXjRrCMZ z@;|#>4^Ly+pj0TnU4kz}DEyg7;)SoOtJ6x7-&NG7YVJr^HQDd*w)Nkigy8z^B4x6_ zzUQ{LRWobXWpDj*KJDl8|EV9B9_qUAdvVLNuHOvaAJvtu7u+uNe0{}xgG$>El{s3n z`Yz@*?ikJ$XZu%+?Pdz9>3OwPRZKM?>h955H8*3h|shoYJ@W>tc@YsV@o1@eN(y z{=P@WC;8(4y2T#G#s7c)j9V9I{)&_J+-+L*8rS>SVsy{f zM`+)?#Tk61{43{U_k}Y)Z@u^W*8TnGuf^;Mewtjk?{%ZE^*z(G3qDxaL{}d>rX3l? zuk|*0jf|X5%gN@ToV_o?r&O&vDG|qZGTAfnRriZePyR{vCke9jP1*8(^Tm!xn~$%A zSz7Nlo^|z07udH|%dG8N?t}a|gVPoblh;6eCytRA(NqOC~m;b07 z-u=L+_V=FWA8WP3YK%S|muyg;!F7SbZt+_kMHc5{7tb?>&r}U)n*V$8|0xHeXS#Fu zna$u+6_C?nwj8ovH#jmfz0Q|b6#z8WLjJM?XSed{EWne82*~S1$UIzcJFFS@sEC^cPXH7-e)TPCw!{(LRGpZ(Ay&w0OBC}`(BKX9n*vQ~~&+14`**SY&G)#^4DPTlUuY`fle z=driB2f6x9WMzK;kuP{wSmsx3CA?zCi{tN}>fX3>?BnOZ>o0Bk@G$&hl*gwEjvIY; zlP-S?UM90D`|s|2hZ4&M@va*)1kbOkea!6lKFK*^_kXX$TX%?mW)M236ybDCog;Z^ zc6-;`f+a5_mn`QvcKGXS$6CXip2|90<_F8>U%wufr?PQQkG6K;3=Rc*v4WtPZtceF z*u`4~b3z#xn1#QrRpdUfxIjvA27{o*_3)70=7O8=xJE4a8#zf*pNQ0FCHMArb$0Xp zU%6Px>DHO+VoR+U73I34yf}T{%6d$(Zxl%5~r@6oxAO<%;_mPd)QXGZ7X-5 z@jqo#lxwPQL6e!shmD(9x-8;6BDx$d$-Gg?et%oeJY>F9z_}yI-QMg@Up8D@JY{3V zCELL2Y})uM^;=lG?k%DH3l7KkE#Ou? z`E!0ccL!ghN_xB6iDeEir8;Izc)2~7|INqapIcW==}?^hVaJP~f}PRt6+NCawj7Uq zv|Q|rpMc8oh8Lz{qHmYVooTS=el}sX%f*N(SCrrF`TXMEw9B>k|Gecrk$dt}XL#+Q zil4@P!uQYkRQ^o7xmIAMaMA3Lm;nF0Pj{vJ{gO8NHam$qT6Qdsnk({ZQ|Nu|&wh6w z7H^F&Fq~<-wCwC$RiB*4Kkj!|d_Q!kRMhBG#E(3dRH1q|aYp;xNAJG=Js`I6>1);7 zj7wkIGdTJyH;V4ne!8~q*8SIgRx{Ve9Z+84mmWDyc+=Y4Q)Qd0(}S(=%$I6hdgHS6 zC$9~iJ5KXf^>?nfiuJkEk@;lt_WHS2-*(#N^RQ00v{lP=`nJ>ECE>>VM`reNRhJFb zYeO&nDqF=gSK+`j@t^MY2d4hqyD8=;>n_#9qNguf6&P&icz)B=!PaR*U{_UT%IAfF zP6sBNRWEyaPcv?#eA^`Dj53)U({HX@-Dz1I#hoZL>6wkrrQ;E&9I}%5ulbsP^}kja zx%{%|BkN~2ioeWkZfM!?4PR5)6uiocuIJe83Ro`#Y zm#`O~H*D+T;ac{lf&1O$>yM5I?WwYt=)Ji`+~4GXyV-|*udjUW`cU5_`c%ochqI`5 z>#9wTEvw%xzx;n?z0%{4J54{nzSEcUdtFb;WUJx>^*0i-Cb&P|b9hh3166^#Kh8Il zdwKaqFVsy7s(ZFV^U1NlpWWMa-FMFnGMV1LmBa07Oqd-Ld!Z)#uWGiJUSI!gk$$3} zvUo8#>MQ}m|o2}wS0vva?8 zkKjfjb@Q@9N#mT23{n9N3syXqO8<6RvptYKD^W&m-Q`W;9v|hTSi%fW@z=Ds=`ZNm z^ps)Q#(1F*$4<>m|725URC6@r8|TDr49h3)XZy)eJ&`RzP9oq;LeXoEl&vB^^4xCp z`JL~)mv{6=h+_HO1NEO_$A@T$6*YudmCj+_pB}_krg27pq@Z@o3Df__Jx9ugs|%bEIee z{IYpMz^#Yp4qNPI5s>m-$$kB~)U(n=$1^1pv36mY?M}ZXPb8Nt zKAwr8S@b-~JTFaM3N*XBo{V)Sb(e?zpv8k#Et?uw?P5kmVPDt?PMt z_&|!_*6ZB~_L(^i#k?1Gr#dD-)?w$Vx%bAJ_oUyNH&QMK8cH*7=@e&MSzoHzethMQ zUpeu8bB>>$cq`3yZFSI=ojWhR`Lgo#2@(I6d#$ybyPOW)o8tX_qGSG}v6Qr(v^0MEBfg@24)z9moy&5+&JWL3 z@i#pj=)EaU|MK3v{`dJ4Pkovr_cN*A_KmnY+Xk_!XB6ceecT%KEn_e*5HDv5FO1 zD!;!?7Ah<|&^}pXEUG`eB`iT9-^fjib2d1*^ zy~%pX$M*Q9E1HphC;a}W2nC4xxNbZl{VVnR@~?f21uO2g7$$cLidp}z;Nyu~ksX~l z{cZU^r%+C=B^Kv)1RkxC%5Y@~^0Ty=o|#f*vT8ABgJ1{GQieQ*Ow)!Yms2NKNyNO^ z<@aWDt5Jf$k!{usCqKR^#<99xeBaJZ5zl0QNX)*|&|4<%#x!xp>FW%&mQE%{`9Ai0 zGJm@1%gMcZpK5i;`t9X+n<98*cD#(YN!uED$Lz*({Y~pD_GGH^=Z9!scAI)@j^zB7 zYeq*eoWIm-{_cV7jOW2mx{alrW{J(R<)~d6tq^;1(iz$H6L#ojm|3>zxH;%{-2MN6 zpRw?Uz>L-q-A$5N+w)R+S{M@a^$WsoZ>SThmz}EdtSN@Ub!(2}XPE=HZp59`IKX(~ z!H%rz6Ez*J%suDgH#%4Uc^N-TA!ag9-%nj za6`|lnL<&$>JIsddjwsRyp%(xzHy7=%>h9>s5R`co37x`M`m+hQz>h|jQGrqa~*sXT%g4WaU zhk*yxH^{KKe_s54_R$r8f7d-e=l}%%`)6_&i`uBDc0w6 zPnu76*l6->haf{_%T0sVM%r1{`B%jcy2>zH{IEZ6^n0D&`|nEvue4SEk!WH*QU3q! zomN%RzS?cC-!1Tc{ix7ja+37kHm;X5dLBDX?N1VpPUZDnosxDy_+)qTImf9X6MiV{ zEv(iNiS3&wcxScb2gwzj(I2*m?VH=W+3&7wLE)8(JqPcZYdh-C-orL6W5@q5uh}Yf zb0T*Z+;^To6#{~a;iVD(d^jPTOy)kpGwa)7KOaEy$^Z%AfcqX9B-mreww)YA5 z7QDFjPV(b~2bX_koZSB@{)hAlUjwNut4G4WU3F*P_7!&2j(^cPOCxLN+2np= zIorfyYv+;BoO~$w-u>n5>)!s;)Yr6VbUeE<)?;^8(7UN@`3V=FcAS$FY`^@GUnF3C zTcx&W*x%Bskb6pI94#B0GT-smZE)ClB<@R;LM2bzLvHt|eLGk6IX$-#NmB|4eXHGM z#T+ST_3b^U+am@q+goo6b0#!h`sY~0aGp)TuQJ0x?fRR{qZtO%7ns-=F}*u-tNH0y z9pRn}lMbEuwjd@W@Fa8p;T1U@txOkg#A_NC`-eEM^lRc+%AR_X?}CiVpLFSsDYiwA z&)5ZjNSXiAH*e z^|m;lbx^$SBQ;*vIqu%f8>j9%pP_Q@?eZztzM1!AEQ|5!Db`L)pSVPtyCm2qxqy9b zNzA*p>Az2&+Q{Y;dhOl^UZDrw$G1$lm*kz${M9nrMe*1a`6WjV9e$?LB( z+iD*)cl6uMJ#5*?*?z#Ub#u=2D;u{}JrxjTf3&2v#co;0<8O`YyZ$HzzFwi-qWB=zli>9nc`-{*0qtbw}1(o-BP*sCz@n*}3hif3mty8*N>>ZsqpIq?`@!Ro?N(Mz|_nR-F*W z+&5wFip1X&HB&Yv1~2nD+Mo5zUC1FeBx1n^_TM=Pdu|tbB!BwrpEPL~_wLlKC%81G ztMbjh^=!+Mz!ITc+Z)TbzB~7A-wv(BD{2=MRXntRyGs8JEvvZq$G|GWPl!kS+LIfN zHqBGBr(a(ANP6vc!bJhw9Vz%X?e;qHx#!*|m#bdCFy+7sJ=q>HNh$F&CgO?p zH!{>Nmh7{-*{38Ed1GSvjW)gL8#XWWeS}^nDsxoiy?DRLrs}3dfw$G=F3Z1@HZ9>x z{8#6``P%BdNw<&5tzWYKY;@Q>Eyh#J&9?DB?v@etJp6+1^meV2OWKb7H7b_9C!}|q zDTH5KG_~qv$f|#<#p2md^77~G5PiF8o~6iZk<`ON2Ct7C7b#hJnDtSmeao|w;x2{X zygD9?mGPb(jz^6)SY2?F3x9PbRD)<-Z-kGK`Z(W>@@+H5^o7;XY-P;~GV?$`$>P45&WN)1m zF2?essx18U+WeE+h5BZP>+>bfcdES1+-19T<94Mt8^yvx^HL>Ftz5bH&_C%XswUdU z{bGO=@U8Mh3CZO}Y^68&TdA4Xcis%Ko%}N&5KDf_H#`4hI%i<=E!F{v- zE?7V3CHn-m^`)8j=Wcz*rIz+*9-Wihu*qtdj>xR$ zs@<9Gf2J<|__8KoO}Jp%Zz;KJ?5;Zmb3XmZ+OpNuth?){KvewAI~s@C!e*JynfCM* zzl)CQYa^vCzQ^p#nC6{5aX47HZS(Q-m7;$9!7YqGTjGz@=7fB_px`BYXNj@#`jbof zU#-wkGyCMX;_HpvcMCk1`!sN>um^nod-UjoralJGmu(GCPD$-wp;F>~VrC#m#vHl8 z%A7;$(r%V*Jlp21f3q`k@xD*`7MmSp=a@}DQnYJI#tSX&vKkHPIjS!;LM6_Iyev{z zu&{ZVfBGBagyJ`cewg$psY$-DhjUnBl)>yPw4b!Ttn@y}VSGn&t9T&c73 zlQPthn&{Z;wfsb;>gKykTv|LYE{=L}@3ZjvkWY!Te;v+J^8;a^q)!-Yv>1oJ1bm{>74Cn{lYslB35)-%?Ifk zYoRSF8@{-Q)k%ENj?tXwKVg}f!=ndL#uZ6T`Q8ZIkF@e;JK`tz+u@7xvfW0&~(l^Y$4gnv>tAPBW5KExV`^`1FjW zr7+*Nl-xt26VKPD{mFS;d`2~xL2d0K&2;yutHE;Tc?u>9t#;9xep}&AcvPnPnagLK zLzqr%GpMOOIHA4tj&+a{*Q0NK7p^l$$Icg2+0_vmVH}xMw{81IHYO8@Wv?%tJaPx-NYiMlPkU*mOQzN($){E)1(+AlcPiCxg!-NOHRw`H@s z)#vG<8>N43G0930opAoa)LQ>YpOZ00;WJdGU5@y>QkRQ0b%g`#ww-J#U9qo9h2Bqk zml*s`tLh(v=+3aI$7^gKxNJQ9$K{Cd#2;}yljm(*H;rS--&)nLzht(0{q0GMR_oPY zQJq-PQc`-xV#B0Mx?3vqR($ri+imt^*3u=~VQWs;O{hr-{p9TSS88oeOTTV456go~ zT-Gs)?_Z@HDxI=VyY58vzh@f~J_L0ws4%L2#<9+OftKn<z&kE zr=0Trb-qYzPE{&LSFMhfwAL2pc)3FV^0vOKZUK#@Gt?iK_Mfm9DZH_E8RT(!^(s*{vSRo7=)gF zyyJa(`+FnNJ=^TIPX2uU`%ITfMkPOQ1iGy+$c%~Xw3YF<`t<$MwNDQjO=Qz{Y^yS} z%wM-U;zpa$vho+xW0tLIR$D)3C%3E5?4Gw%Rqt^<+mtku!T;yoO>y5IPrsVG_v^He zJIY-99eU119FPpVqdak%@j1nMt~I~EJ&7w>+L@Vc5u$$XMRcptC-$HNijPbjgW4_f zCwJ^tO`d8Y#((l<)bu?OJI*~!uG1*`Rqf)i_jYV(L-?fRrK@KKv+Mo8+E~s&}E<4exe4QkVm##$Zr)VsVERr*JNMSrhV*xd+|wn5N?xw|bzb*mO_8N6b6sF@Vi!~GlODF!kK_Ma z=6;;xuv~2w^F4>ok_TrFLDq}>4g{|kSrxgwVnw0Uhj!KG%jFF(zljDgoZL|{A)%+q~A9qc7{-KHc!MafW|6h#1du9r5S-9|W%K__W4Wgc}J0-6_Q_)ra z`b|#NNqxo(dyf+@SKcnLi!XHG@-)1#`+Dl8KN0W0dCro16aB0ti|h9d)#DM>Z-qAh z6*#4wy^3E!=boBm`ES{T<$H}*6sWSyBAAPq)=y%(D&Cflz zqMd#j+n@TS6WCs^Y!;NZy1><-*m>>mtLj$4#!;KE`UeQ!yB)kuYwOvw$IHa5Hl6?B zt0KSoR`ovdaw!3mBP9_bhLZ98k6e?tzpCT;eKJe>;!hS9rz=8kyh7YBj|Dwvubnnc z>OI?n3f;f!&BBFG>TYGQUo3A^`Q`nj$DY>z4wotQ?I~l^zs+TTd!pskCI4>zop)#2 z#VIYn8lo0jMPw%d8e>df$6{~?~ zS$pA>+UD48Y;TIDZL?qNrE6));40znd1?Og(0elXMZ<6JvhQ)#6K?yv_3D9Jsk=Fk z^c0?`nfPDp_?ecEb9PMKcR#y2&(Qu`oblF{;>MS!_ANLxXMdwY*QC(@d_jRGyOqDR zi!ID3D{69EVY9*fW2xT--QT_0-IMmes?cRxp~@Y$B)((SKjVpKXHB*V%;EWQLG(`7 zWWGr2hBt?@S2mlhy%-lPVe0U>*tM0{@XG(xRov4vDr|KUj?e5n&Jwof_4B31-NwNO zf5}ZSaOn<73Dxu|5?)CA5zOJh;cu%b=d!zK^O7%>exnG;6J^0Jbytn@C z_9I(lThwg0uWSo1jN3U=+;gXTS;hsAiF;TCavt1U{3ST6mN{rc>7@0=X;a*c53=r> zHUD0;=FXEW4x0OJeB^1Xh!4{^n*Dp_nm9q(&$Uk!C;z_iCDS`CwRmH8<^#US^%sxU zxmU?eYBnhP|6^0n*PN?qlFyP9gSIOtyFT8Yt9QSw?yc+@{iliF{?$mh%$nD6(&Cuf zcBhwVpC1e5-qp*!=gGQWU*_XLBx#JbP)OTdTW^%kdpk=HF?$kT9v6`%T25XA8xZ#Qt1ScATYG{-vr| z>i5qgx0G_@Gxis*ow#=I%9EvC4_O%+5}jmsD5PiHR_T;%Dcz&6)pH`BPC&%-TOk(= z`?tI(e%$SSVfooBPmb|io4P*ku)6Sq<re~4V1)ckU*o|>#m ztxM(|w#Q8)CwHyebud!z$+;%x*%rFHV%dyjj!)+N*YqyfeXiF%)|Ypygjid5-oBg~ zazb~Jq^go-K7F&dT(bHGYNZ)B_xbcO; zg4ciY6LxGl^=%8CN!e!&OdhQ3&ee-@f zTHJYBz4W|fU(!mKO=>^ylts-s;L+{h5VvD8_k|zR4+V;yd2&-ttH0;i3(wuXQBV6f zyau5~cd^$r~Aab24vrTOJ;T7hrwqJkNMW!1C&W^iYFq8Ya>l1sE zp3C>2%P^Skc6&Sj?E;Ns6~EWrDoDR^XUdH^+QxMZ5#BSdR#fg;{BO#;$&RXj)2}o< zDu`mew*1!FyY@PTZt@$=`KIv&pPP~FR6gTni1Vvohf_bTco-1AX3h-eGWCYl#%YC7 zyNx!VzmmE1)b#(>3E6zgQCH3#d|3L+C200U-LqyhV`>hkxb$2*Ve_d!;Ny*?SQDwk zN@}}T`fsz&QW6iFJN~Qp#&{b?=y*X)bCsn7u+fH|c>^Z}z0)aUR`q2Fqs0PP=Xw{(bT~H-?Wz8oW=Y z&ON~e4eBCDIE$u&>-Q!(} zs9ncZ`#on~>xv%aa;QFb^~<`2)lF-*8N^)R%GNy=qG6hT^WDsbU$Kuf^=>*XUN-AR z(DtYn>*upB?QQo`wpx}fc%n=0;!KVST)TNUH@!g%zRgW-aU7X)RBovSu-vxUOKH7t>=}Jb@zPBNxt)C zE9+S0^!Efly)EX&J5MWq<=w9H55FI4lK=Ym*bb?C>dV%!nusppR6FKWx+2R<;zRka zZw>3R?8`V~CaZDn`Nx>mR`y*m?w5BEAE#sP}^6~2GwIAxtw%IrfJl(W(*2(MtLmOZ%DVf$JDl9?)Tj~6EyxU&r7!Z7`QX^{qiu~ zNCue+(etw87SujHYi0Cu(bdfi_dh-Ij4UkjJ@SifOI)j!K>VE``Ib3cLQU6?eW?t| z{%Nt+HeZ$Pl8M{?3y~}{G{f;K8 zY>^hH5Al2~%~M+_SDibF%YEO6%L$%SDs$OOr+;1Vs{WOI^}Jc!kF`#)-~0LTL|c@w z*WXErtEN}@y>wmcYCnxr`RL}u!ugh4-uQ$^$$Spot|!7XvEJoN=dCAixTFnVdCo|@ z5@?bt`s7zuiBx>d9cRnLw^fr2B+BGF-^ZU@pz>A3P3?G3FME8GndeNNhkGl!Yd`5| zUM`(1BU8e zc-+^OQ)UIW>6tM-nc<^XcdT`J!^=q<#3J^TteCX?-MjvI@}ly)xEm55NjV#`d#x$H z%&_A+qrU!b{=J!^&6(bOj9d>*LKm!wlQ({tW^3pu&NR=Lzp(pnWLQ;6Yhv5%?-$Rv z7XO!3vG>`1=;Q2`XF<}}b=!q)0(Ttp?r>RmeSSi=u*2=u#f(eW`H6H?eYIZbRq=?` zPQ|iv_kIS!(ldrzG-n)~&s1O#TP}ZY)p6zx%E$Q_-E&o!mYXnn%v>3#t(u=F>U4aw z_n-gi8-)TZ*lW!A)kBg$EftWce(#wXzi{EiTERhzx)MhtKae&8hdJIY*>1^RKxu8fqrF% z{vX#~l)AH?`QTN&bWPjui-l*4WyAU&OO~5NDB2#|Ar-uqHL7|W6T9Id!RYsyy$kOh zI{o5~`m5@7s%-iR#SyE8C;HsK>C71PW1B_pBJ-XfZ|e5nUYX`#T(al3y8f|Gzauwn zRTO3Y5i#A@aMqb#7g3+>qW#&vW?2nwE9Nbq`_3XyW!C;SQKk)iznE@4p4h=Tac}J9 zZ*yjow?D5|Xv6EL{TI#!Cr`c;lg?vc>B$~cF<(U5 z*)J;8i zNkt)3jHS()95O^CH;K(TaUyTql1j06#q0;NnEN@ZH?CP^+Vsj`-qj^hI;&sEO4=`S zJS7{?AADfWBRf~`O}kv|1GJ~T-`%}RF6(1ucFL;77dj^V7r45q)pX;2jg}P?Oyfj? z%N__{-o_eP{I|&3{8YMYo379XRlSh9PPw-aHm#b%)~43<t5_eY+PyG&`1$*u zS$|fhE%dlvwn}IMN1deDF{P)k=a-9iguc1oxZ~xGW9`w(;S6T`Z=G7Mx%}fRt!cfh z68>E~k$ZNZVA}nocYD}AmTmifzkAXG$AvRLDji&tCOON=c6OG3nD3m_Q`IZO@3{&u zxMOts>al1^eTFx`XP=&w@=oATmfrKih9f(S3T6m-zbyJRC;4H;y%(OZHTv$&OHX@q z$K~qV{wo1bQrD^_4=dNC|MdF1R*V4-#*QPyN{y_7ESn*>1=Vv#ctmDmmee>D( znco*_?N|PF{7IQZV`Y%dJdA?zS zM(2;)ahVT_LwqlEO}_Fw!E5fqLtP5V5ASdBK0Y@=*kq}$n$BKAn*SO|>&%G}it8$Go|L609#f$&TCfVAoxT4Yi@12lK zPl|@(lO0MChAT8SGnBOo-VQw&F!fsF(ZgTWx0ERfYfQWtTgtTYUR$p2biu4IQ@G=A zDr(ICQowAY{B9xRG@}QXzWtU-eA=YD^KL?mnc?etOV^&eaw?T?@~T`!bt@;oy;dvn zLf*aOV)eSNUvoGj?{@4wQ7g+Hc0FDC!JWpCnHx$u;QSR zBv((O=G^N-Y)bR*JFBU#=I7O)&ZF8DcFO9K$*qQFu}ZO-O=YtT8dY9py%D(o{_Yzt z>tjsUbF1oBiJqUFV$AWBb2X1m5z~v7^nI7j;$$w~-P*7;@PWF=Lk5cnK0CIxT|0D6 zb9M8>a{a@<>*wO`1U&t`e*VL{;F@PWU+31aT3ngytvC0e=sV@I^Phvd->S!7x^8NF z_J-*1@)@s>*Sx%x%d%lbc#g=mzoEz0-(D~)!GXho(akVYe1@aK+0YpWr|g$jlDr&x zdi$>B9>U(!jx9Sh^Lysq$2&ADigNY-JlnO*S=h5evUk6G*k#t9#Cts#O`R$_x6hn1 zXN5_TuKm2@JfEXf-@j;g7Q6D3d)tEp35)+-_UFI5>d%eD$Q?=-le>Q=Z)1 z{8?p5h)c0h(i*A5(hV<8Y2S*emKBP4wRe51(bnlKifm#BK1CR4r9O%N_f!5mM;bE= z!$aBW!OD-HGRuVao;cL(yYoGJ-VHIqwN~BQGM<|p?2h+tTeYa*O;2^qhfgb3MVw$- zcPMNxXWaB~qjSG*oJ!MwroZ6>Xw-^e5@yI*!*du=cNg|az2>_Jv{zXy;ZY3SFfsCm-J6h?hV_T|Em&q#+v`%QN!7r zfA{Y%qYFY}eK)vX=`Cw{#qev*F6ZxiVPI!Hx@T}<1qKgx5ioCv|Tk|xG$;otH z)SsQ2Mja1+gmiRG)Y$RrIpe#%`wwT>A2r%0HcxVsWmL&>&T}GVqn-S}m_;aVt-mcSYzBY@w_n^f7HN4x{_wf93vMbHXep8$@d;24Xk8<}cdMo=n zUFKIjz4(D&Xrq+vkzQl}Pwq*l)Yh|@C+=UYwN;%t@opdg^)vT1G~<{Y9(S~Pf7rpd zpWn-lCB*ljKj*cTjMPEYd9-x_@AG7qvlqo(W|`OL7V#;`J70R*FxmQzQ@EN2|AmaGz7Li{Z&FJ4PL^5O zwB=x)*GnUdz3Izb&Oi9v(ec=9YM@Wc#IHVQ4t#kKdD|sL{+r#+CpKZ9o}FJ;;Iyj5 zD{c2uEvXCB#Pk>zUO#>Ne9cskMbZqd*NmLMg_%BUQ>uHviM`cdMY3VP?fIQs-b)lX zmbn|Sdaa+Pf3tXr&fVB0QQtNyh>8~Z^;lJGf5G zzO$LJJ!Ve!Lm}4?`IpSW)!JK%&ojMt%z1sTFJ|IumUs=uk9X>JMlCZ?E(=&5;qte9 z{#FSo-HUg3a4(HIsawsxM>{0JziboKu|YxO26hnuFu!sLu|%`i2r-66Z}Hv-YjHk$YuP z?kv@RSEFag?UOjmB)w+tLdCD<8~-*=&TsI1C;Xnl`FphDa-F0f1;XmPXXiZK)1R3B z=&QR2V`bGm2~R$yosACF?~8vweswon@T=mo-4`@&h;=?OEsk|>$++}DCCgCkrD-pnZ>gp9HpXuG9`A}BxOw;EtH#OLoZq}FOo?h^qW6JR@S5MsS2(GZ7 zvn%Zv_oiuUPW}-5Y5Gua($78X&Dh_(ymeyzj49vRE_^&1{Pg)j<2KLBET#MQzOz-m zl%7!UWR(#2xyJtuZ#v&Uc7^g^$1*NFd-_Q68Bdv#9s7~_Xa4!g9QO7wyME+l{KU9@ zA3EPnnHFhTYjb(q!n1+p&R02p9pFlQwPW$?MAfJ-wJSsRAJ=UY_K(!DmFChGm)sn4 zQt&t z-`(YYb(gP}Ct!jYcc@2$dQm>VQ|!aUxRaM2Zo+u4Fs)3CV^$4{-0CaP zx$kLap>60V*84@(B^SH|^-DM0msBcplM=7`%sMM8rT$jKH`628lm7d@>)c?H6aF+L z=Y7zl^1G*R-0ye1s(f<+x7Ncu&o}*jI=krkenYj-4+~XF>!Kdca*mp2!908EOO=}4 zWs7{)C7qh!;MgK~@&7@F^L8&y7R=mzCv0Uq>-Ei^=FjinoFEkY%~pNhdA{S1MXlfD1^Z0%dToPNJ}X8rq|RA!IE)SLIjBfdRvaox8ma+}ccZ9>Th z+h_U*Nd66-cWV0dxW%(&gG6~x+?|s&Zd4S5$Oy5>)N>|{LO2vE#F<6p7aSXV^p<19&pEQ=~0%4T*3$L z9GX&-8EUjjjAP6CcIoT4#0BmgKj?Pi&pP)~zlXlN+n4;>@#4yUJf-krp48(@9F57=U;h^@{>9a@?RIKG^tz;7kD0B% zEnku+@#>%mo5a&u&%);v#~M03yQiL@r!gQF=Kf@P@oXwb-{CBl zOY1hXDEdu(^`~}%+^o&dbYtgU&8t1Cbx`d{r*FJfkNpFM@{2(=e>fg^B;L)xczoWn zx$MQ!Dj6-mls`OAaktK{Xgu8HbAa>mygirFN;$)=rj&kvm09As@d)e5veS>huL@*e za_6X*lfK#y4ZRl&dHtTQUw6Rf&Qu%QxLjMGSbN*B<~)WuvJW5YI<8gKZkiUNrKk9X zlg&2c*ff*33@mIHFS`oeew*(n+RrkjI+N|}q4g~X(;ccJn|1D=yg%dg=|ZzTiy5=s zE{HZIy|lKR;F)O}Q9rBV#y76{f6CYKYInT2SfsL6AiDIjev+1dj_tN?2A4mTR=c8E zCf$+qdSq|UpR&b!^T|JFC%GrCdaswd7l{)RK zDHi#NRcJqFqU0m?UfoKo89$4v#J-j2sWEA^ZMT1q6NoN{yydl zyL30SY4@LJIjenCr*{{gj8ZymS88#4{lgP?izTm2QmD<@d+x_`m-YFQi#G0BtX?Ma z=3h3WY$xfF!duP=d%qV}(nY-|M zw#LH=^7|k76*KUp83`$Q@UN9AT3}gXW-qnl@$S-cbL%~6U#*teYTSsD3buP7k$X4) z%PaX;tJOcqT3@-T@_~D%nDTOc=ioPU-FSK4nIA5_cs=Aykl8G^BKPmx*YQjV^plRC zr&HPHIrpv&^OyGr*Gh}7F%qktC5H zNXFrFcM90HG(KP2y3O%S@yUbRiw#ZIeb~I?+vyyQdI{~@#?!tt zE?L@kNj!V`lTBk3!Sbjt6 zou7~`*Qq@=N?UCn?0?PAEGTqsQJH|j^MH!azav-AVPigf=JL#F4=-PlZ$VY1oPiV8 z2=8@BY3p6MUqkn%z_Wjvs~HYvFZ-(h#w~2ttGP$RuS*JC6w^Nu)49wm+_f@y%0FM0 zY)&u3%ZZydxPCYqBo`3*Hp21D(I`LF*cU73l{i25Jhfim`*yk1qlv72-)AYv9(cv= zu&>a2#;iXC#1d{;s#~Fk`)SL)-;VjpXuex?-Up zKS)3JcU)rHXu!F`V11g&ONQ(xv8mZ#Ba)}?wLh=I%+x43_0#;I{~w=995@p)<;UyL z<;D?AD^6cK8&~Ym)XR4;b8=Eg)|&ISX~7z<>pjKlQueP>FH~M<+!Q^#Rj*C5_{=(; z-BOd@COzEeQt{>J$3-)nP5m2cbu6UMez^A`^=0$A&^?>0q*^XcT^l8tvYF#yTz8)O zHb&2f>(-sy*vE0E%KfEWa_#EShaTniQs6SJ;vW;qb!>c{`u&}w$>tE%?gw8?do9-Hwn&u}y`a!rW* zl=O0IW?M{$sV{50y?tuI*SqDC>-mJAs=mH*t$1m*K#W3Jr4hrORT^(zz23uO^(V4e z;piXjycMP`Su<`so39n*%HL*fkRtx~*5;+w^~=vDEb-m=S^ho8qFb*sQYB9ZZ|Hws z;;9|veJy24-1AS$^QAneYi+vrU*__?J1bSXZi^?%7d-oT#qRm!)FWF?NWWxt+3bZ#5#7N@GmKR!DD zsn{O!?svT*%dhjhJTji&4>OTFCik?NAyI%^OKMZ&G>=bL{$8!r2~OI_(R<7It2$?W zNK)3*+$gmmYRyDPK zaPVHf`sdTu;#1DXbH?3%`!pbL!I8Cvsm`y@@K}4a-e`#Hf7ao7^N_aHj@u$N#~!)Z z&()s9x`CBj+p4$luHW+_@db|$-pRQYAk(moea4|Z$6wCb8(rG8X>oGT;c3RgU$-xB z`l24ueQfS@u{k?W|DFH2{t|zG@cK!uEq%`<)$2LW8@xU)zRu?Lq_73aDylzoWm&V! z)AUwf*!yd${o!l>PPJUrdbBBa?JB{&I~Gn0oH{4|?D}NZ^%1{(H15T(xF~A>_m5R9 zd$YnLF3J8U*Hb2kD6ihhQm&=bueaMqx8_@4#h)@>6_>EzX|I@Ff+s4rmcDd8P?#|3 zcEwt5)|<&pen)#YeV*){9Vok7<45N6vhsP7)7xcS9UVWxP)80e#D*H#FX}-CDu>)!{?H;-e0yOe+?6 zd0qGc5iQOHgDde*Kc0NDL#DSfj`7lU9}VM~LX*_j%IR_}(TLfu^X_Z0$<(qN_rJ&= zne%3S%|)w#h5Zq|GNo2LN=zT-25<#;>K}Pxl$JBEc@cw&XGPQJUC$?7UvyCV_pS}X z{LgYaxOp6oskL1@6V9?u{#fp$6ESNaUs@GkZ*yeguetkb7=u6G;nrE^Wbogq^kUQN zS=TnMnPa=vu zeCPiEm(@zwu2zR=3C!?Xv59Hfhc-{f%2{41Gn^l^Z7rT4F=^(ifL8D1B`&|uM!ql3 z&UvsSswr8-Qn-Nk^r>x=*q%xpd${nA*TQEp%0Z3U2MkUd@ibL3zgbdLbboVa9Or-0 zr-C`l+3er`+WoBK&$Y|$pOp+sPCj`y`G3K}BO5Qr$Syv4*4@hgg?H0Q6`w+{<2kYy zm=oRh!jeZb!^a`Y+pstNPV#a4}ht zF3R|30in5pwU0aRbr?ARF$ZU^B$bOwP?C-`TX0wY%?BPKj$>qY;@_0Me!WL z?*g;9TQ$|6{#8+zlzph?Z@TFSPwt%dbKWjD9`fHZ}E$*9L}_{X_**^Su` z?EZXeQ4jfO6nOLF|C#?;FBt5Y&by`5TX@Q55w5iQ56;W?|2)2^S9bpOUz56z^{Cx1m6%Vob$P&KXInRnLd7xe{;5F3*A3zCc$bg75uIG(^t89 zqW6yI6my@o=)0W%aowgzPcCjbwnWHOVK<}1!QB;B@xBi^?X{*(uGHUm<8DYL3%}Hv zvMpQ(UVhFjn>{<`#?p4h`m@uX-`r_ZS!|k7IA?R-yM|k4C*MtZE0H>lc~#~G_9>t5 zl^9m9{;RcGY=g#nlSM~NGE!wX)PFuD?Deo=Y51ENGWX7|kochN+&0rjhdu1r%cD{} zlJ5T${0_ca_gbsbplRP)hWwVc$d3&iGp8z4JPi0E^8XJ1s)=ueG|q%y&-;ATLNQda z(dd?D;m=EdWSSE@1fhw=C_SJJ&Kv$r$D;X2$sC3GcV*us!K{ zbl~5aD}Eb|tW)PXFLQeO)yzsl=Iz;)7f(g}oihEtSEcxIoqR3--(h?dw7aL!AZaqU(`h}7PbC(0epUP|Nqx?lClhiF}`Cu~i&>u#)g z%EB;>i)p>#EB-e*w!#g!UvxS(nU-JSU+!Y(UB2Lk?wi#34;SLj3$-Wee_F1*+03%G zfjMfbq(h}>b?X0^iqz>QyCz<_d_3Iq<=ppA=IgNB z`gn5HvcEefJ>Ta4c*-=p&QGT;|M1I9pTLskDU@K~8Na?TJoVq~4R=nyX69{T&0D*} zmh;Z84NY7d^pE{@&v|;G^($7nexyxw|)nU2Mve zfUk#_v(0j@TFEr^|NAGKgrC3gF0);kBsW`t&puB>RPWWiX`g?5e7m8B`C}xzBkO|& zFD@!Bo-N1zrB(Q7%Jx6|R2$?~L^2urY!{t*KCjYC>*+&HzEl6gLc%-GZ#p#l?53QX zwnDuc?1sK3)@H}5H~bJiFwL_(qI@UA?MqE9`z#y(&U-MW;eDVb*X(-jSDbURSY`KT zFZbks{4hUcTh*zZYQfXOrcV3wbI0R?#l@{#Qre6b#H)7BpA=aW_ixhS`3Ki5x4lyT zTxQXCj!kmib;aRZ_r}W#DK|{q^}Mldr|2Hb#w$|tr#}9lb=&gC`}cFsc4c+{H!9W? zmnnS0mH*OD|4E{%tB%a`M@EOL^Bpb9a%Tm^6#xHPE6Z=Ua35G?Qo${>RhH(DHE7m zm1kwQTs^`jbEkYwqnps4!#|$r7e839dPd)Tnt0;$8@g|v$Qs=aFzH;jN<6h*C)DHI z-$KP)UydaUG~7PPOg5gRlzD&E-q_r&+CMkUWEN72$+@ej9dESg!PitX(^Hx^CPvG$ zr*3xO^q3^*b9(Lpp2gfc$4;DKW1A!RNL2syx`{&he^i9OM>p0?DZbJ-(QEPxJFWyy z@s)||c^n?LB>GN0XRUF)AWU1F$^|i*9&h9-V&sha(MURj3xisHZ%mXo2O?NNj{BaiYReWv=Az(n3HvP)1jooi(E~Y zFD$<)-}~y{HE*Ha)lVa?^Q+#oa-?`}=49nt1dk>q3j|%z1ylNpddVmG(GniEMlL z{SGDnyLuT`9q09zK5RA>JH+ue#9+yi;K}Ow?3Ow$^QRu%ztm*%q_s|lY74q*O X z7a+zkUbLi?bHY6R)H_i)ZcE{MHpDU3=r<gs>t6WC?B^F?o+xm7adLz=gPyc*bnRWiiJwDTcCTFR9sKcE zRj-}B^^eU5=4<|p-ukO|wa~Lf9+8k#Cv(GJocYP?`;SYkneid9CC$AftKZB`mRDkt z(9^y{-<6ciP9-KRFHTmKo0)Jq>f{%Lz2dy-9-AzxSObq-i)LzTpXImCA(c0Z`?zX1 zOX7($jc)(U#C}H?t6qNR?5N4xw(iRAqf;|hU+^g|X^&p~VnM9wgVWL+25c$<;=Cev zZx*du#CKinl+%guRbM~tUm|*}-{+aXQ;w?DA^&sB*GzE!X2|p4fZH!EWt)4Fvez!X z+4gSlRhKqCOZOf3GJE%bVR?D)7{7zSx8sNIcd`ETna%Ww>zUvbD?XDSa$#wV^5LR8 z`IrqZXU>`3;Kd#rUAnK})|bCuT#lb+RJ^*!qKAtkU0KJa;qb{64U-4cqdHE-p8d+f zk}go+^VH@4$El%O+-nc8@o`wYCV1D3dGPQ8_c~+fk-To=dB()CZ`n=oq?YGhiH8thL>#;7E zR|U;D$KLs*KIxkI{GEFI7LOPG+QrZ=(QzQOZI+b80>#7}mH#fBfprSYW7k!s*>N!) z;+!?V;@_9sdyjP9<=Xl0tZ${>{msi*x_$<0If*F>oqy@(z||8_X(D)Qr;wjU#vHeN zuls5fRaYIbS^xI7bAf8ZWrYtnCU?#~!yTVR?qRlInOl|LabOxmdS9$mO zW!^7HYTaw8)~Q^0Hu`er^iod#;FJ#qPs5LQUGU+UlsZd$CDX#ZpHCgmy8Yxg{x04c zkzx5ma_*mxj*_{`kEVEje4-rIo*-VZ<;r~~+qYSXz6K}t8S?LV7Au+GOS*2}Cm*!N zb9+{xN^Ydzbm&RD&<26InZ z_xVgyWW8b^TKSc&R)2OIcmCncmh!bW5t*!~C)Wz8E)lAzk5Ul}u27KO)OP95_9Gq( ztBa3{TJ2F;;p_VB{}i*v9fv*(?vRx{{5SPv=Q+`<<#*r^>%QGWd*0 z@r6DY{(Bo%oAUWgIOb|{(;%aHUg?YjhhjytZ(V(9%BaUhmmM@(VupO?%kHrg>k9JqCb@}Ptv(?Da z`QoQAxgf*4Azep(-XE!F-qxNreZw0^4%;cFJUKf|+F3Q~H~RKI5%=)R@XPj>zM;C{ zec6gvqV{jfDiS^wsw=r4scm=G`Q*B={qC~kk9Qr6A8d~(5Sy^vCLoB#ut?kI!b!#! z)tzrz4*k-JPn^ZM;ug=7sUNz^e6v^QXNxKAP4AdF`I$vYe2nAU2gUa17rUL(oIUTv z?yTMgKYJE>ZF6yZWb;7KWwVFsg8SRzV`j7~$87obE!675G@sOZ$)8?dRFQU`i;vsdK8)dAG>zXQq|;8XN0p zAHSgUGe{sI@6xHvH)nQo{V%L643HH$V|L}D;*5>b`+t@0UFi`sVTP2!!WY`dD;&1& z%kyBh?A>A-bR}Lhe+g4uMS)r9Ro?numtET>ny-X-yI=j_QxLXId69$O?j^TZgm5)7 z-+Uhu)GhngRp{r(UrM}-_zzkt#+g^P#^|%%{k&z9*rsj067RbIwye_rrEw!;i$Q1@ z)05+tA~L!AAE$*HY*#X_{OSJZU-i4~DmKS^UhLw(kg}@ahM?|3r~G9W=iWugTUy=B zKVRN6SG(b>(42sn&$a%u{U`T?^RPE{wxv)w>V!PsbM8>~y^~sEHy4|&y7XqxF9nXC2U+{i9xht4;vieG$h4_f z%)9eaO#P_LO4hqsMj9pY_2_4AN zwf|?lrTO34wNp}x7o6|D`}WtO!?Lb9uU?${6WJ1?cuS~v{fdiQRI|TUzy4j#tn@Nd zPU>Z)^pBXHHG5*^F9#(yJ+42eBD;0!yk9%SUn|wIty;?Ie!p2zXqN8&Z=bAXt>iy8 zMvKp1;KlAy*f{sfOp~1V?2E*=v#@S9UFzJ-W90YPHHOfvKx!3p{Z&wr|qE&tE>-UZnWVG;is3 zrRuMmzB{l^zPbF4=E7AG3s23s^Z3H?4eQ-(dY5@+Z(F#2pG8rW)A8*#^$aPq&-X8$ zr*ivP6|cGe71dTDu@8-n$LAL_{anlRrQLoltAAEw{y~`;`gf}wnZ@s$niQ0U{rtJ( ztk@%muak*DftP*ZSb|Mi;}D`ZX4_*6{D0!`xfB z=5UR>OY5dD+J&1n7J7b|b~{^*?WFg=XH_95uV;O(c8ophpjvud|G>T%mv8henfKEC znVGTs!y+{uNe8B#8fVQT5{u@he+l`rGGxh9*4tWI7GkL4aTf0JaskjHsIea^e4LXVSkd|&#Q|H)pcd_J_~P#{z6ccYbGf}=j< zs$PxRwr`u%j@e(2WSFdf;i8`Y@n^iEVRuH}{i=0B>aurlco#T6Ijb}0)U1cTRac@X zZIQdGd_`7bp7`ANzM{JqN7%f!ym9+lFN@93_=~ai-JCO@wMmO4+4-|qtlxDr8lJhryQH_!T$@{zwRn* z`}t*dar&>>k&mXmjhUa+CztlQ_M+;Rr56|8)>wIEUHr|`3CE@wE6w%QXe?N*a?xp)rQ|;01OAmdTd#;MX3Z?W{5s%;#7*1Tg$7+KPcE9fQ(<$> zNjvi|Zfk7M96kMb`=2*|W_(>MwCwvqZo6N!g^M%`H<2zR9@s((ky9I*$5I9TA-Grmv0d^*Mj`yLZ+6 zcl%<&54VrCFBcvB>SE;Rn8JtY4cw3+GO4)!$osuq<%jaJKxnVaKcY9trx#f zuxPxpx>NOXN5tXfu77)KTz8ecx@f=>_{w$r{I9v+nXjE=k-wYuE<#Ru&x|Qd9Lw3Z zb~$nAoIkH^%lKx7&fAYx8;a_Cp2X_4UNC0MkgmAz^E>s;D$Z|OQHOpV%=ezUsBP&R z-BYhBSgw7Vl_@m2{?mQE=(D#zKB(LiY5Ps-t;!sZ_O(T8BNnYyb6DV+v}aO;Lv8uI z_>`lfvTJhU-v7PfxsWB?mgUck1WAvsCwW`m2EOZ7ugZL{{q0LsapdphgYOTX|F`R9 zBggmdv~6$rt8IR7J92xQ(Sni)5ASBnn%R-fSM2y-vrW;P`O(Krr#Yp}`SO;;Kb?=3 zzxqD8BR!!Z>2JU3ifP{jy8df3zy09+uIWYJjb$f|Q@=AXOisyMC^P>(Ye+zoSkCbi zYU#=u+xZIJTAmeL)KV7qnID^Q=ThPx4RIgcIojd}j$i)Kz3bfLL&_Uja~BEC4__Ab zyHjY!hvG8(SUJw5JH^K~&-gieht$70=Glg4S6tQ3d+e{{pZ&04?*9E5TvI2=mDk5! zd%fx9S61sJE9c74goQYbLeE7f?$-0}hsXiaXZy2xG zULd}I{k*)g1N!|Llh??9bL4!$cuz$tVl8)hU8q*Hh^WM6o}}h&acZV*Pj!E8wO{7G zQDj%(W`V*izw0k`1%!?)GxMKwd(qnNqi^=DlD_+L%D$&Q{nyJgLoS$U{Pb|zRcSv@ zv%pc-?XXGo`^QIAw}^<(RM_8M#Hu>I?b@9R<72_+_WPaQ(?9i6Xh-P5>5(3smA^79 zZyT?+-G0FHz4-mUA94p3+)EevPx9*u6y;aXjBV)FpHaf#eK6tCt{84(ndy}uqvlF* zbP0&=OZGTkzgPK{>d%Ia!Oj==u97gBB`hfy#CCp>_OkD`>g@}n7?!j7%sG7QkGTNP zoAeC(%G#q_GL<~)X1zJ|MHey`Sf_07Lf z+W7A&g`^1$+3a6lcsDIz7Qc|s_VH7iTz`1i_f0MbmXxtgO@5-WBQ98Ze!$vXQ8B)Z zb@8=xLhdhG%I#p-c34_}hC|j>!(;ER$saw>FDQTP>Bb9^hhFUAT^h6WW3JnQmnrcF zcje8UnN=_}6MYW}>dsk%^_~5A(->R=Wzuipg`gHeyrZ?Ummq8ZT@M@=lo+VJ6OjIcaU2_)uVLQVM3N~+rj-EB~`6kX?#p;`}!0T-I36B$ba!1N;GG_(5 zg*rxZN|v3^`60JM;(=h9&|0IkM+x_?)_D{tiK|5P{NH-!T>q|v z!Y9^#-Tvq>?`{DZze^XM&f6_JA*8JL#wBrWi6DKsroArlpO{aX3x8LgarS~~eq$WN z++4pU${eTnT4&2jOlnlGNHsjRu5(956~9{2n`!;Knd6-FB2wN5w74A%68t!AtBiZG zT1avDrW+F$)~s#()Dgk9a*s{N_3wFyZ}%?cW1Cy``>1S(Na`nhyWP$bO`1&yXR&{C zEM36xMwLV1#$oGJ26v~7kR5Z}JtNk0lvZDwdXkkbI-@X@vF2()YnW8>$(3hS_dL{e z37elR`u_R`KiBun_nsVIRzL5!l7ifhO4+V6B8Sc0N^f&$eR@?`x7_(kr7h2&4X$st z3f!rd`zFAW!LqMaZgHIVUIW>)QOn{UGL?a`)-C{ApCkIdHZ~XWQBZdP2$<_RP9A(R5|bei*QD}}>xq0)uxsGE@vQ#fiL?96}i zXNHjKS#OgWTa5KW?oQr&Ka96-_LZ$K%NZ{ns%k&6`{)U2@8msw_Rk|{#lO?{l|9V% zTh<{_Za;6l*ks8MEB>!-JDmB()8NO2SVv`t(#?*KBLWXE{`v5gyt7V~q+aCNO3qhR zml*H(+3?;vzQ)A;;Xg(5>vLMGwI=k=I(_Ve*D;aPC)AxMaD2(P+dvtvQ^Yt7WM$v^M!Id^TTQER{?VZOZ? z5374vIQp;dw0vy(eV>u}fh0qwgh>ZKA86Rmx=T6Y^SX0CcX=;;c|kShSjmyVXGest zA8v_zzW?#j$+woU&kCGUH}Q#TLF*EZiAqX#$xPqs6Qq_a=0Cg3r%;-0|H@+d=R;mh z=KEGjX3IDj+qDMs$^3agF>K`bb`cv-FoXLh$H`Fd$JTom#ZuN;~&$rn;5ANOjZQ18>do9OQ zuAFYe&NFeZk4wDCkUZ+OET2PfLTQe-b=V4lEe#(3&omUx{9F2D`Mdck&*kDyoow91 zD9MrQr>%GM<5Awl_Fp5bm@9s}-`=^z{LRV2nPx}ldno=aE@QucV4tM%Y;)eVG7fJ7 zMZynyCipI6G}nxhzGdxmg4;V@DWg(uN8g#hlMGfR?b@>N;ieCPQK}Et>{fmES%bqs zLD_Jx(xktdg2g4*cf>EfQ6FwD`M5mnE4>eGJgTH3AOD$gbD-E+Ufrd2`(Mc`HLA2D-MaS zzuu@equ|@F?~T{Y zpxon6S1O*CY%fjP^yApwZ>nY4k7V=Je!tGn|Gw??$AITP`E`E}z2COiBa8L8gXhW& zRijnAm$ioFEx*senQ%$CDyrT~PO)@7E5o#P-0VBIYRFmXDxFak&^&Bqu}Y4|Oh_-r z{?6A0=l$!B>ot62(qhOd`)r(h`B{ms{-s&Eb_L5s6N@G_X9gVE(4c3G1S z*J7^4@0V~Mbto79(_Nc$L_DBGuxpCYwchJXuPmRkOeXVLuf|*p>nCzo|GmDbpY!u( zVv$aBn4X~ZxunUCZ;ZUcZklw9%PM(rm%R!+B4>MZQ=?s*wDrY(ZiaR(UTVAMUg*33 zKP%VZ_|*H|@0>nVxpmAt-;;i3c8bETb@f zKUlryUwXFE#Mp&3E8jBnmagsobhTLLmDu&wa`r*OvR8#C%#oAZvEqDYOz3aVCwDF$ zzci)(49mR&rf^y7OOrAJ;&~}{`*TsxmU$MZZtW4K2dQ(QpmJTwnrD) z*=}ID|L@wlwT#TEw_G;a-?~>*`HAW01+VyJ;#Qd{S$Q^zGujqrKAC;*Si;<(1vhM* z)NY5CI*Xl_pAwUlxaboNk@y zesyhwYJy3Bs?C8NTPFPqJ$b@ml4g*UPRZG4zMuRz^}g@AT`r$7t*!azSG~B%`fU~8 zeS?ccr{&7YAGK^VJbk$Dn%g}g7azM|MQ=tgmN)%r8I`HwTnGQnO}5^2S$&PwyWsur z8iGD)a`vqK?)pZyG^LRaY*iabJR7SulY6*KeAo}Xp{GS?#}cU5)Q@9A|D zH>`iFwc-f3?zZYTzdpZe&oVxqu_5`R7weW^mcKqI^mcw))pjLA((*{~|6`(WCKl?< zig({ybIUC5OX$oViR;DU*@7hn$!{0`v-R;jvm*M!QLSx#ocRk4YW6N-zr0!JFRRf8 z#XYg#d#o+@_dI|1;$+!_8Ov8(pVp?i;B@_>42#2DA3mgbYd>8c_+9#oMYXkV(5-&! zjya#M_kTLRLOCTseE$?TJDcD+!3+iqpPnx+KkPj5dS~_|_Ok)ehMor_w>+C)&NxT< zHOJ-{O{Gwmz_zxdBDWoHz4}t=?31>!W&WE}pU$7ydd+T&gk`Vco1MB=-S)M4TCt*+ zI6NH#w>;gS6n}q8)+XjZ@+<}it5+RbzUIHxR(U<=1)|~Yv-fQ`Te13Bnb#-rRcm=4 z$5d<*d}DlThi%%mSyEo}+IQG<>-`hauk75n_PW+D54qQ${~e0-UA;5bO!Z3d`wg;R zcZA(pc6*M)6$3@nS5v?8=3fatJE_-f*4$Kv={tUKoq1UL_wBvVsekMA4^)`%5bySF zyphy={?gQaRWomE>&>j$>i+)9eV_OlK2e++S(58T^rx%#EqAz7!CT+9Z|1s-OMjmW zSeGhuPjGhr{wqqXJ4Jk5&29!c#MoVa$5MLcet*gn?tSl1uF7qZunxH&u>1_i_uM0s zes1vz+d7x$*`4U^+;O)BdF4LEE}lKXsWI!`y8Vg!(>G4D3b$jZ6e^PJF}NEpw_V%n zDA!zdhm6C*_gsuR?rZJ-z`5Az`u#oOx~u&7?s-31A+xWkGm+W8{%h3JWtwT)+wZR~ z`s?JCwQcgQe+rj;*F9r*zAT>fS!A}E$JDEKLMGGJe;`*F~tzHUwO)~4{qBD6OnBH5m^K-uQvyUHIE*w93>8E5z zZ2$g?%UyYQ=bw0|aCXBF{sr9Ub_pnbpR#}R{*zr(XP5UCd(ULDXa36PmbOT!FX^D` zJ56SlioiPKCzofh*!^e6?NDW%*QtD0a_3$;r4YSm4^!p8q$v;gpGaKP_>RY8Nl^Mu zTbB=wU-f)s3>crB&Rx05*_v0TQ`>yC=A2Vqp^HABxPRf}FGkK*qj_(jSgdnC7X;?=$TEi$h9+N}L^g`so4?-SmhDT(F#ZDUg3+?bQJs`pTE z{6n|9Zf!F&4m`)o7S}1U;%#$U zTd%Mjm@zL~;q}ekS#y89FXsHxC%Cpor}O<(ZuMC8kgZ!c%;0j>aIgRHbbH3 zzx?B*k4pW&@XONM>D?BwlpEdiyo}ep)IMKqc4PCWt=dt6Y(5vC9!-$xl@e%>{E+=i zjFs`qkDsejmY#EQo+2`-Kk6XwW=&j7hryr)fx^-SG`eNPR>|(pO<@!;X z|6lx;6*c=C);k8yI2@LwV`^G+7fIb+Y`XQ&zc(RwJeyc=&VHA; zewjkfmCbQZ?|Bz@O?&VE{&J+x>BD=w*Zs;mnGl(N+UR|3z%HTfRzGhCCUwnqT3}^+ zu4k{N<-R3;e>NPFQJrNnd&Am&jGxzjSo{5V+P5SbYd`JV|5vR&&LFl}jA1cXC8Jya znR|I*kEh>Oocwvi!J?%ntFq6g{#MxYSjqEDh*)3w0a4jQKULz&#II?4a92B-Rojbr zb4!0e9Xa**nvzMvk7m4TG}XBj*O)i+%hMk3e%VK+429Dy7ihYE{e8o%eX7-NNw(Y5 zS4-|LO0?9PQ8Bw|G1tu<|L3@d_1ag}Eqm2}tnU+uiRzAf;F0-zU=pXl)Y-Y70dCx%u*Z9WvS@xc;Uz|syu(|Yu~6BPmKP| zJpbeGnT(pXU0Iu_zgB8uY}viHD+`aFu z+WTO^wartP&wj{h?!D?$&5eE9cS}`DUKXgcYB(IRTx+hn@@MF|o4$uvmZ-0py*xkX zRn?RphEF#6|7Z0iv)zkq{=p+weCc#aDc6BVS9i$-o#*zoQezF6wf6GoDRb5rHy=5+kU_M=O)R$ zaO7Wb>Qd#I?Ps`xxwDd`*h51e&z||~eW4KV3{B<#hf6^czWaIw>y?f?ei`ntwk`l+| z(@YbeEfnyuo!ckFD{NA?=GxI>zdPz070CgTH{K;oVC8Vk>ua4Vz5PSU(J5CIzHGEq zUt7OWSG~Snpv~_Iv(#?!SDS9iaaUZ;V=vFOwwSlS#yj}t5xeifNJB%NkF{@i2ZoAgIzpVy{vN*U_EN!0XU=I4{O7M*G;!S8hFrk#7L@U8Pn zVYBq?yneYoc=mYqwe=evW_L@eMSMDX>d@C~=RH?uJ?q)H>9=x((#u@qKR6$o zl&RyqX6H_0$wbk4e3uIQ+!j}?wwnLYCt8}(-`wuT$;28t+p>QD#iE-+&Zw8!^&UF5 zbLT4gX-l?7KkwU8`CjA?>lZ+^)0XIk#poVoF~Jk$UExOmp- z2mhoP&56J6D}7v`6xM5?9K1+4fjeB)aj*Wiq<4c<47 zzrFwUn>=gjhG=UJ)sr*cz6sLR@?`VoUC*#ZvuypQrE04kmnHqQoXv78;f2`8RqU!0 z9)7P3Z^-Y=-CDOW>{ZjflKZm{95`^tXYL%`w{H*p^H2K2UsiVQzuZiV8xsGY|A?P) za7IMrO$o~zGb1Da2OmFj=*$TYwuC?Sx31O~mX;ZoFfknPxvTS*$2Uj!fB51b_n-c^ fKic%+|E}ixe?OnkhZFy&{b!Rl5W33Hz{CImZv$|( literal 0 HcmV?d00001 diff --git a/glib2.0_2.72.4.orig.tar.xz.id b/glib2.0_2.72.4.orig.tar.xz.id new file mode 100644 index 0000000..46b3317 --- /dev/null +++ b/glib2.0_2.72.4.orig.tar.xz.id @@ -0,0 +1 @@ +d4aafc9b262862566840712e0deb326f1f5925f7 From 35354c0100e8d9c70d5c7638070eb794e2ac3f42 Mon Sep 17 00:00:00 2001 From: Alexis Cruz Date: Tue, 4 Jul 2023 11:43:06 +0200 Subject: [PATCH 4/5] update patches --- ...ttributes-see-https-code.evin.team-e.patch | 36 +++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 37 insertions(+) create mode 100644 debian/patches/disable-setting-ACL-attributes-see-https-code.evin.team-e.patch diff --git a/debian/patches/disable-setting-ACL-attributes-see-https-code.evin.team-e.patch b/debian/patches/disable-setting-ACL-attributes-see-https-code.evin.team-e.patch new file mode 100644 index 0000000..d7b357c --- /dev/null +++ b/debian/patches/disable-setting-ACL-attributes-see-https-code.evin.team-e.patch @@ -0,0 +1,36 @@ +From: Alexis Cruz +Date: Tue, 4 Jul 2023 11:27:19 +0200 +Subject: disable setting ACL attributes, + see https://code.evin.team/evin/ansible-managed-servers/issues/5 + +--- + gio/gfile.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/gio/gfile.c b/gio/gfile.c +index 1810e36..42ea204 100644 +--- a/gio/gfile.c ++++ b/gio/gfile.c +@@ -3426,14 +3426,14 @@ file_copy_fallback (GFile *source, + + /* Ignore errors here. Failure to copy metadata is not a hard error */ + /* TODO: set these attributes /before/ we do the rename() on Unix */ +- if (ret && do_set_attributes) +- { +- g_file_set_attributes_from_info (destination, +- info, +- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, +- cancellable, +- NULL); +- } ++ //if (ret && do_set_attributes) ++ // { ++ // g_file_set_attributes_from_info (destination, ++ // info, ++ // G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, ++ // cancellable, ++ // NULL); ++ // } + + g_clear_object (&info); + diff --git a/debian/patches/series b/debian/patches/series index 3bd5e17..1479c06 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -38,3 +38,4 @@ gvariant-security-1-18.patch gvariant-security-2-1.patch gvariant-security-2-2.patch gvariant-security-3-1.patch +disable-setting-ACL-attributes-see-https-code.evin.team-e.patch From 6cfb6704dcd9732277ebbb75b2721ba26779930a Mon Sep 17 00:00:00 2001 From: Alexis Cruz Date: Tue, 4 Jul 2023 12:04:00 +0200 Subject: [PATCH 5/5] release version 2.72.4-0ubuntu2.2+evin1 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index f3b1f43..3381d42 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +glib2.0 (2.72.4-0ubuntu2.2+evin1) jammy; urgency=medium + + * update patches + + -- Alexis Cruz Tue, 04 Jul 2023 12:02:35 +0200 + glib2.0 (2.72.4-0ubuntu2.2) jammy-security; urgency=medium * SECURITY UPDATE: multiple GVariant security issues